This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[MIPS 22/30] Paired-single support for MIPS32R2


[I decided to drop what was patch 21.]

The original motivation for this patch was simply to introduce
an ISA_HAS_PAIRED_SINGLE macro.  However, I thought I might as
well extend the paired-single support to cover MIPS32R2 while
I was there, especially once I discovered that one of the changes
also fixed an XFAIL.

The changes were simple:

  - Add a !TARGET_64BIT movv2sf pattern.

  - Extend the mips_split_doubleword_move support to handle V2SF.

  - Make ISA_HAS_NMADD_NMSUB take a MODE argument and allow V2SF
    instructions for ISA_MIPS32R2.

However, I found that lower-subreg was lowering V2SF moves into
word_mode moves, which wasn't what we wanted at all.  That in turn
was caused by a bogus MODES_TIEABLE_P:

#define MODES_TIEABLE_P(MODE1, MODE2)					\
  ((GET_MODE_CLASS (MODE1) == MODE_FLOAT ||				\
    GET_MODE_CLASS (MODE1) == MODE_COMPLEX_FLOAT)			\
   == (GET_MODE_CLASS (MODE2) == MODE_FLOAT ||				\
       GET_MODE_CLASS (MODE2) == MODE_COMPLEX_FLOAT))

The immediate cause of the problem is a lack of MODE_VECTOR_FLOAT.
However, what we really want here is to forbid ties between different
modes if one of those modes is something we want to store in an FPR,
which is equivalent to "can we move values of this mode between FPRs?".
I've changed the definition accordingly.  We now allow TFmode values to
be tied to all modes, which allows lower-subreg to optimise them,
and which fixes the extra move that led to the fpr-moves-6.c XFAIL.

The mips.exp paired-single execution tests required mipsisa64*
and forced -mips64 -mgp64 -mhard-float on the command line.
I changed them to require mpaired_single instead and removed
the listed options.  I also added -mips32r2 versions of the
-mips64 compile-only tests and made mips.exp cope better with
cases where a -mgp32/-mfp64 multilib is being tested.
With these changes, the paired-single execution tests run
and pass on mipsisa32r2/-mfp64 targets as well.

Various vectorisation tests only tried to vectorise for
mipsisa64*-*-*.  I've changed them to mips*-*-* instead;
mpaired_single does the real work anyway.  The vectorisation
tests then run and pass on mipsisa32r2/-mfp64 targets as well.

Finally, we didn't allow -mpaired-single to be used with an ISA
that we don't think supports the instructions.  I changed this
from an error to warning, for consistency with the -mbranch-likely
case.

Tested on mipsisa32r2-elfoabi and applied.

Richard


gcc/
	* doc/invoke.texi (-mpaired-single): Don't say that the option
	requires 64-bit code.
	* config/mips/mips-protos.h (mips_modes_tieable_p): Declare.
	* config/mips/mips.h (ISA_HAS_PAIRED_SINGLE): New macro.
	(ISA_HAS_NMADD_NMSUB): Add a mode argument.  Return true for
	V2SF if ISA_MIPS32R2.
	(MODES_TIEABLE_P): Use mips_modes_tieable_p.
	* config/mips/mips.c (mips_rtx_costs): Pass a mode argument
	to ISA_HAS_NMADD_NMSUB.
	(mips_split_doubleword_move): Handle V2SF.
	(mips_modes_tieable_p): New function.
	(override_options): Report a warning rather than an error when
	-mpaired-single is used on ISAs that don't support it; use
	ISA_HAS_PAIRED_SINGLE to check that case.
	* config/mips/mips.md (MOVE64): New mode iterator.  Replace DI
	and DF move splitters with a single MOVE64 splitter, thereby adding
	a V2SF splitter too.
	(SPLITF): Add TARGET_DOUBLE_FLOAT conditions to DI and DF.
	Add a TARGET_FLOAT64 condition to TF.  Add V2SF to the iterator.
	(HALFMODE): Add V2SF.
	(*nmadd<mode>, *nmadd<mode>_fastmath, *nmsub<mode>)
	(*nmsub<mode>_fastmath): Add a mode argument to ISA_HAS_NMADD_NMSUB.
	(movv2sf_hardfloat_64bit): Tweak ordering of conditions.
	(movv2sf_hardfloat_32bit): New pattern.
	(load_low<mode>, load_high<mode>, store_word<mode>): Remove
	TARGET_DOUBLE_FLOAT conditions.

gcc/testsuite/
	* gcc.dg/vect/vect.exp: Extend -mpaired-single handling to all
	MIPS targets.
	* g++.dg/vect/vect.exp: Likewise.
	* lib/fortran-torture.exp: Likewise.
	* gcc.target/mips/mips-ps-1.c: Use mpaired_single rather than
	mipsisa64*-*-* as the target selector.  Remove -mips64,
	-mhard-float and -mgp64 from the options list.
	* gcc.target/mips/mips-ps-2.c: Likewise.
	* gcc.target/mips/mips-ps-3.c: Likewise.
	* gcc.target/mips/mips-ps-4.c: Likewise.
	* gcc.target/mips/mips-ps-6.c: Likewise.
	* gcc.target/mips/mips-ps-5.c: Remove -mhard-float from the
	options list.
	* gcc.target/mips/sb1-1.c: Likewise.
	* gcc.target/mips/mips-ps-type.c: Likewise.
	* gcc.target/mips/mips-ps-7.c: New test.
	* gcc.target/mips/mips-ps-type-2.c: Likewise.
	* gcc.target/mips/fpr-moves-6.c: Remove XFAIL.
	* gcc.target/mips/mips.exp (setup_mips_tests): Set mips_fp and
	mips_gp instead of mips_fp64 and mips_gp64.  Treat -mgp32 -mfp64
	as forcing an ABI and an architecture.
	(is_gp32_flag, is_gp64_flag): Fold into...
	(dg-mips-options): ...here.  Make -mpaired-single imply -mfp64,
	then -mfp64 imply -mhard-float.  Apply register rules after the
	loop.  Handle -march=mipsN like -mipsN.

