X-Git-Url: http://nsz.repo.hu/git/?a=blobdiff_plain;f=ir%2Fbe%2Fia32%2Fia32_emitter.c;h=385611b108ce29db11042d4a8d56a100dfbfcc5e;hb=3e49de2f9c8d52f5a6efc55a9e20f4992557d471;hp=bbbf7785fbf55042d66f61664f265faf2fe66379;hpb=2b31fff481c9cb3a16ca4a0dc3b15bad3e19e5ec;p=libfirm diff --git a/ir/be/ia32/ia32_emitter.c b/ir/be/ia32/ia32_emitter.c index bbbf7785f..385611b10 100644 --- a/ir/be/ia32/ia32_emitter.c +++ b/ir/be/ia32/ia32_emitter.c @@ -629,6 +629,7 @@ emit_I: } else if ('0' <= *fmt && *fmt <= '9') { cc = get_ia32_condcode(node); cc = determine_final_cc(node, *fmt - '0', cc); + ++fmt; } else { goto unknown; } @@ -1559,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; @@ -2210,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); @@ -2322,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); \ } \ } \ \ @@ -2335,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); \ } \ } @@ -2493,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); @@ -2676,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); } } @@ -2950,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); } /** @@ -3230,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; @@ -3395,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) @@ -3537,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); } /** @@ -3574,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); @@ -3680,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);