mirror of
git://gcc.gnu.org/git/gcc.git
synced 2025-04-23 01:50:33 +08:00
re PR target/33635 (Bootstrap broken on mips-sgi-irix6.5)
gcc/ PR target/33635 * config/mips/mips-protos.h (mips_split_64bit_move): Rename to... (mips_split_doubleword_move): ...this. * config/mips/mips.c (mips_subword): Extend to handle 64-bit words; use natural endianness for multi-format FPR values. (mips_split_64bit_move): Rename to... (mips_split_doubleword_move): ...this and extend to 64-bit words. Use move_doubleword_fpr* patterns for moves involving FPRs. (mips_save_reg): Update the call to mips_split_64bit_move. (mips_secondary_reload_class): Return NO_REGS for any reload of a nonzero constant into an FPR if the constant can be forced to memory. * config/mips/mips.md: Update the splitter calls to mips_split_64bit_move. (UNSPEC_LOAD_DF_LOW): Rename to... (UNSPEC_LOAD_LOW): ...this. (UNSPEC_LOAD_DF_HIGH): Rename to... (UNSPEC_LOAD_HIGH): ...this. (UNSPEC_STORE_DF_HIGH): Rename to... (UNSPEC_STORE_WORD): ...this. (SPLITF): New mode iterator. (HALFMODE): New mode attribute. (movtf): New expander. (*movtf_internal): New define_insn_and_split. (move_doubleword_fpr<mode>): New expander. (load_df_low, load_df_high, store_df_high, mthc1, mfhc1): Replace with... (load_low<mode>, load_high<mode>, store_word<mode>, mthc1<mode>) (mfhc1<mode>): ...these more general patterns. gcc/testsuite/ PR target/33635 * gcc.target/mips/mips.exp (setup_mips_tests): Set mips_isa_rev and mips_forced_be. (dg-mips-options): Handle -EL and -mel. Make -mfp64 imply -mhard-float and a suitable ISA. Improve handling of -mipsXrY options. * gcc.target/mips/fpr-moves-1.c: New test. * gcc.target/mips/fpr-moves-2.c: Likewise. * gcc.target/mips/fpr-moves-3.c: Likewise. * gcc.target/mips/fpr-moves-4.c: Likewise. * gcc.target/mips/fpr-moves-5.c: Likewise. * gcc.target/mips/fpr-moves-6.c: Likewise. * gcc.target/mips/mips32r2-mxhc1.c: Remove -march=mips32r2 From-SVN: r128991
This commit is contained in:
parent
f5783e34f9
commit
0064fbe9b6
@ -1,3 +1,34 @@
|
||||
2007-10-03 Richard Sandiford <rsandifo@nildram.co.uk>
|
||||
|
||||
PR target/33635
|
||||
* config/mips/mips-protos.h (mips_split_64bit_move): Rename to...
|
||||
(mips_split_doubleword_move): ...this.
|
||||
* config/mips/mips.c (mips_subword): Extend to handle 64-bit words;
|
||||
use natural endianness for multi-format FPR values.
|
||||
(mips_split_64bit_move): Rename to...
|
||||
(mips_split_doubleword_move): ...this and extend to 64-bit words.
|
||||
Use move_doubleword_fpr* patterns for moves involving FPRs.
|
||||
(mips_save_reg): Update the call to mips_split_64bit_move.
|
||||
(mips_secondary_reload_class): Return NO_REGS for any reload of a
|
||||
nonzero constant into an FPR if the constant can be forced to memory.
|
||||
* config/mips/mips.md: Update the splitter calls to
|
||||
mips_split_64bit_move.
|
||||
(UNSPEC_LOAD_DF_LOW): Rename to...
|
||||
(UNSPEC_LOAD_LOW): ...this.
|
||||
(UNSPEC_LOAD_DF_HIGH): Rename to...
|
||||
(UNSPEC_LOAD_HIGH): ...this.
|
||||
(UNSPEC_STORE_DF_HIGH): Rename to...
|
||||
(UNSPEC_STORE_WORD): ...this.
|
||||
(SPLITF): New mode iterator.
|
||||
(HALFMODE): New mode attribute.
|
||||
(movtf): New expander.
|
||||
(*movtf_internal): New define_insn_and_split.
|
||||
(move_doubleword_fpr<mode>): New expander.
|
||||
(load_df_low, load_df_high, store_df_high, mthc1, mfhc1): Replace
|
||||
with...
|
||||
(load_low<mode>, load_high<mode>, store_word<mode>, mthc1<mode>)
|
||||
(mfhc1<mode>): ...these more general patterns.
|
||||
|
||||
2007-10-03 Alexandre Oliva <aoliva@redhat.com>
|
||||
|
||||
* cfgrtl.c (rtl_block_ends_with_call_p): Skip notes at the end.
|
||||
|
@ -201,7 +201,7 @@ extern int m16_nsimm8_8 (rtx, enum machine_mode);
|
||||
|
||||
extern rtx mips_subword (rtx, int);
|
||||
extern bool mips_split_64bit_move_p (rtx, rtx);
|
||||
extern void mips_split_64bit_move (rtx, rtx);
|
||||
extern void mips_split_doubleword_move (rtx, rtx);
|
||||
extern const char *mips_output_move (rtx, rtx);
|
||||
extern void mips_restore_gp (void);
|
||||
#ifdef RTX_CODE
|
||||
|
@ -3477,7 +3477,7 @@ mips_address_cost (rtx addr)
|
||||
rtx
|
||||
mips_subword (rtx op, int high_p)
|
||||
{
|
||||
unsigned int byte;
|
||||
unsigned int byte, offset;
|
||||
enum machine_mode mode;
|
||||
|
||||
mode = GET_MODE (op);
|
||||
@ -3490,7 +3490,11 @@ mips_subword (rtx op, int high_p)
|
||||
byte = 0;
|
||||
|
||||
if (FP_REG_RTX_P (op))
|
||||
return gen_rtx_REG (word_mode, high_p ? REGNO (op) + 1 : REGNO (op));
|
||||
{
|
||||
/* Paired FPRs are always ordered little-endian. */
|
||||
offset = (UNITS_PER_WORD < UNITS_PER_HWFPVALUE ? high_p : byte != 0);
|
||||
return gen_rtx_REG (word_mode, REGNO (op) + offset);
|
||||
}
|
||||
|
||||
if (MEM_P (op))
|
||||
return mips_rewrite_small_data (adjust_address (op, word_mode, byte));
|
||||
@ -3524,58 +3528,23 @@ mips_split_64bit_move_p (rtx dest, rtx src)
|
||||
}
|
||||
|
||||
|
||||
/* Split a 64-bit move from SRC to DEST assuming that
|
||||
mips_split_64bit_move_p holds.
|
||||
|
||||
Moves into and out of FPRs cause some difficulty here. Such moves
|
||||
will always be DFmode, since paired FPRs are not allowed to store
|
||||
DImode values. The most natural representation would be two separate
|
||||
32-bit moves, such as:
|
||||
|
||||
(set (reg:SI $f0) (mem:SI ...))
|
||||
(set (reg:SI $f1) (mem:SI ...))
|
||||
|
||||
However, the second insn is invalid because odd-numbered FPRs are
|
||||
not allowed to store independent values. Use the patterns load_df_low,
|
||||
load_df_high and store_df_high instead. */
|
||||
/* Split a doubleword move from SRC to DEST. On 32-bit targets,
|
||||
this function handles 64-bit moves for which mips_split_64bit_move_p
|
||||
holds. For 64-bit targets, this function handles 128-bit moves. */
|
||||
|
||||
void
|
||||
mips_split_64bit_move (rtx dest, rtx src)
|
||||
mips_split_doubleword_move (rtx dest, rtx src)
|
||||
{
|
||||
if (FP_REG_RTX_P (dest))
|
||||
if (FP_REG_RTX_P (dest) || FP_REG_RTX_P (src))
|
||||
{
|
||||
/* Loading an FPR from memory or from GPRs. */
|
||||
if (ISA_HAS_MXHC1)
|
||||
{
|
||||
if (GET_MODE (dest) != DFmode)
|
||||
dest = gen_rtx_REG_offset (dest, DFmode, REGNO (dest), 0);
|
||||
emit_insn (gen_load_df_low (dest, mips_subword (src, 0)));
|
||||
emit_insn (gen_mthc1 (dest, mips_subword (src, 1),
|
||||
copy_rtx (dest)));
|
||||
}
|
||||
if (!TARGET_64BIT && GET_MODE (dest) == DImode)
|
||||
emit_insn (gen_move_doubleword_fprdi (dest, src));
|
||||
else if (!TARGET_64BIT && GET_MODE (dest) == DFmode)
|
||||
emit_insn (gen_move_doubleword_fprdf (dest, src));
|
||||
else if (TARGET_64BIT && GET_MODE (dest) == TFmode)
|
||||
emit_insn (gen_move_doubleword_fprtf (dest, src));
|
||||
else
|
||||
{
|
||||
emit_insn (gen_load_df_low (copy_rtx (dest),
|
||||
mips_subword (src, 0)));
|
||||
emit_insn (gen_load_df_high (dest, mips_subword (src, 1),
|
||||
copy_rtx (dest)));
|
||||
}
|
||||
}
|
||||
else if (FP_REG_RTX_P (src))
|
||||
{
|
||||
/* Storing an FPR into memory or GPRs. */
|
||||
if (ISA_HAS_MXHC1)
|
||||
{
|
||||
if (GET_MODE (src) != DFmode)
|
||||
src = gen_rtx_REG_offset (src, DFmode, REGNO (src), 0);
|
||||
mips_emit_move (mips_subword (dest, 0), mips_subword (src, 0));
|
||||
emit_insn (gen_mfhc1 (mips_subword (dest, 1), src));
|
||||
}
|
||||
else
|
||||
{
|
||||
mips_emit_move (mips_subword (dest, 0), mips_subword (src, 0));
|
||||
emit_insn (gen_store_df_high (mips_subword (dest, 1), src));
|
||||
}
|
||||
gcc_unreachable ();
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -8042,7 +8011,7 @@ mips_save_reg (rtx reg, rtx mem)
|
||||
rtx x1, x2;
|
||||
|
||||
if (mips_split_64bit_move_p (mem, reg))
|
||||
mips_split_64bit_move (mem, reg);
|
||||
mips_split_doubleword_move (mem, reg);
|
||||
else
|
||||
mips_emit_move (mem, reg);
|
||||
|
||||
@ -9472,18 +9441,15 @@ mips_secondary_reload_class (enum reg_class class,
|
||||
/* In this case we can use mtc1, mfc1, dmtc1 or dmfc1. */
|
||||
return NO_REGS;
|
||||
|
||||
if (mips_mode_ok_for_mov_fmt_p (mode))
|
||||
{
|
||||
if (CONSTANT_P (x))
|
||||
/* We can force the constants to memory and use lwc1
|
||||
and ldc1. As above, we will use pairs of lwc1s if
|
||||
ldc1 is not supported. */
|
||||
return NO_REGS;
|
||||
if (CONSTANT_P (x) && !targetm.cannot_force_const_mem (x))
|
||||
/* We can force the constant to memory and use lwc1
|
||||
and ldc1. As above, we will use pairs of lwc1s if
|
||||
ldc1 is not supported. */
|
||||
return NO_REGS;
|
||||
|
||||
if (FP_REG_P (regno))
|
||||
/* In this case we can use mov.fmt. */
|
||||
return NO_REGS;
|
||||
}
|
||||
if (FP_REG_P (regno) && mips_mode_ok_for_mov_fmt_p (mode))
|
||||
/* In this case we can use mov.fmt. */
|
||||
return NO_REGS;
|
||||
|
||||
/* Otherwise, we need to reload through an integer register. */
|
||||
return GR_REGS;
|
||||
|
@ -24,9 +24,9 @@
|
||||
;; <http://www.gnu.org/licenses/>.
|
||||
|
||||
(define_constants
|
||||
[(UNSPEC_LOAD_DF_LOW 0)
|
||||
(UNSPEC_LOAD_DF_HIGH 1)
|
||||
(UNSPEC_STORE_DF_HIGH 2)
|
||||
[(UNSPEC_LOAD_LOW 0)
|
||||
(UNSPEC_LOAD_HIGH 1)
|
||||
(UNSPEC_STORE_WORD 2)
|
||||
(UNSPEC_GET_FNADDR 3)
|
||||
(UNSPEC_BLOCKAGE 4)
|
||||
(UNSPEC_CPRESTORE 5)
|
||||
@ -498,6 +498,11 @@
|
||||
(define_mode_iterator SCALARF [(SF "TARGET_HARD_FLOAT")
|
||||
(DF "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT")])
|
||||
|
||||
;; A floating-point mode for which moves involving FPRs may need to be split.
|
||||
(define_mode_iterator SPLITF [(DF "!TARGET_64BIT")
|
||||
(DI "!TARGET_64BIT")
|
||||
(TF "TARGET_64BIT")])
|
||||
|
||||
;; In GPR templates, a string like "<d>subu" will expand to "subu" in the
|
||||
;; 32-bit version and "dsubu" in the 64-bit version.
|
||||
(define_mode_attr d [(SI "") (DI "d")
|
||||
@ -546,6 +551,10 @@
|
||||
(V4UQQ "SI") (V2UHQ "SI") (V2UHA "SI")
|
||||
(V2HQ "SI") (V2HA "SI")])
|
||||
|
||||
;; This attribute gives the integer mode that has half the size of
|
||||
;; the controlling mode.
|
||||
(define_mode_attr HALFMODE [(DF "SI") (DI "SI") (TF "DI")])
|
||||
|
||||
;; This attribute works around the early SB-1 rev2 core "F2" erratum:
|
||||
;;
|
||||
;; In certain cases, div.s and div.ps may have a rounding error
|
||||
@ -3999,6 +4008,32 @@
|
||||
(set_attr "mode" "DF")
|
||||
(set_attr "length" "8,8,8,*,*")])
|
||||
|
||||
;; 128-bit floating point moves
|
||||
|
||||
(define_expand "movtf"
|
||||
[(set (match_operand:TF 0 "")
|
||||
(match_operand:TF 1 ""))]
|
||||
""
|
||||
{
|
||||
if (mips_legitimize_move (TFmode, operands[0], operands[1]))
|
||||
DONE;
|
||||
})
|
||||
|
||||
;; This pattern handles both hard- and soft-float cases.
|
||||
(define_insn_and_split "*movtf_internal"
|
||||
[(set (match_operand:TF 0 "nonimmediate_operand" "=d,R,f,dR")
|
||||
(match_operand:TF 1 "move_operand" "dGR,dG,dGR,f"))]
|
||||
""
|
||||
"#"
|
||||
"&& reload_completed"
|
||||
[(const_int 0)]
|
||||
{
|
||||
mips_split_doubleword_move (operands[0], operands[1]);
|
||||
DONE;
|
||||
}
|
||||
[(set_attr "type" "multi")
|
||||
(set_attr "length" "16")])
|
||||
|
||||
(define_split
|
||||
[(set (match_operand:DI 0 "nonimmediate_operand")
|
||||
(match_operand:DI 1 "move_operand"))]
|
||||
@ -4006,7 +4041,7 @@
|
||||
&& mips_split_64bit_move_p (operands[0], operands[1])"
|
||||
[(const_int 0)]
|
||||
{
|
||||
mips_split_64bit_move (operands[0], operands[1]);
|
||||
mips_split_doubleword_move (operands[0], operands[1]);
|
||||
DONE;
|
||||
})
|
||||
|
||||
@ -4017,7 +4052,7 @@
|
||||
&& mips_split_64bit_move_p (operands[0], operands[1])"
|
||||
[(const_int 0)]
|
||||
{
|
||||
mips_split_64bit_move (operands[0], operands[1]);
|
||||
mips_split_doubleword_move (operands[0], operands[1]);
|
||||
DONE;
|
||||
})
|
||||
|
||||
@ -4099,74 +4134,105 @@
|
||||
[(set_attr "type" "mfhilo")
|
||||
(set_attr "mode" "<MODE>")])
|
||||
|
||||
;; Patterns for loading or storing part of a paired floating point
|
||||
;; register. We need them because odd-numbered floating-point registers
|
||||
;; are not fully independent: see mips_split_64bit_move.
|
||||
;; Emit a doubleword move in which exactly one of the operands is
|
||||
;; a floating-point register. We can't just emit two normal moves
|
||||
;; because of the constraints imposed by the FPU register model;
|
||||
;; see mips_cannot_change_mode_class for details. Instead, we keep
|
||||
;; the FPR whole and use special patterns to refer to each word of
|
||||
;; the other operand.
|
||||
|
||||
(define_expand "move_doubleword_fpr<mode>"
|
||||
[(set (match_operand:SPLITF 0)
|
||||
(match_operand:SPLITF 1))]
|
||||
""
|
||||
{
|
||||
if (FP_REG_RTX_P (operands[0]))
|
||||
{
|
||||
rtx low = mips_subword (operands[1], 0);
|
||||
rtx high = mips_subword (operands[1], 1);
|
||||
emit_insn (gen_load_low<mode> (operands[0], low));
|
||||
if (ISA_HAS_MXHC1)
|
||||
emit_insn (gen_mthc1<mode> (operands[0], high, operands[0]));
|
||||
else
|
||||
emit_insn (gen_load_high<mode> (operands[0], high, operands[0]));
|
||||
}
|
||||
else
|
||||
{
|
||||
rtx low = mips_subword (operands[0], 0);
|
||||
rtx high = mips_subword (operands[0], 1);
|
||||
emit_insn (gen_store_word<mode> (low, operands[1], const0_rtx));
|
||||
if (ISA_HAS_MXHC1)
|
||||
emit_insn (gen_mfhc1<mode> (high, operands[1]));
|
||||
else
|
||||
emit_insn (gen_store_word<mode> (high, operands[1], const1_rtx));
|
||||
}
|
||||
DONE;
|
||||
})
|
||||
|
||||
;; Load the low word of operand 0 with operand 1.
|
||||
(define_insn "load_df_low"
|
||||
[(set (match_operand:DF 0 "register_operand" "=f,f")
|
||||
(unspec:DF [(match_operand:SI 1 "general_operand" "dJ,m")]
|
||||
UNSPEC_LOAD_DF_LOW))]
|
||||
"TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && !TARGET_64BIT"
|
||||
(define_insn "load_low<mode>"
|
||||
[(set (match_operand:SPLITF 0 "register_operand" "=f,f")
|
||||
(unspec:SPLITF [(match_operand:<HALFMODE> 1 "general_operand" "dJ,m")]
|
||||
UNSPEC_LOAD_LOW))]
|
||||
"TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
|
||||
{
|
||||
operands[0] = mips_subword (operands[0], 0);
|
||||
return mips_output_move (operands[0], operands[1]);
|
||||
}
|
||||
[(set_attr "type" "mtc,fpload")
|
||||
(set_attr "mode" "SF")])
|
||||
[(set_attr "type" "mtc,fpload")
|
||||
(set_attr "mode" "<HALFMODE>")])
|
||||
|
||||
;; Load the high word of operand 0 from operand 1, preserving the value
|
||||
;; in the low word.
|
||||
(define_insn "load_df_high"
|
||||
[(set (match_operand:DF 0 "register_operand" "=f,f")
|
||||
(unspec:DF [(match_operand:SI 1 "general_operand" "dJ,m")
|
||||
(match_operand:DF 2 "register_operand" "0,0")]
|
||||
UNSPEC_LOAD_DF_HIGH))]
|
||||
"TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && !TARGET_64BIT"
|
||||
(define_insn "load_high<mode>"
|
||||
[(set (match_operand:SPLITF 0 "register_operand" "=f,f")
|
||||
(unspec:SPLITF [(match_operand:<HALFMODE> 1 "general_operand" "dJ,m")
|
||||
(match_operand:SPLITF 2 "register_operand" "0,0")]
|
||||
UNSPEC_LOAD_HIGH))]
|
||||
"TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
|
||||
{
|
||||
operands[0] = mips_subword (operands[0], 1);
|
||||
return mips_output_move (operands[0], operands[1]);
|
||||
}
|
||||
[(set_attr "type" "mtc,fpload")
|
||||
(set_attr "mode" "SF")])
|
||||
[(set_attr "type" "mtc,fpload")
|
||||
(set_attr "mode" "<HALFMODE>")])
|
||||
|
||||
;; Store the high word of operand 1 in operand 0. The corresponding
|
||||
;; low-word move is done in the normal way.
|
||||
(define_insn "store_df_high"
|
||||
[(set (match_operand:SI 0 "nonimmediate_operand" "=d,m")
|
||||
(unspec:SI [(match_operand:DF 1 "register_operand" "f,f")]
|
||||
UNSPEC_STORE_DF_HIGH))]
|
||||
"TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && !TARGET_64BIT"
|
||||
;; Store one word of operand 1 in operand 0. Operand 2 is 1 to store the
|
||||
;; high word and 0 to store the low word.
|
||||
(define_insn "store_word<mode>"
|
||||
[(set (match_operand:<HALFMODE> 0 "nonimmediate_operand" "=d,m")
|
||||
(unspec:<HALFMODE> [(match_operand:SPLITF 1 "register_operand" "f,f")
|
||||
(match_operand 2 "const_int_operand")]
|
||||
UNSPEC_STORE_WORD))]
|
||||
"TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
|
||||
{
|
||||
operands[1] = mips_subword (operands[1], 1);
|
||||
operands[1] = mips_subword (operands[1], INTVAL (operands[2]));
|
||||
return mips_output_move (operands[0], operands[1]);
|
||||
}
|
||||
[(set_attr "type" "mfc,fpstore")
|
||||
(set_attr "mode" "SF")])
|
||||
[(set_attr "type" "mfc,fpstore")
|
||||
(set_attr "mode" "<HALFMODE>")])
|
||||
|
||||
;; Move operand 1 to the high word of operand 0 using mthc1, preserving the
|
||||
;; value in the low word.
|
||||
(define_insn "mthc1"
|
||||
[(set (match_operand:DF 0 "register_operand" "=f")
|
||||
(unspec:DF [(match_operand:SI 1 "general_operand" "dJ")
|
||||
(match_operand:DF 2 "register_operand" "0")]
|
||||
UNSPEC_MTHC1))]
|
||||
"TARGET_HARD_FLOAT && !TARGET_64BIT && ISA_HAS_MXHC1"
|
||||
(define_insn "mthc1<mode>"
|
||||
[(set (match_operand:SPLITF 0 "register_operand" "=f")
|
||||
(unspec:SPLITF [(match_operand:<HALFMODE> 1 "general_operand" "dJ")
|
||||
(match_operand:SPLITF 2 "register_operand" "0")]
|
||||
UNSPEC_MTHC1))]
|
||||
"TARGET_HARD_FLOAT && ISA_HAS_MXHC1"
|
||||
"mthc1\t%z1,%0"
|
||||
[(set_attr "type" "mtc")
|
||||
(set_attr "mode" "SF")])
|
||||
[(set_attr "type" "mtc")
|
||||
(set_attr "mode" "<HALFMODE>")])
|
||||
|
||||
;; Move high word of operand 1 to operand 0 using mfhc1. The corresponding
|
||||
;; low-word move is done in the normal way.
|
||||
(define_insn "mfhc1"
|
||||
[(set (match_operand:SI 0 "register_operand" "=d")
|
||||
(unspec:SI [(match_operand:DF 1 "register_operand" "f")]
|
||||
UNSPEC_MFHC1))]
|
||||
"TARGET_HARD_FLOAT && !TARGET_64BIT && ISA_HAS_MXHC1"
|
||||
;; Move high word of operand 1 to operand 0 using mfhc1.
|
||||
(define_insn "mfhc1<mode>"
|
||||
[(set (match_operand:<HALFMODE> 0 "register_operand" "=d")
|
||||
(unspec:<HALFMODE> [(match_operand:SPLITF 1 "register_operand" "f")]
|
||||
UNSPEC_MFHC1))]
|
||||
"TARGET_HARD_FLOAT && ISA_HAS_MXHC1"
|
||||
"mfhc1\t%0,%1"
|
||||
[(set_attr "type" "mfc")
|
||||
(set_attr "mode" "SF")])
|
||||
[(set_attr "type" "mfc")
|
||||
(set_attr "mode" "<HALFMODE>")])
|
||||
|
||||
;; Move a constant that satisfies CONST_GP_P into operand 0.
|
||||
(define_expand "load_const_gp"
|
||||
|
@ -1,3 +1,19 @@
|
||||
2007-10-03 Richard Sandiford <rsandifo@nildram.co.uk>
|
||||
|
||||
PR target/33635
|
||||
* gcc.target/mips/mips.exp (setup_mips_tests): Set mips_isa_rev
|
||||
and mips_forced_be.
|
||||
(dg-mips-options): Handle -EL and -mel. Make -mfp64 imply
|
||||
-mhard-float and a suitable ISA. Improve handling of -mipsXrY
|
||||
options.
|
||||
* gcc.target/mips/fpr-moves-1.c: New test.
|
||||
* gcc.target/mips/fpr-moves-2.c: Likewise.
|
||||
* gcc.target/mips/fpr-moves-3.c: Likewise.
|
||||
* gcc.target/mips/fpr-moves-4.c: Likewise.
|
||||
* gcc.target/mips/fpr-moves-5.c: Likewise.
|
||||
* gcc.target/mips/fpr-moves-6.c: Likewise.
|
||||
* gcc.target/mips/mips32r2-mxhc1.c: Remove -march=mips32r2
|
||||
|
||||
2007-10-03 Francois-Xavier Coudert <fxcoudert@gcc.gnu.org>
|
||||
|
||||
* gfortran.dg/default_format_1.f90: XFAIL on all darwin targets.
|
||||
|
26
gcc/testsuite/gcc.target/mips/fpr-moves-1.c
Normal file
26
gcc/testsuite/gcc.target/mips/fpr-moves-1.c
Normal file
@ -0,0 +1,26 @@
|
||||
/* { dg-mips-options "-mabi=32 -mhard-float -mips1 -O2 -EL" } */
|
||||
|
||||
NOMIPS16 void
|
||||
foo (double d, double *x)
|
||||
{
|
||||
*x = d;
|
||||
}
|
||||
|
||||
NOMIPS16 double
|
||||
bar (double d)
|
||||
{
|
||||
register double l1 asm ("$8") = d;
|
||||
register double l2 asm ("$f20") = 0.0;
|
||||
asm ("#foo" : "=d" (l1) : "d" (l1));
|
||||
asm volatile ("#foo" :: "f" (l2));
|
||||
return l1;
|
||||
}
|
||||
|
||||
/* { dg-final { scan-assembler "\tswc1\t\\\$f12,0\\\(\\\$6\\\)\n" } } */
|
||||
/* { dg-final { scan-assembler "\tswc1\t\\\$f13,4\\\(\\\$6\\\)\n" } } */
|
||||
/* { dg-final { scan-assembler "\tmfc1\t\\\$8,\\\$f12\n" } } */
|
||||
/* { dg-final { scan-assembler "\tmfc1\t\\\$9,\\\$f13\n" } } */
|
||||
/* { dg-final { scan-assembler "\tmtc1\t\\\$0,\\\$f20\n" } } */
|
||||
/* { dg-final { scan-assembler "\tmtc1\t\\\$0,\\\$f21\n" } } */
|
||||
/* { dg-final { scan-assembler "\tmtc1\t\\\$8,\\\$f0\n" } } */
|
||||
/* { dg-final { scan-assembler "\tmtc1\t\\\$9,\\\$f1\n" } } */
|
26
gcc/testsuite/gcc.target/mips/fpr-moves-2.c
Normal file
26
gcc/testsuite/gcc.target/mips/fpr-moves-2.c
Normal file
@ -0,0 +1,26 @@
|
||||
/* { dg-mips-options "-mabi=32 -mhard-float -mips1 -O2 -EB" } */
|
||||
|
||||
NOMIPS16 void
|
||||
foo (double d, double *x)
|
||||
{
|
||||
*x = d;
|
||||
}
|
||||
|
||||
NOMIPS16 double
|
||||
bar (double d)
|
||||
{
|
||||
register double l1 asm ("$8") = d;
|
||||
register double l2 asm ("$f20") = 0.0;
|
||||
asm ("#foo" : "=d" (l1) : "d" (l1));
|
||||
asm volatile ("#foo" :: "f" (l2));
|
||||
return l1;
|
||||
}
|
||||
|
||||
/* { dg-final { scan-assembler "\tswc1\t\\\$f12,4\\\(\\\$6\\\)\n" } } */
|
||||
/* { dg-final { scan-assembler "\tswc1\t\\\$f13,0\\\(\\\$6\\\)\n" } } */
|
||||
/* { dg-final { scan-assembler "\tmfc1\t\\\$9,\\\$f12\n" } } */
|
||||
/* { dg-final { scan-assembler "\tmfc1\t\\\$8,\\\$f13\n" } } */
|
||||
/* { dg-final { scan-assembler "\tmtc1\t\\\$0,\\\$f20\n" } } */
|
||||
/* { dg-final { scan-assembler "\tmtc1\t\\\$0,\\\$f21\n" } } */
|
||||
/* { dg-final { scan-assembler "\tmtc1\t\\\$9,\\\$f0\n" } } */
|
||||
/* { dg-final { scan-assembler "\tmtc1\t\\\$8,\\\$f1\n" } } */
|
18
gcc/testsuite/gcc.target/mips/fpr-moves-3.c
Normal file
18
gcc/testsuite/gcc.target/mips/fpr-moves-3.c
Normal file
@ -0,0 +1,18 @@
|
||||
/* { dg-mips-options "-mabi=32 -mfp64 -O2 -EL" } */
|
||||
|
||||
NOMIPS16 double
|
||||
foo (double d)
|
||||
{
|
||||
register double l1 asm ("$8") = d;
|
||||
register double l2 asm ("$f20") = 0.0;
|
||||
asm ("#foo" : "=d" (l1) : "d" (l1));
|
||||
asm volatile ("#foo" :: "f" (l2));
|
||||
return l1;
|
||||
}
|
||||
|
||||
/* { dg-final { scan-assembler "\tmfc1\t\\\$8,\\\$f12\n" } } */
|
||||
/* { dg-final { scan-assembler "\tmfhc1\t\\\$9,\\\$f12\n" } } */
|
||||
/* { dg-final { scan-assembler "\tmtc1\t\\\$0,\\\$f20\n" } } */
|
||||
/* { dg-final { scan-assembler "\tmthc1\t\\\$0,\\\$f20\n" } } */
|
||||
/* { dg-final { scan-assembler "\tmtc1\t\\\$8,\\\$f0\n" } } */
|
||||
/* { dg-final { scan-assembler "\tmthc1\t\\\$9,\\\$f0\n" } } */
|
18
gcc/testsuite/gcc.target/mips/fpr-moves-4.c
Normal file
18
gcc/testsuite/gcc.target/mips/fpr-moves-4.c
Normal file
@ -0,0 +1,18 @@
|
||||
/* { dg-mips-options "-mabi=32 -mfp64 -O2 -EB" } */
|
||||
|
||||
NOMIPS16 double
|
||||
foo (double d)
|
||||
{
|
||||
register double l1 asm ("$8") = d;
|
||||
register double l2 asm ("$f20") = 0.0;
|
||||
asm ("#foo" : "=d" (l1) : "d" (l1));
|
||||
asm volatile ("#foo" :: "f" (l2));
|
||||
return l1;
|
||||
}
|
||||
|
||||
/* { dg-final { scan-assembler "\tmfc1\t\\\$9,\\\$f12\n" } } */
|
||||
/* { dg-final { scan-assembler "\tmfhc1\t\\\$8,\\\$f12\n" } } */
|
||||
/* { dg-final { scan-assembler "\tmtc1\t\\\$0,\\\$f20\n" } } */
|
||||
/* { dg-final { scan-assembler "\tmthc1\t\\\$0,\\\$f20\n" } } */
|
||||
/* { dg-final { scan-assembler "\tmtc1\t\\\$9,\\\$f0\n" } } */
|
||||
/* { dg-final { scan-assembler "\tmthc1\t\\\$8,\\\$f0\n" } } */
|
33
gcc/testsuite/gcc.target/mips/fpr-moves-5.c
Normal file
33
gcc/testsuite/gcc.target/mips/fpr-moves-5.c
Normal file
@ -0,0 +1,33 @@
|
||||
/* { dg-mips-options "-mabi=64 -mhard-float -O2 -EL" } */
|
||||
|
||||
NOMIPS16 void
|
||||
foo (long double d, long double *x)
|
||||
{
|
||||
*x = d;
|
||||
}
|
||||
|
||||
NOMIPS16 long double
|
||||
bar (long double d, long double *x)
|
||||
{
|
||||
register long double l1 asm ("$8") = d;
|
||||
register long double l2 asm ("$10") = x[1];
|
||||
register long double l3 asm ("$f20") = 0.0;
|
||||
asm ("#foo" : "=d" (l1) : "d" (l1));
|
||||
asm ("#foo" : "=d" (l2) : "d" (l2));
|
||||
asm volatile ("#foo" :: "f" (l3));
|
||||
x[1] = l1;
|
||||
return l2;
|
||||
}
|
||||
|
||||
/* { dg-final { scan-assembler "\tsdc1\t\\\$f12,0\\\(\\\$6\\\)\n" } } */
|
||||
/* { dg-final { scan-assembler "\tsdc1\t\\\$f13,8\\\(\\\$6\\\)\n" } } */
|
||||
/* { dg-final { scan-assembler "\tdmfc1\t\\\$8,\\\$f12\n" } } */
|
||||
/* { dg-final { scan-assembler "\tdmfc1\t\\\$9,\\\$f13\n" } } */
|
||||
/* { dg-final { scan-assembler "\tld\t\\\$10,16\\\(\\\$6\\\)\n" } } */
|
||||
/* { dg-final { scan-assembler "\tld\t\\\$11,24\\\(\\\$6\\\)\n" } } */
|
||||
/* { dg-final { scan-assembler "\tdmtc1\t\\\$0,\\\$f20\n" } } */
|
||||
/* { dg-final { scan-assembler "\tdmtc1\t\\\$0,\\\$f21\n" } } */
|
||||
/* { dg-final { scan-assembler "\tsd\t\\\$8,16\\\(\\\$6\\\)\n" } } */
|
||||
/* { dg-final { scan-assembler "\tsd\t\\\$9,24\\\(\\\$6\\\)\n" } } */
|
||||
/* { dg-final { scan-assembler "\tdmtc1\t\\\$10,\\\$f0\n" } } */
|
||||
/* { dg-final { scan-assembler "\tdmtc1\t\\\$11,\\\$f2\n" } } */
|
34
gcc/testsuite/gcc.target/mips/fpr-moves-6.c
Normal file
34
gcc/testsuite/gcc.target/mips/fpr-moves-6.c
Normal file
@ -0,0 +1,34 @@
|
||||
/* { dg-mips-options "-mabi=64 -mhard-float -O2 -EB" } */
|
||||
|
||||
NOMIPS16 void
|
||||
foo (long double d, long double *x)
|
||||
{
|
||||
*x = d;
|
||||
}
|
||||
|
||||
NOMIPS16 long double
|
||||
bar (long double d, long double *x)
|
||||
{
|
||||
register long double l1 asm ("$8") = d;
|
||||
register long double l2 asm ("$10") = x[1];
|
||||
register long double l3 asm ("$f20") = 0.0;
|
||||
asm ("#foo" : "=d" (l1) : "d" (l1));
|
||||
asm ("#foo" : "=d" (l2) : "d" (l2));
|
||||
asm volatile ("#foo" :: "f" (l3));
|
||||
x[1] = l1;
|
||||
return l2;
|
||||
}
|
||||
|
||||
/* { dg-final { scan-assembler "\tsdc1\t\\\$f12,0\\\(\\\$6\\\)\n" } } */
|
||||
/* { dg-final { scan-assembler "\tsdc1\t\\\$f13,8\\\(\\\$6\\\)\n" } } */
|
||||
/* { dg-final { scan-assembler "\tdmfc1\t\\\$8,\\\$f12\n" } } */
|
||||
/* { dg-final { scan-assembler "\tdmfc1\t\\\$9,\\\$f13\n" } } */
|
||||
/* { dg-final { scan-assembler "\tld\t\\\$10,16\\\(\\\$6\\\)\n" } } */
|
||||
/* { dg-final { scan-assembler "\tld\t\\\$11,24\\\(\\\$6\\\)\n" } } */
|
||||
/* { dg-final { scan-assembler "\tdmtc1\t\\\$0,\\\$f20\n" } } */
|
||||
/* { dg-final { scan-assembler "\tdmtc1\t\\\$0,\\\$f21\n" } } */
|
||||
/* { dg-final { scan-assembler "\tsd\t\\\$8,16\\\(\\\$6\\\)\n" } } */
|
||||
/* { dg-final { scan-assembler "\tsd\t\\\$9,24\\\(\\\$6\\\)\n" } } */
|
||||
/* We currently move this through a temporary. */
|
||||
/* { dg-final { scan-assembler "\tdmtc1\t\\\$10,\\\$f0\n" { xfail mips*-*-* } } } */
|
||||
/* { dg-final { scan-assembler "\tdmtc1\t\\\$11,\\\$f2\n" } } */
|
@ -29,6 +29,7 @@ load_lib gcc-dg.exp
|
||||
# line (as opposed to being overridable defaults).
|
||||
#
|
||||
# $mips_isa: the ISA level specified by __mips
|
||||
# $mips_isa_rev: the ISA revision specified by __mips_isa_rev
|
||||
# $mips_arch: the architecture specified by _MIPS_ARCH
|
||||
# $mips_gp64: true if 64-bit output is selected
|
||||
# $mips_fp64: true if 64-bit FPRs are selected
|
||||
@ -39,11 +40,13 @@ load_lib gcc-dg.exp
|
||||
# $mips_forced_abi: true if the command line uses -mabi=*
|
||||
# $mips_forced_regs: true if the command line uses -mgp* or -mfp*
|
||||
# $mips_forced_float: true if the command line uses -mhard/soft-float
|
||||
# $mips_forced_be true if the command line uses -EB or -meb
|
||||
# $mips_forced_le true if the command line uses -EL or -mel
|
||||
# $mips_forced_gp true if the command line forces a particular GP mode
|
||||
# $mips_forced_no_er true if the command line contains -mno-explicit-relocs
|
||||
proc setup_mips_tests {} {
|
||||
global mips_isa
|
||||
global mips_isa_rev
|
||||
global mips_arch
|
||||
global mips_gp64
|
||||
global mips_fp64
|
||||
@ -53,6 +56,7 @@ proc setup_mips_tests {} {
|
||||
global mips_forced_isa
|
||||
global mips_forced_abi
|
||||
global mips_forced_float
|
||||
global mips_forced_be
|
||||
global mips_forced_le
|
||||
global mips_forced_gp
|
||||
global mips_forced_no_er
|
||||
@ -65,6 +69,11 @@ proc setup_mips_tests {} {
|
||||
set f [open $src "w"]
|
||||
puts $f {
|
||||
int isa = __mips;
|
||||
#ifdef __mips_isa_rev
|
||||
int isa_rev = __mips_isa_rev;
|
||||
#else
|
||||
int isa_rev = 1;
|
||||
#endif
|
||||
const char *arch = _MIPS_ARCH;
|
||||
#ifdef __mips64
|
||||
int gp64 = 1;
|
||||
@ -94,6 +103,7 @@ proc setup_mips_tests {} {
|
||||
file delete $src
|
||||
|
||||
regexp {isa = ([^;]*)} $output dummy mips_isa
|
||||
regexp {isa_rev = ([^;]*)} $output dummy mips_isa_rev
|
||||
regexp {arch = "([^"]*)} $output dummy mips_arch
|
||||
set mips_gp64 [regexp {gp64 = 1} $output]
|
||||
set mips_fp64 [regexp {fp64 = 1} $output]
|
||||
@ -104,6 +114,7 @@ proc setup_mips_tests {} {
|
||||
set mips_forced_abi [regexp -- {-mabi} $compiler_flags]
|
||||
set mips_forced_regs [regexp -- {(-mgp|-mfp)} $compiler_flags]
|
||||
set mips_forced_float [regexp -- {-m(hard|soft)-float} $compiler_flags]
|
||||
set mips_forced_be [regexp -- {-(EB|meb)[[:>:]]} $compiler_flags]
|
||||
set mips_forced_le [regexp -- {-(EL|mel)[[:>:]]} $compiler_flags]
|
||||
set mips_forced_gp [regexp -- {-(G|m(|no-)((extern|local)-sdata|gpopt)|mabicalls|mrtp)} $compiler_flags]
|
||||
set mips_forced_no_er [regexp -- {-mno-explicit-relocs} $compiler_flags]
|
||||
@ -145,6 +156,12 @@ proc is_gp64_flag {flag} {
|
||||
# if the other flags don't do so. Skip the test if the multilib
|
||||
# flags force a 32-bit ABI or a 32-bit architecture.
|
||||
#
|
||||
# -mfp64
|
||||
# Force the use of 64-bit floating-point registers on a 32-bit target.
|
||||
# Also force -mhard-float and an architecture that supports such a
|
||||
# combination, unless these things are already specified by other
|
||||
# parts of the given flags.
|
||||
#
|
||||
# -mabi=*
|
||||
# Force a particular ABI. Skip the test if the multilib flags
|
||||
# force a specific ABI or a different register size.
|
||||
@ -160,8 +177,9 @@ proc is_gp64_flag {flag} {
|
||||
# multilib flags force a different selection.
|
||||
#
|
||||
# -EB
|
||||
# Select big-endian code. Skip the test if the multilib flags
|
||||
# force a little-endian target.
|
||||
# -EL
|
||||
# Select the given endianness. Skip the test if the multilib flags
|
||||
# force the opposite endianness.
|
||||
#
|
||||
# -G*
|
||||
# -m(no-)extern-sdata
|
||||
@ -179,6 +197,7 @@ proc dg-mips-options {args} {
|
||||
upvar dg-do-what do_what
|
||||
|
||||
global mips_isa
|
||||
global mips_isa_rev
|
||||
global mips_arch
|
||||
global mips_gp64
|
||||
global mips_fp64
|
||||
@ -189,6 +208,7 @@ proc dg-mips-options {args} {
|
||||
global mips_forced_abi
|
||||
global mips_forced_regs
|
||||
global mips_forced_float
|
||||
global mips_forced_be
|
||||
global mips_forced_le
|
||||
global mips_forced_gp
|
||||
global mips_forced_no_er
|
||||
@ -197,6 +217,20 @@ proc dg-mips-options {args} {
|
||||
set matches 1
|
||||
|
||||
# First handle the -mgp* options. Add an architecture option if necessary.
|
||||
foreach flag $flags {
|
||||
if {$flag == "-mfp64"} {
|
||||
if {!$mips_fp64 && $mips_forced_regs} {
|
||||
set matches 0
|
||||
} else {
|
||||
if {[lsearch -regexp $flags {^-m(hard|soft)-float$}] < 0} {
|
||||
append flags " -mhard-float"
|
||||
}
|
||||
if {[lsearch -regexp $flags {^(-mips|-march)}] < 0} {
|
||||
append flags " -mips32r2"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
foreach flag $flags {
|
||||
if {[is_gp32_flag $flag]
|
||||
&& ($mips_gp64
|
||||
@ -221,11 +255,7 @@ proc dg-mips-options {args} {
|
||||
}
|
||||
# Handle the other options.
|
||||
foreach flag $flags {
|
||||
if {$flag == "-mfp64"} {
|
||||
if {$mips_isa < 33 || $mips_float != "hard"} {
|
||||
set matches 0
|
||||
}
|
||||
} elseif {[regexp -- {^-mabi=(.*)} $flag dummy abi]} {
|
||||
if {[regexp -- {^-mabi=(.*)} $flag dummy abi]} {
|
||||
if {$abi != $mips_abi && $mips_forced_abi} {
|
||||
set matches 0
|
||||
}
|
||||
@ -233,8 +263,12 @@ proc dg-mips-options {args} {
|
||||
if {$arch != $mips_arch && $mips_forced_isa} {
|
||||
set matches 0
|
||||
}
|
||||
} elseif {[regexp -- {^-mips(.*)} $flag dummy isa] && $isa != 16} {
|
||||
if {$isa != $mips_isa && $mips_forced_isa} {
|
||||
} elseif {[regexp -- {^-mips(.*)} $flag dummy isa]} {
|
||||
if {![regexp {(.*)r(.*)} $isa dummy isa isa_rev]} {
|
||||
set isa_rev 1
|
||||
}
|
||||
if {($isa != $mips_isa || $isa_rev != $mips_isa_rev)
|
||||
&& $mips_forced_isa} {
|
||||
set matches 0
|
||||
}
|
||||
} elseif {[regexp -- {^-m(hard|soft)-float} $flag dummy float]} {
|
||||
@ -245,6 +279,10 @@ proc dg-mips-options {args} {
|
||||
if {$mips_forced_le} {
|
||||
set matches 0
|
||||
}
|
||||
} elseif {[regexp -- {^-(EL|mel)$} $flag]} {
|
||||
if {$mips_forced_be} {
|
||||
set matches 0
|
||||
}
|
||||
} elseif {[regexp -- {^-(G|m(|no-)((extern|local)-sdata|gpopt))} $flag]} {
|
||||
append flags " -mno-abicalls"
|
||||
if {$mips_forced_gp} {
|
||||
|
@ -1,5 +1,5 @@
|
||||
/* { dg-do compile } */
|
||||
/* { dg-mips-options "-O -march=mips32r2 -mabi=32 -mfp64" } */
|
||||
/* { dg-mips-options "-O -mabi=32 -mfp64" } */
|
||||
/* { dg-final { scan-assembler "mthc1" } } */
|
||||
/* { dg-final { scan-assembler "mfhc1" } } */
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user