diff mbox

Commit: MSP430: Add wakeup function attribute

Message ID 8761qtkr6m.fsf@redhat.com
State New
Headers show

Commit Message

Nick Clifton Dec. 13, 2013, 9:58 a.m. UTC
[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  <nickc@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.
diff mbox

Patch

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: