* config/pa/pa.h (PIC_OFFSET_TABLE_REGNUM_SAVED): Remove.
(machine_function): Define.
(PIC_OFFSET_TABLE_SAVE_RTX) : Define.
* config/pa/pa.c (pa_init_machine_status, pa_mark_machine_status,
pa_free_machine_status): New functions.
(override_options): Set {init,mark,free}_machine_status to above.
(hppa_expand_prologue): Use PIC_OFFSET_TABLE_SAVE_RTX instead of
PIC_OFFSET_TABLE_REGNUM_SAVED.
* config/pa/pa.md: Use PIC_OFFSET_TABLE_SAVE_RTX instead of
PIC_OFFSET_TABLE_REGNUM_SAVED throughout.
* config/pa/pa32-regs.h (CONDITIONAL_REGISTER_USAGE): Remove
references to PIC_OFFSET_TABLE_REGNUM_SAVED.
* config/pa/pa64-regs.h (CONDITIONAL_REGISTER_USAGE): Likewise.
From-SVN: r39083
+Tue Jan 16 22:23:04 2001 Alan Modra (alan@linuxcare.com.au)
+
+ * config/pa/pa.h (PIC_OFFSET_TABLE_REGNUM_SAVED): Remove.
+ (machine_function): Define.
+ (PIC_OFFSET_TABLE_SAVE_RTX) : Define.
+ * config/pa/pa.c (pa_init_machine_status, pa_mark_machine_status,
+ pa_free_machine_status): New functions.
+ (override_options): Set {init,mark,free}_machine_status to above.
+ (hppa_expand_prologue): Use PIC_OFFSET_TABLE_SAVE_RTX instead of
+ PIC_OFFSET_TABLE_REGNUM_SAVED.
+ * config/pa/pa.md: Use PIC_OFFSET_TABLE_SAVE_RTX instead of
+ PIC_OFFSET_TABLE_REGNUM_SAVED throughout.
+ * config/pa/pa32-regs.h (CONDITIONAL_REGISTER_USAGE): Remove
+ references to PIC_OFFSET_TABLE_REGNUM_SAVED.
+ * config/pa/pa64-regs.h (CONDITIONAL_REGISTER_USAGE): Likewise.
+
2001-01-15 DJ Delorie <dj@redhat.com>
* Makefile.in (gcov.1): Protect against texi2pod/pod2man failing.
/* Subroutines for insn-output.c for HPPA.
- Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000
+ Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001
Free Software Foundation, Inc.
Contributed by Tim Moore (moore@cs.utah.edu), based on sparc.c
#include "recog.h"
#include "tm_p.h"
+static void pa_init_machine_status PARAMS ((struct function *));
+static void pa_mark_machine_status PARAMS ((struct function *));
+static void pa_free_machine_status PARAMS ((struct function *));
static void pa_combine_instructions PARAMS ((rtx));
static int pa_can_combine_p PARAMS ((rtx, rtx, rtx, int, rtx, rtx, rtx));
static int forward_branch_p PARAMS ((rtx));
/* Register global variables with the garbage collector. */
pa_add_gc_roots ();
+
+ /* Arrange to save and restore machine status around nested functions. */
+ init_machine_status = pa_init_machine_status;
+ mark_machine_status = pa_mark_machine_status;
+ free_machine_status = pa_free_machine_status;
+}
+
+/* Functions to initialize pic_offset_table_save_rtx.
+ These will be called, via pointer variables,
+ from push_function_context and pop_function_context. */
+
+static void
+pa_init_machine_status (p)
+ struct function *p;
+{
+ p->machine = (machine_function *) xmalloc (sizeof (machine_function));
+
+ p->machine->pic_offset_table_save_rtx = gen_reg_rtx (Pmode);
+}
+
+static void
+pa_mark_machine_status (p)
+ struct function *p;
+{
+ if (p->machine)
+ ggc_mark_rtx (p->machine->pic_offset_table_save_rtx);
+}
+
+static void
+pa_free_machine_status (p)
+ struct function *p;
+{
+ if (p->machine == NULL)
+ return;
+
+ free (p->machine);
+ p->machine = NULL;
}
}
\f
-/* You may have trouble believing this, but this is the HP-PA stack
+/* You may have trouble believing this, but this is the 32 bit HP-PA stack
layout. Wow.
Offset Contents
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 reserved callee saved
- register in the prologue. Then after each call we reload the PIC
- register from the callee saved register. We also reload the PIC
- register from the callee saved register in the epilogue ensure the
- PIC register is valid at function exit.
+ 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.
- This may (depending on the exact characteristics of the function)
- even be more efficient.
+ Avoid doing this if the register isn't used (eg. leaf functions)
+ as it's an error to delete an instruction from the prologue. */
- Avoid this if the callee saved register wasn't used (these are
- leaf functions). */
- if (flag_pic && regs_ever_live[PIC_OFFSET_TABLE_REGNUM_SAVED])
- emit_move_insn (gen_rtx_REG (word_mode, PIC_OFFSET_TABLE_REGNUM_SAVED),
+ 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));
}
ARCHITECTURE_20
};
+struct rtx_def;
+/* A C structure for machine-specific, per-function data.
+ This is added to the cfun structure. */
+typedef struct machine_function
+{
+ struct rtx_def *pic_offset_table_save_rtx;
+} machine_function;
+
/* For -march= option. */
extern const char *pa_arch_string;
extern enum architecture_type pa_arch;
#define PIC_OFFSET_TABLE_REG_CALL_CLOBBERED 1
/* Register into which we save the PIC_OFFEST_TABLE_REGNUM so that it
- can be restore across function calls. */
-#define PIC_OFFSET_TABLE_REGNUM_SAVED 4
+ can be restored across function calls. */
+#define PIC_OFFSET_TABLE_SAVE_RTX (cfun->machine->pic_offset_table_save_rtx)
#define DEFAULT_PCC_STRUCT_RETURN 0
if (flag_pic)
{
use_reg (&CALL_INSN_FUNCTION_USAGE (call_insn), pic_offset_table_rtx);
- use_reg (&CALL_INSN_FUNCTION_USAGE (call_insn),
- gen_rtx_REG (word_mode, PIC_OFFSET_TABLE_REGNUM_SAVED));
if (TARGET_64BIT)
use_reg (&CALL_INSN_FUNCTION_USAGE (call_insn), arg_pointer_rtx);
/* After each call we must restore the PIC register, even if it
- doesn't appear to be used.
-
- This will set regs_ever_live for the callee saved register we
- stored the PIC register in. */
- emit_move_insn (pic_offset_table_rtx,
- gen_rtx_REG (word_mode, PIC_OFFSET_TABLE_REGNUM_SAVED));
+ doesn't appear to be used. */
+ emit_move_insn (pic_offset_table_rtx, PIC_OFFSET_TABLE_SAVE_RTX);
}
DONE;
}")
if (flag_pic)
{
use_reg (&CALL_INSN_FUNCTION_USAGE (call_insn), pic_offset_table_rtx);
- use_reg (&CALL_INSN_FUNCTION_USAGE (call_insn),
- gen_rtx_REG (word_mode, PIC_OFFSET_TABLE_REGNUM_SAVED));
if (TARGET_64BIT)
use_reg (&CALL_INSN_FUNCTION_USAGE (call_insn), arg_pointer_rtx);
/* After each call we must restore the PIC register, even if it
- doesn't appear to be used.
-
- This will set regs_ever_live for the callee saved register we
- stored the PIC register in. */
- emit_move_insn (pic_offset_table_rtx,
- gen_rtx_REG (word_mode, PIC_OFFSET_TABLE_REGNUM_SAVED));
+ doesn't appear to be used. */
+ emit_move_insn (pic_offset_table_rtx, PIC_OFFSET_TABLE_SAVE_RTX);
}
DONE;
}")
if (flag_pic)
{
use_reg (&CALL_INSN_FUNCTION_USAGE (call_insn), pic_offset_table_rtx);
- use_reg (&CALL_INSN_FUNCTION_USAGE (call_insn),
- gen_rtx_REG (word_mode, PIC_OFFSET_TABLE_REGNUM_SAVED));
/* After each call we must restore the PIC register, even if it
- doesn't appear to be used.
-
- This will set regs_ever_live for the callee saved register we
- stored the PIC register in. */
- emit_move_insn (pic_offset_table_rtx,
- gen_rtx_REG (word_mode, PIC_OFFSET_TABLE_REGNUM_SAVED));
+ doesn't appear to be used. */
+ emit_move_insn (pic_offset_table_rtx, PIC_OFFSET_TABLE_SAVE_RTX);
}
DONE;
}")
if (flag_pic)
{
use_reg (&CALL_INSN_FUNCTION_USAGE (call_insn), pic_offset_table_rtx);
- use_reg (&CALL_INSN_FUNCTION_USAGE (call_insn),
- gen_rtx_REG (word_mode, PIC_OFFSET_TABLE_REGNUM_SAVED));
/* After each call we must restore the PIC register, even if it
- doesn't appear to be used.
-
- This will set regs_ever_live for the callee saved register we
- stored the PIC register in. */
- emit_move_insn (pic_offset_table_rtx,
- gen_rtx_REG (word_mode, PIC_OFFSET_TABLE_REGNUM_SAVED));
+ doesn't appear to be used. */
+ emit_move_insn (pic_offset_table_rtx, PIC_OFFSET_TABLE_SAVE_RTX);
}
DONE;
}")
fixed_regs[i] = call_used_regs[i] = 1; \
} \
if (flag_pic) \
- { \
- fixed_regs[PIC_OFFSET_TABLE_REGNUM] = 1; \
- fixed_regs[PIC_OFFSET_TABLE_REGNUM_SAVED] = 1;\
- call_used_regs[PIC_OFFSET_TABLE_REGNUM_SAVED] = 1;\
- } \
+ fixed_regs[PIC_OFFSET_TABLE_REGNUM] = 1; \
}
/* Allocate the call used registers first. This should minimize
fixed_regs[i] = call_used_regs[i] = 1; \
} \
if (flag_pic) \
- { \
- fixed_regs[PIC_OFFSET_TABLE_REGNUM] = 1; \
- fixed_regs[PIC_OFFSET_TABLE_REGNUM_SAVED] = 1;\
- call_used_regs[PIC_OFFSET_TABLE_REGNUM_SAVED] = 1;\
- } \
+ fixed_regs[PIC_OFFSET_TABLE_REGNUM] = 1; \
}
/* Allocate the call used registers first. This should minimize