;;- Machine description for GNU compiler -- System/370 version.
;;   Copyright (C) 1989, 1993 Free Software Foundation, Inc.
;;   Contributed by Jan Stein (jan@cd.chalmers.se).
;;   Modifed for MVS C/370 by Dave Pitts (pitts@mcdata.com)

;; This file is part of GNU CC.

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

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

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

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

;;
;; Special constraints for 370 machine description:
;;
;;    a -- Any address register from 1 to 15.
;;    d -- Any register from 0 to 15.
;;    I -- An 8-bit constant (0..255).
;;    J -- A 12-bit constant (0..4095).
;;    K -- A 16-bit constant (-32768..32767).
;;
;; Special formats used for outputting 370 instructions.
;;
;;   %B -- Print a constant byte integer.
;;   %H -- Print a signed 16-bit constant.
;;   %L -- Print least significant word of a CONST_DOUBLE.
;;   %M -- Print most significant word of a CONST_DOUBLE.
;;   %N -- Print next register (second word of a DImode reg).
;;   %O -- Print the offset of a memory reference (PLUS (REG) (CONST_INT)).
;;   %R -- Print the register of a memory reference (PLUS (REG) (CONST_INT)).
;;   %X -- Print a constant byte integer in hex.
;;
;; We have a special contraint for pattern matching.
;;
;;   s_operand -- Matches a valid S operand in a RS, SI or SS type instruction.
;;
;;   r_or_s_operand -- Matches a register or a valid S operand in a RS, SI
;;		       or SS type instruction or a register
;;
;; For MVS C/370 we use the following stack locations for:
;;
;;   136 - internal function result buffer
;;   140 - numeric conversion buffer
;;   144 - pointer to internal function result buffer
;;   148 - start of automatic variables and function arguments
;;
;; To support programs larger than a page, 4096 bytes, PAGE_REGISTER points
;; to a page origin table, all internal labels are generated to reload the
;; BASE_REGISTER knowing what page it is on and all branch instructions go
;; directly to the target if it is known that the target is on the current
;; page (essentially backward references).  All forward references and off
;; page references are handled by loading the address of target into a
;; register and branching indirectly.
;;
;; Some *di patterns have been commented out per advice from RMS, as gcc
;; will generate the right things to do.
;;

;;
;;- Test instructions.
;;

;
; tstdi instruction pattern(s).
;

(define_insn "tstdi"
  [(set (cc0)
	(match_operand:DI 0 "register_operand" "d"))]
  ""
  "*
{
  check_label_emit ();
  mvs_check_page (0, 4, 0);
  return \"SRDA	%0,0\";
}")

;
; tstsi instruction pattern(s).
;

(define_insn "tstsi"
  [(set (cc0)
	(match_operand:SI 0 "register_operand" "d"))]
  ""
  "*
{
  check_label_emit ();
  mvs_check_page (0, 2, 0);
  return \"LTR	%0,%0\";
}")

;
; tsthi instruction pattern(s).
;

(define_insn "tsthi"
  [(set (cc0)
	(match_operand:HI 0 "register_operand" "d"))]
  ""
  "*
{
  check_label_emit ();
  mvs_check_page (0, 4, 2);
  return \"CH	%0,=H'0'\";
}")

;
; tstqi instruction pattern(s).
;

(define_insn ""
  [(set (cc0)
	(match_operand:QI 0 "r_or_s_operand" "dm"))]
  "unsigned_jump_follows_p (insn)"
  "*
{
  check_label_emit ();
  if (REG_P (operands[0]))
    {
      mvs_check_page (0, 4, 4);
      return \"N	%0,=X'000000FF'\";
    }
  mvs_check_page (0, 4, 0);
  return \"CLI	%0,0\";
}")

(define_insn "tstqi"
  [(set (cc0)
     (match_operand:QI 0 "register_operand" "d"))]
  ""
  "*
{
  check_label_emit ();
  if (unsigned_jump_follows_p (insn))
    {
      mvs_check_page (0, 4, 4);
      return \"N	%0,=X'000000FF'\";
    }
  mvs_check_page (0, 8, 0);
  return \"SLL	%0,24\;SRA	%0,24\";
}")

;
; tstdf instruction pattern(s).
;

(define_insn "tstdf"
  [(set (cc0)
	(match_operand:DF 0 "general_operand" "f"))]
  ""
  "*
{
  check_label_emit ();
  mvs_check_page (0, 2, 0);
  return \"LTDR	%0,%0\";
}")

;
; tstsf instruction pattern(s).
;

(define_insn "tstsf"
  [(set (cc0)
	(match_operand:SF 0 "general_operand" "f"))]
  ""
  "*
{
  check_label_emit ();
  mvs_check_page (0, 2, 0);
  return \"LTER	%0,%0\";
}")

;;
;;- Compare instructions.
;;

;
; cmpdi instruction pattern(s).
;

;(define_insn "cmpdi"
;  [(set (cc0)
;	(compare (match_operand:DI 0 "register_operand" "d")
;		 (match_operand:DI 1 "general_operand" "")))]
;  ""
;  "*
;{
;  check_label_emit ();
;  if (REG_P (operands[1]))
;    {
;      mvs_check_page (0, 8, 0);
;      if (unsigned_jump_follows_p (insn))
;        return \"CLR	%0,%1\;BNE	*+6\;CLR	%N0,%N1\";
;      return \"CR	%0,%1\;BNE	*+6\;CLR	%N0,%N1\";
;    }
;  mvs_check_page (0, 12, 0);
;  if (unsigned_jump_follows_p (insn))
;    return \"CL	%0,%M1\;BNE	*+8\;CL	%N0,%L1\";
;  return \"C	%0,%M1\;BNE	*+8\;CL	%N0,%L1\";
;}")

;
; cmpsi instruction pattern(s).
;

(define_insn "cmpsi"
  [(set (cc0)
	(compare (match_operand:SI 0 "register_operand" "d")
		 (match_operand:SI 1 "general_operand" "")))]
  ""
  "*
{
  check_label_emit ();
  if (REG_P (operands[1]))
    {
      mvs_check_page (0, 2, 0);
      if (unsigned_jump_follows_p (insn))
	return \"CLR	%0,%1\";
      return \"CR	%0,%1\";
    }
  if (GET_CODE (operands[1]) == CONST_INT)
    {
      mvs_check_page (0, 4, 4);
      if (unsigned_jump_follows_p (insn))
	 return \"CL	%0,=F'%c1'\";
      return \"C	%0,=F'%c1'\";
    }
  mvs_check_page (0, 4, 0);
  if (unsigned_jump_follows_p (insn))
    return \"CL	%0,%1\";
  return \"C	%0,%1\";
}")

;
; cmphi instruction pattern(s).
;

(define_insn "cmphi"
  [(set (cc0)
	(compare (match_operand:HI 0 "register_operand" "d")
		 (match_operand:HI 1 "general_operand" "")))]
  ""
  "*
{
  check_label_emit ();
  if (REG_P (operands[1]))
    {
      mvs_check_page (0, 8, 0);
      if (unsigned_jump_follows_p (insn))
	return \"STH	%1,140(,13)\;CLM	%0,3,140(13)\";
      return \"STH	%1,140(,13)\;CH	%0,140(,13)\";
    }
  if (GET_CODE (operands[1]) == CONST_INT)
    {
      mvs_check_page (0, 4, 2);
      return \"CH	%0,=H'%h1'\";
    }
  mvs_check_page (0, 4, 0);
  return \"CH	%0,%1\";
}")

;
; cmpqi instruction pattern(s).
;

(define_insn ""
  [(set (cc0)
	(compare (match_operand:QI 0 "r_or_s_operand" "g")
		 (match_operand:QI 1 "r_or_s_operand" "g")))]
  "unsigned_jump_follows_p (insn)"
  "*
{
  check_label_emit ();
  if (REG_P (operands[0]))
    {
      if (REG_P (operands[1]))
	{
	  mvs_check_page (0, 8, 0);
          return \"STC	%1,140(,13)\;CLM	%0,1,140(13)\";
        }
      if (GET_CODE (operands[1]) == CONST_INT)
	{
	  mvs_check_page (0, 4, 1);
          return \"CLM	%0,1,=X'%X1'\";
        }
      mvs_check_page (0, 4, 0);
      return \"CLM	%0,1,%1\";
    }
  else if (GET_CODE (operands[0]) == CONST_INT)
    {
      cc_status.flags |= CC_REVERSED;
      if (REG_P (operands[1]))
	{
	  mvs_check_page (0, 4, 1);
          return \"CLM	%1,1,=X'%X0'\";
        }
      mvs_check_page (0, 4, 0);
      return \"CLI	%1,%B0\";
    }
  if (GET_CODE (operands[1]) == CONST_INT)
    {
      mvs_check_page (0, 4, 0);
      return \"CLI	%0,%B1\";
    }
  if (GET_CODE (operands[1]) == MEM)
    {
      mvs_check_page (0, 6, 0);
      return \"CLC	%O0(1,%R0),%1\";
    }
  cc_status.flags |= CC_REVERSED;
  mvs_check_page (0, 4, 0);
  return \"CLM	%1,1,%0\";
}")

(define_insn "cmpqi"
  [(set (cc0)
	(compare (match_operand:QI 0 "register_operand" "d")
		 (match_operand:QI 1 "general_operand" "di")))]
  ""
  "*
{
  check_label_emit ();
  if (unsigned_jump_follows_p (insn))
    {
      if (REG_P (operands[1]))
	{
	  mvs_check_page (0, 4, 0);
          return \"CLM	%0,1,%1\";
        }
      if (GET_CODE (operands[1]) == CONST_INT)
	{
	  mvs_check_page (0, 4, 1);
          return \"CLM	%0,1,=X'%X1'\";
        }
      mvs_check_page (0, 8, 0);
      return \"STC	%1,140(,13)\;CLM	%0,1,140(13)\";
    }
  if (REG_P (operands[1]))
    {
      mvs_check_page (0, 18, 0);
      return \"SLL	%0,24\;SRA	%0,24\;SLL	%1,24\;SRA	%1,24\;CR	%0,%1\";
    }
  mvs_check_page (0, 12, 0);
  return \"SLL	%0,24\;SRA	%0,24\;C	%0,%1\";
}")

;
; cmpdf instruction pattern(s).
;

(define_insn "cmpdf"
  [(set (cc0)
	(compare (match_operand:DF 0 "general_operand" "f,mF")
		 (match_operand:DF 1 "general_operand" "fmF,f")))]
  ""
  "*
{
  check_label_emit ();
  if (FP_REG_P (operands[0]))
    {
      if (FP_REG_P (operands[1]))
	{
	  mvs_check_page (0, 2, 0);
	  return \"CDR	%0,%1\";
	}
      mvs_check_page (0, 4, 0);
      return \"CD	%0,%1\";
    }
  cc_status.flags |= CC_REVERSED;
  mvs_check_page (0, 4, 0);
  return \"CD	%1,%0\";
}")

;
; cmpsf instruction pattern(s).
;

(define_insn "cmpsf"
  [(set (cc0)
	(compare (match_operand:SF 0 "general_operand" "f,mF")
		 (match_operand:SF 1 "general_operand" "fmF,f")))]
  ""
  "*
{
check_label_emit ();
  if (FP_REG_P (operands[0]))
    {
      if (FP_REG_P (operands[1]))
	{
	  mvs_check_page (0, 2, 0);
	  return \"CER	%0,%1\";
	}
      mvs_check_page (0, 4, 0);
      return \"CE	%0,%1\";
    }
  cc_status.flags |= CC_REVERSED;
  mvs_check_page (0, 4, 0);
  return \"CE	%1,%0\";
}")

;
; cmpstrsi instruction pattern(s).
;

(define_expand "cmpstrsi"
  [(set (match_operand:SI 0 "general_operand" "")
	  (compare (match_operand:BLK 1 "general_operand" "")
		   (match_operand:BLK 2 "general_operand" "")))
     (use (match_operand:SI 3 "general_operand" ""))
     (use (match_operand:SI 4 "" ""))]
   ""
   "
{
  rtx op1, op2;

  op1 = XEXP (operands[1], 0);
  if (GET_CODE (op1) == REG
      || (GET_CODE (op1) == PLUS && GET_CODE (XEXP (op1, 0)) == REG
	  && GET_CODE (XEXP (op1, 1)) == CONST_INT
	  && (unsigned) INTVAL (XEXP (op1, 1)) < 4096))
    {
      op1 = operands[1];
    }
  else
    {
      op1 = gen_rtx (MEM, BLKmode, copy_to_mode_reg (SImode, op1));
    }

  op2 = XEXP (operands[2], 0);
  if (GET_CODE (op2) == REG
      || (GET_CODE (op2) == PLUS && GET_CODE (XEXP (op2, 0)) == REG
	  && GET_CODE (XEXP (op2, 1)) == CONST_INT
	  && (unsigned) INTVAL (XEXP (op2, 1)) < 4096))
    {
      op2 = operands[2];
    }
  else
    {
      op2 = gen_rtx (MEM, BLKmode, copy_to_mode_reg (SImode, op2));
    }
      
  if (GET_CODE (operands[3]) == CONST_INT && INTVAL (operands[3]) < 256)
    {
      emit_insn (gen_rtx (PARALLEL, VOIDmode, gen_rtvec (2,
		gen_rtx (SET, VOIDmode, operands[0], 
			gen_rtx (COMPARE, VOIDmode, op1, op2)),
		gen_rtx (USE, VOIDmode, operands[3]))));
    }
  else
    {
      rtx reg1 = gen_reg_rtx (DImode);
      rtx reg2 = gen_reg_rtx (DImode);
      rtx subreg = gen_rtx (SUBREG, SImode, reg1, 1);

      emit_insn (gen_rtx (SET, VOIDmode, subreg, operands[3]));
      emit_insn (gen_rtx (SET, VOIDmode, gen_rtx (SUBREG, SImode, reg2, 1),
					    subreg));
      emit_insn (gen_rtx (PARALLEL, VOIDmode, gen_rtvec (5,
		gen_rtx (SET, VOIDmode, operands[0],
			gen_rtx (COMPARE, VOIDmode, op1, op2)),
		gen_rtx (USE, VOIDmode, reg1),
		gen_rtx (USE, VOIDmode, reg2),
		gen_rtx (CLOBBER, VOIDmode, reg1),
		gen_rtx (CLOBBER, VOIDmode, reg2))));
    }
  DONE;
}")

; Compare a block that is less than 256 bytes in length.

(define_insn ""
  [(set (match_operand:SI 0 "register_operand" "d")
	(compare (match_operand:BLK 1 "s_operand" "m")
		 (match_operand:BLK 2 "s_operand" "m")))
   (use (match_operand:QI 3 "immediate_operand" "I"))]
  "((unsigned) INTVAL (operands[3]) < 256)"
  "*
{
  check_label_emit ();
  mvs_check_page (0, 22, 0);
  return \"LA	%0,1\;CLC	%O1(%c3,%R1),%2\;BH	*+12\;BL	*+6\;SLR	%0,%0\;LNR	%0,%0\";
}")

; Compare a block that is larger than 255 bytes in length.

(define_insn ""
  [(set (match_operand:SI 0 "register_operand" "d")
 	(compare (match_operand:BLK 1 "general_operand" "m")
		 (match_operand:BLK 2 "general_operand" "m")))
   (use (match_operand:DI 3 "register_operand" "d"))
   (use (match_operand:DI 4 "register_operand" "d"))
   (clobber (match_dup 3))
   (clobber (match_dup 4))]
  ""
  "*
{
  check_label_emit ();
  mvs_check_page (0, 26, 0);
  return \"LA	%3,%1\;LA	%4,%2\;LA	%0,1\;CLCL	%3,%4\;BH	*+12\;BL	*+6\;SLR	%0,%0\;LNR	%0,%0\";
}")

;;
;;- Move instructions.
;;

;
; movdi instruction pattern(s).
;

(define_insn ""
  [(set (match_operand:DI 0 "r_or_s_operand" "=dm")
        (match_operand:DI 1 "r_or_s_operand" "dim*fF"))]
  "TARGET_CHAR_INSTRUCTIONS"
  "*
{
  check_label_emit ();
  if (REG_P (operands[0]))
    {
      if (FP_REG_P (operands[1]))
	{
	  mvs_check_page (0, 8, 0);
	  return \"STD	%1,140(,13)\;LM	%0,%N0,140(13)\";
	}
      if (REG_P (operands[1]))
	{
	  mvs_check_page (0, 4, 0);
	  return \"LR	%0,%1\;LR	%N0,%N1\";
	}
      if (operands[1] == const0_rtx)
	{
	  CC_STATUS_INIT;
	  mvs_check_page (0, 4, 0);
	  return \"SLR	%0,%0\;SLR	%N0,%N0\";
	}
      if (GET_CODE (operands[1]) == CONST_INT
  	  && (unsigned) INTVAL (operands[1]) < 4096)
	{
	  CC_STATUS_INIT;
	  mvs_check_page (0, 6, 0);
	  return \"SLR	%0,%0\;LA	%N0,%c1\";
	}
      if (GET_CODE (operands[1]) == CONST_INT)
	{
	  CC_STATUS_SET (operands[0], operands[1]);
	  mvs_check_page (0, 8, 0);
	  return \"L	%0,%1\;SRDA	%0,32\";
	}
      mvs_check_page (0, 4, 0);
      return \"LM	%0,%N0,%1\";
    }
  else if (FP_REG_P (operands[1]))
    {
      mvs_check_page (0, 4, 0);
      return \"STD	%1,%0\";
    }
  else if (REG_P (operands[1]))
    {
      mvs_check_page (0, 4, 0);
      return \"STM	%1,%N1,%0\";
    }
  mvs_check_page (0, 6, 0);
  return \"MVC	%O0(8,%R0),%1\";
}")

(define_insn "movdi"
  [(set (match_operand:DI 0 "general_operand" "=dm")
	(match_operand:DI 1 "general_operand" "dim*fF"))]
  ""
  "*
{
  check_label_emit ();
  if (REG_P (operands[0]))
    {
      if (FP_REG_P (operands[1]))
	{
	  mvs_check_page (0, 8, 0);
	  return \"STD	%1,140(,13)\;LM	%0,%N0,140(13)\";
	}
      if (REG_P (operands[1]))
	{
	  mvs_check_page (0, 4, 0);
	  return \"LR	%0,%1\;LR	%N0,%N1\";
	}
      if (operands[1] == const0_rtx)
	{
	  CC_STATUS_INIT;
	  mvs_check_page (0, 4, 0);
	  return \"SLR	%0,%0\;SLR	%N0,%N0\";
	}
      if (GET_CODE (operands[1]) == CONST_INT
  	  && (unsigned) INTVAL (operands[1]) < 4096)
	{
	  CC_STATUS_INIT;
	  mvs_check_page (0, 6, 0);
	  return \"SLR	%0,%0\;LA	%N0,%c1\";
	}
      if (GET_CODE (operands[1]) == CONST_INT)
	{
	  CC_STATUS_SET (operands[0], operands[1]);
	  mvs_check_page (0, 8, 0);
	  return \"L	%0,%1\;SRDA	%0,32\";
	}
      mvs_check_page (0, 4, 0);
      return \"LM	%0,%N0,%1\";
    }
  else if (FP_REG_P (operands[1]))
    {
      mvs_check_page (0, 4, 0);
      return \"STD	%1,%0\";
    }
  mvs_check_page (0, 4, 0);
  return \"STM	%1,%N1,%0\";
}")

;
; movsi instruction pattern(s).
;

(define_insn ""
  [(set (match_operand:SI 0 "r_or_s_operand" "=dm,dm")
        (match_operand:SI 1 "r_or_s_operand" "dim,*fF"))]
  "TARGET_CHAR_INSTRUCTIONS"
  "*
{
  check_label_emit ();
  if (REG_P (operands[0]))
    {
      if (FP_REG_P (operands[1]))
	{
	  mvs_check_page (0, 8, 0);
	  return \"STE	%1,140(,13)\;L	%0,140(,13)\";
	}
      if (REG_P (operands[1]))
	{
	  mvs_check_page (0, 2, 0);
	  return \"LR	%0,%1\";
	}
      if (operands[1] == const0_rtx)
	{
	  CC_STATUS_INIT;
	  mvs_check_page (0, 2, 0);
	  return \"SLR	%0,%0\";
	}
      if (GET_CODE (operands[1]) == CONST_INT
 	  && (unsigned) INTVAL (operands[1]) < 4096)
	{
	  mvs_check_page (0, 4, 0);
	  return \"LA	%0,%c1\";
	}
      mvs_check_page (0, 4, 0);
      return \"L	%0,%1\";
    }
  else if (FP_REG_P (operands[1]))
    {
      mvs_check_page (0, 4, 0);
      return \"STE	%1,%0\";
    }
  else if (REG_P (operands[1]))
    {
      mvs_check_page (0, 4, 0);
      return \"ST	%1,%0\";
    }
  mvs_check_page (0, 6, 0);
  return \"MVC	%O0(4,%R0),%1\";
}")

(define_insn "movsi"
  [(set (match_operand:SI 0 "general_operand" "=d,dm")
	(match_operand:SI 1 "general_operand" "dimF,*fd"))]
  ""
  "*
{
  check_label_emit ();
  if (REG_P (operands[0]))
    {
      if (FP_REG_P (operands[1]))
	{
	  mvs_check_page (0, 8, 0);
	  return \"STE	%1,140(,13)\;L	%0,140(,13)\";
	}
      if (REG_P (operands[1]))
	{
	  mvs_check_page (0, 2, 0);
	  return \"LR	%0,%1\";
	}
      if (operands[1] == const0_rtx)
	{
	  CC_STATUS_INIT;
	  mvs_check_page (0, 2, 0);
	  return \"SLR	%0,%0\";
	}
      if (GET_CODE (operands[1]) == CONST_INT
	  && (unsigned) INTVAL (operands[1]) < 4096)
	{
	  mvs_check_page (0, 4, 0);
	  return \"LA	%0,%c1\";
	}
      mvs_check_page (0, 4, 0);
      return \"L	%0,%1\";
    }
  else if (FP_REG_P (operands[1]))
    {
      mvs_check_page (0, 4, 0);
      return \"STE	%1,%0\";
    }
  mvs_check_page (0, 4, 0);
  return \"ST	%1,%0\";
}")

;(define_expand "movsi"
;  [(set (match_operand:SI 0 "general_operand" "=d,dm")
;	(match_operand:SI 1 "general_operand" "dimF,*fd"))]
;  ""
;  "
;{
;  rtx op0, op1;
;
;  op0 = operands[0];
;  if (GET_CODE (op0) == CONST
;      && GET_CODE (XEXP (XEXP (op0, 0), 0)) == SYMBOL_REF
;      && SYMBOL_REF_FLAG (XEXP (XEXP (op0, 0), 0)))
;    {
;      op0 = gen_rtx (MEM, SImode, copy_to_mode_reg (SImode, XEXP (op0, 0)));
;    }
;
;  op1 = operands[1];
;  if (GET_CODE (op1) == CONST
;      && GET_CODE (XEXP (XEXP (op1, 0), 0)) == SYMBOL_REF
;      && SYMBOL_REF_FLAG (XEXP (XEXP (op1, 0), 0)))
;    {
;      op1 = gen_rtx (MEM, SImode, copy_to_mode_reg (SImode, XEXP (op1, 0)));
;    }
;
;  emit_insn (gen_rtx (SET, VOIDmode, op0, op1));
;  DONE;
;}")

;
; movhi instruction pattern(s).
;

(define_insn ""
  [(set (match_operand:HI 0 "r_or_s_operand" "=g")
        (match_operand:HI 1 "r_or_s_operand" "g"))]
  "TARGET_CHAR_INSTRUCTIONS"
  "*
{
  check_label_emit ();
  if (REG_P (operands[0]))
    {
      if (REG_P (operands[1]))
	{
	  mvs_check_page (0, 2, 0);
	  return \"LR	%0,%1\";
	}
      if (operands[1] == const0_rtx)
	{
	  CC_STATUS_INIT;
	  mvs_check_page (0, 2, 0);
	  return \"SLR	%0,%0\";
	}
      if (GET_CODE (operands[1]) == CONST_INT
	  && (unsigned) INTVAL (operands[1]) < 4096)
	{
	  mvs_check_page (0, 4, 0);
	  return \"LA	%0,%c1\";
	}
      if (GET_CODE (operands[1]) == CONST_INT)
	{
	  mvs_check_page (0, 4, 2);
	  return \"LH	%0,=H'%h1'\";
	}
      mvs_check_page (0, 4, 0);
      return \"LH	%0,%1\";
    }
  else if (REG_P (operands[1]))
    {
      mvs_check_page (0, 4, 0);
      return \"STH	%1,%0\";
    }
  if (GET_CODE (operands[1]) == CONST_INT)
    {
      mvs_check_page (0, 6, 0);
      return \"MVC	%O0(2,%R0),=H'%h1'\";
    }
  mvs_check_page (0, 6, 0);
  return \"MVC	%O0(2,%R0),%1\";
}")

(define_insn "movhi"
  [(set (match_operand:HI 0 "general_operand" "=d,m")
	(match_operand:HI 1 "general_operand" "g,d"))]
  ""
  "*
{
  check_label_emit ();
  if (REG_P (operands[0]))
    {
      if (REG_P (operands[1]))
	{
	  mvs_check_page (0, 2, 0);
	  return \"LR	%0,%1\";
	}
      if (operands[1] == const0_rtx)
	{
	  CC_STATUS_INIT;
	  mvs_check_page (0, 2, 0);
	  return \"SLR	%0,%0\";
	}
      if (GET_CODE (operands[1]) == CONST_INT
	  && (unsigned) INTVAL (operands[1]) < 4096)
	{
	  mvs_check_page (0, 4, 0);
	  return \"LA	%0,%c1\";
	}
      if (GET_CODE (operands[1]) == CONST_INT)
	{
	  mvs_check_page (0, 4, 2);
	  return \"LH	%0,=H'%h1'\";
	}
      mvs_check_page (0, 4, 0);
      return \"LH	%0,%1\";
    }
  mvs_check_page (0, 4, 0);
  return \"STH	%1,%0\";
}")

;
; movqi instruction pattern(s).
;

(define_insn ""
  [(set (match_operand:QI 0 "r_or_s_operand" "=g")
	(match_operand:QI 1 "r_or_s_operand" "g"))]
  "TARGET_CHAR_INSTRUCTIONS"
  "*
{
  check_label_emit ();
  if (REG_P (operands[0]))
    {
      if (REG_P (operands[1]))
	{
	  mvs_check_page (0, 2, 0);
	  return \"LR	%0,%1\";
	}
      if (operands[1] == const0_rtx)
	{
	  CC_STATUS_INIT;
	  mvs_check_page (0, 2, 0);
	  return \"SLR	%0,%0\";
	}
      if (GET_CODE (operands[1]) == CONST_INT)
	{
	  if (INTVAL (operands[1]) >= 0)
	    {
	      mvs_check_page (0, 4, 0);
	      return \"LA	%0,%c1\";
	    }
	  mvs_check_page (0, 4, 0);
	  return \"L	%0,=F'%c1'\";
	}
      mvs_check_page (0, 4, 0);
      return \"IC	%0,%1\";
    }
  else if (REG_P (operands[1]))
    {
      mvs_check_page (0, 4, 0);
      return \"STC	%1,%0\";
    }
  else if (GET_CODE (operands[1]) == CONST_INT)
    {
      mvs_check_page (0, 4, 0);
      return \"MVI	%0,%B1\";
    }
  mvs_check_page (0, 6, 0);
  return \"MVC	%O0(1,%R0),%1\";
}")

(define_insn "movqi"
  [(set (match_operand:QI 0 "general_operand" "=d,m")
	(match_operand:QI 1 "general_operand" "g,d"))]
  ""
  "*
{
  check_label_emit ();
  if (REG_P (operands[0]))
    {
      if (REG_P (operands[1]))
	{
	  mvs_check_page (0, 2, 0);
	  return \"LR	%0,%1\";
	}
      if (operands[1] == const0_rtx)
	{
	  CC_STATUS_INIT;
	  mvs_check_page (0, 2, 0);
	  return \"SLR	%0,%0\";
	}
      if (GET_CODE (operands[1]) == CONST_INT)
	{
	  if (INTVAL (operands[1]) >= 0)
	    {
	      mvs_check_page (0, 4, 0);
	      return \"LA	%0,%c1\";
	    }
	  mvs_check_page (0, 4, 0);
	  return \"L	%0,=F'%c1'\";
	}
      mvs_check_page (0, 4, 0);
      return \"IC	%0,%1\";
    }
  mvs_check_page (0, 4, 0);
  return \"STC	%1,%0\";
}")

;
; movestrictqi instruction pattern(s).
;

(define_insn "movestrictqi"
  [(set (strict_low_part (match_operand:QI 0 "general_operand" "=d"))
	(match_operand:QI 1 "general_operand" "g"))]
  ""
  "*
{
  check_label_emit ();
  if (REG_P (operands[1]))
    {
      mvs_check_page (0, 8, 0);
      return \"STC	%1,140(,13)\;IC	%0,140(,13)\";
    }
  mvs_check_page (0, 4, 0);
  return \"IC	%0,%1\";
}")

;
; movstricthi instruction pattern(s).
;

(define_insn ""
  [(set (strict_low_part (match_operand:HI 0 "register_operand" "=d"))
	(match_operand:HI 1 "r_or_s_operand" "g"))]
  ""
  "*
{
  check_label_emit ();
  if (REG_P (operands[1]))
    {
      mvs_check_page (0, 8, 0);
      return \"STH	%1,140(,13)\;ICM	%0,3,140(13)\";
    }
  else if (GET_CODE (operands[1]) == CONST_INT)
    {
      mvs_check_page (0, 4, 2);
      return \"ICM	%0,3,=H'%h1'\";
    }
  mvs_check_page (0, 4, 0);
  return \"ICM	%0,3,%1\";
}")

(define_insn "movestricthi"
  [(set (strict_low_part (match_operand:HI 0 "general_operand" "=dm"))
	(match_operand:HI 1 "general_operand" "d"))]
  ""
  "*
{
  check_label_emit ();
  if (REG_P (operands[0]))
    {
      mvs_check_page (0, 8, 0);
      return \"STH	%1,140(,13)\;ICM	%0,3,140(13)\";
    }
  mvs_check_page (0, 4, 0);
  return \"STH	%1,%0\";
}")

;
; movdf instruction pattern(s).
;

(define_insn ""
  [(set (match_operand:DF 0 "r_or_s_operand" "=fm,fm,*dm")
        (match_operand:DF 1 "r_or_s_operand" "fmF,*dm,fmF"))]
  "TARGET_CHAR_INSTRUCTIONS"
  "*
{
  check_label_emit ();
  if (FP_REG_P (operands[0]))
    {
      if (FP_REG_P (operands[1]))
	{
	  mvs_check_page (0, 2, 0);
	  return \"LDR	%0,%1\";
	}
      if (REG_P (operands[1]))
	{
	  mvs_check_page (0, 8, 0);
	  return \"STM	%1,%N1,140(13)\;LD	%0,140(,13)\";
	}
      if (operands[1] == const0_rtx)
	{
	  CC_STATUS_SET (operands[0], operands[1]);
	  mvs_check_page (0, 2, 0);
	  return \"SDR	%0,%0\";
	}
      mvs_check_page (0, 4, 0);
      return \"LD	%0,%1\";
    }
  if (REG_P (operands[0]))
    {
      if (FP_REG_P (operands[1]))
	{
	  mvs_check_page (0, 12, 0);
	  return \"STD	%1,140(,13)\;LM	%0,%N0,140(13)\";
	}
      mvs_check_page (0, 4, 0);
      return \"LM	%0,%N0,%1\";
    }
  else if (FP_REG_P (operands[1]))
    {
      mvs_check_page (0, 4, 0);
      return \"STD	%1,%0\";
    }
  else if (REG_P (operands[1]))
    {
      mvs_check_page (0, 4, 0);
      return \"STM	%1,%N1,%0\";
    }
  mvs_check_page (0, 6, 0);
  return \"MVC	%O0(8,%R0),%1\";
}")

(define_insn "movdf"
  [(set (match_operand:DF 0 "general_operand" "=f,fm,m,*d")
	(match_operand:DF 1 "general_operand" "fmF,*d,f,fmF"))]
  ""
  "*
{
  check_label_emit ();
  if (FP_REG_P (operands[0]))
    {
      if (FP_REG_P (operands[1]))
	{
	  mvs_check_page (0, 2, 0);
	  return \"LDR	%0,%1\";
	}
      if (REG_P (operands[1]))
	{
	  mvs_check_page (0, 8, 0);
	  return \"STM	%1,%N1,140(13)\;LD	%0,140(,13)\";
	}
      if (operands[1] == const0_rtx)
	{
	  CC_STATUS_SET (operands[0], operands[1]);
	  mvs_check_page (0, 2, 0);
	  return \"SDR	%0,%0\";
	}
      mvs_check_page (0, 4, 0);
      return \"LD	%0,%1\";
    }
  else if (REG_P (operands[0]))
    {
      if (FP_REG_P (operands[1]))
	{
	  mvs_check_page (0, 12, 0);
	  return \"STD	%1,140(,13)\;LM	%0,%N0,140(13)\";
	}
      mvs_check_page (0, 4, 0);
      return \"LM	%0,%N0,%1\";
    }
  else if (FP_REG_P (operands[1]))
    {
      mvs_check_page (0, 4, 0);
      return \"STD	%1,%0\";
    }
  mvs_check_page (0, 4, 0);
  return \"STM	%1,%N1,%0\";
}")

;
; movsf instruction pattern(s).
;

(define_insn ""
  [(set (match_operand:SF 0 "r_or_s_operand" "=fm,fm,*dm")
        (match_operand:SF 1 "r_or_s_operand" "fmF,*dm,fmF"))]
  "TARGET_CHAR_INSTRUCTIONS"
  "*
{
  check_label_emit ();
  if (FP_REG_P (operands[0]))
    {
      if (FP_REG_P (operands[1]))
	{
	  mvs_check_page (0, 2, 0);
	  return \"LER	%0,%1\";
	}
      if (REG_P (operands[1]))
	{
	  mvs_check_page (0, 8, 0);
	  return \"ST	%1,140(,13)\;LE	%0,140(,13)\";
	}
      if (operands[1] == const0_rtx)
	{
	  CC_STATUS_SET (operands[0], operands[1]);
	  mvs_check_page (0, 2, 0);
	  return \"SER	%0,%0\";
	}
      mvs_check_page (0, 4, 0);
      return \"LE	%0,%1\";
    }
  else if (REG_P (operands[0]))
    {
      if (FP_REG_P (operands[1]))
	{
	  mvs_check_page (0, 8, 0);
	  return \"STE	%1,140(,13)\;L	%0,140(,13)\";
	}
      mvs_check_page (0, 4, 0);
      return \"L	%0,%1\";
    }
  else if (FP_REG_P (operands[1]))
    {
      mvs_check_page (0, 4, 0);
      return \"STE	%1,%0\";
    }
  else if (REG_P (operands[1]))
    {
      mvs_check_page (0, 4, 0);
      return \"ST	%1,%0\";
    }
  mvs_check_page (0, 6, 0);
  return \"MVC	%O0(4,%R0),%1\";
}")

(define_insn "movsf"
  [(set (match_operand:SF 0 "general_operand" "=f,fm,m,*d")
	(match_operand:SF 1 "general_operand" "fmF,*d,f,fmF"))]
  ""
  "*
{
  check_label_emit ();
  if (FP_REG_P (operands[0]))
    {
      if (FP_REG_P (operands[1]))
	{
	  mvs_check_page (0, 2, 0);
	  return \"LER	%0,%1\";
	}
      if (REG_P (operands[1]))
	{
	  mvs_check_page (0, 8, 0);
	  return \"ST	%1,140(,13)\;LE	%0,140(,13)\";
	}
      if (operands[1] == const0_rtx)
	{
	  CC_STATUS_SET (operands[0], operands[1]);
	  mvs_check_page (0, 2, 0);
	  return \"SER	%0,%0\";
	}
      mvs_check_page (0, 4, 0);
      return \"LE	%0,%1\";
    }
  else if (REG_P (operands[0]))
    {
      if (FP_REG_P (operands[1]))
	{
	  mvs_check_page (0, 8, 0);
	  return \"STE	%1,140(,13)\;L	%0,140(,13)\";
	}
      mvs_check_page (0, 4, 0);
      return \"L	%0,%1\";
    }
  else if (FP_REG_P (operands[1]))
    {
      mvs_check_page (0, 4, 0);
      return \"STE	%1,%0\";
    }
  mvs_check_page (0, 4, 0);
  return \"ST	%1,%0\";
}")

;
; movstrsi instruction pattern(s).
;

(define_expand "movstrsi"
  [(set (match_operand:BLK 0 "general_operand" "")
        (match_operand:BLK 1 "general_operand" ""))
   (use (match_operand:SI 2 "general_operand" ""))
   (match_operand 3 "" "")]
   ""
   "
{
  rtx op0, op1;

  op0 = XEXP (operands[0], 0);
  if (GET_CODE (op0) == REG
       || (GET_CODE (op0) == PLUS && GET_CODE (XEXP (op0, 0)) == REG
	   && GET_CODE (XEXP (op0, 1)) == CONST_INT
	   && (unsigned) INTVAL (XEXP (op0, 1)) < 4096))
    {
      op0 = operands[0];
    }
  else
    {
      op0 = gen_rtx (MEM, BLKmode, copy_to_mode_reg (SImode, op0));
    }

  op1 = XEXP (operands[1], 0);
  if (GET_CODE (op1) == REG
      || (GET_CODE (op1) == PLUS && GET_CODE (XEXP (op1, 0)) == REG
	  && GET_CODE (XEXP (op1, 1)) == CONST_INT
	  && (unsigned) INTVAL (XEXP (op1, 1)) < 4096))
    {
      op1 = operands[1];
    }
  else
    {
      op1 = gen_rtx (MEM, BLKmode, copy_to_mode_reg (SImode, op1));
    }

  if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 256)
    {
      emit_insn (gen_rtx (PARALLEL, VOIDmode, gen_rtvec (2,
			gen_rtx (SET, VOIDmode, op0, op1),
			gen_rtx (USE, VOIDmode, operands[2]))));
    }
  else
    {
      rtx reg1 = gen_reg_rtx (DImode);
      rtx reg2 = gen_reg_rtx (DImode);
      rtx subreg = gen_rtx (SUBREG, SImode, reg1, 1);

      emit_insn (gen_rtx (SET, VOIDmode, subreg, operands[2]));
      emit_insn (gen_rtx (SET, VOIDmode, gen_rtx (SUBREG, SImode, reg2, 1),
						 subreg));
      emit_insn (gen_rtx (PARALLEL, VOIDmode, gen_rtvec (5,
			gen_rtx (SET, VOIDmode, op0, op1),
			gen_rtx (USE, VOIDmode, reg1),
			gen_rtx (USE, VOIDmode, reg2),
			gen_rtx (CLOBBER, VOIDmode, reg1),
			gen_rtx (CLOBBER, VOIDmode, reg2))));
    }
  DONE;
}")

; Move a block that is less than 256 bytes in length.

(define_insn ""
  [(set (match_operand:BLK 0 "s_operand" "=m")
	(match_operand:BLK 1 "s_operand" "m"))
   (use (match_operand 2 "immediate_operand" "I"))]
  "((unsigned) INTVAL (operands[2]) < 256)"
  "*
{
  check_label_emit ();
  mvs_check_page (0, 6, 0);
  return \"MVC	%O0(%c2,%R0),%1\";
}")

; Move a block that is larger than 255 bytes in length.

(define_insn ""
  [(set (match_operand:BLK 0 "general_operand" "=m")
        (match_operand:BLK 1 "general_operand" "m"))
   (use (match_operand:DI 2 "register_operand" "d"))
   (use (match_operand:DI 3 "register_operand" "d"))
   (clobber (match_dup 2))
   (clobber (match_dup 3))]
  ""
  "*
{
  check_label_emit ();
  mvs_check_page (0, 10, 0);
  return \"LA	%2,%0\;LA	%3,%1\;MVCL	%2,%3\";
}")

;;
;;- Conversion instructions.
;;

;
; extendsidi2 instruction pattern(s).
;

(define_expand "extendsidi2"
  [(set (match_operand:DI 0 "general_operand" "")
        (sign_extend:DI (match_operand:SI 1 "general_operand" "")))]
  ""
  "
{
  if (GET_CODE (operands[1]) != CONST_INT)
    {
      emit_insn (gen_rtx (SET, VOIDmode,
		  operand_subword (operands[0], 0, 1, DImode), operands[1]));
      emit_insn (gen_rtx (SET, VOIDmode, operands[0],
			gen_rtx (ASHIFTRT, DImode, operands[0],
				gen_rtx (CONST_INT, SImode, 32))));
    }
  else
    {
      if (INTVAL (operands[1]) < 0)
	{
	  emit_insn (gen_rtx (SET, VOIDmode,
				  operand_subword (operands[0], 0, 1, DImode),
			       gen_rtx (CONST_INT, SImode, -1)));
        }
      else
	{
	  emit_insn (gen_rtx (SET, VOIDmode,
				operand_subword (operands[0], 0, 1, DImode),
			       gen_rtx (CONST_INT, SImode, 0)));
        }
      emit_insn (gen_rtx (SET, VOIDmode, gen_lowpart (SImode, operands[0]),
			   operands[1]));
    }
  DONE;
}")

;
; extendhisi2 instruction pattern(s).
;

(define_insn "extendhisi2"
  [(set (match_operand:SI 0 "general_operand" "=d,m")
	(sign_extend:SI (match_operand:HI 1 "general_operand" "g,d")))]
  ""
  "*
{
  check_label_emit ();
  if (REG_P (operands[0]))
    {
      if (REG_P (operands[1]))
        if (REGNO (operands[0]) != REGNO (operands[1]))
	  {
	    mvs_check_page (0, 2, 0);
            return \"LR	%0,%1\;SLL	%0,16\;SRA	%0,16\";
	  }
        else
          return \"\"; /* Should be empty.  16-bits regs are always 32-bits.  */
      if (operands[1] == const0_rtx)
	{
	  CC_STATUS_INIT;
	  mvs_check_page (0, 2, 0);
	  return \"SLR	%0,%0\";
	}
      if (GET_CODE (operands[1]) == CONST_INT
 	  && (unsigned) INTVAL (operands[1]) < 4096)
	{
	  mvs_check_page (0, 4, 0);
	  return \"LA	%0,%c1\";
	}
      if (GET_CODE (operands[1]) == CONST_INT)
	{
	  mvs_check_page (0, 4, 2);
	  return \"LH	%0,=H'%h1'\";
	}
      mvs_check_page (0, 4, 0);
      return \"LH	%0,%1\";
    }
  mvs_check_page (0, 4, 0);
  return \"SLL	%0,16\;SRA	%0,16\;ST	%1,%0\";
}")

;
; extendqisi2 instruction pattern(s).
;

(define_insn "extendqisi2"
  [(set (match_operand:SI 0 "general_operand" "=d")
	(sign_extend:SI (match_operand:QI 1 "general_operand" "0mi")))]
  ""
  "*
{
  check_label_emit ();
  CC_STATUS_SET (operands[0], operands[1]);
  if (REG_P (operands[1]))
    {
      mvs_check_page (0, 8, 0);
      return \"SLL	%0,24\;SRA	%0,24\";
    }
  if (s_operand (operands[1]))
    {
      mvs_check_page (0, 8, 0);
      return \"ICM	%0,8,%1\;SRA	%0,24\";
    }
  mvs_check_page (0, 12, 0);
  return \"IC	%0,%1\;SLL	%0,24\;SRA	%0,24\";
}")

;
; extendqihi2 instruction pattern(s).
;

(define_insn "extendqihi2"
  [(set (match_operand:HI 0 "general_operand" "=d")
	(sign_extend:HI (match_operand:QI 1 "general_operand" "0m")))]
  ""
  "*
{
  check_label_emit ();
  CC_STATUS_SET (operands[0], operands[1]);
  if (REG_P (operands[1]))
    {
      mvs_check_page (0, 8, 0);
      return \"SLL	%0,24\;SRA	%0,24\";
    }
  if (s_operand (operands[1]))
    {
      mvs_check_page (0, 8, 0);
      return \"ICM	%0,8,%1\;SRA	%0,24\";
    }
  mvs_check_page (0, 12, 0);
  return \"IC	%0,%1\;SLL	%0,24\;SRA	%0,24\";
}")

;
; zero_extendsidi2 instruction pattern(s).
;

(define_expand "zero_extendsidi2"
  [(set (match_operand:DI 0 "general_operand" "")
        (zero_extend:DI (match_operand:SI 1 "general_operand" "")))]
  ""
  "
{
      emit_insn (gen_rtx (SET, VOIDmode,
		  operand_subword (operands[0], 0, 1, DImode), operands[1]));
      emit_insn (gen_rtx (SET, VOIDmode, operands[0],
			gen_rtx (LSHIFTRT, DImode, operands[0],
				gen_rtx (CONST_INT, SImode, 32))));
  DONE;
}")

;
; zero_extendhisi2 instruction pattern(s).
;

(define_insn "zero_extendhisi2"
  [(set (match_operand:SI 0 "general_operand" "=d")
	(zero_extend:SI (match_operand:HI 1 "general_operand" "0")))]
  ""
  "*
{
  check_label_emit ();
  CC_STATUS_SET (operands[0], operands[1]);
  mvs_check_page (0, 4, 4);
  return \"N	%1,=X'0000FFFF'\";
}")

;
; zero_extendqisi2 instruction pattern(s).
;

(define_insn "zero_extendqisi2"
  [(set (match_operand:SI 0 "general_operand" "=d,&d")
	(zero_extend:SI (match_operand:QI 1 "general_operand" "0i,m")))]
  ""
  "*
{
  check_label_emit ();
  if (REG_P (operands[1]))
    {
      CC_STATUS_SET (operands[0], operands[1]);
      mvs_check_page (0, 4, 4);
      return \"N	%0,=X'000000FF'\";
    }
  if (GET_CODE (operands[1]) == CONST_INT)
    {
      mvs_check_page (0, 4, 0);
      return \"LA	%0,%c1\";
    }
  CC_STATUS_INIT;
  mvs_check_page (0, 8, 0);
  return \"SLR	%0,%0\;IC	%0,%1\";
}")

;
; zero_extendqihi2 instruction pattern(s).
;

(define_insn "zero_extendqihi2"
  [(set (match_operand:HI 0 "general_operand" "=d,&d")
	(zero_extend:HI (match_operand:QI 1 "general_operand" "0i,m")))]
  ""
  "*
{
  check_label_emit ();
  if (REG_P (operands[1]))
    {
      CC_STATUS_SET (operands[0], operands[1]);
      mvs_check_page (0, 4, 4);
      return \"N	%0,=X'000000FF'\";
    }
  if (GET_CODE (operands[1]) == CONST_INT)
    {
      mvs_check_page (0, 4, 0);
      return \"LA	%0,%c1\";
    }
  CC_STATUS_INIT;
  mvs_check_page (0, 8, 0);
  return \"SLR	%0,%0\;IC	%0,%1\";
}")

;
; truncsihi2 instruction pattern(s).
;

(define_insn "truncsihi2"
  [(set (match_operand:HI 0 "general_operand" "=d,m")
	(truncate:HI (match_operand:SI 1 "general_operand" "0,d")))]
  ""
  "*
{
  check_label_emit ();
  if (REG_P (operands[0]))
    {
      CC_STATUS_SET (operands[0], operands[1]);
      mvs_check_page (0, 8, 0);
      return \"SLL	%0,16\;SRA	%0,16\";
    }
  mvs_check_page (0, 4, 0);
  return \"STH	%1,%0\";
}")

;
; fix_truncdfsi2 instruction pattern(s).
;

(define_insn "fix_truncdfsi2"
  [(set (match_operand:SI 0 "general_operand" "=d")
        (fix:SI (truncate:DF (match_operand:DF 1 "general_operand" "f"))))
	(clobber (reg:DF 16))]
  ""
  "*
{
  check_label_emit ();
  CC_STATUS_INIT;
  if (REGNO (operands[1]) == 16)
    {
      mvs_check_page (0, 12, 8);
      return \"AD	0,=XL8'4F08000000000000'\;STD	0,140(,13)\;L	%0,144(,13)\";
    }
  mvs_check_page (0, 14, 8);
  return \"LDR	0,%1\;AD	0,=XL8'4F08000000000000'\;STD	0,140(,13)\;L	%0,144(,13)\";
}")

;
; floatsidf2 instruction pattern(s).
;
; Uses the float field of the TCA.
;

(define_insn "floatsidf2"
  [(set (match_operand:DF 0 "general_operand" "=f")
        (float:DF (match_operand:SI 1 "general_operand" "d")))]
  ""
  "*
{
  check_label_emit ();
  CC_STATUS_INIT;
  mvs_check_page (0, 16, 8);
  return \"ST	%1,508(,12)\;XI	508(12),128\;LD	%0,504(,12)\;SD	%0,=XL8'4E00000080000000'\";
}")

;
; truncdfsf2 instruction pattern(s).
;

(define_insn "truncdfsf2"
  [(set (match_operand:SF 0 "general_operand" "=f")
        (float_truncate:SF (match_operand:DF 1 "general_operand" "f")))]
  ""
  "*
{
  check_label_emit ();
  mvs_check_page (0, 2, 0);
  return \"LRER	%0,%1\";
}")

;
; extendsfdf2 instruction pattern(s).
;

(define_insn "extendsfdf2"
  [(set (match_operand:DF 0 "general_operand" "=f")
        (float_extend:DF (match_operand:SF 1 "general_operand" "fmF")))]
  ""
  "*
{
  check_label_emit ();
  CC_STATUS_SET (0, const0_rtx);
  if (FP_REG_P (operands[1]))
    {
      if (REGNO (operands[0]) == REGNO (operands[1]))
	{
	  mvs_check_page (0, 10, 0);
	  return \"STE	%1,140(,13)\;SDR	%0,%0\;LE	%0,140(,13)\";
	}
      mvs_check_page (0, 4, 0);
      return \"SDR	%0,%0\;LER	%0,%1\";
    }
  mvs_check_page (0, 6, 0);
  return \"SDR	%0,%0\;LE	%0,%1\";
}")

;;
;;- Add instructions.
;;

;
; adddi3 instruction pattern(s).
;

(define_expand "adddi3"
  [(set (match_operand:DI 0 "general_operand" "")
	(plus:DI (match_operand:DI 1 "general_operand" "")
		 (match_operand:DI 2 "general_operand" "")))]
  ""
  "
{
  rtx label = gen_label_rtx ();
  rtx op0_high = operand_subword (operands[0], 0, 1, DImode);
  rtx op0_low = gen_lowpart (SImode, operands[0]);
	
  emit_insn (gen_rtx (SET, VOIDmode, op0_high,
		    gen_rtx (PLUS, SImode,
			    operand_subword (operands[1], 0, 1, DImode),
			    operand_subword (operands[2], 0, 1, DImode))));
  emit_jump_insn (gen_rtx (PARALLEL, VOIDmode, gen_rtvec (2,
	      gen_rtx (SET, VOIDmode, op0_low,
		      gen_rtx (PLUS, SImode, gen_lowpart (SImode, operands[1]),
			      gen_lowpart (SImode, operands[2]))),
	      gen_rtx (USE, VOIDmode, gen_rtx (LABEL_REF, VOIDmode, label)))));
  emit_insn (gen_rtx (SET, VOIDmode, op0_high,
		    gen_rtx (PLUS, SImode, op0_high,
			    gen_rtx (CONST_INT, SImode, 1))));
  emit_label (label);
  DONE;
}")

(define_insn ""
  [(set (match_operand:SI 0 "general_operand" "=d")
	(plus:SI (match_operand:SI 1 "general_operand" "%0")
		 (match_operand:SI 2 "general_operand" "g")))
   (use (label_ref (match_operand 3 "" "")))]
  ""
  "*
{
  int onpage;

  check_label_emit ();
  onpage = mvs_check_label (CODE_LABEL_NUMBER (operands[3]));
  if (REG_P (operands[2]))
    {
      if (!onpage)
	{
	  mvs_check_page (0, 8, 4);
	  return \"ALR	%0,%2\;L	14,=A(%l3)\;BCR	12,14\";
	}
      if (mvs_check_page (0, 6, 0))
	{
	  mvs_check_page (0, 2, 4);
	  return \"ALR	%0,%2\;L	14,=A(%l3)\;BCR	12,14\";
	}
      return \"ALR	%0,%2\;BC	12,%l3\";
    }
  if (!onpage)
    {
      mvs_check_page (0, 10, 4);
      return \"AL	%0,%2\;L	14,=A(%l3)\;BCR	12,14\";
    }
  if (mvs_check_page (0, 8 ,0))
    {
      mvs_check_page (0, 2, 4);
      return \"AL	%0,%2\;L	14,=A(%l3)\;BCR	12,14\";
    }
  return \"AL	%0,%2\;BC	12,%l3\";
}")

;
; addsi3 instruction pattern(s).
;
; The following insn is used when it is known that operand one is an address,
; frame, stack or argument pointer, and operand two is a constant that is
; small enough to fit in the displacement field.
; Notice that we can't allow the frame pointer to used as a normal register
; because of this insn.
;

(define_insn ""
  [(set (match_operand:SI 0 "register_operand" "=d")
	(plus:SI (match_operand:SI 1 "general_operand" "%a")
		 (match_operand:SI 2 "immediate_operand" "J")))]
  "((REGNO (operands[1]) == FRAME_POINTER_REGNUM || REGNO (operands[1]) == ARG_POINTER_REGNUM || REGNO (operands[1]) == STACK_POINTER_REGNUM) && (unsigned) INTVAL (operands[2]) < 4096)"
  "*
{
  check_label_emit ();
  CC_STATUS_INIT;
  mvs_check_page (0, 4, 0);
  return \"LA	%0,%c2(,%1)\";
}")

; This insn handles additions that are relative to the frame pointer.

(define_insn ""
  [(set (match_operand:SI 0 "register_operand" "=d")
         (plus:SI (match_operand:SI 1 "register_operand" "%a")
                  (match_operand:SI 2 "immediate_operand" "i")))]
  "REGNO (operands[1]) == FRAME_POINTER_REGNUM"
  "*
{
  check_label_emit ();
  if ((unsigned) INTVAL (operands[2]) < 4096)
    {
      mvs_check_page (0, 4, 0);
      return \"LA	%0,%c2(,%1)\";
    }
  if (REGNO (operands[1]) == REGNO (operands[0]))
    {
      mvs_check_page (0, 4, 0);
      return \"A	%0,%2\";
    }
  mvs_check_page (0, 6, 0);
  return \"L	%0,%2\;AR	%0,%1\";
}")

(define_insn "addsi3"
  [(set (match_operand:SI 0 "general_operand" "=d")
	(plus:SI (match_operand:SI 1 "general_operand" "%0")
		 (match_operand:SI 2 "general_operand" "g")))]
  ""
  "*
{
  check_label_emit ();
  if (REG_P (operands[2]))
    {
      mvs_check_page (0, 2, 0);
      return \"AR	%0,%2\";
    }
  if (GET_CODE (operands[2]) == CONST_INT)
    {
      if (INTVAL (operands[2]) == -1)
	{
	  CC_STATUS_INIT;
	  mvs_check_page (0, 2, 0);
	  return \"BCTR	%0,0\";
	}
    }
  mvs_check_page (0, 4, 0);
  return \"A	%0,%2\";
}")

;
; addhi3 instruction pattern(s).
;

(define_insn "addhi3"
  [(set (match_operand:HI 0 "general_operand" "=d")
	(plus:HI (match_operand:HI 1 "general_operand" "%0")
		 (match_operand:HI 2 "general_operand" "dmi")))]
  ""
  "*
{
  check_label_emit ();
  if (REG_P (operands[2]))
    {
      mvs_check_page (0, 2, 0);
      return \"STH	%2,140(,13)\;AH	%0,140(,13)\";
    }
  if (GET_CODE (operands[2]) == CONST_INT)
    {
      if (INTVAL (operands[2]) == -1)
	{
	  CC_STATUS_INIT;
	  mvs_check_page (0, 2, 0);
	  return \"BCTR	%0,0\";
	}
      mvs_check_page (0, 4, 2);
      return \"AH	%0,=H'%h2'\";
    }
  mvs_check_page (0, 4, 0);
  return \"AH	%0,%2\";
}")

;
; addqi3 instruction pattern(s).
;

(define_insn "addqi3"
  [(set (match_operand:QI 0 "general_operand" "=d")
	(plus:QI (match_operand:QI 1 "general_operand" "%a")
		 (match_operand:QI 2 "general_operand" "ai")))]
  ""
  "*
{
  check_label_emit ();
  CC_STATUS_INIT;
  mvs_check_page (0, 4, 0);
  if (REG_P (operands[2]))
    return \"LA	%0,0(%1,%2)\";
  return \"LA	%0,%B2(,%1)\";
}")

;
; adddf3 instruction pattern(s).
;

(define_insn "adddf3"
  [(set (match_operand:DF 0 "general_operand" "=f")
	(plus:DF (match_operand:DF 1 "general_operand" "%0")
		 (match_operand:DF 2 "general_operand" "fmF")))]
  ""
  "*
{
  check_label_emit ();
  if (FP_REG_P (operands[2]))
    {
      mvs_check_page (0, 2, 0);
      return \"ADR	%0,%2\";
    }
  mvs_check_page (0, 4, 0);
  return \"AD	%0,%2\";
}")

;
; addsf3 instruction pattern(s).
;

(define_insn "addsf3"
  [(set (match_operand:SF 0 "general_operand" "=f")
	(plus:SF (match_operand:SF 1 "general_operand" "%0")
		 (match_operand:SF 2 "general_operand" "fmF")))]
  ""
  "*
{
  check_label_emit ();
  if (FP_REG_P (operands[2]))
    {
      mvs_check_page (0, 2, 0);
      return \"AER	%0,%2\";
    }
  mvs_check_page (0, 4, 0);
  return \"AE	%0,%2\";
}")

;;
;;- Subtract instructions.
;;

;
; subdi3 instruction pattern(s).
;

(define_expand "subdi3"
  [(set (match_operand:DI 0 "general_operand" "")
	(minus:DI (match_operand:DI 1 "general_operand" "")
		  (match_operand:DI 2 "general_operand" "")))]
  ""
  "
{
  rtx label = gen_label_rtx ();
  rtx op0_high = operand_subword (operands[0], 0, 1, DImode);
  rtx op0_low = gen_lowpart (SImode, operands[0]);
	
  emit_insn (gen_rtx (SET, VOIDmode, op0_high,
		    gen_rtx (MINUS, SImode,
			      operand_subword (operands[1], 0, 1, DImode),
			      operand_subword (operands[2], 0, 1, DImode))));
  emit_jump_insn (gen_rtx (PARALLEL, VOIDmode, gen_rtvec (2,
		    gen_rtx (SET, VOIDmode, op0_low,
			      gen_rtx (MINUS, SImode,
				      gen_lowpart (SImode, operands[1]),
				      gen_lowpart (SImode, operands[2]))),
		    gen_rtx (USE, VOIDmode,
			      gen_rtx (LABEL_REF, VOIDmode, label)))));
  emit_insn (gen_rtx (SET, VOIDmode, op0_high,
		      gen_rtx (MINUS, SImode, op0_high,
			      gen_rtx (CONST_INT, SImode, 1))));
  emit_label (label);
  DONE;
}")

(define_insn ""
  [(set (match_operand:SI 0 "general_operand" "=d")
	(minus:SI (match_operand:SI 1 "general_operand" "0")
		  (match_operand:SI 2 "general_operand" "g")))
   (use (label_ref (match_operand 3 "" "")))]
  ""
  "*
{
  int onpage;

  check_label_emit ();
  CC_STATUS_INIT;
  onpage = mvs_check_label (CODE_LABEL_NUMBER (operands[3]));
  if (REG_P (operands[2]))
    {
      if (!onpage)
	{
	  mvs_check_page (0, 8, 4);
	  return \"SLR	%0,%2\;L	14,=A(%l3)\;BCR	12,14\";
	}
      if (mvs_check_page (0, 6, 0))
	{
	  mvs_check_page (0, 2, 4);
	  return \"SLR	%0,%2\;L	14,=A(%l3)\;BCR	12,14\";
	}
      return \"SLR	%0,%2\;BC	12,%l3\";
    }
  if (!onpage)
    {
      mvs_check_page (0, 10, 4);
      return \"SL	%0,%2\;L	14,=A(%l3)\;BCR	12,14\";
    }
  if (mvs_check_page (0, 8, 0))
    {
      mvs_check_page (0, 2, 4);
      return \"SL	%0,%2\;L	14,=A(%l3)\;BCR	12,14\";
    }
  return \"SL	%0,%2\;BC	12,%l3\";
}")

;
; subsi3 instruction pattern(s).
;

(define_insn "subsi3"
  [(set (match_operand:SI 0 "general_operand" "=d")
	(minus:SI (match_operand:SI 1 "general_operand" "0")
		  (match_operand:SI 2 "general_operand" "g")))]
  ""
  "*
{
  check_label_emit ();
  if (REG_P (operands[2]))
    {
      mvs_check_page (0, 2, 0);
      return \"SR	%0,%2\";
    }
  if (operands[2] == const1_rtx)
    {
      CC_STATUS_INIT;
      mvs_check_page (0, 2, 0);
      return \"BCTR	%0,0\";
    }
  mvs_check_page (0, 4, 0);
  return \"S	%0,%2\";
}")

;
; subhi3 instruction pattern(s).
;

(define_insn "subhi3"
  [(set (match_operand:HI 0 "general_operand" "=d")
	(minus:HI (match_operand:HI 1 "general_operand" "0")
		  (match_operand:HI 2 "general_operand" "g")))]
  ""
  "*
{
  check_label_emit ();
  if (REG_P (operands[2]))
    {
      mvs_check_page (0, 2, 0);
      return \"STH	%2,140(,13)\;SH	%0,140(,13)\";
    }
  if (operands[2] == const1_rtx)
    {
      CC_STATUS_INIT;
      mvs_check_page (0, 2, 0);
      return \"BCTR	%0,0\";
    }
  if (GET_CODE (operands[2]) == CONST_INT)
    {
      mvs_check_page (0, 4, 2);
      return \"SH	%0,=H'%h2'\";
    }
  mvs_check_page (0, 4, 0);
  return \"SH	%0,%2\";
}")

;
; subqi3 instruction pattern(s).
;

(define_expand "subqi3"
  [(set (match_operand:QI 0 "general_operand" "=d")
	(minus:QI (match_operand:QI 1 "general_operand" "%0")
		  (match_operand:QI 2 "general_operand" "di")))]
  ""
  "
{
  if (REG_P (operands[2]))
    {
      emit_insn (gen_rtx (SET, VOIDmode, operands[0],
			gen_rtx (MINUS, QImode, operands[1], operands[2])));
    }
  else
    {
      emit_insn (gen_rtx (SET, VOIDmode, operands[0],
			gen_rtx (PLUS, QImode, operands[1],
				 negate_rtx (QImode, operands[2]))));
    }
  DONE;
}")

(define_insn ""
  [(set (match_operand:QI 0 "register_operand" "=d")
	(minus:QI (match_operand:QI 1 "register_operand" "%0")
		 (match_operand:QI 2 "register_operand" "d")))]
  ""
  "*
{
  check_label_emit ();
  CC_STATUS_INIT;
  mvs_check_page (0, 2, 0);
  return \"SR	%0,%2\";
}")

;
; subdf3 instruction pattern(s).
;

(define_insn "subdf3"
  [(set (match_operand:DF 0 "general_operand" "=f")
	(minus:DF (match_operand:DF 1 "general_operand" "0")
		  (match_operand:DF 2 "general_operand" "fmF")))]
  ""
  "*
{
  check_label_emit ();
  if (FP_REG_P (operands[2]))
    {
      mvs_check_page (0, 2, 0);
      return \"SDR	%0,%2\";
    }
  mvs_check_page (0, 4, 0);
  return \"SD	%0,%2\";
}")

;
; subsf3 instruction pattern(s).
;

(define_insn "subsf3"
  [(set (match_operand:SF 0 "general_operand" "=f")
	(minus:SF (match_operand:SF 1 "general_operand" "0")
		  (match_operand:SF 2 "general_operand" "fmF")))]
  ""
  "*
{
  check_label_emit ();
  if (FP_REG_P (operands[2]))
    {
      mvs_check_page (0, 2, 0);
      return \"SER	%0,%2\";
    }
  mvs_check_page (0, 4, 0);
  return \"SE	%0,%2\";
}")

;;
;;- Multiply instructions.
;;

;
; mulsi3 instruction pattern(s).
;

(define_expand "mulsi3"
  [(set (match_operand:SI 0 "general_operand" "")
	(mult:SI (match_operand:SI 1 "general_operand" "")
		 (match_operand:SI 2 "general_operand" "")))]
  ""
  "
{
  if (GET_CODE (operands[1]) == CONST_INT
      && CONST_OK_FOR_LETTER_P (INTVAL (operands[1]), 'K'))
    {
      emit_insn (gen_rtx (SET, VOIDmode, operands[0],
			  gen_rtx (MULT, SImode, operands[2], operands[1])));
    }
  else if (GET_CODE (operands[2]) == CONST_INT
	   && CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K'))
    {
      emit_insn (gen_rtx (SET, VOIDmode, operands[0],
			  gen_rtx (MULT, SImode, operands[1], operands[2])));
    }
  else
    {
      rtx r = gen_reg_rtx (DImode);

      emit_insn (gen_rtx (SET, VOIDmode,
			  gen_rtx (SUBREG, SImode, r, 1), operands[1]));
      emit_insn (gen_rtx (SET, VOIDmode, r,
			  gen_rtx (MULT, SImode, r, operands[2])));
      emit_insn (gen_rtx (SET, VOIDmode, operands[0],
			  gen_rtx (SUBREG, SImode, r, 1)));
    }
  DONE;
}")

(define_insn ""
  [(set (match_operand:SI 0 "register_operand" "=d")
	(mult:SI (match_operand:SI 1 "general_operand" "%0")
		 (match_operand:SI 2 "immediate_operand" "K")))]
  ""
  "*
{
  check_label_emit ();
  mvs_check_page (0, 4, 0);
  return \"MH	%0,%2\";
}")

(define_insn ""
  [(set (match_operand:DI 0 "register_operand" "=d")
	(mult:SI (match_operand:DI 1 "general_operand" "%0")
		 (match_operand:SI 2 "general_operand" "g")))]
  ""
  "*
{
  check_label_emit ();
  if (REG_P (operands[2]))
    {
      mvs_check_page (0, 2, 0);
      return \"MR	%0,%2\";
    }
  mvs_check_page (0, 4, 0);
  return \"M	%0,%2\";
}")

;
; muldf3 instruction pattern(s).
;

(define_insn "muldf3"
  [(set (match_operand:DF 0 "general_operand" "=f")
	(mult:DF (match_operand:DF 1 "general_operand" "%0")
		 (match_operand:DF 2 "general_operand" "fmF")))]
  ""
  "*
{
  check_label_emit ();
  if (FP_REG_P (operands[2]))
    {
      mvs_check_page (0, 2, 0);
      return \"MDR	%0,%2\";
    }
  mvs_check_page (0, 4, 0);
  return \"MD	%0,%2\";
}")

;
; mulsf3 instruction pattern(s).
;

(define_insn "mulsf3"
  [(set (match_operand:SF 0 "general_operand" "=f")
	(mult:SF (match_operand:SF 1 "general_operand" "%0")
		 (match_operand:SF 2 "general_operand" "fmF")))]
  ""
  "*
{
  check_label_emit ();
  if (FP_REG_P (operands[2]))
    {
      mvs_check_page (0, 2, 0);
      return \"MER	%0,%2\";
    }
  mvs_check_page (0, 4, 0);
  return \"ME	%0,%2\";
}")

;;
;;- Divide instructions.
;;

;
; divsi3 instruction pattern(s).
;

(define_expand "divsi3"
  [(set (match_operand:SI 0 "general_operand" "")
	(div:SI (match_operand:SI 1 "general_operand" "")
		(match_operand:SI 2 "general_operand" "")))]
  ""
  "
{
  rtx r = gen_reg_rtx (DImode);

  emit_insn (gen_extendsidi2 (r, operands[1]));
  emit_insn (gen_rtx (SET, VOIDmode, r,
			gen_rtx (DIV, SImode, r, operands[2])));
  emit_insn (gen_rtx (SET, VOIDmode, operands[0],
			gen_rtx (SUBREG, SImode, r, 1)));
  DONE;
}")


;
; udivsi3 instruction pattern(s).
;

(define_expand "udivsi3"
  [(set (match_operand:SI 0 "general_operand" "")
	(udiv:SI (match_operand:SI 1 "general_operand" "")
		 (match_operand:SI 2 "general_operand" "")))]
  ""
  "
{
  rtx dr = gen_reg_rtx (DImode);
  rtx dr_0 = gen_rtx (SUBREG, SImode, dr, 0);
  rtx dr_1 = gen_rtx (SUBREG, SImode, dr, 1);


  if (GET_CODE (operands[2]) == CONST_INT)
    {
      if (INTVAL (operands[2]) > 0)
	{
	  emit_insn (gen_zero_extendsidi2 (dr, operands[1]));
	  emit_insn (gen_rtx (SET, VOIDmode, dr,
			gen_rtx (DIV, SImode, dr, operands[2])));
	}
      else
	{
	  rtx label1 = gen_label_rtx ();

	  emit_insn (gen_rtx (SET, VOIDmode, dr_0, operands[1]));
	  emit_insn (gen_rtx (SET, VOIDmode, dr_1, const0_rtx));
	  emit_insn (gen_cmpsi (dr_0, operands[2]));
	  emit_jump_insn (gen_bltu (label1));
	  emit_insn (gen_rtx (SET, VOIDmode, dr_1, const1_rtx));
	  emit_label (label1);
	}
    }
  else
    {
      rtx label1 = gen_label_rtx ();
      rtx label2 = gen_label_rtx ();
      rtx label3 = gen_label_rtx ();
      rtx sr = gen_reg_rtx (SImode);

      emit_insn (gen_rtx (SET, VOIDmode, dr_0, operands[1]));
      emit_insn (gen_rtx (SET, VOIDmode, sr, operands[2]));
      emit_insn (gen_rtx (SET, VOIDmode, dr_1, const0_rtx));
      emit_insn (gen_cmpsi (sr, dr_0));
      emit_jump_insn (gen_bgtu (label3));
      emit_insn (gen_cmpsi (sr, const1_rtx));
      emit_jump_insn (gen_blt (label2));
      emit_jump_insn (gen_beq (label1));
      emit_insn (gen_rtx (SET, VOIDmode, dr,
			  gen_rtx (LSHIFTRT, DImode, dr,
				    gen_rtx (CONST_INT, SImode, 32))));
      emit_insn (gen_rtx (SET, VOIDmode, dr,
		    gen_rtx (DIV, SImode, dr, sr)));
      emit_jump_insn (gen_jump (label3));
      emit_label (label1);
      emit_insn (gen_rtx (SET, VOIDmode, dr_1, dr_0));
      emit_jump_insn (gen_jump (label3));
      emit_label (label2);
      emit_insn (gen_rtx (SET, VOIDmode, dr_1, const1_rtx));
      emit_label (label3);
    }
  emit_insn (gen_rtx (SET, VOIDmode, operands[0], dr_1));

  DONE;
}")

; This is used by divsi3 & udivsi3.

(define_insn ""
  [(set (match_operand:DI 0 "register_operand" "=d")
	(div:SI (match_operand:DI 1 "register_operand" "0")
		(match_operand:SI 2 "general_operand" "")))]
  ""
  "*
{
  check_label_emit ();
  if (REG_P (operands[2]))
    {
      mvs_check_page (0, 2, 0);
      return \"DR	%0,%2\";
    }
  mvs_check_page (0, 4, 0);
  return \"D	%0,%2\";
}")

;
; divdf3 instruction pattern(s).
;

(define_insn "divdf3"
  [(set (match_operand:DF 0 "general_operand" "=f")
        (div:DF (match_operand:DF 1 "general_operand" "0")
                (match_operand:DF 2 "general_operand" "fmF")))]
  ""
  "*
{
  check_label_emit ();
  if (FP_REG_P (operands[2]))
    {
      mvs_check_page (0, 2, 0);
      return \"DDR	%0,%2\";
    }
  mvs_check_page (0, 4, 0);
  return \"DD	%0,%2\";
}")

;
; divsf3 instruction pattern(s).
;

(define_insn "divsf3"
  [(set (match_operand:SF 0 "general_operand" "=f")
        (div:SF (match_operand:SF 1 "general_operand" "0")
                (match_operand:SF 2 "general_operand" "fmF")))]
  ""
  "*
{
  check_label_emit ();
  if (FP_REG_P (operands[2]))
    {
      mvs_check_page (0, 2, 0);
      return \"DER	%0,%2\";
    }
  mvs_check_page (0, 4, 0);
  return \"DE	%0,%2\";
}")

;;
;;- Modulo instructions.
;;

;
; modsi3 instruction pattern(s).
;

(define_expand "modsi3"
  [(set (match_operand:SI 0 "general_operand" "")
	(mod:SI (match_operand:SI 1 "general_operand" "")
		(match_operand:SI 2 "general_operand" "")))]
  ""
  "
{
  rtx r = gen_reg_rtx (DImode);

  emit_insn (gen_extendsidi2 (r, operands[1]));
  emit_insn (gen_rtx (SET, VOIDmode, r,
			gen_rtx (MOD, SImode, r, operands[2])));
  emit_insn (gen_rtx (SET, VOIDmode, operands[0],
			gen_rtx (SUBREG, SImode, r, 0)));
  DONE;
}")

;
; umodsi3 instruction pattern(s).
;

(define_expand "umodsi3"
  [(set (match_operand:SI 0 "general_operand" "")
	(umod:SI (match_operand:SI 1 "general_operand" "")
		 (match_operand:SI 2 "general_operand" "")))]
  ""
  "
{
  rtx dr = gen_reg_rtx (DImode);
  rtx dr_0 = gen_rtx (SUBREG, SImode, dr, 0);
  rtx dr_1 = gen_rtx (SUBREG, SImode, dr, 1);

  emit_insn (gen_rtx (SET, VOIDmode, dr_0, operands[1]));

  if (GET_CODE (operands[2]) == CONST_INT)
    {
      if (INTVAL (operands[2]) > 0)
	{
	  emit_insn (gen_rtx (SET, VOIDmode, dr,
			      gen_rtx (LSHIFTRT, DImode, dr,
					gen_rtx (CONST_INT, SImode, 32))));
	  emit_insn (gen_rtx (SET, VOIDmode, dr,
			gen_rtx (MOD, SImode, dr, operands[2])));
	}
      else
	{
	  rtx label1 = gen_label_rtx ();
	  rtx sr = gen_reg_rtx (SImode);

	  emit_insn (gen_rtx (SET, VOIDmode, sr, operands[2]));
	  emit_insn (gen_cmpsi (dr_0, sr));
	  emit_jump_insn (gen_bltu (label1));
	  emit_insn (gen_rtx (SET, VOIDmode, sr, gen_rtx (ABS, SImode, sr)));
	  emit_insn (gen_rtx (SET, VOIDmode, dr_0,
			      gen_rtx (PLUS, SImode, dr_0, sr)));
	  emit_label (label1);
	}
    }
  else
    {
      rtx label1 = gen_label_rtx ();
      rtx label2 = gen_label_rtx ();
      rtx label3 = gen_label_rtx ();
      rtx sr = gen_reg_rtx (SImode);

      emit_insn (gen_rtx (SET, VOIDmode, dr_0, operands[1]));
      emit_insn (gen_rtx (SET, VOIDmode, sr, operands[2]));
      emit_insn (gen_cmpsi (sr, dr_0));
      emit_jump_insn (gen_bgtu (label3));
      emit_insn (gen_cmpsi (sr, const1_rtx));
      emit_jump_insn (gen_blt (label2));
      emit_jump_insn (gen_beq (label1));
      emit_insn (gen_rtx (SET, VOIDmode, dr,
			  gen_rtx (LSHIFTRT, DImode, dr,
				    gen_rtx (CONST_INT, SImode, 32))));
      emit_insn (gen_rtx (SET, VOIDmode, dr, gen_rtx (MOD, SImode, dr, sr)));
      emit_jump_insn (gen_jump (label3));
      emit_label (label1);
      emit_insn (gen_rtx (SET, VOIDmode, dr_0, const0_rtx));
      emit_jump_insn (gen_jump (label3));
      emit_label (label2);
      emit_insn (gen_rtx (SET, VOIDmode, dr_0,
			  gen_rtx (MINUS, SImode, dr_0, sr)));
      emit_label (label3);

    }
  emit_insn (gen_rtx (SET, VOIDmode, operands[0], dr_0));

  DONE;
}")

; This is used by modsi3 & umodsi3.

(define_insn ""
  [(set (match_operand:DI 0 "register_operand" "=d")
	(mod:SI (match_operand:DI 1 "register_operand" "0")
		(match_operand:SI 2 "general_operand" "")))]
  ""
  "*
{
  check_label_emit ();
  if (REG_P (operands[2]))
    {
      mvs_check_page (0, 2, 0);
      return \"DR	%0,%2\";
    }
  mvs_check_page (0, 4, 0);
  return \"D	%0,%2\";
}")

;;
;;- And instructions.
;;

;
; anddi3 instruction pattern(s).
;

;(define_expand "anddi3"
;  [(set (match_operand:DI 0 "general_operand" "")
;	(and:DI (match_operand:DI 1 "general_operand" "")
;		(match_operand:DI 2 "general_operand" "")))]
;  ""
;  "
;{
;  rtx gen_andsi3();
;
;  emit_insn (gen_andsi3 (operand_subword (operands[0], 0, 1, DImode),
;			 operand_subword (operands[1], 0, 1, DImode),
;			 operand_subword (operands[2], 0, 1, DImode)));
;  emit_insn (gen_andsi3 (gen_lowpart (SImode, operands[0]),
;			 gen_lowpart (SImode, operands[1]),
;			 gen_lowpart (SImode, operands[2])));
;  DONE;
;}")

;
; andsi3 instruction pattern(s).
;

(define_insn ""
  [(set (match_operand:SI 0 "r_or_s_operand" "=d,m")
	(and:SI (match_operand:SI 1 "r_or_s_operand" "%0,0")
		(match_operand:SI 2 "r_or_s_operand" "g,mi")))]
  "TARGET_CHAR_INSTRUCTIONS"
  "*
{
  check_label_emit ();
  if (REG_P (operands[2]))
    {
      mvs_check_page (0, 2, 0);
      return \"NR	%0,%2\";
    }
  if (REG_P (operands[0]))
    {
      mvs_check_page (0, 4, 0);
      return \"N	%0,%2\";
    }
  CC_STATUS_INIT;
  mvs_check_page (0, 6, 0);
  return \"NC	%O0(4,%R0),%2\";
}")

(define_insn "andsi3"
  [(set (match_operand:SI 0 "general_operand" "=d")
	(and:SI (match_operand:SI 1 "general_operand" "%0")
		(match_operand:SI 2 "general_operand" "g")))]
  ""
  "*
{
  check_label_emit ();
  if (REG_P (operands[2]))
    {
      mvs_check_page (0, 2, 0);
      return \"NR	%0,%2\";
    }
  mvs_check_page (0, 4, 0);
  return \"N	%0,%2\";
}")

;
; andhi3 instruction pattern(s).
;

(define_insn ""
  [(set (match_operand:HI 0 "r_or_s_operand" "=d,m")
	(and:HI (match_operand:HI 1 "r_or_s_operand" "%0,0")
		(match_operand:HI 2 "r_or_s_operand" "di,mi")))]
  "TARGET_CHAR_INSTRUCTIONS"
  "*
{
  check_label_emit ();
  if (REG_P (operands[2]))
    {
      mvs_check_page (0, 2, 0);
      return \"NR	%0,%2\";
    }
  if (REG_P (operands[0]))
    {
      mvs_check_page (0, 4, 0);
      return \"N	%0,%H2\";
    }
  CC_STATUS_INIT;
  if (GET_CODE (operands[2]) == CONST_INT)
    {
      mvs_check_page (0, 6, 2);
      return \"NC	%O0(2,%R0),=H'%h2'\";
    }
  mvs_check_page (0, 6, 0);
  return \"NC	%O0(2,%R0),%2\";
}")

(define_insn "andhi3"
  [(set (match_operand:HI 0 "general_operand" "=d")
	(and:HI (match_operand:HI 1 "general_operand" "%0")
		(match_operand:HI 2 "general_operand" "di")))]
  ""
  "*
{
  check_label_emit ();
  if (GET_CODE (operands[2]) == CONST_INT)
    {
      mvs_check_page (0, 4, 0);
      return \"N	%0,%H2\";
    }
  mvs_check_page (0, 2, 0);
  return \"NR	%0,%2\";
}")

;
; andqi3 instruction pattern(s).
;

(define_insn ""
  [(set (match_operand:QI 0 "r_or_s_operand" "=d,m")
	(and:QI (match_operand:QI 1 "r_or_s_operand" "%0,0")
		(match_operand:QI 2 "r_or_s_operand" "di,mi")))]
  "TARGET_CHAR_INSTRUCTIONS"
  "*
{
  check_label_emit ();
  CC_STATUS_INIT; 
  if (REG_P (operands[2]))
    {
      mvs_check_page (0, 2, 0);
      return \"NR	%0,%2\";
    }
  if (REG_P (operands[0]))
    {
      mvs_check_page (0, 4, 0);
      return \"N	%0,%2\";
    }
  if (GET_CODE (operands[2]) == CONST_INT)
    {
      mvs_check_page (0, 4, 0);
      return \"NI	%0,%B2\";
    }
  mvs_check_page (0, 6, 0);
  return \"NC	%O0(1,%R0),%2\";
}")

(define_insn "andqi3"
  [(set (match_operand:QI 0 "general_operand" "=d")
	(and:QI (match_operand:QI 1 "general_operand" "%0")
		(match_operand:QI 2 "general_operand" "di")))]
  ""
  "*
{
  check_label_emit ();
  CC_STATUS_INIT;
  if (GET_CODE (operands[2]) == CONST_INT)
    {
      mvs_check_page (0, 4, 0);
      return \"N	%0,%2\";
    }
  mvs_check_page (0, 2, 0);
  return \"NR	%0,%2\";
}")

;;
;;- Bit set (inclusive or) instructions.
;;

;
; iordi3 instruction pattern(s).
;

;(define_expand "iordi3"
;  [(set (match_operand:DI 0 "general_operand" "")
;	(ior:DI (match_operand:DI 1 "general_operand" "")
;		(match_operand:DI 2 "general_operand" "")))]
;  ""
;  "
;{
;  rtx gen_iorsi3();
;
;  emit_insn (gen_iorsi3 (operand_subword (operands[0], 0, 1, DImode),
;			 operand_subword (operands[1], 0, 1, DImode),
;			 operand_subword (operands[2], 0, 1, DImode)));
;  emit_insn (gen_iorsi3 (gen_lowpart (SImode, operands[0]),
;			 gen_lowpart (SImode, operands[1]),
;			 gen_lowpart (SImode, operands[2])));
;  DONE;
;}")

;
; iorsi3 instruction pattern(s).
;

(define_insn ""
  [(set (match_operand:SI 0 "r_or_s_operand" "=d,m")
	(ior:SI (match_operand:SI 1 "r_or_s_operand" "%0,0")
		(match_operand:SI 2 "r_or_s_operand" "g,mi")))]
  "TARGET_CHAR_INSTRUCTIONS"
  "*
{
  check_label_emit ();
  if (REG_P (operands[2]))
    {
      mvs_check_page (0, 2, 0);
      return \"OR	%0,%2\";
    }
  if (REG_P (operands[0]))
    {
      mvs_check_page (0, 4, 0);
      return \"O	%0,%2\";
    }
  CC_STATUS_INIT;
  mvs_check_page (0, 6, 0);
  return \"OC	%O0(4,%R0),%2\";
}")

(define_insn "iorsi3"
  [(set (match_operand:SI 0 "general_operand" "=d")
	(ior:SI (match_operand:SI 1 "general_operand" "%0")
		(match_operand:SI 2 "general_operand" "g")))]
  ""
  "*
{
  check_label_emit ();
  if (REG_P (operands[2]))
    {
      mvs_check_page (0, 2, 0);
      return \"OR	%0,%2\";
    }
  mvs_check_page (0, 4, 0);
  return \"O	%0,%2\";
}")

;
; iorhi3 instruction pattern(s).
;

(define_insn ""
  [(set (match_operand:HI 0 "r_or_s_operand" "=d,m")
	(ior:HI (match_operand:HI 1 "r_or_s_operand" "%0,0")
		(match_operand:HI 2 "r_or_s_operand" "di,mi")))]
  "TARGET_CHAR_INSTRUCTIONS"
  "*
{
  check_label_emit ();
  if (REG_P (operands[2]))
    {
      mvs_check_page (0, 2, 0);
      return \"OR	%0,%2\";
    }
  if (REG_P (operands[0]))
    {
      mvs_check_page (0, 4, 0);
      return \"O	%0,%H2\";
    }
  CC_STATUS_INIT;
  if (GET_CODE (operands[2]) == CONST_INT)
    {
      mvs_check_page (0, 6, 2);
      return \"OC	%O0(2,%R0),=H'%h2'\";
    }
  mvs_check_page (0, 6, 0);
  return \"OC	%O0(2,%R0),%2\";
}")

(define_insn "iorhi3"
  [(set (match_operand:HI 0 "general_operand" "=d")
	(ior:HI (match_operand:HI 1 "general_operand" "%0")
		(match_operand:HI 2 "general_operand" "di")))]
  ""
  "*
{
  check_label_emit ();
  if (GET_CODE (operands[2]) == CONST_INT)
    {
      mvs_check_page (0, 4, 0);
      return \"O	%0,%H2\";
    }
  mvs_check_page (0, 2, 0);
  return \"OR	%0,%2\";
}")

;
; iorqi3 instruction pattern(s).
;

(define_insn ""
  [(set (match_operand:QI 0 "r_or_s_operand" "=d,m")
	(ior:QI (match_operand:QI 1 "r_or_s_operand" "%0,0")
		(match_operand:QI 2 "r_or_s_operand" "di,mi")))]
  "TARGET_CHAR_INSTRUCTIONS"
  "*
{
  check_label_emit ();
  CC_STATUS_INIT;
  if (REG_P (operands[2]))
    {
      mvs_check_page (0, 2, 0);
      return \"OR	%0,%2\";
    }
  if (REG_P (operands[0]))
    {
      mvs_check_page (0, 4, 0);
      return \"O	%0,%2\";
    }
  CC_STATUS_INIT;
  if (GET_CODE (operands[2]) == CONST_INT)
    {
      mvs_check_page (0, 4, 0);
      return \"OI	%0,%B2\";
    }
  mvs_check_page (0, 6, 0);
  return \"OC	%O0(1,%R0),%2\";
}")

(define_insn "iorqi3"
  [(set (match_operand:QI 0 "general_operand" "=d")
	(ior:QI (match_operand:QI 1 "general_operand" "%0")
		(match_operand:QI 2 "general_operand" "di")))]
  ""
  "*
{
  check_label_emit ();
  CC_STATUS_INIT;
  if (GET_CODE (operands[2]) == CONST_INT)
    {
      mvs_check_page (0, 4, 0);
      return \"O	%0,%2\";
    }
  mvs_check_page (0, 2, 0);
  return \"OR	%0,%2\";
}")

;;
;;- Xor instructions.
;;

;
; xordi3 instruction pattern(s).
;

;(define_expand "xordi3"
;  [(set (match_operand:DI 0 "general_operand" "")
;	(xor:DI (match_operand:DI 1 "general_operand" "")
;		(match_operand:DI 2 "general_operand" "")))]
;  ""
;  "
;{
;  rtx gen_xorsi3();
;
;  emit_insn (gen_xorsi3 (operand_subword (operands[0], 0, 1, DImode),
;			 operand_subword (operands[1], 0, 1, DImode),
;			 operand_subword (operands[2], 0, 1, DImode)));
;  emit_insn (gen_xorsi3 (gen_lowpart (SImode, operands[0]),
;			 gen_lowpart (SImode, operands[1]),
;			 gen_lowpart (SImode, operands[2])));
;  DONE;
;}")

;
; xorsi3 instruction pattern(s).
;

(define_insn ""
  [(set (match_operand:SI 0 "r_or_s_operand" "=d,m")
	(xor:SI (match_operand:SI 1 "r_or_s_operand" "%0,0")
		(match_operand:SI 2 "r_or_s_operand" "g,mi")))]
  "TARGET_CHAR_INSTRUCTIONS"
  "*
{
  check_label_emit ();
  if (REG_P (operands[2]))
    {
      mvs_check_page (0, 2, 0);
      return \"XR	%0,%2\";
    }
  if (REG_P (operands[0]))
    {
      mvs_check_page (0, 4, 0);
      return \"X	%0,%2\";
    }
  CC_STATUS_INIT;
  mvs_check_page (0, 6, 0);
  return \"XC	%O0(4,%R0),%2\";
}")

(define_insn "xorsi3"
  [(set (match_operand:SI 0 "general_operand" "=d")
	(xor:SI (match_operand:SI 1 "general_operand" "%0")
		(match_operand:SI 2 "general_operand" "g")))]
  ""
  "*
{
  check_label_emit ();
  if (REG_P (operands[2]))
    {
      mvs_check_page (0, 2, 0);
      return \"XR	%0,%2\";
    }
  mvs_check_page (0, 4, 0);
  return \"X	%0,%2\";
}")

;
; xorhi3 instruction pattern(s).
;

(define_insn ""
  [(set (match_operand:HI 0 "r_or_s_operand" "=d,m")
	(xor:HI (match_operand:HI 1 "r_or_s_operand" "%0,0")
		(match_operand:HI 2 "r_or_s_operand" "di,mi")))]
  "TARGET_CHAR_INSTRUCTIONS"
  "*
{
  check_label_emit ();
  if (REG_P (operands[2]))
    {
      mvs_check_page (0, 2, 0);
      return \"XR	%0,%2\";
    }
  if (REG_P (operands[0]))
    {
      mvs_check_page (0, 4, 0);
      return \"X	%0,%H2\";
    }
  CC_STATUS_INIT;
  if (GET_CODE (operands[2]) == CONST_INT)
    {
      mvs_check_page (0, 6, 2);
      return \"XC	%O0(2,%R0),=H'%h2'\";
    }
  mvs_check_page (0, 6, 0);
  return \"XC	%O0(2,%R0),%2\";
}")

(define_insn "xorhi3"
  [(set (match_operand:HI 0 "general_operand" "=d")
	(xor:HI (match_operand:HI 1 "general_operand" "%0")
		(match_operand:HI 2 "general_operand" "di")))]
  ""
  "*
{
  check_label_emit ();
  if (GET_CODE (operands[2]) == CONST_INT)
    {
      mvs_check_page (0, 4, 0);
      return \"X	%0,%2\";
    }
  mvs_check_page (0, 2, 0);
  return \"XR	%0,%2\";
}")

;
; xorqi3 instruction pattern(s).
;

(define_insn ""
  [(set (match_operand:QI 0 "r_or_s_operand" "=d,m")
	(xor:QI (match_operand:QI 1 "r_or_s_operand" "%0,0")
		(match_operand:QI 2 "r_or_s_operand" "di,mi")))]
  "TARGET_CHAR_INSTRUCTIONS"
  "*
{
  check_label_emit ();
  CC_STATUS_INIT;
  if (REG_P (operands[2]))
    {
      mvs_check_page (0, 2, 0);
      return \"XR	%0,%2\";
    }
  if (REG_P (operands[0]))
    {
      mvs_check_page (0, 4, 0);
      return \"X	%0,%2\";
    }
  if (GET_CODE (operands[2]) == CONST_INT)
    {
      mvs_check_page (0, 4, 0);
      return \"XI	%0,%B2\";
    }
  mvs_check_page (0, 6, 0);
  return \"XC	%O0(1,%R0),%2\";
}")

(define_insn "xorqi3"
  [(set (match_operand:QI 0 "general_operand" "=d")
	(xor:QI (match_operand:QI 1 "general_operand" "%0")
		(match_operand:QI 2 "general_operand" "di")))]
  ""
  "*
{
  check_label_emit ();
  CC_STATUS_INIT;
  if (GET_CODE (operands[2]) == CONST_INT)
    {
      mvs_check_page (0, 4, 0);
      return \"X	%0,%2\";
    }
  mvs_check_page (0, 2, 0);
  return \"XR	%0,%2\";
}")

;;
;;- Negate instructions.
;;

;
; negsi2 instruction pattern(s).
;

(define_insn "negsi2"
  [(set (match_operand:SI 0 "general_operand" "=d")
	(neg:SI (match_operand:SI 1 "general_operand" "d")))]
  ""
  "*
{
  check_label_emit ();
  mvs_check_page (0, 2, 0);
  return \"LCR	%0,%1\";
}")

;
; neghi2 instruction pattern(s).
;

(define_insn "neghi2"
  [(set (match_operand:HI 0 "general_operand" "=d")
	(neg:HI (match_operand:HI 1 "general_operand" "d")))]
  ""
  "*
{
  check_label_emit ();
  mvs_check_page (0, 10, 0);
  return \"SLL	%1,16\;SRA	%1,16\;LCR	%0,%1\";
}")

;
; negdf2 instruction pattern(s).
;

(define_insn "negdf2"
  [(set (match_operand:DF 0 "general_operand" "=f")
	(neg:DF (match_operand:DF 1 "general_operand" "f")))]
  ""
  "*
{
  check_label_emit ();
  mvs_check_page (0, 2, 0);
  return \"LCDR	%0,%1\";
}")

;
; negsf2 instruction pattern(s).
;

(define_insn "negsf2"
  [(set (match_operand:SF 0 "general_operand" "=f")
	(neg:SF (match_operand:SF 1 "general_operand" "f")))]
  ""
  "*
{
  check_label_emit ();
  mvs_check_page (0, 2, 0);
  return \"LCER	%0,%1\";
}")

;;
;;- Absolute value instructions.
;;

;
; abssi2 instruction pattern(s).
;

(define_insn "abssi2"
  [(set (match_operand:SI 0 "general_operand" "=d")
	(abs:SI (match_operand:SI 1 "general_operand" "d")))]
  ""
  "*
{
  check_label_emit ();
  mvs_check_page (0, 2, 0);
  return \"LPR	%0,%1\";
}")

;
; abshi2 instruction pattern(s).
;

(define_insn "abshi2"
  [(set (match_operand:HI 0 "general_operand" "=d")
	(abs:HI (match_operand:HI 1 "general_operand" "d")))]
  ""
  "*
{
  check_label_emit ();
  mvs_check_page (0, 10, 0);
  return \"SLL	%1,16\;SRA	%1,16\;LPR	%0,%1\";
}")

;
; absdf2 instruction pattern(s).
;

(define_insn "absdf2"
  [(set (match_operand:DF 0 "general_operand" "=f")
	(abs:DF (match_operand:DF 1 "general_operand" "f")))]
  ""
  "*
{
  check_label_emit ();
  mvs_check_page (0, 2, 0);
  return \"LPDR	%0,%1\";
}")

;
; abssf2 instruction pattern(s).
;

(define_insn "abssf2"
  [(set (match_operand:SF 0 "general_operand" "=f")
	(abs:SF (match_operand:SF 1 "general_operand" "f")))]
  ""
  "*
{
  check_label_emit ();
  mvs_check_page (0, 2, 0);
  return \"LPER	%0,%1\";
}")

;;
;;- One complement instructions.
;;

;
; one_cmpldi2 instruction pattern(s).
;

;(define_expand "one_cmpldi2"
;  [(set (match_operand:DI 0 "general_operand" "")
;	(not:DI (match_operand:DI 1 "general_operand" "")))]
;  ""
;  "
;{
;  rtx gen_one_cmplsi2();
;
;  emit_insn (gen_one_cmplsi2 (operand_subword (operands[0], 0, 1, DImode),
;			      operand_subword (operands[1], 0, 1, DImode)));
;  emit_insn (gen_one_cmplsi2 (gen_lowpart (SImode, operands[0]),
;			      gen_lowpart (SImode, operands[1])));
;  DONE;
;}")

;
; one_cmplsi2 instruction pattern(s).
;

(define_insn ""
  [(set (match_operand:SI 0 "r_or_s_operand" "=dm")
	(not:SI (match_operand:SI 1 "r_or_s_operand" "0")))]
  "TARGET_CHAR_INSTRUCTIONS"
  "*
{
  check_label_emit ();
  if (REG_P (operands[0]))
    {
      mvs_check_page (0, 4, 4);
      return \"X	%0,=F'-1'\";
    }
  CC_STATUS_INIT;
  mvs_check_page (0, 6, 4);
  return \"XC	%O0(4,%R0),=F'-1'\";
}")

(define_insn "one_cmplsi2"
  [(set (match_operand:SI 0 "general_operand" "=d")
	(not:SI (match_operand:SI 1 "general_operand" "0")))]
  ""
  "*
{
  check_label_emit ();
  mvs_check_page (0, 4, 4);
  return \"X	%0,=F'-1'\";
}")

;
; one_cmplhi2 instruction pattern(s).
;

(define_insn ""
  [(set (match_operand:HI 0 "r_or_s_operand" "=dm")
	(not:HI (match_operand:HI 1 "r_or_s_operand" "0")))]
  "TARGET_CHAR_INSTRUCTIONS"
  "*
{
  check_label_emit ();
  if (REG_P (operands[0]))
    {
      mvs_check_page (0, 4, 4);
      return \"X	%0,=F'-1'\";
    }
  CC_STATUS_INIT;
  mvs_check_page (0, 6, 4);
  return \"XC	%O0(2,%R0),=X'FFFF'\";
}")

(define_insn "one_cmplhi2"
  [(set (match_operand:HI 0 "general_operand" "=d")
	(not:HI (match_operand:HI 1 "general_operand" "0")))]
  ""
  "*
{
  check_label_emit ();
  mvs_check_page (0, 4, 4);
  return \"X	%0,=F'-1'\";
}")

;
; one_cmplqi2 instruction pattern(s).
;

(define_insn ""
  [(set (match_operand:QI 0 "r_or_s_operand" "=dm")
	(not:QI (match_operand:QI 1 "r_or_s_operand" "0")))]
  "TARGET_CHAR_INSTRUCTIONS"
  "*
{
  check_label_emit ();
  CC_STATUS_INIT;
  if (REG_P (operands[0]))
    {
      mvs_check_page (0, 4, 4);
      return \"X	%0,=F'-1'\";
    }
  mvs_check_page (0, 4, 0);
  return \"XI	%0,255\";
}")

(define_insn "one_cmplqi2"
  [(set (match_operand:QI 0 "general_operand" "=d")
	(not:QI (match_operand:QI 1 "general_operand" "0")))]
  ""
  "*
{
  check_label_emit ();
  CC_STATUS_INIT;
  mvs_check_page (0, 4, 4);
  return \"X	%0,=F'-1'\";
}")

;;
;;- Arithmetic shift instructions.
;;

;
; ashldi3 instruction pattern(s).
;

(define_insn "ashldi3"
  [(set (match_operand:DI 0 "general_operand" "=d")
	(ashift:DI (match_operand:DI 1 "general_operand" "0")
		   (match_operand:SI 2 "general_operand" "Ja")))]
  ""
  "*
{
  check_label_emit ();
  CC_STATUS_INIT;
  mvs_check_page (0, 4, 0);
  if (REG_P (operands[2]))
    return \"SLDA	%0,0(%2)\";
  return \"SLDA	%0,%c2\";
}")

;
; ashrdi3 instruction pattern(s).
;

(define_insn "ashrdi3"
  [(set (match_operand:DI 0 "register_operand" "=d")
	(ashiftrt:DI (match_operand:DI 1 "general_operand" "0")
		     (match_operand:SI 2 "general_operand" "Ja")))]
  ""
  "*
{
  check_label_emit ();
  mvs_check_page (0, 4, 0);
  if (REG_P (operands[2])) 
    return \"SRDA	%0,0(%2)\";
  return \"SRDA	%0,%c2\";
}")

;
; ashlsi3 instruction pattern(s).
;

(define_insn "ashlsi3"
  [(set (match_operand:SI 0 "general_operand" "=d")
	(ashift:SI (match_operand:SI 1 "general_operand" "0")
		   (match_operand:SI 2 "general_operand" "Ja")))]
  ""
  "*
{
  check_label_emit ();
  CC_STATUS_INIT;
  mvs_check_page (0, 4, 0);
  if (REG_P (operands[2])) 
    return \"SLL	%0,0(%2)\";
  return \"SLL	%0,%c2\";
}")

;
; ashrsi3 instruction pattern(s).
;

(define_insn "ashrsi3"
  [(set (match_operand:SI 0 "general_operand" "=d")
	(ashiftrt:SI (match_operand:SI 1 "general_operand" "0")
		     (match_operand:SI 2 "general_operand" "Ja")))]
  ""
  "*
{
  check_label_emit ();
  mvs_check_page (0, 4, 0);
  if (REG_P (operands[2])) 
    return \"SRA	%0,0(%2)\";
  return \"SRA	%0,%c2\";
}")

;
; ashlhi3 instruction pattern(s).
;

(define_insn "ashlhi3"
  [(set (match_operand:HI 0 "general_operand" "=d")
	(ashift:HI (match_operand:HI 1 "general_operand" "0")
		   (match_operand:SI 2 "general_operand" "Ja")))]
  ""
  "*
{
  check_label_emit ();
  mvs_check_page (0, 8, 0);
  if (REG_P (operands[2])) 
    return \"SLL	%0,16(%2)\;SRA	%0,16\";
  return \"SLL	%0,16+%c2\;SRA	%0,16\";
}")

;
; ashrhi3 instruction pattern(s).
;

(define_insn "ashrhi3"
  [(set (match_operand:HI 0 "general_operand" "=d")
	(ashiftrt:HI (match_operand:HI 1 "general_operand" "0")
		     (match_operand:SI 2 "general_operand" "Ja")))]
  ""
  "*
{
  check_label_emit ();
  mvs_check_page (0, 4, 0);
  if (REG_P (operands[2])) 
    return \"SLL	%0,16\;SRA	%0,16(%2)\";
  return \"SLL	%0,16\;SRA	%0,16+%c2\";
}")

;
; ashlqi3 instruction pattern(s).
;

(define_insn "ashlqi3"
  [(set (match_operand:QI 0 "general_operand" "=d")
	(ashift:QI (match_operand:QI 1 "general_operand" "0")
		   (match_operand:SI 2 "general_operand" "Ja")))]
  ""
  "*
{
  check_label_emit ();
  CC_STATUS_INIT;
  mvs_check_page (0, 4, 0);
  if (REG_P (operands[2])) 
    return \"SLL	%0,0(%2)\";
  return \"SLL	%0,%c2\";
}")

;
; ashrqi3 instruction pattern(s).
;

(define_insn "ashrqi3"
  [(set (match_operand:QI 0 "general_operand" "=d")
	(ashiftrt:QI (match_operand:QI 1 "general_operand" "0")
		     (match_operand:SI 2 "general_operand" "Ja")))]
  ""
  "*
{
  check_label_emit ();
  mvs_check_page (0, 8, 0);
  if (REG_P (operands[2])) 
    return \"SLL	%0,24\;SRA	%0,24(%2)\";
  return \"SLL	%0,24\;SRA	%0,24+%c2\";
}")

;;
;;- Logical shift instructions.
;;

;
; lshldi3 instruction pattern(s).
;

(define_insn "lshldi3"
  [(set (match_operand:DI 0 "general_operand" "=d")
	(lshift:DI (match_operand:DI 1 "general_operand" "0")
		   (match_operand:SI 2 "general_operand" "Ja")))]
  ""
  "*
{
  check_label_emit ();
  mvs_check_page (0, 4, 0);
  if (REG_P (operands[2])) 
    return \"SLDL	%0,0(%2)\";
  return \"SLDL	%0,%c2\";
}")

;
; lshrdi3 instruction pattern(s).
;

(define_insn "lshrdi3"
  [(set (match_operand:DI 0 "general_operand" "=d")
	(lshiftrt:DI (match_operand:DI 1 "general_operand" "0")
		     (match_operand:SI 2 "general_operand" "Ja")))]
  ""
  "*
{
  check_label_emit ();
  mvs_check_page (0, 4, 0);
  if (REG_P (operands[2])) 
    return \"SRDL	%0,0(%2)\";
  return \"SRDL	%0,%c2\";
}")

;
; lshlsi3 instruction pattern(s).
;

(define_insn "lshlsi3"
  [(set (match_operand:SI 0 "general_operand" "=d")
	(lshift:SI (match_operand:SI 1 "general_operand" "0")
		   (match_operand:SI 2 "general_operand" "Ja")))]
  ""
  "*
{
  check_label_emit ();
  mvs_check_page (0, 4, 0);
  if (REG_P (operands[2])) 
    return \"SLL	%0,0(%2)\";
  return \"SLL	%0,%c2\";
}")

;
; lshrsi3 instruction pattern(s).
;

(define_insn "lshrsi3"
  [(set (match_operand:SI 0 "general_operand" "=d")
	(lshiftrt:SI (match_operand:SI 1 "general_operand" "0")
		     (match_operand:SI 2 "general_operand" "Ja")))]
  ""
  "*
{
  check_label_emit ();
  mvs_check_page (0, 4, 0);
  if (REG_P (operands[2])) 
    return \"SRL	%0,0(%2)\";
  return \"SRL	%0,%c2\";
}")

;
; lshlhi3 instruction pattern(s).
;

(define_insn "lshlhi3"
  [(set (match_operand:HI 0 "general_operand" "=d")
	(lshift:HI (match_operand:HI 1 "general_operand" "0")
		   (match_operand:SI 2 "general_operand" "Ja")))]
  ""
  "*
{
  check_label_emit ();
  CC_STATUS_INIT;
  mvs_check_page (0, 4, 0);
  if (REG_P (operands[2])) 
    return \"SLL	%0,0(%2)\";
  return \"SLL	%0,%c2\";
}")

;
; lshrhi3 instruction pattern(s).
;

(define_insn "lshrhi3"
  [(set (match_operand:HI 0 "general_operand" "=d")
	(lshiftrt:HI (match_operand:HI 1 "general_operand" "0")
		     (match_operand:SI 2 "general_operand" "Ja")))]
  ""
  "*
{
  check_label_emit ();
  CC_STATUS_INIT;
  if (REG_P (operands[2]))
    {
      mvs_check_page (0, 8, 4);
      return \"N	%0,=X'0000FFFF'\;SRL	%0,0(%2)\";
    }
  mvs_check_page (0, 8, 4);
  return \"N	%0,=X'0000FFFF'\;SRL	%0,%c2\";
}")

;
; lshlqi3 instruction pattern(s).
;

(define_insn "lshlqi3"
  [(set (match_operand:QI 0 "general_operand" "=d")
	(lshift:QI (match_operand:QI 1 "general_operand" "0")
		   (match_operand:SI 2 "general_operand" "Ja")))]
  ""
  "*
{
  check_label_emit ();
  mvs_check_page (0, 4, 0);
  if (REG_P (operands[2])) 
    return \"SLL	%0,0(%2)\";
  return \"SLL	%0,%c2\";
}")

;
; lshrqi3 instruction pattern(s).
;

(define_insn "lshrqi3"
  [(set (match_operand:QI 0 "general_operand" "=d")
	(lshiftrt:QI (match_operand:QI 1 "general_operand" "0")
		     (match_operand:SI 2 "general_operand" "Ja")))]
  ""
  "*
{
  check_label_emit ();
  CC_STATUS_INIT;
  mvs_check_page (0, 8, 4);
  if (REG_P (operands[2])) 
    return \"N	%0,=X'000000FF'\;SRL	%0,0(%2)\";
  return \"N	%0,=X'000000FF'\;SRL	%0,%c2\";
}")

;;
;;- Conditional jump instructions.
;;

;
; beq instruction pattern(s).
;

(define_insn "beq"
  [(set (pc)
	(if_then_else (eq (cc0)
			  (const_int 0))
		      (label_ref (match_operand 0 "" ""))
		      (pc)))]
  ""
  "*
{
  check_label_emit ();
  if (!mvs_check_label (CODE_LABEL_NUMBER (operands[0])))
    {
      mvs_check_page (0, 6, 4);
      return \"L	14,=A(%l0)\;BER	14\";
    }
  if (mvs_check_page (0, 4, 0))
    {
      mvs_check_page (0, 2, 4);
      return \"L	14,=A(%l0)\;BER	14\";
    }
  return \"BE	%l0\";
}")

;
; bne instruction pattern(s).
;

(define_insn "bne"
  [(set (pc)
	(if_then_else (ne (cc0)
			  (const_int 0))
		      (label_ref (match_operand 0 "" ""))
		      (pc)))]
  ""
  "*
{
  check_label_emit ();
  if (!mvs_check_label (CODE_LABEL_NUMBER (operands[0])))
    {
      mvs_check_page (0, 6, 4);
      return \"L	14,=A(%l0)\;BNER	14\";
    }
  if (mvs_check_page (0, 4, 0))
    {
      mvs_check_page (0, 2, 4);
      return \"L	14,=A(%l0)\;BNER	14\";
    }
  return \"BNE	%l0\";
}")

;
; bgt instruction pattern(s).
;

(define_insn "bgt"
  [(set (pc)
	(if_then_else (gt (cc0)
			  (const_int 0))
		      (label_ref (match_operand 0 "" ""))
		      (pc)))]
  ""
  "*
{
  check_label_emit ();
  if (!mvs_check_label (CODE_LABEL_NUMBER (operands[0])))
    {
      mvs_check_page (0, 6, 4);
      return \"L	14,=A(%l0)\;BHR	14\";
    }
  if (mvs_check_page (0, 4, 0))
    {
      mvs_check_page (0, 2, 4);
      return \"L	14,=A(%l0)\;BHR	14\";
    }
  return \"BH	%l0\";
}")

;
; bgtu instruction pattern(s).
;

(define_insn "bgtu"
  [(set (pc)
	(if_then_else (gtu (cc0)
			   (const_int 0))
		      (label_ref (match_operand 0 "" ""))
		      (pc)))]
  ""
  "*
{
  check_label_emit ();
  if (!mvs_check_label (CODE_LABEL_NUMBER (operands[0])))
    {
      mvs_check_page (0, 6, 4);
      return \"L	14,=A(%l0)\;BHR	14\";
    }
  if (mvs_check_page (0, 4, 0))
    {
      mvs_check_page (0, 2, 4);
      return \"L	14,=A(%l0)\;BHR	14\";
    }
  return \"BH	%l0\";
}")

;
; blt instruction pattern(s).
;

(define_insn "blt"
  [(set (pc)
	(if_then_else (lt (cc0)
			  (const_int 0))
		      (label_ref (match_operand 0 "" ""))
		      (pc)))]
  ""
  "*
{
  check_label_emit ();
  if (!mvs_check_label (CODE_LABEL_NUMBER (operands[0])))
    {
      mvs_check_page (0, 6, 4);
      return \"L	14,=A(%l0)\;BLR	14\";
    }
  if (mvs_check_page (0, 4, 0))
    {
      mvs_check_page (0, 2, 4);
      return \"L	14,=A(%l0)\;BLR	14\";
    }
  return \"BL	%l0\";
}")

;
; bltu instruction pattern(s).
;

(define_insn "bltu"
  [(set (pc)
	(if_then_else (ltu (cc0)
			   (const_int 0))
		      (label_ref (match_operand 0 "" ""))
		      (pc)))]
  ""
  "*
{
  check_label_emit ();
  if (!mvs_check_label (CODE_LABEL_NUMBER (operands[0])))
    {
      mvs_check_page (0, 6, 4);
      return \"L	14,=A(%l0)\;BLR	14\";
    }
  if (mvs_check_page (0, 4, 0))
    {
      mvs_check_page (0, 2, 4);
      return \"L	14,=A(%l0)\;BLR	14\";
    }
  return \"BL	%l0\";
}")

;
; bge instruction pattern(s).
;

(define_insn "bge"
  [(set (pc)
	(if_then_else (ge (cc0)
			  (const_int 0))
		      (label_ref (match_operand 0 "" ""))
		      (pc)))]
  ""
  "*
{
  check_label_emit ();
  if (!mvs_check_label (CODE_LABEL_NUMBER (operands[0])))
    {
      mvs_check_page (0, 6, 4);
      return \"L	14,=A(%l0)\;BNLR	14\";
    }
  if (mvs_check_page (0, 4, 0))
    {
      mvs_check_page (0, 2, 4);
      return \"L	14,=A(%l0)\;BNLR	14\";
    }
  return \"BNL	%l0\";
}")

;
; bgeu instruction pattern(s).
;

(define_insn "bgeu"
  [(set (pc)
	(if_then_else (geu (cc0)
			   (const_int 0))
		      (label_ref (match_operand 0 "" ""))
		      (pc)))]
  ""
  "*
{
  check_label_emit ();
  if (!mvs_check_label (CODE_LABEL_NUMBER (operands[0])))
    {
      mvs_check_page (0, 6, 4);
      return \"L	14,=A(%l0)\;BNLR	14\";
    }
  if (mvs_check_page (0, 4, 0))
    {
      mvs_check_page (0, 2, 4);
      return \"L	14,=A(%l0)\;BNLR	14\";
    }
  return \"BNL	%l0\";
}")

;
; ble instruction pattern(s).
;

(define_insn "ble"
  [(set (pc)
	(if_then_else (le (cc0)
			  (const_int 0))
		      (label_ref (match_operand 0 "" ""))
		      (pc)))]
  ""
  "*
{
  check_label_emit ();
  if (!mvs_check_label (CODE_LABEL_NUMBER (operands[0])))
    {
      mvs_check_page (0, 6, 4);
      return \"L	14,=A(%l0)\;BNHR	14\";
    }
  if (mvs_check_page (0, 4, 0))
    {
      mvs_check_page (0, 2, 4);
      return \"L	14,=A(%l0)\;BNHR	14\";
    }
  return \"BNH	%l0\";
}")

;
; bleu instruction pattern(s).
;

(define_insn "bleu"
  [(set (pc)
	(if_then_else (leu (cc0)
			   (const_int 0))
		      (label_ref (match_operand 0 "" ""))
		      (pc)))]
  ""
  "*
{
  check_label_emit ();
  if (!mvs_check_label (CODE_LABEL_NUMBER (operands[0])))
    {
      mvs_check_page (0, 6, 4);
      return \"L	14,=A(%l0)\;BNHR	14\";
    }
  if (mvs_check_page (0, 4, 0))
    {
      mvs_check_page (0, 2, 4);
      return \"L	14,=A(%l0)\;BNHR	14\";
    }
  return \"BNH	%l0\";
}")

;;
;;- Negated conditional jump instructions.
;;

(define_insn ""
  [(set (pc)
	(if_then_else (eq (cc0)
			  (const_int 0))
		      (pc)
		      (label_ref (match_operand 0 "" ""))))]
  ""
  "*
{
  check_label_emit ();
  if (!mvs_check_label (CODE_LABEL_NUMBER (operands[0])))
    {
      mvs_check_page (0, 6, 4);
      return \"L	14,=A(%l0)\;BNER	14\";
    }
  if (mvs_check_page (0, 4, 0))
    {
      mvs_check_page (0, 2, 4);
      return \"L	14,=A(%l0)\;BNER	14\";
    }
  return \"BNE	%l0\";
}")

(define_insn ""
  [(set (pc)
	(if_then_else (ne (cc0)
			  (const_int 0))
		      (pc)
		      (label_ref (match_operand 0 "" ""))))]
  ""
  "*
{
  check_label_emit ();
  if (!mvs_check_label (CODE_LABEL_NUMBER (operands[0])))
    {
      mvs_check_page (0, 6, 4);
      return \"L	14,=A(%l0)\;BER	14\";
    }
  if (mvs_check_page (0, 4, 0))
    {
      mvs_check_page (0, 2, 4);
      return \"L	14,=A(%l0)\;BER	14\";
    }
  return \"BE	%l0\";
}")

(define_insn ""
  [(set (pc)
	(if_then_else (gt (cc0)
			  (const_int 0))
		      (pc)
		      (label_ref (match_operand 0 "" ""))))]
  ""
  "*
{
  check_label_emit ();
  if (!mvs_check_label (CODE_LABEL_NUMBER (operands[0])))
    {
      mvs_check_page (0, 6, 4);
      return \"L	14,=A(%l0)\;BNHR	14\";
    }
  if (mvs_check_page (0, 4, 0))
    {
      mvs_check_page (0, 2, 4);
      return \"L	14,=A(%l0)\;BNHR	14\";
    }
  return \"BNH	%l0\";
}")

(define_insn ""
  [(set (pc)
	(if_then_else (gtu (cc0)
			   (const_int 0))
		      (pc)
		      (label_ref (match_operand 0 "" ""))))]
  ""
  "*
{
  check_label_emit ();
  if (!mvs_check_label (CODE_LABEL_NUMBER (operands[0])))
    {
      mvs_check_page (0, 6, 4);
      return \"L	14,=A(%l0)\;BNHR	14\";
    }
  if (mvs_check_page (0, 4, 0))
    {
      mvs_check_page (0, 2, 4);
      return \"L	14,=A(%l0)\;BNHR	14\";
    }
  return \"BNH	%l0\";
}")

(define_insn ""
  [(set (pc)
	(if_then_else (lt (cc0)
			  (const_int 0))
		      (pc)
		      (label_ref (match_operand 0 "" ""))))]
  ""
  "*
{
  check_label_emit ();
  if (!mvs_check_label (CODE_LABEL_NUMBER (operands[0])))
    {
      mvs_check_page (0, 6, 4);
      return \"L	14,=A(%l0)\;BNLR	14\";
    }
  if (mvs_check_page (0, 4, 0))
    {
      mvs_check_page (0, 2, 4);
      return \"L	14,=A(%l0)\;BNLR	14\";
    }
  return \"BNL	%l0\";
}")

(define_insn ""
  [(set (pc)
	(if_then_else (ltu (cc0)
			   (const_int 0))
		      (pc)
		      (label_ref (match_operand 0 "" ""))))]
  ""
  "*
{
  check_label_emit ();
  if (!mvs_check_label (CODE_LABEL_NUMBER (operands[0])))
    {
      mvs_check_page (0, 6, 4);
      return \"L	14,=A(%l0)\;BNLR	14\";
    }
  if (mvs_check_page (0, 4, 0))
    {
      mvs_check_page (0, 2, 4);
      return \"L	14,=A(%l0)\;BNLR	14\";
    }
  return \"BNL	%l0\";
}")

(define_insn ""
  [(set (pc)
	(if_then_else (ge (cc0)
			  (const_int 0))
		      (pc)
		      (label_ref (match_operand 0 "" ""))))]
  ""
  "*
{
  check_label_emit ();
  if (!mvs_check_label (CODE_LABEL_NUMBER (operands[0])))
    {
      mvs_check_page (0, 6, 4);
      return \"L	14,=A(%l0)\;BLR	14\";
    }
  if (mvs_check_page (0, 4, 0))
    {
      mvs_check_page (0, 2, 4);
      return \"L	14,=A(%l0)\;BLR	14\";
    }
  return \"BL	%l0\";
}")

(define_insn ""
  [(set (pc)
	(if_then_else (geu (cc0)
			   (const_int 0))
		      (pc)
		      (label_ref (match_operand 0 "" ""))))]
  ""
  "*
{
  check_label_emit ();
  if (!mvs_check_label (CODE_LABEL_NUMBER (operands[0])))
    {
      mvs_check_page (0, 6, 4);
      return \"L	14,=A(%l0)\;BLR	14\";
    }
  if (mvs_check_page (0, 4, 0))
    {
      mvs_check_page (0, 2, 4);
      return \"L	14,=A(%l0)\;BLR	14\";
    }
  return \"BL	%l0\";
}")

(define_insn ""
  [(set (pc)
	(if_then_else (le (cc0)
			  (const_int 0))
		      (pc)
		      (label_ref (match_operand 0 "" ""))))]
  ""
  "*
{
  check_label_emit ();
  if (!mvs_check_label (CODE_LABEL_NUMBER (operands[0])))
    {
      mvs_check_page (0, 6, 4);
      return \"L	14,=A(%l0)\;BHR	14\";
    }
  if (mvs_check_page (0, 4, 0))
    {
      mvs_check_page (0, 2, 4);
      return \"L	14,=A(%l0)\;BHR	14\";
    }
  return \"BH	%l0\";
}")

(define_insn ""
  [(set (pc)
	(if_then_else (leu (cc0)
			   (const_int 0))
		      (pc)
		      (label_ref (match_operand 0 "" ""))))]
  ""
  "*
{
  check_label_emit ();
  if (!mvs_check_label (CODE_LABEL_NUMBER (operands[0])))
    {
      mvs_check_page (0, 6, 4);
      return \"L	14,=A(%l0)\;BHR	14\";
    }
  if (mvs_check_page (0, 4, 0))
    {
      mvs_check_page (0, 2, 4);
      return \"L	14,=A(%l0)\;BHR	14\";
    }
  return \"BH	%l0\";
}")

;;
;;- Subtract one and jump if not zero.
;;

(define_insn ""
  [(set (pc)
	(if_then_else
	 (ne (plus:SI (match_operand:SI 0 "register_operand" "+d")
		      (const_int -1))
	     (const_int 0))
	 (label_ref (match_operand 1 "" ""))
	 (pc)))
   (set (match_dup 0)
	(plus:SI (match_dup 0)
		 (const_int -1)))]
  ""
  "*
{
  check_label_emit ();
  if (!mvs_check_label (CODE_LABEL_NUMBER (operands[1])))
    {
      mvs_check_page (0, 6, 4);
      return \"L	14,=A(%l1)\;BCTR	%0,14\";
    }
  if (mvs_check_page (0, 4, 0))
    {
      mvs_check_page (0, 2, 4);
      return \"L	14,=A(%l1)\;BCTR	%0,14\";
    }
  return \"BCT	%0,%l1\";
}")

(define_insn ""
  [(set (pc)
	(if_then_else
	 (eq (plus:SI (match_operand:SI 0 "register_operand" "+d")
		      (const_int -1))
	     (const_int 0))
	 (pc)
	 (label_ref (match_operand 1 "" ""))))
   (set (match_dup 0)
	(plus:SI (match_dup 0)
		 (const_int -1)))]
  ""
  "*
{
  check_label_emit ();
  if (!mvs_check_label (CODE_LABEL_NUMBER (operands[1])))
    {
      mvs_check_page (0, 6, 4);
      return \"L	14,=A(%l1)\;BCTR	%0,14\";
    }
  if (mvs_check_page (0, 4, 0))
    {
      mvs_check_page (0, 2, 4);
      return \"L	14,=A(%l1)\;BCTR	%0,14\";
    }
  return \"BCT	%0,%l1\";
}")

;;
;;- Unconditional jump instructions.
;;

;
; jump instruction pattern(s).
;

(define_insn "jump"
  [(set (pc)
	(label_ref (match_operand 0 "" "")))]
  ""
  "*
{
  check_label_emit ();
  if (!mvs_check_label (CODE_LABEL_NUMBER (operands[0])))
    {
      mvs_check_page (0, 6, 4);
      return \"L	14,=A(%l0)\;BR	14\";
    }
  if (mvs_check_page (0, 4, 0))
    {
      mvs_check_page (0, 2, 4);
      return \"L	14,=A(%l0)\;BR	14\";
    }
  return \"B	%l0\";
}")

;
; indirect-jump instruction pattern(s).
;

(define_insn "indirect_jump"
  [(set (pc) (match_operand:SI 0 "general_operand" "r"))]
  "(GET_CODE (operands[0]) != MEM )"
  "*
{
  check_label_emit ();
  mvs_check_page (0, 2, 0);
  return \"BR	%0\";
}")

;
; tablejump instruction pattern(s).
;

(define_insn "tablejump"
  [(set (pc)
	(match_operand:SI 0 "general_operand" "am"))
   (use (label_ref (match_operand 1 "" "")))]
  ""
  "*
{
  check_label_emit ();
  if (REG_P (operands[0]))
    {
      mvs_check_page (0, 6, 0);
      return \"BR	%0\;DS	0F\";
    }
  mvs_check_page (0, 10, 0);
  return \"L	14,%0\;BR	14\;DS	0F\";
}")

;;
;;- Jump to subroutine.
;;
;; For the C/370 environment the internal functions, ie. sqrt, are called with
;; a non-standard form.  So, we must fix it here.  There's no BM like IBM.
;;

;
; call instruction pattern(s).
;

(define_insn "call"
  [(call (match_operand:QI 0 "memory_operand" "m")
	 (match_operand:SI 1 "immediate_operand" "i"))]
  ""
  "*
{
  static char temp[128];
  int i = STACK_POINTER_OFFSET;

  check_label_emit ();
  if (mvs_function_check (XSTR (operands[0], 0)))
    {
      mvs_check_page (0, 22, 4);
      sprintf ( temp, \"LA	1,136(,13)\;ST	1,%d(,13)\;LA	1,%d(,13)\;L	15,%%0\;BALR	14,15\;LD	0,136(,13)\",
	     i - 4, i - 4 );
    }
  else
    {
      mvs_check_page (0, 10, 4);
      sprintf ( temp, \"LA	1,%d(,13)\;L	15,%%0\;BALR	14,15\", i );
    }
  return temp;
}")

;
; call_value instruction pattern(s).
;

(define_insn "call_value"
  [(set (match_operand 0 "" "rf")
 	(call (match_operand:QI 1 "memory_operand" "m")
 	      (match_operand:SI 2 "general_operand" "i")))]
  ""
  "*
{
  static char temp[128];
  int i = STACK_POINTER_OFFSET;

  check_label_emit ();
  if (mvs_function_check (XSTR (operands[1], 0)))
    {
      mvs_check_page (0, 22, 4);
      sprintf ( temp, \"LA	1,136(,13)\;ST	1,%d(,13)\;LA	1,%d(,13)\;L	15,%%1\;BALR	14,15\;LD	0,136(,13)\",
	   i - 4, i - 4 );
    }
  else
    {
      mvs_check_page (0, 10, 4);
      sprintf ( temp, \"LA	1,%d(,13)\;L	15,%%1\;BALR	14,15\", i );
    }
  return temp;
}")

(define_insn ""
  [(call (mem:QI (match_operand:SI 0 "" "i"))
	 (match_operand:SI 1 "general_operand" "g"))]
  "GET_CODE (operands[0]) == SYMBOL_REF"
  "*
{
  static char temp[128];
  int i = STACK_POINTER_OFFSET;

  check_label_emit ();
  if (mvs_function_check (XSTR (operands[0], 0)))
    {
      mvs_check_page (0, 22, 4);
      sprintf ( temp, \"LA	1,136(,13)\;ST	1,%d(,13)\;LA	1,%d(,13)\;L	15,%%0\;BALR	14,15\;LD	0,136(,13)\",
	   i - 4, i - 4 );
    }
  else
    {
      mvs_check_page (0, 10, 4);
      sprintf ( temp, \"LA	1,%d(,13)\;L	15,%%0\;BALR	14,15\", i );
    }
  return temp;
}")

(define_insn ""
  [(set (match_operand 0 "" "rf")
	(call (mem:QI (match_operand:SI 1 "" "i"))
	      (match_operand:SI 2 "general_operand" "g")))]
  "GET_CODE (operands[1]) == SYMBOL_REF"
  "*
{
  static char temp[128];
  int i = STACK_POINTER_OFFSET;

  check_label_emit ();
  if (mvs_function_check (XSTR (operands[1], 0)))
    {
      mvs_check_page (0, 22, 4);
      sprintf ( temp, \"LA	1,136(,13)\;ST	1,%d(,13)\;LA	1,%d(,13)\;L	15,%%1\;BALR	14,15\;LD	0,136(,13)\",
	   i - 4, i - 4 );
    }
  else
    {
      mvs_check_page (0, 10, 4);
      sprintf ( temp, \"LA	1,%d(,13)\;L	15,%%1\;BALR	14,15\", i );
    }
  return temp;
}")


;;
;;- Miscellaneous instructions.
;;

;
; nop instruction pattern(s).
;

(define_insn "nop"
  [(const_int 0)]
  ""
  "*
{
  check_label_emit ();
  mvs_check_page (0, 2, 0);
  return \"LR	0,0\";
}")

