1107590Sobrien;;- Machine description for GNU compiler -- S/390 / zSeries version.
2169689Skan;;  Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006
3132718Skan;;  Free Software Foundation, Inc.
4107590Sobrien;;  Contributed by Hartmut Penner (hpenner@de.ibm.com) and
5107590Sobrien;;                 Ulrich Weigand (uweigand@de.ibm.com).
6107590Sobrien
7132718Skan;; This file is part of GCC.
8107590Sobrien
9132718Skan;; GCC is free software; you can redistribute it and/or modify it under
10132718Skan;; the terms of the GNU General Public License as published by the Free
11132718Skan;; Software Foundation; either version 2, or (at your option) any later
12132718Skan;; version.
13107590Sobrien
14132718Skan;; GCC is distributed in the hope that it will be useful, but WITHOUT ANY
15132718Skan;; WARRANTY; without even the implied warranty of MERCHANTABILITY or
16132718Skan;; FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
17132718Skan;; for more details.
18132718Skan
19107590Sobrien;; You should have received a copy of the GNU General Public License
20132718Skan;; along with GCC; see the file COPYING.  If not, write to the Free
21169689Skan;; Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
22169689Skan;; 02110-1301, USA.
23107590Sobrien
24107590Sobrien;;
25169689Skan;; See constraints.md for a description of constraints specific to s390.
26107590Sobrien;;
27169689Skan
28107590Sobrien;; Special formats used for outputting 390 instructions.
29107590Sobrien;;
30132718Skan;;     %C: print opcode suffix for branch condition.
31132718Skan;;     %D: print opcode suffix for inverse branch condition.
32132718Skan;;     %J: print tls_load/tls_gdcall/tls_ldcall suffix
33169689Skan;;     %G: print the size of the operand in bytes.
34132718Skan;;     %O: print only the displacement of a memory reference.
35132718Skan;;     %R: print only the base register of a memory reference.
36169689Skan;;     %S: print S-type memory reference (base+displacement).
37132718Skan;;     %N: print the second word of a DImode operand.
38132718Skan;;     %M: print the second word of a TImode operand.
39169689Skan;;     %Y: print shift count operand.
40169689Skan;;  
41132718Skan;;     %b: print integer X as if it's an unsigned byte.
42169689Skan;;     %x: print integer X as if it's an unsigned halfword.
43169689Skan;;     %h: print integer X as if it's a signed halfword.
44169689Skan;;     %i: print the first nonzero HImode part of X.
45169689Skan;;     %j: print the first HImode part unequal to -1 of X.
46169689Skan;;     %k: print the first nonzero SImode part of X.
47169689Skan;;     %m: print the first SImode part unequal to -1 of X.
48169689Skan;;     %o: print integer X as if it's an unsigned 32bit word.
49107590Sobrien;;
50107590Sobrien;; We have a special constraint for pattern matching.
51107590Sobrien;;
52107590Sobrien;;   s_operand -- Matches a valid S operand in a RS, SI or SS type instruction.
53107590Sobrien;;
54107590Sobrien
55117395Skan;;
56117395Skan;; UNSPEC usage
57117395Skan;;
58107590Sobrien
59117395Skan(define_constants
60132718Skan  [; Miscellaneous
61132718Skan   (UNSPEC_ROUND		1)
62169689Skan   (UNSPEC_CMPINT		2)
63169689Skan   (UNSPEC_ICM			10)
64132718Skan
65132718Skan   ; GOT/PLT and lt-relative accesses
66132718Skan   (UNSPEC_LTREL_OFFSET		100)
67132718Skan   (UNSPEC_LTREL_BASE		101)
68132718Skan   (UNSPEC_GOTENT		110)
69132718Skan   (UNSPEC_GOT			111)
70132718Skan   (UNSPEC_GOTOFF		112)
71132718Skan   (UNSPEC_PLT			113)
72132718Skan   (UNSPEC_PLTOFF		114)
73132718Skan
74132718Skan   ; Literal pool
75132718Skan   (UNSPEC_RELOAD_BASE		210)
76132718Skan   (UNSPEC_MAIN_BASE		211)
77169689Skan   (UNSPEC_LTREF		212)
78169689Skan   (UNSPEC_INSN			213)
79169689Skan   (UNSPEC_EXECUTE		214)
80132718Skan
81132718Skan   ; TLS relocation specifiers
82117395Skan   (UNSPEC_TLSGD		500)
83117395Skan   (UNSPEC_TLSLDM		501)
84117395Skan   (UNSPEC_NTPOFF               502)
85117395Skan   (UNSPEC_DTPOFF               503)
86117395Skan   (UNSPEC_GOTNTPOFF            504)
87117395Skan   (UNSPEC_INDNTPOFF            505)
88117395Skan
89117395Skan   ; TLS support
90117395Skan   (UNSPEC_TLSLDM_NTPOFF	511)
91117395Skan   (UNSPEC_TLS_LOAD		512)
92132718Skan
93132718Skan   ; String Functions
94169689Skan   (UNSPEC_SRST			600)
95169689Skan   (UNSPEC_MVST			601)
96169689Skan   
97169689Skan   ; Stack Smashing Protector
98169689Skan   (UNSPEC_SP_SET 		700)
99169689Skan   (UNSPEC_SP_TEST		701)
100117395Skan ])
101117395Skan
102117395Skan;;
103117395Skan;; UNSPEC_VOLATILE usage
104117395Skan;;
105117395Skan
106117395Skan(define_constants
107132718Skan  [; Blockage
108132718Skan   (UNSPECV_BLOCKAGE		0)
109132718Skan
110169689Skan   ; TPF Support
111169689Skan   (UNSPECV_TPF_PROLOGUE        20)
112169689Skan   (UNSPECV_TPF_EPILOGUE        21)
113169689Skan
114132718Skan   ; Literal pool
115132718Skan   (UNSPECV_POOL		200)
116169689Skan   (UNSPECV_POOL_SECTION	201)
117169689Skan   (UNSPECV_POOL_ALIGN		202)
118132718Skan   (UNSPECV_POOL_ENTRY		203)
119132718Skan   (UNSPECV_MAIN_POOL		300)
120132718Skan
121132718Skan   ; TLS support
122117395Skan   (UNSPECV_SET_TP		500)
123169689Skan
124169689Skan   ; Atomic Support
125169689Skan   (UNSPECV_MB			700)
126169689Skan   (UNSPECV_CAS			701)
127117395Skan  ])
128117395Skan
129169689Skan;;
130169689Skan;; Registers
131169689Skan;;
132117395Skan
133169689Skan(define_constants
134169689Skan  [
135169689Skan   ; Sibling call register.
136169689Skan   (SIBCALL_REGNUM		 1)
137169689Skan   ; Literal pool base register.
138169689Skan   (BASE_REGNUM			13)
139169689Skan   ; Return address register.
140169689Skan   (RETURN_REGNUM		14)
141169689Skan   ; Condition code register.
142169689Skan   (CC_REGNUM			33)
143169689Skan   ; Thread local storage pointer register. 
144169689Skan   (TP_REGNUM			36)
145169689Skan  ])
146132718Skan
147132718Skan
148169689Skan;; Instruction operand type as used in the Principles of Operation.
149169689Skan;; Used to determine defaults for length and other attribute values.
150107590Sobrien
151132718Skan(define_attr "op_type"
152132718Skan  "NN,E,RR,RRE,RX,RS,RSI,RI,SI,S,SS,SSE,RXE,RSE,RIL,RIE,RXY,RSY,SIY"
153169689Skan  (const_string "NN"))
154132718Skan
155169689Skan;; Instruction type attribute used for scheduling.
156107590Sobrien
157169689Skan(define_attr "type" "none,integer,load,lr,la,larl,lm,stm,
158169689Skan	             cs,vs,store,sem,idiv,
159169689Skan                     imulhi,imulsi,imuldi,
160169689Skan		     branch,jsr,fsimptf,fsimpdf,fsimpsf,
161169689Skan		     floadtf,floaddf,floadsf,fstoredf,fstoresf,
162169689Skan		     fmultf,fmuldf,fmulsf,fdivtf,fdivdf,fdivsf,
163169689Skan		     ftoi,itof,fsqrttf,fsqrtdf,fsqrtsf,
164169689Skan                     ftrunctf,ftruncdf,other"
165169689Skan  (cond [(eq_attr "op_type" "NN")  (const_string "other")
166169689Skan         (eq_attr "op_type" "SS")  (const_string "cs")]
167169689Skan    (const_string "integer")))
168107590Sobrien
169169689Skan;; Another attribute used for scheduling purposes:
170169689Skan;;   agen: Instruction uses the address generation unit
171169689Skan;;   reg: Instruction does not use the agen unit
172107590Sobrien
173169689Skan(define_attr "atype" "agen,reg"
174169689Skan  (if_then_else (eq_attr "op_type" "E,RR,RI,RRE")  
175169689Skan		(const_string "reg")
176169689Skan		(const_string "agen")))
177107590Sobrien
178169689Skan;; Length in bytes.
179107590Sobrien
180169689Skan(define_attr "length" ""
181169689Skan  (cond [(eq_attr "op_type" "E,RR")		      (const_int 2)
182169689Skan         (eq_attr "op_type" "RX,RI,RRE,RS,RSI,S,SI")  (const_int 4)]
183169689Skan    (const_int 6)))
184132718Skan
185132718Skan
186169689Skan;; Processor type.  This attribute must exactly match the processor_type
187169689Skan;; enumeration in s390.h.  The current machine description does not
188169689Skan;; distinguish between g5 and g6, but there are differences between the two
189169689Skan;; CPUs could in theory be modeled.
190107590Sobrien
191169689Skan(define_attr "cpu" "g5,g6,z900,z990,z9_109"
192169689Skan  (const (symbol_ref "s390_tune")))
193132718Skan
194169689Skan;; Pipeline description for z900.  For lack of anything better,
195169689Skan;; this description is also used for the g5 and g6.
196169689Skan(include "2064.md")
197132718Skan
198169689Skan;; Pipeline description for z990. 
199169689Skan(include "2084.md")
200107590Sobrien
201169689Skan;; Predicates
202169689Skan(include "predicates.md")
203132718Skan
204169689Skan;; Constraint definitions
205169689Skan(include "constraints.md")
206107590Sobrien
207169689Skan;; Other includes
208169689Skan(include "tpf.md")
209132718Skan
210169689Skan;; Macros
211107590Sobrien
212169689Skan;; This mode macro allows floating point patterns to be generated from the
213169689Skan;; same template.
214169689Skan(define_mode_macro FPR [TF DF SF])
215169689Skan(define_mode_macro DSF [DF SF])
216132718Skan
217169689Skan;; These mode macros allow 31-bit and 64-bit TDSI patterns to be generated
218169689Skan;; from the same template.
219169689Skan(define_mode_macro TDSI [(TI "TARGET_64BIT") DI SI])
220132718Skan
221169689Skan;; These mode macros allow 31-bit and 64-bit GPR patterns to be generated
222169689Skan;; from the same template.
223169689Skan(define_mode_macro GPR [(DI "TARGET_64BIT") SI])
224169689Skan(define_mode_macro DSI [DI SI])
225107590Sobrien
226169689Skan;; This mode macro allows :P to be used for patterns that operate on
227169689Skan;; pointer-sized quantities.  Exactly one of the two alternatives will match.
228169689Skan(define_mode_macro DP  [(TI "TARGET_64BIT") (DI "!TARGET_64BIT")])
229169689Skan(define_mode_macro P [(DI "TARGET_64BIT") (SI "!TARGET_64BIT")])
230107590Sobrien
231169689Skan;; This mode macro allows the QI and HI patterns to be defined from
232169689Skan;; the same template.
233169689Skan(define_mode_macro HQI [HI QI])
234107590Sobrien
235169689Skan;; This mode macro allows the integer patterns to be defined from the
236169689Skan;; same template.
237169689Skan(define_mode_macro INT [(DI "TARGET_64BIT") SI HI QI])
238107590Sobrien
239169689Skan;; This macro allows to unify all 'bCOND' expander patterns.
240169689Skan(define_code_macro COMPARE [eq ne gt gtu lt ltu ge geu le leu unordered 
241169689Skan		            ordered uneq unlt ungt unle unge ltgt])
242107590Sobrien
243169689Skan;; This macro allows to unify all 'sCOND' patterns.
244169689Skan(define_code_macro SCOND [ltu gtu leu geu])
245107590Sobrien
246169689Skan;; This macro allows some 'ashift' and 'lshiftrt' pattern to be defined from
247169689Skan;; the same template.
248169689Skan(define_code_macro SHIFT [ashift lshiftrt])
249107590Sobrien
250169689Skan;; These macros allow to combine most atomic operations.
251169689Skan(define_code_macro ATOMIC [and ior xor plus minus mult])
252169689Skan(define_code_attr atomic [(and "and") (ior "ior") (xor "xor") 
253169689Skan			  (plus "add") (minus "sub") (mult "nand")])
254132718Skan
255107590Sobrien
256169689Skan;; In FPR templates, a string like "lt<de>br" will expand to "ltxbr" in TFmode,
257169689Skan;; "ltdbr" in DFmode, and "ltebr" in SFmode.
258169689Skan(define_mode_attr xde [(TF "x") (DF "d") (SF "e")])
259107590Sobrien
260169689Skan;; In FPR templates, a string like "m<dee>br" will expand to "mxbr" in TFmode,
261169689Skan;; "mdbr" in DFmode, and "meebr" in SFmode.
262169689Skan(define_mode_attr xdee [(TF "x") (DF "d") (SF "ee")])
263132718Skan
264169689Skan;; In FPR templates, "<RRe>" will expand to "RRE" in TFmode and "RR" otherwise.
265169689Skan;; Likewise for "<RXe>".
266169689Skan(define_mode_attr RRe [(TF "RRE") (DF "RR") (SF "RR")])
267169689Skan(define_mode_attr RXe [(TF "RXE") (DF "RX") (SF "RX")])
268132718Skan
269169689Skan;; In FPR templates, "<Rf>" will expand to "f" in TFmode and "R" otherwise.
270169689Skan;; This is used to disable the memory alternative in TFmode patterns.
271169689Skan(define_mode_attr Rf [(TF "f") (DF "R") (SF "R")])
272132718Skan
273169689Skan;; In GPR and P templates, a constraint like "<d0>" will expand to "d" in DImode
274169689Skan;; and "0" in SImode. This allows to combine instructions of which the 31bit
275169689Skan;; version only operates on one register.
276169689Skan(define_mode_attr d0 [(DI "d") (SI "0")])
277132718Skan
278169689Skan;; In combination with d0 this allows to combine instructions of which the 31bit
279169689Skan;; version only operates on one register. The DImode version needs an additional
280169689Skan;; register for the assembler output.
281169689Skan(define_mode_attr 1 [(DI "%1,") (SI "")])
282169689Skan  
283169689Skan;; In SHIFT templates, a string like "s<lr>dl" will expand to "sldl" in 
284169689Skan;; 'ashift' and "srdl" in 'lshiftrt'.
285169689Skan(define_code_attr lr [(ashift "l") (lshiftrt "r")])
286132718Skan
287169689Skan;; In SHIFT templates, this attribute holds the correct standard name for the
288169689Skan;; pattern itself and the corresponding function calls. 
289169689Skan(define_code_attr shift [(ashift "ashl") (lshiftrt "lshr")])
290107590Sobrien
291169689Skan;; This attribute handles differences in the instruction 'type' and will result
292169689Skan;; in "RRE" for DImode and "RR" for SImode.
293169689Skan(define_mode_attr E [(DI "E") (SI "")])
294107590Sobrien
295169689Skan;; This attribute handles differences in the instruction 'type' and makes RX<Y>
296169689Skan;; to result in "RXY" for DImode and "RX" for SImode.
297169689Skan(define_mode_attr Y [(DI "Y") (SI "")])
298107590Sobrien
299169689Skan;; This attribute handles differences in the instruction 'type' and will result
300169689Skan;; in "RSE" for TImode and "RS" for DImode.
301169689Skan(define_mode_attr TE [(TI "E") (DI "")])
302107590Sobrien
303169689Skan;; In GPR templates, a string like "lc<g>r" will expand to "lcgr" in DImode
304169689Skan;; and "lcr" in SImode.
305169689Skan(define_mode_attr g [(DI "g") (SI "")])
306107590Sobrien
307169689Skan;; In GPR templates, a string like "sl<y>" will expand to "slg" in DImode
308169689Skan;; and "sly" in SImode. This is useful because on 64bit the ..g instructions
309169689Skan;; were enhanced with long displacements whereas 31bit instructions got a ..y
310169689Skan;; variant for long displacements.
311169689Skan(define_mode_attr y [(DI "g") (SI "y")])
312107590Sobrien
313169689Skan;; In DP templates, a string like "cds<g>" will expand to "cdsg" in TImode
314169689Skan;; and "cds" in DImode.
315169689Skan(define_mode_attr tg [(TI "g") (DI "")])
316107590Sobrien
317169689Skan;; In GPR templates, a string like "c<gf>dbr" will expand to "cgdbr" in DImode
318169689Skan;; and "cfdbr" in SImode.
319169689Skan(define_mode_attr gf [(DI "g") (SI "f")])
320107590Sobrien
321169689Skan;; ICM mask required to load MODE value into the lowest subreg
322169689Skan;; of a SImode register.
323169689Skan(define_mode_attr icm_lo [(HI "3") (QI "1")])
324107590Sobrien
325169689Skan;; In HQI templates, a string like "llg<hc>" will expand to "llgh" in
326169689Skan;; HImode and "llgc" in QImode.
327169689Skan(define_mode_attr hc [(HI "h") (QI "c")])
328132718Skan
329169689Skan;; In P templates, the mode <DBL> will expand to "TI" in DImode and "DI"
330169689Skan;; in SImode.
331169689Skan(define_mode_attr DBL [(DI "TI") (SI "DI")])
332132718Skan
333169689Skan;; Maximum unsigned integer that fits in MODE.
334169689Skan(define_mode_attr max_uint [(HI "65535") (QI "255")])
335107590Sobrien
336107590Sobrien
337107590Sobrien;;
338107590Sobrien;;- Compare instructions.
339107590Sobrien;;
340107590Sobrien
341169689Skan(define_expand "cmp<mode>"
342169689Skan  [(set (reg:CC CC_REGNUM)
343169689Skan        (compare:CC (match_operand:GPR 0 "register_operand" "")
344169689Skan                    (match_operand:GPR 1 "general_operand" "")))]
345107590Sobrien  ""
346107590Sobrien{
347107590Sobrien  s390_compare_op0 = operands[0];
348107590Sobrien  s390_compare_op1 = operands[1];
349107590Sobrien  DONE;
350132718Skan})
351107590Sobrien
352169689Skan(define_expand "cmp<mode>"
353169689Skan  [(set (reg:CC CC_REGNUM)
354169689Skan        (compare:CC (match_operand:FPR 0 "register_operand" "")
355169689Skan                    (match_operand:FPR 1 "general_operand" "")))]
356107590Sobrien  "TARGET_HARD_FLOAT"
357107590Sobrien{
358107590Sobrien  s390_compare_op0 = operands[0];
359107590Sobrien  s390_compare_op1 = operands[1];
360107590Sobrien  DONE;
361132718Skan})
362107590Sobrien
363107590Sobrien
364117395Skan; Test-under-Mask instructions
365117395Skan
366117395Skan(define_insn "*tmqi_mem"
367169689Skan  [(set (reg CC_REGNUM)
368169689Skan        (compare (and:QI (match_operand:QI 0 "memory_operand" "Q,S")
369169689Skan                         (match_operand:QI 1 "immediate_operand" "n,n"))
370169689Skan                 (match_operand:QI 2 "immediate_operand" "n,n")))]
371169689Skan  "s390_match_ccmode (insn, s390_tm_ccmode (operands[1], operands[2], false))"
372132718Skan  "@
373169689Skan   tm\t%S0,%b1
374169689Skan   tmy\t%S0,%b1"
375132718Skan  [(set_attr "op_type" "SI,SIY")])
376107590Sobrien
377117395Skan(define_insn "*tmdi_reg"
378169689Skan  [(set (reg CC_REGNUM)
379132718Skan        (compare (and:DI (match_operand:DI 0 "nonimmediate_operand" "d,d,d,d")
380169689Skan                         (match_operand:DI 1 "immediate_operand"
381132718Skan					     "N0HD0,N1HD0,N2HD0,N3HD0"))
382132718Skan                 (match_operand:DI 2 "immediate_operand" "n,n,n,n")))]
383117395Skan  "TARGET_64BIT
384169689Skan   && s390_match_ccmode (insn, s390_tm_ccmode (operands[1], operands[2], true))
385132718Skan   && s390_single_part (operands[1], DImode, HImode, 0) >= 0"
386132718Skan  "@
387132718Skan   tmhh\t%0,%i1
388132718Skan   tmhl\t%0,%i1
389132718Skan   tmlh\t%0,%i1
390132718Skan   tmll\t%0,%i1"
391107590Sobrien  [(set_attr "op_type" "RI")])
392107590Sobrien
393117395Skan(define_insn "*tmsi_reg"
394169689Skan  [(set (reg CC_REGNUM)
395132718Skan        (compare (and:SI (match_operand:SI 0 "nonimmediate_operand" "d,d")
396132718Skan                         (match_operand:SI 1 "immediate_operand" "N0HS0,N1HS0"))
397132718Skan                 (match_operand:SI 2 "immediate_operand" "n,n")))]
398169689Skan  "s390_match_ccmode (insn, s390_tm_ccmode (operands[1], operands[2], true))
399132718Skan   && s390_single_part (operands[1], SImode, HImode, 0) >= 0"
400132718Skan  "@
401132718Skan   tmh\t%0,%i1
402132718Skan   tml\t%0,%i1"
403107590Sobrien  [(set_attr "op_type" "RI")])
404107590Sobrien
405169689Skan(define_insn "*tm<mode>_full"
406169689Skan  [(set (reg CC_REGNUM)
407169689Skan        (compare (match_operand:HQI 0 "register_operand" "d")
408169689Skan                 (match_operand:HQI 1 "immediate_operand" "n")))]
409169689Skan  "s390_match_ccmode (insn, s390_tm_ccmode (constm1_rtx, operands[1], true))"
410169689Skan  "tml\t%0,<max_uint>"
411117395Skan  [(set_attr "op_type" "RI")])
412107590Sobrien
413117395Skan
414169689Skan;
415117395Skan; Load-and-Test instructions
416169689Skan;
417117395Skan
418169689Skan; tst(di|si) instruction pattern(s).
419169689Skan
420117395Skan(define_insn "*tstdi_sign"
421169689Skan  [(set (reg CC_REGNUM)
422117395Skan        (compare (ashiftrt:DI (ashift:DI (subreg:DI (match_operand:SI 0 "register_operand" "d") 0)
423117395Skan					 (const_int 32)) (const_int 32))
424117395Skan                 (match_operand:DI 1 "const0_operand" "")))
425117395Skan   (set (match_operand:DI 2 "register_operand" "=d")
426117395Skan        (sign_extend:DI (match_dup 0)))]
427117395Skan  "s390_match_ccmode(insn, CCSmode) && TARGET_64BIT"
428132718Skan  "ltgfr\t%2,%0"
429117395Skan  [(set_attr "op_type" "RRE")])
430117395Skan
431169689Skan; ltr, lt, ltgr, ltg
432169689Skan(define_insn "*tst<mode>_extimm"
433169689Skan  [(set (reg CC_REGNUM)
434169689Skan        (compare (match_operand:GPR 0 "nonimmediate_operand" "d,m")
435169689Skan                 (match_operand:GPR 1 "const0_operand" "")))
436169689Skan   (set (match_operand:GPR 2 "register_operand" "=d,d")
437169689Skan        (match_dup 0))]
438169689Skan  "s390_match_ccmode(insn, CCSmode) && TARGET_EXTIMM"
439169689Skan  "@
440169689Skan   lt<g>r\t%2,%0
441169689Skan   lt<g>\t%2,%0"
442169689Skan  [(set_attr "op_type" "RR<E>,RXY")])
443169689Skan
444169689Skan; ltr, lt, ltgr, ltg
445169689Skan(define_insn "*tst<mode>_cconly_extimm"
446169689Skan  [(set (reg CC_REGNUM)
447169689Skan        (compare (match_operand:GPR 0 "nonimmediate_operand" "d,m")
448169689Skan                 (match_operand:GPR 1 "const0_operand" "")))
449169689Skan   (clobber (match_scratch:GPR 2 "=X,d"))]
450169689Skan  "s390_match_ccmode(insn, CCSmode) && TARGET_EXTIMM"
451169689Skan  "@
452169689Skan   lt<g>r\t%0,%0
453169689Skan   lt<g>\t%2,%0"
454169689Skan  [(set_attr "op_type" "RR<E>,RXY")])
455169689Skan
456117395Skan(define_insn "*tstdi"
457169689Skan  [(set (reg CC_REGNUM)
458117395Skan        (compare (match_operand:DI 0 "register_operand" "d")
459117395Skan                 (match_operand:DI 1 "const0_operand" "")))
460117395Skan   (set (match_operand:DI 2 "register_operand" "=d")
461107590Sobrien        (match_dup 0))]
462169689Skan  "s390_match_ccmode(insn, CCSmode) && TARGET_64BIT && !TARGET_EXTIMM"
463132718Skan  "ltgr\t%2,%0"
464117395Skan  [(set_attr "op_type" "RRE")])
465107590Sobrien
466117395Skan(define_insn "*tstsi"
467169689Skan  [(set (reg CC_REGNUM)
468132718Skan        (compare (match_operand:SI 0 "nonimmediate_operand" "d,Q,S")
469107590Sobrien                 (match_operand:SI 1 "const0_operand" "")))
470132718Skan   (set (match_operand:SI 2 "register_operand" "=d,d,d")
471107590Sobrien        (match_dup 0))]
472169689Skan  "s390_match_ccmode(insn, CCSmode) && !TARGET_EXTIMM"
473117395Skan  "@
474132718Skan   ltr\t%2,%0
475169689Skan   icm\t%2,15,%S0
476169689Skan   icmy\t%2,15,%S0"
477132718Skan  [(set_attr "op_type" "RR,RS,RSY")])
478107590Sobrien
479117395Skan(define_insn "*tstsi_cconly"
480169689Skan  [(set (reg CC_REGNUM)
481132718Skan        (compare (match_operand:SI 0 "nonimmediate_operand" "d,Q,S")
482107590Sobrien                 (match_operand:SI 1 "const0_operand" "")))
483132718Skan   (clobber (match_scratch:SI 2 "=X,d,d"))]
484107590Sobrien  "s390_match_ccmode(insn, CCSmode)"
485117395Skan  "@
486132718Skan   ltr\t%0,%0
487169689Skan   icm\t%2,15,%S0
488169689Skan   icmy\t%2,15,%S0"
489132718Skan  [(set_attr "op_type" "RR,RS,RSY")])
490107590Sobrien
491169689Skan(define_insn "*tstdi_cconly_31"
492169689Skan  [(set (reg CC_REGNUM)
493169689Skan        (compare (match_operand:DI 0 "register_operand" "d")
494169689Skan                 (match_operand:DI 1 "const0_operand" "")))]
495169689Skan  "s390_match_ccmode(insn, CCSmode) && !TARGET_64BIT"
496169689Skan  "srda\t%0,0"
497169689Skan  [(set_attr "op_type" "RS")
498169689Skan   (set_attr "atype"   "reg")])
499169689Skan
500169689Skan; ltr, ltgr
501169689Skan(define_insn "*tst<mode>_cconly2"
502169689Skan  [(set (reg CC_REGNUM)
503169689Skan        (compare (match_operand:GPR 0 "register_operand" "d")
504169689Skan                 (match_operand:GPR 1 "const0_operand" "")))]
505107590Sobrien  "s390_match_ccmode(insn, CCSmode)"
506169689Skan  "lt<g>r\t%0,%0"
507169689Skan  [(set_attr "op_type" "RR<E>")])
508107590Sobrien
509169689Skan; tst(hi|qi) instruction pattern(s).
510169689Skan
511169689Skan(define_insn "*tst<mode>CCT"
512169689Skan  [(set (reg CC_REGNUM)
513169689Skan        (compare (match_operand:HQI 0 "nonimmediate_operand" "?Q,?S,d")
514169689Skan                 (match_operand:HQI 1 "const0_operand" "")))
515169689Skan   (set (match_operand:HQI 2 "register_operand" "=d,d,0")
516117395Skan        (match_dup 0))]
517117395Skan  "s390_match_ccmode(insn, CCTmode)"
518117395Skan  "@
519169689Skan   icm\t%2,<icm_lo>,%S0
520169689Skan   icmy\t%2,<icm_lo>,%S0
521169689Skan   tml\t%0,<max_uint>"
522132718Skan  [(set_attr "op_type" "RS,RSY,RI")])
523107590Sobrien
524117395Skan(define_insn "*tsthiCCT_cconly"
525169689Skan  [(set (reg CC_REGNUM)
526132718Skan        (compare (match_operand:HI 0 "nonimmediate_operand" "Q,S,d")
527117395Skan                 (match_operand:HI 1 "const0_operand" "")))
528132718Skan   (clobber (match_scratch:HI 2 "=d,d,X"))]
529117395Skan  "s390_match_ccmode(insn, CCTmode)"
530107590Sobrien  "@
531169689Skan   icm\t%2,3,%S0
532169689Skan   icmy\t%2,3,%S0
533132718Skan   tml\t%0,65535"
534132718Skan  [(set_attr "op_type" "RS,RSY,RI")])
535107590Sobrien
536117395Skan(define_insn "*tstqiCCT_cconly"
537169689Skan  [(set (reg CC_REGNUM)
538132718Skan        (compare (match_operand:QI 0 "nonimmediate_operand" "?Q,?S,d")
539117395Skan                 (match_operand:QI 1 "const0_operand" "")))]
540117395Skan  "s390_match_ccmode(insn, CCTmode)"
541117395Skan  "@
542169689Skan   cli\t%S0,0
543169689Skan   cliy\t%S0,0
544132718Skan   tml\t%0,255"
545132718Skan  [(set_attr "op_type" "SI,SIY,RI")])
546117395Skan
547169689Skan(define_insn "*tst<mode>"
548169689Skan  [(set (reg CC_REGNUM)
549169689Skan        (compare (match_operand:HQI 0 "s_operand" "Q,S")
550169689Skan                 (match_operand:HQI 1 "const0_operand" "")))
551169689Skan   (set (match_operand:HQI 2 "register_operand" "=d,d")
552117395Skan        (match_dup 0))]
553117395Skan  "s390_match_ccmode(insn, CCSmode)"
554132718Skan  "@
555169689Skan   icm\t%2,<icm_lo>,%S0
556169689Skan   icmy\t%2,<icm_lo>,%S0"
557132718Skan  [(set_attr "op_type" "RS,RSY")])
558107590Sobrien
559169689Skan(define_insn "*tst<mode>_cconly"
560169689Skan  [(set (reg CC_REGNUM)
561169689Skan        (compare (match_operand:HQI 0 "s_operand" "Q,S")
562169689Skan                 (match_operand:HQI 1 "const0_operand" "")))
563169689Skan   (clobber (match_scratch:HQI 2 "=d,d"))]
564117395Skan  "s390_match_ccmode(insn, CCSmode)"
565132718Skan  "@
566169689Skan   icm\t%2,<icm_lo>,%S0
567169689Skan   icmy\t%2,<icm_lo>,%S0"
568132718Skan  [(set_attr "op_type" "RS,RSY")])
569107590Sobrien
570107590Sobrien
571169689Skan; Compare (equality) instructions
572169689Skan
573169689Skan(define_insn "*cmpdi_cct"
574169689Skan  [(set (reg CC_REGNUM)
575169689Skan        (compare (match_operand:DI 0 "nonimmediate_operand" "%d,d,d,d,Q")
576169689Skan                 (match_operand:DI 1 "general_operand" "d,K,Os,m,BQ")))]
577169689Skan  "s390_match_ccmode (insn, CCTmode) && TARGET_64BIT"
578169689Skan  "@
579169689Skan   cgr\t%0,%1
580169689Skan   cghi\t%0,%h1
581169689Skan   cgfi\t%0,%1
582169689Skan   cg\t%0,%1
583169689Skan   #"
584169689Skan  [(set_attr "op_type" "RRE,RI,RIL,RXY,SS")])
585169689Skan
586169689Skan(define_insn "*cmpsi_cct"
587169689Skan  [(set (reg CC_REGNUM)
588169689Skan        (compare (match_operand:SI 0 "nonimmediate_operand" "%d,d,d,d,d,Q")
589169689Skan                 (match_operand:SI 1 "general_operand" "d,K,Os,R,T,BQ")))]
590169689Skan  "s390_match_ccmode (insn, CCTmode)"
591169689Skan  "@
592169689Skan   cr\t%0,%1
593169689Skan   chi\t%0,%h1
594169689Skan   cfi\t%0,%1
595169689Skan   c\t%0,%1
596169689Skan   cy\t%0,%1
597169689Skan   #"
598169689Skan  [(set_attr "op_type" "RR,RI,RIL,RX,RXY,SS")])
599169689Skan
600169689Skan
601117395Skan; Compare (signed) instructions
602107590Sobrien
603117395Skan(define_insn "*cmpdi_ccs_sign"
604169689Skan  [(set (reg CC_REGNUM)
605117395Skan        (compare (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "d,m"))
606117395Skan                 (match_operand:DI 0 "register_operand" "d,d")))]
607117395Skan  "s390_match_ccmode(insn, CCSRmode) && TARGET_64BIT"
608107590Sobrien  "@
609132718Skan   cgfr\t%0,%1
610132718Skan   cgf\t%0,%1"
611132718Skan  [(set_attr "op_type" "RRE,RXY")])
612107590Sobrien
613117395Skan(define_insn "*cmpsi_ccs_sign"
614169689Skan  [(set (reg CC_REGNUM)
615132718Skan        (compare (sign_extend:SI (match_operand:HI 1 "memory_operand" "R,T"))
616132718Skan                 (match_operand:SI 0 "register_operand" "d,d")))]
617117395Skan  "s390_match_ccmode(insn, CCSRmode)"
618132718Skan  "@
619132718Skan   ch\t%0,%1
620132718Skan   chy\t%0,%1"
621132718Skan  [(set_attr "op_type" "RX,RXY")])
622107590Sobrien
623169689Skan; cr, chi, cfi, c, cy, cgr, cghi, cgfi, cg
624169689Skan(define_insn "*cmp<mode>_ccs"
625169689Skan  [(set (reg CC_REGNUM)
626169689Skan        (compare (match_operand:GPR 0 "register_operand" "d,d,d,d,d")
627169689Skan                 (match_operand:GPR 1 "general_operand" "d,K,Os,R,T")))]
628107590Sobrien  "s390_match_ccmode(insn, CCSmode)"
629117395Skan  "@
630169689Skan   c<g>r\t%0,%1
631169689Skan   c<g>hi\t%0,%h1
632169689Skan   c<g>fi\t%0,%1
633169689Skan   c<g>\t%0,%1
634169689Skan   c<y>\t%0,%1"
635169689Skan  [(set_attr "op_type" "RR<E>,RI,RIL,RX<Y>,RXY")])
636107590Sobrien
637132718Skan
638117395Skan; Compare (unsigned) instructions
639117395Skan
640117395Skan(define_insn "*cmpdi_ccu_zero"
641169689Skan  [(set (reg CC_REGNUM)
642117395Skan        (compare (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "d,m"))
643117395Skan                 (match_operand:DI 0 "register_operand" "d,d")))]
644169689Skan  "s390_match_ccmode (insn, CCURmode) && TARGET_64BIT"
645117395Skan  "@
646132718Skan   clgfr\t%0,%1
647132718Skan   clgf\t%0,%1"
648132718Skan  [(set_attr "op_type" "RRE,RXY")])
649107590Sobrien
650117395Skan(define_insn "*cmpdi_ccu"
651169689Skan  [(set (reg CC_REGNUM)
652169689Skan        (compare (match_operand:DI 0 "nonimmediate_operand" "d,d,d,Q,BQ")
653169689Skan                 (match_operand:DI 1 "general_operand" "d,Op,m,BQ,Q")))]
654169689Skan  "s390_match_ccmode (insn, CCUmode) && TARGET_64BIT"
655117395Skan  "@
656132718Skan   clgr\t%0,%1
657169689Skan   clgfi\t%0,%1
658169689Skan   clg\t%0,%1
659169689Skan   #
660169689Skan   #"
661169689Skan  [(set_attr "op_type" "RRE,RIL,RXY,SS,SS")])
662107590Sobrien
663117395Skan(define_insn "*cmpsi_ccu"
664169689Skan  [(set (reg CC_REGNUM)
665169689Skan        (compare (match_operand:SI 0 "nonimmediate_operand" "d,d,d,d,Q,BQ")
666169689Skan                 (match_operand:SI 1 "general_operand" "d,Os,R,T,BQ,Q")))]
667169689Skan  "s390_match_ccmode (insn, CCUmode)"
668117395Skan  "@
669132718Skan   clr\t%0,%1
670169689Skan   clfi\t%0,%o1
671132718Skan   cl\t%0,%1
672169689Skan   cly\t%0,%1
673169689Skan   #
674169689Skan   #"
675169689Skan  [(set_attr "op_type" "RR,RIL,RX,RXY,SS,SS")])
676107590Sobrien
677117395Skan(define_insn "*cmphi_ccu"
678169689Skan  [(set (reg CC_REGNUM)
679169689Skan        (compare (match_operand:HI 0 "nonimmediate_operand" "d,d,Q,BQ")
680169689Skan                 (match_operand:HI 1 "general_operand" "Q,S,BQ,Q")))]
681169689Skan  "s390_match_ccmode (insn, CCUmode)
682169689Skan   && !register_operand (operands[1], HImode)"
683132718Skan  "@
684169689Skan   clm\t%0,3,%S1
685169689Skan   clmy\t%0,3,%S1
686169689Skan   #
687169689Skan   #"
688169689Skan  [(set_attr "op_type" "RS,RSY,SS,SS")])
689107590Sobrien
690107590Sobrien(define_insn "*cmpqi_ccu"
691169689Skan  [(set (reg CC_REGNUM)
692169689Skan        (compare (match_operand:QI 0 "nonimmediate_operand" "d,d,Q,S,Q,BQ")
693169689Skan                 (match_operand:QI 1 "general_operand" "Q,S,n,n,BQ,Q")))]
694169689Skan  "s390_match_ccmode (insn, CCUmode)
695169689Skan   && !register_operand (operands[1], QImode)"
696132718Skan  "@
697169689Skan   clm\t%0,1,%S1
698169689Skan   clmy\t%0,1,%S1
699169689Skan   cli\t%S0,%b1
700169689Skan   cliy\t%S0,%b1
701169689Skan   #
702169689Skan   #"
703169689Skan  [(set_attr "op_type" "RS,RSY,SI,SIY,SS,SS")])
704107590Sobrien
705107590Sobrien
706169689Skan; Block compare (CLC) instruction patterns.
707117395Skan
708169689Skan(define_insn "*clc"
709169689Skan  [(set (reg CC_REGNUM)
710169689Skan        (compare (match_operand:BLK 0 "memory_operand" "Q")
711169689Skan                 (match_operand:BLK 1 "memory_operand" "Q")))
712169689Skan   (use (match_operand 2 "const_int_operand" "n"))]
713169689Skan  "s390_match_ccmode (insn, CCUmode)
714169689Skan   && INTVAL (operands[2]) >= 1 && INTVAL (operands[2]) <= 256"
715169689Skan  "clc\t%O0(%2,%R0),%S1"
716132718Skan  [(set_attr "op_type" "SS")])
717117395Skan
718169689Skan(define_split
719169689Skan  [(set (reg CC_REGNUM)
720169689Skan        (compare (match_operand 0 "memory_operand" "")
721169689Skan                 (match_operand 1 "memory_operand" "")))]
722169689Skan  "reload_completed
723169689Skan   && s390_match_ccmode (insn, CCUmode)
724169689Skan   && GET_MODE (operands[0]) == GET_MODE (operands[1])
725169689Skan   && GET_MODE_SIZE (GET_MODE (operands[0])) > 0"
726169689Skan  [(parallel
727169689Skan    [(set (match_dup 0) (match_dup 1))
728169689Skan     (use (match_dup 2))])]
729169689Skan{
730169689Skan  operands[2] = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[0])));
731169689Skan  operands[0] = adjust_address (operands[0], BLKmode, 0);
732169689Skan  operands[1] = adjust_address (operands[1], BLKmode, 0);
733107590Sobrien
734169689Skan  operands[1] = gen_rtx_COMPARE (GET_MODE (SET_DEST (PATTERN (curr_insn))),
735169689Skan				 operands[0], operands[1]);
736169689Skan  operands[0] = SET_DEST (PATTERN (curr_insn));
737169689Skan})
738107590Sobrien
739107590Sobrien
740169689Skan; (DF|SF) instructions
741107590Sobrien
742169689Skan; ltxbr, ltdbr, ltebr
743169689Skan(define_insn "*cmp<mode>_ccs_0"
744169689Skan  [(set (reg CC_REGNUM)
745169689Skan        (compare (match_operand:FPR 0 "register_operand" "f")
746169689Skan                 (match_operand:FPR 1 "const0_operand" "")))]
747107590Sobrien  "s390_match_ccmode(insn, CCSmode) && TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT"
748169689Skan  "lt<xde>br\t%0,%0"
749132718Skan   [(set_attr "op_type" "RRE")
750169689Skan    (set_attr "type"  "fsimp<mode>")])
751107590Sobrien
752169689Skan; ltxr, ltdr, lter
753169689Skan(define_insn "*cmp<mode>_ccs_0_ibm"
754169689Skan  [(set (reg CC_REGNUM)
755169689Skan        (compare (match_operand:FPR 0 "register_operand" "f")
756169689Skan                 (match_operand:FPR 1 "const0_operand" "")))]
757107590Sobrien  "s390_match_ccmode(insn, CCSmode) && TARGET_HARD_FLOAT && TARGET_IBM_FLOAT"
758169689Skan  "lt<xde>r\t%0,%0"
759169689Skan   [(set_attr "op_type" "<RRe>")
760169689Skan    (set_attr "type"  "fsimp<mode>")])
761107590Sobrien
762169689Skan; cxbr, cdbr, cebr, cxb, cdb, ceb
763169689Skan(define_insn "*cmp<mode>_ccs"
764169689Skan  [(set (reg CC_REGNUM)
765169689Skan        (compare (match_operand:FPR 0 "register_operand" "f,f")
766169689Skan                 (match_operand:FPR 1 "general_operand" "f,<Rf>")))]
767107590Sobrien  "s390_match_ccmode(insn, CCSmode) && TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT"
768107590Sobrien  "@
769169689Skan   c<xde>br\t%0,%1
770169689Skan   c<xde>b\t%0,%1"
771132718Skan   [(set_attr "op_type" "RRE,RXE")
772169689Skan    (set_attr "type"  "fsimp<mode>")])
773107590Sobrien
774169689Skan; cxr, cdr, cer, cx, cd, ce
775169689Skan(define_insn "*cmp<mode>_ccs_ibm"
776169689Skan  [(set (reg CC_REGNUM)
777169689Skan        (compare (match_operand:FPR 0 "register_operand" "f,f")
778169689Skan                 (match_operand:FPR 1 "general_operand" "f,<Rf>")))]
779107590Sobrien  "s390_match_ccmode(insn, CCSmode) && TARGET_HARD_FLOAT && TARGET_IBM_FLOAT"
780107590Sobrien  "@
781169689Skan   c<xde>r\t%0,%1
782169689Skan   c<xde>\t%0,%1"
783169689Skan   [(set_attr "op_type" "<RRe>,<RXe>")
784169689Skan    (set_attr "type"  "fsimp<mode>")])
785107590Sobrien
786107590Sobrien
787107590Sobrien;;
788107590Sobrien;;- Move instructions.
789107590Sobrien;;
790107590Sobrien
791107590Sobrien;
792107590Sobrien; movti instruction pattern(s).
793107590Sobrien;
794107590Sobrien
795107590Sobrien(define_insn "movti"
796132718Skan  [(set (match_operand:TI 0 "nonimmediate_operand" "=d,QS,d,o,Q")
797169689Skan        (match_operand:TI 1 "general_operand" "QS,d,dPm,d,Q"))]
798107590Sobrien  "TARGET_64BIT"
799107590Sobrien  "@
800169689Skan   lmg\t%0,%N0,%S1
801169689Skan   stmg\t%1,%N1,%S0
802107590Sobrien   #
803117395Skan   #
804169689Skan   #"
805169689Skan  [(set_attr "op_type" "RSY,RSY,*,*,SS")
806169689Skan   (set_attr "type" "lm,stm,*,*,*")])
807107590Sobrien
808107590Sobrien(define_split
809107590Sobrien  [(set (match_operand:TI 0 "nonimmediate_operand" "")
810107590Sobrien        (match_operand:TI 1 "general_operand" ""))]
811107590Sobrien  "TARGET_64BIT && reload_completed
812117395Skan   && s390_split_ok_p (operands[0], operands[1], TImode, 0)"
813107590Sobrien  [(set (match_dup 2) (match_dup 4))
814107590Sobrien   (set (match_dup 3) (match_dup 5))]
815107590Sobrien{
816117395Skan  operands[2] = operand_subword (operands[0], 0, 0, TImode);
817117395Skan  operands[3] = operand_subword (operands[0], 1, 0, TImode);
818117395Skan  operands[4] = operand_subword (operands[1], 0, 0, TImode);
819117395Skan  operands[5] = operand_subword (operands[1], 1, 0, TImode);
820117395Skan})
821107590Sobrien
822107590Sobrien(define_split
823117395Skan  [(set (match_operand:TI 0 "nonimmediate_operand" "")
824117395Skan        (match_operand:TI 1 "general_operand" ""))]
825117395Skan  "TARGET_64BIT && reload_completed
826117395Skan   && s390_split_ok_p (operands[0], operands[1], TImode, 1)"
827117395Skan  [(set (match_dup 2) (match_dup 4))
828117395Skan   (set (match_dup 3) (match_dup 5))]
829117395Skan{
830117395Skan  operands[2] = operand_subword (operands[0], 1, 0, TImode);
831117395Skan  operands[3] = operand_subword (operands[0], 0, 0, TImode);
832117395Skan  operands[4] = operand_subword (operands[1], 1, 0, TImode);
833117395Skan  operands[5] = operand_subword (operands[1], 0, 0, TImode);
834117395Skan})
835117395Skan
836117395Skan(define_split
837107590Sobrien  [(set (match_operand:TI 0 "register_operand" "")
838107590Sobrien        (match_operand:TI 1 "memory_operand" ""))]
839107590Sobrien  "TARGET_64BIT && reload_completed
840107590Sobrien   && !s_operand (operands[1], VOIDmode)"
841117395Skan  [(set (match_dup 0) (match_dup 1))]
842117395Skan{
843117395Skan  rtx addr = operand_subword (operands[0], 1, 0, TImode);
844117395Skan  s390_load_address (addr, XEXP (operands[1], 0));
845117395Skan  operands[1] = replace_equiv_address (operands[1], addr);
846117395Skan})
847107590Sobrien
848117395Skan(define_expand "reload_outti"
849146895Skan  [(parallel [(match_operand:TI 0 "" "")
850117395Skan              (match_operand:TI 1 "register_operand" "d")
851117395Skan              (match_operand:DI 2 "register_operand" "=&a")])]
852117395Skan  "TARGET_64BIT"
853117395Skan{
854169689Skan  gcc_assert (MEM_P (operands[0]));
855169689Skan  s390_load_address (operands[2], find_replacement (&XEXP (operands[0], 0)));
856117395Skan  operands[0] = replace_equiv_address (operands[0], operands[2]);
857117395Skan  emit_move_insn (operands[0], operands[1]);
858117395Skan  DONE;
859117395Skan})
860117395Skan
861107590Sobrien;
862107590Sobrien; movdi instruction pattern(s).
863107590Sobrien;
864107590Sobrien
865107590Sobrien(define_expand "movdi"
866107590Sobrien  [(set (match_operand:DI 0 "general_operand" "")
867107590Sobrien        (match_operand:DI 1 "general_operand" ""))]
868107590Sobrien  ""
869107590Sobrien{
870117395Skan  /* Handle symbolic constants.  */
871169689Skan  if (TARGET_64BIT
872169689Skan      && (SYMBOLIC_CONST (operands[1])
873169689Skan	  || (GET_CODE (operands[1]) == PLUS
874169689Skan	      && XEXP (operands[1], 0) == pic_offset_table_rtx
875169689Skan	      && SYMBOLIC_CONST (XEXP (operands[1], 1)))))
876117395Skan    emit_symbolic_move (operands);
877132718Skan})
878107590Sobrien
879107590Sobrien(define_insn "*movdi_larl"
880107590Sobrien  [(set (match_operand:DI 0 "register_operand" "=d")
881107590Sobrien        (match_operand:DI 1 "larl_operand" "X"))]
882107590Sobrien  "TARGET_64BIT
883117395Skan   && !FP_REG_P (operands[0])"
884132718Skan  "larl\t%0,%1"
885107590Sobrien   [(set_attr "op_type" "RIL")
886132718Skan    (set_attr "type"    "larl")])
887107590Sobrien
888169689Skan(define_insn "*movdi_64extimm"
889169689Skan  [(set (match_operand:DI 0 "nonimmediate_operand"
890169689Skan                            "=d,d,d,d,d,d,d,d,d,d,d,m,!*f,!*f,!*f,!R,!T,d,t,Q,t,?Q")
891169689Skan        (match_operand:DI 1 "general_operand"
892169689Skan                            "K,N0HD0,N1HD0,N2HD0,N3HD0,Os,N0SD0,N1SD0,L,d,m,d,*f,R,T,*f,*f,t,d,t,Q,?Q"))]
893169689Skan  "TARGET_64BIT && TARGET_EXTIMM"
894169689Skan  "@
895169689Skan   lghi\t%0,%h1
896169689Skan   llihh\t%0,%i1
897169689Skan   llihl\t%0,%i1
898169689Skan   llilh\t%0,%i1
899169689Skan   llill\t%0,%i1
900169689Skan   lgfi\t%0,%1
901169689Skan   llihf\t%0,%k1
902169689Skan   llilf\t%0,%k1
903169689Skan   lay\t%0,%a1
904169689Skan   lgr\t%0,%1
905169689Skan   lg\t%0,%1
906169689Skan   stg\t%1,%0
907169689Skan   ldr\t%0,%1
908169689Skan   ld\t%0,%1
909169689Skan   ldy\t%0,%1
910169689Skan   std\t%1,%0
911169689Skan   stdy\t%1,%0
912169689Skan   #
913169689Skan   #
914169689Skan   stam\t%1,%N1,%S0
915169689Skan   lam\t%0,%N0,%S1
916169689Skan   #"
917169689Skan  [(set_attr "op_type" "RI,RI,RI,RI,RI,RIL,RIL,RIL,RXY,RRE,RXY,RXY,
918169689Skan                        RR,RX,RXY,RX,RXY,*,*,RS,RS,SS")
919169689Skan   (set_attr "type" "*,*,*,*,*,*,*,*,la,lr,load,store,
920169689Skan                     floaddf,floaddf,floaddf,fstoredf,fstoredf,*,*,*,*,*")])
921169689Skan
922107590Sobrien(define_insn "*movdi_64"
923169689Skan  [(set (match_operand:DI 0 "nonimmediate_operand"
924169689Skan                            "=d,d,d,d,d,d,d,d,m,!*f,!*f,!*f,!R,!T,d,t,Q,t,?Q")
925169689Skan        (match_operand:DI 1 "general_operand"
926169689Skan                            "K,N0HD0,N1HD0,N2HD0,N3HD0,L,d,m,d,*f,R,T,*f,*f,t,d,t,Q,?Q"))]
927169689Skan  "TARGET_64BIT && !TARGET_EXTIMM"
928107590Sobrien  "@
929132718Skan   lghi\t%0,%h1
930132718Skan   llihh\t%0,%i1
931132718Skan   llihl\t%0,%i1
932132718Skan   llilh\t%0,%i1
933132718Skan   llill\t%0,%i1
934132718Skan   lay\t%0,%a1
935132718Skan   lgr\t%0,%1
936132718Skan   lg\t%0,%1
937132718Skan   stg\t%1,%0
938132718Skan   ldr\t%0,%1
939132718Skan   ld\t%0,%1
940132718Skan   ldy\t%0,%1
941132718Skan   std\t%1,%0
942132718Skan   stdy\t%1,%0
943169689Skan   #
944169689Skan   #
945169689Skan   stam\t%1,%N1,%S0
946169689Skan   lam\t%0,%N0,%S1
947169689Skan   #"
948169689Skan  [(set_attr "op_type" "RI,RI,RI,RI,RI,RXY,RRE,RXY,RXY,
949169689Skan                        RR,RX,RXY,RX,RXY,*,*,RS,RS,SS")
950169689Skan   (set_attr "type" "*,*,*,*,*,la,lr,load,store,
951169689Skan                     floaddf,floaddf,floaddf,fstoredf,fstoredf,*,*,*,*,*")])
952107590Sobrien
953169689Skan(define_split
954169689Skan  [(set (match_operand:DI 0 "register_operand" "")
955169689Skan        (match_operand:DI 1 "register_operand" ""))]
956169689Skan  "TARGET_64BIT && ACCESS_REG_P (operands[1])"
957169689Skan  [(set (match_dup 2) (match_dup 3))
958169689Skan   (set (match_dup 0) (ashift:DI (match_dup 0) (const_int 32)))
959169689Skan   (set (strict_low_part (match_dup 2)) (match_dup 4))]
960169689Skan  "operands[2] = gen_lowpart (SImode, operands[0]);
961169689Skan   s390_split_access_reg (operands[1], &operands[4], &operands[3]);")
962169689Skan
963169689Skan(define_split
964169689Skan  [(set (match_operand:DI 0 "register_operand" "")
965169689Skan        (match_operand:DI 1 "register_operand" ""))]
966169689Skan  "TARGET_64BIT && ACCESS_REG_P (operands[0])
967169689Skan   && dead_or_set_p (insn, operands[1])"
968169689Skan  [(set (match_dup 3) (match_dup 2))
969169689Skan   (set (match_dup 1) (lshiftrt:DI (match_dup 1) (const_int 32)))
970169689Skan   (set (match_dup 4) (match_dup 2))]
971169689Skan  "operands[2] = gen_lowpart (SImode, operands[1]);
972169689Skan   s390_split_access_reg (operands[0], &operands[3], &operands[4]);")
973169689Skan
974169689Skan(define_split
975169689Skan  [(set (match_operand:DI 0 "register_operand" "")
976169689Skan        (match_operand:DI 1 "register_operand" ""))]
977169689Skan  "TARGET_64BIT && ACCESS_REG_P (operands[0])
978169689Skan   && !dead_or_set_p (insn, operands[1])"
979169689Skan  [(set (match_dup 3) (match_dup 2))
980169689Skan   (set (match_dup 1) (rotate:DI (match_dup 1) (const_int 32)))
981169689Skan   (set (match_dup 4) (match_dup 2))
982169689Skan   (set (match_dup 1) (rotate:DI (match_dup 1) (const_int 32)))]
983169689Skan  "operands[2] = gen_lowpart (SImode, operands[1]);
984169689Skan   s390_split_access_reg (operands[0], &operands[3], &operands[4]);")
985169689Skan
986107590Sobrien(define_insn "*movdi_31"
987169689Skan  [(set (match_operand:DI 0 "nonimmediate_operand" "=d,d,Q,S,d,o,!*f,!*f,!*f,!R,!T,Q")
988169689Skan        (match_operand:DI 1 "general_operand" "Q,S,d,d,dPm,d,*f,R,T,*f,*f,Q"))]
989107590Sobrien  "!TARGET_64BIT"
990107590Sobrien  "@
991169689Skan   lm\t%0,%N0,%S1
992169689Skan   lmy\t%0,%N0,%S1
993169689Skan   stm\t%1,%N1,%S0
994169689Skan   stmy\t%1,%N1,%S0
995107590Sobrien   #
996107590Sobrien   #
997132718Skan   ldr\t%0,%1
998132718Skan   ld\t%0,%1
999132718Skan   ldy\t%0,%1
1000132718Skan   std\t%1,%0
1001132718Skan   stdy\t%1,%0
1002169689Skan   #"
1003169689Skan  [(set_attr "op_type" "RS,RSY,RS,RSY,*,*,RR,RX,RXY,RX,RXY,SS")
1004169689Skan   (set_attr "type" "lm,lm,stm,stm,*,*,floaddf,floaddf,floaddf,fstoredf,fstoredf,*")])
1005107590Sobrien
1006107590Sobrien(define_split
1007107590Sobrien  [(set (match_operand:DI 0 "nonimmediate_operand" "")
1008107590Sobrien        (match_operand:DI 1 "general_operand" ""))]
1009107590Sobrien  "!TARGET_64BIT && reload_completed
1010117395Skan   && s390_split_ok_p (operands[0], operands[1], DImode, 0)"
1011107590Sobrien  [(set (match_dup 2) (match_dup 4))
1012107590Sobrien   (set (match_dup 3) (match_dup 5))]
1013107590Sobrien{
1014117395Skan  operands[2] = operand_subword (operands[0], 0, 0, DImode);
1015117395Skan  operands[3] = operand_subword (operands[0], 1, 0, DImode);
1016117395Skan  operands[4] = operand_subword (operands[1], 0, 0, DImode);
1017117395Skan  operands[5] = operand_subword (operands[1], 1, 0, DImode);
1018117395Skan})
1019107590Sobrien
1020107590Sobrien(define_split
1021117395Skan  [(set (match_operand:DI 0 "nonimmediate_operand" "")
1022117395Skan        (match_operand:DI 1 "general_operand" ""))]
1023117395Skan  "!TARGET_64BIT && reload_completed
1024117395Skan   && s390_split_ok_p (operands[0], operands[1], DImode, 1)"
1025117395Skan  [(set (match_dup 2) (match_dup 4))
1026117395Skan   (set (match_dup 3) (match_dup 5))]
1027117395Skan{
1028117395Skan  operands[2] = operand_subword (operands[0], 1, 0, DImode);
1029117395Skan  operands[3] = operand_subword (operands[0], 0, 0, DImode);
1030117395Skan  operands[4] = operand_subword (operands[1], 1, 0, DImode);
1031117395Skan  operands[5] = operand_subword (operands[1], 0, 0, DImode);
1032117395Skan})
1033117395Skan
1034117395Skan(define_split
1035107590Sobrien  [(set (match_operand:DI 0 "register_operand" "")
1036107590Sobrien        (match_operand:DI 1 "memory_operand" ""))]
1037107590Sobrien  "!TARGET_64BIT && reload_completed
1038117395Skan   && !FP_REG_P (operands[0])
1039107590Sobrien   && !s_operand (operands[1], VOIDmode)"
1040117395Skan  [(set (match_dup 0) (match_dup 1))]
1041117395Skan{
1042117395Skan  rtx addr = operand_subword (operands[0], 1, 0, DImode);
1043117395Skan  s390_load_address (addr, XEXP (operands[1], 0));
1044117395Skan  operands[1] = replace_equiv_address (operands[1], addr);
1045117395Skan})
1046107590Sobrien
1047117395Skan(define_expand "reload_outdi"
1048146895Skan  [(parallel [(match_operand:DI 0 "" "")
1049117395Skan              (match_operand:DI 1 "register_operand" "d")
1050117395Skan              (match_operand:SI 2 "register_operand" "=&a")])]
1051117395Skan  "!TARGET_64BIT"
1052117395Skan{
1053169689Skan  gcc_assert (MEM_P (operands[0]));
1054169689Skan  s390_load_address (operands[2], find_replacement (&XEXP (operands[0], 0)));
1055117395Skan  operands[0] = replace_equiv_address (operands[0], operands[2]);
1056117395Skan  emit_move_insn (operands[0], operands[1]);
1057117395Skan  DONE;
1058117395Skan})
1059117395Skan
1060117395Skan(define_peephole2
1061117395Skan  [(set (match_operand:DI 0 "register_operand" "")
1062117395Skan        (mem:DI (match_operand 1 "address_operand" "")))]
1063117395Skan  "TARGET_64BIT
1064117395Skan   && !FP_REG_P (operands[0])
1065117395Skan   && GET_CODE (operands[1]) == SYMBOL_REF
1066117395Skan   && CONSTANT_POOL_ADDRESS_P (operands[1])
1067117395Skan   && get_pool_mode (operands[1]) == DImode
1068117395Skan   && legitimate_reload_constant_p (get_pool_constant (operands[1]))"
1069117395Skan  [(set (match_dup 0) (match_dup 2))]
1070117395Skan  "operands[2] = get_pool_constant (operands[1]);")
1071117395Skan
1072132718Skan(define_insn "*la_64"
1073132718Skan  [(set (match_operand:DI 0 "register_operand" "=d,d")
1074132718Skan        (match_operand:QI 1 "address_operand" "U,W"))]
1075132718Skan  "TARGET_64BIT"
1076132718Skan  "@
1077132718Skan   la\t%0,%a1
1078132718Skan   lay\t%0,%a1"
1079132718Skan  [(set_attr "op_type" "RX,RXY")
1080132718Skan   (set_attr "type"    "la")])
1081132718Skan
1082132718Skan(define_peephole2
1083132718Skan  [(parallel
1084132718Skan    [(set (match_operand:DI 0 "register_operand" "")
1085132718Skan          (match_operand:QI 1 "address_operand" ""))
1086169689Skan     (clobber (reg:CC CC_REGNUM))])]
1087132718Skan  "TARGET_64BIT
1088169689Skan   && preferred_la_operand_p (operands[1], const0_rtx)"
1089132718Skan  [(set (match_dup 0) (match_dup 1))]
1090132718Skan  "")
1091132718Skan
1092132718Skan(define_peephole2
1093132718Skan  [(set (match_operand:DI 0 "register_operand" "")
1094132718Skan        (match_operand:DI 1 "register_operand" ""))
1095132718Skan   (parallel
1096132718Skan    [(set (match_dup 0)
1097132718Skan          (plus:DI (match_dup 0)
1098132718Skan                   (match_operand:DI 2 "nonmemory_operand" "")))
1099169689Skan     (clobber (reg:CC CC_REGNUM))])]
1100132718Skan  "TARGET_64BIT
1101132718Skan   && !reg_overlap_mentioned_p (operands[0], operands[2])
1102169689Skan   && preferred_la_operand_p (operands[1], operands[2])"
1103132718Skan  [(set (match_dup 0) (plus:DI (match_dup 1) (match_dup 2)))]
1104132718Skan  "")
1105132718Skan
1106132718Skan(define_expand "reload_indi"
1107132718Skan  [(parallel [(match_operand:DI 0 "register_operand" "=a")
1108132718Skan              (match_operand:DI 1 "s390_plus_operand" "")
1109132718Skan              (match_operand:DI 2 "register_operand" "=&a")])]
1110132718Skan  "TARGET_64BIT"
1111132718Skan{
1112132718Skan  s390_expand_plus_operand (operands[0], operands[1], operands[2]);
1113132718Skan  DONE;
1114132718Skan})
1115132718Skan
1116107590Sobrien;
1117107590Sobrien; movsi instruction pattern(s).
1118107590Sobrien;
1119107590Sobrien
1120107590Sobrien(define_expand "movsi"
1121107590Sobrien  [(set (match_operand:SI 0 "general_operand" "")
1122107590Sobrien        (match_operand:SI 1 "general_operand" ""))]
1123107590Sobrien  ""
1124107590Sobrien{
1125117395Skan  /* Handle symbolic constants.  */
1126169689Skan  if (!TARGET_64BIT
1127169689Skan      && (SYMBOLIC_CONST (operands[1])
1128169689Skan	  || (GET_CODE (operands[1]) == PLUS
1129169689Skan	      && XEXP (operands[1], 0) == pic_offset_table_rtx
1130169689Skan	      && SYMBOLIC_CONST (XEXP(operands[1], 1)))))
1131117395Skan    emit_symbolic_move (operands);
1132132718Skan})
1133107590Sobrien
1134132718Skan(define_insn "*movsi_larl"
1135107590Sobrien  [(set (match_operand:SI 0 "register_operand" "=d")
1136132718Skan        (match_operand:SI 1 "larl_operand" "X"))]
1137132718Skan  "!TARGET_64BIT && TARGET_CPU_ZARCH
1138117395Skan   && !FP_REG_P (operands[0])"
1139132718Skan  "larl\t%0,%1"
1140132718Skan   [(set_attr "op_type" "RIL")
1141132718Skan    (set_attr "type"    "larl")])
1142107590Sobrien
1143132718Skan(define_insn "*movsi_zarch"
1144169689Skan  [(set (match_operand:SI 0 "nonimmediate_operand"
1145169689Skan			    "=d,d,d,d,d,d,d,d,R,T,!*f,!*f,!*f,!R,!T,d,t,Q,t,?Q")
1146169689Skan        (match_operand:SI 1 "general_operand"
1147169689Skan			    "K,N0HS0,N1HS0,Os,L,d,R,T,d,d,*f,R,T,*f,*f,t,d,t,Q,?Q"))]
1148132718Skan  "TARGET_ZARCH"
1149132718Skan  "@
1150132718Skan   lhi\t%0,%h1
1151132718Skan   llilh\t%0,%i1
1152132718Skan   llill\t%0,%i1
1153169689Skan   iilf\t%0,%o1
1154132718Skan   lay\t%0,%a1
1155132718Skan   lr\t%0,%1
1156132718Skan   l\t%0,%1
1157132718Skan   ly\t%0,%1
1158132718Skan   st\t%1,%0
1159132718Skan   sty\t%1,%0
1160132718Skan   ler\t%0,%1
1161132718Skan   le\t%0,%1
1162132718Skan   ley\t%0,%1
1163132718Skan   ste\t%1,%0
1164132718Skan   stey\t%1,%0
1165169689Skan   ear\t%0,%1
1166169689Skan   sar\t%0,%1
1167169689Skan   stam\t%1,%1,%S0
1168169689Skan   lam\t%0,%0,%S1
1169169689Skan   #"
1170169689Skan  [(set_attr "op_type" "RI,RI,RI,RIL,RXY,RR,RX,RXY,RX,RXY,
1171169689Skan                        RR,RX,RXY,RX,RXY,RRE,RRE,RS,RS,SS")
1172169689Skan   (set_attr "type" "*,*,*,*,la,lr,load,load,store,store,
1173169689Skan                     floadsf,floadsf,floadsf,fstoresf,fstoresf,*,*,*,*,*")])
1174107590Sobrien
1175132718Skan(define_insn "*movsi_esa"
1176169689Skan  [(set (match_operand:SI 0 "nonimmediate_operand" "=d,d,d,R,!*f,!*f,!R,d,t,Q,t,?Q")
1177169689Skan        (match_operand:SI 1 "general_operand" "K,d,R,d,*f,R,*f,t,d,t,Q,?Q"))]
1178132718Skan  "!TARGET_ZARCH"
1179107590Sobrien  "@
1180132718Skan   lhi\t%0,%h1
1181132718Skan   lr\t%0,%1
1182132718Skan   l\t%0,%1
1183132718Skan   st\t%1,%0
1184132718Skan   ler\t%0,%1
1185132718Skan   le\t%0,%1
1186132718Skan   ste\t%1,%0
1187169689Skan   ear\t%0,%1
1188169689Skan   sar\t%0,%1
1189169689Skan   stam\t%1,%1,%S0
1190169689Skan   lam\t%0,%0,%S1
1191169689Skan   #"
1192169689Skan  [(set_attr "op_type" "RI,RR,RX,RX,RR,RX,RX,RRE,RRE,RS,RS,SS")
1193169689Skan   (set_attr "type" "*,lr,load,store,floadsf,floadsf,fstoresf,*,*,*,*,*")])
1194107590Sobrien
1195117395Skan(define_peephole2
1196117395Skan  [(set (match_operand:SI 0 "register_operand" "")
1197117395Skan        (mem:SI (match_operand 1 "address_operand" "")))]
1198117395Skan  "!FP_REG_P (operands[0])
1199117395Skan   && GET_CODE (operands[1]) == SYMBOL_REF
1200117395Skan   && CONSTANT_POOL_ADDRESS_P (operands[1])
1201117395Skan   && get_pool_mode (operands[1]) == SImode
1202117395Skan   && legitimate_reload_constant_p (get_pool_constant (operands[1]))"
1203117395Skan  [(set (match_dup 0) (match_dup 2))]
1204117395Skan  "operands[2] = get_pool_constant (operands[1]);")
1205107590Sobrien
1206132718Skan(define_insn "*la_31"
1207132718Skan  [(set (match_operand:SI 0 "register_operand" "=d,d")
1208132718Skan        (match_operand:QI 1 "address_operand" "U,W"))]
1209132718Skan  "!TARGET_64BIT && legitimate_la_operand_p (operands[1])"
1210132718Skan  "@
1211132718Skan   la\t%0,%a1
1212132718Skan   lay\t%0,%a1"
1213132718Skan  [(set_attr "op_type"  "RX,RXY")
1214132718Skan   (set_attr "type"     "la")])
1215132718Skan
1216132718Skan(define_peephole2
1217132718Skan  [(parallel
1218132718Skan    [(set (match_operand:SI 0 "register_operand" "")
1219132718Skan          (match_operand:QI 1 "address_operand" ""))
1220169689Skan     (clobber (reg:CC CC_REGNUM))])]
1221132718Skan  "!TARGET_64BIT
1222169689Skan   && preferred_la_operand_p (operands[1], const0_rtx)"
1223132718Skan  [(set (match_dup 0) (match_dup 1))]
1224132718Skan  "")
1225132718Skan
1226132718Skan(define_peephole2
1227132718Skan  [(set (match_operand:SI 0 "register_operand" "")
1228132718Skan        (match_operand:SI 1 "register_operand" ""))
1229132718Skan   (parallel
1230132718Skan    [(set (match_dup 0)
1231132718Skan          (plus:SI (match_dup 0)
1232132718Skan                   (match_operand:SI 2 "nonmemory_operand" "")))
1233169689Skan     (clobber (reg:CC CC_REGNUM))])]
1234132718Skan  "!TARGET_64BIT
1235132718Skan   && !reg_overlap_mentioned_p (operands[0], operands[2])
1236169689Skan   && preferred_la_operand_p (operands[1], operands[2])"
1237132718Skan  [(set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))]
1238132718Skan  "")
1239132718Skan
1240132718Skan(define_insn "*la_31_and"
1241132718Skan  [(set (match_operand:SI 0 "register_operand" "=d,d")
1242132718Skan        (and:SI (match_operand:QI 1 "address_operand" "U,W")
1243132718Skan                (const_int 2147483647)))]
1244132718Skan  "!TARGET_64BIT"
1245132718Skan  "@
1246132718Skan   la\t%0,%a1
1247132718Skan   lay\t%0,%a1"
1248132718Skan  [(set_attr "op_type"  "RX,RXY")
1249132718Skan   (set_attr "type"     "la")])
1250132718Skan
1251132718Skan(define_insn_and_split "*la_31_and_cc"
1252132718Skan  [(set (match_operand:SI 0 "register_operand" "=d")
1253132718Skan        (and:SI (match_operand:QI 1 "address_operand" "p")
1254132718Skan                (const_int 2147483647)))
1255169689Skan   (clobber (reg:CC CC_REGNUM))]
1256132718Skan  "!TARGET_64BIT"
1257132718Skan  "#"
1258132718Skan  "&& reload_completed"
1259132718Skan  [(set (match_dup 0)
1260132718Skan        (and:SI (match_dup 1) (const_int 2147483647)))]
1261132718Skan  ""
1262132718Skan  [(set_attr "op_type"  "RX")
1263132718Skan   (set_attr "type"     "la")])
1264132718Skan
1265132718Skan(define_insn "force_la_31"
1266132718Skan  [(set (match_operand:SI 0 "register_operand" "=d,d")
1267132718Skan        (match_operand:QI 1 "address_operand" "U,W"))
1268132718Skan   (use (const_int 0))]
1269132718Skan  "!TARGET_64BIT"
1270132718Skan  "@
1271132718Skan   la\t%0,%a1
1272132718Skan   lay\t%0,%a1"
1273132718Skan  [(set_attr "op_type"  "RX")
1274132718Skan   (set_attr "type"     "la")])
1275132718Skan
1276132718Skan(define_expand "reload_insi"
1277132718Skan  [(parallel [(match_operand:SI 0 "register_operand" "=a")
1278132718Skan              (match_operand:SI 1 "s390_plus_operand" "")
1279132718Skan              (match_operand:SI 2 "register_operand" "=&a")])]
1280132718Skan  "!TARGET_64BIT"
1281132718Skan{
1282132718Skan  s390_expand_plus_operand (operands[0], operands[1], operands[2]);
1283132718Skan  DONE;
1284132718Skan})
1285132718Skan
1286107590Sobrien;
1287107590Sobrien; movhi instruction pattern(s).
1288107590Sobrien;
1289107590Sobrien
1290132718Skan(define_expand "movhi"
1291132718Skan  [(set (match_operand:HI 0 "nonimmediate_operand" "")
1292132718Skan        (match_operand:HI 1 "general_operand" ""))]
1293107590Sobrien  ""
1294132718Skan{
1295169689Skan  /* Make it explicit that loading a register from memory
1296132718Skan     always sign-extends (at least) to SImode.  */
1297132718Skan  if (optimize && !no_new_pseudos
1298132718Skan      && register_operand (operands[0], VOIDmode)
1299169689Skan      && GET_CODE (operands[1]) == MEM)
1300132718Skan    {
1301132718Skan      rtx tmp = gen_reg_rtx (SImode);
1302132718Skan      rtx ext = gen_rtx_SIGN_EXTEND (SImode, operands[1]);
1303132718Skan      emit_insn (gen_rtx_SET (VOIDmode, tmp, ext));
1304132718Skan      operands[1] = gen_lowpart (HImode, tmp);
1305132718Skan    }
1306132718Skan})
1307132718Skan
1308132718Skan(define_insn "*movhi"
1309132718Skan  [(set (match_operand:HI 0 "nonimmediate_operand" "=d,d,d,d,R,T,?Q")
1310132718Skan        (match_operand:HI 1 "general_operand" "d,n,R,T,d,d,?Q"))]
1311132718Skan  ""
1312107590Sobrien  "@
1313132718Skan   lr\t%0,%1
1314132718Skan   lhi\t%0,%h1
1315132718Skan   lh\t%0,%1
1316132718Skan   lhy\t%0,%1
1317132718Skan   sth\t%1,%0
1318132718Skan   sthy\t%1,%0
1319169689Skan   #"
1320132718Skan  [(set_attr "op_type" "RR,RI,RX,RXY,RX,RXY,SS")
1321169689Skan   (set_attr "type" "lr,*,*,*,store,store,*")])
1322107590Sobrien
1323117395Skan(define_peephole2
1324117395Skan  [(set (match_operand:HI 0 "register_operand" "")
1325117395Skan        (mem:HI (match_operand 1 "address_operand" "")))]
1326117395Skan  "GET_CODE (operands[1]) == SYMBOL_REF
1327117395Skan   && CONSTANT_POOL_ADDRESS_P (operands[1])
1328117395Skan   && get_pool_mode (operands[1]) == HImode
1329117395Skan   && GET_CODE (get_pool_constant (operands[1])) == CONST_INT"
1330117395Skan  [(set (match_dup 0) (match_dup 2))]
1331117395Skan  "operands[2] = get_pool_constant (operands[1]);")
1332107590Sobrien
1333107590Sobrien;
1334107590Sobrien; movqi instruction pattern(s).
1335107590Sobrien;
1336107590Sobrien
1337132718Skan(define_expand "movqi"
1338132718Skan  [(set (match_operand:QI 0 "nonimmediate_operand" "")
1339132718Skan        (match_operand:QI 1 "general_operand" ""))]
1340132718Skan  ""
1341132718Skan{
1342132718Skan  /* On z/Architecture, zero-extending from memory to register
1343132718Skan     is just as fast as a QImode load.  */
1344132718Skan  if (TARGET_ZARCH && optimize && !no_new_pseudos
1345132718Skan      && register_operand (operands[0], VOIDmode)
1346169689Skan      && GET_CODE (operands[1]) == MEM)
1347132718Skan    {
1348132718Skan      rtx tmp = gen_reg_rtx (word_mode);
1349132718Skan      rtx ext = gen_rtx_ZERO_EXTEND (word_mode, operands[1]);
1350132718Skan      emit_insn (gen_rtx_SET (VOIDmode, tmp, ext));
1351132718Skan      operands[1] = gen_lowpart (QImode, tmp);
1352132718Skan    }
1353132718Skan})
1354107590Sobrien
1355132718Skan(define_insn "*movqi"
1356132718Skan  [(set (match_operand:QI 0 "nonimmediate_operand" "=d,d,d,d,R,T,Q,S,?Q")
1357132718Skan        (match_operand:QI 1 "general_operand" "d,n,R,T,d,d,n,n,?Q"))]
1358107590Sobrien  ""
1359107590Sobrien  "@
1360132718Skan   lr\t%0,%1
1361132718Skan   lhi\t%0,%b1
1362132718Skan   ic\t%0,%1
1363132718Skan   icy\t%0,%1
1364132718Skan   stc\t%1,%0
1365132718Skan   stcy\t%1,%0
1366169689Skan   mvi\t%S0,%b1
1367169689Skan   mviy\t%S0,%b1
1368169689Skan   #"
1369132718Skan  [(set_attr "op_type" "RR,RI,RX,RXY,RX,RXY,SI,SIY,SS")
1370169689Skan   (set_attr "type" "lr,*,*,*,store,store,store,store,*")])
1371107590Sobrien
1372117395Skan(define_peephole2
1373117395Skan  [(set (match_operand:QI 0 "nonimmediate_operand" "")
1374117395Skan        (mem:QI (match_operand 1 "address_operand" "")))]
1375117395Skan  "GET_CODE (operands[1]) == SYMBOL_REF
1376117395Skan   && CONSTANT_POOL_ADDRESS_P (operands[1])
1377117395Skan   && get_pool_mode (operands[1]) == QImode
1378117395Skan   && GET_CODE (get_pool_constant (operands[1])) == CONST_INT"
1379117395Skan  [(set (match_dup 0) (match_dup 2))]
1380117395Skan  "operands[2] = get_pool_constant (operands[1]);")
1381107590Sobrien
1382107590Sobrien;
1383117395Skan; movstrictqi instruction pattern(s).
1384107590Sobrien;
1385107590Sobrien
1386107590Sobrien(define_insn "*movstrictqi"
1387132718Skan  [(set (strict_low_part (match_operand:QI 0 "register_operand" "+d,d"))
1388132718Skan                         (match_operand:QI 1 "memory_operand" "R,T"))]
1389107590Sobrien  ""
1390132718Skan  "@
1391132718Skan   ic\t%0,%1
1392132718Skan   icy\t%0,%1"
1393132718Skan  [(set_attr "op_type"  "RX,RXY")])
1394107590Sobrien
1395107590Sobrien;
1396107590Sobrien; movstricthi instruction pattern(s).
1397107590Sobrien;
1398107590Sobrien
1399107590Sobrien(define_insn "*movstricthi"
1400132718Skan  [(set (strict_low_part (match_operand:HI 0 "register_operand" "+d,d"))
1401169689Skan                         (match_operand:HI 1 "memory_operand" "Q,S"))
1402169689Skan   (clobber (reg:CC CC_REGNUM))]
1403107590Sobrien  ""
1404132718Skan  "@
1405169689Skan   icm\t%0,3,%S1
1406169689Skan   icmy\t%0,3,%S1"
1407132718Skan  [(set_attr "op_type" "RS,RSY")])
1408107590Sobrien
1409107590Sobrien;
1410107590Sobrien; movstrictsi instruction pattern(s).
1411107590Sobrien;
1412107590Sobrien
1413117395Skan(define_insn "movstrictsi"
1414169689Skan  [(set (strict_low_part (match_operand:SI 0 "register_operand" "+d,d,d,d"))
1415169689Skan                         (match_operand:SI 1 "general_operand" "d,R,T,t"))]
1416107590Sobrien  "TARGET_64BIT"
1417107590Sobrien  "@
1418132718Skan   lr\t%0,%1
1419132718Skan   l\t%0,%1
1420169689Skan   ly\t%0,%1
1421169689Skan   ear\t%0,%1"
1422169689Skan  [(set_attr "op_type" "RR,RX,RXY,RRE")
1423169689Skan   (set_attr "type" "lr,load,load,*")])
1424107590Sobrien
1425107590Sobrien;
1426169689Skan; movtf instruction pattern(s).
1427169689Skan;
1428169689Skan
1429169689Skan(define_expand "movtf"
1430169689Skan  [(set (match_operand:TF 0 "nonimmediate_operand" "")
1431169689Skan        (match_operand:TF 1 "general_operand"       ""))]
1432169689Skan  ""
1433169689Skan  "")
1434169689Skan
1435169689Skan(define_insn "*movtf_64"
1436169689Skan  [(set (match_operand:TF 0 "nonimmediate_operand" "=f,f,f,o,d,QS,d,o,Q")
1437169689Skan        (match_operand:TF 1 "general_operand"       "G,f,o,f,QS,d,dm,d,Q"))]
1438169689Skan  "TARGET_64BIT"
1439169689Skan  "@
1440169689Skan   lzxr\t%0
1441169689Skan   lxr\t%0,%1
1442169689Skan   #
1443169689Skan   #
1444169689Skan   lmg\t%0,%N0,%S1
1445169689Skan   stmg\t%1,%N1,%S0
1446169689Skan   #
1447169689Skan   #
1448169689Skan   #"
1449169689Skan  [(set_attr "op_type" "RRE,RRE,*,*,RSY,RSY,*,*,*")
1450169689Skan   (set_attr "type"    "fsimptf,fsimptf,*,*,lm,stm,*,*,*")])
1451169689Skan
1452169689Skan(define_insn "*movtf_31"
1453169689Skan  [(set (match_operand:TF 0 "nonimmediate_operand" "=f,f,f,o,Q")
1454169689Skan        (match_operand:TF 1 "general_operand"       "G,f,o,f,Q"))]
1455169689Skan  "!TARGET_64BIT"
1456169689Skan  "@
1457169689Skan   lzxr\t%0
1458169689Skan   lxr\t%0,%1
1459169689Skan   #
1460169689Skan   #
1461169689Skan   #"
1462169689Skan  [(set_attr "op_type" "RRE,RRE,*,*,*")
1463169689Skan   (set_attr "type"    "fsimptf,fsimptf,*,*,*")])
1464169689Skan
1465169689Skan; TFmode in GPRs splitters
1466169689Skan
1467169689Skan(define_split
1468169689Skan  [(set (match_operand:TF 0 "nonimmediate_operand" "")
1469169689Skan        (match_operand:TF 1 "general_operand" ""))]
1470169689Skan  "TARGET_64BIT && reload_completed
1471169689Skan   && s390_split_ok_p (operands[0], operands[1], TFmode, 0)"
1472169689Skan  [(set (match_dup 2) (match_dup 4))
1473169689Skan   (set (match_dup 3) (match_dup 5))]
1474169689Skan{
1475169689Skan  operands[2] = operand_subword (operands[0], 0, 0, TFmode);
1476169689Skan  operands[3] = operand_subword (operands[0], 1, 0, TFmode);
1477169689Skan  operands[4] = operand_subword (operands[1], 0, 0, TFmode);
1478169689Skan  operands[5] = operand_subword (operands[1], 1, 0, TFmode);
1479169689Skan})
1480169689Skan
1481169689Skan(define_split
1482169689Skan  [(set (match_operand:TF 0 "nonimmediate_operand" "")
1483169689Skan        (match_operand:TF 1 "general_operand" ""))]
1484169689Skan  "TARGET_64BIT && reload_completed
1485169689Skan   && s390_split_ok_p (operands[0], operands[1], TFmode, 1)"
1486169689Skan  [(set (match_dup 2) (match_dup 4))
1487169689Skan   (set (match_dup 3) (match_dup 5))]
1488169689Skan{
1489169689Skan  operands[2] = operand_subword (operands[0], 1, 0, TFmode);
1490169689Skan  operands[3] = operand_subword (operands[0], 0, 0, TFmode);
1491169689Skan  operands[4] = operand_subword (operands[1], 1, 0, TFmode);
1492169689Skan  operands[5] = operand_subword (operands[1], 0, 0, TFmode);
1493169689Skan})
1494169689Skan
1495169689Skan(define_split
1496169689Skan  [(set (match_operand:TF 0 "register_operand" "")
1497169689Skan        (match_operand:TF 1 "memory_operand" ""))]
1498169689Skan  "TARGET_64BIT && reload_completed
1499169689Skan   && !FP_REG_P (operands[0])
1500169689Skan   && !s_operand (operands[1], VOIDmode)"
1501169689Skan  [(set (match_dup 0) (match_dup 1))]
1502169689Skan{
1503220150Smm  rtx addr = operand_subword (operands[0], 1, 0, TFmode);
1504169689Skan  s390_load_address (addr, XEXP (operands[1], 0));
1505169689Skan  operands[1] = replace_equiv_address (operands[1], addr);
1506169689Skan})
1507169689Skan
1508169689Skan; TFmode in FPRs splitters
1509169689Skan
1510169689Skan(define_split
1511169689Skan  [(set (match_operand:TF 0 "register_operand" "")
1512169689Skan        (match_operand:TF 1 "memory_operand" ""))]
1513169689Skan  "reload_completed && offsettable_memref_p (operands[1]) 
1514169689Skan   && FP_REG_P (operands[0])"
1515169689Skan  [(set (match_dup 2) (match_dup 4))
1516169689Skan   (set (match_dup 3) (match_dup 5))]
1517169689Skan{
1518169689Skan  operands[2] = simplify_gen_subreg (DFmode, operands[0], TFmode, 0);
1519169689Skan  operands[3] = simplify_gen_subreg (DFmode, operands[0], TFmode, 8);
1520169689Skan  operands[4] = adjust_address_nv (operands[1], DFmode, 0);
1521169689Skan  operands[5] = adjust_address_nv (operands[1], DFmode, 8);
1522169689Skan})
1523169689Skan
1524169689Skan(define_split
1525169689Skan  [(set (match_operand:TF 0 "memory_operand" "")
1526169689Skan        (match_operand:TF 1 "register_operand" ""))]
1527169689Skan  "reload_completed && offsettable_memref_p (operands[0])
1528169689Skan   && FP_REG_P (operands[1])"
1529169689Skan  [(set (match_dup 2) (match_dup 4))
1530169689Skan   (set (match_dup 3) (match_dup 5))]
1531169689Skan{
1532169689Skan  operands[2] = adjust_address_nv (operands[0], DFmode, 0);
1533169689Skan  operands[3] = adjust_address_nv (operands[0], DFmode, 8);
1534169689Skan  operands[4] = simplify_gen_subreg (DFmode, operands[1], TFmode, 0);
1535169689Skan  operands[5] = simplify_gen_subreg (DFmode, operands[1], TFmode, 8);
1536169689Skan})
1537169689Skan
1538169689Skan(define_expand "reload_outtf"
1539169689Skan  [(parallel [(match_operand:TF 0 "" "")
1540169689Skan              (match_operand:TF 1 "register_operand" "f")
1541169689Skan              (match_operand:SI 2 "register_operand" "=&a")])]
1542169689Skan  ""
1543169689Skan{
1544169689Skan  rtx addr = gen_lowpart (Pmode, operands[2]);
1545169689Skan
1546169689Skan  gcc_assert (MEM_P (operands[0]));
1547169689Skan  s390_load_address (addr, find_replacement (&XEXP (operands[0], 0)));
1548169689Skan  operands[0] = replace_equiv_address (operands[0], addr);
1549169689Skan  emit_move_insn (operands[0], operands[1]);
1550169689Skan  DONE;
1551169689Skan})
1552169689Skan
1553169689Skan(define_expand "reload_intf"
1554169689Skan  [(parallel [(match_operand:TF 0 "register_operand" "=f")
1555169689Skan              (match_operand:TF 1 "" "")
1556169689Skan              (match_operand:SI 2 "register_operand" "=&a")])]
1557169689Skan  ""
1558169689Skan{
1559169689Skan  rtx addr = gen_lowpart (Pmode, operands[2]);
1560169689Skan 
1561169689Skan  gcc_assert (MEM_P (operands[1]));
1562169689Skan  s390_load_address (addr, find_replacement (&XEXP (operands[1], 0)));
1563169689Skan  operands[1] = replace_equiv_address (operands[1], addr);
1564169689Skan  emit_move_insn (operands[0], operands[1]);
1565169689Skan  DONE;
1566169689Skan})
1567169689Skan
1568169689Skan;
1569107590Sobrien; movdf instruction pattern(s).
1570107590Sobrien;
1571107590Sobrien
1572107590Sobrien(define_expand "movdf"
1573107590Sobrien  [(set (match_operand:DF 0 "nonimmediate_operand" "")
1574107590Sobrien        (match_operand:DF 1 "general_operand"  ""))]
1575107590Sobrien  ""
1576169689Skan  "")
1577107590Sobrien
1578107590Sobrien(define_insn "*movdf_64"
1579169689Skan  [(set (match_operand:DF 0 "nonimmediate_operand" "=f,f,f,f,R,T,d,d,m,?Q")
1580169689Skan        (match_operand:DF 1 "general_operand" "G,f,R,T,f,f,d,m,d,?Q"))]
1581107590Sobrien  "TARGET_64BIT"
1582107590Sobrien  "@
1583169689Skan   lzdr\t%0
1584132718Skan   ldr\t%0,%1
1585132718Skan   ld\t%0,%1
1586132718Skan   ldy\t%0,%1
1587132718Skan   std\t%1,%0
1588132718Skan   stdy\t%1,%0
1589132718Skan   lgr\t%0,%1
1590132718Skan   lg\t%0,%1
1591132718Skan   stg\t%1,%0
1592169689Skan   #"
1593169689Skan  [(set_attr "op_type" "RRE,RR,RX,RXY,RX,RXY,RRE,RXY,RXY,SS")
1594169689Skan   (set_attr "type" "fsimpdf,floaddf,floaddf,floaddf,fstoredf,fstoredf,lr,load,store,*")])
1595107590Sobrien
1596107590Sobrien(define_insn "*movdf_31"
1597169689Skan  [(set (match_operand:DF 0 "nonimmediate_operand" "=f,f,f,f,R,T,d,d,Q,S,d,o,Q")
1598169689Skan        (match_operand:DF 1 "general_operand" "G,f,R,T,f,f,Q,S,d,d,dPm,d,Q"))]
1599107590Sobrien  "!TARGET_64BIT"
1600107590Sobrien  "@
1601169689Skan   lzdr\t%0
1602132718Skan   ldr\t%0,%1
1603132718Skan   ld\t%0,%1
1604132718Skan   ldy\t%0,%1
1605132718Skan   std\t%1,%0
1606132718Skan   stdy\t%1,%0
1607169689Skan   lm\t%0,%N0,%S1
1608169689Skan   lmy\t%0,%N0,%S1
1609169689Skan   stm\t%1,%N1,%S0
1610169689Skan   stmy\t%1,%N1,%S0
1611107590Sobrien   #
1612117395Skan   #
1613169689Skan   #"
1614169689Skan  [(set_attr "op_type" "RRE,RR,RX,RXY,RX,RXY,RS,RSY,RS,RSY,*,*,SS")
1615169689Skan   (set_attr "type" "fsimpdf,floaddf,floaddf,floaddf,fstoredf,fstoredf,\
1616169689Skan                     lm,lm,stm,stm,*,*,*")])
1617107590Sobrien
1618107590Sobrien(define_split
1619107590Sobrien  [(set (match_operand:DF 0 "nonimmediate_operand" "")
1620107590Sobrien        (match_operand:DF 1 "general_operand" ""))]
1621107590Sobrien  "!TARGET_64BIT && reload_completed
1622117395Skan   && s390_split_ok_p (operands[0], operands[1], DFmode, 0)"
1623107590Sobrien  [(set (match_dup 2) (match_dup 4))
1624107590Sobrien   (set (match_dup 3) (match_dup 5))]
1625107590Sobrien{
1626117395Skan  operands[2] = operand_subword (operands[0], 0, 0, DFmode);
1627117395Skan  operands[3] = operand_subword (operands[0], 1, 0, DFmode);
1628117395Skan  operands[4] = operand_subword (operands[1], 0, 0, DFmode);
1629117395Skan  operands[5] = operand_subword (operands[1], 1, 0, DFmode);
1630117395Skan})
1631107590Sobrien
1632107590Sobrien(define_split
1633117395Skan  [(set (match_operand:DF 0 "nonimmediate_operand" "")
1634117395Skan        (match_operand:DF 1 "general_operand" ""))]
1635117395Skan  "!TARGET_64BIT && reload_completed
1636117395Skan   && s390_split_ok_p (operands[0], operands[1], DFmode, 1)"
1637117395Skan  [(set (match_dup 2) (match_dup 4))
1638117395Skan   (set (match_dup 3) (match_dup 5))]
1639117395Skan{
1640117395Skan  operands[2] = operand_subword (operands[0], 1, 0, DFmode);
1641117395Skan  operands[3] = operand_subword (operands[0], 0, 0, DFmode);
1642117395Skan  operands[4] = operand_subword (operands[1], 1, 0, DFmode);
1643117395Skan  operands[5] = operand_subword (operands[1], 0, 0, DFmode);
1644117395Skan})
1645117395Skan
1646117395Skan(define_split
1647107590Sobrien  [(set (match_operand:DF 0 "register_operand" "")
1648107590Sobrien        (match_operand:DF 1 "memory_operand" ""))]
1649107590Sobrien  "!TARGET_64BIT && reload_completed
1650117395Skan   && !FP_REG_P (operands[0])
1651107590Sobrien   && !s_operand (operands[1], VOIDmode)"
1652117395Skan  [(set (match_dup 0) (match_dup 1))]
1653117395Skan{
1654117395Skan  rtx addr = operand_subword (operands[0], 1, 0, DFmode);
1655117395Skan  s390_load_address (addr, XEXP (operands[1], 0));
1656117395Skan  operands[1] = replace_equiv_address (operands[1], addr);
1657117395Skan})
1658107590Sobrien
1659117395Skan(define_expand "reload_outdf"
1660146895Skan  [(parallel [(match_operand:DF 0 "" "")
1661117395Skan              (match_operand:DF 1 "register_operand" "d")
1662117395Skan              (match_operand:SI 2 "register_operand" "=&a")])]
1663117395Skan  "!TARGET_64BIT"
1664117395Skan{
1665169689Skan  gcc_assert (MEM_P (operands[0]));
1666169689Skan  s390_load_address (operands[2], find_replacement (&XEXP (operands[0], 0)));
1667117395Skan  operands[0] = replace_equiv_address (operands[0], operands[2]);
1668117395Skan  emit_move_insn (operands[0], operands[1]);
1669117395Skan  DONE;
1670117395Skan})
1671117395Skan
1672107590Sobrien;
1673107590Sobrien; movsf instruction pattern(s).
1674107590Sobrien;
1675107590Sobrien
1676169689Skan(define_insn "movsf"
1677169689Skan  [(set (match_operand:SF 0 "nonimmediate_operand" "=f,f,f,f,R,T,d,d,d,R,T,?Q")
1678169689Skan        (match_operand:SF 1 "general_operand" "G,f,R,T,f,f,d,R,T,d,d,?Q"))]
1679107590Sobrien  ""
1680107590Sobrien  "@
1681169689Skan   lzer\t%0
1682132718Skan   ler\t%0,%1
1683132718Skan   le\t%0,%1
1684132718Skan   ley\t%0,%1
1685132718Skan   ste\t%1,%0
1686132718Skan   stey\t%1,%0
1687132718Skan   lr\t%0,%1
1688132718Skan   l\t%0,%1
1689132718Skan   ly\t%0,%1
1690132718Skan   st\t%1,%0
1691132718Skan   sty\t%1,%0
1692169689Skan   #"
1693169689Skan  [(set_attr "op_type" "RRE,RR,RX,RXY,RX,RXY,RR,RX,RXY,RX,RXY,SS")
1694169689Skan   (set_attr "type" "fsimpsf,floadsf,floadsf,floadsf,fstoresf,fstoresf,
1695169689Skan                     lr,load,load,store,store,*")])
1696107590Sobrien
1697107590Sobrien;
1698169689Skan; movcc instruction pattern
1699169689Skan;
1700169689Skan
1701169689Skan(define_insn "movcc"
1702169689Skan  [(set (match_operand:CC 0 "nonimmediate_operand" "=d,c,d,d,d,R,T")
1703169689Skan	(match_operand:CC 1 "nonimmediate_operand" "d,d,c,R,T,d,d"))]
1704169689Skan  ""
1705169689Skan  "@
1706169689Skan   lr\t%0,%1
1707169689Skan   tmh\t%1,12288
1708169689Skan   ipm\t%0
1709169689Skan   st\t%0,%1
1710169689Skan   sty\t%0,%1
1711169689Skan   l\t%1,%0
1712169689Skan   ly\t%1,%0"
1713169689Skan  [(set_attr "op_type" "RR,RI,RRE,RX,RXY,RX,RXY")
1714169689Skan   (set_attr "type" "lr,*,*,store,store,load,load")])
1715169689Skan
1716169689Skan;
1717169689Skan; Block move (MVC) patterns.
1718169689Skan;
1719169689Skan
1720169689Skan(define_insn "*mvc"
1721169689Skan  [(set (match_operand:BLK 0 "memory_operand" "=Q")
1722169689Skan        (match_operand:BLK 1 "memory_operand" "Q"))
1723169689Skan   (use (match_operand 2 "const_int_operand" "n"))]
1724169689Skan  "INTVAL (operands[2]) >= 1 && INTVAL (operands[2]) <= 256"
1725169689Skan  "mvc\t%O0(%2,%R0),%S1"
1726169689Skan  [(set_attr "op_type" "SS")])
1727169689Skan
1728169689Skan(define_split
1729169689Skan  [(set (match_operand 0 "memory_operand" "")
1730169689Skan        (match_operand 1 "memory_operand" ""))]
1731169689Skan  "reload_completed
1732169689Skan   && GET_MODE (operands[0]) == GET_MODE (operands[1])
1733169689Skan   && GET_MODE_SIZE (GET_MODE (operands[0])) > 0"
1734169689Skan  [(parallel
1735169689Skan    [(set (match_dup 0) (match_dup 1))
1736169689Skan     (use (match_dup 2))])]
1737169689Skan{
1738169689Skan  operands[2] = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[0])));
1739169689Skan  operands[0] = adjust_address (operands[0], BLKmode, 0);
1740169689Skan  operands[1] = adjust_address (operands[1], BLKmode, 0);
1741169689Skan})
1742169689Skan
1743169689Skan(define_peephole2
1744169689Skan  [(parallel
1745169689Skan    [(set (match_operand:BLK 0 "memory_operand" "")
1746169689Skan          (match_operand:BLK 1 "memory_operand" ""))
1747169689Skan     (use (match_operand 2 "const_int_operand" ""))])
1748169689Skan   (parallel
1749169689Skan    [(set (match_operand:BLK 3 "memory_operand" "")
1750169689Skan          (match_operand:BLK 4 "memory_operand" ""))
1751169689Skan     (use (match_operand 5 "const_int_operand" ""))])]
1752169689Skan  "s390_offset_p (operands[0], operands[3], operands[2])
1753169689Skan   && s390_offset_p (operands[1], operands[4], operands[2])
1754169689Skan   && !s390_overlap_p (operands[0], operands[1], 
1755169689Skan                       INTVAL (operands[2]) + INTVAL (operands[5]))
1756169689Skan   && INTVAL (operands[2]) + INTVAL (operands[5]) <= 256"
1757169689Skan  [(parallel
1758169689Skan    [(set (match_dup 6) (match_dup 7))
1759169689Skan     (use (match_dup 8))])]
1760169689Skan  "operands[6] = gen_rtx_MEM (BLKmode, XEXP (operands[0], 0));
1761169689Skan   operands[7] = gen_rtx_MEM (BLKmode, XEXP (operands[1], 0));
1762169689Skan   operands[8] = GEN_INT (INTVAL (operands[2]) + INTVAL (operands[5]));")
1763169689Skan
1764169689Skan
1765169689Skan;
1766107590Sobrien; load_multiple pattern(s).
1767107590Sobrien;
1768132718Skan; ??? Due to reload problems with replacing registers inside match_parallel
1769132718Skan; we currently support load_multiple/store_multiple only after reload.
1770132718Skan;
1771107590Sobrien
1772107590Sobrien(define_expand "load_multiple"
1773107590Sobrien  [(match_par_dup 3 [(set (match_operand 0 "" "")
1774107590Sobrien			  (match_operand 1 "" ""))
1775107590Sobrien		     (use (match_operand 2 "" ""))])]
1776132718Skan  "reload_completed"
1777107590Sobrien{
1778132718Skan  enum machine_mode mode;
1779107590Sobrien  int regno;
1780107590Sobrien  int count;
1781107590Sobrien  rtx from;
1782107590Sobrien  int i, off;
1783107590Sobrien
1784107590Sobrien  /* Support only loading a constant number of fixed-point registers from
1785107590Sobrien     memory and only bother with this if more than two */
1786107590Sobrien  if (GET_CODE (operands[2]) != CONST_INT
1787107590Sobrien      || INTVAL (operands[2]) < 2
1788107590Sobrien      || INTVAL (operands[2]) > 16
1789107590Sobrien      || GET_CODE (operands[1]) != MEM
1790107590Sobrien      || GET_CODE (operands[0]) != REG
1791107590Sobrien      || REGNO (operands[0]) >= 16)
1792107590Sobrien    FAIL;
1793107590Sobrien
1794107590Sobrien  count = INTVAL (operands[2]);
1795107590Sobrien  regno = REGNO (operands[0]);
1796132718Skan  mode = GET_MODE (operands[0]);
1797132718Skan  if (mode != SImode && mode != word_mode)
1798132718Skan    FAIL;
1799107590Sobrien
1800107590Sobrien  operands[3] = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (count));
1801107590Sobrien  if (no_new_pseudos)
1802107590Sobrien    {
1803107590Sobrien      if (GET_CODE (XEXP (operands[1], 0)) == REG)
1804107590Sobrien	{
1805107590Sobrien	  from = XEXP (operands[1], 0);
1806107590Sobrien	  off = 0;
1807107590Sobrien	}
1808107590Sobrien      else if (GET_CODE (XEXP (operands[1], 0)) == PLUS
1809107590Sobrien	       && GET_CODE (XEXP (XEXP (operands[1], 0), 0)) == REG
1810107590Sobrien	       && GET_CODE (XEXP (XEXP (operands[1], 0), 1)) == CONST_INT)
1811107590Sobrien	{
1812107590Sobrien	  from = XEXP (XEXP (operands[1], 0), 0);
1813107590Sobrien	  off = INTVAL (XEXP (XEXP (operands[1], 0), 1));
1814107590Sobrien	}
1815107590Sobrien      else
1816107590Sobrien	FAIL;
1817107590Sobrien    }
1818107590Sobrien  else
1819107590Sobrien    {
1820107590Sobrien      from = force_reg (Pmode, XEXP (operands[1], 0));
1821107590Sobrien      off = 0;
1822107590Sobrien    }
1823107590Sobrien
1824107590Sobrien  for (i = 0; i < count; i++)
1825107590Sobrien    XVECEXP (operands[3], 0, i)
1826132718Skan      = gen_rtx_SET (VOIDmode, gen_rtx_REG (mode, regno + i),
1827132718Skan		     change_address (operands[1], mode,
1828132718Skan		       plus_constant (from, off + i * GET_MODE_SIZE (mode))));
1829132718Skan})
1830107590Sobrien
1831107590Sobrien(define_insn "*load_multiple_di"
1832107590Sobrien  [(match_parallel 0 "load_multiple_operation"
1833107590Sobrien		   [(set (match_operand:DI 1 "register_operand" "=r")
1834132718Skan			 (match_operand:DI 2 "s_operand" "QS"))])]
1835132718Skan  "reload_completed && word_mode == DImode"
1836107590Sobrien{
1837107590Sobrien  int words = XVECLEN (operands[0], 0);
1838107590Sobrien  operands[0] = gen_rtx_REG (DImode, REGNO (operands[1]) + words - 1);
1839169689Skan  return "lmg\t%1,%0,%S2";
1840132718Skan}
1841132718Skan   [(set_attr "op_type" "RSY")
1842107590Sobrien    (set_attr "type"    "lm")])
1843107590Sobrien
1844107590Sobrien(define_insn "*load_multiple_si"
1845107590Sobrien  [(match_parallel 0 "load_multiple_operation"
1846132718Skan		   [(set (match_operand:SI 1 "register_operand" "=r,r")
1847132718Skan			 (match_operand:SI 2 "s_operand" "Q,S"))])]
1848132718Skan  "reload_completed"
1849107590Sobrien{
1850107590Sobrien  int words = XVECLEN (operands[0], 0);
1851107590Sobrien  operands[0] = gen_rtx_REG (SImode, REGNO (operands[1]) + words - 1);
1852169689Skan  return which_alternative == 0 ? "lm\t%1,%0,%S2" : "lmy\t%1,%0,%S2";
1853132718Skan}
1854132718Skan   [(set_attr "op_type" "RS,RSY")
1855107590Sobrien    (set_attr "type"    "lm")])
1856107590Sobrien
1857107590Sobrien;
1858132718Skan; store multiple pattern(s).
1859107590Sobrien;
1860107590Sobrien
1861107590Sobrien(define_expand "store_multiple"
1862107590Sobrien  [(match_par_dup 3 [(set (match_operand 0 "" "")
1863107590Sobrien			  (match_operand 1 "" ""))
1864107590Sobrien		     (use (match_operand 2 "" ""))])]
1865132718Skan  "reload_completed"
1866107590Sobrien{
1867132718Skan  enum machine_mode mode;
1868107590Sobrien  int regno;
1869107590Sobrien  int count;
1870107590Sobrien  rtx to;
1871107590Sobrien  int i, off;
1872107590Sobrien
1873107590Sobrien  /* Support only storing a constant number of fixed-point registers to
1874107590Sobrien     memory and only bother with this if more than two.  */
1875107590Sobrien  if (GET_CODE (operands[2]) != CONST_INT
1876107590Sobrien      || INTVAL (operands[2]) < 2
1877107590Sobrien      || INTVAL (operands[2]) > 16
1878107590Sobrien      || GET_CODE (operands[0]) != MEM
1879107590Sobrien      || GET_CODE (operands[1]) != REG
1880107590Sobrien      || REGNO (operands[1]) >= 16)
1881107590Sobrien    FAIL;
1882107590Sobrien
1883107590Sobrien  count = INTVAL (operands[2]);
1884107590Sobrien  regno = REGNO (operands[1]);
1885132718Skan  mode = GET_MODE (operands[1]);
1886132718Skan  if (mode != SImode && mode != word_mode)
1887132718Skan    FAIL;
1888107590Sobrien
1889107590Sobrien  operands[3] = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (count));
1890107590Sobrien
1891107590Sobrien  if (no_new_pseudos)
1892107590Sobrien    {
1893107590Sobrien      if (GET_CODE (XEXP (operands[0], 0)) == REG)
1894107590Sobrien	{
1895107590Sobrien	  to = XEXP (operands[0], 0);
1896107590Sobrien	  off = 0;
1897107590Sobrien	}
1898107590Sobrien      else if (GET_CODE (XEXP (operands[0], 0)) == PLUS
1899107590Sobrien	       && GET_CODE (XEXP (XEXP (operands[0], 0), 0)) == REG
1900107590Sobrien	       && GET_CODE (XEXP (XEXP (operands[0], 0), 1)) == CONST_INT)
1901107590Sobrien	{
1902107590Sobrien	  to = XEXP (XEXP (operands[0], 0), 0);
1903107590Sobrien	  off = INTVAL (XEXP (XEXP (operands[0], 0), 1));
1904107590Sobrien	}
1905107590Sobrien      else
1906107590Sobrien	FAIL;
1907107590Sobrien    }
1908132718Skan  else
1909107590Sobrien    {
1910107590Sobrien      to = force_reg (Pmode, XEXP (operands[0], 0));
1911107590Sobrien      off = 0;
1912107590Sobrien    }
1913107590Sobrien
1914107590Sobrien  for (i = 0; i < count; i++)
1915107590Sobrien    XVECEXP (operands[3], 0, i)
1916107590Sobrien      = gen_rtx_SET (VOIDmode,
1917132718Skan		     change_address (operands[0], mode,
1918132718Skan		       plus_constant (to, off + i * GET_MODE_SIZE (mode))),
1919132718Skan		     gen_rtx_REG (mode, regno + i));
1920132718Skan})
1921107590Sobrien
1922107590Sobrien(define_insn "*store_multiple_di"
1923107590Sobrien  [(match_parallel 0 "store_multiple_operation"
1924132718Skan		   [(set (match_operand:DI 1 "s_operand" "=QS")
1925107590Sobrien			 (match_operand:DI 2 "register_operand" "r"))])]
1926132718Skan  "reload_completed && word_mode == DImode"
1927107590Sobrien{
1928107590Sobrien  int words = XVECLEN (operands[0], 0);
1929107590Sobrien  operands[0] = gen_rtx_REG (DImode, REGNO (operands[2]) + words - 1);
1930169689Skan  return "stmg\t%2,%0,%S1";
1931132718Skan}
1932132718Skan   [(set_attr "op_type" "RSY")
1933107590Sobrien    (set_attr "type"    "stm")])
1934107590Sobrien
1935107590Sobrien
1936107590Sobrien(define_insn "*store_multiple_si"
1937107590Sobrien  [(match_parallel 0 "store_multiple_operation"
1938132718Skan		   [(set (match_operand:SI 1 "s_operand" "=Q,S")
1939132718Skan			 (match_operand:SI 2 "register_operand" "r,r"))])]
1940132718Skan  "reload_completed"
1941107590Sobrien{
1942107590Sobrien  int words = XVECLEN (operands[0], 0);
1943107590Sobrien  operands[0] = gen_rtx_REG (SImode, REGNO (operands[2]) + words - 1);
1944169689Skan  return which_alternative == 0 ? "stm\t%2,%0,%S1" : "stmy\t%2,%0,%S1";
1945132718Skan}
1946132718Skan   [(set_attr "op_type" "RS,RSY")
1947107590Sobrien    (set_attr "type"    "stm")])
1948107590Sobrien
1949107590Sobrien;;
1950107590Sobrien;; String instructions.
1951107590Sobrien;;
1952107590Sobrien
1953169689Skan(define_insn "*execute"
1954169689Skan  [(match_parallel 0 ""
1955169689Skan    [(unspec [(match_operand 1 "register_operand" "a")
1956169689Skan              (match_operand:BLK 2 "memory_operand" "R")
1957169689Skan              (match_operand 3 "" "")] UNSPEC_EXECUTE)])]
1958169689Skan  "GET_MODE_CLASS (GET_MODE (operands[1])) == MODE_INT
1959169689Skan   && GET_MODE_SIZE (GET_MODE (operands[1])) <= UNITS_PER_WORD"
1960169689Skan  "ex\t%1,%2"
1961169689Skan  [(set_attr "op_type" "RX")
1962169689Skan   (set_attr "type" "cs")])
1963169689Skan
1964169689Skan
1965107590Sobrien;
1966132718Skan; strlenM instruction pattern(s).
1967132718Skan;
1968132718Skan
1969169689Skan(define_expand "strlen<mode>"
1970169689Skan  [(set (reg:SI 0) (match_operand:SI 2 "immediate_operand" ""))
1971169689Skan   (parallel
1972132718Skan    [(set (match_dup 4)
1973169689Skan	  (unspec:P [(const_int 0)
1974132718Skan		      (match_operand:BLK 1 "memory_operand" "")
1975169689Skan		      (reg:SI 0)
1976132718Skan		      (match_operand 3 "immediate_operand" "")] UNSPEC_SRST))
1977169689Skan     (clobber (scratch:P))
1978169689Skan     (clobber (reg:CC CC_REGNUM))])
1979132718Skan   (parallel
1980169689Skan    [(set (match_operand:P 0 "register_operand" "")
1981169689Skan          (minus:P (match_dup 4) (match_dup 5)))
1982169689Skan     (clobber (reg:CC CC_REGNUM))])]
1983169689Skan  ""
1984132718Skan{
1985169689Skan  operands[4] = gen_reg_rtx (Pmode);
1986169689Skan  operands[5] = gen_reg_rtx (Pmode);
1987132718Skan  emit_move_insn (operands[5], force_operand (XEXP (operands[1], 0), NULL_RTX));
1988132718Skan  operands[1] = replace_equiv_address (operands[1], operands[5]);
1989132718Skan})
1990132718Skan
1991169689Skan(define_insn "*strlen<mode>"
1992169689Skan  [(set (match_operand:P 0 "register_operand" "=a")
1993169689Skan	(unspec:P [(match_operand:P 2 "general_operand" "0")
1994169689Skan		    (mem:BLK (match_operand:P 3 "register_operand" "1"))
1995169689Skan		    (reg:SI 0)
1996132718Skan		    (match_operand 4 "immediate_operand" "")] UNSPEC_SRST))
1997169689Skan   (clobber (match_scratch:P 1 "=a"))
1998169689Skan   (clobber (reg:CC CC_REGNUM))]
1999169689Skan  ""
2000132718Skan  "srst\t%0,%1\;jo\t.-4"
2001169689Skan  [(set_attr "length" "8")
2002169689Skan   (set_attr "type" "vs")])
2003132718Skan
2004169689Skan;
2005169689Skan; cmpstrM instruction pattern(s).
2006169689Skan;
2007169689Skan
2008169689Skan(define_expand "cmpstrsi"
2009169689Skan  [(set (reg:SI 0) (const_int 0))
2010132718Skan   (parallel
2011169689Skan    [(clobber (match_operand 3 "" ""))
2012169689Skan     (clobber (match_dup 4))
2013169689Skan     (set (reg:CCU CC_REGNUM)
2014169689Skan	  (compare:CCU (match_operand:BLK 1 "memory_operand" "")
2015169689Skan	 	       (match_operand:BLK 2 "memory_operand" "")))
2016169689Skan     (use (reg:SI 0))])
2017169689Skan   (parallel
2018169689Skan    [(set (match_operand:SI 0 "register_operand" "=d")
2019169689Skan	  (unspec:SI [(reg:CCU CC_REGNUM)] UNSPEC_CMPINT))
2020169689Skan     (clobber (reg:CC CC_REGNUM))])]
2021169689Skan  ""
2022132718Skan{
2023169689Skan  /* As the result of CMPINT is inverted compared to what we need,
2024169689Skan     we have to swap the operands.  */
2025169689Skan  rtx op1 = operands[2];
2026169689Skan  rtx op2 = operands[1];
2027169689Skan  rtx addr1 = gen_reg_rtx (Pmode);
2028169689Skan  rtx addr2 = gen_reg_rtx (Pmode);
2029169689Skan
2030169689Skan  emit_move_insn (addr1, force_operand (XEXP (op1, 0), NULL_RTX));
2031169689Skan  emit_move_insn (addr2, force_operand (XEXP (op2, 0), NULL_RTX));
2032169689Skan  operands[1] = replace_equiv_address_nv (op1, addr1);
2033169689Skan  operands[2] = replace_equiv_address_nv (op2, addr2);
2034169689Skan  operands[3] = addr1;
2035169689Skan  operands[4] = addr2;
2036132718Skan})
2037132718Skan
2038169689Skan(define_insn "*cmpstr<mode>"
2039169689Skan  [(clobber (match_operand:P 0 "register_operand" "=d"))
2040169689Skan   (clobber (match_operand:P 1 "register_operand" "=d"))
2041169689Skan   (set (reg:CCU CC_REGNUM)
2042169689Skan	(compare:CCU (mem:BLK (match_operand:P 2 "register_operand" "0"))
2043169689Skan		     (mem:BLK (match_operand:P 3 "register_operand" "1"))))
2044169689Skan   (use (reg:SI 0))]
2045169689Skan  ""
2046169689Skan  "clst\t%0,%1\;jo\t.-4"
2047169689Skan  [(set_attr "length" "8")
2048169689Skan   (set_attr "type" "vs")])
2049169689Skan 
2050169689Skan;
2051169689Skan; movstr instruction pattern.
2052169689Skan;
2053132718Skan
2054169689Skan(define_expand "movstr"
2055169689Skan  [(set (reg:SI 0) (const_int 0))
2056169689Skan   (parallel 
2057169689Skan    [(clobber (match_dup 3))
2058169689Skan     (set (match_operand:BLK 1 "memory_operand" "")
2059169689Skan	  (match_operand:BLK 2 "memory_operand" ""))
2060169689Skan     (set (match_operand 0 "register_operand" "")
2061169689Skan	  (unspec [(match_dup 1) 
2062169689Skan		   (match_dup 2)
2063169689Skan		   (reg:SI 0)] UNSPEC_MVST))
2064169689Skan     (clobber (reg:CC CC_REGNUM))])]
2065169689Skan  ""
2066169689Skan{
2067169689Skan  rtx addr1 = gen_reg_rtx (Pmode);
2068169689Skan  rtx addr2 = gen_reg_rtx (Pmode);
2069169689Skan
2070169689Skan  emit_move_insn (addr1, force_operand (XEXP (operands[1], 0), NULL_RTX));
2071169689Skan  emit_move_insn (addr2, force_operand (XEXP (operands[2], 0), NULL_RTX));
2072169689Skan  operands[1] = replace_equiv_address_nv (operands[1], addr1);
2073169689Skan  operands[2] = replace_equiv_address_nv (operands[2], addr2);
2074169689Skan  operands[3] = addr2;
2075169689Skan})
2076169689Skan
2077169689Skan(define_insn "*movstr"
2078169689Skan  [(clobber (match_operand:P 2 "register_operand" "=d"))
2079169689Skan   (set (mem:BLK (match_operand:P 1 "register_operand" "0"))
2080169689Skan	(mem:BLK (match_operand:P 3 "register_operand" "2")))
2081169689Skan   (set (match_operand:P 0 "register_operand" "=d")
2082169689Skan	(unspec [(mem:BLK (match_dup 1)) 
2083169689Skan		 (mem:BLK (match_dup 3))
2084169689Skan		 (reg:SI 0)] UNSPEC_MVST))
2085169689Skan   (clobber (reg:CC CC_REGNUM))]
2086169689Skan  ""
2087169689Skan  "mvst\t%1,%2\;jo\t.-4"
2088169689Skan  [(set_attr "length" "8")
2089169689Skan   (set_attr "type" "vs")])
2090169689Skan  
2091169689Skan
2092132718Skan;
2093169689Skan; movmemM instruction pattern(s).
2094107590Sobrien;
2095107590Sobrien
2096169689Skan(define_expand "movmem<mode>"
2097117395Skan  [(set (match_operand:BLK 0 "memory_operand" "")
2098117395Skan        (match_operand:BLK 1 "memory_operand" ""))
2099169689Skan   (use (match_operand:GPR 2 "general_operand" ""))
2100117395Skan   (match_operand 3 "" "")]
2101117395Skan  ""
2102169689Skan  "s390_expand_movmem (operands[0], operands[1], operands[2]); DONE;")
2103107590Sobrien
2104107590Sobrien; Move a block that is up to 256 bytes in length.
2105107590Sobrien; The block length is taken as (operands[2] % 256) + 1.
2106107590Sobrien
2107169689Skan(define_expand "movmem_short"
2108132718Skan  [(parallel
2109132718Skan    [(set (match_operand:BLK 0 "memory_operand" "")
2110132718Skan          (match_operand:BLK 1 "memory_operand" ""))
2111132718Skan     (use (match_operand 2 "nonmemory_operand" ""))
2112169689Skan     (use (const:BLK (unspec:BLK [(const_int 0)] UNSPEC_INSN)))
2113132718Skan     (clobber (match_dup 3))])]
2114132718Skan  ""
2115132718Skan  "operands[3] = gen_rtx_SCRATCH (Pmode);")
2116132718Skan
2117169689Skan(define_insn "*movmem_short"
2118169689Skan  [(set (match_operand:BLK 0 "memory_operand" "=Q,Q,Q")
2119169689Skan        (match_operand:BLK 1 "memory_operand" "Q,Q,Q"))
2120169689Skan   (use (match_operand 2 "nonmemory_operand" "n,a,a"))
2121169689Skan   (use (match_operand 3 "immediate_operand" "X,R,X"))
2122169689Skan   (clobber (match_scratch 4 "=X,X,&a"))]
2123132718Skan  "(GET_MODE (operands[2]) == Pmode || GET_MODE (operands[2]) == VOIDmode)
2124169689Skan   && GET_MODE (operands[4]) == Pmode"
2125169689Skan  "#"
2126169689Skan  [(set_attr "type" "cs")])
2127107590Sobrien
2128169689Skan(define_split
2129169689Skan  [(set (match_operand:BLK 0 "memory_operand" "")
2130169689Skan        (match_operand:BLK 1 "memory_operand" ""))
2131169689Skan   (use (match_operand 2 "const_int_operand" ""))
2132169689Skan   (use (match_operand 3 "immediate_operand" ""))
2133169689Skan   (clobber (scratch))]
2134169689Skan  "reload_completed"
2135169689Skan  [(parallel
2136169689Skan    [(set (match_dup 0) (match_dup 1))
2137169689Skan     (use (match_dup 2))])]
2138169689Skan  "operands[2] = GEN_INT ((INTVAL (operands[2]) & 0xff) + 1);")
2139107590Sobrien
2140169689Skan(define_split
2141169689Skan  [(set (match_operand:BLK 0 "memory_operand" "")
2142169689Skan        (match_operand:BLK 1 "memory_operand" ""))
2143169689Skan   (use (match_operand 2 "register_operand" ""))
2144169689Skan   (use (match_operand 3 "memory_operand" ""))
2145169689Skan   (clobber (scratch))]
2146169689Skan  "reload_completed"
2147169689Skan  [(parallel
2148169689Skan    [(unspec [(match_dup 2) (match_dup 3)
2149169689Skan              (const_int 0)] UNSPEC_EXECUTE)
2150169689Skan     (set (match_dup 0) (match_dup 1))
2151169689Skan     (use (const_int 1))])]
2152169689Skan  "")
2153107590Sobrien
2154169689Skan(define_split
2155169689Skan  [(set (match_operand:BLK 0 "memory_operand" "")
2156169689Skan        (match_operand:BLK 1 "memory_operand" ""))
2157169689Skan   (use (match_operand 2 "register_operand" ""))
2158169689Skan   (use (const:BLK (unspec:BLK [(const_int 0)] UNSPEC_INSN)))
2159169689Skan   (clobber (match_operand 3 "register_operand" ""))]
2160169689Skan  "reload_completed && TARGET_CPU_ZARCH"
2161169689Skan  [(set (match_dup 3) (label_ref (match_dup 4)))
2162169689Skan   (parallel
2163169689Skan    [(unspec [(match_dup 2) (mem:BLK (match_dup 3)) 
2164169689Skan              (label_ref (match_dup 4))] UNSPEC_EXECUTE)
2165169689Skan     (set (match_dup 0) (match_dup 1))
2166169689Skan     (use (const_int 1))])]
2167169689Skan  "operands[4] = gen_label_rtx ();")
2168169689Skan
2169132718Skan; Move a block of arbitrary length.
2170132718Skan
2171169689Skan(define_expand "movmem_long"
2172132718Skan  [(parallel
2173132718Skan    [(clobber (match_dup 2))
2174132718Skan     (clobber (match_dup 3))
2175132718Skan     (set (match_operand:BLK 0 "memory_operand" "")
2176132718Skan          (match_operand:BLK 1 "memory_operand" ""))
2177132718Skan     (use (match_operand 2 "general_operand" ""))
2178132718Skan     (use (match_dup 3))
2179169689Skan     (clobber (reg:CC CC_REGNUM))])]
2180132718Skan  ""
2181107590Sobrien{
2182132718Skan  enum machine_mode dword_mode = word_mode == DImode ? TImode : DImode;
2183132718Skan  rtx reg0 = gen_reg_rtx (dword_mode);
2184132718Skan  rtx reg1 = gen_reg_rtx (dword_mode);
2185132718Skan  rtx addr0 = gen_lowpart (Pmode, gen_highpart (word_mode, reg0));
2186132718Skan  rtx addr1 = gen_lowpart (Pmode, gen_highpart (word_mode, reg1));
2187132718Skan  rtx len0 = gen_lowpart (Pmode, reg0);
2188132718Skan  rtx len1 = gen_lowpart (Pmode, reg1);
2189107590Sobrien
2190132718Skan  emit_insn (gen_rtx_CLOBBER (VOIDmode, reg0));
2191132718Skan  emit_move_insn (addr0, force_operand (XEXP (operands[0], 0), NULL_RTX));
2192132718Skan  emit_move_insn (len0, operands[2]);
2193107590Sobrien
2194132718Skan  emit_insn (gen_rtx_CLOBBER (VOIDmode, reg1));
2195132718Skan  emit_move_insn (addr1, force_operand (XEXP (operands[1], 0), NULL_RTX));
2196132718Skan  emit_move_insn (len1, operands[2]);
2197107590Sobrien
2198132718Skan  operands[0] = replace_equiv_address_nv (operands[0], addr0);
2199132718Skan  operands[1] = replace_equiv_address_nv (operands[1], addr1);
2200132718Skan  operands[2] = reg0;
2201132718Skan  operands[3] = reg1;
2202132718Skan})
2203107590Sobrien
2204169689Skan(define_insn "*movmem_long"
2205169689Skan  [(clobber (match_operand:<DBL> 0 "register_operand" "=d"))
2206169689Skan   (clobber (match_operand:<DBL> 1 "register_operand" "=d"))
2207169689Skan   (set (mem:BLK (subreg:P (match_operand:<DBL> 2 "register_operand" "0") 0))
2208169689Skan        (mem:BLK (subreg:P (match_operand:<DBL> 3 "register_operand" "1") 0)))
2209132718Skan   (use (match_dup 2))
2210132718Skan   (use (match_dup 3))
2211169689Skan   (clobber (reg:CC CC_REGNUM))]
2212169689Skan  ""
2213132718Skan  "mvcle\t%0,%1,0\;jo\t.-4"
2214169689Skan  [(set_attr "length" "8")
2215169689Skan   (set_attr "type" "vs")])
2216107590Sobrien
2217107590Sobrien;
2218169689Skan; setmemM instruction pattern(s).
2219107590Sobrien;
2220107590Sobrien
2221169689Skan(define_expand "setmem<mode>"
2222117395Skan  [(set (match_operand:BLK 0 "memory_operand" "")
2223169689Skan        (match_operand:QI 2 "general_operand" ""))
2224169689Skan   (use (match_operand:GPR 1 "general_operand" ""))
2225169689Skan   (match_operand 3 "" "")]
2226117395Skan  ""
2227169689Skan  "s390_expand_setmem (operands[0], operands[1], operands[2]); DONE;")
2228107590Sobrien
2229117395Skan; Clear a block that is up to 256 bytes in length.
2230132718Skan; The block length is taken as (operands[1] % 256) + 1.
2231107590Sobrien
2232169689Skan(define_expand "clrmem_short"
2233132718Skan  [(parallel
2234132718Skan    [(set (match_operand:BLK 0 "memory_operand" "")
2235132718Skan          (const_int 0))
2236132718Skan     (use (match_operand 1 "nonmemory_operand" ""))
2237169689Skan     (use (const:BLK (unspec:BLK [(const_int 0)] UNSPEC_INSN)))
2238132718Skan     (clobber (match_dup 2))
2239169689Skan     (clobber (reg:CC CC_REGNUM))])]
2240132718Skan  ""
2241132718Skan  "operands[2] = gen_rtx_SCRATCH (Pmode);")
2242132718Skan
2243169689Skan(define_insn "*clrmem_short"
2244169689Skan  [(set (match_operand:BLK 0 "memory_operand" "=Q,Q,Q")
2245117395Skan        (const_int 0))
2246169689Skan   (use (match_operand 1 "nonmemory_operand" "n,a,a"))
2247169689Skan   (use (match_operand 2 "immediate_operand" "X,R,X"))
2248169689Skan   (clobber (match_scratch 3 "=X,X,&a"))
2249169689Skan   (clobber (reg:CC CC_REGNUM))]
2250132718Skan  "(GET_MODE (operands[1]) == Pmode || GET_MODE (operands[1]) == VOIDmode)
2251169689Skan   && GET_MODE (operands[3]) == Pmode"
2252169689Skan  "#"
2253169689Skan  [(set_attr "type" "cs")])
2254107590Sobrien
2255169689Skan(define_split
2256169689Skan  [(set (match_operand:BLK 0 "memory_operand" "")
2257169689Skan        (const_int 0))
2258169689Skan   (use (match_operand 1 "const_int_operand" ""))
2259169689Skan   (use (match_operand 2 "immediate_operand" ""))
2260169689Skan   (clobber (scratch))
2261169689Skan   (clobber (reg:CC CC_REGNUM))]
2262169689Skan  "reload_completed"
2263169689Skan  [(parallel
2264169689Skan    [(set (match_dup 0) (const_int 0))
2265169689Skan     (use (match_dup 1))
2266169689Skan     (clobber (reg:CC CC_REGNUM))])]
2267169689Skan  "operands[1] = GEN_INT ((INTVAL (operands[1]) & 0xff) + 1);")
2268107590Sobrien
2269169689Skan(define_split
2270169689Skan  [(set (match_operand:BLK 0 "memory_operand" "")
2271169689Skan        (const_int 0))
2272169689Skan   (use (match_operand 1 "register_operand" ""))
2273169689Skan   (use (match_operand 2 "memory_operand" ""))
2274169689Skan   (clobber (scratch))
2275169689Skan   (clobber (reg:CC CC_REGNUM))]
2276169689Skan  "reload_completed"
2277169689Skan  [(parallel
2278169689Skan    [(unspec [(match_dup 1) (match_dup 2)
2279169689Skan              (const_int 0)] UNSPEC_EXECUTE)
2280169689Skan     (set (match_dup 0) (const_int 0))
2281169689Skan     (use (const_int 1))
2282169689Skan     (clobber (reg:CC CC_REGNUM))])]
2283169689Skan  "")
2284107590Sobrien
2285169689Skan(define_split
2286169689Skan  [(set (match_operand:BLK 0 "memory_operand" "")
2287169689Skan        (const_int 0))
2288169689Skan   (use (match_operand 1 "register_operand" ""))
2289169689Skan   (use (const:BLK (unspec:BLK [(const_int 0)] UNSPEC_INSN)))
2290169689Skan   (clobber (match_operand 2 "register_operand" ""))
2291169689Skan   (clobber (reg:CC CC_REGNUM))]
2292169689Skan  "reload_completed && TARGET_CPU_ZARCH"
2293169689Skan  [(set (match_dup 2) (label_ref (match_dup 3)))
2294169689Skan   (parallel
2295169689Skan    [(unspec [(match_dup 1) (mem:BLK (match_dup 2)) 
2296169689Skan              (label_ref (match_dup 3))] UNSPEC_EXECUTE)
2297169689Skan     (set (match_dup 0) (const_int 0))
2298169689Skan     (use (const_int 1))
2299169689Skan     (clobber (reg:CC CC_REGNUM))])]
2300169689Skan  "operands[3] = gen_label_rtx ();")
2301132718Skan
2302169689Skan; Initialize a block of arbitrary length with (operands[2] % 256). 
2303169689Skan
2304169689Skan(define_expand "setmem_long"
2305132718Skan  [(parallel
2306132718Skan    [(clobber (match_dup 1))
2307132718Skan     (set (match_operand:BLK 0 "memory_operand" "")
2308169689Skan          (match_operand 2 "shift_count_or_setmem_operand" ""))
2309132718Skan     (use (match_operand 1 "general_operand" ""))
2310169689Skan     (use (match_dup 3))
2311169689Skan     (clobber (reg:CC CC_REGNUM))])]
2312132718Skan  ""
2313117395Skan{
2314132718Skan  enum machine_mode dword_mode = word_mode == DImode ? TImode : DImode;
2315132718Skan  rtx reg0 = gen_reg_rtx (dword_mode);
2316132718Skan  rtx reg1 = gen_reg_rtx (dword_mode);
2317132718Skan  rtx addr0 = gen_lowpart (Pmode, gen_highpart (word_mode, reg0));
2318132718Skan  rtx len0 = gen_lowpart (Pmode, reg0);
2319107590Sobrien
2320132718Skan  emit_insn (gen_rtx_CLOBBER (VOIDmode, reg0));
2321132718Skan  emit_move_insn (addr0, force_operand (XEXP (operands[0], 0), NULL_RTX));
2322132718Skan  emit_move_insn (len0, operands[1]);
2323107590Sobrien
2324132718Skan  emit_move_insn (reg1, const0_rtx);
2325107590Sobrien
2326132718Skan  operands[0] = replace_equiv_address_nv (operands[0], addr0);
2327132718Skan  operands[1] = reg0;
2328169689Skan  operands[3] = reg1;
2329132718Skan})
2330107590Sobrien
2331169689Skan(define_insn "*setmem_long"
2332169689Skan  [(clobber (match_operand:<DBL> 0 "register_operand" "=d"))
2333169689Skan   (set (mem:BLK (subreg:P (match_operand:<DBL> 3 "register_operand" "0") 0))
2334169689Skan        (match_operand 2 "shift_count_or_setmem_operand" "Y"))
2335169689Skan   (use (match_dup 3))
2336169689Skan   (use (match_operand:<DBL> 1 "register_operand" "d"))
2337169689Skan   (clobber (reg:CC CC_REGNUM))]
2338169689Skan  ""
2339169689Skan  "mvcle\t%0,%1,%Y2\;jo\t.-4"
2340169689Skan  [(set_attr "length" "8")
2341169689Skan   (set_attr "type" "vs")])
2342107590Sobrien
2343169689Skan(define_insn "*setmem_long_and"
2344169689Skan  [(clobber (match_operand:<DBL> 0 "register_operand" "=d"))
2345169689Skan   (set (mem:BLK (subreg:P (match_operand:<DBL> 3 "register_operand" "0") 0))
2346169689Skan        (and (match_operand 2 "shift_count_or_setmem_operand" "Y")
2347169689Skan	     (match_operand 4 "const_int_operand"             "n")))
2348169689Skan   (use (match_dup 3))
2349169689Skan   (use (match_operand:<DBL> 1 "register_operand" "d"))
2350169689Skan   (clobber (reg:CC CC_REGNUM))]
2351169689Skan  "(INTVAL (operands[4]) & 255) == 255"
2352169689Skan  "mvcle\t%0,%1,%Y2\;jo\t.-4"
2353169689Skan  [(set_attr "length" "8")
2354169689Skan   (set_attr "type" "vs")])
2355107590Sobrien;
2356132718Skan; cmpmemM instruction pattern(s).
2357107590Sobrien;
2358107590Sobrien
2359132718Skan(define_expand "cmpmemsi"
2360117395Skan  [(set (match_operand:SI 0 "register_operand" "")
2361117395Skan        (compare:SI (match_operand:BLK 1 "memory_operand" "")
2362117395Skan                    (match_operand:BLK 2 "memory_operand" "") ) )
2363117395Skan   (use (match_operand:SI 3 "general_operand" ""))
2364117395Skan   (use (match_operand:SI 4 "" ""))]
2365117395Skan  ""
2366132718Skan  "s390_expand_cmpmem (operands[0], operands[1],
2367117395Skan                       operands[2], operands[3]); DONE;")
2368107590Sobrien
2369117395Skan; Compare a block that is up to 256 bytes in length.
2370117395Skan; The block length is taken as (operands[2] % 256) + 1.
2371107590Sobrien
2372132718Skan(define_expand "cmpmem_short"
2373132718Skan  [(parallel
2374169689Skan    [(set (reg:CCU CC_REGNUM)
2375169689Skan          (compare:CCU (match_operand:BLK 0 "memory_operand" "")
2376132718Skan                       (match_operand:BLK 1 "memory_operand" "")))
2377132718Skan     (use (match_operand 2 "nonmemory_operand" ""))
2378169689Skan     (use (const:BLK (unspec:BLK [(const_int 0)] UNSPEC_INSN)))
2379132718Skan     (clobber (match_dup 3))])]
2380132718Skan  ""
2381132718Skan  "operands[3] = gen_rtx_SCRATCH (Pmode);")
2382132718Skan
2383132718Skan(define_insn "*cmpmem_short"
2384169689Skan  [(set (reg:CCU CC_REGNUM)
2385169689Skan        (compare:CCU (match_operand:BLK 0 "memory_operand" "Q,Q,Q")
2386169689Skan                     (match_operand:BLK 1 "memory_operand" "Q,Q,Q")))
2387169689Skan   (use (match_operand 2 "nonmemory_operand" "n,a,a"))
2388169689Skan   (use (match_operand 3 "immediate_operand" "X,R,X"))
2389169689Skan   (clobber (match_scratch 4 "=X,X,&a"))]
2390132718Skan  "(GET_MODE (operands[2]) == Pmode || GET_MODE (operands[2]) == VOIDmode)
2391169689Skan   && GET_MODE (operands[4]) == Pmode"
2392169689Skan  "#"
2393169689Skan  [(set_attr "type" "cs")])
2394107590Sobrien
2395169689Skan(define_split
2396169689Skan  [(set (reg:CCU CC_REGNUM)
2397169689Skan        (compare:CCU (match_operand:BLK 0 "memory_operand" "")
2398169689Skan                     (match_operand:BLK 1 "memory_operand" "")))
2399169689Skan   (use (match_operand 2 "const_int_operand" ""))
2400169689Skan   (use (match_operand 3 "immediate_operand" ""))
2401169689Skan   (clobber (scratch))]
2402169689Skan  "reload_completed"
2403169689Skan  [(parallel
2404169689Skan    [(set (reg:CCU CC_REGNUM) (compare:CCU (match_dup 0) (match_dup 1)))
2405169689Skan     (use (match_dup 2))])]
2406169689Skan  "operands[2] = GEN_INT ((INTVAL (operands[2]) & 0xff) + 1);")
2407107590Sobrien
2408169689Skan(define_split
2409169689Skan  [(set (reg:CCU CC_REGNUM)
2410169689Skan        (compare:CCU (match_operand:BLK 0 "memory_operand" "")
2411169689Skan                     (match_operand:BLK 1 "memory_operand" "")))
2412169689Skan   (use (match_operand 2 "register_operand" ""))
2413169689Skan   (use (match_operand 3 "memory_operand" ""))
2414169689Skan   (clobber (scratch))]
2415169689Skan  "reload_completed"
2416169689Skan  [(parallel
2417169689Skan    [(unspec [(match_dup 2) (match_dup 3)
2418169689Skan              (const_int 0)] UNSPEC_EXECUTE)
2419169689Skan     (set (reg:CCU CC_REGNUM) (compare:CCU (match_dup 0) (match_dup 1)))
2420169689Skan     (use (const_int 1))])]
2421169689Skan  "")
2422107590Sobrien
2423169689Skan(define_split
2424169689Skan  [(set (reg:CCU CC_REGNUM)
2425169689Skan        (compare:CCU (match_operand:BLK 0 "memory_operand" "")
2426169689Skan                     (match_operand:BLK 1 "memory_operand" "")))
2427169689Skan   (use (match_operand 2 "register_operand" ""))
2428169689Skan   (use (const:BLK (unspec:BLK [(const_int 0)] UNSPEC_INSN)))
2429169689Skan   (clobber (match_operand 3 "register_operand" ""))]
2430169689Skan  "reload_completed && TARGET_CPU_ZARCH"
2431169689Skan  [(set (match_dup 3) (label_ref (match_dup 4)))
2432169689Skan   (parallel
2433169689Skan    [(unspec [(match_dup 2) (mem:BLK (match_dup 3)) 
2434169689Skan              (label_ref (match_dup 4))] UNSPEC_EXECUTE)
2435169689Skan     (set (reg:CCU CC_REGNUM) (compare:CCU (match_dup 0) (match_dup 1)))
2436169689Skan     (use (const_int 1))])]
2437169689Skan  "operands[4] = gen_label_rtx ();")
2438169689Skan
2439132718Skan; Compare a block of arbitrary length.
2440132718Skan
2441132718Skan(define_expand "cmpmem_long"
2442132718Skan  [(parallel
2443132718Skan    [(clobber (match_dup 2))
2444132718Skan     (clobber (match_dup 3))
2445169689Skan     (set (reg:CCU CC_REGNUM)
2446169689Skan          (compare:CCU (match_operand:BLK 0 "memory_operand" "")
2447132718Skan                       (match_operand:BLK 1 "memory_operand" "")))
2448132718Skan     (use (match_operand 2 "general_operand" ""))
2449132718Skan     (use (match_dup 3))])]
2450132718Skan  ""
2451107590Sobrien{
2452132718Skan  enum machine_mode dword_mode = word_mode == DImode ? TImode : DImode;
2453132718Skan  rtx reg0 = gen_reg_rtx (dword_mode);
2454132718Skan  rtx reg1 = gen_reg_rtx (dword_mode);
2455132718Skan  rtx addr0 = gen_lowpart (Pmode, gen_highpart (word_mode, reg0));
2456132718Skan  rtx addr1 = gen_lowpart (Pmode, gen_highpart (word_mode, reg1));
2457132718Skan  rtx len0 = gen_lowpart (Pmode, reg0);
2458132718Skan  rtx len1 = gen_lowpart (Pmode, reg1);
2459107590Sobrien
2460132718Skan  emit_insn (gen_rtx_CLOBBER (VOIDmode, reg0));
2461132718Skan  emit_move_insn (addr0, force_operand (XEXP (operands[0], 0), NULL_RTX));
2462132718Skan  emit_move_insn (len0, operands[2]);
2463107590Sobrien
2464132718Skan  emit_insn (gen_rtx_CLOBBER (VOIDmode, reg1));
2465132718Skan  emit_move_insn (addr1, force_operand (XEXP (operands[1], 0), NULL_RTX));
2466132718Skan  emit_move_insn (len1, operands[2]);
2467107590Sobrien
2468132718Skan  operands[0] = replace_equiv_address_nv (operands[0], addr0);
2469132718Skan  operands[1] = replace_equiv_address_nv (operands[1], addr1);
2470132718Skan  operands[2] = reg0;
2471132718Skan  operands[3] = reg1;
2472132718Skan})
2473107590Sobrien
2474169689Skan(define_insn "*cmpmem_long"
2475169689Skan  [(clobber (match_operand:<DBL> 0 "register_operand" "=d"))
2476169689Skan   (clobber (match_operand:<DBL> 1 "register_operand" "=d"))
2477169689Skan   (set (reg:CCU CC_REGNUM)
2478169689Skan        (compare:CCU (mem:BLK (subreg:P (match_operand:<DBL> 2 "register_operand" "0") 0))
2479169689Skan                     (mem:BLK (subreg:P (match_operand:<DBL> 3 "register_operand" "1") 0))))
2480117395Skan   (use (match_dup 2))
2481117395Skan   (use (match_dup 3))]
2482169689Skan  ""
2483132718Skan  "clcle\t%0,%1,0\;jo\t.-4"
2484169689Skan  [(set_attr "length" "8")
2485169689Skan   (set_attr "type" "vs")])
2486107590Sobrien
2487169689Skan; Convert CCUmode condition code to integer.
2488169689Skan; Result is zero if EQ, positive if LTU, negative if GTU.
2489107590Sobrien
2490169689Skan(define_insn_and_split "cmpint"
2491107590Sobrien  [(set (match_operand:SI 0 "register_operand" "=d")
2492169689Skan        (unspec:SI [(match_operand:CCU 1 "register_operand" "0")]
2493169689Skan                   UNSPEC_CMPINT))
2494169689Skan   (clobber (reg:CC CC_REGNUM))]
2495107590Sobrien  ""
2496169689Skan  "#"
2497169689Skan  "reload_completed"
2498169689Skan  [(set (match_dup 0) (ashift:SI (match_dup 0) (const_int 2)))
2499169689Skan   (parallel
2500169689Skan    [(set (match_dup 0) (ashiftrt:SI (match_dup 0) (const_int 30)))
2501169689Skan     (clobber (reg:CC CC_REGNUM))])])
2502169689Skan
2503169689Skan(define_insn_and_split "*cmpint_cc"
2504169689Skan  [(set (reg CC_REGNUM)
2505169689Skan        (compare (unspec:SI [(match_operand:CCU 1 "register_operand" "0")]
2506169689Skan                            UNSPEC_CMPINT)
2507169689Skan                 (const_int 0)))
2508169689Skan   (set (match_operand:SI 0 "register_operand" "=d")
2509169689Skan        (unspec:SI [(match_dup 1)] UNSPEC_CMPINT))]
2510169689Skan  "s390_match_ccmode (insn, CCSmode)"
2511169689Skan  "#"
2512169689Skan  "&& reload_completed"
2513169689Skan  [(set (match_dup 0) (ashift:SI (match_dup 0) (const_int 2)))
2514169689Skan   (parallel
2515169689Skan    [(set (match_dup 2) (match_dup 3))
2516169689Skan     (set (match_dup 0) (ashiftrt:SI (match_dup 0) (const_int 30)))])]
2517107590Sobrien{
2518169689Skan  rtx result = gen_rtx_ASHIFTRT (SImode, operands[0], GEN_INT (30));
2519169689Skan  operands[2] = SET_DEST (XVECEXP (PATTERN (curr_insn), 0, 0));
2520169689Skan  operands[3] = gen_rtx_COMPARE (GET_MODE (operands[2]), result, const0_rtx);
2521169689Skan})
2522107590Sobrien
2523169689Skan(define_insn_and_split "*cmpint_sign"
2524107590Sobrien  [(set (match_operand:DI 0 "register_operand" "=d")
2525169689Skan        (sign_extend:DI (unspec:SI [(match_operand:CCU 1 "register_operand" "0")]
2526169689Skan                                   UNSPEC_CMPINT)))
2527169689Skan   (clobber (reg:CC CC_REGNUM))]
2528107590Sobrien  "TARGET_64BIT"
2529169689Skan  "#"
2530169689Skan  "&& reload_completed"
2531169689Skan  [(set (match_dup 0) (ashift:DI (match_dup 0) (const_int 34)))
2532169689Skan   (parallel
2533169689Skan    [(set (match_dup 0) (ashiftrt:DI (match_dup 0) (const_int 62)))
2534169689Skan     (clobber (reg:CC CC_REGNUM))])])
2535169689Skan
2536169689Skan(define_insn_and_split "*cmpint_sign_cc"
2537169689Skan  [(set (reg CC_REGNUM)
2538169689Skan        (compare (ashiftrt:DI (ashift:DI (subreg:DI 
2539169689Skan                   (unspec:SI [(match_operand:CCU 1 "register_operand" "0")]
2540169689Skan                              UNSPEC_CMPINT) 0)
2541169689Skan                   (const_int 32)) (const_int 32))
2542169689Skan                 (const_int 0)))
2543169689Skan   (set (match_operand:DI 0 "register_operand" "=d")
2544169689Skan        (sign_extend:DI (unspec:SI [(match_dup 1)] UNSPEC_CMPINT)))]
2545169689Skan  "s390_match_ccmode (insn, CCSmode) && TARGET_64BIT"
2546169689Skan  "#"
2547169689Skan  "&& reload_completed"
2548169689Skan  [(set (match_dup 0) (ashift:DI (match_dup 0) (const_int 34)))
2549169689Skan   (parallel
2550169689Skan    [(set (match_dup 2) (match_dup 3))
2551169689Skan     (set (match_dup 0) (ashiftrt:DI (match_dup 0) (const_int 62)))])]
2552107590Sobrien{
2553169689Skan  rtx result = gen_rtx_ASHIFTRT (DImode, operands[0], GEN_INT (62));
2554169689Skan  operands[2] = SET_DEST (XVECEXP (PATTERN (curr_insn), 0, 0));
2555169689Skan  operands[3] = gen_rtx_COMPARE (GET_MODE (operands[2]), result, const0_rtx);
2556169689Skan})
2557107590Sobrien
2558107590Sobrien
2559107590Sobrien;;
2560107590Sobrien;;- Conversion instructions.
2561107590Sobrien;;
2562107590Sobrien
2563169689Skan(define_insn "*sethighpartsi"
2564132718Skan  [(set (match_operand:SI 0 "register_operand" "=d,d")
2565169689Skan	(unspec:SI [(match_operand:BLK 1 "s_operand" "Q,S")
2566169689Skan		    (match_operand 2 "const_int_operand" "n,n")] UNSPEC_ICM))
2567169689Skan   (clobber (reg:CC CC_REGNUM))]
2568107590Sobrien  ""
2569132718Skan  "@
2570169689Skan   icm\t%0,%2,%S1
2571169689Skan   icmy\t%0,%2,%S1"
2572132718Skan  [(set_attr "op_type" "RS,RSY")])
2573107590Sobrien
2574169689Skan(define_insn "*sethighpartdi_64"
2575107590Sobrien  [(set (match_operand:DI 0 "register_operand" "=d")
2576169689Skan	(unspec:DI [(match_operand:BLK 1 "s_operand" "QS")
2577169689Skan		    (match_operand 2 "const_int_operand" "n")] UNSPEC_ICM))
2578169689Skan   (clobber (reg:CC CC_REGNUM))]
2579107590Sobrien  "TARGET_64BIT"
2580169689Skan  "icmh\t%0,%2,%S1"
2581132718Skan  [(set_attr "op_type" "RSY")])
2582107590Sobrien
2583169689Skan(define_insn "*sethighpartdi_31"
2584132718Skan  [(set (match_operand:DI 0 "register_operand" "=d,d")
2585169689Skan	(unspec:DI [(match_operand:BLK 1 "s_operand" "Q,S")
2586169689Skan		    (match_operand 2 "const_int_operand" "n,n")] UNSPEC_ICM))
2587169689Skan   (clobber (reg:CC CC_REGNUM))]
2588107590Sobrien  "!TARGET_64BIT"
2589132718Skan  "@
2590169689Skan   icm\t%0,%2,%S1
2591169689Skan   icmy\t%0,%2,%S1"
2592132718Skan  [(set_attr "op_type" "RS,RSY")])
2593107590Sobrien
2594169689Skan(define_insn_and_split "*extzv<mode>"
2595169689Skan  [(set (match_operand:GPR 0 "register_operand" "=d")
2596169689Skan	(zero_extract:GPR (match_operand:QI 1 "s_operand" "QS")
2597169689Skan		          (match_operand 2 "const_int_operand" "n")
2598169689Skan		          (const_int 0)))
2599169689Skan   (clobber (reg:CC CC_REGNUM))]
2600169689Skan  "INTVAL (operands[2]) > 0
2601169689Skan   && INTVAL (operands[2]) <= GET_MODE_BITSIZE (SImode)"
2602117395Skan  "#"
2603117395Skan  "&& reload_completed"
2604107590Sobrien  [(parallel
2605169689Skan    [(set (match_dup 0) (unspec:GPR [(match_dup 1) (match_dup 3)] UNSPEC_ICM))
2606169689Skan     (clobber (reg:CC CC_REGNUM))])
2607169689Skan   (set (match_dup 0) (lshiftrt:GPR (match_dup 0) (match_dup 2)))]
2608107590Sobrien{
2609169689Skan  int bitsize = INTVAL (operands[2]);
2610169689Skan  int size = (bitsize - 1) / BITS_PER_UNIT + 1; /* round up */
2611169689Skan  int mask = ((1ul << size) - 1) << (GET_MODE_SIZE (SImode) - size);
2612107590Sobrien
2613169689Skan  operands[1] = adjust_address (operands[1], BLKmode, 0);
2614169689Skan  set_mem_size (operands[1], GEN_INT (size));
2615169689Skan  operands[2] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode) - bitsize);
2616169689Skan  operands[3] = GEN_INT (mask);
2617169689Skan})
2618169689Skan
2619169689Skan(define_insn_and_split "*extv<mode>"
2620169689Skan  [(set (match_operand:GPR 0 "register_operand" "=d")
2621169689Skan	(sign_extract:GPR (match_operand:QI 1 "s_operand" "QS")
2622169689Skan		          (match_operand 2 "const_int_operand" "n")
2623169689Skan		          (const_int 0)))
2624169689Skan   (clobber (reg:CC CC_REGNUM))]
2625169689Skan  "INTVAL (operands[2]) > 0
2626169689Skan   && INTVAL (operands[2]) <= GET_MODE_BITSIZE (SImode)"
2627117395Skan  "#"
2628117395Skan  "&& reload_completed"
2629107590Sobrien  [(parallel
2630169689Skan    [(set (match_dup 0) (unspec:GPR [(match_dup 1) (match_dup 3)] UNSPEC_ICM))
2631169689Skan     (clobber (reg:CC CC_REGNUM))])
2632169689Skan   (parallel
2633169689Skan    [(set (match_dup 0) (ashiftrt:GPR (match_dup 0) (match_dup 2)))
2634169689Skan     (clobber (reg:CC CC_REGNUM))])]
2635107590Sobrien{
2636169689Skan  int bitsize = INTVAL (operands[2]);
2637169689Skan  int size = (bitsize - 1) / BITS_PER_UNIT + 1; /* round up */
2638169689Skan  int mask = ((1ul << size) - 1) << (GET_MODE_SIZE (SImode) - size);
2639169689Skan
2640169689Skan  operands[1] = adjust_address (operands[1], BLKmode, 0);
2641169689Skan  set_mem_size (operands[1], GEN_INT (size));
2642169689Skan  operands[2] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode) - bitsize);
2643169689Skan  operands[3] = GEN_INT (mask);
2644169689Skan})
2645169689Skan
2646169689Skan;
2647169689Skan; insv instruction patterns
2648169689Skan;
2649169689Skan
2650169689Skan(define_expand "insv"
2651169689Skan  [(set (zero_extract (match_operand 0 "nonimmediate_operand" "")
2652169689Skan		      (match_operand 1 "const_int_operand" "")
2653169689Skan		      (match_operand 2 "const_int_operand" ""))
2654169689Skan	(match_operand 3 "general_operand" ""))]
2655169689Skan  ""
2656169689Skan{
2657169689Skan  if (s390_expand_insv (operands[0], operands[1], operands[2], operands[3]))
2658169689Skan    DONE;
2659169689Skan  FAIL;
2660169689Skan})
2661169689Skan
2662169689Skan(define_insn "*insv<mode>_mem_reg"
2663169689Skan  [(set (zero_extract:P (match_operand:QI 0 "memory_operand" "+Q,S")
2664169689Skan			(match_operand 1 "const_int_operand" "n,n")
2665169689Skan			(const_int 0))
2666169689Skan	(match_operand:P 2 "register_operand" "d,d"))]
2667169689Skan  "INTVAL (operands[1]) > 0
2668169689Skan   && INTVAL (operands[1]) <= GET_MODE_BITSIZE (SImode)
2669169689Skan   && INTVAL (operands[1]) % BITS_PER_UNIT == 0"
2670169689Skan{
2671169689Skan    int size = INTVAL (operands[1]) / BITS_PER_UNIT;
2672169689Skan
2673169689Skan    operands[1] = GEN_INT ((1ul << size) - 1);
2674169689Skan    return (which_alternative == 0) ? "stcm\t%2,%1,%S0" 
2675169689Skan				    : "stcmy\t%2,%1,%S0";
2676132718Skan}
2677169689Skan  [(set_attr "op_type" "RS,RSY")])
2678107590Sobrien
2679169689Skan(define_insn "*insvdi_mem_reghigh"
2680169689Skan  [(set (zero_extract:DI (match_operand:QI 0 "memory_operand" "+QS")
2681169689Skan			 (match_operand 1 "const_int_operand" "n")
2682169689Skan			 (const_int 0))
2683169689Skan	(lshiftrt:DI (match_operand:DI 2 "register_operand" "d")
2684169689Skan		     (const_int 32)))]
2685169689Skan  "TARGET_64BIT
2686169689Skan   && INTVAL (operands[1]) > 0
2687169689Skan   && INTVAL (operands[1]) <= GET_MODE_BITSIZE (SImode)
2688169689Skan   && INTVAL (operands[1]) % BITS_PER_UNIT == 0"
2689169689Skan{
2690169689Skan    int size = INTVAL (operands[1]) / BITS_PER_UNIT;
2691169689Skan
2692169689Skan    operands[1] = GEN_INT ((1ul << size) - 1);
2693169689Skan    return "stcmh\t%2,%1,%S0";
2694169689Skan}
2695169689Skan[(set_attr "op_type" "RSY")])
2696169689Skan
2697169689Skan(define_insn "*insv<mode>_reg_imm"
2698169689Skan  [(set (zero_extract:P (match_operand:P 0 "register_operand" "+d")
2699169689Skan			(const_int 16)
2700169689Skan			(match_operand 1 "const_int_operand" "n"))
2701169689Skan	(match_operand:P 2 "const_int_operand" "n"))]
2702169689Skan  "TARGET_ZARCH
2703169689Skan   && INTVAL (operands[1]) >= 0
2704169689Skan   && INTVAL (operands[1]) < BITS_PER_WORD
2705169689Skan   && INTVAL (operands[1]) % 16 == 0"
2706169689Skan{
2707169689Skan  switch (BITS_PER_WORD - INTVAL (operands[1]))
2708169689Skan    {
2709169689Skan      case 64: return "iihh\t%0,%x2"; break;
2710169689Skan      case 48: return "iihl\t%0,%x2"; break;
2711169689Skan      case 32: return "iilh\t%0,%x2"; break;
2712169689Skan      case 16: return "iill\t%0,%x2"; break;
2713169689Skan      default: gcc_unreachable();
2714169689Skan    }
2715169689Skan}
2716169689Skan  [(set_attr "op_type" "RI")])
2717169689Skan
2718169689Skan(define_insn "*insv<mode>_reg_extimm"
2719169689Skan  [(set (zero_extract:P (match_operand:P 0 "register_operand" "+d")
2720169689Skan			(const_int 32)
2721169689Skan			(match_operand 1 "const_int_operand" "n"))
2722169689Skan	(match_operand:P 2 "const_int_operand" "n"))]
2723169689Skan  "TARGET_EXTIMM
2724169689Skan   && INTVAL (operands[1]) >= 0
2725169689Skan   && INTVAL (operands[1]) < BITS_PER_WORD
2726169689Skan   && INTVAL (operands[1]) % 32 == 0"
2727169689Skan{
2728169689Skan  switch (BITS_PER_WORD - INTVAL (operands[1]))
2729169689Skan    {
2730169689Skan      case 64: return "iihf\t%0,%o2"; break;
2731169689Skan      case 32: return "iilf\t%0,%o2"; break;
2732169689Skan      default: gcc_unreachable();
2733169689Skan    }
2734169689Skan}
2735169689Skan  [(set_attr "op_type" "RIL")])
2736169689Skan
2737107590Sobrien;
2738107590Sobrien; extendsidi2 instruction pattern(s).
2739107590Sobrien;
2740107590Sobrien
2741107590Sobrien(define_expand "extendsidi2"
2742107590Sobrien  [(set (match_operand:DI 0 "register_operand" "")
2743107590Sobrien        (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "")))]
2744107590Sobrien  ""
2745107590Sobrien{
2746107590Sobrien  if (!TARGET_64BIT)
2747107590Sobrien    {
2748107590Sobrien      emit_insn (gen_rtx_CLOBBER (VOIDmode, operands[0]));
2749107590Sobrien      emit_move_insn (gen_highpart (SImode, operands[0]), operands[1]);
2750107590Sobrien      emit_move_insn (gen_lowpart (SImode, operands[0]), const0_rtx);
2751107590Sobrien      emit_insn (gen_ashrdi3 (operands[0], operands[0], GEN_INT (32)));
2752107590Sobrien      DONE;
2753107590Sobrien    }
2754169689Skan})
2755107590Sobrien
2756107590Sobrien(define_insn "*extendsidi2"
2757107590Sobrien  [(set (match_operand:DI 0 "register_operand" "=d,d")
2758107590Sobrien        (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "d,m")))]
2759107590Sobrien  "TARGET_64BIT"
2760107590Sobrien  "@
2761132718Skan   lgfr\t%0,%1
2762132718Skan   lgf\t%0,%1"
2763132718Skan  [(set_attr "op_type" "RRE,RXY")])
2764107590Sobrien
2765107590Sobrien;
2766169689Skan; extend(hi|qi)(si|di)2 instruction pattern(s).
2767107590Sobrien;
2768107590Sobrien
2769169689Skan(define_expand "extend<HQI:mode><DSI:mode>2"
2770169689Skan  [(set (match_operand:DSI 0 "register_operand" "")
2771169689Skan        (sign_extend:DSI (match_operand:HQI 1 "nonimmediate_operand" "")))]
2772107590Sobrien  ""
2773107590Sobrien{
2774169689Skan  if (<DSI:MODE>mode == DImode && !TARGET_64BIT)
2775107590Sobrien    {
2776107590Sobrien      rtx tmp = gen_reg_rtx (SImode);
2777169689Skan      emit_insn (gen_extend<HQI:mode>si2 (tmp, operands[1]));
2778107590Sobrien      emit_insn (gen_extendsidi2 (operands[0], tmp));
2779107590Sobrien      DONE;
2780107590Sobrien    }
2781169689Skan  else if (!TARGET_EXTIMM)
2782107590Sobrien    {
2783169689Skan      rtx bitcount = GEN_INT (GET_MODE_BITSIZE (<DSI:MODE>mode) -
2784169689Skan			      GET_MODE_BITSIZE (<HQI:MODE>mode));
2785169689Skan
2786169689Skan      operands[1] = gen_lowpart (<DSI:MODE>mode, operands[1]);
2787169689Skan      emit_insn (gen_ashl<DSI:mode>3 (operands[0], operands[1], bitcount));
2788169689Skan      emit_insn (gen_ashr<DSI:mode>3 (operands[0], operands[0], bitcount));
2789107590Sobrien      DONE;
2790107590Sobrien    }
2791169689Skan})
2792107590Sobrien
2793169689Skan;
2794169689Skan; extendhidi2 instruction pattern(s).
2795169689Skan;
2796169689Skan
2797169689Skan(define_insn "*extendhidi2_extimm"
2798169689Skan  [(set (match_operand:DI 0 "register_operand" "=d,d")
2799169689Skan        (sign_extend:DI (match_operand:HI 1 "nonimmediate_operand" "d,m")))]
2800169689Skan  "TARGET_64BIT && TARGET_EXTIMM"
2801169689Skan  "@
2802169689Skan   lghr\t%0,%1
2803169689Skan   lgh\t%0,%1"
2804169689Skan  [(set_attr "op_type" "RRE,RXY")])
2805169689Skan
2806107590Sobrien(define_insn "*extendhidi2"
2807107590Sobrien  [(set (match_operand:DI 0 "register_operand" "=d")
2808107590Sobrien        (sign_extend:DI (match_operand:HI 1 "memory_operand" "m")))]
2809107590Sobrien  "TARGET_64BIT"
2810132718Skan  "lgh\t%0,%1"
2811132718Skan  [(set_attr "op_type" "RXY")])
2812107590Sobrien
2813107590Sobrien;
2814107590Sobrien; extendhisi2 instruction pattern(s).
2815107590Sobrien;
2816107590Sobrien
2817169689Skan(define_insn "*extendhisi2_extimm"
2818169689Skan  [(set (match_operand:SI 0 "register_operand" "=d,d,d")
2819169689Skan        (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "d,R,T")))]
2820169689Skan  "TARGET_EXTIMM"
2821169689Skan  "@
2822169689Skan   lhr\t%0,%1
2823169689Skan   lh\t%0,%1
2824169689Skan   lhy\t%0,%1"
2825169689Skan  [(set_attr "op_type" "RRE,RX,RXY")])
2826107590Sobrien
2827107590Sobrien(define_insn "*extendhisi2"
2828132718Skan  [(set (match_operand:SI 0 "register_operand" "=d,d")
2829132718Skan        (sign_extend:SI (match_operand:HI 1 "memory_operand" "R,T")))]
2830169689Skan  "!TARGET_EXTIMM"
2831132718Skan  "@
2832132718Skan   lh\t%0,%1
2833132718Skan   lhy\t%0,%1"
2834132718Skan  [(set_attr "op_type" "RX,RXY")])
2835107590Sobrien
2836107590Sobrien;
2837169689Skan; extendqi(si|di)2 instruction pattern(s).
2838107590Sobrien;
2839107590Sobrien
2840169689Skan; lbr, lgbr, lb, lgb
2841169689Skan(define_insn "*extendqi<mode>2_extimm"
2842169689Skan  [(set (match_operand:GPR 0 "register_operand" "=d,d")
2843169689Skan        (sign_extend:GPR (match_operand:QI 1 "nonimmediate_operand" "d,m")))]
2844169689Skan  "TARGET_EXTIMM"
2845169689Skan  "@
2846169689Skan   l<g>br\t%0,%1
2847169689Skan   l<g>b\t%0,%1"
2848169689Skan  [(set_attr "op_type" "RRE,RXY")])
2849107590Sobrien
2850169689Skan; lb, lgb
2851169689Skan(define_insn "*extendqi<mode>2"
2852169689Skan  [(set (match_operand:GPR 0 "register_operand" "=d")
2853169689Skan        (sign_extend:GPR (match_operand:QI 1 "memory_operand" "m")))]
2854169689Skan  "!TARGET_EXTIMM && TARGET_LONG_DISPLACEMENT"
2855169689Skan  "l<g>b\t%0,%1"
2856132718Skan  [(set_attr "op_type" "RXY")])
2857132718Skan
2858169689Skan(define_insn_and_split "*extendqi<mode>2_short_displ"
2859169689Skan  [(set (match_operand:GPR 0 "register_operand" "=d")
2860169689Skan        (sign_extend:GPR (match_operand:QI 1 "s_operand" "Q")))
2861169689Skan   (clobber (reg:CC CC_REGNUM))]
2862169689Skan  "!TARGET_EXTIMM && !TARGET_LONG_DISPLACEMENT"
2863132718Skan  "#"
2864132718Skan  "&& reload_completed"
2865107590Sobrien  [(parallel
2866169689Skan    [(set (match_dup 0) (unspec:GPR [(match_dup 1) (const_int 8)] UNSPEC_ICM))
2867169689Skan     (clobber (reg:CC CC_REGNUM))])
2868107590Sobrien   (parallel
2869169689Skan    [(set (match_dup 0) (ashiftrt:GPR (match_dup 0) (match_dup 2)))
2870169689Skan     (clobber (reg:CC CC_REGNUM))])]
2871169689Skan{
2872169689Skan  operands[1] = adjust_address (operands[1], BLKmode, 0);
2873169689Skan  set_mem_size (operands[1], GEN_INT (GET_MODE_SIZE (QImode)));
2874169689Skan  operands[2] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)
2875169689Skan			 - GET_MODE_BITSIZE (QImode));
2876169689Skan})
2877107590Sobrien
2878107590Sobrien;
2879107590Sobrien; zero_extendsidi2 instruction pattern(s).
2880107590Sobrien;
2881107590Sobrien
2882107590Sobrien(define_expand "zero_extendsidi2"
2883107590Sobrien  [(set (match_operand:DI 0 "register_operand" "")
2884107590Sobrien        (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "")))]
2885107590Sobrien  ""
2886107590Sobrien{
2887107590Sobrien  if (!TARGET_64BIT)
2888107590Sobrien    {
2889107590Sobrien      emit_insn (gen_rtx_CLOBBER (VOIDmode, operands[0]));
2890107590Sobrien      emit_move_insn (gen_lowpart (SImode, operands[0]), operands[1]);
2891107590Sobrien      emit_move_insn (gen_highpart (SImode, operands[0]), const0_rtx);
2892107590Sobrien      DONE;
2893107590Sobrien    }
2894169689Skan})
2895107590Sobrien
2896107590Sobrien(define_insn "*zero_extendsidi2"
2897107590Sobrien  [(set (match_operand:DI 0 "register_operand" "=d,d")
2898107590Sobrien        (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "d,m")))]
2899107590Sobrien  "TARGET_64BIT"
2900107590Sobrien  "@
2901132718Skan   llgfr\t%0,%1
2902132718Skan   llgf\t%0,%1"
2903132718Skan  [(set_attr "op_type" "RRE,RXY")])
2904107590Sobrien
2905107590Sobrien;
2906169689Skan; LLGT-type instructions (zero-extend from 31 bit to 64 bit).
2907107590Sobrien;
2908107590Sobrien
2909169689Skan(define_insn "*llgt_sidi"
2910169689Skan  [(set (match_operand:DI 0 "register_operand" "=d")
2911169689Skan        (and:DI (subreg:DI (match_operand:SI 1 "memory_operand" "m") 0)
2912169689Skan		(const_int 2147483647)))]
2913169689Skan  "TARGET_64BIT"
2914169689Skan  "llgt\t%0,%1"
2915169689Skan  [(set_attr "op_type"  "RXE")])
2916107590Sobrien
2917169689Skan(define_insn_and_split "*llgt_sidi_split"
2918107590Sobrien  [(set (match_operand:DI 0 "register_operand" "=d")
2919169689Skan        (and:DI (subreg:DI (match_operand:SI 1 "memory_operand" "m") 0)
2920169689Skan		(const_int 2147483647)))
2921169689Skan   (clobber (reg:CC CC_REGNUM))]
2922107590Sobrien  "TARGET_64BIT"
2923169689Skan  "#"
2924169689Skan  "&& reload_completed"
2925169689Skan  [(set (match_dup 0)
2926169689Skan        (and:DI (subreg:DI (match_dup 1) 0)
2927169689Skan		(const_int 2147483647)))]
2928169689Skan  "")
2929107590Sobrien
2930132718Skan(define_insn "*llgt_sisi"
2931132718Skan  [(set (match_operand:SI 0 "register_operand" "=d,d")
2932132718Skan        (and:SI (match_operand:SI 1 "nonimmediate_operand" "d,m")
2933132718Skan		(const_int 2147483647)))]
2934169689Skan  "TARGET_ZARCH"
2935132718Skan  "@
2936132718Skan   llgtr\t%0,%1
2937132718Skan   llgt\t%0,%1"
2938132718Skan  [(set_attr "op_type"  "RRE,RXE")])
2939132718Skan
2940132718Skan(define_insn "*llgt_didi"
2941132718Skan  [(set (match_operand:DI 0 "register_operand" "=d,d")
2942132718Skan        (and:DI (match_operand:DI 1 "nonimmediate_operand" "d,o")
2943132718Skan                (const_int 2147483647)))]
2944132718Skan  "TARGET_64BIT"
2945132718Skan  "@
2946132718Skan   llgtr\t%0,%1
2947132718Skan   llgt\t%0,%N1"
2948132718Skan  [(set_attr "op_type"  "RRE,RXE")])
2949132718Skan
2950132718Skan(define_split
2951169689Skan  [(set (match_operand:GPR 0 "register_operand" "")
2952169689Skan        (and:GPR (match_operand:GPR 1 "nonimmediate_operand" "")
2953169689Skan                 (const_int 2147483647)))
2954169689Skan   (clobber (reg:CC CC_REGNUM))]
2955169689Skan  "TARGET_ZARCH && reload_completed"
2956132718Skan  [(set (match_dup 0)
2957169689Skan        (and:GPR (match_dup 1)
2958169689Skan                 (const_int 2147483647)))]
2959132718Skan  "")
2960132718Skan
2961132718Skan;
2962169689Skan; zero_extend(hi|qi)(si|di)2 instruction pattern(s).
2963107590Sobrien;
2964107590Sobrien
2965169689Skan(define_expand "zero_extend<mode>di2"
2966107590Sobrien  [(set (match_operand:DI 0 "register_operand" "")
2967169689Skan        (zero_extend:DI (match_operand:HQI 1 "nonimmediate_operand" "")))]
2968107590Sobrien  ""
2969107590Sobrien{
2970107590Sobrien  if (!TARGET_64BIT)
2971107590Sobrien    {
2972107590Sobrien      rtx tmp = gen_reg_rtx (SImode);
2973169689Skan      emit_insn (gen_zero_extend<mode>si2 (tmp, operands[1]));
2974107590Sobrien      emit_insn (gen_zero_extendsidi2 (operands[0], tmp));
2975107590Sobrien      DONE;
2976107590Sobrien    }
2977169689Skan  else if (!TARGET_EXTIMM)
2978107590Sobrien    {
2979169689Skan      rtx bitcount = GEN_INT (GET_MODE_BITSIZE(DImode) - 
2980169689Skan			      GET_MODE_BITSIZE(<MODE>mode));
2981107590Sobrien      operands[1] = gen_lowpart (DImode, operands[1]);
2982169689Skan      emit_insn (gen_ashldi3 (operands[0], operands[1], bitcount));
2983169689Skan      emit_insn (gen_lshrdi3 (operands[0], operands[0], bitcount));
2984107590Sobrien      DONE;
2985107590Sobrien    }
2986169689Skan})
2987107590Sobrien
2988169689Skan(define_expand "zero_extend<mode>si2"
2989107590Sobrien  [(set (match_operand:SI 0 "register_operand" "")
2990169689Skan        (zero_extend:SI (match_operand:HQI 1 "nonimmediate_operand" "")))]
2991107590Sobrien  ""
2992107590Sobrien{
2993169689Skan  if (!TARGET_EXTIMM)
2994169689Skan    {
2995169689Skan      operands[1] = gen_lowpart (SImode, operands[1]);
2996169689Skan      emit_insn (gen_andsi3 (operands[0], operands[1], 
2997169689Skan                   GEN_INT ((1 << GET_MODE_BITSIZE(<MODE>mode)) - 1)));
2998169689Skan      DONE;
2999169689Skan    }
3000169689Skan})
3001107590Sobrien
3002169689Skan; llhr, llcr, llghr, llgcr, llh, llc, llgh, llgc
3003169689Skan(define_insn "*zero_extend<HQI:mode><GPR:mode>2_extimm"
3004169689Skan  [(set (match_operand:GPR 0 "register_operand" "=d,d")
3005169689Skan        (zero_extend:GPR (match_operand:HQI 1 "nonimmediate_operand" "d,m")))]
3006169689Skan  "TARGET_EXTIMM"
3007169689Skan  "@
3008169689Skan   ll<g><hc>r\t%0,%1
3009169689Skan   ll<g><hc>\t%0,%1"
3010169689Skan  [(set_attr "op_type" "RRE,RXY")])
3011169689Skan
3012169689Skan; llgh, llgc
3013169689Skan(define_insn "*zero_extend<HQI:mode><GPR:mode>2"
3014169689Skan  [(set (match_operand:GPR 0 "register_operand" "=d")
3015169689Skan        (zero_extend:GPR (match_operand:HQI 1 "memory_operand" "m")))]
3016169689Skan  "TARGET_ZARCH && !TARGET_EXTIMM"
3017169689Skan  "llg<hc>\t%0,%1"
3018132718Skan  [(set_attr "op_type" "RXY")])
3019117395Skan
3020117395Skan(define_insn_and_split "*zero_extendhisi2_31"
3021117395Skan  [(set (match_operand:SI 0 "register_operand" "=&d")
3022132718Skan        (zero_extend:SI (match_operand:HI 1 "s_operand" "QS")))
3023169689Skan   (clobber (reg:CC CC_REGNUM))]
3024169689Skan  "!TARGET_ZARCH"
3025117395Skan  "#"
3026117395Skan  "&& reload_completed"
3027117395Skan  [(set (match_dup 0) (const_int 0))
3028117395Skan   (parallel
3029117395Skan    [(set (strict_low_part (match_dup 2)) (match_dup 1))
3030169689Skan     (clobber (reg:CC CC_REGNUM))])]
3031169689Skan  "operands[2] = gen_lowpart (HImode, operands[0]);")
3032132718Skan
3033117395Skan(define_insn_and_split "*zero_extendqisi2_31"
3034117395Skan  [(set (match_operand:SI 0 "register_operand" "=&d")
3035117395Skan        (zero_extend:SI (match_operand:QI 1 "memory_operand" "m")))]
3036132718Skan  "!TARGET_ZARCH"
3037117395Skan  "#"
3038117395Skan  "&& reload_completed"
3039117395Skan  [(set (match_dup 0) (const_int 0))
3040117395Skan   (set (strict_low_part (match_dup 2)) (match_dup 1))]
3041169689Skan  "operands[2] = gen_lowpart (QImode, operands[0]);")
3042132718Skan
3043107590Sobrien;
3044107590Sobrien; zero_extendqihi2 instruction pattern(s).
3045107590Sobrien;
3046107590Sobrien
3047107590Sobrien(define_expand "zero_extendqihi2"
3048107590Sobrien  [(set (match_operand:HI 0 "register_operand" "")
3049107590Sobrien        (zero_extend:HI (match_operand:QI 1 "register_operand" "")))]
3050169689Skan  "TARGET_ZARCH && !TARGET_EXTIMM"
3051107590Sobrien{
3052107590Sobrien  operands[1] = gen_lowpart (HImode, operands[1]);
3053107590Sobrien  emit_insn (gen_andhi3 (operands[0], operands[1], GEN_INT (0xff)));
3054107590Sobrien  DONE;
3055169689Skan})
3056107590Sobrien
3057107590Sobrien(define_insn "*zero_extendqihi2_64"
3058107590Sobrien  [(set (match_operand:HI 0 "register_operand" "=d")
3059117395Skan        (zero_extend:HI (match_operand:QI 1 "memory_operand" "m")))]
3060169689Skan  "TARGET_ZARCH && !TARGET_EXTIMM"
3061132718Skan  "llgc\t%0,%1"
3062132718Skan  [(set_attr "op_type" "RXY")])
3063107590Sobrien
3064117395Skan(define_insn_and_split "*zero_extendqihi2_31"
3065117395Skan  [(set (match_operand:HI 0 "register_operand" "=&d")
3066117395Skan        (zero_extend:HI (match_operand:QI 1 "memory_operand" "m")))]
3067132718Skan  "!TARGET_ZARCH"
3068117395Skan  "#"
3069117395Skan  "&& reload_completed"
3070117395Skan  [(set (match_dup 0) (const_int 0))
3071117395Skan   (set (strict_low_part (match_dup 2)) (match_dup 1))]
3072169689Skan  "operands[2] = gen_lowpart (QImode, operands[0]);")
3073117395Skan
3074117395Skan
3075107590Sobrien;
3076169689Skan; fixuns_trunc(sf|df)(si|di)2 and fix_trunc(sf|df)(si|di)2 instruction pattern(s).
3077107590Sobrien;
3078107590Sobrien
3079169689Skan(define_expand "fixuns_trunc<FPR:mode><GPR:mode>2"
3080169689Skan  [(set (match_operand:GPR 0 "register_operand" "")
3081169689Skan        (unsigned_fix:GPR (match_operand:FPR 1 "register_operand" "")))]
3082169689Skan  "TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT"
3083107590Sobrien{
3084107590Sobrien  rtx label1 = gen_label_rtx ();
3085107590Sobrien  rtx label2 = gen_label_rtx ();
3086169689Skan  rtx temp = gen_reg_rtx (<FPR:MODE>mode);
3087169689Skan  REAL_VALUE_TYPE cmp, sub;
3088169689Skan  
3089169689Skan  operands[1] = force_reg (<FPR:MODE>mode, operands[1]);
3090169689Skan  real_2expN (&cmp, GET_MODE_BITSIZE(<GPR:MODE>mode) - 1);
3091169689Skan  real_2expN (&sub, GET_MODE_BITSIZE(<GPR:MODE>mode));
3092169689Skan  
3093169689Skan  emit_insn (gen_cmp<FPR:mode> (operands[1],
3094169689Skan	CONST_DOUBLE_FROM_REAL_VALUE (cmp, <FPR:MODE>mode)));
3095107590Sobrien  emit_jump_insn (gen_blt (label1));
3096169689Skan  emit_insn (gen_sub<FPR:mode>3 (temp, operands[1],
3097169689Skan	CONST_DOUBLE_FROM_REAL_VALUE (sub, <FPR:MODE>mode)));
3098169689Skan  emit_insn (gen_fix_trunc<FPR:mode><GPR:mode>2_ieee (operands[0], temp,
3099169689Skan	GEN_INT(7)));
3100107590Sobrien  emit_jump (label2);
3101107590Sobrien
3102107590Sobrien  emit_label (label1);
3103169689Skan  emit_insn (gen_fix_trunc<FPR:mode><GPR:mode>2_ieee (operands[0],
3104169689Skan	operands[1], GEN_INT(5)));
3105107590Sobrien  emit_label (label2);
3106107590Sobrien  DONE;
3107132718Skan})
3108107590Sobrien
3109169689Skan(define_expand "fix_trunc<mode>di2"
3110107590Sobrien  [(set (match_operand:DI 0 "register_operand" "")
3111169689Skan        (fix:DI (match_operand:DSF 1 "nonimmediate_operand" "")))]
3112107590Sobrien  "TARGET_64BIT && TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT"
3113107590Sobrien{
3114169689Skan  operands[1] = force_reg (<MODE>mode, operands[1]);
3115169689Skan  emit_insn (gen_fix_trunc<mode>di2_ieee (operands[0], operands[1],
3116169689Skan      GEN_INT(5)));
3117107590Sobrien  DONE;
3118132718Skan})
3119107590Sobrien
3120169689Skan; cgxbr, cgdbr, cgebr, cfxbr, cfdbr, cfebr
3121169689Skan(define_insn "fix_trunc<FPR:mode><GPR:mode>2_ieee"
3122169689Skan  [(set (match_operand:GPR 0 "register_operand" "=d")
3123169689Skan        (fix:GPR (match_operand:FPR 1 "register_operand" "f")))
3124169689Skan   (unspec:GPR [(match_operand:GPR 2 "immediate_operand" "K")] UNSPEC_ROUND)
3125169689Skan   (clobber (reg:CC CC_REGNUM))]
3126169689Skan  "TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT"
3127169689Skan  "c<GPR:gf><FPR:xde>br\t%0,%h2,%1"
3128107590Sobrien  [(set_attr "op_type" "RRE")
3129132718Skan   (set_attr "type"    "ftoi")])
3130107590Sobrien
3131107590Sobrien;
3132169689Skan; fix_trunctf(si|di)2 instruction pattern(s).
3133107590Sobrien;
3134107590Sobrien
3135169689Skan(define_expand "fix_trunctf<mode>2"
3136169689Skan  [(parallel [(set (match_operand:GPR 0 "register_operand" "")
3137169689Skan		   (fix:GPR (match_operand:TF 1 "register_operand" "")))
3138169689Skan	      (unspec:GPR [(const_int 5)] UNSPEC_ROUND)
3139169689Skan	      (clobber (reg:CC CC_REGNUM))])]
3140107590Sobrien  "TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT"
3141169689Skan  "")
3142107590Sobrien
3143169689Skan;
3144169689Skan; fix_truncdfsi2 instruction pattern(s).
3145169689Skan;
3146107590Sobrien
3147107590Sobrien(define_expand "fix_truncdfsi2"
3148107590Sobrien  [(set (match_operand:SI 0 "register_operand" "")
3149107590Sobrien        (fix:SI (match_operand:DF 1 "nonimmediate_operand" "")))]
3150107590Sobrien  "TARGET_HARD_FLOAT"
3151107590Sobrien{
3152132718Skan  if (TARGET_IBM_FLOAT)
3153107590Sobrien    {
3154107590Sobrien      /* This is the algorithm from POP chapter A.5.7.2.  */
3155107590Sobrien
3156132718Skan      rtx temp   = assign_stack_local (BLKmode, 8, BITS_PER_WORD);
3157107590Sobrien      rtx two31r = s390_gen_rtx_const_DI (0x4f000000, 0x08000000);
3158107590Sobrien      rtx two32  = s390_gen_rtx_const_DI (0x4e000001, 0x00000000);
3159107590Sobrien
3160107590Sobrien      operands[1] = force_reg (DFmode, operands[1]);
3161132718Skan      emit_insn (gen_fix_truncdfsi2_ibm (operands[0], operands[1],
3162107590Sobrien					 two31r, two32, temp));
3163132718Skan    }
3164132718Skan  else
3165107590Sobrien    {
3166107590Sobrien      operands[1] = force_reg (DFmode, operands[1]);
3167107590Sobrien      emit_insn (gen_fix_truncdfsi2_ieee (operands[0], operands[1], GEN_INT (5)));
3168107590Sobrien    }
3169107590Sobrien
3170107590Sobrien  DONE;
3171132718Skan})
3172107590Sobrien
3173107590Sobrien(define_insn "fix_truncdfsi2_ibm"
3174107590Sobrien  [(set (match_operand:SI 0 "register_operand" "=d")
3175107590Sobrien        (fix:SI (match_operand:DF 1 "nonimmediate_operand" "+f")))
3176107590Sobrien   (use (match_operand:DI 2 "immediate_operand" "m"))
3177107590Sobrien   (use (match_operand:DI 3 "immediate_operand" "m"))
3178107590Sobrien   (use (match_operand:BLK 4 "memory_operand" "m"))
3179169689Skan   (clobber (reg:CC CC_REGNUM))]
3180107590Sobrien  "TARGET_HARD_FLOAT && TARGET_IBM_FLOAT"
3181107590Sobrien{
3182132718Skan   output_asm_insn ("sd\t%1,%2", operands);
3183132718Skan   output_asm_insn ("aw\t%1,%3", operands);
3184132718Skan   output_asm_insn ("std\t%1,%4", operands);
3185132718Skan   output_asm_insn ("xi\t%N4,128", operands);
3186132718Skan   return "l\t%0,%N4";
3187132718Skan}
3188169689Skan  [(set_attr "length" "20")])
3189107590Sobrien
3190107590Sobrien;
3191169689Skan; fix_truncsfsi2 instruction pattern(s).
3192107590Sobrien;
3193107590Sobrien
3194107590Sobrien(define_expand "fix_truncsfsi2"
3195107590Sobrien  [(set (match_operand:SI 0 "register_operand" "")
3196107590Sobrien        (fix:SI (match_operand:SF 1 "nonimmediate_operand" "")))]
3197107590Sobrien  "TARGET_HARD_FLOAT"
3198107590Sobrien{
3199107590Sobrien  if (TARGET_IBM_FLOAT)
3200107590Sobrien    {
3201107590Sobrien      /* Convert to DFmode and then use the POP algorithm.  */
3202107590Sobrien      rtx temp = gen_reg_rtx (DFmode);
3203107590Sobrien      emit_insn (gen_extendsfdf2 (temp, operands[1]));
3204107590Sobrien      emit_insn (gen_fix_truncdfsi2 (operands[0], temp));
3205107590Sobrien    }
3206107590Sobrien  else
3207107590Sobrien    {
3208107590Sobrien      operands[1] = force_reg (SFmode, operands[1]);
3209107590Sobrien      emit_insn (gen_fix_truncsfsi2_ieee (operands[0], operands[1], GEN_INT (5)));
3210107590Sobrien    }
3211107590Sobrien
3212107590Sobrien  DONE;
3213132718Skan})
3214107590Sobrien
3215107590Sobrien;
3216169689Skan; float(si|di)(tf|df|sf)2 instruction pattern(s).
3217107590Sobrien;
3218107590Sobrien
3219169689Skan; cxgbr, cdgbr, cegbr
3220169689Skan(define_insn "floatdi<mode>2"
3221169689Skan  [(set (match_operand:FPR 0 "register_operand" "=f")
3222169689Skan        (float:FPR (match_operand:DI 1 "register_operand" "d")))]
3223107590Sobrien  "TARGET_64BIT && TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT"
3224169689Skan  "c<xde>gbr\t%0,%1"
3225107590Sobrien  [(set_attr "op_type" "RRE")
3226132718Skan   (set_attr "type"    "itof" )])
3227107590Sobrien
3228169689Skan; cxfbr, cdfbr, cefbr
3229169689Skan(define_insn "floatsi<mode>2_ieee"
3230169689Skan  [(set (match_operand:FPR 0 "register_operand" "=f")
3231169689Skan        (float:FPR (match_operand:SI 1 "register_operand" "d")))]
3232169689Skan  "TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT"
3233169689Skan  "c<xde>fbr\t%0,%1"
3234107590Sobrien  [(set_attr "op_type" "RRE")
3235169689Skan   (set_attr "type"   "itof" )])
3236107590Sobrien
3237169689Skan
3238107590Sobrien;
3239169689Skan; floatsi(tf|df)2 instruction pattern(s).
3240107590Sobrien;
3241107590Sobrien
3242169689Skan(define_expand "floatsitf2"
3243169689Skan  [(set (match_operand:TF 0 "register_operand" "")
3244169689Skan        (float:TF (match_operand:SI 1 "register_operand" "")))]
3245169689Skan  "TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT"
3246169689Skan  "")
3247169689Skan
3248107590Sobrien(define_expand "floatsidf2"
3249169689Skan  [(set (match_operand:DF 0 "register_operand" "")
3250169689Skan        (float:DF (match_operand:SI 1 "register_operand" "")))]
3251107590Sobrien  "TARGET_HARD_FLOAT"
3252107590Sobrien{
3253132718Skan  if (TARGET_IBM_FLOAT)
3254107590Sobrien    {
3255107590Sobrien      /* This is the algorithm from POP chapter A.5.7.1.  */
3256107590Sobrien
3257132718Skan      rtx temp  = assign_stack_local (BLKmode, 8, BITS_PER_WORD);
3258132718Skan      rtx two31 = s390_gen_rtx_const_DI (0x4e000000, 0x80000000);
3259107590Sobrien
3260107590Sobrien      emit_insn (gen_floatsidf2_ibm (operands[0], operands[1], two31, temp));
3261107590Sobrien      DONE;
3262107590Sobrien    }
3263132718Skan})
3264107590Sobrien
3265107590Sobrien(define_insn "floatsidf2_ibm"
3266107590Sobrien  [(set (match_operand:DF 0 "register_operand" "=f")
3267107590Sobrien        (float:DF (match_operand:SI 1 "register_operand" "d")))
3268107590Sobrien   (use (match_operand:DI 2 "immediate_operand" "m"))
3269107590Sobrien   (use (match_operand:BLK 3 "memory_operand" "m"))
3270169689Skan   (clobber (reg:CC CC_REGNUM))]
3271107590Sobrien  "TARGET_HARD_FLOAT && TARGET_IBM_FLOAT"
3272107590Sobrien{
3273132718Skan   output_asm_insn ("st\t%1,%N3", operands);
3274132718Skan   output_asm_insn ("xi\t%N3,128", operands);
3275132718Skan   output_asm_insn ("mvc\t%O3(4,%R3),%2", operands);
3276132718Skan   output_asm_insn ("ld\t%0,%3", operands);
3277132718Skan   return "sd\t%0,%2";
3278132718Skan}
3279169689Skan  [(set_attr "length" "20")])
3280107590Sobrien
3281107590Sobrien;
3282107590Sobrien; floatsisf2 instruction pattern(s).
3283107590Sobrien;
3284107590Sobrien
3285107590Sobrien(define_expand "floatsisf2"
3286169689Skan  [(set (match_operand:SF 0 "register_operand" "")
3287169689Skan        (float:SF (match_operand:SI 1 "register_operand" "")))]
3288107590Sobrien  "TARGET_HARD_FLOAT"
3289107590Sobrien{
3290107590Sobrien  if (TARGET_IBM_FLOAT)
3291107590Sobrien    {
3292107590Sobrien      /* Use the POP algorithm to convert to DFmode and then truncate.  */
3293107590Sobrien      rtx temp = gen_reg_rtx (DFmode);
3294107590Sobrien      emit_insn (gen_floatsidf2 (temp, operands[1]));
3295107590Sobrien      emit_insn (gen_truncdfsf2 (operands[0], temp));
3296107590Sobrien      DONE;
3297107590Sobrien    }
3298132718Skan})
3299107590Sobrien
3300107590Sobrien;
3301107590Sobrien; truncdfsf2 instruction pattern(s).
3302107590Sobrien;
3303107590Sobrien
3304107590Sobrien(define_expand "truncdfsf2"
3305107590Sobrien  [(set (match_operand:SF 0 "register_operand" "")
3306169689Skan        (float_truncate:SF (match_operand:DF 1 "register_operand" "")))]
3307107590Sobrien  "TARGET_HARD_FLOAT"
3308107590Sobrien  "")
3309107590Sobrien
3310107590Sobrien(define_insn "truncdfsf2_ieee"
3311107590Sobrien  [(set (match_operand:SF 0 "register_operand" "=f")
3312169689Skan        (float_truncate:SF (match_operand:DF 1 "register_operand" "f")))]
3313107590Sobrien  "TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT"
3314132718Skan  "ledbr\t%0,%1"
3315169689Skan  [(set_attr "op_type"  "RRE")
3316169689Skan   (set_attr "type"   "ftruncdf")])
3317107590Sobrien
3318107590Sobrien(define_insn "truncdfsf2_ibm"
3319107590Sobrien  [(set (match_operand:SF 0 "register_operand" "=f,f")
3320169689Skan        (float_truncate:SF (match_operand:DF 1 "nonimmediate_operand" "f,R")))]
3321107590Sobrien  "TARGET_HARD_FLOAT && TARGET_IBM_FLOAT"
3322107590Sobrien  "@
3323169689Skan   ler\t%0,%1
3324132718Skan   le\t%0,%1"
3325107590Sobrien  [(set_attr "op_type"  "RR,RX")
3326169689Skan   (set_attr "type"   "floadsf")])
3327107590Sobrien
3328107590Sobrien;
3329169689Skan; trunctfdf2 instruction pattern(s).
3330169689Skan;
3331169689Skan
3332169689Skan(define_expand "trunctfdf2"
3333169689Skan  [(parallel 
3334169689Skan    [(set (match_operand:DF 0 "register_operand" "")
3335169689Skan	  (float_truncate:DF (match_operand:TF 1 "register_operand" "")))
3336169689Skan     (clobber (match_scratch:TF 2 "=f"))])]
3337169689Skan  "TARGET_HARD_FLOAT"
3338169689Skan  "")
3339169689Skan
3340169689Skan(define_insn "*trunctfdf2_ieee"
3341169689Skan  [(set (match_operand:DF 0 "register_operand" "=f")
3342169689Skan        (float_truncate:DF (match_operand:TF 1 "register_operand" "f")))
3343169689Skan   (clobber (match_scratch:TF 2 "=f"))]
3344169689Skan  "TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT"
3345169689Skan  "ldxbr\t%2,%1\;ldr\t%0,%2"
3346169689Skan  [(set_attr "length" "6")
3347169689Skan   (set_attr "type"   "ftrunctf")])   
3348169689Skan
3349169689Skan(define_insn "*trunctfdf2_ibm"
3350169689Skan  [(set (match_operand:DF 0 "register_operand" "=f")
3351169689Skan        (float_truncate:DF (match_operand:TF 1 "register_operand" "f")))
3352169689Skan   (clobber (match_scratch:TF 2 "=f"))]
3353169689Skan  "TARGET_HARD_FLOAT && TARGET_IBM_FLOAT"
3354169689Skan  "ldxr\t%2,%1\;ldr\t%0,%2"
3355169689Skan  [(set_attr "length"  "4")
3356169689Skan   (set_attr "type"   "ftrunctf")])
3357169689Skan
3358169689Skan;
3359169689Skan; trunctfsf2 instruction pattern(s).
3360169689Skan;
3361169689Skan
3362169689Skan(define_expand "trunctfsf2"
3363169689Skan  [(parallel 
3364169689Skan    [(set (match_operand:SF 0 "register_operand" "=f")
3365169689Skan	  (float_truncate:SF (match_operand:TF 1 "register_operand" "f")))
3366169689Skan     (clobber (match_scratch:TF 2 "=f"))])]
3367169689Skan  "TARGET_HARD_FLOAT"
3368169689Skan  "")
3369169689Skan
3370169689Skan(define_insn "*trunctfsf2_ieee"
3371169689Skan  [(set (match_operand:SF 0 "register_operand" "=f")
3372169689Skan        (float_truncate:SF (match_operand:TF 1 "register_operand" "f")))
3373169689Skan   (clobber (match_scratch:TF 2 "=f"))]
3374169689Skan  "TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT"
3375169689Skan  "lexbr\t%2,%1\;ler\t%0,%2"
3376169689Skan  [(set_attr "length"  "6")
3377169689Skan   (set_attr "type"   "ftrunctf")])
3378169689Skan
3379169689Skan(define_insn "*trunctfsf2_ibm"
3380169689Skan  [(set (match_operand:SF 0 "register_operand" "=f")
3381169689Skan        (float_truncate:SF (match_operand:TF 1 "register_operand" "f")))
3382169689Skan   (clobber (match_scratch:TF 2 "=f"))]
3383169689Skan  "TARGET_HARD_FLOAT && TARGET_IBM_FLOAT"
3384169689Skan  "lexr\t%2,%1\;ler\t%0,%2"
3385169689Skan  [(set_attr "length"  "6")
3386169689Skan   (set_attr "type"   "ftrunctf")])
3387169689Skan
3388169689Skan;
3389107590Sobrien; extendsfdf2 instruction pattern(s).
3390107590Sobrien;
3391107590Sobrien
3392107590Sobrien(define_expand "extendsfdf2"
3393107590Sobrien  [(set (match_operand:DF 0 "register_operand" "")
3394107590Sobrien        (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "")))]
3395107590Sobrien  "TARGET_HARD_FLOAT"
3396107590Sobrien{
3397107590Sobrien  if (TARGET_IBM_FLOAT)
3398107590Sobrien    {
3399107590Sobrien      emit_insn (gen_extendsfdf2_ibm (operands[0], operands[1]));
3400107590Sobrien      DONE;
3401107590Sobrien    }
3402132718Skan})
3403107590Sobrien
3404107590Sobrien(define_insn "extendsfdf2_ieee"
3405107590Sobrien  [(set (match_operand:DF 0 "register_operand" "=f,f")
3406132718Skan        (float_extend:DF (match_operand:SF 1 "nonimmediate_operand"  "f,R")))]
3407107590Sobrien  "TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT"
3408107590Sobrien  "@
3409132718Skan   ldebr\t%0,%1
3410132718Skan   ldeb\t%0,%1"
3411132718Skan  [(set_attr "op_type"  "RRE,RXE")
3412169689Skan   (set_attr "type"   "fsimpsf, floadsf")])
3413107590Sobrien
3414107590Sobrien(define_insn "extendsfdf2_ibm"
3415107590Sobrien  [(set (match_operand:DF 0 "register_operand" "=f,f")
3416132718Skan        (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "f,R")))
3417169689Skan   (clobber (reg:CC CC_REGNUM))]
3418107590Sobrien  "TARGET_HARD_FLOAT && TARGET_IBM_FLOAT"
3419107590Sobrien  "@
3420132718Skan   sdr\t%0,%0\;ler\t%0,%1
3421132718Skan   sdr\t%0,%0\;le\t%0,%1"
3422169689Skan  [(set_attr "length"   "4,6")
3423169689Skan   (set_attr "type"     "floadsf")])
3424107590Sobrien
3425169689Skan;
3426169689Skan; extenddftf2 instruction pattern(s).
3427169689Skan;
3428107590Sobrien
3429169689Skan(define_expand "extenddftf2"
3430169689Skan  [(set (match_operand:TF 0 "register_operand" "")
3431169689Skan        (float_extend:TF (match_operand:DF 1 "nonimmediate_operand" "")))]
3432169689Skan  "TARGET_HARD_FLOAT"
3433169689Skan  "")
3434169689Skan
3435169689Skan(define_insn "*extenddftf2_ieee"
3436169689Skan  [(set (match_operand:TF 0 "register_operand" "=f,f")
3437169689Skan        (float_extend:TF (match_operand:DF 1 "nonimmediate_operand" "f,R")))]
3438169689Skan  "TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT"
3439169689Skan  "@
3440169689Skan   lxdbr\t%0,%1
3441169689Skan   lxdb\t%0,%1"
3442169689Skan  [(set_attr "op_type"  "RRE,RXE")
3443169689Skan   (set_attr "type"   "fsimptf, floadtf")])
3444169689Skan
3445169689Skan(define_insn "*extenddftf2_ibm"
3446169689Skan  [(set (match_operand:TF 0 "register_operand" "=f,f")
3447169689Skan        (float_extend:TF (match_operand:DF 1 "nonimmediate_operand" "f,R")))]
3448169689Skan  "TARGET_HARD_FLOAT && TARGET_IBM_FLOAT"
3449169689Skan  "@
3450169689Skan   lxdr\t%0,%1
3451169689Skan   lxd\t%0,%1"
3452169689Skan  [(set_attr "op_type"  "RRE,RXE")
3453169689Skan   (set_attr "type"   "fsimptf, floadtf")])
3454169689Skan
3455169689Skan;
3456169689Skan; extendsftf2 instruction pattern(s).
3457169689Skan;
3458169689Skan
3459169689Skan(define_expand "extendsftf2"
3460169689Skan  [(set (match_operand:TF 0 "register_operand" "")
3461169689Skan        (float_extend:TF (match_operand:SF 1 "nonimmediate_operand" "")))]
3462169689Skan  "TARGET_HARD_FLOAT"
3463169689Skan  "")
3464169689Skan
3465169689Skan(define_insn "*extendsftf2_ieee"
3466169689Skan  [(set (match_operand:TF 0 "register_operand" "=f,f")
3467169689Skan        (float_extend:TF (match_operand:SF 1 "nonimmediate_operand" "f,R")))]
3468169689Skan  "TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT"
3469169689Skan  "@
3470169689Skan   lxebr\t%0,%1
3471169689Skan   lxeb\t%0,%1"
3472169689Skan  [(set_attr "op_type"  "RRE,RXE")
3473169689Skan   (set_attr "type"   "fsimptf, floadtf")])
3474169689Skan
3475169689Skan(define_insn "*extendsftf2_ibm"
3476169689Skan  [(set (match_operand:TF 0 "register_operand" "=f,f")
3477169689Skan        (float_extend:TF (match_operand:SF 1 "nonimmediate_operand" "f,R")))]
3478169689Skan  "TARGET_HARD_FLOAT && TARGET_IBM_FLOAT"
3479169689Skan  "@
3480169689Skan   lxer\t%0,%1
3481169689Skan   lxe\t%0,%1"
3482169689Skan  [(set_attr "op_type"  "RRE,RXE")
3483169689Skan   (set_attr "type"   "fsimptf, floadtf")])
3484169689Skan
3485169689Skan
3486107590Sobrien;;
3487132718Skan;; ARITHMETIC OPERATIONS
3488107590Sobrien;;
3489132718Skan;  arithmetic operations set the ConditionCode,
3490107590Sobrien;  because of unpredictable Bits in Register for Halfword and Byte
3491107590Sobrien;  the ConditionCode can be set wrong in operations for Halfword and Byte
3492107590Sobrien
3493107590Sobrien;;
3494107590Sobrien;;- Add instructions.
3495107590Sobrien;;
3496107590Sobrien
3497107590Sobrien;
3498169689Skan; addti3 instruction pattern(s).
3499169689Skan;
3500169689Skan
3501169689Skan(define_insn_and_split "addti3"
3502169689Skan  [(set (match_operand:TI 0 "register_operand" "=&d")
3503169689Skan        (plus:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
3504169689Skan                 (match_operand:TI 2 "general_operand" "do") ) )
3505169689Skan   (clobber (reg:CC CC_REGNUM))]
3506169689Skan  "TARGET_64BIT"
3507169689Skan  "#"
3508169689Skan  "&& reload_completed"
3509169689Skan  [(parallel
3510169689Skan    [(set (reg:CCL1 CC_REGNUM)
3511169689Skan          (compare:CCL1 (plus:DI (match_dup 7) (match_dup 8))
3512169689Skan                        (match_dup 7)))
3513169689Skan     (set (match_dup 6) (plus:DI (match_dup 7) (match_dup 8)))])
3514169689Skan   (parallel
3515169689Skan    [(set (match_dup 3) (plus:DI (plus:DI (match_dup 4) (match_dup 5))
3516169689Skan                                 (ltu:DI (reg:CCL1 CC_REGNUM) (const_int 0))))
3517169689Skan     (clobber (reg:CC CC_REGNUM))])]
3518169689Skan  "operands[3] = operand_subword (operands[0], 0, 0, TImode);
3519169689Skan   operands[4] = operand_subword (operands[1], 0, 0, TImode);
3520169689Skan   operands[5] = operand_subword (operands[2], 0, 0, TImode);
3521169689Skan   operands[6] = operand_subword (operands[0], 1, 0, TImode);
3522169689Skan   operands[7] = operand_subword (operands[1], 1, 0, TImode);
3523169689Skan   operands[8] = operand_subword (operands[2], 1, 0, TImode);")
3524169689Skan
3525169689Skan;
3526107590Sobrien; adddi3 instruction pattern(s).
3527107590Sobrien;
3528107590Sobrien
3529169689Skan(define_expand "adddi3"
3530169689Skan  [(parallel
3531169689Skan    [(set (match_operand:DI 0 "register_operand" "")
3532169689Skan          (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
3533169689Skan                   (match_operand:DI 2 "general_operand" "")))
3534169689Skan     (clobber (reg:CC CC_REGNUM))])]
3535169689Skan  ""
3536169689Skan  "")
3537169689Skan
3538117395Skan(define_insn "*adddi3_sign"
3539117395Skan  [(set (match_operand:DI 0 "register_operand" "=d,d")
3540117395Skan        (plus:DI (sign_extend:DI (match_operand:SI 2 "general_operand" "d,m"))
3541117395Skan                 (match_operand:DI 1 "register_operand" "0,0")))
3542169689Skan   (clobber (reg:CC CC_REGNUM))]
3543117395Skan  "TARGET_64BIT"
3544107590Sobrien  "@
3545132718Skan   agfr\t%0,%2
3546132718Skan   agf\t%0,%2"
3547132718Skan  [(set_attr "op_type"  "RRE,RXY")])
3548107590Sobrien
3549117395Skan(define_insn "*adddi3_zero_cc"
3550169689Skan  [(set (reg CC_REGNUM)
3551117395Skan        (compare (plus:DI (zero_extend:DI (match_operand:SI 2 "general_operand" "d,m"))
3552117395Skan                          (match_operand:DI 1 "register_operand" "0,0"))
3553117395Skan                 (const_int 0)))
3554117395Skan   (set (match_operand:DI 0 "register_operand" "=d,d")
3555117395Skan        (plus:DI (zero_extend:DI (match_dup 2)) (match_dup 1)))]
3556117395Skan  "s390_match_ccmode (insn, CCLmode) && TARGET_64BIT"
3557117395Skan  "@
3558132718Skan   algfr\t%0,%2
3559132718Skan   algf\t%0,%2"
3560132718Skan  [(set_attr "op_type"  "RRE,RXY")])
3561117395Skan
3562117395Skan(define_insn "*adddi3_zero_cconly"
3563169689Skan  [(set (reg CC_REGNUM)
3564117395Skan        (compare (plus:DI (zero_extend:DI (match_operand:SI 2 "general_operand" "d,m"))
3565117395Skan                          (match_operand:DI 1 "register_operand" "0,0"))
3566117395Skan                 (const_int 0)))
3567117395Skan   (clobber (match_scratch:DI 0 "=d,d"))]
3568117395Skan  "s390_match_ccmode (insn, CCLmode) && TARGET_64BIT"
3569117395Skan  "@
3570132718Skan   algfr\t%0,%2
3571132718Skan   algf\t%0,%2"
3572132718Skan  [(set_attr "op_type"  "RRE,RXY")])
3573117395Skan
3574117395Skan(define_insn "*adddi3_zero"
3575117395Skan  [(set (match_operand:DI 0 "register_operand" "=d,d")
3576117395Skan        (plus:DI (zero_extend:DI (match_operand:SI 2 "general_operand" "d,m"))
3577117395Skan                 (match_operand:DI 1 "register_operand" "0,0")))
3578169689Skan   (clobber (reg:CC CC_REGNUM))]
3579117395Skan  "TARGET_64BIT"
3580117395Skan  "@
3581132718Skan   algfr\t%0,%2
3582132718Skan   algf\t%0,%2"
3583132718Skan  [(set_attr "op_type"  "RRE,RXY")])
3584117395Skan
3585132718Skan(define_insn_and_split "*adddi3_31z"
3586132718Skan  [(set (match_operand:DI 0 "register_operand" "=&d")
3587132718Skan        (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
3588132718Skan                 (match_operand:DI 2 "general_operand" "do") ) )
3589169689Skan   (clobber (reg:CC CC_REGNUM))]
3590132718Skan  "!TARGET_64BIT && TARGET_CPU_ZARCH"
3591132718Skan  "#"
3592132718Skan  "&& reload_completed"
3593132718Skan  [(parallel
3594169689Skan    [(set (reg:CCL1 CC_REGNUM)
3595132718Skan          (compare:CCL1 (plus:SI (match_dup 7) (match_dup 8))
3596132718Skan                        (match_dup 7)))
3597132718Skan     (set (match_dup 6) (plus:SI (match_dup 7) (match_dup 8)))])
3598132718Skan   (parallel
3599132718Skan    [(set (match_dup 3) (plus:SI (plus:SI (match_dup 4) (match_dup 5))
3600169689Skan                                 (ltu:SI (reg:CCL1 CC_REGNUM) (const_int 0))))
3601169689Skan     (clobber (reg:CC CC_REGNUM))])]
3602132718Skan  "operands[3] = operand_subword (operands[0], 0, 0, DImode);
3603132718Skan   operands[4] = operand_subword (operands[1], 0, 0, DImode);
3604132718Skan   operands[5] = operand_subword (operands[2], 0, 0, DImode);
3605132718Skan   operands[6] = operand_subword (operands[0], 1, 0, DImode);
3606132718Skan   operands[7] = operand_subword (operands[1], 1, 0, DImode);
3607169689Skan   operands[8] = operand_subword (operands[2], 1, 0, DImode);")
3608132718Skan
3609117395Skan(define_insn_and_split "*adddi3_31"
3610117395Skan  [(set (match_operand:DI 0 "register_operand" "=&d")
3611117395Skan        (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
3612117395Skan                 (match_operand:DI 2 "general_operand" "do") ) )
3613169689Skan   (clobber (reg:CC CC_REGNUM))]
3614132718Skan  "!TARGET_CPU_ZARCH"
3615117395Skan  "#"
3616117395Skan  "&& reload_completed"
3617117395Skan  [(parallel
3618117395Skan    [(set (match_dup 3) (plus:SI (match_dup 4) (match_dup 5)))
3619169689Skan     (clobber (reg:CC CC_REGNUM))])
3620117395Skan   (parallel
3621169689Skan    [(set (reg:CCL1 CC_REGNUM)
3622117395Skan          (compare:CCL1 (plus:SI (match_dup 7) (match_dup 8))
3623117395Skan                        (match_dup 7)))
3624117395Skan     (set (match_dup 6) (plus:SI (match_dup 7) (match_dup 8)))])
3625117395Skan   (set (pc)
3626169689Skan        (if_then_else (ltu (reg:CCL1 CC_REGNUM) (const_int 0))
3627117395Skan                      (pc)
3628117395Skan                      (label_ref (match_dup 9))))
3629117395Skan   (parallel
3630117395Skan    [(set (match_dup 3) (plus:SI (match_dup 3) (const_int 1)))
3631169689Skan     (clobber (reg:CC CC_REGNUM))])
3632117395Skan   (match_dup 9)]
3633117395Skan  "operands[3] = operand_subword (operands[0], 0, 0, DImode);
3634117395Skan   operands[4] = operand_subword (operands[1], 0, 0, DImode);
3635117395Skan   operands[5] = operand_subword (operands[2], 0, 0, DImode);
3636117395Skan   operands[6] = operand_subword (operands[0], 1, 0, DImode);
3637117395Skan   operands[7] = operand_subword (operands[1], 1, 0, DImode);
3638117395Skan   operands[8] = operand_subword (operands[2], 1, 0, DImode);
3639169689Skan   operands[9] = gen_label_rtx ();")
3640107590Sobrien
3641169689Skan;
3642169689Skan; addsi3 instruction pattern(s).
3643169689Skan;
3644169689Skan
3645169689Skan(define_expand "addsi3"
3646117395Skan  [(parallel
3647169689Skan    [(set (match_operand:SI 0 "register_operand" "")
3648169689Skan          (plus:SI (match_operand:SI 1 "nonimmediate_operand" "")
3649169689Skan                   (match_operand:SI 2 "general_operand" "")))
3650169689Skan     (clobber (reg:CC CC_REGNUM))])]
3651107590Sobrien  ""
3652117395Skan  "")
3653107590Sobrien
3654169689Skan(define_insn "*addsi3_sign"
3655169689Skan  [(set (match_operand:SI 0 "register_operand" "=d,d")
3656169689Skan        (plus:SI (sign_extend:SI (match_operand:HI 2 "memory_operand" "R,T"))
3657169689Skan                 (match_operand:SI 1 "register_operand" "0,0")))
3658169689Skan   (clobber (reg:CC CC_REGNUM))]
3659169689Skan  ""
3660169689Skan  "@
3661169689Skan   ah\t%0,%2
3662169689Skan   ahy\t%0,%2"
3663169689Skan  [(set_attr "op_type"  "RX,RXY")])
3664169689Skan
3665107590Sobrien;
3666169689Skan; add(di|si)3 instruction pattern(s).
3667107590Sobrien;
3668107590Sobrien
3669169689Skan; ar, ahi, alfi, slfi, a, ay, agr, aghi, algfi, slgfi, ag
3670169689Skan(define_insn "*add<mode>3"
3671169689Skan  [(set (match_operand:GPR 0 "register_operand" "=d,d,d,d,d,d")
3672169689Skan        (plus:GPR (match_operand:GPR 1 "nonimmediate_operand" "%0,0,0,0,0,0")
3673169689Skan		  (match_operand:GPR 2 "general_operand" "d,K,Op,On,R,T") ) )
3674169689Skan   (clobber (reg:CC CC_REGNUM))]
3675169689Skan  ""
3676169689Skan  "@
3677169689Skan   a<g>r\t%0,%2
3678169689Skan   a<g>hi\t%0,%h2
3679169689Skan   al<g>fi\t%0,%2
3680169689Skan   sl<g>fi\t%0,%n2
3681169689Skan   a<g>\t%0,%2
3682169689Skan   a<y>\t%0,%2"
3683169689Skan  [(set_attr "op_type"  "RR<E>,RI,RIL,RIL,RX<Y>,RXY")])
3684107590Sobrien
3685169689Skan; alr, alfi, slfi, al, aly, algr, algfi, slgfi, alg
3686169689Skan(define_insn "*add<mode>3_carry1_cc"
3687169689Skan  [(set (reg CC_REGNUM)
3688169689Skan        (compare (plus:GPR (match_operand:GPR 1 "nonimmediate_operand" "%0,0,0,0,0")
3689169689Skan			   (match_operand:GPR 2 "general_operand" "d,Op,On,R,T"))
3690117395Skan                 (match_dup 1)))
3691169689Skan   (set (match_operand:GPR 0 "register_operand" "=d,d,d,d,d")
3692169689Skan        (plus:GPR (match_dup 1) (match_dup 2)))]
3693132718Skan  "s390_match_ccmode (insn, CCL1mode)"
3694117395Skan  "@
3695169689Skan   al<g>r\t%0,%2
3696169689Skan   al<g>fi\t%0,%2
3697169689Skan   sl<g>fi\t%0,%n2
3698169689Skan   al<g>\t%0,%2
3699169689Skan   al<y>\t%0,%2"
3700169689Skan  [(set_attr "op_type"  "RR<E>,RIL,RIL,RX<Y>,RXY")])
3701117395Skan
3702169689Skan; alr, al, aly, algr, alg
3703169689Skan(define_insn "*add<mode>3_carry1_cconly"
3704169689Skan  [(set (reg CC_REGNUM)
3705169689Skan        (compare (plus:GPR (match_operand:GPR 1 "nonimmediate_operand" "%0,0,0")
3706169689Skan			   (match_operand:GPR 2 "general_operand" "d,R,T"))
3707117395Skan                 (match_dup 1)))
3708169689Skan   (clobber (match_scratch:GPR 0 "=d,d,d"))]
3709132718Skan  "s390_match_ccmode (insn, CCL1mode)"
3710117395Skan  "@
3711169689Skan   al<g>r\t%0,%2
3712169689Skan   al<g>\t%0,%2
3713169689Skan   al<y>\t%0,%2"
3714169689Skan  [(set_attr "op_type"  "RR<E>,RX<Y>,RXY")])
3715117395Skan
3716169689Skan; alr, alfi, slfi, al, aly, algr, algfi, slgfi, alg
3717169689Skan(define_insn "*add<mode>3_carry2_cc"
3718169689Skan  [(set (reg CC_REGNUM)
3719169689Skan        (compare (plus:GPR (match_operand:GPR 1 "nonimmediate_operand" "%0,0,0,0,0")
3720169689Skan			   (match_operand:GPR 2 "general_operand" "d,Op,On,R,T"))
3721117395Skan                 (match_dup 2)))
3722169689Skan   (set (match_operand:GPR 0 "register_operand" "=d,d,d,d,d")
3723169689Skan        (plus:GPR (match_dup 1) (match_dup 2)))]
3724132718Skan  "s390_match_ccmode (insn, CCL1mode)"
3725117395Skan  "@
3726169689Skan   al<g>r\t%0,%2
3727169689Skan   al<g>fi\t%0,%2
3728169689Skan   sl<g>fi\t%0,%n2
3729169689Skan   al<g>\t%0,%2
3730169689Skan   al<y>\t%0,%2"
3731169689Skan  [(set_attr "op_type"  "RR<E>,RIL,RIL,RX<Y>,RXY")])
3732117395Skan
3733169689Skan; alr, al, aly, algr, alg
3734169689Skan(define_insn "*add<mode>3_carry2_cconly"
3735169689Skan  [(set (reg CC_REGNUM)
3736169689Skan        (compare (plus:GPR (match_operand:GPR 1 "nonimmediate_operand" "%0,0,0")
3737169689Skan			   (match_operand:GPR 2 "general_operand" "d,R,T"))
3738117395Skan                 (match_dup 2)))
3739169689Skan   (clobber (match_scratch:GPR 0 "=d,d,d"))]
3740132718Skan  "s390_match_ccmode (insn, CCL1mode)"
3741117395Skan  "@
3742169689Skan   al<g>r\t%0,%2
3743169689Skan   al<g>\t%0,%2
3744169689Skan   al<y>\t%0,%2"
3745169689Skan  [(set_attr "op_type"  "RR<E>,RX<Y>,RXY")])
3746117395Skan
3747169689Skan; alr, alfi, slfi, al, aly, algr, algfi, slgfi, alg
3748169689Skan(define_insn "*add<mode>3_cc"
3749169689Skan  [(set (reg CC_REGNUM)
3750169689Skan        (compare (plus:GPR (match_operand:GPR 1 "nonimmediate_operand" "%0,0,0,0,0")
3751169689Skan			   (match_operand:GPR 2 "general_operand" "d,Op,On,R,T"))
3752107590Sobrien                 (const_int 0)))
3753169689Skan   (set (match_operand:GPR 0 "register_operand" "=d,d,d,d,d")
3754169689Skan        (plus:GPR (match_dup 1) (match_dup 2)))]
3755132718Skan  "s390_match_ccmode (insn, CCLmode)"
3756107590Sobrien  "@
3757169689Skan   al<g>r\t%0,%2
3758169689Skan   al<g>fi\t%0,%2
3759169689Skan   sl<g>fi\t%0,%n2
3760169689Skan   al<g>\t%0,%2
3761169689Skan   al<y>\t%0,%2"
3762169689Skan  [(set_attr "op_type"  "RR<E>,RIL,RIL,RX<Y>,RXY")])
3763107590Sobrien
3764169689Skan; alr, al, aly, algr, alg
3765169689Skan(define_insn "*add<mode>3_cconly"
3766169689Skan  [(set (reg CC_REGNUM)
3767169689Skan        (compare (plus:GPR (match_operand:GPR 1 "nonimmediate_operand" "%0,0,0")
3768169689Skan			   (match_operand:GPR 2 "general_operand" "d,R,T"))
3769107590Sobrien                 (const_int 0)))
3770169689Skan   (clobber (match_scratch:GPR 0 "=d,d,d"))]
3771132718Skan  "s390_match_ccmode (insn, CCLmode)"
3772107590Sobrien  "@
3773169689Skan   al<g>r\t%0,%2
3774169689Skan   al<g>\t%0,%2
3775169689Skan   al<y>\t%0,%2"
3776169689Skan  [(set_attr "op_type"  "RR<E>,RX<Y>,RXY")])
3777107590Sobrien
3778169689Skan; alr, al, aly, algr, alg
3779169689Skan(define_insn "*add<mode>3_cconly2"
3780169689Skan  [(set (reg CC_REGNUM)
3781169689Skan        (compare (match_operand:GPR 1 "nonimmediate_operand" "%0,0,0")
3782169689Skan                 (neg:GPR (match_operand:GPR 2 "general_operand" "d,R,T"))))
3783169689Skan   (clobber (match_scratch:GPR 0 "=d,d,d"))]
3784169689Skan  "s390_match_ccmode(insn, CCLmode)"
3785107590Sobrien  "@
3786169689Skan   al<g>r\t%0,%2
3787169689Skan   al<g>\t%0,%2
3788169689Skan   al<y>\t%0,%2"
3789169689Skan  [(set_attr "op_type"  "RR<E>,RX<Y>,RXY")])
3790107590Sobrien
3791169689Skan; ahi, afi, aghi, agfi
3792169689Skan(define_insn "*add<mode>3_imm_cc"
3793169689Skan  [(set (reg CC_REGNUM)
3794169689Skan        (compare (plus:GPR (match_operand:GPR 1 "nonimmediate_operand" "0,0")
3795169689Skan			   (match_operand:GPR 2 "const_int_operand" "K,Os"))
3796169689Skan                 (const_int 0)))
3797169689Skan   (set (match_operand:GPR 0 "register_operand" "=d,d")
3798169689Skan        (plus:GPR (match_dup 1) (match_dup 2)))]
3799169689Skan  "s390_match_ccmode (insn, CCAmode)
3800169689Skan   && (CONST_OK_FOR_CONSTRAINT_P (INTVAL (operands[2]), 'K', \"K\")
3801169689Skan       || CONST_OK_FOR_CONSTRAINT_P (INTVAL (operands[2]), 'O', \"Os\"))
3802169689Skan   && INTVAL (operands[2]) != -((HOST_WIDE_INT)1 << (GET_MODE_BITSIZE(<MODE>mode) - 1))"
3803132718Skan  "@
3804169689Skan   a<g>hi\t%0,%h2
3805169689Skan   a<g>fi\t%0,%2"
3806169689Skan  [(set_attr "op_type"  "RI,RIL")])
3807117395Skan
3808107590Sobrien;
3809169689Skan; add(df|sf)3 instruction pattern(s).
3810107590Sobrien;
3811107590Sobrien
3812169689Skan(define_expand "add<mode>3"
3813107590Sobrien  [(parallel
3814169689Skan    [(set (match_operand:FPR 0 "register_operand" "=f,f")
3815169689Skan          (plus:FPR (match_operand:FPR 1 "nonimmediate_operand" "%0,0")
3816169689Skan                    (match_operand:FPR 2 "general_operand" "f,<Rf>")))
3817169689Skan     (clobber (reg:CC CC_REGNUM))])]
3818107590Sobrien  "TARGET_HARD_FLOAT"
3819107590Sobrien  "")
3820107590Sobrien
3821169689Skan; axbr, adbr, aebr, axb, adb, aeb
3822169689Skan(define_insn "*add<mode>3"
3823169689Skan  [(set (match_operand:FPR 0 "register_operand" "=f,f")
3824169689Skan        (plus:FPR (match_operand:FPR 1 "nonimmediate_operand" "%0,0")
3825169689Skan                  (match_operand:FPR 2 "general_operand" "f,<Rf>")))
3826169689Skan   (clobber (reg:CC CC_REGNUM))]
3827107590Sobrien  "TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT"
3828107590Sobrien  "@
3829169689Skan   a<xde>br\t%0,%2
3830169689Skan   a<xde>b\t%0,%2"
3831107590Sobrien  [(set_attr "op_type"  "RRE,RXE")
3832169689Skan   (set_attr "type"     "fsimp<mode>")])
3833107590Sobrien
3834169689Skan; axbr, adbr, aebr, axb, adb, aeb
3835169689Skan(define_insn "*add<mode>3_cc"
3836169689Skan  [(set (reg CC_REGNUM)
3837169689Skan	(compare (plus:FPR (match_operand:FPR 1 "nonimmediate_operand" "%0,0")
3838169689Skan			   (match_operand:FPR 2 "general_operand" "f,<Rf>"))
3839169689Skan		 (match_operand:FPR 3 "const0_operand" "")))
3840169689Skan   (set (match_operand:FPR 0 "register_operand" "=f,f")
3841169689Skan	(plus:FPR (match_dup 1) (match_dup 2)))]
3842132718Skan  "s390_match_ccmode (insn, CCSmode) && TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT"
3843132718Skan  "@
3844169689Skan   a<xde>br\t%0,%2
3845169689Skan   a<xde>b\t%0,%2"
3846132718Skan  [(set_attr "op_type"  "RRE,RXE")
3847169689Skan   (set_attr "type"     "fsimp<mode>")])
3848132718Skan
3849169689Skan; axbr, adbr, aebr, axb, adb, aeb
3850169689Skan(define_insn "*add<mode>3_cconly"
3851169689Skan  [(set (reg CC_REGNUM)
3852169689Skan	(compare (plus:FPR (match_operand:FPR 1 "nonimmediate_operand" "%0,0")
3853169689Skan			   (match_operand:FPR 2 "general_operand" "f,<Rf>"))
3854169689Skan		 (match_operand:FPR 3 "const0_operand" "")))
3855169689Skan   (clobber (match_scratch:FPR 0 "=f,f"))]
3856132718Skan  "s390_match_ccmode (insn, CCSmode) && TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT"
3857132718Skan  "@
3858169689Skan   a<xde>br\t%0,%2
3859169689Skan   a<xde>b\t%0,%2"
3860132718Skan  [(set_attr "op_type"  "RRE,RXE")
3861169689Skan   (set_attr "type"     "fsimp<mode>")])
3862132718Skan
3863169689Skan; axr, adr, aer, ax, ad, ae
3864169689Skan(define_insn "*add<mode>3_ibm"
3865169689Skan  [(set (match_operand:FPR 0 "register_operand" "=f,f")
3866169689Skan        (plus:FPR (match_operand:FPR 1 "nonimmediate_operand" "%0,0")
3867169689Skan                  (match_operand:FPR 2 "general_operand" "f,<Rf>")))
3868169689Skan   (clobber (reg:CC CC_REGNUM))]
3869107590Sobrien  "TARGET_HARD_FLOAT && TARGET_IBM_FLOAT"
3870107590Sobrien  "@
3871169689Skan   a<xde>r\t%0,%2
3872169689Skan   a<xde>\t%0,%2"
3873169689Skan  [(set_attr "op_type"  "<RRe>,<RXe>")
3874169689Skan   (set_attr "type"     "fsimp<mode>")])
3875107590Sobrien
3876107590Sobrien
3877107590Sobrien;;
3878107590Sobrien;;- Subtract instructions.
3879107590Sobrien;;
3880107590Sobrien
3881107590Sobrien;
3882169689Skan; subti3 instruction pattern(s).
3883169689Skan;
3884169689Skan
3885169689Skan(define_insn_and_split "subti3"
3886169689Skan  [(set (match_operand:TI 0 "register_operand" "=&d")
3887169689Skan        (minus:TI (match_operand:TI 1 "register_operand" "0")
3888169689Skan                  (match_operand:TI 2 "general_operand" "do") ) )
3889169689Skan   (clobber (reg:CC CC_REGNUM))]
3890169689Skan  "TARGET_64BIT"
3891169689Skan  "#"
3892169689Skan  "&& reload_completed"
3893169689Skan  [(parallel
3894169689Skan    [(set (reg:CCL2 CC_REGNUM)
3895169689Skan          (compare:CCL2 (minus:DI (match_dup 7) (match_dup 8))
3896169689Skan                        (match_dup 7)))
3897169689Skan     (set (match_dup 6) (minus:DI (match_dup 7) (match_dup 8)))])
3898169689Skan   (parallel
3899169689Skan    [(set (match_dup 3) (minus:DI (minus:DI (match_dup 4) (match_dup 5))
3900169689Skan                                  (gtu:DI (reg:CCL2 CC_REGNUM) (const_int 0))))
3901169689Skan     (clobber (reg:CC CC_REGNUM))])]
3902169689Skan  "operands[3] = operand_subword (operands[0], 0, 0, TImode);
3903169689Skan   operands[4] = operand_subword (operands[1], 0, 0, TImode);
3904169689Skan   operands[5] = operand_subword (operands[2], 0, 0, TImode);
3905169689Skan   operands[6] = operand_subword (operands[0], 1, 0, TImode);
3906169689Skan   operands[7] = operand_subword (operands[1], 1, 0, TImode);
3907169689Skan   operands[8] = operand_subword (operands[2], 1, 0, TImode);")
3908169689Skan
3909169689Skan;
3910107590Sobrien; subdi3 instruction pattern(s).
3911107590Sobrien;
3912107590Sobrien
3913169689Skan(define_expand "subdi3"
3914169689Skan  [(parallel
3915169689Skan    [(set (match_operand:DI 0 "register_operand" "")
3916169689Skan          (minus:DI (match_operand:DI 1 "register_operand" "")
3917169689Skan                    (match_operand:DI 2 "general_operand" "")))
3918169689Skan     (clobber (reg:CC CC_REGNUM))])]
3919169689Skan  ""
3920169689Skan  "")
3921169689Skan
3922117395Skan(define_insn "*subdi3_sign"
3923117395Skan  [(set (match_operand:DI 0 "register_operand" "=d,d")
3924117395Skan        (minus:DI (match_operand:DI 1 "register_operand" "0,0")
3925117395Skan                  (sign_extend:DI (match_operand:SI 2 "general_operand" "d,m"))))
3926169689Skan   (clobber (reg:CC CC_REGNUM))]
3927117395Skan  "TARGET_64BIT"
3928117395Skan  "@
3929132718Skan   sgfr\t%0,%2
3930132718Skan   sgf\t%0,%2"
3931132718Skan  [(set_attr "op_type"  "RRE,RXY")])
3932117395Skan
3933117395Skan(define_insn "*subdi3_zero_cc"
3934169689Skan  [(set (reg CC_REGNUM)
3935117395Skan        (compare (minus:DI (match_operand:DI 1 "register_operand" "0,0")
3936117395Skan                           (zero_extend:DI (match_operand:SI 2 "general_operand" "d,m")))
3937117395Skan                 (const_int 0)))
3938117395Skan   (set (match_operand:DI 0 "register_operand" "=d,d")
3939117395Skan        (minus:DI (match_dup 1) (zero_extend:DI (match_dup 2))))]
3940117395Skan  "s390_match_ccmode (insn, CCLmode) && TARGET_64BIT"
3941117395Skan  "@
3942132718Skan   slgfr\t%0,%2
3943132718Skan   slgf\t%0,%2"
3944132718Skan  [(set_attr "op_type"  "RRE,RXY")])
3945117395Skan
3946117395Skan(define_insn "*subdi3_zero_cconly"
3947169689Skan  [(set (reg CC_REGNUM)
3948117395Skan        (compare (minus:DI (match_operand:DI 1 "register_operand" "0,0")
3949117395Skan                           (zero_extend:DI (match_operand:SI 2 "general_operand" "d,m")))
3950117395Skan                 (const_int 0)))
3951117395Skan   (clobber (match_scratch:DI 0 "=d,d"))]
3952117395Skan  "s390_match_ccmode (insn, CCLmode) && TARGET_64BIT"
3953117395Skan  "@
3954132718Skan   slgfr\t%0,%2
3955132718Skan   slgf\t%0,%2"
3956132718Skan  [(set_attr "op_type"  "RRE,RXY")])
3957117395Skan
3958117395Skan(define_insn "*subdi3_zero"
3959117395Skan  [(set (match_operand:DI 0 "register_operand" "=d,d")
3960117395Skan        (minus:DI (match_operand:DI 1 "register_operand" "0,0")
3961117395Skan                  (zero_extend:DI (match_operand:SI 2 "general_operand" "d,m"))))
3962169689Skan   (clobber (reg:CC CC_REGNUM))]
3963117395Skan  "TARGET_64BIT"
3964117395Skan  "@
3965132718Skan   slgfr\t%0,%2
3966132718Skan   slgf\t%0,%2"
3967132718Skan  [(set_attr "op_type"  "RRE,RXY")])
3968117395Skan
3969132718Skan(define_insn_and_split "*subdi3_31z"
3970132718Skan  [(set (match_operand:DI 0 "register_operand" "=&d")
3971132718Skan        (minus:DI (match_operand:DI 1 "register_operand" "0")
3972132718Skan                  (match_operand:DI 2 "general_operand" "do") ) )
3973169689Skan   (clobber (reg:CC CC_REGNUM))]
3974132718Skan  "!TARGET_64BIT && TARGET_CPU_ZARCH"
3975132718Skan  "#"
3976132718Skan  "&& reload_completed"
3977132718Skan  [(parallel
3978169689Skan    [(set (reg:CCL2 CC_REGNUM)
3979132718Skan          (compare:CCL2 (minus:SI (match_dup 7) (match_dup 8))
3980132718Skan                        (match_dup 7)))
3981132718Skan     (set (match_dup 6) (minus:SI (match_dup 7) (match_dup 8)))])
3982132718Skan   (parallel
3983132718Skan    [(set (match_dup 3) (minus:SI (minus:SI (match_dup 4) (match_dup 5))
3984169689Skan                                  (gtu:SI (reg:CCL2 CC_REGNUM) (const_int 0))))
3985169689Skan     (clobber (reg:CC CC_REGNUM))])]
3986132718Skan  "operands[3] = operand_subword (operands[0], 0, 0, DImode);
3987132718Skan   operands[4] = operand_subword (operands[1], 0, 0, DImode);
3988132718Skan   operands[5] = operand_subword (operands[2], 0, 0, DImode);
3989132718Skan   operands[6] = operand_subword (operands[0], 1, 0, DImode);
3990132718Skan   operands[7] = operand_subword (operands[1], 1, 0, DImode);
3991169689Skan   operands[8] = operand_subword (operands[2], 1, 0, DImode);")
3992132718Skan
3993117395Skan(define_insn_and_split "*subdi3_31"
3994117395Skan  [(set (match_operand:DI 0 "register_operand" "=&d")
3995117395Skan        (minus:DI (match_operand:DI 1 "register_operand" "0")
3996117395Skan                  (match_operand:DI 2 "general_operand" "do") ) )
3997169689Skan   (clobber (reg:CC CC_REGNUM))]
3998132718Skan  "!TARGET_CPU_ZARCH"
3999117395Skan  "#"
4000117395Skan  "&& reload_completed"
4001117395Skan  [(parallel
4002117395Skan    [(set (match_dup 3) (minus:SI (match_dup 4) (match_dup 5)))
4003169689Skan     (clobber (reg:CC CC_REGNUM))])
4004117395Skan   (parallel
4005169689Skan    [(set (reg:CCL2 CC_REGNUM)
4006117395Skan          (compare:CCL2 (minus:SI (match_dup 7) (match_dup 8))
4007117395Skan                        (match_dup 7)))
4008117395Skan     (set (match_dup 6) (minus:SI (match_dup 7) (match_dup 8)))])
4009117395Skan   (set (pc)
4010169689Skan        (if_then_else (gtu (reg:CCL2 CC_REGNUM) (const_int 0))
4011117395Skan                      (pc)
4012117395Skan                      (label_ref (match_dup 9))))
4013117395Skan   (parallel
4014117395Skan    [(set (match_dup 3) (plus:SI (match_dup 3) (const_int -1)))
4015169689Skan     (clobber (reg:CC CC_REGNUM))])
4016117395Skan   (match_dup 9)]
4017117395Skan  "operands[3] = operand_subword (operands[0], 0, 0, DImode);
4018117395Skan   operands[4] = operand_subword (operands[1], 0, 0, DImode);
4019117395Skan   operands[5] = operand_subword (operands[2], 0, 0, DImode);
4020117395Skan   operands[6] = operand_subword (operands[0], 1, 0, DImode);
4021117395Skan   operands[7] = operand_subword (operands[1], 1, 0, DImode);
4022117395Skan   operands[8] = operand_subword (operands[2], 1, 0, DImode);
4023169689Skan   operands[9] = gen_label_rtx ();")
4024117395Skan
4025107590Sobrien;
4026107590Sobrien; subsi3 instruction pattern(s).
4027107590Sobrien;
4028107590Sobrien
4029169689Skan(define_expand "subsi3"
4030169689Skan  [(parallel
4031169689Skan    [(set (match_operand:SI 0 "register_operand" "")
4032169689Skan          (minus:SI (match_operand:SI 1 "register_operand" "")
4033169689Skan                    (match_operand:SI 2 "general_operand" "")))
4034169689Skan     (clobber (reg:CC CC_REGNUM))])]
4035169689Skan  ""
4036169689Skan  "")
4037117395Skan
4038117395Skan(define_insn "*subsi3_sign"
4039132718Skan  [(set (match_operand:SI 0 "register_operand" "=d,d")
4040132718Skan        (minus:SI (match_operand:SI 1 "register_operand" "0,0")
4041132718Skan                  (sign_extend:SI (match_operand:HI 2 "memory_operand" "R,T"))))
4042169689Skan   (clobber (reg:CC CC_REGNUM))]
4043117395Skan  ""
4044132718Skan  "@
4045132718Skan   sh\t%0,%2
4046132718Skan   shy\t%0,%2"
4047132718Skan  [(set_attr "op_type"  "RX,RXY")])
4048117395Skan
4049169689Skan;
4050169689Skan; sub(di|si)3 instruction pattern(s).
4051169689Skan;
4052169689Skan
4053169689Skan; sr, s, sy, sgr, sg
4054169689Skan(define_insn "*sub<mode>3"
4055169689Skan  [(set (match_operand:GPR 0 "register_operand" "=d,d,d")
4056169689Skan        (minus:GPR (match_operand:GPR 1 "register_operand" "0,0,0")
4057169689Skan		   (match_operand:GPR 2 "general_operand" "d,R,T") ) )
4058169689Skan   (clobber (reg:CC CC_REGNUM))]
4059107590Sobrien  ""
4060107590Sobrien  "@
4061169689Skan   s<g>r\t%0,%2
4062169689Skan   s<g>\t%0,%2
4063169689Skan   s<y>\t%0,%2"
4064169689Skan  [(set_attr "op_type"  "RR<E>,RX<Y>,RXY")])
4065107590Sobrien
4066169689Skan; slr, sl, sly, slgr, slg
4067169689Skan(define_insn "*sub<mode>3_borrow_cc"
4068169689Skan  [(set (reg CC_REGNUM)
4069169689Skan        (compare (minus:GPR (match_operand:GPR 1 "register_operand" "0,0,0")
4070169689Skan			    (match_operand:GPR 2 "general_operand" "d,R,T"))
4071169689Skan                 (match_dup 1)))
4072169689Skan   (set (match_operand:GPR 0 "register_operand" "=d,d,d")
4073169689Skan        (minus:GPR (match_dup 1) (match_dup 2)))]
4074169689Skan  "s390_match_ccmode (insn, CCL2mode)"
4075169689Skan  "@
4076169689Skan   sl<g>r\t%0,%2
4077169689Skan   sl<g>\t%0,%2
4078169689Skan   sl<y>\t%0,%2"
4079169689Skan  [(set_attr "op_type"  "RR<E>,RX<Y>,RXY")])
4080107590Sobrien
4081169689Skan; slr, sl, sly, slgr, slg
4082169689Skan(define_insn "*sub<mode>3_borrow_cconly"
4083169689Skan  [(set (reg CC_REGNUM)
4084169689Skan        (compare (minus:GPR (match_operand:GPR 1 "register_operand" "0,0,0")
4085169689Skan			    (match_operand:GPR 2 "general_operand" "d,R,T"))
4086169689Skan                 (match_dup 1)))
4087169689Skan   (clobber (match_scratch:GPR 0 "=d,d,d"))]
4088169689Skan  "s390_match_ccmode (insn, CCL2mode)"
4089169689Skan  "@
4090169689Skan   sl<g>r\t%0,%2
4091169689Skan   sl<g>\t%0,%2
4092169689Skan   sl<y>\t%0,%2"
4093169689Skan  [(set_attr "op_type"  "RR<E>,RX<Y>,RXY")])
4094107590Sobrien
4095169689Skan; slr, sl, sly, slgr, slg
4096169689Skan(define_insn "*sub<mode>3_cc"
4097169689Skan  [(set (reg CC_REGNUM)
4098169689Skan        (compare (minus:GPR (match_operand:GPR 1 "register_operand" "0,0,0")
4099169689Skan			    (match_operand:GPR 2 "general_operand" "d,R,T"))
4100169689Skan                 (const_int 0)))
4101169689Skan   (set (match_operand:GPR 0 "register_operand" "=d,d,d")
4102169689Skan        (minus:GPR (match_dup 1) (match_dup 2)))]
4103169689Skan  "s390_match_ccmode (insn, CCLmode)"
4104107590Sobrien  "@
4105169689Skan   sl<g>r\t%0,%2
4106169689Skan   sl<g>\t%0,%2
4107169689Skan   sl<y>\t%0,%2"
4108169689Skan  [(set_attr "op_type"  "RR<E>,RX<Y>,RXY")])
4109107590Sobrien
4110169689Skan; slr, sl, sly, slgr, slg
4111169689Skan(define_insn "*sub<mode>3_cc2"
4112169689Skan  [(set (reg CC_REGNUM)
4113169689Skan        (compare (match_operand:GPR 1 "register_operand" "0,0,0")
4114169689Skan                 (match_operand:GPR 2 "general_operand" "d,R,T")))
4115169689Skan   (set (match_operand:GPR 0 "register_operand" "=d,d,d")
4116169689Skan        (minus:GPR (match_dup 1) (match_dup 2)))]
4117169689Skan  "s390_match_ccmode (insn, CCL3mode)"
4118132718Skan  "@
4119169689Skan   sl<g>r\t%0,%2
4120169689Skan   sl<g>\t%0,%2
4121169689Skan   sl<y>\t%0,%2"
4122169689Skan  [(set_attr "op_type"  "RR<E>,RX<Y>,RXY")])
4123132718Skan
4124169689Skan; slr, sl, sly, slgr, slg
4125169689Skan(define_insn "*sub<mode>3_cconly"
4126169689Skan  [(set (reg CC_REGNUM)
4127169689Skan        (compare (minus:GPR (match_operand:GPR 1 "register_operand" "0,0,0")
4128169689Skan			    (match_operand:GPR 2 "general_operand" "d,R,T"))
4129169689Skan                 (const_int 0)))
4130169689Skan   (clobber (match_scratch:GPR 0 "=d,d,d"))]
4131169689Skan  "s390_match_ccmode (insn, CCLmode)"
4132132718Skan  "@
4133169689Skan   sl<g>r\t%0,%2
4134169689Skan   sl<g>\t%0,%2
4135169689Skan   sl<y>\t%0,%2"
4136169689Skan  [(set_attr "op_type"  "RR<E>,RX<Y>,RXY")])
4137132718Skan
4138169689Skan; slr, sl, sly, slgr, slg
4139169689Skan(define_insn "*sub<mode>3_cconly2"
4140169689Skan  [(set (reg CC_REGNUM)
4141169689Skan        (compare (match_operand:GPR 1 "register_operand" "0,0,0")
4142169689Skan                 (match_operand:GPR 2 "general_operand" "d,R,T")))
4143169689Skan   (clobber (match_scratch:GPR 0 "=d,d,d"))]
4144169689Skan  "s390_match_ccmode (insn, CCL3mode)"
4145107590Sobrien  "@
4146169689Skan   sl<g>r\t%0,%2
4147169689Skan   sl<g>\t%0,%2
4148169689Skan   sl<y>\t%0,%2"
4149169689Skan  [(set_attr "op_type"  "RR<E>,RX<Y>,RXY")])
4150107590Sobrien
4151107590Sobrien;
4152169689Skan; sub(df|sf)3 instruction pattern(s).
4153107590Sobrien;
4154107590Sobrien
4155169689Skan(define_expand "sub<mode>3"
4156107590Sobrien  [(parallel
4157169689Skan    [(set (match_operand:FPR 0 "register_operand" "=f,f")
4158169689Skan          (minus:FPR (match_operand:FPR 1 "register_operand" "0,0")
4159169689Skan                     (match_operand:FPR 2 "general_operand" "f,R")))
4160169689Skan     (clobber (reg:CC CC_REGNUM))])]
4161107590Sobrien  "TARGET_HARD_FLOAT"
4162107590Sobrien  "")
4163107590Sobrien
4164169689Skan; sxbr, sdbr, sebr, sxb, sdb, seb
4165169689Skan(define_insn "*sub<mode>3"
4166169689Skan  [(set (match_operand:FPR 0 "register_operand" "=f,f")
4167169689Skan        (minus:FPR (match_operand:FPR 1 "register_operand" "0,0")
4168169689Skan                   (match_operand:FPR 2 "general_operand" "f,<Rf>")))
4169169689Skan   (clobber (reg:CC CC_REGNUM))]
4170107590Sobrien  "TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT"
4171107590Sobrien  "@
4172169689Skan   s<xde>br\t%0,%2
4173169689Skan   s<xde>b\t%0,%2"
4174107590Sobrien  [(set_attr "op_type"  "RRE,RXE")
4175169689Skan   (set_attr "type"     "fsimp<mode>")])
4176107590Sobrien
4177169689Skan; sxbr, sdbr, sebr, sxb, sdb, seb
4178169689Skan(define_insn "*sub<mode>3_cc"
4179169689Skan  [(set (reg CC_REGNUM)
4180169689Skan	(compare (minus:FPR (match_operand:FPR 1 "nonimmediate_operand" "0,0")
4181169689Skan			    (match_operand:FPR 2 "general_operand" "f,<Rf>"))
4182169689Skan		 (match_operand:FPR 3 "const0_operand" "")))
4183169689Skan   (set (match_operand:FPR 0 "register_operand" "=f,f")
4184169689Skan	(minus:FPR (match_dup 1) (match_dup 2)))]
4185132718Skan  "s390_match_ccmode (insn, CCSmode) && TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT"
4186132718Skan  "@
4187169689Skan   s<xde>br\t%0,%2
4188169689Skan   s<xde>b\t%0,%2"
4189132718Skan  [(set_attr "op_type"  "RRE,RXE")
4190169689Skan   (set_attr "type"     "fsimp<mode>")])
4191132718Skan
4192169689Skan; sxbr, sdbr, sebr, sxb, sdb, seb
4193169689Skan(define_insn "*sub<mode>3_cconly"
4194169689Skan  [(set (reg CC_REGNUM)
4195169689Skan	(compare (minus:FPR (match_operand:FPR 1 "nonimmediate_operand" "0,0")
4196169689Skan			    (match_operand:FPR 2 "general_operand" "f,<Rf>"))
4197169689Skan		 (match_operand:FPR 3 "const0_operand" "")))
4198169689Skan   (clobber (match_scratch:FPR 0 "=f,f"))]
4199132718Skan  "s390_match_ccmode (insn, CCSmode) && TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT"
4200132718Skan  "@
4201169689Skan   s<xde>br\t%0,%2
4202169689Skan   s<xde>b\t%0,%2"
4203132718Skan  [(set_attr "op_type"  "RRE,RXE")
4204169689Skan   (set_attr "type"     "fsimp<mode>")])
4205132718Skan
4206169689Skan; sxr, sdr, ser, sx, sd, se
4207169689Skan(define_insn "*sub<mode>3_ibm"
4208169689Skan  [(set (match_operand:FPR 0 "register_operand" "=f,f")
4209169689Skan        (minus:FPR (match_operand:FPR 1 "register_operand" "0,0")
4210169689Skan                   (match_operand:FPR 2 "general_operand" "f,<Rf>")))
4211169689Skan   (clobber (reg:CC CC_REGNUM))]
4212107590Sobrien  "TARGET_HARD_FLOAT && TARGET_IBM_FLOAT"
4213107590Sobrien  "@
4214169689Skan   s<xde>r\t%0,%2
4215169689Skan   s<xde>\t%0,%2"
4216169689Skan  [(set_attr "op_type"  "<RRe>,<RXe>")
4217169689Skan   (set_attr "type"     "fsimp<mode>")])
4218107590Sobrien
4219107590Sobrien
4220107590Sobrien;;
4221132718Skan;;- Conditional add/subtract instructions.
4222132718Skan;;
4223132718Skan
4224132718Skan;
4225169689Skan; add(di|si)cc instruction pattern(s).
4226132718Skan;
4227132718Skan
4228169689Skan; alcr, alc, alcgr, alcg
4229169689Skan(define_insn "*add<mode>3_alc_cc"
4230169689Skan  [(set (reg CC_REGNUM)
4231132718Skan        (compare
4232169689Skan          (plus:GPR (plus:GPR (match_operand:GPR 1 "nonimmediate_operand" "%0,0")
4233169689Skan                              (match_operand:GPR 2 "general_operand" "d,m"))
4234169689Skan                    (match_operand:GPR 3 "s390_alc_comparison" ""))
4235132718Skan          (const_int 0)))
4236169689Skan   (set (match_operand:GPR 0 "register_operand" "=d,d")
4237169689Skan        (plus:GPR (plus:GPR (match_dup 1) (match_dup 2)) (match_dup 3)))]
4238169689Skan  "s390_match_ccmode (insn, CCLmode) && TARGET_CPU_ZARCH"
4239132718Skan  "@
4240169689Skan   alc<g>r\t%0,%2
4241169689Skan   alc<g>\t%0,%2"
4242132718Skan  [(set_attr "op_type"  "RRE,RXY")])
4243132718Skan
4244169689Skan; alcr, alc, alcgr, alcg
4245169689Skan(define_insn "*add<mode>3_alc"
4246169689Skan  [(set (match_operand:GPR 0 "register_operand" "=d,d")
4247169689Skan        (plus:GPR (plus:GPR (match_operand:GPR 1 "nonimmediate_operand" "%0,0")
4248169689Skan                            (match_operand:GPR 2 "general_operand" "d,m"))
4249169689Skan                  (match_operand:GPR 3 "s390_alc_comparison" "")))
4250169689Skan   (clobber (reg:CC CC_REGNUM))]
4251169689Skan  "TARGET_CPU_ZARCH"
4252132718Skan  "@
4253169689Skan   alc<g>r\t%0,%2
4254169689Skan   alc<g>\t%0,%2"
4255132718Skan  [(set_attr "op_type"  "RRE,RXY")])
4256132718Skan
4257169689Skan; slbr, slb, slbgr, slbg
4258169689Skan(define_insn "*sub<mode>3_slb_cc"
4259169689Skan  [(set (reg CC_REGNUM)
4260132718Skan        (compare
4261169689Skan          (minus:GPR (minus:GPR (match_operand:GPR 1 "nonimmediate_operand" "0,0")
4262169689Skan                                (match_operand:GPR 2 "general_operand" "d,m"))
4263169689Skan                     (match_operand:GPR 3 "s390_slb_comparison" ""))
4264132718Skan          (const_int 0)))
4265169689Skan   (set (match_operand:GPR 0 "register_operand" "=d,d")
4266169689Skan        (minus:GPR (minus:GPR (match_dup 1) (match_dup 2)) (match_dup 3)))]
4267169689Skan  "s390_match_ccmode (insn, CCLmode) && TARGET_CPU_ZARCH"
4268132718Skan  "@
4269169689Skan   slb<g>r\t%0,%2
4270169689Skan   slb<g>\t%0,%2"
4271132718Skan  [(set_attr "op_type"  "RRE,RXY")])
4272132718Skan
4273169689Skan; slbr, slb, slbgr, slbg
4274169689Skan(define_insn "*sub<mode>3_slb"
4275169689Skan  [(set (match_operand:GPR 0 "register_operand" "=d,d")
4276169689Skan        (minus:GPR (minus:GPR (match_operand:GPR 1 "nonimmediate_operand" "0,0")
4277169689Skan                              (match_operand:GPR 2 "general_operand" "d,m"))
4278169689Skan                   (match_operand:GPR 3 "s390_slb_comparison" "")))
4279169689Skan   (clobber (reg:CC CC_REGNUM))]
4280169689Skan  "TARGET_CPU_ZARCH"
4281132718Skan  "@
4282169689Skan   slb<g>r\t%0,%2
4283169689Skan   slb<g>\t%0,%2"
4284132718Skan  [(set_attr "op_type"  "RRE,RXY")])
4285132718Skan
4286169689Skan(define_expand "add<mode>cc"
4287169689Skan  [(match_operand:GPR 0 "register_operand" "")
4288169689Skan   (match_operand 1 "comparison_operator" "")
4289169689Skan   (match_operand:GPR 2 "register_operand" "")
4290169689Skan   (match_operand:GPR 3 "const_int_operand" "")]
4291169689Skan  "TARGET_CPU_ZARCH"
4292169689Skan  "if (!s390_expand_addcc (GET_CODE (operands[1]), 
4293169689Skan			   s390_compare_op0, s390_compare_op1, 
4294169689Skan			   operands[0], operands[2], 
4295169689Skan			   operands[3])) FAIL; DONE;")
4296169689Skan
4297132718Skan;
4298169689Skan; scond instruction pattern(s).
4299132718Skan;
4300132718Skan
4301169689Skan(define_insn_and_split "*scond<mode>"
4302169689Skan  [(set (match_operand:GPR 0 "register_operand" "=&d")
4303169689Skan        (match_operand:GPR 1 "s390_alc_comparison" ""))
4304169689Skan   (clobber (reg:CC CC_REGNUM))]
4305169689Skan  "TARGET_CPU_ZARCH"
4306169689Skan  "#"
4307169689Skan  "&& reload_completed"
4308169689Skan  [(set (match_dup 0) (const_int 0))
4309169689Skan   (parallel
4310169689Skan    [(set (match_dup 0) (plus:GPR (plus:GPR (match_dup 0) (match_dup 0))
4311169689Skan                                  (match_dup 1)))
4312169689Skan     (clobber (reg:CC CC_REGNUM))])]
4313169689Skan  "")
4314132718Skan
4315169689Skan(define_insn_and_split "*scond<mode>_neg"
4316169689Skan  [(set (match_operand:GPR 0 "register_operand" "=&d")
4317169689Skan        (match_operand:GPR 1 "s390_slb_comparison" ""))
4318169689Skan   (clobber (reg:CC CC_REGNUM))]
4319169689Skan  "TARGET_CPU_ZARCH"
4320169689Skan  "#"
4321169689Skan  "&& reload_completed"
4322169689Skan  [(set (match_dup 0) (const_int 0))
4323169689Skan   (parallel
4324169689Skan    [(set (match_dup 0) (minus:GPR (minus:GPR (match_dup 0) (match_dup 0))
4325169689Skan                                   (match_dup 1)))
4326169689Skan     (clobber (reg:CC CC_REGNUM))])
4327169689Skan   (parallel
4328169689Skan    [(set (match_dup 0) (neg:GPR (match_dup 0)))
4329169689Skan     (clobber (reg:CC CC_REGNUM))])]
4330169689Skan  "")
4331132718Skan
4332132718Skan
4333169689Skan(define_expand "s<code>"
4334169689Skan  [(set (match_operand:SI 0 "register_operand" "")
4335169689Skan	(SCOND (match_dup 0)
4336169689Skan	       (match_dup 0)))]
4337169689Skan  "TARGET_CPU_ZARCH"
4338169689Skan  "if (!s390_expand_addcc (<CODE>, s390_compare_op0, s390_compare_op1,
4339169689Skan			   operands[0], const0_rtx, const1_rtx)) FAIL; DONE;")
4340132718Skan
4341169689Skan(define_expand "seq"
4342169689Skan  [(parallel
4343169689Skan    [(set (match_operand:SI 0 "register_operand" "=d")
4344169689Skan          (match_dup 1))
4345169689Skan     (clobber (reg:CC CC_REGNUM))])
4346169689Skan   (parallel
4347169689Skan    [(set (match_dup 0) (xor:SI (match_dup 0) (const_int 1)))
4348169689Skan     (clobber (reg:CC CC_REGNUM))])]
4349169689Skan  ""
4350169689Skan{ 
4351169689Skan  if (!s390_compare_emitted || GET_MODE (s390_compare_emitted) != CCZ1mode)
4352169689Skan    FAIL;
4353169689Skan  operands[1] = s390_emit_compare (NE, s390_compare_op0, s390_compare_op1);
4354169689Skan  PUT_MODE (operands[1], SImode);
4355169689Skan})
4356132718Skan
4357169689Skan(define_insn_and_split "*sne"
4358169689Skan  [(set (match_operand:SI 0 "register_operand" "=d")
4359169689Skan	(ne:SI (match_operand:CCZ1 1 "register_operand" "0") 
4360169689Skan	       (const_int 0)))
4361169689Skan   (clobber (reg:CC CC_REGNUM))]
4362169689Skan  ""
4363169689Skan  "#"
4364169689Skan  "reload_completed"
4365169689Skan  [(parallel
4366169689Skan    [(set (match_dup 0) (ashiftrt:SI (match_dup 0) (const_int 28)))
4367169689Skan     (clobber (reg:CC CC_REGNUM))])])
4368169689Skan
4369169689Skan
4370132718Skan;;
4371107590Sobrien;;- Multiply instructions.
4372107590Sobrien;;
4373107590Sobrien
4374107590Sobrien;
4375107590Sobrien; muldi3 instruction pattern(s).
4376107590Sobrien;
4377107590Sobrien
4378117395Skan(define_insn "*muldi3_sign"
4379117395Skan  [(set (match_operand:DI 0 "register_operand" "=d,d")
4380117395Skan        (mult:DI (sign_extend:DI (match_operand:SI 2 "nonimmediate_operand" "d,m"))
4381117395Skan                 (match_operand:DI 1 "register_operand" "0,0")))]
4382117395Skan  "TARGET_64BIT"
4383117395Skan  "@
4384132718Skan   msgfr\t%0,%2
4385132718Skan   msgf\t%0,%2"
4386132718Skan  [(set_attr "op_type"  "RRE,RXY")
4387169689Skan   (set_attr "type"     "imuldi")])
4388117395Skan
4389107590Sobrien(define_insn "muldi3"
4390107590Sobrien  [(set (match_operand:DI 0 "register_operand" "=d,d,d")
4391117395Skan        (mult:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
4392117395Skan                 (match_operand:DI 2 "general_operand" "d,K,m")))]
4393107590Sobrien  "TARGET_64BIT"
4394107590Sobrien  "@
4395132718Skan   msgr\t%0,%2
4396132718Skan   mghi\t%0,%h2
4397132718Skan   msg\t%0,%2"
4398132718Skan  [(set_attr "op_type"  "RRE,RI,RXY")
4399169689Skan   (set_attr "type"     "imuldi")])
4400107590Sobrien
4401107590Sobrien;
4402107590Sobrien; mulsi3 instruction pattern(s).
4403107590Sobrien;
4404107590Sobrien
4405132718Skan(define_insn "*mulsi3_sign"
4406132718Skan  [(set (match_operand:SI 0 "register_operand" "=d")
4407132718Skan        (mult:SI (sign_extend:SI (match_operand:HI 2 "memory_operand" "R"))
4408132718Skan                 (match_operand:SI 1 "register_operand" "0")))]
4409132718Skan  ""
4410132718Skan  "mh\t%0,%2"
4411132718Skan  [(set_attr "op_type"  "RX")
4412169689Skan   (set_attr "type"     "imulhi")])
4413132718Skan
4414107590Sobrien(define_insn "mulsi3"
4415132718Skan  [(set (match_operand:SI 0 "register_operand" "=d,d,d,d")
4416132718Skan        (mult:SI  (match_operand:SI 1 "nonimmediate_operand" "%0,0,0,0")
4417132718Skan                  (match_operand:SI 2 "general_operand" "d,K,R,T")))]
4418107590Sobrien  ""
4419107590Sobrien  "@
4420132718Skan   msr\t%0,%2
4421132718Skan   mhi\t%0,%h2
4422132718Skan   ms\t%0,%2
4423132718Skan   msy\t%0,%2"
4424132718Skan  [(set_attr "op_type"  "RRE,RI,RX,RXY")
4425169689Skan   (set_attr "type"     "imulsi,imulhi,imulsi,imulsi")])
4426107590Sobrien
4427107590Sobrien;
4428107590Sobrien; mulsidi3 instruction pattern(s).
4429107590Sobrien;
4430107590Sobrien
4431132718Skan(define_insn "mulsidi3"
4432132718Skan  [(set (match_operand:DI 0 "register_operand" "=d,d")
4433132718Skan        (mult:DI (sign_extend:DI
4434132718Skan	           (match_operand:SI 1 "register_operand" "%0,0"))
4435132718Skan                 (sign_extend:DI
4436132718Skan	           (match_operand:SI 2 "nonimmediate_operand" "d,R"))))]
4437107590Sobrien  "!TARGET_64BIT"
4438132718Skan  "@
4439132718Skan   mr\t%0,%2
4440132718Skan   m\t%0,%2"
4441132718Skan  [(set_attr "op_type"  "RR,RX")
4442169689Skan   (set_attr "type"     "imulsi")])
4443107590Sobrien
4444132718Skan;
4445132718Skan; umulsidi3 instruction pattern(s).
4446132718Skan;
4447107590Sobrien
4448132718Skan(define_insn "umulsidi3"
4449132718Skan  [(set (match_operand:DI 0 "register_operand" "=d,d")
4450132718Skan        (mult:DI (zero_extend:DI
4451132718Skan	           (match_operand:SI 1 "register_operand" "%0,0"))
4452132718Skan                 (zero_extend:DI
4453132718Skan	           (match_operand:SI 2 "nonimmediate_operand" "d,m"))))]
4454132718Skan  "!TARGET_64BIT && TARGET_CPU_ZARCH"
4455132718Skan  "@
4456132718Skan   mlr\t%0,%2
4457132718Skan   ml\t%0,%2"
4458132718Skan  [(set_attr "op_type"  "RRE,RXY")
4459169689Skan   (set_attr "type"     "imulsi")])
4460132718Skan
4461107590Sobrien;
4462169689Skan; mul(df|sf)3 instruction pattern(s).
4463107590Sobrien;
4464107590Sobrien
4465169689Skan(define_expand "mul<mode>3"
4466169689Skan  [(set (match_operand:FPR 0 "register_operand" "=f,f")
4467169689Skan        (mult:FPR (match_operand:FPR 1 "nonimmediate_operand" "%0,0")
4468169689Skan                  (match_operand:FPR 2 "general_operand" "f,<Rf>")))]
4469107590Sobrien  "TARGET_HARD_FLOAT"
4470107590Sobrien  "")
4471107590Sobrien
4472169689Skan; mxbr mdbr, meebr, mxb, mxb, meeb
4473169689Skan(define_insn "*mul<mode>3"
4474169689Skan  [(set (match_operand:FPR 0 "register_operand" "=f,f")
4475169689Skan        (mult:FPR (match_operand:FPR 1 "nonimmediate_operand" "%0,0")
4476169689Skan                  (match_operand:FPR 2 "general_operand" "f,<Rf>")))]
4477107590Sobrien  "TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT"
4478107590Sobrien  "@
4479169689Skan   m<xdee>br\t%0,%2
4480169689Skan   m<xdee>b\t%0,%2"
4481107590Sobrien  [(set_attr "op_type"  "RRE,RXE")
4482169689Skan   (set_attr "type"     "fmul<mode>")])
4483107590Sobrien
4484169689Skan; mxr, mdr, mer, mx, md, me
4485169689Skan(define_insn "*mul<mode>3_ibm"
4486169689Skan  [(set (match_operand:FPR 0 "register_operand" "=f,f")
4487169689Skan        (mult:FPR (match_operand:FPR 1 "nonimmediate_operand" "%0,0")
4488169689Skan                  (match_operand:FPR 2 "general_operand" "f,<Rf>")))]
4489107590Sobrien  "TARGET_HARD_FLOAT && TARGET_IBM_FLOAT"
4490107590Sobrien  "@
4491169689Skan   m<xde>r\t%0,%2
4492169689Skan   m<xde>\t%0,%2"
4493169689Skan  [(set_attr "op_type"  "<RRe>,<RXe>")
4494169689Skan   (set_attr "type"     "fmul<mode>")])
4495107590Sobrien
4496169689Skan; maxbr, madbr, maebr, maxb, madb, maeb
4497169689Skan(define_insn "*fmadd<mode>"
4498169689Skan  [(set (match_operand:DSF 0 "register_operand" "=f,f")
4499169689Skan	(plus:DSF (mult:DSF (match_operand:DSF 1 "register_operand" "%f,f")
4500169689Skan			    (match_operand:DSF 2 "nonimmediate_operand"  "f,R"))
4501169689Skan		 (match_operand:DSF 3 "register_operand" "0,0")))]
4502132718Skan  "TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT && TARGET_FUSED_MADD"
4503132718Skan  "@
4504169689Skan   ma<xde>br\t%0,%1,%2
4505169689Skan   ma<xde>b\t%0,%1,%2"
4506132718Skan  [(set_attr "op_type"  "RRE,RXE")
4507169689Skan   (set_attr "type"     "fmul<mode>")])
4508132718Skan
4509169689Skan; msxbr, msdbr, msebr, msxb, msdb, mseb
4510169689Skan(define_insn "*fmsub<mode>"
4511169689Skan  [(set (match_operand:DSF 0 "register_operand" "=f,f")
4512169689Skan	(minus:DSF (mult:DSF (match_operand:DSF 1 "register_operand" "f,f")
4513169689Skan			     (match_operand:DSF 2 "nonimmediate_operand"  "f,R"))
4514169689Skan		 (match_operand:DSF 3 "register_operand" "0,0")))]
4515132718Skan  "TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT && TARGET_FUSED_MADD"
4516132718Skan  "@
4517169689Skan   ms<xde>br\t%0,%1,%2
4518169689Skan   ms<xde>b\t%0,%1,%2"
4519132718Skan  [(set_attr "op_type"  "RRE,RXE")
4520169689Skan   (set_attr "type"     "fmul<mode>")])
4521132718Skan
4522107590Sobrien;;
4523107590Sobrien;;- Divide and modulo instructions.
4524107590Sobrien;;
4525107590Sobrien
4526107590Sobrien;
4527107590Sobrien; divmoddi4 instruction pattern(s).
4528107590Sobrien;
4529107590Sobrien
4530107590Sobrien(define_expand "divmoddi4"
4531107590Sobrien  [(parallel [(set (match_operand:DI 0 "general_operand" "")
4532132718Skan		   (div:DI (match_operand:DI 1 "register_operand" "")
4533107590Sobrien			   (match_operand:DI 2 "general_operand" "")))
4534107590Sobrien	      (set (match_operand:DI 3 "general_operand" "")
4535107590Sobrien		   (mod:DI (match_dup 1) (match_dup 2)))])
4536107590Sobrien   (clobber (match_dup 4))]
4537107590Sobrien  "TARGET_64BIT"
4538107590Sobrien{
4539132718Skan  rtx insn, div_equal, mod_equal;
4540107590Sobrien
4541107590Sobrien  div_equal = gen_rtx_DIV (DImode, operands[1], operands[2]);
4542107590Sobrien  mod_equal = gen_rtx_MOD (DImode, operands[1], operands[2]);
4543107590Sobrien
4544107590Sobrien  operands[4] = gen_reg_rtx(TImode);
4545132718Skan  emit_insn (gen_divmodtidi3 (operands[4], operands[1], operands[2]));
4546107590Sobrien
4547107590Sobrien  insn = emit_move_insn (operands[0], gen_lowpart (DImode, operands[4]));
4548107590Sobrien  REG_NOTES (insn) =
4549107590Sobrien        gen_rtx_EXPR_LIST (REG_EQUAL, div_equal, REG_NOTES (insn));
4550107590Sobrien
4551107590Sobrien  insn = emit_move_insn (operands[3], gen_highpart (DImode, operands[4]));
4552107590Sobrien  REG_NOTES (insn) =
4553107590Sobrien        gen_rtx_EXPR_LIST (REG_EQUAL, mod_equal, REG_NOTES (insn));
4554107590Sobrien
4555107590Sobrien  DONE;
4556132718Skan})
4557107590Sobrien
4558107590Sobrien(define_insn "divmodtidi3"
4559107590Sobrien  [(set (match_operand:TI 0 "register_operand" "=d,d")
4560107590Sobrien        (ior:TI
4561107590Sobrien          (ashift:TI
4562107590Sobrien            (zero_extend:TI
4563169689Skan              (mod:DI (match_operand:DI 1 "register_operand" "0,0")
4564169689Skan                      (match_operand:DI 2 "general_operand" "d,m")))
4565169689Skan            (const_int 64))
4566169689Skan          (zero_extend:TI (div:DI (match_dup 1) (match_dup 2)))))]
4567107590Sobrien  "TARGET_64BIT"
4568107590Sobrien  "@
4569132718Skan   dsgr\t%0,%2
4570132718Skan   dsg\t%0,%2"
4571132718Skan  [(set_attr "op_type"  "RRE,RXY")
4572132718Skan   (set_attr "type"     "idiv")])
4573107590Sobrien
4574107590Sobrien(define_insn "divmodtisi3"
4575107590Sobrien  [(set (match_operand:TI 0 "register_operand" "=d,d")
4576107590Sobrien        (ior:TI
4577107590Sobrien          (ashift:TI
4578107590Sobrien            (zero_extend:TI
4579169689Skan              (mod:DI (match_operand:DI 1 "register_operand" "0,0")
4580169689Skan                      (sign_extend:DI
4581169689Skan                        (match_operand:SI 2 "nonimmediate_operand" "d,m"))))
4582169689Skan            (const_int 64))
4583169689Skan          (zero_extend:TI
4584169689Skan            (div:DI (match_dup 1) (sign_extend:DI (match_dup 2))))))]
4585107590Sobrien  "TARGET_64BIT"
4586107590Sobrien  "@
4587132718Skan   dsgfr\t%0,%2
4588132718Skan   dsgf\t%0,%2"
4589132718Skan  [(set_attr "op_type"  "RRE,RXY")
4590132718Skan   (set_attr "type"     "idiv")])
4591107590Sobrien
4592107590Sobrien;
4593107590Sobrien; udivmoddi4 instruction pattern(s).
4594107590Sobrien;
4595107590Sobrien
4596107590Sobrien(define_expand "udivmoddi4"
4597107590Sobrien  [(parallel [(set (match_operand:DI 0 "general_operand" "")
4598107590Sobrien		   (udiv:DI (match_operand:DI 1 "general_operand" "")
4599107590Sobrien			    (match_operand:DI 2 "nonimmediate_operand" "")))
4600107590Sobrien	      (set (match_operand:DI 3 "general_operand" "")
4601107590Sobrien		   (umod:DI (match_dup 1) (match_dup 2)))])
4602107590Sobrien   (clobber (match_dup 4))]
4603107590Sobrien  "TARGET_64BIT"
4604107590Sobrien{
4605107590Sobrien  rtx insn, div_equal, mod_equal, equal;
4606107590Sobrien
4607107590Sobrien  div_equal = gen_rtx_UDIV (DImode, operands[1], operands[2]);
4608107590Sobrien  mod_equal = gen_rtx_UMOD (DImode, operands[1], operands[2]);
4609107590Sobrien  equal = gen_rtx_IOR (TImode,
4610107590Sobrien		       gen_rtx_ASHIFT (TImode,
4611107590Sobrien				       gen_rtx_ZERO_EXTEND (TImode, mod_equal),
4612169689Skan				       GEN_INT (64)),
4613169689Skan		       gen_rtx_ZERO_EXTEND (TImode, div_equal));
4614107590Sobrien
4615107590Sobrien  operands[4] = gen_reg_rtx(TImode);
4616107590Sobrien  emit_insn (gen_rtx_CLOBBER (VOIDmode, operands[4]));
4617107590Sobrien  emit_move_insn (gen_lowpart (DImode, operands[4]), operands[1]);
4618107590Sobrien  emit_move_insn (gen_highpart (DImode, operands[4]), const0_rtx);
4619107590Sobrien  insn = emit_insn (gen_udivmodtidi3 (operands[4], operands[4], operands[2]));
4620107590Sobrien  REG_NOTES (insn) =
4621107590Sobrien	gen_rtx_EXPR_LIST (REG_EQUAL, equal, REG_NOTES (insn));
4622107590Sobrien
4623107590Sobrien  insn = emit_move_insn (operands[0], gen_lowpart (DImode, operands[4]));
4624107590Sobrien  REG_NOTES (insn) =
4625107590Sobrien        gen_rtx_EXPR_LIST (REG_EQUAL, div_equal, REG_NOTES (insn));
4626107590Sobrien
4627107590Sobrien  insn = emit_move_insn (operands[3], gen_highpart (DImode, operands[4]));
4628107590Sobrien  REG_NOTES (insn) =
4629107590Sobrien        gen_rtx_EXPR_LIST (REG_EQUAL, mod_equal, REG_NOTES (insn));
4630107590Sobrien
4631107590Sobrien  DONE;
4632132718Skan})
4633107590Sobrien
4634107590Sobrien(define_insn "udivmodtidi3"
4635107590Sobrien  [(set (match_operand:TI 0 "register_operand" "=d,d")
4636169689Skan        (ior:TI
4637169689Skan          (ashift:TI
4638169689Skan            (zero_extend:TI
4639169689Skan              (truncate:DI
4640169689Skan                (umod:TI (match_operand:TI 1 "register_operand" "0,0")
4641169689Skan                         (zero_extend:TI
4642169689Skan                           (match_operand:DI 2 "nonimmediate_operand" "d,m")))))
4643169689Skan            (const_int 64))
4644169689Skan          (zero_extend:TI
4645169689Skan            (truncate:DI
4646169689Skan              (udiv:TI (match_dup 1) (zero_extend:TI (match_dup 2)))))))]
4647107590Sobrien  "TARGET_64BIT"
4648107590Sobrien  "@
4649132718Skan   dlgr\t%0,%2
4650132718Skan   dlg\t%0,%2"
4651132718Skan  [(set_attr "op_type"  "RRE,RXY")
4652132718Skan   (set_attr "type"     "idiv")])
4653107590Sobrien
4654107590Sobrien;
4655107590Sobrien; divmodsi4 instruction pattern(s).
4656107590Sobrien;
4657107590Sobrien
4658107590Sobrien(define_expand "divmodsi4"
4659107590Sobrien  [(parallel [(set (match_operand:SI 0 "general_operand" "")
4660107590Sobrien		   (div:SI (match_operand:SI 1 "general_operand" "")
4661107590Sobrien			   (match_operand:SI 2 "nonimmediate_operand" "")))
4662107590Sobrien	      (set (match_operand:SI 3 "general_operand" "")
4663107590Sobrien		   (mod:SI (match_dup 1) (match_dup 2)))])
4664107590Sobrien   (clobber (match_dup 4))]
4665107590Sobrien  "!TARGET_64BIT"
4666107590Sobrien{
4667107590Sobrien  rtx insn, div_equal, mod_equal, equal;
4668107590Sobrien
4669107590Sobrien  div_equal = gen_rtx_DIV (SImode, operands[1], operands[2]);
4670107590Sobrien  mod_equal = gen_rtx_MOD (SImode, operands[1], operands[2]);
4671107590Sobrien  equal = gen_rtx_IOR (DImode,
4672107590Sobrien		       gen_rtx_ASHIFT (DImode,
4673107590Sobrien				       gen_rtx_ZERO_EXTEND (DImode, mod_equal),
4674169689Skan				       GEN_INT (32)),
4675169689Skan		       gen_rtx_ZERO_EXTEND (DImode, div_equal));
4676107590Sobrien
4677107590Sobrien  operands[4] = gen_reg_rtx(DImode);
4678107590Sobrien  emit_insn (gen_extendsidi2 (operands[4], operands[1]));
4679107590Sobrien  insn = emit_insn (gen_divmoddisi3 (operands[4], operands[4], operands[2]));
4680107590Sobrien  REG_NOTES (insn) =
4681107590Sobrien	gen_rtx_EXPR_LIST (REG_EQUAL, equal, REG_NOTES (insn));
4682107590Sobrien
4683107590Sobrien  insn = emit_move_insn (operands[0], gen_lowpart (SImode, operands[4]));
4684107590Sobrien  REG_NOTES (insn) =
4685107590Sobrien        gen_rtx_EXPR_LIST (REG_EQUAL, div_equal, REG_NOTES (insn));
4686107590Sobrien
4687107590Sobrien  insn = emit_move_insn (operands[3], gen_highpart (SImode, operands[4]));
4688107590Sobrien  REG_NOTES (insn) =
4689107590Sobrien        gen_rtx_EXPR_LIST (REG_EQUAL, mod_equal, REG_NOTES (insn));
4690107590Sobrien
4691107590Sobrien  DONE;
4692132718Skan})
4693107590Sobrien
4694107590Sobrien(define_insn "divmoddisi3"
4695107590Sobrien  [(set (match_operand:DI 0 "register_operand" "=d,d")
4696169689Skan        (ior:DI
4697169689Skan          (ashift:DI
4698169689Skan            (zero_extend:DI
4699169689Skan              (truncate:SI
4700169689Skan                (mod:DI (match_operand:DI 1 "register_operand" "0,0")
4701169689Skan                        (sign_extend:DI
4702169689Skan                          (match_operand:SI 2 "nonimmediate_operand" "d,R")))))
4703169689Skan            (const_int 32))
4704169689Skan          (zero_extend:DI
4705169689Skan            (truncate:SI
4706169689Skan              (div:DI (match_dup 1) (sign_extend:DI (match_dup 2)))))))]
4707107590Sobrien  "!TARGET_64BIT"
4708107590Sobrien  "@
4709132718Skan   dr\t%0,%2
4710132718Skan   d\t%0,%2"
4711107590Sobrien  [(set_attr "op_type"  "RR,RX")
4712132718Skan   (set_attr "type"     "idiv")])
4713107590Sobrien
4714107590Sobrien;
4715107590Sobrien; udivsi3 and umodsi3 instruction pattern(s).
4716107590Sobrien;
4717107590Sobrien
4718132718Skan(define_expand "udivmodsi4"
4719132718Skan  [(parallel [(set (match_operand:SI 0 "general_operand" "")
4720132718Skan		   (udiv:SI (match_operand:SI 1 "general_operand" "")
4721132718Skan			    (match_operand:SI 2 "nonimmediate_operand" "")))
4722132718Skan	      (set (match_operand:SI 3 "general_operand" "")
4723132718Skan		   (umod:SI (match_dup 1) (match_dup 2)))])
4724132718Skan   (clobber (match_dup 4))]
4725132718Skan  "!TARGET_64BIT && TARGET_CPU_ZARCH"
4726132718Skan{
4727132718Skan  rtx insn, div_equal, mod_equal, equal;
4728107590Sobrien
4729132718Skan  div_equal = gen_rtx_UDIV (SImode, operands[1], operands[2]);
4730132718Skan  mod_equal = gen_rtx_UMOD (SImode, operands[1], operands[2]);
4731132718Skan  equal = gen_rtx_IOR (DImode,
4732132718Skan		       gen_rtx_ASHIFT (DImode,
4733132718Skan				       gen_rtx_ZERO_EXTEND (DImode, mod_equal),
4734169689Skan				       GEN_INT (32)),
4735169689Skan		       gen_rtx_ZERO_EXTEND (DImode, div_equal));
4736132718Skan
4737132718Skan  operands[4] = gen_reg_rtx(DImode);
4738132718Skan  emit_insn (gen_rtx_CLOBBER (VOIDmode, operands[4]));
4739132718Skan  emit_move_insn (gen_lowpart (SImode, operands[4]), operands[1]);
4740132718Skan  emit_move_insn (gen_highpart (SImode, operands[4]), const0_rtx);
4741132718Skan  insn = emit_insn (gen_udivmoddisi3 (operands[4], operands[4], operands[2]));
4742132718Skan  REG_NOTES (insn) =
4743132718Skan	gen_rtx_EXPR_LIST (REG_EQUAL, equal, REG_NOTES (insn));
4744132718Skan
4745132718Skan  insn = emit_move_insn (operands[0], gen_lowpart (SImode, operands[4]));
4746132718Skan  REG_NOTES (insn) =
4747132718Skan        gen_rtx_EXPR_LIST (REG_EQUAL, div_equal, REG_NOTES (insn));
4748132718Skan
4749132718Skan  insn = emit_move_insn (operands[3], gen_highpart (SImode, operands[4]));
4750132718Skan  REG_NOTES (insn) =
4751132718Skan        gen_rtx_EXPR_LIST (REG_EQUAL, mod_equal, REG_NOTES (insn));
4752132718Skan
4753132718Skan  DONE;
4754132718Skan})
4755132718Skan
4756132718Skan(define_insn "udivmoddisi3"
4757132718Skan  [(set (match_operand:DI 0 "register_operand" "=d,d")
4758169689Skan        (ior:DI
4759169689Skan          (ashift:DI
4760169689Skan            (zero_extend:DI
4761169689Skan              (truncate:SI
4762169689Skan                (umod:DI (match_operand:DI 1 "register_operand" "0,0")
4763169689Skan                         (zero_extend:DI
4764169689Skan                           (match_operand:SI 2 "nonimmediate_operand" "d,m")))))
4765169689Skan            (const_int 32))
4766169689Skan          (zero_extend:DI
4767169689Skan            (truncate:SI
4768169689Skan              (udiv:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))))]
4769132718Skan  "!TARGET_64BIT && TARGET_CPU_ZARCH"
4770132718Skan  "@
4771132718Skan   dlr\t%0,%2
4772132718Skan   dl\t%0,%2"
4773132718Skan  [(set_attr "op_type"  "RRE,RXY")
4774132718Skan   (set_attr "type"     "idiv")])
4775132718Skan
4776107590Sobrien(define_expand "udivsi3"
4777107590Sobrien  [(set (match_operand:SI 0 "register_operand" "=d")
4778107590Sobrien        (udiv:SI (match_operand:SI 1 "general_operand" "")
4779107590Sobrien                 (match_operand:SI 2 "general_operand" "")))
4780107590Sobrien   (clobber (match_dup 3))]
4781132718Skan  "!TARGET_64BIT && !TARGET_CPU_ZARCH"
4782107590Sobrien{
4783107590Sobrien  rtx insn, udiv_equal, umod_equal, equal;
4784107590Sobrien
4785107590Sobrien  udiv_equal = gen_rtx_UDIV (SImode, operands[1], operands[2]);
4786107590Sobrien  umod_equal = gen_rtx_UMOD (SImode, operands[1], operands[2]);
4787107590Sobrien  equal = gen_rtx_IOR (DImode,
4788107590Sobrien		       gen_rtx_ASHIFT (DImode,
4789107590Sobrien				       gen_rtx_ZERO_EXTEND (DImode, umod_equal),
4790169689Skan				       GEN_INT (32)),
4791169689Skan		       gen_rtx_ZERO_EXTEND (DImode, udiv_equal));
4792107590Sobrien
4793107590Sobrien  operands[3] = gen_reg_rtx (DImode);
4794107590Sobrien
4795107590Sobrien  if (CONSTANT_P (operands[2]))
4796107590Sobrien    {
4797107590Sobrien      if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0)
4798107590Sobrien        {
4799107590Sobrien          rtx label1 = gen_label_rtx ();
4800107590Sobrien
4801107590Sobrien	  operands[1] = make_safe_from (operands[1], operands[0]);
4802107590Sobrien          emit_move_insn (operands[0], const0_rtx);
4803107590Sobrien          emit_insn (gen_cmpsi (operands[1], operands[2]));
4804107590Sobrien          emit_jump_insn (gen_bltu (label1));
4805107590Sobrien          emit_move_insn (operands[0], const1_rtx);
4806107590Sobrien          emit_label (label1);
4807107590Sobrien        }
4808107590Sobrien      else
4809107590Sobrien        {
4810132718Skan          operands[2] = force_reg (SImode, operands[2]);
4811132718Skan          operands[2] = make_safe_from (operands[2], operands[0]);
4812107590Sobrien
4813107590Sobrien	  emit_insn (gen_zero_extendsidi2 (operands[3], operands[1]));
4814107590Sobrien	  insn = emit_insn (gen_divmoddisi3 (operands[3], operands[3],
4815107590Sobrien					     operands[2]));
4816107590Sobrien	  REG_NOTES (insn) =
4817107590Sobrien	    gen_rtx_EXPR_LIST (REG_EQUAL, equal, REG_NOTES (insn));
4818132718Skan
4819132718Skan	  insn = emit_move_insn (operands[0],
4820107590Sobrien				 gen_lowpart (SImode, operands[3]));
4821107590Sobrien	  REG_NOTES (insn) =
4822132718Skan	    gen_rtx_EXPR_LIST (REG_EQUAL,
4823107590Sobrien			       udiv_equal, REG_NOTES (insn));
4824107590Sobrien        }
4825107590Sobrien    }
4826107590Sobrien  else
4827132718Skan    {
4828107590Sobrien      rtx label1 = gen_label_rtx ();
4829107590Sobrien      rtx label2 = gen_label_rtx ();
4830107590Sobrien      rtx label3 = gen_label_rtx ();
4831107590Sobrien
4832132718Skan      operands[1] = force_reg (SImode, operands[1]);
4833132718Skan      operands[1] = make_safe_from (operands[1], operands[0]);
4834132718Skan      operands[2] = force_reg (SImode, operands[2]);
4835132718Skan      operands[2] = make_safe_from (operands[2], operands[0]);
4836107590Sobrien
4837107590Sobrien      emit_move_insn (operands[0], const0_rtx);
4838107590Sobrien      emit_insn (gen_cmpsi (operands[2], operands[1]));
4839107590Sobrien      emit_jump_insn (gen_bgtu (label3));
4840169689Skan      emit_insn (gen_cmpsi (operands[2], const0_rtx));
4841107590Sobrien      emit_jump_insn (gen_blt (label2));
4842107590Sobrien      emit_insn (gen_cmpsi (operands[2], const1_rtx));
4843107590Sobrien      emit_jump_insn (gen_beq (label1));
4844107590Sobrien      emit_insn (gen_zero_extendsidi2 (operands[3], operands[1]));
4845107590Sobrien      insn = emit_insn (gen_divmoddisi3 (operands[3], operands[3],
4846107590Sobrien					 operands[2]));
4847107590Sobrien      REG_NOTES (insn) =
4848107590Sobrien      gen_rtx_EXPR_LIST (REG_EQUAL, equal, REG_NOTES (insn));
4849132718Skan
4850132718Skan      insn = emit_move_insn (operands[0],
4851107590Sobrien			     gen_lowpart (SImode, operands[3]));
4852107590Sobrien      REG_NOTES (insn) =
4853132718Skan      gen_rtx_EXPR_LIST (REG_EQUAL,
4854107590Sobrien			       udiv_equal, REG_NOTES (insn));
4855107590Sobrien      emit_jump (label3);
4856107590Sobrien      emit_label (label1);
4857107590Sobrien      emit_move_insn (operands[0], operands[1]);
4858107590Sobrien      emit_jump (label3);
4859107590Sobrien      emit_label (label2);
4860107590Sobrien      emit_move_insn (operands[0], const1_rtx);
4861107590Sobrien      emit_label (label3);
4862107590Sobrien    }
4863132718Skan  emit_move_insn (operands[0], operands[0]);
4864107590Sobrien  DONE;
4865132718Skan})
4866107590Sobrien
4867107590Sobrien(define_expand "umodsi3"
4868107590Sobrien  [(set (match_operand:SI 0 "register_operand" "=d")
4869107590Sobrien        (umod:SI (match_operand:SI 1 "nonimmediate_operand" "")
4870107590Sobrien                 (match_operand:SI 2 "nonimmediate_operand" "")))
4871107590Sobrien   (clobber (match_dup 3))]
4872132718Skan  "!TARGET_64BIT && !TARGET_CPU_ZARCH"
4873107590Sobrien{
4874107590Sobrien  rtx insn, udiv_equal, umod_equal, equal;
4875107590Sobrien
4876107590Sobrien  udiv_equal = gen_rtx_UDIV (SImode, operands[1], operands[2]);
4877107590Sobrien  umod_equal = gen_rtx_UMOD (SImode, operands[1], operands[2]);
4878107590Sobrien  equal = gen_rtx_IOR (DImode,
4879107590Sobrien		       gen_rtx_ASHIFT (DImode,
4880107590Sobrien				       gen_rtx_ZERO_EXTEND (DImode, umod_equal),
4881169689Skan				       GEN_INT (32)),
4882169689Skan		       gen_rtx_ZERO_EXTEND (DImode, udiv_equal));
4883107590Sobrien
4884107590Sobrien  operands[3] = gen_reg_rtx (DImode);
4885107590Sobrien
4886107590Sobrien  if (CONSTANT_P (operands[2]))
4887107590Sobrien    {
4888107590Sobrien      if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) <= 0)
4889107590Sobrien        {
4890107590Sobrien          rtx label1 = gen_label_rtx ();
4891107590Sobrien
4892107590Sobrien          operands[1] = make_safe_from (operands[1], operands[0]);
4893107590Sobrien	  emit_move_insn (operands[0], operands[1]);
4894107590Sobrien          emit_insn (gen_cmpsi (operands[0], operands[2]));
4895107590Sobrien          emit_jump_insn (gen_bltu (label1));
4896107590Sobrien	  emit_insn (gen_abssi2 (operands[0], operands[2]));
4897107590Sobrien          emit_insn (gen_addsi3 (operands[0], operands[0], operands[1]));
4898107590Sobrien          emit_label (label1);
4899107590Sobrien        }
4900107590Sobrien      else
4901107590Sobrien        {
4902132718Skan          operands[2] = force_reg (SImode, operands[2]);
4903132718Skan          operands[2] = make_safe_from (operands[2], operands[0]);
4904107590Sobrien
4905107590Sobrien	  emit_insn (gen_zero_extendsidi2 (operands[3], operands[1]));
4906107590Sobrien	  insn = emit_insn (gen_divmoddisi3 (operands[3], operands[3],
4907107590Sobrien					     operands[2]));
4908107590Sobrien	  REG_NOTES (insn) =
4909107590Sobrien	    gen_rtx_EXPR_LIST (REG_EQUAL, equal, REG_NOTES (insn));
4910132718Skan
4911132718Skan	  insn = emit_move_insn (operands[0],
4912107590Sobrien				 gen_highpart (SImode, operands[3]));
4913107590Sobrien	  REG_NOTES (insn) =
4914132718Skan	    gen_rtx_EXPR_LIST (REG_EQUAL,
4915107590Sobrien			       umod_equal, REG_NOTES (insn));
4916107590Sobrien        }
4917107590Sobrien    }
4918107590Sobrien  else
4919107590Sobrien    {
4920107590Sobrien      rtx label1 = gen_label_rtx ();
4921107590Sobrien      rtx label2 = gen_label_rtx ();
4922107590Sobrien      rtx label3 = gen_label_rtx ();
4923107590Sobrien
4924132718Skan      operands[1] = force_reg (SImode, operands[1]);
4925132718Skan      operands[1] = make_safe_from (operands[1], operands[0]);
4926132718Skan      operands[2] = force_reg (SImode, operands[2]);
4927132718Skan      operands[2] = make_safe_from (operands[2], operands[0]);
4928107590Sobrien
4929132718Skan      emit_move_insn(operands[0], operands[1]);
4930107590Sobrien      emit_insn (gen_cmpsi (operands[2], operands[1]));
4931107590Sobrien      emit_jump_insn (gen_bgtu (label3));
4932169689Skan      emit_insn (gen_cmpsi (operands[2], const0_rtx));
4933107590Sobrien      emit_jump_insn (gen_blt (label2));
4934107590Sobrien      emit_insn (gen_cmpsi (operands[2], const1_rtx));
4935107590Sobrien      emit_jump_insn (gen_beq (label1));
4936107590Sobrien      emit_insn (gen_zero_extendsidi2 (operands[3], operands[1]));
4937107590Sobrien      insn = emit_insn (gen_divmoddisi3 (operands[3], operands[3],
4938107590Sobrien					 operands[2]));
4939107590Sobrien      REG_NOTES (insn) =
4940107590Sobrien      gen_rtx_EXPR_LIST (REG_EQUAL, equal, REG_NOTES (insn));
4941132718Skan
4942132718Skan      insn = emit_move_insn (operands[0],
4943107590Sobrien			     gen_highpart (SImode, operands[3]));
4944107590Sobrien      REG_NOTES (insn) =
4945132718Skan      gen_rtx_EXPR_LIST (REG_EQUAL,
4946107590Sobrien			 umod_equal, REG_NOTES (insn));
4947107590Sobrien      emit_jump (label3);
4948107590Sobrien      emit_label (label1);
4949107590Sobrien      emit_move_insn (operands[0], const0_rtx);
4950107590Sobrien      emit_jump (label3);
4951107590Sobrien      emit_label (label2);
4952107590Sobrien      emit_insn (gen_subsi3 (operands[0], operands[0], operands[2]));
4953107590Sobrien      emit_label (label3);
4954107590Sobrien    }
4955107590Sobrien  DONE;
4956132718Skan})
4957107590Sobrien
4958107590Sobrien;
4959169689Skan; div(df|sf)3 instruction pattern(s).
4960107590Sobrien;
4961107590Sobrien
4962169689Skan(define_expand "div<mode>3"
4963169689Skan  [(set (match_operand:FPR 0 "register_operand" "=f,f")
4964169689Skan        (div:FPR (match_operand:FPR 1 "register_operand" "0,0")
4965169689Skan                 (match_operand:FPR 2 "general_operand" "f,<Rf>")))]
4966107590Sobrien  "TARGET_HARD_FLOAT"
4967107590Sobrien  "")
4968107590Sobrien
4969169689Skan; dxbr, ddbr, debr, dxb, ddb, deb
4970169689Skan(define_insn "*div<mode>3"
4971169689Skan  [(set (match_operand:FPR 0 "register_operand" "=f,f")
4972169689Skan        (div:FPR (match_operand:FPR 1 "register_operand" "0,0")
4973169689Skan                 (match_operand:FPR 2 "general_operand" "f,<Rf>")))]
4974107590Sobrien  "TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT"
4975107590Sobrien  "@
4976169689Skan   d<xde>br\t%0,%2
4977169689Skan   d<xde>b\t%0,%2"
4978107590Sobrien  [(set_attr "op_type"  "RRE,RXE")
4979169689Skan   (set_attr "type"     "fdiv<mode>")])
4980107590Sobrien
4981169689Skan; dxr, ddr, der, dx, dd, de
4982169689Skan(define_insn "*div<mode>3_ibm"
4983169689Skan  [(set (match_operand:FPR 0 "register_operand" "=f,f")
4984169689Skan        (div:FPR (match_operand:FPR 1 "register_operand" "0,0")
4985169689Skan                 (match_operand:FPR 2 "general_operand" "f,<Rf>")))]
4986107590Sobrien  "TARGET_HARD_FLOAT && TARGET_IBM_FLOAT"
4987107590Sobrien  "@
4988169689Skan   d<xde>r\t%0,%2
4989169689Skan   d<xde>\t%0,%2"
4990169689Skan  [(set_attr "op_type"  "<RRe>,<RXe>")
4991169689Skan   (set_attr "type"     "fdiv<mode>")])
4992107590Sobrien
4993107590Sobrien
4994107590Sobrien;;
4995107590Sobrien;;- And instructions.
4996107590Sobrien;;
4997107590Sobrien
4998169689Skan(define_expand "and<mode>3"
4999169689Skan  [(set (match_operand:INT 0 "nonimmediate_operand" "")
5000169689Skan        (and:INT (match_operand:INT 1 "nonimmediate_operand" "")
5001169689Skan                 (match_operand:INT 2 "general_operand" "")))
5002169689Skan   (clobber (reg:CC CC_REGNUM))]
5003169689Skan  ""
5004169689Skan  "s390_expand_logical_operator (AND, <MODE>mode, operands); DONE;")
5005169689Skan
5006107590Sobrien;
5007107590Sobrien; anddi3 instruction pattern(s).
5008107590Sobrien;
5009107590Sobrien
5010107590Sobrien(define_insn "*anddi3_cc"
5011169689Skan  [(set (reg CC_REGNUM)
5012117395Skan        (compare (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
5013107590Sobrien                         (match_operand:DI 2 "general_operand" "d,m"))
5014107590Sobrien                 (const_int 0)))
5015107590Sobrien   (set (match_operand:DI 0 "register_operand" "=d,d")
5016107590Sobrien        (and:DI (match_dup 1) (match_dup 2)))]
5017107590Sobrien  "s390_match_ccmode(insn, CCTmode) && TARGET_64BIT"
5018107590Sobrien  "@
5019132718Skan   ngr\t%0,%2
5020132718Skan   ng\t%0,%2"
5021132718Skan  [(set_attr "op_type"  "RRE,RXY")])
5022107590Sobrien
5023107590Sobrien(define_insn "*anddi3_cconly"
5024169689Skan  [(set (reg CC_REGNUM)
5025117395Skan        (compare (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
5026107590Sobrien                         (match_operand:DI 2 "general_operand" "d,m"))
5027107590Sobrien                 (const_int 0)))
5028107590Sobrien   (clobber (match_scratch:DI 0 "=d,d"))]
5029169689Skan  "s390_match_ccmode(insn, CCTmode) && TARGET_64BIT
5030169689Skan   /* Do not steal TM patterns.  */
5031169689Skan   && s390_single_part (operands[2], DImode, HImode, 0) < 0"
5032107590Sobrien  "@
5033132718Skan   ngr\t%0,%2
5034132718Skan   ng\t%0,%2"
5035132718Skan  [(set_attr "op_type"  "RRE,RXY")])
5036107590Sobrien
5037169689Skan(define_insn "*anddi3_extimm"
5038169689Skan  [(set (match_operand:DI 0 "nonimmediate_operand" "=d,d,d,d,d,d,d,d,d,d,AQ,Q")
5039169689Skan        (and:DI (match_operand:DI 1 "nonimmediate_operand"
5040169689Skan                                    "%d,o,0,0,0,0,0,0,0,0,0,0")
5041169689Skan                (match_operand:DI 2 "general_operand"
5042169689Skan                                    "M,M,N0HDF,N1HDF,N2HDF,N3HDF,N0SDF,N1SDF,d,m,NxQDF,Q")))
5043169689Skan   (clobber (reg:CC CC_REGNUM))]
5044169689Skan  "TARGET_64BIT && TARGET_EXTIMM && s390_logical_operator_ok_p (operands)"
5045169689Skan  "@
5046169689Skan   #
5047169689Skan   #
5048169689Skan   nihh\t%0,%j2
5049169689Skan   nihl\t%0,%j2
5050169689Skan   nilh\t%0,%j2
5051169689Skan   nill\t%0,%j2
5052169689Skan   nihf\t%0,%m2
5053169689Skan   nilf\t%0,%m2
5054169689Skan   ngr\t%0,%2
5055169689Skan   ng\t%0,%2
5056169689Skan   #
5057169689Skan   #"
5058169689Skan  [(set_attr "op_type" "RRE,RXE,RI,RI,RI,RI,RIL,RIL,RRE,RXY,SI,SS")])
5059107590Sobrien
5060169689Skan(define_insn "*anddi3"
5061169689Skan  [(set (match_operand:DI 0 "nonimmediate_operand" "=d,d,d,d,d,d,d,d,AQ,Q")
5062169689Skan        (and:DI (match_operand:DI 1 "nonimmediate_operand"
5063169689Skan                                    "%d,o,0,0,0,0,0,0,0,0")
5064169689Skan                (match_operand:DI 2 "general_operand"
5065169689Skan                                    "M,M,N0HDF,N1HDF,N2HDF,N3HDF,d,m,NxQDF,Q")))
5066169689Skan   (clobber (reg:CC CC_REGNUM))]
5067169689Skan  "TARGET_64BIT && !TARGET_EXTIMM && s390_logical_operator_ok_p (operands)"
5068169689Skan  "@
5069169689Skan   #
5070169689Skan   #
5071169689Skan   nihh\t%0,%j2
5072169689Skan   nihl\t%0,%j2
5073169689Skan   nilh\t%0,%j2
5074169689Skan   nill\t%0,%j2
5075169689Skan   ngr\t%0,%2
5076169689Skan   ng\t%0,%2
5077169689Skan   #
5078169689Skan   #"
5079169689Skan  [(set_attr "op_type" "RRE,RXE,RI,RI,RI,RI,RRE,RXY,SI,SS")])
5080107590Sobrien
5081169689Skan(define_split
5082169689Skan  [(set (match_operand:DI 0 "s_operand" "")
5083169689Skan        (and:DI (match_dup 0) (match_operand:DI 1 "immediate_operand" "")))
5084169689Skan   (clobber (reg:CC CC_REGNUM))]
5085169689Skan  "reload_completed"
5086169689Skan  [(parallel
5087169689Skan    [(set (match_dup 0) (and:QI (match_dup 0) (match_dup 1)))
5088169689Skan     (clobber (reg:CC CC_REGNUM))])]
5089169689Skan  "s390_narrow_logical_operator (AND, &operands[0], &operands[1]);")
5090107590Sobrien
5091169689Skan
5092107590Sobrien;
5093107590Sobrien; andsi3 instruction pattern(s).
5094107590Sobrien;
5095107590Sobrien
5096107590Sobrien(define_insn "*andsi3_cc"
5097169689Skan  [(set (reg CC_REGNUM)
5098169689Skan        (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,0,0")
5099169689Skan                         (match_operand:SI 2 "general_operand" "Os,d,R,T"))
5100107590Sobrien                 (const_int 0)))
5101169689Skan   (set (match_operand:SI 0 "register_operand" "=d,d,d,d")
5102107590Sobrien        (and:SI (match_dup 1) (match_dup 2)))]
5103107590Sobrien  "s390_match_ccmode(insn, CCTmode)"
5104107590Sobrien  "@
5105169689Skan   nilf\t%0,%o2
5106132718Skan   nr\t%0,%2
5107132718Skan   n\t%0,%2
5108132718Skan   ny\t%0,%2"
5109169689Skan  [(set_attr "op_type"  "RIL,RR,RX,RXY")])
5110107590Sobrien
5111107590Sobrien(define_insn "*andsi3_cconly"
5112169689Skan  [(set (reg CC_REGNUM)
5113169689Skan        (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,0,0")
5114169689Skan                         (match_operand:SI 2 "general_operand" "Os,d,R,T"))
5115107590Sobrien                 (const_int 0)))
5116169689Skan   (clobber (match_scratch:SI 0 "=d,d,d,d"))]
5117169689Skan  "s390_match_ccmode(insn, CCTmode)
5118169689Skan   /* Do not steal TM patterns.  */
5119169689Skan   && s390_single_part (operands[2], SImode, HImode, 0) < 0"
5120107590Sobrien  "@
5121169689Skan   nilf\t%0,%o2
5122132718Skan   nr\t%0,%2
5123132718Skan   n\t%0,%2
5124132718Skan   ny\t%0,%2"
5125169689Skan  [(set_attr "op_type"  "RIL,RR,RX,RXY")])
5126107590Sobrien
5127132718Skan(define_insn "*andsi3_zarch"
5128169689Skan  [(set (match_operand:SI 0 "nonimmediate_operand" "=d,d,d,d,d,d,d,d,AQ,Q")
5129169689Skan        (and:SI (match_operand:SI 1 "nonimmediate_operand"
5130169689Skan				    "%d,o,0,0,0,0,0,0,0,0")
5131169689Skan                (match_operand:SI 2 "general_operand"
5132169689Skan				    "M,M,N0HSF,N1HSF,Os,d,R,T,NxQSF,Q")))
5133169689Skan   (clobber (reg:CC CC_REGNUM))]
5134169689Skan  "TARGET_ZARCH && s390_logical_operator_ok_p (operands)"
5135132718Skan  "@
5136132718Skan   #
5137132718Skan   #
5138132718Skan   nilh\t%0,%j2
5139169689Skan   nill\t%0,%j2
5140169689Skan   nilf\t%0,%o2
5141132718Skan   nr\t%0,%2
5142132718Skan   n\t%0,%2
5143169689Skan   ny\t%0,%2
5144169689Skan   #
5145169689Skan   #"
5146169689Skan  [(set_attr "op_type"  "RRE,RXE,RI,RI,RIL,RR,RX,RXY,SI,SS")])
5147107590Sobrien
5148132718Skan(define_insn "*andsi3_esa"
5149169689Skan  [(set (match_operand:SI 0 "nonimmediate_operand" "=d,d,AQ,Q")
5150169689Skan        (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,0,0")
5151169689Skan                (match_operand:SI 2 "general_operand" "d,R,NxQSF,Q")))
5152169689Skan   (clobber (reg:CC CC_REGNUM))]
5153169689Skan  "!TARGET_ZARCH && s390_logical_operator_ok_p (operands)"
5154107590Sobrien  "@
5155132718Skan   nr\t%0,%2
5156169689Skan   n\t%0,%2
5157169689Skan   #
5158169689Skan   #"
5159169689Skan  [(set_attr "op_type"  "RR,RX,SI,SS")])
5160107590Sobrien
5161169689Skan(define_split
5162169689Skan  [(set (match_operand:SI 0 "s_operand" "")
5163169689Skan        (and:SI (match_dup 0) (match_operand:SI 1 "immediate_operand" "")))
5164169689Skan   (clobber (reg:CC CC_REGNUM))]
5165169689Skan  "reload_completed"
5166169689Skan  [(parallel
5167169689Skan    [(set (match_dup 0) (and:QI (match_dup 0) (match_dup 1)))
5168169689Skan     (clobber (reg:CC CC_REGNUM))])]
5169169689Skan  "s390_narrow_logical_operator (AND, &operands[0], &operands[1]);")
5170107590Sobrien
5171107590Sobrien;
5172107590Sobrien; andhi3 instruction pattern(s).
5173107590Sobrien;
5174107590Sobrien
5175169689Skan(define_insn "*andhi3_zarch"
5176169689Skan  [(set (match_operand:HI 0 "nonimmediate_operand" "=d,d,AQ,Q")
5177169689Skan        (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,0,0")
5178169689Skan                (match_operand:HI 2 "general_operand" "d,n,NxQHF,Q")))
5179169689Skan   (clobber (reg:CC CC_REGNUM))]
5180169689Skan  "TARGET_ZARCH && s390_logical_operator_ok_p (operands)"
5181107590Sobrien  "@
5182132718Skan   nr\t%0,%2
5183169689Skan   nill\t%0,%x2
5184169689Skan   #
5185169689Skan   #"
5186169689Skan  [(set_attr "op_type"  "RR,RI,SI,SS")])
5187107590Sobrien
5188169689Skan(define_insn "*andhi3_esa"
5189169689Skan  [(set (match_operand:HI 0 "nonimmediate_operand" "=d,AQ,Q")
5190169689Skan        (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,0")
5191169689Skan                (match_operand:HI 2 "general_operand" "d,NxQHF,Q")))
5192169689Skan   (clobber (reg:CC CC_REGNUM))]
5193169689Skan  "!TARGET_ZARCH && s390_logical_operator_ok_p (operands)"
5194169689Skan  "@
5195169689Skan   nr\t%0,%2
5196169689Skan   #
5197169689Skan   #"
5198169689Skan  [(set_attr "op_type"  "RR,SI,SS")])
5199107590Sobrien
5200169689Skan(define_split
5201169689Skan  [(set (match_operand:HI 0 "s_operand" "")
5202169689Skan        (and:HI (match_dup 0) (match_operand:HI 1 "immediate_operand" "")))
5203169689Skan   (clobber (reg:CC CC_REGNUM))]
5204169689Skan  "reload_completed"
5205169689Skan  [(parallel
5206169689Skan    [(set (match_dup 0) (and:QI (match_dup 0) (match_dup 1)))
5207169689Skan     (clobber (reg:CC CC_REGNUM))])]
5208169689Skan  "s390_narrow_logical_operator (AND, &operands[0], &operands[1]);")
5209107590Sobrien
5210107590Sobrien;
5211107590Sobrien; andqi3 instruction pattern(s).
5212107590Sobrien;
5213107590Sobrien
5214169689Skan(define_insn "*andqi3_zarch"
5215169689Skan  [(set (match_operand:QI 0 "nonimmediate_operand" "=d,d,Q,S,Q")
5216169689Skan        (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,0,0")
5217169689Skan                (match_operand:QI 2 "general_operand" "d,n,n,n,Q")))
5218169689Skan   (clobber (reg:CC CC_REGNUM))]
5219169689Skan  "TARGET_ZARCH && s390_logical_operator_ok_p (operands)"
5220107590Sobrien  "@
5221132718Skan   nr\t%0,%2
5222169689Skan   nill\t%0,%b2
5223169689Skan   ni\t%S0,%b2
5224169689Skan   niy\t%S0,%b2
5225169689Skan   #"
5226169689Skan  [(set_attr "op_type"  "RR,RI,SI,SIY,SS")])
5227107590Sobrien
5228169689Skan(define_insn "*andqi3_esa"
5229169689Skan  [(set (match_operand:QI 0 "nonimmediate_operand" "=d,Q,Q")
5230169689Skan        (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
5231169689Skan                (match_operand:QI 2 "general_operand" "d,n,Q")))
5232169689Skan   (clobber (reg:CC CC_REGNUM))]
5233169689Skan  "!TARGET_ZARCH && s390_logical_operator_ok_p (operands)"
5234107590Sobrien  "@
5235169689Skan   nr\t%0,%2
5236169689Skan   ni\t%S0,%b2
5237169689Skan   #"
5238169689Skan  [(set_attr "op_type"  "RR,SI,SS")])
5239107590Sobrien
5240169689Skan;
5241169689Skan; Block and (NC) patterns.
5242169689Skan;
5243107590Sobrien
5244169689Skan(define_insn "*nc"
5245169689Skan  [(set (match_operand:BLK 0 "memory_operand" "=Q")
5246169689Skan        (and:BLK (match_dup 0)
5247169689Skan                 (match_operand:BLK 1 "memory_operand" "Q")))
5248169689Skan   (use (match_operand 2 "const_int_operand" "n"))
5249169689Skan   (clobber (reg:CC CC_REGNUM))]
5250169689Skan  "INTVAL (operands[2]) >= 1 && INTVAL (operands[2]) <= 256"
5251169689Skan  "nc\t%O0(%2,%R0),%S1"
5252169689Skan  [(set_attr "op_type" "SS")])
5253107590Sobrien
5254169689Skan(define_split
5255169689Skan  [(set (match_operand 0 "memory_operand" "")
5256169689Skan        (and (match_dup 0)
5257169689Skan             (match_operand 1 "memory_operand" "")))
5258169689Skan   (clobber (reg:CC CC_REGNUM))]
5259169689Skan  "reload_completed
5260169689Skan   && GET_MODE (operands[0]) == GET_MODE (operands[1])
5261169689Skan   && GET_MODE_SIZE (GET_MODE (operands[0])) > 0"
5262169689Skan  [(parallel
5263169689Skan    [(set (match_dup 0) (and:BLK (match_dup 0) (match_dup 1)))
5264169689Skan     (use (match_dup 2))
5265169689Skan     (clobber (reg:CC CC_REGNUM))])]
5266169689Skan{
5267169689Skan  operands[2] = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[0])));
5268169689Skan  operands[0] = adjust_address (operands[0], BLKmode, 0);
5269169689Skan  operands[1] = adjust_address (operands[1], BLKmode, 0);
5270169689Skan})
5271169689Skan
5272169689Skan(define_peephole2
5273169689Skan  [(parallel
5274169689Skan    [(set (match_operand:BLK 0 "memory_operand" "")
5275169689Skan          (and:BLK (match_dup 0)
5276169689Skan                   (match_operand:BLK 1 "memory_operand" "")))
5277169689Skan     (use (match_operand 2 "const_int_operand" ""))
5278169689Skan     (clobber (reg:CC CC_REGNUM))])
5279169689Skan   (parallel
5280169689Skan    [(set (match_operand:BLK 3 "memory_operand" "")
5281169689Skan          (and:BLK (match_dup 3)
5282169689Skan                   (match_operand:BLK 4 "memory_operand" "")))
5283169689Skan     (use (match_operand 5 "const_int_operand" ""))
5284169689Skan     (clobber (reg:CC CC_REGNUM))])]
5285169689Skan  "s390_offset_p (operands[0], operands[3], operands[2])
5286169689Skan   && s390_offset_p (operands[1], operands[4], operands[2])
5287169689Skan   && !s390_overlap_p (operands[0], operands[1], 
5288169689Skan                       INTVAL (operands[2]) + INTVAL (operands[5]))
5289169689Skan   && INTVAL (operands[2]) + INTVAL (operands[5]) <= 256"
5290169689Skan  [(parallel
5291169689Skan    [(set (match_dup 6) (and:BLK (match_dup 6) (match_dup 7)))
5292169689Skan     (use (match_dup 8))
5293169689Skan     (clobber (reg:CC CC_REGNUM))])]
5294169689Skan  "operands[6] = gen_rtx_MEM (BLKmode, XEXP (operands[0], 0));
5295169689Skan   operands[7] = gen_rtx_MEM (BLKmode, XEXP (operands[1], 0));
5296169689Skan   operands[8] = GEN_INT (INTVAL (operands[2]) + INTVAL (operands[5]));")
5297169689Skan
5298169689Skan
5299107590Sobrien;;
5300107590Sobrien;;- Bit set (inclusive or) instructions.
5301107590Sobrien;;
5302107590Sobrien
5303169689Skan(define_expand "ior<mode>3"
5304169689Skan  [(set (match_operand:INT 0 "nonimmediate_operand" "")
5305169689Skan        (ior:INT (match_operand:INT 1 "nonimmediate_operand" "")
5306169689Skan                 (match_operand:INT 2 "general_operand" "")))
5307169689Skan   (clobber (reg:CC CC_REGNUM))]
5308169689Skan  ""
5309169689Skan  "s390_expand_logical_operator (IOR, <MODE>mode, operands); DONE;")
5310169689Skan
5311107590Sobrien;
5312107590Sobrien; iordi3 instruction pattern(s).
5313107590Sobrien;
5314107590Sobrien
5315107590Sobrien(define_insn "*iordi3_cc"
5316169689Skan  [(set (reg CC_REGNUM)
5317117395Skan        (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
5318107590Sobrien                         (match_operand:DI 2 "general_operand" "d,m"))
5319107590Sobrien                 (const_int 0)))
5320107590Sobrien   (set (match_operand:DI 0 "register_operand" "=d,d")
5321107590Sobrien        (ior:DI (match_dup 1) (match_dup 2)))]
5322107590Sobrien  "s390_match_ccmode(insn, CCTmode) && TARGET_64BIT"
5323107590Sobrien  "@
5324132718Skan   ogr\t%0,%2
5325132718Skan   og\t%0,%2"
5326132718Skan  [(set_attr "op_type"  "RRE,RXY")])
5327107590Sobrien
5328107590Sobrien(define_insn "*iordi3_cconly"
5329169689Skan  [(set (reg CC_REGNUM)
5330117395Skan        (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
5331107590Sobrien                         (match_operand:DI 2 "general_operand" "d,m"))
5332107590Sobrien                 (const_int 0)))
5333107590Sobrien   (clobber (match_scratch:DI 0 "=d,d"))]
5334107590Sobrien  "s390_match_ccmode(insn, CCTmode) && TARGET_64BIT"
5335107590Sobrien  "@
5336132718Skan   ogr\t%0,%2
5337132718Skan   og\t%0,%2"
5338132718Skan  [(set_attr "op_type"  "RRE,RXY")])
5339107590Sobrien
5340169689Skan(define_insn "*iordi3_extimm"
5341169689Skan  [(set (match_operand:DI 0 "nonimmediate_operand" "=d,d,d,d,d,d,d,d,AQ,Q")
5342169689Skan        (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,0,0,0,0,0,0,0")
5343169689Skan                (match_operand:DI 2 "general_operand"
5344169689Skan                                    "N0HD0,N1HD0,N2HD0,N3HD0,N0SD0,N1SD0,d,m,NxQD0,Q")))
5345169689Skan   (clobber (reg:CC CC_REGNUM))]
5346169689Skan  "TARGET_64BIT && TARGET_EXTIMM && s390_logical_operator_ok_p (operands)"
5347107590Sobrien  "@
5348132718Skan   oihh\t%0,%i2
5349132718Skan   oihl\t%0,%i2
5350132718Skan   oilh\t%0,%i2
5351132718Skan   oill\t%0,%i2
5352169689Skan   oihf\t%0,%k2
5353169689Skan   oilf\t%0,%k2
5354132718Skan   ogr\t%0,%2
5355169689Skan   og\t%0,%2
5356169689Skan   #
5357169689Skan   #"
5358169689Skan  [(set_attr "op_type"  "RI,RI,RI,RI,RIL,RIL,RRE,RXY,SI,SS")])
5359107590Sobrien
5360169689Skan(define_insn "*iordi3"
5361169689Skan  [(set (match_operand:DI 0 "nonimmediate_operand" "=d,d,d,d,d,d,AQ,Q")
5362169689Skan        (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,0,0,0,0,0")
5363169689Skan                (match_operand:DI 2 "general_operand"
5364169689Skan                                    "N0HD0,N1HD0,N2HD0,N3HD0,d,m,NxQD0,Q")))
5365169689Skan   (clobber (reg:CC CC_REGNUM))]
5366169689Skan  "TARGET_64BIT && !TARGET_EXTIMM && s390_logical_operator_ok_p (operands)"
5367169689Skan  "@
5368169689Skan   oihh\t%0,%i2
5369169689Skan   oihl\t%0,%i2
5370169689Skan   oilh\t%0,%i2
5371169689Skan   oill\t%0,%i2
5372169689Skan   ogr\t%0,%2
5373169689Skan   og\t%0,%2
5374169689Skan   #
5375169689Skan   #"
5376169689Skan  [(set_attr "op_type"  "RI,RI,RI,RI,RRE,RXY,SI,SS")])
5377107590Sobrien
5378169689Skan(define_split
5379169689Skan  [(set (match_operand:DI 0 "s_operand" "")
5380169689Skan        (ior:DI (match_dup 0) (match_operand:DI 1 "immediate_operand" "")))
5381169689Skan   (clobber (reg:CC CC_REGNUM))]
5382169689Skan  "reload_completed"
5383169689Skan  [(parallel
5384169689Skan    [(set (match_dup 0) (ior:QI (match_dup 0) (match_dup 1)))
5385169689Skan     (clobber (reg:CC CC_REGNUM))])]
5386169689Skan  "s390_narrow_logical_operator (IOR, &operands[0], &operands[1]);")
5387107590Sobrien
5388107590Sobrien;
5389107590Sobrien; iorsi3 instruction pattern(s).
5390107590Sobrien;
5391107590Sobrien
5392107590Sobrien(define_insn "*iorsi3_cc"
5393169689Skan  [(set (reg CC_REGNUM)
5394169689Skan        (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,0,0")
5395169689Skan                         (match_operand:SI 2 "general_operand" "Os,d,R,T"))
5396107590Sobrien                 (const_int 0)))
5397169689Skan   (set (match_operand:SI 0 "register_operand" "=d,d,d,d")
5398107590Sobrien        (ior:SI (match_dup 1) (match_dup 2)))]
5399107590Sobrien  "s390_match_ccmode(insn, CCTmode)"
5400107590Sobrien  "@
5401169689Skan   oilf\t%0,%o2
5402132718Skan   or\t%0,%2
5403132718Skan   o\t%0,%2
5404132718Skan   oy\t%0,%2"
5405169689Skan  [(set_attr "op_type"  "RIL,RR,RX,RXY")])
5406107590Sobrien
5407107590Sobrien(define_insn "*iorsi3_cconly"
5408169689Skan  [(set (reg CC_REGNUM)
5409169689Skan        (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,0,0")
5410169689Skan                         (match_operand:SI 2 "general_operand" "Os,d,R,T"))
5411107590Sobrien                 (const_int 0)))
5412169689Skan   (clobber (match_scratch:SI 0 "=d,d,d,d"))]
5413107590Sobrien  "s390_match_ccmode(insn, CCTmode)"
5414107590Sobrien  "@
5415169689Skan   oilf\t%0,%o2
5416132718Skan   or\t%0,%2
5417132718Skan   o\t%0,%2
5418132718Skan   oy\t%0,%2"
5419169689Skan  [(set_attr "op_type"  "RIL,RR,RX,RXY")])
5420107590Sobrien
5421169689Skan(define_insn "*iorsi3_zarch"
5422169689Skan  [(set (match_operand:SI 0 "nonimmediate_operand" "=d,d,d,d,d,d,AQ,Q")
5423169689Skan        (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,0,0,0,0,0,0")
5424169689Skan                (match_operand:SI 2 "general_operand" "N0HS0,N1HS0,Os,d,R,T,NxQS0,Q")))
5425169689Skan   (clobber (reg:CC CC_REGNUM))]
5426169689Skan  "TARGET_ZARCH && s390_logical_operator_ok_p (operands)"
5427132718Skan  "@
5428132718Skan   oilh\t%0,%i2
5429132718Skan   oill\t%0,%i2
5430169689Skan   oilf\t%0,%o2
5431132718Skan   or\t%0,%2
5432132718Skan   o\t%0,%2
5433169689Skan   oy\t%0,%2
5434169689Skan   #
5435169689Skan   #"
5436169689Skan  [(set_attr "op_type"  "RI,RI,RIL,RR,RX,RXY,SI,SS")])
5437107590Sobrien
5438169689Skan(define_insn "*iorsi3_esa"
5439169689Skan  [(set (match_operand:SI 0 "nonimmediate_operand" "=d,d,AQ,Q")
5440169689Skan        (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,0,0")
5441169689Skan                (match_operand:SI 2 "general_operand" "d,R,NxQS0,Q")))
5442169689Skan   (clobber (reg:CC CC_REGNUM))]
5443169689Skan  "!TARGET_ZARCH && s390_logical_operator_ok_p (operands)"
5444107590Sobrien  "@
5445132718Skan   or\t%0,%2
5446169689Skan   o\t%0,%2
5447169689Skan   #
5448169689Skan   #"
5449169689Skan  [(set_attr "op_type"  "RR,RX,SI,SS")])
5450107590Sobrien
5451169689Skan(define_split
5452169689Skan  [(set (match_operand:SI 0 "s_operand" "")
5453169689Skan        (ior:SI (match_dup 0) (match_operand:SI 1 "immediate_operand" "")))
5454169689Skan   (clobber (reg:CC CC_REGNUM))]
5455169689Skan  "reload_completed"
5456169689Skan  [(parallel
5457169689Skan    [(set (match_dup 0) (ior:QI (match_dup 0) (match_dup 1)))
5458169689Skan     (clobber (reg:CC CC_REGNUM))])]
5459169689Skan  "s390_narrow_logical_operator (IOR, &operands[0], &operands[1]);")
5460107590Sobrien
5461107590Sobrien;
5462107590Sobrien; iorhi3 instruction pattern(s).
5463107590Sobrien;
5464107590Sobrien
5465169689Skan(define_insn "*iorhi3_zarch"
5466169689Skan  [(set (match_operand:HI 0 "nonimmediate_operand" "=d,d,AQ,Q")
5467169689Skan        (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,0,0")
5468169689Skan                (match_operand:HI 2 "general_operand" "d,n,NxQH0,Q")))
5469169689Skan   (clobber (reg:CC CC_REGNUM))]
5470169689Skan  "TARGET_ZARCH && s390_logical_operator_ok_p (operands)"
5471107590Sobrien  "@
5472132718Skan   or\t%0,%2
5473169689Skan   oill\t%0,%x2
5474169689Skan   #
5475169689Skan   #"
5476169689Skan  [(set_attr "op_type"  "RR,RI,SI,SS")])
5477107590Sobrien
5478169689Skan(define_insn "*iorhi3_esa"
5479169689Skan  [(set (match_operand:HI 0 "nonimmediate_operand" "=d,AQ,Q")
5480169689Skan        (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,0")
5481169689Skan                (match_operand:HI 2 "general_operand" "d,NxQH0,Q")))
5482169689Skan   (clobber (reg:CC CC_REGNUM))]
5483169689Skan  "!TARGET_ZARCH && s390_logical_operator_ok_p (operands)"
5484169689Skan  "@
5485169689Skan   or\t%0,%2
5486169689Skan   #
5487169689Skan   #"
5488169689Skan  [(set_attr "op_type"  "RR,SI,SS")])
5489107590Sobrien
5490169689Skan(define_split
5491169689Skan  [(set (match_operand:HI 0 "s_operand" "")
5492169689Skan        (ior:HI (match_dup 0) (match_operand:HI 1 "immediate_operand" "")))
5493169689Skan   (clobber (reg:CC CC_REGNUM))]
5494169689Skan  "reload_completed"
5495169689Skan  [(parallel
5496169689Skan    [(set (match_dup 0) (ior:QI (match_dup 0) (match_dup 1)))
5497169689Skan     (clobber (reg:CC CC_REGNUM))])]
5498169689Skan  "s390_narrow_logical_operator (IOR, &operands[0], &operands[1]);")
5499107590Sobrien
5500107590Sobrien;
5501107590Sobrien; iorqi3 instruction pattern(s).
5502107590Sobrien;
5503107590Sobrien
5504169689Skan(define_insn "*iorqi3_zarch"
5505169689Skan  [(set (match_operand:QI 0 "nonimmediate_operand" "=d,d,Q,S,Q")
5506169689Skan        (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,0,0")
5507169689Skan                (match_operand:QI 2 "general_operand" "d,n,n,n,Q")))
5508169689Skan   (clobber (reg:CC CC_REGNUM))]
5509169689Skan  "TARGET_ZARCH && s390_logical_operator_ok_p (operands)"
5510107590Sobrien  "@
5511132718Skan   or\t%0,%2
5512169689Skan   oill\t%0,%b2
5513169689Skan   oi\t%S0,%b2
5514169689Skan   oiy\t%S0,%b2
5515169689Skan   #"
5516169689Skan  [(set_attr "op_type"  "RR,RI,SI,SIY,SS")])
5517107590Sobrien
5518169689Skan(define_insn "*iorqi3_esa"
5519169689Skan  [(set (match_operand:QI 0 "nonimmediate_operand" "=d,Q,Q")
5520169689Skan        (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
5521169689Skan                (match_operand:QI 2 "general_operand" "d,n,Q")))
5522169689Skan   (clobber (reg:CC CC_REGNUM))]
5523169689Skan  "!TARGET_ZARCH && s390_logical_operator_ok_p (operands)"
5524107590Sobrien  "@
5525169689Skan   or\t%0,%2
5526169689Skan   oi\t%S0,%b2
5527169689Skan   #"
5528169689Skan  [(set_attr "op_type"  "RR,SI,SS")])
5529107590Sobrien
5530169689Skan;
5531169689Skan; Block inclusive or (OC) patterns.
5532169689Skan;
5533107590Sobrien
5534169689Skan(define_insn "*oc"
5535169689Skan  [(set (match_operand:BLK 0 "memory_operand" "=Q")
5536169689Skan        (ior:BLK (match_dup 0)
5537169689Skan                 (match_operand:BLK 1 "memory_operand" "Q")))
5538169689Skan   (use (match_operand 2 "const_int_operand" "n"))
5539169689Skan   (clobber (reg:CC CC_REGNUM))]
5540169689Skan  "INTVAL (operands[2]) >= 1 && INTVAL (operands[2]) <= 256"
5541169689Skan  "oc\t%O0(%2,%R0),%S1"
5542169689Skan  [(set_attr "op_type" "SS")])
5543107590Sobrien
5544169689Skan(define_split
5545169689Skan  [(set (match_operand 0 "memory_operand" "")
5546169689Skan        (ior (match_dup 0)
5547169689Skan             (match_operand 1 "memory_operand" "")))
5548169689Skan   (clobber (reg:CC CC_REGNUM))]
5549169689Skan  "reload_completed
5550169689Skan   && GET_MODE (operands[0]) == GET_MODE (operands[1])
5551169689Skan   && GET_MODE_SIZE (GET_MODE (operands[0])) > 0"
5552169689Skan  [(parallel
5553169689Skan    [(set (match_dup 0) (ior:BLK (match_dup 0) (match_dup 1)))
5554169689Skan     (use (match_dup 2))
5555169689Skan     (clobber (reg:CC CC_REGNUM))])]
5556169689Skan{
5557169689Skan  operands[2] = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[0])));
5558169689Skan  operands[0] = adjust_address (operands[0], BLKmode, 0);
5559169689Skan  operands[1] = adjust_address (operands[1], BLKmode, 0);
5560169689Skan})
5561169689Skan
5562169689Skan(define_peephole2
5563169689Skan  [(parallel
5564169689Skan    [(set (match_operand:BLK 0 "memory_operand" "")
5565169689Skan          (ior:BLK (match_dup 0)
5566169689Skan                   (match_operand:BLK 1 "memory_operand" "")))
5567169689Skan     (use (match_operand 2 "const_int_operand" ""))
5568169689Skan     (clobber (reg:CC CC_REGNUM))])
5569169689Skan   (parallel
5570169689Skan    [(set (match_operand:BLK 3 "memory_operand" "")
5571169689Skan          (ior:BLK (match_dup 3)
5572169689Skan                   (match_operand:BLK 4 "memory_operand" "")))
5573169689Skan     (use (match_operand 5 "const_int_operand" ""))
5574169689Skan     (clobber (reg:CC CC_REGNUM))])]
5575169689Skan  "s390_offset_p (operands[0], operands[3], operands[2])
5576169689Skan   && s390_offset_p (operands[1], operands[4], operands[2])
5577169689Skan   && !s390_overlap_p (operands[0], operands[1], 
5578169689Skan                       INTVAL (operands[2]) + INTVAL (operands[5]))
5579169689Skan   && INTVAL (operands[2]) + INTVAL (operands[5]) <= 256"
5580169689Skan  [(parallel
5581169689Skan    [(set (match_dup 6) (ior:BLK (match_dup 6) (match_dup 7)))
5582169689Skan     (use (match_dup 8))
5583169689Skan     (clobber (reg:CC CC_REGNUM))])]
5584169689Skan  "operands[6] = gen_rtx_MEM (BLKmode, XEXP (operands[0], 0));
5585169689Skan   operands[7] = gen_rtx_MEM (BLKmode, XEXP (operands[1], 0));
5586169689Skan   operands[8] = GEN_INT (INTVAL (operands[2]) + INTVAL (operands[5]));")
5587169689Skan
5588169689Skan
5589107590Sobrien;;
5590107590Sobrien;;- Xor instructions.
5591107590Sobrien;;
5592107590Sobrien
5593169689Skan(define_expand "xor<mode>3"
5594169689Skan  [(set (match_operand:INT 0 "nonimmediate_operand" "")
5595169689Skan        (xor:INT (match_operand:INT 1 "nonimmediate_operand" "")
5596169689Skan                 (match_operand:INT 2 "general_operand" "")))
5597169689Skan   (clobber (reg:CC CC_REGNUM))]
5598169689Skan  ""
5599169689Skan  "s390_expand_logical_operator (XOR, <MODE>mode, operands); DONE;")
5600169689Skan
5601107590Sobrien;
5602107590Sobrien; xordi3 instruction pattern(s).
5603107590Sobrien;
5604107590Sobrien
5605107590Sobrien(define_insn "*xordi3_cc"
5606169689Skan  [(set (reg CC_REGNUM)
5607117395Skan        (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
5608107590Sobrien                         (match_operand:DI 2 "general_operand" "d,m"))
5609107590Sobrien                 (const_int 0)))
5610107590Sobrien   (set (match_operand:DI 0 "register_operand" "=d,d")
5611107590Sobrien        (xor:DI (match_dup 1) (match_dup 2)))]
5612107590Sobrien  "s390_match_ccmode(insn, CCTmode) && TARGET_64BIT"
5613107590Sobrien  "@
5614132718Skan   xgr\t%0,%2
5615132718Skan   xg\t%0,%2"
5616132718Skan  [(set_attr "op_type"  "RRE,RXY")])
5617107590Sobrien
5618107590Sobrien(define_insn "*xordi3_cconly"
5619169689Skan  [(set (reg CC_REGNUM)
5620117395Skan        (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
5621107590Sobrien                         (match_operand:DI 2 "general_operand" "d,m"))
5622107590Sobrien                 (const_int 0)))
5623107590Sobrien   (clobber (match_scratch:DI 0 "=d,d"))]
5624107590Sobrien  "s390_match_ccmode(insn, CCTmode) && TARGET_64BIT"
5625107590Sobrien  "@
5626132718Skan   xgr\t%0,%2
5627220150Smm   xg\t%0,%2"
5628132718Skan  [(set_attr "op_type"  "RRE,RXY")])
5629107590Sobrien
5630169689Skan(define_insn "*xordi3_extimm"
5631169689Skan  [(set (match_operand:DI 0 "nonimmediate_operand" "=d,d,d,d,AQ,Q")
5632169689Skan        (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,0,0,0")
5633169689Skan                (match_operand:DI 2 "general_operand" "N0SD0,N1SD0,d,m,NxQD0,Q")))
5634169689Skan   (clobber (reg:CC CC_REGNUM))]
5635169689Skan  "TARGET_64BIT && TARGET_EXTIMM && s390_logical_operator_ok_p (operands)"
5636107590Sobrien  "@
5637169689Skan   xihf\t%0,%k2
5638169689Skan   xilf\t%0,%k2
5639132718Skan   xgr\t%0,%2
5640169689Skan   xg\t%0,%2
5641169689Skan   #
5642169689Skan   #"
5643169689Skan  [(set_attr "op_type"  "RIL,RIL,RRE,RXY,SI,SS")])
5644107590Sobrien
5645169689Skan(define_insn "*xordi3"
5646169689Skan  [(set (match_operand:DI 0 "nonimmediate_operand" "=d,d,AQ,Q")
5647169689Skan        (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,0")
5648169689Skan                (match_operand:DI 2 "general_operand" "d,m,NxQD0,Q")))
5649169689Skan   (clobber (reg:CC CC_REGNUM))]
5650169689Skan  "TARGET_64BIT && !TARGET_EXTIMM && s390_logical_operator_ok_p (operands)"
5651169689Skan  "@
5652169689Skan   xgr\t%0,%2
5653169689Skan   xg\t%0,%2
5654169689Skan   #
5655169689Skan   #"
5656169689Skan  [(set_attr "op_type"  "RRE,RXY,SI,SS")])
5657107590Sobrien
5658169689Skan(define_split
5659169689Skan  [(set (match_operand:DI 0 "s_operand" "")
5660169689Skan        (xor:DI (match_dup 0) (match_operand:DI 1 "immediate_operand" "")))
5661169689Skan   (clobber (reg:CC CC_REGNUM))]
5662169689Skan  "reload_completed"
5663169689Skan  [(parallel
5664169689Skan    [(set (match_dup 0) (xor:QI (match_dup 0) (match_dup 1)))
5665169689Skan     (clobber (reg:CC CC_REGNUM))])]
5666169689Skan  "s390_narrow_logical_operator (XOR, &operands[0], &operands[1]);")
5667107590Sobrien
5668107590Sobrien;
5669107590Sobrien; xorsi3 instruction pattern(s).
5670107590Sobrien;
5671107590Sobrien
5672107590Sobrien(define_insn "*xorsi3_cc"
5673169689Skan  [(set (reg CC_REGNUM)
5674169689Skan        (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,0,0")
5675169689Skan                         (match_operand:SI 2 "general_operand" "Os,d,R,T"))
5676107590Sobrien                 (const_int 0)))
5677169689Skan   (set (match_operand:SI 0 "register_operand" "=d,d,d,d")
5678107590Sobrien        (xor:SI (match_dup 1) (match_dup 2)))]
5679107590Sobrien  "s390_match_ccmode(insn, CCTmode)"
5680107590Sobrien  "@
5681169689Skan   xilf\t%0,%o2
5682132718Skan   xr\t%0,%2
5683132718Skan   x\t%0,%2
5684132718Skan   xy\t%0,%2"
5685169689Skan  [(set_attr "op_type"  "RIL,RR,RX,RXY")])
5686107590Sobrien
5687107590Sobrien(define_insn "*xorsi3_cconly"
5688169689Skan  [(set (reg CC_REGNUM)
5689169689Skan        (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,0,0")
5690169689Skan                         (match_operand:SI 2 "general_operand" "Os,d,R,T"))
5691107590Sobrien                 (const_int 0)))
5692169689Skan   (clobber (match_scratch:SI 0 "=d,d,d,d"))]
5693107590Sobrien  "s390_match_ccmode(insn, CCTmode)"
5694107590Sobrien  "@
5695169689Skan   xilf\t%0,%o2
5696132718Skan   xr\t%0,%2
5697132718Skan   x\t%0,%2
5698132718Skan   xy\t%0,%2"
5699169689Skan  [(set_attr "op_type"  "RIL,RR,RX,RXY")])
5700107590Sobrien
5701169689Skan(define_insn "*xorsi3"
5702169689Skan  [(set (match_operand:SI 0 "nonimmediate_operand" "=d,d,d,d,AQ,Q")
5703169689Skan        (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,0,0,0,0")
5704169689Skan                (match_operand:SI 2 "general_operand" "Os,d,R,T,NxQS0,Q")))
5705169689Skan   (clobber (reg:CC CC_REGNUM))]
5706169689Skan  "s390_logical_operator_ok_p (operands)"
5707107590Sobrien  "@
5708169689Skan   xilf\t%0,%o2
5709132718Skan   xr\t%0,%2
5710132718Skan   x\t%0,%2
5711169689Skan   xy\t%0,%2
5712169689Skan   #
5713169689Skan   #"
5714169689Skan  [(set_attr "op_type"  "RIL,RR,RX,RXY,SI,SS")])
5715107590Sobrien
5716169689Skan(define_split
5717169689Skan  [(set (match_operand:SI 0 "s_operand" "")
5718169689Skan        (xor:SI (match_dup 0) (match_operand:SI 1 "immediate_operand" "")))
5719169689Skan   (clobber (reg:CC CC_REGNUM))]
5720169689Skan  "reload_completed"
5721169689Skan  [(parallel
5722169689Skan    [(set (match_dup 0) (xor:QI (match_dup 0) (match_dup 1)))
5723169689Skan     (clobber (reg:CC CC_REGNUM))])]
5724169689Skan  "s390_narrow_logical_operator (XOR, &operands[0], &operands[1]);")
5725107590Sobrien
5726107590Sobrien;
5727107590Sobrien; xorhi3 instruction pattern(s).
5728107590Sobrien;
5729107590Sobrien
5730169689Skan(define_insn "*xorhi3"
5731169689Skan  [(set (match_operand:HI 0 "nonimmediate_operand" "=d,d,AQ,Q")
5732169689Skan        (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,0,0")
5733169689Skan                (match_operand:HI 2 "general_operand" "Os,d,NxQH0,Q")))
5734169689Skan   (clobber (reg:CC CC_REGNUM))]
5735169689Skan  "s390_logical_operator_ok_p (operands)"
5736169689Skan  "@
5737169689Skan   xilf\t%0,%x2
5738169689Skan   xr\t%0,%2
5739169689Skan   #
5740169689Skan   #"
5741169689Skan  [(set_attr "op_type"  "RIL,RR,SI,SS")])
5742107590Sobrien
5743169689Skan(define_split
5744169689Skan  [(set (match_operand:HI 0 "s_operand" "")
5745169689Skan        (xor:HI (match_dup 0) (match_operand:HI 1 "immediate_operand" "")))
5746169689Skan   (clobber (reg:CC CC_REGNUM))]
5747169689Skan  "reload_completed"
5748169689Skan  [(parallel
5749169689Skan    [(set (match_dup 0) (xor:QI (match_dup 0) (match_dup 1)))
5750169689Skan     (clobber (reg:CC CC_REGNUM))])]
5751169689Skan  "s390_narrow_logical_operator (XOR, &operands[0], &operands[1]);")
5752107590Sobrien
5753107590Sobrien;
5754107590Sobrien; xorqi3 instruction pattern(s).
5755107590Sobrien;
5756107590Sobrien
5757169689Skan(define_insn "*xorqi3"
5758169689Skan  [(set (match_operand:QI 0 "nonimmediate_operand" "=d,d,Q,S,Q")
5759169689Skan        (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,0,0")
5760169689Skan                (match_operand:QI 2 "general_operand" "Os,d,n,n,Q")))
5761169689Skan   (clobber (reg:CC CC_REGNUM))]
5762169689Skan  "s390_logical_operator_ok_p (operands)"
5763107590Sobrien  "@
5764169689Skan   xilf\t%0,%b2
5765169689Skan   xr\t%0,%2
5766169689Skan   xi\t%S0,%b2
5767169689Skan   xiy\t%S0,%b2
5768169689Skan   #"
5769169689Skan  [(set_attr "op_type"  "RIL,RR,SI,SIY,SS")])
5770107590Sobrien
5771169689Skan;
5772169689Skan; Block exclusive or (XC) patterns.
5773169689Skan;
5774107590Sobrien
5775169689Skan(define_insn "*xc"
5776169689Skan  [(set (match_operand:BLK 0 "memory_operand" "=Q")
5777169689Skan        (xor:BLK (match_dup 0)
5778169689Skan                 (match_operand:BLK 1 "memory_operand" "Q")))
5779169689Skan   (use (match_operand 2 "const_int_operand" "n"))
5780169689Skan   (clobber (reg:CC CC_REGNUM))]
5781169689Skan  "INTVAL (operands[2]) >= 1 && INTVAL (operands[2]) <= 256"
5782169689Skan  "xc\t%O0(%2,%R0),%S1"
5783169689Skan  [(set_attr "op_type" "SS")])
5784107590Sobrien
5785169689Skan(define_split
5786169689Skan  [(set (match_operand 0 "memory_operand" "")
5787169689Skan        (xor (match_dup 0)
5788169689Skan             (match_operand 1 "memory_operand" "")))
5789169689Skan   (clobber (reg:CC CC_REGNUM))]
5790169689Skan  "reload_completed
5791169689Skan   && GET_MODE (operands[0]) == GET_MODE (operands[1])
5792169689Skan   && GET_MODE_SIZE (GET_MODE (operands[0])) > 0"
5793169689Skan  [(parallel
5794169689Skan    [(set (match_dup 0) (xor:BLK (match_dup 0) (match_dup 1)))
5795169689Skan     (use (match_dup 2))
5796169689Skan     (clobber (reg:CC CC_REGNUM))])]
5797169689Skan{
5798169689Skan  operands[2] = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[0])));
5799169689Skan  operands[0] = adjust_address (operands[0], BLKmode, 0);
5800169689Skan  operands[1] = adjust_address (operands[1], BLKmode, 0);
5801169689Skan})
5802169689Skan
5803169689Skan(define_peephole2
5804169689Skan  [(parallel
5805169689Skan    [(set (match_operand:BLK 0 "memory_operand" "")
5806169689Skan          (xor:BLK (match_dup 0)
5807169689Skan                   (match_operand:BLK 1 "memory_operand" "")))
5808169689Skan     (use (match_operand 2 "const_int_operand" ""))
5809169689Skan     (clobber (reg:CC CC_REGNUM))])
5810169689Skan   (parallel
5811169689Skan    [(set (match_operand:BLK 3 "memory_operand" "")
5812169689Skan          (xor:BLK (match_dup 3)
5813169689Skan                   (match_operand:BLK 4 "memory_operand" "")))
5814169689Skan     (use (match_operand 5 "const_int_operand" ""))
5815169689Skan     (clobber (reg:CC CC_REGNUM))])]
5816169689Skan  "s390_offset_p (operands[0], operands[3], operands[2])
5817169689Skan   && s390_offset_p (operands[1], operands[4], operands[2])
5818169689Skan   && !s390_overlap_p (operands[0], operands[1], 
5819169689Skan                       INTVAL (operands[2]) + INTVAL (operands[5]))
5820169689Skan   && INTVAL (operands[2]) + INTVAL (operands[5]) <= 256"
5821169689Skan  [(parallel
5822169689Skan    [(set (match_dup 6) (xor:BLK (match_dup 6) (match_dup 7)))
5823169689Skan     (use (match_dup 8))
5824169689Skan     (clobber (reg:CC CC_REGNUM))])]
5825169689Skan  "operands[6] = gen_rtx_MEM (BLKmode, XEXP (operands[0], 0));
5826169689Skan   operands[7] = gen_rtx_MEM (BLKmode, XEXP (operands[1], 0));
5827169689Skan   operands[8] = GEN_INT (INTVAL (operands[2]) + INTVAL (operands[5]));")
5828169689Skan
5829169689Skan;
5830169689Skan; Block xor (XC) patterns with src == dest.
5831169689Skan;
5832169689Skan
5833169689Skan(define_insn "*xc_zero"
5834169689Skan  [(set (match_operand:BLK 0 "memory_operand" "=Q")
5835169689Skan        (const_int 0))
5836169689Skan   (use (match_operand 1 "const_int_operand" "n"))
5837169689Skan   (clobber (reg:CC CC_REGNUM))]
5838169689Skan  "INTVAL (operands[1]) >= 1 && INTVAL (operands[1]) <= 256"
5839169689Skan  "xc\t%O0(%1,%R0),%S0"
5840169689Skan  [(set_attr "op_type" "SS")])
5841169689Skan
5842169689Skan(define_peephole2
5843169689Skan  [(parallel
5844169689Skan    [(set (match_operand:BLK 0 "memory_operand" "")
5845169689Skan          (const_int 0))
5846169689Skan     (use (match_operand 1 "const_int_operand" ""))
5847169689Skan     (clobber (reg:CC CC_REGNUM))])
5848169689Skan   (parallel
5849169689Skan    [(set (match_operand:BLK 2 "memory_operand" "")
5850169689Skan          (const_int 0))
5851169689Skan     (use (match_operand 3 "const_int_operand" ""))
5852169689Skan     (clobber (reg:CC CC_REGNUM))])]
5853169689Skan  "s390_offset_p (operands[0], operands[2], operands[1])
5854169689Skan   && INTVAL (operands[1]) + INTVAL (operands[3]) <= 256"
5855169689Skan  [(parallel
5856169689Skan    [(set (match_dup 4) (const_int 0))
5857169689Skan     (use (match_dup 5))
5858169689Skan     (clobber (reg:CC CC_REGNUM))])]
5859169689Skan  "operands[4] = gen_rtx_MEM (BLKmode, XEXP (operands[0], 0));
5860169689Skan   operands[5] = GEN_INT (INTVAL (operands[1]) + INTVAL (operands[3]));")
5861169689Skan
5862169689Skan
5863107590Sobrien;;
5864107590Sobrien;;- Negate instructions.
5865107590Sobrien;;
5866107590Sobrien
5867107590Sobrien;
5868169689Skan; neg(di|si)2 instruction pattern(s).
5869107590Sobrien;
5870107590Sobrien
5871169689Skan(define_expand "neg<mode>2"
5872107590Sobrien  [(parallel
5873169689Skan    [(set (match_operand:DSI 0 "register_operand" "=d")
5874169689Skan          (neg:DSI (match_operand:DSI 1 "register_operand" "d")))
5875169689Skan     (clobber (reg:CC CC_REGNUM))])]
5876107590Sobrien  ""
5877107590Sobrien  "")
5878107590Sobrien
5879169689Skan(define_insn "*negdi2_sign_cc"
5880169689Skan  [(set (reg CC_REGNUM)
5881169689Skan        (compare (neg:DI (ashiftrt:DI (ashift:DI (subreg:DI
5882169689Skan                           (match_operand:SI 1 "register_operand" "d") 0)
5883169689Skan                           (const_int 32)) (const_int 32)))
5884169689Skan                 (const_int 0)))
5885169689Skan   (set (match_operand:DI 0 "register_operand" "=d")
5886169689Skan        (neg:DI (sign_extend:DI (match_dup 1))))]
5887169689Skan  "TARGET_64BIT && s390_match_ccmode (insn, CCAmode)"
5888169689Skan  "lcgfr\t%0,%1"
5889169689Skan  [(set_attr "op_type"  "RRE")])
5890169689Skan  
5891169689Skan(define_insn "*negdi2_sign"
5892107590Sobrien  [(set (match_operand:DI 0 "register_operand" "=d")
5893169689Skan        (neg:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "d"))))
5894169689Skan   (clobber (reg:CC CC_REGNUM))]
5895107590Sobrien  "TARGET_64BIT"
5896169689Skan  "lcgfr\t%0,%1"
5897169689Skan  [(set_attr "op_type"  "RRE")])
5898107590Sobrien
5899169689Skan; lcr, lcgr
5900169689Skan(define_insn "*neg<mode>2_cc"
5901169689Skan  [(set (reg CC_REGNUM)
5902169689Skan        (compare (neg:GPR (match_operand:GPR 1 "register_operand" "d"))
5903169689Skan                 (const_int 0)))
5904169689Skan   (set (match_operand:GPR 0 "register_operand" "=d")
5905169689Skan        (neg:GPR (match_dup 1)))]
5906169689Skan  "s390_match_ccmode (insn, CCAmode)"
5907169689Skan  "lc<g>r\t%0,%1"
5908169689Skan  [(set_attr "op_type"  "RR<E>")])
5909169689Skan
5910169689Skan; lcr, lcgr
5911169689Skan(define_insn "*neg<mode>2_cconly"
5912169689Skan  [(set (reg CC_REGNUM)
5913169689Skan        (compare (neg:GPR (match_operand:GPR 1 "register_operand" "d"))
5914169689Skan                 (const_int 0)))
5915169689Skan   (clobber (match_scratch:GPR 0 "=d"))]
5916169689Skan  "s390_match_ccmode (insn, CCAmode)"
5917169689Skan  "lc<g>r\t%0,%1"
5918169689Skan  [(set_attr "op_type"  "RR<E>")])
5919169689Skan
5920169689Skan; lcr, lcgr
5921169689Skan(define_insn "*neg<mode>2"
5922169689Skan  [(set (match_operand:GPR 0 "register_operand" "=d")
5923169689Skan        (neg:GPR (match_operand:GPR 1 "register_operand" "d")))
5924169689Skan   (clobber (reg:CC CC_REGNUM))]
5925169689Skan  ""
5926169689Skan  "lc<g>r\t%0,%1"
5927169689Skan  [(set_attr "op_type"  "RR<E>")])
5928169689Skan
5929169689Skan(define_insn_and_split "*negdi2_31"
5930107590Sobrien  [(set (match_operand:DI 0 "register_operand" "=d")
5931107590Sobrien        (neg:DI (match_operand:DI 1 "register_operand" "d")))
5932169689Skan   (clobber (reg:CC CC_REGNUM))]
5933107590Sobrien  "!TARGET_64BIT"
5934169689Skan  "#"
5935169689Skan  "&& reload_completed"
5936169689Skan  [(parallel
5937169689Skan    [(set (match_dup 2) (neg:SI (match_dup 3)))
5938169689Skan     (clobber (reg:CC CC_REGNUM))])
5939169689Skan   (parallel
5940169689Skan    [(set (reg:CCAP CC_REGNUM)
5941169689Skan          (compare:CCAP (neg:SI (match_dup 5)) (const_int 0)))
5942169689Skan     (set (match_dup 4) (neg:SI (match_dup 5)))])
5943169689Skan   (set (pc)
5944169689Skan        (if_then_else (ne (reg:CCAP CC_REGNUM) (const_int 0))
5945169689Skan                      (pc)
5946169689Skan                      (label_ref (match_dup 6))))
5947169689Skan   (parallel
5948169689Skan    [(set (match_dup 2) (plus:SI (match_dup 2) (const_int -1)))
5949169689Skan     (clobber (reg:CC CC_REGNUM))])
5950169689Skan   (match_dup 6)]
5951169689Skan  "operands[2] = operand_subword (operands[0], 0, 0, DImode);
5952169689Skan   operands[3] = operand_subword (operands[1], 0, 0, DImode);
5953169689Skan   operands[4] = operand_subword (operands[0], 1, 0, DImode);
5954169689Skan   operands[5] = operand_subword (operands[1], 1, 0, DImode);
5955169689Skan   operands[6] = gen_label_rtx ();")
5956107590Sobrien
5957107590Sobrien;
5958169689Skan; neg(df|sf)2 instruction pattern(s).
5959107590Sobrien;
5960107590Sobrien
5961169689Skan(define_expand "neg<mode>2"
5962107590Sobrien  [(parallel
5963169689Skan    [(set (match_operand:FPR 0 "register_operand" "=f")
5964169689Skan          (neg:FPR (match_operand:FPR 1 "register_operand" "f")))
5965169689Skan     (clobber (reg:CC CC_REGNUM))])]
5966107590Sobrien  "TARGET_HARD_FLOAT"
5967107590Sobrien  "")
5968107590Sobrien
5969169689Skan; lcxbr, lcdbr, lcebr
5970169689Skan(define_insn "*neg<mode>2_cc"
5971169689Skan  [(set (reg CC_REGNUM)
5972169689Skan        (compare (neg:FPR (match_operand:FPR 1 "register_operand" "f"))
5973169689Skan                 (match_operand:FPR 2 "const0_operand" "")))
5974169689Skan   (set (match_operand:FPR 0 "register_operand" "=f")
5975169689Skan        (neg:FPR (match_dup 1)))]
5976169689Skan  "s390_match_ccmode (insn, CCSmode) && TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT"
5977169689Skan  "lc<xde>br\t%0,%1"
5978132718Skan  [(set_attr "op_type"  "RRE")
5979169689Skan   (set_attr "type"     "fsimp<mode>")])
5980107590Sobrien
5981169689Skan; lcxbr, lcdbr, lcebr
5982169689Skan(define_insn "*neg<mode>2_cconly"
5983169689Skan  [(set (reg CC_REGNUM)
5984169689Skan        (compare (neg:FPR (match_operand:FPR 1 "register_operand" "f"))
5985169689Skan                 (match_operand:FPR 2 "const0_operand" "")))
5986169689Skan   (clobber (match_scratch:FPR 0 "=f"))]
5987169689Skan  "s390_match_ccmode (insn, CCSmode) && TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT"
5988169689Skan  "lc<xde>br\t%0,%1"
5989169689Skan  [(set_attr "op_type"  "RRE")
5990169689Skan   (set_attr "type"     "fsimp<mode>")])
5991107590Sobrien
5992169689Skan; lcxbr, lcdbr, lcebr
5993169689Skan(define_insn "*neg<mode>2"
5994169689Skan  [(set (match_operand:FPR 0 "register_operand" "=f")
5995169689Skan        (neg:FPR (match_operand:FPR 1 "register_operand" "f")))
5996169689Skan   (clobber (reg:CC CC_REGNUM))]
5997107590Sobrien  "TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT"
5998169689Skan  "lc<xde>br\t%0,%1"
5999132718Skan  [(set_attr "op_type"  "RRE")
6000169689Skan   (set_attr "type"     "fsimp<mode>")])
6001107590Sobrien
6002169689Skan; lcxr, lcdr, lcer
6003169689Skan(define_insn "*neg<mode>2_ibm"
6004169689Skan  [(set (match_operand:FPR 0 "register_operand" "=f")
6005169689Skan        (neg:FPR (match_operand:FPR 1 "register_operand" "f")))
6006169689Skan   (clobber (reg:CC CC_REGNUM))]
6007107590Sobrien  "TARGET_HARD_FLOAT && TARGET_IBM_FLOAT"
6008169689Skan  "lc<xde>r\t%0,%1"
6009169689Skan  [(set_attr "op_type"  "<RRe>")
6010169689Skan   (set_attr "type"     "fsimp<mode>")])
6011107590Sobrien
6012107590Sobrien
6013107590Sobrien;;
6014107590Sobrien;;- Absolute value instructions.
6015107590Sobrien;;
6016107590Sobrien
6017107590Sobrien;
6018169689Skan; abs(di|si)2 instruction pattern(s).
6019107590Sobrien;
6020107590Sobrien
6021169689Skan(define_insn "*absdi2_sign_cc"
6022169689Skan  [(set (reg CC_REGNUM)
6023169689Skan        (compare (abs:DI (ashiftrt:DI (ashift:DI (subreg:DI
6024169689Skan                           (match_operand:SI 1 "register_operand" "d") 0)
6025169689Skan                           (const_int 32)) (const_int 32)))
6026169689Skan                 (const_int 0)))
6027169689Skan   (set (match_operand:DI 0 "register_operand" "=d")
6028169689Skan        (abs:DI (sign_extend:DI (match_dup 1))))]
6029169689Skan  "TARGET_64BIT && s390_match_ccmode (insn, CCAmode)"
6030169689Skan  "lpgfr\t%0,%1"
6031169689Skan  [(set_attr "op_type"  "RRE")])
6032169689Skan
6033169689Skan(define_insn "*absdi2_sign"
6034107590Sobrien  [(set (match_operand:DI 0 "register_operand" "=d")
6035169689Skan        (abs:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "d"))))
6036169689Skan   (clobber (reg:CC CC_REGNUM))]
6037107590Sobrien  "TARGET_64BIT"
6038169689Skan  "lpgfr\t%0,%1"
6039107590Sobrien  [(set_attr "op_type"  "RRE")])
6040107590Sobrien
6041169689Skan; lpr, lpgr
6042169689Skan(define_insn "*abs<mode>2_cc"
6043169689Skan  [(set (reg CC_REGNUM)
6044169689Skan        (compare (abs:GPR (match_operand:DI 1 "register_operand" "d"))
6045169689Skan                 (const_int 0)))
6046169689Skan   (set (match_operand:GPR 0 "register_operand" "=d")
6047169689Skan        (abs:GPR (match_dup 1)))]
6048169689Skan  "s390_match_ccmode (insn, CCAmode)"
6049169689Skan  "lp<g>r\t%0,%1"
6050169689Skan  [(set_attr "op_type"  "RR<E>")])
6051107590Sobrien
6052169689Skan; lpr, lpgr  
6053169689Skan(define_insn "*abs<mode>2_cconly"
6054169689Skan  [(set (reg CC_REGNUM)
6055169689Skan        (compare (abs:GPR (match_operand:GPR 1 "register_operand" "d"))
6056169689Skan                 (const_int 0)))
6057169689Skan   (clobber (match_scratch:GPR 0 "=d"))]
6058169689Skan  "s390_match_ccmode (insn, CCAmode)"
6059169689Skan  "lp<g>r\t%0,%1"
6060169689Skan  [(set_attr "op_type"  "RR<E>")])
6061169689Skan
6062169689Skan; lpr, lpgr
6063169689Skan(define_insn "abs<mode>2"
6064169689Skan  [(set (match_operand:GPR 0 "register_operand" "=d")
6065169689Skan        (abs:GPR (match_operand:GPR 1 "register_operand" "d")))
6066169689Skan   (clobber (reg:CC CC_REGNUM))]
6067107590Sobrien  ""
6068169689Skan  "lp<g>r\t%0,%1"
6069169689Skan  [(set_attr "op_type"  "RR<E>")])
6070107590Sobrien
6071107590Sobrien;
6072169689Skan; abs(df|sf)2 instruction pattern(s).
6073107590Sobrien;
6074107590Sobrien
6075169689Skan(define_expand "abs<mode>2"
6076107590Sobrien  [(parallel
6077169689Skan    [(set (match_operand:FPR 0 "register_operand" "=f")
6078169689Skan          (abs:FPR (match_operand:FPR 1 "register_operand" "f")))
6079169689Skan     (clobber (reg:CC CC_REGNUM))])]
6080107590Sobrien  "TARGET_HARD_FLOAT"
6081107590Sobrien  "")
6082107590Sobrien
6083169689Skan; lpxbr, lpdbr, lpebr
6084169689Skan(define_insn "*abs<mode>2_cc"
6085169689Skan  [(set (reg CC_REGNUM)
6086169689Skan        (compare (abs:FPR (match_operand:FPR 1 "register_operand" "f"))
6087169689Skan                 (match_operand:FPR 2 "const0_operand" "")))
6088169689Skan   (set (match_operand:FPR 0 "register_operand" "=f")
6089169689Skan        (abs:FPR (match_dup 1)))]
6090169689Skan  "s390_match_ccmode (insn, CCSmode) && TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT"
6091169689Skan  "lp<xde>br\t%0,%1"
6092132718Skan  [(set_attr "op_type"  "RRE")
6093169689Skan   (set_attr "type"     "fsimp<mode>")])
6094107590Sobrien
6095169689Skan; lpxbr, lpdbr, lpebr
6096169689Skan(define_insn "*abs<mode>2_cconly"
6097169689Skan  [(set (reg CC_REGNUM)
6098169689Skan        (compare (abs:FPR (match_operand:FPR 1 "register_operand" "f"))
6099169689Skan                 (match_operand:FPR 2 "const0_operand" "")))
6100169689Skan   (clobber (match_scratch:FPR 0 "=f"))]
6101169689Skan  "s390_match_ccmode (insn, CCSmode) && TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT"
6102169689Skan  "lp<xde>br\t%0,%1"
6103169689Skan  [(set_attr "op_type"  "RRE")
6104169689Skan   (set_attr "type"     "fsimp<mode>")])
6105107590Sobrien
6106169689Skan; lpxbr, lpdbr, lpebr
6107169689Skan(define_insn "*abs<mode>2"
6108169689Skan  [(set (match_operand:FPR 0 "register_operand" "=f")
6109169689Skan        (abs:FPR (match_operand:FPR 1 "register_operand" "f")))
6110169689Skan   (clobber (reg:CC CC_REGNUM))]
6111107590Sobrien  "TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT"
6112169689Skan  "lp<xde>br\t%0,%1"
6113132718Skan  [(set_attr "op_type"  "RRE")
6114169689Skan   (set_attr "type"     "fsimp<mode>")])
6115107590Sobrien
6116169689Skan; lpxr, lpdr, lper
6117169689Skan(define_insn "*abs<mode>2_ibm"
6118169689Skan  [(set (match_operand:FPR 0 "register_operand" "=f")
6119169689Skan        (abs:FPR (match_operand:FPR 1 "register_operand" "f")))
6120169689Skan   (clobber (reg:CC CC_REGNUM))]
6121107590Sobrien  "TARGET_HARD_FLOAT && TARGET_IBM_FLOAT"
6122169689Skan  "lp<xde>r\t%0,%1"
6123169689Skan  [(set_attr "op_type"  "<RRe>")
6124169689Skan   (set_attr "type"     "fsimp<mode>")])
6125107590Sobrien
6126107590Sobrien;;
6127132718Skan;;- Negated absolute value instructions
6128132718Skan;;
6129132718Skan
6130132718Skan;
6131132718Skan; Integer
6132132718Skan;
6133132718Skan
6134169689Skan(define_insn "*negabsdi2_sign_cc"
6135169689Skan  [(set (reg CC_REGNUM)
6136169689Skan        (compare (neg:DI (abs:DI (ashiftrt:DI (ashift:DI (subreg:DI
6137169689Skan                           (match_operand:SI 1 "register_operand" "d") 0)
6138169689Skan                           (const_int 32)) (const_int 32))))
6139169689Skan                 (const_int 0)))
6140169689Skan   (set (match_operand:DI 0 "register_operand" "=d")
6141169689Skan        (neg:DI (abs:DI (sign_extend:DI (match_dup 1)))))]
6142169689Skan  "TARGET_64BIT && s390_match_ccmode (insn, CCAmode)"
6143169689Skan  "lngfr\t%0,%1"
6144169689Skan  [(set_attr "op_type"  "RRE")])
6145169689Skan 
6146169689Skan(define_insn "*negabsdi2_sign"
6147132718Skan  [(set (match_operand:DI 0 "register_operand" "=d")
6148169689Skan	(neg:DI (abs:DI (sign_extend:DI
6149169689Skan                          (match_operand:SI 1 "register_operand" "d")))))
6150169689Skan   (clobber (reg:CC CC_REGNUM))]
6151132718Skan  "TARGET_64BIT"
6152169689Skan  "lngfr\t%0,%1"
6153132718Skan  [(set_attr "op_type" "RRE")])
6154132718Skan
6155169689Skan; lnr, lngr
6156169689Skan(define_insn "*negabs<mode>2_cc"
6157169689Skan  [(set (reg CC_REGNUM)
6158169689Skan        (compare (neg:GPR (abs:GPR (match_operand:GPR 1 "register_operand" "d")))
6159169689Skan                 (const_int 0)))
6160169689Skan   (set (match_operand:GPR 0 "register_operand" "=d")
6161169689Skan        (neg:GPR (abs:GPR (match_dup 1))))]
6162169689Skan  "s390_match_ccmode (insn, CCAmode)"
6163169689Skan  "ln<g>r\t%0,%1"
6164169689Skan  [(set_attr "op_type"  "RR<E>")])
6165169689Skan
6166169689Skan; lnr, lngr
6167169689Skan(define_insn "*negabs<mode>2_cconly"
6168169689Skan  [(set (reg CC_REGNUM)
6169169689Skan        (compare (neg:GPR (abs:GPR (match_operand:GPR 1 "register_operand" "d")))
6170169689Skan                 (const_int 0)))
6171169689Skan   (clobber (match_scratch:GPR 0 "=d"))]
6172169689Skan  "s390_match_ccmode (insn, CCAmode)"
6173169689Skan  "ln<g>r\t%0,%1"
6174169689Skan  [(set_attr "op_type"  "RR<E>")])
6175169689Skan
6176169689Skan; lnr, lngr
6177169689Skan(define_insn "*negabs<mode>2"
6178169689Skan  [(set (match_operand:GPR 0 "register_operand" "=d")
6179169689Skan	(neg:GPR (abs:GPR (match_operand:GPR 1 "register_operand" "d"))))
6180169689Skan   (clobber (reg:CC CC_REGNUM))]
6181169689Skan  ""
6182169689Skan  "ln<g>r\t%0,%1"
6183169689Skan  [(set_attr "op_type" "RR<E>")])
6184169689Skan
6185132718Skan;
6186132718Skan; Floating point
6187132718Skan;
6188132718Skan
6189169689Skan; lnxbr, lndbr, lnebr
6190169689Skan(define_insn "*negabs<mode>2_cc"
6191169689Skan  [(set (reg CC_REGNUM)
6192169689Skan        (compare (neg:FPR (abs:FPR (match_operand:FPR 1 "register_operand" "f")))
6193169689Skan                 (match_operand:FPR 2 "const0_operand" "")))
6194169689Skan   (set (match_operand:FPR 0 "register_operand" "=f")
6195169689Skan        (neg:FPR (abs:FPR (match_dup 1))))]
6196169689Skan  "s390_match_ccmode (insn, CCSmode) && TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT"
6197169689Skan  "ln<xde>br\t%0,%1"
6198132718Skan  [(set_attr "op_type"  "RRE")
6199169689Skan   (set_attr "type"     "fsimp<mode>")])
6200132718Skan
6201169689Skan; lnxbr, lndbr, lnebr
6202169689Skan(define_insn "*negabs<mode>2_cconly"
6203169689Skan  [(set (reg CC_REGNUM)
6204169689Skan        (compare (neg:FPR (abs:FPR (match_operand:FPR 1 "register_operand" "f")))
6205169689Skan                 (match_operand:FPR 2 "const0_operand" "")))
6206169689Skan   (clobber (match_scratch:FPR 0 "=f"))]
6207169689Skan  "s390_match_ccmode (insn, CCSmode) && TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT"
6208169689Skan  "ln<xde>br\t%0,%1"
6209169689Skan  [(set_attr "op_type"  "RRE")
6210169689Skan   (set_attr "type"     "fsimp<mode>")])
6211169689Skan
6212169689Skan; lnxbr, lndbr, lnebr
6213169689Skan(define_insn "*negabs<mode>2"
6214169689Skan  [(set (match_operand:FPR 0 "register_operand" "=f")
6215169689Skan        (neg:FPR (abs:FPR (match_operand:FPR 1 "register_operand" "f"))))
6216169689Skan   (clobber (reg:CC CC_REGNUM))]
6217132718Skan  "TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT"
6218169689Skan  "ln<xde>br\t%0,%1"
6219132718Skan  [(set_attr "op_type"  "RRE")
6220169689Skan   (set_attr "type"     "fsimp<mode>")])
6221132718Skan
6222132718Skan;;
6223107590Sobrien;;- Square root instructions.
6224107590Sobrien;;
6225107590Sobrien
6226107590Sobrien;
6227169689Skan; sqrt(df|sf)2 instruction pattern(s).
6228107590Sobrien;
6229107590Sobrien
6230169689Skan; sqxbr, sqdbr, sqebr, sqxb, sqdb, sqeb
6231169689Skan(define_insn "sqrt<mode>2"
6232169689Skan  [(set (match_operand:FPR 0 "register_operand" "=f,f")
6233169689Skan	(sqrt:FPR (match_operand:FPR 1 "general_operand" "f,<Rf>")))]
6234107590Sobrien  "TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT"
6235107590Sobrien  "@
6236169689Skan   sq<xde>br\t%0,%1
6237169689Skan   sq<xde>b\t%0,%1"
6238169689Skan  [(set_attr "op_type" "RRE,RXE")
6239169689Skan   (set_attr "type" "fsqrt<mode>")])
6240107590Sobrien
6241107590Sobrien
6242107590Sobrien;;
6243107590Sobrien;;- One complement instructions.
6244107590Sobrien;;
6245107590Sobrien
6246107590Sobrien;
6247169689Skan; one_cmpl(di|si|hi|qi)2 instruction pattern(s).
6248107590Sobrien;
6249132718Skan
6250169689Skan(define_expand "one_cmpl<mode>2"
6251107590Sobrien  [(parallel
6252169689Skan    [(set (match_operand:INT 0 "register_operand" "")
6253169689Skan          (xor:INT (match_operand:INT 1 "register_operand" "")
6254169689Skan		   (const_int -1)))
6255169689Skan     (clobber (reg:CC CC_REGNUM))])]
6256169689Skan  ""
6257107590Sobrien  "")
6258132718Skan
6259132718Skan
6260169689Skan;;
6261169689Skan;; Find leftmost bit instructions.
6262169689Skan;;
6263132718Skan
6264169689Skan(define_expand "clzdi2"
6265169689Skan  [(set (match_operand:DI 0 "register_operand" "=d")
6266169689Skan	(clz:DI (match_operand:DI 1 "register_operand" "d")))]
6267169689Skan  "TARGET_EXTIMM && TARGET_64BIT"
6268169689Skan{
6269169689Skan  rtx insn, clz_equal;
6270169689Skan  rtx wide_reg = gen_reg_rtx (TImode);
6271169689Skan  rtx msb = gen_rtx_CONST_INT (DImode, (unsigned HOST_WIDE_INT) 1 << 63);
6272132718Skan
6273169689Skan  clz_equal = gen_rtx_CLZ (DImode, operands[1]);
6274132718Skan
6275169689Skan  emit_insn (gen_clztidi2 (wide_reg, operands[1], msb));
6276132718Skan
6277169689Skan  insn = emit_move_insn (operands[0], gen_highpart (DImode, wide_reg));  
6278169689Skan  REG_NOTES (insn) =
6279169689Skan        gen_rtx_EXPR_LIST (REG_EQUAL, clz_equal, REG_NOTES (insn));
6280107590Sobrien
6281169689Skan  DONE;
6282169689Skan})
6283107590Sobrien
6284169689Skan(define_insn "clztidi2"
6285169689Skan  [(set (match_operand:TI 0 "register_operand" "=d")
6286169689Skan	(ior:TI
6287169689Skan	  (ashift:TI 
6288169689Skan            (zero_extend:TI 
6289169689Skan   	      (xor:DI (match_operand:DI 1 "register_operand" "d")
6290169689Skan                      (lshiftrt (match_operand:DI 2 "const_int_operand" "")
6291169689Skan				(subreg:SI (clz:DI (match_dup 1)) 4))))
6292169689Skan	    
6293169689Skan	    (const_int 64))
6294169689Skan          (zero_extend:TI (clz:DI (match_dup 1)))))
6295169689Skan   (clobber (reg:CC CC_REGNUM))]
6296169689Skan  "(unsigned HOST_WIDE_INT) INTVAL (operands[2]) 
6297169689Skan   == (unsigned HOST_WIDE_INT) 1 << 63
6298169689Skan   && TARGET_EXTIMM && TARGET_64BIT"
6299169689Skan  "flogr\t%0,%1"
6300169689Skan  [(set_attr "op_type"  "RRE")])
6301169689Skan
6302169689Skan
6303107590Sobrien;;
6304107590Sobrien;;- Rotate instructions.
6305107590Sobrien;;
6306107590Sobrien
6307107590Sobrien;
6308169689Skan; rotl(di|si)3 instruction pattern(s).
6309107590Sobrien;
6310107590Sobrien
6311169689Skan; rll, rllg
6312169689Skan(define_insn "rotl<mode>3"
6313169689Skan  [(set (match_operand:GPR 0 "register_operand" "=d")
6314169689Skan	(rotate:GPR (match_operand:GPR 1 "register_operand" "d")
6315169689Skan		    (match_operand:SI 2 "shift_count_or_setmem_operand" "Y")))]
6316169689Skan  "TARGET_CPU_ZARCH"
6317169689Skan  "rll<g>\t%0,%1,%Y2"
6318132718Skan  [(set_attr "op_type"  "RSE")
6319132718Skan   (set_attr "atype"    "reg")])
6320107590Sobrien
6321169689Skan; rll, rllg
6322169689Skan(define_insn "*rotl<mode>3_and"
6323169689Skan  [(set (match_operand:GPR 0 "register_operand" "=d")
6324169689Skan	(rotate:GPR (match_operand:GPR 1 "register_operand" "d")
6325169689Skan		    (and:SI (match_operand:SI 2 "shift_count_or_setmem_operand" "Y")
6326169689Skan			    (match_operand:SI 3 "const_int_operand"   "n"))))]
6327169689Skan  "TARGET_CPU_ZARCH && (INTVAL (operands[3]) & 63) == 63"
6328169689Skan  "rll<g>\t%0,%1,%Y2"
6329132718Skan  [(set_attr "op_type"  "RSE")
6330132718Skan   (set_attr "atype"    "reg")])
6331107590Sobrien
6332107590Sobrien
6333107590Sobrien;;
6334169689Skan;;- Shift instructions.
6335107590Sobrien;;
6336107590Sobrien
6337107590Sobrien;
6338169689Skan; (ashl|lshr)(di|si)3 instruction pattern(s).
6339107590Sobrien;
6340107590Sobrien
6341169689Skan(define_expand "<shift><mode>3"
6342169689Skan  [(set (match_operand:DSI 0 "register_operand" "")
6343169689Skan        (SHIFT:DSI (match_operand:DSI 1 "register_operand" "")
6344169689Skan                   (match_operand:SI 2 "shift_count_or_setmem_operand" "")))]
6345107590Sobrien  ""
6346107590Sobrien  "")
6347107590Sobrien
6348169689Skan; sldl, srdl
6349169689Skan(define_insn "*<shift>di3_31"
6350132718Skan  [(set (match_operand:DI 0 "register_operand" "=d")
6351169689Skan        (SHIFT:DI (match_operand:DI 1 "register_operand" "0")
6352169689Skan                  (match_operand:SI 2 "shift_count_or_setmem_operand" "Y")))]
6353107590Sobrien  "!TARGET_64BIT"
6354169689Skan  "s<lr>dl\t%0,%Y2"
6355132718Skan  [(set_attr "op_type"  "RS")
6356132718Skan   (set_attr "atype"    "reg")])
6357107590Sobrien
6358169689Skan; sll, srl, sllg, srlg
6359169689Skan(define_insn "*<shift><mode>3"
6360169689Skan  [(set (match_operand:GPR 0 "register_operand" "=d")
6361169689Skan        (SHIFT:GPR (match_operand:GPR 1 "register_operand" "<d0>")
6362169689Skan                   (match_operand:SI 2 "shift_count_or_setmem_operand" "Y")))]
6363169689Skan  ""
6364169689Skan  "s<lr>l<g>\t%0,<1>%Y2"
6365169689Skan  [(set_attr "op_type"  "RS<E>")
6366169689Skan   (set_attr "atype"    "reg")])
6367169689Skan
6368169689Skan; sldl, srdl
6369169689Skan(define_insn "*<shift>di3_31_and"
6370132718Skan  [(set (match_operand:DI 0 "register_operand" "=d")
6371169689Skan        (SHIFT:DI (match_operand:DI 1 "register_operand" "0")
6372169689Skan                  (and:SI (match_operand:SI 2 "shift_count_or_setmem_operand" "Y")
6373169689Skan			  (match_operand:SI 3 "const_int_operand"   "n"))))]
6374169689Skan  "!TARGET_64BIT && (INTVAL (operands[3]) & 63) == 63"
6375169689Skan  "s<lr>dl\t%0,%Y2"
6376169689Skan  [(set_attr "op_type"  "RS")
6377132718Skan   (set_attr "atype"    "reg")])
6378107590Sobrien
6379169689Skan; sll, srl, sllg, srlg
6380169689Skan(define_insn "*<shift><mode>3_and"
6381169689Skan  [(set (match_operand:GPR 0 "register_operand" "=d")
6382169689Skan        (SHIFT:GPR (match_operand:GPR 1 "register_operand" "<d0>")
6383169689Skan                   (and:SI (match_operand:SI 2 "shift_count_or_setmem_operand" "Y")
6384169689Skan			   (match_operand:SI 3 "const_int_operand"   "n"))))]
6385169689Skan  "(INTVAL (operands[3]) & 63) == 63"
6386169689Skan  "s<lr>l<g>\t%0,<1>%Y2"
6387169689Skan  [(set_attr "op_type"  "RS<E>")
6388169689Skan   (set_attr "atype"    "reg")])
6389169689Skan
6390107590Sobrien;
6391169689Skan; ashr(di|si)3 instruction pattern(s).
6392107590Sobrien;
6393107590Sobrien
6394169689Skan(define_expand "ashr<mode>3"
6395107590Sobrien  [(parallel
6396169689Skan    [(set (match_operand:DSI 0 "register_operand" "")
6397169689Skan          (ashiftrt:DSI (match_operand:DSI 1 "register_operand" "")
6398169689Skan                        (match_operand:SI 2 "shift_count_or_setmem_operand" "")))
6399169689Skan     (clobber (reg:CC CC_REGNUM))])]
6400107590Sobrien  ""
6401107590Sobrien  "")
6402107590Sobrien
6403107590Sobrien(define_insn "*ashrdi3_cc_31"
6404169689Skan  [(set (reg CC_REGNUM)
6405132718Skan        (compare (ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
6406169689Skan                              (match_operand:SI 2 "shift_count_or_setmem_operand" "Y"))
6407107590Sobrien                 (const_int 0)))
6408132718Skan   (set (match_operand:DI 0 "register_operand" "=d")
6409107590Sobrien        (ashiftrt:DI (match_dup 1) (match_dup 2)))]
6410107590Sobrien  "!TARGET_64BIT && s390_match_ccmode(insn, CCSmode)"
6411132718Skan  "srda\t%0,%Y2"
6412132718Skan  [(set_attr "op_type"  "RS")
6413132718Skan   (set_attr "atype"    "reg")])
6414107590Sobrien
6415107590Sobrien(define_insn "*ashrdi3_cconly_31"
6416169689Skan  [(set (reg CC_REGNUM)
6417132718Skan        (compare (ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
6418169689Skan                              (match_operand:SI 2 "shift_count_or_setmem_operand" "Y"))
6419107590Sobrien                 (const_int 0)))
6420132718Skan   (clobber (match_scratch:DI 0 "=d"))]
6421107590Sobrien  "!TARGET_64BIT && s390_match_ccmode(insn, CCSmode)"
6422132718Skan  "srda\t%0,%Y2"
6423132718Skan  [(set_attr "op_type"  "RS")
6424132718Skan   (set_attr "atype"    "reg")])
6425107590Sobrien
6426107590Sobrien(define_insn "*ashrdi3_31"
6427132718Skan  [(set (match_operand:DI 0 "register_operand" "=d")
6428132718Skan        (ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
6429169689Skan                     (match_operand:SI 2 "shift_count_or_setmem_operand" "Y")))
6430169689Skan   (clobber (reg:CC CC_REGNUM))]
6431107590Sobrien  "!TARGET_64BIT"
6432132718Skan  "srda\t%0,%Y2"
6433132718Skan  [(set_attr "op_type"  "RS")
6434132718Skan   (set_attr "atype"    "reg")])
6435107590Sobrien
6436169689Skan; sra, srag
6437169689Skan(define_insn "*ashr<mode>3_cc"
6438169689Skan  [(set (reg CC_REGNUM)
6439169689Skan        (compare (ashiftrt:GPR (match_operand:GPR 1 "register_operand" "<d0>")
6440169689Skan                               (match_operand:SI 2 "shift_count_or_setmem_operand" "Y"))
6441107590Sobrien                 (const_int 0)))
6442169689Skan   (set (match_operand:GPR 0 "register_operand" "=d")
6443169689Skan        (ashiftrt:GPR (match_dup 1) (match_dup 2)))]
6444169689Skan  "s390_match_ccmode(insn, CCSmode)"
6445169689Skan  "sra<g>\t%0,<1>%Y2"
6446169689Skan  [(set_attr "op_type"  "RS<E>")
6447132718Skan   (set_attr "atype"    "reg")])
6448107590Sobrien
6449169689Skan; sra, srag
6450169689Skan(define_insn "*ashr<mode>3_cconly"
6451169689Skan  [(set (reg CC_REGNUM)
6452169689Skan        (compare (ashiftrt:GPR (match_operand:GPR 1 "register_operand" "<d0>")
6453169689Skan                               (match_operand:SI 2 "shift_count_or_setmem_operand" "Y"))
6454107590Sobrien                 (const_int 0)))
6455169689Skan   (clobber (match_scratch:GPR 0 "=d"))]
6456169689Skan  "s390_match_ccmode(insn, CCSmode)"
6457169689Skan  "sra<g>\t%0,<1>%Y2"
6458169689Skan  [(set_attr "op_type"  "RS<E>")
6459132718Skan   (set_attr "atype"    "reg")])
6460107590Sobrien
6461169689Skan; sra, srag
6462169689Skan(define_insn "*ashr<mode>3"
6463169689Skan  [(set (match_operand:GPR 0 "register_operand" "=d")
6464169689Skan        (ashiftrt:GPR (match_operand:GPR 1 "register_operand" "<d0>")
6465169689Skan                      (match_operand:SI 2 "shift_count_or_setmem_operand" "Y")))
6466169689Skan   (clobber (reg:CC CC_REGNUM))]
6467169689Skan  ""
6468169689Skan  "sra<g>\t%0,<1>%Y2"
6469169689Skan  [(set_attr "op_type"  "RS<E>")
6470132718Skan   (set_attr "atype"    "reg")])
6471107590Sobrien
6472132718Skan
6473169689Skan; shift pattern with implicit ANDs
6474107590Sobrien
6475169689Skan(define_insn "*ashrdi3_cc_31_and"
6476169689Skan  [(set (reg CC_REGNUM)
6477169689Skan        (compare (ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
6478169689Skan                              (and:SI (match_operand:SI 2 "shift_count_or_setmem_operand" "Y")
6479169689Skan				      (match_operand:SI 3 "const_int_operand"   "n")))
6480169689Skan		 (const_int 0)))
6481169689Skan   (set (match_operand:DI 0 "register_operand" "=d")
6482169689Skan        (ashiftrt:DI (match_dup 1) (and:SI (match_dup 2) (match_dup 3))))]
6483169689Skan  "!TARGET_64BIT && s390_match_ccmode(insn, CCSmode)
6484169689Skan   && (INTVAL (operands[3]) & 63) == 63"
6485169689Skan  "srda\t%0,%Y2"
6486132718Skan  [(set_attr "op_type"  "RS")
6487132718Skan   (set_attr "atype"    "reg")])
6488107590Sobrien
6489169689Skan(define_insn "*ashrdi3_cconly_31_and"
6490169689Skan  [(set (reg CC_REGNUM)
6491169689Skan        (compare (ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
6492169689Skan                              (and:SI (match_operand:SI 2 "shift_count_or_setmem_operand" "Y")
6493169689Skan				      (match_operand:SI 3 "const_int_operand"   "n")))
6494107590Sobrien                 (const_int 0)))
6495169689Skan   (clobber (match_scratch:DI 0 "=d"))]
6496169689Skan  "!TARGET_64BIT && s390_match_ccmode(insn, CCSmode)
6497169689Skan   && (INTVAL (operands[3]) & 63) == 63"
6498169689Skan  "srda\t%0,%Y2"
6499132718Skan  [(set_attr "op_type"  "RS")
6500132718Skan   (set_attr "atype"    "reg")])
6501107590Sobrien
6502169689Skan(define_insn "*ashrdi3_31_and"
6503169689Skan  [(set (match_operand:DI 0 "register_operand" "=d")
6504169689Skan        (ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
6505169689Skan                     (and:SI (match_operand:SI 2 "shift_count_or_setmem_operand" "Y")
6506169689Skan			     (match_operand:SI 3 "const_int_operand"   "n"))))
6507169689Skan   (clobber (reg:CC CC_REGNUM))]
6508169689Skan  "!TARGET_64BIT && (INTVAL (operands[3]) & 63) == 63"
6509169689Skan  "srda\t%0,%Y2"
6510132718Skan  [(set_attr "op_type"  "RS")
6511132718Skan   (set_attr "atype"    "reg")])
6512107590Sobrien
6513169689Skan; sra, srag
6514169689Skan(define_insn "*ashr<mode>3_cc_and"
6515169689Skan  [(set (reg CC_REGNUM)
6516169689Skan        (compare (ashiftrt:GPR (match_operand:GPR 1 "register_operand" "<d0>")
6517169689Skan                               (and:SI (match_operand:SI 2 "shift_count_or_setmem_operand" "Y")
6518169689Skan				       (match_operand:SI 3 "const_int_operand"   "n")))
6519169689Skan		 (const_int 0)))
6520169689Skan   (set (match_operand:GPR 0 "register_operand" "=d")
6521169689Skan        (ashiftrt:GPR (match_dup 1) (and:SI (match_dup 2) (match_dup 3))))]
6522169689Skan  "s390_match_ccmode(insn, CCSmode) && (INTVAL (operands[3]) & 63) == 63"
6523169689Skan  "sra<g>\t%0,<1>%Y2"
6524169689Skan  [(set_attr "op_type"  "RS<E>")
6525132718Skan   (set_attr "atype"    "reg")])
6526107590Sobrien
6527169689Skan; sra, srag
6528169689Skan(define_insn "*ashr<mode>3_cconly_and"
6529169689Skan  [(set (reg CC_REGNUM)
6530169689Skan        (compare (ashiftrt:GPR (match_operand:GPR 1 "register_operand" "<d0>")
6531169689Skan                               (and:SI (match_operand:SI 2 "shift_count_or_setmem_operand" "Y")
6532169689Skan				       (match_operand:SI 3 "const_int_operand"   "n")))
6533169689Skan                 (const_int 0)))
6534169689Skan   (clobber (match_scratch:GPR 0 "=d"))]
6535169689Skan  "s390_match_ccmode(insn, CCSmode) && (INTVAL (operands[3]) & 63) == 63"
6536169689Skan  "sra<g>\t%0,<1>%Y2"
6537169689Skan  [(set_attr "op_type"  "RS<E>")
6538132718Skan   (set_attr "atype"    "reg")])
6539107590Sobrien
6540169689Skan; sra, srag
6541169689Skan(define_insn "*ashr<mode>3_and"
6542169689Skan  [(set (match_operand:GPR 0 "register_operand" "=d")
6543169689Skan        (ashiftrt:GPR (match_operand:GPR 1 "register_operand" "<d0>")
6544169689Skan                      (and:SI (match_operand:SI 2 "shift_count_or_setmem_operand" "Y")
6545169689Skan			      (match_operand:SI 3 "const_int_operand"   "n"))))
6546169689Skan   (clobber (reg:CC CC_REGNUM))]
6547169689Skan  "(INTVAL (operands[3]) & 63) == 63"
6548169689Skan  "sra<g>\t%0,<1>%Y2"
6549169689Skan  [(set_attr "op_type"  "RS<E>")
6550132718Skan   (set_attr "atype"    "reg")])
6551107590Sobrien
6552107590Sobrien
6553107590Sobrien;;
6554107590Sobrien;; Branch instruction patterns.
6555107590Sobrien;;
6556107590Sobrien
6557169689Skan(define_expand "b<code>"
6558169689Skan  [(set (pc)
6559169689Skan        (if_then_else (COMPARE (match_operand 0 "" "")
6560169689Skan                               (const_int 0))
6561169689Skan                      (match_dup 0)
6562107590Sobrien                      (pc)))]
6563107590Sobrien  ""
6564169689Skan  "s390_emit_jump (operands[0],
6565169689Skan    s390_emit_compare (<CODE>, s390_compare_op0, s390_compare_op1)); DONE;")
6566107590Sobrien
6567107590Sobrien
6568107590Sobrien;;
6569107590Sobrien;;- Conditional jump instructions.
6570107590Sobrien;;
6571107590Sobrien
6572169689Skan(define_insn "*cjump_64"
6573169689Skan  [(set (pc)
6574169689Skan        (if_then_else
6575169689Skan          (match_operator 1 "s390_comparison" [(reg CC_REGNUM) (const_int 0)])
6576169689Skan          (label_ref (match_operand 0 "" ""))
6577169689Skan          (pc)))]
6578169689Skan  "TARGET_CPU_ZARCH"
6579107590Sobrien{
6580107590Sobrien  if (get_attr_length (insn) == 4)
6581132718Skan    return "j%C1\t%l0";
6582169689Skan  else
6583132718Skan    return "jg%C1\t%l0";
6584132718Skan}
6585107590Sobrien  [(set_attr "op_type" "RI")
6586132718Skan   (set_attr "type"    "branch")
6587107590Sobrien   (set (attr "length")
6588169689Skan        (if_then_else (lt (abs (minus (pc) (match_dup 0))) (const_int 60000))
6589169689Skan                      (const_int 4) (const_int 6)))])
6590107590Sobrien
6591169689Skan(define_insn "*cjump_31"
6592169689Skan  [(set (pc)
6593169689Skan        (if_then_else
6594169689Skan          (match_operator 1 "s390_comparison" [(reg CC_REGNUM) (const_int 0)])
6595169689Skan          (label_ref (match_operand 0 "" ""))
6596169689Skan          (pc)))]
6597169689Skan  "!TARGET_CPU_ZARCH"
6598169689Skan{
6599169689Skan  gcc_assert (get_attr_length (insn) == 4);
6600169689Skan  return "j%C1\t%l0";
6601169689Skan}
6602169689Skan  [(set_attr "op_type" "RI")
6603169689Skan   (set_attr "type"    "branch")
6604169689Skan   (set (attr "length")
6605169689Skan        (if_then_else (eq (symbol_ref "flag_pic") (const_int 0))
6606169689Skan          (if_then_else (lt (abs (minus (pc) (match_dup 0))) (const_int 60000))
6607169689Skan                        (const_int 4) (const_int 6))
6608169689Skan          (if_then_else (lt (abs (minus (pc) (match_dup 0))) (const_int 60000))
6609169689Skan                        (const_int 4) (const_int 8))))])
6610169689Skan
6611107590Sobrien(define_insn "*cjump_long"
6612169689Skan  [(set (pc)
6613169689Skan        (if_then_else
6614169689Skan          (match_operator 1 "s390_comparison" [(reg CC_REGNUM) (const_int 0)])
6615169689Skan          (match_operand 0 "address_operand" "U")
6616169689Skan          (pc)))]
6617107590Sobrien  ""
6618107590Sobrien{
6619107590Sobrien  if (get_attr_op_type (insn) == OP_TYPE_RR)
6620132718Skan    return "b%C1r\t%0";
6621107590Sobrien  else
6622132718Skan    return "b%C1\t%a0";
6623132718Skan}
6624132718Skan  [(set (attr "op_type")
6625107590Sobrien        (if_then_else (match_operand 0 "register_operand" "")
6626107590Sobrien                      (const_string "RR") (const_string "RX")))
6627169689Skan   (set_attr "type"  "branch")
6628132718Skan   (set_attr "atype" "agen")])
6629107590Sobrien
6630107590Sobrien
6631107590Sobrien;;
6632107590Sobrien;;- Negated conditional jump instructions.
6633107590Sobrien;;
6634107590Sobrien
6635169689Skan(define_insn "*icjump_64"
6636169689Skan  [(set (pc)
6637169689Skan        (if_then_else
6638169689Skan          (match_operator 1 "s390_comparison" [(reg CC_REGNUM) (const_int 0)])
6639169689Skan          (pc)
6640169689Skan          (label_ref (match_operand 0 "" ""))))]
6641169689Skan  "TARGET_CPU_ZARCH"
6642132718Skan{
6643107590Sobrien  if (get_attr_length (insn) == 4)
6644132718Skan    return "j%D1\t%l0";
6645169689Skan  else
6646132718Skan    return "jg%D1\t%l0";
6647132718Skan}
6648107590Sobrien  [(set_attr "op_type" "RI")
6649132718Skan   (set_attr "type"    "branch")
6650107590Sobrien   (set (attr "length")
6651169689Skan        (if_then_else (lt (abs (minus (pc) (match_dup 0))) (const_int 60000))
6652169689Skan                      (const_int 4) (const_int 6)))])
6653107590Sobrien
6654169689Skan(define_insn "*icjump_31"
6655169689Skan  [(set (pc)
6656169689Skan        (if_then_else
6657169689Skan          (match_operator 1 "s390_comparison" [(reg CC_REGNUM) (const_int 0)])
6658169689Skan          (pc)
6659169689Skan          (label_ref (match_operand 0 "" ""))))]
6660169689Skan  "!TARGET_CPU_ZARCH"
6661169689Skan{
6662169689Skan  gcc_assert (get_attr_length (insn) == 4);
6663169689Skan  return "j%D1\t%l0";
6664169689Skan}
6665169689Skan  [(set_attr "op_type" "RI")
6666169689Skan   (set_attr "type"    "branch")
6667169689Skan   (set (attr "length")
6668169689Skan        (if_then_else (eq (symbol_ref "flag_pic") (const_int 0))
6669169689Skan          (if_then_else (lt (abs (minus (pc) (match_dup 0))) (const_int 60000))
6670169689Skan                        (const_int 4) (const_int 6))
6671169689Skan          (if_then_else (lt (abs (minus (pc) (match_dup 0))) (const_int 60000))
6672169689Skan                        (const_int 4) (const_int 8))))])
6673169689Skan
6674107590Sobrien(define_insn "*icjump_long"
6675169689Skan  [(set (pc)
6676169689Skan        (if_then_else
6677169689Skan          (match_operator 1 "s390_comparison" [(reg CC_REGNUM) (const_int 0)])
6678169689Skan          (pc)
6679169689Skan          (match_operand 0 "address_operand" "U")))]
6680107590Sobrien  ""
6681107590Sobrien{
6682107590Sobrien  if (get_attr_op_type (insn) == OP_TYPE_RR)
6683132718Skan    return "b%D1r\t%0";
6684107590Sobrien  else
6685132718Skan    return "b%D1\t%a0";
6686132718Skan}
6687132718Skan  [(set (attr "op_type")
6688107590Sobrien        (if_then_else (match_operand 0 "register_operand" "")
6689107590Sobrien                      (const_string "RR") (const_string "RX")))
6690132718Skan   (set_attr "type"  "branch")
6691132718Skan   (set_attr "atype" "agen")])
6692107590Sobrien
6693117395Skan;;
6694117395Skan;;- Trap instructions.
6695117395Skan;;
6696107590Sobrien
6697117395Skan(define_insn "trap"
6698117395Skan  [(trap_if (const_int 1) (const_int 0))]
6699117395Skan  ""
6700132718Skan  "j\t.+2"
6701169689Skan  [(set_attr "op_type" "RI")
6702132718Skan   (set_attr "type"  "branch")])
6703117395Skan
6704117395Skan(define_expand "conditional_trap"
6705169689Skan  [(trap_if (match_operand 0 "comparison_operator" "")
6706169689Skan	    (match_operand 1 "general_operand" ""))]
6707117395Skan  ""
6708117395Skan{
6709169689Skan  if (operands[1] != const0_rtx) FAIL;
6710169689Skan  operands[0] = s390_emit_compare (GET_CODE (operands[0]), 
6711169689Skan                                   s390_compare_op0, s390_compare_op1);
6712132718Skan})
6713117395Skan
6714117395Skan(define_insn "*trap"
6715169689Skan  [(trap_if (match_operator 0 "s390_comparison" [(reg CC_REGNUM) (const_int 0)])
6716117395Skan	    (const_int 0))]
6717117395Skan  ""
6718132718Skan  "j%C0\t.+2";
6719132718Skan  [(set_attr "op_type" "RI")
6720132718Skan   (set_attr "type"  "branch")])
6721117395Skan
6722107590Sobrien;;
6723117395Skan;;- Loop instructions.
6724107590Sobrien;;
6725117395Skan;;  This is all complicated by the fact that since this is a jump insn
6726117395Skan;;  we must handle our own output reloads.
6727132718Skan
6728117395Skan(define_expand "doloop_end"
6729117395Skan  [(use (match_operand 0 "" ""))        ; loop pseudo
6730117395Skan   (use (match_operand 1 "" ""))        ; iterations; zero if unknown
6731117395Skan   (use (match_operand 2 "" ""))        ; max iterations
6732117395Skan   (use (match_operand 3 "" ""))        ; loop level
6733117395Skan   (use (match_operand 4 "" ""))]       ; label
6734117395Skan  ""
6735117395Skan{
6736169689Skan  if (GET_MODE (operands[0]) == SImode && !TARGET_CPU_ZARCH)
6737169689Skan    emit_jump_insn (gen_doloop_si31 (operands[4], operands[0], operands[0]));
6738169689Skan  else if (GET_MODE (operands[0]) == SImode && TARGET_CPU_ZARCH)
6739169689Skan    emit_jump_insn (gen_doloop_si64 (operands[4], operands[0], operands[0]));
6740117395Skan  else if (GET_MODE (operands[0]) == DImode && TARGET_64BIT)
6741117395Skan    emit_jump_insn (gen_doloop_di (operands[4], operands[0], operands[0]));
6742117395Skan  else
6743117395Skan    FAIL;
6744107590Sobrien
6745117395Skan  DONE;
6746132718Skan})
6747107590Sobrien
6748169689Skan(define_insn_and_split "doloop_si64"
6749117395Skan  [(set (pc)
6750117395Skan        (if_then_else
6751169689Skan          (ne (match_operand:SI 1 "register_operand" "d,d,d")
6752117395Skan              (const_int 1))
6753117395Skan          (label_ref (match_operand 0 "" ""))
6754117395Skan          (pc)))
6755169689Skan   (set (match_operand:SI 2 "nonimmediate_operand" "=1,?X,?X")
6756117395Skan        (plus:SI (match_dup 1) (const_int -1)))
6757169689Skan   (clobber (match_scratch:SI 3 "=X,&1,&?d"))
6758169689Skan   (clobber (reg:CC CC_REGNUM))]
6759169689Skan  "TARGET_CPU_ZARCH"
6760169689Skan{
6761169689Skan  if (which_alternative != 0)
6762169689Skan    return "#";
6763169689Skan  else if (get_attr_length (insn) == 4)
6764169689Skan    return "brct\t%1,%l0";
6765169689Skan  else
6766169689Skan    return "ahi\t%1,-1\;jgne\t%l0";
6767169689Skan}
6768169689Skan  "&& reload_completed
6769169689Skan   && (! REG_P (operands[2])
6770169689Skan       || ! rtx_equal_p (operands[1], operands[2]))"
6771169689Skan  [(set (match_dup 3) (match_dup 1))
6772169689Skan   (parallel [(set (reg:CCAN CC_REGNUM)
6773169689Skan                   (compare:CCAN (plus:SI (match_dup 3) (const_int -1))
6774169689Skan                                 (const_int 0)))
6775169689Skan              (set (match_dup 3) (plus:SI (match_dup 3) (const_int -1)))])
6776169689Skan   (set (match_dup 2) (match_dup 3))
6777169689Skan   (set (pc) (if_then_else (ne (reg:CCAN CC_REGNUM) (const_int 0))
6778169689Skan                           (label_ref (match_dup 0))
6779169689Skan                           (pc)))]
6780117395Skan  ""
6781169689Skan  [(set_attr "op_type"  "RI")
6782169689Skan   (set_attr "type"  "branch")
6783169689Skan   (set (attr "length")
6784169689Skan        (if_then_else (lt (abs (minus (pc) (match_dup 0))) (const_int 60000))
6785169689Skan                      (const_int 4) (const_int 10)))])
6786169689Skan
6787169689Skan(define_insn_and_split "doloop_si31"
6788169689Skan  [(set (pc)
6789169689Skan        (if_then_else
6790169689Skan          (ne (match_operand:SI 1 "register_operand" "d,d,d")
6791169689Skan              (const_int 1))
6792169689Skan          (label_ref (match_operand 0 "" ""))
6793169689Skan          (pc)))
6794169689Skan   (set (match_operand:SI 2 "nonimmediate_operand" "=1,?X,?X")
6795169689Skan        (plus:SI (match_dup 1) (const_int -1)))
6796169689Skan   (clobber (match_scratch:SI 3 "=X,&1,&?d"))
6797169689Skan   (clobber (reg:CC CC_REGNUM))]
6798169689Skan  "!TARGET_CPU_ZARCH"
6799117395Skan{
6800117395Skan  if (which_alternative != 0)
6801132718Skan    return "#";
6802117395Skan  else if (get_attr_length (insn) == 4)
6803132718Skan    return "brct\t%1,%l0";
6804117395Skan  else
6805169689Skan    gcc_unreachable ();
6806132718Skan}
6807169689Skan  "&& reload_completed
6808169689Skan   && (! REG_P (operands[2])
6809169689Skan       || ! rtx_equal_p (operands[1], operands[2]))"
6810169689Skan  [(set (match_dup 3) (match_dup 1))
6811169689Skan   (parallel [(set (reg:CCAN CC_REGNUM)
6812169689Skan                   (compare:CCAN (plus:SI (match_dup 3) (const_int -1))
6813169689Skan                                 (const_int 0)))
6814169689Skan              (set (match_dup 3) (plus:SI (match_dup 3) (const_int -1)))])
6815169689Skan   (set (match_dup 2) (match_dup 3))
6816169689Skan   (set (pc) (if_then_else (ne (reg:CCAN CC_REGNUM) (const_int 0))
6817169689Skan                           (label_ref (match_dup 0))
6818169689Skan                           (pc)))]
6819169689Skan  ""
6820117395Skan  [(set_attr "op_type"  "RI")
6821132718Skan   (set_attr "type"  "branch")
6822117395Skan   (set (attr "length")
6823169689Skan        (if_then_else (eq (symbol_ref "flag_pic") (const_int 0))
6824169689Skan          (if_then_else (lt (abs (minus (pc) (match_dup 0))) (const_int 60000))
6825169689Skan                        (const_int 4) (const_int 6))
6826169689Skan          (if_then_else (lt (abs (minus (pc) (match_dup 0))) (const_int 60000))
6827169689Skan                        (const_int 4) (const_int 8))))])
6828107590Sobrien
6829117395Skan(define_insn "*doloop_si_long"
6830117395Skan  [(set (pc)
6831117395Skan        (if_then_else
6832169689Skan          (ne (match_operand:SI 1 "register_operand" "d")
6833117395Skan              (const_int 1))
6834169689Skan          (match_operand 0 "address_operand" "U")
6835117395Skan          (pc)))
6836169689Skan   (set (match_operand:SI 2 "register_operand" "=1")
6837117395Skan        (plus:SI (match_dup 1) (const_int -1)))
6838169689Skan   (clobber (match_scratch:SI 3 "=X"))
6839169689Skan   (clobber (reg:CC CC_REGNUM))]
6840169689Skan  "!TARGET_CPU_ZARCH"
6841117395Skan{
6842117395Skan  if (get_attr_op_type (insn) == OP_TYPE_RR)
6843132718Skan    return "bctr\t%1,%0";
6844117395Skan  else
6845132718Skan    return "bct\t%1,%a0";
6846132718Skan}
6847132718Skan  [(set (attr "op_type")
6848117395Skan        (if_then_else (match_operand 0 "register_operand" "")
6849117395Skan                      (const_string "RR") (const_string "RX")))
6850132718Skan   (set_attr "type"  "branch")
6851132718Skan   (set_attr "atype" "agen")])
6852117395Skan
6853169689Skan(define_insn_and_split "doloop_di"
6854117395Skan  [(set (pc)
6855117395Skan        (if_then_else
6856169689Skan          (ne (match_operand:DI 1 "register_operand" "d,d,d")
6857117395Skan              (const_int 1))
6858117395Skan          (label_ref (match_operand 0 "" ""))
6859117395Skan          (pc)))
6860169689Skan   (set (match_operand:DI 2 "nonimmediate_operand" "=1,?X,?X")
6861117395Skan        (plus:DI (match_dup 1) (const_int -1)))
6862169689Skan   (clobber (match_scratch:DI 3 "=X,&1,&?d"))
6863169689Skan   (clobber (reg:CC CC_REGNUM))]
6864117395Skan  "TARGET_64BIT"
6865117395Skan{
6866117395Skan  if (which_alternative != 0)
6867132718Skan    return "#";
6868117395Skan  else if (get_attr_length (insn) == 4)
6869132718Skan    return "brctg\t%1,%l0";
6870117395Skan  else
6871132718Skan    return "aghi\t%1,-1\;jgne\t%l0";
6872132718Skan}
6873169689Skan  "&& reload_completed
6874117395Skan   && (! REG_P (operands[2])
6875117395Skan       || ! rtx_equal_p (operands[1], operands[2]))"
6876117395Skan  [(set (match_dup 3) (match_dup 1))
6877169689Skan   (parallel [(set (reg:CCAN CC_REGNUM)
6878117395Skan                   (compare:CCAN (plus:DI (match_dup 3) (const_int -1))
6879117395Skan                                 (const_int 0)))
6880117395Skan              (set (match_dup 3) (plus:DI (match_dup 3) (const_int -1)))])
6881117395Skan   (set (match_dup 2) (match_dup 3))
6882169689Skan   (set (pc) (if_then_else (ne (reg:CCAN CC_REGNUM) (const_int 0))
6883169689Skan                           (label_ref (match_dup 0))
6884117395Skan                           (pc)))]
6885169689Skan  ""
6886169689Skan  [(set_attr "op_type"  "RI")
6887169689Skan   (set_attr "type"  "branch")
6888169689Skan   (set (attr "length")
6889169689Skan        (if_then_else (lt (abs (minus (pc) (match_dup 0))) (const_int 60000))
6890169689Skan                      (const_int 4) (const_int 10)))])
6891117395Skan
6892107590Sobrien;;
6893107590Sobrien;;- Unconditional jump instructions.
6894107590Sobrien;;
6895107590Sobrien
6896107590Sobrien;
6897107590Sobrien; jump instruction pattern(s).
6898107590Sobrien;
6899107590Sobrien
6900169689Skan(define_expand "jump"
6901169689Skan  [(match_operand 0 "" "")]
6902169689Skan  ""
6903169689Skan  "s390_emit_jump (operands[0], NULL_RTX); DONE;")
6904169689Skan
6905169689Skan(define_insn "*jump64"
6906107590Sobrien  [(set (pc) (label_ref (match_operand 0 "" "")))]
6907169689Skan  "TARGET_CPU_ZARCH"
6908107590Sobrien{
6909107590Sobrien  if (get_attr_length (insn) == 4)
6910132718Skan    return "j\t%l0";
6911169689Skan  else
6912132718Skan    return "jg\t%l0";
6913132718Skan}
6914107590Sobrien  [(set_attr "op_type" "RI")
6915132718Skan   (set_attr "type"  "branch")
6916107590Sobrien   (set (attr "length")
6917169689Skan        (if_then_else (lt (abs (minus (pc) (match_dup 0))) (const_int 60000))
6918169689Skan                      (const_int 4) (const_int 6)))])
6919107590Sobrien
6920169689Skan(define_insn "*jump31"
6921169689Skan  [(set (pc) (label_ref (match_operand 0 "" "")))]
6922169689Skan  "!TARGET_CPU_ZARCH"
6923169689Skan{
6924169689Skan  gcc_assert (get_attr_length (insn) == 4);
6925169689Skan  return "j\t%l0";
6926169689Skan}
6927169689Skan  [(set_attr "op_type" "RI")
6928169689Skan   (set_attr "type"  "branch")
6929169689Skan   (set (attr "length")
6930169689Skan        (if_then_else (eq (symbol_ref "flag_pic") (const_int 0))
6931169689Skan          (if_then_else (lt (abs (minus (pc) (match_dup 0))) (const_int 60000))
6932169689Skan                        (const_int 4) (const_int 6))
6933169689Skan          (if_then_else (lt (abs (minus (pc) (match_dup 0))) (const_int 60000))
6934169689Skan                        (const_int 4) (const_int 8))))])
6935169689Skan
6936107590Sobrien;
6937107590Sobrien; indirect-jump instruction pattern(s).
6938107590Sobrien;
6939107590Sobrien
6940107590Sobrien(define_insn "indirect_jump"
6941132718Skan [(set (pc) (match_operand 0 "address_operand" "U"))]
6942107590Sobrien  ""
6943107590Sobrien{
6944107590Sobrien  if (get_attr_op_type (insn) == OP_TYPE_RR)
6945132718Skan    return "br\t%0";
6946107590Sobrien  else
6947132718Skan    return "b\t%a0";
6948132718Skan}
6949132718Skan  [(set (attr "op_type")
6950107590Sobrien        (if_then_else (match_operand 0 "register_operand" "")
6951107590Sobrien                      (const_string "RR") (const_string "RX")))
6952132718Skan   (set_attr "type"  "branch")
6953132718Skan   (set_attr "atype" "agen")])
6954107590Sobrien
6955107590Sobrien;
6956107590Sobrien; casesi instruction pattern(s).
6957107590Sobrien;
6958107590Sobrien
6959107590Sobrien(define_insn "casesi_jump"
6960132718Skan [(set (pc) (match_operand 0 "address_operand" "U"))
6961107590Sobrien   (use (label_ref (match_operand 1 "" "")))]
6962107590Sobrien  ""
6963107590Sobrien{
6964107590Sobrien  if (get_attr_op_type (insn) == OP_TYPE_RR)
6965132718Skan    return "br\t%0";
6966107590Sobrien  else
6967132718Skan    return "b\t%a0";
6968132718Skan}
6969132718Skan  [(set (attr "op_type")
6970107590Sobrien        (if_then_else (match_operand 0 "register_operand" "")
6971107590Sobrien                      (const_string "RR") (const_string "RX")))
6972132718Skan   (set_attr "type"  "branch")
6973132718Skan   (set_attr "atype" "agen")])
6974107590Sobrien
6975107590Sobrien(define_expand "casesi"
6976107590Sobrien  [(match_operand:SI 0 "general_operand" "")
6977107590Sobrien   (match_operand:SI 1 "general_operand" "")
6978107590Sobrien   (match_operand:SI 2 "general_operand" "")
6979107590Sobrien   (label_ref (match_operand 3 "" ""))
6980107590Sobrien   (label_ref (match_operand 4 "" ""))]
6981107590Sobrien  ""
6982107590Sobrien{
6983107590Sobrien   rtx index  = gen_reg_rtx (SImode);
6984107590Sobrien   rtx base   = gen_reg_rtx (Pmode);
6985107590Sobrien   rtx target = gen_reg_rtx (Pmode);
6986107590Sobrien
6987107590Sobrien   emit_move_insn (index, operands[0]);
6988107590Sobrien   emit_insn (gen_subsi3 (index, index, operands[1]));
6989107590Sobrien   emit_cmp_and_jump_insns (index, operands[2], GTU, NULL_RTX, SImode, 1,
6990107590Sobrien                            operands[4]);
6991107590Sobrien
6992107590Sobrien   if (Pmode != SImode)
6993107590Sobrien     index = convert_to_mode (Pmode, index, 1);
6994107590Sobrien   if (GET_CODE (index) != REG)
6995107590Sobrien     index = copy_to_mode_reg (Pmode, index);
6996107590Sobrien
6997107590Sobrien   if (TARGET_64BIT)
6998107590Sobrien       emit_insn (gen_ashldi3 (index, index, GEN_INT (3)));
6999107590Sobrien   else
7000169689Skan       emit_insn (gen_ashlsi3 (index, index, const2_rtx));
7001107590Sobrien
7002107590Sobrien   emit_move_insn (base, gen_rtx_LABEL_REF (Pmode, operands[3]));
7003107590Sobrien
7004169689Skan   index = gen_const_mem (Pmode, gen_rtx_PLUS (Pmode, base, index));
7005107590Sobrien   emit_move_insn (target, index);
7006107590Sobrien
7007107590Sobrien   if (flag_pic)
7008107590Sobrien     target = gen_rtx_PLUS (Pmode, base, target);
7009107590Sobrien   emit_jump_insn (gen_casesi_jump (target, operands[3]));
7010107590Sobrien
7011107590Sobrien   DONE;
7012132718Skan})
7013107590Sobrien
7014107590Sobrien
7015107590Sobrien;;
7016107590Sobrien;;- Jump to subroutine.
7017107590Sobrien;;
7018107590Sobrien;;
7019107590Sobrien
7020107590Sobrien;
7021107590Sobrien; untyped call instruction pattern(s).
7022107590Sobrien;
7023107590Sobrien
7024107590Sobrien;; Call subroutine returning any type.
7025107590Sobrien(define_expand "untyped_call"
7026107590Sobrien  [(parallel [(call (match_operand 0 "" "")
7027107590Sobrien                    (const_int 0))
7028107590Sobrien              (match_operand 1 "" "")
7029107590Sobrien              (match_operand 2 "" "")])]
7030107590Sobrien  ""
7031107590Sobrien{
7032107590Sobrien  int i;
7033107590Sobrien
7034107590Sobrien  emit_call_insn (gen_call (operands[0], const0_rtx, const0_rtx));
7035107590Sobrien
7036107590Sobrien  for (i = 0; i < XVECLEN (operands[2], 0); i++)
7037107590Sobrien    {
7038107590Sobrien      rtx set = XVECEXP (operands[2], 0, i);
7039107590Sobrien      emit_move_insn (SET_DEST (set), SET_SRC (set));
7040107590Sobrien    }
7041107590Sobrien
7042107590Sobrien  /* The optimizer does not know that the call sets the function value
7043107590Sobrien     registers we stored in the result block.  We avoid problems by
7044107590Sobrien     claiming that all hard registers are used and clobbered at this
7045107590Sobrien     point.  */
7046107590Sobrien  emit_insn (gen_blockage ());
7047107590Sobrien
7048107590Sobrien  DONE;
7049132718Skan})
7050107590Sobrien
7051107590Sobrien;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
7052107590Sobrien;; all of memory.  This blocks insns from being moved across this point.
7053107590Sobrien
7054107590Sobrien(define_insn "blockage"
7055132718Skan  [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
7056107590Sobrien  ""
7057107590Sobrien  ""
7058117395Skan  [(set_attr "type"    "none")
7059117395Skan   (set_attr "length"  "0")])
7060107590Sobrien
7061169689Skan;
7062169689Skan; sibcall patterns
7063169689Skan;
7064107590Sobrien
7065169689Skan(define_expand "sibcall"
7066169689Skan  [(call (match_operand 0 "" "")
7067169689Skan	 (match_operand 1 "" ""))]
7068169689Skan  ""
7069169689Skan{
7070169689Skan  s390_emit_call (XEXP (operands[0], 0), NULL_RTX, NULL_RTX, NULL_RTX);
7071169689Skan  DONE;
7072169689Skan})
7073107590Sobrien
7074169689Skan(define_insn "*sibcall_br"
7075169689Skan  [(call (mem:QI (reg SIBCALL_REGNUM))
7076169689Skan         (match_operand 0 "const_int_operand" "n"))]
7077169689Skan  "SIBLING_CALL_P (insn)
7078169689Skan   && GET_MODE (XEXP (XEXP (PATTERN (insn), 0), 0)) == Pmode"
7079169689Skan  "br\t%%r1"
7080169689Skan  [(set_attr "op_type" "RR")
7081169689Skan   (set_attr "type"  "branch")
7082169689Skan   (set_attr "atype" "agen")])
7083169689Skan
7084169689Skan(define_insn "*sibcall_brc"
7085169689Skan  [(call (mem:QI (match_operand 0 "bras_sym_operand" "X"))
7086169689Skan         (match_operand 1 "const_int_operand" "n"))]
7087169689Skan  "SIBLING_CALL_P (insn) && TARGET_SMALL_EXEC"
7088169689Skan  "j\t%0"
7089169689Skan  [(set_attr "op_type" "RI")
7090169689Skan   (set_attr "type"    "branch")])
7091169689Skan
7092169689Skan(define_insn "*sibcall_brcl"
7093169689Skan  [(call (mem:QI (match_operand 0 "bras_sym_operand" "X"))
7094169689Skan         (match_operand 1 "const_int_operand" "n"))]
7095169689Skan  "SIBLING_CALL_P (insn) && TARGET_CPU_ZARCH"
7096169689Skan  "jg\t%0"
7097169689Skan  [(set_attr "op_type" "RIL")
7098169689Skan   (set_attr "type"    "branch")])
7099169689Skan
7100107590Sobrien;
7101169689Skan; sibcall_value patterns
7102107590Sobrien;
7103107590Sobrien
7104169689Skan(define_expand "sibcall_value"
7105169689Skan  [(set (match_operand 0 "" "")
7106169689Skan	(call (match_operand 1 "" "")
7107169689Skan	      (match_operand 2 "" "")))]
7108107590Sobrien  ""
7109107590Sobrien{
7110169689Skan  s390_emit_call (XEXP (operands[1], 0), NULL_RTX, operands[0], NULL_RTX);
7111169689Skan  DONE;
7112169689Skan})
7113107590Sobrien
7114169689Skan(define_insn "*sibcall_value_br"
7115169689Skan  [(set (match_operand 0 "" "")
7116169689Skan	(call (mem:QI (reg SIBCALL_REGNUM))
7117169689Skan	      (match_operand 1 "const_int_operand" "n")))]
7118169689Skan  "SIBLING_CALL_P (insn)
7119169689Skan   && GET_MODE (XEXP (XEXP (XEXP (PATTERN (insn), 1), 0), 0)) == Pmode"
7120169689Skan  "br\t%%r1"
7121169689Skan  [(set_attr "op_type" "RR")
7122169689Skan   (set_attr "type"  "branch")
7123169689Skan   (set_attr "atype" "agen")])
7124107590Sobrien
7125169689Skan(define_insn "*sibcall_value_brc"
7126169689Skan  [(set (match_operand 0 "" "")
7127169689Skan	(call (mem:QI (match_operand 1 "bras_sym_operand" "X"))
7128169689Skan	      (match_operand 2 "const_int_operand" "n")))]
7129169689Skan  "SIBLING_CALL_P (insn) && TARGET_SMALL_EXEC"
7130169689Skan  "j\t%1"
7131169689Skan  [(set_attr "op_type" "RI")
7132169689Skan   (set_attr "type"    "branch")])
7133107590Sobrien
7134169689Skan(define_insn "*sibcall_value_brcl"
7135169689Skan  [(set (match_operand 0 "" "")
7136169689Skan	(call (mem:QI (match_operand 1 "bras_sym_operand" "X"))
7137169689Skan	      (match_operand 2 "const_int_operand" "n")))]
7138169689Skan  "SIBLING_CALL_P (insn) && TARGET_CPU_ZARCH"
7139169689Skan  "jg\t%1"
7140169689Skan  [(set_attr "op_type" "RIL")
7141169689Skan   (set_attr "type"    "branch")])
7142107590Sobrien
7143107590Sobrien
7144169689Skan;
7145169689Skan; call instruction pattern(s).
7146169689Skan;
7147107590Sobrien
7148169689Skan(define_expand "call"
7149169689Skan  [(call (match_operand 0 "" "")
7150169689Skan         (match_operand 1 "" ""))
7151169689Skan   (use (match_operand 2 "" ""))]
7152169689Skan  ""
7153169689Skan{
7154169689Skan  s390_emit_call (XEXP (operands[0], 0), NULL_RTX, NULL_RTX,
7155169689Skan		  gen_rtx_REG (Pmode, RETURN_REGNUM));
7156107590Sobrien  DONE;
7157132718Skan})
7158107590Sobrien
7159132718Skan(define_insn "*bras"
7160132718Skan  [(call (mem:QI (match_operand 0 "bras_sym_operand" "X"))
7161132718Skan         (match_operand 1 "const_int_operand" "n"))
7162132718Skan   (clobber (match_operand 2 "register_operand" "=r"))]
7163169689Skan  "!SIBLING_CALL_P (insn)
7164169689Skan   && TARGET_SMALL_EXEC
7165169689Skan   && GET_MODE (operands[2]) == Pmode"
7166132718Skan  "bras\t%2,%0"
7167132718Skan  [(set_attr "op_type" "RI")
7168107590Sobrien   (set_attr "type"    "jsr")])
7169107590Sobrien
7170132718Skan(define_insn "*brasl"
7171132718Skan  [(call (mem:QI (match_operand 0 "bras_sym_operand" "X"))
7172132718Skan         (match_operand 1 "const_int_operand" "n"))
7173132718Skan   (clobber (match_operand 2 "register_operand" "=r"))]
7174169689Skan  "!SIBLING_CALL_P (insn)
7175169689Skan   && TARGET_CPU_ZARCH
7176169689Skan   && GET_MODE (operands[2]) == Pmode"
7177132718Skan  "brasl\t%2,%0"
7178132718Skan  [(set_attr "op_type" "RIL")
7179107590Sobrien   (set_attr "type"    "jsr")])
7180107590Sobrien
7181132718Skan(define_insn "*basr"
7182132718Skan  [(call (mem:QI (match_operand 0 "address_operand" "U"))
7183132718Skan         (match_operand 1 "const_int_operand" "n"))
7184132718Skan   (clobber (match_operand 2 "register_operand" "=r"))]
7185169689Skan  "!SIBLING_CALL_P (insn) && GET_MODE (operands[2]) == Pmode"
7186132718Skan{
7187132718Skan  if (get_attr_op_type (insn) == OP_TYPE_RR)
7188132718Skan    return "basr\t%2,%0";
7189132718Skan  else
7190132718Skan    return "bas\t%2,%a0";
7191132718Skan}
7192132718Skan  [(set (attr "op_type")
7193132718Skan        (if_then_else (match_operand 0 "register_operand" "")
7194132718Skan                      (const_string "RR") (const_string "RX")))
7195132718Skan   (set_attr "type"  "jsr")
7196132718Skan   (set_attr "atype" "agen")])
7197107590Sobrien
7198107590Sobrien;
7199107590Sobrien; call_value instruction pattern(s).
7200107590Sobrien;
7201107590Sobrien
7202107590Sobrien(define_expand "call_value"
7203107590Sobrien  [(set (match_operand 0 "" "")
7204107590Sobrien        (call (match_operand 1 "" "")
7205107590Sobrien              (match_operand 2 "" "")))
7206107590Sobrien   (use (match_operand 3 "" ""))]
7207107590Sobrien  ""
7208107590Sobrien{
7209169689Skan  s390_emit_call (XEXP (operands[1], 0), NULL_RTX, operands[0],
7210169689Skan		  gen_rtx_REG (Pmode, RETURN_REGNUM));
7211107590Sobrien  DONE;
7212132718Skan})
7213107590Sobrien
7214132718Skan(define_insn "*bras_r"
7215132718Skan  [(set (match_operand 0 "" "")
7216132718Skan        (call (mem:QI (match_operand 1 "bras_sym_operand" "X"))
7217107590Sobrien              (match_operand:SI 2 "const_int_operand" "n")))
7218132718Skan   (clobber (match_operand 3 "register_operand" "=r"))]
7219169689Skan  "!SIBLING_CALL_P (insn)
7220169689Skan   && TARGET_SMALL_EXEC
7221169689Skan   && GET_MODE (operands[3]) == Pmode"
7222132718Skan  "bras\t%3,%1"
7223107590Sobrien  [(set_attr "op_type" "RI")
7224107590Sobrien   (set_attr "type"    "jsr")])
7225107590Sobrien
7226132718Skan(define_insn "*brasl_r"
7227132718Skan  [(set (match_operand 0 "" "")
7228132718Skan        (call (mem:QI (match_operand 1 "bras_sym_operand" "X"))
7229132718Skan              (match_operand 2 "const_int_operand" "n")))
7230132718Skan   (clobber (match_operand 3 "register_operand" "=r"))]
7231169689Skan  "!SIBLING_CALL_P (insn)
7232169689Skan   && TARGET_CPU_ZARCH
7233169689Skan   && GET_MODE (operands[3]) == Pmode"
7234132718Skan  "brasl\t%3,%1"
7235132718Skan  [(set_attr "op_type" "RIL")
7236107590Sobrien   (set_attr "type"    "jsr")])
7237107590Sobrien
7238132718Skan(define_insn "*basr_r"
7239132718Skan  [(set (match_operand 0 "" "")
7240132718Skan        (call (mem:QI (match_operand 1 "address_operand" "U"))
7241132718Skan              (match_operand 2 "const_int_operand" "n")))
7242132718Skan   (clobber (match_operand 3 "register_operand" "=r"))]
7243169689Skan  "!SIBLING_CALL_P (insn) && GET_MODE (operands[3]) == Pmode"
7244132718Skan{
7245132718Skan  if (get_attr_op_type (insn) == OP_TYPE_RR)
7246132718Skan    return "basr\t%3,%1";
7247132718Skan  else
7248132718Skan    return "bas\t%3,%a1";
7249132718Skan}
7250132718Skan  [(set (attr "op_type")
7251132718Skan        (if_then_else (match_operand 1 "register_operand" "")
7252132718Skan                      (const_string "RR") (const_string "RX")))
7253132718Skan   (set_attr "type"  "jsr")
7254132718Skan   (set_attr "atype" "agen")])
7255107590Sobrien
7256117395Skan;;
7257117395Skan;;- Thread-local storage support.
7258117395Skan;;
7259107590Sobrien
7260169689Skan(define_expand "get_tp_64"
7261169689Skan  [(set (match_operand:DI 0 "nonimmediate_operand" "") (reg:DI TP_REGNUM))]
7262117395Skan  "TARGET_64BIT"
7263169689Skan  "")
7264117395Skan
7265169689Skan(define_expand "get_tp_31"
7266169689Skan  [(set (match_operand:SI 0 "nonimmediate_operand" "") (reg:SI TP_REGNUM))]
7267117395Skan  "!TARGET_64BIT"
7268169689Skan  "")
7269117395Skan
7270169689Skan(define_expand "set_tp_64"
7271169689Skan  [(set (reg:DI TP_REGNUM) (match_operand:DI 0 "nonimmediate_operand" ""))
7272169689Skan   (set (reg:DI TP_REGNUM) (unspec_volatile:DI [(reg:DI TP_REGNUM)] UNSPECV_SET_TP))]
7273117395Skan  "TARGET_64BIT"
7274169689Skan  "")
7275117395Skan
7276169689Skan(define_expand "set_tp_31"
7277169689Skan  [(set (reg:SI TP_REGNUM) (match_operand:SI 0 "nonimmediate_operand" ""))
7278169689Skan   (set (reg:SI TP_REGNUM) (unspec_volatile:SI [(reg:SI TP_REGNUM)] UNSPECV_SET_TP))]
7279117395Skan  "!TARGET_64BIT"
7280169689Skan  "")
7281132718Skan
7282169689Skan(define_insn "*set_tp"
7283169689Skan  [(set (reg TP_REGNUM) (unspec_volatile [(reg TP_REGNUM)] UNSPECV_SET_TP))]
7284169689Skan  ""
7285169689Skan  ""
7286169689Skan  [(set_attr "type" "none")
7287169689Skan   (set_attr "length" "0")])
7288169689Skan
7289117395Skan(define_insn "*tls_load_64"
7290117395Skan  [(set (match_operand:DI 0 "register_operand" "=d")
7291117395Skan        (unspec:DI [(match_operand:DI 1 "memory_operand" "m")
7292117395Skan                    (match_operand:DI 2 "" "")]
7293117395Skan		   UNSPEC_TLS_LOAD))]
7294117395Skan  "TARGET_64BIT"
7295132718Skan  "lg\t%0,%1%J2"
7296132718Skan  [(set_attr "op_type" "RXE")])
7297117395Skan
7298117395Skan(define_insn "*tls_load_31"
7299132718Skan  [(set (match_operand:SI 0 "register_operand" "=d,d")
7300132718Skan        (unspec:SI [(match_operand:SI 1 "memory_operand" "R,T")
7301117395Skan                    (match_operand:SI 2 "" "")]
7302117395Skan		   UNSPEC_TLS_LOAD))]
7303117395Skan  "!TARGET_64BIT"
7304132718Skan  "@
7305132718Skan   l\t%0,%1%J2
7306132718Skan   ly\t%0,%1%J2"
7307132718Skan  [(set_attr "op_type" "RX,RXY")])
7308117395Skan
7309132718Skan(define_insn "*bras_tls"
7310132718Skan  [(set (match_operand 0 "" "")
7311132718Skan        (call (mem:QI (match_operand 1 "bras_sym_operand" "X"))
7312132718Skan              (match_operand 2 "const_int_operand" "n")))
7313132718Skan   (clobber (match_operand 3 "register_operand" "=r"))
7314132718Skan   (use (match_operand 4 "" ""))]
7315169689Skan  "!SIBLING_CALL_P (insn)
7316169689Skan   && TARGET_SMALL_EXEC
7317169689Skan   && GET_MODE (operands[3]) == Pmode"
7318132718Skan  "bras\t%3,%1%J4"
7319117395Skan  [(set_attr "op_type" "RI")
7320117395Skan   (set_attr "type"    "jsr")])
7321117395Skan
7322132718Skan(define_insn "*brasl_tls"
7323132718Skan  [(set (match_operand 0 "" "")
7324132718Skan        (call (mem:QI (match_operand 1 "bras_sym_operand" "X"))
7325132718Skan              (match_operand 2 "const_int_operand" "n")))
7326132718Skan   (clobber (match_operand 3 "register_operand" "=r"))
7327132718Skan   (use (match_operand 4 "" ""))]
7328169689Skan  "!SIBLING_CALL_P (insn)
7329169689Skan   && TARGET_CPU_ZARCH
7330169689Skan   && GET_MODE (operands[3]) == Pmode"
7331132718Skan  "brasl\t%3,%1%J4"
7332132718Skan  [(set_attr "op_type" "RIL")
7333117395Skan   (set_attr "type"    "jsr")])
7334117395Skan
7335132718Skan(define_insn "*basr_tls"
7336132718Skan  [(set (match_operand 0 "" "")
7337132718Skan        (call (mem:QI (match_operand 1 "address_operand" "U"))
7338132718Skan              (match_operand 2 "const_int_operand" "n")))
7339132718Skan   (clobber (match_operand 3 "register_operand" "=r"))
7340132718Skan   (use (match_operand 4 "" ""))]
7341169689Skan  "!SIBLING_CALL_P (insn) && GET_MODE (operands[3]) == Pmode"
7342132718Skan{
7343132718Skan  if (get_attr_op_type (insn) == OP_TYPE_RR)
7344132718Skan    return "basr\t%3,%1%J4";
7345132718Skan  else
7346132718Skan    return "bas\t%3,%a1%J4";
7347132718Skan}
7348132718Skan  [(set (attr "op_type")
7349132718Skan        (if_then_else (match_operand 1 "register_operand" "")
7350132718Skan                      (const_string "RR") (const_string "RX")))
7351132718Skan   (set_attr "type"  "jsr")
7352132718Skan   (set_attr "atype" "agen")])
7353117395Skan
7354107590Sobrien;;
7355169689Skan;;- Atomic operations
7356169689Skan;;
7357169689Skan
7358169689Skan;
7359169689Skan; memory barrier pattern.
7360169689Skan;
7361169689Skan
7362169689Skan(define_expand "memory_barrier"
7363169689Skan  [(set (mem:BLK (match_dup 0))
7364169689Skan	(unspec_volatile:BLK [(mem:BLK (match_dup 0))] UNSPECV_MB))]
7365169689Skan  ""
7366169689Skan{
7367169689Skan  operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (DImode));
7368169689Skan  MEM_VOLATILE_P (operands[0]) = 1;
7369169689Skan})
7370169689Skan
7371169689Skan(define_insn "*memory_barrier"
7372169689Skan  [(set (match_operand:BLK 0 "" "")
7373169689Skan	(unspec_volatile:BLK [(match_operand:BLK 1 "" "")] UNSPECV_MB))]
7374169689Skan  ""
7375169689Skan  "bcr\t15,0"
7376169689Skan  [(set_attr "op_type" "RR")])
7377169689Skan
7378169689Skan;
7379169689Skan; compare and swap patterns.
7380169689Skan;
7381169689Skan
7382169689Skan(define_expand "sync_compare_and_swap<mode>"
7383169689Skan  [(parallel
7384169689Skan    [(set (match_operand:TDSI 0 "register_operand" "")
7385169689Skan	  (match_operand:TDSI 1 "memory_operand" ""))
7386169689Skan     (set (match_dup 1)
7387169689Skan	  (unspec_volatile:TDSI
7388169689Skan	    [(match_dup 1)
7389169689Skan	     (match_operand:TDSI 2 "register_operand" "")
7390169689Skan	     (match_operand:TDSI 3 "register_operand" "")]
7391169689Skan	    UNSPECV_CAS))
7392169689Skan     (set (reg:CCZ1 CC_REGNUM)
7393169689Skan	  (compare:CCZ1 (match_dup 1) (match_dup 2)))])]
7394169689Skan  "")
7395169689Skan
7396169689Skan(define_expand "sync_compare_and_swap<mode>"
7397169689Skan  [(parallel
7398169689Skan    [(set (match_operand:HQI 0 "register_operand" "")
7399169689Skan	  (match_operand:HQI 1 "memory_operand" ""))
7400169689Skan     (set (match_dup 1)
7401169689Skan	  (unspec_volatile:HQI
7402169689Skan	    [(match_dup 1)
7403169689Skan	     (match_operand:HQI 2 "general_operand" "")
7404169689Skan	     (match_operand:HQI 3 "general_operand" "")]
7405169689Skan	    UNSPECV_CAS))
7406169689Skan     (set (reg:CCZ1 CC_REGNUM)
7407169689Skan	  (compare:CCZ1 (match_dup 1) (match_dup 2)))])]
7408169689Skan  ""
7409169689Skan  "s390_expand_cs_hqi (<MODE>mode, operands[0], operands[1], 
7410169689Skan		       operands[2], operands[3]); DONE;")
7411169689Skan
7412169689Skan(define_expand "sync_compare_and_swap_cc<mode>"
7413169689Skan  [(parallel
7414169689Skan    [(set (match_operand:TDSI 0 "register_operand" "")
7415169689Skan	  (match_operand:TDSI 1 "memory_operand" ""))
7416169689Skan     (set (match_dup 1)
7417169689Skan	  (unspec_volatile:TDSI
7418169689Skan	    [(match_dup 1)
7419169689Skan	     (match_operand:TDSI 2 "register_operand" "")
7420169689Skan	     (match_operand:TDSI 3 "register_operand" "")]
7421169689Skan	    UNSPECV_CAS))
7422169689Skan     (set (match_dup 4)
7423169689Skan	  (compare:CCZ1 (match_dup 1) (match_dup 2)))])]
7424169689Skan  ""
7425169689Skan{
7426169689Skan  /* Emulate compare.  */
7427169689Skan  operands[4] = gen_rtx_REG (CCZ1mode, CC_REGNUM);
7428169689Skan  s390_compare_op0 = operands[1];
7429169689Skan  s390_compare_op1 = operands[2];
7430169689Skan  s390_compare_emitted = operands[4];
7431169689Skan})
7432169689Skan
7433169689Skan; cds, cdsg
7434169689Skan(define_insn "*sync_compare_and_swap<mode>"
7435169689Skan  [(set (match_operand:DP 0 "register_operand" "=r")
7436169689Skan	(match_operand:DP 1 "memory_operand" "+Q"))
7437169689Skan   (set (match_dup 1)
7438169689Skan	(unspec_volatile:DP
7439169689Skan	  [(match_dup 1)
7440169689Skan	   (match_operand:DP 2 "register_operand" "0")
7441169689Skan	   (match_operand:DP 3 "register_operand" "r")]
7442169689Skan	  UNSPECV_CAS))
7443169689Skan   (set (reg:CCZ1 CC_REGNUM)
7444169689Skan	(compare:CCZ1 (match_dup 1) (match_dup 2)))]
7445169689Skan  ""
7446169689Skan  "cds<tg>\t%0,%3,%S1"
7447169689Skan  [(set_attr "op_type" "RS<TE>")
7448169689Skan   (set_attr "type"   "sem")])
7449169689Skan
7450169689Skan; cs, csg
7451169689Skan(define_insn "*sync_compare_and_swap<mode>"
7452169689Skan  [(set (match_operand:GPR 0 "register_operand" "=r")
7453169689Skan	(match_operand:GPR 1 "memory_operand" "+Q"))
7454169689Skan   (set (match_dup 1)
7455169689Skan	(unspec_volatile:GPR
7456169689Skan	  [(match_dup 1)
7457169689Skan	   (match_operand:GPR 2 "register_operand" "0")
7458169689Skan	   (match_operand:GPR 3 "register_operand" "r")]
7459169689Skan	  UNSPECV_CAS))
7460169689Skan   (set (reg:CCZ1 CC_REGNUM)
7461169689Skan	(compare:CCZ1 (match_dup 1) (match_dup 2)))]
7462169689Skan  "" 
7463169689Skan  "cs<g>\t%0,%3,%S1"
7464169689Skan  [(set_attr "op_type" "RS<E>")
7465169689Skan   (set_attr "type"   "sem")])
7466169689Skan
7467169689Skan
7468169689Skan;
7469169689Skan; Other atomic instruction patterns.
7470169689Skan;
7471169689Skan
7472169689Skan(define_expand "sync_lock_test_and_set<mode>"
7473169689Skan  [(match_operand:HQI 0 "register_operand")
7474169689Skan   (match_operand:HQI 1 "memory_operand")
7475169689Skan   (match_operand:HQI 2 "general_operand")]
7476169689Skan  ""
7477169689Skan  "s390_expand_atomic (<MODE>mode, SET, operands[0], operands[1], 
7478169689Skan		       operands[2], false); DONE;")
7479169689Skan
7480169689Skan(define_expand "sync_<atomic><mode>"
7481169689Skan  [(set (match_operand:HQI 0 "memory_operand")
7482169689Skan	(ATOMIC:HQI (match_dup 0)
7483169689Skan		    (match_operand:HQI 1 "general_operand")))]
7484169689Skan  ""
7485169689Skan  "s390_expand_atomic (<MODE>mode, <CODE>, NULL_RTX, operands[0], 
7486169689Skan		       operands[1], false); DONE;")
7487169689Skan
7488169689Skan(define_expand "sync_old_<atomic><mode>"
7489169689Skan  [(set (match_operand:HQI 0 "register_operand")
7490169689Skan	(match_operand:HQI 1 "memory_operand"))
7491169689Skan   (set (match_dup 1)
7492169689Skan	(ATOMIC:HQI (match_dup 1)
7493169689Skan		    (match_operand:HQI 2 "general_operand")))]
7494169689Skan  ""
7495169689Skan  "s390_expand_atomic (<MODE>mode, <CODE>, operands[0], operands[1], 
7496169689Skan		       operands[2], false); DONE;")
7497169689Skan
7498169689Skan(define_expand "sync_new_<atomic><mode>"
7499169689Skan  [(set (match_operand:HQI 0 "register_operand")
7500169689Skan	(ATOMIC:HQI (match_operand:HQI 1 "memory_operand")
7501169689Skan		    (match_operand:HQI 2 "general_operand"))) 
7502169689Skan   (set (match_dup 1) (ATOMIC:HQI (match_dup 1) (match_dup 2)))]
7503169689Skan  ""
7504169689Skan  "s390_expand_atomic (<MODE>mode, <CODE>, operands[0], operands[1], 
7505169689Skan		       operands[2], true); DONE;")
7506169689Skan
7507169689Skan;;
7508107590Sobrien;;- Miscellaneous instructions.
7509107590Sobrien;;
7510107590Sobrien
7511107590Sobrien;
7512107590Sobrien; allocate stack instruction pattern(s).
7513107590Sobrien;
7514107590Sobrien
7515107590Sobrien(define_expand "allocate_stack"
7516169689Skan  [(match_operand 0 "general_operand" "")
7517169689Skan   (match_operand 1 "general_operand" "")]
7518132718Skan "TARGET_BACKCHAIN"
7519107590Sobrien{
7520169689Skan  rtx temp = gen_reg_rtx (Pmode);
7521132718Skan
7522169689Skan  emit_move_insn (temp, s390_back_chain_rtx ());
7523169689Skan  anti_adjust_stack (operands[1]);
7524169689Skan  emit_move_insn (s390_back_chain_rtx (), temp);
7525107590Sobrien
7526169689Skan  emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
7527169689Skan  DONE;
7528132718Skan})
7529107590Sobrien
7530107590Sobrien
7531107590Sobrien;
7532132718Skan; setjmp instruction pattern.
7533107590Sobrien;
7534107590Sobrien
7535107590Sobrien(define_expand "builtin_setjmp_receiver"
7536132718Skan  [(match_operand 0 "" "")]
7537107590Sobrien  "flag_pic"
7538107590Sobrien{
7539169689Skan  emit_insn (s390_load_got ());
7540132718Skan  emit_insn (gen_rtx_USE (VOIDmode, pic_offset_table_rtx));
7541107590Sobrien  DONE;
7542132718Skan})
7543107590Sobrien
7544107590Sobrien;; These patterns say how to save and restore the stack pointer.  We need not
7545107590Sobrien;; save the stack pointer at function level since we are careful to
7546107590Sobrien;; preserve the backchain.  At block level, we have to restore the backchain
7547107590Sobrien;; when we restore the stack pointer.
7548107590Sobrien;;
7549107590Sobrien;; For nonlocal gotos, we must save both the stack pointer and its
7550107590Sobrien;; backchain and restore both.  Note that in the nonlocal case, the
7551107590Sobrien;; save area is a memory location.
7552107590Sobrien
7553107590Sobrien(define_expand "save_stack_function"
7554107590Sobrien  [(match_operand 0 "general_operand" "")
7555107590Sobrien   (match_operand 1 "general_operand" "")]
7556107590Sobrien  ""
7557107590Sobrien  "DONE;")
7558107590Sobrien
7559107590Sobrien(define_expand "restore_stack_function"
7560107590Sobrien  [(match_operand 0 "general_operand" "")
7561107590Sobrien   (match_operand 1 "general_operand" "")]
7562107590Sobrien  ""
7563107590Sobrien  "DONE;")
7564107590Sobrien
7565107590Sobrien(define_expand "restore_stack_block"
7566169689Skan  [(match_operand 0 "register_operand" "")
7567169689Skan   (match_operand 1 "register_operand" "")]
7568169689Skan  "TARGET_BACKCHAIN"
7569107590Sobrien{
7570169689Skan  rtx temp = gen_reg_rtx (Pmode);
7571169689Skan
7572169689Skan  emit_move_insn (temp, s390_back_chain_rtx ());
7573169689Skan  emit_move_insn (operands[0], operands[1]);
7574169689Skan  emit_move_insn (s390_back_chain_rtx (), temp);
7575169689Skan
7576169689Skan  DONE;
7577132718Skan})
7578107590Sobrien
7579107590Sobrien(define_expand "save_stack_nonlocal"
7580107590Sobrien  [(match_operand 0 "memory_operand" "")
7581107590Sobrien   (match_operand 1 "register_operand" "")]
7582107590Sobrien  ""
7583107590Sobrien{
7584169689Skan  enum machine_mode mode = TARGET_64BIT ? OImode : TImode;
7585169689Skan  rtx base = gen_rtx_REG (Pmode, BASE_REGNUM);
7586107590Sobrien
7587169689Skan  /* Copy the backchain to the first word, sp to the second and the
7588169689Skan     literal pool base to the third.  */
7589169689Skan
7590169689Skan  if (TARGET_BACKCHAIN)
7591169689Skan    {
7592169689Skan      rtx temp = force_reg (Pmode, s390_back_chain_rtx ());
7593169689Skan      emit_move_insn (operand_subword (operands[0], 0, 0, mode), temp);
7594169689Skan    }
7595169689Skan
7596169689Skan  emit_move_insn (operand_subword (operands[0], 1, 0, mode), operands[1]);
7597169689Skan  emit_move_insn (operand_subword (operands[0], 2, 0, mode), base);
7598169689Skan
7599107590Sobrien  DONE;
7600132718Skan})
7601107590Sobrien
7602107590Sobrien(define_expand "restore_stack_nonlocal"
7603107590Sobrien  [(match_operand 0 "register_operand" "")
7604107590Sobrien   (match_operand 1 "memory_operand" "")]
7605107590Sobrien  ""
7606107590Sobrien{
7607169689Skan  enum machine_mode mode = TARGET_64BIT ? OImode : TImode;
7608169689Skan  rtx base = gen_rtx_REG (Pmode, BASE_REGNUM);
7609169689Skan  rtx temp = NULL_RTX;
7610107590Sobrien
7611132718Skan  /* Restore the backchain from the first word, sp from the second and the
7612169689Skan     literal pool base from the third.  */
7613169689Skan
7614169689Skan  if (TARGET_BACKCHAIN)
7615169689Skan    temp = force_reg (Pmode, operand_subword (operands[1], 0, 0, mode));
7616169689Skan    
7617169689Skan  emit_move_insn (base, operand_subword (operands[1], 2, 0, mode));
7618169689Skan  emit_move_insn (operands[0], operand_subword (operands[1], 1, 0, mode));
7619169689Skan
7620169689Skan  if (temp)
7621169689Skan    emit_move_insn (s390_back_chain_rtx (), temp);
7622169689Skan
7623132718Skan  emit_insn (gen_rtx_USE (VOIDmode, base));
7624169689Skan  DONE;
7625169689Skan})
7626132718Skan
7627169689Skan(define_expand "exception_receiver"
7628169689Skan  [(const_int 0)]
7629169689Skan  ""
7630169689Skan{
7631169689Skan  s390_set_has_landing_pad_p (true);
7632107590Sobrien  DONE;
7633132718Skan})
7634107590Sobrien
7635107590Sobrien;
7636107590Sobrien; nop instruction pattern(s).
7637107590Sobrien;
7638107590Sobrien
7639107590Sobrien(define_insn "nop"
7640107590Sobrien  [(const_int 0)]
7641107590Sobrien  ""
7642132718Skan  "lr\t0,0"
7643107590Sobrien  [(set_attr "op_type" "RR")])
7644107590Sobrien
7645107590Sobrien
7646107590Sobrien;
7647107590Sobrien; Special literal pool access instruction pattern(s).
7648107590Sobrien;
7649107590Sobrien
7650132718Skan(define_insn "*pool_entry"
7651132718Skan  [(unspec_volatile [(match_operand 0 "consttable_operand" "X")]
7652132718Skan                    UNSPECV_POOL_ENTRY)]
7653107590Sobrien  ""
7654107590Sobrien{
7655132718Skan  enum machine_mode mode = GET_MODE (PATTERN (insn));
7656132718Skan  unsigned int align = GET_MODE_BITSIZE (mode);
7657169689Skan  s390_output_pool_entry (operands[0], mode, align);
7658132718Skan  return "";
7659132718Skan}
7660169689Skan  [(set (attr "length")
7661132718Skan        (symbol_ref "GET_MODE_SIZE (GET_MODE (PATTERN (insn)))"))])
7662107590Sobrien
7663169689Skan(define_insn "pool_align"
7664169689Skan  [(unspec_volatile [(match_operand 0 "const_int_operand" "n")]
7665169689Skan                    UNSPECV_POOL_ALIGN)]
7666169689Skan  ""
7667169689Skan  ".align\t%0"
7668169689Skan  [(set (attr "length") (symbol_ref "INTVAL (operands[0])"))])
7669107590Sobrien
7670169689Skan(define_insn "pool_section_start"
7671169689Skan  [(unspec_volatile [(const_int 1)] UNSPECV_POOL_SECTION)]
7672169689Skan  ""
7673169689Skan  ".section\t.rodata"
7674169689Skan  [(set_attr "length" "0")])
7675107590Sobrien
7676169689Skan(define_insn "pool_section_end"
7677169689Skan  [(unspec_volatile [(const_int 0)] UNSPECV_POOL_SECTION)]
7678169689Skan  ""
7679107590Sobrien  ".previous"
7680169689Skan  [(set_attr "length" "0")])
7681107590Sobrien
7682132718Skan(define_insn "main_base_31_small"
7683132718Skan  [(set (match_operand 0 "register_operand" "=a")
7684132718Skan        (unspec [(label_ref (match_operand 1 "" ""))] UNSPEC_MAIN_BASE))]
7685132718Skan  "!TARGET_CPU_ZARCH && GET_MODE (operands[0]) == Pmode"
7686132718Skan  "basr\t%0,0"
7687132718Skan  [(set_attr "op_type" "RR")
7688132718Skan   (set_attr "type"    "la")])
7689132718Skan
7690132718Skan(define_insn "main_base_31_large"
7691132718Skan  [(set (match_operand 0 "register_operand" "=a")
7692132718Skan        (unspec [(label_ref (match_operand 1 "" ""))] UNSPEC_MAIN_BASE))
7693132718Skan   (set (pc) (label_ref (match_operand 2 "" "")))]
7694132718Skan  "!TARGET_CPU_ZARCH && GET_MODE (operands[0]) == Pmode"
7695132718Skan  "bras\t%0,%2"
7696132718Skan  [(set_attr "op_type" "RI")])
7697132718Skan
7698132718Skan(define_insn "main_base_64"
7699132718Skan  [(set (match_operand 0 "register_operand" "=a")
7700132718Skan        (unspec [(label_ref (match_operand 1 "" ""))] UNSPEC_MAIN_BASE))]
7701132718Skan  "TARGET_CPU_ZARCH && GET_MODE (operands[0]) == Pmode"
7702132718Skan  "larl\t%0,%1"
7703132718Skan  [(set_attr "op_type" "RIL")
7704132718Skan   (set_attr "type"    "larl")])
7705132718Skan
7706132718Skan(define_insn "main_pool"
7707169689Skan  [(set (match_operand 0 "register_operand" "=a")
7708169689Skan        (unspec_volatile [(const_int 0)] UNSPECV_MAIN_POOL))]
7709169689Skan  "GET_MODE (operands[0]) == Pmode"
7710169689Skan{
7711169689Skan  gcc_unreachable ();
7712169689Skan}
7713169689Skan  [(set (attr "type") 
7714169689Skan        (if_then_else (ne (symbol_ref "TARGET_CPU_ZARCH") (const_int 0))
7715169689Skan                      (const_string "larl") (const_string "la")))])
7716132718Skan
7717117395Skan(define_insn "reload_base_31"
7718132718Skan  [(set (match_operand 0 "register_operand" "=a")
7719132718Skan        (unspec [(label_ref (match_operand 1 "" ""))] UNSPEC_RELOAD_BASE))]
7720132718Skan  "!TARGET_CPU_ZARCH && GET_MODE (operands[0]) == Pmode"
7721132718Skan  "basr\t%0,0\;la\t%0,%1-.(%0)"
7722169689Skan  [(set_attr "length" "6")
7723169689Skan   (set_attr "type" "la")])
7724107590Sobrien
7725117395Skan(define_insn "reload_base_64"
7726132718Skan  [(set (match_operand 0 "register_operand" "=a")
7727132718Skan        (unspec [(label_ref (match_operand 1 "" ""))] UNSPEC_RELOAD_BASE))]
7728132718Skan  "TARGET_CPU_ZARCH && GET_MODE (operands[0]) == Pmode"
7729132718Skan  "larl\t%0,%1"
7730117395Skan  [(set_attr "op_type" "RIL")
7731132718Skan   (set_attr "type"    "larl")])
7732117395Skan
7733117395Skan(define_insn "pool"
7734132718Skan  [(unspec_volatile [(match_operand 0 "const_int_operand" "n")] UNSPECV_POOL)]
7735117395Skan  ""
7736169689Skan{
7737169689Skan  gcc_unreachable ();
7738169689Skan}
7739169689Skan  [(set (attr "length") (symbol_ref "INTVAL (operands[0])"))])
7740107590Sobrien
7741107590Sobrien;;
7742107590Sobrien;; Insns related to generating the function prologue and epilogue.
7743107590Sobrien;;
7744107590Sobrien
7745107590Sobrien
7746107590Sobrien(define_expand "prologue"
7747107590Sobrien  [(use (const_int 0))]
7748107590Sobrien  ""
7749132718Skan  "s390_emit_prologue (); DONE;")
7750107590Sobrien
7751107590Sobrien(define_expand "epilogue"
7752107590Sobrien  [(use (const_int 1))]
7753107590Sobrien  ""
7754169689Skan  "s390_emit_epilogue (false); DONE;")
7755107590Sobrien
7756169689Skan(define_expand "sibcall_epilogue"
7757169689Skan  [(use (const_int 0))]
7758169689Skan  ""
7759169689Skan  "s390_emit_epilogue (true); DONE;")
7760169689Skan
7761132718Skan(define_insn "*return"
7762107590Sobrien  [(return)
7763132718Skan   (use (match_operand 0 "register_operand" "a"))]
7764132718Skan  "GET_MODE (operands[0]) == Pmode"
7765132718Skan  "br\t%0"
7766107590Sobrien  [(set_attr "op_type" "RR")
7767132718Skan   (set_attr "type"    "jsr")
7768132718Skan   (set_attr "atype"   "agen")])
7769107590Sobrien
7770107590Sobrien
7771132718Skan;; Instruction definition to extend a 31-bit pointer into a 64-bit
7772132718Skan;; pointer. This is used for compatibility.
7773117395Skan
7774132718Skan(define_expand "ptr_extend"
7775132718Skan  [(set (match_operand:DI 0 "register_operand" "=r")
7776132718Skan        (match_operand:SI 1 "register_operand" "r"))]
7777132718Skan  "TARGET_64BIT"
7778107590Sobrien{
7779132718Skan  emit_insn (gen_anddi3 (operands[0],
7780132718Skan			 gen_lowpart (DImode, operands[1]),
7781132718Skan			 GEN_INT (0x7fffffff)));
7782132718Skan  DONE;
7783132718Skan})
7784169689Skan
7785169689Skan;; Instruction definition to expand eh_return macro to support
7786169689Skan;; swapping in special linkage return addresses.
7787169689Skan
7788169689Skan(define_expand "eh_return"
7789169689Skan  [(use (match_operand 0 "register_operand" ""))]
7790169689Skan  "TARGET_TPF"
7791169689Skan{
7792169689Skan  s390_emit_tpf_eh_return (operands[0]);
7793169689Skan  DONE;
7794169689Skan})
7795169689Skan
7796169689Skan;
7797169689Skan; Stack Protector Patterns
7798169689Skan;
7799169689Skan
7800169689Skan(define_expand "stack_protect_set"
7801169689Skan  [(set (match_operand 0 "memory_operand" "")
7802169689Skan	(match_operand 1 "memory_operand" ""))]
7803169689Skan  ""
7804169689Skan{
7805169689Skan#ifdef TARGET_THREAD_SSP_OFFSET
7806169689Skan  operands[1]
7807169689Skan    = gen_rtx_MEM (Pmode, gen_rtx_PLUS (Pmode, s390_get_thread_pointer (),
7808169689Skan                                        GEN_INT (TARGET_THREAD_SSP_OFFSET)));
7809169689Skan#endif
7810169689Skan  if (TARGET_64BIT)
7811169689Skan    emit_insn (gen_stack_protect_setdi (operands[0], operands[1]));
7812169689Skan  else
7813169689Skan    emit_insn (gen_stack_protect_setsi (operands[0], operands[1]));
7814169689Skan
7815169689Skan  DONE;
7816169689Skan})
7817169689Skan
7818169689Skan(define_insn "stack_protect_set<mode>"
7819169689Skan  [(set (match_operand:DSI 0 "memory_operand" "=Q")
7820169689Skan        (unspec:DSI [(match_operand:DSI 1 "memory_operand" "Q")] UNSPEC_SP_SET))]
7821169689Skan  ""
7822169689Skan  "mvc\t%O0(%G0,%R0),%S1"
7823169689Skan  [(set_attr "op_type" "SS")])
7824169689Skan
7825169689Skan(define_expand "stack_protect_test"
7826169689Skan  [(set (reg:CC CC_REGNUM)
7827169689Skan	(compare (match_operand 0 "memory_operand" "")
7828169689Skan		 (match_operand 1 "memory_operand" "")))
7829169689Skan   (match_operand 2 "" "")]
7830169689Skan  ""
7831169689Skan{
7832169689Skan#ifdef TARGET_THREAD_SSP_OFFSET
7833169689Skan  operands[1]
7834169689Skan    = gen_rtx_MEM (Pmode, gen_rtx_PLUS (Pmode, s390_get_thread_pointer (),
7835169689Skan                                        GEN_INT (TARGET_THREAD_SSP_OFFSET)));
7836169689Skan#endif
7837169689Skan  s390_compare_op0 = operands[0];
7838169689Skan  s390_compare_op1 = operands[1];
7839169689Skan  s390_compare_emitted = gen_rtx_REG (CCZmode, CC_REGNUM);
7840169689Skan
7841169689Skan  if (TARGET_64BIT)
7842169689Skan    emit_insn (gen_stack_protect_testdi (operands[0], operands[1]));
7843169689Skan  else
7844169689Skan    emit_insn (gen_stack_protect_testsi (operands[0], operands[1]));
7845169689Skan
7846169689Skan  emit_jump_insn (gen_beq (operands[2]));
7847169689Skan
7848169689Skan  DONE;
7849169689Skan})
7850169689Skan
7851169689Skan(define_insn "stack_protect_test<mode>"
7852169689Skan  [(set (reg:CCZ CC_REGNUM)
7853169689Skan        (unspec:CCZ [(match_operand:DSI 0 "memory_operand" "Q")
7854169689Skan		     (match_operand:DSI 1 "memory_operand" "Q")] UNSPEC_SP_TEST))]
7855169689Skan  ""
7856169689Skan  "clc\t%O0(%G0,%R0),%S1"
7857169689Skan  [(set_attr "op_type" "SS")])
7858