mips.h (mips_fix_vr4130_string): Declare.
authorRichard Sandiford <rsandifo@redhat.com>
Fri, 11 Mar 2005 16:38:27 +0000 (16:38 +0000)
committerRichard Sandiford <rsandifo@gcc.gnu.org>
Fri, 11 Mar 2005 16:38:27 +0000 (16:38 +0000)
* config/mips/mips.h (mips_fix_vr4130_string): Declare.
(TARGET_FIX_VR4130): New macro.
(TARGET_OPTIONS): Add -mfix-vr4130.
(ISA_HAS_MACCHI): New macro.
(ASM_SPEC): Add -mfix-vr4130.
* config/mips/mips.c (mips_fix_vr4130_string): New variable.
(override_options): Handle mips_fix_vr4130_string.
(mips_avoid_hazards): Clear all_noreorder_p
if we're working around VR4130 errata and the macc alternatives
are not available.
* config/mips/mips.md (mfhilo_<mode>): Turn into a define_expand.
(*mfhilo_<mode>, *mfhilo_<mode>_macc): New insns.
* config/mips/vr.h (DEFAULT_VR_ARCH): Set to mfix-vr4130.
(MULTILIB_DEFAULTS): Remove leading "march=".
(DRIVER_SELF_SPECS): Likewise.  Make -mfix-vr4130 imply -march=vr4130
if no architecture option is given.
* config/mips/t-vr (MULTILIB_OPTIONS): Use -mfix-vr4130 for the
VR4130 multilibs.
(MULTILIB_MATCHES): Map -march=vr4130 to the -mfix-vr4130 multilibs.
* doc/invoke.texi: Document -mfix-vr4130.

From-SVN: r96301

12 files changed:
gcc/ChangeLog
gcc/config/mips/mips.c
gcc/config/mips/mips.h
gcc/config/mips/mips.md
gcc/config/mips/t-vr
gcc/config/mips/vr.h
gcc/doc/invoke.texi
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.target/mips/fix-vr4130-1.c [new file with mode: 0644]
gcc/testsuite/gcc.target/mips/fix-vr4130-2.c [new file with mode: 0644]
gcc/testsuite/gcc.target/mips/fix-vr4130-3.c [new file with mode: 0644]
gcc/testsuite/gcc.target/mips/fix-vr4130-4.c [new file with mode: 0644]

index d58f993..4944b6c 100644 (file)
@@ -1,5 +1,28 @@
 2005-03-11  Richard Sandiford  <rsandifo@redhat.com>
 
+       * config/mips/mips.h (mips_fix_vr4130_string): Declare.
+       (TARGET_FIX_VR4130): New macro.
+       (TARGET_OPTIONS): Add -mfix-vr4130.
+       (ISA_HAS_MACCHI): New macro.
+       (ASM_SPEC): Add -mfix-vr4130.
+       * config/mips/mips.c (mips_fix_vr4130_string): New variable.
+       (override_options): Handle mips_fix_vr4130_string.
+       (mips_avoid_hazards): Clear all_noreorder_p
+       if we're working around VR4130 errata and the macc alternatives
+       are not available.
+       * config/mips/mips.md (mfhilo_<mode>): Turn into a define_expand.
+       (*mfhilo_<mode>, *mfhilo_<mode>_macc): New insns.
+       * config/mips/vr.h (DEFAULT_VR_ARCH): Set to mfix-vr4130.
+       (MULTILIB_DEFAULTS): Remove leading "march=".
+       (DRIVER_SELF_SPECS): Likewise.  Make -mfix-vr4130 imply -march=vr4130
+       if no architecture option is given.
+       * config/mips/t-vr (MULTILIB_OPTIONS): Use -mfix-vr4130 for the
+       VR4130 multilibs.
+       (MULTILIB_MATCHES): Map -march=vr4130 to the -mfix-vr4130 multilibs.
+       * doc/invoke.texi: Document -mfix-vr4130.
+
+2005-03-11  Richard Sandiford  <rsandifo@redhat.com>
+
        * config/mips/mips.c (override_options): Only warn about -mint64
        deprecation if TARGET_INT64.
 
index 8757497..6748eae 100644 (file)
@@ -562,6 +562,9 @@ int mips16_hard_float;
 
 const char *mips_cache_flush_func = CACHE_FLUSH_FUNC;
 
