-2017-06-11 Jan Hubicka <hubicka@ucw.cz>
+2017-06-12 Georg-Johann Lay <avr@gjlay.de>
+
+ Support multilibs and devices that see flash in RAM address range.
+
+ PR target/81072
+ * config/avr/avr-arch.h (avr_arch_id) <ARCH_AVRXMEGA3>: New enum.
+ (avr_mcu_t) <flash_pm_offset>: New field.
+ (avr_device_specific_features) <AVR_ISA_RCALL>: New enum.
+ * config/avr/avr.h (AVR_SHORT_CALLS): New define.
+ (AVR_HAVE_JMP_CALL): Don't set if AVR_SHORT_CALLS.
+ (AVR_TINY_PM_OFFSET): Remove macro.
+ * config/avr/avr.opt (-mshort-calls): New option.
+ * config/avr/gen-avr-mmcu-specs.c (print_mcu)
+ [*self_spec]: Add / remove -mshort-calls depending on AVR_ISA_RCALL.
+ * config/avr/avr-c.c (avr_cpu_cpp_builtins)
+ <__AVR_SHORT_CALLS__>: Built-in define if AVR_SHORT_CALLS.
+ <__AVR_HAVE_JMP_CALL__>: Use AVR_HAVE_JMP_CALL as condition
+ instead of avr_arch->have_jmp_call.
+ <__AVR_PM_BASE_ADDRESS__>: Built-in define if avr_arch->flash_pm_offset.
+ [AVR_TINY] <__AVR_TINY_PM_BASE_ADDRESS__>: Use
+ avr_arch->flash_pm_offset to define.
+ * config/avr/avr-devices.c (avr_arch_types): Add initializers for
+ new field flash_pm_offset. Add entry for avrxmega3.
+ (avr_texinfo): Add entry for avrxmega3.
+ * config/avr/avr-mcus.def: Add entries for: avrxmega3,
+ attiny212, attiny214,
+ attiny412, attiny414, attiny416, attiny417,
+ attiny814, attiny816, attiny817,
+ attiny1614, attiny1616, attiny1617,
+ attiny3214, attiny3216, attiny3217.
+ * config/avr/avr.c (avr_assemble_integer)[AVR_TINY]: Use
+ avr_arch->flash_pm_offset instead of AVR_TINY_PM_OFFSET.
+ (avr_print_operand_address) [AVR_TINY]: Same.
+ (avr_asm_init_sections) <readonly_data_section>: Only patch
+ callback if avr_arch->flash_pm_offset = 0.
+ (avr_asm_named_section) <avr_need_copy_data_p>: Skip setting it
+ for rodata if avr_arch->flash_pm_offset != 0.
+ (avr_encode_section_info) [AVR_TINY]: Adjust comment.
+ * config/avr/genmultilib.awk (dir_rcall, opt_rcall): New vars.
+ (opts) [AVR_ISA_RCALL]: Append opt_rcall.
+ (m_options): Append opt_rcall.
+ (m_dirnames): Append dir_rcall.
+ * config/avr/t-multilib: Regenerate.
+
+ * configure.ac [target=avr]: Check whether avrxmega3 default
+ linker description file works as needed.
+ * configure: Regenerate.
+ * doc/avr-mmcu.texi: Regenerate.
+ * doc/invoke.texi (AVR Options) <-mshort-calls>: Document it.
+ <__AVR_ARCH__>: Document avrxmega3 and 103.
+ <__AVR_HAVE_JMP_CALL__>: Adjust documentation.
+ <__AVR_SHORT_CALLS__>: Document it.
+ <__AVR_PM_BASE_ADDRESS__>: Document it.
+ * doc/extend.texi (AVR Options) <-mshort-calls>: Document it.
+ (AVR Variable Attributes) <progmem>: Document this is
+ not needed for avrxmega3.
+ (AVR Named Address Spaces) <__flash>: Dito.
+
+2017-06-12 Jan Hubicka <hubicka@ucw.cz>
* cgraph.c (cgraph_node::dump): Complain about profile insanities.
ARCH_AVR6,
ARCH_AVRTINY,
ARCH_AVRXMEGA2,
+ ARCH_AVRXMEGA3,
ARCH_AVRXMEGA4,
ARCH_AVRXMEGA5,
ARCH_AVRXMEGA6,
/* 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;
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
{
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. */
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__");
(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__");
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
{ 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." },
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)
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))
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);
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;
}
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");
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;
}
#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)
|| 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.
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.
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;
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;
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)
{
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)
dir_tiny = "tiny-stack"
opt_tiny = "msp8"
+ dir_rcall = "short-calls"
+ opt_rcall = "mshort-calls"
+
# awk Variable Makefile Variable
# ------------------------------------------
# m_options <-> MULTILIB_OPTIONS
{
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])
# 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
}
# 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 \
mmcu=avr51 \
mmcu=avr6 \
mmcu=avrxmega2 \
+ mmcu=avrxmega3/mshort-calls \
+ mmcu=avrxmega3 \
mmcu=avrxmega4 \
mmcu=avrxmega5 \
mmcu=avrxmega6 \
fi
+
+ # Check how default linker description file implements .rodata for
+ # avrxmega3 (PR21472). avr-gcc assumes .rodata is *not* loaded to
+ # RAM so avr-gcc skips __do_copy_data for .rodata objects.
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking binutils for avrxmega3 .rodata support" >&5
+$as_echo_n "checking binutils for avrxmega3 .rodata support... " >&6; }
+ cat > conftest.s <<EOF
+ .section .rodata,"a",@progbits
+ .global xxvaryy
+ ;; avr-nm should print "... R xxvaryy", not "... D xxvaryy".
+ xxvaryy:
+ .word 1
+EOF
+ rm -f conftest.nm
+ { ac_try='$gcc_cv_as -mmcu=avrxmega3 conftest.s -o conftest.o'
+ { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; }
+ { ac_try='$gcc_cv_ld -mavrxmega3 conftest.o -o conftest.elf'
+ { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; }
+ { ac_try='$gcc_cv_nm conftest.elf > conftest.nm'
+ { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; }
+ if test -f conftest.nm
+ then
+ if grep ' R xxvaryy' conftest.nm > /dev/null; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+ rm -f conftest.s conftest.o conftest.elf conftest.nm
+ else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no: avrxmega3 .rodata located in RAM" >&5
+$as_echo "no: avrxmega3 .rodata located in RAM" >&6; }
+ echo "$as_me: nm output was" >&5
+ cat conftest.nm >&5
+ rm -f conftest.s conftest.o conftest.elf conftest.nm
+ avr_ld_ver="`$gcc_cv_ld -v | sed -e 's:^.* ::'`"
+ as_fn_error "support for avrxmega3 needs Binutils 2.29 or higher (have $avr_ld_ver)" "$LINENO" 5
+ fi
+ else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: test failed" >&5
+$as_echo "test failed" >&6; }
+ echo "$as_me: failed program was" >&5
+ cat conftest.s >&5
+ rm -f conftest.s conftest.o conftest.elf
+ as_fn_error "see \`config.log' for details" "$LINENO" 5
+ fi
;;
cris-*-*)
[-mrmw], [.text],,
[AC_DEFINE(HAVE_AS_AVR_MRMW_OPTION, 1,
[Define if your avr assembler supports -mrmw option.])])
+
+ # Check how default linker description file implements .rodata for
+ # avrxmega3 (PR21472). avr-gcc assumes .rodata is *not* loaded to
+ # RAM so avr-gcc skips __do_copy_data for .rodata objects.
+ AC_MSG_CHECKING(binutils for avrxmega3 .rodata support)
+ cat > conftest.s <<EOF
+ .section .rodata,"a",@progbits
+ .global xxvaryy
+ ;; avr-nm should print "... R xxvaryy", not "... D xxvaryy".
+ xxvaryy:
+ .word 1
+EOF
+ rm -f conftest.nm
+ AC_TRY_COMMAND([$gcc_cv_as -mmcu=avrxmega3 conftest.s -o conftest.o])
+ AC_TRY_COMMAND([$gcc_cv_ld -mavrxmega3 conftest.o -o conftest.elf])
+ AC_TRY_COMMAND([$gcc_cv_nm conftest.elf > conftest.nm])
+ if test -f conftest.nm
+ then
+ if grep ' R xxvaryy' conftest.nm > /dev/null; then
+ AC_MSG_RESULT(yes)
+ rm -f conftest.s conftest.o conftest.elf conftest.nm
+ else
+ AC_MSG_RESULT(no: avrxmega3 .rodata located in RAM)
+ echo "$as_me: nm output was" >&AS_MESSAGE_LOG_FD
+ cat conftest.nm >&AS_MESSAGE_LOG_FD
+ rm -f conftest.s conftest.o conftest.elf conftest.nm
+ avr_ld_ver="`$gcc_cv_ld -v | sed -e 's:^.* ::'`"
+ AC_MSG_ERROR([[support for avrxmega3 needs Binutils 2.29 or higher (have $avr_ld_ver)]])
+ fi
+ else
+ AC_MSG_RESULT(test failed)
+ echo "$as_me: failed program was" >&AS_MESSAGE_LOG_FD
+ cat conftest.s >&AS_MESSAGE_LOG_FD
+ rm -f conftest.s conftest.o conftest.elf
+ AC_MSG_ERROR([[see `config.log' for details]])
+ fi
;;
cris-*-*)
``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}.
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
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
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
@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
-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}
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,
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
@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__
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.