aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRichard Sandiford <rsandifo@redhat.com>2005-03-11 16:38:27 +0000
committerRichard Sandiford <rsandifo@gcc.gnu.org>2005-03-11 16:38:27 +0000
commit0ac40e7a866e3b149bdeacbf5cc36d1fe364a952 (patch)
tree6d67d7deaee3c8d2c5daab6e5ceec21a45c98736
parent266c6b40edea65bc1159fa60a229b7d8182412ff (diff)
downloadgcc-0ac40e7a866e3b149bdeacbf5cc36d1fe364a952.zip
gcc-0ac40e7a866e3b149bdeacbf5cc36d1fe364a952.tar.gz
gcc-0ac40e7a866e3b149bdeacbf5cc36d1fe364a952.tar.bz2
mips.h (mips_fix_vr4130_string): Declare.
* 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
-rw-r--r--gcc/ChangeLog23
-rw-r--r--gcc/config/mips/mips.c28
-rw-r--r--gcc/config/mips/mips.h11
-rw-r--r--gcc/config/mips/mips.md29
-rw-r--r--gcc/config/mips/t-vr9
-rw-r--r--gcc/config/mips/vr.h18
-rw-r--r--gcc/doc/invoke.texi11
-rw-r--r--gcc/testsuite/ChangeLog4
-rw-r--r--gcc/testsuite/gcc.target/mips/fix-vr4130-1.c9
-rw-r--r--gcc/testsuite/gcc.target/mips/fix-vr4130-2.c9
-rw-r--r--gcc/testsuite/gcc.target/mips/fix-vr4130-3.c9
-rw-r--r--gcc/testsuite/gcc.target/mips/fix-vr4130-4.c9
12 files changed, 150 insertions, 19 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index d58f993..4944b6c 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -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.
diff --git a/gcc/config/mips/mips.c b/gcc/config/mips/mips.c
index 8757497..6748eae 100644
--- a/gcc/config/mips/mips.c
+++ b/gcc/config/mips/mips.c
@@ -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;
diff --git a/gcc/config/mips/mips.h b/gcc/config/mips/mips.h
index 41328a3..0417add 100644
--- a/gcc/config/mips/mips.h
+++ b/gcc/config/mips/mips.h
@@ -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)} \
diff --git a/gcc/config/mips/mips.md b/gcc/config/mips/mips.md
index 8c3a80a..0a63df0 100644
--- a/gcc/config/mips/mips.md
+++ b/gcc/config/mips/mips.md
@@ -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.
diff --git a/gcc/config/mips/t-vr b/gcc/config/mips/t-vr
index dd4affe..9c046b0 100644
--- a/gcc/config/mips/t-vr
+++ b/gcc/config/mips/t-vr
@@ -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
diff --git a/gcc/config/mips/vr.h b/gcc/config/mips/vr.h
index 7d2fb63..bb18292 100644
--- a/gcc/config/mips/vr.h
+++ b/gcc/config/mips/vr.h
@@ -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}"
diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi
index e6ac138..a1ef8313 100644
--- a/gcc/doc/invoke.texi
+++ b/gcc/doc/invoke.texi
@@ -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
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 109c848..8e932ab 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -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
index 0000000..d6d2a5ad
--- /dev/null
+++ b/gcc/testsuite/gcc.target/mips/fix-vr4130-1.c
@@ -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
index 0000000..dcb4899
--- /dev/null
+++ b/gcc/testsuite/gcc.target/mips/fix-vr4130-2.c
@@ -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
index 0000000..ff258ba
--- /dev/null
+++ b/gcc/testsuite/gcc.target/mips/fix-vr4130-3.c
@@ -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
index 0000000..acb2d08
--- /dev/null
+++ b/gcc/testsuite/gcc.target/mips/fix-vr4130-4.c
@@ -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" } } */