OSDN Git Service

IA-64 sibcall unwind bug, PR target/13158
[pf3gnuchains/gcc-fork.git] / gcc / config / ia64 / ia64.c
index 5eed721..39258f2 100644 (file)
@@ -2604,10 +2604,13 @@ ia64_expand_epilogue (int sibcall_p)
         preserve those input registers used as arguments to the sibling call.
         It is unclear how to compute that number here.  */
       if (current_frame_info.n_input_regs != 0)
-       emit_insn (gen_alloc (gen_rtx_REG (DImode, fp),
-                             const0_rtx, const0_rtx,
-                             GEN_INT (current_frame_info.n_input_regs),
-                             const0_rtx));
+       {
+         rtx n_inputs = GEN_INT (current_frame_info.n_input_regs);
+         insn = emit_insn (gen_alloc (gen_rtx_REG (DImode, fp),
+                               const0_rtx, const0_rtx,
+                               n_inputs, const0_rtx));
+         RTX_FRAME_RELATED_P (insn) = 1;
+       }
     }
 }
 
@@ -7290,13 +7293,24 @@ process_set (FILE *asm_out_file, rtx pat)
     {
       dest_regno = REGNO (dest);
 
-      /* If this isn't the final destination for ar.pfs, the alloc
-        shouldn't have been marked frame related.  */
-      if (dest_regno != current_frame_info.reg_save_ar_pfs)
-       abort ();
-
-      fprintf (asm_out_file, "\t.save ar.pfs, r%d\n",
-              ia64_dbx_register_number (dest_regno));
+      /* If this is the final destination for ar.pfs, then this must
+        be the alloc in the prologue.  */
+      if (dest_regno == current_frame_info.reg_save_ar_pfs)
+       fprintf (asm_out_file, "\t.save ar.pfs, r%d\n",
+                ia64_dbx_register_number (dest_regno));
+      else
+       {
+         /* This must be an alloc before a sibcall.  We must drop the
+            old frame info.  The easiest way to drop the old frame
+            info is to ensure we had a ".restore sp" directive
+            followed by a new prologue.  If the procedure doesn't
+            have a memory-stack frame, we'll issue a dummy ".restore
+            sp" now.  */
+         if (current_frame_info.total_size == 0)
+           /* if haven't done process_epilogue() yet, do it now */
+           process_epilogue ();
+         fprintf (asm_out_file, "\t.prologue\n");
+       }
       return 1;
     }