diff options
author | gjl <> | 2012-02-28 08:51:39 +0000 |
---|---|---|
committer | gjl <> | 2012-02-28 08:51:39 +0000 |
commit | 5a072155706b8edeb436da53194666e62369e459 (patch) | |
tree | 91edfccb4fb996809f085e75185343238a3d6185 /gcc | |
parent | ebf4c8b42a0a3550a2d3fbf5c8d4927685c5d4f0 (diff) |
PR target/52148
* config/avr/avr.md (movmem_<mode>): Replace match_operand that
match only one single hard register with respective hard reg rtx.
(movmemx_<mode>): Ditto.
* config/avr/avr.c (avr_emit_movmemhi): Adapt expanding to new
insn anatomy of movmem[x]_<mode>.
(avr_out_movmem): Same for printing assembler and operand usage.
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ChangeLog | 10 | ||||
-rw-r--r-- | gcc/config/avr/avr.c | 73 | ||||
-rw-r--r-- | gcc/config/avr/avr.md | 60 |
3 files changed, 72 insertions, 71 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 3adb7c95791..232754873bf 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,5 +1,15 @@ 2012-02-28 Georg-Johann Lay <avr@gjlay.de> + PR target/52148 + * config/avr/avr.md (movmem_<mode>): Replace match_operand that + match only one single hard register with respective hard reg rtx. + (movmemx_<mode>): Ditto. + * config/avr/avr.c (avr_emit_movmemhi): Adapt expanding to new + insn anatomy of movmem[x]_<mode>. + (avr_out_movmem): Same for printing assembler and operand usage. + +2012-02-28 Georg-Johann Lay <avr@gjlay.de> + PR target/49868 PR target/52261 * doc/extend.texi (AVR Named Address Spaces): No more try to fix diff --git a/gcc/config/avr/avr.c b/gcc/config/avr/avr.c index 3fe26d4161f..4779aabfc79 100644 --- a/gcc/config/avr/avr.c +++ b/gcc/config/avr/avr.c @@ -9935,7 +9935,7 @@ avr_emit_movmemhi (rtx *xop) 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])) @@ -9991,11 +9991,7 @@ avr_emit_movmemhi (rtx *xop) 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 @@ -10010,23 +10006,19 @@ avr_emit_movmemhi (rtx *xop) /* 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); @@ -10037,32 +10029,27 @@ avr_emit_movmemhi (rtx *xop) /* 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); @@ -10076,16 +10063,16 @@ avr_out_movmem (rtx insn ATTRIBUTE_UNUSED, rtx *xop, int *plen) 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: @@ -10095,31 +10082,31 @@ avr_out_movmem (rtx insn ATTRIBUTE_UNUSED, rtx *xop, int *plen) 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 */ diff --git a/gcc/config/avr/avr.md b/gcc/config/avr/avr.md index c42f67ac7d3..c669831b8f8 100644 --- a/gcc/config/avr/avr.md +++ b/gcc/config/avr/avr.md @@ -465,6 +465,9 @@ (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" @@ -848,24 +851,23 @@ (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); @@ -873,26 +875,28 @@ [(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") |