Commit 225b8835 by Ian Lance Taylor

Add support for mult instruction in 64 bit mode

From-SVN: r9234
parent b6da8566
......@@ -246,7 +246,7 @@ char mips_reg_names[][8] =
"$f8", "$f9", "$f10", "$f11", "$f12", "$f13", "$f14", "$f15",
"$f16", "$f17", "$f18", "$f19", "$f20", "$f21", "$f22", "$f23",
"$f24", "$f25", "$f26", "$f27", "$f28", "$f29", "$f30", "$f31",
"hi", "lo", "$fcr31"
"hi", "lo", "accum","$fcr31"
};
/* Mips software names for the registers, used to overwrite the
......@@ -262,7 +262,7 @@ char mips_sw_reg_names[][8] =
"$f8", "$f9", "$f10", "$f11", "$f12", "$f13", "$f14", "$f15",
"$f16", "$f17", "$f18", "$f19", "$f20", "$f21", "$f22", "$f23",
"$f24", "$f25", "$f26", "$f27", "$f28", "$f29", "$f30", "$f31",
"hi", "lo", "$fcr31"
"hi", "lo", "accum","$fcr31"
};
/* Map hard register number to register class */
......@@ -284,7 +284,7 @@ enum reg_class mips_regno_to_class[] =
FP_REGS, FP_REGS, FP_REGS, FP_REGS,
FP_REGS, FP_REGS, FP_REGS, FP_REGS,
FP_REGS, FP_REGS, FP_REGS, FP_REGS,
HI_REG, LO_REG, ST_REGS
HI_REG, LO_REG, HILO_REG, ST_REGS
};
/* Map register constraint character to register class. */
......@@ -927,7 +927,10 @@ mips_move_1word (operands, insn, unsignedp)
else if (MD_REG_P (regno1))
{
delay = DELAY_HILO;
if (regno1 != HILO_REGNUM)
ret = "mf%1\t%0";
else
ret = "mflo\t%0";
}
else
......@@ -958,6 +961,7 @@ mips_move_1word (operands, insn, unsignedp)
if (GP_REG_P (regno1))
{
delay = DELAY_HILO;
if (regno0 != HILO_REGNUM)
ret = "mt%0\t%1";
}
}
......@@ -1040,6 +1044,12 @@ mips_move_1word (operands, insn, unsignedp)
delay = DELAY_LOAD;
ret = "mtc1\t%z1,%0";
}
else if (MD_REG_P (regno0))
{
delay = DELAY_HILO;
ret = "mt%0\t%.";
}
}
else if (GP_REG_P (regno0))
......@@ -1301,7 +1311,12 @@ mips_move_2words (operands, insn)
{
delay = DELAY_HILO;
if (TARGET_64BIT)
{
if (regno0 != HILO_REGNUM)
ret = "mt%0\t%1";
else if (regno1 == 0)
ret = "mtlo\t%.\n\tmthi\t%.";
}
else
ret = "mthi\t%M1\n\tmtlo\t%L1";
}
......@@ -1310,7 +1325,10 @@ mips_move_2words (operands, insn)
{
delay = DELAY_HILO;
if (TARGET_64BIT)
{
if (regno1 != HILO_REGNUM)
ret = "mf%1\t%0";
}
else
ret = "mfhi\t%M0\n\tmflo\t%L0";
}
......@@ -1398,6 +1416,14 @@ mips_move_2words (operands, insn)
? "li.d\t%0,%1"
: "mtc1\t%.,%0\n\tmtc1\t%.,%D0");
}
else if (MD_REG_P (regno0))
{
delay = DELAY_HILO;
if (regno0 != HILO_REGNUM)
ret = "mt%0\t%.\n";
else
ret = "mtlo\t%.\n\tmthi\t%.";
}
}
else if (code1 == CONST_INT && GET_MODE (op0) == DImode && GP_REG_P (regno0))
......@@ -3352,7 +3378,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['a'] = HILO_REG;
mips_char_to_class['x'] = MD_REGS;
mips_char_to_class['b'] = ALL_REGS;
mips_char_to_class['y'] = GR_REGS;
mips_char_to_class['z'] = ST_REGS;
......@@ -5533,24 +5561,58 @@ mips_function_value (valtype, func)
}
#endif
/* Moving the HI or LO register somewhere requires a general register. */
/* This function returns the register class required for a secondary
register when copying between one of the registers in CLASS, and X,
using MODE. If IN_P is nonzero, the copy is going from X to the
register, otherwise the register is the source. A return value of
NO_REGS means that no secondary register is required. */
enum reg_class
mips_secondary_reload_class (class, mode, x)
mips_secondary_reload_class (class, mode, x, in_p)
enum reg_class class;
enum machine_mode mode;
rtx x;
int in_p;
{
if (class != HI_REG && class != LO_REG && class != MD_REGS)
return NO_REGS;
int regno = -1;
if (GET_CODE (x) == REG || GET_CODE (x) == SUBREG)
{
int regno = true_regnum (x);
regno = true_regnum (x);
if (regno >= GP_REG_FIRST && regno <= GP_REG_LAST)
/* We always require a general register when copying anything to
HILO_REGNUM, except when copying an SImode value from HILO_REGNUM
to a general register, or when copying from register 0. */
if (class == HILO_REG && regno != GP_REG_FIRST + 0)
{
if (! in_p
&& GP_REG_P (regno)
&& GET_MODE_SIZE (mode) <= GET_MODE_SIZE (SImode))
return NO_REGS;
return GR_REGS;
}
if (regno == HILO_REGNUM)
{
if (in_p
&& class == GR_REGS
&& GET_MODE_SIZE (mode) <= GET_MODE_SIZE (SImode))
return NO_REGS;
return GR_REGS;
}
/* Copying from HI or LO to anywhere other than a general register
requires a general register. */
if (class == HI_REG || class == LO_REG || class == MD_REGS)
{
if (GP_REG_P (regno))
return NO_REGS;
return GR_REGS;
}
if (MD_REG_P (regno))
{
if (class == GR_REGS)
return NO_REGS;
return GR_REGS;
}
return NO_REGS;
}
......@@ -1138,10 +1138,13 @@ do { \
All registers that the compiler knows about must be given numbers,
even those that are not normally considered general registers.
On the Mips, we have 32 integer registers, 32 floating point registers
and the special registers hi, lo, and fp status. */
On the Mips, we have 32 integer registers, 32 floating point
registers and the special registers hi, lo, hilo, and fp status.
The hilo register is only used in 64 bit mode. It represents a 64
bit value stored as two 32 bit values in the hi and lo registers;
this is the result of the mult instruction. */
#define FIRST_PSEUDO_REGISTER 67
#define FIRST_PSEUDO_REGISTER 68
/* 1 for registers that have pervasive standard uses
and are not available for the register allocator.
......@@ -1154,7 +1157,7 @@ do { \
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 1, \
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
0, 0, 1 \
0, 0, 0, 1 \
}
......@@ -1171,7 +1174,7 @@ do { \
0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 1, \
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, \
1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
1, 1, 1 \
1, 1, 1, 1 \
}
......@@ -1190,16 +1193,17 @@ do { \
#define FP_DBX_FIRST ((write_symbols == DBX_DEBUG) ? 38 : 32)
#define MD_REG_FIRST 64
#define MD_REG_LAST 65
#define MD_REG_LAST 66
#define MD_REG_NUM (MD_REG_LAST - MD_REG_FIRST + 1)
#define ST_REG_FIRST 66
#define ST_REG_LAST 66
#define ST_REG_FIRST 67
#define ST_REG_LAST 67
#define ST_REG_NUM (ST_REG_LAST - ST_REG_FIRST + 1)
#define AT_REGNUM (GP_REG_FIRST + 1)
#define HI_REGNUM (MD_REG_FIRST + 0)
#define LO_REGNUM (MD_REG_FIRST + 1)
#define HILO_REGNUM (MD_REG_FIRST + 2)
#define FPSW_REGNUM ST_REG_FIRST
#define GP_REG_P(REGNO) ((unsigned) ((REGNO) - GP_REG_FIRST) < GP_REG_NUM)
......@@ -1342,6 +1346,7 @@ enum reg_class
FP_REGS, /* floating point registers */
HI_REG, /* hi register */
LO_REG, /* lo register */
HILO_REG, /* hilo register pair for 64 bit mode mult */
MD_REGS, /* multiply/divide registers (hi/lo) */
ST_REGS, /* status registers (fp status) */
ALL_REGS, /* all registers */
......@@ -1363,6 +1368,7 @@ enum reg_class
"FP_REGS", \
"HI_REG", \
"LO_REG", \
"HILO_REG", \
"MD_REGS", \
"ST_REGS", \
"ALL_REGS" \
......@@ -1386,9 +1392,10 @@ enum reg_class
{ 0x00000000, 0xffffffff, 0x00000000 }, /* floating registers*/ \
{ 0x00000000, 0x00000000, 0x00000001 }, /* hi register */ \
{ 0x00000000, 0x00000000, 0x00000002 }, /* lo register */ \
{ 0x00000000, 0x00000000, 0x00000004 }, /* hilo register */ \
{ 0x00000000, 0x00000000, 0x00000003 }, /* mul/div registers */ \
{ 0x00000000, 0x00000000, 0x00000004 }, /* status registers */ \
{ 0xffffffff, 0xffffffff, 0x00000007 } /* all registers */ \
{ 0x00000000, 0x00000000, 0x00000008 }, /* status registers */ \
{ 0xffffffff, 0xffffffff, 0x0000000f } /* all registers */ \
}
......@@ -1428,7 +1435,9 @@ extern enum reg_class mips_regno_to_class[];
'h' Hi register
'l' Lo register
'x' Multiply/divide registers
'z' FP Status register */
'a' HILO_REG
'z' FP Status register
'b' All registers */
extern enum reg_class mips_char_to_class[];
......@@ -1548,8 +1557,10 @@ extern enum reg_class mips_char_to_class[];
/* The HI and LO registers can only be reloaded via the general
registers. */
#define SECONDARY_RELOAD_CLASS(CLASS, MODE, X) \
mips_secondary_reload_class (CLASS, MODE, X)
#define SECONDARY_INPUT_RELOAD_CLASS(CLASS, MODE, X) \
mips_secondary_reload_class (CLASS, MODE, X, 1)
#define SECONDARY_OUTPUT_RELOAD_CLASS(CLASS, MODE, X) \
mips_secondary_reload_class (CLASS, MODE, X, 0)
/* Not declared above, with the other functions, because enum
reg_class is not declared yet. */
......@@ -2870,9 +2881,11 @@ while (0)
: (FROM) == FP_REGS && (TO) == FP_REGS ? 2 \
: (FROM) == GR_REGS && (TO) == FP_REGS ? 4 \
: (FROM) == FP_REGS && (TO) == GR_REGS ? 4 \
: (((FROM) == HI_REG || (FROM) == LO_REG || (FROM) == MD_REGS) \
: (((FROM) == HI_REG || (FROM) == LO_REG \
|| (FROM) == MD_REGS || (FROM) == HILO_REG) \
&& (TO) == GR_REGS) ? 6 \
: (((TO) == HI_REG || (TO) == LO_REG || (TO) == MD_REGS) \
: (((TO) == HI_REG || (TO) == LO_REG \
|| (TO) == MD_REGS || (FROM) == HILO_REG) \
&& (FROM) == GR_REGS) ? 6 \
: 12)
......@@ -3085,6 +3098,7 @@ while (0)
&mips_reg_names[64][0], \
&mips_reg_names[65][0], \
&mips_reg_names[66][0], \
&mips_reg_names[67][0], \
}
/* print-rtl.c can't use REGISTER_NAMES, since it depends on mips.c.
......@@ -3099,7 +3113,7 @@ while (0)
"$f8", "$f9", "$f10", "$f11", "$f12", "$f13", "$f14", "$f15", \
"$f16", "$f17", "$f18", "$f19", "$f20", "$f21", "$f22", "$f23", \
"$f24", "$f25", "$f26", "$f27", "$f28", "$f29", "$f30", "$f31", \
"hi", "lo", "$fcr31" \
"hi", "lo", "accum","$fcr31" \
}
/* If defined, a C initializer for an array of structures
......
......@@ -830,7 +830,8 @@
[(set (match_operand:SI 0 "register_operand" "=l")
(mult:SI (match_operand:SI 1 "register_operand" "d")
(match_operand:SI 2 "register_operand" "d")))
(clobber (match_scratch:SI 3 "=h"))]
(clobber (match_scratch:SI 3 "=h"))
(clobber (match_scratch:SI 4 "=a"))]
""
"
{
......@@ -847,7 +848,8 @@
[(set (match_operand:SI 0 "register_operand" "=l")
(mult:SI (match_operand:SI 1 "register_operand" "d")
(match_operand:SI 2 "register_operand" "d")))
(clobber (match_scratch:SI 3 "=h"))]
(clobber (match_scratch:SI 3 "=h"))
(clobber (match_scratch:SI 4 "=a"))]
"mips_cpu != PROCESSOR_R4000"
"mult\\t%1,%2"
[(set_attr "type" "imul")
......@@ -859,7 +861,8 @@
(mult:SI (match_operand:SI 1 "register_operand" "d")
(match_operand:SI 2 "register_operand" "d")))
(clobber (match_scratch:SI 3 "=h"))
(clobber (match_scratch:SI 4 "=l"))]
(clobber (match_scratch:SI 4 "=l"))
(clobber (match_scratch:SI 5 "=a"))]
"mips_cpu == PROCESSOR_R4000"
"*
{
......@@ -881,7 +884,8 @@
(mult:SI (match_operand:SI 1 "register_operand" "d")
(match_operand:SI 2 "register_operand" "d")))
(clobber (match_scratch:SI 3 "=h"))
(clobber (match_scratch:SI 4 "=l"))]
(clobber (match_scratch:SI 4 "=l"))
(clobber (match_scratch:SI 5 "=a"))]
"TARGET_MAD"
"mul\\t%0,%1,%2"
[(set_attr "type" "imul")
......@@ -892,7 +896,8 @@
[(set (match_operand:DI 0 "register_operand" "=l")
(mult:DI (match_operand:DI 1 "register_operand" "d")
(match_operand:DI 2 "register_operand" "d")))
(clobber (match_scratch:DI 3 "=h"))]
(clobber (match_scratch:DI 3 "=h"))
(clobber (match_scratch:DI 4 "=a"))]
"TARGET_64BIT"
"
{
......@@ -907,7 +912,8 @@
[(set (match_operand:DI 0 "register_operand" "=l")
(mult:DI (match_operand:DI 1 "register_operand" "d")
(match_operand:DI 2 "register_operand" "d")))
(clobber (match_scratch:DI 3 "=h"))]
(clobber (match_scratch:DI 3 "=h"))
(clobber (match_scratch:DI 4 "=a"))]
"TARGET_64BIT && mips_cpu != PROCESSOR_R4000"
"dmult\\t%1,%2"
[(set_attr "type" "imul")
......@@ -919,7 +925,8 @@
(mult:DI (match_operand:DI 1 "register_operand" "d")
(match_operand:DI 2 "register_operand" "d")))
(clobber (match_scratch:DI 3 "=h"))
(clobber (match_scratch:DI 4 "=l"))]
(clobber (match_scratch:DI 4 "=l"))
(clobber (match_scratch:DI 5 "=a"))]
"TARGET_64BIT && mips_cpu == PROCESSOR_R4000"
"*
{
......@@ -936,53 +943,104 @@
(set_attr "mode" "DI")
(set_attr "length" "3")]) ;; mult + mflo + delay
;; In 64 bit mode the mult instruction still writes 32 bits each to HI
;; and LO, so to do mulsidi3 and umultsidi3 we need to pull the values
;; out and combine them by hand into the single output register. Not
;; supported for now.
;; ??? We could define a mulditi3 pattern when TARGET_64BIT.
(define_insn "mulsidi3"
(define_expand "mulsidi3"
[(set (match_operand:DI 0 "register_operand" "=x")
(mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "d"))
(sign_extend:DI (match_operand:SI 2 "register_operand" "d"))))]
""
"
{
if (TARGET_64BIT)
emit_insn (gen_mulsidi3_64bit (operands[0], operands[1], operands[2]));
else
emit_insn (gen_mulsidi3_internal (operands[0], operands[1], operands[2]));
DONE;
}")
(define_insn "mulsidi3_internal"
[(set (match_operand:DI 0 "register_operand" "=x")
(mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "d"))
(sign_extend:DI (match_operand:SI 2 "register_operand" "d"))))
(clobber (match_scratch:SI 3 "=a"))]
"!TARGET_64BIT"
"mult\\t%1,%2"
[(set_attr "type" "imul")
(set_attr "mode" "SI")
(set_attr "length" "1")])
(define_insn "mulsidi3_64bit"
[(set (match_operand:DI 0 "register_operand" "=a")
(mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "d"))
(sign_extend:DI (match_operand:SI 2 "register_operand" "d"))))
(clobber (match_scratch:DI 3 "=l"))
(clobber (match_scratch:DI 4 "=h"))]
"TARGET_64BIT"
"mult\\t%1,%2"
[(set_attr "type" "imul")
(set_attr "mode" "SI")
(set_attr "length" "1")])
(define_insn "smulsi3_highpart"
[(set (match_operand:SI 0 "register_operand" "=h")
(truncate:SI
(lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "d"))
(sign_extend:DI (match_operand:SI 2 "register_operand" "d")))
(const_int 32))))
(clobber (match_scratch:SI 3 "=l"))]
(clobber (match_scratch:SI 3 "=l"))
(clobber (match_scratch:SI 4 "=a"))]
""
"mult\\t%1,%2"
[(set_attr "type" "imul")
(set_attr "mode" "SI")
(set_attr "length" "1")])
(define_insn "umulsidi3"
(define_expand "umulsidi3"
[(set (match_operand:DI 0 "register_operand" "=x")
(mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "d"))
(zero_extend:DI (match_operand:SI 2 "register_operand" "d"))))]
""
"
{
if (TARGET_64BIT)
emit_insn (gen_umulsidi3_64bit (operands[0], operands[1], operands[2]));
else
emit_insn (gen_umulsidi3_internal (operands[0], operands[1], operands[2]));
DONE;
}")
(define_insn "umulsidi3_internal"
[(set (match_operand:DI 0 "register_operand" "=x")
(mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "d"))
(zero_extend:DI (match_operand:SI 2 "register_operand" "d"))))
(clobber (match_scratch:SI 3 "=a"))]
"!TARGET_64BIT"
"multu\\t%1,%2"
[(set_attr "type" "imul")
(set_attr "mode" "SI")
(set_attr "length" "1")])
(define_insn "umulsidi3_64bit"
[(set (match_operand:DI 0 "register_operand" "=a")
(mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "d"))
(zero_extend:DI (match_operand:SI 2 "register_operand" "d"))))
(clobber (match_scratch:DI 3 "=l"))
(clobber (match_scratch:DI 4 "=h"))]
"TARGET_64BIT"
"multu\\t%1,%2"
[(set_attr "type" "imul")
(set_attr "mode" "SI")
(set_attr "length" "1")])
(define_insn "umulsi3_highpart"
[(set (match_operand:SI 0 "register_operand" "=h")
(truncate:SI
(lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "d"))
(zero_extend:DI (match_operand:SI 2 "register_operand" "d")))
(const_int 32))))
(clobber (match_scratch:SI 3 "=l"))]
(clobber (match_scratch:SI 3 "=l"))
(clobber (match_scratch:SI 4 "=a"))]
""
"multu\\t%1,%2"
[(set_attr "type" "imul")
......@@ -995,7 +1053,8 @@
(lshiftrt:TI (mult:TI (sign_extend:TI (match_operand:DI 1 "register_operand" "d"))
(sign_extend:TI (match_operand:DI 2 "register_operand" "d")))
(const_int 64))))
(clobber (match_scratch:DI 3 "=l"))]
(clobber (match_scratch:DI 3 "=l"))
(clobber (match_scratch:DI 4 "=a"))]
"TARGET_64BIT"
"dmult\\t%1,%2"
[(set_attr "type" "imul")
......@@ -1008,7 +1067,8 @@
(lshiftrt:TI (mult:TI (zero_extend:TI (match_operand:DI 1 "register_operand" "d"))
(zero_extend:TI (match_operand:DI 2 "register_operand" "d")))
(const_int 64))))
(clobber (match_scratch:DI 3 "=l"))]
(clobber (match_scratch:DI 3 "=l"))
(clobber (match_scratch:DI 4 "=a"))]
"TARGET_64BIT"
"dmultu\\t%1,%2"
[(set_attr "type" "imul")
......@@ -1023,43 +1083,72 @@
(plus:SI (mult:SI (match_operand:SI 1 "register_operand" "d")
(match_operand:SI 2 "register_operand" "d"))
(match_dup 0)))
(clobber (match_scratch:SI 3 "=h"))]
(clobber (match_scratch:SI 3 "=h"))
(clobber (match_scratch:SI 4 "=a"))]
"TARGET_MAD"
"mad\\t%1,%2"
[(set_attr "type" "imul")
(set_attr "mode" "SI")
(set_attr "length" "1")])
;; ??? We can only refer to HI/LO as a register pair when not
;; compiling 64 bit code. That's because we don't know how to extract
;; the two 32 bit values into a single 64 bit register.
(define_insn "maddi"
[(set (match_operand:DI 0 "register_operand" "+x")
(plus:DI (mult:DI (sign_extend:DI
(match_operand:SI 1 "register_operand" "d"))
(sign_extend:DI
(match_operand:SI 2 "register_operand" "d")))
(match_dup 0)))]
(match_dup 0)))
(clobber (match_scratch:SI 3 "=a"))]
"TARGET_MAD && ! TARGET_64BIT"
"mad\\t%1,%2"
[(set_attr "type" "imul")
(set_attr "mode" "SI")
(set_attr "length" "1")])
(define_insn "maddi_64bit"
[(set (match_operand:DI 0 "register_operand" "+a")
(plus:DI (mult:DI (sign_extend:DI
(match_operand:SI 1 "register_operand" "d"))
(sign_extend:DI
(match_operand:SI 2 "register_operand" "d")))
(match_dup 0)))
(clobber (match_scratch:DI 3 "=l"))
(clobber (match_scratch:DI 4 "=h"))]
"TARGET_MAD && TARGET_64BIT"
"mad\\t%1,%2"
[(set_attr "type" "imul")
(set_attr "mode" "SI")
(set_attr "length" "1")])
(define_insn "umaddi"
[(set (match_operand:DI 0 "register_operand" "+x")
(plus:DI (mult:DI (zero_extend:DI
(match_operand:SI 1 "register_operand" "d"))
(zero_extend:DI
(match_operand:SI 2 "register_operand" "d")))
(match_dup 0)))]
(match_dup 0)))
(clobber (match_scratch:SI 3 "=a"))]
"TARGET_MAD && ! TARGET_64BIT"
"madu\\t%1,%2"
[(set_attr "type" "imul")
(set_attr "mode" "SI")
(set_attr "length" "1")])
(define_insn "umaddi_64bit"
[(set (match_operand:DI 0 "register_operand" "+a")
(plus:DI (mult:DI (zero_extend:DI
(match_operand:SI 1 "register_operand" "d"))
(zero_extend:DI
(match_operand:SI 2 "register_operand" "d")))
(match_dup 0)))
(clobber (match_scratch:DI 3 "=l"))
(clobber (match_scratch:DI 4 "=h"))]
"TARGET_MAD && TARGET_64BIT"
"madu\\t%1,%2"
[(set_attr "type" "imul")
(set_attr "mode" "SI")
(set_attr "length" "1")])
;; Floating point multiply accumulate instructions.
(define_insn ""
......@@ -1200,7 +1289,8 @@
(mod:SI (match_dup 1)
(match_dup 2)))
(clobber (match_scratch:SI 4 "=l"))
(clobber (match_scratch:SI 5 "=h"))]
(clobber (match_scratch:SI 5 "=h"))
(clobber (match_scratch:SI 6 "=a"))]
"optimize"
"*
{
......@@ -1224,7 +1314,8 @@
(mod:DI (match_dup 1)
(match_dup 2)))
(clobber (match_scratch:DI 4 "=l"))
(clobber (match_scratch:DI 5 "=h"))]
(clobber (match_scratch:DI 5 "=h"))
(clobber (match_scratch:DI 6 "=a"))]
"TARGET_64BIT && optimize"
"*
{
......@@ -1248,7 +1339,8 @@
(umod:SI (match_dup 1)
(match_dup 2)))
(clobber (match_scratch:SI 4 "=l"))
(clobber (match_scratch:SI 5 "=h"))]
(clobber (match_scratch:SI 5 "=h"))
(clobber (match_scratch:SI 6 "=a"))]
"optimize"
"*
{
......@@ -1272,7 +1364,8 @@
(umod:DI (match_dup 1)
(match_dup 2)))
(clobber (match_scratch:DI 4 "=l"))
(clobber (match_scratch:DI 5 "=h"))]
(clobber (match_scratch:DI 5 "=h"))
(clobber (match_scratch:DI 6 "=a"))]
"TARGET_64BIT && optimize"
"*
{
......@@ -1293,7 +1386,8 @@
(div:SI (match_operand:SI 1 "register_operand" "d")
(match_operand:SI 2 "nonmemory_operand" "di")))
(clobber (match_scratch:SI 3 "=l"))
(clobber (match_scratch:SI 4 "=h"))]
(clobber (match_scratch:SI 4 "=h"))
(clobber (match_scratch:SI 6 "=a"))]
"!optimize"
"div\\t%0,%1,%2"
[(set_attr "type" "idiv")
......@@ -1305,7 +1399,8 @@
(div:DI (match_operand:DI 1 "register_operand" "d")
(match_operand:DI 2 "nonmemory_operand" "di")))
(clobber (match_scratch:DI 3 "=l"))
(clobber (match_scratch:DI 4 "=h"))]
(clobber (match_scratch:DI 4 "=h"))
(clobber (match_scratch:DI 6 "=a"))]
"TARGET_64BIT && !optimize"
"ddiv\\t%0,%1,%2"
[(set_attr "type" "idiv")
......@@ -1317,7 +1412,8 @@
(mod:SI (match_operand:SI 1 "register_operand" "d")
(match_operand:SI 2 "nonmemory_operand" "di")))
(clobber (match_scratch:SI 3 "=l"))
(clobber (match_scratch:SI 4 "=h"))]
(clobber (match_scratch:SI 4 "=h"))
(clobber (match_scratch:SI 6 "=a"))]
"!optimize"
"rem\\t%0,%1,%2"
[(set_attr "type" "idiv")
......@@ -1329,7 +1425,8 @@
(mod:DI (match_operand:DI 1 "register_operand" "d")
(match_operand:DI 2 "nonmemory_operand" "di")))
(clobber (match_scratch:DI 3 "=l"))
(clobber (match_scratch:DI 4 "=h"))]
(clobber (match_scratch:DI 4 "=h"))
(clobber (match_scratch:DI 6 "=a"))]
"TARGET_64BIT && !optimize"
"drem\\t%0,%1,%2"
[(set_attr "type" "idiv")
......@@ -1341,7 +1438,8 @@
(udiv:SI (match_operand:SI 1 "register_operand" "d")
(match_operand:SI 2 "nonmemory_operand" "di")))
(clobber (match_scratch:SI 3 "=l"))
(clobber (match_scratch:SI 4 "=h"))]
(clobber (match_scratch:SI 4 "=h"))
(clobber (match_scratch:SI 6 "=a"))]
"!optimize"
"divu\\t%0,%1,%2"
[(set_attr "type" "idiv")
......@@ -1353,7 +1451,8 @@
(udiv:DI (match_operand:DI 1 "register_operand" "d")
(match_operand:DI 2 "nonmemory_operand" "di")))
(clobber (match_scratch:DI 3 "=l"))
(clobber (match_scratch:DI 4 "=h"))]
(clobber (match_scratch:DI 4 "=h"))
(clobber (match_scratch:DI 6 "=a"))]
"TARGET_64BIT && !optimize"
"ddivu\\t%0,%1,%2"
[(set_attr "type" "idiv")
......@@ -1365,7 +1464,8 @@
(umod:SI (match_operand:SI 1 "register_operand" "d")
(match_operand:SI 2 "nonmemory_operand" "di")))
(clobber (match_scratch:SI 3 "=l"))
(clobber (match_scratch:SI 4 "=h"))]
(clobber (match_scratch:SI 4 "=h"))
(clobber (match_scratch:SI 6 "=a"))]
"!optimize"
"remu\\t%0,%1,%2"
[(set_attr "type" "idiv")
......@@ -1377,7 +1477,8 @@
(umod:DI (match_operand:DI 1 "register_operand" "d")
(match_operand:DI 2 "nonmemory_operand" "di")))
(clobber (match_scratch:DI 3 "=l"))
(clobber (match_scratch:DI 4 "=h"))]
(clobber (match_scratch:DI 4 "=h"))
(clobber (match_scratch:DI 6 "=a"))]
"TARGET_64BIT && !optimize"
"dremu\\t%0,%1,%2"
[(set_attr "type" "idiv")
......@@ -2925,18 +3026,149 @@ move\\t%0,%z4\\n\\
"")
(define_insn "movdi_internal2"
[(set (match_operand:DI 0 "nonimmediate_operand" "=d,d,d,d,d,d,R,m,*d,*x")
(match_operand:DI 1 "general_operand" " d,S,IKL,Mnis,R,m,dJ,dJ,*x,*d"))]
[(set (match_operand:DI 0 "nonimmediate_operand" "=d,d,d,d,d,d,R,m,*d,*x,*a")
(match_operand:DI 1 "general_operand" " d,S,IKL,Mnis,R,m,dJ,dJ,*x,*d,*I"))]
"TARGET_64BIT
&& (register_operand (operands[0], DImode)
|| register_operand (operands[1], DImode)
|| (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) == 0)
|| operands[1] == CONST0_RTX (DImode))"
"* return mips_move_2words (operands, insn); "
[(set_attr "type" "move,load,arith,arith,load,load,store,store,hilo,hilo")
[(set_attr "type" "move,load,arith,arith,load,load,store,store,hilo,hilo,hilo")
(set_attr "mode" "DI")
(set_attr "length" "1,2,1,2,1,2,1,2,1,1")])
(set_attr "length" "1,2,1,2,1,2,1,2,1,1,2")])
;; Handle input reloads in DImode.
;; This is mainly to handle reloading HILO_REGNUM. Note that we may
;; see it as the source or the destination, depending upon which way
;; reload handles the instruction.
;; Making the second operand TImode is a trick. The compiler may
;; reuse the same register for operand 0 and operand 2. Using TImode
;; gives us two registers, so we can always use the one which is not
;; used.
(define_expand "reload_indi"
[(set (match_operand:DI 0 "register_operand" "=b")
(match_operand:DI 1 "general_operand" "b"))
(clobber (match_operand:TI 2 "register_operand" "=&d"))]
"TARGET_64BIT"
"
{
rtx scratch = gen_rtx (REG, DImode,
(REGNO (operands[0]) == REGNO (operands[2])
? REGNO (operands[2]) + 1
: REGNO (operands[2])));
if (GET_CODE (operands[0]) == REG && REGNO (operands[0]) == HILO_REGNUM)
{
if (GET_CODE (operands[1]) == MEM)
{
rtx memword, offword, hiword, loword;
scratch = gen_rtx (REG, SImode, REGNO (scratch));
memword = change_address (operands[1], SImode, NULL_RTX);
offword = change_address (adj_offsettable_operand (operands[1], 4),
SImode, NULL_RTX);
if (BYTES_BIG_ENDIAN)
{
hiword = memword;
loword = offword;
}
else
{
hiword = offword;
loword = memword;
}
emit_move_insn (scratch, hiword);
emit_move_insn (gen_rtx (REG, SImode, 64), scratch);
emit_move_insn (scratch, loword);
emit_move_insn (gen_rtx (REG, SImode, 65), scratch);
}
else
{
emit_insn (gen_ashrdi3 (scratch, operands[1], GEN_INT (32)));
emit_insn (gen_movdi (gen_rtx (REG, DImode, 64), scratch));
emit_insn (gen_ashldi3 (scratch, operands[1], GEN_INT (32)));
emit_insn (gen_ashrdi3 (scratch, scratch, GEN_INT (32)));
emit_insn (gen_movdi (gen_rtx (REG, DImode, 65), scratch));
}
DONE;
}
if (GET_CODE (operands[1]) == REG && REGNO (operands[1]) == HILO_REGNUM)
{
emit_insn (gen_movdi (scratch, gen_rtx (REG, DImode, 65)));
emit_insn (gen_ashldi3 (scratch, scratch, GEN_INT (32)));
emit_insn (gen_lshrdi3 (scratch, scratch, GEN_INT (32)));
emit_insn (gen_movdi (operands[0], gen_rtx (REG, DImode, 64)));
emit_insn (gen_ashldi3 (operands[0], operands[0], GEN_INT (32)));
emit_insn (gen_iordi3 (operands[0], operands[0], scratch));
DONE;
}
/* This handles moves between a float register and HI/LO. */
emit_move_insn (scratch, operands[1]);
emit_move_insn (operands[0], scratch);
DONE;
}")
;; Handle output reloads in DImode.
(define_expand "reload_outdi"
[(set (match_operand:DI 0 "general_operand" "=b")
(match_operand:DI 1 "register_operand" "b"))
(clobber (match_operand:DI 2 "register_operand" "=&d"))]
"TARGET_64BIT"
"
{
if (GET_CODE (operands[0]) == REG && REGNO (operands[0]) == HILO_REGNUM)
{
emit_insn (gen_ashrdi3 (operands[2], operands[1], GEN_INT (32)));
emit_insn (gen_movdi (gen_rtx (REG, DImode, 64), operands[2]));
emit_insn (gen_ashldi3 (operands[2], operands[1], GEN_INT (32)));
emit_insn (gen_ashrdi3 (operands[2], operands[2], GEN_INT (32)));
emit_insn (gen_movdi (gen_rtx (REG, DImode, 65), operands[2]));
DONE;
}
if (GET_CODE (operands[1]) == REG && REGNO (operands[1]) == HILO_REGNUM)
{
if (GET_CODE (operands[0]) == MEM)
{
rtx scratch, memword, offword, hiword, loword;
scratch = gen_rtx (REG, SImode, REGNO (operands[2]));
memword = change_address (operands[0], SImode, NULL_RTX);
offword = change_address (adj_offsettable_operand (operands[0], 4),
SImode, NULL_RTX);
if (BYTES_BIG_ENDIAN)
{
hiword = memword;
loword = offword;
}
else
{
hiword = offword;
loword = memword;
}
emit_move_insn (scratch, gen_rtx (REG, SImode, 64));
emit_move_insn (hiword, scratch);
emit_move_insn (scratch, gen_rtx (REG, SImode, 65));
emit_move_insn (loword, scratch);
}
else
{
emit_insn (gen_movdi (operands[2], gen_rtx (REG, DImode, 65)));
emit_insn (gen_ashldi3 (operands[2], operands[2], GEN_INT (32)));
emit_insn (gen_lshrdi3 (operands[2], operands[2], GEN_INT (32)));
emit_insn (gen_movdi (operands[0], gen_rtx (REG, DImode, 64)));
emit_insn (gen_ashldi3 (operands[0], operands[0], GEN_INT (32)));
emit_insn (gen_iordi3 (operands[0], operands[0], operands[2]));
}
DONE;
}
/* This handles moves between a float register and HI/LO. */
emit_move_insn (operands[2], operands[1]);
emit_move_insn (operands[0], operands[2]);
DONE;
}")
;; 32-bit Integer moves
......@@ -3011,29 +3243,51 @@ move\\t%0,%z4\\n\\
;; in FP registers (off by default, use -mdebugh to enable).
(define_insn "movsi_internal1"
[(set (match_operand:SI 0 "nonimmediate_operand" "=d,d,d,d,d,d,R,m,*d,*f*z,*f,*f,*f,*R,*m,*x,*d")
(match_operand:SI 1 "general_operand" "d,S,IKL,Mnis,R,m,dJ,dJ,*f*z,*d,*f,*R,*m,*f,*f,*d,*x"))]
[(set (match_operand:SI 0 "nonimmediate_operand" "=d,d,d,d,d,d,R,m,*d,*f*z,*f,*f,*f,*R,*m,*x,*x,*d,*d")
(match_operand:SI 1 "general_operand" "d,S,IKL,Mnis,R,m,dJ,dJ,*f*z,*d,*f,*R,*m,*f,*f,I,*d,*x,*a"))]
"TARGET_DEBUG_H_MODE
&& (register_operand (operands[0], SImode)
|| register_operand (operands[1], SImode)
|| (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) == 0))"
"* return mips_move_1word (operands, insn, FALSE);"
[(set_attr "type" "move,load,arith,arith,load,load,store,store,xfer,xfer,move,load,load,store,store,hilo,hilo")
[(set_attr "type" "move,load,arith,arith,load,load,store,store,xfer,xfer,move,load,load,store,store,hilo,hilo,hilo,hilo")
(set_attr "mode" "SI")
(set_attr "length" "1,2,1,2,1,2,1,2,1,1,1,1,2,1,2,1,1")])
(set_attr "length" "1,2,1,2,1,2,1,2,1,1,1,1,2,1,2,1,1,1,1")])
(define_insn "movsi_internal2"
[(set (match_operand:SI 0 "nonimmediate_operand" "=d,d,d,d,d,d,R,m,*d,*z,*d,*x")
(match_operand:SI 1 "general_operand" "d,S,IKL,Mnis,R,m,dJ,dJ,*z,*d,*x,*d"))]
[(set (match_operand:SI 0 "nonimmediate_operand" "=d,d,d,d,d,d,R,m,*d,*z,*x,*d,*x,*d")
(match_operand:SI 1 "general_operand" "d,S,IKL,Mnis,R,m,dJ,dJ,*z,*d,I,*x,*d,*a"))]
"!TARGET_DEBUG_H_MODE
&& (register_operand (operands[0], SImode)
|| register_operand (operands[1], SImode)
|| (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) == 0))"
"* return mips_move_1word (operands, insn, FALSE);"
[(set_attr "type" "move,load,arith,arith,load,load,store,store,xfer,xfer,hilo,hilo")
[(set_attr "type" "move,load,arith,arith,load,load,store,store,xfer,xfer,hilo,hilo,hilo,hilo")
(set_attr "mode" "SI")
(set_attr "length" "1,2,1,2,1,2,1,2,1,1,1,1")])
(set_attr "length" "1,2,1,2,1,2,1,2,1,1,1,1,1,1")])
;; Reload HILO_REGNUM in SI mode. This needs a scratch register in
;; order to set the sign bit correctly in the HI register.
(define_expand "reload_outsi"
[(set (match_operand:SI 0 "general_operand" "=b")
(match_operand:SI 1 "register_operand" "d"))
(clobber (match_operand:SI 2 "register_operand" "=&d"))]
"TARGET_64BIT"
"
{
if (GET_CODE (operands[0]) == REG && REGNO (operands[0]) == HILO_REGNUM)
{
emit_insn (gen_movsi (gen_rtx (REG, SImode, 65), operands[1]));
emit_insn (gen_ashrsi3 (operands[2], operands[1], GEN_INT (31)));
emit_insn (gen_movsi (gen_rtx (REG, SImode, 64), operands[2]));
DONE;
}
/* This handles moves between a float register and HI/LO. */
emit_move_insn (operands[2], operands[1]);
emit_move_insn (operands[0], operands[2]);
DONE;
}")
;; 16-bit Integer moves
......@@ -4201,7 +4455,7 @@ move\\t%0,%z4\\n\\
(define_insn "branch_fp_ne"
[(set (pc)
(if_then_else (ne:CC_FP (reg:CC_FP 66)
(if_then_else (ne:CC_FP (reg:CC_FP 67)
(const_int 0))
(match_operand 0 "pc_or_label_operand" "")
(match_operand 1 "pc_or_label_operand" "")))]
......@@ -4217,7 +4471,7 @@ move\\t%0,%z4\\n\\
(define_insn "branch_fp_ne_rev"
[(set (pc)
(if_then_else (ne:CC_REV_FP (reg:CC_REV_FP 66)
(if_then_else (ne:CC_REV_FP (reg:CC_REV_FP 67)
(const_int 0))
(match_operand 0 "pc_or_label_operand" "")
(match_operand 1 "pc_or_label_operand" "")))]
......@@ -4233,7 +4487,7 @@ move\\t%0,%z4\\n\\
(define_insn "branch_fp_eq"
[(set (pc)
(if_then_else (eq:CC_FP (reg:CC_FP 66)
(if_then_else (eq:CC_FP (reg:CC_FP 67)
(const_int 0))
(match_operand 0 "pc_or_label_operand" "")
(match_operand 1 "pc_or_label_operand" "")))]
......@@ -4249,7 +4503,7 @@ move\\t%0,%z4\\n\\
(define_insn "branch_fp_eq_rev"
[(set (pc)
(if_then_else (eq:CC_REV_FP (reg:CC_REV_FP 66)
(if_then_else (eq:CC_REV_FP (reg:CC_REV_FP 67)
(const_int 0))
(match_operand 0 "pc_or_label_operand" "")
(match_operand 1 "pc_or_label_operand" "")))]
......@@ -5285,7 +5539,7 @@ move\\t%0,%z4\\n\\
;; ....................
(define_insn "seq_df"
[(set (reg:CC_FP 66)
[(set (reg:CC_FP 67)
(eq:CC_FP (match_operand:DF 0 "register_operand" "f")
(match_operand:DF 1 "register_operand" "f")))]
"TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
......@@ -5303,7 +5557,7 @@ move\\t%0,%z4\\n\\
(set_attr "length" "1")])
(define_insn "sne_df"
[(set (reg:CC_REV_FP 66)
[(set (reg:CC_REV_FP 67)
(ne:CC_REV_FP (match_operand:DF 0 "register_operand" "f")
(match_operand:DF 1 "register_operand" "f")))]
"TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
......@@ -5321,7 +5575,7 @@ move\\t%0,%z4\\n\\
(set_attr "length" "1")])
(define_insn "slt_df"
[(set (reg:CC_FP 66)
[(set (reg:CC_FP 67)
(lt:CC_FP (match_operand:DF 0 "register_operand" "f")
(match_operand:DF 1 "register_operand" "f")))]
"TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
......@@ -5339,7 +5593,7 @@ move\\t%0,%z4\\n\\
(set_attr "length" "1")])
(define_insn "sle_df"
[(set (reg:CC_FP 66)
[(set (reg:CC_FP 67)
(le:CC_FP (match_operand:DF 0 "register_operand" "f")
(match_operand:DF 1 "register_operand" "f")))]
"TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
......@@ -5357,7 +5611,7 @@ move\\t%0,%z4\\n\\
(set_attr "length" "1")])
(define_insn "sgt_df"
[(set (reg:CC_FP 66)
[(set (reg:CC_FP 67)
(gt:CC_FP (match_operand:DF 0 "register_operand" "f")
(match_operand:DF 1 "register_operand" "f")))]
"TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
......@@ -5375,7 +5629,7 @@ move\\t%0,%z4\\n\\
(set_attr "length" "1")])
(define_insn "sge_df"
[(set (reg:CC_FP 66)
[(set (reg:CC_FP 67)
(ge:CC_FP (match_operand:DF 0 "register_operand" "f")
(match_operand:DF 1 "register_operand" "f")))]
"TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
......@@ -5393,7 +5647,7 @@ move\\t%0,%z4\\n\\
(set_attr "length" "1")])
(define_insn "seq_sf"
[(set (reg:CC_FP 66)
[(set (reg:CC_FP 67)
(eq:CC_FP (match_operand:SF 0 "register_operand" "f")
(match_operand:SF 1 "register_operand" "f")))]
"TARGET_HARD_FLOAT"
......@@ -5411,7 +5665,7 @@ move\\t%0,%z4\\n\\
(set_attr "length" "1")])
(define_insn "sne_sf"
[(set (reg:CC_REV_FP 66)
[(set (reg:CC_REV_FP 67)
(ne:CC_REV_FP (match_operand:SF 0 "register_operand" "f")
(match_operand:SF 1 "register_operand" "f")))]
"TARGET_HARD_FLOAT"
......@@ -5429,7 +5683,7 @@ move\\t%0,%z4\\n\\
(set_attr "length" "1")])
(define_insn "slt_sf"
[(set (reg:CC_FP 66)
[(set (reg:CC_FP 67)
(lt:CC_FP (match_operand:SF 0 "register_operand" "f")
(match_operand:SF 1 "register_operand" "f")))]
"TARGET_HARD_FLOAT"
......@@ -5447,7 +5701,7 @@ move\\t%0,%z4\\n\\
(set_attr "length" "1")])
(define_insn "sle_sf"
[(set (reg:CC_FP 66)
[(set (reg:CC_FP 67)
(le:CC_FP (match_operand:SF 0 "register_operand" "f")
(match_operand:SF 1 "register_operand" "f")))]
"TARGET_HARD_FLOAT"
......@@ -5465,7 +5719,7 @@ move\\t%0,%z4\\n\\
(set_attr "length" "1")])
(define_insn "sgt_sf"
[(set (reg:CC_FP 66)
[(set (reg:CC_FP 67)
(gt:CC_FP (match_operand:SF 0 "register_operand" "f")
(match_operand:SF 1 "register_operand" "f")))]
"TARGET_HARD_FLOAT"
......@@ -5483,7 +5737,7 @@ move\\t%0,%z4\\n\\
(set_attr "length" "1")])
(define_insn "sge_sf"
[(set (reg:CC_FP 66)
[(set (reg:CC_FP 67)
(ge:CC_FP (match_operand:SF 0 "register_operand" "f")
(match_operand:SF 1 "register_operand" "f")))]
"TARGET_HARD_FLOAT"
......@@ -6193,7 +6447,7 @@ move\\t%0,%z4\\n\\
(define_insn ""
[(set (match_operand:SI 0 "register_operand" "=d,d")
(if_then_else:SI
(match_operator 3 "equality_op" [(reg:CC_FP 66) (const_int 0)])
(match_operator 3 "equality_op" [(reg:CC_FP 67) (const_int 0)])
(match_operand:SI 1 "reg_or_0_operand" "dJ,0")
(match_operand:SI 2 "reg_or_0_operand" "0,dJ")))]
"mips_isa >= 4"
......@@ -6221,7 +6475,7 @@ move\\t%0,%z4\\n\\
(define_insn ""
[(set (match_operand:DI 0 "register_operand" "=d,d")
(if_then_else:DI
(match_operator 3 "equality_op" [(reg:CC_FP 66) (const_int 0)])
(match_operator 3 "equality_op" [(reg:CC_FP 67) (const_int 0)])
(match_operand:DI 1 "reg_or_0_operand" "dJ,0")
(match_operand:DI 2 "reg_or_0_operand" "0,dJ")))]
"mips_isa >= 4"
......@@ -6249,7 +6503,7 @@ move\\t%0,%z4\\n\\
(define_insn ""
[(set (match_operand:SF 0 "register_operand" "=f,f")
(if_then_else:SF
(match_operator 3 "equality_op" [(reg:CC_FP 66) (const_int 0)])
(match_operator 3 "equality_op" [(reg:CC_FP 67) (const_int 0)])
(match_operand:SF 1 "register_operand" "f,0")
(match_operand:SF 2 "register_operand" "0,f")))]
"mips_isa >= 4 && TARGET_HARD_FLOAT"
......@@ -6277,7 +6531,7 @@ move\\t%0,%z4\\n\\
(define_insn ""
[(set (match_operand:DF 0 "register_operand" "=f,f")
(if_then_else:DF
(match_operator 3 "equality_op" [(reg:CC_FP 66) (const_int 0)])
(match_operator 3 "equality_op" [(reg:CC_FP 67) (const_int 0)])
(match_operand:DF 1 "register_operand" "f,0")
(match_operand:DF 2 "register_operand" "0,f")))]
"mips_isa >= 4 && TARGET_HARD_FLOAT"
......
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