diff options
Diffstat (limited to 'gcc/config/h8300/h8300.md')
-rw-r--r-- | gcc/config/h8300/h8300.md | 2200 |
1 files changed, 0 insertions, 2200 deletions
diff --git a/gcc/config/h8300/h8300.md b/gcc/config/h8300/h8300.md deleted file mode 100644 index a68d54cf715..00000000000 --- a/gcc/config/h8300/h8300.md +++ /dev/null @@ -1,2200 +0,0 @@ -;; GCC machine description for Hitachi H8/300 -;; Copyright (C) 1992, 1993, 1994, 1995, 1996 Free Software Foundation, Inc. - -;; Contributed by Steve Chamberlain (sac@cygnus.com), -;; Jim Wilson (wilson@cygnus.com), and Doug Evans (dje@cygnus.com). - -;; 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 2, or (at your option) -;; any later version. - -;; GNU CC is distributed in the hope that it will be useful, -;; but WITHOUT ANY WARRANTY; without even the implied warranty of -;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -;; GNU General Public License for more details. - -;; 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, 59 Temple Place - Suite 330, -;; Boston, MA 02111-1307, USA. - -;; The original PO technology requires these to be ordered by speed, -;; so that assigner will pick the fastest. - -;; See file "rtl.def" for documentation on define_insn, match_*, et. al. - -(define_attr "cpu" "h8300,h8300h" - (const (symbol_ref "cpu_type"))) - -;; ??? If we can remove the operand type on all the insns, do it. -;; ??? Otherwise, try to have the operand type on all the insns. - -(define_attr "type" "branch,return,call,arith,move,float,multi" - (const_string "arith")) - -;; The size of instructions in bytes. - -(define_attr "length" "" - (cond [(eq_attr "type" "branch") - (if_then_else (and (ge (minus (pc) (match_dup 0)) - (const_int -120)) - (le (minus (pc) (match_dup 0)) - (const_int 120))) - (const_int 2) - (if_then_else (and (eq_attr "cpu" "h8300h") - (and (ge (minus (pc) (match_dup 0)) - (const_int -32000)) - (le (minus (pc) (match_dup 0)) - (const_int 32000)))) - (const_int 4) - (const_int 6))) - (eq_attr "type" "move") (const_int 4) - (eq_attr "type" "return") (const_int 2) - (eq_attr "type" "float") (const_int 12) - (eq_attr "type" "call") (const_int 4)] - (const_int 200))) - -;; Condition code settings. -;; none - insn does not affect cc -;; none_0hit - insn does not affect cc but it does modify operand 0 -;; This attribute is used to keep track of when operand 0 changes. -;; See the description of NOTICE_UPDATE_CC for more info. -;; set - insn sets flags z,n. v,c are set to 0. -;; (c may not really be set to 0 but that's ok, we don't need it anyway). -;; set_zn_c0 - insn sets z,n to usable values. v is unknown. c may or may not -;; be known (if it isn't that's ok, we don't need it anyway). -;; compare - compare instruction -;; clobber - value of cc is unknown -(define_attr "cc" "none,none_0hit,set,set_zn_c0,compare,clobber" - (const_string "clobber")) - -;; ---------------------------------------------------------------------- -;; MOVE INSTRUCTIONS -;; ---------------------------------------------------------------------- - -;; movqi - -(define_insn "movqi_push" - [(set (match_operand:QI 0 "push_operand" "=<") - (match_operand:QI 1 "register_operand" "r"))] - "" - "* -{ - if (TARGET_H8300) - return \"push.w %T1\"; - else - return \"push.l %S1\"; -}" - [(set_attr "type" "move") - (set (attr "length") (if_then_else (eq_attr "cpu" "h8300") (const_int 2) (const_int 4))) - (set_attr "cc" "set")]) - -;; ??? Use of the `c' constraint doesn't seem right. -(define_insn "movqi_internal" - [(set (match_operand:QI 0 "general_operand_dst" "=r,r,r,o,<,r") - (match_operand:QI 1 "general_operand_src" "I,r>,io,r,r,c"))] - "register_operand (operands[0],QImode) - || register_operand (operands[1], QImode)" - "@ - sub.b %X0,%X0 - mov.b %X1,%X0 - mov.b %X1,%X0 - mov.b %X1,%X0 - mov.b %X1,%X0 - xor %X0,%X0\;bst #0,%X0" - [(set_attr "type" "move") - (set_attr_alternative "length" - [(const_int 2) (const_int 2) - (if_then_else (eq_attr "cpu" "h8300") (const_int 4) (const_int 8)) - (if_then_else (eq_attr "cpu" "h8300") (const_int 4) (const_int 8)) - (if_then_else (eq_attr "cpu" "h8300") (const_int 2) (const_int 4)) - (const_int 4)]) - (set_attr "cc" "set_zn_c0,set,set,set,set,clobber")]) - -(define_expand "movqi" - [(set (match_operand:QI 0 "general_operand_dst" "") - (match_operand:QI 1 "general_operand_src" ""))] - "" - " -{ - /* One of the ops has to be in a register */ - if (!register_operand(operand0, QImode) - && !register_operand(operand1, QImode)) - { - operands[1] = copy_to_mode_reg(QImode, operand1); - } -}") - -(define_insn "movstrictqi" - [(set (strict_low_part (match_operand:QI 0 "general_operand_dst" "=r,r,r,o,<")) - (match_operand:QI 1 "general_operand_src" "I,r,io,r,r"))] - "" - "@ - sub.b %X0,%X0 - mov.b %X1,%X0 - mov.b %X1,%X0 - mov.b %X1,%X0 - mov.b %X1,%X0" - [(set_attr "type" "move") - (set_attr_alternative "length" - [(const_int 2) (const_int 2) - (if_then_else (eq_attr "cpu" "h8300") (const_int 4) (const_int 8)) - (if_then_else (eq_attr "cpu" "h8300") (const_int 4) (const_int 8)) - (if_then_else (eq_attr "cpu" "h8300") (const_int 2) (const_int 4))]) - (set_attr "cc" "set_zn_c0,set,set,set,set")]) - -;; movhi - -(define_insn "movhi_push" - [(set (match_operand:HI 0 "push_operand" "=<") - (match_operand:HI 1 "register_operand" "ra"))] - "" - "* -{ - if (TARGET_H8300) - return \"push.w %T1\"; - else - return \"push.l %S1\"; -}" - [(set_attr "type" "move") - (set (attr "length") (if_then_else (eq_attr "cpu" "h8300") (const_int 2) (const_int 4))) - (set_attr "cc" "set")]) - -(define_insn "movhi_internal" - [(set (match_operand:HI 0 "general_operand_dst" "=ra,ra,ra,o,<") - (match_operand:HI 1 "general_operand_src" "I,ra>,ion,ra,ra"))] - "" - "@ - sub.w %T0,%T0 - mov.w %T1,%T0 - mov.w %T1,%T0 - mov.w %T1,%T0 - mov.w %T1,%T0" - [(set_attr "type" "move") - (set_attr_alternative "length" - [(const_int 2) (const_int 2) - (if_then_else (eq_attr "cpu" "h8300") (const_int 4) (const_int 8)) - (if_then_else (eq_attr "cpu" "h8300") (const_int 4) (const_int 8)) - (if_then_else (eq_attr "cpu" "h8300") (const_int 2) (const_int 4))]) - (set_attr "cc" "set_zn_c0,set,set,set,set")]) - -(define_expand "movhi" - [(set (match_operand:HI 0 "general_operand_dst" "") - (match_operand:HI 1 "general_operand_src" ""))] - "" - " -{ - /* One of the ops has to be in a register */ - if (!register_operand(operand1, HImode) - && !register_operand(operand0, HImode)) - { - operands[1] = copy_to_mode_reg(HImode, operand1); - } -}") - -(define_insn "movstricthi" - [(set (strict_low_part (match_operand:HI 0 "general_operand_dst" "=r,r,r,o,<")) - (match_operand:HI 1 "general_operand_src" "I,r,io,r,r"))] - "" - "@ - sub.w %T0,%T0 - mov.w %T1,%T0 - mov.w %T1,%T0 - mov.w %T1,%T0 - mov.w %T1,%T0" - [(set_attr "type" "move") - (set_attr_alternative "length" - [(const_int 2) (const_int 2) - (if_then_else (eq_attr "cpu" "h8300") (const_int 4) (const_int 8)) - (if_then_else (eq_attr "cpu" "h8300") (const_int 4) (const_int 8)) - (if_then_else (eq_attr "cpu" "h8300") (const_int 2) (const_int 4))]) - (set_attr "cc" "set_zn_c0,set,set,set,set")]) - -;; movsi - -(define_expand "movsi" - [(set (match_operand:SI 0 "general_operand_dst" "") - (match_operand:SI 1 "general_operand_src" ""))] - "" - " -{ - if (TARGET_H8300) - { - if (do_movsi (operands)) - DONE; - } - else /* TARGET_H8300H */ - { - /* One of the ops has to be in a register. */ - if (!register_operand (operand1, SImode) - && !register_operand (operand0, SImode)) - { - operands[1] = copy_to_mode_reg (SImode, operand1); - } - } -}") - -(define_expand "movsf" - [(set (match_operand:SF 0 "general_operand_dst" "") - (match_operand:SF 1 "general_operand_src" ""))] - "" - " -{ - if (TARGET_H8300) - { - if (do_movsi (operands)) - DONE; - } - else /* TARGET_H8300H */ - { - /* One of the ops has to be in a register. */ - if (!register_operand (operand1, SFmode) - && !register_operand (operand0, SFmode)) - { - operands[1] = copy_to_mode_reg (SFmode, operand1); - } - } -}") - -(define_insn "movsi_h8300" - [(set (match_operand:SI 0 "general_operand_dst" "=r,r,r,o,<,r") - (match_operand:SI 1 "general_operand_src" "I,r,ion,r,r,>"))] - "TARGET_H8300 - && (register_operand (operands[0], SImode) - || register_operand (operands[1], SImode))" - "* -{ - int rn = -1; - switch (which_alternative) - { - case 0: - return \"sub.w %e0,%e0\;sub.w %f0,%f0\"; - case 1: - if (REGNO(operands[0]) < REGNO(operands[1])) - return \"mov.w %e1,%e0\;mov.w %f1,%f0\"; - else - return \"mov.w %f1,%f0\;mov.w %e1,%e0\"; - case 2: - /* Make sure we don't trample the register we index with. */ - - if (GET_CODE(operands[1]) == MEM) - { - rtx inside = XEXP (operands[1],0); - if (REG_P (inside)) - { - rn = REGNO(inside); - } - else if (GET_CODE (inside) == PLUS) - { - rtx lhs = XEXP (inside,0); - rtx rhs = XEXP (inside,1); - if (REG_P (lhs)) rn = REGNO (lhs); - if (REG_P (rhs)) rn = REGNO (rhs); - } - } - if (rn == REGNO (operands[0])) - { - /* Move the second word first. */ - return \"mov.w %f1,%f0\;mov.w %e1,%e0\"; - } - else - { - return \"mov.w %e1,%e0\;mov.w %f1,%f0\"; - } - - case 3: - return \"mov.w %e1,%e0\;mov.w %f1,%f0\"; - case 4: - return \"mov.w %f1,%T0\;mov.w %e1,%T0\"; - case 5: - return \"mov.w %T1,%e0\;mov.w %T1,%f0\"; - } -}" - [(set_attr "type" "move") - (set_attr "length" "4,4,8,8,4,4") - (set_attr "cc" "clobber")]) - -(define_insn "movsf_h8300" - [(set (match_operand:SF 0 "general_operand_dst" "=r,r,r,o,<,r") - (match_operand:SF 1 "general_operand_src" "I,r,ion,r,r,>"))] - "TARGET_H8300 - && (register_operand (operands[0], SFmode) - || register_operand (operands[1], SFmode))" - "* -{ - /* Copy of the movsi stuff */ - int rn = -1; - switch (which_alternative) - { - case 0: - return \"sub.w %e0,%e0\;sub.w %f0,%f0\"; - case 1: - if (REGNO(operands[0]) < REGNO(operands[1])) - return \"mov.w %e1,%e0\;mov.w %f1,%f0\"; - else - return \"mov.w %f1,%f0\;mov.w %e1,%e0\"; - case 2: - /* Make sure we don't trample the register we index with. */ - - if (GET_CODE (operands[1]) == MEM) - { - rtx inside = XEXP (operands[1],0); - if (REG_P (inside)) - { - rn = REGNO (inside); - } - else if (GET_CODE (inside) == PLUS) - { - rtx lhs = XEXP (inside,0); - rtx rhs = XEXP (inside,1); - if (REG_P (lhs)) rn = REGNO (lhs); - if (REG_P (rhs)) rn = REGNO (rhs); - } - } - if (rn == REGNO (operands[0])) - { - /* move the second word first */ - return \"mov.w %f1,%f0\;mov.w %e1,%e0\"; - } - else - { - return \"mov.w %e1,%e0\;mov.w %f1,%f0\"; - } - - case 3: - return \"mov.w %e1,%e0\;mov.w %f1,%f0\"; - case 4: - return \"mov.w %f1,%T0\;mov.w %e1,%T0\"; - case 5: - return \"mov.w %T1,%e0\;mov.w %T1,%f0\"; - - } -}" - [(set_attr "type" "move") - (set_attr "length" "4,4,8,8,4,4") - (set_attr "cc" "clobber")]) - -(define_insn "movsi_h8300h" - [(set (match_operand:SI 0 "general_operand_dst" "=ra,ra,ra,o,<,ra") - (match_operand:SI 1 "general_operand_src" "I,ra,ion,ra,ra,>"))] - "TARGET_H8300H - && (register_operand (operands[0], SImode) - || register_operand (operands[1], SImode))" - "@ - sub.l %S0,%S0 - mov.l %S1,%S0 - mov.l %S1,%S0 - mov.l %S1,%S0 - mov.l %S1,%S0 - mov.l %S1,%S0" - [(set_attr "type" "move") - (set_attr "length" "2,2,8,8,4,4") - (set_attr "cc" "set_zn_c0,set,set,set,set,set")]) - -(define_insn "movsf_h8300h" - [(set (match_operand:SF 0 "general_operand_dst" "=r,r,r,o,<,r") - (match_operand:SF 1 "general_operand_src" "I,r,ion,r,r,>"))] - "TARGET_H8300H - && (register_operand (operands[0], SFmode) - || register_operand (operands[1], SFmode))" - "@ - sub.l %S0,%S0 - mov.l %S1,%S0 - mov.l %S1,%S0 - mov.l %S1,%S0 - mov.l %S1,%S0 - mov.l %S1,%S0" - [(set_attr "type" "move") - (set_attr "length" "2,2,8,8,4,4") - (set_attr "cc" "set_zn_c0,set,set,set,set,set")]) - -;; ---------------------------------------------------------------------- -;; TEST INSTRUCTIONS -;; ---------------------------------------------------------------------- - -(define_insn "tstqi" - [(set (cc0) (match_operand:QI 0 "register_operand" "ra"))] - "" - "cmp.b #0,%X0" - [(set_attr "type" "arith") - (set_attr "length" "2") - (set_attr "cc" "set")]) - -(define_insn "tsthi" - [(set (cc0) (match_operand:HI 0 "general_operand" "ra"))] - "" - "mov.w %T0,%T0" - [(set_attr "type" "arith") - (set_attr "length" "2") - (set_attr "cc" "set")]) - -(define_insn "tstsi" - [(set (cc0) (match_operand:SI 0 "general_operand" "ra"))] - "TARGET_H8300H" - "mov.l %S0,%S0" - [(set_attr "type" "arith") - (set_attr "length" "2") - (set_attr "cc" "set")]) - -(define_insn "cmpqi" - [(set (cc0) - (compare:QI (match_operand:QI 0 "register_operand" "ra") - (match_operand:QI 1 "nonmemory_operand" "rai")))] - "" - "cmp.b %X1,%X0" - [(set_attr "type" "arith") - (set_attr "length" "2") - (set_attr "cc" "compare")]) - -;; ??? 300h can have an immediate operand here. - -(define_insn "cmphi" - [(set (cc0) - (compare:HI (match_operand:HI 0 "register_operand" "ra") - (match_operand:HI 1 "register_operand" "ra")))] - "" - "cmp.w %T1,%T0" - [(set_attr "type" "arith") - (set_attr "length" "2") - (set_attr "cc" "compare")]) - -;; ??? 300h can have an immediate operand here. - -(define_insn "cmpsi" - [(set (cc0) - (compare:SI (match_operand:SI 0 "register_operand" "ra") - (match_operand:SI 1 "register_operand" "ra")))] - "TARGET_H8300H" - "cmp.l %S1,%S0" - [(set_attr "type" "arith") - (set_attr "length" "2") - (set_attr "cc" "compare")]) - -;; ---------------------------------------------------------------------- -;; ADD INSTRUCTIONS -;; ---------------------------------------------------------------------- - -(define_insn "addqi3" - [(set (match_operand:QI 0 "register_operand" "=r") - (plus:QI (match_operand:QI 1 "register_operand" "%0") - (match_operand:QI 2 "nonmemory_operand" "ri")))] - "" - "add.b %X2,%X0" - [(set_attr "type" "arith") - (set_attr "length" "2") - (set_attr "cc" "set_zn_c0")]) - -;; h8300h: adds operates on the 32bit register. We can use it because we don't -;; use the e0-7 registers. -;; ??? 4 can be handled in one insn on the 300h. - -(define_insn "addhi3" - [(set (match_operand:HI 0 "register_operand" "=ra,ra,ra,ra,r,ra") - (plus:HI (match_operand:HI 1 "register_operand" "%0,0,0,0,0,0") - (match_operand:HI 2 "nonmemory_operand" "K,M,L,N,n,ra")))] - "" - "@ - adds %T2,%A0 - adds #2,%A0\;adds %C2,%A0 - subs %M2,%A0 - subs #2,%A0\;subs %M2,%A0 - add.b %s2,%s0\;addx %t2,%t0 - add.w %T2,%T0" - [(set_attr "type" "arith,multi,arith,multi,multi,arith") - (set_attr "length" "2,4,2,4,4,2") - (set_attr "cc" "none_0hit,none_0hit,none_0hit,none_0hit,clobber,set_zn_c0")]) - -(define_expand "addsi3" - [(set (match_operand:SI 0 "register_operand" "") - (plus:SI (match_operand:SI 1 "register_operand" "") - (match_operand:SI 2 "nonmemory_operand" "")))] - "" - "") - -(define_insn "addsi_h8300" - [(set (match_operand:SI 0 "register_operand" "=r,r,&r") - (plus:SI (match_operand:SI 1 "register_operand" "%0,0,r") - (match_operand:SI 2 "nonmemory_operand" "n,r,r")))] - "TARGET_H8300" - "@ - add %w2,%w0\;addx %x2,%x0\;addx %y2,%y0\;addx %z2,%z0 - add.w %f2,%f0\;addx %y2,%y0\;addx %z2,%z0 - mov %f1,%f0\;mov %e1,%e0\;add.w %f2,%f0\;addx %y2,%y0\;addx %z2,%z0" - [(set_attr "type" "arith") - (set_attr "length" "8,6,20") - (set_attr "cc" "clobber")]) - -;; ??? 4 can be handled in one insn on the 300h. -;; ??? Should the 'n' constraint be 'i' here? -;; ??? We don't handle (reg + symbol_ref) which the 300h can handle. - -(define_insn "addsi_h8300h" - [(set (match_operand:SI 0 "register_operand" "=ra,ra,ra,ra,r,ra") - (plus:SI (match_operand:SI 1 "register_operand" "%0,0,0,0,0,0") - (match_operand:SI 2 "nonmemory_operand" "K,M,L,N,n,ra")))] - "TARGET_H8300H" - "@ - adds %S2,%S0 - adds #2,%S0\;adds %C2,%S0 - subs %M2,%S0 - subs #2,%S0\;subs %M2,%S0 - add.l %S2,%S0 - add.l %S2,%S0" - [(set_attr "type" "multi,multi,multi,multi,arith,arith") - (set_attr "length" "2,4,2,4,6,2") - (set_attr "cc" "none_0hit,none_0hit,none_0hit,none_0hit,set_zn_c0,set_zn_c0")]) - -;; ---------------------------------------------------------------------- -;; SUBTRACT INSTRUCTIONS -;; ---------------------------------------------------------------------- - -(define_insn "subqi3" - [(set (match_operand:QI 0 "register_operand" "=r,r") - (minus:QI (match_operand:QI 1 "register_operand" "0,0") - (match_operand:QI 2 "nonmemory_operand" "r,i")))] - "" - "@ - sub.b %X2,%X0 - add.b %G2,%X0" - [(set_attr "type" "arith") - (set_attr "length" "2") - (set_attr "cc" "set_zn_c0")]) - -;; h8300h: subs operates on the 32bit register. We can use it because we don't -;; use the e0-7 registers. -;; ??? 4 can be handled in one insn on the 300h. -;; ??? The fourth alternative can use sub.w on the 300h. -;; ??? Should the 'n' constraint be an 'i' here? - -(define_insn "subhi3" - [(set (match_operand:HI 0 "register_operand" "=ra,ra,ra,r") - (minus:HI (match_operand:HI 1 "general_operand" "0,0,0,0") - (match_operand:HI 2 "nonmemory_operand" "K,M,ra,n")))] - "" - "@ - subs %T2,%T0 - subs #2,%T0\;subs %M2,%T0 - sub.w %T2,%T0 - add.b %E2,%s0\;addx %F2,%t0 ; -%0" - [(set_attr "type" "multi") - (set_attr "length" "2,4,2,4") - (set_attr "cc" "none_0hit,none_0hit,set_zn_c0,clobber")]) - -(define_expand "subsi3" - [(set (match_operand:SI 0 "register_operand" "") - (minus:SI (match_operand:SI 1 "register_operand" "") - (match_operand:SI 2 "nonmemory_operand" "")))] - "" - "") - -(define_insn "subsi3_h8300" - [(set (match_operand:SI 0 "register_operand" "=r") - (minus:SI (match_operand:SI 1 "register_operand" "0") - (match_operand:SI 2 "register_operand" "r")))] - "TARGET_H8300" - "sub.w %f2,%f0\;subx %y2,%y0\;subx %z2,%z0" - [(set_attr "type" "arith") - (set_attr "length" "6") - (set_attr "cc" "clobber")]) - -;; ??? 4 can be handled in one insn on the 300h. - -(define_insn "subsi3_h8300h" - [(set (match_operand:SI 0 "register_operand" "=ra,ra,ra,r") - (minus:SI (match_operand:SI 1 "general_operand" "0,0,0,0") - (match_operand:SI 2 "nonmemory_operand" "K,M,ra,n")))] - "TARGET_H8300H" - "@ - subs %T2,%T0 - subs #2,%T0\;subs %E2,%T0 - sub.l %S2,%S0 - sub.l %S2,%S0" - [(set_attr "type" "multi") - (set_attr "length" "2,4,2,6") - (set_attr "cc" "none_0hit,none_0hit,set_zn_c0,set_zn_c0")]) - -;; ---------------------------------------------------------------------- -;; MULTIPLY INSTRUCTIONS -;; ---------------------------------------------------------------------- - -;; Note that the h8/300 can only handle umulqihi3. - -(define_insn "mulqihi3" - [(set (match_operand:HI 0 "register_operand" "=r") - (mult:HI (sign_extend:HI (match_operand:QI 1 "general_operand" "%0")) - (sign_extend:HI (match_operand:QI 2 "register_operand" "r"))))] - "TARGET_H8300H" - "mulxs.b %X2,%T0" - [(set_attr "type" "multi") - (set_attr "length" "4") - (set_attr "cc" "set_zn_c0")]) - -(define_insn "mulhisi3" - [(set (match_operand:SI 0 "register_operand" "=r") - (mult:SI (sign_extend:SI (match_operand:HI 1 "general_operand" "%0")) - (sign_extend:SI (match_operand:HI 2 "register_operand" "r"))))] - "TARGET_H8300H" - "mulxs.w %T2,%S0" - [(set_attr "type" "multi") - (set_attr "length" "4") - (set_attr "cc" "set_zn_c0")]) - -(define_insn "umulqihi3" - [(set (match_operand:HI 0 "register_operand" "=r") - (mult:HI (zero_extend:HI (match_operand:QI 1 "general_operand" "%0")) - (zero_extend:HI (match_operand:QI 2 "register_operand" "r"))))] - "" - "mulxu %X2,%T0" - [(set_attr "type" "multi") - (set_attr "length" "2") - (set_attr "cc" "none_0hit")]) - -(define_insn "umulhisi3" - [(set (match_operand:SI 0 "register_operand" "=r") - (mult:SI (zero_extend:SI (match_operand:HI 1 "general_operand" "%0")) - (zero_extend:SI (match_operand:HI 2 "register_operand" "r"))))] - "TARGET_H8300H" - "mulxu.w %T2,%S0" - [(set_attr "type" "multi") - (set_attr "length" "2") - (set_attr "cc" "none_0hit")]) - -;; ---------------------------------------------------------------------- -;; DIVIDE INSTRUCTIONS -;; ---------------------------------------------------------------------- - -(define_insn "udivqi3" - [(set (match_operand:QI 0 "register_operand" "=r") - (udiv:QI (match_operand:HI 1 "general_operand" "0") - (match_operand:QI 2 "register_operand" "r")))] - "" - "divxu %X2,%T0" - [(set_attr "type" "multi") - (set_attr "length" "2") - (set_attr "cc" "clobber")]) - -;; ??? Will divxu always work here? - -(define_insn "divqi3" - [(set (match_operand:QI 0 "register_operand" "=r") - (div:QI (match_operand:HI 1 "general_operand" "0") - (match_operand:QI 2 "register_operand" "r")))] - "" - "divxu %X2,%T0" - [(set_attr "type" "multi") - (set_attr "length" "2") - (set_attr "cc" "clobber")]) - -(define_insn "udivhi3" - [(set (match_operand:HI 0 "register_operand" "=r") - (udiv:HI (match_operand:SI 1 "general_operand" "0") - (match_operand:HI 2 "register_operand" "r")))] - "TARGET_H8300H" - "divxu.w %T2,%S0" - [(set_attr "type" "multi") - (set_attr "length" "2") - (set_attr "cc" "clobber")]) - -(define_insn "divhi3" - [(set (match_operand:HI 0 "register_operand" "=r") - (div:HI (match_operand:SI 1 "general_operand" "0") - (match_operand:HI 2 "register_operand" "r")))] - "TARGET_H8300H" - "divxs.w %T2,%S0" - [(set_attr "type" "multi") - (set_attr "length" "4") - (set_attr "cc" "clobber")]) - -;; ---------------------------------------------------------------------- -;; MOD INSTRUCTIONS -;; ---------------------------------------------------------------------- - -(define_insn "umodqi3" - [(set (match_operand:QI 0 "register_operand" "=r") - (umod:QI (match_operand:HI 1 "general_operand" "0") - (match_operand:QI 2 "register_operand" "r")))] - "" - "divxu %X2,%T0\;mov %t0,%s0" - [(set_attr "type" "multi") - (set_attr "length" "4") - (set_attr "cc" "clobber")]) - -(define_insn "modqi3" - [(set (match_operand:QI 0 "register_operand" "=r") - (mod:QI (match_operand:HI 1 "general_operand" "0") - (match_operand:QI 2 "register_operand" "r")))] - "TARGET_H8300H" - "divxs.b %X2,%T0\;mov %t0,%s0" - [(set_attr "type" "multi") - (set_attr "length" "6") - (set_attr "cc" "clobber")]) - -(define_insn "umodhi3" - [(set (match_operand:HI 0 "register_operand" "=r") - (umod:HI (match_operand:SI 1 "general_operand" "0") - (match_operand:HI 2 "register_operand" "r")))] - "TARGET_H8300H" - "divxu.w %T2,%S0\;mov %e0,%f0" - [(set_attr "type" "multi") - (set_attr "length" "4") - (set_attr "cc" "clobber")]) - -(define_insn "modhi3" - [(set (match_operand:HI 0 "register_operand" "=r") - (mod:HI (match_operand:SI 1 "general_operand" "0") - (match_operand:HI 2 "register_operand" "r")))] - "TARGET_H8300H" - "divxs.w %T2,%S0\;mov %e0,%f0" - [(set_attr "type" "multi") - (set_attr "length" "6") - (set_attr "cc" "clobber")]) - -;; ---------------------------------------------------------------------- -;; AND INSTRUCTIONS -;; ---------------------------------------------------------------------- - -(define_insn "andqi3_internal" - [(set (match_operand:QI 0 "bit_operand" "=r,U") - (and:QI (match_operand:QI 1 "bit_operand" "%0,0") - (match_operand:QI 2 "nonmemory_operand" "rn,O")))] - "register_operand (operands[0], QImode) || o_operand (operands[2], QImode)" - "@ - and %X2,%X0 - bclr %W2,%X0" - [(set_attr "type" "arith") - (set_attr "length" "2,4") - (set_attr "cc" "set,none_0hit")]) - -(define_expand "andqi3" - [(set (match_operand:QI 0 "bit_operand" "=r,U") - (and:QI (match_operand:QI 1 "bit_operand" "%0,0") - (match_operand:QI 2 "nonmemory_operand" "rn,O")))] - "" - " -{ - if (fix_bit_operand (operands, 'O', AND)) - DONE; -}") - -;; ??? Should have a bclr case here also. -;; ??? This should be symmetric with iorhi3. - -(define_insn "andhi3" - [(set (match_operand:HI 0 "register_operand" "=r") - (and:HI (match_operand:HI 1 "register_operand" "%0") - (match_operand:HI 2 "nonmemory_operand" "rn")))] - "" - "* -{ - if (GET_CODE (operands[2]) == CONST_INT) - { - int i = INTVAL (operands[2]); - if ((i & 0x00ff) != 0x00ff) - output_asm_insn (\"and %s2,%s0\", operands); - if ((i & 0xff00) != 0xff00) - output_asm_insn (\"and %t2,%t0\", operands); - return \"\"; - } - return \"and %s2,%s0\;and %t2,%t0;\"; -}" - [(set_attr "type" "multi") - (set_attr "length" "4") - (set_attr "cc" "clobber")]) - -;; ??? There is an iorsi3 for TARGET_H8300. Should we have andsi3? - -(define_insn "andsi3" - [(set (match_operand:SI 0 "register_operand" "=r,r") - (and:SI (match_operand:SI 1 "register_operand" "%0,0") - (match_operand:SI 2 "nonmemory_operand" "r,i")))] - "TARGET_H8300H" - "@ - and %S2,%S0 - and %S2,%S0" - [(set_attr "type" "arith") - (set_attr "length" "4,6") - (set_attr "cc" "set")]) - -;; ---------------------------------------------------------------------- -;; OR INSTRUCTIONS -;; ---------------------------------------------------------------------- - -(define_insn "iorqi3_internal" - [(set (match_operand:QI 0 "bit_operand" "=U,r") - (ior:QI (match_operand:QI 1 "bit_operand" "%0,0") - (match_operand:QI 2 "nonmemory_operand" "P,rn")))] - "register_operand (operands[0], QImode) || p_operand (operands[2], QImode)" - "@ - bset %V2,%X0 - or %X2,%X0" - [(set_attr "type" "arith") - (set_attr "length" "4,2") - (set_attr "cc" "none_0hit,set")]) - -(define_expand "iorqi3" - [(set (match_operand:QI 0 "bit_operand" "=r,U") - (ior:QI (match_operand:QI 1 "bit_operand" "%0,0") - (match_operand:QI 2 "nonmemory_operand" "rn,P")))] - "" - " -{ - if (fix_bit_operand (operands, 'P', IOR)) - DONE; -}") - -;; ??? Should have a bset case here also. -;; ??? This should be symmetric with andhi3. - -(define_insn "iorhi3" - [(set (match_operand:HI 0 "general_operand" "=r,r") - (ior:HI (match_operand:HI 1 "general_operand" "%0,0") - (match_operand:HI 2 "general_operand" "J,rn")))] - "" - "* -{ - if (TARGET_H8300) - { - if (GET_CODE (operands[2]) == CONST_INT) - { - int i = INTVAL (operands[2]); - if ((i & 0x00ff) != 0) - output_asm_insn (\"or %s2,%s0\", operands); - if ((i & 0xff00) != 0) - output_asm_insn (\"or %t2,%t0\", operands); - return \"\"; - } - return \"or %s2,%s0\;or %t2,%t0; %2 or2\"; - } - else - { - return \"or %S2,%S0\"; - } -}" - [(set_attr "type" "multi") - (set_attr "length" "2,4") - (set_attr "cc" "clobber,clobber")]) - -(define_insn "iorsi3" - [(set (match_operand:SI 0 "register_operand" "=r") - (ior:SI (match_operand:SI 1 "register_operand" "%0") - (match_operand:SI 2 "nonmemory_operand" "ri")))] - "" - "* -{ - if (TARGET_H8300) - { - if (GET_CODE (operands[2]) == CONST_INT) - { - int i = INTVAL (operands[2]); - if ((i & 0x000000ff) != 0) - output_asm_insn (\"or %w2,%w0\", operands); - if ((i & 0x0000ff00) != 0) - output_asm_insn (\"or %x2,%x0\", operands); - if ((i & 0x00ff0000) != 0) - output_asm_insn (\"or %y2,%y0\", operands); - if ((i & 0xff000000) != 0) - output_asm_insn (\"or %z2,%z0\", operands); - return \"\"; - } - return \"or %w2,%w0\;or %x2,%x0\;or %y2,%y0\;or %z2,%z0\;\"; - } - else - { - return \"or %S2,%S0\"; - } -}" - [(set_attr "type" "multi") - (set_attr "length" "8") - (set_attr "cc" "clobber")]) - -;; ---------------------------------------------------------------------- -;; XOR INSTRUCTIONS -;; ---------------------------------------------------------------------- - -(define_insn "xorqi3_internal" - [(set (match_operand:QI 0 "bit_operand" "=r,U") - (xor:QI (match_operand:QI 1 "bit_operand" "%0,0") - (match_operand:QI 2 "nonmemory_operand" "rn,P")))] - "register_operand (operands[0], QImode) || p_operand (operands[2], QImode)" - "@ - xor %X2,%X0 - bnot %V2,%X0" - [(set_attr "type" "arith") - (set_attr "length" "2,4") - (set_attr "cc" "set,none_0hit")]) - -(define_expand "xorqi3" - [(set (match_operand:QI 0 "bit_operand" "=r,U") - (xor:QI (match_operand:QI 1 "bit_operand" "%0,0") - (match_operand:QI 2 "nonmemory_operand" "rn,O")))] - "" - " -{ - if (fix_bit_operand (operands, 'O', XOR)) - DONE; -}") - -;; ??? This should be symmetric with andhi3. - -(define_insn "xorhi3" - [(set (match_operand:HI 0 "register_operand" "=r") - (xor:HI (match_operand:HI 1 "general_operand" "%0") - (match_operand:HI 2 "nonmemory_operand" "rn")))] - "" - "* -{ - if (TARGET_H8300) - return \"xor %s2,%s0\;xor %t2,%t0\"; - else - return \"xor %S2,%S0\"; -}" - [(set_attr "type" "multi") - (set_attr "length" "4") - (set_attr "cc" "clobber")]) - -;; ??? There is an iorsi3 for TARGET_H8300. Should we have xorsi3? - -(define_insn "xorsi3" - [(set (match_operand:SI 0 "register_operand" "=r,r") - (xor:SI (match_operand:SI 1 "register_operand" "%0,0") - (match_operand:SI 2 "nonmemory_operand" "r,i")))] - "TARGET_H8300H" - "@ - xor %S2,%S0 - xor %S2,%S0" - [(set_attr "type" "arith") - (set_attr "length" "4,6") - (set_attr "cc" "set")]) - -;; ---------------------------------------------------------------------- -;; NEGATION INSTRUCTIONS -;; ---------------------------------------------------------------------- - -(define_insn "negqi2" - [(set (match_operand:QI 0 "register_operand" "=r") - (neg:QI (match_operand:QI 1 "general_operand" "0")))] - "" - "neg %X0" - [(set_attr "type" "arith") - (set_attr "length" "2") - (set_attr "cc" "set_zn_c0")]) - -(define_expand "neghi2" - [(set (match_operand:HI 0 "register_operand" "=r") - (neg:HI (match_operand:HI 1 "general_operand" "0")))] - "" - " -{ - if (TARGET_H8300) - { - emit_insn (gen_neghi2_h8300 (operands[0], operands[1])); - DONE; - } -}") - -(define_expand "neghi2_h8300" - [(set (match_dup 2) - (not:HI (match_operand:HI 1 "register_operand" "r"))) - (set (match_dup 2) (plus:HI (match_dup 2) (const_int 1))) - (set (match_operand:HI 0 "register_operand" "=r") - (match_dup 2))] - "" - "{ operands[2] = gen_reg_rtx (HImode); }") - -(define_insn "neghi2_h8300h" - [(set (match_operand:HI 0 "register_operand" "=r") - (neg:HI (match_operand:HI 1 "general_operand" "0")))] - "TARGET_H8300H" - "neg %T0" - [(set_attr "type" "arith") - (set_attr "length" "2") - (set_attr "cc" "set_zn_c0")]) - -(define_expand "negsi2" - [(set (match_operand:SI 0 "register_operand" "=r") - (neg:SI (match_operand:SI 1 "general_operand" "0")))] - "" - " -{ - if (TARGET_H8300) - { - emit_insn (gen_negsi2_h8300 (operands[0], operands[1])); - DONE; - } -}") - -(define_expand "negsi2_h8300" - [(set (match_dup 2) - (not:SI (match_operand:SI 1 "register_operand" "r"))) - (set (match_dup 2) (plus:SI (match_dup 2) (const_int 1))) - (set (match_operand:SI 0 "register_operand" "=r") - (match_dup 2))] - "" - "{ operands[2] = gen_reg_rtx(SImode); }") - -(define_insn "negsi2_h8300h" - [(set (match_operand:SI 0 "register_operand" "=r") - (neg:SI (match_operand:SI 1 "general_operand" "0")))] - "TARGET_H8300H" - "neg %S0" - [(set_attr "type" "arith") - (set_attr "length" "2") - (set_attr "cc" "set_zn_c0")]) - -;; ---------------------------------------------------------------------- -;; NOT INSTRUCTIONS -;; ---------------------------------------------------------------------- - -(define_insn "one_cmplqi2" - [(set (match_operand:QI 0 "register_operand" "=r") - (not:QI (match_operand:QI 1 "general_operand" "0")))] - "" - "not %X0" - [(set_attr "type" "arith") - (set_attr "length" "2") - (set_attr "cc" "set")]) - -(define_insn "one_cmplhi2" - [(set (match_operand:HI 0 "register_operand" "=r") - (not:HI (match_operand:HI 1 "general_operand" "0")))] - "" - "* -{ - if (TARGET_H8300) - return \"not %s0\;not %t0\"; - else - return \"not %T0\"; -}" - [(set_attr "type" "arith") - (set_attr "length" "4") - (set_attr "cc" "clobber")]) - -(define_insn "one_cmplsi2" - [(set (match_operand:SI 0 "register_operand" "=r") - (not:SI (match_operand:SI 1 "general_operand" "0")))] - "" - "* -{ - if (TARGET_H8300) - return \"not %w0\;not %x0\;not %y0\;not %z0\"; - else - return \"not %S0\"; -}" - [(set_attr "type" "arith") -;; ??? length is wrong for 300h - (set_attr "length" "8") - (set_attr "cc" "clobber")]) - -;; ---------------------------------------------------------------------- -;; JUMP INSTRUCTIONS -;; ---------------------------------------------------------------------- - -;; Conditional jump instructions - -(define_expand "ble" - [(set (pc) - (if_then_else (le (cc0) - (const_int 0)) - (label_ref (match_operand 0 "" "")) - (pc)))] - "" - "") - -(define_expand "bleu" - [(set (pc) - (if_then_else (leu (cc0) - (const_int 0)) - (label_ref (match_operand 0 "" "")) - (pc)))] - "" - "") - -(define_expand "bge" - [(set (pc) - (if_then_else (ge (cc0) - (const_int 0)) - (label_ref (match_operand 0 "" "")) - (pc)))] - "" - "") - -(define_expand "bgeu" - [(set (pc) - (if_then_else (geu (cc0) - (const_int 0)) - (label_ref (match_operand 0 "" "")) - (pc)))] - "" - "") - -(define_expand "blt" - [(set (pc) - (if_then_else (lt (cc0) - (const_int 0)) - (label_ref (match_operand 0 "" "")) - (pc)))] - "" - "") - -(define_expand "bltu" - [(set (pc) - (if_then_else (ltu (cc0) - (const_int 0)) - (label_ref (match_operand 0 "" "")) - (pc)))] - "" - "") - -(define_expand "bgt" - [(set (pc) - (if_then_else (gt (cc0) - (const_int 0)) - (label_ref (match_operand 0 "" "")) - (pc)))] - "" - "") - -(define_expand "bgtu" - [(set (pc) - (if_then_else (gtu (cc0) - (const_int 0)) - (label_ref (match_operand 0 "" "")) - (pc)))] - "" - "") - -(define_expand "beq" - [(set (pc) - (if_then_else (eq (cc0) - (const_int 0)) - (label_ref (match_operand 0 "" "")) - (pc)))] - "" - "") - -(define_expand "bne" - [(set (pc) - (if_then_else (ne (cc0) - (const_int 0)) - (label_ref (match_operand 0 "" "")) - (pc)))] - "" - "") - -(define_insn "branch_true" - [(set (pc) - (if_then_else (match_operator 1 "comparison_operator" - [(cc0) (const_int 0)]) - (label_ref (match_operand 0 "" "")) - (pc)))] - "" - "* -{ - /* If we erroneously deleted a compare insn (which can happen if we need - CC bits set that aren't), emit the compare. */ - if (restore_compare_p (operands[1])) - return 0; - - if (get_attr_length (insn) == 2) - return \"b%j1 %l0\"; - else if (get_attr_length (insn) == 4) - return \"b%j1 %l0:16\"; - else - return \"b%k1 %L0\;jmp @%l0\;%L0:\"; -}" - [(set_attr "type" "branch") - (set_attr "cc" "none")]) - -(define_insn "branch_false" - [(set (pc) - (if_then_else (match_operator 1 "comparison_operator" - [(cc0) (const_int 0)]) - (pc) - (label_ref (match_operand 0 "" ""))))] - "" -;; ??? We don't take advantage of 16 bit relative jumps in the 300h. - "* -{ - /* If we erroneously deleted a compare insn (which can happen if we need - CC bits set that aren't), emit the compare. */ - if (restore_compare_p (operands[1])) - return 0; - - if (get_attr_length (insn) == 2) - return \"b%k1 %l0\"; - else if (get_attr_length (insn) == 4) - return \"b%k1 %l0:16\"; - else - return \"b%j1 %L0\;jmp @%l0\;%L0:\"; -}" - [(set_attr "type" "branch") - (set_attr "cc" "none")]) - -;; Unconditional and other jump instructions. - -(define_insn "jump" - [(set (pc) - (label_ref (match_operand 0 "" "")))] - "" - "* -{ - if (get_attr_length (insn) == 2) - return \"bra %l0\"; - else if (get_attr_length (insn) == 4) - return \"bra %l0:16\"; - else - return \"jmp @%l0\"; -}" - [(set_attr "type" "branch") - (set_attr "cc" "none")]) - -;; This is a define expand, because pointers may be either 16 or 32 bits. - -(define_expand "tablejump" - [(parallel [(set (pc) (match_operand 0 "register_operand" "r")) - (use (label_ref (match_operand 1 "" "")))])] - "" - "") - -(define_insn "tablejump_h8300" - [(set (pc) (match_operand:HI 0 "register_operand" "r")) - (use (label_ref (match_operand 1 "" "")))] - "TARGET_H8300" - "jmp @%0" - [(set_attr "type" "branch") - (set_attr "cc" "none") - (set_attr "length" "2")]) - -(define_insn "tablejump_h8300h" - [(set (pc) (match_operand:SI 0 "register_operand" "r")) - (use (label_ref (match_operand 1 "" "")))] - "TARGET_H8300H" - "jmp @%0" - [(set_attr "type" "branch") - (set_attr "cc" "none") - (set_attr "length" "2")]) - -;; This is a define expand, because pointers may be either 16 or 32 bits. - -(define_expand "indirect_jump" - [(set (pc) (match_operand 0 "jump_address_operand" "Vr"))] - "" - "") - -(define_insn "indirect_jump_h8300" - [(set (pc) (match_operand:HI 0 "jump_address_operand" "V,r"))] - "TARGET_H8300" - "@ - jmp @%0 - jmp @%0" - [(set_attr "type" "branch") - (set_attr "cc" "none") - (set_attr "length" "2")]) - -(define_insn "indirect_jump_h8300h" - [(set (pc) (match_operand:SI 0 "jump_address_operand" "V,r"))] - "TARGET_H8300H" - "@ - jmp @%0 - jmp @%0" - [(set_attr "type" "branch") - (set_attr "cc" "none") - (set_attr "length" "2")]) - -;; Call subroutine with no return value. - -;; ??? Even though we use HImode here, this works for the 300h. - -(define_insn "call" - [(call (match_operand:QI 0 "call_insn_operand" "or") - (match_operand:HI 1 "general_operand" "g"))] - "" - "jsr %0" - [(set_attr "type" "call") - (set_attr "cc" "clobber") - (set_attr "length" "4")]) - -;; Call subroutine, returning value in operand 0 -;; (which must be a hard register). - -;; ??? Even though we use HImode here, this works on the 300h. - -(define_insn "call_value" - [(set (match_operand 0 "" "=r") - (call (match_operand:QI 1 "call_insn_operand" "or") - (match_operand:HI 2 "general_operand" "g")))] - "" - "jsr %1" - [(set_attr "type" "call") - (set_attr "cc" "clobber") - (set_attr "length" "4")]) - -(define_insn "nop" - [(const_int 0)] - "" - "nop" - [(set_attr "type" "multi") - (set_attr "cc" "none") - (set_attr "length" "2")]) - -;; ---------------------------------------------------------------------- -;; EXTEND INSTRUCTIONS -;; ---------------------------------------------------------------------- - -(define_insn "zero_extendqihi2" - [(set (match_operand:HI 0 "register_operand" "=r,r") - (zero_extend:HI (match_operand:QI 1 "general_operand" "0,g")))] - "" - "* -{ - if (which_alternative==0) - return \"mov.b #0,%t0\"; - - if (TARGET_H8300) - return \"mov.b %X1,%s0\;mov.b #0,%t0\"; - else - { - /* ??? See how often this gets optimized. */ - if (REG_P (operands[1]) && (REGNO (operands[1]) == REGNO (operands[0]))) - return \"extu.w %T0\"; - else - return \"mov.b %X1,%s0\;extu.w %T0\"; - } -}" - [(set_attr "type" "multi") -;; ??? This length is wrong for one case. - (set_attr "length" "4") - (set_attr "cc" "clobber")]) - -(define_insn "zero_extendhisi2" - [(set (match_operand:SI 0 "register_operand" "=r") - (zero_extend:SI (match_operand:HI 1 "general_operand" "g")))] - "TARGET_H8300H" - "* -{ - /* ??? See how often this gets optimized. */ - if (REG_P (operands[1]) && (REGNO (operands[1]) == REGNO (operands[0]))) - return \"extu.l %S0\"; - else - return \"mov.w %T1,%T0\;extu.l %S0\"; -}" - [(set_attr "type" "multi") -;; ??? This length is wrong for one case. - (set_attr "length" "4") - (set_attr "cc" "clobber")]) - -(define_insn "extendqihi2" - [(set (match_operand:HI 0 "register_operand" "=r") - (sign_extend:HI (match_operand:QI 1 "general_operand" "g")))] - "" - "* -{ - if (TARGET_H8300) - { - /* ??? See how often this gets optimized. */ - if (REG_P (operands[1]) && (REGNO (operands[1]) == REGNO (operands[0]))) - return \"bld #7,%s0\;subx %t0,%t0\"; - else - return \"mov.b %X1,%s0\;bld #7,%s0\;subx %t0,%t0\"; - } - else - { - /* ??? See how often this gets optimized. */ - if (REG_P (operands[1]) && (REGNO (operands[1]) == REGNO (operands[0]))) - return \"exts.w %T0\"; - else - return \"mov.b %X1,%s0\;exts.w %T0\"; - } -}" - [(set_attr "type" "multi") -;; ??? Length is wrong in some cases. - (set_attr "length" "6") - (set_attr "cc" "clobber")]) - -(define_expand "extendhisi2" - [(set (match_operand:SI 0 "register_operand" "") - (sign_extend:SI (match_operand:HI 1 "general_operand" "")))] - "" - " -{ - if (TARGET_H8300) - emit_insn (gen_extendhisi2_h8300 (operands[0], operands[1])); - else - emit_insn (gen_extendhisi2_h8300h (operands[0], operands[1])); - DONE; -}") - -(define_expand "extendhisi2_h8300" - [(set (reg:HI 1) (match_operand:HI 1 "general_operand" "")) - (set (reg:SI 0) (sign_extend:SI (reg:HI 1))) - (set (match_operand:SI 0 "general_operand" "" ) (reg:SI 0))] - "TARGET_H8300" - "") - -(define_expand "extendhisi2_h8300h" - [(set (match_operand:SI 0 "register_operand" "") - (sign_extend:SI (match_operand:HI 1 "general_operand" "")))] - "TARGET_H8300H" - "") - -(define_insn "extendhisi2_h8300_internal" - [(set (match_operand:SI 0 "register_operand" "=r") - (sign_extend:SI (match_operand:HI 1 "register_operand" "0")))] - "TARGET_H8300" - "mov.w %T1,%f0\;bld #7,%x0\;subx %y0,%y0\;subx %z0,%z0" - [(set_attr "length" "10") - (set_attr "cc" "clobber")]) - -(define_insn "extendhisi2_h8300h_internal" - [(set (match_operand:SI 0 "register_operand" "=r") - (sign_extend:SI (match_operand:HI 1 "general_operand" "g")))] - "TARGET_H8300H" - "* -{ - /* ??? See how often this gets optimized. */ - if (REG_P (operands[1]) && (REGNO (operands[1]) == REGNO (operands[0]))) - return \"exts.l %S0\"; - else - return \"mov.w %T1,%T0\;exts.l %S0\"; -}" - [(set_attr "length" "10") - (set_attr "cc" "clobber")]) - -;; ---------------------------------------------------------------------- -;; SHIFTS -;; ---------------------------------------------------------------------- -;; -;; We make some attempt to provide real efficient shifting. One example is -;; doing an 8 bit shift of a 16 bit value by moving a byte reg into the other -;; reg and moving 0 into the former reg. -;; -;; We also try to achieve this in a uniform way. IE: We don't try to achieve -;; this in both rtl and at insn emit time. Ideally, we'd use rtl as that would -;; give the optimizer more cracks at the code. However, we wish to do things -;; like optimizing shifting the sign bit to bit 0 by rotating the other way. -;; There is rtl to handle this (rotate + and), but the h8/300 doesn't handle -;; 16 bit rotates. Also, if we emit complicated rtl, combine may not be able -;; to detect cases it can optimize. -;; -;; For these and other fuzzy reasons, I've decided to go the less pretty but -;; easier "do it at insn emit time" route. - -;; QI BIT SHIFTS - -(define_expand "ashlqi3" - [(set (match_operand:QI 0 "register_operand" "") - (ashift:QI (match_operand:QI 1 "register_operand" "") - (match_operand:QI 2 "nonmemory_operand" "")))] - "" - "if (expand_a_shift (QImode, ASHIFT, operands)) DONE;else FAIL;") - -(define_expand "ashrqi3" - [(set (match_operand:QI 0 "register_operand" "") - (ashiftrt:QI (match_operand:QI 1 "register_operand" "") - (match_operand:QI 2 "nonmemory_operand" "")))] - "" - "if (expand_a_shift (QImode, ASHIFTRT, operands)) DONE;else FAIL;") - -(define_expand "lshrqi3" - [(set (match_operand:QI 0 "register_operand" "") - (lshiftrt:QI (match_operand:QI 1 "register_operand" "") - (match_operand:QI 2 "nonmemory_operand" "")))] - "" - "if (expand_a_shift (QImode, LSHIFTRT, operands)) DONE;else FAIL;") - -;; WARNING: The constraints on the scratch register say one is not needed -;; for constant shifts of 1,2,3,4. Emit_a_shift() must know this. - -(define_insn "shiftbyn_QI" - [(set (match_operand:QI 0 "register_operand" "=r,r") - (match_operator:QI 3 "nshift_operator" - [ (match_operand:QI 1 "register_operand" "0,0") - (match_operand:QI 2 "nonmemory_operand" "IKM,rn")])) - (clobber (match_scratch:QI 4 "=X,&r"))] - "" - "* return emit_a_shift (insn, operands);" - [(set_attr "type" "arith") - (set_attr "length" "20") -;; ??? We'd like to indicate that cc is set here, and it is for simple shifts. -;; However, for cases that loop or are done in pieces, cc does not contain -;; what we want. Emit_a_shift is free to tweak cc_status as desired. - (set_attr "cc" "clobber")]) - -;; HI BIT SHIFTS - -(define_expand "ashlhi3" - [(set (match_operand:HI 0 "register_operand" "") - (ashift:HI (match_operand:HI 1 "nonmemory_operand" "") - (match_operand:QI 2 "nonmemory_operand" "")))] - "" - "if (expand_a_shift (HImode, ASHIFT, operands)) DONE;else FAIL;") - -(define_expand "lshrhi3" - [(set (match_operand:HI 0 "register_operand" "") - (lshiftrt:HI (match_operand:HI 1 "general_operand_src" "") - (match_operand:QI 2 "nonmemory_operand" "")))] - "" - "if (expand_a_shift (HImode, LSHIFTRT, operands)) DONE;else FAIL;") - -(define_expand "ashrhi3" - [(set (match_operand:HI 0 "register_operand" "") - (ashiftrt:HI (match_operand:HI 1 "register_operand" "") - (match_operand:QI 2 "nonmemory_operand" "")))] - "" - "if (expand_a_shift (HImode, ASHIFTRT, operands)) DONE;else FAIL;") - -;; WARNING: The constraints on the scratch register say one is not needed -;; for constant shifts of 1,2,3,4. Emit_a_shift() must know this. - -(define_insn "shiftbyn_HI" - [(set (match_operand:HI 0 "register_operand" "=r,r") - (match_operator:HI 3 "nshift_operator" - [ (match_operand:HI 1 "register_operand" "0,0") - (match_operand:QI 2 "nonmemory_operand" "IKM,rn")])) - (clobber (match_scratch:QI 4 "=X,&r"))] - "" - "* return emit_a_shift (insn, operands);" - [(set_attr "type" "arith") - (set_attr "length" "20") -;; ??? We'd like to indicate that cc is set here, and it is for simple shifts. -;; However, for cases that loop or are done in pieces, cc does not contain -;; what we want. Emit_a_shift is free to tweak cc_status as desired. - (set_attr "cc" "clobber")]) - -;; SI BIT SHIFTS - -(define_expand "ashlsi3" - [(set (match_operand:SI 0 "register_operand" "") - (ashift:SI - (match_operand:SI 1 "general_operand_src" "") - (match_operand:QI 2 "nonmemory_operand" "")))] - "" - "if (expand_a_shift (SImode, ASHIFT, operands)) DONE;else FAIL;") - -(define_expand "lshrsi3" - [(set (match_operand:SI 0 "register_operand" "") - (lshiftrt:SI - (match_operand:SI 1 "general_operand_src" "") - (match_operand:QI 2 "nonmemory_operand" "")))] - "" - "if (expand_a_shift (SImode, LSHIFTRT, operands)) DONE;else FAIL;") - -(define_expand "ashrsi3" - [(set (match_operand:SI 0 "register_operand" "") - (ashiftrt:SI - (match_operand:SI 1 "general_operand_src" "") - (match_operand:QI 2 "nonmemory_operand" "")))] - "" - "if (expand_a_shift (SImode, ASHIFTRT, operands)) DONE;else FAIL;") - -;; WARNING: The constraints on the scratch register say one is not needed -;; for constant shifts of 1,2. Emit_a_shift() must know this. - -(define_insn "shiftbyn_SI" - [(set (match_operand:SI 0 "register_operand" "=r,r") - (match_operator:SI 3 "nshift_operator" - [ (match_operand:SI 1 "register_operand" "0,0") - (match_operand:QI 2 "nonmemory_operand" "IK,rn")])) - (clobber (match_scratch:QI 4 "=X,&r"))] - "" - "* return emit_a_shift (insn, operands);" - [(set_attr "type" "arith") - (set_attr "length" "20") -;; ??? We'd like to indicate that cc is set here, and it is for simple shifts. -;; However, for cases that loop or are done in pieces, cc does not contain -;; what we want. Emit_a_shift is free to tweak cc_status as desired. - (set_attr "cc" "clobber")]) - -;; ----------------------------------------------------------------- -;; BIT FIELDS -;; ----------------------------------------------------------------- -;; The H8/300 has given 1/8th of its opcode space to bitfield -;; instructions so let's use them as well as we can. - -;; BCC and BCS patterns. - -(define_insn "bcs_qiqi" - [(set (pc) - (if_then_else - (match_operator 1 "eq_operator" - [(zero_extract:QI (match_operand:QI 2 "bit_operand" "Ur") - (const_int 1) - (match_operand:HI 3 "immediate_operand" "i")) - (const_int 0)]) - (label_ref (match_operand 0 "" "")) - (pc)))] - "" - "* -{ - output_asm_insn(\"bld %Z3,%Y2\", operands); - if (get_attr_length (insn) == 2) - return \"b%d1 %l0\"; - else if (get_attr_length (insn) == 4) - return \"b%d1 %l0:16\"; - else - return \"b%g1 %L0\;jmp @%l0\;%L0:\"; -}" - [(set_attr "type" "branch") - (set_attr "cc" "clobber")]) - -(define_insn "bcs_hihi" - [(set (pc) - (if_then_else - (match_operator 1 "eq_operator" - [(zero_extract:HI (match_operand:HI 2 "bit_operand" "Ur") - (const_int 1) - (match_operand:HI 3 "immediate_operand" "i")) - (const_int 0)]) - (label_ref (match_operand 0 "" "")) - (pc)))] - "" - "* -{ - output_asm_insn(\"bld %Z3,%Y2\", operands); - if (get_attr_length (insn) == 2) - return \"%d1 %l0\"; - else if (get_attr_length (insn) == 4) - return \"%d1 %l0:16\"; - else - return \"%g1 %L0\;jmp @%l0\;%L0:\"; -}" - [(set_attr "type" "branch") - (set_attr "cc" "clobber")]) - -(define_insn "bcs_hiqi" - [(set (pc) - (if_then_else - (match_operator 1 "eq_operator" - [(zero_extract:HI (match_operand:QI 2 "bit_operand" "Ur") - (const_int 1) - (match_operand:HI 3 "immediate_operand" "i")) - (const_int 0)]) - (label_ref (match_operand 0 "" "")) - (pc)))] - "" - "* -{ - output_asm_insn(\"bld %Z3,%Y2\", operands); - if (get_attr_length (insn) == 2) - return \"%d1 %l0\"; - else if (get_attr_length (insn) == 4) - return \"%d1 %l0:16\"; - else - return \"%g1 %L0\;jmp @%l0\;%L0:\"; -}" - [(set_attr "type" "branch") - (set_attr "cc" "clobber")]) - -;; BLD and BST patterns - -(define_insn "extract_1" - [(set (match_operand:HI 0 "register_operand" "=&r") - (zero_extract:HI (match_operand:QI 1 "bit_operand" "Ur") - (const_int 1) - (match_operand:HI 2 "immediate_operand" "i")))] - "" - "sub.w %0,%0\;bld %Z2,%Y1\;bst #0,%X0") - -(define_insn "extract_1_hi" - [(set (match_operand:HI 0 "register_operand" "=&r") - (zero_extract:HI (match_operand:HI 1 "bit_operand" "Ur") - (const_int 1) - (match_operand:HI 2 "immediate_operand" "i")))] - "" - "sub.w %0,%0\;bld %Z2,%Y1\;bst #0,%X0") - -(define_insn "insert_1" - [(set (zero_extract:HI (match_operand:QI 0 "bit_operand" "+Ur") - (const_int 1) - (match_operand:HI 1 "immediate_operand" "i")) - (zero_extract:HI (match_operand:QI 2 "bit_operand" "Ur") - (const_int 1) - (const_int 0)))] - "" - "bld #0,%X2\;bst %Z1,%Y0 ; i1") - -;; This is how combine canonicalizes this pattern. This is perhaps a bug -;; in combine.c, but there is no problem with writing it this way so we do. -(define_insn "extract_insert_1" - [(set (zero_extract:QI (match_operand:QI 0 "bit_operand" "+Ur") - (const_int 1) - (match_operand:HI 1 "immediate_operand" "i")) - (lshiftrt:QI (match_operand:QI 2 "bit_operand" "Ur") - (match_operand:HI 3 "immediate_operand" "i")))] - "" - "bld %Z3,%Y2\;bst %Z1,%Y0; ei1") - -;; BAND, BOR, and BXOR patterns - -(define_insn "bitlogical_1" - [(set (match_operand:HI 0 "bit_operand" "=Ur") - (match_operator:HI 4 "bit_operator" - [(zero_extract:HI (match_operand:QI 1 "bit_operand" "Ur") - (const_int 1) - (match_operand:HI 2 "immediate_operand" "i")) - (match_operand:HI 3 "bit_operand" "0")]))] - "" - "bld %Z2,%Y1\;%b4 #0,%X0\;bst #0,%X0; bl1") - -(define_insn "bitlogical_1_hi" - [(set (match_operand:HI 0 "bit_operand" "=Ur") - (match_operator:HI 4 "bit_operator" - [(zero_extract:HI (match_operand:HI 1 "bit_operand" "Ur") - (const_int 1) - (match_operand:HI 2 "immediate_operand" "i")) - (match_operand:HI 3 "bit_operand" "0")]))] - "" - "bld %Z2,%Y1\;%b4 #0,%X0\;bst #0,%X0; bl2") - -(define_insn "bitlogical_2" - [(set (match_operand:HI 0 "bit_operand" "=Ur") - (match_operator:HI 5 "bit_operator" - [(zero_extract:HI (match_operand:QI 1 "bit_operand" "Ur") - (const_int 1) - (match_operand:HI 2 "immediate_operand" "i")) - (zero_extract:HI (match_operand:QI 3 "bit_operand" "Ur") - (const_int 1) - (match_operand:HI 4 "immediate_operand" "i"))]))] - "" - "bld %Z2,%Y1\;%b5 %Z4,%Y3\;bst #0,%X0; bl3") - -(define_insn "bitlogical_2_hi" - [(set (match_operand:HI 0 "bit_operand" "=Ur") - (match_operator:HI 5 "bit_operator" - [(zero_extract:HI (match_operand:HI 1 "bit_operand" "Ur") - (const_int 1) - (match_operand:HI 2 "immediate_operand" "i")) - (zero_extract:HI (match_operand:HI 3 "bit_operand" "Ur") - (const_int 1) - (match_operand:HI 4 "immediate_operand" "i"))]))] - "" - "bld %Z2,%Y1\;%b5 %Z4,%Y3\;bst #0,%X0; bl3") - -;; This is how combine canonicalizes this pattern. This is perhaps a bug -;; in combine.c, but there is no problem with writing it this way so we do. -(define_insn "bitlogical_3" - [(set (zero_extract:QI (match_operand:QI 0 "bit_operand" "+Ur") - (const_int 1) - (match_operand:HI 1 "immediate_operand" "i")) - (match_operator:QI 6 "bit_operator" - [(lshiftrt:QI (match_operand:QI 2 "bit_operand" "Ur") - (match_operand:HI 3 "immediate_operand" "i")) - (lshiftrt:QI (match_operand:QI 4 "bit_operand" "Ur") - (match_operand:HI 5 "immediate_operand" "i"))]))] - "" - "bld %Z3,%Y2\;%b6 %Z5,%Y4\;bst %Z1,%Y0; bl5") - -;; This is how combine canonicalizes this pattern. This is perhaps a bug -;; in combine.c, but there is no problem with writing it this way so we do. -(define_insn "bitnot_1" - [(set (zero_extract:QI (match_operand:QI 0 "bit_operand" "=Ur") - (const_int 1) - (match_operand:HI 1 "immediate_operand" "i")) - (lshiftrt:QI (xor:QI (match_operand:QI 2 "bit_operand" "0") - (match_operand:HI 3 "immediate_operand" "i")) - (match_operand:HI 4 "immediate_operand" "1")))] - "GET_CODE (operands[3]) == CONST_INT && GET_CODE (operands[1]) == CONST_INT - && exact_log2 (INTVAL (operands[3])) == INTVAL (operands[1])" - "bnot %Z1,%Y0") - -;; ??? Implement BIAND, BIOR, BIXOR - -;; ??? Implement BILD, BIST - -;; ??? Apparently general_operand for the 1st and 2nd operands is useful, -;; but I don't know why. --Jim - -(define_expand "insv" - [(set (zero_extract:HI (match_operand:QI 0 "bit_operand" "Ur") - (match_operand:HI 1 "general_operand" "g") - (match_operand:HI 2 "general_operand" "g")) - (zero_extract:HI (match_operand:QI 3 "bit_operand" "Ur") - (const_int 1) - (const_int 0)))] -;; ??? This should have word mode which is SImode for the h8/300h. - "TARGET_H8300" - " -{ - if (INTVAL (operands[1]) != 1) - FAIL; - - /* ??? HACK ??? - This INSV pattern is wrong. It should use HImode for operand 3. - Also, the zero_extract around operand 3 is superfluous and should be - deleted. Fixing this is more work than we care to do for the moment, - because it means most of the above patterns would need to be rewritten, - and we also need more combine.c patches to make this work. - - So, for now, we work around this bug by simply not accepting any bitfield - inserts that have a position greater than fits in QImode. */ - - if (GET_CODE (operands[2]) != CONST_INT || INTVAL (operands[2]) >= 8) - FAIL; - - /* The bit_operand predicate accepts any memory during RTL generation, but - only 'U' memory afterwards, so if this is a MEM operand, we must force - it to be valid for 'U' by reloading the address. */ - - if (GET_CODE (operands[0]) == MEM && ! EXTRA_CONSTRAINT (operands[0], 'U')) - { - rtx mem; - mem = gen_rtx (MEM, GET_MODE (operands[0]), - copy_to_mode_reg (Pmode, XEXP (operands[0], 0))); - RTX_UNCHANGING_P (mem) = RTX_UNCHANGING_P (operands[0]); - MEM_IN_STRUCT_P (mem) = MEM_IN_STRUCT_P (operands[0]); - MEM_VOLATILE_P (mem) = MEM_VOLATILE_P (operands[0]); - operands[0] = mem; - } - - /* Likewise for operands[3]. */ - - if (GET_CODE (operands[3]) == MEM && ! EXTRA_CONSTRAINT (operands[3], 'U')) - { - rtx mem; - mem = gen_rtx (MEM, GET_MODE (operands[3]), - copy_to_mode_reg (Pmode, XEXP (operands[3], 0))); - RTX_UNCHANGING_P (mem) = RTX_UNCHANGING_P (operands[3]); - MEM_IN_STRUCT_P (mem) = MEM_IN_STRUCT_P (operands[3]); - MEM_VOLATILE_P (mem) = MEM_VOLATILE_P (operands[3]); - operands[3] = mem; - } -}") - -;; ??? Apparently general_operand for the 2nd and 3rd operands is useful, -;; but I don't know why. --Jim - -(define_expand "extzv" - [(set (match_operand:HI 0 "register_operand" "") - (zero_extract:HI (match_operand:QI 1 "bit_operand" "") - (match_operand:HI 2 "general_operand" "g") - (match_operand:HI 3 "general_operand" "g")))] -;; ??? This should have word mode which is SImode for the h8/300h. - "TARGET_H8300" - " -{ - if (INTVAL (operands[2]) != 1) - FAIL; - - /* The bit_operand predicate accepts any memory during RTL generation, but - only 'U' memory afterwards, so if this is a MEM operand, we must force - it to be valid for 'U' by reloading the address. */ - - if (GET_CODE (operands[1]) == MEM && ! EXTRA_CONSTRAINT (operands[1], 'U')) - { - rtx mem; - mem = gen_rtx (MEM, GET_MODE (operands[1]), - copy_to_mode_reg (Pmode, XEXP (operands[1], 0))); - RTX_UNCHANGING_P (mem) = RTX_UNCHANGING_P (operands[1]); - MEM_IN_STRUCT_P (mem) = MEM_IN_STRUCT_P (operands[1]); - MEM_VOLATILE_P (mem) = MEM_VOLATILE_P (operands[1]); - operands[1] = mem; - } -}") - -;; ----------------------------------------------------------------- -;; STACK POINTER MANIPULATIONS -;; ----------------------------------------------------------------- - -;; This pattern is needed because there is no way on the H8/300 -;; to add a 16 bit immediate value to the stack pointer in one -;; instruction, which could leave an invalid instruction if interrupted -;; half way through. Here we add to the stack pointer from a -;; register. - -(define_insn "stack_pointer_manip" - [(set (match_operand:HI 0 "register_operand" "=&ra") - (plus:HI (match_operand:HI 1 "general_operand_src" "g") - (match_operand:HI 2 "register_operand" "ra")))] - "TARGET_H8300" - "mov.w %T1,%T0\;add.w %T2,%T0" - [(set_attr "type" "arith") - (set_attr "length" "6") - (set_attr "cc" "set_zn_c0")]) - - -;; ------------------------------------------- -;; BLK moves -;; ------------------------------------------- - -(define_expand "movstrhi" - [(parallel [(set (mem:BLK (match_operand:BLK 0 "general_operand" "")) - (mem:BLK (match_operand:BLK 1 "general_operand" ""))) - (use (match_operand:HI 2 "general_operand" "")) - (use (match_operand:HI 3 "immediate_operand" "")) - (clobber (match_dup 3)) - ])] - "" - " -{ - rtx src_ptr = copy_to_mode_reg (Pmode, XEXP(operands[1], 0)); - rtx dst_ptr = copy_to_mode_reg (Pmode, XEXP(operands[0], 0)); - - int max = GET_CODE (operands[2]) == CONST_INT - ? MIN (INTVAL (operands[2]), INTVAL (operands[3])) : 1; - enum machine_mode mode = max >= 2 ? HImode : QImode; - rtx tmpreg = gen_reg_rtx (mode); - rtx increment = mode == QImode ? const1_rtx : const2_rtx; - rtx length = operands[2]; - rtx label = gen_label_rtx (); - rtx end_src_ptr = gen_reg_rtx (Pmode); - -/* emit_move_insn (length, gen_rtx(MINUS, HImode, length, increment));*/ - FAIL; - if (Pmode == HImode) - emit_insn (gen_addhi3 (end_src_ptr, src_ptr, length)); - else - emit_insn (gen_addsi3 (end_src_ptr, src_ptr, length)); - - emit_label (label); - emit_move_insn (tmpreg, gen_rtx (MEM, mode, src_ptr)); - emit_move_insn (gen_rtx (MEM, mode, dst_ptr), tmpreg); - emit_insn (gen_rtx (SET, VOIDmode, src_ptr, - gen_rtx (PLUS, Pmode, src_ptr, increment))); - emit_insn (gen_rtx (SET, VOIDmode, dst_ptr, - gen_rtx (PLUS, Pmode, dst_ptr, increment))); - - emit_insn (gen_rtx (SET, VOIDmode, cc0_rtx, - gen_rtx (COMPARE, Pmode, src_ptr, end_src_ptr))); - emit_jump_insn (gen_bne (label)); - - DONE; -}") - -;; ---------------------------------------------- -;; Peepholes go at the end. -;; ---------------------------------------------- - -;; Notice when two byte moves in a row could be a word move. - -(define_peephole - [(set (match_operand:QI 0 "register_operand" "=r") - (mem:QI (plus:HI (match_operand:HI 1 "register_operand" "ra") - (match_operand:HI 2 "immediate_operand" "n")))) - (set (match_operand:QI 3 "register_operand" "=r") - (mem:QI (plus:HI (match_dup 1) - (match_operand:HI 4 "immediate_operand" "n"))))] - "(INTVAL(operands[2]) == INTVAL(operands[4])+1) && REGNO(operands[0]) +1 == REGNO(operands[3])" - "mov.w @(%u4,%T1),%T0" - [(set_attr "length" "6") - (set_attr "cc" "set")]) - -(define_peephole - [(set (mem:QI (plus:HI (match_operand:HI 1 "register_operand" "ra") - (match_operand:HI 2 "immediate_operand" "n"))) - (match_operand:QI 0 "register_operand" "r")) - (set (mem:QI (plus:HI (match_dup 1) - (match_operand:HI 4 "immediate_operand" "n"))) - (match_operand:QI 3 "register_operand" "r"))] - "(INTVAL(operands[2]) == INTVAL(operands[4])+1) && REGNO(operands[0]) +1 == REGNO(operands[3])" - "mov.w %T0,@(%u4,%T1)" - [(set_attr "length" "6") - (set_attr "cc" "set")]) - -;; Notice a move which could be post incremented. - -(define_peephole - [(set (match_operand:QI 0 "register_operand" "") - (mem:QI (match_operand:HI 1 "register_operand" ""))) - (set (match_dup 1) (plus:HI (match_dup 1) (const_int 1)))] - "REGNO(operands[1]) != REGNO(operands[0])" - "mov.b @%T1+,%X0" - [(set_attr "length" "2") - (set_attr "cc" "set")]) - -(define_peephole - [(set (match_operand:HI 0 "register_operand" "") - (mem:HI (match_operand:HI 1 "register_operand" ""))) - (set (match_dup 1) (plus:HI (match_dup 1) (const_int 2)))] - "REGNO(operands[1]) != REGNO(operands[0])" - "mov.w @%T1+,%T0" - [(set_attr "length" "2") - (set_attr "cc" "set")]) - -;; Notice a move which could be predecremented. - -(define_peephole - [(set (match_operand:HI 1 "register_operand" "") - (plus:HI (match_dup 1) (const_int -1))) - (set (mem:QI (match_dup 1)) - (match_operand:QI 0 "register_operand" ""))] - "REGNO(operands[1]) != REGNO(operands[0])" - "mov.b %X0,@-%T1" - [(set_attr "length" "2") - (set_attr "cc" "set")]) - -(define_peephole - [(set (match_operand:HI 1 "register_operand" "") - (plus:HI (match_dup 1) (const_int -1))) - (set (mem:HI (match_dup 1)) - (match_operand:HI 0 "register_operand" ""))] - "REGNO(operands[1]) != REGNO(operands[0])" - "mov.w %T0,@-%T1" - [(set_attr "length" "2") - (set_attr "cc" "set")]) - -;(define_insn "" -; [(set (match_operand:HI 0 "register_operand" "=r") -; (MEM:HI (match_operand:HI 1 "register_operand" "r"))) -; (set (match_operand:HI 3 "register_operand" "=r") -; (zero_extract:HI (match_dup 0) -; (const_int 1) -; (match_operand:HI 2 "general_operand" "g"))) -; (set (MEM:HI (match_dup 1) (match_dup 3)))] -; "" -; "bld #0,%3l\;bst %Z2,%0%Y1" -; [(set_attr "type" "multi") -; (set_attr "length" "4") -; (set_attr "cc" "clobber")]) - -(define_insn "fancybset1" - [(set (match_operand:QI 0 "bit_operand" "=Ur") - (ior:QI (subreg:QI - (ashift:HI (const_int 1) - (subreg:QI (match_operand:HI 1 "register_operand" "ri") 0)) 0) - (match_dup 0)))] - "" - "bset %X1,%X0") - -(define_insn "fancybset" - [(set (match_operand:QI 0 "bit_operand" "=Ur") - (ior:QI (subreg:QI - (ashift:HI (const_int 1) - (match_operand:HI 1 "nonmemory_operand" "ri") ) 0) - (match_operand:QI 2 "general_operand" "Ur")))] - "" - "mov.b %X2,%X0\;bset %X1,%X0") - -(define_insn "fancybclr4" - [(set (match_operand:QI 0 "general_operand" "=Ur,Ur") - (and:QI - (subreg:QI - (rotate:HI (const_int -2) - (match_operand:HI 2 "nonmemory_operand" "ri,ri") ) 0) - (match_operand:QI 1 "general_operand" "0,Ur"))) - (clobber (match_scratch:HI 3 "=X,&r"))] - "" - "@ - bclr %X2,%X0; l1 - mov.b %X1,%X3\;mov.b %3,%0\;bclr %X2,%X0; l3") - -(define_insn "fancybclr5" - [(set (match_operand:QI 0 "general_operand" "=Ur,Ur") - (and:QI - (subreg:QI - (rotate:HI (const_int -2) - (match_operand:QI 2 "nonmemory_operand" "ri,ri")) 0) - (match_operand:QI 1 "general_operand" "0,Ur"))) - (clobber (match_scratch:HI 3 "=X,&r"))] - "" - "@ - bclr %X2,%X0; l1 - mov.b %X1,%X3\;mov.b %3,%0\;bclr %X2,%X0;l2") - -(define_insn "fancybclr2" - [(set (match_operand:QI 0 "general_operand" "=U,r") - (and:QI - (subreg:QI - (rotate:HI (const_int -2) - (match_operand:HI 2 "nonmemory_operand" "ri,ri") ) 0) - (match_operand:QI 1 "general_operand" "0,0")))] - "" - "bclr %X2,%X0") - -(define_insn "fancybclr3" - [(set (match_operand:QI 0 "general_operand" "=U,r") - (and:QI - (subreg:QI - (rotate:HI (const_int -2) - (match_operand:QI 2 "nonmemory_operand" "ri,ri")) 0) - (match_operand:QI 1 "general_operand" "0,0")))] - "" - "bclr %X2,%X0") - -(define_insn "fancybclr" - [(set (match_operand:QI 0 "general_operand" "=r") - (and:QI (not:QI (match_operand:QI 1 "general_operand" "0")) - (match_operand:QI 2 "general_operand" "r")))] - "" - "not %X0\;and %X2,%X0") - -(define_insn "fancybsetp3" - [(set (match_operand:QI 0 "bit_operand" "=Ur") - (ior:QI (subreg:QI (ashift:HI (const_int 1) - (match_operand:QI 1 "register_operand" "r")) 0) - (match_operand:QI 2 "bit_operand" "0")))] - "" - "bset %X1,%X0") - -(define_insn "fancybsetp2" - [(set (match_operand:QI 0 "general_operand" "=r,U") - (ior:QI (subreg:QI (ashift:HI (const_int 1) - (match_operand:QI 1 "register_operand" "r,r")) 0) - (match_operand:QI 2 "general_operand" "U,r")))] - "" - "mov.b %X2,%X0\;bset %X1,%X0") - -(define_insn "fancybnot" - [(set (match_operand:QI 0 "bit_operand" "=Ur") - (xor:QI (subreg:QI (ashift:HI (const_int 1) - (match_operand:QI 1 "register_operand" "r")) 0) - (match_operand:QI 2 "bit_operand" "0")))] - - "" - "bnot %X1,%X0") - -(define_insn "fancy_btst" - [(set (pc) - (if_then_else (eq (zero_extract:HI (zero_extend:HI (match_operand:QI 1 "general_operand" "Ur")) - (const_int 1) - (match_operand:HI 2 "nonmemory_operand" "rn")) - (const_int 0)) - (label_ref (match_operand 0 "" "")) - (pc)))] - "" - "* -{ - if (get_attr_length (insn) == 2) - return \"btst %X2,%X1\;beq %l0\"; - else if (get_attr_length (insn) == 4) - return \"btst %X2,%X1\;beq %l0:16\"; - else - return \"btst %X2,%X1\;bne %L1\;jmp @%l0\;%L1:\"; -}" - [(set_attr "type" "branch") - (set_attr "cc" "clobber")]) - -(define_insn "fancy_btst1" - [(set (pc) - (if_then_else (ne (zero_extract:HI (zero_extend:HI (match_operand:QI 1 "general_operand" "Ur")) - (const_int 1) - (match_operand:HI 2 "nonmemory_operand" "rn")) - (const_int 0)) - (label_ref (match_operand 0 "" "")) - (pc)))] - "" - "* -{ - if (get_attr_length (insn) == 2) - return \"btst %X2,%X1\;bne %l0\"; - else if (get_attr_length (insn) == 4) - return \"btst %X2,%X1\;bne %l0:16\"; - else - return \"btst %X2,%X1\;beq %L1\;jmp @%l0\;%L1:\"; -}" - [(set_attr "type" "branch") - (set_attr "cc" "clobber")]) - -(define_insn "pxor" - [(set (zero_extract:QI (match_operand:QI 0 "bit_operand" "=r,U") - (const_int 1) - (match_operand 1 "immediate_operand" "n,n")) - (and:QI (not:QI (match_operand:QI 2 "bit_operand" "r,U")) - (const_int 1)))] - "" - "bld #0,%X2\;bist %1,%0" - [(set_attr "type" "arith") - (set_attr "length" "4") - (set_attr "cc" "clobber")]) |