re PR target/70738 (Add -mgeneral-regs-only option)
authorUros Bizjak <uros@gcc.gnu.org>
Wed, 25 May 2016 18:58:49 +0000 (20:58 +0200)
committerUros Bizjak <uros@gcc.gnu.org>
Wed, 25 May 2016 18:58:49 +0000 (20:58 +0200)
PR target/70738
* common/config/i386/i386-common.c
(OPTION_MASK_ISA_GENERAL_REGS_ONLY_UNSET): New.
(ix86_handle_option) <case OPT_mgeneral_regs_only>: Disable
MPX, MMX, SSE and x87 instructions for -mgeneral-regs-only.
* config/i386/i386.opt (ix86_target_flags): Add new Variable.
(-mgeneral-regs-only): Add new option.
* config/i386/i386.c (ix86_option_override_internal): Don't enable
x87 instructions if only general registers are allowed.
(ix86_target_string): Add ix86_flags argument. Handle additional
flags options through ix86_flags argument.  Update all callers.
* doc/invoke.texi: Document -mgeneral-regs-only.

testsuite/ChangeLog:

PR target/70738
* gcc.target/i386/pr70738-1.c: New test.
* gcc.target/i386/pr70738-2.c: Likewise.
* gcc.target/i386/pr70738-3.c: Likewise.
* gcc.target/i386/pr70738-4.c: Likewise.
* gcc.target/i386/pr70738-5.c: Likewise.
* gcc.target/i386/pr70738-6.c: Likewise.
* gcc.target/i386/pr70738-7.c: Likewise.
* gcc.target/i386/pr70738-8.c: Likewise.
* gcc.target/i386/pr70738-9.c: Likewise.

From-SVN: r236738

15 files changed:
gcc/ChangeLog
gcc/common/config/i386/i386-common.c
gcc/config/i386/i386.c
gcc/config/i386/i386.opt
gcc/doc/invoke.texi
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.target/i386/pr70738-1.c [new file with mode: 0644]
gcc/testsuite/gcc.target/i386/pr70738-2.c [new file with mode: 0644]
gcc/testsuite/gcc.target/i386/pr70738-3.c [new file with mode: 0644]
gcc/testsuite/gcc.target/i386/pr70738-4.c [new file with mode: 0644]
gcc/testsuite/gcc.target/i386/pr70738-5.c [new file with mode: 0644]
gcc/testsuite/gcc.target/i386/pr70738-6.c [new file with mode: 0644]
gcc/testsuite/gcc.target/i386/pr70738-7.c [new file with mode: 0644]
gcc/testsuite/gcc.target/i386/pr70738-8.c [new file with mode: 0644]
gcc/testsuite/gcc.target/i386/pr70738-9.c [new file with mode: 0644]

index 92f094b5655d94947be5291d872af794920ee7da..0172c8ba1546210d84470c87f3666c85b81a8038 100644 (file)
@@ -1,3 +1,27 @@
+2016-05-25  Uros Bizjak  <ubizjak@gmail.com>
+
+       * config/i386/i386.opt (ix86_target_flags_explicit): Remove.
+       (x_ix86_target_flags_explicit): Remove.
+       * config/i386/i386.c (ix86_function_specific_save): Do not copy
+       x_ix86_target_flags_explicit.
+       (ix86_function_specific_restore): Ditto.
+
+2016-05-25  Uros Bizjak  <ubizjak@gmail.com>
+           H.J. Lu  <hongjiu.lu@intel.com>
+
+       PR target/70738
+       * common/config/i386/i386-common.c
+       (OPTION_MASK_ISA_GENERAL_REGS_ONLY_UNSET): New.
+       (ix86_handle_option) <case OPT_mgeneral_regs_only>: Disable
+       MPX, MMX, SSE and x87 instructions for -mgeneral-regs-only.
+       * config/i386/i386.opt (ix86_target_flags): Add new Variable.
+       (-mgeneral-regs-only): Add new option.
+       * config/i386/i386.c (ix86_option_override_internal): Don't enable
+       x87 instructions if only general registers are allowed.
+       (ix86_target_string): Add ix86_flags argument. Handle additional
+       flags options through ix86_flags argument.  Update all callers.
+       * doc/invoke.texi: Document -mgeneral-regs-only.
+
 2016-05-25  Kyrylo Tkachov  <kyrylo.tkachov@arm.com>
 
        PR rtl-optimization/66940
