Change MIPS fp to be at top of stack, instead of bottom; Fix calling mips-tfile with wrong .o file

From-SVN: r1941
This commit is contained in:
Michael Meissner 1992-08-25 17:39:37 +00:00
parent 8436fe3532
commit ab78d4a881
3 changed files with 145 additions and 76 deletions

View File

@ -107,10 +107,6 @@ int mips_section_threshold = -1;
/* Count the number of .file directives, so that .loc is up to date. */
int num_source_filenames = 0;
/* Count of the number of functions created so far, in order to make
unique labels for omitting the frame pointer. */
int number_functions_processed = 0;
/* Count the number of sdb related labels are generated (to find block
start and end boundaries). */
int sdb_label_count = 0;
@ -3085,11 +3081,14 @@ override_options ()
/*
* If the frame pointer has been eliminated, the offset for an auto
* or argument will be based on the stack pointer. But this is not
* what the debugger expects--it needs to find an offset off of the
* frame pointer (whether it exists or not). So here we turn all
* offsets into those based on the (possibly virtual) frame pointer.
* The MIPS debug format wants all automatic variables and arguments
* to be in terms of the virtual frame pointer (stack pointer before
* any adjustment in the function), while the MIPS 3.0 linker wants
* the frame pointer to be the stack pointer after the initial
* adjustment. So, we do the adjustment here. The arg pointer (which
* is eliminated) points to the virtual frame pointer, while the frame
* pointer (which may be eliminated) points to the stack pointer after
* the initial adjustments.
*/
int
@ -3103,7 +3102,7 @@ mips_debugger_offset (addr, offset)
if (!offset)
offset = INTVAL (offset2);
if (reg == stack_pointer_rtx)
if (reg == stack_pointer_rtx || reg == frame_pointer_rtx)
{
int frame_size = (!current_frame_info.initialized)
? compute_frame_size (get_frame_size ())
@ -3111,13 +3110,8 @@ mips_debugger_offset (addr, offset)
offset = offset - frame_size;
}
/* Any other register is, we hope, either the frame pointer,
or a pseudo equivalent to the frame pointer. (Assign_parms
copies the arg pointer to a pseudo if ARG_POINTER_REGNUM is
equal to FRAME_POINTER_REGNUM, so references off of the
arg pointer are all off a pseudo.) Seems like all we can
do is to just return OFFSET and hope for the best. */
else if (reg != arg_pointer_rtx)
abort_with_insn (addr, "mips_debugger_offset called with non stack/frame/arg pointer.");
return offset;
}
@ -3415,6 +3409,9 @@ print_operand_address (file, addr)
break;
case REG:
if (REGNO (addr) == ARG_POINTER_REGNUM)
abort_with_insn (addr, "Arg pointer not eliminated.");
fprintf (file, "0(%s)", reg_names [REGNO (addr)]);
break;
@ -3448,6 +3445,9 @@ print_operand_address (file, addr)
if (!CONSTANT_P (offset))
abort_with_insn (addr, "PRINT_OPERAND_ADDRESS, illegal insn #2");
if (REGNO (reg) == ARG_POINTER_REGNUM)
abort_with_insn (addr, "Arg pointer not eliminated.");
output_addr_const (file, offset);
fprintf (file, "(%s)", reg_names [REGNO (reg)]);
}
@ -3861,10 +3861,6 @@ mips_output_float (stream, value)
| GP save for V.4 abi |
| |
+-----------------------+
| |
| local variables |
| |
+-----------------------+
| |
| fp register save |
| |
@ -3874,6 +3870,10 @@ mips_output_float (stream, value)
| |
+-----------------------+
| |
| local variables |
| |
+-----------------------+
| |
| alloca allocations |
| |
+-----------------------+
@ -3906,16 +3906,23 @@ compute_frame_size (size)
int fp_inc; /* 1 or 2 depending on the size of fp regs */
int fp_bits; /* bitmask to use for each fp register */
extra_size = MIPS_STACK_ALIGN (((TARGET_ABICALLS) ? UNITS_PER_WORD : 0)
-STARTING_FRAME_OFFSET);
var_size = MIPS_STACK_ALIGN (size);
args_size = MIPS_STACK_ALIGN (current_function_outgoing_args_size);
total_size = var_size + args_size + extra_size;
gp_reg_size = 0;
fp_reg_size = 0;
mask = 0;
fmask = 0;
extra_size = MIPS_STACK_ALIGN (((TARGET_ABICALLS) ? UNITS_PER_WORD : 0));
var_size = MIPS_STACK_ALIGN (size);
args_size = MIPS_STACK_ALIGN (current_function_outgoing_args_size);
/* The MIPS 3.0 linker does not like functions that dynamically
allocate the stack and have 0 for STACK_DYNAMIC_OFFSET, since it
looks like we are trying to create a second frame pointer to the
function, so allocate some stack space to make it happy. */
if (args_size == 0 && current_function_calls_alloca)
args_size = 4*UNITS_PER_WORD;
total_size = var_size + args_size + extra_size;
/* Calculate space needed for gp registers. */
for (regno = GP_REG_FIRST; regno <= GP_REG_LAST; regno++)
@ -3969,14 +3976,14 @@ compute_frame_size (size)
if (mask)
{
unsigned long offset = args_size + gp_reg_size - UNITS_PER_WORD;
unsigned long offset = args_size + var_size + gp_reg_size - UNITS_PER_WORD;
current_frame_info.gp_sp_offset = offset;
current_frame_info.gp_save_offset = offset - total_size;
}
if (fmask)
{
unsigned long offset = args_size + gp_reg_rounded + fp_reg_size - 2*UNITS_PER_WORD;
unsigned long offset = args_size + var_size + gp_reg_rounded + fp_reg_size - 2*UNITS_PER_WORD;
current_frame_info.fp_sp_offset = offset;
current_frame_info.fp_save_offset = offset - total_size + UNITS_PER_WORD;
}
@ -4152,8 +4159,6 @@ function_prologue (file, size)
int size;
{
int tsize = current_frame_info.total_size;
int vframe;
int vreg;
ASM_OUTPUT_SOURCE_FILENAME (file, DECL_SOURCE_FILE (current_function_decl));
ASM_OUTPUT_SOURCE_LINE (file, DECL_SOURCE_LINE (current_function_decl));
@ -4174,20 +4179,9 @@ function_prologue (file, size)
if (tsize > 0 && TARGET_ABICALLS)
fprintf (file, "\t.cprestore %d\n", tsize + STARTING_FRAME_OFFSET);
if (frame_pointer_needed)
{
vframe = 0;
vreg = FRAME_POINTER_REGNUM;
}
else
{
vframe = tsize;
vreg = STACK_POINTER_REGNUM;
}
fprintf (file, "\t.frame\t%s,%d,%s\t\t# vars= %d, regs= %d/%d, args = %d, extra= %d\n",
reg_names[ vreg ],
vframe,
reg_names[ (frame_pointer_needed) ? FRAME_POINTER_REGNUM : STACK_POINTER_REGNUM ],
tsize,
reg_names[31 + GP_REG_FIRST],
current_frame_info.var_size,
current_frame_info.num_gp,
@ -4209,7 +4203,6 @@ void
mips_expand_prologue ()
{
int regno;
int size;
int tsize;
tree fndecl = current_function_decl; /* current... is tooo long */
tree fntype = TREE_TYPE (fndecl);
@ -4291,9 +4284,7 @@ mips_expand_prologue ()
}
}
size = MIPS_STACK_ALIGN (get_frame_size ());
tsize = compute_frame_size (size);
tsize = compute_frame_size (get_frame_size ());
if (tsize > 0)
{
rtx tsize_rtx = GEN_INT (tsize);
@ -4310,7 +4301,7 @@ mips_expand_prologue ()
save_restore_insns (TRUE);
if (frame_pointer_needed)
emit_insn (gen_addsi3 (frame_pointer_rtx, stack_pointer_rtx, tsize_rtx));
emit_insn (gen_movsi (frame_pointer_rtx, stack_pointer_rtx));
}
}
@ -4413,15 +4404,8 @@ function_epilogue (file, size)
fprintf (file, "\tli\t%s,%d\n", t1_str, tsize);
if (frame_pointer_needed)
{
char *fp_str = reg_names[FRAME_POINTER_REGNUM];
if (tsize > 32767)
fprintf (file,"\tsubu\t%s,%s,%s\t\t# sp not trusted here\n",
sp_str, fp_str, t1_str);
else
fprintf (file,"\tsubu\t%s,%s,%d\t\t# sp not trusted here\n",
sp_str, fp_str, tsize);
}
fprintf (file, "\tmove\t%s,%s\t\t\t# sp not trusted here\n",
sp_str, reg_names[FRAME_POINTER_REGNUM]);
save_restore (file, "lw", "ld", "l.d");
@ -4489,6 +4473,10 @@ function_epilogue (file, size)
int num_gp_regs = current_frame_info.gp_reg_size / 4;
int num_fp_regs = current_frame_info.fp_reg_size / 8;
int num_regs = num_gp_regs + num_fp_regs;
char *name = current_function_name;
if (name[0] == '*')
name++;
dslots_load_total += num_regs;
@ -4511,7 +4499,7 @@ function_epilogue (file, size)
fprintf (stderr,
"%-20s fp=%c leaf=%c alloca=%c setjmp=%c stack=%4ld arg=%3ld reg=%2d/%d delay=%3d/%3dL %3d/%3dJ refs=%3d/%3d/%3d",
current_function_name,
name,
(frame_pointer_needed) ? 'y' : 'n',
((current_frame_info.mask & (1 << 31)) != 0) ? 'n' : 'y',
(current_function_calls_alloca) ? 'y' : 'n',
@ -4545,7 +4533,6 @@ function_epilogue (file, size)
mips_load_reg = (rtx)0;
mips_load_reg2 = (rtx)0;
current_frame_info = zero_frame_info;
number_functions_processed++;
/* Restore the output file if optimizing the GP (optimizing the GP causes
the text to be diverted to a tempfile, so that data decls come before
@ -4574,7 +4561,7 @@ mips_expand_epilogue ()
if (tsize > 0)
{
if (frame_pointer_needed)
emit_insn (gen_subsi3 (stack_pointer_rtx, frame_pointer_rtx, tsize_rtx));
emit_insn (gen_movsi (stack_pointer_rtx, frame_pointer_rtx));
save_restore_insns (FALSE);

View File

@ -402,7 +402,7 @@ while (0)
\n mips-tfile %{v*: -v} \
%{K: -I %b.o~} \
%{!K: %{save-temps: -I %b.o~}} \
%{c:%W{o*}%{!o*:-o %b.o}}%{!c:-o %u.o} \
%{c:%W{o*}%{!o*:-o %b.o}}%{!c:-o %U.o} \
%{.s:%i} %{!.s:%g.s}}}"
#endif
@ -473,7 +473,7 @@ while (0)
/* Print subsidiary information on the compiler version in use. */
#define MIPS_VERSION "[AL 1.1, MM 23]"
#define MIPS_VERSION "[AL 1.1, MM 24]"
#ifndef MACHINE_TYPE
#define MACHINE_TYPE "BSD Mips"
@ -651,8 +651,12 @@ do { \
#define SDB_GENERATE_FAKE(BUFFER, NUMBER) \
sprintf ((BUFFER), ".%dfake", (NUMBER));
/* Correct the offset of automatic variables and arguments
if the frame pointer has been eliminated. */
/* Correct the offset of automatic variables and arguments. Note that
the MIPS debug format wants all automatic variables and arguments
to be in terms of the virtual frame pointer (stack pointer before
any adjustment in the function), while the MIPS 3.0 linker wants
the frame pointer to be the stack pointer after the initial
adjustment. */
#define DEBUGGER_AUTO_OFFSET(X) mips_debugger_offset (X, 0)
#define DEBUGGER_ARG_OFFSET(OFFSET, X) mips_debugger_offset (X, OFFSET)
@ -1196,7 +1200,7 @@ extern char mips_hard_regno_mode_ok[][FIRST_PSEUDO_REGISTER];
#define FRAME_POINTER_REQUIRED (current_function_calls_alloca)
/* Base register for access to arguments of the function. */
#define ARG_POINTER_REGNUM FRAME_POINTER_REGNUM
#define ARG_POINTER_REGNUM GP_REG_FIRST
/* Register in which static-chain is passed to a function. */
#define STATIC_CHAIN_REGNUM (GP_REG_FIRST + 2)
@ -1485,13 +1489,30 @@ extern enum reg_class mips_char_to_class[];
is at the high-address end of the local variables;
that is, each additional local variable allocated
goes at a more negative offset in the frame. */
#define FRAME_GROWS_DOWNWARD
/* #define FRAME_GROWS_DOWNWARD */
/* Offset within stack frame to start allocating local variables at.
If FRAME_GROWS_DOWNWARD, this is the offset to the END of the
first local allocated. Otherwise, it is the offset to the BEGINNING
of the first local allocated. */
#define STARTING_FRAME_OFFSET (-8)
#define STARTING_FRAME_OFFSET current_function_outgoing_args_size
/* Offset from the stack pointer register to an item dynamically
allocated on the stack, e.g., by `alloca'.
The default value for this macro is `STACK_POINTER_OFFSET' plus the
length of the outgoing arguments. The default is correct for most
machines. See `function.c' for details.
The MIPS 3.0 linker does not like functions that dynamically
allocate the stack and have 0 for STACK_DYNAMIC_OFFSET, since it
looks like we are trying to create a second frame pointer to the
function, so allocate some stack space to make it happy. */
#define STACK_DYNAMIC_OFFSET(FUNDECL) \
((current_function_outgoing_args_size == 0 && current_function_calls_alloca) \
? 4*UNITS_PER_WORD \
: current_function_outgoing_args_size)
/* Structure to be filled in by compute_frame_size with register
save masks, and offsets for the current function. */
@ -1522,8 +1543,69 @@ extern struct mips_frame_info current_frame_info;
as of the start of the function body. This depends on the layout
of the fixed parts of the stack frame and on how registers are saved. */
#define INITIAL_FRAME_POINTER_OFFSET(VAR) \
((VAR) = compute_frame_size (get_frame_size ()))
/* #define INITIAL_FRAME_POINTER_OFFSET(VAR) \
((VAR) = compute_frame_size (get_frame_size ())) */
/* If defined, this macro specifies a table of register pairs used to
eliminate unneeded registers that point into the stack frame. If
it is not defined, the only elimination attempted by the compiler
is to replace references to the frame pointer with references to
the stack pointer.
The definition of this macro is a list of structure
initializations, each of which specifies an original and
replacement register.
On some machines, the position of the argument pointer is not
known until the compilation is completed. In such a case, a
separate hard register must be used for the argument pointer.
This register can be eliminated by replacing it with either the
frame pointer or the argument pointer, depending on whether or not
the frame pointer has been eliminated.
In this case, you might specify:
#define ELIMINABLE_REGS \
{{ARG_POINTER_REGNUM, STACK_POINTER_REGNUM}, \
{ARG_POINTER_REGNUM, FRAME_POINTER_REGNUM}, \
{FRAME_POINTER_REGNUM, STACK_POINTER_REGNUM}}
Note that the elimination of the argument pointer with the stack
pointer is specified first since that is the preferred elimination. */
#define ELIMINABLE_REGS \
{{ ARG_POINTER_REGNUM, STACK_POINTER_REGNUM}, \
{ ARG_POINTER_REGNUM, FRAME_POINTER_REGNUM}, \
{ FRAME_POINTER_REGNUM, STACK_POINTER_REGNUM}}
/* A C expression that returns non-zero if the compiler is allowed to
try to replace register number FROM-REG with register number
TO-REG. This macro need only be defined if `ELIMINABLE_REGS' is
defined, and will usually be the constant 1, since most of the
cases preventing register elimination are things that the compiler
already knows about. */
#define CAN_ELIMINATE(FROM, TO) \
(!frame_pointer_needed \
|| ((FROM) == ARG_POINTER_REGNUM && (TO) == FRAME_POINTER_REGNUM))
/* This macro is similar to `INITIAL_FRAME_POINTER_OFFSET'. It
specifies the initial difference between the specified pair of
registers. This macro must be defined if `ELIMINABLE_REGS' is
defined. */
#define INITIAL_ELIMINATION_OFFSET(FROM, TO, OFFSET) \
{ compute_frame_size (get_frame_size ()); \
if ((FROM) == FRAME_POINTER_REGNUM && (TO) == STACK_POINTER_REGNUM) \
(OFFSET) = 0; \
else if ((FROM) == ARG_POINTER_REGNUM && (TO) == FRAME_POINTER_REGNUM) \
(OFFSET) = current_frame_info.total_size; \
else if ((FROM) == ARG_POINTER_REGNUM && (TO) == STACK_POINTER_REGNUM) \
(OFFSET) = current_frame_info.total_size; \
else \
abort (); \
}
/* If we generate an insn to push BYTES bytes,
this says how many the stack pointer really advances by.
@ -1780,18 +1862,19 @@ typedef struct mips_args {
(get_attr_dslot (INSN) == DSLOT_NO \
&& get_attr_length (INSN) == 1 \
&& ! reg_mentioned_p (stack_pointer_rtx, PATTERN (INSN)) \
&& ! reg_mentioned_p (frame_pointer_rtx, 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. */
#define MUST_SAVE_REGISTER(regno) \
((regs_ever_live[regno] && !call_used_regs[regno]) \
|| (regno == FRAME_POINTER_REGNUM && frame_pointer_needed) \
|| (regno == 31 && regs_ever_live[31]))
|| (regno == (GP_REG_FIRST + 31) && regs_ever_live[GP_REG_FIRST + 31]))
/* ALIGN FRAMES on double word boundaries */
#define MIPS_STACK_ALIGN(LOC) (((LOC)+7) & 0xfffffff8)
#define MIPS_STACK_ALIGN(LOC) (((LOC)+7) & ~7)
/* Output assembler code to FILE to increment profiler label # LABELNO
@ -2918,8 +3001,7 @@ while (0)
$Lb[0-9]+ Begin blocks for MIPS debug support
$Lc[0-9]+ Label for use in s<xx> operation.
$Le[0-9]+ End blocks for MIPS debug support
$Lp\..+ Half-pic labels.
$Ls[0-9]+ FP-SP difference if -fomit-frame-pointer */
$Lp\..+ Half-pic labels. */
/* This is how to output the definition of a user-level label named NAME,
such as the label on a static function or variable NAME.

View File

@ -45,7 +45,7 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
\n mips-tfile %{v*: -v} %{d*} \
%{K: -I %b.o~} \
%{!K: %{save-temps: -I %b.o~}} \
%{c:%W{o*}%{!o*:-o %b.o}}%{!c:-o %u.o} \
%{c:%W{o*}%{!o*:-o %b.o}}%{!c:-o %U.o} \
%{.s:%i} %{!.s:%g.s}}}"
#define CPP_SPEC "\