===================================================================
@@ -157,7 +157,9 @@ enum avr_device_specific_features
AVR_ISA_NONE,
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_ERRATA_SKIP = 0x4, /* device has a core erratum. */
+ AVR_ISA_LDS = 0x8 /* whether LDS / STS is valid for all data in static
+ storage. Only useful for reduced Tiny. */
};
/* Map architecture to its texinfo string. */
===================================================================
@@ -341,11 +341,11 @@ AVR_MCU ("atxmega128a1u", ARCH_AVRXME
AVR_MCU ("atxmega128a4u", ARCH_AVRXMEGA7, AVR_ISA_RMW, "__AVR_ATxmega128A4U__", 0x2000, 0x0, 3)
/* Tiny family */
AVR_MCU ("avrtiny", ARCH_AVRTINY, AVR_ISA_NONE, NULL, 0x0040, 0x0, 1)
-AVR_MCU ("attiny4", ARCH_AVRTINY, AVR_ISA_NONE, "__AVR_ATtiny4__", 0x0040, 0x0, 1)
-AVR_MCU ("attiny5", ARCH_AVRTINY, AVR_ISA_NONE, "__AVR_ATtiny5__", 0x0040, 0x0, 1)
-AVR_MCU ("attiny9", ARCH_AVRTINY, AVR_ISA_NONE, "__AVR_ATtiny9__", 0x0040, 0x0, 1)
-AVR_MCU ("attiny10", ARCH_AVRTINY, AVR_ISA_NONE, "__AVR_ATtiny10__", 0x0040, 0x0, 1)
-AVR_MCU ("attiny20", ARCH_AVRTINY, AVR_ISA_NONE, "__AVR_ATtiny20__", 0x0040, 0x0, 1)
+AVR_MCU ("attiny4", ARCH_AVRTINY, AVR_ISA_LDS, "__AVR_ATtiny4__", 0x0040, 0x0, 1)
+AVR_MCU ("attiny5", ARCH_AVRTINY, AVR_ISA_LDS, "__AVR_ATtiny5__", 0x0040, 0x0, 1)
+AVR_MCU ("attiny9", ARCH_AVRTINY, AVR_ISA_LDS, "__AVR_ATtiny9__", 0x0040, 0x0, 1)
+AVR_MCU ("attiny10", ARCH_AVRTINY, AVR_ISA_LDS, "__AVR_ATtiny10__", 0x0040, 0x0, 1)
+AVR_MCU ("attiny20", ARCH_AVRTINY, AVR_ISA_LDS, "__AVR_ATtiny20__", 0x0040, 0x0, 1)
AVR_MCU ("attiny40", ARCH_AVRTINY, AVR_ISA_NONE, "__AVR_ATtiny40__", 0x0040, 0x0, 1)
/* Assembler only. */
AVR_MCU ("avr1", ARCH_AVR1, AVR_ISA_NONE, NULL, 0x0060, 0x0, 1)
===================================================================
@@ -10182,14 +10182,18 @@ avr_encode_section_info (tree decl, rtx
&& SYMBOL_REF_P (XEXP (rtl, 0)))
{
rtx sym = XEXP (rtl, 0);
+ bool progmem_p = -1 == avr_progmem_p (decl, DECL_ATTRIBUTES (decl));
- if (-1 == avr_progmem_p (decl, DECL_ATTRIBUTES (decl)))
+ if (progmem_p)
{
// Tag symbols for later addition of 0x4000 (AVR_TINY_PM_OFFSET).
SYMBOL_REF_FLAGS (sym) |= AVR_SYMBOL_FLAG_TINY_PM;
}
if (avr_decl_absdata_p (decl, DECL_ATTRIBUTES (decl))
+ || (TARGET_ABSDATA
+ && !progmem_p
+ && !addr_attr)
|| (addr_attr
// If addr_attr is non-null, it has an argument. Peek into it.
&& TREE_INT_CST_LOW (TREE_VALUE (TREE_VALUE (addr_attr))) < 0xc0))
@@ -10198,7 +10202,7 @@ avr_encode_section_info (tree decl, rtx
SYMBOL_REF_FLAGS (sym) |= AVR_SYMBOL_FLAG_TINY_ABSDATA;
}
- if (-1 == avr_progmem_p (decl, DECL_ATTRIBUTES (decl))
+ if (progmem_p
&& avr_decl_absdata_p (decl, DECL_ATTRIBUTES (decl)))
{
error ("%q+D has incompatible attributes %qs and %qs",
===================================================================
@@ -99,6 +99,10 @@ mfract-convert-truncate
Target Report Mask(FRACT_CONV_TRUNC)
Allow to use truncation instead of rounding towards zero for fractional fixed-point types.
+mabsdata
+Target Report Mask(ABSDATA)
+Assume that all data in static storage can be accessed by LDS / STS. This option is only useful for reduced Tiny devices.
+
nodevicelib
Driver Target Report RejectNegative
Do not link against the device-specific library lib<MCU>.a.
===================================================================
@@ -130,6 +130,7 @@ for (arch_mcu = mcu; arch_mcu->macro; )
FILE *f = fopen (name ,"w");
+ bool absdata = 0 != (mcu->dev_attribute & AVR_ISA_LDS);
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);
@@ -189,6 +190,10 @@ bool is_arch = NULL == mcu->macro;
? "\t%{!mno-skip-bug: -mskip-bug}"
: "\t%{!mskip-bug: -mno-skip-bug}");
+ fprintf (f, "*cc1_absdata:\n%s\n\n", absdata
+ ? "\t%{!mno-absdata: -mabsdata}"
+ : "\t%{mabsdata}");
+
// avr-gcc specific specs for assembling / the assembler.
fprintf (f, "*asm_arch:\n\t-mmcu=%s\n\n", arch->name);
===================================================================
@@ -34,7 +34,8 @@ along with GCC; see the file COPYING3.
#define CC1_SPEC \
"%(cc1_n_flash) " \
"%(cc1_errata_skip) " \
- "%(cc1_rmw) "
+ "%(cc1_rmw) " \
+ "%(cc1_absdata) "
#undef CC1PLUS_SPEC
#define CC1PLUS_SPEC \
===================================================================
@@ -650,7 +650,8 @@ -remap -trigraphs -undef -U@var{macro}
-mpure-code}
@emph{AVR Options}
-@gccoptlist{-mmcu=@var{mcu} -maccumulate-args -mbranch-cost=@var{cost} @gol
+@gccoptlist{-mmcu=@var{mcu} -mabsdata -maccumulate-args @gol
+-mbranch-cost=@var{cost} @gol
-mcall-prologues -mint8 -mn_flash=@var{size} -mno-interrupts @gol
-mrelax -mrmw -mstrict-X -mtiny-stack -mfract-convert-truncate -nodevicelib @gol
-Waddr-space-convert -Wmisspelled-isr}
@@ -15261,6 +15262,13 @@ GCC supports the following AVR devices a
@include avr-mmcu.texi
+@item -mabsdata
+@opindex mabsdata
+
+Assume that all data in static stocage can be accessed by LDS / STS
+inctructions. This option has only an effect on reduced Tiny devices like
+ATtiny40.
+
@item -maccumulate-args
@opindex maccumulate-args
Accumulate outgoing function arguments and acquire/release the needed
===================================================================
@@ -0,0 +1,85 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target avr_tiny } */
+/* { dg-options "-mabsdata" } */
+
+typedef struct
+{
+ char a, b, c;
+} abc_t;
+
+extern char varA;
+extern char varB;
+extern const char varC __attribute__((progmem));
+
+extern int arrayA[];
+extern int arrayB[];
+extern char arrayC[] __attribute__((address(0x80)));
+extern char arrayD[] __attribute__((address(0xc0)));
+
+extern abc_t abc;
+
+char get_1 (void)
+{
+ return varA;
+}
+
+int get_2 (void)
+{
+ return arrayA[3];
+}
+
+char get_3 (void)
+{
+ return abc.a + abc.b + abc.c;
+}
+
+char get_4 (void)
+{
+ return varC;
+}
+
+void put_1 (char b)
+{
+ varB = b;
+}
+
+void put_2 (int b)
+{
+ arrayB[3] = b;
+}
+
+void put_3 (void)
+{
+ abc.a = abc.b = abc.c = 0;
+}
+
+void put_4 (void)
+{
+ arrayC[0] = arrayC[1] = arrayC[2] = 0;
+}
+
+void put_5 (void)
+{
+ arrayD[0] = 0;
+}
+
+/* { dg-final { scan-assembler "lds r\[0-9\]+,varA" } } */
+/* { dg-final { scan-assembler "lds r\[0-9\]+,arrayA\\+6" } } */
+/* { dg-final { scan-assembler "lds r\[0-9\]+,arrayA\\+6\\+1" } } */
+/* { dg-final { scan-assembler "lds r\[0-9\]+,abc" } } */
+/* { dg-final { scan-assembler "lds r\[0-9\]+,abc\\+1" } } */
+/* { dg-final { scan-assembler "lds r\[0-9\]+,abc\\+2" } } */
+
+/* { dg-final { scan-assembler "sts varB," } } */
+/* { dg-final { scan-assembler "sts arrayB\\+6," } } */
+/* { dg-final { scan-assembler "sts arrayB\\+6\\+1," } } */
+/* { dg-final { scan-assembler "sts arrayC," } } */
+/* { dg-final { scan-assembler "sts arrayC\\+1," } } */
+/* { dg-final { scan-assembler "sts arrayC\\+2," } } */
+
+/* { dg-final { scan-assembler "sts abc," } } */
+/* { dg-final { scan-assembler "sts abc\\+1," } } */
+/* { dg-final { scan-assembler "sts abc\\+2," } } */
+
+/* { dg-final { scan-assembler-not "lds r\[0-9\]+,varC" } } */
+/* { dg-final { scan-assembler-not "sts arrayD," } } */