aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorNick Clifton <nickc@redhat.com>2013-12-13 10:00:40 +0000
committerNick Clifton <nickc@gcc.gnu.org>2013-12-13 10:00:40 +0000
commita005b5befd6bb3166b1d7c5269a2c791e4a4ee7c (patch)
treecdf53cc2a532fa7be52f7a04968c25e7ca478971 /gcc
parente8111c8c64088b4efdf3e1a1a7818947fc2ae051 (diff)
downloadgcc-a005b5befd6bb3166b1d7c5269a2c791e4a4ee7c.zip
gcc-a005b5befd6bb3166b1d7c5269a2c791e4a4ee7c.tar.gz
gcc-a005b5befd6bb3166b1d7c5269a2c791e4a4ee7c.tar.bz2
msp430.c (is_wakeup_func): New function.
* 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. From-SVN: r205958
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog12
-rw-r--r--gcc/config/msp430/msp430.c25
-rw-r--r--gcc/config/msp430/msp430.md4
-rw-r--r--gcc/doc/extend.texi7
4 files changed, 42 insertions, 6 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 68261c6..ce87c38 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -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
diff --git a/gcc/config/msp430/msp430.c b/gcc/config/msp430/msp430.c
index daff4ae..6887d50 100644
--- a/gcc/config/msp430/msp430.c
+++ b/gcc/config/msp430/msp430.c
@@ -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:
diff --git a/gcc/config/msp430/msp430.md b/gcc/config/msp430/msp430.md
index 6f9f2d3..21720a4 100644
--- a/gcc/config/msp430/msp430.md
+++ b/gcc/config/msp430/msp430.md
@@ -1253,11 +1253,11 @@
"1"
"NOP"
)
-
+
(define_insn "disable_interrupts"
[(unspec_volatile [(const_int 0)] UNS_DINT)]
""
- "DINT"
+ "DINT \; NOP"
)
(define_insn "enable_interrupts"
diff --git a/gcc/doc/extend.texi b/gcc/doc/extend.texi
index da2c63e..af258d7 100644
--- a/gcc/doc/extend.texi
+++ b/gcc/doc/extend.texi
@@ -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: