aboutsummaryrefslogtreecommitdiff
path: root/gcc/config
diff options
context:
space:
mode:
authorGeorg-Johann Lay <avr@gjlay.de>2016-07-20 14:12:16 +0000
committerGeorg-Johann Lay <gjl@gcc.gnu.org>2016-07-20 14:12:16 +0000
commitc25e1d82bf149151af72a8a38db2160b1ca46002 (patch)
tree2bc4015645e9b395fa0a3e6e1abc9653b4d1d21b /gcc/config
parent25e08379b869ba2f2def6d0e9d8443e053f8c3be (diff)
downloadgcc-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.c5
-rw-r--r--gcc/config/avr/avr.c51
-rw-r--r--gcc/config/avr/avr.h2
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.