Add unwind support for epilogues, because the kernel unwinder needs them.
authorJames E. Wilson <wilson@cygnus.com>
Thu, 8 Jun 2000 17:15:32 +0000 (17:15 +0000)
committerJim Wilson <wilson@gcc.gnu.org>
Thu, 8 Jun 2000 17:15:32 +0000 (10:15 -0700)
* 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

gcc/ChangeLog
gcc/config/ia64/ia64-protos.h
gcc/config/ia64/ia64.c
gcc/config/ia64/ia64.h

index b47a92af027377a2011d9f79fb2625a4c9ff188e..18956ddb437e78409008618fb94d1a2b881a8499 100644 (file)
@@ -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
index ec820b1aaa62da13888b6ca3b8c1a839f1c592f7..7c4c5faadda39b5d1bf24e5006ba160c55158195 100644 (file)
@@ -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));
index e9eade30b93c0e7b42067370ff539a0b9fa0be28..43ffdcbed61248d4fb7a004abbfa10d702f9355c 100644 (file)
@@ -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)
index 6ea12dcc9ee957df73372d2cf9dfc1484e53ecfd..cc5ba5b214d208c88f367b144f510b0183df6315 100644 (file)
@@ -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