MIPS: PR target/78176 add -mlxc1-sxc1.
authorMatthew Fortune <mpf@gcc.gnu.org>
Thu, 19 Jan 2017 16:05:59 +0000 (16:05 +0000)
committerMatthew Fortune <mpf@gcc.gnu.org>
Thu, 19 Jan 2017 16:05:59 +0000 (16:05 +0000)
gcc/

PR target/78176
* config.gcc (supported_defaults): Add lxc1-sxc1.
(with_lxc1_sxc1): Add validation.
(all_defaults): Add lxc1-sxc1.
* config/mips/mips.opt (mlxc1-sxc1): New option.
* gcc/config/mips/mips.h (OPTION_DEFAULT_SPECS): Add a default for
mlxc1-sxc1.
(TARGET_CPU_CPP_BUILTINS): Add builtin_define for
__mips_no_lxc1_sxc1.
(ISA_HAS_LXC1_SXC1): Gate with mips_lxc1_sxc1.
* gcc/doc/invoke.texi (-mlxc1-sxc1): Document the new option.
* doc/install.texi (--with-lxc1-sxc1): Document the new option.

gcc/testsuite/

* gcc.target/mips/lxc1-sxc1-1.c: New file.
* gcc.target/mips/lxc1-sxc1-2.c: Likewise.
* gcc.target/mips/mips.exp (mips_option_groups): Add ghost option
HAS_LXC1.
(mips_option_groups): Add -m[no-]lxc1-sxc1.
(mips-dg-init): Detect default -mno-lxc1-sxc1.
(mips-dg-options): Handle HAS_LXC1 arch upgrade/downgrade.

From-SVN: r244640

gcc/ChangeLog
gcc/config.gcc
gcc/config/mips/mips.h
gcc/config/mips/mips.opt
gcc/doc/install.texi
gcc/doc/invoke.texi
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.target/mips/lxc1-sxc1-1.c [new file with mode: 0644]
gcc/testsuite/gcc.target/mips/lxc1-sxc1-2.c [new file with mode: 0644]
gcc/testsuite/gcc.target/mips/mips.exp

index 20b703f1fe77c587402544b8f3f5664536d8ab4d..f933e1ad240e1aa9fdcb86f6d11d3bdfe2b8859a 100644 (file)
@@ -1,3 +1,18 @@
+2017-01-19  Doug Gilmore  <doug.gilmore@imgtec.com>
+
+       PR target/78176
+       * config.gcc (supported_defaults): Add lxc1-sxc1.
+       (with_lxc1_sxc1): Add validation.
+       (all_defaults): Add lxc1-sxc1.
+       * config/mips/mips.opt (mlxc1-sxc1): New option.
+       * gcc/config/mips/mips.h (OPTION_DEFAULT_SPECS): Add a default for
+       mlxc1-sxc1.
+       (TARGET_CPU_CPP_BUILTINS): Add builtin_define for
+       __mips_no_lxc1_sxc1.
+       (ISA_HAS_LXC1_SXC1): Gate with mips_lxc1_sxc1.
+       * gcc/doc/invoke.texi (-mlxc1-sxc1): Document the new option.
+       * doc/install.texi (--with-lxc1-sxc1): Document the new option.
+
 2017-01-19  Richard Biener  <rguenther@suse.de>
 
        PR tree-optimization/72488
index 90308cd457253e4ca42e75ce39c295e1ade32cbe..dd8c08cfd9328f6e1e3f148f4318248ceee37087 100644 (file)
@@ -3940,7 +3940,7 @@ case "${target}" in
                ;;
 
        mips*-*-*)
-               supported_defaults="abi arch arch_32 arch_64 float fpu nan fp_32 odd_spreg_32 tune tune_32 tune_64 divide llsc mips-plt synci"
+               supported_defaults="abi arch arch_32 arch_64 float fpu nan fp_32 odd_spreg_32 tune tune_32 tune_64 divide llsc mips-plt synci lxc1-sxc1"
 
                case ${with_float} in
                "" | soft | hard)
@@ -4063,6 +4063,21 @@ case "${target}" in
                        exit 1
                        ;;
                esac
+
+               case ${with_lxc1_sxc1} in
+               yes)
+                       with_lxc1_sxc1=lxc1-sxc1
+                       ;;
+               no)
+                       with_lxc1_sxc1=no-lxc1-sxc1
+                       ;;
+               "")
+                       ;;
+               *)
+                       echo "Unknown lxc1-sxc1 type used in --with-lxc1-sxc1" 1>&2
+                       exit 1
+                       ;;
+               esac
                ;;
 
        nds32*-*-*)
