aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorRichard Sandiford <rsandifo@nildram.co.uk>2007-10-03 18:39:30 +0000
committerRichard Sandiford <rsandifo@gcc.gnu.org>2007-10-03 18:39:30 +0000
commit0064fbe9b6d395c794fc021d6dc97b40f9d7ac92 (patch)
treefacac44939a51a8591e7804d091bfb66aeb0c6f6 /gcc
parentf5783e34f97cd9012ae3ee4118a5e3bf642d8aed (diff)
downloadgcc-0064fbe9b6d395c794fc021d6dc97b40f9d7ac92.zip
gcc-0064fbe9b6d395c794fc021d6dc97b40f9d7ac92.tar.gz
gcc-0064fbe9b6d395c794fc021d6dc97b40f9d7ac92.tar.bz2
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
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog31
-rw-r--r--gcc/config/mips/mips-protos.h2
-rw-r--r--gcc/config/mips/mips.c90
-rw-r--r--gcc/config/mips/mips.md170
-rw-r--r--gcc/testsuite/ChangeLog16
-rw-r--r--gcc/testsuite/gcc.target/mips/fpr-moves-1.c26
-rw-r--r--gcc/testsuite/gcc.target/mips/fpr-moves-2.c26
-rw-r--r--gcc/testsuite/gcc.target/mips/fpr-moves-3.c18
-rw-r--r--gcc/testsuite/gcc.target/mips/fpr-moves-4.c18
-rw-r--r--gcc/testsuite/gcc.target/mips/fpr-moves-5.c33
-rw-r--r--gcc/testsuite/gcc.target/mips/fpr-moves-6.c34
-rw-r--r--gcc/testsuite/gcc.target/mips/mips.exp56
-rw-r--r--gcc/testsuite/gcc.target/mips/mips32r2-mxhc1.c2
13 files changed, 397 insertions, 125 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 5d7d7a1..45a840f 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -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.
diff --git a/gcc/config/mips/mips-protos.h b/gcc/config/mips/mips-protos.h
index 6237749..371fd93 100644
--- a/gcc/config/mips/mips-protos.h
+++ b/gcc/config/mips/mips-protos.h
@@ -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
diff --git a/gcc/config/mips/mips.c b/gcc/config/mips/mips.c
index 6ac976a..64377b5 100644
--- a/gcc/config/mips/mips.c
+++ b/gcc/config/mips/mips.c
@@ -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))
- {
- /* 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)));
- }
- 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))
+ if (FP_REG_RTX_P (dest) || 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));
- }
+ 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
- {
- 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 (FP_REG_P (regno))
- /* In this case we can use mov.fmt. */
- 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) && 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;
diff --git a/gcc/config/mips/mips.md b/gcc/config/mips/mips.md
index 38800ed..f4b90eb 100644
--- a/gcc/config/mips/mips.md
+++ b/gcc/config/mips/mips.md
@@ -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")])
-
-;; 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"
+ [(set_attr "type" "mtc,fpload")
+ (set_attr "mode" "<HALFMODE>")])
+
+;; 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")])
-
-;; 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"
+ [(set_attr "type" "mtc")
+ (set_attr "mode" "<HALFMODE>")])
+
+;; 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"
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index c6aec50..277c25d 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -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.
diff --git a/gcc/testsuite/gcc.target/mips/fpr-moves-1.c b/gcc/testsuite/gcc.target/mips/fpr-moves-1.c
new file mode 100644
index 0000000..db2190d
--- /dev/null
+++ b/gcc/testsuite/gcc.target/mips/fpr-moves-1.c
@@ -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" } } */
diff --git a/gcc/testsuite/gcc.target/mips/fpr-moves-2.c b/gcc/testsuite/gcc.target/mips/fpr-moves-2.c
new file mode 100644
index 0000000..fe21ee2
--- /dev/null
+++ b/gcc/testsuite/gcc.target/mips/fpr-moves-2.c
@@ -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" } } */
diff --git a/gcc/testsuite/gcc.target/mips/fpr-moves-3.c b/gcc/testsuite/gcc.target/mips/fpr-moves-3.c
new file mode 100644
index 0000000..a32c687
--- /dev/null
+++ b/gcc/testsuite/gcc.target/mips/fpr-moves-3.c
@@ -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" } } */
diff --git a/gcc/testsuite/gcc.target/mips/fpr-moves-4.c b/gcc/testsuite/gcc.target/mips/fpr-moves-4.c
new file mode 100644
index 0000000..4f26f06
--- /dev/null
+++ b/gcc/testsuite/gcc.target/mips/fpr-moves-4.c
@@ -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" } } */
diff --git a/gcc/testsuite/gcc.target/mips/fpr-moves-5.c b/gcc/testsuite/gcc.target/mips/fpr-moves-5.c
new file mode 100644
index 0000000..7159d38
--- /dev/null
+++ b/gcc/testsuite/gcc.target/mips/fpr-moves-5.c
@@ -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" } } */
diff --git a/gcc/testsuite/gcc.target/mips/fpr-moves-6.c b/gcc/testsuite/gcc.target/mips/fpr-moves-6.c
new file mode 100644
index 0000000..048987a
--- /dev/null
+++ b/gcc/testsuite/gcc.target/mips/fpr-moves-6.c
@@ -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" } } */
diff --git a/gcc/testsuite/gcc.target/mips/mips.exp b/gcc/testsuite/gcc.target/mips/mips.exp
index 7e2b781..68c67d3 100644
--- a/gcc/testsuite/gcc.target/mips/mips.exp
+++ b/gcc/testsuite/gcc.target/mips/mips.exp
@@ -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
@@ -198,6 +218,20 @@ proc dg-mips-options {args} {
# 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
|| ($mips_fp64 && [lsearch $flags -mfp64] < 0)) } {
@@ -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} {
diff --git a/gcc/testsuite/gcc.target/mips/mips32r2-mxhc1.c b/gcc/testsuite/gcc.target/mips/mips32r2-mxhc1.c
index 7a3b12d..9257612 100644
--- a/gcc/testsuite/gcc.target/mips/mips32r2-mxhc1.c
+++ b/gcc/testsuite/gcc.target/mips/mips32r2-mxhc1.c
@@ -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" } } */