alpha.c (alpha_ra_ever_killed): Inspect the topmost sequence, not whatever we're...
authorRichard Henderson <rth@cygnus.com>
Sat, 5 Sep 1998 22:22:07 +0000 (15:22 -0700)
committerRichard Henderson <rth@gcc.gnu.org>
Sat, 5 Sep 1998 22:22:07 +0000 (15:22 -0700)
        * alpha.c (alpha_ra_ever_killed): Inspect the topmost sequence,
        not whatever we're generating now.
        * alpha.c (set_frame_related_p, FRP): New.
        (alpha_expand_prologue): Mark frame related insns.
        (alpha_expand_epilogue): Likewise, but with a null FRP.
        * alpha.h (INCOMING_RETURN_ADDR_RTX): New.
        * alpha.md (exception_receiver): New.
        * alpha/crtbegin.asm (.eh_frame): New beginning.
        (__do_frame_setup, __do_frame_takedown): New.
        * alpha/crtend.asm (.eh_frame): New ending.
        * alpha/elf.h (DWARF2_DEBUGGING_INFO): Define.
        (ASM_SPEC): Don't emit both dwarf2 and mdebug.
        (ASM_FILE_START): Don't emit .file for dwarf2.

From-SVN: r22277

gcc/ChangeLog
gcc/config/alpha/alpha.c
gcc/config/alpha/alpha.h
gcc/config/alpha/alpha.md
gcc/config/alpha/crtbegin.asm
gcc/config/alpha/crtend.asm
gcc/config/alpha/elf.h

index dd5d66499ddba44af7dbf418c1507c0138fcd997..0f3b52e0c586b4202009a8986f0c8c158d2565f2 100644 (file)
@@ -1,5 +1,20 @@
 Sat Sep  5 22:05:25 1998  Richard Henderson  <rth@cygnus.com>
 
+       * alpha.c (alpha_ra_ever_killed): Inspect the topmost sequence,
+       not whatever we're generating now.
+
+       * alpha.c (set_frame_related_p, FRP): New.
+       (alpha_expand_prologue): Mark frame related insns.
+       (alpha_expand_epilogue): Likewise, but with a null FRP.
+       * alpha.h (INCOMING_RETURN_ADDR_RTX): New.
+       * alpha.md (exception_receiver): New.
+       * alpha/crtbegin.asm (.eh_frame): New beginning.
+       (__do_frame_setup, __do_frame_takedown): New.
+       * alpha/crtend.asm (.eh_frame): New ending.
+       * alpha/elf.h (DWARF2_DEBUGGING_INFO): Define.
+       (ASM_SPEC): Don't emit both dwarf2 and mdebug.
+       (ASM_FILE_START): Don't emit .file for dwarf2.
+
        * rtl.h (enum reg_note): Add REG_FRAME_RELATED_EXPR.
        * rtl.c (reg_note_name): Likewise.
        * rtl.texi (REG_NOTES): Likewise.
index 17cab88d8d5345c535ffcb2aab463718a66bcdb9..e19ddab0fd8408ded8b46fc606b4800b01e6a85f 100644 (file)
@@ -2468,6 +2468,8 @@ alpha_return_addr (count, frame)
 static int
 alpha_ra_ever_killed ()
 {
+  rtx top;
+
 #ifdef ASM_OUTPUT_MI_THUNK
   if (current_function_is_thunk)
     return 0;
@@ -2475,8 +2477,11 @@ alpha_ra_ever_killed ()
   if (!alpha_return_addr_rtx)
     return regs_ever_live[REG_RA];
 
-  return reg_set_between_p (gen_rtx_REG (Pmode, REG_RA),
-                           get_insns(), NULL_RTX);
+  push_topmost_sequence ();
+  top = get_insns ();
+  pop_topmost_sequence ();
+
+  return reg_set_between_p (gen_rtx_REG (Pmode, REG_RA), top, NULL_RTX);
 }
 
 \f
@@ -3192,6 +3197,32 @@ alpha_write_verstamp (file)
 #endif
 }
 \f
