From d97cca4a46aea362e15fbf3a35f5f8c4f66ded75 Mon Sep 17 00:00:00 2001 From: Georg-Johann Lay Date: Mon, 14 Nov 2016 10:25:34 +0000 Subject: [PATCH] re PR target/78093 ([avr] New variable attribute "absdata" and option "-mabsdata" to enable LDS / STS on Reduced Tiny) gcc/ PR target/78093 * doc/invoke.texi (AVR Options) [-mabsdata]: Document new option. * config/avr/avr.opt (-mabsdata): New option. * config/avr/avr-arch.h (avr_device_specific_features): Add AVR_ISA_LDS. * config/avr/avr.c (avr_encode_section_info) [AVR_TINY]: If -mabsdata & symbol is not progmem, tag as AVR_SYMBOL_FLAG_TINY_ABSDATA. * config/avr/avr-mcus.def (attiny4/5/9/10/20): Use AVR_ISA_LDS. * config/avr/gen-avr-mmcu-specs.c (print_mcu): Print cc1_absdata spec depending on AVR_ISA_LDS. * config/avr/specs.h (CC1_SPEC): Enhanced by cc1_absdata spec. gcc/testsuite/ PR target/78093 * gcc.target/avr/torture/tiny-absdata-2.c: New test. From-SVN: r242379 --- gcc/ChangeLog | 13 +++ gcc/config/avr/avr-arch.h | 4 +- gcc/config/avr/avr-mcus.def | 10 +-- gcc/config/avr/avr.c | 8 +- gcc/config/avr/avr.opt | 4 + gcc/config/avr/gen-avr-mmcu-specs.c | 5 ++ gcc/config/avr/specs.h | 3 +- gcc/doc/invoke.texi | 10 ++- gcc/testsuite/ChangeLog | 5 ++ .../gcc.target/avr/torture/tiny-absdata-2.c | 85 +++++++++++++++++++ 10 files changed, 137 insertions(+), 10 deletions(-) create mode 100644 gcc/testsuite/gcc.target/avr/torture/tiny-absdata-2.c diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 323018240bd..5c53b9bf271 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,16 @@ +2016-11-14 Georg-Johann Lay + + PR target/78093 + * doc/invoke.texi (AVR Options) [-mabsdata]: Document new option. + * config/avr/avr.opt (-mabsdata): New option. + * config/avr/avr-arch.h (avr_device_specific_features): Add AVR_ISA_LDS. + * config/avr/avr.c (avr_encode_section_info) [AVR_TINY]: If + -mabsdata & symbol is not progmem, tag as AVR_SYMBOL_FLAG_TINY_ABSDATA. + * config/avr/avr-mcus.def (attiny4/5/9/10/20): Use AVR_ISA_LDS. + * config/avr/gen-avr-mmcu-specs.c (print_mcu): Print cc1_absdata + spec depending on AVR_ISA_LDS. + * config/avr/specs.h (CC1_SPEC): Enhanced by cc1_absdata spec. + 2016-11-13 Jakub Jelinek * match.pd: Don't try to compare addresses of variables with diff --git a/gcc/config/avr/avr-arch.h b/gcc/config/avr/avr-arch.h index 42eaee56b7b..a740a151105 100644 --- a/gcc/config/avr/avr-arch.h +++ b/gcc/config/avr/avr-arch.h @@ -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. */ diff --git a/gcc/config/avr/avr-mcus.def b/gcc/config/avr/avr-mcus.def index 6bcc6ff08ae..e5b4cdaf660 100644 --- a/gcc/config/avr/avr-mcus.def +++ b/gcc/config/avr/avr-mcus.def @@ -341,11 +341,11 @@ AVR_MCU ("atxmega128a1u", ARCH_AVRXMEGA7, AVR_ISA_RMW, "__AVR_ATxmega128A1U_ 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) diff --git a/gcc/config/avr/avr.c b/gcc/config/avr/avr.c index 7ad2b6422b0..b6899a4b69a 100644 --- a/gcc/config/avr/avr.c +++ b/gcc/config/avr/avr.c @@ -10182,14 +10182,18 @@ avr_encode_section_info (tree decl, rtx rtl, int new_decl_p) && 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 rtl, int new_decl_p) 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", diff --git a/gcc/config/avr/avr.opt b/gcc/config/avr/avr.opt index 1af792b8df0..9ad6c5ab8d7 100644 --- a/gcc/config/avr/avr.opt +++ b/gcc/config/avr/avr.opt @@ -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.a. diff --git a/gcc/config/avr/gen-avr-mmcu-specs.c b/gcc/config/avr/gen-avr-mmcu-specs.c index 7fca756ae62..9ea987f6add 100644 --- a/gcc/config/avr/gen-avr-mmcu-specs.c +++ b/gcc/config/avr/gen-avr-mmcu-specs.c @@ -130,6 +130,7 @@ print_mcu (const avr_mcu_t *mcu) 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 @@ print_mcu (const avr_mcu_t *mcu) ? "\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); diff --git a/gcc/config/avr/specs.h b/gcc/config/avr/specs.h index 52763cc607a..222ad5badae 100644 --- a/gcc/config/avr/specs.h +++ b/gcc/config/avr/specs.h @@ -34,7 +34,8 @@ along with GCC; see the file COPYING3. If not see #define CC1_SPEC \ "%(cc1_n_flash) " \ "%(cc1_errata_skip) " \ - "%(cc1_rmw) " + "%(cc1_rmw) " \ + "%(cc1_absdata) " #undef CC1PLUS_SPEC #define CC1PLUS_SPEC \ diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi index eb89804a8b7..4251bc2010e 100644 --- a/gcc/doc/invoke.texi +++ b/gcc/doc/invoke.texi @@ -650,7 +650,8 @@ Objective-C and Objective-C++ Dialects}. -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} @@ -15310,6 +15311,13 @@ GCC supports the following AVR devices and ISAs: @include avr-mmcu.texi +@item -mabsdata +@opindex mabsdata + +Assume that all data in static storage can be accessed by LDS / STS +instructions. 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 diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 385a2b65361..b87788eaf16 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2016-11-14 Georg-Johann Lay + + PR target/78093 + * gcc.target/avr/torture/tiny-absdata-2.c: New test. + 2016-11-14 Jakub Jelinek Jason Merrill diff --git a/gcc/testsuite/gcc.target/avr/torture/tiny-absdata-2.c b/gcc/testsuite/gcc.target/avr/torture/tiny-absdata-2.c new file mode 100644 index 00000000000..1d98a6b57b7 --- /dev/null +++ b/gcc/testsuite/gcc.target/avr/torture/tiny-absdata-2.c @@ -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," } } */ -- 2.30.2