[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:

Reply via email to