From: Matthias Braun Date: Mon, 18 Jan 2010 15:27:35 +0000 (+0000) Subject: remove ins_permuted from CMovcc and Setcc constructors (again) X-Git-Url: http://nsz.repo.hu/git/?a=commitdiff_plain;h=51d5090095b2f4f2285ff1b7ccd13c72a7b5d9d3;p=libfirm remove ins_permuted from CMovcc and Setcc constructors (again) [r26983] --- diff --git a/ir/be/ia32/ia32_emitter.c b/ir/be/ia32/ia32_emitter.c index a74d9bfd3..87486133f 100644 --- a/ir/be/ia32/ia32_emitter.c +++ b/ir/be/ia32/ia32_emitter.c @@ -959,8 +959,7 @@ static ir_node *find_original_value(ir_node *node) } } -static int determine_final_pnc(const ir_node *node, int flags_pos, - int pnc) +static int determine_final_pnc(const ir_node *node, int flags_pos, int pnc) { ir_node *flags = get_irn_n(node, flags_pos); const ia32_attr_t *flags_attr; @@ -1188,13 +1187,16 @@ static void emit_ia32_Setcc(const ir_node *node) static void emit_ia32_CMovcc(const ir_node *node) { const ia32_attr_t *attr = get_ia32_attr_const(node); - int ins_permuted = attr->data.ins_permuted; const arch_register_t *out = arch_irn_get_register(node, pn_ia32_res); pn_Cmp pnc = get_ia32_condcode(node); const arch_register_t *in_true; const arch_register_t *in_false; pnc = determine_final_pnc(node, n_ia32_CMovcc_eflags, pnc); + /* although you can't set ins_permuted in the constructor it might still + be set by memory operand folding */ + if (attr->data.ins_permuted) + pnc = ia32_get_negated_pnc(pnc); in_true = arch_get_irn_register(get_irn_n(node, n_ia32_CMovcc_val_true)); in_false = arch_get_irn_register(get_irn_n(node, n_ia32_CMovcc_val_false)); @@ -1207,7 +1209,7 @@ static void emit_ia32_CMovcc(const ir_node *node) assert(get_ia32_op_type(node) == ia32_Normal); - ins_permuted = !ins_permuted; + pnc = ia32_get_negated_pnc(pnc); tmp = in_true; in_true = in_false; @@ -1217,10 +1219,20 @@ static void emit_ia32_CMovcc(const ir_node *node) ia32_emitf(node, "\tmovl %R, %R\n", in_false, out); } - if (ins_permuted) - pnc = ia32_get_negated_pnc(pnc); - /* TODO: handling of Nans isn't correct yet */ + if (pnc & ia32_pn_Cmp_float) { + switch (pnc & 0x0f) { + case pn_Cmp_Uo: + case pn_Cmp_Leg: + case pn_Cmp_Eq: + case pn_Cmp_Lt: + case pn_Cmp_Le: + case pn_Cmp_Ug: + case pn_Cmp_Uge: + case pn_Cmp_Ne: + panic("CMov with floatingpoint compare/parity not supported yet"); + } + } ia32_emitf(node, "\tcmov%P %#AR, %#R\n", pnc, in_true, out); } diff --git a/ir/be/ia32/ia32_spec.pl b/ir/be/ia32/ia32_spec.pl index 0196a9f95..3df9a729f 100644 --- a/ir/be/ia32/ia32_spec.pl +++ b/ir/be/ia32/ia32_spec.pl @@ -1096,9 +1096,8 @@ Setcc => { ins => [ "eflags" ], outs => [ "res" ], 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", + attr => "pn_Cmp pnc", + init_attr => "set_ia32_ls_mode(res, mode_Bu);\n", latency => 1, units => [ "GP" ], mode => $mode_gp, @@ -1110,9 +1109,8 @@ SetccMem => { 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", + attr => "pn_Cmp pnc", + init_attr => "set_ia32_ls_mode(res, mode_Bu);\n", emit => '. set%CMP3 %AM', latency => 1, units => [ "GP" ], @@ -1130,8 +1128,7 @@ CMovcc => { outs => [ "res", "flags", "M" ], am => "source,binary", attr_type => "ia32_condcode_attr_t", - attr => "int ins_permuted, pn_Cmp pnc", - init_attr => "attr->attr.data.ins_permuted = ins_permuted;", + attr => "pn_Cmp pnc", latency => 1, units => [ "GP" ], mode => $mode_gp, diff --git a/ir/be/ia32/ia32_transform.c b/ir/be/ia32/ia32_transform.c index d1b2f3917..59548984f 100644 --- a/ir/be/ia32/ia32_transform.c +++ b/ir/be/ia32/ia32_transform.c @@ -1950,6 +1950,8 @@ static ir_node *get_flags_node(ir_node *node, pn_Cmp *pnc_out) } flags = be_transform_node(pred); *pnc_out = pnc; + if (mode_is_float(get_irn_mode(get_Cmp_left(pred)))) + *pnc_out |= ia32_pn_Cmp_float; return flags; } } @@ -2174,6 +2176,12 @@ static ir_node *dest_am_unop(ir_node *node, ir_node *op, ir_node *mem, return new_node; } +static pn_Cmp ia32_get_negated_pnc(pn_Cmp pnc) +{ + ir_mode *mode = pnc & ia32_pn_Cmp_float ? mode_F : mode_Iu; + return get_negated_pnc(pnc, mode); +} + static ir_node *try_create_SetMem(ir_node *node, ir_node *ptr, ir_node *mem) { ir_mode *mode = get_irn_mode(node); @@ -2186,7 +2194,7 @@ static ir_node *try_create_SetMem(ir_node *node, ir_node *ptr, ir_node *mem) ir_node *new_block; ir_node *flags; ir_node *new_node; - int negated; + bool negated; pn_Cmp pnc; ia32_address_t addr; @@ -2194,9 +2202,9 @@ static ir_node *try_create_SetMem(ir_node *node, ir_node *ptr, ir_node *mem) return NULL; if (is_Const_1(mux_true) && is_Const_0(mux_false)) { - negated = 0; + negated = false; } else if (is_Const_0(mux_true) && is_Const_1(mux_false)) { - negated = 1; + negated = true; } else { return NULL; } @@ -2206,6 +2214,8 @@ static ir_node *try_create_SetMem(ir_node *node, ir_node *ptr, ir_node *mem) /* we can't handle the float special cases with SetM */ if (pnc & ia32_pn_Cmp_float) return NULL; + if (negated) + pnc = ia32_get_negated_pnc(pnc); build_address_ptr(&addr, ptr, mem); @@ -2214,7 +2224,7 @@ static ir_node *try_create_SetMem(ir_node *node, ir_node *ptr, ir_node *mem) new_block = be_transform_node(block); new_mem = be_transform_node(mem); new_node = new_bd_ia32_SetccMem(dbgi, new_block, addr.base, - addr.index, addr.mem, flags, pnc, negated); + addr.index, addr.mem, flags, pnc); set_address(new_node, &addr); set_ia32_op_type(new_node, ia32_AddrModeD); set_ia32_ls_mode(new_node, mode); @@ -2965,9 +2975,12 @@ static ir_node *create_CMov(ir_node *node, ir_node *flags, ir_node *new_flags, match_arguments(&am, block, val_false, val_true, flags, match_commutative | match_am | match_16bit_am | match_mode_neutral); + if (am.ins_permuted) + pnc = ia32_get_negated_pnc(pnc); + new_node = new_bd_ia32_CMovcc(dbgi, new_block, addr->base, addr->index, addr->mem, am.new_op1, am.new_op2, new_flags, - am.ins_permuted, pnc); + pnc); set_am_attributes(new_node, &am); SET_IA32_ORIG_NODE(new_node, node); @@ -2982,13 +2995,12 @@ static ir_node *create_CMov(ir_node *node, ir_node *flags, ir_node *new_flags, */ static ir_node *create_set_32bit(dbg_info *dbgi, ir_node *new_block, ir_node *flags, pn_Cmp pnc, - int ins_permuted, ir_node *orig_node) { ir_mode *mode = get_irn_mode(orig_node); ir_node *new_node; - new_node = new_bd_ia32_Setcc(dbgi, new_block, flags, pnc, ins_permuted); + new_node = new_bd_ia32_Setcc(dbgi, new_block, flags, pnc); SET_IA32_ORIG_NODE(new_node, orig_node); /* we might need to conv the result up */ @@ -3150,7 +3162,7 @@ static ir_node *gen_Mux(ir_node *node) unsigned scale; flags = get_flags_node(cond, &pnc); - new_node = create_set_32bit(dbgi, new_block, flags, pnc, /*is_permuted=*/0, node); + new_node = create_set_32bit(dbgi, new_block, flags, pnc, node); if (ia32_cg_config.use_sse2) { /* cannot load from different mode on SSE */ @@ -3247,9 +3259,10 @@ static ir_node *gen_Mux(ir_node *node) if (is_Const(mux_true) && is_Const(mux_false)) { /* both are const, good */ if (is_Const_1(mux_true) && is_Const_0(mux_false)) { - new_node = create_set_32bit(dbgi, new_block, flags, pnc, /*is_permuted=*/0, node); + new_node = create_set_32bit(dbgi, new_block, flags, pnc, node); } else if (is_Const_0(mux_true) && is_Const_1(mux_false)) { - new_node = create_set_32bit(dbgi, new_block, flags, pnc, /*is_permuted=*/1, node); + pnc = ia32_get_negated_pnc(pnc); + new_node = create_set_32bit(dbgi, new_block, flags, pnc, node); } else { /* Not that simple. */ goto need_cmov; @@ -4788,7 +4801,7 @@ static ir_node *gen_ffs(ir_node *node) flag = new_r_Proj(block, real, mode_b, pn_ia32_flags); /* sete */ - set = new_bd_ia32_Setcc(dbgi, block, flag, pn_Cmp_Eq, 0); + set = new_bd_ia32_Setcc(dbgi, block, flag, pn_Cmp_Eq); SET_IA32_ORIG_NODE(set, node); /* conv to 32bit */ @@ -4858,7 +4871,7 @@ static ir_node *gen_parity(ir_node *node) cmp = fix_mem_proj(cmp, &am); /* setp */ - new_node = new_bd_ia32_Setcc(dbgi, new_block, cmp, ia32_pn_Cmp_parity, 0); + new_node = new_bd_ia32_Setcc(dbgi, new_block, cmp, ia32_pn_Cmp_parity); SET_IA32_ORIG_NODE(new_node, node); /* conv to 32bit */