Commit cba300dd by Georg-Johann Lay Committed by Georg-Johann Lay

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

libgcc/
	PR target/49868
	Extend __pgmx semantics to linearize memory.
	* config/avr/t-avr (LIB1ASMFUNCS): Add _xload_1, _movmemx.
	* config/avr/lib1funcs.S (__xload_1): New function.
	(__movmemx_qi, __movmemx_hi): New functions.
	(__xload_2, __xload_3, __xload_4): Rewrite to fit new __pgmx
	semantics.

gcc/
	PR target/49868
	Extend __pgmx semantics to linearize memory.
	* config/avr/avr.md (mov<mode>): Use avr_xload_libgcc_p to
	determine if code comes inline or from libgcc.
	(MOVMEM_r_d:HI): Add "w" to constraint for better preference.
	(movmem_qi, movmem_qi): Set constraint #2 to "n".
	(movmem_qi_elpm, movmem_hi_elpm): Remove insns.
	(movmemx_qi, movmemx_hi): New insns.
	(xload_<mode>_libgcc): Rewrite to new insn condition.
	(xload_<mode>): Remove insns.
	* config/avr/avr.c (avr_out_xload): Rewrite: Only need to handle
	cases that don't satisfy avr_xload_libgcc_p().
	(avr_addr_space_convert): Allow converting in any direction.
	(avr_addr_space_subset_p): Return always true.
	(avr_xload_libgcc_p): Rewrite to fit new __pgmx semantics.
	(avr_emit_movmemhi): Ditto.
	(avr_out_lpm): No need to handle ADDR_SPACE_PGMX any more.
	(avr_out_movmem): Ditto.
	(AVR_SYMBOL_FLAG_PROGMEM): New macro.
	(AVR_SYMBOL_SET_ADDR_SPACE): New macro.
	(AVR_SYMBOL_GET_ADDR_SPACE): New macro.
	(avr_encode_section_info): Encode 'progmem' in symbol flags.
	(output_reload_in_const): Don't zero-extend any 24-bit symbols.

