Richard Sandiford <rdsandif...@googlemail.com> writes:
> -march is "which instructions can I use?" and -mtune is "which
> instructions
> give good performance?".  My understanding is that you wanted to disable
> the instructions for mips32r2 etc. so that they can be safely linked
> with loongson3a code, in which case it's an -march rather than an
> -mtune decision.
> 
> Admittedly the branch-likely case is a bit of a grey area.  It can be
> justified on tuning grounds because it's unlikely that deprecated
> instructions will perform will in general, and the tuning for mips*
> archs is supposed to be an all-round compromise.  But disabling half
> the FPRs for single floats can't be justified on tuning grounds.
> That's never going to help performance. :-)

OK.

Updated patch attached. I've opted to check for mips as a prefix to the
architecture name as part of the default option handling.

regards,
Matthew

2014-04-30  Matthew Fortune <matthew.fort...@imgtec.com>

gcc/
           * config/mips/mips.c: (mips_option_override) Implement -modd-spreg 
           and defaults.
        * config/mips/mips.h: (TARGET_CPU_CPP_BUILTINS) Add _MIPS_SPFPSET
        builtin define.  (ISA_HAS_ODD_SPREG) Define.  (MIN_FPRS_PER_FMT)
        Redefine in terms of TARGET_ODD_SPREG.
        * config/mips/mips.opt: Add -modd-spreg option.
        * doc/invoke.texi: Document -modd-spreg option.

gcc/testsuite/

        * gcc.target/mips/mips.exp: Add -m[no-]odd-spreg.  Use
        _MIPS_SPFPSET to determine default odd-spreg option.  Account for
        -modd-spreg in minimum arch code.
        * gcc.target/mips/oddspreg-1.c: New.
        * gcc.target/mips/oddspreg-2.c: New.
        * gcc.target/mips/oddspreg-3.c: New.
        * gcc.target/mips/oddspreg-4.c: New. 
        * gcc.target/mips/oddspreg-5.c: New.
        * gcc.target/mips/oddspreg-6.c: New.
        * gcc.target/mips/oddspreg-7.c: New.

---
 gcc/config/mips/mips.c                     |   17 +++++++++++++++++
 gcc/config/mips/mips.h                     |   13 +++++++++++--
 gcc/config/mips/mips.opt                   |    4 ++++
 gcc/doc/invoke.texi                        |    7 +++++++
 gcc/testsuite/gcc.target/mips/mips.exp     |   16 +++++++++++++++-
 gcc/testsuite/gcc.target/mips/oddspreg-1.c |   13 +++++++++++++
 gcc/testsuite/gcc.target/mips/oddspreg-2.c |   10 ++++++++++
 gcc/testsuite/gcc.target/mips/oddspreg-3.c |   10 ++++++++++
 gcc/testsuite/gcc.target/mips/oddspreg-4.c |   10 ++++++++++
 gcc/testsuite/gcc.target/mips/oddspreg-5.c |   15 +++++++++++++++
 gcc/testsuite/gcc.target/mips/oddspreg-6.c |   15 +++++++++++++++
 gcc/testsuite/gcc.target/mips/oddspreg-7.c |   13 +++++++++++++
 12 files changed, 140 insertions(+), 3 deletions(-)
 create mode 100644 gcc/testsuite/gcc.target/mips/oddspreg-1.c
 create mode 100644 gcc/testsuite/gcc.target/mips/oddspreg-2.c
 create mode 100644 gcc/testsuite/gcc.target/mips/oddspreg-3.c
 create mode 100644 gcc/testsuite/gcc.target/mips/oddspreg-4.c
 create mode 100644 gcc/testsuite/gcc.target/mips/oddspreg-5.c
 create mode 100644 gcc/testsuite/gcc.target/mips/oddspreg-6.c
 create mode 100644 gcc/testsuite/gcc.target/mips/oddspreg-7.c

diff --git a/gcc/config/mips/mips.c b/gcc/config/mips/mips.c
index 45256e9..c855527 100644
--- a/gcc/config/mips/mips.c
+++ b/gcc/config/mips/mips.c
@@ -17120,6 +17120,23 @@ mips_option_override (void)
     warning (0, "the %qs architecture does not support madd or msub"
             " instructions", mips_arch_info->name);
 
+  /* If neither -modd-spreg nor -mno-odd-spreg was given on the command
+     line, set MASK_ODD_SPREG bsaed on the target architecture, ABI.  */
+  if ((target_flags_explicit & MASK_ODD_SPREG) == 0)
+    {
+      /* Disable TARGET_ODD_SPREG for generic architectures to make them
+        compatible with those implementations which are
+        !ISA_HAS_ODD_SPREG.  */
+      if (ISA_HAS_ODD_SPREG
+         && (strncmp (mips_arch_info->name, "mips", 4) != 0))
+       target_flags |= MASK_ODD_SPREG;
+      else
+       target_flags &= ~MASK_ODD_SPREG;
+    }
+  else if (TARGET_ODD_SPREG && !ISA_HAS_ODD_SPREG)
+    warning (0, "the %qs architecture does not support odd single-precision"
+            " registers", mips_arch_info->name);
+
   /* The effect of -mabicalls isn't defined for the EABI.  */
   if (mips_abi == ABI_EABI && TARGET_ABICALLS)
     {
diff --git a/gcc/config/mips/mips.h b/gcc/config/mips/mips.h
index b25865b..94dc210 100644
--- a/gcc/config/mips/mips.h
+++ b/gcc/config/mips/mips.h
@@ -491,6 +491,8 @@ struct mips_cpu_info {
       builtin_define_with_int_value ("_MIPS_SZPTR", POINTER_SIZE);     \
       builtin_define_with_int_value ("_MIPS_FPSET",                    \
                                     32 / MAX_FPRS_PER_FMT);            \
+      builtin_define_with_int_value ("_MIPS_SPFPSET",                  \
+                                    32 / MIN_FPRS_PER_FMT);            \
                                                                        \
       /* These defines reflect the ABI in use, not whether the         \
         FPU is directly accessible.  */                                \
@@ -808,6 +810,14 @@ struct mips_cpu_info {
    been generated up to this point.  */
 #define ISA_HAS_BRANCHLIKELY   (!ISA_MIPS1)
 
+/* ISA has 32 single-precision registers.  */
+#define ISA_HAS_ODD_SPREG      (((ISA_MIPS32                           \
+                                  || ISA_MIPS32R2                      \
+                                  || ISA_MIPS64                        \
+                                  || ISA_MIPS64R2)                     \
+                                 && !TARGET_LOONGSON_3A)               \
+                                || TARGET_FLOAT64)
+
 /* ISA has a three-operand multiplication instruction (usually spelt "mul").  
*/
 #define ISA_HAS_MUL3           ((TARGET_MIPS3900                       \
                                  || TARGET_MIPS5400                    \
@@ -1349,8 +1359,7 @@ struct mips_cpu_info {
 /* The number of consecutive floating-point registers needed to store the
    smallest format supported by the FPU.  */
 #define MIN_FPRS_PER_FMT \
-  (ISA_MIPS32 || ISA_MIPS32R2 || ISA_MIPS64 || ISA_MIPS64R2 \
-   ? 1 : MAX_FPRS_PER_FMT)
+  (TARGET_ODD_SPREG ? 1 : MAX_FPRS_PER_FMT)
 
 /* The largest size of value that can be held in floating-point
    registers and moved with a single instruction.  */
diff --git a/gcc/config/mips/mips.opt b/gcc/config/mips/mips.opt
index 6ee5398..f91ca44 100644
--- a/gcc/config/mips/mips.opt
+++ b/gcc/config/mips/mips.opt
@@ -400,5 +400,9 @@ mxgot
 Target Report Var(TARGET_XGOT)
 Lift restrictions on GOT size
 
+modd-spreg
+Target Report Mask(ODD_SPREG)
+Enable use of odd-numbered single-precision registers
+
 noasmopt
 Driver
diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi
index ff43f26..9e89bac 100644
--- a/gcc/doc/invoke.texi
+++ b/gcc/doc/invoke.texi
@@ -776,6 +776,7 @@ Objective-C and Objective-C++ Dialects}.
 -mshared  -mno-shared  -mplt  -mno-plt  -mxgot  -mno-xgot @gol
 -mgp32  -mgp64  -mfp32  -mfp64  -mhard-float  -msoft-float @gol
 -mno-float  -msingle-float  -mdouble-float @gol
+-modd-spreg -mno-odd-spreg @gol
 -mabs=@var{mode}  -mnan=@var{encoding} @gol
 -mdsp  -mno-dsp  -mdspr2  -mno-dspr2 @gol
 -mmcu -mmno-mcu @gol
