Hi,

Since x32 runs in 64-bit mode, for address -0x40000300(%rax), hardware
sign-extends displacement from 32-bits to 64-bits and adds it to %rax.
But x32 wants 32-bit -0x40000300, not 64-bit -0x40000300.  This patch
uses 32-bit registers instead of 64-bit registers when displacement 
< -16*1024*1024.  -16*1024*1024 is used instead of 0 so that we will
still generate -16(%rsp) instead of -16(%esp).

Tested it on Linux/x32.  OK to install?

Thanks.


H.J.
---
2012-11-09  H.J. Lu  <hongjiu...@intel.com>

        * config/i386/i386.c (ix86_print_operand_address): For x32,
        print SImode register names to force addr32 prefix if displacement
        < -16*1024*1024.

diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c
index 78e840b..6d4fbb5 100644
--- a/gcc/config/i386/i386.c
+++ b/gcc/config/i386/i386.c
@@ -14502,6 +14514,17 @@ ix86_print_operand_address (FILE *file, rtx addr)
          gcc_assert (!code);
          code = 'l';
        }
+      else if (code == 0
+              && TARGET_X32
+              && disp
+              && CONST_INT_P (disp)
+              && INTVAL (disp) < -16*1024*1024)
+       {
+         /* For x32, print SImode register names to force addr32 prefix
+           if displacement < -16*1024*1024 so that 32-bit displacement
+           isn't sign-extended to 64-bit.  */
+         code = 'k';
+       }
 
       if (ASSEMBLER_DIALECT == ASM_ATT)
        {

Reply via email to