Commit 34b650b3 by Michael Meissner

*** empty log message ***

From-SVN: r844
parent 31d04616
......@@ -94,6 +94,24 @@ extern char **save_argv;
extern char *version_string;
extern char *language_string;
/* 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
};
/* Global variables for machine-dependent things. */
/* Threshold for data being put into the small data/bss area, instead
......@@ -462,6 +480,16 @@ md_register_operand (op, mode)
&& MD_REG_P (REGNO (op)));
}
/* Return truth value of whether OP is the FP status register. */
int
fpsw_register_operand (op, mode)
rtx op;
enum machine_mode mode;
{
return (GET_CODE (op) == REG && ST_REG_P (REGNO (op)));
}
/* Return truth value if a CONST_DOUBLE is ok to be a legitimate constant. */
int
......@@ -659,6 +687,23 @@ fcmp_op (op, mode)
}
/* Return true if the operand is either the PC or a label_ref. */
int
pc_or_label_operand (op, mode)
rtx op;
enum machine_mode mode;
{
if (op == pc_rtx)
return TRUE;
if (GET_CODE (op) == LABEL_REF)
return TRUE;
return FALSE;
}
/* Return an operand string if the given instruction's delay slot or
wrap it in a .set noreorder section. This is for filling delay
slots on load type instructions under GAS, which does no reordering
......@@ -683,7 +728,7 @@ mips_fill_delay_slot (ret, type, operands, cur_insn)
register rtx next_insn = (cur_insn) ? NEXT_INSN (cur_insn) : (rtx)0;
register int num_nops;
if (type == DELAY_LOAD)
if (type == DELAY_LOAD || type == DELAY_FCMP)
num_nops = 1;
else if (type == DELAY_HILO)
......@@ -1436,6 +1481,210 @@ mips_address_cost (addr)
}
/* Make normal rtx_code into something we can index from an array */
static enum internal_test
map_test_to_internal_test (test_code)
enum rtx_code test_code;
{
enum internal_test test = ITEST_MAX;
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;
}
return test;
}
/* Generate the code to compare two integer values. The return value is:
(reg:SI xx) The pseudo register the comparison is in
(const_int 0) The comparison is always false
(const_int 1) The comparison is always true
(rtx)0 No register, generate a simple branch. */
rtx
gen_int_relational (test_code, result, cmp0, cmp1, p_invert)
enum rtx_code test_code; /* relational test (EQ, etc) */
rtx result; /* result to store comp. or 0 if branch */
rtx cmp0; /* first operand to compare */
rtx cmp1; /* second operand to compare */
int *p_invert; /* NULL or ptr to hold whether branch needs */
/* to reserse it's test */
{
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 */
};
static struct cmp_info info[ (int)ITEST_MAX ] = {
{ XOR, 0, 65535, 0, 0, 0, 0 }, /* EQ */
{ XOR, 0, 65535, 0, 0, 1, 1 }, /* NE */
{ LT, -32769, 32766, 1, 1, 1, 0 }, /* GT */
{ LT, -32768, 32767, 0, 0, 1, 1 }, /* GE */
{ LT, -32768, 32767, 0, 0, 0, 0 }, /* LT */
{ LT, -32769, 32766, 1, 1, 0, 1 }, /* LE */
{ LTU, -32769, 32766, 1, 1, 1, 0 }, /* GTU */
{ LTU, -32768, 32767, 0, 0, 1, 1 }, /* GEU */
{ LTU, -32768, 32767, 0, 0, 0, 0 }, /* LTU */
{ LTU, -32769, 32766, 1, 1, 0, 1 }, /* LEU */
};
enum internal_test test;
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);
/* See if the test is always true or false. */
if ((GET_CODE (cmp0) == REG || GET_CODE (cmp0) == SUBREG)
&& GET_CODE (cmp1) == CONST_INT)
{
int value = INTVAL (cmp1);
rtx truth = (rtx)0;
if (test == ITEST_GEU && value == 0)
truth = const1_rtx;
else if (test == ITEST_LTU && value == 0)
truth = const0_rtx;
else if (!TARGET_INT64)
{
if (test == ITEST_LTU && value == -1)
truth = const1_rtx;
else if (test == ITEST_GTU && value == -1)
truth = const0_rtx;
else if (test == ITEST_LEU && value == -1)
truth = const1_rtx;
else if (test == ITEST_GT && value == 0x7fffffff)
truth = const0_rtx;
else if (test == ITEST_LE && value == 0x7fffffff)
truth = const1_rtx;
else if (test == ITEST_LT && value == 0x80000000)
truth = const0_rtx;
else if (test == ITEST_GE && value == 0x80000000)
truth = const1_rtx;
}
if (truth != (rtx)0)
{
if (result != (rtx)0)
emit_move_insn (result, truth);
return truth;
}
}
/* Eliminate simple branches */
branch_p = (result == (rtx)0);
if (branch_p)
{
if (GET_CODE (cmp0) == REG || GET_CODE (cmp0) == SUBREG)
{
/* Comparisons against zero are simple branches */
if (GET_CODE (cmp1) == CONST_INT && INTVAL (cmp1) == 0)
return (rtx)0;
/* Test for beq/bne. */
if (eqne_p)
return (rtx)0;
}
/* allocate a psuedo to calculate the value in. */
result = gen_reg_rtx (SImode);
}
/* Make sure we can handle any constants given to us. */
if (GET_CODE (cmp0) == CONST_INT)
cmp0 = force_reg (SImode, cmp0);
if (GET_CODE (cmp1) == CONST_INT)
{
int value = INTVAL (cmp1);
if (value < p_info->const_low || value > p_info->const_high)
cmp1 = force_reg (SImode, cmp1);
}
/* See if we need to invert the result. */
invert = (GET_CODE (cmp1) == CONST_INT)
? p_info->invert_const
: p_info->invert_reg;
if (p_invert != (int *)0)
{
*p_invert = invert;
invert = FALSE;
}
/* Comparison to constants, may involve adding 1 to change a LT into LE.
Comparison between two registers, may involve switching operands. */
if (GET_CODE (cmp1) == CONST_INT)
{
if (p_info->const_add != 0)
cmp1 = gen_rtx (CONST_INT, VOIDmode, INTVAL (cmp1) + p_info->const_add);
}
else if (p_info->reverse_regs)
{
rtx temp = cmp0;
cmp0 = cmp1;
cmp1 = temp;
}
reg = (invert || eqne_p) ? gen_reg_rtx (SImode) : result;
emit_move_insn (reg, gen_rtx (p_info->test_code, SImode, cmp0, cmp1));
if (test == ITEST_NE && GET_CODE (cmp1) == CONST_INT && INTVAL (cmp1) == 0)
{
emit_move_insn (result, gen_rtx (GTU, SImode, reg, const0_rtx));
invert = FALSE;
}
else if (eqne_p)
{
reg2 = (invert) ? gen_reg_rtx (SImode) : result;
emit_move_insn (reg2, gen_rtx (LTU, SImode, reg, const1_rtx));
reg = reg2;
}
if (invert)
emit_move_insn (result, gen_rtx (XOR, SImode, reg, const1_rtx));
return result;
}
/* 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,sf,df}. */
......@@ -1445,36 +1694,22 @@ gen_conditional_branch (operands, test_code)
rtx operands[];
enum rtx_code test_code;
{
enum {
I_EQ,
I_NE,
I_GT,
I_GE,
I_LT,
I_LE,
I_GTU,
I_GEU,
I_LTU,
I_LEU,
I_MAX
} test = I_MAX;
static enum machine_mode mode_map[(int)CMP_MAX][(int)I_MAX] = {
static enum machine_mode mode_map[(int)CMP_MAX][(int)ITEST_MAX] = {
{ /* CMP_SI */
CC_EQmode, /* eq */
CC_EQmode, /* ne */
CCmode, /* gt */
CCmode, /* ge */
CCmode, /* lt */
CCmode, /* le */
CCmode, /* gtu */
CCmode, /* geu */
CCmode, /* ltu */
CCmode, /* leu */
SImode, /* eq */
SImode, /* ne */
SImode, /* gt */
SImode, /* ge */
SImode, /* lt */
SImode, /* le */
SImode, /* gtu */
SImode, /* geu */
SImode, /* ltu */
SImode, /* leu */
},
{ /* CMP_SF */
CC_FPmode, /* eq */
CC_FPmode, /* ne */
CC_REV_FPmode, /* ne */
CC_FPmode, /* gt */
CC_FPmode, /* ge */
CC_FPmode, /* lt */
......@@ -1486,7 +1721,7 @@ gen_conditional_branch (operands, test_code)
},
{ /* CMP_DF */
CC_FPmode, /* eq */
CC_FPmode, /* ne */
CC_REV_FPmode, /* ne */
CC_FPmode, /* gt */
CC_FPmode, /* ge */
CC_FPmode, /* lt */
......@@ -1502,30 +1737,19 @@ gen_conditional_branch (operands, test_code)
enum cmp_type type = branch_type;
rtx cmp0 = branch_cmp[0];
rtx cmp1 = branch_cmp[1];
rtx label = gen_rtx (LABEL_REF, VOIDmode, operands[0]);
/* Make normal rtx_code into something we can index from an array */
switch (test_code)
{
case EQ: test = I_EQ; break;
case NE: test = I_NE; break;
case GT: test = I_GT; break;
case GE: test = I_GE; break;
case LT: test = I_LT; break;
case LE: test = I_LE; break;
case GTU: test = I_GTU; break;
case GEU: test = I_GEU; break;
case LTU: test = I_LTU; break;
case LEU: test = I_LEU; break;
}
rtx label1 = gen_rtx (LABEL_REF, VOIDmode, operands[0]);
rtx label2 = pc_rtx;
rtx reg = (rtx)0;
int invert = 0;
enum internal_test test = map_test_to_internal_test (test_code);
if (test == I_MAX)
if (test == ITEST_MAX)
{
mode = CCmode;
mode = SImode;
goto fail;
}
/* Get the machine mode to use (CCmode, CC_EQmode, or CC_FPmode). */
/* Get the machine mode to use (CCmode, CC_EQmode, CC_FPmode, or CC_REV_FPmode). */
mode = mode_map[(int)type][(int)test];
if (mode == VOIDmode)
goto fail;
......@@ -1536,50 +1760,46 @@ gen_conditional_branch (operands, test_code)
goto fail;
case CMP_SI:
/* Change >, >=, <, <= tests against 0 to use CC_0mode, since we have
special instructions to do these tests directly. */
if (mode == CCmode && GET_CODE (cmp1) == CONST_INT && INTVAL (cmp1) == 0)
{
emit_insn (gen_rtx (SET, VOIDmode, cc0_rtx, cmp0));
mode = CC_0mode;
}
else if (mode == CCmode && GET_CODE (cmp0) == CONST_INT && INTVAL (cmp0) == 0)
reg = gen_int_relational (test_code, (rtx)0, cmp0, cmp1, &invert);
if (reg != (rtx)0)
{
emit_insn (gen_rtx (SET, VOIDmode, cc0_rtx, cmp1));
test_code = reverse_condition (test_code);
mode = CC_0mode;
cmp0 = reg;
cmp1 = const0_rtx;
test_code = NE;
}
else
{
/* force args to register for equality comparisons. */
if (mode == CC_EQmode && GET_CODE (cmp1) == CONST_INT && INTVAL (cmp1) != 0)
/* Make sure not non-zero constant if ==/!= */
else if (GET_CODE (cmp1) == CONST_INT && INTVAL (cmp1) != 0)
cmp1 = force_reg (SImode, cmp1);
emit_insn (gen_rtx (SET, VOIDmode,
cc0_rtx,
gen_rtx (COMPARE, mode, cmp0, cmp1)));
}
break;
case CMP_DF:
emit_insn (gen_cmpdf_internal (cmp0, cmp1));
break;
case CMP_SF:
emit_insn (gen_cmpsf_internal (cmp0, cmp1));
{
rtx reg = gen_rtx (REG, mode, FPSW_REGNUM);
emit_insn (gen_rtx (SET, VOIDmode, reg, gen_rtx (test_code, mode, cmp0, cmp1)));
cmp0 = reg;
cmp1 = const0_rtx;
test_code = NE;
}
break;
}
/* Generate the jump */
if (invert)
{
label2 = label1;
label1 = pc_rtx;
}
emit_jump_insn (gen_rtx (SET, VOIDmode,
pc_rtx,
gen_rtx (IF_THEN_ELSE, VOIDmode,
gen_rtx (test_code, mode, cc0_rtx, const0_rtx),
label,
pc_rtx)));
gen_rtx (test_code, mode, cmp0, cmp1),
label1,
label2)));
return;
fail:
......@@ -2728,9 +2948,9 @@ override_options ()
mips_char_to_class['f'] = ((TARGET_HARD_FLOAT) ? FP_REGS : NO_REGS);
mips_char_to_class['h'] = HI_REG;
mips_char_to_class['l'] = LO_REG;
mips_char_to_class['s'] = ST_REGS;
mips_char_to_class['x'] = MD_REGS;
mips_char_to_class['y'] = GR_REGS;
mips_char_to_class['z'] = ST_REGS;
/* Set up array to map GCC register number to debug register number.
Ignore the special purpose register numbers. */
......@@ -2762,22 +2982,25 @@ override_options ()
for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
{
register int temp = FALSE;
register int temp;
if (mode == CC_FPmode || mode == CC_REV_FPmode)
temp = (regno == FPSW_REGNUM);
if (GP_REG_P (regno))
else if (GP_REG_P (regno))
temp = ((regno & 1) == 0 || (size <= UNITS_PER_WORD));
else if (FP_REG_P (regno))
temp = ((TARGET_FLOAT64 || ((regno & 1) == 0))
&& (TARGET_DEBUG_H_MODE
|| class == MODE_FLOAT
|| class == MODE_COMPLEX_FLOAT));
&& (class == MODE_FLOAT
|| class == MODE_COMPLEX_FLOAT
|| (TARGET_DEBUG_H_MODE && class == MODE_INT)));
else if (MD_REG_P (regno))
temp = (mode == SImode || (regno == MD_REG_FIRST && mode == DImode));
else if (ST_REG_P (regno))
temp = ((mode == SImode) || (class == MODE_CC));
else
temp = FALSE;
mips_hard_regno_mode_ok[(int)mode][regno] = temp;
}
......
......@@ -49,7 +49,8 @@ enum cmp_type {
enum delay_type {
DELAY_NONE, /* no delay slot */
DELAY_LOAD, /* load from memory delay */
DELAY_HILO /* move from/to hi/lo registers */
DELAY_HILO, /* move from/to hi/lo registers */
DELAY_FCMP /* delay after doing c.<xx>.{d,s} */
};
/* Which processor to schedule for. Since there is no difference between
......@@ -120,12 +121,14 @@ extern unsigned long compute_frame_size ();
extern void expand_block_move ();
extern int equality_op ();
extern int fcmp_op ();
extern int fpsw_register_operand ();
extern struct rtx_def * function_arg ();
extern void function_arg_advance ();
extern int function_arg_partial_nregs ();
extern void function_epilogue ();
extern void function_prologue ();
extern void gen_conditional_branch ();
extern struct rtx_def * gen_int_relational ();
extern void init_cumulative_args ();
extern int large_int ();
extern int md_register_operand ();
......@@ -145,6 +148,7 @@ extern void mips_output_filename ();
extern void mips_output_lineno ();
extern char *output_block_move ();
extern void override_options ();
extern int pc_or_label_operand ();
extern void print_operand_address ();
extern void print_operand ();
extern void print_options ();
......@@ -416,7 +420,7 @@ while (0)
/* Print subsidiary information on the compiler version in use. */
#define MIPS_VERSION "[AL 1.1, MM 15]"
#define MIPS_VERSION "[AL 1.1, MM 16]"
#ifndef MACHINE_TYPE
#define MACHINE_TYPE "BSD Mips"
......@@ -646,7 +650,7 @@ do { \
#define MASK_DEBUG 0x40000000 /* Eliminate version # in .s file */
#define MASK_DEBUG_A 0x20000000 /* don't allow <label>($reg) addrs */
#define MASK_DEBUG_B 0x10000000 /* GO_IF_LEGITIMATE_ADDRESS debug */
#define MASK_DEBUG_C 0x08000000 /* suppress normal divmod patterns */
#define MASK_DEBUG_C 0x08000000 /* allow new seq, sne, etc. patterns */
#define MASK_DEBUG_D 0x04000000 /* don't do define_split's */
#define MASK_DEBUG_E 0x02000000 /* function_arg debug */
#define MASK_DEBUG_F 0x01000000 /* don't try to suppress load nop's */
......@@ -1280,8 +1284,8 @@ extern enum reg_class mips_regno_to_class[];
'f' Floating point registers
'h' Hi register
'l' Lo register
's' Status registers
'x' Multiply/divide registers */
'x' Multiply/divide registers
'z' FP Status register */
extern enum reg_class mips_char_to_class[];
......@@ -2547,47 +2551,34 @@ do \
} \
while (0)
/* A list of names to be used for additional modes for condition
code values in registers (*note Jump Patterns::.). These names
are added to `enum machine_mode' and all have class `MODE_CC'.
By convention, they should start with `CC' and end with `mode'.
/* A list of names to be used for additional modes for condition code
values in registers. These names are added to `enum machine_mode'
and all have class `MODE_CC'. By convention, they should start
with `CC' and end with `mode'.
You should only define this macro if your machine does not use
`cc0' and only if additional modes are required.
On the MIPS, we use CC_FPmode for all floating point, CC_EQmode for
integer equality/inequality comparisons, CC_0mode for comparisons
against 0, and CCmode for other integer comparisons. */
On the MIPS, we use CC_FPmode for all floating point except for not
equal, CC_REV_FPmode for not equal (to reverse the sense of the
jump), CC_EQmode for integer equality/inequality comparisons,
CC_0mode for comparisons against 0, and CCmode for other integer
comparisons. */
#define EXTRA_CC_MODES CC_EQmode, CC_FPmode, CC_0mode
#define EXTRA_CC_MODES CC_EQmode, CC_FPmode, CC_0mode, CC_REV_FPmode
/* A list of C strings giving the names for the modes listed in
`EXTRA_CC_MODES'. For example, the Sparc defines this macro and
`EXTRA_CC_MODES' as
`EXTRA_CC_MODES'. */
#define EXTRA_CC_MODES CC_NOOVmode, CCFPmode
#define EXTRA_CC_NAMES "CC_NOOV", "CCFP"
This macro is not required if `EXTRA_CC_MODES' is not defined. */
#define EXTRA_CC_NAMES "CC_EQ", "CC_FP", "CC_0"
#define EXTRA_CC_NAMES "CC_EQ", "CC_FP", "CC_0", "CC_REV_FP"
/* Returns a mode from class `MODE_CC' to be used when comparison
operation code OP is applied to rtx X. For example, on the
Sparc, `SELECT_CC_MODE' is defined as (see *note Jump
Patterns::. for a description of the reason for this definition)
#define SELECT_CC_MODE(OP,X) \
(GET_MODE_CLASS (GET_MODE (X)) == MODE_FLOAT ? CCFPmode \
: (GET_CODE (X) == PLUS || GET_CODE (X) == MINUS \
|| GET_CODE (X) == NEG) \
? CC_NOOVmode : CCmode)
This macro is not required if `EXTRA_CC_MODES' is not defined. */
operation code OP is applied to rtx X. */
#define SELECT_CC_MODE (OP, X) \
(GET_MODE_CLASS (GET_MODE (X)) == MODE_FLOAT ? CC_FPmode : \
(OP == EQ || OP == NE) ? CC_EQmode : CCmode)
#define SELECT_CC_MODE(OP, X) \
(GET_MODE_CLASS (GET_MODE (X)) != MODE_FLOAT \
? SImode \
: ((OP == NE) ? CC_REV_FPmode : CC_FPmode))
/* Control the assembler format that we output. */
......
......@@ -58,7 +58,7 @@
(const_string "unknown"))
;; Main data type used by the insn
(define_attr "mode" "unknown,none,QI,HI,SI,DI,SF,DF" (const_string "unknown"))
(define_attr "mode" "unknown,none,QI,HI,SI,DI,SF,DF,FPSW" (const_string "unknown"))
;; # instructions (4 bytes each)
(define_attr "length" "" (const_int 1))
......@@ -133,6 +133,8 @@
(define_function_unit "memory" 1 0 (eq_attr "type" "store") 1 0)
(define_function_unit "fp_comp" 1 0 (eq_attr "type" "fcmp") 2 0)
(define_function_unit "transfer" 1 0 (eq_attr "type" "xfer") 2 0)
(define_function_unit "transfer" 1 0 (eq_attr "type" "hilo") 3 0)
......@@ -317,7 +319,7 @@
(subreg:SI (match_dup 2) 0)))
(set (match_dup 3)
(ltu:CC (subreg:SI (match_dup 0) 0)
(ltu:SI (subreg:SI (match_dup 0) 0)
(subreg:SI (match_dup 2) 0)))
(set (subreg:SI (match_dup 0) 1)
......@@ -346,7 +348,7 @@
(subreg:SI (match_dup 2) 1)))
(set (match_dup 3)
(ltu:CC (subreg:SI (match_dup 0) 1)
(ltu:SI (subreg:SI (match_dup 0) 1)
(subreg:SI (match_dup 2) 1)))
(set (subreg:SI (match_dup 0) 0)
......@@ -387,7 +389,7 @@
(match_dup 2)))
(set (match_dup 3)
(ltu:CC (subreg:SI (match_dup 0) 0)
(ltu:SI (subreg:SI (match_dup 0) 0)
(match_dup 2)))
(set (subreg:SI (match_dup 0) 1)
......@@ -410,7 +412,7 @@
(match_dup 2)))
(set (match_dup 3)
(ltu:CC (subreg:SI (match_dup 0) 1)
(ltu:SI (subreg:SI (match_dup 0) 1)
(match_dup 2)))
(set (subreg:SI (match_dup 0) 0)
......@@ -491,7 +493,7 @@
&& GET_CODE (operands[2]) == REG && GP_REG_P (REGNO (operands[2]))"
[(set (match_dup 3)
(ltu:CC (subreg:SI (match_dup 1) 0)
(ltu:SI (subreg:SI (match_dup 1) 0)
(subreg:SI (match_dup 2) 0)))
(set (subreg:SI (match_dup 0) 0)
......@@ -518,7 +520,7 @@
&& GET_CODE (operands[2]) == REG && GP_REG_P (REGNO (operands[2]))"
[(set (match_dup 3)
(ltu:CC (subreg:SI (match_dup 1) 1)
(ltu:SI (subreg:SI (match_dup 1) 1)
(subreg:SI (match_dup 2) 1)))
(set (subreg:SI (match_dup 0) 1)
......@@ -559,7 +561,7 @@
&& INTVAL (operands[2]) > 0"
[(set (match_dup 3)
(ltu:CC (subreg:SI (match_dup 1) 0)
(ltu:SI (subreg:SI (match_dup 1) 0)
(match_dup 2)))
(set (subreg:SI (match_dup 0) 0)
......@@ -582,7 +584,7 @@
&& INTVAL (operands[2]) > 0"
[(set (match_dup 3)
(ltu:CC (subreg:SI (match_dup 1) 1)
(ltu:SI (subreg:SI (match_dup 1) 1)
(match_dup 2)))
(set (subreg:SI (match_dup 0) 1)
......@@ -760,7 +762,7 @@
(match_dup 2)))
(clobber (reg:SI 64))
(clobber (reg:SI 65))]
"optimize && !TARGET_DEBUG_C_MODE"
"optimize"
"*
{
if (find_reg_note (insn, REG_UNUSED, operands[3]))
......@@ -784,7 +786,7 @@
(match_dup 2)))
(clobber (reg:SI 64))
(clobber (reg:SI 65))]
"optimize && !TARGET_DEBUG_C_MODE"
"optimize"
"*
{
if (find_reg_note (insn, REG_UNUSED, operands[3]))
......@@ -805,7 +807,7 @@
(match_operand:SI 2 "register_operand" "d")))
(clobber (reg:SI 64))
(clobber (reg:SI 65))]
"!optimize || TARGET_DEBUG_C_MODE"
"!optimize"
"div\\t%0,%1,%2"
[(set_attr "type" "idiv")
(set_attr "mode" "SI")
......@@ -817,7 +819,7 @@
(match_operand:SI 2 "register_operand" "d")))
(clobber (reg:SI 64))
(clobber (reg:SI 65))]
"!optimize || TARGET_DEBUG_C_MODE"
"!optimize"
"rem\\t%0,%1,%2"
[(set_attr "type" "idiv")
(set_attr "mode" "SI")
......@@ -829,7 +831,7 @@
(match_operand:SI 2 "register_operand" "d")))
(clobber (reg:SI 64))
(clobber (reg:SI 65))]
"!optimize || TARGET_DEBUG_C_MODE"
"!optimize"
"divu\\t%0,%1,%2"
[(set_attr "type" "idiv")
(set_attr "mode" "SI")
......@@ -841,7 +843,7 @@
(match_operand:SI 2 "register_operand" "d")))
(clobber (reg:SI 64))
(clobber (reg:SI 65))]
"!optimize || TARGET_DEBUG_C_MODE"
"!optimize"
"remu\\t%0,%1,%2"
[(set_attr "type" "idiv")
(set_attr "mode" "SI")
......@@ -2629,14 +2631,9 @@ move\\t%0,%z4\\n\\
;; done, so that we can constrain things appropriately. There
;; are assumptions in the rest of GCC that break if we fold the
;; operands into the branchs for integer operations, and use cc0
;; for floating point.
;;
;; 3) The compare define_insns then once again set branch_cmp and
;; branch_type, and the branch define_insns use them.
;;
;; 4) If a set condition code is done instead of a branch, then the
;; operands are folded into the RTL, and a separate set of cc0 is
;; not done. This allows slt's to be put into delay slots.
;; for floating point, so we use the fp status register instead.
;; If needed, an appropriate temporary is created to hold the
;; of the integer compare.
(define_expand "cmpsi"
[(set (cc0)
......@@ -2669,53 +2666,6 @@ move\\t%0,%z4\\n\\
}
}")
(define_insn "cmpsi_eqne"
[(set (cc0)
(compare:CC_EQ (match_operand:SI 0 "register_operand" "dJ")
(match_operand:SI 1 "reg_or_0_operand" "dJ")))]
""
"*
{
branch_cmp[0] = operands[0];
branch_cmp[1] = operands[1];
branch_type = CMP_SI;
return \"\";
}"
[(set_attr "type" "icmp")
(set_attr "mode" "none")
(set_attr "length" "0")])
(define_insn "cmpsi_zero"
[(set (cc0)
(match_operand:SI 0 "reg_or_0_operand" "dJ"))]
""
"*
{
branch_cmp[0] = operands[0];
branch_cmp[1] = const0_rtx;
branch_type = CMP_SI;
return \"\";
}"
[(set_attr "type" "icmp")
(set_attr "mode" "none")
(set_attr "length" "0")])
(define_insn "cmpsi_relational"
[(set (cc0)
(compare:CC (match_operand:SI 0 "register_operand" "dJ")
(match_operand:SI 1 "arith_operand" "dI")))]
""
"*
{
branch_cmp[0] = operands[0];
branch_cmp[1] = operands[1];
branch_type = CMP_SI;
return \"\";
}"
[(set_attr "type" "icmp")
(set_attr "mode" "none")
(set_attr "length" "0")])
(define_expand "cmpdf"
[(set (cc0)
(compare:CC_FP (match_operand:DF 0 "register_operand" "")
......@@ -2732,23 +2682,6 @@ move\\t%0,%z4\\n\\
}
}")
(define_insn "cmpdf_internal"
[(set (cc0)
(compare:CC_FP (match_operand:DF 0 "register_operand" "f")
(match_operand:DF 1 "register_operand" "f")))]
"TARGET_HARD_FLOAT"
"*
{
branch_cmp[0] = operands[0];
branch_cmp[1] = operands[1];
branch_type = CMP_DF;
return \"\";
}"
[(set_attr "type" "fcmp")
(set_attr "mode" "none")
(set_attr "length" "0")])
(define_expand "cmpsf"
[(set (cc0)
(compare:CC_FP (match_operand:SF 0 "register_operand" "")
......@@ -2765,22 +2698,6 @@ move\\t%0,%z4\\n\\
}
}")
(define_insn "cmpsf_internal"
[(set (cc0)
(compare:CC_FP (match_operand:SF 0 "register_operand" "f")
(match_operand:SF 1 "register_operand" "f")))]
"TARGET_HARD_FLOAT"
"*
{
branch_cmp[0] = operands[0];
branch_cmp[1] = operands[1];
branch_type = CMP_SF;
return \"\";
}"
[(set_attr "type" "fcmp")
(set_attr "mode" "none")
(set_attr "length" "0")])
;;
;; ....................
......@@ -2789,224 +2706,163 @@ move\\t%0,%z4\\n\\
;;
;; ....................
;; We really can't note that integer branches clobber $at, and FP
;; branches clobber $fcr31 because if we use a parallel operation, a
;; normal insn is used to hold the value instead of jump_insn. See
;; above for cmpxx saving the operands in branch_cmp and branch_type.
(define_insn "branch_fp_true"
(define_insn "branch_fp_ne"
[(set (pc)
(if_then_else (match_operator:CC_FP 0 "fcmp_op" [(cc0) (const_int 0)])
(label_ref (match_operand 1 "" ""))
(pc)))]
(if_then_else (ne:CC_FP (reg:CC_FP 66)
(const_int 0))
(match_operand 0 "pc_or_label_operand" "")
(match_operand 1 "pc_or_label_operand" "")))]
""
"*
{
operands[2] = branch_cmp[0];
operands[3] = branch_cmp[1];
mips_branch_likely = (final_sequence && INSN_ANNULLED_BRANCH_P (insn));
if (branch_type == CMP_DF)
{
switch (GET_CODE (operands[0]))
{
case EQ: return \"c.eq.d\\t%2,%3%#\;%*bc1t%?\\t%l1\";
case NE: return \"c.eq.d\\t%2,%3%#\;%*bc1f%?\\t%l1\";
case LT: return \"c.lt.d\\t%2,%3%#\;%*bc1t%?\\t%l1\";
case LE: return \"c.le.d\\t%2,%3%#\;%*bc1t%?\\t%l1\";
case GT: return \"c.lt.d\\t%3,%2%#\;%*bc1t%?\\t%l1\";
case GE: return \"c.le.d\\t%3,%2%#\;%*bc1t%?\\t%l1\";
}
}
else if (branch_type == CMP_SF)
{
switch (GET_CODE (operands[0]))
{
case EQ: return \"c.eq.s\\t%2,%3%#\;%*bc1t%?\\t%l1\";
case NE: return \"c.eq.s\\t%2,%3%#\;%*bc1f%?\\t%l1\";
case LT: return \"c.lt.s\\t%2,%3%#\;%*bc1t%?\\t%l1\";
case LE: return \"c.le.s\\t%2,%3%#\;%*bc1t%?\\t%l1\";
case GT: return \"c.lt.s\\t%3,%2%#\;%*bc1t%?\\t%l1\";
case GE: return \"c.le.s\\t%3,%2%#\;%*bc1t%?\\t%l1\";
}
}
abort_with_insn (insn, \"Bad floating compare/branch\");
return (char *)0;
return (operands[0] != pc_rtx) ? \"%*bc1t%?\\t%0\" : \"%*bc1f%?\\t%1\";
}"
[(set_attr "type" "branch")
(set_attr "mode" "none")
(set_attr "length" "3")])
(set_attr "length" "1")])
(define_insn "branch_fp_false"
(define_insn "branch_fp_ne_rev"
[(set (pc)
(if_then_else (match_operator:CC_FP 0 "fcmp_op" [(cc0) (const_int 0)])
(pc)
(label_ref (match_operand 1 "" ""))))]
(if_then_else (ne:CC_REV_FP (reg:CC_REV_FP 66)
(const_int 0))
(match_operand 0 "pc_or_label_operand" "")
(match_operand 1 "pc_or_label_operand" "")))]
""
"*
{
operands[2] = branch_cmp[0];
operands[3] = branch_cmp[1];
mips_branch_likely = (final_sequence && INSN_ANNULLED_BRANCH_P (insn));
if (branch_type == CMP_DF)
{
switch (GET_CODE (operands[0]))
{
case EQ: return \"c.eq.d\\t%2,%3%#\;%*bc1f%?\\t%l1\";
case NE: return \"c.eq.d\\t%2,%3%#\;%*bc1t%?\\t%l1\";
case LT: return \"c.lt.d\\t%2,%3%#\;%*bc1f%?\\t%l1\";
case LE: return \"c.le.d\\t%2,%3%#\;%*bc1f%?\\t%l1\";
case GT: return \"c.lt.d\\t%3,%2%#\;%*bc1f%?\\t%l1\";
case GE: return \"c.le.d\\t%3,%2%#\;%*bc1f%?\\t%l1\";
}
}
else if (branch_type == CMP_SF)
{
switch (GET_CODE (operands[0]))
{
case EQ: return \"c.eq.s\\t%2,%3%#\;%*bc1f%?\\t%l1\";
case NE: return \"c.eq.s\\t%2,%3%#\;%*bc1t%?\\t%l1\";
case LT: return \"c.lt.s\\t%2,%3%#\;%*bc1f%?\\t%l1\";
case LE: return \"c.le.s\\t%2,%3%#\;%*bc1f%?\\t%l1\";
case GT: return \"c.lt.s\\t%3,%2%#\;%*bc1f%?\\t%l1\";
case GE: return \"c.le.s\\t%3,%2%#\;%*bc1f%?\\t%l1\";
}
}
abort_with_insn (insn, \"Bad floating compare/branch\");
return (char *)0;
return (operands[0] != pc_rtx) ? \"%*bc1f%?\\t%0\" : \"%*bc1t%?\\t%1\";
}"
[(set_attr "type" "branch")
(set_attr "mode" "none")
(set_attr "length" "3")])
(set_attr "length" "1")])
(define_insn "branch_eqne_true"
(define_insn "branch_fp_eq"
[(set (pc)
(if_then_else (match_operator:CC_EQ 0 "equality_op" [(cc0) (const_int 0)])
(label_ref (match_operand 1 "" ""))
(pc)))]
(if_then_else (eq:CC_FP (reg:CC_FP 66)
(const_int 0))
(match_operand 0 "pc_or_label_operand" "")
(match_operand 1 "pc_or_label_operand" "")))]
""
"*
{
mips_branch_likely = (final_sequence && INSN_ANNULLED_BRANCH_P (insn));
operands[2] = branch_cmp[0];
operands[3] = branch_cmp[1];
return \"%*b%C0%?\\t%z2,%z3,%1\";
return (operands[0] != pc_rtx) ? \"%*bc1f%?\\t%0\" : \"%*bc1t%?\\t%1\";
}"
[(set_attr "type" "branch")
(set_attr "mode" "none")
(set_attr "length" "1")])
(define_insn "branch_eqne_false"
(define_insn "branch_fp_eq_rev"
[(set (pc)
(if_then_else (match_operator:CC_EQ 0 "equality_op" [(cc0) (const_int 0)])
(pc)
(label_ref (match_operand 1 "" ""))))]
(if_then_else (eq:CC_REV_FP (reg:CC_REV_FP 66)
(const_int 0))
(match_operand 0 "pc_or_label_operand" "")
(match_operand 1 "pc_or_label_operand" "")))]
""
"*
{
mips_branch_likely = (final_sequence && INSN_ANNULLED_BRANCH_P (insn));
operands[2] = branch_cmp[0];
operands[3] = branch_cmp[1];
return \"%*b%N0%?\\t%z2,%z3,%1\";
return (operands[0] != pc_rtx) ? \"%*bc1t%?\\t%0\" : \"%*bc1f%?\\t%1\";
}"
[(set_attr "type" "branch")
(set_attr "mode" "none")
(set_attr "length" "1")])
(define_insn "branch_zero_true"
(define_insn "branch_zero"
[(set (pc)
(if_then_else (match_operator:CC_0 0 "cmp_op" [(cc0) (const_int 0)])
(label_ref (match_operand 1 "" ""))
(pc)))]
(if_then_else (match_operator:SI 0 "cmp_op"
[(match_operand:SI 1 "arith32_operand" "rn")
(const_int 0)])
(match_operand 2 "pc_or_label_operand" "")
(match_operand 3 "pc_or_label_operand" "")))]
""
"*
{
mips_branch_likely = (final_sequence && INSN_ANNULLED_BRANCH_P (insn));
operands[2] = branch_cmp[0];
/* Handle places where CSE has folded a constant into the register operand. */
if (GET_CODE (operands[1]) == CONST_INT)
{
int value = INTVAL (operands[1]);
int truth = 0;
switch (GET_CODE (operands[0]))
{
case EQ: return \"%*beq%?\\t%z2,%.,%1\";
case NE: return \"%*bne%?\\t%z2,%.,%1\";
case GTU: return \"%*bne%?\\t%z2,%.,%1\";
case LEU: return \"%*beq%?\\t%z2,%.,%1\";
case GEU: return \"%*j\\t%1\";
case LTU: return \"#%*bltuz\\t%z2,%1\";
default: abort ();
case EQ: truth = (value == 0); break;
case NE: truth = (value != 0); break;
case GT: truth = (value > 0); break;
case GE: truth = (value >= 0); break;
case LT: truth = (value < 0); break;
case LE: truth = (value <= 0); break;
case GTU: truth = (((unsigned)value) > 0); break;
case GEU: truth = 1; break;
case LTU: truth = 0; break;
case LEU: truth = (((unsigned)value) <= 0); break;
}
return \"%*b%C0z%?\\t%z2,%1\";
}"
[(set_attr "type" "branch")
(set_attr "mode" "none")
(set_attr "length" "1")])
if (operands[2] != pc_rtx)
return (truth) ? \"%*j\\t%2\" : \"#bne\\t%z1,%.,%2\";
else
return (truth) ? \"#bne\\t%z1,%.,%3\" : \"%*j\\t%3\";
}
(define_insn "branch_zero_false"
[(set (pc)
(if_then_else (match_operator:CC_0 0 "cmp_op" [(cc0) (const_int 0)])
(pc)
(label_ref (match_operand 1 "" ""))))]
""
"*
{
mips_branch_likely = (final_sequence && INSN_ANNULLED_BRANCH_P (insn));
operands[2] = branch_cmp[0];
if (operands[2] != pc_rtx)
{ /* normal jump */
switch (GET_CODE (operands[0]))
{
case EQ: return \"%*bne%?\\t%z2,%.,%1\";
case NE: return \"%*beq%?\\t%z2,%.,%1\";
case GTU: return \"%*beq%?\\t%z2,%.,%1\";
case LEU: return \"%*bne\\t%z2,%.,%1\";
case GEU: return \"#%*bgeuz\\t%z2,%1\";
case LTU: return \"%*j\\t%1\";
case EQ: return \"%*beq%?\\t%z1,%.,%2\";
case NE: return \"%*bne%?\\t%z1,%.,%2\";
case GTU: return \"%*bne%?\\t%z1,%.,%2\";
case LEU: return \"%*beq%?\\t%z1,%.,%2\";
case GEU: return \"%*j\\t%2\";
case LTU: return \"#%*bltuz\\t%z1,%2\";
}
return \"%*b%N0z%?\\t%z2,%1\";
return \"%*b%C0z%?\\t%z1,%2\";
}
else
{ /* inverted jump */
switch (GET_CODE (operands[0]))
{
case EQ: return \"%*bne%?\\t%z1,%.,%3\";
case NE: return \"%*beq%?\\t%z1,%.,%3\";
case GTU: return \"%*beq%?\\t%z1,%.,%3\";
case LEU: return \"%*bne%?\\t%z1,%.,%3\";
case GEU: return \"#%*bgeuz\\t%z1,%3\";
case LTU: return \"%*j\\t%3\";
}
return \"%*b%N0z%?\\t%z1,%3\";
}
}"
[(set_attr "type" "branch")
(set_attr "mode" "none")
(set_attr "length" "1")])
(define_insn "branch_relop_true"
[(set (pc)
(if_then_else (match_operator:CC 0 "cmp2_op" [(cc0) (const_int 0)])
(label_ref (match_operand 1 "" ""))
(pc)))]
""
"*
{
mips_branch_likely = (final_sequence && INSN_ANNULLED_BRANCH_P (insn));
operands[2] = branch_cmp[0];
operands[3] = branch_cmp[1];
return \"%&b%C0%?\\t%z2,%z3,%1%!\";
}"
[(set_attr "type" "branch")
(set_attr "mode" "none")
(set_attr "length" "2")])
(define_insn "branch_relop_false"
(define_insn "branch_equality"
[(set (pc)
(if_then_else (match_operator:CC 0 "cmp2_op" [(cc0) (const_int 0)])
(pc)
(label_ref (match_operand 1 "" ""))))]
(if_then_else (match_operator:SI 0 "equality_op"
[(match_operand:SI 1 "register_operand" "d")
(match_operand:SI 2 "register_operand" "d")])
(match_operand 3 "pc_or_label_operand" "")
(match_operand 4 "pc_or_label_operand" "")))]
""
"*
{
mips_branch_likely = (final_sequence && INSN_ANNULLED_BRANCH_P (insn));
operands[2] = branch_cmp[0];
operands[3] = branch_cmp[1];
return \"%&b%N0%?\\t%z2,%z3,%1%!\";
return (operands[3] != pc_rtx)
? \"%*b%C0%?\\t%z1,%z2,%3\"
: \"%*b%N0%?\\t%z1,%z2,%4\";
}"
[(set_attr "type" "branch")
(set_attr "mode" "none")
(set_attr "length" "2")])
(set_attr "length" "1")])
(define_expand "beq"
[(set (pc)
......@@ -3179,7 +3035,7 @@ move\\t%0,%z4\\n\\
(define_expand "seq"
[(set (match_operand:SI 0 "register_operand" "=d")
(eq:CC_EQ (match_dup 1)
(eq:SI (match_dup 1)
(match_dup 2)))]
""
"
......@@ -3193,42 +3049,58 @@ move\\t%0,%z4\\n\\
operands[1] = branch_cmp[0];
operands[2] = branch_cmp[1];
if (TARGET_DEBUG_C_MODE)
{
gen_int_relational (EQ, operands[0], operands[1], operands[2], (int *)0);
DONE;
}
if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0)
operands[2] = force_reg (SImode, operands[2]);
/* fall through and generate default code */
}")
(define_insn "seq_si"
[(set (match_operand:SI 0 "register_operand" "=d,d,d")
(eq:CC_EQ (match_operand:SI 1 "register_operand" "%d,d,d")
(match_operand:SI 2 "uns_arith_operand" "J,d,K")))]
(define_insn "seq_si_zero"
[(set (match_operand:SI 0 "register_operand" "=d")
(eq:SI (match_operand:SI 1 "register_operand" "d")
(const_int 0)))]
""
"sltu\\t%0,%1,1"
[(set_attr "type" "arith")
(set_attr "mode" "SI")
(set_attr "length" "1")])
(define_insn "seq_si"
[(set (match_operand:SI 0 "register_operand" "=d,d")
(eq:SI (match_operand:SI 1 "register_operand" "%d,d")
(match_operand:SI 2 "uns_arith_operand" "d,K")))]
"!TARGET_DEBUG_C_MODE"
"@
sltu\\t%0,%1,1
xor\\t%0,%1,%2\;sltu\\t%0,%0,1
xori\\t%0,%1,%x2\;sltu\\t%0,%0,1"
[(set_attr "type" "arith,arith,arith")
(set_attr "mode" "SI,SI,SI")
(set_attr "length" "1,2,2")])
xori\\t%0,%1,%2\;sltu\\t%0,%0,1"
[(set_attr "type" "arith,arith")
(set_attr "mode" "SI,SI")
(set_attr "length" "2,2")])
(define_split
[(set (match_operand:SI 0 "register_operand" "")
(eq:CC_EQ (match_operand:SI 1 "register_operand" "")
(eq:SI (match_operand:SI 1 "register_operand" "")
(match_operand:SI 2 "uns_arith_operand" "")))]
"!TARGET_DEBUG_D_MODE
"!TARGET_DEBUG_C_MODE && !TARGET_DEBUG_D_MODE
&& (GET_CODE (operands[2]) != CONST_INT || INTVAL (operands[2]) != 0)"
[(set (match_dup 0)
(xor:SI (match_dup 1)
(match_dup 2)))
(set (match_dup 0)
(ltu:CC (match_dup 0)
(ltu:SI (match_dup 0)
(const_int 1)))]
"")
(define_expand "sne"
[(set (match_operand:SI 0 "register_operand" "=d")
(ne:CC_EQ (match_dup 1)
(ne:SI (match_dup 1)
(match_dup 2)))]
""
"
......@@ -3242,48 +3114,57 @@ move\\t%0,%z4\\n\\
operands[1] = branch_cmp[0];
operands[2] = branch_cmp[1];
if (TARGET_DEBUG_C_MODE)
{
gen_int_relational (NE, operands[0], operands[1], operands[2], (int *)0);
DONE;
}
if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0)
operands[2] = force_reg (SImode, operands[2]);
/* fall through and generate default code */
}")
(define_insn "sne_si"
[(set (match_operand:SI 0 "register_operand" "=d,d,d")
(ne:CC_EQ (match_operand:SI 1 "register_operand" "%d,d,d")
(match_operand:SI 2 "uns_arith_operand" "J,d,K")))]
(define_insn "sne_si_zero"
[(set (match_operand:SI 0 "register_operand" "=d")
(ne:SI (match_operand:SI 1 "register_operand" "d")
(const_int 0)))]
""
"*
{
if (GET_CODE (operands[2]) != CONST_INT)
return \"xor\\t%0,%1,%2\;sltu\\t%0,%.,%0\";
if (INTVAL (operands[2]) == 0)
return \"sltu\\t%0,%.,%1\";
"sltu\\t%0,%.,%1"
[(set_attr "type" "arith")
(set_attr "mode" "SI")
(set_attr "length" "1")])
return \"xori\\t%0,%1,%x2\;sltu\\t%0,%.,%0\";
}"
[(set_attr "type" "arith,arith,arith")
(set_attr "mode" "SI,SI,SI")
(set_attr "length" "1,2,2")])
(define_insn "sne_si"
[(set (match_operand:SI 0 "register_operand" "=d,d")
(ne:SI (match_operand:SI 1 "register_operand" "%d,d")
(match_operand:SI 2 "uns_arith_operand" "d,K")))]
"!TARGET_DEBUG_C_MODE"
"@
xor\\t%0,%1,%2\;sltu\\t%0,%.,%0
xori\\t%0,%1,%x2\;sltu\\t%0,%.,%0"
[(set_attr "type" "arith,arith")
(set_attr "mode" "SI,SI")
(set_attr "length" "2,2")])
(define_split
[(set (match_operand:SI 0 "register_operand" "")
(ne:CC_EQ (match_operand:SI 1 "register_operand" "")
(ne:SI (match_operand:SI 1 "register_operand" "")
(match_operand:SI 2 "uns_arith_operand" "")))]
"!TARGET_DEBUG_D_MODE
"!TARGET_DEBUG_C_MODE && !TARGET_DEBUG_D_MODE
&& (GET_CODE (operands[2]) != CONST_INT || INTVAL (operands[2]) != 0)"
[(set (match_dup 0)
(xor:SI (match_dup 1)
(match_dup 2)))
(set (match_dup 0)
(gtu:CC (match_dup 0)
(gtu:SI (match_dup 0)
(const_int 0)))]
"")
(define_expand "sgt"
[(set (match_operand:SI 0 "register_operand" "=d")
(gt:CC (match_dup 1)
(gt:SI (match_dup 1)
(match_dup 2)))]
""
"
......@@ -3297,6 +3178,12 @@ move\\t%0,%z4\\n\\
operands[1] = branch_cmp[0];
operands[2] = branch_cmp[1];
if (TARGET_DEBUG_C_MODE)
{
gen_int_relational (GT, operands[0], operands[1], operands[2], (int *)0);
DONE;
}
if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) != 0)
operands[2] = force_reg (SImode, operands[2]);
......@@ -3305,7 +3192,7 @@ move\\t%0,%z4\\n\\
(define_insn "sgt_si"
[(set (match_operand:SI 0 "register_operand" "=d")
(gt:CC (match_operand:SI 1 "register_operand" "d")
(gt:SI (match_operand:SI 1 "register_operand" "d")
(match_operand:SI 2 "reg_or_0_operand" "dJ")))]
""
"slt\\t%0,%z2,%1"
......@@ -3315,7 +3202,7 @@ move\\t%0,%z4\\n\\
(define_expand "sge"
[(set (match_operand:SI 0 "register_operand" "=d")
(ge:CC (match_dup 1)
(ge:SI (match_dup 1)
(match_dup 2)))]
""
"
......@@ -3327,14 +3214,20 @@ move\\t%0,%z4\\n\\
operands[1] = branch_cmp[0];
operands[2] = branch_cmp[1];
if (TARGET_DEBUG_C_MODE)
{
gen_int_relational (GE, operands[0], operands[1], operands[2], (int *)0);
DONE;
}
/* fall through and generate default code */
}")
(define_insn "sge_si"
[(set (match_operand:SI 0 "register_operand" "=d")
(ge:CC (match_operand:SI 1 "register_operand" "d")
(ge:SI (match_operand:SI 1 "register_operand" "d")
(match_operand:SI 2 "arith_operand" "dI")))]
""
"!TARGET_DEBUG_C_MODE"
"slt\\t%0,%1,%2\;xori\\t%0,%0,0x0001"
[(set_attr "type" "arith")
(set_attr "mode" "SI")
......@@ -3342,11 +3235,11 @@ move\\t%0,%z4\\n\\
(define_split
[(set (match_operand:SI 0 "register_operand" "")
(ge:CC (match_operand:SI 1 "register_operand" "")
(ge:SI (match_operand:SI 1 "register_operand" "")
(match_operand:SI 2 "arith_operand" "")))]
"!TARGET_DEBUG_D_MODE"
"!TARGET_DEBUG_C_MODE && !TARGET_DEBUG_D_MODE"
[(set (match_dup 0)
(lt:CC (match_dup 1)
(lt:SI (match_dup 1)
(match_dup 2)))
(set (match_dup 0)
(xor:SI (match_dup 0)
......@@ -3355,7 +3248,7 @@ move\\t%0,%z4\\n\\
(define_expand "slt"
[(set (match_operand:SI 0 "register_operand" "=d")
(lt:CC (match_dup 1)
(lt:SI (match_dup 1)
(match_dup 2)))]
""
"
......@@ -3367,12 +3260,18 @@ move\\t%0,%z4\\n\\
operands[1] = branch_cmp[0];
operands[2] = branch_cmp[1];
if (TARGET_DEBUG_C_MODE)
{
gen_int_relational (LT, operands[0], operands[1], operands[2], (int *)0);
DONE;
}
/* fall through and generate default code */
}")
(define_insn "slt_si"
[(set (match_operand:SI 0 "register_operand" "=d")
(lt:CC (match_operand:SI 1 "register_operand" "d")
(lt:SI (match_operand:SI 1 "register_operand" "d")
(match_operand:SI 2 "arith_operand" "dI")))]
""
"slt\\t%0,%1,%2"
......@@ -3382,7 +3281,7 @@ move\\t%0,%z4\\n\\
(define_expand "sle"
[(set (match_operand:SI 0 "register_operand" "=d")
(le:CC (match_dup 1)
(le:SI (match_dup 1)
(match_dup 2)))]
""
"
......@@ -3396,31 +3295,49 @@ move\\t%0,%z4\\n\\
operands[1] = branch_cmp[0];
operands[2] = branch_cmp[1];
if (TARGET_DEBUG_C_MODE)
{
gen_int_relational (LE, operands[0], operands[1], operands[2], (int *)0);
DONE;
}
if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) >= 32767)
operands[2] = force_reg (SImode, operands[2]);
/* fall through and generate default code */
}")
(define_insn "sle_si"
[(set (match_operand:SI 0 "register_operand" "=d,d")
(le:CC (match_operand:SI 1 "register_operand" "d,d")
(match_operand:SI 2 "arith_operand" "d,I")))]
"GET_CODE (operands[2]) != CONST_INT || INTVAL (operands[2]) < 32767"
"@
slt\\t%0,%z2,%1\;xori\\t%0,%0,0x0001
slt\\t%0,%1,(%2+1)"
[(set_attr "type" "arith,arith")
(set_attr "mode" "SI,SI")
(set_attr "length" "2,1")])
(define_insn "sle_si_const"
[(set (match_operand:SI 0 "register_operand" "=d")
(le:SI (match_operand:SI 1 "register_operand" "d")
(match_operand:SI 2 "small_int" "I")))]
"INTVAL (operands[2]) < 32767"
"*
{
operands[2] = gen_rtx (CONST_INT, VOIDmode, INTVAL (operands[2])+1);
return \"slt\\t%0,%1,%2\";
}"
[(set_attr "type" "arith")
(set_attr "mode" "SI")
(set_attr "length" "1")])
(define_insn "sle_si_reg"
[(set (match_operand:SI 0 "register_operand" "=d")
(le:SI (match_operand:SI 1 "register_operand" "d")
(match_operand:SI 2 "register_operand" "d")))]
"!TARGET_DEBUG_C_MODE"
"slt\\t%0,%z2,%1\;xori\\t%0,%0,0x0001"
[(set_attr "type" "arith")
(set_attr "mode" "SI")
(set_attr "length" "2")])
(define_split
[(set (match_operand:SI 0 "register_operand" "")
(le:CC (match_operand:SI 1 "register_operand" "")
(le:SI (match_operand:SI 1 "register_operand" "")
(match_operand:SI 2 "register_operand" "")))]
"!TARGET_DEBUG_D_MODE"
"!TARGET_DEBUG_C_MODE && !TARGET_DEBUG_D_MODE"
[(set (match_dup 0)
(lt:CC (match_dup 2)
(lt:SI (match_dup 2)
(match_dup 1)))
(set (match_dup 0)
(xor:SI (match_dup 0)
......@@ -3429,7 +3346,7 @@ move\\t%0,%z4\\n\\
(define_expand "sgtu"
[(set (match_operand:SI 0 "register_operand" "=d")
(gtu:CC (match_dup 1)
(gtu:SI (match_dup 1)
(match_dup 2)))]
""
"
......@@ -3443,6 +3360,12 @@ move\\t%0,%z4\\n\\
operands[1] = branch_cmp[0];
operands[2] = branch_cmp[1];
if (TARGET_DEBUG_C_MODE)
{
gen_int_relational (GTU, operands[0], operands[1], operands[2], (int *)0);
DONE;
}
if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) != 0)
operands[2] = force_reg (SImode, operands[2]);
......@@ -3451,7 +3374,7 @@ move\\t%0,%z4\\n\\
(define_insn "sgtu_si"
[(set (match_operand:SI 0 "register_operand" "=d")
(gtu:CC (match_operand:SI 1 "register_operand" "d")
(gtu:SI (match_operand:SI 1 "register_operand" "d")
(match_operand:SI 2 "reg_or_0_operand" "dJ")))]
""
"sltu\\t%0,%z2,%1"
......@@ -3461,7 +3384,7 @@ move\\t%0,%z4\\n\\
(define_expand "sgeu"
[(set (match_operand:SI 0 "register_operand" "=d")
(geu:CC (match_dup 1)
(geu:SI (match_dup 1)
(match_dup 2)))]
""
"
......@@ -3473,14 +3396,20 @@ move\\t%0,%z4\\n\\
operands[1] = branch_cmp[0];
operands[2] = branch_cmp[1];
if (TARGET_DEBUG_C_MODE)
{
gen_int_relational (GEU, operands[0], operands[1], operands[2], (int *)0);
DONE;
}
/* fall through and generate default code */
}")
(define_insn "sgeu_si"
[(set (match_operand:SI 0 "register_operand" "=d")
(geu:CC (match_operand:SI 1 "register_operand" "d")
(geu:SI (match_operand:SI 1 "register_operand" "d")
(match_operand:SI 2 "arith_operand" "dI")))]
""
"!TARGET_DEBUG_C_MODE"
"sltu\\t%0,%1,%2\;xori\\t%0,%0,0x0001"
[(set_attr "type" "arith")
(set_attr "mode" "SI")
......@@ -3488,11 +3417,11 @@ move\\t%0,%z4\\n\\
(define_split
[(set (match_operand:SI 0 "register_operand" "")
(geu:CC (match_operand:SI 1 "register_operand" "")
(geu:SI (match_operand:SI 1 "register_operand" "")
(match_operand:SI 2 "arith_operand" "")))]
"!TARGET_DEBUG_D_MODE"
"!TARGET_DEBUG_C_MODE && !TARGET_DEBUG_D_MODE"
[(set (match_dup 0)
(ltu:CC (match_dup 1)
(ltu:SI (match_dup 1)
(match_dup 2)))
(set (match_dup 0)
(xor:SI (match_dup 0)
......@@ -3501,7 +3430,7 @@ move\\t%0,%z4\\n\\
(define_expand "sltu"
[(set (match_operand:SI 0 "register_operand" "=d")
(ltu:CC (match_dup 1)
(ltu:SI (match_dup 1)
(match_dup 2)))]
""
"
......@@ -3513,12 +3442,18 @@ move\\t%0,%z4\\n\\
operands[1] = branch_cmp[0];
operands[2] = branch_cmp[1];
if (TARGET_DEBUG_C_MODE)
{
gen_int_relational (LTU, operands[0], operands[1], operands[2], (int *)0);
DONE;
}
/* fall through and generate default code */
}")
(define_insn "sltu_si"
[(set (match_operand:SI 0 "register_operand" "=d")
(ltu:CC (match_operand:SI 1 "register_operand" "d")
(ltu:SI (match_operand:SI 1 "register_operand" "d")
(match_operand:SI 2 "arith_operand" "dI")))]
""
"sltu\\t%0,%1,%2"
......@@ -3528,7 +3463,7 @@ move\\t%0,%z4\\n\\
(define_expand "sleu"
[(set (match_operand:SI 0 "register_operand" "=d")
(leu:CC (match_dup 1)
(leu:SI (match_dup 1)
(match_dup 2)))]
""
"
......@@ -3542,31 +3477,49 @@ move\\t%0,%z4\\n\\
operands[1] = branch_cmp[0];
operands[2] = branch_cmp[1];
if (TARGET_DEBUG_C_MODE)
{
gen_int_relational (LEU, operands[0], operands[1], operands[2], (int *)0);
DONE;
}
if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) >= 32767)
operands[2] = force_reg (SImode, operands[2]);
/* fall through and generate default code */
}")
(define_insn "sleu_si"
[(set (match_operand:SI 0 "register_operand" "=d,d")
(leu:CC (match_operand:SI 1 "register_operand" "d,d")
(match_operand:SI 2 "arith_operand" "d,I")))]
"GET_CODE (operands[2]) != CONST_INT || INTVAL (operands[2]) < 32767"
"@
sltu\\t%0,%z2,%1\;xori\\t%0,%0,0x0001
sltu\\t%0,%1,(%2+1)"
[(set_attr "type" "arith,arith")
(set_attr "mode" "SI,SI")
(set_attr "length" "2,1")])
(define_insn "sleu_si_const"
[(set (match_operand:SI 0 "register_operand" "=d")
(leu:SI (match_operand:SI 1 "register_operand" "d")
(match_operand:SI 2 "small_int" "I")))]
"INTVAL (operands[2]) < 32767"
"*
{
operands[2] = gen_rtx (CONST_INT, VOIDmode, INTVAL (operands[2])+1);
return \"sltu\\t%0,%1,%2\";
}"
[(set_attr "type" "arith")
(set_attr "mode" "SI")
(set_attr "length" "1")])
(define_insn "sleu_si_reg"
[(set (match_operand:SI 0 "register_operand" "=d")
(leu:SI (match_operand:SI 1 "register_operand" "d")
(match_operand:SI 2 "register_operand" "d")))]
"!TARGET_DEBUG_C_MODE"
"sltu\\t%0,%z2,%1\;xori\\t%0,%0,0x0001"
[(set_attr "type" "arith")
(set_attr "mode" "SI")
(set_attr "length" "2")])
(define_split
[(set (match_operand:SI 0 "register_operand" "")
(leu:CC (match_operand:SI 1 "register_operand" "")
(leu:SI (match_operand:SI 1 "register_operand" "")
(match_operand:SI 2 "register_operand" "")))]
"!TARGET_DEBUG_D_MODE"
"!TARGET_DEBUG_C_MODE && !TARGET_DEBUG_D_MODE"
[(set (match_dup 0)
(ltu:CC (match_dup 2)
(ltu:SI (match_dup 2)
(match_dup 1)))
(set (match_dup 0)
(xor:SI (match_dup 0)
......@@ -3577,6 +3530,230 @@ move\\t%0,%z4\\n\\
;;
;; ....................
;;
;; FLOATING POINT COMPARISONS
;;
;; ....................
(define_insn "seq_df"
[(set (reg:CC_FP 66)
(eq:CC_FP (match_operand:DF 0 "register_operand" "f")
(match_operand:DF 1 "register_operand" "f")))]
""
"*
{
rtx xoperands[10];
xoperands[0] = gen_rtx (REG, CC_FPmode, FPSW_REGNUM);
xoperands[1] = operands[0];
xoperands[2] = operands[1];
return mips_fill_delay_slot (\"c.eq.d\\t%0,%1\", DELAY_FCMP, xoperands, insn);
}"
[(set_attr "type" "fcmp")
(set_attr "mode" "FPSW")
(set_attr "length" "1")])
(define_insn "sne_df"
[(set (reg:CC_REV_FP 66)
(ne:CC_REV_FP (match_operand:DF 0 "register_operand" "f")
(match_operand:DF 1 "register_operand" "f")))]
""
"*
{
rtx xoperands[10];
xoperands[0] = gen_rtx (REG, CC_FPmode, FPSW_REGNUM);
xoperands[1] = operands[0];
xoperands[2] = operands[1];
return mips_fill_delay_slot (\"c.eq.d\\t%0,%1\", DELAY_FCMP, xoperands, insn);
}"
[(set_attr "type" "fcmp")
(set_attr "mode" "FPSW")
(set_attr "length" "1")])
(define_insn "slt_df"
[(set (reg:CC_FP 66)
(lt:CC_FP (match_operand:DF 0 "register_operand" "f")
(match_operand:DF 1 "register_operand" "f")))]
""
"*
{
rtx xoperands[10];
xoperands[0] = gen_rtx (REG, CC_FPmode, FPSW_REGNUM);
xoperands[1] = operands[0];
xoperands[2] = operands[1];
return mips_fill_delay_slot (\"c.lt.d\\t%0,%1\", DELAY_FCMP, xoperands, insn);
}"
[(set_attr "type" "fcmp")
(set_attr "mode" "FPSW")
(set_attr "length" "1")])
(define_insn "sle_df"
[(set (reg:CC_FP 66)
(le:CC_FP (match_operand:DF 0 "register_operand" "f")
(match_operand:DF 1 "register_operand" "f")))]
""
"*
{
rtx xoperands[10];
xoperands[0] = gen_rtx (REG, CC_FPmode, FPSW_REGNUM);
xoperands[1] = operands[0];
xoperands[2] = operands[1];
return mips_fill_delay_slot (\"c.le.d\\t%0,%1\", DELAY_FCMP, xoperands, insn);
}"
[(set_attr "type" "fcmp")
(set_attr "mode" "FPSW")
(set_attr "length" "1")])
(define_insn "sgt_df"
[(set (reg:CC_FP 66)
(gt:CC_FP (match_operand:DF 0 "register_operand" "f")
(match_operand:DF 1 "register_operand" "f")))]
""
"*
{
rtx xoperands[10];
xoperands[0] = gen_rtx (REG, CC_FPmode, FPSW_REGNUM);
xoperands[1] = operands[0];
xoperands[2] = operands[1];
return mips_fill_delay_slot (\"c.lt.d\\t%1,%0\", DELAY_FCMP, xoperands, insn);
}"
[(set_attr "type" "fcmp")
(set_attr "mode" "FPSW")
(set_attr "length" "1")])
(define_insn "sge_df"
[(set (reg:CC_FP 66)
(ge:CC_FP (match_operand:DF 0 "register_operand" "f")
(match_operand:DF 1 "register_operand" "f")))]
""
"*
{
rtx xoperands[10];
xoperands[0] = gen_rtx (REG, CC_FPmode, FPSW_REGNUM);
xoperands[1] = operands[0];
xoperands[2] = operands[1];
return mips_fill_delay_slot (\"c.le.d\\t%1,%0\", DELAY_FCMP, xoperands, insn);
}"
[(set_attr "type" "fcmp")
(set_attr "mode" "FPSW")
(set_attr "length" "1")])
(define_insn "seq_sf"
[(set (reg:CC_FP 66)
(eq:CC_FP (match_operand:SF 0 "register_operand" "f")
(match_operand:SF 1 "register_operand" "f")))]
""
"*
{
rtx xoperands[10];
xoperands[0] = gen_rtx (REG, CC_FPmode, FPSW_REGNUM);
xoperands[1] = operands[0];
xoperands[2] = operands[1];
return mips_fill_delay_slot (\"c.eq.s\\t%0,%1\", DELAY_FCMP, xoperands, insn);
}"
[(set_attr "type" "fcmp")
(set_attr "mode" "FPSW")
(set_attr "length" "1")])
(define_insn "sne_sf"
[(set (reg:CC_REV_FP 66)
(ne:CC_REV_FP (match_operand:SF 0 "register_operand" "f")
(match_operand:SF 1 "register_operand" "f")))]
""
"*
{
rtx xoperands[10];
xoperands[0] = gen_rtx (REG, CC_FPmode, FPSW_REGNUM);
xoperands[1] = operands[0];
xoperands[2] = operands[1];
return mips_fill_delay_slot (\"c.eq.s\\t%0,%1\", DELAY_FCMP, xoperands, insn);
}"
[(set_attr "type" "fcmp")
(set_attr "mode" "FPSW")
(set_attr "length" "1")])
(define_insn "slt_sf"
[(set (reg:CC_FP 66)
(lt:CC_FP (match_operand:SF 0 "register_operand" "f")
(match_operand:SF 1 "register_operand" "f")))]
""
"*
{
rtx xoperands[10];
xoperands[0] = gen_rtx (REG, CC_FPmode, FPSW_REGNUM);
xoperands[1] = operands[0];
xoperands[2] = operands[1];
return mips_fill_delay_slot (\"c.lt.s\\t%0,%1\", DELAY_FCMP, xoperands, insn);
}"
[(set_attr "type" "fcmp")
(set_attr "mode" "FPSW")
(set_attr "length" "1")])
(define_insn "sle_sf"
[(set (reg:CC_FP 66)
(le:CC_FP (match_operand:SF 0 "register_operand" "f")
(match_operand:SF 1 "register_operand" "f")))]
""
"*
{
rtx xoperands[10];
xoperands[0] = gen_rtx (REG, CC_FPmode, FPSW_REGNUM);
xoperands[1] = operands[0];
xoperands[2] = operands[1];
return mips_fill_delay_slot (\"c.le.s\\t%0,%1\", DELAY_FCMP, xoperands, insn);
}"
[(set_attr "type" "fcmp")
(set_attr "mode" "FPSW")
(set_attr "length" "1")])
(define_insn "sgt_sf"
[(set (reg:CC_FP 66)
(gt:CC_FP (match_operand:SF 0 "register_operand" "f")
(match_operand:SF 1 "register_operand" "f")))]
""
"*
{
rtx xoperands[10];
xoperands[0] = gen_rtx (REG, CC_FPmode, FPSW_REGNUM);
xoperands[1] = operands[0];
xoperands[2] = operands[1];
return mips_fill_delay_slot (\"c.lt.s\\t%1,%0\", DELAY_FCMP, xoperands, insn);
}"
[(set_attr "type" "fcmp")
(set_attr "mode" "FPSW")
(set_attr "length" "1")])
(define_insn "sge_sf"
[(set (reg:CC_FP 66)
(ge:CC_FP (match_operand:SF 0 "register_operand" "f")
(match_operand:SF 1 "register_operand" "f")))]
""
"*
{
rtx xoperands[10];
xoperands[0] = gen_rtx (REG, CC_FPmode, FPSW_REGNUM);
xoperands[1] = operands[0];
xoperands[2] = operands[1];
return mips_fill_delay_slot (\"c.le.s\\t%1,%0\", DELAY_FCMP, xoperands, insn);
}"
[(set_attr "type" "fcmp")
(set_attr "mode" "FPSW")
(set_attr "length" "1")])
;;
;; ....................
;;
;; UNCONDITIONAL BRANCHES
;;
;; ....................
......
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