;; CYGNUS LOCAL -- meissner/d10v abi change
;; Machine description for Mitsubishi D10V for GNU C compiler
;; Copyright (C) 1996, 1997, 1998 Free Software Foundation, Inc.
;; Contributed by Cygnus Support.

;; This file is part of GNU CC.

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

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

;; You should have received a copy of the GNU General Public License
;; along with GNU CC; see the file COPYING.  If not, write to
;; the Free Software Foundation, 59 Temple Place - Suite 330,
;; Boston, MA 02111-1307, USA.

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

;; Machine dependent register classes used:
;;	'C'	CARRY_REGS
;;	'a'	ACCUM_REGS
;;	'b'	R2_REGS
;;	'c'	CR_REGS
;;	'd'	GENERAL_REGS
;;	'e'	EVEN_REGS
;;	'f'	F0_REGS
;;	'h'	R3_REGS
;;	'j'	R4_REGS
;;	'l'	R13_REGS
;;	'q'	R5_REGS
;;	'x'	CC_REGS
;;	'y'	F1_REGS
;;	'z'	REPEAT_REGS


;; Function unit attributes
;; Note, we lie a little bit here to make it simpler to optimize.  We pretend there
;; is a separate long functional unit for long instructions that uses both the IU & MU.
(define_attr "type" "iu,mu,either,long,unknown"
  (const_string "unknown"))

;; Length in word units
(define_attr "length" ""
  (if_then_else (eq_attr "type" "long,unknown")
		(const_int 2)
		(const_int 1)))

;; (define_function_unit NAME MULTIPLICITY SIMULTANEITY TEST READY-DELAY ISSUE-DELAY [CONFLICT-LIST])
(define_function_unit "iu" 1 1
  (and (eq_attr "type" "iu,either")
       (eq_attr "length" "1"))
  2 2
  [(eq_attr "type" "long,unknown")])

(define_function_unit "mu" 1 1
  (and (eq_attr "type" "mu,either")
       (eq_attr "length" "1"))
  2 2
  [(eq_attr "type" "long,unknown")])

(define_function_unit "long" 1 1
  (eq_attr "type" "long,unknown")
  2 2
  [(and (eq_attr "type" "iu,mu,either")
	(eq_attr "length" "1"))])

(define_function_unit "long" 1 1
  (not (eq_attr "length" "1"))
  2 2
  [(and (eq_attr "type" "iu,mu,either")
	(eq_attr "length" "1"))])



;;  ....................
;;
;;	Move operations
;;
;;  ....................

(define_expand "movqi"
  [(set (match_operand:QI 0 "general_operand" "")
	(match_operand:QI 1 "general_operand" ""))]
  ""
  "
{
  if (GET_CODE (operands[0]) != REG
      && (GET_CODE (operands[1]) != CONST_INT || INTVAL (operands[1]) != 0))
    operands[1] = force_reg (QImode, operands[1]);
}")

(define_insn "*movqi_internal"
  [(set (match_operand:QI 0 "general_operand" "=d,d,d,Q,m,d,d,Q,m")
	(match_operand:QI 1 "general_operand"  "d,Q,m,d,d,L,i,O,O"))]
  "register_operand (operands[0], QImode) || register_operand (operands[1], QImode)
   || (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) == 0)"
  "@
  mv %0,%1
  ldub %0,%M1
  ldub %0,%M1
  stb %1,%M0
  stb %1,%M0
  ldi %0,%1
  ldi %0,%1
  stb %.,%M0
  stb %.,%M0"
  [(set_attr "type" "either,mu,long,mu,long,either,mu,mu,mu")
   (set_attr "length" "1,1,2,1,2,1,2,1,2")])

(define_expand "movhi"
  [(set (match_operand:HI 0 "general_operand" "")
	(match_operand:HI 1 "general_operand" ""))]
  ""
  "
{
  if (GET_CODE (operands[0]) != REG
      && (GET_CODE (operands[1]) != CONST_INT || INTVAL (operands[1]) != 0)
      && ! reload_in_progress)
    operands[1] = force_reg (HImode, operands[1]);
}")

(define_insn "*movhi_internal"
  [(set (match_operand:HI 0 "general_operand" "=d,d,d,Q,m,c,d,d,d,Q,m")
	(match_operand:HI 1 "general_operand"  "d,Q,m,d,d,d,c,L,i,O,O"))]
  "register_operand (operands[0], HImode) || register_operand (operands[1], HImode)
   || (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) == 0)"
  "* return emit_move_word (operands[0], operands[1], insn);"
  [(set_attr "type" "either,mu,long,mu,long,mu,mu,either,mu,mu,mu")
   (set_attr "length" "1,1,2,1,2,1,1,1,2,1,2")])

;; Split constants that we can into a small ldi and a shift.  This may seem
;; counter intuitive to replace one instruction by two, but the reasoning is
;; that it helps avoid nops caused by the long form of ldi and is the same
;; space if no nops where needed, and also allows such constants to be set up
;; with conditional execution.

