x86: Add target("general-regs-only") function attribute
gcc/ PR target/96744 * config/i386/i386-options.c (IX86_ATTR_IX86_YES): New. (IX86_ATTR_IX86_NO): Likewise. (ix86_opt_type): Add ix86_opt_ix86_yes and ix86_opt_ix86_no. (ix86_valid_target_attribute_inner_p): Handle general-regs-only, ix86_opt_ix86_yes and ix86_opt_ix86_no. (ix86_option_override_internal): Check opts->x_ix86_target_flags instead of opts->x_ix86_target_flags. * doc/extend.texi: Document target("general-regs-only") function attribute. gcc/testsuite/ PR target/96744 * gcc.target/i386/pr96744-1.c: New test. * gcc.target/i386/pr96744-2.c: Likewise. * gcc.target/i386/pr96744-3a.c: Likewise. * gcc.target/i386/pr96744-3b.c: Likewise. * gcc.target/i386/pr96744-4.c: Likewise. * gcc.target/i386/pr96744-5.c: Likewise. * gcc.target/i386/pr96744-6.c: Likewise. * gcc.target/i386/pr96744-7.c: Likewise. * gcc.target/i386/pr96744-8a.c: Likewise. * gcc.target/i386/pr96744-8b.c: Likewise. * gcc.target/i386/pr96744-9.c: Likewise.
This commit is contained in:
parent
dbc724d6d2
commit
87c753ac24
@ -922,12 +922,18 @@ ix86_valid_target_attribute_inner_p (tree fndecl, tree args, char *p_strings[],
|
||||
#define IX86_ATTR_ENUM(S,O) { S, sizeof (S)-1, ix86_opt_enum, O, 0 }
|
||||
#define IX86_ATTR_YES(S,O,M) { S, sizeof (S)-1, ix86_opt_yes, O, M }
|
||||
#define IX86_ATTR_NO(S,O,M) { S, sizeof (S)-1, ix86_opt_no, O, M }
|
||||
#define IX86_ATTR_IX86_YES(S,O,M) \
|
||||
{ S, sizeof (S)-1, ix86_opt_ix86_yes, O, M }
|
||||
#define IX86_ATTR_IX86_NO(S,O,M) \
|
||||
{ S, sizeof (S)-1, ix86_opt_ix86_no, O, M }
|
||||
|
||||
enum ix86_opt_type
|
||||
{
|
||||
ix86_opt_unknown,
|
||||
ix86_opt_yes,
|
||||
ix86_opt_no,
|
||||
ix86_opt_ix86_yes,
|
||||
ix86_opt_ix86_no,
|
||||
ix86_opt_str,
|
||||
ix86_opt_enum,
|
||||
ix86_opt_isa
|
||||
@ -1062,6 +1068,10 @@ ix86_valid_target_attribute_inner_p (tree fndecl, tree args, char *p_strings[],
|
||||
IX86_ATTR_YES ("recip",
|
||||
OPT_mrecip,
|
||||
MASK_RECIP),
|
||||
|
||||
IX86_ATTR_IX86_YES ("general-regs-only",
|
||||
OPT_mgeneral_regs_only,
|
||||
OPTION_MASK_GENERAL_REGS_ONLY),
|
||||
};
|
||||
|
||||
location_t loc
|
||||
@ -1175,6 +1185,33 @@ ix86_valid_target_attribute_inner_p (tree fndecl, tree args, char *p_strings[],
|
||||
opts->x_target_flags &= ~mask;
|
||||
}
|
||||
|
||||
else if (type == ix86_opt_ix86_yes || type == ix86_opt_ix86_no)
|
||||
{
|
||||
if (mask == OPTION_MASK_GENERAL_REGS_ONLY)
|
||||
{
|
||||
if (type != ix86_opt_ix86_yes)
|
||||
gcc_unreachable ();
|
||||
|
||||
opts->x_ix86_target_flags |= mask;
|
||||
|
||||
struct cl_decoded_option decoded;
|
||||
generate_option (opt, NULL, opt_set_p, CL_TARGET,
|
||||
&decoded);
|
||||
ix86_handle_option (opts, opts_set, &decoded,
|
||||
input_location);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (type == ix86_opt_ix86_no)
|
||||
opt_set_p = !opt_set_p;
|
||||
|
||||
if (opt_set_p)
|
||||
opts->x_ix86_target_flags |= mask;
|
||||
else
|
||||
opts->x_ix86_target_flags &= ~mask;
|
||||
}
|
||||
}
|
||||
|
||||
else if (type == ix86_opt_str)
|
||||
{
|
||||
if (p_strings[opt])
|
||||
@ -2260,9 +2297,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;
|
||||
|
||||
/* Don't enable x87 instructions if only
|
||||
general registers are allowed. */
|
||||
if (!(opts_set->x_ix86_target_flags & OPTION_MASK_GENERAL_REGS_ONLY)
|
||||
/* Don't enable x87 instructions if only general registers are
|
||||
allowed by target("general-regs-only") function attribute or
|
||||
-mgeneral-regs-only. */
|
||||
if (!(opts->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) != 0))
|
||||
|
@ -6656,6 +6656,10 @@ Enable/disable the generation of RCPSS, RCPPS, RSQRTSS and RSQRTPS
|
||||
instructions followed an additional Newton-Raphson step instead of
|
||||
doing a floating-point division.
|
||||
|
||||
@item general-regs-only
|
||||
@cindex @code{target("general-regs-only")} function attribute, x86
|
||||
Generate code which uses only the general registers.
|
||||
|
||||
@item arch=@var{ARCH}
|
||||
@cindex @code{target("arch=@var{ARCH}")} function attribute, x86
|
||||
Specify the architecture to generate code for in compiling the function.
|
||||
|
10
gcc/testsuite/gcc.target/i386/pr96744-1.c
Normal file
10
gcc/testsuite/gcc.target/i386/pr96744-1.c
Normal file
@ -0,0 +1,10 @@
|
||||
/* { dg-do compile { target { ! ia32 } } } */
|
||||
/* { dg-options "-msse2" } */
|
||||
|
||||
typedef int int32x2_t __attribute__ ((__vector_size__ ((8))));
|
||||
|
||||
__attribute__((__target__("general-regs-only")))
|
||||
int32x2_t test (int32x2_t a, int32x2_t b)
|
||||
{ /* { dg-error "SSE register return with SSE disabled" } */
|
||||
return a + b;
|
||||
}
|
11
gcc/testsuite/gcc.target/i386/pr96744-2.c
Normal file
11
gcc/testsuite/gcc.target/i386/pr96744-2.c
Normal file
@ -0,0 +1,11 @@
|
||||
/* { dg-do compile { target ia32 } } */
|
||||
/* { dg-options "-mmmx" } */
|
||||
|
||||
typedef int int32x2_t __attribute__ ((__vector_size__ ((8))));
|
||||
|
||||
__attribute__((__target__("general-regs-only")))
|
||||
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;
|
||||
}
|
12
gcc/testsuite/gcc.target/i386/pr96744-3a.c
Normal file
12
gcc/testsuite/gcc.target/i386/pr96744-3a.c
Normal file
@ -0,0 +1,12 @@
|
||||
/* { dg-do compile } */
|
||||
/* { dg-options "-msse2" } */
|
||||
|
||||
typedef int int32x4_t __attribute__ ((__vector_size__ ((16))));
|
||||
extern int32x4_t c;
|
||||
|
||||
__attribute__((__target__("general-regs-only")))
|
||||
void
|
||||
test (int32x4_t a, int32x4_t b) /* { dg-warning "SSE vector argument without SSE enabled" } */
|
||||
{
|
||||
c = a + b;
|
||||
}
|
16
gcc/testsuite/gcc.target/i386/pr96744-3b.c
Normal file
16
gcc/testsuite/gcc.target/i386/pr96744-3b.c
Normal file
@ -0,0 +1,16 @@
|
||||
/* { dg-do compile } */
|
||||
/* { dg-options "-msse2" } */
|
||||
|
||||
typedef int int32x4_t __attribute__ ((__vector_size__ ((16))));
|
||||
extern int32x4_t c;
|
||||
|
||||
#pragma GCC push_options
|
||||
#pragma GCC target("general-regs-only")
|
||||
|
||||
void
|
||||
test (int32x4_t a, int32x4_t b) /* { dg-warning "SSE vector argument without SSE enabled" } */
|
||||
{
|
||||
c = a + b;
|
||||
}
|
||||
|
||||
#pragma GCC pop_options
|
11
gcc/testsuite/gcc.target/i386/pr96744-4.c
Normal file
11
gcc/testsuite/gcc.target/i386/pr96744-4.c
Normal file
@ -0,0 +1,11 @@
|
||||
/* { dg-do compile { target ia32 } } */
|
||||
/* { dg-options "-msse2" } */
|
||||
|
||||
typedef int int32x4_t __attribute__ ((__vector_size__ ((16))));
|
||||
|
||||
__attribute__((__target__("general-regs-only")))
|
||||
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;
|
||||
}
|
17
gcc/testsuite/gcc.target/i386/pr96744-5.c
Normal file
17
gcc/testsuite/gcc.target/i386/pr96744-5.c
Normal file
@ -0,0 +1,17 @@
|
||||
/* { dg-do compile { target { ! ia32 } } } */
|
||||
/* { dg-options "-msse2" } */
|
||||
|
||||
#include <stdarg.h>
|
||||
|
||||
typedef int int32x2_t __attribute__ ((__vector_size__ ((8))));
|
||||
|
||||
__attribute__((__target__("general-regs-only")))
|
||||
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];
|
||||
}
|
11
gcc/testsuite/gcc.target/i386/pr96744-6.c
Normal file
11
gcc/testsuite/gcc.target/i386/pr96744-6.c
Normal file
@ -0,0 +1,11 @@
|
||||
/* { dg-do compile { target { ! ia32 } } } */
|
||||
/* { dg-options "-msse2 -mfpmath=sse" } */
|
||||
|
||||
extern float a, b, c;
|
||||
|
||||
__attribute__((__target__("general-regs-only")))
|
||||
void
|
||||
foo (void)
|
||||
{
|
||||
c = a * b; /* { dg-error "SSE register return with SSE disabled" } */
|
||||
}
|
14
gcc/testsuite/gcc.target/i386/pr96744-7.c
Normal file
14
gcc/testsuite/gcc.target/i386/pr96744-7.c
Normal file
@ -0,0 +1,14 @@
|
||||
/* { dg-do compile { target { ia32 && { ! *-*-darwin* } } } } */
|
||||
/* { dg-options "-msse2" } */
|
||||
|
||||
extern float a, b, c;
|
||||
|
||||
__attribute__((__target__("general-regs-only")))
|
||||
void
|
||||
foo (void)
|
||||
{
|
||||
c = a * b;
|
||||
}
|
||||
|
||||
/* { dg-final { scan-assembler-not "mulss" } } */
|
||||
/* { dg-final { scan-assembler "call\[ \t\]__mulsf3" } } */
|
33
gcc/testsuite/gcc.target/i386/pr96744-8a.c
Normal file
33
gcc/testsuite/gcc.target/i386/pr96744-8a.c
Normal file
@ -0,0 +1,33 @@
|
||||
/* { dg-do run } */
|
||||
/* { dg-options "-O2" } */
|
||||
|
||||
extern void abort ();
|
||||
|
||||
__attribute__((__target__("general-regs-only")))
|
||||
int
|
||||
dec (int a, int b)
|
||||
{
|
||||
return a + b;
|
||||
}
|
||||
|
||||
__attribute__((__target__("general-regs-only")))
|
||||
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;
|
||||
}
|
||||
|
||||
__attribute__((__target__("general-regs-only")))
|
||||
int
|
||||
main (int argc, char **argv)
|
||||
{
|
||||
int ret = cal (2, 1);
|
||||
|
||||
if (ret != 11)
|
||||
abort ();
|
||||
|
||||
return 0;
|
||||
}
|
35
gcc/testsuite/gcc.target/i386/pr96744-8b.c
Normal file
35
gcc/testsuite/gcc.target/i386/pr96744-8b.c
Normal file
@ -0,0 +1,35 @@
|
||||
/* { dg-do run } */
|
||||
/* { dg-options "-O2" } */
|
||||
|
||||
#pragma GCC push_options
|
||||
#pragma GCC target("general-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;
|
||||
}
|
||||
|
||||
#pragma GCC pop_options
|
25
gcc/testsuite/gcc.target/i386/pr96744-9.c
Normal file
25
gcc/testsuite/gcc.target/i386/pr96744-9.c
Normal file
@ -0,0 +1,25 @@
|
||||
/* { dg-do run } */
|
||||
/* { dg-options "-O2" } */
|
||||
|
||||
extern void abort ();
|
||||
|
||||
__attribute__((__target__("general-regs-only")))
|
||||
int
|
||||
cal (int a, int b)
|
||||
{
|
||||
int sum = a + b;
|
||||
int sum1 = a * b;
|
||||
return (a + b + sum + sum1);
|
||||
}
|
||||
|
||||
__attribute__((__target__("general-regs-only")))
|
||||
int
|
||||
main (int argc, char **argv)
|
||||
{
|
||||
int ret = cal (1, 2);
|
||||
|
||||
if (ret != 8)
|
||||
abort ();
|
||||
|
||||
return 0;
|
||||
}
|
Loading…
Reference in New Issue
Block a user