+/* Holds string <X> if -mfix-vr4130<X> was passed on the command line.  */
+const char *mips_fix_vr4130_string;
+
 /* If TRUE, we split addresses into their high and low parts in the RTL.  */
 int mips_split_addresses;
 
@@ -4135,6 +4138,9 @@ override_options (void)
   if (TARGET_INT64)
     warning ("-mint64 is a deprecated option");
 
+  if (mips_fix_vr4130_string && mips_fix_vr4130_string[0] != 0)
+    error ("unrecognized option %<-mfix-vr4130%s%>", mips_fix_vr4130_string);
+
   if (MIPS_MARCH_CONTROLS_SOFT_FLOAT
       && (target_flags_explicit & MASK_SOFT_FLOAT) == 0)
     {
@@ -8294,10 +8300,24 @@ mips_avoid_hazards (void)
   cfun->machine->ignore_hazard_length_p = true;
   shorten_branches (get_insns ());
 
-  /* The profiler code uses assembler macros.  -mfix-vr4120 relies on
-     assembler nop insertion.  */
-  cfun->machine->all_noreorder_p = (!current_function_profile
-                                   && !TARGET_FIX_VR4120);
+  cfun->machine->all_noreorder_p = true;
+
+  /* Profiled functions can't be all noreorder because the profiler
+     support uses assembler macros.  */
+  if (current_function_profile)
+    cfun->machine->all_noreorder_p = false;
+
+  /* Code compiled with -mfix-vr4120 can't be all noreorder because
+     we rely on the assembler to work around some errata.  */
+  if (TARGET_FIX_VR4120)
+    cfun->machine->all_noreorder_p = false;
+
+  /* The same is true for -mfix-vr4130 if we might generate mflo or
+     mfhi instructions.  Note that we avoid using mflo and mfhi if
+     the VR4130 macc and dmacc instructions are available instead;
+     see the *mfhilo_{si,di}_macc patterns.  */
+  if (TARGET_FIX_VR4130 && !ISA_HAS_MACCHI)
+    cfun->machine->all_noreorder_p = false;
 
   last_insn = 0;
   hilo_delay = 2;
index 41328a3..0417add 100644 (file)
@@ -111,6 +111,7 @@ extern const char *mips_tune_string;    /* for -mtune=<xxx> */
 extern const char *mips_isa_string;    /* for -mips{1,2,3,4} */
 extern const char *mips_abi_string;    /* for -mabi={32,n32,64} */
 extern const char *mips_cache_flush_func;/* for -mflush-func= and -mno-flush-func */
+extern const char *mips_fix_vr4130_string;
 extern const struct mips_cpu_info mips_cpu_info_table[];
 extern const struct mips_cpu_info *mips_arch_info;
 extern const struct mips_cpu_info *mips_tune_info;
@@ -236,6 +237,7 @@ extern const struct mips_cpu_info *mips_tune_info;
                                        /* Work around R4400 errata.  */
 #define TARGET_FIX_R4400       ((target_flags & MASK_FIX_R4400) != 0)
 #define TARGET_FIX_VR4120      ((target_flags & MASK_FIX_VR4120) != 0)
+#define TARGET_FIX_VR4130      (mips_fix_vr4130_string != 0)
 #define TARGET_VR4130_ALIGN    ((target_flags & MASK_VR4130_ALIGN) != 0)
 
 #define TARGET_FP_EXCEPTIONS   ((target_flags & MASK_FP_EXCEPTIONS) != 0)
@@ -794,6 +796,8 @@ extern const struct mips_cpu_info *mips_tune_info;
       N_("Don't call any cache flush functions"), 0},                  \
   { "flush-func=", &mips_cache_flush_func,                             \
       N_("Specify cache flush function"), 0},                          \
+  { "fix-vr4130", &mips_fix_vr4130_string,                             \
+      N_("Work around VR4130 mflo/mfhi errata"), 0},                   \
 }
 
 /* This is meant to be redefined in the host dependent files.  */
@@ -939,6 +943,11 @@ extern const struct mips_cpu_info *mips_tune_info;
                                  || TARGET_SR71K                        \
                                  )
 
+/* ISA has NEC VR-style MACC, MACCHI, DMACC and DMACCHI instructions.  */
+#define ISA_HAS_MACCHI         (!TARGET_MIPS16                         \
+                                && (TARGET_MIPS4120                    \
+                                    || TARGET_MIPS4130))
+
 /* ISA has 32-bit rotate right instruction.  */
 #define ISA_HAS_ROTR_SI         (!TARGET_MIPS16                         \
                                  && (ISA_MIPS32R2                       \
@@ -1094,7 +1103,7 @@ extern const struct mips_cpu_info *mips_tune_info;
 %{mips32} %{mips32r2} %{mips64} \
 %{mips16:%{!mno-mips16:-mips16}} %{mno-mips16:-no-mips16} \
 %{mips3d:-mips3d} \
-%{mfix-vr4120} \
+%{mfix-vr4120} %{mfix-vr4130} \
 %(subtarget_asm_optimizing_spec) \
 %(subtarget_asm_debugging_spec) \
 %{mabi=*} %{!mabi*: %(asm_abi_default_spec)} \
index 8c3a80a..0a63df0 100644 (file)
@@ -3729,17 +3729,42 @@ beq\t%2,%.,1b\;\
 ;;
 ;; We cope with this by making the mflo and mfhi patterns use both HI and LO.
 ;; Operand 1 is the register we want, operand 2 is the other one.
+;;
+;; When generating VR4120 or VR4130 code, we use macc{,hi} and
+;; dmacc{,hi} instead of mfhi and mflo.  This avoids both the normal
+;; MIPS III hi/lo hazards and the errata related to -mfix-vr4130.
+
+(define_expand "mfhilo_<mode>"
+  [(set (match_operand:GPR 0 "register_operand")
+       (unspec:GPR [(match_operand:GPR 1 "register_operand")
+                    (match_operand:GPR 2 "register_operand")]
+                   UNSPEC_MFHILO))])
 
-(define_insn "mfhilo_<mode>"
+(define_insn "*mfhilo_<mode>"
   [(set (match_operand:GPR 0 "register_operand" "=d,d")
        (unspec:GPR [(match_operand:GPR 1 "register_operand" "h,l")
                     (match_operand:GPR 2 "register_operand" "l,h")]
                    UNSPEC_MFHILO))]
-  ""
+  "!ISA_HAS_MACCHI"
   "mf%1\t%0"
   [(set_attr "type" "mfhilo")
    (set_attr "mode" "<MODE>")])
 
+(define_insn "*mfhilo_<mode>_macc"
+  [(set (match_operand:GPR 0 "register_operand" "=d,d")
+       (unspec:GPR [(match_operand:GPR 1 "register_operand" "h,l")
+                    (match_operand:GPR 2 "register_operand" "l,h")]
+                   UNSPEC_MFHILO))]
+  "ISA_HAS_MACCHI"
+{
+  if (REGNO (operands[1]) == HI_REGNUM)
+    return "<d>macchi\t%0,%.,%.";
+  else
+    return "<d>macc\t%0,%.,%.";
+}
+  [(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.
index dd4affe..9c046b0 100644 (file)
@@ -35,7 +35,7 @@ $(T)crtn.o: $(srcdir)/config/mips/crtn.asm $(GCC_PASSES)
 #      mabi=eabi/mgp32/mlong64
 #
 # Architecture: march=vr4120 with -mfix-vr4120
-#              march=vr4130 (default)
+#              march=vr4130 with -mfix-vr4130 (default)
 #              march=vr5000
 #              march=vr5400
 #              march=vr5500
@@ -65,7 +65,7 @@ $(T)crtn.o: $(srcdir)/config/mips/crtn.asm $(GCC_PASSES)
 #      mabi=eabi/mgp32
 #
 # Architecture: march=vr4120 with -mfix-vr4120
-#              march=vr4130 (default)
+#              march=vr4130 with -mfix-vr4130 (default)
 #
 # Total: 2 * 3 * 2 = 12 multilibs.
 MULTILIB_OPTIONS =                     \
@@ -74,7 +74,7 @@ MULTILIB_OPTIONS =                    \
        mgp32                           \
        mlong64                         \
        mips16                          \
-       mfix-vr4120/march=vr4130/march=vr4300/march=vr5000/march=vr5400/march=vr5500
+       mfix-vr4120/mfix-vr4130/march=vr4300/march=vr5000/march=vr5400/march=vr5500
 
 MULTILIB_DIRNAMES =    \
        el eb           \
@@ -84,7 +84,8 @@ MULTILIB_DIRNAMES =   \
        mips16          \
        vr4120 vr4130 vr4300 vr5000 vr5400 vr5500
 
-MULTILIB_MATCHES = EL=mel EB=meb mfix-vr4120=march?vr4120
+MULTILIB_MATCHES = EL=mel EB=meb mfix-vr4120=march?vr4120 \
+                  mfix-vr4130=march?vr4130
 
 # Assume a 41xx-series is the default: we'd need a *mips16 entry if
 # the default processor didn't support mips16.  Also assume the
index 7d2fb63..bb18292 100644 (file)
@@ -19,20 +19,28 @@ You should have received a copy of the GNU General Public License
 along with GCC; see the file COPYING.  If not, write to
 the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
 
-#define DEFAULT_VR_ARCH "vr4130"
+#define DEFAULT_VR_ARCH "mfix-vr4130"
 #define MIPS_ABI_DEFAULT ABI_EABI
 #define MIPS_MARCH_CONTROLS_SOFT_FLOAT 1
 #define MULTILIB_DEFAULTS \
        { MULTILIB_ENDIAN_DEFAULT,              \
          MULTILIB_ABI_DEFAULT,                 \
-         "march=" DEFAULT_VR_ARCH }
+         DEFAULT_VR_ARCH }
 
 #define DRIVER_SELF_SPECS \
+       /* Enforce the default architecture.  This is mostly for        \
+          the assembler's benefit.  */                                 \
+       "%{!march=*:%{!mfix-vr4120:%{!mfix-vr4130:"                     \
+       "-" DEFAULT_VR_ARCH "}}}",                                      \
+                                                                       \
        /* Make -mfix-vr4120 imply -march=vr4120.  This cuts down       \
           on command-line tautology and makes it easier for t-vr to    \
           provide a -mfix-vr4120 multilib.  */                         \
        "%{mfix-vr4120:%{!march=*:-march=vr4120}}",                     \
                                                                        \
+       /* Same idea for -mfix-vr4130.  */                              \
+       "%{mfix-vr4130:%{!march=*:-march=vr4130}}",                     \
+                                                                       \
        /* Make -mabi=eabi -mlong32 the default.  */                    \
        "%{!mabi=*:-mabi=eabi %{!mlong*:-mlong32}}",                    \
                                                                        \
@@ -41,8 +49,4 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
        "%{mabi=eabi:%{!mlong*:%{!mgp32:-mlong64}}}",                   \
                                                                        \
        /* Remove -mgp32 if it is redundant.  */                        \
-       "%{mabi=32:%<mgp32}",                                           \
-                                                                       \
-       /* Enforce the default architecture.  This is mostly for        \
-          the assembler's benefit.  */                                 \
-       "%{!march=*:-march=" DEFAULT_VR_ARCH "}"
+       "%{mabi=32:%<mgp32}"
index e6ac138..a1ef831 100644 (file)
@@ -558,7 +558,8 @@ Objective-C and Objective-C++ Dialects}.
 -mmemcpy  -mno-memcpy  -mlong-calls  -mno-long-calls @gol
 -mmad  -mno-mad  -mfused-madd  -mno-fused-madd  -nocpp @gol
 -mfix-r4000  -mno-fix-r4000  -mfix-r4400  -mno-fix-r4400 @gol
--mfix-vr4120  -mno-fix-vr4120  -mfix-sb1  -mno-fix-sb1 @gol
+-mfix-vr4120  -mno-fix-vr4120  -mfix-vr4130 @gol
+-mfix-sb1  -mno-fix-sb1 @gol
 -mflush-func=@var{func}  -mno-flush-func @gol
 -mbranch-likely  -mno-branch-likely @gol
 -mfp-exceptions -mno-fp-exceptions @gol
@@ -9848,6 +9849,14 @@ the @code{mips64vr*-elf} configurations.
 Other VR4120 errata require a nop to be inserted between certain pairs of
 instructions.  These errata are handled by the assembler, not by GCC itself.
 
+@item -mfix-vr4130
+@opindex mfix-vr4130
+Work around the VR4130 @code{mflo}/@code{mfhi} errata.  The
+workarounds are implemented by the assembler rather than by GCC,
+although GCC will avoid using @code{mflo} and @code{mfhi} if the
+VR4130 @code{macc}, @code{macchi}, @code{dmacc} and @code{dmacchi}
+instructions are available instead.
+
 @item -mfix-sb1
 @itemx -mno-fix-sb1
 @opindex mfix-sb1
index 109c848..8e932ab 100644 (file)
@@ -1,3 +1,7 @@
+2005-03-11  Richard Sandiford  <rsandifo@redhat.com>
+
+       * gcc.target/mips/fix-vr4130-[1-4].c: New tests.
+
 2005-03-12  Francois-Xavier Coudert  <coudert@clipper.ens.fr>
 
        PR libfortran/20124
diff --git a/gcc/testsuite/gcc.target/mips/fix-vr4130-1.c b/gcc/testsuite/gcc.target/mips/fix-vr4130-1.c
new file mode 100644 (file)
index 0000000..d6d2a5a
--- /dev/null
@@ -0,0 +1,9 @@
+/* { dg-do compile { target mips*-*-* } } */
+/* { dg-skip-if "" { mips-sgi-irix* } { "-mabi=32" } { "" } } */
+/* { dg-options "-mfix-vr4130 -march=vr4130" } */
+#if _MIPS_ARCH_VR4130 && !__mips16
+int foo (void) { int r; asm ("# foo" : "=h" (r)); return r; }
+#else
+asm ("#\tmacchi\t");
+#endif
+/* { dg-final { scan-assembler "\tmacchi\t" } } */
diff --git a/gcc/testsuite/gcc.target/mips/fix-vr4130-2.c b/gcc/testsuite/gcc.target/mips/fix-vr4130-2.c
new file mode 100644 (file)
index 0000000..dcb4899
--- /dev/null
@@ -0,0 +1,9 @@
+/* { dg-do compile { target mips*-*-* } } */
+/* { dg-skip-if "" { mips-sgi-irix* } { "-mabi=32" } { "" } } */
+/* { dg-options "-mfix-vr4130 -march=vr4130" } */
+#if _MIPS_ARCH_VR4130 && !__mips16
+int foo (void) { int r; asm ("# foo" : "=l" (r)); return r; }
+#else
+asm ("#\tmacc\t");
+#endif
+/* { dg-final { scan-assembler "\tmacc\t" } } */
diff --git a/gcc/testsuite/gcc.target/mips/fix-vr4130-3.c b/gcc/testsuite/gcc.target/mips/fix-vr4130-3.c
new file mode 100644 (file)
index 0000000..ff258ba
--- /dev/null
@@ -0,0 +1,9 @@
+/* { dg-do compile { target mips*-*-* } } */
+/* { dg-skip-if "" { mips-sgi-irix* } { "-mabi=32" } { "" } } */
+/* { dg-options "-mfix-vr4130 -march=vr4130" } */
+#if _MIPS_ARCH_VR4130 && !__mips16 && __mips64
+long long foo (void) { long long r; asm ("# foo" : "=h" (r)); return r; }
+#else
+asm ("#\tdmacchi\t");
+#endif
+/* { dg-final { scan-assembler "\tdmacchi\t" } } */
diff --git a/gcc/testsuite/gcc.target/mips/fix-vr4130-4.c b/gcc/testsuite/gcc.target/mips/fix-vr4130-4.c
new file mode 100644 (file)
index 0000000..acb2d08
--- /dev/null
@@ -0,0 +1,9 @@
+/* { dg-do compile { target mips*-*-* } } */
+/* { dg-skip-if "" { mips-sgi-irix* } { "-mabi=32" } { "" } } */
+/* { dg-options "-mfix-vr4130 -march=vr4130" } */
+#if _MIPS_ARCH_VR4130 && !__mips16 && __mips64
+long long foo (void) { long long r; asm ("# foo" : "=l" (r)); return r; }
+#else
+asm ("#\tdmacc\t");
+#endif
+/* { dg-final { scan-assembler "\tdmacc\t" } } */