pa.c (pa_init_machine_status): Initialize pic_offset_table_save_rtx to NULL_RTX.

* 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.

From-SVN: r39351
This commit is contained in:
John David Anglin 2001-01-30 17:25:29 +00:00 committed by Jeff Law
parent 633254a097
commit d966ae6066
4 changed files with 68 additions and 21 deletions

View File

@ -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> 2001-01-29 lars brinkhoff <lars@nocrew.org>
* tm.texi (PUSH_ROUNDING): Remove duplicate lines. * tm.texi (PUSH_ROUNDING): Remove duplicate lines.

View File

@ -206,7 +206,7 @@ pa_init_machine_status (p)
{ {
p->machine = (machine_function *) xmalloc (sizeof (machine_function)); 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 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));
} }

View File

@ -500,7 +500,7 @@ extern int target_flags;
#define PIC_OFFSET_TABLE_REGNUM (TARGET_64BIT ? 27 : 19) #define PIC_OFFSET_TABLE_REGNUM (TARGET_64BIT ? 27 : 19)
#define PIC_OFFSET_TABLE_REG_CALL_CLOBBERED 1 #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. */ can be restored across function calls. */
#define PIC_OFFSET_TABLE_SAVE_RTX (cfun->machine->pic_offset_table_save_rtx) #define PIC_OFFSET_TABLE_SAVE_RTX (cfun->machine->pic_offset_table_save_rtx)

View File

@ -5737,6 +5737,20 @@
gen_rtx_PLUS (word_mode, virtual_outgoing_args_rtx, gen_rtx_PLUS (word_mode, virtual_outgoing_args_rtx,
GEN_INT (64))); 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 /* Use two different patterns for calls to explicitly named functions
and calls through function pointers. This is necessary as these two and calls through function pointers. This is necessary as these two
types of calls use different calling conventions, and CSE might try 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_rtx_PLUS (word_mode, virtual_outgoing_args_rtx,
GEN_INT (64))); 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 /* Use two different patterns for calls to explicitly named functions
and calls through function pointers. This is necessary as these two and calls through function pointers. This is necessary as these two
types of calls use different calling conventions, and CSE might try types of calls use different calling conventions, and CSE might try
@ -6103,6 +6131,20 @@
op = XEXP (operands[0], 0); 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. */ /* We do not allow indirect sibling calls. */
call_insn = emit_call_insn (gen_sibcall_internal_symref (op, operands[1])); call_insn = emit_call_insn (gen_sibcall_internal_symref (op, operands[1]));
@ -6158,6 +6200,20 @@
op = XEXP (operands[1], 0); 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. */ /* We do not allow indirect sibling calls. */
call_insn = emit_call_insn (gen_sibcall_value_internal_symref (operands[0], call_insn = emit_call_insn (gen_sibcall_value_internal_symref (operands[0],
op, op,