Commit 7bea35e7 by Michael Meissner

Rework large stack frame support.

From-SVN: r2884
parent f49acdb4
...@@ -3732,6 +3732,72 @@ mips_output_float (stream, value) ...@@ -3732,6 +3732,72 @@ mips_output_float (stream, value)
} }
/* Return TRUE if any register used in the epilogue is used. This to insure
any insn put into the epilogue delay slots is safe. */
int
epilogue_reg_mentioned_p (insn)
rtx insn;
{
register char *fmt;
register int i;
register enum rtx_code code;
register int regno;
if (insn == (rtx)0)
return 0;
if (GET_CODE (insn) == LABEL_REF)
return 0;
code = GET_CODE (insn);
switch (code)
{
case REG:
regno = REGNO (insn);
if (regno == STACK_POINTER_REGNUM)
return 1;
if (regno == FRAME_POINTER_REGNUM && frame_pointer_needed)
return 1;
if (!call_used_regs[regno])
return 1;
if (regno != MIPS_TEMP1_REGNUM && regno != MIPS_TEMP2_REGNUM)
return 0;
if (!current_frame_info.initialized)
compute_frame_size (get_frame_size ());
return (current_frame_info.total_size >= 32768);
case SCRATCH:
case CC0:
case PC:
case CONST_INT:
case CONST_DOUBLE:
return 0;
}
fmt = GET_RTX_FORMAT (code);
for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
{
if (fmt[i] == 'E')
{
register int j;
for (j = XVECLEN (insn, i) - 1; j >= 0; j--)
if (epilogue_reg_mentioned_p (XVECEXP (insn, i, j)))
return 1;
}
else if (fmt[i] == 'e' && epilogue_reg_mentioned_p (XEXP (insn, i)))
return 1;
}
return 0;
}
/* Return the bytes needed to compute the frame pointer from the current /* Return the bytes needed to compute the frame pointer from the current
stack pointer. stack pointer.
...@@ -3785,22 +3851,22 @@ mips_output_float (stream, value) ...@@ -3785,22 +3851,22 @@ mips_output_float (stream, value)
*/ */
unsigned long long
compute_frame_size (size) compute_frame_size (size)
int size; /* # of var. bytes allocated */ int size; /* # of var. bytes allocated */
{ {
int regno; int regno;
unsigned long total_size; /* # bytes that the entire frame takes up */ long total_size; /* # bytes that the entire frame takes up */
unsigned long var_size; /* # bytes that variables take up */ long var_size; /* # bytes that variables take up */
unsigned long args_size; /* # bytes that outgoing arguments take up */ long args_size; /* # bytes that outgoing arguments take up */
unsigned long extra_size; /* # extra bytes */ long extra_size; /* # extra bytes */
unsigned int gp_reg_rounded; /* # bytes needed to store gp after rounding */ long gp_reg_rounded; /* # bytes needed to store gp after rounding */
unsigned int gp_reg_size; /* # bytes needed to store gp regs */ long gp_reg_size; /* # bytes needed to store gp regs */
unsigned int fp_reg_size; /* # bytes needed to store fp regs */ long fp_reg_size; /* # bytes needed to store fp regs */
unsigned long mask; /* mask of saved gp registers */ long mask; /* mask of saved gp registers */
unsigned long fmask; /* mask of saved fp registers */ long fmask; /* mask of saved fp registers */
int fp_inc; /* 1 or 2 depending on the size of fp regs */ int fp_inc; /* 1 or 2 depending on the size of fp regs */
int fp_bits; /* bitmask to use for each fp register */ long fp_bits; /* bitmask to use for each fp register */
gp_reg_size = 0; gp_reg_size = 0;
fp_reg_size = 0; fp_reg_size = 0;
...@@ -3826,7 +3892,7 @@ compute_frame_size (size) ...@@ -3826,7 +3892,7 @@ compute_frame_size (size)
if (MUST_SAVE_REGISTER (regno)) if (MUST_SAVE_REGISTER (regno))
{ {
gp_reg_size += UNITS_PER_WORD; gp_reg_size += UNITS_PER_WORD;
mask |= 1 << (regno - GP_REG_FIRST); mask |= 1L << (regno - GP_REG_FIRST);
} }
} }
...@@ -3900,156 +3966,213 @@ compute_frame_size (size) ...@@ -3900,156 +3966,213 @@ compute_frame_size (size)
} }
/* Save/restore registers printing out the instructions to a file. */ /* Common code to emit the insns (or to write the instructions to a file)
to save/restore registers.
void Other parts of the code assume that MIPS_TEMP1_REGNUM (aka large_reg)
save_restore (file, gp_op, gp_2word_op, fp_op) is not modified within save_restore_insns. */
FILE *file; /* stream to write to */
char *gp_op; /* operation to do on gp registers */ #define BITSET_P(value,bit) (((value) & (1L << (bit))) != 0)
char *gp_2word_op; /* 2 word op to do on gp registers */
char *fp_op; /* operation to do on fp registers */ static void
save_restore_insns (store_p, large_reg, large_offset, file)
int store_p; /* true if this is prologue */
rtx large_reg; /* register holding large offset constant or NULL */
long large_offset; /* large constant offset value */
FILE *file; /* file to write instructions to instead of making RTL */
{ {
long mask = current_frame_info.mask;
long fmask = current_frame_info.fmask;
int regno; int regno;
unsigned long mask = current_frame_info.mask; rtx base_reg_rtx;
unsigned long fmask = current_frame_info.fmask; long base_offset;
unsigned long gp_offset; long gp_offset;
unsigned long fp_offset; long fp_offset;
unsigned long min_offset; long end_offset;
char *base_reg;
if (frame_pointer_needed && !BITSET_P (mask, FRAME_POINTER_REGNUM - GP_REG_FIRST))
abort ();
if (mask == 0 && fmask == 0) if (mask == 0 && fmask == 0)
return; return;
base_reg = reg_names[STACK_POINTER_REGNUM];
gp_offset = current_frame_info.gp_sp_offset;
fp_offset = current_frame_info.fp_sp_offset;
min_offset = (gp_offset < fp_offset && mask != 0) ? gp_offset : fp_offset;
/* Deal with calling functions with a large structure. */
if (min_offset >= 32768)
{
char *temp = reg_names[MIPS_TEMP2_REGNUM];
fprintf (file, "\tli\t%s,%ld\n", temp, min_offset);
fprintf (file, "\taddu\t%s,%s,%s\n", temp, temp, base_reg);
base_reg = temp;
gp_offset = min_offset - gp_offset;
fp_offset = min_offset - fp_offset;
}
/* Save registers starting from high to low. The debuggers prefer /* Save registers starting from high to low. The debuggers prefer
at least the return register be stored at func+4, and also it at least the return register be stored at func+4, and also it
allows us not to need a nop in the epilog if at least one allows us not to need a nop in the epilog if at least one
register is reloaded in addition to return address. */ register is reloaded in addition to return address. */
if (mask || frame_pointer_needed) /* Save GP registers if needed. */
if (mask)
{ {
for (regno = GP_REG_LAST; regno >= GP_REG_FIRST; regno--) /* Pick which pointer to use as a base register. For small
{ frames, just use the stack pointer. Otherwise, use a
if ((mask & (1L << (regno - GP_REG_FIRST))) != 0 temporary register. Save 2 cycles if the save area is near
|| (regno == FRAME_POINTER_REGNUM && frame_pointer_needed)) the end of a large frame, by reusing the constant created in
{ the prologue/epilogue to adjust the stack frame. */
fprintf (file, "\t%s\t%s,%d(%s)\n",
gp_op, reg_names[regno],
gp_offset, base_reg);
gp_offset -= UNITS_PER_WORD; gp_offset = current_frame_info.gp_sp_offset;
} end_offset = gp_offset - (current_frame_info.gp_reg_size - UNITS_PER_WORD);
if (gp_offset < 0 || end_offset < 0)
fatal ("gp_offset (%ld) or end_offset (%ld) is less than zero.",
gp_offset, end_offset);
else if (gp_offset < 32768)
{
base_reg_rtx = stack_pointer_rtx;
base_offset = 0;
} }
}
if (fmask) else if (large_reg != (rtx)0
{ && (((unsigned long)(large_offset - gp_offset)) < 32768)
int fp_inc = (TARGET_FLOAT64) ? 1 : 2; && (((unsigned long)(large_offset - end_offset)) < 32768))
{
base_reg_rtx = gen_rtx (REG, Pmode, MIPS_TEMP2_REGNUM);
base_offset = large_offset;
if (file == (FILE *)0)
emit_insn (gen_addsi3 (base_reg_rtx, large_reg, stack_pointer_rtx));
else
fprintf (file, "\taddu\t%s,%s,%s\n",
reg_names[MIPS_TEMP2_REGNUM],
reg_names[REGNO (large_reg)],
reg_names[STACK_POINTER_REGNUM]);
}
for (regno = FP_REG_LAST-1; regno >= FP_REG_FIRST; regno -= fp_inc) else
{ {
if ((fmask & (1L << (regno - FP_REG_FIRST))) != 0) base_reg_rtx = gen_rtx (REG, Pmode, MIPS_TEMP2_REGNUM);
base_offset = gp_offset;
if (file == (FILE *)0)
{ {
fprintf (file, "\t%s\t%s,%d(%s)\n", emit_move_insn (base_reg_rtx, GEN_INT (gp_offset));
fp_op, reg_names[regno], fp_offset, base_reg); emit_insn (gen_addsi3 (base_reg_rtx, base_reg_rtx, stack_pointer_rtx));
fp_offset -= 2*UNITS_PER_WORD;
} }
else
fprintf (file, "\tli\t%s,0x%.08lx\t# %ld\n\taddu\t%s,%s,%s\n",
reg_names[MIPS_TEMP2_REGNUM],
(long)base_offset,
(long)base_offset,
reg_names[MIPS_TEMP2_REGNUM],
reg_names[MIPS_TEMP2_REGNUM],
reg_names[STACK_POINTER_REGNUM]);
} }
}
}
/* Common code to emit the insns to save/restore registers. */
static void
save_restore_insns (store_p)
int store_p; /* true if this is prologue */
{
int regno;
rtx base_reg_rtx = stack_pointer_rtx;
unsigned long mask = current_frame_info.mask;
unsigned long fmask = current_frame_info.fmask;
unsigned long gp_offset;
unsigned long fp_offset;
unsigned long min_offset;
if (mask == 0 && fmask == 0)
return;
gp_offset = current_frame_info.gp_sp_offset;
fp_offset = current_frame_info.fp_sp_offset;
min_offset = (gp_offset < fp_offset && mask != 0) ? gp_offset : fp_offset;
/* Deal with calling functions with a large structure. */
if (min_offset >= 32768)
{
base_reg_rtx = gen_rtx (REG, Pmode, MIPS_TEMP2_REGNUM);
emit_move_insn (base_reg_rtx, GEN_INT (min_offset));
emit_insn (gen_addsi3 (base_reg_rtx, base_reg_rtx, stack_pointer_rtx));
gp_offset = min_offset - gp_offset;
fp_offset = min_offset - fp_offset;
}
/* Save registers starting from high to low. The debuggers prefer
at least the return register be stored at func+4, and also it
allows us not to need a nop in the epilog if at least one
register is reloaded in addition to return address. */
if (mask || frame_pointer_needed)
{
for (regno = GP_REG_LAST; regno >= GP_REG_FIRST; regno--) for (regno = GP_REG_LAST; regno >= GP_REG_FIRST; regno--)
{ {
if ((mask & (1L << (regno - GP_REG_FIRST))) != 0 if (BITSET_P (mask, regno - GP_REG_FIRST))
|| (regno == FRAME_POINTER_REGNUM && frame_pointer_needed))
{ {
rtx reg_rtx = gen_rtx (REG, Pmode, regno); if (file == (FILE *)0)
rtx mem_rtx = gen_rtx (MEM, Pmode, {
gen_rtx (PLUS, Pmode, base_reg_rtx, rtx reg_rtx = gen_rtx (REG, Pmode, regno);
GEN_INT (gp_offset))); rtx mem_rtx = gen_rtx (MEM, Pmode,
gen_rtx (PLUS, Pmode, base_reg_rtx,
GEN_INT (gp_offset - base_offset)));
if (store_p) if (store_p)
emit_move_insn (mem_rtx, reg_rtx); emit_move_insn (mem_rtx, reg_rtx);
else
emit_move_insn (reg_rtx, mem_rtx);
}
else else
emit_move_insn (reg_rtx, mem_rtx); fprintf (file, "\t%s\t%s,%ld(%s)\n",
(store_p) ? "sw" : "lw",
reg_names[regno],
gp_offset - base_offset,
reg_names[REGNO(base_reg_rtx)]);
gp_offset -= UNITS_PER_WORD; gp_offset -= UNITS_PER_WORD;
} }
} }
} }
else
{
base_reg_rtx = (rtx)0; /* Make sure these are initialzed */
base_offset = 0;
}
/* Save floating point registers if needed. */
if (fmask) if (fmask)
{ {
int fp_inc = (TARGET_FLOAT64) ? 1 : 2; int fp_inc = (TARGET_FLOAT64) ? 1 : 2;
/* Pick which pointer to use as a base register. */
fp_offset = current_frame_info.fp_sp_offset;
end_offset = fp_offset - (current_frame_info.fp_reg_size - UNITS_PER_WORD);
if (fp_offset < 0 || end_offset < 0)
fatal ("fp_offset (%ld) or end_offset (%ld) is less than zero.",
fp_offset, end_offset);
else if (fp_offset < 32768)
{
base_reg_rtx = stack_pointer_rtx;
base_offset = 0;
}
else if (base_reg_rtx != (rtx)0
&& (((unsigned long)(base_offset - fp_offset)) < 32768)
&& (((unsigned long)(base_offset - end_offset)) < 32768))
{
; /* already set up for gp registers above */
}
else if (large_reg != (rtx)0
&& (((unsigned long)(large_offset - fp_offset)) < 32768)
&& (((unsigned long)(large_offset - end_offset)) < 32768))
{
base_reg_rtx = gen_rtx (REG, Pmode, MIPS_TEMP2_REGNUM);
base_offset = large_offset;
if (file == (FILE *)0)
emit_insn (gen_addsi3 (base_reg_rtx, large_reg, stack_pointer_rtx));
else
fprintf (file, "\taddu\t%s,%s,%s\n",
reg_names[MIPS_TEMP2_REGNUM],
reg_names[REGNO (large_reg)],
reg_names[STACK_POINTER_REGNUM]);
}
else
{
base_reg_rtx = gen_rtx (REG, Pmode, MIPS_TEMP2_REGNUM);
base_offset = fp_offset;
if (file == (FILE *)0)
{
emit_move_insn (base_reg_rtx, GEN_INT (fp_offset));
emit_insn (gen_addsi3 (base_reg_rtx, base_reg_rtx, stack_pointer_rtx));
}
else
fprintf (file, "\tli\t%s,0x%.08lx\t# %ld\n\taddu\t%s,%s,%s\n",
reg_names[MIPS_TEMP2_REGNUM],
(long)base_offset,
(long)base_offset,
reg_names[MIPS_TEMP2_REGNUM],
reg_names[MIPS_TEMP2_REGNUM],
reg_names[STACK_POINTER_REGNUM]);
}
for (regno = FP_REG_LAST-1; regno >= FP_REG_FIRST; regno -= fp_inc) for (regno = FP_REG_LAST-1; regno >= FP_REG_FIRST; regno -= fp_inc)
{ {
if ((fmask & (1L << (regno - FP_REG_FIRST))) != 0) if (BITSET_P (fmask, regno - FP_REG_FIRST))
{ {
rtx reg_rtx = gen_rtx (REG, DFmode, regno); if (file == (FILE *)0)
rtx mem_rtx = gen_rtx (MEM, DFmode, {
gen_rtx (PLUS, Pmode, base_reg_rtx, rtx reg_rtx = gen_rtx (REG, DFmode, regno);
GEN_INT (fp_offset))); rtx mem_rtx = gen_rtx (MEM, DFmode,
gen_rtx (PLUS, Pmode, base_reg_rtx,
GEN_INT (fp_offset - base_offset)));
if (store_p) if (store_p)
emit_move_insn (mem_rtx, reg_rtx); emit_move_insn (mem_rtx, reg_rtx);
else
emit_move_insn (reg_rtx, mem_rtx);
}
else else
emit_move_insn (reg_rtx, mem_rtx); fprintf (file, "\t%s\t%s,%ld(%s)\n",
(store_p) ? "s.d" : "l.d",
reg_names[regno],
fp_offset - base_offset,
reg_names[REGNO(base_reg_rtx)]);
fp_offset -= 2*UNITS_PER_WORD; fp_offset -= 2*UNITS_PER_WORD;
} }
...@@ -4065,7 +4188,7 @@ function_prologue (file, size) ...@@ -4065,7 +4188,7 @@ function_prologue (file, size)
FILE *file; FILE *file;
int size; int size;
{ {
int tsize = current_frame_info.total_size; long tsize = current_frame_info.total_size;
ASM_OUTPUT_SOURCE_FILENAME (file, DECL_SOURCE_FILE (current_function_decl)); ASM_OUTPUT_SOURCE_FILENAME (file, DECL_SOURCE_FILE (current_function_decl));
...@@ -4076,6 +4199,7 @@ function_prologue (file, size) ...@@ -4076,6 +4199,7 @@ function_prologue (file, size)
fputs ("\t.ent\t", file); fputs ("\t.ent\t", file);
assemble_name (file, current_function_name); assemble_name (file, current_function_name);
fputs ("\n", file); fputs ("\n", file);
assemble_name (file, current_function_name); assemble_name (file, current_function_name);
fputs (":\n", file); fputs (":\n", file);
...@@ -4112,7 +4236,7 @@ void ...@@ -4112,7 +4236,7 @@ void
mips_expand_prologue () mips_expand_prologue ()
{ {
int regno; int regno;
int tsize; long tsize;
tree fndecl = current_function_decl; /* current... is tooo long */ tree fndecl = current_function_decl; /* current... is tooo long */
tree fntype = TREE_TYPE (fndecl); tree fntype = TREE_TYPE (fndecl);
tree fnargs = (TREE_CODE (fntype) != METHOD_TYPE) tree fnargs = (TREE_CODE (fntype) != METHOD_TYPE)
...@@ -4120,6 +4244,7 @@ mips_expand_prologue () ...@@ -4120,6 +4244,7 @@ mips_expand_prologue ()
: 0; : 0;
tree next_arg; tree next_arg;
tree cur_arg; tree cur_arg;
rtx tmp_rtx = (rtx)0;
char *arg_name = (char *)0; char *arg_name = (char *)0;
CUMULATIVE_ARGS args_so_far; CUMULATIVE_ARGS args_so_far;
...@@ -4200,14 +4325,14 @@ mips_expand_prologue () ...@@ -4200,14 +4325,14 @@ mips_expand_prologue ()
if (tsize > 32767) if (tsize > 32767)
{ {
rtx tmp_rtx = gen_rtx (REG, SImode, MIPS_TEMP1_REGNUM); tmp_rtx = gen_rtx (REG, SImode, MIPS_TEMP1_REGNUM);
emit_move_insn (tmp_rtx, tsize_rtx); emit_move_insn (tmp_rtx, tsize_rtx);
tsize_rtx = tmp_rtx; tsize_rtx = tmp_rtx;
} }
emit_insn (gen_subsi3 (stack_pointer_rtx, stack_pointer_rtx, tsize_rtx)); emit_insn (gen_subsi3 (stack_pointer_rtx, stack_pointer_rtx, tsize_rtx));
save_restore_insns (TRUE); save_restore_insns (TRUE, tmp_rtx, tsize, (FILE *)0);
if (frame_pointer_needed) if (frame_pointer_needed)
emit_insn (gen_movsi (frame_pointer_rtx, stack_pointer_rtx)); emit_insn (gen_movsi (frame_pointer_rtx, stack_pointer_rtx));
...@@ -4228,7 +4353,7 @@ function_epilogue (file, size) ...@@ -4228,7 +4353,7 @@ function_epilogue (file, size)
FILE *file; FILE *file;
int size; int size;
{ {
int tsize; long tsize;
char *sp_str = reg_names[STACK_POINTER_REGNUM]; char *sp_str = reg_names[STACK_POINTER_REGNUM];
char *t1_str = reg_names[MIPS_TEMP1_REGNUM]; char *t1_str = reg_names[MIPS_TEMP1_REGNUM];
rtx epilogue_delay = current_function_epilogue_delay_list; rtx epilogue_delay = current_function_epilogue_delay_list;
...@@ -4236,6 +4361,9 @@ function_epilogue (file, size) ...@@ -4236,6 +4361,9 @@ function_epilogue (file, size)
int noepilogue = FALSE; int noepilogue = FALSE;
int load_nop = FALSE; int load_nop = FALSE;
int load_only_r31; int load_only_r31;
rtx tmp_rtx = (rtx)0;
rtx restore_rtx;
int i;
/* The epilogue does not depend on any registers, but the stack /* The epilogue does not depend on any registers, but the stack
registers, so we assume that if we have 1 pending nop, it can be registers, so we assume that if we have 1 pending nop, it can be
...@@ -4316,13 +4444,16 @@ function_epilogue (file, size) ...@@ -4316,13 +4444,16 @@ function_epilogue (file, size)
fprintf (file, "\t.set\tnoreorder\n"); fprintf (file, "\t.set\tnoreorder\n");
if (tsize > 32767) if (tsize > 32767)
fprintf (file, "\tli\t%s,%d\n", t1_str, tsize); {
fprintf (file, "\tli\t%s,0x%.08lx\t# %ld\n", t1_str, (long)tsize, (long)tsize);
tmp_rtx = gen_rtx (REG, Pmode, MIPS_TEMP1_REGNUM);
}
if (frame_pointer_needed) if (frame_pointer_needed)
fprintf (file, "\tmove\t%s,%s\t\t\t# sp not trusted here\n", fprintf (file, "\tmove\t%s,%s\t\t\t# sp not trusted here\n",
sp_str, reg_names[FRAME_POINTER_REGNUM]); sp_str, reg_names[FRAME_POINTER_REGNUM]);
save_restore (file, "lw", "ld", "l.d"); save_restore_insns (FALSE, tmp_rtx, tsize, file);
load_only_r31 = (current_frame_info.mask == (1 << 31) load_only_r31 = (current_frame_info.mask == (1 << 31)
&& current_frame_info.fmask == 0); && current_frame_info.fmask == 0);
...@@ -4469,12 +4600,13 @@ function_epilogue (file, size) ...@@ -4469,12 +4600,13 @@ function_epilogue (file, size)
void void
mips_expand_epilogue () mips_expand_epilogue ()
{ {
int tsize = current_frame_info.total_size; long tsize = current_frame_info.total_size;
rtx tsize_rtx = GEN_INT (tsize); rtx tsize_rtx = GEN_INT (tsize);
rtx tmp_rtx = (rtx)0;
if (tsize > 32767) if (tsize > 32767)
{ {
rtx tmp_rtx = gen_rtx (REG, SImode, MIPS_TEMP1_REGNUM); tmp_rtx = gen_rtx (REG, SImode, MIPS_TEMP1_REGNUM);
emit_move_insn (tmp_rtx, tsize_rtx); emit_move_insn (tmp_rtx, tsize_rtx);
tsize_rtx = tmp_rtx; tsize_rtx = tmp_rtx;
} }
...@@ -4484,7 +4616,7 @@ mips_expand_epilogue () ...@@ -4484,7 +4616,7 @@ mips_expand_epilogue ()
if (frame_pointer_needed) if (frame_pointer_needed)
emit_insn (gen_movsi (stack_pointer_rtx, frame_pointer_rtx)); emit_insn (gen_movsi (stack_pointer_rtx, frame_pointer_rtx));
save_restore_insns (FALSE); save_restore_insns (FALSE, tmp_rtx, tsize, (FILE *)0);
emit_insn (gen_addsi3 (stack_pointer_rtx, stack_pointer_rtx, tsize_rtx)); emit_insn (gen_addsi3 (stack_pointer_rtx, stack_pointer_rtx, tsize_rtx));
} }
......
...@@ -126,7 +126,8 @@ extern int arith32_operand (); ...@@ -126,7 +126,8 @@ extern int arith32_operand ();
extern int arith_operand (); extern int arith_operand ();
extern int cmp_op (); extern int cmp_op ();
extern int cmp2_op (); extern int cmp2_op ();
extern unsigned long compute_frame_size (); extern long compute_frame_size ();
extern int epilogue_reg_mentioned_p ();
extern void expand_block_move (); extern void expand_block_move ();
extern int equality_op (); extern int equality_op ();
extern int fcmp_op (); extern int fcmp_op ();
...@@ -482,7 +483,7 @@ while (0) ...@@ -482,7 +483,7 @@ while (0)
/* Print subsidiary information on the compiler version in use. */ /* Print subsidiary information on the compiler version in use. */
#define MIPS_VERSION "[AL 1.1, MM 31]" #define MIPS_VERSION "[AL 1.1, MM 32]"
#ifndef MACHINE_TYPE #ifndef MACHINE_TYPE
#define MACHINE_TYPE "BSD Mips" #define MACHINE_TYPE "BSD Mips"
...@@ -1229,6 +1230,7 @@ extern char mips_hard_regno_mode_ok[][FIRST_PSEUDO_REGISTER]; ...@@ -1229,6 +1230,7 @@ extern char mips_hard_regno_mode_ok[][FIRST_PSEUDO_REGISTER];
scratch register set, and not used for passing and returning scratch register set, and not used for passing and returning
arguments and any other information used in the calling sequence arguments and any other information used in the calling sequence
(such as pic). */ (such as pic). */
#define MIPS_TEMP1_REGNUM (GP_REG_FIRST + 8) #define MIPS_TEMP1_REGNUM (GP_REG_FIRST + 8)
#define MIPS_TEMP2_REGNUM (GP_REG_FIRST + 9) #define MIPS_TEMP2_REGNUM (GP_REG_FIRST + 9)
...@@ -1540,21 +1542,21 @@ extern enum reg_class mips_char_to_class[]; ...@@ -1540,21 +1542,21 @@ extern enum reg_class mips_char_to_class[];
struct mips_frame_info struct mips_frame_info
{ {
unsigned long total_size; /* # bytes that the entire frame takes up */ long total_size; /* # bytes that the entire frame takes up */
unsigned long var_size; /* # bytes that variables take up */ long var_size; /* # bytes that variables take up */
unsigned long args_size; /* # bytes that outgoing arguments take up */ long args_size; /* # bytes that outgoing arguments take up */
unsigned long extra_size; /* # bytes of extra gunk */ long extra_size; /* # bytes of extra gunk */
unsigned int gp_reg_size; /* # bytes needed to store gp regs */ int gp_reg_size; /* # bytes needed to store gp regs */
unsigned int fp_reg_size; /* # bytes needed to store fp regs */ int fp_reg_size; /* # bytes needed to store fp regs */
unsigned long mask; /* mask of saved gp registers */ long mask; /* mask of saved gp registers */
unsigned long fmask; /* mask of saved fp registers */ long fmask; /* mask of saved fp registers */
long gp_save_offset; /* offset from vfp to store gp registers */ long gp_save_offset; /* offset from vfp to store gp registers */
long fp_save_offset; /* offset from vfp to store fp registers */ long fp_save_offset; /* offset from vfp to store fp registers */
unsigned long gp_sp_offset; /* offset from new sp to store gp registers */ long gp_sp_offset; /* offset from new sp to store gp registers */
unsigned long fp_sp_offset; /* offset from new sp to store fp registers */ long fp_sp_offset; /* offset from new sp to store fp registers */
int initialized; /* != 0 if frame size already calculated */ int initialized; /* != 0 if frame size already calculated */
int num_gp; /* number of gp registers saved */ int num_gp; /* number of gp registers saved */
int num_fp; /* number of fp registers saved */ int num_fp; /* number of fp registers saved */
}; };
extern struct mips_frame_info current_frame_info; extern struct mips_frame_info current_frame_info;
...@@ -1896,9 +1898,7 @@ typedef struct mips_args { ...@@ -1896,9 +1898,7 @@ typedef struct mips_args {
#define ELIGIBLE_FOR_EPILOGUE_DELAY(INSN,N) \ #define ELIGIBLE_FOR_EPILOGUE_DELAY(INSN,N) \
(get_attr_dslot (INSN) == DSLOT_NO \ (get_attr_dslot (INSN) == DSLOT_NO \
&& get_attr_length (INSN) == 1 \ && get_attr_length (INSN) == 1 \
&& ! reg_mentioned_p (stack_pointer_rtx, PATTERN (INSN)) \ && ! epilogue_reg_mentioned_p (PATTERN (INSN)))
&& ! reg_mentioned_p (frame_pointer_rtx, PATTERN (INSN)) \
&& ! reg_mentioned_p (arg_pointer_rtx, PATTERN (INSN)))
/* Tell prologue and epilogue if register REGNO should be saved / restored. */ /* Tell prologue and epilogue if register REGNO should be saved / restored. */
......
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