ia32: Clean up ia32_get_op_estimated_cost().
[libfirm] / ir / be / ia32 / ia32_emitter.c
index 0a00aad..902652b 100644 (file)
@@ -1,20 +1,6 @@
 /*
- * Copyright (C) 1995-2011 University of Karlsruhe.  All right reserved.
- *
  * This file is part of libFirm.
- *
- * This file may be distributed and/or modified under the terms of the
- * GNU General Public License version 2 as published by the Free Software
- * Foundation and appearing in the file LICENSE.GPL included in the
- * packaging of this file.
- *
- * Licensees holding valid libFirm Professional Edition licenses may use
- * this file in accordance with the libFirm Commercial License.
- * Agreement provided with the Software.
- *
- * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
- * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE.
+ * Copyright (C) 2012 University of Karlsruhe.
  */
 
 /**
@@ -2202,50 +2188,46 @@ BINOP(sbb, 3)
 BINOP(and, 4)
 BINOP(sub, 5)
 BINOP(xor, 6)
+BINOP(cmp, 7)
 
-#define BINOPMEM(op, ext) \
-static void bemit_##op(const ir_node *node) \
-{ \
-       ir_node *val; \
-       unsigned size = get_mode_size_bits(get_ia32_ls_mode(node)); \
-       if (size == 16) \
-               bemit8(0x66); \
-       val = get_irn_n(node, n_ia32_unary_op); \
-       if (is_ia32_Immediate(val)) { \
-               const ia32_immediate_attr_t *attr   = get_ia32_immediate_attr_const(val); \
-               int                          offset = attr->offset; \
-               if (attr->symconst == NULL && get_signed_imm_size(offset) == 1) { \
-                       bemit8(0x83); \
-                       bemit_mod_am(ext, node); \
-                       bemit8(offset); \
-               } else { \
-                       bemit8(0x81); \
-                       bemit_mod_am(ext, node); \
-                       if (size == 16) { \
-                               bemit16(offset); \
-                       } else { \
-                               bemit_entity(attr->symconst, attr->sc_sign, offset, false); \
-                       } \
-               } \
-       } else { \
-               bemit8(ext << 3 | 1); \
-               bemit_mod_am(reg_gp_map[arch_get_irn_register(val)->index], node); \
-       } \
-} \
- \
-static void bemit_##op##8bit(const ir_node *node) \
-{ \
-       ir_node *val = get_irn_n(node, n_ia32_unary_op); \
-       if (is_ia32_Immediate(val)) { \
-               bemit8(0x80); \
-               bemit_mod_am(ext, node); \
-               bemit8(get_ia32_immediate_attr_const(val)->offset); \
-       } else { \
-               bemit8(ext << 3); \
-               bemit_mod_am(reg_gp_map[arch_get_irn_register(val)->index], node); \
-       } \
+static void bemit_binop_mem(ir_node const *const node, unsigned const code)
+{
+       unsigned size = get_mode_size_bits(get_ia32_ls_mode(node));
+       if (size == 16)
+               bemit8(0x66);
+
+       unsigned       op  = size == 8 ? OP_8 : OP_16_32;
+       ir_node *const val = get_irn_n(node, n_ia32_unary_op);
+       if (is_ia32_Immediate(val)) {
+               ia32_immediate_attr_t const *const attr = get_ia32_immediate_attr_const(val);
+               /* Try to use the short form with 8bit sign extended immediate. */
+               if (op != OP_8 && !attr->symconst && get_signed_imm_size(attr->offset) == 1) {
+                       op   = OP_16_32_IMM8;
+                       size = 8;
+               }
+
+               /* Emit the main opcode. */
+               bemit8(0x80 | op);
+               bemit_mod_am(code, node);
+
+               /* Emit the immediate. */
+               switch (size) {
+               case  8: bemit8(attr->offset);  break;
+               case 16: bemit16(attr->offset); break;
+               case 32: bemit_entity(attr->symconst, attr->sc_sign, attr->offset, false); break;
+               }
+       } else {
+               bemit8(code << 3 | op);
+               bemit_mod_am(reg_gp_map[arch_get_irn_register(val)->index], node);
+       }
 }
 
