diff options
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ChangeLog | 10 | ||||
-rw-r--r-- | gcc/config/pa/pa.c | 21 | ||||
-rw-r--r-- | gcc/config/pa/pa.h | 2 | ||||
-rw-r--r-- | gcc/config/pa/pa.md | 56 |
4 files changed, 68 insertions, 21 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 158b5c17b1f..8f5a437bbcc 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,13 @@ +2001-01-30 John David Anglin <dave@hiauly1.hia.nrc.ca> + + * pa.c (pa_init_machine_status): Initialize pic_offset_table_save_rtx + to NULL_RTX. + (hppa_expand_prologue): Delete code to save pic offset table register + in the function prologue. + * pa.h (PIC_OFFSET_TABLE_SAVE_RTX): Correct type in comment. + * pa.md (call, call_value, sibcall, sibcall_value): Save the pic offset + table register at the beginning of the function after the prologue. + 2001-01-29 lars brinkhoff <lars@nocrew.org> * tm.texi (PUSH_ROUNDING): Remove duplicate lines. diff --git a/gcc/config/pa/pa.c b/gcc/config/pa/pa.c index 06e96654d89..aad9345ed35 100644 --- a/gcc/config/pa/pa.c +++ b/gcc/config/pa/pa.c @@ -206,7 +206,7 @@ pa_init_machine_status (p) { p->machine = (machine_function *) xmalloc (sizeof (machine_function)); - p->machine->pic_offset_table_save_rtx = gen_reg_rtx (Pmode); + p->machine->pic_offset_table_save_rtx = NULL_RTX; } static void @@ -3186,25 +3186,6 @@ hppa_expand_prologue() } } } - - /* When generating PIC code it is necessary to save/restore the - PIC register around each function call. We used to do this - in the call patterns themselves, but that implementation - made incorrect assumptions about using global variables to hold - per-function rtl code generated in the backend. - - So instead, we copy the PIC register into a callee saved register - in the prologue. Then after each call we reload the PIC register - from the callee saved register. - - Avoid doing this if the register isn't used (eg. leaf functions) - as it's an error to delete an instruction from the prologue. */ - - if (flag_pic - && (GET_CODE (PIC_OFFSET_TABLE_SAVE_RTX) != REG - || HARD_REGISTER_P (PIC_OFFSET_TABLE_SAVE_RTX))) - emit_move_insn (PIC_OFFSET_TABLE_SAVE_RTX, - gen_rtx_REG (word_mode, PIC_OFFSET_TABLE_REGNUM)); } diff --git a/gcc/config/pa/pa.h b/gcc/config/pa/pa.h index bbd3f7ae9d5..898008e7305 100644 --- a/gcc/config/pa/pa.h +++ b/gcc/config/pa/pa.h @@ -500,7 +500,7 @@ extern int target_flags; #define PIC_OFFSET_TABLE_REGNUM (TARGET_64BIT ? 27 : 19) #define PIC_OFFSET_TABLE_REG_CALL_CLOBBERED 1 -/* Register into which we save the PIC_OFFEST_TABLE_REGNUM so that it +/* Register into which we save the PIC_OFFSET_TABLE_REGNUM so that it can be restored across function calls. */ #define PIC_OFFSET_TABLE_SAVE_RTX (cfun->machine->pic_offset_table_save_rtx) diff --git a/gcc/config/pa/pa.md b/gcc/config/pa/pa.md index 76857f4eff4..41dc77c0703 100644 --- a/gcc/config/pa/pa.md +++ b/gcc/config/pa/pa.md @@ -5737,6 +5737,20 @@ gen_rtx_PLUS (word_mode, virtual_outgoing_args_rtx, GEN_INT (64))); + if (flag_pic && PIC_OFFSET_TABLE_SAVE_RTX == NULL_RTX) + { + rtx insn; + + PIC_OFFSET_TABLE_SAVE_RTX = gen_reg_rtx (Pmode); + insn = gen_rtx_SET (VOIDmode, PIC_OFFSET_TABLE_SAVE_RTX, + gen_rtx_REG (word_mode, PIC_OFFSET_TABLE_REGNUM)); + + /* Emit the insn at the beginning of the function after the prologue. */ + push_topmost_sequence (); + emit_insn_after (insn, get_insns ()); + pop_topmost_sequence (); + } + /* Use two different patterns for calls to explicitly named functions and calls through function pointers. This is necessary as these two types of calls use different calling conventions, and CSE might try @@ -5907,6 +5921,20 @@ gen_rtx_PLUS (word_mode, virtual_outgoing_args_rtx, GEN_INT (64))); + if (flag_pic && PIC_OFFSET_TABLE_SAVE_RTX == NULL_RTX) + { + rtx insn; + + PIC_OFFSET_TABLE_SAVE_RTX = gen_reg_rtx (Pmode); + insn = gen_rtx_SET (VOIDmode, PIC_OFFSET_TABLE_SAVE_RTX, + gen_rtx_REG (word_mode, PIC_OFFSET_TABLE_REGNUM)); + + /* Emit the insn at the beginning of the function after the prologue. */ + push_topmost_sequence (); + emit_insn_after (insn, get_insns ()); + pop_topmost_sequence (); + } + /* Use two different patterns for calls to explicitly named functions and calls through function pointers. This is necessary as these two types of calls use different calling conventions, and CSE might try @@ -6103,6 +6131,20 @@ op = XEXP (operands[0], 0); + if (flag_pic && PIC_OFFSET_TABLE_SAVE_RTX == NULL_RTX) + { + rtx insn; + + PIC_OFFSET_TABLE_SAVE_RTX = gen_reg_rtx (Pmode); + insn = gen_rtx_SET (VOIDmode, PIC_OFFSET_TABLE_SAVE_RTX, + gen_rtx_REG (word_mode, PIC_OFFSET_TABLE_REGNUM)); + + /* Emit the insn at the beginning of the function after the prologue. */ + push_topmost_sequence (); + emit_insn_after (insn, get_insns ()); + pop_topmost_sequence (); + } + /* We do not allow indirect sibling calls. */ call_insn = emit_call_insn (gen_sibcall_internal_symref (op, operands[1])); @@ -6158,6 +6200,20 @@ op = XEXP (operands[1], 0); + if (flag_pic && PIC_OFFSET_TABLE_SAVE_RTX == NULL_RTX) + { + rtx insn; + + PIC_OFFSET_TABLE_SAVE_RTX = gen_reg_rtx (Pmode); + insn = gen_rtx_SET (VOIDmode, PIC_OFFSET_TABLE_SAVE_RTX, + gen_rtx_REG (word_mode, PIC_OFFSET_TABLE_REGNUM)); + + /* Emit the insn at the beginning of the function after the prologue. */ + push_topmost_sequence (); + emit_insn_after (insn, get_insns ()); + pop_topmost_sequence (); + } + /* We do not allow indirect sibling calls. */ call_insn = emit_call_insn (gen_sibcall_value_internal_symref (operands[0], op, |