[Patch]: PR49868: Named address space support for AVR, #5
Georg-Johann Lay
avr@gjlay.de
Thu Nov 17 14:02:00 GMT 2011
Denis Chertykov wrote:
> Let's wait for
> http://gcc.gnu.org/ml/gcc-patches/2011-10/msg01874.html
> Denis.
This are yet more intrinsic named address spaces:
* __pgm1, ... __pgm5 are 16-bit address spaces that refer to
the n-th 64k chunk of flash. Counting starts at 0.
The 0-th address space __pgm is already upstream.
* __pgmx is a 24-bit address space located in flash.
The annoyance in this patch is the movmemhi insn:
* Register allocator does a bad job and might lead to spills
inside the copy loop so that it is no more guaranteed that
tmp_reg contains the value to be copied because move insns
use that register implicitly. Besides that, spilling in
the copy loop leads to unfortunate code. See respective
FIXMEs in avr.c:avr_emit_movmemhi()
* Using match_dup in respective patterns shreds web.c to that
the insns need up to with 11 operands.
Besides that there are caveats and binutils is missing some support:
* To place variables in __pgm1 ... __pgm5 in appropriate sections
a custom linker script is needed. Data is put in sections
progmem1.data ... __progmem5.data, respectively, and these
sections must be treated in the linker script.
* Address computation for the 24-bit address space is performed
as signed 16-bit. Thus, accessing an array var[i] for example
it is not possible to reach locations that are farther away
than +/- 32768 bytes from var[0].
* It is not possible to assemble a 24-bit address, see the
assembler warning generated in avr.c:avr_assemble_integer().
This warning is triggered for code like
extern const __pgmx int ivar;
const __pgmx void * var = &ivar;
.global var
.data
.type var, @object
.size var, 3
var:
.word ivar
.warning "24-bit address needs binutils extension for hh8(ivar)"
.byte 0 ; hh8(ivar)
The patch passes C tests with one FAIL less (SVN 181349):
gcc.dg/pr43300.c (internal compiler error)
./gcc.dg/pr43300.c: In function 'foo':
./gcc.dg/pr43300.c:19:1: internal compiler error: in commit_one_edge_insertion,
at cfgrtl.c:1582
This tests passes now; seems that the changes to movmemhi allow that test to
PASS now (for whatever reason).
Ok for trunk?
Johann
gcc/
PR target/49868
* config/avr/avr.h (base_arch_s): Add field n_segments.
(ADDR_SPACE_PGM1, ADDR_SPACE_PGM2, ADDR_SPACE_PGM3,
ADDR_SPACE_PGM4, ADDR_SPACE_PGM5, ADDR_SPACE_PGMX): New address spaces.
(AVR_HAVE_ELPM, AVR_HAVE_ELPMX): New defines.
(INIT_EXPANDERS): New define.
* config/avr/avr-protos.h (avr_mem_pgmx_p): New.
(avr_init_expanders): New.
(avr_emit_movmemhi, avr_out_movmem): New.
(avr_xload_libgcc_p): New.
* config/avr/avr-c.c (avr_register_target_pragmas): Register
address spaces __pgm1, __pgm2, __pgm3, __pgm4 __pgm5, __pgmx.
(avr_cpu_cpp_builtins): Add built-in defines __PGM1,
__PGM2, __PGM3, __PGM4, __PGM5, __PGMX.
* config/avr/avr-devices.c (avr_arch_types): Set field n_segments.
* config/avr/avr.c (AVR_SECTION_PROGMEM): Change define to cover
3 bits instead of just 1.
(xstring_empty, xstring_e, rampz_rtx): New static GTYed variables.
(progmem_section): Change from section to array of sections.
(progmem_section_prefix): New static variable.
(avr_file_start): Print set for __RAMPZ__
(avr_option_override): Move initialization of RTXes from here...
(avr_init_expanders): ...to this new function.
(avr_pgm_segment): New static function.
(avr_decl_pgm_p): Handle error_mark_node.
(avr_mem_pgmx_p, avr_decl_pgmx_p): New static functions.
(avr_out_xload, avr_find_unused_d_reg): New static functions.
(expand_prologue, expand_epilogue): Use rampz_rtx.
(print_operand): Hande CONST_STRING.
(avr_xload_libgcc_p): New static function.
(avr_out_lpm_no_lpmx, avr_out_lpm): Handle ELPM.
(avr_progmem_p): Return 2 for 24-bit flash address space.
(avr_out_sbxx_branch): Clean-up code from ASn macros.
(out_movqi_r_mr, out_movqi_mr_r): Ditto. And recognize RAMPZ's
address and print symbolically.
(avr_asm_named_section, avr_section_type_flags,
avr_encode_section_info, avr_asm_select_section,
avr_addr_space_address_mode, avr_addr_space_pointer_mode,
avr_addr_space_legitimate_address_p, avr_addr_space_convert,
avr_addr_space_legitimize_address): Handle new address spaces.
(avr_output_progmem_section_asm_op): New static function.
(avr_asm_init_sections): Initialize progmem_section[].
(adjust_insn_length): Handle ADJUST_LEN_XLOAD, ADJUST_LEN_MOVMEM.
(avr_const_address_lo16): New static function.
(avr_assemble_integer): Use it to handle 3-byte integers.
(avr_emit_movmemhi, avr_out_movmem): New functions.
* config/avr/constraints.md (Cpp): New constraint.
* config/avr/predicates.md (nox_general_operand): Handle new
address spaces.
* config/avr/avr.md (unspec): Add UNSPEC_MOVMEM.
(adjust_len): Add xload, movmem.
(SP_ADDR): New define_constants.
(isa): Add "lpm", "lpmx", "elpm", "elpmx".
(enabled): Handle them.
(load<mode>_libgcc): New expander.
(*load.<mode>.libgcc): Rename to load_<mode>_libgcc.
(xload8_A, xload<mode>_A, n_extendhipsi2): New insn-and-splits.
(xload_8, xload_<mode>_libgcc, xload_<mode>, loadmem_elpm): New insns.
(mov<mode>): Handle new address spaces.
(movmemhi): Rewrite using avr_emit_movmemhi.
(MOVMEM_r_d): New mode attribute.
(movmem_<mode>, movmem_qi_elpm): New insns.
(setmemhi, *clrmemqi, *clrmemhi, strlenhi, *strlenhi): Unquote
C-code. Use label instead of hard-coded instrunction lengths.
libgcc/
PR target/49868
* config/avr/t-avr (LIB1ASMFUNCS): Add _xload_2 _xload_3 _xload_4.
* config/avr/lib1funcs.S (__xload_2, __xload_3, __xload_4):
New functions.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: pgmx-8-b.diff
Type: text/x-patch
Size: 74276 bytes
Desc: not available
URL: <http://gcc.gnu.org/pipermail/gcc-patches/attachments/20111117/50851e4a/attachment.bin>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: pgmx-8-b-libgcc.diff
Type: text/x-patch
Size: 2056 bytes
Desc: not available
URL: <http://gcc.gnu.org/pipermail/gcc-patches/attachments/20111117/50851e4a/attachment-0001.bin>
More information about the Gcc-patches
mailing list