(ATTR_PERSIST): New constant.
(msp430_data_attr): New function - verifies an attribute that only
applies to variables.
(msp430_attributes): Add noinit and persistent attributes.
(noinit_section): New variable.
(presis_section): New variable.
(TARGET_ASM_INIT_SECTIONS): Define.
(msp430_init_sections): New function - initialises the noinit and
persist section variables.
(msp430_select_section): Add support for noinit and persist
attributes.
(msp430_section_type_flags): Likewise.
* doc/extend.texi: Document the reent, critical, wakeup, noinit
and persistent attributes.
tests * gcc.target/msp430: New directory.
* gcc.target/msp430/msp430.exp: New file. Runs MSP430 specific
tests.
* gcc.target/msp430/data-attributes.c: New file. Checks the
noinit and persistent data attributes.
From-SVN: r228531
+2015-10-06 Nick Clifton <nickc@redhat.com>
+
+ * config/msp430/msp430.c (ATTR_NOINIT): New constant.
+ (ATTR_PERSIST): New constant.
+ (msp430_data_attr): New function - verifies an attribute that only
+ applies to variables.
+ (msp430_attributes): Add noinit and persistent attributes.
+ (noinit_section): New variable.
+ (presis_section): New variable.
+ (TARGET_ASM_INIT_SECTIONS): Define.
+ (msp430_init_sections): New function - initialises the noinit and
+ persist section variables.
+ (msp430_select_section): Add support for noinit and persist
+ attributes.
+ (msp430_section_type_flags): Likewise.
+ * doc/extend.texi: Document the reent, critical, wakeup, noinit
+ and persistent attributes.
+
2015-10-05 Aditya Kumar <aditya.k7@samsung.com>
Sebastian Pop <s.pop@samsung.com>
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)
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))
{
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
{ 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 }
};
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
{
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);
}
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);
}
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
* M32R/D Variable Attributes::
* MeP Variable Attributes::
* Microsoft Windows Variable Attributes::
+* MSP430 Variable Attributes::
* PowerPC Variable Attributes::
* SPU Variable Attributes::
* x86 Variable Attributes::
@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
+2015-10-06 Nick Clifton <nickc@redhat.com>
+
+ * gcc.target/msp430: New directory.
+ * gcc.target/msp430/msp430.exp: New file. Runs MSP430 specific
+ tests.
+ * gcc.target/msp430/data-attributes.c: New file. Checks the
+ noinit and persistent data attributes.
+
2015-10-06 Kirill Yukhin <kirill.yukhin@intel.com>
* gcc.target/i386/builtin_target.c: Fix AVX-512VBMI detection.
--- /dev/null
+/* { 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 ();
+}
--- /dev/null
+# 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