On Sun, Aug 16, 2015 at 12:39 PM, H.J. Lu <hjl.to...@gmail.com> wrote: > On Sun, Aug 16, 2015 at 12:24 PM, Alexander Monakov <amona...@ispras.ru> > wrote: > >>> + if (!TARGET_64BIT >>> + || (ix86_cmodel == CM_LARGE_PIC >>> + && DEFAULT_ABI != MS_ABI)) >>> + { >>> + use_reg (&use, gen_rtx_REG (Pmode, >>> + REAL_PIC_OFFSET_TABLE_REGNUM)); >>> + if (ix86_use_pseudo_pic_reg ()) >>> + emit_move_insn (gen_rtx_REG (Pmode, >>> + >>> REAL_PIC_OFFSET_TABLE_REGNUM), >>> + pic_offset_table_rtx); >>> + } >>> + } >>> + else if (!TARGET_PECOFF && !TARGET_MACHO) >>> + { >>> + if (TARGET_64BIT) >>> + { >>> + fnaddr = gen_rtx_UNSPEC (Pmode, >>> + gen_rtvec (1, addr), >>> + UNSPEC_GOTPCREL); >>> + fnaddr = gen_rtx_CONST (Pmode, fnaddr); >>> + } >>> + else >>> + { >>> + fnaddr = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, addr), >>> + UNSPEC_GOT); >>> + fnaddr = gen_rtx_CONST (Pmode, fnaddr); >>> + fnaddr = gen_rtx_PLUS (Pmode, pic_offset_table_rtx, >>> + fnaddr); >>> + } >>> + fnaddr = gen_const_mem (Pmode, fnaddr); >>> + if (GET_MODE (fnaddr) != word_mode) >>> + fnaddr = gen_rtx_ZERO_EXTEND (word_mode, fnaddr); >>> + fnaddr = gen_rtx_MEM (QImode, fnaddr); >>> + } >>> } >>> } >>> >>> @@ -25686,9 +25715,13 @@ ix86_expand_call (rtx retval, rtx fnaddr, rtx >>> callarg1, >>> && GET_CODE (XEXP (fnaddr, 0)) == SYMBOL_REF >>> && !local_symbolic_operand (XEXP (fnaddr, 0), VOIDmode)) >>> fnaddr = gen_rtx_MEM (QImode, construct_plt_address (XEXP (fnaddr, >>> 0))); >>> - else if (sibcall >>> - ? !sibcall_insn_operand (XEXP (fnaddr, 0), word_mode) >>> - : !call_insn_operand (XEXP (fnaddr, 0), word_mode)) >>> + else if (!(TARGET_X32 >>> + && MEM_P (fnaddr) >>> + && GET_CODE (XEXP (fnaddr, 0)) == ZERO_EXTEND >>> + && GOT_memory_operand (XEXP (XEXP (fnaddr, 0), 0), Pmode)) >>> + && (sibcall >>> + ? !sibcall_insn_operand (XEXP (fnaddr, 0), word_mode) >>> + : !call_insn_operand (XEXP (fnaddr, 0), word_mode))) >>> { >>> fnaddr = convert_to_mode (word_mode, XEXP (fnaddr, 0), 1); >>> fnaddr = gen_rtx_MEM (QImode, copy_to_mode_reg (word_mode, fnaddr)); >> >> Perhaps add a comment that GOT slots are 64-bit on x32? >> > > Good idea. I will update my patch. >
How about this? diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c index bf8a21d..216dee6 100644 --- a/gcc/config/i386/i386.c +++ b/gcc/config/i386/i386.c @@ -25690,6 +25690,10 @@ ix86_expand_call (rtx retval, rtx fnaddr, rtx callarg1, fnaddr); } fnaddr = gen_const_mem (Pmode, fnaddr); + /* Pmode may not be the same as word_mode for x32, which + doesn't support indirect branch va 32-bit memory slot. + Since x32 GOT slot is 64 bit with zero upper 32 bits, + indirect branch via x32 GOT slot is OK. */ if (GET_MODE (fnaddr) != word_mode) fnaddr = gen_rtx_ZERO_EXTEND (word_mode, fnaddr); fnaddr = gen_rtx_MEM (QImode, fnaddr); @@ -25715,7 +25719,9 @@ ix86_expand_call (rtx retval, rtx fnaddr, rtx callarg1, && GET_CODE (XEXP (fnaddr, 0)) == SYMBOL_REF && !local_symbolic_operand (XEXP (fnaddr, 0), VOIDmode)) fnaddr = gen_rtx_MEM (QImode, construct_plt_address (XEXP (fnaddr, 0))); - else if (!(TARGET_X32 + /* Since x32 GOT slot is 64 bit with zero upper 32 bits, indirect + branch via x32 GOT slot is OK. */ + else if (!(Pmode != word_mode && MEM_P (fnaddr) && GET_CODE (XEXP (fnaddr, 0)) == ZERO_EXTEND && GOT_memory_operand (XEXP (XEXP (fnaddr, 0), 0), Pmode)) -- H.J.