index cc65c8c8a514933f26fc5c9b49ddf08fd2ebce97..4f0a55fee66da5e0adab91cdd89719807da33014 100644 (file)
@@ -223,6 +223,11 @@ along with GCC; see the file COPYING3.  If not see
 #define OPTION_MASK_ISA_RDRND_UNSET OPTION_MASK_ISA_RDRND
 #define OPTION_MASK_ISA_F16C_UNSET OPTION_MASK_ISA_F16C
 
+#define OPTION_MASK_ISA_GENERAL_REGS_ONLY_UNSET \
+  (OPTION_MASK_ISA_MMX_UNSET \
+   | OPTION_MASK_ISA_SSE_UNSET \
+   | OPTION_MASK_ISA_MPX)
+
 /* Implement TARGET_HANDLE_OPTION.  */
 
 bool
@@ -236,6 +241,22 @@ ix86_handle_option (struct gcc_options *opts,
 
   switch (code)
     {
+    case OPT_mgeneral_regs_only:
+      if (value)
+       {
+         /* Disable MPX, MMX, SSE and x87 instructions if only
+            general registers are allowed.  */
+         opts->x_ix86_isa_flags
+           &= ~OPTION_MASK_ISA_GENERAL_REGS_ONLY_UNSET;
+         opts->x_ix86_isa_flags_explicit
+           |= OPTION_MASK_ISA_GENERAL_REGS_ONLY_UNSET;
+
+         opts->x_target_flags &= ~MASK_80387;
+       }
+      else
+       gcc_unreachable ();
+      return true;
+
     case OPT_mmmx:
       if (value)
        {
index 9a75bed92d097826b6745a756a4897ec30fc799c..7e9f51148f5000e216980e5dd11934a2771f14e7 100644 (file)
@@ -2586,7 +2586,7 @@ enum ix86_function_specific_strings
   IX86_FUNCTION_SPECIFIC_MAX
 };
 
-static char *ix86_target_string (HOST_WIDE_INT, int, const char *,
+static char *ix86_target_string (HOST_WIDE_INT, int, int, const char *,
                                 const char *, enum fpmath_unit, bool);
 static void ix86_function_specific_save (struct cl_target_option *,
                                         struct gcc_options *opts);
@@ -4084,9 +4084,9 @@ ix86_using_red_zone (void)
    responsible for freeing the string.  */
 
 static char *
-ix86_target_string (HOST_WIDE_INT isa, int flags, const char *arch,
-                   const char *tune, enum fpmath_unit fpmath,
-                   bool add_nl_p)
+ix86_target_string (HOST_WIDE_INT isa, int flags, int ix86_flags,
+                   const char *arch, const char *tune,
+                   enum fpmath_unit fpmath, bool add_nl_p)
 {
   struct ix86_target_opts
   {
@@ -4189,10 +4189,18 @@ ix86_target_string (HOST_WIDE_INT isa, int flags, const char *arch,
     { "-mprefer-avx128",               MASK_PREFER_AVX128},
   };
 
-  const char *opts[ARRAY_SIZE (isa_opts) + ARRAY_SIZE (flag_opts) + 6][2];
+  /* Additional flag options.  */
+  static struct ix86_target_opts ix86_flag_opts[] =
+  {
+    { "-mgeneral-regs-only",           OPTION_MASK_GENERAL_REGS_ONLY },
+  };
+
+  const char *opts[ARRAY_SIZE (isa_opts) + ARRAY_SIZE (flag_opts)
+                  + ARRAY_SIZE (ix86_flag_opts) + 6][2];
 
   char isa_other[40];
   char target_other[40];
+  char ix86_target_other[40];
   unsigned num = 0;
   unsigned i, j;
   char *ret;
@@ -4266,6 +4274,22 @@ ix86_target_string (HOST_WIDE_INT isa, int flags, const char *arch,
       sprintf (target_other, "(other flags: %#x)", flags);
     }
 
+    /* Add additional flag options.  */
+  for (i = 0; i < ARRAY_SIZE (ix86_flag_opts); i++)
+    {
+      if ((ix86_flags & ix86_flag_opts[i].mask) != 0)
+       {
+         opts[num++][0] = ix86_flag_opts[i].option;
+         ix86_flags &= ~ ix86_flag_opts[i].mask;
+       }
+    }
+
+  if (ix86_flags && add_nl_p)
+    {
+      opts[num++][0] = ix86_target_other;
+      sprintf (ix86_target_other, "(other flags: %#x)", ix86_flags);
+    }
+
   /* Add -fpmath= option.  */
   if (fpmath)
     {
@@ -4360,6 +4384,7 @@ void ATTRIBUTE_UNUSED
 ix86_debug_options (void)
 {
   char *opts = ix86_target_string (ix86_isa_flags, target_flags,
+                                  ix86_target_flags,
                                   ix86_arch_string, ix86_tune_string,
                                   ix86_fpmath, true);
 
@@ -5337,7 +5362,10 @@ ix86_option_override_internal (bool main_args_p,
            && !(opts->x_ix86_isa_flags_explicit & OPTION_MASK_ISA_PKU))
          opts->x_ix86_isa_flags |= OPTION_MASK_ISA_PKU;
 
-       if (!(opts_set->x_target_flags & MASK_80387))
+       /* Don't enable x87 instructions if only
+          general registers are allowed.  */
+       if (!(opts_set->x_ix86_target_flags & OPTION_MASK_GENERAL_REGS_ONLY)
+           && !(opts_set->x_target_flags & MASK_80387))
          {
            if (processor_alias_table[i].flags & PTA_NO_80387)
              opts->x_target_flags &= ~MASK_80387;
@@ -6075,7 +6103,6 @@ ix86_function_specific_save (struct cl_target_option *ptr,
   ptr->tune_defaulted = ix86_tune_defaulted;
   ptr->arch_specified = ix86_arch_specified;
   ptr->x_ix86_isa_flags_explicit = opts->x_ix86_isa_flags_explicit;
-  ptr->x_ix86_target_flags_explicit = opts->x_ix86_target_flags_explicit;
   ptr->x_recip_mask_explicit = opts->x_recip_mask_explicit;
   ptr->x_ix86_arch_string = opts->x_ix86_arch_string;
   ptr->x_ix86_tune_string = opts->x_ix86_tune_string;
@@ -6132,7 +6159,6 @@ ix86_function_specific_restore (struct gcc_options *opts,
   ix86_tune_defaulted = ptr->tune_defaulted;
   ix86_arch_specified = ptr->arch_specified;
   opts->x_ix86_isa_flags_explicit = ptr->x_ix86_isa_flags_explicit;
-  opts->x_ix86_target_flags_explicit = ptr->x_ix86_target_flags_explicit;
   opts->x_recip_mask_explicit = ptr->x_recip_mask_explicit;
   opts->x_ix86_arch_string = ptr->x_ix86_arch_string;
   opts->x_ix86_tune_string = ptr->x_ix86_tune_string;
@@ -6239,7 +6265,8 @@ ix86_function_specific_print (FILE *file, int indent,
 {
   char *target_string
     = ix86_target_string (ptr->x_ix86_isa_flags, ptr->x_target_flags,
-                         NULL, NULL, ptr->x_ix86_fpmath, false);
+                         ptr->x_ix86_target_flags, NULL, NULL,
+                         ptr->x_ix86_fpmath, false);
 
   gcc_assert (ptr->arch < PROCESSOR_max);
   fprintf (file, "%*sarch = %d (%s)\n",
@@ -40593,9 +40620,9 @@ ix86_expand_builtin (tree exp, rtx target, rtx subtarget,
   if (ix86_builtins_isa[fcode].isa
       && !(ix86_builtins_isa[fcode].isa & ix86_isa_flags))
     {
-      char *opts = ix86_target_string (ix86_builtins_isa[fcode].isa, 0, NULL,
-                                      NULL, (enum fpmath_unit) 0, false);
-
+      char *opts = ix86_target_string (ix86_builtins_isa[fcode].isa, 0, 0,
+                                      NULL, NULL, (enum fpmath_unit) 0,
+                                      false);
       if (!opts)
        error ("%qE needs unknown isa option", fndecl);
       else
index 36dd4bd1572c582a8b69e100aeedacdf2d86eb13..4b75ba8911a6bd1a33abe0c28a0c7986fd497629 100644 (file)
@@ -30,6 +30,10 @@ HOST_WIDE_INT ix86_isa_flags = TARGET_64BIT_DEFAULT | TARGET_SUBTARGET_ISA_DEFAU
 Variable
 HOST_WIDE_INT ix86_isa_flags_explicit
 
+; Additional target flags
+Variable
+int ix86_target_flags
+
 TargetVariable
 int recip_mask = RECIP_MASK_DEFAULT
 
@@ -72,14 +76,6 @@ unsigned char branch_cost
 TargetSave
 HOST_WIDE_INT x_ix86_isa_flags_explicit
 
-;; which flags were passed by the user
-Variable
-int ix86_target_flags_explicit
-
-;; which flags were passed by the user
-TargetSave
-HOST_WIDE_INT x_ix86_target_flags_explicit
-
 ;; whether -mtune was not specified
 TargetSave
 unsigned char tune_defaulted
@@ -897,3 +893,7 @@ Enum(stack_protector_guard) String(global) Value(SSP_GLOBAL)
 mmitigate-rop
 Target Var(flag_mitigate_rop) Init(0)
 Attempt to avoid generating instruction sequences containing ret bytes.
+
+mgeneral-regs-only
+Target Report RejectNegative Mask(GENERAL_REGS_ONLY) Var(ix86_target_flags) Save
+Generate code which uses only the general registers.
index d2dfdd9914f951457749fc01d042780e83d08086..9e921335c3edcf7e12387a602f0f6e203f4335d2 100644 (file)
@@ -1173,7 +1173,7 @@ See RS/6000 and PowerPC Options.
 -msse2avx -mfentry -mrecord-mcount -mnop-mcount -m8bit-idiv @gol
 -mavx256-split-unaligned-load -mavx256-split-unaligned-store @gol
 -malign-data=@var{type} -mstack-protector-guard=@var{guard} @gol
--mmitigate-rop}
+-mmitigate-rop -mgeneral-regs-only}
 
 @emph{x86 Windows Options}
 @gccoptlist{-mconsole -mcygwin -mno-cygwin -mdll @gol
@@ -24298,6 +24298,12 @@ opcodes, to mitigate against certain forms of attack. At the moment,
 this option is limited in what it can do and should not be relied
 on to provide serious protection.
 
+@item -mgeneral-regs-only
+@opindex mgeneral-regs-only
+Generate code that uses only the general-purpose registers.  This
+prevents the compiler from using floating-point, vector, mask and bound
+registers.
+
 @end table
 
 These @samp{-m} switches are supported in addition to the above
index fb7713d32559ed4cc7cd0c88b42f124695a4066b..d7b3796ff3bccd72b4c2a057907d78b1c850c0d3 100644 (file)
@@ -1,3 +1,16 @@
+2016-05-25  H.J. Lu  <hongjiu.lu@intel.com>
+
+       PR target/70738
+       * gcc.target/i386/pr70738-1.c: New test.
+       * gcc.target/i386/pr70738-2.c: Likewise.
+       * gcc.target/i386/pr70738-3.c: Likewise.
+       * gcc.target/i386/pr70738-4.c: Likewise.
+       * gcc.target/i386/pr70738-5.c: Likewise.
+       * gcc.target/i386/pr70738-6.c: Likewise.
+       * gcc.target/i386/pr70738-7.c: Likewise.
+       * gcc.target/i386/pr70738-8.c: Likewise.
+       * gcc.target/i386/pr70738-9.c: Likewise.
+
 2016-05-25  Kyrylo Tkachov  <kyrylo.tkachov@arm.com>
 
        PR rtl-optimization/66940
diff --git a/gcc/testsuite/gcc.target/i386/pr70738-1.c b/gcc/testsuite/gcc.target/i386/pr70738-1.c
new file mode 100644 (file)
index 0000000..19381c2
--- /dev/null
@@ -0,0 +1,9 @@
+/* { dg-do compile { target { ! ia32 } } } */
+/* { dg-options "-msse2 -mgeneral-regs-only" } */
+
+typedef int int32x2_t __attribute__ ((__vector_size__ ((8))));
+
+int32x2_t test (int32x2_t a, int32x2_t b)
+{ /* { dg-error "SSE register return with SSE disabled" } */
+  return a + b;
+}
diff --git a/gcc/testsuite/gcc.target/i386/pr70738-2.c b/gcc/testsuite/gcc.target/i386/pr70738-2.c
new file mode 100644 (file)
index 0000000..8b90904
--- /dev/null
@@ -0,0 +1,10 @@
+/* { dg-do compile { target ia32 } } */
+/* { dg-options "-mmmx -mgeneral-regs-only" } */
+
+typedef int int32x2_t __attribute__ ((__vector_size__ ((8))));
+
+int32x2_t
+test (int32x2_t a, int32x2_t b) /* { dg-warning "MMX vector argument without MMX enabled" } */
+{ /* { dg-warning "MMX vector return without MMX enabled" } */
+  return a + b;
+}
diff --git a/gcc/testsuite/gcc.target/i386/pr70738-3.c b/gcc/testsuite/gcc.target/i386/pr70738-3.c
new file mode 100644 (file)
index 0000000..1ac3adb
--- /dev/null
@@ -0,0 +1,11 @@
+/* { dg-do compile } */
+/* { dg-options "-msse2 -mgeneral-regs-only" } */
+
+typedef int int32x4_t __attribute__ ((__vector_size__ ((16))));
+extern int32x4_t c;
+
+void
+test (int32x4_t a, int32x4_t b) /* { dg-warning "SSE vector argument without SSE enabled" } */
+{
+  c = a + b;
+}
diff --git a/gcc/testsuite/gcc.target/i386/pr70738-4.c b/gcc/testsuite/gcc.target/i386/pr70738-4.c
new file mode 100644 (file)
index 0000000..c6d20f2
--- /dev/null
@@ -0,0 +1,10 @@
+/* { dg-do compile { target ia32 } } */
+/* { dg-options "-msse2 -mgeneral-regs-only" } */
+
+typedef int int32x4_t __attribute__ ((__vector_size__ ((16))));
+
+int32x4_t
+test (int32x4_t a, int32x4_t b) /* { dg-warning "SSE vector argument without SSE enabled" } */
+{ /* { dg-warning "SSE vector return without SSE enabled" } */
+  return a + b;
+}
diff --git a/gcc/testsuite/gcc.target/i386/pr70738-5.c b/gcc/testsuite/gcc.target/i386/pr70738-5.c
new file mode 100644 (file)
index 0000000..8b43809
--- /dev/null
@@ -0,0 +1,16 @@
+/* { dg-do compile { target { ! ia32 } } } */
+/* { dg-options "-msse2 -mgeneral-regs-only" } */
+
+#include <stdarg.h>
+
+typedef int int32x2_t __attribute__ ((__vector_size__ ((8))));
+
+int
+test (int i, ...)
+{
+  va_list argp;
+  va_start (argp, i);
+  int32x2_t x = (int32x2_t) {0, 1};
+  x += va_arg (argp, int32x2_t); /* { dg-error "SSE register argument with SSE disabled" } */
+  return x[0] + x[1];
+}
diff --git a/gcc/testsuite/gcc.target/i386/pr70738-6.c b/gcc/testsuite/gcc.target/i386/pr70738-6.c
new file mode 100644 (file)
index 0000000..3bccabb
--- /dev/null
@@ -0,0 +1,10 @@
+/* { dg-do compile { target { ! ia32 } } } */
+/* { dg-options "-msse2 -mgeneral-regs-only" } */
+
+extern float a, b, c;
+
+void
+foo (void)
+{
+  c = a * b; /* { dg-error "SSE register return with SSE disabled" } */
+}
diff --git a/gcc/testsuite/gcc.target/i386/pr70738-7.c b/gcc/testsuite/gcc.target/i386/pr70738-7.c
new file mode 100644 (file)
index 0000000..2e5b49f
--- /dev/null
@@ -0,0 +1,13 @@
+/* { dg-do compile { target ia32 } } */
+/* { dg-options "-msse2 -mgeneral-regs-only" } */
+
+extern float a, b, c;
+
+void
+foo (void)
+{
+  c = a * b;
+}
+
+/* { dg-final { scan-assembler-not "mulss" } } */
+/* { dg-final { scan-assembler "call\[ \t\]__mulsf3" } } */
diff --git a/gcc/testsuite/gcc.target/i386/pr70738-8.c b/gcc/testsuite/gcc.target/i386/pr70738-8.c
new file mode 100644 (file)
index 0000000..0740460
--- /dev/null
@@ -0,0 +1,30 @@
+/* { dg-do run } */
+/* { dg-options "-O2 -mgeneral-regs-only" } */
+
+extern void abort ();
+
+int
+dec (int a, int b)
+{
+  return a + b;
+}
+
+int
+cal (int a, int b)
+{
+  int sum1 = a * b;
+  int sum2 = a / b;
+  int sum = dec (sum1, sum2);
+  return a + b + sum + sum1 + sum2;
+}
+
+int
+main (int argc, char **argv)
+{
+  int ret = cal (2, 1);
+
+  if (ret != 11)
+    abort ();
+
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.target/i386/pr70738-9.c b/gcc/testsuite/gcc.target/i386/pr70738-9.c
new file mode 100644 (file)
index 0000000..c71f0b0
--- /dev/null
@@ -0,0 +1,23 @@
+/* { dg-do run } */
+/* { dg-options "-O2 -mgeneral-regs-only" } */
+
+extern void abort ();
+
+int
+cal (int a, int b)
+{
+  int sum = a + b;
+  int sum1 = a * b;
+  return (a + b + sum + sum1);
+}
+
+int
+main (int argc, char **argv)
+{
+  int ret = cal (1, 2);
+
+  if (ret != 8)
+    abort ();
+
+  return 0;
+}