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
This commit is contained in:
Richard Sandiford 2004-07-16 09:00:09 +00:00 committed by Richard Sandiford
parent 3758425f53
commit bb5928069e
2 changed files with 102 additions and 164 deletions

View File

@ -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

View File

@ -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;
rtx op0, op1, target;
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;
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;
enum rtx_code code;
rtx op0, op1;
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)));
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])));
}