;; GCC machine description for Renesas H8/300 ;; Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, ;; 2001, 2002, 2003, 2004 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 GCC.

;; GCC 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.

;; GCC 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 GCC; see the file COPYING. If not, write to ;; the Free Software Foundation, 59 Temple Place - Suite 330, ;; Boston, MA 02111-1307, USA.

;; We compute exact length on each instruction for most of the time. ;; In some case, most notably bit operations that may involve memory ;; operands, the lengths in this file are “worst case”.

;; On the H8/300H and H8S, 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 an 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

;; ---------------------------------------------------------------------- ;; CONSTANTS ;; ----------------------------------------------------------------------

(define_constants [(UNSPEC_INCDEC 0) (UNSPEC_MONITOR 1)])

(define_constants [(R0_REG 0) (SC_REG 3) (FP_REG 6) (SP_REG 7) (MAC_REG 8) (AP_REG 9) (RAP_REG 10)])

;; ---------------------------------------------------------------------- ;; ATTRIBUTES ;; ----------------------------------------------------------------------

(define_attr “cpu” “h8300,h8300h” (const (symbol_ref “cpu_type”)))

(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 (match_dup 0) (pc)) (const_int -126)) (le (minus (match_dup 0) (pc)) (const_int 126))) (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”))

;; Provide the maximum length of an assembly instruction in an asm ;; statement. The maximum length of 14 bytes is achieved on H8SX.

(define_asm_attributes [(set (attr “length”) (cond [(ne (symbol_ref “TARGET_H8300”) (const_int 0)) (const_int 4) (ne (symbol_ref “TARGET_H8300H”) (const_int 0)) (const_int 10) (ne (symbol_ref “TARGET_H8300S”) (const_int 0)) (const_int 10)] (const_int 14)))]) ;; ---------------------------------------------------------------------- ;; MOVE INSTRUCTIONS ;; ----------------------------------------------------------------------

;; movqi

(define_insn “pushqi1_h8300” [(parallel [(set (reg:HI SP_REG) (plus:HI (reg:HI SP_REG) (const_int -2))) (set (mem:QI (plus:HI (reg:HI SP_REG) (const_int -1))) (match_operand:QI 0 “register_operand” “r”))])] “TARGET_H8300 && operands[0] != stack_pointer_rtx” “mov.w\t%T0,@-r7” [(set_attr “length” “2”) (set_attr “cc” “clobber”)])

(define_insn “pushqi1_h8300hs” [(parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4))) (set (mem:QI (plus:SI (reg:SI SP_REG) (const_int -3))) (match_operand:QI 0 “register_operand” “r”))])] “(TARGET_H8300H || TARGET_H8300S) && operands[0] != stack_pointer_rtx” “mov.l\t%S0,@-er7” [(set_attr “length” “4”) (set_attr “cc” “clobber”)])

(define_insn “pushqi1_h8300hs_normal” [(parallel [(set (reg:HI SP_REG) (plus:HI (reg:HI SP_REG) (const_int -4))) (set (mem:QI (plus:HI (reg:HI SP_REG) (const_int -3))) (match_operand:QI 0 “register_operand” “r”))])] “(TARGET_H8300H || TARGET_H8300S) && operands[0] != stack_pointer_rtx” “mov.l\t%S0,@-er7” [(set_attr “length” “4”) (set_attr “cc” “clobber”)])

