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]

ARM ISR routines. [v2]


Hi Guys,

  OK, I have been persuaded that we need to support using the frame
  pointer inside interrupt handler functions, so he is the modified
  patch.  The patch is the same as the last one except that now if the
  frame pointer is needed (including the case twhen stack frames are
  requested) the code will push the IP register before corrupting and
  then pop it at the end of the function.

  I have applied this version of the patch.

Cheers
        Nick

2001-06-24  Nick Clifton  <nickc@cambridge.redhat.com>

	* config/arm/arm.c (arm_compute_save_reg_mask): For FIQ interrupt
	handlers examine register r0-r7, for other interrupt handlers
	examine r0-r12.  If the interrupt handler is not a leaf function
	save all call clobbered registers.
	(arm_output_epilogue): If the prologue has pushed the IP register,
	restore it here.
	(Arm_expand_prologue): For interrupt functions that need the frame
	pointer, push the IP register before it is corrupted.

	* config/arm/arm.h (ARM_SIGN_EXTEND): Fix compile time warnings
	about the use of signed and unsigned quantities in a conditional.

Index: arm.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/arm/arm.c,v
retrieving revision 1.147
diff -p -r1.147 arm.c
*** arm.c	2001/06/22 17:38:19	1.147
--- arm.c	2001/06/24 09:37:40
*************** Boston, MA 02111-1307, USA.  */
*** 43,48 ****
--- 43,49 ----
  #include "ggc.h"
  #include "except.h"
  #include "c-pragma.h"
+ #include "integrate.h"
  #include "tm_p.h"
  
  /* Forward definitions of types.  */
*************** arm_compute_save_reg_mask ()
*** 6931,6942 ****
    if (IS_VOLATILE (func_type))
      return save_reg_mask;
  
!   if (ARM_FUNC_TYPE (func_type) == ARM_FT_ISR)
      {
!       /* FIQ handlers have registers r8 - r12 banked, so
! 	 we only need to check r0 - r7, they must save them.  */
!       for (reg = 0; reg < 8; reg++)
! 	if (regs_ever_live[reg])
  	  save_reg_mask |= (1 << reg);
      }
    else
--- 6932,6960 ----
    if (IS_VOLATILE (func_type))
      return save_reg_mask;
  
!   if (IS_INTERRUPT (func_type))
      {
!       unsigned int max_reg;
!       
!       /* Interrupt functions must not corrupt any registers,
! 	 even call clobbered ones.  If this is a leaf function
! 	 we can just examine the registers used by the RTL, but
! 	 otherwise we have to assume that whatever function is
! 	 called might clobber anything, and so we have to save
! 	 all the call-clobbered registers as well.  */
!       if (ARM_FUNC_TYPE (func_type) == ARM_FT_FIQ)
! 	/* FIQ handlers have registers r8 - r12 banked, so
! 	   we only need to check r0 - r7, Normal ISRs only
! 	   bank r14 and r15, so ew must check up to r12.
! 	   r13 is the stack pointer which is always preserved,
! 	   so we do not need to consider it here.  */
! 	max_reg = 7;
!       else
! 	max_reg = 12;
! 	
!       for (reg = 0; reg <= max_reg; reg++)
! 	if (regs_ever_live[reg]
! 	    || (! current_function_is_leaf && call_used_regs [reg]))
  	  save_reg_mask |= (1 << reg);
      }
    else
*************** arm_output_epilogue (really_return)
*** 7410,7415 ****
--- 7428,7438 ----
  	saved_regs_mask &= ~ (1 << PC_REGNUM);
        
        print_multi_reg (f, "ldmea\t%r", FP_REGNUM, saved_regs_mask);
+ 
+       if (IS_INTERRUPT (func_type))
+ 	/* Interrupt handlers will have pushed the
+ 	   IP onto the stack, so restore it now.  */
+ 	print_multi_reg (f, "ldmea\t%r", SP_REGNUM, 1 << IP_REGNUM);
      }
    else
      {
*************** arm_expand_prologue ()
*** 7783,7789 ****
  
    if (frame_pointer_needed)
      {
!       if (IS_NESTED (func_type))
  	{
  	  /* The Static chain register is the same as the IP register
  	     used as a scratch register during stack frame creation.
--- 7806,7820 ----
  
    if (frame_pointer_needed)
      {
!       if (IS_INTERRUPT (func_type))
! 	{
! 	  /* Interrupt functions must not corrupt any registers.
! 	     Creating a frame pointer however, corrupts the IP
! 	     register, so we must push it first.  */
! 	  insn = emit_multi_reg_push (1 << IP_REGNUM);
! 	  RTX_FRAME_RELATED_P (insn) = 1;
! 	}
!       else if (IS_NESTED (func_type))
  	{
  	  /* The Static chain register is the same as the IP register
  	     used as a scratch register during stack frame creation.
*************** replace_symbols_in_block (block, orig, n
*** 8925,8931 ****
  	      )
  	    continue;
  
! 	  DECL_RTL (sym) = new;
  	}
        
        replace_symbols_in_block (BLOCK_SUBBLOCKS (block), orig, new);
--- 8956,8962 ----
  	      )
  	    continue;
  
! 	  SET_DECL_RTL (sym, new);
  	}
        
        replace_symbols_in_block (BLOCK_SUBBLOCKS (block), orig, new);
Index: arm.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/arm/arm.h,v
retrieving revision 1.105
diff -p -r1.105 arm.h
*** arm.h	2001/06/22 17:38:19	1.105
--- arm.h	2001/06/24 09:37:45
*************** extern const char * structure_size_strin
*** 969,976 ****
     If we have to have a frame pointer we might as well make use of it.
     APCS says that the frame pointer does not need to be pushed in leaf
     functions, or simple tail call functions.  */
! #define FRAME_POINTER_REQUIRED						\
!   (current_function_has_nonlocal_label					\
     || (TARGET_ARM && TARGET_APCS_FRAME && ! leaf_function_p ()))
  
  /* Return number of consecutive hard regs needed starting at reg REGNO
--- 969,976 ----
     If we have to have a frame pointer we might as well make use of it.
     APCS says that the frame pointer does not need to be pushed in leaf
     functions, or simple tail call functions.  */
! #define FRAME_POINTER_REQUIRED					\
!   (current_function_has_nonlocal_label				\
     || (TARGET_ARM && TARGET_APCS_FRAME && ! leaf_function_p ()))
  
  /* Return number of consecutive hard regs needed starting at reg REGNO
*************** extern int making_const_table;
*** 2758,2769 ****
  #define HOST_UINT(x) ((unsigned HOST_WIDE_INT) x)
  #endif
  
! #define ARM_SIGN_EXTEND(x)  ((HOST_WIDE_INT)	\
!   (HOST_BITS_PER_WIDE_INT <= 32 ? (x)		\
!    : (((x) & HOST_UINT (0xffffffff)) |		\
!       (((x) & HOST_UINT (0x80000000))		\
!        ? ((~ HOST_INT (0))			\
! 	  & ~ HOST_UINT(0xffffffff))		\
         : 0))))
  
  /* Output the address of an operand.  */
--- 2758,2769 ----
  #define HOST_UINT(x) ((unsigned HOST_WIDE_INT) x)
  #endif
  
! #define ARM_SIGN_EXTEND(x)  ((HOST_WIDE_INT)			\
!   (HOST_BITS_PER_WIDE_INT <= 32 ? (unsigned HOST_WIDE_INT) (x)	\
!    : ((((unsigned HOST_WIDE_INT)(x)) & HOST_UINT (0xffffffff)) |\
!       ((((unsigned HOST_WIDE_INT)(x)) & HOST_UINT (0x80000000))	\
!        ? ((~ HOST_UINT (0))					\
! 	  & ~ HOST_UINT(0xffffffff))				\
         : 0))))
  
  /* Output the address of an operand.  */




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