From 3266ddb36a000a6d3fbad3541ffb67ba980e5a67 Mon Sep 17 00:00:00 2001 From: Georg-Johann Lay Date: Mon, 12 Jun 2017 12:52:30 +0000 Subject: [PATCH] Support multilibs and devices that see flash in RAM address range. gcc/ Support multilibs and devices that see flash in RAM address range. PR target/81072 * config/avr/avr-arch.h (avr_arch_id) : New enum. (avr_mcu_t) : New field. (avr_device_specific_features) : 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) : Only patch callback if avr_arch->flash_pm_offset = 0. (avr_asm_named_section) : 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) : Document this is not needed for avrxmega3. (AVR Named Address Spaces) <__flash>: Dito. From-SVN: r249124 --- gcc/ChangeLog | 60 ++++++++++++++++++++++++- gcc/config/avr/avr-arch.h | 19 +++++++- gcc/config/avr/avr-c.c | 19 +++++--- gcc/config/avr/avr-devices.c | 50 +++++++++++---------- gcc/config/avr/avr-mcus.def | 17 ++++++++ gcc/config/avr/avr.c | 18 +++++--- gcc/config/avr/avr.h | 6 +-- gcc/config/avr/avr.opt | 4 ++ gcc/config/avr/gen-avr-mmcu-specs.c | 19 +++++++- gcc/config/avr/genmultilib.awk | 9 +++- gcc/config/avr/t-multilib | 6 ++- gcc/configure | 55 +++++++++++++++++++++++ gcc/configure.ac | 36 +++++++++++++++ gcc/doc/avr-mmcu.texi | 4 ++ gcc/doc/extend.texi | 68 +++++++++++++++-------------- gcc/doc/invoke.texi | 34 +++++++++++++-- 16 files changed, 341 insertions(+), 83 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 20dafd3c586..d4f4dee2714 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,4 +1,62 @@ -2017-06-11 Jan Hubicka +2017-06-12 Georg-Johann Lay + + Support multilibs and devices that see flash in RAM address range. + + PR target/81072 + * config/avr/avr-arch.h (avr_arch_id) : New enum. + (avr_mcu_t) : New field. + (avr_device_specific_features) : 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) : Only patch + callback if avr_arch->flash_pm_offset = 0. + (avr_asm_named_section) : 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) : Document this is + not needed for avrxmega3. + (AVR Named Address Spaces) <__flash>: Dito. + +2017-06-12 Jan Hubicka * cgraph.c (cgraph_node::dump): Complain about profile insanities. diff --git a/gcc/config/avr/avr-arch.h b/gcc/config/avr/avr-arch.h index 94637356a1e..e38345b69e3 100644 --- a/gcc/config/avr/avr-arch.h +++ b/gcc/config/avr/avr-arch.h @@ -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. */ diff --git a/gcc/config/avr/avr-c.c b/gcc/config/avr/avr-c.c index 9a3a190d234..81ffc4e4321 100644 --- a/gcc/config/avr/avr-c.c +++ b/gcc/config/avr/avr-c.c @@ -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__"); diff --git a/gcc/config/avr/avr-devices.c b/gcc/config/avr/avr-devices.c index ad92e97cdf3..6810ff1cc0f 100644 --- a/gcc/config/avr/avr-devices.c +++ b/gcc/config/avr/avr-devices.c @@ -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." }, diff --git a/gcc/config/avr/avr-mcus.def b/gcc/config/avr/avr-mcus.def index 68d0d817a6e..08a8b69c577 100644 --- a/gcc/config/avr/avr-mcus.def +++ b/gcc/config/avr/avr-mcus.def @@ -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) diff --git a/gcc/config/avr/avr.c b/gcc/config/avr/avr.c index 648a1256f80..4f385d5682f 100644 --- a/gcc/config/avr/avr.c +++ b/gcc/config/avr/avr.c @@ -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; } diff --git a/gcc/config/avr/avr.h b/gcc/config/avr/avr.h index 3dfa8c3b00b..3158887fc01 100644 --- a/gcc/config/avr/avr.h +++ b/gcc/config/avr/avr.h @@ -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. diff --git a/gcc/config/avr/avr.opt b/gcc/config/avr/avr.opt index a1edec97785..1efb1c063b6 100644 --- a/gcc/config/avr/avr.opt +++ b/gcc/config/avr/avr.opt @@ -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. diff --git a/gcc/config/avr/gen-avr-mmcu-specs.c b/gcc/config/avr/gen-avr-mmcu-specs.c index 4cf911490e9..a25ac6f9e50 100644 --- a/gcc/config/avr/gen-avr-mmcu-specs.c +++ b/gcc/config/avr/gen-avr-mmcu-specs.c @@ -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" :"%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*: %%name); + fprintf (f, "%s ", rcall_spec); fprintf (f, "%s\n\n", sp8_spec); #if defined (WITH_AVRLIBC) diff --git a/gcc/config/avr/genmultilib.awk b/gcc/config/avr/genmultilib.awk index 2451087347f..e657e558cae 100644 --- a/gcc/config/avr/genmultilib.awk +++ b/gcc/config/avr/genmultilib.awk @@ -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 } diff --git a/gcc/config/avr/t-multilib b/gcc/config/avr/t-multilib index dbbf3bcb5cb..6a6eebc4913 100644 --- a/gcc/config/avr/t-multilib +++ b/gcc/config/avr/t-multilib @@ -21,9 +21,9 @@ # along with GCC; see the file COPYING3. If not see # . -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 \ diff --git a/gcc/configure b/gcc/configure index c823ffe6290..cc542ac4da5 100755 --- a/gcc/configure +++ b/gcc/configure @@ -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 <&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-*-*) diff --git a/gcc/configure.ac b/gcc/configure.ac index acfe9797389..b54f797b4b9 100644 --- a/gcc/configure.ac +++ b/gcc/configure.ac @@ -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 < 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-*-*) diff --git a/gcc/doc/avr-mmcu.texi b/gcc/doc/avr-mmcu.texi index deb0dd36e59..15fd414f790 100644 --- a/gcc/doc/avr-mmcu.texi +++ b/gcc/doc/avr-mmcu.texi @@ -52,6 +52,10 @@ ``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}. diff --git a/gcc/doc/extend.texi b/gcc/doc/extend.texi index d467a1652ee..ef1ae73954c 100644 --- a/gcc/doc/extend.texi +++ b/gcc/doc/extend.texi @@ -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 diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi index 5d416490d49..653bc076759 100644 --- a/gcc/doc/invoke.texi +++ b/gcc/doc/invoke.texi @@ -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. -- 2.30.2