Index: gcc/doc/invoke.texi
===================================================================
--- gcc/doc/invoke.texi	2007-10-20 11:04:47.000000000 +0100
+++ gcc/doc/invoke.texi	2007-10-20 11:05:57.000000000 +0100
@@ -11877,9 +11877,8 @@ Use (do not use) the MIPS SmartMIPS ASE.
 @opindex mpaired-single
 @opindex mno-paired-single
 Use (do not use) paired-single floating-point instructions.
-@xref{MIPS Paired-Single Support}.  This option can only be used
-when generating 64-bit code and requires hardware floating-point
-support to be enabled.
+@xref{MIPS Paired-Single Support}.  This option requires
+hardware floating-point support to be enabled.
 
 @item -mdmx
 @itemx -mno-mdmx
Index: gcc/config/mips/mips-protos.h
===================================================================
--- gcc/config/mips/mips-protos.h	2007-10-20 15:05:13.000000000 +0100
+++ gcc/config/mips/mips-protos.h	2007-10-20 15:06:28.000000000 +0100
@@ -267,6 +267,7 @@ extern struct rtx_def *mips_function_val
 extern bool mips_cannot_change_mode_class (enum machine_mode,
 					   enum machine_mode, enum reg_class);
 extern bool mips_dangerous_for_la25_p (rtx);
+extern bool mips_modes_tieable_p (enum machine_mode, enum machine_mode);
 extern enum reg_class mips_preferred_reload_class (rtx, enum reg_class);
 extern enum reg_class mips_secondary_reload_class (enum reg_class,
 						   enum machine_mode,
Index: gcc/config/mips/mips.h
===================================================================
--- gcc/config/mips/mips.h	2007-10-20 10:22:08.000000000 +0100
+++ gcc/config/mips/mips.h	2007-10-20 15:30:49.000000000 +0100
@@ -750,6 +750,9 @@ #define ISA_HAS_FP4		((ISA_MIPS4				\
 				  || ISA_MIPS64)			\
 				 && !TARGET_MIPS16)
 
+/* ISA has paired-single instructions.  */
+#define ISA_HAS_PAIRED_SINGLE	(ISA_MIPS32R2 || ISA_MIPS64)
+
 /* ISA has conditional trap instructions.  */
 #define ISA_HAS_COND_TRAP	(!ISA_MIPS1				\
 				 && !TARGET_MIPS16)
@@ -763,8 +766,10 @@ #define ISA_HAS_MADD_MSUB	((ISA_MIPS32		
 /* Integer multiply-accumulate instructions should be generated.  */
 #define GENERATE_MADD_MSUB      (ISA_HAS_MADD_MSUB && !TUNE_74K)
 
-/* ISA has floating-point nmadd and nmsub instructions.  */
-#define ISA_HAS_NMADD_NMSUB	((ISA_MIPS4				\
+/* ISA has floating-point nmadd and nmsub instructions for mode MODE.  */
+#define ISA_HAS_NMADD_NMSUB(MODE) \
+				((ISA_MIPS4				\
+				  || (ISA_MIPS32R2 && (MODE) == V2SFmode) \
 				  || ISA_MIPS64)			\
 				 && (!TARGET_MIPS5400 || TARGET_MAD)	\
 				 && !TARGET_MIPS16)
@@ -1562,15 +1567,7 @@ #define HARD_REGNO_NREGS(REGNO, MODE) mi
 #define HARD_REGNO_MODE_OK(REGNO, MODE)					\
   mips_hard_regno_mode_ok[ (int)(MODE) ][ (REGNO) ]
 
-/* Value is 1 if it is a good idea to tie two pseudo registers
-   when one has mode MODE1 and one has mode MODE2.
-   If HARD_REGNO_MODE_OK could produce different values for MODE1 and MODE2,
-   for any hard reg, then this must be 0 for correct output.  */
-#define MODES_TIEABLE_P(MODE1, MODE2)					\
-  ((GET_MODE_CLASS (MODE1) == MODE_FLOAT ||				\
-    GET_MODE_CLASS (MODE1) == MODE_COMPLEX_FLOAT)			\
-   == (GET_MODE_CLASS (MODE2) == MODE_FLOAT ||				\
-       GET_MODE_CLASS (MODE2) == MODE_COMPLEX_FLOAT))
+#define MODES_TIEABLE_P mips_modes_tieable_p
 
 /* Register to use for pushing function arguments.  */
 #define STACK_POINTER_REGNUM (GP_REG_FIRST + 29)
