diff options
author | Eric Botcazou <ebotcazou@libertysurf.fr> | 2005-07-01 02:15:02 +0200 |
---|---|---|
committer | Eric Botcazou <ebotcazou@gcc.gnu.org> | 2005-07-01 00:15:02 +0000 |
commit | 1b970c28e234bc5da44c76188c8eca9b4d06382a (patch) | |
tree | 504d5714f80295b300bc412a05b0bc308f9a3936 /gcc/config/sparc/sparc.c | |
parent | 5ed32b3871253040272bef49961d17e0fb471a2b (diff) | |
download | gcc-1b970c28e234bc5da44c76188c8eca9b4d06382a.tar.gz |
re PR target/22260 (-fPIC -fno-delayed-branch miscompiles MI this_adjusting thunks)
PR target/22260
* config/sparc/sparc.c (emit_and_preserve): Add 2nd register.
Preserve the 2nd register too, if present.
(sparc_output_mi_thunk) <PIC case>: Preserve the PIC register too.
Adjust call to emit_and_preserve.
From-SVN: r101484
Diffstat (limited to 'gcc/config/sparc/sparc.c')
-rw-r--r-- | gcc/config/sparc/sparc.c | 20 |
1 files changed, 15 insertions, 5 deletions
diff --git a/gcc/config/sparc/sparc.c b/gcc/config/sparc/sparc.c index a16e3b8da23..69bde4b3b70 100644 --- a/gcc/config/sparc/sparc.c +++ b/gcc/config/sparc/sparc.c @@ -8373,17 +8373,26 @@ sparc_rtx_costs (rtx x, int code, int outer_code, int *total) } } -/* Emit the sequence of insns SEQ while preserving the register REG. */ +/* Emit the sequence of insns SEQ while preserving the registers. */ static void -emit_and_preserve (rtx seq, rtx reg) +emit_and_preserve (rtx seq, rtx reg, rtx reg2) { + /* STACK_BOUNDARY guarantees that this is a 2-word slot. */ rtx slot = gen_rtx_MEM (word_mode, plus_constant (stack_pointer_rtx, SPARC_STACK_BIAS)); emit_insn (gen_stack_pointer_dec (GEN_INT (STACK_BOUNDARY/BITS_PER_UNIT))); emit_insn (gen_rtx_SET (VOIDmode, slot, reg)); + if (reg2) + emit_insn (gen_rtx_SET (VOIDmode, + adjust_address (slot, word_mode, UNITS_PER_WORD), + reg2)); emit_insn (seq); + if (reg2) + emit_insn (gen_rtx_SET (VOIDmode, + reg2, + adjust_address (slot, word_mode, UNITS_PER_WORD))); emit_insn (gen_rtx_SET (VOIDmode, reg, slot)); emit_insn (gen_stack_pointer_inc (GEN_INT (STACK_BOUNDARY/BITS_PER_UNIT))); } @@ -8523,11 +8532,12 @@ sparc_output_mi_thunk (FILE *file, tree thunk_fndecl ATTRIBUTE_UNUSED, { /* The hoops we have to jump through in order to generate a sibcall without using delay slots... */ - rtx spill_reg, seq, scratch = gen_rtx_REG (Pmode, 1); + rtx spill_reg, spill_reg2, seq, scratch = gen_rtx_REG (Pmode, 1); if (flag_pic) { spill_reg = gen_rtx_REG (word_mode, 15); /* %o7 */ + spill_reg2 = gen_rtx_REG (word_mode, PIC_OFFSET_TABLE_REGNUM); start_sequence (); /* Delay emitting the PIC helper function because it needs to change the section and we are emitting assembly code. */ @@ -8535,7 +8545,7 @@ sparc_output_mi_thunk (FILE *file, tree thunk_fndecl ATTRIBUTE_UNUSED, scratch = legitimize_pic_address (funexp, Pmode, scratch); seq = get_insns (); end_sequence (); - emit_and_preserve (seq, spill_reg); + emit_and_preserve (seq, spill_reg, spill_reg2); } else if (TARGET_ARCH32) { @@ -8564,7 +8574,7 @@ sparc_output_mi_thunk (FILE *file, tree thunk_fndecl ATTRIBUTE_UNUSED, sparc_emit_set_symbolic_const64 (scratch, funexp, spill_reg); seq = get_insns (); end_sequence (); - emit_and_preserve (seq, spill_reg); + emit_and_preserve (seq, spill_reg, 0); break; default: |