+2016-07-20 Georg-Johann Lay <avr@gjlay.de>
+
+ * 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.
+
2016-07-20 Alexander Monakov <amonakov@ispras.ru>
* config/nvptx/nvptx.c (nvptx_option_override): Do not set
#include "c-family/c-common.h"
#include "stor-layout.h"
#include "langhooks.h"
-
+#include "tm_p.h"
/* IDs for all the AVR builtins. */
gcc_assert (ADDR_SPACE_GENERIC == ADDR_SPACE_RAM);
/* Register address spaces. The order must be the same as in the respective
- enum from avr.h (or designated initializers must be used in avr.c). */
+ enum from avr.h (or designated initializers must be used in avr.c).
+ We always register all address spaces even if some of them make no
+ sense for some targets. Diagnose for non-supported spaces will be
+ emit by TARGET_ADDR_SPACE_DIAGNOSE_USAGE. */
for (i = 0; i < ADDR_SPACE_COUNT; i++)
{
/* Only supply __FLASH<n> macro if the address space is reasonable
for this target. The address space qualifier itself is still
supported, but using it will throw an error. */
- && avr_addrspace[i].segment < avr_n_flash
- /* Only support __MEMX macro if we have LPM. */
- && (AVR_HAVE_LPM || avr_addrspace[i].pointer_size <= 2))
-
+ && avr_addr_space_supported_p ((addr_space_t) i))
{
const char *name = avr_addrspace[i].name;
char *Name = (char*) alloca (1 + strlen (name));
};
+/* 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
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;
}
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;
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))
{
#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