diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 4fdfa966231..9b3891c66c0 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,11 @@ +2012-09-03 Andreas Krebbel + + * 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. + 2012-09-03 Jakub Jelinek PR debug/53923 diff --git a/gcc/config/s390/s390.c b/gcc/config/s390/s390.c index d67c0eb5c57..976d4cbc8a7 100644 --- a/gcc/config/s390/s390.c +++ b/gcc/config/s390/s390.c @@ -2123,6 +2123,22 @@ s390_symref_operand_p (rtx addr, rtx *symref, HOST_WIDE_INT *addend) 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 @@ -2137,7 +2153,7 @@ s390_check_qrst_address (char c, rtx op, bool lit_pool_ok) /* 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)) + if (s390_loadrelative_operand_p (op)) return 0; /* Ensure literal pool references are only accepted if LIT_POOL_OK. */ @@ -2941,6 +2957,13 @@ s390_check_symref_alignment (rtx addr, HOST_WIDE_INT alignment) 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; @@ -3398,9 +3421,14 @@ legitimize_pic_address (rtx orig, rtx reg) 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); + 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; } @@ -5250,7 +5278,7 @@ print_operand_address (FILE *file, rtx addr) { struct s390_address ad; - if (s390_symref_operand_p (addr, NULL, NULL)) + if (s390_loadrelative_operand_p (addr)) { if (!TARGET_Z10) {