From 90bc48789b8ca036a728396de3d26b6a2b6a60e8 Mon Sep 17 00:00:00 2001 From: Nick Clifton Date: Tue, 6 Oct 2015 16:26:22 +0000 Subject: [PATCH] gcc * 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. 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 --- gcc/ChangeLog | 18 ++++++ gcc/config/msp430/msp430.c | 63 ++++++++++++++++++- gcc/doc/extend.texi | 51 +++++++++++++++ gcc/testsuite/ChangeLog | 8 +++ .../gcc.target/msp430/data-attributes.c | 56 +++++++++++++++++ gcc/testsuite/gcc.target/msp430/msp430.exp | 41 ++++++++++++ 6 files changed, 235 insertions(+), 2 deletions(-) create mode 100644 gcc/testsuite/gcc.target/msp430/data-attributes.c create mode 100644 gcc/testsuite/gcc.target/msp430/msp430.exp diff --git a/gcc/ChangeLog b/gcc/ChangeLog index c6bc7011dd6..918ff3ebfc9 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,21 @@ +2015-10-06 Nick Clifton + + * 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 Sebastian Pop diff --git a/gcc/config/msp430/msp430.c b/gcc/config/msp430/msp430.c index ba8d8628846..4f6df0191cc 100644 --- a/gcc/config/msp430/msp430.c +++ b/gcc/config/msp430/msp430.c @@ -1148,6 +1148,8 @@ const char * const ATTR_CRIT = "critical"; 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 @@ msp430_attr (tree * node, 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 @@ msp430_section_attr (tree * node, 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 @@ const struct attribute_spec 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 } }; @@ -1536,6 +1574,19 @@ gen_prefix (tree decl) 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 @@ msp430_select_section (tree decl, int reloc, unsigned HOST_WIDE_INT align) { 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 @@ msp430_section_type_flags (tree decl, const char * name, int reloc) 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); } diff --git a/gcc/doc/extend.texi b/gcc/doc/extend.texi index 2db7bb239c2..79440d301fb 100644 --- a/gcc/doc/extend.texi +++ b/gcc/doc/extend.texi @@ -3319,6 +3319,24 @@ one pass over the objects and does the best that it can. Using the 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 @@ attributes. * 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 @@ The @code{shared} attribute is only available on Microsoft Windows@. @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 diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index e7d316e738d..0e06ee82cd2 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,11 @@ +2015-10-06 Nick Clifton + + * 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 * gcc.target/i386/builtin_target.c: Fix AVX-512VBMI detection. diff --git a/gcc/testsuite/gcc.target/msp430/data-attributes.c b/gcc/testsuite/gcc.target/msp430/data-attributes.c new file mode 100644 index 00000000000..10dd1714d72 --- /dev/null +++ b/gcc/testsuite/gcc.target/msp430/data-attributes.c @@ -0,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 (); +} diff --git a/gcc/testsuite/gcc.target/msp430/msp430.exp b/gcc/testsuite/gcc.target/msp430/msp430.exp new file mode 100644 index 00000000000..488fcb1a79b --- /dev/null +++ b/gcc/testsuite/gcc.target/msp430/msp430.exp @@ -0,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 -- 2.30.2