Commit 7bc6df2c by Georg-Johann Lay Committed by Georg-Johann Lay

re PR target/49868 (Implement named address space to place/access data in flash memory)

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/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): 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.

From-SVN: r181482
parent 59659b59
2011-11-18 Georg-Johann Lay <avr@gjlay.de>
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/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): 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.
2011-11-18 Martin Jambor <mjambor@suse.cz>
PR tree-optimization/50605
......@@ -37,6 +37,12 @@ void
avr_register_target_pragmas (void)
{
c_register_addr_space ("__pgm", ADDR_SPACE_PGM);
c_register_addr_space ("__pgm1", ADDR_SPACE_PGM1);
c_register_addr_space ("__pgm2", ADDR_SPACE_PGM2);
c_register_addr_space ("__pgm3", ADDR_SPACE_PGM3);
c_register_addr_space ("__pgm4", ADDR_SPACE_PGM4);
c_register_addr_space ("__pgm5", ADDR_SPACE_PGM5);
c_register_addr_space ("__pgmx", ADDR_SPACE_PGMX);
}
......@@ -109,6 +115,12 @@ avr_cpu_cpp_builtins (struct cpp_reader *pfile)
if (!strcmp (lang_hooks.name, "GNU C"))
{
cpp_define (pfile, "__PGM=__pgm");
cpp_define (pfile, "__PGM1=__pgm1");
cpp_define (pfile, "__PGM2=__pgm2");
cpp_define (pfile, "__PGM3=__pgm3");
cpp_define (pfile, "__PGM4=__pgm4");
cpp_define (pfile, "__PGM5=__pgm5");
cpp_define (pfile, "__PGMX=__pgmx");
}
/* Define builtin macros so that the user can
......
......@@ -25,18 +25,27 @@
/* List of all known AVR MCU architectures. */
const struct base_arch_s avr_arch_types[] = {
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x0060, NULL, "avr2" }, /* unknown device specified */
{ 1, 0, 0, 0, 0, 0, 0, 0, 0, 0x0060, "__AVR_ARCH__=1", "avr1" },
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x0060, "__AVR_ARCH__=2", "avr2" },
{ 0, 0, 0, 1, 0, 0, 0, 0, 0, 0x0060, "__AVR_ARCH__=25", "avr25" },
{ 0, 0, 1, 0, 0, 0, 0, 0, 0, 0x0060, "__AVR_ARCH__=3", "avr3" },
{ 0, 0, 1, 0, 1, 0, 0, 0, 0, 0x0060, "__AVR_ARCH__=31", "avr31" },
{ 0, 0, 1, 1, 0, 0, 0, 0, 0, 0x0060, "__AVR_ARCH__=35", "avr35" },
{ 0, 1, 0, 1, 0, 0, 0, 0, 0, 0x0060, "__AVR_ARCH__=4", "avr4" },
{ 0, 1, 1, 1, 0, 0, 0, 0, 0, 0x0060, "__AVR_ARCH__=5", "avr5" },
{ 0, 1, 1, 1, 1, 1, 0, 0, 0, 0x0060, "__AVR_ARCH__=51", "avr51" },
{ 0, 1, 1, 1, 1, 1, 1, 0, 0, 0x0060, "__AVR_ARCH__=6", "avr6" }
const struct base_arch_s
avr_arch_types[] =
{
/* unknown device specified */
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x0060, 1, NULL, "avr2" },
/*
A M J L E E E d S # F
S U M P L L I a t 6 l
M L P M P P J - - t a 4 a
X M M M a r s
X P t k h */
{ 1, 0, 0, 0, 0, 0, 0, 0, 0, 0x0060, 1, "__AVR_ARCH__=1", "avr1" },
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x0060, 1, "__AVR_ARCH__=2", "avr2" },
{ 0, 0, 0, 1, 0, 0, 0, 0, 0, 0x0060, 1, "__AVR_ARCH__=25", "avr25" },
{ 0, 0, 1, 0, 0, 0, 0, 0, 0, 0x0060, 1, "__AVR_ARCH__=3", "avr3" },
{ 0, 0, 1, 0, 1, 0, 0, 0, 0, 0x0060, 2, "__AVR_ARCH__=31", "avr31" },
{ 0, 0, 1, 1, 0, 0, 0, 0, 0, 0x0060, 1, "__AVR_ARCH__=35", "avr35" },
{ 0, 1, 0, 1, 0, 0, 0, 0, 0, 0x0060, 1, "__AVR_ARCH__=4", "avr4" },
{ 0, 1, 1, 1, 0, 0, 0, 0, 0, 0x0060, 1, "__AVR_ARCH__=5", "avr5" },
{ 0, 1, 1, 1, 1, 1, 0, 0, 0, 0x0060, 2, "__AVR_ARCH__=51", "avr51" },
{ 0, 1, 1, 1, 1, 1, 1, 0, 0, 0x0060, 4, "__AVR_ARCH__=6", "avr6" }
};
const struct mcu_type_s avr_mcu_types[] = {
......
......@@ -34,6 +34,7 @@ extern int avr_hard_regno_rename_ok (unsigned int, unsigned int);
extern rtx avr_return_addr_rtx (int count, rtx tem);
extern void avr_register_target_pragmas (void);
extern bool avr_accumulate_outgoing_args (void);
extern void avr_init_expanders (void);
#ifdef TREE_CODE
extern void avr_asm_output_aligned_decl_common (FILE*, const_tree, const char*, unsigned HOST_WIDE_INT, unsigned int, bool);
......@@ -84,6 +85,7 @@ extern bool avr_rotate_bytes (rtx operands[]);
extern void expand_prologue (void);
extern void expand_epilogue (bool);
extern bool avr_emit_movmemhi (rtx*);
extern int avr_epilogue_uses (int regno);
extern int avr_starting_frame_offset (void);
......@@ -94,6 +96,8 @@ extern const char* avr_out_bitop (rtx, rtx*, int*);
extern const char* avr_out_plus (rtx*, int*, int*);
extern const char* avr_out_plus_noclobber (rtx*, int*, int*);
extern const char* avr_out_addto_sp (rtx*, int*);
extern const char* avr_out_xload (rtx, rtx*, int*);
extern const char* avr_out_movmem (rtx, rtx*, int*);
extern bool avr_popcount_each_byte (rtx, int, int);
extern int extra_constraint_Q (rtx x);
......@@ -122,7 +126,9 @@ extern bool avr_regno_mode_code_ok_for_base_p (int, enum machine_mode, addr_spac
extern rtx avr_incoming_return_addr_rtx (void);
extern rtx avr_legitimize_reload_address (rtx*, enum machine_mode, int, int, int, int, rtx (*)(rtx,int));
extern bool avr_mem_pgm_p (rtx);
extern bool avr_mem_pgmx_p (rtx);
extern bool avr_load_libgcc_p (rtx);
extern bool avr_xload_libgcc_p (enum machine_mode);
#endif /* RTX_CODE */
#ifdef REAL_VALUE_TYPE
......
......@@ -54,6 +54,9 @@ struct base_arch_s {
/* Default start of data section address for architecture. */
int default_data_section_start;
/* Number of 64k segments in the flash. */
int n_segments;
const char *const macro;
/* Architecture name. */
......@@ -131,6 +134,8 @@ extern const struct base_arch_s avr_arch_types[];
#define AVR_HAVE_MUL (avr_current_arch->have_mul)
#define AVR_HAVE_MOVW (avr_current_arch->have_movw_lpmx)
#define AVR_HAVE_LPMX (avr_current_arch->have_movw_lpmx)
#define AVR_HAVE_ELPM (avr_current_arch->have_elpm)
#define AVR_HAVE_ELPMX (avr_current_arch->have_elpmx)
#define AVR_HAVE_RAMPZ (avr_current_arch->have_elpm)
#define AVR_HAVE_EIJMP_EICALL (avr_current_arch->have_eijmp_eicall)
#define AVR_HAVE_8BIT_SP (avr_current_device->short_sp || TARGET_TINY_STACK)
......@@ -393,6 +398,12 @@ typedef struct avr_args {
#define ADDR_SPACE_PGM 1
#define ADDR_SPACE_PGM1 2
#define ADDR_SPACE_PGM2 3
#define ADDR_SPACE_PGM3 4
#define ADDR_SPACE_PGM4 5
#define ADDR_SPACE_PGM5 6
#define ADDR_SPACE_PGMX 7
#define REGISTER_TARGET_PRAGMAS() \
do { \
......@@ -645,3 +656,5 @@ struct GTY(()) machine_function
#define PUSH_ROUNDING(X) (X)
#define ACCUMULATE_OUTGOING_ARGS avr_accumulate_outgoing_args()
#define INIT_EXPANDERS avr_init_expanders()
......@@ -63,10 +63,11 @@
(match_test "!avr_mem_pgm_p (op)")))
;; Return 1 if OP is an "ordinary" general operand, i.e. a general
;; operand whose load is not handled by a libgcc call.
;; operand whose load is not handled by a libgcc call or ELPM.
(define_predicate "nox_general_operand"
(and (match_operand 0 "general_operand")
(match_test "!avr_load_libgcc_p (op)")))
(not (match_test "avr_load_libgcc_p (op)"))
(not (match_test "avr_mem_pgmx_p (op)"))))
;; Return 1 if OP is the zero constant for MODE.
(define_predicate "const0_operand"
......
2011-11-18 Georg-Johann Lay <avr@gjlay.de>
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.
2011-11-16 Matthew Gretton-Dann <matthew.gretton-dann@arm.com>
* config/arm/lib1funcs.asm (udivsi3): Add support for divide
......
......@@ -1227,6 +1227,73 @@ ENDF __load_4
#endif /* L_load_3 || L_load_3 */
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Loading n bytes from Flash; n = 2,3,4
;; R22... = Flash[R21:Z]
;; Clobbers: __tmp_reg__, R21, R30, R31
#if (defined (L_xload_2) \
|| defined (L_xload_3) \
|| defined (L_xload_4)) \
&& defined (__AVR_HAVE_ELPM__) \
&& !defined (__AVR_HAVE_ELPMX__)
#if !defined (__AVR_HAVE_RAMPZ__)
#error Need RAMPZ
#endif /* have RAMPZ */
;; Destination
#define D0 22
#define D1 D0+1
#define D2 D0+2
#define D3 D0+3
;; Register containing bits 16+ of the address
#define HHI8 21
.macro .xload dest, n
elpm
mov \dest, r0
.if \dest != D0+\n-1
adiw r30, 1
adc HHI8, __zero_reg__
out __RAMPZ__, HHI8
.endif
.endm
#if defined (L_xload_2)
DEFUN __xload_2
out __RAMPZ__, HHI8
.xload D0, 2
.xload D1, 2
ret
ENDF __xload_2
#endif /* L_xload_2 */
#if defined (L_xload_3)
DEFUN __xload_3
out __RAMPZ__, HHI8
.xload D0, 3
.xload D1, 3
.xload D2, 3
ret
ENDF __xload_3
#endif /* L_xload_3 */
#if defined (L_xload_4)
DEFUN __xload_4
out __RAMPZ__, HHI8
.xload D0, 4
.xload D1, 4
.xload D2, 4
.xload D3, 4
ret
ENDF __xload_4
#endif /* L_xload_4 */
#endif /* L_xload_{2|3|4} && ELPM */
.section .text.libgcc.builtins, "ax", @progbits
......
......@@ -22,6 +22,7 @@ LIB1ASMFUNCS = \
_tablejump \
_tablejump_elpm \
_load_3 _load_4 \
_xload_2 _xload_3 _xload_4 \
_copy_data \
_clear_bss \
_ctors \
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment