HOST_WIDE_INT count;
enum machine_mode loop_mode;
addr_space_t as = MEM_ADDR_SPACE (xop[1]);
- rtx loop_reg, addr0, addr1, a_src, a_dest, insn, xas, reg_x;
+ rtx loop_reg, addr1, a_src, a_dest, insn, xas;
rtx a_hi8 = NULL_RTX;
if (avr_mem_flash_p (xop[0]))
X = destination address */
emit_move_insn (lpm_addr_reg_rtx, addr1);
- addr1 = lpm_addr_reg_rtx;
-
- reg_x = gen_rtx_REG (HImode, REG_X);
- emit_move_insn (reg_x, a_dest);
- addr0 = reg_x;
+ emit_move_insn (gen_rtx_REG (HImode, REG_X), a_dest);
/* FIXME: Register allocator does a bad job and might spill address
register(s) inside the loop leading to additional move instruction
/* Load instruction ([E]LPM or LD) is known at compile time:
Do the copy-loop inline. */
- rtx (*fun) (rtx, rtx, rtx, rtx, rtx, rtx, rtx, rtx)
+ rtx (*fun) (rtx, rtx, rtx)
= QImode == loop_mode ? gen_movmem_qi : gen_movmem_hi;
- insn = fun (addr0, addr1, xas, loop_reg,
- addr0, addr1, tmp_reg_rtx, loop_reg);
+ insn = fun (xas, loop_reg, loop_reg);
}
else
{
- rtx loop_reg16 = gen_rtx_REG (HImode, 24);
- rtx r23 = gen_rtx_REG (QImode, 23);
- rtx (*fun) (rtx, rtx, rtx, rtx, rtx, rtx, rtx, rtx, rtx, rtx, rtx)
+ rtx (*fun) (rtx, rtx)
= QImode == loop_mode ? gen_movmemx_qi : gen_movmemx_hi;
- emit_move_insn (r23, a_hi8);
+ emit_move_insn (gen_rtx_REG (QImode, 23), a_hi8);
- insn = fun (addr0, addr1, xas, loop_reg, addr0, addr1,
- lpm_reg_rtx, loop_reg16, r23, r23, GEN_INT (avr_addr.rampz));
+ insn = fun (xas, GEN_INT (avr_addr.rampz));
}
set_mem_addr_space (SET_SRC (XVECEXP (insn, 0, 0)), as);
/* Print assembler for movmem_qi, movmem_hi insns...
- $0, $4 : & dest
- $1, $5 : & src
- $2 : Address Space
- $3, $7 : Loop register
- $6 : Scratch register
-
- ...and movmem_qi_elpm, movmem_hi_elpm insns.
-
- $8, $9 : hh8 (& src)
- $10 : RAMPZ_ADDR
+ $0 : Address Space
+ $1, $2 : Loop register
+ Z : Source address
+ X : Destination address
*/
const char*
-avr_out_movmem (rtx insn ATTRIBUTE_UNUSED, rtx *xop, int *plen)
+avr_out_movmem (rtx insn ATTRIBUTE_UNUSED, rtx *op, int *plen)
{
- addr_space_t as = (addr_space_t) INTVAL (xop[2]);
- enum machine_mode loop_mode = GET_MODE (xop[3]);
-
- bool sbiw_p = test_hard_reg_class (ADDW_REGS, xop[3]);
-
- gcc_assert (REG_X == REGNO (xop[0])
- && REG_Z == REGNO (xop[1]));
+ addr_space_t as = (addr_space_t) INTVAL (op[0]);
+ enum machine_mode loop_mode = GET_MODE (op[1]);
+ bool sbiw_p = test_hard_reg_class (ADDW_REGS, op[1]);
+ rtx xop[3];
if (plen)
*plen = 0;
+ xop[0] = op[0];
+ xop[1] = op[1];
+ xop[2] = tmp_reg_rtx;
+
/* Loop label */
avr_asm_len ("0:", xop, plen, 0);
case ADDR_SPACE_GENERIC:
- avr_asm_len ("ld %6,%a1+", xop, plen, 1);
+ avr_asm_len ("ld %2,Z+", xop, plen, 1);
break;
case ADDR_SPACE_FLASH:
if (AVR_HAVE_LPMX)
- avr_asm_len ("lpm %6,%a1+", xop, plen, 1);
+ avr_asm_len ("lpm %2,%Z+", xop, plen, 1);
else
avr_asm_len ("lpm" CR_TAB
- "adiw %1,1", xop, plen, 2);
+ "adiw r30,1", xop, plen, 2);
break;
case ADDR_SPACE_FLASH1:
case ADDR_SPACE_FLASH5:
if (AVR_HAVE_ELPMX)
- avr_asm_len ("elpm %6,%a1+", xop, plen, 1);
+ avr_asm_len ("elpm %2,Z+", xop, plen, 1);
else
avr_asm_len ("elpm" CR_TAB
- "adiw %1,1", xop, plen, 2);
+ "adiw r30,1", xop, plen, 2);
break;
}
/* Store with post-increment */
- avr_asm_len ("st %a0+,%6", xop, plen, 1);
+ avr_asm_len ("st X+,%2", xop, plen, 1);
/* Decrement loop-counter and set Z-flag */
if (QImode == loop_mode)
{
- avr_asm_len ("dec %3", xop, plen, 1);
+ avr_asm_len ("dec %1", xop, plen, 1);
}
else if (sbiw_p)
{
- avr_asm_len ("sbiw %3,1", xop, plen, 1);
+ avr_asm_len ("sbiw %1,1", xop, plen, 1);
}
else
{
- avr_asm_len ("subi %A3,1" CR_TAB
- "sbci %B3,0", xop, plen, 2);
+ avr_asm_len ("subi %A1,1" CR_TAB
+ "sbci %B1,0", xop, plen, 2);
}
/* Loop until zero */
(set_attr "isa" "lpmx,lpm")
(set_attr "cc" "none")])
+;; R21:Z : 24-bit source address
+;; R22 : 1-4 byte output
+
;; "xload_qi_libgcc"
;; "xload_hi_libgcc"
;; "xload_psi_libgcc"
(define_mode_attr MOVMEM_r_d [(QI "r")
(HI "wd")])
-;; $0, $4 : & dest (REG_X)
-;; $1, $5 : & src (REG_Z)
-;; $2 : Address Space
-;; $3, $7 : Loop register
-;; $6 : Scratch register
+;; $0 : Address Space
+;; $1, $2 : Loop register
+;; R30 : source address
+;; R26 : destination address
;; "movmem_qi"
;; "movmem_hi"
(define_insn "movmem_<mode>"
- [(set (mem:BLK (match_operand:HI 0 "register_operand" "x"))
- (mem:BLK (match_operand:HI 1 "register_operand" "z")))
- (unspec [(match_operand:QI 2 "const_int_operand" "n")]
+ [(set (mem:BLK (reg:HI REG_X))
+ (mem:BLK (reg:HI REG_Z)))
+ (unspec [(match_operand:QI 0 "const_int_operand" "n")]
UNSPEC_MOVMEM)
- (use (match_operand:QIHI 3 "register_operand" "<MOVMEM_r_d>"))
- (clobber (match_operand:HI 4 "register_operand" "=0"))
- (clobber (match_operand:HI 5 "register_operand" "=1"))
- (clobber (match_operand:QI 6 "register_operand" "=&r"))
- (clobber (match_operand:QIHI 7 "register_operand" "=3"))]
+ (use (match_operand:QIHI 1 "register_operand" "<MOVMEM_r_d>"))
+ (clobber (reg:HI REG_X))
+ (clobber (reg:HI REG_Z))
+ (clobber (reg:QI LPM_REGNO))
+ (clobber (match_operand:QIHI 2 "register_operand" "=1"))]
""
{
return avr_out_movmem (insn, operands, NULL);
[(set_attr "adjust_len" "movmem")
(set_attr "cc" "clobber")])
-;; Ditto and
-;; $3, $7 : Loop register = R24
-;; $8, $9 : hh8 (& src) = R23
-;; $10 : RAMPZ_ADDR
+
+;; $0 : Address Space
+;; $1 : RAMPZ RAM address
+;; R24 : #bytes and loop register
+;; R23:Z : 24-bit source address
+;; R26 : 16-bit destination address
;; "movmemx_qi"
;; "movmemx_hi"
(define_insn "movmemx_<mode>"
- [(set (mem:BLK (match_operand:HI 0 "register_operand" "x"))
- (mem:BLK (lo_sum:PSI (match_operand:QI 8 "register_operand" "r")
- (match_operand:HI 1 "register_operand" "z"))))
- (unspec [(match_operand:QI 2 "const_int_operand" "n")]
+ [(set (mem:BLK (reg:HI REG_X))
+ (mem:BLK (lo_sum:PSI (reg:QI 23)
+ (reg:HI REG_Z))))
+ (unspec [(match_operand:QI 0 "const_int_operand" "n")]
UNSPEC_MOVMEM)
- (use (match_operand:QIHI 3 "register_operand" "w"))
- (clobber (match_operand:HI 4 "register_operand" "=0"))
- (clobber (match_operand:HI 5 "register_operand" "=1"))
- (clobber (match_operand:QI 6 "register_operand" "=&r"))
- (clobber (match_operand:HI 7 "register_operand" "=3"))
- (clobber (match_operand:QI 9 "register_operand" "=8"))
- (clobber (mem:QI (match_operand:QI 10 "io_address_operand" "n")))]
+ (use (reg:QIHI 24))
+ (clobber (reg:HI REG_X))
+ (clobber (reg:HI REG_Z))
+ (clobber (reg:QI LPM_REGNO))
+ (clobber (reg:HI 24))
+ (clobber (reg:QI 23))
+ (clobber (mem:QI (match_operand:QI 1 "io_address_operand" "n")))]
""
"%~call __movmemx_<mode>"
[(set_attr "type" "xcall")