summaryrefslogtreecommitdiff
path: root/gcc/config
diff options
context:
space:
mode:
authoruros <uros@138bc75d-0d04-0410-961f-82ee72b054a4>2006-12-11 14:06:07 +0000
committeruros <uros@138bc75d-0d04-0410-961f-82ee72b054a4>2006-12-11 14:06:07 +0000
commitbae5345b3f2dcec67d0e46668b3c4a312e966bd5 (patch)
treeb84b83cd26e28436a111b54380af292b10b0f3c6 /gcc/config
parentca128b4e82bce6cb82fc7805baec971cd0befa38 (diff)
downloadgcc-bae5345b3f2dcec67d0e46668b3c4a312e966bd5.tar.gz
PR target/30120
Revert: 2006-11-15 Uros Bizjak <ubizjak@gmail.com> * config/i386/i386.opt: New target option -mx87regparm. * config/i386/i386.h (struct ix86_args): Add x87_nregs, x87_regno, float_in_x87: Add new variables. mmx_words, sse_words: Remove. (X87_REGPARM_MAX): Define. * config/i386/i386.c (override_options): Error out for -mx87regparm but no 80387 support. (ix86_attribute_table): Add x87regparm. (ix86_handle_cconv_attribute): Update comments for x87regparm. (ix86_comp_type_attributes): Check for mismatched x87regparm types. (ix86_function_x87regparm): New function. (ix86_function_arg_regno_p): Add X87_REGPARM_MAX 80387 floating point registers. (init_cumulative_args): Initialize x87_nregs and float_in_x87 variables. (function_arg_advance): Process x87_nregs and x87_regno when floating point argument is to be passed in 80387 register. (function_arg): Pass XFmode arguments in 80387 registers for local functions. Pass SFmode and DFmode arguments to local functions in 80387 registers when flag_unsafe_math_optimizations is set. * reg-stack.c (convert_regs_entry): Disable NaN load for stack registers that are used for argument passing. * doc/extend.texi: Document x87regparm function attribute. * doc/invoke.texi: Document -mx87regparm. testsuite/ChangeLog: PR target/30120 * gcc.target/i386/pr30120.c: New test. Revert: 2006-11-15 Uros Bizjak <ubizjak@gmail.com> * gcc.target/i386/x87regparm-1.c: New test. * gcc.target/i386/x87regparm-2.c: New test. * gcc.target/i386/x87regparm-3.c: New test. * gcc.target/i386/x87regparm-4.c: New test. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@119734 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/config')
-rw-r--r--gcc/config/i386/i386.c155
-rw-r--r--gcc/config/i386/i386.h16
-rw-r--r--gcc/config/i386/i386.opt4
3 files changed, 26 insertions, 149 deletions
diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c
index fd5c27cc0fc..004ee531477 100644
--- a/gcc/config/i386/i386.c
+++ b/gcc/config/i386/i386.c
@@ -2149,11 +2149,6 @@ override_options (void)
ix86_preferred_stack_boundary = (1 << i) * BITS_PER_UNIT;
}
- /* Accept -mx87regparm only if 80387 support is enabled. */
- if (TARGET_X87REGPARM
- && ! TARGET_80387)
- error ("-mx87regparm used without 80387 enabled");
-
/* Accept -msseregparm only if at least SSE support is enabled. */
if (TARGET_SSEREGPARM
&& ! TARGET_SSE)
@@ -2460,9 +2455,6 @@ const struct attribute_spec ix86_attribute_table[] =
/* Regparm attribute specifies how many integer arguments are to be
passed in registers. */
{ "regparm", 1, 1, false, true, true, ix86_handle_cconv_attribute },
- /* X87regparm attribute says we are passing floating point arguments
- in 80387 registers. */
- { "x87regparm", 0, 0, false, true, true, ix86_handle_cconv_attribute },
/* Sseregparm attribute says we are using x86_64 calling conventions
for FP arguments. */
{ "sseregparm", 0, 0, false, true, true, ix86_handle_cconv_attribute },
@@ -2565,8 +2557,8 @@ ix86_function_ok_for_sibcall (tree decl, tree exp)
return true;
}
-/* Handle "cdecl", "stdcall", "fastcall", "regparm", "x87regparm"
- and "sseregparm" calling convention attributes;
+/* Handle "cdecl", "stdcall", "fastcall", "regparm" and "sseregparm"
+ calling convention attributes;
arguments as in struct attribute_spec.handler. */
static tree
@@ -2631,8 +2623,7 @@ ix86_handle_cconv_attribute (tree *node, tree name,
return NULL_TREE;
}
- /* Can combine fastcall with stdcall (redundant), x87regparm
- and sseregparm. */
+ /* Can combine fastcall with stdcall (redundant) and sseregparm. */
if (is_attribute_p ("fastcall", name))
{
if (lookup_attribute ("cdecl", TYPE_ATTRIBUTES (*node)))
@@ -2649,8 +2640,8 @@ ix86_handle_cconv_attribute (tree *node, tree name,
}
}
- /* Can combine stdcall with fastcall (redundant), regparm,
- x87regparm and sseregparm. */
+ /* Can combine stdcall with fastcall (redundant), regparm and
+ sseregparm. */
else if (is_attribute_p ("stdcall", name))
{
if (lookup_attribute ("cdecl", TYPE_ATTRIBUTES (*node)))
@@ -2663,7 +2654,7 @@ ix86_handle_cconv_attribute (tree *node, tree name,
}
}
- /* Can combine cdecl with regparm, x87regparm and sseregparm. */
+ /* Can combine cdecl with regparm and sseregparm. */
else if (is_attribute_p ("cdecl", name))
{
if (lookup_attribute ("stdcall", TYPE_ATTRIBUTES (*node)))
@@ -2676,7 +2667,7 @@ ix86_handle_cconv_attribute (tree *node, tree name,
}
}
- /* Can combine x87regparm or sseregparm with all attributes. */
+ /* Can combine sseregparm with all attributes. */
return NULL_TREE;
}
@@ -2701,11 +2692,6 @@ ix86_comp_type_attributes (tree type1, tree type2)
!= ix86_function_regparm (type2, NULL)))
return 0;
- /* Check for mismatched x87regparm types. */
- if (!lookup_attribute ("x87regparm", TYPE_ATTRIBUTES (type1))
- != !lookup_attribute ("x87regparm", TYPE_ATTRIBUTES (type2)))
- return 0;
-
/* Check for mismatched sseregparm types. */
if (!lookup_attribute ("sseregparm", TYPE_ATTRIBUTES (type1))
!= !lookup_attribute ("sseregparm", TYPE_ATTRIBUTES (type2)))
@@ -2794,48 +2780,6 @@ ix86_function_regparm (tree type, tree decl)
return regparm;
}
-/* Return 1 if we can pass up to X87_REGPARM_MAX floating point
- arguments in x87 registers for a function with the indicated
- TYPE and DECL. DECL may be NULL when calling function indirectly
- or considering a libcall. For local functions, return 2.
- Otherwise return 0. */
-
-static int
-ix86_function_x87regparm (tree type, tree decl)
-{
- /* Use x87 registers to pass floating point arguments if requested
- by the x87regparm attribute. */
- if (TARGET_X87REGPARM
- || (type
- && lookup_attribute ("x87regparm", TYPE_ATTRIBUTES (type))))
- {
- if (!TARGET_80387)
- {
- if (decl)
- error ("Calling %qD with attribute x87regparm without "
- "80387 enabled", decl);
- else
- error ("Calling %qT with attribute x87regparm without "
- "80387 enabled", type);
- return 0;
- }
-
- return 1;
- }
-
- /* For local functions, pass up to X87_REGPARM_MAX floating point
- arguments in x87 registers. */
- if (!TARGET_64BIT && decl
- && flag_unit_at_a_time && !profile_flag)
- {
- struct cgraph_local_info *i = cgraph_local_info (decl);
- if (i && i->local)
- return 2;
- }
-
- return 0;
-}
-
/* Return 1 or 2, if we can pass up to SSE_REGPARM_MAX SFmode (1) and
DFmode (2) arguments in SSE registers for a function with the
indicated TYPE and DECL. DECL may be NULL when calling function
@@ -2955,8 +2899,6 @@ ix86_function_arg_regno_p (int regno)
int i;
if (!TARGET_64BIT)
return (regno < REGPARM_MAX
- || (TARGET_80387 && FP_REGNO_P (regno)
- && (regno < FIRST_FLOAT_REG + X87_REGPARM_MAX))
|| (TARGET_MMX && MMX_REGNO_P (regno)
&& (regno < FIRST_MMX_REG + MMX_REGPARM_MAX))
|| (TARGET_SSE && SSE_REGNO_P (regno)
@@ -3020,8 +2962,6 @@ init_cumulative_args (CUMULATIVE_ARGS *cum, /* Argument info to initialize */
/* Set up the number of registers to use for passing arguments. */
cum->nregs = ix86_regparm;
- if (TARGET_80387)
- cum->x87_nregs = X87_REGPARM_MAX;
if (TARGET_SSE)
cum->sse_nregs = SSE_REGPARM_MAX;
if (TARGET_MMX)
@@ -3043,10 +2983,6 @@ init_cumulative_args (CUMULATIVE_ARGS *cum, /* Argument info to initialize */
cum->nregs = ix86_function_regparm (fntype, fndecl);
}
- /* Set up the number of 80387 registers used for passing
- floating point arguments. Warn for mismatching ABI. */
- cum->float_in_x87 = ix86_function_x87regparm (fntype, fndecl);
-
/* Set up the number of SSE registers used for passing SFmode
and DFmode arguments. Warn for mismatching ABI. */
cum->float_in_sse = ix86_function_sseregparm (fntype, fndecl);
@@ -3056,8 +2992,7 @@ init_cumulative_args (CUMULATIVE_ARGS *cum, /* Argument info to initialize */
are no variable arguments. If there are variable arguments, then
we won't pass anything in registers in 32-bit mode. */
- if (cum->nregs || cum->mmx_nregs
- || cum->x87_nregs || cum->sse_nregs)
+ if (cum->nregs || cum->mmx_nregs || cum->sse_nregs)
{
for (param = (fntype) ? TYPE_ARG_TYPES (fntype) : 0;
param != 0; param = next_param)
@@ -3068,13 +3003,11 @@ init_cumulative_args (CUMULATIVE_ARGS *cum, /* Argument info to initialize */
if (!TARGET_64BIT)
{
cum->nregs = 0;
- cum->x87_nregs = 0;
cum->sse_nregs = 0;
cum->mmx_nregs = 0;
cum->warn_sse = 0;
cum->warn_mmx = 0;
cum->fastcall = 0;
- cum->float_in_x87 = 0;
cum->float_in_sse = 0;
}
cum->maybe_vaarg = true;
@@ -3771,40 +3704,13 @@ function_arg_advance (CUMULATIVE_ARGS *cum, enum machine_mode mode,
}
break;
- case SFmode:
- if (cum->float_in_sse > 0)
- goto skip_80387;
-
case DFmode:
- if (cum->float_in_sse > 1)
- goto skip_80387;
-
- /* Because no inherent XFmode->DFmode and XFmode->SFmode
- rounding takes place when values are passed in x87
- registers, pass DFmode and SFmode types to local functions
- only when flag_unsafe_math_optimizations is set. */
- if (!cum->float_in_x87
- || (cum->float_in_x87 == 2
- && !flag_unsafe_math_optimizations))
+ if (cum->float_in_sse < 2)
break;
-
- case XFmode:
- if (!cum->float_in_x87)
+ case SFmode:
+ if (cum->float_in_sse < 1)
break;
-
- if (!type || !AGGREGATE_TYPE_P (type))
- {
- cum->x87_nregs -= 1;
- cum->x87_regno += 1;
- if (cum->x87_nregs <= 0)
- {
- cum->x87_nregs = 0;
- cum->x87_regno = 0;
- }
- }
- break;
-
- skip_80387:
+ /* FALLTHRU */
case TImode:
case V16QImode:
@@ -3815,6 +3721,7 @@ function_arg_advance (CUMULATIVE_ARGS *cum, enum machine_mode mode,
case V2DFmode:
if (!type || !AGGREGATE_TYPE_P (type))
{
+ cum->sse_words += words;
cum->sse_nregs -= 1;
cum->sse_regno += 1;
if (cum->sse_nregs <= 0)
@@ -3831,6 +3738,7 @@ function_arg_advance (CUMULATIVE_ARGS *cum, enum machine_mode mode,
case V2SFmode:
if (!type || !AGGREGATE_TYPE_P (type))
{
+ cum->mmx_words += words;
cum->mmx_nregs -= 1;
cum->mmx_regno += 1;
if (cum->mmx_nregs <= 0)
@@ -3895,6 +3803,7 @@ function_arg (CUMULATIVE_ARGS *cum, enum machine_mode orig_mode,
else
switch (mode)
{
+ /* For now, pass fp/complex values on the stack. */
default:
break;
@@ -3924,35 +3833,13 @@ function_arg (CUMULATIVE_ARGS *cum, enum machine_mode orig_mode,
ret = gen_rtx_REG (mode, regno);
}
break;
-
- case SFmode:
- if (cum->float_in_sse > 0)
- goto skip_80387;
-
- case DFmode:
- if (cum->float_in_sse > 1)
- goto skip_80387;
-
- /* Because no inherent XFmode->DFmode and XFmode->SFmode
- rounding takes place when values are passed in x87
- registers, pass DFmode and SFmode types to local functions
- only when flag_unsafe_math_optimizations is set. */
- if (!cum->float_in_x87
- || (cum->float_in_x87 == 2
- && !flag_unsafe_math_optimizations))
- break;
-
- case XFmode:
- if (!cum->float_in_x87)
- break;
-
- if (!type || !AGGREGATE_TYPE_P (type))
- if (cum->x87_nregs)
- ret = gen_rtx_REG (mode, cum->x87_regno + FIRST_FLOAT_REG);
+ case DFmode:
+ if (cum->float_in_sse < 2)
break;
-
- skip_80387:
-
+ case SFmode:
+ if (cum->float_in_sse < 1)
+ break;
+ /* FALLTHRU */
case TImode:
case V16QImode:
case V8HImode:
diff --git a/gcc/config/i386/i386.h b/gcc/config/i386/i386.h
index e05bf66624d..284de4e9c10 100644
--- a/gcc/config/i386/i386.h
+++ b/gcc/config/i386/i386.h
@@ -1481,21 +1481,19 @@ enum reg_class
such as FUNCTION_ARG to determine where the next arg should go. */
typedef struct ix86_args {
+ int words; /* # words passed so far */
int nregs; /* # registers available for passing */
int regno; /* next available register number */
- int words; /* # words passed so far */
int fastcall; /* fastcall calling convention is used */
- int x87_nregs; /* # x87 registers available for passing */
- int x87_regno; /* # next available x87 register number */
+ int sse_words; /* # sse words passed so far */
int sse_nregs; /* # sse registers available for passing */
- int sse_regno; /* next available sse register number */
int warn_sse; /* True when we want to warn about SSE ABI. */
+ int warn_mmx; /* True when we want to warn about MMX ABI. */
+ int sse_regno; /* next available sse register number */
+ int mmx_words; /* # mmx words passed so far */
int mmx_nregs; /* # mmx registers available for passing */
int mmx_regno; /* next available mmx register number */
- int warn_mmx; /* True when we want to warn about MMX ABI. */
int maybe_vaarg; /* true for calls to possibly vardic fncts. */
- int float_in_x87; /* 1 if floating point arguments should
- be passed in 80387 registers. */
int float_in_sse; /* 1 if in 32-bit mode SFmode (2 for DFmode) should
be passed in SSE registers. Otherwise 0. */
} CUMULATIVE_ARGS;
@@ -1778,10 +1776,6 @@ do { \
#define REGPARM_MAX (TARGET_64BIT ? 6 : 3)
-/* ??? Currently disabled, as reg-stack.c does not know how to
- rearrange input registers if some arguments are left unused. */
-#define X87_REGPARM_MAX 0
-
#define SSE_REGPARM_MAX (TARGET_64BIT ? 8 : (TARGET_SSE ? 3 : 0))
#define MMX_REGPARM_MAX (TARGET_64BIT ? 0 : (TARGET_MMX ? 3 : 0))
diff --git a/gcc/config/i386/i386.opt b/gcc/config/i386/i386.opt
index aba2ee7440d..25b2f2d4e95 100644
--- a/gcc/config/i386/i386.opt
+++ b/gcc/config/i386/i386.opt
@@ -205,10 +205,6 @@ mssse3
Target Report Mask(SSSE3)
Support MMX, SSE, SSE2, SSE3 and SSSE3 built-in functions and code generation
-mx87regparm
-Target RejectNegative Mask(X87REGPARM)
-Use x87 register passing conventions to pass floating point arguments
-
msseregparm
Target RejectNegative Mask(SSEREGPARM)
Use SSE register passing conventions for SF and DF mode