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
This commit is contained in:
parent
eaec70cd8b
commit
90bc48789b
|
@ -1,3 +1,21 @@
|
|||
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>
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -1,3 +1,11 @@
|
|||
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.
|
||||
|
|
|
@ -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 ();
|
||||
}
|
|
@ -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
|
Loading…
Reference in New Issue