From patchwork Fri Jun 9 10:29:45 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Georg-Johann Lay X-Patchwork-Id: 773784 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from sourceware.org (server1.sourceware.org [209.132.180.131]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 3wkdpW66TBz9sNC for ; Fri, 9 Jun 2017 20:30:10 +1000 (AEST) Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=gcc.gnu.org header.i=@gcc.gnu.org header.b="nCPR22/K"; dkim-atps=neutral DomainKey-Signature: a=rsa-sha1; c=nofws; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender:to:cc :from:subject:message-id:date:mime-version:content-type; q=dns; s=default; b=Q7KuHf/zsF71PFyyacYu5CbN9oxj9uICJVytx6F4GljESjwM0d xLJt9mu+TEwutGkKrR5e9VAyfp4vNtx4HMD0e9BD1L468ZkbyMFGOFzZLbsqySgt GQKpNQIzBcbCS/zSEoB1iLhePfLny5ZvrS5tVnHMxkLpTmkOJaWFzFDn0= DKIM-Signature: v=1; a=rsa-sha1; c=relaxed; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender:to:cc :from:subject:message-id:date:mime-version:content-type; s= default; bh=qO8o+amH644wMVBHwq5iXnSz3qY=; b=nCPR22/Kfu5sokk1LQG2 My60E+slWp2RBOcwYMnOKy0tr5NAeNB5UAHnDQhpcSqB51n2MNNJaynLmC7KiJ2v eT2XifhhEYSowj3uw5E5u9WydsatnlLBKgf7vlLlzWNtvZlZUW4Irk4j2QLQ2c4/ UGqxeni9iqXVn/IUDcTB3w4= Received: (qmail 13049 invoked by alias); 9 Jun 2017 10:29:55 -0000 Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org Delivered-To: mailing list gcc-patches@gcc.gnu.org Received: (qmail 13021 invoked by uid 89); 9 Jun 2017 10:29:52 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-16.0 required=5.0 tests=AWL, BAYES_00, GIT_PATCH_1, GIT_PATCH_2, GIT_PATCH_3, KAM_ASCII_DIVIDERS, KAM_STOCKGEN, RCVD_IN_DNSWL_LOW autolearn=ham version=3.3.2 spammy=LAS X-HELO: mo4-p00-ob.smtp.rzone.de Received: from mo4-p00-ob.smtp.rzone.de (HELO mo4-p00-ob.smtp.rzone.de) (81.169.146.219) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Fri, 09 Jun 2017 10:29:44 +0000 X-RZG-AUTH: :LXoWVUeid/7A29J/hMvvT3ol15ykJcYwTPLBCxG2PQt6BpGCfQ== X-RZG-CLASS-ID: mo00 Received: from [192.168.0.123] (ip5f587033.dynamic.kabel-deutschland.de [95.88.112.51]) by smtp.strato.de (RZmta 40.9 DYNA|AUTH) with ESMTPSA id V05f90t59ATj8Nh (using TLSv1.2 with cipher ECDHE-RSA-AES256-SHA (curve secp521r1 with 521 ECDH bits, eq. 15360 bits RSA)) (Client did not present a certificate); Fri, 9 Jun 2017 12:29:45 +0200 (CEST) To: gcc-patches Cc: Denis Chertykov , Senthil Kumar Selvaraj , Pitchumani Sivanupandi From: Georg-Johann Lay Subject: [patch,avr] Add support for devices with flash accessible by LD. Message-ID: Date: Fri, 9 Jun 2017 12:29:45 +0200 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:45.0) Gecko/20100101 Thunderbird/45.8.0 MIME-Version: 1.0 X-IsSubscribed: yes Hi, This patch adds support for devices that can access flash memory by LD* instructions, hence there is no need to put .rodata in RAM. The default linker script for the new multilib versions already supports this feature, it's similar to avrtiny, cf. https://sourceware.org/PR21472 This patch does the following: * Add multilib variants avrxmega3 and avrxmega3/short-calls. * Add new option -mshort-calls for multilib selection between devices with <= 8KiB flash and > 8KiB flash. * Add specs handling for -mshort-calls: The compiler knows if this option is needed or not appropriate (similar to -msp8). * Add new ISA feature AVR_ISA_RCALL for multilib selection via -mshort-calls. * Add a new row to architecture description that contains the start address of flash memory in the RAM address range. (The actual value is not needed). * For devices with flash in RAM space, don't let .rodata objects trigger need for __do_copy_data. * Add some devices. * Add configure test for Binutils PR21472. * Adjust documentation etc. Even the smaller devices with flash <= 8KiB support JMP+CALL, but we get better code by assuming RJMP+RCALL: Jump tables are more efficient and insn length computation is more exact (CALL -> RCALL relaxation would need -mrelax and insn size would still be 4 bytes). Moreover, avr-libc uses __AVR_HAVE_JMP_CALL__ to determine vector entry size, and libgcc uses that macro for flash size estimation. Ok for trunk? Johann * 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. * avr-mcus.def: Add entries for: avrxmega3, attiny212, attiny214, attiny412, attiny414, attiny416, attiny417, attiny814, attiny816, attiny817, 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. Index: config/avr/avr-arch.h =================================================================== --- config/avr/avr-arch.h (revision 248745) +++ config/avr/avr-arch.h (working copy) @@ -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 RJMP / RCALL + are available (-mshort-calls). */ }; /* Map architecture to its texinfo string. */ Index: config/avr/avr-c.c =================================================================== --- config/avr/avr-c.c (revision 248745) +++ config/avr/avr-c.c (working copy) @@ -313,11 +313,16 @@ cpp_define_formatted (pfile, "__AVR_ARCH 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 @@ start address. This macro shall be used (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: config/avr/avr-devices.c =================================================================== --- config/avr/avr-devices.c (revision 248745) +++ config/avr/avr-devices.c (working copy) @@ -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" }, + 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, 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" } + { 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: config/avr/avr-mcus.def =================================================================== --- config/avr/avr-mcus.def (revision 248745) +++ config/avr/avr-mcus.def (working copy) @@ -299,6 +299,22 @@ AVR_MCU ("atxmega16c4", ARCH_AVRXME 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 ("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: config/avr/avr.c =================================================================== --- config/avr/avr.c (revision 248745) +++ config/avr/avr.c (working copy) @@ -2502,7 +2502,7 @@ avr_print_operand_address (FILE *file, m 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 in 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, 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 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: config/avr/avr.h =================================================================== --- config/avr/avr.h (revision 248745) +++ config/avr/avr.h (working copy) @@ -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: config/avr/avr.opt =================================================================== --- config/avr/avr.opt (revision 248745) +++ config/avr/avr.opt (working copy) @@ -44,6 +44,10 @@ Target Report Undocumented Mask(ALL_DEBU 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: config/avr/gen-avr-mmcu-specs.c =================================================================== --- config/avr/gen-avr-mmcu-specs.c (revision 248745) +++ config/avr/gen-avr-mmcu-specs.c (working copy) @@ -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 @@ for (arch_mcu = mcu; arch_mcu->macro; ) 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 @@ bool is_arch = NULL == mcu->macro; 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 @@ bool is_arch = NULL == mcu->macro; { 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) Index: config/avr/genmultilib.awk =================================================================== --- config/avr/genmultilib.awk (revision 248745) +++ config/avr/genmultilib.awk (working copy) @@ -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: config/avr/t-multilib =================================================================== --- config/avr/t-multilib (revision 248745) +++ config/avr/t-multilib (working copy) @@ -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 \ Index: configure =================================================================== --- configure (revision 248745) +++ configure (working copy) @@ -24819,6 +24819,61 @@ $as_echo "#define HAVE_AS_AVR_MRMW_OPTIO 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-*-*) Index: configure.ac =================================================================== --- configure.ac (revision 248745) +++ configure.ac (working copy) @@ -3816,6 +3816,42 @@ [ .set nomacro [-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-*-*) Index: doc/avr-mmcu.texi =================================================================== --- doc/avr-mmcu.texi (revision 248745) +++ doc/avr-mmcu.texi (working copy) @@ -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{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: doc/extend.texi =================================================================== --- doc/extend.texi (revision 248745) +++ doc/extend.texi (working copy) @@ -1312,11 +1312,24 @@ in order to put read-only data into the 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 @@ -5928,6 +5938,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 @@ -5949,28 +5972,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: doc/invoke.texi =================================================================== --- doc/invoke.texi (revision 248745) +++ doc/invoke.texi (working copy) @@ -660,7 +660,7 @@ -imacros @var{file} -imultilib @var{dir -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} @@ -15606,6 +15606,15 @@ section on @code{EIND} and linker stubs 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, @@ -15866,10 +15875,12 @@ for @var{mcu}=@code{avr2}, @code{avr25}, 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 @@ -15921,7 +15932,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__ @@ -15978,6 +15989,21 @@ or @code{STS}. This offset depends on th 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.