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]
Other format: [Raw text]

[patch] h8300: Add saveall attribute.


Hi,

Attached is a patch to add saveall attribute.

The saveall attribute is an attribute for a function that need to save
all registers except the stack pointer regardless of whether each
individual register is used or not.

Without this patch, if one wishes to define an interrupt handler that
saves all registers, he/she would have to write

void foo () __attribute__((interrupt_handler));

#pragma saveall

void
foo ()
{
  do something...
}

That is, there are two different places that talk about the attributes
of function foo.  With this patch, all of these can go into one place.
Specifically, a single __attribute__ is enough like so:

void foo () __attribute__((interrupt_handler, saveall));

void
foo ()
{
  do something...
}

Tested on h8300 port.  Committed.

Kazu Hirata

2003-10-22  Kazu Hirata  <kazu@cs.umass.edu>

	* config/h8300/h8300.c (h8300_output_function_epilogue): Remove.
	(h8300_saveall_function_p): New.
	(h8300_insert_attributes): Insert the saveall attribute if
	#pragma saveall is specified.
	(h8300_attribute_table): Add saveall.
	(TARGET_ASM_FUNCTION_EPILOGUE): Remove.
	* doc/extend.texi: Mention the saveall attribute.

Index: config/h8300/h8300.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/h8300/h8300.c,v
retrieving revision 1.252
diff -u -r1.252 h8300.c
*** config/h8300/h8300.c	12 Oct 2003 20:49:43 -0000	1.252
--- config/h8300/h8300.c	22 Oct 2003 18:27:01 -0000
***************
*** 49,54 ****
--- 49,55 ----
  /* Forward declarations.  */
  static const char *byte_reg (rtx, int);
  static int h8300_interrupt_function_p (tree);
+ static int h8300_saveall_function_p (tree);
  static int h8300_monitor_function_p (tree);
  static int h8300_os_task_function_p (tree);
  static void dosize (int, unsigned int);
***************
*** 346,352 ****
    (regno < SP_REG							\
     /* No need to save registers if this function will not return.  */	\
     && ! TREE_THIS_VOLATILE (current_function_decl)			\
!    && (pragma_saveall							\
         /* Save any call saved register that was used.  */		\
         || (regs_ever_live[regno] && !call_used_regs[regno])		\
         /* Save the frame pointer if it was used.  */			\
--- 347,353 ----
    (regno < SP_REG							\
     /* No need to save registers if this function will not return.  */	\
     && ! TREE_THIS_VOLATILE (current_function_decl)			\
!    && (h8300_saveall_function_p (current_function_decl)			\
         /* Save any call saved register that was used.  */		\
         || (regs_ever_live[regno] && !call_used_regs[regno])		\
         /* Save the frame pointer if it was used.  */			\
***************
*** 635,649 ****
      pop (FRAME_POINTER_REGNUM);
  }
  
- /* Output assembly language code for the function epilogue.  */
- 
- static void
- h8300_output_function_epilogue (FILE *file ATTRIBUTE_UNUSED,
- 				HOST_WIDE_INT size ATTRIBUTE_UNUSED)
- {
-   pragma_saveall = 0;
- }
- 
  /* Return nonzero if the current function is an interrupt
     function.  */
  
--- 636,641 ----
***************
*** 4101,4106 ****
--- 4093,4113 ----
    return a != NULL_TREE;
  }
  
+ /* Return nonzero if FUNC is a saveall function as specified by the
+    "saveall" attribute.  */
+ 
+ static int
+ h8300_saveall_function_p (tree func)
+ {
+   tree a;
+ 
+   if (TREE_CODE (func) != FUNCTION_DECL)
+     return 0;
+ 
+   a = lookup_attribute ("saveall", DECL_ATTRIBUTES (func));
+   return a != NULL_TREE;
+ }
+ 
  /* Return nonzero if FUNC is an OS_Task function as specified
     by the "OS_Task" attribute.  */
  
***************
*** 4176,4195 ****
    return a != NULL_TREE;
  }
  
! /* Generate an 'interrupt_handler' attribute for decls.  */
  
  static void
  h8300_insert_attributes (tree node, tree *attributes)
  {
!   if (!pragma_interrupt
!       || TREE_CODE (node) != FUNCTION_DECL)
!     return;
  
!   pragma_interrupt = 0;
  
!   /* Add an 'interrupt_handler' attribute.  */
!   *attributes = tree_cons (get_identifier ("interrupt_handler"),
! 			   NULL, *attributes);
  }
  
  /* Supported attributes:
--- 4183,4214 ----
    return a != NULL_TREE;
  }
  
! /* Generate an 'interrupt_handler' attribute for decls.  We convert
!    all the pragmas to corresponding attributes.  */
  
  static void
  h8300_insert_attributes (tree node, tree *attributes)
  {
!   if (TREE_CODE (node) == FUNCTION_DECL)
!     {
!       if (pragma_interrupt)
! 	{
! 	  pragma_interrupt = 0;
  
! 	  /* Add an 'interrupt_handler' attribute.  */
! 	  *attributes = tree_cons (get_identifier ("interrupt_handler"),
! 				   NULL, *attributes);
! 	}
  
!       if (pragma_saveall)
! 	{
! 	  pragma_saveall = 0;
! 
! 	  /* Add an 'saveall' attribute.  */
! 	  *attributes = tree_cons (get_identifier ("saveall"),
! 				   NULL, *attributes);
! 	}
!     }
  }
  
  /* Supported attributes:
***************
*** 4197,4202 ****
--- 4216,4224 ----
     interrupt_handler: output a prologue and epilogue suitable for an
     interrupt handler.
  
+    saveall: output a prologue and epilogue that saves and restores
+    all registers except the stack pointer.
+ 
     function_vector: This function should be called through the
     function vector.
  
***************
*** 4210,4215 ****
--- 4232,4238 ----
  {
    /* { name, min_len, max_len, decl_req, type_req, fn_type_req, handler } */
    { "interrupt_handler", 0, 0, true,  false, false, h8300_handle_fndecl_attribute },
+   { "saveall",           0, 0, true,  false, false, h8300_handle_fndecl_attribute },
    { "OS_Task",           0, 0, true,  false, false, h8300_handle_fndecl_attribute },
    { "monitor",           0, 0, true,  false, false, h8300_handle_fndecl_attribute },
    { "function_vector",   0, 0, true,  false, false, h8300_handle_fndecl_attribute },
***************
*** 4525,4533 ****
  
  #undef TARGET_ASM_ALIGNED_HI_OP
  #define TARGET_ASM_ALIGNED_HI_OP "\t.word\t"
- 
- #undef TARGET_ASM_FUNCTION_EPILOGUE
- #define TARGET_ASM_FUNCTION_EPILOGUE h8300_output_function_epilogue
  
  #undef TARGET_ASM_FILE_START
  #define TARGET_ASM_FILE_START h8300_file_start
--- 4548,4553 ----
Index: doc/extend.texi
===================================================================
RCS file: /cvs/gcc/gcc/gcc/doc/extend.texi,v
retrieving revision 1.167
diff -u -r1.167 extend.texi
*** doc/extend.texi	22 Oct 2003 18:22:09 -0000	1.167
--- doc/extend.texi	22 Oct 2003 18:27:06 -0000
***************
*** 2550,2555 ****
--- 2550,2561 ----
  on data in the tiny data section.  Note the tiny data area is limited to
  slightly under 32kbytes of data.
  
+ @item saveall
+ @cindex save all registers on the H8/300, H8/300H, and H8S
+ Use this attribute on the H8/300, H8/300H, and H8S to indicate that
+ all registers except the stack pointer should be saved in the prologue
+ regardless of whether they are used or not.
+ 
  @item signal
  @cindex signal handler functions on the AVR processors
  Use this attribute on the AVR to indicate that the specified


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