Currently avr_assemble_integer emits an assembler warning to make gas complain about missing feature
http://sourceware.org/PR13503 if a 3-byte address must be assembled. As PR13503 is implemented now, avr-gcc can use this feature. It's only needed for the new __memx address space. Ok to install? The feature is new in gcc and binutils and only rarely used, IMHO. The current solution will throw a comprehensible warning but generate bad code, with the patch old binutils will throw a not really helpful diagnose but work with new binutils... Thus okay to backport? Or leave 4.7 as is? Johann PR target/46898 * config/avr/avr.c (avr_const_address_lo16): Remove. (avr_assemble_integer): Print ".byte lo8(x)", ".byte hi8(x)", ".byte hh8(x)" instead of emit an assembler .warning if 3-byte address is assembled. * doc/extend.texi (AVR Named Address Spaces): Document that binutils 2.23 is needed to assemble 3-byte addresses.
Index: config/avr/avr.c =================================================================== --- config/avr/avr.c (revision 187411) +++ config/avr/avr.c (working copy) @@ -6639,48 +6639,6 @@ _reg_unused_after (rtx insn, rtx reg) } -/* Return RTX that represents the lower 16 bits of a constant address. - Unfortunately, simplify_gen_subreg does not handle this case. */ - -static rtx -avr_const_address_lo16 (rtx x) -{ - rtx lo16; - - switch (GET_CODE (x)) - { - default: - break; - - case CONST: - if (PLUS == GET_CODE (XEXP (x, 0)) - && SYMBOL_REF == GET_CODE (XEXP (XEXP (x, 0), 0)) - && CONST_INT_P (XEXP (XEXP (x, 0), 1))) - { - HOST_WIDE_INT offset = INTVAL (XEXP (XEXP (x, 0), 1)); - const char *name = XSTR (XEXP (XEXP (x, 0), 0), 0); - - lo16 = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (name)); - lo16 = gen_rtx_CONST (Pmode, plus_constant (Pmode, lo16, offset)); - - return lo16; - } - - break; - - case SYMBOL_REF: - { - const char *name = XSTR (x, 0); - - return gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (name)); - } - } - - avr_edump ("\n%?: %r\n", x); - gcc_unreachable(); -} - - /* Target hook for assembling integer objects. The AVR version needs special handling for references to certain labels. */ @@ -6688,7 +6646,7 @@ static bool avr_assemble_integer (rtx x, unsigned int size, int aligned_p) { if (size == POINTER_SIZE / BITS_PER_UNIT && aligned_p - && text_segment_operand (x, VOIDmode) ) + && text_segment_operand (x, VOIDmode)) { fputs ("\t.word\tgs(", asm_out_file); output_addr_const (asm_out_file, x); @@ -6698,15 +6656,17 @@ avr_assemble_integer (rtx x, unsigned in } else if (GET_MODE (x) == PSImode) { - default_assemble_integer (avr_const_address_lo16 (x), - GET_MODE_SIZE (HImode), aligned_p); + /* This needs binutils 2.23+, see PR binutils/13503 */ + + fputs ("\t.byte\tlo8(", asm_out_file); + output_addr_const (asm_out_file, x); + fputs (")\n", asm_out_file); - fputs ("\t.warning\t\"assembling 24-bit address needs binutils" - " extension for hh8(", asm_out_file); + fputs ("\t.byte\thi8(", asm_out_file); output_addr_const (asm_out_file, x); - fputs (")\"\n", asm_out_file); + fputs (")\n", asm_out_file); - fputs ("\t.byte\t0\t" ASM_COMMENT_START " hh8(", asm_out_file); + fputs ("\t.byte\thh8(", asm_out_file); output_addr_const (asm_out_file, x); fputs (")\n", asm_out_file); Index: doc/extend.texi =================================================================== --- doc/extend.texi (revision 187411) +++ doc/extend.texi (working copy) @@ -1273,6 +1273,7 @@ If the high bit of the address is set, d RAM using the lower two bytes as RAM address. If the high bit of the address is clear, data is read from flash with @code{RAMPZ} set according to the high byte of the address. +@xref{AVR Built-in Functions,,@code{__builtin_avr_flash_segment}}. Objects in this address space will be located in @code{.progmem.data}. @end table @@ -1302,6 +1303,7 @@ int main (void) @} @end example +@noindent For each named address space supported by avr-gcc there is an equally named but uppercase built-in macro defined. The purpose is to facilitate testing if respective address space @@ -1327,7 +1329,8 @@ int read_var (void) #endif /* __FLASH */ @end example -Notice that attribute @ref{AVR Variable Attributes,@code{progmem}} +@noindent +Notice that attribute @ref{AVR Variable Attributes,,@code{progmem}} locates data in flash but accesses to these data will read from generic address space, i.e.@: from RAM, @@ -1335,6 +1338,7 @@ so that you need special accessors like from @w{@uref{http://nongnu.org/avr-libc/user-manual,AVR-LibC}} together with attribute @code{progmem}. +@noindent @b{Limitations and caveats} @itemize @@ -1361,17 +1365,14 @@ must not optimize away known values or i as immediates into operands of instructions. @item -Code like the following is not yet supported because of missing -support in avr-binutils, -see @w{@uref{http://sourceware.org/PR13503,PR13503}}. +The following code initializes a variable @code{pfoo} +located in static storage with a 24-bit address: @example extern const __memx char foo; const __memx void *pfoo = &foo; @end example -The code will throw an assembler warning and the high byte of -@code{pfoo} will be initialized with@tie{}@code{0}, i.e.@: the -initialization will be as if @code{foo} was located in the first -64@tie{}KiB chunk of flash. +Such code requires at least binutils 2.23, see +@w{@uref{http://sourceware.org/PR13503,PR13503}}. @end itemize