@@ -17355,6 +17356,12 @@ operations.
 Assume that the floating-point coprocessor supports double-precision
 operations.  This is the default.
 
+@item -modd-spreg
+@opindex modd-spreg
+Enable the use of odd-numbered single-precision floating-point registers
+with @option{-mfp32}.  This is the default for specific processors
+that are known to support these registers.
+
 @item -mabs=2008
 @itemx -mabs=legacy
 @opindex mabs=2008
diff --git a/gcc/testsuite/gcc.target/mips/mips.exp 
b/gcc/testsuite/gcc.target/mips/mips.exp
index 8c72cff..1fa7b09 100644
--- a/gcc/testsuite/gcc.target/mips/mips.exp
+++ b/gcc/testsuite/gcc.target/mips/mips.exp
@@ -270,6 +270,7 @@ foreach option {
     synci
     relax-pic-calls
     mcount-ra-address
+    odd-spreg
 } {
     lappend mips_option_groups $option "-m(no-|)$option"
 }
@@ -755,6 +756,12 @@ proc mips-dg-init {} {
            "-mno-paired-single",
            #endif
 
+           #if _MIPS_SPFPSET == 32
+           "-modd-spreg",
+           #else
+           "-mno-odd-spreg",
+           #endif
+
            #if __mips_abicalls
            "-mabicalls",
            #else
@@ -840,6 +847,8 @@ proc mips-dg-finish {} {
 #            |                           |
 #         -mfp64                      -mfp32
 #            |                           |
+#         -modd-spreg                 -mno-odd-spreg
+#            |                           |
 #         -mabs=2008/-mabs=legacy     <no option>
 #            |                           |
 #         -mhard-float                -msoft-float
@@ -929,6 +938,7 @@ proc mips-dg-options { args } {
     mips_option_dependency options "-mips3d" "-mpaired-single"
     mips_option_dependency options "-mpaired-single" "-mfp64"
     mips_option_dependency options "-mfp64" "-mhard-float"
+    mips_option_dependency options "-mfp64" "-modd-spreg"
     mips_option_dependency options "-mabs=2008" "-mhard-float"
     mips_option_dependency options "-mabs=legacy" "-mhard-float"
     mips_option_dependency options "-mrelax-pic-calls" "-mno-plt"
@@ -1045,10 +1055,13 @@ proc mips-dg-options { args } {
         # We need a MIPS32 or MIPS64 ISA for:
        #
         #   - paired-single instructions(*)
+        #   - odd numbered single precision registers
         #
        # (*) Note that we don't support MIPS V at the moment.
        } elseif { $isa_rev < 1
-                  && [mips_have_test_option_p options "-mpaired-single"] } {
+                  && ([mips_have_test_option_p options "-mpaired-single"]
+                      || ([mips_have_test_option_p options "-modd-spreg"]
+                          && ![mips_have_test_option_p options "-mfp64"]))} {
            if { $gp_size == 32 } {
                mips_make_test_option options "-mips32"
            } else {
@@ -1192,6 +1205,7 @@ proc mips-dg-options { args } {
        }
        if { $isa_rev < 1 } {
            mips_make_test_option options "-mno-paired-single"
+           mips_make_test_option options "-mno-odd-spreg"
        }
        if { $isa_rev < 2 } {
            if { $gp_size == 32 } {
diff --git a/gcc/testsuite/gcc.target/mips/oddspreg-1.c 
b/gcc/testsuite/gcc.target/mips/oddspreg-1.c
new file mode 100644
index 0000000..a9c6957
--- /dev/null
+++ b/gcc/testsuite/gcc.target/mips/oddspreg-1.c
@@ -0,0 +1,13 @@
+/* Check that we enable odd-numbered single precision registers.  */
+/* { dg-options "-mabi=32 -modd-spreg -mhard-float" } */
+
+#if _MIPS_SPFPSET != 32
+#error "Incorrect number of single-precision registers reported"
+#endif
+
+void
+foo ()
+{
+  register float foo asm ("$f1");
+  asm volatile ("" : "=f" (foo));
+}
diff --git a/gcc/testsuite/gcc.target/mips/oddspreg-2.c 
b/gcc/testsuite/gcc.target/mips/oddspreg-2.c
new file mode 100644
index 0000000..e2e0a26
--- /dev/null
+++ b/gcc/testsuite/gcc.target/mips/oddspreg-2.c
@@ -0,0 +1,10 @@
+/* Check that we disable odd-numbered single precision registers.  */
+/* { dg-skip-if "needs asm output" { *-*-* } { "-fno-fat-lto-objects" } { "" } 
} */
+/* { dg-options "-mabi=32 -mno-odd-spreg -mhard-float" } */
+
+void
+foo ()
+{
+  register float foo asm ("$f1"); /* { dg-error "isn't suitable for" } */
+  asm volatile ("" : "=f" (foo));
+}
diff --git a/gcc/testsuite/gcc.target/mips/oddspreg-3.c 
b/gcc/testsuite/gcc.target/mips/oddspreg-3.c
new file mode 100644
index 0000000..8a2eb63
--- /dev/null
+++ b/gcc/testsuite/gcc.target/mips/oddspreg-3.c
@@ -0,0 +1,10 @@
+/* Check that we disable odd-numbered single precision registers.  */
+/* { dg-skip-if "needs asm output" { *-*-* } { "-fno-fat-lto-objects" } { "" } 
} */
+/* { dg-options "-mabi=32 -march=loongson3a -mhard-float" } */
+
+void
+foo ()
+{
+  register float foo asm ("$f1"); /* { dg-error "isn't suitable for" } */
+  asm volatile ("" : "=f" (foo));
+}
diff --git a/gcc/testsuite/gcc.target/mips/oddspreg-4.c 
b/gcc/testsuite/gcc.target/mips/oddspreg-4.c
new file mode 100644
index 0000000..1364a26
--- /dev/null
+++ b/gcc/testsuite/gcc.target/mips/oddspreg-4.c
@@ -0,0 +1,10 @@
+/* Check that we disable odd-numbered single precision registers.  */
+/* { dg-skip-if "needs asm output" { *-*-* } { "-fno-fat-lto-objects" } { "" } 
} */
+/* { dg-options "-mabi=32 -mips32r2 -mhard-float" } */
+
+void
+foo ()
+{
+  register float foo asm ("$f1"); /* { dg-error "isn't suitable for" } */
+  asm volatile ("" : "=f" (foo));
+}
diff --git a/gcc/testsuite/gcc.target/mips/oddspreg-5.c 
b/gcc/testsuite/gcc.target/mips/oddspreg-5.c
new file mode 100644
index 0000000..723424a
--- /dev/null
+++ b/gcc/testsuite/gcc.target/mips/oddspreg-5.c
@@ -0,0 +1,15 @@
+/* Check that we disable odd-numbered single precision registers and can
+   still generate code.  */
+/* { dg-options "-mabi=32 -mno-odd-spreg -mhard-float" } */
+
+#if _MIPS_SPFPSET != 16
+#error "Incorrect number of single-precision registers reported"
+#endif
+
+float a;
+float
+foo ()
+{
+  float b = a + 1.0f;
+  return b;
+}
diff --git a/gcc/testsuite/gcc.target/mips/oddspreg-6.c 
b/gcc/testsuite/gcc.target/mips/oddspreg-6.c
new file mode 100644
index 0000000..2d1b129
--- /dev/null
+++ b/gcc/testsuite/gcc.target/mips/oddspreg-6.c
@@ -0,0 +1,15 @@
+/* Check that we disable odd-numbered single precision registers and can
+   still generate code.  */
+/* { dg-options "-mabi=64 -mno-odd-spreg -mhard-float" } */
+
+#if _MIPS_SPFPSET != 32
+#error "Incorrect number of single-precision registers reported"
+#endif
+
+float a;
+float
+foo ()
+{
+  float b = a + 1.0f;
+  return b;
+}
diff --git a/gcc/testsuite/gcc.target/mips/oddspreg-7.c 
b/gcc/testsuite/gcc.target/mips/oddspreg-7.c
new file mode 100644
index 0000000..b1e79c1
--- /dev/null
+++ b/gcc/testsuite/gcc.target/mips/oddspreg-7.c
@@ -0,0 +1,13 @@
+/* Check that we enable odd-numbered single precision registers.  */
+/* { dg-options "-mabi=32 -march=octeon -mhard-float" } */
+
+#if _MIPS_SPFPSET != 32
+#error "Incorrect number of single-precision registers reported"
+#endif
+
+void
+foo ()
+{
+  register float foo asm ("$f1");
+  asm volatile ("" : "=f" (foo));
+}
-- 
1.7.1

Reply via email to