aboutsummaryrefslogtreecommitdiff
path: root/gcc/config/avr
diff options
context:
space:
mode:
authorGeorg-Johann Lay <gjl@gcc.gnu.org>2017-06-12 12:52:30 +0000
committerGeorg-Johann Lay <gjl@gcc.gnu.org>2017-06-12 12:52:30 +0000
commit3266ddb36a000a6d3fbad3541ffb67ba980e5a67 (patch)
treea84ea0d61e0bfaf33feebe29b109cc4f0d4b2062 /gcc/config/avr
parent7c41b76e9f61229742328ba95f9085a3460e9a79 (diff)
downloadgcc-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/avr')
-rw-r--r--gcc/config/avr/avr-arch.h19
-rw-r--r--gcc/config/avr/avr-c.c19
-rw-r--r--gcc/config/avr/avr-devices.c50
-rw-r--r--gcc/config/avr/avr-mcus.def17
-rw-r--r--gcc/config/avr/avr.c18
-rw-r--r--gcc/config/avr/avr.h6
-rw-r--r--gcc/config/avr/avr.opt4
-rw-r--r--gcc/config/avr/gen-avr-mmcu-specs.c19
-rw-r--r--gcc/config/avr/genmultilib.awk9
-rw-r--r--gcc/config/avr/t-multilib6
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 \