+#define BINOPMEM(op, code) \
+       static void bemit_##op(ir_node const *const node) \
+       { \
+               bemit_binop_mem(node, code); \
+       }
+
 BINOPMEM(addmem,  0)
 BINOPMEM(ormem,   1)
 BINOPMEM(andmem,  4)
@@ -2485,104 +2467,6 @@ static void bemit_cmovcc(const ir_node *node)
        }
 }
 
-static void bemit_cmp(const ir_node *node)
-{
-       unsigned  ls_size = get_mode_size_bits(get_ia32_ls_mode(node));
-       ir_node  *right;
-
-       if (ls_size == 16)
-               bemit8(0x66);
-
-       right = get_irn_n(node, n_ia32_binary_right);
-       if (is_ia32_Immediate(right)) {
-               /* Use in-reg, because some instructions (cmp, test) have no out-reg. */
-               const ir_node               *op   = get_irn_n(node, n_ia32_binary_right);
-               const ia32_immediate_attr_t *attr = get_ia32_immediate_attr_const(op);
-               unsigned                     size;
-
-               if (attr->symconst != NULL) {
-                       size = 4;
-               } else {
-                       /* check for sign extension */
-                       size = get_signed_imm_size(attr->offset);
-               }
-
-               switch (size) {
-                       case 1:
-                               bemit8(0x80 | OP_16_32_IMM8);
-                               /* cmp has this special mode */
-                               if (get_ia32_op_type(node) == ia32_Normal) {
-                                       const arch_register_t *reg = arch_get_irn_register_in(node, n_ia32_binary_left);
-                                       bemit_modru(reg, 7);
-                               } else {
-                                       bemit_mod_am(7, node);
-                               }
-                               bemit8((unsigned char)attr->offset);
-                               return;
-                       case 2:
-                       case 4:
-                               /* check for eax variant: this variant is shorter for 32bit immediates only */
-                               if (get_ia32_op_type(node) == ia32_Normal) {
-                                       const arch_register_t *reg = arch_get_irn_register_in(node, n_ia32_binary_left);
-                                       if (reg->index == REG_GP_EAX) {
-                                               bemit8(0x3D);
-                                       } else {
-                                               bemit8(0x81);
-                                               bemit_modru(reg, 7);
-                                       }
-                               } else {
-                                       bemit8(0x81);
-                                       bemit_mod_am(7, node);
-                               }
-                               if (ls_size == 16) {
-                                       bemit16(attr->offset);
-                               } else {
-                                       bemit_entity(attr->symconst, attr->sc_sign, attr->offset, false);
-                               }
-                               return;
-               }
-               panic("invalid imm size?!?");
-       } else {
-               const arch_register_t *out = arch_get_irn_register_in(node, n_ia32_binary_left);
-               bemit8(0x3B);
-               if (get_ia32_op_type(node) == ia32_Normal) {
-                       const arch_register_t *op2 = arch_get_irn_register_in(node, n_ia32_binary_right);
-                       bemit_modrr(op2, out);
-               } else {
-                       bemit_mod_am(reg_gp_map[out->index], node);
-               }
-       }
-}
-
-static void bemit_cmp8bit(const ir_node *node)
-{
-       ir_node *right = get_irn_n(node, n_ia32_binary_right);
-       if (is_ia32_Immediate(right)) {
-               if (get_ia32_op_type(node) == ia32_Normal) {
-                       const arch_register_t *out = arch_get_irn_register_in(node, n_ia32_Cmp_left);
-                       if (out->index == REG_GP_EAX) {
-                               bemit8(0x3C);
-                       } else {
-                               bemit8(0x80);
-                               bemit_modru(out, 7);
-                       }
-               } else {
-                       bemit8(0x80);
-                       bemit_mod_am(7, node);
-               }
-               bemit8(get_ia32_immediate_attr_const(right)->offset);
-       } else {
-               const arch_register_t *out = arch_get_irn_register_in(node, n_ia32_Cmp_left);
-               bemit8(0x3A);
-               if (get_ia32_op_type(node) == ia32_Normal) {
-                       const arch_register_t *in = arch_get_irn_register_in(node, n_ia32_Cmp_right);
-                       bemit_modrr(out, in);
-               } else {
-                       bemit_mod_am(reg_gp_map[out->index], node);
-               }
-       }
-}
-
 static void bemit_test(ir_node const *const node)
 {
        unsigned const size = get_mode_size_bits(get_ia32_ls_mode(node));
@@ -3416,10 +3300,8 @@ static void ia32_register_binary_emitters(void)
        be_set_emitter(op_ia32_Adc,           bemit_adc);
        be_set_emitter(op_ia32_Add,           bemit_add);
        be_set_emitter(op_ia32_AddMem,        bemit_addmem);
-       be_set_emitter(op_ia32_AddMem8Bit,    bemit_addmem8bit);
        be_set_emitter(op_ia32_And,           bemit_and);
        be_set_emitter(op_ia32_AndMem,        bemit_andmem);
-       be_set_emitter(op_ia32_AndMem8Bit,    bemit_andmem8bit);
        be_set_emitter(op_ia32_Asm,           emit_ia32_Asm); // TODO implement binary emitter
        be_set_emitter(op_ia32_Breakpoint,    bemit_int3);
        be_set_emitter(op_ia32_Bsf,           bemit_bsf);
@@ -3431,10 +3313,8 @@ static void ia32_register_binary_emitters(void)
        be_set_emitter(op_ia32_Cltd,          bemit_cltd);
        be_set_emitter(op_ia32_Cmc,           bemit_cmc);
        be_set_emitter(op_ia32_Cmp,           bemit_cmp);
-       be_set_emitter(op_ia32_Cmp8Bit,       bemit_cmp8bit);
        be_set_emitter(op_ia32_Const,         bemit_mov_const);
        be_set_emitter(op_ia32_Conv_I2I,      bemit_conv_i2i);
-       be_set_emitter(op_ia32_Conv_I2I8Bit,  bemit_conv_i2i);
        be_set_emitter(op_ia32_CopyB_i,       bemit_copybi);
        be_set_emitter(op_ia32_Cwtl,          bemit_cwtl);
        be_set_emitter(op_ia32_Dec,           bemit_dec);
@@ -3466,7 +3346,6 @@ static void ia32_register_binary_emitters(void)
        be_set_emitter(op_ia32_NotMem,        bemit_notmem);
        be_set_emitter(op_ia32_Or,            bemit_or);
        be_set_emitter(op_ia32_OrMem,         bemit_ormem);
-       be_set_emitter(op_ia32_OrMem8Bit,     bemit_ormem8bit);
        be_set_emitter(op_ia32_Pop,           bemit_pop);
        be_set_emitter(op_ia32_PopEbp,        bemit_pop);
        be_set_emitter(op_ia32_PopMem,        bemit_popmem);
@@ -3491,17 +3370,14 @@ static void ia32_register_binary_emitters(void)
        be_set_emitter(op_ia32_ShrMem,        bemit_shrmem);
        be_set_emitter(op_ia32_Stc,           bemit_stc);
        be_set_emitter(op_ia32_Store,         bemit_store);
-       be_set_emitter(op_ia32_Store8Bit,     bemit_store);
        be_set_emitter(op_ia32_Sub,           bemit_sub);
        be_set_emitter(op_ia32_SubMem,        bemit_submem);
-       be_set_emitter(op_ia32_SubMem8Bit,    bemit_submem8bit);
        be_set_emitter(op_ia32_SubSP,         bemit_subsp);
        be_set_emitter(op_ia32_SwitchJmp,     bemit_switchjmp);
        be_set_emitter(op_ia32_Test,          bemit_test);
        be_set_emitter(op_ia32_Xor,           bemit_xor);
        be_set_emitter(op_ia32_Xor0,          bemit_xor0);
        be_set_emitter(op_ia32_XorMem,        bemit_xormem);
-       be_set_emitter(op_ia32_XorMem8Bit,    bemit_xormem8bit);
        be_set_emitter(op_ia32_fabs,          bemit_fabs);
        be_set_emitter(op_ia32_fadd,          bemit_fadd);
        be_set_emitter(op_ia32_fchs,          bemit_fchs);