@@ -4496,7 +4511,7 @@ case ${target} in
 esac
 
 t=
-all_defaults="abi cpu cpu_32 cpu_64 arch arch_32 arch_64 tune tune_32 tune_64 schedule float mode fpu nan fp_32 odd_spreg_32 divide llsc mips-plt synci tls"
+all_defaults="abi cpu cpu_32 cpu_64 arch arch_32 arch_64 tune tune_32 tune_64 schedule float mode fpu nan fp_32 odd_spreg_32 divide llsc mips-plt synci tls lxc1-sxc1"
 for option in $all_defaults
 do
        eval "val=\$with_"`echo $option | sed s/-/_/g`
index fbd7011512e2658dc4c0cb269b87d246fbbb7d42..4205589af459aa1696c85486232514d360aad21f 100644 (file)
@@ -637,6 +637,8 @@ struct mips_cpu_info {
                                                                        \
       if (TARGET_CACHE_BUILTIN)                                                \
        builtin_define ("__GCC_HAVE_BUILTIN_MIPS_CACHE");               \
+      if (!ISA_HAS_LXC1_SXC1)                                          \
+       builtin_define ("__mips_no_lxc1_sxc1");                         \
     }                                                                  \
   while (0)
 
@@ -866,7 +868,8 @@ struct mips_cpu_info {
   {"divide", "%{!mdivide-traps:%{!mdivide-breaks:-mdivide-%(VALUE)}}" }, \
   {"llsc", "%{!mllsc:%{!mno-llsc:-m%(VALUE)}}" }, \
   {"mips-plt", "%{!mplt:%{!mno-plt:-m%(VALUE)}}" }, \
-  {"synci", "%{!msynci:%{!mno-synci:-m%(VALUE)}}" }
+  {"synci", "%{!msynci:%{!mno-synci:-m%(VALUE)}}" },                   \
+  {"lxc1-sxc1", "%{!mlxc1-sxc1:%{!mno-lxc1-sxc1:-m%(VALUE)}}" } \
 
 /* A spec that infers the:
    -mnan=2008 setting from a -mips argument,
@@ -1036,7 +1039,8 @@ struct mips_cpu_info {
 
 /* ISA has floating-point indexed load and store instructions
    (LWXC1, LDXC1, SWXC1 and SDXC1).  */
-#define ISA_HAS_LXC1_SXC1      ISA_HAS_FP4
+#define ISA_HAS_LXC1_SXC1      (ISA_HAS_FP4                            \
+                                && mips_lxc1_sxc1)
 
 /* ISA has paired-single instructions.  */
 #define ISA_HAS_PAIRED_SINGLE  ((ISA_MIPS64                            \
index 2559649ffc53b19cd28a8955f7f7c53db60a1fc6..75ebafdba26949b1bad3f6e174ddf097709b96d2 100644 (file)
@@ -388,6 +388,10 @@ mlra
 Target Report Var(mips_lra_flag) Init(1) Save
 Use LRA instead of reload.
 
+mlxc1-sxc1
+Target Report Var(mips_lxc1_sxc1) Init(1)
+Use lwxc1/swxc1/ldxc1/sdxc1 instructions where applicable.
+
 mtune=
 Target RejectNegative Joined Var(mips_tune_option) ToLower Enum(mips_arch_opt_value)
 -mtune=PROCESSOR       Optimize the output for PROCESSOR.
index 4793ef85b0d9720dd4ef0c7f4b320a01af79dc9b..712b82a1442a64e65311d752f7b07029293a99b7 100644 (file)
@@ -1375,6 +1375,25 @@ On MIPS targets, make @option{-msynci} the default when no
 On MIPS targets, make @option{-mno-synci} the default when no
 @option{-msynci} option is passed.  This is the default.
 
