diff options
author | Georg-Johann Lay <avr@gjlay.de> | 2016-07-20 14:12:16 +0000 |
---|---|---|
committer | Georg-Johann Lay <gjl@gcc.gnu.org> | 2016-07-20 14:12:16 +0000 |
commit | c25e1d82bf149151af72a8a38db2160b1ca46002 (patch) | |
tree | 2bc4015645e9b395fa0a3e6e1abc9653b4d1d21b /gcc/config | |
parent | 25e08379b869ba2f2def6d0e9d8443e053f8c3be (diff) | |
download | gcc-c25e1d82bf149151af72a8a38db2160b1ca46002.zip gcc-c25e1d82bf149151af72a8a38db2160b1ca46002.tar.gz gcc-c25e1d82bf149151af72a8a38db2160b1ca46002.tar.bz2 |
Implement attribute progmem on reduced Tiny cores by adding flash offset 0x4000 to respective symbols.
gcc/
Implement attribute progmem on reduced Tiny cores by adding
flash offset 0x4000 to respective symbols.
PR target/71948
* doc/extend.texi (AVR Variable Attributes) [progmem]: Add
documentation how it works on reduced Tiny cores.
(AVR Named Address Spaces): No support for reduced Tiny.
* config/avr/avr.c (AVR_SYMBOL_FLAG_TINY_PM): New macro.
(avr_address_tiny_pm_p): New static function.
(avr_print_operand_address) [AVR_TINY]: Add AVR_TINY_PM_OFFSET
if the address is in progmem.
(avr_assemble_integer): Same.
(avr_encode_section_info) [AVR_TINY]: Set AVR_SYMBOL_FLAG_TINY_PM
for symbol_ref in progmem.
* config/avr/avr.h (AVR_TINY_PM_OFFSET): New macro.
* config/avr/avr-c.c (avr_cpu_cpp_builtins): Use it instead of
magic 0x4000 when built-in def'ing __AVR_TINY_PM_BASE_ADDRESS__.
gcc/testsuite/
PR target/71948
* gcc.target/avr/torture/tiny-progmem.c: New test.
From-SVN: r238525
Diffstat (limited to 'gcc/config')
-rw-r--r-- | gcc/config/avr/avr-c.c | 5 | ||||
-rw-r--r-- | gcc/config/avr/avr.c | 51 | ||||
-rw-r--r-- | gcc/config/avr/avr.h | 2 |
3 files changed, 54 insertions, 4 deletions
diff --git a/gcc/config/avr/avr-c.c b/gcc/config/avr/avr-c.c index a338a9f..270b803 100644 --- a/gcc/config/avr/avr-c.c +++ b/gcc/config/avr/avr-c.c @@ -296,7 +296,7 @@ avr_cpu_cpp_builtins (struct cpp_reader *pfile) builtin_define_std ("AVR"); /* __AVR_DEVICE_NAME__ and avr_mcu_types[].macro like __AVR_ATmega8__ - are defined by -D command option, see device-specs file. */ + are defined by -D command option, see device-specs file. */ if (avr_arch->macro) cpp_define_formatted (pfile, "__AVR_ARCH__=%s", avr_arch->macro); @@ -337,7 +337,8 @@ avr_cpu_cpp_builtins (struct cpp_reader *pfile) it has been mapped to the data memory. For AVR_TINY devices (ATtiny4/5/9/10/20 and 40) mapped program memory starts at 0x4000. */ - cpp_define (pfile, "__AVR_TINY_PM_BASE_ADDRESS__=0x4000"); + cpp_define_formatted (pfile, "__AVR_TINY_PM_BASE_ADDRESS__=0x%x", + AVR_TINY_PM_OFFSET); } if (AVR_HAVE_EIJMP_EICALL) diff --git a/gcc/config/avr/avr.c b/gcc/config/avr/avr.c index 6553cd8..95f691c 100644 --- a/gcc/config/avr/avr.c +++ b/gcc/config/avr/avr.c @@ -80,6 +80,10 @@ ((SYMBOL_REF_FLAGS (sym) & AVR_SYMBOL_FLAG_PROGMEM) \ / SYMBOL_FLAG_MACH_DEP) +/* (AVR_TINY only): Symbol has attribute progmem */ +#define AVR_SYMBOL_FLAG_TINY_PM \ + (SYMBOL_FLAG_MACH_DEP << 4) + #define TINY_ADIW(REG1, REG2, I) \ "subi " #REG1 ",lo8(-(" #I "))" CR_TAB \ "sbci " #REG2 ",hi8(-(" #I "))" @@ -2161,12 +2165,35 @@ cond_string (enum rtx_code code) } +/* Return true if rtx X is a CONST or SYMBOL_REF with progmem. + This must be used for AVR_TINY only because on other cores + the flash memory is not visible in the RAM address range and + cannot be read by, say, LD instruction. */ + +static bool +avr_address_tiny_pm_p (rtx x) +{ + if (CONST == GET_CODE (x)) + x = XEXP (XEXP (x, 0), 0); + + if (SYMBOL_REF_P (x)) + return SYMBOL_REF_FLAGS (x) & AVR_SYMBOL_FLAG_TINY_PM; + + return false; +} + /* Implement `TARGET_PRINT_OPERAND_ADDRESS'. */ /* Output ADDR to FILE as address. */ static void 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); + } + switch (GET_CODE (addr)) { case REG: @@ -8937,6 +8964,12 @@ avr_assemble_integer (rtx x, unsigned int size, int aligned_p) return true; } + if (AVR_TINY + && avr_address_tiny_pm_p (x)) + { + x = plus_constant (Pmode, x, AVR_TINY_PM_OFFSET); + } + return default_assemble_integer (x, size, aligned_p); } @@ -9603,7 +9636,7 @@ avr_encode_section_info (tree decl, rtx rtl, int new_decl_p) if (decl && DECL_P (decl) && TREE_CODE (decl) != FUNCTION_DECL && MEM_P (rtl) - && SYMBOL_REF == GET_CODE (XEXP (rtl, 0))) + && SYMBOL_REF_P (XEXP (rtl, 0))) { rtx sym = XEXP (rtl, 0); tree type = TREE_TYPE (decl); @@ -9616,7 +9649,8 @@ avr_encode_section_info (tree decl, rtx rtl, int new_decl_p) /* PSTR strings are in generic space but located in flash: patch address space. */ - if (-1 == avr_progmem_p (decl, attr)) + if (!AVR_TINY + && -1 == avr_progmem_p (decl, attr)) as = ADDR_SPACE_FLASH; AVR_SYMBOL_SET_ADDR_SPACE (sym, as); @@ -9647,6 +9681,19 @@ avr_encode_section_info (tree decl, rtx rtl, int new_decl_p) if (addr_attr && !DECL_EXTERNAL (decl)) SYMBOL_REF_FLAGS (sym) |= SYMBOL_FLAG_ADDRESS; } + + if (AVR_TINY + && decl + && VAR_DECL == TREE_CODE (decl) + && -1 == avr_progmem_p (decl, DECL_ATTRIBUTES (decl)) + && MEM_P (rtl) + && SYMBOL_REF_P (XEXP (rtl, 0))) + { + /* Tag symbols for later addition of 0x4000 (AVR_TINY_PM_OFFSET). */ + + rtx sym = XEXP (rtl, 0); + SYMBOL_REF_FLAGS (sym) |= AVR_SYMBOL_FLAG_TINY_PM; + } } diff --git a/gcc/config/avr/avr.h b/gcc/config/avr/avr.h index ab5e465..5eb90b5 100644 --- a/gcc/config/avr/avr.h +++ b/gcc/config/avr/avr.h @@ -74,6 +74,8 @@ 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. |