(define_expand “pushqi1” [(use (match_operand:QI 0 “register_operand” "“))] "" " { if (TARGET_H8300) emit_insn (gen_pushqi1_h8300 (operands[0])); else if (!TARGET_NORMAL_MODE) emit_insn (gen_pushqi1_h8300hs (operands[0])); else emit_insn (gen_pushqi1_h8300hs_normal (operands[0])); DONE; }”)

(define_insn “*movqi_h8300” [(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"))] “TARGET_H8300 && (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 “length” “2,2,2,2,4,4”) (set_attr “cc” “set_zn,set_znv,set_znv,set_znv,set_znv,set_znv”)])

(define_insn “*movqi_h8300hs” [(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"))] “(TARGET_H8300H || TARGET_H8300S) && (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 “length”) (symbol_ref “compute_mov_length (operands)”)) (set_attr “cc” “set_zn,set_znv,set_znv,clobber,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 “register_operand” “+r,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 %X1,%X0 mov.b %R1,%X0” [(set (attr “length”) (symbol_ref “compute_mov_length (operands)”)) (set_attr “cc” “set_zn,set_znv,set_znv,set_znv,set_znv”)])

;; movhi

(define_expand “pushhi1_h8300” [(set (mem:HI (pre_dec:HI (reg:HI SP_REG))) (match_operand:HI 0 “register_operand” ""))] “TARGET_H8300 && operands[0] != stack_pointer_rtx” "")

(define_insn “pushhi1_h8300hs” [(parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4))) (set (mem:HI (plus:SI (reg:SI SP_REG) (const_int -2))) (match_operand:HI 0 “register_operand” “r”))])] “(TARGET_H8300H || TARGET_H8300S) && operands[0] != stack_pointer_rtx” “mov.l\t%S0,@-er7” [(set_attr “length” “4”) (set_attr “cc” “clobber”)])

(define_insn “pushhi1_h8300hs_normal” [(parallel [(set (reg:HI SP_REG) (plus:HI (reg:HI SP_REG) (const_int -4))) (set (mem:HI (plus:HI (reg:HI SP_REG) (const_int -2))) (match_operand:HI 0 “register_operand” “r”))])] “(TARGET_H8300H || TARGET_H8300S) && operands[0] != stack_pointer_rtx” “mov.l\t%S0,@-er7” [(set_attr “length” “4”) (set_attr “cc” “clobber”)])

(define_expand “pushhi1” [(use (match_operand:HI 0 “register_operand” "“))] "" " { if (TARGET_H8300) emit_insn (gen_pushhi1_h8300 (operands[0])); else if (!TARGET_NORMAL_MODE) emit_insn (gen_pushhi1_h8300hs (operands[0])); else emit_insn (gen_pushhi1_h8300hs_normal (operands[0])); DONE; }”)

(define_insn “*movhi_h8300” [(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”))] “TARGET_H8300 && (register_operand (operands[0], HImode) || register_operand (operands[1], HImode)) && !(GET_CODE (operands[0]) == MEM && GET_CODE (XEXP (operands[0], 0)) == PRE_DEC && GET_CODE (XEXP (XEXP (operands[0], 0), 0)) == REG && GET_CODE (operands[1]) == REG && REGNO (XEXP (XEXP (operands[0], 0), 0)) == REGNO (operands[1]))” “@ 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 “length”) (symbol_ref “compute_mov_length (operands)”)) (set_attr “cc” “set_zn,set_znv,set_znv,set_znv,set_znv,set_znv”)])

(define_insn “*movhi_h8300hs” [(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”))] “(TARGET_H8300H || TARGET_H8300S) && (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 “length”) (symbol_ref “compute_mov_length (operands)”)) (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 “register_operand” “+r,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 mov.w %T1,%T0” [(set (attr “length”) (symbol_ref “compute_mov_length (operands)”)) (set_attr “cc” “set_zn,set_znv,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 (h8300_expand_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 (h8300_expand_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))” “* { unsigned 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 { if (GET_CODE (operands[1]) == CONST_INT) { / If either half is zero, use sub.w to clear that half. / 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"; / If the upper half and the lower half are the same, copy one half to the other. */ if ((INTVAL (operands[1]) & 0xffff) == ((INTVAL (operands[1]) >> 16) & 0xffff)) return "mov.w\t%e1,%e0;mov.w\t%e0,%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"; default: abort (); } }” [(set (attr “length”) (symbol_ref “compute_mov_length (operands)”)) (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” “G,r,io,r,r,>”))] “TARGET_H8300 && (register_operand (operands[0], SFmode) || register_operand (operands[1], SFmode))” "* { /* Copy of the movsi stuff. / unsigned 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 / Move the first word first. */ 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\";
default:
  abort ();
}

}" [(set (attr “length”) (symbol_ref “compute_mov_length (operands)”)) (set_attr “cc” “clobber”)])

(define_insn “*movsi_h8300hs” [(set (match_operand:SI 0 “general_operand_dst” “=r,r,r,<,r,r,m,*a,*a,r”) (match_operand:SI 1 “general_operand_src” “I,r,i,r,>,m,r,I,r,*a”))] “(TARGET_H8300S || TARGET_H8300H) && (register_operand (operands[0], SImode) || register_operand (operands[1], SImode)) && !(GET_CODE (operands[0]) == MEM && GET_CODE (XEXP (operands[0], 0)) == PRE_DEC && GET_CODE (XEXP (XEXP (operands[0], 0), 0)) == REG && GET_CODE (operands[1]) == REG && REGNO (XEXP (XEXP (operands[0], 0), 0)) == REGNO (operands[1]))” "* { switch (which_alternative) { case 0: return "sub.l %S0,%S0"; case 7: return "clrmac"; case 8: return "clrmac;ldmac %1,macl"; case 9: return "stmac macl,%0"; default: 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\\t%S0,%S0\;add.b\\t%1,%w0\";
    }

  if (val == (val & 0xff00))
    {
      operands[1] = GEN_INT ((char) (val >> 8) & 0xff);
      return \"sub.l\\t%S0,%S0\;add.b\\t%1,%x0\";
    }

  /* Look for constants that can be obtained by subs, inc, and
     dec to 0.  */
  switch (val & 0xffffffff)
    {
    case 0xffffffff:
      return \"sub.l\\t%S0,%S0\;subs\\t#1,%S0\";
    case 0xfffffffe:
      return \"sub.l\\t%S0,%S0\;subs\\t#2,%S0\";
    case 0xfffffffc:
      return \"sub.l\\t%S0,%S0\;subs\\t#4,%S0\";

    case 0x0000ffff:
      return \"sub.l\\t%S0,%S0\;dec.w\\t#1,%f0\";
    case 0x0000fffe:
      return \"sub.l\\t%S0,%S0\;dec.w\\t#2,%f0\";

    case 0xffff0000:
      return \"sub.l\\t%S0,%S0\;dec.w\\t#1,%e0\";
    case 0xfffe0000:
      return \"sub.l\\t%S0,%S0\;dec.w\\t#2,%e0\";

    case 0x00010000:
      return \"sub.l\\t%S0,%S0\;inc.w\\t#1,%e0\";
    case 0x00020000:
      return \"sub.l\\t%S0,%S0\;inc.w\\t#2,%e0\";
    }
}
}

return "mov.l %S1,%S0"; }" [(set (attr “length”) (symbol_ref “compute_mov_length (operands)”)) (set_attr “cc” “set_zn,set_znv,clobber,set_znv,set_znv,set_znv,set_znv,none_0hit,none_0hit,set_znv”)])

(define_insn “*movsf_h8300hs” [(set (match_operand:SF 0 “general_operand_dst” “=r,r,r,m,<,r”) (match_operand:SF 1 “general_operand_src” “G,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”) (symbol_ref “compute_mov_length (operands)”)) (set_attr “cc” “set_zn,set_znv,set_znv,set_znv,set_znv,set_znv”)]) ;; ---------------------------------------------------------------------- ;; TEST INSTRUCTIONS ;; ----------------------------------------------------------------------

(define_insn "" [(set (cc0) (zero_extract:HI (match_operand:QI 0 “bit_memory_operand” “r,U”) (const_int 1) (match_operand 1 “const_int_operand” “n,n”)))] “TARGET_H8300” “btst %Z1,%Y0” [(set_attr “length” “2,4”) (set_attr “cc” “set_zn,set_zn”)])

(define_insn "" [(set (cc0) (zero_extract:HI (match_operand:HI 0 “register_operand” “r”) (const_int 1) (match_operand 1 “const_int_operand” “n”)))] “TARGET_H8300” “btst %Z1,%Y0” [(set_attr “length” “2”) (set_attr “cc” “set_zn”)])

(define_insn_and_split “*tst_extzv_1_n” [(set (cc0) (zero_extract:SI (match_operand:QI 0 “general_operand_src” “r,U,mn>”) (const_int 1) (match_operand 1 “const_int_operand” “n,n,n”))) (clobber (match_scratch:QI 2 “=X,X,&r”))] “(TARGET_H8300H || TARGET_H8300S)” “@ btst\t%Z1,%Y0 btst\t%Z1,%Y0 #” “&& reload_completed && !EXTRA_CONSTRAINT (operands[0], ‘U’)” [(set (match_dup 2) (match_dup 0)) (parallel [(set (cc0) (zero_extract:SI (match_dup 2) (const_int 1) (match_dup 1))) (clobber (scratch:QI))])] "" [(set_attr “length” “2,8,10”) (set_attr “cc” “set_zn,set_zn,set_zn”)])

(define_insn "" [(set (cc0) (zero_extract:SI (match_operand:SI 0 “register_operand” “r”) (const_int 1) (match_operand 1 “const_int_operand” “n”)))] “(TARGET_H8300H || TARGET_H8300S) && INTVAL (operands[1]) <= 15” “btst %Z1,%Y0” [(set_attr “length” “2”) (set_attr “cc” “set_zn”)])

(define_insn_and_split “*tstsi_upper_bit” [(set (cc0) (zero_extract:SI (match_operand:SI 0 “register_operand” “r”) (const_int 1) (match_operand 1 “const_int_operand” “n”))) (clobber (match_scratch:SI 2 “=&r”))] “(TARGET_H8300H || TARGET_H8300S) && INTVAL (operands[1]) >= 16” “#” “&& reload_completed” [(set (match_dup 2) (ior:SI (and:SI (match_dup 2) (const_int -65536)) (lshiftrt:SI (match_dup 0) (const_int 16)))) (set (cc0) (zero_extract:SI (match_dup 2) (const_int 1) (match_dup 3)))] “operands[3] = GEN_INT (INTVAL (operands[1]) - 16);”)

(define_insn “*tstsi_variable_bit” [(set (cc0) (zero_extract:SI (match_operand:SI 0 “register_operand” “r”) (const_int 1) (and:SI (match_operand:SI 1 “register_operand” “r”) (const_int 7))))] “TARGET_H8300H || TARGET_H8300S” “btst %w1,%w0” [(set_attr “length” “2”) (set_attr “cc” “set_zn”)])

(define_insn_and_split “*tstsi_variable_bit_qi” [(set (cc0) (zero_extract:SI (zero_extend:SI (match_operand:QI 0 “general_operand_src” “r,U,mn>”)) (const_int 1) (and:SI (match_operand:SI 1 “register_operand” “r,r,r”) (const_int 7)))) (clobber (match_scratch:QI 2 “=X,X,&r”))] “(TARGET_H8300H || TARGET_H8300S)” “@ btst\t%w1,%X0 btst\t%w1,%X0 #” “&& reload_completed && !EXTRA_CONSTRAINT (operands[0], ‘U’)” [(set (match_dup 2) (match_dup 0)) (parallel [(set (cc0) (zero_extract:SI (zero_extend:SI (match_dup 2)) (const_int 1) (and:SI (match_dup 1) (const_int 7)))) (clobber (scratch:QI))])] "" [(set_attr “length” “2,8,10”) (set_attr “cc” “set_zn,set_zn,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 “*tsthi_upper” [(set (cc0) (and:HI (match_operand:HI 0 “register_operand” “r”) (const_int -256)))] "" “mov.b %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 “*tstsi_upper” [(set (cc0) (and:SI (match_operand:SI 0 “register_operand” “r”) (const_int -65536)))] "" “mov.w %e0,%e0” [(set_attr “length” “2”) (set_attr “cc” “set_znv”)])

(define_insn “cmpqi” [(set (cc0) (compare (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 (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 “*cmphi_h8300” [(set (cc0) (compare (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 “*cmphi_h8300hs” [(set (cc0) (compare (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 (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” "")))] "" "")

(define_insn “*addhi3_h8300” [(set (match_operand:HI 0 “register_operand” “=r,r,r,r,r”) (plus:HI (match_operand:HI 1 “register_operand” “%0,0,0,0,0”) (match_operand:HI 2 “nonmemory_operand” “L,N,J,n,r”)))] “TARGET_H8300” “@ adds %2,%T0 subs %G2,%T0 add.b %t2,%t0 add.b %s2,%s0;addx %t2,%t0 add.w %T2,%T0” [(set_attr “length” “2,2,2,4,2”) (set_attr “cc” “none_0hit,none_0hit,clobber,clobber,set_zn”)])

;; This splitter is very important to make the stack adjustment ;; interrupt-safe. The combination of add.b and addx is unsafe! ;; ;; We apply this split after the peephole2 pass so that we won't end ;; up creating too many adds/subs when a scratch register is ;; available, which is actually a common case because stack unrolling ;; tends to happen immediately after a function call.

(define_split [(set (match_operand:HI 0 “stack_pointer_operand” "") (plus:HI (match_dup 0) (match_operand 1 “const_int_gt_2_operand” "")))] “TARGET_H8300 && flow2_completed” [(const_int 0)] “split_adds_subs (HImode, operands); DONE;”)

(define_peephole2 [(match_scratch:HI 2 “r”) (set (match_operand:HI 0 “stack_pointer_operand” "") (plus:HI (match_dup 0) (match_operand:HI 1 “const_int_ge_8_operand” "")))] “TARGET_H8300” [(set (match_dup 2) (match_dup 1)) (set (match_dup 0) (plus:HI (match_dup 0) (match_dup 2)))] "")

(define_insn “*addhi3_h8300hs” [(set (match_operand:HI 0 “register_operand” “=r,r,r,r,r”) (plus:HI (match_operand:HI 1 “register_operand” “%0,0,0,0,0”) (match_operand:HI 2 “nonmemory_operand” “L,N,J,n,r”)))] “TARGET_H8300H || TARGET_H8300S” “@ adds %2,%S0 subs %G2,%S0 add.b %t2,%t0 add.w %T2,%T0 add.w %T2,%T0” [(set_attr “length” “2,2,2,4,2”) (set_attr “cc” “none_0hit,none_0hit,clobber,set_zn,set_zn”)])

(define_insn “*addhi3_incdec” [(set (match_operand:HI 0 “register_operand” “=r,r”) (unspec:HI [(match_operand:HI 1 “register_operand” “0,0”) (match_operand:HI 2 “incdec_operand” “M,O”)] UNSPEC_INCDEC))] “TARGET_H8300H || TARGET_H8300S” “@ inc.w %2,%T0 dec.w %G2,%T0” [(set_attr “length” “2,2”) (set_attr “cc” “set_zn,set_zn”)])

(define_split [(set (match_operand:HI 0 “register_operand” "") (plus:HI (match_dup 0) (match_operand:HI 1 “two_insn_adds_subs_operand” "")))] "" [(const_int 0)] “split_adds_subs (HImode, operands); DONE;”)

(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”) (plus:SI (match_operand:SI 1 “register_operand” “%0,0”) (match_operand:SI 2 “nonmemory_operand” “n,r”)))] “TARGET_H8300” “* return output_plussi (operands);” [(set (attr “length”) (symbol_ref “compute_plussi_length (operands)”)) (set (attr “cc”) (symbol_ref “compute_plussi_cc (operands)”))])

(define_insn “*addsi_h8300hs” [(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” “* return output_plussi (operands);” [(set (attr “length”) (symbol_ref “compute_plussi_length (operands)”)) (set (attr “cc”) (symbol_ref “compute_plussi_cc (operands)”))])

(define_insn “*addsi3_incdec” [(set (match_operand:SI 0 “register_operand” “=r,r”) (unspec:SI [(match_operand:SI 1 “register_operand” “0,0”) (match_operand:SI 2 “incdec_operand” “M,O”)] UNSPEC_INCDEC))] “TARGET_H8300H || TARGET_H8300S” “@ inc.l %2,%S0 dec.l %G2,%S0” [(set_attr “length” “2,2”) (set_attr “cc” “set_zn,set_zn”)])

(define_split [(set (match_operand:SI 0 “register_operand” "") (plus:SI (match_dup 0) (match_operand:SI 1 “two_insn_adds_subs_operand” "")))] “TARGET_H8300H || TARGET_H8300S” [(const_int 0)] “split_adds_subs (SImode, operands); DONE;”)

;; ---------------------------------------------------------------------- ;; SUBTRACT INSTRUCTIONS ;; ----------------------------------------------------------------------

(define_insn “subqi3” [(set (match_operand:QI 0 “register_operand” “=r”) (minus:QI (match_operand:QI 1 “register_operand” “0”) (match_operand:QI 2 “register_operand” “r”)))] "" “sub.b %X2,%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” "")))] "" "")

(define_insn “*subhi3_h8300” [(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 “*subhi3_h8300hs” [(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”)])

(define_insn “*subsi3_h8300hs” [(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 “register_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 “register_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 “register_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 “register_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_MAC” “clrmac;mac @%2+,@%1+” [(set_attr “length” “6”) (set_attr “cc” “none_0hit”)])

(define_insn "" [(set (match_operand:SI 0 “register_operand” “=a”) (plus:SI (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_MAC” “mac @%2+,@%1+” [(set_attr “length” “4”) (set_attr “cc” “none_0hit”)])

;; ---------------------------------------------------------------------- ;; DIVIDE/MOD INSTRUCTIONS ;; ----------------------------------------------------------------------

(define_insn “udivmodqi4” [(set (match_operand:QI 0 “register_operand” “=r”) (truncate:QI (udiv:HI (match_operand:HI 1 “register_operand” “0”) (zero_extend:HI (match_operand:QI 2 “register_operand” “r”))))) (set (match_operand:QI 3 “register_operand” “=r”) (truncate:QI (umod:HI (match_dup 1) (zero_extend:HI (match_dup 2)))))] "" “* { if (find_reg_note (insn, REG_UNUSED, operands[3])) return "divxu.b\t%X2,%T0"; else return "divxu.b\t%X2,%T0;mov.b\t%t0,%s3"; }” [(set_attr “length” “4”) (set_attr “cc” “clobber”)])

(define_insn “divmodqi4” [(set (match_operand:QI 0 “register_operand” “=r”) (truncate:QI (div:HI (match_operand:HI 1 “register_operand” “0”) (sign_extend:HI (match_operand:QI 2 “register_operand” “r”))))) (set (match_operand:QI 3 “register_operand” “=r”) (truncate:QI (mod:HI (match_dup 1) (sign_extend:HI (match_dup 2)))))] “TARGET_H8300H || TARGET_H8300S” “* { if (find_reg_note (insn, REG_UNUSED, operands[3])) return "divxs.b\t%X2,%T0"; else return "divxs.b\t%X2,%T0;mov.b\t%t0,%s3"; }” [(set_attr “length” “6”) (set_attr “cc” “clobber”)])

(define_insn “udivmodhi4” [(set (match_operand:HI 0 “register_operand” “=r”) (truncate:HI (udiv:SI (match_operand:SI 1 “register_operand” “0”) (zero_extend:SI (match_operand:HI 2 “register_operand” “r”))))) (set (match_operand:HI 3 “register_operand” “=r”) (truncate:HI (umod:SI (match_dup 1) (zero_extend:SI (match_dup 2)))))] “TARGET_H8300H || TARGET_H8300S” “* { if (find_reg_note (insn, REG_UNUSED, operands[3])) return "divxu.w\t%T2,%S0"; else return "divxu.w\t%T2,%S0;mov.w\t%e0,%f3"; }” [(set_attr “length” “4”) (set_attr “cc” “clobber”)])

(define_insn “divmodhi4” [(set (match_operand:HI 0 “register_operand” “=r”) (truncate:HI (div:SI (match_operand:SI 1 “register_operand” “0”) (sign_extend:SI (match_operand:HI 2 “register_operand” “r”))))) (set (match_operand:HI 3 “register_operand” “=r”) (truncate:HI (mod:SI (match_dup 1) (sign_extend:SI (match_dup 2)))))] “TARGET_H8300H || TARGET_H8300S” “* { if (find_reg_note (insn, REG_UNUSED, operands[3])) return "divxs.w\t%T2,%S0"; else return "divxs.w\t%T2,%S0;mov.w\t%e0,%f3"; }” [(set_attr “length” “6”) (set_attr “cc” “clobber”)]) ;; ---------------------------------------------------------------------- ;; AND INSTRUCTIONS ;; ----------------------------------------------------------------------

(define_insn “*andqi3_1” [(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,n”)))] “register_operand (operands[0], QImode) || single_zero_operand (operands[2], QImode)” “@ and %X2,%X0 bclr %W2,%R0” [(set_attr “length” “2,8”) (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, 0, AND)) DONE; }”)

(define_expand “andhi3” [(set (match_operand:HI 0 “register_operand” "") (and:HI (match_operand:HI 1 “register_operand” "") (match_operand:HI 2 “nonmemory_operand” "")))] "" "")

(define_insn “*andorqi3” [(set (match_operand:QI 0 “register_operand” “=r”) (ior:QI (and:QI (match_operand:QI 2 “register_operand” “r”) (match_operand:QI 3 “single_one_operand” “n”)) (match_operand:QI 1 “register_operand” “0”)))] "" “bld\t%V3,%X2;bor\t%V3,%X0;bst\t%V3,%X0” [(set_attr “length” “6”) (set_attr “cc” “clobber”)])

(define_insn “*andorhi3” [(set (match_operand:HI 0 “register_operand” “=r”) (ior:HI (and:HI (match_operand:HI 2 “register_operand” “r”) (match_operand:HI 3 “single_one_operand” “n”)) (match_operand:HI 1 “register_operand” “0”)))] "" “* { operands[3] = GEN_INT (INTVAL (operands[3]) & 0xffff); if (INTVAL (operands[3]) > 128) { operands[3] = GEN_INT (INTVAL (operands[3]) >> 8); return "bld\t%V3,%t2;bor\t%V3,%t0;bst\t%V3,%t0"; } return "bld\t%V3,%s2;bor\t%V3,%s0;bst\t%V3,%s0"; }” [(set_attr “length” “6”) (set_attr “cc” “clobber”)])

(define_insn “*andorsi3” [(set (match_operand:SI 0 “register_operand” “=r”) (ior:SI (and:SI (match_operand:SI 2 “register_operand” “r”) (match_operand:SI 3 “single_one_operand” “n”)) (match_operand:SI 1 “register_operand” “0”)))] “(INTVAL (operands[3]) & 0xffff) != 0” “* { operands[3] = GEN_INT (INTVAL (operands[3]) & 0xffff); if (INTVAL (operands[3]) > 128) { operands[3] = GEN_INT (INTVAL (operands[3]) >> 8); return "bld\t%V3,%x2;bor\t%V3,%x0;bst\t%V3,%x0"; } return "bld\t%V3,%w2;bor\t%V3,%w0;bst\t%V3,%w0"; }” [(set_attr “length” “6”) (set_attr “cc” “clobber”)])

(define_insn “*andorsi3_shift_8” [(set (match_operand:SI 0 “register_operand” “=r”) (ior:SI (and:SI (ashift:SI (match_operand:SI 2 “register_operand” “r”) (const_int 8)) (const_int 65280)) (match_operand:SI 1 “register_operand” “0”)))] "" “or.b\t%w2,%x0” [(set_attr “length” “2”) (set_attr “cc” “clobber”)])

(define_expand “andsi3” [(set (match_operand:SI 0 “register_operand” "") (and:SI (match_operand:SI 1 “register_operand” "") (match_operand:SI 2 “nonmemory_operand” "")))] "" "")

;; ---------------------------------------------------------------------- ;; OR INSTRUCTIONS ;; ----------------------------------------------------------------------

(define_insn “*iorqi3_1” [(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,n”)))] “register_operand (operands[0], QImode) || single_one_operand (operands[2], QImode)” “@ or\t%X2,%X0 bset\t%V2,%R0” [(set_attr “length” “2,8”) (set_attr “cc” “set_znv,none_0hit”)])

(define_expand “iorqi3” [(set (match_operand:QI 0 “bit_operand” "") (ior:QI (match_operand:QI 1 “bit_operand” "") (match_operand:QI 2 “nonmemory_operand” "“)))] "" " { if (fix_bit_operand (operands, 1, IOR)) DONE; }”)

(define_expand “iorhi3” [(set (match_operand:HI 0 “register_operand” "") (ior:HI (match_operand:HI 1 “register_operand” "") (match_operand:HI 2 “nonmemory_operand” "")))] "" "")

(define_expand “iorsi3” [(set (match_operand:SI 0 “register_operand” "") (ior:SI (match_operand:SI 1 “register_operand” "") (match_operand:SI 2 “nonmemory_operand” "")))] "" "")

;; ---------------------------------------------------------------------- ;; XOR INSTRUCTIONS ;; ----------------------------------------------------------------------

(define_insn “*xorqi3_1” [(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,n”)))] “register_operand (operands[0], QImode) || single_one_operand (operands[2], QImode)” “@ xor\t%X2,%X0 bnot\t%V2,%R0” [(set_attr “length” “2,8”) (set_attr “cc” “set_znv,none_0hit”)])

(define_expand “xorqi3” [(set (match_operand:QI 0 “bit_operand” "") (xor:QI (match_operand:QI 1 “bit_operand” "") (match_operand:QI 2 “nonmemory_operand” "“)))] "" " { if (fix_bit_operand (operands, 1, XOR)) DONE; }”)

(define_expand “xorhi3” [(set (match_operand:HI 0 “register_operand” "") (xor:HI (match_operand:HI 1 “register_operand” "") (match_operand:HI 2 “nonmemory_operand” "")))] "" "")

(define_expand “xorsi3” [(set (match_operand:SI 0 “register_operand” "") (xor:SI (match_operand:SI 1 “register_operand” "") (match_operand:SI 2 “nonmemory_operand” "")))] "" "")

;; ---------------------------------------------------------------------- ;; {AND,IOR,XOR}{HI3,SI3} PATTERNS ;; ----------------------------------------------------------------------

(define_insn “*logicalhi3” [(set (match_operand:HI 0 “register_operand” “=r”) (match_operator:HI 3 “bit_operator” [(match_operand:HI 1 “register_operand” “%0”) (match_operand:HI 2 “nonmemory_operand” “rn”)]))] "" “* return output_logical_op (HImode, operands);” [(set (attr “length”) (symbol_ref “compute_logical_op_length (HImode, operands)”)) (set (attr “cc”) (symbol_ref “compute_logical_op_cc (HImode, operands)”))])

(define_insn “*logicalsi3” [(set (match_operand:SI 0 “register_operand” “=r”) (match_operator:SI 3 “bit_operator” [(match_operand:SI 1 “register_operand” “%0”) (match_operand:SI 2 “nonmemory_operand” “rn”)]))] "" “* return output_logical_op (SImode, operands);” [(set (attr “length”) (symbol_ref “compute_logical_op_length (SImode, operands)”)) (set (attr “cc”) (symbol_ref “compute_logical_op_cc (SImode, operands)”))]) ;; ---------------------------------------------------------------------- ;; NEGATION INSTRUCTIONS ;; ----------------------------------------------------------------------

(define_insn “negqi2” [(set (match_operand:QI 0 “register_operand” “=r”) (neg:QI (match_operand:QI 1 “register_operand” “0”)))] "" “neg %X0” [(set_attr “length” “2”) (set_attr “cc” “set_zn”)])

(define_expand “neghi2” [(set (match_operand:HI 0 “register_operand” "") (neg:HI (match_operand:HI 1 “register_operand” "“)))] "" " { 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” ""))) (set (match_dup 2) (plus:HI (match_dup 2) (const_int 1))) (set (match_operand:HI 0 “register_operand” "") (match_dup 2))] "" “operands[2] = gen_reg_rtx (HImode);”)

(define_insn “*neghi2_h8300hs” [(set (match_operand:HI 0 “register_operand” “=r”) (neg:HI (match_operand:HI 1 “register_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” "") (neg:SI (match_operand:SI 1 “register_operand” "“)))] "" " { 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” ""))) (set (match_dup 2) (plus:SI (match_dup 2) (const_int 1))) (set (match_operand:SI 0 “register_operand” "") (match_dup 2))] "" “operands[2] = gen_reg_rtx (SImode);”)

(define_insn “*negsi2_h8300hs” [(set (match_operand:SI 0 “register_operand” “=r”) (neg:SI (match_operand:SI 1 “register_operand” “0”)))] “TARGET_H8300H || TARGET_H8300S” “neg %S0” [(set_attr “length” “2”) (set_attr “cc” “set_zn”)])

(define_expand “negsf2” [(set (match_operand:SF 0 “register_operand” "") (neg:SF (match_operand:SF 1 “register_operand” "")))] "" "")

(define_insn “*negsf2_h8300” [(set (match_operand:SF 0 “register_operand” “=r”) (neg:SF (match_operand:SF 1 “register_operand” “0”)))] “TARGET_H8300” “xor.b\t#128,%z0” [(set_attr “cc” “clobber”) (set_attr “length” “2”)])

(define_insn “*negsf2_h8300hs” [(set (match_operand:SF 0 “register_operand” “=r”) (neg:SF (match_operand:SF 1 “register_operand” “0”)))] “TARGET_H8300H || TARGET_H8300S” “xor.w\t#32768,%e0” [(set_attr “cc” “clobber”) (set_attr “length” “4”)]) ;; ---------------------------------------------------------------------- ;; ABSOLUTE VALUE INSTRUCTIONS ;; ----------------------------------------------------------------------

(define_expand “abssf2” [(set (match_operand:SF 0 “register_operand” "") (abs:SF (match_operand:SF 1 “register_operand” "")))] "" "")

(define_insn “*abssf2_h8300” [(set (match_operand:SF 0 “register_operand” “=r”) (abs:SF (match_operand:SF 1 “register_operand” “0”)))] “TARGET_H8300” “and.b\t#127,%z0” [(set_attr “cc” “clobber”) (set_attr “length” “2”)])

(define_insn “*abssf2_h8300hs” [(set (match_operand:SF 0 “register_operand” “=r”) (abs:SF (match_operand:SF 1 “register_operand” “0”)))] “TARGET_H8300H || TARGET_H8300S” “and.w\t#32767,%e0” [(set_attr “cc” “clobber”) (set_attr “length” “4”)]) ;; ---------------------------------------------------------------------- ;; NOT INSTRUCTIONS ;; ----------------------------------------------------------------------

(define_insn “one_cmplqi2” [(set (match_operand:QI 0 “register_operand” “=r”) (not:QI (match_operand:QI 1 “register_operand” “0”)))] "" “not %X0” [(set_attr “length” “2”) (set_attr “cc” “set_znv”)])

(define_expand “one_cmplhi2” [(set (match_operand:HI 0 “register_operand” “=r”) (not:HI (match_operand:HI 1 “register_operand” “0”)))] "" "")

(define_insn “*one_cmplhi2_h8300” [(set (match_operand:HI 0 “register_operand” “=r”) (not:HI (match_operand:HI 1 “register_operand” “0”)))] “TARGET_H8300” “not %s0;not %t0” [(set_attr “cc” “clobber”) (set_attr “length” “4”)])

(define_insn “*one_cmplhi2_h8300hs” [(set (match_operand:HI 0 “register_operand” “=r”) (not:HI (match_operand:HI 1 “register_operand” “0”)))] “TARGET_H8300H || TARGET_H8300S” “not %T0” [(set_attr “cc” “set_znv”) (set_attr “length” “2”)])

(define_expand “one_cmplsi2” [(set (match_operand:SI 0 “register_operand” “=r”) (not:SI (match_operand:SI 1 “register_operand” “0”)))] "" "")

(define_insn “*one_complsi2_h8300” [(set (match_operand:SI 0 “register_operand” “=r”) (not:SI (match_operand:SI 1 “register_operand” “0”)))] “TARGET_H8300” “not %w0;not %x0;not %y0;not %z0” [(set_attr “cc” “clobber”) (set_attr “length” “8”)])

(define_insn “*one_complsi2_h8300hs” [(set (match_operand:SI 0 “register_operand” “=r”) (not:SI (match_operand:SI 1 “register_operand” “0”)))] “TARGET_H8300H || TARGET_H8300S” “not %S0” [(set_attr “cc” “set_znv”) (set_attr “length” “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” "")) (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_h8300hs_advanced” [(set (pc) (match_operand:SI 0 “register_operand” “r”)) (use (label_ref (match_operand 1 "" "")))] “(TARGET_H8300H || TARGET_H8300S) && !TARGET_NORMAL_MODE” “jmp @%0” [(set_attr “cc” “none”) (set_attr “length” “2”)])

(define_insn “*tablejump_h8300hs_normal” [(set (pc) (match_operand:HI 0 “register_operand” “r”)) (use (label_ref (match_operand 1 "" "")))] “(TARGET_H8300H || TARGET_H8300S) && TARGET_NORMAL_MODE” “jmp @%S0” [(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_h8300hs_advanced” [(set (pc) (match_operand:SI 0 “jump_address_operand” “Vr”))] “(TARGET_H8300H || TARGET_H8300S) && !TARGET_NORMAL_MODE” “jmp @%0” [(set_attr “cc” “none”) (set_attr “length” “2”)])

(define_insn “*indirect_jump_h8300hs_normal” [(set (pc) (match_operand:HI 0 “jump_address_operand” “Vr”))] “(TARGET_H8300H || TARGET_H8300S) && TARGET_NORMAL_MODE” “jmp @%S0” [(set_attr “cc” “none”) (set_attr “length” “2”)])

;; Call subroutine with no return value.

;; ??? Even though we use HImode here, this works on the H8/300H and H8S.

(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 2) (const_int 4)))])

;; Call subroutine, returning value in operand 0 ;; (which must be a hard register).

;; ??? Even though we use HImode here, this works on the H8/300H and H8S.

(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 2) (const_int 4)))])

(define_insn “nop” [(const_int 0)] "" “nop” [(set_attr “cc” “none”) (set_attr “length” “2”)]) ;; ---------------------------------------------------------------------- ;; PROLOGUE/EPILOGUE-RELATED INSTRUCTIONS ;; ----------------------------------------------------------------------

(define_expand “push_h8300” [(set (mem:HI (pre_dec:HI (reg:HI SP_REG))) (match_operand:HI 0 “register_operand” ""))] “TARGET_H8300” "")

(define_expand “push_h8300hs_advanced” [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_operand:SI 0 “register_operand” ""))] “TARGET_H8300H && TARGET_H8300S && !TARGET_NORMAL_MODE” "")

(define_expand “push_h8300hs_normal” [(set (mem:SI (pre_dec:HI (reg:HI SP_REG))) (match_operand:SI 0 “register_operand” ""))] “TARGET_H8300H && TARGET_H8300S && TARGET_NORMAL_MODE” "")

(define_expand “pop_h8300” [(set (match_operand:HI 0 “register_operand” "") (mem:HI (post_inc:HI (reg:HI SP_REG))))] “TARGET_H8300” "")

(define_expand “pop_h8300hs_advanced” [(set (match_operand:SI 0 “register_operand” "") (mem:SI (post_inc:SI (reg:SI SP_REG))))] “TARGET_H8300H && TARGET_H8300S && !TARGET_NORMAL_MODE” "")

(define_expand “pop_h8300hs_normal” [(set (match_operand:SI 0 “register_operand” "") (mem:SI (post_inc:HI (reg:HI SP_REG))))] “TARGET_H8300H && TARGET_H8300S && TARGET_NORMAL_MODE” "")

(define_insn “stm_h8300s_2_advanced” [(parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8))) (set (mem:SI (plus:SI (reg:SI SP_REG) (const_int -4))) (match_operand:SI 0 “register_operand” "")) (set (mem:SI (plus:SI (reg:SI SP_REG) (const_int -8))) (match_operand:SI 1 “register_operand” ""))])] “TARGET_H8300S && !TARGET_NORMAL_MODE && ((REGNO (operands[0]) == 0 && REGNO (operands[1]) == 1) || (REGNO (operands[0]) == 2 && REGNO (operands[1]) == 3) || (REGNO (operands[0]) == 4 && REGNO (operands[1]) == 5))” “stm.l\t%S0-%S1,@-er7” [(set_attr “cc” “none”) (set_attr “length” “4”)])

(define_insn “stm_h8300s_2_normal” [(parallel [(set (reg:HI SP_REG) (plus:HI (reg:HI SP_REG) (const_int -8))) (set (mem:SI (plus:HI (reg:HI SP_REG) (const_int -4))) (match_operand:SI 0 “register_operand” "")) (set (mem:SI (plus:HI (reg:HI SP_REG) (const_int -8))) (match_operand:SI 1 “register_operand” ""))])] “TARGET_H8300S && TARGET_NORMAL_MODE && ((REGNO (operands[0]) == 0 && REGNO (operands[1]) == 1) || (REGNO (operands[0]) == 2 && REGNO (operands[1]) == 3) || (REGNO (operands[0]) == 4 && REGNO (operands[1]) == 5))” “stm.l\t%S0-%S1,@-er7” [(set_attr “cc” “none”) (set_attr “length” “4”)])

(define_expand “stm_h8300s_2” [(use (match_operand:SI 0 “register_operand” "")) (use (match_operand:SI 1 “register_operand” "“))] “TARGET_H8300S && ((REGNO (operands[0]) == 0 && REGNO (operands[1]) == 1) || (REGNO (operands[0]) == 2 && REGNO (operands[1]) == 3) || (REGNO (operands[0]) == 4 && REGNO (operands[1]) == 5))” " { if (!TARGET_NORMAL_MODE) emit_insn (gen_stm_h8300s_2_advanced (operands[0], operands[1])); else emit_insn (gen_stm_h8300s_2_normal (operands[0], operands[1])); DONE; }”)

(define_insn “stm_h8300s_3_advanced” [(parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -12))) (set (mem:SI (plus:SI (reg:SI SP_REG) (const_int -4))) (match_operand:SI 0 “register_operand” "")) (set (mem:SI (plus:SI (reg:SI SP_REG) (const_int -8))) (match_operand:SI 1 “register_operand” "")) (set (mem:SI (plus:SI (reg:SI SP_REG) (const_int -12))) (match_operand:SI 2 “register_operand” ""))])] “TARGET_H8300S && !TARGET_NORMAL_MODE && ((REGNO (operands[0]) == 0 && REGNO (operands[1]) == 1 && REGNO (operands[2]) == 2) || (REGNO (operands[0]) == 4 && REGNO (operands[1]) == 5 && REGNO (operands[2]) == 6))” “stm.l\t%S0-%S2,@-er7” [(set_attr “cc” “none”) (set_attr “length” “4”)])

(define_insn “stm_h8300s_3_normal” [(parallel [(set (reg:HI SP_REG) (plus:HI (reg:HI SP_REG) (const_int -12))) (set (mem:SI (plus:HI (reg:HI SP_REG) (const_int -4))) (match_operand:SI 0 “register_operand” "")) (set (mem:SI (plus:HI (reg:HI SP_REG) (const_int -8))) (match_operand:SI 1 “register_operand” "")) (set (mem:SI (plus:HI (reg:HI SP_REG) (const_int -12))) (match_operand:SI 2 “register_operand” ""))])] “TARGET_H8300S && TARGET_NORMAL_MODE && ((REGNO (operands[0]) == 0 && REGNO (operands[1]) == 1 && REGNO (operands[2]) == 2) || (REGNO (operands[0]) == 4 && REGNO (operands[1]) == 5 && REGNO (operands[2]) == 6))” “stm.l\t%S0-%S2,@-er7” [(set_attr “cc” “none”) (set_attr “length” “4”)])

(define_expand “stm_h8300s_3” [(use (match_operand:SI 0 “register_operand” "")) (use (match_operand:SI 1 “register_operand” "")) (use (match_operand:SI 2 “register_operand” "“))] “TARGET_H8300S && ((REGNO (operands[0]) == 0 && REGNO (operands[1]) == 1 && REGNO (operands[2]) == 2) || (REGNO (operands[0]) == 4 && REGNO (operands[1]) == 5 && REGNO (operands[2]) == 6))” " { if (!TARGET_NORMAL_MODE) emit_insn (gen_stm_h8300s_3_advanced (operands[0], operands[1], operands[2])); else emit_insn (gen_stm_h8300s_3_normal (operands[0], operands[1], operands[2])); DONE; }”)

(define_insn “stm_h8300s_4_advanced” [(parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -16))) (set (mem:SI (plus:SI (reg:SI SP_REG) (const_int -4))) (match_operand:SI 0 “register_operand” "")) (set (mem:SI (plus:SI (reg:SI SP_REG) (const_int -8))) (match_operand:SI 1 “register_operand” "")) (set (mem:SI (plus:SI (reg:SI SP_REG) (const_int -12))) (match_operand:SI 2 “register_operand” "")) (set (mem:SI (plus:SI (reg:SI SP_REG) (const_int -16))) (match_operand:SI 3 “register_operand” ""))])] “TARGET_H8300S && !TARGET_NORMAL_MODE && REGNO (operands[0]) == 0 && REGNO (operands[1]) == 1 && REGNO (operands[2]) == 2 && REGNO (operands[3]) == 3” “stm.l\t%S0-%S3,@-er7” [(set_attr “cc” “none”) (set_attr “length” “4”)])

(define_insn “stm_h8300s_4_normal” [(parallel [(set (reg:HI SP_REG) (plus:HI (reg:HI SP_REG) (const_int -16))) (set (mem:SI (plus:HI (reg:HI SP_REG) (const_int -4))) (match_operand:SI 0 “register_operand” "")) (set (mem:SI (plus:HI (reg:HI SP_REG) (const_int -8))) (match_operand:SI 1 “register_operand” "")) (set (mem:SI (plus:HI (reg:HI SP_REG) (const_int -12))) (match_operand:SI 2 “register_operand” "")) (set (mem:SI (plus:HI (reg:HI SP_REG) (const_int -16))) (match_operand:SI 3 “register_operand” ""))])] “TARGET_H8300S && TARGET_NORMAL_MODE && REGNO (operands[0]) == 0 && REGNO (operands[1]) == 1 && REGNO (operands[2]) == 2 && REGNO (operands[3]) == 3” “stm.l\t%S0-%S3,@-er7” [(set_attr “cc” “none”) (set_attr “length” “4”)])

(define_expand “stm_h8300s_4” [(use (match_operand:SI 0 “register_operand” "")) (use (match_operand:SI 1 “register_operand” "")) (use (match_operand:SI 2 “register_operand” "")) (use (match_operand:SI 3 “register_operand” "“))] “TARGET_H8300S && REGNO (operands[0]) == 0 && REGNO (operands[1]) == 1 && REGNO (operands[2]) == 2 && REGNO (operands[3]) == 3” " { if (!TARGET_NORMAL_MODE) emit_insn (gen_stm_h8300s_4_advanced (operands[0], operands[1], operands[2], operands[3])); else emit_insn (gen_stm_h8300s_4_normal (operands[0], operands[1], operands[2], operands[3])); DONE; }”)

(define_insn “ldm_h8300s_2_advanced” [(parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8))) (set (mem:SI (plus:SI (reg:SI SP_REG) (const_int 4))) (match_operand:SI 0 “register_operand” "")) (set (mem:SI (reg:SI SP_REG)) (match_operand:SI 1 “register_operand” ""))])] “TARGET_H8300S && !TARGET_NORMAL_MODE && ((REGNO (operands[0]) == 0 && REGNO (operands[1]) == 1) || (REGNO (operands[0]) == 2 && REGNO (operands[1]) == 3) || (REGNO (operands[0]) == 4 && REGNO (operands[1]) == 5))” “ldm.l\t@er7+,%S0-%S1” [(set_attr “cc” “none”) (set_attr “length” “4”)])

(define_insn “ldm_h8300s_2_normal” [(parallel [(set (reg:HI SP_REG) (plus:HI (reg:HI SP_REG) (const_int 8))) (set (mem:SI (plus:HI (reg:HI SP_REG) (const_int 4))) (match_operand:SI 0 “register_operand” "")) (set (mem:SI (reg:HI SP_REG)) (match_operand:SI 1 “register_operand” ""))])] “TARGET_H8300S && TARGET_NORMAL_MODE && ((REGNO (operands[0]) == 0 && REGNO (operands[1]) == 1) || (REGNO (operands[0]) == 2 && REGNO (operands[1]) == 3) || (REGNO (operands[0]) == 4 && REGNO (operands[1]) == 5))” “ldm.l\t@er7+,%S0-%S1” [(set_attr “cc” “none”) (set_attr “length” “4”)])

(define_expand “ldm_h8300s_2” [(use (match_operand:SI 0 “register_operand” "")) (use (match_operand:SI 1 “register_operand” "“))] “TARGET_H8300S && ((REGNO (operands[0]) == 0 && REGNO (operands[1]) == 1) || (REGNO (operands[0]) == 2 && REGNO (operands[1]) == 3) || (REGNO (operands[0]) == 4 && REGNO (operands[1]) == 5))” " { if (!TARGET_NORMAL_MODE) emit_insn (gen_ldm_h8300s_2_advanced (operands[0], operands[1])); else emit_insn (gen_ldm_h8300s_2_normal (operands[0], operands[1])); DONE; }”)

(define_insn “ldm_h8300s_3_advanced” [(parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 12))) (set (mem:SI (plus:SI (reg:SI SP_REG) (const_int 8))) (match_operand:SI 0 “register_operand” "")) (set (mem:SI (plus:SI (reg:SI SP_REG) (const_int 4))) (match_operand:SI 1 “register_operand” "")) (set (mem:SI (reg:SI SP_REG)) (match_operand:SI 2 “register_operand” ""))])] “TARGET_H8300S && !TARGET_NORMAL_MODE && ((REGNO (operands[0]) == 0 && REGNO (operands[1]) == 1 && REGNO (operands[2]) == 2) || (REGNO (operands[0]) == 4 && REGNO (operands[1]) == 5 && REGNO (operands[2]) == 6))” “ldm.l\t@er7+,%S0-%S2” [(set_attr “cc” “none”) (set_attr “length” “4”)])

(define_insn “ldm_h8300s_3_normal” [(parallel [(set (reg:HI SP_REG) (plus:HI (reg:HI SP_REG) (const_int 12))) (set (mem:SI (plus:HI (reg:HI SP_REG) (const_int 8))) (match_operand:SI 0 “register_operand” "")) (set (mem:SI (plus:HI (reg:HI SP_REG) (const_int 4))) (match_operand:SI 1 “register_operand” "")) (set (mem:SI (reg:HI SP_REG)) (match_operand:SI 2 “register_operand” ""))])] “TARGET_H8300S && TARGET_NORMAL_MODE && ((REGNO (operands[0]) == 0 && REGNO (operands[1]) == 1 && REGNO (operands[2]) == 2) || (REGNO (operands[0]) == 4 && REGNO (operands[1]) == 5 && REGNO (operands[2]) == 6))” “ldm.l\t@er7+,%S0-%S2” [(set_attr “cc” “none”) (set_attr “length” “4”)])

(define_expand “ldm_h8300s_3” [(use (match_operand:SI 0 “register_operand” "")) (use (match_operand:SI 1 “register_operand” "")) (use (match_operand:SI 2 “register_operand” "“))] “TARGET_H8300S && ((REGNO (operands[0]) == 0 && REGNO (operands[1]) == 1 && REGNO (operands[2]) == 2) || (REGNO (operands[0]) == 4 && REGNO (operands[1]) == 5 && REGNO (operands[2]) == 6))” " { if (!TARGET_NORMAL_MODE) emit_insn (gen_ldm_h8300s_3_advanced (operands[0], operands[1], operands[2])); else emit_insn (gen_ldm_h8300s_3_normal (operands[0], operands[1], operands[2])); DONE; }”)

(define_insn “ldm_h8300s_4_advanced” [(parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 16))) (set (mem:SI (plus:SI (reg:SI SP_REG) (const_int 12))) (match_operand:SI 0 “register_operand” "")) (set (mem:SI (plus:SI (reg:SI SP_REG) (const_int 8))) (match_operand:SI 1 “register_operand” "")) (set (mem:SI (plus:SI (reg:SI SP_REG) (const_int 4))) (match_operand:SI 2 “register_operand” "")) (set (mem:SI (reg:SI SP_REG)) (match_operand:SI 3 “register_operand” ""))])] “TARGET_H8300S && !TARGET_NORMAL_MODE && REGNO (operands[0]) == 0 && REGNO (operands[1]) == 1 && REGNO (operands[2]) == 2 && REGNO (operands[3]) == 3” “ldm.l\t@er7+,%S0-%S3” [(set_attr “cc” “none”) (set_attr “length” “4”)])

(define_insn “ldm_h8300s_4_normal” [(parallel [(set (reg:HI SP_REG) (plus:HI (reg:HI SP_REG) (const_int 16))) (set (mem:SI (plus:HI (reg:HI SP_REG) (const_int 12))) (match_operand:SI 0 “register_operand” "")) (set (mem:SI (plus:HI (reg:HI SP_REG) (const_int 8))) (match_operand:SI 1 “register_operand” "")) (set (mem:SI (plus:HI (reg:HI SP_REG) (const_int 4))) (match_operand:SI 2 “register_operand” "")) (set (mem:SI (reg:HI SP_REG)) (match_operand:SI 3 “register_operand” ""))])] “TARGET_H8300S && !TARGET_NORMAL_MODE && REGNO (operands[0]) == 0 && REGNO (operands[1]) == 1 && REGNO (operands[2]) == 2 && REGNO (operands[3]) == 3” “ldm.l\t@er7+,%S0-%S3” [(set_attr “cc” “none”) (set_attr “length” “4”)])

(define_expand “ldm_h8300s_4” [(use (match_operand:SI 0 “register_operand” "")) (use (match_operand:SI 1 “register_operand” "")) (use (match_operand:SI 2 “register_operand” "")) (use (match_operand:SI 3 “register_operand” "“))] “TARGET_H8300S && !TARGET_NORMAL_MODE && REGNO (operands[0]) == 0 && REGNO (operands[1]) == 1 && REGNO (operands[2]) == 2 && REGNO (operands[3]) == 3” " { if (!TARGET_NORMAL_MODE) emit_insn (gen_ldm_h8300s_4_advanced (operands[0], operands[1], operands[2], operands[3])); else emit_insn (gen_ldm_h8300s_4_normal (operands[0], operands[1], operands[2], operands[3])); DONE; }”)

(define_expand “return” [(return)] “h8300_can_use_return_insn_p ()” "")

(define_insn “*return_1” [(return)] “reload_completed” “* { if (h8300_current_function_interrupt_function_p ()) return "rte"; else return "rts"; }” [(set_attr “cc” “none”) (set_attr “length” “2”)])

(define_expand “prologue” [(const_int 0)] "" “h8300_expand_prologue (); DONE;”)

(define_expand “epilogue” [(return)] "" “h8300_expand_epilogue ();”)

(define_insn “monitor_prologue” [(unspec_volatile [(const_int 0)] UNSPEC_MONITOR)] "" “* { if (TARGET_H8300) return "subs\t#2,r7;mov.w\tr0,@-r7;stc\tccr,r0l;mov.b\tr0l,@(2,r7);mov.w\t@r7+,r0;orc\t#128,ccr"; else if (TARGET_H8300H) return "mov.l\ter0,@-er7;stc\tccr,r0l;mov.b\tr0l,@(4,er7);mov.l\t@er7+,er0;orc\t#128,ccr"; else if (TARGET_H8300S) return "stc\texr,@-er7;mov.l\ter0,@-er7;stc\tccr,r0l;mov.b\tr0l,@(6,er7);mov.l\t@er7+,er0;orc\t#128,ccr"; abort (); }” [(set_attr “length” “20”) (set_attr “cc” “clobber”)]) ;; ---------------------------------------------------------------------- ;; EXTEND INSTRUCTIONS ;; ----------------------------------------------------------------------

(define_expand “zero_extendqihi2” [(set (match_operand:HI 0 “register_operand” "") (zero_extend:HI (match_operand:QI 1 “general_operand_src” "")))] "" "")

(define_insn “*zero_extendqihi2_h8300” [(set (match_operand:HI 0 “register_operand” “=r,r”) (zero_extend:HI (match_operand:QI 1 “general_operand_src” “0,g>”)))] “TARGET_H8300” “@ mov.b #0,%t0 #” [(set_attr “length” “2,10”) (set_attr “cc” “clobber,clobber”)])

(define_insn “*zero_extendqihi2_h8300hs” [(set (match_operand:HI 0 “register_operand” “=r,r”) (zero_extend:HI (match_operand:QI 1 “general_operand_src” “0,g>”)))] “TARGET_H8300H || TARGET_H8300S” “@ extu.w %T0 #” [(set_attr “length” “2,10”) (set_attr “cc” “set_znv,set_znv”)])

;; Split the zero extension of a general operand (actually a memory ;; operand) into a load of the operand and the actual zero extension ;; so that 1) the length will be accurate, and 2) the zero extensions ;; appearing at the end of basic blocks may be merged.

(define_split [(set (match_operand:HI 0 “register_operand” "") (zero_extend:HI (match_operand:QI 1 “general_operand_src” "")))] “reload_completed” [(set (match_dup 2) (match_dup 1)) (set (match_dup 0) (zero_extend:HI (match_dup 2)))] “operands[2] = gen_rtx_REG (QImode, REGNO (operands[0]));”)

(define_expand “zero_extendqisi2” [(set (match_operand:SI 0 “register_operand” "") (zero_extend:SI (match_operand:QI 1 “general_operand_src” "")))] "" "")

(define_insn “*zero_extendqisi2_h8300” [(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,8”) (set_attr “cc” “clobber,clobber”)])

(define_insn “*zero_extendqisi2_h8300hs” [(set (match_operand:SI 0 “register_operand” “=r,r”) (zero_extend:SI (match_operand:QI 1 “general_operand_src” “0,g>”)))] “TARGET_H8300H || TARGET_H8300S” “#”)

(define_split [(set (match_operand:SI 0 “register_operand” "") (zero_extend:SI (match_operand:QI 1 “general_operand_src” "")))] “(TARGET_H8300H || TARGET_H8300S) && reg_overlap_mentioned_p (operands[0], operands[1]) && reload_completed” [(set (match_dup 2) (match_dup 1)) (set (match_dup 3) (zero_extend:HI (match_dup 2))) (set (match_dup 0) (zero_extend:SI (match_dup 3)))] “operands[2] = gen_lowpart (QImode, operands[0]); operands[3] = gen_lowpart (HImode, operands[0]);”)

(define_split [(set (match_operand:SI 0 “register_operand” "") (zero_extend:SI (match_operand:QI 1 “general_operand_src” "")))] “(TARGET_H8300H || TARGET_H8300S) && !reg_overlap_mentioned_p (operands[0], operands[1]) && reload_completed” [(set (match_dup 0) (const_int 0)) (set (strict_low_part (match_dup 2)) (match_dup 1))] “operands[2] = gen_rtx_REG (QImode, REGNO (operands[0]));”)

(define_expand “zero_extendhisi2” [(set (match_operand:SI 0 “register_operand” "") (zero_extend:SI (match_operand:HI 1 “register_operand” "")))] "" "")

;; %e prints the high part of a CONST_INT, not the low part. Arggh. (define_insn “*zero_extendhisi2_h8300” [(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,6”) (set_attr “cc” “clobber,clobber,clobber”)])

(define_insn “*zero_extendhisi2_h8300hs” [(set (match_operand:SI 0 “register_operand” “=r”) (zero_extend:SI (match_operand:HI 1 “register_operand” “0”)))] “TARGET_H8300H || TARGET_H8300S” “extu.l %S0” [(set_attr “length” “2”) (set_attr “cc” “set_znv”)])

(define_expand “extendqihi2” [(set (match_operand:HI 0 “register_operand” "") (sign_extend:HI (match_operand:QI 1 “register_operand” "")))] "" "")

(define_insn “*extendqihi2_h8300” [(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,8”) (set_attr “cc” “clobber,clobber”)])

(define_insn “*extendqihi2_h8300hs” [(set (match_operand:HI 0 “register_operand” “=r”) (sign_extend:HI (match_operand:QI 1 “register_operand” “0”)))] “TARGET_H8300H || TARGET_H8300S” “exts.w %T0” [(set_attr “length” “2”) (set_attr “cc” “set_znv”)])

(define_expand “extendqisi2” [(set (match_operand:SI 0 “register_operand” "") (sign_extend:SI (match_operand:QI 1 “register_operand” "")))] "" "")

(define_insn “*extendqisi2_h8300” [(set (match_operand:SI 0 “register_operand” "") (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,12”) (set_attr “cc” “clobber,clobber”)])

;; The following pattern is needed because without the pattern, the ;; combiner would split (sign_extend:SI (reg:QI)) into into two 24-bit ;; shifts, one ashift and one ashiftrt.

(define_insn_and_split “*extendqisi2_h8300hs” [(set (match_operand:SI 0 “register_operand” “=r”) (sign_extend:SI (match_operand:QI 1 “register_operand” “0”)))] “(TARGET_H8300H || TARGET_H8300S)” “#” “&& reload_completed” [(set (match_dup 2) (sign_extend:HI (match_dup 1))) (set (match_dup 0) (sign_extend:SI (match_dup 2)))] “operands[2] = gen_rtx_REG (HImode, REGNO (operands[0]));”)

(define_expand “extendhisi2” [(set (match_operand:SI 0 “register_operand” "") (sign_extend:SI (match_operand:HI 1 “register_operand” "")))] "" "")

(define_insn “*extendhisi2_h8300” [(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,10”) (set_attr “cc” “clobber,clobber”)])

(define_insn “*extendhisi2_h8300hs” [(set (match_operand:SI 0 “register_operand” “=r”) (sign_extend:SI (match_operand:HI 1 “register_operand” “0”)))] “TARGET_H8300H || TARGET_H8300S” “exts.l %S0” [(set_attr “length” “2”) (set_attr “cc” “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” "")))] "" “expand_a_shift (QImode, ASHIFT, operands); DONE;”)

(define_expand “ashrqi3” [(set (match_operand:QI 0 “register_operand” "") (ashiftrt:QI (match_operand:QI 1 “register_operand” "") (match_operand:QI 2 “nonmemory_operand” "")))] "" “expand_a_shift (QImode, ASHIFTRT, operands); DONE;”)

(define_expand “lshrqi3” [(set (match_operand:QI 0 “register_operand” "") (lshiftrt:QI (match_operand:QI 1 “register_operand” "") (match_operand:QI 2 “nonmemory_operand” "")))] "" “expand_a_shift (QImode, LSHIFTRT, operands); DONE;”)

(define_insn “*shiftqi” [(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” “R,rn”)])) (clobber (match_scratch:QI 4 “=X,&r”))] "" “* return output_a_shift (operands);” [(set (attr “length”) (symbol_ref “compute_a_shift_length (insn, operands)”)) (set (attr “cc”) (symbol_ref “compute_a_shift_cc (insn, operands)”))])

;; 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” "")))] "" “expand_a_shift (HImode, ASHIFT, operands); DONE;”)

(define_expand “lshrhi3” [(set (match_operand:HI 0 “register_operand” "") (lshiftrt:HI (match_operand:HI 1 “general_operand” "") (match_operand:QI 2 “nonmemory_operand” "")))] "" “expand_a_shift (HImode, LSHIFTRT, operands); DONE;”)

(define_expand “ashrhi3” [(set (match_operand:HI 0 “register_operand” "") (ashiftrt:HI (match_operand:HI 1 “register_operand” "") (match_operand:QI 2 “nonmemory_operand” "")))] "" “expand_a_shift (HImode, ASHIFTRT, operands); DONE;”)

(define_insn “*shifthi” [(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” “S,rn”)])) (clobber (match_scratch:QI 4 “=X,&r”))] "" “* return output_a_shift (operands);” [(set (attr “length”) (symbol_ref “compute_a_shift_length (insn, operands)”)) (set (attr “cc”) (symbol_ref “compute_a_shift_cc (insn, operands)”))])

;; 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” "")))] "" “expand_a_shift (SImode, ASHIFT, operands); DONE;”)

(define_expand “lshrsi3” [(set (match_operand:SI 0 “register_operand” "") (lshiftrt:SI (match_operand:SI 1 “general_operand” "") (match_operand:QI 2 “nonmemory_operand” "")))] "" “expand_a_shift (SImode, LSHIFTRT, operands); DONE;”)

(define_expand “ashrsi3” [(set (match_operand:SI 0 “register_operand” "") (ashiftrt:SI (match_operand:SI 1 “general_operand” "") (match_operand:QI 2 “nonmemory_operand” "")))] "" “expand_a_shift (SImode, ASHIFTRT, operands); DONE;”)

(define_insn “*shiftsi” [(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” “T,rn”)])) (clobber (match_scratch:QI 4 “=X,&r”))] "" “* return output_a_shift (operands);” [(set (attr “length”) (symbol_ref “compute_a_shift_length (insn, operands)”)) (set (attr “cc”) (symbol_ref “compute_a_shift_cc (insn, operands)”))])

