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.

Reply via email to