ia32: Merge AddMem, AndMem, OrMem, SubMem and XorMem with their 8 bit variants.
authorChristoph Mallon <christoph.mallon@gmx.de>
Sun, 2 Dec 2012 21:32:51 +0000 (22:32 +0100)
committerChristoph Mallon <christoph.mallon@gmx.de>
Sun, 2 Dec 2012 22:30:55 +0000 (23:30 +0100)
ir/be/ia32/ia32_emitter.c
ir/be/ia32/ia32_spec.pl
ir/be/ia32/ia32_transform.c

index 829f8cb..00436c1 100644 (file)
@@ -2204,49 +2204,44 @@ 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)
@@ -3319,10 +3314,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);
@@ -3368,7 +3361,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);
@@ -3396,14 +3388,12 @@ static void ia32_register_binary_emitters(void)
        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);
index fcb14af..7959fd2 100644 (file)
@@ -158,6 +158,11 @@ my %binop_flags_constructors = (
        }
 );
 
+my %binop_mem_constructors = (
+       ""     => { reg_req   => { in => [ "gp", "gp", "none", "gp" ],              out => [ "none" ] } },
+       "8bit" => { reg_req   => { in => [ "gp", "gp", "none", "eax ebx ecx edx" ], out => [ "none" ] } },
+);
+
 %nodes = (
 
 Immediate => {
@@ -212,18 +217,7 @@ Add => {
 AddMem => {
        irn_flags => [ "rematerializable" ],
        state     => "exc_pinned",
-       reg_req   => { in => [ "gp", "gp", "none", "gp" ], out => [ "none" ] },
-       ins       => [ "base", "index", "mem", "val" ],
-       emit      => "add%M %#S3, %AM",
-       latency   => 1,
-       mode      => "mode_M",
-       modified_flags => $status_flags
-},
-
-AddMem8Bit => {
-       irn_flags => [ "rematerializable" ],
-       state     => "exc_pinned",
-       reg_req   => { in => [ "gp", "gp", "none", "eax ebx ecx edx" ], out => [ "none" ] },
+       constructors => \%binop_mem_constructors,
        ins       => [ "base", "index", "mem", "val" ],
        emit      => "add%M %#S3, %AM",
        latency   => 1,
@@ -329,18 +323,7 @@ And => {
 AndMem => {
        irn_flags => [ "rematerializable" ],
        state     => "exc_pinned",
-       reg_req   => { in => [ "gp", "gp", "none", "gp" ], out => [ "none" ] },
-       ins       => [ "base", "index", "mem", "val" ],
-       emit      => 'and%M %#S3, %AM',
-       latency   => 1,
-       mode      => "mode_M",
-       modified_flags => $status_flags
-},
-
-AndMem8Bit => {
-       irn_flags => [ "rematerializable" ],
-       state     => "exc_pinned",
-       reg_req   => { in => [ "gp", "gp", "none",  "eax ebx ecx edx" ], out => [ "none" ] },
+       constructors => \%binop_mem_constructors,
        ins       => [ "base", "index", "mem", "val" ],
        emit      => 'and%M %#S3, %AM',
        latency   => 1,
@@ -365,18 +348,7 @@ Or => {
 OrMem => {
        irn_flags => [ "rematerializable" ],
        state     => "exc_pinned",
-       reg_req   => { in => [ "gp", "gp", "none", "gp" ], out => [ "none" ] },
-       ins       => [ "base", "index", "mem", "val" ],
-       emit      => 'or%M %#S3, %AM',
-       latency   => 1,
-       mode      => "mode_M",
-       modified_flags => $status_flags
-},
-
-OrMem8Bit => {
-       irn_flags => [ "rematerializable" ],
-       state     => "exc_pinned",
-       reg_req   => { in => [ "gp", "gp", "none", "eax ebx ecx edx" ], out => [ "none" ] },
+       constructors => \%binop_mem_constructors,
        ins       => [ "base", "index", "mem", "val" ],
        emit      => 'or%M %#S3, %AM',
        latency   => 1,
@@ -412,18 +384,7 @@ Xor0 => {
 XorMem => {
        irn_flags => [ "rematerializable" ],
        state     => "exc_pinned",
-       reg_req   => { in => [ "gp", "gp", "none", "gp" ], out => [ "none" ] },
-       ins       => [ "base", "index", "mem", "val" ],
-       emit      => 'xor%M %#S3, %AM',
-       latency   => 1,
-       mode      => "mode_M",
-       modified_flags => $status_flags
-},
-
-XorMem8Bit => {
-       irn_flags => [ "rematerializable" ],
-       state     => "exc_pinned",
-       reg_req   => { in => [ "gp", "gp", "none", "eax ebx ecx edx" ], out => [ "none" ] },
+       constructors => \%binop_mem_constructors,
        ins       => [ "base", "index", "mem", "val" ],
        emit      => 'xor%M %#S3, %AM',
        latency   => 1,
@@ -448,18 +409,7 @@ Sub => {
 SubMem => {
        irn_flags => [ "rematerializable" ],
        state     => "exc_pinned",
-       reg_req   => { in => [ "gp", "gp", "none", "gp" ], out => [ "none" ] },
-       ins       => [ "base", "index", "mem", "subtrahend" ],
-       emit      => 'sub%M %#S3, %AM',
-       latency   => 1,
-       mode      => 'mode_M',
-       modified_flags => $status_flags
-},
-
-SubMem8Bit => {
-       irn_flags => [ "rematerializable" ],
-       state     => "exc_pinned",
-       reg_req   => { in => [ "gp", "gp", "none", "eax ebx ecx edx" ], out => [ "none" ] },
+       constructors => \%binop_mem_constructors,
        ins       => [ "base", "index", "mem", "subtrahend" ],
        emit      => 'sub%M %#S3, %AM',
        latency   => 1,
index 8a0e20c..c4e3d94 100644 (file)
@@ -2506,7 +2506,7 @@ static ir_node *try_create_dest_am(ir_node *node)
                        }
                }
                new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
-                                        new_bd_ia32_AddMem, new_bd_ia32_AddMem8Bit,
+                                        new_bd_ia32_AddMem, new_bd_ia32_AddMem_8bit,
                                         match_commutative | match_immediate);
                break;
        case iro_Sub:
@@ -2516,28 +2516,28 @@ static ir_node *try_create_dest_am(ir_node *node)
                        ir_fprintf(stderr, "Optimisation warning: not-normalized sub ,C found\n");
                }
                new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
-                                        new_bd_ia32_SubMem, new_bd_ia32_SubMem8Bit,
+                                        new_bd_ia32_SubMem, new_bd_ia32_SubMem_8bit,
                                         match_immediate);
                break;
        case iro_And:
                op1      = get_And_left(val);
                op2      = get_And_right(val);
                new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
-                                        new_bd_ia32_AndMem, new_bd_ia32_AndMem8Bit,
+                                        new_bd_ia32_AndMem, new_bd_ia32_AndMem_8bit,
                                         match_commutative | match_immediate);
                break;
        case iro_Or:
                op1      = get_Or_left(val);
                op2      = get_Or_right(val);
                new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
-                                        new_bd_ia32_OrMem, new_bd_ia32_OrMem8Bit,
+                                        new_bd_ia32_OrMem, new_bd_ia32_OrMem_8bit,
                                         match_commutative | match_immediate);
                break;
        case iro_Eor:
                op1      = get_Eor_left(val);
                op2      = get_Eor_right(val);
                new_node = dest_am_binop(val, op1, op2, mem, ptr, mode,
-                                        new_bd_ia32_XorMem, new_bd_ia32_XorMem8Bit,
+                                        new_bd_ia32_XorMem, new_bd_ia32_XorMem_8bit,
                                         match_commutative | match_immediate);
                break;
        case iro_Shl: