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]

[patch] h8300.c: Fix prologue.


Hi,

Attached is a patch to fix function prologue on the h8300 port.

The port has special attribute 'monitor' for functions in which
interrupts are disabled.  Thus, the proogue for monitor functions must
save the current contents of the control register ('ccr') and have
return-from-interrupt ('rte') instruction take care of restoring
'ccr'.  Here is platform-specific notes.

H8/300

The original code has '@(4,sp)', which is wrong.  'ccr' must be saved
to a slot made by 'subs #2,sp', which can be referenced by '@(2,sp)'.

H8/300H

Almost right, except that 'er0' is kept on the stack for the entire
function.  It is enough to keep it only while saving 'ccr'.

H8/S

Was sharing code with H8/300H.  Since H8/S has another control
register 'exr', we need to save it.  Actually restoration of 'exr'
depends on yet another register, accessible as a peripheral.  In a
certain mode, 'rte' restores 'exr'.  Otherwise not.  Ideally, we
should have a switch that specifies which mode we are using.  However,
since IAR's compiler does not have any option on this and simply saves
'exr' every time, I made it the same way.

Personally I do not like having a bunch of special platform-specific
features in C code, but I decided to fix this (instead of deprecating
it) because:

1) It's there (in the gcc tree).

2) Doing restoration of 'ccr' and 'rts' at the same time is hard to do
   using inline assembly code because you have to know how a frame is
   constracted.  The compiler must support it somehow.

One more note.  Since a monitor functino is not an interrupt handler,
it is normally used as a regular function with the only difference
being the disabled interrupt.  It shuold be noted that the frame
computation is completely broken (even before this patch).  Thus if
you try to access an argument that is stored in the stack, your code
won't work.  This patch makes things less broken, but not completely.

OK to apply?

p.s.
Please also review the following unreviewed patch:

http://gcc.gnu.org/ml/gcc-patches/2000-10/msg00810.html

Thanks,

Kazu Hirata


===File ~/gnu/gcc/ChangeLog=================================
2000-11-04  Kazu Hirata  <kazu@hxi.com>

	* h8300.c (function_prologue): Fix code for a monitor function.
	Support H8/S.
	(function_epilogue): Do not output pop for a monitor function.

============================================================

===File ~/gnu/gcc/h8monitor.patch===========================
Index: h8300.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/config/h8300/h8300.c,v
retrieving revision 1.46
diff -c -5 -p -r1.46 h8300.c
*** h8300.c	2000/10/18 07:17:36	1.46
--- h8300.c	2000/11/04 20:32:22
*************** function_prologue (file, size)
*** 295,314 ****
        if (TARGET_H8300)
  	{
  	  fprintf (file, "\tsubs\t#2,sp\n");
  	  push (file, 0);
  	  fprintf (file, "\tstc\tccr,r0l\n");
  	  fprintf (file, "\torc\t#128,ccr\n");
  	  fprintf (file, "\tmov.b\tr0l,@(4,sp)\n");
  	}
!       else
  	{
  	  push (file, 0);
  	  fprintf (file, "\tstc\tccr,r0l\n");
  	  fprintf (file, "\torc\t#128,ccr\n");
- 	  fprintf (file, "\tmov.b\tr0l,@(4,sp)\n");
  	}
      }
  
    if (frame_pointer_needed)
      {
        /* Push fp.  */
--- 295,327 ----
        if (TARGET_H8300)
  	{
  	  fprintf (file, "\tsubs\t#2,sp\n");
  	  push (file, 0);
  	  fprintf (file, "\tstc\tccr,r0l\n");
+ 	  fprintf (file, "\tmov.b\tr0l,@(2,sp)\n");
+ 	  pop (file, 0);
  	  fprintf (file, "\torc\t#128,ccr\n");
+ 	}
+       else if (TARGET_H8300H)
+ 	{
+ 	  push (file, 0);
+ 	  fprintf (file, "\tstc\tccr,r0l\n");
  	  fprintf (file, "\tmov.b\tr0l,@(4,sp)\n");
+ 	  pop (file, 0);
+ 	  fprintf (file, "\torc\t#128,ccr\n");
  	}
!       else if (TARGET_H8300S)
  	{
+ 	  fprintf (file, "\tstc\texr,@-sp\n");
  	  push (file, 0);
  	  fprintf (file, "\tstc\tccr,r0l\n");
+ 	  fprintf (file, "\tmov.b\tr0l,@(6,sp)\n");
+ 	  pop (file, 0);
  	  fprintf (file, "\torc\t#128,ccr\n");
  	}
+       else
+ 	abort ();
      }
  
    if (frame_pointer_needed)
      {
        /* Push fp.  */
*************** function_epilogue (file, size)
*** 427,441 ****
    dosize (file, "add", fsize);
  
    /* Pop frame pointer if we had one.  */
    if (frame_pointer_needed)
      pop (file, FRAME_POINTER_REGNUM);
- 
-   /* If this is a monitor function, there is one register still left on
-      the stack.  */
-   if (monitor)
-     pop (file, 0);
  
    if (interrupt_handler)
      fprintf (file, "\trte\n");
    else
      fprintf (file, "\trts\n");
--- 440,449 ----
============================================================


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