Support multilibs and devices that see flash in RAM address range.
authorGeorg-Johann Lay <gjl@gcc.gnu.org>
Mon, 12 Jun 2017 12:52:30 +0000 (12:52 +0000)
committerGeorg-Johann Lay <gjl@gcc.gnu.org>
Mon, 12 Jun 2017 12:52:30 +0000 (12:52 +0000)
gcc/
Support multilibs and devices that see flash in RAM address range.

PR target/81072
* config/avr/avr-arch.h (avr_arch_id) <ARCH_AVRXMEGA3>: New enum.
(avr_mcu_t) <flash_pm_offset>: New field.
(avr_device_specific_features) <AVR_ISA_RCALL>: New enum.
* config/avr/avr.h (AVR_SHORT_CALLS): New define.
(AVR_HAVE_JMP_CALL): Don't set if AVR_SHORT_CALLS.
(AVR_TINY_PM_OFFSET): Remove macro.
* config/avr/avr.opt (-mshort-calls): New option.
* config/avr/gen-avr-mmcu-specs.c (print_mcu)
[*self_spec]: Add / remove -mshort-calls depending on AVR_ISA_RCALL.
* config/avr/avr-c.c (avr_cpu_cpp_builtins)
<__AVR_SHORT_CALLS__>: Built-in define if AVR_SHORT_CALLS.
<__AVR_HAVE_JMP_CALL__>: Use AVR_HAVE_JMP_CALL as condition
instead of avr_arch->have_jmp_call.
<__AVR_PM_BASE_ADDRESS__>: Built-in define if avr_arch->flash_pm_offset.
[AVR_TINY] <__AVR_TINY_PM_BASE_ADDRESS__>: Use
avr_arch->flash_pm_offset to define.
* config/avr/avr-devices.c (avr_arch_types): Add initializers for
new field flash_pm_offset.  Add entry for avrxmega3.
(avr_texinfo): Add entry for avrxmega3.
* config/avr/avr-mcus.def: Add entries for: avrxmega3,
attiny212, attiny214,
attiny412, attiny414, attiny416, attiny417,
attiny814, attiny816, attiny817,
attiny1614, attiny1616, attiny1617,
attiny3214, attiny3216, attiny3217.
* config/avr/avr.c (avr_assemble_integer)[AVR_TINY]: Use
avr_arch->flash_pm_offset instead of AVR_TINY_PM_OFFSET.
(avr_print_operand_address) [AVR_TINY]: Same.
(avr_asm_init_sections) <readonly_data_section>: Only patch
callback if avr_arch->flash_pm_offset = 0.
(avr_asm_named_section) <avr_need_copy_data_p>: Skip setting it
for rodata if avr_arch->flash_pm_offset != 0.
(avr_encode_section_info) [AVR_TINY]: Adjust comment.
* config/avr/genmultilib.awk (dir_rcall, opt_rcall): New vars.
(opts) [AVR_ISA_RCALL]: Append opt_rcall.
(m_options): Append opt_rcall.
(m_dirnames): Append dir_rcall.
* config/avr/t-multilib: Regenerate.
* configure.ac [target=avr]: Check whether avrxmega3 default
linker description file works as needed.
* configure: Regenerate.
* doc/avr-mmcu.texi: Regenerate.
* doc/invoke.texi (AVR Options) <-mshort-calls>: Document it.
<__AVR_ARCH__>: Document avrxmega3 and 103.
<__AVR_HAVE_JMP_CALL__>: Adjust documentation.
<__AVR_SHORT_CALLS__>: Document it.
<__AVR_PM_BASE_ADDRESS__>: Document it.
* doc/extend.texi (AVR Options) <-mshort-calls>: Document it.
(AVR Variable Attributes) <progmem>: Document this is
not needed for avrxmega3.
(AVR Named Address Spaces) <__flash>: Dito.

From-SVN: r249124

16 files changed:
gcc/ChangeLog
gcc/config/avr/avr-arch.h
gcc/config/avr/avr-c.c
gcc/config/avr/avr-devices.c
gcc/config/avr/avr-mcus.def
gcc/config/avr/avr.c
gcc/config/avr/avr.h
gcc/config/avr/avr.opt
gcc/config/avr/gen-avr-mmcu-specs.c
gcc/config/avr/genmultilib.awk
gcc/config/avr/t-multilib
gcc/configure
gcc/configure.ac
gcc/doc/avr-mmcu.texi
gcc/doc/extend.texi
gcc/doc/invoke.texi

