Index: gcc/config/msp430/msp430.c
===================================================================
--- gcc/config/msp430/msp430.c	(revision 228520)
+++ gcc/config/msp430/msp430.c	(working copy)
@@ -1148,6 +1148,8 @@
 const char * const  ATTR_LOWER  = "lower";
 const char * const  ATTR_UPPER  = "upper";
 const char * const  ATTR_EITHER = "either";
+const char * const  ATTR_NOINIT = "noinit";
+const char * const  ATTR_PERSIST = "persistent";
 
 static inline bool
 has_attr (const char * attr, tree decl)
@@ -1278,7 +1280,7 @@
       if (is_naked_func (* node))
 	message = "naked functions cannot be critical";
       else if (is_reentrant_func (* node))
-	message = "reentranct functions cannot be critical";
+	message = "reentrant functions cannot be critical";
     }
   else if (TREE_NAME_EQ (name, ATTR_NAKED))
     {
@@ -1344,6 +1346,39 @@
   return NULL_TREE;
 }
 
+static tree
+msp430_data_attr (tree * node,
+		  tree   name,
+		  tree   args,
+		  int    flags ATTRIBUTE_UNUSED,
+		  bool * no_add_attrs ATTRIBUTE_UNUSED)
+{
+  const char * message = NULL;
+
+  gcc_assert (DECL_P (* node));
+  gcc_assert (args == NULL);
+
+  if (TREE_CODE (* node) != VAR_DECL)
+    message = "%qE attribute only applies to variables";
+
+  if (DECL_SECTION_NAME (* node))
+    message = "%qE attribute cannot be applied to variables with specific sections";
+
+  /* If this var is thought to be common, then change this.  Common variables
+     are assigned to sections before the backend has a chance to process them.  */
+  if (DECL_COMMON (* node))
+    DECL_COMMON (* node) = 0;
+
+  if (message)
+    {
+      warning (OPT_Wattributes, message, name);
+      * no_add_attrs = true;
+    }
+    
+  return NULL_TREE;
+}
+
+
 #undef  TARGET_ATTRIBUTE_TABLE
 #define TARGET_ATTRIBUTE_TABLE		msp430_attribute_table
 
@@ -1363,6 +1398,9 @@
   { ATTR_UPPER,       0, 0, true,  false, false, msp430_section_attr, false },
   { ATTR_EITHER,      0, 0, true,  false, false, msp430_section_attr, false },
 
+  { ATTR_NOINIT,      0, 0, true,  false, false, msp430_data_attr, false },
+  { ATTR_PERSIST,     0, 0, true,  false, false, msp430_data_attr, false },
+
   { NULL,             0, 0, false, false, false, NULL,        false }
 };
 
@@ -1536,6 +1574,19 @@
   return NULL;
 }
 
+static section * noinit_section;
+static section * persist_section;
+
+#undef  TARGET_ASM_INIT_SECTIONS
+#define TARGET_ASM_INIT_SECTIONS msp430_init_sections
+
+static void
+msp430_init_sections (void)
+{
+  noinit_section = get_unnamed_section (0, output_section_asm_op, ".section .noinit,\"aw\"");
+  persist_section = get_unnamed_section (0, output_section_asm_op, ".section .persistent,\"aw\"");
+}
+
 #undef  TARGET_ASM_SELECT_SECTION
 #define TARGET_ASM_SELECT_SECTION msp430_select_section
 
@@ -1561,6 +1612,10 @@
     {
       if (TREE_CODE (decl) == FUNCTION_DECL)
 	return text_section;
+      else if (has_attr (ATTR_NOINIT, decl))
+	return noinit_section;
+      else if (has_attr (ATTR_PERSIST, decl))
+	return persist_section;
       else
 	return default_select_section (decl, reloc, align);
     }
@@ -1629,7 +1684,11 @@
     name += strlen (upper_prefix);
   else if (strncmp (name, either_prefix, strlen (either_prefix)) == 0)
     name += strlen (either_prefix);
-
+  else if (strcmp (name, ".noinit") == 0)
+    return SECTION_WRITE | SECTION_BSS | SECTION_NOTYPE;
+  else if (strcmp (name, ".persisten") == 0)
+    return SECTION_WRITE | SECTION_NOTYPE;
+  
   return default_section_type_flags (decl, name, reloc);
 }
 
Index: gcc/doc/extend.texi
===================================================================
--- gcc/doc/extend.texi	(revision 228520)
+++ gcc/doc/extend.texi	(working copy)
@@ -3319,6 +3319,24 @@
 options can help the packing however, since they produce smaller,
 easier to pack regions.
 
+@item reentrant
+On the MSP430 a function can be given the @code{reentant} attribute.
+This makes the function disable interrupts upon entry and enable
+interrupts upon exit.  Reentrant functions cannot be @code{naked}.
+
+@item critical
+On the MSP430 a function can be given the @code{critical} attribute.
+This makes the function disable interrupts upon entry and restore the
+previous interrupt enabled/disabled state upon exit.  A function
+cannot have both the @code{reentrant} and @code{critical} attributes.
+Critical functions cannot be @code{naked}.
+
+@item wakeup
+On the MSP430 a function can be given the @code{wakeup} attribute.
+Such a function must also have the @code{interrupt} attribute.  When a
+function with the @code{wakeup} attribute exists the processor will be
+woken up from any low-power state in which it may be residing.
+
 @end table
 
 @c This is the end of the target-independent attribute table
@@ -5264,6 +5282,7 @@
 * M32R/D Variable Attributes::
 * MeP Variable Attributes::
 * Microsoft Windows Variable Attributes::
+* MSP430 Variable Attributes::
 * PowerPC Variable Attributes::
 * SPU Variable Attributes::
 * x86 Variable Attributes::
@@ -5854,6 +5873,38 @@
 
 @end table
 
+@node MSP430 Variable Attributes
+@subsection MSP430 Variable Attributes
+
+@table @code
+@item noinit
+@cindex @code{noinit} MSP430 variable attribute
+Any data with the @code{noinit} attribute will not be initialised by
+the C runtime startup code, or the program loader.  Not initialising
+data in this way can reduce program startup times.
+
+@item persistent
+@cindex @code{persistent} MSP430 variable attribute
+Any variable with the @code{persistent} attribute will not be
+initialised by the C runtime startup code.  Instead its value will be
+set once, when the application is loaded, and then never initialised
+again, even if the processor is reset or the program restarts.
+Persistent data is intended to be placed into FLASH RAM, where its
+value will be retained across resets.  The linker script being used to
+create the application should ensure that persistent data is correctly
+placed.
+
+@item lower
+@itemx upper
+@itemx either
+@cindex @code{lower} memory region on the MSP430
+@cindex @code{upper} memory region on the MSP430
+@cindex @code{either} memory region on the MSP430
+These attributes are the same as the MSP430 function attributes of the
+same name.  These attributes can be applied to both functions and
+variables.
+@end table
+
 @node PowerPC Variable Attributes
 @subsection PowerPC Variable Attributes
 
*** /dev/null	2015-10-06 08:23:07.119529620 +0100
--- gcc/testsuite/gcc.target/msp430/msp430.exp	2015-10-06 14:57:38.731692913 +0100
***************
*** 0 ****
--- 1,41 ----
+ # Copyright (C) 2015 Free Software Foundation, Inc.
+ 
+ # This program is free software; you can redistribute it and/or modify
+ # it under the terms of the GNU General Public License as published by
+ # the Free Software Foundation; either version 3 of the License, or
+ # (at your option) any later version.
+ # 
+ # This program is distributed in the hope that it will be useful,
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ # GNU General Public License for more details.
+ # 
+ # You should have received a copy of the GNU General Public License
+ # along with this program; if not, write to the Free Software
+ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.  
+ 
+ # GCC testsuite that uses the `dg.exp' driver.
+ 
+ # Exit immediately if this isn't the right target.
+ if { ![istarget msp430-*-*] } then {
+   return
+ }
+ 
+ # Load support procs.
+ load_lib gcc-dg.exp
+ 
+ # If a testcase doesn't have special options, use these.
+ global DEFAULT_CFLAGS
+ if ![info exists DEFAULT_CFLAGS] then {
+     set DEFAULT_CFLAGS ""
+ }
+ 
+ # Initialize `dg'.
+ dg-init
+ 
+ # Main loop.
+ dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/*.\[cCS\]]] \
+ 	"" $DEFAULT_CFLAGS
+ 
+ # All done.
+ dg-finish
*** /dev/null	2015-10-06 08:23:07.119529620 +0100
--- gcc/testsuite/gcc.target/msp430/data-attributes.c	2015-10-06 16:00:22.566237298 +0100
***************
*** 0 ****
--- 1,56 ----
+ /* { dg-do run } */
+ /* { dg-options "-O2" } */
+ 
+ /* This test checks that persistent and noinit data are handled correctly.  */
+ 
+ extern void __crt0_start (void) __attribute__ ((noreturn));
+ extern void abort (void) __attribute__ ((noreturn));
+ extern void exit (int) __attribute__ ((noreturn));
+ 
+ int a;
+ int b = 0;
+ int c = 1;
+ int __attribute__((noinit)) d;
+ int __attribute__((persistent)) e = 2;
+ 
+ int
+ main (void)
+ {
+   /* Make sure that the C startup code has correctly initialised the ordinary variables.  */
+   if (a != 0)
+     abort ();
+ 
+ #ifndef __MSP430X_LARGE__
+   /* For non-large targets we use the ordinary msp430-sim.ld linker script.
+      This does not support FLASH, and as a side effect it does not support
+      reinitialising initialised data.  Hence we only test b and c if this
+      is the first time through this test, or large support has been enabled.  */
+   if (e == 2)
+ #endif
+   if (b != 0 || c != 1)
+     abort ();
+   
+   switch (e)
+     {
+     case 2:
+       /* First time through - change all the values.  */
+       a = b = c = d = e = 3;
+       break;
+ 
+     case 3:
+       /* Second time through - make sure that d has not been reset.  */
+       if (d != 3)
+ 	abort ();
+       exit (0);
+ 
+     default:
+       /* Any other value for e is an error.  */
+       abort ();
+     }
+ 
+   /* Simulate a processor reset by calling the C startup code.  */
+   __crt0_start ();
+ 
+   /* Should never reach here.  */
+   abort ();
+ }
