diff options
author | Nick Clifton <nickc@redhat.com> | 2015-10-06 16:26:22 +0000 |
---|---|---|
committer | Nick Clifton <nickc@gcc.gnu.org> | 2015-10-06 16:26:22 +0000 |
commit | 90bc48789b8ca036a728396de3d26b6a2b6a60e8 (patch) | |
tree | cab0ca94b0c4571ec5452234d295d64177c9f136 /gcc/config/msp430/msp430.c | |
parent | eaec70cd8bb0d06d550878428a961a41e755f213 (diff) | |
download | gcc-90bc48789b8ca036a728396de3d26b6a2b6a60e8.zip gcc-90bc48789b8ca036a728396de3d26b6a2b6a60e8.tar.gz gcc-90bc48789b8ca036a728396de3d26b6a2b6a60e8.tar.bz2 |
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
Diffstat (limited to 'gcc/config/msp430/msp430.c')
-rw-r--r-- | gcc/config/msp430/msp430.c | 63 |
1 files changed, 61 insertions, 2 deletions
diff --git a/gcc/config/msp430/msp430.c b/gcc/config/msp430/msp430.c index ba8d862..4f6df01 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); } |