sparc.c (eligible_for_epilogue_delay): False if current_function_calls_eh_return.
authorRichard Henderson <rth@redhat.com>
Wed, 28 Mar 2001 11:23:52 +0000 (03:23 -0800)
committerRichard Henderson <rth@gcc.gnu.org>
Wed, 28 Mar 2001 11:23:52 +0000 (03:23 -0800)
        * config/sparc/sparc.c (eligible_for_epilogue_delay): False if
        current_function_calls_eh_return.
        (output_function_epilogue): Handle eh_return.
        * config/sparc/sparc.h (DOESNT_NEED_UNWINDER): Remove.
        (EH_RETURN_DATA_REGNO): New.
        (EH_RETURN_STACKADJ_RTX): New.
        (EH_RETURN_HANDLER_RTX): New.
        * config/sparc/sparc.md (call/short branch peepholes): Check
        can_throw_internal instead of in_same_eh_region.

From-SVN: r40928

gcc/ChangeLog
gcc/config/sparc/sparc.c
gcc/config/sparc/sparc.h
gcc/config/sparc/sparc.md

index b6d3eb9f2e55508019d016440d1802ab7031ff87..6b66ea64c6956aee5bea251554c5642e85a1edec 100644 (file)
@@ -1,5 +1,15 @@
 2001-03-28  Richard Henderson  <rth@redhat.com>
 
+       * config/sparc/sparc.c (eligible_for_epilogue_delay): False if
+       current_function_calls_eh_return.
+       (output_function_epilogue): Handle eh_return.
+       * config/sparc/sparc.h (DOESNT_NEED_UNWINDER): Remove.
+       (EH_RETURN_DATA_REGNO): New.
+       (EH_RETURN_STACKADJ_RTX): New.
+       (EH_RETURN_HANDLER_RTX): New.
+       * config/sparc/sparc.md (call/short branch peepholes): Check
+       can_throw_internal instead of in_same_eh_region.
+
        * config/rs6000/rs6000.c (rs6000_stack_info): Allocate space
        for eh_return data registers.
        (rs6000_emit_prologue): Save eh_return data registers.
index e4850271c6c04b670e90b301eb68030e0ffb0874..9cb4c5ccf09f51804c1b3c3adb9da69fe37d387b 100644 (file)
@@ -2377,6 +2377,11 @@ eligible_for_epilogue_delay (trial, slot)
   if (num_gfregs)
     return 0;
 
+  /* If the function uses __builtin_eh_return, the eh_return machinery
+     occupies the delay slot.  */
+  if (current_function_calls_eh_return)
+    return 0;
+
   /* In the case of a true leaf function, anything can go into the delay slot.
      A delay slot only exists however if the frame size is zero, otherwise
      we will put an insn to adjust the stack after the return.  */
@@ -3594,8 +3599,17 @@ output_function_epilogue (file, size, leaf_function)
 
       if (! leaf_function)
        {
+         if (current_function_calls_eh_return)
+           {
+             if (current_function_epilogue_delay_list)
+               abort ();
+             if (SKIP_CALLERS_UNIMP_P)
+               abort ();
+
+             fputs ("\trestore\n\tretl\n\tadd\t%sp, %g1, %sp\n", file);
+           }
          /* If we wound up with things in our delay slot, flush them here.  */
-         if (current_function_epilogue_delay_list)
+         else if (current_function_epilogue_delay_list)
            {
              rtx delay = PATTERN (XEXP (current_function_epilogue_delay_list, 0));
 
@@ -3635,6 +3649,8 @@ output_function_epilogue (file, size, leaf_function)
          else
            fprintf (file, "\t%s\n\trestore\n", ret);
        }
+      else if (current_function_calls_eh_return)
+       abort ();
       /* All of the following cases are for leaf functions.  */
       else if (current_function_epilogue_delay_list)
        {
index cc6b014900f6b4bb25b24cc186d6be7d6a141b7e..9e49eadb02daa6031c47ed24d48878c0d1f4bd2f 100644 (file)
@@ -2235,7 +2235,10 @@ LFLGRET"ID":\n\
    bias if present.  */
 #define INCOMING_FRAME_SP_OFFSET SPARC_STACK_BIAS
 
-#define DOESNT_NEED_UNWINDER (! TARGET_FLAT)
+/* Describe how we implement __builtin_eh_return.  */
+#define EH_RETURN_DATA_REGNO(N) ((N) < 4 ? (N) + 24 : INVALID_REGNUM)
+#define EH_RETURN_STACKADJ_RTX gen_rtx_REG (Pmode, 1)  /* %g1 */
+#define EH_RETURN_HANDLER_RTX  gen_rtx_REG (Pmode, 31) /* %i7 */
 \f
 /* Addressing modes, and classification of registers for them.  */
 
index abfad793115c782c727eb26425e7f7c991aa4225..8167af887ecd0029e9cb44b4320f24c4ff4a195d 100644 (file)
              (clobber (reg:SI 15))])
    (set (pc) (label_ref (match_operand 3 "" "")))]
   "short_branch (INSN_UID (insn), INSN_UID (operands[3]))
-   && in_same_eh_region (insn, operands[3])
-   && in_same_eh_region (insn, ins1)"
+   && (USING_SJLJ_EXCEPTIONS || ! can_throw_internal (insn))"
   "call\\t%a1, %2\\n\\tadd\\t%%o7, (%l3-.-4), %%o7")
 
 (define_peephole
              (clobber (reg:SI 15))])
    (set (pc) (label_ref (match_operand 2 "" "")))]
   "short_branch (INSN_UID (insn), INSN_UID (operands[2]))
-   && in_same_eh_region (insn, operands[2])
-   && in_same_eh_region (insn, ins1)"
+   && (USING_SJLJ_EXCEPTIONS || ! can_throw_internal (insn))"
   "call\\t%a0, %1\\n\\tadd\\t%%o7, (%l2-.-4), %%o7")
 
 (define_peephole
    (set (pc) (label_ref (match_operand 3 "" "")))]
   "TARGET_ARCH64
    && short_branch (INSN_UID (insn), INSN_UID (operands[3]))
-   && in_same_eh_region (insn, operands[3])
-   && in_same_eh_region (insn, ins1)"
+   && (USING_SJLJ_EXCEPTIONS || ! can_throw_internal (insn))"
   "call\\t%a1, %2\\n\\tadd\\t%%o7, (%l3-.-4), %%o7")
 
 (define_peephole
    (set (pc) (label_ref (match_operand 2 "" "")))]
   "TARGET_ARCH64
    && short_branch (INSN_UID (insn), INSN_UID (operands[2]))
-   && in_same_eh_region (insn, operands[2])
-   && in_same_eh_region (insn, ins1)"
+   && (USING_SJLJ_EXCEPTIONS || ! can_throw_internal (insn))"
   "call\\t%a0, %1\\n\\tadd\\t%%o7, (%l2-.-4), %%o7")
 \f
 (define_expand "prologue"