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]

h8300: patch proposal


Interrupt functions in the h8300 port save/restore all registers
even if they are not used at all. Also, functions with attribute
"noreturn" don't need to save used registers in prologue because
there is no corresponding epilogue.
Those push/pop orgies could be avoided with a slight modification
of h8300.c:

*** replace from line 124 ***

/* REGNO must be saved/restored across calls if this macro is true.  */

#define USED_IN_INTERRUPT(regno)\
   (interrupt_handler && (regs_ever_live[regno] || \                       
                            (!current_function_is_leaf &&
call_used_regs[regno])))

#define WORD_REG_USED(regno)					\
  (regno < 7 &&							\
   (!TREE_THIS_VOLATILE (current_function_decl)) &&             \
   (USED_IN_INTERRUPT(regno)                                    \
    || pragma_saveall						\
    || (regno == FRAME_POINTER_REGNUM && regs_ever_live[regno])	\
    || (regs_ever_live[regno] && !call_used_regs[regno])))

*** end of modification ***


This patch serves several purposes:
1) leaf interrupt functions (i. e. which don't call other functions)
   only preserve registers they really use
2) no-leaf interrupt functions preserve R0..R3 in addition because they
   may be used by the callee
3) noreturn functions (functions of type "volatile") don't push
   registers at all.

Below a small (fictive) example with generated assembler code before
and after the proposed modifications.

test.c:
         __attribute__((interrupt_handler)) void TIMER_INT (void)
         {
           ISR = 0; // clear request flag 
           ms++;    // increment
         }

assembler code before modification of h8300.c:

         push r0
         push r1
         push r2
         push r3
         push r4
         push r5
         push r6
         sub r2l, r2l
         mov.b r2l, ISR;
         mov @_ms, r2l
         add #1, r2l
         mov r2l, @_ms
         pop  r6
         pop  r5
         pop  r4
         pop  r3
         pop  r2
         pop  r1
         pop  r0
         rts

assembler code after modification of h8300.c:

         push r2
         sub r2l, r2l
         mov.b r2l, ISR;
         mov @_ms, r2l
         add #1, r2l
         mov r2l, @_ms
         pop  r2
         rts



Hope this helped and will find its way into a future release.

Regards,
  Ralf


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