;; Split a variable shift into a loop. If the register containing ;; the shift count dies, then we just use that register.

(define_split [(parallel [(set (match_operand 0 “register_operand” "") (match_operator 2 “nshift_operator” [(match_dup 0) (match_operand:QI 1 “register_operand” "")])) (clobber (match_operand:QI 3 “register_operand” ""))])] “flow2_completed && find_regno_note (insn, REG_DEAD, REGNO (operands[1]))” [(set (cc0) (match_dup 1)) (set (pc) (if_then_else (le (cc0) (const_int 0)) (label_ref (match_dup 5)) (pc))) (match_dup 4) (parallel [(set (match_dup 0) (match_op_dup 2 [(match_dup 0) (const_int 1)])) (clobber (scratch:QI))]) (set (match_dup 1) (plus:QI (match_dup 1) (const_int -1))) (set (cc0) (match_dup 1)) (set (pc) (if_then_else (ne (cc0) (const_int 0)) (label_ref (match_dup 4)) (pc))) (match_dup 5)] “operands[4] = gen_label_rtx (); operands[5] = gen_label_rtx ();”)

(define_split [(parallel [(set (match_operand 0 “register_operand” "") (match_operator 2 “nshift_operator” [(match_dup 0) (match_operand:QI 1 “register_operand” "")])) (clobber (match_operand:QI 3 “register_operand” ""))])] “flow2_completed && !find_regno_note (insn, REG_DEAD, REGNO (operands[1]))” [(set (match_dup 3) (match_dup 1)) (set (cc0) (match_dup 3)) (set (pc) (if_then_else (le (cc0) (const_int 0)) (label_ref (match_dup 5)) (pc))) (match_dup 4) (parallel [(set (match_dup 0) (match_op_dup 2 [(match_dup 0) (const_int 1)])) (clobber (scratch:QI))]) (set (match_dup 3) (plus:QI (match_dup 3) (const_int -1))) (set (cc0) (match_dup 3)) (set (pc) (if_then_else (ne (cc0) (const_int 0)) (label_ref (match_dup 4)) (pc))) (match_dup 5)] “operands[4] = gen_label_rtx (); operands[5] = gen_label_rtx ();”) ;; ---------------------------------------------------------------------- ;; ROTATIONS ;; ----------------------------------------------------------------------

