arm interrupt handler fixes

John Aycock aycock@cpsc.ucalgary.ca
Tue Mar 26 12:46:00 GMT 2002


Fixes some problems with generating code for ARM interrupt
handlers: not understanding the "interrupt" attribute (among
others), and failing to save the correct registers.  Still need
to compile with -fomit-frame-pointer however, and declaring
nested functions to be interrupt handlers is guaranteed to break.

John

*** gcc-3.0.3/gcc/config/arm/arm.c-orig	Fri Mar 22 14:01:24 2002
--- gcc-3.0.3/gcc/config/arm/arm.c	Tue Mar 26 13:28:46 2002
***************
*** 4,9 ****
--- 4,10 ----
     Contributed by Pieter `Tiggr' Schoenmakers (rcpieter@win.tue.nl)
     and Martin Simmons (@harleqn.co.uk).
     More major hacks by Richard Earnshaw (rearnsha@arm.com).
+    Some interrupt code fixes by John Aycock (aycock@cpsc.ucalgary.ca).
  
  This file is part of GNU CC.
  
*************** multi_register_push (op, mode)
*** 4093,4117 ****
       not Thumb mode, and that the caller wishes to be returned to in
       ARM mode.  */
  int
! arm_valid_machine_decl_attribute (decl, attr, args)
       tree decl;
!      tree attr;
       tree args;
  {
    /* The interrupt attribute can take args, so check for it before
       rejecting other attributes on the grounds that they did have args.  */
!   if (is_attribute_p ("isr", attr)
!       || is_attribute_p ("interrupt", attr))
      return TREE_CODE (decl) == FUNCTION_DECL;
  
    if (args != NULL_TREE)
      return 0;
  
!   if (is_attribute_p ("naked", attr))
      return TREE_CODE (decl) == FUNCTION_DECL;
  
  #ifdef ARM_PE
!   if (is_attribute_p ("interfacearm", attr))
      return TREE_CODE (decl) == FUNCTION_DECL;
  #endif /* ARM_PE */
    
--- 4094,4119 ----
       not Thumb mode, and that the caller wishes to be returned to in
       ARM mode.  */
  int
! arm_valid_decl_attribute_p (decl, attributes, name, args)
       tree decl;
!      tree attributes;
!      tree name;
       tree args;
  {
    /* The interrupt attribute can take args, so check for it before
       rejecting other attributes on the grounds that they did have args.  */
!   if (is_attribute_p ("isr", name)
!       || is_attribute_p ("interrupt", name))
      return TREE_CODE (decl) == FUNCTION_DECL;
  
    if (args != NULL_TREE)
      return 0;
  
!   if (is_attribute_p ("naked", name))
      return TREE_CODE (decl) == FUNCTION_DECL;
  
  #ifdef ARM_PE
!   if (is_attribute_p ("interfacearm", name))
      return TREE_CODE (decl) == FUNCTION_DECL;
  #endif /* ARM_PE */
    
*************** arm_compute_save_reg_mask ()
*** 6949,6961 ****
    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
      {
--- 6951,6966 ----
    if (IS_VOLATILE (func_type))
      return save_reg_mask;
  
!   if (IS_INTERRUPT (func_type))
      {
!       /* Interrupt routines always have r13-r14 banked; FIQ handlers
!          also have r8-r12 banked.  Everything else must be saved. */
!       for (reg = 0; reg < (ARM_FUNC_TYPE (func_type) == ARM_FT_FIQ ? 8 : 13); reg++)
  	if (regs_ever_live[reg])
  	  save_reg_mask |= (1 << reg);
+ 
+       /* Don't save LR and PC; they're banked. */
+       save_reg_mask &= ~((1 << LR_REGNUM) | (1 << PC_REGNUM));
      }
    else
      {
*** gcc-3.0.3/gcc/config/arm/arm.h-orig	Fri Mar 22 14:01:28 2002
--- gcc-3.0.3/gcc/config/arm/arm.h	Fri Mar 22 14:04:14 2002
*************** extern const char * arm_pic_register_str
*** 2550,2555 ****
--- 2550,2558 ----
     offset.  */
  extern int making_const_table;
  
+ #define VALID_MACHINE_DECL_ATTRIBUTE(DECL, ATTRIBUTES, NAME, ARGS) \
+   (arm_valid_decl_attribute_p (DECL, ATTRIBUTES, NAME, ARGS))
+ 
  /* If defined, a C expression whose value is nonzero if IDENTIFIER
     with arguments ARGS is a valid machine specific attribute for TYPE.
     The attributes in ATTRIBUTES have previously been assigned to TYPE.  */
*** gcc-3.0.3/gcc/config/arm/arm-protos.h-orig	Fri Mar 22 14:14:10 2002
--- gcc-3.0.3/gcc/config/arm/arm-protos.h	Fri Mar 22 14:14:38 2002
*************** extern unsigned long arm_current_func_ty
*** 38,44 ****
  
  #ifdef TREE_CODE
  extern int    arm_return_in_memory	PARAMS ((tree));
! extern int    arm_valid_machine_decl_attribute	PARAMS ((tree, tree, tree));
  extern int    arm_comp_type_attributes	PARAMS ((tree, tree));
  extern int    arm_valid_type_attribute_p PARAMS ((tree, tree, tree, tree));
  extern void   arm_set_default_type_attributes	PARAMS ((tree));
--- 38,44 ----
  
  #ifdef TREE_CODE
  extern int    arm_return_in_memory	PARAMS ((tree));
! extern int    arm_valid_decl_attribute_p	PARAMS ((tree, tree, tree, tree));
  extern int    arm_comp_type_attributes	PARAMS ((tree, tree));
  extern int    arm_valid_type_attribute_p PARAMS ((tree, tree, tree, tree));
  extern void   arm_set_default_type_attributes	PARAMS ((tree));



More information about the Gcc-patches mailing list