;;- Machine description for the Motorola 88000 for GNU C compiler
;;   Copyright (C) 1988 Free Software Foundation, Inc.
;;   Contributed by Michael Tiemann (tiemann@mcc.com)

;; This file is part of GNU CC.

;; GNU CC is free software; you can redistribute it and/or modify
;; it under the terms of the GNU General Public License as published by
;; the Free Software Foundation; either version 1, or (at your option)
;; any later version.

;; GNU CC is distributed in the hope that it will be useful,
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
;; GNU General Public License for more details.

;; You should have received a copy of the GNU General Public License
;; along with GNU CC; see the file COPYING.  If not, write to
;; the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.


;;- See file "rtl.def" for documentation on define_insn, match_*, et. al.

;;- cpp macro #define NOTICE_UPDATE_CC in file tm.h handles condition code
;;- updates for most instructions.

;;- Operand classes for the register allocator:

;; Compare instructions.
;; This pattern is used for generating an "insn"
;; which does just a compare and sets a (fictitious) condition code.

;; The actual the m88000 insns are compare-and-conditional-jump.
;; The define_peephole's below recognize the combinations of
;; compares and jumps, and output each pair as a single assembler insn.

;; This controls RTL generation and register allocation.
(define_insn "cmpsi"
  [(set (cc0)
	(compare (match_operand:SI 0 "arith_operand" "rI")
		 (match_operand:SI 1 "arith_operand" "rI")))]
  ""
  "*
{
  if (GET_CODE (operands[0]) == CONST_INT)
    {
      cc_status.flags |= CC_REVERSED;
      return \"cmp r25,%1,%0\";
    }
  return \"cmp r25,%0,%1\";
}")

(define_insn "cmpdf"
  [(set (cc0)
	(compare (match_operand:DF 0 "nonmemory_operand" "rG")
		 (match_operand:DF 1 "nonmemory_operand" "rG")))]
  ""
  "*
{
  if (GET_CODE (operands[0]) == CONST_DOUBLE)
    {
      cc_status.flags |= CC_REVERSED | CC_IN_FCCR;
      return \"fcmp.sdd r25,%1,%0\";
    }
  cc_status.flags |= CC_IN_FCCR;
  return \"fcmp.sdd r25,%0,%1\";
}")

(define_insn "cmpsf"
  [(set (cc0)
	(compare (match_operand:SF 0 "nonmemory_operand" "rG")
		 (match_operand:SF 1 "nonmemory_operand" "rG")))]
  ""
  "*
{
  if (GET_CODE (operands[0]) == CONST_DOUBLE)
    {
      cc_status.flags |= CC_REVERSED | CC_IN_FCCR;
      return \"fcmp.sss r25,%1,%0\";
    }
  cc_status.flags |= CC_IN_FCCR;
  return \"fcmp.sss r25,%0,%1\";
}")
;; We have to have this because cse can optimize the previous pattern
;; into this one.

(define_insn "tstsi"
  [(set (cc0)
	(match_operand:SI 0 "register_operand" "r"))]
  ""
  "cmp r25,%0,0")

(define_insn "tstdf"
  [(set (cc0)
	(match_operand:DF 0 "register_operand" "r"))]
  ""
  "*
{
  cc_status.flags |= CC_IN_FCCR;
  return \"fcmp.sds r25,%0,r0\";
}")

(define_insn "tstsf"
  [(set (cc0)
	(match_operand:SF 0 "register_operand" "r"))]
  ""
  "*
{
  cc_status.flags |= CC_IN_FCCR;
  return \"fcmp.sss r25,%0,r0\";
}")

;; These control RTL generation for conditional jump insns
;; and match them for register allocation.

(define_insn "beq"
  [(set (pc)
	(if_then_else (eq (cc0)
			  (const_int 0))
		      (label_ref (match_operand 0 "" ""))
		      (pc)))]
  ""
  "bb1 eq,r25,%l0")

(define_peephole
  [(set (cc0)
	(match_operand:SI 0 "register_operand" "r"))
   (set (pc)
	(if_then_else (eq (cc0)
			  (const_int 0))
		      (label_ref (match_operand 1 "" ""))
		      (pc)))]
  ""
  "*
{
  CC_STATUS_INIT;
  return \"bcnd eq0,%0,%l1\";
}")

(define_insn "bne"
  [(set (pc)
	(if_then_else (ne (cc0)
			  (const_int 0))
		      (label_ref (match_operand 0 "" ""))
		      (pc)))]
  ""
  "bb1 ne,r25,%l0")

(define_peephole
  [(set (cc0)
	(match_operand:SI 0 "register_operand" "r"))
   (set (pc)
	(if_then_else (ne (cc0)
			  (const_int 0))
		      (label_ref (match_operand 1 "" ""))
		      (pc)))]
  ""
  "*
{
  CC_STATUS_INIT;
  return \"bcnd ne0,%0,%l1\";
}")

(define_insn "bgt"
  [(set (pc)
	(if_then_else (gt (cc0)
			  (const_int 0))
		      (label_ref (match_operand 0 "" ""))
		      (pc)))]
  ""
  "bb1 gt,r25,%l0")

(define_insn "bgtu"
  [(set (pc)
	(if_then_else (gtu (cc0)
			   (const_int 0))
		      (label_ref (match_operand 0 "" ""))
		      (pc)))]
  ""
  "bb1 hi,r25,%l0")

(define_insn "blt"
  [(set (pc)
	(if_then_else (lt (cc0)
			  (const_int 0))
		      (label_ref (match_operand 0 "" ""))
		      (pc)))]
  ""
  "bb1 lt,r25,%l0")

(define_insn "bltu"
  [(set (pc)
	(if_then_else (ltu (cc0)
			   (const_int 0))
		      (label_ref (match_operand 0 "" ""))
		      (pc)))]
  ""
  "bb1 lo,r25,%l0")

(define_insn "bge"
  [(set (pc)
	(if_then_else (ge (cc0)
			  (const_int 0))
		      (label_ref (match_operand 0 "" ""))
		      (pc)))]
  ""
  "bb1 ge,r25,%l0")

(define_insn "bgeu"
  [(set (pc)
	(if_then_else (geu (cc0)
			   (const_int 0))
		      (label_ref (match_operand 0 "" ""))
		      (pc)))]
  ""
  "bb1 hs,r25,%l0")

(define_insn "ble"
  [(set (pc)
	(if_then_else (le (cc0)
			  (const_int 0))
		      (label_ref (match_operand 0 "" ""))
		      (pc)))]
  ""
  "bb1 le,r25,%l0")

(define_insn "bleu"
  [(set (pc)
	(if_then_else (leu (cc0)
			   (const_int 0))
		      (label_ref (match_operand 0 "" ""))
		      (pc)))]
  ""
  "bb1 ls,r25,%l0")

;; These match inverted jump insns for register allocation.

(define_insn ""
  [(set (pc)
	(if_then_else (eq (cc0)
			  (const_int 0))
		      (pc)
		      (label_ref (match_operand 0 "" ""))))]
  ""
  "bb0 eq,r25,%l0")

(define_peephole
  [(set (cc0) (match_operand:SI 0 "register_operand" "r"))
   (set (pc)
	(if_then_else (eq (cc0)
			  (const_int 0))
		      (pc)
		      (label_ref (match_operand 1 "" ""))))]
  ""
  "*
{
  CC_STATUS_INIT;
  return \"bcnd ne0,%0,%l1\";
}")

(define_insn ""
  [(set (pc)
	(if_then_else (ne (cc0)
			  (const_int 0))
		      (pc)
		      (label_ref (match_operand 0 "" ""))))]
  ""
  "bb0 ne,r25,%l0")

(define_peephole
  [(set (cc0) (match_operand:SI 0 "register_operand" "r"))
   (set (pc)
	(if_then_else (ne (cc0)
			  (const_int 0))
		      (pc)
		      (label_ref (match_operand 1 "" ""))))]
  ""
  "*
{
  CC_STATUS_INIT;
  return \"bcnd eq0,%0,%l1\";
}")

(define_insn ""
  [(set (pc)
	(if_then_else (gt (cc0)
			  (const_int 0))
		      (pc)
		      (label_ref (match_operand 0 "" ""))))]
  ""
  "bb0 gt,r25,%l0")

(define_insn ""
  [(set (pc)
	(if_then_else (gtu (cc0)
			   (const_int 0))
		      (pc)
		      (label_ref (match_operand 0 "" ""))))]
  ""
  "bb0 hi,r25,%l0")

(define_insn ""
  [(set (pc)
	(if_then_else (lt (cc0)
			  (const_int 0))
		      (pc)
		      (label_ref (match_operand 0 "" ""))))]
  ""
  "bb0 lt,r25,%l0")

(define_insn ""
  [(set (pc)
	(if_then_else (ltu (cc0)
			   (const_int 0))
		      (pc)
		      (label_ref (match_operand 0 "" ""))))]
  ""
  "bb0 lo,r25,%l0")

(define_insn ""
  [(set (pc)
	(if_then_else (ge (cc0)
			  (const_int 0))
		      (pc)
		      (label_ref (match_operand 0 "" ""))))]
  ""
  "bb0 ge,r25,%l0")

(define_insn ""
  [(set (pc)
	(if_then_else (geu (cc0)
			   (const_int 0))
		      (pc)
		      (label_ref (match_operand 0 "" ""))))]
  ""
  "bb0 hs,r25,%l0")

(define_insn ""
  [(set (pc)
	(if_then_else (le (cc0)
			  (const_int 0))
		      (pc)
		      (label_ref (match_operand 0 "" ""))))]
  ""
  "bb0 le,r25,%l0")

(define_insn ""
  [(set (pc)
	(if_then_else (leu (cc0)
			   (const_int 0))
		      (pc)
		      (label_ref (match_operand 0 "" ""))))]
  ""
  "bb0 ls,r25,%l0")

;; Move instructions

(define_insn "swapsi"
  [(set (match_operand:SI 0 "general_operand" "g")
	(match_operand:SI 1 "general_operand" "g"))
   (set (match_dup 1) (match_dup 0))]
  ""
  "*
{
  if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
    {
      CC_STATUS_INIT;
      return \"ld r25,%0\;xmem r25,%1\;st r25,%0\";
    }
  if (! REG_P (operands[1]))
    return \"xmem %0,%1\";
  if (REG_P (operands[0]))
    {
      if (REGNO (operands[0]) == REGNO (operands[1]))
	return \"\";
      return \"xor %0,%0,%1\;xor %1,%1,%0\;xor %0,%0,%1\";
    }
  return \"xmem %1,%0\";
}")

(define_peephole
  [(set (match_operand:SI 0 "register_operand" "=r")
	(match_operand:SI 1 "memory_operand" "m"))
   (set (match_operand:SI 2 "register_operand" "=r")
	(match_operand:SI 3 "memory_operand" "m"))
   (set (match_dup 1) (match_dup 2))
   (set (match_dup 3) (match_dup 0))]
  ""
  "*
{
  CC_STATUS_INIT;
  return \"ld r25,%1\;xmem r25,%3\;st r25,%1\";
}")

(define_insn "swapqi"
  [(set (match_operand:QI 0 "general_operand" "g")
	(match_operand:QI 1 "general_operand" "g"))
   (set (match_dup 1) (match_dup 0))]
  ""
  "*
{
  if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
    {
      CC_STATUS_INIT;
      return \"ld.bu r25,%0\;xmem.bu r25,%1\;st.bu r25,%0\";
    }
  if (! REG_P (operands[1]))
    return \"xmem.bu %0,%1\";
  if (REG_P (operands[0]))
    {
      if (REGNO (operands[0]) == REGNO (operands[1]))
	return \"\";
      return \"xor %0,%0,%1\;xor %1,%1,%0\;xor %0,%0,%1\";
    }
  return \"xmem.bu %1,%0\";
}")

(define_peephole
  [(set (match_operand:QI 0 "register_operand" "=r")
	(match_operand:QI 1 "memory_operand" "m"))
   (set (match_operand:QI 2 "register_operand" "=r")
	(match_operand:QI 3 "memory_operand" "m"))
   (set (match_dup 1) (match_dup 2))
   (set (match_dup 3) (match_dup 0))]
  ""
  "*
{
  CC_STATUS_INIT;
  return \"ld.bu r25,%1\;xmem.bu r25,%3\;st.bu r25,%1\";
}")

(define_insn ""
  [(set (match_operand:SI 0 "general_operand" "g")
	(const_int 0))]
  ""
  "*
{
  if (REG_P (operands[0]))
    return \"or %0,r0,0\";
  return \"st r0,%0\";
}")

(define_insn "movsi"
  [(set (match_operand:SI 0 "general_operand" "=g,r")
	(match_operand:SI 1 "general_operand" "r,mi"))]
  ""
  "*
{
  if (REG_P (operands[0]))
    {
      if (GET_CODE (operands[1]) == MEM)
	return \"ld %0,%1\";
      if (GET_CODE (operands[1]) == CONST_INT)
	return output_store_const_int (SImode, operands);
      if (GET_CODE (operands[1]) == LABEL_REF
	  || GET_CODE (operands[1]) == SYMBOL_REF)
	return \"lda %0,r0,%1\";
      return \"or %0,r0,%1\";
    }
  return \"st %1,%0\";
}")

;; Simulate pre inc.  Post inc/dec is automatically optimized
;; by sheer luck.  ?? In which phase should this really be done??
(define_insn ""
  [(set (match_operand:SI 0 "register_operand" "r")
	(mem:SI (plus:SI (match_operand:SI 1 "register_operand" "r")
			 (match_operand:SI 2 "arith_operand" "rI"))))
   (set (match_dup 1)
	(plus:SI (match_dup 1)
		 (match_dup 2)))]
  ""
  "ld %0,%1,%2\\t;; pipelined!\;addu %1,%1,%2\\t;; /")

(define_insn ""
  [(set (mem:SI (plus:SI (match_operand:SI 0 "register_operand" "r")
			 (match_operand:SI 1 "arith_operand" "rI")))
	(match_operand:SI 2 "register_operand" "r"))
   (set (match_dup 0)
	(plus:SI (match_dup 0)
		 (match_dup 1)))]
  ""
  "st %2,%0,%1\\t;; pipelined!\;addu %0,%0,%1\\t;; /")

(define_insn ""
  [(set (match_operand:HI 0 "general_operand" "g")
	(const_int 0))]
  ""
  "*
{
  if (REG_P (operands[0]))
    return \"or %0,r0,0\";
  return \"st.h r0,%0\";
}")

(define_insn "movhi"
  [(set (match_operand:HI 0 "general_operand" "=g,r")
	(match_operand:HI 1 "general_operand" "r,mn"))]
  ""
  "*
{
  if (REG_P (operands[0]))
    {
      if (GET_CODE (operands[1]) == MEM)
	return \"ld.h %0,%1\";
      if (GET_CODE (operands[1]) == CONST_INT)
	return output_store_const_int (HImode, operands);
      return \"or %0,r0,%1\";
    }
  return \"st.h %1,%0\";
}")

(define_insn ""
  [(set (match_operand:SI 0 "register_operand" "r")
	(sign_extend:SI
	  (mem:HI (plus:SI (match_operand:SI 1 "register_operand" "r")
			   (match_operand:SI 2 "arith_operand" "rI")))))
   (set (match_dup 1)
	(plus:SI (match_dup 1)
		 (match_dup 2)))]
  ""
  "ld.h %0,%1,%2\\t;; pipelined!\;addu %1,%1,%2\\t;; /")

(define_insn ""
  [(set (match_operand:SI 0 "register_operand" "r")
	(zero_extend:SI
	  (mem:HI (plus:SI (match_operand:SI 1 "register_operand" "r")
			   (match_operand:SI 2 "arith_operand" "rI")))))
   (set (match_dup 1)
	(plus:SI (match_dup 1)
		 (match_dup 2)))]
  ""
  "ld.hu %0,%1,%2\\t;; pipelined!\;addu %1,%1,%2\\t;; /")

(define_insn ""
  [(set (mem:HI (plus:SI (match_operand:SI 0 "register_operand" "r")
			 (match_operand:SI 1 "arith_operand" "rI")))
	(match_operand:SI 2 "register_operand" "r"))
   (set (match_dup 0)
	(plus:SI (match_dup 0)
		 (match_dup 1)))]
  ""
  "st.h %2,%0,%1\\t;; pipelined!\;addu %0,%0,%1\\t;; /")

(define_insn ""
  [(set (match_operand:QI 0 "general_operand" "g")
	(const_int 0))]
  ""
  "*
{
  if (REG_P (operands[0]))
    return \"or %0,r0,0\";
  return \"st.b r0,%0\";
}")

(define_insn "movqi"
  [(set (match_operand:QI 0 "general_operand" "=g,r")
	(match_operand:QI 1 "general_operand" "r,mn"))]
  ""
  "*
{
  if (REG_P (operands[0]))
    {
      if (GET_CODE (operands[1]) == MEM)
	return \"ld.b %0,%1\";
      if (GET_CODE (operands[1]) == CONST_INT)
	return output_store_const_int (QImode, operands);
      return \"or %0,r0,%1\";
    }
  return \"st.b %1,%0\";
}")

(define_insn ""
  [(set (match_operand:SI 0 "register_operand" "r")
	(sign_extend:SI
	  (mem:QI (plus:SI (match_operand:SI 1 "register_operand" "r")
			   (match_operand:SI 2 "arith_operand" "rI")))))
   (set (match_dup 1)
	(plus:SI (match_dup 1)
		 (match_dup 2)))]
  ""
  "ld.b %0,%1,%2\\t;; pipelined!\;addu %1,%1,%2\\t;; /")

(define_insn ""
  [(set (match_operand:SI 0 "register_operand" "r")
	(zero_extend:SI
	  (mem:QI (plus:SI (match_operand:SI 1 "register_operand" "r")
			   (match_operand:SI 2 "arith_operand" "rI")))))
   (set (match_dup 1)
	(plus:SI (match_dup 1)
		 (match_dup 2)))]
  ""
  "ld.bu %0,%1,%2\\t;; pipelined!\;addu %1,%1,%2\\t;; /")

(define_insn ""
  [(set (mem:QI (plus:SI (match_operand:SI 0 "register_operand" "r")
			 (match_operand:SI 1 "arith_operand" "rI")))
	(match_operand:SI 2 "register_operand" "r"))
   (set (match_dup 0)
	(plus:SI (match_dup 0)
		 (match_dup 1)))]
  ""
  "st.b %2,%0,%1\\t;; pipelined!\;addu %0,%0,%1\\t;; /")

;; The definition of this insn does not really explain what it does,
;; but it should suffice
;; that anything generated as this insn will be recognized as one
;; and that it won't successfully combine with anything.
(define_insn "movstrsi"
  [(set (match_operand:BLK 0 "general_operand" "=g")
	(match_operand:BLK 1 "general_operand" "g"))
   (use (match_operand:SI 2 "arith32_operand" "rn"))
   (clobber (reg:SI 10))
   (clobber (reg:SI 11))
   (clobber (reg:SI 12))]
  ""
  "* output_block_move (operands);")

;; This pattern forces (set (reg:DF ...) (const_double ...))
;; to be reloaded by putting the constant into memory.
;; It must come before the more general movdf pattern.
(define_insn ""
  [(set (match_operand:DF 0 "general_operand" "=r,o")
	(match_operand:DF 1 "" "mG,G"))]
  "GET_CODE (operands[1]) == CONST_DOUBLE"
  "*
{
  if (operands[1] == dconst0_rtx && GET_CODE (operands[0]) == REG)
    {
      operands[1] = gen_rtx (REG, SImode, REGNO (operands[0]) + 1);
      return \"add %0,r0,0\;add %1,r0,0\";
    }
  if (operands[1] == dconst0_rtx && GET_CODE (operands[0]) == MEM)
    {
      operands[1] = adj_offsettable_operand (operands[0], 4);
      return \"st r0,%0\;st r0,%1\";
    }
  return output_move_double (operands);
}
")
  
(define_insn "movdf"
  [(set (match_operand:DF 0 "general_operand" "=r,m")
	(match_operand:DF 1 "general_operand" "rm,r"))]
  ""
  "* return output_move_double (operands);")

(define_insn "movdi"
  [(set (match_operand:DI 0 "general_operand" "=r,m")
	(match_operand:DI 1 "general_operand" "rm,r"))]
  ""
  "* return output_move_double (operands);")

(define_insn "movsf"
  [(set (match_operand:SF 0 "general_operand" "=g,r")
	(match_operand:SF 1 "general_operand" "r,mF"))]
  ""
  "*
{
  if (REG_P (operands[0]))
    {
      if (GET_CODE (operands[1]) == MEM)
	return \"ld %0,%1\";
      if (GET_CODE (operands[1]) == CONST_DOUBLE)
	return output_store_const_float (SFmode, operands);
      return \"or %0,r0,%1\";
    }
  return \"st %1,%0\";
}")

;;- load effective address 
(define_insn ""
  [(set (match_operand:SI 0 "register_operand" "=r")
	(match_operand:QI 1 "address_operand" "p"))]
  ""
  "lda.b %0,%a1")

(define_insn ""
  [(set (match_operand:SI 0 "register_operand" "=r")
	(match_operand:HI 1 "address_operand" "p"))]
  ""
  "lda.w %0,%a1")

(define_insn ""
  [(set (match_operand:SI 0 "register_operand" "=r")
	(match_operand:SI 1 "address_operand" "p"))]
  ""
  "lda %0,%a1")

(define_insn ""
  [(set (match_operand:SI 0 "register_operand" "=r")
	(match_operand:DI 1 "address_operand" "p"))]
  ""
  "lda.d %0,%a1")

(define_insn ""
  [(set (match_operand:SI 0 "register_operand" "=r")
	(match_operand:SF 1 "address_operand" "p"))]
  ""
  "lda %0,%a1")

(define_insn ""
  [(set (match_operand:SI 0 "register_operand" "=r")
	(match_operand:DF 1 "address_operand" "p"))]
  ""
  "lda.d %0,%a1")

;;- truncation instructions
(define_insn "truncsiqi2"
  [(set (match_operand:QI 0 "general_operand" "=g")
	(truncate:QI
	 (match_operand:SI 1 "register_operand" "r")))]
  ""
  "*
{
  if (GET_CODE (operands[0]) == MEM)
    return \"st.b %1,%0\";
  return \"or %0,r0,%1\";
}")

(define_insn "trunchiqi2"
  [(set (match_operand:QI 0 "general_operand" "=g")
	(truncate:QI
	 (match_operand:HI 1 "register_operand" "r")))]
  ""
  "*
{
  if (GET_CODE (operands[0]) == MEM)
    return \"st.b %1,%0\";
  return \"or %0,r0,%1\";
}")

(define_insn "truncsihi2"
  [(set (match_operand:HI 0 "general_operand" "=g")
	(truncate:HI
	 (match_operand:SI 1 "register_operand" "r")))]
  ""
  "*
{
  if (GET_CODE (operands[0]) == MEM)
    return \"st.h %1,%0\";
  return \"or %0,r0,%1\";
}")

;;- zero extension instructions

;; Note that the one starting from HImode comes before those for QImode
;; so that a constant operand will match HImode, not QImode.

(define_insn "zero_extendhisi2"
  [(set (match_operand:SI 0 "register_operand" "=r")
	(zero_extend:SI
	 (match_operand:HI 1 "general_operand" "g")))]
  ""
  "*
{
  if (REG_P (operands[1]))
    return \"mask %0,%1,0xffff\";
  if (GET_CODE (operands[1]) == CONST_INT)
    return output_store_const_int (SImode, operands);
  return \"ld.hu %0,%1\";
}")

(define_insn "zero_extendqihi2"
  [(set (match_operand:HI 0 "register_operand" "=r")
	(zero_extend:HI
	 (match_operand:QI 1 "general_operand" "g")))]
  ""
  "*
{
  if (REG_P (operands[1]))
    return \"mask %0,%1,0xff\";
  if (GET_CODE (operands[1]) == CONST_INT)
    return output_store_const_int (SImode, operands);
  return \"ld.bu %0,%1\";
}")

(define_insn "zero_extendqisi2"
  [(set (match_operand:SI 0 "register_operand" "=r")
	(zero_extend:SI
	 (match_operand:QI 1 "general_operand" "g")))]
  ""
  "*
{
  if (REG_P (operands[1]))
    return \"mask %0,%1,0xff\";
  if (GET_CODE (operands[1]) == CONST_INT)
    return output_store_const_int (SImode, operands);
  return \"ld.bu %0,%1\";
}")

;;- sign extension instructions
;; Note that the one starting from HImode comes before those for QImode
;; so that a constant operand will match HImode, not QImode.

(define_insn "extendhisi2"
  [(set (match_operand:SI 0 "register_operand" "=r")
	(sign_extend:SI
	 (match_operand:HI 1 "general_operand" "g")))]
  ""
  "*
{
  if (REG_P (operands[1]))
    return \"ext %0,%1,16<0>\";
  if (GET_CODE (operands[1]) == CONST_INT)
    return output_store_const_int (SImode, operands);
  return \"ld.h %0,%1\";
}")

(define_insn "extendqihi2"
  [(set (match_operand:HI 0 "register_operand" "=r")
	(sign_extend:HI
	 (match_operand:QI 1 "general_operand" "g")))]
  ""
  "*
{
  if (REG_P (operands[1]))
    return \"ext %0,%1,8<0>\";
  if (GET_CODE (operands[1]) == CONST_INT)
    return output_store_const_int (SImode, operands);
  return \"ld.b %0,%1\";
}")

(define_insn "extendqisi2"
  [(set (match_operand:SI 0 "register_operand" "=r")
	(sign_extend:SI
	 (match_operand:QI 1 "general_operand" "g")))]
  ""
  "*
{
  if (REG_P (operands[1]))
    return \"ext %0,%1,8<0>\";
  if (GET_CODE (operands[1]) == CONST_INT)
    return output_store_const_int (SImode, operands);
  return \"ld.b %0,%1\";
}")

;; Conversions between float and double.

(define_insn "extendsfdf2"
  [(set (match_operand:DF 0 "general_operand" "=r")
	(float_extend:DF
	 (match_operand:SF 1 "general_operand" "r")))]
  ""
  "fadd.dss %0,r0,%1")

(define_insn "truncdfsf2"
  [(set (match_operand:SF 0 "general_operand" "=r")
	(float_truncate:SF
	 (match_operand:DF 1 "general_operand" "r")))]
  ""
  "fadd.ssd %0,r0,%1")
;; Conversions between floating point and integer

(define_insn "floatsidf2"
  [(set (match_operand:DF 0 "general_operand" "=r")
	(float:DF (match_operand:SI 1 "general_operand" "r")))]
  ""
  "flt.ds %0,%1")

(define_insn "floatsisf2"
  [(set (match_operand:SF 0 "general_operand" "=r")
	(float:SF (match_operand:SI 1 "general_operand" "r")))]
  ""
  "flt.ss %0,%1")

(define_insn "fixdfsi2"
  [(set (match_operand:SI 0 "general_operand" "=r")
	(fix:SI (fix:DF (match_operand:DF 1 "general_operand" "r"))))]
  ""
  "int.sd %0,%1")

(define_insn "fixsfsi2"
  [(set (match_operand:SI 0 "general_operand" "=r")
	(fix:SI (fix:SF (match_operand:SF 1 "general_operand" "r"))))]
  ""
  "int.ss %0,%1")

;;- arithmetic instructions
;;- add instructions
(define_insn "addsi3"
  [(set (match_operand:SI 0 "register_operand" "=r")
	(plus:SI (match_operand:SI 1 "arith32_operand" "%r")
		 (match_operand:SI 2 "arith32_operand" "rn")))]
  ""
  "*
{
  unsigned int i;

  if (REG_P (operands[2]))
    return \"addu %0,%1,%2\";
  i = INTVAL (operands[2]);
  if (INT_FITS_16_BITS (i))
    return \"addu %0,%1,%2\";
  if (INT_FITS_16_BITS (-i))
    {
      operands[2] = gen_rtx (CONST_INT, VOIDmode, -i);
      return \"subu %0,%1,%2\";
    }
  return \"or.u %0,r0,hi16(%2)\;or %0,%0,lo16(%2)\;addu %0,%1,%0\";
}")

(define_insn "adddf3"
  [(set (match_operand:DF 0 "register_operand" "=r")
	(plus:DF (match_operand:DF 1 "register_operand" "%r")
		 (match_operand:DF 2 "register_operand" "r")))]
  ""
  "fadd.ddd %0,%1,%2")

;; a bunch more can go in here!

(define_insn "addsf3"
  [(set (match_operand:SF 0 "register_operand" "=r")
	(plus:SF (match_operand:SF 1 "register_operand" "%r")
		 (match_operand:SF 2 "register_operand" "r")))]
  ""
  "fadd.sss %0,%1,%2")

;;- subtract instructions
(define_insn "subsi3"
  [(set (match_operand:SI 0 "register_operand" "=r")
	(minus:SI (match_operand:SI 1 "register_operand" "r")
		  (match_operand:SI 2 "arith32_operand" "rn")))]
  ""
  "*
{
  unsigned int i;

  if (REG_P (operands[2]))
    return \"subu %0,%1,%2\";
  i = INTVAL (operands[2]);
  if (INT_FITS_16_BITS (i))
    return \"subu %0,%1,%2\";
  if (INT_FITS_16_BITS (-i))
    {
      operands[2] = gen_rtx (CONST_INT, VOIDmode, -i);
      return \"addu %0,%1,%2\";
    }
  return \"or.u %0,r0,hi16(%2)\;or %0,%0,lo16(%2)\;subu %0,%1,%0\";
}")

(define_insn "subdf3"
  [(set (match_operand:DF 0 "register_operand" "=r")
	(minus:DF (match_operand:DF 1 "register_operand" "%r")
		  (match_operand:DF 2 "register_operand" "r")))]
  ""
  "fsub.ddd %0,%1,%2")

(define_insn "subsf3"
  [(set (match_operand:SF 0 "register_operand" "=r")
	(minus:SF (match_operand:SF 1 "register_operand" "%r")
		  (match_operand:SF 2 "register_operand" "r")))]
  ""
  "fsub.sss %0,%1,%2")

;;- multiply instructions
(define_insn "mulsi3"
  [(set (match_operand:SI 0 "register_operand" "=r")
	(mult:SI (match_operand:SI 1 "register_operand" "%r")
		 (match_operand:SI 2 "arith32_operand" "rn")))]
  ""
  "*
{
  unsigned int i;

  if (REG_P (operands[2]))
    return \"mul %0,%1,%2\";
  i = INTVAL (operands[2]);
  if (INT_FITS_16_BITS (i))
    return \"mul %0,%1,%2\";
  return \"or.u %0,r0,hi16(%2)\;or %0,%0,lo16(%2)\;mul %0,%1,%0\";
}")

(define_insn "umulsi3"
  [(set (match_operand:SI 0 "register_operand" "=r")
	(umult:SI (match_operand:SI 1 "register_operand" "%r")
		  (match_operand:SI 2 "arith_operand" "rI")))]
  ""
  "mul %0,%1,%2")

(define_insn "muldf3"
  [(set (match_operand:DF 0 "register_operand" "=r")
	(mult:DF (match_operand:DF 1 "register_operand" "%r")
		 (match_operand:DF 2 "register_operand" "r")))]
  ""
  "fmul.ddd %0,%1,%2")

(define_insn "mulsf3"
  [(set (match_operand:SF 0 "register_operand" "=r")
	(mult:SF (match_operand:SF 1 "register_operand" "%r")
		 (match_operand:SF 2 "register_operand" "r")))]
  ""
  "fmul.sss %0,%1,%2")

;;- divide instructions
(define_insn "divsi3"
  [(set (match_operand:SI 0 "register_operand" "=r")
	(div:SI (match_operand:SI 1 "register_operand" "r")
		(match_operand:SI 2 "arith32_operand" "rn")))]
  ""
  "*
{
  unsigned int i;

  if (REG_P (operands[2]))
    return \"div %0,%1,%2\";
  i = INTVAL (operands[2]);
  if (INT_FITS_16_BITS (i))
    return \"div %0,%1,%2\";
  return \"or.u %0,r0,hi16(%2)\;or %0,%0,lo16(%2)\;div %0,%1,%0\";
}")


(define_insn "udivsi3"
  [(set (match_operand:SI 0 "register_operand" "=r")
	(udiv:SI (match_operand:SI 1 "register_operand" "r")
		 (match_operand:SI 2 "arith_operand" "rI")))]
  ""
  "div %0,%1,%2")

(define_insn "divdf3"
  [(set (match_operand:DF 0 "register_operand" "=r")
	(div:DF (match_operand:DF 1 "register_operand" "r")
		(match_operand:DF 2 "register_operand" "r")))]
  ""
  "fdiv.ddd %0,%1,%2")

(define_insn "divsf3"
  [(set (match_operand:SF 0 "register_operand" "=r")
	(div:SF (match_operand:SF 1 "register_operand" "r")
		(match_operand:SF 2 "register_operand" "r")))]
  ""
  "fdiv.sss %0,%1,%2")

;; Remainder instructions.

(define_insn "modsi3"
  [(set (match_operand:SI 0 "register_operand" "=r")
	(mod:SI (match_operand:SI 1 "register_operand" "r")
		(match_operand:SI 2 "arith32_operand" "rn")))]
  ""
  "*
{
  unsigned int i;

  if (REG_P (operands[2]))
    return \"div %0,%1,%2\;mul %0,%0,%2\;sub %0,%1,%0\";
  i = INTVAL (operands[2]);
  if (INT_FITS_16_BITS (i))
    return \"div %0,%1,%2\;mul %0,%0,%2\;sub %0,%1,%0\";
  if (INT_FITS_16_BITS (-i))
    fatal (\"implement negative case for mod\");
  fatal (\"implement 32 bit case for mod\");
}")

(define_insn "umodsi3"
  [(set (match_operand:SI 0 "register_operand" "=r")
	(umod:SI (match_operand:SI 1 "register_operand" "r")
		 (match_operand:SI 2 "arith_operand" "rI")))]
  ""
  "*
{
  unsigned int i;

  if (REG_P (operands[2]))
    return \"div %0,%1,%2\;mul %0,%0,%2\;sub %0,%1,%0\";
  i = INTVAL (operands[2]);
  if (INT_FITS_16_BITS (i))
    return \"div %0,%1,%2\;mul %0,%0,%2\;sub %0,%1,%0\";
  if (INT_FITS_16_BITS (-i))
    fatal (\"implement negative case for umod\");
  fatal (\"implement 32 bit case for umod\");
}")

(define_insn "divmodsi4"
  [(set (match_operand:SI 0 "register_operand" "=r")
	(div:SI (match_operand:SI 1 "register_operand" "r")
		(match_operand:SI 2 "arith_operand" "rI")))
   (set (match_operand:SI 3 "register_operand" "=r")
	(mod:SI (match_dup 1) (match_dup 2)))]
  ""
  "div %0,%1,%2\;mul %3,%0,%2\;sub %3,%1,%3")

(define_insn "udivmodsi4"
  [(set (match_operand:SI 0 "register_operand" "=r")
	(udiv:SI (match_operand:SI 1 "register_operand" "r")
		(match_operand:SI 2 "arith_operand" "rI")))
   (set (match_operand:SI 3 "register_operand" "=r")
	(umod:SI (match_dup 1) (match_dup 2)))]
  ""
  "div %0,%1,%2\;mul %3,%0,%2\;sub %3,%1,%3")

;;- and instructions (with complement also)
(define_insn "andsi3"
  [(set (match_operand:SI 0 "register_operand" "=r")
	(and:SI (match_operand:SI 1 "register_operand" "%r")
		(match_operand:SI 2 "arith32_operand" "rn")))]
  ""
  "*
{
  unsigned int i;

  if (REG_P (operands[2]))
    return \"and %0,%1,%2\";
  i = INTVAL (operands[2]);
  if (INT_FITS_16_BITS (i))
    return \"mask %0,%1,%2\";
  if (INT_FITS_16_BITS (-i))
    {
      operands[2] = gen_rtx (CONST_INT, VOIDmode, i & 0xffff);
      return \"and %0,%1,%2\";
    }
  return \"and.u %0,%1,hi16(%2)\;and %0,%1,lo16(%2)\";
}")

(define_insn "andcbsi3"
  [(set (match_operand:SI 0 "register_operand" "=r")
	(and:SI (match_operand:SI 1 "register_operand" "%r")
		(not:SI (match_operand:SI 2 "register_operand" "r"))))]
  ""
  "and.c %0,%1,%2")

;;- Bit set (inclusive or) instructions (with complement also)
(define_insn "iorsi3"
  [(set (match_operand:SI 0 "register_operand" "=r")
	(ior:SI (match_operand:SI 1 "register_operand" "%r")
		(match_operand:SI 2 "arith32_operand" "rn")))]
  ""
  "*
{
  unsigned int i;

  if (REG_P (operands[2]))
    return \"or %0,%1,%2\";
  i = INTVAL (operands[2]);
  if (INT_FITS_16_BITS (i))
    return \"or %0,%1,%2\";
  return \"or.u %0,%1,hi16(%2)\;or %0,%1,lo16(%2)\";
}")

(define_insn "iorcbsi3"
  [(set (match_operand:SI 0 "register_operand" "=r")
	(ior:SI (match_operand:SI 1 "register_operand" "%r")
		(not:SI (match_operand:SI 2 "register_operand" "r"))))]
  ""
  "or.c %0,%1,%2")

;;- xor instructions (with complement also)
(define_insn "xorsi3"
  [(set (match_operand:SI 0 "register_operand" "=r")
	(xor:SI (match_operand:SI 1 "register_operand" "%r")
		(match_operand:SI 2 "arith32_operand" "rn")))]
  ""
  "*
{
  unsigned int i;

  if (REG_P (operands[2]))
    return \"xor %0,%1,%2\";
  i = INTVAL (operands[2]);
  if (INT_FITS_16_BITS (i))
    return \"xor %0,%1,%2\";
  if ((i & 0xffff) == 0)
    return \"xor.u %0,%1,hi16(%2)\";
  return \"xor.u %0,%1,hi16(%2)\;xor %0,%1,lo16(%2)\";
}")

(define_insn "xorcbsi3"
  [(set (match_operand:SI 0 "register_operand" "=r")
	(xor:SI (match_operand:SI 1 "register_operand" "%r")
		(not:SI (match_operand:SI 2 "register_operand" "r"))))]
  ""
  "xor.c %0,%1,%2")

;;- one complement instructions
(define_insn "one_cmplsi2"
  [(set (match_operand:SI 0 "register_operand" "=r")
	(not:SI (match_operand:SI 1 "register_operand" "r")))]
  ""
  "xor.c %0,%1,r0")

;; Optimized special case of shifting.
;; Must precede the general case.

(define_insn ""
  [(set (match_operand:SI 0 "register_operand" "=r")
	(ashiftrt:SI (match_operand:SI 1 "memory_operand" "m")
		     (const_int 24)))]
  ""
  "ld.b %0,%1")

(define_insn ""
  [(set (match_operand:SI 0 "register_operand" "=r")
	(lshiftrt:SI (match_operand:SI 1 "memory_operand" "m")
		     (const_int 24)))]
  ""
  "ld.bu %0,%1")

;;- arithmetic shift instructions
(define_insn "ashlsi3"
  [(set (match_operand:SI 0 "register_operand" "=r")
	(ashift:SI (match_operand:SI 1 "register_operand" "r")
		   (match_operand:SI 2 "arith_operand" "rI")))]
  ""
  "*
{
  if (GET_CODE (operands[2]) == CONST_INT)
    return \"mak %0,%1,0<%2>\";
  return \"mask %0,%2,0x1f\;mak %0,%1,%0\";
}")

(define_insn "ashrsi3"
  [(set (match_operand:SI 0 "register_operand" "=r")
	(ashiftrt:SI (match_operand:SI 1 "register_operand" "r")
		     (match_operand:SI 2 "arith_operand" "rI")))]
  ""
  "*
{
  if (GET_CODE (operands[2]) == CONST_INT)
    return \"ext %0,%1,0<%2>\";
  return \"mask %0,%2,0x1f\;ext %0,%1,%0\";
}")

;;- logical shift instructions
(define_insn "lshrsi3"
  [(set (match_operand:SI 0 "register_operand" "=r")
	(lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
		     (match_operand:SI 2 "arith_operand" "rI")))]
  ""
  "*
{
  if (GET_CODE (operands[2]) == CONST_INT)
    return \"extu %0,%1,0<%2>\";
  return \"mask %0,%2,0x1f\;extu %0,%1,%0\";
}")

;;- rotate instructions

(define_insn "rotlsi3"
  [(set (match_operand:SI 0 "register_operand" "=r")
	(rotate:SI (match_operand:SI 1 "register_operand" "r")
		   (match_operand:SI 2 "arith_operand" "rI")))]
  ""
  "*
{
  if (GET_CODE (operands[2]) == CONST_INT)
    {
      operands[2] = gen_rtx (CONST_INT, SImode, 32 - INTVAL (operands[2]));
      return \"rot %0,%1,%2\";
    }
  return \"or %0,r0,32\;sub %0,%2,%0\;rot %0,%1,%0\";
}")

(define_insn "rotrsi3"
  [(set (match_operand:SI 0 "register_operand" "=r")
	(rotatert:SI (match_operand:SI 1 "register_operand" "r")
		     (match_operand:SI 2 "arith_operand" "rI")))]
  ""
  "rot %0,%1,%2")

;; Special cases of bit-field insns which we should
;; recognize in preference to the general case.
;; These handle aligned 8-bit and 16-bit fields,
;; which can usually be done with move instructions.

(define_insn ""
  [(set (zero_extract:SI (match_operand:SI 0 "general_operand" "+ro")
			 (match_operand:SI 1 "int5_operand" "K")
			 (match_operand:SI 2 "int5_operand" "K"))
	(match_operand:SI 3 "register_operand" "r"))]
  "(INTVAL (operands[1]) == 8 || INTVAL (operands[1]) == 16)
   && INTVAL (operands[2]) % INTVAL (operands[1]) == 0"
  "*
{
  if (REG_P (operands[0]))
    {
      if (INTVAL (operands[1]) + INTVAL (operands[2]) != 32)
        return \"mak %0,%3,%1<%2>\";
    }
  else
    operands[0]
      = adj_offsettable_operand (operands[0], INTVAL (operands[2]) / 8);

  if (GET_CODE (operands[3]) == MEM)
    operands[3] = adj_offsettable_operand (operands[3],
					   (32 - INTVAL (operands[1])) / 8);
  if (INTVAL (operands[1]) == 8)
    return \"st.b %3,%0\";
  return \"st.w %3,%0\";
}")

(define_insn ""
  [(set (match_operand:SI 0 "register_operand" "=&r")
	(zero_extract:SI (match_operand:SI 1 "general_operand" "ro")
			 (match_operand:SI 2 "int5_operand" "K")
			 (match_operand:SI 3 "int5_operand" "K")))]
  "(INTVAL (operands[2]) == 8 || INTVAL (operands[2]) == 16)
   && INTVAL (operands[3]) % INTVAL (operands[2]) == 0"
  "*
{
  if (REG_P (operands[1]))
    {
      if (INTVAL (operands[2]) + INTVAL (operands[3]) != 32)
	return \"extu %0,%1,%2<%3>\";
    }
  else
    operands[1]
      = adj_offsettable_operand (operands[1], INTVAL (operands[3]) / 8);

  if (GET_CODE (operands[0]) == MEM)
    operands[0] = adj_offsettable_operand (operands[0],
					   (32 - INTVAL (operands[1])) / 8);
  if (INTVAL (operands[2]) == 8)
    return \"ld.bu %0,%1\";
  return \"ld.hu %0,%1\";
}")

(define_insn ""
  [(set (match_operand:SI 0 "register_operand" "=r")
	(sign_extract:SI (match_operand:SI 1 "general_operand" "ro")
			 (match_operand:SI 2 "int5_operand" "K")
			 (match_operand:SI 3 "int5_operand" "K")))]
  "(INTVAL (operands[2]) == 8 || INTVAL (operands[2]) == 16)
   && INTVAL (operands[3]) % INTVAL (operands[2]) == 0"
  "*
{
  if (REG_P (operands[1]))
    {
      if (INTVAL (operands[2]) + INTVAL (operands[3]) != 32)
	return \"extu %0,%1,%2<%3>\";
    }
  else
    operands[1]
      = adj_offsettable_operand (operands[1], INTVAL (operands[3]) / 8);

  if (INTVAL (operands[2]) == 8)
    return \"ld.b %0,%1\";
  return \"ld.h %0,%1\";
}")

;; Bit field instructions.

(define_insn "extv"
  [(set (match_operand:SI 0 "register_operand" "=r,r")
	(sign_extract:SI (match_operand:QI 1 "register_operand" "r,r")
			 (match_operand:SI 2 "arith_operand" "K,rK")
			 (match_operand:SI 3 "arith_operand" "K,&r")))]
  ""
  "*
{
  if (GET_CODE (operands[3]) == CONST_INT)
    return \"ext %0,%1,%2<%3>\";
  if (GET_CODE (operands[2]) == CONST_INT)
    {
      operands[2] = gen_rtx (CONST_INT, VOIDmode,
			     (INTVAL (operands[2]) & 0x1f) << 5);
      return \"mask %3,%3,0x1f\;or %3,%3,%2\;ext %0,%1,%3\";
    }
  return \"mak %0,%2,5<5>\;mask %3,%3,0x1f\;or %3,%3,%0\;ext %0,%1,%3\";
}")

(define_insn ""
  [(set (match_operand:SI 0 "register_operand" "=r,r")
	(sign_extract:SI (match_operand:SI 1 "register_operand" "r,r")
			 (match_operand:SI 2 "arith_operand" "K,rK")
			 (match_operand:SI 3 "arith_operand" "K,&r")))]
  ""
  "*
{
  if (GET_CODE (operands[3]) == CONST_INT)
    return \"ext %0,%1,%2<%3>\";
  if (GET_CODE (operands[2]) == CONST_INT)
    {
      operands[2] = gen_rtx (CONST_INT, VOIDmode,
			     (INTVAL (operands[2]) & 0x1f) << 5);
      return \"mask %3,%3,0x1f\;or %3,%3,%2\;ext %0,%1,%3\";
    }
  return \"mak %0,%2,5<5>\;mask %3,%3,0x1f\;or %3,%3,%0\;ext %0,%1,%3\";
}")

(define_insn "extzv"
  [(set (match_operand:SI 0 "register_operand" "=r,r")
	(zero_extract:SI (match_operand:QI 1 "register_operand" "r,r")
			 (match_operand:SI 2 "arith_operand" "K,Kr")
			 (match_operand:SI 3 "arith_operand" "K,&r")))]
  ""
  "*
{
  if (GET_CODE (operands[3]) == CONST_INT)
    return \"extu %0,%1,%2<%3>\";
  if (GET_CODE (operands[2]) == CONST_INT)
    {
      operands[2] = gen_rtx (CONST_INT, VOIDmode,
			     (INTVAL (operands[2]) & 0x1f) << 5);
      return \"mask %3,%3,0x1f\;or %3,%3,%2\;extu %0,%1,%3\";
    }
  return \"mak %0,%2,5<5>\;mask %3,%3,0x1f\;or %3,%3,%0\;ext %0,%1,%3\";
}")

(define_insn ""
  [(set (match_operand:SI 0 "register_operand" "=r,r")
	(zero_extract:SI (match_operand:SI 1 "register_operand" "r,r")
			 (match_operand:SI 2 "arith_operand" "K,Kr")
			 (match_operand:SI 3 "arith_operand" "K,&r")))]
  ""
  "*
{
  if (GET_CODE (operands[3]) == CONST_INT)
    return \"extu %0,%1,%2<%3>\";
  if (GET_CODE (operands[2]) == CONST_INT)
    {
      operands[2] = gen_rtx (CONST_INT, VOIDmode,
			     (INTVAL (operands[2]) & 0x1f) << 5);
      return \"mask %3,%3,0x1f\;or %3,%3,%2\;extu %0,%1,%3\";
    }
  return \"mak %0,%2,5<5>\;mask %3,%3,0x1f\;or %3,%3,%0\;ext %0,%1,%3\";
}")

(define_insn ""
  [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "r,r,r")
			 (match_operand:SI 1 "arith_operand" "K,K,&r")
			 (match_operand:SI 2 "arith_operand" "K,&r,&"))
	(const_int 0))]
  ""
  "*
{
  if (GET_CODE (operands[2]) == CONST_INT)
    return \"clr %0,%0,%1<%2>\";
  if (GET_CODE (operands[1]) == CONST_INT)
    {
      operands[1] = gen_rtx (CONST_INT, VOIDmode,
			     (INTVAL (operands[1]) & 0x1f) << 5);
      return \"mask %2,%2,0x1f\;or %2,%2,%1\;clr %0,%0,%2\";
    }
  return \"mak %1,%1,5<5>\;mask %2,%2,0x1f\;or %2,%2,%1\;clr %0,%0,%2\";
}")

(define_insn ""
  [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "r,r,r")
			 (match_operand:SI 1 "arith_operand" "K,K,&r")
			 (match_operand:SI 2 "arith_operand" "K,&r,&r"))
	(const_int -1))]
  ""
  "*
{
  if (GET_CODE (operands[2]) == CONST_INT)
    return \"set %0,%0,%1<%2>\";
  if (GET_CODE (operands[1]) == CONST_INT)
    {
      operands[1] = gen_rtx (CONST_INT, VOIDmode,
			     (INTVAL (operands[1]) & 0x1f) << 5);
      return \"mask %2,%2,0x1f\;or %2,%2,%1\;set %0,%0,%2\";
    }
  return \"mak %1,%1,5<5>\;mask %2,%2,0x1f\;or %2,%2,%1\;set %0,%0,%2\";
}")

(define_insn "insv"
  [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "r,r,r")
			 (match_operand:SI 1 "arith_operand" "K,K,&r")
			 (match_operand:SI 2 "arith_operand" "K,&r,&r"))
	(match_operand:SI 3 "register_operand" "&r,&r,r"))]
  ""
  "*
{
  if (GET_CODE (operands[2]) == CONST_INT)
    return \"mak %3,%3,%1<%2>\;clr %0,%0,%1<%2>\;or %0,%0,%3\";
  if (GET_CODE (operands[1]) == CONST_INT)
    {
      operands[1] = gen_rtx (CONST_INT, VOIDmode,
			     (INTVAL (operands[1]) & 0x1f) << 5);
      return \"mask %2,%2,0x1f\;or %2,%2,%1\;mak %3,%3,%2\;clr %0,%0,%2\;or %0,%0,%3\";
    }
  return \"mak %1,%1,5<5>\;mask %2,%2,0x1f\;or %2,%2,%1\;mak %1,%3,%2\;clr %0,%0,%2\;or %0,%0,%1\";
}")

;; negate insns
(define_insn "negsi2"
  [(set (match_operand:SI 0 "register_operand" "=r")
	(neg:SI (match_operand:SI 1 "arith_operand" "rI")))]
  ""
  "sub %0,r0,%1")

(define_insn "negdf2"
  [(set (match_operand:DF 0 "register_operand" "=r")
	(neg:DF (match_operand:DF 1 "register_operand" "r")))]
  ""
  "fsub.dsd %0,r0,%1")

(define_insn "negsf2"
  [(set (match_operand:SF 0 "register_operand" "=r")
	(neg:SF (match_operand:SF 1 "register_operand" "r")))]
  ""
  "fsub.sss %0,r0,%1")

;; Store condition code values into registers
(define_insn "seq"
  [(set (match_operand:SI 0 "general_operand" "=g")
	(eq (cc0) (const_int 0)))]
  ""
  "*
{
  CC_STATUS_INIT;
  if (REG_P (operands[0]))
    return \"extu %0,r25,1<eq>\";
  return \"extu r25,r25,1<eq>\;st r25,%0\";
}")

(define_peephole
  [(set (cc0) (match_operand:SI 0 "register_operand" "r"))
   (set (match_operand:SI 1 "general_operand" "=g")
	(eq (cc0) (const_int 0)))]
  ""
  "*
{
  CC_STATUS_INIT;
  if (REG_P (operands[1]))
    return \"cmp r25,%0,0\;extu %1,r25,1<eq>\";
  return \"cmp r25,%0,0\;extu r25,r25,1<eq>\;st r25,%1\";
}")

(define_peephole
  [(set (cc0)
	(compare
	 (match_operand:SI 0 "arith_operand" "r")
	 (match_operand:SI 1 "arith_operand" "rI")))
   (set (match_operand:SI 2 "general_operand" "=g")
	(eq (cc0) (const_int 0)))]
  ""
  "*
{
  CC_STATUS_INIT;
  if (REG_P (operands[2]))
    return \"cmp r25,%0,%1\;extu %2,r25,1<eq>\";
  return \"cmp r25,%0,%1\;extu r25,r25,1<eq>\;st r25,%2\";
}")

(define_insn "sne"
  [(set (match_operand:SI 0 "general_operand" "=g")
	(ne (cc0) (const_int 0)))]
  ""
  "*
{
  CC_STATUS_INIT;
  if (REG_P (operands[0]))
    return \"extu %0,r25,1<ne>\";
  return \"extu r25,r25,1<ne>\;st r25,%0\";
}")

(define_peephole
  [(set (cc0) (match_operand:SI 0 "register_operand" "r"))
   (set (match_operand:SI 1 "general_operand" "=g")
	(ne (cc0) (const_int 0)))]
  ""
  "*
{
  CC_STATUS_INIT;
  if (REG_P (operands[1]))
    return \"cmp r25,%0,0\;extu %1,r25,1<ne>\";
  return \"cmp r25,%0,0\;extu r25,r25,1<ne>\;st r25,%1\";
}")

(define_peephole
  [(set (cc0)
	(compare
	 (match_operand:SI 0 "arith_operand" "r")
	 (match_operand:SI 1 "arith_operand" "rI")))
   (set (match_operand:SI 2 "general_operand" "=g")
	(ne (cc0) (const_int 0)))]
  ""
  "*
{
  CC_STATUS_INIT;
  if (REG_P (operands[2]))
    return \"cmp r25,%0,%1\;extu %2,r25,1<ne>\";
  return \"cmp r25,%0,%1\;extu r25,r25,1<ne>\;st r25,%2\";
}")

(define_insn "sgt"
  [(set (match_operand:SI 0 "general_operand" "=g")
	(gt (cc0) (const_int 0)))]
  ""
  "*
{
  CC_STATUS_INIT;
  if (REG_P (operands[0]))
    return \"extu %0,r25,1<gt>\";
  return \"extu r25,r25,1<gt>\;st r25,%0\";
}")

(define_peephole
  [(set (cc0) (match_operand:SI 0 "register_operand" "r"))
   (set (match_operand:SI 1 "general_operand" "=g")
	(gt (cc0) (const_int 0)))]
  ""
  "*
{
  CC_STATUS_INIT;
  if (REG_P (operands[1]))
    return \"cmp r25,%0,0\;extu %1,r25,1<gt>\";
  return \"cmp r25,%0,0\;extu r25,r25,1<gt>\;st r25,%1\";
}")

(define_peephole
  [(set (cc0)
	(compare
	 (match_operand:SI 0 "arith_operand" "r")
	 (match_operand:SI 1 "arith_operand" "rI")))
   (set (match_operand:SI 2 "general_operand" "=g")
	(gt (cc0) (const_int 0)))]
  ""
  "*
{
  CC_STATUS_INIT;
  if (REG_P (operands[2]))
    return \"cmp r25,%0,%1\;extu %2,r25,1<gt>\";
  return \"cmp r25,%0,%1\;extu r25,r25,1<gt>\;st r25,%2\";
}")

(define_insn "sgtu"
  [(set (match_operand:SI 0 "general_operand" "=g")
	(gtu (cc0) (const_int 0)))]
  ""
  "*
{
  CC_STATUS_INIT;
  if (REG_P (operands[0]))
    return \"extu %0,r25,1<hi>\";
  return \"extu r25,r25,1<hi>\;st r25,%0\";
}")

(define_peephole
  [(set (cc0) (match_operand:SI 0 "register_operand" "r"))
   (set (match_operand:SI 1 "general_operand" "=g")
	(gtu (cc0) (const_int 0)))]
  ""
  "*
{
  CC_STATUS_INIT;
  if (REG_P (operands[1]))
    return \"cmp r25,%0,0\;extu %1,r25,1<hi>\";
  return \"cmp r25,%0,0\;extu r25,r25,1<hi>\;st r25,%1\";
}")

(define_peephole
  [(set (cc0)
	(compare
	 (match_operand:SI 0 "arith_operand" "r")
	 (match_operand:SI 1 "arith_operand" "rI")))
   (set (match_operand:SI 2 "general_operand" "=g")
	(gtu (cc0) (const_int 0)))]
  ""
  "*
{
  CC_STATUS_INIT;
  if (REG_P (operands[2]))
    return \"cmp r25,%0,%1\;extu %2,r25,1<hi>\";
  return \"cmp r25,%0,%1\;extu r25,r25,1<hi>\;st r25,%2\";
}")

(define_insn "slt"
  [(set (match_operand:SI 0 "general_operand" "=g")
	(lt (cc0) (const_int 0)))]
  ""
  "*
{
  CC_STATUS_INIT;
  if (REG_P (operands[0]))
    return \"extu %0,r25,1<lt>\";
  return \"extu r25,r25,1<lt>\;st r25,%0\";
}")

(define_peephole
  [(set (cc0) (match_operand:SI 0 "register_operand" "r"))
   (set (match_operand:SI 1 "general_operand" "=g")
	(lt (cc0) (const_int 0)))]
  ""
  "*
{
  CC_STATUS_INIT;
  if (REG_P (operands[1]))
    return \"cmp r25,%0,0\;extu %1,r25,1<lt>\";
  return \"cmp r25,%0,0\;extu r25,r25,1<lt>\;st r25,%1\";
}")

(define_peephole
  [(set (cc0)
	(compare
	 (match_operand:SI 0 "arith_operand" "r")
	 (match_operand:SI 1 "arith_operand" "rI")))
   (set (match_operand:SI 2 "general_operand" "=g")
	(lt (cc0) (const_int 0)))]
  ""
  "*
{
  CC_STATUS_INIT;
  if (REG_P (operands[2]))
    return \"cmp r25,%0,%1\;extu %2,r25,1<lt>\";
  return \"cmp r25,%0,%1\;extu r25,r25,1<lt>\;st r25,%2\";
}")

(define_insn "sltu"
  [(set (match_operand:SI 0 "general_operand" "=g")
	(ltu (cc0) (const_int 0)))]
  ""
  "*
{
  CC_STATUS_INIT;
  if (REG_P (operands[0]))
    return \"extu %0,r25,1<lo>\";
  return \"extu r25,r25,1<lo>\;st r25,%0\";
}")

(define_peephole
  [(set (cc0) (match_operand:SI 0 "register_operand" "r"))
   (set (match_operand:SI 1 "general_operand" "=g")
	(ltu (cc0) (const_int 0)))]
  ""
  "*
{
  CC_STATUS_INIT;
  if (REG_P (operands[1]))
    return \"cmp r25,%0,0\;extu %1,r25,1<lo>\";
  return \"cmp r25,%0,0\;extu r25,r25,1<lo>\;st r25,%1\";
}")

(define_peephole
  [(set (cc0)
	(compare
	 (match_operand:SI 0 "arith_operand" "r")
	 (match_operand:SI 1 "arith_operand" "rI")))
   (set (match_operand:SI 2 "general_operand" "=g")
	(ltu (cc0) (const_int 0)))]
  ""
  "*
{
  CC_STATUS_INIT;
  if (REG_P (operands[2]))
    return \"cmp r25,%0,%1\;extu %2,r25,1<lo>\";
  return \"cmp r25,%0,%1\;extu r25,r25,1<lo>\;st r25,%2\";
}")

(define_insn "sge"
  [(set (match_operand:SI 0 "general_operand" "=g")
	(ge (cc0) (const_int 0)))]
  ""
  "*
{
  CC_STATUS_INIT;
  if (REG_P (operands[0]))
    return \"extu %0,r25,1<ge>\";
  return \"extu r25,r25,1<ge>\;st r25,%0\";
}")

(define_peephole
  [(set (cc0) (match_operand:SI 0 "register_operand" "r"))
   (set (match_operand:SI 1 "general_operand" "=g")
	(ge (cc0) (const_int 0)))]
  ""
  "*
{
  CC_STATUS_INIT;
  if (REG_P (operands[1]))
    return \"cmp r25,%0,0\;extu %1,r25,1<ge>\";
  return \"cmp r25,%0,0\;extu r25,r25,1<ge>\;st r25,%1\";
}")

(define_peephole
  [(set (cc0)
	(compare
	 (match_operand:SI 0 "arith_operand" "r")
	 (match_operand:SI 1 "arith_operand" "rI")))
   (set (match_operand:SI 2 "general_operand" "=g")
	(ge (cc0) (const_int 0)))]
  ""
  "*
{
  CC_STATUS_INIT;
  if (REG_P (operands[2]))
    return \"cmp r25,%0,%1\;extu %2,r25,1<ge>\";
  return \"cmp r25,%0,%1\;extu r25,r25,1<ge>\;st r25,%2\";
}")

(define_insn "sgeu"
  [(set (match_operand:SI 0 "general_operand" "=g")
	(geu (cc0) (const_int 0)))]
  ""
  "*
{
  CC_STATUS_INIT;
  if (REG_P (operands[0]))
    return \"extu %0,r25,1<hs>\";
  return \"extu r25,r25,1<hs>\;st r25,%0\";
}")

(define_peephole
  [(set (cc0) (match_operand:SI 0 "register_operand" "r"))
   (set (match_operand:SI 1 "general_operand" "=g")
	(geu (cc0) (const_int 0)))]
  ""
  "*
{
  CC_STATUS_INIT;
  if (REG_P (operands[1]))
    return \"cmp r25,%0,0\;extu %1,r25,1<hs>\";
  return \"cmp r25,%0,0\;extu r25,r25,1<hs>\;st r25,%1\";
}")

(define_peephole
  [(set (cc0)
	(compare
	 (match_operand:SI 0 "arith_operand" "r")
	 (match_operand:SI 1 "arith_operand" "rI")))
   (set (match_operand:SI 2 "general_operand" "=g")
	(geu (cc0) (const_int 0)))]
  ""
  "*
{
  CC_STATUS_INIT;
  if (REG_P (operands[2]))
    return \"cmp r25,%0,%1\;extu %2,r25,1<hs>\";
  return \"cmp r25,%0,%1\;extu r25,r25,1<hs>\;st r25,%2\";
}")

(define_insn "sle"
  [(set (match_operand:SI 0 "general_operand" "=g")
	(le (cc0) (const_int 0)))]
  ""
  "*
{
  CC_STATUS_INIT;
  if (REG_P (operands[0]))
    return \"extu %0,r25,1<le>\";
  return \"extu r25,r25,1<le>\;st r25,%0\";
}")

(define_peephole
  [(set (cc0) (match_operand:SI 0 "register_operand" "r"))
   (set (match_operand:SI 1 "general_operand" "=g")
	(le (cc0) (const_int 0)))]
  ""
  "*
{
  CC_STATUS_INIT;
  if (REG_P (operands[1]))
    return \"cmp r25,%0,0\;extu %1,r25,1<le>\";
  return \"cmp r25,%0,0\;extu r25,r25,1<le>\;st r25,%1\";
}")

(define_peephole
  [(set (cc0)
	(compare
	 (match_operand:SI 0 "arith_operand" "r")
	 (match_operand:SI 1 "arith_operand" "rI")))
   (set (match_operand:SI 2 "general_operand" "=g")
	(le (cc0) (const_int 0)))]
  ""
  "*
{
  CC_STATUS_INIT;
  if (REG_P (operands[2]))
    return \"cmp r25,%0,%1\;extu %2,r25,1<le>\";
  return \"cmp r25,%0,%1\;extu r25,r25,1<le>\;st r25,%2\";
}")

(define_insn "sleu"
  [(set (match_operand:SI 0 "general_operand" "=g")
	(leu (cc0) (const_int 0)))]
  ""
  "*
{
  CC_STATUS_INIT;
  if (REG_P (operands[0]))
    return \"extu %0,r25,1<ls>\";
  return \"extu r25,r25,1<ls>\;st r25,%0\";
}")

(define_peephole
  [(set (cc0) (match_operand:SI 0 "register_operand" "r"))
   (set (match_operand:SI 1 "general_operand" "=g")
	(leu (cc0) (const_int 0)))]
  ""
  "*
{
  CC_STATUS_INIT;
  if (REG_P (operands[1]))
    return \"cmp r25,%0,0\;extu %1,r25,1<ls>\";
  return \"cmp r25,%0,0\;extu r25,r25,1<ls>\;st r25,%1\";
}")

(define_peephole
  [(set (cc0)
	(compare
	 (match_operand:SI 0 "arith_operand" "r")
	 (match_operand:SI 1 "arith_operand" "rI")))
   (set (match_operand:SI 2 "general_operand" "=g")
	(leu (cc0) (const_int 0)))]
  ""
  "*
{
  CC_STATUS_INIT;
  if (REG_P (operands[2]))
    return \"cmp r25,%0,%1\;extu %2,r25,1<ls>\";
  return \"cmp r25,%0,%1\;extu r25,r25,1<ls>\;st r25,%2\";
}")


;; Unconditional and other jump instructions
(define_insn "jump"
  [(set (pc)
	(label_ref (match_operand 0 "" "")))]
  ""
  "br %l0")

(define_insn ""
  [(set (pc)
    (label_ref (match_operand 0 "" "")))
   (clobber (const_int 1))]
  ""
  "br.n %l0")

(define_insn "tablejump"
  [(set (pc) (match_operand:SI 0 "register_operand" "r"))
   (use (label_ref (match_operand 1 "" "")))]
  ""
  "jmp %0")

;;- jump to subroutine
(define_insn "call"
  [(call (match_operand:SI 0 "memory_operand" "m")
	 (match_operand:SI 1 "general_operand" "g"))
   (use (reg:SI 1))]
  ;;- Don't use operand 1 for most machines.
  ""
  "*
{
  operands[0] = XEXP (operands[0], 0);
  if (REG_P (operands[0]))
    return \"jsr %0\";
  return \"bsr %0\";
}")

(define_insn ""
  [(call (match_operand:SI 0 "memory_operand" "m")
	 (match_operand:SI 1 "general_operand" "g"))
   (clobber (const_int 1))
   (use (reg:SI 1))]
  ;;- Don't use operand 1 for most machines.
  ""
  "*
{
  operands[0] = XEXP (operands[0], 0);
  if (REG_P (operands[0]))
    return \"jsr.n %0\";
  return \"bsr.n %0\";
}")

;;- jump to subroutine
(define_insn "call_value"
  [(set (match_operand 0 "" "=r")
	(call (match_operand:SI 1 "memory_operand" "m")
	      (match_operand:SI 2 "general_operand" "g")))
   (use (reg:SI 1))]
  ;;- Don't use operand 2 for most machines.
  ""
  "*
{
  operands[1] = XEXP (operands[1], 0);
  if (REG_P (operands[1]))
    return \"jsr %1\";
  return \"bsr %1\";
}")

(define_insn ""
  [(set (match_operand 0 "" "=r")
	(call (match_operand:SI 1 "memory_operand" "m")
	      (match_operand:SI 2 "general_operand" "g")))
   (use (reg:SI 1))
   (clobber (const_int 2))]
  ;;- Don't use operand 2 for most machines.
  ""
  "*
{
  operands[1] = XEXP (operands[1], 0);
  if (REG_P (operands[1]))
    return \"jsr.n %1\";
  return \"bsr.n %1\";
}")

;; A memory ref with constant address is not normally valid.
;; But it is valid in a call insns.  This pattern allows the
;; loading of the address to combine with the call.
(define_insn ""
  [(call (mem:SI (match_operand:SI 0 "" "i"))
	 (match_operand:SI 1 "general_operand" "g"))
   (use (reg:SI 1))]
  ;;- Don't use operand 1 for most machines.
  "GET_CODE (operands[0]) == SYMBOL_REF"
  "bsr %0")

(define_insn ""
  [(call (mem:SI (match_operand:SI 0 "" "i"))
	 (match_operand:SI 1 "general_operand" "g"))
   (clobber (const_int 1))
   (use (reg:SI 1))]
  ;;- Don't use operand 1 for most machines.
  "GET_CODE (operands[0]) == SYMBOL_REF"
  "bsr.n %0")

(define_insn "nop"
  [(const_int 0)]
  ""
  "nop")

;; Recognize jbs and jbc instructions.

(define_insn ""
  [(set (pc)
	(if_then_else
	 (ne (sign_extract:SI (match_operand:SI 0 "register_operand" "r")
			      (const_int 1)
			      (match_operand:SI 1 "int5_operand" "K"))
	     (const_int 0))
	 (label_ref (match_operand 2 "" ""))
	 (pc)))]
  ""
  "bb1 %1,%0,%l2")

(define_insn ""
  [(set (pc)
	(if_then_else
	 (eq (sign_extract:SI (match_operand:SI 0 "register_operand" "r")
			      (const_int 1)
			      (match_operand:SI 1 "int5_operand" "K"))
	     (const_int 0))
	 (label_ref (match_operand 2 "" ""))
	 (pc)))]
  ""
  "bb0 %1,%0,%l2")

(define_insn ""
  [(set (pc)
	(if_then_else
	 (ne (sign_extract:SI (match_operand:SI 0 "register_operand" "r")
			      (const_int 1)
			      (match_operand:SI 1 "int5_operand" "K"))
	     (const_int 0))
	 (pc)
	 (label_ref (match_operand 2 "" ""))))]
  ""
  "bb0 %1,%0,%l2")

(define_insn ""
  [(set (pc)
	(if_then_else
	 (eq (sign_extract:SI (match_operand:SI 0 "register_operand" "r")
			      (const_int 1)
			      (match_operand:SI 1 "int5_operand" "K"))
	     (const_int 0))
	 (pc)
	 (label_ref (match_operand 2 "" ""))))]
  ""
  "bb1 %1,%0,%l2")

(define_insn ""
  [(set (pc)
	(if_then_else
	 (ne (sign_extract:SI (match_operand:SI 0 "general_operand" "r")
			      (const_int 1)
			      (match_operand:SI 1 "int5_operand" "K"))
	     (const_int 0))
	 (label_ref (match_operand 2 "" ""))
	 (pc)))]
  ""
  "bb1 %1,%0,%l2")

(define_insn ""
  [(set (pc)
	(if_then_else
	 (eq (sign_extract:SI (match_operand:SI 0 "general_operand" "r")
			      (const_int 1)
			      (match_operand:SI 1 "int5_operand" "K"))
	     (const_int 0))
	 (label_ref (match_operand 2 "" ""))
	 (pc)))]
  ""
  "bb0 %1,%0,%l2")

(define_insn ""
  [(set (pc)
	(if_then_else
	 (eq (and:SI (match_operand:SI 0 "register_operand" "r")
		     (match_operand:SI 1 "int5_operand" "K"))
	     (const_int 0))
	 (pc)
	 (label_ref (match_operand 2 "" ""))))]
  "exact_log2 (INTVAL (operands[1])) >= 0"
  "*
{
  operands[1]
    = gen_rtx (CONST_INT, VOIDmode, exact_log2 (INTVAL (operands[1])));
  return \"bb1 %1,%0,%l2\";
}")

(define_insn ""
  [(set (pc)
	(if_then_else
	 (eq (and:SI (match_operand:SI 0 "register_operand" "r")
		     (match_operand:SI 1 "int5_operand" "K"))
	     (const_int 0))
	 (label_ref (match_operand 2 "" ""))
	 (pc)))]
  "exact_log2 (INTVAL (operands[1])) >= 0"
  "*
{
  operands[1]
    = gen_rtx (CONST_INT, VOIDmode, exact_log2 (INTVAL (operands[1])));
  return \"bb0 %1,%0,%l2\";
}")

(define_insn ""
  [(set (pc)
	(if_then_else
	 (ne (and:SI (match_operand:SI 0 "register_operand" "r")
		     (match_operand:SI 1 "int5_operand" "K"))
	     (const_int 0))
	 (pc)
	 (label_ref (match_operand 2 "" ""))))]
  "exact_log2 (INTVAL (operands[1])) >= 0"
  "*
{
  operands[1]
    = gen_rtx (CONST_INT, VOIDmode, exact_log2 (INTVAL (operands[1])));
  return \"bb0 %1,%0,%l2\";
}")

(define_insn ""
  [(set (pc)
	(if_then_else
	 (ne (and:SI (match_operand:SI 0 "register_operand" "r")
		     (match_operand:SI 1 "int5_operand" "K"))
	     (const_int 0))
	 (label_ref (match_operand 2 "" ""))
	 (pc)))]
  "exact_log2 (INTVAL (operands[1])) >= 0"
  "*
{
  operands[1]
    = gen_rtx (CONST_INT, VOIDmode, exact_log2 (INTVAL (operands[1])));
  return \"bb1 %1,%0,%l2\";
}")

(define_insn ""
  [(set (pc)
	(if_then_else
	 (ne (sign_extract:SI (match_operand:SI 0 "general_operand" "r")
			      (const_int 1)
			      (match_operand:SI 1 "int5_operand" "K"))
	     (const_int 0))
	 (pc)
	 (label_ref (match_operand 2 "" ""))))]
  ""
  "bb0 %1,%0,%l2")

(define_insn ""
  [(set (pc)
	(if_then_else
	 (eq (sign_extract:SI (match_operand:SI 0 "general_operand" "r")
			      (const_int 1)
			      (match_operand:SI 1 "int5_operand" "K"))
	     (const_int 0))
	 (pc)
	 (label_ref (match_operand 2 "" ""))))]
  ""
  "bb1 %1,%0,%l2")

(define_insn ""
  [(set (pc)
	(if_then_else
	 (ne (and:SI (match_operand:SI 0 "register_operand" "r")
		     (const_int 1))
	     (const_int 0))
	 (label_ref (match_operand 1 "" ""))
	 (pc)))]
  ""
  "bb1 0,%0,%l1")

(define_insn ""
  [(set (pc)
	(if_then_else
	 (eq (and:SI (match_operand:SI 0 "register_operand" "r")
		     (const_int 1))
	     (const_int 0))
	 (label_ref (match_operand 1 "" ""))
	 (pc)))]
  ""
  "bb0 0,%0,%l1")

(define_insn ""
  [(set (pc)
	(if_then_else
	 (ne (and:SI (match_operand:SI 0 "register_operand" "r")
		     (const_int 1))
	     (const_int 0))
	 (pc)
	 (label_ref (match_operand 1 "" ""))))]
  ""
  "bb0 0,%0,%l1")

(define_insn ""
  [(set (pc)
	(if_then_else
	 (eq (and:SI (match_operand:SI 0 "register_operand" "r")
		     (const_int 1))
	     (const_int 0))
	 (pc)
	 (label_ref (match_operand 1 "" ""))))]
  ""
  "bb1 0,%0,%l1")

;; These four entries allow a jlbc or jlbs,to be made
;; by combination with a bic.
(define_insn ""
  [(set (pc)
	(if_then_else
	 (ne (and:SI (match_operand:SI 0 "register_operand" "r")
		     (not:SI (const_int -2)))
	     (const_int 0))
	 (label_ref (match_operand 1 "" ""))
	 (pc)))]
  ""
  "bb1 0,%0,%l1")

(define_insn ""
  [(set (pc)
	(if_then_else
	 (eq (and:SI (match_operand:SI 0 "register_operand" "r")
		     (not:SI (const_int -2)))
	     (const_int 0))
	 (label_ref (match_operand 1 "" ""))
	 (pc)))]
  ""
  "bb0 0,%0,%l1")

(define_insn ""
  [(set (pc)
	(if_then_else
	 (ne (and:SI (match_operand:SI 0 "register_operand" "r")
		     (not:SI (const_int -2)))
	     (const_int 0))
	 (pc)
	 (label_ref (match_operand 1 "" ""))))]
  ""
  "bb0 0,%0,%l1")

(define_insn ""
  [(set (pc)
	(if_then_else
	 (eq (and:SI (match_operand:SI 0 "register_operand" "r")
		     (not:SI (const_int -2)))
	     (const_int 0))
	 (pc)
	 (label_ref (match_operand 1 "" ""))))]
  ""
  "bb1 0,%0,%l1")
;;- Local variables:
;;- mode:emacs-lisp
;;- comment-start: ";;- "
;;- eval: (set-syntax-table (copy-sequence (syntax-table)))
;;- eval: (modify-syntax-entry ?[ "(]")
;;- eval: (modify-syntax-entry ?] ")[")
;;- eval: (modify-syntax-entry ?{ "(}")
;;- eval: (modify-syntax-entry ?} "){")
;;- End:
