+2017-10-23 Richard Sandiford <richard.sandiford@linaro.org>
+
+ * target.def (starting_frame_offset): New hook.
+ * doc/tm.texi (STARTING_FRAME_OFFSET): Remove in favor of...
+ (TARGET_STARTING_FRAME_OFFSET): ...this new hook.
+ * doc/tm.texi.in: Regenerate.
+ * hooks.h (hook_hwi_void_0): Declare.
+ * hooks.c (hook_hwi_void_0): New function.
+ * doc/rtl.texi: Refer to TARGET_STARTING_FRAME_OFFSET instead of
+ STARTING_FRAME_OFFSET.
+ * builtins.c (expand_builtin_setjmp_receiver): Likewise.
+ * reload1.c (reload): Likewise.
+ * cfgexpand.c (expand_used_vars): Use targetm.starting_frame_offset
+ instead of STARTING_FRAME_OFFSET.
+ * function.c (try_fit_stack_local): Likewise.
+ (assign_stack_local_1): Likewise
+ (instantiate_virtual_regs): Likewise.
+ * rtlanal.c (rtx_addr_can_trap_p_1): Likewise.
+ * config/avr/avr.md (nonlocal_goto_receiver): Likewise.
+ * config/aarch64/aarch64.h (STARTING_FRAME_OFFSET): Delete.
+ * config/alpha/alpha.h (STARTING_FRAME_OFFSET): Likewise.
+ * config/arc/arc.h (STARTING_FRAME_OFFSET): Likewise.
+ * config/arm/arm.h (STARTING_FRAME_OFFSET): Likewise.
+ * config/bfin/bfin.h (STARTING_FRAME_OFFSET): Likewise.
+ * config/c6x/c6x.h (STARTING_FRAME_OFFSET): Likewise.
+ * config/cr16/cr16.h (STARTING_FRAME_OFFSET): Likewise.
+ * config/cris/cris.h (STARTING_FRAME_OFFSET): Likewise.
+ * config/fr30/fr30.h (STARTING_FRAME_OFFSET): Likewise.
+ * config/frv/frv.h (STARTING_FRAME_OFFSET): Likewise.
+ * config/ft32/ft32.h (STARTING_FRAME_OFFSET): Likewise.
+ * config/h8300/h8300.h (STARTING_FRAME_OFFSET): Likewise.
+ * config/i386/i386.h (STARTING_FRAME_OFFSET): Likewise.
+ * config/ia64/ia64.h (STARTING_FRAME_OFFSET): Likewise.
+ * config/m32c/m32c.h (STARTING_FRAME_OFFSET): Likewise.
+ * config/m68k/m68k.h (STARTING_FRAME_OFFSET): Likewise.
+ * config/mcore/mcore.h (STARTING_FRAME_OFFSET): Likewise.
+ * config/mn10300/mn10300.h (STARTING_FRAME_OFFSET): Likewise.
+ * config/moxie/moxie.h (STARTING_FRAME_OFFSET): Likewise.
+ * config/msp430/msp430.h (STARTING_FRAME_OFFSET): Likewise.
+ * config/nds32/nds32.h (STARTING_FRAME_OFFSET): Likewise.
+ * config/nios2/nios2.h (STARTING_FRAME_OFFSET): Likewise.
+ * config/nvptx/nvptx.h (STARTING_FRAME_OFFSET): Likewise.
+ * config/pdp11/pdp11.h (STARTING_FRAME_OFFSET): Likewise.
+ * config/riscv/riscv.h (STARTING_FRAME_OFFSET): Likewise.
+ * config/rl78/rl78.h (STARTING_FRAME_OFFSET): Likewise.
+ * config/rx/rx.h (STARTING_FRAME_OFFSET): Likewise.
+ * config/s390/s390.h (STARTING_FRAME_OFFSET): Likewise.
+ * config/sh/sh.h (STARTING_FRAME_OFFSET): Likewise.
+ * config/sparc/sparc.c (sparc_compute_frame_size): Likewise.
+ * config/sparc/sparc.h (STARTING_FRAME_OFFSET): Likewise.
+ * config/spu/spu.h (STARTING_FRAME_OFFSET): Likewise.
+ * config/stormy16/stormy16.h (STARTING_FRAME_OFFSET): Likewise.
+ * config/tilegx/tilegx.h (STARTING_FRAME_OFFSET): Likewise.
+ * config/tilepro/tilepro.h (STARTING_FRAME_OFFSET): Likewise.
+ * config/v850/v850.h (STARTING_FRAME_OFFSET): Likewise.
+ * config/visium/visium.h (STARTING_FRAME_OFFSET): Likewise.
+ * config/avr/avr.h (STARTING_FRAME_OFFSET): Likewise.
+ * config/avr/avr-protos.h (avr_starting_frame_offset): Likewise.
+ * config/avr/avr.c (avr_starting_frame_offset): Make static and
+ return a HOST_WIDE_INT.
+ (avr_builtin_setjmp_frame_value): Use it instead of
+ STARTING_FRAME_OFFSET.
+ (TARGET_STARTING_FRAME_OFFSET): Redefine.
+ * config/epiphany/epiphany.h (STARTING_FRAME_OFFSET): Delete.
+ * config/epiphany/epiphany.c (epiphany_starting_frame_offset):
+ New function.
+ (TARGET_STARTING_FRAME_OFFSET): Redefine.
+ * config/iq2000/iq2000.h (STARTING_FRAME_OFFSET): Delete.
+ * config/iq2000/iq2000.c (iq2000_starting_frame_offset): New function.
+ (TARGET_CONSTANT_ALIGNMENT): Redefine.
+ * config/lm32/lm32.h (STARTING_FRAME_OFFSET): Delete.
+ * config/lm32/lm32.c (lm32_starting_frame_offset): New function.
+ (TARGET_STARTING_FRAME_OFFSET): Redefine.
+ * config/m32r/m32r.h (STARTING_FRAME_OFFSET): Delete.
+ * config/m32r/m32r.c (m32r_starting_frame_offset): New function.
+ (TARGET_STARTING_FRAME_OFFSET): Redefine.
+ * config/microblaze/microblaze.h (STARTING_FRAME_OFFSET): Delete.
+ * config/microblaze/microblaze.c (microblaze_starting_frame_offset):
+ New function.
+ (TARGET_STARTING_FRAME_OFFSET): Redefine.
+ * config/mips/mips.h (STARTING_FRAME_OFFSET): Delete.
+ * config/mips/mips.c (mips_compute_frame_info): Refer to
+ TARGET_STARTING_FRAME_OFFSET instead of STARTING_FRAME_OFFSET.
+ (mips_starting_frame_offset): New function.
+ (TARGET_STARTING_FRAME_OFFSET): Redefine.
+ * config/mmix/mmix.h (STARTING_FRAME_OFFSET): Delete.
+ * config/mmix/mmix-protos.h (mmix_starting_frame_offset): Delete.
+ * config/mmix/mmix.c (mmix_starting_frame_offset): Make static
+ and return a HOST_WIDE_INT.
+ (TARGET_STARTING_FRAME_OFFSET): Redefine.
+ (mmix_initial_elimination_offset): Refer to
+ TARGET_STARTING_FRAME_OFFSET instead of STARTING_FRAME_OFFSET.
+ * config/pa/pa.h (STARTING_FRAME_OFFSET): Delete.
+ * config/pa/pa.c (pa_starting_frame_offset): New function.
+ (pa_compute_frame_size): Use it instead of STARTING_FRAME_OFFSET.
+ (pa_expand_prologue): Likewise.
+ (TARGET_STARTING_FRAME_OFFSET): Redefine.
+ * config/powerpcspe/aix.h (STARTING_FRAME_OFFSET): Split out
+ !FRAME_GROWS_DOWNWARD handling to...
+ (RS6000_STARTING_FRAME_OFFSET): ...this new macro.
+ * config/powerpcspe/darwin.h (STARTING_FRAME_OFFSET): Split out
+ !FRAME_GROWS_DOWNWARD handling to...
+ (RS6000_STARTING_FRAME_OFFSET): ...this new macro.
+ * config/powerpcspe/powerpcspe.h (STARTING_FRAME_OFFSET): Split out
+ !FRAME_GROWS_DOWNWARD handling to...
+ (RS6000_STARTING_FRAME_OFFSET): ...this new macro.
+ * config/powerpcspe/powerpcspe.c (TARGET_STARTING_FRAME_OFFSET):
+ Redefine.
+ (rs6000_starting_frame_offset): New function.
+ * config/rs6000/aix.h (STARTING_FRAME_OFFSET): Split out
+ !FRAME_GROWS_DOWNWARD handling to...
+ (RS6000_STARTING_FRAME_OFFSET): ...this new macro.
+ * config/rs6000/darwin.h (STARTING_FRAME_OFFSET): Split out
+ !FRAME_GROWS_DOWNWARD handling to...
+ (RS6000_STARTING_FRAME_OFFSET): ...this new macro.
+ * config/rs6000/rs6000.h (STARTING_FRAME_OFFSET): Split out
+ !FRAME_GROWS_DOWNWARD handling to...
+ (RS6000_STARTING_FRAME_OFFSET): ...this new macro.
+ * config/rs6000/rs6000.c (TARGET_STARTING_FRAME_OFFSET): Refine.
+ (rs6000_starting_frame_offset): New function.
+ * config/vax/elf.h (STARTING_FRAME_OFFSET): Delete.
+ * config/vax/vax.h (STARTING_FRAME_OFFSET): Delete.
+ * config/vax/vax.c (vax_starting_frame_offset): New function.
+ (vax_expand_prologue): Use it instead of STARTING_FRAME_OFFSET.
+ (TARGET_STARTING_FRAME_OFFSET): Redefine.
+ * config/xtensa/xtensa.h (STARTING_FRAME_OFFSET): Delete.
+ * config/xtensa/xtensa.c (xtensa_starting_frame_offset): New function.
+ (TARGET_STARTING_FRAME_OFFSET): Redefine.
+ * system.h (STARTING_FRAME_OFFSET): Poison.
+
2017-10-23 Richard Sandiford <richard.sandiford@linaro.org>
* tree-vect-loop.c (vect_create_epilog_for_reduction): Use
to the underlying register (fp in this case) that makes
the original assignment true.
So the following insn will actually be decrementing fp by
- STARTING_FRAME_OFFSET. */
+ TARGET_STARTING_FRAME_OFFSET. */
emit_move_insn (virtual_stack_vars_rtx, hard_frame_pointer_rtx);
/* Restoring the frame pointer also modifies the hard frame pointer.
/* Compute the phase of the stack frame for this function. */
{
int align = PREFERRED_STACK_BOUNDARY / BITS_PER_UNIT;
- int off = STARTING_FRAME_OFFSET % align;
+ int off = targetm.starting_frame_offset () % align;
frame_phase = off ? align - off : 0;
}
#define FRAME_GROWS_DOWNWARD 1
-#define STARTING_FRAME_OFFSET 0
-
#define ACCUMULATE_OUTGOING_ARGS 1
#define FIRST_PARM_OFFSET(FNDECL) 0
goes at a more negative offset in the frame. */
/* #define FRAME_GROWS_DOWNWARD 0 */
-/* 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 0
-
/* If we generate an insn to push BYTES bytes,
this says how many the stack pointer really advances by.
On Alpha, don't define this because there are no push insns. */
goes at a more negative offset in the frame. */
#define FRAME_GROWS_DOWNWARD 1
-/* 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 0
-
/* Offset from the stack pointer register to the first location at which
outgoing arguments are placed. */
#define STACK_POINTER_OFFSET (0)
&& crtl->outgoing_args_size != 0 \
? UNITS_PER_WORD : 0)
-/* 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 0
-
/* If we generate an insn to push BYTES bytes,
this says how many the stack pointer really advances by. */
/* The push insns do not do this rounding implicitly.
extern void avr_expand_epilogue (bool);
extern bool avr_emit_movmemhi (rtx*);
extern int avr_epilogue_uses (int regno);
-extern int avr_starting_frame_offset (void);
extern void avr_output_addr_vec (rtx_insn*, rtx);
extern const char *avr_out_sbxx_branch (rtx_insn *insn, rtx operands[]);
}
-/* Implement `STARTING_FRAME_OFFSET'. */
+/* Implement TARGET_STARTING_FRAME_OFFSET. */
/* This is the offset from the frame pointer register to the first stack slot
that contains a variable living in the frame. */
-int
+static HOST_WIDE_INT
avr_starting_frame_offset (void)
{
return 1 + avr_outgoing_args_size ();
/* Implement `TARGET_BUILTIN_SETJMP_FRAME_VALUE'. */
/* Actual start of frame is virtual_stack_vars_rtx this is offset from
- frame pointer by +STARTING_FRAME_OFFSET.
- Using saved frame = virtual_stack_vars_rtx - STARTING_FRAME_OFFSET
+ frame pointer by +TARGET_STARTING_FRAME_OFFSET.
+ Using saved frame = virtual_stack_vars_rtx - TARGET_STARTING_FRAME_OFFSET
avoids creating add/sub of offset in nonlocal goto and setjmp. */
static rtx
{
rtx xval = gen_reg_rtx (Pmode);
emit_insn (gen_subhi3 (xval, virtual_stack_vars_rtx,
- gen_int_mode (STARTING_FRAME_OFFSET, Pmode)));
+ gen_int_mode (avr_starting_frame_offset (), Pmode)));
return xval;
}
#undef TARGET_LEGITIMATE_COMBINED_INSN
#define TARGET_LEGITIMATE_COMBINED_INSN avr_legitimate_combined_insn
+#undef TARGET_STARTING_FRAME_OFFSET
+#define TARGET_STARTING_FRAME_OFFSET avr_starting_frame_offset
+
struct gcc_target targetm = TARGET_INITIALIZER;
\f
#define STACK_GROWS_DOWNWARD 1
-#define STARTING_FRAME_OFFSET avr_starting_frame_offset()
-
#define STACK_POINTER_OFFSET 1
#define FIRST_PARM_OFFSET(FUNDECL) 0
(unspec_volatile:HI [(const_int 0)] UNSPECV_GOTO_RECEIVER))]
""
{
+ rtx offset = gen_int_mode (targetm.starting_frame_offset (), Pmode);
emit_move_insn (virtual_stack_vars_rtx,
- gen_rtx_PLUS (Pmode, hard_frame_pointer_rtx,
- gen_int_mode (STARTING_FRAME_OFFSET,
- Pmode)));
+ gen_rtx_PLUS (Pmode, hard_frame_pointer_rtx, offset));
/* ; This might change the hard frame pointer in ways that aren't
; apparent to early optimization passes, so force a clobber. */
emit_clobber (hard_frame_pointer_rtx);
it. */
#define FIRST_PARM_OFFSET(DECL) 0
-/* 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 0
-
/* Register to use for pushing function arguments. */
#define STACK_POINTER_REGNUM REG_P6
#define STACK_POINTER_OFFSET 4
/* Likewise for AP (which is the incoming stack pointer). */
#define FIRST_PARM_OFFSET(fundecl) 4
-#define STARTING_FRAME_OFFSET 0
#define FRAME_GROWS_DOWNWARD 1
#define STACK_GROWS_DOWNWARD 1
/* Stack layout and calling conventions. */
#define STACK_GROWS_DOWNWARD 1
-#define STARTING_FRAME_OFFSET 0
-
#define STACK_POINTER_REGNUM 15
#define FRAME_POINTER_REGNUM 13
#define STACK_GROWS_DOWNWARD 1
#define FRAME_GROWS_DOWNWARD 1
-/* It seems to be indicated in the code (at least 2.1) that this is
- better a constant, and best 0. */
-#define STARTING_FRAME_OFFSET 0
-
#define FIRST_PARM_OFFSET(FNDECL) 0
#define RETURN_ADDR_RTX(COUNT, FRAMEADDR) \
#undef TARGET_CONSTANT_ALIGNMENT
#define TARGET_CONSTANT_ALIGNMENT epiphany_constant_alignment
+
+#undef TARGET_STARTING_FRAME_OFFSET
+#define TARGET_STARTING_FRAME_OFFSET epiphany_starting_frame_offset
\f
bool
epiphany_is_interrupt_p (tree decl)
return align;
}
+/* Implement TARGET_STARTING_FRAME_OFFSET. */
+
+static HOST_WIDE_INT
+epiphany_starting_frame_offset (void)
+{
+ return epiphany_stack_offset;
+}
+
struct gcc_target targetm = TARGET_INITIALIZER;
goes at a more negative offset in the frame. */
#define FRAME_GROWS_DOWNWARD 1
-/* 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 epiphany_stack_offset
-
/* Offset from the stack pointer register to the first location at which
outgoing arguments are placed. */
#define STACK_POINTER_OFFSET epiphany_stack_offset
are at negative offsets from the frame pointer. */
#define FRAME_GROWS_DOWNWARD 1
-/* Offset from the frame pointer to the first local variable slot to be
- allocated.
-
- If `FRAME_GROWS_DOWNWARD', find the next slot's offset by subtracting the
- first slot's length from `STARTING_FRAME_OFFSET'. Otherwise, it is found by
- adding the length of the first slot to the value `STARTING_FRAME_OFFSET'. */
-/* #define STARTING_FRAME_OFFSET -4 */
-#define STARTING_FRAME_OFFSET 0
-
/* Offset from the stack pointer register to the first location at which
outgoing arguments are placed. If not specified, the default value of zero
is used. This is the proper value for most machines.
are at negative offsets from the frame pointer. */
#define FRAME_GROWS_DOWNWARD 1
-/* Offset from the frame pointer to the first local variable slot to be
- allocated.
-
- If `FRAME_GROWS_DOWNWARD', find the next slot's offset by subtracting the
- first slot's length from `STARTING_FRAME_OFFSET'. Otherwise, it is found by
- adding the length of the first slot to the value `STARTING_FRAME_OFFSET'. */
-#define STARTING_FRAME_OFFSET 0
-
/* Offset from the stack pointer register to the first location at which
outgoing arguments are placed. If not specified, the default value of zero
is used. This is the proper value for most machines.
pointer to a smaller address. */
#define STACK_GROWS_DOWNWARD 1
-/* Offset from the frame pointer to the first local variable slot to
- be allocated. */
-#define STARTING_FRAME_OFFSET 0
-
/* Offset from the argument pointer register to the first argument's
address. On some machines it may depend on the data type of the
function. */
#define FRAME_GROWS_DOWNWARD 1
-/* 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 0
-
/* If we generate an insn to push BYTES bytes,
this says how many the stack pointer really advances by.
goes at a more negative offset in the frame. */
#define FRAME_GROWS_DOWNWARD 1
-/* 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 0
-
/* If we generate an insn to push BYTES bytes, this says how many the stack
pointer really advances by. On 386, we have pushw instruction that
decrements by exactly 2 no matter what the position was, there is no pushb.
are at negative offsets from the frame pointer. */
#define FRAME_GROWS_DOWNWARD 0
-/* Offset from the frame pointer to the first local variable slot to
- be allocated. */
-#define STARTING_FRAME_OFFSET 0
-
/* Offset from the stack pointer register to the first location at which
outgoing arguments are placed. If not specified, the default value of zero
is used. This is the proper value for most machines. */
static bool iq2000_hard_regno_mode_ok (unsigned int, machine_mode);
static bool iq2000_modes_tieable_p (machine_mode, machine_mode);
static HOST_WIDE_INT iq2000_constant_alignment (const_tree, HOST_WIDE_INT);
+static HOST_WIDE_INT iq2000_starting_frame_offset (void);
#undef TARGET_INIT_BUILTINS
#define TARGET_INIT_BUILTINS iq2000_init_builtins
#undef TARGET_CONSTANT_ALIGNMENT
#define TARGET_CONSTANT_ALIGNMENT iq2000_constant_alignment
+#undef TARGET_STARTING_FRAME_OFFSET
+#define TARGET_STARTING_FRAME_OFFSET iq2000_starting_frame_offset
+
struct gcc_target targetm = TARGET_INITIALIZER;
\f
/* Return nonzero if we split the address into high and low parts. */
return align;
}
+/* Implement TARGET_STARTING_FRAME_OFFSET. */
+
+static HOST_WIDE_INT
+iq2000_starting_frame_offset (void)
+{
+ return crtl->outgoing_args_size;
+}
+
#include "gt-iq2000.h"
#define FRAME_GROWS_DOWNWARD 0
-#define STARTING_FRAME_OFFSET \
- (crtl->outgoing_args_size)
-
/* Use the default value zero. */
/* #define STACK_POINTER_OFFSET 0 */
const_tree type, bool named);
static bool lm32_hard_regno_mode_ok (unsigned int, machine_mode);
static bool lm32_modes_tieable_p (machine_mode, machine_mode);
+static HOST_WIDE_INT lm32_starting_frame_offset (void);
#undef TARGET_OPTION_OVERRIDE
#define TARGET_OPTION_OVERRIDE lm32_option_override
#undef TARGET_CONSTANT_ALIGNMENT
#define TARGET_CONSTANT_ALIGNMENT constant_alignment_word_strings
+#undef TARGET_STARTING_FRAME_OFFSET
+#define TARGET_STARTING_FRAME_OFFSET lm32_starting_frame_offset
+
struct gcc_target targetm = TARGET_INITIALIZER;
/* Current frame information calculated by lm32_compute_frame_size. */
&& GET_MODE_SIZE (mode1) <= UNITS_PER_WORD
&& GET_MODE_SIZE (mode2) <= UNITS_PER_WORD);
}
+
+/* Implement TARGET_STARTING_FRAME_OFFSET. */
+
+static HOST_WIDE_INT
+lm32_starting_frame_offset (void)
+{
+ return UNITS_PER_WORD;
+}
#define STACK_POINTER_OFFSET (UNITS_PER_WORD)
-#define STARTING_FRAME_OFFSET (UNITS_PER_WORD)
-
#define FIRST_PARM_OFFSET(FNDECL) (UNITS_PER_WORD)
#define STACK_POINTER_REGNUM SP_REGNUM
#define STACK_PUSH_CODE PRE_DEC
#define FRAME_GROWS_DOWNWARD 1
-#define STARTING_FRAME_OFFSET 0
#define FIRST_PARM_OFFSET(F) 0
#define RETURN_ADDR_RTX(COUNT,FA) m32c_return_addr_rtx (COUNT)
static bool m32r_attribute_identifier (const_tree);
static bool m32r_hard_regno_mode_ok (unsigned int, machine_mode);
static bool m32r_modes_tieable_p (machine_mode, machine_mode);
+static HOST_WIDE_INT m32r_starting_frame_offset (void);
\f
/* M32R specific attributes. */
#undef TARGET_CONSTANT_ALIGNMENT
#define TARGET_CONSTANT_ALIGNMENT constant_alignment_word_strings
+#undef TARGET_STARTING_FRAME_OFFSET
+#define TARGET_STARTING_FRAME_OFFSET m32r_starting_frame_offset
+
struct gcc_target targetm = TARGET_INITIALIZER;
\f
/* Called by m32r_option_override to initialize various things. */
&& CONST_INT_P (XEXP (XEXP (x, 0), 1))
&& UINTVAL (XEXP (XEXP (x, 0), 1)) > 32767);
}
+
+/* Implement TARGET_STARTING_FRAME_OFFSET. The frame pointer points at
+ the same place as the stack pointer, except if alloca has been called. */
+
+static HOST_WIDE_INT
+m32r_starting_frame_offset (void)
+{
+ return M32R_STACK_ALIGN (crtl->outgoing_args_size);
+}
pointer to a smaller address. */
#define STACK_GROWS_DOWNWARD 1
-/* Offset from frame pointer 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. */
-/* The frame pointer points at the same place as the stack pointer, except if
- alloca has been called. */
-#define STARTING_FRAME_OFFSET \
- M32R_STACK_ALIGN (crtl->outgoing_args_size)
-
/* Offset from the stack pointer register to the first location at which
outgoing arguments are placed. */
#define STACK_POINTER_OFFSET 0
#define STACK_GROWS_DOWNWARD 1
#define FRAME_GROWS_DOWNWARD 1
-#define STARTING_FRAME_OFFSET 0
/* On the 680x0, sp@- in a byte insn really pushes a word.
On the ColdFire, sp@- in a byte insn pushes just a byte. */
makes the stack pointer a smaller address. */
#define STACK_GROWS_DOWNWARD 1
-/* 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 0
-
/* If defined, the maximum amount of space required for outgoing arguments
will be computed and placed into the variable
`crtl->outgoing_args_size'. No space will be pushed
return MAX (align, BITS_PER_WORD);
return align;
}
+
+/* Implement TARGET_STARTING_FRAME_OFFSET. */
+
+static HOST_WIDE_INT
+microblaze_starting_frame_offset (void)
+{
+ return (crtl->outgoing_args_size + FIRST_PARM_OFFSET(FNDECL));
+}
\f
#undef TARGET_ENCODE_SECTION_INFO
#define TARGET_ENCODE_SECTION_INFO microblaze_encode_section_info
#undef TARGET_CONSTANT_ALIGNMENT
#define TARGET_CONSTANT_ALIGNMENT microblaze_constant_alignment
+#undef TARGET_STARTING_FRAME_OFFSET
+#define TARGET_STARTING_FRAME_OFFSET microblaze_starting_frame_offset
+
struct gcc_target targetm = TARGET_INITIALIZER;
\f
#include "gt-microblaze.h"
#define STACK_GROWS_DOWNWARD 1
-/* Changed the starting frame offset to including the new link stuff */
-#define STARTING_FRAME_OFFSET \
- (crtl->outgoing_args_size + FIRST_PARM_OFFSET(FNDECL))
-
/* The return address for the current frame is in r31 if this is a leaf
function. Otherwise, it is on the stack. It is at a variable offset
from sp/fp/ap, so we define a fake hard register rap which is a
if we know that none of the called functions will use this space.
But if the target-independent frame size is nonzero, we have already
- committed to allocating these in STARTING_FRAME_OFFSET for
+ committed to allocating these in TARGET_STARTING_FRAME_OFFSET for
!FRAME_GROWS_DOWNWARD. */
if ((size == 0 || FRAME_GROWS_DOWNWARD)
return MAX (align, BITS_PER_WORD);
return align;
}
+
+/* Implement TARGET_STARTING_FRAME_OFFSET. See mips_compute_frame_info
+ for details about the frame layout. */
+
+static HOST_WIDE_INT
+mips_starting_frame_offset (void)
+{
+ if (FRAME_GROWS_DOWNWARD)
+ return 0;
+ return crtl->outgoing_args_size + MIPS_GP_SAVE_AREA_SIZE;
+}
\f
/* Initialize the GCC target structure. */
#undef TARGET_ASM_ALIGNED_HI_OP
#undef TARGET_CONSTANT_ALIGNMENT
#define TARGET_CONSTANT_ALIGNMENT mips_constant_alignment
+#undef TARGET_STARTING_FRAME_OFFSET
+#define TARGET_STARTING_FRAME_OFFSET mips_starting_frame_offset
+
struct gcc_target targetm = TARGET_INITIALIZER;
\f
#include "gt-mips.h"
#define MIPS_GP_SAVE_AREA_SIZE \
(TARGET_CALL_CLOBBERED_GP ? MIPS_STACK_ALIGN (UNITS_PER_WORD) : 0)
-/* The offset of the first local variable from the frame pointer. See
- mips_compute_frame_info for details about the frame layout. */
-
-#define STARTING_FRAME_OFFSET \
- (FRAME_GROWS_DOWNWARD \
- ? 0 \
- : crtl->outgoing_args_size + MIPS_GP_SAVE_AREA_SIZE)
-
#define RETURN_ADDR_RTX mips_return_addr
/* Mask off the MIPS16 ISA bit in unwind addresses.
extern void mmix_init_expanders (void);
extern int mmix_eh_return_data_regno (int);
extern int mmix_initial_elimination_offset (int, int);
-extern int mmix_starting_frame_offset (void);
extern int mmix_function_arg_regno_p (int, int);
extern void mmix_function_profiler (FILE *, int);
extern int mmix_reversible_cc_mode (machine_mode);
static bool mmix_print_operand_punct_valid_p (unsigned char);
static void mmix_conditional_register_usage (void);
static HOST_WIDE_INT mmix_constant_alignment (const_tree, HOST_WIDE_INT);
+static HOST_WIDE_INT mmix_starting_frame_offset (void);
/* Target structure macros. Listed by node. See `Using and Porting GCC'
for a general description. */
#undef TARGET_CONSTANT_ALIGNMENT
#define TARGET_CONSTANT_ALIGNMENT mmix_constant_alignment
+#undef TARGET_STARTING_FRAME_OFFSET
+#define TARGET_STARTING_FRAME_OFFSET mmix_starting_frame_offset
+
struct gcc_target targetm = TARGET_INITIALIZER;
/* Functions that are expansions for target macros.
return plus_constant (Pmode, frame, -8);
}
-/* STARTING_FRAME_OFFSET. */
+/* Implement TARGET_STARTING_FRAME_OFFSET. */
-int
+static HOST_WIDE_INT
mmix_starting_frame_offset (void)
{
/* The old frame pointer is in the slot below the new one, so
counted; the others go on the register stack.
The frame-pointer is counted too if it is what is eliminated, as we
- need to balance the offset for it from STARTING_FRAME_OFFSET.
+ need to balance the offset for it from TARGET_STARTING_FRAME_OFFSET.
Also add in the slot for the register stack pointer we save if we
have a landing pad.
#define STACK_GROWS_DOWNWARD 1
#define FRAME_GROWS_DOWNWARD 1
-#define STARTING_FRAME_OFFSET \
- mmix_starting_frame_offset ()
-
#define FIRST_PARM_OFFSET(FUNDECL) 0
#define DYNAMIC_CHAIN_ADDRESS(FRAMEADDR) \
#define FRAME_GROWS_DOWNWARD 1
-/* 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 0
-
/* Offset of first parameter from the argument pointer register value. */
/* Is equal to the size of the saved fp + pc, even if an fp isn't
saved since the value is used before we know. */
pointer to a smaller address. */
#define STACK_GROWS_DOWNWARD 1
-/* Offset from the frame pointer to the first local variable slot to
- be allocated. */
-#define STARTING_FRAME_OFFSET 0
-
/* Define this if the above stack space is to be considered part of the
space allocated by the caller. */
#define OUTGOING_REG_PARM_STACK_SPACE(FNTYPE) 1
#define WORD_REGISTER_OPERATIONS 1
#define MOVE_MAX 8
-#define STARTING_FRAME_OFFSET 0
#define INCOMING_RETURN_ADDR_RTX \
msp430_incoming_return_addr_rtx ()
#define FRAME_GROWS_DOWNWARD 1
-#define STARTING_FRAME_OFFSET 0
-
#define STACK_POINTER_OFFSET 0
#define FIRST_PARM_OFFSET(fundecl) \
/* Stack layout. */
#define STACK_GROWS_DOWNWARD 1
-#define STARTING_FRAME_OFFSET 0
#define FIRST_PARM_OFFSET(FUNDECL) 0
/* Before the prologue, RA lives in r31. */
/* Stack and Calling. */
-#define STARTING_FRAME_OFFSET 0
#define FRAME_GROWS_DOWNWARD 0
#define STACK_GROWS_DOWNWARD 1
static bool pa_hard_regno_mode_ok (unsigned int, machine_mode);
static bool pa_modes_tieable_p (machine_mode, machine_mode);
static bool pa_can_change_mode_class (machine_mode, machine_mode, reg_class_t);
+static HOST_WIDE_INT pa_starting_frame_offset (void);
/* The following extra sections are only used for SOM. */
static GTY(()) section *som_readonly_data_section;
#undef TARGET_CONSTANT_ALIGNMENT
#define TARGET_CONSTANT_ALIGNMENT constant_alignment_word_strings
+#undef TARGET_STARTING_FRAME_OFFSET
+#define TARGET_STARTING_FRAME_OFFSET pa_starting_frame_offset
+
struct gcc_target targetm = TARGET_INITIALIZER;
\f
/* Parse the -mfixed-range= option string. */
size = (size + UNITS_PER_WORD - 1) & ~(UNITS_PER_WORD - 1);
/* Space for previous frame pointer + filler. If any frame is
- allocated, we need to add in the STARTING_FRAME_OFFSET. We
+ allocated, we need to add in the TARGET_STARTING_FRAME_OFFSET. We
waste some space here for the sake of HP compatibility. The
first slot is only used when the frame pointer is needed. */
if (size || frame_pointer_needed)
- size += STARTING_FRAME_OFFSET;
+ size += pa_starting_frame_offset ();
/* If the current function calls __builtin_eh_return, then we need
to allocate stack space for registers that will hold data for
and must be changed in tandem with this code. */
local_fsize = (size + UNITS_PER_WORD - 1) & ~(UNITS_PER_WORD - 1);
if (local_fsize || frame_pointer_needed)
- local_fsize += STARTING_FRAME_OFFSET;
+ local_fsize += pa_starting_frame_offset ();
actual_fsize = pa_compute_frame_size (size, &save_fregs);
if (flag_stack_usage_info)
return PA_HARD_REGNO_MODE_OK (regno, mode);
}
+/* Implement TARGET_STARTING_FRAME_OFFSET.
+
+ On the 32-bit ports, we reserve one slot for the previous frame
+ pointer and one fill slot. The fill slot is for compatibility
+ with HP compiled programs. On the 64-bit ports, we reserve one
+ slot for the previous frame pointer. */
+
+static HOST_WIDE_INT
+pa_starting_frame_offset (void)
+{
+ return 8;
+}
+
#include "gt-pa.h"
goes at a more negative offset in the frame. */
#define FRAME_GROWS_DOWNWARD 0
-/* 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.
-
- On the 32-bit ports, we reserve one slot for the previous frame
- pointer and one fill slot. The fill slot is for compatibility
- with HP compiled programs. On the 64-bit ports, we reserve one
- slot for the previous frame pointer. */
-#define STARTING_FRAME_OFFSET 8
-
/* Define STACK_ALIGNMENT_NEEDED to zero to disable final alignment
of the stack. The default is to align it to STACK_BOUNDARY. */
#define STACK_ALIGNMENT_NEEDED 0
*/
#define FRAME_GROWS_DOWNWARD 1
-/* 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 0
-
/* If we generate an insn to push BYTES bytes,
this says how many the stack pointer really advances by.
On the pdp11, the stack is on an even boundary */
sizes of the fixed area and the parameter area must be a multiple of
STACK_BOUNDARY. */
-#undef STARTING_FRAME_OFFSET
-#define STARTING_FRAME_OFFSET \
- (FRAME_GROWS_DOWNWARD \
- ? 0 \
- : (cfun->calls_alloca \
- ? RS6000_ALIGN (crtl->outgoing_args_size + RS6000_SAVE_AREA, 16) \
- : (RS6000_ALIGN (crtl->outgoing_args_size, 16) + RS6000_SAVE_AREA)))
+#undef RS6000_STARTING_FRAME_OFFSET
+#define RS6000_STARTING_FRAME_OFFSET \
+ (cfun->calls_alloca \
+ ? RS6000_ALIGN (crtl->outgoing_args_size + RS6000_SAVE_AREA, 16) \
+ : (RS6000_ALIGN (crtl->outgoing_args_size, 16) + RS6000_SAVE_AREA))
/* Offset from the stack pointer register to an item dynamically
allocated on the stack, e.g., by `alloca'.
/* Pad the outgoing args area to 16 bytes instead of the usual 8. */
-#undef STARTING_FRAME_OFFSET
-#define STARTING_FRAME_OFFSET \
- (FRAME_GROWS_DOWNWARD \
- ? 0 \
- : (RS6000_ALIGN (crtl->outgoing_args_size, 16) \
- + RS6000_SAVE_AREA))
+#undef RS6000_STARTING_FRAME_OFFSET
+#define RS6000_STARTING_FRAME_OFFSET \
+ (RS6000_ALIGN (crtl->outgoing_args_size, 16) \
+ + RS6000_SAVE_AREA)
#undef STACK_DYNAMIC_OFFSET
#define STACK_DYNAMIC_OFFSET(FUNDECL) \
#undef TARGET_CONSTANT_ALIGNMENT
#define TARGET_CONSTANT_ALIGNMENT rs6000_constant_alignment
+
+#undef TARGET_STARTING_FRAME_OFFSET
+#define TARGET_STARTING_FRAME_OFFSET rs6000_starting_frame_offset
\f
/* Processor table. */
return MAX (align, BITS_PER_WORD);
return align;
}
+
+/* Implement TARGET_STARTING_FRAME_OFFSET. */
+
+static HOST_WIDE_INT
+rs6000_starting_frame_offset (void)
+{
+ if (FRAME_GROWS_DOWNWARD)
+ return 0;
+ return RS6000_STARTING_FRAME_OFFSET;
+}
\f
struct gcc_target targetm = TARGET_INITIALIZER;
sizes of the fixed area and the parameter area must be a multiple of
STACK_BOUNDARY. */
-#define STARTING_FRAME_OFFSET \
- (FRAME_GROWS_DOWNWARD \
- ? 0 \
- : (cfun->calls_alloca \
- ? (RS6000_ALIGN (crtl->outgoing_args_size + RS6000_SAVE_AREA, \
- (TARGET_ALTIVEC || TARGET_VSX) ? 16 : 8 )) \
- : (RS6000_ALIGN (crtl->outgoing_args_size, \
- (TARGET_ALTIVEC || TARGET_VSX) ? 16 : 8) \
- + RS6000_SAVE_AREA)))
+#define RS6000_STARTING_FRAME_OFFSET \
+ (cfun->calls_alloca \
+ ? (RS6000_ALIGN (crtl->outgoing_args_size + RS6000_SAVE_AREA, \
+ (TARGET_ALTIVEC || TARGET_VSX) ? 16 : 8 )) \
+ : (RS6000_ALIGN (crtl->outgoing_args_size, \
+ (TARGET_ALTIVEC || TARGET_VSX) ? 16 : 8) \
+ + RS6000_SAVE_AREA))
/* Offset from the stack pointer register to an item dynamically
allocated on the stack, e.g., by `alloca'.
#define FRAME_GROWS_DOWNWARD 1
-#define STARTING_FRAME_OFFSET 0
-
#define RETURN_ADDR_RTX riscv_return_addr
#define ELIMINABLE_REGS \
#define HAS_LONG_UNCOND_BRANCH 0
#define MOVE_MAX 2
-#define STARTING_FRAME_OFFSET 0
#define ADDR_SPACE_NEAR 1
#define ADDR_SPACE_FAR 2
sizes of the fixed area and the parameter area must be a multiple of
STACK_BOUNDARY. */
-#undef STARTING_FRAME_OFFSET
-#define STARTING_FRAME_OFFSET \
- (FRAME_GROWS_DOWNWARD \
- ? 0 \
- : (cfun->calls_alloca \
- ? RS6000_ALIGN (crtl->outgoing_args_size + RS6000_SAVE_AREA, 16) \
- : (RS6000_ALIGN (crtl->outgoing_args_size, 16) + RS6000_SAVE_AREA)))
+#undef RS6000_STARTING_FRAME_OFFSET
+#define RS6000_STARTING_FRAME_OFFSET \
+ (cfun->calls_alloca \
+ ? RS6000_ALIGN (crtl->outgoing_args_size + RS6000_SAVE_AREA, 16) \
+ : (RS6000_ALIGN (crtl->outgoing_args_size, 16) + RS6000_SAVE_AREA))
/* Offset from the stack pointer register to an item dynamically
allocated on the stack, e.g., by `alloca'.
/* Pad the outgoing args area to 16 bytes instead of the usual 8. */
-#undef STARTING_FRAME_OFFSET
-#define STARTING_FRAME_OFFSET \
- (FRAME_GROWS_DOWNWARD \
- ? 0 \
- : (RS6000_ALIGN (crtl->outgoing_args_size, 16) \
- + RS6000_SAVE_AREA))
+#undef RS6000_STARTING_FRAME_OFFSET
+#define RS6000_STARTING_FRAME_OFFSET \
+ (RS6000_ALIGN (crtl->outgoing_args_size, 16) \
+ + RS6000_SAVE_AREA)
#undef STACK_DYNAMIC_OFFSET
#define STACK_DYNAMIC_OFFSET(FUNDECL) \
#undef TARGET_CONSTANT_ALIGNMENT
#define TARGET_CONSTANT_ALIGNMENT rs6000_constant_alignment
+
+#undef TARGET_STARTING_FRAME_OFFSET
+#define TARGET_STARTING_FRAME_OFFSET rs6000_starting_frame_offset
\f
/* Processor table. */
return MAX (align, BITS_PER_WORD);
return align;
}
+
+/* Implement TARGET_STARTING_FRAME_OFFSET. */
+
+static HOST_WIDE_INT
+rs6000_starting_frame_offset (void)
+{
+ if (FRAME_GROWS_DOWNWARD)
+ return 0;
+ return RS6000_STARTING_FRAME_OFFSET;
+}
\f
struct gcc_target targetm = TARGET_INITIALIZER;
sizes of the fixed area and the parameter area must be a multiple of
STACK_BOUNDARY. */
-#define STARTING_FRAME_OFFSET \
- (FRAME_GROWS_DOWNWARD \
- ? 0 \
- : (cfun->calls_alloca \
- ? (RS6000_ALIGN (crtl->outgoing_args_size + RS6000_SAVE_AREA, \
- (TARGET_ALTIVEC || TARGET_VSX) ? 16 : 8 )) \
- : (RS6000_ALIGN (crtl->outgoing_args_size, \
- (TARGET_ALTIVEC || TARGET_VSX) ? 16 : 8) \
- + RS6000_SAVE_AREA)))
+#define RS6000_STARTING_FRAME_OFFSET \
+ (cfun->calls_alloca \
+ ? (RS6000_ALIGN (crtl->outgoing_args_size + RS6000_SAVE_AREA, \
+ (TARGET_ALTIVEC || TARGET_VSX) ? 16 : 8 )) \
+ : (RS6000_ALIGN (crtl->outgoing_args_size, \
+ (TARGET_ALTIVEC || TARGET_VSX) ? 16 : 8) \
+ + RS6000_SAVE_AREA))
/* Offset from the stack pointer register to an item dynamically
allocated on the stack, e.g., by `alloca'.
#define HAS_LONG_UNCOND_BRANCH 0
#define MOVE_MAX 4
-#define STARTING_FRAME_OFFSET 0
#define HAVE_PRE_DECREMENT 1
#define HAVE_POST_INCREMENT 1
/* Offset from stack-pointer to first location of outgoing args. */
#define STACK_POINTER_OFFSET (TARGET_64BIT ? 160 : 96)
-/* Offset within stack frame to start allocating local variables at. */
-#define STARTING_FRAME_OFFSET 0
-
/* Offset from the stack pointer register to an item dynamically
allocated on the stack, e.g., by `alloca'. */
#define STACK_DYNAMIC_OFFSET(FUNDECL) \
are at negative offsets from the frame pointer. */
#define FRAME_GROWS_DOWNWARD 1
-/* Offset from the frame pointer to the first local variable slot to
- be allocated. */
-#define STARTING_FRAME_OFFSET 0
-
/* If we generate an insn to push BYTES bytes,
this says how many the stack pointer really advances by. */
/* Don't define PUSH_ROUNDING, since the hardware doesn't do this.
frame_size = apparent_frame_size = 0;
else
{
- /* We subtract STARTING_FRAME_OFFSET, remember it's negative. */
- apparent_frame_size = ROUND_UP (size - STARTING_FRAME_OFFSET, 8);
+ /* We subtract TARGET_STARTING_FRAME_OFFSET, remember it's negative. */
+ apparent_frame_size
+ = ROUND_UP (size - targetm.starting_frame_offset (), 8);
apparent_frame_size += n_global_fp_regs * 4;
/* We need to add the size of the outgoing argument area. */
goes at a more negative offset in the frame. */
#define FRAME_GROWS_DOWNWARD 1
-/* 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 0
-
/* Offset of first parameter from the argument pointer register value.
!v9: This is 64 for the ins and locals, plus 4 for the struct-return reg
even if this function isn't going to use it.
#define FRAME_GROWS_DOWNWARD 1
-#define STARTING_FRAME_OFFSET (0)
-
#define STACK_POINTER_OFFSET 32
#define FIRST_PARM_OFFSET(FNDECL) (0)
#define ARGS_GROW_DOWNWARD 1
-#define STARTING_FRAME_OFFSET 0
-
#define FIRST_PARM_OFFSET(FUNDECL) 0
#define RETURN_ADDR_RTX(COUNT, FRAMEADDR) \
#define STACK_GROWS_DOWNWARD 1
#define FRAME_GROWS_DOWNWARD 1
-#define STARTING_FRAME_OFFSET 0
#define DYNAMIC_CHAIN_ADDRESS(FRAME) \
plus_constant (Pmode, (FRAME), UNITS_PER_WORD)
#define STACK_GROWS_DOWNWARD 1
#define FRAME_GROWS_DOWNWARD 1
-#define STARTING_FRAME_OFFSET 0
#define DYNAMIC_CHAIN_ADDRESS(FRAME) \
plus_constant (Pmode, (FRAME), UNITS_PER_WORD)
#define FRAME_GROWS_DOWNWARD 1
-/* 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 0
-
/* Offset of first parameter from the argument pointer register value. */
/* Is equal to the size of the saved fp + pc, even if an fp isn't
saved since the value is used before we know. */
16))
-/* Reserve the top of the stack for exception handler stackadj value. */
-#undef STARTING_FRAME_OFFSET
-#define STARTING_FRAME_OFFSET -4
-
/* The VAX wants no space between the case instruction and the jump table. */
#undef ASM_OUTPUT_BEFORE_CASE_LABEL
#define ASM_OUTPUT_BEFORE_CASE_LABEL(FILE, PREFIX, NUM, TABLE)
static void vax_trampoline_init (rtx, tree, rtx);
static int vax_return_pops_args (tree, tree, int);
static bool vax_mode_dependent_address_p (const_rtx, addr_space_t);
+static HOST_WIDE_INT vax_starting_frame_offset (void);
\f
/* Initialize the GCC target structure. */
#undef TARGET_ASM_ALIGNED_HI_OP
#undef TARGET_OPTION_OVERRIDE
#define TARGET_OPTION_OVERRIDE vax_option_override
+#undef TARGET_STARTING_FRAME_OFFSET
+#define TARGET_STARTING_FRAME_OFFSET vax_starting_frame_offset
+
struct gcc_target targetm = TARGET_INITIALIZER;
\f
/* Set global variables as needed for the options enabled. */
/* Allocate the local stack frame. */
size = get_frame_size ();
- size -= STARTING_FRAME_OFFSET;
+ size -= vax_starting_frame_offset ();
emit_insn (gen_addsi3 (stack_pointer_rtx,
stack_pointer_rtx, GEN_INT (-size)));
? (GET_MODE_SIZE (mode) + 3) & ~3
: (int_size_in_bytes (type) + 3) & ~3);
}
+
+static HOST_WIDE_INT
+vax_starting_frame_offset (void)
+{
+ /* On ELF targets, reserve the top of the stack for exception handler
+ stackadj value. */
+ return TARGET_ELF ? -4 : 0;
+}
+
goes at a more negative offset in the frame. */
#define FRAME_GROWS_DOWNWARD 1
-/* 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 0
-
/* Given an rtx for the address of a frame,
return an rtx for the address of the word in the frame
that holds the dynamic chain--the previous frame's address. */
pointer to a smaller address. */
#define STACK_GROWS_DOWNWARD 1
-/* `STARTING_FRAME_OFFSET'
-
- Offset from the frame pointer to the first local variable slot to
- be allocated.
-
- If `FRAME_GROWS_DOWNWARD', find the next slot's offset by
- subtracting the first slot's length from `STARTING_FRAME_OFFSET'.
- Otherwise, it is found by adding the length of the first slot to
- the value `STARTING_FRAME_OFFSET'. */
-#define STARTING_FRAME_OFFSET 0
-
/* `FIRST_PARM_OFFSET (FUNDECL)'
Offset from the argument pointer register to the first argument's
static bool xtensa_hard_regno_mode_ok (unsigned int, machine_mode);
static bool xtensa_modes_tieable_p (machine_mode, machine_mode);
static HOST_WIDE_INT xtensa_constant_alignment (const_tree, HOST_WIDE_INT);
+static HOST_WIDE_INT xtensa_starting_frame_offset (void);
\f
#undef TARGET_CONSTANT_ALIGNMENT
#define TARGET_CONSTANT_ALIGNMENT xtensa_constant_alignment
+#undef TARGET_STARTING_FRAME_OFFSET
+#define TARGET_STARTING_FRAME_OFFSET xtensa_starting_frame_offset
+
struct gcc_target targetm = TARGET_INITIALIZER;
\f
return align;
}
+/* Implement TARGET_STARTING_FRAME_OFFSET. */
+
+static HOST_WIDE_INT
+xtensa_starting_frame_offset (void)
+{
+ if (FRAME_GROWS_DOWNWARD)
+ return 0;
+ return crtl->outgoing_args_size;
+}
+
#include "gt-xtensa.h"
#define FRAME_GROWS_DOWNWARD flag_stack_protect
-/* Offset within stack frame to start allocating local variables at. */
-#define STARTING_FRAME_OFFSET \
- (FRAME_GROWS_DOWNWARD ? 0 : crtl->outgoing_args_size)
-
/* The ARG_POINTER and FRAME_POINTER are not real Xtensa registers, so
they are eliminated to either the stack pointer or hard frame pointer. */
#define ELIMINABLE_REGS \
to immediately above the first variable on the stack. Otherwise, it points
to the first variable on the stack.
-@cindex @code{STARTING_FRAME_OFFSET} and virtual registers
+@cindex @code{TARGET_STARTING_FRAME_OFFSET} and virtual registers
@cindex @code{FRAME_POINTER_REGNUM} and virtual registers
@code{VIRTUAL_STACK_VARS_REGNUM} is replaced with the sum of the
register given by @code{FRAME_POINTER_REGNUM} and the value
-@code{STARTING_FRAME_OFFSET}.
+@code{TARGET_STARTING_FRAME_OFFSET}.
@findex VIRTUAL_STACK_DYNAMIC_REGNUM
@item VIRTUAL_STACK_DYNAMIC_REGNUM
addresses on the stack.
@end defmac
-@defmac STARTING_FRAME_OFFSET
-Offset from the frame pointer to the first local variable slot to be allocated.
-
-If @code{FRAME_GROWS_DOWNWARD}, find the next slot's offset by
-subtracting the first slot's length from @code{STARTING_FRAME_OFFSET}.
-Otherwise, it is found by adding the length of the first slot to the
-value @code{STARTING_FRAME_OFFSET}.
-@c i'm not sure if the above is still correct.. had to change it to get
-@c rid of an overfull. --mew 2feb93
-@end defmac
+@deftypefn {Target Hook} HOST_WIDE_INT TARGET_STARTING_FRAME_OFFSET (void)
+This hook returns the offset from the frame pointer to the first local
+variable slot to be allocated. If @code{FRAME_GROWS_DOWNWARD}, it is the
+offset to @emph{end} of the first slot allocated, otherwise it is the
+offset to @emph{beginning} of the first slot allocated. The default
+implementation returns 0.
+@end deftypefn
@defmac STACK_ALIGNMENT_NEEDED
Define to zero to disable final alignment of the stack during reload.
The nonzero default for this macro is suitable for most ports.
-On ports where @code{STARTING_FRAME_OFFSET} is nonzero or where there
+On ports where @code{TARGET_STARTING_FRAME_OFFSET} is nonzero or where there
is a register save block following the local block that doesn't require
alignment to @code{STACK_BOUNDARY}, it may be beneficial to disable
stack alignment and do it in the backend.
addresses on the stack.
@end defmac
-@defmac STARTING_FRAME_OFFSET
-Offset from the frame pointer to the first local variable slot to be allocated.
-
-If @code{FRAME_GROWS_DOWNWARD}, find the next slot's offset by
-subtracting the first slot's length from @code{STARTING_FRAME_OFFSET}.
-Otherwise, it is found by adding the length of the first slot to the
-value @code{STARTING_FRAME_OFFSET}.
-@c i'm not sure if the above is still correct.. had to change it to get
-@c rid of an overfull. --mew 2feb93
-@end defmac
+@hook TARGET_STARTING_FRAME_OFFSET
@defmac STACK_ALIGNMENT_NEEDED
Define to zero to disable final alignment of the stack during reload.
The nonzero default for this macro is suitable for most ports.
-On ports where @code{STARTING_FRAME_OFFSET} is nonzero or where there
+On ports where @code{TARGET_STARTING_FRAME_OFFSET} is nonzero or where there
is a register save block following the local block that doesn't require
alignment to @code{STACK_BOUNDARY}, it may be beneficial to disable
stack alignment and do it in the backend.
/* Calculate how many bytes the start of local variables is off from
stack alignment. */
frame_alignment = PREFERRED_STACK_BOUNDARY / BITS_PER_UNIT;
- frame_off = STARTING_FRAME_OFFSET % frame_alignment;
+ frame_off = targetm.starting_frame_offset () % frame_alignment;
frame_phase = frame_off ? frame_alignment - frame_off : 0;
/* Round the frame offset to the specified alignment. */
addr = plus_constant (Pmode, frame_pointer_rtx,
trunc_int_for_mode
(slot_offset + bigend_correction
- + STARTING_FRAME_OFFSET, Pmode));
+ + targetm.starting_frame_offset (), Pmode));
else
addr = plus_constant (Pmode, virtual_stack_vars_rtx,
trunc_int_for_mode
/* Compute the offsets to use for this function. */
in_arg_offset = FIRST_PARM_OFFSET (current_function_decl);
- var_offset = STARTING_FRAME_OFFSET;
+ var_offset = targetm.starting_frame_offset ();
dynamic_offset = STACK_DYNAMIC_OFFSET (current_function_decl);
out_arg_offset = STACK_POINTER_OFFSET;
#ifdef FRAME_POINTER_CFA_OFFSET
return 0;
}
+HOST_WIDE_INT
+hook_hwi_void_0 (void)
+{
+ return 0;
+}
+
void
hook_void_tree (tree)
{
extern int hook_int_rtx_mode_as_bool_0 (rtx, machine_mode, addr_space_t,
bool);
+extern HOST_WIDE_INT hook_hwi_void_0 (void);
+
extern tree hook_tree_const_tree_null (const_tree);
extern tree hook_tree_void_null (void);
then repeat the elimination bookkeeping. We don't
realign when there is no stack, as that will cause a
stack frame when none is needed should
- STARTING_FRAME_OFFSET not be already aligned to
+ TARGET_STARTING_FRAME_OFFSET not be already aligned to
STACK_BOUNDARY. */
assign_stack_local (BLKmode, 0, crtl->stack_alignment_needed);
}
{
if (FRAME_GROWS_DOWNWARD)
{
- high_bound = STARTING_FRAME_OFFSET;
+ high_bound = targetm.starting_frame_offset ();
low_bound = high_bound - get_frame_size ();
}
else
{
- low_bound = STARTING_FRAME_OFFSET;
+ low_bound = targetm.starting_frame_offset ();
high_bound = low_bound + get_frame_size ();
}
}
MODES_TIEABLE_P FUNCTION_ARG_PADDING SLOW_UNALIGNED_ACCESS \
HARD_REGNO_NREGS SECONDARY_MEMORY_NEEDED_MODE \
SECONDARY_MEMORY_NEEDED CANNOT_CHANGE_MODE_CLASS \
- TRULY_NOOP_TRUNCATION FUNCTION_ARG_OFFSET CONSTANT_ALIGNMENT
+ TRULY_NOOP_TRUNCATION FUNCTION_ARG_OFFSET CONSTANT_ALIGNMENT \
+ STARTING_FRAME_OFFSET
/* Target macros only used for code built for the target, that have
moved to libgcc-tm.h or have never been present elsewhere. */
unsigned int, (void),
default_case_values_threshold)
+DEFHOOK
+(starting_frame_offset,
+ "This hook returns the offset from the frame pointer to the first local\n\
+variable slot to be allocated. If @code{FRAME_GROWS_DOWNWARD}, it is the\n\
+offset to @emph{end} of the first slot allocated, otherwise it is the\n\
+offset to @emph{beginning} of the first slot allocated. The default\n\
+implementation returns 0.",
+ HOST_WIDE_INT, (void),
+ hook_hwi_void_0)
+
/* Optional callback to advise the target to compute the frame layout. */
DEFHOOK
(compute_frame_layout,