aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorgjl <>2012-02-28 08:51:39 +0000
committergjl <>2012-02-28 08:51:39 +0000
commit5a072155706b8edeb436da53194666e62369e459 (patch)
tree91edfccb4fb996809f085e75185343238a3d6185 /gcc
parentebf4c8b42a0a3550a2d3fbf5c8d4927685c5d4f0 (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/ChangeLog10
-rw-r--r--gcc/config/avr/avr.c73
-rw-r--r--gcc/config/avr/avr.md60
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")