Index: gcc/config/mips/mips.c
===================================================================
--- gcc/config/mips/mips.c	2007-10-20 10:22:08.000000000 +0100
+++ gcc/config/mips/mips.c	2007-10-20 15:33:10.000000000 +0100
@@ -3212,7 +3212,7 @@ mips_rtx_costs (rtx x, int code, int out
 
     case MINUS:
       if (float_mode_p
-	  && ISA_HAS_NMADD_NMSUB
+	  && ISA_HAS_NMADD_NMSUB (mode)
 	  && TARGET_FUSED_MADD
 	  && !HONOR_NANS (mode)
 	  && !HONOR_SIGNED_ZEROS (mode))
@@ -3261,7 +3261,7 @@ mips_rtx_costs (rtx x, int code, int out
 
     case NEG:
       if (float_mode_p
-	  && ISA_HAS_NMADD_NMSUB
+	  && ISA_HAS_NMADD_NMSUB (mode)
 	  && TARGET_FUSED_MADD
 	  && !HONOR_NANS (mode)
 	  && HONOR_SIGNED_ZEROS (mode))
@@ -3459,6 +3459,8 @@ mips_split_doubleword_move (rtx dest, rt
 	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) == V2SFmode)
+	emit_insn (gen_move_doubleword_fprv2sf (dest, src));
       else if (TARGET_64BIT && GET_MODE (dest) == TFmode)
 	emit_insn (gen_move_doubleword_fprtf (dest, src));
       else
@@ -8897,6 +8899,18 @@ mips_mode_ok_for_mov_fmt_p (enum machine
     }
 }
 
+/* Implement MODES_TIEABLE_P.  */
+
+bool
+mips_modes_tieable_p (enum machine_mode mode1, enum machine_mode mode2)
+{
+  /* FPRs allow no mode punning, so it's not worth tying modes if we'd
+     prefer to put one of them in FPRs.  */
+  return (mode1 == mode2
+	  || (!mips_mode_ok_for_mov_fmt_p (mode1)
+	      && !mips_mode_ok_for_mov_fmt_p (mode2)));
+}
+
 /* Implement PREFERRED_RELOAD_CLASS.  */
 
 enum reg_class
@@ -12106,8 +12120,9 @@ override_options (void)
 
   /* Make sure that the ISA supports TARGET_PAIRED_SINGLE_FLOAT when it is
      enabled.  */
-  if (TARGET_PAIRED_SINGLE_FLOAT && !ISA_MIPS64)
-    error ("-mips3d/-mpaired-single must be used with -mips64");
+  if (TARGET_PAIRED_SINGLE_FLOAT && !ISA_HAS_PAIRED_SINGLE)
+    warning (0, "the %qs architecture does not support paired-single"
+	     " instructions", mips_arch_info->name);
 
   /* If TARGET_DSPR2, enable MASK_DSP.  */
   if (TARGET_DSPR2)
Index: gcc/config/mips/mips.md
===================================================================
--- gcc/config/mips/mips.md	2007-10-20 10:34:12.000000000 +0100
+++ gcc/config/mips/mips.md	2007-10-20 15:33:57.000000000 +0100
@@ -492,6 +492,10 @@ (define_mode_iterator P [(SI "Pmode == S
 ;; conditional-move-type condition is needed.
 (define_mode_iterator MOVECC [SI (DI "TARGET_64BIT") (CC "TARGET_HARD_FLOAT")])
 
+;; 64-bit modes for which we provide move patterns.
+(define_mode_iterator MOVE64
+  [DI DF (V2SF "TARGET_HARD_FLOAT && TARGET_PAIRED_SINGLE_FLOAT")])
+
 ;; This mode iterator allows the QI and HI extension patterns to be
 ;; defined from the same template.
 (define_mode_iterator SHORT [QI HI])
@@ -510,9 +514,11 @@ (define_mode_iterator SCALARF [(SF "TARG
 			       (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")])
+(define_mode_iterator SPLITF
+  [(DF "!TARGET_64BIT && TARGET_DOUBLE_FLOAT")
+   (DI "!TARGET_64BIT && TARGET_DOUBLE_FLOAT")
+   (V2SF "!TARGET_64BIT && TARGET_PAIRED_SINGLE_FLOAT")
+   (TF "TARGET_64BIT && TARGET_FLOAT64")])
 
 ;; In GPR templates, a string like "<d>subu" will expand to "subu" in the
 ;; 32-bit version and "dsubu" in the 64-bit version.
@@ -564,7 +570,7 @@ (define_mode_attr IMODE [(QQ "QI") (HQ "
 
 ;; 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")])
+(define_mode_attr HALFMODE [(DF "SI") (DI "SI") (V2SF "SI") (TF "DI")])
 
 ;; This attribute works around the early SB-1 rev2 core "F2" erratum:
 ;;
@@ -1861,7 +1867,8 @@ (define_insn "*nmadd<mode>"
 		   (mult:ANYF (match_operand:ANYF 1 "register_operand" "f")
 			      (match_operand:ANYF 2 "register_operand" "f"))
 		   (match_operand:ANYF 3 "register_operand" "f"))))]
-  "ISA_HAS_NMADD_NMSUB && TARGET_FUSED_MADD
+  "ISA_HAS_NMADD_NMSUB (<MODE>mode)
+   && TARGET_FUSED_MADD
    && HONOR_SIGNED_ZEROS (<MODE>mode)
    && !HONOR_NANS (<MODE>mode)"
   "nmadd.<fmt>\t%0,%3,%1,%2"
@@ -1874,7 +1881,8 @@ (define_insn "*nmadd<mode>_fastmath"
 	 (mult:ANYF (neg:ANYF (match_operand:ANYF 1 "register_operand" "f"))
 		    (match_operand:ANYF 2 "register_operand" "f"))
 	 (match_operand:ANYF 3 "register_operand" "f")))]
-  "ISA_HAS_NMADD_NMSUB && TARGET_FUSED_MADD
+  "ISA_HAS_NMADD_NMSUB (<MODE>mode)
+   && TARGET_FUSED_MADD
    && !HONOR_SIGNED_ZEROS (<MODE>mode)
    && !HONOR_NANS (<MODE>mode)"
   "nmadd.<fmt>\t%0,%3,%1,%2"
@@ -1887,7 +1895,8 @@ (define_insn "*nmsub<mode>"
 		   (mult:ANYF (match_operand:ANYF 2 "register_operand" "f")
 			      (match_operand:ANYF 3 "register_operand" "f"))
 		   (match_operand:ANYF 1 "register_operand" "f"))))]
-  "ISA_HAS_NMADD_NMSUB && TARGET_FUSED_MADD
+  "ISA_HAS_NMADD_NMSUB (<MODE>mode)
+   && TARGET_FUSED_MADD
    && HONOR_SIGNED_ZEROS (<MODE>mode)
    && !HONOR_NANS (<MODE>mode)"
   "nmsub.<fmt>\t%0,%1,%2,%3"
@@ -1900,7 +1909,8 @@ (define_insn "*nmsub<mode>_fastmath"
 	 (match_operand:ANYF 1 "register_operand" "f")
 	 (mult:ANYF (match_operand:ANYF 2 "register_operand" "f")
 		    (match_operand:ANYF 3 "register_operand" "f"))))]