(define_expand “rotlqi3” [(set (match_operand:QI 0 “register_operand” "") (rotate:QI (match_operand:QI 1 “register_operand” "") (match_operand:QI 2 “nonmemory_operand” "")))] "" “if (expand_a_rotate (ROTATE, operands)) DONE; else FAIL;”)

(define_insn “*rotlqi3_1” [(set (match_operand:QI 0 “register_operand” “=r”) (rotate:QI (match_operand:QI 1 “register_operand” “0”) (match_operand:QI 2 “immediate_operand” "")))] "" “* return output_a_rotate (ROTATE, operands);” [(set (attr “length”) (symbol_ref “compute_a_rotate_length (operands)”)) (set_attr “cc” “clobber”)])

(define_expand “rotlhi3” [(set (match_operand:HI 0 “register_operand” "") (rotate:HI (match_operand:HI 1 “register_operand” "") (match_operand:QI 2 “nonmemory_operand” "")))] "" “if (expand_a_rotate (ROTATE, operands)) DONE; else FAIL;”)

(define_insn “*rotlhi3_1” [(set (match_operand:HI 0 “register_operand” “=r”) (rotate:HI (match_operand:HI 1 “register_operand” “0”) (match_operand:QI 2 “immediate_operand” "")))] "" “* return output_a_rotate (ROTATE, operands);” [(set (attr “length”) (symbol_ref “compute_a_rotate_length (operands)”)) (set_attr “cc” “clobber”)])

(define_expand “rotlsi3” [(set (match_operand:SI 0 “register_operand” "") (rotate:SI (match_operand:SI 1 “register_operand” "") (match_operand:QI 2 “nonmemory_operand” "")))] “TARGET_H8300H || TARGET_H8300S” “if (expand_a_rotate (ROTATE, operands)) DONE; else FAIL;”)

(define_insn “*rotlsi3_1” [(set (match_operand:SI 0 “register_operand” “=r”) (rotate:SI (match_operand:SI 1 “register_operand” “0”) (match_operand:QI 2 “immediate_operand” "")))] “TARGET_H8300H || TARGET_H8300S” “* return output_a_rotate (ROTATE, operands);” [(set (attr “length”) (symbol_ref “compute_a_rotate_length (operands)”)) (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. ;;

(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”)))] “TARGET_H8300” “sub.w %0,%0;bld %Z2,%Y1;bst #0,%X0” [(set_attr “cc” “clobber”) (set_attr “length” “6”)])

;; ;; Inverted loads with a 16bit destination. ;;

(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 “const_int_operand” “n”)) (const_int 1) (match_operand:HI 2 “const_int_operand” “n”)))] “TARGET_H8300 && (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”)])

;; ;; Normal loads with a 32bit destination. ;;

(define_insn “*extzv_1_r_h8300” [(set (match_operand:SI 0 “register_operand” “=&r”) (zero_extract:SI (match_operand:HI 1 “register_operand” “r”) (const_int 1) (match_operand 2 “const_int_operand” “n”)))] “TARGET_H8300 && INTVAL (operands[2]) < 16” “* return output_simode_bld (0, operands);” [(set_attr “cc” “clobber”) (set_attr “length” “8”)])

(define_insn “*extzv_1_r_h8300hs” [(set (match_operand:SI 0 “register_operand” “=r,r”) (zero_extract:SI (match_operand:SI 1 “register_operand” “?0,r”) (const_int 1) (match_operand 2 “const_int_operand” “n,n”)))] “(TARGET_H8300H || TARGET_H8300S) && INTVAL (operands[2]) < 16” “* return output_simode_bld (0, operands);” [(set_attr “cc” “set_znv,set_znv”) (set_attr “length” “8,6”)])

;; ;; Inverted loads with a 32bit destination. ;;

(define_insn “*extzv_1_r_inv_h8300” [(set (match_operand:SI 0 “register_operand” “=&r”) (zero_extract:SI (xor:HI (match_operand:HI 1 “register_operand” “r”) (match_operand:HI 3 “const_int_operand” “n”)) (const_int 1) (match_operand 2 “const_int_operand” “n”)))] “TARGET_H8300 && INTVAL (operands[2]) < 16 && (1 << INTVAL (operands[2])) == INTVAL (operands[3])” “* return output_simode_bld (1, operands);” [(set_attr “cc” “clobber”) (set_attr “length” “8”)])

(define_insn “*extzv_1_r_inv_h8300hs” [(set (match_operand:SI 0 “register_operand” “=r,r”) (zero_extract:SI (xor:SI (match_operand:SI 1 “register_operand” “?0,r”) (match_operand 3 “const_int_operand” “n,n”)) (const_int 1) (match_operand 2 “const_int_operand” “n,n”)))] “(TARGET_H8300H || TARGET_H8300S) && INTVAL (operands[2]) < 16 && (1 << INTVAL (operands[2])) == INTVAL (operands[3])” “* return output_simode_bld (1, operands);” [(set_attr “cc” “set_znv,set_znv”) (set_attr “length” “8,6”)])

(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 bit-field 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 bit-field 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;b%c4 #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;b%c5 %Z4,%Y3;bst #0,%R0; bl3” [(set_attr “cc” “clobber”) (set_attr “length” “6”)]) ;; ----------------------------------------------------------------- ;; COMBINE PATTERNS ;; -----------------------------------------------------------------

;; insv:SI

(define_insn “*insv_si_1_n” [(set (zero_extract:SI (match_operand:SI 0 “register_operand” “+r”) (const_int 1) (match_operand:SI 1 “const_int_operand” “n”)) (match_operand:SI 2 “register_operand” “r”))] “(TARGET_H8300H || TARGET_H8300S) && INTVAL (operands[1]) < 16” “bld\t#0,%w2;bst\t%Z1,%Y0” [(set_attr “cc” “clobber”) (set_attr “length” “4”)])

(define_insn “*insv_si_1_n_lshiftrt” [(set (zero_extract:SI (match_operand:SI 0 “register_operand” “+r”) (const_int 1) (match_operand:SI 1 “const_int_operand” “n”)) (lshiftrt:SI (match_operand:SI 2 “register_operand” “r”) (match_operand:SI 3 “const_int_operand” “n”)))] “(TARGET_H8300H || TARGET_H8300S) && INTVAL (operands[1]) < 16 && INTVAL (operands[3]) < 16” “bld\t%Z3,%Y2;bst\t%Z1,%Y0” [(set_attr “cc” “clobber”) (set_attr “length” “4”)])

(define_insn “*insv_si_1_n_lshiftrt_16” [(set (zero_extract:SI (match_operand:SI 0 “register_operand” “+r”) (const_int 1) (match_operand:SI 1 “const_int_operand” “n”)) (lshiftrt:SI (match_operand:SI 2 “register_operand” “r”) (const_int 16)))] “(TARGET_H8300H || TARGET_H8300S) && INTVAL (operands[1]) < 16” “rotr.w\t%e2;rotl.w\t%e2;bst\t%Z1,%Y0” [(set_attr “cc” “clobber”) (set_attr “length” “6”)])

(define_insn “*insv_si_8_8” [(set (zero_extract:SI (match_operand:SI 0 “register_operand” “+r”) (const_int 8) (const_int 8)) (match_operand:SI 1 “register_operand” “r”))] “TARGET_H8300H || TARGET_H8300S” “mov.b\t%w1,%x0” [(set_attr “cc” “clobber”) (set_attr “length” “2”)])

(define_insn “*insv_si_8_8_lshiftrt_8” [(set (zero_extract:SI (match_operand:SI 0 “register_operand” “+r”) (const_int 8) (const_int 8)) (lshiftrt:SI (match_operand:SI 1 “register_operand” “r”) (const_int 8)))] “TARGET_H8300H || TARGET_H8300S” “mov.b\t%x1,%x0” [(set_attr “cc” “clobber”) (set_attr “length” “2”)])

;; extzv:SI

(define_insn “*extzv_8_8” [(set (match_operand:SI 0 “register_operand” “=r,r”) (zero_extract:SI (match_operand:SI 1 “register_operand” “?0,r”) (const_int 8) (const_int 8)))] “TARGET_H8300H || TARGET_H8300S” “@ mov.b\t%x1,%w0;extu.w\t%f0;extu.l\t%S0 sub.l\t%S0,%S0;mov.b\t%x1,%w0” [(set_attr “cc” “set_znv,clobber”) (set_attr “length” “6,4”)])

(define_insn “*extzv_8_16” [(set (match_operand:SI 0 “register_operand” “=r”) (zero_extract:SI (match_operand:SI 1 “register_operand” “r”) (const_int 8) (const_int 16)))] “TARGET_H8300H || TARGET_H8300S” “mov.w\t%e1,%f0;extu.w\t%f0;extu.l\t%S0” [(set_attr “cc” “set_znv”) (set_attr “length” “6”)])

(define_insn “*extzv_16_8” [(set (match_operand:SI 0 “register_operand” “=r”) (zero_extract:SI (match_operand:SI 1 “register_operand” “r”) (const_int 16) (const_int 8))) (clobber (match_scratch:SI 2 “=&r”))] “TARGET_H8300H” “mov.w\t%e1,%f2;mov.b\t%x1,%w0;mov.b\t%w2,%x0;extu.l\t%S0” [(set_attr “length” “8”) (set_attr “cc” “set_znv”)])

;; Extract the exponent of a float.

(define_insn_and_split “*extzv_8_23” [(set (match_operand:SI 0 “register_operand” “=r”) (zero_extract:SI (match_operand:SI 1 “register_operand” “0”) (const_int 8) (const_int 23)))] “(TARGET_H8300H || TARGET_H8300S)” “#” “&& reload_completed” [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (const_int 1))) (clobber (scratch:QI))]) (parallel [(set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 24))) (clobber (scratch:QI))])] "")

;; and:SI

;; ((SImode) HImode) << 15

(define_insn_and_split “*twoshifts_l16_r1” [(set (match_operand:SI 0 “register_operand” “=r”) (and:SI (ashift:SI (match_operand:SI 1 “register_operand” “0”) (const_int 15)) (const_int 2147450880)))] “(TARGET_H8300H || TARGET_H8300S)” “#” “&& reload_completed” [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (const_int 16))) (clobber (scratch:QI))]) (parallel [(set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 1))) (clobber (scratch:QI))])] "")

;; Transform (SImode << B) & 0xffff into (SImode) (HImode << B).

(define_insn_and_split “*andsi3_ashift_n_lower” [(set (match_operand:SI 0 “register_operand” “=r,r”) (and:SI (ashift:SI (match_operand:SI 1 “register_operand” “0,0”) (match_operand:QI 2 “const_int_operand” “S,n”)) (match_operand:SI 3 “const_int_operand” “n,n”))) (clobber (match_scratch:QI 4 “=X,&r”))] “(TARGET_H8300H || TARGET_H8300S) && INTVAL (operands[2]) <= 15 && INTVAL (operands[3]) == ((-1 << INTVAL (operands[2])) & 0xffff)” “#” “&& reload_completed” [(parallel [(set (match_dup 5) (ashift:HI (match_dup 5) (match_dup 2))) (clobber (match_dup 4))]) (set (match_dup 0) (zero_extend:SI (match_dup 5)))] “operands[5] = gen_rtx_REG (HImode, REGNO (operands[0]));”)

;; Accept (A >> 30) & 2 and the like.

(define_insn “*andsi3_lshiftrt_n_sb” [(set (match_operand:SI 0 “register_operand” “=r”) (and:SI (lshiftrt:SI (match_operand:SI 1 “register_operand” “0”) (match_operand:SI 2 “const_int_operand” “n”)) (match_operand:SI 3 “single_one_operand” “n”)))] “(TARGET_H8300H || TARGET_H8300S) && exact_log2 (INTVAL (operands[3])) < 16 && INTVAL (operands[2]) + exact_log2 (INTVAL (operands[3])) == 31” “* { operands[3] = GEN_INT (exact_log2 (INTVAL (operands[3]))); return "shll.l\t%S0;xor.l\t%S0,%S0;bst\t%Z3,%Y0"; }” [(set_attr “length” “8”) (set_attr “cc” “clobber”)])

(define_insn_and_split “*andsi3_lshiftrt_9_sb” [(set (match_operand:SI 0 “register_operand” “=r”) (and:SI (lshiftrt:SI (match_operand:SI 1 “register_operand” “0”) (const_int 9)) (const_int 4194304)))] “(TARGET_H8300H || TARGET_H8300S)” “#” “&& reload_completed” [(set (match_dup 0) (and:SI (lshiftrt:SI (match_dup 0) (const_int 25)) (const_int 64))) (parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (const_int 16))) (clobber (scratch:QI))])] "")

;; plus:SI

(define_insn “*addsi3_upper” [(set (match_operand:SI 0 “register_operand” “=r”) (plus:SI (mult:SI (match_operand:SI 1 “register_operand” “r”) (const_int 65536)) (match_operand:SI 2 “register_operand” “0”)))] “TARGET_H8300H || TARGET_H8300S” “add.w\t%f1,%e0” [(set_attr “length” “2”) (set_attr “cc” “clobber”)])

(define_insn “*addsi3_lshiftrt_16_zexthi” [(set (match_operand:SI 0 “register_operand” “=r”) (plus:SI (lshiftrt:SI (match_operand:SI 1 “register_operand” “r”) (const_int 16)) (zero_extend:SI (match_operand:HI 2 “register_operand” “0”))))] “TARGET_H8300H || TARGET_H8300S” “add.w\t%e1,%f0;xor.w\t%e0,%e0;rotxl.w\t%e0” [(set_attr “cc” “clobber”) (set_attr “length” “6”)])

(define_insn_and_split “*addsi3_and_r_1” [(set (match_operand:SI 0 “register_operand” “=r”) (plus:SI (and:SI (match_operand:SI 1 “register_operand” “r”) (const_int 1)) (match_operand:SI 2 “register_operand” “0”)))] “(TARGET_H8300H || TARGET_H8300S)” “#” “&& reload_completed” [(set (cc0) (zero_extract:SI (match_dup 1) (const_int 1) (const_int 0))) (set (pc) (if_then_else (eq (cc0) (const_int 0)) (label_ref (match_dup 3)) (pc))) (set (match_dup 2) (plus:SI (match_dup 2) (const_int 1))) (match_dup 3)] “operands[3] = gen_label_rtx ();”)

(define_insn_and_split “*addsi3_and_not_r_1” [(set (match_operand:SI 0 “register_operand” “=r”) (plus:SI (and:SI (not:SI (match_operand:SI 1 “register_operand” “r”)) (const_int 1)) (match_operand:SI 2 “register_operand” “0”)))] “(TARGET_H8300H || TARGET_H8300S)” “#” “&& reload_completed” [(set (cc0) (zero_extract:SI (match_dup 1) (const_int 1) (const_int 0))) (set (pc) (if_then_else (ne (cc0) (const_int 0)) (label_ref (match_dup 3)) (pc))) (set (match_dup 2) (plus:SI (match_dup 2) (const_int 1))) (match_dup 3)] “operands[3] = gen_label_rtx ();”)

;; [ix]or:HI

(define_insn “*ixorhi3_zext” [(set (match_operand:HI 0 “register_operand” “=r”) (match_operator:HI 1 “iorxor_operator” [(zero_extend:HI (match_operand:QI 2 “register_operand” “r”)) (match_operand:HI 3 “register_operand” “0”)]))] "" “%c1.b\t%X2,%s0” [(set_attr “cc” “clobber”) (set_attr “length” “2”)])

;; [ix]or:SI

(define_insn “*ixorsi3_zext_qi” [(set (match_operand:SI 0 “register_operand” “=r”) (match_operator:SI 1 “iorxor_operator” [(zero_extend:SI (match_operand:QI 2 “register_operand” “r”)) (match_operand:SI 3 “register_operand” “0”)]))] "" “%c1.b\t%X2,%w0” [(set_attr “cc” “clobber”) (set_attr “length” “2”)])

(define_insn “*ixorsi3_zext_hi” [(set (match_operand:SI 0 “register_operand” “=r”) (match_operator:SI 1 “iorxor_operator” [(zero_extend:SI (match_operand:HI 2 “register_operand” “r”)) (match_operand:SI 3 “register_operand” “0”)]))] “TARGET_H8300H || TARGET_H8300S” “%c1.w\t%T2,%f0” [(set_attr “cc” “clobber”) (set_attr “length” “2”)])

(define_insn “*ixorsi3_ashift_16” [(set (match_operand:SI 0 “register_operand” “=r”) (match_operator:SI 1 “iorxor_operator” [(ashift:SI (match_operand:SI 2 “register_operand” “r”) (const_int 16)) (match_operand:SI 3 “register_operand” “0”)]))] “TARGET_H8300H || TARGET_H8300S” “%c1.w\t%f2,%e0” [(set_attr “cc” “clobber”) (set_attr “length” “2”)])

(define_insn “*ixorsi3_lshiftrt_16” [(set (match_operand:SI 0 “register_operand” “=r”) (match_operator:SI 1 “iorxor_operator” [(lshiftrt:SI (match_operand:SI 2 “register_operand” “r”) (const_int 16)) (match_operand:SI 3 “register_operand” “0”)]))] “TARGET_H8300H || TARGET_H8300S” “%c1.w\t%e2,%f0” [(set_attr “cc” “clobber”) (set_attr “length” “2”)])

;; ior:HI

(define_insn “*iorhi3_ashift_8” [(set (match_operand:HI 0 “register_operand” “=r”) (ior:HI (ashift:HI (match_operand:HI 1 “register_operand” “r”) (const_int 8)) (match_operand:HI 2 “register_operand” “0”)))] "" “or.b\t%s1,%t0” [(set_attr “cc” “clobber”) (set_attr “length” “2”)])

(define_insn “*iorhi3_lshiftrt_8” [(set (match_operand:HI 0 “register_operand” “=r”) (ior:HI (lshiftrt:HI (match_operand:HI 1 “register_operand” “r”) (const_int 8)) (match_operand:HI 2 “register_operand” “0”)))] "" “or.b\t%t1,%s0” [(set_attr “cc” “clobber”) (set_attr “length” “2”)])

(define_insn “*iorhi3_two_qi” [(set (match_operand:HI 0 “register_operand” “=r”) (ior:HI (zero_extend:HI (match_operand:QI 1 “register_operand” “0”)) (ashift:HI (match_operand:HI 2 “register_operand” “r”) (const_int 8))))] "" “mov.b\t%s2,%t0” [(set_attr “cc” “clobber”) (set_attr “length” “2”)])

(define_insn “*iorhi3_two_qi_mem” [(set (match_operand:HI 0 “register_operand” “=&r”) (ior:HI (zero_extend:HI (match_operand:QI 1 “memory_operand” “m”)) (ashift:HI (subreg:HI (match_operand:QI 2 “memory_operand” “m”) 0) (const_int 8))))] "" “mov.b\t%X2,%t0;mov.b\t%X1,%s0” [(set_attr “cc” “clobber”) (set_attr “length” “16”)])

(define_split [(set (match_operand:HI 0 “register_operand” "") (ior:HI (zero_extend:HI (match_operand:QI 1 “memory_operand” "")) (ashift:HI (subreg:HI (match_operand:QI 2 “memory_operand” "") 0) (const_int 8))))] “(TARGET_H8300H || TARGET_H8300S) && reload_completed && byte_accesses_mergeable_p (XEXP (operands[2], 0), XEXP (operands[1], 0))” [(set (match_dup 0) (match_dup 3))] “operands[3] = gen_rtx_MEM (HImode, XEXP (operands[2], 0));”)

;; ior:SI

(define_insn “*iorsi3_two_hi” [(set (match_operand:SI 0 “register_operand” “=r”) (ior:SI (zero_extend:SI (match_operand:HI 1 “register_operand” “0”)) (ashift:SI (match_operand:SI 2 “register_operand” “r”) (const_int 16))))] “TARGET_H8300H || TARGET_H8300S” “mov.w\t%f2,%e0” [(set_attr “cc” “clobber”) (set_attr “length” “2”)])

(define_insn_and_split “*iorsi3_two_qi_zext” [(set (match_operand:SI 0 “register_operand” “=&r”) (ior:SI (zero_extend:SI (match_operand:QI 1 “memory_operand” “m”))

	(and:SI (ashift:SI (subreg:SI (match_operand:QI 2 "memory_operand" "m") 0)
			   (const_int 8))
		(const_int 65280))))]

“(TARGET_H8300H || TARGET_H8300S)” “#” “&& reload_completed” [(set (match_dup 3) (ior:HI (zero_extend:HI (match_dup 1)) (ashift:HI (subreg:HI (match_dup 2) 0) (const_int 8)))) (set (match_dup 0) (zero_extend:SI (match_dup 3)))] “operands[3] = gen_rtx_REG (HImode, REGNO (operands[0]));”)

(define_insn “*iorsi3_e2f” [(set (match_operand:SI 0 “register_operand” “=r”) (ior:SI (and:SI (match_operand:SI 1 “register_operand” “0”) (const_int -65536)) (lshiftrt:SI (match_operand:SI 2 “register_operand” “r”) (const_int 16))))] “TARGET_H8300H || TARGET_H8300S” “mov.w\t%e2,%f0” [(set_attr “length” “2”) (set_attr “cc” “clobber”)])

(define_insn_and_split “*iorsi3_two_qi_sext” [(set (match_operand:SI 0 “register_operand” “=r”) (ior:SI (zero_extend:SI (match_operand:QI 1 “register_operand” “0”)) (ashift:SI (sign_extend:SI (match_operand:QI 2 “register_operand” “r”)) (const_int 8))))] “(TARGET_H8300H || TARGET_H8300S)” “#” “&& reload_completed” [(set (match_dup 3) (ior:HI (zero_extend:HI (match_dup 1)) (ashift:HI (match_dup 4) (const_int 8)))) (set (match_dup 0) (sign_extend:SI (match_dup 3)))] “operands[3] = gen_rtx_REG (HImode, REGNO (operands[0])); operands[4] = gen_rtx_REG (HImode, REGNO (operands[2]));”)

(define_insn “*iorsi3_w” [(set (match_operand:SI 0 “register_operand” “=r,&r”) (ior:SI (and:SI (match_operand:SI 1 “register_operand” “0,0”) (const_int -256)) (zero_extend:SI (match_operand:QI 2 “general_operand_src” “r,g>”))))] “TARGET_H8300H || TARGET_H8300S” “mov.b\t%X2,%w0” [(set_attr “length” “2,8”) (set_attr “cc” “clobber,clobber”)])

(define_insn “*iorsi3_ashift_31” [(set (match_operand:SI 0 “register_operand” “=&r”) (ior:SI (ashift:SI (match_operand:SI 1 “register_operand” “r”) (const_int 31)) (match_operand:SI 2 “register_operand” “0”)))] “TARGET_H8300H || TARGET_H8300S” “rotxl.l\t%S0;bor\t#0,%w1;rotxr.l\t%S0” [(set_attr “length” “6”) (set_attr “cc” “set_znv”)])

(define_insn “*iorsi3_and_ashift” [(set (match_operand:SI 0 “register_operand” “=r”) (ior:SI (and:SI (ashift:SI (match_operand:SI 1 “register_operand” “r”) (match_operand:SI 2 “const_int_operand” “n”)) (match_operand:SI 3 “single_one_operand” “n”)) (match_operand:SI 4 “register_operand” “0”)))] “(TARGET_H8300H || TARGET_H8300S) && (INTVAL (operands[3]) & ~0xffff) == 0” “* { rtx srcpos = GEN_INT (exact_log2 (INTVAL (operands[3])) - INTVAL (operands[2])); rtx dstpos = GEN_INT (exact_log2 (INTVAL (operands[3]))); operands[2] = srcpos; operands[3] = dstpos; return "bld\t%Z2,%Y1;bor\t%Z3,%Y0;bst\t%Z3,%Y0"; }” [(set_attr “length” “6”) (set_attr “cc” “clobber”)])

(define_insn “*iorsi3_and_lshiftrt” [(set (match_operand:SI 0 “register_operand” “=r”) (ior:SI (and:SI (lshiftrt:SI (match_operand:SI 1 “register_operand” “r”) (match_operand:SI 2 “const_int_operand” “n”)) (match_operand:SI 3 “single_one_operand” “n”)) (match_operand:SI 4 “register_operand” “0”)))] “(TARGET_H8300H || TARGET_H8300S) && ((INTVAL (operands[3]) << INTVAL (operands[2])) & ~0xffff) == 0” “* { rtx srcpos = GEN_INT (exact_log2 (INTVAL (operands[3])) + INTVAL (operands[2])); rtx dstpos = GEN_INT (exact_log2 (INTVAL (operands[3]))); operands[2] = srcpos; operands[3] = dstpos; return "bld\t%Z2,%Y1;bor\t%Z3,%Y0;bst\t%Z3,%Y0"; }” [(set_attr “length” “6”) (set_attr “cc” “clobber”)])

(define_insn “*iorsi3_zero_extract” [(set (match_operand:SI 0 “register_operand” “=r”) (ior:SI (zero_extract:SI (match_operand:SI 1 “register_operand” “r”) (const_int 1) (match_operand:SI 2 “const_int_operand” “n”)) (match_operand:SI 3 “register_operand” “0”)))] “(TARGET_H8300H || TARGET_H8300S) && INTVAL (operands[2]) < 16” “bld\t%Z2,%Y1;bor\t#0,%w0;bst\t#0,%w0” [(set_attr “length” “6”) (set_attr “cc” “clobber”)])

(define_insn “*iorsi3_and_lshiftrt_n_sb” [(set (match_operand:SI 0 “register_operand” “=r”) (ior:SI (and:SI (lshiftrt:SI (match_operand:SI 1 “register_operand” “r”) (const_int 30)) (const_int 2)) (match_operand:SI 2 “register_operand” “0”)))] “(TARGET_H8300H || TARGET_H8300S)” “rotl.l\t%S1;rotr.l\t%S1;bor\t#1,%w0;bst\t#1,%w0” [(set_attr “length” “8”) (set_attr “cc” “clobber”)])

(define_insn “*iorsi3_and_lshiftrt_9_sb” [(set (match_operand:SI 0 “register_operand” “=r”) (ior:SI (and:SI (lshiftrt:SI (match_operand:SI 1 “register_operand” “r”) (const_int 9)) (const_int 4194304)) (match_operand:SI 2 “register_operand” “0”))) (clobber (match_scratch:HI 3 “=&r”))] “(TARGET_H8300H || TARGET_H8300S)” “* { if (find_regno_note (insn, REG_DEAD, REGNO (operands[1]))) return "shll.l\t%S1;xor.w\t%T3,%T3;bst\t#6,%s3;or.w\t%T3,%e0"; else return "rotl.l\t%S1;rotr.l\t%S1;xor.w\t%T3,%T3;bst\t#6,%s3;or.w\t%T3,%e0"; }” [(set_attr “length” “10”) (set_attr “cc” “clobber”)])

;; Used to OR the exponent of a float.

(define_insn “*iorsi3_shift” [(set (match_operand:SI 0 “register_operand” “=r”) (ior:SI (ashift:SI (match_operand:SI 1 “register_operand” “r”) (const_int 23)) (match_operand:SI 2 “register_operand” “0”))) (clobber (match_scratch:SI 3 “=&r”))] “TARGET_H8300H || TARGET_H8300S” “#”)

(define_split [(parallel [(set (match_operand:SI 0 “register_operand” "") (ior:SI (ashift:SI (match_operand:SI 1 “register_operand” "") (const_int 23)) (match_dup 0))) (clobber (match_operand:SI 2 “register_operand” ""))])] “(TARGET_H8300H || TARGET_H8300S) && flow2_completed && find_regno_note (insn, REG_DEAD, REGNO (operands[1])) && REGNO (operands[0]) != REGNO (operands[1])” [(parallel [(set (match_dup 3) (ashift:HI (match_dup 3) (const_int 7))) (clobber (scratch:QI))]) (set (match_dup 0) (ior:SI (ashift:SI (match_dup 1) (const_int 16)) (match_dup 0)))] “operands[3] = gen_rtx_REG (HImode, REGNO (operands[1]));”)

(define_split [(parallel [(set (match_operand:SI 0 “register_operand” "") (ior:SI (ashift:SI (match_operand:SI 1 “register_operand” "") (const_int 23)) (match_dup 0))) (clobber (match_operand:SI 2 “register_operand” ""))])] “(TARGET_H8300H || TARGET_H8300S) && flow2_completed && !(find_regno_note (insn, REG_DEAD, REGNO (operands[1])) && REGNO (operands[0]) != REGNO (operands[1]))” [(set (match_dup 2) (match_dup 1)) (parallel [(set (match_dup 3) (ashift:HI (match_dup 3) (const_int 7))) (clobber (scratch:QI))]) (set (match_dup 0) (ior:SI (ashift:SI (match_dup 2) (const_int 16)) (match_dup 0)))] “operands[3] = gen_rtx_REG (HImode, REGNO (operands[2]));”)

(define_insn “*iorsi2_and_1_lshiftrt_1” [(set (match_operand:SI 0 “register_operand” “=r”) (ior:SI (and:SI (match_operand:SI 1 “register_operand” “0”) (const_int 1)) (lshiftrt:SI (match_dup 1) (const_int 1))))] “TARGET_H8300H || TARGET_H8300S” “shlr.l\t%S0;bor\t#0,%w0;bst\t#0,%w0” [(set_attr “length” “6”) (set_attr “cc” “clobber”)])

(define_insn_and_split “*iorsi3_ashift_16_ashift_24” [(set (match_operand:SI 0 “register_operand” “=r”) (ior:SI (ashift:SI (match_operand:SI 1 “register_operand” “0”) (const_int 16)) (ashift:SI (match_operand:SI 2 “register_operand” “r”) (const_int 24))))] “(TARGET_H8300H || TARGET_H8300S)” “#” “&& reload_completed” [(set (match_dup 3) (ior:HI (ashift:HI (match_dup 4) (const_int 8)) (match_dup 3))) (parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (const_int 16))) (clobber (scratch:QI))])] “operands[3] = gen_rtx_REG (HImode, REGNO (operands[0])); operands[4] = gen_rtx_REG (HImode, REGNO (operands[2]));”)

(define_insn_and_split “*iorsi3_ashift_16_ashift_24_mem” [(set (match_operand:SI 0 “register_operand” “=&r”) (ior:SI (and:SI (ashift:SI (subreg:SI (match_operand:QI 1 “memory_operand” “m”) 0) (const_int 16)) (const_int 16711680)) (ashift:SI (subreg:SI (match_operand:QI 2 “memory_operand” “m”) 0) (const_int 24))))] “(TARGET_H8300H || TARGET_H8300S)” “#” “&& reload_completed” [(set (match_dup 3) (ior:HI (zero_extend:HI (match_dup 1)) (ashift:HI (subreg:HI (match_dup 2) 0) (const_int 8)))) (parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (const_int 16))) (clobber (scratch:QI))])] “operands[3] = gen_rtx_REG (HImode, REGNO (operands[0]));”)

;; Used to add the exponent of a float.

(define_insn “*addsi3_shift” [(set (match_operand:SI 0 “register_operand” “=r”) (plus:SI (mult:SI (match_operand:SI 1 “register_operand” “r”) (const_int 8388608)) (match_operand:SI 2 “register_operand” “0”))) (clobber (match_scratch:SI 3 “=&r”))] “TARGET_H8300H || TARGET_H8300S” “#”)

(define_split [(parallel [(set (match_operand:SI 0 “register_operand” "") (plus:SI (mult:SI (match_operand:SI 1 “register_operand” "") (const_int 8388608)) (match_dup 0))) (clobber (match_operand:SI 2 “register_operand” ""))])] “(TARGET_H8300H || TARGET_H8300S) && flow2_completed && find_regno_note (insn, REG_DEAD, REGNO (operands[1])) && REGNO (operands[0]) != REGNO (operands[1])” [(parallel [(set (match_dup 3) (ashift:HI (match_dup 3) (const_int 7))) (clobber (scratch:QI))]) (set (match_dup 0) (plus:SI (mult:SI (match_dup 1) (const_int 65536)) (match_dup 0)))] “operands[3] = gen_rtx_REG (HImode, REGNO (operands[1]));”)

(define_split [(parallel [(set (match_operand:SI 0 “register_operand” "") (plus:SI (mult:SI (match_operand:SI 1 “register_operand” "") (const_int 8388608)) (match_dup 0))) (clobber (match_operand:SI 2 “register_operand” ""))])] “(TARGET_H8300H || TARGET_H8300S) && flow2_completed && !(find_regno_note (insn, REG_DEAD, REGNO (operands[1])) && REGNO (operands[0]) != REGNO (operands[1]))” [(set (match_dup 2) (match_dup 1)) (parallel [(set (match_dup 3) (ashift:HI (match_dup 3) (const_int 7))) (clobber (scratch:QI))]) (set (match_dup 0) (plus:SI (mult:SI (match_dup 2) (const_int 65536)) (match_dup 0)))] “operands[3] = gen_rtx_REG (HImode, REGNO (operands[2]));”)

;; ashift:SI

(define_insn_and_split “*ashiftsi_sextqi_7” [(set (match_operand:SI 0 “register_operand” “=r”) (ashift:SI (sign_extend:SI (match_operand:QI 1 “register_operand” “0”)) (const_int 7)))] “(TARGET_H8300H || TARGET_H8300S)” “#” “&& reload_completed” [(parallel [(set (match_dup 2) (ashift:HI (match_dup 2) (const_int 8))) (clobber (scratch:QI))]) (set (match_dup 0) (sign_extend:SI (match_dup 2))) (parallel [(set (match_dup 0) (ashiftrt:SI (match_dup 0) (const_int 1))) (clobber (scratch:QI))])] “operands[2] = gen_rtx_REG (HImode, REGNO (operands[0]));”)

;; Storing a part of HImode to QImode.

(define_insn "" [(set (match_operand:QI 0 “general_operand_dst” “=rm<”) (subreg:QI (lshiftrt:HI (match_operand:HI 1 “register_operand” “r”) (const_int 8)) 1))] "" “mov.b\t%t1,%R0” [(set_attr “cc” “set_znv”) (set_attr “length” “8”)])

;; Storing a part of SImode to QImode.

(define_insn "" [(set (match_operand:QI 0 “general_operand_dst” “=rm<”) (subreg:QI (lshiftrt:SI (match_operand:SI 1 “register_operand” “r”) (const_int 8)) 3))] "" “mov.b\t%x1,%R0” [(set_attr “cc” “set_znv”) (set_attr “length” “8”)])

(define_insn "" [(set (match_operand:QI 0 “general_operand_dst” “=rm<”) (subreg:QI (lshiftrt:SI (match_operand:SI 1 “register_operand” “r”) (const_int 16)) 3)) (clobber (match_scratch:SI 2 “=&r”))] “TARGET_H8300H || TARGET_H8300S” “mov.w\t%e1,%f2;mov.b\t%w2,%R0” [(set_attr “cc” “set_znv”) (set_attr “length” “10”)])

(define_insn "" [(set (match_operand:QI 0 “general_operand_dst” “=rm<”) (subreg:QI (lshiftrt:SI (match_operand:SI 1 “register_operand” “r”) (const_int 24)) 3)) (clobber (match_scratch:SI 2 “=&r”))] “TARGET_H8300H || TARGET_H8300S” “mov.w\t%e1,%f2;mov.b\t%x2,%R0” [(set_attr “cc” “set_znv”) (set_attr “length” “10”)])

(define_insn_and_split "" [(set (pc) (if_then_else (eq (zero_extract:SI (subreg:SI (match_operand:QI 0 “register_operand” "") 0) (const_int 1) (const_int 7)) (const_int 0)) (label_ref (match_operand 1 "" "")) (pc)))] "" “#” "" [(set (cc0) (match_dup 0)) (set (pc) (if_then_else (ge (cc0) (const_int 0)) (label_ref (match_dup 1)) (pc)))] "")

(define_insn_and_split "" [(set (pc) (if_then_else (ne (zero_extract:SI (subreg:SI (match_operand:QI 0 “register_operand” "") 0) (const_int 1) (const_int 7)) (const_int 0)) (label_ref (match_operand 1 "" "")) (pc)))] "" “#” "" [(set (cc0) (match_dup 0)) (set (pc) (if_then_else (lt (cc0) (const_int 0)) (label_ref (match_dup 1)) (pc)))] "") ;; ----------------------------------------------------------------- ;; PEEPHOLE PATTERNS ;; -----------------------------------------------------------------

;; Convert (A >> B) & C to (A & 255) >> B if C == 255 >> B.

(define_peephole2 [(parallel [(set (match_operand:HI 0 “register_operand” "") (lshiftrt:HI (match_dup 0) (match_operand:HI 1 “const_int_operand” ""))) (clobber (match_operand:HI 2 "" ""))]) (set (match_dup 0) (and:HI (match_dup 0) (match_operand:HI 3 “const_int_operand” "")))] “INTVAL (operands[3]) == (255 >> INTVAL (operands[1]))” [(set (match_dup 0) (and:HI (match_dup 0) (const_int 255))) (parallel [(set (match_dup 0) (lshiftrt:HI (match_dup 0) (match_dup 1))) (clobber (match_dup 2))])] "")

;; Convert (A << B) & C to (A & 255) << B if C == 255 << B.

(define_peephole2 [(parallel [(set (match_operand:HI 0 “register_operand” "") (ashift:HI (match_dup 0) (match_operand:HI 1 “const_int_operand” ""))) (clobber (match_operand:HI 2 "" ""))]) (set (match_dup 0) (and:HI (match_dup 0) (match_operand:HI 3 “const_int_operand” "")))] “INTVAL (operands[3]) == (255 << INTVAL (operands[1]))” [(set (match_dup 0) (and:HI (match_dup 0) (const_int 255))) (parallel [(set (match_dup 0) (ashift:HI (match_dup 0) (match_dup 1))) (clobber (match_dup 2))])] "")

;; Convert (A >> B) & C to (A & 255) >> B if C == 255 >> B.

(define_peephole2 [(parallel [(set (match_operand:SI 0 “register_operand” "") (lshiftrt:SI (match_dup 0) (match_operand:SI 1 “const_int_operand” ""))) (clobber (match_operand:SI 2 "" ""))]) (set (match_dup 0) (and:SI (match_dup 0) (match_operand:SI 3 “const_int_operand” "")))] “INTVAL (operands[3]) == (255 >> INTVAL (operands[1]))” [(set (match_dup 0) (and:SI (match_dup 0) (const_int 255))) (parallel [(set (match_dup 0) (lshiftrt:SI (match_dup 0) (match_dup 1))) (clobber (match_dup 2))])] "")

;; Convert (A << B) & C to (A & 255) << B if C == 255 << B.

(define_peephole2 [(parallel [(set (match_operand:SI 0 “register_operand” "") (ashift:SI (match_dup 0) (match_operand:SI 1 “const_int_operand” ""))) (clobber (match_operand:SI 2 "" ""))]) (set (match_dup 0) (and:SI (match_dup 0) (match_operand:SI 3 “const_int_operand” "")))] “INTVAL (operands[3]) == (255 << INTVAL (operands[1]))” [(set (match_dup 0) (and:SI (match_dup 0) (const_int 255))) (parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 1))) (clobber (match_dup 2))])] "")

;; Convert (A >> B) & C to (A & 65535) >> B if C == 65535 >> B.

(define_peephole2 [(parallel [(set (match_operand:SI 0 “register_operand” "") (lshiftrt:SI (match_dup 0) (match_operand:SI 1 “const_int_operand” ""))) (clobber (match_operand:SI 2 "" ""))]) (set (match_dup 0) (and:SI (match_dup 0) (match_operand:SI 3 “const_int_operand” "")))] “INTVAL (operands[3]) == (65535 >> INTVAL (operands[1]))” [(set (match_dup 0) (and:SI (match_dup 0) (const_int 65535))) (parallel [(set (match_dup 0) (lshiftrt:SI (match_dup 0) (match_dup 1))) (clobber (match_dup 2))])] "")

;; Convert (A << B) & C to (A & 65535) << B if C == 65535 << B.

(define_peephole2 [(parallel [(set (match_operand:SI 0 “register_operand” "") (ashift:SI (match_dup 0) (match_operand:SI 1 “const_int_operand” ""))) (clobber (match_operand:SI 2 "" ""))]) (set (match_dup 0) (and:SI (match_dup 0) (match_operand:SI 3 “const_int_operand” "")))] “INTVAL (operands[3]) == (65535 << INTVAL (operands[1]))” [(set (match_dup 0) (and:SI (match_dup 0) (const_int 65535))) (parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 1))) (clobber (match_dup 2))])] "")

;; Convert a QImode push into an SImode push so that the ;; define_peephole2 below can cram multiple pushes into one stm.l.

(define_peephole2 [(parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4))) (set (mem:QI (plus:SI (reg:SI SP_REG) (const_int -3))) (match_operand:QI 0 “register_operand” ""))])] “TARGET_H8300S && !TARGET_NORMAL_MODE” [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))] “operands[0] = gen_rtx_REG (SImode, REGNO (operands[0]));”)

(define_peephole2 [(parallel [(set (reg:HI SP_REG) (plus:HI (reg:HI SP_REG) (const_int -4))) (set (mem:QI (plus:HI (reg:HI SP_REG) (const_int -3))) (match_operand:QI 0 “register_operand” ""))])] “TARGET_H8300S && TARGET_NORMAL_MODE” [(set (mem:SI (pre_dec:HI (reg:HI SP_REG))) (match_dup 0))] “operands[0] = gen_rtx_REG (SImode, REGNO (operands[0]));”)

;; Convert a HImode push into an SImode push so that the ;; define_peephole2 below can cram multiple pushes into one stm.l.

(define_peephole2 [(parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4))) (set (mem:HI (plus:SI (reg:SI SP_REG) (const_int -2))) (match_operand:HI 0 “register_operand” ""))])] “TARGET_H8300S && !TARGET_NORMAL_MODE” [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))] “operands[0] = gen_rtx_REG (SImode, REGNO (operands[0]));”)

(define_peephole2 [(parallel [(set (reg:HI SP_REG) (plus:HI (reg:HI SP_REG) (const_int -4))) (set (mem:HI (plus:HI (reg:HI SP_REG) (const_int -2))) (match_operand:HI 0 “register_operand” ""))])] “TARGET_H8300S && TARGET_NORMAL_MODE” [(set (mem:SI (pre_dec:HI (reg:HI SP_REG))) (match_dup 0))] “operands[0] = gen_rtx_REG (SImode, REGNO (operands[0]));”)

;; Cram four pushes into stm.l.

(define_peephole2 [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_operand:SI 0 “register_operand” "")) (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_operand:SI 1 “register_operand” "")) (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_operand:SI 2 “register_operand” "")) (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_operand:SI 3 “register_operand” ""))] “TARGET_H8300S && !TARGET_NORMAL_MODE && REGNO (operands[0]) == 0 && REGNO (operands[1]) == 1 && REGNO (operands[2]) == 2 && REGNO (operands[3]) == 3” [(parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -16))) (set (mem:SI (plus:SI (reg:SI SP_REG) (const_int -4))) (match_dup 0)) (set (mem:SI (plus:SI (reg:SI SP_REG) (const_int -8))) (match_dup 1)) (set (mem:SI (plus:SI (reg:SI SP_REG) (const_int -12))) (match_dup 2)) (set (mem:SI (plus:SI (reg:SI SP_REG) (const_int -16))) (match_dup 3))])] "")

(define_peephole2 [(set (mem:SI (pre_dec:HI (reg:HI SP_REG))) (match_operand:SI 0 “register_operand” "")) (set (mem:SI (pre_dec:HI (reg:HI SP_REG))) (match_operand:SI 1 “register_operand” "")) (set (mem:SI (pre_dec:HI (reg:HI SP_REG))) (match_operand:SI 2 “register_operand” "")) (set (mem:SI (pre_dec:HI (reg:HI SP_REG))) (match_operand:SI 3 “register_operand” ""))] “TARGET_H8300S && TARGET_NORMAL_MODE && REGNO (operands[0]) == 0 && REGNO (operands[1]) == 1 && REGNO (operands[2]) == 2 && REGNO (operands[3]) == 3” [(parallel [(set (reg:HI SP_REG) (plus:HI (reg:HI SP_REG) (const_int -16))) (set (mem:SI (plus:HI (reg:HI SP_REG) (const_int -4))) (match_dup 0)) (set (mem:SI (plus:HI (reg:HI SP_REG) (const_int -8))) (match_dup 1)) (set (mem:SI (plus:HI (reg:HI SP_REG) (const_int -12))) (match_dup 2)) (set (mem:SI (plus:HI (reg:HI SP_REG) (const_int -16))) (match_dup 3))])] "")

;; Cram three pushes into stm.l.

(define_peephole2 [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_operand:SI 0 “register_operand” "")) (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_operand:SI 1 “register_operand” "")) (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_operand:SI 2 “register_operand” ""))] “TARGET_H8300S && !TARGET_NORMAL_MODE && ((REGNO (operands[0]) == 0 && REGNO (operands[1]) == 1 && REGNO (operands[2]) == 2) || (REGNO (operands[0]) == 4 && REGNO (operands[1]) == 5 && REGNO (operands[2]) == 6))” [(parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -12))) (set (mem:SI (plus:SI (reg:SI SP_REG) (const_int -4))) (match_dup 0)) (set (mem:SI (plus:SI (reg:SI SP_REG) (const_int -8))) (match_dup 1)) (set (mem:SI (plus:SI (reg:SI SP_REG) (const_int -12))) (match_dup 2))])] "")

(define_peephole2 [(set (mem:SI (pre_dec:HI (reg:HI SP_REG))) (match_operand:SI 0 “register_operand” "")) (set (mem:SI (pre_dec:HI (reg:HI SP_REG))) (match_operand:SI 1 “register_operand” "")) (set (mem:SI (pre_dec:HI (reg:HI SP_REG))) (match_operand:SI 2 “register_operand” ""))] “TARGET_H8300S && TARGET_NORMAL_MODE && ((REGNO (operands[0]) == 0 && REGNO (operands[1]) == 1 && REGNO (operands[2]) == 2) || (REGNO (operands[0]) == 4 && REGNO (operands[1]) == 5 && REGNO (operands[2]) == 6))” [(parallel [(set (reg:HI SP_REG) (plus:HI (reg:HI SP_REG) (const_int -12))) (set (mem:SI (plus:HI (reg:HI SP_REG) (const_int -4))) (match_dup 0)) (set (mem:SI (plus:HI (reg:HI SP_REG) (const_int -8))) (match_dup 1)) (set (mem:SI (plus:HI (reg:HI SP_REG) (const_int -12))) (match_dup 2))])] "")

;; Cram two pushes into stm.l.

(define_peephole2 [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_operand:SI 0 “register_operand” "")) (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_operand:SI 1 “register_operand” ""))] “TARGET_H8300S && !TARGET_NORMAL_MODE && ((REGNO (operands[0]) == 0 && REGNO (operands[1]) == 1) || (REGNO (operands[0]) == 2 && REGNO (operands[1]) == 3) || (REGNO (operands[0]) == 4 && REGNO (operands[1]) == 5))” [(parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8))) (set (mem:SI (plus:SI (reg:SI SP_REG) (const_int -4))) (match_dup 0)) (set (mem:SI (plus:SI (reg:SI SP_REG) (const_int -8))) (match_dup 1))])] "")

(define_peephole2 [(set (mem:SI (pre_dec:HI (reg:HI SP_REG))) (match_operand:SI 0 “register_operand” "")) (set (mem:SI (pre_dec:HI (reg:HI SP_REG))) (match_operand:SI 1 “register_operand” ""))] “TARGET_H8300S && TARGET_NORMAL_MODE && ((REGNO (operands[0]) == 0 && REGNO (operands[1]) == 1) || (REGNO (operands[0]) == 2 && REGNO (operands[1]) == 3) || (REGNO (operands[0]) == 4 && REGNO (operands[1]) == 5))” [(parallel [(set (reg:HI SP_REG) (plus:HI (reg:HI SP_REG) (const_int -8))) (set (mem:SI (plus:HI (reg:HI SP_REG) (const_int -4))) (match_dup 0)) (set (mem:SI (plus:HI (reg:HI SP_REG) (const_int -8))) (match_dup 1))])] "")

;; Turn ;; ;; mov.w #2,r0 ;; add.w r7,r0 (6 bytes) ;; ;; into ;; ;; mov.w r7,r0 ;; adds #2,r0 (4 bytes)

(define_peephole2 [(set (match_operand:HI 0 “register_operand” "") (match_operand:HI 1 “const_int_operand” "")) (set (match_dup 0) (plus:HI (match_dup 0) (match_operand:HI 2 “register_operand” "")))] “REG_P (operands[0]) && REG_P (operands[2]) && REGNO (operands[0]) != REGNO (operands[2]) && (CONST_OK_FOR_J (INTVAL (operands[1])) || CONST_OK_FOR_L (INTVAL (operands[1])) || CONST_OK_FOR_N (INTVAL (operands[1])))” [(set (match_dup 0) (match_dup 2)) (set (match_dup 0) (plus:HI (match_dup 0) (match_dup 1)))] "")

;; Turn ;; ;; sub.l er0,er0 ;; add.b #4,r0l ;; add.l er7,er0 (6 bytes) ;; ;; into ;; ;; mov.l er7,er0 ;; adds #4,er0 (4 bytes)

(define_peephole2 [(set (match_operand:SI 0 “register_operand” "") (match_operand:SI 1 “const_int_operand” "")) (set (match_dup 0) (plus:SI (match_dup 0) (match_operand:SI 2 “register_operand” "")))] “(TARGET_H8300H || TARGET_H8300S) && REG_P (operands[0]) && REG_P (operands[2]) && REGNO (operands[0]) != REGNO (operands[2]) && (CONST_OK_FOR_L (INTVAL (operands[1])) || CONST_OK_FOR_N (INTVAL (operands[1])))” [(set (match_dup 0) (match_dup 2)) (set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))] "")

;; Turn ;; ;; mov.l er7,er0 ;; add.l #10,er0 (takes 8 bytes) ;; ;; into ;; ;; sub.l er0,er0 ;; add.b #10,r0l ;; add.l er7,er0 (takes 6 bytes)

(define_peephole2 [(set (match_operand:SI 0 “register_operand” "") (match_operand:SI 1 “register_operand” "")) (set (match_dup 0) (plus:SI (match_dup 0) (match_operand:SI 2 “const_int_operand” "")))] “(TARGET_H8300H || TARGET_H8300S) && REG_P (operands[0]) && REG_P (operands[1]) && REGNO (operands[0]) != REGNO (operands[1]) && !CONST_OK_FOR_L (INTVAL (operands[2])) && !CONST_OK_FOR_N (INTVAL (operands[2])) && ((INTVAL (operands[2]) & 0xff) == INTVAL (operands[2]) || (INTVAL (operands[2]) & 0xff00) == INTVAL (operands[2]) || INTVAL (operands[2]) == 0xffff || INTVAL (operands[2]) == 0xfffe)” [(set (match_dup 0) (match_dup 2)) (set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))] "")

;; Turn ;; ;; subs #1,er4 ;; mov.w r4,r4 ;; bne .L2028 ;; ;; into ;; ;; dec.w #1,r4 ;; bne .L2028

(define_peephole2 [(set (match_operand:HI 0 “register_operand” "") (plus:HI (match_dup 0) (match_operand 1 “incdec_operand” ""))) (set (cc0) (match_dup 0)) (set (pc) (if_then_else (match_operator 3 “eqne_operator” [(cc0) (const_int 0)]) (label_ref (match_operand 2 "" "")) (pc)))] “TARGET_H8300H || TARGET_H8300S” [(set (match_operand:HI 0 “register_operand” "") (unspec:HI [(match_dup 0) (match_dup 1)] UNSPEC_INCDEC)) (set (cc0) (match_dup 0)) (set (pc) (if_then_else (match_op_dup 3 [(cc0) (const_int 0)]) (label_ref (match_dup 2)) (pc)))] "")

;; The SImode version of the previous pattern.

(define_peephole2 [(set (match_operand:SI 0 “register_operand” "") (plus:SI (match_dup 0) (match_operand 1 “incdec_operand” ""))) (set (cc0) (match_dup 0)) (set (pc) (if_then_else (match_operator 3 “eqne_operator” [(cc0) (const_int 0)]) (label_ref (match_operand 2 "" "")) (pc)))] “TARGET_H8300H || TARGET_H8300S” [(set (match_operand:SI 0 “register_operand” "") (unspec:SI [(match_dup 0) (match_dup 1)] UNSPEC_INCDEC)) (set (cc0) (match_dup 0)) (set (pc) (if_then_else (match_op_dup 3 [(cc0) (const_int 0)]) (label_ref (match_dup 2)) (pc)))] "")

(define_peephole2 [(parallel [(set (cc0) (zero_extract:SI (match_operand:QI 0 “register_operand” "") (const_int 1) (const_int 7))) (clobber (scratch:QI))]) (set (pc) (if_then_else (match_operator 1 “eqne_operator” [(cc0) (const_int 0)]) (label_ref (match_operand 2 "" "")) (pc)))] “(TARGET_H8300H || TARGET_H8300S)” [(set (cc0) (match_dup 0)) (set (pc) (if_then_else (match_op_dup 3 [(cc0) (const_int 0)]) (label_ref (match_dup 2)) (pc)))] “operands[3] = ((GET_CODE (operands[1]) == EQ) ? gen_rtx_GE (VOIDmode, cc0_rtx, const0_rtx) : gen_rtx_LT (VOIDmode, cc0_rtx, const0_rtx));”)

;; The next three peephole2's will try to transform ;; ;; mov.b A,r0l (or mov.l A,er0) ;; and.l #CST,er0 ;; ;; into ;; ;; sub.l er0 ;; mov.b A,r0l ;; and.b #CST,r0l (if CST is not 255)

(define_peephole2 [(set (match_operand:QI 0 “register_operand” "") (match_operand:QI 1 “general_operand” "")) (set (match_operand:SI 2 “register_operand” "") (and:SI (match_dup 2) (const_int 255)))] “(TARGET_H8300H || TARGET_H8300S) && !reg_overlap_mentioned_p (operands[2], operands[1]) && REGNO (operands[0]) == REGNO (operands[2])” [(set (match_dup 2) (const_int 0)) (set (strict_low_part (match_dup 0)) (match_dup 1))] "")

(define_peephole2 [(set (match_operand:SI 0 “register_operand” "") (match_operand:SI 1 “general_operand” "")) (set (match_dup 0) (and:SI (match_dup 0) (const_int 255)))] “(TARGET_H8300H || TARGET_H8300S) && !reg_overlap_mentioned_p (operands[0], operands[1]) && !(GET_CODE (operands[1]) == MEM && MEM_VOLATILE_P (operands[1]))” [(set (match_dup 0) (const_int 0)) (set (strict_low_part (match_dup 2)) (match_dup 3))] “operands[2] = gen_lowpart (QImode, operands[0]); operands[3] = gen_lowpart (QImode, operands[1]);”)

(define_peephole2 [(set (match_operand 0 “register_operand” "") (match_operand 1 “general_operand” "")) (set (match_operand:SI 2 “register_operand” "") (and:SI (match_dup 2) (match_operand:SI 3 “const_int_qi_operand” "")))] “(TARGET_H8300H || TARGET_H8300S) && (GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode || GET_MODE (operands[0]) == SImode) && GET_MODE (operands[0]) == GET_MODE (operands[1]) && REGNO (operands[0]) == REGNO (operands[2]) && !reg_overlap_mentioned_p (operands[2], operands[1]) && !(GET_MODE (operands[1]) != QImode && GET_CODE (operands[1]) == MEM && MEM_VOLATILE_P (operands[1]))” [(set (match_dup 2) (const_int 0)) (set (strict_low_part (match_dup 4)) (match_dup 5)) (set (match_dup 2) (and:SI (match_dup 2) (match_dup 6)))] “operands[4] = gen_lowpart (QImode, operands[0]); operands[5] = gen_lowpart (QImode, operands[1]); operands[6] = GEN_INT (~0xff | INTVAL (operands[3]));”)

(define_peephole2 [(set (match_operand:SI 0 “register_operand” "") (match_operand:SI 1 “register_operand” "")) (set (match_dup 0) (and:SI (match_dup 0) (const_int 65280)))] “(TARGET_H8300H || TARGET_H8300S) && !reg_overlap_mentioned_p (operands[0], operands[1])” [(set (match_dup 0) (const_int 0)) (set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8)) (lshiftrt:SI (match_dup 1) (const_int 8)))] "")

;; If a load of mem:SI is followed by an AND that turns off the upper ;; half, then we can load mem:HI instead.

(define_peephole2 [(set (match_operand:SI 0 “register_operand” "") (match_operand:SI 1 “memory_operand” "")) (set (match_dup 0) (and:SI (match_dup 0) (match_operand:SI 2 “const_int_operand” "")))] “(TARGET_H8300H || TARGET_H8300S) && !MEM_VOLATILE_P (operands[1]) && (INTVAL (operands[2]) & ~0xffff) == 0 && INTVAL (operands[2]) != 255” [(set (match_dup 3) (match_dup 4)) (set (match_dup 0) (and:SI (match_dup 0) (match_dup 2)))] “operands[3] = gen_lowpart (HImode, operands[0]); operands[4] = gen_lowpart (HImode, operands[1]);”)

;; (compare (reg:HI) (const_int)) takes 4 bytes, so we try to achieve ;; the equivalent with shorter sequences. Here is the summary. Cases ;; are grouped for each define_peephole2. ;; ;; reg const_int use insn ;; -------------------------------------------------------- ;; dead -2 eq/ne inc.l ;; dead -1 eq/ne inc.l ;; dead 1 eq/ne dec.l ;; dead 2 eq/ne dec.l ;; ;; dead 1 geu/ltu shar.l ;; dead 3 (H8S) geu/ltu shar.l ;; ;; ---- 255 geu/ltu mov.b

;; Transform ;; ;; cmp.w #1,r0 ;; bne .L1 ;; ;; into ;; ;; dec.w #1,r0 ;; bne .L1

(define_peephole2 [(set (cc0) (compare (match_operand:HI 0 “register_operand” "") (match_operand:HI 1 “incdec_operand” ""))) (set (pc) (if_then_else (match_operator 3 “eqne_operator” [(cc0) (const_int 0)]) (label_ref (match_operand 2 "" "")) (pc)))] “(TARGET_H8300H || TARGET_H8300S) && peep2_reg_dead_p (1, operands[0])” [(set (match_dup 0) (unspec:HI [(match_dup 0) (match_dup 4)] UNSPEC_INCDEC)) (set (cc0) (match_dup 0)) (set (pc) (if_then_else (match_op_dup 3 [(cc0) (const_int 0)]) (label_ref (match_dup 2)) (pc)))] “operands[4] = GEN_INT (- INTVAL (operands[1]));”)

;; Transform ;; ;; cmp.w #1,r0 ;; bhi .L1 ;; ;; into ;; ;; shar.w r0 ;; bne .L1

(define_peephole2 [(set (cc0) (compare (match_operand:HI 0 “register_operand” "") (match_operand:HI 1 “const_int_operand” ""))) (set (pc) (if_then_else (match_operator 2 “gtle_operator” [(cc0) (const_int 0)]) (label_ref (match_operand 3 "" "")) (pc)))] “(TARGET_H8300H || TARGET_H8300S) && peep2_reg_dead_p (1, operands[0]) && (INTVAL (operands[1]) == 1 || (TARGET_H8300S && INTVAL (operands[1]) == 3))” [(parallel [(set (match_dup 0) (ashiftrt:HI (match_dup 0) (match_dup 5))) (clobber (scratch:QI))]) (set (cc0) (match_dup 0)) (set (pc) (if_then_else (match_dup 4) (label_ref (match_dup 3)) (pc)))] “switch (GET_CODE (operands[2])) { case GTU: operands[4] = gen_rtx_NE (VOIDmode, cc0_rtx, const0_rtx); break; case LEU: operands[4] = gen_rtx_EQ (VOIDmode, cc0_rtx, const0_rtx); break; default: operands[4] = operands[2]; break; } operands[5] = GEN_INT (exact_log2 (INTVAL (operands[1]) + 1));”)

;; Transform ;; ;; cmp.w #255,r0 ;; bhi .L1 ;; ;; into ;; ;; mov.b r0h,r0h ;; bne .L1

(define_peephole2 [(set (cc0) (compare (match_operand:HI 0 “register_operand” "") (const_int 255))) (set (pc) (if_then_else (match_operator 1 “gtle_operator” [(cc0) (const_int 0)]) (label_ref (match_operand 2 "" "")) (pc)))] “TARGET_H8300H || TARGET_H8300S” [(set (cc0) (and:HI (match_dup 0) (const_int -256))) (set (pc) (if_then_else (match_dup 3) (label_ref (match_dup 2)) (pc)))] “switch (GET_CODE (operands[1])) { case GTU: operands[3] = gen_rtx_NE (VOIDmode, cc0_rtx, const0_rtx); break; case LEU: operands[3] = gen_rtx_EQ (VOIDmode, cc0_rtx, const0_rtx); break; default: operands[3] = operands[1]; break; }”)

;; (compare (reg:SI) (const_int)) takes 6 bytes, so we try to achieve ;; the equivalent with shorter sequences. Here is the summary. Cases ;; are grouped for each define_peephole2. ;; ;; reg const_int use insn ;; -------------------------------------------------------- ;; live -2 eq/ne copy and inc.l ;; live -1 eq/ne copy and inc.l ;; live 1 eq/ne copy and dec.l ;; live 2 eq/ne copy and dec.l ;; ;; dead -2 eq/ne inc.l ;; dead -1 eq/ne inc.l ;; dead 1 eq/ne dec.l ;; dead 2 eq/ne dec.l ;; ;; dead -131072 eq/ne inc.w and test ;; dead -65536 eq/ne inc.w and test ;; dead 65536 eq/ne dec.w and test ;; dead 131072 eq/ne dec.w and test ;; ;; dead 0x000000?? except 1 and 2 eq/ne xor.b and test ;; dead 0x0000??00 eq/ne xor.b and test ;; dead 0x0000ffff eq/ne not.w and test ;; ;; dead 0xffffff?? except -1 and -2 eq/ne xor.b and not.l ;; dead 0xffff??ff eq/ne xor.b and not.l ;; dead 0x40000000 (H8S) eq/ne rotl.l and dec.l ;; dead 0x80000000 eq/ne rotl.l and dec.l ;; ;; live 1 geu/ltu copy and shar.l ;; live 3 (H8S) geu/ltu copy and shar.l ;; ;; dead 1 geu/ltu shar.l ;; dead 3 (H8S) geu/ltu shar.l ;; ;; dead 3 (H8/300H) geu/ltu and.b and test ;; dead 7 geu/ltu and.b and test ;; dead 15 geu/ltu and.b and test ;; dead 31 geu/ltu and.b and test ;; dead 63 geu/ltu and.b and test ;; dead 127 geu/ltu and.b and test ;; dead 255 geu/ltu and.b and test ;; ;; ---- 65535 geu/ltu mov.w

;; For a small constant, it is cheaper to actually do the subtraction ;; and then test the register.

(define_peephole2 [(set (cc0) (compare (match_operand:SI 0 “register_operand” "") (match_operand:SI 1 “incdec_operand” ""))) (set (pc) (if_then_else (match_operator 3 “eqne_operator” [(cc0) (const_int 0)]) (label_ref (match_operand 2 "" "")) (pc)))] “(TARGET_H8300H || TARGET_H8300S) && peep2_reg_dead_p (1, operands[0])” [(set (match_dup 0) (unspec:SI [(match_dup 0) (match_dup 4)] UNSPEC_INCDEC)) (set (cc0) (match_dup 0)) (set (pc) (if_then_else (match_op_dup 3 [(cc0) (const_int 0)]) (label_ref (match_dup 2)) (pc)))] “operands[4] = GEN_INT (- INTVAL (operands[1]));”)

(define_peephole2 [(set (cc0) (compare (match_operand:SI 0 “register_operand” "") (match_operand:SI 1 “const_int_operand” ""))) (set (pc) (if_then_else (match_operator 3 “eqne_operator” [(cc0) (const_int 0)]) (label_ref (match_operand 2 "" "")) (pc)))] “(TARGET_H8300H || TARGET_H8300S) && peep2_reg_dead_p (1, operands[0]) && (INTVAL (operands[1]) == -131072 || INTVAL (operands[1]) == -65536 || INTVAL (operands[1]) == 65536 || INTVAL (operands[1]) == 131072)” [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 4))) (set (cc0) (match_dup 0)) (set (pc) (if_then_else (match_op_dup 3 [(cc0) (const_int 0)]) (label_ref (match_dup 2)) (pc)))] “operands[4] = GEN_INT (- INTVAL (operands[1]));”)

;; For certain (in)equality comparisons against a constant, we can ;; XOR the register with the constant, and test the register against ;; 0.

(define_peephole2 [(set (cc0) (compare (match_operand:SI 0 “register_operand” "") (match_operand:SI 1 “const_int_operand” ""))) (set (pc) (if_then_else (match_operator 3 “eqne_operator” [(cc0) (const_int 0)]) (label_ref (match_operand 2 "" "")) (pc)))] “(TARGET_H8300H || TARGET_H8300S) && peep2_reg_dead_p (1, operands[0]) && ((INTVAL (operands[1]) & 0x00ff) == INTVAL (operands[1]) || (INTVAL (operands[1]) & 0xff00) == INTVAL (operands[1]) || INTVAL (operands[1]) == 0x0000ffff) && INTVAL (operands[1]) != 1 && INTVAL (operands[1]) != 2” [(set (match_dup 0) (xor:SI (match_dup 0) (match_dup 1))) (set (cc0) (match_dup 0)) (set (pc) (if_then_else (match_op_dup 3 [(cc0) (const_int 0)]) (label_ref (match_dup 2)) (pc)))] "")

(define_peephole2 [(set (cc0) (compare (match_operand:SI 0 “register_operand” "") (match_operand:SI 1 “const_int_operand” ""))) (set (pc) (if_then_else (match_operator 3 “eqne_operator” [(cc0) (const_int 0)]) (label_ref (match_operand 2 "" "")) (pc)))] “(TARGET_H8300H || TARGET_H8300S) && peep2_reg_dead_p (1, operands[0]) && ((INTVAL (operands[1]) | 0x00ff) == -1 || (INTVAL (operands[1]) | 0xff00) == -1) && INTVAL (operands[1]) != -1 && INTVAL (operands[1]) != -2” [(set (match_dup 0) (xor:SI (match_dup 0) (match_dup 4))) (set (match_dup 0) (not:SI (match_dup 0))) (set (cc0) (match_dup 0)) (set (pc) (if_then_else (match_op_dup 3 [(cc0) (const_int 0)]) (label_ref (match_dup 2)) (pc)))] “operands[4] = GEN_INT (INTVAL (operands[1]) ^ -1);”)

(define_peephole2 [(set (cc0) (compare (match_operand:SI 0 “register_operand” "") (match_operand:SI 1 “const_int_operand” ""))) (set (pc) (if_then_else (match_operator 3 “eqne_operator” [(cc0) (const_int 0)]) (label_ref (match_operand 2 "" "")) (pc)))] “(TARGET_H8300H || TARGET_H8300S) && peep2_reg_dead_p (1, operands[0]) && (INTVAL (operands[1]) == -2147483647 - 1 || (TARGET_H8300S && INTVAL (operands[1]) == 1073741824))” [(set (match_dup 0) (rotate:SI (match_dup 0) (match_dup 4))) (set (match_dup 0) (unspec:SI [(match_dup 0) (const_int -1)] UNSPEC_INCDEC)) (set (cc0) (match_dup 0)) (set (pc) (if_then_else (match_op_dup 3 [(cc0) (const_int 0)]) (label_ref (match_dup 2)) (pc)))] “operands[4] = GEN_INT (INTVAL (operands[1]) == -2147483647 - 1 ? 1 : 2);”)

;; Transform ;; ;; cmp.l #1,er0 ;; bhi .L1 ;; ;; into ;; ;; mov.l er0,er1 ;; shar.l er1 ;; bne .L1

;; We avoid this transformation if we see more than one copy of the ;; same compare insn immediately before this one.

(define_peephole2 [(match_scratch:SI 4 “r”) (set (cc0) (compare (match_operand:SI 0 “register_operand” "") (match_operand:SI 1 “const_int_operand” ""))) (set (pc) (if_then_else (match_operator 2 “gtle_operator” [(cc0) (const_int 0)]) (label_ref (match_operand 3 "" "")) (pc)))] “(TARGET_H8300H || TARGET_H8300S) && !peep2_reg_dead_p (1, operands[0]) && (INTVAL (operands[1]) == 1 || (TARGET_H8300S && INTVAL (operands[1]) == 3)) && !same_cmp_preceding_p (insn)” [(set (match_dup 4) (match_dup 0)) (parallel [(set (match_dup 4) (ashiftrt:SI (match_dup 4) (match_dup 6))) (clobber (scratch:QI))]) (set (cc0) (match_dup 4)) (set (pc) (if_then_else (match_dup 5) (label_ref (match_dup 3)) (pc)))] “switch (GET_CODE (operands[2])) { case GTU: operands[5] = gen_rtx_NE (VOIDmode, cc0_rtx, const0_rtx); break; case LEU: operands[5] = gen_rtx_EQ (VOIDmode, cc0_rtx, const0_rtx); break; default: operands[5] = operands[2]; break; } operands[6] = GEN_INT (exact_log2 (INTVAL (operands[1]) + 1));”)

;; Transform ;; ;; cmp.l #1,er0 ;; bhi .L1 ;; ;; into ;; ;; shar.l er0 ;; bne .L1

(define_peephole2 [(set (cc0) (compare (match_operand:SI 0 “register_operand” "") (match_operand:SI 1 “const_int_operand” ""))) (set (pc) (if_then_else (match_operator 2 “gtle_operator” [(cc0) (const_int 0)]) (label_ref (match_operand 3 "" "")) (pc)))] “(TARGET_H8300H || TARGET_H8300S) && peep2_reg_dead_p (1, operands[0]) && (INTVAL (operands[1]) == 1 || (TARGET_H8300S && INTVAL (operands[1]) == 3))” [(parallel [(set (match_dup 0) (ashiftrt:SI (match_dup 0) (match_dup 5))) (clobber (scratch:QI))]) (set (cc0) (match_dup 0)) (set (pc) (if_then_else (match_dup 4) (label_ref (match_dup 3)) (pc)))] “switch (GET_CODE (operands[2])) { case GTU: operands[4] = gen_rtx_NE (VOIDmode, cc0_rtx, const0_rtx); break; case LEU: operands[4] = gen_rtx_EQ (VOIDmode, cc0_rtx, const0_rtx); break; default: operands[4] = operands[2]; break; } operands[5] = GEN_INT (exact_log2 (INTVAL (operands[1]) + 1));”)

;; Transform ;; ;; cmp.l #15,er0 ;; bhi .L1 ;; ;; into ;; ;; and #240,r0l ;; mov.l er0,er0 ;; bne .L1

(define_peephole2 [(set (cc0) (compare (match_operand:SI 0 “register_operand” "") (match_operand:SI 1 “const_int_operand” ""))) (set (pc) (if_then_else (match_operator 2 “gtle_operator” [(cc0) (const_int 0)]) (label_ref (match_operand 3 "" "")) (pc)))] “(TARGET_H8300H || TARGET_H8300S) && peep2_reg_dead_p (1, operands[0]) && ((TARGET_H8300H && INTVAL (operands[1]) == 3) || INTVAL (operands[1]) == 7 || INTVAL (operands[1]) == 15 || INTVAL (operands[1]) == 31 || INTVAL (operands[1]) == 63 || INTVAL (operands[1]) == 127 || INTVAL (operands[1]) == 255)” [(set (match_dup 0) (and:SI (match_dup 0) (match_dup 5))) (set (cc0) (match_dup 0)) (set (pc) (if_then_else (match_dup 4) (label_ref (match_dup 3)) (pc)))] “switch (GET_CODE (operands[2])) { case GTU: operands[4] = gen_rtx_NE (VOIDmode, cc0_rtx, const0_rtx); break; case LEU: operands[4] = gen_rtx_EQ (VOIDmode, cc0_rtx, const0_rtx); break; default: operands[4] = operands[2]; break; } operands[5] = GEN_INT (~INTVAL (operands[1]));”)

;; Transform A <= 65535 to (A & 0xffff0000) == 0.

(define_peephole2 [(set (cc0) (compare (match_operand:SI 0 “register_operand” "") (const_int 65535))) (set (pc) (if_then_else (match_operator 1 “gtle_operator” [(cc0) (const_int 0)]) (label_ref (match_operand 2 "" "")) (pc)))] “TARGET_H8300H || TARGET_H8300S” [(set (cc0) (and:SI (match_dup 0) (const_int -65536))) (set (pc) (if_then_else (match_dup 3) (label_ref (match_dup 2)) (pc)))] “switch (GET_CODE (operands[1])) { case GTU: operands[3] = gen_rtx_NE (VOIDmode, cc0_rtx, const0_rtx); break; case LEU: operands[3] = gen_rtx_EQ (VOIDmode, cc0_rtx, const0_rtx); break; default: operands[3] = operands[1]; break; }”)

;; For constants like -1, -2, 1, 2, it is still cheaper to make a copy ;; of the register being tested, do the subtraction on the copy, and ;; then test the copy. We avoid this transformation if we see more ;; than one copy of the same compare insn.

(define_peephole2 [(match_scratch:SI 4 “r”) (set (cc0) (compare (match_operand:SI 0 “register_operand” "") (match_operand:SI 1 “incdec_operand” ""))) (set (pc) (if_then_else (match_operator 3 “eqne_operator” [(cc0) (const_int 0)]) (label_ref (match_operand 2 "" "")) (pc)))] “(TARGET_H8300H || TARGET_H8300S) && !peep2_reg_dead_p (1, operands[0]) && !same_cmp_following_p (insn)” [(set (match_dup 4) (match_dup 0)) (set (match_dup 4) (unspec:SI [(match_dup 4) (match_dup 5)] UNSPEC_INCDEC)) (set (cc0) (match_dup 4)) (set (pc) (if_then_else (match_op_dup 3 [(cc0) (const_int 0)]) (label_ref (match_dup 2)) (pc)))] “operands[5] = GEN_INT (- INTVAL (operands[1]));”)

;; Narrow the mode of testing if possible.

(define_peephole2 [(set (match_operand:HI 0 “register_operand” "") (and:HI (match_dup 0) (match_operand:HI 1 “const_int_qi_operand” ""))) (set (cc0) (match_dup 0)) (set (pc) (if_then_else (match_operator 3 “eqne_operator” [(cc0) (const_int 0)]) (label_ref (match_operand 2 "" "")) (pc)))] “peep2_reg_dead_p (2, operands[0])” [(set (match_dup 4) (and:QI (match_dup 4) (match_dup 5))) (set (cc0) (match_dup 4)) (set (pc) (if_then_else (match_op_dup 3 [(cc0) (const_int 0)]) (label_ref (match_dup 2)) (pc)))] “operands[4] = gen_rtx_REG (QImode, REGNO (operands[0])); operands[5] = gen_int_mode (INTVAL (operands[1]), QImode);”)

(define_peephole2 [(set (match_operand:SI 0 “register_operand” "") (and:SI (match_dup 0) (match_operand:SI 1 “const_int_qi_operand” ""))) (set (cc0) (match_dup 0)) (set (pc) (if_then_else (match_operator 3 “eqne_operator” [(cc0) (const_int 0)]) (label_ref (match_operand 2 "" "")) (pc)))] “peep2_reg_dead_p (2, operands[0])” [(set (match_dup 4) (and:QI (match_dup 4) (match_dup 5))) (set (cc0) (match_dup 4)) (set (pc) (if_then_else (match_op_dup 3 [(cc0) (const_int 0)]) (label_ref (match_dup 2)) (pc)))] “operands[4] = gen_rtx_REG (QImode, REGNO (operands[0])); operands[5] = gen_int_mode (INTVAL (operands[1]), QImode);”)

(define_peephole2 [(set (match_operand:SI 0 “register_operand” "") (and:SI (match_dup 0) (match_operand:SI 1 “const_int_hi_operand” ""))) (set (cc0) (match_dup 0)) (set (pc) (if_then_else (match_operator 3 “eqne_operator” [(cc0) (const_int 0)]) (label_ref (match_operand 2 "" "")) (pc)))] “peep2_reg_dead_p (2, operands[0])” [(set (match_dup 4) (and:HI (match_dup 4) (match_dup 5))) (set (cc0) (match_dup 4)) (set (pc) (if_then_else (match_op_dup 3 [(cc0) (const_int 0)]) (label_ref (match_dup 2)) (pc)))] “operands[4] = gen_rtx_REG (HImode, REGNO (operands[0])); operands[5] = gen_int_mode (INTVAL (operands[1]), HImode);”)

(define_peephole2 [(set (match_operand:SI 0 “register_operand” "") (and:SI (match_dup 0) (match_operand:SI 1 “const_int_qi_operand” ""))) (set (match_dup 0) (xor:SI (match_dup 0) (match_operand:SI 2 “const_int_qi_operand” ""))) (set (cc0) (match_dup 0)) (set (pc) (if_then_else (match_operator 4 “eqne_operator” [(cc0) (const_int 0)]) (label_ref (match_operand 3 "" "")) (pc)))] “peep2_reg_dead_p (3, operands[0]) && (~INTVAL (operands[1]) & INTVAL (operands[2])) == 0” [(set (match_dup 5) (and:QI (match_dup 5) (match_dup 6))) (set (match_dup 5) (xor:QI (match_dup 5) (match_dup 7))) (set (cc0) (match_dup 5)) (set (pc) (if_then_else (match_op_dup 4 [(cc0) (const_int 0)]) (label_ref (match_dup 3)) (pc)))] “operands[5] = gen_rtx_REG (QImode, REGNO (operands[0])); operands[6] = gen_int_mode (INTVAL (operands[1]), QImode); operands[7] = gen_int_mode (INTVAL (operands[2]), QImode);”)