diff options
author | stuart <stuart@138bc75d-0d04-0410-961f-82ee72b054a4> | 2006-05-18 00:34:44 +0000 |
---|---|---|
committer | stuart <stuart@138bc75d-0d04-0410-961f-82ee72b054a4> | 2006-05-18 00:34:44 +0000 |
commit | 124c02016c90c9794e7e786c22afaf224e867e26 (patch) | |
tree | 76255841987be3306d958753a8feba9aea4e6b6e /gcc | |
parent | 3e9c0efdb1c6e313edd244640d45a21bce0d4678 (diff) | |
download | gcc-124c02016c90c9794e7e786c22afaf224e867e26.tar.gz |
* gcc/config/i386/i386.opt (-mstackrealign): New flag. *
gcc/config/i386/i386.c (force_align_arg_pointer): New attribute.
(ix86_handle_cconv_attribute): Emit error when
force_align_arg_pointer attribute collides with too many regparms.
(ix86_function_regparm): Limit regparms when used with
force_align_arg_pointer attribute. (ix86_internal_arg_pointer):
Support stack-realigning prologue in non-main functions. Emit
warning for nested functions under -mstackrealign, emit error for
nested functions with force_align_arg_pointer attribute.
* gcc/doc/extend.texi (force_align_arg_pointer): Document it.
* gcc/doc/invoke.texi (-mstackrealign): Document it.
* testsuite/gcc.target/i386/20060512-1.c: New.
* testsuite/gcc.target/i386/20060512-2.c: New.
* testsuite/gcc.target/i386/20060512-3.c: New.
* testsuite/gcc.target/i386/20060512-4.c: New.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@113880 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ChangeLog | 14 | ||||
-rw-r--r-- | gcc/config/i386/i386.c | 55 | ||||
-rw-r--r-- | gcc/config/i386/i386.opt | 4 | ||||
-rw-r--r-- | gcc/doc/extend.texi | 14 | ||||
-rw-r--r-- | gcc/doc/invoke.texi | 16 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 7 | ||||
-rw-r--r-- | gcc/testsuite/gcc.target/i386/20060512-1.c | 28 | ||||
-rw-r--r-- | gcc/testsuite/gcc.target/i386/20060512-2.c | 12 | ||||
-rw-r--r-- | gcc/testsuite/gcc.target/i386/20060512-3.c | 28 | ||||
-rw-r--r-- | gcc/testsuite/gcc.target/i386/20060512-4.c | 12 |
10 files changed, 185 insertions, 5 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 94598927bf0..4759c32b81c 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,17 @@ +2006-05-12 Stuart Hastings <stuart@apple.com> + + * gcc/config/i386/i386.opt (-mstackrealign): New flag. * + gcc/config/i386/i386.c (force_align_arg_pointer): New attribute. + (ix86_handle_cconv_attribute): Emit error when + force_align_arg_pointer attribute collides with too many regparms. + (ix86_function_regparm): Limit regparms when used with + force_align_arg_pointer attribute. (ix86_internal_arg_pointer): + Support stack-realigning prologue in non-main functions. Emit + warning for nested functions under -mstackrealign, emit error for + nested functions with force_align_arg_pointer attribute. + * gcc/doc/extend.texi (force_align_arg_pointer): Document it. + * gcc/doc/invoke.texi (-mstackrealign): Document it. + 2006-05-17 Kazu Hirata <kazu@codesourcery.com> PR rtl-optimization/27477 diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c index 3ff5abbd66c..cfdcb2fc926 100644 --- a/gcc/config/i386/i386.c +++ b/gcc/config/i386/i386.c @@ -1049,6 +1049,10 @@ int x86_prefetch_sse; /* ix86_regparm_string as a number */ static int ix86_regparm; +/* -mstackrealign option */ +extern int ix86_force_align_arg_pointer; +static const char ix86_force_align_arg_pointer_string[] = "force_align_arg_pointer"; + /* Preferred alignment for stack boundary in bits. */ unsigned int ix86_preferred_stack_boundary; @@ -2225,6 +2229,9 @@ const struct attribute_spec ix86_attribute_table[] = /* Sseregparm attribute says we are using x86_64 calling conventions for FP arguments. */ { "sseregparm", 0, 0, false, true, true, ix86_handle_cconv_attribute }, + /* force_align_arg_pointer says this function realigns the stack at entry. */ + { (const char *)&ix86_force_align_arg_pointer_string, 0, 0, + false, true, true, ix86_handle_cconv_attribute }, #if TARGET_DLLIMPORT_DECL_ATTRIBUTES { "dllimport", 0, 0, false, false, false, handle_dll_attribute }, { "dllexport", 0, 0, false, false, false, handle_dll_attribute }, @@ -2367,6 +2374,15 @@ ix86_handle_cconv_attribute (tree *node, tree name, *no_add_attrs = true; } + if (!TARGET_64BIT + && lookup_attribute (ix86_force_align_arg_pointer_string, + TYPE_ATTRIBUTES (*node)) + && compare_tree_int (cst, REGPARM_MAX-1)) + { + error ("%s functions limited to %d register parameters", + ix86_force_align_arg_pointer_string, REGPARM_MAX-1); + } + return NULL_TREE; } @@ -2506,6 +2522,18 @@ ix86_function_regparm (tree type, tree decl) && decl_function_context (decl) && !DECL_NO_STATIC_CHAIN (decl)) local_regparm = 2; + /* If the function realigns its stackpointer, the + prologue will clobber %ecx. If we've already + generated code for the callee, the callee + DECL_STRUCT_FUNCTION is gone, so we fall back to + scanning the attributes for the self-realigning + property. */ + if ((DECL_STRUCT_FUNCTION (decl) + && DECL_STRUCT_FUNCTION (decl)->machine->force_align_arg_pointer) + || (!DECL_STRUCT_FUNCTION (decl) + && lookup_attribute (ix86_force_align_arg_pointer_string, + TYPE_ATTRIBUTES (TREE_TYPE (decl))))) + local_regparm = 2; /* Each global register variable increases register preassure, so the more global reg vars there are, the smaller regparm optimization use, unless requested by the user explicitly. */ @@ -5181,11 +5209,28 @@ pro_epilogue_adjust_stack (rtx dest, rtx src, rtx offset, int style) static rtx ix86_internal_arg_pointer (void) { - if (FORCE_PREFERRED_STACK_BOUNDARY_IN_MAIN - && DECL_NAME (current_function_decl) - && MAIN_NAME_P (DECL_NAME (current_function_decl)) - && DECL_FILE_SCOPE_P (current_function_decl)) - { + bool has_force_align_arg_pointer = + (0 != lookup_attribute (ix86_force_align_arg_pointer_string, + TYPE_ATTRIBUTES (TREE_TYPE (current_function_decl)))); + if ((FORCE_PREFERRED_STACK_BOUNDARY_IN_MAIN + && DECL_NAME (current_function_decl) + && MAIN_NAME_P (DECL_NAME (current_function_decl)) + && DECL_FILE_SCOPE_P (current_function_decl)) + || ix86_force_align_arg_pointer + || has_force_align_arg_pointer) + { + /* Nested functions can't realign the stack due to a register + conflict. */ + if (DECL_CONTEXT (current_function_decl) + && TREE_CODE (DECL_CONTEXT (current_function_decl)) == FUNCTION_DECL) + { + if (ix86_force_align_arg_pointer) + warning (0, "-mstackrealign ignored for nested functions"); + if (has_force_align_arg_pointer) + error ("%s not supported for nested functions", + ix86_force_align_arg_pointer_string); + return virtual_incoming_args_rtx; + } cfun->machine->force_align_arg_pointer = gen_rtx_REG (Pmode, 2); return copy_to_reg (cfun->machine->force_align_arg_pointer); } diff --git a/gcc/config/i386/i386.opt b/gcc/config/i386/i386.opt index 4d71492d090..6581291208d 100644 --- a/gcc/config/i386/i386.opt +++ b/gcc/config/i386/i386.opt @@ -205,6 +205,10 @@ msselibm Target Mask(SSELIBM) Use SSE2 ABI libgcc-math routines if using SSE math +mstackrealign +Target Report Var(ix86_force_align_arg_pointer) +Realign stack in prologue + msvr3-shlib Target Report Mask(SVR3_SHLIB) Uninitialized locals in .bss diff --git a/gcc/doc/extend.texi b/gcc/doc/extend.texi index a72fb7fb8a1..a281f92cbc9 100644 --- a/gcc/doc/extend.texi +++ b/gcc/doc/extend.texi @@ -2207,6 +2207,20 @@ SSE registers instead of on the stack. Functions that take a variable number of arguments will continue to pass all of their floating point arguments on the stack. +@item force_align_arg_pointer +@cindex @code{force_align_arg_pointer} attribute +On the Intel x86, the @code{force_align_arg_pointer} attribute may be +applied to individual function definitions, generating an alternate +prologue and epilogue that realigns the runtime stack. This supports +mixing legacy codes that run with a 4-byte aligned stack with modern +codes that keep a 16-byte stack for SSE compatibility. The alternate +prologue and epilogue are slower and bigger than the regular ones, and +the alternate prologue requires a scratch register; this lowers the +number of registers available if used in conjunction with the +@code{regparm} attribute. The @code{force_align_arg_pointer} +attribute is incompatible with nested functions; this is considered a +hard error. + @item returns_twice @cindex @code{returns_twice} attribute The @code{returns_twice} attribute tells the compiler that a function may diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi index df6074c3a09..9ac49e999eb 100644 --- a/gcc/doc/invoke.texi +++ b/gcc/doc/invoke.texi @@ -537,6 +537,7 @@ Objective-C and Objective-C++ Dialects}. -mthreads -mno-align-stringops -minline-all-stringops @gol -mpush-args -maccumulate-outgoing-args -m128bit-long-double @gol -m96bit-long-double -mregparm=@var{num} -msseregparm @gol +-mstackrealign @gol -momit-leaf-frame-pointer -mno-red-zone -mno-tls-direct-seg-refs @gol -mcmodel=@var{code-model} @gol -m32 -m64 -mlarge-data-threshold=@var{num}} @@ -9464,6 +9465,21 @@ function by using the function attribute @samp{sseregparm}. modules with the same value, including any libraries. This includes the system libraries and startup modules. +@item -mstackrealign +@opindex mstackrealign +Realign the stack at entry. On the Intel x86, the +@option{-mstackrealign} option will generate an alternate prologue and +epilogue that realigns the runtime stack. This supports mixing legacy +codes that keep a 4-byte aligned stack with modern codes that keep a +16-byte stack for SSE compatibility. The alternate prologue and +epilogue are slower and bigger than the regular ones, and the +alternate prologue requires an extra scratch register; this lowers the +number of registers available if used in conjunction with the +@code{regparm} attribute. The @option{-mstackrealign} option is +incompatible with the nested function prologue; this is considered a +hard error. See also the attribute @code{force_align_arg_pointer}, +applicable to individual functions. + @item -mpreferred-stack-boundary=@var{num} @opindex mpreferred-stack-boundary Attempt to keep the stack boundary aligned to a 2 raised to @var{num} diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 9cf94049cf8..e270f7a8791 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,10 @@ +2006-05-12 Stuart Hastings <stuart@apple.com> + + * testsuite/gcc.target/i386/20060512-1.c: New. + * testsuite/gcc.target/i386/20060512-2.c: New. + * testsuite/gcc.target/i386/20060512-3.c: New. + * testsuite/gcc.target/i386/20060512-4.c: New. + 2006-05-17 Mark Mitchell <mark@codesourcery.com> PR c++/26122 diff --git a/gcc/testsuite/gcc.target/i386/20060512-1.c b/gcc/testsuite/gcc.target/i386/20060512-1.c new file mode 100644 index 00000000000..a3724ec47ba --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/20060512-1.c @@ -0,0 +1,28 @@ +/* { dg-do run { target i?86-*-* } } */ +/* { dg-options "-std=gnu99" } */ +#include <emmintrin.h> +__m128i __attribute__ ((__noinline__)) +vector_using_function () +{ + volatile __m128i vx; /* We want to force a vector-aligned store into the stack. */ + vx = _mm_xor_si128 (vx, vx); + return vx; +} +int __attribute__ ((__noinline__, __force_align_arg_pointer__)) +self_aligning_function (int x, int y) +{ + __m128i ignored = vector_using_function (); + return (x + y); +} +int g_1 = 20; +int g_2 = 22; +int +main () +{ + int result; + asm ("pushl %esi"); /* Disalign runtime stack. */ + result = self_aligning_function (g_1, g_2); + asm ("popl %esi"); + if (result != 42) + abort (); +} diff --git a/gcc/testsuite/gcc.target/i386/20060512-2.c b/gcc/testsuite/gcc.target/i386/20060512-2.c new file mode 100644 index 00000000000..4f411c4a520 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/20060512-2.c @@ -0,0 +1,12 @@ +/* { dg-do compile { target i?86-*-* } } */ +/* { dg-options "-std=gnu99" } */ +int +outer_function (int x, int y) +{ + int __attribute__ ((__noinline__, __force_align_arg_pointer__)) + nested_function (int x, int y) + { /* { dg-error "force_align_arg_pointer not supported for nested functions" } */ + return (x + y); + } + return (3 + nested_function (x, y)); +} diff --git a/gcc/testsuite/gcc.target/i386/20060512-3.c b/gcc/testsuite/gcc.target/i386/20060512-3.c new file mode 100644 index 00000000000..72f0da00bb6 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/20060512-3.c @@ -0,0 +1,28 @@ +/* { dg-do run { target i?86-*-* } } */ +/* { dg-options "-std=gnu99 -mstackrealign" } */ +#include <emmintrin.h> +__m128i __attribute__ ((__noinline__)) +vector_using_function () +{ + volatile __m128i vx; /* We want to force a vector-aligned store into the stack. */ + vx = _mm_xor_si128 (vx, vx); + return vx; +} +int __attribute__ ((__noinline__)) +self_aligning_function (int x, int y) +{ + __m128i ignored = vector_using_function (); + return (x + y); +} +int g_1 = 20; +int g_2 = 22; +int +main () +{ + int result; + asm ("pushl %esi"); /* Disalign runtime stack. */ + result = self_aligning_function (g_1, g_2); + asm ("popl %esi"); + if (result != 42) + abort (); +} diff --git a/gcc/testsuite/gcc.target/i386/20060512-4.c b/gcc/testsuite/gcc.target/i386/20060512-4.c new file mode 100644 index 00000000000..cd569108b70 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/20060512-4.c @@ -0,0 +1,12 @@ +/* { dg-do compile { target i?86-*-* } } */ +/* { dg-options "-mstackrealign" } */ +int +outer_function (int x, int y) +{ + int __attribute__ ((__noinline__)) + nested_function (int x, int y) + { /* { dg-error "-mstackrealign ignored for nested functions" } */ + return (x + y); + } + return (3 + nested_function (x, y)); +} |