-  "ISA_HAS_NMADD_NMSUB && TARGET_FUSED_MADD
+  "ISA_HAS_NMADD_NMSUB (<MODE>mode)
+   && TARGET_FUSED_MADD
    && !HONOR_SIGNED_ZEROS (<MODE>mode)
    && !HONOR_NANS (<MODE>mode)"
   "nmsub.<fmt>\t%0,%1,%2,%3"
@@ -4046,19 +4056,8 @@ (define_insn_and_split "*movtf_internal"
    (set_attr "length" "16")])
 
 (define_split
-  [(set (match_operand:DI 0 "nonimmediate_operand")
-	(match_operand:DI 1 "move_operand"))]
-  "reload_completed && !TARGET_64BIT
-   && mips_split_64bit_move_p (operands[0], operands[1])"
-  [(const_int 0)]
-{
-  mips_split_doubleword_move (operands[0], operands[1]);
-  DONE;
-})
-
-(define_split
-  [(set (match_operand:DF 0 "nonimmediate_operand")
-	(match_operand:DF 1 "move_operand"))]
+  [(set (match_operand:MOVE64 0 "nonimmediate_operand")
+	(match_operand:MOVE64 1 "move_operand"))]
   "reload_completed && !TARGET_64BIT
    && mips_split_64bit_move_p (operands[0], operands[1])"
   [(const_int 0)]
@@ -4097,8 +4096,8 @@ (define_insn "movv2sf_hardfloat_64bit"
   [(set (match_operand:V2SF 0 "nonimmediate_operand" "=f,f,f,m,m,*f,*d,*d,*d,*m")
 	(match_operand:V2SF 1 "move_operand" "f,YG,m,f,YG,*d,*f,*d*YG,*m,*d"))]
   "TARGET_HARD_FLOAT
-   && TARGET_64BIT
    && TARGET_PAIRED_SINGLE_FLOAT
+   && TARGET_64BIT
    && (register_operand (operands[0], V2SFmode)
        || reg_or_0_operand (operands[1], V2SFmode))"
   { return mips_output_move (operands[0], operands[1]); }
@@ -4106,6 +4105,19 @@ (define_insn "movv2sf_hardfloat_64bit"
    (set_attr "mode" "SF")
    (set_attr "length" "4,4,*,*,*,4,4,4,*,*")])
 
+(define_insn "movv2sf_hardfloat_32bit"
+  [(set (match_operand:V2SF 0 "nonimmediate_operand" "=f,f,f,m,m,*f,*d,*d,*d,*m")
+	(match_operand:V2SF 1 "move_operand" "f,YG,m,f,YG,*d,*f,*d*YG,*m,*d"))]
+  "TARGET_HARD_FLOAT
+   && TARGET_PAIRED_SINGLE_FLOAT
+   && !TARGET_64BIT
+   && (register_operand (operands[0], V2SFmode)
+       || reg_or_0_operand (operands[1], V2SFmode))"
+  { return mips_output_move (operands[0], operands[1]); }
+  [(set_attr "type" "fmove,mtc,fpload,fpstore,store,mtc,mfc,move,load,store")
+   (set_attr "mode" "SF")
+   (set_attr "length" "4,8,*,*,*,8,8,8,*,*")])
+
 ;; The HI and LO registers are not truly independent.  If we move an mthi
 ;; instruction before an mflo instruction, it will make the result of the
 ;; mflo unpredictable.  The same goes for mtlo and mfhi.
@@ -4185,7 +4197,7 @@ (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"
+  "TARGET_HARD_FLOAT"
 {
   operands[0] = mips_subword (operands[0], 0);
   return mips_output_move (operands[0], operands[1]);
@@ -4200,7 +4212,7 @@ (define_insn "load_high<mode>"
 	(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"
+  "TARGET_HARD_FLOAT"
 {
   operands[0] = mips_subword (operands[0], 1);
   return mips_output_move (operands[0], operands[1]);
@@ -4215,7 +4227,7 @@ (define_insn "store_word<mode>"
 	(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"
+  "TARGET_HARD_FLOAT"
 {
   operands[1] = mips_subword (operands[1], INTVAL (operands[2]));
   return mips_output_move (operands[0], operands[1]);
Index: gcc/testsuite/gcc.dg/vect/vect.exp
===================================================================
--- gcc/testsuite/gcc.dg/vect/vect.exp	2007-10-20 11:07:11.000000000 +0100
+++ gcc/testsuite/gcc.dg/vect/vect.exp	2007-10-20 11:07:21.000000000 +0100
@@ -57,7 +57,7 @@ if [istarget "powerpc*-*-*"] {
 } elseif { [istarget "i?86-*-*"] || [istarget "x86_64-*-*"] } {
     lappend DEFAULT_VECTCFLAGS "-msse2"
     set dg-do-what-default run
-} elseif { [istarget "mipsisa64*-*-*"]
+} elseif { [istarget "mips*-*-*"]
 	   && [check_effective_target_mpaired_single]
 	   && [check_effective_target_nomips16] } {
     lappend DEFAULT_VECTCFLAGS "-mpaired-single"
Index: gcc/testsuite/g++.dg/vect/vect.exp
===================================================================
--- gcc/testsuite/g++.dg/vect/vect.exp	2007-10-20 11:07:48.000000000 +0100
+++ gcc/testsuite/g++.dg/vect/vect.exp	2007-10-20 11:07:56.000000000 +0100
@@ -66,7 +66,7 @@ if [istarget "powerpc*-*-*"] {
 } elseif { [istarget "i?86-*-*"] || [istarget "x86_64-*-*"] } {
     lappend DEFAULT_VECTCFLAGS "-msse2"
     set dg-do-what-default run
-} elseif { [istarget "mipsisa64*-*-*"]
+} elseif { [istarget "mips*-*-*"]
 	   && [check_effective_target_mpaired_single]
 	   && [check_effective_target_nomips16] } {
     lappend DEFAULT_VECTCFLAGS "-mpaired-single"
Index: gcc/testsuite/lib/fortran-torture.exp
===================================================================
--- gcc/testsuite/lib/fortran-torture.exp	2007-10-20 11:08:18.000000000 +0100
+++ gcc/testsuite/lib/fortran-torture.exp	2007-10-20 11:08:27.000000000 +0100
@@ -41,7 +41,7 @@ if ![info exists TORTURE_OPTIONS] {
     } elseif { [istarget "i?86-*-*"] || [istarget "x86_64-*-*"] } {
 	lappend vectorizer_options "-msse2"
 	set test_tree_vectorize 1
-    } elseif { [istarget "mipsisa64*-*-*"]
+    } elseif { [istarget "mips*-*-*"]
 	       && [check_effective_target_mpaired_single]
 	       && [check_effective_target_nomips16] } {
 	lappend vectorizer_options "-mpaired-single"
Index: gcc/testsuite/gcc.target/mips/mips-ps-1.c
===================================================================
--- gcc/testsuite/gcc.target/mips/mips-ps-1.c	2007-10-20 10:22:51.000000000 +0100
+++ gcc/testsuite/gcc.target/mips/mips-ps-1.c	2007-10-20 10:54:30.000000000 +0100
@@ -1,5 +1,5 @@
-/* { dg-do run { target mipsisa64*-*-* } } */
-/* { dg-mips-options "-mips64 -O2 -mpaired-single -mhard-float -mgp64" } */
+/* { dg-do run { target mpaired_single } } */
+/* { dg-mips-options "-O2 -mpaired-single" } */
 
 /* Test v2sf calculations */
 #include <stdlib.h>
Index: gcc/testsuite/gcc.target/mips/mips-ps-2.c
===================================================================
--- gcc/testsuite/gcc.target/mips/mips-ps-2.c	2007-10-20 10:23:56.000000000 +0100
+++ gcc/testsuite/gcc.target/mips/mips-ps-2.c	2007-10-20 10:54:39.000000000 +0100
@@ -1,5 +1,5 @@
-/* { dg-do run { target mipsisa64*-*-* } } */
-/* { dg-mips-options "-mips64 -O2 -mpaired-single -mhard-float -mgp64" } */
+/* { dg-do run { target mpaired_single } } */
+/* { dg-mips-options "-O2 -mpaired-single" } */
 
 /* Test MIPS paired-single builtin functions */
 #include <stdlib.h>
Index: gcc/testsuite/gcc.target/mips/mips-ps-3.c
===================================================================
--- gcc/testsuite/gcc.target/mips/mips-ps-3.c	2007-10-20 10:24:15.000000000 +0100
+++ gcc/testsuite/gcc.target/mips/mips-ps-3.c	2007-10-20 10:54:44.000000000 +0100
@@ -1,5 +1,5 @@
-/* { dg-do run { target mipsisa64*-*-* } } */
-/* { dg-mips-options "-mips64 -O2 -mpaired-single -mhard-float -mgp64" } */
+/* { dg-do run { target mpaired_single } } */
+/* { dg-mips-options "-O2 -mpaired-single" } */
 
 /* Test MIPS paired-single conditional move */
 #include <stdlib.h>
Index: gcc/testsuite/gcc.target/mips/mips-ps-4.c
===================================================================
--- gcc/testsuite/gcc.target/mips/mips-ps-4.c	2007-10-20 10:24:31.000000000 +0100
+++ gcc/testsuite/gcc.target/mips/mips-ps-4.c	2007-10-20 10:54:50.000000000 +0100
@@ -1,5 +1,5 @@
-/* { dg-do run { target mipsisa64*-*-* } } */
-/* { dg-mips-options "-mips64 -O2 -mpaired-single -mhard-float -mgp64" } */
+/* { dg-do run { target mpaired_single } } */
+/* { dg-mips-options "-O2 -mpaired-single" } */
 
 /* Test MIPS paired-single comparisons */
 #include <stdlib.h>
Index: gcc/testsuite/gcc.target/mips/mips-ps-6.c
===================================================================
--- gcc/testsuite/gcc.target/mips/mips-ps-6.c	2007-10-20 10:26:07.000000000 +0100
+++ gcc/testsuite/gcc.target/mips/mips-ps-6.c	2007-10-20 10:54:59.000000000 +0100
@@ -1,7 +1,7 @@
 /* mips-ps-2.c with an extra -ffinite-math-only option.  This option
    changes the way that abs.ps is handled.  */
-/* { dg-do run { target mipsisa64*-*-* } } */
-/* { dg-mips-options "-mips64 -O2 -mpaired-single -mhard-float -mgp64 -ffinite-math-only" } */
+/* { dg-do run { target mpaired_single } } */
+/* { dg-mips-options "-O2 -mpaired-single -ffinite-math-only" } */
 
 /* Test MIPS paired-single builtin functions */
 #include <stdlib.h>
Index: gcc/testsuite/gcc.target/mips/mips-ps-5.c
===================================================================
--- gcc/testsuite/gcc.target/mips/mips-ps-5.c	2007-10-20 10:25:00.000000000 +0100
+++ gcc/testsuite/gcc.target/mips/mips-ps-5.c	2007-10-20 11:43:05.000000000 +0100
@@ -1,5 +1,5 @@
 /* { dg-do compile } */
-/* { dg-mips-options "-mips64 -O2 -mpaired-single -mhard-float -mgp64 -ftree-vectorize" } */
+/* { dg-mips-options "-mips64 -O2 -mpaired-single -mgp64 -ftree-vectorize" } */
 
 extern float a[], b[], c[];
 
Index: gcc/testsuite/gcc.target/mips/sb1-1.c
===================================================================
--- gcc/testsuite/gcc.target/mips/sb1-1.c	2007-10-20 11:09:03.000000000 +0100
+++ gcc/testsuite/gcc.target/mips/sb1-1.c	2007-10-20 11:45:09.000000000 +0100
@@ -1,6 +1,6 @@
 /* Test SB-1 v2sf extensions.  */
 /* { dg-do compile } */ 
-/* { dg-mips-options "-march=sb1 -O2 -mpaired-single -mhard-float -mgp64 -ffast-math" } */ 
+/* { dg-mips-options "-march=sb1 -O2 -mpaired-single -mgp64 -ffast-math" } */
 /* { dg-final { scan-assembler "div.ps" } } */ 
 /* { dg-final { scan-assembler "recip.ps" } } */ 
 /* { dg-final { scan-assembler "sqrt.ps" } } */ 
Index: gcc/testsuite/gcc.target/mips/mips-ps-type.c
===================================================================
--- gcc/testsuite/gcc.target/mips/mips-ps-type.c	2007-10-20 14:32:55.000000000 +0100
+++ gcc/testsuite/gcc.target/mips/mips-ps-type.c	2007-10-20 14:37:42.000000000 +0100
@@ -1,7 +1,7 @@
 /* Test v2sf calculations.  The nmadd and nmsub patterns need
    -ffinite-math-only.  */
 /* { dg-do compile } */ 
-/* { dg-mips-options "-mips64 -O2 -mpaired-single -mhard-float -mgp64 -ffinite-math-only" } */
+/* { dg-mips-options "-mips64 -O2 -mpaired-single -mgp64 -ffinite-math-only" } */
 /* { dg-final { scan-assembler "cvt.ps.s" } } */ 
 /* { dg-final { scan-assembler "mov.ps" } } */ 
 /* { dg-final { scan-assembler "ldc1" } } */ 
Index: gcc/testsuite/gcc.target/mips/mips-ps-7.c
===================================================================
--- /dev/null	2007-10-17 09:55:09.552097000 +0100
+++ gcc/testsuite/gcc.target/mips/mips-ps-7.c	2007-10-20 10:47:45.000000000 +0100
@@ -0,0 +1,17 @@
+/* mips-ps-5.c with -mips32r2 instead of -mips64.  */
+/* { dg-do compile } */
+/* { dg-mips-options "-mips32r2 -O2 -mpaired-single -ftree-vectorize" } */
+
+extern float a[], b[], c[];
+
+NOMIPS16 void
+foo (void)
+{
+  int i;
+  for (i = 0; i < 16; i++)
+    a[i] = b[i] == c[i] + 1 ? b[i] : c[i];
+}
+
+/* { dg-final { scan-assembler "add\\.ps" } } */
+/* { dg-final { scan-assembler "c\\.eq\\.ps" } } */
+/* { dg-final { scan-assembler "mov\[tf\]\\.ps" } } */
Index: gcc/testsuite/gcc.target/mips/mips-ps-type-2.c
===================================================================
--- /dev/null	2007-10-17 09:55:09.552097000 +0100
+++ gcc/testsuite/gcc.target/mips/mips-ps-type-2.c	2007-10-20 15:30:02.000000000 +0100
@@ -0,0 +1,111 @@
+/* Test v2sf calculations.  The nmadd and nmsub patterns need
+   -ffinite-math-only.  */
+/* { dg-do compile } */
+/* { dg-mips-options "-mips32r2 -O2 -mpaired-single -ffinite-math-only" } */
+/* { dg-final { scan-assembler "cvt.ps.s" } } */
+/* { dg-final { scan-assembler "mov.ps" } } */
+/* { dg-final { scan-assembler "ldc1" } } */
+/* { dg-final { scan-assembler "sdc1" } } */
+/* { dg-final { scan-assembler "add.ps" } } */
+/* { dg-final { scan-assembler "sub.ps" } } */
+/* { dg-final { scan-assembler "neg.ps" } } */
+/* { dg-final { scan-assembler "mul.ps" } } */
+/* { dg-final { scan-assembler "madd.ps" } } */
+/* { dg-final { scan-assembler "msub.ps" } } */
+/* { dg-final { scan-assembler "nmadd.ps" } } */
+/* { dg-final { scan-assembler "nmsub.ps" } } */
+/* { dg-final { scan-assembler "movn.ps" } } */
+/* { dg-final { scan-assembler "movz.ps" } } */
+
+typedef float v2sf __attribute__ ((vector_size(8)));
+void gobble (v2sf);
+
+v2sf A = {100, 200};
+
+/* Init from  floats */
+NOMIPS16 v2sf init (float a, float b)
+{
+  return (v2sf) {a, b};
+}
+
+/* Move between registers */
+NOMIPS16 v2sf move (v2sf a)
+{
+  return a;
+}
+
+/* Load from memory */
+NOMIPS16 v2sf load ()
+{
+  return A;
+}
+
+/* Store to memory */
+NOMIPS16 void store (v2sf a)
+{
+  A = a;
+}
+
+/* Add */
+NOMIPS16 v2sf add (v2sf a, v2sf b)
+{
+  return a + b;
+}
+
+/* Subtract */
+NOMIPS16 v2sf sub (v2sf a, v2sf b)
+{
+  return a - b;
+}
+
+/* Negate */
+NOMIPS16 v2sf neg (v2sf a)
+{
+  return - a;
+}
+
+/* Multiply */
+NOMIPS16 v2sf mul (v2sf a, v2sf b)
+{
+  return a * b;
+}
+
+/* Multiply and add */
+NOMIPS16 v2sf madd (v2sf a, v2sf b, v2sf c)
+{
+  return a * b + c;
+}
+
+/* Multiply and subtract */
+NOMIPS16 v2sf msub (v2sf a, v2sf b, v2sf c)
+{
+  return a * b - c;
+}
+
+/* Negate Multiply and add */
+NOMIPS16 v2sf nmadd (v2sf a, v2sf b, v2sf c)
+{
+  return - (a * b + c);
+}
+
+/* Negate Multiply and subtract */
+NOMIPS16 v2sf nmsub (v2sf a, v2sf b, v2sf c)
+{
+  return - (a * b - c);
+}
+
+/* Conditional Move */
+NOMIPS16 v2sf cond_move1 (v2sf a, v2sf b, int i)
+{
+  if (i == 0)
+    a = b;
+  gobble (a);
+}
+
+/* Conditional Move */
+NOMIPS16 v2sf cond_move2 (v2sf a, v2sf b, int i)
+{
+  if (i != 0)
+    a = b;
+  gobble (a);
+}
Index: gcc/testsuite/gcc.target/mips/fpr-moves-6.c
===================================================================
--- gcc/testsuite/gcc.target/mips/fpr-moves-6.c	2007-10-20 15:22:03.000000000 +0100
+++ gcc/testsuite/gcc.target/mips/fpr-moves-6.c	2007-10-20 15:22:19.000000000 +0100
@@ -29,6 +29,5 @@ bar (long double d, long double *x)
 /* { 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\\\$10,\\\$f0\n" } } */
 /* { dg-final { scan-assembler "\tdmtc1\t\\\$11,\\\$f2\n" } } */
Index: gcc/testsuite/gcc.target/mips/mips.exp
===================================================================
--- gcc/testsuite/gcc.target/mips/mips.exp	2007-10-20 10:22:08.000000000 +0100
+++ gcc/testsuite/gcc.target/mips/mips.exp	2007-10-20 14:29:15.000000000 +0100
@@ -31,8 +31,8 @@ load_lib gcc-dg.exp
 #    $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
+#    $mips_gp:		 the number of bytes in a general register
+#    $mips_fp:		 the number of bytes in a floating-point register
 #    $mips_float:	 "hard" or "soft"
 #    $mips_abi:		 the ABI specified by _MIPS_SIM
 #
@@ -48,8 +48,8 @@ proc setup_mips_tests {} {
     global mips_isa
     global mips_isa_rev
     global mips_arch
-    global mips_gp64
-    global mips_fp64
+    global mips_gp
+    global mips_fp
     global mips_float
     global mips_abi
 
@@ -76,11 +76,11 @@ proc setup_mips_tests {} {
 	#endif
 	const char *arch = _MIPS_ARCH;
 	#ifdef __mips64
-	int gp64 = 1;
-	#endif
-	#if __mips_fpr==64
-	int fp64 = 1;
+	int gp = 64;
+	#else
+	int gp = 32;
 	#endif
+	int fp = __mips_fpr;
 	#ifdef __mips_hard_float
 	const char *float = "hard";
 	#else
@@ -105,8 +105,8 @@ proc setup_mips_tests {} {
     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]
+    regexp {gp = ([^;]*)} $output dummy mips_gp
+    regexp {fp = ([^;]*)} $output dummy mips_fp
     regexp {float = "([^"]*)} $output dummy mips_float
     regexp {abi = "([^"]*)} $output dummy mips_abi
 
@@ -118,29 +118,10 @@ proc setup_mips_tests {} {
     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]
-}
 
-# Return true if command-line option FLAG forces 32-bit code.
-proc is_gp32_flag {flag} {
-    switch -glob -- $flag {
-	-msmartmips -
-	-mips[12] -
-	-mips32* -
-	-march=mips32* -
-	-mabi=32 -
-	-mgp32 { return 1 }
-	default { return 0 }
-    }
-}
-
-# Return true if command-line option FLAG forces 64-bit code.
-proc is_gp64_flag {flag} {
-    switch -glob -- $flag {
-	-mabi=64 -
-	-mabi=o64 -
-	-mabi=n32 -
-	-mgp64 { return 1 }
-	default { return 0 }
+    if {$mips_forced_regs && $mips_gp == 32 && $mips_fp == 64} {
+	set mips_forced_abi 1
+	set mips_forced_isa 1
     }
 }
 
@@ -157,10 +138,10 @@ proc is_gp64_flag {flag} {
 #	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.
+#	Force the use of 64-bit floating-point registers, even 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
@@ -192,6 +173,9 @@ proc is_gp64_flag {flag} {
 #    -mexplicit-relocs
 #	Select explicit relocations.  Skip the test if the multilib flags
 #	force -mno-explicit-relocs.
+#
+#    -mpaired-single
+#	Select paired-single instructions.  Also behave as for -mfp64.
 proc dg-mips-options {args} {
     upvar dg-extra-tool-flags extra_tool_flags
     upvar dg-do-what do_what
@@ -199,8 +183,8 @@ proc dg-mips-options {args} {
     global mips_isa
     global mips_isa_rev
     global mips_arch
-    global mips_gp64
-    global mips_fp64
+    global mips_gp
+    global mips_fp
     global mips_float
     global mips_abi
 
@@ -216,54 +200,76 @@ proc dg-mips-options {args} {
     set flags [lindex $args 1]
     set matches 1
 
-    # First handle the -mgp* options.  Add an architecture option if necessary.
+    # Add implied flags.
     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"
-		}
-	    }
+	if {[string match -mpaired-single $flag]
+	    && [lsearch $flags -mfp*] < 0} {
+	    append flags " -mfp64"
 	}
     }
     foreach flag $flags {
-	if {[is_gp32_flag $flag]
-	    && ($mips_gp64
-		|| ($mips_fp64 && [lsearch $flags -mfp64] < 0)) } {
-	    if {$mips_forced_regs || $mips_forced_abi} {
-		set matches 0
-	    } elseif {[lsearch $flags "-mabi=*"] < 0} {
-		append flags " -mabi=32"
+	if {[string match -mfp* $flag]
+	    && [lsearch -regexp $flags {^-m(hard|soft)-float$}] < 0} {
+	    append flags " -mhard-float"
+	}
+    }
+
+    # Handle options that force a particular register size.  Add
+    # architecture and ABI options if necessary.
+    set mips_new_gp $mips_gp
+    set mips_new_fp $mips_fp
+    foreach flag $flags {
+	switch -glob -- $flag {
+	    -msmartmips -
+	    -mips[12] -
+	    -mips32* -
+	    -march=mips32* -
+	    -mabi=32 -
+	    -mgp32 {
+		set mips_new_gp 32
+	    }
+	    -mabi=64 -
+	    -mabi=o64 -
+	    -mabi=n32 -
+	    -mgp64 {
+		set mips_new_gp 64
 	    }
-	} elseif {[is_gp64_flag $flag] && !$mips_gp64} {
-	    if {$mips_forced_regs || $mips_forced_abi} {
-		set matches 0
+	    -mfp64 {
+		set mips_new_fp 64
+	    }
+	}
+    }
+
+    if {$mips_new_gp != $mips_gp || $mips_new_fp != $mips_fp} {
+	if {$mips_forced_regs} {
+	    set matches 0
+	}
+	# Select an appropriate ABI.
+	if {[lsearch $flags "-mabi=*"] < 0} {
+	    if {$mips_new_gp == 32} {
+		append flags " -mabi=32"
 	    } else {
-	    	if {[lsearch $flags "-mabi=*"] < 0} {
-		    append flags " -mabi=o64"
-		}
-		if {[lsearch -regexp $flags {^(-mips|-march)}] < 0} {
-		    append flags " -mips3"
-		}
+		append flags " -mabi=o64"
+	    }
+	}
+	# And an appropriate architecture.
+	if {[lsearch -regexp $flags {^(-mips|-march)}] < 0} {
+	    if {$mips_new_gp == 64 && $mips_gp == 32} {
+		append flags " -mips3"
+	    } elseif {$mips_new_gp == 32 && $mips_new_fp == 64} {
+		append flags " -mips32r2"
 	    }
 	}
     }
+
     # Handle the other options.
     foreach flag $flags {
 	if {[regexp -- {^-mabi=(.*)} $flag dummy abi]} {
 	    if {$abi != $mips_abi && $mips_forced_abi} {
 		set matches 0
 	    }
-	} elseif {[regexp -- {^-march=(.*)} $flag dummy arch]} {
-	    if {$arch != $mips_arch && $mips_forced_isa} {
-		set matches 0
-	    }
-	} elseif {[regexp -- {^-mips(.*)} $flag dummy isa]} {
+	} elseif {[regexp -- {^-mips(.*)} $flag dummy isa]
+		  || [regexp -- {^-march=mips(.*)} $flag dummy isa]} {
 	    if {![regexp {(.*)r(.*)} $isa dummy isa isa_rev]} {
 		set isa_rev 1
 	    }
@@ -271,6 +277,10 @@ proc dg-mips-options {args} {
 		&& $mips_forced_isa} {
 		set matches 0
 	    }
+	} elseif {[regexp -- {^-march=(.*)} $flag dummy arch]} {
+	    if {$arch != $mips_arch && $mips_forced_isa} {
+		set matches 0
+	    }
 	} elseif {[regexp -- {^-m(hard|soft)-float} $flag dummy float]} {
 	    if {$mips_float != $float && $mips_forced_float} {
 		set matches 0


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]