+@item --with-lxc1-sxc1
+On MIPS targets, make @option{-mlxc1-sxc1} the default when no
+@option{-mno-lxc1-sxc1} option is passed.  This is the default.
+
+@item --without-lxc1-sxc1
+On MIPS targets, make @option{-mno-lxc1-sxc1} the default when no
+@option{-mlxc1-sxc1} option is passed.  The indexed load/store
+instructions are not directly a problem but can lead to unexpected
+behaviour when deployed in an application intended for a 32-bit address
+space but run on a 64-bit processor.  The issue is seen because all
+known MIPS 64-bit Linux kernels execute o32 and n32 applications
+with 64-bit addressing enabled which affects the overflow behaviour
+of the indexed addressing mode.  GCC will assume that ordinary
+32-bit arithmetic overflow behaviour is the same whether performed
+as an @code{addu} instruction or as part of the address calculation
+in @code{lwxc1} type instructions.  This assumption holds true in a
+pure 32-bit environment and can hold true in a 64-bit environment if
+the address space is accurately set to be 32-bit for o32 and n32.
+
 @item --with-mips-plt
 On MIPS targets, make use of copy relocations and PLTs.
 These features are extensions to the traditional
index 82cb1b5751feda4d331cf8efe130cbac2ba8d62f..a13a450b1ee25c7f1e1ec1ca286fb90d7c184107 100644 (file)
@@ -19932,6 +19932,12 @@ it is unused.
 
 This optimization is off by default at all optimization levels.
 
+@item -mlxc1-sxc1
+@itemx -mno-lxc1-sxc1
+@opindex mlxc1-sxc1
+When applicable, enable (disable) the generation of @code{lwxc1},
+@code{swxc1}, @code{ldxc1}, @code{sdxc1} instructions.  Enabled by default.
+
 @end table
 
 @node MMIX Options
index e0e0bd5432b4054c1ea96e432b9162d1d831551e..0ba8f93b6a889492ca5b86e9880d3cd06f96c583 100644 (file)
@@ -1,3 +1,14 @@
+2017-01-19  Matthew Fortune  <matthew.fortune@imgtec.com>
+
+       PR target/78176
+       * gcc.target/mips/lxc1-sxc1-1.c: New file.
+       * gcc.target/mips/lxc1-sxc1-2.c: Likewise.
+       * gcc.target/mips/mips.exp (mips_option_groups): Add ghost option
+       HAS_LXC1.
+       (mips_option_groups): Add -m[no-]lxc1-sxc1.
+       (mips-dg-init): Detect default -mno-lxc1-sxc1.
+       (mips-dg-options): Handle HAS_LXC1 arch upgrade/downgrade.
+
 2017-01-19  Andre Vehreschild  <vehre@gcc.gnu.org>
 
        PR fortran/70696
