diff mbox

PATCH: PR target/70738: Add -mgeneral-regs-only option

Message ID CAMe9rOpeTqvuA-cL8aJi9RBBxtNV-tqS7crskpy3GesuHSHxWA@mail.gmail.com
State New
Headers show

Commit Message

H.J. Lu May 13, 2016, 3 p.m. UTC
On Thu, May 12, 2016 at 10:54 AM, H.J. Lu <hjl.tools@gmail.com> wrote:
>>> Here is a patch to add
>>> -mgeneral-regs-only option to x86 backend.   We can update
>>> spec for interrupt handle to recommend compiling interrupt handler
>>> with -mgeneral-regs-only option and add a note for compiler
>>> implementers.
>>>
>>> OK for trunk if there is no regression?
>>
>>
>> I can't comment on the code patch, but for the documentation part:
>>
>>> @@ -24242,6 +24242,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 which uses only the general-purpose registers.  This will
>>
>>
>> s/which/that/
>>
>>> +prevent the compiler from using floating-point, vector, mask and bound
>>
>>
>> s/will prevent/prevents/
>>
>>> +registers, but will not impose any restrictions on the assembler.
>>
>>
>> Maybe you mean to say "does not restrict use of those registers in inline
>> assembly code"?  In any case, please get rid of the future tense here, too.
>
> I changed it to
>
> ---
> @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.
> ---
>

Here is the updated patch.  Tested on x86-64.  OK for trunk?

Thanks.

Comments

Uros Bizjak May 20, 2016, 3:50 p.m. UTC | #1
On Fri, May 13, 2016 at 5:00 PM, H.J. Lu <hjl.tools@gmail.com> wrote:
> On Thu, May 12, 2016 at 10:54 AM, H.J. Lu <hjl.tools@gmail.com> wrote:
>>>> Here is a patch to add
>>>> -mgeneral-regs-only option to x86 backend.   We can update
>>>> spec for interrupt handle to recommend compiling interrupt handler
>>>> with -mgeneral-regs-only option and add a note for compiler
>>>> implementers.
>>>>
>>>> OK for trunk if there is no regression?
>>>
>>>
>>> I can't comment on the code patch, but for the documentation part:
>>>
>>>> @@ -24242,6 +24242,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 which uses only the general-purpose registers.  This will
>>>
>>>
>>> s/which/that/
>>>
>>>> +prevent the compiler from using floating-point, vector, mask and bound
>>>
>>>
>>> s/will prevent/prevents/
>>>
>>>> +registers, but will not impose any restrictions on the assembler.
>>>
>>>
>>> Maybe you mean to say "does not restrict use of those registers in inline
>>> assembly code"?  In any case, please get rid of the future tense here, too.
>>
>> I changed it to
>>
>> ---
>> @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.
>> ---
>>
>
> Here is the updated patch.  Tested on x86-64.  OK for trunk?

OK.

Thanks,
Uros.
Sandra Loosemore May 20, 2016, 4:29 p.m. UTC | #2
On 05/13/2016 09:00 AM, H.J. Lu wrote:
>>
>> I changed it to
>>
>> ---
>> @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.
>> ---
>>
>
> Here is the updated patch.  Tested on x86-64.  OK for trunk?

The documentation looks OK now.

-Sandra
Rainer Orth May 20, 2016, 5:15 p.m. UTC | #3
"H.J. Lu" <hjl.tools@gmail.com> writes:

> On Thu, May 12, 2016 at 10:54 AM, H.J. Lu <hjl.tools@gmail.com> wrote:
>>>> Here is a patch to add
>>>> -mgeneral-regs-only option to x86 backend.   We can update
>>>> spec for interrupt handle to recommend compiling interrupt handler
>>>> with -mgeneral-regs-only option and add a note for compiler
>>>> implementers.
>>>>
>>>> OK for trunk if there is no regression?
>>>
>>>
>>> I can't comment on the code patch, but for the documentation part:
>>>
>>>> @@ -24242,6 +24242,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 which uses only the general-purpose registers.  This will
>>>
>>>
>>> s/which/that/
>>>
>>>> +prevent the compiler from using floating-point, vector, mask and bound
>>>
>>>
>>> s/will prevent/prevents/
>>>
>>>> +registers, but will not impose any restrictions on the assembler.
>>>
>>>
>>> Maybe you mean to say "does not restrict use of those registers in inline
>>> assembly code"?  In any case, please get rid of the future tense here, too.
>>
>> I changed it to
>>
>> ---
>> @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.
>> ---
>>
>
> Here is the updated patch.  Tested on x86-64.  OK for trunk?

This patch broke {i386,x86_64}-apple-darwin15.5.0 bootstrap:

In file included from ./tm.h:16:0,
                 from /vol/gcc/src/hg/trunk/local/gcc/genattrtab.c:108:
./options.h:5443:2: error: #error too many target masks
 #error too many target masks
  ^
Makefile:2497: recipe for target 'build/genattrtab.o' failed
make[3]: *** [build/genattrtab.o] Error 1

options.h has

#define OPTION_MASK_ISA_XSAVES (HOST_WIDE_INT_1 << 62)
#error too many target masks

The tree bootstraps just fine at the previous revision.

	Rainer
diff mbox

Patch

