From b77d3a47774fd137aa76b086339fe2394dc84477 Mon Sep 17 00:00:00 2001 From: Matthias Braun Date: Fri, 19 Oct 2007 11:10:56 +0000 Subject: [PATCH] - improve set transformation - create SetMems - support 3 operand IMul - started writing a new incsp->store to push peephole phase [r16273] --- ir/be/ia32/bearch_ia32.c | 9 +- ir/be/ia32/ia32_emitter.c | 21 ++++ ir/be/ia32/ia32_finish.c | 7 ++ ir/be/ia32/ia32_new_nodes.c | 5 - ir/be/ia32/ia32_optimize.c | 126 +++++++++++++++++------ ir/be/ia32/ia32_spec.pl | 23 ++++- ir/be/ia32/ia32_transform.c | 197 +++++++++++++++++++++++++++--------- 7 files changed, 299 insertions(+), 89 deletions(-) diff --git a/ir/be/ia32/bearch_ia32.c b/ir/be/ia32/bearch_ia32.c index b9b4e9bd3..2df148316 100644 --- a/ir/be/ia32/bearch_ia32.c +++ b/ir/be/ia32/bearch_ia32.c @@ -906,7 +906,7 @@ static const arch_irn_ops_if_t ia32_irn_ops_if = { ia32_perform_memory_operand, }; -ia32_irn_ops_t ia32_irn_ops = { +static ia32_irn_ops_t ia32_irn_ops = { &ia32_irn_ops_if, NULL }; @@ -925,9 +925,14 @@ ia32_irn_ops_t ia32_irn_ops = { **************************************************/ static void ia32_before_abi(void *self) { + lower_mode_b_config_t lower_mode_b_config = { + mode_Iu, /* lowered mode */ + mode_Bu, /* prefered mode for set */ + 0, /* don't lower direct compares */ + }; ia32_code_gen_t *cg = self; - ir_lower_mode_b(cg->irg, mode_Iu, 0); + ir_lower_mode_b(cg->irg, &lower_mode_b_config); if(cg->dump) be_dump(cg->irg, "-lower_modeb", dump_ir_block_graph_sched); } diff --git a/ir/be/ia32/ia32_emitter.c b/ir/be/ia32/ia32_emitter.c index 66562b0be..603c77be0 100644 --- a/ir/be/ia32/ia32_emitter.c +++ b/ir/be/ia32/ia32_emitter.c @@ -563,6 +563,26 @@ void ia32_emit_am(const ir_node *node) { } } +static void emit_ia32_IMul(const ir_node *node) +{ + ir_node *left = get_irn_n(node, n_ia32_IMul_left); + const arch_register_t *out_reg = get_out_reg(node, pn_ia32_IMul_res); + + be_emit_cstring("\timul"); + ia32_emit_mode_suffix(node); + be_emit_char(' '); + + ia32_emit_binop(node); + + /* do we need the 3-address form? */ + if(is_ia32_NoReg_GP(left) || + get_in_reg(node, n_ia32_IMul_left) != out_reg) { + be_emit_cstring(", "); + emit_register(out_reg, get_ia32_ls_mode(node)); + } + be_emit_finish_line_gas(node); +} + /************************************************* * _ _ _ * (_) | | | @@ -1838,6 +1858,7 @@ void ia32_register_emitters(void) { /* other ia32 emitter functions */ IA32_EMIT(Asm); IA32_EMIT(CMov); + IA32_EMIT(IMul); IA32_EMIT(SwitchJmp); IA32_EMIT(CopyB); IA32_EMIT(CopyB_i); diff --git a/ir/be/ia32/ia32_finish.c b/ir/be/ia32/ia32_finish.c index 5306d62a5..6cb689959 100644 --- a/ir/be/ia32/ia32_finish.c +++ b/ir/be/ia32/ia32_finish.c @@ -142,6 +142,13 @@ static void ia32_transform_sub_to_neg_add(ir_node *irn, ia32_code_gen_t *cg) { } static INLINE int need_constraint_copy(ir_node *irn) { + /* the 3 operand form of IMul needs no constraint copy */ + if(is_ia32_IMul(irn)) { + ir_node *right = get_irn_n(irn, n_ia32_IMul_right); + if(is_ia32_Immediate(right)) + return 0; + } + return ! is_ia32_Lea(irn) && ! is_ia32_Conv_I2I(irn) && ! is_ia32_Conv_I2I8Bit(irn) && diff --git a/ir/be/ia32/ia32_new_nodes.c b/ir/be/ia32/ia32_new_nodes.c index 9d0360985..5b53ed969 100644 --- a/ir/be/ia32/ia32_new_nodes.c +++ b/ir/be/ia32/ia32_new_nodes.c @@ -411,7 +411,6 @@ const ia32_immediate_attr_t *get_ia32_immediate_attr_const(const ir_node *node) const ia32_attr_t *attr = get_ia32_attr_const(node); const ia32_immediate_attr_t *imm_attr = CONST_CAST_IA32_ATTR(ia32_immediate_attr_t, attr); - assert(is_ia32_Immediate(node) || is_ia32_Const(node)); return imm_attr; } @@ -419,7 +418,6 @@ ia32_condcode_attr_t *get_ia32_condcode_attr(ir_node *node) { ia32_attr_t *attr = get_ia32_attr(node); ia32_condcode_attr_t *cc_attr = CAST_IA32_ATTR(ia32_condcode_attr_t, attr); - assert(is_ia32_SwitchJmp(node) || is_ia32_CMov(node) || is_ia32_Set(node) || is_ia32_Jcc(node)); return cc_attr; } @@ -427,7 +425,6 @@ const ia32_condcode_attr_t *get_ia32_condcode_attr_const(const ir_node *node) { const ia32_attr_t *attr = get_ia32_attr_const(node); const ia32_condcode_attr_t *cc_attr = CONST_CAST_IA32_ATTR(ia32_condcode_attr_t, attr); - assert(is_ia32_SwitchJmp(node) || is_ia32_CMov(node) || is_ia32_Set(node) || is_ia32_Jcc(node)); return cc_attr; } @@ -435,7 +432,6 @@ ia32_copyb_attr_t *get_ia32_copyb_attr(ir_node *node) { ia32_attr_t *attr = get_ia32_attr(node); ia32_copyb_attr_t *copyb_attr = CAST_IA32_ATTR(ia32_copyb_attr_t, attr); - assert(is_ia32_CopyB(node) || is_ia32_CopyB_i(node)); return copyb_attr; } @@ -443,7 +439,6 @@ const ia32_copyb_attr_t *get_ia32_copyb_attr_const(const ir_node *node) { const ia32_attr_t *attr = get_ia32_attr_const(node); const ia32_copyb_attr_t *copyb_attr = CONST_CAST_IA32_ATTR(ia32_copyb_attr_t, attr); - assert(is_ia32_CopyB(node) || is_ia32_CopyB_i(node)); return copyb_attr; } diff --git a/ir/be/ia32/ia32_optimize.c b/ir/be/ia32/ia32_optimize.c index 45295ceb9..f9ddc32ef 100644 --- a/ir/be/ia32/ia32_optimize.c +++ b/ir/be/ia32/ia32_optimize.c @@ -39,6 +39,7 @@ #include "height.h" #include "irbitset.h" #include "irprintf.h" +#include "error.h" #include "../be_t.h" #include "../beabi.h" @@ -59,30 +60,82 @@ DEBUG_ONLY(static firm_dbg_module_t *dbg = NULL;) static const arch_env_t *arch_env; static ia32_code_gen_t *cg; -typedef int is_op_func_t(const ir_node *n); -typedef ir_node *load_func_t(dbg_info *db, ir_graph *irg, ir_node *block, ir_node *base, ir_node *index, ir_node *mem); +static void peephole_IncSP_IncSP(ir_node *node); -/** - * checks if a node represents the NOREG value - */ -static INLINE int be_is_NoReg(ia32_code_gen_t *cg, const ir_node *irn) { - return irn == cg->noreg_gp || irn == cg->noreg_xmm || irn == cg->noreg_vfp; -} +#if 0 +static void peephole_ia32_Store_IncSP_to_push(ir_node *node) +{ + ir_node *base = get_irn_n(node, n_ia32_Store_base); + ir_node *index = get_irn_n(node, n_ia32_Store_index); + ir_node *mem = get_irn_n(node, n_ia32_Store_mem); + ir_node *incsp = base; + ir_node *val; + ir_node *noreg; + ir_graph *irg; + ir_node *block; + dbg_info *dbgi; + ir_mode *mode; + ir_node *push; + ir_node *proj; + int offset; + int node_offset; + + /* nomem inidicates the store doesn't alias with anything else */ + if(!is_NoMem(mem)) + return; -/******************************************************************************************************** - * _____ _ _ ____ _ _ _ _ _ - * | __ \ | | | | / __ \ | | (_) (_) | | (_) - * | |__) |__ ___ _ __ | |__ ___ | | ___ | | | |_ __ | |_ _ _ __ ___ _ ______ _| |_ _ ___ _ __ - * | ___/ _ \/ _ \ '_ \| '_ \ / _ \| |/ _ \ | | | | '_ \| __| | '_ ` _ \| |_ / _` | __| |/ _ \| '_ \ - * | | | __/ __/ |_) | | | | (_) | | __/ | |__| | |_) | |_| | | | | | | |/ / (_| | |_| | (_) | | | | - * |_| \___|\___| .__/|_| |_|\___/|_|\___| \____/| .__/ \__|_|_| |_| |_|_/___\__,_|\__|_|\___/|_| |_| - * | | | | - * |_| |_| - ********************************************************************************************************/ + /* find an IncSP in front of us, we might have to skip barriers for this */ + while(is_Proj(incsp)) { + ir_node *proj_pred = get_Proj_pred(incsp); + if(!be_is_Barrier(proj_pred)) + return; + incsp = get_irn_n(proj_pred, get_Proj_proj(incsp)); + } + if(!be_is_IncSP(incsp)) + return; -/** - * NOTE: THESE PEEPHOLE OPTIMIZATIONS MUST BE CALLED AFTER SCHEDULING AND REGISTER ALLOCATION. - */ + peephole_IncSP_IncSP(incsp); + + /* must be in the same block */ + if(get_nodes_block(incsp) != get_nodes_block(node)) + return; + + if(!is_ia32_NoReg_GP(index) || get_ia32_am_sc(node) != NULL) { + panic("Invalid storeAM found (%+F)", node); + } + + /* we should be the store to the end of the stackspace */ + offset = be_get_IncSP_offset(incsp); + mode = get_ia32_ls_mode(node); + node_offset = get_ia32_am_offs_int(node); + if(node_offset != offset - get_mode_size_bytes(mode)) + return; + + /* we can use a push instead of the store */ + irg = current_ir_graph; + block = get_nodes_block(node); + dbgi = get_irn_dbg_info(node); + noreg = ia32_new_NoReg_gp(cg); + base = be_get_IncSP_pred(incsp); + val = get_irn_n(node, n_ia32_Store_val); + push = new_rd_ia32_Push(dbgi, irg, block, noreg, noreg, mem, base, val); + + proj = new_r_Proj(irg, block, push, mode_M, pn_ia32_Push_M); + + be_set_IncSP_offset(incsp, offset - get_mode_size_bytes(mode)); + + sched_add_before(node, push); + sched_remove(node); + + be_peephole_node_replaced(node, proj); + exchange(node, proj); +} + +static void peephole_ia32_Store(ir_node *node) +{ + peephole_ia32_Store_IncSP_to_push(node); +} +#endif // only optimize up to 48 stores behind IncSPs #define MAXPUSH_OPTIMIZE 48 @@ -179,8 +232,6 @@ static void peephole_IncSP_Store_to_push(ir_node *irn) push = new_rd_ia32_Push(get_irn_dbg_info(store), irg, block, noreg, noreg, mem, curr_sp, val); - set_ia32_am_support(push, ia32_am_Source, ia32_am_unary); - sched_add_before(irn, push); // create stackpointer proj @@ -604,6 +655,7 @@ void ia32_peephole_optimization(ia32_code_gen_t *new_cg) /* register peephole optimisations */ clear_irp_opcodes_generic_func(); register_peephole_optimisation(op_ia32_Const, peephole_ia32_Const); + //register_peephole_optimisation(op_ia32_Store, peephole_ia32_Store); register_peephole_optimisation(op_be_IncSP, peephole_be_IncSP); register_peephole_optimisation(op_ia32_Lea, peephole_ia32_Lea); @@ -638,15 +690,24 @@ static INLINE void try_kill(ir_node *node) static void optimize_conv_store(ir_node *node) { ir_node *pred; + ir_node *pred_proj; ir_mode *conv_mode; ir_mode *store_mode; if(!is_ia32_Store(node) && !is_ia32_Store8Bit(node)) return; - pred = get_irn_n(node, 2); + assert(n_ia32_Store_val == n_ia32_Store8Bit_val); + pred_proj = get_irn_n(node, n_ia32_Store_val); + if(is_Proj(pred_proj)) { + pred = get_Proj_pred(pred_proj); + } else { + pred = pred_proj; + } if(!is_ia32_Conv_I2I(pred) && !is_ia32_Conv_I2I8Bit(pred)) return; + if(get_ia32_op_type(pred) != ia32_Normal) + return; /* the store only stores the lower bits, so we only need the conv * it it shrinks the mode */ @@ -655,9 +716,11 @@ static void optimize_conv_store(ir_node *node) if(get_mode_size_bits(conv_mode) < get_mode_size_bits(store_mode)) return; - set_irn_n(node, 2, get_irn_n(pred, 2)); - if(get_irn_n_edges(pred) == 0) { - be_kill_node(pred); + set_irn_n(node, n_ia32_Store_val, get_irn_n(pred, n_ia32_Conv_I2I_val)); + if(get_irn_n_edges(pred_proj) == 0) { + be_kill_node(pred_proj); + if(pred != pred_proj) + be_kill_node(pred); } } @@ -670,7 +733,8 @@ static void optimize_load_conv(ir_node *node) if (!is_ia32_Conv_I2I(node) && !is_ia32_Conv_I2I8Bit(node)) return; - pred = get_irn_n(node, 2); + assert(n_ia32_Conv_I2I_val == n_ia32_Conv_I2I8Bit_val); + pred = get_irn_n(node, n_ia32_Conv_I2I_val); if(!is_Proj(pred)) return; @@ -780,8 +844,10 @@ static void optimize_conv_conv(ir_node *node) /* kill the conv */ exchange(node, result_conv); - if(get_irn_n_edges(pred) == 0) { - be_kill_node(pred); + if(get_irn_n_edges(pred_proj) == 0) { + be_kill_node(pred_proj); + if(pred != pred_proj) + be_kill_node(pred); } optimize_conv_conv(result_conv); } diff --git a/ir/be/ia32/ia32_spec.pl b/ir/be/ia32/ia32_spec.pl index 805ec1ad8..a6390a2ea 100644 --- a/ir/be/ia32/ia32_spec.pl +++ b/ir/be/ia32/ia32_spec.pl @@ -218,6 +218,7 @@ $arch = "ia32"; binop => "${arch}_emit_binop(node);", x87_binop => "${arch}_emit_x87_binop(node);", CMP0 => "${arch}_emit_cmp_suffix_node(node, 0);", + CMP3 => "${arch}_emit_cmp_suffix_node(node, 3);", ); #--------------------------------------------------# @@ -452,9 +453,12 @@ l_Mul => { IMul => { irn_flags => "R", state => "exc_pinned", - reg_req => { in => [ "gp", "gp", "none", "gp", "gp" ], out => [ "in_r4 in_r5" ] }, + # TODO: adjust out requirements for the 3 operand form + # (no need for should_be_same then) + reg_req => { in => [ "gp", "gp", "none", "gp", "gp" ], + out => [ "in_r4 in_r5", "none", "flags" ] }, ins => [ "base", "index", "mem", "left", "right" ], - emit => '. imul%M %binop', + outs => [ "res", "M", "flags" ], am => "source,binary", latency => 5, units => [ "GP" ], @@ -1054,6 +1058,21 @@ Set => { mode => $mode_gp, }, +SetMem => { + #irn_flags => "R", + state => "exc_pinned", + reg_req => { in => [ "gp", "gp", "none", "eflags" ], out => [ "none" ] }, + ins => [ "base", "index", "mem","eflags" ], + attr_type => "ia32_condcode_attr_t", + attr => "pn_Cmp pnc, int ins_permuted", + init_attr => "attr->attr.data.ins_permuted = ins_permuted;\n". + "\tset_ia32_ls_mode(res, mode_Bu);\n", + emit => '. set%CMP3 %AM', + latency => 1, + units => [ "GP" ], + mode => 'mode_M', +}, + CMov => { #irn_flags => "R", # (note: leave the false,true order intact to make it compatible with other diff --git a/ir/be/ia32/ia32_transform.c b/ir/be/ia32/ia32_transform.c index ed2c1b33f..2c9f75ad7 100644 --- a/ir/be/ia32/ia32_transform.c +++ b/ir/be/ia32/ia32_transform.c @@ -512,10 +512,32 @@ struct ia32_address_mode_t { ir_node *new_op1; ir_node *new_op2; op_pin_state pinned; - unsigned commutative:1; - unsigned ins_permuted:1; + unsigned commutative : 1; + unsigned ins_permuted : 1; }; +static void build_address_ptr(ia32_address_t *addr, ir_node *ptr, ir_node *mem) +{ + ir_node *noreg_gp = ia32_new_NoReg_gp(env_cg); + + /* construct load address */ + memset(addr, 0, sizeof(addr[0])); + ia32_create_address_mode(addr, ptr, /*force=*/0); + + if(addr->base == NULL) { + addr->base = noreg_gp; + } else { + addr->base = be_transform_node(addr->base); + } + + if(addr->index == NULL) { + addr->index = noreg_gp; + } else { + addr->index = be_transform_node(addr->index); + } + addr->mem = be_transform_node(mem); +} + static void build_address(ia32_address_mode_t *am, ir_node *node) { ir_node *noreg_gp = ia32_new_NoReg_gp(env_cg); @@ -1144,7 +1166,8 @@ static ir_node *gen_Mul(ir_node *node) { constraints */ return gen_binop(node, op1, op2, new_rd_ia32_IMul, - match_commutative | match_am | match_mode_neutral); + match_commutative | match_am | match_mode_neutral | + match_immediate | match_am_and_immediates); } /** @@ -1712,6 +1735,38 @@ static ir_node *gen_Abs(ir_node *node) return new_node; } +static ir_node *get_flags_node(ir_node *node, pn_Cmp *pnc_out) +{ + ir_graph *irg = current_ir_graph; + ir_node *flags; + ir_node *new_op; + ir_node *noreg; + ir_node *nomem; + ir_node *new_block; + dbg_info *dbgi; + + /* we have a Cmp as input */ + if(is_Proj(node)) { + ir_node *pred = get_Proj_pred(node); + if(is_Cmp(pred)) { + flags = be_transform_node(pred); + *pnc_out = get_Proj_proj(node); + return flags; + } + } + + /* a mode_b value, we have to compare it against 0 */ + dbgi = get_irn_dbg_info(node); + new_block = be_transform_node(get_nodes_block(node)); + new_op = be_transform_node(node); + noreg = ia32_new_NoReg_gp(env_cg); + nomem = new_NoMem(); + flags = new_rd_ia32_Test(dbgi, irg, new_block, noreg, noreg, nomem, + new_op, new_op, 0, 0); + *pnc_out = pn_Cmp_Lg; + return flags; +} + /** * Transforms a Load. * @@ -1886,10 +1941,9 @@ static ir_node *dest_am_unop(ir_node *node, ir_node *op, ir_node *mem, ir_node *ptr, ir_mode *mode, construct_unop_dest_func *func) { + ir_graph *irg = current_ir_graph; ir_node *src_block = get_nodes_block(node); ir_node *block; - ir_node *noreg_gp = ia32_new_NoReg_gp(env_cg); - ir_graph *irg = current_ir_graph; dbg_info *dbgi; ir_node *new_node; ia32_address_mode_t am; @@ -1901,13 +1955,6 @@ static ir_node *dest_am_unop(ir_node *node, ir_node *op, ir_node *mem, build_address(&am, op); - if(addr->base == NULL) - addr->base = noreg_gp; - if(addr->index == NULL) - addr->index = noreg_gp; - if(addr->mem == NULL) - addr->mem = new_NoMem(); - dbgi = get_irn_dbg_info(node); block = be_transform_node(src_block); new_node = func(dbgi, irg, block, addr->base, addr->index, addr->mem); @@ -1919,11 +1966,58 @@ static ir_node *dest_am_unop(ir_node *node, ir_node *op, ir_node *mem, return new_node; } +static ir_node *try_create_SetMem(ir_node *node, ir_node *ptr, ir_node *mem) { + ir_mode *mode = get_irn_mode(node); + ir_node *psi_true = get_Psi_val(node, 0); + ir_node *psi_default = get_Psi_default(node); + ir_graph *irg; + ir_node *cond; + ir_node *new_mem; + dbg_info *dbgi; + ir_node *block; + ir_node *new_block; + ir_node *flags; + ir_node *new_node; + int negated; + pn_Cmp pnc; + ia32_address_t addr; + + if(get_mode_size_bits(mode) != 8) + return NULL; + + if(is_Const_1(psi_true) && is_Const_0(psi_default)) { + negated = 0; + } else if(is_Const_0(psi_true) && is_Const_1(psi_default)) { + negated = 1; + } else { + return NULL; + } + + build_address_ptr(&addr, ptr, mem); + + irg = current_ir_graph; + dbgi = get_irn_dbg_info(node); + block = get_nodes_block(node); + new_block = be_transform_node(block); + cond = get_Psi_cond(node, 0); + flags = get_flags_node(cond, &pnc); + new_mem = be_transform_node(mem); + new_node = new_rd_ia32_SetMem(dbgi, irg, new_block, addr.base, + addr.index, addr.mem, flags, pnc, negated); + set_address(new_node, &addr); + set_ia32_op_type(new_node, ia32_AddrModeD); + set_ia32_ls_mode(new_node, mode); + SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node)); + + return new_node; +} + static ir_node *try_create_dest_am(ir_node *node) { ir_node *val = get_Store_value(node); ir_node *mem = get_Store_mem(node); ir_node *ptr = get_Store_ptr(node); ir_mode *mode = get_irn_mode(val); + int bits = get_mode_size_bits(mode); ir_node *op1; ir_node *op2; ir_node *new_node; @@ -1932,8 +2026,24 @@ static ir_node *try_create_dest_am(ir_node *node) { if(!mode_needs_gp_reg(mode)) return NULL; - /* store must be the only user of the val node */ - if(get_irn_n_edges(val) > 1) + while(1) { + /* store must be the only user of the val node */ + if(get_irn_n_edges(val) > 1) + return NULL; + /* skip pointless convs */ + if(is_Conv(val)) { + ir_node *conv_op = get_Conv_op(val); + ir_mode *pred_mode = get_irn_mode(conv_op); + if(pred_mode == mode_b || bits <= get_mode_size_bits(pred_mode)) { + val = conv_op; + continue; + } + } + break; + } + + /* value must be in the same block */ + if(get_nodes_block(node) != get_nodes_block(val)) return NULL; switch(get_irn_opcode(val)) { @@ -2019,6 +2129,9 @@ static ir_node *try_create_dest_am(ir_node *node) { match_dest_am | match_immediate); break; /* TODO: match ROR patterns... */ + case iro_Psi: + new_node = try_create_SetMem(val, ptr, mem); + break; case iro_Minus: op1 = get_Minus_op(val); new_node = dest_am_unop(val, op1, mem, ptr, mode, new_rd_ia32_NegMem); @@ -2033,6 +2146,13 @@ static ir_node *try_create_dest_am(ir_node *node) { return NULL; } + if(new_node != NULL) { + if(get_irn_pinned(new_node) != op_pin_state_pinned && + get_irn_pinned(node) == op_pin_state_pinned) { + set_irn_pinned(new_node, op_pin_state_pinned); + } + } + return new_node; } @@ -2189,38 +2309,6 @@ static ir_node *create_Switch(ir_node *node) return new_node; } -static ir_node *get_flags_node(ir_node *node, pn_Cmp *pnc_out) -{ - ir_graph *irg = current_ir_graph; - ir_node *flags; - ir_node *new_op; - ir_node *noreg; - ir_node *nomem; - ir_node *new_block; - dbg_info *dbgi; - - /* we have a Cmp as input */ - if(is_Proj(node)) { - ir_node *pred = get_Proj_pred(node); - if(is_Cmp(pred)) { - flags = be_transform_node(pred); - *pnc_out = get_Proj_proj(node); - return flags; - } - } - - /* a mode_b value, we have to compare it against 0 */ - dbgi = get_irn_dbg_info(node); - new_block = be_transform_node(get_nodes_block(node)); - new_op = be_transform_node(node); - noreg = ia32_new_NoReg_gp(env_cg); - nomem = new_NoMem(); - flags = new_rd_ia32_Test(dbgi, irg, new_block, noreg, noreg, nomem, - new_op, new_op, 0, 0); - *pnc_out = pn_Cmp_Lg; - return flags; -} - static ir_node *gen_Cond(ir_node *node) { ir_node *block = get_nodes_block(node); ir_node *new_block = be_transform_node(block); @@ -2537,14 +2625,18 @@ static ir_node *create_set_32bit(dbg_info *dbgi, ir_node *new_block, ir_graph *irg = current_ir_graph; ir_node *noreg = ia32_new_NoReg_gp(env_cg); ir_node *nomem = new_NoMem(); + ir_mode *mode = get_irn_mode(orig_node); ir_node *new_node; new_node = new_rd_ia32_Set(dbgi, irg, new_block, flags, pnc, ins_permuted); SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, orig_node)); - new_node = new_rd_ia32_Conv_I2I8Bit(dbgi, irg, new_block, noreg, noreg, - nomem, new_node, mode_Bu); - SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, orig_node)); - (void) orig_node; + + /* we might need to conv the result up */ + if(get_mode_size_bits(mode) > 8) { + new_node = new_rd_ia32_Conv_I2I8Bit(dbgi, irg, new_block, noreg, noreg, + nomem, new_node, mode_Bu); + SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, orig_node)); + } return new_node; } @@ -4562,6 +4654,10 @@ static ir_node *gen_Proj_be_Call(ir_node *node) { */ static ir_node *gen_Proj_Cmp(ir_node *node) { + (void) node; + panic("not all mode_b nodes are lowered"); + +#if 0 /* normally Cmps are processed when looking at Cond nodes, but this case * can happen in complicated Psi conditions */ dbg_info *dbgi = get_irn_dbg_info(node); @@ -4575,6 +4671,7 @@ static ir_node *gen_Proj_Cmp(ir_node *node) res = create_set_32bit(dbgi, new_block, new_cmp, pnc, node, 0); return res; +#endif } /** -- 2.20.1