aboutsummaryrefslogtreecommitdiff
path: root/gcc/config/msp430/msp430.c
diff options
context:
space:
mode:
authorNick Clifton <nickc@redhat.com>2015-10-06 16:26:22 +0000
committerNick Clifton <nickc@gcc.gnu.org>2015-10-06 16:26:22 +0000
commit90bc48789b8ca036a728396de3d26b6a2b6a60e8 (patch)
treecab0ca94b0c4571ec5452234d295d64177c9f136 /gcc/config/msp430/msp430.c
parenteaec70cd8bb0d06d550878428a961a41e755f213 (diff)
downloadgcc-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.c63
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);
}