Since the upper 32 bits of stack register are always zero for x32, we can encode %esp as %rsp to avoid 0x67 prefix in address if there is no index or base register.
Tested on x86-64. OK for trunk? H.J. ---- gcc/ PR target/82267 * config/i386/i386.c (ix86_print_operand_address_as): Encode %esp as %rsp to avoid 0x67 prefix if there is no index or base register. gcc/testsuite/ PR target/82267 * gcc.target/i386/pr82267.c: New tests. --- gcc/config/i386/i386.c | 17 +++++++++++++++++ gcc/testsuite/gcc.target/i386/pr82267.c | 14 ++++++++++++++ 2 files changed, 31 insertions(+) create mode 100644 gcc/testsuite/gcc.target/i386/pr82267.c diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c index 5e8f58c5e9f..519fdb0ffae 100644 --- a/gcc/config/i386/i386.c +++ b/gcc/config/i386/i386.c @@ -19849,6 +19849,23 @@ ix86_print_operand_address_as (FILE *file, rtx addr, disp = parts.disp; scale = parts.scale; + /* Since the upper 32 bits of RSP are always zero for x32, we can + encode %esp as %rsp to avoid 0x67 prefix if there is no index or + base register. */ + if (TARGET_X32 + && Pmode == SImode + && (!index || !base) + && index != base) + { + if (base) + { + if (REGNO (base) == SP_REG) + base = gen_rtx_REG (DImode, SP_REG); + } + else if (REGNO (index) == SP_REG) + index = gen_rtx_REG (DImode, SP_REG); + } + if (ADDR_SPACE_GENERIC_P (as)) as = parts.seg; else diff --git a/gcc/testsuite/gcc.target/i386/pr82267.c b/gcc/testsuite/gcc.target/i386/pr82267.c new file mode 100644 index 00000000000..5e4b271d41d --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/pr82267.c @@ -0,0 +1,14 @@ +/* { dg-do compile { target { ! ia32 } } } */ +/* { dg-require-effective-target maybe_x32 } */ +/* { dg-options "-O2 -mx32 -maddress-mode=short" } */ + +int +stackuse (void) +{ + volatile int foo = 2; + return foo * 3; +} + +/* Verify we that use %rsp to access stack. */ +/* { dg-final { scan-assembler-not "%esp" } } */ +/* { dg-final { scan-assembler "%rsp" } } */ -- 2.13.5