aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJames E. Wilson <wilson@cygnus.com>2000-06-08 17:15:32 +0000
committerJim Wilson <wilson@gcc.gnu.org>2000-06-08 10:15:32 -0700
commit0186257f7898165091cde0d6e6f307862966fa2a (patch)
tree9b846030fa205e5d39712e49ce20756c808b7861
parent6223e158fded51fafae924863a81262b86d9edef (diff)
downloadgcc-0186257f7898165091cde0d6e6f307862966fa2a.zip
gcc-0186257f7898165091cde0d6e6f307862966fa2a.tar.gz
gcc-0186257f7898165091cde0d6e6f307862966fa2a.tar.bz2
Add unwind support for epilogues, because the kernel unwinder needs them.
* config/ia64/ia64-protos.h (ia64_output_end_prologue): Add. (output_function_prologue): Fix mispelling. (output_function_prologue, output_function_epilogue): Reorder to match ia64.c definition order. * config/ia64/ia64.c (ia64_expand_prologue): Add comment. (ia64_expand_epilogue): Set RTX_FRAME_RELATED_P on stack restore insns. Use r3 instead of r2 for large stack restores. (ia64_output_end_prologue): New function. (process_set): Emit ".restore sp" for epilogue stack restores. * config/ia64/ia64.h (FUNCTION_END_PROLOGUE): Define. From-SVN: r34456
-rw-r--r--gcc/ChangeLog13
-rw-r--r--gcc/config/ia64/ia64-protos.h5
-rw-r--r--gcc/config/ia64/ia64.c68
-rw-r--r--gcc/config/ia64/ia64.h4
4 files changed, 75 insertions, 15 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index b47a92a..18956dd 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,16 @@
+2000-06-08 James E. Wilson <wilson@cygnus.com>
+
+ * config/ia64/ia64-protos.h (ia64_output_end_prologue): Add.
+ (output_function_prologue): Fix mispelling.
+ (output_function_prologue, output_function_epilogue): Reorder to
+ match ia64.c definition order.
+ * config/ia64/ia64.c (ia64_expand_prologue): Add comment.
+ (ia64_expand_epilogue): Set RTX_FRAME_RELATED_P on stack restore insns.
+ Use r3 instead of r2 for large stack restores.
+ (ia64_output_end_prologue): New function.
+ (process_set): Emit ".restore sp" for epilogue stack restores.
+ * config/ia64/ia64.h (FUNCTION_END_PROLOGUE): Define.
+
2000-06-08 Jakub Jelinek <jakub@redhat.com>
* dbxout.c (dbxout_type_fields): Don't segfault on fields with
diff --git a/gcc/config/ia64/ia64-protos.h b/gcc/config/ia64/ia64-protos.h
index ec820b1..7c4c5fa 100644
--- a/gcc/config/ia64/ia64-protos.h
+++ b/gcc/config/ia64/ia64-protos.h
@@ -92,11 +92,12 @@ extern void ia64_encode_section_info PARAMS((tree));
extern int ia64_epilogue_uses PARAMS((int));
extern void ia64_expand_prologue PARAMS((void));
extern void ia64_expand_epilogue PARAMS((void));
+extern void ia64_function_prologue PARAMS((FILE *, int));
+extern void ia64_output_end_prologue PARAMS((FILE *));
+extern void ia64_function_epilogue PARAMS((FILE *, int));
extern int ia64_direct_return PARAMS((void));
extern int ia64_rap_fp_offset PARAMS((void));
extern void ia64_init_builtins PARAMS((void));
extern void ia64_override_options PARAMS((void));
extern unsigned int ia64_compute_frame_size PARAMS((int));
extern void save_restore_insns PARAMS((int));
-extern void ia64_function_prologue PARAMS((FILE *, int));
-extern void ia64_funtion_epilogue PARAMS((FILE *, int));
diff --git a/gcc/config/ia64/ia64.c b/gcc/config/ia64/ia64.c
index e9eade3..43ffdcb 100644
--- a/gcc/config/ia64/ia64.c
+++ b/gcc/config/ia64/ia64.c
@@ -1001,6 +1001,8 @@ ia64_expand_prologue ()
offset = GEN_INT (-frame_size);
else
{
+ /* ??? We use r2 to tell process_set that this is a stack pointer
+ decrement. See also ia64_expand_epilogue. */
offset = gen_rtx_REG (DImode, GR_REG (2));
insn = emit_insn (gen_movdi (offset, GEN_INT (-frame_size)));
RTX_FRAME_RELATED_P (insn) = 1;
@@ -1033,6 +1035,8 @@ ia64_expand_prologue ()
void
ia64_expand_epilogue ()
{
+ rtx insn;
+
/* Restore registers from frame. */
save_restore_insns (0);
@@ -1053,8 +1057,10 @@ ia64_expand_epilogue ()
/* If there is a frame pointer, then we need to make the stack pointer
restore depend on the frame pointer, so that the stack pointer
restore won't be moved up past fp-relative loads from the frame. */
- emit_insn (gen_epilogue_deallocate_stack (stack_pointer_rtx,
- hard_frame_pointer_rtx));
+ insn
+ = emit_insn (gen_epilogue_deallocate_stack (stack_pointer_rtx,
+ hard_frame_pointer_rtx));
+ RTX_FRAME_RELATED_P (insn) = 1;
}
else
{
@@ -1067,11 +1073,14 @@ ia64_expand_epilogue ()
offset = GEN_INT (frame_size);
else
{
- offset = gen_rtx_REG (DImode, GR_REG (2));
+ /* ??? We use r3 to tell process_set that this is a stack
+ pointer increment. See also ia64_expand_prologue. */
+ offset = gen_rtx_REG (DImode, GR_REG (3));
emit_insn (gen_movdi (offset, GEN_INT (frame_size)));
}
- emit_insn (gen_adddi3 (stack_pointer_rtx, stack_pointer_rtx,
- offset));
+ insn = emit_insn (gen_adddi3 (stack_pointer_rtx, stack_pointer_rtx,
+ offset));
+ RTX_FRAME_RELATED_P (insn) = 1;
}
}
}
@@ -1136,6 +1145,18 @@ ia64_function_prologue (file, size)
fprintf (file, "\t.prologue\n");
}
+/* Emit the .body directive at the scheduled end of the prologue. */
+
+void
+ia64_output_end_prologue (file)
+ FILE *file;
+{
+ if (!flag_unwind_tables && (!flag_exceptions || exceptions_via_longjmp))
+ return;
+
+ fputs ("\t.body\n", file);
+}
+
/* Emit the function epilogue. */
void
@@ -3021,19 +3042,40 @@ process_set (asm_out_file, pat)
rtx op1 = XEXP (src, 1);
if (op0 == dest && GET_CODE (op1) == CONST_INT)
{
- fputs ("\t.fframe ", asm_out_file);
- fprintf (asm_out_file, HOST_WIDE_INT_PRINT_DEC, -INTVAL (op1));
- fputc ('\n', asm_out_file);
- frame_size = INTVAL (op1);
- return 1;
+ if (INTVAL (op1) < 0)
+ {
+ fputs ("\t.fframe ", asm_out_file);
+ fprintf (asm_out_file, HOST_WIDE_INT_PRINT_DEC,
+ -INTVAL (op1));
+ fputc ('\n', asm_out_file);
+ frame_size = INTVAL (op1);
+ }
+ else
+ fprintf (asm_out_file, "\t.restore sp\n");
}
else if (op0 == dest && GET_CODE (op1) == REG)
{
- fprintf (asm_out_file, "\t.vframe r%d\n", REGNO (op1));
- frame_size = 0;
- return 1;
+ /* ia64_expand_prologue uses r2 for stack pointer decrements,
+ ia64_expand_epilogue uses r3 for stack pointer increments. */
+ if (REGNO (op1) == GR_REG (2))
+ {
+ fprintf (asm_out_file, "\t.vframe r%d\n", REGNO (op1));
+ frame_size = 0;
+ }
+ else if (REGNO (op1) == GR_REG (3))
+ fprintf (asm_out_file, "\t.restore sp\n");
+ else
+ abort ();
}
+ else
+ abort ();
}
+ else if (GET_CODE (src) == REG && REGNO (src) == FRAME_POINTER_REGNUM)
+ fprintf (asm_out_file, "\t.restore sp\n");
+ else
+ abort ();
+
+ return 1;
}
/* Look for a frame offset. */
if (GET_CODE (dest) == REG)
diff --git a/gcc/config/ia64/ia64.h b/gcc/config/ia64/ia64.h
index 6ea12dc..cc5ba5b 100644
--- a/gcc/config/ia64/ia64.h
+++ b/gcc/config/ia64/ia64.h
@@ -1464,6 +1464,10 @@ do { \
#define FUNCTION_PROLOGUE(FILE, SIZE) \
ia64_function_prologue (FILE, SIZE)
+/* This macro notes the end of the prologue. */
+
+#define FUNCTION_END_PROLOGUE(FILE) ia64_output_end_prologue (FILE)
+
/* Define this macro as a C expression that is nonzero if the return
instruction or the function epilogue ignores the value of the stack pointer;
in other words, if it is safe to delete an instruction to adjust the stack