This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

ia64 eh, part 21


Update the alpha port for the changes to eh_return.


r~


        * config/alpha/alpha.c (alpha_sa_mask): Add EH_RETURN_DATA_REGNOs.
        (alpha_mark_machine_status): No eh_epilogue_sp_ofs ...
        (alpha_expand_epilogue): ... use EH_RETURN_STACKADJ_RTX instead.
        * config/alpha/alpha.h (machine_function): Remove eh_epilogue_sp_ofs.
        (EH_RETURN_DATA_REGNO): New.
        (EH_RETURN_STACKADJ_RTX, EH_RETURN_HANDLER_RTX): New.
        * config/alpha/alpha.md (eh_epilogue): Remove.
        (exception_receiver): Use $26 for ldgp input.
        * config/alpha/linux.h (MD_FALLBACK_FRAME_STATE_FOR): New.

Index: alpha/alpha.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/alpha/alpha.c,v
retrieving revision 1.158
diff -c -p -d -r1.158 alpha.c
*** alpha.c	2001/03/22 18:48:32	1.158
--- alpha.c	2001/03/28 11:06:23
*************** alpha_mark_machine_status (p)
*** 3664,3670 ****
  
    if (machine)
      {
-       ggc_mark_rtx (machine->eh_epilogue_sp_ofs);
        ggc_mark_rtx (machine->ra_rtx);
      }
  }
--- 3664,3669 ----
*************** alpha_sa_mask (imaskP, fmaskP)
*** 4416,4421 ****
--- 4415,4432 ----
  	      fmask |= (1L << (i - 32));
  	  }
  
+       /* We need to restore these for the handler.  */
+       if (current_function_calls_eh_return)
+ 	{
+ 	  for (i = 0; ; ++i)
+ 	    {
+ 	      unsigned regno = EH_RETURN_DATA_REGNO (i);
+ 	      if (regno == INVALID_REGNUM)
+ 		break;
+ 	      imask |= 1L << regno;
+ 	    }
+ 	}
+ 
        if (imask || fmask || alpha_ra_ever_killed ())
  	imask |= (1L << REG_RA);
      }
*************** alpha_expand_epilogue ()
*** 5112,5118 ****
    fp_offset = 0;
    sa_reg = stack_pointer_rtx;
  
