aboutsummaryrefslogtreecommitdiff
path: root/gcc/config
diff options
context:
space:
mode:
authorRichard Stallman <rms@gnu.org>1992-06-06 21:38:47 +0000
committerRichard Stallman <rms@gnu.org>1992-06-06 21:38:47 +0000
commite241407e6a487d1f55cfc76d7e729c6b6334226d (patch)
tree75c859c169ea3e6b7bbfff0e2153a64d0cba08f7 /gcc/config
parentc34122d0fe0b65ef6387088d73f1f0f901dcd987 (diff)
downloadgcc-e241407e6a487d1f55cfc76d7e729c6b6334226d.zip
gcc-e241407e6a487d1f55cfc76d7e729c6b6334226d.tar.gz
gcc-e241407e6a487d1f55cfc76d7e729c6b6334226d.tar.bz2
entered into RCS
From-SVN: r1175
Diffstat (limited to 'gcc/config')
-rw-r--r--gcc/config/i860/fx2800.h5
-rw-r--r--gcc/config/i860/i860.c93
2 files changed, 93 insertions, 5 deletions
diff --git a/gcc/config/i860/fx2800.h b/gcc/config/i860/fx2800.h
index fc71303..f69ef4f 100644
--- a/gcc/config/i860/fx2800.h
+++ b/gcc/config/i860/fx2800.h
@@ -21,6 +21,8 @@ You should have received a copy of the GNU General Public License
along with GNU CC; see the file COPYING. If not, write to
the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
+#define OUTPUT_TDESC
+
#include "i860v4.h"
/* The Alliant fx2800 running Concentrix 2.x is weird. This is basically
@@ -279,6 +281,9 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
#undef ASM_FILE_START
#define ASM_FILE_START(FILE)
#undef ASM_OUTPUT_FUNCTION_PREFIX
+#define ASM_OUTPUT_FUNCTION_PREFIX(FILE,NAME) \
+ fputs("\tnop\n", (FILE)); \
+ current_function_original_name = (NAME)
#undef ASM_OUTPUT_PROLOGUE_SUFFIX
/* Overrides for svr4.h begin here */
diff --git a/gcc/config/i860/i860.c b/gcc/config/i860/i860.c
index f4ecdb2..5fcf7a2 100644
--- a/gcc/config/i860/i860.c
+++ b/gcc/config/i860/i860.c
@@ -2039,15 +2039,49 @@ function_prologue (asm_file, local_bytes)
instruction, so what the hell.
*/
+/* This corresponds to a version 4 TDESC structure. Lower numbered
+ versions successively omit the last word of the structure. We
+ don't try to handle version 5 here. */
+
+typedef struct TDESC_flags {
+ int version:4;
+ int reg_packing:1;
+ int callable_block:1;
+ int reserved:4;
+ int fregs:6; /* fp regs 2-7 */
+ int iregs:16; /* regs 0-15 */
+} TDESC_flags;
+
+typedef struct TDESC {
+ TDESC_flags flags;
+ int integer_reg_offset; /* same as must_preserve_bytes */
+ int floating_point_reg_offset;
+ unsigned int positive_frame_size; /* same as frame_upper_bytes */
+ unsigned int negative_frame_size; /* same as frame_lower_bytes */
+} TDESC;
+
void
function_epilogue (asm_file, local_bytes)
register FILE *asm_file;
register unsigned local_bytes;
{
register unsigned frame_upper_bytes;
+ register unsigned frame_lower_bytes;
register unsigned preserved_reg_bytes = 0;
register unsigned i;
register unsigned restored_so_far = 0;
+ register unsigned int_restored;
+ register unsigned mask;
+ unsigned intflags=0;
+ register TDESC_flags *flags = (TDESC_flags *) &intflags;
+
+ flags->version = 4;
+ flags->reg_packing = 1;
+ flags->iregs = 8; /* old fp always gets saved */
+
+ /* Round-up the frame_lower_bytes so that it's a multiple of 16. */
+
+ frame_lower_bytes = (local_bytes + STACK_ALIGNMENT - 1) & -STACK_ALIGNMENT;
/* Count the number of registers that were preserved in the prologue.
Ignore r0. It is never preserved. */
@@ -2071,17 +2105,31 @@ function_epilogue (asm_file, local_bytes)
/* Restore all of the "preserved" registers that need restoring. */
- for (i = 1; i < 32; i++)
- if (regs_ever_live[i] && ! call_used_regs[i])
+ mask = 2;
+
+ for (i = 1; i < 32; i++, mask<<=1)
+ if (regs_ever_live[i] && ! call_used_regs[i]) {
fprintf (asm_file, "\tld.l %d(%sfp),%s%s\n",
must_preserve_bytes + (4 * restored_so_far++),
i860_reg_prefix, i860_reg_prefix, reg_names[i]);
+ if (i > 3 && i < 16)
+ flags->iregs |= mask;
+ }
+
+ int_restored = restored_so_far;
+ mask = 1;
- for (i = 32; i < 64; i++)
- if (regs_ever_live[i] && ! call_used_regs[i])
+ for (i = 32; i < 64; i++) {
+ if (regs_ever_live[i] && ! call_used_regs[i]) {
fprintf (asm_file, "\tfld.l %d(%sfp),%s%s\n",
must_preserve_bytes + (4 * restored_so_far++),
i860_reg_prefix, i860_reg_prefix, reg_names[i]);
+ if (i > 33 & i < 40)
+ flags->fregs |= mask;
+ }
+ if (i > 33 && i < 40)
+ mask<<=1;
+ }
/* Get the value we plan to use to restore the stack pointer into r31. */
@@ -2090,9 +2138,11 @@ function_epilogue (asm_file, local_bytes)
/* Restore the return address and the old frame pointer. */
- if (must_preserve_r1)
+ if (must_preserve_r1) {
fprintf (asm_file, "\tld.l 4(%sfp),%sr1\n",
i860_reg_prefix, i860_reg_prefix);
+ flags->iregs |= 2;
+ }
fprintf (asm_file, "\tld.l 0(%sfp),%sfp\n",
i860_reg_prefix, i860_reg_prefix);
@@ -2101,4 +2151,37 @@ function_epilogue (asm_file, local_bytes)
fprintf (asm_file, "\tbri %sr1\n\tmov %sr31,%ssp\n",
i860_reg_prefix, i860_reg_prefix, i860_reg_prefix);
+
+#ifdef OUTPUT_TDESC /* Output an ABI-compliant TDESC entry */
+ if (! frame_lower_bytes) {
+ flags->version--;
+ if (! frame_upper_bytes) {
+ flags->version--;
+ if (restored_so_far == int_restored) /* No FP saves */
+ flags->version--;
+ }
+ }
+ assemble_name(asm_file,current_function_original_name);
+ fputs(".TDESC:\n", asm_file);
+ fprintf(asm_file, "%s 0x%0x\n", ASM_LONG, intflags);
+ fprintf(asm_file, "%s %d\n", ASM_LONG,
+ int_restored ? must_preserve_bytes : 0);
+ if (flags->version > 1) {
+ fprintf(asm_file, "%s %d\n", ASM_LONG,
+ (restored_so_far == int_restored) ? 0 : must_preserve_bytes +
+ (4 * int_restored));
+ if (flags->version > 2) {
+ fprintf(asm_file, "%s %d\n", ASM_LONG, frame_upper_bytes);
+ if (flags->version > 3)
+ fprintf(asm_file, "%s %d\n", ASM_LONG, frame_lower_bytes);
+ }
+ }
+ tdesc_section();
+ fprintf(asm_file, "%s ", ASM_LONG);
+ assemble_name(asm_file, current_function_original_name);
+ fprintf(asm_file, "\n%s ", ASM_LONG);
+ assemble_name(asm_file, current_function_original_name);
+ fputs(".TDESC\n", asm_file);
+ text_section();
+#endif
}