+/* Helper function to set RTX_FRAME_RELATED_P on instructions, including
+   sequences.  */
+
+static rtx
+set_frame_related_p ()
+{
+  rtx seq = gen_sequence ();
+  end_sequence ();
+
+  if (GET_CODE (seq) == SEQUENCE)
+    {
+      int i = XVECLEN (seq, 0);
+      while (--i >= 0)
+       RTX_FRAME_RELATED_P (XVECEXP (seq, 0, i)) = 1;
+     return emit_insn (seq);
+    }
+  else
+    {
+      seq = emit_insn (seq);
+      RTX_FRAME_RELATED_P (seq) = 1;
+      return seq;
+    }
+}
+
+#define FRP(exp)  (start_sequence (), exp, set_frame_related_p ())
+
 /* Write function prologue.  */
 
 /* On vms we have two kinds of functions:
@@ -3271,8 +3302,8 @@ alpha_expand_prologue ()
 
       if (frame_size != 0)
        {
-         emit_move_insn (stack_pointer_rtx,
-                         plus_constant (stack_pointer_rtx, -frame_size));
+         FRP (emit_move_insn (stack_pointer_rtx,
+                              plus_constant (stack_pointer_rtx, -frame_size)));
        }
     }
   else
@@ -3302,7 +3333,18 @@ alpha_expand_prologue ()
          emit_move_insn (last, const0_rtx);
        }
 
-      emit_move_insn (stack_pointer_rtx, plus_constant (ptr, -leftover));
+      ptr = emit_move_insn (stack_pointer_rtx, plus_constant (ptr, -leftover));
+
+      /* This alternative is special, because the DWARF code cannot possibly
+        intuit through the loop above.  So we invent this note it looks at
+        instead.  */
+      RTX_FRAME_RELATED_P (ptr) = 1;
+      REG_NOTES (ptr)
+       = gen_rtx_EXPR_LIST (REG_FRAME_RELATED_EXPR,
+                            gen_rtx_SET (VOIDmode, stack_pointer_rtx,
+                              gen_rtx_PLUS (Pmode, stack_pointer_rtx,
+                                            GEN_INT (-frame_size))),
+                            REG_NOTES (ptr));
     }
 
   /* Cope with very large offsets to the register save area.  */
@@ -3318,21 +3360,22 @@ alpha_expand_prologue ()
        bias = reg_offset, reg_offset = 0;
 
       sa_reg = gen_rtx_REG (DImode, 24);
-      emit_move_insn (sa_reg, plus_constant (stack_pointer_rtx, bias));
+      FRP (emit_move_insn (sa_reg, plus_constant (stack_pointer_rtx, bias)));
     }
     
   /* Save regs in stack order.  Beginning with VMS PV.  */
   if (TARGET_OPEN_VMS && vms_is_stack_procedure)
     {
-      emit_move_insn (gen_rtx_MEM (DImode, stack_pointer_rtx),
-                     gen_rtx_REG (DImode, REG_PV));
+      FRP (emit_move_insn (gen_rtx_MEM (DImode, stack_pointer_rtx),
+                          gen_rtx_REG (DImode, REG_PV)));
     }
 
   /* Save register RA next.  */
   if (imask & (1L << REG_RA))
     {
-      emit_move_insn (gen_rtx_MEM (DImode, plus_constant (sa_reg, reg_offset)),
-                     gen_rtx_REG (DImode, REG_RA));
+      FRP (emit_move_insn (gen_rtx_MEM (DImode,
+                                       plus_constant (sa_reg, reg_offset)),
+                          gen_rtx_REG (DImode, REG_RA)));
       imask &= ~(1L << REG_RA);
       reg_offset += 8;
     }
@@ -3341,18 +3384,18 @@ alpha_expand_prologue ()
   for (i = 0; i < 32; i++)
     if (imask & (1L << i))
       {
-       emit_move_insn (gen_rtx_MEM (DImode,
-                                    plus_constant (sa_reg, reg_offset)),
-                       gen_rtx_REG (DImode, i));
+       FRP (emit_move_insn (gen_rtx_MEM (DImode,
+                                         plus_constant (sa_reg, reg_offset)),
+                            gen_rtx_REG (DImode, i)));
        reg_offset += 8;
       }
 
   for (i = 0; i < 32; i++)
     if (fmask & (1L << i))
       {
-       emit_move_insn (gen_rtx_MEM (DFmode,
-                                    plus_constant (sa_reg, reg_offset)),
-                       gen_rtx_REG (DFmode, i+32));
+       FRP (emit_move_insn (gen_rtx_MEM (DFmode,
+                                         plus_constant (sa_reg, reg_offset)),
+                            gen_rtx_REG (DFmode, i+32)));
        reg_offset += 8;
       }
 