From-SVN: r183058
parent 59c61547
2012-01-10 Georg-Johann Lay <avr@gjlay.de>
PR target/49868
Extend __pgmx semantics to linearize memory.
* config/avr/avr.md (mov<mode>): Use avr_xload_libgcc_p to
determine if code comes inline or from libgcc.
(MOVMEM_r_d:HI): Add "w" to constraint for better preference.
(movmem_qi, movmem_qi): Set constraint #2 to "n".
(movmem_qi_elpm, movmem_hi_elpm): Remove insns.
(movmemx_qi, movmemx_hi): New insns.
(xload_<mode>_libgcc): Rewrite to new insn condition.
(xload_<mode>): Remove insns.
* config/avr/avr.c (avr_out_xload): Rewrite: Only need to handle
cases that don't satisfy avr_xload_libgcc_p().
(avr_addr_space_convert): Allow converting in any direction.
(avr_addr_space_subset_p): Return always true.
(avr_xload_libgcc_p): Rewrite to fit new __pgmx semantics.
(avr_emit_movmemhi): Ditto.
(avr_out_lpm): No need to handle ADDR_SPACE_PGMX any more.
(avr_out_movmem): Ditto.
(AVR_SYMBOL_FLAG_PROGMEM): New macro.
(AVR_SYMBOL_SET_ADDR_SPACE): New macro.
(AVR_SYMBOL_GET_ADDR_SPACE): New macro.
(avr_encode_section_info): Encode 'progmem' in symbol flags.
(output_reload_in_const): Don't zero-extend any 24-bit symbols.
2012-01-10 Richard Guenther <rguenther@suse.de> 2012-01-10 Richard Guenther <rguenther@suse.de>
PR tree-optimization/50913 PR tree-optimization/50913
......
...@@ -390,6 +390,7 @@ ...@@ -390,6 +390,7 @@
(match_operand:QI 1 "memory_operand" "m")) (match_operand:QI 1 "memory_operand" "m"))
(clobber (reg:HI REG_Z))] (clobber (reg:HI REG_Z))]
"can_create_pseudo_p() "can_create_pseudo_p()
&& !avr_xload_libgcc_p (QImode)
&& avr_mem_pgmx_p (operands[1]) && avr_mem_pgmx_p (operands[1])
&& REG_P (XEXP (operands[1], 0))" && REG_P (XEXP (operands[1], 0))"
{ gcc_unreachable(); } { gcc_unreachable(); }
...@@ -414,8 +415,7 @@ ...@@ -414,8 +415,7 @@
(match_operand:MOVMODE 1 "memory_operand" "m")) (match_operand:MOVMODE 1 "memory_operand" "m"))
(clobber (reg:QI 21)) (clobber (reg:QI 21))
(clobber (reg:HI REG_Z))] (clobber (reg:HI REG_Z))]
"QImode != <MODE>mode "can_create_pseudo_p()
&& can_create_pseudo_p()
&& avr_mem_pgmx_p (operands[1]) && avr_mem_pgmx_p (operands[1])
&& REG_P (XEXP (operands[1], 0))" && REG_P (XEXP (operands[1], 0))"
{ gcc_unreachable(); } { gcc_unreachable(); }
...@@ -426,35 +426,19 @@ ...@@ -426,35 +426,19 @@
rtx reg_z = gen_rtx_REG (HImode, REG_Z); rtx reg_z = gen_rtx_REG (HImode, REG_Z);
rtx addr_hi8 = simplify_gen_subreg (QImode, addr, PSImode, 2); rtx addr_hi8 = simplify_gen_subreg (QImode, addr, PSImode, 2);
addr_space_t as = MEM_ADDR_SPACE (operands[1]); addr_space_t as = MEM_ADDR_SPACE (operands[1]);
rtx hi8, insn; rtx insn;
/* Split the address to R21:Z */
emit_move_insn (reg_z, simplify_gen_subreg (HImode, addr, PSImode, 0)); emit_move_insn (reg_z, simplify_gen_subreg (HImode, addr, PSImode, 0));
emit_move_insn (gen_rtx_REG (QImode, 21), addr_hi8);
if (avr_xload_libgcc_p (<MODE>mode)) /* Load with code from libgcc */
{ insn = emit_insn (gen_xload_<mode>_libgcc ());
emit_move_insn (gen_rtx_REG (QImode, 21), addr_hi8);
insn = emit_insn (gen_xload_<mode>_libgcc ());
emit_move_insn (operands[0], gen_rtx_REG (<MODE>mode, 22));
}
else if (avr_current_arch->n_segments == 1
&& GET_MODE_SIZE (<MODE>mode) > 2
&& !AVR_HAVE_LPMX)
{
rtx src = gen_rtx_MEM (<MODE>mode, reg_z);
as = ADDR_SPACE_PGM;
insn = emit_insn (gen_load_<mode>_libgcc (src));
emit_move_insn (operands[0], gen_rtx_REG (<MODE>mode, 22));
}
else
{
hi8 = gen_reg_rtx (QImode);
emit_move_insn (hi8, addr_hi8);
insn = emit_insn (gen_xload_<mode> (operands[0], hi8));
}
set_mem_addr_space (SET_SRC (single_set (insn)), as); set_mem_addr_space (SET_SRC (single_set (insn)), as);
/* Move to destination */
emit_move_insn (operands[0], gen_rtx_REG (<MODE>mode, 22));
DONE; DONE;
}) })
...@@ -462,16 +446,19 @@ ...@@ -462,16 +446,19 @@
;; These insns must be prior to respective generic move insn. ;; These insns must be prior to respective generic move insn.
(define_insn "xload_8" (define_insn "xload_8"
[(set (match_operand:QI 0 "register_operand" "=r") [(set (match_operand:QI 0 "register_operand" "=&r,r")
(mem:QI (lo_sum:PSI (match_operand:QI 1 "register_operand" "r") (mem:QI (lo_sum:PSI (match_operand:QI 1 "register_operand" "r,r")
(reg:HI REG_Z))))] (reg:HI REG_Z))))]
"" "!avr_xload_libgcc_p (QImode)"
{ {
return avr_out_xload (insn, operands, NULL); return avr_out_xload (insn, operands, NULL);
} }
[(set_attr "adjust_len" "xload") [(set_attr "length" "3,4")
(set_attr "cc" "clobber")]) (set_attr "adjust_len" "*,xload")
(set_attr "isa" "lpmx,lpm")
(set_attr "cc" "none")])
;; "xload_qi_libgcc"
;; "xload_hi_libgcc" ;; "xload_hi_libgcc"
;; "xload_psi_libgcc" ;; "xload_psi_libgcc"
;; "xload_si_libgcc" ;; "xload_si_libgcc"
...@@ -482,35 +469,14 @@ ...@@ -482,35 +469,14 @@
(reg:HI REG_Z)))) (reg:HI REG_Z))))
(clobber (reg:QI 21)) (clobber (reg:QI 21))
(clobber (reg:HI REG_Z))] (clobber (reg:HI REG_Z))]
"<MODE>mode != QImode "avr_xload_libgcc_p (<MODE>mode)"
&& avr_xload_libgcc_p (<MODE>mode)"
{ {
rtx x_bytes = GEN_INT (GET_MODE_SIZE (<MODE>mode)); rtx x_bytes = GEN_INT (GET_MODE_SIZE (<MODE>mode));
/* Devices with ELPM* also have CALL. */ output_asm_insn ("%~call __xload_%0", &x_bytes);
output_asm_insn ("call __xload_%0", &x_bytes);
return ""; return "";
} }
[(set_attr "length" "2") [(set_attr "type" "xcall")
(set_attr "cc" "clobber")])
;; "xload_hi"
;; "xload_psi"
;; "xload_si"
;; "xload_sf"
(define_insn "xload_<mode>"
[(set (match_operand:MOVMODE 0 "register_operand" "=r")
(mem:MOVMODE (lo_sum:PSI (match_operand:QI 1 "register_operand" "r")
(reg:HI REG_Z))))
(clobber (scratch:HI))
(clobber (reg:HI REG_Z))]
"<MODE>mode != QImode
&& !avr_xload_libgcc_p (<MODE>mode)"
{
return avr_out_xload (insn, operands, NULL);
}
[(set_attr "adjust_len" "xload")
(set_attr "cc" "clobber")]) (set_attr "cc" "clobber")])
...@@ -521,7 +487,6 @@ ...@@ -521,7 +487,6 @@
;; "movsi" ;; "movsi"
;; "movsf" ;; "movsf"
;; "movpsi" ;; "movpsi"
(define_expand "mov<mode>" (define_expand "mov<mode>"
[(set (match_operand:MOVMODE 0 "nonimmediate_operand" "") [(set (match_operand:MOVMODE 0 "nonimmediate_operand" "")
(match_operand:MOVMODE 1 "general_operand" ""))] (match_operand:MOVMODE 1 "general_operand" ""))]
...@@ -548,7 +513,7 @@ ...@@ -548,7 +513,7 @@
if (!REG_P (addr)) if (!REG_P (addr))
src = replace_equiv_address (src, copy_to_mode_reg (PSImode, addr)); src = replace_equiv_address (src, copy_to_mode_reg (PSImode, addr));
if (QImode == <MODE>mode) if (!avr_xload_libgcc_p (<MODE>mode))
emit_insn (gen_xload8_A (dest, src)); emit_insn (gen_xload8_A (dest, src));
else else
emit_insn (gen_xload<mode>_A (dest, src)); emit_insn (gen_xload<mode>_A (dest, src));
...@@ -869,10 +834,10 @@ ...@@ -869,10 +834,10 @@
}) })
(define_mode_attr MOVMEM_r_d [(QI "r") (define_mode_attr MOVMEM_r_d [(QI "r")
(HI "d")]) (HI "wd")])
;; $0, $4 : & dest ;; $0, $4 : & dest (REG_X)
;; $1, $5 : & src ;; $1, $5 : & src (REG_Z)
;; $2 : Address Space ;; $2 : Address Space
;; $3, $7 : Loop register ;; $3, $7 : Loop register
;; $6 : Scratch register ;; $6 : Scratch register
...@@ -882,7 +847,7 @@ ...@@ -882,7 +847,7 @@
(define_insn "movmem_<mode>" (define_insn "movmem_<mode>"
[(set (mem:BLK (match_operand:HI 0 "register_operand" "x")) [(set (mem:BLK (match_operand:HI 0 "register_operand" "x"))
(mem:BLK (match_operand:HI 1 "register_operand" "z"))) (mem:BLK (match_operand:HI 1 "register_operand" "z")))
(unspec [(match_operand:QI 2 "const_int_operand" "LP")] (unspec [(match_operand:QI 2 "const_int_operand" "n")]
UNSPEC_MOVMEM) UNSPEC_MOVMEM)
(use (match_operand:QIHI 3 "register_operand" "<MOVMEM_r_d>")) (use (match_operand:QIHI 3 "register_operand" "<MOVMEM_r_d>"))
(clobber (match_operand:HI 4 "register_operand" "=0")) (clobber (match_operand:HI 4 "register_operand" "=0"))
...@@ -897,29 +862,28 @@ ...@@ -897,29 +862,28 @@
(set_attr "cc" "clobber")]) (set_attr "cc" "clobber")])
;; Ditto and ;; Ditto and
;; $8, $9 : hh8 (& src) ;; $3, $7 : Loop register = R24
;; $8, $9 : hh8 (& src) = R23
;; $10 : RAMPZ_ADDR ;; $10 : RAMPZ_ADDR
;; "movmem_qi_elpm" ;; "movmemx_qi"
;; "movmem_hi_elpm" ;; "movmemx_hi"
(define_insn "movmem_<mode>_elpm" (define_insn "movmemx_<mode>"
[(set (mem:BLK (match_operand:HI 0 "register_operand" "x")) [(set (mem:BLK (match_operand:HI 0 "register_operand" "x"))
(mem:BLK (lo_sum:PSI (match_operand:QI 8 "register_operand" "r") (mem:BLK (lo_sum:PSI (match_operand:QI 8 "register_operand" "r")
(match_operand:HI 1 "register_operand" "z")))) (match_operand:HI 1 "register_operand" "z"))))
(unspec [(match_operand:QI 2 "const_int_operand" "n")] (unspec [(match_operand:QI 2 "const_int_operand" "n")]
UNSPEC_MOVMEM) UNSPEC_MOVMEM)
(use (match_operand:QIHI 3 "register_operand" "<MOVMEM_r_d>")) (use (match_operand:QIHI 3 "register_operand" "w"))
(clobber (match_operand:HI 4 "register_operand" "=0")) (clobber (match_operand:HI 4 "register_operand" "=0"))
(clobber (match_operand:HI 5 "register_operand" "=1")) (clobber (match_operand:HI 5 "register_operand" "=1"))
(clobber (match_operand:QI 6 "register_operand" "=&r")) (clobber (match_operand:QI 6 "register_operand" "=&r"))
(clobber (match_operand:QIHI 7 "register_operand" "=3")) (clobber (match_operand:HI 7 "register_operand" "=3"))
(clobber (match_operand:QI 9 "register_operand" "=8")) (clobber (match_operand:QI 9 "register_operand" "=8"))
(clobber (mem:QI (match_operand:QI 10 "io_address_operand" "n")))] (clobber (mem:QI (match_operand:QI 10 "io_address_operand" "n")))]
"" ""
{ "%~call __movmemx_<mode>"
return avr_out_movmem (insn, operands, NULL); [(set_attr "type" "xcall")
}
[(set_attr "adjust_len" "movmem")
(set_attr "cc" "clobber")]) (set_attr "cc" "clobber")])
......
2012-01-10 Georg-Johann Lay <avr@gjlay.de>
PR target/49868
Extend __pgmx semantics to linearize memory.
* config/avr/t-avr (LIB1ASMFUNCS): Add _xload_1, _movmemx.
* config/avr/lib1funcs.S (__xload_1): New function.
(__movmemx_qi, __movmemx_hi): New functions.
(__xload_2, __xload_3, __xload_4): Rewrite to fit new __pgmx
semantics.
2012-01-09 Eric Botcazou <ebotcazou@adacore.com> 2012-01-09 Eric Botcazou <ebotcazou@adacore.com>
* config/sparc/sol2-unwind.h (sparc64_is_sighandler): Check that the * config/sparc/sol2-unwind.h (sparc64_is_sighandler): Check that the
......
...@@ -2061,19 +2061,14 @@ ENDF __load_4 ...@@ -2061,19 +2061,14 @@ ENDF __load_4
#endif /* L_load_3 || L_load_3 */ #endif /* L_load_3 || L_load_3 */
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Loading n bytes from Flash; n = 2,3,4 ;; Loading n bytes from Flash or RAM; n = 1,2,3,4
;; R22... = Flash[R21:Z] ;; R22... = Flash[R21:Z] or RAM[Z] depending on R21.7
;; Clobbers: __tmp_reg__, R21, R30, R31 ;; Clobbers: __tmp_reg__, R21, R30, R31
#if (defined (L_xload_2) \ #if (defined (L_xload_1) \
|| defined (L_xload_2) \
|| defined (L_xload_3) \ || defined (L_xload_3) \
|| defined (L_xload_4)) \ || defined (L_xload_4))
&& defined (__AVR_HAVE_ELPM__) \
&& !defined (__AVR_HAVE_ELPMX__)
#if !defined (__AVR_HAVE_RAMPZ__)
#error Need RAMPZ
#endif /* have RAMPZ */
;; Destination ;; Destination
#define D0 22 #define D0 22
...@@ -2086,6 +2081,9 @@ ENDF __load_4 ...@@ -2086,6 +2081,9 @@ ENDF __load_4
#define HHI8 21 #define HHI8 21
.macro .xload dest, n .macro .xload dest, n
#if defined (__AVR_HAVE_ELPMX__)
elpm \dest, Z+
#elif defined (__AVR_HAVE_ELPM__)
elpm elpm
mov \dest, r0 mov \dest, r0
.if \dest != D0+\n-1 .if \dest != D0+\n-1
...@@ -2093,39 +2091,161 @@ ENDF __load_4 ...@@ -2093,39 +2091,161 @@ ENDF __load_4
adc HHI8, __zero_reg__ adc HHI8, __zero_reg__
out __RAMPZ__, HHI8 out __RAMPZ__, HHI8
.endif .endif
.endm #elif defined (__AVR_HAVE_LPMX__)
lpm \dest, Z+
#else
lpm
mov \dest, r0
.if \dest != D0+\n-1
adiw r30, 1
.endif
#endif
.endm ; .xload
#if defined (L_xload_1)
DEFUN __xload_1
#if defined (__AVR_HAVE_LPMX__) && !defined (__AVR_HAVE_RAMPZ__)
ld D0, Z
sbrs HHI8, 7
lpm D0, Z
ret
#else
sbrc HHI8, 7
rjmp 1f
#if defined (__AVR_HAVE_RAMPZ__)
out __RAMPZ__, HHI8
#endif /* __AVR_HAVE_RAMPZ__ */
.xload D0, 1
ret
1: ld D0, Z
ret
#endif /* LPMx && ! RAMPZ */
ENDF __xload_1
#endif /* L_xload_1 */
#if defined (L_xload_2) #if defined (L_xload_2)
DEFUN __xload_2 DEFUN __xload_2
sbrc HHI8, 7
rjmp 1f
#if defined (__AVR_HAVE_RAMPZ__)
out __RAMPZ__, HHI8 out __RAMPZ__, HHI8
.xload D0, 2 #endif /* __AVR_HAVE_RAMPZ__ */
.xload D1, 2 .xload D0, 2
.xload D1, 2
ret
1: ld D0, Z+
ld D1, Z+
ret ret
ENDF __xload_2 ENDF __xload_2
#endif /* L_xload_2 */ #endif /* L_xload_2 */
#if defined (L_xload_3) #if defined (L_xload_3)
DEFUN __xload_3 DEFUN __xload_3
sbrc HHI8, 7
rjmp 1f
#if defined (__AVR_HAVE_RAMPZ__)
out __RAMPZ__, HHI8 out __RAMPZ__, HHI8
.xload D0, 3 #endif /* __AVR_HAVE_RAMPZ__ */
.xload D1, 3 .xload D0, 3
.xload D2, 3 .xload D1, 3
.xload D2, 3
ret
1: ld D0, Z+
ld D1, Z+
ld D2, Z+
ret ret
ENDF __xload_3 ENDF __xload_3
#endif /* L_xload_3 */ #endif /* L_xload_3 */
#if defined (L_xload_4) #if defined (L_xload_4)
DEFUN __xload_4 DEFUN __xload_4
sbrc HHI8, 7
rjmp 1f
#if defined (__AVR_HAVE_RAMPZ__)
out __RAMPZ__, HHI8 out __RAMPZ__, HHI8
.xload D0, 4 #endif /* __AVR_HAVE_RAMPZ__ */
.xload D1, 4 .xload D0, 4
.xload D2, 4 .xload D1, 4
.xload D3, 4 .xload D2, 4
.xload D3, 4
ret
1: ld D0, Z+
ld D1, Z+
ld D2, Z+
ld D3, Z+
ret ret
ENDF __xload_4 ENDF __xload_4
#endif /* L_xload_4 */ #endif /* L_xload_4 */
#endif /* L_xload_{2|3|4} && ELPM */ #endif /* L_xload_{1|2|3|4} */
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; memcopy from Address Space __pgmx to RAM
;; R23:Z = Source Address
;; X = Destination Address
;; Clobbers: __tmp_reg__, R23, R24, R25, X, Z
#if defined (L_movmemx)
#define HHI8 23
#define LOOP 24
DEFUN __movmemx_qi
;; #Bytes to copy fity in 8 Bits (1..255)
;; Zero-extend Loop Counter
clr LOOP+1
;; FALLTHRU
ENDF __movmemx_qi
DEFUN __movmemx_hi
;; Read from where?
sbrc HHI8, 7
rjmp 1f
;; Read from Flash
#if defined (__AVR_HAVE_RAMPZ__)
out __RAMPZ__, HHI8
#endif
0: ;; Load 1 Byte from Flash...
#if defined (__AVR_HAVE_ELPMX__)
elpm r0, Z+
#elif defined (__AVR_HAVE_ELPM__)
elpm
adiw r30, 1
adc HHI8, __zero_reg__
out __RAMPZ__, HHI8
#elif defined (__AVR_HAVE_LPMX__)
lpm r0, Z+
#else
lpm
adiw r30, 1
#endif
;; ...and store that Byte to RAM Destination
st X+, r0
sbiw LOOP, 1
brne 0b
ret
;; Read from RAM
1: ;; Read 1 Byte from RAM...
ld r0, Z+
;; and store that Byte to RAM Destination
st X+, r0
sbiw LOOP, 1
brne 0b
ret
ENDF __movmemx_hi
#undef HHI8
#undef LOOP
#endif /* L_movmemx */
.section .text.libgcc.builtins, "ax", @progbits .section .text.libgcc.builtins, "ax", @progbits
......
...@@ -27,7 +27,8 @@ LIB1ASMFUNCS = \ ...@@ -27,7 +27,8 @@ LIB1ASMFUNCS = \
_tablejump \ _tablejump \
_tablejump_elpm \ _tablejump_elpm \
_load_3 _load_4 \ _load_3 _load_4 \
_xload_2 _xload_3 _xload_4 \ _xload_1 _xload_2 _xload_3 _xload_4 \
_movmemx \
_copy_data \ _copy_data \
_clear_bss \ _clear_bss \
_ctors \ _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