* config/msp430/msp430.c (is_wakeup_func): New function. Returns
authornickc <nickc@138bc75d-0d04-0410-961f-82ee72b054a4>
Fri, 13 Dec 2013 10:00:40 +0000 (10:00 +0000)
committernickc <nickc@138bc75d-0d04-0410-961f-82ee72b054a4>
Fri, 13 Dec 2013 10:00:40 +0000 (10:00 +0000)
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.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@205958 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/ChangeLog
gcc/config/msp430/msp430.c
gcc/config/msp430/msp430.md
gcc/doc/extend.texi

index 68261c6..ce87c38 100644 (file)
@@ -1,3 +1,15 @@
+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.
+
 2013-12-13  Kai Tietz  <kitetz@redhat.com>
 
        PR c++/57897
index daff4ae..6887d50 100644 (file)
@@ -188,7 +188,7 @@ msp430_mcu_name (void)
        mcu_name[i] = TOUPPER (mcu_name[i]);
       return mcu_name;
     }
-  
+
   return msp430x ? "__MSP430XGENERIC__" : "__MSP430GENERIC__";
 }
 
@@ -966,6 +966,12 @@ msp430_is_interrupt_func (void)
   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 @@ msp430_start_function (FILE *outfile, HOST_WIDE_INT hwi_local ATTRIBUTE_UNUSED)
        fprintf (outfile, "reentrant ");
       if (is_critical_func ())
        fprintf (outfile, "critical ");
+      if (is_wakeup_func ())
+       fprintf (outfile, "wakeup ");
       fprintf (outfile, "\n");
     }
 
@@ -1131,6 +1139,7 @@ const struct attribute_spec msp430_attribute_table[] =
   { "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 @@ msp430_expand_epilogue (int is_eh)
 
   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);
@@ -1828,7 +1845,7 @@ msp430_output_labelref (FILE *file, const char *name)
 static void
 msp430_print_operand_raw (FILE * file, rtx op)
 {
-  int i;
+  HOST_WIDE_INT i;
 
   switch (GET_CODE (op))
     {
@@ -1839,9 +1856,9 @@ msp430_print_operand_raw (FILE * file, rtx op)
     case CONST_INT:
       i = INTVAL (op);
       if (TARGET_ASM_HEX)
-       fprintf (file, "%#x", i);
+       fprintf (file, "%#" HOST_WIDE_INT_PRINT "x", i);
       else
-       fprintf (file, "%d", i);
+       fprintf (file, "%" HOST_WIDE_INT_PRINT "d", i);
       break;
 
     case CONST:
index 6f9f2d3..21720a4 100644 (file)
   "1"
   "NOP"
 )
-  
+
 (define_insn "disable_interrupts"
   [(unspec_volatile [(const_int 0)] UNS_DINT)]
   ""
-  "DINT"
+  "DINT \; NOP"
   )
 
 (define_insn "enable_interrupts"
index da2c63e..af258d7 100644 (file)
@@ -2919,6 +2919,13 @@ upon exit.  Reentrant functions cannot also have the @code{naked}
 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: