Implement binary emitters for AddMem8Bit, AndMem8Bit, OrMem8Bit, SubMem8Bit and XorMe...
[libfirm] / ir / be / ia32 / ia32_emitter.c
index af1c9bd..602fc5b 100644 (file)
@@ -2251,22 +2251,34 @@ static void build_reg_map(void)
        reg_gp_map[REG_ESI] = 0x6;
        reg_gp_map[REG_EDI] = 0x7;
 
-       pnc_map_signed[pn_Cmp_Eq] = 0x04;
-       pnc_map_signed[pn_Cmp_Lt] = 0x0C;
-       pnc_map_signed[pn_Cmp_Le] = 0x0E;
-       pnc_map_signed[pn_Cmp_Gt] = 0x0F;
-       pnc_map_signed[pn_Cmp_Ge] = 0x0D;
-       pnc_map_signed[pn_Cmp_Ne] = 0x05;
+       pnc_map_signed[pn_Cmp_Eq]    = 0x04;
+       pnc_map_signed[pn_Cmp_Lt]    = 0x0C;
+       pnc_map_signed[pn_Cmp_Le]    = 0x0E;
+       pnc_map_signed[pn_Cmp_Gt]    = 0x0F;
+       pnc_map_signed[pn_Cmp_Ge]    = 0x0D;
+       pnc_map_signed[pn_Cmp_Lg]    = 0x05;
 
-       pnc_map_unsigned[pn_Cmp_Eq] = 0x04;
-       pnc_map_unsigned[pn_Cmp_Lt] = 0x02;
-       pnc_map_unsigned[pn_Cmp_Le] = 0x06;
-       pnc_map_unsigned[pn_Cmp_Gt] = 0x07;
-       pnc_map_unsigned[pn_Cmp_Ge] = 0x03;
-       pnc_map_unsigned[pn_Cmp_Ne] = 0x05;
+       pnc_map_unsigned[pn_Cmp_Eq]    = 0x04;
+       pnc_map_unsigned[pn_Cmp_Lt]    = 0x02;
+       pnc_map_unsigned[pn_Cmp_Le]    = 0x06;
+       pnc_map_unsigned[pn_Cmp_Gt]    = 0x07;
+       pnc_map_unsigned[pn_Cmp_Ge]    = 0x03;
+       pnc_map_unsigned[pn_Cmp_Lg]    = 0x05;
 }
 
