This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Arg pointer patch for hppa64 tail calls
- From: "John David Anglin" <dave at hiauly1 dot hia dot nrc dot ca>
- To: gcc-patches at gcc dot gnu dot org, law at redhat dot com, rth at redhat dot com
- Date: Sat, 2 Nov 2002 21:26:31 -0500 (EST)
- Subject: Arg pointer patch for hppa64 tail calls
This is the current patch to change the arg pointer handling on hppa64. It
needs this patch <http://gcc.gnu.org/ml/gcc-patches/2002-11/msg00105.html>
to allow the prologue to determine when to save the arg pointer and copy
the incoming arg pointer.
It has been tested with no regressions on hppa64-hp-hpux11.11.
Dave
--
J. David Anglin dave.anglin@nrc.ca
National Research Council of Canada (613) 990-0752 (FAX: 952-6605)
* pa-64.h (ARG_POINTER_REGNUM): Move define to pa.h.
(STATIC_CHAIN_REGNUM): Likewise.
(FUNCTION_OK_FOR_SIBCALL): Define.
* pa.c (arg_pointer_incoming_rtx): Unique rtx for incoming arg pointer.
(override_options): Call pa_init_machine_status on TARGET_64BIT.
(compute_frame_size): Use call really used registers in calculating
frame size.
(hppa_expand_prologue): Use call_really_used_regs instead of
call_used_regs when doing register saves. Copy incoming arg pointer
to fixed arg pointer register.
(hppa_expand_epilogue): Use call_really_used_regs instead of
call_used_regs when doing register restores.
(hppa_profile_hook): Copy virtual_outgoing_args_rtx + 64 to incoming
arg pointer register. Set call usage for incoming arg pointer.
(hppa_builtin_saveregs): Rewrite TARGET_64BIT portion using new
fixed arg pointer.
Miscellaneous format changes.
* pa.h (ARG_POINTER_REGNUM, STATIC_CHAIN_REGNUM): Add TARGET_64BIT
defines.
(ARG_POINTER_INCOMING_REGNUM): Define.
(STARTING_FRAME_OFFSET): Change TARGET_64BIT value to 16.
(arg_pointer_incoming_rtx): Declare.
(FUNCTION_OK_FOR_SIBCALL): Don't exclude TARGET_64BIT.
* pa.md (call, call_value): Move virtual_outgoing_args_rtx + 64 to
arg_pointer_incoming_rtx and adjust call usage to use
arg_pointer_incoming_rtx.
(sibcall, sibcall_value): Move arg_pointer_rtx to
arg_pointer_incoming_rtx and adjust call usage to use
arg_pointer_incoming_rtx.
* pa32-regs.h (CALL_REALLY_USED_REGISTERS): Define.
* pa64-linux.h (ELIMINABLE_REGS, CAN_ELIMINATE,
INITIAL_ELIMINATION_OFFSET): Delete unused defines.
* pa64-regs.h: Update register usage comments.
(CALL_REALLY_USED_REGISTERS): Define.
Index: config/pa/pa-64.h
===================================================================
RCS file: /cvsroot/gcc/gcc/gcc/config/pa/pa-64.h,v
retrieving revision 1.12
diff -u -3 -p -r1.12 pa-64.h
--- config/pa/pa-64.h 17 Sep 2002 03:30:37 -0000 1.12
+++ config/pa/pa-64.h 2 Nov 2002 18:23:55 -0000
@@ -1,6 +1,6 @@
/* Definitions of target machine for GNU compiler, for HPs using the
64bit runtime model.
- Copyright (C) 1999, 2000 Free Software Foundation, Inc.
+ Copyright (C) 1999, 2000, 2002 Free Software Foundation, Inc.
This file is part of GNU CC.
@@ -76,17 +76,26 @@ Boston, MA 02111-1307, USA. */
?!? This may not work reliably. Keep an eye out for problems. */
#undef SECONDARY_MEMORY_NEEDED_RTX
-
/* ?!? This needs to be made compile-time selectable.
The PA64 runtime model has arguments that grow to higher addresses
(like most other targets). The older runtime model has arguments
that grow to lower addresses. What fun. */
#undef ARGS_GROW_DOWNWARD
-#undef ARG_POINTER_REGNUM
-#define ARG_POINTER_REGNUM 29
-#undef STATIC_CHAIN_REGNUM
-#define STATIC_CHAIN_REGNUM 31
+
+/* Sibling calls are mostly ok but there are limitations imposed by
+ the handling of stubs when using GNU ld.
+
+ FIXME: There are problems with out-of-range sibcalls using GNU ld.
+ As a temporary workaround, only enable sibcalls when not using GNU
+ ld or when TARGET_LONG_CALLS is true. GNU ld needs to be fixed to
+ check the distance from the call site to the stub and to generate
+ an error if the distance is too large. It also needs to do a better
+ job placing stubs close to the call site. Currently, it appears
+ to put them all in a stub section. The same problem applies to
+ regular calls but is less severe because of the larger branch range. */
+#undef FUNCTION_OK_FOR_SIBCALL
+#define FUNCTION_OK_FOR_SIBCALL(DECL) (!TARGET_GNU_LD || TARGET_LONG_CALLS)
/* If defined, a C expression which determines whether the default
implementation of va_arg will attempt to pad down before reading the
Index: config/pa/pa.c
===================================================================
RCS file: /cvsroot/gcc/gcc/gcc/config/pa/pa.c,v
retrieving revision 1.185
diff -u -3 -p -r1.185 pa.c
--- config/pa/pa.c 31 Oct 2002 03:13:43 -0000 1.185
+++ config/pa/pa.c 2 Nov 2002 18:24:01 -0000
@@ -95,6 +95,7 @@ hppa_fpstore_bypass_p (out_insn, in_insn
#endif
#endif
+static struct machine_function * pa_init_machine_status PARAMS ((void));
static inline rtx force_mode PARAMS ((enum machine_mode, rtx));
static void pa_combine_instructions PARAMS ((rtx));
static int pa_can_combine_p PARAMS ((rtx, rtx, rtx, int, rtx, rtx, rtx));
@@ -126,6 +127,9 @@ static int length_fp_args PARAMS ((rtx))
static struct deferred_plabel *get_plabel PARAMS ((const char *))
ATTRIBUTE_UNUSED;
+/* Unique rtx for the incoming arg pointer register. */
+rtx arg_pointer_incoming_rtx;
+
/* Save the operands last given to a compare for use when we
generate a scc or bcc insn. */
rtx hppa_compare_op0, hppa_compare_op1;
@@ -205,6 +209,16 @@ static size_t n_deferred_plabels = 0;
struct gcc_target targetm = TARGET_INITIALIZER;
+static struct machine_function *
+pa_init_machine_status ()
+{
+ if (arg_pointer_incoming_rtx == 0)
+ arg_pointer_incoming_rtx
+ = gen_rtx_REG (Pmode, ARG_POINTER_INCOMING_REGNUM);
+
+ return NULL;
+}
+
void
override_options ()
{
@@ -289,7 +303,7 @@ override_options ()
warning ("PIC code generation is not compatible with fast indirect calls\n");
}
- if (! TARGET_GAS && write_symbols != NO_DEBUG)
+ if (!TARGET_GAS && write_symbols != NO_DEBUG)
{
warning ("-g is only supported when using GAS on this processor,");
warning ("-g option disabled");
@@ -312,6 +326,9 @@ override_options ()
targetm.asm_out.unaligned_op.si = NULL;
targetm.asm_out.unaligned_op.di = NULL;
}
+
+ if (TARGET_64BIT)
+ init_machine_status = pa_init_machine_status;
}
/* Return nonzero only if OP is a register of mode MODE,
@@ -3106,9 +3123,11 @@ compute_frame_size (size, fregs_live)
fsize += i * UNITS_PER_WORD;
}
- /* Account for space used by the callee general register saves. */
+ /* Account for space used by the callee general register saves.
+ We use call_really_used_regs instead of call_used_regs to reserve
+ a slot for the arg pointer on TARGET_64BIT when it is needed. */
for (i = 18; i >= 3; i--)
- if (regs_ever_live[i])
+ if (regs_ever_live[i] && !call_really_used_regs[i])
fsize += UNITS_PER_WORD;
/* Round the stack. */
@@ -3347,7 +3366,7 @@ hppa_expand_prologue ()
}
for (i = 18; i >= 4; i--)
- if (regs_ever_live[i] && ! call_used_regs[i])
+ if (regs_ever_live[i] && !call_really_used_regs[i])
{
store_reg (i, offset, FRAME_POINTER_REGNUM);
offset += UNITS_PER_WORD;
@@ -3387,7 +3406,7 @@ hppa_expand_prologue ()
}
for (i = 18; i >= 3; i--)
- if (regs_ever_live[i] && ! call_used_regs[i])
+ if (regs_ever_live[i] && !call_really_used_regs[i])
{
/* If merge_sp_adjust_with_store is nonzero, then we can
optimize the first GR save. */
@@ -3488,6 +3507,14 @@ hppa_expand_prologue ()
}
}
+#ifdef ARG_POINTER_INCOMING_REGNUM
+ if (ARG_POINTER_REGNUM != ARG_POINTER_INCOMING_REGNUM
+ && regs_ever_live[ARG_POINTER_REGNUM])
+ {
+ emit_move_insn (arg_pointer_rtx, arg_pointer_incoming_rtx);
+ }
+#endif
+
/* FIXME: expand_call and expand_millicode_call need to be fixed to
prevent insns with frame notes being scheduled in the delay slot
of calls. This causes problems because the dwarf2 output code
@@ -3620,7 +3647,7 @@ hppa_expand_epilogue ()
}
for (i = 18; i >= 4; i--)
- if (regs_ever_live[i] && ! call_used_regs[i])
+ if (regs_ever_live[i] && !call_really_used_regs[i])
{
load_reg (i, offset, FRAME_POINTER_REGNUM);
offset += UNITS_PER_WORD;
@@ -3657,7 +3684,7 @@ hppa_expand_epilogue ()
for (i = 18; i >= 3; i--)
{
- if (regs_ever_live[i] && ! call_used_regs[i])
+ if (regs_ever_live[i] && !call_really_used_regs[i])
{
/* Only for the first load.
merge_sp_adjust_with_load holds the register load
@@ -3758,7 +3785,7 @@ hppa_profile_hook (label_no)
begin_label_rtx = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (begin_label_name));
if (TARGET_64BIT)
- emit_move_insn (arg_pointer_rtx,
+ emit_move_insn (arg_pointer_incoming_rtx,
gen_rtx_PLUS (word_mode, virtual_outgoing_args_rtx,
GEN_INT (64)));
@@ -3801,7 +3828,8 @@ hppa_profile_hook (label_no)
{
use_reg (&CALL_INSN_FUNCTION_USAGE (call_insn), pic_offset_table_rtx);
if (TARGET_64BIT)
- use_reg (&CALL_INSN_FUNCTION_USAGE (call_insn), arg_pointer_rtx);
+ use_reg (&CALL_INSN_FUNCTION_USAGE (call_insn),
+ arg_pointer_incoming_rtx);
emit_move_insn (pic_offset_table_rtx, hppa_pic_save_rtx ());
}
@@ -5185,13 +5213,9 @@ hppa_builtin_saveregs ()
!= void_type_node)))
? UNITS_PER_WORD : 0);
- if (argadj)
- offset = plus_constant (current_function_arg_offset_rtx, argadj);
- else
- offset = current_function_arg_offset_rtx;
-
if (TARGET_64BIT)
{
+ rtx pa64_arg_pointer_rtx = plus_constant (arg_pointer_rtx, -64);
int i, off;
/* Adjust for varargs/stdarg differences. */
@@ -5207,18 +5231,15 @@ hppa_builtin_saveregs ()
plus_constant (arg_pointer_rtx, off)),
gen_rtx_REG (word_mode, i));
- /* The incoming args pointer points just beyond the flushback area;
- normally this is not a serious concern. However, when we are doing
- varargs/stdargs we want to make the arg pointer point to the start
- of the incoming argument area. */
- emit_move_insn (virtual_incoming_args_rtx,
- plus_constant (arg_pointer_rtx, -64));
-
/* Now return a pointer to the first anonymous argument. */
- return copy_to_reg (expand_binop (Pmode, add_optab,
- virtual_incoming_args_rtx,
+ return copy_to_reg (expand_binop (Pmode, add_optab, pa64_arg_pointer_rtx,
offset, 0, 0, OPTAB_LIB_WIDEN));
}
+
+ if (argadj)
+ offset = plus_constant (current_function_arg_offset_rtx, argadj);
+ else
+ offset = current_function_arg_offset_rtx;
/* Store general registers on the stack. */
dest = gen_rtx_MEM (BLKmode,
Index: config/pa/pa.h
===================================================================
RCS file: /cvsroot/gcc/gcc/gcc/config/pa/pa.h,v
retrieving revision 1.174
diff -u -3 -p -r1.174 pa.h
--- config/pa/pa.h 31 Oct 2002 03:13:43 -0000 1.174
+++ config/pa/pa.h 2 Nov 2002 18:24:03 -0000
@@ -528,15 +528,30 @@ do { \
#define INITIAL_FRAME_POINTER_OFFSET(VAR) \
do {(VAR) = - compute_frame_size (get_frame_size (), 0);} while (0)
-/* Base register for access to arguments of the function. */
-#define ARG_POINTER_REGNUM 3
+/* Base register for access to arguments of the function.
+
+ For TARGET_64BIT, the incoming argument pointer is in GR (29).
+ This register is also used for millicode returns and can't be
+ fixed. We can't use the frame pointer for the argument pointer
+ because both the stack and arguments grow upward. The offset
+ between the argument pointer and the stack pointer varies from
+ one caller to another. This makes it impossible to eliminate
+ the argument pointer. If we use GR (29) as the arg pointer
+ register, then it is copied to a pseudo in assign_parms because
+ it isn't fixed. This copy inhibits tail and sibcall optimization.
+ Thus, we need to dedicate a fixed register for the argument
+ pointer and copy the incoming value to it in the function prologue.
+
+ For !TARGET_64BIT, we can use the frame pointer for the argument
+ pointer as args grow downward. */
+#define ARG_POINTER_REGNUM (TARGET_64BIT ? 4 : 3)
+#define ARG_POINTER_INCOMING_REGNUM (TARGET_64BIT ? 29 : 3)
/* Register in which static-chain is passed to a function. */
-#define STATIC_CHAIN_REGNUM 29
+#define STATIC_CHAIN_REGNUM (TARGET_64BIT ? 31 : 29)
/* Register which holds offset table for position-independent
data references. */
-
#define PIC_OFFSET_TABLE_REGNUM (TARGET_64BIT ? 27 : 19)
#define PIC_OFFSET_TABLE_REG_CALL_CLOBBERED 1
@@ -672,8 +687,10 @@ extern struct rtx_def *hppa_pic_save_rtx
/* Offset within stack frame to start allocating local variables at.
If FRAME_GROWS_DOWNWARD, this is the offset to the END of the
first local allocated. Otherwise, it is the offset to the BEGINNING
- of the first local allocated. */
-#define STARTING_FRAME_OFFSET 8
+ of the first local allocated. The start of the locals must lie on
+ a STACK_BOUNDARY or else the frame size of leaf functions will not
+ be zero. */
+#define STARTING_FRAME_OFFSET (TARGET_64BIT ? 16 : 8)
/* If we generate an insn to push BYTES bytes,
this says how many the stack pointer really advances by.
@@ -708,7 +725,7 @@ extern struct rtx_def *hppa_pic_save_rtx
This is the difference between the logical top of stack and the
actual sp. */
#define STACK_POINTER_OFFSET \
- (TARGET_64BIT ? -(current_function_outgoing_args_size + 16): -32)
+ (TARGET_64BIT ? -(current_function_outgoing_args_size + 16) : -32)
#define STACK_DYNAMIC_OFFSET(FNDECL) \
(TARGET_64BIT \
@@ -924,6 +941,8 @@ struct hppa_args {int words, nargs_proto
FUNCTION_ARG_PASS_BY_REFERENCE (CUM, MODE, TYPE, NAMED)
+extern GTY(()) rtx arg_pointer_incoming_rtx;
+
extern GTY(()) rtx hppa_compare_op0;
extern GTY(()) rtx hppa_compare_op1;
extern enum cmp_type hppa_branch_type;
@@ -1927,7 +1946,6 @@ do { \
#define FUNCTION_OK_FOR_SIBCALL(DECL) \
(DECL \
&& ! TARGET_PORTABLE_RUNTIME \
- && ! TARGET_64BIT \
&& ! TREE_PUBLIC (DECL))
#define PREDICATE_CODES \
Index: config/pa/pa.md
===================================================================
RCS file: /cvsroot/gcc/gcc/gcc/config/pa/pa.md,v
retrieving revision 1.114
diff -u -3 -p -r1.114 pa.md
--- config/pa/pa.md 31 Oct 2002 03:13:43 -0000 1.114
+++ config/pa/pa.md 2 Nov 2002 18:24:05 -0000
@@ -5910,7 +5910,7 @@
op = XEXP (operands[0], 0);
if (TARGET_64BIT)
- emit_move_insn (arg_pointer_rtx,
+ emit_move_insn (arg_pointer_incoming_rtx,
gen_rtx_PLUS (word_mode, virtual_outgoing_args_rtx,
GEN_INT (64)));
@@ -5935,7 +5935,7 @@
}
if (TARGET_64BIT)
- use_reg (&CALL_INSN_FUNCTION_USAGE (call_insn), arg_pointer_rtx);
+ use_reg (&CALL_INSN_FUNCTION_USAGE (call_insn), arg_pointer_incoming_rtx);
if (flag_pic)
{
@@ -6077,7 +6077,7 @@
op = XEXP (operands[1], 0);
if (TARGET_64BIT)
- emit_move_insn (arg_pointer_rtx,
+ emit_move_insn (arg_pointer_incoming_rtx,
gen_rtx_PLUS (word_mode, virtual_outgoing_args_rtx,
GEN_INT (64)));
@@ -6107,7 +6107,7 @@
}
if (TARGET_64BIT)
- use_reg (&CALL_INSN_FUNCTION_USAGE (call_insn), arg_pointer_rtx);
+ use_reg (&CALL_INSN_FUNCTION_USAGE (call_insn), arg_pointer_incoming_rtx);
if (flag_pic)
{
@@ -6276,10 +6276,10 @@
op = XEXP (operands[0], 0);
+ /* As the frame is popped in the sibcall, we use the arg pointer for
+ this function rather than one based on virtual_outgoing_args_rtx. */
if (TARGET_64BIT)
- emit_move_insn (arg_pointer_rtx,
- gen_rtx_PLUS (word_mode, virtual_outgoing_args_rtx,
- GEN_INT (64)));
+ emit_move_insn (arg_pointer_incoming_rtx, arg_pointer_rtx);
/* Indirect sibling calls are not allowed. */
if (TARGET_64BIT)
@@ -6290,7 +6290,7 @@
call_insn = emit_call_insn (call_insn);
if (TARGET_64BIT)
- use_reg (&CALL_INSN_FUNCTION_USAGE (call_insn), arg_pointer_rtx);
+ use_reg (&CALL_INSN_FUNCTION_USAGE (call_insn), arg_pointer_incoming_rtx);
if (flag_pic)
{
@@ -6346,10 +6346,10 @@
op = XEXP (operands[1], 0);
+ /* As the frame is popped in the sibcall, we use the arg pointer for
+ this function rather than one based on virtual_outgoing_args_rtx. */
if (TARGET_64BIT)
- emit_move_insn (arg_pointer_rtx,
- gen_rtx_PLUS (word_mode, virtual_outgoing_args_rtx,
- GEN_INT (64)));
+ emit_move_insn (arg_pointer_incoming_rtx, arg_pointer_rtx);
/* Indirect sibling calls are not allowed. */
if (TARGET_64BIT)
@@ -6362,7 +6362,7 @@
call_insn = emit_call_insn (call_insn);
if (TARGET_64BIT)
- use_reg (&CALL_INSN_FUNCTION_USAGE (call_insn), arg_pointer_rtx);
+ use_reg (&CALL_INSN_FUNCTION_USAGE (call_insn), arg_pointer_incoming_rtx);
if (flag_pic)
{
Index: config/pa/pa32-regs.h
===================================================================
RCS file: /cvsroot/gcc/gcc/gcc/config/pa/pa32-regs.h,v
retrieving revision 1.11
diff -u -3 -p -r1.11 pa32-regs.h
--- config/pa/pa32-regs.h 3 Sep 2002 18:01:23 -0000 1.11
+++ config/pa/pa32-regs.h 2 Nov 2002 18:24:05 -0000
@@ -95,6 +95,8 @@
1, 1, 1, 1, 1, 1, 1, 1, \
1}
+#define CALL_REALLY_USED_REGISTERS CALL_USED_REGISTERS
+
#define CONDITIONAL_REGISTER_USAGE \
{ \
int i; \
Index: config/pa/pa64-linux.h
===================================================================
RCS file: /cvsroot/gcc/gcc/gcc/config/pa/pa64-linux.h,v
retrieving revision 1.3
diff -u -3 -p -r1.3 pa64-linux.h
--- config/pa/pa64-linux.h 22 Sep 2002 19:23:19 -0000 1.3
+++ config/pa/pa64-linux.h 2 Nov 2002 18:24:05 -0000
@@ -18,55 +18,3 @@ along with GNU CC; see the file COPYING.
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
-#if 0 /* needs some work :-( */
-/* If defined, this macro specifies a table of register pairs used to
- eliminate unneeded registers that point into the stack frame. */
-
-#define ELIMINABLE_REGS \
-{ \
- {FRAME_POINTER_REGNUM, STACK_POINTER_REGNUM}, \
- {ARG_POINTER_REGNUM, STACK_POINTER_REGNUM}, \
- {ARG_POINTER_REGNUM, FRAME_POINTER_REGNUM}, \
-}
-
-/* A C expression that returns nonzero if the compiler is allowed to try to
- replace register number FROM with register number TO. The frame pointer
- is automatically handled. */
-
-#define CAN_ELIMINATE(FROM, TO) 1
-
-/* This macro is similar to `INITIAL_FRAME_POINTER_OFFSET'. It
- specifies the initial difference between the specified pair of
- registers. This macro must be defined if `ELIMINABLE_REGS' is
- defined. */
-#define INITIAL_ELIMINATION_OFFSET(FROM, TO, OFFSET) \
- do \
- { \
- int fsize; \
- \
- fsize = compute_frame_size (get_frame_size (), 0); \
- if ((TO) == FRAME_POINTER_REGNUM \
- && (FROM) == ARG_POINTER_REGNUM) \
- { \
- (OFFSET) = -16; \
- break; \
- } \
- \
- if ((TO) != STACK_POINTER_REGNUM) \
- abort (); \
- \
- switch (FROM) \
- { \
- case FRAME_POINTER_REGNUM: \
- (OFFSET) = - fsize; \
- break; \
- \
- case ARG_POINTER_REGNUM: \
- (OFFSET) = - fsize - 16; \
- break; \
- \
- default: \
- abort (); \
- } \
- } while (0)
-#endif
Index: config/pa/pa64-regs.h
===================================================================
RCS file: /cvsroot/gcc/gcc/gcc/config/pa/pa64-regs.h,v
retrieving revision 1.10
diff -u -3 -p -r1.10 pa64-regs.h
--- config/pa/pa64-regs.h 4 Sep 2002 18:09:32 -0000 1.10
+++ config/pa/pa64-regs.h 2 Nov 2002 18:24:05 -0000
@@ -48,29 +48,27 @@ Boston, MA 02111-1307, USA. */
Reg 0 = 0 (hardware). However, 0 is used for condition code,
so is not fixed.
Reg 1 = ADDIL target/Temporary (hardware).
- Reg 2 = Return Pointer
+ Reg 2 = Return Pointer, Millicode Return Pointer
Reg 3 = Frame Pointer
- Reg 4 = Frame Pointer (>8k varying frame with HP compilers only)
+ Reg 4 = Internal Argument Pointer
Reg 4-18 = Preserved Registers
- Reg 19 = Linkage Table Register in HPUX 8.0 shared library scheme.
- Reg 20-22 = Temporary Registers
- Reg 23-26 = Temporary/Parameter Registers
+ Reg 19-26 = Temporary/Parameter Registers
Reg 27 = Global Data Pointer (hp)
- Reg 28 = Temporary/Return Value register
- Reg 29 = Temporary/Static Chain/Return Value register #2
+ Reg 28 = Temporary/Return Value register #1
+ Reg 29 = Temporary/Arg Pointer register/Return Value register #2
Reg 30 = stack pointer
- Reg 31 = Temporary/Millicode Return Pointer (hp)
+ Reg 31 = Temporary/Static Chain/Millicode Return Pointer register (hp)
Freg 0-3 = Status Registers -- Not known to the compiler.
Freg 4-7 = Arguments/Return Value
Freg 8-11 = Temporary Registers
Freg 12-21 = Preserved Registers
- Freg 22-31 = Temporary Registers
+ Freg 22-31 = Temporary Registers
*/
#define FIXED_REGISTERS \
- {0, 0, 0, 0, 0, 0, 0, 0, \
+ {0, 0, 0, 0, 1, 0, 0, 0, \
0, 0, 0, 0, 0, 0, 0, 0, \
0, 0, 0, 0, 0, 0, 0, 0, \
0, 0, 0, 1, 0, 0, 1, 0, \
@@ -89,6 +87,21 @@ Boston, MA 02111-1307, USA. */
and the register where structure-value addresses are passed.
Aside from that, you can include as many other registers as you like. */
#define CALL_USED_REGISTERS \
+ {1, 1, 1, 0, 1, 0, 0, 0, \
+ 0, 0, 0, 0, 0, 0, 0, 0, \
+ 0, 0, 0, 1, 1, 1, 1, 1, \
+ 1, 1, 1, 1, 1, 1, 1, 1, \
+ /* fp registers */ \
+ 1, 1, 1, 1, 1, 1, 1, 1, \
+ 0, 0, 0, 0, 0, 0, 0, 0, \
+ 0, 0, 1, 1, 1, 1, 1, 1, \
+ 1, 1, 1, 1, \
+ /* shift register */ \
+ 1}
+
+/* This differs from CALL_USED_REGISTERS only in that GR (4)
+ is not really call used. */
+#define CALL_REALLY_USED_REGISTERS \
{1, 1, 1, 0, 0, 0, 0, 0, \
0, 0, 0, 0, 0, 0, 0, 0, \
0, 0, 0, 1, 1, 1, 1, 1, \