@@ -3361,25 +3404,25 @@ alpha_expand_prologue ()
       if (!vms_is_stack_procedure)
        {
          /* Register frame procedures fave the fp.  */
-         emit_move_insn (gen_rtx_REG (DImode, vms_save_fp_regno),
-                         hard_frame_pointer_rtx);
+         FRP (emit_move_insn (gen_rtx_REG (DImode, vms_save_fp_regno),
+                              hard_frame_pointer_rtx));
        }
 
       if (vms_base_regno != REG_PV)
-       emit_move_insn (gen_rtx_REG (DImode, vms_base_regno),
-                       gen_rtx_REG (DImode, REG_PV));
+       FRP (emit_move_insn (gen_rtx_REG (DImode, vms_base_regno),
+                            gen_rtx_REG (DImode, REG_PV)));
 
       if (vms_unwind_regno == HARD_FRAME_POINTER_REGNUM)
        {
-         emit_move_insn (hard_frame_pointer_rtx, stack_pointer_rtx);
+         FRP (emit_move_insn (hard_frame_pointer_rtx, stack_pointer_rtx));
        }
 
       /* If we have to allocate space for outgoing args, do it now.  */
       if (current_function_outgoing_args_size != 0)
        {
-         emit_move_insn (stack_pointer_rtx, 
-           plus_constant (hard_frame_pointer_rtx,
-             - ALPHA_ROUND (current_function_outgoing_args_size)));
+         FRP (emit_move_insn (stack_pointer_rtx, 
+               plus_constant (hard_frame_pointer_rtx,
+                - ALPHA_ROUND (current_function_outgoing_args_size))));
        }
     }
   else
@@ -3388,13 +3431,13 @@ alpha_expand_prologue ()
       if (frame_pointer_needed)
        {
          if (TARGET_CAN_FAULT_IN_PROLOGUE)
-           emit_move_insn (hard_frame_pointer_rtx, stack_pointer_rtx);
+           FRP (emit_move_insn (hard_frame_pointer_rtx, stack_pointer_rtx));
          else
            {
              /* This must always be the last instruction in the
                 prologue, thus we emit a special move + clobber.  */
-             emit_insn (gen_init_fp (hard_frame_pointer_rtx,
-                                     stack_pointer_rtx, sa_reg));
+             FRP (emit_insn (gen_init_fp (hard_frame_pointer_rtx,
+                                          stack_pointer_rtx, sa_reg)));
            }
        }
     }
@@ -3611,6 +3654,12 @@ output_end_prologue (file)
 
 /* Write function epilogue.  */
 
+/* ??? At some point we will want to support full unwind, and so will 
+   need to mark the epilogue as well.  At the moment, we just confuse
+   dwarf2out.  */
+#undef FRP
+#define FRP(exp) exp
+
 void
 alpha_expand_epilogue ()
 {
@@ -3659,7 +3708,7 @@ alpha_expand_epilogue ()
           && vms_unwind_regno == HARD_FRAME_POINTER_REGNUM)
          || (!TARGET_OPEN_VMS && frame_pointer_needed))
        {
-         emit_move_insn (stack_pointer_rtx, hard_frame_pointer_rtx);
+         FRP (emit_move_insn (stack_pointer_rtx, hard_frame_pointer_rtx));
        }
 
       /* Cope with very large offsets to the register save area.  */
@@ -3677,13 +3726,14 @@ alpha_expand_epilogue ()
          sa_reg = gen_rtx_REG (DImode, 22);
          sa_reg_exp = plus_constant (stack_pointer_rtx, bias);
 
-         emit_move_insn (sa_reg, sa_reg_exp);
+         FRP (emit_move_insn (sa_reg, sa_reg_exp));
        }
          
       /* Restore registers in order, excepting a true frame pointer. */
 