index 20dafd3c5861a5f62435231807ba7844fdad14ad..d4f4dee2714130eaac2a2ac6ffd282af50f66f1d 100644 (file)
@@ -1,4 +1,62 @@
-2017-06-11  Jan Hubicka  <hubicka@ucw.cz>
+2017-06-12  Georg-Johann Lay  <avr@gjlay.de>
+
+       Support multilibs and devices that see flash in RAM address range.
+
+       PR target/81072
+       * config/avr/avr-arch.h (avr_arch_id) <ARCH_AVRXMEGA3>: New enum.
+       (avr_mcu_t) <flash_pm_offset>: New field.
+       (avr_device_specific_features) <AVR_ISA_RCALL>: New enum.
+       * config/avr/avr.h (AVR_SHORT_CALLS): New define.
+       (AVR_HAVE_JMP_CALL): Don't set if AVR_SHORT_CALLS.
+       (AVR_TINY_PM_OFFSET): Remove macro.
+       * config/avr/avr.opt (-mshort-calls): New option.
+       * config/avr/gen-avr-mmcu-specs.c (print_mcu)
+       [*self_spec]: Add / remove -mshort-calls depending on AVR_ISA_RCALL.
+       * config/avr/avr-c.c (avr_cpu_cpp_builtins)
+       <__AVR_SHORT_CALLS__>: Built-in define if AVR_SHORT_CALLS.
+       <__AVR_HAVE_JMP_CALL__>: Use AVR_HAVE_JMP_CALL as condition
+       instead of avr_arch->have_jmp_call.
+       <__AVR_PM_BASE_ADDRESS__>: Built-in define if avr_arch->flash_pm_offset.
+       [AVR_TINY] <__AVR_TINY_PM_BASE_ADDRESS__>: Use
+       avr_arch->flash_pm_offset to define.
+       * config/avr/avr-devices.c (avr_arch_types): Add initializers for
+       new field flash_pm_offset.  Add entry for avrxmega3.
+       (avr_texinfo): Add entry for avrxmega3.
+       * config/avr/avr-mcus.def: Add entries for: avrxmega3,
+       attiny212, attiny214,
+       attiny412, attiny414, attiny416, attiny417,
+       attiny814, attiny816, attiny817,
+       attiny1614, attiny1616, attiny1617,
+       attiny3214, attiny3216, attiny3217.
+       * config/avr/avr.c (avr_assemble_integer)[AVR_TINY]: Use
+       avr_arch->flash_pm_offset instead of AVR_TINY_PM_OFFSET.
+       (avr_print_operand_address) [AVR_TINY]: Same.
+       (avr_asm_init_sections) <readonly_data_section>: Only patch
+       callback if avr_arch->flash_pm_offset = 0.
+       (avr_asm_named_section) <avr_need_copy_data_p>: Skip setting it
+       for rodata if avr_arch->flash_pm_offset != 0.
+       (avr_encode_section_info) [AVR_TINY]: Adjust comment.
+       * config/avr/genmultilib.awk (dir_rcall, opt_rcall): New vars.
+       (opts) [AVR_ISA_RCALL]: Append opt_rcall.
+       (m_options): Append opt_rcall.
+       (m_dirnames): Append dir_rcall.
+       * config/avr/t-multilib: Regenerate.
+
+       * configure.ac [target=avr]: Check whether avrxmega3 default
+       linker description file works as needed.
+       * configure: Regenerate.
+       * doc/avr-mmcu.texi: Regenerate.
+       * doc/invoke.texi (AVR Options) <-mshort-calls>: Document it.
+       <__AVR_ARCH__>: Document avrxmega3 and 103.
+       <__AVR_HAVE_JMP_CALL__>: Adjust documentation.
+       <__AVR_SHORT_CALLS__>: Document it.
+       <__AVR_PM_BASE_ADDRESS__>: Document it.
+       * doc/extend.texi (AVR Options) <-mshort-calls>: Document it.
+       (AVR Variable Attributes) <progmem>: Document this is
+       not needed for avrxmega3.
+       (AVR Named Address Spaces) <__flash>: Dito.
+
+2017-06-12  Jan Hubicka  <hubicka@ucw.cz>
 
        * cgraph.c (cgraph_node::dump): Complain about profile insanities.
 
index 94637356a1ed6269c6553ccdabb9a38cde6ffd09..e38345b69e3bb48a640fdd1f3a00ee4003f9d59f 100644 (file)
@@ -41,6 +41,7 @@ enum avr_arch_id
   ARCH_AVR6,
   ARCH_AVRTINY,
   ARCH_AVRXMEGA2,
+  ARCH_AVRXMEGA3,
   ARCH_AVRXMEGA4,
   ARCH_AVRXMEGA5,
   ARCH_AVRXMEGA6,
@@ -86,6 +87,9 @@ typedef struct
   /* Default start of data section address for architecture.  */
   int default_data_section_start;
 
+  /* Offset where flash memory is seen in RAM address range or 0.  */
+  int flash_pm_offset;
+
   /* Offset between SFR address and RAM address:
      SFR-address = RAM-address - sfr_offset  */
   int sfr_offset;
@@ -150,7 +154,16 @@ AVR_ERRATA_SKIP
 
      For information please refer the following respective errata links
        http://www.atmel.com/dyn/resources/prod_documents/doc2494.pdf
-       http://www.atmel.com/dyn/resources/prod_documents/doc1436.pdf  */
+       http://www.atmel.com/dyn/resources/prod_documents/doc1436.pdf
+
+AVR_ISA_RCALL
+  Always use RJMP / RCALL and assume JMP / CALL are not available.
+  This affects multilib selection via specs generation and -mshort-calls.
+  Even if a device like ATtiny417 from avrxmega3 supports JMP / CALL, we
+  assume these instructions are not available and we set the built-in
+  macro __AVR_HAVE_JMP_CALL__ accordingly.  This macro is used to
+  determine a rough estimate of flash size in libgcc, and AVR-LibC uses
+  this macro to determine vector sizes.  */
 
 enum avr_device_specific_features
 {
@@ -158,8 +171,10 @@ enum avr_device_specific_features
   AVR_ISA_RMW     = 0x1, /* device has RMW instructions. */
   AVR_SHORT_SP    = 0x2, /* Stack Pointer has 8 bits width. */
   AVR_ERRATA_SKIP = 0x4, /* device has a core erratum. */
-  AVR_ISA_LDS     = 0x8  /* whether LDS / STS is valid for all data in static
+  AVR_ISA_LDS     = 0x8, /* whether LDS / STS is valid for all data in static
                             storage.  Only useful for reduced Tiny.  */
+  AVR_ISA_RCALL   = 0x10 /* Use RJMP / RCALL even though JMP / CALL
+                            are available (-mshort-calls).  */
 };
 
 /* Map architecture to its texinfo string.  */
index 9a3a190d2346dbee27449bd98efaa34aa4c13f11..81ffc4e43210d4c507bb5f9c9b418ed0cda2eccc 100644 (file)
@@ -313,11 +313,16 @@ avr_cpu_cpp_builtins (struct cpp_reader *pfile)
       cpp_define (pfile, "__AVR_ENHANCED__");
       cpp_define (pfile, "__AVR_HAVE_MUL__");
     }
+
+  if (AVR_HAVE_JMP_CALL)
+    cpp_define (pfile, "__AVR_HAVE_JMP_CALL__");
+
   if (avr_arch->have_jmp_call)
-    {
-      cpp_define (pfile, "__AVR_MEGA__");
-      cpp_define (pfile, "__AVR_HAVE_JMP_CALL__");
-    }
+    cpp_define (pfile, "__AVR_MEGA__");
+
+  if (AVR_SHORT_CALLS)
+    cpp_define (pfile, "__AVR_SHORT_CALLS__");
+
   if (AVR_XMEGA)
     cpp_define (pfile, "__AVR_XMEGA__");
 
@@ -335,9 +340,13 @@ avr_cpu_cpp_builtins (struct cpp_reader *pfile)
          (ATtiny4/5/9/10/20 and 40) mapped program memory starts at 0x4000. */
 
       cpp_define_formatted (pfile, "__AVR_TINY_PM_BASE_ADDRESS__=0x%x",
-                            AVR_TINY_PM_OFFSET);
+                            avr_arch->flash_pm_offset);
     }
 
+  if (avr_arch->flash_pm_offset)
+    cpp_define_formatted (pfile, "__AVR_PM_BASE_ADDRESS__=0x%x",
+                          avr_arch->flash_pm_offset);
+
   if (AVR_HAVE_EIJMP_EICALL)
     {
       cpp_define (pfile, "__AVR_HAVE_EIJMP_EICALL__");
index ad92e97cdf3b1d91990be0e46f09df2099ef29fe..6810ff1cc0f7470433fedccd68addbc522678155 100644 (file)
@@ -34,30 +34,31 @@ const avr_arch_t
 avr_arch_types[] =
 {
   /* unknown device specified */
-  { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x0060, 32, NULL, AVR_MMCU_DEFAULT },
+  { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x0060, 0,      32, NULL, AVR_MMCU_DEFAULT },
   /*
-    A  M  J  LM E  E  E  X  R  T  d S   S O   A
-    S  U  M  PO L  L  I  M  A  I  a t   F ff  r
-    M  L  P  MV P  P  J  E  M  N  t a   R s   c
-             XW M  M  M  G  P  Y  a r     e   h
-                   X  P  A  D       t     t   ID   */
-  { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x0060, 32, "1",   "avr1"  },
-  { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x0060, 32, "2",   "avr2"  },
-  { 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0x0060, 32, "25",  "avr25" },
-  { 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0x0060, 32, "3",   "avr3"  },
-  { 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0x0060, 32, "31",  "avr31" },
-  { 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0x0060, 32, "35",  "avr35" },
-  { 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0x0060, 32, "4",   "avr4"  },
-  { 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0x0060, 32, "5",   "avr5"  },
-  { 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0x0060, 32, "51",  "avr51" },
-  { 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0x0060, 32, "6",   "avr6"  },
-
-  { 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0x0040,  0, "100", "avrtiny" },
-  { 0, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0x2000,  0, "102", "avrxmega2" },
-  { 0, 1, 1, 1, 1, 1, 0, 1, 0, 0, 0x2000,  0, "104", "avrxmega4" },
-  { 0, 1, 1, 1, 1, 1, 0, 1, 1, 0, 0x2000,  0, "105", "avrxmega5" },
-  { 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0x2000,  0, "106", "avrxmega6" },
-  { 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0x2000,  0, "107", "avrxmega7" }
+    A  M  J  LM E  E  E  X  R  T  d S     FPO     S O   A
+    S  U  M  PO L  L  I  M  A  I  a t     lMff    F ff  r
+    M  L  P  MV P  P  J  E  M  N  t a     a s     R s   c
+             XW M  M  M  G  P  Y  a r     s e       e   h
+                   X  P  A  D       t     h t       t   ID   */
+  { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x0060, 0,      32, "1",   "avr1"  },
+  { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x0060, 0,      32, "2",   "avr2"  },
+  { 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0x0060, 0,      32, "25",  "avr25" },
+  { 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0x0060, 0,      32, "3",   "avr3"  },
+  { 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0x0060, 0,      32, "31",  "avr31" },
+  { 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0x0060, 0,      32, "35",  "avr35" },
+  { 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0x0060, 0,      32, "4",   "avr4"  },
+  { 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0x0060, 0,      32, "5",   "avr5"  },
+  { 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0x0060, 0,      32, "51",  "avr51" },
+  { 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0x0060, 0,      32, "6",   "avr6"  },
+
+  { 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0x0040, 0x4000, 0, "100", "avrtiny" },
+  { 0, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0x2000, 0,      0, "102", "avrxmega2" },
+  { 0, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0x2000, 0x8000, 0, "103", "avrxmega3" },
+  { 0, 1, 1, 1, 1, 1, 0, 1, 0, 0, 0x2000, 0,      0, "104", "avrxmega4" },
+  { 0, 1, 1, 1, 1, 1, 0, 1, 1, 0, 0x2000, 0,      0, "105", "avrxmega5" },
+  { 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0x2000, 0,      0, "106", "avrxmega6" },
+  { 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0x2000, 0,      0, "107", "avrxmega7" }
 };
 
 const avr_arch_info_t
@@ -95,6 +96,9 @@ avr_texinfo[] =
   { ARCH_AVRXMEGA2,
     "``XMEGA'' devices with more than 8@tie{}KiB and up to 64@tie{}KiB "
     "of program memory." },
+  { ARCH_AVRXMEGA3,
+    "``XMEGA'' devices with up to 64@tie{}KiB of combined program memory "
+       "and RAM, and with program memory visible in the RAM address space." },
   { ARCH_AVRXMEGA4,
     "``XMEGA'' devices with more than 64@tie{}KiB and up to 128@tie{}KiB "
     "of program memory." },
index 68d0d817a6e4033088587420879e64528d4b634c..08a8b69c57768d9b40cba8c3750796f59d98af65 100644 (file)
@@ -299,6 +299,23 @@ AVR_MCU ("atxmega16c4",      ARCH_AVRXMEGA2, AVR_ISA_RMW,  "__AVR_ATxmega16C4__"
 AVR_MCU ("atxmega32a4u",     ARCH_AVRXMEGA2, AVR_ISA_RMW,  "__AVR_ATxmega32A4U__", 0x2000, 0x0, 0x9000)
 AVR_MCU ("atxmega32c4",      ARCH_AVRXMEGA2, AVR_ISA_RMW,  "__AVR_ATxmega32C4__",  0x2000, 0x0, 0x9000)
 AVR_MCU ("atxmega32e5",      ARCH_AVRXMEGA2, AVR_ISA_NONE, "__AVR_ATxmega32E5__",  0x2000, 0x0, 0x9000)
+/* Xmega, Flash + RAM < 64K, flash visible in RAM address space */
+AVR_MCU ("avrxmega3",        ARCH_AVRXMEGA3, AVR_ISA_NONE,  NULL,                  0x3f00, 0x0, 0x8000)
+AVR_MCU ("attiny212",        ARCH_AVRXMEGA3, AVR_ISA_RCALL, "__AVR_ATtiny212__",   0x3f80, 0x0, 0x800)
+AVR_MCU ("attiny214",        ARCH_AVRXMEGA3, AVR_ISA_RCALL, "__AVR_ATtiny214__",   0x3f80, 0x0, 0x800)
+AVR_MCU ("attiny412",        ARCH_AVRXMEGA3, AVR_ISA_RCALL, "__AVR_ATtiny412__",   0x3f00, 0x0, 0x1000)
+AVR_MCU ("attiny414",        ARCH_AVRXMEGA3, AVR_ISA_RCALL, "__AVR_ATtiny414__",   0x3f00, 0x0, 0x1000)
+AVR_MCU ("attiny416",        ARCH_AVRXMEGA3, AVR_ISA_RCALL, "__AVR_ATtiny416__",   0x3f00, 0x0, 0x1000)
+AVR_MCU ("attiny417",        ARCH_AVRXMEGA3, AVR_ISA_RCALL, "__AVR_ATtiny417__",   0x3f00, 0x0, 0x1000)
+AVR_MCU ("attiny814",        ARCH_AVRXMEGA3, AVR_ISA_RCALL, "__AVR_ATtiny814__",   0x3e00, 0x0, 0x2000)
+AVR_MCU ("attiny816",        ARCH_AVRXMEGA3, AVR_ISA_RCALL, "__AVR_ATtiny816__",   0x3e00, 0x0, 0x2000)
+AVR_MCU ("attiny817",        ARCH_AVRXMEGA3, AVR_ISA_RCALL, "__AVR_ATtiny817__",   0x3e00, 0x0, 0x2000)
+AVR_MCU ("attiny1614",       ARCH_AVRXMEGA3, AVR_ISA_NONE,  "__AVR_ATtiny1614__",  0x3800, 0x0, 0x4000)
+AVR_MCU ("attiny1616",       ARCH_AVRXMEGA3, AVR_ISA_NONE,  "__AVR_ATtiny1616__",  0x3800, 0x0, 0x4000)
+AVR_MCU ("attiny1617",       ARCH_AVRXMEGA3, AVR_ISA_NONE,  "__AVR_ATtiny1617__",  0x3800, 0x0, 0x4000)
+AVR_MCU ("attiny3214",       ARCH_AVRXMEGA3, AVR_ISA_NONE,  "__AVR_ATtiny3214__",  0x3800, 0x0, 0x8000)
+AVR_MCU ("attiny3216",       ARCH_AVRXMEGA3, AVR_ISA_NONE,  "__AVR_ATtiny3216__",  0x3800, 0x0, 0x8000)
+AVR_MCU ("attiny3217",       ARCH_AVRXMEGA3, AVR_ISA_NONE,  "__AVR_ATtiny3217__",  0x3800, 0x0, 0x8000)
 /* Xmega, 64K < Flash <= 128K, RAM <= 64K */
 AVR_MCU ("avrxmega4",        ARCH_AVRXMEGA4, AVR_ISA_NONE, NULL,                   0x2000, 0x0, 0x11000)
 AVR_MCU ("atxmega64a3",      ARCH_AVRXMEGA4, AVR_ISA_NONE, "__AVR_ATxmega64A3__",  0x2000, 0x0, 0x11000)
index 648a1256f803dfc896ce277a83c6d9dbaaa2a8f5..4f385d5682f6d373384630d897b0f76509b4c45b 100644 (file)
@@ -2502,7 +2502,7 @@ avr_print_operand_address (FILE *file, machine_mode /*mode*/, rtx addr)
   if (AVR_TINY
       && avr_address_tiny_pm_p (addr))
     {
-      addr = plus_constant (Pmode, addr, AVR_TINY_PM_OFFSET);
+      addr = plus_constant (Pmode, addr, avr_arch->flash_pm_offset);
     }
 
   switch (GET_CODE (addr))
@@ -9398,7 +9398,7 @@ avr_assemble_integer (rtx x, unsigned int size, int aligned_p)
   if (AVR_TINY
       && avr_address_tiny_pm_p (x))
     {
-      x = plus_constant (Pmode, x, AVR_TINY_PM_OFFSET);
+      x = plus_constant (Pmode, x, avr_arch->flash_pm_offset);
     }
 
   return default_assemble_integer (x, size, aligned_p);
@@ -9998,9 +9998,11 @@ static void
 avr_asm_init_sections (void)
 {
   /* Override section callbacks to keep track of `avr_need_clear_bss_p'
-     resp. `avr_need_copy_data_p'.  */
+     resp. `avr_need_copy_data_p'.  If flash is not mapped to RAM then
+     we have also to track .rodata because it is located in RAM then.  */
 
-  readonly_data_section->unnamed.callback = avr_output_data_section_asm_op;
+  if (0 == avr_arch->flash_pm_offset)
+    readonly_data_section->unnamed.callback = avr_output_data_section_asm_op;
   data_section->unnamed.callback = avr_output_data_section_asm_op;
   bss_section->unnamed.callback = avr_output_bss_section_asm_op;
 }
@@ -10032,9 +10034,13 @@ avr_asm_named_section (const char *name, unsigned int flags, tree decl)
 
   if (!avr_need_copy_data_p)
     avr_need_copy_data_p = (STR_PREFIX_P (name, ".data")
-                            || STR_PREFIX_P (name, ".rodata")
                             || STR_PREFIX_P (name, ".gnu.linkonce.d"));
 
+  if (!avr_need_copy_data_p
+      && 0 == avr_arch->flash_pm_offset)
+    avr_need_copy_data_p = (STR_PREFIX_P (name, ".rodata")
+                            || STR_PREFIX_P (name, ".gnu.linkonce.r"));
+
   if (!avr_need_clear_bss_p)
     avr_need_clear_bss_p = STR_PREFIX_P (name, ".bss");
 
@@ -10201,7 +10207,7 @@ avr_encode_section_info (tree decl, rtx rtl, int new_decl_p)
 
       if (progmem_p)
         {
-          // Tag symbols for later addition of 0x4000 (AVR_TINY_PM_OFFSET).
+          // Tag symbols for addition of 0x4000 (avr_arch->flash_pm_offset).
           SYMBOL_REF_FLAGS (sym) |= AVR_SYMBOL_FLAG_TINY_PM;
         }
 
index 3dfa8c3b00b90a57aefe8e9e147f146e626101b0..3158887fc01eba8ee28db248a6e2003f1f5d3941 100644 (file)
@@ -60,7 +60,9 @@ enum
 
 #define TARGET_CPU_CPP_BUILTINS()      avr_cpu_cpp_builtins (pfile)
 
-#define AVR_HAVE_JMP_CALL (avr_arch->have_jmp_call)
+#define AVR_SHORT_CALLS (TARGET_SHORT_CALLS                             \
+                         && avr_arch == &avr_arch_types[ARCH_AVRXMEGA3])
+#define AVR_HAVE_JMP_CALL (avr_arch->have_jmp_call && ! AVR_SHORT_CALLS)
 #define AVR_HAVE_MUL (avr_arch->have_mul)
 #define AVR_HAVE_MOVW (avr_arch->have_movw_lpmx)
 #define AVR_HAVE_LPM (!AVR_TINY)
@@ -74,8 +76,6 @@ enum
                         || avr_arch->have_rampd)
 #define AVR_HAVE_EIJMP_EICALL (avr_arch->have_eijmp_eicall)
 
-#define AVR_TINY_PM_OFFSET (0x4000)
-
 /* Handling of 8-bit SP versus 16-bit SP is as follows:
 
 FIXME: DRIVER_SELF_SPECS has changed.
index a1edec977857a681ee57f9af3090722c391bfd03..1efb1c063b6eae5297a549491cb7ccb7962ded0d 100644 (file)
@@ -44,6 +44,10 @@ Target Report Undocumented Mask(ALL_DEBUG)
 mlog=
 Target RejectNegative Joined Undocumented Var(avr_log_details)
 
+mshort-calls
+Target Report RejectNegative Mask(SHORT_CALLS)
+Use RJMP / RCALL even though CALL / JMP are available.
+
 mint8
 Target Report Mask(INT8)
 Use an 8-bit 'int' type.
index 4cf911490e9a5704e10456298f25f27d5086d98f..a25ac6f9e50005192d0ed0f2efd7a924b4843507 100644 (file)
@@ -113,6 +113,7 @@ static void
 print_mcu (const avr_mcu_t *mcu)
 {
   const char *sp8_spec;
+  const char *rcall_spec;
   const avr_mcu_t *arch_mcu;
   const avr_arch_t *arch;
   enum avr_arch_id arch_id = mcu->arch_id;
@@ -134,6 +135,7 @@ print_mcu (const avr_mcu_t *mcu)
   bool errata_skip = 0 != (mcu->dev_attribute & AVR_ERRATA_SKIP);
   bool rmw = 0 != (mcu->dev_attribute & AVR_ISA_RMW);
   bool sp8 = 0 != (mcu->dev_attribute & AVR_SHORT_SP);
+  bool rcall = (mcu->dev_attribute & AVR_ISA_RCALL);
   bool is_arch = NULL == mcu->macro;
   bool is_device = ! is_arch;
 
@@ -150,13 +152,25 @@ print_mcu (const avr_mcu_t *mcu)
       sp8_spec = sp8 ? "-msp8" :"%<msp8";
     }
 
+  if (is_arch
+      && ARCH_AVRXMEGA3 == arch_id)
+    {
+      // Leave "avrxmega3" alone.  This architectures is the only one
+      // that mixes devices with and without JMP / CALL.
+      rcall_spec = "";
+    }
+  else
+    {
+      rcall_spec = rcall ? "-mshort-calls" : "%<mshort-calls";
+    }
+
   fprintf (f, "#\n"
            "# Auto-generated specs for AVR ");
   if (is_arch)
     fprintf (f, "core architecture %s\n", arch->name);
   else
-    fprintf (f, "device %s (core %s, %d-bit SP)\n",
-             mcu->name, arch->name, sp8 ? 8 : 16);
+    fprintf (f, "device %s (core %s, %d-bit SP%s)\n", mcu->name,
+                        arch->name, sp8 ? 8 : 16, rcall ? ", short-calls" : "");
   fprintf (f, "%s\n", header);
 
   if (is_device)
@@ -255,6 +269,7 @@ print_mcu (const avr_mcu_t *mcu)
     {
       fprintf (f, "*self_spec:\n");
       fprintf (f, "\t%%{!mmcu=avr*: %%<mmcu=* -mmcu=%s} ", arch->name);
+      fprintf (f, "%s ", rcall_spec);
       fprintf (f, "%s\n\n", sp8_spec);
 
 #if defined (WITH_AVRLIBC)
index 2451087347ff3059001b4dbaf045313da546a513..e657e558cae80493ed6804eccb597171004834be 100644 (file)
@@ -35,6 +35,9 @@ BEGIN {
     dir_tiny = "tiny-stack"
     opt_tiny = "msp8"
 
+    dir_rcall = "short-calls"
+    opt_rcall = "mshort-calls"
+
     #    awk Variable         Makefile Variable  
     #  ------------------------------------------
     #    m_options     <->    MULTILIB_OPTIONS
@@ -116,6 +119,8 @@ BEGIN {
     {
       if (dev_attribute[i] == "AVR_SHORT_SP")
         opts = opts "/" opt_tiny
+      if (dev_attribute[i] == "AVR_ISA_RCALL")
+        opts = opts "/" opt_rcall
     }
 
     if (!have[opts])
@@ -140,7 +145,7 @@ END {
 
     # Intended Target: ./gcc/config/avr/t-multilib
 
-    print m_options  " " opt_tiny
-    print m_dirnames " " dir_tiny
+    print m_options  " " opt_tiny " " opt_rcall
+    print m_dirnames " " dir_tiny " " dir_rcall
     print m_required
 }
index dbbf3bcb5cb37ea88fb8ab65a8eb970acf2ac682..6a6eebc49138733304e88bc970a0738f6493b61b 100644 (file)
@@ -21,9 +21,9 @@
 # along with GCC; see the file COPYING3.  If not see
 # <http://www.gnu.org/licenses/>.
 
-MULTILIB_OPTIONS = mmcu=avr2/mmcu=avr25/mmcu=avr3/mmcu=avr31/mmcu=avr35/mmcu=avr4/mmcu=avr5/mmcu=avr51/mmcu=avr6/mmcu=avrxmega2/mmcu=avrxmega4/mmcu=avrxmega5/mmcu=avrxmega6/mmcu=avrxmega7/mmcu=avrtiny msp8
+MULTILIB_OPTIONS = mmcu=avr2/mmcu=avr25/mmcu=avr3/mmcu=avr31/mmcu=avr35/mmcu=avr4/mmcu=avr5/mmcu=avr51/mmcu=avr6/mmcu=avrxmega2/mmcu=avrxmega3/mmcu=avrxmega4/mmcu=avrxmega5/mmcu=avrxmega6/mmcu=avrxmega7/mmcu=avrtiny msp8 mshort-calls
 
-MULTILIB_DIRNAMES = avr2 avr25 avr3 avr31 avr35 avr4 avr5 avr51 avr6 avrxmega2 avrxmega4 avrxmega5 avrxmega6 avrxmega7 avrtiny tiny-stack
+MULTILIB_DIRNAMES = avr2 avr25 avr3 avr31 avr35 avr4 avr5 avr51 avr6 avrxmega2 avrxmega3 avrxmega4 avrxmega5 avrxmega6 avrxmega7 avrtiny tiny-stack short-calls
 
 MULTILIB_REQUIRED = \
        msp8 \
@@ -37,6 +37,8 @@ MULTILIB_REQUIRED = \
        mmcu=avr51 \
        mmcu=avr6 \
        mmcu=avrxmega2 \
+       mmcu=avrxmega3/mshort-calls \
+       mmcu=avrxmega3 \
        mmcu=avrxmega4 \
        mmcu=avrxmega5 \
        mmcu=avrxmega6 \
index c823ffe6290435c41bd8e0e44dfef3934af80983..cc542ac4da58fa839beb0fc5de4fb04bce298ea5 100755 (executable)
@@ -24819,6 +24819,61 @@ $as_echo "#define HAVE_AS_AVR_MRMW_OPTION 1" >>confdefs.h
 
 fi
 
+
+    # Check how default linker description file implements .rodata for
+    # avrxmega3 (PR21472).  avr-gcc assumes .rodata is *not* loaded to
+    # RAM so avr-gcc skips __do_copy_data for .rodata objects.
+    { $as_echo "$as_me:${as_lineno-$LINENO}: checking binutils for avrxmega3 .rodata support" >&5
+$as_echo_n "checking binutils for avrxmega3 .rodata support... " >&6; }
+    cat > conftest.s <<EOF
+        .section .rodata,"a",@progbits
+        .global xxvaryy
+    ;; avr-nm should print "... R xxvaryy", not "... D xxvaryy".
+    xxvaryy:
+        .word 1
+EOF
+    rm -f conftest.nm
+    { ac_try='$gcc_cv_as -mmcu=avrxmega3 conftest.s -o conftest.o'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; }
+    { ac_try='$gcc_cv_ld -mavrxmega3 conftest.o -o conftest.elf'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; }
+    { ac_try='$gcc_cv_nm conftest.elf > conftest.nm'
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; }
+    if test -f conftest.nm
+    then
+       if grep ' R xxvaryy' conftest.nm > /dev/null; then
+           { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+           rm -f conftest.s conftest.o conftest.elf conftest.nm
+       else
+           { $as_echo "$as_me:${as_lineno-$LINENO}: result: no: avrxmega3 .rodata located in RAM" >&5
+$as_echo "no: avrxmega3 .rodata located in RAM" >&6; }
+           echo "$as_me: nm output was" >&5
+           cat conftest.nm >&5
+           rm -f conftest.s conftest.o conftest.elf conftest.nm
+           avr_ld_ver="`$gcc_cv_ld -v | sed -e 's:^.* ::'`"
+           as_fn_error "support for avrxmega3 needs Binutils 2.29 or higher (have $avr_ld_ver)" "$LINENO" 5
+       fi
+    else
+       { $as_echo "$as_me:${as_lineno-$LINENO}: result: test failed" >&5
+$as_echo "test failed" >&6; }
+       echo "$as_me: failed program was" >&5
+       cat conftest.s >&5
+       rm -f conftest.s conftest.o conftest.elf
+       as_fn_error "see \`config.log' for details" "$LINENO" 5
+    fi
     ;;
 
   cris-*-*)
index acfe9797389643e81cb63ca9a6bf791555dc0acd..b54f797b4b9ca856811f8da901f566c397ceeaba 100644 (file)
@@ -3816,6 +3816,42 @@ AS_HELP_STRING([--disable-fix-cortex-a53-843419],
       [-mrmw], [.text],,
       [AC_DEFINE(HAVE_AS_AVR_MRMW_OPTION, 1,
                [Define if your avr assembler supports -mrmw option.])])
+
+    # Check how default linker description file implements .rodata for
+    # avrxmega3 (PR21472).  avr-gcc assumes .rodata is *not* loaded to
+    # RAM so avr-gcc skips __do_copy_data for .rodata objects.
+    AC_MSG_CHECKING(binutils for avrxmega3 .rodata support)
+    cat > conftest.s <<EOF
+        .section .rodata,"a",@progbits
+        .global xxvaryy
+    ;; avr-nm should print "... R xxvaryy", not "... D xxvaryy".
+    xxvaryy:
+        .word 1
+EOF
+    rm -f conftest.nm
+    AC_TRY_COMMAND([$gcc_cv_as -mmcu=avrxmega3 conftest.s -o conftest.o])
+    AC_TRY_COMMAND([$gcc_cv_ld -mavrxmega3 conftest.o -o conftest.elf])
+    AC_TRY_COMMAND([$gcc_cv_nm conftest.elf > conftest.nm])
+    if test -f conftest.nm
+    then
+       if grep ' R xxvaryy' conftest.nm > /dev/null; then
+           AC_MSG_RESULT(yes)
+           rm -f conftest.s conftest.o conftest.elf conftest.nm
+       else
+           AC_MSG_RESULT(no: avrxmega3 .rodata located in RAM)
+           echo "$as_me: nm output was" >&AS_MESSAGE_LOG_FD
+           cat conftest.nm >&AS_MESSAGE_LOG_FD
+           rm -f conftest.s conftest.o conftest.elf conftest.nm
+           avr_ld_ver="`$gcc_cv_ld -v | sed -e 's:^.* ::'`"
+           AC_MSG_ERROR([[support for avrxmega3 needs Binutils 2.29 or higher (have $avr_ld_ver)]])
+       fi
+    else
+       AC_MSG_RESULT(test failed)
+       echo "$as_me: failed program was" >&AS_MESSAGE_LOG_FD
+       cat conftest.s >&AS_MESSAGE_LOG_FD
+       rm -f conftest.s conftest.o conftest.elf
+       AC_MSG_ERROR([[see `config.log' for details]])
+    fi
     ;;
 
   cris-*-*)
index deb0dd36e59269f5ba6e8e2720496e6a1c205556..15fd414f790f3484d54870c60da95ed4079e28ab 100644 (file)
 ``XMEGA'' devices with more than 8@tie{}KiB and up to 64@tie{}KiB of program memory.
 @*@var{mcu}@tie{}= @code{atxmega16a4}, @code{atxmega16a4u}, @code{atxmega16c4}, @code{atxmega16d4}, @code{atxmega16e5}, @code{atxmega32a4}, @code{atxmega32a4u}, @code{atxmega32c3}, @code{atxmega32c4}, @code{atxmega32d3}, @code{atxmega32d4}, @code{atxmega32e5}, @code{atxmega8e5}.
 
+@item avrxmega3
+``XMEGA'' devices with up to 64@tie{}KiB of combined program memory and RAM, and with program memory visible in the RAM address space.
+@*@var{mcu}@tie{}= @code{attiny1614}, @code{attiny1616}, @code{attiny1617}, @code{attiny212}, @code{attiny214}, @code{attiny3214}, @code{attiny3216}, @code{attiny3217}, @code{attiny412}, @code{attiny414}, @code{attiny416}, @code{attiny417}, @code{attiny814}, @code{attiny816}, @code{attiny817}.
+
 @item avrxmega4
 ``XMEGA'' devices with more than 64@tie{}KiB and up to 128@tie{}KiB of program memory.
 @*@var{mcu}@tie{}= @code{atxmega64a3}, @code{atxmega64a3u}, @code{atxmega64a4u}, @code{atxmega64b1}, @code{atxmega64b3}, @code{atxmega64c3}, @code{atxmega64d3}, @code{atxmega64d4}.
index d467a1652eeaba47140734796b1c75322527cd9f..ef1ae73954c4e92490d1e1cdad02c17abdea6b33 100644 (file)
@@ -1312,11 +1312,24 @@ in order to put read-only data into the flash memory and access that
 data by means of the special instructions @code{LPM} or @code{ELPM}
 needed to read from flash.
 
-Per default, any data including read-only data is located in RAM
-(the generic address space) so that non-generic address spaces are
-needed to locate read-only data in flash memory
-@emph{and} to generate the right instructions to access this data
-without using (inline) assembler code.
+Devices belonging to @code{avrtiny} and @code{avrxmega3} can access
+flash memory by means of @code{LD*} instructions because the flash
+memory is mapped into the RAM address space.  There is @emph{no need}
+for language extensions like @code{__flash} or attribute
+@ref{AVR Variable Attributes,,@code{progmem}}.
+The default linker description files for these devices cater for that
+feature and @code{.rodata} stays in flash: The compiler just generates
+@code{LD*} instructions, and the linker script adds core specific
+offsets to all @code{.rodata} symbols: @code{0x4000} in the case of
+@code{avrtiny} and @code{0x8000} in the case of @code{avrxmega3}.
+See @ref{AVR Options} for a list of respective devices.
+
+For devices not in @code{avrtiny} or @code{avrxmega3},
+any data including read-only data is located in RAM (the generic
+address space) because flash memory is not visible in the RAM address
+space.  In order to locate read-only data in flash memory @emph{and}
+to generate the right instructions to access this data without
+using (inline) assembler code, special address spaces are needed.
 
 @table @code
 @item __flash
@@ -1447,14 +1460,11 @@ extern const __memx char foo;
 const __memx void *pfoo = &foo;
 @end smallexample
 
-@noindent
-Such code requires at least binutils 2.23, see
-@w{@uref{https://sourceware.org/PR13503,PR13503}}.
-
 @item
 On the reduced Tiny devices like ATtiny40, no address spaces are supported.
-Data can be put into and read from flash memory by means of
-attribute @code{progmem}, see @ref{AVR Variable Attributes}.
+Just use vanilla C / C++ code without overhead as outlined above.
+Attribute @code{progmem} is supported but works differently,
+see @ref{AVR Variable Attributes}.
 
 @end itemize
 
@@ -5936,6 +5946,19 @@ normally resides in the data memory (RAM).
 See also the @ref{AVR Named Address Spaces} section for
 an alternate way to locate and access data in flash memory.
 
+@item @bullet{}@tie{} AVR cores with flash memory visible in the RAM address range:
+On such devices, there is no need for attribute @code{progmem} or
+@ref{AVR Named Address Spaces,,@code{__flash}} qualifier at all.
+Just use standard C / C++.  The compiler will generate @code{LD*}
+instructions.  As flash memory is visible in the RAM address range,
+and the default linker script does @emph{not} locate @code{.rodata} in
+RAM, no special features are needed in order not to waste RAM for
+read-only data or to read from flash.  You might even get slightly better
+performance by
+avoiding @code{progmem} and @code{__flash}.  This applies to devices from
+families @code{avrtiny} and @code{avrxmega3}, see @ref{AVR Options} for
+an overview.
+
 @item @bullet{}@tie{}Reduced AVR Tiny cores like ATtiny40:
 The compiler adds @code{0x4000}
 to the addresses of objects and declarations in @code{progmem} and locates
@@ -5957,28 +5980,7 @@ int read_var (int i)
 @end smallexample
 
 Please notice that on these devices, there is no need for @code{progmem}
-at all.  Just use an appropriate linker description file like outlined below.
-
-@smallexample
-  .text :
-  @{ ...
-  @} > text
-  /* Leave .rodata in flash and add an offset of 0x4000 to all
-     addresses so that respective objects can be accessed by
-     LD instructions and open coded C/C++.  This means there
-     is no need for progmem in the source and no overhead by
-     read-only data in RAM.  */
-  .rodata ADDR(.text) + SIZEOF (.text) + 0x4000 :
-  @{
-    *(.rodata)
-    *(.rodata*)
-    *(.gnu.linkonce.r*)
-  @} AT> text
-  /* No more need to put .rodata into .data:
-     Removed all .rodata entries from .data.  */
-  .data :
-  @{ ...
-@end smallexample
+at all.
 
 @end table
 
index 5d416490d49f976be9cd60ad77cee713d5c2412f..653bc076759203c6b6399f5f54d4153824fdc294 100644 (file)
@@ -662,7 +662,7 @@ Objective-C and Objective-C++ Dialects}.
 -mbranch-cost=@var{cost} @gol
 -mcall-prologues  -mint8  -mn_flash=@var{size}  -mno-interrupts @gol
 -mrelax  -mrmw  -mstrict-X  -mtiny-stack  -mfract-convert-truncate @gol
--nodevicelib @gol
+-mshort-calls  -nodevicelib @gol
 -Waddr-space-convert  -Wmisspelled-isr}
 
 @emph{Blackfin Options}
@@ -15637,6 +15637,15 @@ section on @code{EIND} and linker stubs below.
 Assume that the device supports the Read-Modify-Write
 instructions @code{XCH}, @code{LAC}, @code{LAS} and @code{LAT}.
 
+@item -mshort-calls
+@opindex mshort-calls
+
+Assume that @code{RJMP} and @code{RCALL} can target the whole
+program memory.
+
+This option is used internally for multilib selection.  It is
+not an optimization option, and you don't need to set it by hand.
+
 @item -msp8
 @opindex msp8
 Treat the stack pointer register as an 8-bit register,
@@ -15897,10 +15906,12 @@ for @var{mcu}=@code{avr2}, @code{avr25}, @code{avr3}, @code{avr31},
 
 respectively and
 
-@code{100}, @code{102}, @code{104},
+@code{100},
+@code{102}, @code{103}, @code{104},
 @code{105}, @code{106}, @code{107}
 
-for @var{mcu}=@code{avrtiny}, @code{avrxmega2}, @code{avrxmega4},
+for @var{mcu}=@code{avrtiny},
+@code{avrxmega2}, @code{avrxmega3}, @code{avrxmega4},
 @code{avrxmega5}, @code{avrxmega6}, @code{avrxmega7}, respectively.
 If @var{mcu} specifies a device, this built-in macro is set
 accordingly. For example, with @option{-mmcu=atmega8} the macro is
@@ -15952,7 +15963,7 @@ The device has a hardware multiplier.
 
 @item __AVR_HAVE_JMP_CALL__
 The device has the @code{JMP} and @code{CALL} instructions.
-This is the case for devices with at least 16@tie{}KiB of program
+This is the case for devices with more than 8@tie{}KiB of program
 memory.
 
 @item __AVR_HAVE_EIJMP_EICALL__
@@ -16009,6 +16020,21 @@ or @code{STS}. This offset depends on the device architecture and has
 to be subtracted from the RAM address in order to get the
 respective I/O@tie{}address.
 
+@item __AVR_SHORT_CALLS__
+The @option{-mshort-calls} command line option is set.
+
+@item __AVR_PM_BASE_ADDRESS__=@var{addr}
+Some devices support reading from flash memory by means of @code{LD*}
+instructions.  The flash memory is seen in the data address space
+at an offset of @code{__AVR_PM_BASE_ADDRESS__}.  If this macro
+is not defined, this feature is not available.  If defined,
+the address space is linear and there is no need to put
+@code{.rodata} into RAM.  This is handled by the default linker
+description file, and is currently available for
+@code{avrtiny} and @code{avrxmega3}.  Even more convenient,
+there is no need to use address spaces like @code{__flash} or
+features like attribute @code{progmem} and @code{pgm_read_*}.
+
 @item __WITH_AVRLIBC__
 The compiler is configured to be used together with AVR-Libc.
 See the @option{--with-avrlibc} configure option.