From 1432847f8d2e00fe8ff85e9cdb61abbed0202cb4 Mon Sep 17 00:00:00 2001
From: "H.J. Lu" <hjl.tools@gmail.com>
Date: Wed, 11 May 2016 09:49:33 -0700
Subject: [PATCH] Add -mgeneral-regs-only option

X86 Linux kernel is compiled only with integer instructions.  Currently,

-mno-sse -mno-mmx -mno-sse2 -mno-3dnow -mno-avx -mno-80387
-mno-fp-ret-in-387  -mskip-rax-setup

is used to compile kernel.  If we add another non-integer feature, it
has to be turned off.  We can add a -mgeneral-regs-only option, similar
to AArch64, to disable all non-integer features so that kernel doesn't
need a long list and the same option will work for future compilers.
It can also be used to compile interrupt handler.

gcc/

	PR target/70738
	* common/config/i386/i386-common.c
	(OPTION_MASK_ISA_GENERAL_REGS_ONLY_UNSET): New.
	(ix86_handle_option): Disable MPX, MMX, SSE and x87 instructions
	for -mgeneral-regs-only.
	* config/i386/i386.c (ix86_option_override_internal): Don't
	enable x87 instructions if only the general registers are
	allowed.
	* config/i386/i386.opt: Add -mgeneral-regs-only.
	* doc/invoke.texi: Document -mgeneral-regs-only.

gcc/testsuite/

	PR target/70738
	* gcc.target/i386/pr70738-1.c: Likewise.
	* 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.
---
 gcc/common/config/i386/i386-common.c      | 20 ++++++++++++++++++++
 gcc/config/i386/i386.c                    |  5 ++++-
 gcc/config/i386/i386.opt                  |  4 ++++
 gcc/doc/invoke.texi                       |  8 +++++++-
 gcc/testsuite/gcc.target/i386/pr70738-1.c |  9 +++++++++
 gcc/testsuite/gcc.target/i386/pr70738-2.c | 10 ++++++++++
 gcc/testsuite/gcc.target/i386/pr70738-3.c | 11 +++++++++++
 gcc/testsuite/gcc.target/i386/pr70738-4.c | 10 ++++++++++
 gcc/testsuite/gcc.target/i386/pr70738-5.c | 16 ++++++++++++++++
 gcc/testsuite/gcc.target/i386/pr70738-6.c | 10 ++++++++++
 gcc/testsuite/gcc.target/i386/pr70738-7.c | 13 +++++++++++++
 gcc/testsuite/gcc.target/i386/pr70738-8.c | 30 ++++++++++++++++++++++++++++++
 gcc/testsuite/gcc.target/i386/pr70738-9.c | 23 +++++++++++++++++++++++
 13 files changed, 167 insertions(+), 2 deletions(-)
 create mode 100644 gcc/testsuite/gcc.target/i386/pr70738-1.c
 create mode 100644 gcc/testsuite/gcc.target/i386/pr70738-2.c
 create mode 100644 gcc/testsuite/gcc.target/i386/pr70738-3.c
 create mode 100644 gcc/testsuite/gcc.target/i386/pr70738-4.c
 create mode 100644 gcc/testsuite/gcc.target/i386/pr70738-5.c
 create mode 100644 gcc/testsuite/gcc.target/i386/pr70738-6.c
 create mode 100644 gcc/testsuite/gcc.target/i386/pr70738-7.c
 create mode 100644 gcc/testsuite/gcc.target/i386/pr70738-8.c
 create mode 100644 gcc/testsuite/gcc.target/i386/pr70738-9.c

diff --git a/gcc/common/config/i386/i386-common.c b/gcc/common/config/i386/i386-common.c
index cc65c8c..b150c9e 100644
--- a/gcc/common/config/i386/i386-common.c
+++ b/gcc/common/config/i386/i386-common.c
@@ -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,21 @@  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 the
+	     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)
 	{
diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c
index 501e26f..63c61be 100644
--- a/gcc/config/i386/i386.c
+++ b/gcc/config/i386/i386.c
@@ -5331,7 +5331,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 the general registers
+	   are allowed.  */
+	if (!(opts_set->x_target_flags & 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;
diff --git a/gcc/config/i386/i386.opt b/gcc/config/i386/i386.opt
index 36dd4bd..d12b29a 100644
--- a/gcc/config/i386/i386.opt
+++ b/gcc/config/i386/i386.opt
@@ -897,3 +897,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) Save
+Generate code which uses only the general registers.
diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi
index 8f35f47..7538601 100644
--- a/gcc/doc/invoke.texi
+++ b/gcc/doc/invoke.texi
@@ -1172,7 +1172,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
@@ -24272,6 +24272,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
diff --git a/gcc/testsuite/gcc.target/i386/pr70738-1.c b/gcc/testsuite/gcc.target/i386/pr70738-1.c
new file mode 100644
index 0000000..19381c2
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr70738-1.c
@@ -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
index 0000000..8b90904
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr70738-2.c
@@ -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
index 0000000..1ac3adb
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr70738-3.c
@@ -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
index 0000000..c6d20f2
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr70738-4.c
@@ -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
index 0000000..8b43809
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr70738-5.c
@@ -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
index 0000000..3bccabb
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr70738-6.c
@@ -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
index 0000000..2e5b49f
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr70738-7.c
@@ -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
index 0000000..0740460
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr70738-8.c
@@ -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
index 0000000..c71f0b0
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr70738-9.c
@@ -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;
+}
-- 
2.5.5