!   eh_ofs = cfun->machine->eh_epilogue_sp_ofs;
    if (sa_size)
      {
        /* If we have a frame pointer, restore SP from it.  */
--- 5123,5133 ----
    fp_offset = 0;
    sa_reg = stack_pointer_rtx;
  
!   if (current_function_calls_eh_return)
!     eh_ofs = EH_RETURN_STACKADJ_RTX;
!   else
!     eh_ofs = NULL_RTX;
! 
    if (sa_size)
      {
        /* If we have a frame pointer, restore SP from it.  */
*************** alpha_expand_epilogue ()
*** 5140,5151 ****
  	  
        /* Restore registers in order, excepting a true frame pointer. */
  
        if (! eh_ofs)
! 	{
! 	  mem = gen_rtx_MEM (DImode, plus_constant(sa_reg, reg_offset));
! 	  MEM_ALIAS_SET (mem) = alpha_sr_alias_set;
!           FRP (emit_move_insn (gen_rtx_REG (DImode, REG_RA), mem));
! 	}
        reg_offset += 8;
        imask &= ~(1L << REG_RA);
  
--- 5155,5165 ----
  	  
        /* Restore registers in order, excepting a true frame pointer. */
  
+       mem = gen_rtx_MEM (DImode, plus_constant (sa_reg, reg_offset));
        if (! eh_ofs)
!         MEM_ALIAS_SET (mem) = alpha_sr_alias_set;
!       FRP (emit_move_insn (gen_rtx_REG (DImode, REG_RA), mem));
! 
        reg_offset += 8;
        imask &= ~(1L << REG_RA);
  
Index: alpha/alpha.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/alpha/alpha.h,v
retrieving revision 1.113
diff -c -p -d -r1.113 alpha.h
*** alpha.h	2001/01/01 20:35:26	1.113
--- alpha.h	2001/03/28 11:06:23
*************** extern struct alpha_compare alpha_compar
*** 1213,1221 ****
  
  struct machine_function
  {
-   /* An offset to apply to the stack pointer when unwinding from EH.  */
-   struct rtx_def *eh_epilogue_sp_ofs;
- 
    /* If non-null, this rtx holds the return address for the function.  */
    struct rtx_def *ra_rtx;
  };
--- 1213,1218 ----
*************** do {						\
*** 1342,1347 ****
--- 1339,1351 ----
  /* Before the prologue, RA lives in $26. */
  #define INCOMING_RETURN_ADDR_RTX  gen_rtx_REG (Pmode, 26)
  #define DWARF_FRAME_RETURN_COLUMN DWARF_FRAME_REGNUM (26)
+ 
+ /* Describe how we implement __builtin_eh_return.  */
+ #define EH_RETURN_DATA_REGNO(N)	((N) < 4 ? (N) + 16 : INVALID_REGNUM)
+ #define EH_RETURN_STACKADJ_RTX	gen_rtx_REG (Pmode, 28)
+ #define EH_RETURN_HANDLER_RTX \
+   gen_rtx_MEM (Pmode, plus_constant (stack_pointer_rtx, \
+ 				     current_function_outgoing_args_size))
  
  /* Addressing modes, and classification of registers for them.  */
  
Index: alpha/alpha.md
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/alpha/alpha.md,v
retrieving revision 1.138
diff -c -p -d -r1.138 alpha.md
*** alpha.md	2001/03/07 18:50:26	1.138
--- alpha.md	2001/03/28 11:06:23
***************
*** 5900,5921 ****
    DONE;
  }")
  
- (define_expand "eh_epilogue"
-   [(use (match_operand:DI 0 "register_operand" "r"))
-    (use (match_operand:DI 1 "register_operand" "r"))
-    (use (match_operand:DI 2 "register_operand" "r"))]
-   "! TARGET_OPEN_VMS"
-   "
- {
-   cfun->machine->eh_epilogue_sp_ofs = operands[1];
-   if (GET_CODE (operands[2]) != REG || REGNO (operands[2]) != 26)
-     {
-       rtx ra = gen_rtx_REG (Pmode, 26);
-       emit_move_insn (ra, operands[2]);
-       operands[2] = ra;
-     }
- }")
- 
  ;; In creating a large stack frame, NT _must_ use ldah+lda to load
  ;; the frame size into a register.  We use this pattern to ensure
  ;; we get lda instead of addq.
--- 5900,5905 ----
***************
*** 5978,5985 ****
  (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")])
  
  (define_expand "nonlocal_goto_receiver"
--- 5962,5969 ----
  (define_insn "exception_receiver"
    [(unspec_volatile [(const_int 0)] 7)]
    "! TARGET_OPEN_VMS && ! TARGET_WINDOWS_NT"
!   "ldgp $29,0($26)"
!   [(set_attr "length" "8")
     (set_attr "type" "multi")])
  
  (define_expand "nonlocal_goto_receiver"
Index: alpha/linux.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/alpha/linux.h,v
retrieving revision 1.21
diff -c -p -d -r1.21 linux.h
*** linux.h	2000/11/09 23:57:41	1.21
--- linux.h	2001/03/28 11:06:23
*************** SUB_CPP_PREDEFINES
*** 44,46 ****
--- 44,97 ----
  
  /* Define this so that all GNU/Linux targets handle the same pragmas.  */
  #define HANDLE_PRAGMA_PACK_PUSH_POP
+ 
+ /* Do code reading to identify a signal frame, and set the frame
+    state data appropriately.  See unwind-dw2.c for the structs.  */
+ 
+ #ifdef IN_LIBGCC2
+ #include <signal.h>
+ #include <sys/ucontext.h>
+ #endif
+ 
+ #define MD_FALLBACK_FRAME_STATE_FOR(CONTEXT, FS, SUCCESS)		\
+   do {									\
+     unsigned int *pc_ = (CONTEXT)->ra;					\
+     struct sigcontext *sc_;						\
+     long new_cfa_, i_;							\
+ 									\
+     if (pc_[0] != 0x47fe0410		/* mov $30,$16 */		\
+         || pc_[2] != 0x00000083		/* callsys */)			\
+       break;								\
+     if (pc_[1] == 0x201f0067)		/* lda $0,NR_sigreturn */	\
+       sc_ = (CONTEXT)->cfa;						\
+     else if (pc_[1] == 0x201f015f)	/* lda $0,NR_rt_sigreturn */	\
+       {									\
+ 	struct rt_sigframe {						\
+ 	  struct siginfo info;						\
+ 	  struct ucontext uc;						\
+ 	} *rt_ = (CONTEXT)->cfa;					\
+ 	sc_ = &rt_->uc.uc_mcontext;					\
+       }									\
+     else								\
+       break;								\
+     new_cfa_ = sc_->sc_regs[30];					\
+     (FS)->cfa_how = CFA_REG_OFFSET;					\
+     (FS)->cfa_reg = 30;							\
+     (FS)->cfa_offset = new_cfa_ - (long) (CONTEXT)->cfa;		\
+     for (i_ = 0; i_ < 30; ++i_)						\
+       {									\
+ 	(FS)->regs.reg[i_].how = REG_SAVED_OFFSET;			\
+ 	(FS)->regs.reg[i_].loc.offset					\
+ 	  = (long)&sc_->sc_regs[i_] - new_cfa_;				\
+       }									\
+     for (i_ = 0; i_ < 31; ++i_)						\
+       {									\
+ 	(FS)->regs.reg[i_+32].how = REG_SAVED_OFFSET;			\
+ 	(FS)->regs.reg[i_+32].loc.offset				\
+ 	  = (long)&sc_->sc_fpregs[i_] - new_cfa_;			\
+       }									\
+     (FS)->regs.reg[31].how = REG_SAVED_OFFSET;				\
+     (FS)->regs.reg[31].loc.offset = (long)&sc_->sc_pc - new_cfa_;	\
+     (FS)->retaddr_column = 31;						\
+     goto SUCCESS;							\
+   } while (0)


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]