diff options
author | Georg-Johann Lay <gjl@gcc.gnu.org> | 2017-06-12 12:52:30 +0000 |
---|---|---|
committer | Georg-Johann Lay <gjl@gcc.gnu.org> | 2017-06-12 12:52:30 +0000 |
commit | 3266ddb36a000a6d3fbad3541ffb67ba980e5a67 (patch) | |
tree | a84ea0d61e0bfaf33feebe29b109cc4f0d4b2062 /gcc/config | |
parent | 7c41b76e9f61229742328ba95f9085a3460e9a79 (diff) | |
download | gcc-3266ddb36a000a6d3fbad3541ffb67ba980e5a67.zip gcc-3266ddb36a000a6d3fbad3541ffb67ba980e5a67.tar.gz gcc-3266ddb36a000a6d3fbad3541ffb67ba980e5a67.tar.bz2 |
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) <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
Diffstat (limited to 'gcc/config')
-rw-r--r-- | gcc/config/avr/avr-arch.h | 19 | ||||
-rw-r--r-- | gcc/config/avr/avr-c.c | 19 | ||||
-rw-r--r-- | gcc/config/avr/avr-devices.c | 50 | ||||
-rw-r--r-- | gcc/config/avr/avr-mcus.def | 17 | ||||
-rw-r--r-- | gcc/config/avr/avr.c | 18 | ||||
-rw-r--r-- | gcc/config/avr/avr.h | 6 | ||||
-rw-r--r-- | gcc/config/avr/avr.opt | 4 | ||||
-rw-r--r-- | gcc/config/avr/gen-avr-mmcu-specs.c | 19 | ||||
-rw-r--r-- | gcc/config/avr/genmultilib.awk | 9 | ||||
-rw-r--r-- | gcc/config/avr/t-multilib | 6 |
10 files changed, 122 insertions, 45 deletions
diff --git a/gcc/config/avr/avr-arch.h b/gcc/config/avr/avr-arch.h index 9463735..e38345b 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 9a3a190..81ffc4e 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 ad92e97..6810ff1 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 68d0d81..08a8b69 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 648a125..4f385d5 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 3dfa8c3..3158887 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 a1edec9..1efb1c0 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 4cf9114..a25ac6f 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" :"%<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) diff --git a/gcc/config/avr/genmultilib.awk b/gcc/config/avr/genmultilib.awk index 2451087..e657e55 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 dbbf3bc..6a6eebc 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 # <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 \ |