-      emit_move_insn (gen_rtx_REG (DImode, REG_RA),
-                     gen_rtx_MEM (DImode, plus_constant(sa_reg, reg_offset)));
+      FRP (emit_move_insn (gen_rtx_REG (DImode, REG_RA),
+                          gen_rtx_MEM (DImode, plus_constant(sa_reg,
+                                                             reg_offset))));
       reg_offset += 8;
       imask &= ~(1L << REG_RA);
 
@@ -3694,10 +3744,10 @@ alpha_expand_epilogue ()
              fp_offset = reg_offset;
            else
              {
-               emit_move_insn (gen_rtx_REG (DImode, i),
-                               gen_rtx_MEM (DImode,
-                                            plus_constant(sa_reg,
-                                                          reg_offset)));
+               FRP (emit_move_insn (gen_rtx_REG (DImode, i),
+                                    gen_rtx_MEM (DImode,
+                                                 plus_constant(sa_reg,
+                                                               reg_offset))));
              }
            reg_offset += 8;
          }
@@ -3705,9 +3755,10 @@ alpha_expand_epilogue ()
       for (i = 0; i < 32; ++i)
        if (fmask & (1L << i))
          {
-           emit_move_insn (gen_rtx_REG (DFmode, i+32),
-                           gen_rtx_MEM (DFmode,
-                                        plus_constant(sa_reg, reg_offset)));
+           FRP (emit_move_insn (gen_rtx_REG (DFmode, i+32),
+                                gen_rtx_MEM (DFmode,
+                                             plus_constant(sa_reg,
+                                                           reg_offset))));
            reg_offset += 8;
          }
     }
