Index: config/avr/avr-c.c =================================================================== --- config/avr/avr-c.c (revision 237643) +++ config/avr/avr-c.c (working copy) @@ -334,7 +334,8 @@ start address. This macro shall be used 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) Index: config/avr/avr.c =================================================================== --- config/avr/avr.c (revision 237643) +++ config/avr/avr.c (working copy) @@ -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,30 @@ cond_string (enum rtx_code code) } +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: @@ -8909,6 +8931,12 @@ avr_assemble_integer (rtx x, unsigned in 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); } @@ -9579,7 +9607,8 @@ avr_encode_section_info (tree decl, rtx /* 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); @@ -9610,6 +9639,17 @@ avr_encode_section_info (tree decl, rtx 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))) + { + rtx sym = XEXP (rtl, 0); + SYMBOL_REF_FLAGS (sym) |= AVR_SYMBOL_FLAG_TINY_PM; + } } Index: config/avr/avr.h =================================================================== --- config/avr/avr.h (revision 237643) +++ config/avr/avr.h (working copy) @@ -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. Index: doc/extend.texi =================================================================== --- doc/extend.texi (revision 237587) +++ doc/extend.texi (working copy) @@ -5847,10 +5847,12 @@ attribute accomplishes this by putting r section whose name starts with @code{.progmem}. This attribute works similar to the @code{section} attribute -but adds additional checking. Notice that just like the address@hidden attribute, @code{progmem} affects the location -of the data but not how this data is accessed. +but adds additional checking. address@hidden @asis address@hidden @address@hidden Ordinary AVR cores with 32 general purpose registers: address@hidden affects the location +of the data but not how this data is accessed. In order to read data located with the @code{progmem} attribute (inline) assembler must be used. @smallexample @@ -5873,6 +5875,13 @@ normally resides in the data memory (RAM See also the @ref{AVR Named Address Spaces} section for an alternate way to locate and access data in flash memory. address@hidden @address@hidden AVR Tiny cores like ATtiny40: +The compiler adds @code{0x4000} +to the addresses of objects in @code{progmem}. This is needed because the +flash is visible in the RAM address space starting at address @code{0x4000}. +Data in @code{progmem} can be accessed by means of ordinary address@hidden address@hidden table + @item io @itemx io (@var{addr}) @cindex @code{io} variable attribute, AVR