Re: [Patch]: PR49868: Named address space support for AVR, #5
2011/11/17 Georg-Johann Lay : > 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, ADJ
Re: [Patch]: PR49868: Named address space support for AVR, #4
2011/11/15 Georg-Johann Lay : > Denis Chertykov wrote: > >> Let's wait for >> http://gcc.gnu.org/ml/gcc-patches/2011-10/msg01874.html > > As that patch is now upstream, here the updated version. > > Difference to the prior implementation of AS1 is: > > o If no LPMX instruction is available and more than 2 bytes > have to be loaded, a libgcc call is used. This also makes > the implementation simpler. > > > o Some functions are more general than actually needed. > This will reduce the number of changes for the 24-bit > address spaces. > > o There are 2 new predicates to filter out loads from > non-generic address space. This is needed in shift > insns for example because they allow mem. > > Tested without regressions. > > Ok for trunk? > > Johann > > gcc/ > PR target/49868 > * config/avr/avr.h (ADDR_SPACE_PGM): New address spaces. > (REGISTER_TARGET_PRAGMAS): New define. > * config/avr/avr-protos.h (avr_mem_pgm_p): New. > (avr_load_libgcc_p): New. > (asm_output_external_libcall): Remove. > (avr_register_target_pragmas): New. > (avr_log_t): Add field "progmem". Order alphabetically. > * config/avr/avr-log.c (avr_log_set_avr_log): Set avr_log.progmem. > * config/avr/avr-c.c (langhooks.h): New include. > (avr_register_target_pragmas): New function. Register address > space __pgm. > (avr_cpu_cpp_builtins): Add built-in define __PGM. > * config/avr/avr-devices.c (avr_arch_types): Set field n_segments. > > * config/avr/avr.c: Include "c-family/c-common.h". > (TARGET_LEGITIMATE_ADDRESS_P): Remove define. > (TARGET_LEGITIMIZE_ADDRESS): Remove define. > (TARGET_ADDR_SPACE_SUBSET_P): Define to... > (avr_addr_space_subset_p): ...this new static function. > (TARGET_ADDR_SPACE_CONVERT): Define to... > (avr_addr_space_convert): ...this new static function. > (TARGET_ADDR_SPACE_ADDRESS_MODE): Define to... > (avr_addr_space_address_mode): ...this new static function. > (TARGET_ADDR_SPACE_POINTER_MODE): Define to... > (avr_addr_space_pointer_mode): ...this new static function. > (TARGET_ADDR_SPACE_LEGITIMATE_ADDRESS_P): Define to... > (avr_addr_space_legitimate_address_p): ...this new static function. > (TARGET_ADDR_SPACE_LEGITIMIZE_ADDRESS): Define to... > (avr_addr_space_legitimize_address): ...this new static function. > (avr_mode_code_base_reg_class): Handle address spaces. > (avr_regno_mode_code_ok_for_base_p): Ditto. > (lpm_addr_reg_rtx, lpm_reg_rtx, all_regs_rtx): New static variables. > (avr_option_override): Initialize them. > (output_reload_in_const): Use all_regs_rtx. Fix signedness of loop > variables. > (avr_pgm_segment): New static function. > (avr_decl_pgm_p, avr_mem_pgm_p): New static functions. > (avr_out_lpm, avr_out_lpm_no_lpmx): New static functions. > (output_movqi, output_movhi, output_movsisf, avr_out_movpsi): Call > avr_out_lpm to handle loads from progmem. > (avr_load_libgcc_p): New static function. > (avr_progmem_p): Test if decl is in flash. > (avr_pgm_pointer_const_p): New static function. > (avr_nonconst_pointer_addrspace): New static function. > (avr_pgm_check_var_decl): New static function. > (avr_insert_attributes): Use it. Change error message to report > cause (progmem or address space) when code wants to write to flash. > (avr_section_type_flags): Unset section flag SECTION_BSS for > data in progmem. > > * config/avr/predicates.md (nop_general_operand): New predicate. > (nox_general_operand): New predicate. > * config/avr/avr.md (LPM_REGNO): New define_constant. > (load_libgcc): New expander. > (*load..libgcc): New insn. > (mov): Handle loads from non-generic AS. > (movmemhi): Ditto. Propagate address space information to newly > created MEM. > (movqi_insn, *movhi, *movpsi, *movsi, *movsf): Change predicate #1 > to nox_general_operand. > (ashrqi3, ashrhi3, ashrsi3): Change predicate #1 to > nop_general_operand. > (ashlqi3, *ashlqi3, ashlhi3, ashlsi3): Ditto. > (lshrqi3, *lshrqi3, lshrhi3, lshrsi3): Ditto. > (split-lpmx): New split. > (*ashlhi3_const, *ashlsi3_const, *ashrhi3_const, *ashrsi3_const, > *lshrhi3_const, *lshrsi3_const): Indent, unquote C. > > libgcc/ > PR target/49868 > * config/avr/t-avr (LIB1ASMFUNCS): Add _load_3, _load_4. > * config/avr/lib1funcs.S (__load_3, __load_4, __xload_2): New > functions. > Please commit. Denis.
Re: [Patch]: PR49868: Named address space support for AVR, #4
Denis Chertykov wrote: > Let's wait for > http://gcc.gnu.org/ml/gcc-patches/2011-10/msg01874.html As that patch is now upstream, here the updated version. Difference to the prior implementation of AS1 is: o If no LPMX instruction is available and more than 2 bytes have to be loaded, a libgcc call is used. This also makes the implementation simpler. o Some functions are more general than actually needed. This will reduce the number of changes for the 24-bit address spaces. o There are 2 new predicates to filter out loads from non-generic address space. This is needed in shift insns for example because they allow mem. Tested without regressions. Ok for trunk? Johann gcc/ PR target/49868 * config/avr/avr.h (ADDR_SPACE_PGM): New address spaces. (REGISTER_TARGET_PRAGMAS): New define. * config/avr/avr-protos.h (avr_mem_pgm_p): New. (avr_load_libgcc_p): New. (asm_output_external_libcall): Remove. (avr_register_target_pragmas): New. (avr_log_t): Add field "progmem". Order alphabetically. * config/avr/avr-log.c (avr_log_set_avr_log): Set avr_log.progmem. * config/avr/avr-c.c (langhooks.h): New include. (avr_register_target_pragmas): New function. Register address space __pgm. (avr_cpu_cpp_builtins): Add built-in define __PGM. * config/avr/avr-devices.c (avr_arch_types): Set field n_segments. * config/avr/avr.c: Include "c-family/c-common.h". (TARGET_LEGITIMATE_ADDRESS_P): Remove define. (TARGET_LEGITIMIZE_ADDRESS): Remove define. (TARGET_ADDR_SPACE_SUBSET_P): Define to... (avr_addr_space_subset_p): ...this new static function. (TARGET_ADDR_SPACE_CONVERT): Define to... (avr_addr_space_convert): ...this new static function. (TARGET_ADDR_SPACE_ADDRESS_MODE): Define to... (avr_addr_space_address_mode): ...this new static function. (TARGET_ADDR_SPACE_POINTER_MODE): Define to... (avr_addr_space_pointer_mode): ...this new static function. (TARGET_ADDR_SPACE_LEGITIMATE_ADDRESS_P): Define to... (avr_addr_space_legitimate_address_p): ...this new static function. (TARGET_ADDR_SPACE_LEGITIMIZE_ADDRESS): Define to... (avr_addr_space_legitimize_address): ...this new static function. (avr_mode_code_base_reg_class): Handle address spaces. (avr_regno_mode_code_ok_for_base_p): Ditto. (lpm_addr_reg_rtx, lpm_reg_rtx, all_regs_rtx): New static variables. (avr_option_override): Initialize them. (output_reload_in_const): Use all_regs_rtx. Fix signedness of loop variables. (avr_pgm_segment): New static function. (avr_decl_pgm_p, avr_mem_pgm_p): New static functions. (avr_out_lpm, avr_out_lpm_no_lpmx): New static functions. (output_movqi, output_movhi, output_movsisf, avr_out_movpsi): Call avr_out_lpm to handle loads from progmem. (avr_load_libgcc_p): New static function. (avr_progmem_p): Test if decl is in flash. (avr_pgm_pointer_const_p): New static function. (avr_nonconst_pointer_addrspace): New static function. (avr_pgm_check_var_decl): New static function. (avr_insert_attributes): Use it. Change error message to report cause (progmem or address space) when code wants to write to flash. (avr_section_type_flags): Unset section flag SECTION_BSS for data in progmem. * config/avr/predicates.md (nop_general_operand): New predicate. (nox_general_operand): New predicate. * config/avr/avr.md (LPM_REGNO): New define_constant. (load_libgcc): New expander. (*load..libgcc): New insn. (mov): Handle loads from non-generic AS. (movmemhi): Ditto. Propagate address space information to newly created MEM. (movqi_insn, *movhi, *movpsi, *movsi, *movsf): Change predicate #1 to nox_general_operand. (ashrqi3, ashrhi3, ashrsi3): Change predicate #1 to nop_general_operand. (ashlqi3, *ashlqi3, ashlhi3, ashlsi3): Ditto. (lshrqi3, *lshrqi3, lshrhi3, lshrsi3): Ditto. (split-lpmx): New split. (*ashlhi3_const, *ashlsi3_const, *ashrhi3_const, *ashrsi3_const, *lshrhi3_const, *lshrsi3_const): Indent, unquote C. libgcc/ PR target/49868 * config/avr/t-avr (LIB1ASMFUNCS): Add _load_3, _load_4. * config/avr/lib1funcs.S (__load_3, __load_4, __xload_2): New functions. Index: config/avr/predicates.md === --- config/avr/predicates.md (revision 181349) +++ config/avr/predicates.md (working copy) @@ -57,6 +57,17 @@ (define_predicate "io_address_operand" (and (match_code "const_int") (match_test "IN_RANGE((INTVAL (op)), 0x20, (0x60 - GET_MODE_SIZE(mode)))"))) +;; Return 1 if OP is a general operand not in program memory +(de
Re: [Patch]: PR49868: Named address space support for AVR
Let's wait for http://gcc.gnu.org/ml/gcc-patches/2011-10/msg01874.html Denis.
Re: [Patch]: PR49868: Named address space support for AVR
Georg-Johann Lay wrote: > Denis Chertykov wrote: >> 2011/10/28 Georg-Johann Lay : >>> Georg-Johann Lay schrieb: >>> This patch adds named address space support to read data from flash (aka. progmem) to target AVR. The patch has two parts: The first part is a repost of Ulrich's work from http://gcc.gnu.org/ml/gcc/2011-08/msg00131.html with the needed changes to ./gcc and ./gcc/doc This patch is needed because the target hooks MODE_CODE_BASE_REG_CLASS and REGNO_MODE_CODE_OK_FOR_BASE_P don't distinguish between different address spaces. Ulrich's patch adds respective support to these hooks. The second part is the AVR dependent part that adds __pgm as address space qualifier for address space AS1. The AVR part is just the worker code. If there is agreement that AS support for AVR is okay in principle and Ulrich's work will go into GCC, I will supply test programs and updates to the user manual, of course. The major drawbacks of the current AS implementation are: - It works only for C. For C++, a language extension would be needed as indicated in ISO/IEC DTR 18037 Annex F - C++ Compatibility and Migration issues F.2 Multiple Address Spaces Support - Register allocation does not a good job. AS1 can only be addressed byte-wise by one single address register (Z) as per *Z or *Z++. >>> This flaw from register allocator are filed as PR50775 now. >>> The AVR part does several things: - It locates data in AS1 into appropriate section, i.e. somewhere in .progmem - It does early sanity checks to ensure that __pgm is always accompanied with const so that writing to AS1 in not possible. - It prints LPM instructions to access flash memory. >>> The attached patch is an update merge so that it fits without conflicts. >>> >>> The patch requires Ulrich's works which is still in review >>> http://gcc.gnu.org/bugzilla/show_bug.cgi?id=50775 >>> >>> The regression tests run with this patch and the new ChangeLog enttry si >>> written as if Ulrich's patch was applied. >>> >>> Tests pass without regression. >>> >>> Besides the update to a nor up-to-date SVN version, the patch sets a >>> built-in >>> define __PGM so that it is easy for users to test if or if not the feature >>> is >>> available. >>> >>> Documentation and test cases will follow in separate patch. >>> >>> Ok for trunk after Ulrich's work has been approved? >>> >>> Johann >>> >>>PR target/49868 >>>* config/avr/avr.h (ADDR_SPACE_PGM): New define for address space >>> AS1. >>>(REGISTER_TARGET_PRAGMAS): New define. >>>* config/avr/avr-protos.h (avr_mem_pgm_p): New prototype. >>>(avr_register_target_pragmas): New prototype. >>>(avr_log_t): Add field "progmem". Order alphabetically. >>>* config/avr/avr-log.c (avr_log_set_avr_log): Set avr_log.progmem. >>>* config/avr/avr-c.c (langhooks.h): New include. >>>(avr_register_target_pragmas): New function. Register address >>>space AS1 as "__pgm". >>>(avr_cpu_cpp_builtins): Add built-in define __PGM. >>>* config/avr/avr.c: Include "c-family/c-common.h". >>>(TARGET_LEGITIMATE_ADDRESS_P): Remove define. >>>(TARGET_LEGITIMIZE_ADDRESS): Remove define. >>>(TARGET_ADDR_SPACE_SUBSET_P): Define to... >>>(avr_addr_space_subset_p): ...this new static function. >>>(TARGET_ADDR_SPACE_CONVERT): Define to... >>>(avr_addr_space_convert): ...this new static function. >>>(TARGET_ADDR_SPACE_ADDRESS_MODE): Define to... >>>(avr_addr_space_address_mode): ...this new static function. >>>(TARGET_ADDR_SPACE_POINTER_MODE): Define to... >>>(avr_addr_space_pointer_mode): ...this new static function. >>>(TARGET_ADDR_SPACE_LEGITIMATE_ADDRESS_P): Define to... >>>(avr_addr_space_legitimate_address_p): ...this new static function. >>>(TARGET_ADDR_SPACE_LEGITIMIZE_ADDRESS): Define to... >>>(avr_addr_space_legitimize_address): ...this new static function. >>>(avr_mode_code_base_reg_class): Handle AS1. >>>(avr_regno_mode_code_ok_for_base_p): Handle AS1. >>>(lpm_addr_reg_rtx, lpm_reg_rtx): New static GTYed variables. >>>(avr_decl_pgm_p): New static function. >>>(avr_mem_pgm_p): New function. >>>(avr_asm_len): Return always "" instead of void. >>>(avr_out_lpm_no_lpmx): New static function. >>>(avr_out_lpm): New static function. >>>(output_movqi, output_movhi, output_movsisf): Call avr_out_lpm to >>>handle loads from progmem. >>>(avr_progmem_p): Test if decl is in AS1. >>>(avr_pgm_pointer_const_p): New static function. >>>(avr_pgm_check_var_decl): New static function. >>>(avr_insert_attributes): Use it. Change error me
Re: [Patch]: PR49868: Named address space support for AVR
2011/10/28 Georg-Johann Lay : > Georg-Johann Lay schrieb: > >> This patch adds named address space support to read data from flash (aka. >> progmem) to target AVR. >> >> The patch has two parts: >> >> The first part is a repost of Ulrich's work from >> http://gcc.gnu.org/ml/gcc/2011-08/msg00131.html >> with the needed changes to ./gcc and ./gcc/doc >> >> This patch is needed because the target hooks MODE_CODE_BASE_REG_CLASS and >> REGNO_MODE_CODE_OK_FOR_BASE_P don't distinguish between different address >> spaces. Ulrich's patch adds respective support to these hooks. >> >> The second part is the AVR dependent part that adds __pgm as address space >> qualifier for address space AS1. >> >> The AVR part is just the worker code. If there is agreement that AS support >> for AVR is okay in principle and Ulrich's work will go into GCC, I will >> supply >> test programs and updates to the user manual, of course. >> >> The major drawbacks of the current AS implementation are: >> >> - It works only for C. >> For C++, a language extension would be needed as indicated in >> ISO/IEC DTR 18037 >> Annex F - C++ Compatibility and Migration issues >> F.2 Multiple Address Spaces Support >> >> - Register allocation does not a good job. AS1 can only be addressed >> byte-wise by one single address register (Z) as per *Z or *Z++. > > This flaw from register allocator are filed as PR50775 now. > >> The AVR part does several things: >> >> - It locates data in AS1 into appropriate section, i.e. somewhere in >> .progmem >> >> - It does early sanity checks to ensure that __pgm is always accompanied >> with const so that writing to AS1 in not possible. >> >> - It prints LPM instructions to access flash memory. > > The attached patch is an update merge so that it fits without conflicts. > > The patch requires Ulrich's works which is still in review > http://gcc.gnu.org/bugzilla/show_bug.cgi?id=50775 > > The regression tests run with this patch and the new ChangeLog enttry si > written as if Ulrich's patch was applied. > > Tests pass without regression. > > Besides the update to a nor up-to-date SVN version, the patch sets a built-in > define __PGM so that it is easy for users to test if or if not the feature is > available. > > Documentation and test cases will follow in separate patch. > > Ok for trunk after Ulrich's work has been approved? > > Johann > > PR target/49868 > * config/avr/avr.h (ADDR_SPACE_PGM): New define for address space AS1. > (REGISTER_TARGET_PRAGMAS): New define. > * config/avr/avr-protos.h (avr_mem_pgm_p): New prototype. > (avr_register_target_pragmas): New prototype. > (avr_log_t): Add field "progmem". Order alphabetically. > * config/avr/avr-log.c (avr_log_set_avr_log): Set avr_log.progmem. > * config/avr/avr-c.c (langhooks.h): New include. > (avr_register_target_pragmas): New function. Register address > space AS1 as "__pgm". > (avr_cpu_cpp_builtins): Add built-in define __PGM. > * config/avr/avr.c: Include "c-family/c-common.h". > (TARGET_LEGITIMATE_ADDRESS_P): Remove define. > (TARGET_LEGITIMIZE_ADDRESS): Remove define. > (TARGET_ADDR_SPACE_SUBSET_P): Define to... > (avr_addr_space_subset_p): ...this new static function. > (TARGET_ADDR_SPACE_CONVERT): Define to... > (avr_addr_space_convert): ...this new static function. > (TARGET_ADDR_SPACE_ADDRESS_MODE): Define to... > (avr_addr_space_address_mode): ...this new static function. > (TARGET_ADDR_SPACE_POINTER_MODE): Define to... > (avr_addr_space_pointer_mode): ...this new static function. > (TARGET_ADDR_SPACE_LEGITIMATE_ADDRESS_P): Define to... > (avr_addr_space_legitimate_address_p): ...this new static function. > (TARGET_ADDR_SPACE_LEGITIMIZE_ADDRESS): Define to... > (avr_addr_space_legitimize_address): ...this new static function. > (avr_mode_code_base_reg_class): Handle AS1. > (avr_regno_mode_code_ok_for_base_p): Handle AS1. > (lpm_addr_reg_rtx, lpm_reg_rtx): New static GTYed variables. > (avr_decl_pgm_p): New static function. > (avr_mem_pgm_p): New function. > (avr_asm_len): Return always "" instead of void. > (avr_out_lpm_no_lpmx): New static function. > (avr_out_lpm): New static function. > (output_movqi, output_movhi, output_movsisf): Call avr_out_lpm to > handle loads from progmem. > (avr_progmem_p): Test if decl is in AS1. > (avr_pgm_pointer_const_p): New static function. > (avr_pgm_check_var_decl): New static function. > (avr_insert_attributes): Use it. Change error message to report > cause (progmem or AS1) when code wants to write to AS1. > (avr_section_type_flags): Unset section flag SECTION_BSS for > data in progmem. > * config/avr/avr.md (LPM_REGNO): New define_constants. > (movqi, movhi, movsi, movsf
Re: [Patch]: PR49868: Named address space support for AVR
> The patch requires Ulrich's works which is still in review Now the correct link: http://gcc.gnu.org/ml/gcc-patches/2011-10/msg01874.html
Re: [Patch]: PR49868: Named address space support for AVR
Georg-Johann Lay schrieb: > This patch adds named address space support to read data from flash (aka. > progmem) to target AVR. > > The patch has two parts: > > The first part is a repost of Ulrich's work from >http://gcc.gnu.org/ml/gcc/2011-08/msg00131.html > with the needed changes to ./gcc and ./gcc/doc > > This patch is needed because the target hooks MODE_CODE_BASE_REG_CLASS and > REGNO_MODE_CODE_OK_FOR_BASE_P don't distinguish between different address > spaces. Ulrich's patch adds respective support to these hooks. > > The second part is the AVR dependent part that adds __pgm as address space > qualifier for address space AS1. > > The AVR part is just the worker code. If there is agreement that AS support > for AVR is okay in principle and Ulrich's work will go into GCC, I will supply > test programs and updates to the user manual, of course. > > The major drawbacks of the current AS implementation are: > > - It works only for C. > For C++, a language extension would be needed as indicated in > ISO/IEC DTR 18037 > Annex F - C++ Compatibility and Migration issues > F.2 Multiple Address Spaces Support > > - Register allocation does not a good job. AS1 can only be addressed > byte-wise by one single address register (Z) as per *Z or *Z++. This flaw from register allocator are filed as PR50775 now. > The AVR part does several things: > > - It locates data in AS1 into appropriate section, i.e. somewhere in > .progmem > > - It does early sanity checks to ensure that __pgm is always accompanied > with const so that writing to AS1 in not possible. > > - It prints LPM instructions to access flash memory. The attached patch is an update merge so that it fits without conflicts. The patch requires Ulrich's works which is still in review http://gcc.gnu.org/bugzilla/show_bug.cgi?id=50775 The regression tests run with this patch and the new ChangeLog enttry si written as if Ulrich's patch was applied. Tests pass without regression. Besides the update to a nor up-to-date SVN version, the patch sets a built-in define __PGM so that it is easy for users to test if or if not the feature is available. Documentation and test cases will follow in separate patch. Ok for trunk after Ulrich's work has been approved? Johann PR target/49868 * config/avr/avr.h (ADDR_SPACE_PGM): New define for address space AS1. (REGISTER_TARGET_PRAGMAS): New define. * config/avr/avr-protos.h (avr_mem_pgm_p): New prototype. (avr_register_target_pragmas): New prototype. (avr_log_t): Add field "progmem". Order alphabetically. * config/avr/avr-log.c (avr_log_set_avr_log): Set avr_log.progmem. * config/avr/avr-c.c (langhooks.h): New include. (avr_register_target_pragmas): New function. Register address space AS1 as "__pgm". (avr_cpu_cpp_builtins): Add built-in define __PGM. * config/avr/avr.c: Include "c-family/c-common.h". (TARGET_LEGITIMATE_ADDRESS_P): Remove define. (TARGET_LEGITIMIZE_ADDRESS): Remove define. (TARGET_ADDR_SPACE_SUBSET_P): Define to... (avr_addr_space_subset_p): ...this new static function. (TARGET_ADDR_SPACE_CONVERT): Define to... (avr_addr_space_convert): ...this new static function. (TARGET_ADDR_SPACE_ADDRESS_MODE): Define to... (avr_addr_space_address_mode): ...this new static function. (TARGET_ADDR_SPACE_POINTER_MODE): Define to... (avr_addr_space_pointer_mode): ...this new static function. (TARGET_ADDR_SPACE_LEGITIMATE_ADDRESS_P): Define to... (avr_addr_space_legitimate_address_p): ...this new static function. (TARGET_ADDR_SPACE_LEGITIMIZE_ADDRESS): Define to... (avr_addr_space_legitimize_address): ...this new static function. (avr_mode_code_base_reg_class): Handle AS1. (avr_regno_mode_code_ok_for_base_p): Handle AS1. (lpm_addr_reg_rtx, lpm_reg_rtx): New static GTYed variables. (avr_decl_pgm_p): New static function. (avr_mem_pgm_p): New function. (avr_asm_len): Return always "" instead of void. (avr_out_lpm_no_lpmx): New static function. (avr_out_lpm): New static function. (output_movqi, output_movhi, output_movsisf): Call avr_out_lpm to handle loads from progmem. (avr_progmem_p): Test if decl is in AS1. (avr_pgm_pointer_const_p): New static function. (avr_pgm_check_var_decl): New static function. (avr_insert_attributes): Use it. Change error message to report cause (progmem or AS1) when code wants to write to AS1. (avr_section_type_flags): Unset section flag SECTION_BSS for data in progmem. * config/avr/avr.md (LPM_REGNO): New define_constants. (movqi, movhi, movsi, movsf): Skip if code would write to AS1. (movmemhi): Ditto. Propagate address space information to newly created MEM. (split-l