@@ -3732,20 +3783,20 @@ alpha_expand_epilogue ()
          else
            {
              sp_adj1 = gen_rtx_REG (DImode, 23);
-             emit_move_insn (sp_adj1, sp_adj2);
+             FRP (emit_move_insn (sp_adj1, sp_adj2));
            }
          sp_adj2 = GEN_INT (low);
        }
       else
        {
          sp_adj2 = gen_rtx_REG (DImode, 23);
-         sp_adj1 = alpha_emit_set_const (sp_adj2, DImode, frame_size, 3);
+         FRP (sp_adj1 = alpha_emit_set_const (sp_adj2, DImode, frame_size, 3));
          if (!sp_adj1)
            {
              /* We can't drop new things to memory this late, afaik,
                 so build it up by pieces.  */
 #if HOST_BITS_PER_WIDE_INT == 64
-             sp_adj1 = alpha_emit_set_long_const (sp_adj2, frame_size);
+             FRP (sp_adj1 = alpha_emit_set_long_const (sp_adj2, frame_size));
              if (!sp_adj1)
                abort ();
 #else
@@ -3761,29 +3812,29 @@ alpha_expand_epilogue ()
       if (fp_is_frame_pointer)
        {
          emit_insn (gen_blockage ());
-         emit_move_insn (hard_frame_pointer_rtx,
-                         gen_rtx_MEM (DImode,
-                                      plus_constant(sa_reg, fp_offset)));
+         FRP (emit_move_insn (hard_frame_pointer_rtx,
+                              gen_rtx_MEM (DImode,
+                                           plus_constant(sa_reg, fp_offset))));
        }
       else if (TARGET_OPEN_VMS)
        {
          emit_insn (gen_blockage ());
-         emit_move_insn (hard_frame_pointer_rtx,
-                         gen_rtx_REG (DImode, vms_save_fp_regno));
+         FRP (emit_move_insn (hard_frame_pointer_rtx,
+                              gen_rtx_REG (DImode, vms_save_fp_regno)));
        }
 
       /* Restore the stack pointer.  */
       emit_insn (gen_blockage ());
-      emit_move_insn (stack_pointer_rtx,
-                     gen_rtx_PLUS (DImode, sp_adj1, sp_adj2));
+      FRP (emit_move_insn (stack_pointer_rtx,
+                          gen_rtx_PLUS (DImode, sp_adj1, sp_adj2)));
     }
   else 
     {
       if (TARGET_OPEN_VMS && !vms_is_stack_procedure)
         {
           emit_insn (gen_blockage ());
-          emit_move_insn (hard_frame_pointer_rtx,
-                         gen_rtx_REG (DImode, vms_save_fp_regno));
+          FRP (emit_move_insn (hard_frame_pointer_rtx,
+                              gen_rtx_REG (DImode, vms_save_fp_regno)));
         }
     }
 
index b77f3b9e855dd053f944aaf843a5a63fa7b8903a..9aacab5d83310f71fee102f943234cc5dab13298 100644 (file)
@@ -1301,6 +1301,9 @@ extern void alpha_initialize_trampoline ();
 #define RETURN_ADDR_RTX  alpha_return_addr
 extern struct rtx_def *alpha_return_addr ();
 
+/* Before the prologue, RA lives in $26. */
+#define INCOMING_RETURN_ADDR_RTX  gen_rtx_REG (Pmode, 26)
+
 /* Initialize data used by insn expanders.  This is called from insn_emit,
    once for every function before code is generated.  */
 
index 89184bf25b3f3b68d73f226d3604f1e7b0aa70e9..232fb01def14ba1aafca04bf733fd789ff4aa8d0 100644 (file)
@@ -39,6 +39,7 @@
 ;;     4       trapb
 ;;     5       prologue_stack_probe_loop
 ;;     6       realign
+;;     7       exception_receiver
 \f
 ;; Processor type -- this attribute must exactly match the processor_type
 ;; enumeration in alpha.h.
 (define_insn ""
   [(unspec_volatile [(match_operand 0 "" "")] 2)]
   "! TARGET_OPEN_VMS && ! TARGET_WINDOWS_NT"
-  "br $27,$LSJ%=\\n$LSJ%=:\;ldgp $29,0($27)"
+  "br $29,$LSJ%=\\n$LSJ%=:\;ldgp $29,0($29)"
+  [(set_attr "length" "12")
+   (set_attr "type" "multi")])
+
+(define_insn "exception_receiver"
+  [(unspec_volatile [(const_int 0)] 7)]
+  "! TARGET_OPEN_VMS && ! TARGET_WINDOWS_NT"
+  "br $29,$LSJ%=\\n$LSJ%=:\;ldgp $29,0($29)"
   [(set_attr "length" "12")
    (set_attr "type" "multi")])
 
index c28440d8a248d6c56930c81013966e1e9f3e9714..f954f1ab0d3e55670131a60c85b33d240ac9f045 100644 (file)
@@ -50,6 +50,8 @@ __CTOR_LIST__:
 __DTOR_LIST__:
        .quad -1
 
+.section .eh_frame,"aw"
+__EH_FRAME_BEGIN__:
 
  #
  # Fragment of the ELF _fini routine that invokes our dtor cleanup.
@@ -67,10 +69,25 @@ __DTOR_LIST__:
 1:     ldgp    $29,0($29)
        jsr     $26,__do_global_dtors_aux
 
+       # Ideally this call would go in crtend.o, except that we can't
+       # get hold of __EH_FRAME_BEGIN__ there.
+
+       jsr     $26,__do_frame_takedown
+
        # Must match the alignment we got from crti.o else we get
        # zero-filled holes in our _fini function and then SIGILL.
        .align 3
 
+ #
+ # Fragment of the ELF _init routine that sets up the frame info.
+ #
+
+.section .init,"ax"
+       br      $29,1f
+1:     ldgp    $29,0($29)
+       jsr     $26,__do_frame_setup
+       .align 3
+
  #
  # Invoke our destructors in order.
  #
@@ -78,7 +95,7 @@ __DTOR_LIST__:
 .data
 
  # Support recursive calls to exit.
-9:     .quad   __DTOR_LIST__
+$ptr:  .quad   __DTOR_LIST__
 
 .text
 
@@ -86,15 +103,14 @@ __DTOR_LIST__:
        .ent __do_global_dtors_aux
 
 __do_global_dtors_aux:
-       ldgp    $29,0($27)
        lda     $30,-16($30)
        .frame  $30,16,$26,0
        stq     $9,8($30)
        stq     $26,0($30)
        .mask   0x4000200,-16
-       .prologue 1
+       .prologue 0
 
-       lda     $9,9b
+       lda     $9,$ptr
        br      1f
 0:     stq     $1,0($9)
        jsr     $26,($27)
@@ -109,3 +125,68 @@ __do_global_dtors_aux:
        ret
 
        .end __do_global_dtors_aux
+
+ #
+ # Install our frame info.
+ #
+
+ # ??? How can we rationally keep this size correct?
+
+.section .bss
+       .type $object,@object
+       .align 3
+$object:
+       .zero 48
+       .size $object, 48
+
+.text 
+
+       .align 3
+       .ent __do_frame_setup
+
+__do_frame_setup:
+       ldgp    $29,0($27)
+       lda     $30,-16($30)
+       .frame  $30,16,$26,0
+       stq     $26,0($30)
+       .mask   0x4000000,-16
+       .prologue 1
+
+       lda     $1,__register_frame_info
+       beq     $1,0f
+       lda     $16,__EH_FRAME_BEGIN__
+       lda     $17,$object
+       jsr     $26,__register_frame_info
+       ldq     $26,0($30)
+0:     lda     $30,16($30)
+       ret
+
+       .end __do_frame_setup
+
+ #
+ # Remove our frame info.
+ #
+
+       .align 3
+       .ent __do_frame_takedown
+
+__do_frame_takedown:
+       ldgp    $29,0($27)
+       lda     $30,-16($30)
+       .frame  $30,16,$26,0
+       stq     $26,0($30)
+       .mask   0x4000000,-16
+       .prologue 1
+
+       lda     $1,__deregister_frame_info
+       beq     $1,0f
+       lda     $16,__EH_FRAME_BEGIN__
+       jsr     $26,__deregister_frame_info
+       ldq     $26,0($30)
+0:     lda     $30,16($30)
+       ret
+
+       .end __do_frame_takedown
+
+.weak __register_frame_info
+.weak __deregister_frame_info
index 36f11b9723aa98a1bdef00c84deb2683d1b022ef..4a0cc5e9f61247e59def8532d0cf1b2ac011ddff 100644 (file)
@@ -50,6 +50,9 @@ __CTOR_END__:
 __DTOR_END__:
        .quad   0
 
+.section .eh_frame,"aw"
+__FRAME_END__:
+       .quad   0
 
  #
  # Fragment of the ELF _init routine that invokes our ctor startup
index 4f4703c14ef0e7943d1a12efbf482426618f6edc..89eda748c0650c8e36314b13a985f761b9a016a1 100644 (file)
@@ -24,6 +24,7 @@ Boston, MA 02111-1307, USA.    */
 #define OBJECT_FORMAT_ELF
 
 #define DBX_DEBUGGING_INFO
+#define DWARF2_DEBUGGING_INFO
 
 #undef PREFERRED_DEBUGGING_TYPE
 #define PREFERRED_DEBUGGING_TYPE DBX_DEBUG
@@ -34,7 +35,7 @@ Boston, MA 02111-1307, USA.    */
 #define CC1_SPEC  "%{G*}"
 
 #undef ASM_SPEC
-#define ASM_SPEC  "%{G*} %{relax:-relax}"
+#define ASM_SPEC  "%{G*} %{relax:-relax} %{gdwarf*:-no-mdebug}"
 
 #undef LINK_SPEC
 #define LINK_SPEC "-m elf64alpha %{G*} %{relax:-relax}         \
@@ -49,18 +50,21 @@ Boston, MA 02111-1307, USA.    */
 /* Output at beginning of assembler file.  */
 #undef ASM_FILE_START
 #define ASM_FILE_START(FILE)                                   \
-{                                                              \
-  alpha_write_verstamp (FILE);                                 \
-  output_file_directive (FILE, main_input_filename);           \
+do {                                                           \
+  if (write_symbols != DWARF2_DEBUG)                           \
+    {                                                          \
+      alpha_write_verstamp (FILE);                             \
+      output_file_directive (FILE, main_input_filename);       \
+    }                                                          \
   fprintf (FILE, "\t.set noat\n");                             \
-  fprintf (FILE, "\t.set noreorder\n");                         \
+  fprintf (FILE, "\t.set noreorder\n");                                \
   if (TARGET_BWX | TARGET_MAX | TARGET_CIX)                    \
     {                                                          \
       fprintf (FILE, "\t.arch %s\n",                           \
                (alpha_cpu == PROCESSOR_EV6 ? "ev6"             \
                 : TARGET_MAX ? "pca56" : "ev56"));             \
     }                                                          \
-}
+} while (0)
 
 extern void output_file_directive ();