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