From: Christoph Mallon Date: Thu, 6 Nov 2008 10:56:19 +0000 (+0000) Subject: The K6 does not like cltd and cwtl. X-Git-Url: http://nsz.repo.hu/git/?a=commitdiff_plain;h=ff28a84d47af32824433a98405fa4c1a7a106309;p=libfirm The K6 does not like cltd and cwtl. [r23473] --- diff --git a/ir/be/ia32/ia32_architecture.c b/ir/be/ia32/ia32_architecture.c index cb729aac4..ecffa9229 100644 --- a/ir/be/ia32/ia32_architecture.c +++ b/ir/be/ia32/ia32_architecture.c @@ -493,6 +493,7 @@ void ia32_setup_cg_config(void) c->use_imul_mem_imm32 = !FLAGS(opt_arch, arch_k8 | arch_k10) || opt_size; c->use_pxor = FLAGS(opt_arch, arch_netburst); c->use_mov_0 = FLAGS(opt_arch, arch_k6) && !opt_size; + c->use_short_sex_eax = !FLAGS(opt_arch, arch_k6) && !opt_size; c->use_pad_return = FLAGS(opt_arch, arch_athlon_plus | arch_core2 | arch_generic32) && !opt_size; c->use_bt = FLAGS(opt_arch, arch_core2 | arch_athlon_plus) || opt_size; c->use_fisttp = FLAGS(opt_arch & arch, arch_feature_sse3); diff --git a/ir/be/ia32/ia32_architecture.h b/ir/be/ia32/ia32_architecture.h index e6c2efd3e..b9a7a5eb9 100644 --- a/ir/be/ia32/ia32_architecture.h +++ b/ir/be/ia32/ia32_architecture.h @@ -63,6 +63,8 @@ typedef struct { unsigned use_pxor:1; /** use mov reg, 0 instruction */ unsigned use_mov_0:1; + /** use cwtl/cltd, which are shorter, to sign extend ax/eax */ + unsigned use_short_sex_eax:1; /** pad Ret instructions that are destination of conditional jump or directly preceded by other jump instruction. */ unsigned use_pad_return:1; diff --git a/ir/be/ia32/ia32_emitter.c b/ir/be/ia32/ia32_emitter.c index a03d7ae2f..7f88a8301 100644 --- a/ir/be/ia32/ia32_emitter.c +++ b/ir/be/ia32/ia32_emitter.c @@ -1529,9 +1529,10 @@ static void emit_ia32_Conv_I2I(const ir_node *node) assert(smaller_bits == 8 || smaller_bits == 16); const arch_register_t *eax = &ia32_gp_regs[REG_EAX]; - if (signed_mode && - smaller_bits == 16 && - eax == get_out_reg(node, 0) && + if (signed_mode && + smaller_bits == 16 && + ia32_cg_config.use_short_sex_eax && + eax == get_out_reg(node, 0) && eax == arch_get_irn_register(get_irn_n(node, n_ia32_unary_op))) { /* argument and result are both in EAX and signedness is ok: use the * smaller cwtl opcode */ diff --git a/ir/be/ia32/ia32_transform.c b/ir/be/ia32/ia32_transform.c index 00007f8a0..ff955f3e3 100644 --- a/ir/be/ia32/ia32_transform.c +++ b/ir/be/ia32/ia32_transform.c @@ -1337,6 +1337,19 @@ static ir_node *transform_AM_mem(ir_graph *const irg, ir_node *const block, } } +static ir_node *create_sex_32_64(dbg_info *dbgi, ir_graph *irg, ir_node *block, + ir_node *val) +{ + if (ia32_cg_config.use_short_sex_eax) { + ir_node *pval = new_rd_ia32_ProduceVal(dbgi, irg, block); + be_dep_on_frame(pval); + return new_rd_ia32_Cltd(dbgi, irg, block, val, pval); + } else { + ir_node *imm31 = create_Immediate(NULL, 0, 31); + return new_rd_ia32_Sar(dbgi, irg, block, val, imm31); + } +} + /** * Generates an ia32 DivMod with additional infrastructure for the * register allocator if needed. @@ -1389,14 +1402,9 @@ static ir_node *create_Div(ir_node *node) new_mem = transform_AM_mem(irg, block, op2, mem, addr->mem); if (mode_is_signed(mode)) { - ir_node *produceval = new_rd_ia32_ProduceVal(dbgi, irg, new_block); - be_dep_on_frame(produceval); - sign_extension = new_rd_ia32_Cltd(dbgi, irg, new_block, am.new_op1, - produceval); - - new_node = new_rd_ia32_IDiv(dbgi, irg, new_block, addr->base, - addr->index, new_mem, am.new_op2, - am.new_op1, sign_extension); + sign_extension = create_sex_32_64(dbgi, irg, new_block, am.new_op1); + new_node = new_rd_ia32_IDiv(dbgi, irg, new_block, addr->base, + addr->index, new_mem, am.new_op2, am.new_op1, sign_extension); } else { sign_extension = new_rd_ia32_Const(dbgi, irg, new_block, NULL, 0, 0); be_dep_on_frame(sign_extension); @@ -1497,15 +1505,11 @@ static ir_node *gen_Shrs(ir_node *node) long val = get_tarval_long(tv); if (val == 31) { /* this is a sign extension */ - ir_graph *irg = current_ir_graph; dbg_info *dbgi = get_irn_dbg_info(node); ir_node *block = be_transform_node(get_nodes_block(node)); - ir_node *op = left; - ir_node *new_op = be_transform_node(op); - ir_node *pval = new_rd_ia32_ProduceVal(dbgi, irg, block); + ir_node *new_op = be_transform_node(left); - be_dep_on_frame(pval); - return new_rd_ia32_Cltd(dbgi, irg, block, new_op, pval); + return create_sex_32_64(dbgi, current_ir_graph, block, new_op); } } @@ -1724,7 +1728,7 @@ static ir_node *gen_Abs(ir_node *node) SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node)); } } else { - ir_node *xor, *pval, *sign_extension; + ir_node *xor, *sign_extension; if (get_mode_size_bits(mode) == 32) { new_op = be_transform_node(op); @@ -1732,12 +1736,8 @@ static ir_node *gen_Abs(ir_node *node) new_op = create_I2I_Conv(mode, mode_Is, dbgi, block, op, node); } - pval = new_rd_ia32_ProduceVal(dbgi, irg, new_block); - sign_extension = new_rd_ia32_Cltd(dbgi, irg, new_block, - new_op, pval); - - be_dep_on_frame(pval); - SET_IA32_ORIG_NODE(sign_extension,ia32_get_old_node_name(env_cg, node)); + sign_extension = create_sex_32_64(dbgi, irg, new_op, new_op); + SET_IA32_ORIG_NODE(sign_extension, ia32_get_old_node_name(env_cg, node)); xor = new_rd_ia32_Xor(dbgi, irg, new_block, noreg_gp, noreg_gp, nomem, new_op, sign_extension);