From: Christian Würdig Date: Wed, 3 May 2006 13:57:53 +0000 (+0000) Subject: added Set node X-Git-Url: http://nsz.repo.hu/git/?a=commitdiff_plain;h=7ac5905eb66a8d67d3d53572f073612babc67eec;p=libfirm added Set node transform Psi to Set if possible --- diff --git a/ir/be/ia32/ia32_spec.pl b/ir/be/ia32/ia32_spec.pl index ac5f7c628..fe279a5d6 100644 --- a/ir/be/ia32/ia32_spec.pl +++ b/ir/be/ia32/ia32_spec.pl @@ -104,6 +104,28 @@ $comment_string = "/*"; { "name" => "ecx", "type" => 1 }, { "name" => "esi", "type" => 2 }, { "name" => "edi", "type" => 2 }, +# { "name" => "r11", "type" => 1 }, +# { "name" => "r12", "type" => 1 }, +# { "name" => "r13", "type" => 1 }, +# { "name" => "r14", "type" => 1 }, +# { "name" => "r15", "type" => 1 }, +# { "name" => "r16", "type" => 1 }, +# { "name" => "r17", "type" => 1 }, +# { "name" => "r18", "type" => 1 }, +# { "name" => "r19", "type" => 1 }, +# { "name" => "r20", "type" => 1 }, +# { "name" => "r21", "type" => 1 }, +# { "name" => "r22", "type" => 1 }, +# { "name" => "r23", "type" => 1 }, +# { "name" => "r24", "type" => 1 }, +# { "name" => "r25", "type" => 1 }, +# { "name" => "r26", "type" => 1 }, +# { "name" => "r27", "type" => 1 }, +# { "name" => "r28", "type" => 1 }, +# { "name" => "r29", "type" => 1 }, +# { "name" => "r30", "type" => 1 }, +# { "name" => "r31", "type" => 1 }, +# { "name" => "r32", "type" => 1 }, { "name" => "ebp", "type" => 2 }, { "name" => "esp", "type" => 4 }, { "name" => "gp_NOREG", "type" => 6 }, # we need a dummy register for NoReg nodes @@ -272,10 +294,16 @@ $comment_string = "/*"; "CMov" => { "irn_flags" => "R", - "comment" => "construct Mux: Mux(sel, a, b) == sel ? a : b", + "comment" => "construct Conditional Move: CMov(sel, a, b) == sel ? a : b", "reg_req" => { "in" => [ "gp", "gp", "gp", "gp" ], "out" => [ "in_r4" ] } }, +"Set" => { + "irn_flags" => "R", + "comment" => "construct Set: Set(sel) == sel ? 1 : 0", + "reg_req" => { "in" => [ "gp", "gp" ], "out" => [ "eax ebx ecx edx" ] }, +}, + # not commutative operations "Sub" => { diff --git a/ir/be/ia32/ia32_transform.c b/ir/be/ia32/ia32_transform.c index 97a420490..0f9e5b9d3 100644 --- a/ir/be/ia32/ia32_transform.c +++ b/ir/be/ia32/ia32_transform.c @@ -78,6 +78,20 @@ typedef enum { * ****************************************************************************************************/ +/** + * Returns 1 if irn is a Const representing 0, 0 otherwise + */ +static INLINE int is_ia32_Const_0(ir_node *irn) { + return is_ia32_Const(irn) ? classify_tarval(get_ia32_Immop_tarval(irn)) == TV_CLASSIFY_NULL : 0; +} + +/** + * Returns 1 if irn is a Const representing 1, 0 otherwise + */ +static INLINE int is_ia32_Const_1(ir_node *irn) { + return is_ia32_Const(irn) ? classify_tarval(get_ia32_Immop_tarval(irn)) == TV_CLASSIFY_ONE : 0; +} + /** * Returns the Proj representing the UNKNOWN register for given mode. */ @@ -1610,21 +1624,47 @@ static ir_node *gen_Mux(ia32_transform_env_t *env) { static ir_node *gen_Psi(ia32_transform_env_t *env) { ir_node *node = env->irn; ir_node *cmp_proj = get_Mux_sel(node); - ir_node *cmp, *cmp_a, *cmp_b, *new_op; + ir_node *cmp, *cmp_a, *cmp_b, *new_op = NULL; assert(get_irn_mode(cmp_proj) == mode_b && "Condition for Psi must have mode_b"); - cmp = get_Proj_pred(cmp_proj); - cmp_a = get_Cmp_left(cmp); - cmp_b = get_Cmp_right(cmp); - - - new_op = new_rd_ia32_CMov(env->dbg, env->irg, env->block, \ - cmp_a, cmp_b, get_Psi_val(node, 0), get_Psi_default(node), env->mode); + if (mode_is_float(env->mode)) { + /* floating point psi */ - set_ia32_pncode(new_op, get_Proj_proj(cmp_proj)); + if (USE_SSE2(env->cg)) { + /* unfortunately there is no conditional move for SSE */ + } + else { + } + } + else { + ir_node *psi_true = get_Psi_val(node, 0); + ir_node *psi_default = get_Psi_default(node); + + /* integer psi */ + cmp = get_Proj_pred(cmp_proj); + cmp_a = get_Cmp_left(cmp); + cmp_b = get_Cmp_right(cmp); + + if (is_ia32_Const_1(psi_true) && is_ia32_Const_0(psi_default)) { + /* first case for SETcc: default is 0, set to 1 iff condition is true */ + new_op = new_rd_ia32_Set(env->dbg, env->irg, env->block, cmp_a, cmp_b, env->mode); + set_ia32_pncode(new_op, get_Proj_proj(cmp_proj)); + } + else if (is_ia32_Const_0(psi_true) && is_ia32_Const_1(psi_default)) { + /* second case for SETcc: default is 1, set to 0 iff condition is true: */ + /* we invert condition and set default to 0 */ + new_op = new_rd_ia32_Set(env->dbg, env->irg, env->block, cmp_a, cmp_b, env->mode); + set_ia32_pncode(new_op, get_inversed_pnc(get_Proj_proj(cmp_proj))); + } + else { + /* otherwise: use CMOVcc */ + new_op = new_rd_ia32_CMov(env->dbg, env->irg, env->block, cmp_a, cmp_b, psi_true, psi_default, env->mode); + set_ia32_pncode(new_op, get_Proj_proj(cmp_proj)); + } - SET_IA32_ORIG_NODE(new_op, ia32_get_old_node_name(env->cg, env->irn)); + SET_IA32_ORIG_NODE(new_op, ia32_get_old_node_name(env->cg, env->irn)); + } return new_op; }