summaryrefslogtreecommitdiffstats
path: root/contrib/gcc/config/s390/s390.md
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/gcc/config/s390/s390.md')
-rw-r--r--contrib/gcc/config/s390/s390.md6727
1 files changed, 6727 insertions, 0 deletions
diff --git a/contrib/gcc/config/s390/s390.md b/contrib/gcc/config/s390/s390.md
new file mode 100644
index 0000000..2742638
--- /dev/null
+++ b/contrib/gcc/config/s390/s390.md
@@ -0,0 +1,6727 @@
+;;- Machine description for GNU compiler -- S/390 / zSeries version.
+;; Copyright (C) 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+;; Contributed by Hartmut Penner (hpenner@de.ibm.com) and
+;; Ulrich Weigand (uweigand@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.
+;;
+
+
+;; Define an insn type attribute. This is used in function unit delay
+;; computations.
+
+(define_attr "type" "none,integer,load,lr,la,lm,stm,cs,vs,store,imul,lmul,fmul,idiv,ldiv,fdiv,branch,jsr,other,o2,o3"
+ (const_string "integer"))
+
+;; Insn are devide in two classes:
+;; mem: Insn accessing memory
+;; reg: Insn operands all in registers
+
+(define_attr "atype" "reg,mem"
+ (const_string "reg"))
+
+;; Generic pipeline function unit.
+
+(define_function_unit "integer" 1 0
+ (eq_attr "type" "none") 0 0)
+
+(define_function_unit "integer" 1 0
+ (eq_attr "type" "integer") 1 1)
+
+(define_function_unit "integer" 1 0
+ (eq_attr "type" "load") 1 1)
+
+(define_function_unit "integer" 1 0
+ (eq_attr "type" "la") 1 1)
+
+(define_function_unit "integer" 1 0
+ (eq_attr "type" "lr") 1 1)
+
+(define_function_unit "integer" 1 0
+ (eq_attr "type" "store") 1 1)
+
+(define_function_unit "integer" 1 0
+ (eq_attr "type" "lm") 2 2)
+
+(define_function_unit "integer" 1 0
+ (eq_attr "type" "stm") 2 2)
+
+(define_function_unit "integer" 1 0
+ (eq_attr "type" "cs") 5 5)
+
+(define_function_unit "integer" 1 0
+ (eq_attr "type" "vs") 30 30)
+
+(define_function_unit "integer" 1 0
+ (eq_attr "type" "jsr") 5 5)
+
+(define_function_unit "integer" 1 0
+ (eq_attr "type" "imul") 7 7)
+
+(define_function_unit "integer" 1 0
+ (eq_attr "type" "fmul") 6 6)
+
+(define_function_unit "integer" 1 0
+ (eq_attr "type" "idiv") 33 33)
+
+(define_function_unit "integer" 1 0
+ (eq_attr "type" "fdiv") 33 33)
+
+(define_function_unit "integer" 1 0
+ (eq_attr "type" "o2") 2 2)
+
+(define_function_unit "integer" 1 0
+ (eq_attr "type" "o3") 3 3)
+
+(define_function_unit "integer" 1 0
+ (eq_attr "type" "other") 5 5)
+
+;; 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" "other")
+ (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 "const_int_operand" "n")
+ (match_operand:DI 2 "const_int_operand" "n"))
+ (const_int 0)))]
+ "s390_match_ccmode(insn, CCTmode) && TARGET_64BIT
+ && INTVAL (operands[1]) >= 1 && INTVAL (operands[2]) >= 0
+ && INTVAL (operands[1]) + INTVAL (operands[2]) <= 64
+ && (INTVAL (operands[1]) + INTVAL (operands[2]) - 1) >> 4
+ == INTVAL (operands[2]) >> 4"
+ "*
+{
+ int part = INTVAL (operands[2]) >> 4;
+ int block = (1 << INTVAL (operands[1])) - 1;
+ int shift = 16 - INTVAL (operands[1]) - (INTVAL (operands[2]) & 15);
+
+ operands[2] = GEN_INT (block << shift);
+
+ switch (part)
+ {
+ case 0: return \"tmhh\\t%0,%x2\";
+ case 1: return \"tmhl\\t%0,%x2\";
+ case 2: return \"tmlh\\t%0,%x2\";
+ case 3: return \"tmll\\t%0,%x2\";
+ default: abort ();
+ }
+}"
+ [(set_attr "op_type" "RI")])
+
+(define_insn "*cmpdi_tm_reg"
+ [(set (reg 33)
+ (compare (and:DI (match_operand:DI 0 "register_operand" "%d")
+ (match_operand:DI 1 "immediate_operand" "n"))
+ (const_int 0)))]
+ "s390_match_ccmode(insn, CCTmode) && TARGET_64BIT
+ && s390_single_hi (operands[1], DImode, 0) >= 0"
+ "*
+{
+ int part = s390_single_hi (operands[1], DImode, 0);
+ operands[1] = GEN_INT (s390_extract_hi (operands[1], DImode, part));
+
+ switch (part)
+ {
+ case 0: return \"tmhh\\t%0,%x1\";
+ case 1: return \"tmhl\\t%0,%x1\";
+ case 2: return \"tmlh\\t%0,%x1\";
+ case 3: return \"tmll\\t%0,%x1\";
+ default: abort ();
+ }
+}"
+ [(set_attr "op_type" "RI")])
+
+(define_insn "*cmpdi_tm_mem"
+ [(set (reg 33)
+ (compare (and:DI (match_operand:DI 0 "s_operand" "%Qo")
+ (match_operand:DI 1 "immediate_operand" "n"))
+ (const_int 0)))]
+ "s390_match_ccmode(insn, CCTmode) && TARGET_64BIT
+ && s390_single_qi (operands[1], DImode, 0) >= 0"
+ "*
+{
+ int part = s390_single_qi (operands[1], DImode, 0);
+ operands[1] = GEN_INT (s390_extract_qi (operands[1], DImode, part));
+
+ operands[0] = gen_rtx_MEM (QImode,
+ plus_constant (XEXP (operands[0], 0), part));
+ return \"tm\\t%0,%b1\";
+}"
+ [(set_attr "op_type" "SI")
+ (set_attr "atype" "mem")])
+
+(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")])
+
+(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")])
+
+(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")])
+
+(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_imm_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_tm2"
+ [(set (reg 33)
+ (compare (zero_extract:SI (match_operand:SI 0 "register_operand" "d")
+ (match_operand:SI 1 "const_int_operand" "n")
+ (match_operand:SI 2 "const_int_operand" "n"))
+ (const_int 0)))]
+ "s390_match_ccmode(insn, CCTmode)
+ && INTVAL (operands[1]) >= 1 && INTVAL (operands[2]) >= 0
+ && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
+ && (INTVAL (operands[1]) + INTVAL (operands[2]) - 1) >> 4
+ == INTVAL (operands[2]) >> 4"
+ "*
+{
+ int part = INTVAL (operands[2]) >> 4;
+ int block = (1 << INTVAL (operands[1])) - 1;
+ int shift = 16 - INTVAL (operands[1]) - (INTVAL (operands[2]) & 15);
+
+ operands[2] = GEN_INT (block << shift);
+
+ switch (part)
+ {
+ case 0: return \"tmh\\t%0,%x2\";
+ case 1: return \"tml\\t%0,%x2\";
+ default: abort ();
+ }
+}"
+ [(set_attr "op_type" "RI")])
+
+(define_insn "*cmpsi_tm_reg"
+ [(set (reg 33)
+ (compare (and:SI (match_operand:SI 0 "register_operand" "%d")
+ (match_operand:SI 1 "immediate_operand" "n"))
+ (const_int 0)))]
+ "s390_match_ccmode(insn, CCTmode)
+ && s390_single_hi (operands[1], SImode, 0) >= 0"
+ "*
+{
+ int part = s390_single_hi (operands[1], SImode, 0);
+ operands[1] = GEN_INT (s390_extract_hi (operands[1], SImode, part));
+
+ switch (part)
+ {
+ case 0: return \"tmh\\t%0,%x1\";
+ case 1: return \"tml\\t%0,%x1\";
+ default: abort ();
+ }
+}"
+ [(set_attr "op_type" "RI")])
+
+(define_insn "*cmpsi_tm_mem"
+ [(set (reg 33)
+ (compare (and:SI (match_operand:SI 0 "s_operand" "%Qo")
+ (match_operand:SI 1 "immediate_operand" "n"))
+ (const_int 0)))]
+ "s390_match_ccmode(insn, CCTmode)
+ && s390_single_qi (operands[1], SImode, 0) >= 0"
+ "*
+{
+ int part = s390_single_qi (operands[1], SImode, 0);
+ operands[1] = GEN_INT (s390_extract_qi (operands[1], SImode, part));
+
+ operands[0] = gen_rtx_MEM (QImode,
+ plus_constant (XEXP (operands[0], 0), part));
+ return \"tm\\t%0,%b1\";
+}"
+ [(set_attr "op_type" "SI")
+ (set_attr "atype" "mem")])
+
+(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")])
+
+(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")])
+
+(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")])
+
+(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")])
+
+(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")])
+
+(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")])
+
+(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_imm_operand" "oQ")))]
+ "s390_match_ccmode(insn, CCUmode)"
+ "clc\\t%O0(4,%R0),%1"
+ [(set_attr "op_type" "SS")
+ (set_attr "atype" "mem")])
+
+
+; HI instructions
+
+(define_insn "*cmphi_tm_sub"
+ [(set (reg 33)
+ (compare (and:SI (subreg:SI (match_operand:HI 0 "s_operand" "%Qo") 0)
+ (match_operand:SI 1 "immediate_operand" "n"))
+ (const_int 0)))]
+ "s390_match_ccmode(insn, CCTmode)
+ && s390_single_qi (operands[1], HImode, 0) >= 0"
+ "*
+{
+ int part = s390_single_qi (operands[1], HImode, 0);
+ operands[1] = GEN_INT (s390_extract_qi (operands[1], HImode, part));
+
+ operands[0] = gen_rtx_MEM (QImode,
+ plus_constant (XEXP (operands[0], 0), part));
+ return \"tm\\t%0,%b1\";
+}"
+ [(set_attr "op_type" "SI")
+ (set_attr "atype" "mem")])
+
+(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")])
+
+(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")])
+
+(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")])
+
+(define_insn "*cmphi_ccu"
+ [(set (reg 33)
+ (compare (match_operand:HI 0 "register_operand" "d")
+ (match_operand:HI 1 "s_imm_operand" "Qo")))]
+ "s390_match_ccmode(insn, CCUmode)"
+ "clm\\t%0,3,%1"
+ [(set_attr "op_type" "RS")
+ (set_attr "atype" "mem")])
+
+(define_insn "*cmphi_ccu_mem"
+ [(set (reg 33)
+ (compare (match_operand:HI 0 "s_operand" "oQ")
+ (match_operand:HI 1 "s_imm_operand" "oQ")))]
+ "s390_match_ccmode(insn, CCUmode)"
+ "clc\\t%O0(2,%R0),%1"
+ [(set_attr "op_type" "SS")
+ (set_attr "atype" "mem")])
+
+
+; QI instructions
+
+(define_insn "*cmpqi_tm2"
+ [(set (reg 33)
+ (compare (zero_extract:SI (match_operand:QI 0 "s_operand" "Qo")
+ (match_operand:SI 1 "const_int_operand" "n")
+ (match_operand:SI 2 "const_int_operand" "n"))
+ (const_int 0)))]
+ "s390_match_ccmode(insn, CCTmode)
+ && INTVAL (operands[1]) >= 1 && INTVAL (operands[2]) >= 0
+ && INTVAL (operands[1]) + INTVAL (operands[2]) <= 8"
+ "*
+{
+ int block = (1 << INTVAL (operands[1])) - 1;
+ int shift = 8 - INTVAL (operands[1]) - INTVAL (operands[2]);
+
+ operands[2] = GEN_INT (block << shift);
+ return \"tm\\t%0,%b2\";
+}"
+ [(set_attr "op_type" "SI")
+ (set_attr "atype" "mem")])
+
+(define_insn "*cmpqi_tm"
+ [(set (reg 33)
+ (compare (and:QI (match_operand:QI 0 "nonimmediate_operand" "%d,Q")
+ (match_operand:QI 1 "immediate_operand" "n,n"))
+ (const_int 0)))]
+ "s390_match_ccmode(insn, CCTmode)"
+ "@
+ tml\\t%0,%b1
+ tm\\t%0,%b1"
+ [(set_attr "op_type" "RI,SI")
+ (set_attr "atype" "reg,mem")])
+
+(define_insn "*cmpqi_tm_sub"
+ [(set (reg 33)
+ (compare (and:SI (subreg:SI (match_operand:QI 0 "s_operand" "%Qo") 0)
+ (match_operand:SI 1 "immediate_operand" "n"))
+ (const_int 0)))]
+ "s390_match_ccmode(insn, CCTmode)"
+ "tm\\t%0,%b1"
+ [(set_attr "op_type" "SI")
+ (set_attr "atype" "mem")])
+
+(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")])
+
+(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")])
+
+(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")])
+
+(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 "atype" "mem")])
+
+(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")])
+
+(define_insn "*cmpqi_ccu"
+ [(set (reg 33)
+ (compare (match_operand:QI 0 "register_operand" "d")
+ (match_operand:QI 1 "s_imm_operand" "Qo")))]
+ "s390_match_ccmode(insn, CCUmode)"
+ "clm\\t%0,1,%1"
+ [(set_attr "op_type" "RS")
+ (set_attr "atype" "mem")])
+
+(define_insn "*cmpqi_ccu_immed"
+ [(set (reg 33)
+ (compare (match_operand:QI 0 "s_operand" "Qo")
+ (match_operand:QI 1 "const_int_operand" "n")))]
+ "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")])
+
+(define_insn "*cmpqi_ccu_mem"
+ [(set (reg 33)
+ (compare (match_operand:QI 0 "s_operand" "oQ")
+ (match_operand:QI 1 "s_imm_operand" "oQ")))]
+ "s390_match_ccmode(insn, CCUmode)"
+ "clc\\t%O0(1,%R0),%1"
+ [(set_attr "op_type" "SS")
+ (set_attr "atype" "mem")])
+
+
+; 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" "RRE")])
+
+(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")])
+
+(define_insn "*cmpdf_ccs"
+ [(set (reg 33)
+ (compare (match_operand:DF 0 "register_operand" "f,f")
+ (match_operand:DF 1 "general_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" "RRE,RXE")
+ (set_attr "atype" "reg,mem")])
+
+(define_insn "*cmpdf_ccs_ibm"
+ [(set (reg 33)
+ (compare (match_operand:DF 0 "register_operand" "f,f")
+ (match_operand:DF 1 "general_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")])
+
+
+; 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" "RRE")])
+
+(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")])
+
+(define_insn "*cmpsf_ccs"
+ [(set (reg 33)
+ (compare (match_operand:SF 0 "register_operand" "f,f")
+ (match_operand:SF 1 "general_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" "RRE,RXE")
+ (set_attr "atype" "reg,mem")])
+
+(define_insn "*cmpsf_ccs"
+ [(set (reg 33)
+ (compare (match_operand:SF 0 "register_operand" "f,f")
+ (match_operand:SF 1 "general_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")])
+
+
+;;
+;;- Move instructions.
+;;
+
+;
+; movti instruction pattern(s).
+;
+
+(define_insn "*movti_ss"
+ [(set (match_operand:TI 0 "s_operand" "=Qo")
+ (match_operand:TI 1 "s_imm_operand" "Qo"))]
+ ""
+ "mvc\\t%O0(16,%R0),%1"
+ [(set_attr "op_type" "SS")
+ (set_attr "atype" "mem")])
+
+(define_insn "movti"
+ [(set (match_operand:TI 0 "nonimmediate_operand" "=d,Q,d,m")
+ (match_operand:TI 1 "general_operand" "Q,d,dKm,d"))]
+ "TARGET_64BIT"
+ "@
+ lmg\\t%0,%N0,%1
+ stmg\\t%1,%N1,%0
+ #
+ #"
+ [(set_attr "op_type" "RSE,RSE,NN,NN")
+ (set_attr "atype" "mem")])
+
+(define_split
+ [(set (match_operand:TI 0 "nonimmediate_operand" "")
+ (match_operand:TI 1 "general_operand" ""))]
+ "TARGET_64BIT && reload_completed
+ && !s_operand (operands[0], VOIDmode)
+ && !s_operand (operands[1], VOIDmode)
+ && (register_operand (operands[0], VOIDmode)
+ || register_operand (operands[1], VOIDmode))
+ && (!register_operand (operands[0], VOIDmode)
+ || !reg_overlap_mentioned_p (operand_subword (operands[0], 0, 0, TImode),
+ operands[1])
+ || !reg_overlap_mentioned_p (operand_subword (operands[0], 1, 0, TImode),
+ operands[1]))"
+ [(set (match_dup 2) (match_dup 4))
+ (set (match_dup 3) (match_dup 5))]
+ "
+{
+ if (!register_operand (operands[0], VOIDmode)
+ || !reg_overlap_mentioned_p (operand_subword (operands[0], 0, 0, TImode),
+ operands[1]))
+ {
+ operands[2] = operand_subword (operands[0], 0, 0, TImode);
+ operands[3] = operand_subword (operands[0], 1, 0, TImode);
+ operands[4] = operand_subword (operands[1], 0, 0, TImode);
+ operands[5] = operand_subword (operands[1], 1, 0, TImode);
+ }
+ else
+ {
+ operands[2] = operand_subword (operands[0], 1, 0, TImode);
+ operands[3] = operand_subword (operands[0], 0, 0, TImode);
+ operands[4] = operand_subword (operands[1], 1, 0, TImode);
+ operands[5] = operand_subword (operands[1], 0, 0, TImode);
+ }
+}")
+
+(define_split
+ [(set (match_operand:TI 0 "register_operand" "")
+ (match_operand:TI 1 "memory_operand" ""))]
+ "TARGET_64BIT && reload_completed
+ && !s_operand (operands[1], VOIDmode)"
+ [(set (match_dup 2) (match_dup 3))
+ (set (match_dup 0) (mem:TI (match_dup 2)))]
+ "operands[2] = operand_subword (operands[0], 1, 0, TImode);
+ operands[3] = legitimize_la_operand (XEXP (operands[1], 0));")
+
+;
+; 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" ""))]
+ ""
+ "
+{
+ /* Handle PIC symbolic constants. */
+ if (TARGET_64BIT && flag_pic && SYMBOLIC_CONST (operands[1]))
+ emit_pic_move (operands, DImode);
+
+ /* During and after reload, we need to force constants
+ to the literal pool ourselves, if necessary. */
+ if ((reload_in_progress || reload_completed)
+ && CONSTANT_P (operands[1])
+ && (!legitimate_reload_constant_p (operands[1])
+ || fp_operand (operands[0], VOIDmode)))
+ operands[1] = force_const_mem (DImode, operands[1]);
+}")
+
+(define_insn "*movdi_lhi"
+ [(set (match_operand:DI 0 "register_operand" "=d")
+ (match_operand:DI 1 "immediate_operand" "K"))]
+ "TARGET_64BIT
+ && GET_CODE (operands[1]) == CONST_INT
+ && CONST_OK_FOR_LETTER_P (INTVAL (operands[1]), 'K')
+ && !fp_operand (operands[0], VOIDmode)"
+ "lghi\\t%0,%h1"
+ [(set_attr "op_type" "RI")
+ (set_attr "atype" "reg")])
+
+(define_insn "*movdi_lli"
+ [(set (match_operand:DI 0 "register_operand" "=d")
+ (match_operand:DI 1 "immediate_operand" "n"))]
+ "TARGET_64BIT && s390_single_hi (operands[1], DImode, 0) >= 0
+ && !fp_operand (operands[0], VOIDmode)"
+ "*
+{
+ int part = s390_single_hi (operands[1], DImode, 0);
+ operands[1] = GEN_INT (s390_extract_hi (operands[1], DImode, part));
+
+ switch (part)
+ {
+ case 0: return \"llihh\\t%0,%x1\";
+ case 1: return \"llihl\\t%0,%x1\";
+ case 2: return \"llilh\\t%0,%x1\";
+ case 3: return \"llill\\t%0,%x1\";
+ default: abort ();
+ }
+}"
+ [(set_attr "op_type" "RI")
+ (set_attr "atype" "reg")])
+
+(define_insn "*movdi_larl"
+ [(set (match_operand:DI 0 "register_operand" "=d")
+ (match_operand:DI 1 "larl_operand" "X"))]
+ "TARGET_64BIT
+ && !fp_operand (operands[0], VOIDmode)"
+ "larl\\t%0,%1"
+ [(set_attr "op_type" "RIL")
+ (set_attr "atype" "reg")
+ (set_attr "type" "la")])
+
+(define_insn "*movdi_ss"
+ [(set (match_operand:DI 0 "s_operand" "=Qo")
+ (match_operand:DI 1 "s_imm_operand" "Qo"))]
+ ""
+ "mvc\\t%O0(8,%R0),%1"
+ [(set_attr "op_type" "SS")
+ (set_attr "atype" "mem")])
+
+(define_insn "*movdi_64"
+ [(set (match_operand:DI 0 "nonimmediate_operand" "=d,d,m,!*f,!*f,!m")
+ (match_operand:DI 1 "general_operand" "d,m,d,*f,m,*f"))]
+ "TARGET_64BIT"
+ "@
+ lgr\\t%0,%1
+ lg\\t%0,%1
+ stg\\t%1,%0
+ ldr\\t%0,%1
+ ld\\t%0,%1
+ std\\t%1,%0"
+ [(set_attr "op_type" "RRE,RXE,RXE,RR,RX,RX")
+ (set_attr "atype" "reg,mem,mem,reg,mem,mem")])
+
+(define_insn "*movdi_31"
+ [(set (match_operand:DI 0 "nonimmediate_operand" "=d,Q,d,m,!*f,!*f,!m")
+ (match_operand:DI 1 "general_operand" "Q,d,dKm,d,*f,m,*f"))]
+ "!TARGET_64BIT"
+ "@
+ lm\\t%0,%N0,%1
+ stm\\t%1,%N1,%0
+ #
+ #
+ ldr\\t%0,%1
+ ld\\t%0,%1
+ std\\t%1,%0"
+ [(set_attr "op_type" "RS,RS,NN,NN,RR,RX,RX")
+ (set_attr "atype" "mem,mem,*,*,reg,mem,mem")])
+
+(define_split
+ [(set (match_operand:DI 0 "nonimmediate_operand" "")
+ (match_operand:DI 1 "general_operand" ""))]
+ "!TARGET_64BIT && reload_completed
+ && !fp_operand (operands[0], VOIDmode)
+ && !fp_operand (operands[1], VOIDmode)
+ && !s_operand (operands[0], VOIDmode)
+ && !s_operand (operands[1], VOIDmode)
+ && (register_operand (operands[0], VOIDmode)
+ || register_operand (operands[1], VOIDmode))
+ && (!register_operand (operands[0], VOIDmode)
+ || !reg_overlap_mentioned_p (operand_subword (operands[0], 0, 0, DImode),
+ operands[1])
+ || !reg_overlap_mentioned_p (operand_subword (operands[0], 1, 0, DImode),
+ operands[1]))"
+ [(set (match_dup 2) (match_dup 4))
+ (set (match_dup 3) (match_dup 5))]
+ "
+{
+ if (!register_operand (operands[0], VOIDmode)
+ || !reg_overlap_mentioned_p (operand_subword (operands[0], 0, 0, DImode),
+ operands[1]))
+ {
+ operands[2] = operand_subword (operands[0], 0, 0, DImode);
+ operands[3] = operand_subword (operands[0], 1, 0, DImode);
+ operands[4] = operand_subword (operands[1], 0, 0, DImode);
+ operands[5] = operand_subword (operands[1], 1, 0, DImode);
+ }
+ else
+ {
+ operands[2] = operand_subword (operands[0], 1, 0, DImode);
+ operands[3] = operand_subword (operands[0], 0, 0, DImode);
+ operands[4] = operand_subword (operands[1], 1, 0, DImode);
+ operands[5] = operand_subword (operands[1], 0, 0, DImode);
+ }
+}")
+
+(define_split
+ [(set (match_operand:DI 0 "register_operand" "")
+ (match_operand:DI 1 "memory_operand" ""))]
+ "!TARGET_64BIT && reload_completed
+ && !fp_operand (operands[0], VOIDmode)
+ && !fp_operand (operands[1], VOIDmode)
+ && !s_operand (operands[1], VOIDmode)"
+ [(set (match_dup 2) (match_dup 3))
+ (set (match_dup 0) (mem:DI (match_dup 2)))]
+ "operands[2] = operand_subword (operands[0], 1, 0, DImode);
+ operands[3] = legitimize_la_operand (XEXP (operands[1], 0));")
+
+;
+; 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" ""))]
+ ""
+ "
+{
+ /* Handle PIC symbolic constants. */
+ if (!TARGET_64BIT && flag_pic && SYMBOLIC_CONST (operands[1]))
+ emit_pic_move (operands, SImode);
+
+ /* expr.c tries to load an effective address using
+ force_reg. This fails because we don't have a
+ generic load_address pattern. Convert the move
+ to a proper arithmetic operation instead, unless
+ it is guaranteed to be OK. */
+ if (GET_CODE (operands[1]) == PLUS
+ && !legitimate_la_operand_p (operands[1]))
+ {
+ operands[1] = force_operand (operands[1], operands[0]);
+ if (operands[1] == operands[0])
+ DONE;
+ }
+
+ /* During and after reload, we need to force constants
+ to the literal pool ourselves, if necessary. */
+ if ((reload_in_progress || reload_completed)
+ && CONSTANT_P (operands[1])
+ && (!legitimate_reload_constant_p (operands[1])
+ || fp_operand (operands[0], VOIDmode)))
+ operands[1] = force_const_mem (SImode, operands[1]);
+}")
+
+(define_insn "*movsi_lhi"
+ [(set (match_operand:SI 0 "register_operand" "=d")
+ (match_operand:SI 1 "immediate_operand" "K"))]
+ "GET_CODE (operands[1]) == CONST_INT
+ && CONST_OK_FOR_LETTER_P (INTVAL (operands[1]), 'K')
+ && !fp_operand (operands[0], VOIDmode)"
+ "lhi\\t%0,%h1"
+ [(set_attr "op_type" "RI")])
+
+(define_insn "*movsi_lli"
+ [(set (match_operand:SI 0 "register_operand" "=d")
+ (match_operand:SI 1 "immediate_operand" "n"))]
+ "TARGET_64BIT && s390_single_hi (operands[1], SImode, 0) >= 0
+ && !fp_operand (operands[0], VOIDmode)"
+ "*
+{
+ int part = s390_single_hi (operands[1], SImode, 0);
+ operands[1] = GEN_INT (s390_extract_hi (operands[1], SImode, part));
+
+ switch (part)
+ {
+ case 0: return \"llilh\\t%0,%x1\";
+ case 1: return \"llill\\t%0,%x1\";
+ default: abort ();
+ }
+}"
+ [(set_attr "op_type" "RI")])
+
+(define_insn "*movsi_ss"
+ [(set (match_operand:SI 0 "s_operand" "=Qo")
+ (match_operand:SI 1 "s_imm_operand" "Qo"))]
+ ""
+ "mvc\\t%O0(4,%R0),%1"
+ [(set_attr "op_type" "SS")
+ (set_attr "atype" "mem")])
+
+(define_insn "*movsi"
+ [(set (match_operand:SI 0 "nonimmediate_operand" "=d,d,m,!*f,!*f,!m")
+ (match_operand:SI 1 "general_operand" "d,m,d,*f,m,*f"))]
+ ""
+ "@
+ lr\\t%0,%1
+ l\\t%0,%1
+ st\\t%1,%0
+ ler\\t%0,%1
+ le\\t%0,%1
+ ste\\t%1,%0"
+ [(set_attr "op_type" "RR,RX,RX,RR,RX,RX")
+ (set_attr "atype" "reg,mem,mem,reg,mem,mem")])
+
+
+;
+; movhi instruction pattern(s).
+;
+
+(define_insn "movhi"
+ [(set (match_operand:HI 0 "nonimmediate_operand" "=d,d,d,m")
+ (match_operand:HI 1 "general_operand" "d,n,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")])
+
+
+;
+; 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,n,m,d,n"))]
+ "TARGET_64BIT"
+ "@
+ lr\\t%0,%1
+ lhi\\t%0,%b1
+ 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")])
+
+
+(define_insn "movqi"
+ [(set (match_operand:QI 0 "nonimmediate_operand" "=d,d,d,m,Q")
+ (match_operand:QI 1 "general_operand" "d,n,m,d,n"))]
+ ""
+ "@
+ lr\\t%0,%1
+ lhi\\t%0,%b1
+ ic\\t%0,%1
+ stc\\t%1,%0
+ mvi\\t%0,%b1"
+ [(set_attr "op_type" "RR,RI,RX,RX,SI")
+ (set_attr "atype" "reg,reg,mem,mem,mem")])
+
+
+;
+; moveqstrictqi instruction pattern(s).
+;
+
+(define_insn "*movstrictqi"
+ [(set (strict_low_part (match_operand:QI 0 "register_operand" "+d"))
+ (match_operand:QI 1 "memory_operand" "m"))]
+ ""
+ "ic\\t%0,%1"
+ [(set_attr "op_type" "RX")
+ (set_attr "atype" "mem")])
+
+;
+; movstricthi instruction pattern(s).
+;
+
+(define_insn "*movstricthi"
+ [(set (strict_low_part (match_operand:HI 0 "register_operand" "+d"))
+ (match_operand:HI 1 "s_imm_operand" "Qo"))
+ (clobber (reg:CC 33))]
+ ""
+ "icm\\t%0,3,%1"
+ [(set_attr "op_type" "RS")
+ (set_attr "atype" "mem")])
+
+
+;
+; movstrictsi instruction pattern(s).
+;
+
+(define_insn "movestrictsi"
+ [(set (strict_low_part (match_operand:SI 0 "register_operand" "+d,d"))
+ (match_operand:SI 1 "general_operand" "d,m"))]
+ "TARGET_64BIT"
+ "@
+ lr\\t%0,%1
+ l\\t%0,%1"
+ [(set_attr "op_type" "RR,RS")
+ (set_attr "atype" "reg,mem")])
+
+
+;
+; movdf instruction pattern(s).
+;
+
+(define_expand "movdf"
+ [(set (match_operand:DF 0 "nonimmediate_operand" "")
+ (match_operand:DF 1 "general_operand" ""))]
+ ""
+ "
+{
+ /* During and after reload, we need to force constants
+ to the literal pool ourselves, if necessary. */
+ if ((reload_in_progress || reload_completed)
+ && CONSTANT_P (operands[1]))
+ operands[1] = force_const_mem (DFmode, operands[1]);
+}")
+
+(define_insn "*movdf_ss"
+ [(set (match_operand:DF 0 "s_operand" "=Qo")
+ (match_operand:DF 1 "s_imm_operand" "Qo"))]
+ ""
+ "mvc\\t%O0(8,%R0),%1"
+ [(set_attr "op_type" "SS")
+ (set_attr "atype" "mem")])
+
+(define_insn "*movdf_64"
+ [(set (match_operand:DF 0 "nonimmediate_operand" "=f,f,m,d,d,m")
+ (match_operand:DF 1 "general_operand" "f,m,f,d,m,d"))]
+ "TARGET_64BIT"
+ "@
+ ldr\\t%0,%1
+ ld\\t%0,%1
+ std\\t%1,%0
+ lgr\\t%0,%1
+ lg\\t%0,%1
+ stg\\t%1,%0"
+ [(set_attr "op_type" "RR,RX,RX,RRE,RXE,RXE")
+ (set_attr "atype" "reg,mem,mem,reg,mem,mem")])
+
+(define_insn "*movdf_31"
+ [(set (match_operand:DF 0 "nonimmediate_operand" "=f,f,m,d,Q,d,m")
+ (match_operand:DF 1 "general_operand" "f,m,f,Q,d,dKm,d"))]
+ "!TARGET_64BIT"
+ "@
+ ldr\\t%0,%1
+ ld\\t%0,%1
+ std\\t%1,%0
+ lm\\t%0,%N0,%1
+ stm\\t%1,%N1,%0
+ #
+ #"
+ [(set_attr "op_type" "RR,RX,RX,RS,RS,NN,NN")
+ (set_attr "atype" "reg,mem,mem,mem,mem,*,*")])
+
+(define_split
+ [(set (match_operand:DF 0 "nonimmediate_operand" "")
+ (match_operand:DF 1 "general_operand" ""))]
+ "!TARGET_64BIT && reload_completed
+ && !fp_operand (operands[0], VOIDmode)
+ && !fp_operand (operands[1], VOIDmode)
+ && !s_operand (operands[0], VOIDmode)
+ && !s_operand (operands[1], VOIDmode)
+ && (register_operand (operands[0], VOIDmode)
+ || register_operand (operands[1], VOIDmode))
+ && (!register_operand (operands[0], VOIDmode)
+ || !reg_overlap_mentioned_p (operand_subword (operands[0], 0, 0, DFmode),
+ operands[1])
+ || !reg_overlap_mentioned_p (operand_subword (operands[0], 1, 0, DFmode),
+ operands[1]))"
+ [(set (match_dup 2) (match_dup 4))
+ (set (match_dup 3) (match_dup 5))]
+ "
+{
+ if (!register_operand (operands[0], VOIDmode)
+ || !reg_overlap_mentioned_p (operand_subword (operands[0], 0, 0, DFmode),
+ operands[1]))
+ {
+ operands[2] = operand_subword (operands[0], 0, 0, DFmode);
+ operands[3] = operand_subword (operands[0], 1, 0, DFmode);
+ operands[4] = operand_subword (operands[1], 0, 0, DFmode);
+ operands[5] = operand_subword (operands[1], 1, 0, DFmode);
+ }
+ else
+ {
+ operands[2] = operand_subword (operands[0], 1, 0, DFmode);
+ operands[3] = operand_subword (operands[0], 0, 0, DFmode);
+ operands[4] = operand_subword (operands[1], 1, 0, DFmode);
+ operands[5] = operand_subword (operands[1], 0, 0, DFmode);
+ }
+}")
+
+(define_split
+ [(set (match_operand:DF 0 "register_operand" "")
+ (match_operand:DF 1 "memory_operand" ""))]
+ "!TARGET_64BIT && reload_completed
+ && !fp_operand (operands[0], VOIDmode)
+ && !fp_operand (operands[1], VOIDmode)
+ && !s_operand (operands[1], VOIDmode)"
+ [(set (match_dup 2) (match_dup 3))
+ (set (match_dup 0) (mem:DI (match_dup 2)))]
+ "operands[2] = operand_subword (operands[0], 1, 0, DFmode);
+ operands[3] = legitimize_la_operand (XEXP (operands[1], 0));")
+
+;
+; movsf instruction pattern(s).
+;
+
+(define_expand "movsf"
+ [(set (match_operand:SF 0 "nonimmediate_operand" "")
+ (match_operand:SF 1 "general_operand" ""))]
+ ""
+ "
+{
+ /* During and after reload, we need to force constants
+ to the literal pool ourselves, if necessary. */
+ if ((reload_in_progress || reload_completed)
+ && CONSTANT_P (operands[1]))
+ operands[1] = force_const_mem (SFmode, operands[1]);
+}")
+
+(define_insn "*movsf_ss"
+ [(set (match_operand:SF 0 "s_operand" "=Qo")
+ (match_operand:SF 1 "s_imm_operand" "Qo"))]
+ ""
+ "mvc\\t%O0(4,%R0),%1"
+ [(set_attr "op_type" "SS")
+ (set_attr "atype" "mem")])
+
+(define_insn "*movsf"
+ [(set (match_operand:SF 0 "nonimmediate_operand" "=f,f,m,d,d,m")
+ (match_operand:SF 1 "general_operand" "f,m,f,d,m,d"))]
+ ""
+ "@
+ ler\\t%0,%1
+ le\\t%0,%1
+ ste\\t%1,%0
+ lr\\t%0,%1
+ l\\t%0,%1
+ st\\t%1,%0"
+ [(set_attr "op_type" "RR,RX,RX,RR,RX,RX")
+ (set_attr "atype" "reg,mem,mem,reg,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, off;
+
+ /* 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));
+ if (no_new_pseudos)
+ {
+ if (GET_CODE (XEXP (operands[1], 0)) == REG)
+ {
+ from = XEXP (operands[1], 0);
+ off = 0;
+ }
+ else if (GET_CODE (XEXP (operands[1], 0)) == PLUS
+ && GET_CODE (XEXP (XEXP (operands[1], 0), 0)) == REG
+ && GET_CODE (XEXP (XEXP (operands[1], 0), 1)) == CONST_INT)
+ {
+ from = XEXP (XEXP (operands[1], 0), 0);
+ off = INTVAL (XEXP (XEXP (operands[1], 0), 1));
+ }
+ else
+ FAIL;
+
+ if (from == frame_pointer_rtx || from == arg_pointer_rtx)
+ FAIL;
+ }
+ else
+ {
+ from = force_reg (Pmode, XEXP (operands[1], 0));
+ off = 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,
+ off + i * UNITS_PER_WORD)));
+}")
+
+(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" "lm")])
+
+(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" "lm")])
+
+;
+; 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, off;
+
+ /* 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));
+
+ if (no_new_pseudos)
+ {
+ if (GET_CODE (XEXP (operands[0], 0)) == REG)
+ {
+ to = XEXP (operands[0], 0);
+ off = 0;
+ }
+ else if (GET_CODE (XEXP (operands[0], 0)) == PLUS
+ && GET_CODE (XEXP (XEXP (operands[0], 0), 0)) == REG
+ && GET_CODE (XEXP (XEXP (operands[0], 0), 1)) == CONST_INT)
+ {
+ to = XEXP (XEXP (operands[0], 0), 0);
+ off = INTVAL (XEXP (XEXP (operands[0], 0), 1));
+ }
+ else
+ FAIL;
+
+ if (to == frame_pointer_rtx || to == arg_pointer_rtx)
+ FAIL;
+ }
+ else
+ {
+ to = force_reg (Pmode, XEXP (operands[0], 0));
+ off = 0;
+ }
+
+ for (i = 0; i < count; i++)
+ XVECEXP (operands[3], 0, i)
+ = gen_rtx_SET (VOIDmode,
+ change_address (operands[0], Pmode,
+ plus_constant (to,
+ off + i * UNITS_PER_WORD)),
+ 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" "stm")])
+
+
+(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" "stm")])
+
+;;
+;; 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_movstrdi_short (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_highpart (DImode, reg0), addr0);
+ emit_move_insn (gen_lowpart (DImode, reg0), len);
+
+ emit_move_insn (gen_highpart (DImode, reg1), addr1);
+ emit_move_insn (gen_lowpart (DImode, reg1), len);
+
+ /* MOVE */
+ emit_insn (gen_movstrdi_64 (reg0, reg1, reg0, reg1));
+ DONE;
+ }
+ else
+ {
+ rtx label1 = gen_label_rtx ();
+ rtx label2 = gen_label_rtx ();
+ rtx reg0, reg1, len, blocks;
+
+ reg0 = gen_reg_rtx (DImode);
+ reg1 = gen_reg_rtx (DImode);
+ len = gen_reg_rtx (DImode);
+ blocks = gen_reg_rtx (DImode);
+
+ emit_move_insn (len, operands[2]);
+ emit_insn (gen_cmpdi (len, const0_rtx));
+ emit_jump_insn (gen_beq (label1));
+ emit_move_insn (reg0, addr0);
+ emit_move_insn (reg1, addr1);
+ emit_insn (gen_adddi3 (len, len, constm1_rtx));
+ emit_insn (gen_ashrdi3 (blocks, len, GEN_INT (8)));
+ emit_insn (gen_cmpdi (blocks, const0_rtx));
+ emit_jump_insn (gen_beq (label2));
+ emit_insn (gen_movstrdi_long (reg0, reg1, reg0, reg1, blocks, blocks));
+ emit_label (label2);
+ operands[0] = change_address (operands[0], VOIDmode, reg0);
+ operands[1] = change_address (operands[1], VOIDmode, reg1);
+ emit_insn (gen_movstrdi_short (operands[0], operands[1], len));
+ emit_label (label1);
+ 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 "" "")]
+ "!TARGET_64BIT"
+ "
+{
+ 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_movstrsi_short (operands[0], operands[1], operands[2]));
+ DONE;
+ }
+ else
+ {
+ 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_highpart (SImode, reg0), addr0);
+ emit_move_insn (gen_lowpart (SImode, reg0), len);
+
+ emit_move_insn (gen_highpart (SImode, reg1), addr1);
+ emit_move_insn (gen_lowpart (SImode, reg1), len);
+
+ /* MOVE */
+ emit_insn (gen_movstrsi_31 (reg0, reg1, reg0, reg1));
+ DONE;
+ }
+ else
+ {
+ rtx label1 = gen_label_rtx ();
+ rtx label2 = gen_label_rtx ();
+ rtx reg0, reg1, len, blocks;
+
+ reg0 = gen_reg_rtx (SImode);
+ reg1 = gen_reg_rtx (SImode);
+ len = gen_reg_rtx (SImode);
+ blocks = gen_reg_rtx (SImode);
+
+ emit_move_insn (len, operands[2]);
+ emit_insn (gen_cmpsi (len, const0_rtx));
+ emit_jump_insn (gen_beq (label1));
+ emit_move_insn (reg0, addr0);
+ emit_move_insn (reg1, addr1);
+ emit_insn (gen_addsi3 (len, len, constm1_rtx));
+ emit_insn (gen_ashrsi3 (blocks, len, GEN_INT (8)));
+ emit_insn (gen_cmpsi (blocks, const0_rtx));
+ emit_jump_insn (gen_beq (label2));
+ emit_insn (gen_movstrsi_long (reg0, reg1, reg0, reg1, blocks, blocks));
+ emit_label (label2);
+ operands[0] = change_address (operands[0], VOIDmode, reg0);
+ operands[1] = change_address (operands[1], VOIDmode, reg1);
+ emit_insn (gen_movstrsi_short (operands[0], operands[1], len));
+ emit_label (label1);
+ DONE;
+ }
+ }
+}")
+
+; Move a block that is up to 256 bytes in length.
+; The block length is taken as (operands[2] % 256) + 1.
+
+(define_insn "movstrdi_short"
+ [(set (match_operand:BLK 0 "s_operand" "=oQ,oQ")
+ (match_operand:BLK 1 "s_operand" "oQ,oQ"))
+ (use (match_operand:DI 2 "nonmemory_operand" "n,a"))
+ (clobber (match_scratch:DI 3 "=X,&a"))]
+ "TARGET_64BIT"
+ "*
+{
+ switch (which_alternative)
+ {
+ case 0:
+ return \"mvc\\t%O0(%b2+1,%R0),%1\";
+
+ case 1:
+ output_asm_insn (\"bras\\t%3,.+10\", operands);
+ output_asm_insn (\"mvc\\t%O0(1,%R0),%1\", operands);
+ return \"ex\\t%2,0(%3)\";
+
+ default:
+ abort ();
+ }
+}"
+ [(set_attr "op_type" "SS,NN")
+ (set_attr "atype" "mem,mem")
+ (set_attr "length" "*,14")])
+
+(define_insn "movstrsi_short"
+ [(set (match_operand:BLK 0 "s_operand" "=oQ,oQ")
+ (match_operand:BLK 1 "s_operand" "oQ,oQ"))
+ (use (match_operand:SI 2 "nonmemory_operand" "n,a"))
+ (clobber (match_scratch:SI 3 "=X,&a"))]
+ "!TARGET_64BIT"
+ "*
+{
+ switch (which_alternative)
+ {
+ case 0:
+ return \"mvc\\t%O0(%b2+1,%R0),%1\";
+
+ case 1:
+ output_asm_insn (\"bras\\t%3,.+10\", operands);
+ output_asm_insn (\"mvc\\t%O0(1,%R0),%1\", operands);
+ return \"ex\\t%2,0(%3)\";
+
+ default:
+ abort ();
+ }
+}"
+ [(set_attr "op_type" "SS,NN")
+ (set_attr "atype" "mem,mem")
+ (set_attr "length" "*,14")])
+
+; Move a block that is a multiple of 256 bytes in length
+
+(define_insn "movstrdi_long"
+ [(set (match_operand:DI 4 "register_operand" "=d")
+ (const_int 0))
+ (set (match_operand:DI 0 "register_operand" "=a")
+ (plus:DI (match_operand:DI 2 "register_operand" "0")
+ (ashift:DI (match_operand:DI 5 "register_operand" "4")
+ (const_int 8))))
+ (set (match_operand:DI 1 "register_operand" "=a")
+ (plus:DI (match_operand:DI 3 "register_operand" "1")
+ (ashift:DI (match_dup 5) (const_int 8))))
+ (set (mem:BLK (match_dup 2))
+ (mem:BLK (match_dup 3)))
+ (use (match_dup 5))]
+ "TARGET_64BIT"
+ "*
+{
+ 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);
+ return \"brct\\t%4,.-14\";
+}"
+ [(set_attr "op_type" "NN")
+ (set_attr "atype" "mem")
+ (set_attr "length" "18")])
+
+(define_insn "movstrsi_long"
+ [(set (match_operand:SI 4 "register_operand" "=d")
+ (const_int 0))
+ (set (match_operand:SI 0 "register_operand" "=a")
+ (plus:SI (match_operand:SI 2 "register_operand" "0")
+ (ashift:SI (match_operand:SI 5 "register_operand" "4")
+ (const_int 8))))
+ (set (match_operand:SI 1 "register_operand" "=a")
+ (plus:SI (match_operand:SI 3 "register_operand" "1")
+ (ashift:SI (match_dup 5) (const_int 8))))
+ (set (mem:BLK (match_dup 2))
+ (mem:BLK (match_dup 3)))
+ (use (match_dup 5))]
+ "!TARGET_64BIT"
+ "*
+{
+ 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);
+ return \"brct\\t%4,.-14\";
+}"
+ [(set_attr "op_type" "NN")
+ (set_attr "atype" "mem")
+ (set_attr "length" "18")])
+
+; Move a block that is larger than 255 bytes in length.
+
+(define_insn "movstrdi_64"
+ [(set (match_operand:TI 0 "register_operand" "=d")
+ (ashift:TI (plus:TI (match_operand:TI 2 "register_operand" "0")
+ (lshiftrt:TI (match_dup 2) (const_int 64)))
+ (const_int 64)))
+ (set (match_operand:TI 1 "register_operand" "=d")
+ (ashift:TI (plus:TI (match_operand:TI 3 "register_operand" "1")
+ (lshiftrt:TI (match_dup 3) (const_int 64)))
+ (const_int 64)))
+ (set (mem:BLK (subreg:DI (match_dup 2) 0))
+ (mem:BLK (subreg:DI (match_dup 3) 0)))
+ (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 "length" "8")])
+
+(define_insn "movstrsi_31"
+ [(set (match_operand:DI 0 "register_operand" "=d")
+ (ashift:DI (plus:DI (match_operand:DI 2 "register_operand" "0")
+ (lshiftrt:DI (match_dup 2) (const_int 32)))
+ (const_int 32)))
+ (set (match_operand:DI 1 "register_operand" "=d")
+ (ashift:DI (plus:DI (match_operand:DI 3 "register_operand" "1")
+ (lshiftrt:DI (match_dup 3) (const_int 32)))
+ (const_int 32)))
+ (set (mem:BLK (subreg:SI (match_dup 2) 0))
+ (mem:BLK (subreg:SI (match_dup 3) 0)))
+ (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 "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_highpart (DImode, reg0), addr);
+ emit_move_insn (gen_lowpart (DImode, reg0), len);
+
+ emit_move_insn (gen_lowpart (DImode, reg1), const0_rtx);
+
+ /* Clear! */
+ emit_insn (gen_clrstrsi_64 (reg0, reg1, reg0));
+ 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_highpart (SImode, reg0), addr);
+ emit_move_insn (gen_lowpart (SImode, reg0), len);
+
+ emit_move_insn (gen_lowpart (SImode, reg1), const0_rtx);
+
+ /* CLear! */
+ emit_insn (gen_clrstrsi_31 (reg0, reg1, reg0));
+ 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 "type" "cs")
+ (set_attr "atype" "mem")])
+
+; Clear memory with length greater 256 bytes or lenght not constant
+
+(define_insn "clrstrsi_64"
+ [(set (match_operand:TI 0 "register_operand" "=d")
+ (ashift:TI (plus:TI (match_operand:TI 2 "register_operand" "0")
+ (lshiftrt:TI (match_dup 2) (const_int 64)))
+ (const_int 64)))
+ (set (mem:BLK (subreg:DI (match_dup 2) 0))
+ (const_int 0))
+ (use (match_operand:TI 1 "register_operand" "d"))
+ (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 "type" "vs")
+ (set_attr "length" "8")])
+
+(define_insn "clrstrsi_31"
+ [(set (match_operand:DI 0 "register_operand" "=d")
+ (ashift:DI (plus:DI (match_operand:DI 2 "register_operand" "0")
+ (lshiftrt:DI (match_dup 2) (const_int 32)))
+ (const_int 32)))
+ (set (mem:BLK (subreg:SI (match_dup 2) 0))
+ (const_int 0))
+ (use (match_operand:DI 1 "register_operand" "d"))
+ (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 "type" "vs")
+ (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_highpart (DImode, reg0), addr0);
+ emit_move_insn (gen_lowpart (DImode, reg0), len);
+
+ emit_move_insn (gen_highpart (DImode, reg1), addr1);
+ emit_move_insn (gen_lowpart (DImode, reg1), len);
+
+ /* Compare! */
+ emit_insn (gen_cmpstr_64 (reg0, reg1, 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);
+ }
+
+ /* Load up the address+length pairs. */
+ emit_move_insn (gen_highpart (Pmode, reg0), addr0);
+ convert_move (gen_lowpart (Pmode, reg0), len, 1);
+
+ emit_move_insn (gen_highpart (Pmode, reg1), addr1);
+ convert_move (gen_lowpart (Pmode, reg1), len, 1);
+
+ /* Compare! */
+ if (TARGET_64BIT)
+ emit_insn (gen_cmpstr_64 (reg0, reg1, reg0, reg1));
+ else
+ emit_insn (gen_cmpstr_31 (reg0, reg1, 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:CCS 33)
+ (compare:CCS (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" "cs")])
+
+; Compare a block that is larger than 255 bytes in length.
+
+(define_insn "cmpstr_64"
+ [(clobber (match_operand:TI 0 "register_operand" "=d"))
+ (clobber (match_operand:TI 1 "register_operand" "=d"))
+ (set (reg:CCS 33)
+ (compare:CCS (mem:BLK (subreg:DI (match_operand:TI 2 "register_operand" "0") 0))
+ (mem:BLK (subreg:DI (match_operand:TI 3 "register_operand" "1") 0))))]
+ "TARGET_64BIT"
+ "clcl\\t%0,%1"
+ [(set_attr "op_type" "RR")
+ (set_attr "atype" "mem")
+ (set_attr "type" "vs")])
+
+(define_insn "cmpstr_31"
+ [(clobber (match_operand:DI 0 "register_operand" "=d"))
+ (clobber (match_operand:DI 1 "register_operand" "=d"))
+ (set (reg:CCS 33)
+ (compare:CCS (mem:BLK (subreg:SI (match_operand:DI 2 "register_operand" "0") 0))
+ (mem:BLK (subreg:SI (match_operand:DI 3 "register_operand" "1") 0))))]
+ "!TARGET_64BIT"
+ "clcl\\t%0,%1"
+ [(set_attr "op_type" "RR")
+ (set_attr "atype" "mem")
+ (set_attr "type" "vs")])
+
+; 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:CCS 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" "other")])
+
+(define_insn "cmpint_di"
+ [(set (match_operand:DI 0 "register_operand" "=d")
+ (compare:DI (reg:CCS 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" "other")])
+
+
+;;
+;;- Conversion instructions.
+;;
+
+(define_insn "*sethighqisi"
+ [(set (match_operand:SI 0 "register_operand" "=d")
+ (unspec:SI [(match_operand:QI 1 "s_operand" "Qo")] 10))
+ (clobber (reg:CC 33))]
+ ""
+ "icm\\t%0,8,%1"
+ [(set_attr "op_type" "RS")
+ (set_attr "atype" "mem")])
+
+(define_insn "*sethighhisi"
+ [(set (match_operand:SI 0 "register_operand" "=d")
+ (unspec:SI [(match_operand:HI 1 "s_operand" "Qo")] 10))
+ (clobber (reg:CC 33))]
+ ""
+ "icm\\t%0,12,%1"
+ [(set_attr "op_type" "RS")
+ (set_attr "atype" "mem")])
+
+(define_insn "*sethighqidi_64"
+ [(set (match_operand:DI 0 "register_operand" "=d")
+ (unspec:DI [(match_operand:QI 1 "s_operand" "Qo")] 10))
+ (clobber (reg:CC 33))]
+ "TARGET_64BIT"
+ "icmh\\t%0,8,%1"
+ [(set_attr "op_type" "RSE")
+ (set_attr "atype" "mem")])
+
+(define_insn "*sethighqidi_31"
+ [(set (match_operand:DI 0 "register_operand" "=d")
+ (unspec:DI [(match_operand:QI 1 "s_operand" "Qo")] 10))
+ (clobber (reg:CC 33))]
+ "!TARGET_64BIT"
+ "icm\\t%0,8,%1"
+ [(set_attr "op_type" "RS")
+ (set_attr "atype" "mem")])
+
+(define_split
+ [(set (match_operand:SI 0 "register_operand" "")
+ (zero_extract:SI (match_operand:QI 1 "s_operand" "")
+ (match_operand 2 "const_int_operand" "")
+ (const_int 0)))]
+ "!TARGET_64BIT && !reload_completed
+ && INTVAL (operands[2]) > 0 && INTVAL (operands[2]) < 8"
+ [(parallel
+ [(set (match_dup 0) (unspec:SI [(match_dup 1)] 10))
+ (clobber (reg:CC 33))])
+ (set (match_dup 0) (lshiftrt:SI (match_dup 0) (match_dup 2)))]
+ "
+{
+ operands[2] = GEN_INT (32 - INTVAL (operands[2]));
+ operands[1] = change_address (operands[1], QImode, 0);
+}")
+
+(define_split
+ [(set (match_operand:SI 0 "register_operand" "")
+ (zero_extract:SI (match_operand:QI 1 "s_operand" "")
+ (match_operand 2 "const_int_operand" "")
+ (const_int 0)))]
+ "!TARGET_64BIT && !reload_completed
+ && INTVAL (operands[2]) >= 8 && INTVAL (operands[2]) < 16"
+ [(parallel
+ [(set (match_dup 0) (unspec:SI [(match_dup 1)] 10))
+ (clobber (reg:CC 33))])
+ (set (match_dup 0) (lshiftrt:SI (match_dup 0) (match_dup 2)))]
+ "
+{
+ operands[2] = GEN_INT (32 - INTVAL (operands[2]));
+ operands[1] = change_address (operands[1], HImode, 0);
+}")
+
+;
+; extendsidi2 instruction pattern(s).
+;
+
+(define_expand "extendsidi2"
+ [(set (match_operand:DI 0 "register_operand" "")
+ (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "")))]
+ ""
+ "
+{
+ if (!TARGET_64BIT)
+ {
+ emit_insn (gen_rtx_CLOBBER (VOIDmode, operands[0]));
+ emit_move_insn (gen_highpart (SImode, operands[0]), operands[1]);
+ emit_move_insn (gen_lowpart (SImode, operands[0]), const0_rtx);
+ emit_insn (gen_ashrdi3 (operands[0], operands[0], GEN_INT (32)));
+ DONE;
+ }
+}
+")
+
+(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")])
+
+;
+; extendhidi2 instruction pattern(s).
+;
+
+(define_expand "extendhidi2"
+ [(set (match_operand:DI 0 "register_operand" "")
+ (sign_extend:DI (match_operand:HI 1 "register_operand" "")))]
+ ""
+ "
+{
+ if (!TARGET_64BIT)
+ {
+ rtx tmp = gen_reg_rtx (SImode);
+ emit_insn (gen_extendhisi2 (tmp, operands[1]));
+ emit_insn (gen_extendsidi2 (operands[0], tmp));
+ DONE;
+ }
+ else
+ {
+ operands[1] = gen_lowpart (DImode, operands[1]);
+ emit_insn (gen_ashldi3 (operands[0], operands[1], GEN_INT (48)));
+ emit_insn (gen_ashrdi3 (operands[0], operands[0], GEN_INT (48)));
+ DONE;
+ }
+}
+")
+
+(define_insn "*extendhidi2"
+ [(set (match_operand:DI 0 "register_operand" "=d")
+ (sign_extend:DI (match_operand:HI 1 "memory_operand" "m")))]
+ "TARGET_64BIT"
+ "lgh\\t%0,%1"
+ [(set_attr "op_type" "RXE")
+ (set_attr "atype" "mem")])
+
+;
+; extendqidi2 instruction pattern(s).
+;
+
+(define_expand "extendqidi2"
+ [(set (match_operand:DI 0 "register_operand" "")
+ (sign_extend:DI (match_operand:QI 1 "register_operand" "")))]
+ ""
+ "
+{
+ if (!TARGET_64BIT)
+ {
+ rtx tmp = gen_reg_rtx (SImode);
+ emit_insn (gen_extendqisi2 (tmp, operands[1]));
+ emit_insn (gen_extendsidi2 (operands[0], tmp));
+ DONE;
+ }
+ else
+ {
+ operands[1] = gen_lowpart (DImode, operands[1]);
+ emit_insn (gen_ashldi3 (operands[0], operands[1], GEN_INT (56)));
+ emit_insn (gen_ashrdi3 (operands[0], operands[0], GEN_INT (56)));
+ DONE;
+ }
+}
+")
+
+(define_split
+ [(set (match_operand:DI 0 "register_operand" "")
+ (sign_extend:DI (match_operand:QI 1 "s_operand" "")))]
+ "TARGET_64BIT && !reload_completed"
+ [(parallel
+ [(set (match_dup 0) (unspec:DI [(match_dup 1)] 10))
+ (clobber (reg:CC 33))])
+ (parallel
+ [(set (match_dup 0) (ashiftrt:DI (match_dup 0) (const_int 56)))
+ (clobber (reg:CC 33))])]
+ "")
+
+;
+; extendhisi2 instruction pattern(s).
+;
+
+(define_expand "extendhisi2"
+ [(set (match_operand:SI 0 "register_operand" "")
+ (sign_extend:SI (match_operand:HI 1 "register_operand" "")))]
+ ""
+ "
+{
+ operands[1] = gen_lowpart (SImode, operands[1]);
+ emit_insn (gen_ashlsi3 (operands[0], operands[1], GEN_INT (16)));
+ emit_insn (gen_ashrsi3 (operands[0], operands[0], GEN_INT (16)));
+ DONE;
+}
+")
+
+(define_insn "*extendhisi2"
+ [(set (match_operand:SI 0 "register_operand" "=d")
+ (sign_extend:SI (match_operand:HI 1 "memory_operand" "m")))]
+ ""
+ "lh\\t%0,%1"
+ [(set_attr "op_type" "RX")
+ (set_attr "atype" "mem")])
+
+;
+; extendqisi2 instruction pattern(s).
+;
+
+(define_expand "extendqisi2"
+ [(set (match_operand:SI 0 "register_operand" "")
+ (sign_extend:SI (match_operand:QI 1 "register_operand" "")))]
+ ""
+ "
+{
+ operands[1] = gen_lowpart (SImode, operands[1]);
+ emit_insn (gen_ashlsi3 (operands[0], operands[1], GEN_INT (24)));
+ emit_insn (gen_ashrsi3 (operands[0], operands[0], GEN_INT (24)));
+ DONE;
+}
+")
+
+(define_split
+ [(set (match_operand:SI 0 "register_operand" "")
+ (sign_extend:SI (match_operand:QI 1 "s_operand" "")))]
+ "!reload_completed"
+ [(parallel
+ [(set (match_dup 0) (unspec:SI [(match_dup 1)] 10))
+ (clobber (reg:CC 33))])
+ (parallel
+ [(set (match_dup 0) (ashiftrt:SI (match_dup 0) (const_int 24)))
+ (clobber (reg:CC 33))])]
+ "")
+
+;
+; extendqihi2 instruction pattern(s).
+;
+
+
+;
+; zero_extendsidi2 instruction pattern(s).
+;
+
+(define_expand "zero_extendsidi2"
+ [(set (match_operand:DI 0 "register_operand" "")
+ (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "")))]
+ ""
+ "
+{
+ if (!TARGET_64BIT)
+ {
+ emit_insn (gen_rtx_CLOBBER (VOIDmode, operands[0]));
+ emit_move_insn (gen_lowpart (SImode, operands[0]), operands[1]);
+ emit_move_insn (gen_highpart (SImode, operands[0]), const0_rtx);
+ DONE;
+ }
+}
+")
+
+(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")])
+
+;
+; zero_extendhidi2 instruction pattern(s).
+;
+
+(define_expand "zero_extendhidi2"
+ [(set (match_operand:DI 0 "register_operand" "")
+ (zero_extend:DI (match_operand:HI 1 "register_operand" "")))]
+ ""
+ "
+{
+ if (!TARGET_64BIT)
+ {
+ rtx tmp = gen_reg_rtx (SImode);
+ emit_insn (gen_zero_extendhisi2 (tmp, operands[1]));
+ emit_insn (gen_zero_extendsidi2 (operands[0], tmp));
+ DONE;
+ }
+ else
+ {
+ operands[1] = gen_lowpart (DImode, operands[1]);
+ emit_insn (gen_ashldi3 (operands[0], operands[1], GEN_INT (48)));
+ emit_insn (gen_lshrdi3 (operands[0], operands[0], GEN_INT (48)));
+ DONE;
+ }
+}
+")
+
+(define_insn "*zero_extendhidi2"
+ [(set (match_operand:DI 0 "register_operand" "=d")
+ (zero_extend:DI (match_operand:HI 1 "memory_operand" "m")))]
+ "TARGET_64BIT"
+ "llgh\\t%0,%1"
+ [(set_attr "op_type" "RXE")
+ (set_attr "atype" "mem")])
+
+;
+; zero_extendqidi2 instruction pattern(s)
+;
+
+(define_expand "zero_extendqidi2"
+ [(set (match_operand:DI 0 "register_operand" "")
+ (zero_extend:DI (match_operand:QI 1 "register_operand" "")))]
+ ""
+ "
+{
+ if (!TARGET_64BIT)
+ {
+ rtx tmp = gen_reg_rtx (SImode);
+ emit_insn (gen_zero_extendqisi2 (tmp, operands[1]));
+ emit_insn (gen_zero_extendsidi2 (operands[0], tmp));
+ DONE;
+ }
+ else
+ {
+ operands[1] = gen_lowpart (DImode, operands[1]);
+ emit_insn (gen_ashldi3 (operands[0], operands[1], GEN_INT (56)));
+ emit_insn (gen_lshrdi3 (operands[0], operands[0], GEN_INT (56)));
+ DONE;
+ }
+}
+")
+
+(define_insn "*zero_extendqidi2"
+ [(set (match_operand:DI 0 "register_operand" "=d")
+ (zero_extend:DI (match_operand:QI 1 "memory_operand" "m")))]
+ "TARGET_64BIT"
+ "llgc\\t%0,%1"
+ [(set_attr "op_type" "RXE")
+ (set_attr "atype" "mem")])
+
+;
+; zero_extendhisi2 instruction pattern(s).
+;
+
+(define_expand "zero_extendhisi2"
+ [(set (match_operand:SI 0 "register_operand" "")
+ (zero_extend:SI (match_operand:HI 1 "register_operand" "")))]
+ ""
+ "
+{
+ operands[1] = gen_lowpart (SImode, operands[1]);
+ emit_insn (gen_andsi3 (operands[0], operands[1], GEN_INT (0xffff)));
+ DONE;
+}
+")
+
+(define_insn "*zero_extendhisi2_64"
+ [(set (match_operand:SI 0 "register_operand" "=d")
+ (zero_extend:SI (match_operand:HI 1 "memory_operand" "m")))]
+ "TARGET_64BIT"
+ "llgh\\t%0,%1"
+ [(set_attr "op_type" "RXE")
+ (set_attr "atype" "mem")])
+
+;
+; zero_extendqisi2 instruction pattern(s).
+;
+
+(define_expand "zero_extendqisi2"
+ [(set (match_operand:SI 0 "register_operand" "")
+ (zero_extend:SI (match_operand:QI 1 "register_operand" "")))]
+ ""
+ "
+{
+ operands[1] = gen_lowpart (SImode, operands[1]);
+ emit_insn (gen_andsi3 (operands[0], operands[1], GEN_INT (0xff)));
+ DONE;
+}
+")
+
+(define_insn "*zero_extendqisi2_64"
+ [(set (match_operand:SI 0 "register_operand" "=d")
+ (zero_extend:SI (match_operand:QI 1 "memory_operand" "m")))]
+ "TARGET_64BIT"
+ "llgc\\t%0,%1"
+ [(set_attr "op_type" "RXE")
+ (set_attr "atype" "mem")])
+
+;
+; zero_extendqihi2 instruction pattern(s).
+;
+
+(define_expand "zero_extendqihi2"
+ [(set (match_operand:HI 0 "register_operand" "")
+ (zero_extend:HI (match_operand:QI 1 "register_operand" "")))]
+ "TARGET_64BIT"
+ "
+{
+ operands[1] = gen_lowpart (HImode, operands[1]);
+ emit_insn (gen_andhi3 (operands[0], operands[1], GEN_INT (0xff)));
+ DONE;
+}
+")
+
+(define_insn "*zero_extendqihi2_64"
+ [(set (match_operand:HI 0 "register_operand" "=d")
+ (zero_extend:HI (match_operand:QI 1 "memory_operand" "m")))
+ (clobber (reg:CC 33))]
+ "TARGET_64BIT"
+ "llgc\\t%0,%1"
+ [(set_attr "op_type" "RXE")
+ (set_attr "atype" "mem")])
+
+;
+; 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],
+ CONST_DOUBLE_FROM_REAL_VALUE (
+ REAL_VALUE_ATOF (\"9223372036854775808.0\", DFmode), DFmode)));
+ emit_jump_insn (gen_blt (label1));
+ emit_insn (gen_subdf3 (temp, operands[1],
+ CONST_DOUBLE_FROM_REAL_VALUE (
+ REAL_VALUE_ATOF (\"18446744073709551616.0\", DFmode), DFmode)));
+ emit_insn (gen_fix_truncdfdi2_ieee (operands[0], temp, GEN_INT(7)));
+ emit_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 "type" "other")])
+
+;
+; 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],
+ CONST_DOUBLE_FROM_REAL_VALUE (
+ REAL_VALUE_ATOF (\"2147483648.0\", DFmode), DFmode)));
+ emit_jump_insn (gen_blt (label1));
+ emit_insn (gen_subdf3 (temp, operands[1],
+ CONST_DOUBLE_FROM_REAL_VALUE (
+ REAL_VALUE_ATOF (\"4294967296.0\", DFmode), DFmode)));
+ emit_insn (gen_fix_truncdfsi2_ieee (operands[0], temp, GEN_INT (7)));
+ emit_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 = s390_gen_rtx_const_DI (0x4f000000, 0x08000000);
+ rtx two32 = s390_gen_rtx_const_DI (0x4e000001, 0x00000000);
+
+ 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 "type" "other" )])
+
+(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:DI 2 "immediate_operand" "m"))
+ (use (match_operand:DI 3 "immediate_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 "type" "other")
+ (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],
+ CONST_DOUBLE_FROM_REAL_VALUE (
+ REAL_VALUE_ATOF (\"9223372036854775808.0\", SFmode), SFmode)));
+ emit_jump_insn (gen_blt (label1));
+
+ emit_insn (gen_subsf3 (temp, operands[1],
+ CONST_DOUBLE_FROM_REAL_VALUE (
+ REAL_VALUE_ATOF (\"18446744073709551616.0\", SFmode), SFmode)));
+ emit_insn (gen_fix_truncsfdi2_ieee (operands[0], temp, GEN_INT(7)));
+ emit_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 "type" "other")])
+
+;
+; 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],
+ CONST_DOUBLE_FROM_REAL_VALUE (
+ REAL_VALUE_ATOF (\"2147483648.0\", SFmode), SFmode)));
+ emit_jump_insn (gen_blt (label1));
+ emit_insn (gen_subsf3 (temp, operands[1],
+ CONST_DOUBLE_FROM_REAL_VALUE (
+ REAL_VALUE_ATOF (\"4294967296.0\", SFmode), SFmode)));
+ emit_insn (gen_fix_truncsfsi2_ieee (operands[0], temp, GEN_INT (7)));
+ emit_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 "type" "other")])
+
+;
+; floatdidf2 instruction pattern(s).
+;
+
+(define_insn "floatdidf2"
+ [(set (match_operand:DF 0 "register_operand" "=f")
+ (float:DF (match_operand:DI 1 "register_operand" "d")))
+ (clobber (reg:CC 33))]
+ "TARGET_64BIT && TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT"
+ "cdgbr\\t%0,%1"
+ [(set_attr "op_type" "RRE")
+ (set_attr "type" "other" )])
+
+;
+; floatdisf2 instruction pattern(s).
+;
+
+(define_insn "floatdisf2"
+ [(set (match_operand:SF 0 "register_operand" "=f")
+ (float:SF (match_operand:DI 1 "register_operand" "d")))
+ (clobber (reg:CC 33))]
+ "TARGET_64BIT && TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT"
+ "cegbr\\t%0,%1"
+ [(set_attr "op_type" "RRE")
+ (set_attr "type" "other" )])
+
+;
+; floatsidf2 instruction pattern(s).
+;
+
+(define_expand "floatsidf2"
+ [(parallel
+ [(set (match_operand:DF 0 "register_operand" "")
+ (float:DF (match_operand:SI 1 "register_operand" "")))
+ (clobber (reg:CC 33))])]
+ "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 = s390_gen_rtx_const_DI (0x4e000000, 0x80000000);
+
+ 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")))
+ (clobber (reg:CC 33))]
+ "TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT"
+ "cdfbr\\t%0,%1"
+ [(set_attr "op_type" "RRE")
+ (set_attr "type" "other" )])
+
+(define_insn "floatsidf2_ibm"
+ [(set (match_operand:DF 0 "register_operand" "=f")
+ (float:DF (match_operand:SI 1 "register_operand" "d")))
+ (use (match_operand:DI 2 "immediate_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%1,%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 "type" "other" )
+ (set_attr "length" "20")])
+
+;
+; floatsisf2 instruction pattern(s).
+;
+
+(define_expand "floatsisf2"
+ [(parallel
+ [(set (match_operand:SF 0 "register_operand" "")
+ (float:SF (match_operand:SI 1 "register_operand" "")))
+ (clobber (reg:CC 33))])]
+ "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")))
+ (clobber (reg:CC 33))]
+ "TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT"
+ "cefbr\\t%0,%1"
+ [(set_attr "op_type" "RRE")
+ (set_attr "type" "other" )])
+
+;
+; 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"
+ "")
+
+(define_insn "truncdfsf2_ieee"
+ [(set (match_operand:SF 0 "register_operand" "=f")
+ (float_truncate:SF (match_operand:DF 1 "general_operand" "f")))]
+ "TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT"
+ "ledbr\\t%0,%1"
+ [(set_attr "op_type" "RRE")])
+
+(define_insn "truncdfsf2_ibm"
+ [(set (match_operand:SF 0 "register_operand" "=f,f")
+ (float_truncate:SF (match_operand:DF 1 "general_operand" "f,m")))]
+ "TARGET_HARD_FLOAT && TARGET_IBM_FLOAT"
+ "@
+ lrer\\t%0,%1
+ le\\t%0,%1"
+ [(set_attr "op_type" "RR,RX")
+ (set_attr "atype" "reg,mem")])
+
+;
+; 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")
+ (set_attr "atype" "reg,mem")
+ (set_attr "type" "o2,o2")])
+
+
+;;
+;; 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")])
+
+(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;
+
+ default:
+ abort ();
+ }
+
+ 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 "type" "o2,o2")
+ (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 "*la_64"
+ [(set (match_operand:DI 0 "register_operand" "=d")
+ (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_expand "reload_indi"
+ [(parallel [(match_operand:DI 0 "register_operand" "=a")
+ (match_operand:DI 1 "s390_plus_operand" "")
+ (match_operand:TI 2 "register_operand" "=&a")])]
+ "TARGET_64BIT"
+ "
+{
+ s390_expand_plus_operand (operands[0], operands[1], operands[2]);
+ DONE;
+}")
+
+
+;
+; addsi3 instruction pattern(s).
+;
+
+(define_insn "*la_ccclobber"
+ [(set (match_operand:SI 0 "register_operand" "=d")
+ (match_operand:QI 1 "address_operand" "p"))
+ (clobber (reg:CC 33))]
+ "legitimate_la_operand_p (operands[1])"
+ "la\\t%0,%a1"
+ [(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")
+ (match_operand:SI 2 "nonimmediate_operand" "d,m"))
+ (const_int 0)))
+ (set (match_operand:SI 0 "register_operand" "=d,d")
+ (plus:SI (match_dup 1) (match_dup 2)))]
+ "s390_match_ccmode(insn, CCLmode)"
+ "@
+ alr\\t%0,%2
+ al\\t%0,%2"
+ [(set_attr "op_type" "RR,RX")
+ (set_attr "atype" "reg,mem")])
+
+(define_insn "*addsi3_cconly"
+ [(set (reg 33)
+ (compare (plus: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, CCLmode)"
+ "@
+ alr\\t%0,%2
+ al\\t%0,%2"
+ [(set_attr "op_type" "RR,RX")
+ (set_attr "atype" "reg,mem")])
+
+(define_insn "*addsi3_cconly2"
+ [(set (reg 33)
+ (compare (match_operand:SI 1 "register_operand" "%0,0")
+ (neg:SI (match_operand:SI 2 "general_operand" "d,m"))))
+ (clobber (match_scratch:SI 0 "=d,d"))]
+ "s390_match_ccmode(insn, CCLmode)"
+ "@
+ alr\\t%0,%2
+ al\\t%0,%2"
+ [(set_attr "op_type" "RR,RX")
+ (set_attr "atype" "reg,mem")])
+
+(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")])
+
+(define_insn "*addsi3_inv"
+ [(set (match_operand:SI 0 "register_operand" "=d,d,d")
+ (plus:SI (match_operand:SI 1 "general_operand" "%d,K,m")
+ (match_operand:SI 2 "register_operand" "0,0,0")))
+ (clobber (reg:CC 33))]
+ ""
+ "@
+ ar\\t%0,%1
+ ahi\\t%0,%h1
+ a\\t%0,%1"
+ [(set_attr "op_type" "RR,RI,RX")
+ (set_attr "atype" "reg,reg,mem")])
+
+(define_insn "*la_31"
+ [(set (match_operand:SI 0 "register_operand" "=d")
+ (match_operand:QI 1 "address_operand" "p"))]
+ "legitimate_la_operand_p (operands[1])"
+ "la\\t%0,%a1"
+ [(set_attr "op_type" "RX")
+ (set_attr "atype" "mem")
+ (set_attr "type" "la")])
+
+(define_expand "reload_insi"
+ [(parallel [(match_operand:SI 0 "register_operand" "=a")
+ (match_operand:SI 1 "s390_plus_operand" "")
+ (match_operand:DI 2 "register_operand" "=&a")])]
+ "!TARGET_64BIT"
+ "
+{
+ s390_expand_plus_operand (operands[0], operands[1], operands[2]);
+ DONE;
+}")
+
+
+;
+; 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 "general_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 "general_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" "RRE,RXE")
+ (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 "general_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 "general_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 "general_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" "RRE,RXE")
+ (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 "general_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")])
+
+(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 "general_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;
+
+ default:
+ abort ();
+ }
+
+ 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 "type" "other,other")
+ (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, CCLmode)"
+ "@
+ slr\\t%0,%2
+ sl\\t%0,%2"
+ [(set_attr "op_type" "RR,RX")
+ (set_attr "atype" "reg,mem")])
+
+(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, CCLmode)"
+ "@
+ slr\\t%0,%2
+ sl\\t%0,%2"
+ [(set_attr "op_type" "RR,RX")
+ (set_attr "atype" "reg,mem")])
+
+(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")])
+
+;
+; subhi3 instruction pattern(s).
+;
+
+(define_insn "subhi3"
+ [(set (match_operand:HI 0 "register_operand" "=d,d")
+ (minus:HI (match_operand:HI 1 "register_operand" "0,0")
+ (match_operand:HI 2 "general_operand" "d,m")))
+ (clobber (reg:CC 33))]
+ ""
+ "@
+ sr\\t%0,%2
+ sh\\t%0,%2"
+ [(set_attr "op_type" "RR,RX")
+ (set_attr "atype" "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 "general_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 "general_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" "RRE,RXE")
+ (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 "general_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 "general_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 "general_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" "RRE,RXE")
+ (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 "general_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.
+;;
+
+;
+; muldi3 instruction pattern(s).
+;
+
+(define_insn "muldi3"
+ [(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 "atype" "reg,reg,mem")
+ (set_attr "type" "imul")])
+
+;
+; 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 "atype" "reg,reg,mem")
+ (set_attr "type" "imul")])
+
+;
+; mulsidi3 instruction pattern(s).
+;
+
+(define_expand "mulsidi3"
+ [(set (match_operand:DI 0 "register_operand" "")
+ (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" ""))
+ (sign_extend:DI (match_operand:SI 2 "nonimmediate_operand" ""))))]
+ "!TARGET_64BIT"
+ "
+{
+ rtx insn;
+
+ emit_insn (gen_zero_extendsidi2 (operands[0], operands[1]));
+ insn = emit_insn (gen_mulsi_6432 (operands[0], operands[0], operands[2]));
+
+ REG_NOTES (insn) =
+ gen_rtx_EXPR_LIST (REG_EQUAL,
+ gen_rtx_MULT (DImode,
+ gen_rtx_SIGN_EXTEND (DImode, operands[1]),
+ gen_rtx_SIGN_EXTEND (DImode, operands[2])),
+ REG_NOTES (insn));
+ DONE;
+}")
+
+(define_insn "mulsi_6432"
+ [(set (match_operand:DI 0 "register_operand" "=d,d")
+ (mult:DI (sign_extend:DI
+ (truncate:SI (match_operand:DI 1 "register_operand" "0,0")))
+ (sign_extend:DI
+ (match_operand:SI 2 "nonimmediate_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 "atype" "reg,mem")
+ (set_attr "type" "imul")])
+
+;
+; 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 "general_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 "general_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" "RRE,RXE")
+ (set_attr "type" "fmul")
+ (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 "general_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 "type" "fmul")
+ (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 "general_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 "general_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" "RRE,RXE")
+ (set_attr "type" "fmul")
+ (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 "general_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 "type" "fmul")
+ (set_attr "atype" "reg,mem")])
+
+
+;;
+;;- Divide and modulo instructions.
+;;
+
+;
+; divmoddi4 instruction pattern(s).
+;
+
+(define_expand "divmoddi4"
+ [(parallel [(set (match_operand:DI 0 "general_operand" "")
+ (div:DI (match_operand:DI 1 "general_operand" "")
+ (match_operand:DI 2 "general_operand" "")))
+ (set (match_operand:DI 3 "general_operand" "")
+ (mod:DI (match_dup 1) (match_dup 2)))])
+ (clobber (match_dup 4))]
+ "TARGET_64BIT"
+ "
+{
+ rtx insn, div_equal, mod_equal, equal;
+
+ div_equal = gen_rtx_DIV (DImode, operands[1], operands[2]);
+ mod_equal = gen_rtx_MOD (DImode, operands[1], operands[2]);
+ equal = gen_rtx_IOR (TImode,
+ gen_rtx_ZERO_EXTEND (TImode, div_equal),
+ gen_rtx_ASHIFT (TImode,
+ gen_rtx_ZERO_EXTEND (TImode, mod_equal),
+ GEN_INT (64)));
+
+ operands[4] = gen_reg_rtx(TImode);
+ emit_insn (gen_rtx_CLOBBER (VOIDmode, operands[4]));
+ emit_move_insn (gen_lowpart (DImode, operands[4]), operands[1]);
+ emit_move_insn (gen_highpart (DImode, operands[4]), const0_rtx);
+ insn = emit_insn (gen_divmodtidi3 (operands[4], operands[4], operands[2]));
+ REG_NOTES (insn) =
+ gen_rtx_EXPR_LIST (REG_EQUAL, equal, REG_NOTES (insn));
+
+ insn = emit_move_insn (operands[0], gen_lowpart (DImode, operands[4]));
+ REG_NOTES (insn) =
+ gen_rtx_EXPR_LIST (REG_EQUAL, div_equal, REG_NOTES (insn));
+
+ insn = emit_move_insn (operands[3], gen_highpart (DImode, operands[4]));
+ REG_NOTES (insn) =
+ gen_rtx_EXPR_LIST (REG_EQUAL, mod_equal, REG_NOTES (insn));
+
+ DONE;
+}")
+
+(define_insn "divmodtidi3"
+ [(set (match_operand:TI 0 "register_operand" "=d,d")
+ (ior:TI
+ (zero_extend:TI
+ (div:DI (truncate:DI (match_operand:TI 1 "register_operand" "0,0"))
+ (match_operand:DI 2 "general_operand" "d,m")))
+ (ashift:TI
+ (zero_extend:TI
+ (mod:DI (truncate:DI (match_dup 1))
+ (match_dup 2)))
+ (const_int 64))))]
+ "TARGET_64BIT"
+ "@
+ dsgr\\t%0,%2
+ dsg\\t%0,%2"
+ [(set_attr "op_type" "RRE,RXE")
+ (set_attr "type" "idiv")
+ (set_attr "atype" "reg,mem")])
+
+(define_insn "divmodtisi3"
+ [(set (match_operand:TI 0 "register_operand" "=d,d")
+ (ior:TI
+ (zero_extend:TI
+ (div:DI (truncate:DI (match_operand:TI 1 "register_operand" "0,0"))
+ (sign_extend:DI (match_operand:SI 2 "nonimmediate_operand" "d,m"))))
+ (ashift:TI
+ (zero_extend:TI
+ (mod:DI (truncate:DI (match_dup 1))
+ (sign_extend:DI (match_dup 2))))
+ (const_int 64))))]
+ "TARGET_64BIT"
+ "@
+ dsgfr\\t%0,%2
+ dsgf\\t%0,%2"
+ [(set_attr "op_type" "RRE,RXE")
+ (set_attr "type" "idiv")
+ (set_attr "atype" "reg,mem")])
+
+;
+; udivmoddi4 instruction pattern(s).
+;
+
+(define_expand "udivmoddi4"
+ [(parallel [(set (match_operand:DI 0 "general_operand" "")
+ (udiv:DI (match_operand:DI 1 "general_operand" "")
+ (match_operand:DI 2 "nonimmediate_operand" "")))
+ (set (match_operand:DI 3 "general_operand" "")
+ (umod:DI (match_dup 1) (match_dup 2)))])
+ (clobber (match_dup 4))]
+ "TARGET_64BIT"
+ "
+{
+ rtx insn, div_equal, mod_equal, equal;
+
+ div_equal = gen_rtx_UDIV (DImode, operands[1], operands[2]);
+ mod_equal = gen_rtx_UMOD (DImode, operands[1], operands[2]);
+ equal = gen_rtx_IOR (TImode,
+ gen_rtx_ZERO_EXTEND (TImode, div_equal),
+ gen_rtx_ASHIFT (TImode,
+ gen_rtx_ZERO_EXTEND (TImode, mod_equal),
+ GEN_INT (64)));
+
+ operands[4] = gen_reg_rtx(TImode);
+ emit_insn (gen_rtx_CLOBBER (VOIDmode, operands[4]));
+ emit_move_insn (gen_lowpart (DImode, operands[4]), operands[1]);
+ emit_move_insn (gen_highpart (DImode, operands[4]), const0_rtx);
+ insn = emit_insn (gen_udivmodtidi3 (operands[4], operands[4], operands[2]));
+ REG_NOTES (insn) =
+ gen_rtx_EXPR_LIST (REG_EQUAL, equal, REG_NOTES (insn));
+
+ insn = emit_move_insn (operands[0], gen_lowpart (DImode, operands[4]));
+ REG_NOTES (insn) =
+ gen_rtx_EXPR_LIST (REG_EQUAL, div_equal, REG_NOTES (insn));
+
+ insn = emit_move_insn (operands[3], gen_highpart (DImode, operands[4]));
+ REG_NOTES (insn) =
+ gen_rtx_EXPR_LIST (REG_EQUAL, mod_equal, REG_NOTES (insn));
+
+ DONE;
+}")
+
+(define_insn "udivmodtidi3"
+ [(set (match_operand:TI 0 "register_operand" "=d,d")
+ (ior:TI (zero_extend:TI
+ (truncate:DI
+ (udiv:TI (match_operand:TI 1 "register_operand" "0,0")
+ (zero_extend:TI
+ (match_operand:DI 2 "nonimmediate_operand" "d,m")))))
+ (ashift:TI
+ (zero_extend:TI
+ (truncate:DI
+ (umod:TI (match_dup 1) (zero_extend:TI (match_dup 2)))))
+ (const_int 64))))]
+ "TARGET_64BIT"
+ "@
+ dlgr\\t%0,%2
+ dlg\\t%0,%2"
+ [(set_attr "op_type" "RRE,RXE")
+ (set_attr "type" "idiv")
+ (set_attr "atype" "reg,mem")])
+
+;
+; divmodsi4 instruction pattern(s).
+;
+
+(define_expand "divmodsi4"
+ [(parallel [(set (match_operand:SI 0 "general_operand" "")
+ (div:SI (match_operand:SI 1 "general_operand" "")
+ (match_operand:SI 2 "nonimmediate_operand" "")))
+ (set (match_operand:SI 3 "general_operand" "")
+ (mod:SI (match_dup 1) (match_dup 2)))])
+ (clobber (match_dup 4))]
+ "!TARGET_64BIT"
+ "
+{
+ rtx insn, div_equal, mod_equal, equal;
+
+ div_equal = gen_rtx_DIV (SImode, operands[1], operands[2]);
+ mod_equal = gen_rtx_MOD (SImode, operands[1], operands[2]);
+ equal = gen_rtx_IOR (DImode,
+ gen_rtx_ZERO_EXTEND (DImode, div_equal),
+ gen_rtx_ASHIFT (DImode,
+ gen_rtx_ZERO_EXTEND (DImode, mod_equal),
+ GEN_INT (32)));
+
+ operands[4] = gen_reg_rtx(DImode);
+ emit_insn (gen_extendsidi2 (operands[4], operands[1]));
+ insn = emit_insn (gen_divmoddisi3 (operands[4], operands[4], operands[2]));
+ REG_NOTES (insn) =
+ gen_rtx_EXPR_LIST (REG_EQUAL, equal, REG_NOTES (insn));
+
+ insn = emit_move_insn (operands[0], gen_lowpart (SImode, operands[4]));
+ REG_NOTES (insn) =
+ gen_rtx_EXPR_LIST (REG_EQUAL, div_equal, REG_NOTES (insn));
+
+ insn = emit_move_insn (operands[3], gen_highpart (SImode, operands[4]));
+ REG_NOTES (insn) =
+ gen_rtx_EXPR_LIST (REG_EQUAL, mod_equal, REG_NOTES (insn));
+
+ DONE;
+}")
+
+(define_insn "divmoddisi3"
+ [(set (match_operand:DI 0 "register_operand" "=d,d")
+ (ior:DI (zero_extend:DI
+ (truncate:SI
+ (div:DI (match_operand:DI 1 "register_operand" "0,0")
+ (sign_extend:DI
+ (match_operand:SI 2 "nonimmediate_operand" "d,m")))))
+ (ashift:DI
+ (zero_extend:DI
+ (truncate:SI
+ (mod:DI (match_dup 1) (sign_extend:SI (match_dup 2)))))
+ (const_int 32))))]
+ "!TARGET_64BIT"
+ "@
+ dr\\t%0,%2
+ d\\t%0,%2"
+ [(set_attr "op_type" "RR,RX")
+ (set_attr "type" "idiv")
+ (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" "")))
+ (clobber (match_dup 3))]
+ "!TARGET_64BIT"
+ "
+{
+ rtx insn, udiv_equal, umod_equal, equal;
+
+ udiv_equal = gen_rtx_UDIV (SImode, operands[1], operands[2]);
+ umod_equal = gen_rtx_UMOD (SImode, operands[1], operands[2]);
+ equal = gen_rtx_IOR (DImode,
+ gen_rtx_ZERO_EXTEND (DImode, udiv_equal),
+ gen_rtx_ASHIFT (DImode,
+ gen_rtx_ZERO_EXTEND (DImode, umod_equal),
+ GEN_INT (32)));
+
+ operands[3] = gen_reg_rtx (DImode);
+
+ if (CONSTANT_P (operands[2]))
+ {
+ if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0)
+ {
+ rtx label1 = gen_label_rtx ();
+
+ operands[1] = make_safe_from (operands[1], operands[0]);
+ emit_move_insn (operands[0], const0_rtx);
+ emit_insn (gen_cmpsi (operands[1], operands[2]));
+ emit_jump_insn (gen_bltu (label1));
+ emit_move_insn (operands[0], const1_rtx);
+ emit_label (label1);
+ }
+ else
+ {
+ operands[2] = force_reg (SImode, operands[2]);
+ operands[2] = make_safe_from (operands[2], operands[0]);
+
+ emit_insn (gen_zero_extendsidi2 (operands[3], operands[1]));
+ insn = emit_insn (gen_divmoddisi3 (operands[3], operands[3],
+ operands[2]));
+ REG_NOTES (insn) =
+ gen_rtx_EXPR_LIST (REG_EQUAL, equal, REG_NOTES (insn));
+
+ insn = emit_move_insn (operands[0],
+ gen_lowpart (SImode, operands[3]));
+ REG_NOTES (insn) =
+ gen_rtx_EXPR_LIST (REG_EQUAL,
+ udiv_equal, REG_NOTES (insn));
+ }
+ }
+ else
+ {
+ rtx label1 = gen_label_rtx ();
+ rtx label2 = gen_label_rtx ();
+ rtx label3 = gen_label_rtx ();
+
+ operands[1] = force_reg (SImode, operands[1]);
+ operands[1] = make_safe_from (operands[1], operands[0]);
+ operands[2] = force_reg (SImode, operands[2]);
+ operands[2] = make_safe_from (operands[2], operands[0]);
+
+ emit_move_insn (operands[0], 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_insn (gen_zero_extendsidi2 (operands[3], operands[1]));
+ insn = emit_insn (gen_divmoddisi3 (operands[3], operands[3],
+ operands[2]));
+ REG_NOTES (insn) =
+ gen_rtx_EXPR_LIST (REG_EQUAL, equal, REG_NOTES (insn));
+
+ insn = emit_move_insn (operands[0],
+ gen_lowpart (SImode, operands[3]));
+ REG_NOTES (insn) =
+ gen_rtx_EXPR_LIST (REG_EQUAL,
+ udiv_equal, REG_NOTES (insn));
+ emit_jump (label3);
+ emit_label (label1);
+ emit_move_insn (operands[0], operands[1]);
+ emit_jump (label3);
+ emit_label (label2);
+ emit_move_insn (operands[0], const1_rtx);
+ emit_label (label3);
+ }
+ emit_move_insn (operands[0], operands[0]);
+ 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" "")))
+ (clobber (match_dup 3))]
+ "!TARGET_64BIT"
+ "
+{
+ rtx insn, udiv_equal, umod_equal, equal;
+
+ udiv_equal = gen_rtx_UDIV (SImode, operands[1], operands[2]);
+ umod_equal = gen_rtx_UMOD (SImode, operands[1], operands[2]);
+ equal = gen_rtx_IOR (DImode,
+ gen_rtx_ZERO_EXTEND (DImode, udiv_equal),
+ gen_rtx_ASHIFT (DImode,
+ gen_rtx_ZERO_EXTEND (DImode, umod_equal),
+ GEN_INT (32)));
+
+ operands[3] = gen_reg_rtx (DImode);
+
+ if (CONSTANT_P (operands[2]))
+ {
+ if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) <= 0)
+ {
+ rtx label1 = gen_label_rtx ();
+
+ operands[1] = make_safe_from (operands[1], operands[0]);
+ emit_move_insn (operands[0], operands[1]);
+ emit_insn (gen_cmpsi (operands[0], operands[2]));
+ emit_jump_insn (gen_bltu (label1));
+ emit_insn (gen_abssi2 (operands[0], operands[2]));
+ emit_insn (gen_addsi3 (operands[0], operands[0], operands[1]));
+ emit_label (label1);
+ }
+ else
+ {
+ operands[2] = force_reg (SImode, operands[2]);
+ operands[2] = make_safe_from (operands[2], operands[0]);
+
+ emit_insn (gen_zero_extendsidi2 (operands[3], operands[1]));
+ insn = emit_insn (gen_divmoddisi3 (operands[3], operands[3],
+ operands[2]));
+ REG_NOTES (insn) =
+ gen_rtx_EXPR_LIST (REG_EQUAL, equal, REG_NOTES (insn));
+
+ insn = emit_move_insn (operands[0],
+ gen_highpart (SImode, operands[3]));
+ REG_NOTES (insn) =
+ gen_rtx_EXPR_LIST (REG_EQUAL,
+ umod_equal, REG_NOTES (insn));
+ }
+ }
+ else
+ {
+ rtx label1 = gen_label_rtx ();
+ rtx label2 = gen_label_rtx ();
+ rtx label3 = gen_label_rtx ();
+
+ operands[1] = force_reg (SImode, operands[1]);
+ operands[1] = make_safe_from (operands[1], operands[0]);
+ operands[2] = force_reg (SImode, operands[2]);
+ operands[2] = make_safe_from (operands[2], operands[0]);
+
+ emit_move_insn(operands[0], operands[1]);
+ 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_insn (gen_zero_extendsidi2 (operands[3], operands[1]));
+ insn = emit_insn (gen_divmoddisi3 (operands[3], operands[3],
+ operands[2]));
+ REG_NOTES (insn) =
+ gen_rtx_EXPR_LIST (REG_EQUAL, equal, REG_NOTES (insn));
+
+ insn = emit_move_insn (operands[0],
+ gen_highpart (SImode, operands[3]));
+ REG_NOTES (insn) =
+ gen_rtx_EXPR_LIST (REG_EQUAL,
+ umod_equal, REG_NOTES (insn));
+ emit_jump (label3);
+ emit_label (label1);
+ emit_move_insn (operands[0], const0_rtx);
+ emit_jump (label3);
+ emit_label (label2);
+ emit_insn (gen_subsi3 (operands[0], operands[0], operands[2]));
+ emit_label (label3);
+ }
+ DONE;
+}")
+
+;
+; divdf3 instruction pattern(s).
+;
+
+(define_expand "divdf3"
+ [(parallel
+ [(set (match_operand:DF 0 "register_operand" "=f,f")
+ (div:DF (match_operand:DF 1 "register_operand" "0,0")
+ (match_operand:DF 2 "general_operand" "f,m")))
+ (clobber (reg:CC 33))])]
+ "TARGET_HARD_FLOAT"
+ "")
+
+(define_insn "*divdf3"
+ [(set (match_operand:DF 0 "register_operand" "=f,f")
+ (div:DF (match_operand:DF 1 "register_operand" "0,0")
+ (match_operand:DF 2 "general_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" "RRE,RXE")
+ (set_attr "type" "fdiv")
+ (set_attr "atype" "reg,mem")])
+
+(define_insn "*divdf3_ibm"
+ [(set (match_operand:DF 0 "register_operand" "=f,f")
+ (div:DF (match_operand:DF 1 "register_operand" "0,0")
+ (match_operand:DF 2 "general_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 "type" "fdiv")
+ (set_attr "atype" "reg,mem")])
+
+;
+; divsf3 instruction pattern(s).
+;
+
+(define_expand "divsf3"
+ [(parallel
+ [(set (match_operand:SF 0 "register_operand" "=f,f")
+ (div:SF (match_operand:SF 1 "register_operand" "0,0")
+ (match_operand:SF 2 "general_operand" "f,m")))
+ (clobber (reg:CC 33))])]
+ "TARGET_HARD_FLOAT"
+ "")
+
+(define_insn "*divsf3"
+ [(set (match_operand:SF 0 "register_operand" "=f,f")
+ (div:SF (match_operand:SF 1 "register_operand" "0,0")
+ (match_operand:SF 2 "general_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" "RRE,RXE")
+ (set_attr "type" "fdiv")
+ (set_attr "atype" "reg,mem")])
+
+(define_insn "*divsf3"
+ [(set (match_operand:SF 0 "register_operand" "=f,f")
+ (div:SF (match_operand:SF 1 "register_operand" "0,0")
+ (match_operand:SF 2 "general_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 "type" "fdiv")
+ (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 "register_operand" "%0,0")
+ (match_operand:DI 2 "general_operand" "d,m"))
+ (const_int 0)))
+ (set (match_operand:DI 0 "register_operand" "=d,d")
+ (and:DI (match_dup 1) (match_dup 2)))]
+ "s390_match_ccmode(insn, CCTmode) && TARGET_64BIT"
+ "@
+ ngr\\t%0,%2
+ ng\\t%0,%2"
+ [(set_attr "op_type" "RRE,RXE")
+ (set_attr "atype" "reg,mem")])
+
+(define_insn "*anddi3_cconly"
+ [(set (reg 33)
+ (compare (and:DI (match_operand:DI 1 "register_operand" "%0,0")
+ (match_operand:DI 2 "general_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" "RRE,RXE")
+ (set_attr "atype" "reg,mem")])
+
+(define_insn "*anddi3_ni"
+ [(set (match_operand:DI 0 "register_operand" "=d")
+ (and:DI (match_operand:DI 1 "register_operand" "%0")
+ (match_operand:DI 2 "immediate_operand" "n")))
+ (clobber (reg:CC 33))]
+ "TARGET_64BIT && s390_single_hi (operands[2], DImode, -1) >= 0"
+ "*
+{
+ int part = s390_single_hi (operands[2], DImode, -1);
+ operands[2] = GEN_INT (s390_extract_hi (operands[2], DImode, part));
+
+ switch (part)
+ {
+ case 0: return \"nihh\\t%0,%x2\";
+ case 1: return \"nihl\\t%0,%x2\";
+ case 2: return \"nilh\\t%0,%x2\";
+ case 3: return \"nill\\t%0,%x2\";
+ default: abort ();
+ }
+}"
+ [(set_attr "op_type" "RI")
+ (set_attr "atype" "reg")])
+
+(define_insn "anddi3"
+ [(set (match_operand:DI 0 "register_operand" "=d,d")
+ (and:DI (match_operand:DI 1 "register_operand" "%0,0")
+ (match_operand:DI 2 "general_operand" "d,m")))
+ (clobber (reg:CC 33))]
+ "TARGET_64BIT"
+ "@
+ ngr\\t%0,%2
+ ng\\t%0,%2"
+ [(set_attr "op_type" "RRE,RXE")
+ (set_attr "atype" "reg,mem")])
+
+(define_insn "*anddi3_ss"
+ [(set (match_operand:DI 0 "s_operand" "=Qo")
+ (and:DI (match_dup 0)
+ (match_operand:DI 1 "s_imm_operand" "Qo")))
+ (clobber (reg:CC 33))]
+ ""
+ "nc\\t%O0(8,%R0),%1"
+ [(set_attr "op_type" "SS")
+ (set_attr "atype" "mem")])
+
+(define_insn "*anddi3_ss_inv"
+ [(set (match_operand:DI 0 "s_operand" "=Qo")
+ (and:DI (match_operand:DI 1 "s_imm_operand" "Qo")
+ (match_dup 0)))
+ (clobber (reg:CC 33))]
+ ""
+ "nc\\t%O0(8,%R0),%1"
+ [(set_attr "op_type" "SS")
+ (set_attr "atype" "mem")])
+
+;
+; andsi3 instruction pattern(s).
+;
+
+(define_insn "*andsi3_cc"
+ [(set (reg 33)
+ (compare (and: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")
+ (and:SI (match_dup 1) (match_dup 2)))]
+ "s390_match_ccmode(insn, CCTmode)"
+ "@
+ nr\\t%0,%2
+ n\\t%0,%2"
+ [(set_attr "op_type" "RR,RX")
+ (set_attr "atype" "reg,mem")])
+
+(define_insn "*andsi3_cconly"
+ [(set (reg 33)
+ (compare (and: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, CCTmode)"
+ "@
+ nr\\t%0,%2
+ n\\t%0,%2"
+ [(set_attr "op_type" "RR,RX")
+ (set_attr "atype" "reg,mem")])
+
+(define_insn "*andsi3_ni"
+ [(set (match_operand:SI 0 "register_operand" "=d")
+ (and:SI (match_operand:SI 1 "register_operand" "%0")
+ (match_operand:SI 2 "immediate_operand" "n")))
+ (clobber (reg:CC 33))]
+ "TARGET_64BIT && s390_single_hi (operands[2], SImode, -1) >= 0"
+ "*
+{
+ int part = s390_single_hi (operands[2], SImode, -1);
+ operands[2] = GEN_INT (s390_extract_hi (operands[2], SImode, part));
+
+ switch (part)
+ {
+ case 0: return \"nilh\\t%0,%x2\";
+ case 1: return \"nill\\t%0,%x2\";
+ default: abort ();
+ }
+}"
+ [(set_attr "op_type" "RI")
+ (set_attr "atype" "reg")])
+
+(define_insn "andsi3"
+ [(set (match_operand:SI 0 "register_operand" "=d,d")
+ (and:SI (match_operand:SI 1 "register_operand" "%0,0")
+ (match_operand:SI 2 "general_operand" "d,m")))
+ (clobber (reg:CC 33))]
+ ""
+ "@
+ nr\\t%0,%2
+ n\\t%0,%2"
+ [(set_attr "op_type" "RR,RX")
+ (set_attr "atype" "reg,mem")])
+
+(define_insn "*andsi3_ss"
+ [(set (match_operand:SI 0 "s_operand" "=Qo")
+ (and:SI (match_dup 0)
+ (match_operand:SI 1 "s_imm_operand" "Qo")))
+ (clobber (reg:CC 33))]
+ ""
+ "nc\\t%O0(4,%R0),%1"
+ [(set_attr "op_type" "SS")
+ (set_attr "atype" "mem")])
+
+(define_insn "*andsi3_ss_inv"
+ [(set (match_operand:SI 0 "s_operand" "=Qo")
+ (and:SI (match_operand:SI 1 "s_imm_operand" "Qo")
+ (match_dup 0)))
+ (clobber (reg:CC 33))]
+ ""
+ "nc\\t%O0(4,%R0),%1"
+ [(set_attr "op_type" "SS")
+ (set_attr "atype" "mem")])
+
+;
+; andhi3 instruction pattern(s).
+;
+
+(define_insn "*andhi3_ni"
+ [(set (match_operand:HI 0 "register_operand" "=d,d")
+ (and:HI (match_operand:HI 1 "register_operand" "%0,0")
+ (match_operand:HI 2 "nonmemory_operand" "d,n")))
+ (clobber (reg:CC 33))]
+ "TARGET_64BIT"
+ "@
+ nr\\t%0,%2
+ nill\\t%0,%x2"
+ [(set_attr "op_type" "RR,RI")
+ (set_attr "atype" "reg")])
+
+(define_insn "andhi3"
+ [(set (match_operand:HI 0 "register_operand" "=d")
+ (and:HI (match_operand:HI 1 "register_operand" "%0")
+ (match_operand:HI 2 "nonmemory_operand" "d")))
+ (clobber (reg:CC 33))]
+ ""
+ "nr\\t%0,%2"
+ [(set_attr "op_type" "RR")
+ (set_attr "atype" "reg")])
+
+(define_insn "*andhi3_ss"
+ [(set (match_operand:HI 0 "s_operand" "=Qo")
+ (and:HI (match_dup 0)
+ (match_operand:HI 1 "s_imm_operand" "Qo")))
+ (clobber (reg:CC 33))]
+ ""
+ "nc\\t%O0(2,%R0),%1"
+ [(set_attr "op_type" "SS")
+ (set_attr "atype" "mem")])
+
+(define_insn "*andhi3_ss_inv"
+ [(set (match_operand:HI 0 "s_operand" "=Qo")
+ (and:HI (match_operand:HI 1 "s_imm_operand" "Qo")
+ (match_dup 0)))
+ (clobber (reg:CC 33))]
+ ""
+ "nc\\t%O0(2,%R0),%1"
+ [(set_attr "op_type" "SS")
+ (set_attr "atype" "mem")])
+
+;
+; andqi3 instruction pattern(s).
+;
+
+(define_insn "*andqi3_ni"
+ [(set (match_operand:QI 0 "register_operand" "=d,d")
+ (and:QI (match_operand:QI 1 "register_operand" "%0,0")
+ (match_operand:QI 2 "nonmemory_operand" "d,n")))
+ (clobber (reg:CC 33))]
+ "TARGET_64BIT"
+ "@
+ nr\\t%0,%2
+ nill\\t%0,%b2"
+ [(set_attr "op_type" "RR,RI")
+ (set_attr "atype" "reg")])
+
+(define_insn "andqi3"
+ [(set (match_operand:QI 0 "register_operand" "=d")
+ (and:QI (match_operand:QI 1 "register_operand" "%0")
+ (match_operand:QI 2 "nonmemory_operand" "d")))
+ (clobber (reg:CC 33))]
+ ""
+ "nr\\t%0,%2"
+ [(set_attr "op_type" "RR")
+ (set_attr "atype" "reg")])
+
+(define_insn "*andqi3_ss"
+ [(set (match_operand:QI 0 "s_operand" "=Qo,Qo")
+ (and:QI (match_dup 0)
+ (match_operand:QI 1 "s_imm_operand" "n,Qo")))
+ (clobber (reg:CC 33))]
+ ""
+ "@
+ ni\\t%0,%b1
+ nc\\t%O0(1,%R0),%1"
+ [(set_attr "op_type" "SI,SS")
+ (set_attr "atype" "mem")])
+
+(define_insn "*andqi3_ss_inv"
+ [(set (match_operand:QI 0 "s_operand" "=Qo,Qo")
+ (and:QI (match_operand:QI 1 "s_imm_operand" "n,Qo")
+ (match_dup 0)))
+ (clobber (reg:CC 33))]
+ ""
+ "@
+ ni\\t%0,%b1
+ nc\\t%O0(1,%R0),%1"
+ [(set_attr "op_type" "SI,SS")
+ (set_attr "atype" "mem")])
+
+
+;;
+;;- Bit set (inclusive or) instructions.
+;;
+
+;
+; iordi3 instruction pattern(s).
+;
+
+(define_insn "*iordi3_cc"
+ [(set (reg 33)
+ (compare (ior:DI (match_operand:DI 1 "register_operand" "%0,0")
+ (match_operand:DI 2 "general_operand" "d,m"))
+ (const_int 0)))
+ (set (match_operand:DI 0 "register_operand" "=d,d")
+ (ior:DI (match_dup 1) (match_dup 2)))]
+ "s390_match_ccmode(insn, CCTmode) && TARGET_64BIT"
+ "@
+ ogr\\t%0,%2
+ og\\t%0,%2"
+ [(set_attr "op_type" "RRE,RXE")
+ (set_attr "atype" "reg,mem")])
+
+(define_insn "*iordi3_cconly"
+ [(set (reg 33)
+ (compare (ior:DI (match_operand:DI 1 "register_operand" "%0,0")
+ (match_operand:DI 2 "general_operand" "d,m"))
+ (const_int 0)))
+ (clobber (match_scratch:DI 0 "=d,d"))]
+ "s390_match_ccmode(insn, CCTmode) && TARGET_64BIT"
+ "@
+ ogr\\t%0,%2
+ og\\t%0,%2"
+ [(set_attr "op_type" "RRE,RXE")
+ (set_attr "atype" "reg,mem")])
+
+(define_insn "*iordi3_oi"
+ [(set (match_operand:DI 0 "register_operand" "=d")
+ (ior:DI (match_operand:DI 1 "register_operand" "%0")
+ (match_operand:DI 2 "immediate_operand" "n")))
+ (clobber (reg:CC 33))]
+ "TARGET_64BIT && s390_single_hi (operands[2], DImode, 0) >= 0"
+ "*
+{
+ int part = s390_single_hi (operands[2], DImode, 0);
+ operands[2] = GEN_INT (s390_extract_hi (operands[2], DImode, part));
+
+ switch (part)
+ {
+ case 0: return \"oihh\\t%0,%x2\";
+ case 1: return \"oihl\\t%0,%x2\";
+ case 2: return \"oilh\\t%0,%x2\";
+ case 3: return \"oill\\t%0,%x2\";
+ default: abort ();
+ }
+}"
+ [(set_attr "op_type" "RI")
+ (set_attr "atype" "reg")])
+
+(define_insn "iordi3"
+ [(set (match_operand:DI 0 "register_operand" "=d,d")
+ (ior:DI (match_operand:DI 1 "register_operand" "%0,0")
+ (match_operand:DI 2 "general_operand" "d,m")))
+ (clobber (reg:CC 33))]
+ "TARGET_64BIT"
+ "@
+ ogr\\t%0,%2
+ og\\t%0,%2"
+ [(set_attr "op_type" "RRE,RXE")
+ (set_attr "atype" "reg,mem")])
+
+(define_insn "*iordi3_ss"
+ [(set (match_operand:DI 0 "s_operand" "=Qo")
+ (ior:DI (match_dup 0)
+ (match_operand:DI 1 "s_imm_operand" "Qo")))
+ (clobber (reg:CC 33))]
+ ""
+ "oc\\t%O0(8,%R0),%1"
+ [(set_attr "op_type" "SS")
+ (set_attr "atype" "mem")])
+
+(define_insn "*iordi3_ss_inv"
+ [(set (match_operand:DI 0 "s_operand" "=Qo")
+ (ior:DI (match_operand:DI 1 "s_imm_operand" "Qo")
+ (match_dup 0)))
+ (clobber (reg:CC 33))]
+ ""
+ "oc\\t%O0(8,%R0),%1"
+ [(set_attr "op_type" "SS")
+ (set_attr "atype" "mem")])
+
+;
+; iorsi3 instruction pattern(s).
+;
+
+(define_insn "*iorsi3_cc"
+ [(set (reg 33)
+ (compare (ior: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")
+ (ior:SI (match_dup 1) (match_dup 2)))]
+ "s390_match_ccmode(insn, CCTmode)"
+ "@
+ or\\t%0,%2
+ o\\t%0,%2"
+ [(set_attr "op_type" "RR,RX")
+ (set_attr "atype" "reg,mem")])
+
+(define_insn "*iorsi3_cconly"
+ [(set (reg 33)
+ (compare (ior: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, CCTmode)"
+ "@
+ or\\t%0,%2
+ o\\t%0,%2"
+ [(set_attr "op_type" "RR,RX")
+ (set_attr "atype" "reg,mem")])
+
+(define_insn "*iorsi3_oi"
+ [(set (match_operand:SI 0 "register_operand" "=d")
+ (ior:SI (match_operand:SI 1 "register_operand" "%0")
+ (match_operand:SI 2 "immediate_operand" "n")))
+ (clobber (reg:CC 33))]
+ "TARGET_64BIT && s390_single_hi (operands[2], SImode, 0) >= 0"
+ "*
+{
+ int part = s390_single_hi (operands[2], SImode, 0);
+ operands[2] = GEN_INT (s390_extract_hi (operands[2], SImode, part));
+
+ switch (part)
+ {
+ case 0: return \"oilh\\t%0,%x2\";
+ case 1: return \"oill\\t%0,%x2\";
+ default: abort ();
+ }
+}"
+ [(set_attr "op_type" "RI")
+ (set_attr "atype" "reg")])
+
+(define_insn "iorsi3"
+ [(set (match_operand:SI 0 "register_operand" "=d,d")
+ (ior:SI (match_operand:SI 1 "register_operand" "%0,0")
+ (match_operand:SI 2 "general_operand" "d,m")))
+ (clobber (reg:CC 33))]
+ ""
+ "@
+ or\\t%0,%2
+ o\\t%0,%2"
+ [(set_attr "op_type" "RR,RX")
+ (set_attr "atype" "reg,mem")])
+
+(define_insn "*iorsi3_ss"
+ [(set (match_operand:SI 0 "s_operand" "=Qo")
+ (ior:SI (match_dup 0)
+ (match_operand:SI 1 "s_imm_operand" "Qo")))
+ (clobber (reg:CC 33))]
+ ""
+ "oc\\t%O0(4,%R0),%1"
+ [(set_attr "op_type" "SS")
+ (set_attr "atype" "mem")])
+
+(define_insn "*iorsi3_ss_inv"
+ [(set (match_operand:SI 0 "s_operand" "=Qo")
+ (ior:SI (match_operand:SI 1 "s_imm_operand" "Qo")
+ (match_dup 0)))
+ (clobber (reg:CC 33))]
+ ""
+ "oc\\t%O0(4,%R0),%1"
+ [(set_attr "op_type" "SS")
+ (set_attr "atype" "mem")])
+
+;
+; iorhi3 instruction pattern(s).
+;
+
+(define_insn "*iorhi3_oi"
+ [(set (match_operand:HI 0 "register_operand" "=d,d")
+ (ior:HI (match_operand:HI 1 "register_operand" "%0,0")
+ (match_operand:HI 2 "nonmemory_operand" "d,n")))
+ (clobber (reg:CC 33))]
+ "TARGET_64BIT"
+ "@
+ or\\t%0,%2
+ oill\\t%0,%x2"
+ [(set_attr "op_type" "RR,RI")
+ (set_attr "atype" "reg")])
+
+(define_insn "iorhi3"
+ [(set (match_operand:HI 0 "register_operand" "=d")
+ (ior:HI (match_operand:HI 1 "register_operand" "%0")
+ (match_operand:HI 2 "nonmemory_operand" "d")))
+ (clobber (reg:CC 33))]
+ ""
+ "or\\t%0,%2"
+ [(set_attr "op_type" "RR")
+ (set_attr "atype" "reg")])
+
+(define_insn "*iorhi3_ss"
+ [(set (match_operand:HI 0 "s_operand" "=Qo")
+ (ior:HI (match_dup 0)
+ (match_operand:HI 1 "s_imm_operand" "Qo")))
+ (clobber (reg:CC 33))]
+ ""
+ "oc\\t%O0(2,%R0),%1"
+ [(set_attr "op_type" "SS")
+ (set_attr "atype" "mem")])
+
+(define_insn "*iorhi3_ss_inv"
+ [(set (match_operand:HI 0 "s_operand" "=Qo")
+ (ior:HI (match_operand:HI 1 "s_imm_operand" "Qo")
+ (match_dup 0)))
+ (clobber (reg:CC 33))]
+ ""
+ "oc\\t%O0(2,%R0),%1"
+ [(set_attr "op_type" "SS")
+ (set_attr "atype" "mem")])
+
+;
+; iorqi3 instruction pattern(s).
+;
+
+(define_insn "*iorqi3_oi"
+ [(set (match_operand:QI 0 "register_operand" "=d,d")
+ (ior:QI (match_operand:QI 1 "register_operand" "%0,0")
+ (match_operand:QI 2 "nonmemory_operand" "d,n")))
+ (clobber (reg:CC 33))]
+ "TARGET_64BIT"
+ "@
+ or\\t%0,%2
+ oill\\t%0,%b2"
+ [(set_attr "op_type" "RR,RI")
+ (set_attr "atype" "reg")])
+
+(define_insn "iorqi3"
+ [(set (match_operand:QI 0 "register_operand" "=d")
+ (ior:QI (match_operand:QI 1 "register_operand" "%0")
+ (match_operand:QI 2 "nonmemory_operand" "d")))
+ (clobber (reg:CC 33))]
+ ""
+ "or\\t%0,%2"
+ [(set_attr "op_type" "RR")
+ (set_attr "atype" "reg")])
+
+(define_insn "*iorqi3_ss"
+ [(set (match_operand:QI 0 "s_operand" "=Qo,Qo")
+ (ior:QI (match_dup 0)
+ (match_operand:QI 1 "s_imm_operand" "n,Qo")))
+ (clobber (reg:CC 33))]
+ ""
+ "@
+ oi\\t%0,%b1
+ oc\\t%O0(1,%R0),%1"
+ [(set_attr "op_type" "SI,SS")
+ (set_attr "atype" "reg,mem")])
+
+(define_insn "*iorqi3_ss_inv"
+ [(set (match_operand:QI 0 "s_operand" "=Qo,Qo")
+ (ior:QI (match_operand:QI 1 "s_imm_operand" "n,Qo")
+ (match_dup 0)))
+ (clobber (reg:CC 33))]
+ ""
+ "@
+ oi\\t%0,%b1
+ oc\\t%O0(1,%R0),%1"
+ [(set_attr "op_type" "SI,SS")
+ (set_attr "atype" "reg,mem")])
+
+
+;;
+;;- Xor instructions.
+;;
+
+;
+; xordi3 instruction pattern(s).
+;
+
+(define_insn "*xordi3_cc"
+ [(set (reg 33)
+ (compare (xor:DI (match_operand:DI 1 "register_operand" "%0,0")
+ (match_operand:DI 2 "general_operand" "d,m"))
+ (const_int 0)))
+ (set (match_operand:DI 0 "register_operand" "=d,d")
+ (xor:DI (match_dup 1) (match_dup 2)))]
+ "s390_match_ccmode(insn, CCTmode) && TARGET_64BIT"
+ "@
+ xgr\\t%0,%2
+ xg\\t%0,%2"
+ [(set_attr "op_type" "RRE,RXE")
+ (set_attr "atype" "reg,mem")])
+
+(define_insn "*xordi3_cconly"
+ [(set (reg 33)
+ (compare (xor:DI (match_operand:DI 1 "register_operand" "%0,0")
+ (match_operand:DI 2 "general_operand" "d,m"))
+ (const_int 0)))
+ (clobber (match_scratch:DI 0 "=d,d"))]
+ "s390_match_ccmode(insn, CCTmode) && TARGET_64BIT"
+ "@
+ xgr\\t%0,%2
+ xr\\t%0,%2"
+ [(set_attr "op_type" "RRE,RXE")
+ (set_attr "atype" "reg,mem")])
+
+(define_insn "xordi3"
+ [(set (match_operand:DI 0 "register_operand" "=d,d")
+ (xor:DI (match_operand:DI 1 "register_operand" "%0,0")
+ (match_operand:DI 2 "general_operand" "d,m")))
+ (clobber (reg:CC 33))]
+ "TARGET_64BIT"
+ "@
+ xgr\\t%0,%2
+ xg\\t%0,%2"
+ [(set_attr "op_type" "RRE,RXE")
+ (set_attr "atype" "reg,mem")])
+
+(define_insn "*xordi3_ss"
+ [(set (match_operand:DI 0 "s_operand" "=Qo")
+ (xor:DI (match_dup 0)
+ (match_operand:DI 1 "s_imm_operand" "Qo")))
+ (clobber (reg:CC 33))]
+ ""
+ "xc\\t%O0(8,%R0),%1"
+ [(set_attr "op_type" "SS")
+ (set_attr "atype" "mem")])
+
+(define_insn "*xordi3_ss_inv"
+ [(set (match_operand:DI 0 "s_operand" "=Qo")
+ (xor:DI (match_operand:DI 1 "s_imm_operand" "Qo")
+ (match_dup 0)))
+ (clobber (reg:CC 33))]
+ ""
+ "xc\\t%O0(8,%R0),%1"
+ [(set_attr "op_type" "SS")
+ (set_attr "atype" "mem")])
+
+;
+; xorsi3 instruction pattern(s).
+;
+
+(define_insn "*xorsi3_cc"
+ [(set (reg 33)
+ (compare (xor: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")
+ (xor:SI (match_dup 1) (match_dup 2)))]
+ "s390_match_ccmode(insn, CCTmode)"
+ "@
+ xr\\t%0,%2
+ x\\t%0,%2"
+ [(set_attr "op_type" "RR,RX")
+ (set_attr "atype" "reg,mem")])
+
+(define_insn "*xorsi3_cconly"
+ [(set (reg 33)
+ (compare (xor: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, CCTmode)"
+ "@
+ xr\\t%0,%2
+ x\\t%0,%2"
+ [(set_attr "op_type" "RR,RX")
+ (set_attr "atype" "reg,mem")])
+
+(define_insn "xorsi3"
+ [(set (match_operand:SI 0 "register_operand" "=d,d")
+ (xor:SI (match_operand:SI 1 "register_operand" "%0,0")
+ (match_operand:SI 2 "general_operand" "d,m")))
+ (clobber (reg:CC 33))]
+ ""
+ "@
+ xr\\t%0,%2
+ x\\t%0,%2"
+ [(set_attr "op_type" "RR,RX")
+ (set_attr "atype" "reg,mem")])
+
+(define_insn "*xorsi3_ss"
+ [(set (match_operand:SI 0 "s_operand" "=Qo")
+ (xor:SI (match_dup 0)
+ (match_operand:SI 1 "s_imm_operand" "Qo")))
+ (clobber (reg:CC 33))]
+ ""
+ "xc\\t%O0(4,%R0),%1"
+ [(set_attr "op_type" "SS")
+ (set_attr "atype" "mem")])
+
+(define_insn "*xorsi3_ss_inv"
+ [(set (match_operand:SI 0 "s_operand" "=Qo")
+ (xor:SI (match_operand:SI 1 "s_imm_operand" "Qo")
+ (match_dup 0)))
+ (clobber (reg:CC 33))]
+ ""
+ "xc\\t%O0(4,%R0),%1"
+ [(set_attr "op_type" "SS")
+ (set_attr "atype" "mem")])
+
+;
+; xorhi3 instruction pattern(s).
+;
+
+(define_insn "xorhi3"
+ [(set (match_operand:HI 0 "register_operand" "=d")
+ (xor:HI (match_operand:HI 1 "register_operand" "%0")
+ (match_operand:HI 2 "nonmemory_operand" "d")))
+ (clobber (reg:CC 33))]
+ ""
+ "xr\\t%0,%2"
+ [(set_attr "op_type" "RR")
+ (set_attr "atype" "reg")])
+
+(define_insn "*xorhi3_ss"
+ [(set (match_operand:HI 0 "s_operand" "=Qo")
+ (xor:HI (match_dup 0)
+ (match_operand:HI 1 "s_imm_operand" "Qo")))
+ (clobber (reg:CC 33))]
+ ""
+ "xc\\t%O0(2,%R0),%1"
+ [(set_attr "op_type" "SS")
+ (set_attr "atype" "mem")])
+
+(define_insn "*xorhi3_ss_inv"
+ [(set (match_operand:HI 0 "s_operand" "=Qo")
+ (xor:HI (match_operand:HI 1 "s_imm_operand" "Qo")
+ (match_dup 0)))
+ (clobber (reg:CC 33))]
+ ""
+ "xc\\t%O0(2,%R0),%1"
+ [(set_attr "op_type" "SS")
+ (set_attr "atype" "mem")])
+
+;
+; xorqi3 instruction pattern(s).
+;
+
+(define_insn "xorqi3"
+ [(set (match_operand:QI 0 "register_operand" "=d")
+ (xor:QI (match_operand:QI 1 "register_operand" "%0")
+ (match_operand:QI 2 "nonmemory_operand" "d")))
+ (clobber (reg:CC 33))]
+ ""
+ "xr\\t%0,%2"
+ [(set_attr "op_type" "RR")
+ (set_attr "atype" "reg")])
+
+(define_insn "*xorqi3_ss"
+ [(set (match_operand:QI 0 "s_operand" "=Qo,Qo")
+ (xor:QI (match_dup 0)
+ (match_operand:QI 1 "s_imm_operand" "n,Qo")))
+ (clobber (reg:CC 33))]
+ ""
+ "@
+ xi\\t%0,%b1
+ xc\\t%O0(1,%R0),%1"
+ [(set_attr "op_type" "SI,SS")
+ (set_attr "atype" "mem")])
+
+(define_insn "*xorqi3_ss_inv"
+ [(set (match_operand:QI 0 "s_operand" "=Qo,Qo")
+ (xor:QI (match_operand:QI 1 "s_imm_operand" "n,Qo")
+ (match_dup 0)))
+ (clobber (reg:CC 33))]
+ ""
+ "@
+ xi\\t%0,%b1
+ xc\\t%O0(1,%R0),%1"
+ [(set_attr "op_type" "SI,SS")
+ (set_attr "atype" "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")])
+
+(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 "type" "other")
+ (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")])
+
+;
+; 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" "RRE")])
+
+(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" "RRE")])
+
+(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")])
+
+;
+; 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")])
+
+;
+; 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" "RRE")])
+
+(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" "RRE")])
+
+(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")])
+
+;;
+;;- Square root instructions.
+;;
+
+;
+; sqrtdf2 instruction pattern(s).
+;
+
+(define_insn "sqrtdf2"
+ [(set (match_operand:DF 0 "register_operand" "=f,f")
+ (sqrt:DF (match_operand:DF 1 "general_operand" "f,m")))]
+ "TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT"
+ "@
+ sqdbr\\t%0,%1
+ sqdb\\t%0,%1"
+ [(set_attr "op_type" "RRE,RSE")])
+
+;
+; sqrtsf2 instruction pattern(s).
+;
+
+(define_insn "sqrtsf2"
+ [(set (match_operand:SF 0 "register_operand" "=f,f")
+ (sqrt:SF (match_operand:SF 1 "general_operand" "f,m")))]
+ "TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT"
+ "@
+ sqebr\\t%0,%1
+ sqeb\\t%0,%1"
+ [(set_attr "op_type" "RRE,RSE")])
+
+;;
+;;- One complement instructions.
+;;
+
+;
+; one_cmpldi2 instruction pattern(s).
+;
+
+(define_expand "one_cmpldi2"
+ [(parallel
+ [(set (match_operand:DI 0 "register_operand" "")
+ (xor:DI (match_operand:DI 1 "register_operand" "")
+ (const_int -1)))
+ (clobber (reg:CC 33))])]
+ "TARGET_64BIT"
+ "")
+
+;
+; one_cmplsi2 instruction pattern(s).
+;
+
+(define_expand "one_cmplsi2"
+ [(parallel
+ [(set (match_operand:SI 0 "register_operand" "")
+ (xor:SI (match_operand:SI 1 "register_operand" "")
+ (const_int -1)))
+ (clobber (reg:CC 33))])]
+ ""
+ "")
+
+;
+; one_cmplhi2 instruction pattern(s).
+;
+
+(define_expand "one_cmplhi2"
+ [(parallel
+ [(set (match_operand:HI 0 "register_operand" "")
+ (xor:HI (match_operand:HI 1 "register_operand" "")
+ (const_int -1)))
+ (clobber (reg:CC 33))])]
+ ""
+ "")
+
+;
+; one_cmplqi2 instruction pattern(s).
+;
+
+(define_expand "one_cmplqi2"
+ [(parallel
+ [(set (match_operand:QI 0 "register_operand" "")
+ (xor:QI (match_operand:QI 1 "register_operand" "")
+ (const_int -1)))
+ (clobber (reg:CC 33))])]
+ ""
+ "")
+
+
+;;
+;;- 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:SI 2 "nonmemory_operand" "J,a")))]
+ "TARGET_64BIT"
+ "@
+ rllg\\t%0,%1,%c2
+ rllg\\t%0,%1,0(%2)"
+ [(set_attr "op_type" "RSE")])
+
+;
+; 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")))]
+ "TARGET_64BIT"
+ "@
+ rll\\t%0,%1,%c2
+ rll\\t%0,%1,0(%2)"
+ [(set_attr "op_type" "RSE")])
+
+
+;;
+;;- Arithmetic shift instructions.
+;;
+
+;
+; ashldi3 instruction pattern(s).
+;
+
+(define_expand "ashldi3"
+ [(set (match_operand:DI 0 "register_operand" "")
+ (ashift:DI (match_operand:DI 1 "register_operand" "")
+ (match_operand:SI 2 "nonmemory_operand" "")))]
+ ""
+ "")
+
+(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")))]
+ "!TARGET_64BIT"
+ "@
+ sldl\\t%0,%c2
+ sldl\\t%0,0(%2)"
+ [(set_attr "op_type" "RS")])
+
+(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")))]
+ "TARGET_64BIT"
+ "@
+ sllg\\t%0,%1,%2
+ sllg\\t%0,%1,0(%2)"
+ [(set_attr "op_type" "RSE")])
+
+;
+; 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_cc_31"
+ [(set (reg 33)
+ (compare (ashiftrt:DI (match_operand:DI 1 "register_operand" "0,0")
+ (match_operand:SI 2 "nonmemory_operand" "J,a"))
+ (const_int 0)))
+ (set (match_operand:DI 0 "register_operand" "=d,d")
+ (ashiftrt:DI (match_dup 1) (match_dup 2)))]
+ "!TARGET_64BIT && s390_match_ccmode(insn, CCSmode)"
+ "@
+ srda\\t%0,%c2
+ srda\\t%0,0(%2)"
+ [(set_attr "op_type" "RS")])
+
+(define_insn "*ashrdi3_cconly_31"
+ [(set (reg 33)
+ (compare (ashiftrt:DI (match_operand:DI 1 "register_operand" "0,0")
+ (match_operand:SI 2 "nonmemory_operand" "J,a"))
+ (const_int 0)))
+ (clobber (match_scratch:DI 0 "=d,d"))]
+ "!TARGET_64BIT && s390_match_ccmode(insn, CCSmode)"
+ "@
+ srda\\t%0,%c2
+ srda\\t%0,0(%2)"
+ [(set_attr "op_type" "RS")])
+
+(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_cc_64"
+ [(set (reg 33)
+ (compare (ashiftrt:DI (match_operand:DI 1 "register_operand" "d,d")
+ (match_operand:SI 2 "nonmemory_operand" "J,a"))
+ (const_int 0)))
+ (set (match_operand:DI 0 "register_operand" "=d,d")
+ (ashiftrt:DI (match_dup 1) (match_dup 2)))]
+ "s390_match_ccmode(insn, CCSmode) && TARGET_64BIT"
+ "@
+ srag\\t%0,%1,%c2
+ srag\\t%0,%1,0(%2)"
+ [(set_attr "op_type" "RSE")])
+
+(define_insn "*ashrdi3_cconly_64"
+ [(set (reg 33)
+ (compare (ashiftrt:DI (match_operand:DI 1 "register_operand" "d,d")
+ (match_operand:SI 2 "nonmemory_operand" "J,a"))
+ (const_int 0)))
+ (clobber (match_scratch:DI 0 "=d,d"))]
+ "s390_match_ccmode(insn, CCSmode) && TARGET_64BIT"
+ "@
+ srag\\t%0,%1,%c2
+ srag\\t%0,%1,0(%2)"
+ [(set_attr "op_type" "RSE")])
+
+(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")])
+
+;
+; ashlsi3 instruction pattern(s).
+;
+
+(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 "nonmemory_operand" "J,a")))]
+ ""
+ "@
+ sll\\t%0,%c2
+ sll\\t%0,0(%2)"
+ [(set_attr "op_type" "RS")])
+
+;
+; ashrsi3 instruction pattern(s).
+;
+
+(define_insn "*ashrsi3_cc"
+ [(set (reg 33)
+ (compare (ashiftrt:SI (match_operand:SI 1 "register_operand" "0,0")
+ (match_operand:SI 2 "nonmemory_operand" "J,a"))
+ (const_int 0)))
+ (set (match_operand:SI 0 "register_operand" "=d,d")
+ (ashiftrt:SI (match_dup 1) (match_dup 2)))]
+ "s390_match_ccmode(insn, CCSmode)"
+ "@
+ sra\\t%0,%c2
+ sra\\t%0,0(%2)"
+ [(set_attr "op_type" "RS")])
+
+(define_insn "*ashrsi3_cconly"
+ [(set (reg 33)
+ (compare (ashiftrt:SI (match_operand:SI 1 "register_operand" "0,0")
+ (match_operand:SI 2 "nonmemory_operand" "J,a"))
+ (const_int 0)))
+ (clobber (match_scratch:SI 0 "=d,d"))]
+ "s390_match_ccmode(insn, CCSmode)"
+ "@
+ sra\\t%0,%c2
+ sra\\t%0,0(%2)"
+ [(set_attr "op_type" "RS")])
+
+(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 "nonmemory_operand" "J,a")))
+ (clobber (reg:CC 33))]
+ ""
+ "@
+ sra\\t%0,%c2
+ sra\\t%0,0(%2)"
+ [(set_attr "op_type" "RS")])
+
+
+;;
+;;- logical shift instructions.
+;;
+
+;
+; lshrdi3 instruction pattern(s).
+;
+
+(define_expand "lshrdi3"
+ [(set (match_operand:DI 0 "register_operand" "")
+ (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
+ (match_operand:SI 2 "nonmemory_operand" "")))]
+ ""
+ "")
+
+(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")))]
+ "!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")))]
+ "TARGET_64BIT"
+ "@
+ srlg\\t%0,%1,%c2
+ srlg\\t%0,%1,0(%2)"
+ [(set_attr "op_type" "RSE,RSE")])
+
+;
+; 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 "nonmemory_operand" "J,a")))]
+ ""
+ "@
+ srl\\t%0,%c2
+ srl\\t%0,0(%2)"
+ [(set_attr "op_type" "RS")])
+
+
+;;
+;; 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; }")
+
+(define_expand "bunordered"
+ [(set (reg:CCS 33) (compare:CCS (match_dup 1) (match_dup 2)))
+ (set (pc)
+ (if_then_else (unordered (reg:CCS 33) (const_int 0))
+ (label_ref (match_operand 0 "" ""))
+ (pc)))]
+ ""
+ "{ operands[1] = s390_compare_op0; operands[2] = s390_compare_op1; }")
+
+(define_expand "bordered"
+ [(set (reg:CCS 33) (compare:CCS (match_dup 1) (match_dup 2)))
+ (set (pc)
+ (if_then_else (ordered (reg:CCS 33) (const_int 0))
+ (label_ref (match_operand 0 "" ""))
+ (pc)))]
+ ""
+ "{ operands[1] = s390_compare_op0; operands[2] = s390_compare_op1; }")
+
+(define_expand "buneq"
+ [(set (reg:CCS 33) (compare:CCS (match_dup 1) (match_dup 2)))
+ (set (pc)
+ (if_then_else (uneq (reg:CCS 33) (const_int 0))
+ (label_ref (match_operand 0 "" ""))
+ (pc)))]
+ ""
+ "{ operands[1] = s390_compare_op0; operands[2] = s390_compare_op1; }")
+
+(define_expand "bungt"
+ [(set (reg:CCS 33) (compare:CCS (match_dup 1) (match_dup 2)))
+ (set (pc)
+ (if_then_else (ungt (reg:CCS 33) (const_int 0))
+ (label_ref (match_operand 0 "" ""))
+ (pc)))]
+ ""
+ "{ operands[1] = s390_compare_op0; operands[2] = s390_compare_op1; }")
+
+(define_expand "bunlt"
+ [(set (reg:CCS 33) (compare:CCS (match_dup 1) (match_dup 2)))
+ (set (pc)
+ (if_then_else (unlt (reg:CCS 33) (const_int 0))
+ (label_ref (match_operand 0 "" ""))
+ (pc)))]
+ ""
+ "{ operands[1] = s390_compare_op0; operands[2] = s390_compare_op1; }")
+
+(define_expand "bunge"
+ [(set (reg:CCS 33) (compare:CCS (match_dup 1) (match_dup 2)))
+ (set (pc)
+ (if_then_else (unge (reg:CCS 33) (const_int 0))
+ (label_ref (match_operand 0 "" ""))
+ (pc)))]
+ ""
+ "{ operands[1] = s390_compare_op0; operands[2] = s390_compare_op1; }")
+
+(define_expand "bunle"
+ [(set (reg:CCS 33) (compare:CCS (match_dup 1) (match_dup 2)))
+ (set (pc)
+ (if_then_else (unle (reg:CCS 33) (const_int 0))
+ (label_ref (match_operand 0 "" ""))
+ (pc)))]
+ ""
+ "{ operands[1] = s390_compare_op0; operands[2] = s390_compare_op1; }")
+
+(define_expand "bltgt"
+ [(set (reg:CCS 33) (compare:CCS (match_dup 1) (match_dup 2)))
+ (set (pc)
+ (if_then_else (ltgt (reg:CCS 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)
+ return \"j%C1\\t%l0\";
+ else if (TARGET_64BIT)
+ return \"jg%C1\\t%l0\";
+ else
+ abort ();
+}"
+ [(set_attr "op_type" "RI")
+ (set (attr "length")
+ (cond [(lt (abs (minus (pc) (match_dup 0))) (const_int 60000))
+ (const_int 4)
+ (ne (symbol_ref "TARGET_64BIT") (const_int 0))
+ (const_int 6)
+ (ne (symbol_ref "s390_pool_overflow") (const_int 0))
+ (if_then_else (eq (symbol_ref "flag_pic") (const_int 0))
+ (const_int 12) (const_int 14))
+ (eq (symbol_ref "flag_pic") (const_int 0))
+ (const_int 6)] (const_int 8)))])
+
+(define_insn "*cjump_long"
+ [(set (pc)
+ (if_then_else
+ (match_operator 1 "comparison_operator" [(reg 33) (const_int 0)])
+ (match_operand 0 "address_operand" "p")
+ (pc)))]
+ ""
+ "*
+{
+ if (get_attr_op_type (insn) == OP_TYPE_RR)
+ return \"b%C1r\\t%0\";
+ else
+ return \"b%C1\\t%a0\";
+}"
+ [(set (attr "op_type")
+ (if_then_else (match_operand 0 "register_operand" "")
+ (const_string "RR") (const_string "RX")))
+ (set_attr "atype" "mem")])
+
+
+;;
+;;- 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)
+ return \"j%D1\\t%l0\";
+ else if (TARGET_64BIT)
+ return \"jg%D1\\t%l0\";
+ else
+ abort ();
+}"
+ [(set_attr "op_type" "RI")
+ (set (attr "length")
+ (cond [(lt (abs (minus (pc) (match_dup 0))) (const_int 60000))
+ (const_int 4)
+ (ne (symbol_ref "TARGET_64BIT") (const_int 0))
+ (const_int 6)
+ (ne (symbol_ref "s390_pool_overflow") (const_int 0))
+ (if_then_else (eq (symbol_ref "flag_pic") (const_int 0))
+ (const_int 12) (const_int 14))
+ (eq (symbol_ref "flag_pic") (const_int 0))
+ (const_int 6)] (const_int 8)))])
+
+(define_insn "*icjump_long"
+ [(set (pc)
+ (if_then_else
+ (match_operator 1 "comparison_operator" [(reg 33) (const_int 0)])
+ (pc)
+ (match_operand 0 "address_operand" "p")))]
+ ""
+ "*
+{
+ if (get_attr_op_type (insn) == OP_TYPE_RR)
+ return \"b%D1r\\t%0\";
+ else
+ return \"b%D1\\t%a0\";
+}"
+ [(set (attr "op_type")
+ (if_then_else (match_operand 0 "register_operand" "")
+ (const_string "RR") (const_string "RX")))
+ (set_attr "atype" "mem")])
+
+
+;;
+;;- 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)
+ return \"j\\t%l0\";
+ else if (TARGET_64BIT)
+ return \"jg\\t%l0\";
+ else
+ abort ();
+}"
+ [(set_attr "op_type" "RI")
+ (set (attr "length")
+ (cond [(lt (abs (minus (pc) (match_dup 0))) (const_int 60000))
+ (const_int 4)
+ (ne (symbol_ref "TARGET_64BIT") (const_int 0))
+ (const_int 6)
+ (eq (symbol_ref "flag_pic") (const_int 0))
+ (const_int 6)] (const_int 8)))])
+
+;
+; indirect-jump instruction pattern(s).
+;
+
+(define_insn "indirect_jump"
+ [(set (pc) (match_operand 0 "address_operand" "p"))]
+ ""
+ "*
+{
+ if (get_attr_op_type (insn) == OP_TYPE_RR)
+ return \"br\\t%0\";
+ else
+ return \"b\\t%a0\";
+}"
+ [(set (attr "op_type")
+ (if_then_else (match_operand 0 "register_operand" "")
+ (const_string "RR") (const_string "RX")))
+ (set_attr "atype" "mem")])
+
+;
+; casesi instruction pattern(s).
+;
+
+(define_insn "casesi_jump"
+ [(set (pc) (match_operand 0 "address_operand" "p"))
+ (use (label_ref (match_operand 1 "" "")))]
+ ""
+ "*
+{
+ if (get_attr_op_type (insn) == OP_TYPE_RR)
+ return \"br\\t%0\";
+ else
+ return \"b\\t%a0\";
+}"
+ [(set (attr "op_type")
+ (if_then_else (match_operand 0 "register_operand" "")
+ (const_string "RR") (const_string "RX")))
+ (set_attr "atype" "mem")])
+
+(define_expand "casesi"
+ [(match_operand:SI 0 "general_operand" "")
+ (match_operand:SI 1 "general_operand" "")
+ (match_operand:SI 2 "general_operand" "")
+ (label_ref (match_operand 3 "" ""))
+ (label_ref (match_operand 4 "" ""))]
+ ""
+ "
+{
+ rtx index = gen_reg_rtx (SImode);
+ rtx base = gen_reg_rtx (Pmode);
+ rtx target = gen_reg_rtx (Pmode);
+
+ emit_move_insn (index, operands[0]);
+ emit_insn (gen_subsi3 (index, index, operands[1]));
+ emit_cmp_and_jump_insns (index, operands[2], GTU, NULL_RTX, SImode, 1,
+ operands[4]);
+
+ if (Pmode != SImode)
+ index = convert_to_mode (Pmode, index, 1);
+ if (GET_CODE (index) != REG)
+ index = copy_to_mode_reg (Pmode, index);
+
+ if (TARGET_64BIT)
+ emit_insn (gen_ashldi3 (index, index, GEN_INT (3)));
+ else
+ emit_insn (gen_ashlsi3 (index, index, GEN_INT (2)));
+
+ emit_move_insn (base, gen_rtx_LABEL_REF (Pmode, operands[3]));
+
+ index = gen_rtx_MEM (Pmode, gen_rtx_PLUS (Pmode, base, index));
+ emit_move_insn (target, index);
+
+ if (flag_pic)
+ target = gen_rtx_PLUS (Pmode, base, target);
+ emit_jump_insn (gen_casesi_jump (target, operands[3]));
+
+ DONE;
+}")
+
+
+;;
+;;- 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)]
+ ""
+ ""
+ [(set_attr "type" "none")])
+
+
+
+;
+; call instruction pattern(s).
+;
+
+(define_expand "call"
+ [(call (match_operand 0 "" "")
+ (match_operand 1 "" ""))
+ (use (match_operand 2 "" ""))]
+ ""
+ "
+{
+ int plt_call = 0;
+ rtx insn;
+
+ /* 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);
+
+ plt_call = 1;
+ }
+
+ /* 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);
+ }
+
+ /* Emit insn. */
+ insn = emit_call_insn (gen_call_exp (operands[0], operands[1],
+ 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 (plt_call && !TARGET_64BIT)
+ {
+ current_function_uses_pic_offset_table = 1;
+ use_reg (&CALL_INSN_FUNCTION_USAGE (insn), pic_offset_table_rtx);
+ }
+
+ DONE;
+}")
+
+(define_expand "call_exp"
+ [(parallel [(call (match_operand 0 "" "")
+ (match_operand 1 "" ""))
+ (clobber (match_operand 2 "" ""))])]
+ ""
+ "")
+
+(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 "type" "jsr")])
+
+(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 "type" "jsr")])
+
+(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 "type" "jsr")
+ (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 "type" "jsr")
+ (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 "type" "jsr")
+ (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 "type" "jsr")
+ (set_attr "atype" "mem")])
+
+
+;
+; call_value instruction pattern(s).
+;
+
+(define_expand "call_value"
+ [(set (match_operand 0 "" "")
+ (call (match_operand 1 "" "")
+ (match_operand 2 "" "")))
+ (use (match_operand 3 "" ""))]
+ ""
+ "
+{
+ int plt_call = 0;
+ rtx insn;
+
+ /* 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);
+
+ plt_call = 1;
+ }
+
+ /* 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);
+ }
+
+ /* Emit insn. */
+ insn = emit_call_insn (
+ gen_call_value_exp (operands[0], operands[1], 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 (plt_call && !TARGET_64BIT)
+ {
+ current_function_uses_pic_offset_table = 1;
+ use_reg (&CALL_INSN_FUNCTION_USAGE (insn), pic_offset_table_rtx);
+ }
+
+ DONE;
+}")
+
+(define_expand "call_value_exp"
+ [(parallel [(set (match_operand 0 "" "")
+ (call (match_operand 1 "" "")
+ (match_operand 2 "" "")))
+ (clobber (match_operand 3 "" ""))])]
+ ""
+ "")
+
+(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 "type" "jsr")])
+
+(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 "type" "jsr")])
+
+(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 "type" "jsr")])
+
+(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 "type" "jsr")
+ (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 "type" "jsr")
+ (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 "type" "jsr")
+ (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)]
+ ""
+ "
+{
+ rtx base = gen_rtx_MEM (Pmode, plus_constant (operands[0], 4 * GET_MODE_SIZE (Pmode)));
+ rtx basereg = gen_rtx_REG (Pmode, BASE_REGISTER);
+
+ emit_move_insn (base, basereg);
+ DONE;
+}")
+
+(define_expand "builtin_setjmp_receiver"
+ [(unspec_volatile [(label_ref (match_operand 0 "" ""))] 2)]
+ "flag_pic"
+ "
+{
+ rtx gotreg = gen_rtx_REG (Pmode, PIC_OFFSET_TABLE_REGNUM);
+ rtx got = gen_rtx_SYMBOL_REF (Pmode, \"_GLOBAL_OFFSET_TABLE_\");
+ SYMBOL_REF_FLAG (got) = 1;
+
+ emit_move_insn (gotreg, got);
+ emit_insn (gen_rtx_USE (VOIDmode, gotreg));
+ DONE;
+}")
+
+(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], GET_MODE_SIZE (Pmode)));
+ rtx stack = gen_rtx_MEM (Pmode, plus_constant (operands[0], 2 * GET_MODE_SIZE (Pmode)));
+ rtx base = gen_rtx_MEM (Pmode, plus_constant (operands[0], 4 * GET_MODE_SIZE (Pmode)));
+ rtx basereg = gen_rtx_REG (Pmode, BASE_REGISTER);
+ rtx jmp = gen_rtx_REG (Pmode, 14);
+
+ emit_move_insn (jmp, lab);
+ emit_move_insn (basereg, base);
+ 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, basereg));
+ 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 "consttable_qi"
+ [(unspec_volatile [(match_operand:QI 0 "consttable_operand" "X")] 200)]
+ ""
+ "*
+{
+ assemble_integer (operands[0], 1, BITS_PER_UNIT, 1);
+ return \"\";
+}"
+ [(set_attr "op_type" "NN")
+ (set_attr "length" "1")])
+
+(define_insn "consttable_hi"
+ [(unspec_volatile [(match_operand:HI 0 "consttable_operand" "X")] 201)]
+ ""
+ "*
+{
+ assemble_integer (operands[0], 2, 2*BITS_PER_UNIT, 1);
+ return \"\";
+}"
+ [(set_attr "op_type" "NN")
+ (set_attr "length" "2")])
+
+(define_insn "consttable_si"
+ [(unspec_volatile [(match_operand:SI 0 "consttable_operand" "X")] 202)]
+ ""
+ "*
+{
+ if (!TARGET_64BIT && flag_pic && SYMBOLIC_CONST (operands[0]))
+ return \".long\\t%0\";
+
+ assemble_integer (operands[0], 4, 4*BITS_PER_UNIT, 1);
+ return \"\";
+}"
+ [(set_attr "op_type" "NN")
+ (set_attr "length" "4")])
+
+(define_insn "consttable_di"
+ [(unspec_volatile [(match_operand:DI 0 "consttable_operand" "X")] 203)]
+ ""
+ "*
+{
+ assemble_integer (operands[0], 8, 8*BITS_PER_UNIT, 1);
+ return \"\";
+}"
+ [(set_attr "op_type" "NN")
+ (set_attr "length" "8")])
+
+(define_insn "consttable_sf"
+ [(unspec_volatile [(match_operand:SF 0 "consttable_operand" "X")] 204)]
+ ""
+ "*
+{
+ REAL_VALUE_TYPE r;
+
+ if (GET_CODE (operands[0]) != CONST_DOUBLE)
+ abort ();
+
+ REAL_VALUE_FROM_CONST_DOUBLE (r, operands[0]);
+ assemble_real (r, SFmode, 4*BITS_PER_UNIT);
+ return \"\";
+}"
+ [(set_attr "op_type" "NN")
+ (set_attr "length" "4")])
+
+(define_insn "consttable_df"
+ [(unspec_volatile [(match_operand:DF 0 "consttable_operand" "X")] 205)]
+ ""
+ "*
+{
+ REAL_VALUE_TYPE r;
+
+ if (GET_CODE (operands[0]) != CONST_DOUBLE)
+ abort ();
+
+ REAL_VALUE_FROM_CONST_DOUBLE (r, operands[0]);
+ assemble_real (r, DFmode, 8*BITS_PER_UNIT);
+ return \"\";
+}"
+ [(set_attr "op_type" "NN")
+ (set_attr "length" "8")])
+
+(define_insn "pool_start_31"
+ [(unspec_volatile [(const_int 0)] 206)]
+ "!TARGET_64BIT"
+ ".align\\t4"
+ [(set_attr "op_type" "NN")
+ (set_attr "length" "2")])
+
+(define_insn "pool_end_31"
+ [(unspec_volatile [(const_int 0)] 207)]
+ "!TARGET_64BIT"
+ ".align\\t2"
+ [(set_attr "op_type" "NN")
+ (set_attr "length" "2")])
+
+(define_insn "pool_start_64"
+ [(unspec_volatile [(const_int 0)] 206)]
+ "TARGET_64BIT"
+ ".section\\t.rodata\;.align\\t8"
+ [(set_attr "op_type" "NN")
+ (set_attr "length" "0")])
+
+(define_insn "pool_end_64"
+ [(unspec_volatile [(const_int 0)] 207)]
+ "TARGET_64BIT"
+ ".previous"
+ [(set_attr "op_type" "NN")
+ (set_attr "length" "0")])
+
+(define_insn "reload_base"
+ [(set (match_operand:SI 0 "register_operand" "=a")
+ (unspec:SI [(label_ref (match_operand 1 "" ""))] 210))]
+ "!TARGET_64BIT"
+ "basr\\t%0,0\;la\\t%0,%1-.(%0)"
+ [(set_attr "op_type" "NN")
+ (set_attr "type" "la")
+ (set_attr "length" "6")])
+
+(define_insn "reload_base2"
+ [(set (match_operand:SI 0 "register_operand" "=a")
+ (unspec:SI [(label_ref (match_operand 1 "" ""))] 211))]
+ "!TARGET_64BIT"
+ "la\\t%0,%1-.(%0)"
+ [(set_attr "op_type" "NN")
+ (set_attr "type" "la")
+ (set_attr "length" "4")])
+
+
+;;
+;; Insns related to generating the function prologue and epilogue.
+;;
+
+
+(define_expand "prologue"
+ [(use (const_int 0))]
+ ""
+ "
+{
+ s390_emit_prologue ();
+ DONE;
+}")
+
+(define_expand "epilogue"
+ [(use (const_int 1))]
+ ""
+ "
+{
+ s390_emit_epilogue ();
+ DONE;
+}")
+
+
+(define_insn "*return_si"
+ [(return)
+ (use (match_operand:SI 0 "register_operand" "a"))]
+ "!TARGET_64BIT"
+ "br\\t%0"
+ [(set_attr "op_type" "RR")
+ (set_attr "type" "jsr")
+ (set_attr "atype" "mem")])
+
+(define_insn "*return_di"
+ [(return)
+ (use (match_operand:DI 0 "register_operand" "a"))]
+ "TARGET_64BIT"
+ "br\\t%0"
+ [(set_attr "op_type" "RR")
+ (set_attr "type" "jsr")
+ (set_attr "atype" "mem")])
+
+
+(define_insn "lit"
+ [(set (reg 13) (pc))
+ (unspec_volatile [(const_int 0)] 200)]
+ ""
+ "*
+{
+ s390_output_constant_pool (asm_out_file);
+ return \"\";
+}"
+ [(set_attr "op_type" "NN")
+ (set_attr "type" "integer")])
+
+
+;;
+;; 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\";
+}")
+
OpenPOWER on IntegriCloud