diff --git a/gcc/testsuite/gcc.target/mips/lxc1-sxc1-1.c b/gcc/testsuite/gcc.target/mips/lxc1-sxc1-1.c
new file mode 100644 (file)
index 0000000..f455eb8
--- /dev/null
@@ -0,0 +1,60 @@
+/* { dg-options "(HAS_LXC1) -mno-lxc1-sxc1" } */
+/* { dg-final { scan-assembler-not "\tldxc1\t" } } */
+/* { dg-final { scan-assembler-not "\tsdxc1\t" } } */
+
+#ifndef __mips_no_lxc1_sxc1
+#error missing definition of __mips_no_lxc1_sxc1
+#endif
+
+double ldexp(double x, int exp);
+
+typedef struct
+{
+  double** rows;
+} d_mat_struct;
+
+typedef d_mat_struct d_mat_t[1];
+
+#define d_mat_entry(mat,i,j) (*((mat)->rows[i] + (j)))
+
+double __attribute__((noinline))
+ldxc1_test (int kappa, int zeros, double ctt, int* expo, d_mat_t r, double* s)
+{
+  int kappa2 = kappa;
+  double tmp = 0.0;
+
+  do
+    {
+      kappa--;
+      if (kappa > zeros + 1)
+       {
+         tmp = d_mat_entry(r, kappa - 1, kappa - 1) * ctt;
+         tmp = ldexp(tmp, (expo[kappa - 1] - expo[kappa2]));
+       }
+    }
+  while ((kappa >= zeros + 2) && (s[kappa - 1] <= tmp));
+
+  return tmp;
+}
+
+#define SIZE 20
+
+int main(void)
+{
+  int kappa = SIZE - 1;
+  int zeros = 1;
+  double ctt = 2;
+
+  int expo[SIZE] = {0};
+  double s[SIZE] = {0};
+  double rows_data[SIZE][SIZE] = {0};
+  double* rows[SIZE];
+
+  for (int i = 0; i < SIZE; i++)
+    rows[i] = rows_data[i];
+
+  d_mat_t r = { rows };
+
+  ldxc1_test(kappa, zeros, ctt, expo, r, s);
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.target/mips/lxc1-sxc1-2.c b/gcc/testsuite/gcc.target/mips/lxc1-sxc1-2.c
new file mode 100644 (file)
index 0000000..dfbf6b5
--- /dev/null
@@ -0,0 +1,60 @@
+/* { dg-options "(HAS_LXC1) -mlxc1-sxc1" } */
+/* { dg-skip-if "code quality test" { *-*-* } { "-O0" } { "" } } */
+/* { dg-final { scan-assembler "\tldxc1\t" } } */
+
+#ifdef __mips_no_lxc1_sxc1
+#error unexpected definition of __mips_no_lxc1_sxc1
+#endif
+
+double ldexp(double x, int exp);
+
+typedef struct
+{
+  double** rows;
+} d_mat_struct;
+
+typedef d_mat_struct d_mat_t[1];
+
+#define d_mat_entry(mat,i,j) (*((mat)->rows[i] + (j)))
+
+double __attribute__((noinline))
+ldxc1_test (int kappa, int zeros, double ctt, int* expo, d_mat_t r, double* s)
+{
+  int kappa2 = kappa;
+  double tmp = 0.0;
+
+  do
+    {
+      kappa--;
+      if (kappa > zeros + 1)
+       {
+         tmp = d_mat_entry(r, kappa - 1, kappa - 1) * ctt;
+         tmp = ldexp(tmp, (expo[kappa - 1] - expo[kappa2]));
+       }
+    }
+  while ((kappa >= zeros + 2) && (s[kappa - 1] <= tmp));
+
+  return tmp;
+}
+
+#define SIZE 20
+
+int main(void)
+{
+  int kappa = SIZE - 1;
+  int zeros = 1;
+  double ctt = 2;
+
+  int expo[SIZE] = {0};
+  double s[SIZE] = {0};
+  double rows_data[SIZE][SIZE] = {0};
+  double* rows[SIZE];
+
+  for (int i = 0; i < SIZE; i++)
+    rows[i] = rows_data[i];
+
+  d_mat_t r = { rows };
+
+  ldxc1_test(kappa, zeros, ctt, expo, r, s);
+  return 0;
+}
index b2f4e1824cc8314cb1fee3b0ae8af58695a83386..5296a15f616fedb839ff12289692bc4e6d653c28 100644 (file)
@@ -258,6 +258,7 @@ set mips_option_groups {
     madd "HAS_MADD"
     maddps "HAS_MADDPS"
     lsa "(|!)HAS_LSA"
+    lxc1 "HAS_LXC1"
     section_start "-Wl,--section-start=.*"
     frame-header "-mframe-header-opt|-mno-frame-header-opt"
     stack-protector "-fstack-protector"
@@ -282,6 +283,7 @@ foreach option {
     gpopt
     local-sdata
     long-calls
+    lxc1-sxc1
     paired-single
     plt
     shared
@@ -855,6 +857,12 @@ proc mips-dg-init {} {
            "-mno-smartmips",
            #endif
 
+           #ifdef __mips_no_lxc1_sxc1
+           "-mno-lxc1-sxc1",
+           #else
+           "-mlxc1-sxc1"
+           #endif
+
            #ifdef __mips_synci
            "-msynci",
            #else
@@ -1173,7 +1181,8 @@ proc mips-dg-options { args } {
        #
        #
        } elseif { $isa < 4
-                  && [mips_have_test_option_p options "HAS_MOVN"] } {
+                  && ([mips_have_test_option_p options "HAS_LXC1"]
+                      || [mips_have_test_option_p options "HAS_MOVN"]) } {
            mips_make_test_option options "-mips4"
         # We need MIPS III or higher for:
        #
@@ -1214,6 +1223,7 @@ proc mips-dg-options { args } {
                       || [mips_have_test_option_p options "-mfp32"]
                       || [mips_have_test_option_p options "-mfix-r10000"]
                       || [mips_have_test_option_p options "NOT_HAS_DMUL"]
+                      || [mips_have_test_option_p options "HAS_LXC1"]
                       || [mips_have_test_option_p options "HAS_MOVN"]
                       || [mips_have_test_option_p options "HAS_MADD"]
                       || [mips_have_test_option_p options "-mpaired-single"]