]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
expr.c (expand_builtin_setjmp): Set current_function_has_nonlocal_label.
authorRichard Henderson <rth@cygnus.com>
Fri, 14 Nov 1997 14:48:31 +0000 (06:48 -0800)
committerJeff Law <law@gcc.gnu.org>
Fri, 14 Nov 1997 14:48:31 +0000 (07:48 -0700)
        * expr.c (expand_builtin_setjmp): Set
        current_function_has_nonlocal_label.
        * stupid.c (stupid_life_analysis): If has_nonlocal_label, kill
        call-saved registers across calls.

        * alpha.md (exception_receiver): Remove.
        (nonlocal_goto_receiver_osf): New
        (nonlocal_goto_receiver_vms): Renamed from nonlocal_goto_receiver.
        (nonlocal_goto_receiver): New, select _osf or _vms.

From-SVN: r16491

gcc/ChangeLog
gcc/config/alpha/alpha.md
gcc/expr.c
gcc/stupid.c

index 3e7c23bc637d4e61fa446f91b9a9ae7ce9aa28cd..aaccef84970c0f75068203e2fba675f24a13dd17 100644 (file)
 
 Fri Nov 14 07:24:20 1997  Richard Henderson  <rth@cygnus.com>
 
+       * expr.c (expand_builtin_setjmp): Set
+       current_function_has_nonlocal_label.
+       * stupid.c (stupid_life_analysis): If has_nonlocal_label, kill
+       call-saved registers across calls.
+
+       * alpha.md (exception_receiver): Remove.
+       (nonlocal_goto_receiver_osf): New
+       (nonlocal_goto_receiver_vms): Renamed from nonlocal_goto_receiver.
+       (nonlocal_goto_receiver): New, select _osf or _vms.
+
        * alpha.c (output_prolog [*]): Prefix entry labels with '$' to 
        keep them from being propogated to the object file.
        (alpha_write_linkage): Likewise.
index 769a42300b800273c472344ed5a33bb5d2afed8a..54801173201b200096d8b531e36bbf1dcea6df3c 100644 (file)
     }
 }")
 
-(define_insn "exception_receiver"
+;; Ideally we should be able to define nonlocal_goto and arrange
+;; for the pc to be in a known place.  Or perhaps branch back via
+;; br instead of jmp.
+(define_insn "nonlocal_goto_receiver_osf"
   [(unspec_volatile [(const_int 0)] 2)]
   "! TARGET_OPEN_VMS && ! TARGET_WINDOWS_NT"
-  ".long 0xc3a00000\;ldgp $29,0($29)")
+  "br $29,$LGOTO%=\\n$LGOTO%=:\;ldgp $29,0($29)")
 
-(define_expand "nonlocal_goto_receiver"
+(define_expand "nonlocal_goto_receiver_vms"
   [(unspec_volatile [(const_int 0)] 1)
    (set (reg:DI 27) (mem:DI (reg:DI 29)))
    (unspec_volatile [(const_int 0)] 1)
   "TARGET_OPEN_VMS"
   "")
 
+(define_expand "nonlocal_goto_receiver"
+  [(unspec_volatile [(const_int 0)] 2)]
+  ""
+  "
+{
+  if (TARGET_OPEN_VMS)
+    emit_insn(gen_nonlocal_goto_receiver_vms ());
+  else if (!TARGET_WINDOWS_NT)
+    emit_insn(gen_nonlocal_goto_receiver_osf ());
+  DONE;
+}")
+
 (define_insn "arg_home"
   [(unspec [(const_int 0)] 0)
    (use (reg:DI 1))
index 1097ac4f13c7803c465112d06f8de6420e6c8fbc..076bc924ad64c968a1fddcc77bdec065c1b3f762 100644 (file)
@@ -8151,12 +8151,7 @@ expand_builtin_setjmp (buf_addr, target)
 #endif
     emit_move_insn (virtual_stack_vars_rtx, hard_frame_pointer_rtx);
 
-  /* Do we need to do something like:
-     
-     current_function_has_nonlocal_label = 1;
-
-     here?  It seems like we might have to, or some subset of that
-     functionality, but I am unsure.  (mrs) */
+  current_function_has_nonlocal_label = 1;
 
 #if ARG_POINTER_REGNUM != HARD_FRAME_POINTER_REGNUM
   if (fixed_regs[ARG_POINTER_REGNUM])
index b68b196bcaab012fddcf4d6e41dd4719507a957a..69d6e952824cd84de8aa915f73bc89b4ad3bb202 100644 (file)
@@ -230,21 +230,34 @@ stupid_life_analysis (f, nregs, file)
          && NOTE_LINE_NUMBER (insn) == NOTE_INSN_SETJMP)
        last_setjmp_suid = INSN_SUID (insn);
 
-      /* Mark all call-clobbered regs as live after each call insn
-        so that a pseudo whose life span includes this insn
-        will not go in one of them.
+      /* Mark all call-clobbered regs as dead after each call insn so that
+        a pseudo whose life span includes this insn will not go in one of
+        them.  If the function contains a non-local goto, mark all hard
+        registers dead (except for stack related bits).
+
         Then mark those regs as all dead for the continuing scan
         of the insns before the call.  */
 
       if (GET_CODE (insn) == CALL_INSN)
        {
          last_call_suid = INSN_SUID (insn);
-         IOR_HARD_REG_SET (after_insn_hard_regs[last_call_suid],
-                           call_used_reg_set);
 
-         for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
-           if (call_used_regs[i])
-             regs_live[i] = 0;
+         if (current_function_has_nonlocal_label)
+           {
+             IOR_COMPL_HARD_REG_SET (after_insn_hard_regs[last_call_suid],
+                                     fixed_reg_set);
+             for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
+               if (! fixed_regs[i])
+                 regs_live[i] = 0;
+           }
+         else
+           {
+             IOR_HARD_REG_SET (after_insn_hard_regs[last_call_suid],
+                               call_used_reg_set);
+             for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
+               if (call_used_regs[i])
+                 regs_live[i] = 0;
+           }
 
          /* It is important that this be done after processing the insn's
             pattern because we want the function result register to still