* RFA: RL78: Improve interrupt function generation
@ 2013-05-01 12:15 Nick Clifton
2013-05-06 22:06 ` DJ Delorie
0 siblings, 1 reply; 4+ messages in thread
From: Nick Clifton @ 2013-05-01 12:15 UTC (permalink / raw)
To: dj; +Cc: gcc-patches
Hi DJ,
The patch below makes some changes to the way the RL78 backend handles
the generation of interrupt functions. Specifically it:
* Uses register bank 3 instead of register bank 0 inside the
handler.
* Tweaks the need_to_save() function so only those registers that
will be clobbered by the handler are push onto the stack.
* Provides support for a "naked" function attribute so that
programmers can write their own mixed C/assembler interrupt
handlers if they want to.
Tested, with no regressions, on an rl78-elf target.
OK to apply ?
Cheers
Nick
gcc/ChangeLog
2013-05-01 Nick Clifton <nickc@redhat.com>
* config/rl78/rl78.c (need_to_save): Make into a boolean
function. Do not save register bank 0 registers in interrupt
handlers.
(rl78_attribute_table): Add "naked".
(rl78_is_naked_func): New function.
(rl78_expand_prologue): Skip prologue generation for naked
functions. Switch to register bank 3 for interrupt handlers.
(rl78_expand_epilogue): Skip epilogue generation for naked
functions. Switch back to register bank 0 in interrupt
handlers.
* doc/extend.texi: Document that the RL78 backend supports the
"naked" function attribute.
Index: gcc/config/rl78/rl78.c
===================================================================
--- gcc/config/rl78/rl78.c (revision 198496)
+++ gcc/config/rl78/rl78.c (working copy)
@@ -373,34 +373,42 @@
return true;
}
-/* Returns nonzero if the given register needs to be saved by the
+/* Returns true if the given register needs to be saved by the
current function. */
-static int
-need_to_save (int regno)
+static bool
+need_to_save (unsigned int regno)
{
if (is_interrupt_func (cfun->decl))
{
+ /* We don't need to save registers that have
+ been reserved for interrupt handlers. */
+ if (regno > 23)
+ return false;
+
+ /* If the handler is a non-leaf function then it may call
+ non-interrupt aware routines which will happily clobber
+ any call_used registers, so we have to preserve them. */
+ if (!crtl->is_leaf && call_used_regs[regno])
+ return true;
+
+ /* Interrupt functions do not use register bank 0. */
if (regno < 8)
- return 1; /* don't know what devirt will need */
- if (regno > 23)
- return 0; /* don't need to save interrupt registers */
- if (crtl->is_leaf)
- {
- return df_regs_ever_live_p (regno);
- }
- else
- return 1;
+ return false;
+
+ /* Otherwise we only have to save a register, call_used
+ or not, if it is used by this handler. */
+ return df_regs_ever_live_p (regno);
}
if (regno == FRAME_POINTER_REGNUM && frame_pointer_needed)
- return 1;
+ return true;
if (fixed_regs[regno])
- return 0;
+ return false;
if (crtl->calls_eh_return)
- return 1;
+ return true;
if (df_regs_ever_live_p (regno)
&& !call_used_regs[regno])
- return 1;
- return 0;
+ return true;
+ return false;
}
/* We use this to wrap all emitted insns in the prologue. */
@@ -499,6 +507,8 @@
false },
{ "brk_interrupt", 0, 0, true, false, false, rl78_handle_func_attribute,
false },
+ { "naked", 0, 0, true, false, false, rl78_handle_func_attribute,
+ false },
{ NULL, 0, 0, false, false, false, NULL, false }
};
@@ -825,6 +833,12 @@
return rv;
}
+static int
+rl78_is_naked_func (void)
+{
+ return (lookup_attribute ("naked", DECL_ATTRIBUTES (current_function_decl)) != NULL_TREE);
+}
+
/* Expand the function prologue (from the prologue pattern). */
void
rl78_expand_prologue (void)
@@ -833,19 +847,22 @@
rtx sp = gen_rtx_REG (HImode, STACK_POINTER_REGNUM);
int rb = 0;
+ if (rl78_is_naked_func ())
+ return;
+
+ rb = is_interrupt_func (cfun->decl) ? -1 : 0;
+
if (!cfun->machine->computed)
rl78_compute_frame_info ();
if (flag_stack_usage_info)
current_function_static_stack_size = cfun->machine->framesize;
- if (is_interrupt_func (cfun->decl))
- emit_insn (gen_sel_rb (GEN_INT (0)));
-
for (i = 0; i < 16; i++)
if (cfun->machine->need_to_push [i])
{
int need_bank = i/4;
+
if (need_bank != rb)
{
emit_insn (gen_sel_rb (GEN_INT (need_bank)));
@@ -853,7 +870,14 @@
}
F (emit_insn (gen_push (gen_rtx_REG (HImode, i*2))));
}
- if (rb != 0)
+
+ /* Interrupt functions use rb3 instead of rb0. */
+ if (is_interrupt_func (cfun->decl))
+ {
+ if (rb != 3)
+ emit_insn (gen_sel_rb (GEN_INT (3)));
+ }
+ else if (rb != 0)
emit_insn (gen_sel_rb (GEN_INT (0)));
if (frame_pointer_needed)
@@ -877,6 +901,11 @@
rtx sp = gen_rtx_REG (HImode, STACK_POINTER_REGNUM);
int rb = 0;
+ if (rl78_is_naked_func ())
+ return;
+
+ rb = is_interrupt_func (cfun->decl) ? 3 : 0;
+
if (frame_pointer_needed)
{
emit_move_insn (gen_rtx_REG (HImode, STACK_POINTER_REGNUM),
Index: gcc/doc/extend.texi
===================================================================
--- gcc/doc/extend.texi (revision 198496)
+++ gcc/doc/extend.texi (working copy)
@@ -3142,7 +3142,7 @@
@item naked
@cindex function without a prologue/epilogue code
-Use this attribute on the ARM, AVR, MCORE, RX and SPU ports to indicate that
+Use this attribute on the ARM, AVR, MCORE, RL78, RX and SPU ports to indicate that
the specified function does not need prologue/epilogue sequences generated by
the compiler. It is up to the programmer to provide these sequences. The
only statements that can be safely included in naked functions are
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: RFA: RL78: Improve interrupt function generation
2013-05-01 12:15 RFA: RL78: Improve interrupt function generation Nick Clifton
@ 2013-05-06 22:06 ` DJ Delorie
2013-05-08 11:50 ` nick clifton
0 siblings, 1 reply; 4+ messages in thread
From: DJ Delorie @ 2013-05-06 22:06 UTC (permalink / raw)
To: Nick Clifton; +Cc: gcc-patches
> * Uses register bank 3 instead of register bank 0 inside the
> handler.
I wonder if nested interrupts will cause problems, since the second
interrupt will occur with RB3 already selected.
Also, there are some hand-coded routines in libgloss/libgcc that
manually swap banks, they'd have to be checked to see if there are
issues there. Perhaps the G10 work there solved it already.
Those, plus Vinay's patch, should be OK otherwise. My original
intention was to leave RB3 unused for *hand coded* assembler, but if
we can use it for simpler C handlers too that's all for the better :-)
> Tested, with no regressions, on an rl78-elf target.
The testsuite doesn't test interrupts... I'm not even sure the
simulator can simulate interrupt events.
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: RFA: RL78: Improve interrupt function generation
2013-05-06 22:06 ` DJ Delorie
@ 2013-05-08 11:50 ` nick clifton
2013-05-08 16:45 ` DJ Delorie
0 siblings, 1 reply; 4+ messages in thread
From: nick clifton @ 2013-05-08 11:50 UTC (permalink / raw)
To: DJ Delorie; +Cc: gcc-patches
[-- Attachment #1: Type: text/plain, Size: 1627 bytes --]
Hi DJ,
>> * Uses register bank 3 instead of register bank 0 inside the
>> handler.
>
> I wonder if nested interrupts will cause problems, since the second
> interrupt will occur with RB3 already selected.
Yes - in fact this appears to be a general problem with RL78 interrupt
handlers. There are no instructions to push/pop the current bank
selection, so in order for nested interrupt handlers to work they would
have to do something like:
push ax ; Save AX
mov psw, a ; Get the current register bank selection
push ax ; Save it.
[... rest of interrupt handler code ...]
pop ax
and a, #0x24
cmp a, #0x24
sknz
sel rb3
cmp a, #0x20
sknz
sel rb2
cmp a, #0x04
sknz
sel rb1
cmp0 a
sknz
sel rb0
pop ax
Which sure seems messy to me. Is it reasonable to say that C based
interrupt handlers cannot be nested, or would you like me to extend the
current patch to generate prologues/epilogues as suggested above ?
> Also, there are some hand-coded routines in libgloss/libgcc that
> manually swap banks, they'd have to be checked to see if there are
> issues there. Perhaps the G10 work there solved it already.
There are ? I did not find any.
> Those, plus Vinay's patch, should be OK otherwise.
Vinay's patch was based on the RL78 backend supporting the G10
architecture variant, which it currently does not. So I am attaching a
revised patch which includes my ISR improvements, Vinay's G10 ISR
improvements and the addition of G10 support to the RL78 backend. What
do you think of this version ?
Cheers
Nick
[-- Attachment #2: rl78.intr.patch.2 --]
[-- Type: application/x-troff-man, Size: 8514 bytes --]
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: RFA: RL78: Improve interrupt function generation
2013-05-08 11:50 ` nick clifton
@ 2013-05-08 16:45 ` DJ Delorie
0 siblings, 0 replies; 4+ messages in thread
From: DJ Delorie @ 2013-05-08 16:45 UTC (permalink / raw)
To: nick clifton; +Cc: gcc-patches
> Yes - in fact this appears to be a general problem with RL78 interrupt
> handlers. There are no instructions to push/pop the current bank
> selection, so in order for nested interrupt handlers to work they would
> have to do something like:
The bank select bits are in PSW, which is automatically saved as part
of the hardware interrupt handling, and restored with RETI. My
concern was with the registers in bank 3 - in a nested interrupt,
those registers need to be saved too.
> Which sure seems messy to me. Is it reasonable to say that C based
> interrupt handlers cannot be nested, or would you like me to extend the
> current patch to generate prologues/epilogues as suggested above ?
I can't think of a good way to have gcc detect nested interrupts
automatically. Perhaps some attribute that the user can use to
override the pessimistic choice?
> > Also, there are some hand-coded routines in libgloss/libgcc that
> > manually swap banks, they'd have to be checked to see if there are
> > issues there. Perhaps the G10 work there solved it already.
>
> There are ? I did not find any.
Look in libgcc/config/rl78/mulsi3.S
> > Those, plus Vinay's patch, should be OK otherwise.
>
> Vinay's patch was based on the RL78 backend supporting the G10
> architecture variant, which it currently does not. So I am attaching a
> revised patch which includes my ISR improvements, Vinay's G10 ISR
> improvements and the addition of G10 support to the RL78 backend. What
> do you think of this version ?
This is OK, but let's keep considering the nested interrupt question.
^ permalink raw reply [flat|nested] 4+ messages in thread
end of thread, other threads:[~2013-05-08 16:45 UTC | newest]
Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2013-05-01 12:15 RFA: RL78: Improve interrupt function generation Nick Clifton
2013-05-06 22:06 ` DJ Delorie
2013-05-08 11:50 ` nick clifton
2013-05-08 16:45 ` DJ Delorie
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).