* combine.c (force_to_mode): Remove STACK_BIAS code.
(nonzero_bits): Likewise. Replace sp/fp special case with
REGNO_POINTER_ALIGN.
* config/sparc/sparc.h (FRAME_POINTER_REGNUM): Change to SFP.
(HARD_FRAME_POINTER_REGNUM): New.
(FIRST_PSEUDO_REGISTER, REG_CLASS_CONTENTS): Update.
(FIXED_REGS, CALL_USED_REGS): Update.
(REG_ALLOC_ORDER, REGISTER_NAMES): Update.
(CONDITIONAL_REGISTER_USAGE): Update for HFP.
(HARD_REGNO_NREGS): Update for SFP.
(STACK_POINTER_OFFSET): Include bias here ...
(FIRST_PARM_OFFSET): ... not here.
(STACK_BIAS): Remove.
(INIT_EXPANDERS): New.
(STARTING_FRAME_OFFSET): Do not include bias.
(ELIMINABLE_REGS, CAN_ELIMINATE, INITIAL_ELIMINATION_OFFSET): New.
(REGNO_OK_FOR_INDEX_P, REGNO_OK_FOR_BASE_P): Update for SFP.
(REG_OK_FOR_INDEX_P, REG_OK_FOR_BASE_P): Likewise.
* config/sparc/aout.h (DBX_REGISTER_NUMBER): Update for HFP.
* config/sparc/litecoff.h, config/sparc/sol2.h: Likewise.
* config/sparc/sparc.c (mem_min_alignment): Update for HFP.
(sparc_nonflat_function_prologue, epilogue_renumber): Likewise.
(MUST_SAVE_REGISTER): Likewise.
(sparc_flat_function_prologue): Likewise.
(sparc_flat_function_epilogue): Likewise.
(HARD_FRAME_POINTER_MASK): Rename from FRAME_POINTER_MASK.
(sparc_init_modes): SFP is GENERAL_REGS.
(sparc_builtin_saveregs): SFP does not have bias applied.
From-SVN: r49486
+2002-02-04 Richard Henderson <rth@redhat.com>
+
+ * combine.c (force_to_mode): Remove STACK_BIAS code.
+ (nonzero_bits): Likewise. Replace sp/fp special case with
+ REGNO_POINTER_ALIGN.
+
+ * config/sparc/sparc.h (FRAME_POINTER_REGNUM): Change to SFP.
+ (HARD_FRAME_POINTER_REGNUM): New.
+ (FIRST_PSEUDO_REGISTER, REG_CLASS_CONTENTS): Update.
+ (FIXED_REGS, CALL_USED_REGS): Update.
+ (REG_ALLOC_ORDER, REGISTER_NAMES): Update.
+ (CONDITIONAL_REGISTER_USAGE): Update for HFP.
+ (HARD_REGNO_NREGS): Update for SFP.
+ (STACK_POINTER_OFFSET): Include bias here ...
+ (FIRST_PARM_OFFSET): ... not here.
+ (STACK_BIAS): Remove.
+ (INIT_EXPANDERS): New.
+ (STARTING_FRAME_OFFSET): Do not include bias.
+ (ELIMINABLE_REGS, CAN_ELIMINATE, INITIAL_ELIMINATION_OFFSET): New.
+ (REGNO_OK_FOR_INDEX_P, REGNO_OK_FOR_BASE_P): Update for SFP.
+ (REG_OK_FOR_INDEX_P, REG_OK_FOR_BASE_P): Likewise.
+ * config/sparc/aout.h (DBX_REGISTER_NUMBER): Update for HFP.
+ * config/sparc/litecoff.h, config/sparc/sol2.h: Likewise.
+ * config/sparc/sparc.c (mem_min_alignment): Update for HFP.
+ (sparc_nonflat_function_prologue, epilogue_renumber): Likewise.
+ (MUST_SAVE_REGISTER): Likewise.
+ (sparc_flat_function_prologue): Likewise.
+ (sparc_flat_function_epilogue): Likewise.
+ (HARD_FRAME_POINTER_MASK): Rename from FRAME_POINTER_MASK.
+ (sparc_init_modes): SFP is GENERAL_REGS.
+ (sparc_builtin_saveregs): SFP does not have bias applied.
+
2002-02-04 Richard Henderson <rth@redhat.com>
* config/alpha/alpha.c (current_function_is_thunk): Don't check
smask |= (HOST_WIDE_INT) -1 << width;
if (GET_CODE (XEXP (x, 1)) == CONST_INT
- && exact_log2 (- smask) >= 0)
- {
-#ifdef STACK_BIAS
- if (STACK_BIAS
- && (XEXP (x, 0) == stack_pointer_rtx
- || XEXP (x, 0) == frame_pointer_rtx))
- {
- int sp_alignment = STACK_BOUNDARY / BITS_PER_UNIT;
- unsigned HOST_WIDE_INT sp_mask = GET_MODE_MASK (mode);
-
- sp_mask &= ~(sp_alignment - 1);
- if ((sp_mask & ~smask) == 0
- && ((INTVAL (XEXP (x, 1)) - STACK_BIAS) & ~smask) != 0)
- return force_to_mode (plus_constant (XEXP (x, 0),
- ((INTVAL (XEXP (x, 1)) -
- STACK_BIAS) & smask)
- + STACK_BIAS),
- mode, smask, reg, next_select);
- }
-#endif
- if ((nonzero_bits (XEXP (x, 0), mode) & ~smask) == 0
- && (INTVAL (XEXP (x, 1)) & ~smask) != 0)
- return force_to_mode (plus_constant (XEXP (x, 0),
- (INTVAL (XEXP (x, 1))
- & smask)),
- mode, smask, reg, next_select);
- }
+ && exact_log2 (- smask) >= 0
+ && (nonzero_bits (XEXP (x, 0), mode) & ~smask) == 0
+ && (INTVAL (XEXP (x, 1)) & ~smask) != 0)
+ return force_to_mode (plus_constant (XEXP (x, 0),
+ (INTVAL (XEXP (x, 1)) & smask)),
+ mode, smask, reg, next_select);
}
/* ... fall through ... */
nonzero &= GET_MODE_MASK (ptr_mode);
#endif
-#ifdef STACK_BOUNDARY
- /* If this is the stack pointer, we may know something about its
- alignment. If PUSH_ROUNDING is defined, it is possible for the
- stack to be momentarily aligned only to that amount, so we pick
- the least alignment. */
-
- /* We can't check for arg_pointer_rtx here, because it is not
- guaranteed to have as much alignment as the stack pointer.
- In particular, in the Irix6 n64 ABI, the stack has 128 bit
- alignment but the argument pointer has only 64 bit alignment. */
-
- if ((x == frame_pointer_rtx
- || x == stack_pointer_rtx
- || x == hard_frame_pointer_rtx
- || (REGNO (x) >= FIRST_VIRTUAL_REGISTER
- && REGNO (x) <= LAST_VIRTUAL_REGISTER))
-#ifdef STACK_BIAS
- && !STACK_BIAS
-#endif
- )
+ /* Include declared information about alignment of pointers. */
+
+ if (REG_POINTER (x) && REGNO_POINTER_ALIGN (REGNO (x)))
{
- int sp_alignment = STACK_BOUNDARY / BITS_PER_UNIT;
+ unsigned HOST_WIDE_INT alignment
+ = REGNO_POINTER_ALIGN (REGNO (x)) / BITS_PER_UNIT;
#ifdef PUSH_ROUNDING
- if (REGNO (x) == STACK_POINTER_REGNUM && PUSH_ARGS)
- sp_alignment = MIN (PUSH_ROUNDING (1), sp_alignment);
+ /* If PUSH_ROUNDING is defined, it is possible for the
+ stack to be momentarily aligned only to that amount,
+ so we pick the least alignment. */
+ if (x == stack_pointer_rtx && PUSH_ARGS)
+ alignment = MIN (PUSH_ROUNDING (1), alignment);
#endif
- /* We must return here, otherwise we may get a worse result from
- one of the choices below. There is nothing useful below as
- far as the stack pointer is concerned. */
- return nonzero &= ~(sp_alignment - 1);
+ nonzero &= ~(alignment - 1);
}
-#endif
/* If X is a register whose nonzero bits value is current, use it.
Otherwise, if X is a register whose value we can find, use that
&& ! REGNO_REG_SET_P (BASIC_BLOCK (0)->global_live_at_start,
REGNO (x))))
&& INSN_CUID (reg_last_set[REGNO (x)]) < subst_low_cuid)
- return reg_last_set_nonzero_bits[REGNO (x)];
+ return reg_last_set_nonzero_bits[REGNO (x)] & nonzero;
tem = get_last_value (x);
| ((HOST_WIDE_INT) (-1)
<< GET_MODE_BITSIZE (GET_MODE (x))));
#endif
- return nonzero_bits (tem, mode);
+ return nonzero_bits (tem, mode) & nonzero;
}
else if (nonzero_sign_valid && reg_nonzero_bits[REGNO (x)])
{
switch (code)
{
case PLUS:
-#ifdef STACK_BIAS
- if (STACK_BIAS
- && (XEXP (x, 0) == stack_pointer_rtx
- || XEXP (x, 0) == frame_pointer_rtx)
- && GET_CODE (XEXP (x, 1)) == CONST_INT)
- {
- int sp_alignment = STACK_BOUNDARY / BITS_PER_UNIT;
-
- nz0 = (GET_MODE_MASK (mode) & ~(sp_alignment - 1));
- nz1 = INTVAL (XEXP (x, 1)) - STACK_BIAS;
- width0 = floor_log2 (nz0) + 1;
- width1 = floor_log2 (nz1) + 1;
- low0 = floor_log2 (nz0 & -nz0);
- low1 = floor_log2 (nz1 & -nz1);
- }
-#endif
result_width = MAX (width0, width1) + 1;
result_low = MIN (low0, low1);
break;
pointer is really %i7. */
#define DBX_REGISTER_NUMBER(REGNO) \
- (TARGET_FLAT && REGNO == FRAME_POINTER_REGNUM ? 31 : REGNO)
+ (TARGET_FLAT && (REGNO) == HARD_FRAME_POINTER_REGNUM ? 31 : REGNO)
/* This is how to output a note to DBX telling it the line number
to which the following sequence of instructions corresponds.
pointer is really %i7. */
#define DBX_REGISTER_NUMBER(REGNO) \
- (TARGET_FLAT && REGNO == FRAME_POINTER_REGNUM ? 31 : REGNO)
+ (TARGET_FLAT && (REGNO) == HARD_FRAME_POINTER_REGNUM ? 31 : REGNO)
#undef DBX_REGISTER_NUMBER
/* Same as sparc.h */
#define DBX_REGISTER_NUMBER(REGNO) \
- (TARGET_FLAT && REGNO == FRAME_POINTER_REGNUM ? 31 : REGNO)
+ (TARGET_FLAT && (REGNO) == HARD_FRAME_POINTER_REGNUM ? 31 : REGNO)
/* We use stabs-in-elf for debugging, because that is what the native
toolchain uses. */
#ifdef LEAF_REGISTERS
-/* Vector to say how input registers are mapped to output
- registers. FRAME_POINTER_REGNUM cannot be remapped by
- this function to eliminate it. You must use -fomit-frame-pointer
- to get that. */
+/* Vector to say how input registers are mapped to output registers.
+ HARD_FRAME_POINTER_REGNUM cannot be remapped by this function to
+ eliminate it. You must use -fomit-frame-pointer to get that. */
const char leaf_reg_remap[] =
{ 0, 1, 2, 3, 4, 5, 6, 7,
-1, -1, -1, -1, -1, -1, 14, -1,
{
int regno = REGNO (base);
- if (regno != FRAME_POINTER_REGNUM
- && regno != STACK_POINTER_REGNUM)
+ if (regno != HARD_FRAME_POINTER_REGNUM && regno != STACK_POINTER_REGNUM)
{
/* Check if the compiler has recorded some information
about the alignment of the base REG. If reload has
{
if (i < 16 && TARGET_V8PLUS)
sparc_regno_reg_class[i] = I64_REGS;
- else if (i < 32)
+ else if (i < 32 || i == FRAME_POINTER_REGNUM)
sparc_regno_reg_class[i] = GENERAL_REGS;
else if (i < 64)
sparc_regno_reg_class[i] = FP_REGS;
/* The canonical frame address refers to the top of the frame. */
dwarf2out_def_cfa (label, (leaf_function ? STACK_POINTER_REGNUM
- : FRAME_POINTER_REGNUM),
+ : HARD_FRAME_POINTER_REGNUM),
frame_base_offset);
if (! leaf_function)
emit_move_insn (gen_rtx_MEM (word_mode,
gen_rtx_PLUS (Pmode,
frame_pointer_rtx,
- GEN_INT (STACK_POINTER_OFFSET
+ GEN_INT (FIRST_PARM_OFFSET (0)
+ (UNITS_PER_WORD
* regno)))),
gen_rtx_REG (word_mode,
address = gen_rtx_PLUS (Pmode,
frame_pointer_rtx,
- GEN_INT (STACK_POINTER_OFFSET
+ GEN_INT (FIRST_PARM_OFFSET (0)
+ UNITS_PER_WORD * first_reg));
return address;
are in the return delayed slot. */
case PLUS:
if (GET_CODE (XEXP (*where, 0)) == REG
- && REGNO (XEXP (*where, 0)) == FRAME_POINTER_REGNUM
+ && REGNO (XEXP (*where, 0)) == HARD_FRAME_POINTER_REGNUM
&& (GET_CODE (XEXP (*where, 1)) != CONST_INT
|| INTVAL (XEXP (*where, 1)) < SPARC_STACK_BIAS))
return 1;
case MEM:
if (SPARC_STACK_BIAS
&& GET_CODE (XEXP (*where, 0)) == REG
- && REGNO (XEXP (*where, 0)) == FRAME_POINTER_REGNUM)
+ && REGNO (XEXP (*where, 0)) == HARD_FRAME_POINTER_REGNUM)
return 1;
break;
/* Tell prologue and epilogue if register REGNO should be saved / restored. */
#define RETURN_ADDR_REGNUM 15
-#define FRAME_POINTER_MASK (1 << (FRAME_POINTER_REGNUM))
+#define HARD_FRAME_POINTER_MASK (1 << (HARD_FRAME_POINTER_REGNUM))
#define RETURN_ADDR_MASK (1 << (RETURN_ADDR_REGNUM))
#define MUST_SAVE_REGISTER(regno) \
- ((regs_ever_live[regno] && !call_used_regs[regno]) \
- || (regno == FRAME_POINTER_REGNUM && frame_pointer_needed) \
+ ((regs_ever_live[regno] && !call_used_regs[regno]) \
+ || (regno == HARD_FRAME_POINTER_REGNUM && frame_pointer_needed) \
|| (regno == RETURN_ADDR_REGNUM && regs_ever_live[RETURN_ADDR_REGNUM]))
/* Return the bytes needed to compute the frame pointer from the current
if (size > 0)
{
unsigned int reg_offset = current_frame_info.reg_offset;
- const char *const fp_str = reg_names[FRAME_POINTER_REGNUM];
+ const char *const fp_str = reg_names[HARD_FRAME_POINTER_REGNUM];
static const char *const t1_str = "%g1";
/* Things get a little tricky if local variables take up more than ~4096
{
fprintf (file, "\tadd\t%s, %d, %s\n",
sp_str, (int) -size, sp_str);
- if (gmask & FRAME_POINTER_MASK)
+ if (gmask & HARD_FRAME_POINTER_MASK)
{
fprintf (file, "\tst\t%s, [%s+%d]\n",
fp_str, sp_str, reg_offset);
fprintf (file, HOST_WIDE_INT_PRINT_DEC, size);
fprintf (file, ", %s\n\tsub\t%s, %s, %s\n",
t1_str, sp_str, t1_str, sp_str);
- if (gmask & FRAME_POINTER_MASK)
+ if (gmask & HARD_FRAME_POINTER_MASK)
{
fprintf (file, "\tst\t%s, [%s+%d]\n",
fp_str, sp_str, reg_offset);
if (dwarf2out_do_frame ())
{
char *l = dwarf2out_cfi_label ();
- if (gmask & FRAME_POINTER_MASK)
+ if (gmask & HARD_FRAME_POINTER_MASK)
{
- dwarf2out_reg_save (l, FRAME_POINTER_REGNUM,
+ dwarf2out_reg_save (l, HARD_FRAME_POINTER_REGNUM,
reg_offset - 4 - size);
- dwarf2out_def_cfa (l, FRAME_POINTER_REGNUM, 0);
+ dwarf2out_def_cfa (l, HARD_FRAME_POINTER_REGNUM, 0);
}
else
dwarf2out_def_cfa (l, STACK_POINTER_REGNUM, size);
reg_offset += 4;
}
sparc_flat_save_restore (file, sp_str, reg_offset,
- gmask & ~(FRAME_POINTER_MASK | RETURN_ADDR_MASK),
+ gmask & ~(HARD_FRAME_POINTER_MASK | RETURN_ADDR_MASK),
current_frame_info.fmask,
"st", "std", -size);
}
{
fprintf (file, "\tadd\t%s, %d, %s\n",
sp_str, (int) -size1, sp_str);
- if (gmask & FRAME_POINTER_MASK)
+ if (gmask & HARD_FRAME_POINTER_MASK)
{
fprintf (file, "\tst\t%s, [%s+%d]\n\tsub\t%s, %d, %s\t%s# set up frame pointer\n",
fp_str, sp_str, (int) offset, sp_str, (int) -size1,
fprintf (file, HOST_WIDE_INT_PRINT_DEC, size1);
fprintf (file, ", %s\n\tsub\t%s, %s, %s\n",
t1_str, sp_str, t1_str, sp_str);
- if (gmask & FRAME_POINTER_MASK)
+ if (gmask & HARD_FRAME_POINTER_MASK)
{
fprintf (file, "\tst\t%s, [%s+%d]\n\tadd\t%s, %s, %s\t%s# set up frame pointer\n",
fp_str, sp_str, (int) offset, sp_str, t1_str,
if (dwarf2out_do_frame ())
{
char *l = dwarf2out_cfi_label ();
- if (gmask & FRAME_POINTER_MASK)
+ if (gmask & HARD_FRAME_POINTER_MASK)
{
- dwarf2out_reg_save (l, FRAME_POINTER_REGNUM,
+ dwarf2out_reg_save (l, HARD_FRAME_POINTER_REGNUM,
offset - 4 - size1);
- dwarf2out_def_cfa (l, FRAME_POINTER_REGNUM, 0);
+ dwarf2out_def_cfa (l, HARD_FRAME_POINTER_REGNUM, 0);
}
else
dwarf2out_def_cfa (l, STACK_POINTER_REGNUM, size1);
offset += 4;
}
sparc_flat_save_restore (file, sp_str, offset,
- gmask & ~(FRAME_POINTER_MASK | RETURN_ADDR_MASK),
+ gmask & ~(HARD_FRAME_POINTER_MASK | RETURN_ADDR_MASK),
current_frame_info.fmask,
"st", "std", -size1);
fprintf (file, "\tset\t");
fprintf (file, ", %s\n\tsub\t%s, %s, %s\n",
t1_str, sp_str, t1_str, sp_str);
if (dwarf2out_do_frame ())
- if (! (gmask & FRAME_POINTER_MASK))
+ if (! (gmask & HARD_FRAME_POINTER_MASK))
dwarf2out_def_cfa ("", STACK_POINTER_REGNUM, size);
}
}
unsigned HOST_WIDE_INT reg_offset = current_frame_info.reg_offset;
unsigned HOST_WIDE_INT size1;
const char *const sp_str = reg_names[STACK_POINTER_REGNUM];
- const char *const fp_str = reg_names[FRAME_POINTER_REGNUM];
+ const char *const fp_str = reg_names[HARD_FRAME_POINTER_REGNUM];
static const char *const t1_str = "%g1";
/* In the reload sequence, we don't need to fill the load delay
/* We must restore the frame pointer and return address reg first
because they are treated specially by the prologue output code. */
- if (current_frame_info.gmask & FRAME_POINTER_MASK)
+ if (current_frame_info.gmask & HARD_FRAME_POINTER_MASK)
{
fprintf (file, "\tld\t[%s+%d], %s\n",
sp_str, (int) reg_offset, fp_str);
/* Restore any remaining saved registers. */
sparc_flat_save_restore (file, sp_str, reg_offset,
- current_frame_info.gmask & ~(FRAME_POINTER_MASK | RETURN_ADDR_MASK),
+ current_frame_info.gmask & ~(HARD_FRAME_POINTER_MASK | RETURN_ADDR_MASK),
current_frame_info.fmask,
"ld", "ldd", 0);
accessible. We still account for them to simplify register computations
(eg: in CLASS_MAX_NREGS). There are also 4 fp condition code registers, so
32+32+32+4 == 100.
- Register 100 is used as the integer condition code register. */
+ Register 100 is used as the integer condition code register.
+ Register 101 is used as the soft frame pointer register. */
-#define FIRST_PSEUDO_REGISTER 101
+#define FIRST_PSEUDO_REGISTER 102
#define SPARC_FIRST_FP_REG 32
/* Additional V9 fp regs. */
0, 0, 0, 0, 0, 0, 0, 0, \
0, 0, 0, 0, 0, 0, 0, 0, \
\
- 0, 0, 0, 0, 0}
+ 0, 0, 0, 0, 0, 1}
/* 1 for registers not available across function calls.
These must include the FIXED_REGISTERS and also any
1, 1, 1, 1, 1, 1, 1, 1, \
1, 1, 1, 1, 1, 1, 1, 1, \
\
- 1, 1, 1, 1, 1}
+ 1, 1, 1, 1, 1, 1}
/* If !TARGET_FPU, then make the fp registers and fp cc regs fixed so that
they won't be allocated. */
/* Let the compiler believe the frame pointer is still \
%fp, but output it as %i7. */ \
fixed_regs[31] = 1; \
- reg_names[FRAME_POINTER_REGNUM] = "%i7"; \
+ reg_names[HARD_FRAME_POINTER_REGNUM] = "%i7"; \
/* Disable leaf functions */ \
memset (sparc_leaf_regs, 0, FIRST_PSEUDO_REGISTER); \
} \
#define HARD_REGNO_NREGS(REGNO, MODE) \
(TARGET_ARCH64 \
- ? ((REGNO) < 32 \
- ? (GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD \
- : (GET_MODE_SIZE (MODE) + 3) / 4) \
+ ? ((REGNO) < 32 || (REGNO) == FRAME_POINTER_REGNUM \
+ ? (GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD \
+ : (GET_MODE_SIZE (MODE) + 3) / 4) \
: ((GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD))
/* Due to the ARCH64 descrepancy above we must override this next
/* Register to use for pushing function arguments. */
#define STACK_POINTER_REGNUM 14
+/* The stack bias (amount by which the hardware register is offset by). */
+#define SPARC_STACK_BIAS ((TARGET_ARCH64 && TARGET_STACK_BIAS) ? 2047 : 0)
+
/* Actual top-of-stack address is 92/176 greater than the contents of the
stack pointer register for !v9/v9. That is:
- !v9: 64 bytes for the in and local registers, 4 bytes for structure return
address, and 6*4 bytes for the 6 register parameters.
- v9: 128 bytes for the in and local registers + 6*8 bytes for the integer
parameter regs. */
-#define STACK_POINTER_OFFSET FIRST_PARM_OFFSET(0)
-
-/* The stack bias (amount by which the hardware register is offset by). */
-#define SPARC_STACK_BIAS ((TARGET_ARCH64 && TARGET_STACK_BIAS) ? 2047 : 0)
-
-/* Is stack biased? */
-#define STACK_BIAS SPARC_STACK_BIAS
+#define STACK_POINTER_OFFSET (FIRST_PARM_OFFSET(0) + SPARC_STACK_BIAS)
/* Base register for access to local variables of the function. */
-#define FRAME_POINTER_REGNUM 30
-
-#if 0
-/* Register that is used for the return address for the flat model. */
-#define RETURN_ADDR_REGNUM 15
-#endif
+#define HARD_FRAME_POINTER_REGNUM 30
+
+/* The soft frame pointer does not have the stack bias applied. */
+#define FRAME_POINTER_REGNUM 101
+
+/* Given the stack bias, the stack pointer isn't actually aligned. */
+#define INIT_EXPANDERS \
+ do { \
+ if (cfun && cfun->emit->regno_pointer_align && SPARC_STACK_BIAS) \
+ { \
+ REGNO_POINTER_ALIGN (STACK_POINTER_REGNUM) = BITS_PER_UNIT; \
+ REGNO_POINTER_ALIGN (HARD_FRAME_POINTER_REGNUM) = BITS_PER_UNIT; \
+ } \
+ } while (0)
/* Value should be nonzero if functions must have frame pointers.
Zero means the frame pointer need not be set up (and parms
Being a non-leaf function does not mean a frame pointer is needed in the
flat window model. However, the debugger won't be able to backtrace through
us with out it. */
-#define FRAME_POINTER_REQUIRED \
- (TARGET_FLAT ? (current_function_calls_alloca || current_function_varargs \
- || !leaf_function_p ()) \
+#define FRAME_POINTER_REQUIRED \
+ (TARGET_FLAT \
+ ? (current_function_calls_alloca \
+ || current_function_varargs \
+ || !leaf_function_p ()) \
: ! (leaf_function_p () && only_leaf_regs_used ()))
/* C statement to store the difference between the frame pointer
This is an initializer for a vector of HARD_REG_SET
of length N_REG_CLASSES. */
-#define REG_CLASS_CONTENTS \
- {{0, 0, 0, 0}, {0, 0, 0, 0xf}, {0xffff, 0, 0, 0}, \
- {-1, 0, 0, 0}, {0, -1, 0, 0}, {0, -1, -1, 0}, \
- {-1, -1, 0, 0}, {-1, -1, -1, 0}, {-1, -1, -1, 0x1f}}
+#define REG_CLASS_CONTENTS \
+ {{0, 0, 0, 0}, /* NO_REGS */ \
+ {0, 0, 0, 0xf}, /* FPCC_REGS */ \
+ {0xffff, 0, 0, 0}, /* I64_REGS */ \
+ {-1, 0, 0, 0x20}, /* GENERAL_REGS */ \
+ {0, -1, 0, 0}, /* FP_REGS */ \
+ {0, -1, -1, 0}, /* EXTRA_FP_REGS */ \
+ {-1, -1, 0, 0x20}, /* GENERAL_OR_FP_REGS */ \
+ {-1, -1, -1, 0x20}, /* GENERAL_OR_EXTRA_FP_REGS */ \
+ {-1, -1, -1, 0x3f}} /* ALL_REGS */
/* The same information, inverted:
Return the class number of the smallest class containing
88, 89, 90, 91, 92, 93, 94, 95, /* %f56-%f63 */ \
32, 33, /* %f0,%f1 */ \
96, 97, 98, 99, 100, /* %fcc0-3, %icc */ \
- 1, 4, 5, 6, 7, 0, 14, 30}
+ 1, 4, 5, 6, 7, 0, 14, 30, 101}
/* This is the order in which to allocate registers for
leaf functions. If all registers can fit in the "gi" registers,
88, 89, 90, 91, 92, 93, 94, 95, \
32, 33, \
96, 97, 98, 99, 100, \
- 0, 14, 30, 31}
+ 0, 14, 30, 31, 101}
#define ORDER_REGS_FOR_LOCAL_ALLOC order_regs_for_local_alloc ()
of the first local allocated. */
/* This allows space for one TFmode floating point value. */
#define STARTING_FRAME_OFFSET \
- (TARGET_ARCH64 ? (SPARC_STACK_BIAS - 16) \
+ (TARGET_ARCH64 ? -16 \
: (-SPARC_STACK_ALIGN (LONG_DOUBLE_TYPE_SIZE / BITS_PER_UNIT)))
/* If we generate an insn to push BYTES bytes,
even if this function isn't going to use it.
v9: This is 128 for the ins and locals. */
#define FIRST_PARM_OFFSET(FNDECL) \
- (TARGET_ARCH64 ? (SPARC_STACK_BIAS + 16 * UNITS_PER_WORD) \
- : (STRUCT_VALUE_OFFSET + UNITS_PER_WORD))
+ (TARGET_ARCH64 ? 16 * UNITS_PER_WORD : STRUCT_VALUE_OFFSET + UNITS_PER_WORD)
/* Offset from the argument pointer register value to the CFA.
This is different from FIRST_PARM_OFFSET because the register window
comes between the CFA and the arguments. */
-
#define ARG_POINTER_CFA_OFFSET(FNDECL) SPARC_STACK_BIAS
/* When a parameter is passed in a register, stack space is still
all 6 slots even for v9. */
#define REG_PARM_STACK_SPACE(DECL) (6 * UNITS_PER_WORD)
+/* Definitions for register elimination. */
+/* ??? In TARGET_FLAT mode we needn't have a hard frame pointer. */
+
+#define ELIMINABLE_REGS \
+ {{ FRAME_POINTER_REGNUM, HARD_FRAME_POINTER_REGNUM}}
+
+#define CAN_ELIMINATE(FROM, TO) 1
+
+#define INITIAL_ELIMINATION_OFFSET(FROM, TO, OFFSET) \
+ ((OFFSET) = SPARC_STACK_BIAS)
+
/* Keep the stack pointer constant throughout the function.
This is both an optimization and a necessity: longjmp
doesn't behave itself when the stack pointer moves within
has been allocated, which happens in local-alloc.c. */
#define REGNO_OK_FOR_INDEX_P(REGNO) \
-((REGNO) < 32 || (unsigned) reg_renumber[REGNO] < (unsigned)32)
-#define REGNO_OK_FOR_BASE_P(REGNO) \
-((REGNO) < 32 || (unsigned) reg_renumber[REGNO] < (unsigned)32)
+((REGNO) < 32 || (unsigned) reg_renumber[REGNO] < (unsigned)32 \
+ || (REGNO) == FRAME_POINTER_REGNUM \
+ || reg_renumber[REGNO] == FRAME_POINTER_REGNUM)
+
+#define REGNO_OK_FOR_BASE_P(REGNO) REGNO_OK_FOR_INDEX_P (REGNO)
+
#define REGNO_OK_FOR_FP_P(REGNO) \
(((unsigned) (REGNO) - 32 < (TARGET_V9 ? (unsigned)64 : (unsigned)32)) \
|| ((unsigned) reg_renumber[REGNO] - 32 < (TARGET_V9 ? (unsigned)64 : (unsigned)32)))
/* Nonzero if X is a hard reg that can be used as an index
or if it is a pseudo reg. */
#define REG_OK_FOR_INDEX_P(X) \
- (((unsigned) REGNO (X)) - 32 >= (FIRST_PSEUDO_REGISTER - 32))
+ (REGNO (X) < 32 \
+ || REGNO (X) == FRAME_POINTER_REGNUM \
+ || REGNO (X) >= FIRST_PSEUDO_REGISTER)
+
/* Nonzero if X is a hard reg that can be used as a base reg
or if it is a pseudo reg. */
-#define REG_OK_FOR_BASE_P(X) \
- (((unsigned) REGNO (X)) - 32 >= (FIRST_PSEUDO_REGISTER - 32))
+#define REG_OK_FOR_BASE_P(X) REG_OK_FOR_INDEX_P (X)
/* 'T', 'U' are for aligned memory loads which aren't needed for arch64. */
"%f40", "%f41", "%f42", "%f43", "%f44", "%f45", "%f46", "%f47", \
"%f48", "%f49", "%f50", "%f51", "%f52", "%f53", "%f54", "%f55", \
"%f56", "%f57", "%f58", "%f59", "%f60", "%f61", "%f62", "%f63", \
- "%fcc0", "%fcc1", "%fcc2", "%fcc3", "%icc"}
+ "%fcc0", "%fcc1", "%fcc2", "%fcc3", "%icc", "%sfp" }
/* Define additional names for use in asm clobbers and asm declarations. */