This is the mail archive of the crossgcc@sourceware.cygnus.com mailing list for the crossgcc project.

See the CrossGCC FAQ for lots more infromation.


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

m68k attribute interrupt patch


OK! I have made a patch from the latest files in the GCC CVS for the
attribute interrupt flag based on Michael Schwingen's and Kai Ruottu's
patches. If what I have done is all in good order can one of us post
it to the gcc-patches list to have it committed somehow??? I think
I have done everything that is required (fingers crossed).

Changelog:

	* config/m68k/m68k.h (m68k_valid_machine_decl_attribute) declared.
	(VALID_MACHINE_DECL_ATTRIBUTE) define.
	* config/m68k/m68k.c (MUST_SAVE_REGISTER) defined.
	(output_function_prologue) interrupt_handler declared and
initialised
	and use MUST_SAVE_REGISTER macro in place of looking in the
regs_ever_live
	and call_used_regs arrays.
	(use_return_insn) interrupt_handler declared and initialised and use
	MUST_SAVE_REGISTER macro in place of looking in the regs_ever_live
	and call_used_regs arrays.
	(output_function_epilogue) interrupt_handler declared and
initialised
	and use MUST_SAVE_REGISTER macro in place of looking in the
regs_ever_live
	and call_used_regs arrays.
	(m68k_valid_machine_decl_attribute) function added.	
	(m68k_interrupt_function_p) function added.


*** m68k.h.orig	Thu Feb 24 10:31:55 2000
--- m68k.h	Thu Feb 24 10:37:45 2000
*************** extern int m68k_align_jumps;
*** 2162,2167 ****
--- 2162,2174 ----
  extern int m68k_align_funcs;
  extern int m68k_last_compare_had_fp_operands;
  
+ /* A C expression whose value is nonzero if IDENTIFIER with arguments ARGS
+    is a valid machine specific attribute for DECL.
+    The attributes in ATTRIBUTES have previously been assigned to DECL.  */
+ extern int m68k_valid_machine_decl_attribute ();
+ #define VALID_MACHINE_DECL_ATTRIBUTE(DECL, ATTRIBUTES, IDENTIFIER, ARGS) \
+ m68k_valid_machine_decl_attribute (DECL, ATTRIBUTES, IDENTIFIER, ARGS)
+ 

  /*
  Local variables:
*** m68k.c.orig	Thu Feb 24 10:30:56 2000
--- m68k.c	Thu Feb 24 10:49:20 2000
***************
*** 1,5 ****
--- 1,6 ----
  /* Subroutines for insn-output.c for Motorola 68000 family.
     Copyright (C) 1987, 93-99, 2000 Free Software Foundation, Inc.
+    Modified by Michael Schwingen <rincewind@discworld.dascon.de> and Kai
Ruottu <karuottu@freenet.hut.fi>
  
  This file is part of GNU CC.
  
*************** Boston, MA 02111-1307, USA.  */
*** 38,43 ****
--- 39,54 ----
  /* Needed for use_return_insn.  */
  #include "flags.h"
  
+ #define MUST_SAVE_REGISTER(regno)					\
+  (! TREE_THIS_VOLATILE (current_function_decl)
\
+    && (regno != STACK_POINTER_REGNUM)					\
+    /* Save any call saved register that was used.  */			\
+    && (regs_ever_live[regno] && !call_used_regs[regno])
\
+    /* Save any register used in an interrupt handler.	 */		\
+    || (regs_ever_live[regno] && interrupt_handler)			\
+    /* Save call clobbered registers in non-leaf interrupt handlers. */
\
+    || (call_used_regs[regno] && interrupt_handler &&
!current_function_is_leaf))
+ 
  #ifdef SUPPORT_SUN_FPA
  
  /* Index into this array by (register number >> 3) to find the
*************** output_function_prologue (stream, size)
*** 151,156 ****
--- 162,168 ----
    extern char call_used_regs[];
    int fsize = (size + 3) & -4;
    int cfa_offset = INCOMING_FRAME_SP_OFFSET, cfa_store_offset =
cfa_offset;
+   int interrupt_handler = m68k_interrupt_function_p
(current_function_decl);
  
    /* If the stack limit is a symbol, we can check it here,
       before actually allocating the space.  */
