diff options
-rw-r--r-- | gcc/ChangeLog | 8 | ||||
-rw-r--r-- | gcc/config/i386/i386.c | 7 | ||||
-rw-r--r-- | gcc/config/i386/i386.opt | 4 | ||||
-rw-r--r-- | gcc/doc/invoke.texi | 13 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/testsuite/gcc.target/i386/amd64-abi-7.c | 46 | ||||
-rw-r--r-- | gcc/testsuite/gcc.target/i386/amd64-abi-8.c | 18 | ||||
-rw-r--r-- | gcc/testsuite/gcc.target/i386/amd64-abi-9.c | 18 |
8 files changed, 119 insertions, 1 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 1fd5b4f..6e7cfeb 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,11 @@ +2014-12-18 H.J. Lu <hongjiu.lu@intel.com> + + * config/i386/i386.c (ix86_expand_call): Skip setting up RAX + register for -mskip-rax-setup when there are no parameters + passed in vector registers. + * config/i386/i386.opt (mskip-rax-setup): New option. + * doc/invoke.texi: Document -mskip-rax-setup. + 2014-12-18 Alan Lawrence <alan.lawrence@arm.com> * config/aarch64/aarch64-simd.md (aarch64_lshr_simddi): Handle shift diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c index 17ef751..122a350 100644 --- a/gcc/config/i386/i386.c +++ b/gcc/config/i386/i386.c @@ -25461,7 +25461,12 @@ ix86_expand_call (rtx retval, rtx fnaddr, rtx callarg1, } } - if (TARGET_64BIT && INTVAL (callarg2) >= 0) + /* Skip setting up RAX register for -mskip-rax-setup when there are no + parameters passed in vector registers. */ + if (TARGET_64BIT + && (INTVAL (callarg2) > 0 + || (INTVAL (callarg2) == 0 + && (TARGET_SSE || !flag_skip_rax_setup)))) { rtx al = gen_rtx_REG (QImode, AX_REG); emit_move_insn (al, callarg2); diff --git a/gcc/config/i386/i386.opt b/gcc/config/i386/i386.opt index 3d54bfa..6dc4da2 100644 --- a/gcc/config/i386/i386.opt +++ b/gcc/config/i386/i386.opt @@ -831,6 +831,10 @@ Target Report Var(flag_nop_mcount) Init(0) Generate mcount/__fentry__ calls as nops. To activate they need to be patched in. +mskip-rax-setup +Target Report Var(flag_skip_rax_setup) Init(0) +Skip setting up RAX register when passing variable arguments. + m8bit-idiv Target Report Mask(USE_8BIT_IDIV) Save Expand 32bit/64bit integer divide into 8bit unsigned integer divide with run-time check diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi index 15068da..33a7ed2 100644 --- a/gcc/doc/invoke.texi +++ b/gcc/doc/invoke.texi @@ -16256,6 +16256,19 @@ the profiling functions as nops. This is useful when they should be patched in later dynamically. This is likely only useful together with @option{-mrecord-mcount}. +@item -mskip-rax-setup +@itemx -mno-skip-rax-setup +@opindex mskip-rax-setup +When generating code for the x86-64 architecture with SSE extensions +disabled, @option{-skip-rax-setup} can be used to skip setting up RAX +register when there are no variable arguments passed in vector registers. + +@strong{Warning:} Since RAX register is used to avoid unnecessarily +saving vector registers on stack when passing variable arguments, the +impacts of this option are callees may waste some stack space, +misbehave or jump to a random location. GCC 4.4 or newer don't have +those issues, regardless the RAX register value. + @item -m8bit-idiv @itemx -mno-8bit-idiv @opindex 8bit-idiv diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index f7e72ed..4d75d0e 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,9 @@ +2014-12-18 H.J. Lu <hongjiu.lu@intel.com> + + * gcc.target/i386/amd64-abi-7.c: New tests. + * gcc.target/i386/amd64-abi-8.c: Likwise. + * gcc.target/i386/amd64-abi-9.c: Likwise. + 2014-12-18 Alan Lawrence <alan.lawrence@arm.com> * gcc.target/aarch64/ushr64_1.c: Remove scan-assembler "ushr...64". diff --git a/gcc/testsuite/gcc.target/i386/amd64-abi-7.c b/gcc/testsuite/gcc.target/i386/amd64-abi-7.c new file mode 100644 index 0000000..fcca680 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/amd64-abi-7.c @@ -0,0 +1,46 @@ +/* { dg-do run { target { ! { ia32 } } } } */ +/* { dg-options "-O2 -mno-sse" } */ + +#include <stdarg.h> +#include <assert.h> + +int n1 = 30; +int n2 = 324; +void *n3 = (void *) &n2; +int n4 = 407; + +int e1; +int e2; +void *e3; +int e4; + +static void +__attribute__((noinline)) +foo (va_list va_arglist) +{ + e2 = va_arg (va_arglist, int); + e3 = va_arg (va_arglist, void *); + e4 = va_arg (va_arglist, int); +} + +static void +__attribute__((noinline)) +test (int a1, ...) +{ + va_list va_arglist; + e1 = a1; + va_start (va_arglist, a1); + foo (va_arglist); + va_end (va_arglist); +} + +int +main () +{ + test (n1, n2, n3, n4); + assert (n1 == e1); + assert (n2 == e2); + assert (n3 == e3); + assert (n4 == e4); + return 0; +} diff --git a/gcc/testsuite/gcc.target/i386/amd64-abi-8.c b/gcc/testsuite/gcc.target/i386/amd64-abi-8.c new file mode 100644 index 0000000..b25ceec --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/amd64-abi-8.c @@ -0,0 +1,18 @@ +/* { dg-do compile { target { ! { ia32 } } } } */ +/* { dg-options "-O2 -mno-sse -mskip-rax-setup" } */ +/* { dg-final { scan-assembler-not "xorl\[\\t \]*\\\%eax,\[\\t \]*%eax" } } */ + +void foo (const char *, ...); + +void +test1 (void) +{ + foo ("%d", 20); +} + +int +test2 (void) +{ + foo ("%d", 20); + return 3; +} diff --git a/gcc/testsuite/gcc.target/i386/amd64-abi-9.c b/gcc/testsuite/gcc.target/i386/amd64-abi-9.c new file mode 100644 index 0000000..4707eb7 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/amd64-abi-9.c @@ -0,0 +1,18 @@ +/* { dg-do compile { target { ! { ia32 } } } } */ +/* { dg-options "-O2 -mno-sse -mno-skip-rax-setup" } */ +/* { dg-final { scan-assembler-times "xorl\[\\t \]*\\\%eax,\[\\t \]*%eax" 2 } } */ + +void foo (const char *, ...); + +void +test1 (void) +{ + foo ("%d", 20); +} + +int +test2 (void) +{ + foo ("%d", 20); + return 3; +} |