--- gcc/config/1750a/1750a.md 2018/04/24 18:22:37 1.1 +++ gcc/config/1750a/1750a.md 2018/04/24 18:30:22 1.1.1.2 @@ -1,7 +1,7 @@ ;;- Machine description for GNU compiler ;;- MIL-STD-1750A version. -;; Copyright (C) 1994 Free Software Foundation, Inc. -;; Contributed by O.M.Kellogg, DASA (okellogg@salyko.cube.net). +;; Copyright (C) 1994, 1995 Free Software Foundation, Inc. +;; Contributed by O.M.Kellogg, DASA (kellogg@space.otn.dasa.de). ;; This file is part of GNU CC. @@ -17,7 +17,8 @@ ;; You should have received a copy of the GNU General Public License ;; along with GNU CC; see the file COPYING. If not, write to -;; the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. +;; the Free Software Foundation, 59 Temple Place - Suite 330, +;; Boston, MA 02111-1307, USA. ;;- instruction definitions @@ -54,7 +55,7 @@ [(set (match_operand:QI 0 "push_operand" "=<") (match_operand:QI 1 "general_operand" "r"))] "" - "pshm r%1,r%1") + "pshm r%1,r%1 ; stackptr = R%0") (define_insn "" [(set (match_operand:HI 0 "push_operand" "=<") @@ -62,9 +63,12 @@ "" "* { - rtx new_operands[2]; + rtx new_operands[3]; + new_operands[2] = operands[0]; new_operands[0] = operands[1]; new_operands[1] = gen_rtx(CONST_INT,VOIDmode,REGNO(operands[1])+1); + output_asm_insn(\"pshm r%0,r%1 ; stackptr = r%2\",new_operands); + return \";\"; } ") (define_insn "" @@ -73,11 +77,12 @@ "" "* { - rtx new_operands[2]; + rtx new_operands[3]; + new_operands[2] = operands[0]; new_operands[0] = operands[1]; new_operands[1] = gen_rtx(CONST_INT,VOIDmode,REGNO(operands[1])+1); - output_asm_insn(\"pshm r%0,r%1\",new_operands); - return \"\;\"; + output_asm_insn(\"pshm r%0,r%1 ; stackptr = r%2\",new_operands); + return \";\"; } ") (define_insn "" @@ -86,11 +91,12 @@ "" "* { - rtx new_operands[2]; + rtx new_operands[3]; + new_operands[2] = operands[0]; new_operands[0] = operands[1]; new_operands[1] = gen_rtx(CONST_INT,VOIDmode,REGNO(operands[1])+2); - output_asm_insn(\"pshm r%0,r%1\",new_operands); - return \"\;\"; + output_asm_insn(\"pshm r%0,r%1 ; stackptr = r%2\",new_operands); + return \";\"; } ") ;; stackpop @@ -110,7 +116,7 @@ new_operands[0] = operands[0]; new_operands[1] = gen_rtx(CONST_INT,VOIDmode,REGNO(operands[0])+1); output_asm_insn(\"popm r%0,r%1\",new_operands); - return \"\;\"; + return \";\"; } ") (define_insn "" @@ -123,7 +129,7 @@ new_operands[0] = operands[0]; new_operands[1] = gen_rtx(CONST_INT,VOIDmode,REGNO(operands[0])+1); output_asm_insn(\"popm r%0,r%1\",new_operands); - return \"\;\"; + return \";\"; } ") (define_insn "" @@ -136,7 +142,7 @@ new_operands[0] = operands[0]; new_operands[1] = gen_rtx(CONST_INT,VOIDmode,REGNO(operands[0])+2); output_asm_insn(\"popm r%0,r%1\",new_operands); - return \"\;\"; + return \";\"; } ") ;; Test operations. These shouldn't really occur for 1750: @@ -192,12 +198,35 @@ (compare (match_operand:QI 0 "register_operand" "r,r,r,r,r") (match_operand:QI 1 "general_operand" "I,J,i,r,m")))] "" - "@ - cisp r%0,%1 - cisn r%0,%J1 - cim r%0,%1 - cr r%0,r%1 - c r%0,%1 ") + "* + { + if (next_cc_user_is_unsigned (insn)) + switch (which_alternative) + { + case 0: + case 1: + case 2: + return \"ucim.m %0,%1\"; + case 3: + return \"ucr.m %0,%1\"; + case 4: + return \"uc.m %0,%1\"; + } + else + switch (which_alternative) + { + case 0: + return \"cisp r%0,%1\"; + case 1: + return \"cisn r%0,%J1\"; + case 2: + return \"cim r%0,%1\"; + case 3: + return \"cr r%0,r%1\"; + case 4: + return \"c r%0,%1\"; + } + } ") (define_insn "cmphi" [(set (cc0) @@ -210,11 +239,12 @@ (define_insn "cmphf" [(set (cc0) - (compare (match_operand:HF 0 "general_operand" "r,r") - (match_operand:HF 1 "general_operand" "r,m")))] + (compare (match_operand:HF 0 "general_operand" "r,z,r") + (match_operand:HF 1 "general_operand" "r,Q,m")))] "" "@ fcr r%0,r%1 + fcb %Q1 fc r%0,%1 ") (define_insn "cmptqf" @@ -237,8 +267,11 @@ "" "* { - REGNO(operands[1]) += 1; - return \"lr r%0,r%1 ;trunchiqi2\"; + rtx new_operands[2]; + new_operands[0] = operands[0]; + new_operands[1] = gen_rtx (REG, HImode, REGNO(operands[1]) + 1); + output_asm_insn(\"lr r%0,r%1 ;trunchiqi2\",new_operands); + return \";\"; } ") ;; zero extension instructions @@ -249,17 +282,23 @@ "" "* { + rtx new_opnds[2]; output_asm_insn(\"xorr r%0,r%0 ;zero_extendqihi2\",operands); - REGNO(operands[0]) += 1; + new_opnds[0] = gen_rtx (REG, HImode, REGNO(operands[0]) + 1); + new_opnds[1] = operands[1]; switch (which_alternative) { case 0: - return \"lr r%0,r%1\"; + output_asm_insn(\"lr r%0,r%1\",new_opnds); + break; case 1: - return \"l r%0,%1\"; + output_asm_insn(\"l r%0,%1\",new_opnds); + break; case 2: - return \"lim r%0,%1\"; + output_asm_insn(\"lim r%0,%1\",new_opnds); + break; } + return \";\"; } ") ;; sign extension instructions @@ -279,18 +318,18 @@ ; 1750 HF-to-TQF extend: just append 16 bits (least signif.) with all bits zero (define_insn "extendhftqf2" [(set (match_operand:TQF 0 "register_operand" "=r,r") - (float_extend:TQF - (match_operand:HF 1 "general_operand" "r,m")))] + (float_extend:TQF (match_operand:HF 1 "general_operand" "r,m")))] "" "* { - REGNO(operands[0]) += 2; - output_asm_insn(\"xorr r%0,r%0 ;extendhftqf2\",operands); - REGNO(operands[0]) -= 2; + rtx new_opnds[2]; + new_opnds[0] = gen_rtx (REG, QImode, REGNO(operands[0]) + 2); + new_opnds[1] = operands[1]; + output_asm_insn(\"xorr r%0,r%0 ;extendhftqf2\",new_opnds); if (which_alternative == 0) - return \"dlr r%0,r%1\"; + return \"dlr r%0,r%1 ; put condition codes back on track\"; else - return \"dl r%0,%1\"; + return \"dl r%0,%1 ; put condition codes back on track\"; } ") ; 1750 TQF-to-HF truncate is a no-op: just leave away the least signif. 16 bits @@ -343,8 +382,8 @@ ;; 16-bit moves (define_insn "movqi" - [(set (match_operand:QI 0 "general_operand" "=r,r,r,r,r,r,r,m,m") - (match_operand:QI 1 "general_operand" "O,I,J,M,i,r,m,r,K"))] + [(set (match_operand:QI 0 "general_operand" "=r,r,r,r,r,r,t,r,Q,m,m") + (match_operand:QI 1 "general_operand" "O,I,J,M,i,r,Q,m,t,r,K"))] "" "@ xorr r%0,r%0 @@ -353,54 +392,62 @@ lim r%0,%1 ; 'M' constraint lim r%0,%1 ; 'i' constraint lr r%0,r%1 + lb %Q1 l r%0,%1 + stb %Q0 st r%1,%0 stc %1,%0 ") ;; 32-bit moves -;; Set HIreg to constant +; Set HIreg to constant (define_insn "" [(set (match_operand:HI 0 "register_operand" "=r") - (match_operand 1 "immediate_operand" "i"))] + (match_operand:HI 1 "immediate_operand" "i"))] "" "* - if (GET_CODE(operands[1]) == CONST_INT) { + rtx new_opnds[2]; int val = INTVAL(operands[1]); if (val >= 0) { if (val <= 65535) { - output_asm_insn(\"xorr r%0,r%0 ;movhi cst->reg\",operands); - operands[0] = gen_rtx(REG,QImode,REGNO(operands[0]) + 1); + new_opnds[0] = gen_rtx(REG,QImode,REGNO(operands[0])); + new_opnds[1] = operands[1]; + output_asm_insn(\"xorr r%0,r%0 ;movhi cst->reg\",new_opnds); + REGNO(new_opnds[0]) += 1; if (val == 0) - return \"xorr r%0,r%0\"; + output_asm_insn(\"xorr r%0,r%0\",new_opnds); else if (val <= 16) - return \"lisp r%0,%1\"; + output_asm_insn(\"lisp r%0,%1\",new_opnds); else - return \"lim r%0,%1\"; + output_asm_insn(\"lim r%0,%1\",new_opnds); + return \";\"; } } else if (val >= -16) return \"lisn r%0,%J1\;dsra r%0,16 ;movhi cst\"; - INTVAL(operands[1]) >>= 16; - output_asm_insn(\"lim r%0,%1 ;movhi cst->reg\",operands); - REGNO(operands[0]) += 1; - INTVAL(operands[1]) = val & 0xFFFF; - return \"lim r%0,%1\"; + new_opnds[0] = gen_rtx(REG, QImode, REGNO(operands[0])); + new_opnds[1] = gen_rtx(CONST_INT,VOIDmode,(INTVAL(operands[1])) >> 16); + output_asm_insn(\"lim r%0,%1 ;movhi cst->reg\",new_opnds); + INTVAL(new_opnds[1]) = val & 0xFFFF; + REGNO(new_opnds[0]) += 1; + output_asm_insn(\"lim r%0,%1\",new_opnds); + return \";\"; } - return \"lim r%0,%1\;dsra r%0,16 ;movhi cst\"; ") (define_insn "movhi" - [(set (match_operand:HI 0 "general_operand" "=r,r,m") - (match_operand:HI 1 "general_operand" "r,m,r"))] + [(set (match_operand:HI 0 "general_operand" "=r,z,r,Q,m") + (match_operand:HI 1 "general_operand" "r,Q,m,z,r"))] "" "@ - dlr r%0,r%1 - dl r%0,%1 - dst r%1,%0 ") + dlr r%0,r%1 + dlb %Q1 + dl r%0,%1 + dstb %Q0 + dst r%1,%0 ") ;; Single-Float moves are *same* as HImode moves: @@ -416,13 +463,15 @@ ; dst r%1,%0 ") (define_insn "movhf" - [(set (match_operand:HF 0 "general_operand" "=r,r,m") - (match_operand:HF 1 "general_operand" "r,m,r"))] + [(set (match_operand:HF 0 "general_operand" "=r,z,r,Q,m") + (match_operand:HF 1 "general_operand" "r,Q,m,z,r"))] "" "@ - dlr r%0,r%1 - dl r%0,%1 - dst r%1,%0 ") + dlr r%0,r%1 + dlb %Q1 + dl r%0,%1 + dstb %Q0 + dst r%1,%0 ") ;; Longfloat moves @@ -451,19 +500,10 @@ ;; single integer -;; Use "LIM Ra,sym,Rb" for adding a symbol value to a register and -;; transferring the result to a different register. -;(define_insn "" -; [(set (match_operand:QI 0 "register_operand" "=r") -; (plus:QI (match_operand:QI 1 "register_operand" "b") -; (match_operand:QI 2 "immediate_operand" "i")))] -; "REGNO(operands[0]) != REGNO(operands[1])" -; "lim r%0,%2,r%1 ;md special addqi") - (define_insn "addqi3" - [(set (match_operand:QI 0 "general_operand" "=r,r,r,r,r,m,m") - (plus:QI (match_operand:QI 1 "general_operand" "%0,0,0,0,0,0,0") - (match_operand:QI 2 "general_operand" "I,J,i,r,m,I,J")))] + [(set (match_operand:QI 0 "general_operand" "=r,r,r,r,t,r,m,m") + (plus:QI (match_operand:QI 1 "general_operand" "%0,0,0,0,0,0,0,0") + (match_operand:QI 2 "general_operand" "I,J,i,r,Q,m,I,J")))] "" "* switch (which_alternative) @@ -480,10 +520,12 @@ case 3: return \"ar r%0,r%2\"; case 4: - return \"a r%0,%2\"; + return \"ab %Q2\"; case 5: - return \"incm %2,%0\"; + return \"a r%0,%2\"; case 6: + return \"incm %2,%0\"; + case 7: return \"decm %J2,%0\"; } ") @@ -498,36 +540,38 @@ da r%0,%2 ") (define_insn "addhf3" - [(set (match_operand:HF 0 "register_operand" "=r,r") - (plus:HF (match_operand:HF 1 "register_operand" "%0,0") - (match_operand:HF 2 "general_operand" "m,r")))] + [(set (match_operand:HF 0 "register_operand" "=r,z,r") + (plus:HF (match_operand:HF 1 "register_operand" "%0,0,0") + (match_operand:HF 2 "general_operand" "r,Q,m")))] "" "@ - fa r%0,%2 - far r%0,r%2 ") + far r%0,r%2 + fab %Q2 + fa r%0,%2 ") (define_insn "addtqf3" [(set (match_operand:TQF 0 "register_operand" "=r,r") (plus:TQF (match_operand:TQF 1 "register_operand" "%0,0") - (match_operand:TQF 2 "general_operand" "m,r")))] + (match_operand:TQF 2 "general_operand" "r,m")))] "" "@ - efa r%0,%2 - efar r%0,r%2 ") + efar r%0,r%2 + efa r%0,%2 ") ;; subtract instructions ;; single integer (define_insn "subqi3" - [(set (match_operand:QI 0 "general_operand" "=r,r,r,r,m") - (minus:QI (match_operand:QI 1 "general_operand" "0,0,0,0,0") - (match_operand:QI 2 "general_operand" "I,i,r,m,I")))] + [(set (match_operand:QI 0 "general_operand" "=r,r,r,t,r,m") + (minus:QI (match_operand:QI 1 "general_operand" "0,0,0,0,0,0") + (match_operand:QI 2 "general_operand" "I,i,r,Q,m,I")))] "" "@ sisp r%0,%2 sim r%0,%2 sr r%0,r%2 + sbb %Q2 s r%0,%2 decm %2,%0 ") @@ -542,12 +586,13 @@ ds r%0,%2 ") (define_insn "subhf3" - [(set (match_operand:HF 0 "register_operand" "=r,r") - (minus:HF (match_operand:HF 1 "register_operand" "0,0") - (match_operand:HF 2 "general_operand" "r,m")))] + [(set (match_operand:HF 0 "register_operand" "=r,z,r") + (minus:HF (match_operand:HF 1 "register_operand" "0,0,0") + (match_operand:HF 2 "general_operand" "r,Q,m")))] "" "@ fsr r%0,r%2 + fsb %Q2 fs r%0,%2 ") (define_insn "subtqf3" @@ -577,13 +622,14 @@ ; 32-bit product (define_insn "mulqihi3" - [(set (match_operand:HI 0 "register_operand" "=r,r,r") - (mult:HI (match_operand:QI 1 "register_operand" "%0,0,0") - (match_operand:QI 2 "general_operand" "M,r,m")))] + [(set (match_operand:HI 0 "register_operand" "=r,r,t,r") + (mult:HI (match_operand:QI 1 "register_operand" "%0,0,0,0") + (match_operand:QI 2 "general_operand" "M,r,Q,m")))] "" "@ mim r%0,%1 mr r%0,r%2 + mb %Q2 m r%0,%2 ") (define_insn "mulhi3" @@ -598,12 +644,13 @@ ; not available on 1750: "umulhi3","umulhisi3","umulsi3" (unsigned multiply's) (define_insn "mulhf3" - [(set (match_operand:HF 0 "register_operand" "=r,r") - (mult:HF (match_operand:HF 1 "register_operand" "%0,0") - (match_operand:HF 2 "general_operand" "r,m")))] + [(set (match_operand:HF 0 "register_operand" "=r,z,r") + (mult:HF (match_operand:HF 1 "register_operand" "%0,0,0") + (match_operand:HF 2 "general_operand" "r,Q,m")))] "" "@ fmr r%0,r%2 + fmb %Q2 fm r%0,%2 ") (define_insn "multqf3" @@ -642,8 +689,15 @@ istr = \"disp\"; break; case 1: - INTVAL(operands[2]) = - INTVAL(operands[2]); /* to be corrected */ - istr = \"disn\"; + { + rtx new_opnds[4]; + new_opnds[0] = operands[0]; + new_opnds[1] = operands[1]; + new_opnds[2] = gen_rtx (CONST_INT, VOIDmode, -INTVAL(operands[2])); + new_opnds[3] = operands[3]; + istr = \"disn\"; + return (char *)mod_regno_adjust(istr,new_opnds); + } break; case 2: istr = \"dvim\"; @@ -670,12 +724,13 @@ dd r%0,%2 ") (define_insn "divhf3" - [(set (match_operand:HF 0 "register_operand" "=r,r") - (div:HF (match_operand:HF 1 "register_operand" "0,0") - (match_operand:HF 2 "general_operand" "r,m")))] + [(set (match_operand:HF 0 "register_operand" "=r,z,r") + (div:HF (match_operand:HF 1 "register_operand" "0,0,0") + (match_operand:HF 2 "general_operand" "r,Q,m")))] "" "@ fdr r%0,r%2 + fdb %Q2 fd r%0,%2 ") (define_insn "divtqf3" @@ -749,13 +804,14 @@ ;; AND (define_insn "andqi3" - [(set (match_operand:QI 0 "general_operand" "=r,r,r") - (and:QI (match_operand:QI 1 "general_operand" "%0,0,0") - (match_operand:QI 2 "general_operand" "M,r,m")))] + [(set (match_operand:QI 0 "general_operand" "=r,r,t,r") + (and:QI (match_operand:QI 1 "general_operand" "%0,0,0,0") + (match_operand:QI 2 "general_operand" "M,r,Q,m")))] "" "@ andm r%0,%2 andr r%0,r%2 + andb %Q2 and r%0,%2 ") ; This sets incorrect condition codes. See notice_update_cc() @@ -769,13 +825,14 @@ ;; OR (define_insn "iorqi3" - [(set (match_operand:QI 0 "general_operand" "=r,r,r") - (ior:QI (match_operand:QI 1 "general_operand" "%0,0,0") - (match_operand:QI 2 "general_operand" "M,r,m")))] + [(set (match_operand:QI 0 "general_operand" "=r,r,t,r") + (ior:QI (match_operand:QI 1 "general_operand" "%0,0,0,0") + (match_operand:QI 2 "general_operand" "M,r,Q,m")))] "" "@ orim r%0,%2 orr r%0,r%2 + orb %Q2 or r%0,%2 ") ; This sets incorrect condition codes. See notice_update_cc() @@ -846,59 +903,166 @@ ; (What to the 1750 is logical-shift-left, GCC likes to call "arithmetic") (define_insn "ashlqi3" - [(set (match_operand:QI 0 "register_operand" "=r,r,r") - (ashift:QI (match_operand:QI 1 "register_operand" "0,0,0") - (match_operand:QI 2 "general_operand" "O,I,r")))] + [(set (match_operand:QI 0 "register_operand" "=r,r") + (ashift:QI (match_operand:QI 1 "register_operand" "0,0") + (match_operand:QI 2 "nonmemory_operand" "I,r")))] "" "@ - ; optimized away an SLL r%0,0 sll r%0,%2 slr r%0,r%2 ") (define_insn "ashlhi3" [(set (match_operand:HI 0 "register_operand" "=r,r") (ashift:HI (match_operand:HI 1 "register_operand" "0,0") - (match_operand:QI 2 "general_operand" "L,r")))] + (match_operand:QI 2 "nonmemory_operand" "L,r")))] "" ; the 'L' constraint is a slight imprecise... - "@ - dsll r%0,%2 - dslr r%0,r%2 ") + "* + if (which_alternative == 1) + return \"dslr r%0,r%2\"; + else if (INTVAL(operands[2]) <= 16) + return \"dsll r%0,%2\"; + else + { + rtx new_opnds[2]; + new_opnds[0] = gen_rtx (REG, QImode, REGNO(operands[0])); + new_opnds[1] = gen_rtx (REG, QImode, REGNO(operands[0]) + 1); + output_asm_insn(\"lr r%0,r%1 ; ashlhi3 shiftcount > 16\",new_opnds); + new_opnds[1] = gen_rtx (CONST_INT, VOIDmode, INTVAL(operands[2]) - 16); + output_asm_insn(\"sll r%0,%1\",new_opnds); + return \";\"; + } ") + + +;; Right shift by a variable shiftcount works by negating the shift count, +;; then emitting a right shift with the shift count negated. This means +;; that all actual shift counts in the RTL will be positive. This +;; prevents converting shifts to ZERO_EXTRACTs with negative positions, +;; which isn't valid. +(define_expand "lshrqi3" + [(set (match_operand:QI 0 "general_operand" "=r") + (lshiftrt:QI (match_operand:QI 1 "general_operand" "0") + (match_operand:QI 2 "nonmemory_operand" "g")))] + "" + " +{ + if (GET_CODE (operands[2]) != CONST_INT) + operands[2] = gen_rtx (NEG, QImode, negate_rtx (QImode, operands[2])); +}") -(define_insn "lshrqi3" - [(set (match_operand:QI 0 "register_operand" "=r,r") - (lshiftrt:QI (match_operand:QI 1 "register_operand" "0,0") - (match_operand:QI 2 "general_operand" "I,r")))] +(define_insn "" + [(set (match_operand:QI 0 "register_operand" "=r") + (lshiftrt:QI (match_operand:QI 1 "register_operand" "0") + (match_operand:QI 2 "immediate_operand" "I")))] "" - "@ - srl r%0,%2 - neg r%2,r%2\;slr r%0,r%2 ") + "srl r%0,%2") -(define_insn "lshrhi3" - [(set (match_operand:HI 0 "register_operand" "=r,r") - (lshiftrt:HI (match_operand:HI 1 "register_operand" "0,0") - (match_operand:QI 2 "general_operand" "L,r")))] - "" ; the 'L' constraint is a slight imprecise... - "@ - dsrl r%0,%2 - neg r%2,r%2\;dslr r%0,r%2 ") +(define_insn "" + [(set (match_operand:QI 0 "register_operand" "=r") + (lshiftrt:QI (match_operand:QI 1 "register_operand" "0") + (neg:QI (match_operand:QI 2 "register_operand" "r"))))] + "" + "slr r%0,r%2 ") -(define_insn "ashrqi3" - [(set (match_operand:QI 0 "register_operand" "=r,r") - (ashiftrt:QI (match_operand:QI 1 "register_operand" "0,0") - (match_operand:QI 2 "general_operand" "I,r")))] +;; Same thing for HImode. + +(define_expand "lshrhi3" + [(set (match_operand:HI 0 "register_operand" "=r") + (lshiftrt:HI (match_operand:HI 1 "register_operand" "0") + (match_operand:QI 2 "nonmemory_operand" "g")))] "" - "@ - sra r%0,%2 - neg r%2,r%2\;sar r%0,r%2 ") + " + { + if (GET_CODE (operands[2]) != CONST_INT) + operands[2] = gen_rtx (NEG, QImode, negate_rtx (QImode, operands[2])); + }") -(define_insn "ashrhi3" - [(set (match_operand:HI 0 "register_operand" "=r,r") - (ashiftrt:HI (match_operand:HI 1 "register_operand" "0,0") - (match_operand:QI 2 "general_operand" "I,r")))] +(define_insn "" + [(set (match_operand:HI 0 "register_operand" "=r") + (lshiftrt:HI (match_operand:HI 1 "register_operand" "0") + (match_operand:QI 2 "immediate_operand" "L")))] "" - "@ - dsra r%0,%2 - neg r%2,r%2\;dsar r%0,r%2 ") + "* + { + rtx new_opnds[2]; + int amount = INTVAL(operands[2]); + if (amount <= 16) + return \"dsrl r%0,%2\"; + output_asm_insn(\"dsrl r%0,16 ; lshrhi3 shiftcount > 16\",operands); + new_opnds[0] = gen_rtx (REG, QImode, REGNO(operands[0]) + 1); + new_opnds[1] = gen_rtx (CONST_INT, VOIDmode, amount - 16); + output_asm_insn(\"srl r%0,%1\",new_opnds); + return \";\"; + } ") + +(define_insn "" + [(set (match_operand:HI 0 "register_operand" "=r") + (lshiftrt:HI (match_operand:HI 1 "register_operand" "0") + (neg:QI (match_operand:QI 2 "register_operand" "r"))))] + "" + "dslr r%0,r%2 ") + +;; Same applies for arithmetic shift right. +(define_expand "ashrqi3" + [(set (match_operand:QI 0 "general_operand" "=r") + (ashiftrt:QI (match_operand:QI 1 "general_operand" "0") + (match_operand:QI 2 "nonmemory_operand" "g")))] + "" + " + { + if (GET_CODE (operands[2]) != CONST_INT) + operands[2] = gen_rtx (NEG, QImode, negate_rtx (QImode, operands[2])); + }") + +(define_insn "" + [(set (match_operand:QI 0 "register_operand" "=r") + (ashiftrt:QI (match_operand:QI 1 "register_operand" "0") + (match_operand:QI 2 "immediate_operand" "I")))] + "" + "sra r%0,%2") + +(define_insn "" + [(set (match_operand:QI 0 "register_operand" "=r") + (ashiftrt:QI (match_operand:QI 1 "register_operand" "0") + (neg:QI (match_operand:QI 2 "register_operand" "r"))))] + "" + "sar r%0,r%2 ") + +;; HImode arithmetic shift right. +(define_expand "ashrhi3" + [(set (match_operand:HI 0 "general_operand" "=r") + (ashiftrt:HI (match_operand:HI 1 "general_operand" "0") + (match_operand:QI 2 "nonmemory_operand" "g")))] + "" + " + { + if (GET_CODE (operands[2]) != CONST_INT) + operands[2] = gen_rtx (NEG, QImode, negate_rtx (QImode, operands[2])); + }") + +(define_insn "" + [(set (match_operand:HI 0 "register_operand" "=r") + (ashiftrt:HI (match_operand:HI 1 "register_operand" "0") + (match_operand:QI 2 "immediate_operand" "L")))] + "" + "* + { + rtx new_opnds[2]; + int amount = INTVAL(operands[2]); + if (amount <= 16) + return \"dsra r%0,%2\"; + output_asm_insn(\"dsra r%0,16 ; ashrhi3 shiftcount > 16\",operands); + new_opnds[0] = gen_rtx (REG, QImode, REGNO(operands[0]) + 1); + new_opnds[1] = gen_rtx (CONST_INT, VOIDmode, amount - 16); + output_asm_insn(\"sra r%0,%1\",new_opnds); + return \";\"; + } ") + +(define_insn "" + [(set (match_operand:HI 0 "register_operand" "=r") + (ashiftrt:HI (match_operand:HI 1 "register_operand" "0") + (neg:QI (match_operand:QI 2 "register_operand" "r"))))] + "" + "dsar r%0,r%2 ") ;; rotate instructions @@ -906,7 +1070,7 @@ (define_insn "rotlqi3" [(set (match_operand:QI 0 "register_operand" "=r,r") (rotate:QI (match_operand:QI 1 "register_operand" "0,0") - (match_operand:QI 2 "general_operand" "I,r")))] + (match_operand:QI 2 "nonmemory_operand" "I,r")))] "" "@ slc r%0,%2 @@ -915,29 +1079,25 @@ (define_insn "rotlhi3" [(set (match_operand:HI 0 "register_operand" "=r,r") (rotate:HI (match_operand:HI 1 "register_operand" "0,0") - (match_operand:QI 2 "general_operand" "I,r")))] + (match_operand:QI 2 "nonmemory_operand" "I,r")))] "" "@ dslc r%0,%2 dscr r%0,r%2 ") (define_insn "rotrqi3" - [(set (match_operand:QI 0 "register_operand" "=r,r") - (rotatert:QI (match_operand:QI 1 "register_operand" "0,0") - (match_operand:QI 2 "general_operand" "I,r")))] + [(set (match_operand:QI 0 "register_operand" "=r") + (rotatert:QI (match_operand:QI 1 "register_operand" "0") + (match_operand:QI 2 "register_operand" "r")))] "" - "@ - slc r%0,%2 - neg r%2,r%2\;scr r%0,r%2 ") + "neg r%2,r%2\;scr r%0,r%2 ") (define_insn "rotrhi3" - [(set (match_operand:HI 0 "register_operand" "=r,r") - (rotatert:HI (match_operand:HI 1 "register_operand" "0,0") - (match_operand:QI 2 "general_operand" "I,r")))] + [(set (match_operand:HI 0 "register_operand" "=r") + (rotatert:HI (match_operand:HI 1 "register_operand" "0") + (match_operand:QI 2 "nonmemory_operand" "r")))] "" - "@ - dslc r%0,%2 - neg r%2,r%2\;dscr r%0,r%2 ") + "neg r%2,r%2\;dscr r%0,r%2 ") @@ -1191,7 +1351,7 @@ [(set (pc) (label_ref (match_operand 0 "" "")))] "" - "jc uc,%0") + "jc 15,%0") ;; Call subroutine, returning value in operand 0 ;; (which must be a hard register). @@ -1255,5 +1415,26 @@ "INTVAL(operands[2]) == -1" "soj r%0,%3") -;;;End. +;; Combine a Load Register with subsequent increment/decrement into a LIM +(define_peephole + [(set (match_operand:QI 0 "register_operand" "=r") + (match_operand:QI 1 "register_operand" "b")) + (set (match_dup 0) + (plus:QI (match_dup 0) + (match_operand:QI 2 "immediate_operand" "i")))] + "REGNO(operands[1]) > 0" + "lim r%0,%2,r%1 ; LR,inc/dec peephole") +;; Eliminate the redundant load in a store/load sequence +(define_peephole + [(set (mem:QI (plus:QI (match_operand:QI 0 "register_operand" "r") + (match_operand:QI 1 "immediate_operand" "i"))) + (match_operand:QI 2 "register_operand" "r")) + (set (match_operand:QI 3 "register_operand" "=r") + (mem:QI (plus:QI (match_dup 0) + (match_dup 1)))) + ] + "REGNO(operands[2]) == REGNO(operands[3])" + "st r%2,%1,r%0 ; eliminated previous redundant load") + +;;;End.