Commit a012718f by Richard Sandiford Committed by Richard Sandiford

mips-protos.h (gen_int_relational): Delete.

	* config/mips/mips-protos.h (gen_int_relational): Delete.
	(mips_emit_scc): Declare.
	* config/mips/mips.c (internal_test): Delete.
	(sle_operand, sleu_operand): New functions.
	(map_test_to_internal_test, gen_int_relational): Delete.
	(mips_emit_binary, mips_relational_operand_ok_p)
	(mips_emit_int_relational, mips_zero_if_equal)
	(mips_emit_scc): New functions.
	(gen_conditional_branch): Rework to use mips_emit_int_relational.
	* config/mips/mips.h (PREDICATE_CODES): Add sle_operand and
	sleu_operand.
	* config/mips/mips.md (seq, sne, sgt, sge, slt, sle, sgtu, sgeu)
	(sltu, sleu): Use mips_emit_scc.
	(*sge_[sd]i, *sgeu_[sd]i): New patterns.
	(*sle_[sd]i, *sle_[sd]i_mips16): Use sle_operand.
	(*sleu_[sd]i, *sleu_[sd]i_mips16): Use sleu_operand.

From-SVN: r84808
parent c03eb5a3
2004-07-16 Richard Sandiford <rsandifo@redhat.com> 2004-07-16 Richard Sandiford <rsandifo@redhat.com>
* config/mips/mips-protos.h (gen_int_relational): Delete.
(mips_emit_scc): Declare.
* config/mips/mips.c (internal_test): Delete.
(sle_operand, sleu_operand): New functions.
(map_test_to_internal_test, gen_int_relational): Delete.
(mips_emit_binary, mips_relational_operand_ok_p)
(mips_emit_int_relational, mips_zero_if_equal)
(mips_emit_scc): New functions.
(gen_conditional_branch): Rework to use mips_emit_int_relational.
* config/mips/mips.h (PREDICATE_CODES): Add sle_operand and
sleu_operand.
* config/mips/mips.md (seq, sne, sgt, sge, slt, sle, sgtu, sgeu)
(sltu, sleu): Use mips_emit_scc.
(*sge_[sd]i, *sgeu_[sd]i): New patterns.
(*sle_[sd]i, *sle_[sd]i_mips16): Use sle_operand.
(*sleu_[sd]i, *sleu_[sd]i_mips16): Use sleu_operand.
2004-07-16 Richard Sandiford <rsandifo@redhat.com>
* config/mips/mips.md (*sgt_di_mips16): Fix destination constraint. * config/mips/mips.md (*sgt_di_mips16): Fix destination constraint.
2004-07-16 Richard Sandiford <rsandifo@redhat.com> 2004-07-16 Richard Sandiford <rsandifo@redhat.com>
......
...@@ -123,7 +123,7 @@ extern void mips_split_64bit_move (rtx, rtx); ...@@ -123,7 +123,7 @@ extern void mips_split_64bit_move (rtx, rtx);
extern const char *mips_output_move (rtx, rtx); extern const char *mips_output_move (rtx, rtx);
extern rtx mips_gp_save_slot (void); extern rtx mips_gp_save_slot (void);
#ifdef RTX_CODE #ifdef RTX_CODE
extern rtx gen_int_relational (enum rtx_code, rtx, rtx, rtx, int *); extern bool mips_emit_scc (enum rtx_code, rtx);
extern void gen_conditional_branch (rtx *, enum rtx_code); extern void gen_conditional_branch (rtx *, enum rtx_code);
#endif #endif
extern void gen_conditional_move (rtx *); extern void gen_conditional_move (rtx *);
......
...@@ -57,24 +57,6 @@ Boston, MA 02111-1307, USA. */ ...@@ -57,24 +57,6 @@ Boston, MA 02111-1307, USA. */
#include "sched-int.h" #include "sched-int.h"
#include "tree-gimple.h" #include "tree-gimple.h"
/* Enumeration for all of the relational tests, so that we can build
arrays indexed by the test type, and not worry about the order
of EQ, NE, etc. */
enum internal_test {
ITEST_EQ,
ITEST_NE,
ITEST_GT,
ITEST_GE,
ITEST_LT,
ITEST_LE,
ITEST_GTU,
ITEST_GEU,
ITEST_LTU,
ITEST_LEU,
ITEST_MAX
};
/* True if X is an unspec wrapper around a SYMBOL_REF or LABEL_REF. */ /* True if X is an unspec wrapper around a SYMBOL_REF or LABEL_REF. */
#define UNSPEC_ADDRESS_P(X) \ #define UNSPEC_ADDRESS_P(X) \
(GET_CODE (X) == UNSPEC \ (GET_CODE (X) == UNSPEC \
...@@ -193,7 +175,6 @@ static void mips_legitimize_const_move (enum machine_mode, rtx, rtx); ...@@ -193,7 +175,6 @@ static void mips_legitimize_const_move (enum machine_mode, rtx, rtx);
static int m16_check_op (rtx, int, int, int); static int m16_check_op (rtx, int, int, int);
static bool mips_rtx_costs (rtx, int, int, int *); static bool mips_rtx_costs (rtx, int, int, int *);
static int mips_address_cost (rtx); static int mips_address_cost (rtx);
static enum internal_test map_test_to_internal_test (enum rtx_code);
static void get_float_compare_codes (enum rtx_code, enum rtx_code *, static void get_float_compare_codes (enum rtx_code, enum rtx_code *,
enum rtx_code *); enum rtx_code *);
static void mips_load_call_address (rtx, rtx, int); static void mips_load_call_address (rtx, rtx, int);
...@@ -1343,6 +1324,24 @@ arith_operand (rtx op, enum machine_mode mode) ...@@ -1343,6 +1324,24 @@ arith_operand (rtx op, enum machine_mode mode)
return const_arith_operand (op, mode) || register_operand (op, mode); return const_arith_operand (op, mode) || register_operand (op, mode);
} }
/* Return true if OP can be used as the second argument to an LE operation. */
int
sle_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
{
return GET_CODE (op) == CONST_INT && SMALL_OPERAND (INTVAL (op) + 1);
}
/* Likewise LEU. */
int
sleu_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
{
return (GET_CODE (op) == CONST_INT
&& INTVAL (op) + 1 != 0
&& SMALL_OPERAND (INTVAL (op) + 1));
}
/* Return truth value of whether OP is an integer which fits in 16 bits. */ /* Return truth value of whether OP is an integer which fits in 16 bits. */
int int
...@@ -2691,248 +2690,117 @@ mips_gp_save_slot (void) ...@@ -2691,248 +2690,117 @@ mips_gp_save_slot (void)
return loc; return loc;
} }
/* Make normal rtx_code into something we can index from an array */ /* Emit an instruction of the form (set TARGET (CODE OP0 OP1)). */
static enum internal_test static void
map_test_to_internal_test (enum rtx_code test_code) mips_emit_binary (enum rtx_code code, rtx target, rtx op0, rtx op1)
{ {
enum internal_test test = ITEST_MAX; emit_insn (gen_rtx_SET (VOIDmode, target,
gen_rtx_fmt_ee (code, GET_MODE (target), op0, op1)));
switch (test_code)
{
case EQ: test = ITEST_EQ; break;
case NE: test = ITEST_NE; break;
case GT: test = ITEST_GT; break;
case GE: test = ITEST_GE; break;
case LT: test = ITEST_LT; break;
case LE: test = ITEST_LE; break;
case GTU: test = ITEST_GTU; break;
case GEU: test = ITEST_GEU; break;
case LTU: test = ITEST_LTU; break;
case LEU: test = ITEST_LEU; break;
default: break;
}
return test;
} }
/* Return true if CMP1 is a suitable second operand for relational
/* Generate the code to compare two integer values. The return value is: operator CODE. See also the *sCC patterns in mips.md. */
(reg:SI xx) The pseudo register the comparison is in
0 No register, generate a simple branch.
??? This is called with result nonzero by the Scond patterns in
mips.md. These patterns are called with a target in the mode of
the Scond instruction pattern. Since this must be a constant, we
must use SImode. This means that if RESULT is nonzero, it will
always be an SImode register, even if TARGET_64BIT is true. We
cope with this by calling convert_move rather than emit_move_insn.
This will sometimes lead to an unnecessary extension of the result;
for example:
long long
foo (long long i)
{
return i < 5;
}
TEST_CODE is the rtx code for the comparison.
CMP0 and CMP1 are the two operands to compare.
RESULT is the register in which the result should be stored (null for
branches).
For branches, P_INVERT points to an integer that is nonzero on return
if the branch should be inverted. */
rtx
gen_int_relational (enum rtx_code test_code, rtx result, rtx cmp0,
rtx cmp1, int *p_invert)
{
struct cmp_info
{
enum rtx_code test_code; /* code to use in instruction (LT vs. LTU) */
int const_low; /* low bound of constant we can accept */
int const_high; /* high bound of constant we can accept */
int const_add; /* constant to add (convert LE -> LT) */
int reverse_regs; /* reverse registers in test */
int invert_const; /* != 0 if invert value if cmp1 is constant */
int invert_reg; /* != 0 if invert value if cmp1 is register */
int unsignedp; /* != 0 for unsigned comparisons. */
};
static const struct cmp_info info[ (int)ITEST_MAX ] = {
{ XOR, 0, 65535, 0, 0, 0, 0, 0 }, /* EQ */
{ XOR, 0, 65535, 0, 0, 1, 1, 0 }, /* NE */
{ LT, -32769, 32766, 1, 1, 1, 0, 0 }, /* GT */
{ LT, -32768, 32767, 0, 0, 1, 1, 0 }, /* GE */
{ LT, -32768, 32767, 0, 0, 0, 0, 0 }, /* LT */
{ LT, -32769, 32766, 1, 1, 0, 1, 0 }, /* LE */
{ LTU, -32769, 32766, 1, 1, 1, 0, 1 }, /* GTU */
{ LTU, -32768, 32767, 0, 0, 1, 1, 1 }, /* GEU */
{ LTU, -32768, 32767, 0, 0, 0, 0, 1 }, /* LTU */
{ LTU, -32769, 32766, 1, 1, 0, 1, 1 }, /* LEU */
};
enum internal_test test;
enum machine_mode mode;
const struct cmp_info *p_info;
int branch_p;
int eqne_p;
int invert;
rtx reg;
rtx reg2;
test = map_test_to_internal_test (test_code);
if (test == ITEST_MAX)
abort ();
p_info = &info[(int) test];
eqne_p = (p_info->test_code == XOR);
mode = GET_MODE (cmp0);
if (mode == VOIDmode)
mode = GET_MODE (cmp1);
/* Eliminate simple branches. */ static bool
branch_p = (result == 0); mips_relational_operand_ok_p (enum rtx_code code, rtx cmp1)
if (branch_p) {
switch (code)
{ {
if (GET_CODE (cmp0) == REG || GET_CODE (cmp0) == SUBREG) case GT:
{ case GTU:
/* Comparisons against zero are simple branches. */ return reg_or_0_operand (cmp1, VOIDmode);
if (GET_CODE (cmp1) == CONST_INT && INTVAL (cmp1) == 0
&& (! TARGET_MIPS16 || eqne_p))
return 0;
/* Test for beq/bne. */
if (eqne_p && ! TARGET_MIPS16)
return 0;
}
/* Allocate a pseudo to calculate the value in. */
result = gen_reg_rtx (mode);
}
/* Make sure we can handle any constants given to us. */ case GE:
if (GET_CODE (cmp0) == CONST_INT) case GEU:
cmp0 = force_reg (mode, cmp0); return !TARGET_MIPS16 && cmp1 == const1_rtx;
if (GET_CODE (cmp1) == CONST_INT) case LT:
{ case LTU:
HOST_WIDE_INT value = INTVAL (cmp1); return arith_operand (cmp1, VOIDmode);
if (value < p_info->const_low case LE:
|| value > p_info->const_high return sle_operand (cmp1, VOIDmode);
/* ??? Why? And why wasn't the similar code below modified too? */
|| (TARGET_64BIT
&& HOST_BITS_PER_WIDE_INT < 64
&& p_info->const_add != 0
&& ((p_info->unsignedp
? ((unsigned HOST_WIDE_INT) (value + p_info->const_add)
> (unsigned HOST_WIDE_INT) INTVAL (cmp1))
: (value + p_info->const_add) > INTVAL (cmp1))
!= (p_info->const_add > 0))))
cmp1 = force_reg (mode, cmp1);
}
/* See if we need to invert the result. */ case LEU:
invert = (GET_CODE (cmp1) == CONST_INT return sleu_operand (cmp1, VOIDmode);
? p_info->invert_const : p_info->invert_reg);
if (p_invert != (int *)0) default:
{ abort ();
*p_invert = invert;
invert = 0;
} }
}
/* Comparison to constants, may involve adding 1 to change a LT into LE. /* Compare CMP0 and CMP1 using relational operator CODE and store the
Comparison between two registers, may involve switching operands. */ result in TARGET. CMP0 and TARGET are register_operands that have
if (GET_CODE (cmp1) == CONST_INT) the same integer mode. If INVERT_PTR is nonnull, it's OK to set
{ TARGET to the inverse of the result and flip *INVERT_PTR instead. */
if (p_info->const_add != 0)
{
HOST_WIDE_INT new = INTVAL (cmp1) + p_info->const_add;
/* If modification of cmp1 caused overflow,
we would get the wrong answer if we follow the usual path;
thus, x > 0xffffffffU would turn into x > 0U. */
if ((p_info->unsignedp
? (unsigned HOST_WIDE_INT) new >
(unsigned HOST_WIDE_INT) INTVAL (cmp1)
: new > INTVAL (cmp1))
!= (p_info->const_add > 0))
{
/* This test is always true, but if INVERT is true then
the result of the test needs to be inverted so 0 should
be returned instead. */
emit_move_insn (result, invert ? const0_rtx : const_true_rtx);
return result;
}
else
cmp1 = GEN_INT (new);
}
}
else if (p_info->reverse_regs) static void
{ mips_emit_int_relational (enum rtx_code code, bool *invert_ptr,
rtx temp = cmp0; rtx target, rtx cmp0, rtx cmp1)
cmp0 = cmp1; {
cmp1 = temp; /* First see if there is a MIPS instruction that can do this operation
} with CMP1 in its current form. If not, try doing the same for the
inverse operation. If that also fails, force CMP1 into a register
if (test == ITEST_NE && GET_CODE (cmp1) == CONST_INT && INTVAL (cmp1) == 0) and try again. */
reg = cmp0; if (mips_relational_operand_ok_p (code, cmp1))
mips_emit_binary (code, target, cmp0, cmp1);
else else
{ {
reg = (invert || eqne_p) ? gen_reg_rtx (mode) : result; enum rtx_code inv_code = reverse_condition (code);
convert_move (reg, gen_rtx_fmt_ee (p_info->test_code, if (!mips_relational_operand_ok_p (inv_code, cmp1))
mode, cmp0, cmp1), 0); {
} cmp1 = force_reg (GET_MODE (cmp0), cmp1);
mips_emit_int_relational (code, invert_ptr, target, cmp0, cmp1);
if (test == ITEST_NE) }
{ else if (invert_ptr == 0)
if (! TARGET_MIPS16)
{ {
convert_move (result, gen_rtx_GTU (mode, reg, const0_rtx), 0); rtx inv_target = gen_reg_rtx (GET_MODE (target));
if (p_invert != NULL) mips_emit_binary (inv_code, inv_target, cmp0, cmp1);
*p_invert = 0; mips_emit_binary (XOR, target, inv_target, const1_rtx);
invert = 0;
} }
else else
{ {
reg2 = invert ? gen_reg_rtx (mode) : result; *invert_ptr = !*invert_ptr;
convert_move (reg2, gen_rtx_LTU (mode, reg, const1_rtx), 0); mips_emit_binary (inv_code, target, cmp0, cmp1);
reg = reg2;
} }
} }
}
else if (test == ITEST_EQ) /* Return a register that is zero iff CMP0 and CMP1 are equal.
{ The register will have the same mode as CMP0. */
reg2 = invert ? gen_reg_rtx (mode) : result;
convert_move (reg2, gen_rtx_LTU (mode, reg, const1_rtx), 0);
reg = reg2;
}
if (invert) static rtx
{ mips_zero_if_equal (rtx cmp0, rtx cmp1)
rtx one; {
if (cmp1 == const0_rtx)
return cmp0;
if (! TARGET_MIPS16) return expand_binop (GET_MODE (cmp0), xor_optab,
one = const1_rtx; cmp0, cmp1, 0, 0, OPTAB_DIRECT);
else }
{
/* The value is in $24. Copy it to another register, so
that reload doesn't think it needs to store the $24 and
the input to the XOR in the same location. */
reg2 = gen_reg_rtx (mode);
emit_move_insn (reg2, reg);
reg = reg2;
one = force_reg (mode, const1_rtx);
}
convert_move (result, gen_rtx_XOR (mode, reg, one), 0);
}
return result; /* Try comparing cmp_operands[0] and cmp_operands[1] using rtl code CODE.
Store the result in TARGET and return true if successful.
On 64-bit targets, TARGET may be wider than cmp_operands[0]. */
bool
mips_emit_scc (enum rtx_code code, rtx target)
{
if (GET_MODE_CLASS (GET_MODE (cmp_operands[0])) != MODE_INT)
return false;
target = gen_lowpart (GET_MODE (cmp_operands[0]), target);
if (code == EQ || code == NE)
{
rtx zie = mips_zero_if_equal (cmp_operands[0], cmp_operands[1]);
mips_emit_binary (code, target, zie, const0_rtx);
}
else
mips_emit_int_relational (code, 0, target,
cmp_operands[0], cmp_operands[1]);
return true;
} }
/* Work out how to check a floating-point condition. We need a /* Work out how to check a floating-point condition. We need a
...@@ -2970,74 +2838,67 @@ get_float_compare_codes (enum rtx_code in_code, enum rtx_code *cmp_code, ...@@ -2970,74 +2838,67 @@ get_float_compare_codes (enum rtx_code in_code, enum rtx_code *cmp_code,
void void
gen_conditional_branch (rtx *operands, enum rtx_code test_code) gen_conditional_branch (rtx *operands, enum rtx_code test_code)
{ {
rtx cmp0 = cmp_operands[0]; rtx cmp0, cmp1, target;
rtx cmp1 = cmp_operands[1];
enum machine_mode mode; enum machine_mode mode;
enum rtx_code cmp_code; enum rtx_code cmp_code;
rtx reg;
int invert;
rtx label1, label2;
switch (GET_MODE (cmp0)) switch (GET_MODE (cmp_operands[0]))
{ {
case SImode: case SImode:
case DImode: case DImode:
mode = GET_MODE (cmp0); mode = GET_MODE (cmp_operands[0]);
invert = 0; if (!TARGET_MIPS16 && cmp_operands[1] == const0_rtx)
reg = gen_int_relational (test_code, NULL_RTX, cmp0, cmp1, &invert); {
cmp0 = cmp_operands[0];
if (reg) 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
{ {
cmp0 = reg; bool invert = false;
cmp0 = gen_reg_rtx (mode);
cmp1 = const0_rtx; cmp1 = const0_rtx;
test_code = NE; mips_emit_int_relational (test_code, &invert, cmp0,
cmp_operands[0], cmp_operands[1]);
test_code = (invert ? EQ : NE);
} }
else if (GET_CODE (cmp1) == CONST_INT && INTVAL (cmp1) != 0)
/* We don't want to build a comparison against a nonzero
constant. */
cmp1 = force_reg (mode, cmp1);
break; break;
case SFmode: case SFmode:
case DFmode: case DFmode:
if (! ISA_HAS_8CC) mode = CCmode;
reg = gen_rtx_REG (CCmode, FPSW_REGNUM); if (!ISA_HAS_8CC)
cmp0 = gen_rtx_REG (mode, FPSW_REGNUM);
else else
reg = gen_reg_rtx (CCmode); cmp0 = gen_reg_rtx (mode);
cmp1 = const0_rtx;
get_float_compare_codes (test_code, &cmp_code, &test_code); get_float_compare_codes (test_code, &cmp_code, &test_code);
emit_insn (gen_rtx_SET (VOIDmode, reg, mips_emit_binary (cmp_code, cmp0, cmp_operands[0], cmp_operands[1]);
gen_rtx_fmt_ee (cmp_code, CCmode, cmp0, cmp1)));
mode = CCmode;
cmp0 = reg;
cmp1 = const0_rtx;
invert = 0;
break; break;
default: default:
fatal_insn ("bad test", abort ();
gen_rtx_fmt_ee (test_code, VOIDmode, cmp0, cmp1));
} }
/* Generate the branch. */ /* Generate the branch. */
target = gen_rtx_IF_THEN_ELSE (VOIDmode,
label1 = gen_rtx_LABEL_REF (VOIDmode, operands[0]); gen_rtx_fmt_ee (test_code, mode, cmp0, cmp1),
label2 = pc_rtx; gen_rtx_LABEL_REF (VOIDmode, operands[0]),
pc_rtx);
if (invert) emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, target));
{
label2 = label1;
label1 = pc_rtx;
}
emit_jump_insn
(gen_rtx_SET (VOIDmode, pc_rtx,
gen_rtx_IF_THEN_ELSE (VOIDmode,
gen_rtx_fmt_ee (test_code, mode,
cmp0, cmp1),
label1, label2)));
} }
/* Emit the common code for conditional moves. OPERANDS is the array /* Emit the common code for conditional moves. OPERANDS is the array
......
...@@ -2727,6 +2727,8 @@ typedef struct mips_args { ...@@ -2727,6 +2727,8 @@ typedef struct mips_args {
UNSPEC_VOLATILE }}, \ UNSPEC_VOLATILE }}, \
{"arith_operand", { REG, CONST_INT, CONST, SUBREG }}, \ {"arith_operand", { REG, CONST_INT, CONST, SUBREG }}, \
{"reg_or_0_operand", { REG, CONST_INT, CONST_DOUBLE, SUBREG }}, \ {"reg_or_0_operand", { REG, CONST_INT, CONST_DOUBLE, SUBREG }}, \
{"sle_operand", { CONST_INT }}, \
{"sleu_operand", { CONST_INT }}, \
{"small_int", { CONST_INT }}, \ {"small_int", { CONST_INT }}, \
{"const_float_1_operand", { CONST_DOUBLE }}, \ {"const_float_1_operand", { CONST_DOUBLE }}, \
{"reg_or_const_float_1_operand", { CONST_DOUBLE, REG}}, \ {"reg_or_const_float_1_operand", { CONST_DOUBLE, REG}}, \
......
...@@ -6012,14 +6012,7 @@ dsrl\t%3,%3,1\n\ ...@@ -6012,14 +6012,7 @@ dsrl\t%3,%3,1\n\
(eq:SI (match_dup 1) (eq:SI (match_dup 1)
(match_dup 2)))] (match_dup 2)))]
"" ""
{ { if (mips_emit_scc (EQ, operands[0])) DONE; else FAIL; })
if (GET_MODE_CLASS (GET_MODE (cmp_operands[0])) != MODE_INT)
FAIL;
gen_int_relational (EQ, operands[0], cmp_operands[0], cmp_operands[1], NULL);
DONE;
})
(define_insn "*seq_si" (define_insn "*seq_si"
[(set (match_operand:SI 0 "register_operand" "=d") [(set (match_operand:SI 0 "register_operand" "=d")
...@@ -6057,20 +6050,15 @@ dsrl\t%3,%3,1\n\ ...@@ -6057,20 +6050,15 @@ dsrl\t%3,%3,1\n\
[(set_attr "type" "slt") [(set_attr "type" "slt")
(set_attr "mode" "DI")]) (set_attr "mode" "DI")])
;; On the mips16 the default code is better than using sltu. ;; "sne" uses sltu instructions in which the first operand is $0.
;; This isn't possible in mips16 code.
(define_expand "sne" (define_expand "sne"
[(set (match_operand:SI 0 "register_operand") [(set (match_operand:SI 0 "register_operand")
(ne:SI (match_dup 1) (ne:SI (match_dup 1)
(match_dup 2)))] (match_dup 2)))]
"!TARGET_MIPS16" "!TARGET_MIPS16"
{ { if (mips_emit_scc (NE, operands[0])) DONE; else FAIL; })
if (GET_MODE_CLASS (GET_MODE (cmp_operands[0])) != MODE_INT)
FAIL;
gen_int_relational (NE, operands[0], cmp_operands[0], cmp_operands[1], NULL);
DONE;
})
(define_insn "*sne_si" (define_insn "*sne_si"
[(set (match_operand:SI 0 "register_operand" "=d") [(set (match_operand:SI 0 "register_operand" "=d")
...@@ -6095,13 +6083,7 @@ dsrl\t%3,%3,1\n\ ...@@ -6095,13 +6083,7 @@ dsrl\t%3,%3,1\n\
(gt:SI (match_dup 1) (gt:SI (match_dup 1)
(match_dup 2)))] (match_dup 2)))]
"" ""
{ { if (mips_emit_scc (GT, operands[0])) DONE; else FAIL; })
if (GET_MODE_CLASS (GET_MODE (cmp_operands[0])) != MODE_INT)
FAIL;
gen_int_relational (GT, operands[0], cmp_operands[0], cmp_operands[1], NULL);
DONE;
})
(define_insn "*sgt_si" (define_insn "*sgt_si"
[(set (match_operand:SI 0 "register_operand" "=d") [(set (match_operand:SI 0 "register_operand" "=d")
...@@ -6144,26 +6126,32 @@ dsrl\t%3,%3,1\n\ ...@@ -6144,26 +6126,32 @@ dsrl\t%3,%3,1\n\
(ge:SI (match_dup 1) (ge:SI (match_dup 1)
(match_dup 2)))] (match_dup 2)))]
"" ""
{ { if (mips_emit_scc (GE, operands[0])) DONE; else FAIL; })
if (GET_MODE_CLASS (GET_MODE (cmp_operands[0])) != MODE_INT)
FAIL;
gen_int_relational (GE, operands[0], cmp_operands[0], cmp_operands[1], NULL); (define_insn "*sge_si"
DONE; [(set (match_operand:SI 0 "register_operand" "=d")
}) (ge:SI (match_operand:SI 1 "register_operand" "d")
(const_int 1)))]
"!TARGET_MIPS16"
"slt\t%0,%.,%1"
[(set_attr "type" "slt")
(set_attr "mode" "SI")])
(define_insn "*sge_di"
[(set (match_operand:DI 0 "register_operand" "=d")
(ge:DI (match_operand:DI 1 "register_operand" "d")
(const_int 1)))]
"TARGET_64BIT && !TARGET_MIPS16"
"slt\t%0,%.,%1"
[(set_attr "type" "slt")
(set_attr "mode" "DI")])
(define_expand "slt" (define_expand "slt"
[(set (match_operand:SI 0 "register_operand") [(set (match_operand:SI 0 "register_operand")
(lt:SI (match_dup 1) (lt:SI (match_dup 1)
(match_dup 2)))] (match_dup 2)))]
"" ""
{ { if (mips_emit_scc (LT, operands[0])) DONE; else FAIL; })
if (GET_MODE_CLASS (GET_MODE (cmp_operands[0])) != MODE_INT)
FAIL;
gen_int_relational (LT, operands[0], cmp_operands[0], cmp_operands[1], NULL);
DONE;
})
(define_insn "*slt_si" (define_insn "*slt_si"
[(set (match_operand:SI 0 "register_operand" "=d") [(set (match_operand:SI 0 "register_operand" "=d")
...@@ -6216,19 +6204,13 @@ dsrl\t%3,%3,1\n\ ...@@ -6216,19 +6204,13 @@ dsrl\t%3,%3,1\n\
(le:SI (match_dup 1) (le:SI (match_dup 1)
(match_dup 2)))] (match_dup 2)))]
"" ""
{ { if (mips_emit_scc (LE, operands[0])) DONE; else FAIL; })
if (GET_MODE_CLASS (GET_MODE (cmp_operands[0])) != MODE_INT)
FAIL;
gen_int_relational (LE, operands[0], cmp_operands[0], cmp_operands[1], NULL);
DONE;
})
(define_insn "*sle_si" (define_insn "*sle_si"
[(set (match_operand:SI 0 "register_operand" "=d") [(set (match_operand:SI 0 "register_operand" "=d")
(le:SI (match_operand:SI 1 "register_operand" "d") (le:SI (match_operand:SI 1 "register_operand" "d")
(match_operand:SI 2 "small_int" "I")))] (match_operand:SI 2 "sle_operand" "")))]
"!TARGET_MIPS16 && INTVAL (operands[2]) < 32767" "!TARGET_MIPS16"
{ {
operands[2] = GEN_INT (INTVAL (operands[2]) + 1); operands[2] = GEN_INT (INTVAL (operands[2]) + 1);
return "slt\t%0,%1,%2"; return "slt\t%0,%1,%2";
...@@ -6239,8 +6221,8 @@ dsrl\t%3,%3,1\n\ ...@@ -6239,8 +6221,8 @@ dsrl\t%3,%3,1\n\
(define_insn "*sle_si_mips16" (define_insn "*sle_si_mips16"
[(set (match_operand:SI 0 "register_operand" "=t") [(set (match_operand:SI 0 "register_operand" "=t")
(le:SI (match_operand:SI 1 "register_operand" "d") (le:SI (match_operand:SI 1 "register_operand" "d")
(match_operand:SI 2 "small_int" "I")))] (match_operand:SI 2 "sle_operand" "")))]
"TARGET_MIPS16 && INTVAL (operands[2]) < 32767" "TARGET_MIPS16"
{ {
operands[2] = GEN_INT (INTVAL (operands[2]) + 1); operands[2] = GEN_INT (INTVAL (operands[2]) + 1);
return "slt\t%1,%2"; return "slt\t%1,%2";
...@@ -6254,8 +6236,8 @@ dsrl\t%3,%3,1\n\ ...@@ -6254,8 +6236,8 @@ dsrl\t%3,%3,1\n\
(define_insn "*sle_di" (define_insn "*sle_di"
[(set (match_operand:DI 0 "register_operand" "=d") [(set (match_operand:DI 0 "register_operand" "=d")
(le:DI (match_operand:DI 1 "register_operand" "d") (le:DI (match_operand:DI 1 "register_operand" "d")
(match_operand:DI 2 "small_int" "I")))] (match_operand:DI 2 "sle_operand" "")))]
"TARGET_64BIT && !TARGET_MIPS16 && INTVAL (operands[2]) < 32767" "TARGET_64BIT && !TARGET_MIPS16"
{ {
operands[2] = GEN_INT (INTVAL (operands[2]) + 1); operands[2] = GEN_INT (INTVAL (operands[2]) + 1);
return "slt\t%0,%1,%2"; return "slt\t%0,%1,%2";
...@@ -6266,8 +6248,8 @@ dsrl\t%3,%3,1\n\ ...@@ -6266,8 +6248,8 @@ dsrl\t%3,%3,1\n\
(define_insn "*sle_di_mips16" (define_insn "*sle_di_mips16"
[(set (match_operand:DI 0 "register_operand" "=t") [(set (match_operand:DI 0 "register_operand" "=t")
(le:DI (match_operand:DI 1 "register_operand" "d") (le:DI (match_operand:DI 1 "register_operand" "d")
(match_operand:DI 2 "small_int" "I")))] (match_operand:DI 2 "sle_operand" "")))]
"TARGET_64BIT && TARGET_MIPS16 && INTVAL (operands[2]) < 32767" "TARGET_64BIT && TARGET_MIPS16"
{ {
operands[2] = GEN_INT (INTVAL (operands[2]) + 1); operands[2] = GEN_INT (INTVAL (operands[2]) + 1);
return "slt\t%1,%2"; return "slt\t%1,%2";
...@@ -6283,13 +6265,7 @@ dsrl\t%3,%3,1\n\ ...@@ -6283,13 +6265,7 @@ dsrl\t%3,%3,1\n\
(gtu:SI (match_dup 1) (gtu:SI (match_dup 1)
(match_dup 2)))] (match_dup 2)))]
"" ""
{ { if (mips_emit_scc (GTU, operands[0])) DONE; else FAIL; })
if (GET_MODE_CLASS (GET_MODE (cmp_operands[0])) != MODE_INT)
FAIL;
gen_int_relational (GTU, operands[0], cmp_operands[0], cmp_operands[1], NULL);
DONE;
})
(define_insn "*sgtu_si" (define_insn "*sgtu_si"
[(set (match_operand:SI 0 "register_operand" "=d") [(set (match_operand:SI 0 "register_operand" "=d")
...@@ -6332,26 +6308,32 @@ dsrl\t%3,%3,1\n\ ...@@ -6332,26 +6308,32 @@ dsrl\t%3,%3,1\n\
(geu:SI (match_dup 1) (geu:SI (match_dup 1)
(match_dup 2)))] (match_dup 2)))]
"" ""
{ { if (mips_emit_scc (GEU, operands[0])) DONE; else FAIL; })
if (GET_MODE_CLASS (GET_MODE (cmp_operands[0])) != MODE_INT)
FAIL;
gen_int_relational (GEU, operands[0], cmp_operands[0], cmp_operands[1], NULL); (define_insn "*sge_si"
DONE; [(set (match_operand:SI 0 "register_operand" "=d")
}) (geu:SI (match_operand:SI 1 "register_operand" "d")
(const_int 1)))]
"!TARGET_MIPS16"
"sltu\t%0,%.,%1"
[(set_attr "type" "slt")
(set_attr "mode" "SI")])
(define_insn "*sge_di"
[(set (match_operand:DI 0 "register_operand" "=d")
(geu:DI (match_operand:DI 1 "register_operand" "d")
(const_int 1)))]
"TARGET_64BIT && !TARGET_MIPS16"
"sltu\t%0,%.,%1"
[(set_attr "type" "slt")
(set_attr "mode" "DI")])
(define_expand "sltu" (define_expand "sltu"
[(set (match_operand:SI 0 "register_operand") [(set (match_operand:SI 0 "register_operand")
(ltu:SI (match_dup 1) (ltu:SI (match_dup 1)
(match_dup 2)))] (match_dup 2)))]
"" ""
{ { if (mips_emit_scc (LTU, operands[0])) DONE; else FAIL; })
if (GET_MODE_CLASS (GET_MODE (cmp_operands[0])) != MODE_INT)
FAIL;
gen_int_relational (LTU, operands[0], cmp_operands[0], cmp_operands[1], NULL);
DONE;
})
(define_insn "*sltu_si" (define_insn "*sltu_si"
[(set (match_operand:SI 0 "register_operand" "=d") [(set (match_operand:SI 0 "register_operand" "=d")
...@@ -6404,19 +6386,13 @@ dsrl\t%3,%3,1\n\ ...@@ -6404,19 +6386,13 @@ dsrl\t%3,%3,1\n\
(leu:SI (match_dup 1) (leu:SI (match_dup 1)
(match_dup 2)))] (match_dup 2)))]
"" ""
{ { if (mips_emit_scc (LEU, operands[0])) DONE; else FAIL; })
if (GET_MODE_CLASS (GET_MODE (cmp_operands[0])) != MODE_INT)
FAIL;
gen_int_relational (LEU, operands[0], cmp_operands[0], cmp_operands[1], NULL);
DONE;
})
(define_insn "*sleu_si" (define_insn "*sleu_si"
[(set (match_operand:SI 0 "register_operand" "=d") [(set (match_operand:SI 0 "register_operand" "=d")
(leu:SI (match_operand:SI 1 "register_operand" "d") (leu:SI (match_operand:SI 1 "register_operand" "d")
(match_operand:SI 2 "small_int" "I")))] (match_operand:SI 2 "sleu_operand" "")))]
"!TARGET_MIPS16 && INTVAL (operands[2]) < 32767" "!TARGET_MIPS16"
{ {
operands[2] = GEN_INT (INTVAL (operands[2]) + 1); operands[2] = GEN_INT (INTVAL (operands[2]) + 1);
return "sltu\t%0,%1,%2"; return "sltu\t%0,%1,%2";
...@@ -6427,8 +6403,8 @@ dsrl\t%3,%3,1\n\ ...@@ -6427,8 +6403,8 @@ dsrl\t%3,%3,1\n\
(define_insn "*sleu_si_mips16" (define_insn "*sleu_si_mips16"
[(set (match_operand:SI 0 "register_operand" "=t") [(set (match_operand:SI 0 "register_operand" "=t")
(leu:SI (match_operand:SI 1 "register_operand" "d") (leu:SI (match_operand:SI 1 "register_operand" "d")
(match_operand:SI 2 "small_int" "I")))] (match_operand:SI 2 "sleu_operand" "")))]
"TARGET_MIPS16 && INTVAL (operands[2]) < 32767" "TARGET_MIPS16"
{ {
operands[2] = GEN_INT (INTVAL (operands[2]) + 1); operands[2] = GEN_INT (INTVAL (operands[2]) + 1);
return "sltu\t%1,%2"; return "sltu\t%1,%2";
...@@ -6442,8 +6418,8 @@ dsrl\t%3,%3,1\n\ ...@@ -6442,8 +6418,8 @@ dsrl\t%3,%3,1\n\
(define_insn "*sleu_di" (define_insn "*sleu_di"
[(set (match_operand:DI 0 "register_operand" "=d") [(set (match_operand:DI 0 "register_operand" "=d")
(leu:DI (match_operand:DI 1 "register_operand" "d") (leu:DI (match_operand:DI 1 "register_operand" "d")
(match_operand:DI 2 "small_int" "I")))] (match_operand:DI 2 "sleu_operand" "")))]
"TARGET_64BIT && !TARGET_MIPS16 && INTVAL (operands[2]) < 32767" "TARGET_64BIT && !TARGET_MIPS16"
{ {
operands[2] = GEN_INT (INTVAL (operands[2]) + 1); operands[2] = GEN_INT (INTVAL (operands[2]) + 1);
return "sltu\t%0,%1,%2"; return "sltu\t%0,%1,%2";
...@@ -6454,8 +6430,8 @@ dsrl\t%3,%3,1\n\ ...@@ -6454,8 +6430,8 @@ dsrl\t%3,%3,1\n\
(define_insn "*sleu_di_mips16" (define_insn "*sleu_di_mips16"
[(set (match_operand:DI 0 "register_operand" "=t") [(set (match_operand:DI 0 "register_operand" "=t")
(leu:DI (match_operand:DI 1 "register_operand" "d") (leu:DI (match_operand:DI 1 "register_operand" "d")
(match_operand:DI 2 "small_int" "I")))] (match_operand:DI 2 "sleu_operand" "")))]
"TARGET_64BIT && TARGET_MIPS16 && INTVAL (operands[2]) < 32767" "TARGET_64BIT && TARGET_MIPS16"
{ {
operands[2] = GEN_INT (INTVAL (operands[2]) + 1); operands[2] = GEN_INT (INTVAL (operands[2]) + 1);
return "sltu\t%1,%2"; return "sltu\t%1,%2";
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment