Factorise code for binary emitters of ia32 fp operation with fp register.
[libfirm] / ir / be / ia32 / ia32_emitter.c
index 221b055..385611b 100644 (file)
@@ -1560,27 +1560,23 @@ static void ia32_emit_align_label(void)
 static int should_align_block(const ir_node *block)
 {
        static const double DELTA = .0001;
-       ir_graph     *irg         = get_irn_irg(block);
-       ir_exec_freq *exec_freq   = be_get_irg_exec_freq(irg);
-       ir_node      *prev        = get_prev_block_sched(block);
-       double        block_freq;
-       double        prev_freq = 0;  /**< execfreq of the fallthrough block */
-       double        jmp_freq  = 0;  /**< execfreq of all non-fallthrough blocks */
-       int           i, n_cfgpreds;
-
-       if (exec_freq == NULL)
-               return 0;
+       ir_node *prev      = get_prev_block_sched(block);
+       double   prev_freq = 0;  /**< execfreq of the fallthrough block */
+       double   jmp_freq  = 0;  /**< execfreq of all non-fallthrough blocks */
+       double   block_freq;
+       int      i, n_cfgpreds;
+
        if (ia32_cg_config.label_alignment_factor <= 0)
                return 0;
 
-       block_freq = get_block_execfreq(exec_freq, block);
+       block_freq = get_block_execfreq(block);
        if (block_freq < DELTA)
                return 0;
 
        n_cfgpreds = get_Block_n_cfgpreds(block);
        for (i = 0; i < n_cfgpreds; ++i) {
                const ir_node *pred      = get_Block_cfgpred_block(block, i);
-               double         pred_freq = get_block_execfreq(exec_freq, pred);
+               double         pred_freq = get_block_execfreq(pred);
 
                if (pred == prev) {
                        prev_freq += pred_freq;
@@ -2211,6 +2207,12 @@ static void bemit_unop_mem(const ir_node *node, unsigned char code, unsigned cha
        bemit_mod_am(ext, node);
 }
 
+static void bemit_0f_unop_reg(ir_node const *const node, unsigned char const code, int const input)
+{
+       bemit8(0x0F);
+       bemit_unop_reg(node, code, input);
+}
+
 static void bemit_immediate(const ir_node *node, bool relative)
 {
        const ia32_immediate_attr_t *attr = get_ia32_immediate_attr_const(node);
@@ -2323,7 +2325,7 @@ static void bemit_##op(const ir_node *node) \
                } \
        } else { \
                bemit8(ext << 3 | 1); \
-               bemit_mod_am(reg_gp_map[arch_get_irn_register_out(val, 0)->index], node); \
+               bemit_mod_am(reg_gp_map[arch_get_irn_register(val)->index], node); \
        } \
 } \
  \
@@ -2336,7 +2338,7 @@ static void bemit_##op##8bit(const ir_node *node) \
                bemit8(get_ia32_immediate_attr_const(val)->offset); \
        } else { \
                bemit8(ext << 3); \
-               bemit_mod_am(reg_gp_map[arch_get_irn_register_out(val, 0)->index], node); \
+               bemit_mod_am(reg_gp_map[arch_get_irn_register(val)->index], node); \
        } \
 }
 
@@ -2494,6 +2496,16 @@ static void bemit_setcc(const ir_node *node)
        }
 }
 
+static void bemit_bsf(ir_node const *const node)
+{
+       bemit_0f_unop_reg(node, 0xBC, n_ia32_Bsf_operand);
+}
+
+static void bemit_bsr(ir_node const *const node)
+{
+       bemit_0f_unop_reg(node, 0xBD, n_ia32_Bsr_operand);
+}
+
 static void bemit_cmovcc(const ir_node *node)
 {
        const ia32_attr_t     *attr         = get_ia32_attr_const(node);
@@ -2677,8 +2689,7 @@ static void bemit_imul(const ir_node *node)
                        bemit32(imm);
                }
        } else {
-               bemit8(0x0F);
-               bemit_unop_reg(node, 0xAF, n_ia32_IMul_right);
+               bemit_0f_unop_reg(node, 0xAF, n_ia32_IMul_right);
        }
 }
 
@@ -2951,18 +2962,14 @@ static void bemit_store(const ir_node *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;
+        * movsx BE BF */
+       ir_mode *const smaller_mode = get_ia32_ls_mode(node);
+       unsigned       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);
+       bemit_0f_unop_reg(node, opcode, n_ia32_Conv_I2I_val);
 }
 
 /**
@@ -3231,6 +3238,12 @@ static void bemit_fbinopp(const ir_node *node, unsigned const code)
        bemit8(code + out->index);
 }
 
+static void bemit_fop_reg(ir_node const *const node, unsigned char const op0, unsigned char const op1)
+{
+       bemit8(op0);
+       bemit8(op1 + get_ia32_x87_attr_const(node)->x87[0]->index);
+}
+
 static void bemit_fabs(const ir_node *node)
 {
        (void)node;
@@ -3396,23 +3409,17 @@ static void bemit_fmulp(const ir_node *node)
 
 static void bemit_fpop(const ir_node *node)
 {
-       const ia32_x87_attr_t *attr = get_ia32_x87_attr_const(node);
-       bemit8(0xDD);
-       bemit8(0xD8 + attr->x87[0]->index);
+       bemit_fop_reg(node, 0xDD, 0xD8);
 }
 
 static void bemit_fpush(const ir_node *node)
 {
-       const ia32_x87_attr_t *attr = get_ia32_x87_attr_const(node);
-       bemit8(0xD9);
-       bemit8(0xC0 + attr->x87[0]->index);
+       bemit_fop_reg(node, 0xD9, 0xC0);
 }
 
 static void bemit_fpushcopy(const ir_node *node)
 {
-       const ia32_x87_attr_t *attr = get_ia32_x87_attr_const(node);
-       bemit8(0xD9);
-       bemit8(0xC0 + attr->x87[0]->index);
+       bemit_fop_reg(node, 0xD9, 0xC0);
 }
 
 static void bemit_fst(const ir_node *node)
@@ -3538,9 +3545,7 @@ static void bemit_fucomppfnstsw(const ir_node *node)
 
 static void bemit_fxch(const ir_node *node)
 {
-       const ia32_x87_attr_t *attr = get_ia32_x87_attr_const(node);
-       bemit8(0xD9);
-       bemit8(0xC8 + attr->x87[0]->index);
+       bemit_fop_reg(node, 0xD9, 0xC8);
 }
 
 /**
@@ -3575,6 +3580,8 @@ static void ia32_register_binary_emitters(void)
        register_emitter(op_ia32_AndMem,        bemit_andmem);
        register_emitter(op_ia32_AndMem8Bit,    bemit_andmem8bit);
        register_emitter(op_ia32_Breakpoint,    bemit_int3);
+       register_emitter(op_ia32_Bsf,           bemit_bsf);
+       register_emitter(op_ia32_Bsr,           bemit_bsr);
        register_emitter(op_ia32_CMovcc,        bemit_cmovcc);
        register_emitter(op_ia32_Call,          bemit_call);
        register_emitter(op_ia32_Cltd,          bemit_cltd);
@@ -3681,6 +3688,7 @@ static void ia32_register_binary_emitters(void)
 
        /* ignore the following nodes */
        register_emitter(op_ia32_ProduceVal,   emit_Nothing);
+       register_emitter(op_ia32_Unknown,      emit_Nothing);
        register_emitter(op_be_Keep,           emit_Nothing);
        register_emitter(op_be_Start,          emit_Nothing);
        register_emitter(op_Phi,               emit_Nothing);