diff options
author | krebbel <krebbel@138bc75d-0d04-0410-961f-82ee72b054a4> | 2008-07-14 06:56:46 +0000 |
---|---|---|
committer | krebbel <krebbel@138bc75d-0d04-0410-961f-82ee72b054a4> | 2008-07-14 06:56:46 +0000 |
commit | 08b5e26232fa08e766f268d46fad5c0714ae14b4 (patch) | |
tree | 248042c82d6c3e0c548673cd33a0225dc6bfff91 /gcc/config/s390 | |
parent | 89768577114030eb69375ca94b7e749ae2428868 (diff) | |
download | gcc-08b5e26232fa08e766f268d46fad5c0714ae14b4.tar.gz |
2008-07-14 Andreas Krebbel <krebbel1@de.ibm.com>
PR target/36745
* config/s390/s390.c: (s390_secondary_reload): Add a secondary
reload for symbol refs moved to r0 with -fPIC.
(legitimize_pic_address): Use the target register as temporary
reg if possible.
(emit_symbolic_move): Adjust comment.
* config/s390/s390.md (reloadsi_PIC_addr, reloaddi_PIC_addr):
New expanders.
2008-07-14 Andreas Krebbel <krebbel1@de.ibm.com>
PR target/36745
* g++.dg/torture/pr36745.C: New testcase.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@137777 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/config/s390')
-rw-r--r-- | gcc/config/s390/s390.c | 23 | ||||
-rw-r--r-- | gcc/config/s390/s390.md | 10 |
2 files changed, 30 insertions, 3 deletions
diff --git a/gcc/config/s390/s390.c b/gcc/config/s390/s390.c index b9f231729a6..936e0a0ead2 100644 --- a/gcc/config/s390/s390.c +++ b/gcc/config/s390/s390.c @@ -3026,6 +3026,14 @@ s390_secondary_reload (bool in_p, rtx x, enum reg_class class, } } + /* A scratch address register is needed when a symbolic constant is + copied to r0 compiling with -fPIC. In other cases the target + register might be used as temporary (see legitimize_pic_address). */ + if (in_p && SYMBOLIC_CONST (x) && flag_pic == 2 && class != ADDR_REGS) + sri->icode = (TARGET_64BIT ? + CODE_FOR_reloaddi_PIC_addr : + CODE_FOR_reloadsi_PIC_addr); + /* Either scratch or no register needed. */ return NO_REGS; } @@ -3272,7 +3280,10 @@ legitimize_pic_address (rtx orig, rtx reg) /* If the GOT offset might be >= 4k, we determine the position of the GOT entry via a PC-relative LARL (@GOTENT). */ - rtx temp = gen_reg_rtx (Pmode); + rtx temp = reg ? reg : gen_reg_rtx (Pmode); + + gcc_assert (REGNO (temp) >= FIRST_PSEUDO_REGISTER + || REGNO_REG_CLASS (REGNO (temp)) == ADDR_REGS); new = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, addr), UNSPEC_GOTENT); new = gen_rtx_CONST (Pmode, new); @@ -3287,7 +3298,10 @@ legitimize_pic_address (rtx orig, rtx reg) /* If the GOT offset might be >= 4k, we have to load it from the literal pool (@GOT). */ - rtx temp = gen_reg_rtx (Pmode); + rtx temp = reg ? reg : gen_reg_rtx (Pmode); + + gcc_assert (REGNO (temp) >= FIRST_PSEUDO_REGISTER + || REGNO_REG_CLASS (REGNO (temp)) == ADDR_REGS); if (reload_in_progress || reload_completed) df_set_regs_ever_live (PIC_OFFSET_TABLE_REGNUM, true); @@ -3707,7 +3721,10 @@ legitimize_tls_address (rtx addr, rtx reg) return new; } -/* Emit insns to move operands[1] into operands[0]. */ +/* Emit insns making the address in operands[1] valid for a standard + move to operands[0]. operands[1] is replaced by an address which + should be used instead of the former RTX to emit the move + pattern. */ void emit_symbolic_move (rtx *operands) diff --git a/gcc/config/s390/s390.md b/gcc/config/s390/s390.md index d33cc5c3267..ec5b7532977 100644 --- a/gcc/config/s390/s390.md +++ b/gcc/config/s390/s390.md @@ -1175,6 +1175,16 @@ DONE; }) +(define_expand "reload<mode>_PIC_addr" + [(parallel [(match_operand 0 "register_operand" "=d") + (match_operand 1 "larl_operand" "") + (match_operand:P 2 "register_operand" "=a")])] + "" +{ + rtx new = legitimize_pic_address (operands[1], operands[2]); + emit_move_insn (operands[0], new); +}) + ; ; movdi instruction pattern(s). ; |