1;;- Machine description for GNU compiler -- S/390 / zSeries version.
2;;  Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006
3;;  Free Software Foundation, Inc.
4;;  Contributed by Hartmut Penner (hpenner@de.ibm.com) and
5;;                 Ulrich Weigand (uweigand@de.ibm.com).
6
7;; This file is part of GCC.
8
9;; GCC is free software; you can redistribute it and/or modify it under
10;; the terms of the GNU General Public License as published by the Free
11;; Software Foundation; either version 2, or (at your option) any later
12;; version.
13
14;; GCC is distributed in the hope that it will be useful, but WITHOUT ANY
15;; WARRANTY; without even the implied warranty of MERCHANTABILITY or
16;; FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
17;; for more details.
18
19;; You should have received a copy of the GNU General Public License
20;; along with GCC; see the file COPYING.  If not, write to the Free
21;; Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
22;; 02110-1301, USA.
23
24;;
25;; See constraints.md for a description of constraints specific to s390.
26;;
27
28;; Special formats used for outputting 390 instructions.
29;;
30;;     %C: print opcode suffix for branch condition.
31;;     %D: print opcode suffix for inverse branch condition.
32;;     %J: print tls_load/tls_gdcall/tls_ldcall suffix
33;;     %G: print the size of the operand in bytes.
34;;     %O: print only the displacement of a memory reference.
35;;     %R: print only the base register of a memory reference.
36;;     %S: print S-type memory reference (base+displacement).
37;;     %N: print the second word of a DImode operand.
38;;     %M: print the second word of a TImode operand.
39;;     %Y: print shift count operand.
40;;  
41;;     %b: print integer X as if it's an unsigned byte.
42;;     %x: print integer X as if it's an unsigned halfword.
43;;     %h: print integer X as if it's a signed halfword.
44;;     %i: print the first nonzero HImode part of X.
45;;     %j: print the first HImode part unequal to -1 of X.
46;;     %k: print the first nonzero SImode part of X.
47;;     %m: print the first SImode part unequal to -1 of X.
48;;     %o: print integer X as if it's an unsigned 32bit word.
49;;
50;; We have a special constraint for pattern matching.
51;;
52;;   s_operand -- Matches a valid S operand in a RS, SI or SS type instruction.
53;;
54
55;;
56;; UNSPEC usage
57;;
58
59(define_constants
60  [; Miscellaneous
61   (UNSPEC_ROUND		1)
62   (UNSPEC_CMPINT		2)
63   (UNSPEC_ICM			10)
64
65   ; GOT/PLT and lt-relative accesses
66   (UNSPEC_LTREL_OFFSET		100)
67   (UNSPEC_LTREL_BASE		101)
68   (UNSPEC_GOTENT		110)
69   (UNSPEC_GOT			111)
70   (UNSPEC_GOTOFF		112)
71   (UNSPEC_PLT			113)
72   (UNSPEC_PLTOFF		114)
73
74   ; Literal pool
75   (UNSPEC_RELOAD_BASE		210)
76   (UNSPEC_MAIN_BASE		211)
77   (UNSPEC_LTREF		212)
78   (UNSPEC_INSN			213)
79   (UNSPEC_EXECUTE		214)
80
81   ; TLS relocation specifiers
82   (UNSPEC_TLSGD		500)
83   (UNSPEC_TLSLDM		501)
84   (UNSPEC_NTPOFF               502)
85   (UNSPEC_DTPOFF               503)
86   (UNSPEC_GOTNTPOFF            504)
87   (UNSPEC_INDNTPOFF            505)
88
89   ; TLS support
90   (UNSPEC_TLSLDM_NTPOFF	511)
91   (UNSPEC_TLS_LOAD		512)
92
93   ; String Functions
94   (UNSPEC_SRST			600)
95   (UNSPEC_MVST			601)
96   
97   ; Stack Smashing Protector
98   (UNSPEC_SP_SET 		700)
99   (UNSPEC_SP_TEST		701)
100 ])
101
102;;
103;; UNSPEC_VOLATILE usage
104;;
105
106(define_constants
107  [; Blockage
108   (UNSPECV_BLOCKAGE		0)
109
110   ; TPF Support
111   (UNSPECV_TPF_PROLOGUE        20)
112   (UNSPECV_TPF_EPILOGUE        21)
113
114   ; Literal pool
115   (UNSPECV_POOL		200)
116   (UNSPECV_POOL_SECTION	201)
117   (UNSPECV_POOL_ALIGN		202)
118   (UNSPECV_POOL_ENTRY		203)
119   (UNSPECV_MAIN_POOL		300)
120
121   ; TLS support
122   (UNSPECV_SET_TP		500)
123
124   ; Atomic Support
125   (UNSPECV_MB			700)
126   (UNSPECV_CAS			701)
127  ])
128
129;;
130;; Registers
131;;
132
133(define_constants
134  [
135   ; Sibling call register.
136   (SIBCALL_REGNUM		 1)
137   ; Literal pool base register.
138   (BASE_REGNUM			13)
139   ; Return address register.
140   (RETURN_REGNUM		14)
141   ; Condition code register.
142   (CC_REGNUM			33)
143   ; Thread local storage pointer register. 
144   (TP_REGNUM			36)
145  ])
146
147
148;; Instruction operand type as used in the Principles of Operation.
149;; Used to determine defaults for length and other attribute values.
150
151(define_attr "op_type"
152  "NN,E,RR,RRE,RX,RS,RSI,RI,SI,S,SS,SSE,RXE,RSE,RIL,RIE,RXY,RSY,SIY"
153  (const_string "NN"))
154
155;; Instruction type attribute used for scheduling.
156
157(define_attr "type" "none,integer,load,lr,la,larl,lm,stm,
158	             cs,vs,store,sem,idiv,
159                     imulhi,imulsi,imuldi,
160		     branch,jsr,fsimptf,fsimpdf,fsimpsf,
161		     floadtf,floaddf,floadsf,fstoredf,fstoresf,
162		     fmultf,fmuldf,fmulsf,fdivtf,fdivdf,fdivsf,
163		     ftoi,itof,fsqrttf,fsqrtdf,fsqrtsf,
164                     ftrunctf,ftruncdf,other"
165  (cond [(eq_attr "op_type" "NN")  (const_string "other")
166         (eq_attr "op_type" "SS")  (const_string "cs")]
167    (const_string "integer")))
168
169;; Another attribute used for scheduling purposes:
170;;   agen: Instruction uses the address generation unit
171;;   reg: Instruction does not use the agen unit
172
173(define_attr "atype" "agen,reg"
174  (if_then_else (eq_attr "op_type" "E,RR,RI,RRE")  
175		(const_string "reg")
176		(const_string "agen")))
177
178;; Length in bytes.
179
180(define_attr "length" ""
181  (cond [(eq_attr "op_type" "E,RR")		      (const_int 2)
182         (eq_attr "op_type" "RX,RI,RRE,RS,RSI,S,SI")  (const_int 4)]
183    (const_int 6)))
184
185
186;; Processor type.  This attribute must exactly match the processor_type
187;; enumeration in s390.h.  The current machine description does not
188;; distinguish between g5 and g6, but there are differences between the two
189;; CPUs could in theory be modeled.
190
191(define_attr "cpu" "g5,g6,z900,z990,z9_109"
192  (const (symbol_ref "s390_tune")))
193
194;; Pipeline description for z900.  For lack of anything better,
195;; this description is also used for the g5 and g6.
196(include "2064.md")
197
198;; Pipeline description for z990. 
199(include "2084.md")
200
201;; Predicates
202(include "predicates.md")
203
204;; Constraint definitions
205(include "constraints.md")
206
207;; Other includes
208(include "tpf.md")
209
210;; Macros
211
212;; This mode macro allows floating point patterns to be generated from the
213;; same template.
214(define_mode_macro FPR [TF DF SF])
215(define_mode_macro DSF [DF SF])
216
217;; These mode macros allow 31-bit and 64-bit TDSI patterns to be generated
218;; from the same template.
219(define_mode_macro TDSI [(TI "TARGET_64BIT") DI SI])
220
221;; These mode macros allow 31-bit and 64-bit GPR patterns to be generated
222;; from the same template.
223(define_mode_macro GPR [(DI "TARGET_64BIT") SI])
224(define_mode_macro DSI [DI SI])
225
226;; This mode macro allows :P to be used for patterns that operate on
227;; pointer-sized quantities.  Exactly one of the two alternatives will match.
228(define_mode_macro DP  [(TI "TARGET_64BIT") (DI "!TARGET_64BIT")])
229(define_mode_macro P [(DI "TARGET_64BIT") (SI "!TARGET_64BIT")])
230
231;; This mode macro allows the QI and HI patterns to be defined from
232;; the same template.
233(define_mode_macro HQI [HI QI])
234
235;; This mode macro allows the integer patterns to be defined from the
236;; same template.
237(define_mode_macro INT [(DI "TARGET_64BIT") SI HI QI])
238
239;; This macro allows to unify all 'bCOND' expander patterns.
240(define_code_macro COMPARE [eq ne gt gtu lt ltu ge geu le leu unordered 
241		            ordered uneq unlt ungt unle unge ltgt])
242
243;; This macro allows to unify all 'sCOND' patterns.
244(define_code_macro SCOND [ltu gtu leu geu])
245
246;; This macro allows some 'ashift' and 'lshiftrt' pattern to be defined from
247;; the same template.
248(define_code_macro SHIFT [ashift lshiftrt])
249
250;; These macros allow to combine most atomic operations.
251(define_code_macro ATOMIC [and ior xor plus minus mult])
252(define_code_attr atomic [(and "and") (ior "ior") (xor "xor") 
253			  (plus "add") (minus "sub") (mult "nand")])
254
255
256;; In FPR templates, a string like "lt<de>br" will expand to "ltxbr" in TFmode,
257;; "ltdbr" in DFmode, and "ltebr" in SFmode.
258(define_mode_attr xde [(TF "x") (DF "d") (SF "e")])
259
260;; In FPR templates, a string like "m<dee>br" will expand to "mxbr" in TFmode,
261;; "mdbr" in DFmode, and "meebr" in SFmode.
262(define_mode_attr xdee [(TF "x") (DF "d") (SF "ee")])
263
264;; In FPR templates, "<RRe>" will expand to "RRE" in TFmode and "RR" otherwise.
265;; Likewise for "<RXe>".
266(define_mode_attr RRe [(TF "RRE") (DF "RR") (SF "RR")])
267(define_mode_attr RXe [(TF "RXE") (DF "RX") (SF "RX")])
268
269;; In FPR templates, "<Rf>" will expand to "f" in TFmode and "R" otherwise.
270;; This is used to disable the memory alternative in TFmode patterns.
271(define_mode_attr Rf [(TF "f") (DF "R") (SF "R")])
272
273;; In GPR and P templates, a constraint like "<d0>" will expand to "d" in DImode
274;; and "0" in SImode. This allows to combine instructions of which the 31bit
275;; version only operates on one register.
276(define_mode_attr d0 [(DI "d") (SI "0")])
277
278;; In combination with d0 this allows to combine instructions of which the 31bit
279;; version only operates on one register. The DImode version needs an additional
280;; register for the assembler output.
281(define_mode_attr 1 [(DI "%1,") (SI "")])
282  
283;; In SHIFT templates, a string like "s<lr>dl" will expand to "sldl" in 
284;; 'ashift' and "srdl" in 'lshiftrt'.
285(define_code_attr lr [(ashift "l") (lshiftrt "r")])
286
287;; In SHIFT templates, this attribute holds the correct standard name for the
288;; pattern itself and the corresponding function calls. 
289(define_code_attr shift [(ashift "ashl") (lshiftrt "lshr")])
290
291;; This attribute handles differences in the instruction 'type' and will result
292;; in "RRE" for DImode and "RR" for SImode.
293(define_mode_attr E [(DI "E") (SI "")])
294
295;; This attribute handles differences in the instruction 'type' and makes RX<Y>
296;; to result in "RXY" for DImode and "RX" for SImode.
297(define_mode_attr Y [(DI "Y") (SI "")])
298
299;; This attribute handles differences in the instruction 'type' and will result
300;; in "RSE" for TImode and "RS" for DImode.
301(define_mode_attr TE [(TI "E") (DI "")])
302
303;; In GPR templates, a string like "lc<g>r" will expand to "lcgr" in DImode
304;; and "lcr" in SImode.
305(define_mode_attr g [(DI "g") (SI "")])
306
307;; In GPR templates, a string like "sl<y>" will expand to "slg" in DImode
308;; and "sly" in SImode. This is useful because on 64bit the ..g instructions
309;; were enhanced with long displacements whereas 31bit instructions got a ..y
310;; variant for long displacements.
311(define_mode_attr y [(DI "g") (SI "y")])
312
313;; In DP templates, a string like "cds<g>" will expand to "cdsg" in TImode
314;; and "cds" in DImode.
315(define_mode_attr tg [(TI "g") (DI "")])
316
317;; In GPR templates, a string like "c<gf>dbr" will expand to "cgdbr" in DImode
318;; and "cfdbr" in SImode.
319(define_mode_attr gf [(DI "g") (SI "f")])
320
321;; ICM mask required to load MODE value into the lowest subreg
322;; of a SImode register.
323(define_mode_attr icm_lo [(HI "3") (QI "1")])
324
325;; In HQI templates, a string like "llg<hc>" will expand to "llgh" in
326;; HImode and "llgc" in QImode.
327(define_mode_attr hc [(HI "h") (QI "c")])
328
329;; In P templates, the mode <DBL> will expand to "TI" in DImode and "DI"
330;; in SImode.
331(define_mode_attr DBL [(DI "TI") (SI "DI")])
332
333;; Maximum unsigned integer that fits in MODE.
334(define_mode_attr max_uint [(HI "65535") (QI "255")])
335
336
337;;
338;;- Compare instructions.
339;;
340
341(define_expand "cmp<mode>"
342  [(set (reg:CC CC_REGNUM)
343        (compare:CC (match_operand:GPR 0 "register_operand" "")
344                    (match_operand:GPR 1 "general_operand" "")))]
345  ""
346{
347  s390_compare_op0 = operands[0];
348  s390_compare_op1 = operands[1];
349  DONE;
350})
351
352(define_expand "cmp<mode>"
353  [(set (reg:CC CC_REGNUM)
354        (compare:CC (match_operand:FPR 0 "register_operand" "")
355                    (match_operand:FPR 1 "general_operand" "")))]
356  "TARGET_HARD_FLOAT"
357{
358  s390_compare_op0 = operands[0];
359  s390_compare_op1 = operands[1];
360  DONE;
361})
362
363
364; Test-under-Mask instructions
365
366(define_insn "*tmqi_mem"
367  [(set (reg CC_REGNUM)
368        (compare (and:QI (match_operand:QI 0 "memory_operand" "Q,S")
369                         (match_operand:QI 1 "immediate_operand" "n,n"))
370                 (match_operand:QI 2 "immediate_operand" "n,n")))]
371  "s390_match_ccmode (insn, s390_tm_ccmode (operands[1], operands[2], false))"
372  "@
373   tm\t%S0,%b1
374   tmy\t%S0,%b1"
375  [(set_attr "op_type" "SI,SIY")])
376
377(define_insn "*tmdi_reg"
378  [(set (reg CC_REGNUM)
379        (compare (and:DI (match_operand:DI 0 "nonimmediate_operand" "d,d,d,d")
380                         (match_operand:DI 1 "immediate_operand"
381					     "N0HD0,N1HD0,N2HD0,N3HD0"))
382                 (match_operand:DI 2 "immediate_operand" "n,n,n,n")))]
383  "TARGET_64BIT
384   && s390_match_ccmode (insn, s390_tm_ccmode (operands[1], operands[2], true))
385   && s390_single_part (operands[1], DImode, HImode, 0) >= 0"
386  "@
387   tmhh\t%0,%i1
388   tmhl\t%0,%i1
389   tmlh\t%0,%i1
390   tmll\t%0,%i1"
391  [(set_attr "op_type" "RI")])
392
393(define_insn "*tmsi_reg"
394  [(set (reg CC_REGNUM)
395        (compare (and:SI (match_operand:SI 0 "nonimmediate_operand" "d,d")
396                         (match_operand:SI 1 "immediate_operand" "N0HS0,N1HS0"))
397                 (match_operand:SI 2 "immediate_operand" "n,n")))]
398  "s390_match_ccmode (insn, s390_tm_ccmode (operands[1], operands[2], true))
399   && s390_single_part (operands[1], SImode, HImode, 0) >= 0"
400  "@
401   tmh\t%0,%i1
402   tml\t%0,%i1"
403  [(set_attr "op_type" "RI")])
404
405(define_insn "*tm<mode>_full"
406  [(set (reg CC_REGNUM)
407        (compare (match_operand:HQI 0 "register_operand" "d")
408                 (match_operand:HQI 1 "immediate_operand" "n")))]
409  "s390_match_ccmode (insn, s390_tm_ccmode (constm1_rtx, operands[1], true))"
410  "tml\t%0,<max_uint>"
411  [(set_attr "op_type" "RI")])
412
413
414;
415; Load-and-Test instructions
416;
417
418; tst(di|si) instruction pattern(s).
419
420(define_insn "*tstdi_sign"
421  [(set (reg CC_REGNUM)
422        (compare (ashiftrt:DI (ashift:DI (subreg:DI (match_operand:SI 0 "register_operand" "d") 0)
423					 (const_int 32)) (const_int 32))
424                 (match_operand:DI 1 "const0_operand" "")))
425   (set (match_operand:DI 2 "register_operand" "=d")
426        (sign_extend:DI (match_dup 0)))]
427  "s390_match_ccmode(insn, CCSmode) && TARGET_64BIT"
428  "ltgfr\t%2,%0"
429  [(set_attr "op_type" "RRE")])
430
431; ltr, lt, ltgr, ltg
432(define_insn "*tst<mode>_extimm"
433  [(set (reg CC_REGNUM)
434        (compare (match_operand:GPR 0 "nonimmediate_operand" "d,m")
435                 (match_operand:GPR 1 "const0_operand" "")))
436   (set (match_operand:GPR 2 "register_operand" "=d,d")
437        (match_dup 0))]
438  "s390_match_ccmode(insn, CCSmode) && TARGET_EXTIMM"
439  "@
440   lt<g>r\t%2,%0
441   lt<g>\t%2,%0"
442  [(set_attr "op_type" "RR<E>,RXY")])
443
444; ltr, lt, ltgr, ltg
445(define_insn "*tst<mode>_cconly_extimm"
446  [(set (reg CC_REGNUM)
447        (compare (match_operand:GPR 0 "nonimmediate_operand" "d,m")
448                 (match_operand:GPR 1 "const0_operand" "")))
449   (clobber (match_scratch:GPR 2 "=X,d"))]
450  "s390_match_ccmode(insn, CCSmode) && TARGET_EXTIMM"
451  "@
452   lt<g>r\t%0,%0
453   lt<g>\t%2,%0"
454  [(set_attr "op_type" "RR<E>,RXY")])
455
456(define_insn "*tstdi"
457  [(set (reg CC_REGNUM)
458        (compare (match_operand:DI 0 "register_operand" "d")
459                 (match_operand:DI 1 "const0_operand" "")))
460   (set (match_operand:DI 2 "register_operand" "=d")
461        (match_dup 0))]
462  "s390_match_ccmode(insn, CCSmode) && TARGET_64BIT && !TARGET_EXTIMM"
463  "ltgr\t%2,%0"
464  [(set_attr "op_type" "RRE")])
465
466(define_insn "*tstsi"
467  [(set (reg CC_REGNUM)
468        (compare (match_operand:SI 0 "nonimmediate_operand" "d,Q,S")
469                 (match_operand:SI 1 "const0_operand" "")))
470   (set (match_operand:SI 2 "register_operand" "=d,d,d")
471        (match_dup 0))]
472  "s390_match_ccmode(insn, CCSmode) && !TARGET_EXTIMM"
473  "@
474   ltr\t%2,%0
475   icm\t%2,15,%S0
476   icmy\t%2,15,%S0"
477  [(set_attr "op_type" "RR,RS,RSY")])
478
479(define_insn "*tstsi_cconly"
480  [(set (reg CC_REGNUM)
481        (compare (match_operand:SI 0 "nonimmediate_operand" "d,Q,S")
482                 (match_operand:SI 1 "const0_operand" "")))
483   (clobber (match_scratch:SI 2 "=X,d,d"))]
484  "s390_match_ccmode(insn, CCSmode)"
485  "@
486   ltr\t%0,%0
487   icm\t%2,15,%S0
488   icmy\t%2,15,%S0"
489  [(set_attr "op_type" "RR,RS,RSY")])
490
491(define_insn "*tstdi_cconly_31"
492  [(set (reg CC_REGNUM)
493        (compare (match_operand:DI 0 "register_operand" "d")
494                 (match_operand:DI 1 "const0_operand" "")))]
495  "s390_match_ccmode(insn, CCSmode) && !TARGET_64BIT"
496  "srda\t%0,0"
497  [(set_attr "op_type" "RS")
498   (set_attr "atype"   "reg")])
499
500; ltr, ltgr
501(define_insn "*tst<mode>_cconly2"
502  [(set (reg CC_REGNUM)
503        (compare (match_operand:GPR 0 "register_operand" "d")
504                 (match_operand:GPR 1 "const0_operand" "")))]
505  "s390_match_ccmode(insn, CCSmode)"
506  "lt<g>r\t%0,%0"
507  [(set_attr "op_type" "RR<E>")])
508
509; tst(hi|qi) instruction pattern(s).
510
511(define_insn "*tst<mode>CCT"
512  [(set (reg CC_REGNUM)
513        (compare (match_operand:HQI 0 "nonimmediate_operand" "?Q,?S,d")
514                 (match_operand:HQI 1 "const0_operand" "")))
515   (set (match_operand:HQI 2 "register_operand" "=d,d,0")
516        (match_dup 0))]
517  "s390_match_ccmode(insn, CCTmode)"
518  "@
519   icm\t%2,<icm_lo>,%S0
520   icmy\t%2,<icm_lo>,%S0
521   tml\t%0,<max_uint>"
522  [(set_attr "op_type" "RS,RSY,RI")])
523
524(define_insn "*tsthiCCT_cconly"
525  [(set (reg CC_REGNUM)
526        (compare (match_operand:HI 0 "nonimmediate_operand" "Q,S,d")
527                 (match_operand:HI 1 "const0_operand" "")))
528   (clobber (match_scratch:HI 2 "=d,d,X"))]
529  "s390_match_ccmode(insn, CCTmode)"
530  "@
531   icm\t%2,3,%S0
532   icmy\t%2,3,%S0
533   tml\t%0,65535"
534  [(set_attr "op_type" "RS,RSY,RI")])
535
536(define_insn "*tstqiCCT_cconly"
537  [(set (reg CC_REGNUM)
538        (compare (match_operand:QI 0 "nonimmediate_operand" "?Q,?S,d")
539                 (match_operand:QI 1 "const0_operand" "")))]
540  "s390_match_ccmode(insn, CCTmode)"
541  "@
542   cli\t%S0,0
543   cliy\t%S0,0
544   tml\t%0,255"
545  [(set_attr "op_type" "SI,SIY,RI")])
546
547(define_insn "*tst<mode>"
548  [(set (reg CC_REGNUM)
549        (compare (match_operand:HQI 0 "s_operand" "Q,S")
550                 (match_operand:HQI 1 "const0_operand" "")))
551   (set (match_operand:HQI 2 "register_operand" "=d,d")
552        (match_dup 0))]
553  "s390_match_ccmode(insn, CCSmode)"
554  "@
555   icm\t%2,<icm_lo>,%S0
556   icmy\t%2,<icm_lo>,%S0"
557  [(set_attr "op_type" "RS,RSY")])
558
559(define_insn "*tst<mode>_cconly"
560  [(set (reg CC_REGNUM)
561        (compare (match_operand:HQI 0 "s_operand" "Q,S")
562                 (match_operand:HQI 1 "const0_operand" "")))
563   (clobber (match_scratch:HQI 2 "=d,d"))]
564  "s390_match_ccmode(insn, CCSmode)"
565  "@
566   icm\t%2,<icm_lo>,%S0
567   icmy\t%2,<icm_lo>,%S0"
568  [(set_attr "op_type" "RS,RSY")])
569
570
571; Compare (equality) instructions
572
573(define_insn "*cmpdi_cct"
574  [(set (reg CC_REGNUM)
575        (compare (match_operand:DI 0 "nonimmediate_operand" "%d,d,d,d,Q")
576                 (match_operand:DI 1 "general_operand" "d,K,Os,m,BQ")))]
577  "s390_match_ccmode (insn, CCTmode) && TARGET_64BIT"
578  "@
579   cgr\t%0,%1
580   cghi\t%0,%h1
581   cgfi\t%0,%1
582   cg\t%0,%1
583   #"
584  [(set_attr "op_type" "RRE,RI,RIL,RXY,SS")])
585
586(define_insn "*cmpsi_cct"
587  [(set (reg CC_REGNUM)
588        (compare (match_operand:SI 0 "nonimmediate_operand" "%d,d,d,d,d,Q")
589                 (match_operand:SI 1 "general_operand" "d,K,Os,R,T,BQ")))]
590  "s390_match_ccmode (insn, CCTmode)"
591  "@
592   cr\t%0,%1
593   chi\t%0,%h1
594   cfi\t%0,%1
595   c\t%0,%1
596   cy\t%0,%1
597   #"
598  [(set_attr "op_type" "RR,RI,RIL,RX,RXY,SS")])
599
600
601; Compare (signed) instructions
602
603(define_insn "*cmpdi_ccs_sign"
604  [(set (reg CC_REGNUM)
605        (compare (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "d,m"))
606                 (match_operand:DI 0 "register_operand" "d,d")))]
607  "s390_match_ccmode(insn, CCSRmode) && TARGET_64BIT"
608  "@
609   cgfr\t%0,%1
610   cgf\t%0,%1"
611  [(set_attr "op_type" "RRE,RXY")])
612
613(define_insn "*cmpsi_ccs_sign"
614  [(set (reg CC_REGNUM)
615        (compare (sign_extend:SI (match_operand:HI 1 "memory_operand" "R,T"))
616                 (match_operand:SI 0 "register_operand" "d,d")))]
617  "s390_match_ccmode(insn, CCSRmode)"
618  "@
619   ch\t%0,%1
620   chy\t%0,%1"
621  [(set_attr "op_type" "RX,RXY")])
622
623; cr, chi, cfi, c, cy, cgr, cghi, cgfi, cg
624(define_insn "*cmp<mode>_ccs"
625  [(set (reg CC_REGNUM)
626        (compare (match_operand:GPR 0 "register_operand" "d,d,d,d,d")
627                 (match_operand:GPR 1 "general_operand" "d,K,Os,R,T")))]
628  "s390_match_ccmode(insn, CCSmode)"
629  "@
630   c<g>r\t%0,%1
631   c<g>hi\t%0,%h1
632   c<g>fi\t%0,%1
633   c<g>\t%0,%1
634   c<y>\t%0,%1"
635  [(set_attr "op_type" "RR<E>,RI,RIL,RX<Y>,RXY")])
636
637
638; Compare (unsigned) instructions
639
640(define_insn "*cmpdi_ccu_zero"
641  [(set (reg CC_REGNUM)
642        (compare (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "d,m"))
643                 (match_operand:DI 0 "register_operand" "d,d")))]
644  "s390_match_ccmode (insn, CCURmode) && TARGET_64BIT"
645  "@
646   clgfr\t%0,%1
647   clgf\t%0,%1"
648  [(set_attr "op_type" "RRE,RXY")])
649
650(define_insn "*cmpdi_ccu"
651  [(set (reg CC_REGNUM)
652        (compare (match_operand:DI 0 "nonimmediate_operand" "d,d,d,Q,BQ")
653                 (match_operand:DI 1 "general_operand" "d,Op,m,BQ,Q")))]
654  "s390_match_ccmode (insn, CCUmode) && TARGET_64BIT"
655  "@
656   clgr\t%0,%1
657   clgfi\t%0,%1
658   clg\t%0,%1
659   #
660   #"
661  [(set_attr "op_type" "RRE,RIL,RXY,SS,SS")])
662
663(define_insn "*cmpsi_ccu"
664  [(set (reg CC_REGNUM)
665        (compare (match_operand:SI 0 "nonimmediate_operand" "d,d,d,d,Q,BQ")
666                 (match_operand:SI 1 "general_operand" "d,Os,R,T,BQ,Q")))]
667  "s390_match_ccmode (insn, CCUmode)"
668  "@
669   clr\t%0,%1
670   clfi\t%0,%o1
671   cl\t%0,%1
672   cly\t%0,%1
673   #
674   #"
675  [(set_attr "op_type" "RR,RIL,RX,RXY,SS,SS")])
676
677(define_insn "*cmphi_ccu"
678  [(set (reg CC_REGNUM)
679        (compare (match_operand:HI 0 "nonimmediate_operand" "d,d,Q,BQ")
680                 (match_operand:HI 1 "general_operand" "Q,S,BQ,Q")))]
681  "s390_match_ccmode (insn, CCUmode)
682   && !register_operand (operands[1], HImode)"
683  "@
684   clm\t%0,3,%S1
685   clmy\t%0,3,%S1
686   #
687   #"
688  [(set_attr "op_type" "RS,RSY,SS,SS")])
689
690(define_insn "*cmpqi_ccu"
691  [(set (reg CC_REGNUM)
692        (compare (match_operand:QI 0 "nonimmediate_operand" "d,d,Q,S,Q,BQ")
693                 (match_operand:QI 1 "general_operand" "Q,S,n,n,BQ,Q")))]
694  "s390_match_ccmode (insn, CCUmode)
695   && !register_operand (operands[1], QImode)"
696  "@
697   clm\t%0,1,%S1
698   clmy\t%0,1,%S1
699   cli\t%S0,%b1
700   cliy\t%S0,%b1
701   #
702   #"
703  [(set_attr "op_type" "RS,RSY,SI,SIY,SS,SS")])
704
705
706; Block compare (CLC) instruction patterns.
707
708(define_insn "*clc"
709  [(set (reg CC_REGNUM)
710        (compare (match_operand:BLK 0 "memory_operand" "Q")
711                 (match_operand:BLK 1 "memory_operand" "Q")))
712   (use (match_operand 2 "const_int_operand" "n"))]
713  "s390_match_ccmode (insn, CCUmode)
714   && INTVAL (operands[2]) >= 1 && INTVAL (operands[2]) <= 256"
715  "clc\t%O0(%2,%R0),%S1"
716  [(set_attr "op_type" "SS")])
717
718(define_split
719  [(set (reg CC_REGNUM)
720        (compare (match_operand 0 "memory_operand" "")
721                 (match_operand 1 "memory_operand" "")))]
722  "reload_completed
723   && s390_match_ccmode (insn, CCUmode)
724   && GET_MODE (operands[0]) == GET_MODE (operands[1])
725   && GET_MODE_SIZE (GET_MODE (operands[0])) > 0"
726  [(parallel
727    [(set (match_dup 0) (match_dup 1))
728     (use (match_dup 2))])]
729{
730  operands[2] = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[0])));
731  operands[0] = adjust_address (operands[0], BLKmode, 0);
732  operands[1] = adjust_address (operands[1], BLKmode, 0);
733
734  operands[1] = gen_rtx_COMPARE (GET_MODE (SET_DEST (PATTERN (curr_insn))),
735				 operands[0], operands[1]);
736  operands[0] = SET_DEST (PATTERN (curr_insn));
737})
738
739
740; (DF|SF) instructions
741
742; ltxbr, ltdbr, ltebr
743(define_insn "*cmp<mode>_ccs_0"
744  [(set (reg CC_REGNUM)
745        (compare (match_operand:FPR 0 "register_operand" "f")
746                 (match_operand:FPR 1 "const0_operand" "")))]
747  "s390_match_ccmode(insn, CCSmode) && TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT"
748  "lt<xde>br\t%0,%0"
749   [(set_attr "op_type" "RRE")
750    (set_attr "type"  "fsimp<mode>")])
751
752; ltxr, ltdr, lter
753(define_insn "*cmp<mode>_ccs_0_ibm"
754  [(set (reg CC_REGNUM)
755        (compare (match_operand:FPR 0 "register_operand" "f")
756                 (match_operand:FPR 1 "const0_operand" "")))]
757  "s390_match_ccmode(insn, CCSmode) && TARGET_HARD_FLOAT && TARGET_IBM_FLOAT"
758  "lt<xde>r\t%0,%0"
759   [(set_attr "op_type" "<RRe>")
760    (set_attr "type"  "fsimp<mode>")])
761
762; cxbr, cdbr, cebr, cxb, cdb, ceb
763(define_insn "*cmp<mode>_ccs"
764  [(set (reg CC_REGNUM)
765        (compare (match_operand:FPR 0 "register_operand" "f,f")
766                 (match_operand:FPR 1 "general_operand" "f,<Rf>")))]
767  "s390_match_ccmode(insn, CCSmode) && TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT"
768  "@
769   c<xde>br\t%0,%1
770   c<xde>b\t%0,%1"
771   [(set_attr "op_type" "RRE,RXE")
772    (set_attr "type"  "fsimp<mode>")])
773
774; cxr, cdr, cer, cx, cd, ce
775(define_insn "*cmp<mode>_ccs_ibm"
776  [(set (reg CC_REGNUM)
777        (compare (match_operand:FPR 0 "register_operand" "f,f")
778                 (match_operand:FPR 1 "general_operand" "f,<Rf>")))]
779  "s390_match_ccmode(insn, CCSmode) && TARGET_HARD_FLOAT && TARGET_IBM_FLOAT"
780  "@
781   c<xde>r\t%0,%1
782   c<xde>\t%0,%1"
783   [(set_attr "op_type" "<RRe>,<RXe>")
784    (set_attr "type"  "fsimp<mode>")])
785
786
787;;
788;;- Move instructions.
789;;
790
791;
792; movti instruction pattern(s).
793;
794
795(define_insn "movti"
796  [(set (match_operand:TI 0 "nonimmediate_operand" "=d,QS,d,o,Q")
797        (match_operand:TI 1 "general_operand" "QS,d,dPm,d,Q"))]
798  "TARGET_64BIT"
799  "@
800   lmg\t%0,%N0,%S1
801   stmg\t%1,%N1,%S0
802   #
803   #
804   #"
805  [(set_attr "op_type" "RSY,RSY,*,*,SS")
806   (set_attr "type" "lm,stm,*,*,*")])
807
808(define_split
809  [(set (match_operand:TI 0 "nonimmediate_operand" "")
810        (match_operand:TI 1 "general_operand" ""))]
811  "TARGET_64BIT && reload_completed
812   && s390_split_ok_p (operands[0], operands[1], TImode, 0)"
813  [(set (match_dup 2) (match_dup 4))
814   (set (match_dup 3) (match_dup 5))]
815{
816  operands[2] = operand_subword (operands[0], 0, 0, TImode);
817  operands[3] = operand_subword (operands[0], 1, 0, TImode);
818  operands[4] = operand_subword (operands[1], 0, 0, TImode);
819  operands[5] = operand_subword (operands[1], 1, 0, TImode);
820})
821
822(define_split
823  [(set (match_operand:TI 0 "nonimmediate_operand" "")
824        (match_operand:TI 1 "general_operand" ""))]
825  "TARGET_64BIT && reload_completed
826   && s390_split_ok_p (operands[0], operands[1], TImode, 1)"
827  [(set (match_dup 2) (match_dup 4))
828   (set (match_dup 3) (match_dup 5))]
829{
830  operands[2] = operand_subword (operands[0], 1, 0, TImode);
831  operands[3] = operand_subword (operands[0], 0, 0, TImode);
832  operands[4] = operand_subword (operands[1], 1, 0, TImode);
833  operands[5] = operand_subword (operands[1], 0, 0, TImode);
834})
835
836(define_split
837  [(set (match_operand:TI 0 "register_operand" "")
838        (match_operand:TI 1 "memory_operand" ""))]
839  "TARGET_64BIT && reload_completed
840   && !s_operand (operands[1], VOIDmode)"
841  [(set (match_dup 0) (match_dup 1))]
842{
843  rtx addr = operand_subword (operands[0], 1, 0, TImode);
844  s390_load_address (addr, XEXP (operands[1], 0));
845  operands[1] = replace_equiv_address (operands[1], addr);
846})
847
848(define_expand "reload_outti"
849  [(parallel [(match_operand:TI 0 "" "")
850              (match_operand:TI 1 "register_operand" "d")
851              (match_operand:DI 2 "register_operand" "=&a")])]
852  "TARGET_64BIT"
853{
854  gcc_assert (MEM_P (operands[0]));
855  s390_load_address (operands[2], find_replacement (&XEXP (operands[0], 0)));
856  operands[0] = replace_equiv_address (operands[0], operands[2]);
857  emit_move_insn (operands[0], operands[1]);
858  DONE;
859})
860
861;
862; movdi instruction pattern(s).
863;
864
865(define_expand "movdi"
866  [(set (match_operand:DI 0 "general_operand" "")
867        (match_operand:DI 1 "general_operand" ""))]
868  ""
869{
870  /* Handle symbolic constants.  */
871  if (TARGET_64BIT
872      && (SYMBOLIC_CONST (operands[1])
873	  || (GET_CODE (operands[1]) == PLUS
874	      && XEXP (operands[1], 0) == pic_offset_table_rtx
875	      && SYMBOLIC_CONST (XEXP (operands[1], 1)))))
876    emit_symbolic_move (operands);
877})
878
879(define_insn "*movdi_larl"
880  [(set (match_operand:DI 0 "register_operand" "=d")
881        (match_operand:DI 1 "larl_operand" "X"))]
882  "TARGET_64BIT
883   && !FP_REG_P (operands[0])"
884  "larl\t%0,%1"
885   [(set_attr "op_type" "RIL")
886    (set_attr "type"    "larl")])
887
888(define_insn "*movdi_64extimm"
889  [(set (match_operand:DI 0 "nonimmediate_operand"
890                            "=d,d,d,d,d,d,d,d,d,d,d,m,!*f,!*f,!*f,!R,!T,d,t,Q,t,?Q")
891        (match_operand:DI 1 "general_operand"
892                            "K,N0HD0,N1HD0,N2HD0,N3HD0,Os,N0SD0,N1SD0,L,d,m,d,*f,R,T,*f,*f,t,d,t,Q,?Q"))]
893  "TARGET_64BIT && TARGET_EXTIMM"
894  "@
895   lghi\t%0,%h1
896   llihh\t%0,%i1
897   llihl\t%0,%i1
898   llilh\t%0,%i1
899   llill\t%0,%i1
900   lgfi\t%0,%1
901   llihf\t%0,%k1
902   llilf\t%0,%k1
903   lay\t%0,%a1
904   lgr\t%0,%1
905   lg\t%0,%1
906   stg\t%1,%0
907   ldr\t%0,%1
908   ld\t%0,%1
909   ldy\t%0,%1
910   std\t%1,%0
911   stdy\t%1,%0
912   #
913   #
914   stam\t%1,%N1,%S0
915   lam\t%0,%N0,%S1
916   #"
917  [(set_attr "op_type" "RI,RI,RI,RI,RI,RIL,RIL,RIL,RXY,RRE,RXY,RXY,
918                        RR,RX,RXY,RX,RXY,*,*,RS,RS,SS")
919   (set_attr "type" "*,*,*,*,*,*,*,*,la,lr,load,store,
920                     floaddf,floaddf,floaddf,fstoredf,fstoredf,*,*,*,*,*")])
921
922(define_insn "*movdi_64"
923  [(set (match_operand:DI 0 "nonimmediate_operand"
924                            "=d,d,d,d,d,d,d,d,m,!*f,!*f,!*f,!R,!T,d,t,Q,t,?Q")
925        (match_operand:DI 1 "general_operand"
926                            "K,N0HD0,N1HD0,N2HD0,N3HD0,L,d,m,d,*f,R,T,*f,*f,t,d,t,Q,?Q"))]
927  "TARGET_64BIT && !TARGET_EXTIMM"
928  "@
929   lghi\t%0,%h1
930   llihh\t%0,%i1
931   llihl\t%0,%i1
932   llilh\t%0,%i1
933   llill\t%0,%i1
934   lay\t%0,%a1
935   lgr\t%0,%1
936   lg\t%0,%1
937   stg\t%1,%0
938   ldr\t%0,%1
939   ld\t%0,%1
940   ldy\t%0,%1
941   std\t%1,%0
942   stdy\t%1,%0
943   #
944   #
945   stam\t%1,%N1,%S0
946   lam\t%0,%N0,%S1
947   #"
948  [(set_attr "op_type" "RI,RI,RI,RI,RI,RXY,RRE,RXY,RXY,
949                        RR,RX,RXY,RX,RXY,*,*,RS,RS,SS")
950   (set_attr "type" "*,*,*,*,*,la,lr,load,store,
951                     floaddf,floaddf,floaddf,fstoredf,fstoredf,*,*,*,*,*")])
952
953(define_split
954  [(set (match_operand:DI 0 "register_operand" "")
955        (match_operand:DI 1 "register_operand" ""))]
956  "TARGET_64BIT && ACCESS_REG_P (operands[1])"
957  [(set (match_dup 2) (match_dup 3))
958   (set (match_dup 0) (ashift:DI (match_dup 0) (const_int 32)))
959   (set (strict_low_part (match_dup 2)) (match_dup 4))]
960  "operands[2] = gen_lowpart (SImode, operands[0]);
961   s390_split_access_reg (operands[1], &operands[4], &operands[3]);")
962
963(define_split
964  [(set (match_operand:DI 0 "register_operand" "")
965        (match_operand:DI 1 "register_operand" ""))]
966  "TARGET_64BIT && ACCESS_REG_P (operands[0])
967   && dead_or_set_p (insn, operands[1])"
968  [(set (match_dup 3) (match_dup 2))
969   (set (match_dup 1) (lshiftrt:DI (match_dup 1) (const_int 32)))
970   (set (match_dup 4) (match_dup 2))]
971  "operands[2] = gen_lowpart (SImode, operands[1]);
972   s390_split_access_reg (operands[0], &operands[3], &operands[4]);")
973
974(define_split
975  [(set (match_operand:DI 0 "register_operand" "")
976        (match_operand:DI 1 "register_operand" ""))]
977  "TARGET_64BIT && ACCESS_REG_P (operands[0])
978   && !dead_or_set_p (insn, operands[1])"
979  [(set (match_dup 3) (match_dup 2))
980   (set (match_dup 1) (rotate:DI (match_dup 1) (const_int 32)))
981   (set (match_dup 4) (match_dup 2))
982   (set (match_dup 1) (rotate:DI (match_dup 1) (const_int 32)))]
983  "operands[2] = gen_lowpart (SImode, operands[1]);
984   s390_split_access_reg (operands[0], &operands[3], &operands[4]);")
985
986(define_insn "*movdi_31"
987  [(set (match_operand:DI 0 "nonimmediate_operand" "=d,d,Q,S,d,o,!*f,!*f,!*f,!R,!T,Q")
988        (match_operand:DI 1 "general_operand" "Q,S,d,d,dPm,d,*f,R,T,*f,*f,Q"))]
989  "!TARGET_64BIT"
990  "@
991   lm\t%0,%N0,%S1
992   lmy\t%0,%N0,%S1
993   stm\t%1,%N1,%S0
994   stmy\t%1,%N1,%S0
995   #
996   #
997   ldr\t%0,%1
998   ld\t%0,%1
999   ldy\t%0,%1
1000   std\t%1,%0
1001   stdy\t%1,%0
1002   #"
1003  [(set_attr "op_type" "RS,RSY,RS,RSY,*,*,RR,RX,RXY,RX,RXY,SS")
1004   (set_attr "type" "lm,lm,stm,stm,*,*,floaddf,floaddf,floaddf,fstoredf,fstoredf,*")])
1005
1006(define_split
1007  [(set (match_operand:DI 0 "nonimmediate_operand" "")
1008        (match_operand:DI 1 "general_operand" ""))]
1009  "!TARGET_64BIT && reload_completed
1010   && s390_split_ok_p (operands[0], operands[1], DImode, 0)"
1011  [(set (match_dup 2) (match_dup 4))
1012   (set (match_dup 3) (match_dup 5))]
1013{
1014  operands[2] = operand_subword (operands[0], 0, 0, DImode);
1015  operands[3] = operand_subword (operands[0], 1, 0, DImode);
1016  operands[4] = operand_subword (operands[1], 0, 0, DImode);
1017  operands[5] = operand_subword (operands[1], 1, 0, DImode);
1018})
1019
1020(define_split
1021  [(set (match_operand:DI 0 "nonimmediate_operand" "")
1022        (match_operand:DI 1 "general_operand" ""))]
1023  "!TARGET_64BIT && reload_completed
1024   && s390_split_ok_p (operands[0], operands[1], DImode, 1)"
1025  [(set (match_dup 2) (match_dup 4))
1026   (set (match_dup 3) (match_dup 5))]
1027{
1028  operands[2] = operand_subword (operands[0], 1, 0, DImode);
1029  operands[3] = operand_subword (operands[0], 0, 0, DImode);
1030  operands[4] = operand_subword (operands[1], 1, 0, DImode);
1031  operands[5] = operand_subword (operands[1], 0, 0, DImode);
1032})
1033
1034(define_split
1035  [(set (match_operand:DI 0 "register_operand" "")
1036        (match_operand:DI 1 "memory_operand" ""))]
1037  "!TARGET_64BIT && reload_completed
1038   && !FP_REG_P (operands[0])
1039   && !s_operand (operands[1], VOIDmode)"
1040  [(set (match_dup 0) (match_dup 1))]
1041{
1042  rtx addr = operand_subword (operands[0], 1, 0, DImode);
1043  s390_load_address (addr, XEXP (operands[1], 0));
1044  operands[1] = replace_equiv_address (operands[1], addr);
1045})
1046
1047(define_expand "reload_outdi"
1048  [(parallel [(match_operand:DI 0 "" "")
1049              (match_operand:DI 1 "register_operand" "d")
1050              (match_operand:SI 2 "register_operand" "=&a")])]
1051  "!TARGET_64BIT"
1052{
1053  gcc_assert (MEM_P (operands[0]));
1054  s390_load_address (operands[2], find_replacement (&XEXP (operands[0], 0)));
1055  operands[0] = replace_equiv_address (operands[0], operands[2]);
1056  emit_move_insn (operands[0], operands[1]);
1057  DONE;
1058})
1059
1060(define_peephole2
1061  [(set (match_operand:DI 0 "register_operand" "")
1062        (mem:DI (match_operand 1 "address_operand" "")))]
1063  "TARGET_64BIT
1064   && !FP_REG_P (operands[0])
1065   && GET_CODE (operands[1]) == SYMBOL_REF
1066   && CONSTANT_POOL_ADDRESS_P (operands[1])
1067   && get_pool_mode (operands[1]) == DImode
1068   && legitimate_reload_constant_p (get_pool_constant (operands[1]))"
1069  [(set (match_dup 0) (match_dup 2))]
1070  "operands[2] = get_pool_constant (operands[1]);")
1071
1072(define_insn "*la_64"
1073  [(set (match_operand:DI 0 "register_operand" "=d,d")
1074        (match_operand:QI 1 "address_operand" "U,W"))]
1075  "TARGET_64BIT"
1076  "@
1077   la\t%0,%a1
1078   lay\t%0,%a1"
1079  [(set_attr "op_type" "RX,RXY")
1080   (set_attr "type"    "la")])
1081
1082(define_peephole2
1083  [(parallel
1084    [(set (match_operand:DI 0 "register_operand" "")
1085          (match_operand:QI 1 "address_operand" ""))
1086     (clobber (reg:CC CC_REGNUM))])]
1087  "TARGET_64BIT
1088   && preferred_la_operand_p (operands[1], const0_rtx)"
1089  [(set (match_dup 0) (match_dup 1))]
1090  "")
1091
1092(define_peephole2
1093  [(set (match_operand:DI 0 "register_operand" "")
1094        (match_operand:DI 1 "register_operand" ""))
1095   (parallel
1096    [(set (match_dup 0)
1097          (plus:DI (match_dup 0)
1098                   (match_operand:DI 2 "nonmemory_operand" "")))
1099     (clobber (reg:CC CC_REGNUM))])]
1100  "TARGET_64BIT
1101   && !reg_overlap_mentioned_p (operands[0], operands[2])
1102   && preferred_la_operand_p (operands[1], operands[2])"
1103  [(set (match_dup 0) (plus:DI (match_dup 1) (match_dup 2)))]
1104  "")
1105
1106(define_expand "reload_indi"
1107  [(parallel [(match_operand:DI 0 "register_operand" "=a")
1108              (match_operand:DI 1 "s390_plus_operand" "")
1109              (match_operand:DI 2 "register_operand" "=&a")])]
1110  "TARGET_64BIT"
1111{
1112  s390_expand_plus_operand (operands[0], operands[1], operands[2]);
1113  DONE;
1114})
1115
1116;
1117; movsi instruction pattern(s).
1118;
1119
1120(define_expand "movsi"
1121  [(set (match_operand:SI 0 "general_operand" "")
1122        (match_operand:SI 1 "general_operand" ""))]
1123  ""
1124{
1125  /* Handle symbolic constants.  */
1126  if (!TARGET_64BIT
1127      && (SYMBOLIC_CONST (operands[1])
1128	  || (GET_CODE (operands[1]) == PLUS
1129	      && XEXP (operands[1], 0) == pic_offset_table_rtx
1130	      && SYMBOLIC_CONST (XEXP(operands[1], 1)))))
1131    emit_symbolic_move (operands);
1132})
1133
1134(define_insn "*movsi_larl"
1135  [(set (match_operand:SI 0 "register_operand" "=d")
1136        (match_operand:SI 1 "larl_operand" "X"))]
1137  "!TARGET_64BIT && TARGET_CPU_ZARCH
1138   && !FP_REG_P (operands[0])"
1139  "larl\t%0,%1"
1140   [(set_attr "op_type" "RIL")
1141    (set_attr "type"    "larl")])
1142
1143(define_insn "*movsi_zarch"
1144  [(set (match_operand:SI 0 "nonimmediate_operand"
1145			    "=d,d,d,d,d,d,d,d,R,T,!*f,!*f,!*f,!R,!T,d,t,Q,t,?Q")
1146        (match_operand:SI 1 "general_operand"
1147			    "K,N0HS0,N1HS0,Os,L,d,R,T,d,d,*f,R,T,*f,*f,t,d,t,Q,?Q"))]
1148  "TARGET_ZARCH"
1149  "@
1150   lhi\t%0,%h1
1151   llilh\t%0,%i1
1152   llill\t%0,%i1
1153   iilf\t%0,%o1
1154   lay\t%0,%a1
1155   lr\t%0,%1
1156   l\t%0,%1
1157   ly\t%0,%1
1158   st\t%1,%0
1159   sty\t%1,%0
1160   ler\t%0,%1
1161   le\t%0,%1
1162   ley\t%0,%1
1163   ste\t%1,%0
1164   stey\t%1,%0
1165   ear\t%0,%1
1166   sar\t%0,%1
1167   stam\t%1,%1,%S0
1168   lam\t%0,%0,%S1
1169   #"
1170  [(set_attr "op_type" "RI,RI,RI,RIL,RXY,RR,RX,RXY,RX,RXY,
1171                        RR,RX,RXY,RX,RXY,RRE,RRE,RS,RS,SS")
1172   (set_attr "type" "*,*,*,*,la,lr,load,load,store,store,
1173                     floadsf,floadsf,floadsf,fstoresf,fstoresf,*,*,*,*,*")])
1174
1175(define_insn "*movsi_esa"
1176  [(set (match_operand:SI 0 "nonimmediate_operand" "=d,d,d,R,!*f,!*f,!R,d,t,Q,t,?Q")
1177        (match_operand:SI 1 "general_operand" "K,d,R,d,*f,R,*f,t,d,t,Q,?Q"))]
1178  "!TARGET_ZARCH"
1179  "@
1180   lhi\t%0,%h1
1181   lr\t%0,%1
1182   l\t%0,%1
1183   st\t%1,%0
1184   ler\t%0,%1
1185   le\t%0,%1
1186   ste\t%1,%0
1187   ear\t%0,%1
1188   sar\t%0,%1
1189   stam\t%1,%1,%S0
1190   lam\t%0,%0,%S1
1191   #"
1192  [(set_attr "op_type" "RI,RR,RX,RX,RR,RX,RX,RRE,RRE,RS,RS,SS")
1193   (set_attr "type" "*,lr,load,store,floadsf,floadsf,fstoresf,*,*,*,*,*")])
1194
1195(define_peephole2
1196  [(set (match_operand:SI 0 "register_operand" "")
1197        (mem:SI (match_operand 1 "address_operand" "")))]
1198  "!FP_REG_P (operands[0])
1199   && GET_CODE (operands[1]) == SYMBOL_REF
1200   && CONSTANT_POOL_ADDRESS_P (operands[1])
1201   && get_pool_mode (operands[1]) == SImode
1202   && legitimate_reload_constant_p (get_pool_constant (operands[1]))"
1203  [(set (match_dup 0) (match_dup 2))]
1204  "operands[2] = get_pool_constant (operands[1]);")
1205
1206(define_insn "*la_31"
1207  [(set (match_operand:SI 0 "register_operand" "=d,d")
1208        (match_operand:QI 1 "address_operand" "U,W"))]
1209  "!TARGET_64BIT && legitimate_la_operand_p (operands[1])"
1210  "@
1211   la\t%0,%a1
1212   lay\t%0,%a1"
1213  [(set_attr "op_type"  "RX,RXY")
1214   (set_attr "type"     "la")])
1215
1216(define_peephole2
1217  [(parallel
1218    [(set (match_operand:SI 0 "register_operand" "")
1219          (match_operand:QI 1 "address_operand" ""))
1220     (clobber (reg:CC CC_REGNUM))])]
1221  "!TARGET_64BIT
1222   && preferred_la_operand_p (operands[1], const0_rtx)"
1223  [(set (match_dup 0) (match_dup 1))]
1224  "")
1225
1226(define_peephole2
1227  [(set (match_operand:SI 0 "register_operand" "")
1228        (match_operand:SI 1 "register_operand" ""))
1229   (parallel
1230    [(set (match_dup 0)
1231          (plus:SI (match_dup 0)
1232                   (match_operand:SI 2 "nonmemory_operand" "")))
1233     (clobber (reg:CC CC_REGNUM))])]
1234  "!TARGET_64BIT
1235   && !reg_overlap_mentioned_p (operands[0], operands[2])
1236   && preferred_la_operand_p (operands[1], operands[2])"
1237  [(set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))]
1238  "")
1239
1240(define_insn "*la_31_and"
1241  [(set (match_operand:SI 0 "register_operand" "=d,d")
1242        (and:SI (match_operand:QI 1 "address_operand" "U,W")
1243                (const_int 2147483647)))]
1244  "!TARGET_64BIT"
1245  "@
1246   la\t%0,%a1
1247   lay\t%0,%a1"
1248  [(set_attr "op_type"  "RX,RXY")
1249   (set_attr "type"     "la")])
1250
1251(define_insn_and_split "*la_31_and_cc"
1252  [(set (match_operand:SI 0 "register_operand" "=d")
1253        (and:SI (match_operand:QI 1 "address_operand" "p")
1254                (const_int 2147483647)))
1255   (clobber (reg:CC CC_REGNUM))]
1256  "!TARGET_64BIT"
1257  "#"
1258  "&& reload_completed"
1259  [(set (match_dup 0)
1260        (and:SI (match_dup 1) (const_int 2147483647)))]
1261  ""
1262  [(set_attr "op_type"  "RX")
1263   (set_attr "type"     "la")])
1264
1265(define_insn "force_la_31"
1266  [(set (match_operand:SI 0 "register_operand" "=d,d")
1267        (match_operand:QI 1 "address_operand" "U,W"))
1268   (use (const_int 0))]
1269  "!TARGET_64BIT"
1270  "@
1271   la\t%0,%a1
1272   lay\t%0,%a1"
1273  [(set_attr "op_type"  "RX")
1274   (set_attr "type"     "la")])
1275
1276(define_expand "reload_insi"
1277  [(parallel [(match_operand:SI 0 "register_operand" "=a")
1278              (match_operand:SI 1 "s390_plus_operand" "")
1279              (match_operand:SI 2 "register_operand" "=&a")])]
1280  "!TARGET_64BIT"
1281{
1282  s390_expand_plus_operand (operands[0], operands[1], operands[2]);
1283  DONE;
1284})
1285
1286;
1287; movhi instruction pattern(s).
1288;
1289
1290(define_expand "movhi"
1291  [(set (match_operand:HI 0 "nonimmediate_operand" "")
1292        (match_operand:HI 1 "general_operand" ""))]
1293  ""
1294{
1295  /* Make it explicit that loading a register from memory
1296     always sign-extends (at least) to SImode.  */
1297  if (optimize && !no_new_pseudos
1298      && register_operand (operands[0], VOIDmode)
1299      && GET_CODE (operands[1]) == MEM)
1300    {
1301      rtx tmp = gen_reg_rtx (SImode);
1302      rtx ext = gen_rtx_SIGN_EXTEND (SImode, operands[1]);
1303      emit_insn (gen_rtx_SET (VOIDmode, tmp, ext));
1304      operands[1] = gen_lowpart (HImode, tmp);
1305    }
1306})
1307
1308(define_insn "*movhi"
1309  [(set (match_operand:HI 0 "nonimmediate_operand" "=d,d,d,d,R,T,?Q")
1310        (match_operand:HI 1 "general_operand" "d,n,R,T,d,d,?Q"))]
1311  ""
1312  "@
1313   lr\t%0,%1
1314   lhi\t%0,%h1
1315   lh\t%0,%1
1316   lhy\t%0,%1
1317   sth\t%1,%0
1318   sthy\t%1,%0
1319   #"
1320  [(set_attr "op_type" "RR,RI,RX,RXY,RX,RXY,SS")
1321   (set_attr "type" "lr,*,*,*,store,store,*")])
1322
1323(define_peephole2
1324  [(set (match_operand:HI 0 "register_operand" "")
1325        (mem:HI (match_operand 1 "address_operand" "")))]
1326  "GET_CODE (operands[1]) == SYMBOL_REF
1327   && CONSTANT_POOL_ADDRESS_P (operands[1])
1328   && get_pool_mode (operands[1]) == HImode
1329   && GET_CODE (get_pool_constant (operands[1])) == CONST_INT"
1330  [(set (match_dup 0) (match_dup 2))]
1331  "operands[2] = get_pool_constant (operands[1]);")
1332
1333;
1334; movqi instruction pattern(s).
1335;
1336
1337(define_expand "movqi"
1338  [(set (match_operand:QI 0 "nonimmediate_operand" "")
1339        (match_operand:QI 1 "general_operand" ""))]
1340  ""
1341{
1342  /* On z/Architecture, zero-extending from memory to register
1343     is just as fast as a QImode load.  */
1344  if (TARGET_ZARCH && optimize && !no_new_pseudos
1345      && register_operand (operands[0], VOIDmode)
1346      && GET_CODE (operands[1]) == MEM)
1347    {
1348      rtx tmp = gen_reg_rtx (word_mode);
1349      rtx ext = gen_rtx_ZERO_EXTEND (word_mode, operands[1]);
1350      emit_insn (gen_rtx_SET (VOIDmode, tmp, ext));
1351      operands[1] = gen_lowpart (QImode, tmp);
1352    }
1353})
1354
1355(define_insn "*movqi"
1356  [(set (match_operand:QI 0 "nonimmediate_operand" "=d,d,d,d,R,T,Q,S,?Q")
1357        (match_operand:QI 1 "general_operand" "d,n,R,T,d,d,n,n,?Q"))]
1358  ""
1359  "@
1360   lr\t%0,%1
1361   lhi\t%0,%b1
1362   ic\t%0,%1
1363   icy\t%0,%1
1364   stc\t%1,%0
1365   stcy\t%1,%0
1366   mvi\t%S0,%b1
1367   mviy\t%S0,%b1
1368   #"
1369  [(set_attr "op_type" "RR,RI,RX,RXY,RX,RXY,SI,SIY,SS")
1370   (set_attr "type" "lr,*,*,*,store,store,store,store,*")])
1371
1372(define_peephole2
1373  [(set (match_operand:QI 0 "nonimmediate_operand" "")
1374        (mem:QI (match_operand 1 "address_operand" "")))]
1375  "GET_CODE (operands[1]) == SYMBOL_REF
1376   && CONSTANT_POOL_ADDRESS_P (operands[1])
1377   && get_pool_mode (operands[1]) == QImode
1378   && GET_CODE (get_pool_constant (operands[1])) == CONST_INT"
1379  [(set (match_dup 0) (match_dup 2))]
1380  "operands[2] = get_pool_constant (operands[1]);")
1381
1382;
1383; movstrictqi instruction pattern(s).
1384;
1385
1386(define_insn "*movstrictqi"
1387  [(set (strict_low_part (match_operand:QI 0 "register_operand" "+d,d"))
1388                         (match_operand:QI 1 "memory_operand" "R,T"))]
1389  ""
1390  "@
1391   ic\t%0,%1
1392   icy\t%0,%1"
1393  [(set_attr "op_type"  "RX,RXY")])
1394
1395;
1396; movstricthi instruction pattern(s).
1397;
1398
1399(define_insn "*movstricthi"
1400  [(set (strict_low_part (match_operand:HI 0 "register_operand" "+d,d"))
1401                         (match_operand:HI 1 "memory_operand" "Q,S"))
1402   (clobber (reg:CC CC_REGNUM))]
1403  ""
1404  "@
1405   icm\t%0,3,%S1
1406   icmy\t%0,3,%S1"
1407  [(set_attr "op_type" "RS,RSY")])
1408
1409;
1410; movstrictsi instruction pattern(s).
1411;
1412
1413(define_insn "movstrictsi"
1414  [(set (strict_low_part (match_operand:SI 0 "register_operand" "+d,d,d,d"))
1415                         (match_operand:SI 1 "general_operand" "d,R,T,t"))]
1416  "TARGET_64BIT"
1417  "@
1418   lr\t%0,%1
1419   l\t%0,%1
1420   ly\t%0,%1
1421   ear\t%0,%1"
1422  [(set_attr "op_type" "RR,RX,RXY,RRE")
1423   (set_attr "type" "lr,load,load,*")])
1424
1425;
1426; movtf instruction pattern(s).
1427;
1428
1429(define_expand "movtf"
1430  [(set (match_operand:TF 0 "nonimmediate_operand" "")
1431        (match_operand:TF 1 "general_operand"       ""))]
1432  ""
1433  "")
1434
1435(define_insn "*movtf_64"
1436  [(set (match_operand:TF 0 "nonimmediate_operand" "=f,f,f,o,d,QS,d,o,Q")
1437        (match_operand:TF 1 "general_operand"       "G,f,o,f,QS,d,dm,d,Q"))]
1438  "TARGET_64BIT"
1439  "@
1440   lzxr\t%0
1441   lxr\t%0,%1
1442   #
1443   #
1444   lmg\t%0,%N0,%S1
1445   stmg\t%1,%N1,%S0
1446   #
1447   #
1448   #"
1449  [(set_attr "op_type" "RRE,RRE,*,*,RSY,RSY,*,*,*")
1450   (set_attr "type"    "fsimptf,fsimptf,*,*,lm,stm,*,*,*")])
1451
1452(define_insn "*movtf_31"
1453  [(set (match_operand:TF 0 "nonimmediate_operand" "=f,f,f,o,Q")
1454        (match_operand:TF 1 "general_operand"       "G,f,o,f,Q"))]
1455  "!TARGET_64BIT"
1456  "@
1457   lzxr\t%0
1458   lxr\t%0,%1
1459   #
1460   #
1461   #"
1462  [(set_attr "op_type" "RRE,RRE,*,*,*")
1463   (set_attr "type"    "fsimptf,fsimptf,*,*,*")])
1464
1465; TFmode in GPRs splitters
1466
1467(define_split
1468  [(set (match_operand:TF 0 "nonimmediate_operand" "")
1469        (match_operand:TF 1 "general_operand" ""))]
1470  "TARGET_64BIT && reload_completed
1471   && s390_split_ok_p (operands[0], operands[1], TFmode, 0)"
1472  [(set (match_dup 2) (match_dup 4))
1473   (set (match_dup 3) (match_dup 5))]
1474{
1475  operands[2] = operand_subword (operands[0], 0, 0, TFmode);
1476  operands[3] = operand_subword (operands[0], 1, 0, TFmode);
1477  operands[4] = operand_subword (operands[1], 0, 0, TFmode);
1478  operands[5] = operand_subword (operands[1], 1, 0, TFmode);
1479})
1480
1481(define_split
1482  [(set (match_operand:TF 0 "nonimmediate_operand" "")
1483        (match_operand:TF 1 "general_operand" ""))]
1484  "TARGET_64BIT && reload_completed
1485   && s390_split_ok_p (operands[0], operands[1], TFmode, 1)"
1486  [(set (match_dup 2) (match_dup 4))
1487   (set (match_dup 3) (match_dup 5))]
1488{
1489  operands[2] = operand_subword (operands[0], 1, 0, TFmode);
1490  operands[3] = operand_subword (operands[0], 0, 0, TFmode);
1491  operands[4] = operand_subword (operands[1], 1, 0, TFmode);
1492  operands[5] = operand_subword (operands[1], 0, 0, TFmode);
1493})
1494
1495(define_split
1496  [(set (match_operand:TF 0 "register_operand" "")
1497        (match_operand:TF 1 "memory_operand" ""))]
1498  "TARGET_64BIT && reload_completed
1499   && !FP_REG_P (operands[0])
1500   && !s_operand (operands[1], VOIDmode)"
1501  [(set (match_dup 0) (match_dup 1))]
1502{
1503  rtx addr = operand_subword (operands[0], 1, 0, TFmode);
1504  s390_load_address (addr, XEXP (operands[1], 0));
1505  operands[1] = replace_equiv_address (operands[1], addr);
1506})
1507
1508; TFmode in FPRs splitters
1509
1510(define_split
1511  [(set (match_operand:TF 0 "register_operand" "")
1512        (match_operand:TF 1 "memory_operand" ""))]
1513  "reload_completed && offsettable_memref_p (operands[1]) 
1514   && FP_REG_P (operands[0])"
1515  [(set (match_dup 2) (match_dup 4))
1516   (set (match_dup 3) (match_dup 5))]
1517{
1518  operands[2] = simplify_gen_subreg (DFmode, operands[0], TFmode, 0);
1519  operands[3] = simplify_gen_subreg (DFmode, operands[0], TFmode, 8);
1520  operands[4] = adjust_address_nv (operands[1], DFmode, 0);
1521  operands[5] = adjust_address_nv (operands[1], DFmode, 8);
1522})
1523
1524(define_split
1525  [(set (match_operand:TF 0 "memory_operand" "")
1526        (match_operand:TF 1 "register_operand" ""))]
1527  "reload_completed && offsettable_memref_p (operands[0])
1528   && FP_REG_P (operands[1])"
1529  [(set (match_dup 2) (match_dup 4))
1530   (set (match_dup 3) (match_dup 5))]
1531{
1532  operands[2] = adjust_address_nv (operands[0], DFmode, 0);
1533  operands[3] = adjust_address_nv (operands[0], DFmode, 8);
1534  operands[4] = simplify_gen_subreg (DFmode, operands[1], TFmode, 0);
1535  operands[5] = simplify_gen_subreg (DFmode, operands[1], TFmode, 8);
1536})
1537
1538(define_expand "reload_outtf"
1539  [(parallel [(match_operand:TF 0 "" "")
1540              (match_operand:TF 1 "register_operand" "f")
1541              (match_operand:SI 2 "register_operand" "=&a")])]
1542  ""
1543{
1544  rtx addr = gen_lowpart (Pmode, operands[2]);
1545
1546  gcc_assert (MEM_P (operands[0]));
1547  s390_load_address (addr, find_replacement (&XEXP (operands[0], 0)));
1548  operands[0] = replace_equiv_address (operands[0], addr);
1549  emit_move_insn (operands[0], operands[1]);
1550  DONE;
1551})
1552
1553(define_expand "reload_intf"
1554  [(parallel [(match_operand:TF 0 "register_operand" "=f")
1555              (match_operand:TF 1 "" "")
1556              (match_operand:SI 2 "register_operand" "=&a")])]
1557  ""
1558{
1559  rtx addr = gen_lowpart (Pmode, operands[2]);
1560 
1561  gcc_assert (MEM_P (operands[1]));
1562  s390_load_address (addr, find_replacement (&XEXP (operands[1], 0)));
1563  operands[1] = replace_equiv_address (operands[1], addr);
1564  emit_move_insn (operands[0], operands[1]);
1565  DONE;
1566})
1567
1568;
1569; movdf instruction pattern(s).
1570;
1571
1572(define_expand "movdf"
1573  [(set (match_operand:DF 0 "nonimmediate_operand" "")
1574        (match_operand:DF 1 "general_operand"  ""))]
1575  ""
1576  "")
1577
1578(define_insn "*movdf_64"
1579  [(set (match_operand:DF 0 "nonimmediate_operand" "=f,f,f,f,R,T,d,d,m,?Q")
1580        (match_operand:DF 1 "general_operand" "G,f,R,T,f,f,d,m,d,?Q"))]
1581  "TARGET_64BIT"
1582  "@
1583   lzdr\t%0
1584   ldr\t%0,%1
1585   ld\t%0,%1
1586   ldy\t%0,%1
1587   std\t%1,%0
1588   stdy\t%1,%0
1589   lgr\t%0,%1
1590   lg\t%0,%1
1591   stg\t%1,%0
1592   #"
1593  [(set_attr "op_type" "RRE,RR,RX,RXY,RX,RXY,RRE,RXY,RXY,SS")
1594   (set_attr "type" "fsimpdf,floaddf,floaddf,floaddf,fstoredf,fstoredf,lr,load,store,*")])
1595
1596(define_insn "*movdf_31"
1597  [(set (match_operand:DF 0 "nonimmediate_operand" "=f,f,f,f,R,T,d,d,Q,S,d,o,Q")
1598        (match_operand:DF 1 "general_operand" "G,f,R,T,f,f,Q,S,d,d,dPm,d,Q"))]
1599  "!TARGET_64BIT"
1600  "@
1601   lzdr\t%0
1602   ldr\t%0,%1
1603   ld\t%0,%1
1604   ldy\t%0,%1
1605   std\t%1,%0
1606   stdy\t%1,%0
1607   lm\t%0,%N0,%S1
1608   lmy\t%0,%N0,%S1
1609   stm\t%1,%N1,%S0
1610   stmy\t%1,%N1,%S0
1611   #
1612   #
1613   #"
1614  [(set_attr "op_type" "RRE,RR,RX,RXY,RX,RXY,RS,RSY,RS,RSY,*,*,SS")
1615   (set_attr "type" "fsimpdf,floaddf,floaddf,floaddf,fstoredf,fstoredf,\
1616                     lm,lm,stm,stm,*,*,*")])
1617
1618(define_split
1619  [(set (match_operand:DF 0 "nonimmediate_operand" "")
1620        (match_operand:DF 1 "general_operand" ""))]
1621  "!TARGET_64BIT && reload_completed
1622   && s390_split_ok_p (operands[0], operands[1], DFmode, 0)"
1623  [(set (match_dup 2) (match_dup 4))
1624   (set (match_dup 3) (match_dup 5))]
1625{
1626  operands[2] = operand_subword (operands[0], 0, 0, DFmode);
1627  operands[3] = operand_subword (operands[0], 1, 0, DFmode);
1628  operands[4] = operand_subword (operands[1], 0, 0, DFmode);
1629  operands[5] = operand_subword (operands[1], 1, 0, DFmode);
1630})
1631
1632(define_split
1633  [(set (match_operand:DF 0 "nonimmediate_operand" "")
1634        (match_operand:DF 1 "general_operand" ""))]
1635  "!TARGET_64BIT && reload_completed
1636   && s390_split_ok_p (operands[0], operands[1], DFmode, 1)"
1637  [(set (match_dup 2) (match_dup 4))
1638   (set (match_dup 3) (match_dup 5))]
1639{
1640  operands[2] = operand_subword (operands[0], 1, 0, DFmode);
1641  operands[3] = operand_subword (operands[0], 0, 0, DFmode);
1642  operands[4] = operand_subword (operands[1], 1, 0, DFmode);
1643  operands[5] = operand_subword (operands[1], 0, 0, DFmode);
1644})
1645
1646(define_split
1647  [(set (match_operand:DF 0 "register_operand" "")
1648        (match_operand:DF 1 "memory_operand" ""))]
1649  "!TARGET_64BIT && reload_completed
1650   && !FP_REG_P (operands[0])
1651   && !s_operand (operands[1], VOIDmode)"
1652  [(set (match_dup 0) (match_dup 1))]
1653{
1654  rtx addr = operand_subword (operands[0], 1, 0, DFmode);
1655  s390_load_address (addr, XEXP (operands[1], 0));
1656  operands[1] = replace_equiv_address (operands[1], addr);
1657})
1658
1659(define_expand "reload_outdf"
1660  [(parallel [(match_operand:DF 0 "" "")
1661              (match_operand:DF 1 "register_operand" "d")
1662              (match_operand:SI 2 "register_operand" "=&a")])]
1663  "!TARGET_64BIT"
1664{
1665  gcc_assert (MEM_P (operands[0]));
1666  s390_load_address (operands[2], find_replacement (&XEXP (operands[0], 0)));
1667  operands[0] = replace_equiv_address (operands[0], operands[2]);
1668  emit_move_insn (operands[0], operands[1]);
1669  DONE;
1670})
1671
1672;
1673; movsf instruction pattern(s).
1674;
1675
1676(define_insn "movsf"
1677  [(set (match_operand:SF 0 "nonimmediate_operand" "=f,f,f,f,R,T,d,d,d,R,T,?Q")
1678        (match_operand:SF 1 "general_operand" "G,f,R,T,f,f,d,R,T,d,d,?Q"))]
1679  ""
1680  "@
1681   lzer\t%0
1682   ler\t%0,%1
1683   le\t%0,%1
1684   ley\t%0,%1
1685   ste\t%1,%0
1686   stey\t%1,%0
1687   lr\t%0,%1
1688   l\t%0,%1
1689   ly\t%0,%1
1690   st\t%1,%0
1691   sty\t%1,%0
1692   #"
1693  [(set_attr "op_type" "RRE,RR,RX,RXY,RX,RXY,RR,RX,RXY,RX,RXY,SS")
1694   (set_attr "type" "fsimpsf,floadsf,floadsf,floadsf,fstoresf,fstoresf,
1695                     lr,load,load,store,store,*")])
1696
1697;
1698; movcc instruction pattern
1699;
1700
1701(define_insn "movcc"
1702  [(set (match_operand:CC 0 "nonimmediate_operand" "=d,c,d,d,d,R,T")
1703	(match_operand:CC 1 "nonimmediate_operand" "d,d,c,R,T,d,d"))]
1704  ""
1705  "@
1706   lr\t%0,%1
1707   tmh\t%1,12288
1708   ipm\t%0
1709   st\t%0,%1
1710   sty\t%0,%1
1711   l\t%1,%0
1712   ly\t%1,%0"
1713  [(set_attr "op_type" "RR,RI,RRE,RX,RXY,RX,RXY")
1714   (set_attr "type" "lr,*,*,store,store,load,load")])
1715
1716;
1717; Block move (MVC) patterns.
1718;
1719
1720(define_insn "*mvc"
1721  [(set (match_operand:BLK 0 "memory_operand" "=Q")
1722        (match_operand:BLK 1 "memory_operand" "Q"))
1723   (use (match_operand 2 "const_int_operand" "n"))]
1724  "INTVAL (operands[2]) >= 1 && INTVAL (operands[2]) <= 256"
1725  "mvc\t%O0(%2,%R0),%S1"
1726  [(set_attr "op_type" "SS")])
1727
1728(define_split
1729  [(set (match_operand 0 "memory_operand" "")
1730        (match_operand 1 "memory_operand" ""))]
1731  "reload_completed
1732   && GET_MODE (operands[0]) == GET_MODE (operands[1])
1733   && GET_MODE_SIZE (GET_MODE (operands[0])) > 0"
1734  [(parallel
1735    [(set (match_dup 0) (match_dup 1))
1736     (use (match_dup 2))])]
1737{
1738  operands[2] = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[0])));
1739  operands[0] = adjust_address (operands[0], BLKmode, 0);
1740  operands[1] = adjust_address (operands[1], BLKmode, 0);
1741})
1742
1743(define_peephole2
1744  [(parallel
1745    [(set (match_operand:BLK 0 "memory_operand" "")
1746          (match_operand:BLK 1 "memory_operand" ""))
1747     (use (match_operand 2 "const_int_operand" ""))])
1748   (parallel
1749    [(set (match_operand:BLK 3 "memory_operand" "")
1750          (match_operand:BLK 4 "memory_operand" ""))
1751     (use (match_operand 5 "const_int_operand" ""))])]
1752  "s390_offset_p (operands[0], operands[3], operands[2])
1753   && s390_offset_p (operands[1], operands[4], operands[2])
1754   && !s390_overlap_p (operands[0], operands[1], 
1755                       INTVAL (operands[2]) + INTVAL (operands[5]))
1756   && INTVAL (operands[2]) + INTVAL (operands[5]) <= 256"
1757  [(parallel
1758    [(set (match_dup 6) (match_dup 7))
1759     (use (match_dup 8))])]
1760  "operands[6] = gen_rtx_MEM (BLKmode, XEXP (operands[0], 0));
1761   operands[7] = gen_rtx_MEM (BLKmode, XEXP (operands[1], 0));
1762   operands[8] = GEN_INT (INTVAL (operands[2]) + INTVAL (operands[5]));")
1763
1764
1765;
1766; load_multiple pattern(s).
1767;
1768; ??? Due to reload problems with replacing registers inside match_parallel
1769; we currently support load_multiple/store_multiple only after reload.
1770;
1771
1772(define_expand "load_multiple"
1773  [(match_par_dup 3 [(set (match_operand 0 "" "")
1774			  (match_operand 1 "" ""))
1775		     (use (match_operand 2 "" ""))])]
1776  "reload_completed"
1777{
1778  enum machine_mode mode;
1779  int regno;
1780  int count;
1781  rtx from;
1782  int i, off;
1783
1784  /* Support only loading a constant number of fixed-point registers from
1785     memory and only bother with this if more than two */
1786  if (GET_CODE (operands[2]) != CONST_INT
1787      || INTVAL (operands[2]) < 2
1788      || INTVAL (operands[2]) > 16
1789      || GET_CODE (operands[1]) != MEM
1790      || GET_CODE (operands[0]) != REG
1791      || REGNO (operands[0]) >= 16)
1792    FAIL;
1793
1794  count = INTVAL (operands[2]);
1795  regno = REGNO (operands[0]);
1796  mode = GET_MODE (operands[0]);
1797  if (mode != SImode && mode != word_mode)
1798    FAIL;
1799
1800  operands[3] = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (count));
1801  if (no_new_pseudos)
1802    {
1803      if (GET_CODE (XEXP (operands[1], 0)) == REG)
1804	{
1805	  from = XEXP (operands[1], 0);
1806	  off = 0;
1807	}
1808      else if (GET_CODE (XEXP (operands[1], 0)) == PLUS
1809	       && GET_CODE (XEXP (XEXP (operands[1], 0), 0)) == REG
1810	       && GET_CODE (XEXP (XEXP (operands[1], 0), 1)) == CONST_INT)
1811	{
1812	  from = XEXP (XEXP (operands[1], 0), 0);
1813	  off = INTVAL (XEXP (XEXP (operands[1], 0), 1));
1814	}
1815      else
1816	FAIL;
1817    }
1818  else
1819    {
1820      from = force_reg (Pmode, XEXP (operands[1], 0));
1821      off = 0;
1822    }
1823
1824  for (i = 0; i < count; i++)
1825    XVECEXP (operands[3], 0, i)
1826      = gen_rtx_SET (VOIDmode, gen_rtx_REG (mode, regno + i),
1827		     change_address (operands[1], mode,
1828		       plus_constant (from, off + i * GET_MODE_SIZE (mode))));
1829})
1830
1831(define_insn "*load_multiple_di"
1832  [(match_parallel 0 "load_multiple_operation"
1833		   [(set (match_operand:DI 1 "register_operand" "=r")
1834			 (match_operand:DI 2 "s_operand" "QS"))])]
1835  "reload_completed && word_mode == DImode"
1836{
1837  int words = XVECLEN (operands[0], 0);
1838  operands[0] = gen_rtx_REG (DImode, REGNO (operands[1]) + words - 1);
1839  return "lmg\t%1,%0,%S2";
1840}
1841   [(set_attr "op_type" "RSY")
1842    (set_attr "type"    "lm")])
1843
1844(define_insn "*load_multiple_si"
1845  [(match_parallel 0 "load_multiple_operation"
1846		   [(set (match_operand:SI 1 "register_operand" "=r,r")
1847			 (match_operand:SI 2 "s_operand" "Q,S"))])]
1848  "reload_completed"
1849{
1850  int words = XVECLEN (operands[0], 0);
1851  operands[0] = gen_rtx_REG (SImode, REGNO (operands[1]) + words - 1);
1852  return which_alternative == 0 ? "lm\t%1,%0,%S2" : "lmy\t%1,%0,%S2";
1853}
1854   [(set_attr "op_type" "RS,RSY")
1855    (set_attr "type"    "lm")])
1856
1857;
1858; store multiple pattern(s).
1859;
1860
1861(define_expand "store_multiple"
1862  [(match_par_dup 3 [(set (match_operand 0 "" "")
1863			  (match_operand 1 "" ""))
1864		     (use (match_operand 2 "" ""))])]
1865  "reload_completed"
1866{
1867  enum machine_mode mode;
1868  int regno;
1869  int count;
1870  rtx to;
1871  int i, off;
1872
1873  /* Support only storing a constant number of fixed-point registers to
1874     memory and only bother with this if more than two.  */
1875  if (GET_CODE (operands[2]) != CONST_INT
1876      || INTVAL (operands[2]) < 2
1877      || INTVAL (operands[2]) > 16
1878      || GET_CODE (operands[0]) != MEM
1879      || GET_CODE (operands[1]) != REG
1880      || REGNO (operands[1]) >= 16)
1881    FAIL;
1882
1883  count = INTVAL (operands[2]);
1884  regno = REGNO (operands[1]);
1885  mode = GET_MODE (operands[1]);
1886  if (mode != SImode && mode != word_mode)
1887    FAIL;
1888
1889  operands[3] = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (count));
1890
1891  if (no_new_pseudos)
1892    {
1893      if (GET_CODE (XEXP (operands[0], 0)) == REG)
1894	{
1895	  to = XEXP (operands[0], 0);
1896	  off = 0;
1897	}
1898      else if (GET_CODE (XEXP (operands[0], 0)) == PLUS
1899	       && GET_CODE (XEXP (XEXP (operands[0], 0), 0)) == REG
1900	       && GET_CODE (XEXP (XEXP (operands[0], 0), 1)) == CONST_INT)
1901	{
1902	  to = XEXP (XEXP (operands[0], 0), 0);
1903	  off = INTVAL (XEXP (XEXP (operands[0], 0), 1));
1904	}
1905      else
1906	FAIL;
1907    }
1908  else
1909    {
1910      to = force_reg (Pmode, XEXP (operands[0], 0));
1911      off = 0;
1912    }
1913
1914  for (i = 0; i < count; i++)
1915    XVECEXP (operands[3], 0, i)
1916      = gen_rtx_SET (VOIDmode,
1917		     change_address (operands[0], mode,
1918		       plus_constant (to, off + i * GET_MODE_SIZE (mode))),
1919		     gen_rtx_REG (mode, regno + i));
1920})
1921
1922(define_insn "*store_multiple_di"
1923  [(match_parallel 0 "store_multiple_operation"
1924		   [(set (match_operand:DI 1 "s_operand" "=QS")
1925			 (match_operand:DI 2 "register_operand" "r"))])]
1926  "reload_completed && word_mode == DImode"
1927{
1928  int words = XVECLEN (operands[0], 0);
1929  operands[0] = gen_rtx_REG (DImode, REGNO (operands[2]) + words - 1);
1930  return "stmg\t%2,%0,%S1";
1931}
1932   [(set_attr "op_type" "RSY")
1933    (set_attr "type"    "stm")])
1934
1935
1936(define_insn "*store_multiple_si"
1937  [(match_parallel 0 "store_multiple_operation"
1938		   [(set (match_operand:SI 1 "s_operand" "=Q,S")
1939			 (match_operand:SI 2 "register_operand" "r,r"))])]
1940  "reload_completed"
1941{
1942  int words = XVECLEN (operands[0], 0);
1943  operands[0] = gen_rtx_REG (SImode, REGNO (operands[2]) + words - 1);
1944  return which_alternative == 0 ? "stm\t%2,%0,%S1" : "stmy\t%2,%0,%S1";
1945}
1946   [(set_attr "op_type" "RS,RSY")
1947    (set_attr "type"    "stm")])
1948
1949;;
1950;; String instructions.
1951;;
1952
1953(define_insn "*execute"
1954  [(match_parallel 0 ""
1955    [(unspec [(match_operand 1 "register_operand" "a")
1956              (match_operand:BLK 2 "memory_operand" "R")
1957              (match_operand 3 "" "")] UNSPEC_EXECUTE)])]
1958  "GET_MODE_CLASS (GET_MODE (operands[1])) == MODE_INT
1959   && GET_MODE_SIZE (GET_MODE (operands[1])) <= UNITS_PER_WORD"
1960  "ex\t%1,%2"
1961  [(set_attr "op_type" "RX")
1962   (set_attr "type" "cs")])
1963
1964
1965;
1966; strlenM instruction pattern(s).
1967;
1968
1969(define_expand "strlen<mode>"
1970  [(set (reg:SI 0) (match_operand:SI 2 "immediate_operand" ""))
1971   (parallel
1972    [(set (match_dup 4)
1973	  (unspec:P [(const_int 0)
1974		      (match_operand:BLK 1 "memory_operand" "")
1975		      (reg:SI 0)
1976		      (match_operand 3 "immediate_operand" "")] UNSPEC_SRST))
1977     (clobber (scratch:P))
1978     (clobber (reg:CC CC_REGNUM))])
1979   (parallel
1980    [(set (match_operand:P 0 "register_operand" "")
1981          (minus:P (match_dup 4) (match_dup 5)))
1982     (clobber (reg:CC CC_REGNUM))])]
1983  ""
1984{
1985  operands[4] = gen_reg_rtx (Pmode);
1986  operands[5] = gen_reg_rtx (Pmode);
1987  emit_move_insn (operands[5], force_operand (XEXP (operands[1], 0), NULL_RTX));
1988  operands[1] = replace_equiv_address (operands[1], operands[5]);
1989})
1990
1991(define_insn "*strlen<mode>"
1992  [(set (match_operand:P 0 "register_operand" "=a")
1993	(unspec:P [(match_operand:P 2 "general_operand" "0")
1994		    (mem:BLK (match_operand:P 3 "register_operand" "1"))
1995		    (reg:SI 0)
1996		    (match_operand 4 "immediate_operand" "")] UNSPEC_SRST))
1997   (clobber (match_scratch:P 1 "=a"))
1998   (clobber (reg:CC CC_REGNUM))]
1999  ""
2000  "srst\t%0,%1\;jo\t.-4"
2001  [(set_attr "length" "8")
2002   (set_attr "type" "vs")])
2003
2004;
2005; cmpstrM instruction pattern(s).
2006;
2007
2008(define_expand "cmpstrsi"
2009  [(set (reg:SI 0) (const_int 0))
2010   (parallel
2011    [(clobber (match_operand 3 "" ""))
2012     (clobber (match_dup 4))
2013     (set (reg:CCU CC_REGNUM)
2014	  (compare:CCU (match_operand:BLK 1 "memory_operand" "")
2015	 	       (match_operand:BLK 2 "memory_operand" "")))
2016     (use (reg:SI 0))])
2017   (parallel
2018    [(set (match_operand:SI 0 "register_operand" "=d")
2019	  (unspec:SI [(reg:CCU CC_REGNUM)] UNSPEC_CMPINT))
2020     (clobber (reg:CC CC_REGNUM))])]
2021  ""
2022{
2023  /* As the result of CMPINT is inverted compared to what we need,
2024     we have to swap the operands.  */
2025  rtx op1 = operands[2];
2026  rtx op2 = operands[1];
2027  rtx addr1 = gen_reg_rtx (Pmode);
2028  rtx addr2 = gen_reg_rtx (Pmode);
2029
2030  emit_move_insn (addr1, force_operand (XEXP (op1, 0), NULL_RTX));
2031  emit_move_insn (addr2, force_operand (XEXP (op2, 0), NULL_RTX));
2032  operands[1] = replace_equiv_address_nv (op1, addr1);
2033  operands[2] = replace_equiv_address_nv (op2, addr2);
2034  operands[3] = addr1;
2035  operands[4] = addr2;
2036})
2037
2038(define_insn "*cmpstr<mode>"
2039  [(clobber (match_operand:P 0 "register_operand" "=d"))
2040   (clobber (match_operand:P 1 "register_operand" "=d"))
2041   (set (reg:CCU CC_REGNUM)
2042	(compare:CCU (mem:BLK (match_operand:P 2 "register_operand" "0"))
2043		     (mem:BLK (match_operand:P 3 "register_operand" "1"))))
2044   (use (reg:SI 0))]
2045  ""
2046  "clst\t%0,%1\;jo\t.-4"
2047  [(set_attr "length" "8")
2048   (set_attr "type" "vs")])
2049 
2050;
2051; movstr instruction pattern.
2052;
2053
2054(define_expand "movstr"
2055  [(set (reg:SI 0) (const_int 0))
2056   (parallel 
2057    [(clobber (match_dup 3))
2058     (set (match_operand:BLK 1 "memory_operand" "")
2059	  (match_operand:BLK 2 "memory_operand" ""))
2060     (set (match_operand 0 "register_operand" "")
2061	  (unspec [(match_dup 1) 
2062		   (match_dup 2)
2063		   (reg:SI 0)] UNSPEC_MVST))
2064     (clobber (reg:CC CC_REGNUM))])]
2065  ""
2066{
2067  rtx addr1 = gen_reg_rtx (Pmode);
2068  rtx addr2 = gen_reg_rtx (Pmode);
2069
2070  emit_move_insn (addr1, force_operand (XEXP (operands[1], 0), NULL_RTX));
2071  emit_move_insn (addr2, force_operand (XEXP (operands[2], 0), NULL_RTX));
2072  operands[1] = replace_equiv_address_nv (operands[1], addr1);
2073  operands[2] = replace_equiv_address_nv (operands[2], addr2);
2074  operands[3] = addr2;
2075})
2076
2077(define_insn "*movstr"
2078  [(clobber (match_operand:P 2 "register_operand" "=d"))
2079   (set (mem:BLK (match_operand:P 1 "register_operand" "0"))
2080	(mem:BLK (match_operand:P 3 "register_operand" "2")))
2081   (set (match_operand:P 0 "register_operand" "=d")
2082	(unspec [(mem:BLK (match_dup 1)) 
2083		 (mem:BLK (match_dup 3))
2084		 (reg:SI 0)] UNSPEC_MVST))
2085   (clobber (reg:CC CC_REGNUM))]
2086  ""
2087  "mvst\t%1,%2\;jo\t.-4"
2088  [(set_attr "length" "8")
2089   (set_attr "type" "vs")])
2090  
2091
2092;
2093; movmemM instruction pattern(s).
2094;
2095
2096(define_expand "movmem<mode>"
2097  [(set (match_operand:BLK 0 "memory_operand" "")
2098        (match_operand:BLK 1 "memory_operand" ""))
2099   (use (match_operand:GPR 2 "general_operand" ""))
2100   (match_operand 3 "" "")]
2101  ""
2102  "s390_expand_movmem (operands[0], operands[1], operands[2]); DONE;")
2103
2104; Move a block that is up to 256 bytes in length.
2105; The block length is taken as (operands[2] % 256) + 1.
2106
2107(define_expand "movmem_short"
2108  [(parallel
2109    [(set (match_operand:BLK 0 "memory_operand" "")
2110          (match_operand:BLK 1 "memory_operand" ""))
2111     (use (match_operand 2 "nonmemory_operand" ""))
2112     (use (const:BLK (unspec:BLK [(const_int 0)] UNSPEC_INSN)))
2113     (clobber (match_dup 3))])]
2114  ""
2115  "operands[3] = gen_rtx_SCRATCH (Pmode);")
2116
2117(define_insn "*movmem_short"
2118  [(set (match_operand:BLK 0 "memory_operand" "=Q,Q,Q")
2119        (match_operand:BLK 1 "memory_operand" "Q,Q,Q"))
2120   (use (match_operand 2 "nonmemory_operand" "n,a,a"))
2121   (use (match_operand 3 "immediate_operand" "X,R,X"))
2122   (clobber (match_scratch 4 "=X,X,&a"))]
2123  "(GET_MODE (operands[2]) == Pmode || GET_MODE (operands[2]) == VOIDmode)
2124   && GET_MODE (operands[4]) == Pmode"
2125  "#"
2126  [(set_attr "type" "cs")])
2127
2128(define_split
2129  [(set (match_operand:BLK 0 "memory_operand" "")
2130        (match_operand:BLK 1 "memory_operand" ""))
2131   (use (match_operand 2 "const_int_operand" ""))
2132   (use (match_operand 3 "immediate_operand" ""))
2133   (clobber (scratch))]
2134  "reload_completed"
2135  [(parallel
2136    [(set (match_dup 0) (match_dup 1))
2137     (use (match_dup 2))])]
2138  "operands[2] = GEN_INT ((INTVAL (operands[2]) & 0xff) + 1);")
2139
2140(define_split
2141  [(set (match_operand:BLK 0 "memory_operand" "")
2142        (match_operand:BLK 1 "memory_operand" ""))
2143   (use (match_operand 2 "register_operand" ""))
2144   (use (match_operand 3 "memory_operand" ""))
2145   (clobber (scratch))]
2146  "reload_completed"
2147  [(parallel
2148    [(unspec [(match_dup 2) (match_dup 3)
2149              (const_int 0)] UNSPEC_EXECUTE)
2150     (set (match_dup 0) (match_dup 1))
2151     (use (const_int 1))])]
2152  "")
2153
2154(define_split
2155  [(set (match_operand:BLK 0 "memory_operand" "")
2156        (match_operand:BLK 1 "memory_operand" ""))
2157   (use (match_operand 2 "register_operand" ""))
2158   (use (const:BLK (unspec:BLK [(const_int 0)] UNSPEC_INSN)))
2159   (clobber (match_operand 3 "register_operand" ""))]
2160  "reload_completed && TARGET_CPU_ZARCH"
2161  [(set (match_dup 3) (label_ref (match_dup 4)))
2162   (parallel
2163    [(unspec [(match_dup 2) (mem:BLK (match_dup 3)) 
2164              (label_ref (match_dup 4))] UNSPEC_EXECUTE)
2165     (set (match_dup 0) (match_dup 1))
2166     (use (const_int 1))])]
2167  "operands[4] = gen_label_rtx ();")
2168
2169; Move a block of arbitrary length.
2170
2171(define_expand "movmem_long"
2172  [(parallel
2173    [(clobber (match_dup 2))
2174     (clobber (match_dup 3))
2175     (set (match_operand:BLK 0 "memory_operand" "")
2176          (match_operand:BLK 1 "memory_operand" ""))
2177     (use (match_operand 2 "general_operand" ""))
2178     (use (match_dup 3))
2179     (clobber (reg:CC CC_REGNUM))])]
2180  ""
2181{
2182  enum machine_mode dword_mode = word_mode == DImode ? TImode : DImode;
2183  rtx reg0 = gen_reg_rtx (dword_mode);
2184  rtx reg1 = gen_reg_rtx (dword_mode);
2185  rtx addr0 = gen_lowpart (Pmode, gen_highpart (word_mode, reg0));
2186  rtx addr1 = gen_lowpart (Pmode, gen_highpart (word_mode, reg1));
2187  rtx len0 = gen_lowpart (Pmode, reg0);
2188  rtx len1 = gen_lowpart (Pmode, reg1);
2189
2190  emit_insn (gen_rtx_CLOBBER (VOIDmode, reg0));
2191  emit_move_insn (addr0, force_operand (XEXP (operands[0], 0), NULL_RTX));
2192  emit_move_insn (len0, operands[2]);
2193
2194  emit_insn (gen_rtx_CLOBBER (VOIDmode, reg1));
2195  emit_move_insn (addr1, force_operand (XEXP (operands[1], 0), NULL_RTX));
2196  emit_move_insn (len1, operands[2]);
2197
2198  operands[0] = replace_equiv_address_nv (operands[0], addr0);
2199  operands[1] = replace_equiv_address_nv (operands[1], addr1);
2200  operands[2] = reg0;
2201  operands[3] = reg1;
2202})
2203
2204(define_insn "*movmem_long"
2205  [(clobber (match_operand:<DBL> 0 "register_operand" "=d"))
2206   (clobber (match_operand:<DBL> 1 "register_operand" "=d"))
2207   (set (mem:BLK (subreg:P (match_operand:<DBL> 2 "register_operand" "0") 0))
2208        (mem:BLK (subreg:P (match_operand:<DBL> 3 "register_operand" "1") 0)))
2209   (use (match_dup 2))
2210   (use (match_dup 3))
2211   (clobber (reg:CC CC_REGNUM))]
2212  ""
2213  "mvcle\t%0,%1,0\;jo\t.-4"
2214  [(set_attr "length" "8")
2215   (set_attr "type" "vs")])
2216
2217;
2218; setmemM instruction pattern(s).
2219;
2220
2221(define_expand "setmem<mode>"
2222  [(set (match_operand:BLK 0 "memory_operand" "")
2223        (match_operand:QI 2 "general_operand" ""))
2224   (use (match_operand:GPR 1 "general_operand" ""))
2225   (match_operand 3 "" "")]
2226  ""
2227  "s390_expand_setmem (operands[0], operands[1], operands[2]); DONE;")
2228
2229; Clear a block that is up to 256 bytes in length.
2230; The block length is taken as (operands[1] % 256) + 1.
2231
2232(define_expand "clrmem_short"
2233  [(parallel
2234    [(set (match_operand:BLK 0 "memory_operand" "")
2235          (const_int 0))
2236     (use (match_operand 1 "nonmemory_operand" ""))
2237     (use (const:BLK (unspec:BLK [(const_int 0)] UNSPEC_INSN)))
2238     (clobber (match_dup 2))
2239     (clobber (reg:CC CC_REGNUM))])]
2240  ""
2241  "operands[2] = gen_rtx_SCRATCH (Pmode);")
2242
2243(define_insn "*clrmem_short"
2244  [(set (match_operand:BLK 0 "memory_operand" "=Q,Q,Q")
2245        (const_int 0))
2246   (use (match_operand 1 "nonmemory_operand" "n,a,a"))
2247   (use (match_operand 2 "immediate_operand" "X,R,X"))
2248   (clobber (match_scratch 3 "=X,X,&a"))
2249   (clobber (reg:CC CC_REGNUM))]
2250  "(GET_MODE (operands[1]) == Pmode || GET_MODE (operands[1]) == VOIDmode)
2251   && GET_MODE (operands[3]) == Pmode"
2252  "#"
2253  [(set_attr "type" "cs")])
2254
2255(define_split
2256  [(set (match_operand:BLK 0 "memory_operand" "")
2257        (const_int 0))
2258   (use (match_operand 1 "const_int_operand" ""))
2259   (use (match_operand 2 "immediate_operand" ""))
2260   (clobber (scratch))
2261   (clobber (reg:CC CC_REGNUM))]
2262  "reload_completed"
2263  [(parallel
2264    [(set (match_dup 0) (const_int 0))
2265     (use (match_dup 1))
2266     (clobber (reg:CC CC_REGNUM))])]
2267  "operands[1] = GEN_INT ((INTVAL (operands[1]) & 0xff) + 1);")
2268
2269(define_split
2270  [(set (match_operand:BLK 0 "memory_operand" "")
2271        (const_int 0))
2272   (use (match_operand 1 "register_operand" ""))
2273   (use (match_operand 2 "memory_operand" ""))
2274   (clobber (scratch))
2275   (clobber (reg:CC CC_REGNUM))]
2276  "reload_completed"
2277  [(parallel
2278    [(unspec [(match_dup 1) (match_dup 2)
2279              (const_int 0)] UNSPEC_EXECUTE)
2280     (set (match_dup 0) (const_int 0))
2281     (use (const_int 1))
2282     (clobber (reg:CC CC_REGNUM))])]
2283  "")
2284
2285(define_split
2286  [(set (match_operand:BLK 0 "memory_operand" "")
2287        (const_int 0))
2288   (use (match_operand 1 "register_operand" ""))
2289   (use (const:BLK (unspec:BLK [(const_int 0)] UNSPEC_INSN)))
2290   (clobber (match_operand 2 "register_operand" ""))
2291   (clobber (reg:CC CC_REGNUM))]
2292  "reload_completed && TARGET_CPU_ZARCH"
2293  [(set (match_dup 2) (label_ref (match_dup 3)))
2294   (parallel
2295    [(unspec [(match_dup 1) (mem:BLK (match_dup 2)) 
2296              (label_ref (match_dup 3))] UNSPEC_EXECUTE)
2297     (set (match_dup 0) (const_int 0))
2298     (use (const_int 1))
2299     (clobber (reg:CC CC_REGNUM))])]
2300  "operands[3] = gen_label_rtx ();")
2301
2302; Initialize a block of arbitrary length with (operands[2] % 256). 
2303
2304(define_expand "setmem_long"
2305  [(parallel
2306    [(clobber (match_dup 1))
2307     (set (match_operand:BLK 0 "memory_operand" "")
2308          (match_operand 2 "shift_count_or_setmem_operand" ""))
2309     (use (match_operand 1 "general_operand" ""))
2310     (use (match_dup 3))
2311     (clobber (reg:CC CC_REGNUM))])]
2312  ""
2313{
2314  enum machine_mode dword_mode = word_mode == DImode ? TImode : DImode;
2315  rtx reg0 = gen_reg_rtx (dword_mode);
2316  rtx reg1 = gen_reg_rtx (dword_mode);
2317  rtx addr0 = gen_lowpart (Pmode, gen_highpart (word_mode, reg0));
2318  rtx len0 = gen_lowpart (Pmode, reg0);
2319
2320  emit_insn (gen_rtx_CLOBBER (VOIDmode, reg0));
2321  emit_move_insn (addr0, force_operand (XEXP (operands[0], 0), NULL_RTX));
2322  emit_move_insn (len0, operands[1]);
2323
2324  emit_move_insn (reg1, const0_rtx);
2325
2326  operands[0] = replace_equiv_address_nv (operands[0], addr0);
2327  operands[1] = reg0;
2328  operands[3] = reg1;
2329})
2330
2331(define_insn "*setmem_long"
2332  [(clobber (match_operand:<DBL> 0 "register_operand" "=d"))
2333   (set (mem:BLK (subreg:P (match_operand:<DBL> 3 "register_operand" "0") 0))
2334        (match_operand 2 "shift_count_or_setmem_operand" "Y"))
2335   (use (match_dup 3))
2336   (use (match_operand:<DBL> 1 "register_operand" "d"))
2337   (clobber (reg:CC CC_REGNUM))]
2338  ""
2339  "mvcle\t%0,%1,%Y2\;jo\t.-4"
2340  [(set_attr "length" "8")
2341   (set_attr "type" "vs")])
2342
2343(define_insn "*setmem_long_and"
2344  [(clobber (match_operand:<DBL> 0 "register_operand" "=d"))
2345   (set (mem:BLK (subreg:P (match_operand:<DBL> 3 "register_operand" "0") 0))
2346        (and (match_operand 2 "shift_count_or_setmem_operand" "Y")
2347	     (match_operand 4 "const_int_operand"             "n")))
2348   (use (match_dup 3))
2349   (use (match_operand:<DBL> 1 "register_operand" "d"))
2350   (clobber (reg:CC CC_REGNUM))]
2351  "(INTVAL (operands[4]) & 255) == 255"
2352  "mvcle\t%0,%1,%Y2\;jo\t.-4"
2353  [(set_attr "length" "8")
2354   (set_attr "type" "vs")])
2355;
2356; cmpmemM instruction pattern(s).
2357;
2358
2359(define_expand "cmpmemsi"
2360  [(set (match_operand:SI 0 "register_operand" "")
2361        (compare:SI (match_operand:BLK 1 "memory_operand" "")
2362                    (match_operand:BLK 2 "memory_operand" "") ) )
2363   (use (match_operand:SI 3 "general_operand" ""))
2364   (use (match_operand:SI 4 "" ""))]
2365  ""
2366  "s390_expand_cmpmem (operands[0], operands[1],
2367                       operands[2], operands[3]); DONE;")
2368
2369; Compare a block that is up to 256 bytes in length.
2370; The block length is taken as (operands[2] % 256) + 1.
2371
2372(define_expand "cmpmem_short"
2373  [(parallel
2374    [(set (reg:CCU CC_REGNUM)
2375          (compare:CCU (match_operand:BLK 0 "memory_operand" "")
2376                       (match_operand:BLK 1 "memory_operand" "")))
2377     (use (match_operand 2 "nonmemory_operand" ""))
2378     (use (const:BLK (unspec:BLK [(const_int 0)] UNSPEC_INSN)))
2379     (clobber (match_dup 3))])]
2380  ""
2381  "operands[3] = gen_rtx_SCRATCH (Pmode);")
2382
2383(define_insn "*cmpmem_short"
2384  [(set (reg:CCU CC_REGNUM)
2385        (compare:CCU (match_operand:BLK 0 "memory_operand" "Q,Q,Q")
2386                     (match_operand:BLK 1 "memory_operand" "Q,Q,Q")))
2387   (use (match_operand 2 "nonmemory_operand" "n,a,a"))
2388   (use (match_operand 3 "immediate_operand" "X,R,X"))
2389   (clobber (match_scratch 4 "=X,X,&a"))]
2390  "(GET_MODE (operands[2]) == Pmode || GET_MODE (operands[2]) == VOIDmode)
2391   && GET_MODE (operands[4]) == Pmode"
2392  "#"
2393  [(set_attr "type" "cs")])
2394
2395(define_split
2396  [(set (reg:CCU CC_REGNUM)
2397        (compare:CCU (match_operand:BLK 0 "memory_operand" "")
2398                     (match_operand:BLK 1 "memory_operand" "")))
2399   (use (match_operand 2 "const_int_operand" ""))
2400   (use (match_operand 3 "immediate_operand" ""))
2401   (clobber (scratch))]
2402  "reload_completed"
2403  [(parallel
2404    [(set (reg:CCU CC_REGNUM) (compare:CCU (match_dup 0) (match_dup 1)))
2405     (use (match_dup 2))])]
2406  "operands[2] = GEN_INT ((INTVAL (operands[2]) & 0xff) + 1);")
2407
2408(define_split
2409  [(set (reg:CCU CC_REGNUM)
2410        (compare:CCU (match_operand:BLK 0 "memory_operand" "")
2411                     (match_operand:BLK 1 "memory_operand" "")))
2412   (use (match_operand 2 "register_operand" ""))
2413   (use (match_operand 3 "memory_operand" ""))
2414   (clobber (scratch))]
2415  "reload_completed"
2416  [(parallel
2417    [(unspec [(match_dup 2) (match_dup 3)
2418              (const_int 0)] UNSPEC_EXECUTE)
2419     (set (reg:CCU CC_REGNUM) (compare:CCU (match_dup 0) (match_dup 1)))
2420     (use (const_int 1))])]
2421  "")
2422
2423(define_split
2424  [(set (reg:CCU CC_REGNUM)
2425        (compare:CCU (match_operand:BLK 0 "memory_operand" "")
2426                     (match_operand:BLK 1 "memory_operand" "")))
2427   (use (match_operand 2 "register_operand" ""))
2428   (use (const:BLK (unspec:BLK [(const_int 0)] UNSPEC_INSN)))
2429   (clobber (match_operand 3 "register_operand" ""))]
2430  "reload_completed && TARGET_CPU_ZARCH"
2431  [(set (match_dup 3) (label_ref (match_dup 4)))
2432   (parallel
2433    [(unspec [(match_dup 2) (mem:BLK (match_dup 3)) 
2434              (label_ref (match_dup 4))] UNSPEC_EXECUTE)
2435     (set (reg:CCU CC_REGNUM) (compare:CCU (match_dup 0) (match_dup 1)))
2436     (use (const_int 1))])]
2437  "operands[4] = gen_label_rtx ();")
2438
2439; Compare a block of arbitrary length.
2440
2441(define_expand "cmpmem_long"
2442  [(parallel
2443    [(clobber (match_dup 2))
2444     (clobber (match_dup 3))
2445     (set (reg:CCU CC_REGNUM)
2446          (compare:CCU (match_operand:BLK 0 "memory_operand" "")
2447                       (match_operand:BLK 1 "memory_operand" "")))
2448     (use (match_operand 2 "general_operand" ""))
2449     (use (match_dup 3))])]
2450  ""
2451{
2452  enum machine_mode dword_mode = word_mode == DImode ? TImode : DImode;
2453  rtx reg0 = gen_reg_rtx (dword_mode);
2454  rtx reg1 = gen_reg_rtx (dword_mode);
2455  rtx addr0 = gen_lowpart (Pmode, gen_highpart (word_mode, reg0));
2456  rtx addr1 = gen_lowpart (Pmode, gen_highpart (word_mode, reg1));
2457  rtx len0 = gen_lowpart (Pmode, reg0);
2458  rtx len1 = gen_lowpart (Pmode, reg1);
2459
2460  emit_insn (gen_rtx_CLOBBER (VOIDmode, reg0));
2461  emit_move_insn (addr0, force_operand (XEXP (operands[0], 0), NULL_RTX));
2462  emit_move_insn (len0, operands[2]);
2463
2464  emit_insn (gen_rtx_CLOBBER (VOIDmode, reg1));
2465  emit_move_insn (addr1, force_operand (XEXP (operands[1], 0), NULL_RTX));
2466  emit_move_insn (len1, operands[2]);
2467
2468  operands[0] = replace_equiv_address_nv (operands[0], addr0);
2469  operands[1] = replace_equiv_address_nv (operands[1], addr1);
2470  operands[2] = reg0;
2471  operands[3] = reg1;
2472})
2473
2474(define_insn "*cmpmem_long"
2475  [(clobber (match_operand:<DBL> 0 "register_operand" "=d"))
2476   (clobber (match_operand:<DBL> 1 "register_operand" "=d"))
2477   (set (reg:CCU CC_REGNUM)
2478        (compare:CCU (mem:BLK (subreg:P (match_operand:<DBL> 2 "register_operand" "0") 0))
2479                     (mem:BLK (subreg:P (match_operand:<DBL> 3 "register_operand" "1") 0))))
2480   (use (match_dup 2))
2481   (use (match_dup 3))]
2482  ""
2483  "clcle\t%0,%1,0\;jo\t.-4"
2484  [(set_attr "length" "8")
2485   (set_attr "type" "vs")])
2486
2487; Convert CCUmode condition code to integer.
2488; Result is zero if EQ, positive if LTU, negative if GTU.
2489
2490(define_insn_and_split "cmpint"
2491  [(set (match_operand:SI 0 "register_operand" "=d")
2492        (unspec:SI [(match_operand:CCU 1 "register_operand" "0")]
2493                   UNSPEC_CMPINT))
2494   (clobber (reg:CC CC_REGNUM))]
2495  ""
2496  "#"
2497  "reload_completed"
2498  [(set (match_dup 0) (ashift:SI (match_dup 0) (const_int 2)))
2499   (parallel
2500    [(set (match_dup 0) (ashiftrt:SI (match_dup 0) (const_int 30)))
2501     (clobber (reg:CC CC_REGNUM))])])
2502
2503(define_insn_and_split "*cmpint_cc"
2504  [(set (reg CC_REGNUM)
2505        (compare (unspec:SI [(match_operand:CCU 1 "register_operand" "0")]
2506                            UNSPEC_CMPINT)
2507                 (const_int 0)))
2508   (set (match_operand:SI 0 "register_operand" "=d")
2509        (unspec:SI [(match_dup 1)] UNSPEC_CMPINT))]
2510  "s390_match_ccmode (insn, CCSmode)"
2511  "#"
2512  "&& reload_completed"
2513  [(set (match_dup 0) (ashift:SI (match_dup 0) (const_int 2)))
2514   (parallel
2515    [(set (match_dup 2) (match_dup 3))
2516     (set (match_dup 0) (ashiftrt:SI (match_dup 0) (const_int 30)))])]
2517{
2518  rtx result = gen_rtx_ASHIFTRT (SImode, operands[0], GEN_INT (30));
2519  operands[2] = SET_DEST (XVECEXP (PATTERN (curr_insn), 0, 0));
2520  operands[3] = gen_rtx_COMPARE (GET_MODE (operands[2]), result, const0_rtx);
2521})
2522
2523(define_insn_and_split "*cmpint_sign"
2524  [(set (match_operand:DI 0 "register_operand" "=d")
2525        (sign_extend:DI (unspec:SI [(match_operand:CCU 1 "register_operand" "0")]
2526                                   UNSPEC_CMPINT)))
2527   (clobber (reg:CC CC_REGNUM))]
2528  "TARGET_64BIT"
2529  "#"
2530  "&& reload_completed"
2531  [(set (match_dup 0) (ashift:DI (match_dup 0) (const_int 34)))
2532   (parallel
2533    [(set (match_dup 0) (ashiftrt:DI (match_dup 0) (const_int 62)))
2534     (clobber (reg:CC CC_REGNUM))])])
2535
2536(define_insn_and_split "*cmpint_sign_cc"
2537  [(set (reg CC_REGNUM)
2538        (compare (ashiftrt:DI (ashift:DI (subreg:DI 
2539                   (unspec:SI [(match_operand:CCU 1 "register_operand" "0")]
2540                              UNSPEC_CMPINT) 0)
2541                   (const_int 32)) (const_int 32))
2542                 (const_int 0)))
2543   (set (match_operand:DI 0 "register_operand" "=d")
2544        (sign_extend:DI (unspec:SI [(match_dup 1)] UNSPEC_CMPINT)))]
2545  "s390_match_ccmode (insn, CCSmode) && TARGET_64BIT"
2546  "#"
2547  "&& reload_completed"
2548  [(set (match_dup 0) (ashift:DI (match_dup 0) (const_int 34)))
2549   (parallel
2550    [(set (match_dup 2) (match_dup 3))
2551     (set (match_dup 0) (ashiftrt:DI (match_dup 0) (const_int 62)))])]
2552{
2553  rtx result = gen_rtx_ASHIFTRT (DImode, operands[0], GEN_INT (62));
2554  operands[2] = SET_DEST (XVECEXP (PATTERN (curr_insn), 0, 0));
2555  operands[3] = gen_rtx_COMPARE (GET_MODE (operands[2]), result, const0_rtx);
2556})
2557
2558
2559;;
2560;;- Conversion instructions.
2561;;
2562
2563(define_insn "*sethighpartsi"
2564  [(set (match_operand:SI 0 "register_operand" "=d,d")
2565	(unspec:SI [(match_operand:BLK 1 "s_operand" "Q,S")
2566		    (match_operand 2 "const_int_operand" "n,n")] UNSPEC_ICM))
2567   (clobber (reg:CC CC_REGNUM))]
2568  ""
2569  "@
2570   icm\t%0,%2,%S1
2571   icmy\t%0,%2,%S1"
2572  [(set_attr "op_type" "RS,RSY")])
2573
2574(define_insn "*sethighpartdi_64"
2575  [(set (match_operand:DI 0 "register_operand" "=d")
2576	(unspec:DI [(match_operand:BLK 1 "s_operand" "QS")
2577		    (match_operand 2 "const_int_operand" "n")] UNSPEC_ICM))
2578   (clobber (reg:CC CC_REGNUM))]
2579  "TARGET_64BIT"
2580  "icmh\t%0,%2,%S1"
2581  [(set_attr "op_type" "RSY")])
2582
2583(define_insn "*sethighpartdi_31"
2584  [(set (match_operand:DI 0 "register_operand" "=d,d")
2585	(unspec:DI [(match_operand:BLK 1 "s_operand" "Q,S")
2586		    (match_operand 2 "const_int_operand" "n,n")] UNSPEC_ICM))
2587   (clobber (reg:CC CC_REGNUM))]
2588  "!TARGET_64BIT"
2589  "@
2590   icm\t%0,%2,%S1
2591   icmy\t%0,%2,%S1"
2592  [(set_attr "op_type" "RS,RSY")])
2593
2594(define_insn_and_split "*extzv<mode>"
2595  [(set (match_operand:GPR 0 "register_operand" "=d")
2596	(zero_extract:GPR (match_operand:QI 1 "s_operand" "QS")
2597		          (match_operand 2 "const_int_operand" "n")
2598		          (const_int 0)))
2599   (clobber (reg:CC CC_REGNUM))]
2600  "INTVAL (operands[2]) > 0
2601   && INTVAL (operands[2]) <= GET_MODE_BITSIZE (SImode)"
2602  "#"
2603  "&& reload_completed"
2604  [(parallel
2605    [(set (match_dup 0) (unspec:GPR [(match_dup 1) (match_dup 3)] UNSPEC_ICM))
2606     (clobber (reg:CC CC_REGNUM))])
2607   (set (match_dup 0) (lshiftrt:GPR (match_dup 0) (match_dup 2)))]
2608{
2609  int bitsize = INTVAL (operands[2]);
2610  int size = (bitsize - 1) / BITS_PER_UNIT + 1; /* round up */
2611  int mask = ((1ul << size) - 1) << (GET_MODE_SIZE (SImode) - size);
2612
2613  operands[1] = adjust_address (operands[1], BLKmode, 0);
2614  set_mem_size (operands[1], GEN_INT (size));
2615  operands[2] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode) - bitsize);
2616  operands[3] = GEN_INT (mask);
2617})
2618
2619(define_insn_and_split "*extv<mode>"
2620  [(set (match_operand:GPR 0 "register_operand" "=d")
2621	(sign_extract:GPR (match_operand:QI 1 "s_operand" "QS")
2622		          (match_operand 2 "const_int_operand" "n")
2623		          (const_int 0)))
2624   (clobber (reg:CC CC_REGNUM))]
2625  "INTVAL (operands[2]) > 0
2626   && INTVAL (operands[2]) <= GET_MODE_BITSIZE (SImode)"
2627  "#"
2628  "&& reload_completed"
2629  [(parallel
2630    [(set (match_dup 0) (unspec:GPR [(match_dup 1) (match_dup 3)] UNSPEC_ICM))
2631     (clobber (reg:CC CC_REGNUM))])
2632   (parallel
2633    [(set (match_dup 0) (ashiftrt:GPR (match_dup 0) (match_dup 2)))
2634     (clobber (reg:CC CC_REGNUM))])]
2635{
2636  int bitsize = INTVAL (operands[2]);
2637  int size = (bitsize - 1) / BITS_PER_UNIT + 1; /* round up */
2638  int mask = ((1ul << size) - 1) << (GET_MODE_SIZE (SImode) - size);
2639
2640  operands[1] = adjust_address (operands[1], BLKmode, 0);
2641  set_mem_size (operands[1], GEN_INT (size));
2642  operands[2] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode) - bitsize);
2643  operands[3] = GEN_INT (mask);
2644})
2645
2646;
2647; insv instruction patterns
2648;
2649
2650(define_expand "insv"
2651  [(set (zero_extract (match_operand 0 "nonimmediate_operand" "")
2652		      (match_operand 1 "const_int_operand" "")
2653		      (match_operand 2 "const_int_operand" ""))
2654	(match_operand 3 "general_operand" ""))]
2655  ""
2656{
2657  if (s390_expand_insv (operands[0], operands[1], operands[2], operands[3]))
2658    DONE;
2659  FAIL;
2660})
2661
2662(define_insn "*insv<mode>_mem_reg"
2663  [(set (zero_extract:P (match_operand:QI 0 "memory_operand" "+Q,S")
2664			(match_operand 1 "const_int_operand" "n,n")
2665			(const_int 0))
2666	(match_operand:P 2 "register_operand" "d,d"))]
2667  "INTVAL (operands[1]) > 0
2668   && INTVAL (operands[1]) <= GET_MODE_BITSIZE (SImode)
2669   && INTVAL (operands[1]) % BITS_PER_UNIT == 0"
2670{
2671    int size = INTVAL (operands[1]) / BITS_PER_UNIT;
2672
2673    operands[1] = GEN_INT ((1ul << size) - 1);
2674    return (which_alternative == 0) ? "stcm\t%2,%1,%S0" 
2675				    : "stcmy\t%2,%1,%S0";
2676}
2677  [(set_attr "op_type" "RS,RSY")])
2678
2679(define_insn "*insvdi_mem_reghigh"
2680  [(set (zero_extract:DI (match_operand:QI 0 "memory_operand" "+QS")
2681			 (match_operand 1 "const_int_operand" "n")
2682			 (const_int 0))
2683	(lshiftrt:DI (match_operand:DI 2 "register_operand" "d")
2684		     (const_int 32)))]
2685  "TARGET_64BIT
2686   && INTVAL (operands[1]) > 0
2687   && INTVAL (operands[1]) <= GET_MODE_BITSIZE (SImode)
2688   && INTVAL (operands[1]) % BITS_PER_UNIT == 0"
2689{
2690    int size = INTVAL (operands[1]) / BITS_PER_UNIT;
2691
2692    operands[1] = GEN_INT ((1ul << size) - 1);
2693    return "stcmh\t%2,%1,%S0";
2694}
2695[(set_attr "op_type" "RSY")])
2696
2697(define_insn "*insv<mode>_reg_imm"
2698  [(set (zero_extract:P (match_operand:P 0 "register_operand" "+d")
2699			(const_int 16)
2700			(match_operand 1 "const_int_operand" "n"))
2701	(match_operand:P 2 "const_int_operand" "n"))]
2702  "TARGET_ZARCH
2703   && INTVAL (operands[1]) >= 0
2704   && INTVAL (operands[1]) < BITS_PER_WORD
2705   && INTVAL (operands[1]) % 16 == 0"
2706{
2707  switch (BITS_PER_WORD - INTVAL (operands[1]))
2708    {
2709      case 64: return "iihh\t%0,%x2"; break;
2710      case 48: return "iihl\t%0,%x2"; break;
2711      case 32: return "iilh\t%0,%x2"; break;
2712      case 16: return "iill\t%0,%x2"; break;
2713      default: gcc_unreachable();
2714    }
2715}
2716  [(set_attr "op_type" "RI")])
2717
2718(define_insn "*insv<mode>_reg_extimm"
2719  [(set (zero_extract:P (match_operand:P 0 "register_operand" "+d")
2720			(const_int 32)
2721			(match_operand 1 "const_int_operand" "n"))
2722	(match_operand:P 2 "const_int_operand" "n"))]
2723  "TARGET_EXTIMM
2724   && INTVAL (operands[1]) >= 0
2725   && INTVAL (operands[1]) < BITS_PER_WORD
2726   && INTVAL (operands[1]) % 32 == 0"
2727{
2728  switch (BITS_PER_WORD - INTVAL (operands[1]))
2729    {
2730      case 64: return "iihf\t%0,%o2"; break;
2731      case 32: return "iilf\t%0,%o2"; break;
2732      default: gcc_unreachable();
2733    }
2734}
2735  [(set_attr "op_type" "RIL")])
2736
2737;
2738; extendsidi2 instruction pattern(s).
2739;
2740
2741(define_expand "extendsidi2"
2742  [(set (match_operand:DI 0 "register_operand" "")
2743        (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "")))]
2744  ""
2745{
2746  if (!TARGET_64BIT)
2747    {
2748      emit_insn (gen_rtx_CLOBBER (VOIDmode, operands[0]));
2749      emit_move_insn (gen_highpart (SImode, operands[0]), operands[1]);
2750      emit_move_insn (gen_lowpart (SImode, operands[0]), const0_rtx);
2751      emit_insn (gen_ashrdi3 (operands[0], operands[0], GEN_INT (32)));
2752      DONE;
2753    }
2754})
2755
2756(define_insn "*extendsidi2"
2757  [(set (match_operand:DI 0 "register_operand" "=d,d")
2758        (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "d,m")))]
2759  "TARGET_64BIT"
2760  "@
2761   lgfr\t%0,%1
2762   lgf\t%0,%1"
2763  [(set_attr "op_type" "RRE,RXY")])
2764
2765;
2766; extend(hi|qi)(si|di)2 instruction pattern(s).
2767;
2768
2769(define_expand "extend<HQI:mode><DSI:mode>2"
2770  [(set (match_operand:DSI 0 "register_operand" "")
2771        (sign_extend:DSI (match_operand:HQI 1 "nonimmediate_operand" "")))]
2772  ""
2773{
2774  if (<DSI:MODE>mode == DImode && !TARGET_64BIT)
2775    {
2776      rtx tmp = gen_reg_rtx (SImode);
2777      emit_insn (gen_extend<HQI:mode>si2 (tmp, operands[1]));
2778      emit_insn (gen_extendsidi2 (operands[0], tmp));
2779      DONE;
2780    }
2781  else if (!TARGET_EXTIMM)
2782    {
2783      rtx bitcount = GEN_INT (GET_MODE_BITSIZE (<DSI:MODE>mode) -
2784			      GET_MODE_BITSIZE (<HQI:MODE>mode));
2785
2786      operands[1] = gen_lowpart (<DSI:MODE>mode, operands[1]);
2787      emit_insn (gen_ashl<DSI:mode>3 (operands[0], operands[1], bitcount));
2788      emit_insn (gen_ashr<DSI:mode>3 (operands[0], operands[0], bitcount));
2789      DONE;
2790    }
2791})
2792
2793;
2794; extendhidi2 instruction pattern(s).
2795;
2796
2797(define_insn "*extendhidi2_extimm"
2798  [(set (match_operand:DI 0 "register_operand" "=d,d")
2799        (sign_extend:DI (match_operand:HI 1 "nonimmediate_operand" "d,m")))]
2800  "TARGET_64BIT && TARGET_EXTIMM"
2801  "@
2802   lghr\t%0,%1
2803   lgh\t%0,%1"
2804  [(set_attr "op_type" "RRE,RXY")])
2805
2806(define_insn "*extendhidi2"
2807  [(set (match_operand:DI 0 "register_operand" "=d")
2808        (sign_extend:DI (match_operand:HI 1 "memory_operand" "m")))]
2809  "TARGET_64BIT"
2810  "lgh\t%0,%1"
2811  [(set_attr "op_type" "RXY")])
2812
2813;
2814; extendhisi2 instruction pattern(s).
2815;
2816
2817(define_insn "*extendhisi2_extimm"
2818  [(set (match_operand:SI 0 "register_operand" "=d,d,d")
2819        (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "d,R,T")))]
2820  "TARGET_EXTIMM"
2821  "@
2822   lhr\t%0,%1
2823   lh\t%0,%1
2824   lhy\t%0,%1"
2825  [(set_attr "op_type" "RRE,RX,RXY")])
2826
2827(define_insn "*extendhisi2"
2828  [(set (match_operand:SI 0 "register_operand" "=d,d")
2829        (sign_extend:SI (match_operand:HI 1 "memory_operand" "R,T")))]
2830  "!TARGET_EXTIMM"
2831  "@
2832   lh\t%0,%1
2833   lhy\t%0,%1"
2834  [(set_attr "op_type" "RX,RXY")])
2835
2836;
2837; extendqi(si|di)2 instruction pattern(s).
2838;
2839
2840; lbr, lgbr, lb, lgb
2841(define_insn "*extendqi<mode>2_extimm"
2842  [(set (match_operand:GPR 0 "register_operand" "=d,d")
2843        (sign_extend:GPR (match_operand:QI 1 "nonimmediate_operand" "d,m")))]
2844  "TARGET_EXTIMM"
2845  "@
2846   l<g>br\t%0,%1
2847   l<g>b\t%0,%1"
2848  [(set_attr "op_type" "RRE,RXY")])
2849
2850; lb, lgb
2851(define_insn "*extendqi<mode>2"
2852  [(set (match_operand:GPR 0 "register_operand" "=d")
2853        (sign_extend:GPR (match_operand:QI 1 "memory_operand" "m")))]
2854  "!TARGET_EXTIMM && TARGET_LONG_DISPLACEMENT"
2855  "l<g>b\t%0,%1"
2856  [(set_attr "op_type" "RXY")])
2857
2858(define_insn_and_split "*extendqi<mode>2_short_displ"
2859  [(set (match_operand:GPR 0 "register_operand" "=d")
2860        (sign_extend:GPR (match_operand:QI 1 "s_operand" "Q")))
2861   (clobber (reg:CC CC_REGNUM))]
2862  "!TARGET_EXTIMM && !TARGET_LONG_DISPLACEMENT"
2863  "#"
2864  "&& reload_completed"
2865  [(parallel
2866    [(set (match_dup 0) (unspec:GPR [(match_dup 1) (const_int 8)] UNSPEC_ICM))
2867     (clobber (reg:CC CC_REGNUM))])
2868   (parallel
2869    [(set (match_dup 0) (ashiftrt:GPR (match_dup 0) (match_dup 2)))
2870     (clobber (reg:CC CC_REGNUM))])]
2871{
2872  operands[1] = adjust_address (operands[1], BLKmode, 0);
2873  set_mem_size (operands[1], GEN_INT (GET_MODE_SIZE (QImode)));
2874  operands[2] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)
2875			 - GET_MODE_BITSIZE (QImode));
2876})
2877
2878;
2879; zero_extendsidi2 instruction pattern(s).
2880;
2881
2882(define_expand "zero_extendsidi2"
2883  [(set (match_operand:DI 0 "register_operand" "")
2884        (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "")))]
2885  ""
2886{
2887  if (!TARGET_64BIT)
2888    {
2889      emit_insn (gen_rtx_CLOBBER (VOIDmode, operands[0]));
2890      emit_move_insn (gen_lowpart (SImode, operands[0]), operands[1]);
2891      emit_move_insn (gen_highpart (SImode, operands[0]), const0_rtx);
2892      DONE;
2893    }
2894})
2895
2896(define_insn "*zero_extendsidi2"
2897  [(set (match_operand:DI 0 "register_operand" "=d,d")
2898        (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "d,m")))]
2899  "TARGET_64BIT"
2900  "@
2901   llgfr\t%0,%1
2902   llgf\t%0,%1"
2903  [(set_attr "op_type" "RRE,RXY")])
2904
2905;
2906; LLGT-type instructions (zero-extend from 31 bit to 64 bit).
2907;
2908
2909(define_insn "*llgt_sidi"
2910  [(set (match_operand:DI 0 "register_operand" "=d")
2911        (and:DI (subreg:DI (match_operand:SI 1 "memory_operand" "m") 0)
2912		(const_int 2147483647)))]
2913  "TARGET_64BIT"
2914  "llgt\t%0,%1"
2915  [(set_attr "op_type"  "RXE")])
2916
2917(define_insn_and_split "*llgt_sidi_split"
2918  [(set (match_operand:DI 0 "register_operand" "=d")
2919        (and:DI (subreg:DI (match_operand:SI 1 "memory_operand" "m") 0)
2920		(const_int 2147483647)))
2921   (clobber (reg:CC CC_REGNUM))]
2922  "TARGET_64BIT"
2923  "#"
2924  "&& reload_completed"
2925  [(set (match_dup 0)
2926        (and:DI (subreg:DI (match_dup 1) 0)
2927		(const_int 2147483647)))]
2928  "")
2929
2930(define_insn "*llgt_sisi"
2931  [(set (match_operand:SI 0 "register_operand" "=d,d")
2932        (and:SI (match_operand:SI 1 "nonimmediate_operand" "d,m")
2933		(const_int 2147483647)))]
2934  "TARGET_ZARCH"
2935  "@
2936   llgtr\t%0,%1
2937   llgt\t%0,%1"
2938  [(set_attr "op_type"  "RRE,RXE")])
2939
2940(define_insn "*llgt_didi"
2941  [(set (match_operand:DI 0 "register_operand" "=d,d")
2942        (and:DI (match_operand:DI 1 "nonimmediate_operand" "d,o")
2943                (const_int 2147483647)))]
2944  "TARGET_64BIT"
2945  "@
2946   llgtr\t%0,%1
2947   llgt\t%0,%N1"
2948  [(set_attr "op_type"  "RRE,RXE")])
2949
2950(define_split
2951  [(set (match_operand:GPR 0 "register_operand" "")
2952        (and:GPR (match_operand:GPR 1 "nonimmediate_operand" "")
2953                 (const_int 2147483647)))
2954   (clobber (reg:CC CC_REGNUM))]
2955  "TARGET_ZARCH && reload_completed"
2956  [(set (match_dup 0)
2957        (and:GPR (match_dup 1)
2958                 (const_int 2147483647)))]
2959  "")
2960
2961;
2962; zero_extend(hi|qi)(si|di)2 instruction pattern(s).
2963;
2964
2965(define_expand "zero_extend<mode>di2"
2966  [(set (match_operand:DI 0 "register_operand" "")
2967        (zero_extend:DI (match_operand:HQI 1 "nonimmediate_operand" "")))]
2968  ""
2969{
2970  if (!TARGET_64BIT)
2971    {
2972      rtx tmp = gen_reg_rtx (SImode);
2973      emit_insn (gen_zero_extend<mode>si2 (tmp, operands[1]));
2974      emit_insn (gen_zero_extendsidi2 (operands[0], tmp));
2975      DONE;
2976    }
2977  else if (!TARGET_EXTIMM)
2978    {
2979      rtx bitcount = GEN_INT (GET_MODE_BITSIZE(DImode) - 
2980			      GET_MODE_BITSIZE(<MODE>mode));
2981      operands[1] = gen_lowpart (DImode, operands[1]);
2982      emit_insn (gen_ashldi3 (operands[0], operands[1], bitcount));
2983      emit_insn (gen_lshrdi3 (operands[0], operands[0], bitcount));
2984      DONE;
2985    }
2986})
2987
2988(define_expand "zero_extend<mode>si2"
2989  [(set (match_operand:SI 0 "register_operand" "")
2990        (zero_extend:SI (match_operand:HQI 1 "nonimmediate_operand" "")))]
2991  ""
2992{
2993  if (!TARGET_EXTIMM)
2994    {
2995      operands[1] = gen_lowpart (SImode, operands[1]);
2996      emit_insn (gen_andsi3 (operands[0], operands[1], 
2997                   GEN_INT ((1 << GET_MODE_BITSIZE(<MODE>mode)) - 1)));
2998      DONE;
2999    }
3000})
3001
3002; llhr, llcr, llghr, llgcr, llh, llc, llgh, llgc
3003(define_insn "*zero_extend<HQI:mode><GPR:mode>2_extimm"
3004  [(set (match_operand:GPR 0 "register_operand" "=d,d")
3005        (zero_extend:GPR (match_operand:HQI 1 "nonimmediate_operand" "d,m")))]
3006  "TARGET_EXTIMM"
3007  "@
3008   ll<g><hc>r\t%0,%1
3009   ll<g><hc>\t%0,%1"
3010  [(set_attr "op_type" "RRE,RXY")])
3011
3012; llgh, llgc
3013(define_insn "*zero_extend<HQI:mode><GPR:mode>2"
3014  [(set (match_operand:GPR 0 "register_operand" "=d")
3015        (zero_extend:GPR (match_operand:HQI 1 "memory_operand" "m")))]
3016  "TARGET_ZARCH && !TARGET_EXTIMM"
3017  "llg<hc>\t%0,%1"
3018  [(set_attr "op_type" "RXY")])
3019
3020(define_insn_and_split "*zero_extendhisi2_31"
3021  [(set (match_operand:SI 0 "register_operand" "=&d")
3022        (zero_extend:SI (match_operand:HI 1 "s_operand" "QS")))
3023   (clobber (reg:CC CC_REGNUM))]
3024  "!TARGET_ZARCH"
3025  "#"
3026  "&& reload_completed"
3027  [(set (match_dup 0) (const_int 0))
3028   (parallel
3029    [(set (strict_low_part (match_dup 2)) (match_dup 1))
3030     (clobber (reg:CC CC_REGNUM))])]
3031  "operands[2] = gen_lowpart (HImode, operands[0]);")
3032
3033(define_insn_and_split "*zero_extendqisi2_31"
3034  [(set (match_operand:SI 0 "register_operand" "=&d")
3035        (zero_extend:SI (match_operand:QI 1 "memory_operand" "m")))]
3036  "!TARGET_ZARCH"
3037  "#"
3038  "&& reload_completed"
3039  [(set (match_dup 0) (const_int 0))
3040   (set (strict_low_part (match_dup 2)) (match_dup 1))]
3041  "operands[2] = gen_lowpart (QImode, operands[0]);")
3042
3043;
3044; zero_extendqihi2 instruction pattern(s).
3045;
3046
3047(define_expand "zero_extendqihi2"
3048  [(set (match_operand:HI 0 "register_operand" "")
3049        (zero_extend:HI (match_operand:QI 1 "register_operand" "")))]
3050  "TARGET_ZARCH && !TARGET_EXTIMM"
3051{
3052  operands[1] = gen_lowpart (HImode, operands[1]);
3053  emit_insn (gen_andhi3 (operands[0], operands[1], GEN_INT (0xff)));
3054  DONE;
3055})
3056
3057(define_insn "*zero_extendqihi2_64"
3058  [(set (match_operand:HI 0 "register_operand" "=d")
3059        (zero_extend:HI (match_operand:QI 1 "memory_operand" "m")))]
3060  "TARGET_ZARCH && !TARGET_EXTIMM"
3061  "llgc\t%0,%1"
3062  [(set_attr "op_type" "RXY")])
3063
3064(define_insn_and_split "*zero_extendqihi2_31"
3065  [(set (match_operand:HI 0 "register_operand" "=&d")
3066        (zero_extend:HI (match_operand:QI 1 "memory_operand" "m")))]
3067  "!TARGET_ZARCH"
3068  "#"
3069  "&& reload_completed"
3070  [(set (match_dup 0) (const_int 0))
3071   (set (strict_low_part (match_dup 2)) (match_dup 1))]
3072  "operands[2] = gen_lowpart (QImode, operands[0]);")
3073
3074
3075;
3076; fixuns_trunc(sf|df)(si|di)2 and fix_trunc(sf|df)(si|di)2 instruction pattern(s).
3077;
3078
3079(define_expand "fixuns_trunc<FPR:mode><GPR:mode>2"
3080  [(set (match_operand:GPR 0 "register_operand" "")
3081        (unsigned_fix:GPR (match_operand:FPR 1 "register_operand" "")))]
3082  "TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT"
3083{
3084  rtx label1 = gen_label_rtx ();
3085  rtx label2 = gen_label_rtx ();
3086  rtx temp = gen_reg_rtx (<FPR:MODE>mode);
3087  REAL_VALUE_TYPE cmp, sub;
3088  
3089  operands[1] = force_reg (<FPR:MODE>mode, operands[1]);
3090  real_2expN (&cmp, GET_MODE_BITSIZE(<GPR:MODE>mode) - 1);
3091  real_2expN (&sub, GET_MODE_BITSIZE(<GPR:MODE>mode));
3092  
3093  emit_insn (gen_cmp<FPR:mode> (operands[1],
3094	CONST_DOUBLE_FROM_REAL_VALUE (cmp, <FPR:MODE>mode)));
3095  emit_jump_insn (gen_blt (label1));
3096  emit_insn (gen_sub<FPR:mode>3 (temp, operands[1],
3097	CONST_DOUBLE_FROM_REAL_VALUE (sub, <FPR:MODE>mode)));
3098  emit_insn (gen_fix_trunc<FPR:mode><GPR:mode>2_ieee (operands[0], temp,
3099	GEN_INT(7)));
3100  emit_jump (label2);
3101
3102  emit_label (label1);
3103  emit_insn (gen_fix_trunc<FPR:mode><GPR:mode>2_ieee (operands[0],
3104	operands[1], GEN_INT(5)));
3105  emit_label (label2);
3106  DONE;
3107})
3108
3109(define_expand "fix_trunc<mode>di2"
3110  [(set (match_operand:DI 0 "register_operand" "")
3111        (fix:DI (match_operand:DSF 1 "nonimmediate_operand" "")))]
3112  "TARGET_64BIT && TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT"
3113{
3114  operands[1] = force_reg (<MODE>mode, operands[1]);
3115  emit_insn (gen_fix_trunc<mode>di2_ieee (operands[0], operands[1],
3116      GEN_INT(5)));
3117  DONE;
3118})
3119
3120; cgxbr, cgdbr, cgebr, cfxbr, cfdbr, cfebr
3121(define_insn "fix_trunc<FPR:mode><GPR:mode>2_ieee"
3122  [(set (match_operand:GPR 0 "register_operand" "=d")
3123        (fix:GPR (match_operand:FPR 1 "register_operand" "f")))
3124   (unspec:GPR [(match_operand:GPR 2 "immediate_operand" "K")] UNSPEC_ROUND)
3125   (clobber (reg:CC CC_REGNUM))]
3126  "TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT"
3127  "c<GPR:gf><FPR:xde>br\t%0,%h2,%1"
3128  [(set_attr "op_type" "RRE")
3129   (set_attr "type"    "ftoi")])
3130
3131;
3132; fix_trunctf(si|di)2 instruction pattern(s).
3133;
3134
3135(define_expand "fix_trunctf<mode>2"
3136  [(parallel [(set (match_operand:GPR 0 "register_operand" "")
3137		   (fix:GPR (match_operand:TF 1 "register_operand" "")))
3138	      (unspec:GPR [(const_int 5)] UNSPEC_ROUND)
3139	      (clobber (reg:CC CC_REGNUM))])]
3140  "TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT"
3141  "")
3142
3143;
3144; fix_truncdfsi2 instruction pattern(s).
3145;
3146
3147(define_expand "fix_truncdfsi2"
3148  [(set (match_operand:SI 0 "register_operand" "")
3149        (fix:SI (match_operand:DF 1 "nonimmediate_operand" "")))]
3150  "TARGET_HARD_FLOAT"
3151{
3152  if (TARGET_IBM_FLOAT)
3153    {
3154      /* This is the algorithm from POP chapter A.5.7.2.  */
3155
3156      rtx temp   = assign_stack_local (BLKmode, 8, BITS_PER_WORD);
3157      rtx two31r = s390_gen_rtx_const_DI (0x4f000000, 0x08000000);
3158      rtx two32  = s390_gen_rtx_const_DI (0x4e000001, 0x00000000);
3159
3160      operands[1] = force_reg (DFmode, operands[1]);
3161      emit_insn (gen_fix_truncdfsi2_ibm (operands[0], operands[1],
3162					 two31r, two32, temp));
3163    }
3164  else
3165    {
3166      operands[1] = force_reg (DFmode, operands[1]);
3167      emit_insn (gen_fix_truncdfsi2_ieee (operands[0], operands[1], GEN_INT (5)));
3168    }
3169
3170  DONE;
3171})
3172
3173(define_insn "fix_truncdfsi2_ibm"
3174  [(set (match_operand:SI 0 "register_operand" "=d")
3175        (fix:SI (match_operand:DF 1 "nonimmediate_operand" "+f")))
3176   (use (match_operand:DI 2 "immediate_operand" "m"))
3177   (use (match_operand:DI 3 "immediate_operand" "m"))
3178   (use (match_operand:BLK 4 "memory_operand" "m"))
3179   (clobber (reg:CC CC_REGNUM))]
3180  "TARGET_HARD_FLOAT && TARGET_IBM_FLOAT"
3181{
3182   output_asm_insn ("sd\t%1,%2", operands);
3183   output_asm_insn ("aw\t%1,%3", operands);
3184   output_asm_insn ("std\t%1,%4", operands);
3185   output_asm_insn ("xi\t%N4,128", operands);
3186   return "l\t%0,%N4";
3187}
3188  [(set_attr "length" "20")])
3189
3190;
3191; fix_truncsfsi2 instruction pattern(s).
3192;
3193
3194(define_expand "fix_truncsfsi2"
3195  [(set (match_operand:SI 0 "register_operand" "")
3196        (fix:SI (match_operand:SF 1 "nonimmediate_operand" "")))]
3197  "TARGET_HARD_FLOAT"
3198{
3199  if (TARGET_IBM_FLOAT)
3200    {
3201      /* Convert to DFmode and then use the POP algorithm.  */
3202      rtx temp = gen_reg_rtx (DFmode);
3203      emit_insn (gen_extendsfdf2 (temp, operands[1]));
3204      emit_insn (gen_fix_truncdfsi2 (operands[0], temp));
3205    }
3206  else
3207    {
3208      operands[1] = force_reg (SFmode, operands[1]);
3209      emit_insn (gen_fix_truncsfsi2_ieee (operands[0], operands[1], GEN_INT (5)));
3210    }
3211
3212  DONE;
3213})
3214
3215;
3216; float(si|di)(tf|df|sf)2 instruction pattern(s).
3217;
3218
3219; cxgbr, cdgbr, cegbr
3220(define_insn "floatdi<mode>2"
3221  [(set (match_operand:FPR 0 "register_operand" "=f")
3222        (float:FPR (match_operand:DI 1 "register_operand" "d")))]
3223  "TARGET_64BIT && TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT"
3224  "c<xde>gbr\t%0,%1"
3225  [(set_attr "op_type" "RRE")
3226   (set_attr "type"    "itof" )])
3227
3228; cxfbr, cdfbr, cefbr
3229(define_insn "floatsi<mode>2_ieee"
3230  [(set (match_operand:FPR 0 "register_operand" "=f")
3231        (float:FPR (match_operand:SI 1 "register_operand" "d")))]
3232  "TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT"
3233  "c<xde>fbr\t%0,%1"
3234  [(set_attr "op_type" "RRE")
3235   (set_attr "type"   "itof" )])
3236
3237
3238;
3239; floatsi(tf|df)2 instruction pattern(s).
3240;
3241
3242(define_expand "floatsitf2"
3243  [(set (match_operand:TF 0 "register_operand" "")
3244        (float:TF (match_operand:SI 1 "register_operand" "")))]
3245  "TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT"
3246  "")
3247
3248(define_expand "floatsidf2"
3249  [(set (match_operand:DF 0 "register_operand" "")
3250        (float:DF (match_operand:SI 1 "register_operand" "")))]
3251  "TARGET_HARD_FLOAT"
3252{
3253  if (TARGET_IBM_FLOAT)
3254    {
3255      /* This is the algorithm from POP chapter A.5.7.1.  */
3256
3257      rtx temp  = assign_stack_local (BLKmode, 8, BITS_PER_WORD);
3258      rtx two31 = s390_gen_rtx_const_DI (0x4e000000, 0x80000000);
3259
3260      emit_insn (gen_floatsidf2_ibm (operands[0], operands[1], two31, temp));
3261      DONE;
3262    }
3263})
3264
3265(define_insn "floatsidf2_ibm"
3266  [(set (match_operand:DF 0 "register_operand" "=f")
3267        (float:DF (match_operand:SI 1 "register_operand" "d")))
3268   (use (match_operand:DI 2 "immediate_operand" "m"))
3269   (use (match_operand:BLK 3 "memory_operand" "m"))
3270   (clobber (reg:CC CC_REGNUM))]
3271  "TARGET_HARD_FLOAT && TARGET_IBM_FLOAT"
3272{
3273   output_asm_insn ("st\t%1,%N3", operands);
3274   output_asm_insn ("xi\t%N3,128", operands);
3275   output_asm_insn ("mvc\t%O3(4,%R3),%2", operands);
3276   output_asm_insn ("ld\t%0,%3", operands);
3277   return "sd\t%0,%2";
3278}
3279  [(set_attr "length" "20")])
3280
3281;
3282; floatsisf2 instruction pattern(s).
3283;
3284
3285(define_expand "floatsisf2"
3286  [(set (match_operand:SF 0 "register_operand" "")
3287        (float:SF (match_operand:SI 1 "register_operand" "")))]
3288  "TARGET_HARD_FLOAT"
3289{
3290  if (TARGET_IBM_FLOAT)
3291    {
3292      /* Use the POP algorithm to convert to DFmode and then truncate.  */
3293      rtx temp = gen_reg_rtx (DFmode);
3294      emit_insn (gen_floatsidf2 (temp, operands[1]));
3295      emit_insn (gen_truncdfsf2 (operands[0], temp));
3296      DONE;
3297    }
3298})
3299
3300;
3301; truncdfsf2 instruction pattern(s).
3302;
3303
3304(define_expand "truncdfsf2"
3305  [(set (match_operand:SF 0 "register_operand" "")
3306        (float_truncate:SF (match_operand:DF 1 "register_operand" "")))]
3307  "TARGET_HARD_FLOAT"
3308  "")
3309
3310(define_insn "truncdfsf2_ieee"
3311  [(set (match_operand:SF 0 "register_operand" "=f")
3312        (float_truncate:SF (match_operand:DF 1 "register_operand" "f")))]
3313  "TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT"
3314  "ledbr\t%0,%1"
3315  [(set_attr "op_type"  "RRE")
3316   (set_attr "type"   "ftruncdf")])
3317
3318(define_insn "truncdfsf2_ibm"
3319  [(set (match_operand:SF 0 "register_operand" "=f,f")
3320        (float_truncate:SF (match_operand:DF 1 "nonimmediate_operand" "f,R")))]
3321  "TARGET_HARD_FLOAT && TARGET_IBM_FLOAT"
3322  "@
3323   ler\t%0,%1
3324   le\t%0,%1"
3325  [(set_attr "op_type"  "RR,RX")
3326   (set_attr "type"   "floadsf")])
3327
3328;
3329; trunctfdf2 instruction pattern(s).
3330;
3331
3332(define_expand "trunctfdf2"
3333  [(parallel 
3334    [(set (match_operand:DF 0 "register_operand" "")
3335	  (float_truncate:DF (match_operand:TF 1 "register_operand" "")))
3336     (clobber (match_scratch:TF 2 "=f"))])]
3337  "TARGET_HARD_FLOAT"
3338  "")
3339
3340(define_insn "*trunctfdf2_ieee"
3341  [(set (match_operand:DF 0 "register_operand" "=f")
3342        (float_truncate:DF (match_operand:TF 1 "register_operand" "f")))
3343   (clobber (match_scratch:TF 2 "=f"))]
3344  "TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT"
3345  "ldxbr\t%2,%1\;ldr\t%0,%2"
3346  [(set_attr "length" "6")
3347   (set_attr "type"   "ftrunctf")])   
3348
3349(define_insn "*trunctfdf2_ibm"
3350  [(set (match_operand:DF 0 "register_operand" "=f")
3351        (float_truncate:DF (match_operand:TF 1 "register_operand" "f")))
3352   (clobber (match_scratch:TF 2 "=f"))]
3353  "TARGET_HARD_FLOAT && TARGET_IBM_FLOAT"
3354  "ldxr\t%2,%1\;ldr\t%0,%2"
3355  [(set_attr "length"  "4")
3356   (set_attr "type"   "ftrunctf")])
3357
3358;
3359; trunctfsf2 instruction pattern(s).
3360;
3361
3362(define_expand "trunctfsf2"
3363  [(parallel 
3364    [(set (match_operand:SF 0 "register_operand" "=f")
3365	  (float_truncate:SF (match_operand:TF 1 "register_operand" "f")))
3366     (clobber (match_scratch:TF 2 "=f"))])]
3367  "TARGET_HARD_FLOAT"
3368  "")
3369
3370(define_insn "*trunctfsf2_ieee"
3371  [(set (match_operand:SF 0 "register_operand" "=f")
3372        (float_truncate:SF (match_operand:TF 1 "register_operand" "f")))
3373   (clobber (match_scratch:TF 2 "=f"))]
3374  "TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT"
3375  "lexbr\t%2,%1\;ler\t%0,%2"
3376  [(set_attr "length"  "6")
3377   (set_attr "type"   "ftrunctf")])
3378
3379(define_insn "*trunctfsf2_ibm"
3380  [(set (match_operand:SF 0 "register_operand" "=f")
3381        (float_truncate:SF (match_operand:TF 1 "register_operand" "f")))
3382   (clobber (match_scratch:TF 2 "=f"))]
3383  "TARGET_HARD_FLOAT && TARGET_IBM_FLOAT"
3384  "lexr\t%2,%1\;ler\t%0,%2"
3385  [(set_attr "length"  "6")
3386   (set_attr "type"   "ftrunctf")])
3387
3388;
3389; extendsfdf2 instruction pattern(s).
3390;
3391
3392(define_expand "extendsfdf2"
3393  [(set (match_operand:DF 0 "register_operand" "")
3394        (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "")))]
3395  "TARGET_HARD_FLOAT"
3396{
3397  if (TARGET_IBM_FLOAT)
3398    {
3399      emit_insn (gen_extendsfdf2_ibm (operands[0], operands[1]));
3400      DONE;
3401    }
3402})
3403
3404(define_insn "extendsfdf2_ieee"
3405  [(set (match_operand:DF 0 "register_operand" "=f,f")
3406        (float_extend:DF (match_operand:SF 1 "nonimmediate_operand"  "f,R")))]
3407  "TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT"
3408  "@
3409   ldebr\t%0,%1
3410   ldeb\t%0,%1"
3411  [(set_attr "op_type"  "RRE,RXE")
3412   (set_attr "type"   "fsimpsf, floadsf")])
3413
3414(define_insn "extendsfdf2_ibm"
3415  [(set (match_operand:DF 0 "register_operand" "=f,f")
3416        (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "f,R")))
3417   (clobber (reg:CC CC_REGNUM))]
3418  "TARGET_HARD_FLOAT && TARGET_IBM_FLOAT"
3419  "@
3420   sdr\t%0,%0\;ler\t%0,%1
3421   sdr\t%0,%0\;le\t%0,%1"
3422  [(set_attr "length"   "4,6")
3423   (set_attr "type"     "floadsf")])
3424
3425;
3426; extenddftf2 instruction pattern(s).
3427;
3428
3429(define_expand "extenddftf2"
3430  [(set (match_operand:TF 0 "register_operand" "")
3431        (float_extend:TF (match_operand:DF 1 "nonimmediate_operand" "")))]
3432  "TARGET_HARD_FLOAT"
3433  "")
3434
3435(define_insn "*extenddftf2_ieee"
3436  [(set (match_operand:TF 0 "register_operand" "=f,f")
3437        (float_extend:TF (match_operand:DF 1 "nonimmediate_operand" "f,R")))]
3438  "TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT"
3439  "@
3440   lxdbr\t%0,%1
3441   lxdb\t%0,%1"
3442  [(set_attr "op_type"  "RRE,RXE")
3443   (set_attr "type"   "fsimptf, floadtf")])
3444
3445(define_insn "*extenddftf2_ibm"
3446  [(set (match_operand:TF 0 "register_operand" "=f,f")
3447        (float_extend:TF (match_operand:DF 1 "nonimmediate_operand" "f,R")))]
3448  "TARGET_HARD_FLOAT && TARGET_IBM_FLOAT"
3449  "@
3450   lxdr\t%0,%1
3451   lxd\t%0,%1"
3452  [(set_attr "op_type"  "RRE,RXE")
3453   (set_attr "type"   "fsimptf, floadtf")])
3454
3455;
3456; extendsftf2 instruction pattern(s).
3457;
3458
3459(define_expand "extendsftf2"
3460  [(set (match_operand:TF 0 "register_operand" "")
3461        (float_extend:TF (match_operand:SF 1 "nonimmediate_operand" "")))]
3462  "TARGET_HARD_FLOAT"
3463  "")
3464
3465(define_insn "*extendsftf2_ieee"
3466  [(set (match_operand:TF 0 "register_operand" "=f,f")
3467        (float_extend:TF (match_operand:SF 1 "nonimmediate_operand" "f,R")))]
3468  "TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT"
3469  "@
3470   lxebr\t%0,%1
3471   lxeb\t%0,%1"
3472  [(set_attr "op_type"  "RRE,RXE")
3473   (set_attr "type"   "fsimptf, floadtf")])
3474
3475(define_insn "*extendsftf2_ibm"
3476  [(set (match_operand:TF 0 "register_operand" "=f,f")
3477        (float_extend:TF (match_operand:SF 1 "nonimmediate_operand" "f,R")))]
3478  "TARGET_HARD_FLOAT && TARGET_IBM_FLOAT"
3479  "@
3480   lxer\t%0,%1
3481   lxe\t%0,%1"
3482  [(set_attr "op_type"  "RRE,RXE")
3483   (set_attr "type"   "fsimptf, floadtf")])
3484
3485
3486;;
3487;; ARITHMETIC OPERATIONS
3488;;
3489;  arithmetic operations set the ConditionCode,
3490;  because of unpredictable Bits in Register for Halfword and Byte
3491;  the ConditionCode can be set wrong in operations for Halfword and Byte
3492
3493;;
3494;;- Add instructions.
3495;;
3496
3497;
3498; addti3 instruction pattern(s).
3499;
3500
3501(define_insn_and_split "addti3"
3502  [(set (match_operand:TI 0 "register_operand" "=&d")
3503        (plus:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
3504                 (match_operand:TI 2 "general_operand" "do") ) )
3505   (clobber (reg:CC CC_REGNUM))]
3506  "TARGET_64BIT"
3507  "#"
3508  "&& reload_completed"
3509  [(parallel
3510    [(set (reg:CCL1 CC_REGNUM)
3511          (compare:CCL1 (plus:DI (match_dup 7) (match_dup 8))
3512                        (match_dup 7)))
3513     (set (match_dup 6) (plus:DI (match_dup 7) (match_dup 8)))])
3514   (parallel
3515    [(set (match_dup 3) (plus:DI (plus:DI (match_dup 4) (match_dup 5))
3516                                 (ltu:DI (reg:CCL1 CC_REGNUM) (const_int 0))))
3517     (clobber (reg:CC CC_REGNUM))])]
3518  "operands[3] = operand_subword (operands[0], 0, 0, TImode);
3519   operands[4] = operand_subword (operands[1], 0, 0, TImode);
3520   operands[5] = operand_subword (operands[2], 0, 0, TImode);
3521   operands[6] = operand_subword (operands[0], 1, 0, TImode);
3522   operands[7] = operand_subword (operands[1], 1, 0, TImode);
3523   operands[8] = operand_subword (operands[2], 1, 0, TImode);")
3524
3525;
3526; adddi3 instruction pattern(s).
3527;
3528
3529(define_expand "adddi3"
3530  [(parallel
3531    [(set (match_operand:DI 0 "register_operand" "")
3532          (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
3533                   (match_operand:DI 2 "general_operand" "")))
3534     (clobber (reg:CC CC_REGNUM))])]
3535  ""
3536  "")
3537
3538(define_insn "*adddi3_sign"
3539  [(set (match_operand:DI 0 "register_operand" "=d,d")
3540        (plus:DI (sign_extend:DI (match_operand:SI 2 "general_operand" "d,m"))
3541                 (match_operand:DI 1 "register_operand" "0,0")))
3542   (clobber (reg:CC CC_REGNUM))]
3543  "TARGET_64BIT"
3544  "@
3545   agfr\t%0,%2
3546   agf\t%0,%2"
3547  [(set_attr "op_type"  "RRE,RXY")])
3548
3549(define_insn "*adddi3_zero_cc"
3550  [(set (reg CC_REGNUM)
3551        (compare (plus:DI (zero_extend:DI (match_operand:SI 2 "general_operand" "d,m"))
3552                          (match_operand:DI 1 "register_operand" "0,0"))
3553                 (const_int 0)))
3554   (set (match_operand:DI 0 "register_operand" "=d,d")
3555        (plus:DI (zero_extend:DI (match_dup 2)) (match_dup 1)))]
3556  "s390_match_ccmode (insn, CCLmode) && TARGET_64BIT"
3557  "@
3558   algfr\t%0,%2
3559   algf\t%0,%2"
3560  [(set_attr "op_type"  "RRE,RXY")])
3561
3562(define_insn "*adddi3_zero_cconly"
3563  [(set (reg CC_REGNUM)
3564        (compare (plus:DI (zero_extend:DI (match_operand:SI 2 "general_operand" "d,m"))
3565                          (match_operand:DI 1 "register_operand" "0,0"))
3566                 (const_int 0)))
3567   (clobber (match_scratch:DI 0 "=d,d"))]
3568  "s390_match_ccmode (insn, CCLmode) && TARGET_64BIT"
3569  "@
3570   algfr\t%0,%2
3571   algf\t%0,%2"
3572  [(set_attr "op_type"  "RRE,RXY")])
3573
3574(define_insn "*adddi3_zero"
3575  [(set (match_operand:DI 0 "register_operand" "=d,d")
3576        (plus:DI (zero_extend:DI (match_operand:SI 2 "general_operand" "d,m"))
3577                 (match_operand:DI 1 "register_operand" "0,0")))
3578   (clobber (reg:CC CC_REGNUM))]
3579  "TARGET_64BIT"
3580  "@
3581   algfr\t%0,%2
3582   algf\t%0,%2"
3583  [(set_attr "op_type"  "RRE,RXY")])
3584
3585(define_insn_and_split "*adddi3_31z"
3586  [(set (match_operand:DI 0 "register_operand" "=&d")
3587        (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
3588                 (match_operand:DI 2 "general_operand" "do") ) )
3589   (clobber (reg:CC CC_REGNUM))]
3590  "!TARGET_64BIT && TARGET_CPU_ZARCH"
3591  "#"
3592  "&& reload_completed"
3593  [(parallel
3594    [(set (reg:CCL1 CC_REGNUM)
3595          (compare:CCL1 (plus:SI (match_dup 7) (match_dup 8))
3596                        (match_dup 7)))
3597     (set (match_dup 6) (plus:SI (match_dup 7) (match_dup 8)))])
3598   (parallel
3599    [(set (match_dup 3) (plus:SI (plus:SI (match_dup 4) (match_dup 5))
3600                                 (ltu:SI (reg:CCL1 CC_REGNUM) (const_int 0))))
3601     (clobber (reg:CC CC_REGNUM))])]
3602  "operands[3] = operand_subword (operands[0], 0, 0, DImode);
3603   operands[4] = operand_subword (operands[1], 0, 0, DImode);
3604   operands[5] = operand_subword (operands[2], 0, 0, DImode);
3605   operands[6] = operand_subword (operands[0], 1, 0, DImode);
3606   operands[7] = operand_subword (operands[1], 1, 0, DImode);
3607   operands[8] = operand_subword (operands[2], 1, 0, DImode);")
3608
3609(define_insn_and_split "*adddi3_31"
3610  [(set (match_operand:DI 0 "register_operand" "=&d")
3611        (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
3612                 (match_operand:DI 2 "general_operand" "do") ) )
3613   (clobber (reg:CC CC_REGNUM))]
3614  "!TARGET_CPU_ZARCH"
3615  "#"
3616  "&& reload_completed"
3617  [(parallel
3618    [(set (match_dup 3) (plus:SI (match_dup 4) (match_dup 5)))
3619     (clobber (reg:CC CC_REGNUM))])
3620   (parallel
3621    [(set (reg:CCL1 CC_REGNUM)
3622          (compare:CCL1 (plus:SI (match_dup 7) (match_dup 8))
3623                        (match_dup 7)))
3624     (set (match_dup 6) (plus:SI (match_dup 7) (match_dup 8)))])
3625   (set (pc)
3626        (if_then_else (ltu (reg:CCL1 CC_REGNUM) (const_int 0))
3627                      (pc)
3628                      (label_ref (match_dup 9))))
3629   (parallel
3630    [(set (match_dup 3) (plus:SI (match_dup 3) (const_int 1)))
3631     (clobber (reg:CC CC_REGNUM))])
3632   (match_dup 9)]
3633  "operands[3] = operand_subword (operands[0], 0, 0, DImode);
3634   operands[4] = operand_subword (operands[1], 0, 0, DImode);
3635   operands[5] = operand_subword (operands[2], 0, 0, DImode);
3636   operands[6] = operand_subword (operands[0], 1, 0, DImode);
3637   operands[7] = operand_subword (operands[1], 1, 0, DImode);
3638   operands[8] = operand_subword (operands[2], 1, 0, DImode);
3639   operands[9] = gen_label_rtx ();")
3640
3641;
3642; addsi3 instruction pattern(s).
3643;
3644
3645(define_expand "addsi3"
3646  [(parallel
3647    [(set (match_operand:SI 0 "register_operand" "")
3648          (plus:SI (match_operand:SI 1 "nonimmediate_operand" "")
3649                   (match_operand:SI 2 "general_operand" "")))
3650     (clobber (reg:CC CC_REGNUM))])]
3651  ""
3652  "")
3653
3654(define_insn "*addsi3_sign"
3655  [(set (match_operand:SI 0 "register_operand" "=d,d")
3656        (plus:SI (sign_extend:SI (match_operand:HI 2 "memory_operand" "R,T"))
3657                 (match_operand:SI 1 "register_operand" "0,0")))
3658   (clobber (reg:CC CC_REGNUM))]
3659  ""
3660  "@
3661   ah\t%0,%2
3662   ahy\t%0,%2"
3663  [(set_attr "op_type"  "RX,RXY")])
3664
3665;
3666; add(di|si)3 instruction pattern(s).
3667;
3668
3669; ar, ahi, alfi, slfi, a, ay, agr, aghi, algfi, slgfi, ag
3670(define_insn "*add<mode>3"
3671  [(set (match_operand:GPR 0 "register_operand" "=d,d,d,d,d,d")
3672        (plus:GPR (match_operand:GPR 1 "nonimmediate_operand" "%0,0,0,0,0,0")
3673		  (match_operand:GPR 2 "general_operand" "d,K,Op,On,R,T") ) )
3674   (clobber (reg:CC CC_REGNUM))]
3675  ""
3676  "@
3677   a<g>r\t%0,%2
3678   a<g>hi\t%0,%h2
3679   al<g>fi\t%0,%2
3680   sl<g>fi\t%0,%n2
3681   a<g>\t%0,%2
3682   a<y>\t%0,%2"
3683  [(set_attr "op_type"  "RR<E>,RI,RIL,RIL,RX<Y>,RXY")])
3684
3685; alr, alfi, slfi, al, aly, algr, algfi, slgfi, alg
3686(define_insn "*add<mode>3_carry1_cc"
3687  [(set (reg CC_REGNUM)
3688        (compare (plus:GPR (match_operand:GPR 1 "nonimmediate_operand" "%0,0,0,0,0")
3689			   (match_operand:GPR 2 "general_operand" "d,Op,On,R,T"))
3690                 (match_dup 1)))
3691   (set (match_operand:GPR 0 "register_operand" "=d,d,d,d,d")
3692        (plus:GPR (match_dup 1) (match_dup 2)))]
3693  "s390_match_ccmode (insn, CCL1mode)"
3694  "@
3695   al<g>r\t%0,%2
3696   al<g>fi\t%0,%2
3697   sl<g>fi\t%0,%n2
3698   al<g>\t%0,%2
3699   al<y>\t%0,%2"
3700  [(set_attr "op_type"  "RR<E>,RIL,RIL,RX<Y>,RXY")])
3701
3702; alr, al, aly, algr, alg
3703(define_insn "*add<mode>3_carry1_cconly"
3704  [(set (reg CC_REGNUM)
3705        (compare (plus:GPR (match_operand:GPR 1 "nonimmediate_operand" "%0,0,0")
3706			   (match_operand:GPR 2 "general_operand" "d,R,T"))
3707                 (match_dup 1)))
3708   (clobber (match_scratch:GPR 0 "=d,d,d"))]
3709  "s390_match_ccmode (insn, CCL1mode)"
3710  "@
3711   al<g>r\t%0,%2
3712   al<g>\t%0,%2
3713   al<y>\t%0,%2"
3714  [(set_attr "op_type"  "RR<E>,RX<Y>,RXY")])
3715
3716; alr, alfi, slfi, al, aly, algr, algfi, slgfi, alg
3717(define_insn "*add<mode>3_carry2_cc"
3718  [(set (reg CC_REGNUM)
3719        (compare (plus:GPR (match_operand:GPR 1 "nonimmediate_operand" "%0,0,0,0,0")
3720			   (match_operand:GPR 2 "general_operand" "d,Op,On,R,T"))
3721                 (match_dup 2)))
3722   (set (match_operand:GPR 0 "register_operand" "=d,d,d,d,d")
3723        (plus:GPR (match_dup 1) (match_dup 2)))]
3724  "s390_match_ccmode (insn, CCL1mode)"
3725  "@
3726   al<g>r\t%0,%2
3727   al<g>fi\t%0,%2
3728   sl<g>fi\t%0,%n2
3729   al<g>\t%0,%2
3730   al<y>\t%0,%2"
3731  [(set_attr "op_type"  "RR<E>,RIL,RIL,RX<Y>,RXY")])
3732
3733; alr, al, aly, algr, alg
3734(define_insn "*add<mode>3_carry2_cconly"
3735  [(set (reg CC_REGNUM)
3736        (compare (plus:GPR (match_operand:GPR 1 "nonimmediate_operand" "%0,0,0")
3737			   (match_operand:GPR 2 "general_operand" "d,R,T"))
3738                 (match_dup 2)))
3739   (clobber (match_scratch:GPR 0 "=d,d,d"))]
3740  "s390_match_ccmode (insn, CCL1mode)"
3741  "@
3742   al<g>r\t%0,%2
3743   al<g>\t%0,%2
3744   al<y>\t%0,%2"
3745  [(set_attr "op_type"  "RR<E>,RX<Y>,RXY")])
3746
3747; alr, alfi, slfi, al, aly, algr, algfi, slgfi, alg
3748(define_insn "*add<mode>3_cc"
3749  [(set (reg CC_REGNUM)
3750        (compare (plus:GPR (match_operand:GPR 1 "nonimmediate_operand" "%0,0,0,0,0")
3751			   (match_operand:GPR 2 "general_operand" "d,Op,On,R,T"))
3752                 (const_int 0)))
3753   (set (match_operand:GPR 0 "register_operand" "=d,d,d,d,d")
3754        (plus:GPR (match_dup 1) (match_dup 2)))]
3755  "s390_match_ccmode (insn, CCLmode)"
3756  "@
3757   al<g>r\t%0,%2
3758   al<g>fi\t%0,%2
3759   sl<g>fi\t%0,%n2
3760   al<g>\t%0,%2
3761   al<y>\t%0,%2"
3762  [(set_attr "op_type"  "RR<E>,RIL,RIL,RX<Y>,RXY")])
3763
3764; alr, al, aly, algr, alg
3765(define_insn "*add<mode>3_cconly"
3766  [(set (reg CC_REGNUM)
3767        (compare (plus:GPR (match_operand:GPR 1 "nonimmediate_operand" "%0,0,0")
3768			   (match_operand:GPR 2 "general_operand" "d,R,T"))
3769                 (const_int 0)))
3770   (clobber (match_scratch:GPR 0 "=d,d,d"))]
3771  "s390_match_ccmode (insn, CCLmode)"
3772  "@
3773   al<g>r\t%0,%2
3774   al<g>\t%0,%2
3775   al<y>\t%0,%2"
3776  [(set_attr "op_type"  "RR<E>,RX<Y>,RXY")])
3777
3778; alr, al, aly, algr, alg
3779(define_insn "*add<mode>3_cconly2"
3780  [(set (reg CC_REGNUM)
3781        (compare (match_operand:GPR 1 "nonimmediate_operand" "%0,0,0")
3782                 (neg:GPR (match_operand:GPR 2 "general_operand" "d,R,T"))))
3783   (clobber (match_scratch:GPR 0 "=d,d,d"))]
3784  "s390_match_ccmode(insn, CCLmode)"
3785  "@
3786   al<g>r\t%0,%2
3787   al<g>\t%0,%2
3788   al<y>\t%0,%2"
3789  [(set_attr "op_type"  "RR<E>,RX<Y>,RXY")])
3790
3791; ahi, afi, aghi, agfi
3792(define_insn "*add<mode>3_imm_cc"
3793  [(set (reg CC_REGNUM)
3794        (compare (plus:GPR (match_operand:GPR 1 "nonimmediate_operand" "0,0")
3795			   (match_operand:GPR 2 "const_int_operand" "K,Os"))
3796                 (const_int 0)))
3797   (set (match_operand:GPR 0 "register_operand" "=d,d")
3798        (plus:GPR (match_dup 1) (match_dup 2)))]
3799  "s390_match_ccmode (insn, CCAmode)
3800   && (CONST_OK_FOR_CONSTRAINT_P (INTVAL (operands[2]), 'K', \"K\")
3801       || CONST_OK_FOR_CONSTRAINT_P (INTVAL (operands[2]), 'O', \"Os\"))
3802   && INTVAL (operands[2]) != -((HOST_WIDE_INT)1 << (GET_MODE_BITSIZE(<MODE>mode) - 1))"
3803  "@
3804   a<g>hi\t%0,%h2
3805   a<g>fi\t%0,%2"
3806  [(set_attr "op_type"  "RI,RIL")])
3807
3808;
3809; add(df|sf)3 instruction pattern(s).
3810;
3811
3812(define_expand "add<mode>3"
3813  [(parallel
3814    [(set (match_operand:FPR 0 "register_operand" "=f,f")
3815          (plus:FPR (match_operand:FPR 1 "nonimmediate_operand" "%0,0")
3816                    (match_operand:FPR 2 "general_operand" "f,<Rf>")))
3817     (clobber (reg:CC CC_REGNUM))])]
3818  "TARGET_HARD_FLOAT"
3819  "")
3820
3821; axbr, adbr, aebr, axb, adb, aeb
3822(define_insn "*add<mode>3"
3823  [(set (match_operand:FPR 0 "register_operand" "=f,f")
3824        (plus:FPR (match_operand:FPR 1 "nonimmediate_operand" "%0,0")
3825                  (match_operand:FPR 2 "general_operand" "f,<Rf>")))
3826   (clobber (reg:CC CC_REGNUM))]
3827  "TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT"
3828  "@
3829   a<xde>br\t%0,%2
3830   a<xde>b\t%0,%2"
3831  [(set_attr "op_type"  "RRE,RXE")
3832   (set_attr "type"     "fsimp<mode>")])
3833
3834; axbr, adbr, aebr, axb, adb, aeb
3835(define_insn "*add<mode>3_cc"
3836  [(set (reg CC_REGNUM)
3837	(compare (plus:FPR (match_operand:FPR 1 "nonimmediate_operand" "%0,0")
3838			   (match_operand:FPR 2 "general_operand" "f,<Rf>"))
3839		 (match_operand:FPR 3 "const0_operand" "")))
3840   (set (match_operand:FPR 0 "register_operand" "=f,f")
3841	(plus:FPR (match_dup 1) (match_dup 2)))]
3842  "s390_match_ccmode (insn, CCSmode) && TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT"
3843  "@
3844   a<xde>br\t%0,%2
3845   a<xde>b\t%0,%2"
3846  [(set_attr "op_type"  "RRE,RXE")
3847   (set_attr "type"     "fsimp<mode>")])
3848
3849; axbr, adbr, aebr, axb, adb, aeb
3850(define_insn "*add<mode>3_cconly"
3851  [(set (reg CC_REGNUM)
3852	(compare (plus:FPR (match_operand:FPR 1 "nonimmediate_operand" "%0,0")
3853			   (match_operand:FPR 2 "general_operand" "f,<Rf>"))
3854		 (match_operand:FPR 3 "const0_operand" "")))
3855   (clobber (match_scratch:FPR 0 "=f,f"))]
3856  "s390_match_ccmode (insn, CCSmode) && TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT"
3857  "@
3858   a<xde>br\t%0,%2
3859   a<xde>b\t%0,%2"
3860  [(set_attr "op_type"  "RRE,RXE")
3861   (set_attr "type"     "fsimp<mode>")])
3862
3863; axr, adr, aer, ax, ad, ae
3864(define_insn "*add<mode>3_ibm"
3865  [(set (match_operand:FPR 0 "register_operand" "=f,f")
3866        (plus:FPR (match_operand:FPR 1 "nonimmediate_operand" "%0,0")
3867                  (match_operand:FPR 2 "general_operand" "f,<Rf>")))
3868   (clobber (reg:CC CC_REGNUM))]
3869  "TARGET_HARD_FLOAT && TARGET_IBM_FLOAT"
3870  "@
3871   a<xde>r\t%0,%2
3872   a<xde>\t%0,%2"
3873  [(set_attr "op_type"  "<RRe>,<RXe>")
3874   (set_attr "type"     "fsimp<mode>")])
3875
3876
3877;;
3878;;- Subtract instructions.
3879;;
3880
3881;
3882; subti3 instruction pattern(s).
3883;
3884
3885(define_insn_and_split "subti3"
3886  [(set (match_operand:TI 0 "register_operand" "=&d")
3887        (minus:TI (match_operand:TI 1 "register_operand" "0")
3888                  (match_operand:TI 2 "general_operand" "do") ) )
3889   (clobber (reg:CC CC_REGNUM))]
3890  "TARGET_64BIT"
3891  "#"
3892  "&& reload_completed"
3893  [(parallel
3894    [(set (reg:CCL2 CC_REGNUM)
3895          (compare:CCL2 (minus:DI (match_dup 7) (match_dup 8))
3896                        (match_dup 7)))
3897     (set (match_dup 6) (minus:DI (match_dup 7) (match_dup 8)))])
3898   (parallel
3899    [(set (match_dup 3) (minus:DI (minus:DI (match_dup 4) (match_dup 5))
3900                                  (gtu:DI (reg:CCL2 CC_REGNUM) (const_int 0))))
3901     (clobber (reg:CC CC_REGNUM))])]
3902  "operands[3] = operand_subword (operands[0], 0, 0, TImode);
3903   operands[4] = operand_subword (operands[1], 0, 0, TImode);
3904   operands[5] = operand_subword (operands[2], 0, 0, TImode);
3905   operands[6] = operand_subword (operands[0], 1, 0, TImode);
3906   operands[7] = operand_subword (operands[1], 1, 0, TImode);
3907   operands[8] = operand_subword (operands[2], 1, 0, TImode);")
3908
3909;
3910; subdi3 instruction pattern(s).
3911;
3912
3913(define_expand "subdi3"
3914  [(parallel
3915    [(set (match_operand:DI 0 "register_operand" "")
3916          (minus:DI (match_operand:DI 1 "register_operand" "")
3917                    (match_operand:DI 2 "general_operand" "")))
3918     (clobber (reg:CC CC_REGNUM))])]
3919  ""
3920  "")
3921
3922(define_insn "*subdi3_sign"
3923  [(set (match_operand:DI 0 "register_operand" "=d,d")
3924        (minus:DI (match_operand:DI 1 "register_operand" "0,0")
3925                  (sign_extend:DI (match_operand:SI 2 "general_operand" "d,m"))))
3926   (clobber (reg:CC CC_REGNUM))]
3927  "TARGET_64BIT"
3928  "@
3929   sgfr\t%0,%2
3930   sgf\t%0,%2"
3931  [(set_attr "op_type"  "RRE,RXY")])
3932
3933(define_insn "*subdi3_zero_cc"
3934  [(set (reg CC_REGNUM)
3935        (compare (minus:DI (match_operand:DI 1 "register_operand" "0,0")
3936                           (zero_extend:DI (match_operand:SI 2 "general_operand" "d,m")))
3937                 (const_int 0)))
3938   (set (match_operand:DI 0 "register_operand" "=d,d")
3939        (minus:DI (match_dup 1) (zero_extend:DI (match_dup 2))))]
3940  "s390_match_ccmode (insn, CCLmode) && TARGET_64BIT"
3941  "@
3942   slgfr\t%0,%2
3943   slgf\t%0,%2"
3944  [(set_attr "op_type"  "RRE,RXY")])
3945
3946(define_insn "*subdi3_zero_cconly"
3947  [(set (reg CC_REGNUM)
3948        (compare (minus:DI (match_operand:DI 1 "register_operand" "0,0")
3949                           (zero_extend:DI (match_operand:SI 2 "general_operand" "d,m")))
3950                 (const_int 0)))
3951   (clobber (match_scratch:DI 0 "=d,d"))]
3952  "s390_match_ccmode (insn, CCLmode) && TARGET_64BIT"
3953  "@
3954   slgfr\t%0,%2
3955   slgf\t%0,%2"
3956  [(set_attr "op_type"  "RRE,RXY")])
3957
3958(define_insn "*subdi3_zero"
3959  [(set (match_operand:DI 0 "register_operand" "=d,d")
3960        (minus:DI (match_operand:DI 1 "register_operand" "0,0")
3961                  (zero_extend:DI (match_operand:SI 2 "general_operand" "d,m"))))
3962   (clobber (reg:CC CC_REGNUM))]
3963  "TARGET_64BIT"
3964  "@
3965   slgfr\t%0,%2
3966   slgf\t%0,%2"
3967  [(set_attr "op_type"  "RRE,RXY")])
3968
3969(define_insn_and_split "*subdi3_31z"
3970  [(set (match_operand:DI 0 "register_operand" "=&d")
3971        (minus:DI (match_operand:DI 1 "register_operand" "0")
3972                  (match_operand:DI 2 "general_operand" "do") ) )
3973   (clobber (reg:CC CC_REGNUM))]
3974  "!TARGET_64BIT && TARGET_CPU_ZARCH"
3975  "#"
3976  "&& reload_completed"
3977  [(parallel
3978    [(set (reg:CCL2 CC_REGNUM)
3979          (compare:CCL2 (minus:SI (match_dup 7) (match_dup 8))
3980                        (match_dup 7)))
3981     (set (match_dup 6) (minus:SI (match_dup 7) (match_dup 8)))])
3982   (parallel
3983    [(set (match_dup 3) (minus:SI (minus:SI (match_dup 4) (match_dup 5))
3984                                  (gtu:SI (reg:CCL2 CC_REGNUM) (const_int 0))))
3985     (clobber (reg:CC CC_REGNUM))])]
3986  "operands[3] = operand_subword (operands[0], 0, 0, DImode);
3987   operands[4] = operand_subword (operands[1], 0, 0, DImode);
3988   operands[5] = operand_subword (operands[2], 0, 0, DImode);
3989   operands[6] = operand_subword (operands[0], 1, 0, DImode);
3990   operands[7] = operand_subword (operands[1], 1, 0, DImode);
3991   operands[8] = operand_subword (operands[2], 1, 0, DImode);")
3992
3993(define_insn_and_split "*subdi3_31"
3994  [(set (match_operand:DI 0 "register_operand" "=&d")
3995        (minus:DI (match_operand:DI 1 "register_operand" "0")
3996                  (match_operand:DI 2 "general_operand" "do") ) )
3997   (clobber (reg:CC CC_REGNUM))]
3998  "!TARGET_CPU_ZARCH"
3999  "#"
4000  "&& reload_completed"
4001  [(parallel
4002    [(set (match_dup 3) (minus:SI (match_dup 4) (match_dup 5)))
4003     (clobber (reg:CC CC_REGNUM))])
4004   (parallel
4005    [(set (reg:CCL2 CC_REGNUM)
4006          (compare:CCL2 (minus:SI (match_dup 7) (match_dup 8))
4007                        (match_dup 7)))
4008     (set (match_dup 6) (minus:SI (match_dup 7) (match_dup 8)))])
4009   (set (pc)
4010        (if_then_else (gtu (reg:CCL2 CC_REGNUM) (const_int 0))
4011                      (pc)
4012                      (label_ref (match_dup 9))))
4013   (parallel
4014    [(set (match_dup 3) (plus:SI (match_dup 3) (const_int -1)))
4015     (clobber (reg:CC CC_REGNUM))])
4016   (match_dup 9)]
4017  "operands[3] = operand_subword (operands[0], 0, 0, DImode);
4018   operands[4] = operand_subword (operands[1], 0, 0, DImode);
4019   operands[5] = operand_subword (operands[2], 0, 0, DImode);
4020   operands[6] = operand_subword (operands[0], 1, 0, DImode);
4021   operands[7] = operand_subword (operands[1], 1, 0, DImode);
4022   operands[8] = operand_subword (operands[2], 1, 0, DImode);
4023   operands[9] = gen_label_rtx ();")
4024
4025;
4026; subsi3 instruction pattern(s).
4027;
4028
4029(define_expand "subsi3"
4030  [(parallel
4031    [(set (match_operand:SI 0 "register_operand" "")
4032          (minus:SI (match_operand:SI 1 "register_operand" "")
4033                    (match_operand:SI 2 "general_operand" "")))
4034     (clobber (reg:CC CC_REGNUM))])]
4035  ""
4036  "")
4037
4038(define_insn "*subsi3_sign"
4039  [(set (match_operand:SI 0 "register_operand" "=d,d")
4040        (minus:SI (match_operand:SI 1 "register_operand" "0,0")
4041                  (sign_extend:SI (match_operand:HI 2 "memory_operand" "R,T"))))
4042   (clobber (reg:CC CC_REGNUM))]
4043  ""
4044  "@
4045   sh\t%0,%2
4046   shy\t%0,%2"
4047  [(set_attr "op_type"  "RX,RXY")])
4048
4049;
4050; sub(di|si)3 instruction pattern(s).
4051;
4052
4053; sr, s, sy, sgr, sg
4054(define_insn "*sub<mode>3"
4055  [(set (match_operand:GPR 0 "register_operand" "=d,d,d")
4056        (minus:GPR (match_operand:GPR 1 "register_operand" "0,0,0")
4057		   (match_operand:GPR 2 "general_operand" "d,R,T") ) )
4058   (clobber (reg:CC CC_REGNUM))]
4059  ""
4060  "@
4061   s<g>r\t%0,%2
4062   s<g>\t%0,%2
4063   s<y>\t%0,%2"
4064  [(set_attr "op_type"  "RR<E>,RX<Y>,RXY")])
4065
4066; slr, sl, sly, slgr, slg
4067(define_insn "*sub<mode>3_borrow_cc"
4068  [(set (reg CC_REGNUM)
4069        (compare (minus:GPR (match_operand:GPR 1 "register_operand" "0,0,0")
4070			    (match_operand:GPR 2 "general_operand" "d,R,T"))
4071                 (match_dup 1)))
4072   (set (match_operand:GPR 0 "register_operand" "=d,d,d")
4073        (minus:GPR (match_dup 1) (match_dup 2)))]
4074  "s390_match_ccmode (insn, CCL2mode)"
4075  "@
4076   sl<g>r\t%0,%2
4077   sl<g>\t%0,%2
4078   sl<y>\t%0,%2"
4079  [(set_attr "op_type"  "RR<E>,RX<Y>,RXY")])
4080
4081; slr, sl, sly, slgr, slg
4082(define_insn "*sub<mode>3_borrow_cconly"
4083  [(set (reg CC_REGNUM)
4084        (compare (minus:GPR (match_operand:GPR 1 "register_operand" "0,0,0")
4085			    (match_operand:GPR 2 "general_operand" "d,R,T"))
4086                 (match_dup 1)))
4087   (clobber (match_scratch:GPR 0 "=d,d,d"))]
4088  "s390_match_ccmode (insn, CCL2mode)"
4089  "@
4090   sl<g>r\t%0,%2
4091   sl<g>\t%0,%2
4092   sl<y>\t%0,%2"
4093  [(set_attr "op_type"  "RR<E>,RX<Y>,RXY")])
4094
4095; slr, sl, sly, slgr, slg
4096(define_insn "*sub<mode>3_cc"
4097  [(set (reg CC_REGNUM)
4098        (compare (minus:GPR (match_operand:GPR 1 "register_operand" "0,0,0")
4099			    (match_operand:GPR 2 "general_operand" "d,R,T"))
4100                 (const_int 0)))
4101   (set (match_operand:GPR 0 "register_operand" "=d,d,d")
4102        (minus:GPR (match_dup 1) (match_dup 2)))]
4103  "s390_match_ccmode (insn, CCLmode)"
4104  "@
4105   sl<g>r\t%0,%2
4106   sl<g>\t%0,%2
4107   sl<y>\t%0,%2"
4108  [(set_attr "op_type"  "RR<E>,RX<Y>,RXY")])
4109
4110; slr, sl, sly, slgr, slg
4111(define_insn "*sub<mode>3_cc2"
4112  [(set (reg CC_REGNUM)
4113        (compare (match_operand:GPR 1 "register_operand" "0,0,0")
4114                 (match_operand:GPR 2 "general_operand" "d,R,T")))
4115   (set (match_operand:GPR 0 "register_operand" "=d,d,d")
4116        (minus:GPR (match_dup 1) (match_dup 2)))]
4117  "s390_match_ccmode (insn, CCL3mode)"
4118  "@
4119   sl<g>r\t%0,%2
4120   sl<g>\t%0,%2
4121   sl<y>\t%0,%2"
4122  [(set_attr "op_type"  "RR<E>,RX<Y>,RXY")])
4123
4124; slr, sl, sly, slgr, slg
4125(define_insn "*sub<mode>3_cconly"
4126  [(set (reg CC_REGNUM)
4127        (compare (minus:GPR (match_operand:GPR 1 "register_operand" "0,0,0")
4128			    (match_operand:GPR 2 "general_operand" "d,R,T"))
4129                 (const_int 0)))
4130   (clobber (match_scratch:GPR 0 "=d,d,d"))]
4131  "s390_match_ccmode (insn, CCLmode)"
4132  "@
4133   sl<g>r\t%0,%2
4134   sl<g>\t%0,%2
4135   sl<y>\t%0,%2"
4136  [(set_attr "op_type"  "RR<E>,RX<Y>,RXY")])
4137
4138; slr, sl, sly, slgr, slg
4139(define_insn "*sub<mode>3_cconly2"
4140  [(set (reg CC_REGNUM)
4141        (compare (match_operand:GPR 1 "register_operand" "0,0,0")
4142                 (match_operand:GPR 2 "general_operand" "d,R,T")))
4143   (clobber (match_scratch:GPR 0 "=d,d,d"))]
4144  "s390_match_ccmode (insn, CCL3mode)"
4145  "@
4146   sl<g>r\t%0,%2
4147   sl<g>\t%0,%2
4148   sl<y>\t%0,%2"
4149  [(set_attr "op_type"  "RR<E>,RX<Y>,RXY")])
4150
4151;
4152; sub(df|sf)3 instruction pattern(s).
4153;
4154
4155(define_expand "sub<mode>3"
4156  [(parallel
4157    [(set (match_operand:FPR 0 "register_operand" "=f,f")
4158          (minus:FPR (match_operand:FPR 1 "register_operand" "0,0")
4159                     (match_operand:FPR 2 "general_operand" "f,R")))
4160     (clobber (reg:CC CC_REGNUM))])]
4161  "TARGET_HARD_FLOAT"
4162  "")
4163
4164; sxbr, sdbr, sebr, sxb, sdb, seb
4165(define_insn "*sub<mode>3"
4166  [(set (match_operand:FPR 0 "register_operand" "=f,f")
4167        (minus:FPR (match_operand:FPR 1 "register_operand" "0,0")
4168                   (match_operand:FPR 2 "general_operand" "f,<Rf>")))
4169   (clobber (reg:CC CC_REGNUM))]
4170  "TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT"
4171  "@
4172   s<xde>br\t%0,%2
4173   s<xde>b\t%0,%2"
4174  [(set_attr "op_type"  "RRE,RXE")
4175   (set_attr "type"     "fsimp<mode>")])
4176
4177; sxbr, sdbr, sebr, sxb, sdb, seb
4178(define_insn "*sub<mode>3_cc"
4179  [(set (reg CC_REGNUM)
4180	(compare (minus:FPR (match_operand:FPR 1 "nonimmediate_operand" "0,0")
4181			    (match_operand:FPR 2 "general_operand" "f,<Rf>"))
4182		 (match_operand:FPR 3 "const0_operand" "")))
4183   (set (match_operand:FPR 0 "register_operand" "=f,f")
4184	(minus:FPR (match_dup 1) (match_dup 2)))]
4185  "s390_match_ccmode (insn, CCSmode) && TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT"
4186  "@
4187   s<xde>br\t%0,%2
4188   s<xde>b\t%0,%2"
4189  [(set_attr "op_type"  "RRE,RXE")
4190   (set_attr "type"     "fsimp<mode>")])
4191
4192; sxbr, sdbr, sebr, sxb, sdb, seb
4193(define_insn "*sub<mode>3_cconly"
4194  [(set (reg CC_REGNUM)
4195	(compare (minus:FPR (match_operand:FPR 1 "nonimmediate_operand" "0,0")
4196			    (match_operand:FPR 2 "general_operand" "f,<Rf>"))
4197		 (match_operand:FPR 3 "const0_operand" "")))
4198   (clobber (match_scratch:FPR 0 "=f,f"))]
4199  "s390_match_ccmode (insn, CCSmode) && TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT"
4200  "@
4201   s<xde>br\t%0,%2
4202   s<xde>b\t%0,%2"
4203  [(set_attr "op_type"  "RRE,RXE")
4204   (set_attr "type"     "fsimp<mode>")])
4205
4206; sxr, sdr, ser, sx, sd, se
4207(define_insn "*sub<mode>3_ibm"
4208  [(set (match_operand:FPR 0 "register_operand" "=f,f")
4209        (minus:FPR (match_operand:FPR 1 "register_operand" "0,0")
4210                   (match_operand:FPR 2 "general_operand" "f,<Rf>")))
4211   (clobber (reg:CC CC_REGNUM))]
4212  "TARGET_HARD_FLOAT && TARGET_IBM_FLOAT"
4213  "@
4214   s<xde>r\t%0,%2
4215   s<xde>\t%0,%2"
4216  [(set_attr "op_type"  "<RRe>,<RXe>")
4217   (set_attr "type"     "fsimp<mode>")])
4218
4219
4220;;
4221;;- Conditional add/subtract instructions.
4222;;
4223
4224;
4225; add(di|si)cc instruction pattern(s).
4226;
4227
4228; alcr, alc, alcgr, alcg
4229(define_insn "*add<mode>3_alc_cc"
4230  [(set (reg CC_REGNUM)
4231        (compare
4232          (plus:GPR (plus:GPR (match_operand:GPR 1 "nonimmediate_operand" "%0,0")
4233                              (match_operand:GPR 2 "general_operand" "d,m"))
4234                    (match_operand:GPR 3 "s390_alc_comparison" ""))
4235          (const_int 0)))
4236   (set (match_operand:GPR 0 "register_operand" "=d,d")
4237        (plus:GPR (plus:GPR (match_dup 1) (match_dup 2)) (match_dup 3)))]
4238  "s390_match_ccmode (insn, CCLmode) && TARGET_CPU_ZARCH"
4239  "@
4240   alc<g>r\t%0,%2
4241   alc<g>\t%0,%2"
4242  [(set_attr "op_type"  "RRE,RXY")])
4243
4244; alcr, alc, alcgr, alcg
4245(define_insn "*add<mode>3_alc"
4246  [(set (match_operand:GPR 0 "register_operand" "=d,d")
4247        (plus:GPR (plus:GPR (match_operand:GPR 1 "nonimmediate_operand" "%0,0")
4248                            (match_operand:GPR 2 "general_operand" "d,m"))
4249                  (match_operand:GPR 3 "s390_alc_comparison" "")))
4250   (clobber (reg:CC CC_REGNUM))]
4251  "TARGET_CPU_ZARCH"
4252  "@
4253   alc<g>r\t%0,%2
4254   alc<g>\t%0,%2"
4255  [(set_attr "op_type"  "RRE,RXY")])
4256
4257; slbr, slb, slbgr, slbg
4258(define_insn "*sub<mode>3_slb_cc"
4259  [(set (reg CC_REGNUM)
4260        (compare
4261          (minus:GPR (minus:GPR (match_operand:GPR 1 "nonimmediate_operand" "0,0")
4262                                (match_operand:GPR 2 "general_operand" "d,m"))
4263                     (match_operand:GPR 3 "s390_slb_comparison" ""))
4264          (const_int 0)))
4265   (set (match_operand:GPR 0 "register_operand" "=d,d")
4266        (minus:GPR (minus:GPR (match_dup 1) (match_dup 2)) (match_dup 3)))]
4267  "s390_match_ccmode (insn, CCLmode) && TARGET_CPU_ZARCH"
4268  "@
4269   slb<g>r\t%0,%2
4270   slb<g>\t%0,%2"
4271  [(set_attr "op_type"  "RRE,RXY")])
4272
4273; slbr, slb, slbgr, slbg
4274(define_insn "*sub<mode>3_slb"
4275  [(set (match_operand:GPR 0 "register_operand" "=d,d")
4276        (minus:GPR (minus:GPR (match_operand:GPR 1 "nonimmediate_operand" "0,0")
4277                              (match_operand:GPR 2 "general_operand" "d,m"))
4278                   (match_operand:GPR 3 "s390_slb_comparison" "")))
4279   (clobber (reg:CC CC_REGNUM))]
4280  "TARGET_CPU_ZARCH"
4281  "@
4282   slb<g>r\t%0,%2
4283   slb<g>\t%0,%2"
4284  [(set_attr "op_type"  "RRE,RXY")])
4285
4286(define_expand "add<mode>cc"
4287  [(match_operand:GPR 0 "register_operand" "")
4288   (match_operand 1 "comparison_operator" "")
4289   (match_operand:GPR 2 "register_operand" "")
4290   (match_operand:GPR 3 "const_int_operand" "")]
4291  "TARGET_CPU_ZARCH"
4292  "if (!s390_expand_addcc (GET_CODE (operands[1]), 
4293			   s390_compare_op0, s390_compare_op1, 
4294			   operands[0], operands[2], 
4295			   operands[3])) FAIL; DONE;")
4296
4297;
4298; scond instruction pattern(s).
4299;
4300
4301(define_insn_and_split "*scond<mode>"
4302  [(set (match_operand:GPR 0 "register_operand" "=&d")
4303        (match_operand:GPR 1 "s390_alc_comparison" ""))
4304   (clobber (reg:CC CC_REGNUM))]
4305  "TARGET_CPU_ZARCH"
4306  "#"
4307  "&& reload_completed"
4308  [(set (match_dup 0) (const_int 0))
4309   (parallel
4310    [(set (match_dup 0) (plus:GPR (plus:GPR (match_dup 0) (match_dup 0))
4311                                  (match_dup 1)))
4312     (clobber (reg:CC CC_REGNUM))])]
4313  "")
4314
4315(define_insn_and_split "*scond<mode>_neg"
4316  [(set (match_operand:GPR 0 "register_operand" "=&d")
4317        (match_operand:GPR 1 "s390_slb_comparison" ""))
4318   (clobber (reg:CC CC_REGNUM))]
4319  "TARGET_CPU_ZARCH"
4320  "#"
4321  "&& reload_completed"
4322  [(set (match_dup 0) (const_int 0))
4323   (parallel
4324    [(set (match_dup 0) (minus:GPR (minus:GPR (match_dup 0) (match_dup 0))
4325                                   (match_dup 1)))
4326     (clobber (reg:CC CC_REGNUM))])
4327   (parallel
4328    [(set (match_dup 0) (neg:GPR (match_dup 0)))
4329     (clobber (reg:CC CC_REGNUM))])]
4330  "")
4331
4332
4333(define_expand "s<code>"
4334  [(set (match_operand:SI 0 "register_operand" "")
4335	(SCOND (match_dup 0)
4336	       (match_dup 0)))]
4337  "TARGET_CPU_ZARCH"
4338  "if (!s390_expand_addcc (<CODE>, s390_compare_op0, s390_compare_op1,
4339			   operands[0], const0_rtx, const1_rtx)) FAIL; DONE;")
4340
4341(define_expand "seq"
4342  [(parallel
4343    [(set (match_operand:SI 0 "register_operand" "=d")
4344          (match_dup 1))
4345     (clobber (reg:CC CC_REGNUM))])
4346   (parallel
4347    [(set (match_dup 0) (xor:SI (match_dup 0) (const_int 1)))
4348     (clobber (reg:CC CC_REGNUM))])]
4349  ""
4350{ 
4351  if (!s390_compare_emitted || GET_MODE (s390_compare_emitted) != CCZ1mode)
4352    FAIL;
4353  operands[1] = s390_emit_compare (NE, s390_compare_op0, s390_compare_op1);
4354  PUT_MODE (operands[1], SImode);
4355})
4356
4357(define_insn_and_split "*sne"
4358  [(set (match_operand:SI 0 "register_operand" "=d")
4359	(ne:SI (match_operand:CCZ1 1 "register_operand" "0") 
4360	       (const_int 0)))
4361   (clobber (reg:CC CC_REGNUM))]
4362  ""
4363  "#"
4364  "reload_completed"
4365  [(parallel
4366    [(set (match_dup 0) (ashiftrt:SI (match_dup 0) (const_int 28)))
4367     (clobber (reg:CC CC_REGNUM))])])
4368
4369
4370;;
4371;;- Multiply instructions.
4372;;
4373
4374;
4375; muldi3 instruction pattern(s).
4376;
4377
4378(define_insn "*muldi3_sign"
4379  [(set (match_operand:DI 0 "register_operand" "=d,d")
4380        (mult:DI (sign_extend:DI (match_operand:SI 2 "nonimmediate_operand" "d,m"))
4381                 (match_operand:DI 1 "register_operand" "0,0")))]
4382  "TARGET_64BIT"
4383  "@
4384   msgfr\t%0,%2
4385   msgf\t%0,%2"
4386  [(set_attr "op_type"  "RRE,RXY")
4387   (set_attr "type"     "imuldi")])
4388
4389(define_insn "muldi3"
4390  [(set (match_operand:DI 0 "register_operand" "=d,d,d")
4391        (mult:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
4392                 (match_operand:DI 2 "general_operand" "d,K,m")))]
4393  "TARGET_64BIT"
4394  "@
4395   msgr\t%0,%2
4396   mghi\t%0,%h2
4397   msg\t%0,%2"
4398  [(set_attr "op_type"  "RRE,RI,RXY")
4399   (set_attr "type"     "imuldi")])
4400
4401;
4402; mulsi3 instruction pattern(s).
4403;
4404
4405(define_insn "*mulsi3_sign"
4406  [(set (match_operand:SI 0 "register_operand" "=d")
4407        (mult:SI (sign_extend:SI (match_operand:HI 2 "memory_operand" "R"))
4408                 (match_operand:SI 1 "register_operand" "0")))]
4409  ""
4410  "mh\t%0,%2"
4411  [(set_attr "op_type"  "RX")
4412   (set_attr "type"     "imulhi")])
4413
4414(define_insn "mulsi3"
4415  [(set (match_operand:SI 0 "register_operand" "=d,d,d,d")
4416        (mult:SI  (match_operand:SI 1 "nonimmediate_operand" "%0,0,0,0")
4417                  (match_operand:SI 2 "general_operand" "d,K,R,T")))]
4418  ""
4419  "@
4420   msr\t%0,%2
4421   mhi\t%0,%h2
4422   ms\t%0,%2
4423   msy\t%0,%2"
4424  [(set_attr "op_type"  "RRE,RI,RX,RXY")
4425   (set_attr "type"     "imulsi,imulhi,imulsi,imulsi")])
4426
4427;
4428; mulsidi3 instruction pattern(s).
4429;
4430
4431(define_insn "mulsidi3"
4432  [(set (match_operand:DI 0 "register_operand" "=d,d")
4433        (mult:DI (sign_extend:DI
4434	           (match_operand:SI 1 "register_operand" "%0,0"))
4435                 (sign_extend:DI
4436	           (match_operand:SI 2 "nonimmediate_operand" "d,R"))))]
4437  "!TARGET_64BIT"
4438  "@
4439   mr\t%0,%2
4440   m\t%0,%2"
4441  [(set_attr "op_type"  "RR,RX")
4442   (set_attr "type"     "imulsi")])
4443
4444;
4445; umulsidi3 instruction pattern(s).
4446;
4447
4448(define_insn "umulsidi3"
4449  [(set (match_operand:DI 0 "register_operand" "=d,d")
4450        (mult:DI (zero_extend:DI
4451	           (match_operand:SI 1 "register_operand" "%0,0"))
4452                 (zero_extend:DI
4453	           (match_operand:SI 2 "nonimmediate_operand" "d,m"))))]
4454  "!TARGET_64BIT && TARGET_CPU_ZARCH"
4455  "@
4456   mlr\t%0,%2
4457   ml\t%0,%2"
4458  [(set_attr "op_type"  "RRE,RXY")
4459   (set_attr "type"     "imulsi")])
4460
4461;
4462; mul(df|sf)3 instruction pattern(s).
4463;
4464
4465(define_expand "mul<mode>3"
4466  [(set (match_operand:FPR 0 "register_operand" "=f,f")
4467        (mult:FPR (match_operand:FPR 1 "nonimmediate_operand" "%0,0")
4468                  (match_operand:FPR 2 "general_operand" "f,<Rf>")))]
4469  "TARGET_HARD_FLOAT"
4470  "")
4471
4472; mxbr mdbr, meebr, mxb, mxb, meeb
4473(define_insn "*mul<mode>3"
4474  [(set (match_operand:FPR 0 "register_operand" "=f,f")
4475        (mult:FPR (match_operand:FPR 1 "nonimmediate_operand" "%0,0")
4476                  (match_operand:FPR 2 "general_operand" "f,<Rf>")))]
4477  "TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT"
4478  "@
4479   m<xdee>br\t%0,%2
4480   m<xdee>b\t%0,%2"
4481  [(set_attr "op_type"  "RRE,RXE")
4482   (set_attr "type"     "fmul<mode>")])
4483
4484; mxr, mdr, mer, mx, md, me
4485(define_insn "*mul<mode>3_ibm"
4486  [(set (match_operand:FPR 0 "register_operand" "=f,f")
4487        (mult:FPR (match_operand:FPR 1 "nonimmediate_operand" "%0,0")
4488                  (match_operand:FPR 2 "general_operand" "f,<Rf>")))]
4489  "TARGET_HARD_FLOAT && TARGET_IBM_FLOAT"
4490  "@
4491   m<xde>r\t%0,%2
4492   m<xde>\t%0,%2"
4493  [(set_attr "op_type"  "<RRe>,<RXe>")
4494   (set_attr "type"     "fmul<mode>")])
4495
4496; maxbr, madbr, maebr, maxb, madb, maeb
4497(define_insn "*fmadd<mode>"
4498  [(set (match_operand:DSF 0 "register_operand" "=f,f")
4499	(plus:DSF (mult:DSF (match_operand:DSF 1 "register_operand" "%f,f")
4500			    (match_operand:DSF 2 "nonimmediate_operand"  "f,R"))
4501		 (match_operand:DSF 3 "register_operand" "0,0")))]
4502  "TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT && TARGET_FUSED_MADD"
4503  "@
4504   ma<xde>br\t%0,%1,%2
4505   ma<xde>b\t%0,%1,%2"
4506  [(set_attr "op_type"  "RRE,RXE")
4507   (set_attr "type"     "fmul<mode>")])
4508
4509; msxbr, msdbr, msebr, msxb, msdb, mseb
4510(define_insn "*fmsub<mode>"
4511  [(set (match_operand:DSF 0 "register_operand" "=f,f")
4512	(minus:DSF (mult:DSF (match_operand:DSF 1 "register_operand" "f,f")
4513			     (match_operand:DSF 2 "nonimmediate_operand"  "f,R"))
4514		 (match_operand:DSF 3 "register_operand" "0,0")))]
4515  "TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT && TARGET_FUSED_MADD"
4516  "@
4517   ms<xde>br\t%0,%1,%2
4518   ms<xde>b\t%0,%1,%2"
4519  [(set_attr "op_type"  "RRE,RXE")
4520   (set_attr "type"     "fmul<mode>")])
4521
4522;;
4523;;- Divide and modulo instructions.
4524;;
4525
4526;
4527; divmoddi4 instruction pattern(s).
4528;
4529
4530(define_expand "divmoddi4"
4531  [(parallel [(set (match_operand:DI 0 "general_operand" "")
4532		   (div:DI (match_operand:DI 1 "register_operand" "")
4533			   (match_operand:DI 2 "general_operand" "")))
4534	      (set (match_operand:DI 3 "general_operand" "")
4535		   (mod:DI (match_dup 1) (match_dup 2)))])
4536   (clobber (match_dup 4))]
4537  "TARGET_64BIT"
4538{
4539  rtx insn, div_equal, mod_equal;
4540
4541  div_equal = gen_rtx_DIV (DImode, operands[1], operands[2]);
4542  mod_equal = gen_rtx_MOD (DImode, operands[1], operands[2]);
4543
4544  operands[4] = gen_reg_rtx(TImode);
4545  emit_insn (gen_divmodtidi3 (operands[4], operands[1], operands[2]));
4546
4547  insn = emit_move_insn (operands[0], gen_lowpart (DImode, operands[4]));
4548  REG_NOTES (insn) =
4549        gen_rtx_EXPR_LIST (REG_EQUAL, div_equal, REG_NOTES (insn));
4550
4551  insn = emit_move_insn (operands[3], gen_highpart (DImode, operands[4]));
4552  REG_NOTES (insn) =
4553        gen_rtx_EXPR_LIST (REG_EQUAL, mod_equal, REG_NOTES (insn));
4554
4555  DONE;
4556})
4557
4558(define_insn "divmodtidi3"
4559  [(set (match_operand:TI 0 "register_operand" "=d,d")
4560        (ior:TI
4561          (ashift:TI
4562            (zero_extend:TI
4563              (mod:DI (match_operand:DI 1 "register_operand" "0,0")
4564                      (match_operand:DI 2 "general_operand" "d,m")))
4565            (const_int 64))
4566          (zero_extend:TI (div:DI (match_dup 1) (match_dup 2)))))]
4567  "TARGET_64BIT"
4568  "@
4569   dsgr\t%0,%2
4570   dsg\t%0,%2"
4571  [(set_attr "op_type"  "RRE,RXY")
4572   (set_attr "type"     "idiv")])
4573
4574(define_insn "divmodtisi3"
4575  [(set (match_operand:TI 0 "register_operand" "=d,d")
4576        (ior:TI
4577          (ashift:TI
4578            (zero_extend:TI
4579              (mod:DI (match_operand:DI 1 "register_operand" "0,0")
4580                      (sign_extend:DI
4581                        (match_operand:SI 2 "nonimmediate_operand" "d,m"))))
4582            (const_int 64))
4583          (zero_extend:TI
4584            (div:DI (match_dup 1) (sign_extend:DI (match_dup 2))))))]
4585  "TARGET_64BIT"
4586  "@
4587   dsgfr\t%0,%2
4588   dsgf\t%0,%2"
4589  [(set_attr "op_type"  "RRE,RXY")
4590   (set_attr "type"     "idiv")])
4591
4592;
4593; udivmoddi4 instruction pattern(s).
4594;
4595
4596(define_expand "udivmoddi4"
4597  [(parallel [(set (match_operand:DI 0 "general_operand" "")
4598		   (udiv:DI (match_operand:DI 1 "general_operand" "")
4599			    (match_operand:DI 2 "nonimmediate_operand" "")))
4600	      (set (match_operand:DI 3 "general_operand" "")
4601		   (umod:DI (match_dup 1) (match_dup 2)))])
4602   (clobber (match_dup 4))]
4603  "TARGET_64BIT"
4604{
4605  rtx insn, div_equal, mod_equal, equal;
4606
4607  div_equal = gen_rtx_UDIV (DImode, operands[1], operands[2]);
4608  mod_equal = gen_rtx_UMOD (DImode, operands[1], operands[2]);
4609  equal = gen_rtx_IOR (TImode,
4610		       gen_rtx_ASHIFT (TImode,
4611				       gen_rtx_ZERO_EXTEND (TImode, mod_equal),
4612				       GEN_INT (64)),
4613		       gen_rtx_ZERO_EXTEND (TImode, div_equal));
4614
4615  operands[4] = gen_reg_rtx(TImode);
4616  emit_insn (gen_rtx_CLOBBER (VOIDmode, operands[4]));
4617  emit_move_insn (gen_lowpart (DImode, operands[4]), operands[1]);
4618  emit_move_insn (gen_highpart (DImode, operands[4]), const0_rtx);
4619  insn = emit_insn (gen_udivmodtidi3 (operands[4], operands[4], operands[2]));
4620  REG_NOTES (insn) =
4621	gen_rtx_EXPR_LIST (REG_EQUAL, equal, REG_NOTES (insn));
4622
4623  insn = emit_move_insn (operands[0], gen_lowpart (DImode, operands[4]));
4624  REG_NOTES (insn) =
4625        gen_rtx_EXPR_LIST (REG_EQUAL, div_equal, REG_NOTES (insn));
4626
4627  insn = emit_move_insn (operands[3], gen_highpart (DImode, operands[4]));
4628  REG_NOTES (insn) =
4629        gen_rtx_EXPR_LIST (REG_EQUAL, mod_equal, REG_NOTES (insn));
4630
4631  DONE;
4632})
4633
4634(define_insn "udivmodtidi3"
4635  [(set (match_operand:TI 0 "register_operand" "=d,d")
4636        (ior:TI
4637          (ashift:TI
4638            (zero_extend:TI
4639              (truncate:DI
4640                (umod:TI (match_operand:TI 1 "register_operand" "0,0")
4641                         (zero_extend:TI
4642                           (match_operand:DI 2 "nonimmediate_operand" "d,m")))))
4643            (const_int 64))
4644          (zero_extend:TI
4645            (truncate:DI
4646              (udiv:TI (match_dup 1) (zero_extend:TI (match_dup 2)))))))]
4647  "TARGET_64BIT"
4648  "@
4649   dlgr\t%0,%2
4650   dlg\t%0,%2"
4651  [(set_attr "op_type"  "RRE,RXY")
4652   (set_attr "type"     "idiv")])
4653
4654;
4655; divmodsi4 instruction pattern(s).
4656;
4657
4658(define_expand "divmodsi4"
4659  [(parallel [(set (match_operand:SI 0 "general_operand" "")
4660		   (div:SI (match_operand:SI 1 "general_operand" "")
4661			   (match_operand:SI 2 "nonimmediate_operand" "")))
4662	      (set (match_operand:SI 3 "general_operand" "")
4663		   (mod:SI (match_dup 1) (match_dup 2)))])
4664   (clobber (match_dup 4))]
4665  "!TARGET_64BIT"
4666{
4667  rtx insn, div_equal, mod_equal, equal;
4668
4669  div_equal = gen_rtx_DIV (SImode, operands[1], operands[2]);
4670  mod_equal = gen_rtx_MOD (SImode, operands[1], operands[2]);
4671  equal = gen_rtx_IOR (DImode,
4672		       gen_rtx_ASHIFT (DImode,
4673				       gen_rtx_ZERO_EXTEND (DImode, mod_equal),
4674				       GEN_INT (32)),
4675		       gen_rtx_ZERO_EXTEND (DImode, div_equal));
4676
4677  operands[4] = gen_reg_rtx(DImode);
4678  emit_insn (gen_extendsidi2 (operands[4], operands[1]));
4679  insn = emit_insn (gen_divmoddisi3 (operands[4], operands[4], operands[2]));
4680  REG_NOTES (insn) =
4681	gen_rtx_EXPR_LIST (REG_EQUAL, equal, REG_NOTES (insn));
4682
4683  insn = emit_move_insn (operands[0], gen_lowpart (SImode, operands[4]));
4684  REG_NOTES (insn) =
4685        gen_rtx_EXPR_LIST (REG_EQUAL, div_equal, REG_NOTES (insn));
4686
4687  insn = emit_move_insn (operands[3], gen_highpart (SImode, operands[4]));
4688  REG_NOTES (insn) =
4689        gen_rtx_EXPR_LIST (REG_EQUAL, mod_equal, REG_NOTES (insn));
4690
4691  DONE;
4692})
4693
4694(define_insn "divmoddisi3"
4695  [(set (match_operand:DI 0 "register_operand" "=d,d")
4696        (ior:DI
4697          (ashift:DI
4698            (zero_extend:DI
4699              (truncate:SI
4700                (mod:DI (match_operand:DI 1 "register_operand" "0,0")
4701                        (sign_extend:DI
4702                          (match_operand:SI 2 "nonimmediate_operand" "d,R")))))
4703            (const_int 32))
4704          (zero_extend:DI
4705            (truncate:SI
4706              (div:DI (match_dup 1) (sign_extend:DI (match_dup 2)))))))]
4707  "!TARGET_64BIT"
4708  "@
4709   dr\t%0,%2
4710   d\t%0,%2"
4711  [(set_attr "op_type"  "RR,RX")
4712   (set_attr "type"     "idiv")])
4713
4714;
4715; udivsi3 and umodsi3 instruction pattern(s).
4716;
4717
4718(define_expand "udivmodsi4"
4719  [(parallel [(set (match_operand:SI 0 "general_operand" "")
4720		   (udiv:SI (match_operand:SI 1 "general_operand" "")
4721			    (match_operand:SI 2 "nonimmediate_operand" "")))
4722	      (set (match_operand:SI 3 "general_operand" "")
4723		   (umod:SI (match_dup 1) (match_dup 2)))])
4724   (clobber (match_dup 4))]
4725  "!TARGET_64BIT && TARGET_CPU_ZARCH"
4726{
4727  rtx insn, div_equal, mod_equal, equal;
4728
4729  div_equal = gen_rtx_UDIV (SImode, operands[1], operands[2]);
4730  mod_equal = gen_rtx_UMOD (SImode, operands[1], operands[2]);
4731  equal = gen_rtx_IOR (DImode,
4732		       gen_rtx_ASHIFT (DImode,
4733				       gen_rtx_ZERO_EXTEND (DImode, mod_equal),
4734				       GEN_INT (32)),
4735		       gen_rtx_ZERO_EXTEND (DImode, div_equal));
4736
4737  operands[4] = gen_reg_rtx(DImode);
4738  emit_insn (gen_rtx_CLOBBER (VOIDmode, operands[4]));
4739  emit_move_insn (gen_lowpart (SImode, operands[4]), operands[1]);
4740  emit_move_insn (gen_highpart (SImode, operands[4]), const0_rtx);
4741  insn = emit_insn (gen_udivmoddisi3 (operands[4], operands[4], operands[2]));
4742  REG_NOTES (insn) =
4743	gen_rtx_EXPR_LIST (REG_EQUAL, equal, REG_NOTES (insn));
4744
4745  insn = emit_move_insn (operands[0], gen_lowpart (SImode, operands[4]));
4746  REG_NOTES (insn) =
4747        gen_rtx_EXPR_LIST (REG_EQUAL, div_equal, REG_NOTES (insn));
4748
4749  insn = emit_move_insn (operands[3], gen_highpart (SImode, operands[4]));
4750  REG_NOTES (insn) =
4751        gen_rtx_EXPR_LIST (REG_EQUAL, mod_equal, REG_NOTES (insn));
4752
4753  DONE;
4754})
4755
4756(define_insn "udivmoddisi3"
4757  [(set (match_operand:DI 0 "register_operand" "=d,d")
4758        (ior:DI
4759          (ashift:DI
4760            (zero_extend:DI
4761              (truncate:SI
4762                (umod:DI (match_operand:DI 1 "register_operand" "0,0")
4763                         (zero_extend:DI
4764                           (match_operand:SI 2 "nonimmediate_operand" "d,m")))))
4765            (const_int 32))
4766          (zero_extend:DI
4767            (truncate:SI
4768              (udiv:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))))]
4769  "!TARGET_64BIT && TARGET_CPU_ZARCH"
4770  "@
4771   dlr\t%0,%2
4772   dl\t%0,%2"
4773  [(set_attr "op_type"  "RRE,RXY")
4774   (set_attr "type"     "idiv")])
4775
4776(define_expand "udivsi3"
4777  [(set (match_operand:SI 0 "register_operand" "=d")
4778        (udiv:SI (match_operand:SI 1 "general_operand" "")
4779                 (match_operand:SI 2 "general_operand" "")))
4780   (clobber (match_dup 3))]
4781  "!TARGET_64BIT && !TARGET_CPU_ZARCH"
4782{
4783  rtx insn, udiv_equal, umod_equal, equal;
4784
4785  udiv_equal = gen_rtx_UDIV (SImode, operands[1], operands[2]);
4786  umod_equal = gen_rtx_UMOD (SImode, operands[1], operands[2]);
4787  equal = gen_rtx_IOR (DImode,
4788		       gen_rtx_ASHIFT (DImode,
4789				       gen_rtx_ZERO_EXTEND (DImode, umod_equal),
4790				       GEN_INT (32)),
4791		       gen_rtx_ZERO_EXTEND (DImode, udiv_equal));
4792
4793  operands[3] = gen_reg_rtx (DImode);
4794
4795  if (CONSTANT_P (operands[2]))
4796    {
4797      if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0)
4798        {
4799          rtx label1 = gen_label_rtx ();
4800
4801	  operands[1] = make_safe_from (operands[1], operands[0]);
4802          emit_move_insn (operands[0], const0_rtx);
4803          emit_insn (gen_cmpsi (operands[1], operands[2]));
4804          emit_jump_insn (gen_bltu (label1));
4805          emit_move_insn (operands[0], const1_rtx);
4806          emit_label (label1);
4807        }
4808      else
4809        {
4810          operands[2] = force_reg (SImode, operands[2]);
4811          operands[2] = make_safe_from (operands[2], operands[0]);
4812
4813	  emit_insn (gen_zero_extendsidi2 (operands[3], operands[1]));
4814	  insn = emit_insn (gen_divmoddisi3 (operands[3], operands[3],
4815					     operands[2]));
4816	  REG_NOTES (insn) =
4817	    gen_rtx_EXPR_LIST (REG_EQUAL, equal, REG_NOTES (insn));
4818
4819	  insn = emit_move_insn (operands[0],
4820				 gen_lowpart (SImode, operands[3]));
4821	  REG_NOTES (insn) =
4822	    gen_rtx_EXPR_LIST (REG_EQUAL,
4823			       udiv_equal, REG_NOTES (insn));
4824        }
4825    }
4826  else
4827    {
4828      rtx label1 = gen_label_rtx ();
4829      rtx label2 = gen_label_rtx ();
4830      rtx label3 = gen_label_rtx ();
4831
4832      operands[1] = force_reg (SImode, operands[1]);
4833      operands[1] = make_safe_from (operands[1], operands[0]);
4834      operands[2] = force_reg (SImode, operands[2]);
4835      operands[2] = make_safe_from (operands[2], operands[0]);
4836
4837      emit_move_insn (operands[0], const0_rtx);
4838      emit_insn (gen_cmpsi (operands[2], operands[1]));
4839      emit_jump_insn (gen_bgtu (label3));
4840      emit_insn (gen_cmpsi (operands[2], const0_rtx));
4841      emit_jump_insn (gen_blt (label2));
4842      emit_insn (gen_cmpsi (operands[2], const1_rtx));
4843      emit_jump_insn (gen_beq (label1));
4844      emit_insn (gen_zero_extendsidi2 (operands[3], operands[1]));
4845      insn = emit_insn (gen_divmoddisi3 (operands[3], operands[3],
4846					 operands[2]));
4847      REG_NOTES (insn) =
4848      gen_rtx_EXPR_LIST (REG_EQUAL, equal, REG_NOTES (insn));
4849
4850      insn = emit_move_insn (operands[0],
4851			     gen_lowpart (SImode, operands[3]));
4852      REG_NOTES (insn) =
4853      gen_rtx_EXPR_LIST (REG_EQUAL,
4854			       udiv_equal, REG_NOTES (insn));
4855      emit_jump (label3);
4856      emit_label (label1);
4857      emit_move_insn (operands[0], operands[1]);
4858      emit_jump (label3);
4859      emit_label (label2);
4860      emit_move_insn (operands[0], const1_rtx);
4861      emit_label (label3);
4862    }
4863  emit_move_insn (operands[0], operands[0]);
4864  DONE;
4865})
4866
4867(define_expand "umodsi3"
4868  [(set (match_operand:SI 0 "register_operand" "=d")
4869        (umod:SI (match_operand:SI 1 "nonimmediate_operand" "")
4870                 (match_operand:SI 2 "nonimmediate_operand" "")))
4871   (clobber (match_dup 3))]
4872  "!TARGET_64BIT && !TARGET_CPU_ZARCH"
4873{
4874  rtx insn, udiv_equal, umod_equal, equal;
4875
4876  udiv_equal = gen_rtx_UDIV (SImode, operands[1], operands[2]);
4877  umod_equal = gen_rtx_UMOD (SImode, operands[1], operands[2]);
4878  equal = gen_rtx_IOR (DImode,
4879		       gen_rtx_ASHIFT (DImode,
4880				       gen_rtx_ZERO_EXTEND (DImode, umod_equal),
4881				       GEN_INT (32)),
4882		       gen_rtx_ZERO_EXTEND (DImode, udiv_equal));
4883
4884  operands[3] = gen_reg_rtx (DImode);
4885
4886  if (CONSTANT_P (operands[2]))
4887    {
4888      if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) <= 0)
4889        {
4890          rtx label1 = gen_label_rtx ();
4891
4892          operands[1] = make_safe_from (operands[1], operands[0]);
4893	  emit_move_insn (operands[0], operands[1]);
4894          emit_insn (gen_cmpsi (operands[0], operands[2]));
4895          emit_jump_insn (gen_bltu (label1));
4896	  emit_insn (gen_abssi2 (operands[0], operands[2]));
4897          emit_insn (gen_addsi3 (operands[0], operands[0], operands[1]));
4898          emit_label (label1);
4899        }
4900      else
4901        {
4902          operands[2] = force_reg (SImode, operands[2]);
4903          operands[2] = make_safe_from (operands[2], operands[0]);
4904
4905	  emit_insn (gen_zero_extendsidi2 (operands[3], operands[1]));
4906	  insn = emit_insn (gen_divmoddisi3 (operands[3], operands[3],
4907					     operands[2]));
4908	  REG_NOTES (insn) =
4909	    gen_rtx_EXPR_LIST (REG_EQUAL, equal, REG_NOTES (insn));
4910
4911	  insn = emit_move_insn (operands[0],
4912				 gen_highpart (SImode, operands[3]));
4913	  REG_NOTES (insn) =
4914	    gen_rtx_EXPR_LIST (REG_EQUAL,
4915			       umod_equal, REG_NOTES (insn));
4916        }
4917    }
4918  else
4919    {
4920      rtx label1 = gen_label_rtx ();
4921      rtx label2 = gen_label_rtx ();
4922      rtx label3 = gen_label_rtx ();
4923
4924      operands[1] = force_reg (SImode, operands[1]);
4925      operands[1] = make_safe_from (operands[1], operands[0]);
4926      operands[2] = force_reg (SImode, operands[2]);
4927      operands[2] = make_safe_from (operands[2], operands[0]);
4928
4929      emit_move_insn(operands[0], operands[1]);
4930      emit_insn (gen_cmpsi (operands[2], operands[1]));
4931      emit_jump_insn (gen_bgtu (label3));
4932      emit_insn (gen_cmpsi (operands[2], const0_rtx));
4933      emit_jump_insn (gen_blt (label2));
4934      emit_insn (gen_cmpsi (operands[2], const1_rtx));
4935      emit_jump_insn (gen_beq (label1));
4936      emit_insn (gen_zero_extendsidi2 (operands[3], operands[1]));
4937      insn = emit_insn (gen_divmoddisi3 (operands[3], operands[3],
4938					 operands[2]));
4939      REG_NOTES (insn) =
4940      gen_rtx_EXPR_LIST (REG_EQUAL, equal, REG_NOTES (insn));
4941
4942      insn = emit_move_insn (operands[0],
4943			     gen_highpart (SImode, operands[3]));
4944      REG_NOTES (insn) =
4945      gen_rtx_EXPR_LIST (REG_EQUAL,
4946			 umod_equal, REG_NOTES (insn));
4947      emit_jump (label3);
4948      emit_label (label1);
4949      emit_move_insn (operands[0], const0_rtx);
4950      emit_jump (label3);
4951      emit_label (label2);
4952      emit_insn (gen_subsi3 (operands[0], operands[0], operands[2]));
4953      emit_label (label3);
4954    }
4955  DONE;
4956})
4957
4958;
4959; div(df|sf)3 instruction pattern(s).
4960;
4961
4962(define_expand "div<mode>3"
4963  [(set (match_operand:FPR 0 "register_operand" "=f,f")
4964        (div:FPR (match_operand:FPR 1 "register_operand" "0,0")
4965                 (match_operand:FPR 2 "general_operand" "f,<Rf>")))]
4966  "TARGET_HARD_FLOAT"
4967  "")
4968
4969; dxbr, ddbr, debr, dxb, ddb, deb
4970(define_insn "*div<mode>3"
4971  [(set (match_operand:FPR 0 "register_operand" "=f,f")
4972        (div:FPR (match_operand:FPR 1 "register_operand" "0,0")
4973                 (match_operand:FPR 2 "general_operand" "f,<Rf>")))]
4974  "TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT"
4975  "@
4976   d<xde>br\t%0,%2
4977   d<xde>b\t%0,%2"
4978  [(set_attr "op_type"  "RRE,RXE")
4979   (set_attr "type"     "fdiv<mode>")])
4980
4981; dxr, ddr, der, dx, dd, de
4982(define_insn "*div<mode>3_ibm"
4983  [(set (match_operand:FPR 0 "register_operand" "=f,f")
4984        (div:FPR (match_operand:FPR 1 "register_operand" "0,0")
4985                 (match_operand:FPR 2 "general_operand" "f,<Rf>")))]
4986  "TARGET_HARD_FLOAT && TARGET_IBM_FLOAT"
4987  "@
4988   d<xde>r\t%0,%2
4989   d<xde>\t%0,%2"
4990  [(set_attr "op_type"  "<RRe>,<RXe>")
4991   (set_attr "type"     "fdiv<mode>")])
4992
4993
4994;;
4995;;- And instructions.
4996;;
4997
4998(define_expand "and<mode>3"
4999  [(set (match_operand:INT 0 "nonimmediate_operand" "")
5000        (and:INT (match_operand:INT 1 "nonimmediate_operand" "")
5001                 (match_operand:INT 2 "general_operand" "")))
5002   (clobber (reg:CC CC_REGNUM))]
5003  ""
5004  "s390_expand_logical_operator (AND, <MODE>mode, operands); DONE;")
5005
5006;
5007; anddi3 instruction pattern(s).
5008;
5009
5010(define_insn "*anddi3_cc"
5011  [(set (reg CC_REGNUM)
5012        (compare (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
5013                         (match_operand:DI 2 "general_operand" "d,m"))
5014                 (const_int 0)))
5015   (set (match_operand:DI 0 "register_operand" "=d,d")
5016        (and:DI (match_dup 1) (match_dup 2)))]
5017  "s390_match_ccmode(insn, CCTmode) && TARGET_64BIT"
5018  "@
5019   ngr\t%0,%2
5020   ng\t%0,%2"
5021  [(set_attr "op_type"  "RRE,RXY")])
5022
5023(define_insn "*anddi3_cconly"
5024  [(set (reg CC_REGNUM)
5025        (compare (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
5026                         (match_operand:DI 2 "general_operand" "d,m"))
5027                 (const_int 0)))
5028   (clobber (match_scratch:DI 0 "=d,d"))]
5029  "s390_match_ccmode(insn, CCTmode) && TARGET_64BIT
5030   /* Do not steal TM patterns.  */
5031   && s390_single_part (operands[2], DImode, HImode, 0) < 0"
5032  "@
5033   ngr\t%0,%2
5034   ng\t%0,%2"
5035  [(set_attr "op_type"  "RRE,RXY")])
5036
5037(define_insn "*anddi3_extimm"
5038  [(set (match_operand:DI 0 "nonimmediate_operand" "=d,d,d,d,d,d,d,d,d,d,AQ,Q")
5039        (and:DI (match_operand:DI 1 "nonimmediate_operand"
5040                                    "%d,o,0,0,0,0,0,0,0,0,0,0")
5041                (match_operand:DI 2 "general_operand"
5042                                    "M,M,N0HDF,N1HDF,N2HDF,N3HDF,N0SDF,N1SDF,d,m,NxQDF,Q")))
5043   (clobber (reg:CC CC_REGNUM))]
5044  "TARGET_64BIT && TARGET_EXTIMM && s390_logical_operator_ok_p (operands)"
5045  "@
5046   #
5047   #
5048   nihh\t%0,%j2
5049   nihl\t%0,%j2
5050   nilh\t%0,%j2
5051   nill\t%0,%j2
5052   nihf\t%0,%m2
5053   nilf\t%0,%m2
5054   ngr\t%0,%2
5055   ng\t%0,%2
5056   #
5057   #"
5058  [(set_attr "op_type" "RRE,RXE,RI,RI,RI,RI,RIL,RIL,RRE,RXY,SI,SS")])
5059
5060(define_insn "*anddi3"
5061  [(set (match_operand:DI 0 "nonimmediate_operand" "=d,d,d,d,d,d,d,d,AQ,Q")
5062        (and:DI (match_operand:DI 1 "nonimmediate_operand"
5063                                    "%d,o,0,0,0,0,0,0,0,0")
5064                (match_operand:DI 2 "general_operand"
5065                                    "M,M,N0HDF,N1HDF,N2HDF,N3HDF,d,m,NxQDF,Q")))
5066   (clobber (reg:CC CC_REGNUM))]
5067  "TARGET_64BIT && !TARGET_EXTIMM && s390_logical_operator_ok_p (operands)"
5068  "@
5069   #
5070   #
5071   nihh\t%0,%j2
5072   nihl\t%0,%j2
5073   nilh\t%0,%j2
5074   nill\t%0,%j2
5075   ngr\t%0,%2
5076   ng\t%0,%2
5077   #
5078   #"
5079  [(set_attr "op_type" "RRE,RXE,RI,RI,RI,RI,RRE,RXY,SI,SS")])
5080
5081(define_split
5082  [(set (match_operand:DI 0 "s_operand" "")
5083        (and:DI (match_dup 0) (match_operand:DI 1 "immediate_operand" "")))
5084   (clobber (reg:CC CC_REGNUM))]
5085  "reload_completed"
5086  [(parallel
5087    [(set (match_dup 0) (and:QI (match_dup 0) (match_dup 1)))
5088     (clobber (reg:CC CC_REGNUM))])]
5089  "s390_narrow_logical_operator (AND, &operands[0], &operands[1]);")
5090
5091
5092;
5093; andsi3 instruction pattern(s).
5094;
5095
5096(define_insn "*andsi3_cc"
5097  [(set (reg CC_REGNUM)
5098        (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,0,0")
5099                         (match_operand:SI 2 "general_operand" "Os,d,R,T"))
5100                 (const_int 0)))
5101   (set (match_operand:SI 0 "register_operand" "=d,d,d,d")
5102        (and:SI (match_dup 1) (match_dup 2)))]
5103  "s390_match_ccmode(insn, CCTmode)"
5104  "@
5105   nilf\t%0,%o2
5106   nr\t%0,%2
5107   n\t%0,%2
5108   ny\t%0,%2"
5109  [(set_attr "op_type"  "RIL,RR,RX,RXY")])
5110
5111(define_insn "*andsi3_cconly"
5112  [(set (reg CC_REGNUM)
5113        (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,0,0")
5114                         (match_operand:SI 2 "general_operand" "Os,d,R,T"))
5115                 (const_int 0)))
5116   (clobber (match_scratch:SI 0 "=d,d,d,d"))]
5117  "s390_match_ccmode(insn, CCTmode)
5118   /* Do not steal TM patterns.  */
5119   && s390_single_part (operands[2], SImode, HImode, 0) < 0"
5120  "@
5121   nilf\t%0,%o2
5122   nr\t%0,%2
5123   n\t%0,%2
5124   ny\t%0,%2"
5125  [(set_attr "op_type"  "RIL,RR,RX,RXY")])
5126
5127(define_insn "*andsi3_zarch"
5128  [(set (match_operand:SI 0 "nonimmediate_operand" "=d,d,d,d,d,d,d,d,AQ,Q")
5129        (and:SI (match_operand:SI 1 "nonimmediate_operand"
5130				    "%d,o,0,0,0,0,0,0,0,0")
5131                (match_operand:SI 2 "general_operand"
5132				    "M,M,N0HSF,N1HSF,Os,d,R,T,NxQSF,Q")))
5133   (clobber (reg:CC CC_REGNUM))]
5134  "TARGET_ZARCH && s390_logical_operator_ok_p (operands)"
5135  "@
5136   #
5137   #
5138   nilh\t%0,%j2
5139   nill\t%0,%j2
5140   nilf\t%0,%o2
5141   nr\t%0,%2
5142   n\t%0,%2
5143   ny\t%0,%2
5144   #
5145   #"
5146  [(set_attr "op_type"  "RRE,RXE,RI,RI,RIL,RR,RX,RXY,SI,SS")])
5147
5148(define_insn "*andsi3_esa"
5149  [(set (match_operand:SI 0 "nonimmediate_operand" "=d,d,AQ,Q")
5150        (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,0,0")
5151                (match_operand:SI 2 "general_operand" "d,R,NxQSF,Q")))
5152   (clobber (reg:CC CC_REGNUM))]
5153  "!TARGET_ZARCH && s390_logical_operator_ok_p (operands)"
5154  "@
5155   nr\t%0,%2
5156   n\t%0,%2
5157   #
5158   #"
5159  [(set_attr "op_type"  "RR,RX,SI,SS")])
5160
5161(define_split
5162  [(set (match_operand:SI 0 "s_operand" "")
5163        (and:SI (match_dup 0) (match_operand:SI 1 "immediate_operand" "")))
5164   (clobber (reg:CC CC_REGNUM))]
5165  "reload_completed"
5166  [(parallel
5167    [(set (match_dup 0) (and:QI (match_dup 0) (match_dup 1)))
5168     (clobber (reg:CC CC_REGNUM))])]
5169  "s390_narrow_logical_operator (AND, &operands[0], &operands[1]);")
5170
5171;
5172; andhi3 instruction pattern(s).
5173;
5174
5175(define_insn "*andhi3_zarch"
5176  [(set (match_operand:HI 0 "nonimmediate_operand" "=d,d,AQ,Q")
5177        (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,0,0")
5178                (match_operand:HI 2 "general_operand" "d,n,NxQHF,Q")))
5179   (clobber (reg:CC CC_REGNUM))]
5180  "TARGET_ZARCH && s390_logical_operator_ok_p (operands)"
5181  "@
5182   nr\t%0,%2
5183   nill\t%0,%x2
5184   #
5185   #"
5186  [(set_attr "op_type"  "RR,RI,SI,SS")])
5187
5188(define_insn "*andhi3_esa"
5189  [(set (match_operand:HI 0 "nonimmediate_operand" "=d,AQ,Q")
5190        (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,0")
5191                (match_operand:HI 2 "general_operand" "d,NxQHF,Q")))
5192   (clobber (reg:CC CC_REGNUM))]
5193  "!TARGET_ZARCH && s390_logical_operator_ok_p (operands)"
5194  "@
5195   nr\t%0,%2
5196   #
5197   #"
5198  [(set_attr "op_type"  "RR,SI,SS")])
5199
5200(define_split
5201  [(set (match_operand:HI 0 "s_operand" "")
5202        (and:HI (match_dup 0) (match_operand:HI 1 "immediate_operand" "")))
5203   (clobber (reg:CC CC_REGNUM))]
5204  "reload_completed"
5205  [(parallel
5206    [(set (match_dup 0) (and:QI (match_dup 0) (match_dup 1)))
5207     (clobber (reg:CC CC_REGNUM))])]
5208  "s390_narrow_logical_operator (AND, &operands[0], &operands[1]);")
5209
5210;
5211; andqi3 instruction pattern(s).
5212;
5213
5214(define_insn "*andqi3_zarch"
5215  [(set (match_operand:QI 0 "nonimmediate_operand" "=d,d,Q,S,Q")
5216        (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,0,0")
5217                (match_operand:QI 2 "general_operand" "d,n,n,n,Q")))
5218   (clobber (reg:CC CC_REGNUM))]
5219  "TARGET_ZARCH && s390_logical_operator_ok_p (operands)"
5220  "@
5221   nr\t%0,%2
5222   nill\t%0,%b2
5223   ni\t%S0,%b2
5224   niy\t%S0,%b2
5225   #"
5226  [(set_attr "op_type"  "RR,RI,SI,SIY,SS")])
5227
5228(define_insn "*andqi3_esa"
5229  [(set (match_operand:QI 0 "nonimmediate_operand" "=d,Q,Q")
5230        (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
5231                (match_operand:QI 2 "general_operand" "d,n,Q")))
5232   (clobber (reg:CC CC_REGNUM))]
5233  "!TARGET_ZARCH && s390_logical_operator_ok_p (operands)"
5234  "@
5235   nr\t%0,%2
5236   ni\t%S0,%b2
5237   #"
5238  [(set_attr "op_type"  "RR,SI,SS")])
5239
5240;
5241; Block and (NC) patterns.
5242;
5243
5244(define_insn "*nc"
5245  [(set (match_operand:BLK 0 "memory_operand" "=Q")
5246        (and:BLK (match_dup 0)
5247                 (match_operand:BLK 1 "memory_operand" "Q")))
5248   (use (match_operand 2 "const_int_operand" "n"))
5249   (clobber (reg:CC CC_REGNUM))]
5250  "INTVAL (operands[2]) >= 1 && INTVAL (operands[2]) <= 256"
5251  "nc\t%O0(%2,%R0),%S1"
5252  [(set_attr "op_type" "SS")])
5253
5254(define_split
5255  [(set (match_operand 0 "memory_operand" "")
5256        (and (match_dup 0)
5257             (match_operand 1 "memory_operand" "")))
5258   (clobber (reg:CC CC_REGNUM))]
5259  "reload_completed
5260   && GET_MODE (operands[0]) == GET_MODE (operands[1])
5261   && GET_MODE_SIZE (GET_MODE (operands[0])) > 0"
5262  [(parallel
5263    [(set (match_dup 0) (and:BLK (match_dup 0) (match_dup 1)))
5264     (use (match_dup 2))
5265     (clobber (reg:CC CC_REGNUM))])]
5266{
5267  operands[2] = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[0])));
5268  operands[0] = adjust_address (operands[0], BLKmode, 0);
5269  operands[1] = adjust_address (operands[1], BLKmode, 0);
5270})
5271
5272(define_peephole2
5273  [(parallel
5274    [(set (match_operand:BLK 0 "memory_operand" "")
5275          (and:BLK (match_dup 0)
5276                   (match_operand:BLK 1 "memory_operand" "")))
5277     (use (match_operand 2 "const_int_operand" ""))
5278     (clobber (reg:CC CC_REGNUM))])
5279   (parallel
5280    [(set (match_operand:BLK 3 "memory_operand" "")
5281          (and:BLK (match_dup 3)
5282                   (match_operand:BLK 4 "memory_operand" "")))
5283     (use (match_operand 5 "const_int_operand" ""))
5284     (clobber (reg:CC CC_REGNUM))])]
5285  "s390_offset_p (operands[0], operands[3], operands[2])
5286   && s390_offset_p (operands[1], operands[4], operands[2])
5287   && !s390_overlap_p (operands[0], operands[1], 
5288                       INTVAL (operands[2]) + INTVAL (operands[5]))
5289   && INTVAL (operands[2]) + INTVAL (operands[5]) <= 256"
5290  [(parallel
5291    [(set (match_dup 6) (and:BLK (match_dup 6) (match_dup 7)))
5292     (use (match_dup 8))
5293     (clobber (reg:CC CC_REGNUM))])]
5294  "operands[6] = gen_rtx_MEM (BLKmode, XEXP (operands[0], 0));
5295   operands[7] = gen_rtx_MEM (BLKmode, XEXP (operands[1], 0));
5296   operands[8] = GEN_INT (INTVAL (operands[2]) + INTVAL (operands[5]));")
5297
5298
5299;;
5300;;- Bit set (inclusive or) instructions.
5301;;
5302
5303(define_expand "ior<mode>3"
5304  [(set (match_operand:INT 0 "nonimmediate_operand" "")
5305        (ior:INT (match_operand:INT 1 "nonimmediate_operand" "")
5306                 (match_operand:INT 2 "general_operand" "")))
5307   (clobber (reg:CC CC_REGNUM))]
5308  ""
5309  "s390_expand_logical_operator (IOR, <MODE>mode, operands); DONE;")
5310
5311;
5312; iordi3 instruction pattern(s).
5313;
5314
5315(define_insn "*iordi3_cc"
5316  [(set (reg CC_REGNUM)
5317        (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
5318                         (match_operand:DI 2 "general_operand" "d,m"))
5319                 (const_int 0)))
5320   (set (match_operand:DI 0 "register_operand" "=d,d")
5321        (ior:DI (match_dup 1) (match_dup 2)))]
5322  "s390_match_ccmode(insn, CCTmode) && TARGET_64BIT"
5323  "@
5324   ogr\t%0,%2
5325   og\t%0,%2"
5326  [(set_attr "op_type"  "RRE,RXY")])
5327
5328(define_insn "*iordi3_cconly"
5329  [(set (reg CC_REGNUM)
5330        (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
5331                         (match_operand:DI 2 "general_operand" "d,m"))
5332                 (const_int 0)))
5333   (clobber (match_scratch:DI 0 "=d,d"))]
5334  "s390_match_ccmode(insn, CCTmode) && TARGET_64BIT"
5335  "@
5336   ogr\t%0,%2
5337   og\t%0,%2"
5338  [(set_attr "op_type"  "RRE,RXY")])
5339
5340(define_insn "*iordi3_extimm"
5341  [(set (match_operand:DI 0 "nonimmediate_operand" "=d,d,d,d,d,d,d,d,AQ,Q")
5342        (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,0,0,0,0,0,0,0")
5343                (match_operand:DI 2 "general_operand"
5344                                    "N0HD0,N1HD0,N2HD0,N3HD0,N0SD0,N1SD0,d,m,NxQD0,Q")))
5345   (clobber (reg:CC CC_REGNUM))]
5346  "TARGET_64BIT && TARGET_EXTIMM && s390_logical_operator_ok_p (operands)"
5347  "@
5348   oihh\t%0,%i2
5349   oihl\t%0,%i2
5350   oilh\t%0,%i2
5351   oill\t%0,%i2
5352   oihf\t%0,%k2
5353   oilf\t%0,%k2
5354   ogr\t%0,%2
5355   og\t%0,%2
5356   #
5357   #"
5358  [(set_attr "op_type"  "RI,RI,RI,RI,RIL,RIL,RRE,RXY,SI,SS")])
5359
5360(define_insn "*iordi3"
5361  [(set (match_operand:DI 0 "nonimmediate_operand" "=d,d,d,d,d,d,AQ,Q")
5362        (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,0,0,0,0,0")
5363                (match_operand:DI 2 "general_operand"
5364                                    "N0HD0,N1HD0,N2HD0,N3HD0,d,m,NxQD0,Q")))
5365   (clobber (reg:CC CC_REGNUM))]
5366  "TARGET_64BIT && !TARGET_EXTIMM && s390_logical_operator_ok_p (operands)"
5367  "@
5368   oihh\t%0,%i2
5369   oihl\t%0,%i2
5370   oilh\t%0,%i2
5371   oill\t%0,%i2
5372   ogr\t%0,%2
5373   og\t%0,%2
5374   #
5375   #"
5376  [(set_attr "op_type"  "RI,RI,RI,RI,RRE,RXY,SI,SS")])
5377
5378(define_split
5379  [(set (match_operand:DI 0 "s_operand" "")
5380        (ior:DI (match_dup 0) (match_operand:DI 1 "immediate_operand" "")))
5381   (clobber (reg:CC CC_REGNUM))]
5382  "reload_completed"
5383  [(parallel
5384    [(set (match_dup 0) (ior:QI (match_dup 0) (match_dup 1)))
5385     (clobber (reg:CC CC_REGNUM))])]
5386  "s390_narrow_logical_operator (IOR, &operands[0], &operands[1]);")
5387
5388;
5389; iorsi3 instruction pattern(s).
5390;
5391
5392(define_insn "*iorsi3_cc"
5393  [(set (reg CC_REGNUM)
5394        (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,0,0")
5395                         (match_operand:SI 2 "general_operand" "Os,d,R,T"))
5396                 (const_int 0)))
5397   (set (match_operand:SI 0 "register_operand" "=d,d,d,d")
5398        (ior:SI (match_dup 1) (match_dup 2)))]
5399  "s390_match_ccmode(insn, CCTmode)"
5400  "@
5401   oilf\t%0,%o2
5402   or\t%0,%2
5403   o\t%0,%2
5404   oy\t%0,%2"
5405  [(set_attr "op_type"  "RIL,RR,RX,RXY")])
5406
5407(define_insn "*iorsi3_cconly"
5408  [(set (reg CC_REGNUM)
5409        (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,0,0")
5410                         (match_operand:SI 2 "general_operand" "Os,d,R,T"))
5411                 (const_int 0)))
5412   (clobber (match_scratch:SI 0 "=d,d,d,d"))]
5413  "s390_match_ccmode(insn, CCTmode)"
5414  "@
5415   oilf\t%0,%o2
5416   or\t%0,%2
5417   o\t%0,%2
5418   oy\t%0,%2"
5419  [(set_attr "op_type"  "RIL,RR,RX,RXY")])
5420
5421(define_insn "*iorsi3_zarch"
5422  [(set (match_operand:SI 0 "nonimmediate_operand" "=d,d,d,d,d,d,AQ,Q")
5423        (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,0,0,0,0,0,0")
5424                (match_operand:SI 2 "general_operand" "N0HS0,N1HS0,Os,d,R,T,NxQS0,Q")))
5425   (clobber (reg:CC CC_REGNUM))]
5426  "TARGET_ZARCH && s390_logical_operator_ok_p (operands)"
5427  "@
5428   oilh\t%0,%i2
5429   oill\t%0,%i2
5430   oilf\t%0,%o2
5431   or\t%0,%2
5432   o\t%0,%2
5433   oy\t%0,%2
5434   #
5435   #"
5436  [(set_attr "op_type"  "RI,RI,RIL,RR,RX,RXY,SI,SS")])
5437
5438(define_insn "*iorsi3_esa"
5439  [(set (match_operand:SI 0 "nonimmediate_operand" "=d,d,AQ,Q")
5440        (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,0,0")
5441                (match_operand:SI 2 "general_operand" "d,R,NxQS0,Q")))
5442   (clobber (reg:CC CC_REGNUM))]
5443  "!TARGET_ZARCH && s390_logical_operator_ok_p (operands)"
5444  "@
5445   or\t%0,%2
5446   o\t%0,%2
5447   #
5448   #"
5449  [(set_attr "op_type"  "RR,RX,SI,SS")])
5450
5451(define_split
5452  [(set (match_operand:SI 0 "s_operand" "")
5453        (ior:SI (match_dup 0) (match_operand:SI 1 "immediate_operand" "")))
5454   (clobber (reg:CC CC_REGNUM))]
5455  "reload_completed"
5456  [(parallel
5457    [(set (match_dup 0) (ior:QI (match_dup 0) (match_dup 1)))
5458     (clobber (reg:CC CC_REGNUM))])]
5459  "s390_narrow_logical_operator (IOR, &operands[0], &operands[1]);")
5460
5461;
5462; iorhi3 instruction pattern(s).
5463;
5464
5465(define_insn "*iorhi3_zarch"
5466  [(set (match_operand:HI 0 "nonimmediate_operand" "=d,d,AQ,Q")
5467        (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,0,0")
5468                (match_operand:HI 2 "general_operand" "d,n,NxQH0,Q")))
5469   (clobber (reg:CC CC_REGNUM))]
5470  "TARGET_ZARCH && s390_logical_operator_ok_p (operands)"
5471  "@
5472   or\t%0,%2
5473   oill\t%0,%x2
5474   #
5475   #"
5476  [(set_attr "op_type"  "RR,RI,SI,SS")])
5477
5478(define_insn "*iorhi3_esa"
5479  [(set (match_operand:HI 0 "nonimmediate_operand" "=d,AQ,Q")
5480        (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,0")
5481                (match_operand:HI 2 "general_operand" "d,NxQH0,Q")))
5482   (clobber (reg:CC CC_REGNUM))]
5483  "!TARGET_ZARCH && s390_logical_operator_ok_p (operands)"
5484  "@
5485   or\t%0,%2
5486   #
5487   #"
5488  [(set_attr "op_type"  "RR,SI,SS")])
5489
5490(define_split
5491  [(set (match_operand:HI 0 "s_operand" "")
5492        (ior:HI (match_dup 0) (match_operand:HI 1 "immediate_operand" "")))
5493   (clobber (reg:CC CC_REGNUM))]
5494  "reload_completed"
5495  [(parallel
5496    [(set (match_dup 0) (ior:QI (match_dup 0) (match_dup 1)))
5497     (clobber (reg:CC CC_REGNUM))])]
5498  "s390_narrow_logical_operator (IOR, &operands[0], &operands[1]);")
5499
5500;
5501; iorqi3 instruction pattern(s).
5502;
5503
5504(define_insn "*iorqi3_zarch"
5505  [(set (match_operand:QI 0 "nonimmediate_operand" "=d,d,Q,S,Q")
5506        (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,0,0")
5507                (match_operand:QI 2 "general_operand" "d,n,n,n,Q")))
5508   (clobber (reg:CC CC_REGNUM))]
5509  "TARGET_ZARCH && s390_logical_operator_ok_p (operands)"
5510  "@
5511   or\t%0,%2
5512   oill\t%0,%b2
5513   oi\t%S0,%b2
5514   oiy\t%S0,%b2
5515   #"
5516  [(set_attr "op_type"  "RR,RI,SI,SIY,SS")])
5517
5518(define_insn "*iorqi3_esa"
5519  [(set (match_operand:QI 0 "nonimmediate_operand" "=d,Q,Q")
5520        (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
5521                (match_operand:QI 2 "general_operand" "d,n,Q")))
5522   (clobber (reg:CC CC_REGNUM))]
5523  "!TARGET_ZARCH && s390_logical_operator_ok_p (operands)"
5524  "@
5525   or\t%0,%2
5526   oi\t%S0,%b2
5527   #"
5528  [(set_attr "op_type"  "RR,SI,SS")])
5529
5530;
5531; Block inclusive or (OC) patterns.
5532;
5533
5534(define_insn "*oc"
5535  [(set (match_operand:BLK 0 "memory_operand" "=Q")
5536        (ior:BLK (match_dup 0)
5537                 (match_operand:BLK 1 "memory_operand" "Q")))
5538   (use (match_operand 2 "const_int_operand" "n"))
5539   (clobber (reg:CC CC_REGNUM))]
5540  "INTVAL (operands[2]) >= 1 && INTVAL (operands[2]) <= 256"
5541  "oc\t%O0(%2,%R0),%S1"
5542  [(set_attr "op_type" "SS")])
5543
5544(define_split
5545  [(set (match_operand 0 "memory_operand" "")
5546        (ior (match_dup 0)
5547             (match_operand 1 "memory_operand" "")))
5548   (clobber (reg:CC CC_REGNUM))]
5549  "reload_completed
5550   && GET_MODE (operands[0]) == GET_MODE (operands[1])
5551   && GET_MODE_SIZE (GET_MODE (operands[0])) > 0"
5552  [(parallel
5553    [(set (match_dup 0) (ior:BLK (match_dup 0) (match_dup 1)))
5554     (use (match_dup 2))
5555     (clobber (reg:CC CC_REGNUM))])]
5556{
5557  operands[2] = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[0])));
5558  operands[0] = adjust_address (operands[0], BLKmode, 0);
5559  operands[1] = adjust_address (operands[1], BLKmode, 0);
5560})
5561
5562(define_peephole2
5563  [(parallel
5564    [(set (match_operand:BLK 0 "memory_operand" "")
5565          (ior:BLK (match_dup 0)
5566                   (match_operand:BLK 1 "memory_operand" "")))
5567     (use (match_operand 2 "const_int_operand" ""))
5568     (clobber (reg:CC CC_REGNUM))])
5569   (parallel
5570    [(set (match_operand:BLK 3 "memory_operand" "")
5571          (ior:BLK (match_dup 3)
5572                   (match_operand:BLK 4 "memory_operand" "")))
5573     (use (match_operand 5 "const_int_operand" ""))
5574     (clobber (reg:CC CC_REGNUM))])]
5575  "s390_offset_p (operands[0], operands[3], operands[2])
5576   && s390_offset_p (operands[1], operands[4], operands[2])
5577   && !s390_overlap_p (operands[0], operands[1], 
5578                       INTVAL (operands[2]) + INTVAL (operands[5]))
5579   && INTVAL (operands[2]) + INTVAL (operands[5]) <= 256"
5580  [(parallel
5581    [(set (match_dup 6) (ior:BLK (match_dup 6) (match_dup 7)))
5582     (use (match_dup 8))
5583     (clobber (reg:CC CC_REGNUM))])]
5584  "operands[6] = gen_rtx_MEM (BLKmode, XEXP (operands[0], 0));
5585   operands[7] = gen_rtx_MEM (BLKmode, XEXP (operands[1], 0));
5586   operands[8] = GEN_INT (INTVAL (operands[2]) + INTVAL (operands[5]));")
5587
5588
5589;;
5590;;- Xor instructions.
5591;;
5592
5593(define_expand "xor<mode>3"
5594  [(set (match_operand:INT 0 "nonimmediate_operand" "")
5595        (xor:INT (match_operand:INT 1 "nonimmediate_operand" "")
5596                 (match_operand:INT 2 "general_operand" "")))
5597   (clobber (reg:CC CC_REGNUM))]
5598  ""
5599  "s390_expand_logical_operator (XOR, <MODE>mode, operands); DONE;")
5600
5601;
5602; xordi3 instruction pattern(s).
5603;
5604
5605(define_insn "*xordi3_cc"
5606  [(set (reg CC_REGNUM)
5607        (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
5608                         (match_operand:DI 2 "general_operand" "d,m"))
5609                 (const_int 0)))
5610   (set (match_operand:DI 0 "register_operand" "=d,d")
5611        (xor:DI (match_dup 1) (match_dup 2)))]
5612  "s390_match_ccmode(insn, CCTmode) && TARGET_64BIT"
5613  "@
5614   xgr\t%0,%2
5615   xg\t%0,%2"
5616  [(set_attr "op_type"  "RRE,RXY")])
5617
5618(define_insn "*xordi3_cconly"
5619  [(set (reg CC_REGNUM)
5620        (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
5621                         (match_operand:DI 2 "general_operand" "d,m"))
5622                 (const_int 0)))
5623   (clobber (match_scratch:DI 0 "=d,d"))]
5624  "s390_match_ccmode(insn, CCTmode) && TARGET_64BIT"
5625  "@
5626   xgr\t%0,%2
5627   xg\t%0,%2"
5628  [(set_attr "op_type"  "RRE,RXY")])
5629
5630(define_insn "*xordi3_extimm"
5631  [(set (match_operand:DI 0 "nonimmediate_operand" "=d,d,d,d,AQ,Q")
5632        (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,0,0,0")
5633                (match_operand:DI 2 "general_operand" "N0SD0,N1SD0,d,m,NxQD0,Q")))
5634   (clobber (reg:CC CC_REGNUM))]
5635  "TARGET_64BIT && TARGET_EXTIMM && s390_logical_operator_ok_p (operands)"
5636  "@
5637   xihf\t%0,%k2
5638   xilf\t%0,%k2
5639   xgr\t%0,%2
5640   xg\t%0,%2
5641   #
5642   #"
5643  [(set_attr "op_type"  "RIL,RIL,RRE,RXY,SI,SS")])
5644
5645(define_insn "*xordi3"
5646  [(set (match_operand:DI 0 "nonimmediate_operand" "=d,d,AQ,Q")
5647        (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,0")
5648                (match_operand:DI 2 "general_operand" "d,m,NxQD0,Q")))
5649   (clobber (reg:CC CC_REGNUM))]
5650  "TARGET_64BIT && !TARGET_EXTIMM && s390_logical_operator_ok_p (operands)"
5651  "@
5652   xgr\t%0,%2
5653   xg\t%0,%2
5654   #
5655   #"
5656  [(set_attr "op_type"  "RRE,RXY,SI,SS")])
5657
5658(define_split
5659  [(set (match_operand:DI 0 "s_operand" "")
5660        (xor:DI (match_dup 0) (match_operand:DI 1 "immediate_operand" "")))
5661   (clobber (reg:CC CC_REGNUM))]
5662  "reload_completed"
5663  [(parallel
5664    [(set (match_dup 0) (xor:QI (match_dup 0) (match_dup 1)))
5665     (clobber (reg:CC CC_REGNUM))])]
5666  "s390_narrow_logical_operator (XOR, &operands[0], &operands[1]);")
5667
5668;
5669; xorsi3 instruction pattern(s).
5670;
5671
5672(define_insn "*xorsi3_cc"
5673  [(set (reg CC_REGNUM)
5674        (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,0,0")
5675                         (match_operand:SI 2 "general_operand" "Os,d,R,T"))
5676                 (const_int 0)))
5677   (set (match_operand:SI 0 "register_operand" "=d,d,d,d")
5678        (xor:SI (match_dup 1) (match_dup 2)))]
5679  "s390_match_ccmode(insn, CCTmode)"
5680  "@
5681   xilf\t%0,%o2
5682   xr\t%0,%2
5683   x\t%0,%2
5684   xy\t%0,%2"
5685  [(set_attr "op_type"  "RIL,RR,RX,RXY")])
5686
5687(define_insn "*xorsi3_cconly"
5688  [(set (reg CC_REGNUM)
5689        (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,0,0")
5690                         (match_operand:SI 2 "general_operand" "Os,d,R,T"))
5691                 (const_int 0)))
5692   (clobber (match_scratch:SI 0 "=d,d,d,d"))]
5693  "s390_match_ccmode(insn, CCTmode)"
5694  "@
5695   xilf\t%0,%o2
5696   xr\t%0,%2
5697   x\t%0,%2
5698   xy\t%0,%2"
5699  [(set_attr "op_type"  "RIL,RR,RX,RXY")])
5700
5701(define_insn "*xorsi3"
5702  [(set (match_operand:SI 0 "nonimmediate_operand" "=d,d,d,d,AQ,Q")
5703        (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,0,0,0,0")
5704                (match_operand:SI 2 "general_operand" "Os,d,R,T,NxQS0,Q")))
5705   (clobber (reg:CC CC_REGNUM))]
5706  "s390_logical_operator_ok_p (operands)"
5707  "@
5708   xilf\t%0,%o2
5709   xr\t%0,%2
5710   x\t%0,%2
5711   xy\t%0,%2
5712   #
5713   #"
5714  [(set_attr "op_type"  "RIL,RR,RX,RXY,SI,SS")])
5715
5716(define_split
5717  [(set (match_operand:SI 0 "s_operand" "")
5718        (xor:SI (match_dup 0) (match_operand:SI 1 "immediate_operand" "")))
5719   (clobber (reg:CC CC_REGNUM))]
5720  "reload_completed"
5721  [(parallel
5722    [(set (match_dup 0) (xor:QI (match_dup 0) (match_dup 1)))
5723     (clobber (reg:CC CC_REGNUM))])]
5724  "s390_narrow_logical_operator (XOR, &operands[0], &operands[1]);")
5725
5726;
5727; xorhi3 instruction pattern(s).
5728;
5729
5730(define_insn "*xorhi3"
5731  [(set (match_operand:HI 0 "nonimmediate_operand" "=d,d,AQ,Q")
5732        (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,0,0")
5733                (match_operand:HI 2 "general_operand" "Os,d,NxQH0,Q")))
5734   (clobber (reg:CC CC_REGNUM))]
5735  "s390_logical_operator_ok_p (operands)"
5736  "@
5737   xilf\t%0,%x2
5738   xr\t%0,%2
5739   #
5740   #"
5741  [(set_attr "op_type"  "RIL,RR,SI,SS")])
5742
5743(define_split
5744  [(set (match_operand:HI 0 "s_operand" "")
5745        (xor:HI (match_dup 0) (match_operand:HI 1 "immediate_operand" "")))
5746   (clobber (reg:CC CC_REGNUM))]
5747  "reload_completed"
5748  [(parallel
5749    [(set (match_dup 0) (xor:QI (match_dup 0) (match_dup 1)))
5750     (clobber (reg:CC CC_REGNUM))])]
5751  "s390_narrow_logical_operator (XOR, &operands[0], &operands[1]);")
5752
5753;
5754; xorqi3 instruction pattern(s).
5755;
5756
5757(define_insn "*xorqi3"
5758  [(set (match_operand:QI 0 "nonimmediate_operand" "=d,d,Q,S,Q")
5759        (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,0,0")
5760                (match_operand:QI 2 "general_operand" "Os,d,n,n,Q")))
5761   (clobber (reg:CC CC_REGNUM))]
5762  "s390_logical_operator_ok_p (operands)"
5763  "@
5764   xilf\t%0,%b2
5765   xr\t%0,%2
5766   xi\t%S0,%b2
5767   xiy\t%S0,%b2
5768   #"
5769  [(set_attr "op_type"  "RIL,RR,SI,SIY,SS")])
5770
5771;
5772; Block exclusive or (XC) patterns.
5773;
5774
5775(define_insn "*xc"
5776  [(set (match_operand:BLK 0 "memory_operand" "=Q")
5777        (xor:BLK (match_dup 0)
5778                 (match_operand:BLK 1 "memory_operand" "Q")))
5779   (use (match_operand 2 "const_int_operand" "n"))
5780   (clobber (reg:CC CC_REGNUM))]
5781  "INTVAL (operands[2]) >= 1 && INTVAL (operands[2]) <= 256"
5782  "xc\t%O0(%2,%R0),%S1"
5783  [(set_attr "op_type" "SS")])
5784
5785(define_split
5786  [(set (match_operand 0 "memory_operand" "")
5787        (xor (match_dup 0)
5788             (match_operand 1 "memory_operand" "")))
5789   (clobber (reg:CC CC_REGNUM))]
5790  "reload_completed
5791   && GET_MODE (operands[0]) == GET_MODE (operands[1])
5792   && GET_MODE_SIZE (GET_MODE (operands[0])) > 0"
5793  [(parallel
5794    [(set (match_dup 0) (xor:BLK (match_dup 0) (match_dup 1)))
5795     (use (match_dup 2))
5796     (clobber (reg:CC CC_REGNUM))])]
5797{
5798  operands[2] = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[0])));
5799  operands[0] = adjust_address (operands[0], BLKmode, 0);
5800  operands[1] = adjust_address (operands[1], BLKmode, 0);
5801})
5802
5803(define_peephole2
5804  [(parallel
5805    [(set (match_operand:BLK 0 "memory_operand" "")
5806          (xor:BLK (match_dup 0)
5807                   (match_operand:BLK 1 "memory_operand" "")))
5808     (use (match_operand 2 "const_int_operand" ""))
5809     (clobber (reg:CC CC_REGNUM))])
5810   (parallel
5811    [(set (match_operand:BLK 3 "memory_operand" "")
5812          (xor:BLK (match_dup 3)
5813                   (match_operand:BLK 4 "memory_operand" "")))
5814     (use (match_operand 5 "const_int_operand" ""))
5815     (clobber (reg:CC CC_REGNUM))])]
5816  "s390_offset_p (operands[0], operands[3], operands[2])
5817   && s390_offset_p (operands[1], operands[4], operands[2])
5818   && !s390_overlap_p (operands[0], operands[1], 
5819                       INTVAL (operands[2]) + INTVAL (operands[5]))
5820   && INTVAL (operands[2]) + INTVAL (operands[5]) <= 256"
5821  [(parallel
5822    [(set (match_dup 6) (xor:BLK (match_dup 6) (match_dup 7)))
5823     (use (match_dup 8))
5824     (clobber (reg:CC CC_REGNUM))])]
5825  "operands[6] = gen_rtx_MEM (BLKmode, XEXP (operands[0], 0));
5826   operands[7] = gen_rtx_MEM (BLKmode, XEXP (operands[1], 0));
5827   operands[8] = GEN_INT (INTVAL (operands[2]) + INTVAL (operands[5]));")
5828
5829;
5830; Block xor (XC) patterns with src == dest.
5831;
5832
5833(define_insn "*xc_zero"
5834  [(set (match_operand:BLK 0 "memory_operand" "=Q")
5835        (const_int 0))
5836   (use (match_operand 1 "const_int_operand" "n"))
5837   (clobber (reg:CC CC_REGNUM))]
5838  "INTVAL (operands[1]) >= 1 && INTVAL (operands[1]) <= 256"
5839  "xc\t%O0(%1,%R0),%S0"
5840  [(set_attr "op_type" "SS")])
5841
5842(define_peephole2
5843  [(parallel
5844    [(set (match_operand:BLK 0 "memory_operand" "")
5845          (const_int 0))
5846     (use (match_operand 1 "const_int_operand" ""))
5847     (clobber (reg:CC CC_REGNUM))])
5848   (parallel
5849    [(set (match_operand:BLK 2 "memory_operand" "")
5850          (const_int 0))
5851     (use (match_operand 3 "const_int_operand" ""))
5852     (clobber (reg:CC CC_REGNUM))])]
5853  "s390_offset_p (operands[0], operands[2], operands[1])
5854   && INTVAL (operands[1]) + INTVAL (operands[3]) <= 256"
5855  [(parallel
5856    [(set (match_dup 4) (const_int 0))
5857     (use (match_dup 5))
5858     (clobber (reg:CC CC_REGNUM))])]
5859  "operands[4] = gen_rtx_MEM (BLKmode, XEXP (operands[0], 0));
5860   operands[5] = GEN_INT (INTVAL (operands[1]) + INTVAL (operands[3]));")
5861
5862
5863;;
5864;;- Negate instructions.
5865;;
5866
5867;
5868; neg(di|si)2 instruction pattern(s).
5869;
5870
5871(define_expand "neg<mode>2"
5872  [(parallel
5873    [(set (match_operand:DSI 0 "register_operand" "=d")
5874          (neg:DSI (match_operand:DSI 1 "register_operand" "d")))
5875     (clobber (reg:CC CC_REGNUM))])]
5876  ""
5877  "")
5878
5879(define_insn "*negdi2_sign_cc"
5880  [(set (reg CC_REGNUM)
5881        (compare (neg:DI (ashiftrt:DI (ashift:DI (subreg:DI
5882                           (match_operand:SI 1 "register_operand" "d") 0)
5883                           (const_int 32)) (const_int 32)))
5884                 (const_int 0)))
5885   (set (match_operand:DI 0 "register_operand" "=d")
5886        (neg:DI (sign_extend:DI (match_dup 1))))]
5887  "TARGET_64BIT && s390_match_ccmode (insn, CCAmode)"
5888  "lcgfr\t%0,%1"
5889  [(set_attr "op_type"  "RRE")])
5890  
5891(define_insn "*negdi2_sign"
5892  [(set (match_operand:DI 0 "register_operand" "=d")
5893        (neg:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "d"))))
5894   (clobber (reg:CC CC_REGNUM))]
5895  "TARGET_64BIT"
5896  "lcgfr\t%0,%1"
5897  [(set_attr "op_type"  "RRE")])
5898
5899; lcr, lcgr
5900(define_insn "*neg<mode>2_cc"
5901  [(set (reg CC_REGNUM)
5902        (compare (neg:GPR (match_operand:GPR 1 "register_operand" "d"))
5903                 (const_int 0)))
5904   (set (match_operand:GPR 0 "register_operand" "=d")
5905        (neg:GPR (match_dup 1)))]
5906  "s390_match_ccmode (insn, CCAmode)"
5907  "lc<g>r\t%0,%1"
5908  [(set_attr "op_type"  "RR<E>")])
5909
5910; lcr, lcgr
5911(define_insn "*neg<mode>2_cconly"
5912  [(set (reg CC_REGNUM)
5913        (compare (neg:GPR (match_operand:GPR 1 "register_operand" "d"))
5914                 (const_int 0)))
5915   (clobber (match_scratch:GPR 0 "=d"))]
5916  "s390_match_ccmode (insn, CCAmode)"
5917  "lc<g>r\t%0,%1"
5918  [(set_attr "op_type"  "RR<E>")])
5919
5920; lcr, lcgr
5921(define_insn "*neg<mode>2"
5922  [(set (match_operand:GPR 0 "register_operand" "=d")
5923        (neg:GPR (match_operand:GPR 1 "register_operand" "d")))
5924   (clobber (reg:CC CC_REGNUM))]
5925  ""
5926  "lc<g>r\t%0,%1"
5927  [(set_attr "op_type"  "RR<E>")])
5928
5929(define_insn_and_split "*negdi2_31"
5930  [(set (match_operand:DI 0 "register_operand" "=d")
5931        (neg:DI (match_operand:DI 1 "register_operand" "d")))
5932   (clobber (reg:CC CC_REGNUM))]
5933  "!TARGET_64BIT"
5934  "#"
5935  "&& reload_completed"
5936  [(parallel
5937    [(set (match_dup 2) (neg:SI (match_dup 3)))
5938     (clobber (reg:CC CC_REGNUM))])
5939   (parallel
5940    [(set (reg:CCAP CC_REGNUM)
5941          (compare:CCAP (neg:SI (match_dup 5)) (const_int 0)))
5942     (set (match_dup 4) (neg:SI (match_dup 5)))])
5943   (set (pc)
5944        (if_then_else (ne (reg:CCAP CC_REGNUM) (const_int 0))
5945                      (pc)
5946                      (label_ref (match_dup 6))))
5947   (parallel
5948    [(set (match_dup 2) (plus:SI (match_dup 2) (const_int -1)))
5949     (clobber (reg:CC CC_REGNUM))])
5950   (match_dup 6)]
5951  "operands[2] = operand_subword (operands[0], 0, 0, DImode);
5952   operands[3] = operand_subword (operands[1], 0, 0, DImode);
5953   operands[4] = operand_subword (operands[0], 1, 0, DImode);
5954   operands[5] = operand_subword (operands[1], 1, 0, DImode);
5955   operands[6] = gen_label_rtx ();")
5956
5957;
5958; neg(df|sf)2 instruction pattern(s).
5959;
5960
5961(define_expand "neg<mode>2"
5962  [(parallel
5963    [(set (match_operand:FPR 0 "register_operand" "=f")
5964          (neg:FPR (match_operand:FPR 1 "register_operand" "f")))
5965     (clobber (reg:CC CC_REGNUM))])]
5966  "TARGET_HARD_FLOAT"
5967  "")
5968
5969; lcxbr, lcdbr, lcebr
5970(define_insn "*neg<mode>2_cc"
5971  [(set (reg CC_REGNUM)
5972        (compare (neg:FPR (match_operand:FPR 1 "register_operand" "f"))
5973                 (match_operand:FPR 2 "const0_operand" "")))
5974   (set (match_operand:FPR 0 "register_operand" "=f")
5975        (neg:FPR (match_dup 1)))]
5976  "s390_match_ccmode (insn, CCSmode) && TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT"
5977  "lc<xde>br\t%0,%1"
5978  [(set_attr "op_type"  "RRE")
5979   (set_attr "type"     "fsimp<mode>")])
5980
5981; lcxbr, lcdbr, lcebr
5982(define_insn "*neg<mode>2_cconly"
5983  [(set (reg CC_REGNUM)
5984        (compare (neg:FPR (match_operand:FPR 1 "register_operand" "f"))
5985                 (match_operand:FPR 2 "const0_operand" "")))
5986   (clobber (match_scratch:FPR 0 "=f"))]
5987  "s390_match_ccmode (insn, CCSmode) && TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT"
5988  "lc<xde>br\t%0,%1"
5989  [(set_attr "op_type"  "RRE")
5990   (set_attr "type"     "fsimp<mode>")])
5991
5992; lcxbr, lcdbr, lcebr
5993(define_insn "*neg<mode>2"
5994  [(set (match_operand:FPR 0 "register_operand" "=f")
5995        (neg:FPR (match_operand:FPR 1 "register_operand" "f")))
5996   (clobber (reg:CC CC_REGNUM))]
5997  "TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT"
5998  "lc<xde>br\t%0,%1"
5999  [(set_attr "op_type"  "RRE")
6000   (set_attr "type"     "fsimp<mode>")])
6001
6002; lcxr, lcdr, lcer
6003(define_insn "*neg<mode>2_ibm"
6004  [(set (match_operand:FPR 0 "register_operand" "=f")
6005        (neg:FPR (match_operand:FPR 1 "register_operand" "f")))
6006   (clobber (reg:CC CC_REGNUM))]
6007  "TARGET_HARD_FLOAT && TARGET_IBM_FLOAT"
6008  "lc<xde>r\t%0,%1"
6009  [(set_attr "op_type"  "<RRe>")
6010   (set_attr "type"     "fsimp<mode>")])
6011
6012
6013;;
6014;;- Absolute value instructions.
6015;;
6016
6017;
6018; abs(di|si)2 instruction pattern(s).
6019;
6020
6021(define_insn "*absdi2_sign_cc"
6022  [(set (reg CC_REGNUM)
6023        (compare (abs:DI (ashiftrt:DI (ashift:DI (subreg:DI
6024                           (match_operand:SI 1 "register_operand" "d") 0)
6025                           (const_int 32)) (const_int 32)))
6026                 (const_int 0)))
6027   (set (match_operand:DI 0 "register_operand" "=d")
6028        (abs:DI (sign_extend:DI (match_dup 1))))]
6029  "TARGET_64BIT && s390_match_ccmode (insn, CCAmode)"
6030  "lpgfr\t%0,%1"
6031  [(set_attr "op_type"  "RRE")])
6032
6033(define_insn "*absdi2_sign"
6034  [(set (match_operand:DI 0 "register_operand" "=d")
6035        (abs:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "d"))))
6036   (clobber (reg:CC CC_REGNUM))]
6037  "TARGET_64BIT"
6038  "lpgfr\t%0,%1"
6039  [(set_attr "op_type"  "RRE")])
6040
6041; lpr, lpgr
6042(define_insn "*abs<mode>2_cc"
6043  [(set (reg CC_REGNUM)
6044        (compare (abs:GPR (match_operand:DI 1 "register_operand" "d"))
6045                 (const_int 0)))
6046   (set (match_operand:GPR 0 "register_operand" "=d")
6047        (abs:GPR (match_dup 1)))]
6048  "s390_match_ccmode (insn, CCAmode)"
6049  "lp<g>r\t%0,%1"
6050  [(set_attr "op_type"  "RR<E>")])
6051
6052; lpr, lpgr  
6053(define_insn "*abs<mode>2_cconly"
6054  [(set (reg CC_REGNUM)
6055        (compare (abs:GPR (match_operand:GPR 1 "register_operand" "d"))
6056                 (const_int 0)))
6057   (clobber (match_scratch:GPR 0 "=d"))]
6058  "s390_match_ccmode (insn, CCAmode)"
6059  "lp<g>r\t%0,%1"
6060  [(set_attr "op_type"  "RR<E>")])
6061
6062; lpr, lpgr
6063(define_insn "abs<mode>2"
6064  [(set (match_operand:GPR 0 "register_operand" "=d")
6065        (abs:GPR (match_operand:GPR 1 "register_operand" "d")))
6066   (clobber (reg:CC CC_REGNUM))]
6067  ""
6068  "lp<g>r\t%0,%1"
6069  [(set_attr "op_type"  "RR<E>")])
6070
6071;
6072; abs(df|sf)2 instruction pattern(s).
6073;
6074
6075(define_expand "abs<mode>2"
6076  [(parallel
6077    [(set (match_operand:FPR 0 "register_operand" "=f")
6078          (abs:FPR (match_operand:FPR 1 "register_operand" "f")))
6079     (clobber (reg:CC CC_REGNUM))])]
6080  "TARGET_HARD_FLOAT"
6081  "")
6082
6083; lpxbr, lpdbr, lpebr
6084(define_insn "*abs<mode>2_cc"
6085  [(set (reg CC_REGNUM)
6086        (compare (abs:FPR (match_operand:FPR 1 "register_operand" "f"))
6087                 (match_operand:FPR 2 "const0_operand" "")))
6088   (set (match_operand:FPR 0 "register_operand" "=f")
6089        (abs:FPR (match_dup 1)))]
6090  "s390_match_ccmode (insn, CCSmode) && TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT"
6091  "lp<xde>br\t%0,%1"
6092  [(set_attr "op_type"  "RRE")
6093   (set_attr "type"     "fsimp<mode>")])
6094
6095; lpxbr, lpdbr, lpebr
6096(define_insn "*abs<mode>2_cconly"
6097  [(set (reg CC_REGNUM)
6098        (compare (abs:FPR (match_operand:FPR 1 "register_operand" "f"))
6099                 (match_operand:FPR 2 "const0_operand" "")))
6100   (clobber (match_scratch:FPR 0 "=f"))]
6101  "s390_match_ccmode (insn, CCSmode) && TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT"
6102  "lp<xde>br\t%0,%1"
6103  [(set_attr "op_type"  "RRE")
6104   (set_attr "type"     "fsimp<mode>")])
6105
6106; lpxbr, lpdbr, lpebr
6107(define_insn "*abs<mode>2"
6108  [(set (match_operand:FPR 0 "register_operand" "=f")
6109        (abs:FPR (match_operand:FPR 1 "register_operand" "f")))
6110   (clobber (reg:CC CC_REGNUM))]
6111  "TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT"
6112  "lp<xde>br\t%0,%1"
6113  [(set_attr "op_type"  "RRE")
6114   (set_attr "type"     "fsimp<mode>")])
6115
6116; lpxr, lpdr, lper
6117(define_insn "*abs<mode>2_ibm"
6118  [(set (match_operand:FPR 0 "register_operand" "=f")
6119        (abs:FPR (match_operand:FPR 1 "register_operand" "f")))
6120   (clobber (reg:CC CC_REGNUM))]
6121  "TARGET_HARD_FLOAT && TARGET_IBM_FLOAT"
6122  "lp<xde>r\t%0,%1"
6123  [(set_attr "op_type"  "<RRe>")
6124   (set_attr "type"     "fsimp<mode>")])
6125
6126;;
6127;;- Negated absolute value instructions
6128;;
6129
6130;
6131; Integer
6132;
6133
6134(define_insn "*negabsdi2_sign_cc"
6135  [(set (reg CC_REGNUM)
6136        (compare (neg:DI (abs:DI (ashiftrt:DI (ashift:DI (subreg:DI
6137                           (match_operand:SI 1 "register_operand" "d") 0)
6138                           (const_int 32)) (const_int 32))))
6139                 (const_int 0)))
6140   (set (match_operand:DI 0 "register_operand" "=d")
6141        (neg:DI (abs:DI (sign_extend:DI (match_dup 1)))))]
6142  "TARGET_64BIT && s390_match_ccmode (insn, CCAmode)"
6143  "lngfr\t%0,%1"
6144  [(set_attr "op_type"  "RRE")])
6145 
6146(define_insn "*negabsdi2_sign"
6147  [(set (match_operand:DI 0 "register_operand" "=d")
6148	(neg:DI (abs:DI (sign_extend:DI
6149                          (match_operand:SI 1 "register_operand" "d")))))
6150   (clobber (reg:CC CC_REGNUM))]
6151  "TARGET_64BIT"
6152  "lngfr\t%0,%1"
6153  [(set_attr "op_type" "RRE")])
6154
6155; lnr, lngr
6156(define_insn "*negabs<mode>2_cc"
6157  [(set (reg CC_REGNUM)
6158        (compare (neg:GPR (abs:GPR (match_operand:GPR 1 "register_operand" "d")))
6159                 (const_int 0)))
6160   (set (match_operand:GPR 0 "register_operand" "=d")
6161        (neg:GPR (abs:GPR (match_dup 1))))]
6162  "s390_match_ccmode (insn, CCAmode)"
6163  "ln<g>r\t%0,%1"
6164  [(set_attr "op_type"  "RR<E>")])
6165
6166; lnr, lngr
6167(define_insn "*negabs<mode>2_cconly"
6168  [(set (reg CC_REGNUM)
6169        (compare (neg:GPR (abs:GPR (match_operand:GPR 1 "register_operand" "d")))
6170                 (const_int 0)))
6171   (clobber (match_scratch:GPR 0 "=d"))]
6172  "s390_match_ccmode (insn, CCAmode)"
6173  "ln<g>r\t%0,%1"
6174  [(set_attr "op_type"  "RR<E>")])
6175
6176; lnr, lngr
6177(define_insn "*negabs<mode>2"
6178  [(set (match_operand:GPR 0 "register_operand" "=d")
6179	(neg:GPR (abs:GPR (match_operand:GPR 1 "register_operand" "d"))))
6180   (clobber (reg:CC CC_REGNUM))]
6181  ""
6182  "ln<g>r\t%0,%1"
6183  [(set_attr "op_type" "RR<E>")])
6184
6185;
6186; Floating point
6187;
6188
6189; lnxbr, lndbr, lnebr
6190(define_insn "*negabs<mode>2_cc"
6191  [(set (reg CC_REGNUM)
6192        (compare (neg:FPR (abs:FPR (match_operand:FPR 1 "register_operand" "f")))
6193                 (match_operand:FPR 2 "const0_operand" "")))
6194   (set (match_operand:FPR 0 "register_operand" "=f")
6195        (neg:FPR (abs:FPR (match_dup 1))))]
6196  "s390_match_ccmode (insn, CCSmode) && TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT"
6197  "ln<xde>br\t%0,%1"
6198  [(set_attr "op_type"  "RRE")
6199   (set_attr "type"     "fsimp<mode>")])
6200
6201; lnxbr, lndbr, lnebr
6202(define_insn "*negabs<mode>2_cconly"
6203  [(set (reg CC_REGNUM)
6204        (compare (neg:FPR (abs:FPR (match_operand:FPR 1 "register_operand" "f")))
6205                 (match_operand:FPR 2 "const0_operand" "")))
6206   (clobber (match_scratch:FPR 0 "=f"))]
6207  "s390_match_ccmode (insn, CCSmode) && TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT"
6208  "ln<xde>br\t%0,%1"
6209  [(set_attr "op_type"  "RRE")
6210   (set_attr "type"     "fsimp<mode>")])
6211
6212; lnxbr, lndbr, lnebr
6213(define_insn "*negabs<mode>2"
6214  [(set (match_operand:FPR 0 "register_operand" "=f")
6215        (neg:FPR (abs:FPR (match_operand:FPR 1 "register_operand" "f"))))
6216   (clobber (reg:CC CC_REGNUM))]
6217  "TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT"
6218  "ln<xde>br\t%0,%1"
6219  [(set_attr "op_type"  "RRE")
6220   (set_attr "type"     "fsimp<mode>")])
6221
6222;;
6223;;- Square root instructions.
6224;;
6225
6226;
6227; sqrt(df|sf)2 instruction pattern(s).
6228;
6229
6230; sqxbr, sqdbr, sqebr, sqxb, sqdb, sqeb
6231(define_insn "sqrt<mode>2"
6232  [(set (match_operand:FPR 0 "register_operand" "=f,f")
6233	(sqrt:FPR (match_operand:FPR 1 "general_operand" "f,<Rf>")))]
6234  "TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT"
6235  "@
6236   sq<xde>br\t%0,%1
6237   sq<xde>b\t%0,%1"
6238  [(set_attr "op_type" "RRE,RXE")
6239   (set_attr "type" "fsqrt<mode>")])
6240
6241
6242;;
6243;;- One complement instructions.
6244;;
6245
6246;
6247; one_cmpl(di|si|hi|qi)2 instruction pattern(s).
6248;
6249
6250(define_expand "one_cmpl<mode>2"
6251  [(parallel
6252    [(set (match_operand:INT 0 "register_operand" "")
6253          (xor:INT (match_operand:INT 1 "register_operand" "")
6254		   (const_int -1)))
6255     (clobber (reg:CC CC_REGNUM))])]
6256  ""
6257  "")
6258
6259
6260;;
6261;; Find leftmost bit instructions.
6262;;
6263
6264(define_expand "clzdi2"
6265  [(set (match_operand:DI 0 "register_operand" "=d")
6266	(clz:DI (match_operand:DI 1 "register_operand" "d")))]
6267  "TARGET_EXTIMM && TARGET_64BIT"
6268{
6269  rtx insn, clz_equal;
6270  rtx wide_reg = gen_reg_rtx (TImode);
6271  rtx msb = gen_rtx_CONST_INT (DImode, (unsigned HOST_WIDE_INT) 1 << 63);
6272
6273  clz_equal = gen_rtx_CLZ (DImode, operands[1]);
6274
6275  emit_insn (gen_clztidi2 (wide_reg, operands[1], msb));
6276
6277  insn = emit_move_insn (operands[0], gen_highpart (DImode, wide_reg));  
6278  REG_NOTES (insn) =
6279        gen_rtx_EXPR_LIST (REG_EQUAL, clz_equal, REG_NOTES (insn));
6280
6281  DONE;
6282})
6283
6284(define_insn "clztidi2"
6285  [(set (match_operand:TI 0 "register_operand" "=d")
6286	(ior:TI
6287	  (ashift:TI 
6288            (zero_extend:TI 
6289   	      (xor:DI (match_operand:DI 1 "register_operand" "d")
6290                      (lshiftrt (match_operand:DI 2 "const_int_operand" "")
6291				(subreg:SI (clz:DI (match_dup 1)) 4))))
6292	    
6293	    (const_int 64))
6294          (zero_extend:TI (clz:DI (match_dup 1)))))
6295   (clobber (reg:CC CC_REGNUM))]
6296  "(unsigned HOST_WIDE_INT) INTVAL (operands[2]) 
6297   == (unsigned HOST_WIDE_INT) 1 << 63
6298   && TARGET_EXTIMM && TARGET_64BIT"
6299  "flogr\t%0,%1"
6300  [(set_attr "op_type"  "RRE")])
6301
6302
6303;;
6304;;- Rotate instructions.
6305;;
6306
6307;
6308; rotl(di|si)3 instruction pattern(s).
6309;
6310
6311; rll, rllg
6312(define_insn "rotl<mode>3"
6313  [(set (match_operand:GPR 0 "register_operand" "=d")
6314	(rotate:GPR (match_operand:GPR 1 "register_operand" "d")
6315		    (match_operand:SI 2 "shift_count_or_setmem_operand" "Y")))]
6316  "TARGET_CPU_ZARCH"
6317  "rll<g>\t%0,%1,%Y2"
6318  [(set_attr "op_type"  "RSE")
6319   (set_attr "atype"    "reg")])
6320
6321; rll, rllg
6322(define_insn "*rotl<mode>3_and"
6323  [(set (match_operand:GPR 0 "register_operand" "=d")
6324	(rotate:GPR (match_operand:GPR 1 "register_operand" "d")
6325		    (and:SI (match_operand:SI 2 "shift_count_or_setmem_operand" "Y")
6326			    (match_operand:SI 3 "const_int_operand"   "n"))))]
6327  "TARGET_CPU_ZARCH && (INTVAL (operands[3]) & 63) == 63"
6328  "rll<g>\t%0,%1,%Y2"
6329  [(set_attr "op_type"  "RSE")
6330   (set_attr "atype"    "reg")])
6331
6332
6333;;
6334;;- Shift instructions.
6335;;
6336
6337;
6338; (ashl|lshr)(di|si)3 instruction pattern(s).
6339;
6340
6341(define_expand "<shift><mode>3"
6342  [(set (match_operand:DSI 0 "register_operand" "")
6343        (SHIFT:DSI (match_operand:DSI 1 "register_operand" "")
6344                   (match_operand:SI 2 "shift_count_or_setmem_operand" "")))]
6345  ""
6346  "")
6347
6348; sldl, srdl
6349(define_insn "*<shift>di3_31"
6350  [(set (match_operand:DI 0 "register_operand" "=d")
6351        (SHIFT:DI (match_operand:DI 1 "register_operand" "0")
6352                  (match_operand:SI 2 "shift_count_or_setmem_operand" "Y")))]
6353  "!TARGET_64BIT"
6354  "s<lr>dl\t%0,%Y2"
6355  [(set_attr "op_type"  "RS")
6356   (set_attr "atype"    "reg")])
6357
6358; sll, srl, sllg, srlg
6359(define_insn "*<shift><mode>3"
6360  [(set (match_operand:GPR 0 "register_operand" "=d")
6361        (SHIFT:GPR (match_operand:GPR 1 "register_operand" "<d0>")
6362                   (match_operand:SI 2 "shift_count_or_setmem_operand" "Y")))]
6363  ""
6364  "s<lr>l<g>\t%0,<1>%Y2"
6365  [(set_attr "op_type"  "RS<E>")
6366   (set_attr "atype"    "reg")])
6367
6368; sldl, srdl
6369(define_insn "*<shift>di3_31_and"
6370  [(set (match_operand:DI 0 "register_operand" "=d")
6371        (SHIFT:DI (match_operand:DI 1 "register_operand" "0")
6372                  (and:SI (match_operand:SI 2 "shift_count_or_setmem_operand" "Y")
6373			  (match_operand:SI 3 "const_int_operand"   "n"))))]
6374  "!TARGET_64BIT && (INTVAL (operands[3]) & 63) == 63"
6375  "s<lr>dl\t%0,%Y2"
6376  [(set_attr "op_type"  "RS")
6377   (set_attr "atype"    "reg")])
6378
6379; sll, srl, sllg, srlg
6380(define_insn "*<shift><mode>3_and"
6381  [(set (match_operand:GPR 0 "register_operand" "=d")
6382        (SHIFT:GPR (match_operand:GPR 1 "register_operand" "<d0>")
6383                   (and:SI (match_operand:SI 2 "shift_count_or_setmem_operand" "Y")
6384			   (match_operand:SI 3 "const_int_operand"   "n"))))]
6385  "(INTVAL (operands[3]) & 63) == 63"
6386  "s<lr>l<g>\t%0,<1>%Y2"
6387  [(set_attr "op_type"  "RS<E>")
6388   (set_attr "atype"    "reg")])
6389
6390;
6391; ashr(di|si)3 instruction pattern(s).
6392;
6393
6394(define_expand "ashr<mode>3"
6395  [(parallel
6396    [(set (match_operand:DSI 0 "register_operand" "")
6397          (ashiftrt:DSI (match_operand:DSI 1 "register_operand" "")
6398                        (match_operand:SI 2 "shift_count_or_setmem_operand" "")))
6399     (clobber (reg:CC CC_REGNUM))])]
6400  ""
6401  "")
6402
6403(define_insn "*ashrdi3_cc_31"
6404  [(set (reg CC_REGNUM)
6405        (compare (ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
6406                              (match_operand:SI 2 "shift_count_or_setmem_operand" "Y"))
6407                 (const_int 0)))
6408   (set (match_operand:DI 0 "register_operand" "=d")
6409        (ashiftrt:DI (match_dup 1) (match_dup 2)))]
6410  "!TARGET_64BIT && s390_match_ccmode(insn, CCSmode)"
6411  "srda\t%0,%Y2"
6412  [(set_attr "op_type"  "RS")
6413   (set_attr "atype"    "reg")])
6414
6415(define_insn "*ashrdi3_cconly_31"
6416  [(set (reg CC_REGNUM)
6417        (compare (ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
6418                              (match_operand:SI 2 "shift_count_or_setmem_operand" "Y"))
6419                 (const_int 0)))
6420   (clobber (match_scratch:DI 0 "=d"))]
6421  "!TARGET_64BIT && s390_match_ccmode(insn, CCSmode)"
6422  "srda\t%0,%Y2"
6423  [(set_attr "op_type"  "RS")
6424   (set_attr "atype"    "reg")])
6425
6426(define_insn "*ashrdi3_31"
6427  [(set (match_operand:DI 0 "register_operand" "=d")
6428        (ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
6429                     (match_operand:SI 2 "shift_count_or_setmem_operand" "Y")))
6430   (clobber (reg:CC CC_REGNUM))]
6431  "!TARGET_64BIT"
6432  "srda\t%0,%Y2"
6433  [(set_attr "op_type"  "RS")
6434   (set_attr "atype"    "reg")])
6435
6436; sra, srag
6437(define_insn "*ashr<mode>3_cc"
6438  [(set (reg CC_REGNUM)
6439        (compare (ashiftrt:GPR (match_operand:GPR 1 "register_operand" "<d0>")
6440                               (match_operand:SI 2 "shift_count_or_setmem_operand" "Y"))
6441                 (const_int 0)))
6442   (set (match_operand:GPR 0 "register_operand" "=d")
6443        (ashiftrt:GPR (match_dup 1) (match_dup 2)))]
6444  "s390_match_ccmode(insn, CCSmode)"
6445  "sra<g>\t%0,<1>%Y2"
6446  [(set_attr "op_type"  "RS<E>")
6447   (set_attr "atype"    "reg")])
6448
6449; sra, srag
6450(define_insn "*ashr<mode>3_cconly"
6451  [(set (reg CC_REGNUM)
6452        (compare (ashiftrt:GPR (match_operand:GPR 1 "register_operand" "<d0>")
6453                               (match_operand:SI 2 "shift_count_or_setmem_operand" "Y"))
6454                 (const_int 0)))
6455   (clobber (match_scratch:GPR 0 "=d"))]
6456  "s390_match_ccmode(insn, CCSmode)"
6457  "sra<g>\t%0,<1>%Y2"
6458  [(set_attr "op_type"  "RS<E>")
6459   (set_attr "atype"    "reg")])
6460
6461; sra, srag
6462(define_insn "*ashr<mode>3"
6463  [(set (match_operand:GPR 0 "register_operand" "=d")
6464        (ashiftrt:GPR (match_operand:GPR 1 "register_operand" "<d0>")
6465                      (match_operand:SI 2 "shift_count_or_setmem_operand" "Y")))
6466   (clobber (reg:CC CC_REGNUM))]
6467  ""
6468  "sra<g>\t%0,<1>%Y2"
6469  [(set_attr "op_type"  "RS<E>")
6470   (set_attr "atype"    "reg")])
6471
6472
6473; shift pattern with implicit ANDs
6474
6475(define_insn "*ashrdi3_cc_31_and"
6476  [(set (reg CC_REGNUM)
6477        (compare (ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
6478                              (and:SI (match_operand:SI 2 "shift_count_or_setmem_operand" "Y")
6479				      (match_operand:SI 3 "const_int_operand"   "n")))
6480		 (const_int 0)))
6481   (set (match_operand:DI 0 "register_operand" "=d")
6482        (ashiftrt:DI (match_dup 1) (and:SI (match_dup 2) (match_dup 3))))]
6483  "!TARGET_64BIT && s390_match_ccmode(insn, CCSmode)
6484   && (INTVAL (operands[3]) & 63) == 63"
6485  "srda\t%0,%Y2"
6486  [(set_attr "op_type"  "RS")
6487   (set_attr "atype"    "reg")])
6488
6489(define_insn "*ashrdi3_cconly_31_and"
6490  [(set (reg CC_REGNUM)
6491        (compare (ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
6492                              (and:SI (match_operand:SI 2 "shift_count_or_setmem_operand" "Y")
6493				      (match_operand:SI 3 "const_int_operand"   "n")))
6494                 (const_int 0)))
6495   (clobber (match_scratch:DI 0 "=d"))]
6496  "!TARGET_64BIT && s390_match_ccmode(insn, CCSmode)
6497   && (INTVAL (operands[3]) & 63) == 63"
6498  "srda\t%0,%Y2"
6499  [(set_attr "op_type"  "RS")
6500   (set_attr "atype"    "reg")])
6501
6502(define_insn "*ashrdi3_31_and"
6503  [(set (match_operand:DI 0 "register_operand" "=d")
6504        (ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
6505                     (and:SI (match_operand:SI 2 "shift_count_or_setmem_operand" "Y")
6506			     (match_operand:SI 3 "const_int_operand"   "n"))))
6507   (clobber (reg:CC CC_REGNUM))]
6508  "!TARGET_64BIT && (INTVAL (operands[3]) & 63) == 63"
6509  "srda\t%0,%Y2"
6510  [(set_attr "op_type"  "RS")
6511   (set_attr "atype"    "reg")])
6512
6513; sra, srag
6514(define_insn "*ashr<mode>3_cc_and"
6515  [(set (reg CC_REGNUM)
6516        (compare (ashiftrt:GPR (match_operand:GPR 1 "register_operand" "<d0>")
6517                               (and:SI (match_operand:SI 2 "shift_count_or_setmem_operand" "Y")
6518				       (match_operand:SI 3 "const_int_operand"   "n")))
6519		 (const_int 0)))
6520   (set (match_operand:GPR 0 "register_operand" "=d")
6521        (ashiftrt:GPR (match_dup 1) (and:SI (match_dup 2) (match_dup 3))))]
6522  "s390_match_ccmode(insn, CCSmode) && (INTVAL (operands[3]) & 63) == 63"
6523  "sra<g>\t%0,<1>%Y2"
6524  [(set_attr "op_type"  "RS<E>")
6525   (set_attr "atype"    "reg")])
6526
6527; sra, srag
6528(define_insn "*ashr<mode>3_cconly_and"
6529  [(set (reg CC_REGNUM)
6530        (compare (ashiftrt:GPR (match_operand:GPR 1 "register_operand" "<d0>")
6531                               (and:SI (match_operand:SI 2 "shift_count_or_setmem_operand" "Y")
6532				       (match_operand:SI 3 "const_int_operand"   "n")))
6533                 (const_int 0)))
6534   (clobber (match_scratch:GPR 0 "=d"))]
6535  "s390_match_ccmode(insn, CCSmode) && (INTVAL (operands[3]) & 63) == 63"
6536  "sra<g>\t%0,<1>%Y2"
6537  [(set_attr "op_type"  "RS<E>")
6538   (set_attr "atype"    "reg")])
6539
6540; sra, srag
6541(define_insn "*ashr<mode>3_and"
6542  [(set (match_operand:GPR 0 "register_operand" "=d")
6543        (ashiftrt:GPR (match_operand:GPR 1 "register_operand" "<d0>")
6544                      (and:SI (match_operand:SI 2 "shift_count_or_setmem_operand" "Y")
6545			      (match_operand:SI 3 "const_int_operand"   "n"))))
6546   (clobber (reg:CC CC_REGNUM))]
6547  "(INTVAL (operands[3]) & 63) == 63"
6548  "sra<g>\t%0,<1>%Y2"
6549  [(set_attr "op_type"  "RS<E>")
6550   (set_attr "atype"    "reg")])
6551
6552
6553;;
6554;; Branch instruction patterns.
6555;;
6556
6557(define_expand "b<code>"
6558  [(set (pc)
6559        (if_then_else (COMPARE (match_operand 0 "" "")
6560                               (const_int 0))
6561                      (match_dup 0)
6562                      (pc)))]
6563  ""
6564  "s390_emit_jump (operands[0],
6565    s390_emit_compare (<CODE>, s390_compare_op0, s390_compare_op1)); DONE;")
6566
6567
6568;;
6569;;- Conditional jump instructions.
6570;;
6571
6572(define_insn "*cjump_64"
6573  [(set (pc)
6574        (if_then_else
6575          (match_operator 1 "s390_comparison" [(reg CC_REGNUM) (const_int 0)])
6576          (label_ref (match_operand 0 "" ""))
6577          (pc)))]
6578  "TARGET_CPU_ZARCH"
6579{
6580  if (get_attr_length (insn) == 4)
6581    return "j%C1\t%l0";
6582  else
6583    return "jg%C1\t%l0";
6584}
6585  [(set_attr "op_type" "RI")
6586   (set_attr "type"    "branch")
6587   (set (attr "length")
6588        (if_then_else (lt (abs (minus (pc) (match_dup 0))) (const_int 60000))
6589                      (const_int 4) (const_int 6)))])
6590
6591(define_insn "*cjump_31"
6592  [(set (pc)
6593        (if_then_else
6594          (match_operator 1 "s390_comparison" [(reg CC_REGNUM) (const_int 0)])
6595          (label_ref (match_operand 0 "" ""))
6596          (pc)))]
6597  "!TARGET_CPU_ZARCH"
6598{
6599  gcc_assert (get_attr_length (insn) == 4);
6600  return "j%C1\t%l0";
6601}
6602  [(set_attr "op_type" "RI")
6603   (set_attr "type"    "branch")
6604   (set (attr "length")
6605        (if_then_else (eq (symbol_ref "flag_pic") (const_int 0))
6606          (if_then_else (lt (abs (minus (pc) (match_dup 0))) (const_int 60000))
6607                        (const_int 4) (const_int 6))
6608          (if_then_else (lt (abs (minus (pc) (match_dup 0))) (const_int 60000))
6609                        (const_int 4) (const_int 8))))])
6610
6611(define_insn "*cjump_long"
6612  [(set (pc)
6613        (if_then_else
6614          (match_operator 1 "s390_comparison" [(reg CC_REGNUM) (const_int 0)])
6615          (match_operand 0 "address_operand" "U")
6616          (pc)))]
6617  ""
6618{
6619  if (get_attr_op_type (insn) == OP_TYPE_RR)
6620    return "b%C1r\t%0";
6621  else
6622    return "b%C1\t%a0";
6623}
6624  [(set (attr "op_type")
6625        (if_then_else (match_operand 0 "register_operand" "")
6626                      (const_string "RR") (const_string "RX")))
6627   (set_attr "type"  "branch")
6628   (set_attr "atype" "agen")])
6629
6630
6631;;
6632;;- Negated conditional jump instructions.
6633;;
6634
6635(define_insn "*icjump_64"
6636  [(set (pc)
6637        (if_then_else
6638          (match_operator 1 "s390_comparison" [(reg CC_REGNUM) (const_int 0)])
6639          (pc)
6640          (label_ref (match_operand 0 "" ""))))]
6641  "TARGET_CPU_ZARCH"
6642{
6643  if (get_attr_length (insn) == 4)
6644    return "j%D1\t%l0";
6645  else
6646    return "jg%D1\t%l0";
6647}
6648  [(set_attr "op_type" "RI")
6649   (set_attr "type"    "branch")
6650   (set (attr "length")
6651        (if_then_else (lt (abs (minus (pc) (match_dup 0))) (const_int 60000))
6652                      (const_int 4) (const_int 6)))])
6653
6654(define_insn "*icjump_31"
6655  [(set (pc)
6656        (if_then_else
6657          (match_operator 1 "s390_comparison" [(reg CC_REGNUM) (const_int 0)])
6658          (pc)
6659          (label_ref (match_operand 0 "" ""))))]
6660  "!TARGET_CPU_ZARCH"
6661{
6662  gcc_assert (get_attr_length (insn) == 4);
6663  return "j%D1\t%l0";
6664}
6665  [(set_attr "op_type" "RI")
6666   (set_attr "type"    "branch")
6667   (set (attr "length")
6668        (if_then_else (eq (symbol_ref "flag_pic") (const_int 0))
6669          (if_then_else (lt (abs (minus (pc) (match_dup 0))) (const_int 60000))
6670                        (const_int 4) (const_int 6))
6671          (if_then_else (lt (abs (minus (pc) (match_dup 0))) (const_int 60000))
6672                        (const_int 4) (const_int 8))))])
6673
6674(define_insn "*icjump_long"
6675  [(set (pc)
6676        (if_then_else
6677          (match_operator 1 "s390_comparison" [(reg CC_REGNUM) (const_int 0)])
6678          (pc)
6679          (match_operand 0 "address_operand" "U")))]
6680  ""
6681{
6682  if (get_attr_op_type (insn) == OP_TYPE_RR)
6683    return "b%D1r\t%0";
6684  else
6685    return "b%D1\t%a0";
6686}
6687  [(set (attr "op_type")
6688        (if_then_else (match_operand 0 "register_operand" "")
6689                      (const_string "RR") (const_string "RX")))
6690   (set_attr "type"  "branch")
6691   (set_attr "atype" "agen")])
6692
6693;;
6694;;- Trap instructions.
6695;;
6696
6697(define_insn "trap"
6698  [(trap_if (const_int 1) (const_int 0))]
6699  ""
6700  "j\t.+2"
6701  [(set_attr "op_type" "RI")
6702   (set_attr "type"  "branch")])
6703
6704(define_expand "conditional_trap"
6705  [(trap_if (match_operand 0 "comparison_operator" "")
6706	    (match_operand 1 "general_operand" ""))]
6707  ""
6708{
6709  if (operands[1] != const0_rtx) FAIL;
6710  operands[0] = s390_emit_compare (GET_CODE (operands[0]), 
6711                                   s390_compare_op0, s390_compare_op1);
6712})
6713
6714(define_insn "*trap"
6715  [(trap_if (match_operator 0 "s390_comparison" [(reg CC_REGNUM) (const_int 0)])
6716	    (const_int 0))]
6717  ""
6718  "j%C0\t.+2";
6719  [(set_attr "op_type" "RI")
6720   (set_attr "type"  "branch")])
6721
6722;;
6723;;- Loop instructions.
6724;;
6725;;  This is all complicated by the fact that since this is a jump insn
6726;;  we must handle our own output reloads.
6727
6728(define_expand "doloop_end"
6729  [(use (match_operand 0 "" ""))        ; loop pseudo
6730   (use (match_operand 1 "" ""))        ; iterations; zero if unknown
6731   (use (match_operand 2 "" ""))        ; max iterations
6732   (use (match_operand 3 "" ""))        ; loop level
6733   (use (match_operand 4 "" ""))]       ; label
6734  ""
6735{
6736  if (GET_MODE (operands[0]) == SImode && !TARGET_CPU_ZARCH)
6737    emit_jump_insn (gen_doloop_si31 (operands[4], operands[0], operands[0]));
6738  else if (GET_MODE (operands[0]) == SImode && TARGET_CPU_ZARCH)
6739    emit_jump_insn (gen_doloop_si64 (operands[4], operands[0], operands[0]));
6740  else if (GET_MODE (operands[0]) == DImode && TARGET_64BIT)
6741    emit_jump_insn (gen_doloop_di (operands[4], operands[0], operands[0]));
6742  else
6743    FAIL;
6744
6745  DONE;
6746})
6747
6748(define_insn_and_split "doloop_si64"
6749  [(set (pc)
6750        (if_then_else
6751          (ne (match_operand:SI 1 "register_operand" "d,d,d")
6752              (const_int 1))
6753          (label_ref (match_operand 0 "" ""))
6754          (pc)))
6755   (set (match_operand:SI 2 "nonimmediate_operand" "=1,?X,?X")
6756        (plus:SI (match_dup 1) (const_int -1)))
6757   (clobber (match_scratch:SI 3 "=X,&1,&?d"))
6758   (clobber (reg:CC CC_REGNUM))]
6759  "TARGET_CPU_ZARCH"
6760{
6761  if (which_alternative != 0)
6762    return "#";
6763  else if (get_attr_length (insn) == 4)
6764    return "brct\t%1,%l0";
6765  else
6766    return "ahi\t%1,-1\;jgne\t%l0";
6767}
6768  "&& reload_completed
6769   && (! REG_P (operands[2])
6770       || ! rtx_equal_p (operands[1], operands[2]))"
6771  [(set (match_dup 3) (match_dup 1))
6772   (parallel [(set (reg:CCAN CC_REGNUM)
6773                   (compare:CCAN (plus:SI (match_dup 3) (const_int -1))
6774                                 (const_int 0)))
6775              (set (match_dup 3) (plus:SI (match_dup 3) (const_int -1)))])
6776   (set (match_dup 2) (match_dup 3))
6777   (set (pc) (if_then_else (ne (reg:CCAN CC_REGNUM) (const_int 0))
6778                           (label_ref (match_dup 0))
6779                           (pc)))]
6780  ""
6781  [(set_attr "op_type"  "RI")
6782   (set_attr "type"  "branch")
6783   (set (attr "length")
6784        (if_then_else (lt (abs (minus (pc) (match_dup 0))) (const_int 60000))
6785                      (const_int 4) (const_int 10)))])
6786
6787(define_insn_and_split "doloop_si31"
6788  [(set (pc)
6789        (if_then_else
6790          (ne (match_operand:SI 1 "register_operand" "d,d,d")
6791              (const_int 1))
6792          (label_ref (match_operand 0 "" ""))
6793          (pc)))
6794   (set (match_operand:SI 2 "nonimmediate_operand" "=1,?X,?X")
6795        (plus:SI (match_dup 1) (const_int -1)))
6796   (clobber (match_scratch:SI 3 "=X,&1,&?d"))
6797   (clobber (reg:CC CC_REGNUM))]
6798  "!TARGET_CPU_ZARCH"
6799{
6800  if (which_alternative != 0)
6801    return "#";
6802  else if (get_attr_length (insn) == 4)
6803    return "brct\t%1,%l0";
6804  else
6805    gcc_unreachable ();
6806}
6807  "&& reload_completed
6808   && (! REG_P (operands[2])
6809       || ! rtx_equal_p (operands[1], operands[2]))"
6810  [(set (match_dup 3) (match_dup 1))
6811   (parallel [(set (reg:CCAN CC_REGNUM)
6812                   (compare:CCAN (plus:SI (match_dup 3) (const_int -1))
6813                                 (const_int 0)))
6814              (set (match_dup 3) (plus:SI (match_dup 3) (const_int -1)))])
6815   (set (match_dup 2) (match_dup 3))
6816   (set (pc) (if_then_else (ne (reg:CCAN CC_REGNUM) (const_int 0))
6817                           (label_ref (match_dup 0))
6818                           (pc)))]
6819  ""
6820  [(set_attr "op_type"  "RI")
6821   (set_attr "type"  "branch")
6822   (set (attr "length")
6823        (if_then_else (eq (symbol_ref "flag_pic") (const_int 0))
6824          (if_then_else (lt (abs (minus (pc) (match_dup 0))) (const_int 60000))
6825                        (const_int 4) (const_int 6))
6826          (if_then_else (lt (abs (minus (pc) (match_dup 0))) (const_int 60000))
6827                        (const_int 4) (const_int 8))))])
6828
6829(define_insn "*doloop_si_long"
6830  [(set (pc)
6831        (if_then_else
6832          (ne (match_operand:SI 1 "register_operand" "d")
6833              (const_int 1))
6834          (match_operand 0 "address_operand" "U")
6835          (pc)))
6836   (set (match_operand:SI 2 "register_operand" "=1")
6837        (plus:SI (match_dup 1) (const_int -1)))
6838   (clobber (match_scratch:SI 3 "=X"))
6839   (clobber (reg:CC CC_REGNUM))]
6840  "!TARGET_CPU_ZARCH"
6841{
6842  if (get_attr_op_type (insn) == OP_TYPE_RR)
6843    return "bctr\t%1,%0";
6844  else
6845    return "bct\t%1,%a0";
6846}
6847  [(set (attr "op_type")
6848        (if_then_else (match_operand 0 "register_operand" "")
6849                      (const_string "RR") (const_string "RX")))
6850   (set_attr "type"  "branch")
6851   (set_attr "atype" "agen")])
6852
6853(define_insn_and_split "doloop_di"
6854  [(set (pc)
6855        (if_then_else
6856          (ne (match_operand:DI 1 "register_operand" "d,d,d")
6857              (const_int 1))
6858          (label_ref (match_operand 0 "" ""))
6859          (pc)))
6860   (set (match_operand:DI 2 "nonimmediate_operand" "=1,?X,?X")
6861        (plus:DI (match_dup 1) (const_int -1)))
6862   (clobber (match_scratch:DI 3 "=X,&1,&?d"))
6863   (clobber (reg:CC CC_REGNUM))]
6864  "TARGET_64BIT"
6865{
6866  if (which_alternative != 0)
6867    return "#";
6868  else if (get_attr_length (insn) == 4)
6869    return "brctg\t%1,%l0";
6870  else
6871    return "aghi\t%1,-1\;jgne\t%l0";
6872}
6873  "&& reload_completed
6874   && (! REG_P (operands[2])
6875       || ! rtx_equal_p (operands[1], operands[2]))"
6876  [(set (match_dup 3) (match_dup 1))
6877   (parallel [(set (reg:CCAN CC_REGNUM)
6878                   (compare:CCAN (plus:DI (match_dup 3) (const_int -1))
6879                                 (const_int 0)))
6880              (set (match_dup 3) (plus:DI (match_dup 3) (const_int -1)))])
6881   (set (match_dup 2) (match_dup 3))
6882   (set (pc) (if_then_else (ne (reg:CCAN CC_REGNUM) (const_int 0))
6883                           (label_ref (match_dup 0))
6884                           (pc)))]
6885  ""
6886  [(set_attr "op_type"  "RI")
6887   (set_attr "type"  "branch")
6888   (set (attr "length")
6889        (if_then_else (lt (abs (minus (pc) (match_dup 0))) (const_int 60000))
6890                      (const_int 4) (const_int 10)))])
6891
6892;;
6893;;- Unconditional jump instructions.
6894;;
6895
6896;
6897; jump instruction pattern(s).
6898;
6899
6900(define_expand "jump"
6901  [(match_operand 0 "" "")]
6902  ""
6903  "s390_emit_jump (operands[0], NULL_RTX); DONE;")
6904
6905(define_insn "*jump64"
6906  [(set (pc) (label_ref (match_operand 0 "" "")))]
6907  "TARGET_CPU_ZARCH"
6908{
6909  if (get_attr_length (insn) == 4)
6910    return "j\t%l0";
6911  else
6912    return "jg\t%l0";
6913}
6914  [(set_attr "op_type" "RI")
6915   (set_attr "type"  "branch")
6916   (set (attr "length")
6917        (if_then_else (lt (abs (minus (pc) (match_dup 0))) (const_int 60000))
6918                      (const_int 4) (const_int 6)))])
6919
6920(define_insn "*jump31"
6921  [(set (pc) (label_ref (match_operand 0 "" "")))]
6922  "!TARGET_CPU_ZARCH"
6923{
6924  gcc_assert (get_attr_length (insn) == 4);
6925  return "j\t%l0";
6926}
6927  [(set_attr "op_type" "RI")
6928   (set_attr "type"  "branch")
6929   (set (attr "length")
6930        (if_then_else (eq (symbol_ref "flag_pic") (const_int 0))
6931          (if_then_else (lt (abs (minus (pc) (match_dup 0))) (const_int 60000))
6932                        (const_int 4) (const_int 6))
6933          (if_then_else (lt (abs (minus (pc) (match_dup 0))) (const_int 60000))
6934                        (const_int 4) (const_int 8))))])
6935
6936;
6937; indirect-jump instruction pattern(s).
6938;
6939
6940(define_insn "indirect_jump"
6941 [(set (pc) (match_operand 0 "address_operand" "U"))]
6942  ""
6943{
6944  if (get_attr_op_type (insn) == OP_TYPE_RR)
6945    return "br\t%0";
6946  else
6947    return "b\t%a0";
6948}
6949  [(set (attr "op_type")
6950        (if_then_else (match_operand 0 "register_operand" "")
6951                      (const_string "RR") (const_string "RX")))
6952   (set_attr "type"  "branch")
6953   (set_attr "atype" "agen")])
6954
6955;
6956; casesi instruction pattern(s).
6957;
6958
6959(define_insn "casesi_jump"
6960 [(set (pc) (match_operand 0 "address_operand" "U"))
6961   (use (label_ref (match_operand 1 "" "")))]
6962  ""
6963{
6964  if (get_attr_op_type (insn) == OP_TYPE_RR)
6965    return "br\t%0";
6966  else
6967    return "b\t%a0";
6968}
6969  [(set (attr "op_type")
6970        (if_then_else (match_operand 0 "register_operand" "")
6971                      (const_string "RR") (const_string "RX")))
6972   (set_attr "type"  "branch")
6973   (set_attr "atype" "agen")])
6974
6975(define_expand "casesi"
6976  [(match_operand:SI 0 "general_operand" "")
6977   (match_operand:SI 1 "general_operand" "")
6978   (match_operand:SI 2 "general_operand" "")
6979   (label_ref (match_operand 3 "" ""))
6980   (label_ref (match_operand 4 "" ""))]
6981  ""
6982{
6983   rtx index  = gen_reg_rtx (SImode);
6984   rtx base   = gen_reg_rtx (Pmode);
6985   rtx target = gen_reg_rtx (Pmode);
6986
6987   emit_move_insn (index, operands[0]);
6988   emit_insn (gen_subsi3 (index, index, operands[1]));
6989   emit_cmp_and_jump_insns (index, operands[2], GTU, NULL_RTX, SImode, 1,
6990                            operands[4]);
6991
6992   if (Pmode != SImode)
6993     index = convert_to_mode (Pmode, index, 1);
6994   if (GET_CODE (index) != REG)
6995     index = copy_to_mode_reg (Pmode, index);
6996
6997   if (TARGET_64BIT)
6998       emit_insn (gen_ashldi3 (index, index, GEN_INT (3)));
6999   else
7000       emit_insn (gen_ashlsi3 (index, index, const2_rtx));
7001
7002   emit_move_insn (base, gen_rtx_LABEL_REF (Pmode, operands[3]));
7003
7004   index = gen_const_mem (Pmode, gen_rtx_PLUS (Pmode, base, index));
7005   emit_move_insn (target, index);
7006
7007   if (flag_pic)
7008     target = gen_rtx_PLUS (Pmode, base, target);
7009   emit_jump_insn (gen_casesi_jump (target, operands[3]));
7010
7011   DONE;
7012})
7013
7014
7015;;
7016;;- Jump to subroutine.
7017;;
7018;;
7019
7020;
7021; untyped call instruction pattern(s).
7022;
7023
7024;; Call subroutine returning any type.
7025(define_expand "untyped_call"
7026  [(parallel [(call (match_operand 0 "" "")
7027                    (const_int 0))
7028              (match_operand 1 "" "")
7029              (match_operand 2 "" "")])]
7030  ""
7031{
7032  int i;
7033
7034  emit_call_insn (gen_call (operands[0], const0_rtx, const0_rtx));
7035
7036  for (i = 0; i < XVECLEN (operands[2], 0); i++)
7037    {
7038      rtx set = XVECEXP (operands[2], 0, i);
7039      emit_move_insn (SET_DEST (set), SET_SRC (set));
7040    }
7041
7042  /* The optimizer does not know that the call sets the function value
7043     registers we stored in the result block.  We avoid problems by
7044     claiming that all hard registers are used and clobbered at this
7045     point.  */
7046  emit_insn (gen_blockage ());
7047
7048  DONE;
7049})
7050
7051;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
7052;; all of memory.  This blocks insns from being moved across this point.
7053
7054(define_insn "blockage"
7055  [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
7056  ""
7057  ""
7058  [(set_attr "type"    "none")
7059   (set_attr "length"  "0")])
7060
7061;
7062; sibcall patterns
7063;
7064
7065(define_expand "sibcall"
7066  [(call (match_operand 0 "" "")
7067	 (match_operand 1 "" ""))]
7068  ""
7069{
7070  s390_emit_call (XEXP (operands[0], 0), NULL_RTX, NULL_RTX, NULL_RTX);
7071  DONE;
7072})
7073
7074(define_insn "*sibcall_br"
7075  [(call (mem:QI (reg SIBCALL_REGNUM))
7076         (match_operand 0 "const_int_operand" "n"))]
7077  "SIBLING_CALL_P (insn)
7078   && GET_MODE (XEXP (XEXP (PATTERN (insn), 0), 0)) == Pmode"
7079  "br\t%%r1"
7080  [(set_attr "op_type" "RR")
7081   (set_attr "type"  "branch")
7082   (set_attr "atype" "agen")])
7083
7084(define_insn "*sibcall_brc"
7085  [(call (mem:QI (match_operand 0 "bras_sym_operand" "X"))
7086         (match_operand 1 "const_int_operand" "n"))]
7087  "SIBLING_CALL_P (insn) && TARGET_SMALL_EXEC"
7088  "j\t%0"
7089  [(set_attr "op_type" "RI")
7090   (set_attr "type"    "branch")])
7091
7092(define_insn "*sibcall_brcl"
7093  [(call (mem:QI (match_operand 0 "bras_sym_operand" "X"))
7094         (match_operand 1 "const_int_operand" "n"))]
7095  "SIBLING_CALL_P (insn) && TARGET_CPU_ZARCH"
7096  "jg\t%0"
7097  [(set_attr "op_type" "RIL")
7098   (set_attr "type"    "branch")])
7099
7100;
7101; sibcall_value patterns
7102;
7103
7104(define_expand "sibcall_value"
7105  [(set (match_operand 0 "" "")
7106	(call (match_operand 1 "" "")
7107	      (match_operand 2 "" "")))]
7108  ""
7109{
7110  s390_emit_call (XEXP (operands[1], 0), NULL_RTX, operands[0], NULL_RTX);
7111  DONE;
7112})
7113
7114(define_insn "*sibcall_value_br"
7115  [(set (match_operand 0 "" "")
7116	(call (mem:QI (reg SIBCALL_REGNUM))
7117	      (match_operand 1 "const_int_operand" "n")))]
7118  "SIBLING_CALL_P (insn)
7119   && GET_MODE (XEXP (XEXP (XEXP (PATTERN (insn), 1), 0), 0)) == Pmode"
7120  "br\t%%r1"
7121  [(set_attr "op_type" "RR")
7122   (set_attr "type"  "branch")
7123   (set_attr "atype" "agen")])
7124
7125(define_insn "*sibcall_value_brc"
7126  [(set (match_operand 0 "" "")
7127	(call (mem:QI (match_operand 1 "bras_sym_operand" "X"))
7128	      (match_operand 2 "const_int_operand" "n")))]
7129  "SIBLING_CALL_P (insn) && TARGET_SMALL_EXEC"
7130  "j\t%1"
7131  [(set_attr "op_type" "RI")
7132   (set_attr "type"    "branch")])
7133
7134(define_insn "*sibcall_value_brcl"
7135  [(set (match_operand 0 "" "")
7136	(call (mem:QI (match_operand 1 "bras_sym_operand" "X"))
7137	      (match_operand 2 "const_int_operand" "n")))]
7138  "SIBLING_CALL_P (insn) && TARGET_CPU_ZARCH"
7139  "jg\t%1"
7140  [(set_attr "op_type" "RIL")
7141   (set_attr "type"    "branch")])
7142
7143
7144;
7145; call instruction pattern(s).
7146;
7147
7148(define_expand "call"
7149  [(call (match_operand 0 "" "")
7150         (match_operand 1 "" ""))
7151   (use (match_operand 2 "" ""))]
7152  ""
7153{
7154  s390_emit_call (XEXP (operands[0], 0), NULL_RTX, NULL_RTX,
7155		  gen_rtx_REG (Pmode, RETURN_REGNUM));
7156  DONE;
7157})
7158
7159(define_insn "*bras"
7160  [(call (mem:QI (match_operand 0 "bras_sym_operand" "X"))
7161         (match_operand 1 "const_int_operand" "n"))
7162   (clobber (match_operand 2 "register_operand" "=r"))]
7163  "!SIBLING_CALL_P (insn)
7164   && TARGET_SMALL_EXEC
7165   && GET_MODE (operands[2]) == Pmode"
7166  "bras\t%2,%0"
7167  [(set_attr "op_type" "RI")
7168   (set_attr "type"    "jsr")])
7169
7170(define_insn "*brasl"
7171  [(call (mem:QI (match_operand 0 "bras_sym_operand" "X"))
7172         (match_operand 1 "const_int_operand" "n"))
7173   (clobber (match_operand 2 "register_operand" "=r"))]
7174  "!SIBLING_CALL_P (insn)
7175   && TARGET_CPU_ZARCH
7176   && GET_MODE (operands[2]) == Pmode"
7177  "brasl\t%2,%0"
7178  [(set_attr "op_type" "RIL")
7179   (set_attr "type"    "jsr")])
7180
7181(define_insn "*basr"
7182  [(call (mem:QI (match_operand 0 "address_operand" "U"))
7183         (match_operand 1 "const_int_operand" "n"))
7184   (clobber (match_operand 2 "register_operand" "=r"))]
7185  "!SIBLING_CALL_P (insn) && GET_MODE (operands[2]) == Pmode"
7186{
7187  if (get_attr_op_type (insn) == OP_TYPE_RR)
7188    return "basr\t%2,%0";
7189  else
7190    return "bas\t%2,%a0";
7191}
7192  [(set (attr "op_type")
7193        (if_then_else (match_operand 0 "register_operand" "")
7194                      (const_string "RR") (const_string "RX")))
7195   (set_attr "type"  "jsr")
7196   (set_attr "atype" "agen")])
7197
7198;
7199; call_value instruction pattern(s).
7200;
7201
7202(define_expand "call_value"
7203  [(set (match_operand 0 "" "")
7204        (call (match_operand 1 "" "")
7205              (match_operand 2 "" "")))
7206   (use (match_operand 3 "" ""))]
7207  ""
7208{
7209  s390_emit_call (XEXP (operands[1], 0), NULL_RTX, operands[0],
7210		  gen_rtx_REG (Pmode, RETURN_REGNUM));
7211  DONE;
7212})
7213
7214(define_insn "*bras_r"
7215  [(set (match_operand 0 "" "")
7216        (call (mem:QI (match_operand 1 "bras_sym_operand" "X"))
7217              (match_operand:SI 2 "const_int_operand" "n")))
7218   (clobber (match_operand 3 "register_operand" "=r"))]
7219  "!SIBLING_CALL_P (insn)
7220   && TARGET_SMALL_EXEC
7221   && GET_MODE (operands[3]) == Pmode"
7222  "bras\t%3,%1"
7223  [(set_attr "op_type" "RI")
7224   (set_attr "type"    "jsr")])
7225
7226(define_insn "*brasl_r"
7227  [(set (match_operand 0 "" "")
7228        (call (mem:QI (match_operand 1 "bras_sym_operand" "X"))
7229              (match_operand 2 "const_int_operand" "n")))
7230   (clobber (match_operand 3 "register_operand" "=r"))]
7231  "!SIBLING_CALL_P (insn)
7232   && TARGET_CPU_ZARCH
7233   && GET_MODE (operands[3]) == Pmode"
7234  "brasl\t%3,%1"
7235  [(set_attr "op_type" "RIL")
7236   (set_attr "type"    "jsr")])
7237
7238(define_insn "*basr_r"
7239  [(set (match_operand 0 "" "")
7240        (call (mem:QI (match_operand 1 "address_operand" "U"))
7241              (match_operand 2 "const_int_operand" "n")))
7242   (clobber (match_operand 3 "register_operand" "=r"))]
7243  "!SIBLING_CALL_P (insn) && GET_MODE (operands[3]) == Pmode"
7244{
7245  if (get_attr_op_type (insn) == OP_TYPE_RR)
7246    return "basr\t%3,%1";
7247  else
7248    return "bas\t%3,%a1";
7249}
7250  [(set (attr "op_type")
7251        (if_then_else (match_operand 1 "register_operand" "")
7252                      (const_string "RR") (const_string "RX")))
7253   (set_attr "type"  "jsr")
7254   (set_attr "atype" "agen")])
7255
7256;;
7257;;- Thread-local storage support.
7258;;
7259
7260(define_expand "get_tp_64"
7261  [(set (match_operand:DI 0 "nonimmediate_operand" "") (reg:DI TP_REGNUM))]
7262  "TARGET_64BIT"
7263  "")
7264
7265(define_expand "get_tp_31"
7266  [(set (match_operand:SI 0 "nonimmediate_operand" "") (reg:SI TP_REGNUM))]
7267  "!TARGET_64BIT"
7268  "")
7269
7270(define_expand "set_tp_64"
7271  [(set (reg:DI TP_REGNUM) (match_operand:DI 0 "nonimmediate_operand" ""))
7272   (set (reg:DI TP_REGNUM) (unspec_volatile:DI [(reg:DI TP_REGNUM)] UNSPECV_SET_TP))]
7273  "TARGET_64BIT"
7274  "")
7275
7276(define_expand "set_tp_31"
7277  [(set (reg:SI TP_REGNUM) (match_operand:SI 0 "nonimmediate_operand" ""))
7278   (set (reg:SI TP_REGNUM) (unspec_volatile:SI [(reg:SI TP_REGNUM)] UNSPECV_SET_TP))]
7279  "!TARGET_64BIT"
7280  "")
7281
7282(define_insn "*set_tp"
7283  [(set (reg TP_REGNUM) (unspec_volatile [(reg TP_REGNUM)] UNSPECV_SET_TP))]
7284  ""
7285  ""
7286  [(set_attr "type" "none")
7287   (set_attr "length" "0")])
7288
7289(define_insn "*tls_load_64"
7290  [(set (match_operand:DI 0 "register_operand" "=d")
7291        (unspec:DI [(match_operand:DI 1 "memory_operand" "m")
7292                    (match_operand:DI 2 "" "")]
7293		   UNSPEC_TLS_LOAD))]
7294  "TARGET_64BIT"
7295  "lg\t%0,%1%J2"
7296  [(set_attr "op_type" "RXE")])
7297
7298(define_insn "*tls_load_31"
7299  [(set (match_operand:SI 0 "register_operand" "=d,d")
7300        (unspec:SI [(match_operand:SI 1 "memory_operand" "R,T")
7301                    (match_operand:SI 2 "" "")]
7302		   UNSPEC_TLS_LOAD))]
7303  "!TARGET_64BIT"
7304  "@
7305   l\t%0,%1%J2
7306   ly\t%0,%1%J2"
7307  [(set_attr "op_type" "RX,RXY")])
7308
7309(define_insn "*bras_tls"
7310  [(set (match_operand 0 "" "")
7311        (call (mem:QI (match_operand 1 "bras_sym_operand" "X"))
7312              (match_operand 2 "const_int_operand" "n")))
7313   (clobber (match_operand 3 "register_operand" "=r"))
7314   (use (match_operand 4 "" ""))]
7315  "!SIBLING_CALL_P (insn)
7316   && TARGET_SMALL_EXEC
7317   && GET_MODE (operands[3]) == Pmode"
7318  "bras\t%3,%1%J4"
7319  [(set_attr "op_type" "RI")
7320   (set_attr "type"    "jsr")])
7321
7322(define_insn "*brasl_tls"
7323  [(set (match_operand 0 "" "")
7324        (call (mem:QI (match_operand 1 "bras_sym_operand" "X"))
7325              (match_operand 2 "const_int_operand" "n")))
7326   (clobber (match_operand 3 "register_operand" "=r"))
7327   (use (match_operand 4 "" ""))]
7328  "!SIBLING_CALL_P (insn)
7329   && TARGET_CPU_ZARCH
7330   && GET_MODE (operands[3]) == Pmode"
7331  "brasl\t%3,%1%J4"
7332  [(set_attr "op_type" "RIL")
7333   (set_attr "type"    "jsr")])
7334
7335(define_insn "*basr_tls"
7336  [(set (match_operand 0 "" "")
7337        (call (mem:QI (match_operand 1 "address_operand" "U"))
7338              (match_operand 2 "const_int_operand" "n")))
7339   (clobber (match_operand 3 "register_operand" "=r"))
7340   (use (match_operand 4 "" ""))]
7341  "!SIBLING_CALL_P (insn) && GET_MODE (operands[3]) == Pmode"
7342{
7343  if (get_attr_op_type (insn) == OP_TYPE_RR)
7344    return "basr\t%3,%1%J4";
7345  else
7346    return "bas\t%3,%a1%J4";
7347}
7348  [(set (attr "op_type")
7349        (if_then_else (match_operand 1 "register_operand" "")
7350                      (const_string "RR") (const_string "RX")))
7351   (set_attr "type"  "jsr")
7352   (set_attr "atype" "agen")])
7353
7354;;
7355;;- Atomic operations
7356;;
7357
7358;
7359; memory barrier pattern.
7360;
7361
7362(define_expand "memory_barrier"
7363  [(set (mem:BLK (match_dup 0))
7364	(unspec_volatile:BLK [(mem:BLK (match_dup 0))] UNSPECV_MB))]
7365  ""
7366{
7367  operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (DImode));
7368  MEM_VOLATILE_P (operands[0]) = 1;
7369})
7370
7371(define_insn "*memory_barrier"
7372  [(set (match_operand:BLK 0 "" "")
7373	(unspec_volatile:BLK [(match_operand:BLK 1 "" "")] UNSPECV_MB))]
7374  ""
7375  "bcr\t15,0"
7376  [(set_attr "op_type" "RR")])
7377
7378;
7379; compare and swap patterns.
7380;
7381
7382(define_expand "sync_compare_and_swap<mode>"
7383  [(parallel
7384    [(set (match_operand:TDSI 0 "register_operand" "")
7385	  (match_operand:TDSI 1 "memory_operand" ""))
7386     (set (match_dup 1)
7387	  (unspec_volatile:TDSI
7388	    [(match_dup 1)
7389	     (match_operand:TDSI 2 "register_operand" "")
7390	     (match_operand:TDSI 3 "register_operand" "")]
7391	    UNSPECV_CAS))
7392     (set (reg:CCZ1 CC_REGNUM)
7393	  (compare:CCZ1 (match_dup 1) (match_dup 2)))])]
7394  "")
7395
7396(define_expand "sync_compare_and_swap<mode>"
7397  [(parallel
7398    [(set (match_operand:HQI 0 "register_operand" "")
7399	  (match_operand:HQI 1 "memory_operand" ""))
7400     (set (match_dup 1)
7401	  (unspec_volatile:HQI
7402	    [(match_dup 1)
7403	     (match_operand:HQI 2 "general_operand" "")
7404	     (match_operand:HQI 3 "general_operand" "")]
7405	    UNSPECV_CAS))
7406     (set (reg:CCZ1 CC_REGNUM)
7407	  (compare:CCZ1 (match_dup 1) (match_dup 2)))])]
7408  ""
7409  "s390_expand_cs_hqi (<MODE>mode, operands[0], operands[1], 
7410		       operands[2], operands[3]); DONE;")
7411
7412(define_expand "sync_compare_and_swap_cc<mode>"
7413  [(parallel
7414    [(set (match_operand:TDSI 0 "register_operand" "")
7415	  (match_operand:TDSI 1 "memory_operand" ""))
7416     (set (match_dup 1)
7417	  (unspec_volatile:TDSI
7418	    [(match_dup 1)
7419	     (match_operand:TDSI 2 "register_operand" "")
7420	     (match_operand:TDSI 3 "register_operand" "")]
7421	    UNSPECV_CAS))
7422     (set (match_dup 4)
7423	  (compare:CCZ1 (match_dup 1) (match_dup 2)))])]
7424  ""
7425{
7426  /* Emulate compare.  */
7427  operands[4] = gen_rtx_REG (CCZ1mode, CC_REGNUM);
7428  s390_compare_op0 = operands[1];
7429  s390_compare_op1 = operands[2];
7430  s390_compare_emitted = operands[4];
7431})
7432
7433; cds, cdsg
7434(define_insn "*sync_compare_and_swap<mode>"
7435  [(set (match_operand:DP 0 "register_operand" "=r")
7436	(match_operand:DP 1 "memory_operand" "+Q"))
7437   (set (match_dup 1)
7438	(unspec_volatile:DP
7439	  [(match_dup 1)
7440	   (match_operand:DP 2 "register_operand" "0")
7441	   (match_operand:DP 3 "register_operand" "r")]
7442	  UNSPECV_CAS))
7443   (set (reg:CCZ1 CC_REGNUM)
7444	(compare:CCZ1 (match_dup 1) (match_dup 2)))]
7445  ""
7446  "cds<tg>\t%0,%3,%S1"
7447  [(set_attr "op_type" "RS<TE>")
7448   (set_attr "type"   "sem")])
7449
7450; cs, csg
7451(define_insn "*sync_compare_and_swap<mode>"
7452  [(set (match_operand:GPR 0 "register_operand" "=r")
7453	(match_operand:GPR 1 "memory_operand" "+Q"))
7454   (set (match_dup 1)
7455	(unspec_volatile:GPR
7456	  [(match_dup 1)
7457	   (match_operand:GPR 2 "register_operand" "0")
7458	   (match_operand:GPR 3 "register_operand" "r")]
7459	  UNSPECV_CAS))
7460   (set (reg:CCZ1 CC_REGNUM)
7461	(compare:CCZ1 (match_dup 1) (match_dup 2)))]
7462  "" 
7463  "cs<g>\t%0,%3,%S1"
7464  [(set_attr "op_type" "RS<E>")
7465   (set_attr "type"   "sem")])
7466
7467
7468;
7469; Other atomic instruction patterns.
7470;
7471
7472(define_expand "sync_lock_test_and_set<mode>"
7473  [(match_operand:HQI 0 "register_operand")
7474   (match_operand:HQI 1 "memory_operand")
7475   (match_operand:HQI 2 "general_operand")]
7476  ""
7477  "s390_expand_atomic (<MODE>mode, SET, operands[0], operands[1], 
7478		       operands[2], false); DONE;")
7479
7480(define_expand "sync_<atomic><mode>"
7481  [(set (match_operand:HQI 0 "memory_operand")
7482	(ATOMIC:HQI (match_dup 0)
7483		    (match_operand:HQI 1 "general_operand")))]
7484  ""
7485  "s390_expand_atomic (<MODE>mode, <CODE>, NULL_RTX, operands[0], 
7486		       operands[1], false); DONE;")
7487
7488(define_expand "sync_old_<atomic><mode>"
7489  [(set (match_operand:HQI 0 "register_operand")
7490	(match_operand:HQI 1 "memory_operand"))
7491   (set (match_dup 1)
7492	(ATOMIC:HQI (match_dup 1)
7493		    (match_operand:HQI 2 "general_operand")))]
7494  ""
7495  "s390_expand_atomic (<MODE>mode, <CODE>, operands[0], operands[1], 
7496		       operands[2], false); DONE;")
7497
7498(define_expand "sync_new_<atomic><mode>"
7499  [(set (match_operand:HQI 0 "register_operand")
7500	(ATOMIC:HQI (match_operand:HQI 1 "memory_operand")
7501		    (match_operand:HQI 2 "general_operand"))) 
7502   (set (match_dup 1) (ATOMIC:HQI (match_dup 1) (match_dup 2)))]
7503  ""
7504  "s390_expand_atomic (<MODE>mode, <CODE>, operands[0], operands[1], 
7505		       operands[2], true); DONE;")
7506
7507;;
7508;;- Miscellaneous instructions.
7509;;
7510
7511;
7512; allocate stack instruction pattern(s).
7513;
7514
7515(define_expand "allocate_stack"
7516  [(match_operand 0 "general_operand" "")
7517   (match_operand 1 "general_operand" "")]
7518 "TARGET_BACKCHAIN"
7519{
7520  rtx temp = gen_reg_rtx (Pmode);
7521
7522  emit_move_insn (temp, s390_back_chain_rtx ());
7523  anti_adjust_stack (operands[1]);
7524  emit_move_insn (s390_back_chain_rtx (), temp);
7525
7526  emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
7527  DONE;
7528})
7529
7530
7531;
7532; setjmp instruction pattern.
7533;
7534
7535(define_expand "builtin_setjmp_receiver"
7536  [(match_operand 0 "" "")]
7537  "flag_pic"
7538{
7539  emit_insn (s390_load_got ());
7540  emit_insn (gen_rtx_USE (VOIDmode, pic_offset_table_rtx));
7541  DONE;
7542})
7543
7544;; These patterns say how to save and restore the stack pointer.  We need not
7545;; save the stack pointer at function level since we are careful to
7546;; preserve the backchain.  At block level, we have to restore the backchain
7547;; when we restore the stack pointer.
7548;;
7549;; For nonlocal gotos, we must save both the stack pointer and its
7550;; backchain and restore both.  Note that in the nonlocal case, the
7551;; save area is a memory location.
7552
7553(define_expand "save_stack_function"
7554  [(match_operand 0 "general_operand" "")
7555   (match_operand 1 "general_operand" "")]
7556  ""
7557  "DONE;")
7558
7559(define_expand "restore_stack_function"
7560  [(match_operand 0 "general_operand" "")
7561   (match_operand 1 "general_operand" "")]
7562  ""
7563  "DONE;")
7564
7565(define_expand "restore_stack_block"
7566  [(match_operand 0 "register_operand" "")
7567   (match_operand 1 "register_operand" "")]
7568  "TARGET_BACKCHAIN"
7569{
7570  rtx temp = gen_reg_rtx (Pmode);
7571
7572  emit_move_insn (temp, s390_back_chain_rtx ());
7573  emit_move_insn (operands[0], operands[1]);
7574  emit_move_insn (s390_back_chain_rtx (), temp);
7575
7576  DONE;
7577})
7578
7579(define_expand "save_stack_nonlocal"
7580  [(match_operand 0 "memory_operand" "")
7581   (match_operand 1 "register_operand" "")]
7582  ""
7583{
7584  enum machine_mode mode = TARGET_64BIT ? OImode : TImode;
7585  rtx base = gen_rtx_REG (Pmode, BASE_REGNUM);
7586
7587  /* Copy the backchain to the first word, sp to the second and the
7588     literal pool base to the third.  */
7589
7590  if (TARGET_BACKCHAIN)
7591    {
7592      rtx temp = force_reg (Pmode, s390_back_chain_rtx ());
7593      emit_move_insn (operand_subword (operands[0], 0, 0, mode), temp);
7594    }
7595
7596  emit_move_insn (operand_subword (operands[0], 1, 0, mode), operands[1]);
7597  emit_move_insn (operand_subword (operands[0], 2, 0, mode), base);
7598
7599  DONE;
7600})
7601
7602(define_expand "restore_stack_nonlocal"
7603  [(match_operand 0 "register_operand" "")
7604   (match_operand 1 "memory_operand" "")]
7605  ""
7606{
7607  enum machine_mode mode = TARGET_64BIT ? OImode : TImode;
7608  rtx base = gen_rtx_REG (Pmode, BASE_REGNUM);
7609  rtx temp = NULL_RTX;
7610
7611  /* Restore the backchain from the first word, sp from the second and the
7612     literal pool base from the third.  */
7613
7614  if (TARGET_BACKCHAIN)
7615    temp = force_reg (Pmode, operand_subword (operands[1], 0, 0, mode));
7616    
7617  emit_move_insn (base, operand_subword (operands[1], 2, 0, mode));
7618  emit_move_insn (operands[0], operand_subword (operands[1], 1, 0, mode));
7619
7620  if (temp)
7621    emit_move_insn (s390_back_chain_rtx (), temp);
7622
7623  emit_insn (gen_rtx_USE (VOIDmode, base));
7624  DONE;
7625})
7626
7627(define_expand "exception_receiver"
7628  [(const_int 0)]
7629  ""
7630{
7631  s390_set_has_landing_pad_p (true);
7632  DONE;
7633})
7634
7635;
7636; nop instruction pattern(s).
7637;
7638
7639(define_insn "nop"
7640  [(const_int 0)]
7641  ""
7642  "lr\t0,0"
7643  [(set_attr "op_type" "RR")])
7644
7645
7646;
7647; Special literal pool access instruction pattern(s).
7648;
7649
7650(define_insn "*pool_entry"
7651  [(unspec_volatile [(match_operand 0 "consttable_operand" "X")]
7652                    UNSPECV_POOL_ENTRY)]
7653  ""
7654{
7655  enum machine_mode mode = GET_MODE (PATTERN (insn));
7656  unsigned int align = GET_MODE_BITSIZE (mode);
7657  s390_output_pool_entry (operands[0], mode, align);
7658  return "";
7659}
7660  [(set (attr "length")
7661        (symbol_ref "GET_MODE_SIZE (GET_MODE (PATTERN (insn)))"))])
7662
7663(define_insn "pool_align"
7664  [(unspec_volatile [(match_operand 0 "const_int_operand" "n")]
7665                    UNSPECV_POOL_ALIGN)]
7666  ""
7667  ".align\t%0"
7668  [(set (attr "length") (symbol_ref "INTVAL (operands[0])"))])
7669
7670(define_insn "pool_section_start"
7671  [(unspec_volatile [(const_int 1)] UNSPECV_POOL_SECTION)]
7672  ""
7673  ".section\t.rodata"
7674  [(set_attr "length" "0")])
7675
7676(define_insn "pool_section_end"
7677  [(unspec_volatile [(const_int 0)] UNSPECV_POOL_SECTION)]
7678  ""
7679  ".previous"
7680  [(set_attr "length" "0")])
7681
7682(define_insn "main_base_31_small"
7683  [(set (match_operand 0 "register_operand" "=a")
7684        (unspec [(label_ref (match_operand 1 "" ""))] UNSPEC_MAIN_BASE))]
7685  "!TARGET_CPU_ZARCH && GET_MODE (operands[0]) == Pmode"
7686  "basr\t%0,0"
7687  [(set_attr "op_type" "RR")
7688   (set_attr "type"    "la")])
7689
7690(define_insn "main_base_31_large"
7691  [(set (match_operand 0 "register_operand" "=a")
7692        (unspec [(label_ref (match_operand 1 "" ""))] UNSPEC_MAIN_BASE))
7693   (set (pc) (label_ref (match_operand 2 "" "")))]
7694  "!TARGET_CPU_ZARCH && GET_MODE (operands[0]) == Pmode"
7695  "bras\t%0,%2"
7696  [(set_attr "op_type" "RI")])
7697
7698(define_insn "main_base_64"
7699  [(set (match_operand 0 "register_operand" "=a")
7700        (unspec [(label_ref (match_operand 1 "" ""))] UNSPEC_MAIN_BASE))]
7701  "TARGET_CPU_ZARCH && GET_MODE (operands[0]) == Pmode"
7702  "larl\t%0,%1"
7703  [(set_attr "op_type" "RIL")
7704   (set_attr "type"    "larl")])
7705
7706(define_insn "main_pool"
7707  [(set (match_operand 0 "register_operand" "=a")
7708        (unspec_volatile [(const_int 0)] UNSPECV_MAIN_POOL))]
7709  "GET_MODE (operands[0]) == Pmode"
7710{
7711  gcc_unreachable ();
7712}
7713  [(set (attr "type") 
7714        (if_then_else (ne (symbol_ref "TARGET_CPU_ZARCH") (const_int 0))
7715                      (const_string "larl") (const_string "la")))])
7716
7717(define_insn "reload_base_31"
7718  [(set (match_operand 0 "register_operand" "=a")
7719        (unspec [(label_ref (match_operand 1 "" ""))] UNSPEC_RELOAD_BASE))]
7720  "!TARGET_CPU_ZARCH && GET_MODE (operands[0]) == Pmode"
7721  "basr\t%0,0\;la\t%0,%1-.(%0)"
7722  [(set_attr "length" "6")
7723   (set_attr "type" "la")])
7724
7725(define_insn "reload_base_64"
7726  [(set (match_operand 0 "register_operand" "=a")
7727        (unspec [(label_ref (match_operand 1 "" ""))] UNSPEC_RELOAD_BASE))]
7728  "TARGET_CPU_ZARCH && GET_MODE (operands[0]) == Pmode"
7729  "larl\t%0,%1"
7730  [(set_attr "op_type" "RIL")
7731   (set_attr "type"    "larl")])
7732
7733(define_insn "pool"
7734  [(unspec_volatile [(match_operand 0 "const_int_operand" "n")] UNSPECV_POOL)]
7735  ""
7736{
7737  gcc_unreachable ();
7738}
7739  [(set (attr "length") (symbol_ref "INTVAL (operands[0])"))])
7740
7741;;
7742;; Insns related to generating the function prologue and epilogue.
7743;;
7744
7745
7746(define_expand "prologue"
7747  [(use (const_int 0))]
7748  ""
7749  "s390_emit_prologue (); DONE;")
7750
7751(define_expand "epilogue"
7752  [(use (const_int 1))]
7753  ""
7754  "s390_emit_epilogue (false); DONE;")
7755
7756(define_expand "sibcall_epilogue"
7757  [(use (const_int 0))]
7758  ""
7759  "s390_emit_epilogue (true); DONE;")
7760
7761(define_insn "*return"
7762  [(return)
7763   (use (match_operand 0 "register_operand" "a"))]
7764  "GET_MODE (operands[0]) == Pmode"
7765  "br\t%0"
7766  [(set_attr "op_type" "RR")
7767   (set_attr "type"    "jsr")
7768   (set_attr "atype"   "agen")])
7769
7770
7771;; Instruction definition to extend a 31-bit pointer into a 64-bit
7772;; pointer. This is used for compatibility.
7773
7774(define_expand "ptr_extend"
7775  [(set (match_operand:DI 0 "register_operand" "=r")
7776        (match_operand:SI 1 "register_operand" "r"))]
7777  "TARGET_64BIT"
7778{
7779  emit_insn (gen_anddi3 (operands[0],
7780			 gen_lowpart (DImode, operands[1]),
7781			 GEN_INT (0x7fffffff)));
7782  DONE;
7783})
7784
7785;; Instruction definition to expand eh_return macro to support
7786;; swapping in special linkage return addresses.
7787
7788(define_expand "eh_return"
7789  [(use (match_operand 0 "register_operand" ""))]
7790  "TARGET_TPF"
7791{
7792  s390_emit_tpf_eh_return (operands[0]);
7793  DONE;
7794})
7795
7796;
7797; Stack Protector Patterns
7798;
7799
7800(define_expand "stack_protect_set"
7801  [(set (match_operand 0 "memory_operand" "")
7802	(match_operand 1 "memory_operand" ""))]
7803  ""
7804{
7805#ifdef TARGET_THREAD_SSP_OFFSET
7806  operands[1]
7807    = gen_rtx_MEM (Pmode, gen_rtx_PLUS (Pmode, s390_get_thread_pointer (),
7808                                        GEN_INT (TARGET_THREAD_SSP_OFFSET)));
7809#endif
7810  if (TARGET_64BIT)
7811    emit_insn (gen_stack_protect_setdi (operands[0], operands[1]));
7812  else
7813    emit_insn (gen_stack_protect_setsi (operands[0], operands[1]));
7814
7815  DONE;
7816})
7817
7818(define_insn "stack_protect_set<mode>"
7819  [(set (match_operand:DSI 0 "memory_operand" "=Q")
7820        (unspec:DSI [(match_operand:DSI 1 "memory_operand" "Q")] UNSPEC_SP_SET))]
7821  ""
7822  "mvc\t%O0(%G0,%R0),%S1"
7823  [(set_attr "op_type" "SS")])
7824
7825(define_expand "stack_protect_test"
7826  [(set (reg:CC CC_REGNUM)
7827	(compare (match_operand 0 "memory_operand" "")
7828		 (match_operand 1 "memory_operand" "")))
7829   (match_operand 2 "" "")]
7830  ""
7831{
7832#ifdef TARGET_THREAD_SSP_OFFSET
7833  operands[1]
7834    = gen_rtx_MEM (Pmode, gen_rtx_PLUS (Pmode, s390_get_thread_pointer (),
7835                                        GEN_INT (TARGET_THREAD_SSP_OFFSET)));
7836#endif
7837  s390_compare_op0 = operands[0];
7838  s390_compare_op1 = operands[1];
7839  s390_compare_emitted = gen_rtx_REG (CCZmode, CC_REGNUM);
7840
7841  if (TARGET_64BIT)
7842    emit_insn (gen_stack_protect_testdi (operands[0], operands[1]));
7843  else
7844    emit_insn (gen_stack_protect_testsi (operands[0], operands[1]));
7845
7846  emit_jump_insn (gen_beq (operands[2]));
7847
7848  DONE;
7849})
7850
7851(define_insn "stack_protect_test<mode>"
7852  [(set (reg:CCZ CC_REGNUM)
7853        (unspec:CCZ [(match_operand:DSI 0 "memory_operand" "Q")
7854		     (match_operand:DSI 1 "memory_operand" "Q")] UNSPEC_SP_TEST))]
7855  ""
7856  "clc\t%O0(%G0,%R0),%S1"
7857  [(set_attr "op_type" "SS")])
7858