Hi,

so far we were missing to use load relative when accessing GOT slots.
Fixed with the attached patch.

Committed to mainline after tested on s390 and s390x.

Bye,

-Andreas-

2012-09-03  Andreas Krebbel  <andreas.kreb...@de.ibm.com>

        * config/s390/s390.c (s390_loadrelative_operand_p): New function.
        (s390_check_qrst_address, print_operand_address): Use
        s390_loadrelative_operand_p instead of s390_symref_operand_p.
        (s390_check_symref_alignment): Accept pointer size alignment for GOT 
slots.
        (legitimize_pic_address): Use load relative on z10 or later.

---
 gcc/config/s390/s390.c |   36 +++++++++++++++++++++++-!!!!!!!!!!!!
 1 file changed, 23 insertions(+), 1 deletion(-), 12 modifications(!)

Index: gcc/config/s390/s390.c
===================================================================
*** gcc/config/s390/s390.c.orig
--- gcc/config/s390/s390.c
*************** s390_symref_operand_p (rtx addr, rtx *sy
*** 2123,2128 ****
--- 2123,2144 ----
    return true;
  }
  
+ /* Return TRUE if ADDR is an operand valid for a load/store relative
+    instructions.  Be aware that the alignment of the operand needs to
+    be checked separately.  */
+ static bool
+ s390_loadrelative_operand_p (rtx addr)
+ {
+   if (GET_CODE (addr) == CONST)
+     addr = XEXP (addr, 0);
+ 
+   /* Enable load relative for symbol@GOTENT.  */
+   if (GET_CODE (addr) == UNSPEC
+       && XINT (addr, 1) == UNSPEC_GOTENT)
+     return true;
+ 
+   return s390_symref_operand_p (addr, NULL, NULL);
+ }
  
  /* Return true if the address in OP is valid for constraint letter C
     if wrapped in a MEM rtx.  Set LIT_POOL_OK to true if it literal
*************** s390_check_qrst_address (char c, rtx op,
*** 2137,2143 ****
  
    /* This check makes sure that no symbolic address (except literal
       pool references) are accepted by the R or T constraints.  */
!   if (s390_symref_operand_p (op, NULL, NULL))
      return 0;
  
    /* Ensure literal pool references are only accepted if LIT_POOL_OK.  */
--- 2153,2159 ----
  
    /* This check makes sure that no symbolic address (except literal
       pool references) are accepted by the R or T constraints.  */
!   if (s390_loadrelative_operand_p (op))
      return 0;
  
    /* Ensure literal pool references are only accepted if LIT_POOL_OK.  */
*************** s390_check_symref_alignment (rtx addr, H
*** 2941,2946 ****
--- 2957,2969 ----
    HOST_WIDE_INT addend;
    rtx symref;
  
+   /* Accept symbol@GOTENT with pointer size alignment.  */
+   if (GET_CODE (addr) == CONST
+       && GET_CODE (XEXP (addr, 0)) == UNSPEC
+       && XINT (XEXP (addr, 0), 1) == UNSPEC_GOTENT
+       && alignment <= UNITS_PER_LONG)
+     return true;
+ 
    if (!s390_symref_operand_p (addr, &symref, &addend))
      return false;
  
*************** legitimize_pic_address (rtx orig, rtx re
*** 3398,3406 ****
  
            new_rtx = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, addr), 
UNSPEC_GOTENT);
            new_rtx = gen_rtx_CONST (Pmode, new_rtx);
-           emit_move_insn (temp, new_rtx);
  
!           new_rtx = gen_const_mem (Pmode, temp);
            emit_move_insn (reg, new_rtx);
            new_rtx = reg;
          }
--- 3421,3434 ----
  
            new_rtx = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, addr), 
UNSPEC_GOTENT);
            new_rtx = gen_rtx_CONST (Pmode, new_rtx);
  
!         if (!TARGET_Z10)
!           {
!             emit_move_insn (temp, new_rtx);
!             new_rtx = gen_const_mem (Pmode, temp);
!           }
!         else
!           new_rtx = gen_const_mem (GET_MODE (reg), new_rtx);
            emit_move_insn (reg, new_rtx);
            new_rtx = reg;
          }
*************** print_operand_address (FILE *file, rtx a
*** 5250,5256 ****
  {
    struct s390_address ad;
  
!   if (s390_symref_operand_p (addr, NULL, NULL))
      {
        if (!TARGET_Z10)
        {
--- 5278,5284 ----
  {
    struct s390_address ad;
  
!   if (s390_loadrelative_operand_p (addr))
      {
        if (!TARGET_Z10)
        {

Reply via email to