X-Git-Url: http://git.sourceforge.jp/view?p=pf3gnuchains%2Fgcc-fork.git;a=blobdiff_plain;f=gcc%2Fconfig%2F1750a%2F1750a.md;h=1ebd02e213fff4c6ea6167173945a76faa71dd08;hp=bcfc64eb4d475b3e22920038f43cbf315187ec2f;hb=f380450bdceb4c8294e2d54b4925645385935520;hpb=20daf2a0eb56ae47ae12a376e6cbfbf652f6d185 diff --git a/gcc/config/1750a/1750a.md b/gcc/config/1750a/1750a.md index bcfc64eb4d4..1ebd02e213f 100644 --- a/gcc/config/1750a/1750a.md +++ b/gcc/config/1750a/1750a.md @@ -1,13 +1,14 @@ ;;- Machine description for GNU compiler ;;- MIL-STD-1750A version. -;; Copyright (C) 1994, 1995 Free Software Foundation, Inc. -;; Contributed by O.M.Kellogg, DASA (kellogg@space.otn.dasa.de). +;; Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, +;; 2000 Free Software Foundation, Inc. +;; Contributed by O.M.Kellogg, DASA (oliver.kellogg@space.otn.dasa.de). ;; This file is part of GNU CC. ;; GNU CC is free software; you can redistribute it and/or modify ;; it under the terms of the GNU General Public License as published by -;; the Free Software Foundation; either version 1, or (at your option) +;; the Free Software Foundation; either version 2, or (at your option) ;; any later version. ;; GNU CC is distributed in the hope that it will be useful, @@ -61,38 +62,19 @@ [(set (match_operand:HI 0 "push_operand" "=<") (match_operand:HI 1 "general_operand" "r"))] "" - "* - { - rtx new_operands[2]; - new_operands[0] = operands[1]; - new_operands[1] = gen_rtx(CONST_INT,VOIDmode,REGNO(operands[1])+1); - } ") + "pshm r%1,r%d1") (define_insn "" [(set (match_operand:HF 0 "push_operand" "=<") (match_operand:HF 1 "general_operand" "r"))] "" - "* - { - rtx new_operands[2]; - 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 \"\;\"; - } ") + "pshm r%1,r%d1") (define_insn "" [(set (match_operand:TQF 0 "push_operand" "=<") (match_operand:TQF 1 "general_operand" "r"))] "" - "* - { - rtx new_operands[2]; - 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 \"\;\"; - } ") + "pshm r%1,r%t1") ;; stackpop (define_insn "" @@ -105,43 +87,22 @@ [(set (match_operand:HI 0 "general_operand" "=r") (match_operand:HI 1 "push_operand" ">"))] "" - "* - { - rtx new_operands[2]; - 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 \"\;\"; - } ") + "popm r%1,r%d1") (define_insn "" [(set (match_operand:HF 0 "general_operand" "=r") (match_operand:HF 1 "push_operand" ">"))] "" - "* - { - rtx new_operands[2]; - 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 \"\;\"; - } ") - + "popm r%1,r%d1") + (define_insn "" [(set (match_operand:TQF 0 "general_operand" "=r") (match_operand:TQF 1 "push_operand" ">"))] "" - "* - { - rtx new_operands[2]; - 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 \"\;\"; - } ") + "popm r%1,r%t1") -;; Test operations. These shouldn't really occur for 1750: -;; all important instructions set the cc's (see NOTICE_UPDATE_CC) + +;; Test operations. (define_insn "tstqi" [(set (cc0) @@ -155,35 +116,42 @@ "" "dlr r%0,r%0 ; from tsthi") +; With 1750A floats, testing the most significant word suffices. + (define_insn "tsthf" [(set (cc0) (match_operand:HF 0 "register_operand" "r"))] "" - "dlr r%0,r%0 ; from tsthf") + "lr r%0,r%0 ; tsthf") -;; This one is happy with "roughly zero" :-) (should be improved) (define_insn "tsttqf" [(set (cc0) (match_operand:TQF 0 "register_operand" "r"))] "" - "dlr r%0,r%0 ; from tsttqf") + "lr r%0,r%0 ; tsttqf") ;; block move. -; there is a problem with this insn in gcc-2.2.3 -; (clobber (match_dup 2)) does not prevent use of this operand later -; (define_insn "movstrqi" - [(set (mem:BLK (match_operand:QI 0 "register_operand" "r")) - (mem:BLK (match_operand:QI 1 "register_operand" "r"))) - (use (match_operand:QI 2 "register_operand" "r")) - (use (match_operand:QI 3 "immediate_operand" "")) + [(set (match_operand:BLK 0 "mov_memory_operand" "=m") + (match_operand:BLK 1 "mov_memory_operand" "m")) + (use (match_operand:QI 2 "general_operand" "r")) + (match_operand 3 "" "") (clobber (match_dup 0)) (clobber (match_dup 1)) (clobber (match_dup 2))] "" - "* return (char *)movcnt_regno_adjust(operands); ") + "* + { + rtx regops[3]; + + regops[0] = XEXP (operands[0], 0); + regops[1] = XEXP (operands[1], 0); + regops[2] = operands[2]; + + return movcnt_regno_adjust (regops); + } ") ;; compare instructions. @@ -206,6 +174,8 @@ return \"ucr.m %0,%1\"; case 4: return \"uc.m %0,%1\"; + default: + abort(); } else switch (which_alternative) @@ -220,6 +190,8 @@ return \"cr r%0,r%1\"; case 4: return \"c r%0,%1\"; + default: + abort(); } } ") @@ -228,9 +200,21 @@ (compare (match_operand:HI 0 "general_operand" "r,r") (match_operand:HI 1 "general_operand" "r,m")))] "" - "@ - dcr r%0,r%1 - dc r%0,%1 ") + "* + { + if (next_cc_user_is_unsigned (insn)) + { + if (which_alternative == 0) + return \"ducr.m %0,%1\"; + return \"duc.m %0,%1\"; + } + else + { + if (which_alternative == 0) + return \"dcr r%0,r%1\"; + return \"dc r%0,%1\"; + } + } ") (define_insn "cmphf" [(set (cc0) @@ -256,46 +240,29 @@ (define_insn "trunchiqi2" [(set (match_operand:QI 0 "register_operand" "=r") - (truncate:QI - (match_operand:HI 1 "register_operand" "r")))] + (truncate:QI (match_operand:HI 1 "register_operand" "r")))] "" - "* - { - REGNO(operands[1]) += 1; - return \"lr r%0,r%1 ;trunchiqi2\"; - } ") + "lr r%0,r%d1") -;; zero extension instructions -(define_insn "zero_extendqihi2" - [(set (match_operand:HI 0 "register_operand" "=r,r,r") - (zero_extend:HI (match_operand:QI 1 "general_operand" "r,m,i")))] - "" - "* - { - output_asm_insn(\"xorr r%0,r%0 ;zero_extendqihi2\",operands); - REGNO(operands[0]) += 1; - switch (which_alternative) - { - case 0: - return \"lr r%0,r%1\"; - case 1: - return \"l r%0,%1\"; - case 2: - return \"lim r%0,%1\"; - } - } ") +;; zero extension instructions: not defined, GCC can synthesize ;; sign extension instructions (define_insn "extendqihi2" - [(set (match_operand:HI 0 "register_operand" "=r,r,r") - (sign_extend:HI (match_operand:QI 1 "general_operand" "r,m,i")) )] + [(set (match_operand:HI 0 "register_operand" "=r,r") + (sign_extend:HI (match_operand:QI 1 "general_operand" "r,m")) )] "" - "@ - lr r%0,r%1 ;extendqihi2\;dsra r%0,16 - l r%0,%1 ;extendqihi2\;dsra r%0,16 - lim r%0,%1 ;extendqihi2\;dsra r%0,16 ") + "* + if (which_alternative == 0) + { + if (REGNO (operands [0]) != REGNO (operands [1])) + output_asm_insn (\"lr r%0,r%1\", operands); + } + else + output_asm_insn (\"l r%0,%1\", operands); + return \"dsra r%0,16 ;extendqihi2\"; + ") ;; Conversions between float and double. @@ -303,19 +270,20 @@ ; 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")))] "" "* + output_asm_insn(\"xorr r%t0,r%t0 ;extendhftqf2\", operands); + if (which_alternative == 0) { - REGNO(operands[0]) += 2; - output_asm_insn(\"xorr r%0,r%0 ;extendhftqf2\",operands); - REGNO(operands[0]) -= 2; - if (which_alternative == 0) + if (REGNO (operands[1]) != REGNO (operands[0])) return \"dlr r%0,r%1\"; else - return \"dl r%0,%1\"; - } ") + return \";\"; + } + else + return \"dl r%0,%1\"; + ") ; 1750 TQF-to-HF truncate is a no-op: just leave away the least signif. 16 bits (define_insn "trunctqfhf2" @@ -366,16 +334,32 @@ ;; 16-bit moves +; memory indirect to reg +(define_insn "" + [(set (match_operand:QI 0 "register_operand" "=r") + (mem:QI (match_operand 1 "memory_operand" "m")))] + "" + "li r%0,%1") + +; reg/const to memory indirect +(define_insn "" + [(set (mem:QI (match_operand 0 "memory_operand" "=m,m")) + (match_operand:QI 1 "nonmemory_operand" "r,K"))] + "" + "@ + sti r%1,%0 + stci %1,%0") + +; general case (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,m,m") + (match_operand:QI 1 "general_operand" "O,I,J,i,r,m,r,K"))] "" "@ xorr r%0,r%0 lisp r%0,%1 lisn r%0,%J1 - lim r%0,%1 ; 'M' constraint - lim r%0,%1 ; 'i' constraint + lim r%0,%1 lr r%0,r%1 l r%0,%1 st r%1,%0 @@ -383,85 +367,87 @@ ;; 32-bit moves -;; Set HIreg to constant +; memory indirect to reg (define_insn "" [(set (match_operand:HI 0 "register_operand" "=r") - (match_operand 1 "immediate_operand" "i"))] + (mem:HI (match_operand 1 "memory_operand" "m")))] "" - "* - if (GET_CODE(operands[1]) == CONST_INT) - { - 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); - if (val == 0) - return \"xorr r%0,r%0\"; - else if (val <= 16) - return \"lisp r%0,%1\"; - else - return \"lim r%0,%1\"; - } - } - 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\"; - } - return \"lim r%0,%1\;dsra r%0,16 ;movhi cst\"; - ") + "dli r%0,%1") -(define_insn "movhi" - [(set (match_operand:HI 0 "general_operand" "=r,r,m") - (match_operand:HI 1 "general_operand" "r,m,r"))] +; reg to memory indirect +(define_insn "" + [(set (mem:HI (match_operand 0 "memory_operand" "=m")) + (match_operand:HI 1 "register_operand" "r"))] "" - "@ - dlr r%0,r%1 - dl r%0,%1 - dst r%1,%0 ") + "dsti r%1,%0") +; general case +(define_insn "" + [(set (match_operand:HI 0 "general_operand" "=r,r,r,r,r,m,m") + (match_operand:HI 1 "general_operand" "O,I,J,r,m,r,K"))] + "" + "@ + xorr r%0,r%0\;xorr r%d0,r%d0 + xorr r%0,r%0\;lisp r%d0,%1 + lisn r%0,1 \;lisn r%d0,%J1 + dlr r%0,r%1 + dl r%0,%1 + dst r%1,%0 + stc 0,%0 \;stc %1,%A0 ") + +(define_expand "movhi" + [(set (match_operand:HI 0 "general_operand" "=g") + (match_operand:HI 1 "general_operand" "g"))] + "" + " + { + rtx op1 = operands[1]; + if (GET_CODE (operands[0]) == MEM) + { + if (GET_CODE (op1) == MEM + || (GET_CODE (op1) == CONST_INT + && (INTVAL (op1) < 0 || INTVAL (op1) > 15))) + operands[1] = force_reg (HImode, operands[1]); + } + else if (GET_CODE (op1) == CONST_INT + && (INTVAL (op1) < -16 || INTVAL (op1) > 16)) + operands[1] = force_const_mem (HImode, operands[1]); + }") -;; Single-Float moves are *same* as HImode moves: -;(define_insn "movhf" -; [(set (match_operand:HF 0 "general_operand" "=r,r,r,m") -; (match_operand:HF 1 "general_operand" "F,r,m,r"))] -; "" -; "@ -; %D1\;dl r%0,%F1 -; dlr r%0,r%1 -; dl r%0,%1 -; dst r%1,%0 ") +;; Single-Float moves -(define_insn "movhf" - [(set (match_operand:HF 0 "general_operand" "=r,r,m") - (match_operand:HF 1 "general_operand" "r,m,r"))] +(define_insn "" + [(set (match_operand:HF 0 "general_operand" "=r,r,m,m") + (match_operand:HF 1 "general_operand" "r,m,r,G"))] "" "@ - dlr r%0,r%1 - dl r%0,%1 - dst r%1,%0 ") + dlr r%0,r%1 + dl r%0,%1 + dst r%1,%0 + stc 0,%0 \;stc 0,%A0 ") + +(define_expand "movhf" + [(set (match_operand:HF 0 "general_operand" "") + (match_operand:HF 1 "general_operand" ""))] + "" + " + { + enum rtx_code op1code = GET_CODE (operands[1]); + if (GET_CODE (operands[0]) == MEM) + { + if (op1code == MEM || (op1code == CONST_DOUBLE + && !rtx_equal_p (operands[1], CONST0_RTX (HFmode)))) + operands[1] = force_reg (HFmode, operands[1]); + } + else if (op1code == CONST_DOUBLE) + operands[1] = force_const_mem (HFmode, operands[1]); + }") ;; Longfloat moves -;(define_insn "movtqf" -; [(set (match_operand:TQF 0 "general_operand" "=r,r,r,m") -; (match_operand:TQF 1 "general_operand" "F,r,m,r"))] -; "" -; "@ -; %E1\;efl r%0,%G1 -; eflr.m %0,%1 -; efl r%0,%1 -; efst r%1,%0 ") - -(define_insn "movtqf" +(define_insn "" [(set (match_operand:TQF 0 "general_operand" "=r,r,m") (match_operand:TQF 1 "general_operand" "r,m,r"))] "" @@ -470,20 +456,27 @@ efl r%0,%1 efst r%1,%0 ") +(define_expand "movtqf" + [(set (match_operand:TQF 0 "general_operand" "") + (match_operand:TQF 1 "general_operand" ""))] + "" + " + { + enum rtx_code op1code = GET_CODE (operands[1]); + if (GET_CODE (operands[0]) == MEM) + { + if (op1code == MEM || op1code == CONST_DOUBLE) + operands[1] = force_reg (TQFmode, operands[1]); + } + else if (op1code == CONST_DOUBLE) + operands[1] = force_const_mem (TQFmode, operands[1]); + }") + ;; add instructions ;; 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") @@ -509,6 +502,8 @@ return \"incm %2,%0\"; case 6: return \"decm %J2,%0\"; + default: + abort(); } ") ;; double integer @@ -524,20 +519,20 @@ (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")))] + (match_operand:HF 2 "general_operand" "r,m")))] "" "@ - fa r%0,%2 - far r%0,r%2 ") + far r%0,r%2 + 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 @@ -602,13 +597,26 @@ ; 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")))] + (mult:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "%r,r,r")) + (sign_extend:HI (match_operand:QI 2 "general_operand" "r,m,i"))))] "" - "@ - mim r%0,%1 - mr r%0,r%2 - m r%0,%2 ") + "* + if (REGNO (operands[1]) != REGNO (operands[0])) + output_asm_insn (\"lr r%0,r%1\", operands); + + switch (which_alternative) + { + case 0: + return \"mr r%0,r%2\"; + case 1: + return \"m r%0,%2\"; + case 2: + return \"mim r%0,%2\"; + default: + abort(); + } + ") + (define_insn "mulhi3" [(set (match_operand:HI 0 "register_operand" "=r,r") @@ -659,15 +667,22 @@ "" "* { - char *istr; + const char *istr; switch(which_alternative) { case 0: 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_INT (-INTVAL(operands[2])); + new_opnds[3] = operands[3]; + istr = \"disn\"; + return mod_regno_adjust (istr, new_opnds); + } break; case 2: istr = \"dvim\"; @@ -679,7 +694,7 @@ istr = \"dv \"; break; } - return (char *)mod_regno_adjust(istr,operands); + return mod_regno_adjust (istr, operands); }") ;; Division for other types is straightforward. @@ -761,15 +776,54 @@ (neg:TQF (match_operand:TQF 1 "register_operand" "r")))] "" " - emit_insn(gen_rtx(SET,VOIDmode,operands[0],CONST0_RTX(TQFmode))); - emit_insn(gen_rtx(SET,VOIDmode,operands[0], - gen_rtx(MINUS,TQFmode,operands[0],operands[1]))); + emit_insn (gen_rtx_SET (VOIDmode, operands[0], CONST0_RTX (TQFmode))); + emit_insn (gen_rtx_SET (VOIDmode, operands[0], + gen_rtx_MINUS (TQFmode, operands[0], operands[1]))); DONE; ") ;; bit-logical instructions +;; Set Bit +(define_insn "" + [(set (match_operand:QI 0 "general_operand" "=r,m") + (ior:QI (match_operand:QI 1 "general_operand" "0,0") + (match_operand:QI 2 "const_int_operand" "i,i")))] + "one_bit_set_p (INTVAL (operands [2]))" + "@ + sbr %b2,r%0 + sb %b2,%0") + +;; Reset Bit +(define_insn "" + [(set (match_operand:QI 0 "general_operand" "=r,m") + (and:QI (match_operand:QI 1 "general_operand" "0,0") + (match_operand:QI 2 "const_int_operand" "i,i")))] + "one_bit_set_p ((~INTVAL (operands [2])) & 0xffff)" + "@ + rbr %B2,r%0 + rb %B2,%0") + +;; Set Variable Bit +(define_insn "" + [(set (match_operand:QI 0 "register_operand" "=r") + (ior:QI (match_operand:QI 1 "register_operand" "0") + (lshiftrt:QI (const_int 32768) + (match_operand:QI 2 "register_operand" "r"))))] + "" + "svbr r%2,%r0") + +;; Reset Variable Bit +(define_insn "" + [(set (match_operand:QI 0 "general_operand" "=r") + (and:QI (match_operand:QI 1 "general_operand" "0") + (not:QI (lshiftrt:QI (const_int 32768) + (match_operand:QI 2 "register_operand" "r")))))] + "" + "rvbr r%2,%r0") + + ;; AND (define_insn "andqi3" @@ -795,7 +849,7 @@ (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")))] + (match_operand:QI 2 "general_operand" "M,r,m")))] "" "@ orim r%0,%2 @@ -870,59 +924,150 @@ ; (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 + { + output_asm_insn (\"dsll r%0,16 ; ashlhi3 shiftcnt > 16\", operands); + return \"sll r%0,%w2\"; + } + ") -(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")))] + +;; 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 "register_operand" "=r") + (lshiftrt:QI (match_operand:QI 1 "register_operand" "0") + (match_operand:QI 2 "nonmemory_operand" "g")))] "" - "@ - srl r%0,%2 - neg r%2,r%2\;slr r%0,r%2 ") + " +{ + if (GET_CODE (operands[2]) != CONST_INT) + operands[2] = gen_rtx_NEG (QImode, negate_rtx (QImode, operands[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") + (match_operand:QI 2 "immediate_operand" "I")))] + "" + "srl r%0,%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")))] +(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"))))] "" - "@ - sra r%0,%2 - neg r%2,r%2\;sar r%0,r%2 ") + "slr r%0,r%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")))] +;; 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")))] "" - "@ - dsra r%0,%2 - neg r%2,r%2\;dsar r%0,r%2 ") + " + { + 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") + (lshiftrt:HI (match_operand:HI 1 "register_operand" "0") + (match_operand:QI 2 "immediate_operand" "L")))] + "" + "* + if (INTVAL (operands[2]) <= 16) + return \"dsrl r%0,%2\"; + output_asm_insn (\"dsrl r%0,16 ; lshrhi3 shiftcount > 16\", operands); + return \"srl r%d0,%w2\"; + ") + +(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 "register_operand" "=r") + (ashiftrt:QI (match_operand:QI 1 "register_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 "register_operand" "=r") + (ashiftrt:HI (match_operand:HI 1 "register_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")))] + "" + "* + if (INTVAL (operands[2]) <= 16) + return \"dsra r%0,%2\"; + output_asm_insn (\"dsra r%0,16 ; ashrhi3 shiftcount > 16\", operands); + return \"sra r%d0,%w2\"; + ") + +(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 @@ -930,7 +1075,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 @@ -939,7 +1084,7 @@ (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 @@ -955,7 +1100,7 @@ (define_insn "rotrhi3" [(set (match_operand:HI 0 "register_operand" "=r") (rotatert:HI (match_operand:HI 1 "register_operand" "0") - (match_operand:QI 2 "general_operand" "r")))] + (match_operand:QI 2 "nonmemory_operand" "r")))] "" "neg r%2,r%2\;dscr r%0,r%2 ") @@ -1002,7 +1147,7 @@ (label_ref (match_operand 0 "" "")) (pc)))] "" - "* return (char *)branch_or_jump(\"ez\",CODE_LABEL_NUMBER(operands[0])); + "* return branch_or_jump (\"ez\", CODE_LABEL_NUMBER (operands[0])); ") (define_insn "bne" @@ -1012,7 +1157,7 @@ (label_ref (match_operand 0 "" "")) (pc)))] "" - "* return (char *)branch_or_jump(\"nz\",CODE_LABEL_NUMBER(operands[0])); + "* return branch_or_jump (\"nz\", CODE_LABEL_NUMBER (operands[0])); ") (define_insn "bgt" @@ -1022,7 +1167,7 @@ (label_ref (match_operand 0 "" "")) (pc)))] "" - "* return (char *)branch_or_jump(\"gt\",CODE_LABEL_NUMBER(operands[0])); + "* return branch_or_jump (\"gt\", CODE_LABEL_NUMBER (operands[0])); ") (define_insn "blt" @@ -1032,7 +1177,7 @@ (label_ref (match_operand 0 "" "")) (pc)))] "" - "* return (char *)branch_or_jump(\"lt\",CODE_LABEL_NUMBER(operands[0])); + "* return branch_or_jump (\"lt\", CODE_LABEL_NUMBER (operands[0])); ") (define_insn "bge" @@ -1042,7 +1187,7 @@ (label_ref (match_operand 0 "" "")) (pc)))] "" - "* return (char *)branch_or_jump(\"ge\",CODE_LABEL_NUMBER(operands[0])); + "* return branch_or_jump (\"ge\", CODE_LABEL_NUMBER (operands[0])); ") (define_insn "ble" @@ -1052,7 +1197,7 @@ (label_ref (match_operand 0 "" "")) (pc)))] "" - "* return (char *)branch_or_jump(\"le\",CODE_LABEL_NUMBER(operands[0])); + "* return branch_or_jump (\"le\", CODE_LABEL_NUMBER (operands[0])); ") @@ -1104,7 +1249,7 @@ (pc) (label_ref (match_operand 0 "" ""))))] "" - "* return (char *)branch_or_jump(\"nz\",CODE_LABEL_NUMBER(operands[0])); + "* return branch_or_jump (\"nz\", CODE_LABEL_NUMBER (operands[0])); ") (define_insn "" @@ -1114,7 +1259,7 @@ (pc) (label_ref (match_operand 0 "" ""))))] "" - "* return (char *)branch_or_jump(\"ez\",CODE_LABEL_NUMBER(operands[0])); + "* return branch_or_jump (\"ez\", CODE_LABEL_NUMBER (operands[0])); ") (define_insn "" @@ -1124,7 +1269,7 @@ (pc) (label_ref (match_operand 0 "" ""))))] "" - "* return (char *)branch_or_jump(\"le\",CODE_LABEL_NUMBER(operands[0])); + "* return branch_or_jump (\"le\", CODE_LABEL_NUMBER (operands[0])); ") (define_insn "" @@ -1134,7 +1279,7 @@ (pc) (label_ref (match_operand 0 "" ""))))] "" - "* return (char *)branch_or_jump(\"ge\",CODE_LABEL_NUMBER(operands[0])); + "* return branch_or_jump (\"ge\", CODE_LABEL_NUMBER (operands[0])); ") (define_insn "" @@ -1144,7 +1289,7 @@ (pc) (label_ref (match_operand 0 "" ""))))] "" - "* return (char *)branch_or_jump(\"lt\",CODE_LABEL_NUMBER(operands[0])); + "* return branch_or_jump (\"lt\", CODE_LABEL_NUMBER (operands[0])); ") (define_insn "" @@ -1154,7 +1299,7 @@ (pc) (label_ref (match_operand 0 "" ""))))] "" - "* return (char *)branch_or_jump(\"gt\",CODE_LABEL_NUMBER(operands[0])); + "* return branch_or_jump (\"gt\", CODE_LABEL_NUMBER (operands[0])); ") @@ -1216,7 +1361,7 @@ ;; Call subroutine, returning value in operand 0 ;; (which must be a hard register). (define_insn "call_value" - [(set (match_operand 0 "register_operand" "r") + [(set (match_operand 0 "register_operand" "=r") (call (match_operand:QI 1 "memory_operand" "m") (match_operand:QI 2 "general_operand" "g")))] ;; Operand 2 not really used for 1750. @@ -1239,17 +1384,6 @@ "" "ANYCALL %0") - -; (define_insn "return" -; [(return)] -; "" -; "* -; { -; rtx oprnd = gen_rtx(CONST_INT,VOIDmode,get_frame_size()); -; output_asm_insn(\"ret.m %0\",&oprnd); -; return \"\;\"; -; } ") - (define_insn "indirect_jump" [(set (pc) (match_operand:QI 0 "address_operand" "p"))] "" @@ -1275,77 +1409,26 @@ "INTVAL(operands[2]) == -1" "soj r%0,%3") -;; Load Base +;; Combine a Load Register with subsequent increment/decrement into a LIM (define_peephole [(set (match_operand:QI 0 "register_operand" "=r") - (mem:QI (plus:QI (match_operand:QI 1 "register_operand" "x") - (match_operand:QI 2 "immediate_operand" "L")))) - ] - "REGNO(operands[0]) == 2 && REGNO(operands[1]) >= 12 - && INTVAL(operands[2]) <= 255" - "lb r%1,%2") - -;; Double Load Base -(define_peephole - [(set (match_operand:HI 0 "register_operand" "=r") - (mem:HI (plus:QI (match_operand:QI 1 "register_operand" "x") - (match_operand:QI 2 "immediate_operand" "L")))) - ] - "REGNO(operands[0]) == 0 && REGNO(operands[1]) >= 12 - && INTVAL(operands[2]) <= 255" - "dlb r%1,%2") - -(define_peephole - [(set (match_operand:HF 0 "register_operand" "=r") - (mem:HF (plus:QI (match_operand:QI 1 "register_operand" "x") - (match_operand:QI 2 "immediate_operand" "L")))) - ] - "REGNO(operands[0]) == 0 && REGNO(operands[1]) >= 12 - && INTVAL(operands[2]) <= 255" - "dlb r%1,%2") - -;; Store Base -(define_peephole - [(set (mem:QI (plus:QI (match_operand:QI 0 "register_operand" "x") - (match_operand:QI 1 "immediate_operand" "L"))) - (match_operand:QI 2 "register_operand" "r")) - ] - "REGNO(operands[2]) == 2 && REGNO(operands[0]) >= 12 - && INTVAL(operands[1]) <= 255" - "stb r%0,%1") - -;; Double Store Base -(define_peephole - [(set (mem:HI (plus:QI (match_operand:QI 0 "register_operand" "x") - (match_operand:QI 1 "immediate_operand" "L"))) - (match_operand:HI 2 "register_operand" "r")) - ] - "REGNO(operands[2]) == 0 && REGNO(operands[0]) >= 12 - && INTVAL(operands[1]) <= 255" - "dstb r%0,%1") - -(define_peephole - [(set (mem:HF (plus:QI (match_operand:QI 0 "register_operand" "x") - (match_operand:QI 1 "immediate_operand" "L"))) - (match_operand:HF 2 "register_operand" "r")) - ] - "REGNO(operands[2]) == 0 && REGNO(operands[0]) >= 12 - && INTVAL(operands[1]) <= 255" - "dstb r%0,%1") + (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 1 "immediate_operand" "i"))) (match_operand:QI 2 "register_operand" "r")) (set (match_operand:QI 3 "register_operand" "=r") - (mem:QI (plus:QI (match_operand:QI 4 "register_operand" "r") - (match_operand:QI 5 "immediate_operand" "i")))) + (mem:QI (plus:QI (match_dup 0) + (match_dup 1)))) ] - "REGNO(operands[2]) == REGNO(operands[3]) && - REGNO(operands[0]) == REGNO(operands[4]) && - INTVAL(operands[1]) == INTVAL(operands[5])" + "REGNO(operands[2]) == REGNO(operands[3])" "st r%2,%1,r%0 ; eliminated previous redundant load") ;;;End. -