aboutsummaryrefslogtreecommitdiff
path: root/gcc/config/avr/avr.c
diff options
context:
space:
mode:
authorGeorg-Johann Lay <avr@gjlay.de>2016-07-20 13:50:31 +0000
committerGeorg-Johann Lay <gjl@gcc.gnu.org>2016-07-20 13:50:31 +0000
commit2d06ca74a23cc87d2edc983f24a196a815af1c01 (patch)
treece0abd1f7dce44f3b5e61e8e4daa5a6b41940f05 /gcc/config/avr/avr.c
parentb25ea150b6d2b9021f785ce4397e0ffe478b5a42 (diff)
downloadgcc-2d06ca74a23cc87d2edc983f24a196a815af1c01.zip
gcc-2d06ca74a23cc87d2edc983f24a196a815af1c01.tar.gz
gcc-2d06ca74a23cc87d2edc983f24a196a815af1c01.tar.bz2
avr-protos.h (avr_addr_space_supported_p): New prototype.
gcc/ * config/avr/avr-protos.h (avr_addr_space_supported_p): New prototype. * config/avr/avr.c (TARGET_ADDR_SPACE_DIAGNOSE_USAGE): New hook define... (avr_addr_space_diagnose_usage): ...and implementation. (avr_addr_space_supported_p): New function. (avr_nonconst_pointer_addrspace, avr_pgm_check_var_decl): Only report bad address space usage if that space is supported. (avr_insert_attributes): Same. No more complain about unsupported address spaces. * config/avr/avr-c.c (tm_p.h): Include it. (avr_cpu_cpp_builtins): Only define addr-space related built-in macro if avr_addr_space_supported_p. From-SVN: r238519
Diffstat (limited to 'gcc/config/avr/avr.c')
-rw-r--r--gcc/config/avr/avr.c84
1 files changed, 48 insertions, 36 deletions
diff --git a/gcc/config/avr/avr.c b/gcc/config/avr/avr.c
index 2c0d884..6553cd8 100644
--- a/gcc/config/avr/avr.c
+++ b/gcc/config/avr/avr.c
@@ -9148,6 +9148,42 @@ avr_attribute_table[] =
};
+/* Return true if we support address space AS for the architecture in effect
+ and false, otherwise. If LOC is not UNKNOWN_LOCATION then also issue
+ a respective error. */
+
+bool
+avr_addr_space_supported_p (addr_space_t as, location_t loc)
+{
+ if (AVR_TINY)
+ {
+ if (loc != UNKNOWN_LOCATION)
+ error_at (loc, "address spaces are not supported for reduced "
+ "Tiny devices");
+ return false;
+ }
+ else if (avr_addrspace[as].segment >= avr_n_flash)
+ {
+ if (loc != UNKNOWN_LOCATION)
+ error_at (loc, "address space %qs not supported for devices with "
+ "flash size up to %d KiB", avr_addrspace[as].name,
+ 64 * avr_n_flash);
+ return false;
+ }
+
+ return true;
+}
+
+
+/* Implement `TARGET_ADDR_SPACE_DIAGNOSE_USAGE'. */
+
+static void
+avr_addr_space_diagnose_usage (addr_space_t as, location_t loc)
+{
+ (void) avr_addr_space_supported_p (as, loc);
+}
+
+
/* Look if DECL shall be placed in program memory space by
means of attribute `progmem' or some address-space qualifier.
Return non-zero if DECL is data that must end up in Flash and
@@ -9218,16 +9254,13 @@ avr_nonconst_pointer_addrspace (tree typ)
while (TREE_CODE (target) == ARRAY_TYPE)
target = TREE_TYPE (target);
- /* Pointers to non-generic address space must be const.
- Refuse address spaces outside the device's flash. */
+ /* Pointers to non-generic address space must be const. */
as = TYPE_ADDR_SPACE (target);
if (!ADDR_SPACE_GENERIC_P (as)
- && (!TYPE_READONLY (target)
- || avr_addrspace[as].segment >= avr_n_flash
- /* Also refuse __memx address space if we can't support it. */
- || (!AVR_HAVE_LPM && avr_addrspace[as].pointer_size > 2)))
+ && !TYPE_READONLY (target)
+ && avr_addr_space_supported_p (as))
{
return as;
}
@@ -9291,25 +9324,13 @@ avr_pgm_check_var_decl (tree node)
if (reason)
{
- if (avr_addrspace[as].segment >= avr_n_flash)
- {
- if (TYPE_P (node))
- error ("%qT uses address space %qs beyond flash of %d KiB",
- node, avr_addrspace[as].name, 64 * avr_n_flash);
- else
- error ("%s %q+D uses address space %qs beyond flash of %d KiB",
- reason, node, avr_addrspace[as].name, 64 * avr_n_flash);
- }
+ if (TYPE_P (node))
+ error ("pointer targeting address space %qs must be const in %qT",
+ avr_addrspace[as].name, node);
else
- {
- if (TYPE_P (node))
- error ("pointer targeting address space %qs must be const in %qT",
- avr_addrspace[as].name, node);
- else
- error ("pointer targeting address space %qs must be const"
- " in %s %q+D",
- avr_addrspace[as].name, reason, node);
- }
+ error ("pointer targeting address space %qs must be const"
+ " in %s %q+D",
+ avr_addrspace[as].name, reason, node);
}
return reason == NULL;
@@ -9342,18 +9363,6 @@ avr_insert_attributes (tree node, tree *attributes)
as = TYPE_ADDR_SPACE (TREE_TYPE (node));
- if (avr_addrspace[as].segment >= avr_n_flash)
- {
- error ("variable %q+D located in address space %qs beyond flash "
- "of %d KiB", node, avr_addrspace[as].name, 64 * avr_n_flash);
- }
- else if (!AVR_HAVE_LPM && avr_addrspace[as].pointer_size > 2)
- {
- error ("variable %q+D located in address space %qs"
- " which is not supported for architecture %qs",
- node, avr_addrspace[as].name, avr_arch->name);
- }
-
if (!TYPE_READONLY (node0)
&& !TREE_READONLY (node))
{
@@ -13728,6 +13737,9 @@ avr_fold_builtin (tree fndecl, int n_args ATTRIBUTE_UNUSED, tree *arg,
#undef TARGET_ADDR_SPACE_LEGITIMIZE_ADDRESS
#define TARGET_ADDR_SPACE_LEGITIMIZE_ADDRESS avr_addr_space_legitimize_address
+#undef TARGET_ADDR_SPACE_DIAGNOSE_USAGE
+#define TARGET_ADDR_SPACE_DIAGNOSE_USAGE avr_addr_space_diagnose_usage
+
#undef TARGET_MODE_DEPENDENT_ADDRESS_P
#define TARGET_MODE_DEPENDENT_ADDRESS_P avr_mode_dependent_address_p