Commit 563c12b0 by Richard Henderson Committed by Richard Henderson

combine.c (force_to_mode): Remove STACK_BIAS code.

        * 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
parent ca56cd30
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
current_function_is_thunk.
(alpha_sa_mask): Distinguish between current_function_is_thunk
......
......@@ -6753,33 +6753,12 @@ force_to_mode (x, mode, mask, reg, just_select)
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 ... */
......@@ -7916,40 +7895,23 @@ nonzero_bits (x, mode)
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
......@@ -7964,7 +7926,7 @@ nonzero_bits (x, mode)
&& ! 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);
......@@ -7990,7 +7952,7 @@ nonzero_bits (x, mode)
| ((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)])
{
......@@ -8128,22 +8090,6 @@ nonzero_bits (x, mode)
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;
......
......@@ -88,7 +88,7 @@ do { \
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.
......
......@@ -73,4 +73,4 @@ do { \
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)
......@@ -83,7 +83,7 @@ Boston, MA 02111-1307, USA. */
#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. */
......
......@@ -83,10 +83,9 @@ static rtx leaf_label;
#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,
......@@ -2988,8 +2987,7 @@ mem_min_alignment (mem, desired)
{
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
......@@ -3206,7 +3204,7 @@ sparc_init_modes ()
{
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;
......@@ -3554,7 +3552,7 @@ sparc_nonflat_function_prologue (file, size, leaf_function)
/* 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)
......@@ -4862,7 +4860,7 @@ sparc_builtin_saveregs ()
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,
......@@ -4870,7 +4868,7 @@ sparc_builtin_saveregs ()
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;
......@@ -5483,7 +5481,7 @@ epilogue_renumber (where, test)
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;
......@@ -5492,7 +5490,7 @@ epilogue_renumber (where, test)
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;
......@@ -6437,12 +6435,12 @@ struct sparc_frame_info zero_frame_info;
/* 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
......@@ -6715,7 +6713,7 @@ sparc_flat_function_prologue (file, size)
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
......@@ -6736,7 +6734,7 @@ sparc_flat_function_prologue (file, size)
{
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);
......@@ -6751,7 +6749,7 @@ sparc_flat_function_prologue (file, size)
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);
......@@ -6763,11 +6761,11 @@ sparc_flat_function_prologue (file, size)
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);
......@@ -6781,7 +6779,7 @@ sparc_flat_function_prologue (file, 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);
}
......@@ -6798,7 +6796,7 @@ sparc_flat_function_prologue (file, 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,
......@@ -6812,7 +6810,7 @@ sparc_flat_function_prologue (file, size)
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,
......@@ -6823,11 +6821,11 @@ sparc_flat_function_prologue (file, size)
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);
......@@ -6843,7 +6841,7 @@ sparc_flat_function_prologue (file, size)
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");
......@@ -6851,7 +6849,7 @@ sparc_flat_function_prologue (file, size)
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);
}
}
......@@ -6900,7 +6898,7 @@ sparc_flat_function_epilogue (file, 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
......@@ -6946,7 +6944,7 @@ sparc_flat_function_epilogue (file, size)
/* 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);
......@@ -6961,7 +6959,7 @@ sparc_flat_function_epilogue (file, size)
/* 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);
......
......@@ -894,9 +894,10 @@ if (TARGET_ARCH64 \
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. */
......@@ -962,7 +963,7 @@ if (TARGET_ARCH64 \
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
......@@ -987,7 +988,7 @@ if (TARGET_ARCH64 \
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. */
......@@ -1042,7 +1043,7 @@ do \
/* 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); \
} \
......@@ -1062,9 +1063,9 @@ while (0)
#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
......@@ -1107,27 +1108,32 @@ extern int sparc_mode_class[];
/* 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
......@@ -1138,9 +1144,11 @@ extern int sparc_mode_class[];
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
......@@ -1275,10 +1283,16 @@ enum reg_class { NO_REGS, FPCC_REGS, I64_REGS, GENERAL_REGS, FP_REGS,
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
......@@ -1310,7 +1324,7 @@ extern enum reg_class sparc_regno_reg_class[FIRST_PSEUDO_REGISTER];
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,
......@@ -1331,7 +1345,7 @@ extern enum reg_class sparc_regno_reg_class[FIRST_PSEUDO_REGISTER];
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 ()
......@@ -1535,7 +1549,7 @@ extern const char leaf_reg_remap[];
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,
......@@ -1548,13 +1562,11 @@ extern const char leaf_reg_remap[];
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
......@@ -1568,6 +1580,17 @@ extern const char leaf_reg_remap[];
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
......@@ -1996,9 +2019,12 @@ do { \
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)))
......@@ -2092,11 +2118,13 @@ do { \
/* 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. */
......@@ -2675,7 +2703,7 @@ do { \
"%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. */
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment