> This surprises me, you accept there arbitrary > offsets and throw them away. If it behaves like i?86 GOTOFF, > then I'd expect you want to remember the offset and > > > + > > if (GET_CODE (y) == UNSPEC > > ! && (XINT (y, 1) == UNSPEC_GOTOFF > > ! || XINT (y, 1) == UNSPEC_PLTOFF)) > > return XVECEXP (y, 0, 0); > > return plus_constant (XVECEXP (y, 0, 0), offset); > > here... Not sure what exactly PLTOFF with a constant > offset means though.
Oh right. Fixed with the attached patch. I'll commit it after running some tests. PLTOFF is used to address plt slots relative to the GOT. It isn't needed for 64bit code but in the 31 bit PIC case. Bye, -Andreas- Index: gcc/config/s390/s390.c =================================================================== *** gcc/config/s390/s390.c.orig --- gcc/config/s390/s390.c *************** s390_delegitimize_address (rtx orig_x) *** 5030,5046 **** && REGNO (XEXP (x, 0)) == PIC_OFFSET_TABLE_REGNUM && GET_CODE (XEXP (x, 1)) == CONST) { /* The const operand. */ y = XEXP (XEXP (x, 1), 0); if (GET_CODE (y) == PLUS && GET_CODE (XEXP (y, 1)) == CONST_INT) ! y = XEXP (y, 0); if (GET_CODE (y) == UNSPEC && (XINT (y, 1) == UNSPEC_GOTOFF || XINT (y, 1) == UNSPEC_PLTOFF)) ! return XVECEXP (y, 0, 0); } if (GET_CODE (x) != MEM) --- 5030,5051 ---- && REGNO (XEXP (x, 0)) == PIC_OFFSET_TABLE_REGNUM && GET_CODE (XEXP (x, 1)) == CONST) { + HOST_WIDE_INT offset = 0; + /* The const operand. */ y = XEXP (XEXP (x, 1), 0); if (GET_CODE (y) == PLUS && GET_CODE (XEXP (y, 1)) == CONST_INT) ! { ! offset = INTVAL (XEXP (y, 1)); ! y = XEXP (y, 0); ! } if (GET_CODE (y) == UNSPEC && (XINT (y, 1) == UNSPEC_GOTOFF || XINT (y, 1) == UNSPEC_PLTOFF)) ! return plus_constant (XVECEXP (y, 0, 0), offset); } if (GET_CODE (x) != MEM)