(define_split
  [(set (match_operand:HI 0 "gpr_operand" "")
	(match_operand:HI 1 "ldi_shift_operand" ""))]
  ""
  [(set (match_dup 0) (match_dup 2))
   (set (match_dup 0) (ashift:HI (match_dup 0) (match_dup 3)))]
  "
{
  int shift = ldi_shift_operand (operands[1], HImode);
  operands[2] = GEN_INT (INTVAL (operands[1]) >> shift);
  operands[3] = GEN_INT (shift);
}")

(define_expand "movsi"
  [(set (match_operand:SI 0 "general_operand" "")
	(match_operand:SI 1 "general_operand" ""))]
  ""
  "
{
  if (GET_CODE (operands[0]) != REG)
    operands[1] = force_reg (SImode, operands[1]);
  /* reload might ask us to use something like (subreg:SI (reg/v:DI 0 r0) 1) .
     Example: unsorted/dilayout.c -O1 */
  if (reload_in_progress)
    {
      int reg0 = true_regnum (operands[0]);
      int reg1 = true_regnum (operands[1]);

      if ((reg0 >= 0 && reg0 < FIRST_PSEUDO_REGISTER && (reg0 & 1))
	  || (reg1 >= 0 && reg1 < FIRST_PSEUDO_REGISTER && (reg1 & 1)))
	{
	  rtx high, low;
	  int word0 = 0, word1 = 0;

	  if (GET_CODE (operands[0]) == SUBREG)
	    {
	      word0 = SUBREG_WORD (operands[0]);
	      operands[0] = SUBREG_REG (operands[0]);
	    }
	  if (GET_CODE (operands[1]) == SUBREG)
	    {
	      word1 = SUBREG_WORD (operands[1]);
	      operands[1] = SUBREG_REG (operands[1]);
	    }
	  high = gen_movhi (gen_rtx (SUBREG, HImode, operands[0], word0),
			    gen_rtx (SUBREG, HImode, operands[1], word1));
	  operands[0] = copy_rtx (operands[0]);
	  operands[1] = copy_rtx (operands[1]);
	  low = gen_movhi (gen_rtx (SUBREG, HImode, operands[0], word0 + 1),
			   gen_rtx (SUBREG, HImode, operands[1], word1 + 1));
	  /* Check for overlap.  We know this is big endian.  */
	  if (reg0 == reg1 + 1)
	    {
	      emit_insn (low);
	      emit_insn (high);
	    }
	  else
	    {
	      emit_insn (high);
	      emit_insn (low);
	    }
	  DONE;
	}
    }
}")

(define_insn "*movsi_internal"
  [(set (match_operand:SI 0 "general_operand" "=e,e,e,Q,m,a,a,e,e,a")
	(match_operand:SI 1 "general_operand" "e,Q,m,e,e,e,a,a,i,O"))]
  "register_operand (operands[0], SImode) || register_operand (operands[1], SImode)"
  "* return emit_move_2words (operands[0], operands[1], insn);"
  [(set_attr "type" "either,mu,long,mu,long,mu,iu,mu,long,iu")
   (set_attr "length" "1,1,2,1,2,1,1,1,4,1")])

(define_split
  [(set (match_operand:SI 0 "register_operand" "")
	(match_operand:SI 1 "const_int_operand" ""))]
  "reload_completed"
  [(set (match_dup 2) (match_dup 4))
   (set (match_dup 3) (match_dup 5))]
  "
{
  operands[2] = d10v_subword (operands[0], 0, HImode, SImode);
  operands[3] = d10v_subword (operands[0], 1, HImode, SImode);
  operands[4] = GEN_INT (SIGN_EXTEND_SHORT (INTVAL (operands[1]) >> 16));
  operands[5] = GEN_INT (SIGN_EXTEND_SHORT (INTVAL (operands[1])));
}")

(define_insn "reload_insi"
  [(set (match_operand:SI 0 "register_operand" "=a,a")
	(match_operand:SI 1 "memory_operand" "Q,m"))
   (clobber (match_operand:SI 2 "gpr_operand" "=e,e"))]
  "TARGET_ACCUM"
  "#"
  [(set_attr "type" "long,long")
   (set_attr "length" "2,3")])

(define_insn "reload_outsi"
  [(set (match_operand:SI 0 "memory_operand" "=Q,m")
	(match_operand:SI 1 "accum_operand" "a,a"))
   (clobber (match_operand:SI 2 "gpr_operand" "=&e,e"))]
  "TARGET_ACCUM"
  "#"
  [(set_attr "type" "long,long")
   (set_attr "length" "2,3")])

(define_split
  [(set (match_operand:SI 0 "general_operand" "")
	(match_operand:SI 1 "general_operand" ""))
   (clobber (match_operand:SI 2 "gpr_operand" ""))]
  "TARGET_ACCUM && reload_completed"
  [(set (match_dup 2) (match_dup 1))
   (set (match_dup 0) (match_dup 2))]
  "")

(define_expand "movsf"
  [(set (match_operand:SF 0 "general_operand" "")
	(match_operand:SF 1 "general_operand" ""))]
  ""
  "
{
  if (GET_CODE (operands[0]) != REG)
    operands[1] = force_reg (SFmode, operands[1]);
}")

(define_insn "*movsf_internal"
  [(set (match_operand:SF 0 "general_operand" "=e,e,e,Q,m,e")
	(match_operand:SF 1 "general_operand" "e,Q,m,e,e,F"))]
  "register_operand (operands[0], SFmode) || register_operand (operands[1], SFmode)"
  "* return emit_move_2words (operands[0], operands[1], insn);"
  [(set_attr "type" "either,mu,long,mu,long,long")
   (set_attr "length" "1,1,2,1,2,4")])

(define_split
  [(set (match_operand:SF 0 "gpr_operand" "")
	(match_operand:SF 1 "const_double_operand" ""))]
  "reload_completed"
  [(set (match_dup 2) (match_dup 4))
   (set (match_dup 3) (match_dup 5))]
  "
{
  REAL_VALUE_TYPE rv;
  HOST_WIDE_INT value;

  REAL_VALUE_FROM_CONST_DOUBLE (rv, operands[1]);
  REAL_VALUE_TO_TARGET_SINGLE (rv, value);

  operands[2] = d10v_subword (operands[0], 0, HImode, SFmode);
  operands[3] = d10v_subword (operands[0], 1, HImode, SFmode);
  operands[4] = GEN_INT (SIGN_EXTEND_SHORT (value >> 16));
  operands[5] = GEN_INT (SIGN_EXTEND_SHORT (value));
}")

(define_expand "movdi"
  [(parallel [(set (match_operand:DI 0 "general_operand" "")
		   (match_operand:DI 1 "general_operand" ""))
	      (clobber (match_scratch:SI 2 ""))
	      (clobber (match_scratch:HI 3 ""))])]
  ""
  "")

(define_insn "*movdi_internal"
  [(set (match_operand:DI 0 "general_operand" "=e,e,o,e,o,o,o,??o,??o")
	(match_operand:DI 1 "general_operand" "e,o,e,iF,o,OG,iF,o,o"))
   (clobber (match_scratch:SI 2 "=X,X,X,X,&e,X,&e,X,e"))
   (clobber (match_scratch:HI 3 "=X,X,X,X,X,X,X,&d,X"))]
  ""
  "* return emit_move_4words (operands[0], operands[1], operands[2], operands[3], insn);"
  [(set_attr "type" "long,long,long,long,long,long,long,long,long")
   (set_attr "length" "4,4,4,4,8,8,16,32,32")])

(define_expand "movdf"
  [(parallel [(set (match_operand:DF 0 "general_operand" "")
		   (match_operand:DF 1 "general_operand" ""))
	      (clobber (match_scratch:SI 2 ""))
	      (clobber (match_scratch:HI 3 ""))])]
  ""
  "")

(define_insn "*movdf_internal"
  [(set (match_operand:DF 0 "general_operand" "=e,e,o,e,o,o,o,??o,??o")
	(match_operand:DF 1 "general_operand" "e,o,e,iF,o,OG,F,o,o"))
   (clobber (match_scratch:SI 2 "=X,X,X,X,&e,X,&e,X,e"))
   (clobber (match_scratch:HI 3 "=X,X,X,X,X,X,X,&d,X"))]
  ""
  "* return emit_move_4words (operands[0], operands[1], operands[2], operands[3], insn);"
  [(set_attr "type" "long,long,long,long,long,long,long,long,long")
   (set_attr "length" "4,4,4,4,8,8,16,32,32")])

(define_insn "movcc"
  [(set (match_operand:CC 0 "general_operand" "=x")
	(match_operand:CC 1 "general_operand" "x"))]
  ""
  "cpfg %0,%1"
  [(set_attr "type" "mu")
   (set_attr "length" "1")])


;;  ....................
;;
;;	Unconditional branch, return, and case table
;;
;;  ....................

(define_insn "jump"
  [(set (pc)
	(label_ref (match_operand 0 "" "")))]
  ""
  "bra %l0"
  [(set_attr "type" "long")
   (set_attr "length" "2")])

;; Note, do not list a dependency on r13, since jump.c currently can't handle a parallel
;; operation.
(define_expand "return"
  [(return)]
  "direct_return ()"
  "")

(define_insn "*return_1"
  [(return)]
  "direct_return () && (d10v_stack_info ())->total_size == 0"
  "*
{
  operands[0] = gen_rtx (REG, Pmode, RETURN_ADDRESS_REGNUM);
  return \"jmp %0\";
}"
  [(set_attr "type" "mu")
   (set_attr "length" "1")])

(define_insn "*return_2"
  [(return)]
  "direct_return () && (d10v_stack_info ())->total_size != 0"
  "*
{
  d10v_stack_t *info = d10v_stack_info ();

  operands[0] = gen_rtx (REG, Pmode, STACK_POINTER_REGNUM);
  operands[1] = gen_rtx (REG, Pmode, RETURN_ADDRESS_REGNUM);
  if (info->total_size == UNITS_PER_WORD && info->save_p[RETURN_ADDRESS_REGNUM])
    return \"ld %1,@%0+\;jmp %1\";

  else if (info->total_size == info->vars_size
	   && IN_RANGE_P (info->total_size, 1, 16))
    {
      operands[2] = GEN_INT (info->total_size);
      return \"addi %0,%2\;jmp %1\";
    }

  else
    fatal_insn (\"return_2 unexpected return stack\", insn);

  return \"\";
}"
  [(set_attr "type" "long")
   (set_attr "length" "2")])

(define_insn "indirect_jump"
  [(set (pc) (match_operand:HI 0 "gpr_operand" "d"))]
  ""
  "jmp %0"
  [(set_attr "type" "mu")
   (set_attr "length" "1")])

;; No operation
(define_insn "nop"
  [(const_int 0)]
  ""
  "nop"
  [(set_attr "type" "either")
   (set_attr "length" "1")])

;; Table jump for switch statements:
(define_insn "tablejump"
  [(set (pc) (match_operand:HI 0 "gpr_operand" "d"))
   (use (label_ref (match_operand 1 "" "")))]
  ""
  "jmp %0"
  [(set_attr "type" "mu")
   (set_attr "length" "1")])


;;  ....................
;;
;;	Calls
;;
;;  ....................

(define_expand "call"
  [(parallel [(call (match_operand 0 "memory_operand" "")
		    (match_operand 1 "" ""))
	      (clobber (match_scratch:HI 2 "=l"))])]
  ""
  "
{
  rtx addr;

  addr = XEXP (operands[0], 0);
  if (GET_CODE (addr) != REG && !CONSTANT_ADDRESS_P (addr))
    {
      rtx reg = gen_reg_rtx (Pmode);
      emit_move_insn (reg, addr);
      operands[0] = gen_rtx (MEM, FUNCTION_MODE, reg);
    }
}")

(define_insn "*call_internal1"
  [(call (match_operand 0 "memory_operand" "m")
	 (match_operand 1 "" "i"))
   (clobber (match_scratch:HI 2 "=l"))]			;; return address, r13
  "GET_CODE (XEXP (operands[0], 0)) == REG"
  "jl %0"
  [(set_attr "type" "mu")
   (set_attr "length" "1")])

(define_insn "*call_internal2"
  [(call (match_operand 0 "memory_operand" "m")
	 (match_operand 1 "" "i"))
   (clobber (match_scratch:HI 2 "=l"))]			;; return address, r13
  "CONSTANT_ADDRESS_P (XEXP (operands[0], 0))"
  "bl %0"
  [(set_attr "type" "long")
   (set_attr "length" "2")])

(define_expand "call_value"
  [(parallel [(set (match_operand 0 "gpr_operand" "")
		   (call (match_operand 1 "memory_operand" "m")
			 (match_operand 2 "" "i")))
	      (clobber (match_scratch:HI 3 "=l"))])]
  ""
  "
{
  rtx addr;

  addr = XEXP (operands[1], 0);
  if (GET_CODE (addr) != REG && !CONSTANT_ADDRESS_P (addr))
    {
      rtx reg = gen_reg_rtx (Pmode);
      emit_move_insn (reg, addr);
      operands[1] = gen_rtx (MEM, FUNCTION_MODE, reg);
    }
}")

(define_insn "*call_value_internal1"
  [(set (match_operand 0 "gpr_operand" "=e")
	(call (match_operand 1 "memory_operand" "m")
	      (match_operand 2 "" "i")))
   (clobber (match_scratch:HI 3 "=l"))]			;; return address, r13
  "GET_CODE (XEXP (operands[1], 0)) == REG"
  "jl %1"
  [(set_attr "type" "mu")
   (set_attr "length" "1")])

(define_insn "*call_value_internal2"
  [(set (match_operand 0 "gpr_operand" "=e")
	(call (match_operand 1 "memory_operand" "m")
	      (match_operand 2 "" "i")))
   (clobber (match_scratch:HI 3 "=l"))]			;; return address, r13
  "CONSTANT_ADDRESS_P (XEXP (operands[1], 0))"
  "bl %1"
  [(set_attr "type" "long")
   (set_attr "length" "2")])


;;
;;  ....................
;;
;;	Comparisons
;;
;;  ....................

;; Flow here is rather complex:
;;
;;  1)	The cmp{hi,si,di,sf,df} routine is called.  It deposits the
;;	arguments into global variables, and the type into
;;	branch_type.  No RTL is generated.
;;
;;  2)	The appropriate branch define_expand is called, which then
;;	creates the appropriate RTL for the comparison and branch.

(define_expand "cmphi"
  [(set (cc0)
	(compare:CC (match_operand:HI 0 "gpr_operand" "")
		    (match_operand:HI 1 "arith16_operand" "")))]
  ""
  "
{
  if (operands[0])		/* avoid unused code message */
    {
      compare_op0 = operands[0];
      compare_op1 = operands[1];
      DONE;
    }
}")

(define_expand "tsthi"
  [(set (cc0)
	(match_operand:HI 0 "gpr_operand" ""))]
  ""
  "
{
  if (operands[0])		/* avoid unused code message */
    {
      compare_op0 = operands[0];
      compare_op1 = const0_rtx;
      DONE;
    }
}")

(define_expand "cmpsi"
  [(set (cc0)
	(compare:CC (match_operand:SI 0 "gpr_operand" "")
		    (match_operand:SI 1 "reg_or_0_operand" "")))]
  ""
  "
{
  if (operands[0])		/* avoid unused code message */
    {
      compare_op0 = operands[0];
      compare_op1 = operands[1];
      DONE;
    }
}")

(define_expand "tstsi"
  [(set (cc0)
	(match_operand:SI 0 "gpr_operand" ""))]
  ""
  "
{
  if (operands[0])		/* avoid unused code message */
    {
      compare_op0 = operands[0];
      compare_op1 = const0_rtx;
      DONE;
    }
}")

(define_expand "cmpdi"
  [(set (cc0)
	(compare:CC (match_operand:DI 0 "general_operand" "")
		    (match_operand:DI 1 "reg_or_0_operand" "")))]
  ""
  "
{
  if (operands[0])		/* avoid unused code message */
    {
      compare_op0 = operands[0];
      compare_op1 = operands[1];
      DONE;
    }
}")

(define_expand "tstdi"
  [(set (cc0) (match_operand:DI 0 "general_operand" ""))]
  ""
  "
{
  if (operands[0])		/* avoid unused code message */
    {
      compare_op0 = operands[0];
      compare_op1 = const0_rtx;
      DONE;
    }
}")

(define_insn "*tst_ne_true"
  [(set (match_operand:CC 0 "f0_operand" "")
	(ne:CC (and:HI (match_operand:HI 1 "gpr_operand" "d,d")
		       (match_operand:HI 2 "const_int_operand" "P,n"))
		   (const_int 0)))]
  ""
  "*
{
  int log = exact_log2 (INTVAL (operands[2]));

  if (IN_RANGE_P (log, 0, 15))
    {
      operands[3] = GEN_INT (15 - log);
      return \"btsti %1,%3\";
    }

  return \"tst0i %1,%2\";
}"
  [(set_attr "type" "iu,long")
   (set_attr "length" "1,2")])

; the following is wrong
;(define_insn "*tst_eq_true"
;  [(set (match_operand:CC 0 "f0_operand" "")
;	(eq:CC (and:HI (match_operand:HI 1 "gpr_operand" "d")
;		       (match_operand:HI 2 "const_int_operand" "n"))
;	       (const_int 0)))]
;  ""
;  "tst0i %1,%2"
;  [(set_attr "type" "long")
;   (set_attr "length" "2")])
;
;(define_insn "*tst_ne_false"
;  [(set (match_operand:CC_REV 0 "f0_operand" "")
;	(ne:CC_REV (and:HI (match_operand:HI 1 "gpr_operand" "d")
;			   (match_operand:HI 2 "const_int_operand" "n"))
;		   (const_int 0)))]
;  ""
;  "tst0i %1,%2"
;  [(set_attr "type" "long")
;   (set_attr "length" "2")])

(define_insn "*tst_eq_false"
  [(set (match_operand:CC_REV 0 "f0_operand" "")
	(eq:CC_REV (and:HI (match_operand:HI 1 "gpr_operand" "d,d")
			   (match_operand:HI 2 "const_int_operand" "P,n"))
		   (const_int 0)))]
  ""
  "*
{
  int log = exact_log2 (INTVAL (operands[2]));

  if (IN_RANGE_P (log, 0, 15))
    {
      operands[3] = GEN_INT (15 - log);
      return \"btsti %1,%3\";
    }

  return \"tst0i %1,%2\";
}"
  [(set_attr "type" "iu,long")
   (set_attr "length" "1,2")])

(define_insn "*eq_hi_true"
  [(set (match_operand:CC 0 "f0_operand" "")
	(eq:CC (match_operand:HI 1 "gpr_operand" "d,d")
	       (match_operand:HI 2 "arith16_operand" "dL,i")))]
  "emit_comparison (EQ, operands[1], operands[2], NULL_RTX, NULL_RTX, HImode, FALSE)"
  "*
{
  emit_comparison (EQ, operands[1], operands[2], NULL_RTX, insn, HImode, TRUE);
  return \"\";
}"
  [(set_attr "type" "either,long")
   (set_attr "length" "1,2")])

(define_insn "*lt_hi_true"
  [(set (match_operand:CC 0 "f0_operand" "")
	(lt:CC (match_operand:HI 1 "gpr_operand" "d,d")
	       (match_operand:HI 2 "arith16_operand" "dL,i")))]
  "emit_comparison (LT, operands[1], operands[2], NULL_RTX, NULL_RTX, HImode, FALSE)"
  "*
{
  emit_comparison (LT, operands[1], operands[2], NULL_RTX, insn, HImode, TRUE);
  return \"\";
}"
  [(set_attr "type" "either,long")
   (set_attr "length" "1,2")])

(define_insn "*le_hi_true"
  [(set (match_operand:CC 0 "f0_operand" "")
	(le:CC (match_operand:HI 1 "gpr_operand" "d,d")
	       (match_operand:HI 2 "const_int_operand" "O,i")))]
  "emit_comparison (LE, operands[1], operands[2], NULL_RTX, NULL_RTX, HImode, FALSE)"
  "*
{
  emit_comparison (LE, operands[1], operands[2], NULL_RTX, insn, HImode, TRUE);
  return \"\";
}"
  [(set_attr "type" "either,long")
   (set_attr "length" "1,2")])

(define_insn "*gt_hi_true"
  [(set (match_operand:CC 0 "f0_operand" "")
	(gt:CC (match_operand:HI 1 "gpr_operand" "d")
	       (match_operand:HI 2 "gpr_operand" "d")))]
  "emit_comparison (GT, operands[1], operands[2], NULL_RTX, NULL_RTX, HImode, FALSE)"
  "*
{
  emit_comparison (GT, operands[1], operands[2], NULL_RTX, insn, HImode, TRUE);
  return \"\";
}"
  [(set_attr "type" "either")
   (set_attr "length" "1")])

(define_insn "*ltu_hi_true"
  [(set (match_operand:CC 0 "f0_operand" "")
	(ltu:CC (match_operand:HI 1 "gpr_operand" "d,d")
		(match_operand:HI 2 "arith16_operand" "d,i")))]
  "emit_comparison (LTU, operands[1], operands[2], NULL_RTX, NULL_RTX, HImode, FALSE)"
  "*
{
  emit_comparison (LTU, operands[1], operands[2], NULL_RTX, insn, HImode, TRUE);
  return \"\";
}"
  [(set_attr "type" "either,long")
   (set_attr "length" "1,2")])

(define_insn "*leu_hi_true"
  [(set (match_operand:CC 0 "f0_operand" "")
	(leu:CC (match_operand:HI 1 "gpr_operand" "d")
		(match_operand:HI 2 "const_int_operand" "i")))]
  "emit_comparison (LEU, operands[1], operands[2], NULL_RTX, NULL_RTX, HImode, FALSE)"
  "*
{
  emit_comparison (LEU, operands[1], operands[2], NULL_RTX, insn, HImode, TRUE);
  return \"\";
}"
  [(set_attr "type" "long")
   (set_attr "length" "2")])

(define_insn "*gtu_hi_true"
  [(set (match_operand:CC 0 "f0_operand" "")
	(gtu:CC (match_operand:HI 1 "gpr_operand" "d")
		(match_operand:HI 2 "gpr_operand" "d")))]
  "emit_comparison (GTU, operands[1], operands[2], NULL_RTX, NULL_RTX, HImode, FALSE)"
  "*
{
  emit_comparison (GTU, operands[1], operands[2], NULL_RTX, insn, HImode, TRUE);
  return \"\";
}"
  [(set_attr "type" "either")
   (set_attr "length" "1")])

(define_insn "*ne_hi_false"
  [(set (match_operand:CC_REV 0 "f0_operand" "")
	(ne:CC_REV (match_operand:HI 1 "gpr_operand" "d,d")
		   (match_operand:HI 2 "arith16_operand" "dL,i")))]
  "!emit_comparison (NE, operands[1], operands[2], NULL_RTX, NULL_RTX, HImode, FALSE)"
  "*
{
  emit_comparison (NE, operands[1], operands[2], NULL_RTX, insn, HImode, TRUE);
  return \"\";
}"
  [(set_attr "type" "either,long")
   (set_attr "length" "1,2")])

(define_insn "*le_hi_false"
  [(set (match_operand:CC_REV 0 "f0_operand" "")
	(le:CC_REV (match_operand:HI 1 "gpr_operand" "d")
		   (match_operand:HI 2 "gpr_operand" "d")))]
  "!emit_comparison (LE, operands[1], operands[2], NULL_RTX, NULL_RTX, HImode, FALSE)"
  "*
{
  emit_comparison (LE, operands[1], operands[2], NULL_RTX, insn, HImode, TRUE);
  return \"\";
}"
  [(set_attr "type" "either")
   (set_attr "length" "1")])

(define_insn "*gt_hi_false"
  [(set (match_operand:CC_REV 0 "f0_operand" "")
	(gt:CC_REV (match_operand:HI 1 "gpr_operand" "d,d")
		   (match_operand:HI 2 "const_int_operand" "O,i")))]
  "!emit_comparison (GT, operands[1], operands[2], NULL_RTX, NULL_RTX, HImode, FALSE)"
  "*
{
  emit_comparison (GT, operands[1], operands[2], NULL_RTX, insn, HImode, TRUE);
  return \"\";
}"
  [(set_attr "type" "either,long")
   (set_attr "length" "1,2")])

(define_insn "*ge_hi_false"
  [(set (match_operand:CC_REV 0 "f0_operand" "")
	(ge:CC_REV (match_operand:HI 1 "gpr_operand" "d,d")
		   (match_operand:HI 2 "arith16_operand" "dL,i")))]
  "!emit_comparison (GE, operands[1], operands[2], NULL_RTX, NULL_RTX, HImode, FALSE)"
  "*
{
  emit_comparison (GE, operands[1], operands[2], NULL_RTX, insn, HImode, TRUE);
  return \"\";
}"
  [(set_attr "type" "either,long")
   (set_attr "length" "1,2")])

(define_insn "*leu_hi_false"
  [(set (match_operand:CC_REV 0 "f0_operand" "")
	(leu:CC_REV (match_operand:HI 1 "gpr_operand" "d")
		    (match_operand:HI 2 "gpr_operand" "d")))]
  "!emit_comparison (LEU, operands[1], operands[2], NULL_RTX, NULL_RTX, HImode, FALSE)"
  "*
{
  emit_comparison (LEU, operands[1], operands[2], NULL_RTX, insn, HImode, TRUE);
  return \"\";
}"
  [(set_attr "type" "either")
   (set_attr "length" "1")])

(define_insn "*gtu_hi_false"
  [(set (match_operand:CC_REV 0 "f0_operand" "")
	(gtu:CC_REV (match_operand:HI 1 "gpr_operand" "d")
		    (match_operand:HI 2 "const_int_operand" "i")))]
  "!emit_comparison (GTU, operands[1], operands[2], NULL_RTX, NULL_RTX, HImode, FALSE)"
  "*
{
  emit_comparison (GTU, operands[1], operands[2], NULL_RTX, insn, HImode, TRUE);
  return \"\";
}"
  [(set_attr "type" "long")
   (set_attr "length" "2")])

(define_insn "*geu_hi_false"
  [(set (match_operand:CC_REV 0 "f0_operand" "")
	(geu:CC_REV (match_operand:HI 1 "gpr_operand" "d,d")
		    (match_operand:HI 2 "arith16_operand" "dL,i")))]
  "!emit_comparison (GEU, operands[1], operands[2], NULL_RTX, NULL_RTX, HImode, FALSE)"
  "*
{
  emit_comparison (GEU, operands[1], operands[2], NULL_RTX, insn, HImode, TRUE);
  return \"\";
}"
  [(set_attr "type" "either,long")
   (set_attr "length" "1,2")])

(define_insn "*equality_si_true"
  [(set (match_operand:CC 0 "f0_operand" "")
	(match_operator:CC 1 "equality_operator"
			   [(match_operand:SI 2 "gpr_operand" "e,e,e")
			    (match_operand:SI 3 "arith_lower0_operand" "e,O,K")]))]
  "emit_comparison (GET_CODE (operands[1]), operands[2], operands[3], NULL_RTX, NULL_RTX, SImode, FALSE)"
  "*
{
  !emit_comparison (GET_CODE (operands[1]), operands[2], operands[3], NULL_RTX, insn, SImode, TRUE);
  return \"\";
}"
  [(set_attr "type" "long,long,long")
   (set_attr "length" "4,4,4")])

(define_insn "*signed_si_true"
  [(set (match_operand:CC 0 "f0_operand" "")
	(match_operator:CC 1 "signed_compare_operator"
			   [(match_operand:SI 2 "gpr_operand" "e,e")
			    (match_operand:SI 3 "reg_or_0_operand" "e,O")]))]
  "emit_comparison (GET_CODE (operands[1]), operands[2], operands[3], NULL_RTX, NULL_RTX, SImode, FALSE)"
  "*
{
  emit_comparison (GET_CODE (operands[1]), operands[2], operands[3], NULL_RTX, insn, SImode, TRUE);
  return \"\";
}"
  [(set_attr "type" "long,long")
   (set_attr "length" "4,4")])

(define_insn "*unsigned_si_true"
  [(set (match_operand:CC 0 "f0_operand" "")
	(match_operator:CC 1 "unsigned_compare_operator"
			   [(match_operand:SI 2 "gpr_operand" "e,e")
			    (match_operand:SI 3 "reg_or_0_operand" "e,O")]))]
  "emit_comparison (GET_CODE (operands[1]), operands[2], operands[3], NULL_RTX, NULL_RTX, SImode, FALSE)"
  "*
{
  emit_comparison (GET_CODE (operands[1]), operands[2], operands[3], NULL_RTX, insn, SImode, TRUE);
  return \"\";
}"
  [(set_attr "type" "long,long")
   (set_attr "length" "4,4")])

(define_insn "*equality_si_false"
  [(set (match_operand:CC_REV 0 "f0_operand" "")
	(match_operator:CC_REV 1 "equality_operator"
			       [(match_operand:SI 2 "gpr_operand" "e,e,e")
				(match_operand:SI 3 "arith_lower0_operand" "e,O,K")]))]
  "!emit_comparison (GET_CODE (operands[1]), operands[2], operands[3], NULL_RTX, NULL_RTX, SImode, FALSE)"
  "*
{
  emit_comparison (GET_CODE (operands[1]), operands[2], operands[3], NULL_RTX, insn, SImode, TRUE);
  return \"\";
}"
  [(set_attr "type" "long,long,long")
   (set_attr "length" "4,4,4")])

(define_insn "*signed_si_false"
  [(set (match_operand:CC_REV 0 "f0_operand" "")
	(match_operator:CC_REV 1 "signed_compare_operator"
			       [(match_operand:SI 2 "gpr_operand" "e,e")
				(match_operand:SI 3 "reg_or_0_operand" "e,O")]))]
  "!emit_comparison (GET_CODE (operands[1]), operands[2], operands[3], NULL_RTX, NULL_RTX, SImode, FALSE)"
  "*
{
  emit_comparison (GET_CODE (operands[1]), operands[2], operands[3], NULL_RTX, insn, SImode, TRUE);
  return \"\";
}"
  [(set_attr "type" "long,long")
   (set_attr "length" "4,4")])

(define_insn "*unsigned_si_false"
  [(set (match_operand:CC_REV 0 "f0_operand" "")
	(match_operator:CC_REV 1 "unsigned_compare_operator"
			       [(match_operand:SI 2 "gpr_operand" "e,e")
				(match_operand:SI 3 "reg_or_0_operand" "e,O")]))]
  "!emit_comparison (GET_CODE (operands[1]), operands[2], operands[3], NULL_RTX, NULL_RTX, SImode, FALSE)"
  "*
{
  emit_comparison (GET_CODE (operands[1]), operands[2], operands[3], NULL_RTX, insn, SImode, TRUE);
  return \"\";
}"
  [(set_attr "type" "long,long")
   (set_attr "length" "4,4")])



;;
;;  ....................
;;
;;	Conditional moves
;;
;;  ....................

(define_expand "movqicc"
  [(match_dup 4)
   (set (match_operand:QI 0 "cond_move_operand" "")
	(if_then_else:QI (match_operand 1 "" "")
			 (match_operand:QI 2 "cond_move_operand" "")
			 (match_operand:QI 3 "cond_move_operand" "")))]
  "TARGET_COND_MOVE"
  "
{
  rtx f0;

  if (GET_CODE (operands[0]) == MEM)
    {
      if (GET_CODE (operands[2]) != REG && !(GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 0))
	FAIL;

      if (GET_CODE (operands[3]) != REG && !(GET_CODE (operands[3]) == CONST_INT && INTVAL (operands[3]) == 0))
	FAIL;
    }

  operands[4] = expand_comparison (GET_CODE (operands[1]), compare_op0, compare_op1, &f0);
  operands[1] = gen_rtx (NE, GET_MODE (f0), f0, const0_rtx);
}")

(define_insn "*movqicc_internal"
  [(set (match_operand:QI 0 "cond_move_operand" "=d,d,?d,d,d,?d,Q")
	(if_then_else:QI (match_operator:CC 1 "f0_compare_operator"
					    [(match_operand:CC 2 "f0_operand" "")
					     (const_int 0)])
			 (match_operand:QI 3 "cond_move_operand" "0,d,d,0,LQ,LQd,Od")
			 (match_operand:QI 4 "cond_move_operand" "d,0,d,LQ,0,LQd,Od")))]
  "TARGET_COND_MOVE
   && (GET_CODE (operands[0]) != MEM
       || GET_CODE (operands[3]) == REG
       || (GET_CODE (operands[3]) == CONST_INT && INTVAL (operands[3]) == 0)
       || GET_CODE (operands[4]) == REG
       || (GET_CODE (operands[4]) == CONST_INT && INTVAL (operands[4]) == 0))"
  "* return emit_cond_move (operands, insn);"
  [(set_attr "type" "either,either,long,long,long,long,long")
   (set_attr "length" "1,1,2,2,2,4,4")])

(define_expand "movhicc"
  [(match_dup 4)
   (set (match_operand:HI 0 "cond_move_operand" "")
	(if_then_else:HI (match_operand 1 "" "")
			 (match_operand:HI 2 "cond_move_operand" "")
			 (match_operand:HI 3 "cond_move_operand" "")))]
  "TARGET_COND_MOVE"
  "
{
  rtx f0;

  if (GET_CODE (operands[0]) == MEM)
    {
      if (GET_CODE (operands[2]) != REG && !(GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 0))
	FAIL;

      if (GET_CODE (operands[3]) != REG && !(GET_CODE (operands[3]) == CONST_INT && INTVAL (operands[3]) == 0))
	FAIL;
    }

  operands[4] = expand_comparison (GET_CODE (operands[1]), compare_op0, compare_op1, &f0);
  operands[1] = gen_rtx (NE, GET_MODE (f0), f0, const0_rtx);
}")

(define_insn "*movhicc_internal"
  [(set (match_operand:HI 0 "cond_move_operand" "=d,d,?d,d,d,?d,Q")
	(if_then_else:HI (match_operator:CC 1 "f0_compare_operator"
					    [(match_operand:CC 2 "f0_operand" "")
					     (const_int 0)])
			 (match_operand:HI 3 "cond_move_operand" "0,d,d,0,LQ,LQd,Od")
			 (match_operand:HI 4 "cond_move_operand" "d,0,d,LQ,0,LQd,Od")))]
  "TARGET_COND_MOVE
   && (GET_CODE (operands[0]) != MEM
       || GET_CODE (operands[3]) == REG
       || (GET_CODE (operands[3]) == CONST_INT && INTVAL (operands[3]) == 0)
       || GET_CODE (operands[4]) == REG
       || (GET_CODE (operands[4]) == CONST_INT && INTVAL (operands[4]) == 0))"
  "* return emit_cond_move (operands, insn);"
  [(set_attr "type" "either,either,long,long,long,long,long")
   (set_attr "length" "1,1,2,2,2,4,4")])

(define_expand "movsicc"
  [(match_dup 4)
   (set (match_operand:SI 0 "cond_move_operand" "")
	(if_then_else:SI (match_operand 1 "" "")
			 (match_operand:SI 2 "cond_move_operand" "")
			 (match_operand:SI 3 "cond_move_operand" "")))]
  "TARGET_COND_MOVE"
  "
{
  rtx f0;

  if (GET_CODE (operands[0]) == MEM
      && (GET_CODE (operands[2]) != REG || GET_CODE (operands[3]) != REG))
    {
      FAIL;
    }

  operands[4] = expand_comparison (GET_CODE (operands[1]), compare_op0, compare_op1, &f0);
  operands[1] = gen_rtx (NE, GET_MODE (f0), f0, const0_rtx);
}")

(define_insn "*movsicc_internal"
  [(set (match_operand:SI 0 "cond_move_operand" "=e,e,?e,Q")
	(if_then_else:SI (match_operator:CC 1 "f0_compare_operator"
					    [(match_operand:CC 2 "f0_operand" "")
					     (const_int 0)])
			 (match_operand:SI 3 "cond_move_operand" "0,Qe,Qe,e")
			 (match_operand:SI 4 "cond_move_operand" "Qe,0,Qe,e")))]
  "TARGET_COND_MOVE
   && (GET_CODE (operands[0]) != MEM
       || GET_CODE (operands[3]) == REG
       || GET_CODE (operands[4]) == REG)"
  "* return emit_cond_move (operands, insn);"
  [(set_attr "type" "long,long,long,long")
   (set_attr "length" "2,2,4,4")])

(define_expand "movsfcc"
  [(match_dup 4)
   (set (match_operand:SF 0 "cond_move_operand" "")
	(if_then_else:SF (match_operand 1 "" "")
			 (match_operand:SF 2 "cond_move_operand" "")
			 (match_operand:SF 3 "cond_move_operand" "")))]
  "TARGET_COND_MOVE"
  "
{
  rtx f0;

  if (GET_CODE (operands[0]) == MEM
      && (GET_CODE (operands[2]) != REG || GET_CODE (operands[3]) != REG))
    {
      FAIL;
    }

  operands[4] = expand_comparison (GET_CODE (operands[1]), compare_op0, compare_op1, &f0);
  operands[1] = gen_rtx (NE, GET_MODE (f0), f0, const0_rtx);
}")

(define_insn "*movsfcc_internal"
  [(set (match_operand:SF 0 "cond_move_operand" "=e,e,?e,Q")
	(if_then_else:SF (match_operator:CC 1 "f0_compare_operator"
					    [(match_operand:CC 2 "f0_operand" "")
					     (const_int 0)])
			 (match_operand:SF 3 "cond_move_operand" "0,Qe,Qe,e")
			 (match_operand:SF 4 "cond_move_operand" "Qe,0,Qe,e")))]
  "TARGET_COND_MOVE
   && (GET_CODE (operands[0]) != MEM
       || GET_CODE (operands[3]) == REG
       || GET_CODE (operands[4]) == REG)"
  "* return emit_cond_move (operands, insn);"
  [(set_attr "type" "long,long,long,long")
   (set_attr "length" "2,2,4,4")])


;;
;;  ....................
;;
;;	Conditional execution
;;
;;  ....................

(define_insn "*cond_exec_qi_store_true"
  [(if_then_else (match_operator 2 "f0_compare_operator"
				 [(match_operand:CC 3 "f0_operand" "")
				  (const_int 0)])
		 (set (match_operand:QI 0 "short_memory_operand" "=Q,Q")
		      (match_operand:QI 1 "reg_or_0_operand" "d,O"))
		 (const_int 0))]
  ""
  "@
   stb %1,%M0 || exef0%T2
   stb %.,%M0 || exef0%T2"
  [(set_attr "type" "long")
   (set_attr "length" "2")])

(define_insn "*cond_exec_qi_store_false"
  [(if_then_else (match_operator 2 "f0_compare_operator"
				 [(match_operand:CC 3 "f0_operand" "")
				  (const_int 0)])
		 (const_int 0)
		 (set (match_operand:QI 0 "short_memory_operand" "=Q,Q")
		      (match_operand:QI 1 "reg_or_0_operand" "d,O")))]
  ""
  "@
   stb %1,%M0 || exef0%F2
   stb %.,%M0 || exef0%F2"
  [(set_attr "type" "long")
   (set_attr "length" "2")])

(define_insn "*cond_exec_qi_load_true"
  [(if_then_else (match_operator 2 "f0_compare_operator"
				 [(match_operand:CC 3 "f0_operand" "")
				  (const_int 0)])
		 (set (match_operand:QI 0 "gpr_operand" "=d,d,d")
		      (match_operand:QI 1 "cond_exec_operand" "d,L,Q"))
		 (const_int 0))]
  ""
  "@
   exef0%T2 || mv %0,%1
   exef0%T2 || ldi %0,%1
   ldub %0,%M1 || exef0%T2"
  [(set_attr "type" "long")
   (set_attr "length" "2")])

(define_insn "*cond_exec_qi_load_true"
  [(if_then_else (match_operator 2 "f0_compare_operator"
				 [(match_operand:CC 3 "f0_operand" "")
				  (const_int 0)])
		 (const_int 0)
		 (set (match_operand:QI 0 "gpr_operand" "=d,d,d")
		      (match_operand:QI 1 "cond_exec_operand" "d,L,Q")))]
  ""
  "@
   exef0%F2 || mv %0,%1
   exef0%F2 || ldi %0,%1
   ldub %0,%M1 || exef0%F2"
  [(set_attr "type" "long")
   (set_attr "length" "2")])

(define_insn "*cond_exec_hi_binary_true"
  [(if_then_else (match_operator 3 "f0_compare_operator"
				 [(match_operand:CC 4 "f0_operand" "")
				  (const_int 0)])
		 (set (match_operand:HI 0 "gpr_operand" "=d")
		      (match_operator:HI 5 "binary_parallel_operator"
					 [(match_operand:HI 1 "gpr_operand" "0")
					  (match_operand:HI 2 "arith16_operand" "di")]))
		 (const_int 0))]
  "rtx_equal_p (operands[0], operands[1])"
  "*
{
  if (GET_CODE (operands[2]) == REG || GET_CODE (operands[2]) == SUBREG)
    switch (GET_CODE (operands[5]))
      {
      case PLUS:	return \"exef0%T3 || add %0,%2\";
      case MINUS:	return \"exef0%T3 || sub %0,%2\";
      case MULT:	return \"exef0%T3 || mul %0,%2\";
      case AND:		return \"exef0%T3 || and %0,%2\";
      case IOR:		return \"exef0%T3 || or %0,%2\";
      case XOR:		return \"exef0%T3 || xor %0,%2\";
      case ASHIFT:	return \"exef0%T3 || sll %0,%2\";
      case ASHIFTRT:	return \"exef0%T3 || sra %0,%2\";
      case LSHIFTRT:	return \"exef0%T3 || srl %0,%2\";
      }

  else if (GET_CODE (operands[2]) == CONST_INT)
    {
      HOST_WIDE_INT value = INTVAL (operands[2]);
      int log;

      switch (GET_CODE (operands[5]))
	{
	case PLUS:
	  if (IN_RANGE_P (value, 1, 16))
	    return \"exef0%T3 || addi %0,%2\";

	  else if (IN_RANGE_P (value, -16, -1))
	    return \"exef0%T3 || subi %0,%n2\";

	  else if (value == 0)
	    return \"\";

	  else
	    break;

	case MINUS:
	  if (IN_RANGE_P (value, 1, 16))
	    return \"exef0%T3 || subi %0,%2\";

	  else if (IN_RANGE_P (value, -16, -1))
	    return \"exef0%T3 || addi %0,%n2\";

	  else if (value == 0)
	    return \"\";

	  else
	    break;

	case IOR:
	case XOR:
	  if (value == 0)
	    return \"\";

	  log = exact_log2 (value);
	  if (IN_RANGE_P (log, 0, 15))
	    {
	      operands[2] = GEN_INT (15 - log);
	      return ((GET_CODE (operands[5]) == IOR)
		      ? \"exef0%T3 || bseti %0,%2\"
		      : \"exef0%T3 || bnoti %0,%2\");
	    }
	  break;

	case AND:
	  if ((value & 0xffff) == 0xffff)
	    return \"\";

	  log = exact_log2 (~value);
	  if (IN_RANGE_P (log, 0, 15))
	    {
	      operands[2] = GEN_INT (15 - log);
	      return \"exef0%T3 || bclri %0,%2\";
	    }
	  break;
	}
    }

  fatal_insn (\"cond_exec_hi_binary_true\", insn);
  return \"\";
}"
  [(set_attr "type" "long")
   (set_attr "length" "2")])

(define_insn "*cond_exec_hi_binary_false"
  [(if_then_else (match_operator 3 "f0_compare_operator"
				 [(match_operand:CC 4 "f0_operand" "")
				  (const_int 0)])
		 (const_int 0)
		 (set (match_operand:HI 0 "gpr_operand" "=d")
		      (match_operator:HI 5 "binary_parallel_operator"
					 [(match_operand:HI 1 "gpr_operand" "0")
					  (match_operand:HI 2 "arith16_operand" "di")])))]
  "rtx_equal_p (operands[0], operands[1])"
  "*
{
  if (GET_CODE (operands[2]) == REG || GET_CODE (operands[2]) == SUBREG)
    switch (GET_CODE (operands[5]))
      {
      case PLUS:	return \"exef0%F3 || add %0,%2\";
      case MINUS:	return \"exef0%F3 || sub %0,%2\";
      case MULT:	return \"exef0%F3 || mul %0,%2\";
      case AND:		return \"exef0%F3 || and %0,%2\";
      case IOR:		return \"exef0%F3 || or %0,%2\";
      case XOR:		return \"exef0%F3 || xor %0,%2\";
      case ASHIFT:	return \"exef0%F3 || sll %0,%2\";
      case ASHIFTRT:	return \"exef0%F3 || sra %0,%2\";
      case LSHIFTRT:	return \"exef0%F3 || srl %0,%2\";
      }

  else if (GET_CODE (operands[2]) == CONST_INT)
    {
      HOST_WIDE_INT value = INTVAL (operands[2]);
      int log;

      switch (GET_CODE (operands[5]))
	{
	case PLUS:
	  if (IN_RANGE_P (value, 1, 16))
	    return \"exef0%F3 || addi %0,%2\";

	  else if (IN_RANGE_P (value, -16, -1))
	    return \"exef0%F3 || subi %0,%n2\";

	  else if (value == 0)
	    return \"\";

	  else
	    break;

	case MINUS:
	  if (IN_RANGE_P (value, 1, 16))
	    return \"exef0%F3 || subi %0,%2\";

	  else if (IN_RANGE_P (value, -16, -1))
	    return \"exef0%F3 || addi %0,%n2\";

	  else if (value == 0)
	    return \"\";

	  else
	    break;

	case IOR:
	case XOR:
	  if (value == 0)
	    return \"\";

	  log = exact_log2 (value);
	  if (IN_RANGE_P (log, 0, 15))
	    {
	      operands[2] = GEN_INT (15 - log);
	      return ((GET_CODE (operands[5]) == IOR)
		      ? \"exef0%F3 || bseti %0,%2\"
		      : \"exef0%F3 || bnoti %0,%2\");
	    }
	  break;

	case AND:
	  if ((value & 0xffff) == 0xffff)
	    return \"\";

	  log = exact_log2 (~value);
	  if (IN_RANGE_P (log, 0, 15))
	    {
	      operands[2] = GEN_INT (15 - log);
	      return \"exef0%F3 || bclri %0,%2\";
	    }
	  break;
	}
    }

  fatal_insn (\"cond_exec_hi_binary_false\", insn);
  return \"\";
}"
  [(set_attr "type" "long")
   (set_attr "length" "2")])

(define_insn "*cond_exec_hi_unary_true"
  [(if_then_else (match_operator 2 "f0_compare_operator"
				 [(match_operand:CC 3 "f0_operand" "")
				  (const_int 0)])
		 (set (match_operand:HI 0 "gpr_operand" "=d")
		      (match_operator:HI 4 "unary_parallel_operator"
					 [(match_operand:HI 1 "gpr_operand" "0")]))
		 (const_int 0))]
  "rtx_equal_p (operands[0], operands[1])"
  "*
{
  switch (GET_CODE (operands[4]))
    {
    case NEG: return \"exef0%T2 || neg %0\";
    case NOT: return \"exef0%T2 || not %0\";

    case SIGN_EXTEND:
      if (GET_CODE (operands[1]) == MEM)
	return \"ldb %0,%M1 || exef0%T2\";
      else if (GET_CODE (operands[1]) == REG || GET_CODE (operands[1]) == SUBREG)
	return \"exef0%T2 || mvb %0,%1\";
      break;

    case ZERO_EXTEND:
      if (GET_CODE (operands[1]) == MEM)
	return \"ldub %0,%M1 || exef0%T2\";
      else if (GET_CODE (operands[1]) == REG || GET_CODE (operands[1]) == SUBREG)
	return \"exef0%T2 || mvub %0,%1\";
      break;
    }

  fatal_insn (\"cond_exec_hi_unary_true\", insn);
  return \"\";
}"
  [(set_attr "type" "long")
   (set_attr "length" "2")])

(define_insn "*cond_exec_hi_unary_false"
  [(if_then_else (match_operator 2 "f0_compare_operator"
				 [(match_operand:CC 3 "f0_operand" "")
				  (const_int 0)])
		 (const_int 0)
		 (set (match_operand:HI 0 "gpr_operand" "=d")
		      (match_operator:HI 4 "unary_parallel_operator"
					 [(match_operand:HI 1 "gpr_operand" "0")])))]
  "rtx_equal_p (operands[0], operands[1])"
  "*
{
  switch (GET_CODE (operands[4]))
    {
    case NEG: return \"exef0%F2 || neg %0\";
    case NOT: return \"exef0%F2 || not %0\";

    case SIGN_EXTEND:
      if (GET_CODE (operands[1]) == REG || GET_CODE (operands[1]) == SUBREG)
	return \"exef0%F2 || mvb %0,%1\";
      break;

    case ZERO_EXTEND:
      if (GET_CODE (operands[1]) == REG || GET_CODE (operands[1]) == SUBREG)
	return \"exef0%F2 || mvub %0,%1\";
      break;
    }

  fatal_insn (\"cond_exec_hi_unary_false\", insn);
  return \"\";
}"
  [(set_attr "type" "long")
   (set_attr "length" "2")])

(define_insn "*cond_exec_hi_abs_true"
  [(if_then_else (match_operator 3 "f0_compare_operator"
				 [(match_operand:CC 4 "f0_operand" "")
				  (const_int 0)])
		 (parallel [(set (match_operand:HI 0 "gpr_operand" "=d")
				 (abs:HI (match_operand:HI 1 "gpr_operand" "0")))
			    (clobber (match_operand:CC 2 "f0_operand" ""))])
		 (const_int 0))]
  "rtx_equal_p (operands[0], operands[1])"
  "exef0%T3 || abs %0"
  [(set_attr "type" "long")
   (set_attr "length" "2")])

(define_insn "*cond_exec_hi_abs_false"
  [(if_then_else (match_operator 3 "f0_compare_operator"
				 [(match_operand:CC 4 "f0_operand" "")
				  (const_int 0)])
		 (const_int 0)
		 (parallel [(set (match_operand:HI 0 "gpr_operand" "=d")
				 (abs:HI (match_operand:HI 1 "gpr_operand" "0")))
			    (clobber (match_operand:CC 2 "f0_operand" ""))]))]
  "rtx_equal_p (operands[0], operands[1])"
  "exef0%F3 || abs %0"
  [(set_attr "type" "long")
   (set_attr "length" "2")])

(define_insn "*cond_exec_hi_minmax_true"
  [(if_then_else (match_operator 5 "f0_compare_operator"
				 [(match_operand:CC 6 "f0_operand" "")
				  (const_int 0)])
		 (parallel [(set (match_operand:HI 0 "gpr_operand" "=d")
				 (match_operator:HI 3 "minmax_parallel_operator"
						    [(match_operand:HI 1 "gpr_operand" "%0")
						     (match_operand:HI 2 "gpr_operand" "d")]))
			    (clobber (match_operand:CC 4 "f0_operand" ""))])
		 (const_int 0))]
  "rtx_equal_p (operands[0], operands[1])"
  "*
{
  if (GET_CODE (operands[3]) == SMIN)
    return \"exef0%T5 || min %0,%2\";
  else
    return \"exef0%T5 || max %0,%2\";
}"
  [(set_attr "type" "long")
   (set_attr "length" "2")])

(define_insn "*cond_exec_hi_minmax_false"
  [(if_then_else (match_operator 5 "f0_compare_operator"
				 [(match_operand:CC 6 "f0_operand" "")
				  (const_int 0)])
		 (const_int 0)
		 (parallel [(set (match_operand:HI 0 "gpr_operand" "=d")
				 (match_operator:HI 3 "minmax_parallel_operator"
						    [(match_operand:HI 1 "gpr_operand" "%0")
						     (match_operand:HI 2 "gpr_operand" "d")]))
			    (clobber (match_operand:CC 4 "f0_operand" ""))]))]
  "rtx_equal_p (operands[0], operands[1])"
  "*
{
  if (GET_CODE (operands[3]) == SMIN)
    return \"exef0%F5 || min %0,%2\";
  else
    return \"exef0%F5 || max %0,%2\";
}"
  [(set_attr "type" "long")
   (set_attr "length" "2")])

(define_insn "*cond_exec_hi_extend_true"
  [(if_then_else (match_operator 2 "f0_compare_operator"
				 [(match_operand:CC 3 "f0_operand" "")
				  (const_int 0)])
		 (set (match_operand:HI 0 "gpr_operand" "=d")
		      (match_operator:HI 4 "extend_parallel_operator"
					 [(match_operand:QI 1 "short_memory_operand" "Q")]))
		 (const_int 0))]
  ""
  "ld%u4b %0,%M1 || exef0%T2"
  [(set_attr "type" "long")
   (set_attr "length" "2")])

(define_insn "*cond_exec_hi_extend_false"
  [(if_then_else (match_operator 2 "f0_compare_operator"
				 [(match_operand:CC 3 "f0_operand" "")
				  (const_int 0)])
		 (const_int 0)
		 (set (match_operand:HI 0 "gpr_operand" "=d")
		      (match_operator:HI 4 "extend_parallel_operator"
					 [(match_operand:QI 1 "short_memory_operand" "Q")])))]
  ""
  "ld%u4b %0,%M1 || exef0%F2"
  [(set_attr "type" "long")
   (set_attr "length" "2")])

(define_insn "*cond_exec_hi_store_true"
  [(if_then_else (match_operator 2 "f0_compare_operator"
				 [(match_operand:CC 3 "f0_operand" "")
				  (const_int 0)])
		 (set (match_operand:HI 0 "short_memory_operand" "=Q,Q")
		      (match_operand:HI 1 "reg_or_0_operand" "d,O"))
		 (const_int 0))]
  ""
  "@
   st %1,%M0 || exef0%T2
   st %.,%M0 || exef0%T2"
  [(set_attr "type" "long")
   (set_attr "length" "2")])

(define_insn "*cond_exec_hi_store_false"
  [(if_then_else (match_operator 2 "f0_compare_operator"
				 [(match_operand:CC 3 "f0_operand" "")
				  (const_int 0)])
		 (const_int 0)
		 (set (match_operand:HI 0 "short_memory_operand" "=Q,Q")
		      (match_operand:HI 1 "reg_or_0_operand" "d,O")))]
  ""
  "@
   st %1,%M0 || exef0%F2
   st %.,%M0 || exef0%F2"
  [(set_attr "type" "long")
   (set_attr "length" "2")])

(define_insn "*cond_exec_hi_load_true"
  [(if_then_else (match_operator 2 "f0_compare_operator"
				 [(match_operand:CC 3 "f0_operand" "")
				  (const_int 0)])
		 (set (match_operand:HI 0 "gpr_operand" "=d,d,d")
		      (match_operand:HI 1 "cond_exec_operand" "d,L,Q"))
		 (const_int 0))]
  ""
  "@
   exef0%T2 || mv %0,%1
   exef0%T2 || ldi %0,%1
   ld %0,%M1 || exef0%T2"
  [(set_attr "type" "long")
   (set_attr "length" "2")])

(define_insn "*cond_exec_hi_load_true"
  [(if_then_else (match_operator 2 "f0_compare_operator"
				 [(match_operand:CC 3 "f0_operand" "")
				  (const_int 0)])
		 (const_int 0)
		 (set (match_operand:HI 0 "gpr_operand" "=d,d,d")
		      (match_operand:HI 1 "cond_exec_operand" "d,L,Q")))]
  ""
  "@
   exef0%F2 || mv %0,%1
   exef0%F2 || ldi %0,%1
   ld %0,%M1 || exef0%F2"
  [(set_attr "type" "long")
   (set_attr "length" "2")])

(define_insn "*cond_exec_si_binary_true"
  [(if_then_else (match_operator 3 "f0_compare_operator"
				 [(match_operand:CC 4 "f0_operand" "")
				  (const_int 0)])
		 (set (match_operand:SI 0 "gpr_operand" "=e")
		      (match_operator:SI 5 "binary_parallel_operator"
					 [(match_operand:SI 1 "gpr_operand" "0")
					  (match_operand:SI 2 "gpr_operand" "e")]))
		 (const_int 0))]
  "rtx_equal_p (operands[0], operands[1])"
  "*
{
  if (GET_CODE (operands[2]) == REG || GET_CODE (operands[2]) == SUBREG)
    switch (GET_CODE (operands[5]))
      {
      case PLUS:	return \"exef0%T3 || add2w %0,%2\";
      case MINUS:	return \"exef0%T3 || sub2w %0,%2\";
      }

  fatal_insn (\"cond_exec_si_binary_true\", insn);
  return \"\";
}"
  [(set_attr "type" "long")
   (set_attr "length" "2")])

(define_insn "*cond_exec_si_binary_false"
  [(if_then_else (match_operator 3 "f0_compare_operator"
				 [(match_operand:CC 4 "f0_operand" "")
				  (const_int 0)])
		 (const_int 0)
		 (set (match_operand:SI 0 "gpr_operand" "=d")
		      (match_operator:SI 5 "binary_parallel_operator"
					 [(match_operand:SI 1 "gpr_operand" "0")
					  (match_operand:SI 2 "arith16_operand" "di")])))]
  "rtx_equal_p (operands[0], operands[1])"
  "*
{
  if (GET_CODE (operands[2]) == REG || GET_CODE (operands[2]) == SUBREG)
    switch (GET_CODE (operands[5]))
      {
      case PLUS:	return \"exef0%F3 || add2w %0,%2\";
      case MINUS:	return \"exef0%F3 || sub2w %0,%2\";
      }

  fatal_insn (\"cond_exec_si_binary_false\", insn);
  return \"\";
}"
  [(set_attr "type" "long")
   (set_attr "length" "2")])

(define_insn "*cond_exec_si_store_true"
  [(if_then_else (match_operator 2 "f0_compare_operator"
				 [(match_operand:CC 3 "f0_operand" "")
				  (const_int 0)])
		 (set (match_operand:SI 0 "short_memory_operand" "=Q")
		      (match_operand:SI 1 "gpr_operand" "e"))
		 (const_int 0))]
  ""
  "st2w %1,%M0 || exef0%T2"
  [(set_attr "type" "long")
   (set_attr "length" "2")])

(define_insn "*cond_exec_si_store_false"
  [(if_then_else (match_operator 2 "f0_compare_operator"
				 [(match_operand:CC 3 "f0_operand" "")
				  (const_int 0)])
		 (const_int 0)
		 (set (match_operand:SI 0 "short_memory_operand" "=Q")
		      (match_operand:SI 1 "gpr_operand" "d")))]
  ""
  "st2w %1,%M0 || exef0%F2"
  [(set_attr "type" "long")
   (set_attr "length" "2")])

(define_insn "*cond_exec_si_load_true"
  [(if_then_else (match_operator 2 "f0_compare_operator"
				 [(match_operand:CC 3 "f0_operand" "")
				  (const_int 0)])
		 (set (match_operand:SI 0 "gpr_operand" "=e,e")
		      (match_operand:SI 1 "cond_exec_operand" "e,Q"))
		 (const_int 0))]
  ""
  "@
   exef0%T2 || mv2w %0,%1
   ld2w %0,%M1 || exef0%T2"
  [(set_attr "type" "long")
   (set_attr "length" "2")])

(define_insn "*cond_exec_si_load_true"
  [(if_then_else (match_operator 2 "f0_compare_operator"
				 [(match_operand:CC 3 "f0_operand" "")
				  (const_int 0)])
		 (const_int 0)
		 (set (match_operand:SI 0 "gpr_operand" "=e,e")
		      (match_operand:SI 1 "cond_exec_operand" "e,Q")))]
  ""
  "@
   exef0%F2 || mv2w %0,%1
   ld2w %0,%M1 || exef0%F2"
  [(set_attr "type" "long")
   (set_attr "length" "2")])

(define_insn "*cond_exec_sf_store_true"
  [(if_then_else (match_operator 2 "f0_compare_operator"
				 [(match_operand:CC 3 "f0_operand" "")
				  (const_int 0)])
		 (set (match_operand:SF 0 "short_memory_operand" "=Q")
		      (match_operand:SF 1 "gpr_operand" "e"))
		 (const_int 0))]
  ""
  "st2w %1,%M0 || exef0%T2"
  [(set_attr "type" "long")
   (set_attr "length" "2")])

(define_insn "*cond_exec_sf_store_false"
  [(if_then_else (match_operator 2 "f0_compare_operator"
				 [(match_operand:CC 3 "f0_operand" "")
				  (const_int 0)])
		 (const_int 0)
		 (set (match_operand:SF 0 "short_memory_operand" "=Q")
		      (match_operand:SF 1 "gpr_operand" "d")))]
  ""
  "st2w %1,%M0 || exef0%F2"
  [(set_attr "type" "long")
   (set_attr "length" "2")])

(define_insn "*cond_exec_sf_load_true"
  [(if_then_else (match_operator 2 "f0_compare_operator"
				 [(match_operand:CC 3 "f0_operand" "")
				  (const_int 0)])
		 (set (match_operand:SF 0 "gpr_operand" "=e,e")
		      (match_operand:SF 1 "cond_exec_operand" "e,Q"))
		 (const_int 0))]
  ""
  "@
   exef0%T2 || mv2w %0,%1
   ld2w %0,%M1 || exef0%T2"
  [(set_attr "type" "long")
   (set_attr "length" "2")])

(define_insn "*cond_exec_sf_load_true"
  [(if_then_else (match_operator 2 "f0_compare_operator"
				 [(match_operand:CC 3 "f0_operand" "")
				  (const_int 0)])
		 (const_int 0)
		 (set (match_operand:SF 0 "gpr_operand" "=e,e")
		      (match_operand:SF 1 "cond_exec_operand" "e,Q")))]
  ""
  "@
   exef0%F2 || mv2w %0,%1
   ld2w %0,%M1 || exef0%F2"
  [(set_attr "type" "long")
   (set_attr "length" "2")])

(define_insn "*cond_exec_call_true"
  [(if_then_else (match_operator 3 "f0_compare_operator"
				 [(match_operand:CC 4 "f0_operand" "")
				  (const_int 0)])
		 (parallel [(call (match_operand 0 "memory_operand" "m")
				  (match_operand 1 "" "i"))
			    (clobber (match_scratch:HI 2 "=l"))])			;; return address, r13
		 (const_int 0))]
  "GET_CODE (XEXP (operands[0], 0)) == REG"
  "jl %0 || exef0%T3"
  [(set_attr "type" "long")
   (set_attr "length" "2")])

(define_insn "*cond_exec_call_false"
  [(if_then_else (match_operator 3 "f0_compare_operator"
				 [(match_operand:CC 4 "f0_operand" "")
				  (const_int 0)])
		 (const_int 0)
		 (parallel [(call (match_operand 0 "memory_operand" "m")
				  (match_operand 1 "" "i"))
			    (clobber (match_scratch:HI 2 "=l"))]))]			;; return address, r13
  "GET_CODE (XEXP (operands[0], 0)) == REG"
  "jl %0 || exef0%F3"
  [(set_attr "type" "long")
   (set_attr "length" "2")])

(define_insn "*cond_exec_call_value_true"
  [(if_then_else (match_operator 4 "f0_compare_operator"
				 [(match_operand:CC 5 "f0_operand" "")
				  (const_int 0)])
		 (parallel [(set (match_operand 0 "gpr_operand" "=r")
				 (call (match_operand 1 "memory_operand" "m")
				       (match_operand 2 "" "i")))
			    (clobber (match_scratch:HI 3 "=l"))])			;; return address, r13
		 (const_int 0))]
  "GET_CODE (XEXP (operands[1], 0)) == REG"
  "jl %1 || exef0%T4"
  [(set_attr "type" "long")
   (set_attr "length" "2")])

(define_insn "*cond_exec_call_value_false"
  [(if_then_else (match_operator 4 "f0_compare_operator"
				 [(match_operand:CC 5 "f0_operand" "")
				  (const_int 0)])
		 (const_int 0)
		 (parallel [(set (match_operand 0 "gpr_operand" "=r")
				 (call (match_operand 1 "memory_operand" "m")
				       (match_operand 2 "" "i")))
			    (clobber (match_scratch:HI 3 "=l"))]))]			;; return address, r13
  "GET_CODE (XEXP (operands[1], 0)) == REG"
  "jl %1 || exef0%F4"
  [(set_attr "type" "long")
   (set_attr "length" "2")])

;;
;;  ....................
;;
;;	Conditional branches
;;
;;  ....................

(define_expand "beq"
  [(match_dup 2)
   (set (pc)
	(if_then_else (match_dup 1)
		      (label_ref (match_operand 0 "" ""))
		      (pc)))]
  ""
  "
{
  rtx reg;
  operands[2] = expand_comparison (EQ, compare_op0, compare_op1, &reg);
  operands[1] = gen_rtx (NE, GET_MODE (reg), reg, const0_rtx);
}")

(define_expand "bne"
  [(match_dup 2)
   (set (pc)
	(if_then_else (match_dup 1)
		      (label_ref (match_operand 0 "" ""))
		      (pc)))]
  ""
  "
{
  rtx reg;
  operands[2] = expand_comparison (NE, compare_op0, compare_op1, &reg);
  operands[1] = gen_rtx (NE, GET_MODE (reg), reg, const0_rtx);
}")

(define_expand "bgt"
  [(match_dup 2)
   (set (pc)
	(if_then_else (match_dup 1)
		      (label_ref (match_operand 0 "" ""))
		      (pc)))]
  ""
  "
{
  rtx reg;
  operands[2] = expand_comparison (GT, compare_op0, compare_op1, &reg);
  operands[1] = gen_rtx (NE, GET_MODE (reg), reg, const0_rtx);
}")

(define_expand "bge"
  [(match_dup 2)
   (set (pc)
	(if_then_else (match_dup 1)
		      (label_ref (match_operand 0 "" ""))
		      (pc)))]
  ""
  "
{
  rtx reg;
  operands[2] = expand_comparison (GE, compare_op0, compare_op1, &reg);
  operands[1] = gen_rtx (NE, GET_MODE (reg), reg, const0_rtx);
}")

(define_expand "blt"
  [(match_dup 2)
   (set (pc)
	(if_then_else (match_dup 1)
		      (label_ref (match_operand 0 "" ""))
		      (pc)))]
  ""
  "
{
  rtx reg;
  operands[2] = expand_comparison (LT, compare_op0, compare_op1, &reg);
  operands[1] = gen_rtx (NE, GET_MODE (reg), reg, const0_rtx);
}")

(define_expand "ble"
  [(match_dup 2)
   (set (pc)
	(if_then_else (match_dup 1)
		      (label_ref (match_operand 0 "" ""))
		      (pc)))]
  ""
  "
{
  rtx reg;
  operands[2] = expand_comparison (LE, compare_op0, compare_op1, &reg);
  operands[1] = gen_rtx (NE, GET_MODE (reg), reg, const0_rtx);
}")

(define_expand "bgtu"
  [(match_dup 2)
   (set (pc)
	(if_then_else (match_dup 1)
		      (label_ref (match_operand 0 "" ""))
		      (pc)))]
  ""
  "
{
  rtx reg;
  operands[2] = expand_comparison (GTU, compare_op0, compare_op1, &reg);
  operands[1] = gen_rtx (NE, GET_MODE (reg), reg, const0_rtx);
}")

(define_expand "bgeu"
  [(match_dup 2)
   (set (pc)
	(if_then_else (match_dup 1)
		      (label_ref (match_operand 0 "" ""))
		      (pc)))]
  ""
  "
{
  rtx reg;
  operands[2] = expand_comparison (GEU, compare_op0, compare_op1, &reg);
  operands[1] = gen_rtx (NE, GET_MODE (reg), reg, const0_rtx);
}")

(define_expand "bltu"
  [(match_dup 2)
   (set (pc)
	(if_then_else (match_dup 1)
		      (label_ref (match_operand 0 "" ""))
		      (pc)))]
  ""
  "
{
  rtx reg;
  operands[2] = expand_comparison (LTU, compare_op0, compare_op1, &reg);
  operands[1] = gen_rtx (NE, GET_MODE (reg), reg, const0_rtx);
}")

(define_expand "bleu"
  [(match_dup 2)
   (set (pc)
	(if_then_else (match_dup 1)
		      (label_ref (match_operand 0 "" ""))
		      (pc)))]
  ""
  "
{
  rtx reg;
  operands[2] = expand_comparison (LEU, compare_op0, compare_op1, &reg);
  operands[1] = gen_rtx (NE, GET_MODE (reg), reg, const0_rtx);
}")

(define_insn "*cond_branch"
  [(set (pc)
	(if_then_else (match_operator:CC 0 "f0_compare_operator"
					 [(match_operand:CC 1 "f0_operand" "")
					  (const_int 0)])
		      (match_operand 2 "pc_or_label_operand" "")
		      (match_operand 3 "pc_or_label_operand" "")))]
  ""
  "*
{
  if (operands[2] == pc_rtx)
    return (GET_CODE (operands[3]) == RETURN) ? \"jmp r13 || exef0%T0\" : \"brf0%T0 %l3\";
  else
    return (GET_CODE (operands[2]) == RETURN) ? \"jmp r13 || exef0%F0\" : \"brf0%F0 %l2\";
}"
  [(set_attr "type" "long")
   (set_attr "length" "2")])


;;
;;  ....................
;;
;;	Set from condition code
;;
;;  ....................

(define_expand "seq"
  [(match_dup 2)
   (set (match_operand:HI 0 "gpr_operand" "")
	(match_dup 1))]
  ""
  "
{
  rtx reg;
  operands[2] = expand_comparison (EQ, compare_op0, compare_op1, &reg);
  operands[1] = gen_rtx (NE, GET_MODE (reg), reg, const0_rtx);
}")

(define_expand "sne"
  [(match_dup 2)
   (set (match_operand:HI 0 "gpr_operand" "")
	(match_dup 1))]
  ""
  "
{
  rtx reg;
  operands[2] = expand_comparison (NE, compare_op0, compare_op1, &reg);
  operands[1] = gen_rtx (NE, GET_MODE (reg), reg, const0_rtx);
}")

(define_expand "sgt"
  [(match_dup 2)
   (set (match_operand:HI 0 "gpr_operand" "")
	(match_dup 1))]
  ""
  "
{
  rtx reg;
  operands[2] = expand_comparison (GT, compare_op0, compare_op1, &reg);
  operands[1] = gen_rtx (NE, GET_MODE (reg), reg, const0_rtx);
}")

(define_expand "sge"
  [(match_dup 2)
   (set (match_operand:HI 0 "gpr_operand" "")
	(match_dup 1))]
  ""
  "
{
  rtx reg;
  operands[2] = expand_comparison (GE, compare_op0, compare_op1, &reg);
  operands[1] = gen_rtx (NE, GET_MODE (reg), reg, const0_rtx);
}")

(define_expand "slt"
  [(match_dup 2)
   (set (match_operand:HI 0 "gpr_operand" "")
	(match_dup 1))]
  ""
  "
{
  rtx reg;
  operands[2] = expand_comparison (LT, compare_op0, compare_op1, &reg);
  operands[1] = gen_rtx (NE, GET_MODE (reg), reg, const0_rtx);
}")

(define_expand "sle"
  [(match_dup 2)
   (set (match_operand:HI 0 "gpr_operand" "")
	(match_dup 1))]
  ""
  "
{
  rtx reg;
  operands[2] = expand_comparison (LE, compare_op0, compare_op1, &reg);
  operands[1] = gen_rtx (NE, GET_MODE (reg), reg, const0_rtx);
}")

(define_expand "sgtu"
  [(match_dup 2)
   (set (match_operand:HI 0 "gpr_operand" "")
	(match_dup 1))]
  ""
  "
{
  rtx reg;
  operands[2] = expand_comparison (GTU, compare_op0, compare_op1, &reg);
  operands[1] = gen_rtx (NE, GET_MODE (reg), reg, const0_rtx);
}")

(define_expand "sgeu"
  [(match_dup 2)
   (set (match_operand:HI 0 "gpr_operand" "")
	(match_dup 1))]
  ""
  "
{
  rtx reg;
  operands[2] = expand_comparison (GEU, compare_op0, compare_op1, &reg);
  operands[1] = gen_rtx (NE, GET_MODE (reg), reg, const0_rtx);
}")

(define_expand "sltu"
  [(match_dup 2)
   (set (match_operand:HI 0 "gpr_operand" "")
	(match_dup 1))]
  ""
  "
{
  rtx reg;
  operands[2] = expand_comparison (LTU, compare_op0, compare_op1, &reg);
  operands[1] = gen_rtx (NE, GET_MODE (reg), reg, const0_rtx);
}")

(define_expand "sleu"
  [(match_dup 2)
   (set (match_operand:HI 0 "gpr_operand" "")
	(match_dup 1))]
  ""
  "
{
  rtx reg;
  operands[2] = expand_comparison (LEU, compare_op0, compare_op1, &reg);
  operands[1] = gen_rtx (NE, GET_MODE (reg), reg, const0_rtx);
}")

(define_insn "*scc"
  [(set (match_operand:HI 0 "gpr_operand" "=d")
	(match_operator 1 "f0_compare_operator"
			[(match_operand:CC 2 "f0_operand" "")
			 (const_int 0)]))]
  ""
  "setf0%F1 %0"
  [(set_attr "type" "mu")
   (set_attr "length" "1")])


;;
;;  ....................
;;
;;	Data conversion
;;
;;  ....................

(define_insn "zero_extendqihi2"
  [(set (match_operand:HI 0 "gpr_operand" "=d,d,d")
	(zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "d,Q,m")))]
  ""
  "@
   mvub %0,%1
   ldub %0,%M1
   ldub %0,%M1"
  [(set_attr "type" "iu,mu,long")
   (set_attr "length" "1,1,2")])

(define_insn "zero_extendqisi2"
  [(set (match_operand:SI 0 "gpr_operand" "=d,d,d")
	(zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "d,Q,m")))]
  ""
  "@
   mvub %L0,%1\;ldi %U0,0
   ldub %L0,%M1\;ldi %U0,0
   ldub %L0,%M1\;ldi %U0,0"
  [(set_attr "type" "long,long,long")
   (set_attr "length" "2,2,3")])

(define_split
  [(set (match_operand:SI 0 "gpr_operand" "")
	(zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))]
  "reload_completed"
  [(set (match_dup 3) (zero_extend:HI (match_dup 1)))
   (set (match_dup 2) (const_int 0))]
  "
{
  operands[2] = d10v_subword (operands[0], 0, HImode, SImode);
  operands[3] = d10v_subword (operands[0], 1, HImode, SImode);
}")

(define_insn "zero_extendhisi2"
  [(set (match_operand:SI 0 "gpr_operand" "=e,e,e")
	(zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "e,Q,m")))]
  ""
  "@
   mv %L0,%1\;ldi %U0,0
   ld %L0,%M1\;ldi %U0,0
   ld %L0,%M1\;ldi %U0,0"
  [(set_attr "type" "long,long,long")
   (set_attr "length" "2,2,3")])

(define_split
  [(set (match_operand:SI 0 "gpr_operand" "")
	(zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
  "reload_completed"
  [(set (match_dup 3) (match_dup 1))
   (set (match_dup 2) (const_int 0))]   
  "
{
  operands[2] = d10v_subword (operands[0], 0, HImode, SImode);
  operands[3] = d10v_subword (operands[0], 1, HImode, SImode);
}")

(define_insn "zero_extendqidi2"
  [(set (match_operand:DI 0 "gpr_operand" "=e,e,e")
	(zero_extend:DI (match_operand:QI 1 "nonimmediate_operand" "d,Q,m")))]
  ""
  "@
   mvub %D0,%1\;ldi %C0,0\;ldi %B0,0\;ldi %A0,0
   ldub %D0,%M1\;ldi %C0,0\;ldi %B0,0\;ldi %A0,0
   ldub %D0,%M1\;ldi %C0,0\;ldi %B0,0\;ldi %A0,0"
  [(set_attr "type" "long,long,long")
   (set_attr "length" "4,4,5")])

(define_split
  [(set (match_operand:DI 0 "gpr_operand" "")
	(zero_extend:DI (match_operand:QI 1 "gpr_operand" "")))]
  "reload_completed"
  [(set (match_dup 5) (zero_extend:HI (match_dup 1)))
   (set (match_dup 2) (const_int 0))
   (set (match_dup 3) (const_int 0))
   (set (match_dup 4) (const_int 0))]
  "
{
  operands[2] = d10v_subword (operands[0], 0, HImode, DImode);
  operands[3] = d10v_subword (operands[0], 1, HImode, DImode);
  operands[4] = d10v_subword (operands[0], 2, HImode, DImode);
  operands[5] = d10v_subword (operands[0], 3, HImode, DImode);
}")

(define_insn "zero_extendhidi2"
  [(set (match_operand:DI 0 "gpr_operand" "=e,e,e")
	(zero_extend:DI (match_operand:HI 1 "nonimmediate_operand" "d,Q,m")))]
  ""
  "@
   mv %D0,%1\;ldi %C0,0\;ldi %B0,0\;ldi %A0,0
   ld %D0,%M1\;ldi %C0,0\;ldi %B0,0\;ldi %A0,0
   ld %D0,%M1\;ldi %C0,0\;ldi %B0,0\;ldi %A0,0"
  [(set_attr "type" "long,long,long")
   (set_attr "length" "4,4,5")])

(define_split
  [(set (match_operand:DI 0 "gpr_operand" "")
	(zero_extend:DI (match_operand:HI 1 "nonimmediate_operand" "")))]
  "reload_completed"
  [(set (match_dup 5) (match_dup 1))
   (set (match_dup 2) (const_int 0))
   (set (match_dup 3) (const_int 0))
   (set (match_dup 4) (const_int 0))]
  "
{
  operands[2] = d10v_subword (operands[0], 0, HImode, DImode);
  operands[3] = d10v_subword (operands[0], 1, HImode, DImode);
  operands[4] = d10v_subword (operands[0], 2, HImode, DImode);
  operands[5] = d10v_subword (operands[0], 3, HImode, DImode);
}")

(define_insn "zero_extendsidi2"
  [(set (match_operand:DI 0 "gpr_operand" "=e,e,e")
	(zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "e,Q,m")))]
  ""
  "@
   mv2w %C0,%1\;ldi %B0,0\;ldi %A0,0
   ld2w %C0,%M1\;ldi %B0,0\;ldi %A0,0
   ld2w %C0,%M1\;ldi %B0,0\;ldi %A0,0"
  [(set_attr "type" "long,long,long")
   (set_attr "length" "3,3,4")])

(define_split
  [(set (match_operand:DI 0 "gpr_operand" "")
	(zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "")))]
  "reload_completed"
  [(set (match_dup 4) (match_dup 1))
   (set (match_dup 2) (const_int 0))
   (set (match_dup 3) (const_int 0))]
  "
{
  operands[2] = d10v_subword (operands[0], 0, HImode, DImode);
  operands[3] = d10v_subword (operands[0], 1, HImode, DImode);
  operands[4] = d10v_subword (operands[0], 2, SImode, DImode);
}")

(define_insn "extendqihi2"
  [(set (match_operand:HI 0 "gpr_operand" "=d,d,d")
	(sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "d,Q,m")))]
  ""
  "@
   mvb %0,%1
   ldb %0,%M1
   ldb %0,%M1"
  [(set_attr "type" "iu,mu,long")
   (set_attr "length" "1,1,2")])

(define_insn "extendqisi2"
  [(set (match_operand:SI 0 "gpr_operand" "=e,e,e")
	(sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "e,Q,m")))]
  ""
  "@
   mvb %L0,%1\;mv %U0,%L0\;srai %U0,15
   ldb %L0,%M1\;mv %U0,%L0\;srai %U0,15
   ldb %L0,%M1\;mv %U0,%L0\;srai %U0,15"
  [(set_attr "type" "long,long,long")
   (set_attr "length" "3,3,4")])

(define_insn "extendhisi2"
  [(set (match_operand:SI 0 "gpr_operand" "=e,e,e,a")
	(sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "e,Q,m,e")))]
  ""
  "*
{
  if (ACCUM_P (REGNO (operands[0])))
    return \"mvtaclo %1,%0\";

  if (GET_CODE (operands[1]) == MEM)
    return \"ld %L0,%M1\;mv %U0,%L0\;srai %U0,15\";

  if (REGNO (operands[0]) == REGNO (operands[1]))
    return \"mv %L0,%1\;srai %U0,15\";

  return \"mv %L0,%1\;mv %U0,%L0\;srai %U0,15\";
}"
  [(set_attr "type" "long,long,long,iu")
   (set_attr "length" "3,3,4,1")])

(define_insn "extendqidi2"
  [(set (match_operand:DI 0 "gpr_operand" "=e,e,e")
	(sign_extend:DI (match_operand:QI 1 "nonimmediate_operand" "e,Q,m")))]
  ""
  "@
   mvb %D0,%1\;mv %C0,%D0\;srai %C0,15\;mv %B0,%C0\;mv %A0,%C0
   ldb %D0,%M1\;mv %C0,%D0\;srai %C0,15\;mv %B0,%C0\;mv %A0,%C0
   ldb %D0,%M1\;mv %C0,%D0\;srai %C0,15\;mv %B0,%C0\;mv %A0,%C0"
  [(set_attr "type" "long,long,long")
   (set_attr "length" "5,5,6")])

(define_insn "extendhidi2"
  [(set (match_operand:DI 0 "gpr_operand" "=e,e,e")
	(sign_extend:DI (match_operand:HI 1 "nonimmediate_operand" "e,Q,m")))]
  ""
  "@
   mv %D0,%1\;mv %C0,%D0\;srai %C0,15\;mv %B0,%C0\;mv %A0,%C0
   ld %D0,%M1\;mv %C0,%D0\;srai %C0,15\;mv %B0,%C0\;mv %A0,%C0
   ld %D0,%M1\;mv %C0,%D0\;srai %C0,15\;mv %B0,%C0\;mv %A0,%C0"
  [(set_attr "type" "long,long,long")
   (set_attr "length" "5,5,6")])

(define_insn "extendsidi2"
  [(set (match_operand:DI 0 "gpr_operand" "=e,e,e")
	(sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "e,Q,m")))]
  ""
  "@
   mv2w %C0,%1\;mv %B0,%C0\;srai %B0,15\;mv %A0,%B0
   ld2w %C0,%M1\;mv %B0,%C0\;srai %B0,15\;mv %A0,%B0
   ld2w %C0,%M1\;mv %B0,%C0\;srai %B0,15\;mv %A0,%B0"
  [(set_attr "type" "long,long,long")
   (set_attr "length" "4,4,5")])


;;
;;  ....................
;;
;;	Addition
;;
;;  ....................

(define_expand "addhi3"
  [(set (match_operand:HI 0 "gpr_operand" "")
	(plus:HI (match_operand:HI 1 "gpr_operand" "")
		 (match_operand:HI 2 "arith16_operand" "")))]
  ""
  "")

(define_insn "*addhi3_no_small_insns"
  [(set (match_operand:HI 0 "gpr_operand" "=d,d,d,d")
	(plus:HI (match_operand:HI 1 "gpr_operand" "%0,0,0,d")
		 (match_operand:HI 2 "arith16_operand" "d,I,N,i")))]
  "TARGET_NO_SMALL_INSNS || !optimize"
  "@
   add %0,%2
   addi %0,%2
   subi %0,%n2
   add3 %0,%1,%2"
  [(set_attr "type" "either,either,either,long")
   (set_attr "length" "1,1,1,2")])

(define_insn "*addhi3_small_insns"
  [(set (match_operand:HI 0 "gpr_operand" "=d,d,d,d,d,d")
	(plus:HI (match_operand:HI 1 "gpr_operand" "%0,0,0,d,d,d")
		 (match_operand:HI 2 "arith16_operand" "d,I,N,I,N,i")))]
  "TARGET_SMALL_INSNS && optimize"
  "@
   add %0,%2
   addi %0,%2
   subi %0,%n2
   mv %0,%1\;addi %0,%2
   mv %0,%1\;subi %0,%n2
   add3 %0,%1,%2"
  [(set_attr "type" "either,either,either,long,long,long")
   (set_attr "length" "1,1,1,2,2,2")])

(define_split
  [(set (match_operand:HI 0 "gpr_operand" "")
	(plus:HI (match_operand:HI 1 "gpr_operand" "")
		 (match_operand:HI 2 "const_int_operand" "")))]
  "reload_completed && TARGET_SMALL_INSNS && optimize
   && REGNO (operands[0]) != REGNO (operands[1])
   && IN_RANGE_P (INTVAL (operands[2]), -16, 16)
   && INTVAL (operands[2]) != 0"
  [(set (match_dup 0) (match_dup 1))
   (set (match_dup 0) (plus:HI (match_dup 0) (match_dup 2)))]
  "")

(define_expand "addsi3"
  [(set (match_operand:SI 0 "register_operand" "")
	(plus:SI (match_operand:SI 1 "register_operand" "")
		 (match_operand:SI 2 "register_operand" "")))]
  ""
  "")

(define_insn "*addsi3_noaccum"
  [(set (match_operand:SI 0 "gpr_operand" "=e")
	(plus:SI (match_operand:SI 1 "gpr_operand" "%0")
		 (match_operand:SI 2 "gpr_operand" "e")))]
  "!TARGET_ACCUM"
  "add2w %0,%2"
  [(set_attr "type" "iu")
   (set_attr "length" "1")])

(define_insn "*addsi3_noaddac3"
  [(set (match_operand:SI 0 "register_operand" "=e,a")
	(plus:SI (match_operand:SI 1 "register_operand" "%0,0")
		 (match_operand:SI 2 "register_operand" "e,ea")))]
  "TARGET_ACCUM && !TARGET_ADDAC3"
  "@
   add2w %0,%2
   add %0,%2"
  [(set_attr "type" "iu")
   (set_attr "length" "1")])

(define_insn "*addsi3_addac3"
  [(set (match_operand:SI 0 "register_operand" "=e,e,a")
	(plus:SI (match_operand:SI 1 "register_operand" "%0,ea,0")
		 (match_operand:SI 2 "register_operand" "e,a,ea")))]
  "TARGET_ACCUM && TARGET_ADDAC3"
  "@
   add2w %0,%2
   addac3 %0,%1,%2
   add %0,%2"
  [(set_attr "type" "iu")
   (set_attr "length" "1")])

(define_expand "adddi3"
  [(parallel [(set (match_operand:DI 0 "gpr_operand" "")
		   (plus:DI (match_operand:DI 1 "gpr_operand" "")
			    (match_operand:DI 2 "arith_nonnegative_operand" "")))
	      (clobber (match_dup 3))])]
  "TARGET_LONGLONG_ALU"
  "operands[3] = gen_rtx (REG, CCmode, F0_REGNUM);")

(define_insn "*adddi3_internal"
  [(parallel [(set (match_operand:DI 0 "gpr_operand" "=e,e,e")
		   (plus:DI (match_operand:DI 1 "gpr_operand" "%0,0,0")
			    (match_operand:DI 2 "arith_nonnegative_operand" "e,I,M")))
	      (clobber (match_operand:CC 3 "f0_operand" ""))])]
  "TARGET_LONGLONG_ALU"
  "* return emit_add (operands, insn);"
  [(set_attr "type" "long")
   (set_attr "length" "10,10,12")])


;;
;;  ....................
;;
;;	Subtraction
;;
;;  ....................

(define_expand "subhi3"
  [(set (match_operand:HI 0 "gpr_operand" "")
	(minus:HI (match_operand:HI 1 "gpr_operand" "")
		  (match_operand:HI 2 "arith16_operand" "")))]
  ""
  "")

(define_insn "*subhi3_no_small_insns"
  [(set (match_operand:HI 0 "gpr_operand" "=d,d,d,d")
	(minus:HI (match_operand:HI 1 "gpr_operand" "0,0,0,d")
		  (match_operand:HI 2 "arith16_operand" "d,I,N,i")))]
  "TARGET_NO_SMALL_INSNS || !optimize"
  "@
   sub %0,%2
   subi %0,%2
   addi %0,%n2
   add3 %0,%1,%n2"
  [(set_attr "type" "either,either,either,long")
   (set_attr "length" "1,1,1,2")])

(define_insn "*subhi3_small_insns"
  [(set (match_operand:HI 0 "gpr_operand" "=d,d,d,d,d,d")
	(minus:HI (match_operand:HI 1 "gpr_operand" "0,0,0,d,d,d")
		  (match_operand:HI 2 "arith16_operand" "d,I,N,I,N,i")))]
  "TARGET_SMALL_INSNS && optimize"
  "@
   sub %0,%2
   subi %0,%2
   addi %0,%n2
   mv %0,%1\;subi %0,%2
   mv %0,%1\;addi %0,%n2
   add3 %0,%1,%n2"
  [(set_attr "type" "either,either,either,long,long,long")
   (set_attr "length" "1,1,1,2,2,2")])

(define_split
  [(set (match_operand:HI 0 "gpr_operand" "")
	(minus:HI (match_operand:HI 1 "gpr_operand" "")
		  (match_operand:HI 2 "const_int_operand" "")))]
  "reload_completed && TARGET_SMALL_INSNS && optimize
   && REGNO (operands[0]) != REGNO (operands[1])
   && IN_RANGE_P (INTVAL (operands[2]), -16, 16)
   && INTVAL (operands[2]) != 0"
  [(set (match_dup 0) (match_dup 1))
   (set (match_dup 0) (minus:HI (match_dup 0) (match_dup 2)))]
  "")


(define_expand "subsi3"
  [(set (match_operand:SI 0 "register_operand" "")
	(minus:SI (match_operand:SI 1 "register_operand" "")
		  (match_operand:SI 2 "register_operand" "")))]
  ""
  "")

(define_insn "*subsi3_noaccum"
  [(set (match_operand:SI 0 "gpr_operand" "=e")
	(minus:SI (match_operand:SI 1 "gpr_operand" "0")
		  (match_operand:SI 2 "gpr_operand" "e")))]
  "!TARGET_ACCUM"
  "sub2w %0,%2"
  [(set_attr "type" "iu")
   (set_attr "length" "1")])

(define_insn "*subsi3_noaddac3"
  [(set (match_operand:SI 0 "register_operand" "=e,a")
	(minus:SI (match_operand:SI 1 "register_operand" "0,0")
		 (match_operand:SI 2 "register_operand" "e,ea")))]
  "TARGET_ACCUM && !TARGET_ADDAC3"
  "@
   sub2w %0,%2
   sub %0,%2"
  [(set_attr "type" "iu")
   (set_attr "length" "1")])

(define_insn "*subsi3_addac3"
  [(set (match_operand:SI 0 "register_operand" "=e,e,a")
	(minus:SI (match_operand:SI 1 "register_operand" "0,ea,0")
		  (match_operand:SI 2 "register_operand" "e,a,ea")))]
  "TARGET_ACCUM && TARGET_ADDAC3"
  "@
   sub2w %0,%2
   subac3 %0,%1,%2
   sub %0,%2"
  [(set_attr "type" "iu")
   (set_attr "length" "1")])

(define_expand "subdi3"
  [(parallel [(set (match_operand:DI 0 "gpr_operand" "")
		   (minus:DI (match_operand:DI 1 "gpr_operand" "")
			     (match_operand:DI 2 "gpr_operand" "")))
	      (clobber (match_dup 3))])]
  "TARGET_LONGLONG_ALU"
  "operands[3] = gen_rtx (REG, CCmode, F0_REGNUM);")

(define_insn "*subdi3_internal1"
  [(parallel [(set (match_operand:DI 0 "gpr_operand" "=e")
		   (minus:DI (match_operand:DI 1 "gpr_operand" "0")
			     (match_operand:DI 2 "gpr_operand" "e")))
	      (clobber (match_operand:CC 3 "f0_operand" ""))])]
  "TARGET_LONGLONG_ALU"
  "* return emit_subtract (operands, insn);"
  [(set_attr "type" "long")
   (set_attr "length" "10")])


;;
;;  ....................
;;
;;	Negation
;;
;;  ....................

(define_insn "neghi2"
  [(set (match_operand:HI 0 "gpr_operand" "=d")
	(neg:HI (match_operand:HI 1 "gpr_operand" "0")))]
  ""
  "neg %0"
  [(set_attr "type" "either")
   (set_attr "length" "1")])

(define_expand "negsi2"
  [(parallel [(set (match_operand:SI 0 "register_operand" "")
		   (neg:SI (match_operand:SI 1 "register_operand" "")))
	      (clobber (match_dup 2))])]
  ""
  "operands[2] = gen_rtx (REG, CCmode, F0_REGNUM);")

(define_insn "*negsi2_internal"
  [(set (match_operand:SI 0 "register_operand" "=a,e")
	(neg:SI (match_operand:SI 1 "register_operand" "0,0")))
   (clobber (match_operand:CC 2 "f0_operand" ""))]
  ""
  "@
   neg %0
   not %U0\;neg %L0\;cmpeqi %L0,0\;exef0t || addi %U0,1"
  [(set_attr "type" "iu,long")
   (set_attr "length" "1,6")])

(define_expand "negdi2"
  [(parallel [(set (match_operand:DI 0 "gpr_operand" "")
		   (neg:DI (match_operand:DI 1 "gpr_operand" "")))
	      (clobber (match_dup 2))])]
  "TARGET_LONGLONG_ALU"
  "operands[2] = gen_rtx (REG, CCmode, F0_REGNUM);")

(define_insn "*negdi2_internal"
  [(set (match_operand:DI 0 "gpr_operand" "=e")
	(neg:DI (match_operand:DI 1 "gpr_operand" "0")))
   (clobber (match_operand:CC 2 "f0_operand" ""))]
  "TARGET_LONGLONG_ALU"
  "not %A0\;not %B0\;not %C0\;neg %D0\;cmpeqi %D0,0\;exef0t || addi %C0,1\;exef0t || cmpeqi %C0,0\;exef0t || addi %B0,1\;exef0t || cmpeqi %B0,0\;exef0t || addi %A0,1"
  [(set_attr "type" "long")
   (set_attr "length" "16")])


;;
;;  ....................
;;
;;	Multiplication
;;
;;  ....................

(define_insn "mulhi3"
  [(set (match_operand:HI 0 "gpr_operand" "=d")
	(mult:HI (match_operand:HI 1 "gpr_operand" "%0")
		 (match_operand:HI 2 "gpr_operand" "d")))]
  ""
  "mul %0,%2"
  [(set_attr "type" "iu")
   (set_attr "length" "1")])

(define_insn "*mulhisi3_add"
  [(set (match_operand:SI 0 "accum_operand" "=a")
	(plus:SI (mult:SI (sign_extend:SI (match_operand:HI 1 "gpr_operand" "%d"))
			  (sign_extend:SI (match_operand:HI 2 "gpr_operand" "d")))
		 (match_operand:SI 3 "register_operand" "0")))]
  "TARGET_ACCUM"
  "mac %0,%1,%2"
  [(set_attr "type" "iu")
   (set_attr "length" "1")])

(define_insn "mulhisi3"
  [(set (match_operand:SI 0 "accum_operand" "=a")
	(mult:SI (sign_extend:SI (match_operand:HI 1 "gpr_operand" "%d"))
		 (sign_extend:SI (match_operand:HI 2 "gpr_operand" "d"))))]
  "TARGET_ACCUM"
  "mulx %0,%1,%2"
  [(set_attr "type" "iu")
   (set_attr "length" "1")])

(define_insn "*umulhisi3_add"
  [(set (match_operand:SI 0 "accum_operand" "=a")
	(plus:SI (mult:SI (zero_extend:SI (match_operand:HI 1 "gpr_operand" "%d"))
			  (zero_extend:SI (match_operand:HI 2 "gpr_operand" "d")))
		 (match_operand:SI 3 "register_operand" "0")))]
  "TARGET_ACCUM"
  "macu %0,%1,%2"
  [(set_attr "type" "iu")
   (set_attr "length" "1")])

(define_insn "umulhisi3"
  [(set (match_operand:SI 0 "accum_operand" "=a")
	(mult:SI (zero_extend:SI (match_operand:HI 1 "gpr_operand" "%d"))
		 (zero_extend:SI (match_operand:HI 2 "gpr_operand" "d"))))]
  "TARGET_ACCUM"
  "mulxu %0,%1,%2"
  [(set_attr "type" "iu")
   (set_attr "length" "1")])

(define_insn "*mulhisi3_mixed_add1"
  [(set (match_operand:SI 0 "accum_operand" "=a")
	(plus:SI (mult:SI (sign_extend:SI (match_operand:HI 1 "gpr_operand" "%d"))
			  (zero_extend:SI (match_operand:HI 2 "gpr_operand" "d")))
		 (match_operand:SI 3 "register_operand" "0")))]
  "TARGET_ACCUM"
  "macsu %0,%1,%2"
  [(set_attr "type" "iu")
   (set_attr "length" "1")])

(define_insn "*mulhisi3_mixed1"
  [(set (match_operand:SI 0 "accum_operand" "=a")
	(mult:SI (sign_extend:SI (match_operand:HI 1 "gpr_operand" "%d"))
		 (zero_extend:SI (match_operand:HI 2 "gpr_operand" "d"))))]
  "TARGET_ACCUM"
  "mulxsu %0,%1,%2"
  [(set_attr "type" "iu")
   (set_attr "length" "1")])

(define_insn "*mulhisi3_mixed_add2"
  [(set (match_operand:SI 0 "accum_operand" "=a")
	(plus:SI (mult:SI (zero_extend:SI (match_operand:HI 1 "gpr_operand" "%d"))
			  (sign_extend:SI (match_operand:HI 2 "gpr_operand" "d")))
		 (match_operand:SI 3 "register_operand" "0")))]
  "TARGET_ACCUM"
  "macsu %0,%2,%1"
  [(set_attr "type" "iu")
   (set_attr "length" "1")])

(define_insn "*mulhisi3_mixed2"
  [(set (match_operand:SI 0 "accum_operand" "=a")
	(mult:SI (zero_extend:SI (match_operand:HI 1 "gpr_operand" "%d"))
		 (sign_extend:SI (match_operand:HI 2 "gpr_operand" "d"))))]
  "TARGET_ACCUM"
  "mulxsu %0,%2,%1"
  [(set_attr "type" "iu")
   (set_attr "length" "1")])

(define_insn "mulsi3"
  [(set (match_operand:SI 0 "accum_operand" "=a")
	(mult:SI (match_operand:SI 1 "gpr_operand" "e")
		 (match_operand:SI 2 "gpr_operand" "e")))]
  "TARGET_ACCUM"
  "#"
  [(set_attr "type" "long")
   (set_attr "length" "8")])

(define_split
  [(set (match_operand:SI 0 "register_operand" "")
	(mult:SI (match_operand:SI 1 "gpr_operand" "")
		 (match_operand:SI 2 "gpr_operand" "")))]
  "TARGET_ACCUM && reload_completed"
  [(set (match_dup 0)
	(mult:SI (zero_extend:SI (match_dup 3))
		 (zero_extend:SI (match_dup 6))))
   (set (match_dup 0)
	(plus:SI (mult:SI (zero_extend:SI (match_dup 4))
			  (zero_extend:SI (match_dup 5)))
		 (match_dup 0)))
   (set (match_dup 0)
	(ashift:SI (match_dup 0)
		   (const_int 16)))
   (set (match_dup 0)
	(plus:SI (mult:SI (zero_extend:SI (match_dup 4))
			  (zero_extend:SI (match_dup 6)))
		 (match_dup 0)))]
  "
{
  operands[3] = d10v_subword (operands[1], 0, HImode, SImode);
  operands[4] = d10v_subword (operands[1], 1, HImode, SImode);

  operands[5] = d10v_subword (operands[2], 0, HImode, SImode);
  operands[6] = d10v_subword (operands[2], 1, HImode, SImode);
}")


;;
;;  ....................
;;
;;	Division
;;
;;  ....................

(define_expand "divmodhi4"
  [(parallel [(set (match_operand:HI 0 "gpr_operand" "")
		   (div:HI (match_operand:HI 1 "general_operand" "")
			   (match_operand:HI 2 "general_operand" "")))
	      (set (match_operand:HI 3 "gpr_operand" "")
		   (mod:HI (match_dup 1)
			   (match_dup 2)))])]
  ""
  "
{
  d10v_expand_divmod (operands, FALSE);
  DONE;
}")

(define_expand "udivmodhi4"
  [(parallel [(set (match_operand:HI 0 "gpr_operand" "")
		   (udiv:HI (match_operand:HI 1 "general_operand" "")
			    (match_operand:HI 2 "general_operand" "")))
	      (set (match_operand:HI 3 "gpr_operand" "")
		   (umod:HI (match_dup 1)
			    (match_dup 2)))])]
  ""
  "
{
  d10v_expand_divmod (operands, TRUE);
  DONE;
}")


;;
;;  ....................
;;
;;	Logical operations
;;
;;  ....................

(define_expand "andhi3"
  [(set (match_operand:HI 0 "gpr_operand" "")
	(and:HI (match_operand:HI 1 "gpr_operand" "")
		(match_operand:HI 2 "arith16_operand" "")))]
  ""
  "")

(define_insn "*andhi3_register"
  [(set (match_operand:HI 0 "gpr_operand" "=d")
	(and:HI (match_operand:HI 1 "gpr_operand" "%0")
		(match_operand:HI 2 "gpr_operand" "d")))]
  ""
  "and %0,%2"
  [(set_attr "type" "either")
   (set_attr "length" "1")])

(define_insn "*andhi3_move"
  [(set (match_operand:HI 0 "gpr_operand" "=d")
	(and:HI (match_operand:HI 1 "gpr_operand" "%d")
		(match_operand:HI 2 "const_int_operand" "n")))]
  "(INTVAL (operands[2]) & 0xffff) == 0xffff"
  "mv %0,%1"
  [(set_attr "type" "either")
   (set_attr "length" "1")])

(define_insn "*andhi3_constant"
  [(set (match_operand:HI 0 "gpr_operand" "=d,d,d")
	(and:HI (match_operand:HI 1 "gpr_operand" "%d,0,d")
		(match_operand:HI 2 "const_int_operand" "O,J,n")))]
  ""
  "*
{
  HOST_WIDE_INT value = INTVAL (operands[2]);

  if (value == 0)
    return \"ldi %0,0\";

  if ((value & 0xffff) == 0xffff)
    return \"mv %0,%1\";

  if (IN_RANGE_P (exact_log2 (~value), 0, 15))
    {
      if (REGNO (operands[0]) == REGNO (operands[1]))
	return \"bclri %0,%b2\";

      if (TARGET_SMALL_INSNS && optimize)
	return \"mv %0,%1\;bclri %0,%b2\";
    }

  return \"and3 %0,%1,%2\";
}"
  [(set_attr "type" "either,iu,long")
   (set_attr "length" "1,1,2")])

(define_split
  [(set (match_operand:HI 0 "gpr_operand" "")
	(and:HI (match_operand:HI 1 "gpr_operand" "")
		(match_operand:HI 2 "const_int_operand" "")))]
  "reload_completed && TARGET_SMALL_INSNS && optimize
   && !rtx_equal_p (operands[0], operands[1])
   && IN_RANGE_P (exact_log2 (~ INTVAL (operands[2])), 0, 15)"
  [(set (match_dup 0) (match_dup 1))
   (set (match_dup 0) (and:HI (match_dup 0) (match_dup 2)))]
  "")

(define_insn "andsi3"
  [(set (match_operand:SI 0 "gpr_operand" "=e,e,e")
	(and:SI (match_operand:SI 1 "gpr_operand" "%0,0,?e")
		(match_operand:SI 2 "arith32_operand" "e,n,n")))]
  ""
  "#"
  [(set_attr "type" "long,long,long")
   (set_attr "length" "2,4,4")])

(define_split
  [(set (match_operand:SI 0 "gpr_operand" "")
	(and:SI (match_operand:SI 1 "gpr_operand" "")
		(match_operand:SI 2 "arith32_operand" "")))]
  "reload_completed"
  [(match_dup 3)]
  "operands[3] = d10v_split_logical_op (operands, AND);")

(define_insn "anddi3"
  [(set (match_operand:DI 0 "gpr_operand" "=e,e,e")
	(and:DI (match_operand:DI 1 "gpr_operand" "0,0,?e")
		(match_operand:DI 2 "arith64_operand" "e,nF,nF")))]
  ""
  "#"
  [(set_attr "type" "long")
   (set_attr "length" "4,8,8")])

(define_split
  [(set (match_operand:DI 0 "gpr_operand" "")
	(and:DI (match_operand:DI 1 "gpr_operand" "")
		(match_operand:DI 2 "arith64_operand" "")))]
  "reload_completed"
  [(match_dup 3)]
  "operands[3] = d10v_split_logical_op (operands, AND);")

(define_expand "iorhi3"
  [(set (match_operand:HI 0 "gpr_operand" "")
	(ior:HI (match_operand:HI 1 "gpr_operand" "")
		(match_operand:HI 2 "arith16_operand" "")))]
  ""
  "")

(define_insn "*iorhi3_register"
  [(set (match_operand:HI 0 "gpr_operand" "=d")
	(ior:HI (match_operand:HI 1 "gpr_operand" "%0")
		(match_operand:HI 2 "gpr_operand" "d")))]
  ""
  "or %0,%2"
  [(set_attr "type" "either")
   (set_attr "length" "1")])

(define_insn "*iorhi3_neg1"
  [(set (match_operand:HI 0 "gpr_operand" "=d")
	(ior:HI (match_operand:HI 1 "gpr_operand" "d")
		(match_operand:HI 2 "const_int_operand" "n")))]
  "(INTVAL (operands[2]) & 0xffff) == 0xffff"
  "ldi %0,-1"
  [(set_attr "type" "either")
   (set_attr "length" "1")])

(define_insn "*iorhi3_constant"
  [(set (match_operand:HI 0 "gpr_operand" "=d,d,d")
	(ior:HI (match_operand:HI 1 "gpr_operand" "%d,0,d")
		(match_operand:HI 2 "const_int_operand" "O,P,n")))]
  ""
  "*
{
  HOST_WIDE_INT value = INTVAL (operands[2]);
  int log = exact_log2 (value);

  if (value == 0)
    return \"mv %0,%1\";

  if ((value & 0xffff) == 0xffff)
    return \"ldi %0,-1\";

  if (IN_RANGE_P (exact_log2 (value), 0, 15))
    {
      if (REGNO (operands[0]) == REGNO (operands[1]))
	return \"bseti %0,%b2\";

      if (TARGET_SMALL_INSNS && optimize)
	return \"mv %0,%1\;bseti %0,%b2\";
    }

  return \"or3 %0,%1,%2\";
}"
  [(set_attr "type" "either,iu,long")
   (set_attr "length" "1,1,2")])

(define_split
  [(set (match_operand:HI 0 "gpr_operand" "")
	(ior:HI (match_operand:HI 1 "gpr_operand" "")
		(match_operand:HI 2 "const_int_operand" "")))]
  "reload_completed && TARGET_SMALL_INSNS && optimize
   && !rtx_equal_p (operands[0], operands[1])
   && IN_RANGE_P (exact_log2 (INTVAL (operands[2])), 0, 15)"
  [(set (match_dup 0) (match_dup 1))
   (set (match_dup 0) (ior:HI (match_dup 0) (match_dup 2)))]
  "")

(define_insn "iorsi3"
  [(set (match_operand:SI 0 "gpr_operand" "=e,e")
	(ior:SI (match_operand:SI 1 "gpr_operand" "%0,e")
		(match_operand:SI 2 "arith32_operand" "e,i")))]
  ""
  "#"
  [(set_attr "type" "long,long")
   (set_attr "length" "2,4")])

(define_split
  [(set (match_operand:SI 0 "gpr_operand" "")
	(ior:SI (match_operand:SI 1 "gpr_operand" "")
		(match_operand:SI 2 "arith32_operand" "")))]
  "reload_completed"
  [(match_dup 3)]
  "operands[3] = d10v_split_logical_op (operands, IOR);")

(define_insn "iordi3"
  [(set (match_operand:DI 0 "gpr_operand" "=e,e,e")
	(ior:DI (match_operand:DI 1 "gpr_operand" "0,0,?e")
		(match_operand:DI 2 "arith64_operand" "e,nF,nF")))]
  ""
  "#"
  [(set_attr "type" "long")
   (set_attr "length" "4,8,8")])

(define_split
  [(set (match_operand:DI 0 "gpr_operand" "")
	(ior:DI (match_operand:DI 1 "gpr_operand" "")
		(match_operand:DI 2 "arith64_operand" "")))]
  "reload_completed"
  [(match_dup 3)]
  "operands[3] = d10v_split_logical_op (operands, IOR);")

(define_expand "xorhi3"
  [(set (match_operand:HI 0 "gpr_operand" "")
	(xor:HI (match_operand:HI 1 "gpr_operand" "")
		(match_operand:HI 2 "arith16_operand" "")))]
  ""
  "")

(define_insn "*xorhi3_register"
  [(set (match_operand:HI 0 "gpr_operand" "=d")
	(xor:HI (match_operand:HI 1 "gpr_operand" "%0")
		(match_operand:HI 2 "gpr_operand" "d")))]
  ""
  "xor %0,%2"
  [(set_attr "type" "either")
   (set_attr "length" "1")])

(define_insn "*xorhi3_not"
  [(set (match_operand:HI 0 "gpr_operand" "=d,?d")
	(xor:HI (match_operand:HI 1 "gpr_operand" "%0,d")
		(match_operand:HI 2 "const_int_operand" "n,n")))]
  "(INTVAL (operands[2]) & 0xffff) == 0xffff"
  "@
   not %0
   mv %0,%1\;not %0"
  [(set_attr "type" "either,long")
   (set_attr "length" "1,2")])

(define_split
  [(set (match_operand:HI 0 "gpr_operand" "")
	(xor:HI (match_operand:HI 1 "gpr_operand" "")
		(match_operand:HI 2 "const_int_operand" "n")))]
  "(INTVAL (operands[2]) & 0xffff) == 0xffff
   && !rtx_equal_p (operands[0], operands[1])"
  [(set (match_dup 0) (match_dup 1))
   (set (match_dup 0) (not:HI (match_dup 0)))]
  "")

(define_insn "*xorhi3_constant"
  [(set (match_operand:HI 0 "gpr_operand" "=d")
	(xor:HI (match_operand:HI 1 "gpr_operand" "%d")
		(match_operand:HI 2 "const_int_operand" "n")))]
  ""
  "*
{
  HOST_WIDE_INT value = INTVAL (operands[2]);
  int log = exact_log2 (value);

  if (value == 0)
    return \"mv %0,%1\";

  if ((value & 0xffff) == 0xffff && REGNO (operands[0]) == REGNO (operands[1]))
    return \"not %0\";

  if (IN_RANGE_P (exact_log2 (value), 0, 15))
    {
      if (REGNO (operands[0]) == REGNO (operands[1]))
	return \"bnoti %0,%b2\";

      if (TARGET_SMALL_INSNS && optimize)
	return \"mv %0,%1\;bnoti %0,%b2\";
    }

  return \"xor3 %0,%1,%2\";
}"
  [(set_attr "type" "long")
   (set_attr "length" "2")])

(define_split
  [(set (match_operand:HI 0 "gpr_operand" "")
	(xor:HI (match_operand:HI 1 "gpr_operand" "")
		(match_operand:HI 2 "const_int_operand" "")))]
  "reload_completed && TARGET_SMALL_INSNS && optimize
   && !rtx_equal_p (operands[0], operands[1])
   && IN_RANGE_P (exact_log2 (INTVAL (operands[2])), 0, 15)"
  [(set (match_dup 0) (match_dup 1))
   (set (match_dup 0) (xor:HI (match_dup 0) (match_dup 2)))]
  "")

(define_insn "xorsi3"
  [(set (match_operand:SI 0 "gpr_operand" "=e,e")
	(xor:SI (match_operand:SI 1 "gpr_operand" "%0,e")
		(match_operand:SI 2 "arith32_operand" "e,i")))]
  ""
  "#"
  [(set_attr "type" "long,long")
   (set_attr "length" "2,4")])

(define_split
  [(set (match_operand:SI 0 "gpr_operand" "")
	(xor:SI (match_operand:SI 1 "gpr_operand" "")
		(match_operand:SI 2 "arith32_operand" "")))]
  "reload_completed"
  [(match_dup 3)]
  "operands[3] = d10v_split_logical_op (operands, XOR);")

(define_insn "xordi3"
  [(set (match_operand:DI 0 "gpr_operand" "=e,e,e")
	(xor:DI (match_operand:DI 1 "gpr_operand" "0,0,?e")
		(match_operand:DI 2 "arith64_operand" "e,nF,nF")))]
  ""
  "#"
  [(set_attr "type" "long")
   (set_attr "length" "4,8,8")])

(define_split
  [(set (match_operand:DI 0 "gpr_operand" "")
	(xor:DI (match_operand:DI 1 "gpr_operand" "")
		(match_operand:DI 2 "arith64_operand" "")))]
  "reload_completed"
  [(match_dup 3)]
  "operands[3] = d10v_split_logical_op (operands, XOR);")

(define_insn "one_cmplhi2"
  [(set (match_operand:HI 0 "gpr_operand" "=d")
	(not:HI (match_operand:HI 1 "gpr_operand" "0")))]
  ""
  "not %0"
  [(set_attr "type" "either")
   (set_attr "length" "1")])

(define_insn "one_cmplsi2"
  [(set (match_operand:SI 0 "gpr_operand" "=e")
	(not:SI (match_operand:SI 1 "gpr_operand" "0")))]
  ""
  "#"
  [(set_attr "type" "long")
   (set_attr "length" "2")])

(define_split
  [(set (match_operand:SI 0 "gpr_operand" "")
	(not:SI (match_operand:SI 1 "gpr_operand" "")))]
  "reload_completed"
  [(match_dup 2)]
  "operands[2] = d10v_split_logical_op (operands, NOT);")

(define_insn "one_cmpldi2"
  [(set (match_operand:DI 0 "gpr_operand" "=e")
	(not:DI (match_operand:DI 1 "gpr_operand" "0")))]
  ""
  "#"
  [(set_attr "type" "long")
   (set_attr "length" "4")])

(define_split
  [(set (match_operand:DI 0 "gpr_operand" "")
	(not:DI (match_operand:SI 1 "gpr_operand" "")))]
  "reload_completed"
  [(match_dup 2)]
  "operands[2] = d10v_split_logical_op (operands, NOT);")


;;
;;  ....................
;;
;;	Shifts
;;
;;  ....................

(define_expand "ashlhi3"
  [(set (match_operand:HI 0 "gpr_operand" "")
	(ashift:HI (match_operand:HI 1 "gpr_operand" "")
		   (match_operand:HI 2 "arith16_operand" "")))]
  ""
  "
{
  if (GET_CODE (operands[2]) == CONST_INT && !IN_RANGE_P (INTVAL (operands[2]), 0, 15))
    operands[2] = force_reg (HImode, operands[2]);
}")

(define_insn "*ashlhi3_internal"
  [(set (match_operand:HI 0 "gpr_operand" "=d,d,d")
	(ashift:HI (match_operand:HI 1 "gpr_operand" "0,0,0")
		   (match_operand:HI 2 "arith16_operand" "I,O,d")))]
  "GET_CODE (operands[2]) != CONST_INT || IN_RANGE_P (INTVAL (operands[2]), 0, 15)"
  "@
   slli %0,%2
   nop
   sll %0,%2"
  [(set_attr "type" "iu,either,iu")
   (set_attr "length" "1,1,1")])

(define_expand "ashlsi3"
  [(set (match_operand:SI 0 "register_operand" "")
	(ashift:SI (match_operand:SI 1 "register_operand" "")
		   (match_operand:HI 2 "arith16_operand" "")))]
  ""
  "
{
  if (!TARGET_ACCUM && (GET_CODE (operands[2]) != CONST_INT || INTVAL (operands[2]) != 16))
    FAIL;

  if (GET_CODE (operands[2]) == CONST_INT && ((unsigned long)INTVAL (operands[2])) > 31)
    operands[2] = force_reg (HImode, operands[2]);

  if (GET_CODE (operands[2]) != CONST_INT)
    {
      emit_insn (gen_ashlsi3_variable (operands[0], operands[1], operands[2],
				       gen_reg_rtx (HImode),
				       gen_rtx (REG, CCmode, F0_REGNUM),
				       gen_rtx (REG, HImode, GPR_ZERO_REGNUM)));
      DONE;
    }
}")

(define_insn "*ashlsi3_16"
  [(set (match_operand:SI 0 "register_operand" "=e,a")
	(ashift:SI (match_operand:SI 1 "register_operand" "e,0")
		   (const_int 16)))]
  ""
  "@
   mv %U0,%L1\;ldi %L0,0
   slli %0,16"
  [(set_attr "type" "long,long")
   (set_attr "length" "2,2")])

(define_insn "*ashlsi3_constant"
  [(set (match_operand:SI 0 "accum_operand" "=a,a,a")
	(ashift:SI (match_operand:SI 1 "accum_operand" "0,0,0")
		   (match_operand:SI 2 "const_int_operand" "I,O,n")))]
  "TARGET_ACCUM && ((unsigned HOST_WIDE_INT)INTVAL (operands[2])) <= 31"
  "*
{
  HOST_WIDE_INT shift_value = INTVAL (operands[2]);

  if (shift_value == 0)
    return \"\";

  if (shift_value <= 16)
    return \"slli %0,%2\";

  operands[3] = GEN_INT (16);
  operands[4] = GEN_INT (shift_value - 16);
  return \"slli %0,%3\;slli %0,%4\";
}"
  [(set_attr "type" "iu,either,long")
   (set_attr "length" "1,1,2")])

(define_insn "ashlsi3_variable"
  [(set (match_operand:SI 0 "accum_operand" "=a")
	(ashift:SI (match_operand:SI 1 "accum_operand" "0")
		   (match_operand:HI 2 "gpr_operand" "d")))
   (clobber (match_operand:HI 3 "gpr_operand" "=&d"))
   (clobber (match_operand:CC 4 "f0_operand" ""))
   (use (match_operand:HI 5 "gpr_operand" "d"))
   (use (const_int 0))]
  "TARGET_ACCUM"
  "#"
  [(set_attr "type" "long")
   (set_attr "length" "10")])

(define_insn "*ashlsi3_variable2"
  [(set (match_operand:SI 0 "accum_operand" "=a")
	(ashift:SI (match_operand:SI 1 "accum_operand" "0")
		   (match_operand:HI 2 "gpr_operand" "d")))
   (use (const_int 1))]
  "TARGET_ACCUM"
  "sll %0,%2"
  [(set_attr "type" "long")
   (set_attr "length" "1")])

(define_split
  [(set (match_operand:SI 0 "accum_operand" "")
	(ashift:SI (match_operand:SI 1 "accum_operand" "")
		   (match_operand:HI 2 "gpr_operand" "")))
   (clobber (match_operand:HI 3 "gpr_operand" ""))
   (clobber (match_operand:CC 4 "f0_operand" ""))
   (use (match_operand:HI 5 "gpr_operand" ""))
   (use (const_int 0))]
  "TARGET_ACCUM && reload_completed"
  [(set (match_dup 3)
	(and:HI (match_dup 2)
		(const_int 15)))
   (parallel [(set (match_dup 0)
		   (ashift:SI (match_dup 0)
			      (match_dup 3)))
	      (use (const_int 1))])
   (set (match_dup 3)
	(plus:HI (match_dup 2)
		 (const_int -15)))
   (parallel [(set (match_dup 3)
		   (smax:HI (match_dup 3)
			    (match_dup 5)))
	      (clobber (match_dup 4))])
   (parallel [(set (match_dup 0)
		   (ashift:SI (match_dup 0)
			      (match_dup 3)))
	      (use (const_int 1))])]
  "")

(define_expand "ashrhi3"
  [(set (match_operand:HI 0 "gpr_operand" "")
	(ashiftrt:HI (match_operand:HI 1 "gpr_operand" "")
		     (match_operand:HI 2 "arith16_operand" "")))]
  ""
  "
{
  if (GET_CODE (operands[2]) == CONST_INT && !IN_RANGE_P (INTVAL (operands[2]), 0, 15))
    operands[2] = force_reg (HImode, operands[2]);
}")

(define_insn "*ashrhi3_internal"
  [(set (match_operand:HI 0 "gpr_operand" "=d,d,d")
	(ashiftrt:HI (match_operand:HI 1 "gpr_operand" "0,0,0")
		     (match_operand:HI 2 "arith16_operand" "I,O,d")))]
  "GET_CODE (operands[2]) != CONST_INT || IN_RANGE_P (INTVAL (operands[2]), 0, 15)"
  "@
   srai %0,%2
   nop
   sra %0,%2"
  [(set_attr "type" "iu,either,iu")
   (set_attr "length" "1,1,1")])

(define_expand "ashrsi3"
  [(set (match_operand:SI 0 "register_operand" "")
	(ashiftrt:SI (match_operand:SI 1 "register_operand" "")
		     (match_operand:HI 2 "arith16_operand" "")))]
  ""
  "
{
  if (!TARGET_ACCUM && (GET_CODE (operands[2]) != CONST_INT || INTVAL (operands[2]) != 16))
    FAIL;

  if (GET_CODE (operands[2]) == CONST_INT && ((unsigned long)INTVAL (operands[2])) > 31)
    operands[2] = force_reg (HImode, operands[2]);

  if (GET_CODE (operands[2]) != CONST_INT)
    {
      emit_insn (gen_ashrsi3_variable (operands[0], operands[1], operands[2],
				       gen_reg_rtx (HImode),
				       gen_rtx (REG, CCmode, F0_REGNUM),
				       gen_rtx (REG, HImode, GPR_ZERO_REGNUM)));
      DONE;
    }
}")

(define_insn "*ashrsi3_16"
  [(set (match_operand:SI 0 "register_operand" "=e,e,a")
	(ashiftrt:SI (match_operand:SI 1 "register_operand" "0,e,0")
		     (const_int 16)))]
  ""
  "@
   mv %L0,%U1\;srai %U0,15
   mv %L0,%U1\;mv %U0,%U1\;srai %U0,15
   srai %0,16"
  [(set_attr "type" "long,long,long")
   (set_attr "length" "2,3,2")])

(define_insn "*ashrsi3_constant"
  [(set (match_operand:SI 0 "accum_operand" "=a,a,a")
	(ashiftrt:SI (match_operand:SI 1 "accum_operand" "0,0,0")
		     (match_operand:SI 2 "const_int_operand" "I,O,n")))]
  "TARGET_ACCUM && ((unsigned HOST_WIDE_INT)INTVAL (operands[2])) <= 31"
  "*
{
  HOST_WIDE_INT shift_value = INTVAL (operands[2]);

  if (shift_value == 0)
    return \"\";

  if (shift_value <= 16)
    return \"srai %0,%2\";

  operands[3] = GEN_INT (16);
  operands[4] = GEN_INT (shift_value - 16);
  return \"srai %0,%3\;srai %0,%4\";
}"
  [(set_attr "type" "iu,either,long")
   (set_attr "length" "1,1,2")])

(define_insn "ashrsi3_variable"
  [(set (match_operand:SI 0 "accum_operand" "=a")
	(ashiftrt:SI (match_operand:SI 1 "accum_operand" "0")
		     (match_operand:HI 2 "gpr_operand" "d")))
   (clobber (match_operand:HI 3 "gpr_operand" "=&d"))
   (clobber (match_operand:CC 4 "f0_operand" ""))
   (use (match_operand:HI 5 "gpr_operand" "d"))
   (use (const_int 0))]
  "TARGET_ACCUM"
  "#"
  [(set_attr "type" "long")
   (set_attr "length" "10")])

(define_insn "*ashrsi3_variable2"
  [(set (match_operand:SI 0 "accum_operand" "=a")
	(ashiftrt:SI (match_operand:SI 1 "accum_operand" "0")
		     (match_operand:HI 2 "gpr_operand" "d")))
   (use (const_int 1))]
  "TARGET_ACCUM"
  "sra %0,%2"
  [(set_attr "type" "long")
   (set_attr "length" "1")])

(define_split
  [(set (match_operand:SI 0 "accum_operand" "")
	(ashiftrt:SI (match_operand:SI 1 "accum_operand" "")
		     (match_operand:HI 2 "gpr_operand" "")))
   (clobber (match_operand:HI 3 "gpr_operand" ""))
   (clobber (match_operand:CC 4 "f0_operand" ""))
   (use (match_operand:HI 5 "gpr_operand" ""))
   (use (const_int 0))]
  "TARGET_ACCUM && reload_completed"
  [(set (match_dup 3)
	(and:HI (match_dup 2)
		(const_int 15)))
   (parallel [(set (match_dup 0)
		   (ashiftrt:SI (match_dup 0)
				(match_dup 3)))
	      (use (const_int 1))])
   (set (match_dup 3)
	(plus:HI (match_dup 2)
		 (const_int -15)))
   (parallel [(set (match_dup 3)
		   (smax:HI (match_dup 3)
			    (match_dup 5)))
	      (clobber (match_dup 4))])
   (parallel [(set (match_dup 0)
		   (ashiftrt:SI (match_dup 0)
				(match_dup 3)))
	      (use (const_int 1))])]
  "")

(define_expand "lshrhi3"
  [(set (match_operand:HI 0 "gpr_operand" "")
	(lshiftrt:HI (match_operand:HI 1 "gpr_operand" "")
		     (match_operand:HI 2 "arith16_operand" "")))]
  ""
  "
{
  if (GET_CODE (operands[2]) == CONST_INT && !IN_RANGE_P (INTVAL (operands[2]), 0, 15))
    operands[2] = force_reg (HImode, operands[2]);
}")

(define_insn "*lshrhi3_internal"
  [(set (match_operand:HI 0 "gpr_operand" "=d,d,d")
	(lshiftrt:HI (match_operand:HI 1 "gpr_operand" "0,0,0")
		     (match_operand:HI 2 "arith16_operand" "I,O,d")))]
  "GET_CODE (operands[2]) != CONST_INT || IN_RANGE_P (INTVAL (operands[2]), 0, 15)"
  "@
   srli %0,%2
   nop
   srl %0,%2"
  [(set_attr "type" "iu,either,iu")
   (set_attr "length" "1,1,1")])

(define_expand "lshrsi3"
  [(set (match_operand:SI 0 "register_operand" "")
	(lshiftrt:SI (match_operand:SI 1 "register_operand" "")
		     (match_operand:HI 2 "arith16_operand" "")))]
  ""
  "
{
  if (!TARGET_ACCUM && (GET_CODE (operands[2]) != CONST_INT || INTVAL (operands[2]) != 16))
    FAIL;

  if (GET_CODE (operands[2]) == CONST_INT && ((unsigned long)INTVAL (operands[2])) > 31)
    operands[2] = force_reg (HImode, operands[2]);

  if (GET_CODE (operands[2]) != CONST_INT)
    {
      emit_insn (gen_lshrsi3_variable (operands[0], operands[1], operands[2],
				       gen_reg_rtx (HImode),
				       gen_rtx (REG, CCmode, F0_REGNUM),
				       gen_rtx (REG, HImode, GPR_ZERO_REGNUM)));
      DONE;
    }
}")

(define_insn "*lshlsi3_16"
  [(set (match_operand:SI 0 "register_operand" "=e,a")
	(lshiftrt:SI (match_operand:SI 1 "register_operand" "e,0")
		     (const_int 16)))]
  ""
  "@
   mv %L0,%U1\;ldi %U0,0
   srli %0,16"
  [(set_attr "type" "long,long")
   (set_attr "length" "2,2")])

(define_insn "*lshlsi3_constant"
  [(set (match_operand:SI 0 "accum_operand" "=a,a,a")
	(lshiftrt:SI (match_operand:SI 1 "accum_operand" "0,0,0")
		     (match_operand:SI 2 "const_int_operand" "I,O,n")))]
  "TARGET_ACCUM && ((unsigned HOST_WIDE_INT)INTVAL (operands[2])) <= 31"
  "*
{
  HOST_WIDE_INT shift_value = INTVAL (operands[2]);

  if (shift_value == 0)
    return \"\";

  if (shift_value <= 16)
    return \"srli %0,%2\";

  operands[3] = GEN_INT (16);
  operands[4] = GEN_INT (shift_value - 16);
  return \"srli %0,%3\;srli %0,%4\";
}"
  [(set_attr "type" "iu,either,long")
   (set_attr "length" "1,1,2")])

(define_insn "lshrsi3_variable"
  [(set (match_operand:SI 0 "accum_operand" "=a")
	(lshiftrt:SI (match_operand:SI 1 "accum_operand" "0")
		     (match_operand:HI 2 "gpr_operand" "d")))
   (clobber (match_operand:HI 3 "gpr_operand" "=&d"))
   (clobber (match_operand:CC 4 "f0_operand" ""))
   (use (match_operand:HI 5 "gpr_operand" "d"))
   (use (const_int 0))]
  "TARGET_ACCUM"
  "#"
  [(set_attr "type" "long")
   (set_attr "length" "10")])

(define_insn "*lshrsi3_variable2"
  [(set (match_operand:SI 0 "accum_operand" "=a")
	(lshiftrt:SI (match_operand:SI 1 "accum_operand" "0")
		     (match_operand:HI 2 "gpr_operand" "d")))
   (use (const_int 1))]
  "TARGET_ACCUM"
  "srl %0,%2"
  [(set_attr "type" "long")
   (set_attr "length" "1")])

(define_split
  [(set (match_operand:SI 0 "accum_operand" "")
	(lshiftrt:SI (match_operand:SI 1 "accum_operand" "")
		     (match_operand:HI 2 "gpr_operand" "")))
   (clobber (match_operand:HI 3 "gpr_operand" ""))
   (clobber (match_operand:CC 4 "f0_operand" ""))
   (use (match_operand:HI 5 "gpr_operand" ""))
   (use (const_int 0))]
  "TARGET_ACCUM && reload_completed"
  [(set (match_dup 3)
	(and:HI (match_dup 2)
		(const_int 15)))
   (parallel [(set (match_dup 0)
		   (lshiftrt:SI (match_dup 0)
				(match_dup 3)))
	      (use (const_int 1))])
   (set (match_dup 3)
	(plus:HI (match_dup 2)
		 (const_int -15)))
   (parallel [(set (match_dup 3)
		   (smax:HI (match_dup 3)
			    (match_dup 5)))
	      (clobber (match_dup 4))])
   (parallel [(set (match_dup 0)
		   (lshiftrt:SI (match_dup 0)
				(match_dup 3)))
	      (use (const_int 1))])]
  "")


;;
;;  ....................
;;
;;	Min/max/abs
;;
;;  ....................

(define_expand "sminhi3"
  [(parallel [(set (match_operand:HI 0 "gpr_operand" "")
		   (smin:HI (match_operand:HI 1 "gpr_operand" "")
			    (match_operand:HI 2 "reg_or_0_operand" "")))
	      (clobber (match_dup 3))])]
  ""
  "operands[3] = gen_rtx (REG, CCmode, F0_REGNUM);")

(define_insn "*sminhi3_internal"
  [(set (match_operand:HI 0 "gpr_operand" "=d,d")
	(smin:HI (match_operand:HI 1 "gpr_operand" "%0,0")
		 (match_operand:HI 2 "reg_or_0_operand" "d,O")))
   (clobber (match_operand:CC 3 "f0_operand" ""))]
  ""
  "@
   min %0,%2
   min %0,%."
  [(set_attr "type" "iu,iu")
   (set_attr "length" "1,1")])

(define_expand "sminsi3"
  [(parallel [(set (match_operand:SI 0 "gpr_operand" "")
		   (smin:SI (match_operand:SI 1 "gpr_operand" "")
			    (match_operand:SI 2 "gpr_operand" "")))
	      (clobber (match_dup 3))])]
  "TARGET_ACCUM"
  "operands[3] = gen_rtx (REG, CCmode, F0_REGNUM);")

(define_insn "*sminsi3_internal"
  [(set (match_operand:SI 0 "gpr_operand" "=a")
	(smin:SI (match_operand:SI 1 "gpr_operand" "%0")
		 (match_operand:SI 2 "gpr_operand" "ad")))
   (clobber (match_operand:CC 3 "f0_operand" ""))]
  "TARGET_ACCUM"
  "min %0,%2"
  [(set_attr "type" "iu")
   (set_attr "length" "1")])

(define_expand "smaxhi3"
  [(parallel [(set (match_operand:HI 0 "gpr_operand" "")
		   (smax:HI (match_operand:HI 1 "gpr_operand" "")
			    (match_operand:HI 2 "reg_or_0_operand" "")))
	      (clobber (match_dup 3))])]
  ""
  "operands[3] = gen_rtx (REG, CCmode, F0_REGNUM);")

(define_insn "*smaxhi3_internal"
  [(set (match_operand:HI 0 "gpr_operand" "=d,d")
	(smax:HI (match_operand:HI 1 "gpr_operand" "%0,0")
		 (match_operand:HI 2 "reg_or_0_operand" "d,O")))
   (clobber (match_operand:CC 3 "f0_operand" ""))]
  ""
  "@
   max %0,%2
   max %0,%."
  [(set_attr "type" "iu,iu")
   (set_attr "length" "1,1")])

(define_expand "smaxsi3"
  [(parallel [(set (match_operand:SI 0 "register_operand" "")
		   (smax:SI (match_operand:SI 1 "register_operand" "")
			    (match_operand:SI 2 "register_operand" "")))
	      (clobber (match_dup 3))])]
  "TARGET_ACCUM"
  "operands[3] = gen_rtx (REG, CCmode, F0_REGNUM);")

(define_insn "*smaxsi3_internal"
  [(set (match_operand:SI 0 "accum_operand" "=a")
	(smax:SI (match_operand:SI 1 "register_operand" "%0")
		 (match_operand:SI 2 "register_operand" "ad")))
   (clobber (match_operand:CC 3 "f0_operand" ""))]
  "TARGET_ACCUM"
  "max %0,%2"
  [(set_attr "type" "iu")
   (set_attr "length" "1")])

(define_expand "abshi2"
  [(parallel [(set (match_operand:HI 0 "gpr_operand" "")
		   (abs:HI (match_operand:HI 1 "gpr_operand" "")))
	      (clobber (match_dup 3))])]
  ""
  "operands[3] = gen_rtx (REG, CCmode, F0_REGNUM);")

(define_insn "*abshi2_internal"
  [(set (match_operand:HI 0 "gpr_operand" "=d")
	(abs:HI (match_operand:HI 1 "gpr_operand" "0")))
   (clobber (match_operand:CC 3 "f0_operand" ""))]
  ""
  "abs %0"
  [(set_attr "type" "either")
   (set_attr "length" "1")])

(define_expand "abssi2"
  [(parallel [(set (match_operand:SI 0 "register_operand" "")
		   (abs:SI (match_operand:SI 1 "register_operand" "")))
	      (clobber (match_dup 3))])]
  "TARGET_ACCUM"
  "operands[3] = gen_rtx (REG, CCmode, F0_REGNUM);")

(define_insn "*abssi2_internal"
  [(set (match_operand:SI 0 "accum_operand" "=a")
	(abs:SI (match_operand:SI 1 "register_operand" "0")))
   (clobber (match_operand:CC 3 "f0_operand" ""))]
  "TARGET_ACCUM"
  "abs %0"
  [(set_attr "type" "iu")
   (set_attr "length" "1")])


;;
;;  ....................
;;
;;	Peepholes
;;
;;  ....................

(define_peephole
  [(set (match_operand:HI 0 "gpr_operand" "=e") (match_operand:HI 1 "gpr_operand" "e"))
   (set (match_operand:HI 2 "gpr_operand" "=d") (match_operand:HI 3 "gpr_operand" "d"))]
  "((REGNO (operands[0]) & 1) == 0 && (REGNO (operands[2]) == REGNO (operands[0]) + 1)
    && (REGNO (operands[1]) & 1) == 0 && (REGNO (operands[3]) == REGNO (operands[1]) + 1))"
  "mv2w %0,%1"
  [(set_attr "type" "iu")
   (set_attr "length" "1")])

(define_peephole
  [(set (match_operand:HI 0 "gpr_operand" "=d") (match_operand:HI 1 "gpr_operand" "d"))
   (set (match_operand:HI 2 "gpr_operand" "=e") (match_operand:HI 3 "gpr_operand" "e"))]
  "((REGNO (operands[2]) & 1) == 0 && (REGNO (operands[2]) == REGNO (operands[0]) - 1)
    && (REGNO (operands[3]) & 1) == 0 && (REGNO (operands[3]) == REGNO (operands[1]) - 1))"
  "mv2w %2,%3"
  [(set_attr "type" "iu")
   (set_attr "length" "1")])

(define_peephole
  [(set (match_operand:HI 0 "gpr_operand" "=e,e") (match_operand:HI 1 "memory_operand" "Q,m"))
   (set (match_operand:HI 2 "gpr_operand" "=d,d") (match_operand:HI 3 "memory_operand" "Q,m"))]
  "((REGNO (operands[0]) & 1) == 0 && (REGNO (operands[2]) == REGNO (operands[0]) + 1)
   && adjacent_memory_operands (operands[1], operands[3], insn)
   && !reg_mentioned_p (operands[0], operands[3]))"
  "ld2w %0,%M1"
  [(set_attr "type" "mu,mu")
   (set_attr "length" "1,2")])

(define_peephole
  [(set (match_operand:HI 0 "gpr_operand" "=d,d") (match_operand:HI 1 "memory_operand" "Q,m"))
   (set (match_operand:HI 2 "gpr_operand" "=e,e") (match_operand:HI 3 "memory_operand" "Q,m"))]
  "((REGNO (operands[2]) & 1) == 0 && (REGNO (operands[2]) == REGNO (operands[0]) - 1)
   && adjacent_memory_operands (operands[3], operands[1], insn)
   && !reg_mentioned_p (operands[0], operands[3]))"
  "ld2w %2,%M3"
  [(set_attr "type" "mu,mu")
   (set_attr "length" "1,2")])

(define_peephole
  [(set (match_operand:HI 0 "memory_operand" "=Q,m") (match_operand:HI 1 "gpr_operand" "e,e"))
   (set (match_operand:HI 2 "memory_operand" "=Q,m") (match_operand:HI 3 "gpr_operand" "d,d"))]
  "((REGNO (operands[1]) & 1) == 0 && (REGNO (operands[3]) == REGNO (operands[1]) + 1)
   && adjacent_memory_operands (operands[0], operands[2], insn))"
  "st2w %1,%M0"
  [(set_attr "type" "mu,mu")
   (set_attr "length" "1,2")])

(define_peephole
  [(set (match_operand:HI 0 "memory_operand" "=Q,m") (match_operand:HI 1 "gpr_operand" "d,d"))
   (set (match_operand:HI 2 "memory_operand" "=Q,m") (match_operand:HI 3 "gpr_operand" "e,e"))]
  "((REGNO (operands[3]) & 1) == 0 && (REGNO (operands[3]) == REGNO (operands[1]) - 1)
   && adjacent_memory_operands (operands[2], operands[0], insn))"
  "st2w %3,%M2"
  [(set_attr "type" "mu,mu")
   (set_attr "length" "1,2")])

;; Peepholes for tst0i, tst1i, and btsti instructions
(define_peephole
  [(set (match_operand:HI 0 "gpr_operand" "=d")
	(and:HI (match_operand:HI 1 "gpr_operand" "d")
		(match_operand:HI 2 "const_int_operand" "n")))
   (set (match_operand:CC_REV 3 "f0_operand" "")
	(ne:CC_REV (match_dup 0)
		   (const_int 0)))
   (set (pc)
	(if_then_else (match_operator:CC 4 "f0_compare_operator"
					 [(match_dup 3)
					  (const_int 0)])
		      (match_operand 5 "pc_or_label_operand" "")
		      (match_operand 6 "pc_or_label_operand" "")))]
  "IN_RANGE_P (exact_log2 (INTVAL (operands[2])), 0, 15)
   && find_regno_note (prev_nonnote_insn (insn), REG_DEAD, REGNO (operands[0]))
   && find_regno_note (insn, REG_DEAD, F0_REGNUM)"
  "*
{
  operands[7] = GEN_INT (15 - exact_log2 (INTVAL (operands[2])));
  output_asm_insn (\"btsti %1,%7\", operands);

  if (operands[5] == pc_rtx)
    return (GET_CODE (operands[6]) == RETURN) ? \"jmp r13 || exef0%T4\" : \"brf0%F4 %l6\";
  else
    return (GET_CODE (operands[5]) == RETURN) ? \"jmp r13 || exef0%F4\" : \"brf0%T4 %l5\";
}"
  [(set_attr "type" "long")
   (set_attr "length" "4")])

(define_peephole
  [(set (match_operand:HI 0 "gpr_operand" "=d")
	(and:HI (not:HI (match_operand:HI 1 "gpr_operand" "d"))
		(match_operand:HI 2 "const_int_operand" "n")))
   (set (match_operand:CC_REV 3 "f0_operand" "")
	(ne:CC (match_dup 0)
	       (const_int 0)))]
  "find_regno_note (insn, REG_DEAD, REGNO (operands[0]))"
  "tst1i %1,%2"
  [(set_attr "type" "long")
   (set_attr "length" "2")])

(define_peephole
  [(set (match_operand:HI 0 "gpr_operand" "=d")
	(and:HI (match_operand:HI 1 "gpr_operand" "d")
		(match_operand:HI 2 "const_int_operand" "n")))
   (set (match_operand:CC 3 "f0_operand" "")
	(eq:CC_REV (match_dup 0)
		   (const_int 0)))]
  "IN_RANGE_P (exact_log2 (INTVAL (operands[2])), 0, 15)
   && find_regno_note (insn, REG_DEAD, REGNO (operands[0]))"
  "*
{
  operands[4] = GEN_INT (15 - exact_log2 (INTVAL (operands[2])));
  return \"btsti %1,%4\";
}"
  [(set_attr "type" "iu")
   (set_attr "length" "1")])

(define_peephole
  [(set (match_operand:HI 0 "gpr_operand" "=d")
	(and:HI (match_operand:HI 1 "gpr_operand" "d")
		(match_operand:HI 2 "const_int_operand" "n")))
   (set (match_operand:CC 3 "f0_operand" "")
	(eq:CC_REV (match_dup 0)
		   (const_int 0)))]
  "!IN_RANGE_P (exact_log2 (INTVAL (operands[2])), 0, 15)
   && find_regno_note (insn, REG_DEAD, REGNO (operands[0]))"
  "tst0i %1,%2"
  [(set_attr "type" "long")
   (set_attr "length" "2")])
;; END CYGNUS LOCAL -- meissner/d10v abi change