*************** output_function_prologue (stream, size)
*** 301,307 ****
      }
  #ifdef SUPPORT_SUN_FPA
    for (regno = 24; regno < 56; regno++)
!     if (regs_ever_live[regno] && ! call_used_regs[regno])
        {
  #ifdef MOTOROLA
  	asm_fprintf (stream, "\tfpmovd %s,-(%Rsp)\n",
--- 313,319 ----
      }
  #ifdef SUPPORT_SUN_FPA
    for (regno = 24; regno < 56; regno++)
!     if (MUST_SAVE_REGISTER(regno))
        {
  #ifdef MOTOROLA
  	asm_fprintf (stream, "\tfpmovd %s,-(%Rsp)\n",
*************** output_function_prologue (stream, size)
*** 327,333 ****
    if (TARGET_68881)
      {
        for (regno = 16; regno < 24; regno++)
! 	if (regs_ever_live[regno] && ! call_used_regs[regno])
  	  {
  	    mask |= 1 << (regno - 16);
  	    num_saved_regs++;
--- 339,345 ----
    if (TARGET_68881)
      {
        for (regno = 16; regno < 24; regno++)
! 	if (MUST_SAVE_REGISTER(regno))
  	  {
  	    mask |= 1 << (regno - 16);
  	    num_saved_regs++;
*************** output_function_prologue (stream, size)
*** 360,366 ****
        num_saved_regs = 0;
      }
    for (regno = 0; regno < 16; regno++)
!     if (regs_ever_live[regno] && ! call_used_regs[regno])
        {
          mask |= 1 << (15 - regno);
          num_saved_regs++;
--- 372,378 ----
        num_saved_regs = 0;
      }
    for (regno = 0; regno < 16; regno++)
!     if (MUST_SAVE_REGISTER(regno))
        {
          mask |= 1 << (15 - regno);
          num_saved_regs++;
*************** int
*** 515,520 ****
--- 527,533 ----
  use_return_insn ()
  {
    int regno;
+   int interrupt_handler = m68k_interrupt_function_p
(current_function_decl);
  
    if (!reload_completed || frame_pointer_needed || get_frame_size () != 0)
      return 0;
*************** use_return_insn ()
*** 523,529 ****
       separate layout routine to perform the common work.  */
    
    for (regno = 0 ; regno < FIRST_PSEUDO_REGISTER ; regno++)
!     if (regs_ever_live[regno] && ! call_used_regs[regno])
        return 0;
  
    if (flag_pic && current_function_uses_pic_offset_table)
--- 536,542 ----
       separate layout routine to perform the common work.  */
    
    for (regno = 0 ; regno < FIRST_PSEUDO_REGISTER ; regno++)
!     if (MUST_SAVE_REGISTER(regno))
        return 0;
  
    if (flag_pic && current_function_uses_pic_offset_table)
*************** output_function_epilogue (stream, size)
*** 554,559 ****
--- 567,573 ----
    int big = 0;
    rtx insn = get_last_insn ();
    int restore_from_sp = 0;
+   int interrupt_handler = m68k_interrupt_function_p
(current_function_decl);
    
    /* If the last insn was a BARRIER, we don't have to write any code.  */
    if (GET_CODE (insn) == NOTE)
*************** output_function_epilogue (stream, size)
*** 579,585 ****
    nregs = 0;  fmask = 0; fpoffset = 0;
  #ifdef SUPPORT_SUN_FPA
    for (regno = 24 ; regno < 56 ; regno++)
!     if (regs_ever_live[regno] && ! call_used_regs[regno])
        nregs++;
    fpoffset = nregs * 8;
  #endif
--- 593,599 ----
    nregs = 0;  fmask = 0; fpoffset = 0;
  #ifdef SUPPORT_SUN_FPA
    for (regno = 24 ; regno < 56 ; regno++)
!     if (MUST_SAVE_REGISTER(regno))
        nregs++;
    fpoffset = nregs * 8;
  #endif
*************** output_function_epilogue (stream, size)
*** 587,593 ****
    if (TARGET_68881)
      {
        for (regno = 16; regno < 24; regno++)
! 	if (regs_ever_live[regno] && ! call_used_regs[regno])
  	  {
  	    nregs++;
  	    fmask |= 1 << (23 - regno);
--- 601,607 ----
    if (TARGET_68881)
      {
        for (regno = 16; regno < 24; regno++)
! 	if (MUST_SAVE_REGISTER(regno))
  	  {
  	    nregs++;
  	    fmask |= 1 << (23 - regno);
*************** output_function_epilogue (stream, size)
*** 598,604 ****
    if (frame_pointer_needed)
      regs_ever_live[FRAME_POINTER_REGNUM] = 0;
    for (regno = 0; regno < 16; regno++)
!     if (regs_ever_live[regno] && ! call_used_regs[regno])
        {
          nregs++;
  	mask |= 1 << regno;
--- 612,618 ----
    if (frame_pointer_needed)
      regs_ever_live[FRAME_POINTER_REGNUM] = 0;
    for (regno = 0; regno < 16; regno++)
!     if (MUST_SAVE_REGISTER(regno))
        {
          nregs++;
  	mask |= 1 << regno;
*************** output_function_epilogue (stream, size)
*** 753,759 ****
      }
    if (fpoffset != 0)
      for (regno = 55; regno >= 24; regno--)
!       if (regs_ever_live[regno] && ! call_used_regs[regno])
          {
  	  if (big)
  	    {
--- 767,773 ----
      }
    if (fpoffset != 0)
      for (regno = 55; regno >= 24; regno--)
!       if (MUST_SAVE_REGISTER(regno))
          {
  	  if (big)
  	    {
*************** output_function_epilogue (stream, size)
*** 863,873 ****
--- 877,894 ----
  #endif
  	}
      }
+   if (interrupt_handler)
+   {
+     fprintf (stream, "\trte\n");
+   }
+   else
+   {
      if (current_function_pops_args)
        asm_fprintf (stream, "\trtd %0I%d\n", current_function_pops_args);
      else
        fprintf (stream, "\trts\n");
    }
+ }
  

  /* Similar to general_operand, but exclude stack_pointer_rtx.  */
  
*************** output_xorsi3 (operands)
*** 3590,3592 ****
--- 3611,3656 ----
      }
    return "eor%.l %2,%0";
  }
+ 
+ /* Return nonzero if ATTR is a valid attribute for DECL.
+    ATTRIBUTES are any existing attributes and ARGS are the arguments
+    supplied with ATTR.
+ 
+    Supported attributes:
+ 
+    interrupt -- specifies this function is an interrupt handler.
+ */
+ 
+ int
+ m68k_valid_machine_decl_attribute (decl, attributes, attr, args)
+      tree decl;
+      tree attributes;
+      tree attr;
+      tree args;
+ {
+   if (args != NULL_TREE)
+     return 0;
+ 
+   if (is_attribute_p ("interrupt", attr))
+     return TREE_CODE (decl) == FUNCTION_DECL;
+ 
+   return 0;
+ }
+ 
+ /* Return nonzero if FUNC is an interrupt function as specified by the
+    "interrupt" attribute.  */
+ 
+ int
+ m68k_interrupt_function_p(func)
+      tree func;
+ {
+   tree a;
+ 
+   if (TREE_CODE (func) != FUNCTION_DECL)
+     return 0;
+ 
+   a = lookup_attribute ("interrupt", DECL_MACHINE_ATTRIBUTES (func));
+   return (a != NULL_TREE);
+ }
+ 
+

------
Want more information?  See the CrossGCC FAQ, http://www.objsw.com/CrossGCC/
Want to unsubscribe? Send a note to crossgcc-unsubscribe@sourceware.cygnus.com


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