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) {