diff options
Diffstat (limited to 'gcc/config/h8300/h8300.md')
-rwxr-xr-x | gcc/config/h8300/h8300.md | 2291 |
1 files changed, 0 insertions, 2291 deletions
diff --git a/gcc/config/h8300/h8300.md b/gcc/config/h8300/h8300.md deleted file mode 100755 index d892cad..0000000 --- a/gcc/config/h8300/h8300.md +++ /dev/null @@ -1,2291 +0,0 @@ -;; GCC machine description for Hitachi H8/300 -;; Copyright (C) 1992, 93, 94, 95, 96, 1997 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"))) - -;; Many logical operations should have "bit" variants if only one -;; bit is going to be operated on. - -;; (and (logical op) (const_int X)) -;; If const_int only specifies a few bits (like a single byte in a 4 byte -;; operation, then it's more efficient to only apply the and and logical_op -;; to the bits we care about. - -;; Some of the extend instructions accept a general_operand_src, which -;; allows all the normal memory addressing modes. The length computations -;; don't take this into account. The lengths in the MD file should be -;; "worst case" and then be adjusted to their correct values by -;; h8300_adjust_insn_length. - -;; On the h8300h, adds/subs operate on the 32bit "er" registers. Right -;; now GCC doesn't expose the "e" half to the compiler, so using add/subs -;; for addhi and subhi is safe. -;; Long term, we want to expose the "e" half to the compiler (gives us -;; 8 more 16bit registers). At that point addhi and subhi can't use adds/subs. - -;; There's currently no way to have a insv/extzv expander for the h8/300h -;; because word_mode is different for the h8/300 and h8/300h. - -;; Shifts/rotates by small constants should be handled by special -;; patterns so we get the length and cc status correct. - -;; Bitfield operations no longer accept memory operands. We need -;; to add variants which operate on memory back to the MD. - -;; ??? Implement remaining bit ops available on the h8300 - -(define_attr "type" "branch,arith" - (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)))] - (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_znv - insn sets z,n,v to usable values (like a tst insn); c is unknown. -;; set_zn - insn sets z,n to usable values; v,c are unknown. -;; compare - compare instruction -;; clobber - value of cc is unknown -(define_attr "cc" "none,none_0hit,set_znv,set_zn,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 "length") (if_then_else (eq_attr "cpu" "h8300") (const_int 2) (const_int 4))) - (set_attr "cc" "set_znv")]) - -(define_insn "" - [(set (match_operand:QI 0 "general_operand_dst" "=r,r,<,r,r,m") - (match_operand:QI 1 "general_operand_src" "I,r>,r,n,m,r"))] - "register_operand (operands[0],QImode) - || register_operand (operands[1], QImode)" - "@ - sub.b %X0,%X0 - mov.b %R1,%X0 - mov.b %X1,%R0 - mov.b %R1,%X0 - mov.b %R1,%X0 - mov.b %X1,%R0" - [(set_attr_alternative "length" - [(const_int 2) (const_int 2) (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))]) - (set_attr "cc" "set_zn,set_znv,set_znv,set_znv,set_znv,set_znv")]) - -(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,r")) - (match_operand:QI 1 "general_operand_src" "I,r,n,m"))] - "" - "@ - sub.b %X0,%X0 - mov.b %X1,%X0 - mov.b %R1,%X0 - mov.b %R1,%X0" - [(set_attr_alternative "length" - [(const_int 2) (const_int 2) (const_int 2) - (if_then_else (eq_attr "cpu" "h8300") (const_int 4) (const_int 8))]) - (set_attr "cc" "set_zn,set_znv,set_znv,set_znv")]) - -;; movhi - -;; ??? We use push.l on the h8300h to push a 16bit value?!? We have -;; 16bit push insns! -(define_insn "movhi_push" - [(set (match_operand:HI 0 "push_operand" "=<") - (match_operand:HI 1 "register_operand" "r"))] - "" - "* -{ - if (TARGET_H8300) - return \"push.w %T1\"; - else - return \"push.l %S1\"; -}" - [(set (attr "length") (if_then_else (eq_attr "cpu" "h8300") (const_int 2) (const_int 4))) - (set_attr "cc" "set_znv")]) - -(define_insn "" - [(set (match_operand:HI 0 "general_operand_dst" "=r,r,<,r,r,m") - (match_operand:HI 1 "general_operand_src" "I,r>,r,i,m,r"))] - "register_operand (operands[0],HImode) - || register_operand (operands[1], HImode)" - "@ - sub.w %T0,%T0 - mov.w %T1,%T0 - mov.w %T1,%T0 - mov.w %T1,%T0 - mov.w %T1,%T0 - mov.w %T1,%T0" - [(set_attr_alternative "length" - [(const_int 2) (const_int 2) (const_int 2) (const_int 4) - (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))]) - (set_attr "cc" "set_zn,set_znv,set_znv,set_znv,set_znv,set_znv")]) - -(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,r")) - (match_operand:HI 1 "general_operand_src" "I,r,i,m"))] - "" - "@ - sub.w %T0,%T0 - mov.w %T1,%T0 - mov.w %T1,%T0 - mov.w %T1,%T0" - [(set_attr_alternative "length" - [(const_int 2) (const_int 2) (const_int 4) - (if_then_else (eq_attr "cpu" "h8300") (const_int 4) (const_int 8))]) - (set_attr "cc" "set_zn,set_znv,set_znv,set_znv")]) - -;; 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 - { - /* 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 - { - /* 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,io,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 - { - /* See if either half is zero. If so, use sub.w to clear - that half. */ - if (GET_CODE (operands[1]) == CONST_INT) - { - if ((INTVAL (operands[1]) & 0xffff) == 0) - return \"mov.w %e1,%e0\;sub.w %f0,%f0\"; - if (((INTVAL (operands[1]) >> 16) & 0xffff) == 0) - return \"sub.w %e0,%e0\;mov.w %f1,%f0\"; - } - 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 "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,io,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 "length" "4,4,8,8,4,4") - (set_attr "cc" "clobber")]) - -(define_insn "movsi_h8300hs" - [(set (match_operand:SI 0 "general_operand_dst" "=r,r,r,m,<,r,*a,*a,r") - (match_operand:SI 1 "general_operand_src" "I,r,im,r,r,>,I,r,*a"))] - "(TARGET_H8300S || TARGET_H8300H) - && (register_operand (operands[0], SImode) - || register_operand (operands[1], SImode))" - "* -{ - if (which_alternative == 0) - return \"sub.l %S0,%S0\"; - if (which_alternative == 6) - return \"clrmac\"; - if (which_alternative == 7) - return \"clrmac\;ldmac %1,macl\"; - if (which_alternative == 8) - return \"stmac macl,%0\"; - if (GET_CODE (operands[1]) == CONST_INT) - { - int val = INTVAL (operands[1]); - - /* Look for constants which can be made by adding an 8-bit - number to zero in one of the two low bytes. */ - if (val == (val & 0xff)) - { - operands[1] = GEN_INT ((char)val & 0xff); - return \"sub.l %S0,%S0\;add.b %1,%w0\"; - } - - if (val == (val & 0xff00)) - { - operands[1] = GEN_INT ((char)(val >> 8) & 0xff); - return \"sub.l %S0,%S0\;add.b %1,%x0\"; - } - - /* Now look for small negative numbers. We can subtract them - from zero to get the desired constant. */ - if (val == -4 || val == -2 || val == -1) - { - operands[1] = GEN_INT (-INTVAL (operands[1])); - return \"sub.l %S0,%S0\;subs %1,%S0\"; - } - } - return \"mov.l %S1,%S0\"; -}" - [(set_attr "length" "2,2,10,10,4,4,2,6,4") - (set_attr "cc" "set_zn,set_znv,set_znv,set_znv,set_znv,set_znv,none_0hit,none_0hit,set_znv")]) - -(define_insn "movsf_h8300h" - [(set (match_operand:SF 0 "general_operand_dst" "=r,r,r,m,<,r") - (match_operand:SF 1 "general_operand_src" "I,r,im,r,r,>"))] - "(TARGET_H8300H || TARGET_H8300S) - && (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 "length" "2,2,10,10,4,4") - (set_attr "cc" "set_zn,set_znv,set_znv,set_znv,set_znv,set_znv")]) - -;; ---------------------------------------------------------------------- -;; TEST INSTRUCTIONS -;; ---------------------------------------------------------------------- - -(define_insn "" - [(set (cc0) (zero_extract:QI (match_operand:QI 0 "bit_memory_operand" "rU") - (const_int 1) - (match_operand:QI 1 "const_int_operand" "n")))] - "" - "btst %Z1,%R0" - [(set_attr "length" "2") - (set_attr "cc" "set_zn")]) - -(define_insn "" - [(set (cc0) (zero_extract:HI (match_operand:QI 0 "bit_memory_operand" "rU") - (const_int 1) - (match_operand:QI 1 "const_int_operand" "n")))] - "" - "btst %Z1,%Y0" - [(set_attr "length" "2") - (set_attr "cc" "set_zn")]) - -(define_insn "" - [(set (cc0) (zero_extract:SI (match_operand:QI 0 "bit_memory_operand" "rU") - (const_int 1) - (match_operand:QI 1 "const_int_operand" "n")))] - "" - "btst %Z1,%Y0" - [(set_attr "length" "2") - (set_attr "cc" "set_zn")]) - -(define_insn "" - [(set (cc0) (zero_extract:QI (match_operand:HI 0 "register_operand" "r") - (const_int 1) - (match_operand:HI 1 "const_int_operand" "n")))] - "" - "btst %Z1,%R0" - [(set_attr "length" "2") - (set_attr "cc" "set_zn")]) - -(define_insn "" - [(set (cc0) (zero_extract:HI (match_operand:HI 0 "register_operand" "r") - (const_int 1) - (match_operand:HI 1 "const_int_operand" "n")))] - "" - "btst %Z1,%Y0" - [(set_attr "length" "2") - (set_attr "cc" "set_zn")]) - -(define_insn "" - [(set (cc0) (zero_extract:SI (match_operand:HI 0 "register_operand" "r") - (const_int 1) - (match_operand:HI 1 "const_int_operand" "n")))] - "" - "btst %Z1,%Y0" - [(set_attr "length" "2") - (set_attr "cc" "set_zn")]) - -(define_insn "tstqi" - [(set (cc0) (match_operand:QI 0 "register_operand" "r"))] - "" - "mov.b %X0,%X0" - [(set_attr "length" "2") - (set_attr "cc" "set_znv")]) - -(define_insn "tsthi" - [(set (cc0) (match_operand:HI 0 "register_operand" "r"))] - "" - "mov.w %T0,%T0" - [(set_attr "length" "2") - (set_attr "cc" "set_znv")]) - -(define_insn "tstsi" - [(set (cc0) (match_operand:SI 0 "register_operand" "r"))] - "TARGET_H8300H || TARGET_H8300S" - "mov.l %S0,%S0" - [(set_attr "length" "2") - (set_attr "cc" "set_znv")]) - -(define_insn "cmpqi" - [(set (cc0) - (compare:QI (match_operand:QI 0 "register_operand" "r") - (match_operand:QI 1 "nonmemory_operand" "rn")))] - "" - "cmp.b %X1,%X0" - [(set_attr "length" "2") - (set_attr "cc" "compare")]) - -(define_expand "cmphi" - [(set (cc0) - (compare:HI (match_operand:HI 0 "register_operand" "") - (match_operand:HI 1 "nonmemory_operand" "")))] - "" - " -{ - /* Force operand1 into a register if we're compiling - for the h8/300. */ - if (GET_CODE (operands[1]) != REG && TARGET_H8300) - operands[1] = force_reg (HImode, operands[1]); -}") - -(define_insn "" - [(set (cc0) - (compare:HI (match_operand:HI 0 "register_operand" "r") - (match_operand:HI 1 "register_operand" "r")))] - "TARGET_H8300" - "cmp.w %T1,%T0" - [(set_attr "length" "2") - (set_attr "cc" "compare")]) - -(define_insn "" - [(set (cc0) - (compare:HI (match_operand:HI 0 "register_operand" "r,r") - (match_operand:HI 1 "nonmemory_operand" "r,n")))] - "TARGET_H8300H || TARGET_H8300S" - "cmp.w %T1,%T0" - [(set_attr "length" "2,4") - (set_attr "cc" "compare,compare")]) - -(define_insn "cmpsi" - [(set (cc0) - (compare:SI (match_operand:SI 0 "register_operand" "r,r") - (match_operand:SI 1 "nonmemory_operand" "r,i")))] - "TARGET_H8300H || TARGET_H8300S" - "cmp.l %S1,%S0" - [(set_attr "length" "2,6") - (set_attr "cc" "compare,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" "rn")))] - "" - "add.b %X2,%X0" - [(set_attr "length" "2") - (set_attr "cc" "set_zn")]) - -(define_expand "addhi3" - [(set (match_operand:HI 0 "register_operand" "") - (plus:HI (match_operand:HI 1 "register_operand" "") - (match_operand:HI 2 "nonmemory_operand" "")))] - "" - "") - -;; Specialized version using adds/subs. This must come before -;; the more general patterns below. -(define_insn "" - [(set (match_operand:HI 0 "register_operand" "=r") - (plus:HI (match_operand:HI 1 "register_operand" "%0") - (match_operand:HI 2 "adds_subs_operand" "n")))] - "" - "* return output_adds_subs (operands);" - [(set_attr "cc" "none_0hit") - (set (attr "length") - (if_then_else (ne (match_operand:HI 2 "one_insn_adds_subs_operand" "") - (const_int 0)) - (const_int 2) - (const_int 4)))]) - -(define_insn "" - [(set (match_operand:HI 0 "register_operand" "=&r,r,&r") - (plus:HI (match_operand:HI 1 "register_operand" "%0,0,g") - (match_operand:HI 2 "nonmemory_operand" "n,r,r")))] - "TARGET_H8300" - "@ - add.b %s2,%s0\;addx %t2,%t0 - add.w %T2,%T0 - mov.w %T1,%T0\;add.w %T2,%T0" - [(set_attr "length" "4,2,6") - (set_attr "cc" "clobber,set_zn,set_zn")]) - -(define_insn "" - [(set (match_operand:HI 0 "register_operand" "=r,r") - (plus:HI (match_operand:HI 1 "register_operand" "%0,0") - (match_operand:HI 2 "nonmemory_operand" "n,r")))] - "TARGET_H8300H || TARGET_H8300S" - "@ - add.w %T2,%T0 - add.w %T2,%T0" - [(set_attr "length" "4,2") - (set_attr "cc" "set_zn,set_zn")]) - -(define_expand "addsi3" - [(set (match_operand:SI 0 "register_operand" "") - (plus:SI (match_operand:SI 1 "register_operand" "") - (match_operand:SI 2 "nonmemory_operand" "")))] - "" - "") - -;; Specialized version using adds/subs. This must come before -;; the more general patterns below. -(define_insn "" - [(set (match_operand:SI 0 "register_operand" "=r") - (plus:SI (match_operand:SI 1 "register_operand" "%0") - (match_operand:SI 2 "adds_subs_operand" "n")))] - "TARGET_H8300H || TARGET_H8300S" - "* return output_adds_subs (operands);" - [(set_attr "cc" "none_0hit") - (set (attr "length") - (if_then_else (ne (match_operand:HI 2 "one_insn_adds_subs_operand" "") - (const_int 0)) - (const_int 2) - (const_int 4)))]) - -(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.w %f1,%f0\;mov.w %e1,%e0\;add.w %f2,%f0\;addx %y2,%y0\;addx %z2,%z0" - [(set_attr "length" "8,6,10") - (set_attr "cc" "clobber")]) - -(define_insn "addsi_h8300h" - [(set (match_operand:SI 0 "register_operand" "=r,r") - (plus:SI (match_operand:SI 1 "register_operand" "%0,0") - (match_operand:SI 2 "nonmemory_operand" "i,r")))] - "TARGET_H8300H || TARGET_H8300S" - "@ - add.l %S2,%S0 - add.l %S2,%S0" - [(set_attr "length" "6,2") - (set_attr "cc" "set_zn,set_zn")]) - -;; ---------------------------------------------------------------------- -;; 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,n")))] - "" - "@ - sub.b %X2,%X0 - add.b %G2,%X0" - [(set_attr "length" "2") - (set_attr "cc" "set_zn")]) - -(define_expand "subhi3" - [(set (match_operand:HI 0 "register_operand" "") - (minus:HI (match_operand:HI 1 "general_operand" "") - (match_operand:HI 2 "nonmemory_operand" "")))] - "" - "") - -;; Specialized version using adds/subs. This must come before -;; the more general patterns below. This may not be needed -;; due to instruction canonicalization. -(define_insn "" - [(set (match_operand:HI 0 "register_operand" "=r") - (minus:HI (match_operand:HI 1 "register_operand" "r") - (match_operand:HI 2 "adds_subs_operand" "n")))] - "" - "* -{ - operands[2] = GEN_INT (-INTVAL (operands[2])); - return output_adds_subs (operands); -}" - [(set_attr "cc" "none_0hit") - (set (attr "length") - (if_then_else (ne (match_operand:HI 2 "one_insn_adds_subs_operand" "") - (const_int 0)) - (const_int 2) - (const_int 4)))]) - -(define_insn "" - [(set (match_operand:HI 0 "register_operand" "=r,&r") - (minus:HI (match_operand:HI 1 "general_operand" "0,0") - (match_operand:HI 2 "nonmemory_operand" "r,n")))] - "TARGET_H8300" - "@ - sub.w %T2,%T0 - add.b %E2,%s0\;addx %F2,%t0" - [(set_attr "length" "2,4") - (set_attr "cc" "set_zn,clobber")]) - -(define_insn "" - [(set (match_operand:HI 0 "register_operand" "=r,&r") - (minus:HI (match_operand:HI 1 "general_operand" "0,0") - (match_operand:HI 2 "nonmemory_operand" "r,n")))] - "TARGET_H8300H || TARGET_H8300S" - "@ - sub.w %T2,%T0 - sub.w %T2,%T0" - [(set_attr "length" "2,4") - (set_attr "cc" "set_zn,set_zn")]) - -(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 "length" "6") - (set_attr "cc" "clobber")]) - -;; Specialized version using adds/subs. This must come before -;; the more general patterns below. This may not be needed -;; due to instruction canonicalization. -(define_insn "" - [(set (match_operand:SI 0 "register_operand" "=r") - (minus:SI (match_operand:SI 1 "general_operand" "0") - (match_operand:SI 2 "adds_subs_operand" "n")))] - "TARGET_H8300H || TARGET_H8300S" - "* -{ - operands[2] = GEN_INT (-INTVAL (operands[2])); - return output_adds_subs (operands); -}" - [(set_attr "cc" "none_0hit") - (set (attr "length") - (if_then_else (ne (match_operand:HI 2 "one_insn_adds_subs_operand" "") - (const_int 0)) - (const_int 2) - (const_int 4)))]) - -(define_insn "subsi3_h8300h" - [(set (match_operand:SI 0 "register_operand" "=r,r") - (minus:SI (match_operand:SI 1 "general_operand" "0,0") - (match_operand:SI 2 "nonmemory_operand" "r,i")))] - "TARGET_H8300H || TARGET_H8300S" - "@ - sub.l %S2,%S0 - sub.l %S2,%S0" - [(set_attr "length" "2,6") - (set_attr "cc" "set_zn,set_zn")]) - -;; ---------------------------------------------------------------------- -;; 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 || TARGET_H8300S" - "mulxs.b %X2,%T0" - [(set_attr "length" "4") - (set_attr "cc" "set_zn")]) - -(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 || TARGET_H8300S" - "mulxs.w %T2,%S0" - [(set_attr "length" "4") - (set_attr "cc" "set_zn")]) - -(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 "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 || TARGET_H8300S" - "mulxu.w %T2,%S0" - [(set_attr "length" "2") - (set_attr "cc" "none_0hit")]) - -;; This is a "bridge" instruction. Combine can't cram enough insns -;; together to crate a MAC instruction directly, but it can create -;; this instruction, which then allows combine to create the real -;; MAC insn. -;; -;; Unfortunately, if combine doesn't create a MAC instruction, this -;; insn must generate reasonably correct code. Egad. -(define_insn "" - [(set (match_operand:SI 0 "register_operand" "=a") - (mult:SI - (sign_extend:SI - (mem:HI (post_inc:SI (match_operand:SI 1 "register_operand" "r")))) - (sign_extend:SI - (mem:HI (post_inc:SI (match_operand:SI 2 "register_operand" "r"))))))] - "TARGET_H8300S" - "clrmac\;mac %2,%1" - [(set_attr "length" "6") - (set_attr "cc" "none_0hit")]) - -(define_insn "" - [(set (match_operand:SI 0 "register_operand" "=a") - (plus (mult:SI - (sign_extend:SI (mem:HI - (post_inc:SI (match_operand:SI 1 "register_operand" "r")))) - (sign_extend:SI (mem:HI - (post_inc:SI (match_operand:SI 2 "register_operand" "r"))))) - (match_operand:SI 3 "register_operand" "0")))] - "TARGET_H8300S" - "mac %2,%1" - [(set_attr "length" "4") - (set_attr "cc" "none_0hit")]) - -;; ---------------------------------------------------------------------- -;; DIVIDE INSTRUCTIONS -;; ---------------------------------------------------------------------- - -(define_insn "udivqi3" - [(set (match_operand:QI 0 "register_operand" "=r") - (truncate:QI - (udiv:HI - (match_operand:HI 1 "general_operand" "0") - (zero_extend:HI (match_operand:QI 2 "register_operand" "r")))))] - "" - "divxu %X2,%T0" - [(set_attr "length" "2") - (set_attr "cc" "clobber")]) - -;; ??? Will divxu always work here? - -(define_insn "divqi3" - [(set (match_operand:QI 0 "register_operand" "=r") - (truncate:QI - (div:HI - (match_operand:HI 1 "general_operand" "0") - (sign_extend:HI (match_operand:QI 2 "register_operand" "r")))))] - "" - "divxu %X2,%T0" - [(set_attr "length" "2") - (set_attr "cc" "clobber")]) - -(define_insn "udivhi3" - [(set (match_operand:HI 0 "register_operand" "=r") - (truncate:HI - (udiv:SI - (match_operand:SI 1 "general_operand" "0") - (zero_extend:SI (match_operand:HI 2 "register_operand" "r")))))] - "TARGET_H8300H || TARGET_H8300S" - "divxu.w %T2,%S0" - [(set_attr "length" "2") - (set_attr "cc" "clobber")]) - -(define_insn "divhi3" - [(set (match_operand:HI 0 "register_operand" "=r") - (truncate:HI - (div:SI - (match_operand:SI 1 "general_operand" "0") - (sign_extend:SI (match_operand:HI 2 "register_operand" "r")))))] - "TARGET_H8300H || TARGET_H8300S" - "divxs.w %T2,%S0" - [(set_attr "length" "4") - (set_attr "cc" "clobber")]) - -;; ---------------------------------------------------------------------- -;; MOD INSTRUCTIONS -;; ---------------------------------------------------------------------- - -(define_insn "umodqi3" - [(set (match_operand:QI 0 "register_operand" "=r") - (truncate:QI - (umod:HI - (match_operand:HI 1 "general_operand" "0") - (zero_extend:HI (match_operand:QI 2 "register_operand" "r")))))] - "" - "divxu %X2,%T0\;mov %t0,%s0" - [(set_attr "length" "4") - (set_attr "cc" "clobber")]) - -(define_insn "modqi3" - [(set (match_operand:QI 0 "register_operand" "=r") - (truncate:QI - (mod:HI - (match_operand:HI 1 "general_operand" "0") - (sign_extend:HI (match_operand:QI 2 "register_operand" "r")))))] - "TARGET_H8300H || TARGET_H8300S" - "divxs.b %X2,%T0\;mov %t0,%s0" - [(set_attr "length" "6") - (set_attr "cc" "clobber")]) - -(define_insn "umodhi3" - [(set (match_operand:HI 0 "register_operand" "=r") - (truncate:HI - (umod:SI - (match_operand:SI 1 "general_operand" "0") - (zero_extend:SI (match_operand:HI 2 "register_operand" "r")))))] - "TARGET_H8300H || TARGET_H8300S" - "divxu.w %T2,%S0\;mov %e0,%f0" - [(set_attr "length" "4") - (set_attr "cc" "clobber")]) - -(define_insn "modhi3" - [(set (match_operand:HI 0 "register_operand" "=r") - (truncate:HI - (mod:SI - (match_operand:SI 1 "general_operand" "0") - (sign_extend:SI (match_operand:HI 2 "register_operand" "r")))))] - "TARGET_H8300H || TARGET_H8300S" - "divxs.w %T2,%S0\;mov %e0,%f0" - [(set_attr "length" "6") - (set_attr "cc" "clobber")]) - -;; ---------------------------------------------------------------------- -;; AND INSTRUCTIONS -;; ---------------------------------------------------------------------- - -(define_insn "" - [(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,%R0" - [(set_attr "length" "2,4") - (set_attr "cc" "set_znv,none_0hit")]) - -(define_expand "andqi3" - [(set (match_operand:QI 0 "bit_operand" "") - (and:QI (match_operand:QI 1 "bit_operand" "") - (match_operand:QI 2 "nonmemory_operand" "")))] - "" - " -{ - if (fix_bit_operand (operands, 'O', AND)) - DONE; -}") - -(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 \"\"; - } - if (TARGET_H8300H || TARGET_H8300S) - return \"and.w %T2,%T0\"; - return \"and %s2,%s0\;and %t2,%t0;\"; -}" - [(set_attr "length" "4") - (set_attr "cc" "clobber")]) - -(define_insn "andsi3" - [(set (match_operand:SI 0 "register_operand" "=r") - (and:SI (match_operand:SI 1 "register_operand" "%0") - (match_operand:SI 2 "nonmemory_operand" "rn")))] - "" - "* -{ - if (GET_CODE (operands[2]) == CONST_INT) - { - int i = INTVAL (operands[2]); - int upper_cleared, lower_cleared; - - /* The h8300h can't do byte-wise operations on the - upper 16bits of 32bit registers. However, if - those bits aren't going to change, or they're - going to be zero'd out, then we can work on the - low-order bits. */ - if ((TARGET_H8300H || TARGET_H8300S) - && ((i & 0xffff0000) != 0xffff0000 - || (i & 0xffff0000) == 0x00000000)) - return \"and.l %S2,%S0\"; - - lower_cleared = 0; - if ((i & 0x0000ffff) == 0x00000000) - { - output_asm_insn (\"sub.w %f0,%f0\", operands); - lower_cleared = 1; - } - - upper_cleared = 0; - if ((i & 0xffff0000) == 0x00000000) - { - output_asm_insn (\"sub.w %e0,%e0\", operands); - upper_cleared = 1; - } - - if ((i & 0x000000ff) != 0x000000ff && !lower_cleared) - output_asm_insn (\"and %w2,%w0\", operands); - if ((i & 0x0000ff00) != 0x0000ff00 && !lower_cleared) - output_asm_insn (\"and %x2,%x0\", operands); - if ((i & 0x00ff0000) != 0x00ff0000 && !upper_cleared) - output_asm_insn (\"and %y2,%y0\", operands); - if ((i & 0xff000000) != 0xff000000 && !upper_cleared) - output_asm_insn (\"and %z2,%z0\", operands); - return \"\"; - } - if (TARGET_H8300H || TARGET_H8300S) - return \"and.l %S2,%S0\"; - return \"and %w2,%w0\;and %x2,%x0\;and %y2,%y0\;and %z2,%z0\;\"; -}" - [(set_attr "length" "8") - (set_attr "cc" "clobber")]) - - -;; ---------------------------------------------------------------------- -;; OR INSTRUCTIONS -;; ---------------------------------------------------------------------- - -(define_insn "" - [(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")))] - "register_operand (operands[0], QImode) || p_operand (operands[2], QImode)" - "@ - or %X2,%X0 - bset %V2,%R0" - [(set_attr "length" "2,4") - (set_attr "cc" "set_znv,none_0hit")]) - -(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; -}") - -(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 (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 \"\"; - } - if (TARGET_H8300H || TARGET_H8300S) - return \"or.w %T2,%T0\"; - return \"or %s2,%s0\;or %t2,%t0; %2 or2\"; -}" - [(set_attr "length" "2,4") - (set_attr "cc" "clobber,clobber")]) - -(define_insn "iorsi3" - [(set (match_operand:SI 0 "register_operand" "=r,r") - (ior:SI (match_operand:SI 1 "register_operand" "%0,0") - (match_operand:SI 2 "nonmemory_operand" "J,rn")))] - "" - "* -{ - if (GET_CODE (operands[2]) == CONST_INT) - { - int i = INTVAL (operands[2]); - - /* The h8300h can't do byte-wise operations on the - upper 16bits of 32bit registers. However, if - those bits aren't going to change, then we can - work on the low-order bits. */ - if ((TARGET_H8300H || TARGET_H8300S) - && (i & 0xffff0000) != 0x00000000) - return \"or.l %S2,%S0\"; - - 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 \"\"; - } - if (TARGET_H8300H || TARGET_H8300S) - return \"or.l %S2,%S0\"; - return \"or %w2,%w0\;or %x2,%x0\;or %y2,%y0\;or %z2,%z0\;\"; -}" - [(set_attr "length" "2,8") - (set_attr "cc" "clobber,clobber")]) - -;; ---------------------------------------------------------------------- -;; XOR INSTRUCTIONS -;; ---------------------------------------------------------------------- - -(define_insn "" - [(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,%R0" - [(set_attr "length" "2,4") - (set_attr "cc" "set_znv,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; -}") - -(define_insn "xorhi3" - [(set (match_operand:HI 0 "register_operand" "=r,r") - (xor:HI (match_operand:HI 1 "general_operand" "%0,0") - (match_operand:HI 2 "nonmemory_operand" "J,rn")))] - "" - "* -{ - if (GET_CODE (operands[2]) == CONST_INT) - { - int i = INTVAL (operands[2]); - - if ((i & 0x00ff) != 0) - output_asm_insn (\"xor %s2,%s0\", operands); - if ((i & 0xff00) != 0) - output_asm_insn (\"xor %t2,%t0\", operands); - return \"\"; - } - if (TARGET_H8300H || TARGET_H8300S) - return \"xor.w %T2,%T0\"; - return \"xor %s2,%s0\;xor %t2,%t0\"; -}" - [(set_attr "length" "2,4") - (set_attr "cc" "clobber,clobber")]) - -(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" "J,rn")))] - "" - "* -{ - if (GET_CODE (operands[2]) == CONST_INT) - { - int i = INTVAL (operands[2]); - - /* The h8300h can't do byte-wise operations on the - upper 16bits of 32bit registers. However, if - those bits aren't going to change, then we can - work on the low-order bits. */ - if ((TARGET_H8300H || TARGET_H8300S) - && (i & 0xffff0000) != 0x00000000) - return \"xor.l %S2,%S0\"; - - if ((i & 0x000000ff) != 0) - output_asm_insn (\"xor %w2,%w0\", operands); - if ((i & 0x0000ff00) != 0) - output_asm_insn (\"xor %x2,%x0\", operands); - if ((i & 0x00ff0000) != 0) - output_asm_insn (\"xor %y2,%y0\", operands); - if ((i & 0xff000000) != 0) - output_asm_insn (\"xor %z2,%z0\", operands); - return \"\"; - } - if (TARGET_H8300H || TARGET_H8300S) - return \"xor.l %S2,%S0\"; - return \"xor %w2,%w0\;xor %x2,%x0\;xor %y2,%y0\;xor %z2,%z0\;\"; -}" - [(set_attr "length" "2,8") - (set_attr "cc" "clobber,clobber")]) - -;; ---------------------------------------------------------------------- -;; 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 "length" "2") - (set_attr "cc" "set_zn")]) - -(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 || TARGET_H8300S" - "neg %T0" - [(set_attr "length" "2") - (set_attr "cc" "set_zn")]) - -(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 || TARGET_H8300S" - "neg %S0" - [(set_attr "length" "2") - (set_attr "cc" "set_zn")]) - -;; ---------------------------------------------------------------------- -;; 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 "length" "2") - (set_attr "cc" "set_znv")]) - -(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 "cc" "clobber") - (set (attr "length") - (if_then_else (eq (symbol_ref "TARGET_H8300H || TARGET_H8300S") - (const_int 0)) - (const_int 4) - (const_int 2)))]) - -(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 "cc" "clobber") - (set (attr "length") - (if_then_else (eq (symbol_ref "TARGET_H8300H || TARGET_H8300S") - (const_int 0)) - (const_int 8) - (const_int 2)))]) - - -;; ---------------------------------------------------------------------- -;; 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 ((cc_status.flags & CC_OVERFLOW_UNUSABLE) != 0 - && (GET_CODE (operands[1]) == GT - || GET_CODE (operands[1]) == GE - || GET_CODE (operands[1]) == LE - || GET_CODE (operands[1]) == LT)) - { - cc_status.flags &= ~CC_OVERFLOW_UNUSABLE; - 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 .Lh8BR%=\;jmp @%l0\\n.Lh8BR%=:\"; -}" - [(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 "" ""))))] - "" - "* -{ - if ((cc_status.flags & CC_OVERFLOW_UNUSABLE) != 0 - && (GET_CODE (operands[1]) == GT - || GET_CODE (operands[1]) == GE - || GET_CODE (operands[1]) == LE - || GET_CODE (operands[1]) == LT)) - { - cc_status.flags &= ~CC_OVERFLOW_UNUSABLE; - 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 .Lh8BR%=\;jmp @%l0\\n.Lh8BR%=:\"; -}" - [(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 "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 || TARGET_H8300S" - "jmp @%0" - [(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" ""))] - "" - "") - -(define_insn "indirect_jump_h8300" - [(set (pc) (match_operand:HI 0 "jump_address_operand" "Vr"))] - "TARGET_H8300" - "jmp @%0" - [(set_attr "cc" "none") - (set_attr "length" "2")]) - -(define_insn "indirect_jump_h8300h" - [(set (pc) (match_operand:SI 0 "jump_address_operand" "Vr"))] - "TARGET_H8300H || TARGET_H8300S" - "jmp @%0" - [(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"))] - "" - "* -{ - if (GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF - && SYMBOL_REF_FLAG (XEXP (operands[0], 0))) - return \"jsr\\t\@%0:8\"; - else - return \"jsr\\t%0\"; -}" - [(set_attr "cc" "clobber") - (set (attr "length") - (if_then_else (match_operand:QI 0 "small_call_insn_operand" "") - (const_int 4) - (const_int 8)))]) - -;; 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")))] - "" - "* -{ - if (GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF - && SYMBOL_REF_FLAG (XEXP (operands[1], 0))) - return \"jsr\\t\@%1:8\"; - else - return \"jsr\\t%1\"; -}" - [(set_attr "cc" "clobber") - (set (attr "length") - (if_then_else (match_operand:QI 0 "small_call_insn_operand" "") - (const_int 4) - (const_int 8)))]) - -(define_insn "nop" - [(const_int 0)] - "" - "nop" - [(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_src" "0,g>")))] - "" - "@ - mov.b #0,%t0 - mov.b %R1,%s0\;mov.b #0,%t0" - [(set_attr "length" "2,4") - (set_attr "cc" "clobber,clobber")]) - -;; The compiler can synthesize a 300H variant of this which is -;; just as efficient as one that we'd create -(define_insn "zero_extendqisi2" - [(set (match_operand:SI 0 "register_operand" "=r,r") - (zero_extend:SI (match_operand:QI 1 "general_operand_src" "0,g>")))] - "TARGET_H8300" - "@ - mov.b #0,%x0\;sub.w %e0,%e0 - mov.b %R1,%w0\;mov.b #0,%x0\;sub.w %e0,%e0" - [(set_attr "length" "4,6") - (set_attr "cc" "clobber,clobber")]) - -(define_expand "zero_extendhisi2" - [(set (match_operand:SI 0 "register_operand" "") - (zero_extend:SI (match_operand:HI 1 "general_operand" "")))] - "" - " -{ - if (TARGET_H8300 - && GET_CODE (operands[1]) != CONST_INT - && !optimize) - { - emit_insn (gen_zero_extendhisi2_h8300 (operands[0], operands[1])); - DONE; - } -}") - -;; This is used when not optimizing. It avoids severe code explosion -;; due to poor register allocation. -(define_expand "zero_extendhisi2_h8300" - [(set (reg:HI 1) (match_operand:HI 1 "general_operand" "")) - (set (reg:SI 0) (zero_extend:SI (reg:HI 1))) - (set (match_operand:SI 0 "general_operand" "" ) (reg:SI 0))] - "TARGET_H8300" - "") - -;; %e prints the high part of a CONST_INT, not the low part. Arggh. -(define_insn "" - [(set (match_operand:SI 0 "register_operand" "=r,r,r") - (zero_extend:SI (match_operand:HI 1 "general_operand_src" "0,i,g>")))] - "TARGET_H8300" - "@ - sub.w %e0,%e0 - mov.w %f1,%f0\;sub.w %e0,%e0 - mov.w %e1,%f0\;sub.w %e0,%e0" - [(set_attr "length" "2,4,4") - (set_attr "cc" "clobber,clobber,clobber")]) - -(define_insn "" - [(set (match_operand:SI 0 "register_operand" "=r,r") - (zero_extend:SI (match_operand:HI 1 "general_operand_src" "0,g>")))] - "TARGET_H8300H || TARGET_H8300S" - "@ - extu.l %S0 - mov.w %T1,%T0\;extu.l %S0" - [(set_attr "length" "2,4") - (set_attr "cc" "set_znv,set_znv")]) - -(define_expand "extendqihi2" - [(set (match_operand:HI 0 "register_operand" "") - (sign_extend:HI (match_operand:QI 1 "general_operand" "")))] - "" - "") - -(define_insn "" - [(set (match_operand:HI 0 "register_operand" "=r,r") - (sign_extend:HI (match_operand:QI 1 "general_operand_src" "0,g>")))] - "TARGET_H8300" - "@ - bld #7,%s0\;subx %t0,%t0 - mov.b %R1,%s0\;bld #7,%s0\;subx %t0,%t0" - [(set_attr "length" "4,6") - (set_attr "cc" "clobber,clobber")]) - -(define_insn "" - [(set (match_operand:HI 0 "register_operand" "=r,r") - (sign_extend:HI (match_operand:QI 1 "general_operand_src" "0,g>")))] - "TARGET_H8300H || TARGET_H8300S" - "@ - exts.w %T0 - mov.b %R1,%s0\;exts.w %T0" - [(set_attr "length" "2,4") - (set_attr "cc" "set_znv,set_znv")]) - -;; The compiler can synthesize a 300H variant of this which is -;; just as efficient as one that we'd create -(define_insn "extendqisi2" - [(set (match_operand:SI 0 "register_operand" "=r,r") - (sign_extend:SI (match_operand:QI 1 "general_operand_src" "0,g>")))] - "TARGET_H8300" - "@ - bld #7,%w0\;subx %x0,%x0\;subx %y0,%y0\;subx %z0,%z0 - mov.b %R1,%w0\;bld #7,%w0\;subx %x0,%x0\;subx %y0,%y0\;subx %z0,%z0" - [(set_attr "length" "8,10") - (set_attr "cc" "clobber,clobber")]) - -(define_expand "extendhisi2" - [(set (match_operand:SI 0 "register_operand" "") - (sign_extend:SI (match_operand:HI 1 "general_operand" "")))] - "" - " -{ - if (TARGET_H8300 - && GET_CODE (operands[1]) != CONST_INT - && !optimize) - { - emit_insn (gen_extendhisi2_h8300 (operands[0], operands[1])); - DONE; - } -}") - -;; This is used when not optimizing. It avoids severe code explosion -;; due to poor register allocation. -(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_insn "" - [(set (match_operand:SI 0 "register_operand" "=r,r") - (sign_extend:SI (match_operand:HI 1 "general_operand_src" "0,g>")))] - "TARGET_H8300" - "@ - bld #7,%x0\;subx %y0,%y0\;subx %z0,%z0 - mov.w %T1,%f0\;bld #7,%x0\;subx %y0,%y0\;subx %z0,%z0" - [(set_attr "length" "6,8") - (set_attr "cc" "clobber,clobber")]) - -(define_insn "" - [(set (match_operand:SI 0 "register_operand" "=r,r") - (sign_extend:SI (match_operand:HI 1 "general_operand_src" "0,g>")))] - "TARGET_H8300H || TARGET_H8300S" - "@ - exts.l %S0 - mov.w %T1,%T0\;exts.l %S0" - [(set_attr "length" "2,4") - (set_attr "cc" "set_znv,set_znv")]) - -;; ---------------------------------------------------------------------- -;; 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;") - -(define_insn "" - [(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" "KM,rn")])) - (clobber (match_scratch:QI 4 "=X,&r"))] - "" - "* return emit_a_shift (insn, operands);" - [(set_attr "length" "20") - (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" "") - (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;") - -(define_insn "" - [(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" "KM,rn")])) - (clobber (match_scratch:QI 4 "=X,&r"))] - "" - "* return emit_a_shift (insn, operands);" - [(set_attr "length" "20") - (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" "") - (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" "") - (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" "") - (match_operand:QI 2 "nonmemory_operand" "")))] - "" - "if (expand_a_shift (SImode, ASHIFTRT, operands)) DONE;else FAIL;") - -(define_insn "" - [(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" "K,rn")])) - (clobber (match_scratch:QI 4 "=X,&r"))] - "" - "* return emit_a_shift (insn, operands);" - [(set_attr "length" "20") - (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. - -;; You'll never believe all these patterns perform one basic action -- -;; load a bit from the source, optionally invert the bit, then store it -;; in the destination (which is known to be zero).. -;; -;; Combine obviously need some work to better identify this situation and -;; canonicalize the form better. - -;; -;; Normal loads with a 16bit destination. -;; -;; Yes, both cases are needed. -;; -(define_insn "" - [(set (match_operand:HI 0 "register_operand" "=&r") - (zero_extract:HI (match_operand:HI 1 "register_operand" "r") - (const_int 1) - (match_operand:HI 2 "immediate_operand" "n")))] - "" - "sub.w %0,%0\;bld %Z2,%Y1\;bst #0,%X0" - [(set_attr "cc" "clobber") - (set_attr "length" "6")]) - -(define_insn "" - [(set (match_operand:HI 0 "register_operand" "=&r") - (subreg:HI (zero_extract:SI - (match_operand:HI 1 "register_operand" "r") - (const_int 1) - (match_operand:HI 2 "immediate_operand" "n")) 1))] - "" - "sub.w %0,%0\;bld %Z2,%Y1\;bst #0,%X0" - [(set_attr "cc" "clobber") - (set_attr "length" "6")]) - -;; -;; Inverted loads with a 16bit destination. -;; -;; Yes, all four cases are needed. -;; - -(define_insn "" - [(set (match_operand:HI 0 "register_operand" "=&r") - (zero_extract:HI (xor:HI (match_operand:HI 1 "register_operand" "r") - (match_operand:HI 3 "p_operand" "P")) - (const_int 1) - (match_operand:HI 2 "const_int_operand" "n")))] - "(1 << INTVAL (operands[2])) == INTVAL (operands[3])" - "sub.w %0,%0\;bild %Z2,%Y1\;bst #0,%X0" - [(set_attr "cc" "clobber") - (set_attr "length" "8")]) - -(define_insn "" - [(set (match_operand:HI 0 "register_operand" "=&r") - (and:HI (not:HI - (lshiftrt:HI - (match_operand:HI 1 "bit_operand" "Ur") - (match_operand:HI 2 "const_int_operand" "n"))) - (const_int 1)))] - "" - "sub.w %0,%0\;bild %Z2,%Y1\;bst #0,%X0" - [(set_attr "cc" "clobber") - (set_attr "length" "8")]) - -(define_insn "" - [(set (match_operand:HI 0 "register_operand" "=&r") - (and:HI (not:HI - (subreg:HI - (lshiftrt:SI - (match_operand:SI 1 "register_operand" "Ur") - (match_operand:SI 2 "const_int_operand" "n")) 1)) - (const_int 1)))] - "INTVAL (operands[2]) < 16" - "sub.w %0,%0\;bild %Z2,%Y1\;bst #0,%X0" - [(set_attr "cc" "clobber") - (set_attr "length" "8")]) - -(define_insn "" - [(set (match_operand:HI 0 "register_operand" "=&r") - (and:HI (not:HI - (subreg:HI - (lshiftrt:SI - (match_operand:SI 1 "bit_operand" "Ur") - (match_operand:SI 2 "const_int_operand" "n")) 0)) - (const_int 1)))] - "(TARGET_H8300H || TARGET_H8300S) - && INTVAL (operands[2]) < 16" - "sub.w %0,%0\;bild %Z2,%Y1\;bst #0,%X0" - [(set_attr "cc" "clobber") - (set_attr "length" "8")]) - -;; -;; Normal loads with a 32bit destination. -;; -;; Yes, all three cases are needed. -;; -(define_insn "" - [(set (match_operand:SI 0 "register_operand" "=&r") - (zero_extract:SI (match_operand:HI 1 "register_operand" "r") - (const_int 1) - (match_operand:HI 2 "const_int_operand" "n")))] - "" - "* return output_simode_bld (0, 0, operands);" - [(set_attr "cc" "clobber") - (set (attr "length") - (if_then_else (eq (symbol_ref "TARGET_H8300H || TARGET_H8300S") - (const_int 0)) - (const_int 10) - (const_int 8)))]) - -(define_insn "" - [(set (match_operand:SI 0 "register_operand" "=&r") - (and:SI (zero_extend:SI - (lshiftrt:QI - (match_operand:QI 1 "bit_operand" "Ur") - (match_operand:QI 2 "const_int_operand" "n"))) - (const_int 1)))] - "" - "* return output_simode_bld (0, 0, operands);" - [(set_attr "cc" "clobber") - (set (attr "length") - (if_then_else (eq (symbol_ref "TARGET_H8300H || TARGET_H8300S") - (const_int 0)) - (const_int 10) - (const_int 8)))]) - -(define_insn "" - [(set (match_operand:SI 0 "register_operand" "=&r") - (and:SI (zero_extend:SI - (lshiftrt:HI - (match_operand:HI 1 "bit_operand" "Ur") - (match_operand:HI 2 "const_int_operand" "n"))) - (const_int 1)))] - "" - "* return output_simode_bld (0, 0, operands);" - [(set_attr "cc" "clobber") - (set (attr "length") - (if_then_else (eq (symbol_ref "TARGET_H8300H || TARGET_H8300S") - (const_int 0)) - (const_int 10) - (const_int 8)))]) - -;; -;; Inverted loads with a 32bit destination. -;; -;; Yes, all seven cases are needed. -;; -(define_insn "" - [(set (match_operand:SI 0 "register_operand" "=&r") - (and:SI (not:SI - (zero_extend:SI (match_operand:HI 1 "register_operand" "r"))) - (match_operand:SI 2 "p_operand" "P")))] - "" - "* return output_simode_bld (1, 1, operands);" - [(set_attr "cc" "clobber") - (set (attr "length") - (if_then_else (eq (symbol_ref "TARGET_H8300H || TARGET_H8300S") - (const_int 0)) - (const_int 10) - (const_int 8)))]) -(define_insn "" - [(set (match_operand:SI 0 "register_operand" "=&r") - (and:SI (not:SI - (zero_extend:SI - (lshiftrt:HI (match_operand:HI 1 "bit_operand" "Ur") - (match_operand:HI 2 "const_int_operand" "n")))) - (const_int 1)))] - "" - "* return output_simode_bld (1, 0, operands);" - [(set_attr "cc" "clobber") - (set (attr "length") - (if_then_else (eq (symbol_ref "TARGET_H8300H || TARGET_H8300S") - (const_int 0)) - (const_int 10) - (const_int 8)))]) - -(define_insn "" - [(set (match_operand:SI 0 "register_operand" "=&r") - (and:SI (not:SI - (zero_extend:SI (match_operand:QI 1 "register_operand" "r"))) - (match_operand:SI 2 "p_operand" "P")))] - "" - "* return output_simode_bld (1, 1, operands);" - [(set_attr "cc" "clobber") - (set (attr "length") - (if_then_else (eq (symbol_ref "TARGET_H8300H || TARGET_H8300S") - (const_int 0)) - (const_int 10) - (const_int 8)))]) -(define_insn "" - [(set (match_operand:SI 0 "register_operand" "=&r") - (and:SI (not:SI - (zero_extend:SI - (lshiftrt:QI (match_operand:QI 1 "bit_operand" "Ur") - (match_operand:QI 2 "const_int_operand" "n")))) - (const_int 1)))] - "" - "* return output_simode_bld (1, 0, operands);" - [(set_attr "cc" "clobber") - (set (attr "length") - (if_then_else (eq (symbol_ref "TARGET_H8300H || TARGET_H8300S") - (const_int 0)) - (const_int 10) - (const_int 8)))]) - -(define_insn "" - [(set (match_operand:SI 0 "register_operand" "=&r") - (and:SI (not:SI - (subreg:SI - (lshiftrt:HI - (match_operand:HI 1 "bit_operand" "Ur") - (match_operand:HI 2 "const_int_operand" "n")) 0)) - (const_int 1)))] - "1" - "* return output_simode_bld (1, 0, operands);" - [(set_attr "cc" "clobber") - (set (attr "length") - (if_then_else (eq (symbol_ref "TARGET_H8300H || TARGET_H8300S") - (const_int 0)) - (const_int 10) - (const_int 8)))]) - -(define_insn "" - [(set (match_operand:SI 0 "register_operand" "=&r") - (and:SI (not:SI - (subreg:SI - (lshiftrt:QI - (match_operand:QI 1 "bit_operand" "Ur") - (match_operand:QI 2 "const_int_operand" "n")) 0)) - (const_int 1)))] - "1" - "* return output_simode_bld (1, 0, operands);" - [(set_attr "cc" "clobber") - (set (attr "length") - (if_then_else (eq (symbol_ref "TARGET_H8300H || TARGET_H8300S") - (const_int 0)) - (const_int 10) - (const_int 8)))]) - -(define_insn "" - [(set (match_operand:SI 0 "register_operand" "=&r") - (zero_extract:SI (xor:HI (match_operand:HI 1 "register_operand" "r") - (match_operand:HI 3 "p_operand" "P")) - (const_int 1) - (match_operand:HI 2 "const_int_operand" "n")))] - "(1 << INTVAL (operands[2])) == INTVAL (operands[3])" - "sub.w %0,%0\;bild %Z2,%Y1\;bst #0,%X0" - [(set_attr "cc" "clobber") - (set_attr "length" "8")]) - -(define_expand "insv" - [(set (zero_extract:HI (match_operand:HI 0 "general_operand" "") - (match_operand:HI 1 "general_operand" "") - (match_operand:HI 2 "general_operand" "")) - (match_operand:HI 3 "general_operand" ""))] - "TARGET_H8300" - " -{ - /* We only have single bit bitfield instructions. */ - if (INTVAL (operands[1]) != 1) - FAIL; - - /* For now, we don't allow memory operands. */ - if (GET_CODE (operands[0]) == MEM - || GET_CODE (operands[3]) == MEM) - FAIL; -}") - -(define_insn "" - [(set (zero_extract:HI (match_operand:HI 0 "register_operand" "+r") - (const_int 1) - (match_operand:HI 1 "immediate_operand" "n")) - (match_operand:HI 2 "register_operand" "r"))] - "" - "bld #0,%R2\;bst %Z1,%Y0 ; i1" - [(set_attr "cc" "clobber") - (set_attr "length" "4")]) - -(define_expand "extzv" - [(set (match_operand:HI 0 "register_operand" "") - (zero_extract:HI (match_operand:HI 1 "bit_operand" "") - (match_operand:HI 2 "general_operand" "") - (match_operand:HI 3 "general_operand" "")))] - "TARGET_H8300" - " -{ - /* We only have single bit bitfield instructions. */ - if (INTVAL (operands[2]) != 1) - FAIL; - - /* For now, we don't allow memory operands. */ - if (GET_CODE (operands[1]) == MEM) - FAIL; -}") - -;; BAND, BOR, and BXOR patterns - -(define_insn "" - [(set (match_operand:HI 0 "bit_operand" "=Ur") - (match_operator:HI 4 "bit_operator" - [(zero_extract:HI (match_operand:HI 1 "register_operand" "r") - (const_int 1) - (match_operand:HI 2 "immediate_operand" "n")) - (match_operand:HI 3 "bit_operand" "0")]))] - "" - "bld %Z2,%Y1\;%b4 #0,%R0\;bst #0,%R0; bl1" - [(set_attr "cc" "clobber") - (set_attr "length" "6")]) - -(define_insn "" - [(set (match_operand:HI 0 "bit_operand" "=Ur") - (match_operator:HI 5 "bit_operator" - [(zero_extract:HI (match_operand:HI 1 "register_operand" "r") - (const_int 1) - (match_operand:HI 2 "immediate_operand" "n")) - (zero_extract:HI (match_operand:HI 3 "register_operand" "r") - (const_int 1) - (match_operand:HI 4 "immediate_operand" "n"))]))] - "" - "bld %Z2,%Y1\;%b5 %Z4,%Y3\;bst #0,%R0; bl3" - [(set_attr "cc" "clobber") - (set_attr "length" "6")]) - - -;; ---------------------------------------------- -;; Peepholes go at the end. -;; ---------------------------------------------- - -;; 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_znv")]) - -(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_znv")]) - -;; 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_znv")]) - -(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_znv")]) - |