From: Richard Stallman Date: Sun, 18 Apr 1993 04:41:54 +0000 (+0000) Subject: (clipper_frame_size): New function. X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=a3404926b09df8cc0da6e98ff27691f527c24851;p=gcc.git (clipper_frame_size): New function. (output_function_pro/epilogue): Support omitting frame pointer. From-SVN: r4181 --- diff --git a/gcc/config/clipper/clipper.c b/gcc/config/clipper/clipper.c index e40c7871c0a..dcb7d57768f 100644 --- a/gcc/config/clipper/clipper.c +++ b/gcc/config/clipper/clipper.c @@ -38,28 +38,24 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ extern char regs_ever_live[]; -#ifdef ACCUMULATE_OUTGOING_ARGS -extern int current_function_outgoing_args_size; -#endif +extern int frame_pointer_needed; -static int save_reg_offset; +static int frame_size; /* - * prologue and epilogue output - * function is entered with pc pushed, i.e. stack is 32 bit alligned - * + * compute size of a clipper stack frame where 'lsize' is the required + * space for local variables. */ -void -output_function_prologue (file, lsize) - FILE *file; - int lsize; /* size for locals */ + +int +clipper_frame_size (lsize) + int lsize; { - int i, offset; + int i,size; /* total size of frame */ int save_size; - int size; /* total size of frame */ - 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]) save_size += 8; @@ -67,49 +63,75 @@ output_function_prologue (file, lsize) if (regs_ever_live[i] && !call_used_regs[i]) save_size += 4; - save_reg_offset = lsize + save_size; - - save_reg_offset = (save_reg_offset + 7) & ~7; /* align to 64 Bit */ + size = lsize + save_size; -#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 */ + 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 ("\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) - fprintf (file, "\tsubq $%d,sp\n", size + 4); /* room for fp */ + fprintf (file, "\tsubq $%d,sp\n", size); else - fprintf (file, "\tsubi $%d,sp\n", size + 4); - - fprintf (file, "\tstorw fp,%d(sp)\n", size); - fprintf (file, "\tloada %d(sp),fp\n", size); + fprintf (file, "\tsubi $%d,sp\n", size); + + /* register save slots are relative to sp, because we have small positive + 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 @@ -119,24 +141,62 @@ output_function_epilogue (file, size) { int i, offset; - offset = -save_reg_offset; - - for (i = 16; i < 32; i++) - if (regs_ever_live[i] && !call_used_regs[i]) - { - fprintf (file, "\tloadd %d(fp),f%d\n", offset, i-16); - offset += 8; - } + if (frame_pointer_needed) + { + offset = -frame_size; + + for (i = 16; i < 32; i++) + if (regs_ever_live[i] && !call_used_regs[i]) + { + 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++) - if (regs_ever_live[i] && !call_used_regs[i]) - { - fprintf (file, "\tloadw %d(fp),r%d\n", offset, i); - offset += 4; - } + else /* no frame pointer */ + { + offset = 0; + + 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", - file); + fputs ("\tret sp\n", file); + } } /*