From: Marek Michalkiewicz Date: Wed, 20 Dec 2000 18:49:22 +0000 (+0100) Subject: avr.c (out_movsi_r_mr, [...]): Do not output undefined opcodes where source or destin... X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=dfaf5abf0f831d2ed94eedf13ba2dd7d647b0ad7;p=platform%2Fupstream%2Fgcc.git avr.c (out_movsi_r_mr, [...]): Do not output undefined opcodes where source or destination register overlaps... * config/avr/avr.c (out_movsi_r_mr, out_movsi_mr_r, out_movhi_mr_r): Do not output undefined opcodes where source or destination register overlaps with modified pointer register. Handle (X + d) addresses. * config/avr/avr.md (*movhi, *movsi, *movsf): Correct insn length in alternatives with memory operand. From-SVN: r38405 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 6eca585..72dd495 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,11 @@ +2000-12-20 Marek Michalkiewicz + + * config/avr/avr.c (out_movsi_r_mr, out_movsi_mr_r, out_movhi_mr_r): + Do not output undefined opcodes where source or destination register + overlaps with modified pointer register. Handle (X + d) addresses. + * config/avr/avr.md (*movhi, *movsi, *movsf): Correct insn length + in alternatives with memory operand. + 2000-12-20 Richard Henderson * c-typeck.c (build_asm_stmt): New, broken out from ... diff --git a/gcc/config/avr/avr.c b/gcc/config/avr/avr.c index 2903509..72c3523 100644 --- a/gcc/config/avr/avr.c +++ b/gcc/config/avr/avr.c @@ -1995,12 +1995,14 @@ out_movsi_r_mr (insn, op, l) if (reg_base == REG_X) /* (R26) */ { if (reg_dest == REG_X) - return *l=6, (AS2 (adiw,r26,3) CR_TAB - AS2 (ld,%D0,X) CR_TAB - AS2 (ld,%C0,-X) CR_TAB - AS2 (ld,__tmp_reg__,-X) CR_TAB - AS2 (ld,%A0,-X) CR_TAB - AS2 (mov,%B0,__tmp_reg__)); + /* "ld r26,-X" is undefined */ + return *l=7, (AS2 (adiw,r26,3) CR_TAB + AS2 (ld,r29,X) CR_TAB + AS2 (ld,r28,-X) CR_TAB + AS2 (ld,__tmp_reg__,-X) CR_TAB + AS2 (sbiw,r26,1) CR_TAB + AS2 (ld,r26,X) CR_TAB + AS2 (mov,r27,__tmp_reg__)); else if (reg_dest == REG_X - 2) return *l=5, (AS2 (ld,%A0,X+) CR_TAB AS2 (ld,%B0,X+) CR_TAB @@ -2073,6 +2075,37 @@ out_movsi_r_mr (insn, op, l) } reg_base = true_regnum (XEXP (base, 0)); + if (reg_base == REG_X) + { + /* R = (X + d) */ + if (reg_dest == REG_X) + { + *l = 7; + /* "ld r26,-X" is undefined */ + return (AS2 (adiw,r26,%o1+3) CR_TAB + AS2 (ld,r29,X) CR_TAB + AS2 (ld,r28,-X) CR_TAB + AS2 (ld,__tmp_reg__,-X) CR_TAB + AS2 (sbiw,r26,1) CR_TAB + AS2 (ld,r26,X) CR_TAB + AS2 (mov,r27,__tmp_reg__)); + } + *l = 6; + if (reg_dest == REG_X - 2) + return (AS2 (adiw,r26,%o1) CR_TAB + AS2 (ld,r24,X+) CR_TAB + AS2 (ld,r25,X+) CR_TAB + AS2 (ld,__tmp_reg__,X+) CR_TAB + AS2 (ld,r27,X) CR_TAB + AS2 (mov,r26,__tmp_reg__)); + + return (AS2 (adiw,r26,%o1) CR_TAB + AS2 (ld,%A0,X+) CR_TAB + AS2 (ld,%B0,X+) CR_TAB + AS2 (ld,%C0,X+) CR_TAB + AS2 (ld,%D0,X) CR_TAB + AS2 (sbiw,r26,%o1+3)); + } if (reg_dest == reg_base) return *l=5, (AS2 (ldd,%D0,%D1) CR_TAB AS2 (ldd,%C0,%C1) CR_TAB @@ -2137,19 +2170,22 @@ out_movsi_mr_r (insn, op, l) { if (reg_src == REG_X) { + /* "st X+,r26" is undefined */ if (reg_unused_after (insn, base)) - return *l=5, (AS2 (mov,__tmp_reg__,%B1) CR_TAB - AS2 (st,%0+,%A1) CR_TAB - AS2 (st,%0+,__tmp_reg__) CR_TAB - AS2 (st,%0+,%C1) CR_TAB - AS2 (st,%0,%D1)); + return *l=6, (AS2 (mov,__tmp_reg__,r27) CR_TAB + AS2 (st,X,r26) CR_TAB + AS2 (adiw,r26,1) CR_TAB + AS2 (st,X+,__tmp_reg__) CR_TAB + AS2 (st,X+,r28) CR_TAB + AS2 (st,X,r29)); else - return *l=6, (AS2 (mov,__tmp_reg__,%B1) CR_TAB - AS2 (st,%0+,%A1) CR_TAB - AS2 (st,%0+,__tmp_reg__) CR_TAB - AS2 (st,%0+,%C1) CR_TAB - AS2 (st,%0,%D1) CR_TAB - AS2 (sbiw,r26,3)); + return *l=7, (AS2 (mov,__tmp_reg__,r27) CR_TAB + AS2 (st,X,r26) CR_TAB + AS2 (adiw,r26,1) CR_TAB + AS2 (st,X+,__tmp_reg__) CR_TAB + AS2 (st,X+,r28) CR_TAB + AS2 (st,X,r29) CR_TAB + AS2 (sbiw,r26,3)); } else if (reg_base == reg_src + 2) { @@ -2186,9 +2222,10 @@ out_movsi_mr_r (insn, op, l) else if (GET_CODE (base) == PLUS) /* (R + i) */ { int disp = INTVAL (XEXP (base, 1)); + reg_base = REGNO (XEXP (base, 0)); if (disp > MAX_LD_OFFSET (GET_MODE (dest))) { - if (REGNO (XEXP (base, 0)) != REG_Y) + if (reg_base != REG_Y) fatal_insn ("Incorrect insn:",insn); if (disp <= 63 + MAX_LD_OFFSET (GET_MODE (dest))) { @@ -2213,6 +2250,43 @@ out_movsi_mr_r (insn, op, l) AS2 (sbci, r29, hi8(%4))); } } + if (reg_base == REG_X) + { + /* (X + d) = R */ + if (reg_src == REG_X) + { + *l = 9; + return (AS2 (mov,__tmp_reg__,r26) CR_TAB + AS2 (mov,__zero_reg__,r27) CR_TAB + AS2 (adiw,r26,%o0) CR_TAB + AS2 (st,X+,__tmp_reg__) CR_TAB + AS2 (st,X+,__zero_reg__) CR_TAB + AS2 (st,X+,r28) CR_TAB + AS2 (st,X,r29) CR_TAB + AS1 (clr,__zero_reg__) CR_TAB + AS2 (sbiw,r26,%o0+3)); + } + else if (reg_src == REG_X - 2) + { + *l = 9; + return (AS2 (mov,__tmp_reg__,r26) CR_TAB + AS2 (mov,__zero_reg__,r27) CR_TAB + AS2 (adiw,r26,%o0) CR_TAB + AS2 (st,X+,r24) CR_TAB + AS2 (st,X+,r25) CR_TAB + AS2 (st,X+,__tmp_reg__) CR_TAB + AS2 (st,X,__zero_reg__) CR_TAB + AS1 (clr,__zero_reg__) CR_TAB + AS2 (sbiw,r26,%o0+3)); + } + *l = 6; + return (AS2 (adiw,r26,%o0) CR_TAB + AS2 (st,X+,%A1) CR_TAB + AS2 (st,X+,%B1) CR_TAB + AS2 (st,X+,%C1) CR_TAB + AS2 (st,X,%D1) CR_TAB + AS2 (sbiw,r26,%o0+3)); + } return *l=4, (AS2 (std,%A0,%A1) CR_TAB AS2 (std,%B0,%B1) CR_TAB AS2 (std,%C0,%C1) CR_TAB @@ -2545,15 +2619,18 @@ out_movhi_mr_r (insn, op, l) { if (reg_src == REG_X) { + /* "st X+,r26" is undefined */ if (reg_unused_after (insn, src)) - return *l=3, (AS2 (mov,__tmp_reg__,r27) CR_TAB - AS2 (st ,X+,r26) CR_TAB - AS2 (st ,X,__tmp_reg__)); + return *l=4, (AS2 (mov,__tmp_reg__,r27) CR_TAB + AS2 (st,X,r26) CR_TAB + AS2 (adiw,r26,1) CR_TAB + AS2 (st,X,__tmp_reg__)); else - return *l=4, (AS2 (mov,__tmp_reg__,r27) CR_TAB - AS2 (st ,X+,r26) CR_TAB - AS2 (st ,X,__tmp_reg__) CR_TAB - AS2 (sbiw,r26,1)); + return *l=5, (AS2 (mov,__tmp_reg__,r27) CR_TAB + AS2 (st,X,r26) CR_TAB + AS2 (adiw,r26,1) CR_TAB + AS2 (st,X,__tmp_reg__) CR_TAB + AS2 (sbiw,r26,1)); } else { @@ -2573,9 +2650,10 @@ out_movhi_mr_r (insn, op, l) else if (GET_CODE (base) == PLUS) { int disp = INTVAL (XEXP (base, 1)); + reg_base = REGNO (XEXP (base, 0)); if (disp > MAX_LD_OFFSET (GET_MODE (dest))) { - if (REGNO (XEXP (base, 0)) != REG_Y) + if (reg_base != REG_Y) fatal_insn ("Incorrect insn:",insn); if (disp <= 63 + MAX_LD_OFFSET (GET_MODE (dest))) { @@ -2596,6 +2674,26 @@ out_movhi_mr_r (insn, op, l) AS2 (sbci, r29, hi8(%4))); } } + if (reg_base == REG_X) + { + /* (X + d) = R */ + if (reg_src == REG_X) + { + *l = 7; + return (AS2 (mov,__tmp_reg__,r26) CR_TAB + AS2 (mov,__zero_reg__,r27) CR_TAB + AS2 (adiw,r26,%o0) CR_TAB + AS2 (st,X+,__tmp_reg__) CR_TAB + AS2 (st,X,__zero_reg__) CR_TAB + AS1 (clr,__zero_reg__) CR_TAB + AS2 (sbiw,r26,%o0+1)); + } + *l = 4; + return (AS2 (adiw,r26,%o0) CR_TAB + AS2 (st,X+,%A1) CR_TAB + AS2 (st,X,%B1) CR_TAB + AS2 (sbiw,r26,%o0+1)); + } return *l=2, (AS2 (std,%A0,%A1) CR_TAB AS2 (std,%B0,%B1)); } diff --git a/gcc/config/avr/avr.md b/gcc/config/avr/avr.md index c49b72d..c3a5e37 100644 --- a/gcc/config/avr/avr.md +++ b/gcc/config/avr/avr.md @@ -246,7 +246,7 @@ "(register_operand (operands[0],HImode) || register_operand (operands[1],HImode) || const0_rtx == operands[1])" "* return output_movhi (insn, operands, NULL);" - [(set_attr "length" "2,4,4,2,6,5,2") + [(set_attr "length" "2,6,7,2,6,5,2") (set_attr "cc" "none,clobber,clobber,none,clobber,none,none")]) ;;========================================================================== @@ -295,7 +295,7 @@ "(register_operand (operands[0],SImode) || register_operand (operands[1],SImode) || const0_rtx == operands[1])" "* return output_movsisf (insn, operands, NULL);" - [(set_attr "length" "4,4,8,8,4,10") + [(set_attr "length" "4,4,8,9,4,10") (set_attr "cc" "none,set_zn,clobber,clobber,none,clobber")]) ;; fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff @@ -321,7 +321,7 @@ "register_operand (operands[0], SFmode) || register_operand (operands[1], SFmode)" "* return output_movsisf (insn, operands, NULL);" - [(set_attr "length" "4,4,8,8,4,10") + [(set_attr "length" "4,4,8,9,4,10") (set_attr "cc" "none,set_zn,clobber,clobber,none,clobber")]) ;;=========================================================================