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]

Re: math context save for floating point coprocessor and context save switch for interrupt attribute patch.


> Ken Desmet wrote:
> 
> I fount the interrupt attribute patch from Michael Schwingen and Kai
> Ruottu an excellent initiative. It is extremely helpful when you want
> to write exception handlers and interrupt handlers in "C" without the
> need for any complex assembler macros. I found however a few details
> in it that I have changed somewhat to solve a few possible problems
> when compiled for 68020 and successors.

 Nice work from you too, Ken...

 Meanwhile I found another thing still unhandled.

 When the m68k is one of those 'CISC'-processors, it may be that there
isn't any need for a prologue/epilogue, everything the ISR may do is to
only to increment/reset a counter snd to change some bits in memory-
mapped I/O and no CPU-registers will be used :

---------------------- clip
------------------------------------------------------
#include <stdio.h>

#define PBDR		(*(char *) (0xffffd6))
#define ITU_TSR0	(*(char *) (0xffff67))

#define ISR_FUNC	__attribute__((interrupt))

int count;

void ISR_FUNC handle_intr(void)
{
	count++;
	if (count == 400)
	  {
	    PBDR ^= 0x01;
	    count = 0;
	  }
	ITU_TSR0 &= 0xFE;
}
---------------------- clip
------------------------------------------------------

 The generated code from the previous can be (after the fix described
later) :

---------------------- clip
------------------------------------------------------
	.file	"isr_demo.c"
gcc2_compiled.:
__gnu_compiled_c:
.text
	.even
.globl handle_intr
handle_intr:
	addq.l #1,count
	cmp.l #400,count
	jbne .L3
	eor.b #1,16777174
	clr.l count
.L3:
	and.b #254,16777063
	rte
	nop
.comm count,4
---------------------- clip
------------------------------------------------------

 Without the following fixes it would generate just a normal 'rts' using
the 'insert a
return' in the machine description file....

 BTW, try to change the 'count' and the two memory places to be
'volatile' and see
what happens to the previous code.... A 'volatile' should take care that
nothing
will be optimized away, but replacing the direct operations with
'load/change/store/reload'
doesn't sound very sane... This bug is deeply inside the GCC-core, so we
can only pray that
there will appear someone who could fix it...

 Ok, in order to get the info about the current function being an ISR
(for which the
return will be needed) elsewhere, some changes are still needed after
installing
the "FPU-aware" patches Ken provided :

 1. The variable named 'interrupt_handler' should be changed to be a
global one :

---------------------- clip
------------------------------------------------------
*** m68k.c.orig	Thu Aug 19 02:36:02 1999
--- m68k.c	Sat Feb 26 17:47:48 2000
***************
*** 38,43 ****
--- 38,56 ----
  /* Needed for use_return_insn.  */
  #include "flags.h"
  
+ /* Flag to tell if the current function is an interrupt handler. */
+ int interrupt_handler;
+ 
+ #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
---------------------- clip
------------------------------------------------------

 And so all the appearances of 'int interrupt_handler = ...' later need
to be changed to
be only 'interrupt_handler = ...'.


2. It must also be defined 'extern' somewhere in 'm68k.h', so that the
info about it
goes to the routines handling the 'm68k.md' :

---------------------- clip
------------------------------------------------------
***************
*** 2131,2136 ****
--- 2149,2165 ----
  extern void finalize_pic ();
  extern void override_options ();
  
+ /* 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)
+ 
+ extern int interrupt_handler;
+ extern int m68k_interrupt_function_p();
  

  /*
  Local variables:
---------------------- clip
------------------------------------------------------

 3. And finally a patch to 'm68k.md' will be needed :

---------------------- clip
------------------------------------------------------
*** m68k.md.orig	Thu Aug 19 02:36:02 1999
--- m68k.md	Sat Feb 26 17:06:06 2000
***************
*** 6964,6969 ****
--- 6964,6971 ----
    "USE_RETURN_INSN"
    "*
  {
+   if (interrupt_handler)
+     return \"rte\";
    if (current_function_pops_args == 0)
      return \"rts\";
    operands[0] = GEN_INT (current_function_pops_args);
---------------------- clip
------------------------------------------------------

 Let's hope this addition would be useful...

Cheers, Kai



------
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]