Commit a3404926 by Richard Stallman

(clipper_frame_size): New function.

(output_function_pro/epilogue): Support omitting frame pointer.

From-SVN: r4181
parent 9257a149
...@@ -38,28 +38,24 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ ...@@ -38,28 +38,24 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
extern char regs_ever_live[]; extern char regs_ever_live[];
#ifdef ACCUMULATE_OUTGOING_ARGS extern int frame_pointer_needed;
extern int current_function_outgoing_args_size;
#endif
static int save_reg_offset; static int frame_size;
/* /*
* prologue and epilogue output * compute size of a clipper stack frame where 'lsize' is the required
* function is entered with pc pushed, i.e. stack is 32 bit alligned * space for local variables.
*
*/ */
void
output_function_prologue (file, lsize) int
FILE *file; clipper_frame_size (lsize)
int lsize; /* size for locals */ int lsize;
{ {
int i, offset; int i,size; /* total size of frame */
int save_size; int save_size;
int size; /* total size of frame */
save_size = 0; /* compute size for reg saves */ save_size = 0; /* compute size for reg saves */
for (i = 17; i < 32; i++)
for (i = 16; i < 32; i++)
if (regs_ever_live[i] && !call_used_regs[i]) if (regs_ever_live[i] && !call_used_regs[i])
save_size += 8; save_size += 8;
...@@ -67,49 +63,75 @@ output_function_prologue (file, lsize) ...@@ -67,49 +63,75 @@ output_function_prologue (file, lsize)
if (regs_ever_live[i] && !call_used_regs[i]) if (regs_ever_live[i] && !call_used_regs[i])
save_size += 4; save_size += 4;
save_reg_offset = lsize + save_size; size = lsize + save_size;
save_reg_offset = (save_reg_offset + 7) & ~7; /* align to 64 Bit */
#ifdef ACCUMULATE_OUTGOING_ARGS
size = save_reg_offset + current_function_outgoing_args_size;
#else
size = save_reg_offset;
#endif
size = (size + 7) & ~7; /* align to 64 Bit */ size = (size + 7) & ~7; /* align to 64 Bit */
return size;
}
/*
* prologue and epilogue output
* function is entered with pc pushed, i.e. stack is 32 bit aligned
*
* current_function_args_size == 0 means that the current function's args
* are passed totally in registers i.e fp is not used as ap.
* If frame_size is also 0 the current function does not push anything and
* can run with misaligned stack -> subq $4,sp / add $4,sp on entry and exit
* can be omitted.
*
*/
void
output_function_prologue (file, lsize)
FILE *file;
int lsize; /* size for locals */
{
int i, offset;
int size;
frame_size = size = clipper_frame_size (lsize);
if (size == 0) if (frame_pointer_needed)
{ {
fputs ("\tpushw fp,sp\n", file); fputs ("\tpushw fp,sp\n", file);
fputs ("\tmovw sp,fp\n", file); fputs ("\tmovw sp,fp\n", file);
} }
else else if (size != 0 || current_function_args_size != 0)
{
size += 4; /* keep stack aligned */
frame_size = size; /* must push data or access args */
}
if (size)
{ {
if (size < 16) if (size < 16)
fprintf (file, "\tsubq $%d,sp\n", size + 4); /* room for fp */ fprintf (file, "\tsubq $%d,sp\n", size);
else else
fprintf (file, "\tsubi $%d,sp\n", size + 4); fprintf (file, "\tsubi $%d,sp\n", size);
fprintf (file, "\tstorw fp,%d(sp)\n", size); /* register save slots are relative to sp, because we have small positive
fprintf (file, "\tloada %d(sp),fp\n", size); displacements and this works whether we have a frame pointer or not */
offset = 0;
for (i = 16; i < 32; i++)
if (regs_ever_live[i] && !call_used_regs[i])
{
if (offset == 0)
fprintf (file, "\tstord f%d,(sp)\n", i-16);
else
fprintf (file, "\tstord f%d,%d(sp)\n", i-16, offset);
offset += 8;
}
for (i = 0; i < 16; i++)
if (regs_ever_live[i] && !call_used_regs[i])
{
if (offset == 0)
fprintf (file, "\tstorw r%d,(sp)\n", i);
else
fprintf (file, "\tstorw r%d,%d(sp)\n", i, offset);
offset += 4;
}
} }
offset = -save_reg_offset;
for (i = 16; i < 32; i++)
if (regs_ever_live[i] && !call_used_regs[i])
{
fprintf (file, "\tstord f%d,%d(fp)\n", i-16, offset);
offset += 8;
}
for (i = 0; i < 16; i++)
if (regs_ever_live[i] && !call_used_regs[i])
{
fprintf (file, "\tstorw r%d,%d(fp)\n", i, offset);
offset += 4;
}
} }
void void
...@@ -119,24 +141,62 @@ output_function_epilogue (file, size) ...@@ -119,24 +141,62 @@ output_function_epilogue (file, size)
{ {
int i, offset; int i, offset;
offset = -save_reg_offset; if (frame_pointer_needed)
{
for (i = 16; i < 32; i++) offset = -frame_size;
if (regs_ever_live[i] && !call_used_regs[i])
{ for (i = 16; i < 32; i++)
fprintf (file, "\tloadd %d(fp),f%d\n", offset, i-16); if (regs_ever_live[i] && !call_used_regs[i])
offset += 8; {
} fprintf (file, "\tloadd %d(fp),f%d\n", offset, i-16);
offset += 8;
}
for (i = 0; i < 16; i++)
if (regs_ever_live[i] && !call_used_regs[i])
{
fprintf (file, "\tloadw %d(fp),r%d\n", offset, i);
offset += 4;
}
fputs ("\tmovw fp,sp\n\tpopw sp,fp\n\tret sp\n",
file);
}
for (i = 0; i < 16; i++) else /* no frame pointer */
if (regs_ever_live[i] && !call_used_regs[i]) {
{ offset = 0;
fprintf (file, "\tloadw %d(fp),r%d\n", offset, i);
offset += 4; for (i = 16; i < 32; i++)
} if (regs_ever_live[i] && !call_used_regs[i])
{
if (offset == 0)
fprintf (file, "\tloadd (sp),f%d\n", i-16);
else
fprintf (file, "\tloadd %d(sp),f%d\n", offset, i-16);
offset += 8;
}
for (i = 0; i < 16; i++)
if (regs_ever_live[i] && !call_used_regs[i])
{
if (offset == 0)
fprintf (file, "\tloadw (sp),r%d\n", i);
else
fprintf (file, "\tloadw %d(sp),r%d\n", offset, i);
offset += 4;
}
if (frame_size > 0)
{
if (frame_size < 16)
fprintf (file, "\taddq $%d,sp\n", frame_size);
else
fprintf (file, "\taddi $%d,sp\n", frame_size);
}
fputs ("\tmovw fp,sp\n\tpopw sp,fp\n\tret sp\n", fputs ("\tret sp\n", file);
file); }
} }
/* /*
......
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