aboutsummaryrefslogtreecommitdiff
path: root/gcc/config/s390/s390.md
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/config/s390/s390.md')
-rw-r--r--gcc/config/s390/s390.md5834
1 files changed, 5834 insertions, 0 deletions
diff --git a/gcc/config/s390/s390.md b/gcc/config/s390/s390.md
new file mode 100644
index 0000000..5c6b183
--- /dev/null
+++ b/gcc/config/s390/s390.md
@@ -0,0 +1,5834 @@
+;;- Machine description for GNU compiler -- S/390 / zSeries version.
+;; Copyright (C) 1999, 2000, 2001 Free Software Foundation, Inc.
+;; Contributed by Hartmut Penner (hpenner@de.ibm.com) and
+;; Ulrich Weigand (weigand@de.ibm.com).
+;; This file is part of GNU CC.
+
+;; GNU CC is free software; you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation; either version 2, or (at your option)
+;; any later version.
+
+;; GNU CC is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+;; GNU General Public License for more details.
+
+;; You should have received a copy of the GNU General Public License
+;; along with GNU CC; see the file COPYING. If not, write to
+;; the Free Software Foundation, 59 Temple Place - Suite 330,
+;; Boston, MA 02111-1307, USA.
+
+;;
+;; Special constraints for s/390 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).
+;; Q -- A memory reference without index-register.
+;; S -- Valid operand for the LARL instruction.
+;;
+;; Special formats used for outputting 390 instructions.
+;;
+;; %b -- Print a constant byte integer. xy
+;; %h -- Print a signed 16-bit. wxyz
+;; %N -- Print next register (second word of a DImode reg) or next word.
+;; %M -- Print next register (second word of a TImode reg) or next word.
+;; %O -- Print the offset of a memory reference (PLUS (REG) (CONST_INT)).
+;; %R -- Print the register of a memory reference (PLUS (REG) (CONST_INT)).
+;;
+;; We have a special constraint 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
+;;
+
+;; Insn type. Used to default other attribute values.
+
+;
+; Insn are devide in two classes:
+; mem: Use of base and/or index register for address generation
+; reg: Use of second and third register not for address generation
+;
+
+(define_attr "atype" "mem,reg" (const_string "reg"))
+
+;
+; Insn may take 1,2,3 or many cycles
+; For the scheduling it does not matter, if a instruction has
+; a issue_delay from 4 or more cycles, since the address dependency
+; between two insns needs at least 4 cycles.
+;
+
+(define_attr "cycle" "1,2,3,n" (const_string "1"))
+
+;
+; There are three classes of insns:
+; set: instruction setting a (potential) address relevant register
+; xset: instruction setting no address relevant register
+; la: instruction setting a (potential) address relevant register,
+; but behave 'better' on the pipeline
+;
+
+(define_attr "type" "set,xset,la" (const_string "xset"))
+
+;
+; Set operations changing a target register, which could be used for
+; address generation. Adjust cost will check, if realy applicable.
+;
+
+(define_function_unit "memory" 1 0
+ (and (eq_attr "type" "set")
+ (eq_attr "cycle" "1"))
+ 5 1 [(eq_attr "atype" "mem")] )
+
+(define_function_unit "memory" 1 0
+ (and (eq_attr "type" "set")
+ (eq_attr "cycle" "2")) 5 2)
+
+(define_function_unit "memory" 1 0
+ (and (eq_attr "type" "set")
+ (eq_attr "cycle" "3")) 5 3)
+
+(define_function_unit "memory" 1 0
+ (and (eq_attr "type" "set")
+ (eq_attr "cycle" "n")) 5 4)
+
+(define_function_unit "memory" 1 0
+ (eq_attr "type" "la") 2 1)
+
+;
+; xset insns, which don't set any valid address register.
+; Only the issue delay matters.
+;
+
+(define_function_unit "memory" 1 0
+ (and (eq_attr "type" "xset")
+ (eq_attr "cycle" "1")) 1 1)
+
+(define_function_unit "memory" 1 0
+ (and (eq_attr "type" "xset")
+ (eq_attr "cycle" "2")) 1 2)
+
+(define_function_unit "memory" 1 0
+ (and (eq_attr "type" "xset")
+ (eq_attr "cycle" "3")) 1 3)
+
+(define_function_unit "memory" 1 0
+ (and (eq_attr "type" "xset")
+ (eq_attr "cycle" "n")) 1 4)
+
+; Operand type. Used to default length attribute values
+
+(define_attr "op_type"
+ "NN,E,RR,RRE,RX,RS,RSI,RI,SI,S,SS,SSE,RXE,RSE,RIL,RIE"
+ (const_string "RX"))
+
+;; Length in bytes.
+
+(define_attr "length" ""
+(cond [ (eq_attr "op_type" "E") (const_int 2)
+ (eq_attr "op_type" "RR") (const_int 2)
+ (eq_attr "op_type" "RX") (const_int 4)
+ (eq_attr "op_type" "RI") (const_int 4)
+ (eq_attr "op_type" "RRE") (const_int 4)
+ (eq_attr "op_type" "RS") (const_int 4)
+ (eq_attr "op_type" "RSI") (const_int 4)
+ (eq_attr "op_type" "RX") (const_int 4)
+ (eq_attr "op_type" "S") (const_int 4)
+ (eq_attr "op_type" "SI") (const_int 4)
+ (eq_attr "op_type" "SS") (const_int 6)
+ (eq_attr "op_type" "SSE") (const_int 6)
+ (eq_attr "op_type" "RXE") (const_int 6)
+ (eq_attr "op_type" "RSE") (const_int 6)
+ (eq_attr "op_type" "RIL") (const_int 6)]
+ (const_int 4)))
+
+;; Define attributes for `asm' insns.
+
+(define_asm_attributes [(set_attr "type" "xset")
+ (set_attr "op_type" "NN")])
+
+;;
+;; Condition Codes
+;;
+;
+; CCL: Zero Nonzero Zero Nonzero (AL, ALR, SL, SLR, N, NC, NI, NR, O, OC, OI, OR, X, XC, XI, XR)
+; CCA: Zero <Zero >Zero Overflow (A, AR, AH, AHI, S, SR, SH, SHI, LTR, LCR, LNR, LPR, SLA, SLDA, SLA, SRDA)
+; CCU: Equal ULess UGreater -- (CL, CLR, CLI, CLM)
+; CCS: Equal SLess SGreater -- (C, CR, CH, CHI, ICM)
+; CCT: Zero Mixed Mixed Ones (TM, TMH, TML)
+
+; CCZ -> CCL / CCZ1
+; CCZ1 -> CCA/CCU/CCS/CCT
+; CCS -> CCA
+
+; String: CLC, CLCL, CLCLE, CLST, CUSE, MVCL, MVCLE, MVPG, MVST, SRST
+; Clobber: CKSM, CFC, CS, CDS, CUUTF, CUTFU, PLO, SPM, STCK, STCKE, TS, TRT, TRE, UPT
+
+
+;;
+;;- Compare instructions.
+;;
+
+(define_expand "cmpdi"
+ [(set (reg:CC 33)
+ (compare:CC (match_operand:DI 0 "register_operand" "")
+ (match_operand:DI 1 "general_operand" "")))]
+ "TARGET_64BIT"
+ "
+{
+ s390_compare_op0 = operands[0];
+ s390_compare_op1 = operands[1];
+ DONE;
+}")
+
+(define_expand "cmpsi"
+ [(set (reg:CC 33)
+ (compare:CC (match_operand:SI 0 "register_operand" "")
+ (match_operand:SI 1 "general_operand" "")))]
+ ""
+ "
+{
+ s390_compare_op0 = operands[0];
+ s390_compare_op1 = operands[1];
+ DONE;
+}")
+
+;(define_expand "cmphi"
+; [(set (reg:CC 33)
+; (compare:CC (match_operand:HI 0 "register_operand" "")
+; (match_operand:HI 1 "general_operand" "")))]
+; ""
+; "
+;{
+; s390_compare_op0 = operands[0];
+; s390_compare_op1 = operands[1];
+; DONE;
+;}")
+
+;(define_expand "cmpqi"
+; [(set (reg:CC 33)
+; (compare:CC (match_operand:QI 0 "register_operand" "")
+; (match_operand:QI 1 "general_operand" "")))]
+; ""
+; "
+;{
+; s390_compare_op0 = operands[0];
+; s390_compare_op1 = operands[1];
+; DONE;
+;}")
+
+(define_expand "cmpdf"
+ [(set (reg:CC 33)
+ (compare:CC (match_operand:DF 0 "register_operand" "")
+ (match_operand:DF 1 "general_operand" "")))]
+ "TARGET_HARD_FLOAT"
+ "
+{
+ s390_compare_op0 = operands[0];
+ s390_compare_op1 = operands[1];
+ DONE;
+}")
+
+(define_expand "cmpsf"
+ [(set (reg:CC 33)
+ (compare:CC (match_operand:SF 0 "register_operand" "")
+ (match_operand:SF 1 "general_operand" "")))]
+ "TARGET_HARD_FLOAT"
+ "
+{
+ s390_compare_op0 = operands[0];
+ s390_compare_op1 = operands[1];
+ DONE;
+}")
+
+
+; DI instructions
+
+(define_insn "*cmpdi_tm2"
+ [(set (reg 33)
+ (compare (zero_extract:DI (match_operand:DI 0 "register_operand" "d")
+ (match_operand:DI 1 "const1_operand" "")
+ (match_operand:DI 2 "immediate_operand" "I"))
+ (const_int 0)))]
+ "s390_match_ccmode(insn, CCTmode) &&
+ INTVAL(operands[2]) >= 0 && INTVAL(operands[2]) < 64"
+ "*
+{
+ if (INTVAL (operands[2]) > 47)
+ {
+ operands[1] = GEN_INT (1 << (63 - INTVAL(operands[2])));
+ return \"tmll\\t%0,%x1\";
+ }
+ else if (INTVAL (operands[2]) > 31)
+ {
+ operands[1] = GEN_INT (1 << (47 - INTVAL(operands[2])));
+ return \"tmlh\\t%0,%x1\";
+ }
+ else if (INTVAL (operands[2]) > 15)
+ {
+ operands[1] = GEN_INT (1 << (31 - INTVAL(operands[2])));
+ return \"tmhl\\t%0,%x1\";
+ }
+ operands[1] = GEN_INT (1 << (15 - INTVAL(operands[2])));
+ return \"tmhh\\t%0,%x1\";
+}"
+ [(set_attr "op_type" "RX")
+ (set_attr "type" "xset")])
+
+
+(define_insn "*cmpdi_tm"
+ [(set (reg 33)
+ (compare (and:DI (match_operand:DI 0 "register_operand" "%d")
+ (match_operand:DI 1 "tmxx_operand" "Lm"))
+ (const_int 0)))]
+ "s390_match_ccmode(insn, CCTmode)"
+ "*
+{
+ unsigned HOST_WIDEST_INT i;
+ if (GET_CODE (operands[1]) == MEM &&
+ GET_CODE (XEXP (operands[1],0)) == SYMBOL_REF &&
+ CONSTANT_POOL_ADDRESS_P (XEXP (operands[1],0)))
+ {
+ operands[1] = get_pool_constant (XEXP (operands[1],0));
+ }
+
+ i = (unsigned HOST_WIDEST_INT) INTVAL (operands[1]);
+
+ if (i >= 0x1000000000000ULL)
+ {
+ operands[1] = GEN_INT (i >> 48);
+ return \"tmhh\\t%0,%x1\";
+ }
+ else if (i > 0x100000000ULL)
+ {
+ operands[1] = GEN_INT (i >> 32);
+ return \"tmhl\\t%0,%x1\";
+ }
+ else if (i >= 0x10000ULL)
+ {
+ operands[1] = GEN_INT (i >> 16);
+ return \"tmlh\\t%0,%x1\";
+ }
+ else
+ return \"tmll\\t%0,%x1\";
+}"
+ [(set_attr "op_type" "RX")
+ (set_attr "type" "xset")])
+
+
+(define_insn "*ltgr"
+ [(set (reg 33)
+ (compare (match_operand:DI 0 "register_operand" "d")
+ (match_operand:DI 1 "const0_operand" "")))
+ (set (match_operand:DI 2 "register_operand" "=d")
+ (match_dup 0))]
+ "s390_match_ccmode(insn, CCSmode) && TARGET_64BIT"
+ "ltgr\\t%2,%0"
+ [(set_attr "op_type" "RRE")
+ (set_attr "type" "set")])
+
+(define_insn "*cmpdi_ccs_0_64"
+ [(set (reg 33)
+ (compare (match_operand:DI 0 "register_operand" "d")
+ (match_operand:DI 1 "const0_operand" "")))]
+ "s390_match_ccmode(insn, CCSmode) && TARGET_64BIT"
+ "ltgr\\t%0,%0"
+ [(set_attr "op_type" "RRE")
+ (set_attr "type" "set")])
+
+(define_insn "*cmpdi_ccs_0_31"
+ [(set (reg 33)
+ (compare (match_operand:DI 0 "register_operand" "d")
+ (match_operand:DI 1 "const0_operand" "")))]
+ "s390_match_ccmode(insn, CCSmode)"
+ "srda\\t%0,0"
+ [(set_attr "op_type" "RS")
+ (set_attr "type" "set")])
+
+(define_insn "*cmpdi_ccs"
+ [(set (reg 33)
+ (compare (match_operand:DI 0 "register_operand" "d,d,d")
+ (match_operand:DI 1 "general_operand" "d,K,m")))]
+ "s390_match_ccmode(insn, CCSmode) && TARGET_64BIT"
+ "@
+ cgr\\t%0,%1
+ cghi\\t%0,%c1
+ cg\\t%0,%1"
+ [(set_attr "op_type" "RRE,RI,RXE")
+ (set_attr "atype" "reg,reg,mem")])
+
+(define_insn "*cmpdi_ccu"
+ [(set (reg 33)
+ (compare (match_operand:DI 0 "register_operand" "d,d")
+ (match_operand:DI 1 "general_operand" "d,m")))]
+ "s390_match_ccmode(insn, CCUmode) && TARGET_64BIT"
+ "@
+ clgr\\t%0,%1
+ clg\\t%0,%1"
+ [(set_attr "op_type" "RRE,RXE")
+ (set_attr "atype" "reg,mem")])
+
+(define_insn "*cmpdi_ccu_mem"
+ [(set (reg 33)
+ (compare (match_operand:DI 0 "s_operand" "oQ")
+ (match_operand:DI 1 "s_operand" "oQ")))]
+ "s390_match_ccmode(insn, CCUmode)"
+ "clc\\t%O0(8,%R0),%1"
+ [(set_attr "op_type" "SS")
+ (set_attr "atype" "mem")])
+
+; SI instructions
+
+(define_insn "*cmpsi_cct"
+ [(set (reg 33)
+ (compare (zero_extract:SI (match_operand:SI 0 "register_operand" "%d")
+ (match_operand:SI 1 "const1_operand" "")
+ (match_operand:SI 2 "immediate_operand" "I"))
+ (const_int 0)))]
+ "s390_match_ccmode(insn, CCTmode) &&
+ INTVAL(operands[2]) >= 0 && INTVAL(operands[2]) < 32"
+ "*
+{
+ if (INTVAL (operands[2]) > 15)
+ {
+ operands[1] = GEN_INT (1 << (31 - INTVAL(operands[2])));
+ return \"tml\\t%0,%x1\";
+ }
+ operands[1] = GEN_INT (1 << (15 - INTVAL(operands[2])));
+ return \"tmh\\t%0,%x1\";
+}"
+ [(set_attr "op_type" "RI")
+ (set_attr "type" "xset")])
+
+(define_insn "*cmpsi_tm"
+ [(set (reg 33)
+ (compare (and:SI (match_operand:SI 0 "register_operand" "%d")
+ (match_operand:SI 1 "tmxx_operand" "Lm"))
+ (const_int 0)))]
+ "s390_match_ccmode(insn, CCTmode)"
+ "*
+{
+ unsigned long i;
+ if (GET_CODE (operands[1]) == MEM &&
+ GET_CODE (XEXP (operands[1],0)) == SYMBOL_REF &&
+ CONSTANT_POOL_ADDRESS_P (XEXP (operands[1],0)))
+ {
+ operands[1] = get_pool_constant (XEXP (operands[1],0));
+ }
+
+ i = (unsigned long) INTVAL (operands[1]);
+ if (i > 0xffff)
+ {
+ operands[1] = GEN_INT (i / 0x10000);
+ return \"tmh\\t%0,%x1\";
+ }
+ return \"tml\\t%0,%x1\";
+}"
+ [(set_attr "op_type" "RX")
+ (set_attr "type" "xset")])
+
+
+(define_insn "*ltr"
+ [(set (reg 33)
+ (compare (match_operand:SI 0 "register_operand" "d")
+ (match_operand:SI 1 "const0_operand" "")))
+ (set (match_operand:SI 2 "register_operand" "=d")
+ (match_dup 0))]
+ "s390_match_ccmode(insn, CCSmode)"
+ "ltr\\t%2,%0"
+ [(set_attr "op_type" "RR")
+ (set_attr "type" "set")])
+
+(define_insn "*icm15"
+ [(set (reg 33)
+ (compare (match_operand:SI 0 "s_operand" "Qo")
+ (match_operand:SI 1 "const0_operand" "")))
+ (set (match_operand:SI 2 "register_operand" "=d")
+ (match_dup 0))]
+ "s390_match_ccmode(insn, CCSmode)"
+ "icm\\t%2,15,%0"
+ [(set_attr "op_type" "RS")
+ (set_attr "atype" "mem")
+ (set_attr "type" "set")])
+
+(define_insn "*icm15_cconly"
+ [(set (reg 33)
+ (compare (match_operand:SI 0 "s_operand" "Qo")
+ (match_operand:SI 1 "const0_operand" "")))
+ (clobber (match_scratch:SI 2 "=d"))]
+ "s390_match_ccmode(insn, CCSmode)"
+ "icm\\t%2,15,%0"
+ [(set_attr "op_type" "RS")
+ (set_attr "atype" "mem")
+ (set_attr "type" "set")])
+
+(define_insn "*cmpsi_ccs_0"
+ [(set (reg 33)
+ (compare (match_operand:SI 0 "register_operand" "d")
+ (match_operand:SI 1 "const0_operand" "")))]
+ "s390_match_ccmode(insn, CCSmode)"
+ "ltr\\t%0,%0"
+ [(set_attr "op_type" "RR")
+ (set_attr "type" "set")])
+
+(define_insn "*cmpsidi_ccs"
+ [(set (reg 33)
+ (compare (match_operand:SI 0 "register_operand" "d")
+ (sign_extend:SI (match_operand:HI 1 "memory_operand" "m"))))]
+ "s390_match_ccmode(insn, CCSmode)"
+ "ch\\t%0,%1"
+ [(set_attr "op_type" "RR")
+ (set_attr "atype" "mem")
+ (set_attr "type" "xset")])
+
+(define_insn "*cmpsi_ccs"
+ [(set (reg 33)
+ (compare (match_operand:SI 0 "register_operand" "d,d,d")
+ (match_operand:SI 1 "general_operand" "d,K,m")))]
+ "s390_match_ccmode(insn, CCSmode)"
+ "@
+ cr\\t%0,%1
+ chi\\t%0,%c1
+ c\\t%0,%1"
+ [(set_attr "op_type" "RR,RI,RX")
+ (set_attr "atype" "reg,reg,mem")
+ (set_attr "type" "xset,xset,xset")])
+
+(define_insn "*cmpsi_ccu"
+ [(set (reg 33)
+ (compare (match_operand:SI 0 "register_operand" "d,d")
+ (match_operand:SI 1 "general_operand" "d,m")))]
+ "s390_match_ccmode(insn, CCUmode)"
+ "@
+ clr\\t%0,%1
+ cl\\t%0,%1"
+ [(set_attr "op_type" "RR,RX")
+ (set_attr "atype" "reg,mem")])
+
+(define_insn "*cmpsi_ccu_mem"
+ [(set (reg 33)
+ (compare (match_operand:SI 0 "s_operand" "oQ")
+ (match_operand:SI 1 "s_operand" "oQ")))]
+ "s390_match_ccmode(insn, CCUmode)"
+ "clc\\t%O0(4,%R0),%1"
+ [(set_attr "op_type" "SS")
+ (set_attr "atype" "mem")
+ (set_attr "type" "xset")])
+
+
+; HI instructions
+
+(define_insn "*icm3"
+ [(set (reg 33)
+ (compare (match_operand:HI 0 "s_operand" "Qo")
+ (match_operand:HI 1 "const0_operand" "")))
+ (set (match_operand:HI 2 "register_operand" "=d")
+ (match_dup 0))]
+ "s390_match_ccmode(insn, CCSmode)"
+ "icm\\t%2,3,%0"
+ [(set_attr "op_type" "RS")
+ (set_attr "atype" "mem")
+ (set_attr "type" "set")])
+
+(define_insn "*cmphi_cct_0"
+ [(set (reg 33)
+ (compare (match_operand:HI 0 "register_operand" "d")
+ (match_operand:HI 1 "const0_operand" "")))]
+ "s390_match_ccmode(insn, CCTmode)"
+ "tml\\t%0,65535"
+ [(set_attr "op_type" "RX")
+ (set_attr "type" "xset")])
+
+(define_insn "*cmphi_ccs_0"
+ [(set (reg 33)
+ (compare (match_operand:HI 0 "s_operand" "Qo")
+ (match_operand:HI 1 "const0_operand" "")))
+ (clobber (match_scratch:HI 2 "=d"))]
+ "s390_match_ccmode(insn, CCSmode)"
+ "icm\\t%2,3,%0"
+ [(set_attr "op_type" "RS")
+ (set_attr "atype" "mem")
+ (set_attr "type" "set")])
+
+(define_insn "*cmphi_ccu"
+ [(set (reg 33)
+ (compare (match_operand:HI 0 "register_operand" "d")
+ (match_operand:HI 1 "s_operand" "Qo")))]
+ "s390_match_ccmode(insn, CCUmode)"
+ "clm\\t%0,3,%1"
+ [(set_attr "op_type" "RS")
+ (set_attr "atype" "mem")
+ (set_attr "type" "xset")])
+
+(define_insn "*cmphi_ccu_mem"
+ [(set (reg 33)
+ (compare (match_operand:HI 0 "s_operand" "oQ")
+ (match_operand:HI 1 "s_operand" "oQ")))]
+ "s390_match_ccmode(insn, CCUmode)"
+ "clc\\t%O0(2,%R0),%1"
+ [(set_attr "op_type" "SS")
+ (set_attr "atype" "mem")
+ (set_attr "type" "xset")])
+
+
+; QI instructions
+
+(define_insn "*icm1"
+ [(set (reg 33)
+ (compare (match_operand:QI 0 "s_operand" "Qo")
+ (match_operand:QI 1 "const0_operand" "")))
+ (set (match_operand:QI 2 "register_operand" "=d")
+ (match_dup 0))]
+ "s390_match_ccmode(insn, CCSmode)"
+ "icm\\t%2,1,%0"
+ [(set_attr "op_type" "RS")
+ (set_attr "atype" "mem")
+ (set_attr "type" "set")])
+
+(define_insn "*tm_0"
+ [(set (reg 33)
+ (compare (zero_extend:SI (and:QI (match_operand:QI 0 "s_operand" "Qo")
+ (match_operand:QI 1 "immediate_operand" "")))
+ (const_int 0)))]
+ "s390_match_ccmode(insn, CCTmode) &&
+ INTVAL(operands[1]) >= 0 && INTVAL(operands[1]) < 256"
+ "tm\\t%0,%1"
+ [(set_attr "op_type" "RI")
+ (set_attr "atype" "mem")
+ (set_attr "type" "xset")])
+
+(define_insn "*cmpqi_cct_0"
+ [(set (reg 33)
+ (compare (match_operand:QI 0 "register_operand" "d")
+ (match_operand:QI 1 "const0_operand" "")))]
+ "s390_match_ccmode(insn, CCTmode)"
+ "tml\\t%0,255"
+ [(set_attr "op_type" "RI")
+ (set_attr "type" "xset")])
+
+(define_insn "*cmpqi_ccs_0"
+ [(set (reg 33)
+ (compare (match_operand:QI 0 "s_operand" "Qo")
+ (match_operand:QI 1 "const0_operand" "")))
+ (clobber (match_scratch:QI 2 "=d"))]
+ "s390_match_ccmode(insn, CCSmode)"
+ "icm\\t%2,1,%0"
+ [(set_attr "op_type" "RS")
+ (set_attr "type" "xset")])
+
+(define_insn "*cmpqi_ccu_0"
+ [(set (reg 33)
+ (compare (match_operand:QI 0 "s_operand" "Qo")
+ (match_operand:QI 1 "const0_operand" "")))]
+ "s390_match_ccmode(insn, CCUmode)"
+ "cli\\t%0,0"
+ [(set_attr "op_type" "SI")
+ (set_attr "atype" "mem")
+ (set_attr "type" "xset")])
+
+(define_insn "*cmpqi_ccu"
+ [(set (reg 33)
+ (compare (match_operand:QI 0 "register_operand" "d")
+ (match_operand:QI 1 "s_operand" "Qo")))]
+ "s390_match_ccmode(insn, CCUmode)"
+ "clm\\t%0,1,%1"
+ [(set_attr "op_type" "RS")
+ (set_attr "atype" "mem")
+ (set_attr "type" "xset")])
+
+(define_insn "*cmpqi_ccu_immed"
+ [(set (reg 33)
+ (compare (match_operand:QI 0 "s_operand" "Qo")
+ (match_operand:QI 1 "immediate_operand" "")))]
+ "s390_match_ccmode(insn, CCUmode) &&
+ INTVAL(operands[1]) >= 0 && INTVAL(operands[1]) < 256"
+ "cli\\t%0,%1"
+ [(set_attr "op_type" "SI")
+ (set_attr "atype" "mem")
+ (set_attr "type" "xset")])
+
+(define_insn "*cmpqi_ccu_mem"
+ [(set (reg 33)
+ (compare (match_operand:QI 0 "s_operand" "oQ")
+ (match_operand:QI 1 "s_operand" "oQ")))]
+ "s390_match_ccmode(insn, CCUmode)"
+ "clc\\t%O0(1,%R0),%1"
+ [(set_attr "op_type" "SS")
+ (set_attr "atype" "mem")
+ (set_attr "type" "xset")])
+
+
+; DF instructions
+
+(define_insn "*cmpdf_ccs_0"
+ [(set (reg 33)
+ (compare (match_operand:DF 0 "register_operand" "f")
+ (match_operand:DF 1 "const0_operand" "")))]
+ "s390_match_ccmode(insn, CCSmode) && TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT"
+ "ltdbr\\t%0,%0"
+ [(set_attr "op_type" "RR")
+ (set_attr "type" "set")])
+
+(define_insn "*cmpdf_ccs_0_ibm"
+ [(set (reg 33)
+ (compare (match_operand:DF 0 "register_operand" "f")
+ (match_operand:DF 1 "const0_operand" "")))]
+ "s390_match_ccmode(insn, CCSmode) && TARGET_HARD_FLOAT && TARGET_IBM_FLOAT"
+ "ltdr\\t%0,%0"
+ [(set_attr "op_type" "RR")
+ (set_attr "type" "set")])
+
+(define_insn "*cmpdf_ccs"
+ [(set (reg 33)
+ (compare (match_operand:DF 0 "register_operand" "f,f")
+ (match_operand:DF 1 "nonimmediate_operand" "f,m")))]
+ "s390_match_ccmode(insn, CCSmode) && TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT"
+ "@
+ cdbr\\t%0,%1
+ cdb\\t%0,%1"
+ [(set_attr "op_type" "RR,RX")
+ (set_attr "atype" "reg,mem")
+ (set_attr "type" "xset,xset")])
+
+(define_insn "*cmpdf_ccs_ibm"
+ [(set (reg 33)
+ (compare (match_operand:DF 0 "register_operand" "f,f")
+ (match_operand:DF 1 "nonimmediate_operand" "f,m")))]
+ "s390_match_ccmode(insn, CCSmode) && TARGET_HARD_FLOAT && TARGET_IBM_FLOAT"
+ "@
+ cdr\\t%0,%1
+ cd\\t%0,%1"
+ [(set_attr "op_type" "RR,RX")
+ (set_attr "atype" "reg,mem")
+ (set_attr "type" "xset,xset")])
+
+
+; SF instructions
+
+(define_insn "*cmpsf_ccs_0"
+ [(set (reg 33)
+ (compare (match_operand:SF 0 "register_operand" "f")
+ (match_operand:SF 1 "const0_operand" "")))]
+ "s390_match_ccmode(insn, CCSmode) && TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT"
+ "ltebr\\t%0,%0"
+ [(set_attr "op_type" "RR")
+ (set_attr "type" "set")])
+
+(define_insn "*cmpsf_ccs_0_ibm"
+ [(set (reg 33)
+ (compare (match_operand:SF 0 "register_operand" "f")
+ (match_operand:SF 1 "const0_operand" "")))]
+ "s390_match_ccmode(insn, CCSmode) && TARGET_HARD_FLOAT && TARGET_IBM_FLOAT"
+ "lter\\t%0,%0"
+ [(set_attr "op_type" "RR")
+ (set_attr "type" "set")])
+
+(define_insn "*cmpsf_ccs"
+ [(set (reg 33)
+ (compare (match_operand:SF 0 "register_operand" "f,f")
+ (match_operand:SF 1 "nonimmediate_operand" "f,m")))]
+ "s390_match_ccmode(insn, CCSmode) && TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT"
+ "@
+ cebr\\t%0,%1
+ ceb\\t%0,%1"
+ [(set_attr "op_type" "RR,RX")
+ (set_attr "atype" "reg,mem")
+ (set_attr "type" "xset,xset")])
+
+(define_insn "*cmpsf_ccs"
+ [(set (reg 33)
+ (compare (match_operand:SF 0 "register_operand" "f,f")
+ (match_operand:SF 1 "nonimmediate_operand" "f,m")))]
+ "s390_match_ccmode(insn, CCSmode) && TARGET_HARD_FLOAT && TARGET_IBM_FLOAT"
+ "@
+ cer\\t%0,%1
+ ce\\t%0,%1"
+ [(set_attr "op_type" "RR,RX")
+ (set_attr "atype" "reg,mem")
+ (set_attr "type" "xset,xset")])
+
+
+;;
+;;- Move instructions.
+;;
+
+;
+; movti instruction pattern(s).
+;
+
+(define_insn "movti"
+ [(set (match_operand:TI 0 "nonimmediate_operand" "=d,d,d,m,Q")
+ (match_operand:TI 1 "general_operand" "d,K,m,d,Q"))]
+ "TARGET_64BIT"
+ "*
+{
+ switch (which_alternative)
+ {
+ case 0: /* d <- d */
+ if (REGNO (operands[0]) == REGNO (operands[1]) + 1)
+ return \"lgr\\t%M0,%M1\;lgr\\t%0,%1\";
+ else
+ return \"lgr\\t%0,%1\;lgr\\t%M0,%M1\";
+
+ case 1: /* d <- K */
+ if (INTVAL(operands[1]) < 0)
+ return \"lghi\\t%0,-1\;lghi\\t%M0,%h1\";
+ else
+ return \"lghi\\t%0,0\;lghi\\t%M0,%h1\";
+
+ case 2: /* d <- m */
+ if (s_operand (operands[1], GET_MODE (operands[1])))
+ return \"lmg\\t%0,%M0,%1\";
+ else
+ return \"la\\t%M0,%1\;lmg\\t%0,%M0,0(%M0)\";
+
+ case 3: /* m <- d */
+ if (!s_operand (operands[0], GET_MODE (operands[0])))
+ return \"stg\\t%1,%0\;stg\\t%M1,%M0\";
+ else
+ return \"stmg\\t%1,%M1,%0\";
+
+ case 4: /* m <- m */
+ return \"mvc\\t%O0(16,%R0),%1\";
+ }
+}"
+ [(set_attr "op_type" "NN,NN,RS,RS,SS")
+ (set_attr "atype" "reg,reg,mem,mem,mem")
+ (set_attr "type" "set")
+ (set_attr "length" "12,8,10,10,*")])
+
+;
+; movdi instruction pattern(s).
+;
+
+;; If generating PIC code and operands[1] is a symbolic CONST, emit a
+;; move to get the address of the symbolic object from the GOT.
+
+(define_expand "movdi"
+ [(set (match_operand:DI 0 "general_operand" "")
+ (match_operand:DI 1 "general_operand" ""))]
+ ""
+ "
+{
+ if (CONSTANT_P (operands[1])
+ && !LEGITIMATE_CONSTANT_P (operands[1]))
+ operands[1] = force_const_mem (DImode, operands[1]);
+
+ if (TARGET_64BIT && flag_pic && SYMBOLIC_CONST (operands[1]))
+ emit_pic_move (operands, DImode);
+}")
+
+(define_insn "*movdi_64"
+ [(set (match_operand:DI 0 "nonimmediate_operand" "=d,d,d,d,m,Q")
+ (match_operand:DI 1 "general_operand" "d,K,S,m,d,Q"))]
+ "TARGET_64BIT"
+ "@
+ lgr\\t%0,%1
+ lghi\\t%0,%h1
+ larl\\t%0,%1
+ lg\\t%0,%1
+ stg\\t%1,%0
+ mvc\\t%O0(8,%R0),%1"
+ [(set_attr "op_type" "RRE,RI,RIL,RXE,RXE,SS")
+ (set_attr "atype" "reg,reg,reg,mem,mem,mem")
+ (set_attr "type" "set,set,la,set,set,set")])
+
+(define_insn "*movdi_31"
+ [(set (match_operand:DI 0 "nonimmediate_operand" "=d,d,d,m,Q")
+ (match_operand:DI 1 "general_operand" "d,K,m,d,Q"))]
+ "!TARGET_64BIT"
+ "*
+{
+ switch (which_alternative)
+ {
+ case 0: /* d <- d */
+ if (REGNO (operands[0]) == REGNO (operands[1]) + 1)
+ return \"lr\\t%N0,%N1\;lr\\t%0,%1\";
+ else
+ return \"lr\\t%0,%1\;lr\\t%N0,%N1\";
+
+ case 1: /* d <- K */
+ if (INTVAL (operands[1]) < 0)
+ return \"lhi\\t%0,-1\;lhi\\t%N0,%h1\";
+ else
+ return \"lhi\\t%0,0\;lhi\\t%N0,%h1\";
+
+ case 2: /* d <- m */
+ if (s_operand (operands[1], GET_MODE (operands[1])))
+ return \"lm\\t%0,%N0,%1\";
+ else
+ return \"la\\t%N0,%1\;lm\\t%0,%N0,0(%N0)\";
+
+ case 3: /* m <- d */
+ if (s_operand (operands[0], GET_MODE (operands[0])))
+ return \"stm\\t%1,%N1,%0\";
+ else
+ return \"st\\t%1,%0\;st\\t%N1,%N0\";
+
+ case 4: /* m <- m */
+ return \"mvc\\t%O0(8,%R0),%1\";
+ }
+}"
+ [(set_attr "op_type" "NN,NN,RS,RS,SS")
+ (set_attr "atype" "reg,reg,mem,mem,mem")
+ (set_attr "type" "set")
+ (set_attr "length" "4,8,8,8,*")])
+
+
+;
+; movsi instruction pattern(s).
+;
+
+;; If generating PIC code and operands[1] is a symbolic CONST, emit a
+;; move to get the address of the symbolic object from the GOT.
+
+(define_expand "movsi"
+ [(set (match_operand:SI 0 "general_operand" "")
+ (match_operand:SI 1 "general_operand" ""))]
+ ""
+ "
+{
+ if (CONSTANT_P (operands[1])
+ && !LEGITIMATE_CONSTANT_P (operands[1]))
+ operands[1] = force_const_mem (SImode, operands[1]);
+
+ if (flag_pic && SYMBOLIC_CONST (operands[1]))
+ emit_pic_move (operands, SImode);
+}")
+
+(define_insn "*movsi"
+ [(set (match_operand:SI 0 "nonimmediate_operand" "=d,d,d,m,Q")
+ (match_operand:SI 1 "general_operand" "d,K,m,d,Q"))]
+ ""
+ "@
+ lr\\t%0,%1
+ lhi\\t%0,%h1
+ l\\t%0,%1
+ st\\t%1,%0
+ mvc\\t%O0(4,%R0),%1"
+ [(set_attr "op_type" "RR,RI,RX,RX,SS")
+ (set_attr "atype" "reg,reg,mem,mem,mem")
+ (set_attr "type" "set")])
+
+
+;
+; movhi instruction pattern(s).
+;
+
+(define_insn "movhi"
+ [(set (match_operand:HI 0 "nonimmediate_operand" "=d,d,d,m")
+ (match_operand:HI 1 "r_or_x_or_im16_operand" "d,K,m,d"))]
+ ""
+ "@
+ lr\\t%0,%1
+ lhi\\t%0,%h1
+ lh\\t%0,%1
+ sth\\t%1,%0"
+ [(set_attr "op_type" "RR,RI,RX,RX")
+ (set_attr "atype" "reg,reg,mem,mem")
+ (set_attr "type" "xset")])
+
+
+;
+; movqi instruction pattern(s).
+;
+
+(define_insn "movqi_64"
+ [(set (match_operand:QI 0 "nonimmediate_operand" "=d,d,d,m,Q")
+ (match_operand:QI 1 "general_operand" "d,K,m,d,n"))]
+ "TARGET_64BIT"
+ "@
+ lr\\t%0,%1
+ llill\\t%0,%x1
+ llgc\\t%0,%1
+ stc\\t%1,%0
+ mvi\\t%0,%b1"
+ [(set_attr "op_type" "RR,RI,RXE,RX,SI")
+ (set_attr "atype" "reg,reg,mem,mem,mem")
+ (set_attr "type" "xset")])
+
+
+(define_insn "movqi"
+ [(set (match_operand:QI 0 "nonimmediate_operand" "=d,d,d,m,Q")
+ (match_operand:QI 1 "r_or_x_or_im16_operand" "d,n,m,d,n"))]
+ ""
+ "@
+ lr\\t%0,%1
+ lhi\\t%0,%c1
+ ic\\t%0,%1
+ stc\\t%1,%0
+ mvi\\t%0,%b1"
+ [(set_attr "op_type" "RR,RX,RX,RX,SI")
+ (set_attr "atype" "reg,reg,mem,mem,mem")
+ (set_attr "type" "xset")])
+
+
+;
+; moveqstrictqi instruction pattern(s).
+;
+
+(define_insn "*movstrictqi"
+ [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+d,m"))
+ (match_operand:QI 1 "nonimmediate_operand" "m,d"))]
+ ""
+ "@
+ ic\\t%0,%1
+ stc\\t%1,%0"
+ [(set_attr "op_type" "RX,RX")
+ (set_attr "atype" "mem,mem")])
+
+
+;
+; movstricthi instruction pattern(s).
+;
+
+(define_insn "*movstricthi"
+ [(set (strict_low_part (match_operand:HI 0 "r_or_s_operand" "+d,Q"))
+ (match_operand:HI 1 "r_or_s_operand" "Q,d"))
+ (clobber (reg:CC 33))]
+ ""
+ "@
+ icm\\t%0,3,%1
+ stcm\\t%1,3,%0"
+ [(set_attr "op_type" "RS,RS")
+ (set_attr "atype" "mem")
+ (set_attr "type" "xset")])
+
+
+;
+; movstrictsi instruction pattern(s).
+;
+
+(define_insn "movestrictsi"
+ [(set (strict_low_part (match_operand:SI 0 "nonimmediate_operand" "+d,d,m"))
+ (match_operand:SI 1 "nonimmediate_operand" "d,m,d"))]
+ "TARGET_64BIT"
+ "@
+ lr\\t%0,%1
+ l\\t%0,%1
+ st\\t%1,%0"
+ [(set_attr "op_type" "RR,RS,RS")
+ (set_attr "atype" "reg,mem,mem")
+ (set_attr "type" "xset")])
+
+
+;
+; movdf instruction pattern(s).
+;
+
+(define_expand "movdf"
+ [(set (match_operand:DF 0 "nonimmediate_operand" "")
+ (match_operand:DF 1 "general_operand" ""))]
+ ""
+ "
+{
+ if (GET_CODE (operands[1]) == CONST_DOUBLE)
+ operands[1] = force_const_mem (DFmode, operands[1]);
+}")
+
+(define_insn "*movdf_64"
+ [(set (match_operand:DF 0 "nonimmediate_operand" "=f,f,m,d,m,d,Q")
+ (match_operand:DF 1 "general_operand" "f,m,f,m,d,d,Q"))]
+ "TARGET_64BIT && TARGET_HARD_FLOAT"
+ "@
+ ldr\\t%0,%1
+ ld\\t%0,%1
+ std\\t%1,%0
+ lg\\t%0,%1
+ stg\\t%1,%0
+ lgr\\t%0,%1
+ mvc\\t%O0(8,%R0),%1"
+ [(set_attr "op_type" "RR,RX,RX,RXE,RXE,RR,SS")
+ (set_attr "atype" "reg,mem,mem,mem,mem,mem,mem")
+ (set_attr "type" "xset")])
+
+(define_insn "*movdf_31"
+ [(set (match_operand:DF 0 "nonimmediate_operand" "=f,f,m,d,m,d,Q")
+ (match_operand:DF 1 "general_operand" "f,m,f,m,d,d,Q"))]
+ "TARGET_HARD_FLOAT"
+ "*
+{
+ switch (which_alternative)
+ {
+ case 0: /* f <- f */
+ return \"ldr\\t%0,%1\";
+
+ case 1: /* f <- m */
+ return \"ld\\t%0,%1\";
+
+ case 2: /* m <- f */
+ return \"std\\t%1,%0\";
+
+ case 3: /* d <- m */
+ if (s_operand (operands[1], GET_MODE (operands[1])))
+ return \"lm\\t%0,%N0,%1\";
+ else
+ return \"la\\t%N0,%1\;lm\\t%0,%N0,0(%N0)\";
+
+ case 4: /* m <- d */
+ if (s_operand (operands[0], GET_MODE (operands[0])))
+ return \"stm\\t%1,%N1,%0\";
+ else
+ return \"st\\t%1,%0\;st\\t%N1,%N0\";
+
+ case 5: /* d <- d */
+ if (REGNO (operands[0]) == REGNO (operands[1]) + 1)
+ return \"lr\\t%N0,%N1\;lr\\t%0,%1\";
+ else
+ return \"lr\\t%0,%1\;lr\\t%N0,%N1\";
+
+ case 6: /* m <- m */
+ return \"mvc\\t%O0(8,%R0),%1\";
+ }
+}"
+ [(set_attr "op_type" "RR,RX,RX,RS,RS,NN,SS")
+ (set_attr "atype" "reg,mem,mem,mem,mem,reg,mem")
+ (set_attr "length" "*,*,*,*,*,4,*")])
+
+(define_insn "*movdf_soft_64"
+ [(set (match_operand:DF 0 "nonimmediate_operand" "=d,m,d,Q")
+ (match_operand:DF 1 "general_operand" "m,d,d,Q"))]
+ "TARGET_64BIT && TARGET_SOFT_FLOAT"
+ "@
+ lg\\t%0,%1
+ stg\\t%1,%0
+ lgr\\t%0,%1
+ mvc\\t%O0(8,%R0),%1"
+ [(set_attr "op_type" "RXE,RXE,RR,SS")
+ (set_attr "atype" "mem,mem,mem,mem")
+ (set_attr "type" "xset")])
+
+(define_insn "*movdf_soft_31"
+ [(set (match_operand:DF 0 "nonimmediate_operand" "=!d,d,m,Q")
+ (match_operand:DF 1 "general_operand" "!d,m,d,Q"))]
+ "TARGET_SOFT_FLOAT"
+ "*
+{
+ switch (which_alternative)
+ {
+ case 0: /* d <- d */
+ if (REGNO (operands[0]) == REGNO (operands[1]) + 1)
+ return \"lr\\t%N0,%N1\;lr\\t%0,%1\";
+ else
+ return \"lr\\t%0,%1\;lr\\t%N0,%N1\";
+
+ case 1: /* d <- m */
+ if (s_operand (operands[1], GET_MODE (operands[1])))
+ return \"lm\\t%0,%N0,%1\";
+ else
+ return \"la\\t%N0,%1\;lm\\t%0,%N0,0(%N0)\";
+
+ case 2: /* m <- d */
+ if (s_operand (operands[0], GET_MODE (operands[0])))
+ return \"stm\\t%1,%N1,%0\";
+ else
+ return \"st\\t%1,%0\;st\\t%N1,%N0\";
+
+ case 3: /* m <- m */
+ return \"mvc\\t%O0(8,%R0),%1\";
+ }
+}"
+ [(set_attr "op_type" "NN,RS,RS,SS")
+ (set_attr "atype" "reg,mem,mem,mem")
+ (set_attr "length" "8,*,*,*")])
+
+
+;
+; movsf instruction pattern(s).
+;
+
+(define_expand "movsf"
+ [(set (match_operand:SF 0 "nonimmediate_operand" "")
+ (match_operand:SF 1 "general_operand" ""))]
+ ""
+ "
+{
+ if (GET_CODE (operands[1]) == CONST_DOUBLE)
+ operands[1] = force_const_mem (SFmode, operands[1]);
+}")
+
+(define_insn "*movsf_64"
+ [(set (match_operand:SF 0 "nonimmediate_operand" "=f,f,m,d,m,d,Q")
+ (match_operand:SF 1 "general_operand" "f,m,f,m,d,d,Q"))]
+ "TARGET_64BIT && TARGET_HARD_FLOAT"
+ "@
+ ler\\t%0,%1
+ le\\t%0,%1
+ ste\\t%1,%0
+ llgf\\t%0,%1
+ st\\t%1,%0
+ lgr\\t%0,%1
+ mvc\\t%O0(4,%R0),%1"
+ [(set_attr "op_type" "RR,RX,RX,RXE,RX,RR,SS")
+ (set_attr "atype" "reg,mem,mem,mem,mem,reg,mem")])
+
+(define_insn "*movsf_31"
+ [(set (match_operand:SF 0 "nonimmediate_operand" "=f,f,m,d,m,d,Q")
+ (match_operand:SF 1 "general_operand" "f,m,f,m,d,d,Q"))]
+ "TARGET_HARD_FLOAT"
+ "@
+ ler\\t%0,%1
+ le\\t%0,%1
+ ste\\t%1,%0
+ l\\t%0,%1
+ st\\t%1,%0
+ lr\\t%0,%1
+ mvc\\t%O0(4,%R0),%1"
+ [(set_attr "op_type" "RR,RX,RX,RX,RX,RR,SS")
+ (set_attr "atype" "reg,mem,mem,mem,mem,reg,mem")])
+
+(define_insn "*movsf_soft"
+ [(set (match_operand:SF 0 "nonimmediate_operand" "=d,d,m,Q")
+ (match_operand:SF 1 "general_operand" "d,m,d,Q"))]
+ "TARGET_SOFT_FLOAT"
+ "@
+ lr\\t%0,%1
+ l\\t%0,%1
+ st\\t%1,%0
+ mvc\\t%O0(4,%R0),%1"
+ [(set_attr "op_type" "RR,RX,RX,SS")
+ (set_attr "atype" "reg,mem,mem,mem")])
+;
+; load_multiple pattern(s).
+;
+
+(define_expand "load_multiple"
+ [(match_par_dup 3 [(set (match_operand 0 "" "")
+ (match_operand 1 "" ""))
+ (use (match_operand 2 "" ""))])]
+ ""
+ "
+{
+ int regno;
+ int count;
+ rtx from;
+ int i;
+
+ /* Support only loading a constant number of fixed-point registers from
+ memory and only bother with this if more than two */
+ if (GET_CODE (operands[2]) != CONST_INT
+ || INTVAL (operands[2]) <= 2
+ || INTVAL (operands[2]) > 16
+ || GET_CODE (operands[1]) != MEM
+ || GET_CODE (operands[0]) != REG
+ || REGNO (operands[0]) >= 16)
+ FAIL;
+
+ count = INTVAL (operands[2]);
+ regno = REGNO (operands[0]);
+
+ operands[3] = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (count));
+ from = force_reg (Pmode, XEXP (operands[1], 0));
+
+ for (i = 0; i < count; i++)
+ XVECEXP (operands[3], 0, i)
+ = gen_rtx_SET (VOIDmode, gen_rtx_REG (Pmode, regno + i),
+ change_address (operands[1], Pmode,
+ plus_constant (from, i * 4)));
+}")
+
+(define_insn "*load_multiple_di"
+ [(match_parallel 0 "load_multiple_operation"
+ [(set (match_operand:DI 1 "register_operand" "=r")
+ (match_operand:DI 2 "s_operand" "oQ"))])]
+ ""
+ "*
+{
+ int words = XVECLEN (operands[0], 0);
+
+ if (XVECLEN (operands[0], 0) == 1)
+ return \"lg\\t%1,0(%2)\";
+
+ operands[0] = gen_rtx_REG (DImode, REGNO (operands[1]) + words - 1);
+ return \"lmg\\t%1,%0,%2\";
+}"
+ [(set_attr "op_type" "RXE")
+ (set_attr "atype" "mem")
+ (set_attr "type" "set")])
+
+(define_insn "*load_multiple_si"
+ [(match_parallel 0 "load_multiple_operation"
+ [(set (match_operand:SI 1 "register_operand" "=r")
+ (match_operand:SI 2 "s_operand" "oQ"))])]
+ ""
+ "*
+{
+ int words = XVECLEN (operands[0], 0);
+
+ if (XVECLEN (operands[0], 0) == 1)
+ return \"l\\t%1,0(%2)\";
+
+ operands[0] = gen_rtx_REG (SImode, REGNO (operands[1]) + words - 1);
+ return \"lm\\t%1,%0,%2\";
+}"
+ [(set_attr "op_type" "RXE")
+ (set_attr "atype" "mem")
+ (set_attr "type" "set")])
+
+;
+; store multiple pattern(s).
+;
+
+(define_expand "store_multiple"
+ [(match_par_dup 3 [(set (match_operand 0 "" "")
+ (match_operand 1 "" ""))
+ (use (match_operand 2 "" ""))])]
+ ""
+ "
+{
+ int regno;
+ int count;
+ rtx to;
+ int i;
+
+ /* Support only storing a constant number of fixed-point registers to
+ memory and only bother with this if more than two. */
+ if (GET_CODE (operands[2]) != CONST_INT
+ || INTVAL (operands[2]) <= 2
+ || INTVAL (operands[2]) > 16
+ || GET_CODE (operands[0]) != MEM
+ || GET_CODE (operands[1]) != REG
+ || REGNO (operands[1]) >= 16)
+ FAIL;
+
+ count = INTVAL (operands[2]);
+ regno = REGNO (operands[1]);
+
+ operands[3] = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (count));
+ to = force_reg (Pmode, XEXP (operands[0], 0));
+
+ for (i = 0; i < count; i++)
+ XVECEXP (operands[3], 0, i)
+ = gen_rtx_SET (VOIDmode,
+ change_address (operands[0], Pmode,
+ plus_constant (to, i * 4)),
+ gen_rtx_REG (Pmode, regno + i));
+}")
+
+(define_insn "*store_multiple_di"
+ [(match_parallel 0 "store_multiple_operation"
+ [(set (match_operand:DI 1 "s_operand" "=oQ")
+ (match_operand:DI 2 "register_operand" "r"))])]
+ ""
+ "*
+{
+ int words = XVECLEN (operands[0], 0);
+
+ if (XVECLEN (operands[0], 0) == 1)
+ return \"stg\\t%1,0(%2)\";
+
+ operands[0] = gen_rtx_REG (DImode, REGNO (operands[2]) + words - 1);
+ return \"stmg\\t%2,%0,%1\";
+}"
+ [(set_attr "op_type" "RXE")
+ (set_attr "atype" "mem")
+ (set_attr "type" "xset")])
+
+
+(define_insn "*store_multiple_si"
+ [(match_parallel 0 "store_multiple_operation"
+ [(set (match_operand:SI 1 "s_operand" "=oQ")
+ (match_operand:SI 2 "register_operand" "r"))])]
+ ""
+ "*
+{
+ int words = XVECLEN (operands[0], 0);
+
+ if (XVECLEN (operands[0], 0) == 1)
+ return \"st\\t%1,0(%2)\";
+
+ operands[0] = gen_rtx_REG (SImode, REGNO (operands[2]) + words - 1);
+ return \"stm\\t%2,%0,%1\";
+}"
+ [(set_attr "op_type" "RXE")
+ (set_attr "atype" "mem")
+ (set_attr "type" "xset")])
+
+;;
+;; String instructions.
+;;
+
+;
+; movstrdi instruction pattern(s).
+;
+
+(define_expand "movstrdi"
+ [(set (match_operand:BLK 0 "general_operand" "")
+ (match_operand:BLK 1 "general_operand" ""))
+ (use (match_operand:DI 2 "general_operand" ""))
+ (match_operand 3 "" "")]
+ "TARGET_64BIT"
+ "
+{
+ rtx addr0, addr1;
+
+ addr0 = force_operand (XEXP (operands[0], 0), NULL_RTX);
+ addr1 = force_operand (XEXP (operands[1], 0), NULL_RTX);
+
+ if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) <= 256)
+ {
+ operands[0] = change_address (operands[0], VOIDmode, addr0);
+ operands[1] = change_address (operands[1], VOIDmode, addr1);
+ operands[2] = GEN_INT (INTVAL (operands[2]) - 1);
+
+ emit_insn (gen_movstrsico (operands[0], operands[1], operands[2]));
+ DONE;
+ }
+ else
+ {
+ if (TARGET_MVCLE)
+ {
+ /* implementation suggested by Richard Henderson <rth@cygnus.com> */
+ rtx reg0 = gen_reg_rtx (TImode);
+ rtx reg1 = gen_reg_rtx (TImode);
+ rtx len = operands[2];
+
+ if (! CONSTANT_P (len))
+ len = force_reg (DImode, len);
+
+ /* Load up the address+length pairs. */
+
+ emit_move_insn (gen_rtx_SUBREG (DImode, reg0, 0), addr0);
+ emit_move_insn (gen_rtx_SUBREG (DImode, reg0, 8), len);
+
+ emit_move_insn (gen_rtx_SUBREG (DImode, reg1, 0), addr1);
+ emit_move_insn (gen_rtx_SUBREG (DImode, reg1, 8), len);
+
+ /* MOVE */
+ emit_insn (gen_movstrdi_64 (reg0, reg1));
+ DONE;
+ }
+ else
+ {
+ rtx label = gen_label_rtx ();
+ rtx reg0, reg1, len;
+
+ reg0 = gen_reg_rtx (DImode);
+ reg1 = gen_reg_rtx (DImode);
+ len = gen_reg_rtx (DImode);
+
+ emit_move_insn (len, operands[2]);
+ emit_insn (gen_cmpdi (len, const0_rtx));
+ emit_jump_insn (gen_beq (label));
+ emit_move_insn (reg0, addr0);
+ emit_move_insn (reg1, addr1);
+ emit_insn (gen_adddi3 (len, len, constm1_rtx));
+ emit_insn (gen_movstrdix_64 (reg0, reg1, len));
+ emit_label (label);
+ DONE;
+ }
+ }
+}")
+
+;
+; 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 addr0 = force_operand (XEXP (operands[0], 0), NULL_RTX);
+ rtx addr1 = force_operand (XEXP (operands[1], 0), NULL_RTX);
+
+ if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) <= 256)
+ {
+ operands[0] = change_address (operands[0], VOIDmode, addr0);
+ operands[1] = change_address (operands[1], VOIDmode, addr1);
+ operands[2] = GEN_INT (INTVAL (operands[2]) - 1);
+
+ emit_insn (gen_movstrsico (operands[0], operands[1], operands[2]));
+ DONE;
+ }
+ else
+ {
+ if (TARGET_64BIT)
+ FAIL;
+
+ if (TARGET_MVCLE)
+ {
+ /* implementation suggested by Richard Henderson <rth@cygnus.com> */
+ rtx reg0 = gen_reg_rtx (DImode);
+ rtx reg1 = gen_reg_rtx (DImode);
+ rtx len = operands[2];
+
+
+ if (! CONSTANT_P (len))
+ len = force_reg (SImode, len);
+
+ /* Load up the address+length pairs. */
+
+ emit_move_insn (gen_rtx_SUBREG (SImode, reg0, 0), addr0);
+ emit_move_insn (gen_rtx_SUBREG (SImode, reg0, 4), len);
+
+ emit_move_insn (gen_rtx_SUBREG (SImode, reg1, 0), addr1);
+ emit_move_insn (gen_rtx_SUBREG (SImode, reg1, 4), len);
+
+ /* MOVE */
+ emit_insn (gen_movstrsi_31 (reg0, reg1));
+ DONE;
+ }
+ else
+ {
+ rtx label = gen_label_rtx ();
+ rtx reg0, reg1, len;
+
+ reg0 = gen_reg_rtx (SImode);
+ reg1 = gen_reg_rtx (SImode);
+ len = gen_reg_rtx (SImode);
+
+ emit_move_insn (len, operands[2]);
+ emit_insn (gen_cmpsi (len, const0_rtx));
+ emit_jump_insn (gen_beq (label));
+ emit_move_insn (reg0, addr0);
+ emit_move_insn (reg1, addr1);
+ emit_insn (gen_addsi3 (len, len, constm1_rtx));
+ emit_insn (gen_movstrsix_31 (reg0, reg1, len));
+ emit_label (label);
+ DONE;
+ }
+ }
+}")
+
+; Move a block that is less than 256 bytes in length.
+
+(define_insn "movstrsico"
+ [(set (match_operand:BLK 0 "s_operand" "=oQ")
+ (match_operand:BLK 1 "s_operand" "oQ"))
+ (use (match_operand 2 "const_int_operand" "I"))]
+ "((unsigned) INTVAL (operands[2]) < 256)"
+ "mvc\\t%O0(%c2+1,%R0),%1"
+ [(set_attr "op_type" "SS")
+ (set_attr "atype" "mem")])
+
+; Move a block that is more than 256 bytes in lenght or length in register
+
+(define_insn "movstrdix_64"
+ [(set (mem:BLK (match_operand:DI 0 "register_operand" "a"))
+ (mem:BLK (match_operand:DI 1 "register_operand" "a")))
+ (use (match_operand:DI 2 "register_operand" "a"))
+ (clobber (match_dup 0))
+ (clobber (match_dup 1))
+ (clobber (match_scratch:DI 3 "=&a"))
+ (clobber (reg:CC 33))]
+ ""
+ "*
+{
+ rtx xop[4];
+ xop[0] = gen_label_rtx ();
+ xop[1] = gen_label_rtx ();
+ xop[2] = gen_label_rtx ();
+ xop[3] = operands[3];
+ output_asm_insn (\"srag\\t%3,%2,8\",operands);
+ output_asm_insn (\"jz\\t%l1\",xop);
+ ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, \"L\",
+ CODE_LABEL_NUMBER (xop[0]));
+ output_asm_insn (\"mvc\\t0(256,%0),0(%1)\",operands);
+ output_asm_insn (\"la\\t%0,256(%0)\",operands);
+ output_asm_insn (\"la\\t%1,256(%1)\",operands);
+ xop[3] = operands[3];
+ output_asm_insn (\"brct\\t%3,%l0\",xop);
+ ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, \"L\",
+ CODE_LABEL_NUMBER (xop[1]));
+ xop[3] = operands[3];
+ output_asm_insn (\"bras\\t%3,%l2\",xop);
+ output_asm_insn (\"mvc\\t0(1,%0),0(%1)\",operands);
+ ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, \"L\",
+ CODE_LABEL_NUMBER (xop[2]));
+ return \"ex\\t%2,0(%3)\";
+}"
+ [(set_attr "op_type" "NN")
+ (set_attr "atype" "mem")
+ (set_attr "length" "44")])
+
+(define_insn "movstrsix_31"
+ [(set (mem:BLK (match_operand:SI 0 "register_operand" "a"))
+ (mem:BLK (match_operand:SI 1 "register_operand" "a")))
+ (use (match_operand:SI 2 "register_operand" "a"))
+ (clobber (match_dup 0))
+ (clobber (match_dup 1))
+ (clobber (match_scratch:SI 3 "=&a"))
+ (clobber (reg:CC 33))]
+ ""
+ "*
+{
+ rtx xop[4];
+ xop[0] = gen_label_rtx ();
+ xop[1] = gen_label_rtx ();
+ xop[2] = gen_label_rtx ();
+ xop[3] = operands[3];
+ output_asm_insn (\"lr\\t%3,%2\",operands);
+ output_asm_insn (\"sra\\t%3,8\",operands);
+ output_asm_insn (\"jz\\t%l1\",xop);
+ ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, \"L\",
+ CODE_LABEL_NUMBER (xop[0]));
+ output_asm_insn (\"mvc\\t0(256,%0),0(%1)\",operands);
+ output_asm_insn (\"la\\t%0,256(%0)\",operands);
+ output_asm_insn (\"la\\t%1,256(%1)\",operands);
+ xop[3] = operands[3];
+ output_asm_insn (\"brct\\t%3,%l0\",xop);
+ ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, \"L\",
+ CODE_LABEL_NUMBER (xop[1]));
+ xop[3] = operands[3];
+ output_asm_insn (\"bras\\t%3,%l2\",xop);
+ output_asm_insn (\"mvc\\t0(1,%0),0(%1)\",operands);
+ ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, \"L\",
+ CODE_LABEL_NUMBER (xop[2]));
+ return \"ex\\t%2,0(%3)\";
+}"
+ [(set_attr "op_type" "NN")
+ (set_attr "length" "42")
+ (set_attr "atype" "mem")])
+
+; Move a block that is larger than 255 bytes in length.
+
+(define_insn "movstrdi_64"
+ [(set (mem:BLK (subreg:DI (match_operand:TI 0 "register_operand" "d") 0))
+ (mem:BLK (subreg:DI (match_operand:TI 1 "register_operand" "d") 0)))
+ (clobber (match_dup 0))
+ (clobber (match_dup 1))
+ (clobber (reg:CC 33))]
+ ""
+ "mvcle\\t%0,%1,0\;jo\\t.-4"
+ [(set_attr "op_type" "NN")
+ (set_attr "atype" "mem")
+ (set_attr "length" "8")])
+
+(define_insn "movstrsi_31"
+ [(set (mem:BLK (subreg:SI (match_operand:DI 0 "register_operand" "d") 0))
+ (mem:BLK (subreg:SI (match_operand:DI 1 "register_operand" "d") 0)))
+ (clobber (match_dup 0))
+ (clobber (match_dup 1))
+ (clobber (reg:CC 33))]
+ ""
+ "mvcle\\t%0,%1,0\;jo\\t.-4"
+ [(set_attr "op_type" "NN")
+ (set_attr "atype" "mem")
+ (set_attr "length" "8")])
+
+;
+; clrstrdi instruction pattern(s).
+;
+
+(define_expand "clrstrdi"
+ [(set (match_operand:BLK 0 "general_operand" "")
+ (const_int 0))
+ (use (match_operand:DI 1 "general_operand" ""))
+ (match_operand 2 "" "")]
+ "TARGET_64BIT"
+ "
+{
+ rtx addr = force_operand (XEXP (operands[0], 0), NULL_RTX);
+
+ operands[0] = change_address (operands[0], VOIDmode, addr);
+
+ if (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) < 256)
+ {
+ emit_insn (gen_clrstrsico (operands[0], operands[1]));
+ DONE;
+ }
+ else
+ {
+ rtx reg0 = gen_reg_rtx (TImode);
+ rtx reg1 = gen_reg_rtx (TImode);
+ rtx len = operands[1];
+
+ if (! CONSTANT_P (len))
+ len = force_reg (DImode, len);
+
+ /* Load up the address+length pairs. */
+
+ emit_move_insn (gen_rtx_SUBREG (DImode, reg0, 0), addr);
+ emit_move_insn (gen_rtx_SUBREG (DImode, reg0, 8), len);
+
+ emit_move_insn (gen_rtx_SUBREG (DImode, reg1, 8), const0_rtx);
+
+ /* Clear! */
+ emit_insn (gen_clrstrsi_64 (reg0, reg1));
+ DONE;
+ }
+}")
+
+;
+; clrstrsi instruction pattern(s).
+;
+
+(define_expand "clrstrsi"
+ [(set (match_operand:BLK 0 "general_operand" "")
+ (const_int 0))
+ (use (match_operand:SI 1 "general_operand" ""))
+ (match_operand 2 "" "")]
+ "!TARGET_64BIT"
+ "
+{
+ rtx addr = force_operand (XEXP (operands[0], 0), NULL_RTX);
+
+ operands[0] = change_address (operands[0], VOIDmode, addr);
+
+ if (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) < 256)
+ {
+ emit_insn (gen_clrstrsico (operands[0], operands[1]));
+ DONE;
+ }
+ else
+ {
+ rtx reg0 = gen_reg_rtx (DImode);
+ rtx reg1 = gen_reg_rtx (DImode);
+ rtx len = operands[1];
+
+ if (! CONSTANT_P (len))
+ len = force_reg (SImode, len);
+
+ /* Load up the address+length pairs. */
+
+ emit_move_insn (gen_rtx_SUBREG (SImode, reg0, 0), addr);
+ emit_move_insn (gen_rtx_SUBREG (SImode, reg0, 4), len);
+
+ emit_move_insn (gen_rtx_SUBREG (SImode, reg1, 4), const0_rtx);
+
+ /* CLear! */
+ emit_insn (gen_clrstrsi_31 (reg0, reg1));
+ DONE;
+ }
+}")
+
+; Clear memory with length less than 256 bytes
+
+(define_insn "clrstrsico"
+ [(set (match_operand:BLK 0 "s_operand" "=Qo")
+ (const_int 0))
+ (use (match_operand 1 "immediate_operand" "I"))
+ (clobber (reg:CC 33))]
+ ""
+ "xc\\t%O0(%1,%R0),%0"
+ [(set_attr "op_type" "RS")
+ (set_attr "atype" "mem")])
+
+; Clear memory with length greater 256 bytes or lenght not constant
+
+(define_insn "clrstrsi_64"
+ [(set (mem:BLK (subreg:DI (match_operand:TI 0 "register_operand" "d") 0))
+ (const_int 0))
+ (use (match_operand:TI 1 "register_operand" "d"))
+ (clobber (match_dup 0))
+ (clobber (match_dup 1))
+ (clobber (reg:CC 33))]
+ "TARGET_64BIT"
+ "mvcle\\t%0,%1,0\;jo\\t.-4"
+ [(set_attr "op_type" "NN")
+ (set_attr "atype" "mem")
+ (set_attr "cycle" "n")
+ (set_attr "length" "8")])
+
+(define_insn "clrstrsi_31"
+ [(set (mem:BLK (subreg:SI (match_operand:DI 0 "register_operand" "d") 0))
+ (const_int 0))
+ (use (match_operand:DI 1 "register_operand" "d"))
+ (clobber (match_dup 0))
+ (clobber (match_dup 1))
+ (clobber (reg:CC 33))]
+ "!TARGET_64BIT"
+ "mvcle\\t%0,%1,0\;jo\\t.-4"
+ [(set_attr "op_type" "NN")
+ (set_attr "atype" "mem")
+ (set_attr "cycle" "n")
+ (set_attr "length" "8")])
+
+;
+; cmpstrdi instruction pattern(s).
+;
+
+(define_expand "cmpstrdi"
+ [(set (match_operand:DI 0 "register_operand" "")
+ (compare:DI (match_operand:BLK 1 "s_operand" "")
+ (match_operand:BLK 2 "s_operand" "") ) )
+ (use (match_operand:DI 3 "general_operand" ""))
+ (use (match_operand:DI 4 "" ""))]
+ "TARGET_64BIT"
+ "
+{
+ rtx addr0, addr1;
+
+ /* for pre/post increment */
+ operands[1] = protect_from_queue (operands[1], 0);
+ operands[2] = protect_from_queue (operands[2], 0);
+ operands[3] = protect_from_queue (operands[3], 0);
+
+ addr0 = force_operand (XEXP (operands[1], 0), NULL_RTX);
+ addr1 = force_operand (XEXP (operands[2], 0), NULL_RTX);
+
+ if (GET_CODE (operands[3]) == CONST_INT && INTVAL (operands[3]) < 256)
+ {
+ if (INTVAL (operands[3]) == 0) {
+ emit_move_insn (operands[0], operands[3]);
+ DONE;
+ }
+
+ operands[1] = change_address (operands[1], VOIDmode, addr0);
+ operands[2] = change_address (operands[2], VOIDmode, addr1);
+
+ emit_insn (gen_cmpstr_const (operands[1], operands[2], operands[3]));
+ emit_insn (gen_cmpint_di (operands[0]));
+ DONE;
+ }
+ else
+ {
+ /* implementation suggested by Richard Henderson <rth@cygnus.com> */
+ rtx reg0 = gen_reg_rtx (TImode);
+ rtx reg1 = gen_reg_rtx (TImode);
+ rtx len = operands[3];
+
+ if (! CONSTANT_P (len))
+ len = force_reg (DImode, len);
+
+ /* Load up the address+length pairs. */
+ emit_move_insn (gen_rtx_SUBREG (DImode, reg0, 0), addr0);
+ emit_move_insn (gen_rtx_SUBREG (DImode, reg0, 8), len);
+
+ emit_move_insn (gen_rtx_SUBREG (DImode, reg1, 0), addr1);
+ emit_move_insn (gen_rtx_SUBREG (DImode, reg1, 8), len);
+
+ /* Compare! */
+ emit_insn (gen_cmpstr_64 (reg0, reg1));
+ emit_insn (gen_cmpint_di (operands[0]));
+ DONE;
+ }
+}")
+
+;
+; cmpstrsi instruction pattern(s).
+;
+
+(define_expand "cmpstrsi"
+ [(set (match_operand:SI 0 "register_operand" "")
+ (compare:SI (match_operand:BLK 1 "s_operand" "")
+ (match_operand:BLK 2 "s_operand" "") ) )
+ (use (match_operand:SI 3 "general_operand" ""))
+ (use (match_operand:SI 4 "" ""))]
+ ""
+ "
+{
+ rtx addr0, addr1;
+
+ /* for pre/post increment */
+ operands[1] = protect_from_queue (operands[1], 0);
+ operands[2] = protect_from_queue (operands[2], 0);
+ operands[3] = protect_from_queue (operands[3], 0);
+
+ addr0 = force_operand (XEXP (operands[1], 0), NULL_RTX);
+ addr1 = force_operand (XEXP (operands[2], 0), NULL_RTX);
+
+ if (GET_CODE (operands[3]) == CONST_INT && INTVAL (operands[3]) < 256)
+ {
+ if (INTVAL (operands[3]) == 0) {
+ emit_move_insn (operands[0], operands[3]);
+ DONE;
+ }
+
+ operands[1] = change_address (operands[1], VOIDmode, addr0);
+ operands[2] = change_address (operands[2], VOIDmode, addr1);
+
+ emit_insn (gen_cmpstr_const (operands[1], operands[2], operands[3]));
+ emit_insn (gen_cmpint_si (operands[0]));
+ DONE;
+ }
+ else
+ {
+ /* implementation suggested by Richard Henderson <rth@cygnus.com> */
+ rtx reg0, reg1;
+ rtx len = operands[3];
+
+ if (TARGET_64BIT)
+ {
+ reg0 = gen_reg_rtx (TImode);
+ reg1 = gen_reg_rtx (TImode);
+ }
+ else
+ {
+ reg0 = gen_reg_rtx (DImode);
+ reg1 = gen_reg_rtx (DImode);
+ }
+
+ if (! CONSTANT_P (len))
+ len = force_reg (Pmode, len);
+
+ /* Load up the address+length pairs. */
+ emit_move_insn (gen_rtx_SUBREG (Pmode, reg0, 0), addr0);
+ emit_move_insn (gen_rtx_SUBREG (Pmode, reg0,
+ GET_MODE_SIZE (Pmode)), len);
+
+ emit_move_insn (gen_rtx_SUBREG (Pmode, reg1, 0), addr1);
+ emit_move_insn (gen_rtx_SUBREG (Pmode, reg1,
+ GET_MODE_SIZE (Pmode)), len);
+
+ /* Compare! */
+ if (TARGET_64BIT)
+ emit_insn (gen_cmpstr_64 (reg0, reg1));
+ else
+ emit_insn (gen_cmpstr_31 (reg0, reg1));
+
+ emit_insn (gen_cmpint_si (operands[0]));
+ DONE;
+ }
+}")
+
+; Compare a block that is less than 256 bytes in length.
+
+(define_insn "cmpstr_const"
+ [(set (reg:CCU 33)
+ (compare:CCU (match_operand:BLK 0 "s_operand" "oQ")
+ (match_operand:BLK 1 "s_operand" "oQ")))
+ (use (match_operand 2 "immediate_operand" "I"))]
+ "(unsigned) INTVAL (operands[2]) < 256"
+ "clc\\t%O0(%c2,%R0),%1"
+ [(set_attr "op_type" "SS")
+ (set_attr "atype" "mem")
+ (set_attr "type" "xset")])
+
+; Compare a block that is larger than 255 bytes in length.
+
+(define_insn "cmpstr_64"
+ [(set (reg:CCU 33)
+ (compare:CCU (mem:BLK (subreg:DI (match_operand:TI 0 "register_operand" "d") 0))
+ (mem:BLK (subreg:DI (match_operand:TI 1 "register_operand" "d") 0))))
+ (clobber (subreg:DI (match_dup 0) 0))
+ (clobber (subreg:DI (match_dup 0) 8))
+ (clobber (subreg:DI (match_dup 1) 0))
+ (clobber (subreg:DI (match_dup 1) 8))]
+ "TARGET_64BIT"
+ "clcl\\t%0,%1"
+ [(set_attr "op_type" "RR")
+ (set_attr "atype" "mem")
+ (set_attr "type" "xset")])
+
+(define_insn "cmpstr_31"
+ [(set (reg:CCU 33)
+ (compare:CCU (mem:BLK (subreg:SI (match_operand:DI 0 "register_operand" "d") 0))
+ (mem:BLK (subreg:SI (match_operand:DI 1 "register_operand" "d") 0))))
+ (clobber (subreg:SI (match_dup 0) 0))
+ (clobber (subreg:SI (match_dup 0) 4))
+ (clobber (subreg:SI (match_dup 1) 0))
+ (clobber (subreg:SI (match_dup 1) 4))]
+ "!TARGET_64BIT"
+ "clcl\\t%0,%1"
+ [(set_attr "op_type" "RR")
+ (set_attr "atype" "mem")
+ (set_attr "type" "xset")])
+
+; Convert condition code to integer in range (-1, 0, 1)
+
+(define_insn "cmpint_si"
+ [(set (match_operand:SI 0 "register_operand" "=d")
+ (compare:SI (reg:CCU 33) (const_int 0)))]
+ ""
+ "*
+{
+ output_asm_insn (\"lhi\\t%0,1\", operands);
+ output_asm_insn (\"jh\\t.+12\", operands);
+ output_asm_insn (\"jl\\t.+6\", operands);
+ output_asm_insn (\"sr\\t%0,%0\", operands);
+ return \"lcr\\t%0,%0\";
+}"
+ [(set_attr "op_type" "NN")
+ (set_attr "length" "16")
+ (set_attr "atype" "reg")
+ (set_attr "type" "xset")])
+
+(define_insn "cmpint_di"
+ [(set (match_operand:DI 0 "register_operand" "=d")
+ (compare:DI (reg:CCU 33) (const_int 0)))]
+ "TARGET_64BIT"
+ "*
+{
+ output_asm_insn (\"lghi\\t%0,1\", operands);
+ output_asm_insn (\"jh\\t.+12\", operands);
+ output_asm_insn (\"jl\\t.+6\", operands);
+ output_asm_insn (\"sgr\\t%0,%0\", operands);
+ return \"lcgr\\t%0,%0\";
+}"
+ [(set_attr "op_type" "NN")
+ (set_attr "length" "22")
+ (set_attr "atype" "reg")
+ (set_attr "type" "xset")])
+
+;;
+;;- Conversion instructions.
+;;
+
+;
+; extendsidi2 instruction pattern(s).
+;
+
+(define_insn "extendsidi2"
+ [(set (match_operand:DI 0 "register_operand" "=d,d")
+ (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "d,m")))]
+ "TARGET_64BIT"
+ "@
+ lgfr\\t%0,%1
+ lgf\\t%0,%1"
+ [(set_attr "op_type" "RRE,RXE")
+ (set_attr "atype" "reg,mem")
+ (set_attr "type" "set")])
+
+
+;
+; extendhidi2 instruction pattern(s).
+;
+
+(define_insn "extendhidi2"
+ [(set (match_operand:DI 0 "register_operand" "=d")
+ (sign_extend:DI (match_operand:HI 1 "register_operand" "d")))
+ (clobber (reg:CC 33))]
+ "TARGET_64BIT"
+ "sllg\\t%0,%1,48\;srag\\t%0,%0,48"
+ [(set_attr "op_type" "NN")
+ (set_attr "length" "12")
+ (set_attr "cycle" "2")
+ (set_attr "type" "set")])
+
+
+;
+; extendqidi2 instruction pattern(s).
+;
+
+(define_insn "extendqidi2"
+ [(set (match_operand:DI 0 "register_operand" "=d")
+ (sign_extend:DI (match_operand:QI 1 "register_operand" "d")))
+ (clobber (reg:CC 33))]
+ "TARGET_64BIT"
+ "sllg\\t%0,%1,56\;srag\\t%0,%0,56"
+ [(set_attr "op_type" "NN")
+ (set_attr "length" "12")
+ (set_attr "cycle" "2")
+ (set_attr "type" "set")])
+
+
+;
+; extendhisi2 instruction pattern(s).
+;
+
+(define_insn "extendhisi2"
+ [(set (match_operand:SI 0 "register_operand" "=d,!d,d")
+ (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "0,d,m")))
+ (clobber (reg:CC 33))]
+ ""
+ "@
+ sll\\t%1,16\;sra\\t%1,16
+ lr\\t%0,%1\;sll\\t%0,16\;sra\\t%0,16
+ lh\\t%0,%1"
+ [(set_attr "op_type" "NN,NN,RX")
+ (set_attr "cycle" "2,3,1")
+ (set_attr "atype" "reg,reg,mem")
+ (set_attr "type" "set")
+ (set_attr "length" "8,10,*")])
+
+
+;
+; extendqisi2 instruction pattern(s).
+;
+
+(define_insn "extendqisi2"
+ [(set (match_operand:SI 0 "register_operand" "=d,d")
+ (sign_extend:SI (match_operand:QI 1 "r_or_s_operand" "0,Q")))
+ (clobber (reg:CC 33))]
+ ""
+ "@
+ sll\\t%0,24\;sra\\t%0,24
+ icm\\t%0,8,%1\;sra\\t%0,24"
+ [(set_attr "op_type" "NN,NN")
+ (set_attr "cycle" "2")
+ (set_attr "atype" "reg,mem")
+ (set_attr "type" "set")
+ (set_attr "length" "8,8")])
+
+
+;
+; extendqihi2 instruction pattern(s).
+;
+
+(define_insn "extendqihi2"
+ [(set (match_operand:HI 0 "register_operand" "=d,d")
+ (sign_extend:HI (match_operand:QI 1 "r_or_s_operand" "0,Q")))
+ (clobber (reg:CC 33))]
+ ""
+ "@
+ sll\\t%0,24\;sra\\t%0,24
+ icm\\t%0,8,%1\;sra\\t%0,24"
+ [(set_attr "op_type" "NN,NN")
+ (set_attr "cycle" "2")
+ (set_attr "atype" "reg,mem")
+ (set_attr "type" "set")
+ (set_attr "length" "8,8")])
+
+
+;
+; zero_extendsidi2 instruction pattern(s).
+;
+
+(define_insn "zero_extendsidi2"
+ [(set (match_operand:DI 0 "register_operand" "=d,d")
+ (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "d,m")))]
+ "TARGET_64BIT"
+ "@
+ llgfr\\t%0,%1
+ llgf\\t%0,%1"
+ [(set_attr "op_type" "RRE,RXE")
+ (set_attr "atype" "reg,mem")
+ (set_attr "type" "set")])
+
+
+;
+; zero_extendhidi2 instruction pattern(s).
+;
+
+(define_insn "zero_extendhidi2"
+ [(set (match_operand:DI 0 "register_operand" "=!d,d")
+ (zero_extend:DI (match_operand:HI 1 "nonimmediate_operand" "d,m")))]
+ "TARGET_64BIT"
+ "@
+ llgfr\\t%0,%1\;iilh\\t%0,0
+ llgh\\t%0,%1"
+ [(set_attr "op_type" "NN,RXE")
+ (set_attr "cycle" "2,1")
+ (set_attr "atype" "reg,mem")
+ (set_attr "length" "12,*")
+ (set_attr "type" "set")])
+
+
+;
+; zero_extendqidi2 instruction pattern(s)
+;
+
+(define_insn "zero_extendqidi2"
+ [(set (match_operand:DI 0 "register_operand" "=!d,d")
+ (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand" "d,m")))
+ (clobber (reg:CC 33))]
+ "TARGET_64BIT"
+ "@
+ sllg\\t%0,%1,56\;srlg\\t%0,%0,56
+ llgc\\t%0,%1"
+ [(set_attr "op_type" "NN,RXE")
+ (set_attr "cycle" "2,1")
+ (set_attr "atype" "reg,mem")
+ (set_attr "type" "set")
+ (set_attr "length" "12,*")])
+
+
+;
+; zero_extendhisi2 instruction pattern(s).
+;
+
+(define_expand "zero_extendhisi2"
+ [(set (match_operand:SI 0 "register_operand" "")
+ (zero_extend:SI (match_operand:HI 1 "r_or_s_operand" "")))]
+ ""
+ "
+{
+ if (!TARGET_64BIT)
+ {
+ emit_insn (gen_zero_extendhisi2_31 (operands[0], operands[1],
+ force_const_mem (SImode, const0_rtx)));
+ DONE;
+ }
+}")
+
+(define_insn "*zero_extendhisi2_64"
+ [(set (match_operand:SI 0 "register_operand" "=d,d")
+ (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "0,m")))]
+ "TARGET_64BIT"
+ "@
+ iilh\\t%0,0
+ llgh\\t%0,%1"
+ [(set_attr "op_type" "RI,RXE")
+ (set_attr "atype" "reg,mem")])
+
+(define_insn "zero_extendhisi2_31"
+ [(set (match_operand:SI 0 "register_operand" "=d,d")
+ (zero_extend:SI (match_operand:HI 1 "r_or_s_operand" "0,Q")))
+ (use (match_operand:SI 2 "memory_operand" "m,m"))
+ (clobber (reg:CC 33))]
+ ""
+ "@
+ icm\\t%0,12,%2
+ icm\\t%0,12,%1\;srl\\t%0,16"
+ [(set_attr "op_type" "RX,NN")
+ (set_attr "cycle" "1,2")
+ (set_attr "atype" "reg,mem")
+ (set_attr "type" "set")
+ (set_attr "length" "*,8")])
+
+
+;
+; zero_extendqisi2 instruction pattern(s).
+;
+
+(define_insn "*zero_extendqisi2_mem_31"
+ [(set (match_operand:SI 0 "register_operand" "=&d")
+ (zero_extend:SI (match_operand:QI 1 "memory_operand" "m")))
+ (use (match_operand:SI 2 "memory_operand" "m" ))
+ (clobber (reg:CC 33))]
+ ""
+ "sr\\t%0,%0\;ic\\t%0,%1"
+ [(set_attr "op_type" "NN")
+ (set_attr "cycle" "2")
+ (set_attr "atype" "mem")
+ (set_attr "type" "set")
+ (set_attr "length" "6")])
+
+(define_insn "zero_extendqisi2_reg_31"
+ [(set (match_operand:SI 0 "register_operand" "=d")
+ (zero_extend:SI (match_operand:QI 1 "register_operand" "0")))
+ (use (match_operand:SI 2 "memory_operand" "m" ))
+ (clobber (reg:CC 33))]
+ ""
+ "icm\\t%0,14,%2"
+ [(set_attr "op_type" "RX")
+ (set_attr "atype" "mem")
+ (set_attr "type" "set")])
+
+(define_insn "*zero_extendqisi2_64"
+ [(set (match_operand:SI 0 "register_operand" "=!d,d")
+ (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "d,m")))]
+ "TARGET_64BIT"
+ "@
+ sllg\\t%0,%1,56\;srlg\\t%0,%0,56
+ llgc\\t%0,%1"
+ [(set_attr "op_type" "NN,RXE")
+ (set_attr "cycle" "2,1")
+ (set_attr "atype" "reg,mem")
+ (set_attr "length" "12,*")])
+
+(define_expand "zero_extendqisi2"
+ [(set (match_operand:SI 0 "register_operand" "")
+ (zero_extend:SI (match_operand:QI 1 "r_or_s_operand" "")))]
+ ""
+ "
+{
+ if (!TARGET_64BIT)
+ {
+ emit_insn (gen_zero_extendqisi2_reg_31 (operands[0], operands[1],
+ force_const_mem (SImode, const0_rtx)));
+ DONE;
+ }
+}")
+
+
+;
+; zero_extendqihi2 instruction pattern(s).
+;
+
+(define_insn "zero_extendqihi2_64"
+ [(set (match_operand:HI 0 "register_operand" "=d,d")
+ (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,m")))
+ (clobber (reg:CC 33))]
+ "TARGET_64BIT"
+ "@
+ nill\\t%0,0x00FF
+ llgc\\t%0,%1"
+ [(set_attr "op_type" "RI,RXE")
+ (set_attr "atype" "reg,mem")])
+
+(define_insn "zero_extendqihi2_31"
+ [(set (match_operand:HI 0 "register_operand" "=d,&d")
+ (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,m")))
+ (use (match_operand:SI 2 "memory_operand" "m,m"))
+ (clobber (reg:CC 33))]
+ ""
+ "@
+ icm\\t%0,14,%2
+ sr\\t%0,%0\;ic\\t%0,%1"
+ [(set_attr "op_type" "RX,NN")
+ (set_attr "atype" "reg,mem")
+ (set_attr "length" "*,8")])
+
+(define_expand "zero_extendqihi2"
+ [(set (match_operand:HI 0 "register_operand" "")
+ (zero_extend:HI (match_operand:QI 1 "general_operand" "")))]
+ ""
+ "
+{
+ if (!TARGET_64BIT)
+ {
+ emit_insn (gen_zero_extendqihi2_31 (operands[0], operands[1],
+ force_const_mem (SImode, const0_rtx)));
+ DONE;
+ }
+ else
+ {
+ emit_insn (gen_zero_extendqihi2_64 (operands[0], operands[1]));
+ DONE;
+ }
+}")
+
+
+;
+; truncdisi2 instruction pattern(s).
+;
+
+(define_insn "truncdisi2"
+ [(set (match_operand:SI 0 "register_operand" "=d")
+ (truncate:SI (match_operand:DI 1 "register_operand" "d")))]
+ "TARGET_64BIT"
+ "llgfr\\t%0,%1"
+ [(set_attr "op_type" "RRE")])
+
+
+;
+; truncdihi2 instruction pattern(s).
+;
+
+(define_insn "truncdihi2"
+ [(set (match_operand:HI 0 "register_operand" "=d")
+ (truncate:HI (match_operand:DI 1 "register_operand" "d")))]
+ "TARGET_64BIT"
+ "llgfr\\t%0,%1\;iilh\\t%0,0"
+ [(set_attr "op_type" "NN")
+ (set_attr "length" "10")])
+
+
+;
+; truncdiqi2 instruction pattern(s).
+;
+
+(define_insn "truncdiqi2"
+ [(set (match_operand:QI 0 "register_operand" "=d")
+ (truncate:QI (match_operand:DI 1 "register_operand" "d")))
+ (clobber (reg:CC 33))]
+ "TARGET_64BIT"
+ "sllg\\t%0,%1,56\;srlg\\t%0,%0,56"
+ [(set_attr "op_type" "NN")
+ (set_attr "cycle" "2")
+ (set_attr "length" "12")])
+
+
+;
+; truncsihi2 instruction pattern(s).
+;
+
+(define_expand "truncsihi2"
+ [(set (match_operand:HI 0 "register_operand" "")
+ (truncate:HI (match_operand:SI 1 "register_operand" "")))]
+ ""
+ "
+{
+ if (!TARGET_64BIT)
+ {
+ emit_insn (gen_do_truncsihi2 (operands[0], operands[1],
+ force_const_mem (SImode, const0_rtx)));
+ DONE;
+ }
+}")
+
+
+(define_insn "do_truncsihi2"
+ [(set (match_operand:HI 0 "register_operand" "=d")
+ (truncate:HI (match_operand:SI 1 "register_operand" "0")))
+ (use (match_operand:SI 2 "memory_operand" "m"))
+ (clobber (reg:CC 33))]
+ ""
+ "icm\\t%0,12,%2"
+ [(set_attr "op_type" "RX")])
+
+(define_insn "*truncsihi2_64"
+ [(set (match_operand:HI 0 "register_operand" "=d")
+ (truncate:HI (match_operand:SI 1 "register_operand" "0")))]
+ "TARGET_64BIT"
+ "iilh\\t%0,0"
+ [(set_attr "op_type" "RI")])
+
+
+;
+; truncsiqi2 instruction pattern(s).
+;
+
+(define_insn "truncsiqi2"
+ [(set (match_operand:QI 0 "register_operand" "=d")
+ (truncate:QI (match_operand:SI 1 "register_operand" "0")))
+ (clobber (reg:CC 33))]
+ "TARGET_64BIT"
+ "iilh\\t%0,0\;nill\\t%0,0x00FF"
+ [(set_attr "op_type" "NN")
+ (set_attr "cycle" "2")
+ (set_attr "length" "8")])
+
+
+;
+; trunchiqi2 instruction pattern(s).
+;
+
+(define_insn "trunchiqi2"
+ [(set (match_operand:QI 0 "register_operand" "=d")
+ (truncate:QI (match_operand:HI 1 "register_operand" "0")))
+ (clobber (reg:CC 33))]
+ "TARGET_64BIT"
+ "nill\\t%0,0x00FF"
+ [(set_attr "op_type" "RI")])
+
+
+;
+; fixuns_truncdfdi2 and fix_truncdfsi2 instruction pattern(s).
+;
+
+(define_expand "fixuns_truncdfdi2"
+ [(set (match_operand:DI 0 "register_operand" "")
+ (unsigned_fix:DI (match_operand:DF 1 "register_operand" "")))]
+ "TARGET_64BIT && TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT"
+ "
+{
+ rtx label1 = gen_label_rtx ();
+ rtx label2 = gen_label_rtx ();
+ rtx temp = gen_reg_rtx (DFmode);
+ operands[1] = force_reg (DFmode, operands[1]);
+
+ emit_insn (gen_cmpdf (operands[1], force_const_mem (DFmode,
+ CONST_DOUBLE_FROM_REAL_VALUE (0x8000000000000000ULL, DFmode))));
+ emit_jump_insn (gen_blt (label1));
+
+ emit_insn (gen_subdf3 (temp, operands[1], force_const_mem (DFmode,
+ CONST_DOUBLE_FROM_REAL_VALUE (0x10000000000000000ULL, DFmode))));
+ emit_insn (gen_fix_truncdfdi2_ieee (operands[0], temp, GEN_INT(7)));
+ emit_jump_insn (gen_jump (label2));
+
+ emit_label (label1);
+ emit_insn (gen_fix_truncdfdi2_ieee (operands[0], operands[1], GEN_INT(5)));
+ emit_label (label2);
+ DONE;
+}")
+
+(define_expand "fix_truncdfdi2"
+ [(set (match_operand:DI 0 "register_operand" "")
+ (fix:DI (match_operand:DF 1 "nonimmediate_operand" "")))]
+ "TARGET_64BIT && TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT"
+ "
+{
+ operands[1] = force_reg (DFmode, operands[1]);
+ emit_insn (gen_fix_truncdfdi2_ieee (operands[0], operands[1], GEN_INT(5)));
+ DONE;
+}")
+
+(define_insn "fix_truncdfdi2_ieee"
+ [(set (match_operand:DI 0 "register_operand" "=d")
+ (fix:DI (match_operand:DF 1 "register_operand" "f")))
+ (unspec:DI [(match_operand:DI 2 "immediate_operand" "K")] 1)
+ (clobber (reg:CC 33))]
+ "TARGET_64BIT && TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT"
+ "cgdbr\\t%0,%h2,%1"
+ [(set_attr "op_type" "RRE")
+ (set_attr "cycle" "n")])
+
+;
+; fixuns_truncdfsi2 and fix_truncdfsi2 instruction pattern(s).
+;
+
+(define_expand "fixuns_truncdfsi2"
+ [(set (match_operand:SI 0 "register_operand" "")
+ (unsigned_fix:SI (match_operand:DF 1 "register_operand" "")))]
+ "TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT"
+ "
+{
+ rtx label1 = gen_label_rtx ();
+ rtx label2 = gen_label_rtx ();
+ rtx temp = gen_reg_rtx (DFmode);
+
+ operands[1] = force_reg (DFmode,operands[1]);
+ emit_insn (gen_cmpdf (operands[1], force_const_mem (DFmode,
+ CONST_DOUBLE_FROM_REAL_VALUE (0x80000000, DFmode))));
+ emit_jump_insn (gen_blt (label1));
+ emit_insn (gen_subdf3 (temp, operands[1], force_const_mem (DFmode,
+ CONST_DOUBLE_FROM_REAL_VALUE (0x100000000ULL, DFmode))));
+ emit_insn (gen_fix_truncdfsi2_ieee (operands[0], temp, GEN_INT (7)));
+ emit_jump_insn (gen_jump (label2));
+
+ emit_label (label1);
+ emit_insn (gen_fix_truncdfsi2_ieee (operands[0], operands[1], GEN_INT (5)));
+ emit_label (label2);
+ DONE;
+}")
+
+(define_expand "fix_truncdfsi2"
+ [(set (match_operand:SI 0 "register_operand" "")
+ (fix:SI (match_operand:DF 1 "nonimmediate_operand" "")))]
+ "TARGET_HARD_FLOAT"
+ "
+{
+ if (TARGET_IBM_FLOAT)
+ {
+ /* This is the algorithm from POP chapter A.5.7.2. */
+
+ rtx temp = assign_stack_local (BLKmode, 2 * UNITS_PER_WORD, BITS_PER_WORD);
+ rtx two31r = force_const_mem (DFmode,
+ gen_rtx (CONST_DOUBLE, VOIDmode, cc0_rtx,
+ 0x08000000, 0x4F000000));
+ rtx two32 = force_const_mem (DFmode,
+ gen_rtx (CONST_DOUBLE, VOIDmode, cc0_rtx,
+ 0x0, 0x4E000001));
+
+ operands[1] = force_reg (DFmode, operands[1]);
+ emit_insn (gen_fix_truncdfsi2_ibm (operands[0], operands[1],
+ two31r, two32, temp));
+ }
+ else
+ {
+ operands[1] = force_reg (DFmode, operands[1]);
+ emit_insn (gen_fix_truncdfsi2_ieee (operands[0], operands[1], GEN_INT (5)));
+ }
+
+ DONE;
+}")
+
+(define_insn "fix_truncdfsi2_ieee"
+ [(set (match_operand:SI 0 "register_operand" "=d")
+ (fix:SI (match_operand:DF 1 "register_operand" "f")))
+ (unspec:SI [(match_operand:SI 2 "immediate_operand" "K")] 1)
+ (clobber (reg:CC 33))]
+ "TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT"
+ "cfdbr\\t%0,%h2,%1"
+ [(set_attr "op_type" "RRE")
+ (set_attr "cycle" "n" )])
+
+(define_insn "fix_truncdfsi2_ibm"
+ [(set (match_operand:SI 0 "register_operand" "=d")
+ (fix:SI (match_operand:DF 1 "nonimmediate_operand" "+f")))
+ (use (match_operand:DF 2 "memory_operand" "m"))
+ (use (match_operand:DF 3 "memory_operand" "m"))
+ (use (match_operand:BLK 4 "memory_operand" "m"))
+ (clobber (reg:CC 33))]
+ "TARGET_HARD_FLOAT && TARGET_IBM_FLOAT"
+ "*
+{
+ output_asm_insn (\"sd\\t%1,%2\", operands);
+ output_asm_insn (\"aw\\t%1,%3\", operands);
+ output_asm_insn (\"std\\t%1,%4\", operands);
+ output_asm_insn (\"xi\\t%N4,128\", operands);
+ return \"l\\t%0,%N4\";
+}"
+ [(set_attr "op_type" "NN")
+ (set_attr "cycle" "n")
+ (set_attr "length" "20")])
+
+;
+; fixuns_truncsfdi2 and fix_truncsfdi2 instruction pattern(s).
+;
+
+(define_expand "fixuns_truncsfdi2"
+ [(set (match_operand:DI 0 "register_operand" "")
+ (unsigned_fix:DI (match_operand:SF 1 "register_operand" "")))]
+ "TARGET_64BIT && TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT"
+ "
+{
+ rtx label1 = gen_label_rtx ();
+ rtx label2 = gen_label_rtx ();
+ rtx temp = gen_reg_rtx (SFmode);
+
+ operands[1] = force_reg (SFmode, operands[1]);
+ emit_insn (gen_cmpsf (operands[1], force_const_mem (SFmode,
+ CONST_DOUBLE_FROM_REAL_VALUE (0x8000000000000000ULL, SFmode))));
+ emit_jump_insn (gen_blt (label1));
+
+ emit_insn (gen_subsf3 (temp, operands[1], force_const_mem (SFmode,
+ CONST_DOUBLE_FROM_REAL_VALUE (0x10000000000000000ULL, SFmode))));
+ emit_insn (gen_fix_truncsfdi2_ieee (operands[0], temp, GEN_INT(7)));
+ emit_jump_insn (gen_jump (label2));
+
+ emit_label (label1);
+ emit_insn (gen_fix_truncsfdi2_ieee (operands[0], operands[1], GEN_INT(5)));
+ emit_label (label2);
+ DONE;
+}")
+
+(define_expand "fix_truncsfdi2"
+ [(set (match_operand:DI 0 "register_operand" "")
+ (fix:DI (match_operand:SF 1 "nonimmediate_operand" "")))]
+ "TARGET_64BIT && TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT"
+ "
+{
+ operands[1] = force_reg (SFmode, operands[1]);
+ emit_insn (gen_fix_truncsfdi2_ieee (operands[0], operands[1], GEN_INT(5)));
+ DONE;
+}")
+
+(define_insn "fix_truncsfdi2_ieee"
+ [(set (match_operand:DI 0 "register_operand" "=d")
+ (fix:DI (match_operand:SF 1 "register_operand" "f")))
+ (unspec:DI [(match_operand:DI 2 "immediate_operand" "K")] 1)
+ (clobber (reg:CC 33))]
+ "TARGET_64BIT && TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT"
+ "cgebr\\t%0,%h2,%1"
+ [(set_attr "op_type" "RRE")
+ (set_attr "cycle" "n")])
+
+;
+; fixuns_truncsfsi2 and fix_truncsfsi2 instruction pattern(s).
+;
+
+(define_expand "fixuns_truncsfsi2"
+ [(set (match_operand:SI 0 "register_operand" "")
+ (unsigned_fix:SI (match_operand:SF 1 "register_operand" "")))]
+ "TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT"
+ "
+{
+ rtx label1 = gen_label_rtx ();
+ rtx label2 = gen_label_rtx ();
+ rtx temp = gen_reg_rtx (SFmode);
+
+ operands[1] = force_reg (SFmode, operands[1]);
+ emit_insn (gen_cmpsf (operands[1], force_const_mem (SFmode,
+ CONST_DOUBLE_FROM_REAL_VALUE (0x80000000, SFmode))));
+ emit_jump_insn (gen_blt (label1));
+ emit_insn (gen_subsf3 (temp, operands[1], force_const_mem (SFmode,
+ CONST_DOUBLE_FROM_REAL_VALUE (0x100000000ULL, SFmode))));
+ emit_insn (gen_fix_truncsfsi2_ieee (operands[0], temp, GEN_INT (7)));
+ emit_jump_insn (gen_jump (label2));
+
+ emit_label (label1);
+ emit_insn (gen_fix_truncsfsi2_ieee (operands[0], operands[1], GEN_INT (5)));
+ emit_label (label2);
+ DONE;
+}")
+
+(define_expand "fix_truncsfsi2"
+ [(set (match_operand:SI 0 "register_operand" "")
+ (fix:SI (match_operand:SF 1 "nonimmediate_operand" "")))]
+ "TARGET_HARD_FLOAT"
+ "
+{
+ if (TARGET_IBM_FLOAT)
+ {
+ /* Convert to DFmode and then use the POP algorithm. */
+ rtx temp = gen_reg_rtx (DFmode);
+ emit_insn (gen_extendsfdf2 (temp, operands[1]));
+ emit_insn (gen_fix_truncdfsi2 (operands[0], temp));
+ }
+ else
+ {
+ operands[1] = force_reg (SFmode, operands[1]);
+ emit_insn (gen_fix_truncsfsi2_ieee (operands[0], operands[1], GEN_INT (5)));
+ }
+
+ DONE;
+}")
+
+(define_insn "fix_truncsfsi2_ieee"
+ [(set (match_operand:SI 0 "register_operand" "=d")
+ (fix:SI (match_operand:SF 1 "register_operand" "f")))
+ (unspec:SI [(match_operand:SI 2 "immediate_operand" "K")] 1)
+ (clobber (reg:CC 33))]
+ "TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT"
+ "cfebr\\t%0,%h2,%1"
+ [(set_attr "op_type" "RRE")
+ (set_attr "cycle" "n")])
+
+;
+; floatdidf2 instruction pattern(s).
+;
+
+(define_insn "floatdidf2"
+ [(set (match_operand:DF 0 "register_operand" "=f")
+ (float:DF (match_operand:DI 1 "register_operand" "d")))]
+ "TARGET_64BIT && TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT"
+ "cdgbr\\t%0,%1"
+ [(set_attr "op_type" "RRE")
+ (set_attr "cycle" "n" )])
+
+;
+; floatdisf2 instruction pattern(s).
+;
+
+(define_insn "floatdisf2"
+ [(set (match_operand:SF 0 "register_operand" "=f")
+ (float:SF (match_operand:DI 1 "register_operand" "d")))]
+ "TARGET_64BIT && TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT"
+ "cegbr\\t%0,%1"
+ [(set_attr "op_type" "RRE")
+ (set_attr "cycle" "n" )])
+
+;
+; floatsidf2 instruction pattern(s).
+;
+
+(define_expand "floatsidf2"
+ [(set (match_operand:DF 0 "register_operand" "")
+ (float:DF (match_operand:SI 1 "register_operand" "")))]
+ "TARGET_HARD_FLOAT"
+ "
+{
+ if (TARGET_IBM_FLOAT)
+ {
+ /* This is the algorithm from POP chapter A.5.7.1. */
+
+ rtx temp = assign_stack_local (BLKmode, 2 * UNITS_PER_WORD, BITS_PER_WORD);
+ rtx two31 = force_const_mem (DFmode,
+ gen_rtx (CONST_DOUBLE, VOIDmode, cc0_rtx,
+ 0x80000000, 0x4E000000));
+
+ emit_insn (gen_floatsidf2_ibm (operands[0], operands[1], two31, temp));
+ DONE;
+ }
+}")
+
+(define_insn "floatsidf2_ieee"
+ [(set (match_operand:DF 0 "register_operand" "=f")
+ (float:DF (match_operand:SI 1 "register_operand" "d")))]
+ "TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT"
+ "cdfbr\\t%0,%1"
+ [(set_attr "op_type" "RRE")
+ (set_attr "cycle" "n" )])
+
+(define_insn "floatsidf2_ibm"
+ [(set (match_operand:DF 0 "register_operand" "=f")
+ (float:DF (match_operand:SI 1 "register_operand" "d")))
+ (use (match_operand:DF 2 "memory_operand" "m"))
+ (use (match_operand:BLK 3 "memory_operand" "m"))
+ (clobber (reg:CC 33))]
+ "TARGET_HARD_FLOAT && TARGET_IBM_FLOAT"
+ "*
+{
+ output_asm_insn (\"st\\t%0,%N3\", operands);
+ output_asm_insn (\"xi\\t%N3,128\", operands);
+ output_asm_insn (\"mvc\\t%O3(4,%R3),%2\", operands);
+ output_asm_insn (\"ld\\t%0,%3\", operands);
+ return \"sd\\t%0,%2\";
+}"
+ [(set_attr "op_type" "NN")
+ (set_attr "cycle" "n" )
+ (set_attr "length" "20")])
+
+;
+; floatsisf2 instruction pattern(s).
+;
+
+(define_expand "floatsisf2"
+ [(set (match_operand:SF 0 "register_operand" "")
+ (float:SF (match_operand:SI 1 "register_operand" "")))]
+ "TARGET_HARD_FLOAT"
+ "
+{
+ if (TARGET_IBM_FLOAT)
+ {
+ /* Use the POP algorithm to convert to DFmode and then truncate. */
+ rtx temp = gen_reg_rtx (DFmode);
+ emit_insn (gen_floatsidf2 (temp, operands[1]));
+ emit_insn (gen_truncdfsf2 (operands[0], temp));
+ DONE;
+ }
+}")
+
+(define_insn "floatsisf2_ieee"
+ [(set (match_operand:SF 0 "register_operand" "=f")
+ (float:SF (match_operand:SI 1 "register_operand" "d")))]
+ "TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT"
+ "cefbr\\t%0,%1"
+ [(set_attr "op_type" "RRE")
+ (set_attr "cycle" "n" )])
+
+;
+; truncdfsf2 instruction pattern(s).
+;
+
+(define_expand "truncdfsf2"
+ [(set (match_operand:SF 0 "register_operand" "")
+ (float_truncate:SF (match_operand:DF 1 "general_operand" "")))]
+ "TARGET_HARD_FLOAT"
+ "
+{
+ if (CONSTANT_P(operands[1]))
+ operands[1] = force_const_mem (DFmode, operands[1]);
+}")
+
+(define_insn "truncdfsf2_ieee"
+ [(set (match_operand:SF 0 "register_operand" "=f")
+ (float_truncate:SF (match_operand:DF 1 "nonimmediate_operand" "f")))]
+ "TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT"
+ "ledbr\\t%0,%1"
+ [(set_attr "op_type" "RR")])
+
+(define_insn "truncdfsf2_ibm"
+ [(set (match_operand:SF 0 "register_operand" "=f,f")
+ (float_truncate:SF (match_operand:DF 1 "nonimmediate_operand" "f,m")))]
+ "TARGET_HARD_FLOAT && TARGET_IBM_FLOAT"
+ "@
+ lrer\\t%0,%1
+ le\\t%0,%1"
+ [(set_attr "op_type" "RR,RX")])
+
+;
+; extendsfdf2 instruction pattern(s).
+;
+
+(define_expand "extendsfdf2"
+ [(set (match_operand:DF 0 "register_operand" "")
+ (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "")))]
+ "TARGET_HARD_FLOAT"
+ "
+{
+ if (TARGET_IBM_FLOAT)
+ {
+ emit_insn (gen_extendsfdf2_ibm (operands[0], operands[1]));
+ DONE;
+ }
+}")
+
+(define_insn "extendsfdf2_ieee"
+ [(set (match_operand:DF 0 "register_operand" "=f,f")
+ (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "f,m")))]
+ "TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT"
+ "@
+ ldebr\\t%0,%1
+ ldeb\\t%0,%1"
+ [(set_attr "op_type" "RRE,RXE")])
+
+(define_insn "extendsfdf2_ibm"
+ [(set (match_operand:DF 0 "register_operand" "=f,f")
+ (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "f,m")))
+ (clobber (reg:CC 33))]
+ "TARGET_HARD_FLOAT && TARGET_IBM_FLOAT"
+ "@
+ sdr\\t%0,%0\;ler\\t%0,%1
+ sdr\\t%0,%0\;le\\t%0,%1"
+ [(set_attr "op_type" "RRE,RXE")])
+
+
+;;
+;; ARITHMETRIC OPERATIONS
+;;
+; arithmetric operations set the ConditionCode,
+; because of unpredictable Bits in Register for Halfword and Byte
+; the ConditionCode can be set wrong in operations for Halfword and Byte
+
+;;
+;;- Add instructions.
+;;
+
+;
+; adddi3 instruction pattern(s).
+;
+
+(define_insn "addaddr_esame"
+ [(set (match_operand:DI 0 "register_operand" "=a,a")
+ (plus:DI (match_operand:DI 1 "register_operand" "%a,a")
+ (match_operand:DI 2 "nonmemory_operand" "J,a")))]
+ "TARGET_64BIT && (((REGNO (operands[1]) == STACK_POINTER_REGNUM ) ||
+ (REGNO (operands[1]) == BASE_REGISTER)) &&
+ (GET_CODE (operands[2]) == REG ||
+ CONST_OK_FOR_LETTER_P (INTVAL (operands[2]),'J')))"
+ "@
+ la\\t%0,%c2(,%1)
+ la\\t%0,0(%1,%2)"
+ [(set_attr "op_type" "RX")
+ (set_attr "atype" "mem")
+ (set_attr "type" "la")])
+
+(define_insn "adddi3_64"
+ [(set (match_operand:DI 0 "register_operand" "=d,d,d")
+ (plus:DI (match_operand:DI 1 "register_operand" "%0,0,0")
+ (match_operand:DI 2 "general_operand" "d,K,m") ) )
+ (clobber (reg:CC 33))]
+ "TARGET_64BIT"
+ "@
+ agr\\t%0,%2
+ aghi\\t%0,%h2
+ ag\\t%0,%2"
+ [(set_attr "op_type" "RRE,RI,RXE")
+ (set_attr "atype" "reg,reg,mem")
+ (set_attr "type" "set")])
+
+;
+; For weakness of reload, need (set (reg x) (plus (reg y) (reg x)))
+;
+
+(define_insn "adddi3_inv_64"
+ [(set (match_operand:DI 0 "register_operand" "=d,d,d")
+ (plus:DI (match_operand:DI 1 "general_operand" "%d,K,m")
+ (match_operand:DI 2 "register_operand" "0,0,0") ) )
+ (clobber (reg:CC 33))]
+ "TARGET_64BIT"
+ "@
+ agr\\t%0,%1
+ aghi\\t%0,%h1
+ ag\\t%0,%1"
+ [(set_attr "op_type" "RRE,RI,RXE")
+ (set_attr "atype" "reg,reg,mem")
+ (set_attr "type" "set")])
+
+(define_insn "adddi3_31"
+ [(set (match_operand:DI 0 "register_operand" "=d,d")
+ (plus:DI (match_operand:DI 1 "register_operand" "0,0")
+ (match_operand:DI 2 "general_operand" "d,m") ) )
+ (clobber (reg:CC 33))]
+ "!TARGET_64BIT"
+ "*
+{
+ switch(which_alternative)
+ {
+ case 0: /* d <- d */
+ output_asm_insn (\"ar\\t%0,%2\", operands);
+ output_asm_insn (\"alr\\t%N0,%N2\", operands);
+ break;
+
+ case 1: /* d <- m */
+ output_asm_insn (\"a\\t%0,%2\", operands);
+ output_asm_insn (\"al\\t%N0,%N2\", operands);
+ break;
+ }
+
+ output_asm_insn (\"brc\\t12,.+8\", operands);
+ return \"ahi\\t%0,1\";
+}"
+ [(set_attr "op_type" "NN,NN")
+ (set_attr "atype" "reg,mem")
+ (set_attr "length" "12,16")])
+
+(define_expand "adddi3"
+ [(set (match_operand:DI 0 "register_operand" "")
+ (plus:DI (match_operand:DI 1 "register_operand" "")
+ (match_operand:DI 2 "general_operand" "")))]
+ ""
+ "
+{
+ if (TARGET_64BIT)
+ emit_insn(gen_adddi3_64 (operands[0],operands[1],operands[2]));
+ else
+ emit_insn(gen_adddi3_31 (operands[0],operands[1],operands[2]));
+ DONE;
+}")
+
+(define_insn "reload_load_address"
+ [(set (match_operand:DI 0 "register_operand" "=a")
+ (match_operand:QI 1 "address_operand" "p"))]
+ "TARGET_64BIT"
+ "la\\t%0,%a1"
+ [(set_attr "op_type" "RX")
+ (set_attr "atype" "mem")
+ (set_attr "type" "la")])
+
+(define_insn "*reload_load_address_reg_0"
+ [(set (match_operand:DI 0 "register_operand" "=d")
+ (plus:DI (match_operand:DI 1 "register_operand" "%0")
+ (match_operand:DI 2 "register_operand" "d")))]
+ "TARGET_64BIT"
+ "brxlg\\t%0,%2,.+6"
+ [(set_attr "op_type" "RIE")
+ (set_attr "atype" "reg")
+ (set_attr "type" "set")])
+
+(define_insn "*reload_la_64"
+ [(set (match_operand:DI 0 "register_operand" "=d")
+ (plus:DI (match_operand:DI 1 "general_operand" "g")
+ (match_operand:DI 2 "general_operand" "g")))]
+ "TARGET_64BIT && reload_in_progress"
+ "#")
+
+(define_split
+ [(set (match_operand:DI 0 "register_operand" "")
+ (plus:DI (match_operand:DI 1 "general_operand" "")
+ (match_operand:DI 2 "register_operand" "")))]
+ "TARGET_64BIT && reload_completed
+ && !address_operand (gen_rtx_PLUS (DImode, operands[1], operands[2]), QImode)
+ && !rtx_equal_p (operands[0], operands[1])
+ && !rtx_equal_p (operands[0], operands[2])"
+ [(set (match_dup 0) (match_dup 1))
+ (set (match_dup 0) (plus:DI (match_dup 0) (match_dup 2)))]
+ "")
+
+(define_split
+ [(set (match_operand:DI 0 "register_operand" "")
+ (plus:DI (match_operand:DI 1 "register_operand" "")
+ (match_operand:DI 2 "general_operand" "")))]
+ "TARGET_64BIT && reload_completed
+ && !address_operand (gen_rtx_PLUS (DImode, operands[1], operands[2]), QImode)
+ && !rtx_equal_p (operands[0], operands[1])
+ && !rtx_equal_p (operands[0], operands[2])"
+ [(set (match_dup 0) (match_dup 2))
+ (set (match_dup 0) (plus:DI (match_dup 0) (match_dup 1)))]
+ "")
+
+;
+; addsi3 instruction pattern(s).
+;
+; The following insn is used when it is known that operand one is the stack pointer,
+; and operand two is small enough to fit in the displacement field
+; In this case, the result will be a address
+;
+
+(define_insn "addaddr"
+ [(set (match_operand:SI 0 "register_operand" "=d,d")
+ (plus:SI (match_operand:SI 1 "register_operand" "%a,a")
+ (match_operand:SI 2 "nonmemory_operand" "J,a")))]
+ "(((REGNO (operands[1]) == STACK_POINTER_REGNUM ) ||
+ (REGNO (operands[1]) == BASE_REGISTER)) &&
+ (GET_CODE (operands[2]) == REG ||
+ CONST_OK_FOR_LETTER_P (INTVAL (operands[2]),'J')))"
+ "@
+ la\\t%0,%c2(,%1)
+ la\\t%0,0(%1,%2)"
+ [(set_attr "op_type" "RX")
+ (set_attr "atype" "mem")
+ (set_attr "type" "la")])
+
+(define_insn "*addaddr_picR"
+ [(set (match_operand:SI 0 "register_operand" "=d")
+ (plus:SI (match_operand:SI 1 "register_operand" "a")
+ (unspec:SI [(match_operand:SI 2 "register_operand" "a")] 101)))]
+ ""
+ "la\\t%0,0(%1,%2)"
+ [(set_attr "op_type" "RX")
+ (set_attr "atype" "mem")
+ (set_attr "type" "la")])
+
+(define_insn "*addaddr_picL"
+ [(set (match_operand:SI 0 "register_operand" "=d")
+ (plus:SI (unspec:SI [(match_operand:SI 2 "register_operand" "a")] 101)
+ (match_operand:SI 1 "register_operand" "a")))]
+ ""
+ "la\\t%0,0(%1,%2)"
+ [(set_attr "op_type" "RX")
+ (set_attr "atype" "mem")
+ (set_attr "type" "la")])
+
+(define_insn "*addaddr_picN"
+ [(set (match_operand:SI 0 "register_operand" "=d")
+ (unspec:SI [(match_operand:SI 1 "register_operand" "a")] 101))]
+ ""
+ "la\\t%0,0(%1)"
+ [(set_attr "op_type" "RX")
+ (set_attr "atype" "mem")
+ (set_attr "type" "la")])
+
+(define_insn "*addsi3_cc"
+ [(set (reg 33)
+ (compare (plus:SI (match_operand:SI 1 "register_operand" "%0,0,0")
+ (match_operand:SI 2 "general_operand" "d,K,m"))
+ (const_int 0)))
+ (set (match_operand:SI 0 "register_operand" "=d,d,d")
+ (plus:SI (match_dup 1) (match_dup 2)))]
+ "s390_match_ccmode(insn, CCSmode)"
+ "@
+ ar\\t%0,%2
+ ahi\\t%0,%h2
+ a\\t%0,%2"
+ [(set_attr "op_type" "RR,RI,RX")
+ (set_attr "atype" "reg,reg,mem")
+ (set_attr "type" "set")])
+
+(define_insn "*addsi3_cconly"
+ [(set (reg 33)
+ (compare (plus:SI (match_operand:SI 1 "register_operand" "%0,0,0")
+ (match_operand:SI 2 "general_operand" "d,K,m"))
+ (const_int 0)))
+ (clobber (match_scratch:SI 0 "=d,d,d"))]
+ "s390_match_ccmode(insn, CCSmode)"
+ "@
+ ar\\t%0,%2
+ ahi\\t%0,%h2
+ a\\t%0,%2"
+ [(set_attr "op_type" "RR,RI,RX")
+ (set_attr "atype" "reg,reg,mem")
+ (set_attr "type" "set")])
+
+(define_insn "*addsi3_cconly2"
+ [(set (reg 33)
+ (compare (match_operand:SI 1 "register_operand" "%0,0,0")
+ (neg:SI (match_operand:SI 2 "general_operand" "d,K,m"))))
+ (clobber (match_scratch:SI 0 "=d,d,d"))]
+ "s390_match_ccmode(insn, CCSmode)"
+ "@
+ ar\\t%0,%2
+ ahi\\t%0,%h2
+ a\\t%0,%2"
+ [(set_attr "op_type" "RR,RI,RX")
+ (set_attr "atype" "reg,reg,mem")
+ (set_attr "type" "set")])
+
+(define_insn "addsi3"
+ [(set (match_operand:SI 0 "register_operand" "=d,d,d")
+ (plus:SI (match_operand:SI 1 "register_operand" "%0,0,0")
+ (match_operand:SI 2 "general_operand" "d,K,m")))
+ (clobber (reg:CC 33))]
+ ""
+ "@
+ ar\\t%0,%2
+ ahi\\t%0,%h2
+ a\\t%0,%2"
+ [(set_attr "op_type" "RR,RI,RX")
+ (set_attr "atype" "reg,reg,mem")
+ (set_attr "type" "set")])
+
+(define_insn "do_la"
+ [(set (match_operand:SI 0 "register_operand" "=a")
+ (match_operand:QI 1 "address_operand" "p"))]
+ "volatile_ok"
+ "la\\t%0,%a1"
+ [(set_attr "op_type" "RX")
+ (set_attr "atype" "mem")
+ (set_attr "type" "la")])
+
+(define_insn "*do_la_reg_0"
+ [(set (match_operand:SI 0 "register_operand" "=d")
+ (plus:SI (match_operand:SI 1 "register_operand" "%0")
+ (match_operand:SI 2 "register_operand" "d")))]
+ ""
+ "brxle\\t%0,%2,.+4"
+ [(set_attr "op_type" "RSI")
+ (set_attr "atype" "reg")
+ (set_attr "type" "set")])
+
+(define_insn "*reload_la_31"
+ [(set (match_operand:SI 0 "register_operand" "=d")
+ (plus:SI (match_operand:SI 1 "general_operand" "g")
+ (match_operand:SI 2 "general_operand" "g")))]
+ "reload_in_progress"
+ "#")
+
+(define_split
+ [(set (match_operand:SI 0 "register_operand" "")
+ (plus:SI (match_operand:SI 1 "general_operand" "")
+ (match_operand:SI 2 "register_operand" "")))]
+ "reload_completed
+ && !address_operand (gen_rtx_PLUS (SImode, operands[1], operands[2]), QImode)
+ && !rtx_equal_p (operands[0], operands[1])
+ && !rtx_equal_p (operands[0], operands[2])"
+ [(set (match_dup 0) (match_dup 1))
+ (set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))]
+ "")
+
+(define_split
+ [(set (match_operand:SI 0 "register_operand" "")
+ (plus:SI (match_operand:SI 1 "register_operand" "")
+ (match_operand:SI 2 "general_operand" "")))]
+ "reload_completed
+ && !address_operand (gen_rtx_PLUS (SImode, operands[1], operands[2]), QImode)
+ && !rtx_equal_p (operands[0], operands[1])
+ && !rtx_equal_p (operands[0], operands[2])"
+ [(set (match_dup 0) (match_dup 2))
+ (set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))]
+ "")
+
+(define_insn "addsi_64"
+ [(set (match_operand:SI 0 "register_operand" "=d,d")
+ (plus:SI (match_operand:SI 1 "register_operand" "%a,a")
+ (match_operand:SI 2 "nonmemory_operand" "J,a")))]
+ "TARGET_64BIT"
+ "@
+ la\\t%0,%c2(,%1)
+ la\\t%0,0(%1,%2)"
+ [(set_attr "op_type" "RX")
+ (set_attr "atype" "mem")
+ (set_attr "type" "la")])
+
+;
+; addhi3 instruction pattern(s).
+;
+
+(define_insn "addhi3"
+ [(set (match_operand:HI 0 "register_operand" "=d,d,d")
+ (plus:HI (match_operand:HI 1 "register_operand" "%0,0,0")
+ (match_operand:HI 2 "general_operand" "d,K,m")))
+ (clobber (reg:CC 33))]
+ ""
+ "@
+ ar\\t%0,%2
+ ahi\\t%0,%h2
+ ah\\t%0,%2"
+ [(set_attr "op_type" "RR,RI,RX")
+ (set_attr "atype" "reg,reg,mem")])
+
+
+;
+; addqi3 instruction pattern(s).
+;
+
+(define_insn "addqi3"
+ [(set (match_operand:QI 0 "register_operand" "=d,d")
+ (plus:QI (match_operand:QI 1 "register_operand" "%0,0")
+ (match_operand:QI 2 "general_operand" "a,n")))
+ (clobber (reg:CC 33))]
+ ""
+ "@
+ ar\\t%0,%2
+ ahi\\t%0,%h2"
+ [(set_attr "op_type" "RX,RX")
+ (set_attr "atype" "reg,mem")])
+
+
+;
+; adddf3 instruction pattern(s).
+;
+
+(define_expand "adddf3"
+ [(parallel
+ [(set (match_operand:DF 0 "register_operand" "=f,f")
+ (plus:DF (match_operand:DF 1 "register_operand" "%0,0")
+ (match_operand:DF 2 "nonimmediate_operand" "f,m")))
+ (clobber (reg:CC 33))])]
+ "TARGET_HARD_FLOAT"
+ "")
+
+(define_insn "*adddf3"
+ [(set (match_operand:DF 0 "register_operand" "=f,f")
+ (plus:DF (match_operand:DF 1 "register_operand" "%0,0")
+ (match_operand:DF 2 "nonimmediate_operand" "f,m")))
+ (clobber (reg:CC 33))]
+ "TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT"
+ "@
+ adbr\\t%0,%2
+ adb\\t%0,%2"
+ [(set_attr "op_type" "RR,RX")
+ (set_attr "atype" "reg,mem")])
+
+(define_insn "*adddf3_ibm"
+ [(set (match_operand:DF 0 "register_operand" "=f,f")
+ (plus:DF (match_operand:DF 1 "register_operand" "%0,0")
+ (match_operand:DF 2 "nonimmediate_operand" "f,m")))
+ (clobber (reg:CC 33))]
+ "TARGET_HARD_FLOAT && TARGET_IBM_FLOAT"
+ "@
+ adr\\t%0,%2
+ ad\\t%0,%2"
+ [(set_attr "op_type" "RR,RX")
+ (set_attr "atype" "reg,mem")])
+
+;
+; addsf3 instruction pattern(s).
+;
+
+(define_expand "addsf3"
+ [(parallel
+ [(set (match_operand:SF 0 "register_operand" "=f,f")
+ (plus:SF (match_operand:SF 1 "register_operand" "%0,0")
+ (match_operand:SF 2 "nonimmediate_operand" "f,m")))
+ (clobber (reg:CC 33))])]
+ "TARGET_HARD_FLOAT"
+ "")
+
+(define_insn "*addsf3"
+ [(set (match_operand:SF 0 "register_operand" "=f,f")
+ (plus:SF (match_operand:SF 1 "register_operand" "%0,0")
+ (match_operand:SF 2 "nonimmediate_operand" "f,m")))
+ (clobber (reg:CC 33))]
+ "TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT"
+ "@
+ aebr\\t%0,%2
+ aeb\\t%0,%2"
+ [(set_attr "op_type" "RR,RX")
+ (set_attr "atype" "reg,mem")])
+
+(define_insn "*addsf3"
+ [(set (match_operand:SF 0 "register_operand" "=f,f")
+ (plus:SF (match_operand:SF 1 "register_operand" "%0,0")
+ (match_operand:SF 2 "nonimmediate_operand" "f,m")))
+ (clobber (reg:CC 33))]
+ "TARGET_HARD_FLOAT && TARGET_IBM_FLOAT"
+ "@
+ aer\\t%0,%2
+ ae\\t%0,%2"
+ [(set_attr "op_type" "RR,RX")
+ (set_attr "atype" "reg,mem")])
+
+
+;;
+;;- Subtract instructions.
+;;
+
+;
+; subdi3 instruction pattern(s).
+;
+
+(define_insn "*subdi3_64"
+ [(set (match_operand:DI 0 "register_operand" "=d,d")
+ (minus:DI (match_operand:DI 1 "register_operand" "0,0")
+ (match_operand:DI 2 "general_operand" "d,m") ) )
+ (clobber (reg:CC 33))]
+ "TARGET_64BIT"
+ "@
+ sgr\\t%0,%2
+ sg\\t%0,%2"
+ [(set_attr "op_type" "RRE,RRE")
+ (set_attr "atype" "reg,mem")
+ (set_attr "type" "set")])
+
+(define_insn "subdi3"
+ [(set (match_operand:DI 0 "register_operand" "=d,d")
+ (minus:DI (match_operand:DI 1 "register_operand" "0,0")
+ (match_operand:DI 2 "nonimmediate_operand" "d,m")))
+ (clobber (reg:CC 33))]
+ ""
+ "*
+{
+ switch (which_alternative)
+ {
+ case 0: /* d <- d */
+ output_asm_insn (\"sr\\t%0,%2\", operands);
+ output_asm_insn (\"slr\\t%N0,%N2\", operands);
+ break;
+ case 1: /* d <- m */
+ output_asm_insn (\"s\\t%0,%2\", operands);
+ output_asm_insn (\"sl\\t%N0,%N2\", operands);
+ break;
+ }
+
+ output_asm_insn (\"brc\\t11,.+8\", operands);
+ return \"ahi\\t%0,-1\";
+}"
+ [(set_attr "op_type" "NN,NN")
+ (set_attr "atype" "reg,mem")
+ (set_attr "length" "12,16")])
+
+;
+; subsi3 instruction pattern(s).
+;
+
+(define_insn "*subsi3_cc"
+ [(set (reg 33)
+ (compare (minus:SI (match_operand:SI 1 "register_operand" "0,0")
+ (match_operand:SI 2 "general_operand" "d,m"))
+ (const_int 0)))
+ (set (match_operand:SI 0 "register_operand" "=d,d")
+ (minus:SI (match_dup 1) (match_dup 2)))]
+ "s390_match_ccmode(insn, CCSmode)"
+ "@
+ sr\\t%0,%2
+ s\\t%0,%2"
+ [(set_attr "op_type" "RR,RX")
+ (set_attr "atype" "reg,mem")
+ (set_attr "type" "set")])
+
+(define_insn "*subsi3_cconly"
+ [(set (reg 33)
+ (compare (minus:SI (match_operand:SI 1 "register_operand" "0,0")
+ (match_operand:SI 2 "general_operand" "d,m"))
+ (const_int 0)))
+ (clobber (match_scratch:SI 0 "=d,d"))]
+ "s390_match_ccmode(insn, CCSmode)"
+ "@
+ sr\\t%0,%2
+ s\\t%0,%2"
+ [(set_attr "op_type" "RR,RX")
+ (set_attr "atype" "reg,mem")
+ (set_attr "type" "set")])
+
+(define_insn "subsi3"
+ [(set (match_operand:SI 0 "register_operand" "=d,d")
+ (minus:SI (match_operand:SI 1 "register_operand" "0,0")
+ (match_operand:SI 2 "general_operand" "d,m")))
+ (clobber (reg:CC 33))]
+ ""
+ "@
+ sr\\t%0,%2
+ s\\t%0,%2"
+ [(set_attr "op_type" "RR,RX")
+ (set_attr "atype" "reg,mem")
+ (set_attr "type" "set")])
+
+;
+; subhi3 instruction pattern(s).
+;
+
+(define_insn "subhi3"
+ [(set (match_operand:HI 0 "register_operand" "=d,d,d")
+ (minus:HI (match_operand:HI 1 "register_operand" "0,0,0")
+ (match_operand:HI 2 "nonimmediate_operand" "d,K,m")))
+ (clobber (reg:CC 33))]
+ ""
+ "@
+ sr\\t%0,%2
+ ahi\\t%0,-%h2
+ sh\\t%0,%2"
+ [(set_attr "op_type" "RR,RI,RX")
+ (set_attr "atype" "reg,reg,mem")])
+
+;
+; subqi3 instruction pattern(s).
+;
+
+(define_insn "subqi3"
+ [(set (match_operand:QI 0 "register_operand" "=d")
+ (minus:QI (match_operand:QI 1 "register_operand" "0")
+ (match_operand:QI 2 "register_operand" "d")))
+ (clobber (reg:CC 33))]
+ ""
+ "sr\\t%0,%2"
+ [(set_attr "op_type" "RR")])
+
+;
+; subdf3 instruction pattern(s).
+;
+
+(define_expand "subdf3"
+ [(parallel
+ [(set (match_operand:DF 0 "register_operand" "=f,f")
+ (minus:DF (match_operand:DF 1 "register_operand" "0,0")
+ (match_operand:DF 2 "nonimmediate_operand" "f,m")))
+ (clobber (reg:CC 33))])]
+ "TARGET_HARD_FLOAT"
+ "")
+
+(define_insn "*subdf3"
+ [(set (match_operand:DF 0 "register_operand" "=f,f")
+ (minus:DF (match_operand:DF 1 "register_operand" "0,0")
+ (match_operand:DF 2 "nonimmediate_operand" "f,m")))
+ (clobber (reg:CC 33))]
+ "TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT"
+ "@
+ sdbr\\t%0,%2
+ sdb\\t%0,%2"
+ [(set_attr "op_type" "RR,RX")
+ (set_attr "atype" "reg,mem")])
+
+(define_insn "*subdf3_ibm"
+ [(set (match_operand:DF 0 "register_operand" "=f,f")
+ (minus:DF (match_operand:DF 1 "register_operand" "0,0")
+ (match_operand:DF 2 "nonimmediate_operand" "f,m")))
+ (clobber (reg:CC 33))]
+ "TARGET_HARD_FLOAT && TARGET_IBM_FLOAT"
+ "@
+ sdr\\t%0,%2
+ sd\\t%0,%2"
+ [(set_attr "op_type" "RR,RX")
+ (set_attr "atype" "reg,mem")])
+
+;
+; subsf3 instruction pattern(s).
+;
+
+(define_expand "subsf3"
+ [(parallel
+ [(set (match_operand:SF 0 "register_operand" "=f,f")
+ (minus:SF (match_operand:SF 1 "register_operand" "0,0")
+ (match_operand:SF 2 "nonimmediate_operand" "f,m")))
+ (clobber (reg:CC 33))])]
+ "TARGET_HARD_FLOAT"
+ "")
+
+(define_insn "*subsf3"
+ [(set (match_operand:SF 0 "register_operand" "=f,f")
+ (minus:SF (match_operand:SF 1 "register_operand" "0,0")
+ (match_operand:SF 2 "nonimmediate_operand" "f,m")))
+ (clobber (reg:CC 33))]
+ "TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT"
+ "@
+ sebr\\t%0,%2
+ seb\\t%0,%2"
+ [(set_attr "op_type" "RR,RX")
+ (set_attr "atype" "reg,mem")])
+
+(define_insn "*subsf3_ibm"
+ [(set (match_operand:SF 0 "register_operand" "=f,f")
+ (minus:SF (match_operand:SF 1 "register_operand" "0,0")
+ (match_operand:SF 2 "nonimmediate_operand" "f,m")))
+ (clobber (reg:CC 33))]
+ "TARGET_HARD_FLOAT && TARGET_IBM_FLOAT"
+ "@
+ ser\\t%0,%2
+ se\\t%0,%2"
+ [(set_attr "op_type" "RR,RX")
+ (set_attr "atype" "reg,mem")])
+
+
+;;
+;;- Multiply instructions.
+;;
+
+(define_expand "muldi3"
+ [(parallel
+ [(set (match_operand:DI 0 "register_operand" "")
+ (mult:DI (match_operand:DI 1 "register_operand" "")
+ (match_operand:DI 2 "register_operand" "")))
+ (clobber (reg:CC 33))])]
+ ""
+ "
+{
+ if (!TARGET_64BIT)
+ {
+ rtx label1 = gen_label_rtx ();
+ rtx label2 = gen_label_rtx ();
+ rtx op0_0 = operand_subword (operands[0], 0 ,1, DImode);
+ rtx op0_1 = operand_subword (operands[0], 1 ,1, DImode);
+ rtx temp1_0 = gen_reg_rtx (SImode);
+ rtx temp1_1 = gen_reg_rtx (SImode);
+ rtx temp2_0 = gen_reg_rtx (SImode);
+ rtx temp2_1 = gen_reg_rtx (SImode);
+
+ emit_move_insn (temp1_0, operand_subword (operands[1], 0 ,1, DImode));
+ emit_move_insn (temp1_1, operand_subword (operands[1], 1 ,1, DImode));
+ emit_move_insn (temp2_0, operand_subword (operands[2], 0 ,1, DImode));
+ emit_move_insn (temp2_1, operand_subword (operands[2], 1 ,1, DImode));
+ emit_move_insn (op0_1, temp1_1);
+ emit_insn (gen_mulsi_6432 (operands[0], operands[0], temp2_1));
+
+ emit_insn (gen_cmpsi (temp1_1, const0_rtx));
+ emit_jump_insn (gen_bge (label1));
+ emit_insn (gen_addsi3 (op0_0, op0_0, temp2_1));
+ emit_label (label1);
+ emit_insn (gen_cmpsi (temp2_1, const0_rtx));
+ emit_jump_insn (gen_bge (label2));
+ emit_insn (gen_addsi3 (op0_0, op0_0, temp1_1));
+ emit_label (label2);
+
+ emit_insn (gen_mulsi3 (temp2_1, temp2_1, temp1_0));
+ emit_insn (gen_addsi3 (op0_0, op0_0, temp2_1));
+
+ emit_insn (gen_mulsi3 (temp1_1, temp1_1, temp2_0));
+ emit_insn (gen_addsi3 (op0_0, op0_0, temp1_1));
+
+ DONE;
+ }
+}")
+
+(define_insn "*muldi3_64"
+ [(set (match_operand:DI 0 "register_operand" "=d,d,d")
+ (mult:DI (match_operand:DI 1 "register_operand" "%0,0,0")
+ (match_operand:DI 2 "general_operand" "d,K,m")))
+ (clobber (reg:CC 33))]
+ "TARGET_64BIT"
+ "@
+ msgr\\t%0,%2
+ mghi\\t%0,%h2
+ msg\\t%0,%2"
+ [(set_attr "op_type" "RRE,RI,RX")
+ (set_attr "cycle" "n")
+ (set_attr "atype" "reg,reg,mem")
+ (set_attr "type" "set")])
+
+;
+; mulsi3 instruction pattern(s).
+;
+
+(define_insn "mulsi3"
+ [(set (match_operand:SI 0 "register_operand" "=d,d,d")
+ (mult:SI (match_operand:SI 1 "register_operand" "%0,0,0")
+ (match_operand:SI 2 "general_operand" "d,K,m")))
+ (clobber (reg:CC 33))]
+ ""
+ "@
+ msr\\t%0,%2
+ mhi\\t%0,%h2
+ ms\\t%0,%2"
+ [(set_attr "op_type" "RRE,RI,RX")
+ (set_attr "cycle" "n")
+ (set_attr "atype" "reg,reg,mem")
+ (set_attr "type" "set")])
+
+(define_insn "mulsi_6432"
+ [(set (match_operand:DI 0 "register_operand" "=d,d")
+ (mult:DI (sign_extend:DI
+ (subreg:SI (match_operand:DI 1 "register_operand" "0,0") 4))
+ (sign_extend:DI
+ (match_operand:SI 2 "general_operand" "d,m"))))
+ (clobber (reg:CC 33))]
+ "!TARGET_64BIT"
+ "@
+ mr\\t%0,%2
+ m\\t%0,%2"
+ [(set_attr "op_type" "RR,RX")
+ (set_attr "cycle" "n")
+ (set_attr "atype" "reg,mem")
+ (set_attr "type" "set")])
+
+
+;
+; muldf3 instruction pattern(s).
+;
+
+(define_expand "muldf3"
+ [(parallel
+ [(set (match_operand:DF 0 "register_operand" "=f,f")
+ (mult:DF (match_operand:DF 1 "register_operand" "%0,0")
+ (match_operand:DF 2 "nonimmediate_operand" "f,m")))
+ (clobber (reg:CC 33))])]
+ "TARGET_HARD_FLOAT"
+ "")
+
+(define_insn "*muldf3"
+ [(set (match_operand:DF 0 "register_operand" "=f,f")
+ (mult:DF (match_operand:DF 1 "register_operand" "%0,0")
+ (match_operand:DF 2 "nonimmediate_operand" "f,m")))
+ (clobber (reg:CC 33))]
+ "TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT"
+ "@
+ mdbr\\t%0,%2
+ mdb\\t%0,%2"
+ [(set_attr "op_type" "RR,RX")
+ (set_attr "cycle" "n")
+ (set_attr "atype" "reg,mem")])
+
+(define_insn "*muldf3_ibm"
+ [(set (match_operand:DF 0 "register_operand" "=f,f")
+ (mult:DF (match_operand:DF 1 "register_operand" "%0,0")
+ (match_operand:DF 2 "nonimmediate_operand" "f,m")))
+ (clobber (reg:CC 33))]
+ "TARGET_HARD_FLOAT && TARGET_IBM_FLOAT"
+ "@
+ mdr\\t%0,%2
+ md\\t%0,%2"
+ [(set_attr "op_type" "RR,RX")
+ (set_attr "cycle" "n")
+ (set_attr "atype" "reg,mem")])
+
+;
+; mulsf3 instruction pattern(s).
+;
+
+(define_expand "mulsf3"
+ [(parallel
+ [(set (match_operand:SF 0 "register_operand" "=f,f")
+ (mult:SF (match_operand:SF 1 "register_operand" "%0,0")
+ (match_operand:SF 2 "nonimmediate_operand" "f,m")))
+ (clobber (reg:CC 33))])]
+ "TARGET_HARD_FLOAT"
+ "")
+
+(define_insn "*mulsf3"
+ [(set (match_operand:SF 0 "register_operand" "=f,f")
+ (mult:SF (match_operand:SF 1 "register_operand" "%0,0")
+ (match_operand:SF 2 "nonimmediate_operand" "f,m")))
+ (clobber (reg:CC 33))]
+ "TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT"
+ "@
+ meebr\\t%0,%2
+ meeb\\t%0,%2"
+ [(set_attr "op_type" "RR,RX")
+ (set_attr "cycle" "n")
+ (set_attr "atype" "reg,mem")])
+
+(define_insn "*mulsf3_ibm"
+ [(set (match_operand:SF 0 "register_operand" "=f,f")
+ (mult:SF (match_operand:SF 1 "register_operand" "%0,0")
+ (match_operand:SF 2 "nonimmediate_operand" "f,m")))
+ (clobber (reg:CC 33))]
+ "TARGET_HARD_FLOAT && TARGET_IBM_FLOAT"
+ "@
+ mer\\t%0,%2
+ me\\t%0,%2"
+ [(set_attr "op_type" "RR,RX")
+ (set_attr "cycle" "n")
+ (set_attr "atype" "reg,mem")])
+
+
+;;
+;;- Divide and modulo instructions.
+;;
+
+;
+; divdi3 and moddi3 instruction pattern(s).
+;
+
+(define_expand "divdi3"
+ [(set (match_operand:DI 0 "register_operand" "=d")
+ (div:DI (match_operand:DI 1 "register_operand" "d")
+ (match_operand:DI 2 "general_operand" "")))]
+ "TARGET_64BIT"
+ "
+{
+ rtx op3 = gen_reg_rtx (TImode);
+
+ if (CONSTANT_P (operands[2]))
+ operands[2] = force_const_mem (DImode, operands[2]);
+
+ emit_move_insn (gen_rtx_SUBREG (DImode, op3, 0), const0_rtx);
+ emit_move_insn (gen_rtx_SUBREG (DImode, op3, 8), operands[1]);
+ emit_insn (gen_divmodtidi3 (op3, op3, operands[2]));
+ emit_move_insn (operands[0], gen_rtx_SUBREG (DImode, op3, 8));
+ DONE;
+}")
+
+(define_expand "moddi3"
+ [(set (match_operand:DI 0 "register_operand" "=d")
+ (mod:DI (match_operand:DI 1 "register_operand" "d")
+ (match_operand:DI 2 "general_operand" "")))]
+ "TARGET_64BIT"
+ "
+{
+ rtx op3 = gen_reg_rtx (TImode);
+
+ if (CONSTANT_P (operands[2]))
+ operands[2] = force_const_mem (DImode, operands[2]);
+
+ emit_move_insn (gen_rtx_SUBREG (DImode, op3, 0), const0_rtx);
+ emit_move_insn (gen_rtx_SUBREG (DImode, op3, 8), operands[1]);
+ emit_insn (gen_divmodtidi3 (op3, op3, operands[2]));
+ emit_move_insn (operands[0], gen_rtx_SUBREG (DImode, op3, 0));
+ DONE;
+}")
+
+(define_insn "divmodtidi3"
+ [(set (subreg:DI (match_operand:TI 0 "register_operand" "=d,d") 0)
+ (truncate:DI
+ (mod:TI (match_operand:TI 1 "register_operand" "0,0")
+ (sign_extend:TI
+ (match_operand:DI 2 "nonimmediate_operand" "d,m")))))
+ (set (subreg:DI (match_dup 0) 8)
+ (truncate:DI (div:TI (match_dup 1) (sign_extend:TI (match_dup 2)))))
+ (clobber (reg:CC 33))]
+ "TARGET_64BIT"
+ "@
+ dsgr\\t%0,%2
+ dsg\\t%0,%2"
+ [(set_attr "op_type" "RRE,RXE")
+ (set_attr "cycle" "n")
+ (set_attr "atype" "reg,mem")])
+
+;
+; udivdi3 and umoddi3 instruction pattern(s).
+;
+
+(define_expand "udivdi3"
+ [(set (match_operand:DI 0 "register_operand" "=d")
+ (udiv:DI (match_operand:DI 1 "register_operand" "d")
+ (match_operand:DI 2 "general_operand" "")))]
+ "TARGET_64BIT"
+ "
+{
+ rtx op3 = gen_reg_rtx(TImode);
+
+ if (CONSTANT_P (operands[2]))
+ operands[2] = force_const_mem (DImode, operands[2]);
+
+ emit_move_insn (gen_rtx_SUBREG (DImode, op3, 0), const0_rtx);
+ emit_move_insn (gen_rtx_SUBREG (DImode, op3, 8), operands[1]);
+ emit_insn (gen_udivmodtidi3 (op3, op3, operands[2]));
+ emit_move_insn (operands[0], gen_rtx_SUBREG (DImode, op3, 8));
+ DONE;
+}")
+
+(define_expand "umoddi3"
+ [(set (match_operand:DI 0 "register_operand" "=d")
+ (umod:DI (match_operand:DI 1 "register_operand" "d")
+ (match_operand:DI 2 "general_operand" "")))]
+ "TARGET_64BIT"
+ "
+{
+ rtx op3 = gen_reg_rtx (TImode);
+
+ if (CONSTANT_P (operands[2]))
+ operands[2] = force_const_mem (DImode, operands[2]);
+
+ emit_move_insn (gen_rtx_SUBREG (DImode, op3, 0), const0_rtx);
+ emit_move_insn (gen_rtx_SUBREG (DImode, op3, 8), operands[1]);
+ emit_insn (gen_udivmodtidi3 (op3, op3, operands[2]));
+ emit_move_insn (operands[0], gen_rtx_SUBREG (DImode, op3, 0));
+ DONE;
+}")
+
+(define_insn "udivmodtidi3"
+ [(set (subreg:DI (match_operand:TI 0 "register_operand" "=d,d") 0)
+ (truncate:DI
+ (umod:TI (match_operand:TI 1 "register_operand" "0,0")
+ (zero_extend:TI
+ (match_operand:DI 2 "nonimmediate_operand" "d,m")))))
+ (set (subreg:DI (match_dup 0) 8)
+ (truncate:DI (udiv:TI (match_dup 1) (zero_extend:TI (match_dup 2)))))
+ (clobber (reg:CC 33))]
+ "TARGET_64BIT"
+ "@
+ dlgr\\t%0,%2
+ dlg\\t%0,%2"
+ [(set_attr "op_type" "RRE,RXE")
+ (set_attr "cycle" "n")
+ (set_attr "atype" "reg,mem")])
+
+;
+; divsi3 and modsi3 instruction pattern(s).
+;
+
+(define_expand "divsi3"
+ [(set (match_operand:SI 0 "register_operand" "=d")
+ (div:SI (match_operand:SI 1 "register_operand" "d")
+ (match_operand:SI 2 "nonimmediate_operand" "")))]
+ "!TARGET_64BIT"
+ "
+{
+ rtx tmp = gen_reg_rtx (DImode);
+
+ if (CONSTANT_P (operands[2]))
+ operands[2] = force_const_mem (SImode, operands[2]);
+ else
+ operands[2] = force_reg (SImode, operands[2]);
+
+ emit_insn (gen_rtx_CLOBBER (DImode, tmp));
+ emit_move_insn (gen_rtx_SUBREG (SImode, tmp, 0), operands[1]);
+ emit_insn (gen_ashrdi3 (tmp, tmp, GEN_INT (32)));
+ emit_insn (gen_divmoddisi3 (tmp, tmp, operands[2]));
+ emit_move_insn (operands[0], gen_rtx_SUBREG (SImode, tmp, 4));
+ DONE;
+}")
+
+(define_expand "modsi3"
+ [(set (match_operand:SI 0 "register_operand" "=d")
+ (mod:SI (match_operand:SI 1 "register_operand" "d")
+ (match_operand:SI 2 "nonimmediate_operand" "")))]
+ "!TARGET_64BIT"
+ "
+{
+ rtx tmp = gen_reg_rtx (DImode);
+
+ if (CONSTANT_P (operands[2]))
+ operands[2] = force_const_mem (SImode, operands[2]);
+ else
+ operands[2] = force_reg (SImode, operands[2]);
+
+ emit_insn (gen_rtx_CLOBBER (DImode, tmp));
+ emit_insn (gen_movsi (gen_rtx_SUBREG (SImode, tmp, 0), operands[1]));
+ emit_insn (gen_ashrdi3 (tmp, tmp, GEN_INT (32)));
+ emit_insn (gen_divmoddisi3 (tmp, tmp, operands[2]));
+ emit_move_insn (operands[0], gen_rtx_SUBREG (SImode, tmp, 0));
+ DONE;
+}")
+
+(define_insn "divmoddisi3"
+ [(set (subreg:SI (match_operand:DI 0 "register_operand" "=d,d") 0)
+ (truncate:SI
+ (mod:DI (match_operand:DI 1 "register_operand" "0,0")
+ (sign_extend:DI
+ (match_operand:SI 2 "nonimmediate_operand" "d,m")))))
+ (set (subreg:SI (match_dup 0) 4)
+ (truncate:SI (div:DI (match_dup 1) (sign_extend:DI (match_dup 2)))))
+ (clobber (reg:CC 33))]
+ "!TARGET_64BIT"
+ "@
+ dr\\t%0,%2
+ d\\t%0,%2"
+ [(set_attr "op_type" "RR,RX")
+ (set_attr "cycle" "n")
+ (set_attr "atype" "reg,mem")])
+
+;
+; udivsi3 and umodsi3 instruction pattern(s).
+;
+
+(define_expand "udivsi3"
+ [(set (match_operand:SI 0 "register_operand" "=d")
+ (udiv:SI (match_operand:SI 1 "general_operand" "")
+ (match_operand:SI 2 "general_operand" "")))]
+ "!TARGET_64BIT"
+ "
+{
+ rtx dr_0, dr_1, tmp;
+
+ tmp = gen_reg_rtx (DImode);
+ dr_0 = gen_rtx_SUBREG (SImode, tmp, 0);
+ dr_1 = gen_rtx_SUBREG (SImode, tmp, 4);
+
+ if (CONSTANT_P (operands[2]))
+ {
+ if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0)
+ {
+ rtx label1 = gen_label_rtx ();
+
+ emit_move_insn (dr_0, operands[1]);
+ emit_move_insn (dr_1, const0_rtx);
+ emit_insn (gen_cmpsi (dr_0, operands[2]));
+ emit_jump_insn (gen_bltu (label1));
+ emit_move_insn (dr_1, const1_rtx);
+ emit_label (label1);
+ }
+ else
+ {
+ operands[2] = force_const_mem (SImode, operands[2]);
+ emit_move_insn (gen_rtx_SUBREG (SImode, tmp, 0), const0_rtx);
+ emit_move_insn (gen_rtx_SUBREG (SImode, tmp, 4), operands[1]);
+ emit_insn (gen_divmoddisi3 (tmp, tmp, operands[2]));
+ }
+ }
+ else
+ {
+ rtx label1 = gen_label_rtx ();
+ rtx label2 = gen_label_rtx ();
+ rtx label3 = gen_label_rtx ();
+
+ operands[1] = force_reg (SImode, operands[1]);
+ operands[2] = force_reg (SImode, operands[2]);
+
+ emit_move_insn (dr_1, const0_rtx);
+ emit_insn (gen_cmpsi (operands[2], operands[1]));
+ emit_jump_insn (gen_bgtu (label3));
+ emit_insn (gen_cmpsi (operands[2], const1_rtx));
+ emit_jump_insn (gen_blt (label2));
+ emit_insn (gen_cmpsi (operands[2], const1_rtx));
+ emit_jump_insn (gen_beq (label1));
+ emit_move_insn (gen_rtx_SUBREG (SImode, tmp, 0), const0_rtx);
+ emit_move_insn (gen_rtx_SUBREG (SImode, tmp, 4), operands[1]);
+ emit_insn (gen_divmoddisi3 (tmp, tmp, operands[2]));
+ emit_jump_insn (gen_jump (label3));
+ emit_label (label1);
+ emit_move_insn (dr_1, operands[1]);
+ emit_jump_insn (gen_jump (label3));
+ emit_label (label2);
+ emit_move_insn (dr_1, const1_rtx);
+ emit_label (label3);
+ }
+
+ emit_move_insn (operands[0], dr_1);
+ DONE;
+}")
+
+(define_expand "umodsi3"
+ [(set (match_operand:SI 0 "register_operand" "=d")
+ (umod:SI (match_operand:SI 1 "nonimmediate_operand" "")
+ (match_operand:SI 2 "nonimmediate_operand" "")))]
+ "!TARGET_64BIT"
+ "
+{
+ rtx dr_0, dr_1, tmp;
+
+ tmp = gen_reg_rtx (DImode);
+ dr_0 = gen_rtx_SUBREG (SImode, tmp, 0);
+ dr_1 = gen_rtx_SUBREG (SImode, tmp, 4);
+
+ if (CONSTANT_P (operands[2]))
+ {
+ if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) <= 0)
+ {
+ rtx label1 = gen_label_rtx ();
+
+ emit_move_insn (dr_0, operands[1]);
+ emit_insn (gen_cmpsi (dr_0, operands[2]));
+ emit_jump_insn (gen_bltu (label1));
+ emit_insn (gen_abssi2 (dr_0, operands[2]));
+ emit_insn (gen_addsi3 (dr_0,dr_0, operands[1]));
+ emit_label (label1);
+ }
+ else
+ {
+ operands[2] = force_const_mem (SImode, operands[2]);
+ emit_move_insn (gen_rtx_SUBREG (SImode, tmp, 0), const0_rtx);
+ emit_move_insn (gen_rtx_SUBREG (SImode, tmp, 4), operands[1]);
+ emit_insn (gen_divmoddisi3 (tmp, tmp, operands[2]));
+ }
+ }
+ else
+ {
+ rtx label1 = gen_label_rtx ();
+ rtx label2 = gen_label_rtx ();
+ rtx label3 = gen_label_rtx ();
+
+ operands[1] = force_reg (SImode, operands[1]);
+ operands[2] = force_reg (SImode, operands[2]);
+
+ emit_move_insn(dr_0, operands[1]);
+ emit_insn (gen_cmpsi (operands[2], dr_0));
+ emit_jump_insn (gen_bgtu (label3));
+ emit_insn (gen_cmpsi (operands[2], const1_rtx));
+ emit_jump_insn (gen_blt (label2));
+ emit_insn (gen_cmpsi (operands[2], const1_rtx));
+ emit_jump_insn (gen_beq (label1));
+ emit_move_insn (gen_rtx_SUBREG (SImode, tmp, 0), const0_rtx);
+ emit_move_insn (gen_rtx_SUBREG (SImode, tmp, 4), operands[1]);
+ emit_insn (gen_divmoddisi3 (tmp, tmp, operands[2]));
+ emit_jump_insn (gen_jump (label3));
+ emit_label (label1);
+ emit_move_insn (dr_0, const0_rtx);
+ emit_jump_insn (gen_jump (label3));
+ emit_label (label2);
+ emit_insn (gen_subsi3 (dr_0, dr_0, operands[2]));
+ emit_label (label3);
+ }
+
+ emit_move_insn (operands[0], dr_0);
+ DONE;
+}")
+
+;
+; divdf3 instruction pattern(s).
+;
+
+(define_expand "divdf3"
+ [(parallel
+ [(set (match_operand:DF 0 "nonimmediate_operand" "=f,f")
+ (div:DF (match_operand:DF 1 "general_operand" "0,0")
+ (match_operand:DF 2 "nonimmediate_operand" "f,m")))
+ (clobber (reg:CC 33))])]
+ "TARGET_HARD_FLOAT"
+ "")
+
+(define_insn "*divdf3"
+ [(set (match_operand:DF 0 "nonimmediate_operand" "=f,f")
+ (div:DF (match_operand:DF 1 "general_operand" "0,0")
+ (match_operand:DF 2 "nonimmediate_operand" "f,m")))
+ (clobber (reg:CC 33))]
+ "TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT"
+ "@
+ ddbr\\t%0,%2
+ ddb\\t%0,%2"
+ [(set_attr "op_type" "RR,RX")
+ (set_attr "cycle" "n")
+ (set_attr "atype" "reg,mem")])
+
+(define_insn "*divdf3_ibm"
+ [(set (match_operand:DF 0 "nonimmediate_operand" "=f,f")
+ (div:DF (match_operand:DF 1 "general_operand" "0,0")
+ (match_operand:DF 2 "nonimmediate_operand" "f,m")))
+ (clobber (reg:CC 33))]
+ "TARGET_HARD_FLOAT && TARGET_IBM_FLOAT"
+ "@
+ ddr\\t%0,%2
+ dd\\t%0,%2"
+ [(set_attr "op_type" "RR,RX")
+ (set_attr "cycle" "n")
+ (set_attr "atype" "reg,mem")])
+
+;
+; divsf3 instruction pattern(s).
+;
+
+(define_expand "divsf3"
+ [(parallel
+ [(set (match_operand:SF 0 "nonimmediate_operand" "=f,f")
+ (div:SF (match_operand:SF 1 "nonimmediate_operand" "0,0")
+ (match_operand:SF 2 "nonimmediate_operand" "f,m")))
+ (clobber (reg:CC 33))])]
+ "TARGET_HARD_FLOAT"
+ "")
+
+(define_insn "*divsf3"
+ [(set (match_operand:SF 0 "nonimmediate_operand" "=f,f")
+ (div:SF (match_operand:SF 1 "nonimmediate_operand" "0,0")
+ (match_operand:SF 2 "nonimmediate_operand" "f,m")))
+ (clobber (reg:CC 33))]
+ "TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT"
+ "@
+ debr\\t%0,%2
+ deb\\t%0,%2"
+ [(set_attr "op_type" "RR,RX")
+ (set_attr "cycle" "n")
+ (set_attr "atype" "reg,mem")])
+
+(define_insn "*divsf3"
+ [(set (match_operand:SF 0 "nonimmediate_operand" "=f,f")
+ (div:SF (match_operand:SF 1 "nonimmediate_operand" "0,0")
+ (match_operand:SF 2 "nonimmediate_operand" "f,m")))
+ (clobber (reg:CC 33))]
+ "TARGET_HARD_FLOAT && TARGET_IBM_FLOAT"
+ "@
+ der\\t%0,%2
+ de\\t%0,%2"
+ [(set_attr "op_type" "RR,RX")
+ (set_attr "cycle" "n")
+ (set_attr "atype" "reg,mem")])
+
+
+;;
+;;- And instructions.
+;;
+
+;
+; anddi3 instruction pattern(s).
+;
+
+(define_insn "*anddi3_cc"
+ [(set (reg 33)
+ (compare (and:DI (match_operand:DI 1 "r_or_s_operand" "%0,0,0")
+ (match_operand:DI 2 "r_or_s_operand" "d,m,Q"))
+ (const_int 0)))
+ (set (match_operand:DI 0 "r_or_s_operand" "=d,d,Q")
+ (and:DI (match_dup 1) (match_dup 2)))]
+ "s390_match_ccmode(insn, CCTmode) && TARGET_64BIT"
+ "@
+ ngr\\t%0,%2
+ ng\\t%0,%2
+ nc\\t%O0(8,%R0),%2"
+ [(set_attr "op_type" "RR,RX,SS")
+ (set_attr "atype" "reg,mem,mem")
+ (set_attr "type" "set")])
+
+(define_insn "*anddi3_cconly"
+ [(set (reg 33)
+ (compare (and:DI (match_operand:DI 1 "register_operand" "%0,0")
+ (match_operand:DI 2 "r_or_s_operand" "d,m"))
+ (const_int 0)))
+ (clobber (match_scratch:DI 0 "=d,d"))]
+ "s390_match_ccmode(insn, CCTmode) && TARGET_64BIT"
+ "@
+ ngr\\t%0,%2
+ ng\\t%0,%2"
+ [(set_attr "op_type" "RR,RX")
+ (set_attr "atype" "reg,mem")
+ (set_attr "type" "set")])
+
+(define_insn "anddi3"
+ [(set (match_operand:DI 0 "r_or_s_operand" "=d,d,Q")
+ (and:DI (match_operand:DI 1 "r_or_s_operand" "%0,0,0")
+ (match_operand:DI 2 "r_or_s_operand" "d,m,Q")))
+ (clobber (reg:CC 33))]
+ "TARGET_64BIT"
+ "@
+ ngr\\t%0,%2
+ ng\\t%0,%2
+ nc\\t%O0(8,%R0),%2"
+ [(set_attr "op_type" "RR,RX,SS")
+ (set_attr "atype" "reg,mem,mem")
+ (set_attr "type" "set")])
+
+;
+; andsi3 instruction pattern(s).
+;
+
+(define_insn "*andsi3_cc"
+ [(set (reg 33)
+ (compare (and:SI (match_operand:SI 1 "r_or_s_operand" "%0,0,0")
+ (match_operand:SI 2 "r_or_s_operand" "d,m,Q"))
+ (const_int 0)))
+ (set (match_operand:SI 0 "r_or_s_operand" "=d,d,Q")
+ (and:SI (match_dup 1) (match_dup 2)))]
+ "s390_match_ccmode(insn, CCTmode)"
+ "@
+ nr\\t%0,%2
+ n\\t%0,%2
+ nc\\t%O0(4,%R0),%2"
+ [(set_attr "op_type" "RR,RX,SS")
+ (set_attr "atype" "reg,mem,mem")
+ (set_attr "type" "set")])
+
+(define_insn "*andsi3_cconly"
+ [(set (reg 33)
+ (compare (and:SI (match_operand:SI 1 "register_operand" "%0,0")
+ (match_operand:SI 2 "r_or_s_operand" "d,m"))
+ (const_int 0)))
+ (clobber (match_scratch:SI 0 "=d,d"))]
+ "s390_match_ccmode(insn, CCTmode)"
+ "@
+ nr\\t%0,%2
+ n\\t%0,%2"
+ [(set_attr "op_type" "RR,RX")
+ (set_attr "atype" "reg,mem")
+ (set_attr "type" "set")])
+
+(define_insn "andsi3"
+ [(set (match_operand:SI 0 "r_or_s_operand" "=d,d,Q")
+ (and:SI (match_operand:SI 1 "r_or_s_operand" "%0,0,0")
+ (match_operand:SI 2 "r_or_s_operand" "d,m,Q")))
+ (clobber (reg:CC 33))]
+ ""
+ "@
+ nr\\t%0,%2
+ n\\t%0,%2
+ nc\\t%O0(4,%R0),%2"
+ [(set_attr "op_type" "RR,RX,SS")
+ (set_attr "atype" "reg,mem,mem")
+ (set_attr "type" "set")])
+
+;
+; andhi3 instruction pattern(s).
+;
+
+(define_expand "andhi3"
+ [(parallel
+ [(set (match_operand:HI 0 "r_or_s_operand" "")
+ (and:HI (match_operand:HI 1 "r_or_s_operand" "")
+ (match_operand:HI 2 "r_or_s_operand" "")))
+ (clobber (reg:CC 33))])]
+ ""
+ "
+{
+ if (CONSTANT_P (operands[2]))
+ operands[2] = force_const_mem (HImode, operands[2]);
+}")
+
+(define_insn "*andhi3"
+ [(set (match_operand:HI 0 "r_or_s_operand" "=d,Q")
+ (and:HI (match_operand:HI 1 "r_or_s_operand" "%0,0")
+ (match_operand:HI 2 "r_or_s_operand" "d,Q")))
+ (clobber (reg:CC 33))]
+ ""
+ "@
+ nr\\t%0,%2
+ nc\\t%O0(2,%R0),%2"
+ [(set_attr "op_type" "RR,SS")
+ (set_attr "atype" "reg,mem")])
+
+;
+; andqi3 instruction pattern(s).
+;
+
+(define_insn "andqi3"
+ [(set (match_operand:QI 0 "r_or_s_operand" "=d,Q,Q")
+ (and:QI (match_operand:QI 1 "r_or_s_operand" "%0,0,0")
+ (match_operand:QI 2 "r_or_s_or_im8_operand" "d,n,Q")))
+ (clobber (reg:CC 33))]
+ ""
+ "@
+ nr\\t%0,%2
+ ni\\t%0,%b2
+ nc\\t%O0(1,%R0),%2"
+ [(set_attr "op_type" "RR,SI,SS")
+ (set_attr "atype" "reg,mem,mem")])
+
+
+;;
+;;- Bit set (inclusive or) instructions.
+;;
+
+;
+; iordi3 instruction pattern(s).
+;
+
+(define_insn "iordi3"
+ [(set (match_operand:DI 0 "r_or_s_operand" "=d,d,Q,d")
+ (ior:DI (match_operand:DI 1 "r_or_s_operand" "%0,0,0,0")
+ (match_operand:DI 2 "r_or_s_operand" "d,m,Q,L")))
+ (clobber (reg:CC 33))]
+ "TARGET_64BIT"
+ "@
+ ogr\\t%0,%2
+ og\\t%0,%2
+ oc\\t%O0(8,%R0),%2
+ oill\\t%0,%2"
+ [(set_attr "op_type" "RRE,RXE,SS,RI")
+ (set_attr "atype" "reg,mem,mem,reg")
+ (set_attr "type" "set")])
+
+;
+; iorsi3 instruction pattern(s).
+;
+
+(define_expand "iorsi3"
+ [(parallel
+ [(set (match_operand:SI 0 "r_or_s_operand" "")
+ (ior:SI (match_operand:SI 1 "r_or_s_operand" "")
+ (match_operand:SI 2 "r_or_s_operand" "")))
+ (clobber (reg:CC 33))])]
+ ""
+ "
+{
+ if (CONSTANT_P (operands[2]))
+ operands[2] = force_const_mem (SImode, operands[2]);
+}")
+
+(define_insn "*iorsi3"
+ [(set (match_operand:SI 0 "r_or_s_operand" "=d,d,Q")
+ (ior:SI (match_operand:SI 1 "r_or_s_operand" "%0,0,0")
+ (match_operand:SI 2 "r_or_s_operand" "d,m,Q")))
+ (clobber (reg:CC 33))]
+ ""
+ "@
+ or\\t%0,%2
+ o\\t%0,%2
+ oc\\t%O0(4,%R0),%2"
+ [(set_attr "op_type" "RR,RX,SS")
+ (set_attr "atype" "reg,mem,mem")
+ (set_attr "type" "set")])
+
+;
+; iorhi3 instruction pattern(s).
+;
+
+(define_expand "iorhi3"
+ [(parallel
+ [(set (match_operand:HI 0 "r_or_s_operand" "")
+ (ior:HI (match_operand:HI 1 "r_or_s_operand" "")
+ (match_operand:HI 2 "r_or_s_operand" "")))
+ (clobber (reg:CC 33))])]
+ ""
+ "
+{
+ if (CONSTANT_P (operands[2]))
+ operands[2] = force_const_mem (HImode, operands[2]);
+}")
+
+(define_insn "*iorhi3"
+ [(set (match_operand:HI 0 "r_or_s_operand" "=d,Q")
+ (ior:HI (match_operand:HI 1 "r_or_s_operand" "%0,0")
+ (match_operand:HI 2 "r_or_s_operand" "d,Q")))
+ (clobber (reg:CC 33))]
+ ""
+ "@
+ or\\t%0,%2
+ oc\\t%O0(2,%R0),%2"
+ [(set_attr "op_type" "RR,SS")
+ (set_attr "atype" "reg,mem")])
+
+;
+; iorqi3 instruction pattern(s).
+;
+
+(define_insn "iorqi3"
+ [(set (match_operand:QI 0 "r_or_s_operand" "=d,Q,Q")
+ (ior:QI (match_operand:QI 1 "r_or_s_operand" "%0,0,0")
+ (match_operand:QI 2 "r_or_s_or_im8_operand" "d,n,Q")))
+ (clobber (reg:CC 33))]
+ ""
+ "@
+ or\\t%0,%2
+ oi\\t%0,%b2
+ oc\\t%O0(1,%R0),%2"
+ [(set_attr "op_type" "RR,SI,SS")
+ (set_attr "atype" "reg,mem,mem")])
+
+
+;;
+;;- Xor instructions.
+;;
+
+;
+; xordi3 instruction pattern(s).
+;
+
+(define_insn "xordi3"
+ [(set (match_operand:DI 0 "r_or_s_operand" "=d,d,Q")
+ (xor:DI (match_operand:DI 1 "r_or_s_operand" "%0,0,0")
+ (match_operand:DI 2 "r_or_s_operand" "d,m,Q")))
+ (clobber (reg:CC 33))]
+ "TARGET_64BIT"
+ "@
+ xgr\\t%0,%2
+ xg\\t%0,%2
+ xc\\t%O0(8,%R0),%2"
+ [(set_attr "op_type" "RRE,RXE,SS")
+ (set_attr "atype" "reg,mem,mem")
+ (set_attr "type" "set")])
+
+;
+; xorsi3 instruction pattern(s).
+;
+
+(define_expand "xorsi3"
+ [(parallel
+ [(set (match_operand:SI 0 "r_or_s_operand" "")
+ (xor:SI (match_operand:SI 1 "r_or_s_operand" "")
+ (match_operand:SI 2 "r_or_s_operand" "")))
+ (clobber (reg:CC 33))])]
+ ""
+ "
+{
+ if (CONSTANT_P (operands[2]))
+ operands[2] = force_const_mem (SImode, operands[2]);
+}")
+
+(define_insn "*xorsi3"
+ [(set (match_operand:SI 0 "r_or_s_operand" "=d,d,Q")
+ (xor:SI (match_operand:SI 1 "r_or_s_operand" "%0,0,0")
+ (match_operand:SI 2 "r_or_s_operand" "d,m,Q")))
+ (clobber (reg:CC 33))]
+ ""
+ "@
+ xr\\t%0,%2
+ x\\t%0,%2
+ xc\\t%O0(4,%R0),%2"
+ [(set_attr "op_type" "RR,RX,SS")
+ (set_attr "atype" "reg,mem,mem")
+ (set_attr "type" "set")])
+
+;
+; xorhi3 instruction pattern(s).
+;
+
+(define_expand "xorhi3"
+ [(parallel
+ [(set (match_operand:HI 0 "r_or_s_operand" "")
+ (xor:HI (match_operand:HI 1 "r_or_s_operand" "")
+ (match_operand:HI 2 "r_or_s_operand" "")))
+ (clobber (reg:CC 33))])]
+ ""
+ "
+{
+ if (CONSTANT_P (operands[2]))
+ operands[2] = force_const_mem (HImode, operands[2]);
+}")
+
+(define_insn "*xorhi3"
+ [(set (match_operand:HI 0 "r_or_s_operand" "=d,Q")
+ (xor:HI (match_operand:HI 1 "r_or_s_operand" "%0,0")
+ (match_operand:HI 2 "r_or_s_operand" "d,Q")))
+ (clobber (reg:CC 33))]
+ ""
+ "@
+ xr\\t%0,%2
+ xc\\t%O0(2,%R0),%2"
+ [(set_attr "op_type" "RR,SS")
+ (set_attr "atype" "reg,mem")])
+
+;
+; xorqi3 instruction pattern(s).
+;
+
+(define_insn "xorqi3"
+ [(set (match_operand:QI 0 "r_or_s_operand" "=d,Q,Q")
+ (xor:QI (match_operand:QI 1 "r_or_s_operand" "0,0,0")
+ (match_operand:QI 2 "r_or_s_or_im8_operand" "d,n,Q")))
+ (clobber (reg:CC 33))]
+ ""
+ "@
+ xr\\t%0,%2
+ xi\\t%0,%b2
+ xc\\t%O0(1,%R0),%2"
+ [(set_attr "op_type" "RR,SI,SS")
+ (set_attr "atype" "reg,mem,mem")])
+
+
+;;
+;;- Negate instructions.
+;;
+
+;
+; negdi2 instruction pattern(s).
+;
+
+(define_expand "negdi2"
+ [(parallel
+ [(set (match_operand:DI 0 "register_operand" "=d")
+ (neg:DI (match_operand:DI 1 "register_operand" "d")))
+ (clobber (reg:CC 33))])]
+ ""
+ "")
+
+(define_insn "*negdi2_64"
+ [(set (match_operand:DI 0 "register_operand" "=d")
+ (neg:DI (match_operand:DI 1 "register_operand" "d")))
+ (clobber (reg:CC 33))]
+ "TARGET_64BIT"
+ "lcgr\\t%0,%1"
+ [(set_attr "op_type" "RR")
+ (set_attr "type" "set")])
+
+(define_insn "*negdi2_31"
+ [(set (match_operand:DI 0 "register_operand" "=d")
+ (neg:DI (match_operand:DI 1 "register_operand" "d")))
+ (clobber (reg:CC 33))]
+ "!TARGET_64BIT"
+ "*
+{
+ rtx xop[1];
+ xop[0] = gen_label_rtx ();
+ output_asm_insn (\"lcr\\t%0,%1\", operands);
+ output_asm_insn (\"lcr\\t%N0,%N1\", operands);
+ output_asm_insn (\"je\\t%l0\", xop);
+ output_asm_insn (\"bctr\\t%0,0\", operands);
+ ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, \"L\",
+ CODE_LABEL_NUMBER (xop[0]));
+ return \"\";
+}"
+ [(set_attr "op_type" "NN")
+ (set_attr "length" "10")])
+
+;
+; negsi2 instruction pattern(s).
+;
+
+(define_insn "negsi2"
+ [(set (match_operand:SI 0 "register_operand" "=d")
+ (neg:SI (match_operand:SI 1 "register_operand" "d")))
+ (clobber (reg:CC 33))]
+ ""
+ "lcr\\t%0,%1"
+ [(set_attr "op_type" "RR")
+ (set_attr "type" "set")])
+
+;
+; negdf2 instruction pattern(s).
+;
+
+(define_expand "negdf2"
+ [(parallel
+ [(set (match_operand:DF 0 "register_operand" "=f")
+ (neg:DF (match_operand:DF 1 "register_operand" "f")))
+ (clobber (reg:CC 33))])]
+ "TARGET_HARD_FLOAT"
+ "")
+
+(define_insn "*negdf2"
+ [(set (match_operand:DF 0 "register_operand" "=f")
+ (neg:DF (match_operand:DF 1 "register_operand" "f")))
+ (clobber (reg:CC 33))]
+ "TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT"
+ "lcdbr\\t%0,%1"
+ [(set_attr "op_type" "RR")])
+
+(define_insn "*negdf2_ibm"
+ [(set (match_operand:DF 0 "register_operand" "=f")
+ (neg:DF (match_operand:DF 1 "register_operand" "f")))
+ (clobber (reg:CC 33))]
+ "TARGET_HARD_FLOAT && TARGET_IBM_FLOAT"
+ "lcdr\\t%0,%1"
+ [(set_attr "op_type" "RR")])
+
+;
+; negsf2 instruction pattern(s).
+;
+
+(define_expand "negsf2"
+ [(parallel
+ [(set (match_operand:SF 0 "register_operand" "=f")
+ (neg:SF (match_operand:SF 1 "register_operand" "f")))
+ (clobber (reg:CC 33))])]
+ "TARGET_HARD_FLOAT"
+ "")
+
+(define_insn "*negsf2"
+ [(set (match_operand:SF 0 "register_operand" "=f")
+ (neg:SF (match_operand:SF 1 "register_operand" "f")))
+ (clobber (reg:CC 33))]
+ "TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT"
+ "lcebr\\t%0,%1"
+ [(set_attr "op_type" "RR")])
+
+(define_insn "*negsf2"
+ [(set (match_operand:SF 0 "register_operand" "=f")
+ (neg:SF (match_operand:SF 1 "register_operand" "f")))
+ (clobber (reg:CC 33))]
+ "TARGET_HARD_FLOAT && TARGET_IBM_FLOAT"
+ "lcer\\t%0,%1"
+ [(set_attr "op_type" "RR")])
+
+
+;;
+;;- Absolute value instructions.
+;;
+
+;
+; absdi2 instruction pattern(s).
+;
+
+(define_insn "absdi2"
+ [(set (match_operand:DI 0 "register_operand" "=d")
+ (abs:DI (match_operand:DI 1 "register_operand" "d")))
+ (clobber (reg:CC 33))]
+ "TARGET_64BIT"
+ "lpgr\\t%0,%1"
+ [(set_attr "op_type" "RRE")
+ (set_attr "type" "set")])
+
+;
+; abssi2 instruction pattern(s).
+;
+
+(define_insn "abssi2"
+ [(set (match_operand:SI 0 "register_operand" "=d")
+ (abs:SI (match_operand:SI 1 "register_operand" "d")))
+ (clobber (reg:CC 33))]
+ ""
+ "lpr\\t%0,%1"
+ [(set_attr "op_type" "RR")
+ (set_attr "type" "set")])
+
+;
+; abshi2 instruction pattern(s).
+;
+
+(define_insn "abshi2"
+ [(set (match_operand:HI 0 "register_operand" "=d")
+ (abs:HI (match_operand:HI 1 "register_operand" "d")))
+ (clobber (reg:CC 33))]
+ ""
+ "sll\\t%1,16\;sra\\t%1,16\;lpr\\t%0,%1"
+ [(set_attr "op_type" "NN")
+ (set_attr "cycle" "3")
+ (set_attr "length" "10")])
+
+;
+; absdf2 instruction pattern(s).
+;
+
+(define_expand "absdf2"
+ [(parallel
+ [(set (match_operand:DF 0 "register_operand" "=f")
+ (abs:DF (match_operand:DF 1 "register_operand" "f")))
+ (clobber (reg:CC 33))])]
+ "TARGET_HARD_FLOAT"
+ "")
+
+(define_insn "*absdf2"
+ [(set (match_operand:DF 0 "register_operand" "=f")
+ (abs:DF (match_operand:DF 1 "register_operand" "f")))
+ (clobber (reg:CC 33))]
+ "TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT"
+ "lpdbr\\t%0,%1"
+ [(set_attr "op_type" "RR")])
+
+(define_insn "*absdf2_ibm"
+ [(set (match_operand:DF 0 "register_operand" "=f")
+ (abs:DF (match_operand:DF 1 "register_operand" "f")))
+ (clobber (reg:CC 33))]
+ "TARGET_HARD_FLOAT && TARGET_IBM_FLOAT"
+ "lpdr\\t%0,%1"
+ [(set_attr "op_type" "RR")])
+
+;
+; abssf2 instruction pattern(s).
+;
+
+(define_expand "abssf2"
+ [(parallel
+ [(set (match_operand:SF 0 "register_operand" "=f")
+ (abs:SF (match_operand:SF 1 "register_operand" "f")))
+ (clobber (reg:CC 33))])]
+ "TARGET_HARD_FLOAT"
+ "")
+
+(define_insn "*abssf2"
+ [(set (match_operand:SF 0 "register_operand" "=f")
+ (abs:SF (match_operand:SF 1 "register_operand" "f")))
+ (clobber (reg:CC 33))]
+ "TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT"
+ "lpebr\\t%0,%1"
+ [(set_attr "op_type" "RR")])
+
+(define_insn "*abssf2_ibm"
+ [(set (match_operand:SF 0 "register_operand" "=f")
+ (abs:SF (match_operand:SF 1 "register_operand" "f")))
+ (clobber (reg:CC 33))]
+ "TARGET_HARD_FLOAT && TARGET_IBM_FLOAT"
+ "lper\\t%0,%1"
+ [(set_attr "op_type" "RR")])
+
+
+;;
+;;- One complement instructions.
+;;
+
+;
+; one_cmpldi2 instruction pattern(s).
+;
+
+(define_expand "one_cmpldi2"
+ [(parallel
+ [(set (match_operand:DI 0 "r_or_s_operand" "=d")
+ (not:DI (match_operand:DI 1 "r_or_s_operand" "0")))
+ (use (match_dup 2))
+ (clobber (reg:CC 33))])]
+ "TARGET_64BIT"
+ "{ operands[2] = force_const_mem (DImode, constm1_rtx); }")
+
+(define_insn "*one_cmpldi2"
+ [(set (match_operand:DI 0 "r_or_s_operand" "=d,Q")
+ (not:DI (match_operand:DI 1 "r_or_s_operand" "0,0")))
+ (use (match_operand:DI 2 "memory_operand" "m,m"))
+ (clobber (reg:CC 33))]
+ ""
+ "@
+ xg\\t%0,%2
+ xc\\t%O0(8,%R0),%2"
+ [(set_attr "op_type" "RR,SS")
+ (set_attr "atype" "mem")])
+
+;
+; one_cmplsi2 instruction pattern(s).
+;
+
+(define_expand "one_cmplsi2"
+ [(parallel
+ [(set (match_operand:SI 0 "r_or_s_operand" "=d")
+ (not:SI (match_operand:SI 1 "r_or_s_operand" "0")))
+ (use (match_dup 2))
+ (clobber (reg:CC 33))])]
+ ""
+ "{ operands[2] = force_const_mem (SImode, constm1_rtx); }")
+
+(define_insn "*one_cmplsi2"
+ [(set (match_operand:SI 0 "r_or_s_operand" "=d,Q")
+ (not:SI (match_operand:SI 1 "r_or_s_operand" "0,0")))
+ (use (match_operand:SI 2 "memory_operand" "m,m"))
+ (clobber (reg:CC 33))]
+ ""
+ "@
+ x\\t%0,%2
+ xc\\t%O0(4,%R0),%2"
+ [(set_attr "op_type" "RR,SS")
+ (set_attr "atype" "mem")])
+
+;
+; one_cmplhi2 instruction pattern(s).
+;
+
+(define_expand "one_cmplhi2"
+ [(parallel
+ [(set (match_operand:HI 0 "r_or_s_operand" "=d")
+ (not:HI (match_operand:HI 1 "r_or_s_operand" "0")))
+ (use (match_dup 2))
+ (clobber (reg:CC 33))])]
+ ""
+ "{ operands[2] = force_const_mem (SImode, constm1_rtx); }")
+
+(define_insn "*one_cmplhi2"
+ [(set (match_operand:HI 0 "r_or_s_operand" "=d,Q")
+ (not:HI (match_operand:HI 1 "r_or_s_operand" "0,0")))
+ (use (match_operand:SI 2 "memory_operand" "m,m"))
+ (clobber (reg:CC 33))]
+ ""
+ "@
+ x\\t%0,%2
+ xc\\t%O0(2,%R0),%2"
+ [(set_attr "op_type" "RX,SS")
+ (set_attr "atype" "mem")])
+
+;
+; one_cmplqi2 instruction pattern(s).
+;
+
+(define_insn "one_cmpqi2"
+ [(set (match_operand:QI 0 "memory_operand" "=Q")
+ (not:QI (match_operand:QI 1 "memory_operand" "0")))
+ (clobber (reg:CC 33))]
+ ""
+ "xi\\t%0,255"
+ [(set_attr "op_type" "SI")])
+
+
+;;
+;;- Rotate instructions.
+;;
+
+;
+; rotldi3 instruction pattern(s).
+;
+
+(define_insn "rotldi3"
+ [(set (match_operand:DI 0 "register_operand" "=d,d")
+ (rotate:DI (match_operand:DI 1 "register_operand" "d,d")
+ (match_operand:DI 2 "nonmemory_operand" "J,a")))
+ (clobber (reg:CC 33))]
+ "TARGET_64BIT"
+ "@
+ rllg\\t%0,%1,%c2
+ rllg\\t%0,%1,0(%2)"
+ [(set_attr "op_type" "RSE")
+ (set_attr "type" "set")])
+
+;
+; rotlsi3 instruction pattern(s).
+;
+
+(define_insn "rotlsi3"
+ [(set (match_operand:SI 0 "register_operand" "=d,d")
+ (rotate:SI (match_operand:SI 1 "register_operand" "d,d")
+ (match_operand:SI 2 "nonmemory_operand" "J,a")))
+ (clobber (reg:CC 33))]
+ "TARGET_64BIT"
+ "@
+ rll\\t%0,%1,%c2
+ rll\\t%0,%1,0(%2)"
+ [(set_attr "op_type" "RSE")
+ (set_attr "type" "set")])
+
+
+;;
+;;- Arithmetic shift instructions.
+;;
+;; for left shifts always setal shifts are used (ANSI-C)
+
+;
+; ashldi3 instruction pattern(s).
+;
+
+(define_expand "ashldi3"
+ [(parallel
+ [(set (match_operand:DI 0 "register_operand" "")
+ (ashift:DI (match_operand:DI 1 "register_operand" "")
+ (match_operand:SI 2 "nonmemory_operand" "")))
+ (clobber (reg:CC 33))])]
+ ""
+ "")
+
+(define_insn "*ashldi3_31"
+ [(set (match_operand:DI 0 "register_operand" "=d,d")
+ (ashift:DI (match_operand:DI 1 "register_operand" "0,0")
+ (match_operand:SI 2 "nonmemory_operand" "J,a")))
+ (clobber (reg:CC 33))]
+ "!TARGET_64BIT"
+ "@
+ sldl\\t%0,%c2
+ sldl\\t%0,0(%2)"
+ [(set_attr "op_type" "RS")
+ (set_attr "type" "set")])
+
+(define_insn "*ashldi3_64"
+ [(set (match_operand:DI 0 "register_operand" "=d,d")
+ (ashift:DI (match_operand:DI 1 "register_operand" "d,d")
+ (match_operand:SI 2 "nonmemory_operand" "J,a")))
+ (clobber (reg:CC 33))]
+ "TARGET_64BIT"
+ "@
+ sllg\\t%0,%1,%2
+ sllg\\t%0,%1,0(%2)"
+ [(set_attr "op_type" "RSE")
+ (set_attr "type" "set")])
+
+;
+; ashrdi3 instruction pattern(s).
+;
+
+(define_expand "ashrdi3"
+ [(parallel
+ [(set (match_operand:DI 0 "register_operand" "")
+ (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
+ (match_operand:SI 2 "nonmemory_operand" "")))
+ (clobber (reg:CC 33))])]
+ ""
+ "")
+
+(define_insn "*ashrdi3_31"
+ [(set (match_operand:DI 0 "register_operand" "=d,d")
+ (ashiftrt:DI (match_operand:DI 1 "register_operand" "0,0")
+ (match_operand:SI 2 "nonmemory_operand" "J,a")))
+ (clobber (reg:CC 33))]
+ "!TARGET_64BIT"
+ "@
+ srda\\t%0,%c2
+ srda\\t%0,0(%2)"
+ [(set_attr "op_type" "RS")])
+
+(define_insn "*ashrdi3_64"
+ [(set (match_operand:DI 0 "register_operand" "=d,d")
+ (ashiftrt:DI (match_operand:DI 1 "register_operand" "d,d")
+ (match_operand:SI 2 "nonmemory_operand" "J,a")))
+ (clobber (reg:CC 33))]
+ "TARGET_64BIT"
+ "@
+ srag\\t%0,%1,%c2
+ srag\\t%0,%1,0(%2)"
+ [(set_attr "op_type" "RSE")
+ (set_attr "type" "set")])
+
+;
+; ashlsi3 instruction pattern(s).
+;
+; all 32 bits has to be shifted (testcase co750c)
+
+(define_insn "ashlsi3"
+ [(set (match_operand:SI 0 "register_operand" "=d,d")
+ (ashift:SI (match_operand:SI 1 "register_operand" "0,0")
+ (match_operand:SI 2 "r_or_im8_operand" "J,a")))
+ (clobber (reg:CC 33))]
+ ""
+ "@
+ sll\\t%0,%c2
+ sll\\t%0,0(%2)"
+ [(set_attr "op_type" "RS")
+ (set_attr "type" "set")])
+
+;
+; ashrsi3 instruction pattern(s).
+;
+
+(define_insn "ashrsi3"
+ [(set (match_operand:SI 0 "register_operand" "=d,d")
+ (ashiftrt:SI (match_operand:SI 1 "register_operand" "0,0")
+ (match_operand:SI 2 "r_or_im8_operand" "J,a")))
+ (clobber (reg:CC 33))]
+ ""
+ "@
+ sra\\t%0,%c2
+ sra\\t%0,0(%2)"
+ [(set_attr "op_type" "RS")
+ (set_attr "type" "set")])
+
+;
+; ashlhi3 instruction pattern(s).
+;
+
+(define_insn "ashlhi3"
+ [(set (match_operand:HI 0 "register_operand" "=d,d")
+ (ashift:HI (match_operand:HI 1 "register_operand" "0,0")
+ (match_operand:SI 2 "r_or_im8_operand" "J,a")))
+ (clobber (reg:CC 33))]
+ ""
+ "@
+ sll\\t%0,%c2
+ sll\\t%0,0(%2)"
+ [(set_attr "op_type" "RS,RS")])
+
+;
+; ashrhi3 instruction pattern(s).
+;
+
+(define_insn "ashrhi3"
+ [(set (match_operand:HI 0 "register_operand" "=d,d")
+ (ashiftrt:HI (match_operand:HI 1 "register_operand" "0,0")
+ (match_operand:SI 2 "r_or_im8_operand" "J,a")))
+ (clobber (reg:CC 33))]
+ ""
+ "@
+ sll\\t%0,16\;sra\\t%0,16+%c2
+ sll\\t%0,16\;sra\\t%0,16(%2)"
+ [(set_attr "op_type" "NN,NN")
+ (set_attr "length" "8,8")])
+
+
+;;
+;;- logical shift instructions.
+;;
+
+;
+; lshrdi3 instruction pattern(s).
+;
+
+(define_expand "lshrdi3"
+ [(parallel
+ [(set (match_operand:DI 0 "register_operand" "")
+ (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
+ (match_operand:SI 2 "nonmemory_operand" "")))
+ (clobber (reg:CC 33))])]
+ ""
+ "")
+
+(define_insn "*lshrdi3_31"
+ [(set (match_operand:DI 0 "register_operand" "=d,d")
+ (lshiftrt:DI (match_operand:DI 1 "register_operand" "0,0")
+ (match_operand:SI 2 "nonmemory_operand" "J,a")))
+ (clobber (reg:CC 33))]
+ "!TARGET_64BIT"
+ "@
+ srdl\\t%0,%c2
+ srdl\\t%0,0(%2)"
+ [(set_attr "op_type" "RS,RS")])
+
+(define_insn "*lshrdi3_64"
+ [(set (match_operand:DI 0 "register_operand" "=d,d")
+ (lshiftrt:DI (match_operand:DI 1 "register_operand" "d,d")
+ (match_operand:SI 2 "nonmemory_operand" "J,a")))
+ (clobber (reg:CC 33))]
+ "TARGET_64BIT"
+ "@
+ srlg\\t%0,%1,%c2
+ srlg\\t%0,%1,0(%2)"
+ [(set_attr "op_type" "RS,RS")
+ (set_attr "type" "set")])
+
+;
+; lshrsi3 instruction pattern(s).
+;
+
+(define_insn "lshrsi3"
+ [(set (match_operand:SI 0 "register_operand" "=d,d")
+ (lshiftrt:SI (match_operand:SI 1 "register_operand" "0,0")
+ (match_operand:SI 2 "r_or_im8_operand" "J,a")))
+ (clobber (reg:CC 33))]
+ ""
+ "@
+ srl\\t%0,%c2
+ srl\\t%0,0(%2)"
+ [(set_attr "op_type" "RS")
+ (set_attr "type" "set")])
+
+;
+; lshrhi3 instruction pattern(s).
+;
+
+(define_insn "lshrhi3"
+ [(set (match_operand:HI 0 "register_operand" "=d,d")
+ (lshiftrt:HI (match_operand:HI 1 "register_operand" "0,0")
+ (match_operand:SI 2 "r_or_im8_operand" "J,a")))
+ (clobber (reg:CC 33))]
+ ""
+ "@
+ sll\\t%0,16\;srl\\t%0,16+%c2
+ sll\\t%0,16\;srl\\t%0,16(%2)"
+ [(set_attr "op_type" "NN,NN")
+ (set_attr "length" "8,8")])
+
+
+;;
+;; Branch instruction patterns.
+;;
+
+(define_expand "beq"
+ [(set (reg:CCZ 33) (compare:CCZ (match_dup 1) (match_dup 2)))
+ (set (pc)
+ (if_then_else (eq (reg:CCZ 33) (const_int 0))
+ (label_ref (match_operand 0 "" ""))
+ (pc)))]
+ ""
+ "{ operands[1] = s390_compare_op0; operands[2] = s390_compare_op1; }")
+
+(define_expand "bne"
+ [(set (reg:CCZ 33) (compare:CCZ (match_dup 1) (match_dup 2)))
+ (set (pc)
+ (if_then_else (ne (reg:CCZ 33) (const_int 0))
+ (label_ref (match_operand 0 "" ""))
+ (pc)))]
+ ""
+ "{ operands[1] = s390_compare_op0; operands[2] = s390_compare_op1; }")
+
+(define_expand "bgt"
+ [(set (reg:CCS 33) (compare:CCS (match_dup 1) (match_dup 2)))
+ (set (pc)
+ (if_then_else (gt (reg:CCS 33) (const_int 0))
+ (label_ref (match_operand 0 "" ""))
+ (pc)))]
+ ""
+ "{ operands[1] = s390_compare_op0; operands[2] = s390_compare_op1; }")
+
+(define_expand "bgtu"
+ [(set (reg:CCU 33) (compare:CCU (match_dup 1) (match_dup 2)))
+ (set (pc)
+ (if_then_else (gtu (reg:CCU 33) (const_int 0))
+ (label_ref (match_operand 0 "" ""))
+ (pc)))]
+ ""
+ "{ operands[1] = s390_compare_op0; operands[2] = s390_compare_op1; }")
+
+(define_expand "blt"
+ [(set (reg:CCS 33) (compare:CCS (match_dup 1) (match_dup 2)))
+ (set (pc)
+ (if_then_else (lt (reg:CCS 33) (const_int 0))
+ (label_ref (match_operand 0 "" ""))
+ (pc)))]
+ ""
+ "{ operands[1] = s390_compare_op0; operands[2] = s390_compare_op1; }")
+
+(define_expand "bltu"
+ [(set (reg:CCU 33) (compare:CCU (match_dup 1) (match_dup 2)))
+ (set (pc)
+ (if_then_else (ltu (reg:CCU 33) (const_int 0))
+ (label_ref (match_operand 0 "" ""))
+ (pc)))]
+ ""
+ "{ operands[1] = s390_compare_op0; operands[2] = s390_compare_op1; }")
+
+(define_expand "bge"
+ [(set (reg:CCS 33) (compare:CCS (match_dup 1) (match_dup 2)))
+ (set (pc)
+ (if_then_else (ge (reg:CCS 33) (const_int 0))
+ (label_ref (match_operand 0 "" ""))
+ (pc)))]
+ ""
+ "{ operands[1] = s390_compare_op0; operands[2] = s390_compare_op1; }")
+
+(define_expand "bgeu"
+ [(set (reg:CCU 33) (compare:CCU (match_dup 1) (match_dup 2)))
+ (set (pc)
+ (if_then_else (geu (reg:CCU 33) (const_int 0))
+ (label_ref (match_operand 0 "" ""))
+ (pc)))]
+ ""
+ "{ operands[1] = s390_compare_op0; operands[2] = s390_compare_op1; }")
+
+(define_expand "ble"
+ [(set (reg:CCS 33) (compare:CCS (match_dup 1) (match_dup 2)))
+ (set (pc)
+ (if_then_else (le (reg:CCS 33) (const_int 0))
+ (label_ref (match_operand 0 "" ""))
+ (pc)))]
+ ""
+ "{ operands[1] = s390_compare_op0; operands[2] = s390_compare_op1; }")
+
+(define_expand "bleu"
+ [(set (reg:CCU 33) (compare:CCU (match_dup 1) (match_dup 2)))
+ (set (pc)
+ (if_then_else (leu (reg:CCU 33) (const_int 0))
+ (label_ref (match_operand 0 "" ""))
+ (pc)))]
+ ""
+ "{ operands[1] = s390_compare_op0; operands[2] = s390_compare_op1; }")
+
+
+;;
+;;- Conditional jump instructions.
+;;
+
+(define_insn "cjump"
+ [(set (pc)
+ (if_then_else
+ (match_operator 1 "comparison_operator" [(reg 33) (const_int 0)])
+ (label_ref (match_operand 0 "" ""))
+ (pc)))]
+ ""
+ "*
+{
+ if (get_attr_length (insn) == 4 || !TARGET_64BIT)
+ return \"j%C1\\t%l0\";
+ else
+ return \"jg%C1\\t%l0\";
+}"
+ [(set_attr "op_type" "RI")
+ (set (attr "length") (if_then_else
+ (lt (abs (minus (pc) (match_dup 0))) (const_int 60000))
+ (const_int 4) (const_int 6)))])
+
+(define_insn "cjump_long"
+ [(set (pc)
+ (if_then_else
+ (match_operator 1 "comparison_operator" [(reg 33) (const_int 0)])
+ (match_operand 0 "memory_operand" "m")
+ (pc)))]
+ ""
+ "b%C1\\t%0"
+ [(set_attr "op_type" "RX")])
+
+
+;;
+;;- Negated conditional jump instructions.
+;;
+
+(define_insn "icjump"
+ [(set (pc)
+ (if_then_else
+ (match_operator 1 "comparison_operator" [(reg 33) (const_int 0)])
+ (pc)
+ (label_ref (match_operand 0 "" ""))))]
+ ""
+ "*
+{
+ if (get_attr_length (insn) == 4 || !TARGET_64BIT)
+ return \"j%D1\\t%l0\";
+ else
+ return \"jg%D1\\t%l0\";
+}"
+ [(set_attr "op_type" "RI")
+ (set (attr "length") (if_then_else
+ (lt (abs (minus (pc) (match_dup 0))) (const_int 60000))
+ (const_int 4) (const_int 6)))])
+
+(define_insn "icjump_long"
+ [(set (pc)
+ (if_then_else
+ (match_operator 1 "comparison_operator" [(reg 33) (const_int 0)])
+ (pc)
+ (match_operand 0 "memory_operand" "m")))]
+ ""
+ "b%D1\\t%0"
+ [(set_attr "op_type" "RX")])
+
+
+;;
+;;- Subtract one and jump if not zero.
+;;
+
+;(define_expand "decrement_and_branch_on_count"
+; [(use (match_operand 0 "register_operand" ""))
+; (use (label_ref (match_operand 1 "" "")))]
+; ""
+; "
+;{
+;/* if (TARGET_64BIT)
+; emit_jump_insn (gen_brctdi (operands[0], operands[1]));
+; else */
+; emit_jump_insn (gen_brctsi (operands[0], operands[1]));
+; DONE;
+;}")
+;
+;(define_insn "brctsi"
+; [(set (pc)
+; (if_then_else
+; (ne (match_operand:SI 0 "register_operand" "+a")
+; (const_int 1))
+; (label_ref (match_operand 1 "" ""))
+; (pc)))
+; (set (match_dup 0)
+; (plus:SI (match_dup 0) (const_int -1)))]
+; ""
+; "brct\\t%0,%l1"
+; [(set_attr "op_type" "RI")
+; (set_attr "type" "branch")]
+;)
+;
+;(define_insn "ibrctsi"
+; [(set (pc)
+; (if_then_else
+; (eq (match_operand:SI 0 "register_operand" "+a")
+; (const_int 1))
+; (pc)
+; (label_ref (match_operand 1 "" ""))))
+; (set (match_dup 0)
+; (plus:SI (match_dup 0) (const_int -1)))]
+; ""
+; "brct\\t%0,%l1"
+; [(set_attr "op_type" "RI")
+; (set_attr "type" "branch")]
+;)
+
+
+;;
+;;- Unconditional jump instructions.
+;;
+
+;
+; jump instruction pattern(s).
+;
+
+(define_insn "jump"
+ [(set (pc) (label_ref (match_operand 0 "" "")))]
+ ""
+ "*
+{
+ if (get_attr_length (insn) == 4 || !TARGET_64BIT)
+ return \"j\\t%l0\";
+ else
+ return \"jg\\t%l0\";
+}"
+ [(set_attr "op_type" "RI")
+ (set (attr "length") (if_then_else
+ (lt (abs (minus (pc) (match_dup 0))) (const_int 60000))
+ (const_int 4) (const_int 6)))])
+
+;
+; indirect-jump instruction pattern(s).
+;
+
+(define_insn "indirect_jump"
+ [(set (pc) (match_operand 0 "register_operand" "a"))]
+ ""
+ "br\\t%0"
+ [(set_attr "op_type" "RX")])
+
+(define_insn "jump_long"
+ [(set (pc) (match_operand 0 "address_operand" "p"))]
+ ""
+ "b\\t%a0"
+ [(set_attr "op_type" "RX")
+ (set_attr "atype" "mem")])
+
+
+;
+; tablejump instruction pattern(s).
+;
+
+(define_expand "tablejump"
+ [(parallel
+ [(set (pc) (match_operand 0 "register_operand" "a"))
+ (use (label_ref (match_operand 1 "" "")))])]
+ ""
+ "
+{
+ if (flag_pic)
+ {
+ rtx base;
+ base = gen_rtx_REG (Pmode, BASE_REGISTER);
+ base = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, base), 101);
+ operands[0] = gen_rtx_PLUS (Pmode, base, operands[0]);
+ }
+}")
+
+(define_insn "*tablejump1"
+ [(set (pc) (match_operand 0 "register_operand" "a"))
+ (use (label_ref (match_operand 1 "" "")))]
+ ""
+ "br\\t%0"
+ [(set_attr "op_type" "RX")])
+
+(define_insn "*tablejump2"
+ [(set (pc) (match_operand 0 "address_operand" "p"))
+ (use (label_ref (match_operand 1 "" "")))]
+ ""
+ "b\\t%a0"
+ [(set_attr "op_type" "RX")
+ (set_attr "atype" "mem")])
+
+
+;;
+;;- Jump to subroutine.
+;;
+;;
+
+;
+; untyped call instruction pattern(s).
+;
+
+;; Call subroutine returning any type.
+(define_expand "untyped_call"
+ [(parallel [(call (match_operand 0 "" "")
+ (const_int 0))
+ (match_operand 1 "" "")
+ (match_operand 2 "" "")])]
+ ""
+ "
+{
+ int i;
+
+ emit_call_insn (gen_call (operands[0], const0_rtx, const0_rtx));
+
+ for (i = 0; i < XVECLEN (operands[2], 0); i++)
+ {
+ rtx set = XVECEXP (operands[2], 0, i);
+ emit_move_insn (SET_DEST (set), SET_SRC (set));
+ }
+
+ /* The optimizer does not know that the call sets the function value
+ registers we stored in the result block. We avoid problems by
+ claiming that all hard registers are used and clobbered at this
+ point. */
+ emit_insn (gen_blockage ());
+
+ DONE;
+}")
+
+;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
+;; all of memory. This blocks insns from being moved across this point.
+
+(define_insn "blockage"
+ [(unspec_volatile [(const_int 0)] 0)]
+ ""
+ "")
+
+
+;
+; call instruction pattern(s).
+;
+
+(define_expand "call"
+ [(parallel [(call (match_operand 0 "" "")
+ (match_operand 1 "" ""))
+ (clobber (match_operand 2 "" ""))])]
+ ""
+ "
+{
+ /* Abuse operand 2 to hold the return register. */
+ operands[2] = gen_rtx_REG (Pmode, RETURN_REGNUM);
+
+ /* In 31-bit, we must load the GOT register even if the
+ compiler doesn't know about it, because the PLT glue
+ code uses it. In 64-bit, this is not necessary. */
+ if (flag_pic && !TARGET_64BIT)
+ current_function_uses_pic_offset_table = 1;
+
+ /* Direct function calls need special treatment. */
+ if (GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF)
+ {
+ rtx sym = XEXP (operands[0], 0);
+
+ /* When calling a global routine in PIC mode, we must
+ replace the symbol itself with the PLT stub. */
+ if (flag_pic && !SYMBOL_REF_FLAG(sym))
+ {
+ sym = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, sym), 113);
+ sym = gen_rtx_CONST (Pmode, sym);
+ }
+
+ /* Unless we can use the bras(l) insn, force the
+ routine address into a register. */
+ if (!TARGET_SMALL_EXEC && !TARGET_64BIT)
+ {
+ rtx target = gen_reg_rtx (Pmode);
+ emit_move_insn (target, sym);
+ sym = target;
+ }
+
+ operands[0] = gen_rtx_MEM (QImode, sym);
+ }
+}")
+
+(define_insn "brasl"
+ [(call (mem:QI (match_operand:DI 0 "bras_sym_operand" "X"))
+ (match_operand:SI 1 "const_int_operand" "n"))
+ (clobber (match_operand:DI 2 "register_operand" "=r"))]
+ "TARGET_64BIT"
+ "brasl\\t%2,%0"
+ [(set_attr "op_type" "RIL")
+ (set_attr "cycle" "n")])
+
+(define_insn "bras"
+ [(call (mem:QI (match_operand:SI 0 "bras_sym_operand" "X"))
+ (match_operand:SI 1 "const_int_operand" "n"))
+ (clobber (match_operand:SI 2 "register_operand" "=r"))]
+ "TARGET_SMALL_EXEC"
+ "bras\\t%2,%0"
+ [(set_attr "op_type" "RI")
+ (set_attr "cycle" "n")])
+
+(define_insn "basr_64"
+ [(call (mem:QI (match_operand:DI 0 "register_operand" "a"))
+ (match_operand:SI 1 "const_int_operand" "n"))
+ (clobber (match_operand:DI 2 "register_operand" "=r"))]
+ "TARGET_64BIT"
+ "basr\\t%2,%0"
+ [(set_attr "op_type" "RR")
+ (set_attr "cycle" "n")
+ (set_attr "atype" "mem")])
+
+(define_insn "basr_31"
+ [(call (mem:QI (match_operand:SI 0 "register_operand" "a"))
+ (match_operand:SI 1 "const_int_operand" "n"))
+ (clobber (match_operand:SI 2 "register_operand" "=r"))]
+ "!TARGET_64BIT"
+ "basr\\t%2,%0"
+ [(set_attr "op_type" "RR")
+ (set_attr "cycle" "n")
+ (set_attr "atype" "mem")])
+
+(define_insn "bas_64"
+ [(call (mem:QI (match_operand:QI 0 "address_operand" "p"))
+ (match_operand:SI 1 "const_int_operand" "n"))
+ (clobber (match_operand:DI 2 "register_operand" "=r"))]
+ "TARGET_64BIT"
+ "bas\\t%2,%a0"
+ [(set_attr "op_type" "RX")
+ (set_attr "cycle" "n")
+ (set_attr "atype" "mem")])
+
+(define_insn "bas_31"
+ [(call (mem:QI (match_operand:QI 0 "address_operand" "p"))
+ (match_operand:SI 1 "const_int_operand" "n"))
+ (clobber (match_operand:SI 2 "register_operand" "=r"))]
+ "!TARGET_64BIT"
+ "bas\\t%2,%a0"
+ [(set_attr "op_type" "RX")
+ (set_attr "cycle" "n")
+ (set_attr "atype" "mem")])
+
+
+;
+; call_value instruction pattern(s).
+;
+
+(define_expand "call_value"
+ [(parallel [(set (match_operand 0 "" "")
+ (call (match_operand 1 "" "")
+ (match_operand 2 "" "")))
+ (clobber (match_operand 3 "" ""))])]
+ ""
+ "
+{
+ /* Abuse operand 3 to hold the return register. */
+ operands[3] = gen_rtx_REG (Pmode, RETURN_REGNUM);
+
+ /* In 31-bit, we must load the GOT register even if the
+ compiler doesn't know about it, because the PLT glue
+ code uses it. In 64-bit, this is not necessary. */
+ if (flag_pic && !TARGET_64BIT)
+ current_function_uses_pic_offset_table = 1;
+
+ /* Direct function calls need special treatment. */
+ if (GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF)
+ {
+ rtx sym = XEXP (operands[1], 0);
+
+ /* When calling a global routine in PIC mode, we must
+ replace the symbol itself with the PLT stub. */
+ if (flag_pic && !SYMBOL_REF_FLAG(sym))
+ {
+ sym = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, sym), 113);
+ sym = gen_rtx_CONST (Pmode, sym);
+ }
+
+ /* Unless we can use the bras(l) insn, force the
+ routine address into a register. */
+ if (!TARGET_SMALL_EXEC && !TARGET_64BIT)
+ {
+ rtx target = gen_reg_rtx (Pmode);
+ emit_move_insn (target, sym);
+ sym = target;
+ }
+
+ operands[1] = gen_rtx_MEM (QImode, sym);
+ }
+}")
+
+(define_insn "brasl_r"
+ [(set (match_operand 0 "register_operand" "=df")
+ (call (mem:QI (match_operand:DI 1 "bras_sym_operand" "X"))
+ (match_operand:SI 2 "const_int_operand" "n")))
+ (clobber (match_operand:DI 3 "register_operand" "=r"))]
+ "TARGET_64BIT"
+ "brasl\\t%3,%1"
+ [(set_attr "op_type" "RIL")
+ (set_attr "cycle" "n")])
+
+(define_insn "bras_r"
+ [(set (match_operand 0 "register_operand" "=df")
+ (call (mem:QI (match_operand:SI 1 "bras_sym_operand" "X"))
+ (match_operand:SI 2 "const_int_operand" "n")))
+ (clobber (match_operand:SI 3 "register_operand" "=r"))]
+ "TARGET_SMALL_EXEC"
+ "bras\\t%3,%1"
+ [(set_attr "op_type" "RI")
+ (set_attr "cycle" "n")])
+
+(define_insn "basr_r_64"
+ [(set (match_operand 0 "register_operand" "=df")
+ (call (mem:QI (match_operand:DI 1 "register_operand" "a"))
+ (match_operand:SI 2 "const_int_operand" "n")))
+ (clobber (match_operand:DI 3 "register_operand" "=r"))]
+ "TARGET_64BIT"
+ "basr\\t%3,%1"
+ [(set_attr "op_type" "RR")
+ (set_attr "cycle" "n")])
+
+(define_insn "basr_r_31"
+ [(set (match_operand 0 "register_operand" "=df")
+ (call (mem:QI (match_operand:SI 1 "register_operand" "a"))
+ (match_operand:SI 2 "const_int_operand" "n")))
+ (clobber (match_operand:SI 3 "register_operand" "=r"))]
+ "!TARGET_64BIT"
+ "basr\\t%3,%1"
+ [(set_attr "op_type" "RR")
+ (set_attr "cycle" "n")
+ (set_attr "atype" "mem")])
+
+(define_insn "bas_r_64"
+ [(set (match_operand 0 "register_operand" "=df")
+ (call (mem:QI (match_operand:QI 1 "address_operand" "p"))
+ (match_operand:SI 2 "const_int_operand" "n")))
+ (clobber (match_operand:DI 3 "register_operand" "=r"))]
+ "TARGET_64BIT"
+ "bas\\t%3,%a1"
+ [(set_attr "op_type" "RX")
+ (set_attr "cycle" "n")
+ (set_attr "atype" "mem")])
+
+(define_insn "bas_r_31"
+ [(set (match_operand 0 "register_operand" "=df")
+ (call (mem:QI (match_operand:QI 1 "address_operand" "p"))
+ (match_operand:SI 2 "const_int_operand" "n")))
+ (clobber (match_operand:SI 3 "register_operand" "=r"))]
+ "!TARGET_64BIT"
+ "bas\\t%3,%a1"
+ [(set_attr "op_type" "RX")
+ (set_attr "cycle" "n")
+ (set_attr "atype" "mem")])
+
+
+;;
+;;- Miscellaneous instructions.
+;;
+
+;
+; allocate stack instruction pattern(s).
+;
+
+(define_expand "allocate_stack"
+ [(set (reg 15)
+ (plus (reg 15) (match_operand 1 "general_operand" "")))
+ (set (match_operand 0 "general_operand" "")
+ (reg 15))]
+ ""
+ "
+{
+ rtx stack = gen_rtx (REG, Pmode, STACK_POINTER_REGNUM);
+ rtx chain = gen_rtx (MEM, Pmode, stack);
+ rtx temp = gen_reg_rtx (Pmode);
+
+ emit_move_insn (temp, chain);
+
+ if (TARGET_64BIT)
+ emit_insn (gen_adddi3 (stack, stack, negate_rtx (Pmode, operands[1])));
+ else
+ emit_insn (gen_addsi3 (stack, stack, negate_rtx (Pmode, operands[1])));
+
+ emit_move_insn (chain, temp);
+
+ emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
+ DONE;
+}")
+
+
+;
+; setjmp/longjmp instruction pattern(s).
+;
+
+(define_expand "builtin_setjmp_setup"
+ [(unspec [(match_operand 0 "register_operand" "a")] 1)]
+ ""
+ "
+{
+ emit_insn (gen_do_builtin_setjmp_setup (operands[0]));
+ DONE;
+}")
+
+(define_expand "builtin_setjmp_receiver"
+ [(unspec_volatile [(label_ref (match_operand 0 "" ""))] 2)]
+ ""
+ "
+{
+ emit_insn (gen_blockage ());
+ DONE;
+}")
+
+(define_expand "do_builtin_setjmp_setup"
+ [(set (mem:SI (plus:SI (match_operand:SI 0 "register_operand" "a")
+ (const_int 12)))
+ (reg:SI 12))
+ (set (mem:SI (plus:SI (match_dup 0)
+ (const_int 16)))
+ (reg:SI 13)) ]
+ ""
+ "")
+
+(define_expand "builtin_longjmp"
+ [(unspec_volatile [(match_operand 0 "register_operand" "r")] 3)]
+ ""
+ "
+{
+ /* The elements of the buffer are, in order: */
+ rtx fp = gen_rtx_MEM (Pmode, operands[0]);
+ rtx lab = gen_rtx_MEM (Pmode, plus_constant (operands[0], 4));
+ rtx stack = gen_rtx_MEM (Pmode, plus_constant (operands[0], 8));
+ rtx gotv = gen_rtx_MEM (Pmode, plus_constant (operands[0], 12));
+ rtx basev = gen_rtx_MEM (Pmode, plus_constant (operands[0], 16));
+ rtx base = gen_rtx_REG (Pmode, 13);
+ rtx got = gen_rtx_REG (Pmode, 12);
+ rtx jmp = gen_rtx_REG (Pmode, 14);
+
+ emit_move_insn (jmp, lab);
+ emit_move_insn (got, gotv);
+ emit_move_insn (base, basev);
+ emit_stack_restore (SAVE_NONLOCAL, stack, NULL_RTX);
+ emit_move_insn (hard_frame_pointer_rtx, fp);
+
+ emit_insn (gen_rtx_USE (VOIDmode, hard_frame_pointer_rtx));
+ emit_insn (gen_rtx_USE (VOIDmode, stack_pointer_rtx));
+ emit_insn (gen_rtx_USE (VOIDmode, got));
+ emit_insn (gen_rtx_USE (VOIDmode, base));
+ emit_indirect_jump (jmp);
+ DONE;
+}")
+
+
+;; These patterns say how to save and restore the stack pointer. We need not
+;; save the stack pointer at function level since we are careful to
+;; preserve the backchain. At block level, we have to restore the backchain
+;; when we restore the stack pointer.
+;;
+;; For nonlocal gotos, we must save both the stack pointer and its
+;; backchain and restore both. Note that in the nonlocal case, the
+;; save area is a memory location.
+
+(define_expand "save_stack_function"
+ [(match_operand 0 "general_operand" "")
+ (match_operand 1 "general_operand" "")]
+ ""
+ "DONE;")
+
+(define_expand "restore_stack_function"
+ [(match_operand 0 "general_operand" "")
+ (match_operand 1 "general_operand" "")]
+ ""
+ "DONE;")
+
+(define_expand "restore_stack_block"
+ [(use (match_operand 0 "register_operand" ""))
+ (set (match_dup 2) (match_dup 3))
+ (set (match_dup 0) (match_operand 1 "register_operand" ""))
+ (set (match_dup 3) (match_dup 2))]
+ ""
+ "
+{
+ operands[2] = gen_reg_rtx (Pmode);
+ operands[3] = gen_rtx_MEM (Pmode, operands[0]);
+}")
+
+(define_expand "save_stack_nonlocal"
+ [(match_operand 0 "memory_operand" "")
+ (match_operand 1 "register_operand" "")]
+ ""
+ "
+{
+ rtx temp = gen_reg_rtx (Pmode);
+
+ /* Copy the backchain to the first word, sp to the second. */
+ emit_move_insn (temp, gen_rtx_MEM (Pmode, operands[1]));
+ emit_move_insn (operand_subword (operands[0], 0, 0,
+ TARGET_64BIT ? TImode : DImode),
+ temp);
+ emit_move_insn (operand_subword (operands[0], 1, 0,
+ TARGET_64BIT ? TImode : DImode),
+ operands[1]);
+ DONE;
+}")
+
+(define_expand "restore_stack_nonlocal"
+ [(match_operand 0 "register_operand" "")
+ (match_operand 1 "memory_operand" "")]
+ ""
+ "
+{
+ rtx temp = gen_reg_rtx (Pmode);
+
+ /* Restore the backchain from the first word, sp from the second. */
+ emit_move_insn (temp,
+ operand_subword (operands[1], 0, 0,
+ TARGET_64BIT ? TImode : DImode));
+ emit_move_insn (operands[0],
+ operand_subword (operands[1], 1, 0,
+ TARGET_64BIT ? TImode : DImode));
+ emit_move_insn (gen_rtx_MEM (Pmode, operands[0]), temp);
+ DONE;
+}")
+
+
+;
+; nop instruction pattern(s).
+;
+
+(define_insn "nop"
+ [(const_int 0)]
+ ""
+ "lr\\t0,0"
+ [(set_attr "op_type" "RR")])
+
+
+;
+; Special literal pool access instruction pattern(s).
+;
+
+(define_insn "reload_base"
+ [(parallel [(set (reg 13) (pc))
+ (use (label_ref (match_operand 0 "" "")))])]
+ ""
+ "*
+{
+ if (TARGET_64BIT)
+ return \"larl\\t13,%y0\";
+ else
+ return \"basr\\t13,0\;ahi\\t13,%Y0\";
+}"
+ [(set_attr "op_type" "NN")
+ (set_attr "cycle" "2")
+ (set_attr "length" "8")])
+
+(define_insn "ltorg"
+ [(parallel [(set (reg 13) (pc))
+ (use (match_operand:SI 0 "const_int_operand" ""))])]
+ ""
+ "*
+{
+ s390_dump_literal_pool (insn, operands[0]);
+ return \"0:\";
+}"
+ [(set_attr "op_type" "NN")
+ (set_attr "cycle" "n")
+ (set_attr "length" "4096")])
+
+
+;;
+;; Peephole optimization patterns.
+;;
+
+(define_peephole
+ [(set (match_operand:SI 0 "memory_operand" "m")
+ (match_operand:SI 1 "register_operand" "d"))
+ (set (match_dup 1)
+ (match_dup 0))]
+ ""
+ "st\\t%1,%0")
+
+(define_peephole
+ [(set (match_operand:SI 0 "memory_operand" "m")
+ (match_operand:SI 1 "register_operand" "d"))
+ (set (match_dup 0)
+ (match_dup 1))]
+ ""
+ "st\\t%1,%0")
+
+(define_peephole
+ [(set (match_operand:SI 0 "register_operand" "")
+ (match_operand:SI 1 "register_operand" ""))
+ (parallel
+ [(set (match_dup 0)
+ (plus:SI (match_dup 0)
+ (match_operand:SI 2 "immediate_operand" "")))
+ (clobber (reg:CC 33))])]
+ "(REGNO (operands[0]) == STACK_POINTER_REGNUM ||
+ REGNO (operands[1]) == STACK_POINTER_REGNUM ||
+ REGNO (operands[0]) == BASE_REGISTER ||
+ REGNO (operands[1]) == BASE_REGISTER) &&
+ INTVAL (operands[2]) > 0 && INTVAL (operands[2]) < 4096"
+ "la\\t%0,%c2(%1)")
+
+;
+; peepholes for fast char instructions
+;
+
+;(define_peephole
+; [(set (match_operand:QI 0 "register_operand" "d")
+; (match_operand:QI 1 "s_operand" "Q"))
+; (set (match_operand:SI 2 "register_operand" "0")
+; (zero_extend:SI (match_dup 0)))]
+; "REGNO(operands[0]) == REGNO(operands[2])"
+; "icm\\t%0,8,%1\;srl\\t%0,24")
+
+;(define_peephole
+; [(set (match_operand:QI 0 "register_operand" "d")
+; (match_operand:QI 1 "s_operand" "Q"))
+; (set (match_operand:SI 2 "register_operand" "0")
+; (sign_extend:SI (match_dup 0)))]
+; "REGNO(operands[0]) == REGNO(operands[2])"
+; "icm\\t%0,8,%1\;sra\\t%0,24")
+
+(define_peephole
+ [(set (match_operand:QI 0 "register_operand" "d")
+ (match_operand:QI 1 "immediate_operand" "J"))
+ (set (match_operand:SI 2 "register_operand" "0" )
+ (sign_extend:SI (match_dup 0) ) )]
+ "REGNO(operands[0]) == REGNO(operands[2])"
+ "lhi\\t%0,%h1")
+
+;
+; peepholes for fast short instructions
+;
+
+;(define_peephole
+; [(set (match_operand:HI 0 "register_operand" "d")
+; (match_operand:HI 1 "s_operand" "Q"))
+; (set (match_operand:SI 2 "register_operand" "0" )
+; (zero_extend:SI (match_dup 0)))]
+; "REGNO(operands[0]) == REGNO(operands[2])"
+; "icm\\t%0,12,%1\;srl\\t%0,16")
+
+(define_peephole
+ [(set (match_operand:HI 0 "register_operand" "d")
+ (match_operand:HI 1 "memory_operand" "m"))
+ (set (match_operand:SI 2 "register_operand" "0" )
+ (sign_extend:SI (match_dup 0)))]
+ "REGNO(operands[0]) == REGNO(operands[2])"
+ "lh\\t%0,%1")
+
+(define_peephole
+ [(set (match_operand:HI 0 "register_operand" "d")
+ (match_operand:HI 1 "immediate_operand" "K"))
+ (set (match_operand:SI 2 "register_operand" "0" )
+ (sign_extend:SI (match_dup 0) ) )]
+ "REGNO(operands[0]) == REGNO(operands[2])"
+ "lhi\\t%0,%h1")
+
+;
+; peepholes for divide instructions
+;
+
+(define_peephole
+ [(set (match_operand:DI 0 "register_operand" "d")
+ (match_operand:DI 1 "memory_operand" "m"))
+ (set (match_dup 0)
+ (lshiftrt:DI (match_dup 0)
+ (match_operand:SI 2 "immediate_operand" "J")))
+ (set (match_dup 0)
+ (div:SI (match_dup 0)
+ (match_operand:SI 3 "nonimmediate_operand" "g")))
+ (set (match_dup 1)
+ (match_dup 0))]
+ ""
+ "*
+{
+ output_asm_insn (\"l\\t%0,%1\", operands);
+ output_asm_insn (\"srdl\\t%0,%b2\", operands);
+
+ if (REG_P (operands[3]))
+ output_asm_insn (\"dr\\t%0,%3\", operands);
+ else
+ output_asm_insn (\"d\\t%0,%3\", operands);
+
+ return \"st\\t%N0,%N1\";
+}")
+
+(define_peephole
+ [(set (match_operand:DI 0 "register_operand" "d")
+ (match_operand:DI 1 "memory_operand" "m"))
+ (set (match_dup 0)
+ (lshiftrt:DI (match_dup 0)
+ (match_operand:SI 2 "immediate_operand" "J")))
+ (set (match_dup 0)
+ (mod:SI (match_dup 0)
+ (match_operand:SI 3 "nonimmediate_operand" "g")))
+ (set (match_dup 1)
+ (match_dup 0))]
+ ""
+ "*
+{
+ output_asm_insn (\"l\\t%0,%1\", operands);
+ output_asm_insn (\"srdl\\t%0,%b2\", operands);
+
+ if (REG_P (operands[3]))
+ output_asm_insn (\"dr\\t%0,%3\", operands);
+ else
+ output_asm_insn (\"d\\t%0,%3\", operands);
+
+ return \"st\\t%0,%1\";
+}")
+