avr-protos.h (avr_addr_space_supported_p): New prototype.
authorGeorg-Johann Lay <avr@gjlay.de>
Wed, 20 Jul 2016 13:50:31 +0000 (13:50 +0000)
committerGeorg-Johann Lay <gjl@gcc.gnu.org>
Wed, 20 Jul 2016 13:50:31 +0000 (13:50 +0000)
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

gcc/ChangeLog
gcc/config/avr/avr-c.c
gcc/config/avr/avr-protos.h
gcc/config/avr/avr.c

index 54dfc13..42ffaa0 100644 (file)
@@ -1,3 +1,18 @@
+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
index 440e801..a338a9f 100644 (file)
@@ -26,7 +26,7 @@
 #include "c-family/c-common.h"
 #include "stor-layout.h"
 #include "langhooks.h"
-
+#include "tm_p.h"
 
 /* IDs for all the AVR builtins.  */
 
@@ -253,7 +253,10 @@ avr_register_target_pragmas (void)
   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++)
     {
@@ -391,10 +394,7 @@ avr_cpu_cpp_builtins (struct cpp_reader *pfile)
             /* 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));
index afd056b..9ad1572 100644 (file)
@@ -37,6 +37,7 @@ extern void avr_asm_output_aligned_decl_common (FILE*, tree, const char*, unsign
 extern void avr_asm_asm_output_aligned_bss (FILE *, tree, const char *, unsigned HOST_WIDE_INT, int, void (*) (FILE *, tree, const char *, unsigned HOST_WIDE_INT, int));
 extern void asm_output_external (FILE *file, tree decl, char *name);
 extern int avr_progmem_p (tree decl, tree attributes);
+extern bool avr_addr_space_supported_p (addr_space_t, location_t loc = UNKNOWN_LOCATION);
 
 #ifdef RTX_CODE /* inside TREE_CODE */
 extern void avr_init_cumulative_args (CUMULATIVE_ARGS*, tree, rtx, tree);
index 2c0d884..6553cd8 100644 (file)
@@ -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