-#define GET_MODE(code) ((code) & 0xC0)
+static unsigned char pnc2cc(int pnc)
+{
+       unsigned char cc;
+       if (pnc == ia32_pn_Cmp_parity) {
+               cc = 0x0A;
+       } else if (pnc & ia32_pn_Cmp_float || pnc & ia32_pn_Cmp_unsigned) {
+               cc = pnc_map_unsigned[pnc & 0x07];
+       } else {
+               cc = pnc_map_signed[pnc & 0x07];
+       }
+       assert(cc != 0);
+       return cc;
+}
 
 /** Sign extension bit values for binops */
 enum SignExt {
@@ -2287,12 +2299,8 @@ enum Mod {
 /** create REG encoding for ModR/M */
 #define ENC_REG(x) ((x) << 3)
 
-/** create Base encoding for SIB */
-#define ENC_BASE(x) (x)
-/** create Index encoding for SIB */
-#define ENC_INDEX(x) ((x) << 3)
-/** create Scale encoding for SIB */
-#define ENC_SCALE(x) ((x) << 6)
+/** create encoding for a SIB byte */
+#define ENC_SIB(scale, index, base) ((scale) << 6 | (index) << 3 | (base))
 
 /* Node: The following routines are supposed to append bytes, words, dwords
    to the output stream.
@@ -2307,7 +2315,7 @@ static void bemit8(const unsigned char byte)
        be_emit_write_line();
 }
 
-static void bemit16(const unsigned u16)
+static void bemit16(const unsigned short u16)
 {
        be_emit_irprintf("\t.word 0x%x\n", u16);
        be_emit_write_line();
@@ -2359,6 +2367,7 @@ static void bemit_jmp_destination(const ir_node *dest_block)
        be_emit_cstring("\t.long ");
        ia32_emit_block_name(dest_block);
        be_emit_cstring(" - . - 4\n");
+       be_emit_write_line();
 }
 
 /* end emit routines, all emitters following here should only use the functions
@@ -2434,6 +2443,7 @@ static void bemit_mod_am(unsigned reg, const ir_node *node)
        unsigned   sib       = 0;
        unsigned   emitoffs  = 0;
        bool       emitsib   = false;
+       unsigned   base_enc;
 
        /* set the mod part depending on displacement */
        if (ent != NULL) {
@@ -2450,53 +2460,42 @@ static void bemit_mod_am(unsigned reg, const ir_node *node)
                emitoffs = 32;
        }
 
-       /* determine if we need a SIB byte */
+       if (has_base) {
+               const arch_register_t *base_reg = arch_get_irn_register(base);
+               base_enc = reg_gp_map[base_reg->index];
+       } else {
+               /* Use the EBP encoding + MOD_IND if NO base register. There is
+                * always a 32bit offset present in this case. */
+               modrm    = MOD_IND;
+               base_enc = 0x05;
+               emitoffs = 32;
+       }
+
+       /* Determine if we need a SIB byte. */
        if (has_index) {
-               int scale;
                const arch_register_t *reg_index = arch_get_irn_register(index);
-               assert(reg_index->index != REG_ESP);
-               sib |= ENC_INDEX(reg_gp_map[reg_index->index]);
-
-               if (has_base) {
-                       const arch_register_t *base_reg = arch_get_irn_register(base);
-                       sib |= ENC_BASE(reg_gp_map[base_reg->index]);
-               } else {
-                       /* use the EBP encoding if NO base register */
-                       sib |= 0x05;
-               }
-
-               scale = get_ia32_am_scale(node);
+               int                    scale     = get_ia32_am_scale(node);
                assert(scale < 4);
-               sib |= ENC_SCALE(scale);
+               /* R/M set to ESP means SIB in 32bit mode. */
+               modrm   |= ENC_RM(0x04);
+               sib      = ENC_SIB(scale, reg_gp_map[reg_index->index], base_enc);
                emitsib = true;
+       } else if (base_enc == 0x04) {
+               /* for the above reason we are forced to emit a SIB when base is ESP.
+                * Only the base is used, index must be ESP too, which means no index.
+                */
+               modrm   |= ENC_RM(0x04);
+               sib      = ENC_SIB(0, 0x04, 0x04);
+               emitsib  = true;
+       } else {
+               modrm |= ENC_RM(base_enc);
        }
 
-       /* determine modrm byte */
-       if (emitsib) {
-               /* R/M set to ESP means SIB in 32bit mode */
-               modrm |= ENC_RM(0x04);
-       } else if (has_base) {
-               const arch_register_t *base_reg = arch_get_irn_register(base);
-               if (base_reg->index == REG_ESP) {
-                       /* for the above reason we are forced to emit a sib when base is
-                        * ESP. Only the base is used, index must be ESP too, which means no
-                        * index. */
-                       sib     = ENC_BASE(0x04) | ENC_INDEX(0x04);
-                       emitsib = true;
-
-               /* we are forced to emit a 8bit offset as EBP base without
-                  offset is a special case for SIB without base register */
-               } else if (base_reg->index == REG_EBP && emitoffs == 0) {
-                       assert(GET_MODE(modrm) == MOD_IND);
-                       emitoffs  = 8;
-                       modrm    |= MOD_IND_BYTE_OFS;
-               }
-
-               modrm |= ENC_RM(reg_gp_map[base_reg->index]);
-       } else {
-               /* only displacement: Use EBP + disp encoding in 32bit mode */
-               emitoffs = 32;
-               modrm    = ENC_RM(0x05);
+       /* We are forced to emit an 8bit offset as EBP base without offset is a
+        * special case for SIB without base register. */
+       if (base_enc == 0x05 && emitoffs == 0) {
+               modrm    |= MOD_IND_BYTE_OFS;
+               emitoffs  = 8;
        }
 
        modrm |= ENC_REG(reg);
@@ -2618,19 +2617,26 @@ static void bemit_binop(const ir_node *node, const unsigned char opcodes[4])
  */
 static void bemit_unop(const ir_node *node, unsigned char code, unsigned char ext, int input)
 {
-       ia32_op_type_t am_type = get_ia32_op_type(node);
-
        bemit8(code);
-       if (am_type == ia32_AddrModeD) {
-               bemit8(code);
-               bemit_mod_am(ext, node);
-       } else {
+       if (get_ia32_op_type(node) == ia32_Normal) {
                const arch_register_t *in = get_in_reg(node, input);
-               assert(am_type == ia32_Normal);
                bemit_modru(in, ext);
+       } else {
+               bemit_mod_am(ext, node);
        }
 }
 
+static void bemit_unop_reg(const ir_node *node, unsigned char code, int input)
+{
+       const arch_register_t *out = get_out_reg(node, 0);
+       bemit_unop(node, code, reg_gp_map[out->index], input);
+}
+
+static void bemit_unop_mem(const ir_node *node, unsigned char code, unsigned char ext)
+{
+       bemit8(code);
+       bemit_mod_am(ext, node);
+}
 
 static void bemit_immediate(const ir_node *node, bool relative)
 {
@@ -2658,6 +2664,37 @@ static void bemit_copy(const ir_node *copy)
        }
 }
 
+static void bemit_perm(const ir_node *node)
+{
+       const arch_register_t       *in0  = arch_get_irn_register(get_irn_n(node, 0));
+       const arch_register_t       *in1  = arch_get_irn_register(get_irn_n(node, 1));
+       const arch_register_class_t *cls0 = arch_register_get_class(in0);
+
+       assert(cls0 == arch_register_get_class(in1) && "Register class mismatch at Perm");
+
+       if (cls0 == &ia32_reg_classes[CLASS_ia32_gp]) {
+               if (in0->index == REG_EAX) {
+                       bemit8(0x90 + reg_gp_map[in1->index]);
+               } else if (in1->index == REG_EAX) {
+                       bemit8(0x90 + reg_gp_map[in0->index]);
+               } else {
+                       bemit8(0x87);
+                       bemit_modrr(in0, in1);
+               }
+       } else if (cls0 == &ia32_reg_classes[CLASS_ia32_xmm]) {
+               panic("unimplemented"); // TODO implement
+               //ia32_emitf(NULL, "\txorpd %R, %R\n", in1, in0);
+               //ia32_emitf(NULL, "\txorpd %R, %R\n", in0, in1);
+               //ia32_emitf(node, "\txorpd %R, %R\n", in1, in0);
+       } else if (cls0 == &ia32_reg_classes[CLASS_ia32_vfp]) {
+               /* is a NOP */
+       } else if (cls0 == &ia32_reg_classes[CLASS_ia32_st]) {
+               /* is a NOP */
+       } else {
+               panic("unexpected register class in be_Perm (%+F)", node);
+       }
+}
+
 static void bemit_xor0(const ir_node *node)
 {
        const arch_register_t *out = get_out_reg(node, 0);
@@ -2692,6 +2729,48 @@ BINOP(xor,  0x31, 0x35, 0x81, 6)
 BINOP(cmp,  0x39, 0x3D, 0x81, 7)
 BINOP(test, 0x85, 0xA9, 0xF7, 0)
 
+#define BINOPMEM(op, ext) \
+static void bemit_##op(const ir_node *node) \
+{ \
+       ir_node *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 == 0 && get_signed_imm_size(offset) == 1) { \
+                       bemit8(0x83); \
+                       bemit_mod_am(ext, node); \
+                       bemit8(offset); \
+               } else { \
+                       bemit8(0x81); \
+                       bemit_mod_am(ext, node); \
+                       bemit_entity(attr->symconst, attr->sc_sign, offset, false); \
+               } \
+       } else { \
+               bemit8(ext << 3 | 1); \
+               bemit_mod_am(reg_gp_map[get_out_reg(val, 0)->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[get_out_reg(val, 0)->index], node); \
+       } \
+}
+
+BINOPMEM(addmem,  0)
+BINOPMEM(ormem,   1)
+BINOPMEM(andmem,  4)
+BINOPMEM(submem,  5)
+BINOPMEM(xormem,  6)
+
+
 /**
  * Creates a function for an Unop with code /ext encoding.
  */
@@ -2737,6 +2816,54 @@ SHIFT(shl, 4)
 SHIFT(shr, 5)
 SHIFT(sar, 7)
 
+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 = get_in_reg(node, n_ia32_Cmp_left);
+                       if (out->index == REG_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 {
+               bemit8(0x3A);
+               const arch_register_t *out = get_in_reg(node, n_ia32_Cmp_left);
+               if (get_ia32_op_type(node) == ia32_Normal) {
+                       const arch_register_t *in = get_in_reg(node, n_ia32_Cmp_right);
+                       bemit_modrr(out, in);
+               } else {
+                       bemit_mod_am(reg_gp_map[out->index], node);
+               }
+       }
+}
+
+static void bemit_imul(const ir_node *node)
+{
+       ir_node *right = get_irn_n(node, n_ia32_IMul_right);
+       /* Do we need the immediate form? */
+       if (is_ia32_Immediate(right)) {
+               int imm = get_ia32_immediate_attr_const(right)->offset;
+               if (get_signed_imm_size(imm) == 1) {
+                       bemit_unop_reg(node, 0x6B, n_ia32_IMul_left);
+                       bemit8(imm);
+               } else {
+                       bemit_unop_reg(node, 0x69, n_ia32_IMul_left);
+                       bemit32(imm);
+               }
+       } else {
+               bemit8(0x0F);
+               bemit_unop_reg(node, 0xAF, n_ia32_IMul_right);
+       }
+}
+
 static void bemit_dec(const ir_node *node)
 {
        const arch_register_t *out = get_out_reg(node, pn_ia32_Dec_res);
@@ -2749,6 +2876,32 @@ static void bemit_inc(const ir_node *node)
        bemit8(0x40 + reg_gp_map[out->index]);
 }
 
+#define UNOPMEM(op, code, ext) \
+static void bemit_##op(const ir_node *node) \
+{ \
+       bemit_unop_mem(node, code, ext); \
+}
+
+UNOPMEM(notmem, 0xF7, 2)
+UNOPMEM(negmem, 0xF7, 3)
+UNOPMEM(incmem, 0xFF, 0)
+UNOPMEM(decmem, 0xFF, 1)
+
+static void bemit_set(const ir_node *node)
+{
+       pn_Cmp pnc;
+
+       bemit8(0x0F);
+
+       pnc = get_ia32_condcode(node);
+       pnc = determine_final_pnc(node, n_ia32_Set_eflags, pnc);
+       if (get_ia32_attr_const(node)->data.ins_permuted)
+               pnc = ia32_get_negated_pnc(pnc);
+
+       bemit8(0x90 + pnc2cc(pnc));
+       bemit_modru(get_out_reg(node, pn_ia32_Set_res), 2);
+}
+
 /**
  * Emit a Lea.
  */
@@ -2760,7 +2913,7 @@ static void bemit_lea(const ir_node *node)
 }
 
 /**
- * Emit a single optcode.
+ * Emit a single opcode.
  */
 #define EMIT_SINGLEOP(op, code)                 \
 static void bemit_ ## op(const ir_node *node) { \
@@ -2773,7 +2926,7 @@ static void bemit_ ## op(const ir_node *node) { \
 //EMIT_SINGLEOP(aaa,  0x37)
 //EMIT_SINGLEOP(aas,  0x3F)
 //EMIT_SINGLEOP(nop,  0x90)
-//EMIT_SINGLEOP(cwde, 0x98)
+EMIT_SINGLEOP(cwtl, 0x98)
 EMIT_SINGLEOP(cltd, 0x99)
 //EMIT_SINGLEOP(fwait, 0x9B)
 EMIT_SINGLEOP(sahf, 0x9E)
@@ -2798,18 +2951,17 @@ static void bemit_load(const ir_node *node)
        const arch_register_t *out = get_out_reg(node, 0);
 
        if (out->index == REG_EAX) {
-               ir_entity *ent       = get_ia32_am_sc(node);
-               int        offs      = get_ia32_am_offs_int(node);
                ir_node   *base      = get_irn_n(node, n_ia32_base);
                int        has_base  = !is_ia32_NoReg_GP(base);
                ir_node   *index     = get_irn_n(node, n_ia32_index);
                int        has_index = !is_ia32_NoReg_GP(index);
-
-               if (ent == NULL && !has_base && !has_index) {
+               if (!has_base && !has_index) {
+                       ir_entity *ent  = get_ia32_am_sc(node);
+                       int        offs = get_ia32_am_offs_int(node);
                        /* load from constant address to EAX can be encoded
                           as 0xA1 [offset] */
                        bemit8(0xA1);
-                       bemit_entity(NULL, 0, offs, false);
+                       bemit_entity(ent, 0, offs, false);
                        return;
                }
        }
@@ -2823,35 +2975,75 @@ static void bemit_load(const ir_node *node)
 static void bemit_store(const ir_node *node)
 {
        const ir_node *value = get_irn_n(node, n_ia32_Store_val);
+       unsigned       size  = get_mode_size_bits(get_ia32_ls_mode(node));
 
        if (is_ia32_Immediate(value)) {
-               bemit8(0xC7);
-               bemit_mod_am(0, node);
-               bemit_immediate(value, false);
+               if (size == 8) {
+                       bemit8(0xC6);
+                       bemit_mod_am(0, node);
+                       bemit8(get_ia32_immediate_attr_const(value)->offset);
+               } else if (size == 16) {
+                       bemit8(0x66);
+                       bemit8(0xC7);
+                       bemit_mod_am(0, node);
+                       bemit16(get_ia32_immediate_attr_const(value)->offset);
+               } else {
+                       bemit8(0xC7);
+                       bemit_mod_am(0, node);
+                       bemit_immediate(value, false);
+               }
        } else {
                const arch_register_t *in = get_in_reg(node, n_ia32_Store_val);
 
                if (in->index == REG_EAX) {
-                       ir_entity *ent       = get_ia32_am_sc(node);
-                       int        offs      = get_ia32_am_offs_int(node);
                        ir_node   *base      = get_irn_n(node, n_ia32_base);
                        int        has_base  = !is_ia32_NoReg_GP(base);
                        ir_node   *index     = get_irn_n(node, n_ia32_index);
                        int        has_index = !is_ia32_NoReg_GP(index);
-
-                       if (ent == NULL && !has_base && !has_index) {
+                       if (!has_base && !has_index) {
+                               ir_entity *ent  = get_ia32_am_sc(node);
+                               int        offs = get_ia32_am_offs_int(node);
                                /* store to constant address from EAX can be encoded as
-                                  0xA3 [offset]*/
-                               bemit8(0xA3);
-                               bemit_entity(NULL, 0, offs, false);
+                                * 0xA2/0xA3 [offset]*/
+                               if (size == 8) {
+                                       bemit8(0xA2);
+                               } else {
+                                       if (size == 16)
+                                               bemit8(0x66);
+                                       bemit8(0xA3);
+                               }
+                               bemit_entity(ent, 0, offs, false);
                                return;
                        }
                }
-               bemit8(0x89);
+
+               if (size == 8) {
+                       bemit8(0x88);
+               } else {
+                       if (size == 16)
+                               bemit8(0x66);
+                       bemit8(0x89);
+               }
                bemit_mod_am(reg_gp_map[in->index], node);
        }
 }
 
+static void bemit_conv_i2i(const ir_node *node)
+{
+       ir_mode  *smaller_mode = get_ia32_ls_mode(node);
+       unsigned  opcode;
+
+       bemit8(0x0F);
+       /*        8 16 bit source
+        * movzx B6 B7
+        * movsx BE BF
+        */
+       opcode = 0xB6;
+       if (mode_is_signed(smaller_mode))           opcode |= 0x08;
+       if (get_mode_size_bits(smaller_mode) == 16) opcode |= 0x01;
+       bemit_unop_reg(node, opcode, n_ia32_Conv_I2I_val);
+}
+
 /**
  * Emit a Push.
  */
@@ -2908,12 +3100,7 @@ static void bemit_call(const ir_node *node)
                bemit8(0xE8);
                bemit_immediate(proc, true);
        } else {
-               bemit8(0xFF);
-               if (get_ia32_op_type(node) == ia32_Normal) {
-                       bemit_modru(get_in_reg(node, n_ia32_unary_op), 2);
-               } else {
-                       bemit_mod_am(2, node);
-               }
+               bemit_unop(node, 0xFF, 2, n_ia32_Call_addr);
        }
 }
 
@@ -2933,18 +3120,7 @@ static void bemit_jump(const ir_node *node)
 
 static void bemit_jcc(int pnc, const ir_node *dest_block)
 {
-       unsigned char cc;
-
-       if (pnc == ia32_pn_Cmp_parity) {
-               cc = 0x0A;
-       } else {
-               if (pnc & ia32_pn_Cmp_float || pnc & ia32_pn_Cmp_unsigned) {
-                       cc = pnc_map_unsigned[pnc & 0x07];
-               } else {
-                       cc = pnc_map_signed[pnc & 0x07];
-               }
-       }
-
+       unsigned char cc = pnc2cc(pnc);
        bemit8(0x0F);
        bemit8(0x80 + cc);
        bemit_jmp_destination(dest_block);
@@ -3101,59 +3277,81 @@ static void ia32_register_binary_emitters(void)
        clear_irp_opcodes_generic_func();
 
        /* benode emitter */
-       register_emitter(op_be_Copy, bemit_copy);
-       register_emitter(op_be_CopyKeep, bemit_copy);
-       register_emitter(op_be_IncSP, bemit_incsp);
-       register_emitter(op_be_Return, bemit_return);
-       register_emitter(op_ia32_Adc, bemit_adc);
-       register_emitter(op_ia32_Add, bemit_add);
-       register_emitter(op_ia32_And, bemit_and);
-       register_emitter(op_ia32_Breakpoint, bemit_int3);
-       register_emitter(op_ia32_Call, bemit_call);
-       register_emitter(op_ia32_Cltd, bemit_cltd);
-       register_emitter(op_ia32_Cmc, bemit_cmc);
-       register_emitter(op_ia32_Cmp, bemit_cmp);
-       register_emitter(op_ia32_Const, bemit_mov_const);
-       register_emitter(op_ia32_Dec, bemit_dec);
-       register_emitter(op_ia32_Div, bemit_div);
-       register_emitter(op_ia32_IDiv, bemit_idiv);
-       register_emitter(op_ia32_IJmp, bemit_ijmp);
-       register_emitter(op_ia32_IMul1OP, bemit_imul1op);
-       register_emitter(op_ia32_Inc, bemit_inc);
-       register_emitter(op_ia32_Jcc, bemit_ia32_jcc);
-       register_emitter(op_ia32_Jmp, bemit_jump);
-       register_emitter(op_ia32_Lea, bemit_lea);
-       register_emitter(op_ia32_Load, bemit_load);
-       register_emitter(op_ia32_Mul, bemit_mul);
-       register_emitter(op_ia32_Neg, bemit_neg);
-       register_emitter(op_ia32_Not, bemit_not);
-       register_emitter(op_ia32_Or, bemit_or);
-       register_emitter(op_ia32_Pop, bemit_pop);
-       register_emitter(op_ia32_PopEbp, bemit_pop);
-       register_emitter(op_ia32_PopMem, bemit_popmem);
-       register_emitter(op_ia32_Push, bemit_push);
-       register_emitter(op_ia32_RepPrefix, bemit_rep);
-       register_emitter(op_ia32_Rol, bemit_rol);
-       register_emitter(op_ia32_Ror, bemit_ror);
-       register_emitter(op_ia32_Sahf, bemit_sahf);
-       register_emitter(op_ia32_Sar, bemit_sar);
-       register_emitter(op_ia32_Sbb, bemit_sbb);
-       register_emitter(op_ia32_Shl, bemit_shl);
-       register_emitter(op_ia32_Shr, bemit_shr);
-       register_emitter(op_ia32_Stc, bemit_stc);
-       register_emitter(op_ia32_Store, bemit_store);
-       register_emitter(op_ia32_Sub, bemit_sub);
-       register_emitter(op_ia32_Test, bemit_test);
-       register_emitter(op_ia32_Xor, bemit_xor);
-       register_emitter(op_ia32_Xor0, bemit_xor0);
+       register_emitter(op_be_Copy,           bemit_copy);
+       register_emitter(op_be_CopyKeep,       bemit_copy);
+       register_emitter(op_be_IncSP,          bemit_incsp);
+       register_emitter(op_be_Perm,           bemit_perm);
+       register_emitter(op_be_Return,         bemit_return);
+       register_emitter(op_ia32_Adc,          bemit_adc);
+       register_emitter(op_ia32_Add,          bemit_add);
+       register_emitter(op_ia32_AddMem8Bit,   bemit_addmem8bit);
+       register_emitter(op_ia32_AddMem,       bemit_addmem);
+       register_emitter(op_ia32_And,          bemit_and);
+       register_emitter(op_ia32_AndMem8Bit,   bemit_andmem8bit);
+       register_emitter(op_ia32_AndMem,       bemit_andmem);
+       register_emitter(op_ia32_Breakpoint,   bemit_int3);
+       register_emitter(op_ia32_Call,         bemit_call);
+       register_emitter(op_ia32_Cltd,         bemit_cltd);
+       register_emitter(op_ia32_Cmc,          bemit_cmc);
+       register_emitter(op_ia32_Cmp8Bit,      bemit_cmp8bit);
+       register_emitter(op_ia32_Cmp,          bemit_cmp);
+       register_emitter(op_ia32_Const,        bemit_mov_const);
+       register_emitter(op_ia32_Conv_I2I8Bit, bemit_conv_i2i);
+       register_emitter(op_ia32_Conv_I2I,     bemit_conv_i2i);
+       register_emitter(op_ia32_Cwtl,         bemit_cwtl);
+       register_emitter(op_ia32_Dec,          bemit_dec);
+       register_emitter(op_ia32_DecMem,       bemit_decmem);
+       register_emitter(op_ia32_Div,          bemit_div);
+       register_emitter(op_ia32_IDiv,         bemit_idiv);
+       register_emitter(op_ia32_IJmp,         bemit_ijmp);
+       register_emitter(op_ia32_IMul1OP,      bemit_imul1op);
+       register_emitter(op_ia32_IMul,         bemit_imul);
+       register_emitter(op_ia32_Inc,          bemit_inc);
+       register_emitter(op_ia32_IncMem,       bemit_incmem);
+       register_emitter(op_ia32_Jcc,          bemit_ia32_jcc);
+       register_emitter(op_ia32_Jmp,          bemit_jump);
+       register_emitter(op_ia32_Lea,          bemit_lea);
+       register_emitter(op_ia32_Load,         bemit_load);
+       register_emitter(op_ia32_Mul,          bemit_mul);
+       register_emitter(op_ia32_Neg,          bemit_neg);
+       register_emitter(op_ia32_NegMem,       bemit_negmem);
+       register_emitter(op_ia32_Not,          bemit_not);
+       register_emitter(op_ia32_NotMem,       bemit_notmem);
+       register_emitter(op_ia32_Or,           bemit_or);
+       register_emitter(op_ia32_OrMem8Bit,    bemit_ormem8bit);
+       register_emitter(op_ia32_OrMem,        bemit_ormem);
+       register_emitter(op_ia32_Pop,          bemit_pop);
+       register_emitter(op_ia32_PopEbp,       bemit_pop);
+       register_emitter(op_ia32_PopMem,       bemit_popmem);
+       register_emitter(op_ia32_Push,         bemit_push);
+       register_emitter(op_ia32_RepPrefix,    bemit_rep);
+       register_emitter(op_ia32_Rol,          bemit_rol);
+       register_emitter(op_ia32_Ror,          bemit_ror);
+       register_emitter(op_ia32_Sahf,         bemit_sahf);
+       register_emitter(op_ia32_Sar,          bemit_sar);
+       register_emitter(op_ia32_Sbb,          bemit_sbb);
+       register_emitter(op_ia32_Set,          bemit_set);
+       register_emitter(op_ia32_Shl,          bemit_shl);
+       register_emitter(op_ia32_Shr,          bemit_shr);
+       register_emitter(op_ia32_Stc,          bemit_stc);
+       register_emitter(op_ia32_Store8Bit,    bemit_store);
+       register_emitter(op_ia32_Store,        bemit_store);
+       register_emitter(op_ia32_Sub,          bemit_sub);
+       register_emitter(op_ia32_SubMem8Bit,   bemit_submem8bit);
+       register_emitter(op_ia32_SubMem,       bemit_submem);
+       register_emitter(op_ia32_Test,         bemit_test);
+       register_emitter(op_ia32_Xor0,         bemit_xor0);
+       register_emitter(op_ia32_Xor,          bemit_xor);
+       register_emitter(op_ia32_XorMem8Bit,   bemit_xormem8bit);
+       register_emitter(op_ia32_XorMem,       bemit_xormem);
 
        /* ignore the following nodes */
-       register_emitter(op_ia32_ProduceVal, emit_Nothing);
-       register_emitter(op_be_Barrier, emit_Nothing);
-       register_emitter(op_be_Keep, emit_Nothing);
-       register_emitter(op_be_Start, emit_Nothing);
-       register_emitter(op_Phi, emit_Nothing);
-       register_emitter(op_Start, emit_Nothing);
+       register_emitter(op_ia32_ProduceVal,   emit_Nothing);
+       register_emitter(op_be_Barrier,        emit_Nothing);
+       register_emitter(op_be_Keep,           emit_Nothing);
+       register_emitter(op_be_Start,          emit_Nothing);
+       register_emitter(op_Phi,               emit_Nothing);
+       register_emitter(op_Start,             emit_Nothing);
 }
 
 static void gen_binary_block(ir_node *block)