[This time with the patch attached] Hi Guys, I have applied the patch below to add support for a wakeup function attribute to the MSP430 backend. The wakeup attribute applies to interrupt functions, and it makes them wake the processor from low power sleep states when the interrupt handler exits.
Cheers Nick gcc/ChangeLog 2013-12-13 Nick Clifton <ni...@redhat.com> * config/msp430/msp430.c (is_wakeup_func): New function. Returns true if the current function has the wakeup attribute. (msp430_start_function): Note if the function has the wakeup attribute. (msp430_attribute_table): Add wakeup attribute. (msp430_expand_epilogue): Add support for wakeup functions. * config/msp430/msp430.md (disable_interrupts): Emit a NOP after the DINT instruction. * doc/extend.texi: Document the wakeup attribute.
Index: config/msp430/msp430.c =================================================================== --- config/msp430/msp430.c (revision 205957) +++ config/msp430/msp430.c (working copy) @@ -966,6 +966,12 @@ return is_attr_func ("interrupt"); } +static bool +is_wakeup_func (void) +{ + return msp430_is_interrupt_func () && is_attr_func ("wakeup"); +} + static inline bool is_naked_func (void) { @@ -1005,6 +1011,8 @@ fprintf (outfile, "reentrant "); if (is_critical_func ()) fprintf (outfile, "critical "); + if (is_wakeup_func ()) + fprintf (outfile, "wakeup "); fprintf (outfile, "\n"); } @@ -1131,6 +1139,7 @@ { "naked", 0, 0, true, false, false, msp430_attr, false }, { "reentrant", 0, 0, true, false, false, msp430_attr, false }, { "critical", 0, 0, true, false, false, msp430_attr, false }, + { "wakeup", 0, 0, true, false, false, msp430_attr, false }, { NULL, 0, 0, false, false, false, NULL, false } }; @@ -1409,6 +1418,14 @@ emit_insn (gen_epilogue_start_marker ()); + if (is_wakeup_func ()) + /* Clear the SCG1, SCG0, OSCOFF and CPUOFF bits in the saved copy of the + status register current residing on the stack. When this function + executes its RETI instruction the SR will be updated with this saved + value, thus ensuring that the processor is woken up from any low power + state in which it may be residing. */ + emit_insn (gen_bic_SR (GEN_INT (0xf0))); + fs = cfun->machine->framesize_locals + cfun->machine->framesize_outgoing; increment_stack (fs); Index: config/msp430/msp430.md =================================================================== --- config/msp430/msp430.md (revision 205957) +++ config/msp430/msp430.md (working copy) @@ -1253,11 +1253,11 @@ "1" "NOP" ) - + (define_insn "disable_interrupts" [(unspec_volatile [(const_int 0)] UNS_DINT)] "" - "DINT" + "DINT \; NOP" ) (define_insn "enable_interrupts" Index: doc/extend.texi =================================================================== --- doc/extend.texi (revision 205957) +++ doc/extend.texi (working copy) @@ -2919,6 +2919,13 @@ or @code{critical} attributes. They can have the @code{interrupt} attribute. +@item wakeup +@cindex @code{wakeup} attribute +This attribute only applies to interrupt functions. It is silently +ignored if applied to a non-interrupt function. A wakeup interrupt +function will rouse the processor from any low-power state that it +might be in when the function exits. + @end table On Epiphany targets one or more optional parameters can be added like this: