+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
#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
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)
{
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);
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
{
{ "-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;
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)
{
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);
&& !(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;
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;
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;
{
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",
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
Variable
HOST_WIDE_INT ix86_isa_flags_explicit
+; Additional target flags
+Variable
+int ix86_target_flags
+
TargetVariable
int recip_mask = RECIP_MASK_DEFAULT
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
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.
-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
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
+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
--- /dev/null
+/* { 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;
+}
--- /dev/null
+/* { 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;
+}
--- /dev/null
+/* { 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;
+}
--- /dev/null
+/* { 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;
+}
--- /dev/null
+/* { 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];
+}
--- /dev/null
+/* { 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" } */
+}
--- /dev/null
+/* { 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" } } */
--- /dev/null
+/* { 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;
+}
--- /dev/null
+/* { 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;
+}