diff options
author | Richard Sandiford <rsandifo@redhat.com> | 2004-07-16 09:00:09 +0000 |
---|---|---|
committer | Richard Sandiford <rsandifo@gcc.gnu.org> | 2004-07-16 09:00:09 +0000 |
commit | bb5928069ec6cfdb19e9c2f2e2fe110e9413f634 (patch) | |
tree | 308a6bf7c556869c5bd6e3b0dd6b8a1d329a0323 /gcc | |
parent | 3758425f53961334de12516f1ea598d4ee491ed6 (diff) | |
download | gcc-bb5928069ec6cfdb19e9c2f2e2fe110e9413f634.zip gcc-bb5928069ec6cfdb19e9c2f2e2fe110e9413f634.tar.gz gcc-bb5928069ec6cfdb19e9c2f2e2fe110e9413f634.tar.bz2 |
mips.c (get_float_compare_codes): Delete.
* config/mips/mips.c (get_float_compare_codes): Delete.
(mips_emit_compare): New function, mostly extracted from
get_float_compare_codes and gen_conditional_branch.
(gen_conditional_branch, gen_conditional_move): Use it.
From-SVN: r84813
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ChangeLog | 7 | ||||
-rw-r--r-- | gcc/config/mips/mips.c | 259 |
2 files changed, 102 insertions, 164 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 532695d..80e703f 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,10 @@ +2004-07-16 Richard Sandiford <rsandifo@redhat.com> + + * config/mips/mips.c (get_float_compare_codes): Delete. + (mips_emit_compare): New function, mostly extracted from + get_float_compare_codes and gen_conditional_branch. + (gen_conditional_branch, gen_conditional_move): Use it. + 2004-07-16 Segher Boessenkool <segher@kernel.crashing.org> * genautomata.c (add_vect): Speedup by using integers as diff --git a/gcc/config/mips/mips.c b/gcc/config/mips/mips.c index 489016a..c3c7fa3 100644 --- a/gcc/config/mips/mips.c +++ b/gcc/config/mips/mips.c @@ -175,8 +175,7 @@ static void mips_legitimize_const_move (enum machine_mode, rtx, rtx); static int m16_check_op (rtx, int, int, int); static bool mips_rtx_costs (rtx, int, int, int *); static int mips_address_cost (rtx); -static void get_float_compare_codes (enum rtx_code, enum rtx_code *, - enum rtx_code *); +static void mips_emit_compare (enum rtx_code *, rtx *, rtx *, bool); static void mips_load_call_address (rtx, rtx, int); static bool mips_function_ok_for_sibcall (tree, tree); static void mips_block_move_straight (rtx, rtx, HOST_WIDE_INT); @@ -2784,6 +2783,87 @@ mips_zero_if_equal (rtx cmp0, rtx cmp1) cmp0, cmp1, 0, 0, OPTAB_DIRECT); } +/* Convert a comparison into something that can be used in a branch or + conditional move. cmp_operands[0] and cmp_operands[1] are the values + being compared and *CODE is the code used to compare them. + + Update *CODE, *OP0 and *OP1 so that they describe the final comparison. + If NEED_EQ_NE_P, then only EQ/NE comparisons against zero are possible, + otherwise any standard branch condition can be used. The standard branch + conditions are: + + - EQ/NE between two registers. + - any comparison between a register and zero. */ + +static void +mips_emit_compare (enum rtx_code *code, rtx *op0, rtx *op1, bool need_eq_ne_p) +{ + if (GET_MODE_CLASS (GET_MODE (cmp_operands[0])) == MODE_INT) + { + if (!need_eq_ne_p && cmp_operands[1] == const0_rtx) + { + *op0 = cmp_operands[0]; + *op1 = cmp_operands[1]; + } + else if (*code == EQ || *code == NE) + { + if (need_eq_ne_p) + { + *op0 = mips_zero_if_equal (cmp_operands[0], cmp_operands[1]); + *op1 = const0_rtx; + } + else + { + *op0 = cmp_operands[0]; + *op1 = force_reg (GET_MODE (*op0), cmp_operands[1]); + } + } + else + { + /* The comparison needs a separate scc instruction. Store the + result of the scc in *OP0 and compare it against zero. */ + bool invert = false; + *op0 = gen_reg_rtx (GET_MODE (cmp_operands[0])); + *op1 = const0_rtx; + mips_emit_int_relational (*code, &invert, *op0, + cmp_operands[0], cmp_operands[1]); + *code = (invert ? EQ : NE); + } + } + else + { + enum rtx_code cmp_code; + + /* Floating-point tests use a separate c.cond.fmt comparison to + set a condition code register. The branch or conditional move + will then compare that register against zero. + + Set CMP_CODE to the code of the comparison instruction and + *CODE to the code that the branch or move should use. */ + switch (*code) + { + case NE: + case UNGE: + case UNGT: + case LTGT: + case ORDERED: + cmp_code = reverse_condition_maybe_unordered (*code); + *code = EQ; + break; + + default: + cmp_code = *code; + *code = NE; + break; + } + *op0 = (ISA_HAS_8CC + ? gen_reg_rtx (CCmode) + : gen_rtx_REG (CCmode, FPSW_REGNUM)); + *op1 = const0_rtx; + mips_emit_binary (cmp_code, *op0, cmp_operands[0], cmp_operands[1]); + } +} + /* Try comparing cmp_operands[0] and cmp_operands[1] using rtl code CODE. Store the result in TARGET and return true if successful. @@ -2806,100 +2886,20 @@ mips_emit_scc (enum rtx_code code, rtx target) cmp_operands[0], cmp_operands[1]); return true; } - -/* Work out how to check a floating-point condition. We need a - separate comparison instruction (C.cond.fmt), followed by a - branch or conditional move. Given that IN_CODE is the - required condition, set *CMP_CODE to the C.cond.fmt code - and *action_code to the branch or move code. */ - -static void -get_float_compare_codes (enum rtx_code in_code, enum rtx_code *cmp_code, - enum rtx_code *action_code) -{ - switch (in_code) - { - case NE: - case UNGE: - case UNGT: - case LTGT: - case ORDERED: - *cmp_code = reverse_condition_maybe_unordered (in_code); - *action_code = EQ; - break; - - default: - *cmp_code = in_code; - *action_code = NE; - break; - } -} /* Emit the common code for doing conditional branches. operand[0] is the label to jump to. The comparison operands are saved away by cmp{si,di,sf,df}. */ void -gen_conditional_branch (rtx *operands, enum rtx_code test_code) +gen_conditional_branch (rtx *operands, enum rtx_code code) { - rtx cmp0, cmp1, target; - enum machine_mode mode; - enum rtx_code cmp_code; - - switch (GET_MODE (cmp_operands[0])) - { - case SImode: - case DImode: - mode = GET_MODE (cmp_operands[0]); - if (!TARGET_MIPS16 && cmp_operands[1] == const0_rtx) - { - cmp0 = cmp_operands[0]; - cmp1 = cmp_operands[1]; - } - else if (test_code == EQ || test_code == NE) - { - if (TARGET_MIPS16) - { - cmp0 = mips_zero_if_equal (cmp_operands[0], cmp_operands[1]); - cmp1 = const0_rtx; - } - else - { - cmp0 = cmp_operands[0]; - cmp1 = force_reg (mode, cmp_operands[1]); - } - } - else - { - bool invert = false; - cmp0 = gen_reg_rtx (mode); - cmp1 = const0_rtx; - mips_emit_int_relational (test_code, &invert, cmp0, - cmp_operands[0], cmp_operands[1]); - test_code = (invert ? EQ : NE); - } - break; - - case SFmode: - case DFmode: - mode = CCmode; - if (!ISA_HAS_8CC) - cmp0 = gen_rtx_REG (mode, FPSW_REGNUM); - else - cmp0 = gen_reg_rtx (mode); - cmp1 = const0_rtx; + rtx op0, op1, target; - get_float_compare_codes (test_code, &cmp_code, &test_code); - mips_emit_binary (cmp_code, cmp0, cmp_operands[0], cmp_operands[1]); - break; - - default: - abort (); - } - - /* Generate the branch. */ + mips_emit_compare (&code, &op0, &op1, TARGET_MIPS16); target = gen_rtx_IF_THEN_ELSE (VOIDmode, - gen_rtx_fmt_ee (test_code, mode, cmp0, cmp1), + gen_rtx_fmt_ee (code, GET_MODE (op0), + op0, op1), gen_rtx_LABEL_REF (VOIDmode, operands[0]), pc_rtx); emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, target)); @@ -2911,84 +2911,15 @@ gen_conditional_branch (rtx *operands, enum rtx_code test_code) void gen_conditional_move (rtx *operands) { - rtx op0 = cmp_operands[0]; - rtx op1 = cmp_operands[1]; - enum machine_mode mode = GET_MODE (cmp_operands[0]); - enum rtx_code cmp_code = GET_CODE (operands[1]); - enum rtx_code move_code = NE; - enum machine_mode op_mode = GET_MODE (operands[0]); - enum machine_mode cmp_mode; - rtx cmp_reg; - - if (GET_MODE_CLASS (mode) != MODE_FLOAT) - { - switch (cmp_code) - { - case EQ: - cmp_code = XOR; - move_code = EQ; - break; - case NE: - cmp_code = XOR; - break; - case LT: - break; - case GE: - cmp_code = LT; - move_code = EQ; - break; - case GT: - cmp_code = LT; - op0 = force_reg (mode, cmp_operands[1]); - op1 = cmp_operands[0]; - break; - case LE: - cmp_code = LT; - op0 = force_reg (mode, cmp_operands[1]); - op1 = cmp_operands[0]; - move_code = EQ; - break; - case LTU: - break; - case GEU: - cmp_code = LTU; - move_code = EQ; - break; - case GTU: - cmp_code = LTU; - op0 = force_reg (mode, cmp_operands[1]); - op1 = cmp_operands[0]; - break; - case LEU: - cmp_code = LTU; - op0 = force_reg (mode, cmp_operands[1]); - op1 = cmp_operands[0]; - move_code = EQ; - break; - default: - abort (); - } - } - else - get_float_compare_codes (cmp_code, &cmp_code, &move_code); - - if (mode == SImode || mode == DImode) - cmp_mode = mode; - else if (mode == SFmode || mode == DFmode) - cmp_mode = CCmode; - else - abort (); - - cmp_reg = gen_reg_rtx (cmp_mode); - emit_insn (gen_rtx_SET (cmp_mode, cmp_reg, - gen_rtx_fmt_ee (cmp_code, cmp_mode, op0, op1))); + enum rtx_code code; + rtx op0, op1; - emit_insn (gen_rtx_SET (op_mode, operands[0], - gen_rtx_IF_THEN_ELSE (op_mode, - gen_rtx_fmt_ee (move_code, - VOIDmode, - cmp_reg, - const0_rtx), + code = GET_CODE (operands[1]); + mips_emit_compare (&code, &op0, &op1, true); + emit_insn (gen_rtx_SET (VOIDmode, operands[0], + gen_rtx_IF_THEN_ELSE (GET_MODE (operands[0]), + gen_rtx_fmt_ee (code, VOIDmode, + op0, op1), operands[2], operands[3]))); } |