1;;- Machine description for GNU compiler -- S/390 / zSeries version.
2;;  Copyright (C) 1999-2020 Free Software Foundation, Inc.
3;;  Contributed by Hartmut Penner (hpenner@de.ibm.com) and
4;;                 Ulrich Weigand (uweigand@de.ibm.com) and
5;;                 Andreas Krebbel (Andreas.Krebbel@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 3, 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 COPYING3.  If not see
21;; <http://www.gnu.org/licenses/>.
22
23;;
24;; See constraints.md for a description of constraints specific to s390.
25;;
26
27;; Special formats used for outputting 390 instructions.
28;;
29;;     %C: print opcode suffix for branch condition.
30;;     %D: print opcode suffix for inverse branch condition.
31;;     %J: print tls_load/tls_gdcall/tls_ldcall suffix
32;;     %G: print the size of the operand in bytes.
33;;     %O: print only the displacement of a memory reference.
34;;     %R: print only the base register of a memory reference.
35;;     %S: print S-type memory reference (base+displacement).
36;;     %N: print the second word of a DImode operand.
37;;     %M: print the second word of a TImode operand.
38;;     %Y: print shift count operand.
39;;
40;;     %b: print integer X as if it's an unsigned byte.
41;;     %c: print integer X as if it's an signed 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_c_enum "unspec" [
60   ; Miscellaneous
61   UNSPEC_ROUND
62   UNSPEC_ICM
63   UNSPEC_TIE
64
65   ; Convert CC into a str comparison result and copy it into an
66   ; integer register
67   ; cc0->0, cc1->1, cc2->-1, (cc3->-1)
68   UNSPEC_STRCMPCC_TO_INT
69
70   ; Copy CC as is into the lower 2 bits of an integer register
71   UNSPEC_CC_TO_INT
72
73   ; The right hand side of an setmem
74   UNSPEC_REPLICATE_BYTE
75
76   ; GOT/PLT and lt-relative accesses
77   UNSPEC_LTREL_OFFSET
78   UNSPEC_POOL_OFFSET
79   UNSPEC_GOTENT
80   UNSPEC_GOT
81   UNSPEC_GOTOFF
82   UNSPEC_PLT
83   UNSPEC_PLTOFF
84
85   ; Literal pool
86   UNSPEC_RELOAD_BASE
87   UNSPEC_MAIN_BASE
88   UNSPEC_LTREF
89   UNSPEC_INSN
90   UNSPEC_EXECUTE
91   UNSPEC_EXECUTE_JUMP
92
93   ; Atomic Support
94   UNSPEC_MB
95   UNSPEC_MOVA
96
97   ; TLS relocation specifiers
98   UNSPEC_TLSGD
99   UNSPEC_TLSLDM
100   UNSPEC_NTPOFF
101   UNSPEC_DTPOFF
102   UNSPEC_GOTNTPOFF
103   UNSPEC_INDNTPOFF
104
105   ; TLS support
106   UNSPEC_TLSLDM_NTPOFF
107   UNSPEC_TLS_LOAD
108   UNSPEC_GET_TP
109
110   ; String Functions
111   UNSPEC_SRST
112   UNSPEC_MVST
113
114   ; Stack Smashing Protector
115   UNSPEC_SP_SET
116   UNSPEC_SP_TEST
117
118   ; Split stack support
119   UNSPEC_STACK_CHECK
120
121   ; Test Data Class (TDC)
122   UNSPEC_TDC_INSN
123
124   ; Byte-wise Population Count
125   UNSPEC_POPCNT
126   UNSPEC_COPYSIGN
127
128   ; Load FP Integer
129   UNSPEC_FPINT_FLOOR
130   UNSPEC_FPINT_BTRUNC
131   UNSPEC_FPINT_ROUND
132   UNSPEC_FPINT_CEIL
133   UNSPEC_FPINT_NEARBYINT
134   UNSPEC_FPINT_RINT
135
136   UNSPEC_LCBB
137
138   ; Vector
139   UNSPEC_VEC_SMULT_HI
140   UNSPEC_VEC_UMULT_HI
141   UNSPEC_VEC_SMULT_LO
142   UNSPEC_VEC_SMULT_EVEN
143   UNSPEC_VEC_UMULT_EVEN
144   UNSPEC_VEC_SMULT_ODD
145   UNSPEC_VEC_UMULT_ODD
146
147   UNSPEC_VEC_VMAL
148   UNSPEC_VEC_VMAH
149   UNSPEC_VEC_VMALH
150   UNSPEC_VEC_VMAE
151   UNSPEC_VEC_VMALE
152   UNSPEC_VEC_VMAO
153   UNSPEC_VEC_VMALO
154
155   UNSPEC_VEC_GATHER
156   UNSPEC_VEC_EXTRACT
157   UNSPEC_VEC_INSERT_AND_ZERO
158   UNSPEC_VEC_LOAD_BNDRY
159   UNSPEC_VEC_LOAD_LEN
160   UNSPEC_VEC_LOAD_LEN_R
161   UNSPEC_VEC_MERGEH
162   UNSPEC_VEC_MERGEL
163   UNSPEC_VEC_PACK
164   UNSPEC_VEC_PACK_SATURATE
165   UNSPEC_VEC_PACK_SATURATE_CC
166   UNSPEC_VEC_PACK_SATURATE_GENCC
167   UNSPEC_VEC_PACK_UNSIGNED_SATURATE
168   UNSPEC_VEC_PACK_UNSIGNED_SATURATE_CC
169   UNSPEC_VEC_PACK_UNSIGNED_SATURATE_GENCC
170   UNSPEC_VEC_PERM
171   UNSPEC_VEC_PERMI
172   UNSPEC_VEC_EXTEND
173   UNSPEC_VEC_STORE_LEN
174   UNSPEC_VEC_STORE_LEN_R
175   UNSPEC_VEC_VBPERM
176   UNSPEC_VEC_UNPACKH
177   UNSPEC_VEC_UNPACKH_L
178   UNSPEC_VEC_UNPACKL
179   UNSPEC_VEC_UNPACKL_L
180   UNSPEC_VEC_ADDC
181   UNSPEC_VEC_ADDE_U128
182   UNSPEC_VEC_ADDEC_U128
183   UNSPEC_VEC_AVG
184   UNSPEC_VEC_AVGU
185   UNSPEC_VEC_CHECKSUM
186   UNSPEC_VEC_GFMSUM
187   UNSPEC_VEC_GFMSUM_128
188   UNSPEC_VEC_GFMSUM_ACCUM
189   UNSPEC_VEC_GFMSUM_ACCUM_128
190   UNSPEC_VEC_SET
191
192   UNSPEC_VEC_VSUMG
193   UNSPEC_VEC_VSUMQ
194   UNSPEC_VEC_VSUM
195   UNSPEC_VEC_RL_MASK
196   UNSPEC_VEC_SLL
197   UNSPEC_VEC_SLB
198   UNSPEC_VEC_SLDBYTE
199   UNSPEC_VEC_SLDBIT
200   UNSPEC_VEC_SRDBIT
201   UNSPEC_VEC_SRAL
202   UNSPEC_VEC_SRAB
203   UNSPEC_VEC_SRL
204   UNSPEC_VEC_SRLB
205
206   UNSPEC_VEC_SUBC
207   UNSPEC_VEC_SUBE_U128
208   UNSPEC_VEC_SUBEC_U128
209
210   UNSPEC_VEC_TEST_MASK
211
212   UNSPEC_VEC_VFAE
213   UNSPEC_VEC_VFAECC
214
215   UNSPEC_VEC_VFEE
216   UNSPEC_VEC_VFEECC
217   UNSPEC_VEC_VFENE
218   UNSPEC_VEC_VFENECC
219
220   UNSPEC_VEC_VISTR
221   UNSPEC_VEC_VISTRCC
222
223   UNSPEC_VEC_VSTRC
224   UNSPEC_VEC_VSTRCCC
225
226   UNSPEC_VEC_VSTRS
227   UNSPEC_VEC_VSTRSCC
228
229   UNSPEC_VEC_VCDGB
230   UNSPEC_VEC_VCDLGB
231
232   UNSPEC_VEC_VCGDB
233   UNSPEC_VEC_VCLGDB
234
235   UNSPEC_VEC_VFI
236
237   UNSPEC_VEC_VFLL        ; vector fp load lengthened
238   UNSPEC_VEC_VFLR        ; vector fp load rounded
239
240   UNSPEC_VEC_VFTCI
241   UNSPEC_VEC_VFTCICC
242
243   UNSPEC_VEC_MSUM
244
245   UNSPEC_VEC_VFMIN
246   UNSPEC_VEC_VFMAX
247
248   UNSPEC_VEC_ELTSWAP
249])
250
251;;
252;; UNSPEC_VOLATILE usage
253;;
254
255(define_c_enum "unspecv" [
256   ; Blockage
257   UNSPECV_BLOCKAGE
258
259   ; TPF Support
260   UNSPECV_TPF_PROLOGUE
261   UNSPECV_TPF_EPILOGUE
262
263   ; Literal pool
264   UNSPECV_POOL
265   UNSPECV_POOL_SECTION
266   UNSPECV_POOL_ALIGN
267   UNSPECV_POOL_ENTRY
268   UNSPECV_MAIN_POOL
269
270   ; TLS support
271   UNSPECV_SET_TP
272
273   ; Atomic Support
274   UNSPECV_CAS
275   UNSPECV_ATOMIC_OP
276
277   ; Non-branch nops used for compare-and-branch adjustments on z10
278   UNSPECV_NOP_LR_0
279   UNSPECV_NOP_LR_1
280
281   ; Hotpatching (unremovable NOPs)
282   UNSPECV_NOP_2_BYTE
283   UNSPECV_NOP_4_BYTE
284   UNSPECV_NOP_6_BYTE
285
286   ; Transactional Execution support
287   UNSPECV_TBEGIN
288   UNSPECV_TBEGIN_TDB
289   UNSPECV_TBEGINC
290   UNSPECV_TEND
291   UNSPECV_TABORT
292   UNSPECV_ETND
293   UNSPECV_NTSTG
294   UNSPECV_PPA
295
296   ; Set and get floating point control register
297   UNSPECV_SFPC
298   UNSPECV_EFPC
299
300   ; Split stack support
301   UNSPECV_SPLIT_STACK_CALL
302
303   UNSPECV_OSC_BREAK
304  ])
305
306;;
307;; Registers
308;;
309
310; Registers with special meaning
311
312(define_constants
313  [
314   ; Sibling call register.
315   (SIBCALL_REGNUM		 1)
316   ; A call-clobbered reg which can be used in indirect branch thunks
317   (INDIRECT_BRANCH_THUNK_REGNUM 1)
318   ; Literal pool base register.
319   (BASE_REGNUM			13)
320   ; Return address register.
321   (RETURN_REGNUM		14)
322   ; Stack pointer register.
323   (STACK_REGNUM		15)
324   ; Condition code register.
325   (CC_REGNUM			33)
326   ; Thread local storage pointer register.
327   (TP_REGNUM			36)
328  ])
329
330; Hardware register names
331
332(define_constants
333  [
334   ; General purpose registers
335   (GPR0_REGNUM                  0)
336   (GPR1_REGNUM                  1)
337   (GPR2_REGNUM                  2)
338   (GPR6_REGNUM                  6)
339   ; Floating point registers.
340   (FPR0_REGNUM                 16)
341   (FPR1_REGNUM                 20)
342   (FPR2_REGNUM                 17)
343   (FPR3_REGNUM                 21)
344   (FPR4_REGNUM                 18)
345   (FPR5_REGNUM                 22)
346   (FPR6_REGNUM                 19)
347   (FPR7_REGNUM                 23)
348   (FPR8_REGNUM                 24)
349   (FPR9_REGNUM                 28)
350   (FPR10_REGNUM                25)
351   (FPR11_REGNUM                29)
352   (FPR12_REGNUM                26)
353   (FPR13_REGNUM                30)
354   (FPR14_REGNUM                27)
355   (FPR15_REGNUM                31)
356   (VR0_REGNUM                  16)
357   (VR16_REGNUM                 38)
358   (VR23_REGNUM                 45)
359   (VR24_REGNUM                 46)
360   (VR31_REGNUM                 53)
361  ])
362
363; Rounding modes for binary floating point numbers
364(define_constants
365  [(BFP_RND_CURRENT                 0)
366   (BFP_RND_NEAREST_TIE_AWAY_FROM_0 1)
367   (BFP_RND_PREP_FOR_SHORT_PREC     3)
368   (BFP_RND_NEAREST_TIE_TO_EVEN     4)
369   (BFP_RND_TOWARD_0                5)
370   (BFP_RND_TOWARD_INF              6)
371   (BFP_RND_TOWARD_MINF             7)])
372
373; Rounding modes for decimal floating point numbers
374; 1-7 were introduced with the floating point extension facility
375; available with z196
376; With these rounding modes (1-7) a quantum exception might occur
377; which is suppressed for the other modes.
378(define_constants
379  [(DFP_RND_CURRENT                          0)
380   (DFP_RND_NEAREST_TIE_AWAY_FROM_0_QUANTEXC 1)
381   (DFP_RND_CURRENT_QUANTEXC                 2)
382   (DFP_RND_PREP_FOR_SHORT_PREC_QUANTEXC     3)
383   (DFP_RND_NEAREST_TIE_TO_EVEN_QUANTEXC     4)
384   (DFP_RND_TOWARD_0_QUANTEXC                5)
385   (DFP_RND_TOWARD_INF_QUANTEXC              6)
386   (DFP_RND_TOWARD_MINF_QUANTEXC             7)
387   (DFP_RND_NEAREST_TIE_TO_EVEN              8)
388   (DFP_RND_TOWARD_0                         9)
389   (DFP_RND_TOWARD_INF                      10)
390   (DFP_RND_TOWARD_MINF                     11)
391   (DFP_RND_NEAREST_TIE_AWAY_FROM_0         12)
392   (DFP_RND_NEAREST_TIE_TO_0                13)
393   (DFP_RND_AWAY_FROM_0                     14)
394   (DFP_RND_PREP_FOR_SHORT_PREC             15)])
395
396;;
397;; PFPO GPR0 argument format
398;;
399
400(define_constants
401  [
402   ; PFPO operation type
403   (PFPO_CONVERT          0x1000000)
404   ; PFPO operand types
405   (PFPO_OP_TYPE_SF             0x5)
406   (PFPO_OP_TYPE_DF             0x6)
407   (PFPO_OP_TYPE_TF             0x7)
408   (PFPO_OP_TYPE_SD             0x8)
409   (PFPO_OP_TYPE_DD             0x9)
410   (PFPO_OP_TYPE_TD             0xa)
411   ; Bitposition of operand types
412   (PFPO_OP0_TYPE_SHIFT          16)
413   (PFPO_OP1_TYPE_SHIFT           8)
414   ; Decide whether current DFP or BFD rounding mode should be used
415   ; for the conversion.
416   (PFPO_RND_MODE_DFP             0)
417   (PFPO_RND_MODE_BFP             1)
418  ])
419
420;; PPA constants
421
422; Immediate values which can be used as the third operand to the
423; perform processor assist instruction
424
425(define_constants
426  [(PPA_TX_ABORT                 1)
427   (PPA_OOO_BARRIER             15)])
428
429; Immediate operands for tbegin and tbeginc
430(define_constants [(TBEGIN_MASK  65292)]) ; 0xff0c
431(define_constants [(TBEGINC_MASK 65288)]) ; 0xff08
432
433;; Instruction operand type as used in the Principles of Operation.
434;; Used to determine defaults for length and other attribute values.
435
436(define_attr "op_type"
437  "NN,E,RR,RRE,RX,RS,RSI,RI,SI,S,SS,SSE,RXE,RSE,RIL,RIE,RXY,RSY,SIY,RRF,SIL,RRS,RIS,VRI,VRR,VRS,VRV,VRX,VSI"
438  (const_string "NN"))
439
440;; Instruction type attribute used for scheduling.
441
442(define_attr "type" "none,integer,load,lr,la,larl,lm,stm,
443	             cs,vs,store,sem,idiv,
444                     imulhi,imulsi,imuldi,
445		     branch,jsr,fsimptf,fsimpdf,fsimpsf,fhex,
446		     floadtf,floaddf,floadsf,fstoredf,fstoresf,
447		     fmultf,fmuldf,fmulsf,fdivtf,fdivdf,fdivsf,
448		     ftoi,fsqrttf,fsqrtdf,fsqrtsf,
449		     fmadddf,fmaddsf,
450                     ftrunctf,ftruncdf, ftruncsd, ftruncdd,
451                     itoftf, itofdf, itofsf, itofdd, itoftd,
452                     fdivdd, fdivtd, floaddd, floadsd, fmuldd, fmultd,
453                     fsimpdd, fsimpsd, fsimptd, fstoredd, fstoresd,
454                     ftoidfp, other"
455  (cond [(eq_attr "op_type" "NN")  (const_string "other")
456         (eq_attr "op_type" "SS")  (const_string "cs")]
457    (const_string "integer")))
458
459;; Another attribute used for scheduling purposes:
460;;   agen: Instruction uses the address generation unit
461;;   reg: Instruction does not use the agen unit
462
463(define_attr "atype" "agen,reg"
464  (if_then_else (eq_attr "op_type" "E,RR,RI,RRE,RSI,RIL,RIE,RRF")
465		(const_string "reg")
466		(const_string "agen")))
467
468;; Properties concerning Z10 execution grouping and value forwarding.
469;; z10_super: instruction is superscalar.
470;; z10_super_c: instruction is superscalar and meets the condition of z10_c.
471;; z10_fwd: The instruction reads the value of an operand and stores it into a
472;;   target register.  It can forward this value to a second instruction that reads
473;;   the same register if that second instruction is issued in the same group.
474;; z10_rec: The instruction is in the T pipeline and reads a register. If the
475;;   instruction in the S pipe writes to the register, then the T instruction
476;;   can immediately read the new value.
477;; z10_fr: union of Z10_fwd and z10_rec.
478;; z10_c: second operand of instruction is a register and read with complemented bits.
479;;
480;; An additional suffix A1, A3, or E1 indicates the respective AGI bypass.
481
482
483(define_attr "z10prop" "none,
484                        z10_super, z10_super_E1, z10_super_A1, z10_super_c, z10_super_c_E1,
485                        z10_fwd, z10_fwd_A1, z10_fwd_A3, z10_fwd_E1,
486                        z10_rec,
487                        z10_fr, z10_fr_A3, z10_fr_E1,
488                        z10_c"
489             (const_string "none"))
490
491;; Properties concerning Z196 decoding
492;; z196_alone: must group alone
493;; z196_end: ends a group
494;; z196_cracked: instruction is cracked or expanded
495(define_attr "z196prop" "none,
496                         z196_alone, z196_ends,
497                         z196_cracked"
498             (const_string "none"))
499
500; mnemonics which only get defined through if_then_else currently
501; don't get added to the list values automatically and hence need to
502; be listed here.
503(define_attr "mnemonic" "b,bas,basr,bc,bcr_flush,unknown" (const_string "unknown"))
504
505;; Length in bytes.
506
507(define_attr "length" ""
508  (cond [(eq_attr "op_type" "E,RR")		          (const_int 2)
509         (eq_attr "op_type" "RX,RI,RRE,RS,RSI,S,SI,RRF")  (const_int 4)]
510    (const_int 6)))
511
512
513;; Processor type.  This attribute must exactly match the processor_type
514;; enumeration in s390.h.
515
516(define_attr "cpu" "z900,z990,z9_109,z9_ec,z10,z196,zEC12,z13,z14,z15"
517  (const (symbol_ref "s390_tune_attr")))
518
519(define_attr "cpu_facility"
520  "standard,ieee,zarch,cpu_zarch,longdisp,extimm,dfp,z10,z196,zEC12,vx,z13,z14,vxe,z15,vxe2"
521  (const_string "standard"))
522
523(define_attr "enabled" ""
524  (cond [(eq_attr "cpu_facility" "standard")
525	 (const_int 1)
526
527         (and (eq_attr "cpu_facility" "ieee")
528	      (match_test "TARGET_CPU_IEEE_FLOAT"))
529	 (const_int 1)
530
531	 (and (eq_attr "cpu_facility" "zarch")
532	      (match_test "TARGET_ZARCH"))
533	 (const_int 1)
534
535	 (and (eq_attr "cpu_facility" "longdisp")
536	      (match_test "TARGET_LONG_DISPLACEMENT"))
537	 (const_int 1)
538
539         (and (eq_attr "cpu_facility" "extimm")
540	      (match_test "TARGET_EXTIMM"))
541	 (const_int 1)
542
543         (and (eq_attr "cpu_facility" "dfp")
544	      (match_test "TARGET_DFP"))
545	 (const_int 1)
546
547         (eq_attr "cpu_facility" "cpu_zarch")
548	 (const_int 1)
549
550         (and (eq_attr "cpu_facility" "z10")
551              (match_test "TARGET_Z10"))
552	 (const_int 1)
553
554         (and (eq_attr "cpu_facility" "z196")
555              (match_test "TARGET_Z196"))
556	 (const_int 1)
557
558         (and (eq_attr "cpu_facility" "zEC12")
559              (match_test "TARGET_ZEC12"))
560	 (const_int 1)
561
562         (and (eq_attr "cpu_facility" "vx")
563              (match_test "TARGET_VX"))
564	 (const_int 1)
565
566         (and (eq_attr "cpu_facility" "z13")
567              (match_test "TARGET_Z13"))
568	 (const_int 1)
569
570         (and (eq_attr "cpu_facility" "z14")
571              (match_test "TARGET_Z14"))
572	 (const_int 1)
573
574         (and (eq_attr "cpu_facility" "vxe")
575	      (match_test "TARGET_VXE"))
576	 (const_int 1)
577
578	 (and (eq_attr "cpu_facility" "z15")
579	      (match_test "TARGET_Z15"))
580	 (const_int 1)
581
582         (and (eq_attr "cpu_facility" "vxe2")
583	      (match_test "TARGET_VXE2"))
584	 (const_int 1)
585	 ]
586	(const_int 0)))
587
588;; Whether an instruction supports relative long addressing.
589;; Currently this corresponds to RIL-b and RIL-c instruction formats,
590;; but having a separate attribute, as opposed to reusing op_type,
591;; provides additional flexibility.
592
593(define_attr "relative_long" "no,yes" (const_string "no"))
594
595;; Pipeline description for z900.
596(include "2064.md")
597
598;; Pipeline description for z990, z9-109 and z9-ec.
599(include "2084.md")
600
601;; Pipeline description for z10
602(include "2097.md")
603
604;; Pipeline description for z196
605(include "2817.md")
606
607;; Pipeline description for zEC12
608(include "2827.md")
609
610;; Pipeline description for z13
611(include "2964.md")
612
613;; Pipeline description for z14
614(include "3906.md")
615
616;; Pipeline description for z15
617(include "8561.md")
618
619;; Predicates
620(include "predicates.md")
621
622;; Constraint definitions
623(include "constraints.md")
624
625;; Other includes
626(include "tpf.md")
627
628;; Iterators
629
630(define_mode_iterator ALL [TI DI SI HI QI TF DF SF TD DD SD V1QI V2QI V4QI V8QI V16QI V1HI V2HI V4HI V8HI V1SI V2SI V4SI V1DI V2DI V1SF V2SF V4SF V1TI V1DF V2DF V1TF])
631
632;; These mode iterators allow floating point patterns to be generated from the
633;; same template.
634(define_mode_iterator FP_ALL [TF DF SF (TD "TARGET_HARD_DFP") (DD "TARGET_HARD_DFP")
635                              (SD "TARGET_HARD_DFP")])
636(define_mode_iterator FP [TF DF SF (TD "TARGET_HARD_DFP") (DD "TARGET_HARD_DFP")])
637(define_mode_iterator BFP [TF DF SF])
638(define_mode_iterator DFP [TD DD])
639(define_mode_iterator DFP_ALL [TD DD SD])
640(define_mode_iterator DSF [DF SF])
641(define_mode_iterator SD_SF [SF SD])
642(define_mode_iterator DD_DF [DF DD])
643(define_mode_iterator TD_TF [TF TD])
644
645; 32 bit int<->fp conversion instructions are available since VXE2 (z15).
646(define_mode_iterator VX_CONV_BFP [DF (SF "TARGET_VXE2")])
647(define_mode_iterator VX_CONV_INT [DI (SI "TARGET_VXE2")])
648
649;; These mode iterators allow 31-bit and 64-bit GPR patterns to be generated
650;; from the same template.
651(define_mode_iterator GPR [(DI "TARGET_ZARCH") SI])
652(define_mode_iterator DGPR [(TI "TARGET_ZARCH") DI SI])
653(define_mode_iterator DSI [DI SI])
654(define_mode_iterator TDI [TI DI])
655
656;; These mode iterators allow :P to be used for patterns that operate on
657;; pointer-sized quantities.  Exactly one of the two alternatives will match.
658(define_mode_iterator P [(DI "TARGET_64BIT") (SI "!TARGET_64BIT")])
659
660;; These macros refer to the actual word_mode of the configuration.
661;; This is equal to Pmode except on 31-bit machines in zarch mode.
662(define_mode_iterator DW [(TI "TARGET_ZARCH") (DI "!TARGET_ZARCH")])
663(define_mode_iterator W  [(DI "TARGET_ZARCH") (SI "!TARGET_ZARCH")])
664
665;; Used by the umul pattern to express modes having half the size.
666(define_mode_attr DWH [(TI "DI") (DI "SI")])
667(define_mode_attr dwh [(TI "di") (DI "si")])
668
669;; This mode iterator allows the QI and HI patterns to be defined from
670;; the same template.
671(define_mode_iterator HQI [HI QI])
672
673;; This mode iterator allows the integer patterns to be defined from the
674;; same template.
675(define_mode_iterator INT [(DI "TARGET_ZARCH") SI HI QI])
676(define_mode_iterator DINT [(TI "TARGET_ZARCH") DI SI HI QI])
677(define_mode_iterator SINT [SI HI QI])
678
679;; This iterator allows some 'ashift' and 'lshiftrt' pattern to be defined from
680;; the same template.
681(define_code_iterator SHIFT [ashift lshiftrt])
682
683;; This iterator allows r[ox]sbg to be defined with the same template
684(define_code_iterator IXOR [ior xor])
685
686;; This is used for merging the nand/nor and and/or with complement patterns
687(define_code_iterator ANDOR [and ior])
688(define_code_attr bitops_name [(and "and") (ior "or")])
689(define_code_attr inv_bitops_name [(and "or") (ior "and")])
690(define_code_attr inv_no [(and "o") (ior "n")])
691
692;; This iterator is used to expand the patterns for the nearest
693;; integer functions.
694(define_int_iterator FPINT [UNSPEC_FPINT_FLOOR UNSPEC_FPINT_BTRUNC
695			    UNSPEC_FPINT_ROUND UNSPEC_FPINT_CEIL
696			    UNSPEC_FPINT_NEARBYINT])
697(define_int_attr fpint_name [(UNSPEC_FPINT_FLOOR "floor")
698			     (UNSPEC_FPINT_BTRUNC "btrunc")
699			     (UNSPEC_FPINT_ROUND "round")
700			     (UNSPEC_FPINT_CEIL "ceil")
701			     (UNSPEC_FPINT_NEARBYINT "nearbyint")])
702(define_int_attr fpint_roundingmode [(UNSPEC_FPINT_FLOOR "7")
703				     (UNSPEC_FPINT_BTRUNC "5")
704				     (UNSPEC_FPINT_ROUND "1")
705				     (UNSPEC_FPINT_CEIL "6")
706				     (UNSPEC_FPINT_NEARBYINT "0")])
707
708;; This iterator and attribute allow to combine most atomic operations.
709(define_code_iterator ATOMIC [and ior xor plus minus mult])
710(define_code_iterator ATOMIC_Z196 [and ior xor plus])
711(define_code_attr atomic [(and "and") (ior "or") (xor "xor")
712			  (plus "add") (minus "sub") (mult "nand")])
713(define_code_attr noxa [(and "n") (ior "o") (xor "x") (plus "a")])
714
715;; In FP templates, a string like "lt<de>br" will expand to "ltxbr" in
716;; TF/TDmode, "ltdbr" in DF/DDmode, and "ltebr" in SF/SDmode.
717(define_mode_attr xde [(TF "x") (DF "d") (SF "e") (TD "x") (DD "d") (SD "e") (V4SF "e") (V2DF "d")])
718
719;; In FP templates, a <dee> in "m<dee><bt>r" will expand to "mx<bt>r" in
720;; TF/TDmode, "md<bt>r" in DF/DDmode, "mee<bt>r" in SFmode and "me<bt>r in
721;; SDmode.
722(define_mode_attr xdee [(TF "x") (DF "d") (SF "ee") (TD "x") (DD "d") (SD "e")])
723
724;; In FP templates, "<RRe>" will expand to "RRE" in TFmode and "RR" otherwise.
725;; Likewise for "<RXe>".
726(define_mode_attr RRe [(TF "RRE") (DF "RR") (SF "RR")])
727(define_mode_attr RXe [(TF "RXE") (DF "RX") (SF "RX")])
728
729;; The decimal floating point variants of add, sub, div and mul support 3
730;; fp register operands.  The following attributes allow to merge the bfp and
731;; dfp variants in a single insn definition.
732
733;; These mode attributes are supposed to be used in the `enabled' insn
734;; attribute to disable certain alternatives for certain modes.
735(define_mode_attr nBFP [(TF "0") (DF "0") (SF "0") (TD "*") (DD "*") (DD "*")])
736(define_mode_attr nDFP [(TF "*") (DF "*") (SF "*") (TD "0") (DD "0") (DD "0")])
737(define_mode_attr DSF [(TF "0") (DF "*") (SF "*") (TD "0") (DD "0") (SD "0")])
738(define_mode_attr DFDI [(TF "0") (DF "*") (SF "0")
739			(TD "0") (DD "0") (DD "0")
740			(TI "0") (DI "*") (SI "0")])
741(define_mode_attr SFSI [(TF "0") (DF "0") (SF "*")
742			(TD "0") (DD "0") (DD "0")
743			(TI "0") (DI "0") (SI "*")])
744(define_mode_attr DF [(TF "0") (DF "*") (SF "0")
745		      (TD "0") (DD "0") (DD "0")
746		      (TI "0") (DI "0") (SI "0")])
747(define_mode_attr SF [(TF "0") (DF "0") (SF "*")
748		      (TD "0") (DD "0") (DD "0")
749		      (TI "0") (DI "0") (SI "0")])
750
751;; This attribute is used in the operand constraint list
752;; for instructions dealing with the sign bit of 32 or 64bit fp values.
753;; TFmode values are represented by a fp register pair.  Since the
754;; sign bit instructions only handle single source and target fp registers
755;; these instructions can only be used for TFmode values if the source and
756;; target operand uses the same fp register.
757(define_mode_attr fT0 [(TF "0") (DF "f") (SF "f")])
758
759;; This attribute adds b for bfp instructions and t for dfp instructions and is used
760;; within instruction mnemonics.
761(define_mode_attr bt [(TF "b") (DF "b") (SF "b") (TD "t") (DD "t") (SD "t")])
762
763;; This attribute is used within instruction mnemonics.  It evaluates to d for dfp
764;; modes and to an empty string for bfp modes.
765(define_mode_attr _d [(TF "") (DF "") (SF "") (TD "d") (DD "d") (SD "d")])
766
767;; In GPR and P templates, a constraint like "<d0>" will expand to "d" in DImode
768;; and "0" in SImode. This allows to combine instructions of which the 31bit
769;; version only operates on one register.
770(define_mode_attr d0 [(DI "d") (SI "0")])
771
772;; In combination with d0 this allows to combine instructions of which the 31bit
773;; version only operates on one register. The DImode version needs an additional
774;; register for the assembler output.
775(define_mode_attr 1 [(DI "%1,") (SI "")])
776
777;; In SHIFT templates, a string like "s<lr>dl" will expand to "sldl" in
778;; 'ashift' and "srdl" in 'lshiftrt'.
779(define_code_attr lr [(ashift "l") (lshiftrt "r")])
780
781;; In SHIFT templates, this attribute holds the correct standard name for the
782;; pattern itself and the corresponding function calls.
783(define_code_attr shift [(ashift "ashl") (lshiftrt "lshr")])
784
785;; This attribute handles differences in the instruction 'type' and will result
786;; in "RRE" for DImode and "RR" for SImode.
787(define_mode_attr E [(DI "E") (SI "")])
788
789;; This attribute handles differences in the instruction 'type' and makes RX<Y>
790;; to result in "RXY" for DImode and "RX" for SImode.
791(define_mode_attr Y [(DI "Y") (SI "")])
792
793;; This attribute handles differences in the instruction 'type' and will result
794;; in "RSE" for TImode and "RS" for DImode.
795(define_mode_attr TE [(TI "E") (DI "")])
796
797;; In GPR templates, a string like "lc<g>r" will expand to "lcgr" in DImode
798;; and "lcr" in SImode.
799(define_mode_attr g [(DI "g") (SI "")])
800
801;; In GPR templates, a string like "sl<y>" will expand to "slg" in DImode
802;; and "sly" in SImode. This is useful because on 64bit the ..g instructions
803;; were enhanced with long displacements whereas 31bit instructions got a ..y
804;; variant for long displacements.
805(define_mode_attr y [(DI "g") (SI "y")])
806
807;; In DW templates, a string like "cds<g>" will expand to "cdsg" in TImode
808;; and "cds" in DImode.
809(define_mode_attr tg [(TI "g") (DI "")])
810
811;; In TDI templates, a string like "c<d>sg".
812(define_mode_attr td [(TI "d") (DI "")])
813
814;; In GPR templates, a string like "c<gf>dbr" will expand to "cgdbr" in DImode
815;; and "cfdbr" in SImode.
816(define_mode_attr gf [(DI "g") (SI "f")])
817
818;; In GPR templates, a string like sll<gk> will expand to sllg for DI
819;; and sllk for SI.  This way it is possible to merge the new z196 SI
820;; 3 operands shift instructions into the existing patterns.
821(define_mode_attr gk [(DI "g") (SI "k")])
822
823;; ICM mask required to load MODE value into the lowest subreg
824;; of a SImode register.
825(define_mode_attr icm_lo [(HI "3") (QI "1")])
826
827;; In HQI templates, a string like "llg<hc>" will expand to "llgh" in
828;; HImode and "llgc" in QImode.
829(define_mode_attr hc [(HI "h") (QI "c")])
830
831;; In P templates, the mode <DBL> will expand to "TI" in DImode and "DI"
832;; in SImode.
833(define_mode_attr DBL [(DI "TI") (SI "DI")])
834
835;; This attribute expands to DF for TFmode and to DD for TDmode .  It is
836;; used for Txmode splitters splitting a Txmode copy into 2 Dxmode copies.
837(define_mode_attr HALF_TMODE [(TF "DF") (TD "DD")])
838
839;; Maximum unsigned integer that fits in MODE.
840(define_mode_attr max_uint [(HI "65535") (QI "255")])
841
842;; Start and end field computations for RISBG et al.
843(define_mode_attr bfstart [(DI "s") (SI "t")])
844(define_mode_attr bfend   [(DI "e") (SI "f")])
845
846;; In place of GET_MODE_BITSIZE (<MODE>mode)
847(define_mode_attr bitsize [(DI "64") (SI "32") (HI "16") (QI "8")])
848;; 64 - bitsize
849(define_mode_attr bitoff [(DI "0") (SI "32") (HI "48") (QI "56")])
850(define_mode_attr bitoff_plus [(DI "") (SI "32+") (HI "48+") (QI "56+")])
851
852;; In place of GET_MODE_SIZE (<MODE>mode)
853(define_mode_attr modesize [(DI "8") (SI "4")])
854
855;; Allow return and simple_return to be defined from a single template.
856(define_code_iterator ANY_RETURN [return simple_return])
857
858
859
860; Condition code modes generated by vector fp comparisons.  These will
861; be used also in single element mode.
862(define_mode_iterator VFCMP [CCVEQ CCVFH CCVFHE])
863; Used with VFCMP to expand part of the mnemonic
864; For fp we have a mismatch: eq in the insn name - e in asm
865(define_mode_attr asm_fcmp [(CCVEQ "e") (CCVFH "h") (CCVFHE "he")])
866(define_mode_attr insn_cmp [(CCVEQ "eq") (CCVIH "h") (CCVIHU "hl") (CCVFH "h") (CCVFHE "he")])
867
868;; Subst pattern definitions
869(include "subst.md")
870
871(include "vector.md")
872
873;;
874;;- Compare instructions.
875;;
876
877; Test-under-Mask instructions
878
879(define_insn "*tmqi_mem"
880  [(set (reg CC_REGNUM)
881        (compare (and:QI (match_operand:QI 0 "memory_operand" "Q,S")
882                         (match_operand:QI 1 "immediate_operand" "n,n"))
883                 (match_operand:QI 2 "immediate_operand" "n,n")))]
884  "s390_match_ccmode (insn, s390_tm_ccmode (operands[1], operands[2], false))"
885  "@
886   tm\t%S0,%b1
887   tmy\t%S0,%b1"
888  [(set_attr "op_type" "SI,SIY")
889   (set_attr "cpu_facility" "*,longdisp")
890   (set_attr "z10prop" "z10_super,z10_super")])
891
892(define_insn "*tmdi_reg"
893  [(set (reg CC_REGNUM)
894        (compare (and:DI (match_operand:DI 0 "nonimmediate_operand" "d,d,d,d")
895                         (match_operand:DI 1 "immediate_operand"
896					     "N0HD0,N1HD0,N2HD0,N3HD0"))
897                 (match_operand:DI 2 "immediate_operand" "n,n,n,n")))]
898  "TARGET_ZARCH
899   && s390_match_ccmode (insn, s390_tm_ccmode (operands[1], operands[2], true))
900   && s390_single_part (operands[1], DImode, HImode, 0) >= 0"
901  "@
902   tmhh\t%0,%i1
903   tmhl\t%0,%i1
904   tmlh\t%0,%i1
905   tmll\t%0,%i1"
906  [(set_attr "op_type" "RI")
907   (set_attr "z10prop" "z10_super,z10_super,z10_super,z10_super")])
908
909(define_insn "*tmsi_reg"
910  [(set (reg CC_REGNUM)
911        (compare (and:SI (match_operand:SI 0 "nonimmediate_operand" "d,d")
912                         (match_operand:SI 1 "immediate_operand" "N0HS0,N1HS0"))
913                 (match_operand:SI 2 "immediate_operand" "n,n")))]
914  "s390_match_ccmode (insn, s390_tm_ccmode (operands[1], operands[2], true))
915   && s390_single_part (operands[1], SImode, HImode, 0) >= 0"
916  "@
917   tmh\t%0,%i1
918   tml\t%0,%i1"
919  [(set_attr "op_type" "RI")
920   (set_attr "z10prop" "z10_super,z10_super")])
921
922(define_insn "*tm<mode>_full"
923  [(set (reg CC_REGNUM)
924        (compare (match_operand:HQI 0 "register_operand" "d")
925                 (match_operand:HQI 1 "immediate_operand" "n")))]
926  "s390_match_ccmode (insn, s390_tm_ccmode (constm1_rtx, operands[1], true))"
927  "tml\t%0,<max_uint>"
928  [(set_attr "op_type" "RI")
929   (set_attr "z10prop" "z10_super")])
930
931
932;
933; Load-and-Test instructions
934;
935
936; tst(di|si) instruction pattern(s).
937
938(define_insn "*tstdi_sign"
939  [(set (reg CC_REGNUM)
940        (compare
941          (ashiftrt:DI
942            (ashift:DI
943              (subreg:DI (match_operand:SI 0 "nonimmediate_operand" "d,T") 0)
944	      (const_int 32)) (const_int 32))
945	  (match_operand:DI 1 "const0_operand" "")))
946   (set (match_operand:DI 2 "register_operand" "=d,d")
947        (sign_extend:DI (match_dup 0)))]
948  "s390_match_ccmode(insn, CCSmode) && TARGET_ZARCH"
949  "ltgfr\t%2,%0
950   ltgf\t%2,%0"
951  [(set_attr "op_type"      "RRE,RXY")
952   (set_attr "cpu_facility" "*,z10")
953   (set_attr "z10prop" "z10_super_E1,z10_super_E1") ])
954
955; ltr, lt, ltgr, ltg
956(define_insn "*tst<mode>_extimm"
957  [(set (reg CC_REGNUM)
958        (compare (match_operand:GPR 0 "nonimmediate_operand" "d,T")
959                 (match_operand:GPR 1 "const0_operand" "")))
960   (set (match_operand:GPR 2 "register_operand" "=d,d")
961        (match_dup 0))]
962  "s390_match_ccmode(insn, CCSmode) && TARGET_EXTIMM"
963  "@
964   lt<g>r\t%2,%0
965   lt<g>\t%2,%0"
966  [(set_attr "op_type" "RR<E>,RXY")
967   (set_attr "z10prop" "z10_fr_E1,z10_fwd_A3") ])
968
969; Peephole to combine a load-and-test from volatile memory which combine does
970; not do.
971(define_peephole2
972  [(set (match_operand:GPR 0 "register_operand")
973	(match_operand:GPR 2 "memory_operand"))
974   (set (reg CC_REGNUM)
975	(compare (match_dup 0) (match_operand:GPR 1 "const0_operand")))]
976  "s390_match_ccmode (peep2_next_insn (1), CCSmode) && TARGET_EXTIMM
977   && GENERAL_REG_P (operands[0])
978   && satisfies_constraint_T (operands[2])
979   && !contains_constant_pool_address_p (operands[2])"
980  [(parallel
981    [(set (reg:CCS CC_REGNUM)
982	  (compare:CCS (match_dup 2) (match_dup 1)))
983     (set (match_dup 0) (match_dup 2))])])
984
985; ltr, lt, ltgr, ltg
986(define_insn "*tst<mode>_cconly_extimm"
987  [(set (reg CC_REGNUM)
988        (compare (match_operand:GPR 0 "nonimmediate_operand" "d,T")
989                 (match_operand:GPR 1 "const0_operand" "")))
990   (clobber (match_scratch:GPR 2 "=X,d"))]
991  "s390_match_ccmode(insn, CCSmode) && TARGET_EXTIMM"
992  "@
993   lt<g>r\t%0,%0
994   lt<g>\t%2,%0"
995  [(set_attr "op_type" "RR<E>,RXY")
996   (set_attr "z10prop" "z10_fr_E1,z10_fwd_A3")])
997
998(define_insn "*tstdi"
999  [(set (reg CC_REGNUM)
1000        (compare (match_operand:DI 0 "register_operand" "d")
1001                 (match_operand:DI 1 "const0_operand" "")))
1002   (set (match_operand:DI 2 "register_operand" "=d")
1003        (match_dup 0))]
1004  "s390_match_ccmode(insn, CCSmode) && TARGET_ZARCH && !TARGET_EXTIMM"
1005  "ltgr\t%2,%0"
1006  [(set_attr "op_type" "RRE")
1007   (set_attr "z10prop" "z10_fr_E1")])
1008
1009(define_insn "*tstsi"
1010  [(set (reg CC_REGNUM)
1011        (compare (match_operand:SI 0 "nonimmediate_operand" "d,Q,S")
1012                 (match_operand:SI 1 "const0_operand" "")))
1013   (set (match_operand:SI 2 "register_operand" "=d,d,d")
1014        (match_dup 0))]
1015  "s390_match_ccmode(insn, CCSmode) && !TARGET_EXTIMM"
1016  "@
1017   ltr\t%2,%0
1018   icm\t%2,15,%S0
1019   icmy\t%2,15,%S0"
1020  [(set_attr "op_type" "RR,RS,RSY")
1021   (set_attr "cpu_facility" "*,*,longdisp")
1022   (set_attr "z10prop" "z10_fr_E1,z10_super_E1,z10_super_E1")])
1023
1024(define_insn "*tstsi_cconly"
1025  [(set (reg CC_REGNUM)
1026        (compare (match_operand:SI 0 "nonimmediate_operand" "d,Q,S")
1027                 (match_operand:SI 1 "const0_operand" "")))
1028   (clobber (match_scratch:SI 2 "=X,d,d"))]
1029  "s390_match_ccmode(insn, CCSmode)"
1030  "@
1031   ltr\t%0,%0
1032   icm\t%2,15,%S0
1033   icmy\t%2,15,%S0"
1034  [(set_attr "op_type" "RR,RS,RSY")
1035   (set_attr "cpu_facility" "*,*,longdisp")
1036   (set_attr "z10prop" "z10_fr_E1,z10_super_E1,z10_super_E1")])
1037
1038(define_insn "*tstdi_cconly_31"
1039  [(set (reg CC_REGNUM)
1040        (compare (match_operand:DI 0 "register_operand" "d")
1041                 (match_operand:DI 1 "const0_operand" "")))]
1042  "s390_match_ccmode(insn, CCSmode) && !TARGET_ZARCH"
1043  "srda\t%0,0"
1044  [(set_attr "op_type" "RS")
1045   (set_attr "atype"   "reg")])
1046
1047; ltr, ltgr
1048(define_insn "*tst<mode>_cconly2"
1049  [(set (reg CC_REGNUM)
1050        (compare (match_operand:GPR 0 "register_operand" "d")
1051                 (match_operand:GPR 1 "const0_operand" "")))]
1052  "s390_match_ccmode(insn, CCSmode)"
1053  "lt<g>r\t%0,%0"
1054  [(set_attr "op_type" "RR<E>")
1055   (set_attr "z10prop" "z10_fr_E1")])
1056
1057; tst(hi|qi) instruction pattern(s).
1058
1059(define_insn "*tst<mode>CCT"
1060  [(set (reg CC_REGNUM)
1061        (compare (match_operand:HQI 0 "nonimmediate_operand" "?Q,?S,d")
1062                 (match_operand:HQI 1 "const0_operand" "")))
1063   (set (match_operand:HQI 2 "register_operand" "=d,d,0")
1064        (match_dup 0))]
1065  "s390_match_ccmode(insn, CCTmode)"
1066  "@
1067   icm\t%2,<icm_lo>,%S0
1068   icmy\t%2,<icm_lo>,%S0
1069   tml\t%0,<max_uint>"
1070  [(set_attr "op_type" "RS,RSY,RI")
1071   (set_attr "cpu_facility" "*,longdisp,*")
1072   (set_attr "z10prop" "z10_super_E1,z10_super_E1,z10_super")])
1073
1074(define_insn "*tsthiCCT_cconly"
1075  [(set (reg CC_REGNUM)
1076        (compare (match_operand:HI 0 "nonimmediate_operand" "Q,S,d")
1077                 (match_operand:HI 1 "const0_operand" "")))
1078   (clobber (match_scratch:HI 2 "=d,d,X"))]
1079  "s390_match_ccmode(insn, CCTmode)"
1080  "@
1081   icm\t%2,3,%S0
1082   icmy\t%2,3,%S0
1083   tml\t%0,65535"
1084  [(set_attr "op_type" "RS,RSY,RI")
1085   (set_attr "cpu_facility" "*,longdisp,*")
1086   (set_attr "z10prop" "z10_super_E1,z10_super_E1,z10_super")])
1087
1088(define_insn "*tstqiCCT_cconly"
1089  [(set (reg CC_REGNUM)
1090        (compare (match_operand:QI 0 "nonimmediate_operand" "?Q,?S,d")
1091                 (match_operand:QI 1 "const0_operand" "")))]
1092  "s390_match_ccmode(insn, CCTmode)"
1093  "@
1094   cli\t%S0,0
1095   cliy\t%S0,0
1096   tml\t%0,255"
1097  [(set_attr "op_type" "SI,SIY,RI")
1098   (set_attr "cpu_facility" "*,longdisp,*")
1099   (set_attr "z10prop" "z10_super,z10_super,z10_super")])
1100
1101(define_insn "*tst<mode>"
1102  [(set (reg CC_REGNUM)
1103        (compare (match_operand:HQI 0 "s_operand" "Q,S")
1104                 (match_operand:HQI 1 "const0_operand" "")))
1105   (set (match_operand:HQI 2 "register_operand" "=d,d")
1106        (match_dup 0))]
1107  "s390_match_ccmode(insn, CCSmode)"
1108  "@
1109   icm\t%2,<icm_lo>,%S0
1110   icmy\t%2,<icm_lo>,%S0"
1111  [(set_attr "op_type" "RS,RSY")
1112   (set_attr "cpu_facility" "*,longdisp")
1113   (set_attr "z10prop" "z10_super_E1,z10_super_E1")])
1114
1115(define_insn "*tst<mode>_cconly"
1116  [(set (reg CC_REGNUM)
1117        (compare (match_operand:HQI 0 "s_operand" "Q,S")
1118                 (match_operand:HQI 1 "const0_operand" "")))
1119   (clobber (match_scratch:HQI 2 "=d,d"))]
1120  "s390_match_ccmode(insn, CCSmode)"
1121  "@
1122   icm\t%2,<icm_lo>,%S0
1123   icmy\t%2,<icm_lo>,%S0"
1124  [(set_attr "op_type" "RS,RSY")
1125   (set_attr "cpu_facility" "*,longdisp")
1126   (set_attr "z10prop" "z10_super_E1,z10_super_E1")])
1127
1128
1129; Compare (equality) instructions
1130
1131(define_insn "*cmpdi_cct"
1132  [(set (reg CC_REGNUM)
1133        (compare (match_operand:DI 0 "nonimmediate_operand" "%d,d,d,d,Q")
1134                 (match_operand:DI 1 "general_operand" "d,K,Os,T,BQ")))]
1135  "s390_match_ccmode (insn, CCTmode) && TARGET_ZARCH"
1136  "@
1137   cgr\t%0,%1
1138   cghi\t%0,%h1
1139   cgfi\t%0,%1
1140   cg\t%0,%1
1141   #"
1142  [(set_attr "op_type" "RRE,RI,RIL,RXY,SS")
1143   (set_attr "z10prop" "z10_super_c,z10_super,z10_super,z10_super,*")])
1144
1145(define_insn "*cmpsi_cct"
1146  [(set (reg CC_REGNUM)
1147        (compare (match_operand:SI 0 "nonimmediate_operand" "%d,d,d,d,d,Q")
1148                 (match_operand:SI 1 "general_operand" "d,K,Os,R,T,BQ")))]
1149  "s390_match_ccmode (insn, CCTmode)"
1150  "@
1151   cr\t%0,%1
1152   chi\t%0,%h1
1153   cfi\t%0,%1
1154   c\t%0,%1
1155   cy\t%0,%1
1156   #"
1157  [(set_attr "op_type" "RR,RI,RIL,RX,RXY,SS")
1158   (set_attr "cpu_facility" "*,*,*,*,longdisp,*")
1159   (set_attr "z10prop" "z10_super_c,z10_super,z10_super,z10_super,z10_super,*")])
1160
1161; Compare (signed) instructions
1162
1163(define_insn "*cmpdi_ccs_sign"
1164  [(set (reg CC_REGNUM)
1165        (compare (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand"
1166						     "d,T,b"))
1167                 (match_operand:DI 0 "register_operand" "d, d,d")))]
1168  "s390_match_ccmode(insn, CCSRmode) && TARGET_ZARCH"
1169  "@
1170   cgfr\t%0,%1
1171   cgf\t%0,%1
1172   cgfrl\t%0,%1"
1173  [(set_attr "op_type"      "RRE,RXY,RIL")
1174   (set_attr "z10prop" "z10_c,*,*")
1175   (set_attr "type"         "*,*,larl")
1176   (set_attr "relative_long" "*,*,yes")])
1177
1178
1179
1180(define_insn "*cmpsi_ccs_sign"
1181  [(set (reg CC_REGNUM)
1182        (compare (sign_extend:SI (match_operand:HI 1 "memory_operand" "R,T,b"))
1183                 (match_operand:SI 0 "register_operand" "d,d,d")))]
1184  "s390_match_ccmode(insn, CCSRmode)"
1185  "@
1186   ch\t%0,%1
1187   chy\t%0,%1
1188   chrl\t%0,%1"
1189  [(set_attr "op_type"      "RX,RXY,RIL")
1190   (set_attr "cpu_facility" "*,longdisp,z10")
1191   (set_attr "type"         "*,*,larl")
1192   (set_attr "z196prop" "z196_cracked,z196_cracked,z196_cracked")
1193   (set_attr "relative_long" "*,*,yes")])
1194
1195(define_insn "*cmphi_ccs_z10"
1196  [(set (reg CC_REGNUM)
1197        (compare (match_operand:HI 0 "s_operand"         "Q")
1198                 (match_operand:HI 1 "immediate_operand" "K")))]
1199  "s390_match_ccmode(insn, CCSmode) && TARGET_Z10"
1200  "chhsi\t%0,%1"
1201  [(set_attr "op_type" "SIL")
1202   (set_attr "z196prop" "z196_cracked")])
1203
1204(define_insn "*cmpdi_ccs_signhi_rl"
1205  [(set (reg CC_REGNUM)
1206	(compare (sign_extend:DI (match_operand:HI 1 "memory_operand" "T,b"))
1207		 (match_operand:GPR 0 "register_operand"  "d,d")))]
1208  "s390_match_ccmode(insn, CCSRmode) && TARGET_Z10"
1209  "@
1210   cgh\t%0,%1
1211   cghrl\t%0,%1"
1212  [(set_attr "op_type" "RXY,RIL")
1213   (set_attr "type"    "*,larl")
1214   (set_attr "relative_long" "*,yes")])
1215
1216; cr, chi, cfi, c, cy, cgr, cghi, cgfi, cg, chsi, cghsi, crl, cgrl
1217(define_insn "*cmp<mode>_ccs"
1218  [(set (reg CC_REGNUM)
1219        (compare (match_operand:GPR 0 "nonimmediate_operand"
1220                                      "d,d,Q, d,d,d,d")
1221                 (match_operand:GPR 1 "general_operand"
1222                                      "d,K,K,Os,R,T,b")))]
1223  "s390_match_ccmode(insn, CCSmode)"
1224  "@
1225   c<g>r\t%0,%1
1226   c<g>hi\t%0,%h1
1227   c<g>hsi\t%0,%h1
1228   c<g>fi\t%0,%1
1229   c<g>\t%0,%1
1230   c<y>\t%0,%1
1231   c<g>rl\t%0,%1"
1232  [(set_attr "op_type" "RR<E>,RI,SIL,RIL,RX<Y>,RXY,RIL")
1233   (set_attr "cpu_facility" "*,*,z10,extimm,*,longdisp,z10")
1234   (set_attr "type" "*,*,*,*,*,*,larl")
1235   (set_attr "z10prop" "z10_super_c,z10_super,z10_super,z10_super,z10_super,z10_super,z10_super")
1236   (set_attr "relative_long" "*,*,*,*,*,*,yes")])
1237
1238
1239; Compare (unsigned) instructions
1240
1241(define_insn "*cmpsi_ccu_zerohi_rlsi"
1242  [(set (reg CC_REGNUM)
1243 	(compare (zero_extend:SI (mem:HI (match_operand:SI 1
1244					  "larl_operand" "X")))
1245		 (match_operand:SI 0 "register_operand" "d")))]
1246  "s390_match_ccmode(insn, CCURmode) && TARGET_Z10"
1247  "clhrl\t%0,%1"
1248  [(set_attr "op_type" "RIL")
1249   (set_attr "type"    "larl")
1250   (set_attr "z10prop" "z10_super")
1251   (set_attr "relative_long" "yes")])
1252
1253; clhrl, clghrl
1254(define_insn "*cmp<GPR:mode>_ccu_zerohi_rldi"
1255  [(set (reg CC_REGNUM)
1256 	(compare (zero_extend:GPR (mem:HI (match_operand:DI 1
1257					  "larl_operand" "X")))
1258		 (match_operand:GPR 0 "register_operand" "d")))]
1259  "s390_match_ccmode(insn, CCURmode) && TARGET_Z10"
1260  "cl<g>hrl\t%0,%1"
1261  [(set_attr "op_type" "RIL")
1262   (set_attr "type"    "larl")
1263   (set_attr "z10prop" "z10_super")
1264   (set_attr "relative_long" "yes")])
1265
1266(define_insn "*cmpdi_ccu_zero"
1267  [(set (reg CC_REGNUM)
1268        (compare (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand"
1269                                                        "d,T,b"))
1270                 (match_operand:DI 0 "register_operand" "d,d,d")))]
1271  "s390_match_ccmode (insn, CCURmode) && TARGET_ZARCH"
1272  "@
1273   clgfr\t%0,%1
1274   clgf\t%0,%1
1275   clgfrl\t%0,%1"
1276  [(set_attr "op_type"      "RRE,RXY,RIL")
1277   (set_attr "cpu_facility" "*,*,z10")
1278   (set_attr "type"         "*,*,larl")
1279   (set_attr "z10prop" "z10_super_c,z10_super_E1,z10_super")
1280   (set_attr "relative_long" "*,*,yes")])
1281
1282(define_insn "*cmpdi_ccu"
1283  [(set (reg CC_REGNUM)
1284        (compare (match_operand:DI 0 "nonimmediate_operand"
1285                                     "d, d,d,Q,d, Q,BQ")
1286                 (match_operand:DI 1 "general_operand"
1287                                     "d,Op,b,D,T,BQ,Q")))]
1288  "s390_match_ccmode (insn, CCUmode) && TARGET_ZARCH"
1289  "@
1290   clgr\t%0,%1
1291   clgfi\t%0,%1
1292   clgrl\t%0,%1
1293   clghsi\t%0,%x1
1294   clg\t%0,%1
1295   #
1296   #"
1297  [(set_attr "op_type" "RRE,RIL,RIL,SIL,RXY,SS,SS")
1298   (set_attr "cpu_facility" "*,extimm,z10,z10,*,*,*")
1299   (set_attr "type"         "*,*,larl,*,*,*,*")
1300   (set_attr "z10prop" "z10_super_c,z10_super,z10_super,z10_super,z10_super,*,*")
1301   (set_attr "relative_long" "*,*,yes,*,*,*,*")])
1302
1303(define_insn "*cmpsi_ccu"
1304  [(set (reg CC_REGNUM)
1305        (compare (match_operand:SI 0 "nonimmediate_operand" "d, d,d,Q,d,d, Q,BQ")
1306                 (match_operand:SI 1 "general_operand"      "d,Os,b,D,R,T,BQ, Q")))]
1307  "s390_match_ccmode (insn, CCUmode)"
1308  "@
1309   clr\t%0,%1
1310   clfi\t%0,%o1
1311   clrl\t%0,%1
1312   clfhsi\t%0,%x1
1313   cl\t%0,%1
1314   cly\t%0,%1
1315   #
1316   #"
1317  [(set_attr "op_type" "RR,RIL,RIL,SIL,RX,RXY,SS,SS")
1318   (set_attr "cpu_facility" "*,extimm,z10,z10,*,longdisp,*,*")
1319   (set_attr "type"         "*,*,larl,*,*,*,*,*")
1320   (set_attr "z10prop" "z10_super_c,z10_super,z10_super,z10_super,z10_super,z10_super,*,*")
1321   (set_attr "relative_long" "*,*,yes,*,*,*,*,*")])
1322
1323(define_insn "*cmphi_ccu"
1324  [(set (reg CC_REGNUM)
1325        (compare (match_operand:HI 0 "nonimmediate_operand" "d,d,Q,Q,BQ")
1326                 (match_operand:HI 1 "general_operand"      "Q,S,D,BQ,Q")))]
1327  "s390_match_ccmode (insn, CCUmode)
1328   && !register_operand (operands[1], HImode)"
1329  "@
1330   clm\t%0,3,%S1
1331   clmy\t%0,3,%S1
1332   clhhsi\t%0,%1
1333   #
1334   #"
1335  [(set_attr "op_type" "RS,RSY,SIL,SS,SS")
1336   (set_attr "cpu_facility" "*,longdisp,z10,*,*")
1337   (set_attr "z10prop" "*,*,z10_super,*,*")])
1338
1339(define_insn "*cmpqi_ccu"
1340  [(set (reg CC_REGNUM)
1341        (compare (match_operand:QI 0 "nonimmediate_operand" "d,d,Q,S,Q,BQ")
1342                 (match_operand:QI 1 "general_operand" "Q,S,n,n,BQ,Q")))]
1343  "s390_match_ccmode (insn, CCUmode)
1344   && !register_operand (operands[1], QImode)"
1345  "@
1346   clm\t%0,1,%S1
1347   clmy\t%0,1,%S1
1348   cli\t%S0,%b1
1349   cliy\t%S0,%b1
1350   #
1351   #"
1352  [(set_attr "op_type" "RS,RSY,SI,SIY,SS,SS")
1353   (set_attr "cpu_facility" "*,longdisp,*,longdisp,*,*")
1354   (set_attr "z10prop" "*,*,z10_super,z10_super,*,*")])
1355
1356
1357; Block compare (CLC) instruction patterns.
1358
1359(define_insn "*clc"
1360  [(set (reg CC_REGNUM)
1361        (compare (match_operand:BLK 0 "memory_operand" "Q")
1362                 (match_operand:BLK 1 "memory_operand" "Q")))
1363   (use (match_operand 2 "const_int_operand" "n"))]
1364  "s390_match_ccmode (insn, CCUmode)
1365   && INTVAL (operands[2]) >= 1 && INTVAL (operands[2]) <= 256"
1366  "clc\t%O0(%2,%R0),%S1"
1367  [(set_attr "op_type" "SS")])
1368
1369(define_split
1370  [(set (reg CC_REGNUM)
1371        (compare (match_operand 0 "memory_operand" "")
1372                 (match_operand 1 "memory_operand" "")))]
1373  "reload_completed
1374   && s390_match_ccmode (insn, CCUmode)
1375   && GET_MODE (operands[0]) == GET_MODE (operands[1])
1376   && GET_MODE_SIZE (GET_MODE (operands[0])) > 0"
1377  [(parallel
1378    [(set (match_dup 0) (match_dup 1))
1379     (use (match_dup 2))])]
1380{
1381  operands[2] = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[0])));
1382  operands[0] = adjust_address (operands[0], BLKmode, 0);
1383  operands[1] = adjust_address (operands[1], BLKmode, 0);
1384
1385  operands[1] = gen_rtx_COMPARE (GET_MODE (SET_DEST (PATTERN (curr_insn))),
1386				 operands[0], operands[1]);
1387  operands[0] = SET_DEST (PATTERN (curr_insn));
1388})
1389
1390
1391; (TF|DF|SF|TD|DD|SD) instructions
1392
1393
1394; FIXME: load and test instructions turn SNaN into QNaN what is not
1395; acceptable if the target will be used afterwards.  On the other hand
1396; they are quite convenient for implementing comparisons with 0.0. So
1397; try to enable them via splitter/peephole if the value isn't needed anymore.
1398; See testcases: load-and-test-fp-1.c and load-and-test-fp-2.c
1399
1400; ltxbr, ltdbr, ltebr, ltxtr, ltdtr
1401(define_insn "*cmp<mode>_ccs_0"
1402  [(set (reg CC_REGNUM)
1403	(compare (match_operand:FP 0 "register_operand"  "f")
1404		 (match_operand:FP 1 "const0_operand"    "")))
1405   (clobber (match_operand:FP      2 "register_operand" "=0"))]
1406  "s390_match_ccmode(insn, CCSmode) && TARGET_HARD_FLOAT"
1407  "lt<xde><bt>r\t%0,%0"
1408   [(set_attr "op_type" "RRE")
1409    (set_attr "type"  "fsimp<mode>")])
1410
1411; VX: TFmode in FPR pairs: use cxbr instead of wfcxb
1412; cxtr, cdtr, cxbr, cdbr, cebr, cdb, ceb, wfcsb, wfcdb
1413(define_insn "*cmp<mode>_ccs"
1414  [(set (reg CC_REGNUM)
1415        (compare (match_operand:FP 0 "register_operand" "f,f,v,v")
1416                 (match_operand:FP 1 "general_operand"  "f,R,v,v")))]
1417  "s390_match_ccmode(insn, CCSmode) && TARGET_HARD_FLOAT"
1418  "@
1419   c<xde><bt>r\t%0,%1
1420   c<xde>b\t%0,%1
1421   wfcdb\t%0,%1
1422   wfcsb\t%0,%1"
1423  [(set_attr "op_type" "RRE,RXE,VRR,VRR")
1424   (set_attr "cpu_facility" "*,*,vx,vxe")
1425   (set_attr "enabled" "*,<DSF>,<DF>,<SF>")])
1426
1427(define_insn "*cmp<mode>_ccsfps"
1428  [(set (reg CC_REGNUM)
1429	(compare (match_operand:FP 0 "register_operand" "f,f,v,v")
1430		 (match_operand:FP 1 "general_operand"  "f,R,v,v")))]
1431  "s390_match_ccmode (insn, CCSFPSmode) && TARGET_HARD_FLOAT"
1432  "@
1433   k<xde><bt>r\t%0,%1
1434   k<xde>b\t%0,%1
1435   wfkdb\t%0,%1
1436   wfksb\t%0,%1"
1437  [(set_attr "op_type" "RRE,RXE,VRR,VRR")
1438   (set_attr "cpu_facility" "*,*,vx,vxe")
1439   (set_attr "enabled" "*,<DSF>,<DF>,<SF>")])
1440
1441; Compare and Branch instructions
1442
1443; cij, cgij, crj, cgrj, cfi, cgfi, cr, cgr
1444; The following instructions do a complementary access of their second
1445; operand (z01 only): crj_c, cgrjc, cr, cgr
1446(define_insn "*cmp_and_br_signed_<mode>"
1447  [(set (pc)
1448	(if_then_else (match_operator 0 "s390_signed_integer_comparison"
1449			[(match_operand:GPR 1 "register_operand"  "d,d")
1450			 (match_operand:GPR 2 "nonmemory_operand" "d,C")])
1451		      (label_ref (match_operand 3 "" ""))
1452		      (pc)))
1453   (clobber (reg:CC CC_REGNUM))]
1454  "TARGET_Z10 && !TARGET_AVOID_CMP_AND_BRANCH"
1455{
1456  if (get_attr_length (insn) == 6)
1457    return which_alternative ?
1458      "c<g>ij%C0\t%1,%c2,%l3" : "c<g>rj%C0\t%1,%2,%l3";
1459  else
1460    return which_alternative ?
1461      "c<g>fi\t%1,%c2\;jg%C0\t%l3" : "c<g>r\t%1,%2\;jg%C0\t%l3";
1462}
1463  [(set_attr "op_type" "RIE")
1464   (set_attr "type"    "branch")
1465   (set_attr "z10prop" "z10_super_c,z10_super")
1466   (set (attr "length")
1467        (if_then_else (lt (abs (minus (pc) (match_dup 3))) (const_int 60000))
1468                      (const_int 6) (const_int 12)))]) ; 8 byte for cr/jg
1469                                                       ; 10 byte for cgr/jg
1470
1471; clij, clgij, clrj, clgrj, clfi, clgfi, clr, clgr
1472; The following instructions do a complementary access of their second
1473; operand (z10 only): clrj, clgrj, clr, clgr
1474(define_insn "*cmp_and_br_unsigned_<mode>"
1475  [(set (pc)
1476	(if_then_else (match_operator 0 "s390_unsigned_integer_comparison"
1477			[(match_operand:GPR 1 "register_operand"  "d,d")
1478			 (match_operand:GPR 2 "nonmemory_operand" "d,I")])
1479		      (label_ref (match_operand 3 "" ""))
1480		      (pc)))
1481   (clobber (reg:CC CC_REGNUM))]
1482  "TARGET_Z10 && !TARGET_AVOID_CMP_AND_BRANCH"
1483{
1484  if (get_attr_length (insn) == 6)
1485    return which_alternative ?
1486      "cl<g>ij%C0\t%1,%b2,%l3" : "cl<g>rj%C0\t%1,%2,%l3";
1487  else
1488    return which_alternative ?
1489      "cl<g>fi\t%1,%b2\;jg%C0\t%l3" : "cl<g>r\t%1,%2\;jg%C0\t%l3";
1490}
1491  [(set_attr "op_type" "RIE")
1492   (set_attr "type"    "branch")
1493   (set_attr "z10prop" "z10_super_c,z10_super")
1494   (set (attr "length")
1495        (if_then_else (lt (abs (minus (pc) (match_dup 3))) (const_int 60000))
1496                      (const_int 6) (const_int 12)))]) ; 8 byte for clr/jg
1497                                                       ; 10 byte for clgr/jg
1498
1499; And now the same two patterns as above but with a negated CC mask.
1500
1501; cij, cgij, crj, cgrj, cfi, cgfi, cr, cgr
1502; The following instructions do a complementary access of their second
1503; operand (z01 only): crj_c, cgrjc, cr, cgr
1504(define_insn "*icmp_and_br_signed_<mode>"
1505  [(set (pc)
1506	(if_then_else (match_operator 0 "s390_signed_integer_comparison"
1507			[(match_operand:GPR 1 "register_operand"  "d,d")
1508			 (match_operand:GPR 2 "nonmemory_operand" "d,C")])
1509		      (pc)
1510		      (label_ref (match_operand 3 "" ""))))
1511   (clobber (reg:CC CC_REGNUM))]
1512  "TARGET_Z10 && !TARGET_AVOID_CMP_AND_BRANCH"
1513{
1514  if (get_attr_length (insn) == 6)
1515    return which_alternative ?
1516      "c<g>ij%D0\t%1,%c2,%l3" : "c<g>rj%D0\t%1,%2,%l3";
1517  else
1518    return which_alternative ?
1519      "c<g>fi\t%1,%c2\;jg%D0\t%l3" : "c<g>r\t%1,%2\;jg%D0\t%l3";
1520}
1521  [(set_attr "op_type" "RIE")
1522   (set_attr "type"    "branch")
1523   (set_attr "z10prop" "z10_super_c,z10_super")
1524   (set (attr "length")
1525        (if_then_else (lt (abs (minus (pc) (match_dup 3))) (const_int 60000))
1526                      (const_int 6) (const_int 12)))]) ; 8 byte for cr/jg
1527                                                       ; 10 byte for cgr/jg
1528
1529; clij, clgij, clrj, clgrj, clfi, clgfi, clr, clgr
1530; The following instructions do a complementary access of their second
1531; operand (z10 only): clrj, clgrj, clr, clgr
1532(define_insn "*icmp_and_br_unsigned_<mode>"
1533  [(set (pc)
1534	(if_then_else (match_operator 0 "s390_unsigned_integer_comparison"
1535			[(match_operand:GPR 1 "register_operand"  "d,d")
1536			 (match_operand:GPR 2 "nonmemory_operand" "d,I")])
1537		      (pc)
1538		      (label_ref (match_operand 3 "" ""))))
1539   (clobber (reg:CC CC_REGNUM))]
1540  "TARGET_Z10 && !TARGET_AVOID_CMP_AND_BRANCH"
1541{
1542  if (get_attr_length (insn) == 6)
1543    return which_alternative ?
1544      "cl<g>ij%D0\t%1,%b2,%l3" : "cl<g>rj%D0\t%1,%2,%l3";
1545  else
1546    return which_alternative ?
1547      "cl<g>fi\t%1,%b2\;jg%D0\t%l3" : "cl<g>r\t%1,%2\;jg%D0\t%l3";
1548}
1549  [(set_attr "op_type" "RIE")
1550   (set_attr "type"    "branch")
1551   (set_attr "z10prop" "z10_super_c,z10_super")
1552   (set (attr "length")
1553        (if_then_else (lt (abs (minus (pc) (match_dup 3))) (const_int 60000))
1554                      (const_int 6) (const_int 12)))]) ; 8 byte for clr/jg
1555                                                       ; 10 byte for clgr/jg
1556
1557;;
1558;;- Move instructions.
1559;;
1560
1561;
1562; movti instruction pattern(s).
1563;
1564
1565
1566; Separate out the register pair alternative since constraints (P) are
1567; not able to deal with const_wide_int's.  But predicates do.
1568(define_insn "*movti_bigconst"
1569  [(set (match_operand:TI 0 "register_operand"              "=d")
1570        (match_operand:TI 1 "reload_const_wide_int_operand" ""))]
1571  "TARGET_ZARCH"
1572  "#")
1573
1574; FIXME: More constants are possible by enabling jxx, jyy constraints
1575; for TImode (use double-int for the calculations)
1576(define_insn "movti"
1577  [(set (match_operand:TI 0 "nonimmediate_operand" "=d,S,v,  v,  v,v,d,v,R,d,    d, d,    d, d,o")
1578        (match_operand:TI 1 "general_operand"      " S,d,v,j00,jm1,d,v,R,v,K,NxHD0,Os,NxSD0,dT,d"))]
1579  "TARGET_ZARCH"
1580  "@
1581   lmg\t%0,%N0,%S1
1582   stmg\t%1,%N1,%S0
1583   vlr\t%v0,%v1
1584   vzero\t%v0
1585   vone\t%v0
1586   vlvgp\t%v0,%1,%N1
1587   #
1588   vl\t%v0,%1%A1
1589   vst\t%v1,%0%A0
1590   #
1591   #
1592   #
1593   #
1594   #
1595   #"
1596  [(set_attr "op_type" "RSY,RSY,VRR,VRI,VRI,VRR,*,VRX,VRX,*,*,*,*,*,*")
1597   (set_attr "type" "lm,stm,*,*,*,*,*,*,*,*,*,*,*,*,*")
1598   (set_attr "cpu_facility" "*,*,vx,vx,vx,vx,vx,vx,vx,*,*,*,extimm,*,*")])
1599
1600(define_split
1601  [(set (match_operand:TI 0 "nonimmediate_operand" "")
1602        (match_operand:TI 1 "general_operand" ""))]
1603  "TARGET_ZARCH && reload_completed
1604   && !s_operand (operands[0], TImode)
1605   && !s_operand (operands[1], TImode)
1606   && s390_split_ok_p (operands[0], operands[1], TImode, 0)"
1607  [(set (match_dup 2) (match_dup 4))
1608   (set (match_dup 3) (match_dup 5))]
1609{
1610  operands[2] = operand_subword (operands[0], 0, 0, TImode);
1611  operands[3] = operand_subword (operands[0], 1, 0, TImode);
1612  operands[4] = operand_subword (operands[1], 0, 0, TImode);
1613  operands[5] = operand_subword (operands[1], 1, 0, TImode);
1614})
1615
1616(define_split
1617  [(set (match_operand:TI 0 "nonimmediate_operand" "")
1618        (match_operand:TI 1 "general_operand" ""))]
1619  "TARGET_ZARCH && reload_completed
1620   && !s_operand (operands[0], TImode)
1621   && !s_operand (operands[1], TImode)
1622   && s390_split_ok_p (operands[0], operands[1], TImode, 1)"
1623  [(set (match_dup 2) (match_dup 4))
1624   (set (match_dup 3) (match_dup 5))]
1625{
1626  operands[2] = operand_subword (operands[0], 1, 0, TImode);
1627  operands[3] = operand_subword (operands[0], 0, 0, TImode);
1628  operands[4] = operand_subword (operands[1], 1, 0, TImode);
1629  operands[5] = operand_subword (operands[1], 0, 0, TImode);
1630})
1631
1632; Use part of the TImode target reg to perform the address
1633; calculation.  If the TImode value is supposed to be copied into a VR
1634; this splitter is not necessary.
1635(define_split
1636  [(set (match_operand:TI 0 "register_operand" "")
1637        (match_operand:TI 1 "memory_operand" ""))]
1638  "TARGET_ZARCH && reload_completed
1639   && !VECTOR_REG_P (operands[0])
1640   && !s_operand (operands[1], VOIDmode)"
1641  [(set (match_dup 0) (match_dup 1))]
1642{
1643  rtx addr = operand_subword (operands[0], 1, 0, TImode);
1644  addr = gen_lowpart (Pmode, addr);
1645  s390_load_address (addr, XEXP (operands[1], 0));
1646  operands[1] = replace_equiv_address (operands[1], addr);
1647})
1648
1649
1650; Split a VR -> GPR TImode move into 2 vector load GR from VR element.
1651; For the higher order bits we do simply a DImode move while the
1652; second part is done via vec extract.  Both will end up as vlgvg.
1653(define_split
1654  [(set (match_operand:TI 0 "register_operand" "")
1655        (match_operand:TI 1 "register_operand" ""))]
1656  "TARGET_VX && reload_completed
1657   && GENERAL_REG_P (operands[0])
1658   && VECTOR_REG_P (operands[1])"
1659  [(set (match_dup 2) (match_dup 4))
1660   (set (match_dup 3) (unspec:DI [(match_dup 5) (const_int 1)]
1661				 UNSPEC_VEC_EXTRACT))]
1662{
1663  operands[2] = operand_subword (operands[0], 0, 0, TImode);
1664  operands[3] = operand_subword (operands[0], 1, 0, TImode);
1665  operands[4] = gen_rtx_REG (DImode, REGNO (operands[1]));
1666  operands[5] = gen_rtx_REG (V2DImode, REGNO (operands[1]));
1667})
1668
1669;
1670; Patterns used for secondary reloads
1671;
1672
1673; z10 provides move instructions accepting larl memory operands.
1674; Unfortunately there is no such variant for QI, TI and FP mode moves.
1675; These patterns are also used for unaligned SI and DI accesses.
1676
1677(define_expand "reload<ALL:mode><P:mode>_tomem_z10"
1678  [(parallel [(match_operand:ALL 0 "memory_operand"   "")
1679	      (match_operand:ALL 1 "register_operand" "=d")
1680	      (match_operand:P   2 "register_operand" "=&a")])]
1681  "TARGET_Z10"
1682{
1683  s390_reload_symref_address (operands[1], operands[0], operands[2], 1);
1684  DONE;
1685})
1686
1687(define_expand "reload<ALL:mode><P:mode>_toreg_z10"
1688  [(parallel [(match_operand:ALL 0 "register_operand" "=d")
1689	      (match_operand:ALL 1 "memory_operand"   "")
1690	      (match_operand:P   2 "register_operand" "=a")])]
1691  "TARGET_Z10"
1692{
1693  s390_reload_symref_address (operands[0], operands[1], operands[2], 0);
1694  DONE;
1695})
1696
1697(define_expand "reload<P:mode>_larl_odd_addend_z10"
1698  [(parallel [(match_operand:P 0 "register_operand" "=d")
1699	      (match_operand:P 1 "larl_operand"     "")
1700	      (match_operand:P 2 "register_operand" "=a")])]
1701  "TARGET_Z10"
1702{
1703  s390_reload_larl_operand (operands[0], operands[1], operands[2]);
1704  DONE;
1705})
1706
1707; Handles loading a PLUS (load address) expression
1708
1709(define_expand "reload<mode>_plus"
1710  [(parallel [(match_operand:P 0 "register_operand"  "=a")
1711              (match_operand:P 1 "s390_plus_operand" "")
1712              (match_operand:P 2 "register_operand"  "=&a")])]
1713  ""
1714{
1715  s390_expand_plus_operand (operands[0], operands[1], operands[2]);
1716  DONE;
1717})
1718
1719; Not all the indirect memory access instructions support the full
1720; format (long disp + index + base).  So whenever a move from/to such
1721; an address is required and the instruction cannot deal with it we do
1722; a load address into a scratch register first and use this as the new
1723; base register.
1724; This in particular is used for:
1725; - non-offsetable memory accesses for multiword moves
1726; - full vector reg moves with long displacements
1727
1728(define_expand "reload<mode>_la_in"
1729  [(parallel [(match_operand 0   "register_operand" "")
1730              (match_operand 1   "" "")
1731              (match_operand:P 2 "register_operand" "=&a")])]
1732  ""
1733{
1734  gcc_assert (MEM_P (operands[1]));
1735  s390_load_address (operands[2], find_replacement (&XEXP (operands[1], 0)));
1736  operands[1] = replace_equiv_address (operands[1], operands[2]);
1737  emit_move_insn (operands[0], operands[1]);
1738  DONE;
1739})
1740
1741(define_expand "reload<mode>_la_out"
1742  [(parallel [(match_operand   0 "" "")
1743              (match_operand   1 "register_operand" "")
1744              (match_operand:P 2 "register_operand" "=&a")])]
1745  ""
1746{
1747  gcc_assert (MEM_P (operands[0]));
1748  s390_load_address (operands[2], find_replacement (&XEXP (operands[0], 0)));
1749  operands[0] = replace_equiv_address (operands[0], operands[2]);
1750  emit_move_insn (operands[0], operands[1]);
1751  DONE;
1752})
1753
1754(define_expand "reload<mode>_PIC_addr"
1755  [(parallel [(match_operand   0 "register_operand" "=d")
1756	      (match_operand   1 "larl_operand"     "")
1757	      (match_operand:P 2 "register_operand" "=a")])]
1758  ""
1759{
1760  rtx new_rtx = legitimize_pic_address (operands[1], operands[2]);
1761  emit_move_insn (operands[0], new_rtx);
1762})
1763
1764;
1765; movdi instruction pattern(s).
1766;
1767
1768(define_expand "movdi"
1769  [(set (match_operand:DI 0 "general_operand" "")
1770        (match_operand:DI 1 "general_operand" ""))]
1771  ""
1772{
1773  /* Handle symbolic constants.  */
1774  if (TARGET_64BIT
1775      && (SYMBOLIC_CONST (operands[1])
1776	  || (GET_CODE (operands[1]) == PLUS
1777	      && XEXP (operands[1], 0) == pic_offset_table_rtx
1778	      && SYMBOLIC_CONST (XEXP (operands[1], 1)))))
1779    emit_symbolic_move (operands);
1780})
1781
1782(define_insn "*movdi_64"
1783  [(set (match_operand:DI 0 "nonimmediate_operand"
1784         "=d,    d,    d,    d,    d, d,    d,    d,f,d,d,d,d,d,T,!*f,!*f,!*f,!R,!T,b,Q,d,t,Q,t,v,v,v,d,v,R,d")
1785        (match_operand:DI 1 "general_operand"
1786         " K,N0HD0,N1HD0,N2HD0,N3HD0,Os,N0SD0,N1SD0,d,f,L,b,d,T,d, *f,  R,  T,*f,*f,d,K,t,d,t,Q,K,v,d,v,R,v,ZL"))]
1787  "TARGET_ZARCH"
1788  "@
1789   lghi\t%0,%h1
1790   llihh\t%0,%i1
1791   llihl\t%0,%i1
1792   llilh\t%0,%i1
1793   llill\t%0,%i1
1794   lgfi\t%0,%1
1795   llihf\t%0,%k1
1796   llilf\t%0,%k1
1797   ldgr\t%0,%1
1798   lgdr\t%0,%1
1799   lay\t%0,%a1
1800   lgrl\t%0,%1
1801   lgr\t%0,%1
1802   lg\t%0,%1
1803   stg\t%1,%0
1804   ldr\t%0,%1
1805   ld\t%0,%1
1806   ldy\t%0,%1
1807   std\t%1,%0
1808   stdy\t%1,%0
1809   stgrl\t%1,%0
1810   mvghi\t%0,%1
1811   #
1812   #
1813   stam\t%1,%N1,%S0
1814   lam\t%0,%N0,%S1
1815   vleig\t%v0,%h1,0
1816   vlr\t%v0,%v1
1817   vlvgg\t%v0,%1,0
1818   vlgvg\t%0,%v1,0
1819   vleg\t%v0,%1,0
1820   vsteg\t%v1,%0,0
1821   larl\t%0,%1"
1822  [(set_attr "op_type" "RI,RI,RI,RI,RI,RIL,RIL,RIL,RRE,RRE,RXY,RIL,RRE,RXY,
1823                        RXY,RR,RX,RXY,RX,RXY,RIL,SIL,*,*,RS,RS,VRI,VRR,VRS,VRS,
1824                        VRX,VRX,RIL")
1825   (set_attr "type" "*,*,*,*,*,*,*,*,floaddf,floaddf,la,larl,lr,load,store,
1826                     floaddf,floaddf,floaddf,fstoredf,fstoredf,larl,*,*,*,*,
1827                     *,*,*,*,*,*,*,larl")
1828   (set_attr "cpu_facility" "*,*,*,*,*,extimm,extimm,extimm,dfp,dfp,longdisp,
1829                             z10,*,*,*,*,*,longdisp,*,longdisp,
1830                             z10,z10,*,*,*,*,vx,vx,vx,vx,vx,vx,*")
1831   (set_attr "z10prop" "z10_fwd_A1,
1832                        z10_fwd_E1,
1833                        z10_fwd_E1,
1834                        z10_fwd_E1,
1835                        z10_fwd_E1,
1836                        z10_fwd_A1,
1837                        z10_fwd_E1,
1838                        z10_fwd_E1,
1839                        *,
1840                        *,
1841                        z10_fwd_A1,
1842                        z10_fwd_A3,
1843                        z10_fr_E1,
1844                        z10_fwd_A3,
1845                        z10_rec,
1846                        *,
1847                        *,
1848                        *,
1849                        *,
1850                        *,
1851                        z10_rec,
1852                        z10_super,
1853                        *,
1854                        *,
1855                        *,
1856                        *,*,*,*,*,*,*,
1857                        z10_super_A1")
1858   (set_attr "relative_long" "*,*,*,*,*,*,*,*,*,*,
1859                              *,yes,*,*,*,*,*,*,*,*,
1860                              yes,*,*,*,*,*,*,*,*,*,
1861                              *,*,yes")
1862])
1863
1864; Splitters for loading TLS pointer from UNSPEC_GET_TP.
1865; UNSPEC_GET_TP is used instead of %a0:P, since the latter is a hard register,
1866; and those are not handled by Partial Redundancy Elimination (gcse.c), which
1867; results in generation of redundant thread pointer loads.
1868
1869(define_insn_and_split "*get_tp_31"
1870  [(set (match_operand:SI 0 "register_operand" "=r")
1871	(unspec:SI [(match_operand:SI 1 "register_operand" "t")]
1872		   UNSPEC_GET_TP))]
1873  ""
1874  "#"
1875  "&& reload_completed"
1876  [(set (match_dup 0) (match_dup 1))])
1877
1878(define_insn_and_split "*get_tp_64"
1879  [(set (match_operand:DI 0 "register_operand" "=r")
1880	(unspec:DI [(match_operand:DI 1 "register_operand" "t")]
1881		   UNSPEC_GET_TP))]
1882  "TARGET_ZARCH"
1883  "#"
1884  "&& reload_completed"
1885  [(set (match_dup 2) (match_dup 3))
1886   (set (match_dup 0) (ashift:DI (match_dup 0) (const_int 32)))
1887   (set (strict_low_part (match_dup 2)) (match_dup 4))]
1888  "operands[2] = gen_lowpart (SImode, operands[0]);
1889   s390_split_access_reg (operands[1], &operands[4], &operands[3]);")
1890
1891; Splitters for storing TLS pointer to %a0:DI.
1892
1893(define_split
1894  [(set (match_operand:DI 0 "register_operand" "")
1895        (match_operand:DI 1 "register_operand" ""))]
1896  "TARGET_ZARCH && ACCESS_REG_P (operands[0]) && reload_completed
1897   && dead_or_set_p (insn, operands[1])"
1898  [(set (match_dup 3) (match_dup 2))
1899   (set (match_dup 1) (lshiftrt:DI (match_dup 1) (const_int 32)))
1900   (set (match_dup 4) (match_dup 2))]
1901  "operands[2] = gen_lowpart (SImode, operands[1]);
1902   s390_split_access_reg (operands[0], &operands[3], &operands[4]);")
1903
1904(define_split
1905  [(set (match_operand:DI 0 "register_operand" "")
1906        (match_operand:DI 1 "register_operand" ""))]
1907  "TARGET_ZARCH && ACCESS_REG_P (operands[0]) && reload_completed
1908   && !dead_or_set_p (insn, operands[1])"
1909  [(set (match_dup 3) (match_dup 2))
1910   (set (match_dup 1) (rotate:DI (match_dup 1) (const_int 32)))
1911   (set (match_dup 4) (match_dup 2))
1912   (set (match_dup 1) (rotate:DI (match_dup 1) (const_int 32)))]
1913  "operands[2] = gen_lowpart (SImode, operands[1]);
1914   s390_split_access_reg (operands[0], &operands[3], &operands[4]);")
1915
1916(define_insn "*movdi_31"
1917  [(set (match_operand:DI 0 "nonimmediate_operand"
1918                            "=d,d,Q,S,d  ,o,!*f,!*f,!*f,!R,!T,d")
1919        (match_operand:DI 1 "general_operand"
1920                            " Q,S,d,d,dPT,d, *f,  R,  T,*f,*f,b"))]
1921  "!TARGET_ZARCH"
1922  "@
1923   lm\t%0,%N0,%S1
1924   lmy\t%0,%N0,%S1
1925   stm\t%1,%N1,%S0
1926   stmy\t%1,%N1,%S0
1927   #
1928   #
1929   ldr\t%0,%1
1930   ld\t%0,%1
1931   ldy\t%0,%1
1932   std\t%1,%0
1933   stdy\t%1,%0
1934   #"
1935  [(set_attr "op_type" "RS,RSY,RS,RSY,*,*,RR,RX,RXY,RX,RXY,*")
1936   (set_attr "type" "lm,lm,stm,stm,*,*,floaddf,floaddf,floaddf,fstoredf,fstoredf,*")
1937   (set_attr "cpu_facility" "*,longdisp,*,longdisp,*,*,*,*,longdisp,*,longdisp,z10")])
1938
1939; For a load from a symbol ref we can use one of the target registers
1940; together with larl to load the address.
1941(define_split
1942  [(set (match_operand:DI 0 "register_operand" "")
1943        (match_operand:DI 1 "memory_operand" ""))]
1944  "!TARGET_ZARCH && reload_completed && TARGET_Z10
1945   && larl_operand (XEXP (operands[1], 0), SImode)"
1946  [(set (match_dup 2) (match_dup 3))
1947   (set (match_dup 0) (match_dup 1))]
1948{
1949  operands[2] = operand_subword (operands[0], 1, 0, DImode);
1950  operands[3] = XEXP (operands[1], 0);
1951  operands[1] = replace_equiv_address (operands[1], operands[2]);
1952})
1953
1954(define_split
1955  [(set (match_operand:DI 0 "nonimmediate_operand" "")
1956        (match_operand:DI 1 "general_operand" ""))]
1957  "!TARGET_ZARCH && reload_completed
1958   && !s_operand (operands[0], DImode)
1959   && !s_operand (operands[1], DImode)
1960   && s390_split_ok_p (operands[0], operands[1], DImode, 0)"
1961  [(set (match_dup 2) (match_dup 4))
1962   (set (match_dup 3) (match_dup 5))]
1963{
1964  operands[2] = operand_subword (operands[0], 0, 0, DImode);
1965  operands[3] = operand_subword (operands[0], 1, 0, DImode);
1966  operands[4] = operand_subword (operands[1], 0, 0, DImode);
1967  operands[5] = operand_subword (operands[1], 1, 0, DImode);
1968})
1969
1970(define_split
1971  [(set (match_operand:DI 0 "nonimmediate_operand" "")
1972        (match_operand:DI 1 "general_operand" ""))]
1973  "!TARGET_ZARCH && reload_completed
1974   && !s_operand (operands[0], DImode)
1975   && !s_operand (operands[1], DImode)
1976   && s390_split_ok_p (operands[0], operands[1], DImode, 1)"
1977  [(set (match_dup 2) (match_dup 4))
1978   (set (match_dup 3) (match_dup 5))]
1979{
1980  operands[2] = operand_subword (operands[0], 1, 0, DImode);
1981  operands[3] = operand_subword (operands[0], 0, 0, DImode);
1982  operands[4] = operand_subword (operands[1], 1, 0, DImode);
1983  operands[5] = operand_subword (operands[1], 0, 0, DImode);
1984})
1985
1986(define_split
1987  [(set (match_operand:DI 0 "register_operand" "")
1988        (match_operand:DI 1 "memory_operand" ""))]
1989  "!TARGET_ZARCH && reload_completed
1990   && !FP_REG_P (operands[0])
1991   && !s_operand (operands[1], VOIDmode)"
1992  [(set (match_dup 0) (match_dup 1))]
1993{
1994  rtx addr = operand_subword (operands[0], 1, 0, DImode);
1995  s390_load_address (addr, XEXP (operands[1], 0));
1996  operands[1] = replace_equiv_address (operands[1], addr);
1997})
1998
1999(define_peephole2
2000  [(set (match_operand:DI 0 "register_operand" "")
2001        (mem:DI (match_operand 1 "address_operand" "")))]
2002  "TARGET_ZARCH
2003   && !FP_REG_P (operands[0])
2004   && GET_CODE (operands[1]) == SYMBOL_REF
2005   && CONSTANT_POOL_ADDRESS_P (operands[1])
2006   && get_pool_mode (operands[1]) == DImode
2007   && legitimate_reload_constant_p (get_pool_constant (operands[1]))"
2008  [(set (match_dup 0) (match_dup 2))]
2009  "operands[2] = get_pool_constant (operands[1]);")
2010
2011(define_insn "*la_64"
2012  [(set (match_operand:DI 0 "register_operand" "=d,d")
2013        (match_operand:QI 1 "address_operand" "ZR,ZT"))]
2014  "TARGET_64BIT"
2015  "@
2016   la\t%0,%a1
2017   lay\t%0,%a1"
2018  [(set_attr "op_type" "RX,RXY")
2019   (set_attr "type"    "la")
2020   (set_attr "cpu_facility" "*,longdisp")
2021   (set_attr "z10prop" "z10_fwd_A1,z10_fwd_A1")])
2022
2023(define_peephole2
2024  [(parallel
2025    [(set (match_operand:DI 0 "register_operand" "")
2026          (match_operand:QI 1 "address_operand" ""))
2027     (clobber (reg:CC CC_REGNUM))])]
2028  "TARGET_64BIT
2029   && preferred_la_operand_p (operands[1], const0_rtx)"
2030  [(set (match_dup 0) (match_dup 1))]
2031  "")
2032
2033(define_peephole2
2034  [(set (match_operand:DI 0 "register_operand" "")
2035        (match_operand:DI 1 "register_operand" ""))
2036   (parallel
2037    [(set (match_dup 0)
2038          (plus:DI (match_dup 0)
2039                   (match_operand:DI 2 "nonmemory_operand" "")))
2040     (clobber (reg:CC CC_REGNUM))])]
2041  "TARGET_64BIT
2042   && !reg_overlap_mentioned_p (operands[0], operands[2])
2043   && preferred_la_operand_p (operands[1], operands[2])"
2044  [(set (match_dup 0) (plus:DI (match_dup 1) (match_dup 2)))]
2045  "")
2046
2047;
2048; movsi instruction pattern(s).
2049;
2050
2051(define_expand "movsi"
2052  [(set (match_operand:SI 0 "general_operand" "")
2053        (match_operand:SI 1 "general_operand" ""))]
2054  ""
2055{
2056  /* Handle symbolic constants.  */
2057  if (!TARGET_64BIT
2058      && (SYMBOLIC_CONST (operands[1])
2059	  || (GET_CODE (operands[1]) == PLUS
2060	      && XEXP (operands[1], 0) == pic_offset_table_rtx
2061	      && SYMBOLIC_CONST (XEXP(operands[1], 1)))))
2062    emit_symbolic_move (operands);
2063})
2064
2065(define_insn "*movsi_larl"
2066  [(set (match_operand:SI 0 "register_operand" "=d")
2067        (match_operand:SI 1 "larl_operand" "X"))]
2068  "!TARGET_64BIT
2069   && !FP_REG_P (operands[0])"
2070  "larl\t%0,%1"
2071   [(set_attr "op_type" "RIL")
2072    (set_attr "type"    "larl")
2073    (set_attr "z10prop" "z10_fwd_A1")
2074    (set_attr "relative_long" "yes")])
2075
2076(define_insn "*movsi_zarch"
2077  [(set (match_operand:SI 0 "nonimmediate_operand"
2078	 "=d,    d,    d, d,d,d,d,d,d,R,T,!*f,!*f,!*f,!*f,!*f,!R,!T,d,t,Q,b,Q,t,v,v,v,d,v,R")
2079        (match_operand:SI 1 "general_operand"
2080	 " K,N0HS0,N1HS0,Os,L,b,d,R,T,d,d, *f, *f,  R,  R,  T,*f,*f,t,d,t,d,K,Q,K,v,d,v,R,v"))]
2081  "TARGET_ZARCH"
2082  "@
2083   lhi\t%0,%h1
2084   llilh\t%0,%i1
2085   llill\t%0,%i1
2086   iilf\t%0,%o1
2087   lay\t%0,%a1
2088   lrl\t%0,%1
2089   lr\t%0,%1
2090   l\t%0,%1
2091   ly\t%0,%1
2092   st\t%1,%0
2093   sty\t%1,%0
2094   ldr\t%0,%1
2095   ler\t%0,%1
2096   lde\t%0,%1
2097   le\t%0,%1
2098   ley\t%0,%1
2099   ste\t%1,%0
2100   stey\t%1,%0
2101   ear\t%0,%1
2102   sar\t%0,%1
2103   stam\t%1,%1,%S0
2104   strl\t%1,%0
2105   mvhi\t%0,%1
2106   lam\t%0,%0,%S1
2107   vleif\t%v0,%h1,0
2108   vlr\t%v0,%v1
2109   vlvgf\t%v0,%1,0
2110   vlgvf\t%0,%v1,0
2111   vlef\t%v0,%1,0
2112   vstef\t%v1,%0,0"
2113  [(set_attr "op_type" "RI,RI,RI,RIL,RXY,RIL,RR,RX,RXY,RX,RXY,
2114                        RR,RR,RXE,RX,RXY,RX,RXY,RRE,RRE,RS,RIL,SIL,RS,VRI,VRR,VRS,VRS,VRX,VRX")
2115   (set_attr "type" "*,
2116                     *,
2117                     *,
2118                     *,
2119                     la,
2120                     larl,
2121                     lr,
2122                     load,
2123                     load,
2124                     store,
2125                     store,
2126                     floadsf,
2127                     floadsf,
2128                     floadsf,
2129                     floadsf,
2130                     floadsf,
2131                     fstoresf,
2132                     fstoresf,
2133                     *,
2134                     *,
2135                     *,
2136                     larl,
2137                     *,
2138                     *,*,*,*,*,*,*")
2139   (set_attr "cpu_facility" "*,*,*,extimm,longdisp,z10,*,*,longdisp,*,longdisp,
2140                             vx,*,vx,*,longdisp,*,longdisp,*,*,*,z10,z10,*,vx,vx,vx,vx,vx,vx")
2141   (set_attr "z10prop" "z10_fwd_A1,
2142                        z10_fwd_E1,
2143                        z10_fwd_E1,
2144                        z10_fwd_A1,
2145                        z10_fwd_A1,
2146                        z10_fwd_A3,
2147                        z10_fr_E1,
2148                        z10_fwd_A3,
2149                        z10_fwd_A3,
2150                        z10_rec,
2151                        z10_rec,
2152                        *,
2153                        *,
2154                        *,
2155                        *,
2156                        *,
2157                        *,
2158                        *,
2159                        z10_super_E1,
2160                        z10_super,
2161                        *,
2162                        z10_rec,
2163                        z10_super,
2164                        *,*,*,*,*,*,*")
2165   (set_attr "relative_long" "*,*,*,*,*,yes,*,*,*,*,
2166                              *,*,*,*,*,*,*,*,*,*,
2167                              *,yes,*,*,*,*,*,*,*,*")])
2168
2169(define_insn "*movsi_esa"
2170  [(set (match_operand:SI 0 "nonimmediate_operand" "=d,d,d,R,!*f,!*f,!*f,!*f,!R,d,t,Q,t")
2171        (match_operand:SI 1 "general_operand"       "K,d,R,d, *f, *f,  R,  R,*f,t,d,t,Q"))]
2172  "!TARGET_ZARCH"
2173  "@
2174   lhi\t%0,%h1
2175   lr\t%0,%1
2176   l\t%0,%1
2177   st\t%1,%0
2178   ldr\t%0,%1
2179   ler\t%0,%1
2180   lde\t%0,%1
2181   le\t%0,%1
2182   ste\t%1,%0
2183   ear\t%0,%1
2184   sar\t%0,%1
2185   stam\t%1,%1,%S0
2186   lam\t%0,%0,%S1"
2187  [(set_attr "op_type" "RI,RR,RX,RX,RR,RR,RXE,RX,RX,RRE,RRE,RS,RS")
2188   (set_attr "type" "*,lr,load,store,floadsf,floadsf,floadsf,floadsf,fstoresf,*,*,*,*")
2189   (set_attr "z10prop" "z10_fwd_A1,z10_fr_E1,z10_fwd_A3,z10_rec,*,*,*,*,*,z10_super_E1,
2190                        z10_super,*,*")
2191   (set_attr "cpu_facility" "*,*,*,*,vx,*,vx,*,*,*,*,*,*")
2192])
2193
2194(define_peephole2
2195  [(set (match_operand:SI 0 "register_operand" "")
2196        (mem:SI (match_operand 1 "address_operand" "")))]
2197  "!FP_REG_P (operands[0])
2198   && GET_CODE (operands[1]) == SYMBOL_REF
2199   && CONSTANT_POOL_ADDRESS_P (operands[1])
2200   && get_pool_mode (operands[1]) == SImode
2201   && legitimate_reload_constant_p (get_pool_constant (operands[1]))"
2202  [(set (match_dup 0) (match_dup 2))]
2203  "operands[2] = get_pool_constant (operands[1]);")
2204
2205(define_insn "*la_31"
2206  [(set (match_operand:SI 0 "register_operand" "=d,d")
2207        (match_operand:QI 1 "address_operand" "ZR,ZT"))]
2208  "!TARGET_64BIT && legitimate_la_operand_p (operands[1])"
2209  "@
2210   la\t%0,%a1
2211   lay\t%0,%a1"
2212  [(set_attr "op_type"  "RX,RXY")
2213   (set_attr "type"     "la")
2214   (set_attr "cpu_facility" "*,longdisp")
2215   (set_attr "z10prop" "z10_fwd_A1,z10_fwd_A1")])
2216
2217(define_peephole2
2218  [(parallel
2219    [(set (match_operand:SI 0 "register_operand" "")
2220          (match_operand:QI 1 "address_operand" ""))
2221     (clobber (reg:CC CC_REGNUM))])]
2222  "!TARGET_64BIT
2223   && preferred_la_operand_p (operands[1], const0_rtx)"
2224  [(set (match_dup 0) (match_dup 1))]
2225  "")
2226
2227(define_peephole2
2228  [(set (match_operand:SI 0 "register_operand" "")
2229        (match_operand:SI 1 "register_operand" ""))
2230   (parallel
2231    [(set (match_dup 0)
2232          (plus:SI (match_dup 0)
2233                   (match_operand:SI 2 "nonmemory_operand" "")))
2234     (clobber (reg:CC CC_REGNUM))])]
2235  "!TARGET_64BIT
2236   && !reg_overlap_mentioned_p (operands[0], operands[2])
2237   && preferred_la_operand_p (operands[1], operands[2])"
2238  [(set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))]
2239  "")
2240
2241(define_insn "*la_31_and"
2242  [(set (match_operand:SI 0 "register_operand" "=d,d")
2243        (and:SI (match_operand:QI 1 "address_operand" "ZR,ZT")
2244                (const_int 2147483647)))]
2245  "!TARGET_64BIT"
2246  "@
2247   la\t%0,%a1
2248   lay\t%0,%a1"
2249  [(set_attr "op_type"  "RX,RXY")
2250   (set_attr "type"     "la")
2251   (set_attr "cpu_facility" "*,longdisp")
2252   (set_attr "z10prop" "z10_fwd_A1,z10_fwd_A1")])
2253
2254(define_insn_and_split "*la_31_and_cc"
2255  [(set (match_operand:SI 0 "register_operand" "=d")
2256        (and:SI (match_operand:QI 1 "address_operand" "p")
2257                (const_int 2147483647)))
2258   (clobber (reg:CC CC_REGNUM))]
2259  "!TARGET_64BIT"
2260  "#"
2261  "&& reload_completed"
2262  [(set (match_dup 0)
2263        (and:SI (match_dup 1) (const_int 2147483647)))]
2264  ""
2265  [(set_attr "op_type"  "RX")
2266   (set_attr "type"     "la")])
2267
2268(define_insn "force_la_31"
2269  [(set (match_operand:SI 0 "register_operand" "=d,d")
2270        (match_operand:QI 1 "address_operand" "ZR,ZT"))
2271   (use (const_int 0))]
2272  "!TARGET_64BIT"
2273  "@
2274   la\t%0,%a1
2275   lay\t%0,%a1"
2276  [(set_attr "op_type"  "RX")
2277   (set_attr "type"     "la")
2278   (set_attr "cpu_facility" "*,longdisp")
2279   (set_attr "z10prop" "z10_fwd_A1,z10_fwd_A1")])
2280
2281;
2282; movhi instruction pattern(s).
2283;
2284
2285(define_expand "movhi"
2286  [(set (match_operand:HI 0 "nonimmediate_operand" "")
2287        (match_operand:HI 1 "general_operand" ""))]
2288  ""
2289{
2290  /* Make it explicit that loading a register from memory
2291     always sign-extends (at least) to SImode.  */
2292  if (optimize && can_create_pseudo_p ()
2293      && register_operand (operands[0], VOIDmode)
2294      && GET_CODE (operands[1]) == MEM)
2295    {
2296      rtx tmp = gen_reg_rtx (SImode);
2297      rtx ext = gen_rtx_SIGN_EXTEND (SImode, operands[1]);
2298      emit_insn (gen_rtx_SET (tmp, ext));
2299      operands[1] = gen_lowpart (HImode, tmp);
2300    }
2301})
2302
2303(define_insn "*movhi"
2304  [(set (match_operand:HI 0 "nonimmediate_operand" "=d,d,d,d,d,R,T,b,Q,v,v,v,d,v,R")
2305        (match_operand:HI 1 "general_operand"      " d,n,R,T,b,d,d,d,K,K,v,d,v,R,v"))]
2306  ""
2307  "@
2308   lr\t%0,%1
2309   lhi\t%0,%h1
2310   lh\t%0,%1
2311   lhy\t%0,%1
2312   lhrl\t%0,%1
2313   sth\t%1,%0
2314   sthy\t%1,%0
2315   sthrl\t%1,%0
2316   mvhhi\t%0,%1
2317   vleih\t%v0,%h1,0
2318   vlr\t%v0,%v1
2319   vlvgh\t%v0,%1,0
2320   vlgvh\t%0,%v1,0
2321   vleh\t%v0,%1,0
2322   vsteh\t%v1,%0,0"
2323  [(set_attr "op_type"      "RR,RI,RX,RXY,RIL,RX,RXY,RIL,SIL,VRI,VRR,VRS,VRS,VRX,VRX")
2324   (set_attr "type"         "lr,*,*,*,larl,store,store,store,*,*,*,*,*,*,*")
2325   (set_attr "cpu_facility" "*,*,*,longdisp,z10,*,longdisp,z10,z10,vx,vx,vx,vx,vx,vx")
2326   (set_attr "z10prop" "z10_fr_E1,
2327                       z10_fwd_A1,
2328                       z10_super_E1,
2329                       z10_super_E1,
2330                       z10_super_E1,
2331                       z10_rec,
2332                       z10_rec,
2333                       z10_rec,
2334                       z10_super,*,*,*,*,*,*")
2335   (set_attr "relative_long" "*,*,*,*,yes,*,*,yes,*,*,*,*,*,*,*")])
2336
2337(define_peephole2
2338  [(set (match_operand:HI 0 "register_operand" "")
2339        (mem:HI (match_operand 1 "address_operand" "")))]
2340  "GET_CODE (operands[1]) == SYMBOL_REF
2341   && CONSTANT_POOL_ADDRESS_P (operands[1])
2342   && get_pool_mode (operands[1]) == HImode
2343   && GET_CODE (get_pool_constant (operands[1])) == CONST_INT"
2344  [(set (match_dup 0) (match_dup 2))]
2345  "operands[2] = get_pool_constant (operands[1]);")
2346
2347;
2348; movqi instruction pattern(s).
2349;
2350
2351(define_expand "movqi"
2352  [(set (match_operand:QI 0 "nonimmediate_operand" "")
2353        (match_operand:QI 1 "general_operand" ""))]
2354  ""
2355{
2356  /* On z/Architecture, zero-extending from memory to register
2357     is just as fast as a QImode load.  */
2358  if (TARGET_ZARCH && optimize && can_create_pseudo_p ()
2359      && register_operand (operands[0], VOIDmode)
2360      && GET_CODE (operands[1]) == MEM)
2361    {
2362      rtx tmp = gen_reg_rtx (DImode);
2363      rtx ext = gen_rtx_ZERO_EXTEND (DImode, operands[1]);
2364      emit_insn (gen_rtx_SET (tmp, ext));
2365      operands[1] = gen_lowpart (QImode, tmp);
2366    }
2367})
2368
2369(define_insn "*movqi"
2370  [(set (match_operand:QI 0 "nonimmediate_operand" "=d,d,d,d,R,T,Q,S,?Q,v,v,v,d,v,R")
2371        (match_operand:QI 1 "general_operand"      " d,n,R,T,d,d,n,n,?Q,K,v,d,v,R,v"))]
2372  ""
2373  "@
2374   lr\t%0,%1
2375   lhi\t%0,%b1
2376   ic\t%0,%1
2377   icy\t%0,%1
2378   stc\t%1,%0
2379   stcy\t%1,%0
2380   mvi\t%S0,%b1
2381   mviy\t%S0,%b1
2382   #
2383   vleib\t%v0,%b1,0
2384   vlr\t%v0,%v1
2385   vlvgb\t%v0,%1,0
2386   vlgvb\t%0,%v1,0
2387   vleb\t%v0,%1,0
2388   vsteb\t%v1,%0,0"
2389  [(set_attr "op_type" "RR,RI,RX,RXY,RX,RXY,SI,SIY,SS,VRI,VRR,VRS,VRS,VRX,VRX")
2390   (set_attr "type" "lr,*,*,*,store,store,store,store,*,*,*,*,*,*,*")
2391   (set_attr "cpu_facility" "*,*,*,longdisp,*,longdisp,*,longdisp,*,vx,vx,vx,vx,vx,vx")
2392   (set_attr "z10prop" "z10_fr_E1,
2393                        z10_fwd_A1,
2394                        z10_super_E1,
2395                        z10_super_E1,
2396                        z10_rec,
2397                        z10_rec,
2398                        z10_super,
2399                        z10_super,
2400                        *,*,*,*,*,*,*")])
2401
2402(define_peephole2
2403  [(set (match_operand:QI 0 "nonimmediate_operand" "")
2404        (mem:QI (match_operand 1 "address_operand" "")))]
2405  "GET_CODE (operands[1]) == SYMBOL_REF
2406   && CONSTANT_POOL_ADDRESS_P (operands[1])
2407   && get_pool_mode (operands[1]) == QImode
2408   && GET_CODE (get_pool_constant (operands[1])) == CONST_INT"
2409  [(set (match_dup 0) (match_dup 2))]
2410  "operands[2] = get_pool_constant (operands[1]);")
2411
2412;
2413; movstrictqi instruction pattern(s).
2414;
2415
2416(define_insn "*movstrictqi"
2417  [(set (strict_low_part (match_operand:QI 0 "register_operand" "+d,d"))
2418                         (match_operand:QI 1 "memory_operand" "R,T"))]
2419  ""
2420  "@
2421   ic\t%0,%1
2422   icy\t%0,%1"
2423  [(set_attr "op_type"  "RX,RXY")
2424   (set_attr "cpu_facility" "*,longdisp")
2425   (set_attr "z10prop" "z10_super_E1,z10_super_E1")])
2426
2427;
2428; movstricthi instruction pattern(s).
2429;
2430
2431(define_insn "*movstricthi"
2432  [(set (strict_low_part (match_operand:HI 0 "register_operand" "+d,d"))
2433                         (match_operand:HI 1 "memory_operand" "Q,S"))
2434   (clobber (reg:CC CC_REGNUM))]
2435  ""
2436  "@
2437   icm\t%0,3,%S1
2438   icmy\t%0,3,%S1"
2439  [(set_attr "op_type" "RS,RSY")
2440   (set_attr "cpu_facility" "*,longdisp")
2441   (set_attr "z10prop" "z10_super_E1,z10_super_E1")])
2442
2443;
2444; movstrictsi instruction pattern(s).
2445;
2446
2447(define_insn "movstrictsi"
2448  [(set (strict_low_part (match_operand:SI 0 "register_operand" "+d,d,d,d"))
2449                         (match_operand:SI 1 "general_operand" "d,R,T,t"))]
2450  "TARGET_ZARCH"
2451  "@
2452   lr\t%0,%1
2453   l\t%0,%1
2454   ly\t%0,%1
2455   ear\t%0,%1"
2456  [(set_attr "op_type" "RR,RX,RXY,RRE")
2457   (set_attr "type" "lr,load,load,*")
2458   (set_attr "cpu_facility" "*,*,longdisp,*")
2459   (set_attr "z10prop" "z10_fr_E1,z10_fwd_A3,z10_fwd_A3,z10_super_E1")])
2460
2461;
2462; mov(tf|td) instruction pattern(s).
2463;
2464
2465(define_expand "mov<mode>"
2466  [(set (match_operand:TD_TF 0 "nonimmediate_operand" "")
2467        (match_operand:TD_TF 1 "general_operand"      ""))]
2468  ""
2469  "")
2470
2471(define_insn "*mov<mode>_64"
2472  [(set (match_operand:TD_TF 0 "nonimmediate_operand" "=f,f,f,o,d,S, d,o")
2473        (match_operand:TD_TF 1 "general_operand"      " G,f,o,f,S,d,dT,d"))]
2474  "TARGET_ZARCH"
2475  "@
2476   lzxr\t%0
2477   lxr\t%0,%1
2478   #
2479   #
2480   lmg\t%0,%N0,%S1
2481   stmg\t%1,%N1,%S0
2482   #
2483   #"
2484  [(set_attr "op_type"      "RRE,RRE,*,*,RSY,RSY,*,*")
2485   (set_attr "type"         "fsimptf,fsimptf,*,*,lm,stm,*,*")
2486   (set_attr "cpu_facility" "z196,*,*,*,*,*,*,*")])
2487
2488(define_insn "*mov<mode>_31"
2489  [(set (match_operand:TD_TF 0 "nonimmediate_operand" "=f,f,f,o")
2490        (match_operand:TD_TF 1 "general_operand"      " G,f,o,f"))]
2491  "!TARGET_ZARCH"
2492  "@
2493   lzxr\t%0
2494   lxr\t%0,%1
2495   #
2496   #"
2497  [(set_attr "op_type"      "RRE,RRE,*,*")
2498   (set_attr "type"         "fsimptf,fsimptf,*,*")
2499   (set_attr "cpu_facility" "z196,*,*,*")])
2500
2501; TFmode in GPRs splitters
2502
2503(define_split
2504  [(set (match_operand:TD_TF 0 "nonimmediate_operand" "")
2505        (match_operand:TD_TF 1 "general_operand"      ""))]
2506  "TARGET_ZARCH && reload_completed
2507   && !s_operand (operands[0], <MODE>mode)
2508   && !s_operand (operands[1], <MODE>mode)
2509   && s390_split_ok_p (operands[0], operands[1], <MODE>mode, 0)"
2510  [(set (match_dup 2) (match_dup 4))
2511   (set (match_dup 3) (match_dup 5))]
2512{
2513  operands[2] = operand_subword (operands[0], 0, 0, <MODE>mode);
2514  operands[3] = operand_subword (operands[0], 1, 0, <MODE>mode);
2515  operands[4] = operand_subword (operands[1], 0, 0, <MODE>mode);
2516  operands[5] = operand_subword (operands[1], 1, 0, <MODE>mode);
2517})
2518
2519(define_split
2520  [(set (match_operand:TD_TF 0 "nonimmediate_operand" "")
2521        (match_operand:TD_TF 1 "general_operand"      ""))]
2522  "TARGET_ZARCH && reload_completed
2523   && !s_operand (operands[0], <MODE>mode)
2524   && !s_operand (operands[1], <MODE>mode)
2525   && s390_split_ok_p (operands[0], operands[1], <MODE>mode, 1)"
2526  [(set (match_dup 2) (match_dup 4))
2527   (set (match_dup 3) (match_dup 5))]
2528{
2529  operands[2] = operand_subword (operands[0], 1, 0, <MODE>mode);
2530  operands[3] = operand_subword (operands[0], 0, 0, <MODE>mode);
2531  operands[4] = operand_subword (operands[1], 1, 0, <MODE>mode);
2532  operands[5] = operand_subword (operands[1], 0, 0, <MODE>mode);
2533})
2534
2535(define_split
2536  [(set (match_operand:TD_TF 0 "register_operand" "")
2537        (match_operand:TD_TF 1 "memory_operand"   ""))]
2538  "TARGET_ZARCH && reload_completed
2539   && GENERAL_REG_P (operands[0])
2540   && !s_operand (operands[1], VOIDmode)"
2541  [(set (match_dup 0) (match_dup 1))]
2542{
2543  rtx addr = operand_subword (operands[0], 1, 0, <MODE>mode);
2544  addr = gen_lowpart (Pmode, addr);
2545  s390_load_address (addr, XEXP (operands[1], 0));
2546  operands[1] = replace_equiv_address (operands[1], addr);
2547})
2548
2549; TFmode in BFPs splitters
2550
2551(define_split
2552  [(set (match_operand:TD_TF 0 "register_operand" "")
2553        (match_operand:TD_TF 1 "memory_operand" ""))]
2554  "reload_completed && offsettable_memref_p (operands[1])
2555   && FP_REG_P (operands[0])"
2556  [(set (match_dup 2) (match_dup 4))
2557   (set (match_dup 3) (match_dup 5))]
2558{
2559  operands[2] = simplify_gen_subreg (<HALF_TMODE>mode, operands[0],
2560                                     <MODE>mode, 0);
2561  operands[3] = simplify_gen_subreg (<HALF_TMODE>mode, operands[0],
2562                                     <MODE>mode, 8);
2563  operands[4] = adjust_address_nv (operands[1], <HALF_TMODE>mode, 0);
2564  operands[5] = adjust_address_nv (operands[1], <HALF_TMODE>mode, 8);
2565})
2566
2567(define_split
2568  [(set (match_operand:TD_TF 0 "memory_operand" "")
2569        (match_operand:TD_TF 1 "register_operand" ""))]
2570  "reload_completed && offsettable_memref_p (operands[0])
2571   && FP_REG_P (operands[1])"
2572  [(set (match_dup 2) (match_dup 4))
2573   (set (match_dup 3) (match_dup 5))]
2574{
2575  operands[2] = adjust_address_nv (operands[0], <HALF_TMODE>mode, 0);
2576  operands[3] = adjust_address_nv (operands[0], <HALF_TMODE>mode, 8);
2577  operands[4] = simplify_gen_subreg (<HALF_TMODE>mode, operands[1],
2578				     <MODE>mode, 0);
2579  operands[5] = simplify_gen_subreg (<HALF_TMODE>mode, operands[1],
2580                                     <MODE>mode, 8);
2581})
2582
2583;
2584; mov(df|dd) instruction pattern(s).
2585;
2586
2587(define_expand "mov<mode>"
2588  [(set (match_operand:DD_DF 0 "nonimmediate_operand" "")
2589        (match_operand:DD_DF 1 "general_operand"  ""))]
2590  ""
2591  "")
2592
2593(define_insn "*mov<mode>_64dfp"
2594  [(set (match_operand:DD_DF 0 "nonimmediate_operand"
2595			       "=f,f,f,d,f,f,R,T,d,d,d,d,b,T,v,v,v,d,v,R")
2596        (match_operand:DD_DF 1 "general_operand"
2597			       " G,f,d,f,R,T,f,f,G,d,b,T,d,d,v,G,d,v,R,v"))]
2598  "TARGET_DFP"
2599  "@
2600   lzdr\t%0
2601   ldr\t%0,%1
2602   ldgr\t%0,%1
2603   lgdr\t%0,%1
2604   ld\t%0,%1
2605   ldy\t%0,%1
2606   std\t%1,%0
2607   stdy\t%1,%0
2608   lghi\t%0,0
2609   lgr\t%0,%1
2610   lgrl\t%0,%1
2611   lg\t%0,%1
2612   stgrl\t%1,%0
2613   stg\t%1,%0
2614   vlr\t%v0,%v1
2615   vleig\t%v0,0,0
2616   vlvgg\t%v0,%1,0
2617   vlgvg\t%0,%v1,0
2618   vleg\t%0,%1,0
2619   vsteg\t%1,%0,0"
2620  [(set_attr "op_type" "RRE,RR,RRE,RRE,RX,RXY,RX,RXY,RI,RRE,RIL,RXY,RIL,RXY,VRR,VRI,VRS,VRS,VRX,VRX")
2621   (set_attr "type" "fsimpdf,floaddf,floaddf,floaddf,floaddf,floaddf,
2622                     fstoredf,fstoredf,*,lr,load,load,store,store,*,*,*,*,load,store")
2623   (set_attr "z10prop" "*,*,*,*,*,*,*,*,z10_fwd_A1,z10_fr_E1,z10_fwd_A3,z10_fwd_A3,z10_rec,z10_rec,*,*,*,*,*,*")
2624   (set_attr "cpu_facility" "z196,*,*,*,*,longdisp,*,longdisp,*,*,z10,*,z10,*,vx,vx,vx,vx,vx,vx")
2625   (set_attr "relative_long" "*,*,*,*,*,*,*,*,*,*,yes,*,yes,*,*,*,*,*,*,*")])
2626
2627(define_insn "*mov<mode>_64"
2628  [(set (match_operand:DD_DF 0 "nonimmediate_operand" "=f,f,f,f,R,T,d,d,d,d,b,T")
2629        (match_operand:DD_DF 1 "general_operand"      " G,f,R,T,f,f,G,d,b,T,d,d"))]
2630  "TARGET_ZARCH"
2631  "@
2632   lzdr\t%0
2633   ldr\t%0,%1
2634   ld\t%0,%1
2635   ldy\t%0,%1
2636   std\t%1,%0
2637   stdy\t%1,%0
2638   lghi\t%0,0
2639   lgr\t%0,%1
2640   lgrl\t%0,%1
2641   lg\t%0,%1
2642   stgrl\t%1,%0
2643   stg\t%1,%0"
2644  [(set_attr "op_type" "RRE,RR,RX,RXY,RX,RXY,RI,RRE,RIL,RXY,RIL,RXY")
2645   (set_attr "type"    "fsimpdf,fload<mode>,fload<mode>,fload<mode>,
2646                        fstore<mode>,fstore<mode>,*,lr,load,load,store,store")
2647   (set_attr "z10prop" "*,*,*,*,*,*,z10_fwd_A1,z10_fr_E1,z10_fwd_A3,z10_fwd_A3,z10_rec,z10_rec")
2648   (set_attr "cpu_facility" "z196,*,*,longdisp,*,longdisp,*,*,z10,*,z10,*")
2649   (set_attr "relative_long" "*,*,*,*,*,*,*,*,yes,*,*,*")])
2650
2651(define_insn "*mov<mode>_31"
2652  [(set (match_operand:DD_DF 0 "nonimmediate_operand"
2653                               "=f,f,f,f,R,T,d,d,Q,S,  d,o")
2654        (match_operand:DD_DF 1 "general_operand"
2655                               " G,f,R,T,f,f,Q,S,d,d,dPT,d"))]
2656  "!TARGET_ZARCH"
2657  "@
2658   lzdr\t%0
2659   ldr\t%0,%1
2660   ld\t%0,%1
2661   ldy\t%0,%1
2662   std\t%1,%0
2663   stdy\t%1,%0
2664   lm\t%0,%N0,%S1
2665   lmy\t%0,%N0,%S1
2666   stm\t%1,%N1,%S0
2667   stmy\t%1,%N1,%S0
2668   #
2669   #"
2670  [(set_attr "op_type" "RRE,RR,RX,RXY,RX,RXY,RS,RSY,RS,RSY,*,*")
2671   (set_attr "type"    "fsimpdf,fload<mode>,fload<mode>,fload<mode>,
2672                        fstore<mode>,fstore<mode>,lm,lm,stm,stm,*,*")
2673   (set_attr "cpu_facility" "z196,*,*,longdisp,*,longdisp,*,longdisp,*,longdisp,*,*")])
2674
2675(define_split
2676  [(set (match_operand:DD_DF 0 "nonimmediate_operand" "")
2677        (match_operand:DD_DF 1 "general_operand" ""))]
2678  "!TARGET_ZARCH && reload_completed
2679   && !s_operand (operands[0], <MODE>mode)
2680   && !s_operand (operands[1], <MODE>mode)
2681   && s390_split_ok_p (operands[0], operands[1], <MODE>mode, 0)"
2682  [(set (match_dup 2) (match_dup 4))
2683   (set (match_dup 3) (match_dup 5))]
2684{
2685  operands[2] = operand_subword (operands[0], 0, 0, <MODE>mode);
2686  operands[3] = operand_subword (operands[0], 1, 0, <MODE>mode);
2687  operands[4] = operand_subword (operands[1], 0, 0, <MODE>mode);
2688  operands[5] = operand_subword (operands[1], 1, 0, <MODE>mode);
2689})
2690
2691(define_split
2692  [(set (match_operand:DD_DF 0 "nonimmediate_operand" "")
2693        (match_operand:DD_DF 1 "general_operand" ""))]
2694  "!TARGET_ZARCH && reload_completed
2695   && !s_operand (operands[0], <MODE>mode)
2696   && !s_operand (operands[1], <MODE>mode)
2697   && s390_split_ok_p (operands[0], operands[1], <MODE>mode, 1)"
2698  [(set (match_dup 2) (match_dup 4))
2699   (set (match_dup 3) (match_dup 5))]
2700{
2701  operands[2] = operand_subword (operands[0], 1, 0, <MODE>mode);
2702  operands[3] = operand_subword (operands[0], 0, 0, <MODE>mode);
2703  operands[4] = operand_subword (operands[1], 1, 0, <MODE>mode);
2704  operands[5] = operand_subword (operands[1], 0, 0, <MODE>mode);
2705})
2706
2707(define_split
2708  [(set (match_operand:DD_DF 0 "register_operand" "")
2709        (match_operand:DD_DF 1 "memory_operand" ""))]
2710  "!TARGET_ZARCH && reload_completed
2711   && !FP_REG_P (operands[0])
2712   && !s_operand (operands[1], VOIDmode)"
2713  [(set (match_dup 0) (match_dup 1))]
2714{
2715  rtx addr = operand_subword (operands[0], 1, 0, <MODE>mode);
2716  s390_load_address (addr, XEXP (operands[1], 0));
2717  operands[1] = replace_equiv_address (operands[1], addr);
2718})
2719
2720;
2721; mov(sf|sd) instruction pattern(s).
2722;
2723
2724(define_insn "mov<mode>"
2725  [(set (match_operand:SD_SF 0 "nonimmediate_operand"
2726			       "=f,f,f,f,f,f,R,T,d,d,d,d,d,b,R,T,v,v,v,d,v,R")
2727        (match_operand:SD_SF 1 "general_operand"
2728			       " G,f,f,R,R,T,f,f,G,d,b,R,T,d,d,d,v,G,d,v,R,v"))]
2729  ""
2730  "@
2731   lzer\t%0
2732   ldr\t%0,%1
2733   ler\t%0,%1
2734   lde\t%0,%1
2735   le\t%0,%1
2736   ley\t%0,%1
2737   ste\t%1,%0
2738   stey\t%1,%0
2739   lhi\t%0,0
2740   lr\t%0,%1
2741   lrl\t%0,%1
2742   l\t%0,%1
2743   ly\t%0,%1
2744   strl\t%1,%0
2745   st\t%1,%0
2746   sty\t%1,%0
2747   vlr\t%v0,%v1
2748   vleif\t%v0,0,0
2749   vlvgf\t%v0,%1,0
2750   vlgvf\t%0,%v1,0
2751   vlef\t%0,%1,0
2752   vstef\t%1,%0,0"
2753  [(set_attr "op_type" "RRE,RR,RR,RXE,RX,RXY,RX,RXY,RI,RR,RIL,RX,RXY,RIL,RX,RXY,VRR,VRI,VRS,VRS,VRX,VRX")
2754   (set_attr "type"    "fsimpsf,fsimpsf,fload<mode>,fload<mode>,fload<mode>,fload<mode>,
2755                        fstore<mode>,fstore<mode>,*,lr,load,load,load,store,store,store,*,*,*,*,load,store")
2756   (set_attr "z10prop" "*,*,*,*,*,*,*,*,z10_fwd_A1,z10_fr_E1,z10_fr_E1,z10_fwd_A3,z10_fwd_A3,z10_rec,z10_rec,z10_rec,*,*,*,*,*,*")
2757   (set_attr "cpu_facility" "z196,vx,*,vx,*,longdisp,*,longdisp,*,*,z10,*,longdisp,z10,*,longdisp,vx,vx,vx,vx,vx,vx")
2758   (set_attr "relative_long" "*,*,*,*,*,*,*,*,*,*,yes,*,*,yes,*,*,*,*,*,*,*,*")])
2759
2760;
2761; movcc instruction pattern
2762;
2763
2764(define_insn "movcc"
2765  [(set (match_operand:CC 0 "nonimmediate_operand" "=d,c,d,d,d,R,T")
2766	(match_operand:CC 1 "nonimmediate_operand" " d,d,c,R,T,d,d"))]
2767  ""
2768  "@
2769   lr\t%0,%1
2770   tmh\t%1,12288
2771   ipm\t%0
2772   l\t%0,%1
2773   ly\t%0,%1
2774   st\t%1,%0
2775   sty\t%1,%0"
2776  [(set_attr "op_type" "RR,RI,RRE,RX,RXY,RX,RXY")
2777   (set_attr "type" "lr,*,*,load,load,store,store")
2778   (set_attr "cpu_facility" "*,*,*,*,longdisp,*,longdisp")
2779   (set_attr "z10prop" "z10_fr_E1,z10_super,*,z10_fwd_A3,z10_fwd_A3,z10_rec,z10_rec")
2780   (set_attr "z196prop" "*,*,z196_ends,*,*,*,*")])
2781
2782;
2783; Block move (MVC) patterns.
2784;
2785
2786(define_insn "*mvc"
2787  [(set (match_operand:BLK 0 "memory_operand" "=Q")
2788        (match_operand:BLK 1 "memory_operand" "Q"))
2789   (use (match_operand 2 "const_int_operand" "n"))]
2790  "INTVAL (operands[2]) >= 1 && INTVAL (operands[2]) <= 256"
2791  "mvc\t%O0(%2,%R0),%S1"
2792  [(set_attr "op_type" "SS")])
2793
2794; This splitter converts a QI to QI mode copy into a BLK mode copy in
2795; order to have it implemented with mvc.
2796
2797(define_split
2798  [(set (match_operand:QI 0 "memory_operand" "")
2799        (match_operand:QI 1 "memory_operand" ""))]
2800  "reload_completed"
2801  [(parallel
2802    [(set (match_dup 0) (match_dup 1))
2803     (use (const_int 1))])]
2804{
2805  operands[0] = adjust_address (operands[0], BLKmode, 0);
2806  operands[1] = adjust_address (operands[1], BLKmode, 0);
2807})
2808
2809
2810(define_peephole2
2811  [(parallel
2812    [(set (match_operand:BLK 0 "memory_operand" "")
2813          (match_operand:BLK 1 "memory_operand" ""))
2814     (use (match_operand 2 "const_int_operand" ""))])
2815   (parallel
2816    [(set (match_operand:BLK 3 "memory_operand" "")
2817          (match_operand:BLK 4 "memory_operand" ""))
2818     (use (match_operand 5 "const_int_operand" ""))])]
2819  "((INTVAL (operands[2]) > 16 && INTVAL (operands[5]) > 16)
2820    || (INTVAL (operands[2]) + INTVAL (operands[5]) <= 16))
2821   && s390_offset_p (operands[0], operands[3], operands[2])
2822   && s390_offset_p (operands[1], operands[4], operands[2])
2823   && !s390_overlap_p (operands[0], operands[1],
2824                       INTVAL (operands[2]) + INTVAL (operands[5]))
2825   && INTVAL (operands[2]) + INTVAL (operands[5]) <= 256"
2826  [(parallel
2827    [(set (match_dup 6) (match_dup 7))
2828     (use (match_dup 8))])]
2829  "operands[6] = gen_rtx_MEM (BLKmode, XEXP (operands[0], 0));
2830   operands[7] = gen_rtx_MEM (BLKmode, XEXP (operands[1], 0));
2831   operands[8] = GEN_INT (INTVAL (operands[2]) + INTVAL (operands[5]));")
2832
2833(define_peephole2
2834  [(parallel
2835    [(set (match_operand:BLK 0 "plus16_Q_operand" "")
2836          (match_operand:BLK 1 "plus16_Q_operand" ""))
2837     (use (match_operand 2 "const_int_operand" ""))])]
2838  "INTVAL (operands[2]) > 16 && INTVAL (operands[2]) <= 32"
2839  [(parallel
2840    [(set (match_dup 0) (match_dup 1))
2841     (use (const_int 16))])
2842   (parallel
2843    [(set (match_dup 3) (match_dup 4))
2844     (use (match_dup 5))])]
2845  "operands[3] = change_address (operands[0], VOIDmode,
2846                                 plus_constant (Pmode, XEXP (operands[0], 0), 16));
2847   operands[4] = change_address (operands[1], VOIDmode,
2848                                 plus_constant (Pmode, XEXP (operands[1], 0), 16));
2849   operands[5] = GEN_INT (INTVAL (operands[2]) - 16);")
2850
2851
2852;
2853; load_multiple pattern(s).
2854;
2855; ??? Due to reload problems with replacing registers inside match_parallel
2856; we currently support load_multiple/store_multiple only after reload.
2857;
2858
2859(define_expand "load_multiple"
2860  [(match_par_dup 3 [(set (match_operand 0 "" "")
2861			  (match_operand 1 "" ""))
2862		     (use (match_operand 2 "" ""))])]
2863  "reload_completed"
2864{
2865  machine_mode mode;
2866  int regno;
2867  int count;
2868  rtx from;
2869  int i, off;
2870
2871  /* Support only loading a constant number of fixed-point registers from
2872     memory and only bother with this if more than two */
2873  if (GET_CODE (operands[2]) != CONST_INT
2874      || INTVAL (operands[2]) < 2
2875      || INTVAL (operands[2]) > 16
2876      || GET_CODE (operands[1]) != MEM
2877      || GET_CODE (operands[0]) != REG
2878      || REGNO (operands[0]) >= 16)
2879    FAIL;
2880
2881  count = INTVAL (operands[2]);
2882  regno = REGNO (operands[0]);
2883  mode = GET_MODE (operands[0]);
2884  if (mode != SImode && (!TARGET_ZARCH || mode != DImode))
2885    FAIL;
2886
2887  operands[3] = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (count));
2888  if (!can_create_pseudo_p ())
2889    {
2890      if (GET_CODE (XEXP (operands[1], 0)) == REG)
2891	{
2892	  from = XEXP (operands[1], 0);
2893	  off = 0;
2894	}
2895      else if (GET_CODE (XEXP (operands[1], 0)) == PLUS
2896	       && GET_CODE (XEXP (XEXP (operands[1], 0), 0)) == REG
2897	       && GET_CODE (XEXP (XEXP (operands[1], 0), 1)) == CONST_INT)
2898	{
2899	  from = XEXP (XEXP (operands[1], 0), 0);
2900	  off = INTVAL (XEXP (XEXP (operands[1], 0), 1));
2901	}
2902      else
2903	FAIL;
2904    }
2905  else
2906    {
2907      from = force_reg (Pmode, XEXP (operands[1], 0));
2908      off = 0;
2909    }
2910
2911  for (i = 0; i < count; i++)
2912    XVECEXP (operands[3], 0, i)
2913      = gen_rtx_SET (gen_rtx_REG (mode, regno + i),
2914		     change_address (operands[1], mode,
2915		       plus_constant (Pmode, from,
2916				      off + i * GET_MODE_SIZE (mode))));
2917})
2918
2919(define_insn "*load_multiple_di"
2920  [(match_parallel 0 "load_multiple_operation"
2921		   [(set (match_operand:DI 1 "register_operand" "=r")
2922			 (match_operand:DI 2 "s_operand" "S"))])]
2923  "reload_completed && TARGET_ZARCH"
2924{
2925  int words = XVECLEN (operands[0], 0);
2926  operands[0] = gen_rtx_REG (DImode, REGNO (operands[1]) + words - 1);
2927  return "lmg\t%1,%0,%S2";
2928}
2929   [(set_attr "op_type" "RSY")
2930    (set_attr "type"    "lm")])
2931
2932(define_insn "*load_multiple_si"
2933  [(match_parallel 0 "load_multiple_operation"
2934		   [(set (match_operand:SI 1 "register_operand" "=r,r")
2935			 (match_operand:SI 2 "s_operand" "Q,S"))])]
2936  "reload_completed"
2937{
2938  int words = XVECLEN (operands[0], 0);
2939  operands[0] = gen_rtx_REG (SImode, REGNO (operands[1]) + words - 1);
2940  return which_alternative == 0 ? "lm\t%1,%0,%S2" : "lmy\t%1,%0,%S2";
2941}
2942   [(set_attr "op_type" "RS,RSY")
2943    (set_attr "cpu_facility" "*,longdisp")
2944    (set_attr "type"    "lm")])
2945
2946;
2947; store multiple pattern(s).
2948;
2949
2950(define_expand "store_multiple"
2951  [(match_par_dup 3 [(set (match_operand 0 "" "")
2952			  (match_operand 1 "" ""))
2953		     (use (match_operand 2 "" ""))])]
2954  "reload_completed"
2955{
2956  machine_mode mode;
2957  int regno;
2958  int count;
2959  rtx to;
2960  int i, off;
2961
2962  /* Support only storing a constant number of fixed-point registers to
2963     memory and only bother with this if more than two.  */
2964  if (GET_CODE (operands[2]) != CONST_INT
2965      || INTVAL (operands[2]) < 2
2966      || INTVAL (operands[2]) > 16
2967      || GET_CODE (operands[0]) != MEM
2968      || GET_CODE (operands[1]) != REG
2969      || REGNO (operands[1]) >= 16)
2970    FAIL;
2971
2972  count = INTVAL (operands[2]);
2973  regno = REGNO (operands[1]);
2974  mode = GET_MODE (operands[1]);
2975  if (mode != SImode && (!TARGET_ZARCH || mode != DImode))
2976    FAIL;
2977
2978  operands[3] = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (count));
2979
2980  if (!can_create_pseudo_p ())
2981    {
2982      if (GET_CODE (XEXP (operands[0], 0)) == REG)
2983	{
2984	  to = XEXP (operands[0], 0);
2985	  off = 0;
2986	}
2987      else if (GET_CODE (XEXP (operands[0], 0)) == PLUS
2988	       && GET_CODE (XEXP (XEXP (operands[0], 0), 0)) == REG
2989	       && GET_CODE (XEXP (XEXP (operands[0], 0), 1)) == CONST_INT)
2990	{
2991	  to = XEXP (XEXP (operands[0], 0), 0);
2992	  off = INTVAL (XEXP (XEXP (operands[0], 0), 1));
2993	}
2994      else
2995	FAIL;
2996    }
2997  else
2998    {
2999      to = force_reg (Pmode, XEXP (operands[0], 0));
3000      off = 0;
3001    }
3002
3003  for (i = 0; i < count; i++)
3004    XVECEXP (operands[3], 0, i)
3005      = gen_rtx_SET (change_address (operands[0], mode,
3006		       plus_constant (Pmode, to,
3007				      off + i * GET_MODE_SIZE (mode))),
3008		     gen_rtx_REG (mode, regno + i));
3009})
3010
3011(define_insn "*store_multiple_di"
3012  [(match_parallel 0 "store_multiple_operation"
3013		   [(set (match_operand:DI 1 "s_operand" "=S")
3014			 (match_operand:DI 2 "register_operand" "r"))])]
3015  "reload_completed && TARGET_ZARCH"
3016{
3017  int words = XVECLEN (operands[0], 0);
3018  operands[0] = gen_rtx_REG (DImode, REGNO (operands[2]) + words - 1);
3019  return "stmg\t%2,%0,%S1";
3020}
3021   [(set_attr "op_type" "RSY")
3022    (set_attr "type"    "stm")])
3023
3024
3025(define_insn "*store_multiple_si"
3026  [(match_parallel 0 "store_multiple_operation"
3027		   [(set (match_operand:SI 1 "s_operand" "=Q,S")
3028			 (match_operand:SI 2 "register_operand" "r,r"))])]
3029  "reload_completed"
3030{
3031  int words = XVECLEN (operands[0], 0);
3032  operands[0] = gen_rtx_REG (SImode, REGNO (operands[2]) + words - 1);
3033  return which_alternative == 0 ? "stm\t%2,%0,%S1" : "stmy\t%2,%0,%S1";
3034}
3035   [(set_attr "op_type" "RS,RSY")
3036    (set_attr "cpu_facility" "*,longdisp")
3037    (set_attr "type"    "stm")])
3038
3039;;
3040;; String instructions.
3041;;
3042
3043(define_insn "*execute_rl"
3044  [(match_parallel 0 "execute_operation"
3045    [(unspec [(match_operand 1    "register_operand" "a")
3046	      (match_operand 2    "" "")
3047              (match_operand:SI 3 "larl_operand" "X")] UNSPEC_EXECUTE)])]
3048  "TARGET_Z10 && GET_MODE_CLASS (GET_MODE (operands[1])) == MODE_INT
3049   && GET_MODE_SIZE (GET_MODE (operands[1])) <= UNITS_PER_WORD"
3050  "exrl\t%1,%3"
3051  [(set_attr "op_type" "RIL")
3052   (set_attr "type"    "cs")
3053   (set_attr "relative_long" "yes")])
3054
3055(define_insn "*execute"
3056  [(match_parallel 0 "execute_operation"
3057    [(unspec [(match_operand 1 "register_operand" "a")
3058              (match_operand:BLK 2 "memory_operand" "R")
3059              (match_operand 3 "" "")] UNSPEC_EXECUTE)])]
3060  "GET_MODE_CLASS (GET_MODE (operands[1])) == MODE_INT
3061   && GET_MODE_SIZE (GET_MODE (operands[1])) <= UNITS_PER_WORD"
3062  "ex\t%1,%2"
3063  [(set_attr "op_type" "RX")
3064   (set_attr "type" "cs")])
3065
3066
3067;
3068; strlenM instruction pattern(s).
3069;
3070
3071(define_expand "strlen<mode>"
3072  [(match_operand:P   0 "register_operand" "")  ; result
3073   (match_operand:BLK 1 "memory_operand" "")    ; input string
3074   (match_operand:SI  2 "immediate_operand" "") ; search character
3075   (match_operand:SI  3 "immediate_operand" "")] ; known alignment
3076  ""
3077{
3078  if (!TARGET_VX || operands[2] != const0_rtx)
3079    emit_insn (gen_strlen_srst<mode> (operands[0], operands[1],
3080				      operands[2], operands[3]));
3081  else
3082    s390_expand_vec_strlen (operands[0], operands[1], operands[3]);
3083
3084  DONE;
3085})
3086
3087(define_expand "strlen_srst<mode>"
3088  [(set (reg:SI 0) (match_operand:SI 2 "immediate_operand" ""))
3089   (parallel
3090    [(set (match_dup 4)
3091	  (unspec:P [(const_int 0)
3092		      (match_operand:BLK 1 "memory_operand" "")
3093		      (reg:SI 0)
3094		      (match_operand 3 "immediate_operand" "")] UNSPEC_SRST))
3095     (clobber (scratch:P))
3096     (clobber (reg:CC CC_REGNUM))])
3097   (parallel
3098    [(set (match_operand:P 0 "register_operand" "")
3099          (minus:P (match_dup 4) (match_dup 5)))
3100     (clobber (reg:CC CC_REGNUM))])]
3101  ""
3102{
3103  operands[4] = gen_reg_rtx (Pmode);
3104  operands[5] = gen_reg_rtx (Pmode);
3105  emit_move_insn (operands[5], force_operand (XEXP (operands[1], 0), NULL_RTX));
3106  operands[1] = replace_equiv_address (operands[1], operands[5]);
3107})
3108
3109(define_insn "*strlen<mode>"
3110  [(set (match_operand:P 0 "register_operand" "=a")
3111	(unspec:P [(match_operand:P 2 "general_operand" "0")
3112		    (mem:BLK (match_operand:P 3 "register_operand" "1"))
3113		    (reg:SI 0)
3114		    (match_operand 4 "immediate_operand" "")] UNSPEC_SRST))
3115   (clobber (match_scratch:P 1 "=a"))
3116   (clobber (reg:CC CC_REGNUM))]
3117  ""
3118  "srst\t%0,%1\;jo\t.-4"
3119  [(set_attr "length" "8")
3120   (set_attr "type" "vs")])
3121
3122;
3123; cmpstrM instruction pattern(s).
3124;
3125
3126(define_expand "cmpstrsi"
3127  [(set (reg:SI 0) (const_int 0))
3128   (parallel
3129    [(clobber (match_operand 3 "" ""))
3130     (clobber (match_dup 4))
3131     (set (reg:CCU CC_REGNUM)
3132	  (compare:CCU (match_operand:BLK 1 "memory_operand" "")
3133	 	       (match_operand:BLK 2 "memory_operand" "")))
3134     (use (reg:SI 0))])
3135   (parallel
3136    [(set (match_operand:SI 0 "register_operand" "=d")
3137	  (unspec:SI [(reg:CCU CC_REGNUM)] UNSPEC_STRCMPCC_TO_INT))
3138     (clobber (reg:CC CC_REGNUM))])]
3139  ""
3140{
3141  /* As the result of CMPINT is inverted compared to what we need,
3142     we have to swap the operands.  */
3143  rtx op1 = operands[2];
3144  rtx op2 = operands[1];
3145  rtx addr1 = gen_reg_rtx (Pmode);
3146  rtx addr2 = gen_reg_rtx (Pmode);
3147
3148  emit_move_insn (addr1, force_operand (XEXP (op1, 0), NULL_RTX));
3149  emit_move_insn (addr2, force_operand (XEXP (op2, 0), NULL_RTX));
3150  operands[1] = replace_equiv_address_nv (op1, addr1);
3151  operands[2] = replace_equiv_address_nv (op2, addr2);
3152  operands[3] = addr1;
3153  operands[4] = addr2;
3154})
3155
3156(define_insn "*cmpstr<mode>"
3157  [(clobber (match_operand:P 0 "register_operand" "=d"))
3158   (clobber (match_operand:P 1 "register_operand" "=d"))
3159   (set (reg:CCU CC_REGNUM)
3160	(compare:CCU (mem:BLK (match_operand:P 2 "register_operand" "0"))
3161		     (mem:BLK (match_operand:P 3 "register_operand" "1"))))
3162   (use (reg:SI 0))]
3163  ""
3164  "clst\t%0,%1\;jo\t.-4"
3165  [(set_attr "length" "8")
3166   (set_attr "type" "vs")])
3167
3168;
3169; movstr instruction pattern.
3170;
3171
3172(define_expand "movstr"
3173  [(match_operand 0 "register_operand" "")
3174   (match_operand 1 "memory_operand" "")
3175   (match_operand 2 "memory_operand" "")]
3176  ""
3177{
3178  if (TARGET_64BIT)
3179    emit_insn (gen_movstrdi (operands[0], operands[1], operands[2]));
3180  else
3181    emit_insn (gen_movstrsi (operands[0], operands[1], operands[2]));
3182  DONE;
3183})
3184
3185(define_expand "movstr<P:mode>"
3186  [(set (reg:SI 0) (const_int 0))
3187   (parallel
3188    [(clobber (match_dup 3))
3189     (set (match_operand:BLK 1 "memory_operand" "")
3190	  (match_operand:BLK 2 "memory_operand" ""))
3191     (set (match_operand:P 0 "register_operand" "")
3192	  (unspec:P [(match_dup 1)
3193		   (match_dup 2)
3194		   (reg:SI 0)] UNSPEC_MVST))
3195     (clobber (reg:CC CC_REGNUM))])]
3196  ""
3197{
3198  rtx addr1, addr2;
3199
3200  if (TARGET_VX && optimize_function_for_speed_p (cfun))
3201    {
3202      s390_expand_vec_movstr (operands[0], operands[1], operands[2]);
3203      DONE;
3204    }
3205
3206  addr1 = gen_reg_rtx (Pmode);
3207  addr2 = gen_reg_rtx (Pmode);
3208
3209  emit_move_insn (addr1, force_operand (XEXP (operands[1], 0), NULL_RTX));
3210  emit_move_insn (addr2, force_operand (XEXP (operands[2], 0), NULL_RTX));
3211  operands[1] = replace_equiv_address_nv (operands[1], addr1);
3212  operands[2] = replace_equiv_address_nv (operands[2], addr2);
3213  operands[3] = addr2;
3214})
3215
3216(define_insn "*movstr"
3217  [(clobber (match_operand:P 2 "register_operand" "=d"))
3218   (set (mem:BLK (match_operand:P 1 "register_operand" "0"))
3219	(mem:BLK (match_operand:P 3 "register_operand" "2")))
3220   (set (match_operand:P 0 "register_operand" "=d")
3221	(unspec:P [(mem:BLK (match_dup 1))
3222		 (mem:BLK (match_dup 3))
3223		 (reg:SI 0)] UNSPEC_MVST))
3224   (clobber (reg:CC CC_REGNUM))]
3225  ""
3226  "mvst\t%1,%2\;jo\t.-4"
3227  [(set_attr "length" "8")
3228   (set_attr "type" "vs")])
3229
3230
3231;
3232; cpymemM instruction pattern(s).
3233;
3234
3235(define_expand "cpymem<mode>"
3236  [(set (match_operand:BLK 0 "memory_operand" "")   ; destination
3237        (match_operand:BLK 1 "memory_operand" ""))  ; source
3238   (use (match_operand:GPR 2 "general_operand" "")) ; count
3239   (match_operand 3 "" "")]
3240  ""
3241{
3242  if (s390_expand_cpymem (operands[0], operands[1], operands[2]))
3243    DONE;
3244  else
3245    FAIL;
3246})
3247
3248; Move a block that is up to 256 bytes in length.
3249; The block length is taken as (operands[2] % 256) + 1.
3250
3251(define_expand "cpymem_short"
3252  [(parallel
3253    [(set (match_operand:BLK 0 "memory_operand" "")
3254          (match_operand:BLK 1 "memory_operand" ""))
3255     (use (match_operand 2 "nonmemory_operand" ""))
3256     (use (const:BLK (unspec:BLK [(const_int 0)] UNSPEC_INSN)))
3257     (clobber (match_dup 3))])]
3258  ""
3259  "operands[3] = gen_rtx_SCRATCH (Pmode);")
3260
3261(define_insn "*cpymem_short"
3262  [(set (match_operand:BLK 0 "memory_operand" "=Q,Q,Q,Q")
3263        (match_operand:BLK 1 "memory_operand" "Q,Q,Q,Q"))
3264   (use (match_operand 2 "nonmemory_operand" "n,a,a,a"))
3265   (use (match_operand 3 "immediate_operand" "X,R,X,X"))
3266   (clobber (match_scratch:P 4 "=X,X,X,&a"))]
3267  "(GET_MODE (operands[2]) == Pmode || GET_MODE (operands[2]) == VOIDmode)"
3268  "#"
3269  [(set_attr "type"         "cs")
3270   (set_attr "cpu_facility" "*,*,z10,cpu_zarch")])
3271
3272(define_split
3273  [(set (match_operand:BLK 0 "memory_operand" "")
3274        (match_operand:BLK 1 "memory_operand" ""))
3275   (use (match_operand 2 "const_int_operand" ""))
3276   (use (match_operand 3 "immediate_operand" ""))
3277   (clobber (scratch))]
3278  "reload_completed"
3279  [(parallel
3280    [(set (match_dup 0) (match_dup 1))
3281     (use (match_dup 2))])]
3282  "operands[2] = GEN_INT ((INTVAL (operands[2]) & 0xff) + 1);")
3283
3284(define_split
3285  [(set (match_operand:BLK 0 "memory_operand" "")
3286        (match_operand:BLK 1 "memory_operand" ""))
3287   (use (match_operand 2 "register_operand" ""))
3288   (use (match_operand 3 "memory_operand" ""))
3289   (clobber (scratch))]
3290  "reload_completed"
3291  [(parallel
3292    [(unspec [(match_dup 2) (match_dup 3)
3293              (const_int 0)] UNSPEC_EXECUTE)
3294     (set (match_dup 0) (match_dup 1))
3295     (use (const_int 1))])]
3296  "")
3297
3298(define_split
3299  [(set (match_operand:BLK 0 "memory_operand" "")
3300        (match_operand:BLK 1 "memory_operand" ""))
3301   (use (match_operand 2 "register_operand" ""))
3302   (use (const:BLK (unspec:BLK [(const_int 0)] UNSPEC_INSN)))
3303   (clobber (scratch))]
3304  "TARGET_Z10 && reload_completed"
3305  [(parallel
3306    [(unspec [(match_dup 2) (const_int 0)
3307              (label_ref (match_dup 3))] UNSPEC_EXECUTE)
3308     (set (match_dup 0) (match_dup 1))
3309     (use (const_int 1))])]
3310  "operands[3] = gen_label_rtx ();")
3311
3312(define_split
3313  [(set (match_operand:BLK 0 "memory_operand" "")
3314        (match_operand:BLK 1 "memory_operand" ""))
3315   (use (match_operand 2 "register_operand" ""))
3316   (use (const:BLK (unspec:BLK [(const_int 0)] UNSPEC_INSN)))
3317   (clobber (match_operand 3 "register_operand" ""))]
3318  "reload_completed"
3319  [(set (match_dup 3) (label_ref (match_dup 4)))
3320   (parallel
3321    [(unspec [(match_dup 2) (mem:BLK (match_dup 3))
3322              (label_ref (match_dup 4))] UNSPEC_EXECUTE)
3323     (set (match_dup 0) (match_dup 1))
3324     (use (const_int 1))])]
3325  "operands[4] = gen_label_rtx ();")
3326
3327; Move a block of arbitrary length.
3328
3329(define_expand "cpymem_long"
3330  [(parallel
3331    [(clobber (match_dup 2))
3332     (clobber (match_dup 3))
3333     (set (match_operand:BLK 0 "memory_operand" "")
3334          (match_operand:BLK 1 "memory_operand" ""))
3335     (use (match_operand 2 "general_operand" ""))
3336     (use (match_dup 3))
3337     (clobber (reg:CC CC_REGNUM))])]
3338  ""
3339{
3340  machine_mode sreg_mode = TARGET_ZARCH ? DImode : SImode;
3341  machine_mode dreg_mode = TARGET_ZARCH ? TImode : DImode;
3342  rtx reg0 = gen_reg_rtx (dreg_mode);
3343  rtx reg1 = gen_reg_rtx (dreg_mode);
3344  rtx addr0 = gen_lowpart (Pmode, gen_highpart (sreg_mode, reg0));
3345  rtx addr1 = gen_lowpart (Pmode, gen_highpart (sreg_mode, reg1));
3346  rtx len0 = gen_lowpart (Pmode, reg0);
3347  rtx len1 = gen_lowpart (Pmode, reg1);
3348
3349  emit_clobber (reg0);
3350  emit_move_insn (addr0, force_operand (XEXP (operands[0], 0), NULL_RTX));
3351  emit_move_insn (len0, operands[2]);
3352
3353  emit_clobber (reg1);
3354  emit_move_insn (addr1, force_operand (XEXP (operands[1], 0), NULL_RTX));
3355  emit_move_insn (len1, operands[2]);
3356
3357  operands[0] = replace_equiv_address_nv (operands[0], addr0);
3358  operands[1] = replace_equiv_address_nv (operands[1], addr1);
3359  operands[2] = reg0;
3360  operands[3] = reg1;
3361})
3362
3363(define_insn "*cpymem_long"
3364  [(clobber (match_operand:<DBL> 0 "register_operand" "=d"))
3365   (clobber (match_operand:<DBL> 1 "register_operand" "=d"))
3366   (set (mem:BLK (subreg:P (match_operand:<DBL> 2 "register_operand" "0") 0))
3367        (mem:BLK (subreg:P (match_operand:<DBL> 3 "register_operand" "1") 0)))
3368   (use (match_dup 2))
3369   (use (match_dup 3))
3370   (clobber (reg:CC CC_REGNUM))]
3371  "TARGET_64BIT || !TARGET_ZARCH"
3372  "mvcle\t%0,%1,0\;jo\t.-4"
3373  [(set_attr "length" "8")
3374   (set_attr "type" "vs")])
3375
3376(define_insn "*cpymem_long_31z"
3377  [(clobber (match_operand:TI 0 "register_operand" "=d"))
3378   (clobber (match_operand:TI 1 "register_operand" "=d"))
3379   (set (mem:BLK (subreg:SI (match_operand:TI 2 "register_operand" "0") 4))
3380        (mem:BLK (subreg:SI (match_operand:TI 3 "register_operand" "1") 4)))
3381   (use (match_dup 2))
3382   (use (match_dup 3))
3383   (clobber (reg:CC CC_REGNUM))]
3384  "!TARGET_64BIT && TARGET_ZARCH"
3385  "mvcle\t%0,%1,0\;jo\t.-4"
3386  [(set_attr "length" "8")
3387   (set_attr "type" "vs")])
3388
3389
3390;
3391; Test data class.
3392;
3393
3394(define_expand "signbit<mode>2"
3395  [(set (reg:CCZ CC_REGNUM)
3396        (unspec:CCZ [(match_operand:FP_ALL 1 "register_operand" "f")
3397                     (match_dup 2)]
3398                     UNSPEC_TDC_INSN))
3399   (set (match_operand:SI 0 "register_operand" "=d")
3400        (unspec:SI [(reg:CCZ CC_REGNUM)] UNSPEC_CC_TO_INT))]
3401  "TARGET_HARD_FLOAT"
3402{
3403  operands[2] = GEN_INT (S390_TDC_SIGNBIT_SET);
3404})
3405
3406(define_expand "isinf<mode>2"
3407  [(set (reg:CCZ CC_REGNUM)
3408        (unspec:CCZ [(match_operand:FP_ALL 1 "register_operand" "f")
3409                     (match_dup 2)]
3410                     UNSPEC_TDC_INSN))
3411   (set (match_operand:SI 0 "register_operand" "=d")
3412        (unspec:SI [(reg:CCZ CC_REGNUM)] UNSPEC_CC_TO_INT))]
3413  "TARGET_HARD_FLOAT"
3414{
3415  operands[2] = GEN_INT (S390_TDC_INFINITY);
3416})
3417
3418; This extracts CC into a GPR properly shifted.  The actual IPM
3419; instruction will be issued by reload.  The constraint of operand 1
3420; forces reload to use a GPR.  So reload will issue a movcc insn for
3421; copying CC into a GPR first.
3422(define_insn_and_split "*cc_to_int"
3423  [(set (match_operand:SI 0 "nonimmediate_operand"     "=d")
3424        (unspec:SI [(match_operand 1 "register_operand" "0")]
3425                   UNSPEC_CC_TO_INT))]
3426  "operands != NULL"
3427  "#"
3428  "reload_completed"
3429  [(set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 28)))])
3430
3431; This insn is used to generate all variants of the Test Data Class
3432; instruction, namely tcxb, tcdb, and tceb.  The insn's first operand
3433; is the register to be tested and the second one is the bit mask
3434; specifying the required test(s).
3435;
3436; tcxb, tcdb, tceb, tdcxt, tdcdt, tdcet
3437(define_insn "*TDC_insn_<mode>"
3438  [(set (reg:CCZ CC_REGNUM)
3439        (unspec:CCZ [(match_operand:FP_ALL 0 "register_operand" "f")
3440                     (match_operand:SI 1 "const_int_operand")] UNSPEC_TDC_INSN))]
3441  "TARGET_HARD_FLOAT"
3442  "t<_d>c<xde><bt>\t%0,%1"
3443   [(set_attr "op_type" "RXE")
3444    (set_attr "type"  "fsimp<mode>")])
3445
3446
3447
3448;
3449; setmemM instruction pattern(s).
3450;
3451
3452(define_expand "setmem<mode>"
3453  [(set (match_operand:BLK 0 "memory_operand" "")
3454        (match_operand:QI 2 "general_operand" ""))
3455   (use (match_operand:GPR 1 "general_operand" ""))
3456   (match_operand 3 "" "")]
3457  ""
3458  "s390_expand_setmem (operands[0], operands[1], operands[2]); DONE;")
3459
3460; Clear a block that is up to 256 bytes in length.
3461; The block length is taken as (operands[1] % 256) + 1.
3462
3463(define_expand "clrmem_short"
3464  [(parallel
3465    [(set (match_operand:BLK 0 "memory_operand" "")
3466          (const_int 0))
3467     (use (match_operand 1 "nonmemory_operand" ""))
3468     (use (const:BLK (unspec:BLK [(const_int 0)] UNSPEC_INSN)))
3469     (clobber (match_dup 2))
3470     (clobber (reg:CC CC_REGNUM))])]
3471  ""
3472  "operands[2] = gen_rtx_SCRATCH (Pmode);")
3473
3474(define_insn "*clrmem_short"
3475  [(set (match_operand:BLK 0 "memory_operand" "=Q,Q,Q,Q")
3476        (const_int 0))
3477   (use (match_operand 1 "nonmemory_operand" "n,a,a,a"))
3478   (use (match_operand 2 "immediate_operand" "X,R,X,X"))
3479   (clobber (match_scratch:P 3 "=X,X,X,&a"))
3480   (clobber (reg:CC CC_REGNUM))]
3481  "(GET_MODE (operands[1]) == Pmode || GET_MODE (operands[1]) == VOIDmode)"
3482  "#"
3483  [(set_attr "type" "cs")
3484   (set_attr "cpu_facility" "*,*,z10,cpu_zarch")])
3485
3486(define_split
3487  [(set (match_operand:BLK 0 "memory_operand" "")
3488        (const_int 0))
3489   (use (match_operand 1 "const_int_operand" ""))
3490   (use (match_operand 2 "immediate_operand" ""))
3491   (clobber (scratch))
3492   (clobber (reg:CC CC_REGNUM))]
3493  "reload_completed"
3494  [(parallel
3495    [(set (match_dup 0) (const_int 0))
3496     (use (match_dup 1))
3497     (clobber (reg:CC CC_REGNUM))])]
3498  "operands[1] = GEN_INT ((INTVAL (operands[1]) & 0xff) + 1);")
3499
3500(define_split
3501  [(set (match_operand:BLK 0 "memory_operand" "")
3502        (const_int 0))
3503   (use (match_operand 1 "register_operand" ""))
3504   (use (match_operand 2 "memory_operand" ""))
3505   (clobber (scratch))
3506   (clobber (reg:CC CC_REGNUM))]
3507  "reload_completed"
3508  [(parallel
3509    [(unspec [(match_dup 1) (match_dup 2)
3510              (const_int 0)] UNSPEC_EXECUTE)
3511     (set (match_dup 0) (const_int 0))
3512     (use (const_int 1))
3513     (clobber (reg:CC CC_REGNUM))])]
3514  "")
3515
3516(define_split
3517  [(set (match_operand:BLK 0 "memory_operand" "")
3518        (const_int 0))
3519   (use (match_operand 1 "register_operand" ""))
3520   (use (const:BLK (unspec:BLK [(const_int 0)] UNSPEC_INSN)))
3521   (clobber (scratch))
3522   (clobber (reg:CC CC_REGNUM))]
3523  "TARGET_Z10 && reload_completed"
3524  [(parallel
3525    [(unspec [(match_dup 1) (const_int 0)
3526              (label_ref (match_dup 3))] UNSPEC_EXECUTE)
3527     (set (match_dup 0) (const_int 0))
3528     (use (const_int 1))
3529     (clobber (reg:CC CC_REGNUM))])]
3530  "operands[3] = gen_label_rtx ();")
3531
3532(define_split
3533  [(set (match_operand:BLK 0 "memory_operand" "")
3534        (const_int 0))
3535   (use (match_operand 1 "register_operand" ""))
3536   (use (const:BLK (unspec:BLK [(const_int 0)] UNSPEC_INSN)))
3537   (clobber (match_operand 2 "register_operand" ""))
3538   (clobber (reg:CC CC_REGNUM))]
3539  "reload_completed"
3540  [(set (match_dup 2) (label_ref (match_dup 3)))
3541   (parallel
3542    [(unspec [(match_dup 1) (mem:BLK (match_dup 2))
3543              (label_ref (match_dup 3))] UNSPEC_EXECUTE)
3544     (set (match_dup 0) (const_int 0))
3545     (use (const_int 1))
3546     (clobber (reg:CC CC_REGNUM))])]
3547  "operands[3] = gen_label_rtx ();")
3548
3549; Initialize a block of arbitrary length with (operands[2] % 256).
3550
3551(define_expand "setmem_long_<P:mode>"
3552  [(parallel
3553    [(clobber (match_dup 1))
3554     (set (match_operand:BLK 0 "memory_operand" "")
3555	  (unspec:BLK [(match_operand:P 2 "setmem_operand" "")
3556		      (match_dup 4)] UNSPEC_REPLICATE_BYTE))
3557     (use (match_dup 3))
3558     (clobber (reg:CC CC_REGNUM))])]
3559  ""
3560{
3561  machine_mode sreg_mode = TARGET_ZARCH ? DImode : SImode;
3562  machine_mode dreg_mode = TARGET_ZARCH ? TImode : DImode;
3563  rtx reg0 = gen_reg_rtx (dreg_mode);
3564  rtx reg1 = gen_reg_rtx (dreg_mode);
3565  rtx addr0 = gen_lowpart (Pmode, gen_highpart (sreg_mode, reg0));
3566  rtx len0 = gen_lowpart (Pmode, reg0);
3567
3568  emit_clobber (reg0);
3569  emit_move_insn (addr0, force_operand (XEXP (operands[0], 0), NULL_RTX));
3570  emit_move_insn (len0, operands[1]);
3571
3572  emit_move_insn (reg1, const0_rtx);
3573
3574  operands[0] = replace_equiv_address_nv (operands[0], addr0);
3575  operands[1] = reg0;
3576  operands[3] = reg1;
3577  operands[4] = gen_lowpart (Pmode, operands[1]);
3578})
3579
3580; Patterns for 31 bit + Esa and 64 bit + Zarch.
3581
3582(define_insn "*setmem_long"
3583  [(clobber (match_operand:<DBL> 0 "register_operand" "=d"))
3584   (set (mem:BLK (subreg:P (match_operand:<DBL> 3 "register_operand" "0") 0))
3585        (unspec:BLK [(match_operand:P 2 "setmem_operand" "Y")
3586		     (subreg:P (match_dup 3) <modesize>)]
3587		     UNSPEC_REPLICATE_BYTE))
3588   (use (match_operand:<DBL> 1 "register_operand" "d"))
3589   (clobber (reg:CC CC_REGNUM))]
3590  "TARGET_64BIT || !TARGET_ZARCH"
3591  "mvcle\t%0,%1,%Y2\;jo\t.-4"
3592  [(set_attr "length" "8")
3593   (set_attr "type" "vs")])
3594
3595(define_insn "*setmem_long_and"
3596  [(clobber (match_operand:<DBL> 0 "register_operand" "=d"))
3597   (set (mem:BLK (subreg:P (match_operand:<DBL> 3 "register_operand" "0") 0))
3598        (unspec:BLK [(zero_extend:P (match_operand:QI 2 "setmem_operand" "Y"))
3599		    (subreg:P (match_dup 3) <modesize>)]
3600		    UNSPEC_REPLICATE_BYTE))
3601   (use (match_operand:<DBL> 1 "register_operand" "d"))
3602   (clobber (reg:CC CC_REGNUM))]
3603  "(TARGET_64BIT || !TARGET_ZARCH)"
3604  "mvcle\t%0,%1,%Y2\;jo\t.-4"
3605  [(set_attr "length" "8")
3606   (set_attr "type" "vs")])
3607
3608; Variants for 31 bit + Zarch, necessary because of the odd in-register offsets
3609; of the SImode subregs.
3610
3611(define_insn "*setmem_long_31z"
3612  [(clobber (match_operand:TI 0 "register_operand" "=d"))
3613   (set (mem:BLK (subreg:SI (match_operand:TI 3 "register_operand" "0") 4))
3614        (unspec:BLK [(match_operand:SI 2 "setmem_operand" "Y")
3615		     (subreg:SI (match_dup 3) 12)] UNSPEC_REPLICATE_BYTE))
3616   (use (match_operand:TI 1 "register_operand" "d"))
3617   (clobber (reg:CC CC_REGNUM))]
3618  "!TARGET_64BIT && TARGET_ZARCH"
3619  "mvcle\t%0,%1,%Y2\;jo\t.-4"
3620  [(set_attr "length" "8")
3621   (set_attr "type" "vs")])
3622
3623(define_insn "*setmem_long_and_31z"
3624  [(clobber (match_operand:TI 0 "register_operand" "=d"))
3625   (set (mem:BLK (subreg:SI (match_operand:TI 3 "register_operand" "0") 4))
3626        (unspec:BLK [(zero_extend:SI (match_operand:QI 2 "setmem_operand" "Y"))
3627		    (subreg:SI (match_dup 3) 12)] UNSPEC_REPLICATE_BYTE))
3628   (use (match_operand:TI 1 "register_operand" "d"))
3629   (clobber (reg:CC CC_REGNUM))]
3630  "(!TARGET_64BIT && TARGET_ZARCH)"
3631  "mvcle\t%0,%1,%Y2\;jo\t.-4"
3632  [(set_attr "length" "8")
3633   (set_attr "type" "vs")])
3634
3635;
3636; cmpmemM instruction pattern(s).
3637;
3638
3639(define_expand "cmpmemsi"
3640  [(set (match_operand:SI 0 "register_operand" "")
3641        (compare:SI (match_operand:BLK 1 "memory_operand" "")
3642                    (match_operand:BLK 2 "memory_operand" "") ) )
3643   (use (match_operand:SI 3 "general_operand" ""))
3644   (use (match_operand:SI 4 "" ""))]
3645  ""
3646{
3647  if (s390_expand_cmpmem (operands[0], operands[1],
3648                          operands[2], operands[3]))
3649    DONE;
3650  else
3651    FAIL;
3652})
3653
3654; Compare a block that is up to 256 bytes in length.
3655; The block length is taken as (operands[2] % 256) + 1.
3656
3657(define_expand "cmpmem_short"
3658  [(parallel
3659    [(set (reg:CCU CC_REGNUM)
3660          (compare:CCU (match_operand:BLK 0 "memory_operand" "")
3661                       (match_operand:BLK 1 "memory_operand" "")))
3662     (use (match_operand 2 "nonmemory_operand" ""))
3663     (use (const:BLK (unspec:BLK [(const_int 0)] UNSPEC_INSN)))
3664     (clobber (match_dup 3))])]
3665  ""
3666  "operands[3] = gen_rtx_SCRATCH (Pmode);")
3667
3668(define_insn "*cmpmem_short"
3669  [(set (reg:CCU CC_REGNUM)
3670        (compare:CCU (match_operand:BLK 0 "memory_operand" "Q,Q,Q,Q")
3671                     (match_operand:BLK 1 "memory_operand" "Q,Q,Q,Q")))
3672   (use (match_operand 2 "nonmemory_operand" "n,a,a,a"))
3673   (use (match_operand 3 "immediate_operand" "X,R,X,X"))
3674   (clobber (match_scratch:P 4 "=X,X,X,&a"))]
3675  "(GET_MODE (operands[2]) == Pmode || GET_MODE (operands[2]) == VOIDmode)"
3676  "#"
3677  [(set_attr "type" "cs")
3678   (set_attr "cpu_facility" "*,*,z10,cpu_zarch")])
3679
3680(define_split
3681  [(set (reg:CCU CC_REGNUM)
3682        (compare:CCU (match_operand:BLK 0 "memory_operand" "")
3683                     (match_operand:BLK 1 "memory_operand" "")))
3684   (use (match_operand 2 "const_int_operand" ""))
3685   (use (match_operand 3 "immediate_operand" ""))
3686   (clobber (scratch))]
3687  "reload_completed"
3688  [(parallel
3689    [(set (reg:CCU CC_REGNUM) (compare:CCU (match_dup 0) (match_dup 1)))
3690     (use (match_dup 2))])]
3691  "operands[2] = GEN_INT ((INTVAL (operands[2]) & 0xff) + 1);")
3692
3693(define_split
3694  [(set (reg:CCU CC_REGNUM)
3695        (compare:CCU (match_operand:BLK 0 "memory_operand" "")
3696                     (match_operand:BLK 1 "memory_operand" "")))
3697   (use (match_operand 2 "register_operand" ""))
3698   (use (match_operand 3 "memory_operand" ""))
3699   (clobber (scratch))]
3700  "reload_completed"
3701  [(parallel
3702    [(unspec [(match_dup 2) (match_dup 3)
3703              (const_int 0)] UNSPEC_EXECUTE)
3704     (set (reg:CCU CC_REGNUM) (compare:CCU (match_dup 0) (match_dup 1)))
3705     (use (const_int 1))])]
3706  "")
3707
3708(define_split
3709  [(set (reg:CCU CC_REGNUM)
3710        (compare:CCU (match_operand:BLK 0 "memory_operand" "")
3711                     (match_operand:BLK 1 "memory_operand" "")))
3712   (use (match_operand 2 "register_operand" ""))
3713   (use (const:BLK (unspec:BLK [(const_int 0)] UNSPEC_INSN)))
3714   (clobber (scratch))]
3715  "TARGET_Z10 && reload_completed"
3716  [(parallel
3717    [(unspec [(match_dup 2) (const_int 0)
3718              (label_ref (match_dup 4))] UNSPEC_EXECUTE)
3719     (set (reg:CCU CC_REGNUM) (compare:CCU (match_dup 0) (match_dup 1)))
3720     (use (const_int 1))])]
3721  "operands[4] = gen_label_rtx ();")
3722
3723(define_split
3724  [(set (reg:CCU CC_REGNUM)
3725        (compare:CCU (match_operand:BLK 0 "memory_operand" "")
3726                     (match_operand:BLK 1 "memory_operand" "")))
3727   (use (match_operand 2 "register_operand" ""))
3728   (use (const:BLK (unspec:BLK [(const_int 0)] UNSPEC_INSN)))
3729   (clobber (match_operand 3 "register_operand" ""))]
3730  "reload_completed"
3731  [(set (match_dup 3) (label_ref (match_dup 4)))
3732   (parallel
3733    [(unspec [(match_dup 2) (mem:BLK (match_dup 3))
3734              (label_ref (match_dup 4))] UNSPEC_EXECUTE)
3735     (set (reg:CCU CC_REGNUM) (compare:CCU (match_dup 0) (match_dup 1)))
3736     (use (const_int 1))])]
3737  "operands[4] = gen_label_rtx ();")
3738
3739; Compare a block of arbitrary length.
3740
3741(define_expand "cmpmem_long"
3742  [(parallel
3743    [(clobber (match_dup 2))
3744     (clobber (match_dup 3))
3745     (set (reg:CCU CC_REGNUM)
3746          (compare:CCU (match_operand:BLK 0 "memory_operand" "")
3747                       (match_operand:BLK 1 "memory_operand" "")))
3748     (use (match_operand 2 "general_operand" ""))
3749     (use (match_dup 3))])]
3750  ""
3751{
3752  machine_mode sreg_mode = TARGET_ZARCH ? DImode : SImode;
3753  machine_mode dreg_mode = TARGET_ZARCH ? TImode : DImode;
3754  rtx reg0 = gen_reg_rtx (dreg_mode);
3755  rtx reg1 = gen_reg_rtx (dreg_mode);
3756  rtx addr0 = gen_lowpart (Pmode, gen_highpart (sreg_mode, reg0));
3757  rtx addr1 = gen_lowpart (Pmode, gen_highpart (sreg_mode, reg1));
3758  rtx len0 = gen_lowpart (Pmode, reg0);
3759  rtx len1 = gen_lowpart (Pmode, reg1);
3760
3761  emit_clobber (reg0);
3762  emit_move_insn (addr0, force_operand (XEXP (operands[0], 0), NULL_RTX));
3763  emit_move_insn (len0, operands[2]);
3764
3765  emit_clobber (reg1);
3766  emit_move_insn (addr1, force_operand (XEXP (operands[1], 0), NULL_RTX));
3767  emit_move_insn (len1, operands[2]);
3768
3769  operands[0] = replace_equiv_address_nv (operands[0], addr0);
3770  operands[1] = replace_equiv_address_nv (operands[1], addr1);
3771  operands[2] = reg0;
3772  operands[3] = reg1;
3773})
3774
3775(define_insn "*cmpmem_long"
3776  [(clobber (match_operand:<DBL> 0 "register_operand" "=d"))
3777   (clobber (match_operand:<DBL> 1 "register_operand" "=d"))
3778   (set (reg:CCU CC_REGNUM)
3779        (compare:CCU (mem:BLK (subreg:P (match_operand:<DBL> 2 "register_operand" "0") 0))
3780                     (mem:BLK (subreg:P (match_operand:<DBL> 3 "register_operand" "1") 0))))
3781   (use (match_dup 2))
3782   (use (match_dup 3))]
3783  "TARGET_64BIT || !TARGET_ZARCH"
3784  "clcle\t%0,%1,0\;jo\t.-4"
3785  [(set_attr "length" "8")
3786   (set_attr "type" "vs")])
3787
3788(define_insn "*cmpmem_long_31z"
3789  [(clobber (match_operand:TI 0 "register_operand" "=d"))
3790   (clobber (match_operand:TI 1 "register_operand" "=d"))
3791   (set (reg:CCU CC_REGNUM)
3792        (compare:CCU (mem:BLK (subreg:SI (match_operand:TI 2 "register_operand" "0") 4))
3793                     (mem:BLK (subreg:SI (match_operand:TI 3 "register_operand" "1") 4))))
3794   (use (match_dup 2))
3795   (use (match_dup 3))]
3796  "!TARGET_64BIT && TARGET_ZARCH"
3797  "clcle\t%0,%1,0\;jo\t.-4"
3798  [(set_attr "op_type" "NN")
3799   (set_attr "type"    "vs")
3800   (set_attr "length"  "8")])
3801
3802; Convert CCUmode condition code to integer.
3803; Result is zero if EQ, positive if LTU, negative if GTU.
3804
3805(define_insn_and_split "cmpint"
3806  [(set (match_operand:SI 0 "register_operand" "=d")
3807        (unspec:SI [(match_operand:CCU 1 "register_operand" "0")]
3808                   UNSPEC_STRCMPCC_TO_INT))
3809   (clobber (reg:CC CC_REGNUM))]
3810  ""
3811  "#"
3812  "reload_completed"
3813  [(set (match_dup 0) (ashift:SI (match_dup 0) (const_int 2)))
3814   (parallel
3815    [(set (match_dup 0) (ashiftrt:SI (match_dup 0) (const_int 30)))
3816     (clobber (reg:CC CC_REGNUM))])])
3817
3818(define_insn_and_split "*cmpint_cc"
3819  [(set (reg CC_REGNUM)
3820        (compare (unspec:SI [(match_operand:CCU 1 "register_operand" "0")]
3821                            UNSPEC_STRCMPCC_TO_INT)
3822                 (const_int 0)))
3823   (set (match_operand:SI 0 "register_operand" "=d")
3824        (unspec:SI [(match_dup 1)] UNSPEC_STRCMPCC_TO_INT))]
3825  "s390_match_ccmode (insn, CCSmode)"
3826  "#"
3827  "&& reload_completed"
3828  [(set (match_dup 0) (ashift:SI (match_dup 0) (const_int 2)))
3829   (parallel
3830    [(set (match_dup 2) (match_dup 3))
3831     (set (match_dup 0) (ashiftrt:SI (match_dup 0) (const_int 30)))])]
3832{
3833  rtx result = gen_rtx_ASHIFTRT (SImode, operands[0], GEN_INT (30));
3834  operands[2] = SET_DEST (XVECEXP (PATTERN (curr_insn), 0, 0));
3835  operands[3] = gen_rtx_COMPARE (GET_MODE (operands[2]), result, const0_rtx);
3836})
3837
3838(define_insn_and_split "*cmpint_sign"
3839  [(set (match_operand:DI 0 "register_operand" "=d")
3840        (sign_extend:DI (unspec:SI [(match_operand:CCU 1 "register_operand" "0")]
3841                                   UNSPEC_STRCMPCC_TO_INT)))
3842   (clobber (reg:CC CC_REGNUM))]
3843  "TARGET_ZARCH"
3844  "#"
3845  "&& reload_completed"
3846  [(set (match_dup 0) (ashift:DI (match_dup 0) (const_int 34)))
3847   (parallel
3848    [(set (match_dup 0) (ashiftrt:DI (match_dup 0) (const_int 62)))
3849     (clobber (reg:CC CC_REGNUM))])])
3850
3851(define_insn_and_split "*cmpint_sign_cc"
3852  [(set (reg CC_REGNUM)
3853        (compare (ashiftrt:DI (ashift:DI (subreg:DI
3854                   (unspec:SI [(match_operand:CCU 1 "register_operand" "0")]
3855                              UNSPEC_STRCMPCC_TO_INT) 0)
3856                   (const_int 32)) (const_int 32))
3857                 (const_int 0)))
3858   (set (match_operand:DI 0 "register_operand" "=d")
3859        (sign_extend:DI (unspec:SI [(match_dup 1)] UNSPEC_STRCMPCC_TO_INT)))]
3860  "s390_match_ccmode (insn, CCSmode) && TARGET_ZARCH"
3861  "#"
3862  "&& reload_completed"
3863  [(set (match_dup 0) (ashift:DI (match_dup 0) (const_int 34)))
3864   (parallel
3865    [(set (match_dup 2) (match_dup 3))
3866     (set (match_dup 0) (ashiftrt:DI (match_dup 0) (const_int 62)))])]
3867{
3868  rtx result = gen_rtx_ASHIFTRT (DImode, operands[0], GEN_INT (62));
3869  operands[2] = SET_DEST (XVECEXP (PATTERN (curr_insn), 0, 0));
3870  operands[3] = gen_rtx_COMPARE (GET_MODE (operands[2]), result, const0_rtx);
3871})
3872
3873
3874;;
3875;;- Conversion instructions.
3876;;
3877
3878(define_insn "*sethighpartsi"
3879  [(set (match_operand:SI 0 "register_operand" "=d,d")
3880	(unspec:SI [(match_operand:BLK 1 "s_operand" "Q,S")
3881		    (match_operand 2 "const_int_operand" "n,n")] UNSPEC_ICM))
3882   (clobber (reg:CC CC_REGNUM))]
3883  ""
3884  "@
3885   icm\t%0,%2,%S1
3886   icmy\t%0,%2,%S1"
3887  [(set_attr "op_type" "RS,RSY")
3888   (set_attr "cpu_facility" "*,longdisp")
3889   (set_attr "z10prop" "z10_super_E1,z10_super_E1")])
3890
3891(define_insn "*sethighpartdi_64"
3892  [(set (match_operand:DI 0 "register_operand" "=d")
3893	(unspec:DI [(match_operand:BLK 1 "s_operand" "S")
3894		    (match_operand 2 "const_int_operand" "n")] UNSPEC_ICM))
3895   (clobber (reg:CC CC_REGNUM))]
3896  "TARGET_ZARCH"
3897  "icmh\t%0,%2,%S1"
3898  [(set_attr "op_type" "RSY")
3899   (set_attr "z10prop" "z10_super")])
3900
3901(define_insn "*sethighpartdi_31"
3902  [(set (match_operand:DI 0 "register_operand" "=d,d")
3903	(unspec:DI [(match_operand:BLK 1 "s_operand" "Q,S")
3904		    (match_operand 2 "const_int_operand" "n,n")] UNSPEC_ICM))
3905   (clobber (reg:CC CC_REGNUM))]
3906  "!TARGET_ZARCH"
3907  "@
3908   icm\t%0,%2,%S1
3909   icmy\t%0,%2,%S1"
3910  [(set_attr "op_type" "RS,RSY")
3911   (set_attr "cpu_facility" "*,longdisp")
3912   (set_attr "z10prop" "z10_super_E1,z10_super_E1")])
3913
3914;
3915; extv instruction patterns
3916;
3917
3918; FIXME: This expander needs to be converted from DI to GPR as well
3919; after resolving some issues with it.
3920
3921(define_expand "extzv"
3922  [(parallel
3923    [(set (match_operand:DI 0 "register_operand" "=d")
3924        (zero_extract:DI
3925         (match_operand:DI 1 "register_operand" "d")
3926         (match_operand 2 "const_int_operand" "")   ; size
3927         (match_operand 3 "const_int_operand" ""))) ; start
3928     (clobber (reg:CC CC_REGNUM))])]
3929  "TARGET_Z10"
3930{
3931  if (! EXTRACT_ARGS_IN_RANGE (INTVAL (operands[2]), INTVAL (operands[3]), 64))
3932    FAIL;
3933  /* Starting with zEC12 there is risbgn not clobbering CC.  */
3934  if (TARGET_ZEC12)
3935    {
3936      emit_move_insn (operands[0],
3937                    gen_rtx_ZERO_EXTRACT (DImode,
3938                                          operands[1],
3939                                          operands[2],
3940                                          operands[3]));
3941      DONE;
3942    }
3943})
3944
3945(define_insn "*extzv<mode><clobbercc_or_nocc>"
3946  [(set (match_operand:GPR 0 "register_operand" "=d")
3947      (zero_extract:GPR
3948        (match_operand:GPR 1 "register_operand" "d")
3949        (match_operand 2 "const_int_operand" "")   ; size
3950        (match_operand 3 "const_int_operand" ""))) ; start
3951  ]
3952  "<z10_or_zEC12_cond>
3953   && EXTRACT_ARGS_IN_RANGE (INTVAL (operands[2]), INTVAL (operands[3]),
3954			     GET_MODE_BITSIZE (<MODE>mode))"
3955  "<risbg_n>\t%0,%1,64-%2,128+63,<bitoff_plus>%3+%2" ; dst, src, start, end, shift
3956  [(set_attr "op_type" "RIE")
3957   (set_attr "z10prop" "z10_super_E1")])
3958
3959; 64 bit: (a & -16) | ((b >> 8) & 15)
3960(define_insn "*extzvdi<clobbercc_or_nocc>_lshiftrt"
3961  [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+d")
3962			 (match_operand 1 "const_int_operand" "")  ; size
3963			 (match_operand 2 "const_int_operand" "")) ; start
3964	(lshiftrt:DI (match_operand:DI 3 "register_operand" "d")
3965		     (match_operand:DI 4 "nonzero_shift_count_operand" "")))]
3966  "<z10_or_zEC12_cond>
3967   && EXTRACT_ARGS_IN_RANGE (INTVAL (operands[1]), INTVAL (operands[2]), 64)
3968   && 64 - UINTVAL (operands[4]) >= UINTVAL (operands[1])"
3969  "<risbg_n>\t%0,%3,%2,%2+%1-1,128-%2-%1-%4"
3970  [(set_attr "op_type" "RIE")
3971   (set_attr "z10prop" "z10_super_E1")])
3972
3973; (a & -16) | ((b >> 8) & 15)
3974(define_insn "*<risbg_n>_ior_and_sr_ze<mode>"
3975  [(set (match_operand:DSI 0 "register_operand" "=d")
3976	(ior:DSI (and:DSI
3977		  (match_operand:DSI 1 "register_operand" "0")
3978		  (match_operand:DSI 2 "const_int_operand" ""))
3979		 (zero_extract:DSI
3980		  (match_operand:DSI 3 "register_operand" "d")
3981		  (match_operand 4 "const_int_operand" "")  ; size
3982		  (match_operand 5 "const_int_operand" "")) ; start
3983		  ))]
3984  "<z10_or_zEC12_cond>
3985   && EXTRACT_ARGS_IN_RANGE (INTVAL (operands[4]), INTVAL (operands[5]), <DSI:bitsize>)
3986   && UINTVAL (operands[2]) == (HOST_WIDE_INT_M1U << UINTVAL (operands[4]))"
3987  "<risbg_n>\t%0,%3,64-%4,63,(64-<DSI:bitsize>)+%4+%5"
3988  [(set_attr "op_type" "RIE")
3989   (set_attr "z10prop" "z10_super_E1")])
3990
3991; ((int)foo >> 10) & 1;
3992(define_insn "*extract1bitdi<clobbercc_or_nocc>"
3993  [(set (match_operand:DI 0 "register_operand" "=d")
3994	(ne:DI (zero_extract:DI
3995		(match_operand:DI 1 "register_operand" "d")
3996		(const_int 1)  ; size
3997		(match_operand 2 "const_int_operand" "")) ; start
3998	       (const_int 0)))]
3999  "<z10_or_zEC12_cond>
4000   && EXTRACT_ARGS_IN_RANGE (1, INTVAL (operands[2]), 64)"
4001  "<risbg_n>\t%0,%1,64-1,128+63,%2+1" ; dst, src, start, end, shift
4002  [(set_attr "op_type" "RIE")
4003   (set_attr "z10prop" "z10_super_E1")])
4004
4005(define_insn "*<risbg_n>_and_subregdi_rotr"
4006  [(set (match_operand:DI 0 "register_operand" "=d")
4007	(and:DI (subreg:DI
4008		 (rotate:SINT (match_operand:SINT 1 "register_operand" "d")
4009			     (match_operand:SINT 2 "const_int_operand" "")) 0)
4010		(match_operand:DI 3 "contiguous_bitmask_operand" "")))]
4011  "<z10_or_zEC12_cond>
4012   && (UINTVAL (operands[3])
4013       < (HOST_WIDE_INT_1U << (UINTVAL (operands[2]) & 0x3f)))"
4014  "<risbg_n>\t%0,%1,%s3,128+%e3,<bitoff_plus>%2" ; dst, src, start, end, shift
4015  [(set_attr "op_type" "RIE")
4016   (set_attr "z10prop" "z10_super_E1")])
4017
4018(define_insn "*<risbg_n>_and_subregdi_rotl"
4019  [(set (match_operand:DI 0 "register_operand" "=d")
4020	(and:DI (subreg:DI
4021		 (rotate:SINT (match_operand:SINT 1 "register_operand" "d")
4022			     (match_operand:SINT 2 "const_int_operand" "")) 0)
4023		(match_operand:DI 3 "contiguous_bitmask_operand" "")))]
4024  "<z10_or_zEC12_cond>
4025   && !(UINTVAL (operands[3])
4026	& ((HOST_WIDE_INT_1U << (UINTVAL (operands[2]) & 0x3f)) - 1))"
4027  "<risbg_n>\t%0,%1,%s3,128+%e3,%2" ; dst, src, start, end, shift
4028  [(set_attr "op_type" "RIE")
4029   (set_attr "z10prop" "z10_super_E1")])
4030
4031(define_insn "*<risbg_n>_di_and_rot"
4032  [(set (match_operand:DI 0 "register_operand" "=d")
4033	(and:DI (rotate:DI (match_operand:DI 1 "register_operand" "d")
4034			    (match_operand:DI 2 "const_int_operand" ""))
4035		(match_operand:DI 3 "contiguous_bitmask_operand" "")))]
4036  "<z10_or_zEC12_cond>"
4037  "<risbg_n>\t%0,%1,%s3,128+%e3,%2" ; dst, src, start, end, shift
4038  [(set_attr "op_type" "RIE")
4039   (set_attr "z10prop" "z10_super_E1")])
4040
4041(define_insn_and_split "*pre_z10_extzv<mode>"
4042  [(set (match_operand:GPR 0 "register_operand" "=d")
4043	(zero_extract:GPR (match_operand:QI 1 "s_operand" "S")
4044		          (match_operand 2 "nonzero_shift_count_operand" "")
4045		          (const_int 0)))
4046   (clobber (reg:CC CC_REGNUM))]
4047  "!TARGET_Z10"
4048  "#"
4049  "&& reload_completed"
4050  [(parallel
4051    [(set (match_dup 0) (unspec:GPR [(match_dup 1) (match_dup 3)] UNSPEC_ICM))
4052     (clobber (reg:CC CC_REGNUM))])
4053   (set (match_dup 0) (lshiftrt:GPR (match_dup 0) (match_dup 2)))]
4054{
4055  int bitsize = INTVAL (operands[2]);
4056  int size = (bitsize - 1) / BITS_PER_UNIT + 1; /* round up */
4057  unsigned HOST_WIDE_INT mask
4058    = ((HOST_WIDE_INT_1U << size) - 1) << (GET_MODE_SIZE (SImode) - size);
4059
4060  operands[1] = adjust_address (operands[1], BLKmode, 0);
4061  set_mem_size (operands[1], size);
4062  operands[2] = GEN_INT (<GPR:bitsize> - bitsize);
4063  operands[3] = GEN_INT (mask);
4064})
4065
4066(define_insn_and_split "*pre_z10_extv<mode>"
4067  [(set (match_operand:GPR 0 "register_operand" "=d")
4068	(sign_extract:GPR (match_operand:QI 1 "s_operand" "S")
4069		          (match_operand 2 "nonzero_shift_count_operand" "")
4070		          (const_int 0)))
4071   (clobber (reg:CC CC_REGNUM))]
4072  ""
4073  "#"
4074  "&& reload_completed"
4075  [(parallel
4076    [(set (match_dup 0) (unspec:GPR [(match_dup 1) (match_dup 3)] UNSPEC_ICM))
4077     (clobber (reg:CC CC_REGNUM))])
4078   (parallel
4079    [(set (match_dup 0) (ashiftrt:GPR (match_dup 0) (match_dup 2)))
4080     (clobber (reg:CC CC_REGNUM))])]
4081{
4082  int bitsize = INTVAL (operands[2]);
4083  int size = (bitsize - 1) / BITS_PER_UNIT + 1; /* round up */
4084  unsigned HOST_WIDE_INT mask
4085    = ((HOST_WIDE_INT_1U << size) - 1) << (GET_MODE_SIZE (SImode) - size);
4086
4087  operands[1] = adjust_address (operands[1], BLKmode, 0);
4088  set_mem_size (operands[1], size);
4089  operands[2] = GEN_INT (<GPR:bitsize> - bitsize);
4090  operands[3] = GEN_INT (mask);
4091})
4092
4093;
4094; insv instruction patterns
4095;
4096
4097(define_expand "insv"
4098  [(set (zero_extract (match_operand 0 "nonimmediate_operand" "")
4099		      (match_operand 1 "const_int_operand" "")
4100		      (match_operand 2 "const_int_operand" ""))
4101	(match_operand 3 "general_operand" ""))]
4102  ""
4103{
4104  if (s390_expand_insv (operands[0], operands[1], operands[2], operands[3]))
4105    DONE;
4106  FAIL;
4107})
4108
4109
4110; The normal RTL expansion will never generate a zero_extract where
4111; the location operand isn't word mode.  However, we do this in the
4112; back-end when generating atomic operations. See s390_two_part_insv.
4113(define_insn "*insv<mode><clobbercc_or_nocc>"
4114  [(set (zero_extract:GPR (match_operand:GPR 0 "nonimmediate_operand" "+d")
4115			  (match_operand 1 "const_int_operand"    "I")  ; size
4116			  (match_operand 2 "const_int_operand"    "I")) ; pos
4117	(match_operand:GPR 3 "nonimmediate_operand" "d"))]
4118  "<z10_or_zEC12_cond>
4119   && EXTRACT_ARGS_IN_RANGE (INTVAL (operands[1]), INTVAL (operands[2]),
4120			     GET_MODE_BITSIZE (<MODE>mode))
4121   && (INTVAL (operands[1]) + INTVAL (operands[2])) <= <bitsize>"
4122  "<risbg_n>\t%0,%3,<bitoff_plus>%2,<bitoff_plus>%2+%1-1,<bitsize>-%2-%1"
4123  [(set_attr "op_type" "RIE")
4124   (set_attr "z10prop" "z10_super_E1")])
4125
4126; and op1 with a mask being 1 for the selected bits and 0 for the rest
4127; and op3=op0 with a mask being 0 for the selected bits and 1 for the rest
4128(define_insn "*insv<mode><clobbercc_or_nocc>_noshift"
4129  [(set (match_operand:GPR 0 "nonimmediate_operand" "=d,d")
4130	(ior:GPR (and:GPR (match_operand:GPR 1 "nonimmediate_operand" "d,0")
4131			  (match_operand:GPR 2 "contiguous_bitmask_operand" ""))
4132		 (and:GPR (match_operand:GPR 3 "nonimmediate_operand" "0,d")
4133			  (match_operand:GPR 4 "const_int_operand" ""))))]
4134  "<z10_or_zEC12_cond> && INTVAL (operands[2]) == ~INTVAL (operands[4])"
4135  "@
4136   <risbg_n>\t%0,%1,%<bfstart>2,%<bfend>2,0
4137   <risbg_n>\t%0,%3,%<bfstart>4,%<bfend>4,0"
4138  [(set_attr "op_type" "RIE")
4139   (set_attr "z10prop" "z10_super_E1")])
4140
4141(define_insn "*insv_z10_noshift_cc"
4142  [(set (reg CC_REGNUM)
4143       (compare
4144	(ior:DI
4145	 (and:DI (match_operand:DI 1 "nonimmediate_operand" "d,0")
4146		  (match_operand:DI 2 "contiguous_bitmask_operand" ""))
4147	 (and:DI (match_operand:DI 3 "nonimmediate_operand" "0,d")
4148		  (match_operand:DI 4 "const_int_operand" "")))
4149	(const_int 0)))
4150   (set (match_operand:DI 0 "nonimmediate_operand" "=d,d")
4151	(ior:DI (and:DI (match_dup 1) (match_dup 2))
4152		 (and:DI (match_dup 3) (match_dup 4))))]
4153  "TARGET_Z10 && s390_match_ccmode (insn, CCSmode)
4154   && INTVAL (operands[2]) == ~INTVAL (operands[4])"
4155  "@
4156   risbg\t%0,%1,%s2,%e2,0
4157   risbg\t%0,%3,%s4,%e4,0"
4158  [(set_attr "op_type" "RIE")
4159   (set_attr "z10prop" "z10_super_E1")])
4160
4161(define_insn "*insv_z10_noshift_cconly"
4162  [(set
4163    (reg CC_REGNUM)
4164    (compare
4165     (ior:DI
4166      (and:DI (match_operand:DI 1 "nonimmediate_operand" "d,0")
4167	       (match_operand:DI 2 "contiguous_bitmask_operand" ""))
4168      (and:DI (match_operand:DI 3 "nonimmediate_operand" "0,d")
4169	       (match_operand:DI 4 "const_int_operand" "")))
4170     (const_int 0)))
4171  (clobber (match_scratch:DI 0 "=d,d"))]
4172  "TARGET_Z10 && s390_match_ccmode (insn, CCSmode)
4173   && INTVAL (operands[2]) == ~INTVAL (operands[4])"
4174  "@
4175   risbg\t%0,%1,%s2,%e2,0
4176   risbg\t%0,%3,%s4,%e4,0"
4177  [(set_attr "op_type" "RIE")
4178   (set_attr "z10prop" "z10_super_E1")])
4179
4180; Implement appending Y on the left of S bits of X
4181; x = (y << s) | (x & ((1 << s) - 1))
4182(define_insn "*insv<mode><clobbercc_or_nocc>_appendbitsleft"
4183  [(set (match_operand:GPR 0 "nonimmediate_operand" "=d")
4184	(ior:GPR (and:GPR (match_operand:GPR 1 "nonimmediate_operand" "0")
4185			  (match_operand:GPR 2 "immediate_operand" ""))
4186		 (ashift:GPR (match_operand:GPR 3 "nonimmediate_operand" "d")
4187			     (match_operand:GPR 4 "nonzero_shift_count_operand" ""))))]
4188  "<z10_or_zEC12_cond>
4189   && UINTVAL (operands[2]) == (HOST_WIDE_INT_1U << UINTVAL (operands[4])) - 1"
4190  "<risbg_n>\t%0,%3,<bitoff>,64-%4-1,%4"
4191  [(set_attr "op_type" "RIE")
4192   (set_attr "z10prop" "z10_super_E1")])
4193
4194; a = ((i32)a & -16777216) | (((ui32)b) >> 8)
4195(define_insn "*<risbg_n>_<mode>_ior_and_lshiftrt"
4196  [(set (match_operand:GPR 0 "register_operand" "=d")
4197	(ior:GPR (and:GPR
4198		  (match_operand:GPR 1 "register_operand" "0")
4199		  (match_operand:GPR 2 "const_int_operand" ""))
4200		 (lshiftrt:GPR
4201		  (match_operand:GPR 3 "register_operand" "d")
4202		  (match_operand:GPR 4 "nonzero_shift_count_operand" ""))))]
4203  "<z10_or_zEC12_cond> && UINTVAL (operands[2])
4204   == (HOST_WIDE_INT_M1U
4205       << (GET_MODE_BITSIZE (<MODE>mode) - UINTVAL (operands[4])))"
4206  "<risbg_n>\t%0,%3,<bitoff_plus>%4,63,64-%4"
4207  [(set_attr "op_type" "RIE")
4208   (set_attr "z10prop" "z10_super_E1")])
4209
4210; (ui32)(((ui64)x) >> 48) | ((i32)y & -65536);
4211(define_insn "*<risbg_n>_sidi_ior_and_lshiftrt"
4212  [(set (match_operand:SI 0 "register_operand" "=d")
4213	(ior:SI (and:SI
4214		 (match_operand:SI 1 "register_operand" "0")
4215		 (match_operand:SI 2 "const_int_operand" ""))
4216		(subreg:SI
4217		 (lshiftrt:DI
4218		  (match_operand:DI 3 "register_operand" "d")
4219		  (match_operand:DI 4 "nonzero_shift_count_operand" "")) 4)))]
4220  "<z10_or_zEC12_cond>
4221   && UINTVAL (operands[2]) == ~(HOST_WIDE_INT_M1U >> UINTVAL (operands[4]))"
4222  "<risbg_n>\t%0,%3,%4,63,64-%4"
4223  [(set_attr "op_type" "RIE")
4224   (set_attr "z10prop" "z10_super_E1")])
4225
4226; (ui32)(((ui64)x) >> 12) & -4
4227(define_insn "*trunc_sidi_and_subreg_lshrt<clobbercc_or_nocc>"
4228  [(set (match_operand:SI 0 "register_operand" "=d")
4229	(and:SI
4230	 (subreg:SI (lshiftrt:DI
4231		     (match_operand:DI 1 "register_operand" "d")
4232		     (match_operand:DI 2 "nonzero_shift_count_operand" "")) 4)
4233	 (match_operand:SI 3 "contiguous_bitmask_nowrap_operand" "")))]
4234  "<z10_or_zEC12_cond>"
4235  "<risbg_n>\t%0,%1,%t3,128+%f3,64-%2"
4236  [(set_attr "op_type" "RIE")
4237   (set_attr "z10prop" "z10_super_E1")])
4238
4239; (ui32)(((ui64)x) >> 12) & -4
4240(define_insn "*trunc_sidi_and_subreg_ze<clobbercc_or_nocc>"
4241  [(set (match_operand:SI 0 "register_operand" "=d")
4242	(and:SI
4243	 (subreg:SI (zero_extract:DI
4244		     (match_operand:DI 1 "register_operand" "d")
4245		     (const_int 32)
4246		     (match_operand:SI 2 "nonzero_shift_count_operand" "")) 4)
4247	 (match_operand:SI 3 "contiguous_bitmask_nowrap_operand" "")))]
4248  "<z10_or_zEC12_cond>"
4249  "<risbg_n>\t%0,%1,%t3,128+%f3,32+%2"
4250  [(set_attr "op_type" "RIE")
4251   (set_attr "z10prop" "z10_super_E1")])
4252
4253; z = (x << c) | (y >> d) with (x << c) and (y >> d) not overlapping after shifting
4254;  -> z = y >> d; z = (x << c) | (z & ((1 << c) - 1))
4255;  -> z = y >> d; z = risbg;
4256
4257(define_split
4258  [(set (match_operand:GPR 0 "nonimmediate_operand" "")
4259	(ior:GPR (lshiftrt:GPR (match_operand:GPR 1 "nonimmediate_operand" "")
4260			       (match_operand:GPR 2 "nonzero_shift_count_operand" ""))
4261		 (ashift:GPR (match_operand:GPR 3 "nonimmediate_operand" "")
4262			     (match_operand:GPR 4 "nonzero_shift_count_operand" ""))))]
4263  "TARGET_ZEC12 && UINTVAL (operands[2]) + UINTVAL (operands[4]) >= <bitsize>"
4264  [(set (match_dup 6)
4265	(lshiftrt:GPR (match_dup 1) (match_dup 2)))
4266   (set (match_dup 0)
4267	(ior:GPR (and:GPR (match_dup 6) (match_dup 5))
4268		 (ashift:GPR (match_dup 3) (match_dup 4))))]
4269{
4270  operands[5] = GEN_INT ((HOST_WIDE_INT_1U << UINTVAL (operands[4])) - 1);
4271  if (reg_overlap_mentioned_p (operands[0], operands[3]))
4272    {
4273      if (!can_create_pseudo_p ())
4274	FAIL;
4275      operands[6] = gen_reg_rtx (<MODE>mode);
4276    }
4277  else
4278    operands[6] = operands[0];
4279})
4280
4281(define_split
4282  [(parallel
4283    [(set (match_operand:GPR 0 "nonimmediate_operand" "")
4284	  (ior:GPR (lshiftrt:GPR (match_operand:GPR 1 "nonimmediate_operand" "")
4285				 (match_operand:GPR 2 "nonzero_shift_count_operand" ""))
4286		   (ashift:GPR (match_operand:GPR 3 "nonimmediate_operand" "")
4287			       (match_operand:GPR 4 "nonzero_shift_count_operand" ""))))
4288     (clobber (reg:CC CC_REGNUM))])]
4289  "TARGET_Z10 && !TARGET_ZEC12 && UINTVAL (operands[2]) + UINTVAL (operands[4]) >= <bitsize>"
4290  [(set (match_dup 6)
4291	(lshiftrt:GPR (match_dup 1) (match_dup 2)))
4292   (parallel
4293    [(set (match_dup 0)
4294	  (ior:GPR (and:GPR (match_dup 6) (match_dup 5))
4295		   (ashift:GPR (match_dup 3) (match_dup 4))))
4296     (clobber (reg:CC CC_REGNUM))])]
4297{
4298  operands[5] = GEN_INT ((HOST_WIDE_INT_1U << UINTVAL (operands[4])) - 1);
4299  if (reg_overlap_mentioned_p (operands[0], operands[3]))
4300    {
4301      if (!can_create_pseudo_p ())
4302	FAIL;
4303      operands[6] = gen_reg_rtx (<MODE>mode);
4304    }
4305  else
4306    operands[6] = operands[0];
4307})
4308
4309; rosbg, rxsbg
4310(define_insn "*r<noxa>sbg_<mode>_noshift"
4311  [(set (match_operand:GPR 0 "nonimmediate_operand" "=d")
4312	(IXOR:GPR
4313	  (and:GPR (match_operand:GPR 1 "nonimmediate_operand" "d")
4314                   (match_operand:GPR 2 "contiguous_bitmask_operand" ""))
4315	  (match_operand:GPR 3 "nonimmediate_operand" "0")))
4316   (clobber (reg:CC CC_REGNUM))]
4317  "TARGET_Z10"
4318  "r<noxa>sbg\t%0,%1,%<bfstart>2,%<bfend>2,0"
4319  [(set_attr "op_type" "RIE")])
4320
4321; rosbg, rxsbg
4322(define_insn "*r<noxa>sbg_di_rotl"
4323  [(set (match_operand:DI 0 "nonimmediate_operand" "=d")
4324	(IXOR:DI
4325	  (and:DI
4326	    (rotate:DI
4327	      (match_operand:DI 1 "nonimmediate_operand" "d")
4328              (match_operand:DI 3 "const_int_operand" ""))
4329            (match_operand:DI 2 "contiguous_bitmask_operand" ""))
4330	  (match_operand:DI 4 "nonimmediate_operand" "0")))
4331   (clobber (reg:CC CC_REGNUM))]
4332  "TARGET_Z10"
4333  "r<noxa>sbg\t%0,%1,%s2,%e2,%b3"
4334  [(set_attr "op_type" "RIE")])
4335
4336; rosbg, rxsbg
4337(define_insn "*r<noxa>sbg_<mode>_srl_bitmask"
4338  [(set (match_operand:GPR 0 "nonimmediate_operand" "=d")
4339	(IXOR:GPR
4340	  (and:GPR
4341	    (lshiftrt:GPR
4342              (match_operand:GPR 1 "nonimmediate_operand" "d")
4343              (match_operand:GPR 3 "nonzero_shift_count_operand" ""))
4344            (match_operand:GPR 2 "contiguous_bitmask_nowrap_operand" ""))
4345	  (match_operand:GPR 4 "nonimmediate_operand" "0")))
4346   (clobber (reg:CC CC_REGNUM))]
4347  "TARGET_Z10
4348   && s390_extzv_shift_ok (<bitsize>, 64 - INTVAL (operands[3]),
4349                           INTVAL (operands[2]))"
4350  {
4351    operands[3] = GEN_INT (64 - INTVAL (operands[3]));
4352    return "r<noxa>sbg\t%0,%1,%<bfstart>2,%<bfend>2,%3";
4353  }
4354  [(set_attr "op_type" "RIE")])
4355
4356; rosbg, rxsbg
4357(define_insn "*r<noxa>sbg_<mode>_sll_bitmask"
4358  [(set (match_operand:GPR 0 "nonimmediate_operand" "=d")
4359	(IXOR:GPR
4360	  (and:GPR
4361	    (ashift:GPR
4362              (match_operand:GPR 1 "nonimmediate_operand" "d")
4363              (match_operand:GPR 3 "nonzero_shift_count_operand" ""))
4364            (match_operand:GPR 2 "contiguous_bitmask_nowrap_operand" ""))
4365	  (match_operand:GPR 4 "nonimmediate_operand" "0")))
4366   (clobber (reg:CC CC_REGNUM))]
4367  "TARGET_Z10
4368   && s390_extzv_shift_ok (<bitsize>, INTVAL (operands[3]),
4369                           INTVAL (operands[2]))"
4370  "r<noxa>sbg\t%0,%1,%<bfstart>2,%<bfend>2,%3"
4371  [(set_attr "op_type" "RIE")])
4372
4373;; unsigned {int,long} a, b
4374;; a = a | (b << const_int)
4375;; a = a ^ (b << const_int)
4376; rosbg, rxsbg
4377(define_insn "*r<noxa>sbg_<mode>_sll"
4378  [(set (match_operand:GPR 0 "nonimmediate_operand" "=d")
4379	(IXOR:GPR
4380	  (ashift:GPR
4381            (match_operand:GPR 1 "nonimmediate_operand" "d")
4382            (match_operand:GPR 2 "nonzero_shift_count_operand" ""))
4383	  (match_operand:GPR 3 "nonimmediate_operand" "0")))
4384   (clobber (reg:CC CC_REGNUM))]
4385  "TARGET_Z10"
4386  {
4387    operands[3] = GEN_INT (63 - INTVAL (operands[2]));
4388    return "r<noxa>sbg\t%0,%1,<bitoff>,%3,%2";
4389  }
4390  [(set_attr "op_type" "RIE")])
4391
4392;; unsigned {int,long} a, b
4393;; a = a | (b >> const_int)
4394;; a = a ^ (b >> const_int)
4395; rosbg, rxsbg
4396(define_insn "*r<noxa>sbg_<mode>_srl"
4397  [(set (match_operand:GPR 0 "nonimmediate_operand" "=d")
4398	(IXOR:GPR
4399	  (lshiftrt:GPR
4400            (match_operand:GPR 1 "nonimmediate_operand" "d")
4401            (match_operand:GPR 2 "nonzero_shift_count_operand" ""))
4402	  (match_operand:GPR 3 "nonimmediate_operand" "0")))
4403   (clobber (reg:CC CC_REGNUM))]
4404  "TARGET_Z10"
4405  {
4406    operands[3] = GEN_INT (64 - INTVAL (operands[2]));
4407    operands[2] = GEN_INT (<bitoff_plus> INTVAL (operands[2]));
4408    return "r<noxa>sbg\t%0,%1,%2,63,%3";
4409  }
4410  [(set_attr "op_type" "RIE")])
4411
4412; rosbg, rxsbg
4413(define_insn "*r<noxa>sbg_sidi_srl"
4414  [(set (match_operand:SI 0 "nonimmediate_operand" "=d")
4415        (IXOR:SI
4416          (subreg:SI
4417            (zero_extract:DI
4418              (match_operand:DI 1 "nonimmediate_operand" "d")
4419              (const_int 32)
4420              (match_operand:DI 2 "immediate_operand" ""))
4421            4)
4422          (match_operand:SI 3 "nonimmediate_operand" "0")))
4423   (clobber (reg:CC CC_REGNUM))]
4424  "TARGET_Z10"
4425  {
4426    operands[2] = GEN_INT (32 + INTVAL (operands[2]));
4427    return "r<noxa>sbg\t%0,%1,32,63,%2";
4428  }
4429  [(set_attr "op_type" "RIE")])
4430
4431;; These two are generated by combine for s.bf &= val.
4432;; ??? For bitfields smaller than 32-bits, we wind up with SImode
4433;; shifts and ands, which results in some truly awful patterns
4434;; including subregs of operations.  Rather unnecessisarily, IMO.
4435;; Instead of
4436;;
4437;; (set (zero_extract:DI (reg/v:DI 50 [ s ])
4438;;        (const_int 24 [0x18])
4439;;        (const_int 0 [0]))
4440;;    (subreg:DI (and:SI (subreg:SI (lshiftrt:DI (reg/v:DI 50 [ s ])
4441;;                    (const_int 40 [0x28])) 4)
4442;;            (reg:SI 4 %r4 [ y+4 ])) 0))
4443;;
4444;; we should instead generate
4445;;
4446;; (set (zero_extract:DI (reg/v:DI 50 [ s ])
4447;;        (const_int 24 [0x18])
4448;;        (const_int 0 [0]))
4449;;    (and:DI (lshiftrt:DI (reg/v:DI 50 [ s ])
4450;;                    (const_int 40 [0x28]))
4451;;            (subreg:DI (reg:SI 4 %r4 [ y+4 ]) 0)))
4452;;
4453;; by noticing that we can push down the outer paradoxical subreg
4454;; into the operation.
4455
4456(define_insn "*insv_rnsbg_noshift"
4457  [(set (zero_extract:DI
4458	  (match_operand:DI 0 "nonimmediate_operand" "+d")
4459	  (match_operand 1 "const_int_operand" "")
4460	  (match_operand 2 "const_int_operand" ""))
4461	(and:DI
4462	  (match_dup 0)
4463	  (match_operand:DI 3 "nonimmediate_operand" "d")))
4464   (clobber (reg:CC CC_REGNUM))]
4465  "TARGET_Z10
4466   && EXTRACT_ARGS_IN_RANGE (INTVAL (operands[1]), INTVAL (operands[2]), 64)
4467   && INTVAL (operands[1]) + INTVAL (operands[2]) == 64"
4468  "rnsbg\t%0,%3,%2,63,0"
4469  [(set_attr "op_type" "RIE")])
4470
4471(define_insn "*insv_rnsbg_srl"
4472  [(set (zero_extract:DI
4473	  (match_operand:DI 0 "nonimmediate_operand" "+d")
4474	  (match_operand 1 "const_int_operand" "")
4475	  (match_operand 2 "const_int_operand" ""))
4476	(and:DI
4477	  (lshiftrt:DI
4478	    (match_dup 0)
4479	    (match_operand 3 "const_int_operand" ""))
4480	  (match_operand:DI 4 "nonimmediate_operand" "d")))
4481   (clobber (reg:CC CC_REGNUM))]
4482  "TARGET_Z10
4483   && EXTRACT_ARGS_IN_RANGE (INTVAL (operands[1]), INTVAL (operands[2]), 64)
4484   && INTVAL (operands[3]) == 64 - INTVAL (operands[1]) - INTVAL (operands[2])"
4485  "rnsbg\t%0,%4,%2,%2+%1-1,%3"
4486  [(set_attr "op_type" "RIE")])
4487
4488(define_insn "*insv<mode>_mem_reg"
4489  [(set (zero_extract:W (match_operand:QI 0 "memory_operand" "+Q,S")
4490			(match_operand 1 "const_int_operand" "n,n")
4491			(const_int 0))
4492	(match_operand:W 2 "register_operand" "d,d"))]
4493  "EXTRACT_ARGS_IN_RANGE (INTVAL (operands[1]), 0, 64)
4494   && INTVAL (operands[1]) > 0
4495   && INTVAL (operands[1]) <= GET_MODE_BITSIZE (SImode)
4496   && INTVAL (operands[1]) % BITS_PER_UNIT == 0"
4497{
4498    int size = INTVAL (operands[1]) / BITS_PER_UNIT;
4499
4500    operands[1] = GEN_INT ((HOST_WIDE_INT_1U << size) - 1);
4501    return (which_alternative == 0) ? "stcm\t%2,%1,%S0"
4502				    : "stcmy\t%2,%1,%S0";
4503}
4504  [(set_attr "op_type" "RS,RSY")
4505   (set_attr "cpu_facility" "*,longdisp")
4506   (set_attr "z10prop" "z10_super,z10_super")])
4507
4508(define_insn "*insvdi_mem_reghigh"
4509  [(set (zero_extract:DI (match_operand:QI 0 "memory_operand" "+S")
4510			 (match_operand 1 "const_int_operand" "n")
4511			 (const_int 0))
4512	(lshiftrt:DI (match_operand:DI 2 "register_operand" "d")
4513		     (const_int 32)))]
4514  "TARGET_ZARCH
4515   && EXTRACT_ARGS_IN_RANGE (INTVAL (operands[1]), 0, 64)
4516   && INTVAL (operands[1]) > 0
4517   && INTVAL (operands[1]) <= GET_MODE_BITSIZE (SImode)
4518   && INTVAL (operands[1]) % BITS_PER_UNIT == 0"
4519{
4520    int size = INTVAL (operands[1]) / BITS_PER_UNIT;
4521
4522    operands[1] = GEN_INT ((HOST_WIDE_INT_1U << size) - 1);
4523    return "stcmh\t%2,%1,%S0";
4524}
4525[(set_attr "op_type" "RSY")
4526 (set_attr "z10prop" "z10_super")])
4527
4528(define_insn "*insvdi_reg_imm"
4529  [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+d")
4530			 (const_int 16)
4531			 (match_operand 1 "const_int_operand" "n"))
4532	(match_operand:DI 2 "const_int_operand" "n"))]
4533  "TARGET_ZARCH
4534   && EXTRACT_ARGS_IN_RANGE (16, INTVAL (operands[1]), 64)
4535   && INTVAL (operands[1]) >= 0
4536   && INTVAL (operands[1]) < BITS_PER_WORD
4537   && INTVAL (operands[1]) % 16 == 0"
4538{
4539  switch (BITS_PER_WORD - INTVAL (operands[1]))
4540    {
4541      case 64: return "iihh\t%0,%x2"; break;
4542      case 48: return "iihl\t%0,%x2"; break;
4543      case 32: return "iilh\t%0,%x2"; break;
4544      case 16: return "iill\t%0,%x2"; break;
4545      default: gcc_unreachable();
4546    }
4547}
4548  [(set_attr "op_type" "RI")
4549   (set_attr "z10prop" "z10_super_E1")])
4550
4551; Update the left-most 32 bit of a DI.
4552(define_insn "*insv_h_di_reg_extimm"
4553  [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+d")
4554			 (const_int 32)
4555			 (const_int 0))
4556	(match_operand:DI 1 "const_int_operand" "n"))]
4557  "TARGET_EXTIMM"
4558  "iihf\t%0,%o1"
4559  [(set_attr "op_type" "RIL")
4560   (set_attr "z10prop" "z10_fwd_E1")])
4561
4562; Update the right-most 32 bit of a DI.
4563(define_insn "*insv_l_di_reg_extimm"
4564  [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+d")
4565			 (const_int 32)
4566			 (const_int 32))
4567	(match_operand:DI 1 "const_int_operand" "n"))]
4568  "TARGET_EXTIMM"
4569  "iilf\t%0,%o1"
4570  [(set_attr "op_type" "RIL")
4571   (set_attr "z10prop" "z10_fwd_A1")])
4572
4573;
4574; extendsidi2 instruction pattern(s).
4575;
4576
4577(define_expand "extendsidi2"
4578  [(set (match_operand:DI 0 "register_operand" "")
4579        (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "")))]
4580  ""
4581{
4582  if (!TARGET_ZARCH)
4583    {
4584      emit_clobber (operands[0]);
4585      emit_move_insn (gen_highpart (SImode, operands[0]), operands[1]);
4586      emit_move_insn (gen_lowpart (SImode, operands[0]), const0_rtx);
4587      emit_insn (gen_ashrdi3 (operands[0], operands[0], GEN_INT (32)));
4588      DONE;
4589    }
4590})
4591
4592(define_insn "*extendsidi2"
4593  [(set (match_operand:DI 0 "register_operand" "=d,d,d")
4594        (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "d,T,b")))]
4595  "TARGET_ZARCH"
4596  "@
4597   lgfr\t%0,%1
4598   lgf\t%0,%1
4599   lgfrl\t%0,%1"
4600  [(set_attr "op_type"      "RRE,RXY,RIL")
4601   (set_attr "type"         "*,*,larl")
4602   (set_attr "cpu_facility" "*,*,z10")
4603   (set_attr "z10prop" "z10_super_E1,z10_super_E1,z10_super_E1")
4604   (set_attr "relative_long" "*,*,yes")])
4605
4606;
4607; extend(hi|qi)(si|di)2 instruction pattern(s).
4608;
4609
4610(define_expand "extend<HQI:mode><DSI:mode>2"
4611  [(set (match_operand:DSI 0 "register_operand" "")
4612        (sign_extend:DSI (match_operand:HQI 1 "nonimmediate_operand" "")))]
4613  ""
4614{
4615  if (<DSI:MODE>mode == DImode && !TARGET_ZARCH)
4616    {
4617      rtx tmp = gen_reg_rtx (SImode);
4618      emit_insn (gen_extend<HQI:mode>si2 (tmp, operands[1]));
4619      emit_insn (gen_extendsidi2 (operands[0], tmp));
4620      DONE;
4621    }
4622  else if (!TARGET_EXTIMM)
4623    {
4624      rtx bitcount = GEN_INT (<DSI:bitsize> - <HQI:bitsize>);
4625
4626      operands[1] = gen_lowpart (<DSI:MODE>mode, operands[1]);
4627      emit_insn (gen_ashl<DSI:mode>3 (operands[0], operands[1], bitcount));
4628      emit_insn (gen_ashr<DSI:mode>3 (operands[0], operands[0], bitcount));
4629      DONE;
4630    }
4631})
4632
4633;
4634; extendhidi2 instruction pattern(s).
4635;
4636
4637(define_insn "*extendhidi2_extimm"
4638  [(set (match_operand:DI 0 "register_operand" "=d,d,d")
4639        (sign_extend:DI (match_operand:HI 1 "general_operand" "d,T,b")))]
4640  "TARGET_ZARCH && TARGET_EXTIMM"
4641  "@
4642   lghr\t%0,%1
4643   lgh\t%0,%1
4644   lghrl\t%0,%1"
4645  [(set_attr "op_type"      "RRE,RXY,RIL")
4646   (set_attr "type"         "*,*,larl")
4647   (set_attr "cpu_facility" "extimm,extimm,z10")
4648   (set_attr "z10prop" "z10_super_E1,z10_super_E1,z10_super_E1")
4649   (set_attr "relative_long" "*,*,yes")])
4650
4651(define_insn "*extendhidi2"
4652  [(set (match_operand:DI 0 "register_operand" "=d")
4653        (sign_extend:DI (match_operand:HI 1 "memory_operand" "T")))]
4654  "TARGET_ZARCH"
4655  "lgh\t%0,%1"
4656  [(set_attr "op_type" "RXY")
4657   (set_attr "z10prop" "z10_super_E1")])
4658
4659;
4660; extendhisi2 instruction pattern(s).
4661;
4662
4663(define_insn "*extendhisi2_extimm"
4664  [(set (match_operand:SI 0 "register_operand" "=d,d,d,d")
4665        (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" " d,R,T,b")))]
4666  "TARGET_EXTIMM"
4667  "@
4668   lhr\t%0,%1
4669   lh\t%0,%1
4670   lhy\t%0,%1
4671   lhrl\t%0,%1"
4672  [(set_attr "op_type"      "RRE,RX,RXY,RIL")
4673   (set_attr "type"         "*,*,*,larl")
4674   (set_attr "cpu_facility" "extimm,extimm,extimm,z10")
4675   (set_attr "z10prop" "z10_super_E1,z10_super_E1,z10_super_E1,z10_super_E1")
4676   (set_attr "relative_long" "*,*,*,yes")])
4677
4678(define_insn "*extendhisi2"
4679  [(set (match_operand:SI 0 "register_operand" "=d,d")
4680        (sign_extend:SI (match_operand:HI 1 "memory_operand" "R,T")))]
4681  "!TARGET_EXTIMM"
4682  "@
4683   lh\t%0,%1
4684   lhy\t%0,%1"
4685  [(set_attr "op_type" "RX,RXY")
4686   (set_attr "cpu_facility" "*,longdisp")
4687   (set_attr "z10prop" "z10_super_E1,z10_super_E1")])
4688
4689;
4690; extendqi(si|di)2 instruction pattern(s).
4691;
4692
4693; lbr, lgbr, lb, lgb
4694(define_insn "*extendqi<mode>2_extimm"
4695  [(set (match_operand:GPR 0 "register_operand" "=d,d")
4696        (sign_extend:GPR (match_operand:QI 1 "nonimmediate_operand" "d,T")))]
4697  "TARGET_EXTIMM"
4698  "@
4699   l<g>br\t%0,%1
4700   l<g>b\t%0,%1"
4701  [(set_attr "op_type" "RRE,RXY")
4702   (set_attr "z10prop" "z10_super_E1,z10_super_E1")])
4703
4704; lb, lgb
4705(define_insn "*extendqi<mode>2"
4706  [(set (match_operand:GPR 0 "register_operand" "=d")
4707        (sign_extend:GPR (match_operand:QI 1 "memory_operand" "T")))]
4708  "!TARGET_EXTIMM && TARGET_LONG_DISPLACEMENT"
4709  "l<g>b\t%0,%1"
4710  [(set_attr "op_type" "RXY")
4711   (set_attr "z10prop" "z10_super_E1")])
4712
4713(define_insn_and_split "*extendqi<mode>2_short_displ"
4714  [(set (match_operand:GPR 0 "register_operand" "=d")
4715        (sign_extend:GPR (match_operand:QI 1 "s_operand" "Q")))
4716   (clobber (reg:CC CC_REGNUM))]
4717  "!TARGET_EXTIMM && !TARGET_LONG_DISPLACEMENT"
4718  "#"
4719  "&& reload_completed"
4720  [(parallel
4721    [(set (match_dup 0) (unspec:GPR [(match_dup 1) (const_int 8)] UNSPEC_ICM))
4722     (clobber (reg:CC CC_REGNUM))])
4723   (parallel
4724    [(set (match_dup 0) (ashiftrt:GPR (match_dup 0) (match_dup 2)))
4725     (clobber (reg:CC CC_REGNUM))])]
4726{
4727  operands[1] = adjust_address (operands[1], BLKmode, 0);
4728  set_mem_size (operands[1], GET_MODE_SIZE (QImode));
4729  operands[2] = GEN_INT (<GPR:bitsize> - BITS_PER_UNIT);
4730})
4731
4732;
4733; zero_extendsidi2 instruction pattern(s).
4734;
4735
4736(define_expand "zero_extendsidi2"
4737  [(set (match_operand:DI 0 "register_operand" "")
4738        (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "")))]
4739  ""
4740{
4741  if (!TARGET_ZARCH)
4742    {
4743      emit_clobber (operands[0]);
4744      emit_move_insn (gen_lowpart (SImode, operands[0]), operands[1]);
4745      emit_move_insn (gen_highpart (SImode, operands[0]), const0_rtx);
4746      DONE;
4747    }
4748})
4749
4750(define_insn "*zero_extendsidi2"
4751  [(set (match_operand:DI 0 "register_operand" "=d,d,d")
4752        (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "d,T,b")))]
4753  "TARGET_ZARCH"
4754  "@
4755   llgfr\t%0,%1
4756   llgf\t%0,%1
4757   llgfrl\t%0,%1"
4758  [(set_attr "op_type"      "RRE,RXY,RIL")
4759   (set_attr "type"         "*,*,larl")
4760   (set_attr "cpu_facility" "*,*,z10")
4761   (set_attr "z10prop" "z10_fwd_E1,z10_fwd_A3,z10_fwd_A3")
4762   (set_attr "relative_long" "*,*,yes")])
4763
4764;
4765; LLGT-type instructions (zero-extend from 31 bit to 64 bit).
4766;
4767
4768(define_insn "*llgt_sidi"
4769  [(set (match_operand:DI 0 "register_operand" "=d")
4770        (and:DI (subreg:DI (match_operand:SI 1 "memory_operand" "T") 0)
4771		(const_int 2147483647)))]
4772  "TARGET_ZARCH"
4773  "llgt\t%0,%1"
4774  [(set_attr "op_type"  "RXE")
4775   (set_attr "z10prop" "z10_super_E1")])
4776
4777(define_insn_and_split "*llgt_sidi_split"
4778  [(set (match_operand:DI 0 "register_operand" "=d")
4779        (and:DI (subreg:DI (match_operand:SI 1 "memory_operand" "T") 0)
4780		(const_int 2147483647)))
4781   (clobber (reg:CC CC_REGNUM))]
4782  "TARGET_ZARCH"
4783  "#"
4784  "&& reload_completed"
4785  [(set (match_dup 0)
4786        (and:DI (subreg:DI (match_dup 1) 0)
4787		(const_int 2147483647)))]
4788  "")
4789
4790(define_insn "*llgt_sisi"
4791  [(set (match_operand:SI 0 "register_operand" "=d,d")
4792        (and:SI (match_operand:SI 1 "nonimmediate_operand" "d,T")
4793		(const_int 2147483647)))]
4794  "TARGET_ZARCH"
4795  "@
4796   llgtr\t%0,%1
4797   llgt\t%0,%1"
4798  [(set_attr "op_type"  "RRE,RXE")
4799   (set_attr "z10prop" "z10_super_E1,z10_super_E1")])
4800
4801(define_insn "*llgt_didi"
4802  [(set (match_operand:DI 0 "register_operand" "=d,d")
4803        (and:DI (match_operand:DI 1 "nonimmediate_operand" "d,o")
4804                (const_int 2147483647)))]
4805  "TARGET_ZARCH"
4806  "@
4807   llgtr\t%0,%1
4808   llgt\t%0,%N1"
4809  [(set_attr "op_type"  "RRE,RXE")
4810   (set_attr "z10prop" "z10_super_E1,z10_super_E1")])
4811
4812(define_split
4813  [(set (match_operand:DSI 0 "register_operand" "")
4814        (and:DSI (match_operand:DSI 1 "nonimmediate_operand" "")
4815                 (const_int 2147483647)))
4816   (clobber (reg:CC CC_REGNUM))]
4817  "TARGET_ZARCH && reload_completed"
4818  [(set (match_dup 0)
4819        (and:DSI (match_dup 1)
4820                 (const_int 2147483647)))]
4821  "")
4822
4823;
4824; zero_extend(hi|qi)(si|di)2 instruction pattern(s).
4825;
4826
4827(define_expand "zero_extend<mode>di2"
4828  [(set (match_operand:DI 0 "register_operand" "")
4829        (zero_extend:DI (match_operand:HQI 1 "nonimmediate_operand" "")))]
4830  ""
4831{
4832  if (!TARGET_ZARCH)
4833    {
4834      rtx tmp = gen_reg_rtx (SImode);
4835      emit_insn (gen_zero_extend<mode>si2 (tmp, operands[1]));
4836      emit_insn (gen_zero_extendsidi2 (operands[0], tmp));
4837      DONE;
4838    }
4839  else if (!TARGET_EXTIMM)
4840    {
4841      rtx bitcount = GEN_INT (64 - <HQI:bitsize>);
4842      operands[1] = gen_lowpart (DImode, operands[1]);
4843      emit_insn (gen_ashldi3 (operands[0], operands[1], bitcount));
4844      emit_insn (gen_lshrdi3 (operands[0], operands[0], bitcount));
4845      DONE;
4846    }
4847})
4848
4849(define_expand "zero_extend<mode>si2"
4850  [(set (match_operand:SI 0 "register_operand" "")
4851        (zero_extend:SI (match_operand:HQI 1 "nonimmediate_operand" "")))]
4852  ""
4853{
4854  if (!TARGET_EXTIMM)
4855    {
4856      operands[1] = gen_lowpart (SImode, operands[1]);
4857      emit_insn (gen_andsi3 (operands[0], operands[1],
4858			     GEN_INT ((1 << <HQI:bitsize>) - 1)));
4859      DONE;
4860    }
4861})
4862
4863; llhrl, llghrl
4864(define_insn "*zero_extendhi<mode>2_z10"
4865  [(set (match_operand:GPR 0 "register_operand" "=d,d,d")
4866        (zero_extend:GPR (match_operand:HI 1 "nonimmediate_operand" "d,T,b")))]
4867  "TARGET_Z10"
4868  "@
4869   ll<g>hr\t%0,%1
4870   ll<g>h\t%0,%1
4871   ll<g>hrl\t%0,%1"
4872  [(set_attr "op_type"      "RXY,RRE,RIL")
4873   (set_attr "type"         "*,*,larl")
4874   (set_attr "cpu_facility" "*,*,z10")
4875   (set_attr "z10prop" "z10_super_E1,z10_fwd_A3,z10_fwd_A3")
4876   (set_attr "relative_long" "*,*,yes")])
4877
4878; llhr, llcr, llghr, llgcr, llh, llc, llgh, llgc
4879(define_insn "*zero_extend<HQI:mode><GPR:mode>2_extimm"
4880  [(set (match_operand:GPR 0 "register_operand" "=d,d")
4881        (zero_extend:GPR (match_operand:HQI 1 "nonimmediate_operand" "d,T")))]
4882  "TARGET_EXTIMM"
4883  "@
4884   ll<g><hc>r\t%0,%1
4885   ll<g><hc>\t%0,%1"
4886  [(set_attr "op_type" "RRE,RXY")
4887   (set_attr "z10prop" "z10_super_E1,z10_fwd_A3")])
4888
4889; llgh, llgc
4890(define_insn "*zero_extend<HQI:mode><GPR:mode>2"
4891  [(set (match_operand:GPR 0 "register_operand" "=d")
4892        (zero_extend:GPR (match_operand:HQI 1 "memory_operand" "T")))]
4893  "TARGET_ZARCH && !TARGET_EXTIMM"
4894  "llg<hc>\t%0,%1"
4895  [(set_attr "op_type" "RXY")
4896   (set_attr "z10prop" "z10_fwd_A3")])
4897
4898(define_insn_and_split "*zero_extendhisi2_31"
4899  [(set (match_operand:SI 0 "register_operand" "=&d")
4900        (zero_extend:SI (match_operand:HI 1 "s_operand" "S")))
4901   (clobber (reg:CC CC_REGNUM))]
4902  "!TARGET_ZARCH"
4903  "#"
4904  "&& reload_completed"
4905  [(set (match_dup 0) (const_int 0))
4906   (parallel
4907    [(set (strict_low_part (match_dup 2)) (match_dup 1))
4908     (clobber (reg:CC CC_REGNUM))])]
4909  "operands[2] = gen_lowpart (HImode, operands[0]);")
4910
4911(define_insn_and_split "*zero_extendqisi2_31"
4912  [(set (match_operand:SI 0 "register_operand" "=&d")
4913        (zero_extend:SI (match_operand:QI 1 "memory_operand" "T")))]
4914  "!TARGET_ZARCH"
4915  "#"
4916  "&& reload_completed"
4917  [(set (match_dup 0) (const_int 0))
4918   (set (strict_low_part (match_dup 2)) (match_dup 1))]
4919  "operands[2] = gen_lowpart (QImode, operands[0]);")
4920
4921;
4922; zero_extendqihi2 instruction pattern(s).
4923;
4924
4925(define_expand "zero_extendqihi2"
4926  [(set (match_operand:HI 0 "register_operand" "")
4927        (zero_extend:HI (match_operand:QI 1 "register_operand" "")))]
4928  "TARGET_ZARCH && !TARGET_EXTIMM"
4929{
4930  operands[1] = gen_lowpart (HImode, operands[1]);
4931  emit_insn (gen_andhi3 (operands[0], operands[1], GEN_INT (0xff)));
4932  DONE;
4933})
4934
4935(define_insn "*zero_extendqihi2_64"
4936  [(set (match_operand:HI 0 "register_operand" "=d")
4937        (zero_extend:HI (match_operand:QI 1 "memory_operand" "T")))]
4938  "TARGET_ZARCH && !TARGET_EXTIMM"
4939  "llgc\t%0,%1"
4940  [(set_attr "op_type" "RXY")
4941   (set_attr "z10prop" "z10_fwd_A3")])
4942
4943(define_insn_and_split "*zero_extendqihi2_31"
4944  [(set (match_operand:HI 0 "register_operand" "=&d")
4945        (zero_extend:HI (match_operand:QI 1 "memory_operand" "T")))]
4946  "!TARGET_ZARCH"
4947  "#"
4948  "&& reload_completed"
4949  [(set (match_dup 0) (const_int 0))
4950   (set (strict_low_part (match_dup 2)) (match_dup 1))]
4951  "operands[2] = gen_lowpart (QImode, operands[0]);")
4952
4953;
4954; fixuns_trunc(dd|td|sf|df|tf)(si|di)2 expander
4955;
4956
4957; This is the only entry point for fixuns_trunc.  It multiplexes the
4958; expansion to either the *_emu expanders below for pre z196 machines
4959; or emits the default pattern otherwise.
4960(define_expand "fixuns_trunc<FP:mode><GPR:mode>2"
4961  [(parallel
4962    [(set (match_operand:GPR 0 "register_operand" "")
4963	  (unsigned_fix:GPR (match_operand:FP 1 "register_operand" "")))
4964     (unspec:GPR [(match_dup 2)] UNSPEC_ROUND)
4965     (clobber (reg:CC CC_REGNUM))])]
4966  "TARGET_HARD_FLOAT"
4967{
4968  if (!TARGET_Z196)
4969    {
4970      /* We don't provide emulation for TD|DD->SI.  */
4971      if (GET_MODE_CLASS (<FP:MODE>mode) == MODE_DECIMAL_FLOAT
4972	  && <GPR:MODE>mode == SImode)
4973	FAIL;
4974      emit_insn (gen_fixuns_trunc<FP:mode><GPR:mode>2_emu (operands[0],
4975							       operands[1]));
4976      DONE;
4977    }
4978
4979  if (GET_MODE_CLASS (<FP:MODE>mode) == MODE_DECIMAL_FLOAT)
4980    operands[2] = GEN_INT (DFP_RND_TOWARD_0);
4981  else
4982    operands[2] = GEN_INT (BFP_RND_TOWARD_0);
4983})
4984
4985; (sf|df|tf)->unsigned (si|di)
4986
4987; Emulate the unsigned conversion with the signed version for pre z196
4988; machines.
4989(define_expand "fixuns_trunc<BFP:mode><GPR:mode>2_emu"
4990  [(parallel
4991    [(set (match_operand:GPR 0 "register_operand" "")
4992	  (unsigned_fix:GPR (match_operand:BFP 1 "register_operand" "")))
4993     (unspec:GPR [(const_int BFP_RND_TOWARD_0)] UNSPEC_ROUND)
4994     (clobber (reg:CC CC_REGNUM))])]
4995  "!TARGET_Z196 && TARGET_HARD_FLOAT"
4996{
4997  rtx_code_label *label1 = gen_label_rtx ();
4998  rtx_code_label *label2 = gen_label_rtx ();
4999  rtx temp = gen_reg_rtx (<BFP:MODE>mode);
5000  REAL_VALUE_TYPE cmp, sub;
5001
5002  operands[1] = force_reg (<BFP:MODE>mode, operands[1]);
5003  real_2expN (&cmp, <GPR:bitsize> - 1, <BFP:MODE>mode);
5004  real_2expN (&sub, <GPR:bitsize>, <BFP:MODE>mode);
5005
5006  emit_cmp_and_jump_insns (operands[1],
5007			   const_double_from_real_value (cmp, <BFP:MODE>mode),
5008			   LT, NULL_RTX, VOIDmode, 0, label1);
5009  emit_insn (gen_sub<BFP:mode>3 (temp, operands[1],
5010	       const_double_from_real_value (sub, <BFP:MODE>mode)));
5011  emit_insn (gen_fix_trunc<BFP:mode><GPR:mode>2_bfp (operands[0], temp,
5012	       GEN_INT (BFP_RND_TOWARD_MINF)));
5013  emit_jump (label2);
5014
5015  emit_label (label1);
5016  emit_insn (gen_fix_trunc<BFP:mode><GPR:mode>2_bfp (operands[0],
5017							 operands[1],
5018							 GEN_INT (BFP_RND_TOWARD_0)));
5019  emit_label (label2);
5020  DONE;
5021})
5022
5023; dd->unsigned di
5024
5025; Emulate the unsigned conversion with the signed version for pre z196
5026; machines.
5027(define_expand "fixuns_truncdddi2_emu"
5028  [(parallel
5029    [(set (match_operand:DI 0 "register_operand" "")
5030	  (unsigned_fix:DI (match_operand:DD 1 "register_operand" "")))
5031     (unspec:DI [(const_int DFP_RND_TOWARD_0)] UNSPEC_ROUND)
5032     (clobber (reg:CC CC_REGNUM))])]
5033
5034  "!TARGET_Z196 && TARGET_HARD_DFP"
5035{
5036  rtx_code_label *label1 = gen_label_rtx ();
5037  rtx_code_label *label2 = gen_label_rtx ();
5038  rtx temp = gen_reg_rtx (TDmode);
5039  REAL_VALUE_TYPE cmp, sub;
5040
5041  decimal_real_from_string (&cmp, "9223372036854775808.0");  /* 2^63 */
5042  decimal_real_from_string (&sub, "18446744073709551616.0"); /* 2^64 */
5043
5044  /* 2^63 can't be represented as 64bit DFP number with full precision.  The
5045     solution is doing the check and the subtraction in TD mode and using a
5046     TD -> DI convert afterwards.  */
5047  emit_insn (gen_extendddtd2 (temp, operands[1]));
5048  temp = force_reg (TDmode, temp);
5049  emit_cmp_and_jump_insns (temp,
5050			   const_double_from_real_value (cmp, TDmode),
5051			   LT, NULL_RTX, VOIDmode, 0, label1);
5052  emit_insn (gen_subtd3 (temp, temp,
5053			 const_double_from_real_value (sub, TDmode)));
5054  emit_insn (gen_fix_trunctddi2_dfp (operands[0], temp,
5055				     GEN_INT (DFP_RND_TOWARD_MINF)));
5056  emit_jump (label2);
5057
5058  emit_label (label1);
5059  emit_insn (gen_fix_truncdddi2_dfp (operands[0], operands[1],
5060				     GEN_INT (DFP_RND_TOWARD_0)));
5061  emit_label (label2);
5062  DONE;
5063})
5064
5065; td->unsigned di
5066
5067; Emulate the unsigned conversion with the signed version for pre z196
5068; machines.
5069(define_expand "fixuns_trunctddi2_emu"
5070  [(parallel
5071    [(set (match_operand:DI 0 "register_operand" "")
5072	  (unsigned_fix:DI (match_operand:TD 1 "register_operand" "")))
5073     (unspec:DI [(const_int DFP_RND_TOWARD_0)] UNSPEC_ROUND)
5074     (clobber (reg:CC CC_REGNUM))])]
5075
5076  "!TARGET_Z196 && TARGET_HARD_DFP"
5077{
5078  rtx_code_label *label1 = gen_label_rtx ();
5079  rtx_code_label *label2 = gen_label_rtx ();
5080  rtx temp = gen_reg_rtx (TDmode);
5081  REAL_VALUE_TYPE cmp, sub;
5082
5083  operands[1] = force_reg (TDmode, operands[1]);
5084  decimal_real_from_string (&cmp, "9223372036854775808.0");  /* 2^63 */
5085  decimal_real_from_string (&sub, "18446744073709551616.0"); /* 2^64 */
5086
5087  emit_cmp_and_jump_insns (operands[1],
5088			   const_double_from_real_value (cmp, TDmode),
5089			   LT, NULL_RTX, VOIDmode, 0, label1);
5090  emit_insn (gen_subtd3 (temp, operands[1],
5091			 const_double_from_real_value (sub, TDmode)));
5092  emit_insn (gen_fix_trunctddi2_dfp (operands[0], temp,
5093				     GEN_INT (DFP_RND_TOWARD_MINF)));
5094  emit_jump (label2);
5095
5096  emit_label (label1);
5097  emit_insn (gen_fix_trunctddi2_dfp (operands[0], operands[1],
5098				     GEN_INT (DFP_RND_TOWARD_0)));
5099  emit_label (label2);
5100  DONE;
5101})
5102
5103; Just a dummy to make the code in the first expander a bit easier.
5104(define_expand "fixuns_trunc<mode>si2_emu"
5105  [(parallel
5106    [(set (match_operand:SI 0 "register_operand" "")
5107	  (unsigned_fix:SI (match_operand:DFP 1 "register_operand" "")))
5108     (unspec:DI [(const_int DFP_RND_TOWARD_0)] UNSPEC_ROUND)
5109     (clobber (reg:CC CC_REGNUM))])]
5110
5111  "!TARGET_Z196 && TARGET_HARD_DFP"
5112 {
5113   FAIL;
5114 })
5115
5116
5117; fixuns_trunc(tf|df|sf|td|dd)(di|si)2 instruction patterns.
5118
5119; df -> unsigned di, vxe2: sf -> unsigned si
5120; clgdbr, clfebr, wclgdb, wclfeb
5121(define_insn "*fixuns_trunc<VX_CONV_BFP:mode><VX_CONV_INT:mode>2_z13"
5122  [(set (match_operand:VX_CONV_INT                           0 "register_operand" "=d,v")
5123	(unsigned_fix:VX_CONV_INT (match_operand:VX_CONV_BFP 1 "register_operand"  "f,v")))
5124   (unspec:DI [(match_operand:DI                             2 "immediate_operand" "K,K")] UNSPEC_ROUND)
5125   (clobber (reg:CC CC_REGNUM))]
5126  "TARGET_VX && TARGET_HARD_FLOAT
5127   && GET_MODE_SIZE (<VX_CONV_INT:MODE>mode) == GET_MODE_SIZE (<VX_CONV_BFP:MODE>mode)"
5128  "@
5129   cl<VX_CONV_INT:gf><VX_CONV_BFP:xde>br\t%0,%h2,%1,0
5130   wcl<VX_CONV_INT:gf><VX_CONV_BFP:xde>b\t%v0,%v1,0,%h2"
5131  [(set_attr "op_type" "RRF,VRR")
5132   (set_attr "type"    "ftoi")])
5133
5134; (dd|td|sf|df|tf)->unsigned (di|si)
5135; clfebr, clfdbr, clfxbr, clgebr, clgdbr, clgxbr
5136;         clfdtr, clfxtr,         clgdtr, clgxtr
5137(define_insn "*fixuns_trunc<FP:mode><GPR:mode>2_z196"
5138  [(set (match_operand:GPR                  0 "register_operand" "=d")
5139	(unsigned_fix:GPR (match_operand:FP 1 "register_operand"  "f")))
5140   (unspec:GPR [(match_operand:GPR          2 "immediate_operand" "K")] UNSPEC_ROUND)
5141   (clobber (reg:CC CC_REGNUM))]
5142   "TARGET_Z196 && TARGET_HARD_FLOAT
5143    && (!TARGET_VX || <GPR:MODE>mode != DImode || <FP:MODE>mode != DFmode)"
5144   "cl<GPR:gf><FP:xde><FP:bt>r\t%0,%h2,%1,0"
5145   [(set_attr "op_type" "RRF")
5146    (set_attr "type"    "ftoi")])
5147
5148(define_expand "fix_trunc<DSF:mode><GPR:mode>2"
5149  [(set (match_operand:GPR 0 "register_operand" "")
5150        (fix:GPR (match_operand:DSF 1 "register_operand" "")))]
5151  "TARGET_HARD_FLOAT"
5152{
5153  emit_insn (gen_fix_trunc<DSF:mode><GPR:mode>2_bfp (operands[0], operands[1],
5154             GEN_INT (BFP_RND_TOWARD_0)));
5155  DONE;
5156})
5157
5158; df -> signed di, vxe2: sf -> signed si
5159; cgdbr, cfebr, wcgdb, wcfeb
5160(define_insn "*fix_trunc<VX_CONV_BFP:mode><VX_CONV_INT:mode>2_bfp_z13"
5161  [(set (match_operand:VX_CONV_INT                  0 "register_operand" "=d,v")
5162        (fix:VX_CONV_INT (match_operand:VX_CONV_BFP 1 "register_operand"  "f,v")))
5163   (unspec:VX_CONV_INT [(match_operand:VX_CONV_INT  2 "immediate_operand" "K,K")] UNSPEC_ROUND)
5164   (clobber (reg:CC CC_REGNUM))]
5165  "TARGET_VX && TARGET_HARD_FLOAT
5166   && GET_MODE_SIZE (<VX_CONV_INT:MODE>mode) == GET_MODE_SIZE (<VX_CONV_BFP:MODE>mode)"
5167  "@
5168   c<VX_CONV_INT:gf><VX_CONV_BFP:xde>br\t%0,%h2,%1
5169   wc<VX_CONV_INT:gf><VX_CONV_BFP:xde>b\t%v0,%v1,0,%h2"
5170  [(set_attr "op_type" "RRE,VRR")
5171   (set_attr "type"    "ftoi")])
5172
5173; cgxbr, cgdbr, cgebr, cfxbr, cfdbr, cfebr
5174(define_insn "*fix_trunc<BFP:mode><GPR:mode>2_bfp"
5175  [(set (match_operand:GPR          0 "register_operand" "=d")
5176        (fix:GPR (match_operand:BFP 1 "register_operand"  "f")))
5177   (unspec:GPR [(match_operand:GPR  2 "immediate_operand" "K")] UNSPEC_ROUND)
5178   (clobber (reg:CC CC_REGNUM))]
5179  "TARGET_HARD_FLOAT
5180    && (!TARGET_VX || <GPR:MODE>mode != DImode || <BFP:MODE>mode != DFmode)"
5181  "c<GPR:gf><BFP:xde>br\t%0,%h2,%1"
5182  [(set_attr "op_type" "RRE")
5183   (set_attr "type"    "ftoi")])
5184
5185(define_expand "fix_trunc<BFP:mode><GPR:mode>2_bfp"
5186  [(parallel
5187    [(set (match_operand:GPR          0 "register_operand" "=d")
5188	  (fix:GPR (match_operand:BFP 1 "register_operand"  "f")))
5189     (unspec:GPR [(match_operand:GPR  2 "immediate_operand" "K")] UNSPEC_ROUND)
5190     (clobber (reg:CC CC_REGNUM))])]
5191  "TARGET_HARD_FLOAT")
5192;
5193; fix_trunc(td|dd)di2 instruction pattern(s).
5194;
5195
5196(define_expand "fix_trunc<mode>di2"
5197  [(set (match_operand:DI 0 "register_operand" "")
5198        (fix:DI (match_operand:DFP 1 "nonimmediate_operand" "")))]
5199  "TARGET_ZARCH && TARGET_HARD_DFP"
5200{
5201  operands[1] = force_reg (<MODE>mode, operands[1]);
5202  emit_insn (gen_fix_trunc<mode>di2_dfp (operands[0], operands[1],
5203      GEN_INT (DFP_RND_TOWARD_0)));
5204  DONE;
5205})
5206
5207; cgxtr, cgdtr
5208(define_insn "fix_trunc<DFP:mode>di2_dfp"
5209  [(set (match_operand:DI 0 "register_operand" "=d")
5210        (fix:DI (match_operand:DFP 1 "register_operand" "f")))
5211   (unspec:DI [(match_operand:DI 2 "immediate_operand" "K")] UNSPEC_ROUND)
5212   (clobber (reg:CC CC_REGNUM))]
5213  "TARGET_ZARCH && TARGET_HARD_DFP"
5214  "cg<DFP:xde>tr\t%0,%h2,%1"
5215  [(set_attr "op_type" "RRF")
5216   (set_attr "type"    "ftoidfp")])
5217
5218
5219;
5220; fix_trunctf(si|di)2 instruction pattern(s).
5221;
5222
5223(define_expand "fix_trunctf<mode>2"
5224  [(parallel [(set (match_operand:GPR 0 "register_operand" "")
5225		   (fix:GPR (match_operand:TF 1 "register_operand" "")))
5226	      (unspec:GPR [(const_int BFP_RND_TOWARD_0)] UNSPEC_ROUND)
5227	      (clobber (reg:CC CC_REGNUM))])]
5228  "TARGET_HARD_FLOAT"
5229  "")
5230
5231
5232;
5233; float(si|di)(tf|df|sf|td|dd)2 instruction pattern(s).
5234;
5235
5236; cxgbr, cdgbr, cegbr, cxgtr, cdgtr
5237(define_insn "floatdi<mode>2"
5238  [(set (match_operand:FP           0 "register_operand" "=f,v")
5239        (float:FP (match_operand:DI 1 "register_operand"  "d,v")))]
5240  "TARGET_ZARCH && TARGET_HARD_FLOAT"
5241  "@
5242   c<xde>g<bt>r\t%0,%1
5243   wcdgb\t%v0,%v1,0,0"
5244  [(set_attr "op_type"      "RRE,VRR")
5245   (set_attr "type"         "itof<mode>" )
5246   (set_attr "cpu_facility" "*,vx")
5247   (set_attr "enabled"      "*,<DFDI>")])
5248
5249; cxfbr, cdfbr, cefbr, wcefb
5250(define_insn "floatsi<mode>2"
5251  [(set (match_operand:BFP           0 "register_operand" "=f,v")
5252        (float:BFP (match_operand:SI 1 "register_operand"  "d,v")))]
5253  "TARGET_HARD_FLOAT"
5254  "@
5255   c<xde>fbr\t%0,%1
5256   wcefb\t%v0,%v1,0,0"
5257  [(set_attr "op_type"      "RRE,VRR")
5258   (set_attr "type"         "itof<mode>" )
5259   (set_attr "cpu_facility" "*,vxe2")
5260   (set_attr "enabled"      "*,<SFSI>")])
5261
5262; cxftr, cdftr
5263(define_insn "floatsi<mode>2"
5264  [(set (match_operand:DFP 0 "register_operand" "=f")
5265        (float:DFP (match_operand:SI 1 "register_operand" "d")))]
5266  "TARGET_Z196 && TARGET_HARD_FLOAT"
5267  "c<xde>ftr\t%0,0,%1,0"
5268  [(set_attr "op_type" "RRE")
5269   (set_attr "type"   "itof<mode>" )])
5270
5271;
5272; floatuns(si|di)(tf|df|sf|td|dd)2 instruction pattern(s).
5273;
5274
5275(define_insn "*floatuns<VX_CONV_INT:mode><VX_CONV_BFP:mode>2_z13"
5276  [(set (match_operand:VX_CONV_BFP                             0 "register_operand" "=f,v")
5277        (unsigned_float:VX_CONV_BFP (match_operand:VX_CONV_INT 1 "register_operand"  "d,v")))]
5278  "TARGET_VX && TARGET_HARD_FLOAT
5279   && GET_MODE_SIZE (<VX_CONV_INT:MODE>mode) == GET_MODE_SIZE (<VX_CONV_BFP:MODE>mode)"
5280  "@
5281   c<VX_CONV_BFP:xde>l<VX_CONV_INT:gf>br\t%0,0,%1,0
5282   wc<VX_CONV_BFP:xde>l<VX_CONV_INT:gf>b\t%v0,%v1,0,0"
5283  [(set_attr "op_type" "RRE,VRR")
5284   (set_attr "type"    "itofdf")])
5285
5286; cxlgbr, cdlgbr, celgbr, cxlgtr, cdlgtr
5287; cxlfbr, cdlfbr, celfbr, cxlftr, cdlftr
5288(define_insn "*floatuns<GPR:mode><FP:mode>2"
5289  [(set (match_operand:FP                     0 "register_operand" "=f")
5290        (unsigned_float:FP (match_operand:GPR 1 "register_operand"  "d")))]
5291  "TARGET_Z196 && TARGET_HARD_FLOAT
5292   && (!TARGET_VX || <FP:MODE>mode != DFmode || <GPR:MODE>mode != DImode)"
5293  "c<FP:xde>l<GPR:gf><FP:bt>r\t%0,0,%1,0"
5294  [(set_attr "op_type" "RRE")
5295   (set_attr "type"    "itof<FP:mode>")])
5296
5297(define_expand "floatuns<GPR:mode><FP:mode>2"
5298  [(set (match_operand:FP                     0 "register_operand" "")
5299        (unsigned_float:FP (match_operand:GPR 1 "register_operand" "")))]
5300  "TARGET_Z196 && TARGET_HARD_FLOAT")
5301
5302;
5303; truncdfsf2 instruction pattern(s).
5304;
5305
5306(define_insn "truncdfsf2"
5307  [(set (match_operand:SF                    0 "register_operand" "=f,v")
5308        (float_truncate:SF (match_operand:DF 1 "register_operand"  "f,v")))]
5309  "TARGET_HARD_FLOAT"
5310  "@
5311   ledbr\t%0,%1
5312   wledb\t%v0,%v1,0,0" ; IEEE inexact exception not suppressed
5313                       ; According to BFP rounding mode
5314  [(set_attr "op_type"      "RRE,VRR")
5315   (set_attr "type"         "ftruncdf")
5316   (set_attr "cpu_facility" "*,vx")])
5317
5318;
5319; trunctf(df|sf)2 instruction pattern(s).
5320;
5321
5322; ldxbr, lexbr
5323(define_insn "trunctf<mode>2"
5324  [(set (match_operand:DSF 0 "register_operand" "=f")
5325        (float_truncate:DSF (match_operand:TF 1 "register_operand" "f")))
5326   (clobber (match_scratch:TF 2 "=f"))]
5327  "TARGET_HARD_FLOAT"
5328  "l<xde>xbr\t%2,%1\;l<xde>r\t%0,%2"
5329  [(set_attr "length" "6")
5330   (set_attr "type"   "ftrunctf")])
5331
5332;
5333; trunctddd2 and truncddsd2 instruction pattern(s).
5334;
5335
5336
5337(define_expand "trunctddd2"
5338  [(parallel
5339    [(set (match_operand:DD 0 "register_operand" "")
5340	  (float_truncate:DD (match_operand:TD 1 "register_operand" "")))
5341     (unspec:DI [(const_int DFP_RND_CURRENT)] UNSPEC_ROUND)
5342     (clobber (scratch:TD))])]
5343  "TARGET_HARD_DFP")
5344
5345(define_insn "*trunctddd2"
5346  [(set (match_operand:DD 0 "register_operand" "=f")
5347	(float_truncate:DD (match_operand:TD 1 "register_operand" "f")))
5348   (unspec:DI [(match_operand:DI 2 "const_mask_operand" "I")] UNSPEC_ROUND)
5349   (clobber (match_scratch:TD 3 "=f"))]
5350  "TARGET_HARD_DFP"
5351  "ldxtr\t%3,%2,%1,0\;ldr\t%0,%3"
5352  [(set_attr "length"  "6")
5353   (set_attr "type"    "ftruncdd")])
5354
5355(define_insn "truncddsd2"
5356  [(set (match_operand:SD 0 "register_operand" "=f")
5357	(float_truncate:SD (match_operand:DD 1 "register_operand" "f")))]
5358  "TARGET_HARD_DFP"
5359  "ledtr\t%0,0,%1,0"
5360  [(set_attr "op_type" "RRF")
5361   (set_attr "type"    "ftruncsd")])
5362
5363(define_expand "trunctdsd2"
5364  [(parallel
5365    [(set (match_dup 2)
5366	  (float_truncate:DD (match_operand:TD 1 "register_operand" "")))
5367     (unspec:DI [(const_int DFP_RND_PREP_FOR_SHORT_PREC)] UNSPEC_ROUND)
5368     (clobber (match_scratch:TD 3 ""))])
5369   (set (match_operand:SD 0 "register_operand" "")
5370	(float_truncate:SD (match_dup 2)))]
5371  "TARGET_HARD_DFP"
5372{
5373  operands[2] = gen_reg_rtx (DDmode);
5374})
5375
5376;
5377; extend(sf|df)(df|tf)2 instruction pattern(s).
5378;
5379
5380; wflls
5381(define_insn "*extendsfdf2_z13"
5382  [(set (match_operand:DF                  0 "register_operand"     "=f,f,v")
5383        (float_extend:DF (match_operand:SF 1 "nonimmediate_operand"  "f,R,v")))]
5384  "TARGET_VX && TARGET_HARD_FLOAT"
5385  "@
5386   ldebr\t%0,%1
5387   ldeb\t%0,%1
5388   wldeb\t%v0,%v1"
5389  [(set_attr "op_type" "RRE,RXE,VRR")
5390   (set_attr "type"    "fsimpdf, floaddf,fsimpdf")])
5391
5392; ldebr, ldeb, lxdbr, lxdb, lxebr, lxeb
5393(define_insn "*extend<DSF:mode><BFP:mode>2"
5394  [(set (match_operand:BFP                   0 "register_operand"     "=f,f")
5395        (float_extend:BFP (match_operand:DSF 1 "nonimmediate_operand"  "f,R")))]
5396  "TARGET_HARD_FLOAT
5397   && GET_MODE_SIZE (<BFP:MODE>mode) > GET_MODE_SIZE (<DSF:MODE>mode)
5398   && (!TARGET_VX || <BFP:MODE>mode != DFmode || <DSF:MODE>mode != SFmode)"
5399  "@
5400   l<BFP:xde><DSF:xde>br\t%0,%1
5401   l<BFP:xde><DSF:xde>b\t%0,%1"
5402  [(set_attr "op_type" "RRE,RXE")
5403   (set_attr "type"    "fsimp<BFP:mode>, fload<BFP:mode>")])
5404
5405(define_expand "extend<DSF:mode><BFP:mode>2"
5406  [(set (match_operand:BFP                   0 "register_operand"     "")
5407        (float_extend:BFP (match_operand:DSF 1 "nonimmediate_operand" "")))]
5408  "TARGET_HARD_FLOAT
5409   && GET_MODE_SIZE (<BFP:MODE>mode) > GET_MODE_SIZE (<DSF:MODE>mode)")
5410
5411;
5412; extendddtd2 and extendsddd2 instruction pattern(s).
5413;
5414
5415(define_insn "extendddtd2"
5416  [(set (match_operand:TD 0 "register_operand" "=f")
5417	(float_extend:TD (match_operand:DD 1 "register_operand" "f")))]
5418  "TARGET_HARD_DFP"
5419  "lxdtr\t%0,%1,0"
5420  [(set_attr "op_type" "RRF")
5421   (set_attr "type"    "fsimptf")])
5422
5423(define_insn "extendsddd2"
5424  [(set (match_operand:DD 0 "register_operand" "=f")
5425	(float_extend:DD (match_operand:SD 1 "register_operand" "f")))]
5426  "TARGET_HARD_DFP"
5427  "ldetr\t%0,%1,0"
5428  [(set_attr "op_type" "RRF")
5429   (set_attr "type"    "fsimptf")])
5430
5431(define_expand "extendsdtd2"
5432  [(set (match_dup 2)
5433	(float_extend:DD (match_operand:SD 1 "register_operand" "")))
5434   (set (match_operand:TD 0 "register_operand" "")
5435	(float_extend:TD (match_dup 2)))]
5436  "TARGET_HARD_DFP"
5437{
5438  operands[2] = gen_reg_rtx (DDmode);
5439})
5440
5441; Binary Floating Point - load fp integer
5442
5443; Expanders for: floor, btrunc, round, ceil, and nearbyint
5444; For all of them the inexact exceptions are suppressed.
5445
5446; fiebra, fidbra, fixbra
5447(define_insn "<FPINT:fpint_name><BFP:mode>2"
5448  [(set (match_operand:BFP 0 "register_operand" "=f")
5449	(unspec:BFP [(match_operand:BFP 1 "register_operand" "f")]
5450		    FPINT))]
5451  "TARGET_Z196"
5452  "fi<BFP:xde>bra\t%0,<FPINT:fpint_roundingmode>,%1,4"
5453  [(set_attr "op_type"   "RRF")
5454   (set_attr "type"      "fsimp<BFP:mode>")])
5455
5456; rint is supposed to raise an inexact exception so we can use the
5457; older instructions.
5458
5459; fiebr, fidbr, fixbr
5460(define_insn "rint<BFP:mode>2"
5461  [(set (match_operand:BFP 0 "register_operand" "=f")
5462	(unspec:BFP [(match_operand:BFP 1 "register_operand" "f")]
5463		    UNSPEC_FPINT_RINT))]
5464  ""
5465  "fi<BFP:xde>br\t%0,0,%1"
5466  [(set_attr "op_type"   "RRF")
5467   (set_attr "type"      "fsimp<BFP:mode>")])
5468
5469
5470; Decimal Floating Point - load fp integer
5471
5472; fidtr, fixtr
5473(define_insn "<FPINT:fpint_name><DFP:mode>2"
5474  [(set (match_operand:DFP 0 "register_operand" "=f")
5475	(unspec:DFP [(match_operand:DFP 1 "register_operand" "f")]
5476		    FPINT))]
5477  "TARGET_HARD_DFP"
5478  "fi<DFP:xde>tr\t%0,<FPINT:fpint_roundingmode>,%1,4"
5479  [(set_attr "op_type"   "RRF")
5480   (set_attr "type"      "fsimp<DFP:mode>")])
5481
5482; fidtr, fixtr
5483(define_insn "rint<DFP:mode>2"
5484  [(set (match_operand:DFP 0 "register_operand" "=f")
5485	(unspec:DFP [(match_operand:DFP 1 "register_operand" "f")]
5486		    UNSPEC_FPINT_RINT))]
5487  "TARGET_HARD_DFP"
5488  "fi<DFP:xde>tr\t%0,0,%1,0"
5489  [(set_attr "op_type"   "RRF")
5490   (set_attr "type"      "fsimp<DFP:mode>")])
5491
5492;
5493; Binary <-> Decimal floating point trunc patterns
5494;
5495
5496(define_insn "*trunc<BFP:mode><DFP_ALL:mode>2"
5497  [(set (reg:DFP_ALL FPR0_REGNUM)
5498        (float_truncate:DFP_ALL (reg:BFP FPR4_REGNUM)))
5499   (use (reg:SI GPR0_REGNUM))
5500   (clobber (reg:CC CC_REGNUM))
5501   (clobber (reg:SI GPR1_REGNUM))]
5502  "TARGET_HARD_DFP"
5503  "pfpo")
5504
5505(define_insn "*trunc<DFP_ALL:mode><BFP:mode>2"
5506  [(set (reg:BFP FPR0_REGNUM)
5507        (float_truncate:BFP (reg:DFP_ALL FPR4_REGNUM)))
5508   (use (reg:SI GPR0_REGNUM))
5509   (clobber (reg:CC CC_REGNUM))
5510   (clobber (reg:SI GPR1_REGNUM))]
5511  "TARGET_HARD_DFP"
5512  "pfpo")
5513
5514(define_expand "trunc<BFP:mode><DFP_ALL:mode>2"
5515  [(set (reg:BFP FPR4_REGNUM) (match_operand:BFP 1 "nonimmediate_operand" ""))
5516   (set (reg:SI GPR0_REGNUM) (match_dup 2))
5517   (parallel
5518    [(set (reg:DFP_ALL FPR0_REGNUM)
5519          (float_truncate:DFP_ALL (reg:BFP FPR4_REGNUM)))
5520     (use (reg:SI GPR0_REGNUM))
5521     (clobber (reg:CC CC_REGNUM))
5522     (clobber (reg:SI GPR1_REGNUM))])
5523   (set (match_operand:DFP_ALL 0 "nonimmediate_operand" "")
5524        (reg:DFP_ALL FPR0_REGNUM))]
5525  "TARGET_HARD_DFP
5526   && GET_MODE_SIZE (<BFP:MODE>mode) > GET_MODE_SIZE (<DFP_ALL:MODE>mode)"
5527{
5528  HOST_WIDE_INT flags;
5529
5530  /* According to IEEE 754 2008 4.3 'Rounding-direction attributes' the
5531     rounding mode of the target format needs to be used.  */
5532
5533  flags = (PFPO_CONVERT |
5534           PFPO_OP_TYPE_<DFP_ALL:MODE> << PFPO_OP0_TYPE_SHIFT |
5535           PFPO_OP_TYPE_<BFP:MODE> << PFPO_OP1_TYPE_SHIFT |
5536	   PFPO_RND_MODE_DFP);
5537
5538  operands[2] = GEN_INT (flags);
5539})
5540
5541(define_expand "trunc<DFP_ALL:mode><BFP:mode>2"
5542  [(set (reg:DFP_ALL FPR4_REGNUM)
5543        (match_operand:DFP_ALL 1 "nonimmediate_operand" ""))
5544   (set (reg:SI GPR0_REGNUM) (match_dup 2))
5545   (parallel
5546    [(set (reg:BFP FPR0_REGNUM) (float_truncate:BFP (reg:DFP_ALL FPR4_REGNUM)))
5547     (use (reg:SI GPR0_REGNUM))
5548     (clobber (reg:CC CC_REGNUM))
5549     (clobber (reg:SI GPR1_REGNUM))])
5550   (set (match_operand:BFP 0 "nonimmediate_operand" "") (reg:BFP FPR0_REGNUM))]
5551  "TARGET_HARD_DFP
5552   && GET_MODE_SIZE (<DFP_ALL:MODE>mode) >= GET_MODE_SIZE (<BFP:MODE>mode)"
5553{
5554  HOST_WIDE_INT flags;
5555
5556  /* According to IEEE 754 2008 4.3 'Rounding-direction attributes' the
5557     rounding mode of the target format needs to be used.  */
5558
5559  flags = (PFPO_CONVERT |
5560           PFPO_OP_TYPE_<BFP:MODE> << PFPO_OP0_TYPE_SHIFT |
5561           PFPO_OP_TYPE_<DFP_ALL:MODE> << PFPO_OP1_TYPE_SHIFT |
5562	   PFPO_RND_MODE_BFP);
5563
5564  operands[2] = GEN_INT (flags);
5565})
5566
5567;
5568; Binary <-> Decimal floating point extend patterns
5569;
5570
5571(define_insn "*extend<BFP:mode><DFP_ALL:mode>2"
5572  [(set (reg:DFP_ALL FPR0_REGNUM) (float_extend:DFP_ALL (reg:BFP FPR4_REGNUM)))
5573   (use (reg:SI GPR0_REGNUM))
5574   (clobber (reg:CC CC_REGNUM))
5575   (clobber (reg:SI GPR1_REGNUM))]
5576  "TARGET_HARD_DFP"
5577  "pfpo")
5578
5579(define_insn "*extend<DFP_ALL:mode><BFP:mode>2"
5580  [(set (reg:BFP FPR0_REGNUM) (float_extend:BFP (reg:DFP_ALL FPR4_REGNUM)))
5581   (use (reg:SI GPR0_REGNUM))
5582   (clobber (reg:CC CC_REGNUM))
5583   (clobber (reg:SI GPR1_REGNUM))]
5584  "TARGET_HARD_DFP"
5585  "pfpo")
5586
5587(define_expand "extend<BFP:mode><DFP_ALL:mode>2"
5588  [(set (reg:BFP FPR4_REGNUM) (match_operand:BFP 1 "nonimmediate_operand" ""))
5589   (set (reg:SI GPR0_REGNUM) (match_dup 2))
5590   (parallel
5591    [(set (reg:DFP_ALL FPR0_REGNUM)
5592          (float_extend:DFP_ALL (reg:BFP FPR4_REGNUM)))
5593     (use (reg:SI GPR0_REGNUM))
5594     (clobber (reg:CC CC_REGNUM))
5595     (clobber (reg:SI GPR1_REGNUM))])
5596   (set (match_operand:DFP_ALL 0 "nonimmediate_operand" "")
5597        (reg:DFP_ALL FPR0_REGNUM))]
5598  "TARGET_HARD_DFP
5599   && GET_MODE_SIZE (<BFP:MODE>mode) <= GET_MODE_SIZE (<DFP_ALL:MODE>mode)"
5600{
5601  HOST_WIDE_INT flags;
5602
5603  /* According to IEEE 754 2008 4.3 'Rounding-direction attributes' the
5604     rounding mode of the target format needs to be used.  */
5605
5606  flags = (PFPO_CONVERT |
5607           PFPO_OP_TYPE_<DFP_ALL:MODE> << PFPO_OP0_TYPE_SHIFT |
5608           PFPO_OP_TYPE_<BFP:MODE> << PFPO_OP1_TYPE_SHIFT |
5609	   PFPO_RND_MODE_DFP);
5610
5611  operands[2] = GEN_INT (flags);
5612})
5613
5614(define_expand "extend<DFP_ALL:mode><BFP:mode>2"
5615  [(set (reg:DFP_ALL FPR4_REGNUM)
5616        (match_operand:DFP_ALL 1 "nonimmediate_operand" ""))
5617   (set (reg:SI GPR0_REGNUM) (match_dup 2))
5618   (parallel
5619    [(set (reg:BFP FPR0_REGNUM) (float_extend:BFP (reg:DFP_ALL FPR4_REGNUM)))
5620     (use (reg:SI GPR0_REGNUM))
5621     (clobber (reg:CC CC_REGNUM))
5622     (clobber (reg:SI GPR1_REGNUM))])
5623   (set (match_operand:BFP 0 "nonimmediate_operand" "") (reg:BFP FPR0_REGNUM))]
5624  "TARGET_HARD_DFP
5625   && GET_MODE_SIZE (<DFP_ALL:MODE>mode) < GET_MODE_SIZE (<BFP:MODE>mode)"
5626{
5627  HOST_WIDE_INT flags;
5628
5629  /* According to IEEE 754 2008 4.3 'Rounding-direction attributes' the
5630     rounding mode of the target format needs to be used.  */
5631
5632  flags = (PFPO_CONVERT |
5633           PFPO_OP_TYPE_<BFP:MODE> << PFPO_OP0_TYPE_SHIFT |
5634           PFPO_OP_TYPE_<DFP_ALL:MODE> << PFPO_OP1_TYPE_SHIFT |
5635	   PFPO_RND_MODE_BFP);
5636
5637  operands[2] = GEN_INT (flags);
5638})
5639
5640
5641;;
5642;; ARITHMETIC OPERATIONS
5643;;
5644;  arithmetic operations set the ConditionCode,
5645;  because of unpredictable Bits in Register for Halfword and Byte
5646;  the ConditionCode can be set wrong in operations for Halfword and Byte
5647
5648;;
5649;;- Add instructions.
5650;;
5651
5652;
5653; addti3 instruction pattern(s).
5654;
5655
5656(define_expand "addti3"
5657  [(parallel
5658    [(set (match_operand:TI          0 "register_operand"     "")
5659	  (plus:TI (match_operand:TI 1 "nonimmediate_operand" "")
5660		   (match_operand:TI 2 "general_operand"      "") ) )
5661     (clobber (reg:CC CC_REGNUM))])]
5662  "TARGET_ZARCH"
5663{
5664  /* For z13 we have vaq which doesn't set CC.  */
5665  if (TARGET_VX)
5666    {
5667      emit_insn (gen_rtx_SET (operands[0],
5668			      gen_rtx_PLUS (TImode,
5669                                            copy_to_mode_reg (TImode, operands[1]),
5670                                            copy_to_mode_reg (TImode, operands[2]))));
5671      DONE;
5672    }
5673})
5674
5675(define_insn_and_split "*addti3"
5676  [(set (match_operand:TI          0 "register_operand"    "=&d")
5677        (plus:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
5678                 (match_operand:TI 2 "general_operand"      "do") ) )
5679   (clobber (reg:CC CC_REGNUM))]
5680  "TARGET_ZARCH"
5681  "#"
5682  "&& reload_completed"
5683  [(parallel
5684    [(set (reg:CCL1 CC_REGNUM)
5685          (compare:CCL1 (plus:DI (match_dup 7) (match_dup 8))
5686                        (match_dup 7)))
5687     (set (match_dup 6) (plus:DI (match_dup 7) (match_dup 8)))])
5688   (parallel
5689    [(set (match_dup 3) (plus:DI
5690                          (plus:DI (ltu:DI (reg:CCL1 CC_REGNUM) (const_int 0))
5691                                   (match_dup 4)) (match_dup 5)))
5692     (clobber (reg:CC CC_REGNUM))])]
5693  "operands[3] = operand_subword (operands[0], 0, 0, TImode);
5694   operands[4] = operand_subword (operands[1], 0, 0, TImode);
5695   operands[5] = operand_subword (operands[2], 0, 0, TImode);
5696   operands[6] = operand_subword (operands[0], 1, 0, TImode);
5697   operands[7] = operand_subword (operands[1], 1, 0, TImode);
5698   operands[8] = operand_subword (operands[2], 1, 0, TImode);"
5699  [(set_attr "op_type"  "*")
5700   (set_attr "cpu_facility" "*")])
5701
5702;
5703; adddi3 instruction pattern(s).
5704;
5705
5706(define_expand "adddi3"
5707  [(parallel
5708    [(set (match_operand:DI 0 "nonimmediate_operand" "")
5709          (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
5710                   (match_operand:DI 2 "general_operand" "")))
5711     (clobber (reg:CC CC_REGNUM))])]
5712  ""
5713  "")
5714
5715(define_insn "*adddi3_sign"
5716  [(set (match_operand:DI 0 "register_operand" "=d,d")
5717        (plus:DI (sign_extend:DI (match_operand:SI 2 "general_operand" "d,T"))
5718                 (match_operand:DI 1 "register_operand" "0,0")))
5719   (clobber (reg:CC CC_REGNUM))]
5720  "TARGET_ZARCH"
5721  "@
5722   agfr\t%0,%2
5723   agf\t%0,%2"
5724  [(set_attr "op_type"  "RRE,RXY")
5725   (set_attr "z196prop" "z196_cracked,z196_cracked")])
5726
5727(define_insn "*adddi3_zero_cc"
5728  [(set (reg CC_REGNUM)
5729        (compare (plus:DI (zero_extend:DI (match_operand:SI 2 "general_operand" "d,T"))
5730                          (match_operand:DI 1 "register_operand" "0,0"))
5731                 (const_int 0)))
5732   (set (match_operand:DI 0 "register_operand" "=d,d")
5733        (plus:DI (zero_extend:DI (match_dup 2)) (match_dup 1)))]
5734  "s390_match_ccmode (insn, CCLmode) && TARGET_ZARCH"
5735  "@
5736   algfr\t%0,%2
5737   algf\t%0,%2"
5738  [(set_attr "op_type"  "RRE,RXY")
5739   (set_attr "z10prop" "z10_super_E1,z10_super_E1")])
5740
5741(define_insn "*adddi3_zero_cconly"
5742  [(set (reg CC_REGNUM)
5743        (compare (plus:DI (zero_extend:DI (match_operand:SI 2 "general_operand" "d,T"))
5744                          (match_operand:DI 1 "register_operand" "0,0"))
5745                 (const_int 0)))
5746   (clobber (match_scratch:DI 0 "=d,d"))]
5747  "s390_match_ccmode (insn, CCLmode) && TARGET_ZARCH"
5748  "@
5749   algfr\t%0,%2
5750   algf\t%0,%2"
5751  [(set_attr "op_type"  "RRE,RXY")
5752   (set_attr "z10prop" "z10_super_E1,z10_super_E1")])
5753
5754(define_insn "*adddi3_zero"
5755  [(set (match_operand:DI 0 "register_operand" "=d,d")
5756        (plus:DI (zero_extend:DI (match_operand:SI 2 "general_operand" "d,T"))
5757                 (match_operand:DI 1 "register_operand" "0,0")))
5758   (clobber (reg:CC CC_REGNUM))]
5759  "TARGET_ZARCH"
5760  "@
5761   algfr\t%0,%2
5762   algf\t%0,%2"
5763  [(set_attr "op_type"  "RRE,RXY")
5764   (set_attr "z10prop" "z10_super_E1,z10_super_E1")])
5765
5766(define_insn_and_split "*adddi3_31z"
5767  [(set (match_operand:DI 0 "nonimmediate_operand" "=&d")
5768        (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
5769                 (match_operand:DI 2 "general_operand" "do") ) )
5770   (clobber (reg:CC CC_REGNUM))]
5771  "!TARGET_ZARCH"
5772  "#"
5773  "&& reload_completed"
5774  [(parallel
5775    [(set (reg:CCL1 CC_REGNUM)
5776          (compare:CCL1 (plus:SI (match_dup 7) (match_dup 8))
5777                        (match_dup 7)))
5778     (set (match_dup 6) (plus:SI (match_dup 7) (match_dup 8)))])
5779   (parallel
5780    [(set (match_dup 3) (plus:SI
5781			  (plus:SI (ltu:SI (reg:CCL1 CC_REGNUM) (const_int 0))
5782				   (match_dup 4)) (match_dup 5)))
5783     (clobber (reg:CC CC_REGNUM))])]
5784  "operands[3] = operand_subword (operands[0], 0, 0, DImode);
5785   operands[4] = operand_subword (operands[1], 0, 0, DImode);
5786   operands[5] = operand_subword (operands[2], 0, 0, DImode);
5787   operands[6] = operand_subword (operands[0], 1, 0, DImode);
5788   operands[7] = operand_subword (operands[1], 1, 0, DImode);
5789   operands[8] = operand_subword (operands[2], 1, 0, DImode);")
5790
5791;
5792; addsi3 instruction pattern(s).
5793;
5794
5795(define_expand "addsi3"
5796  [(parallel
5797    [(set (match_operand:SI 0 "nonimmediate_operand" "")
5798          (plus:SI (match_operand:SI 1 "nonimmediate_operand" "")
5799                   (match_operand:SI 2 "general_operand" "")))
5800     (clobber (reg:CC CC_REGNUM))])]
5801  ""
5802  "")
5803
5804(define_insn "*addsi3_sign"
5805  [(set (match_operand:SI 0 "register_operand" "=d,d")
5806        (plus:SI (sign_extend:SI (match_operand:HI 2 "memory_operand" "R,T"))
5807                 (match_operand:SI 1 "register_operand" "0,0")))
5808   (clobber (reg:CC CC_REGNUM))]
5809  ""
5810  "@
5811   ah\t%0,%2
5812   ahy\t%0,%2"
5813  [(set_attr "op_type"  "RX,RXY")
5814   (set_attr "cpu_facility" "*,longdisp")
5815   (set_attr "z196prop" "z196_cracked,z196_cracked")])
5816
5817;
5818; add(di|si)3 instruction pattern(s).
5819;
5820
5821; ark, agrk, ar, ahi, ahik, aghik, alfi, slfi, a, ay, agr, aghi, algfi, slgfi, ag, asi, agsi
5822(define_insn "*add<mode>3"
5823  [(set (match_operand:GPR 0 "nonimmediate_operand"           "=d,d,d,d, d, d,d,d,S")
5824        (plus:GPR (match_operand:GPR 1 "nonimmediate_operand" "%0,d,0,d, 0, 0,0,0,0")
5825		  (match_operand:GPR 2 "general_operand"      " d,d,K,K,Op,On,R,T,C") ) )
5826   (clobber (reg:CC CC_REGNUM))]
5827  ""
5828  "@
5829   a<g>r\t%0,%2
5830   a<g>rk\t%0,%1,%2
5831   a<g>hi\t%0,%h2
5832   a<g>hik\t%0,%1,%h2
5833   al<g>fi\t%0,%2
5834   sl<g>fi\t%0,%n2
5835   a<g>\t%0,%2
5836   a<y>\t%0,%2
5837   a<g>si\t%0,%c2"
5838  [(set_attr "op_type"  "RR<E>,RRF,RI,RIE,RIL,RIL,RX<Y>,RXY,SIY")
5839   (set_attr "cpu_facility" "*,z196,*,z196,extimm,extimm,*,longdisp,z10")
5840   (set_attr "z10prop" "z10_super_E1,*,z10_super_E1,*,z10_super_E1,z10_super_E1,
5841                        z10_super_E1,z10_super_E1,z10_super_E1")])
5842
5843; alr, alfi, slfi, al, aly, alrk, alhsik, algr, algfi, slgfi, alg, alsi, algsi, algrk, alghsik
5844(define_insn "*add<mode>3_carry1_cc"
5845  [(set (reg CC_REGNUM)
5846        (compare (plus:GPR (match_operand:GPR 1 "nonimmediate_operand" "%0,d, 0, 0,d,0,0,0")
5847			   (match_operand:GPR 2 "general_operand"      " d,d,Op,On,K,R,T,C"))
5848                 (match_dup 1)))
5849   (set (match_operand:GPR 0 "nonimmediate_operand"                    "=d,d, d, d,d,d,d,d")
5850        (plus:GPR (match_dup 1) (match_dup 2)))]
5851  "s390_match_ccmode (insn, CCL1mode)"
5852  "@
5853   al<g>r\t%0,%2
5854   al<g>rk\t%0,%1,%2
5855   al<g>fi\t%0,%2
5856   sl<g>fi\t%0,%n2
5857   al<g>hsik\t%0,%1,%h2
5858   al<g>\t%0,%2
5859   al<y>\t%0,%2
5860   al<g>si\t%0,%c2"
5861  [(set_attr "op_type"      "RR<E>,RRF,RIL,RIL,RIE,RX<Y>,RXY,SIY")
5862   (set_attr "cpu_facility" "*,z196,extimm,extimm,z196,*,longdisp,z10")
5863   (set_attr "z10prop" "z10_super_E1,*,z10_super_E1,z10_super_E1,*,
5864                        z10_super_E1,z10_super_E1,z10_super_E1")])
5865
5866; alr, al, aly, algr, alg, alrk, algrk
5867(define_insn "*add<mode>3_carry1_cconly"
5868  [(set (reg CC_REGNUM)
5869        (compare (plus:GPR (match_operand:GPR 1 "nonimmediate_operand" "%0,d,0,0")
5870			   (match_operand:GPR 2 "general_operand"       "d,d,R,T"))
5871                 (match_dup 1)))
5872   (clobber (match_scratch:GPR 0                                       "=d,d,d,d"))]
5873  "s390_match_ccmode (insn, CCL1mode)"
5874  "@
5875   al<g>r\t%0,%2
5876   al<g>rk\t%0,%1,%2
5877   al<g>\t%0,%2
5878   al<y>\t%0,%2"
5879  [(set_attr "op_type"  "RR<E>,RRF,RX<Y>,RXY")
5880   (set_attr "cpu_facility" "*,z196,*,longdisp")
5881   (set_attr "z10prop" "z10_super_E1,*,z10_super_E1,z10_super_E1")])
5882
5883; alr, alfi, slfi, al, aly, algr, algfi, slgfi, alg, alsi, algsi, alrk, algrk, alhsik, alghsik
5884(define_insn "*add<mode>3_carry2_cc"
5885  [(set (reg CC_REGNUM)
5886        (compare (plus:GPR (match_operand:GPR 1 "nonimmediate_operand" "%0,d, 0, 0,d,0,0,0")
5887			   (match_operand:GPR 2 "general_operand"      " d,d,Op,On,K,R,T,C"))
5888                 (match_dup 2)))
5889   (set (match_operand:GPR 0 "nonimmediate_operand"                    "=d,d, d, d,d,d,d,S")
5890        (plus:GPR (match_dup 1) (match_dup 2)))]
5891  "s390_match_ccmode (insn, CCL1mode)"
5892  "@
5893   al<g>r\t%0,%2
5894   al<g>rk\t%0,%1,%2
5895   al<g>fi\t%0,%2
5896   sl<g>fi\t%0,%n2
5897   al<g>hsik\t%0,%1,%h2
5898   al<g>\t%0,%2
5899   al<y>\t%0,%2
5900   al<g>si\t%0,%c2"
5901  [(set_attr "op_type"  "RR<E>,RRF,RIL,RIL,RIE,RX<Y>,RXY,SIY")
5902   (set_attr "cpu_facility" "*,z196,extimm,extimm,z196,*,longdisp,z10")
5903   (set_attr "z10prop" "z10_super_E1,*,z10_super_E1,z10_super_E1,*,
5904                        z10_super_E1,z10_super_E1,z10_super_E1")])
5905
5906; alr, al, aly, algr, alg, alrk, algrk
5907(define_insn "*add<mode>3_carry2_cconly"
5908  [(set (reg CC_REGNUM)
5909        (compare (plus:GPR (match_operand:GPR 1 "nonimmediate_operand" "%0,d,0,0")
5910			   (match_operand:GPR 2 "general_operand"       "d,d,R,T"))
5911                 (match_dup 2)))
5912   (clobber (match_scratch:GPR 0                                       "=d,d,d,d"))]
5913  "s390_match_ccmode (insn, CCL1mode)"
5914  "@
5915   al<g>r\t%0,%2
5916   al<g>rk\t%0,%1,%2
5917   al<g>\t%0,%2
5918   al<y>\t%0,%2"
5919  [(set_attr "op_type"  "RR<E>,RRF,RX<Y>,RXY")
5920   (set_attr "cpu_facility" "*,z196,*,longdisp")
5921   (set_attr "z10prop" "z10_super_E1,*,z10_super_E1,z10_super_E1")])
5922
5923; alr, alfi, slfi, al, aly, algr, algfi, slgfi, alg, alsi, algsi, alrk, algrk, alhsik, alghsik
5924(define_insn "*add<mode>3_cc"
5925  [(set (reg CC_REGNUM)
5926        (compare (plus:GPR (match_operand:GPR 1 "nonimmediate_operand" "%0,d, 0, 0,d,0,0,0")
5927			   (match_operand:GPR 2 "general_operand"      " d,d,Op,On,K,R,T,C"))
5928                 (const_int 0)))
5929   (set (match_operand:GPR 0 "nonimmediate_operand"                    "=d,d, d, d,d,d,d,S")
5930        (plus:GPR (match_dup 1) (match_dup 2)))]
5931  "s390_match_ccmode (insn, CCLmode)"
5932  "@
5933   al<g>r\t%0,%2
5934   al<g>rk\t%0,%1,%2
5935   al<g>fi\t%0,%2
5936   sl<g>fi\t%0,%n2
5937   al<g>hsik\t%0,%1,%h2
5938   al<g>\t%0,%2
5939   al<y>\t%0,%2
5940   al<g>si\t%0,%c2"
5941  [(set_attr "op_type"  "RR<E>,RRF,RIL,RIL,RIE,RX<Y>,RXY,SIY")
5942   (set_attr "cpu_facility" "*,z196,extimm,extimm,z196,*,longdisp,z10")
5943   (set_attr "z10prop" "z10_super_E1,*,z10_super_E1,z10_super_E1,
5944                        *,z10_super_E1,z10_super_E1,z10_super_E1")])
5945
5946; alr, al, aly, algr, alg, alrk, algrk
5947(define_insn "*add<mode>3_cconly"
5948  [(set (reg CC_REGNUM)
5949        (compare (plus:GPR (match_operand:GPR 1 "nonimmediate_operand" "%0,d,0,0")
5950			   (match_operand:GPR 2 "general_operand"       "d,d,R,T"))
5951                 (const_int 0)))
5952   (clobber (match_scratch:GPR 0                                       "=d,d,d,d"))]
5953  "s390_match_ccmode (insn, CCLmode)"
5954  "@
5955   al<g>r\t%0,%2
5956   al<g>rk\t%0,%1,%2
5957   al<g>\t%0,%2
5958   al<y>\t%0,%2"
5959  [(set_attr "op_type"  "RR<E>,RRF,RX<Y>,RXY")
5960   (set_attr "cpu_facility" "*,z196,*,longdisp")
5961   (set_attr "z10prop" "z10_super_E1,*,z10_super_E1,z10_super_E1")])
5962
5963; alr, al, aly, algr, alg, alrk, algrk
5964(define_insn "*add<mode>3_cconly2"
5965  [(set (reg CC_REGNUM)
5966        (compare (match_operand:GPR 1 "nonimmediate_operand"    "%0,d,0,0")
5967                 (neg:GPR (match_operand:GPR 2 "general_operand" "d,d,R,T"))))
5968   (clobber (match_scratch:GPR 0                                "=d,d,d,d"))]
5969  "s390_match_ccmode(insn, CCLmode)"
5970  "@
5971   al<g>r\t%0,%2
5972   al<g>rk\t%0,%1,%2
5973   al<g>\t%0,%2
5974   al<y>\t%0,%2"
5975  [(set_attr "op_type"  "RR<E>,RRF,RX<Y>,RXY")
5976   (set_attr "cpu_facility" "*,z196,*,longdisp")
5977   (set_attr "z10prop" "z10_super_E1,*,z10_super_E1,z10_super_E1")])
5978
5979; ahi, afi, aghi, agfi, asi, agsi
5980(define_insn "*add<mode>3_imm_cc"
5981  [(set (reg CC_REGNUM)
5982        (compare (plus:GPR (match_operand:GPR 1 "nonimmediate_operand" " 0, d,0, 0")
5983			   (match_operand:GPR 2 "const_int_operand"    " K, K,Os,C"))
5984                 (const_int 0)))
5985   (set (match_operand:GPR 0 "nonimmediate_operand"                    "=d, d,d, S")
5986        (plus:GPR (match_dup 1) (match_dup 2)))]
5987  "s390_match_ccmode (insn, CCAmode)
5988   && (CONST_OK_FOR_CONSTRAINT_P (INTVAL (operands[2]), 'K', \"K\")
5989       || (CONST_OK_FOR_CONSTRAINT_P (INTVAL (operands[2]), 'O', \"Os\")
5990           /* Avoid INT32_MIN on 32 bit.  */
5991           && (!TARGET_ZARCH || INTVAL (operands[2]) != -0x7fffffff - 1)))"
5992  "@
5993   a<g>hi\t%0,%h2
5994   a<g>hik\t%0,%1,%h2
5995   a<g>fi\t%0,%2
5996   a<g>si\t%0,%c2"
5997  [(set_attr "op_type"      "RI,RIE,RIL,SIY")
5998   (set_attr "cpu_facility" "*,z196,extimm,z10")
5999   (set_attr "z10prop" "z10_super_E1,*,z10_super_E1,z10_super_E1")])
6000
6001(define_insn "*adddi3_sign"
6002  [(set (match_operand:DI                          0 "register_operand" "=d")
6003        (plus:DI (sign_extend:DI (match_operand:HI 2 "memory_operand"    "T"))
6004		 (match_operand:DI                 1 "register_operand"  "0")))
6005   (clobber (reg:CC CC_REGNUM))]
6006  "TARGET_Z14"
6007  "agh\t%0,%2"
6008  [(set_attr "op_type"  "RXY")])
6009
6010
6011; Jump to label OP3 if OP1 + OP2 results in a signed overflow
6012
6013; addv_const_operand accepts all constants which can be handled
6014; without reloads.  These will be handled primarily by
6015; "*addv<mode>3_ccoverflow_const" which doesn't provide a register
6016; alternative.  Hence we have to match the operand exactly.
6017; For immediates we have to avoid the SIGN_EXTEND around OP2.
6018(define_expand "addv<mode>4"
6019  [(parallel
6020    [(set (reg:CCO CC_REGNUM)
6021	  (compare:CCO (plus:<DBL>
6022			(sign_extend:<DBL> (match_operand:GPR 1 "nonimmediate_operand"))
6023			(match_dup 4))
6024		       (sign_extend:<DBL> (plus:GPR (match_dup 1)
6025						    (match_operand:GPR 2 "general_operand")))))
6026     (set (match_operand:GPR 0 "nonimmediate_operand")
6027	  (plus:GPR (match_dup 1) (match_dup 2)))])
6028   (set (pc)
6029	(if_then_else (ne (reg:CCO CC_REGNUM) (const_int 0))
6030		      (label_ref (match_operand 3))
6031		      (pc)))]
6032  ""
6033{
6034  if (CONSTANT_P (operands[2])
6035      && !addv_const_operand (operands[2], GET_MODE (operands[2])))
6036    operands[2] = force_reg (<GPR:MODE>mode, operands[2]);
6037
6038  if (GET_MODE (operands[2]) != VOIDmode)
6039    operands[4] = gen_rtx_SIGN_EXTEND (<DBL>mode, operands[2]);
6040  else
6041    /* This is what CSE does when propagating a constant into the pattern.  */
6042    operands[4] = simplify_unary_operation (SIGN_EXTEND, <GPR:DBL>mode, operands[2], <GPR:MODE>mode);
6043})
6044
6045; ark, agrk, ar, ahi, ahik, aghik, a, ay, agr, aghi, ag, asi, agsi
6046(define_insn "*addv<mode>3_ccoverflow"
6047  [(set (reg CC_REGNUM)
6048	(compare (plus:<DBL>
6049		  (sign_extend:<DBL> (match_operand:GPR 1 "nonimmediate_operand" "%0,d,0,d,0,0,0"))
6050		  (sign_extend:<DBL> (match_operand:GPR 2 "general_operand"      " d,d,K,K,R,T,C")))
6051		 (sign_extend:<DBL> (plus:GPR (match_dup 1) (match_dup 2)))))
6052   (set (match_operand:GPR                              0 "nonimmediate_operand" "=d,d,d,d,d,d,S")
6053        (plus:GPR (match_dup 1) (match_dup 2)))]
6054  "s390_match_ccmode (insn, CCOmode)"
6055  "@
6056   a<g>r\t%0,%2
6057   a<g>rk\t%0,%1,%2
6058   a<g>hi\t%0,%h2
6059   a<g>hik\t%0,%1,%h2
6060   a<g>\t%0,%2
6061   a<y>\t%0,%2
6062   a<g>si\t%0,%c2"
6063  [(set_attr "op_type"  "RR<E>,RRF,RI,RIE,RX<Y>,RXY,SIY")
6064   (set_attr "cpu_facility" "*,z196,*,z196,*,longdisp,z10")
6065   (set_attr "z10prop" "z10_super_E1,*,z10_super_E1,*,
6066                        z10_super_E1,z10_super_E1,z10_super_E1")])
6067
6068; ahi, aghi, ahik, aghik, asi, agsi
6069(define_insn "*addv<mode>3_ccoverflow_const"
6070  [(set (reg CC_REGNUM)
6071	(compare (plus:<DBL>
6072		  (sign_extend:<DBL> (match_operand:GPR 1 "nonimmediate_operand" "%0,d,0"))
6073		  (match_operand:<DBL>                  2 "addv_const_operand"    "K,K,C"))
6074		 (sign_extend:<DBL> (plus:GPR (match_dup 1) (match_dup 2)))))
6075   (set (match_operand:GPR                              0 "nonimmediate_operand" "=d,d,S")
6076        (plus:GPR (match_dup 1) (match_dup 2)))]
6077  "s390_match_ccmode (insn, CCOmode)"
6078  "@
6079   a<g>hi\t%0,%h2
6080   a<g>hik\t%0,%1,%h2
6081   a<g>si\t%0,%c2"
6082  [(set_attr "op_type"  "RI,RIE,SIY")
6083   (set_attr "cpu_facility" "*,z196,z10")
6084   (set_attr "z10prop" "z10_super_E1,*,z10_super_E1")])
6085
6086
6087;
6088; add(tf|df|sf|td|dd)3 instruction pattern(s).
6089;
6090
6091; axbr, adbr, aebr, axb, adb, aeb, adtr, axtr
6092; FIXME: wfadb does not clobber cc
6093(define_insn "add<mode>3"
6094  [(set (match_operand:FP          0 "register_operand"     "=f,f,f,v,v")
6095        (plus:FP (match_operand:FP 1 "nonimmediate_operand" "%f,0,0,v,v")
6096		 (match_operand:FP 2 "general_operand"       "f,f,R,v,v")))
6097   (clobber (reg:CC CC_REGNUM))]
6098  "TARGET_HARD_FLOAT"
6099  "@
6100   a<xde>tr\t%0,%1,%2
6101   a<xde>br\t%0,%2
6102   a<xde>b\t%0,%2
6103   wfadb\t%v0,%v1,%v2
6104   wfasb\t%v0,%v1,%v2"
6105  [(set_attr "op_type"      "RRF,RRE,RXE,VRR,VRR")
6106   (set_attr "type"         "fsimp<mode>")
6107   (set_attr "cpu_facility" "*,*,*,vx,vxe")
6108   (set_attr "enabled"      "<nBFP>,<nDFP>,<DSF>,<DF>,<SF>")])
6109
6110; axbr, adbr, aebr, axb, adb, aeb, adtr, axtr
6111(define_insn "*add<mode>3_cc"
6112  [(set (reg CC_REGNUM)
6113	(compare (plus:FP (match_operand:FP 1 "nonimmediate_operand" "%f,0,0")
6114			  (match_operand:FP 2 "general_operand"       "f,f,R"))
6115		 (match_operand:FP 3 "const0_operand" "")))
6116   (set (match_operand:FP 0 "register_operand" "=f,f,f")
6117	(plus:FP (match_dup 1) (match_dup 2)))]
6118  "s390_match_ccmode (insn, CCSmode) && TARGET_HARD_FLOAT"
6119  "@
6120   a<xde>tr\t%0,%1,%2
6121   a<xde>br\t%0,%2
6122   a<xde>b\t%0,%2"
6123  [(set_attr "op_type"  "RRF,RRE,RXE")
6124   (set_attr "type"     "fsimp<mode>")
6125   (set_attr "enabled"  "<nBFP>,<nDFP>,<DSF>")])
6126
6127; axbr, adbr, aebr, axb, adb, aeb, adtr, axtr
6128(define_insn "*add<mode>3_cconly"
6129  [(set (reg CC_REGNUM)
6130	(compare (plus:FP (match_operand:FP 1 "nonimmediate_operand" "%f,0,0")
6131			  (match_operand:FP 2 "general_operand"       "f,f,R"))
6132		 (match_operand:FP 3 "const0_operand" "")))
6133   (clobber (match_scratch:FP 0 "=f,f,f"))]
6134  "s390_match_ccmode (insn, CCSmode) && TARGET_HARD_FLOAT"
6135  "@
6136   a<xde>tr\t%0,%1,%2
6137   a<xde>br\t%0,%2
6138   a<xde>b\t%0,%2"
6139  [(set_attr "op_type"  "RRF,RRE,RXE")
6140   (set_attr "type"     "fsimp<mode>")
6141   (set_attr "enabled"  "<nBFP>,<nDFP>,<DSF>")])
6142
6143;
6144; Pointer add instruction patterns
6145;
6146
6147; This will match "*la_64"
6148(define_expand "addptrdi3"
6149  [(set (match_operand:DI 0 "register_operand" "")
6150        (plus:DI (match_operand:DI 1 "register_operand" "")
6151		 (match_operand:DI 2 "nonmemory_operand" "")))]
6152  "TARGET_64BIT"
6153{
6154  if (GET_CODE (operands[2]) == CONST_INT)
6155    {
6156      HOST_WIDE_INT c = INTVAL (operands[2]);
6157
6158      if (!CONST_OK_FOR_CONSTRAINT_P (c, 'K', "K")
6159	  && !CONST_OK_FOR_CONSTRAINT_P (c, 'O', "Os"))
6160        {
6161	  operands[2] = force_const_mem (DImode, operands[2]);
6162	  operands[2] = force_reg (DImode, operands[2]);
6163        }
6164      else if (!DISP_IN_RANGE (INTVAL (operands[2])))
6165        operands[2] = force_reg (DImode, operands[2]);
6166    }
6167})
6168
6169; For 31 bit we have to prevent the generated pattern from matching
6170; normal ADDs since la only does a 31 bit add.  This is supposed to
6171; match "force_la_31".
6172(define_expand "addptrsi3"
6173  [(parallel
6174    [(set (match_operand:SI 0 "register_operand" "")
6175	  (plus:SI (match_operand:SI 1 "register_operand" "")
6176		   (match_operand:SI 2 "nonmemory_operand" "")))
6177		   (use (const_int 0))])]
6178  "!TARGET_64BIT"
6179{
6180  if (GET_CODE (operands[2]) == CONST_INT)
6181    {
6182      HOST_WIDE_INT c = INTVAL (operands[2]);
6183
6184      if (!CONST_OK_FOR_CONSTRAINT_P (c, 'K', "K")
6185	  && !CONST_OK_FOR_CONSTRAINT_P (c, 'O', "Os"))
6186        {
6187	  operands[2] = force_const_mem (SImode, operands[2]);
6188	  operands[2] = force_reg (SImode, operands[2]);
6189        }
6190      else if (!DISP_IN_RANGE (INTVAL (operands[2])))
6191        operands[2] = force_reg (SImode, operands[2]);
6192    }
6193})
6194
6195;;
6196;;- Subtract instructions.
6197;;
6198
6199;
6200; subti3 instruction pattern(s).
6201;
6202
6203(define_expand "subti3"
6204  [(parallel
6205    [(set (match_operand:TI           0 "register_operand" "")
6206	  (minus:TI (match_operand:TI 1 "register_operand" "")
6207		    (match_operand:TI 2 "general_operand"  "") ) )
6208     (clobber (reg:CC CC_REGNUM))])]
6209  "TARGET_ZARCH"
6210{
6211  /* For z13 we have vsq which doesn't set CC.  */
6212  if (TARGET_VX)
6213    {
6214      emit_insn (gen_rtx_SET (operands[0],
6215			      gen_rtx_MINUS (TImode,
6216                                            operands[1],
6217                                            copy_to_mode_reg (TImode, operands[2]))));
6218      DONE;
6219    }
6220})
6221
6222(define_insn_and_split "*subti3"
6223  [(set (match_operand:TI           0 "register_operand" "=&d")
6224        (minus:TI (match_operand:TI 1 "register_operand"   "0")
6225                  (match_operand:TI 2 "general_operand"   "do") ) )
6226   (clobber (reg:CC CC_REGNUM))]
6227  "TARGET_ZARCH"
6228  "#"
6229  "&& reload_completed"
6230  [(parallel
6231    [(set (reg:CCL2 CC_REGNUM)
6232          (compare:CCL2 (minus:DI (match_dup 7) (match_dup 8))
6233                        (match_dup 7)))
6234     (set (match_dup 6) (minus:DI (match_dup 7) (match_dup 8)))])
6235   (parallel
6236    [(set (match_dup 3) (minus:DI (minus:DI (match_dup 4) (match_dup 5))
6237                                  (gtu:DI (reg:CCL2 CC_REGNUM) (const_int 0))))
6238     (clobber (reg:CC CC_REGNUM))])]
6239  "operands[3] = operand_subword (operands[0], 0, 0, TImode);
6240   operands[4] = operand_subword (operands[1], 0, 0, TImode);
6241   operands[5] = operand_subword (operands[2], 0, 0, TImode);
6242   operands[6] = operand_subword (operands[0], 1, 0, TImode);
6243   operands[7] = operand_subword (operands[1], 1, 0, TImode);
6244   operands[8] = operand_subword (operands[2], 1, 0, TImode);"
6245  [(set_attr "op_type"      "*")
6246   (set_attr "cpu_facility" "*")])
6247
6248;
6249; subdi3 instruction pattern(s).
6250;
6251
6252(define_expand "subdi3"
6253  [(parallel
6254    [(set (match_operand:DI 0 "register_operand" "")
6255          (minus:DI (match_operand:DI 1 "register_operand" "")
6256                    (match_operand:DI 2 "general_operand" "")))
6257     (clobber (reg:CC CC_REGNUM))])]
6258  ""
6259  "")
6260
6261(define_insn "*subdi3_sign"
6262  [(set (match_operand:DI 0 "register_operand" "=d,d")
6263        (minus:DI (match_operand:DI 1 "register_operand" "0,0")
6264                  (sign_extend:DI (match_operand:SI 2 "general_operand" "d,T"))))
6265   (clobber (reg:CC CC_REGNUM))]
6266  "TARGET_ZARCH"
6267  "@
6268   sgfr\t%0,%2
6269   sgf\t%0,%2"
6270  [(set_attr "op_type"  "RRE,RXY")
6271   (set_attr "z10prop" "z10_c,*")
6272   (set_attr "z196prop" "z196_cracked")])
6273
6274(define_insn "*subdi3_zero_cc"
6275  [(set (reg CC_REGNUM)
6276        (compare (minus:DI (match_operand:DI 1 "register_operand" "0,0")
6277                           (zero_extend:DI (match_operand:SI 2 "general_operand" "d,T")))
6278                 (const_int 0)))
6279   (set (match_operand:DI 0 "register_operand" "=d,d")
6280        (minus:DI (match_dup 1) (zero_extend:DI (match_dup 2))))]
6281  "s390_match_ccmode (insn, CCLmode) && TARGET_ZARCH"
6282  "@
6283   slgfr\t%0,%2
6284   slgf\t%0,%2"
6285  [(set_attr "op_type"  "RRE,RXY")
6286   (set_attr "z10prop" "z10_super_c_E1,z10_super_E1")])
6287
6288(define_insn "*subdi3_zero_cconly"
6289  [(set (reg CC_REGNUM)
6290        (compare (minus:DI (match_operand:DI 1 "register_operand" "0,0")
6291                           (zero_extend:DI (match_operand:SI 2 "general_operand" "d,T")))
6292                 (const_int 0)))
6293   (clobber (match_scratch:DI 0 "=d,d"))]
6294  "s390_match_ccmode (insn, CCLmode) && TARGET_ZARCH"
6295  "@
6296   slgfr\t%0,%2
6297   slgf\t%0,%2"
6298  [(set_attr "op_type"  "RRE,RXY")
6299   (set_attr "z10prop" "z10_super_c_E1,z10_super_E1")])
6300
6301(define_insn "*subdi3_zero"
6302  [(set (match_operand:DI 0 "register_operand" "=d,d")
6303        (minus:DI (match_operand:DI 1 "register_operand" "0,0")
6304                  (zero_extend:DI (match_operand:SI 2 "general_operand" "d,T"))))
6305   (clobber (reg:CC CC_REGNUM))]
6306  "TARGET_ZARCH"
6307  "@
6308   slgfr\t%0,%2
6309   slgf\t%0,%2"
6310  [(set_attr "op_type"  "RRE,RXY")
6311   (set_attr "z10prop" "z10_super_c_E1,z10_super_E1")])
6312
6313(define_insn_and_split "*subdi3_31z"
6314  [(set (match_operand:DI 0 "register_operand" "=&d")
6315        (minus:DI (match_operand:DI 1 "register_operand" "0")
6316                  (match_operand:DI 2 "general_operand" "do") ) )
6317   (clobber (reg:CC CC_REGNUM))]
6318  "!TARGET_ZARCH"
6319  "#"
6320  "&& reload_completed"
6321  [(parallel
6322    [(set (reg:CCL2 CC_REGNUM)
6323          (compare:CCL2 (minus:SI (match_dup 7) (match_dup 8))
6324                        (match_dup 7)))
6325     (set (match_dup 6) (minus:SI (match_dup 7) (match_dup 8)))])
6326   (parallel
6327    [(set (match_dup 3) (minus:SI (minus:SI (match_dup 4) (match_dup 5))
6328                                  (gtu:SI (reg:CCL2 CC_REGNUM) (const_int 0))))
6329     (clobber (reg:CC CC_REGNUM))])]
6330  "operands[3] = operand_subword (operands[0], 0, 0, DImode);
6331   operands[4] = operand_subword (operands[1], 0, 0, DImode);
6332   operands[5] = operand_subword (operands[2], 0, 0, DImode);
6333   operands[6] = operand_subword (operands[0], 1, 0, DImode);
6334   operands[7] = operand_subword (operands[1], 1, 0, DImode);
6335   operands[8] = operand_subword (operands[2], 1, 0, DImode);")
6336
6337;
6338; subsi3 instruction pattern(s).
6339;
6340
6341(define_expand "subsi3"
6342  [(parallel
6343    [(set (match_operand:SI 0 "register_operand" "")
6344          (minus:SI (match_operand:SI 1 "register_operand" "")
6345                    (match_operand:SI 2 "general_operand" "")))
6346     (clobber (reg:CC CC_REGNUM))])]
6347  ""
6348  "")
6349
6350(define_insn "*subsi3_sign"
6351  [(set (match_operand:SI 0 "register_operand" "=d,d")
6352        (minus:SI (match_operand:SI 1 "register_operand" "0,0")
6353                  (sign_extend:SI (match_operand:HI 2 "memory_operand" "R,T"))))
6354   (clobber (reg:CC CC_REGNUM))]
6355  ""
6356  "@
6357   sh\t%0,%2
6358   shy\t%0,%2"
6359  [(set_attr "op_type"  "RX,RXY")
6360   (set_attr "cpu_facility" "*,longdisp")
6361   (set_attr "z196prop" "z196_cracked,z196_cracked")])
6362
6363;
6364; sub(di|si)3 instruction pattern(s).
6365;
6366
6367; sr, s, sy, sgr, sg, srk, sgrk
6368(define_insn "*sub<mode>3"
6369  [(set (match_operand:GPR 0 "register_operand"           "=d,d,d,d")
6370        (minus:GPR (match_operand:GPR 1 "register_operand" "0,d,0,0")
6371		   (match_operand:GPR 2 "general_operand"  "d,d,R,T") ) )
6372   (clobber (reg:CC CC_REGNUM))]
6373  ""
6374  "@
6375   s<g>r\t%0,%2
6376   s<g>rk\t%0,%1,%2
6377   s<g>\t%0,%2
6378   s<y>\t%0,%2"
6379  [(set_attr "op_type"  "RR<E>,RRF,RX<Y>,RXY")
6380   (set_attr "cpu_facility" "*,z196,*,longdisp")
6381   (set_attr "z10prop" "z10_super_c_E1,*,z10_super_E1,z10_super_E1")])
6382
6383; slr, sl, sly, slgr, slg, slrk, slgrk
6384(define_insn "*sub<mode>3_borrow_cc"
6385  [(set (reg CC_REGNUM)
6386        (compare (minus:GPR (match_operand:GPR 1 "register_operand" "0,d,0,0")
6387			    (match_operand:GPR 2 "general_operand"  "d,d,R,T"))
6388                 (match_dup 1)))
6389   (set (match_operand:GPR 0 "register_operand"                    "=d,d,d,d")
6390        (minus:GPR (match_dup 1) (match_dup 2)))]
6391  "s390_match_ccmode (insn, CCL2mode)"
6392  "@
6393   sl<g>r\t%0,%2
6394   sl<g>rk\t%0,%1,%2
6395   sl<g>\t%0,%2
6396   sl<y>\t%0,%2"
6397  [(set_attr "op_type"  "RR<E>,RRF,RX<Y>,RXY")
6398   (set_attr "cpu_facility" "*,z196,*,longdisp")
6399   (set_attr "z10prop" "z10_super_c_E1,*,z10_super_E1,z10_super_E1")])
6400
6401; slr, sl, sly, slgr, slg, slrk, slgrk
6402(define_insn "*sub<mode>3_borrow_cconly"
6403  [(set (reg CC_REGNUM)
6404        (compare (minus:GPR (match_operand:GPR 1 "register_operand" "0,d,0,0")
6405			    (match_operand:GPR 2 "general_operand"  "d,d,R,T"))
6406                 (match_dup 1)))
6407   (clobber (match_scratch:GPR 0                                   "=d,d,d,d"))]
6408  "s390_match_ccmode (insn, CCL2mode)"
6409  "@
6410   sl<g>r\t%0,%2
6411   sl<g>rk\t%0,%1,%2
6412   sl<g>\t%0,%2
6413   sl<y>\t%0,%2"
6414  [(set_attr "op_type"  "RR<E>,RRF,RX<Y>,RXY")
6415   (set_attr "cpu_facility" "*,z196,*,longdisp")
6416   (set_attr "z10prop" "z10_super_c_E1,*,z10_super_E1,z10_super_E1")])
6417
6418; slr, sl, sly, slgr, slg, slrk, slgrk
6419(define_insn "*sub<mode>3_cc"
6420  [(set (reg CC_REGNUM)
6421        (compare (minus:GPR (match_operand:GPR 1 "register_operand" "0,d,0,0")
6422			    (match_operand:GPR 2 "general_operand"  "d,d,R,T"))
6423                 (const_int 0)))
6424   (set (match_operand:GPR 0 "register_operand"                    "=d,d,d,d")
6425        (minus:GPR (match_dup 1) (match_dup 2)))]
6426  "s390_match_ccmode (insn, CCLmode)"
6427  "@
6428   sl<g>r\t%0,%2
6429   sl<g>rk\t%0,%1,%2
6430   sl<g>\t%0,%2
6431   sl<y>\t%0,%2"
6432  [(set_attr "op_type"  "RR<E>,RRF,RX<Y>,RXY")
6433   (set_attr "cpu_facility" "*,z196,*,longdisp")
6434   (set_attr "z10prop" "z10_super_c_E1,*,z10_super_E1,z10_super_E1")])
6435
6436; slr, sl, sly, slgr, slg, slrk, slgrk
6437(define_insn "*sub<mode>3_cc2"
6438  [(set (reg CC_REGNUM)
6439        (compare (match_operand:GPR 1 "register_operand" "0,d,0,0")
6440                 (match_operand:GPR 2 "general_operand"  "d,d,R,T")))
6441   (set (match_operand:GPR 0 "register_operand"         "=d,d,d,d")
6442        (minus:GPR (match_dup 1) (match_dup 2)))]
6443  "s390_match_ccmode (insn, CCL3mode)"
6444  "@
6445   sl<g>r\t%0,%2
6446   sl<g>rk\t%0,%1,%2
6447   sl<g>\t%0,%2
6448   sl<y>\t%0,%2"
6449  [(set_attr "op_type"  "RR<E>,RRF,RX<Y>,RXY")
6450   (set_attr "cpu_facility" "*,z196,*,longdisp")
6451   (set_attr "z10prop" "z10_super_c_E1,*,z10_super_E1,z10_super_E1")])
6452
6453; slr, sl, sly, slgr, slg, slrk, slgrk
6454(define_insn "*sub<mode>3_cconly"
6455  [(set (reg CC_REGNUM)
6456        (compare (minus:GPR (match_operand:GPR 1 "register_operand" "0,d,0,0")
6457			    (match_operand:GPR 2 "general_operand"  "d,d,R,T"))
6458                 (const_int 0)))
6459   (clobber (match_scratch:GPR 0                                   "=d,d,d,d"))]
6460  "s390_match_ccmode (insn, CCLmode)"
6461  "@
6462   sl<g>r\t%0,%2
6463   sl<g>rk\t%0,%1,%2
6464   sl<g>\t%0,%2
6465   sl<y>\t%0,%2"
6466  [(set_attr "op_type"  "RR<E>,RRF,RX<Y>,RXY")
6467   (set_attr "cpu_facility" "*,z196,*,longdisp")
6468   (set_attr "z10prop" "z10_super_c_E1,*,z10_super_E1,z10_super_E1")])
6469
6470
6471; slr, sl, sly, slgr, slg, slrk, slgrk
6472(define_insn "*sub<mode>3_cconly2"
6473  [(set (reg CC_REGNUM)
6474        (compare (match_operand:GPR 1 "register_operand" "0,d,0,0")
6475                 (match_operand:GPR 2 "general_operand"  "d,d,R,T")))
6476   (clobber (match_scratch:GPR 0                        "=d,d,d,d"))]
6477  "s390_match_ccmode (insn, CCL3mode)"
6478  "@
6479   sl<g>r\t%0,%2
6480   sl<g>rk\t%0,%1,%2
6481   sl<g>\t%0,%2
6482   sl<y>\t%0,%2"
6483  [(set_attr "op_type"  "RR<E>,RRF,RX<Y>,RXY")
6484   (set_attr "cpu_facility" "*,z196,*,longdisp")
6485   (set_attr "z10prop" "z10_super_c_E1,*,z10_super_E1,z10_super_E1")])
6486
6487(define_insn "*subdi3_sign"
6488  [(set (match_operand:DI                           0 "register_operand" "=d")
6489        (minus:DI (match_operand:DI                 1 "register_operand"  "0")
6490                  (sign_extend:DI (match_operand:HI 2 "memory_operand"    "T"))))
6491   (clobber (reg:CC CC_REGNUM))]
6492  "TARGET_Z14"
6493  "sgh\t%0,%2"
6494  [(set_attr "op_type"  "RXY")])
6495
6496; Jump to label OP3 if OP1 - OP2 results in a signed overflow
6497(define_expand "subv<mode>4"
6498  [(parallel
6499    [(set (reg:CCO CC_REGNUM)
6500	  (compare:CCO (minus:<DBL>
6501			(sign_extend:<DBL> (match_operand:GPR 1 "nonimmediate_operand"))
6502			(sign_extend:<DBL> (match_operand:GPR 2 "nonimmediate_operand")))
6503		       (sign_extend:<DBL> (minus:GPR (match_dup 1) (match_dup 2)))))
6504     (set (match_operand:GPR                                  0 "nonimmediate_operand")
6505          (minus:GPR (match_dup 1) (match_dup 2)))])
6506   (set (pc)
6507        (if_then_else (ne (reg:CCO CC_REGNUM) (const_int 0))
6508		      (label_ref (match_operand 3))
6509                      (pc)))]
6510  "")
6511
6512; sr, s, sy, sgr, sg, srk, sgrk
6513(define_insn "*subv<mode>3_ccoverflow"
6514  [(set (reg CC_REGNUM)
6515	(compare (minus:<DBL>
6516		  (sign_extend:<DBL> (match_operand:GPR 1 "nonimmediate_operand" "0,d,0,0"))
6517		  (sign_extend:<DBL> (match_operand:GPR 2 "nonimmediate_operand" "d,d,R,T")))
6518		 (sign_extend:<DBL> (minus:GPR (match_dup 1) (match_dup 2)))))
6519   (set (match_operand:GPR                              0 "register_operand"    "=d,d,d,d")
6520        (minus:GPR (match_dup 1) (match_dup 2)))]
6521  "s390_match_ccmode (insn, CCOmode)"
6522  "@
6523   s<g>r\t%0,%2
6524   s<g>rk\t%0,%1,%2
6525   s<g>\t%0,%2
6526   s<y>\t%0,%2"
6527  [(set_attr "op_type"  "RR<E>,RRF,RX<Y>,RXY")
6528   (set_attr "cpu_facility" "*,z196,*,longdisp")
6529   (set_attr "z10prop" "z10_super_c_E1,*,z10_super_E1,z10_super_E1")])
6530
6531
6532;
6533; sub(tf|df|sf|td|dd)3 instruction pattern(s).
6534;
6535
6536; FIXME: (clobber (match_scratch:CC 3 "=c,c,c,X,X")) does not work - why?
6537; sxbr, sdbr, sebr, sdb, seb, sxtr, sdtr
6538(define_insn "sub<mode>3"
6539  [(set (match_operand:FP           0 "register_operand" "=f,f,f,v,v")
6540        (minus:FP (match_operand:FP 1 "register_operand"  "f,0,0,v,v")
6541		  (match_operand:FP 2 "general_operand"   "f,f,R,v,v")))
6542   (clobber (reg:CC CC_REGNUM))]
6543  "TARGET_HARD_FLOAT"
6544  "@
6545   s<xde>tr\t%0,%1,%2
6546   s<xde>br\t%0,%2
6547   s<xde>b\t%0,%2
6548   wfsdb\t%v0,%v1,%v2
6549   wfssb\t%v0,%v1,%v2"
6550  [(set_attr "op_type"      "RRF,RRE,RXE,VRR,VRR")
6551   (set_attr "type"         "fsimp<mode>")
6552   (set_attr "cpu_facility" "*,*,*,vx,vxe")
6553   (set_attr "enabled"      "<nBFP>,<nDFP>,<DSF>,<DF>,<SF>")])
6554
6555; sxbr, sdbr, sebr, sdb, seb, sxtr, sdtr
6556(define_insn "*sub<mode>3_cc"
6557  [(set (reg CC_REGNUM)
6558	(compare (minus:FP (match_operand:FP 1 "nonimmediate_operand" "f,0,0")
6559			   (match_operand:FP 2 "general_operand"      "f,f,R"))
6560		 (match_operand:FP 3 "const0_operand" "")))
6561   (set (match_operand:FP 0 "register_operand" "=f,f,f")
6562	(minus:FP (match_dup 1) (match_dup 2)))]
6563  "s390_match_ccmode (insn, CCSmode) && TARGET_HARD_FLOAT"
6564  "@
6565   s<xde>tr\t%0,%1,%2
6566   s<xde>br\t%0,%2
6567   s<xde>b\t%0,%2"
6568  [(set_attr "op_type"  "RRF,RRE,RXE")
6569   (set_attr "type"     "fsimp<mode>")
6570   (set_attr "enabled"  "<nBFP>,<nDFP>,<DSF>")])
6571
6572; sxbr, sdbr, sebr, sdb, seb, sxtr, sdtr
6573(define_insn "*sub<mode>3_cconly"
6574  [(set (reg CC_REGNUM)
6575	(compare (minus:FP (match_operand:FP 1 "nonimmediate_operand" "f,0,0")
6576			   (match_operand:FP 2 "general_operand"      "f,f,R"))
6577		 (match_operand:FP 3 "const0_operand" "")))
6578   (clobber (match_scratch:FP 0 "=f,f,f"))]
6579  "s390_match_ccmode (insn, CCSmode) && TARGET_HARD_FLOAT"
6580  "@
6581   s<xde>tr\t%0,%1,%2
6582   s<xde>br\t%0,%2
6583   s<xde>b\t%0,%2"
6584  [(set_attr "op_type"  "RRF,RRE,RXE")
6585   (set_attr "type"     "fsimp<mode>")
6586   (set_attr "enabled"  "<nBFP>,<nDFP>,<DSF>")])
6587
6588
6589;;
6590;;- Conditional add/subtract instructions.
6591;;
6592
6593;
6594; add(di|si)cc instruction pattern(s).
6595;
6596
6597; the following 4 patterns are used when the result of an add with
6598; carry is checked for an overflow condition
6599
6600; op1 + op2 + c < op1
6601
6602; alcr, alc, alcgr, alcg
6603(define_insn "*add<mode>3_alc_carry1_cc"
6604  [(set (reg CC_REGNUM)
6605        (compare
6606          (plus:GPR (plus:GPR (match_operand:GPR 3 "s390_alc_comparison" "")
6607                              (match_operand:GPR 1 "nonimmediate_operand" "%0,0"))
6608                    (match_operand:GPR 2 "general_operand" "d,T"))
6609          (match_dup 1)))
6610   (set (match_operand:GPR 0 "register_operand" "=d,d")
6611        (plus:GPR (plus:GPR (match_dup 3) (match_dup 1)) (match_dup 2)))]
6612  "s390_match_ccmode (insn, CCL1mode)"
6613  "@
6614   alc<g>r\t%0,%2
6615   alc<g>\t%0,%2"
6616  [(set_attr "op_type"  "RRE,RXY")
6617   (set_attr "z196prop" "z196_alone,z196_alone")])
6618
6619; alcr, alc, alcgr, alcg
6620(define_insn "*add<mode>3_alc_carry1_cconly"
6621  [(set (reg CC_REGNUM)
6622        (compare
6623          (plus:GPR (plus:GPR (match_operand:GPR 3 "s390_alc_comparison" "")
6624                              (match_operand:GPR 1 "nonimmediate_operand" "%0,0"))
6625                    (match_operand:GPR 2 "general_operand" "d,T"))
6626          (match_dup 1)))
6627   (clobber (match_scratch:GPR 0 "=d,d"))]
6628  "s390_match_ccmode (insn, CCL1mode)"
6629  "@
6630   alc<g>r\t%0,%2
6631   alc<g>\t%0,%2"
6632  [(set_attr "op_type"  "RRE,RXY")
6633   (set_attr "z196prop" "z196_alone,z196_alone")])
6634
6635; op1 + op2 + c < op2
6636
6637; alcr, alc, alcgr, alcg
6638(define_insn "*add<mode>3_alc_carry2_cc"
6639  [(set (reg CC_REGNUM)
6640        (compare
6641          (plus:GPR (plus:GPR (match_operand:GPR 3 "s390_alc_comparison" "")
6642                              (match_operand:GPR 1 "nonimmediate_operand" "%0,0"))
6643                    (match_operand:GPR 2 "general_operand" "d,T"))
6644          (match_dup 2)))
6645   (set (match_operand:GPR 0 "register_operand" "=d,d")
6646        (plus:GPR (plus:GPR (match_dup 3) (match_dup 1)) (match_dup 2)))]
6647  "s390_match_ccmode (insn, CCL1mode)"
6648  "@
6649   alc<g>r\t%0,%2
6650   alc<g>\t%0,%2"
6651  [(set_attr "op_type"  "RRE,RXY")])
6652
6653; alcr, alc, alcgr, alcg
6654(define_insn "*add<mode>3_alc_carry2_cconly"
6655  [(set (reg CC_REGNUM)
6656        (compare
6657          (plus:GPR (plus:GPR (match_operand:GPR 3 "s390_alc_comparison" "")
6658                              (match_operand:GPR 1 "nonimmediate_operand" "%0,0"))
6659                    (match_operand:GPR 2 "general_operand" "d,T"))
6660          (match_dup 2)))
6661   (clobber (match_scratch:GPR 0 "=d,d"))]
6662  "s390_match_ccmode (insn, CCL1mode)"
6663  "@
6664   alc<g>r\t%0,%2
6665   alc<g>\t%0,%2"
6666  [(set_attr "op_type"  "RRE,RXY")])
6667
6668; alcr, alc, alcgr, alcg
6669(define_insn "*add<mode>3_alc_cc"
6670  [(set (reg CC_REGNUM)
6671        (compare
6672          (plus:GPR (plus:GPR (match_operand:GPR 3 "s390_alc_comparison" "")
6673                              (match_operand:GPR 1 "nonimmediate_operand" "%0,0"))
6674                    (match_operand:GPR 2 "general_operand" "d,T"))
6675          (const_int 0)))
6676   (set (match_operand:GPR 0 "register_operand" "=d,d")
6677        (plus:GPR (plus:GPR (match_dup 3) (match_dup 1)) (match_dup 2)))]
6678  "s390_match_ccmode (insn, CCLmode)"
6679  "@
6680   alc<g>r\t%0,%2
6681   alc<g>\t%0,%2"
6682  [(set_attr "op_type"  "RRE,RXY")])
6683
6684; alcr, alc, alcgr, alcg
6685(define_insn "*add<mode>3_alc"
6686  [(set (match_operand:GPR 0 "register_operand" "=d,d")
6687        (plus:GPR (plus:GPR (match_operand:GPR 3 "s390_alc_comparison" "")
6688                            (match_operand:GPR 1 "nonimmediate_operand" "%0,0"))
6689                  (match_operand:GPR 2 "general_operand" "d,T")))
6690   (clobber (reg:CC CC_REGNUM))]
6691  ""
6692  "@
6693   alc<g>r\t%0,%2
6694   alc<g>\t%0,%2"
6695  [(set_attr "op_type"  "RRE,RXY")])
6696
6697; slbr, slb, slbgr, slbg
6698(define_insn "*sub<mode>3_slb_cc"
6699  [(set (reg CC_REGNUM)
6700        (compare
6701          (minus:GPR (minus:GPR (match_operand:GPR 1 "nonimmediate_operand" "0,0")
6702                                (match_operand:GPR 2 "general_operand" "d,T"))
6703                     (match_operand:GPR 3 "s390_slb_comparison" ""))
6704          (const_int 0)))
6705   (set (match_operand:GPR 0 "register_operand" "=d,d")
6706        (minus:GPR (minus:GPR (match_dup 1) (match_dup 2)) (match_dup 3)))]
6707  "s390_match_ccmode (insn, CCLmode)"
6708  "@
6709   slb<g>r\t%0,%2
6710   slb<g>\t%0,%2"
6711  [(set_attr "op_type"  "RRE,RXY")
6712   (set_attr "z10prop" "z10_c,*")])
6713
6714; slbr, slb, slbgr, slbg
6715(define_insn "*sub<mode>3_slb"
6716  [(set (match_operand:GPR 0 "register_operand" "=d,d")
6717        (minus:GPR (minus:GPR (match_operand:GPR 1 "nonimmediate_operand" "0,0")
6718                              (match_operand:GPR 2 "general_operand" "d,T"))
6719                   (match_operand:GPR 3 "s390_slb_comparison" "")))
6720   (clobber (reg:CC CC_REGNUM))]
6721  ""
6722  "@
6723   slb<g>r\t%0,%2
6724   slb<g>\t%0,%2"
6725  [(set_attr "op_type"  "RRE,RXY")
6726   (set_attr "z10prop" "z10_c,*")])
6727
6728(define_expand "add<mode>cc"
6729  [(match_operand:GPR 0 "register_operand" "")
6730   (match_operand 1 "comparison_operator" "")
6731   (match_operand:GPR 2 "register_operand" "")
6732   (match_operand:GPR 3 "const_int_operand" "")]
6733  ""
6734  "if (!s390_expand_addcc (GET_CODE (operands[1]),
6735			   XEXP (operands[1], 0), XEXP (operands[1], 1),
6736			   operands[0], operands[2],
6737			   operands[3])) FAIL; DONE;")
6738
6739;
6740; scond instruction pattern(s).
6741;
6742
6743(define_insn_and_split "*scond<mode>"
6744  [(set (match_operand:GPR 0 "register_operand" "=&d")
6745        (match_operand:GPR 1 "s390_alc_comparison" ""))
6746   (clobber (reg:CC CC_REGNUM))]
6747  ""
6748  "#"
6749  "&& reload_completed"
6750  [(set (match_dup 0) (const_int 0))
6751   (parallel
6752    [(set (match_dup 0) (plus:GPR (plus:GPR (match_dup 1) (match_dup 0))
6753                                  (match_dup 0)))
6754     (clobber (reg:CC CC_REGNUM))])]
6755  "")
6756
6757(define_insn_and_split "*scond<mode>_neg"
6758  [(set (match_operand:GPR 0 "register_operand" "=&d")
6759        (match_operand:GPR 1 "s390_slb_comparison" ""))
6760   (clobber (reg:CC CC_REGNUM))]
6761  ""
6762  "#"
6763  "&& reload_completed"
6764  [(set (match_dup 0) (const_int 0))
6765   (parallel
6766    [(set (match_dup 0) (minus:GPR (minus:GPR (match_dup 0) (match_dup 0))
6767                                   (match_dup 1)))
6768     (clobber (reg:CC CC_REGNUM))])
6769   (parallel
6770    [(set (match_dup 0) (neg:GPR (match_dup 0)))
6771     (clobber (reg:CC CC_REGNUM))])]
6772  "")
6773
6774
6775(define_expand "cstore<mode>4"
6776  [(set (match_operand:SI 0 "register_operand" "")
6777        (match_operator:SI 1 "s390_scond_operator"
6778  	 [(match_operand:GPR 2 "register_operand" "")
6779          (match_operand:GPR 3 "general_operand" "")]))]
6780  ""
6781  "if (!s390_expand_addcc (GET_CODE (operands[1]), operands[2], operands[3],
6782			   operands[0], const0_rtx, const1_rtx)) FAIL; DONE;")
6783
6784(define_expand "cstorecc4"
6785  [(parallel
6786    [(set (match_operand:SI 0 "register_operand" "")
6787	  (match_operator:SI 1 "s390_eqne_operator"
6788           [(match_operand 2 "cc_reg_operand")
6789	    (match_operand 3 "const0_operand")]))
6790     (clobber (reg:CC CC_REGNUM))])]
6791  ""
6792  "machine_mode mode = GET_MODE (operands[2]);
6793   if (TARGET_Z196)
6794     {
6795       rtx cond, ite;
6796
6797       if (GET_CODE (operands[1]) == NE)
6798	 cond = gen_rtx_NE (VOIDmode, operands[2], const0_rtx);
6799       else
6800	 cond = gen_rtx_EQ (VOIDmode, operands[2], const0_rtx);
6801       ite = gen_rtx_IF_THEN_ELSE (SImode, cond, const1_rtx, const0_rtx);
6802       emit_insn (gen_rtx_SET (operands[0], ite));
6803     }
6804   else
6805     {
6806       if (mode != CCZ1mode)
6807	 FAIL;
6808       emit_insn (gen_sne (operands[0], operands[2]));
6809       if (GET_CODE (operands[1]) == EQ)
6810	 emit_insn (gen_xorsi3 (operands[0], operands[0], const1_rtx));
6811     }
6812   DONE;")
6813
6814(define_insn_and_split "sne"
6815  [(set (match_operand:SI 0 "register_operand" "=d")
6816	(ne:SI (match_operand:CCZ1 1 "register_operand" "0")
6817	       (const_int 0)))
6818   (clobber (reg:CC CC_REGNUM))]
6819  ""
6820  "#"
6821  "reload_completed"
6822  [(parallel
6823    [(set (match_dup 0) (ashiftrt:SI (match_dup 0) (const_int 28)))
6824     (clobber (reg:CC CC_REGNUM))])])
6825
6826; Such patterns get directly emitted by noce_emit_store_flag.
6827(define_insn_and_split "*cstorecc<mode>_z13"
6828  [(set (match_operand:GPR  0 "register_operand"                "=&d")
6829	(match_operator:GPR 1 "s390_comparison"
6830			    [(match_operand 2 "cc_reg_operand"    "c")
6831			     (match_operand 3 "const_int_operand"  "")]))]
6832  "TARGET_Z13"
6833  "#"
6834  "reload_completed"
6835  [(set (match_dup 0) (const_int 0))
6836   (set (match_dup 0)
6837	(if_then_else:GPR
6838	 (match_op_dup 1 [(match_dup 2) (match_dup 3)])
6839	 (const_int 1)
6840	 (match_dup 0)))])
6841
6842;;
6843;; - Conditional move instructions (introduced with z196)
6844;;
6845
6846(define_expand "mov<mode>cc"
6847  [(set (match_operand:GPR 0 "nonimmediate_operand" "")
6848	(if_then_else:GPR (match_operand 1 "comparison_operator" "")
6849			  (match_operand:GPR 2 "loc_operand" "")
6850			  (match_operand:GPR 3 "loc_operand" "")))]
6851  "TARGET_Z196"
6852{
6853  if (!TARGET_Z13 && CONSTANT_P (operands[2]))
6854    operands[2] = force_reg (<MODE>mode, operands[2]);
6855
6856  if (!TARGET_Z13 && CONSTANT_P (operands[3]))
6857    operands[3] = force_reg (<MODE>mode, operands[3]);
6858
6859  /* Emit the comparison insn in case we do not already have a comparison result.  */
6860  if (!s390_comparison (operands[1], VOIDmode))
6861    operands[1] = s390_emit_compare (GET_CODE (operands[1]),
6862				     XEXP (operands[1], 0),
6863				     XEXP (operands[1], 1));
6864})
6865
6866;;
6867;; - We do not have instructions for QImode or HImode but still
6868;;   enable load on condition/if conversion for them.
6869(define_expand "mov<mode>cc"
6870 [(set (match_operand:HQI 0 "nonimmediate_operand" "")
6871	(if_then_else:HQI (match_operand 1 "comparison_operator" "")
6872		(match_operand:HQI 2 "loc_operand" "")
6873		(match_operand:HQI 3 "loc_operand" "")))]
6874 "TARGET_Z196"
6875{
6876  /* Emit the comparison insn in case we do not already have a comparison
6877     result. */
6878  if (!s390_comparison (operands[1], VOIDmode))
6879    operands[1] = s390_emit_compare (GET_CODE (operands[1]),
6880			      XEXP (operands[1], 0),
6881			      XEXP (operands[1], 1));
6882
6883  rtx then = operands[2];
6884  rtx els = operands[3];
6885
6886  if ((!TARGET_Z13 && CONSTANT_P (then)) || MEM_P (then))
6887	then = force_reg (<MODE>mode, then);
6888  if ((!TARGET_Z13 && CONSTANT_P (els)) || MEM_P (els))
6889	els = force_reg (<MODE>mode, els);
6890
6891  if (!CONSTANT_P (then))
6892    then = simplify_gen_subreg (E_SImode, then, <MODE>mode, 0);
6893  if (!CONSTANT_P (els))
6894    els = simplify_gen_subreg (E_SImode, els, <MODE>mode, 0);
6895
6896  rtx tmp_target = gen_reg_rtx (E_SImode);
6897  emit_insn (gen_movsicc (tmp_target, operands[1], then, els));
6898  emit_move_insn (operands[0], gen_lowpart (<MODE>mode, tmp_target));
6899  DONE;
6900})
6901
6902
6903
6904; locr, loc, stoc, locgr, locg, stocg, lochi, locghi, selr, selgr
6905(define_insn "*mov<mode>cc"
6906  [(set (match_operand:GPR 0 "nonimmediate_operand" "=d,d,d,d,d,d,d,S,S")
6907	(if_then_else:GPR
6908	  (match_operator 1 "s390_comparison"
6909	    [(match_operand 2 "cc_reg_operand"      " c,c,c,c,c,c,c,c,c")
6910	     (match_operand 5 "const_int_operand"   "")])
6911	  (match_operand:GPR 3 "loc_operand"        " d,0,d,S,0,K,0,d,0")
6912	  (match_operand:GPR 4 "loc_operand"        " 0,d,d,0,S,0,K,0,d")))]
6913  "TARGET_Z196"
6914  "@
6915   loc<g>r%C1\t%0,%3
6916   loc<g>r%D1\t%0,%4
6917   sel<g>r%C1\t%0,%3,%4
6918   loc<g>%C1\t%0,%3
6919   loc<g>%D1\t%0,%4
6920   loc<g>hi%C1\t%0,%h3
6921   loc<g>hi%D1\t%0,%h4
6922   stoc<g>%C1\t%3,%0
6923   stoc<g>%D1\t%4,%0"
6924  [(set_attr "op_type" "RRF,RRF,RRF,RSY,RSY,RIE,RIE,RSY,RSY")
6925   (set_attr "cpu_facility" "*,*,z15,*,*,z13,z13,*,*")])
6926
6927;;
6928;;- Multiply instructions.
6929;;
6930
6931;
6932; muldi3 instruction pattern(s).
6933;
6934
6935(define_expand "muldi3"
6936  [(parallel
6937    [(set (match_operand:DI          0 "register_operand")
6938	  (mult:DI (match_operand:DI 1 "nonimmediate_operand")
6939		   (match_operand:DI 2 "general_operand")))
6940     (clobber (reg:CC CC_REGNUM))])]
6941  "TARGET_ZARCH")
6942
6943(define_insn "*muldi3_sign"
6944  [(set (match_operand:DI 0 "register_operand" "=d,d")
6945        (mult:DI (sign_extend:DI (match_operand:SI 2 "general_operand" "d,T"))
6946                 (match_operand:DI 1 "register_operand" "0,0")))]
6947  "TARGET_ZARCH"
6948  "@
6949   msgfr\t%0,%2
6950   msgf\t%0,%2"
6951  [(set_attr "op_type"      "RRE,RXY")
6952   (set_attr "type"         "imuldi")])
6953
6954(define_insn "*muldi3"
6955  [(set (match_operand:DI          0 "register_operand"     "=d,d,d,d,d")
6956	(mult:DI (match_operand:DI 1 "nonimmediate_operand" "%0,d,0,0,0")
6957		 (match_operand:DI 2 "general_operand"       "d,d,K,T,Os")))
6958   (clobber (match_scratch:CC      3                        "=X,c,X,X,X"))]
6959  "TARGET_ZARCH"
6960  "@
6961   msgr\t%0,%2
6962   msgrkc\t%0,%1,%2
6963   mghi\t%0,%h2
6964   msg\t%0,%2
6965   msgfi\t%0,%2"
6966  [(set_attr "op_type"      "RRE,RRF,RI,RXY,RIL")
6967   (set_attr "type"         "imuldi")
6968   (set_attr "cpu_facility" "*,z14,*,*,z10")])
6969
6970(define_insn "mulditi3"
6971  [(set (match_operand:TI 0 "register_operand"               "=d,d")
6972        (mult:TI (sign_extend:TI
6973		  (match_operand:DI 1 "register_operand"     "%d,0"))
6974		 (sign_extend:TI
6975		  (match_operand:DI 2 "nonimmediate_operand" " d,T"))))]
6976  "TARGET_Z14"
6977  "@
6978   mgrk\t%0,%1,%2
6979   mg\t%0,%2"
6980  [(set_attr "op_type"  "RRF,RXY")])
6981
6982; Combine likes op1 and op2 to be swapped sometimes.
6983(define_insn "mulditi3_2"
6984  [(set (match_operand:TI 0 "register_operand"               "=d,d")
6985        (mult:TI (sign_extend:TI
6986		  (match_operand:DI 1 "nonimmediate_operand" "%d,T"))
6987		 (sign_extend:TI
6988		  (match_operand:DI 2 "register_operand"     " d,0"))))]
6989  "TARGET_Z14"
6990  "@
6991   mgrk\t%0,%1,%2
6992   mg\t%0,%1"
6993  [(set_attr "op_type"  "RRF,RXY")])
6994
6995(define_insn "*muldi3_sign"
6996  [(set (match_operand:DI                          0 "register_operand" "=d")
6997        (mult:DI (sign_extend:DI (match_operand:HI 2 "memory_operand"    "T"))
6998                 (match_operand:DI                 1 "register_operand"  "0")))]
6999  "TARGET_Z14"
7000  "mgh\t%0,%2"
7001  [(set_attr "op_type" "RXY")])
7002
7003
7004;
7005; mulsi3 instruction pattern(s).
7006;
7007
7008(define_expand "mulsi3"
7009  [(parallel
7010    [(set (match_operand:SI           0 "register_operand"     "=d,d,d,d,d,d")
7011	  (mult:SI  (match_operand:SI 1 "nonimmediate_operand" "%0,d,0,0,0,0")
7012		    (match_operand:SI 2 "general_operand"       "d,d,K,R,T,Os")))
7013     (clobber (reg:CC CC_REGNUM))])]
7014  "")
7015
7016(define_insn "*mulsi3_sign"
7017  [(set (match_operand:SI 0 "register_operand" "=d,d")
7018        (mult:SI (sign_extend:SI (match_operand:HI 2 "memory_operand" "R,T"))
7019                 (match_operand:SI 1 "register_operand" "0,0")))]
7020  ""
7021  "@
7022   mh\t%0,%2
7023   mhy\t%0,%2"
7024  [(set_attr "op_type"      "RX,RXY")
7025   (set_attr "type"         "imulhi")
7026   (set_attr "cpu_facility" "*,z10")])
7027
7028(define_insn "*mulsi3"
7029  [(set (match_operand:SI           0 "register_operand"     "=d,d,d,d,d,d")
7030        (mult:SI  (match_operand:SI 1 "nonimmediate_operand" "%0,d,0,0,0,0")
7031                  (match_operand:SI 2 "general_operand"       "d,d,K,R,T,Os")))
7032   (clobber (match_scratch:CC       3                        "=X,c,X,X,X,X"))]
7033  ""
7034  "@
7035   msr\t%0,%2
7036   msrkc\t%0,%1,%2
7037   mhi\t%0,%h2
7038   ms\t%0,%2
7039   msy\t%0,%2
7040   msfi\t%0,%2"
7041  [(set_attr "op_type"      "RRE,RRF,RI,RX,RXY,RIL")
7042   (set_attr "type"         "imulsi,*,imulhi,imulsi,imulsi,imulsi")
7043   (set_attr "cpu_facility" "*,z14,*,*,longdisp,z10")])
7044
7045;
7046; mulsidi3 instruction pattern(s).
7047;
7048
7049(define_insn "mulsidi3"
7050  [(set (match_operand:DI 0 "register_operand" "=d,d,d")
7051        (mult:DI (sign_extend:DI
7052	           (match_operand:SI 1 "register_operand" "%0,0,0"))
7053                 (sign_extend:DI
7054	           (match_operand:SI 2 "nonimmediate_operand" "d,R,T"))))]
7055  "!TARGET_ZARCH"
7056  "@
7057   mr\t%0,%2
7058   m\t%0,%2
7059   mfy\t%0,%2"
7060  [(set_attr "op_type"      "RR,RX,RXY")
7061   (set_attr "type"         "imulsi")
7062   (set_attr "cpu_facility" "*,*,z10")])
7063
7064; Jump to label OP3 if OP1 * OP2 results in a signed overflow
7065(define_expand "mulv<mode>4"
7066  [(parallel
7067    [(set (reg:CCO CC_REGNUM)
7068	  (compare:CCO (mult:<DBL>
7069			 (sign_extend:<DBL> (match_operand:GPR 1 "register_operand"))
7070			 (sign_extend:<DBL> (match_operand:GPR 2 "nonimmediate_operand")))
7071			(sign_extend:<DBL> (mult:GPR (match_dup 1) (match_dup 2)))))
7072     (set (match_operand:GPR 0 "register_operand")
7073          (mult:GPR (match_dup 1) (match_dup 2)))])
7074   (set (pc)
7075        (if_then_else (ne (reg:CCO CC_REGNUM) (const_int 0))
7076		      (label_ref (match_operand 3))
7077                      (pc)))]
7078  "TARGET_Z14")
7079
7080; msrkc, msc, msgrkc, msgc
7081(define_insn "*mulv<mode>3_ccoverflow"
7082  [(set (reg CC_REGNUM)
7083	(compare (mult:<DBL>
7084		  (sign_extend:<DBL> (match_operand:GPR 1 "register_operand"     "%d,0"))
7085		  (sign_extend:<DBL> (match_operand:GPR 2 "nonimmediate_operand" " d,T")))
7086		 (sign_extend:<DBL> (mult:GPR (match_dup 1) (match_dup 2)))))
7087   (set (match_operand:GPR                              0 "register_operand"     "=d,d")
7088        (mult:GPR (match_dup 1) (match_dup 2)))]
7089  "s390_match_ccmode (insn, CCOmode) && TARGET_Z14"
7090  "@
7091   ms<g>rkc\t%0,%1,%2
7092   ms<g>c\t%0,%2"
7093  [(set_attr "op_type"  "RRF,RXY")])
7094
7095
7096;
7097; umul instruction pattern(s).
7098;
7099
7100; mlr, ml, mlgr, mlg
7101(define_insn "umul<dwh><mode>3"
7102  [(set (match_operand:DW 0 "register_operand"                   "=d,d")
7103        (mult:DW (zero_extend:DW
7104	           (match_operand:<DWH> 1 "register_operand"     "%0,0"))
7105                 (zero_extend:DW
7106	           (match_operand:<DWH> 2 "nonimmediate_operand" " d,T"))))]
7107  ""
7108  "@
7109   ml<tg>r\t%0,%2
7110   ml<tg>\t%0,%2"
7111  [(set_attr "op_type"  "RRE,RXY")
7112   (set_attr "type"     "imul<dwh>")])
7113
7114;
7115; mul(tf|df|sf|td|dd)3 instruction pattern(s).
7116;
7117
7118; mxbr, mdbr, meebr, mxb, mxb, meeb, mdtr, mxtr
7119(define_insn "mul<mode>3"
7120  [(set (match_operand:FP          0 "register_operand"     "=f,f,f,v,v")
7121        (mult:FP (match_operand:FP 1 "nonimmediate_operand" "%f,0,0,v,v")
7122		 (match_operand:FP 2 "general_operand"       "f,f,R,v,v")))]
7123  "TARGET_HARD_FLOAT"
7124  "@
7125   m<xdee>tr\t%0,%1,%2
7126   m<xdee>br\t%0,%2
7127   m<xdee>b\t%0,%2
7128   wfmdb\t%v0,%v1,%v2
7129   wfmsb\t%v0,%v1,%v2"
7130  [(set_attr "op_type"      "RRF,RRE,RXE,VRR,VRR")
7131   (set_attr "type"         "fmul<mode>")
7132   (set_attr "cpu_facility" "*,*,*,vx,vxe")
7133   (set_attr "enabled"      "<nBFP>,<nDFP>,<DSF>,<DF>,<SF>")])
7134
7135; madbr, maebr, maxb, madb, maeb
7136(define_insn "fma<mode>4"
7137  [(set (match_operand:DSF          0 "register_operand"     "=f,f,v,v")
7138	(fma:DSF (match_operand:DSF 1 "nonimmediate_operand" "%f,f,v,v")
7139		 (match_operand:DSF 2 "nonimmediate_operand"  "f,R,v,v")
7140		 (match_operand:DSF 3 "register_operand"      "0,0,v,v")))]
7141  "TARGET_HARD_FLOAT"
7142  "@
7143   ma<xde>br\t%0,%1,%2
7144   ma<xde>b\t%0,%1,%2
7145   wfmadb\t%v0,%v1,%v2,%v3
7146   wfmasb\t%v0,%v1,%v2,%v3"
7147  [(set_attr "op_type"      "RRE,RXE,VRR,VRR")
7148   (set_attr "type"         "fmadd<mode>")
7149   (set_attr "cpu_facility" "*,*,vx,vxe")
7150   (set_attr "enabled"      "*,*,<DF>,<SF>")])
7151
7152; msxbr, msdbr, msebr, msxb, msdb, mseb
7153(define_insn "fms<mode>4"
7154  [(set (match_operand:DSF                   0 "register_operand"     "=f,f,v,v")
7155	(fma:DSF (match_operand:DSF          1 "nonimmediate_operand" "%f,f,v,v")
7156		 (match_operand:DSF          2 "nonimmediate_operand"  "f,R,v,v")
7157		 (neg:DSF (match_operand:DSF 3 "register_operand"      "0,0,v,v"))))]
7158  "TARGET_HARD_FLOAT"
7159  "@
7160   ms<xde>br\t%0,%1,%2
7161   ms<xde>b\t%0,%1,%2
7162   wfmsdb\t%v0,%v1,%v2,%v3
7163   wfmssb\t%v0,%v1,%v2,%v3"
7164  [(set_attr "op_type"      "RRE,RXE,VRR,VRR")
7165   (set_attr "type"         "fmadd<mode>")
7166   (set_attr "cpu_facility" "*,*,vx,vxe")
7167   (set_attr "enabled"      "*,*,<DF>,<SF>")])
7168
7169;;
7170;;- Divide and modulo instructions.
7171;;
7172
7173;
7174; divmoddi4 instruction pattern(s).
7175;
7176
7177(define_expand "divmoddi4"
7178  [(parallel [(set (match_operand:DI 0 "general_operand" "")
7179		   (div:DI (match_operand:DI 1 "register_operand" "")
7180			   (match_operand:DI 2 "general_operand" "")))
7181	      (set (match_operand:DI 3 "general_operand" "")
7182		   (mod:DI (match_dup 1) (match_dup 2)))])
7183   (clobber (match_dup 4))]
7184  "TARGET_ZARCH"
7185{
7186  rtx div_equal, mod_equal;
7187  rtx_insn *insn;
7188
7189  div_equal = gen_rtx_DIV (DImode, operands[1], operands[2]);
7190  mod_equal = gen_rtx_MOD (DImode, operands[1], operands[2]);
7191
7192  operands[4] = gen_reg_rtx(TImode);
7193  emit_insn (gen_divmodtidi3 (operands[4], operands[1], operands[2]));
7194
7195  insn = emit_move_insn (operands[0], gen_lowpart (DImode, operands[4]));
7196  set_unique_reg_note (insn, REG_EQUAL, div_equal);
7197
7198  insn = emit_move_insn (operands[3], gen_highpart (DImode, operands[4]));
7199  set_unique_reg_note (insn, REG_EQUAL, mod_equal);
7200
7201  DONE;
7202})
7203
7204(define_insn "divmodtidi3"
7205  [(set (match_operand:TI 0 "register_operand" "=d,d")
7206        (ior:TI
7207          (ashift:TI
7208            (zero_extend:TI
7209              (mod:DI (match_operand:DI 1 "register_operand" "0,0")
7210                      (match_operand:DI 2 "general_operand" "d,T")))
7211            (const_int 64))
7212          (zero_extend:TI (div:DI (match_dup 1) (match_dup 2)))))]
7213  "TARGET_ZARCH"
7214  "@
7215   dsgr\t%0,%2
7216   dsg\t%0,%2"
7217  [(set_attr "op_type"  "RRE,RXY")
7218   (set_attr "type"     "idiv")])
7219
7220(define_insn "divmodtisi3"
7221  [(set (match_operand:TI 0 "register_operand" "=d,d")
7222        (ior:TI
7223          (ashift:TI
7224            (zero_extend:TI
7225              (mod:DI (match_operand:DI 1 "register_operand" "0,0")
7226                      (sign_extend:DI
7227                        (match_operand:SI 2 "nonimmediate_operand" "d,T"))))
7228            (const_int 64))
7229          (zero_extend:TI
7230            (div:DI (match_dup 1) (sign_extend:DI (match_dup 2))))))]
7231  "TARGET_ZARCH"
7232  "@
7233   dsgfr\t%0,%2
7234   dsgf\t%0,%2"
7235  [(set_attr "op_type"  "RRE,RXY")
7236   (set_attr "type"     "idiv")])
7237
7238;
7239; udivmoddi4 instruction pattern(s).
7240;
7241
7242(define_expand "udivmoddi4"
7243  [(parallel [(set (match_operand:DI 0 "general_operand" "")
7244		   (udiv:DI (match_operand:DI 1 "general_operand" "")
7245			    (match_operand:DI 2 "nonimmediate_operand" "")))
7246	      (set (match_operand:DI 3 "general_operand" "")
7247		   (umod:DI (match_dup 1) (match_dup 2)))])
7248   (clobber (match_dup 4))]
7249  "TARGET_ZARCH"
7250{
7251  rtx div_equal, mod_equal, equal;
7252  rtx_insn *insn;
7253
7254  div_equal = gen_rtx_UDIV (DImode, operands[1], operands[2]);
7255  mod_equal = gen_rtx_UMOD (DImode, operands[1], operands[2]);
7256  equal = gen_rtx_IOR (TImode,
7257		       gen_rtx_ASHIFT (TImode,
7258				       gen_rtx_ZERO_EXTEND (TImode, mod_equal),
7259				       GEN_INT (64)),
7260		       gen_rtx_ZERO_EXTEND (TImode, div_equal));
7261
7262  operands[4] = gen_reg_rtx(TImode);
7263  emit_clobber (operands[4]);
7264  emit_move_insn (gen_lowpart (DImode, operands[4]), operands[1]);
7265  emit_move_insn (gen_highpart (DImode, operands[4]), const0_rtx);
7266
7267  insn = emit_insn (gen_udivmodtidi3 (operands[4], operands[4], operands[2]));
7268  set_unique_reg_note (insn, REG_EQUAL, equal);
7269
7270  insn = emit_move_insn (operands[0], gen_lowpart (DImode, operands[4]));
7271  set_unique_reg_note (insn, REG_EQUAL, div_equal);
7272
7273  insn = emit_move_insn (operands[3], gen_highpart (DImode, operands[4]));
7274  set_unique_reg_note (insn, REG_EQUAL, mod_equal);
7275
7276  DONE;
7277})
7278
7279(define_insn "udivmodtidi3"
7280  [(set (match_operand:TI 0 "register_operand" "=d,d")
7281        (ior:TI
7282          (ashift:TI
7283            (zero_extend:TI
7284              (truncate:DI
7285                (umod:TI (match_operand:TI 1 "register_operand" "0,0")
7286                         (zero_extend:TI
7287                           (match_operand:DI 2 "nonimmediate_operand" "d,T")))))
7288            (const_int 64))
7289          (zero_extend:TI
7290            (truncate:DI
7291              (udiv:TI (match_dup 1) (zero_extend:TI (match_dup 2)))))))]
7292  "TARGET_ZARCH"
7293  "@
7294   dlgr\t%0,%2
7295   dlg\t%0,%2"
7296  [(set_attr "op_type"  "RRE,RXY")
7297   (set_attr "type"     "idiv")])
7298
7299;
7300; divmodsi4 instruction pattern(s).
7301;
7302
7303(define_expand "divmodsi4"
7304  [(parallel [(set (match_operand:SI 0 "general_operand" "")
7305		   (div:SI (match_operand:SI 1 "general_operand" "")
7306			   (match_operand:SI 2 "nonimmediate_operand" "")))
7307	      (set (match_operand:SI 3 "general_operand" "")
7308		   (mod:SI (match_dup 1) (match_dup 2)))])
7309   (clobber (match_dup 4))]
7310  "!TARGET_ZARCH"
7311{
7312  rtx div_equal, mod_equal, equal;
7313  rtx_insn *insn;
7314
7315  div_equal = gen_rtx_DIV (SImode, operands[1], operands[2]);
7316  mod_equal = gen_rtx_MOD (SImode, operands[1], operands[2]);
7317  equal = gen_rtx_IOR (DImode,
7318		       gen_rtx_ASHIFT (DImode,
7319				       gen_rtx_ZERO_EXTEND (DImode, mod_equal),
7320				       GEN_INT (32)),
7321		       gen_rtx_ZERO_EXTEND (DImode, div_equal));
7322
7323  operands[4] = gen_reg_rtx(DImode);
7324  emit_insn (gen_extendsidi2 (operands[4], operands[1]));
7325
7326  insn = emit_insn (gen_divmoddisi3 (operands[4], operands[4], operands[2]));
7327  set_unique_reg_note (insn, REG_EQUAL, equal);
7328
7329  insn = emit_move_insn (operands[0], gen_lowpart (SImode, operands[4]));
7330  set_unique_reg_note (insn, REG_EQUAL, div_equal);
7331
7332  insn = emit_move_insn (operands[3], gen_highpart (SImode, operands[4]));
7333  set_unique_reg_note (insn, REG_EQUAL, mod_equal);
7334
7335  DONE;
7336})
7337
7338(define_insn "divmoddisi3"
7339  [(set (match_operand:DI 0 "register_operand" "=d,d")
7340        (ior:DI
7341          (ashift:DI
7342            (zero_extend:DI
7343              (truncate:SI
7344                (mod:DI (match_operand:DI 1 "register_operand" "0,0")
7345                        (sign_extend:DI
7346                          (match_operand:SI 2 "nonimmediate_operand" "d,R")))))
7347            (const_int 32))
7348          (zero_extend:DI
7349            (truncate:SI
7350              (div:DI (match_dup 1) (sign_extend:DI (match_dup 2)))))))]
7351  "!TARGET_ZARCH"
7352  "@
7353   dr\t%0,%2
7354   d\t%0,%2"
7355  [(set_attr "op_type"  "RR,RX")
7356   (set_attr "type"     "idiv")])
7357
7358;
7359; udivsi3 and umodsi3 instruction pattern(s).
7360;
7361
7362(define_expand "udivmodsi4"
7363  [(parallel [(set (match_operand:SI 0 "general_operand" "")
7364		   (udiv:SI (match_operand:SI 1 "general_operand" "")
7365			    (match_operand:SI 2 "nonimmediate_operand" "")))
7366	      (set (match_operand:SI 3 "general_operand" "")
7367		   (umod:SI (match_dup 1) (match_dup 2)))])
7368   (clobber (match_dup 4))]
7369  "!TARGET_ZARCH"
7370{
7371  rtx div_equal, mod_equal, equal;
7372  rtx_insn *insn;
7373
7374  div_equal = gen_rtx_UDIV (SImode, operands[1], operands[2]);
7375  mod_equal = gen_rtx_UMOD (SImode, operands[1], operands[2]);
7376  equal = gen_rtx_IOR (DImode,
7377		       gen_rtx_ASHIFT (DImode,
7378				       gen_rtx_ZERO_EXTEND (DImode, mod_equal),
7379				       GEN_INT (32)),
7380		       gen_rtx_ZERO_EXTEND (DImode, div_equal));
7381
7382  operands[4] = gen_reg_rtx(DImode);
7383  emit_clobber (operands[4]);
7384  emit_move_insn (gen_lowpart (SImode, operands[4]), operands[1]);
7385  emit_move_insn (gen_highpart (SImode, operands[4]), const0_rtx);
7386
7387  insn = emit_insn (gen_udivmoddisi3 (operands[4], operands[4], operands[2]));
7388  set_unique_reg_note (insn, REG_EQUAL, equal);
7389
7390  insn = emit_move_insn (operands[0], gen_lowpart (SImode, operands[4]));
7391  set_unique_reg_note (insn, REG_EQUAL, div_equal);
7392
7393  insn = emit_move_insn (operands[3], gen_highpart (SImode, operands[4]));
7394  set_unique_reg_note (insn, REG_EQUAL, mod_equal);
7395
7396  DONE;
7397})
7398
7399(define_insn "udivmoddisi3"
7400  [(set (match_operand:DI 0 "register_operand" "=d,d")
7401        (ior:DI
7402          (ashift:DI
7403            (zero_extend:DI
7404              (truncate:SI
7405                (umod:DI (match_operand:DI 1 "register_operand" "0,0")
7406                         (zero_extend:DI
7407                           (match_operand:SI 2 "nonimmediate_operand" "d,T")))))
7408            (const_int 32))
7409          (zero_extend:DI
7410            (truncate:SI
7411              (udiv:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))))]
7412  "!TARGET_ZARCH"
7413  "@
7414   dlr\t%0,%2
7415   dl\t%0,%2"
7416  [(set_attr "op_type"  "RRE,RXY")
7417   (set_attr "type"     "idiv")])
7418
7419;
7420; div(df|sf)3 instruction pattern(s).
7421;
7422
7423; dxbr, ddbr, debr, dxb, ddb, deb, ddtr, dxtr
7424(define_insn "div<mode>3"
7425  [(set (match_operand:FP         0 "register_operand" "=f,f,f,v,v")
7426        (div:FP (match_operand:FP 1 "register_operand"  "f,0,0,v,v")
7427		(match_operand:FP 2 "general_operand"   "f,f,R,v,v")))]
7428  "TARGET_HARD_FLOAT"
7429  "@
7430   d<xde>tr\t%0,%1,%2
7431   d<xde>br\t%0,%2
7432   d<xde>b\t%0,%2
7433   wfddb\t%v0,%v1,%v2
7434   wfdsb\t%v0,%v1,%v2"
7435  [(set_attr "op_type"      "RRF,RRE,RXE,VRR,VRR")
7436   (set_attr "type"         "fdiv<mode>")
7437   (set_attr "cpu_facility" "*,*,*,vx,vxe")
7438   (set_attr "enabled"      "<nBFP>,<nDFP>,<DSF>,<DF>,<SF>")])
7439
7440
7441;;
7442;;- And instructions.
7443;;
7444
7445(define_expand "and<mode>3"
7446  [(set (match_operand:INT 0 "nonimmediate_operand" "")
7447        (and:INT (match_operand:INT 1 "nonimmediate_operand" "")
7448                 (match_operand:INT 2 "general_operand" "")))
7449   (clobber (reg:CC CC_REGNUM))]
7450  ""
7451  "s390_expand_logical_operator (AND, <MODE>mode, operands); DONE;")
7452
7453;
7454; anddi3 instruction pattern(s).
7455;
7456
7457(define_insn "*anddi3_cc"
7458  [(set (reg CC_REGNUM)
7459        (compare
7460	  (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,d,0,    d")
7461                  (match_operand:DI 2 "general_operand"      " d,d,T,NxxDw"))
7462          (const_int 0)))
7463   (set (match_operand:DI 0 "register_operand"               "=d,d,d,    d")
7464        (and:DI (match_dup 1) (match_dup 2)))]
7465  "TARGET_ZARCH && s390_match_ccmode(insn, CCTmode)"
7466  "@
7467   ngr\t%0,%2
7468   ngrk\t%0,%1,%2
7469   ng\t%0,%2
7470   risbg\t%0,%1,%s2,128+%e2,0"
7471  [(set_attr "op_type"  "RRE,RRF,RXY,RIE")
7472   (set_attr "cpu_facility" "*,z196,*,z10")
7473   (set_attr "z10prop" "z10_super_E1,*,z10_super_E1,z10_super_E1")])
7474
7475(define_insn "*anddi3_cconly"
7476  [(set (reg CC_REGNUM)
7477        (compare
7478	  (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,d,0,    d")
7479                  (match_operand:DI 2 "general_operand"      " d,d,T,NxxDw"))
7480                 (const_int 0)))
7481   (clobber (match_scratch:DI 0                              "=d,d,d,    d"))]
7482  "TARGET_ZARCH
7483   && s390_match_ccmode(insn, CCTmode)
7484   /* Do not steal TM patterns.  */
7485   && s390_single_part (operands[2], DImode, HImode, 0) < 0"
7486  "@
7487   ngr\t%0,%2
7488   ngrk\t%0,%1,%2
7489   ng\t%0,%2
7490   risbg\t%0,%1,%s2,128+%e2,0"
7491  [(set_attr "op_type"  "RRE,RRF,RXY,RIE")
7492   (set_attr "cpu_facility" "*,z196,*,z10")
7493   (set_attr "z10prop" "z10_super_E1,*,z10_super_E1,z10_super_E1")])
7494
7495(define_insn "*anddi3"
7496  [(set (match_operand:DI 0 "nonimmediate_operand"
7497            "=d,d,    d,    d,    d,    d,    d,    d,d,d,d,    d,   AQ,Q")
7498        (and:DI
7499	  (match_operand:DI 1 "nonimmediate_operand"
7500            "%d,o,    0,    0,    0,    0,    0,    0,0,d,0,    d,    0,0")
7501          (match_operand:DI 2 "general_operand"
7502            "M, M,N0HDF,N1HDF,N2HDF,N3HDF,N0SDF,N1SDF,d,d,T,NxxDw,NxQDF,Q")))
7503   (clobber (reg:CC CC_REGNUM))]
7504  "TARGET_ZARCH && s390_logical_operator_ok_p (operands)"
7505  "@
7506   #
7507   #
7508   nihh\t%0,%j2
7509   nihl\t%0,%j2
7510   nilh\t%0,%j2
7511   nill\t%0,%j2
7512   nihf\t%0,%m2
7513   nilf\t%0,%m2
7514   ngr\t%0,%2
7515   ngrk\t%0,%1,%2
7516   ng\t%0,%2
7517   risbg\t%0,%1,%s2,128+%e2,0
7518   #
7519   #"
7520  [(set_attr "op_type" "RRE,RXE,RI,RI,RI,RI,RIL,RIL,RRE,RRF,RXY,RIE,SI,SS")
7521   (set_attr "cpu_facility" "*,*,*,*,*,*,extimm,extimm,*,z196,*,z10,*,*")
7522   (set_attr "z10prop" "*,
7523                        *,
7524                        z10_super_E1,
7525                        z10_super_E1,
7526                        z10_super_E1,
7527                        z10_super_E1,
7528                        z10_super_E1,
7529                        z10_super_E1,
7530                        z10_super_E1,
7531                        *,
7532                        z10_super_E1,
7533                        z10_super_E1,
7534                        *,
7535                        *")])
7536
7537(define_split
7538  [(set (match_operand:DI 0 "s_operand" "")
7539        (and:DI (match_dup 0) (match_operand:DI 1 "immediate_operand" "")))
7540   (clobber (reg:CC CC_REGNUM))]
7541  "reload_completed"
7542  [(parallel
7543    [(set (match_dup 0) (and:QI (match_dup 0) (match_dup 1)))
7544     (clobber (reg:CC CC_REGNUM))])]
7545  "s390_narrow_logical_operator (AND, &operands[0], &operands[1]);")
7546
7547;; These two are what combine generates for (ashift (zero_extract)).
7548(define_insn "*extzv_<mode>_srl<clobbercc_or_nocc>"
7549  [(set (match_operand:GPR 0 "register_operand" "=d")
7550	(and:GPR (lshiftrt:GPR
7551		   (match_operand:GPR 1 "register_operand" "d")
7552		   (match_operand:GPR 2 "nonzero_shift_count_operand" ""))
7553		(match_operand:GPR 3 "contiguous_bitmask_nowrap_operand" "")))]
7554  "<z10_or_zEC12_cond>
7555   /* Note that even for the SImode pattern, the rotate is always DImode.  */
7556   && s390_extzv_shift_ok (<bitsize>, -INTVAL (operands[2]),
7557			   INTVAL (operands[3]))"
7558  "<risbg_n>\t%0,%1,%<bfstart>3,128+%<bfend>3,64-%2"
7559  [(set_attr "op_type" "RIE")
7560   (set_attr "z10prop" "z10_super_E1")])
7561
7562(define_insn "*extzv_<mode>_sll<clobbercc_or_nocc>"
7563  [(set (match_operand:GPR 0 "register_operand" "=d")
7564	(and:GPR (ashift:GPR
7565		  (match_operand:GPR 1 "register_operand" "d")
7566		  (match_operand:GPR 2 "nonzero_shift_count_operand" ""))
7567		(match_operand:GPR 3 "contiguous_bitmask_nowrap_operand" "")))]
7568  "<z10_or_zEC12_cond>
7569   && s390_extzv_shift_ok (<bitsize>, INTVAL (operands[2]),
7570			   INTVAL (operands[3]))"
7571  "<risbg_n>\t%0,%1,%<bfstart>3,128+%<bfend>3,%2"
7572  [(set_attr "op_type" "RIE")
7573   (set_attr "z10prop" "z10_super_E1")])
7574
7575
7576;
7577; andsi3 instruction pattern(s).
7578;
7579
7580(define_insn "*andsi3_cc"
7581  [(set (reg CC_REGNUM)
7582        (compare
7583	  (and:SI
7584	    (match_operand:SI 1 "nonimmediate_operand" "%0,0,d,0,0,    d")
7585            (match_operand:SI 2 "general_operand"      "Os,d,d,R,T,NxxSq"))
7586          (const_int 0)))
7587   (set (match_operand:SI 0 "register_operand"         "=d,d,d,d,d,    d")
7588        (and:SI (match_dup 1) (match_dup 2)))]
7589  "s390_match_ccmode(insn, CCTmode)"
7590  "@
7591   nilf\t%0,%o2
7592   nr\t%0,%2
7593   nrk\t%0,%1,%2
7594   n\t%0,%2
7595   ny\t%0,%2
7596   risbg\t%0,%1,%t2,128+%f2,0"
7597  [(set_attr "op_type"  "RIL,RR,RRF,RX,RXY,RIE")
7598   (set_attr "cpu_facility" "*,*,z196,*,longdisp,z10")
7599   (set_attr "z10prop" "z10_super_E1,z10_super_E1,*,
7600			z10_super_E1,z10_super_E1,z10_super_E1")])
7601
7602(define_insn "*andsi3_cconly"
7603  [(set (reg CC_REGNUM)
7604        (compare
7605	  (and:SI
7606	    (match_operand:SI 1 "nonimmediate_operand" "%0,0,d,0,0,    d")
7607            (match_operand:SI 2 "general_operand"      "Os,d,d,R,T,NxxSq"))
7608          (const_int 0)))
7609   (clobber (match_scratch:SI 0                        "=d,d,d,d,d,    d"))]
7610  "s390_match_ccmode(insn, CCTmode)
7611   /* Do not steal TM patterns.  */
7612   && s390_single_part (operands[2], SImode, HImode, 0) < 0"
7613  "@
7614   nilf\t%0,%o2
7615   nr\t%0,%2
7616   nrk\t%0,%1,%2
7617   n\t%0,%2
7618   ny\t%0,%2
7619   risbg\t%0,%1,%t2,128+%f2,0"
7620  [(set_attr "op_type"  "RIL,RR,RRF,RX,RXY,RIE")
7621   (set_attr "cpu_facility" "*,*,z196,*,longdisp,z10")
7622   (set_attr "z10prop" "z10_super_E1,z10_super_E1,*,
7623                        z10_super_E1,z10_super_E1,z10_super_E1")])
7624
7625(define_insn "*andsi3_zarch"
7626  [(set (match_operand:SI 0 "nonimmediate_operand"
7627                            "=d,d,    d,    d, d,d,d,d,d,    d,   AQ,Q")
7628        (and:SI (match_operand:SI 1 "nonimmediate_operand"
7629			    "%d,o,    0,    0, 0,0,d,0,0,    d,    0,0")
7630                (match_operand:SI 2 "general_operand"
7631			    " M,M,N0HSF,N1HSF,Os,d,d,R,T,NxxSw,NxQSF,Q")))
7632   (clobber (reg:CC CC_REGNUM))]
7633  "TARGET_ZARCH && s390_logical_operator_ok_p (operands)"
7634  "@
7635   #
7636   #
7637   nilh\t%0,%j2
7638   nill\t%0,%j2
7639   nilf\t%0,%o2
7640   nr\t%0,%2
7641   nrk\t%0,%1,%2
7642   n\t%0,%2
7643   ny\t%0,%2
7644   risbg\t%0,%1,%t2,128+%f2,0
7645   #
7646   #"
7647  [(set_attr "op_type"  "RRE,RXE,RI,RI,RIL,RR,RRF,RX,RXY,RIE,SI,SS")
7648   (set_attr "cpu_facility" "*,*,*,*,*,*,z196,*,longdisp,z10,*,*")
7649   (set_attr "z10prop" "*,
7650                        *,
7651                        z10_super_E1,
7652                        z10_super_E1,
7653                        z10_super_E1,
7654                        z10_super_E1,
7655                        *,
7656                        z10_super_E1,
7657                        z10_super_E1,
7658                        z10_super_E1,
7659                        *,
7660                        *")])
7661
7662(define_insn "*andsi3_esa"
7663  [(set (match_operand:SI 0 "nonimmediate_operand"         "=d,d,   AQ,Q")
7664        (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,    0,0")
7665                (match_operand:SI 2 "general_operand"      " d,R,NxQSF,Q")))
7666   (clobber (reg:CC CC_REGNUM))]
7667  "!TARGET_ZARCH && s390_logical_operator_ok_p (operands)"
7668  "@
7669   nr\t%0,%2
7670   n\t%0,%2
7671   #
7672   #"
7673  [(set_attr "op_type"  "RR,RX,SI,SS")
7674   (set_attr "z10prop" "z10_super_E1,z10_super_E1,*,*")])
7675
7676
7677(define_split
7678  [(set (match_operand:SI 0 "s_operand" "")
7679        (and:SI (match_dup 0) (match_operand:SI 1 "immediate_operand" "")))
7680   (clobber (reg:CC CC_REGNUM))]
7681  "reload_completed"
7682  [(parallel
7683    [(set (match_dup 0) (and:QI (match_dup 0) (match_dup 1)))
7684     (clobber (reg:CC CC_REGNUM))])]
7685  "s390_narrow_logical_operator (AND, &operands[0], &operands[1]);")
7686
7687;
7688; andhi3 instruction pattern(s).
7689;
7690
7691(define_insn "*andhi3_zarch"
7692  [(set (match_operand:HI 0 "nonimmediate_operand"         "=d,d,d,   AQ,Q")
7693        (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,d,0,    0,0")
7694                (match_operand:HI 2 "general_operand"      " d,d,n,NxQHF,Q")))
7695   (clobber (reg:CC CC_REGNUM))]
7696  "TARGET_ZARCH && s390_logical_operator_ok_p (operands)"
7697  "@
7698   nr\t%0,%2
7699   nrk\t%0,%1,%2
7700   nill\t%0,%x2
7701   #
7702   #"
7703  [(set_attr "op_type"  "RR,RRF,RI,SI,SS")
7704   (set_attr "cpu_facility" "*,z196,*,*,*")
7705   (set_attr "z10prop" "z10_super_E1,*,z10_super_E1,*,*")
7706])
7707
7708(define_insn "*andhi3_esa"
7709  [(set (match_operand:HI 0 "nonimmediate_operand" "=d,AQ,Q")
7710        (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,0")
7711                (match_operand:HI 2 "general_operand" "d,NxQHF,Q")))
7712   (clobber (reg:CC CC_REGNUM))]
7713  "!TARGET_ZARCH && s390_logical_operator_ok_p (operands)"
7714  "@
7715   nr\t%0,%2
7716   #
7717   #"
7718  [(set_attr "op_type"  "RR,SI,SS")
7719   (set_attr "z10prop" "z10_super_E1,*,*")
7720])
7721
7722(define_split
7723  [(set (match_operand:HI 0 "s_operand" "")
7724        (and:HI (match_dup 0) (match_operand:HI 1 "immediate_operand" "")))
7725   (clobber (reg:CC CC_REGNUM))]
7726  "reload_completed"
7727  [(parallel
7728    [(set (match_dup 0) (and:QI (match_dup 0) (match_dup 1)))
7729     (clobber (reg:CC CC_REGNUM))])]
7730  "s390_narrow_logical_operator (AND, &operands[0], &operands[1]);")
7731
7732;
7733; andqi3 instruction pattern(s).
7734;
7735
7736(define_insn "*andqi3_zarch"
7737  [(set (match_operand:QI 0 "nonimmediate_operand"         "=d,d,d,Q,S,Q")
7738        (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,d,0,0,0,0")
7739                (match_operand:QI 2 "general_operand"      " d,d,n,n,n,Q")))
7740   (clobber (reg:CC CC_REGNUM))]
7741  "TARGET_ZARCH && s390_logical_operator_ok_p (operands)"
7742  "@
7743   nr\t%0,%2
7744   nrk\t%0,%1,%2
7745   nill\t%0,%b2
7746   ni\t%S0,%b2
7747   niy\t%S0,%b2
7748   #"
7749  [(set_attr "op_type"  "RR,RRF,RI,SI,SIY,SS")
7750   (set_attr "cpu_facility" "*,z196,*,*,longdisp,*")
7751   (set_attr "z10prop" "z10_super_E1,*,z10_super_E1,z10_super,z10_super,*")])
7752
7753(define_insn "*andqi3_esa"
7754  [(set (match_operand:QI 0 "nonimmediate_operand" "=d,Q,Q")
7755        (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
7756                (match_operand:QI 2 "general_operand" "d,n,Q")))
7757   (clobber (reg:CC CC_REGNUM))]
7758  "!TARGET_ZARCH && s390_logical_operator_ok_p (operands)"
7759  "@
7760   nr\t%0,%2
7761   ni\t%S0,%b2
7762   #"
7763  [(set_attr "op_type"  "RR,SI,SS")
7764   (set_attr "z10prop" "z10_super_E1,z10_super,*")])
7765
7766;
7767; And with complement
7768;
7769; c = ~b & a = (b & a) ^ a
7770
7771(define_insn_and_split "*andc_split_<mode>"
7772  [(set (match_operand:GPR 0 "nonimmediate_operand" "")
7773	(and:GPR (not:GPR (match_operand:GPR 1 "nonimmediate_operand" ""))
7774		 (match_operand:GPR 2 "general_operand" "")))
7775   (clobber (reg:CC CC_REGNUM))]
7776  "!TARGET_Z15
7777   && ! reload_completed
7778   && (GET_CODE (operands[0]) != MEM
7779      /* Ensure that s390_logical_operator_ok_p will succeed even
7780	 on the split xor if (b & a) is stored into a pseudo.  */
7781       || rtx_equal_p (operands[0], operands[2]))"
7782  "#"
7783  "&& 1"
7784  [
7785  (parallel
7786   [(set (match_dup 3) (and:GPR (match_dup 1) (match_dup 2)))
7787   (clobber (reg:CC CC_REGNUM))])
7788  (parallel
7789   [(set (match_dup 0) (xor:GPR (match_dup 3) (match_dup 2)))
7790   (clobber (reg:CC CC_REGNUM))])]
7791{
7792  if (reg_overlap_mentioned_p (operands[0], operands[2]))
7793    operands[3] = gen_reg_rtx (<MODE>mode);
7794  else
7795    operands[3] = operands[0];
7796})
7797
7798;
7799; Block and (NC) patterns.
7800;
7801
7802(define_insn "*nc"
7803  [(set (match_operand:BLK 0 "memory_operand" "=Q")
7804        (and:BLK (match_dup 0)
7805                 (match_operand:BLK 1 "memory_operand" "Q")))
7806   (use (match_operand 2 "const_int_operand" "n"))
7807   (clobber (reg:CC CC_REGNUM))]
7808  "INTVAL (operands[2]) >= 1 && INTVAL (operands[2]) <= 256"
7809  "nc\t%O0(%2,%R0),%S1"
7810  [(set_attr "op_type" "SS")
7811   (set_attr "z196prop" "z196_cracked")])
7812
7813(define_split
7814  [(set (match_operand 0 "memory_operand" "")
7815        (and (match_dup 0)
7816             (match_operand 1 "memory_operand" "")))
7817   (clobber (reg:CC CC_REGNUM))]
7818  "reload_completed
7819   && GET_MODE (operands[0]) == GET_MODE (operands[1])
7820   && GET_MODE_SIZE (GET_MODE (operands[0])) > 0"
7821  [(parallel
7822    [(set (match_dup 0) (and:BLK (match_dup 0) (match_dup 1)))
7823     (use (match_dup 2))
7824     (clobber (reg:CC CC_REGNUM))])]
7825{
7826  operands[2] = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[0])));
7827  operands[0] = adjust_address (operands[0], BLKmode, 0);
7828  operands[1] = adjust_address (operands[1], BLKmode, 0);
7829})
7830
7831(define_peephole2
7832  [(parallel
7833    [(set (match_operand:BLK 0 "memory_operand" "")
7834          (and:BLK (match_dup 0)
7835                   (match_operand:BLK 1 "memory_operand" "")))
7836     (use (match_operand 2 "const_int_operand" ""))
7837     (clobber (reg:CC CC_REGNUM))])
7838   (parallel
7839    [(set (match_operand:BLK 3 "memory_operand" "")
7840          (and:BLK (match_dup 3)
7841                   (match_operand:BLK 4 "memory_operand" "")))
7842     (use (match_operand 5 "const_int_operand" ""))
7843     (clobber (reg:CC CC_REGNUM))])]
7844  "s390_offset_p (operands[0], operands[3], operands[2])
7845   && s390_offset_p (operands[1], operands[4], operands[2])
7846   && !s390_overlap_p (operands[0], operands[1],
7847                       INTVAL (operands[2]) + INTVAL (operands[5]))
7848   && INTVAL (operands[2]) + INTVAL (operands[5]) <= 256"
7849  [(parallel
7850    [(set (match_dup 6) (and:BLK (match_dup 6) (match_dup 7)))
7851     (use (match_dup 8))
7852     (clobber (reg:CC CC_REGNUM))])]
7853  "operands[6] = gen_rtx_MEM (BLKmode, XEXP (operands[0], 0));
7854   operands[7] = gen_rtx_MEM (BLKmode, XEXP (operands[1], 0));
7855   operands[8] = GEN_INT (INTVAL (operands[2]) + INTVAL (operands[5]));")
7856
7857
7858;;
7859;;- Bit set (inclusive or) instructions.
7860;;
7861
7862(define_expand "ior<mode>3"
7863  [(set (match_operand:INT 0 "nonimmediate_operand" "")
7864        (ior:INT (match_operand:INT 1 "nonimmediate_operand" "")
7865                 (match_operand:INT 2 "general_operand" "")))
7866   (clobber (reg:CC CC_REGNUM))]
7867  ""
7868  "s390_expand_logical_operator (IOR, <MODE>mode, operands); DONE;")
7869
7870;
7871; iordi3 instruction pattern(s).
7872;
7873
7874(define_insn "*iordi3_cc"
7875  [(set (reg CC_REGNUM)
7876        (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,d,0")
7877                         (match_operand:DI 2 "general_operand"      " d,d,T"))
7878                 (const_int 0)))
7879   (set (match_operand:DI 0 "register_operand"                      "=d,d,d")
7880        (ior:DI (match_dup 1) (match_dup 2)))]
7881  "s390_match_ccmode(insn, CCTmode) && TARGET_ZARCH"
7882  "@
7883   ogr\t%0,%2
7884   ogrk\t%0,%1,%2
7885   og\t%0,%2"
7886  [(set_attr "op_type"  "RRE,RRF,RXY")
7887   (set_attr "cpu_facility" "*,z196,*")
7888   (set_attr "z10prop" "z10_super_E1,*,z10_super_E1")])
7889
7890(define_insn "*iordi3_cconly"
7891  [(set (reg CC_REGNUM)
7892        (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,d,0")
7893                         (match_operand:DI 2 "general_operand"      " d,d,T"))
7894                 (const_int 0)))
7895   (clobber (match_scratch:DI 0                                     "=d,d,d"))]
7896  "s390_match_ccmode(insn, CCTmode) && TARGET_ZARCH"
7897  "@
7898   ogr\t%0,%2
7899   ogrk\t%0,%1,%2
7900   og\t%0,%2"
7901  [(set_attr "op_type"  "RRE,RRF,RXY")
7902   (set_attr "cpu_facility" "*,z196,*")
7903   (set_attr "z10prop" "z10_super_E1,*,z10_super_E1")])
7904
7905(define_insn "*iordi3"
7906  [(set (match_operand:DI 0 "nonimmediate_operand"
7907                               "=d,    d,    d,    d,    d,    d,d,d,d,   AQ,Q")
7908        (ior:DI (match_operand:DI 1 "nonimmediate_operand"
7909                            "   %0,    0,    0,    0,    0,    0,0,d,0,    0,0")
7910                (match_operand:DI 2 "general_operand"
7911                            "N0HD0,N1HD0,N2HD0,N3HD0,N0SD0,N1SD0,d,d,T,NxQD0,Q")))
7912   (clobber (reg:CC CC_REGNUM))]
7913  "TARGET_ZARCH && s390_logical_operator_ok_p (operands)"
7914  "@
7915   oihh\t%0,%i2
7916   oihl\t%0,%i2
7917   oilh\t%0,%i2
7918   oill\t%0,%i2
7919   oihf\t%0,%k2
7920   oilf\t%0,%k2
7921   ogr\t%0,%2
7922   ogrk\t%0,%1,%2
7923   og\t%0,%2
7924   #
7925   #"
7926  [(set_attr "op_type"  "RI,RI,RI,RI,RIL,RIL,RRE,RRF,RXY,SI,SS")
7927   (set_attr "cpu_facility" "*,*,*,*,extimm,extimm,*,z196,*,*,*")
7928   (set_attr "z10prop" "z10_super_E1,
7929                        z10_super_E1,
7930                        z10_super_E1,
7931                        z10_super_E1,
7932                        z10_super_E1,
7933                        z10_super_E1,
7934                        z10_super_E1,
7935                        *,
7936                        z10_super_E1,
7937                        *,
7938                        *")])
7939
7940(define_split
7941  [(set (match_operand:DI 0 "s_operand" "")
7942        (ior:DI (match_dup 0) (match_operand:DI 1 "immediate_operand" "")))
7943   (clobber (reg:CC CC_REGNUM))]
7944  "reload_completed"
7945  [(parallel
7946    [(set (match_dup 0) (ior:QI (match_dup 0) (match_dup 1)))
7947     (clobber (reg:CC CC_REGNUM))])]
7948  "s390_narrow_logical_operator (IOR, &operands[0], &operands[1]);")
7949
7950;
7951; iorsi3 instruction pattern(s).
7952;
7953
7954(define_insn "*iorsi3_cc"
7955  [(set (reg CC_REGNUM)
7956        (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,d,0,0")
7957                         (match_operand:SI 2 "general_operand"      "Os,d,d,R,T"))
7958                 (const_int 0)))
7959   (set (match_operand:SI 0 "register_operand"                      "=d,d,d,d,d")
7960        (ior:SI (match_dup 1) (match_dup 2)))]
7961  "s390_match_ccmode(insn, CCTmode)"
7962  "@
7963   oilf\t%0,%o2
7964   or\t%0,%2
7965   ork\t%0,%1,%2
7966   o\t%0,%2
7967   oy\t%0,%2"
7968  [(set_attr "op_type"  "RIL,RR,RRF,RX,RXY")
7969   (set_attr "cpu_facility" "*,*,z196,*,longdisp")
7970   (set_attr "z10prop" "z10_super_E1,z10_super_E1,*,z10_super_E1,z10_super_E1")])
7971
7972(define_insn "*iorsi3_cconly"
7973  [(set (reg CC_REGNUM)
7974        (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,d,0,0")
7975                         (match_operand:SI 2 "general_operand"      "Os,d,d,R,T"))
7976                 (const_int 0)))
7977   (clobber (match_scratch:SI 0                                     "=d,d,d,d,d"))]
7978  "s390_match_ccmode(insn, CCTmode)"
7979  "@
7980   oilf\t%0,%o2
7981   or\t%0,%2
7982   ork\t%0,%1,%2
7983   o\t%0,%2
7984   oy\t%0,%2"
7985  [(set_attr "op_type"  "RIL,RR,RRF,RX,RXY")
7986   (set_attr "cpu_facility" "*,*,z196,*,longdisp")
7987   (set_attr "z10prop" "z10_super_E1,z10_super_E1,*,z10_super_E1,z10_super_E1")])
7988
7989(define_insn "*iorsi3_zarch"
7990  [(set (match_operand:SI 0 "nonimmediate_operand"         "=d,    d, d,d,d,d,d,   AQ,Q")
7991        (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,    0, 0,0,d,0,0,    0,0")
7992                (match_operand:SI 2 "general_operand"   "N0HS0,N1HS0,Os,d,d,R,T,NxQS0,Q")))
7993   (clobber (reg:CC CC_REGNUM))]
7994  "TARGET_ZARCH && s390_logical_operator_ok_p (operands)"
7995  "@
7996   oilh\t%0,%i2
7997   oill\t%0,%i2
7998   oilf\t%0,%o2
7999   or\t%0,%2
8000   ork\t%0,%1,%2
8001   o\t%0,%2
8002   oy\t%0,%2
8003   #
8004   #"
8005  [(set_attr "op_type"  "RI,RI,RIL,RR,RRF,RX,RXY,SI,SS")
8006   (set_attr "cpu_facility" "*,*,*,*,z196,*,longdisp,*,*")
8007   (set_attr "z10prop" "z10_super_E1,
8008                        z10_super_E1,
8009                        z10_super_E1,
8010                        z10_super_E1,
8011                        *,
8012                        z10_super_E1,
8013                        z10_super_E1,
8014                        *,
8015                        *")])
8016
8017(define_insn "*iorsi3_esa"
8018  [(set (match_operand:SI 0 "nonimmediate_operand" "=d,d,AQ,Q")
8019        (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,0,0")
8020                (match_operand:SI 2 "general_operand" "d,R,NxQS0,Q")))
8021   (clobber (reg:CC CC_REGNUM))]
8022  "!TARGET_ZARCH && s390_logical_operator_ok_p (operands)"
8023  "@
8024   or\t%0,%2
8025   o\t%0,%2
8026   #
8027   #"
8028  [(set_attr "op_type"  "RR,RX,SI,SS")
8029   (set_attr "z10prop" "z10_super_E1,z10_super_E1,*,*")])
8030
8031(define_split
8032  [(set (match_operand:SI 0 "s_operand" "")
8033        (ior:SI (match_dup 0) (match_operand:SI 1 "immediate_operand" "")))
8034   (clobber (reg:CC CC_REGNUM))]
8035  "reload_completed"
8036  [(parallel
8037    [(set (match_dup 0) (ior:QI (match_dup 0) (match_dup 1)))
8038     (clobber (reg:CC CC_REGNUM))])]
8039  "s390_narrow_logical_operator (IOR, &operands[0], &operands[1]);")
8040
8041;
8042; iorhi3 instruction pattern(s).
8043;
8044
8045(define_insn "*iorhi3_zarch"
8046  [(set (match_operand:HI 0 "nonimmediate_operand"         "=d,d,d,   AQ,Q")
8047        (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,d,0,    0,0")
8048                (match_operand:HI 2 "general_operand"      " d,d,n,NxQH0,Q")))
8049   (clobber (reg:CC CC_REGNUM))]
8050  "TARGET_ZARCH && s390_logical_operator_ok_p (operands)"
8051  "@
8052   or\t%0,%2
8053   ork\t%0,%1,%2
8054   oill\t%0,%x2
8055   #
8056   #"
8057  [(set_attr "op_type"  "RR,RRF,RI,SI,SS")
8058   (set_attr "cpu_facility" "*,z196,*,*,*")
8059   (set_attr "z10prop" "z10_super_E1,*,z10_super_E1,*,*")])
8060
8061(define_insn "*iorhi3_esa"
8062  [(set (match_operand:HI 0 "nonimmediate_operand" "=d,AQ,Q")
8063        (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,0")
8064                (match_operand:HI 2 "general_operand" "d,NxQH0,Q")))
8065   (clobber (reg:CC CC_REGNUM))]
8066  "!TARGET_ZARCH && s390_logical_operator_ok_p (operands)"
8067  "@
8068   or\t%0,%2
8069   #
8070   #"
8071  [(set_attr "op_type"  "RR,SI,SS")
8072   (set_attr "z10prop" "z10_super_E1,*,*")])
8073
8074(define_split
8075  [(set (match_operand:HI 0 "s_operand" "")
8076        (ior:HI (match_dup 0) (match_operand:HI 1 "immediate_operand" "")))
8077   (clobber (reg:CC CC_REGNUM))]
8078  "reload_completed"
8079  [(parallel
8080    [(set (match_dup 0) (ior:QI (match_dup 0) (match_dup 1)))
8081     (clobber (reg:CC CC_REGNUM))])]
8082  "s390_narrow_logical_operator (IOR, &operands[0], &operands[1]);")
8083
8084;
8085; iorqi3 instruction pattern(s).
8086;
8087
8088(define_insn "*iorqi3_zarch"
8089  [(set (match_operand:QI 0 "nonimmediate_operand"         "=d,d,d,Q,S,Q")
8090        (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,d,0,0,0,0")
8091                (match_operand:QI 2 "general_operand"      " d,d,n,n,n,Q")))
8092   (clobber (reg:CC CC_REGNUM))]
8093  "TARGET_ZARCH && s390_logical_operator_ok_p (operands)"
8094  "@
8095   or\t%0,%2
8096   ork\t%0,%1,%2
8097   oill\t%0,%b2
8098   oi\t%S0,%b2
8099   oiy\t%S0,%b2
8100   #"
8101  [(set_attr "op_type" "RR,RRF,RI,SI,SIY,SS")
8102   (set_attr "cpu_facility" "*,z196,*,*,longdisp,*")
8103   (set_attr "z10prop" "z10_super_E1,*,z10_super_E1,
8104                        z10_super,z10_super,*")])
8105
8106(define_insn "*iorqi3_esa"
8107  [(set (match_operand:QI 0 "nonimmediate_operand" "=d,Q,Q")
8108        (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8109                (match_operand:QI 2 "general_operand" "d,n,Q")))
8110   (clobber (reg:CC CC_REGNUM))]
8111  "!TARGET_ZARCH && s390_logical_operator_ok_p (operands)"
8112  "@
8113   or\t%0,%2
8114   oi\t%S0,%b2
8115   #"
8116  [(set_attr "op_type"  "RR,SI,SS")
8117   (set_attr "z10prop" "z10_super_E1,z10_super,*")])
8118
8119;
8120; And/Or with complement
8121;
8122
8123; ncrk, ncgrk, ocrk, ocgrk
8124(define_insn "*<ANDOR:bitops_name>c<GPR:mode>_cc"
8125  [(set (reg CC_REGNUM)
8126	(compare
8127	 (ANDOR:GPR (not:GPR (match_operand:GPR 1 "register_operand" "d"))
8128		    (match_operand:GPR 2 "register_operand" "d"))
8129	 (const_int 0)))
8130   (set (match_operand:GPR 0 "register_operand" "=d")
8131	(ANDOR:GPR (not:GPR (match_dup 1))
8132		   (match_dup 2)))]
8133  "TARGET_Z15 && s390_match_ccmode(insn, CCTmode)"
8134  "<ANDOR:noxa>c<GPR:g>rk\t%0,%2,%1"
8135  [(set_attr "op_type" "RRF")])
8136
8137; ncrk, ncgrk, ocrk, ocgrk
8138(define_insn "*<ANDOR:bitops_name>c<GPR:mode>_cconly"
8139  [(set (reg CC_REGNUM)
8140	(compare
8141	 (ANDOR:GPR (not:GPR (match_operand:GPR 1 "register_operand" "d"))
8142		    (match_operand:GPR 2 "register_operand" "d"))
8143	 (const_int 0)))
8144   (clobber (match_scratch:GPR 0 "=d"))]
8145  "TARGET_Z15 && s390_match_ccmode(insn, CCTmode)"
8146  "<ANDOR:noxa>c<GPR:g>rk\t%0,%2,%1"
8147  [(set_attr "op_type" "RRF")])
8148
8149; ncrk, ncgrk, ocrk, ocgrk
8150(define_insn "*<ANDOR:bitops_name>c<GPR:mode>"
8151  [(set (match_operand:GPR 0 "register_operand" "=d")
8152	(ANDOR:GPR (not:GPR (match_operand:GPR 1 "register_operand" "d"))
8153		   (match_operand:GPR 2 "register_operand" "d")))
8154   (clobber (reg:CC CC_REGNUM))]
8155  "TARGET_Z15"
8156  "<ANDOR:noxa>c<GPR:g>rk\t%0,%2,%1"
8157  [(set_attr "op_type" "RRF")])
8158
8159;
8160;- Nand/Nor instructions.
8161;
8162
8163; nnrk, nngrk, nork, nogrk
8164(define_insn "*n<ANDOR:inv_bitops_name><GPR:mode>_cc"
8165  [(set (reg CC_REGNUM)
8166	(compare
8167	 (ANDOR:GPR (not:GPR (match_operand:GPR 1 "register_operand" "d"))
8168		    (not:GPR (match_operand:GPR 2 "register_operand" "d")))
8169	 (const_int 0)))
8170   (set (match_operand:GPR 0 "register_operand" "=d")
8171	(ANDOR:GPR (not:GPR (match_dup 1))
8172		   (not:GPR (match_dup 2))))]
8173  "TARGET_Z15 && s390_match_ccmode(insn, CCTmode)"
8174  "n<ANDOR:inv_no><GPR:g>rk\t%0,%1,%2"
8175  [(set_attr "op_type" "RRF")])
8176
8177; nnrk, nngrk, nork, nogrk
8178(define_insn "*n<ANDOR:inv_bitops_name><mode>_cconly"
8179  [(set (reg CC_REGNUM)
8180	(compare
8181	 (ANDOR:GPR (not:GPR (match_operand:GPR 1 "register_operand" "d"))
8182		    (not:GPR (match_operand:GPR 2 "register_operand" "d")))
8183	 (const_int 0)))
8184   (clobber (match_scratch:GPR 0 "=d"))]
8185  "TARGET_Z15 && s390_match_ccmode(insn, CCTmode)"
8186  "n<ANDOR:inv_no><GPR:g>rk\t%0,%1,%2"
8187  [(set_attr "op_type" "RRF")])
8188
8189; nnrk, nngrk, nork, nogrk
8190(define_insn "*n<ANDOR:inv_bitops_name><mode>"
8191  [(set (match_operand:GPR 0 "register_operand" "=d")
8192	(ANDOR:GPR (not:GPR (match_operand:GPR 1 "register_operand" "d"))
8193		   (not:GPR (match_operand:GPR 2 "register_operand" "d"))))
8194   (clobber (reg:CC CC_REGNUM))]
8195  "TARGET_Z15"
8196  "n<ANDOR:inv_no><GPR:g>rk\t%0,%1,%2"
8197  [(set_attr "op_type" "RRF")])
8198
8199
8200;
8201; Block inclusive or (OC) patterns.
8202;
8203
8204(define_insn "*oc"
8205  [(set (match_operand:BLK 0 "memory_operand" "=Q")
8206        (ior:BLK (match_dup 0)
8207                 (match_operand:BLK 1 "memory_operand" "Q")))
8208   (use (match_operand 2 "const_int_operand" "n"))
8209   (clobber (reg:CC CC_REGNUM))]
8210  "INTVAL (operands[2]) >= 1 && INTVAL (operands[2]) <= 256"
8211  "oc\t%O0(%2,%R0),%S1"
8212  [(set_attr "op_type" "SS")
8213   (set_attr "z196prop" "z196_cracked")])
8214
8215(define_split
8216  [(set (match_operand 0 "memory_operand" "")
8217        (ior (match_dup 0)
8218             (match_operand 1 "memory_operand" "")))
8219   (clobber (reg:CC CC_REGNUM))]
8220  "reload_completed
8221   && GET_MODE (operands[0]) == GET_MODE (operands[1])
8222   && GET_MODE_SIZE (GET_MODE (operands[0])) > 0"
8223  [(parallel
8224    [(set (match_dup 0) (ior:BLK (match_dup 0) (match_dup 1)))
8225     (use (match_dup 2))
8226     (clobber (reg:CC CC_REGNUM))])]
8227{
8228  operands[2] = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[0])));
8229  operands[0] = adjust_address (operands[0], BLKmode, 0);
8230  operands[1] = adjust_address (operands[1], BLKmode, 0);
8231})
8232
8233(define_peephole2
8234  [(parallel
8235    [(set (match_operand:BLK 0 "memory_operand" "")
8236          (ior:BLK (match_dup 0)
8237                   (match_operand:BLK 1 "memory_operand" "")))
8238     (use (match_operand 2 "const_int_operand" ""))
8239     (clobber (reg:CC CC_REGNUM))])
8240   (parallel
8241    [(set (match_operand:BLK 3 "memory_operand" "")
8242          (ior:BLK (match_dup 3)
8243                   (match_operand:BLK 4 "memory_operand" "")))
8244     (use (match_operand 5 "const_int_operand" ""))
8245     (clobber (reg:CC CC_REGNUM))])]
8246  "s390_offset_p (operands[0], operands[3], operands[2])
8247   && s390_offset_p (operands[1], operands[4], operands[2])
8248   && !s390_overlap_p (operands[0], operands[1],
8249                       INTVAL (operands[2]) + INTVAL (operands[5]))
8250   && INTVAL (operands[2]) + INTVAL (operands[5]) <= 256"
8251  [(parallel
8252    [(set (match_dup 6) (ior:BLK (match_dup 6) (match_dup 7)))
8253     (use (match_dup 8))
8254     (clobber (reg:CC CC_REGNUM))])]
8255  "operands[6] = gen_rtx_MEM (BLKmode, XEXP (operands[0], 0));
8256   operands[7] = gen_rtx_MEM (BLKmode, XEXP (operands[1], 0));
8257   operands[8] = GEN_INT (INTVAL (operands[2]) + INTVAL (operands[5]));")
8258
8259
8260;;
8261;;- Xor instructions.
8262;;
8263
8264(define_expand "xor<mode>3"
8265  [(set (match_operand:INT 0 "nonimmediate_operand" "")
8266        (xor:INT (match_operand:INT 1 "nonimmediate_operand" "")
8267                 (match_operand:INT 2 "general_operand" "")))
8268   (clobber (reg:CC CC_REGNUM))]
8269  ""
8270  "s390_expand_logical_operator (XOR, <MODE>mode, operands); DONE;")
8271
8272; Combine replaces (xor (x) (const_int -1)) with (not (x)) when doing
8273; simplifications.  So its better to have something matching.
8274(define_split
8275  [(set (match_operand:INT 0 "nonimmediate_operand" "")
8276        (not:INT (match_operand:INT 1 "nonimmediate_operand" "")))]
8277  ""
8278  [(parallel
8279    [(set (match_dup 0) (xor:INT (match_dup 1) (match_dup 2)))
8280     (clobber (reg:CC CC_REGNUM))])]
8281{
8282  operands[2] = constm1_rtx;
8283  if (!s390_logical_operator_ok_p (operands))
8284    FAIL;
8285})
8286
8287;
8288; xordi3 instruction pattern(s).
8289;
8290
8291(define_insn "*xordi3_cc"
8292  [(set (reg CC_REGNUM)
8293        (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,d,0")
8294                         (match_operand:DI 2 "general_operand"      " d,d,T"))
8295                 (const_int 0)))
8296   (set (match_operand:DI 0 "register_operand"                      "=d,d,d")
8297        (xor:DI (match_dup 1) (match_dup 2)))]
8298  "s390_match_ccmode(insn, CCTmode) && TARGET_ZARCH"
8299  "@
8300   xgr\t%0,%2
8301   xgrk\t%0,%1,%2
8302   xg\t%0,%2"
8303  [(set_attr "op_type" "RRE,RRF,RXY")
8304   (set_attr "cpu_facility" "*,z196,*")
8305   (set_attr "z10prop" "z10_super_E1,*,z10_super_E1")])
8306
8307(define_insn "*xordi3_cconly"
8308  [(set (reg CC_REGNUM)
8309        (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,d,0")
8310                         (match_operand:DI 2 "general_operand"      " d,d,T"))
8311                 (const_int 0)))
8312   (clobber (match_scratch:DI 0                                     "=d,d,d"))]
8313  "s390_match_ccmode(insn, CCTmode) && TARGET_ZARCH"
8314  "@
8315   xgr\t%0,%2
8316   xgrk\t%0,%1,%2
8317   xg\t%0,%2"
8318  [(set_attr "op_type" "RRE,RRF,RXY")
8319   (set_attr "cpu_facility" "*,z196,*")
8320   (set_attr "z10prop" "z10_super_E1,*,z10_super_E1")])
8321
8322(define_insn "*xordi3"
8323  [(set (match_operand:DI 0 "nonimmediate_operand"         "=d,    d,d,d,d,   AQ,Q")
8324        (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,    0,0,d,0,    0,0")
8325                (match_operand:DI 2 "general_operand"   "N0SD0,N1SD0,d,d,T,NxQD0,Q")))
8326   (clobber (reg:CC CC_REGNUM))]
8327  "TARGET_ZARCH && s390_logical_operator_ok_p (operands)"
8328  "@
8329   xihf\t%0,%k2
8330   xilf\t%0,%k2
8331   xgr\t%0,%2
8332   xgrk\t%0,%1,%2
8333   xg\t%0,%2
8334   #
8335   #"
8336  [(set_attr "op_type"  "RIL,RIL,RRE,RRF,RXY,SI,SS")
8337   (set_attr "cpu_facility" "extimm,extimm,*,z196,*,*,*")
8338   (set_attr "z10prop" "z10_super_E1,z10_super_E1,z10_super_E1,
8339                        *,z10_super_E1,*,*")])
8340
8341(define_split
8342  [(set (match_operand:DI 0 "s_operand" "")
8343        (xor:DI (match_dup 0) (match_operand:DI 1 "immediate_operand" "")))
8344   (clobber (reg:CC CC_REGNUM))]
8345  "reload_completed"
8346  [(parallel
8347    [(set (match_dup 0) (xor:QI (match_dup 0) (match_dup 1)))
8348     (clobber (reg:CC CC_REGNUM))])]
8349  "s390_narrow_logical_operator (XOR, &operands[0], &operands[1]);")
8350
8351;
8352; xorsi3 instruction pattern(s).
8353;
8354
8355(define_insn "*xorsi3_cc"
8356  [(set (reg CC_REGNUM)
8357        (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,d,0,0")
8358                         (match_operand:SI 2 "general_operand"      "Os,d,d,R,T"))
8359                 (const_int 0)))
8360   (set (match_operand:SI 0 "register_operand"                      "=d,d,d,d,d")
8361        (xor:SI (match_dup 1) (match_dup 2)))]
8362  "s390_match_ccmode(insn, CCTmode)"
8363  "@
8364   xilf\t%0,%o2
8365   xr\t%0,%2
8366   xrk\t%0,%1,%2
8367   x\t%0,%2
8368   xy\t%0,%2"
8369  [(set_attr "op_type" "RIL,RR,RRF,RX,RXY")
8370   (set_attr "cpu_facility" "*,*,z196,*,longdisp")
8371   (set_attr "z10prop" "z10_super_E1,z10_super_E1,*,
8372                        z10_super_E1,z10_super_E1")])
8373
8374(define_insn "*xorsi3_cconly"
8375  [(set (reg CC_REGNUM)
8376        (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,d,0,0")
8377                         (match_operand:SI 2 "general_operand"      "Os,d,d,R,T"))
8378                 (const_int 0)))
8379   (clobber (match_scratch:SI 0                                     "=d,d,d,d,d"))]
8380  "s390_match_ccmode(insn, CCTmode)"
8381  "@
8382   xilf\t%0,%o2
8383   xr\t%0,%2
8384   xrk\t%0,%1,%2
8385   x\t%0,%2
8386   xy\t%0,%2"
8387  [(set_attr "op_type" "RIL,RR,RRF,RX,RXY")
8388   (set_attr "cpu_facility" "*,*,z196,*,longdisp")
8389   (set_attr "z10prop" "z10_super_E1,z10_super_E1,*,
8390                        z10_super_E1,z10_super_E1")])
8391
8392(define_insn "*xorsi3"
8393  [(set (match_operand:SI 0 "nonimmediate_operand"         "=d,d,d,d,d,   AQ,Q")
8394        (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,d,0,0,    0,0")
8395                (match_operand:SI 2 "general_operand"      "Os,d,d,R,T,NxQS0,Q")))
8396   (clobber (reg:CC CC_REGNUM))]
8397  "s390_logical_operator_ok_p (operands)"
8398  "@
8399   xilf\t%0,%o2
8400   xr\t%0,%2
8401   xrk\t%0,%1,%2
8402   x\t%0,%2
8403   xy\t%0,%2
8404   #
8405   #"
8406  [(set_attr "op_type"  "RIL,RR,RRF,RX,RXY,SI,SS")
8407   (set_attr "cpu_facility" "*,*,z196,*,longdisp,*,*")
8408   (set_attr "z10prop" "z10_super_E1,z10_super_E1,*,
8409                        z10_super_E1,z10_super_E1,*,*")])
8410
8411(define_split
8412  [(set (match_operand:SI 0 "s_operand" "")
8413        (xor:SI (match_dup 0) (match_operand:SI 1 "immediate_operand" "")))
8414   (clobber (reg:CC CC_REGNUM))]
8415  "reload_completed"
8416  [(parallel
8417    [(set (match_dup 0) (xor:QI (match_dup 0) (match_dup 1)))
8418     (clobber (reg:CC CC_REGNUM))])]
8419  "s390_narrow_logical_operator (XOR, &operands[0], &operands[1]);")
8420
8421;
8422; xorhi3 instruction pattern(s).
8423;
8424
8425(define_insn "*xorhi3"
8426  [(set (match_operand:HI 0 "nonimmediate_operand"         "=d,d,d,   AQ,Q")
8427        (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,d,    0,0")
8428                (match_operand:HI 2 "general_operand"      "Os,d,d,NxQH0,Q")))
8429   (clobber (reg:CC CC_REGNUM))]
8430  "s390_logical_operator_ok_p (operands)"
8431  "@
8432   xilf\t%0,%x2
8433   xr\t%0,%2
8434   xrk\t%0,%1,%2
8435   #
8436   #"
8437  [(set_attr "op_type"  "RIL,RR,RRF,SI,SS")
8438   (set_attr "cpu_facility" "*,*,z196,*,*")
8439   (set_attr "z10prop" "z10_super_E1,z10_super_E1,*,*,*")])
8440
8441(define_split
8442  [(set (match_operand:HI 0 "s_operand" "")
8443        (xor:HI (match_dup 0) (match_operand:HI 1 "immediate_operand" "")))
8444   (clobber (reg:CC CC_REGNUM))]
8445  "reload_completed"
8446  [(parallel
8447    [(set (match_dup 0) (xor:QI (match_dup 0) (match_dup 1)))
8448     (clobber (reg:CC CC_REGNUM))])]
8449  "s390_narrow_logical_operator (XOR, &operands[0], &operands[1]);")
8450
8451;
8452; xorqi3 instruction pattern(s).
8453;
8454
8455(define_insn "*xorqi3"
8456  [(set (match_operand:QI 0 "nonimmediate_operand"         "=d,d,d,Q,S,Q")
8457        (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,d,0,0,0")
8458                (match_operand:QI 2 "general_operand"      "Os,d,d,n,n,Q")))
8459   (clobber (reg:CC CC_REGNUM))]
8460  "s390_logical_operator_ok_p (operands)"
8461  "@
8462   xilf\t%0,%b2
8463   xr\t%0,%2
8464   xrk\t%0,%1,%2
8465   xi\t%S0,%b2
8466   xiy\t%S0,%b2
8467   #"
8468  [(set_attr "op_type"  "RIL,RR,RRF,SI,SIY,SS")
8469   (set_attr "cpu_facility" "*,*,z196,*,longdisp,*")
8470   (set_attr "z10prop" "z10_super_E1,z10_super_E1,*,z10_super,z10_super,*")])
8471
8472
8473;
8474; Block exclusive or (XC) patterns.
8475;
8476
8477(define_insn "*xc"
8478  [(set (match_operand:BLK 0 "memory_operand" "=Q")
8479        (xor:BLK (match_dup 0)
8480                 (match_operand:BLK 1 "memory_operand" "Q")))
8481   (use (match_operand 2 "const_int_operand" "n"))
8482   (clobber (reg:CC CC_REGNUM))]
8483  "INTVAL (operands[2]) >= 1 && INTVAL (operands[2]) <= 256"
8484  "xc\t%O0(%2,%R0),%S1"
8485  [(set_attr "op_type" "SS")])
8486
8487(define_split
8488  [(set (match_operand 0 "memory_operand" "")
8489        (xor (match_dup 0)
8490             (match_operand 1 "memory_operand" "")))
8491   (clobber (reg:CC CC_REGNUM))]
8492  "reload_completed
8493   && GET_MODE (operands[0]) == GET_MODE (operands[1])
8494   && GET_MODE_SIZE (GET_MODE (operands[0])) > 0"
8495  [(parallel
8496    [(set (match_dup 0) (xor:BLK (match_dup 0) (match_dup 1)))
8497     (use (match_dup 2))
8498     (clobber (reg:CC CC_REGNUM))])]
8499{
8500  operands[2] = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[0])));
8501  operands[0] = adjust_address (operands[0], BLKmode, 0);
8502  operands[1] = adjust_address (operands[1], BLKmode, 0);
8503})
8504
8505(define_peephole2
8506  [(parallel
8507    [(set (match_operand:BLK 0 "memory_operand" "")
8508          (xor:BLK (match_dup 0)
8509                   (match_operand:BLK 1 "memory_operand" "")))
8510     (use (match_operand 2 "const_int_operand" ""))
8511     (clobber (reg:CC CC_REGNUM))])
8512   (parallel
8513    [(set (match_operand:BLK 3 "memory_operand" "")
8514          (xor:BLK (match_dup 3)
8515                   (match_operand:BLK 4 "memory_operand" "")))
8516     (use (match_operand 5 "const_int_operand" ""))
8517     (clobber (reg:CC CC_REGNUM))])]
8518  "s390_offset_p (operands[0], operands[3], operands[2])
8519   && s390_offset_p (operands[1], operands[4], operands[2])
8520   && !s390_overlap_p (operands[0], operands[1],
8521                       INTVAL (operands[2]) + INTVAL (operands[5]))
8522   && INTVAL (operands[2]) + INTVAL (operands[5]) <= 256"
8523  [(parallel
8524    [(set (match_dup 6) (xor:BLK (match_dup 6) (match_dup 7)))
8525     (use (match_dup 8))
8526     (clobber (reg:CC CC_REGNUM))])]
8527  "operands[6] = gen_rtx_MEM (BLKmode, XEXP (operands[0], 0));
8528   operands[7] = gen_rtx_MEM (BLKmode, XEXP (operands[1], 0));
8529   operands[8] = GEN_INT (INTVAL (operands[2]) + INTVAL (operands[5]));")
8530
8531;
8532; Block xor (XC) patterns with src == dest.
8533;
8534
8535(define_insn "*xc_zero"
8536  [(set (match_operand:BLK 0 "memory_operand" "=Q")
8537        (const_int 0))
8538   (use (match_operand 1 "const_int_operand" "n"))
8539   (clobber (reg:CC CC_REGNUM))]
8540  "INTVAL (operands[1]) >= 1 && INTVAL (operands[1]) <= 256"
8541  "xc\t%O0(%1,%R0),%S0"
8542  [(set_attr "op_type" "SS")
8543   (set_attr "z196prop" "z196_cracked")])
8544
8545(define_peephole2
8546  [(parallel
8547    [(set (match_operand:BLK 0 "memory_operand" "")
8548          (const_int 0))
8549     (use (match_operand 1 "const_int_operand" ""))
8550     (clobber (reg:CC CC_REGNUM))])
8551   (parallel
8552    [(set (match_operand:BLK 2 "memory_operand" "")
8553          (const_int 0))
8554     (use (match_operand 3 "const_int_operand" ""))
8555     (clobber (reg:CC CC_REGNUM))])]
8556  "s390_offset_p (operands[0], operands[2], operands[1])
8557   && INTVAL (operands[1]) + INTVAL (operands[3]) <= 256"
8558  [(parallel
8559    [(set (match_dup 4) (const_int 0))
8560     (use (match_dup 5))
8561     (clobber (reg:CC CC_REGNUM))])]
8562  "operands[4] = gen_rtx_MEM (BLKmode, XEXP (operands[0], 0));
8563   operands[5] = GEN_INT (INTVAL (operands[1]) + INTVAL (operands[3]));")
8564
8565;
8566;- Nxor instructions.
8567;
8568
8569; nxrk, nxgrk
8570(define_insn "*nxor<GPR:mode>_cc"
8571  [(set (reg CC_REGNUM)
8572	(compare
8573	 (not:GPR (xor:GPR (match_operand:GPR 1 "register_operand" "d")
8574			   (match_operand:GPR 2 "register_operand" "d")))
8575	 (const_int 0)))
8576   (set (match_operand:GPR 0 "register_operand" "=d")
8577	(xor:GPR (not:GPR (match_dup 1))
8578		    (match_dup 2)))]
8579  "TARGET_Z15 && s390_match_ccmode(insn, CCTmode)"
8580  "nx<GPR:g>rk\t%0,%1,%2"
8581  [(set_attr "op_type" "RRF")])
8582
8583; nxrk, nxgrk
8584(define_insn "*nxor<mode>_cconly"
8585  [(set (reg CC_REGNUM)
8586	(compare
8587	 (not:GPR (xor:GPR (match_operand:GPR 1 "register_operand" "d")
8588			   (match_operand:GPR 2 "register_operand" "d")))
8589	 (const_int 0)))
8590   (clobber (match_scratch:GPR 0 "=d"))]
8591  "TARGET_Z15 && s390_match_ccmode(insn, CCTmode)"
8592  "nx<GPR:g>rk\t%0,%1,%2"
8593  [(set_attr "op_type" "RRF")])
8594
8595; nxrk, nxgrk
8596(define_insn "*nxor<mode>"
8597  [(set (match_operand:GPR 0 "register_operand" "=d")
8598	(not:GPR (xor:GPR (match_operand:GPR 1 "register_operand" "d")
8599			  (match_operand:GPR 2 "register_operand" "d"))))
8600   (clobber (reg:CC CC_REGNUM))]
8601  "TARGET_Z15"
8602  "nx<GPR:g>rk\t%0,%1,%2"
8603  [(set_attr "op_type" "RRF")])
8604
8605;;
8606;;- Negate instructions.
8607;;
8608
8609;
8610; neg(di|si)2 instruction pattern(s).
8611;
8612
8613(define_expand "neg<mode>2"
8614  [(parallel
8615    [(set (match_operand:DSI 0 "register_operand" "=d")
8616          (neg:DSI (match_operand:DSI 1 "register_operand" "d")))
8617     (clobber (reg:CC CC_REGNUM))])]
8618  ""
8619  "")
8620
8621(define_insn "*negdi2_sign_cc"
8622  [(set (reg CC_REGNUM)
8623        (compare (neg:DI (ashiftrt:DI (ashift:DI (subreg:DI
8624                           (match_operand:SI 1 "register_operand" "d") 0)
8625                           (const_int 32)) (const_int 32)))
8626                 (const_int 0)))
8627   (set (match_operand:DI 0 "register_operand" "=d")
8628        (neg:DI (sign_extend:DI (match_dup 1))))]
8629  "TARGET_ZARCH && s390_match_ccmode (insn, CCAmode)"
8630  "lcgfr\t%0,%1"
8631  [(set_attr "op_type"  "RRE")
8632   (set_attr "z10prop" "z10_c")])
8633
8634(define_insn "*negdi2_sign"
8635  [(set (match_operand:DI 0 "register_operand" "=d")
8636        (neg:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "d"))))
8637   (clobber (reg:CC CC_REGNUM))]
8638  "TARGET_ZARCH"
8639  "lcgfr\t%0,%1"
8640  [(set_attr "op_type"  "RRE")
8641   (set_attr "z10prop" "z10_c")])
8642
8643; lcr, lcgr
8644(define_insn "*neg<mode>2_cc"
8645  [(set (reg CC_REGNUM)
8646        (compare (neg:GPR (match_operand:GPR 1 "register_operand" "d"))
8647                 (const_int 0)))
8648   (set (match_operand:GPR 0 "register_operand" "=d")
8649        (neg:GPR (match_dup 1)))]
8650  "s390_match_ccmode (insn, CCAmode)"
8651  "lc<g>r\t%0,%1"
8652  [(set_attr "op_type"  "RR<E>")
8653   (set_attr "z10prop" "z10_super_c_E1")])
8654
8655; lcr, lcgr
8656(define_insn "*neg<mode>2_cconly"
8657  [(set (reg CC_REGNUM)
8658        (compare (neg:GPR (match_operand:GPR 1 "register_operand" "d"))
8659                 (const_int 0)))
8660   (clobber (match_scratch:GPR 0 "=d"))]
8661  "s390_match_ccmode (insn, CCAmode)"
8662  "lc<g>r\t%0,%1"
8663  [(set_attr "op_type"  "RR<E>")
8664   (set_attr "z10prop" "z10_super_c_E1")])
8665
8666; lcr, lcgr
8667(define_insn "*neg<mode>2"
8668  [(set (match_operand:GPR 0 "register_operand" "=d")
8669        (neg:GPR (match_operand:GPR 1 "register_operand" "d")))
8670   (clobber (reg:CC CC_REGNUM))]
8671  ""
8672  "lc<g>r\t%0,%1"
8673  [(set_attr "op_type"  "RR<E>")
8674   (set_attr "z10prop" "z10_super_c_E1")])
8675
8676(define_insn "*negdi2_31"
8677  [(set (match_operand:DI 0 "register_operand" "=d")
8678        (neg:DI (match_operand:DI 1 "register_operand" "d")))
8679   (clobber (reg:CC CC_REGNUM))]
8680  "!TARGET_ZARCH"
8681  "#")
8682
8683; Split a DImode NEG on 31bit into 2 SImode NEGs
8684
8685; Doing the twos complement separately on the SImode parts does an
8686; unwanted +1 on the high part which needs to be subtracted afterwards
8687; ... unless the +1 on the low part created an overflow.
8688
8689(define_split
8690  [(set (match_operand:DI 0 "register_operand" "")
8691        (neg:DI (match_operand:DI 1 "register_operand" "")))
8692   (clobber (reg:CC CC_REGNUM))]
8693  "!TARGET_ZARCH
8694   && (REGNO (operands[0]) == REGNO (operands[1])
8695      || s390_split_ok_p (operands[0], operands[1], DImode, 0))
8696   && reload_completed"
8697  [(parallel
8698    [(set (match_dup 2) (neg:SI (match_dup 3)))
8699     (clobber (reg:CC CC_REGNUM))])
8700   (parallel
8701    [(set (reg:CCAP CC_REGNUM)
8702          (compare:CCAP (neg:SI (match_dup 5)) (const_int 0)))
8703     (set (match_dup 4) (neg:SI (match_dup 5)))])
8704   (set (pc)
8705        (if_then_else (ne (reg:CCAP CC_REGNUM) (const_int 0))
8706                      (pc)
8707                      (label_ref (match_dup 6))))
8708   (parallel
8709    [(set (match_dup 2) (plus:SI (match_dup 2) (const_int -1)))
8710     (clobber (reg:CC CC_REGNUM))])
8711   (match_dup 6)]
8712  "operands[2] = operand_subword (operands[0], 0, 0, DImode);
8713   operands[3] = operand_subword (operands[1], 0, 0, DImode);
8714   operands[4] = operand_subword (operands[0], 1, 0, DImode);
8715   operands[5] = operand_subword (operands[1], 1, 0, DImode);
8716   operands[6] = gen_label_rtx ();")
8717
8718; Like above but first make a copy of the low part of the src operand
8719; since it might overlap with the high part of the destination.
8720
8721(define_split
8722  [(set (match_operand:DI 0 "register_operand" "")
8723        (neg:DI (match_operand:DI 1 "register_operand" "")))
8724   (clobber (reg:CC CC_REGNUM))]
8725  "!TARGET_ZARCH
8726   && s390_split_ok_p (operands[0], operands[1], DImode, 1)
8727   && reload_completed"
8728  [; Make a backup of op5 first
8729   (set (match_dup 4) (match_dup 5))
8730   ; Setting op2 here might clobber op5
8731   (parallel
8732    [(set (match_dup 2) (neg:SI (match_dup 3)))
8733     (clobber (reg:CC CC_REGNUM))])
8734   (parallel
8735    [(set (reg:CCAP CC_REGNUM)
8736          (compare:CCAP (neg:SI (match_dup 4)) (const_int 0)))
8737     (set (match_dup 4) (neg:SI (match_dup 4)))])
8738   (set (pc)
8739        (if_then_else (ne (reg:CCAP CC_REGNUM) (const_int 0))
8740                      (pc)
8741                      (label_ref (match_dup 6))))
8742   (parallel
8743    [(set (match_dup 2) (plus:SI (match_dup 2) (const_int -1)))
8744     (clobber (reg:CC CC_REGNUM))])
8745   (match_dup 6)]
8746  "operands[2] = operand_subword (operands[0], 0, 0, DImode);
8747   operands[3] = operand_subword (operands[1], 0, 0, DImode);
8748   operands[4] = operand_subword (operands[0], 1, 0, DImode);
8749   operands[5] = operand_subword (operands[1], 1, 0, DImode);
8750   operands[6] = gen_label_rtx ();")
8751
8752;
8753; neg(df|sf)2 instruction pattern(s).
8754;
8755
8756(define_expand "neg<mode>2"
8757  [(parallel
8758    [(set (match_operand:BFP          0 "register_operand")
8759          (neg:BFP (match_operand:BFP 1 "register_operand")))
8760     (clobber (reg:CC CC_REGNUM))])]
8761  "TARGET_HARD_FLOAT")
8762
8763; lcxbr, lcdbr, lcebr
8764(define_insn "*neg<mode>2_cc"
8765  [(set (reg CC_REGNUM)
8766        (compare (neg:BFP (match_operand:BFP 1 "register_operand" "f"))
8767                 (match_operand:BFP 2 "const0_operand" "")))
8768   (set (match_operand:BFP 0 "register_operand" "=f")
8769        (neg:BFP (match_dup 1)))]
8770  "s390_match_ccmode (insn, CCSmode) && TARGET_HARD_FLOAT"
8771  "lc<xde>br\t%0,%1"
8772  [(set_attr "op_type"  "RRE")
8773   (set_attr "type"     "fsimp<mode>")])
8774
8775; lcxbr, lcdbr, lcebr
8776(define_insn "*neg<mode>2_cconly"
8777  [(set (reg CC_REGNUM)
8778        (compare (neg:BFP (match_operand:BFP 1 "register_operand" "f"))
8779                 (match_operand:BFP 2 "const0_operand" "")))
8780   (clobber (match_scratch:BFP 0 "=f"))]
8781  "s390_match_ccmode (insn, CCSmode) && TARGET_HARD_FLOAT"
8782  "lc<xde>br\t%0,%1"
8783  [(set_attr "op_type"  "RRE")
8784   (set_attr "type"     "fsimp<mode>")])
8785
8786; lcdfr
8787(define_insn "*neg<mode>2_nocc"
8788  [(set (match_operand:FP 0 "register_operand"         "=f")
8789        (neg:FP (match_operand:FP 1 "register_operand" "<fT0>")))]
8790  "TARGET_DFP"
8791  "lcdfr\t%0,%1"
8792  [(set_attr "op_type"  "RRE")
8793   (set_attr "type"     "fsimp<mode>")])
8794
8795; lcxbr, lcdbr, lcebr
8796; FIXME: wflcdb does not clobber cc
8797; FIXME: Does wflcdb ever match here?
8798(define_insn "*neg<mode>2"
8799  [(set (match_operand:BFP          0 "register_operand" "=f,v,v")
8800        (neg:BFP (match_operand:BFP 1 "register_operand"  "f,v,v")))
8801   (clobber (reg:CC CC_REGNUM))]
8802  "TARGET_HARD_FLOAT"
8803  "@
8804   lc<xde>br\t%0,%1
8805   wflcdb\t%0,%1
8806   wflcsb\t%0,%1"
8807  [(set_attr "op_type"      "RRE,VRR,VRR")
8808   (set_attr "cpu_facility" "*,vx,vxe")
8809   (set_attr "type"         "fsimp<mode>,*,*")
8810   (set_attr "enabled"      "*,<DF>,<SF>")])
8811
8812
8813;;
8814;;- Absolute value instructions.
8815;;
8816
8817;
8818; abs(di|si)2 instruction pattern(s).
8819;
8820
8821(define_insn "*absdi2_sign_cc"
8822  [(set (reg CC_REGNUM)
8823        (compare (abs:DI (ashiftrt:DI (ashift:DI (subreg:DI
8824                           (match_operand:SI 1 "register_operand" "d") 0)
8825                           (const_int 32)) (const_int 32)))
8826                 (const_int 0)))
8827   (set (match_operand:DI 0 "register_operand" "=d")
8828        (abs:DI (sign_extend:DI (match_dup 1))))]
8829  "TARGET_ZARCH && s390_match_ccmode (insn, CCAmode)"
8830  "lpgfr\t%0,%1"
8831  [(set_attr "op_type"  "RRE")
8832   (set_attr "z10prop" "z10_c")])
8833
8834(define_insn "*absdi2_sign"
8835  [(set (match_operand:DI 0 "register_operand" "=d")
8836        (abs:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "d"))))
8837   (clobber (reg:CC CC_REGNUM))]
8838  "TARGET_ZARCH"
8839  "lpgfr\t%0,%1"
8840  [(set_attr "op_type"  "RRE")
8841   (set_attr "z10prop" "z10_c")])
8842
8843; lpr, lpgr
8844(define_insn "*abs<mode>2_cc"
8845  [(set (reg CC_REGNUM)
8846        (compare (abs:GPR (match_operand:DI 1 "register_operand" "d"))
8847                 (const_int 0)))
8848   (set (match_operand:GPR 0 "register_operand" "=d")
8849        (abs:GPR (match_dup 1)))]
8850  "s390_match_ccmode (insn, CCAmode)"
8851  "lp<g>r\t%0,%1"
8852  [(set_attr "op_type"  "RR<E>")
8853   (set_attr "z10prop" "z10_c")])
8854
8855; lpr, lpgr
8856(define_insn "*abs<mode>2_cconly"
8857  [(set (reg CC_REGNUM)
8858        (compare (abs:GPR (match_operand:GPR 1 "register_operand" "d"))
8859                 (const_int 0)))
8860   (clobber (match_scratch:GPR 0 "=d"))]
8861  "s390_match_ccmode (insn, CCAmode)"
8862  "lp<g>r\t%0,%1"
8863  [(set_attr "op_type"  "RR<E>")
8864   (set_attr "z10prop" "z10_c")])
8865
8866; lpr, lpgr
8867(define_insn "abs<mode>2"
8868  [(set (match_operand:GPR 0 "register_operand" "=d")
8869        (abs:GPR (match_operand:GPR 1 "register_operand" "d")))
8870   (clobber (reg:CC CC_REGNUM))]
8871  ""
8872  "lp<g>r\t%0,%1"
8873  [(set_attr "op_type"  "RR<E>")
8874   (set_attr "z10prop" "z10_c")])
8875
8876;
8877; abs(df|sf)2 instruction pattern(s).
8878;
8879
8880(define_expand "abs<mode>2"
8881  [(parallel
8882    [(set (match_operand:BFP 0 "register_operand" "=f")
8883          (abs:BFP (match_operand:BFP 1 "register_operand" "f")))
8884     (clobber (reg:CC CC_REGNUM))])]
8885  "TARGET_HARD_FLOAT"
8886  "")
8887
8888; lpxbr, lpdbr, lpebr
8889(define_insn "*abs<mode>2_cc"
8890  [(set (reg CC_REGNUM)
8891        (compare (abs:BFP (match_operand:BFP 1 "register_operand" "f"))
8892                 (match_operand:BFP 2 "const0_operand" "")))
8893   (set (match_operand:BFP 0 "register_operand" "=f")
8894        (abs:BFP (match_dup 1)))]
8895  "s390_match_ccmode (insn, CCSmode) && TARGET_HARD_FLOAT"
8896  "lp<xde>br\t%0,%1"
8897  [(set_attr "op_type"  "RRE")
8898   (set_attr "type"     "fsimp<mode>")])
8899
8900; lpxbr, lpdbr, lpebr
8901(define_insn "*abs<mode>2_cconly"
8902  [(set (reg CC_REGNUM)
8903        (compare (abs:BFP (match_operand:BFP 1 "register_operand" "f"))
8904                 (match_operand:BFP 2 "const0_operand" "")))
8905   (clobber (match_scratch:BFP 0 "=f"))]
8906  "s390_match_ccmode (insn, CCSmode) && TARGET_HARD_FLOAT"
8907  "lp<xde>br\t%0,%1"
8908  [(set_attr "op_type"  "RRE")
8909   (set_attr "type"     "fsimp<mode>")])
8910
8911; lpdfr
8912(define_insn "*abs<mode>2_nocc"
8913  [(set (match_operand:FP 0 "register_operand"         "=f")
8914        (abs:FP (match_operand:FP 1 "register_operand" "<fT0>")))]
8915  "TARGET_DFP"
8916  "lpdfr\t%0,%1"
8917  [(set_attr "op_type"  "RRE")
8918   (set_attr "type"     "fsimp<mode>")])
8919
8920; lpxbr, lpdbr, lpebr
8921; FIXME: wflpdb does not clobber cc
8922(define_insn "*abs<mode>2"
8923  [(set (match_operand:BFP          0 "register_operand" "=f,v")
8924        (abs:BFP (match_operand:BFP 1 "register_operand"  "f,v")))
8925   (clobber (reg:CC CC_REGNUM))]
8926  "TARGET_HARD_FLOAT"
8927  "@
8928    lp<xde>br\t%0,%1
8929    wflpdb\t%0,%1"
8930  [(set_attr "op_type"      "RRE,VRR")
8931   (set_attr "cpu_facility" "*,vx")
8932   (set_attr "type"         "fsimp<mode>,*")
8933   (set_attr "enabled"      "*,<DFDI>")])
8934
8935
8936;;
8937;;- Negated absolute value instructions
8938;;
8939
8940;
8941; Integer
8942;
8943
8944(define_insn "*negabsdi2_sign_cc"
8945  [(set (reg CC_REGNUM)
8946        (compare (neg:DI (abs:DI (ashiftrt:DI (ashift:DI (subreg:DI
8947                           (match_operand:SI 1 "register_operand" "d") 0)
8948                           (const_int 32)) (const_int 32))))
8949                 (const_int 0)))
8950   (set (match_operand:DI 0 "register_operand" "=d")
8951        (neg:DI (abs:DI (sign_extend:DI (match_dup 1)))))]
8952  "TARGET_ZARCH && s390_match_ccmode (insn, CCAmode)"
8953  "lngfr\t%0,%1"
8954  [(set_attr "op_type"  "RRE")
8955   (set_attr "z10prop" "z10_c")])
8956
8957(define_insn "*negabsdi2_sign"
8958  [(set (match_operand:DI 0 "register_operand" "=d")
8959	(neg:DI (abs:DI (sign_extend:DI
8960                          (match_operand:SI 1 "register_operand" "d")))))
8961   (clobber (reg:CC CC_REGNUM))]
8962  "TARGET_ZARCH"
8963  "lngfr\t%0,%1"
8964  [(set_attr "op_type" "RRE")
8965   (set_attr "z10prop" "z10_c")])
8966
8967; lnr, lngr
8968(define_insn "*negabs<mode>2_cc"
8969  [(set (reg CC_REGNUM)
8970        (compare (neg:GPR (abs:GPR (match_operand:GPR 1 "register_operand" "d")))
8971                 (const_int 0)))
8972   (set (match_operand:GPR 0 "register_operand" "=d")
8973        (neg:GPR (abs:GPR (match_dup 1))))]
8974  "s390_match_ccmode (insn, CCAmode)"
8975  "ln<g>r\t%0,%1"
8976  [(set_attr "op_type"  "RR<E>")
8977   (set_attr "z10prop" "z10_c")])
8978
8979; lnr, lngr
8980(define_insn "*negabs<mode>2_cconly"
8981  [(set (reg CC_REGNUM)
8982        (compare (neg:GPR (abs:GPR (match_operand:GPR 1 "register_operand" "d")))
8983                 (const_int 0)))
8984   (clobber (match_scratch:GPR 0 "=d"))]
8985  "s390_match_ccmode (insn, CCAmode)"
8986  "ln<g>r\t%0,%1"
8987  [(set_attr "op_type"  "RR<E>")
8988   (set_attr "z10prop" "z10_c")])
8989
8990; lnr, lngr
8991(define_insn "*negabs<mode>2"
8992  [(set (match_operand:GPR 0 "register_operand" "=d")
8993	(neg:GPR (abs:GPR (match_operand:GPR 1 "register_operand" "d"))))
8994   (clobber (reg:CC CC_REGNUM))]
8995  ""
8996  "ln<g>r\t%0,%1"
8997  [(set_attr "op_type" "RR<E>")
8998   (set_attr "z10prop" "z10_c")])
8999
9000;
9001; Floating point
9002;
9003
9004; lnxbr, lndbr, lnebr
9005(define_insn "*negabs<mode>2_cc"
9006  [(set (reg CC_REGNUM)
9007        (compare (neg:BFP (abs:BFP (match_operand:BFP 1 "register_operand" "f")))
9008                 (match_operand:BFP 2 "const0_operand" "")))
9009   (set (match_operand:BFP 0 "register_operand" "=f")
9010        (neg:BFP (abs:BFP (match_dup 1))))]
9011  "s390_match_ccmode (insn, CCSmode) && TARGET_HARD_FLOAT"
9012  "ln<xde>br\t%0,%1"
9013  [(set_attr "op_type"  "RRE")
9014   (set_attr "type"     "fsimp<mode>")])
9015
9016; lnxbr, lndbr, lnebr
9017(define_insn "*negabs<mode>2_cconly"
9018  [(set (reg CC_REGNUM)
9019        (compare (neg:BFP (abs:BFP (match_operand:BFP 1 "register_operand" "f")))
9020                 (match_operand:BFP 2 "const0_operand" "")))
9021   (clobber (match_scratch:BFP 0 "=f"))]
9022  "s390_match_ccmode (insn, CCSmode) && TARGET_HARD_FLOAT"
9023  "ln<xde>br\t%0,%1"
9024  [(set_attr "op_type"  "RRE")
9025   (set_attr "type"     "fsimp<mode>")])
9026
9027; lndfr
9028(define_insn "*negabs<mode>2_nocc"
9029  [(set (match_operand:FP 0 "register_operand"                 "=f")
9030        (neg:FP (abs:FP (match_operand:FP 1 "register_operand" "<fT0>"))))]
9031  "TARGET_DFP"
9032  "lndfr\t%0,%1"
9033  [(set_attr "op_type"  "RRE")
9034   (set_attr "type"     "fsimp<mode>")])
9035
9036; lnxbr, lndbr, lnebr
9037; FIXME: wflndb does not clobber cc
9038(define_insn "*negabs<mode>2"
9039  [(set (match_operand:BFP                   0 "register_operand" "=f,v")
9040        (neg:BFP (abs:BFP (match_operand:BFP 1 "register_operand"  "f,v"))))
9041   (clobber (reg:CC CC_REGNUM))]
9042  "TARGET_HARD_FLOAT"
9043  "@
9044   ln<xde>br\t%0,%1
9045   wflndb\t%0,%1"
9046  [(set_attr "op_type"      "RRE,VRR")
9047   (set_attr "cpu_facility" "*,vx")
9048   (set_attr "type"         "fsimp<mode>,*")
9049   (set_attr "enabled"      "*,<DFDI>")])
9050
9051;;
9052;;- Square root instructions.
9053;;
9054
9055;
9056; sqrt(df|sf)2 instruction pattern(s).
9057;
9058
9059; sqxbr, sqdbr, sqebr, sqdb, sqeb
9060(define_insn "sqrt<mode>2"
9061  [(set (match_operand:BFP           0 "register_operand" "=f,f,v")
9062	(sqrt:BFP (match_operand:BFP 1 "general_operand"   "f,R,v")))]
9063  "TARGET_HARD_FLOAT"
9064  "@
9065   sq<xde>br\t%0,%1
9066   sq<xde>b\t%0,%1
9067   wfsqdb\t%v0,%v1"
9068  [(set_attr "op_type"      "RRE,RXE,VRR")
9069   (set_attr "type"         "fsqrt<mode>")
9070   (set_attr "cpu_facility" "*,*,vx")
9071   (set_attr "enabled"      "*,<DSF>,<DFDI>")])
9072
9073
9074;;
9075;;- One complement instructions.
9076;;
9077
9078;
9079; one_cmpl(di|si|hi|qi)2 instruction pattern(s).
9080;
9081
9082(define_expand "one_cmpl<mode>2"
9083  [(parallel
9084    [(set (match_operand:INT 0 "register_operand" "")
9085          (xor:INT (match_operand:INT 1 "register_operand" "")
9086		   (const_int -1)))
9087     (clobber (reg:CC CC_REGNUM))])]
9088  ""
9089  "")
9090
9091
9092;;
9093;; Find leftmost bit instructions.
9094;;
9095
9096(define_expand "clzdi2"
9097  [(set (match_operand:DI 0 "register_operand" "=d")
9098	(clz:DI (match_operand:DI 1 "register_operand" "d")))]
9099  "TARGET_EXTIMM && TARGET_ZARCH"
9100{
9101  rtx_insn *insn;
9102  rtx clz_equal;
9103  rtx wide_reg = gen_reg_rtx (TImode);
9104  rtx msb = gen_rtx_CONST_INT (DImode, HOST_WIDE_INT_1U << 63);
9105
9106  clz_equal = gen_rtx_CLZ (DImode, operands[1]);
9107
9108  emit_insn (gen_clztidi2 (wide_reg, operands[1], msb));
9109
9110  insn = emit_move_insn (operands[0], gen_highpart (DImode, wide_reg));
9111  set_unique_reg_note (insn, REG_EQUAL, clz_equal);
9112
9113  DONE;
9114})
9115
9116; CLZ result is in hard reg op0 - this is the high part of the target operand
9117; The source with the left-most one bit cleared is in hard reg op0 + 1 - the low part
9118(define_insn "clztidi2"
9119  [(set (match_operand:TI 0 "register_operand" "=d")
9120	(ior:TI
9121	  (ashift:TI (zero_extend:TI (clz:DI (match_operand:DI 1 "register_operand" "d")))
9122		     (const_int 64))
9123	  (zero_extend:TI
9124	   (xor:DI (match_dup 1)
9125		   (lshiftrt (match_operand:DI 2 "const_int_operand" "")
9126			     (subreg:SI (clz:DI (match_dup 1)) 4))))))
9127   (clobber (reg:CC CC_REGNUM))]
9128  "UINTVAL (operands[2]) == HOST_WIDE_INT_1U << 63
9129   && TARGET_EXTIMM && TARGET_ZARCH"
9130  "flogr\t%0,%1"
9131  [(set_attr "op_type"  "RRE")])
9132
9133
9134;;
9135;;- Rotate instructions.
9136;;
9137
9138;
9139; rotl(di|si)3 instruction pattern(s).
9140;
9141
9142(define_expand "rotl<mode>3"
9143  [(set (match_operand:GPR 0 "register_operand" "")
9144        (rotate:GPR (match_operand:GPR 1 "register_operand" "")
9145		    (match_operand:QI 2 "shift_count_operand" "")))]
9146  ""
9147  "")
9148
9149; rll, rllg
9150(define_insn "*rotl<mode>3"
9151  [(set (match_operand:GPR             0 "register_operand"  "=d")
9152	(rotate:GPR (match_operand:GPR 1 "register_operand"   "d")
9153		    (match_operand:QI  2 "shift_count_operand" "jsc")))]
9154  ""
9155  "rll<g>\t%0,%1,%Y2"
9156  [(set_attr "op_type"  "RSE")
9157   (set_attr "atype"    "reg")
9158   (set_attr "z10prop"  "z10_super_E1")])
9159
9160
9161;;
9162;;- Shift instructions.
9163;;
9164
9165;
9166; (ashl|lshr)(di|si)3 instruction pattern(s).
9167; Left shifts and logical right shifts
9168
9169(define_expand "<shift><mode>3"
9170  [(set (match_operand:DSI 0 "register_operand" "")
9171        (SHIFT:DSI (match_operand:DSI 1 "register_operand" "")
9172                   (match_operand:QI 2 "shift_count_operand" "")))]
9173  ""
9174  "")
9175
9176; ESA 64 bit register pair shift with reg or imm shift count
9177; sldl, srdl
9178(define_insn "*<shift>di3_31"
9179  [(set (match_operand:DI 0 "register_operand"            "=d")
9180        (SHIFT:DI (match_operand:DI 1 "register_operand"   "0")
9181                  (match_operand:QI 2 "shift_count_operand" "jsc")))]
9182  "!TARGET_ZARCH"
9183  "s<lr>dl\t%0,%Y2"
9184  [(set_attr "op_type"  "RS")
9185   (set_attr "atype"    "reg")
9186   (set_attr "z196prop" "z196_cracked")])
9187
9188
9189; 64 bit register shift with reg or imm shift count
9190; sll, srl, sllg, srlg, sllk, srlk
9191(define_insn "*<shift><mode>3"
9192  [(set (match_operand:GPR 0 "register_operand"              "=d, d")
9193        (SHIFT:GPR (match_operand:GPR 1 "register_operand" "<d0>, d")
9194                   (match_operand:QI 2 "shift_count_operand"   "jsc,jsc")))]
9195  ""
9196  "@
9197   s<lr>l<g>\t%0,<1>%Y2
9198   s<lr>l<gk>\t%0,%1,%Y2"
9199  [(set_attr "op_type"  "RS<E>,RSY")
9200   (set_attr "atype"    "reg,reg")
9201   (set_attr "cpu_facility" "*,z196")
9202   (set_attr "z10prop"  "z10_super_E1,*")])
9203
9204
9205;
9206; ashr(di|si)3 instruction pattern(s).
9207; Arithmetic right shifts
9208
9209(define_expand "ashr<mode>3"
9210  [(parallel
9211    [(set (match_operand:DSI 0 "register_operand" "")
9212          (ashiftrt:DSI (match_operand:DSI 1 "register_operand" "")
9213                        (match_operand:QI 2 "shift_count_operand" "")))
9214     (clobber (reg:CC CC_REGNUM))])]
9215  ""
9216  "")
9217
9218; FIXME: The number of alternatives is doubled here to match the fix
9219; number of 2 in the subst pattern for the (clobber (match_scratch...
9220; The right fix should be to support match_scratch in the output
9221; pattern of a define_subst.
9222(define_insn "*ashrdi3_31<setcc><cconly>"
9223  [(set (match_operand:DI 0 "register_operand"               "=d, d")
9224        (ashiftrt:DI (match_operand:DI 1 "register_operand"   "0, 0")
9225                     (match_operand:QI 2 "shift_count_operand" "jsc,jsc")))
9226   (clobber (reg:CC CC_REGNUM))]
9227  "!TARGET_ZARCH"
9228  "@
9229   srda\t%0,%Y2
9230   srda\t%0,%Y2"
9231  [(set_attr "op_type" "RS")
9232   (set_attr "atype"   "reg")])
9233
9234
9235; sra, srag
9236(define_insn "*ashr<mode>3<setcc><cconly>"
9237  [(set (match_operand:GPR 0 "register_operand"                 "=d, d")
9238        (ashiftrt:GPR (match_operand:GPR 1 "register_operand" "<d0>, d")
9239                      (match_operand:QI 2 "shift_count_operand"   "jsc,jsc")))
9240   (clobber (reg:CC CC_REGNUM))]
9241  ""
9242  "@
9243   sra<g>\t%0,<1>%Y2
9244   sra<gk>\t%0,%1,%Y2"
9245  [(set_attr "op_type"  "RS<E>,RSY")
9246   (set_attr "atype"    "reg")
9247   (set_attr "cpu_facility" "*,z196")
9248   (set_attr "z10prop" "z10_super_E1,*")])
9249
9250
9251;;
9252;; Branch instruction patterns.
9253;;
9254
9255(define_expand "cbranch<mode>4"
9256  [(set (pc)
9257        (if_then_else (match_operator 0 "comparison_operator"
9258        	       [(match_operand:GPR 1 "register_operand" "")
9259                        (match_operand:GPR 2 "general_operand" "")])
9260		      (label_ref (match_operand 3 "" ""))
9261                      (pc)))]
9262  ""
9263  "s390_emit_jump (operands[3],
9264    s390_emit_compare (GET_CODE (operands[0]), operands[1], operands[2]));
9265   DONE;")
9266
9267(define_expand "cbranch<mode>4"
9268  [(set (pc)
9269        (if_then_else (match_operator 0 "comparison_operator"
9270        	       [(match_operand:FP 1 "register_operand" "")
9271                        (match_operand:FP 2 "general_operand" "")])
9272		      (label_ref (match_operand 3 "" ""))
9273                      (pc)))]
9274  "TARGET_HARD_FLOAT"
9275  "s390_emit_jump (operands[3],
9276    s390_emit_compare (GET_CODE (operands[0]), operands[1], operands[2]));
9277   DONE;")
9278
9279(define_expand "cbranchcc4"
9280  [(set (pc)
9281        (if_then_else (match_operator 0 "s390_comparison"
9282        	       [(match_operand 1 "cc_reg_operand" "")
9283                        (match_operand 2 "const_int_operand" "")])
9284		      (label_ref (match_operand 3 "" ""))
9285                      (pc)))]
9286  ""
9287  "")
9288
9289
9290;;
9291;;- Conditional jump instructions.
9292;;
9293
9294(define_insn "*cjump_64"
9295  [(set (pc)
9296        (if_then_else
9297          (match_operator 1 "s390_comparison" [(reg CC_REGNUM)
9298					       (match_operand 2 "const_int_operand" "")])
9299          (label_ref (match_operand 0 "" ""))
9300          (pc)))]
9301  ""
9302{
9303  if (get_attr_length (insn) == 4)
9304    return "j%C1\t%l0";
9305  else
9306    return "jg%C1\t%l0";
9307}
9308  [(set_attr "op_type" "RI")
9309   (set_attr "type"    "branch")
9310   (set (attr "length")
9311        (if_then_else (lt (abs (minus (pc) (match_dup 0))) (const_int 60000))
9312                      (const_int 4) (const_int 6)))])
9313
9314(define_insn "*cjump_long"
9315  [(set (pc)
9316        (if_then_else
9317          (match_operator 1 "s390_comparison" [(reg CC_REGNUM) (const_int 0)])
9318          (match_operand 0 "address_operand" "ZQZR")
9319          (pc)))]
9320  "!TARGET_INDIRECT_BRANCH_NOBP_JUMP"
9321{
9322  if (get_attr_op_type (insn) == OP_TYPE_RR)
9323    return "b%C1r\t%0";
9324  else
9325    return "b%C1\t%a0";
9326}
9327  [(set (attr "op_type")
9328        (if_then_else (match_operand 0 "register_operand" "")
9329                      (const_string "RR") (const_string "RX")))
9330   (set (attr "mnemonic")
9331        (if_then_else (match_operand 0 "register_operand" "")
9332                      (const_string "bcr") (const_string "bc")))
9333   (set_attr "type"  "branch")
9334   (set_attr "atype" "agen")])
9335
9336;; A conditional return instruction.
9337(define_insn "*c<code>"
9338  [(set (pc)
9339        (if_then_else
9340          (match_operator 0 "s390_comparison" [(reg CC_REGNUM) (const_int 0)])
9341          (ANY_RETURN)
9342          (pc)))]
9343  "s390_can_use_<code>_insn ()"
9344{
9345  if (TARGET_INDIRECT_BRANCH_NOBP_RET)
9346    {
9347      s390_indirect_branch_via_thunk (RETURN_REGNUM,
9348				      INVALID_REGNUM,
9349				      operands[0],
9350				      s390_indirect_branch_type_return);
9351      return "";
9352    }
9353  else
9354    return "b%C0r\t%%r14";
9355}
9356  [(set (attr "op_type")
9357	(if_then_else (match_test "TARGET_INDIRECT_BRANCH_NOBP_RET")
9358		      (const_string "RIL")
9359		      (const_string "RR")))
9360   (set (attr "mnemonic")
9361	(if_then_else (match_test "TARGET_INDIRECT_BRANCH_NOBP_RET")
9362		      (const_string "brcl")
9363		      (const_string "bcr")))
9364   (set_attr "type"  "jsr")
9365   (set_attr "atype" "agen")])
9366
9367;;
9368;;- Negated conditional jump instructions.
9369;;
9370
9371(define_insn "*icjump_64"
9372  [(set (pc)
9373        (if_then_else
9374          (match_operator 1 "s390_comparison" [(reg CC_REGNUM) (const_int 0)])
9375          (pc)
9376          (label_ref (match_operand 0 "" ""))))]
9377  ""
9378{
9379  if (get_attr_length (insn) == 4)
9380    return "j%D1\t%l0";
9381  else
9382    return "jg%D1\t%l0";
9383}
9384  [(set_attr "op_type" "RI")
9385   (set_attr "type"    "branch")
9386   (set (attr "length")
9387        (if_then_else (lt (abs (minus (pc) (match_dup 0))) (const_int 60000))
9388                      (const_int 4) (const_int 6)))])
9389
9390(define_insn "*icjump_long"
9391  [(set (pc)
9392        (if_then_else
9393          (match_operator 1 "s390_comparison" [(reg CC_REGNUM) (const_int 0)])
9394          (pc)
9395          (match_operand 0 "address_operand" "ZQZR")))]
9396  "!TARGET_INDIRECT_BRANCH_NOBP_JUMP"
9397{
9398  if (get_attr_op_type (insn) == OP_TYPE_RR)
9399    return "b%D1r\t%0";
9400  else
9401    return "b%D1\t%a0";
9402}
9403  [(set (attr "op_type")
9404        (if_then_else (match_operand 0 "register_operand" "")
9405                      (const_string "RR") (const_string "RX")))
9406   (set (attr "mnemonic")
9407        (if_then_else (match_operand 0 "register_operand" "")
9408                      (const_string "bcr") (const_string "bc")))
9409   (set_attr "type"  "branch")
9410   (set_attr "atype" "agen")])
9411
9412;;
9413;;- Trap instructions.
9414;;
9415
9416(define_insn "trap"
9417  [(trap_if (const_int 1) (const_int 0))]
9418  ""
9419  "j\t.+2"
9420  [(set_attr "op_type" "RI")
9421   (set_attr "type"  "branch")])
9422
9423(define_expand "ctrap<mode>4"
9424  [(trap_if (match_operator 0 "comparison_operator"
9425             [(match_operand:GPR 1 "register_operand" "")
9426              (match_operand:GPR 2 "general_operand" "")])
9427	     (match_operand 3 "const0_operand" ""))]
9428  ""
9429  {
9430    rtx cond = s390_emit_compare (GET_CODE (operands[0]),
9431                                  operands[1], operands[2]);
9432    emit_insn (gen_condtrap (cond, XEXP (cond, 0)));
9433    DONE;
9434  })
9435
9436(define_expand "ctrap<mode>4"
9437  [(trap_if (match_operator 0 "comparison_operator"
9438             [(match_operand:FP 1 "register_operand" "")
9439              (match_operand:FP 2 "general_operand" "")])
9440	     (match_operand 3 "const0_operand" ""))]
9441  ""
9442  {
9443    rtx cond = s390_emit_compare (GET_CODE (operands[0]),
9444                                  operands[1], operands[2]);
9445    emit_insn (gen_condtrap (cond, XEXP (cond, 0)));
9446    DONE;
9447  })
9448
9449(define_insn "condtrap"
9450  [(trap_if (match_operator 0 "s390_comparison"
9451             [(match_operand 1 "cc_reg_operand" "c")
9452              (const_int 0)])
9453	    (const_int 0))]
9454  ""
9455  "j%C0\t.+2";
9456  [(set_attr "op_type" "RI")
9457   (set_attr "type"  "branch")])
9458
9459; crt, cgrt, cit, cgit
9460(define_insn "*cmp_and_trap_signed_int<mode>"
9461  [(trap_if (match_operator 0 "s390_signed_integer_comparison"
9462	       [(match_operand:GPR 1 "register_operand"  "d,d")
9463		(match_operand:GPR 2 "nonmemory_operand" "d,K")])
9464	    (const_int 0))]
9465  "TARGET_Z10"
9466  "@
9467   c<g>rt%C0\t%1,%2
9468   c<g>it%C0\t%1,%h2"
9469  [(set_attr "op_type" "RRF,RIE")
9470   (set_attr "type"    "branch")
9471   (set_attr "z10prop" "z10_super_c,z10_super")])
9472
9473; clrt, clgrt, clfit, clgit, clt, clgt
9474(define_insn "*cmp_and_trap_unsigned_int<mode>"
9475  [(trap_if (match_operator 0 "s390_unsigned_integer_comparison"
9476	       [(match_operand:GPR 1 "register_operand" "d,d,d")
9477		(match_operand:GPR 2 "general_operand"  "d,D,S")])
9478	    (const_int 0))]
9479  "TARGET_Z10"
9480  "@
9481   cl<g>rt%C0\t%1,%2
9482   cl<gf>it%C0\t%1,%x2
9483   cl<g>t%C0\t%1,%2"
9484  [(set_attr "op_type"      "RRF,RIE,RSY")
9485   (set_attr "type"         "branch")
9486   (set_attr "z10prop"      "z10_super_c,z10_super,*")
9487   (set_attr "cpu_facility" "z10,z10,zEC12")])
9488
9489; lat, lgat
9490(define_insn "*load_and_trap<mode>"
9491  [(trap_if (eq (match_operand:GPR 0 "memory_operand"  "T")
9492		(const_int 0))
9493	    (const_int 0))
9494   (set (match_operand:GPR 1 "register_operand" "=d")
9495	(match_dup 0))]
9496  "TARGET_ZEC12"
9497  "l<g>at\t%1,%0"
9498  [(set_attr "op_type" "RXY")])
9499
9500
9501;;
9502;;- Loop instructions.
9503;;
9504;;  This is all complicated by the fact that since this is a jump insn
9505;;  we must handle our own output reloads.
9506
9507;; branch on index
9508
9509; This splitter will be matched by combine and has to add the 2 moves
9510; necessary to load the compare and the increment values into a
9511; register pair as needed by brxle.
9512
9513(define_insn_and_split "*brx_stage1_<GPR:mode>"
9514  [(set (pc)
9515        (if_then_else
9516	 (match_operator 6 "s390_brx_operator"
9517	    [(plus:GPR (match_operand:GPR 1 "register_operand" "")
9518		       (match_operand:GPR 2 "general_operand"  ""))
9519	     (match_operand:GPR 3 "register_operand" "")])
9520	 (label_ref (match_operand 0 "" ""))
9521	 (pc)))
9522   (set (match_operand:GPR 4 "nonimmediate_operand" "")
9523        (plus:GPR (match_dup 1) (match_dup 2)))
9524   (clobber (match_scratch:GPR 5 ""))]
9525  ""
9526  "#"
9527  "!reload_completed && !reload_in_progress"
9528  [(set (match_dup 7) (match_dup 2)) ; the increment
9529   (set (match_dup 8) (match_dup 3)) ; the comparison value
9530   (parallel [(set (pc)
9531		   (if_then_else
9532		    (match_op_dup 6
9533		       [(plus:GPR (match_dup 1) (match_dup 7))
9534			(match_dup 8)])
9535		    (label_ref (match_dup 0))
9536		    (pc)))
9537	      (set (match_dup 4)
9538		   (plus:GPR (match_dup 1) (match_dup 7)))
9539	      (clobber (match_dup 5))
9540	      (clobber (reg:CC CC_REGNUM))])]
9541  {
9542    rtx dreg = gen_reg_rtx (word_mode == DImode ? TImode : DImode);
9543    operands[7] = gen_lowpart (<GPR:MODE>mode,
9544			       gen_highpart (word_mode, dreg));
9545    operands[8] = gen_lowpart (<GPR:MODE>mode,
9546			       gen_lowpart (word_mode, dreg));
9547  })
9548
9549; brxlg, brxhg
9550
9551(define_insn_and_split "*brxg_64bit"
9552  [(set (pc)
9553        (if_then_else
9554          (match_operator 5 "s390_brx_operator"
9555	     [(plus:DI (match_operand:DI 1 "register_operand" "d,d,d")
9556		       (subreg:DI (match_operand:TI 2 "register_operand" "d,d,d") 0))
9557              (subreg:DI (match_dup 2) 8)])
9558          (label_ref (match_operand 0 "" ""))
9559          (pc)))
9560   (set (match_operand:DI 3 "nonimmediate_operand" "=1,?X,?X")
9561        (plus:DI (match_dup 1)
9562		 (subreg:DI (match_dup 2) 0)))
9563   (clobber (match_scratch:DI 4 "=X,&1,&?d"))
9564   (clobber (reg:CC CC_REGNUM))]
9565  "TARGET_ZARCH"
9566{
9567  if (which_alternative != 0)
9568    return "#";
9569  else if (get_attr_length (insn) == 6)
9570    return "brx%E5g\t%1,%2,%l0";
9571  else
9572    return "agr\t%1,%2\;cgr\t%1,%M2\;jg%C5\t%l0";
9573}
9574  "&& reload_completed
9575   && (!REG_P (operands[3])
9576       || !rtx_equal_p (operands[1], operands[3]))"
9577  [(set (match_dup 4) (match_dup 1))
9578   (parallel [(set (match_dup 4) (plus:DI (match_dup 4) (subreg:DI (match_dup 2) 0)))
9579	      (clobber (reg:CC CC_REGNUM))])
9580   (set (reg:CCS CC_REGNUM) (compare:CCS (match_dup 4) (subreg:DI (match_dup 2) 8)))
9581   (set (match_dup 3) (match_dup 4))
9582   (set (pc) (if_then_else (match_op_dup 5 [(reg:CCS CC_REGNUM) (const_int 0)])
9583			   (label_ref (match_dup 0))
9584			   (pc)))]
9585  ""
9586  [(set_attr "op_type"  "RIE")
9587   (set_attr "type"  "branch")
9588   (set (attr "length")
9589        (if_then_else (lt (abs (minus (pc) (match_dup 0))) (const_int 60000))
9590                      (const_int 6) (const_int 16)))])
9591
9592; brxle, brxh
9593
9594(define_insn_and_split "*brx_64bit"
9595  [(set (pc)
9596        (if_then_else
9597          (match_operator 5 "s390_brx_operator"
9598	     [(plus:SI (match_operand:SI 1 "register_operand" "d,d,d")
9599		       (subreg:SI (match_operand:TI 2 "register_operand" "d,d,d") 4))
9600              (subreg:SI (match_dup 2) 12)])
9601          (label_ref (match_operand 0 "" ""))
9602          (pc)))
9603   (set (match_operand:SI 3 "nonimmediate_operand" "=1,?X,?X")
9604        (plus:SI (match_dup 1)
9605		 (subreg:SI (match_dup 2) 4)))
9606   (clobber (match_scratch:SI 4 "=X,&1,&?d"))
9607   (clobber (reg:CC CC_REGNUM))]
9608  "TARGET_ZARCH"
9609{
9610  if (which_alternative != 0)
9611    return "#";
9612  else if (get_attr_length (insn) == 6)
9613    return "brx%C5\t%1,%2,%l0";
9614  else
9615    return "ar\t%1,%2\;cr\t%1,%M2\;jg%C5\t%l0";
9616}
9617  "&& reload_completed
9618   && (!REG_P (operands[3])
9619       || !rtx_equal_p (operands[1], operands[3]))"
9620  [(set (match_dup 4) (match_dup 1))
9621   (parallel [(set (match_dup 4) (plus:SI (match_dup 4) (subreg:SI (match_dup 2) 4)))
9622	      (clobber (reg:CC CC_REGNUM))])
9623   (set (reg:CCS CC_REGNUM) (compare:CCS (match_dup 4) (subreg:SI (match_dup 2) 12)))
9624   (set (match_dup 3) (match_dup 4))
9625   (set (pc) (if_then_else (match_op_dup 5 [(reg:CCS CC_REGNUM) (const_int 0)])
9626			   (label_ref (match_dup 0))
9627			   (pc)))]
9628  ""
9629  [(set_attr "op_type"  "RSI")
9630   (set_attr "type"  "branch")
9631   (set (attr "length")
9632        (if_then_else (lt (abs (minus (pc) (match_dup 0))) (const_int 60000))
9633                      (const_int 6) (const_int 14)))])
9634
9635; brxle, brxh
9636
9637(define_insn_and_split "*brx_31bit"
9638  [(set (pc)
9639        (if_then_else
9640          (match_operator 5 "s390_brx_operator"
9641	    [(plus:SI (match_operand:SI 1 "register_operand" "d,d,d")
9642		      (subreg:SI (match_operand:DI 2 "register_operand" "d,d,d") 0))
9643	     (subreg:SI (match_dup 2) 4)])
9644          (label_ref (match_operand 0 "" ""))
9645          (pc)))
9646   (set (match_operand:SI 3 "nonimmediate_operand" "=1,?X,?X")
9647        (plus:SI (match_dup 1)
9648		 (subreg:SI (match_dup 2) 0)))
9649   (clobber (match_scratch:SI 4 "=X,&1,&?d"))
9650   (clobber (reg:CC CC_REGNUM))]
9651  "!TARGET_ZARCH"
9652{
9653  if (which_alternative != 0)
9654    return "#";
9655  else if (get_attr_length (insn) == 6)
9656    return "brx%C5\t%1,%2,%l0";
9657  else
9658    return "ar\t%1,%2\;cr\t%1,%M2\;jg%C5\t%l0";
9659}
9660  "&& reload_completed
9661   && (!REG_P (operands[3])
9662       || !rtx_equal_p (operands[1], operands[3]))"
9663  [(set (match_dup 4) (match_dup 1))
9664   (parallel [(set (match_dup 4) (plus:SI (match_dup 4) (subreg:SI (match_dup 2) 0)))
9665	      (clobber (reg:CC CC_REGNUM))])
9666   (set (reg:CCS CC_REGNUM) (compare:CCS (match_dup 4) (subreg:SI (match_dup 2) 4)))
9667   (set (match_dup 3) (match_dup 4))
9668   (set (pc) (if_then_else (match_op_dup 5 [(reg:CCS CC_REGNUM) (const_int 0)])
9669			   (label_ref (match_dup 0))
9670			   (pc)))]
9671  ""
9672  [(set_attr "op_type"  "RSI")
9673   (set_attr "type"  "branch")
9674   (set (attr "length")
9675        (if_then_else (lt (abs (minus (pc) (match_dup 0))) (const_int 60000))
9676                      (const_int 6) (const_int 14)))])
9677
9678
9679;; branch on count
9680
9681(define_expand "doloop_end"
9682  [(use (match_operand 0 "" ""))        ; loop pseudo
9683   (use (match_operand 1 "" ""))]       ; label
9684  ""
9685{
9686  if (GET_MODE (operands[0]) == SImode)
9687    emit_jump_insn (gen_doloop_si64 (operands[1], operands[0], operands[0]));
9688  else if (GET_MODE (operands[0]) == DImode && TARGET_ZARCH)
9689    emit_jump_insn (gen_doloop_di (operands[1], operands[0], operands[0]));
9690  else
9691    FAIL;
9692
9693  DONE;
9694})
9695
9696(define_insn_and_split "doloop_si64"
9697  [(set (pc)
9698        (if_then_else
9699          (ne (match_operand:SI 1 "register_operand" "d,d,d")
9700              (const_int 1))
9701          (label_ref (match_operand 0 "" ""))
9702          (pc)))
9703   (set (match_operand:SI 2 "nonimmediate_operand" "=1,?X,?X")
9704        (plus:SI (match_dup 1) (const_int -1)))
9705   (clobber (match_scratch:SI 3 "=X,&1,&?d"))
9706   (clobber (reg:CC CC_REGNUM))]
9707  ""
9708{
9709  if (which_alternative != 0)
9710    return "#";
9711  else if (get_attr_length (insn) == 4)
9712    return "brct\t%1,%l0";
9713  else
9714    return "ahi\t%1,-1\;jgne\t%l0";
9715}
9716  "&& reload_completed
9717   && (! REG_P (operands[2])
9718       || ! rtx_equal_p (operands[1], operands[2]))"
9719  [(set (match_dup 3) (match_dup 1))
9720   (parallel [(set (reg:CCAN CC_REGNUM)
9721                   (compare:CCAN (plus:SI (match_dup 3) (const_int -1))
9722                                 (const_int 0)))
9723              (set (match_dup 3) (plus:SI (match_dup 3) (const_int -1)))])
9724   (set (match_dup 2) (match_dup 3))
9725   (set (pc) (if_then_else (ne (reg:CCAN CC_REGNUM) (const_int 0))
9726                           (label_ref (match_dup 0))
9727                           (pc)))]
9728  ""
9729  [(set_attr "op_type"  "RI")
9730   ; Strictly speaking, the z10 properties are valid for brct only, however, it does not
9731   ; hurt us in the (rare) case of ahi.
9732   (set_attr "z10prop"  "z10_super_E1")
9733   (set_attr "type"  "branch")
9734   (set (attr "length")
9735        (if_then_else (lt (abs (minus (pc) (match_dup 0))) (const_int 60000))
9736                      (const_int 4) (const_int 10)))])
9737
9738(define_insn_and_split "doloop_di"
9739  [(set (pc)
9740        (if_then_else
9741          (ne (match_operand:DI 1 "register_operand" "d,d,d")
9742              (const_int 1))
9743          (label_ref (match_operand 0 "" ""))
9744          (pc)))
9745   (set (match_operand:DI 2 "nonimmediate_operand" "=1,?X,?X")
9746        (plus:DI (match_dup 1) (const_int -1)))
9747   (clobber (match_scratch:DI 3 "=X,&1,&?d"))
9748   (clobber (reg:CC CC_REGNUM))]
9749  "TARGET_ZARCH"
9750{
9751  if (which_alternative != 0)
9752    return "#";
9753  else if (get_attr_length (insn) == 4)
9754    return "brctg\t%1,%l0";
9755  else
9756    return "aghi\t%1,-1\;jgne\t%l0";
9757}
9758  "&& reload_completed
9759   && (! REG_P (operands[2])
9760       || ! rtx_equal_p (operands[1], operands[2]))"
9761  [(set (match_dup 3) (match_dup 1))
9762   (parallel [(set (reg:CCAN CC_REGNUM)
9763                   (compare:CCAN (plus:DI (match_dup 3) (const_int -1))
9764                                 (const_int 0)))
9765              (set (match_dup 3) (plus:DI (match_dup 3) (const_int -1)))])
9766   (set (match_dup 2) (match_dup 3))
9767   (set (pc) (if_then_else (ne (reg:CCAN CC_REGNUM) (const_int 0))
9768                           (label_ref (match_dup 0))
9769                           (pc)))]
9770  ""
9771  [(set_attr "op_type"  "RI")
9772   ; Strictly speaking, the z10 properties are valid for brct only, however, it does not
9773   ; hurt us in the (rare) case of ahi.
9774   (set_attr "z10prop"  "z10_super_E1")
9775   (set_attr "type"  "branch")
9776   (set (attr "length")
9777        (if_then_else (lt (abs (minus (pc) (match_dup 0))) (const_int 60000))
9778                      (const_int 4) (const_int 10)))])
9779
9780;;
9781;;- Unconditional jump instructions.
9782;;
9783
9784;
9785; jump instruction pattern(s).
9786;
9787
9788(define_expand "jump"
9789  [(match_operand 0 "" "")]
9790  ""
9791  "s390_emit_jump (operands[0], NULL_RTX); DONE;")
9792
9793(define_insn "*jump64"
9794  [(set (pc) (label_ref (match_operand 0 "" "")))]
9795  ""
9796{
9797  if (get_attr_length (insn) == 4)
9798    return "j\t%l0";
9799  else
9800    return "jg\t%l0";
9801}
9802  [(set_attr "op_type" "RI")
9803   (set_attr "type"  "branch")
9804   (set (attr "length")
9805        (if_then_else (lt (abs (minus (pc) (match_dup 0))) (const_int 60000))
9806                      (const_int 4) (const_int 6)))])
9807
9808;
9809; indirect-jump instruction pattern(s).
9810;
9811
9812(define_expand "indirect_jump"
9813  [(set (pc) (match_operand 0 "nonimmediate_operand" ""))]
9814  ""
9815{
9816  if (address_operand (operands[0], GET_MODE (operands[0])))
9817    ;
9818  else if (TARGET_Z14
9819	   && GET_MODE (operands[0]) == Pmode
9820	   && memory_operand (operands[0], Pmode))
9821    ;
9822  else
9823    operands[0] = force_reg (Pmode, operands[0]);
9824
9825  if (TARGET_INDIRECT_BRANCH_NOBP_JUMP_THUNK)
9826    {
9827      operands[0] = force_reg (Pmode, operands[0]);
9828      if (TARGET_CPU_Z10)
9829	{
9830	  if (TARGET_64BIT)
9831	    emit_jump_insn (gen_indirect_jump_via_thunkdi_z10 (operands[0]));
9832	  else
9833	    emit_jump_insn (gen_indirect_jump_via_thunksi_z10 (operands[0]));
9834	}
9835      else
9836	{
9837	  if (TARGET_64BIT)
9838	    emit_jump_insn (gen_indirect_jump_via_thunkdi (operands[0]));
9839	  else
9840	    emit_jump_insn (gen_indirect_jump_via_thunksi (operands[0]));
9841	}
9842      DONE;
9843    }
9844
9845  if (TARGET_INDIRECT_BRANCH_NOBP_JUMP_INLINE_THUNK)
9846    {
9847      operands[0] = force_reg (Pmode, operands[0]);
9848      rtx label_ref = gen_rtx_LABEL_REF (VOIDmode, gen_label_rtx ());
9849      if (TARGET_CPU_Z10)
9850	{
9851	  if (TARGET_64BIT)
9852	    emit_jump_insn (gen_indirect_jump_via_inlinethunkdi_z10 (operands[0],
9853								     label_ref));
9854	  else
9855	    emit_jump_insn (gen_indirect_jump_via_inlinethunksi_z10 (operands[0],
9856								     label_ref));
9857	}
9858      else
9859	{
9860	  if (TARGET_64BIT)
9861	    emit_jump_insn (gen_indirect_jump_via_inlinethunkdi (operands[0],
9862								 label_ref,
9863								 force_reg (Pmode, label_ref)));
9864	  else
9865	    emit_jump_insn (gen_indirect_jump_via_inlinethunksi (operands[0],
9866								 label_ref,
9867								 force_reg (Pmode, label_ref)));
9868	}
9869      DONE;
9870    }
9871})
9872
9873(define_insn "*indirect_jump"
9874  [(set (pc)
9875	(match_operand 0 "address_operand" "ZR"))]
9876 "!TARGET_INDIRECT_BRANCH_NOBP_JUMP_THUNK"
9877{
9878  if (get_attr_op_type (insn) == OP_TYPE_RR)
9879    return "br\t%0";
9880  else
9881    return "b\t%a0";
9882}
9883 [(set (attr "op_type")
9884       (if_then_else (match_operand 0 "register_operand" "")
9885		     (const_string "RR") (const_string "RX")))
9886  (set (attr "mnemonic")
9887       (if_then_else (match_operand 0 "register_operand" "")
9888		     (const_string "br") (const_string "b")))
9889  (set_attr "type"  "branch")
9890  (set_attr "atype" "agen")])
9891
9892(define_insn "indirect_jump_via_thunk<mode>_z10"
9893  [(set (pc)
9894	(match_operand:P 0 "register_operand" "a"))]
9895 "TARGET_INDIRECT_BRANCH_NOBP_JUMP_THUNK
9896  && TARGET_CPU_Z10"
9897{
9898  s390_indirect_branch_via_thunk (REGNO (operands[0]),
9899				  INVALID_REGNUM,
9900				  NULL_RTX,
9901				  s390_indirect_branch_type_jump);
9902  return "";
9903}
9904 [(set_attr "op_type"  "RIL")
9905  (set_attr "mnemonic" "jg")
9906  (set_attr "type"  "branch")
9907  (set_attr "atype" "agen")])
9908
9909(define_insn "indirect_jump_via_thunk<mode>"
9910  [(set (pc)
9911	(match_operand:P 0 "register_operand" " a"))
9912   (clobber (reg:P INDIRECT_BRANCH_THUNK_REGNUM))]
9913 "TARGET_INDIRECT_BRANCH_NOBP_JUMP_THUNK
9914  && !TARGET_CPU_Z10"
9915{
9916  s390_indirect_branch_via_thunk (REGNO (operands[0]),
9917				  INVALID_REGNUM,
9918				  NULL_RTX,
9919				  s390_indirect_branch_type_jump);
9920  return "";
9921}
9922 [(set_attr "op_type"  "RIL")
9923  (set_attr "mnemonic" "jg")
9924  (set_attr "type"  "branch")
9925  (set_attr "atype" "agen")])
9926
9927
9928; The label_ref is wrapped into an if_then_else in order to hide it
9929; from mark_jump_label.  Without this the label_ref would become the
9930; ONLY jump target of that jump breaking the control flow graph.
9931(define_insn "indirect_jump_via_inlinethunk<mode>_z10"
9932  [(unspec [(if_then_else (match_operand:P 1 "larl_operand" "X")
9933			  (const_int 0)
9934			  (const_int 0))
9935	    (const_int 0)] UNSPEC_EXECUTE_JUMP)
9936   (set (pc) (match_operand:P 0 "register_operand" "a"))]
9937  "TARGET_INDIRECT_BRANCH_NOBP_JUMP_INLINE_THUNK
9938   && TARGET_CPU_Z10"
9939{
9940  s390_indirect_branch_via_inline_thunk (operands[1]);
9941  return "";
9942}
9943  [(set_attr "op_type" "RIL")
9944   (set_attr "type"    "branch")
9945   (set_attr "length"  "10")])
9946
9947(define_insn "indirect_jump_via_inlinethunk<mode>"
9948  [(unspec [(if_then_else (match_operand:P 1 "larl_operand" "X")
9949			  (const_int 0)
9950			  (const_int 0))
9951	    (match_operand:P 2 "register_operand" "a")] UNSPEC_EXECUTE_JUMP)
9952   (set (pc) (match_operand:P 0 "register_operand" "a"))]
9953  "TARGET_INDIRECT_BRANCH_NOBP_JUMP_INLINE_THUNK
9954   && !TARGET_CPU_Z10"
9955{
9956  s390_indirect_branch_via_inline_thunk (operands[2]);
9957  return "";
9958}
9959  [(set_attr "op_type" "RX")
9960   (set_attr "type"    "branch")
9961   (set_attr "length"  "8")])
9962
9963; FIXME: LRA does not appear to be able to deal with MEMs being
9964; checked against address constraints like ZR above.  So make this a
9965; separate pattern for now.
9966(define_insn "*indirect2_jump"
9967  [(set (pc)
9968	(match_operand 0 "nonimmediate_operand" "a,T"))]
9969 "!TARGET_INDIRECT_BRANCH_NOBP_JUMP"
9970 "@
9971  br\t%0
9972  bi\t%0"
9973 [(set_attr "op_type" "RR,RXY")
9974  (set_attr "type"  "branch")
9975  (set_attr "atype" "agen")
9976  (set_attr "cpu_facility" "*,z14")])
9977
9978;
9979; casesi instruction pattern(s).
9980;
9981
9982(define_expand "casesi_jump"
9983  [(parallel
9984    [(set (pc) (match_operand 0 "address_operand"))
9985     (use (label_ref (match_operand 1 "")))])]
9986  ""
9987{
9988  if (TARGET_INDIRECT_BRANCH_NOBP_JUMP_THUNK)
9989    {
9990      operands[0] = force_reg (GET_MODE (operands[0]), operands[0]);
9991
9992      if (TARGET_CPU_Z10)
9993	{
9994	  if (TARGET_64BIT)
9995	    emit_jump_insn (gen_casesi_jump_via_thunkdi_z10 (operands[0],
9996							     operands[1]));
9997	  else
9998	    emit_jump_insn (gen_casesi_jump_via_thunksi_z10 (operands[0],
9999							     operands[1]));
10000	}
10001      else
10002	{
10003	  if (TARGET_64BIT)
10004	    emit_jump_insn (gen_casesi_jump_via_thunkdi (operands[0],
10005							 operands[1]));
10006	  else
10007	    emit_jump_insn (gen_casesi_jump_via_thunksi (operands[0],
10008							 operands[1]));
10009	}
10010      DONE;
10011    }
10012
10013    if (TARGET_INDIRECT_BRANCH_NOBP_JUMP_INLINE_THUNK)
10014    {
10015      operands[0] = force_reg (Pmode, operands[0]);
10016      rtx label_ref = gen_rtx_LABEL_REF (VOIDmode, gen_label_rtx ());
10017      if (TARGET_CPU_Z10)
10018	{
10019	  if (TARGET_64BIT)
10020	    emit_jump_insn (gen_casesi_jump_via_inlinethunkdi_z10 (operands[0],
10021								   operands[1],
10022								   label_ref));
10023	  else
10024	    emit_jump_insn (gen_casesi_jump_via_inlinethunksi_z10 (operands[0],
10025								   operands[1],
10026								   label_ref));
10027	}
10028      else
10029	{
10030	  if (TARGET_64BIT)
10031	    emit_jump_insn (gen_casesi_jump_via_inlinethunkdi (operands[0],
10032							       operands[1],
10033							       label_ref,
10034							       force_reg (Pmode, label_ref)));
10035	  else
10036	    emit_jump_insn (gen_casesi_jump_via_inlinethunksi (operands[0],
10037							       operands[1],
10038							       label_ref,
10039							       force_reg (Pmode, label_ref)));
10040	}
10041      DONE;
10042    }
10043})
10044
10045(define_insn "*casesi_jump"
10046 [(set (pc) (match_operand 0 "address_operand" "ZR"))
10047  (use (label_ref (match_operand 1 "" "")))]
10048 "!TARGET_INDIRECT_BRANCH_NOBP_JUMP_THUNK"
10049{
10050  if (get_attr_op_type (insn) == OP_TYPE_RR)
10051    return "br\t%0";
10052  else
10053    return "b\t%a0";
10054}
10055  [(set (attr "op_type")
10056        (if_then_else (match_operand 0 "register_operand" "")
10057                      (const_string "RR") (const_string "RX")))
10058   (set (attr "mnemonic")
10059        (if_then_else (match_operand 0 "register_operand" "")
10060                      (const_string "br") (const_string "b")))
10061   (set_attr "type"  "branch")
10062   (set_attr "atype" "agen")])
10063
10064(define_insn "casesi_jump_via_thunk<mode>_z10"
10065 [(set (pc) (match_operand:P 0 "register_operand" "a"))
10066  (use (label_ref (match_operand 1 "" "")))]
10067 "TARGET_INDIRECT_BRANCH_NOBP_JUMP_THUNK
10068  && TARGET_CPU_Z10"
10069{
10070  s390_indirect_branch_via_thunk (REGNO (operands[0]),
10071				  INVALID_REGNUM,
10072				  NULL_RTX,
10073				  s390_indirect_branch_type_jump);
10074  return "";
10075}
10076  [(set_attr "op_type" "RIL")
10077   (set_attr "mnemonic" "jg")
10078   (set_attr "type"  "branch")
10079   (set_attr "atype" "agen")])
10080
10081(define_insn "casesi_jump_via_thunk<mode>"
10082 [(set (pc) (match_operand:P 0 "register_operand" "a"))
10083  (use (label_ref (match_operand 1 "" "")))
10084  (clobber (reg:P INDIRECT_BRANCH_THUNK_REGNUM))]
10085 "TARGET_INDIRECT_BRANCH_NOBP_JUMP_THUNK
10086  && !TARGET_CPU_Z10"
10087{
10088  s390_indirect_branch_via_thunk (REGNO (operands[0]),
10089				  INVALID_REGNUM,
10090				  NULL_RTX,
10091				  s390_indirect_branch_type_jump);
10092  return "";
10093}
10094  [(set_attr "op_type" "RIL")
10095   (set_attr "mnemonic" "jg")
10096   (set_attr "type"  "branch")
10097   (set_attr "atype" "agen")])
10098
10099
10100; The label_ref is wrapped into an if_then_else in order to hide it
10101; from mark_jump_label.  Without this the label_ref would become the
10102; ONLY jump target of that jump breaking the control flow graph.
10103(define_insn "casesi_jump_via_inlinethunk<mode>_z10"
10104  [(unspec [(if_then_else (match_operand:P 2 "larl_operand" "X")
10105			  (const_int 0)
10106			  (const_int 0))
10107	    (const_int 0)] UNSPEC_EXECUTE_JUMP)
10108   (set (pc) (match_operand:P 0 "register_operand" "a"))
10109   (use (label_ref (match_operand 1 "" "")))]
10110  "TARGET_INDIRECT_BRANCH_NOBP_JUMP_INLINE_THUNK
10111   && TARGET_CPU_Z10"
10112{
10113  s390_indirect_branch_via_inline_thunk (operands[2]);
10114  return "";
10115}
10116  [(set_attr "op_type" "RIL")
10117   (set_attr "type"    "cs")
10118   (set_attr "length"  "10")])
10119
10120(define_insn "casesi_jump_via_inlinethunk<mode>"
10121  [(unspec [(if_then_else (match_operand:P 2 "larl_operand" "X")
10122			  (const_int 0)
10123			  (const_int 0))
10124	    (match_operand:P 3 "register_operand" "a")] UNSPEC_EXECUTE_JUMP)
10125   (set (pc) (match_operand:P 0 "register_operand" "a"))
10126   (use (label_ref (match_operand 1 "" "")))]
10127  "TARGET_INDIRECT_BRANCH_NOBP_JUMP_INLINE_THUNK
10128   && !TARGET_CPU_Z10"
10129{
10130  s390_indirect_branch_via_inline_thunk (operands[3]);
10131  return "";
10132}
10133  [(set_attr "op_type" "RX")
10134   (set_attr "type"    "cs")
10135   (set_attr "length"  "8")])
10136
10137(define_expand "casesi"
10138  [(match_operand:SI 0 "general_operand" "")
10139   (match_operand:SI 1 "general_operand" "")
10140   (match_operand:SI 2 "general_operand" "")
10141   (label_ref (match_operand 3 "" ""))
10142   (label_ref (match_operand 4 "" ""))]
10143  ""
10144{
10145   rtx index  = gen_reg_rtx (SImode);
10146   rtx base   = gen_reg_rtx (Pmode);
10147   rtx target = gen_reg_rtx (Pmode);
10148
10149   emit_move_insn (index, operands[0]);
10150   emit_insn (gen_subsi3 (index, index, operands[1]));
10151   emit_cmp_and_jump_insns (index, operands[2], GTU, NULL_RTX, SImode, 1,
10152                            operands[4]);
10153
10154   if (Pmode != SImode)
10155     index = convert_to_mode (Pmode, index, 1);
10156   if (GET_CODE (index) != REG)
10157     index = copy_to_mode_reg (Pmode, index);
10158
10159   if (TARGET_64BIT)
10160       emit_insn (gen_ashldi3 (index, index, GEN_INT (3)));
10161   else
10162       emit_insn (gen_ashlsi3 (index, index, const2_rtx));
10163
10164   emit_move_insn (base, gen_rtx_LABEL_REF (Pmode, operands[3]));
10165
10166   index = gen_const_mem (Pmode, gen_rtx_PLUS (Pmode, base, index));
10167   emit_move_insn (target, index);
10168
10169   if (flag_pic)
10170     target = gen_rtx_PLUS (Pmode, base, target);
10171   emit_jump_insn (gen_casesi_jump (target, operands[3]));
10172
10173   DONE;
10174})
10175
10176
10177;;
10178;;- Jump to subroutine.
10179;;
10180;;
10181
10182;
10183; untyped call instruction pattern(s).
10184;
10185
10186;; Call subroutine returning any type.
10187(define_expand "untyped_call"
10188  [(parallel [(call (match_operand 0 "" "")
10189                    (const_int 0))
10190              (match_operand 1 "" "")
10191              (match_operand 2 "" "")])]
10192  ""
10193{
10194  int i;
10195
10196  emit_call_insn (gen_call (operands[0], const0_rtx, const0_rtx));
10197
10198  for (i = 0; i < XVECLEN (operands[2], 0); i++)
10199    {
10200      rtx set = XVECEXP (operands[2], 0, i);
10201      emit_move_insn (SET_DEST (set), SET_SRC (set));
10202    }
10203
10204  /* The optimizer does not know that the call sets the function value
10205     registers we stored in the result block.  We avoid problems by
10206     claiming that all hard registers are used and clobbered at this
10207     point.  */
10208  emit_insn (gen_blockage ());
10209
10210  DONE;
10211})
10212
10213;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
10214;; all of memory.  This blocks insns from being moved across this point.
10215
10216(define_insn "blockage"
10217  [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
10218  ""
10219  ""
10220  [(set_attr "type"    "none")
10221   (set_attr "length"  "0")])
10222
10223;
10224; sibcall patterns
10225;
10226
10227(define_expand "sibcall"
10228  [(call (match_operand 0 "" "")
10229	 (match_operand 1 "" ""))]
10230  ""
10231{
10232  s390_emit_call (XEXP (operands[0], 0), NULL_RTX, NULL_RTX, NULL_RTX);
10233  DONE;
10234})
10235
10236(define_insn "*sibcall_br"
10237  [(call (mem:QI (reg SIBCALL_REGNUM))
10238         (match_operand 0 "const_int_operand" "n"))]
10239  "SIBLING_CALL_P (insn)
10240   && GET_MODE (XEXP (XEXP (PATTERN (insn), 0), 0)) == Pmode"
10241{
10242  if (TARGET_INDIRECT_BRANCH_NOBP_CALL)
10243    {
10244      gcc_assert (TARGET_CPU_Z10);
10245      s390_indirect_branch_via_thunk (SIBCALL_REGNUM,
10246				      INVALID_REGNUM,
10247				      NULL_RTX,
10248				      s390_indirect_branch_type_call);
10249      return "";
10250    }
10251  else
10252    return "br\t%%r1";
10253}
10254 [(set (attr "op_type")
10255       (if_then_else (match_test "TARGET_INDIRECT_BRANCH_NOBP_CALL")
10256		     (const_string "RIL")
10257		     (const_string "RR")))
10258  (set (attr "mnemonic")
10259       (if_then_else (match_test "TARGET_INDIRECT_BRANCH_NOBP_CALL")
10260		     (const_string "jg")
10261		     (const_string "br")))
10262   (set_attr "type"  "branch")
10263   (set_attr "atype" "agen")])
10264
10265(define_insn "*sibcall_brc"
10266  [(call (mem:QI (match_operand 0 "bras_sym_operand" "X"))
10267         (match_operand 1 "const_int_operand" "n"))]
10268  "SIBLING_CALL_P (insn) && TARGET_SMALL_EXEC"
10269  "j\t%0"
10270  [(set_attr "op_type" "RI")
10271   (set_attr "type"    "branch")])
10272
10273(define_insn "*sibcall_brcl"
10274  [(call (mem:QI (match_operand 0 "bras_sym_operand" "X"))
10275         (match_operand 1 "const_int_operand" "n"))]
10276  "SIBLING_CALL_P (insn)"
10277  "jg\t%0"
10278  [(set_attr "op_type" "RIL")
10279   (set_attr "type"    "branch")])
10280
10281;
10282; sibcall_value patterns
10283;
10284
10285(define_expand "sibcall_value"
10286  [(set (match_operand 0 "" "")
10287	(call (match_operand 1 "" "")
10288	      (match_operand 2 "" "")))]
10289  ""
10290{
10291  s390_emit_call (XEXP (operands[1], 0), NULL_RTX, operands[0], NULL_RTX);
10292  DONE;
10293})
10294
10295(define_insn "*sibcall_value_br"
10296  [(set (match_operand 0 "" "")
10297	(call (mem:QI (reg SIBCALL_REGNUM))
10298	      (match_operand 1 "const_int_operand" "n")))]
10299  "SIBLING_CALL_P (insn)
10300   && GET_MODE (XEXP (XEXP (XEXP (PATTERN (insn), 1), 0), 0)) == Pmode"
10301{
10302  if (TARGET_INDIRECT_BRANCH_NOBP_CALL)
10303    {
10304      gcc_assert (TARGET_CPU_Z10);
10305      s390_indirect_branch_via_thunk (SIBCALL_REGNUM,
10306				      INVALID_REGNUM,
10307				      NULL_RTX,
10308				      s390_indirect_branch_type_call);
10309      return "";
10310    }
10311  else
10312    return "br\t%%r1";
10313}
10314  [(set (attr "op_type")
10315       (if_then_else (match_test "TARGET_INDIRECT_BRANCH_NOBP_CALL")
10316		     (const_string "RIL")
10317		     (const_string "RR")))
10318   (set (attr "mnemonic")
10319       (if_then_else (match_test "TARGET_INDIRECT_BRANCH_NOBP_CALL")
10320		     (const_string "jg")
10321		     (const_string "br")))
10322   (set_attr "type"  "branch")
10323   (set_attr "atype" "agen")])
10324
10325(define_insn "*sibcall_value_brc"
10326  [(set (match_operand 0 "" "")
10327	(call (mem:QI (match_operand 1 "bras_sym_operand" "X"))
10328	      (match_operand 2 "const_int_operand" "n")))]
10329  "SIBLING_CALL_P (insn) && TARGET_SMALL_EXEC"
10330  "j\t%1"
10331  [(set_attr "op_type" "RI")
10332   (set_attr "type"    "branch")])
10333
10334(define_insn "*sibcall_value_brcl"
10335  [(set (match_operand 0 "" "")
10336	(call (mem:QI (match_operand 1 "bras_sym_operand" "X"))
10337	      (match_operand 2 "const_int_operand" "n")))]
10338  "SIBLING_CALL_P (insn)"
10339  "jg\t%1"
10340  [(set_attr "op_type" "RIL")
10341   (set_attr "type"    "branch")])
10342
10343
10344;
10345; call instruction pattern(s).
10346;
10347
10348(define_expand "call"
10349  [(call (match_operand 0 "" "")
10350         (match_operand 1 "" ""))
10351   (use (match_operand 2 "" ""))]
10352  ""
10353{
10354  s390_emit_call (XEXP (operands[0], 0), NULL_RTX, NULL_RTX,
10355		  gen_rtx_REG (Pmode, RETURN_REGNUM));
10356  DONE;
10357})
10358
10359(define_insn "*bras"
10360  [(call (mem:QI (match_operand 0 "bras_sym_operand" "X"))
10361         (match_operand 1 "const_int_operand" "n"))
10362   (clobber (match_operand 2 "register_operand" "=r"))]
10363  "!SIBLING_CALL_P (insn)
10364   && TARGET_SMALL_EXEC
10365   && GET_MODE (operands[2]) == Pmode"
10366  "bras\t%2,%0"
10367  [(set_attr "op_type" "RI")
10368   (set_attr "type"    "jsr")
10369   (set_attr "z196prop" "z196_cracked")])
10370
10371(define_insn "*brasl"
10372  [(call (mem:QI (match_operand 0 "bras_sym_operand" "X"))
10373         (match_operand 1 "const_int_operand" "n"))
10374   (clobber (match_operand 2 "register_operand" "=r"))]
10375  "!SIBLING_CALL_P (insn)
10376
10377   && GET_MODE (operands[2]) == Pmode"
10378  "brasl\t%2,%0"
10379  [(set_attr "op_type" "RIL")
10380   (set_attr "type"    "jsr")
10381   (set_attr "z196prop" "z196_cracked")
10382   (set_attr "relative_long" "yes")])
10383
10384(define_insn "*basr"
10385  [(call (mem:QI (match_operand 0 "address_operand" "ZR"))
10386         (match_operand 1 "const_int_operand" "n"))
10387   (clobber (match_operand 2 "register_operand" "=r"))]
10388  "!TARGET_INDIRECT_BRANCH_NOBP_CALL
10389   && !SIBLING_CALL_P (insn)
10390   && GET_MODE (operands[2]) == Pmode"
10391{
10392  if (get_attr_op_type (insn) == OP_TYPE_RR)
10393    return "basr\t%2,%0";
10394  else
10395    return "bas\t%2,%a0";
10396}
10397  [(set (attr "op_type")
10398        (if_then_else (match_operand 0 "register_operand" "")
10399                      (const_string "RR") (const_string "RX")))
10400   (set (attr "mnemonic")
10401        (if_then_else (match_operand 0 "register_operand" "")
10402                      (const_string "basr") (const_string "bas")))
10403   (set_attr "type"  "jsr")
10404   (set_attr "atype" "agen")
10405   (set_attr "z196prop" "z196_cracked")])
10406
10407(define_insn "*basr_via_thunk<mode>_z10"
10408  [(call (mem:QI (match_operand:P 0 "register_operand" "a"))
10409         (match_operand 1 "const_int_operand"          "n"))
10410   (clobber (match_operand:P 2 "register_operand"    "=&r"))]
10411  "TARGET_INDIRECT_BRANCH_NOBP_CALL
10412   && TARGET_CPU_Z10
10413   && !SIBLING_CALL_P (insn)"
10414{
10415  s390_indirect_branch_via_thunk (REGNO (operands[0]),
10416				  REGNO (operands[2]),
10417				  NULL_RTX,
10418				  s390_indirect_branch_type_call);
10419  return "";
10420}
10421  [(set_attr "op_type" "RIL")
10422   (set_attr "mnemonic" "brasl")
10423   (set_attr "type"  "jsr")
10424   (set_attr "atype" "agen")
10425   (set_attr "z196prop" "z196_cracked")])
10426
10427(define_insn "*basr_via_thunk<mode>"
10428  [(call (mem:QI (match_operand:P 0 "register_operand" "a"))
10429         (match_operand 1 "const_int_operand"          "n"))
10430   (clobber (match_operand:P 2 "register_operand"    "=&r"))
10431   (clobber (reg:P INDIRECT_BRANCH_THUNK_REGNUM))]
10432  "TARGET_INDIRECT_BRANCH_NOBP_CALL
10433   && !TARGET_CPU_Z10
10434   && !SIBLING_CALL_P (insn)"
10435{
10436  s390_indirect_branch_via_thunk (REGNO (operands[0]),
10437				  REGNO (operands[2]),
10438				  NULL_RTX,
10439				  s390_indirect_branch_type_call);
10440  return "";
10441}
10442  [(set_attr "op_type" "RIL")
10443   (set_attr "mnemonic" "brasl")
10444   (set_attr "type"  "jsr")
10445   (set_attr "atype" "agen")
10446   (set_attr "z196prop" "z196_cracked")])
10447
10448;
10449; call_value instruction pattern(s).
10450;
10451
10452(define_expand "call_value"
10453  [(set (match_operand 0 "" "")
10454        (call (match_operand 1 "" "")
10455              (match_operand 2 "" "")))
10456   (use (match_operand 3 "" ""))]
10457  ""
10458{
10459  s390_emit_call (XEXP (operands[1], 0), NULL_RTX, operands[0],
10460		  gen_rtx_REG (Pmode, RETURN_REGNUM));
10461  DONE;
10462})
10463
10464(define_insn "*bras_r"
10465  [(set (match_operand 0 "" "")
10466        (call (mem:QI (match_operand 1 "bras_sym_operand" "X"))
10467              (match_operand:SI 2 "const_int_operand" "n")))
10468   (clobber (match_operand 3 "register_operand" "=r"))]
10469  "!SIBLING_CALL_P (insn)
10470   && TARGET_SMALL_EXEC
10471   && GET_MODE (operands[3]) == Pmode"
10472  "bras\t%3,%1"
10473  [(set_attr "op_type" "RI")
10474   (set_attr "type"    "jsr")
10475   (set_attr "z196prop" "z196_cracked")])
10476
10477(define_insn "*brasl_r"
10478  [(set (match_operand 0 "" "")
10479        (call (mem:QI (match_operand 1 "bras_sym_operand" "X"))
10480              (match_operand 2 "const_int_operand" "n")))
10481   (clobber (match_operand 3 "register_operand" "=r"))]
10482  "!SIBLING_CALL_P (insn)
10483
10484   && GET_MODE (operands[3]) == Pmode"
10485  "brasl\t%3,%1"
10486  [(set_attr "op_type" "RIL")
10487   (set_attr "type"    "jsr")
10488   (set_attr "z196prop" "z196_cracked")
10489   (set_attr "relative_long" "yes")])
10490
10491(define_insn "*basr_r"
10492  [(set (match_operand 0 "" "")
10493        (call (mem:QI (match_operand 1 "address_operand" "ZR"))
10494              (match_operand 2 "const_int_operand" "n")))
10495   (clobber (match_operand 3 "register_operand" "=r"))]
10496  "!TARGET_INDIRECT_BRANCH_NOBP_CALL
10497   && !SIBLING_CALL_P (insn)
10498   && GET_MODE (operands[3]) == Pmode"
10499{
10500  if (get_attr_op_type (insn) == OP_TYPE_RR)
10501    return "basr\t%3,%1";
10502  else
10503    return "bas\t%3,%a1";
10504}
10505  [(set (attr "op_type")
10506        (if_then_else (match_operand 1 "register_operand" "")
10507                      (const_string "RR") (const_string "RX")))
10508   (set (attr "mnemonic")
10509        (if_then_else (match_operand 1 "register_operand" "")
10510                      (const_string "basr") (const_string "bas")))
10511   (set_attr "type"  "jsr")
10512   (set_attr "atype" "agen")
10513   (set_attr "z196prop" "z196_cracked")])
10514
10515(define_insn "*basr_r_via_thunk_z10"
10516  [(set (match_operand 0 "" "")
10517        (call (mem:QI (match_operand 1 "register_operand" "a"))
10518              (match_operand 2 "const_int_operand"        "n")))
10519   (clobber (match_operand 3 "register_operand"         "=&r"))]
10520  "TARGET_INDIRECT_BRANCH_NOBP_CALL
10521   && TARGET_CPU_Z10
10522   && !SIBLING_CALL_P (insn)
10523   && GET_MODE (operands[3]) == Pmode"
10524{
10525  s390_indirect_branch_via_thunk (REGNO (operands[1]),
10526				  REGNO (operands[3]),
10527				  NULL_RTX,
10528				  s390_indirect_branch_type_call);
10529  return "";
10530}
10531  [(set_attr "op_type" "RIL")
10532   (set_attr "mnemonic" "brasl")
10533   (set_attr "type"  "jsr")
10534   (set_attr "atype" "agen")
10535   (set_attr "z196prop" "z196_cracked")])
10536
10537(define_insn "*basr_r_via_thunk"
10538  [(set (match_operand 0 "" "")
10539        (call (mem:QI (match_operand 1 "register_operand" "a"))
10540              (match_operand 2 "const_int_operand"        "n")))
10541   (clobber (match_operand 3 "register_operand"         "=&r"))
10542   (clobber (reg:P INDIRECT_BRANCH_THUNK_REGNUM))]
10543  "TARGET_INDIRECT_BRANCH_NOBP_CALL
10544   && !TARGET_CPU_Z10
10545   && !SIBLING_CALL_P (insn)
10546   && GET_MODE (operands[3]) == Pmode"
10547{
10548  s390_indirect_branch_via_thunk (REGNO (operands[1]),
10549				  REGNO (operands[3]),
10550				  NULL_RTX,
10551				  s390_indirect_branch_type_call);
10552  return "";
10553}
10554  [(set_attr "op_type" "RIL")
10555   (set_attr "mnemonic"  "brasl")
10556   (set_attr "type"  "jsr")
10557   (set_attr "atype" "agen")
10558   (set_attr "z196prop" "z196_cracked")])
10559
10560;;
10561;;- Thread-local storage support.
10562;;
10563
10564(define_expand "@get_thread_pointer<mode>"
10565  [(set (match_operand:P 0 "nonimmediate_operand" "")
10566	(unspec:P [(reg:P TP_REGNUM)] UNSPEC_GET_TP))]
10567  ""
10568  "")
10569
10570(define_expand "set_thread_pointer<mode>"
10571  [(set (reg:P TP_REGNUM) (match_operand:P 0 "nonimmediate_operand" ""))
10572   (set (reg:P TP_REGNUM) (unspec_volatile:P [(reg:P TP_REGNUM)] UNSPECV_SET_TP))]
10573  ""
10574  "")
10575
10576(define_insn "*set_tp"
10577  [(set (reg TP_REGNUM) (unspec_volatile [(reg TP_REGNUM)] UNSPECV_SET_TP))]
10578  ""
10579  ""
10580  [(set_attr "type" "none")
10581   (set_attr "length" "0")])
10582
10583(define_insn "*tls_load_64"
10584  [(set (match_operand:DI 0 "register_operand" "=d")
10585        (unspec:DI [(match_operand:DI 1 "memory_operand" "T")
10586                    (match_operand:DI 2 "" "")]
10587		   UNSPEC_TLS_LOAD))]
10588  "TARGET_64BIT"
10589  "lg\t%0,%1%J2"
10590  [(set_attr "op_type" "RXE")
10591   (set_attr "z10prop" "z10_fwd_A3")])
10592
10593(define_insn "*tls_load_31"
10594  [(set (match_operand:SI 0 "register_operand" "=d,d")
10595        (unspec:SI [(match_operand:SI 1 "memory_operand" "R,T")
10596                    (match_operand:SI 2 "" "")]
10597		   UNSPEC_TLS_LOAD))]
10598  "!TARGET_64BIT"
10599  "@
10600   l\t%0,%1%J2
10601   ly\t%0,%1%J2"
10602  [(set_attr "op_type" "RX,RXY")
10603   (set_attr "type" "load")
10604   (set_attr "cpu_facility" "*,longdisp")
10605   (set_attr "z10prop" "z10_fwd_A3,z10_fwd_A3")])
10606
10607(define_insn "*bras_tls"
10608  [(set (match_operand 0 "" "")
10609        (call (mem:QI (match_operand 1 "bras_sym_operand" "X"))
10610              (match_operand 2 "const_int_operand" "n")))
10611   (clobber (match_operand 3 "register_operand" "=r"))
10612   (use (match_operand 4 "" ""))]
10613  "!SIBLING_CALL_P (insn)
10614   && TARGET_SMALL_EXEC
10615   && GET_MODE (operands[3]) == Pmode"
10616  "bras\t%3,%1%J4"
10617  [(set_attr "op_type" "RI")
10618   (set_attr "type"    "jsr")
10619   (set_attr "z196prop" "z196_cracked")])
10620
10621(define_insn "*brasl_tls"
10622  [(set (match_operand 0 "" "")
10623        (call (mem:QI (match_operand 1 "bras_sym_operand" "X"))
10624              (match_operand 2 "const_int_operand" "n")))
10625   (clobber (match_operand 3 "register_operand" "=r"))
10626   (use (match_operand 4 "" ""))]
10627  "!SIBLING_CALL_P (insn)
10628
10629   && GET_MODE (operands[3]) == Pmode"
10630  "brasl\t%3,%1%J4"
10631  [(set_attr "op_type" "RIL")
10632   (set_attr "type"    "jsr")
10633   (set_attr "z196prop" "z196_cracked")
10634   (set_attr "relative_long" "yes")])
10635
10636(define_insn "*basr_tls"
10637  [(set (match_operand 0 "" "")
10638        (call (mem:QI (match_operand 1 "address_operand" "ZR"))
10639              (match_operand 2 "const_int_operand" "n")))
10640   (clobber (match_operand 3 "register_operand" "=r"))
10641   (use (match_operand 4 "" ""))]
10642  "!SIBLING_CALL_P (insn) && GET_MODE (operands[3]) == Pmode"
10643{
10644  if (get_attr_op_type (insn) == OP_TYPE_RR)
10645    return "basr\t%3,%1%J4";
10646  else
10647    return "bas\t%3,%a1%J4";
10648}
10649  [(set (attr "op_type")
10650        (if_then_else (match_operand 1 "register_operand" "")
10651                      (const_string "RR") (const_string "RX")))
10652   (set_attr "type"  "jsr")
10653   (set_attr "atype" "agen")
10654   (set_attr "z196prop" "z196_cracked")])
10655
10656;;
10657;;- Atomic operations
10658;;
10659
10660;
10661; memory barrier patterns.
10662;
10663
10664(define_expand "mem_thread_fence"
10665  [(match_operand:SI 0 "const_int_operand")]		;; model
10666  ""
10667{
10668  /* Unless this is a SEQ_CST fence, the s390 memory model is strong
10669     enough not to require barriers of any kind.  */
10670  if (is_mm_seq_cst (memmodel_from_int (INTVAL (operands[0]))))
10671    {
10672      rtx mem = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
10673      MEM_VOLATILE_P (mem) = 1;
10674      emit_insn (gen_mem_thread_fence_1 (mem));
10675    }
10676  DONE;
10677})
10678
10679; Although bcr is superscalar on Z10, this variant will never
10680; become part of an execution group.
10681; With z196 we can make use of the fast-BCR-serialization facility.
10682; This allows for a slightly faster sync which is sufficient for our
10683; purposes.
10684(define_insn "mem_thread_fence_1"
10685  [(set (match_operand:BLK 0 "" "")
10686	(unspec:BLK [(match_dup 0)] UNSPEC_MB))]
10687  ""
10688{
10689  if (TARGET_Z196)
10690    return "bcr\t14,0";
10691  else
10692    return "bcr\t15,0";
10693}
10694  [(set_attr "op_type" "RR")
10695   (set_attr "mnemonic" "bcr_flush")
10696   (set_attr "z196prop" "z196_alone")])
10697
10698;
10699; atomic load/store operations
10700;
10701
10702; Atomic loads need not examine the memory model at all.
10703(define_expand "atomic_load<mode>"
10704  [(match_operand:DINT 0 "register_operand")	;; output
10705   (match_operand:DINT 1 "memory_operand")	;; memory
10706   (match_operand:SI 2 "const_int_operand")]	;; model
10707  ""
10708{
10709  if (MEM_ALIGN (operands[1]) < GET_MODE_BITSIZE (GET_MODE (operands[1])))
10710    FAIL;
10711
10712  if (<MODE>mode == TImode)
10713    emit_insn (gen_atomic_loadti_1 (operands[0], operands[1]));
10714  else if (<MODE>mode == DImode && !TARGET_ZARCH)
10715    emit_insn (gen_atomic_loaddi_1 (operands[0], operands[1]));
10716  else
10717    emit_move_insn (operands[0], operands[1]);
10718  DONE;
10719})
10720
10721; Different from movdi_31 in that we want no splitters.
10722(define_insn "atomic_loaddi_1"
10723  [(set (match_operand:DI 0 "register_operand" "=d,d,!*f,!*f")
10724	(unspec:DI [(match_operand:DI 1 "memory_operand" "Q,S,R,T")]
10725		   UNSPEC_MOVA))]
10726  "!TARGET_ZARCH"
10727  "@
10728   lm\t%0,%M0,%S1
10729   lmy\t%0,%M0,%S1
10730   ld\t%0,%1
10731   ldy\t%0,%1"
10732  [(set_attr "op_type" "RS,RSY,RS,RSY")
10733   (set_attr "cpu_facility" "*,longdisp,*,longdisp")
10734   (set_attr "type" "lm,lm,floaddf,floaddf")])
10735
10736(define_insn "atomic_loadti_1"
10737  [(set (match_operand:TI 0 "register_operand" "=r")
10738	(unspec:TI [(match_operand:TI 1 "memory_operand" "T")]
10739		   UNSPEC_MOVA))]
10740  "TARGET_ZARCH"
10741  "lpq\t%0,%1"
10742  [(set_attr "op_type" "RXY")
10743   (set_attr "type" "other")])
10744
10745; Atomic stores must(?) enforce sequential consistency.
10746(define_expand "atomic_store<mode>"
10747  [(match_operand:DINT 0 "memory_operand")	;; memory
10748   (match_operand:DINT 1 "register_operand")	;; input
10749   (match_operand:SI 2 "const_int_operand")]	;; model
10750  ""
10751{
10752  enum memmodel model = memmodel_from_int (INTVAL (operands[2]));
10753
10754  if (MEM_ALIGN (operands[0]) < GET_MODE_BITSIZE (GET_MODE (operands[0])))
10755    FAIL;
10756
10757  if (<MODE>mode == TImode)
10758    emit_insn (gen_atomic_storeti_1 (operands[0], operands[1]));
10759  else if (<MODE>mode == DImode && !TARGET_ZARCH)
10760    emit_insn (gen_atomic_storedi_1 (operands[0], operands[1]));
10761  else
10762    emit_move_insn (operands[0], operands[1]);
10763  if (is_mm_seq_cst (model))
10764    emit_insn (gen_mem_thread_fence (operands[2]));
10765  DONE;
10766})
10767
10768; Different from movdi_31 in that we want no splitters.
10769(define_insn "atomic_storedi_1"
10770  [(set (match_operand:DI 0 "memory_operand" "=Q,S,R,T")
10771	(unspec:DI [(match_operand:DI 1 "register_operand" "d,d,!*f,!*f")]
10772		   UNSPEC_MOVA))]
10773  "!TARGET_ZARCH"
10774  "@
10775   stm\t%1,%N1,%S0
10776   stmy\t%1,%N1,%S0
10777   std %1,%0
10778   stdy %1,%0"
10779  [(set_attr "op_type" "RS,RSY,RS,RSY")
10780   (set_attr "cpu_facility" "*,longdisp,*,longdisp")
10781   (set_attr "type" "stm,stm,fstoredf,fstoredf")])
10782
10783(define_insn "atomic_storeti_1"
10784  [(set (match_operand:TI 0 "memory_operand" "=T")
10785	(unspec:TI [(match_operand:TI 1 "register_operand" "r")]
10786		   UNSPEC_MOVA))]
10787  "TARGET_ZARCH"
10788  "stpq\t%1,%0"
10789  [(set_attr "op_type" "RXY")
10790   (set_attr "type" "other")])
10791
10792;
10793; compare and swap patterns.
10794;
10795
10796(define_expand "atomic_compare_and_swap<mode>"
10797  [(match_operand:SI 0 "register_operand")	;; bool success output
10798   (match_operand:DINT 1 "nonimmediate_operand");; oldval output
10799   (match_operand:DINT 2 "s_operand")		;; memory
10800   (match_operand:DINT 3 "general_operand")	;; expected intput
10801   (match_operand:DINT 4 "general_operand")	;; newval intput
10802   (match_operand:SI 5 "const_int_operand")	;; is_weak
10803   (match_operand:SI 6 "const_int_operand")	;; success model
10804   (match_operand:SI 7 "const_int_operand")]	;; failure model
10805  ""
10806{
10807  if (GET_MODE_BITSIZE (<MODE>mode) >= 16
10808      && GET_MODE_BITSIZE (<MODE>mode) > MEM_ALIGN (operands[2]))
10809    FAIL;
10810
10811  s390_expand_cs (<MODE>mode, operands[0], operands[1], operands[2],
10812		  operands[3], operands[4], INTVAL (operands[5]));
10813  DONE;})
10814
10815(define_expand "atomic_compare_and_swap<mode>_internal"
10816  [(parallel
10817     [(set (match_operand:DGPR 0 "register_operand")
10818	   (match_operand:DGPR 1 "s_operand"))
10819      (set (match_dup 1)
10820	   (unspec_volatile:DGPR
10821	     [(match_dup 1)
10822	      (match_operand:DGPR 2 "register_operand")
10823	      (match_operand:DGPR 3 "register_operand")]
10824	     UNSPECV_CAS))
10825      (set (match_operand 4 "cc_reg_operand")
10826	   (match_dup 5))])]
10827  "GET_MODE (operands[4]) == CCZmode
10828   || GET_MODE (operands[4]) == CCZ1mode"
10829{
10830  operands[5]
10831    = gen_rtx_COMPARE (GET_MODE (operands[4]), operands[1], operands[2]);
10832})
10833
10834; cdsg, csg
10835(define_insn "*atomic_compare_and_swap<mode>_1"
10836  [(set (match_operand:TDI 0 "register_operand" "=r")
10837	(match_operand:TDI 1 "nonsym_memory_operand" "+S"))
10838   (set (match_dup 1)
10839	(unspec_volatile:TDI
10840	  [(match_dup 1)
10841	   (match_operand:TDI 2 "register_operand" "0")
10842	   (match_operand:TDI 3 "register_operand" "r")]
10843	  UNSPECV_CAS))
10844   (set (reg CC_REGNUM)
10845	(compare (match_dup 1) (match_dup 2)))]
10846  "TARGET_ZARCH
10847   && s390_match_ccmode (insn, CCZ1mode)"
10848  "c<td>sg\t%0,%3,%S1"
10849  [(set_attr "op_type" "RSY")
10850   (set_attr "type"   "sem")])
10851
10852; cds, cdsy
10853(define_insn "*atomic_compare_and_swapdi_2"
10854  [(set (match_operand:DI 0 "register_operand" "=r,r")
10855	(match_operand:DI 1 "nonsym_memory_operand" "+Q,S"))
10856   (set (match_dup 1)
10857	(unspec_volatile:DI
10858	  [(match_dup 1)
10859	   (match_operand:DI 2 "register_operand" "0,0")
10860	   (match_operand:DI 3 "register_operand" "r,r")]
10861	  UNSPECV_CAS))
10862   (set (reg CC_REGNUM)
10863	(compare (match_dup 1) (match_dup 2)))]
10864  "!TARGET_ZARCH
10865   && s390_match_ccmode (insn, CCZ1mode)"
10866  "@
10867   cds\t%0,%3,%S1
10868   cdsy\t%0,%3,%S1"
10869  [(set_attr "op_type" "RS,RSY")
10870   (set_attr "cpu_facility" "*,longdisp")
10871   (set_attr "type" "sem")])
10872
10873; cs, csy
10874(define_insn "*atomic_compare_and_swapsi_3"
10875  [(set (match_operand:SI 0 "register_operand" "=r,r")
10876	(match_operand:SI 1 "nonsym_memory_operand" "+Q,S"))
10877   (set (match_dup 1)
10878	(unspec_volatile:SI
10879	  [(match_dup 1)
10880	   (match_operand:SI 2 "register_operand" "0,0")
10881	   (match_operand:SI 3 "register_operand" "r,r")]
10882	  UNSPECV_CAS))
10883   (set (reg CC_REGNUM)
10884	(compare (match_dup 1) (match_dup 2)))]
10885  "s390_match_ccmode (insn, CCZ1mode)"
10886  "@
10887   cs\t%0,%3,%S1
10888   csy\t%0,%3,%S1"
10889  [(set_attr "op_type" "RS,RSY")
10890   (set_attr "cpu_facility" "*,longdisp")
10891   (set_attr "type"   "sem")])
10892
10893;
10894; Other atomic instruction patterns.
10895;
10896
10897; z196 load and add, xor, or and and instructions
10898
10899(define_expand "atomic_fetch_<atomic><mode>"
10900  [(match_operand:GPR 0 "register_operand")		;; val out
10901   (ATOMIC_Z196:GPR
10902     (match_operand:GPR 1 "memory_operand")		;; memory
10903     (match_operand:GPR 2 "register_operand"))		;; val in
10904   (match_operand:SI 3 "const_int_operand")]		;; model
10905  "TARGET_Z196"
10906{
10907  if (MEM_ALIGN (operands[1]) < GET_MODE_BITSIZE (GET_MODE (operands[1])))
10908    FAIL;
10909
10910  emit_insn (gen_atomic_fetch_<atomic><mode>_iaf
10911	     (operands[0], operands[1], operands[2]));
10912  DONE;
10913})
10914
10915; lan, lang, lao, laog, lax, laxg, laa, laag
10916(define_insn "atomic_fetch_<atomic><mode>_iaf"
10917  [(set (match_operand:GPR 0 "register_operand" "=d")
10918	(match_operand:GPR 1 "memory_operand" "+S"))
10919   (set (match_dup 1)
10920	(unspec_volatile:GPR
10921	 [(ATOMIC_Z196:GPR (match_dup 1)
10922			   (match_operand:GPR 2 "general_operand" "d"))]
10923	 UNSPECV_ATOMIC_OP))
10924   (clobber (reg:CC CC_REGNUM))]
10925  "TARGET_Z196"
10926  "la<noxa><g>\t%0,%2,%1"
10927  [(set_attr "op_type" "RSY")
10928   (set_attr "type" "sem")])
10929
10930;; For SImode and larger, the optabs.c code will do just fine in
10931;; expanding a compare-and-swap loop.  For QI/HImode, we can do
10932;; better by expanding our own loop.
10933
10934(define_expand "atomic_<atomic><mode>"
10935  [(ATOMIC:HQI
10936     (match_operand:HQI 0 "memory_operand")		;; memory
10937     (match_operand:HQI 1 "general_operand"))		;; val in
10938   (match_operand:SI 2 "const_int_operand")]		;; model
10939  ""
10940{
10941  s390_expand_atomic (<MODE>mode, <CODE>, NULL_RTX, operands[0],
10942		       operands[1], false);
10943  DONE;
10944})
10945
10946(define_expand "atomic_fetch_<atomic><mode>"
10947  [(match_operand:HQI 0 "register_operand")		;; val out
10948   (ATOMIC:HQI
10949     (match_operand:HQI 1 "memory_operand")		;; memory
10950     (match_operand:HQI 2 "general_operand"))		;; val in
10951   (match_operand:SI 3 "const_int_operand")]		;; model
10952  ""
10953{
10954  s390_expand_atomic (<MODE>mode, <CODE>, operands[0], operands[1],
10955		      operands[2], false);
10956  DONE;
10957})
10958
10959(define_expand "atomic_<atomic>_fetch<mode>"
10960  [(match_operand:HQI 0 "register_operand")		;; val out
10961   (ATOMIC:HQI
10962     (match_operand:HQI 1 "memory_operand")		;; memory
10963     (match_operand:HQI 2 "general_operand"))		;; val in
10964   (match_operand:SI 3 "const_int_operand")]		;; model
10965  ""
10966{
10967  s390_expand_atomic (<MODE>mode, <CODE>, operands[0], operands[1],
10968		      operands[2], true);
10969  DONE;
10970})
10971
10972;; Pattern to implement atomic_exchange with a compare-and-swap loop.  The code
10973;; generated by the middleend is not good.
10974(define_expand "atomic_exchange<mode>"
10975  [(match_operand:DINT 0 "register_operand")		;; val out
10976   (match_operand:DINT 1 "s_operand")			;; memory
10977   (match_operand:DINT 2 "general_operand")		;; val in
10978   (match_operand:SI 3 "const_int_operand")]		;; model
10979  ""
10980{
10981  if (<MODE>mode != QImode
10982      && MEM_ALIGN (operands[1]) < GET_MODE_BITSIZE (<MODE>mode))
10983    FAIL;
10984  if (<MODE>mode == HImode || <MODE>mode == QImode)
10985    s390_expand_atomic (<MODE>mode, SET, operands[0], operands[1], operands[2],
10986			false);
10987  else if (<MODE>mode == SImode || TARGET_ZARCH)
10988    s390_expand_atomic_exchange_tdsi (operands[0], operands[1], operands[2]);
10989  else
10990    FAIL;
10991  DONE;
10992})
10993
10994;;
10995;;- Miscellaneous instructions.
10996;;
10997
10998;
10999; allocate stack instruction pattern(s).
11000;
11001
11002(define_expand "allocate_stack"
11003  [(match_operand 0 "general_operand" "")
11004   (match_operand 1 "general_operand" "")]
11005 "TARGET_BACKCHAIN"
11006{
11007  rtx temp = gen_reg_rtx (Pmode);
11008
11009  emit_move_insn (temp, s390_back_chain_rtx ());
11010  anti_adjust_stack (operands[1]);
11011  emit_move_insn (s390_back_chain_rtx (), temp);
11012
11013  emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
11014  DONE;
11015})
11016
11017
11018;
11019; setjmp instruction pattern.
11020;
11021
11022(define_expand "builtin_setjmp_receiver"
11023  [(match_operand 0 "" "")]
11024  "flag_pic"
11025{
11026  emit_insn (s390_load_got ());
11027  emit_use (pic_offset_table_rtx);
11028  DONE;
11029})
11030
11031;; These patterns say how to save and restore the stack pointer.  We need not
11032;; save the stack pointer at function level since we are careful to
11033;; preserve the backchain.  At block level, we have to restore the backchain
11034;; when we restore the stack pointer.
11035;;
11036;; For nonlocal gotos, we must save both the stack pointer and its
11037;; backchain and restore both.  Note that in the nonlocal case, the
11038;; save area is a memory location.
11039
11040(define_expand "save_stack_function"
11041  [(match_operand 0 "general_operand" "")
11042   (match_operand 1 "general_operand" "")]
11043  ""
11044  "DONE;")
11045
11046(define_expand "restore_stack_function"
11047  [(match_operand 0 "general_operand" "")
11048   (match_operand 1 "general_operand" "")]
11049  ""
11050  "DONE;")
11051
11052(define_expand "restore_stack_block"
11053  [(match_operand 0 "register_operand" "")
11054   (match_operand 1 "register_operand" "")]
11055  "TARGET_BACKCHAIN"
11056{
11057  rtx temp = gen_reg_rtx (Pmode);
11058
11059  emit_move_insn (temp, s390_back_chain_rtx ());
11060  emit_move_insn (operands[0], operands[1]);
11061  emit_move_insn (s390_back_chain_rtx (), temp);
11062
11063  DONE;
11064})
11065
11066(define_expand "save_stack_nonlocal"
11067  [(match_operand 0 "memory_operand" "")
11068   (match_operand 1 "register_operand" "")]
11069  ""
11070{
11071  rtx base = gen_rtx_REG (Pmode, BASE_REGNUM);
11072
11073  /* Copy the backchain to the first word, sp to the second and the
11074     literal pool base to the third.  */
11075
11076  rtx save_bc = adjust_address (operands[0], Pmode, 0);
11077  rtx save_sp = adjust_address (operands[0], Pmode, GET_MODE_SIZE (Pmode));
11078  rtx save_bp = adjust_address (operands[0], Pmode, 2 * GET_MODE_SIZE (Pmode));
11079
11080  if (TARGET_BACKCHAIN)
11081    emit_move_insn (save_bc, force_reg (Pmode, s390_back_chain_rtx ()));
11082
11083  emit_move_insn (save_sp, operands[1]);
11084  emit_move_insn (save_bp, base);
11085
11086  DONE;
11087})
11088
11089(define_expand "restore_stack_nonlocal"
11090  [(match_operand 0 "register_operand" "")
11091   (match_operand 1 "memory_operand" "")]
11092  ""
11093{
11094  rtx base = gen_rtx_REG (Pmode, BASE_REGNUM);
11095  rtx temp = NULL_RTX;
11096
11097  /* Restore the backchain from the first word, sp from the second and the
11098     literal pool base from the third.  */
11099
11100  rtx save_bc = adjust_address (operands[1], Pmode, 0);
11101  rtx save_sp = adjust_address (operands[1], Pmode, GET_MODE_SIZE (Pmode));
11102  rtx save_bp = adjust_address (operands[1], Pmode, 2 * GET_MODE_SIZE (Pmode));
11103
11104  if (TARGET_BACKCHAIN)
11105    temp = force_reg (Pmode, save_bc);
11106
11107  emit_move_insn (base, save_bp);
11108  emit_move_insn (operands[0], save_sp);
11109
11110  if (temp)
11111    emit_move_insn (s390_back_chain_rtx (), temp);
11112
11113  emit_use (base);
11114  DONE;
11115})
11116
11117(define_expand "exception_receiver"
11118  [(const_int 0)]
11119  ""
11120{
11121  s390_set_has_landing_pad_p (true);
11122  DONE;
11123})
11124
11125;
11126; nop instruction pattern(s).
11127;
11128
11129(define_insn "nop"
11130  [(const_int 0)]
11131  ""
11132  "nopr\t%%r0"
11133  [(set_attr "op_type" "RR")])
11134
11135; non-branch NOPs required for optimizing compare-and-branch patterns
11136; on z10
11137
11138(define_insn "nop_lr0"
11139  [(unspec_volatile [(const_int 0)] UNSPECV_NOP_LR_0)]
11140  ""
11141  "lr\t0,0"
11142  [(set_attr "op_type" "RR")
11143   (set_attr "z10prop"  "z10_fr_E1")])
11144
11145(define_insn "nop_lr1"
11146  [(unspec_volatile [(const_int 0)] UNSPECV_NOP_LR_1)]
11147  ""
11148  "lr\t1,1"
11149  [(set_attr "op_type" "RR")])
11150
11151;;- Undeletable nops (used for hotpatching)
11152
11153(define_insn "nop_2_byte"
11154  [(unspec_volatile [(const_int 0)] UNSPECV_NOP_2_BYTE)]
11155  ""
11156  "nopr\t%%r0"
11157  [(set_attr "op_type" "RR")])
11158
11159(define_insn "nop_4_byte"
11160  [(unspec_volatile [(const_int 0)] UNSPECV_NOP_4_BYTE)]
11161  ""
11162  "nop\t0"
11163  [(set_attr "op_type" "RX")])
11164
11165(define_insn "nop_6_byte"
11166  [(unspec_volatile [(const_int 0)] UNSPECV_NOP_6_BYTE)]
11167  ""
11168  "brcl\t0, 0"
11169  [(set_attr "op_type" "RIL")
11170   (set_attr "relative_long" "yes")])
11171
11172
11173;
11174; Special literal pool access instruction pattern(s).
11175;
11176
11177(define_insn "*pool_entry"
11178  [(unspec_volatile [(match_operand 0 "consttable_operand" "X")]
11179                    UNSPECV_POOL_ENTRY)]
11180  ""
11181{
11182  machine_mode mode = GET_MODE (PATTERN (insn));
11183  unsigned int align = GET_MODE_BITSIZE (mode);
11184  s390_output_pool_entry (operands[0], mode, align);
11185  return "";
11186}
11187  [(set (attr "length")
11188        (symbol_ref "GET_MODE_SIZE (GET_MODE (PATTERN (insn)))"))])
11189
11190(define_insn "pool_align"
11191  [(unspec_volatile [(match_operand 0 "const_int_operand" "n")]
11192                    UNSPECV_POOL_ALIGN)]
11193  ""
11194  ".align\t%0"
11195  [(set (attr "length") (symbol_ref "INTVAL (operands[0])"))])
11196
11197(define_insn "pool_section_start"
11198  [(unspec_volatile [(const_int 1)] UNSPECV_POOL_SECTION)]
11199  ""
11200{
11201  switch_to_section (targetm.asm_out.function_rodata_section
11202		 (current_function_decl));
11203  return "";
11204}
11205  [(set_attr "length" "0")])
11206
11207(define_insn "pool_section_end"
11208  [(unspec_volatile [(const_int 0)] UNSPECV_POOL_SECTION)]
11209  ""
11210{
11211  switch_to_section (current_function_section ());
11212  return "";
11213}
11214  [(set_attr "length" "0")])
11215
11216(define_insn "main_base_64"
11217  [(set (match_operand 0 "register_operand" "=a")
11218        (unspec [(label_ref (match_operand 1 "" ""))] UNSPEC_MAIN_BASE))]
11219  "GET_MODE (operands[0]) == Pmode"
11220  "larl\t%0,%1"
11221  [(set_attr "op_type" "RIL")
11222   (set_attr "type"    "larl")
11223   (set_attr "z10prop" "z10_fwd_A1")
11224   (set_attr "relative_long" "yes")])
11225
11226(define_insn "main_pool"
11227  [(set (match_operand 0 "register_operand" "=a")
11228        (unspec_volatile [(const_int 0)] UNSPECV_MAIN_POOL))]
11229  "GET_MODE (operands[0]) == Pmode"
11230{
11231  gcc_unreachable ();
11232}
11233  [(set (attr "type")
11234        (const_string "larl"))])
11235
11236(define_insn "reload_base_64"
11237  [(set (match_operand 0 "register_operand" "=a")
11238        (unspec [(label_ref (match_operand 1 "" ""))] UNSPEC_RELOAD_BASE))]
11239  "GET_MODE (operands[0]) == Pmode"
11240  "larl\t%0,%1"
11241  [(set_attr "op_type" "RIL")
11242   (set_attr "type"    "larl")
11243   (set_attr "z10prop" "z10_fwd_A1")])
11244
11245(define_insn "pool"
11246  [(unspec_volatile [(match_operand 0 "const_int_operand" "n")] UNSPECV_POOL)]
11247  ""
11248{
11249  gcc_unreachable ();
11250}
11251  [(set (attr "length") (symbol_ref "INTVAL (operands[0])"))])
11252
11253;;
11254;; Insns related to generating the function prologue and epilogue.
11255;;
11256
11257
11258(define_expand "prologue"
11259  [(use (const_int 0))]
11260  ""
11261  "s390_emit_prologue (); DONE;")
11262
11263(define_expand "epilogue"
11264  [(use (const_int 1))]
11265  ""
11266  "s390_emit_epilogue (false); DONE;")
11267
11268(define_expand "sibcall_epilogue"
11269  [(use (const_int 0))]
11270  ""
11271  "s390_emit_epilogue (true); DONE;")
11272
11273;; A direct return instruction, without using an epilogue.
11274(define_insn "<code>"
11275  [(ANY_RETURN)]
11276  "s390_can_use_<code>_insn ()"
11277{
11278  if (TARGET_INDIRECT_BRANCH_NOBP_RET)
11279    {
11280      /* The target is always r14 so there is no clobber
11281	 of r1 needed for pre z10 targets.  */
11282      s390_indirect_branch_via_thunk (RETURN_REGNUM,
11283				      INVALID_REGNUM,
11284				      NULL_RTX,
11285				      s390_indirect_branch_type_return);
11286      return "";
11287    }
11288  else
11289    return "br\t%%r14";
11290}
11291  [(set (attr "op_type")
11292	(if_then_else (match_test "TARGET_INDIRECT_BRANCH_NOBP_RET")
11293		      (const_string "RIL")
11294		      (const_string "RR")))
11295   (set (attr "mnemonic")
11296	(if_then_else (match_test "TARGET_INDIRECT_BRANCH_NOBP_RET")
11297		      (const_string "jg")
11298		      (const_string "br")))
11299   (set_attr "type"    "jsr")
11300   (set_attr "atype"   "agen")])
11301
11302
11303(define_expand "return_use"
11304  [(parallel
11305    [(return)
11306     (use (match_operand 0 "register_operand" "a"))])]
11307  ""
11308{
11309  if (!TARGET_CPU_Z10
11310      && TARGET_INDIRECT_BRANCH_NOBP_RET_OPTION)
11311    {
11312      if (TARGET_64BIT)
11313        emit_jump_insn (gen_returndi_prez10 (operands[0]));
11314      else
11315        emit_jump_insn (gen_returnsi_prez10 (operands[0]));
11316      DONE;
11317    }
11318})
11319
11320(define_insn "*return<mode>"
11321  [(return)
11322   (use (match_operand:P 0 "register_operand" "a"))]
11323  "TARGET_CPU_Z10 || !TARGET_INDIRECT_BRANCH_NOBP_RET_OPTION"
11324{
11325  if (TARGET_INDIRECT_BRANCH_NOBP_RET)
11326    {
11327      s390_indirect_branch_via_thunk (REGNO (operands[0]),
11328                                      INVALID_REGNUM,
11329                                      NULL_RTX,
11330                                      s390_indirect_branch_type_return);
11331      return "";
11332    }
11333  else
11334    return "br\t%0";
11335}
11336  [(set (attr "op_type")
11337       (if_then_else (match_test "TARGET_INDIRECT_BRANCH_NOBP_RET")
11338                     (const_string "RIL")
11339                     (const_string "RR")))
11340   (set (attr "mnemonic")
11341       (if_then_else (match_test "TARGET_INDIRECT_BRANCH_NOBP_RET")
11342                     (const_string "jg")
11343                     (const_string "br")))
11344   (set_attr "type"    "jsr")
11345   (set_attr "atype"   "agen")])
11346
11347(define_insn "return<mode>_prez10"
11348  [(return)
11349   (use (match_operand:P 0 "register_operand" "a"))
11350   (clobber (reg:P INDIRECT_BRANCH_THUNK_REGNUM))]
11351  "!TARGET_CPU_Z10 && TARGET_INDIRECT_BRANCH_NOBP_RET_OPTION"
11352{
11353  if (TARGET_INDIRECT_BRANCH_NOBP_RET)
11354    {
11355      s390_indirect_branch_via_thunk (REGNO (operands[0]),
11356                                      INVALID_REGNUM,
11357                                      NULL_RTX,
11358                                      s390_indirect_branch_type_return);
11359      return "";
11360    }
11361  else
11362    return "br\t%0";
11363}
11364  [(set (attr "op_type")
11365       (if_then_else (match_test "TARGET_INDIRECT_BRANCH_NOBP_RET")
11366                     (const_string "RIL")
11367                     (const_string "RR")))
11368   (set (attr "mnemonic")
11369       (if_then_else (match_test "TARGET_INDIRECT_BRANCH_NOBP_RET")
11370                     (const_string "jg")
11371                     (const_string "br")))
11372   (set_attr "type"    "jsr")
11373   (set_attr "atype"   "agen")])
11374
11375
11376;; Instruction definition to extend a 31-bit pointer into a 64-bit
11377;; pointer. This is used for compatibility.
11378
11379(define_expand "ptr_extend"
11380  [(set (match_operand:DI 0 "register_operand" "=r")
11381        (match_operand:SI 1 "register_operand" "r"))]
11382  "TARGET_64BIT"
11383{
11384  emit_insn (gen_anddi3 (operands[0],
11385			 gen_lowpart (DImode, operands[1]),
11386			 GEN_INT (0x7fffffff)));
11387  DONE;
11388})
11389
11390;; Instruction definition to expand eh_return macro to support
11391;; swapping in special linkage return addresses.
11392
11393(define_expand "eh_return"
11394  [(use (match_operand 0 "register_operand" ""))]
11395  "TARGET_TPF"
11396{
11397  s390_emit_tpf_eh_return (operands[0]);
11398  DONE;
11399})
11400
11401;
11402; Stack Protector Patterns
11403;
11404
11405(define_expand "stack_protect_set"
11406  [(set (match_operand 0 "memory_operand" "")
11407	(match_operand 1 "memory_operand" ""))]
11408  ""
11409{
11410#ifdef TARGET_THREAD_SSP_OFFSET
11411  operands[1]
11412    = gen_rtx_MEM (Pmode, gen_rtx_PLUS (Pmode, s390_get_thread_pointer (),
11413                                        GEN_INT (TARGET_THREAD_SSP_OFFSET)));
11414#endif
11415  if (TARGET_64BIT)
11416    emit_insn (gen_stack_protect_setdi (operands[0], operands[1]));
11417  else
11418    emit_insn (gen_stack_protect_setsi (operands[0], operands[1]));
11419
11420  DONE;
11421})
11422
11423(define_insn "stack_protect_set<mode>"
11424  [(set (match_operand:DSI 0 "memory_operand" "=Q")
11425        (unspec:DSI [(match_operand:DSI 1 "memory_operand" "Q")] UNSPEC_SP_SET))]
11426  ""
11427  "mvc\t%O0(%G0,%R0),%S1"
11428  [(set_attr "op_type" "SS")])
11429
11430(define_expand "stack_protect_test"
11431  [(set (reg:CC CC_REGNUM)
11432	(compare (match_operand 0 "memory_operand" "")
11433		 (match_operand 1 "memory_operand" "")))
11434   (match_operand 2 "" "")]
11435  ""
11436{
11437  rtx cc_reg, test;
11438#ifdef TARGET_THREAD_SSP_OFFSET
11439  operands[1]
11440    = gen_rtx_MEM (Pmode, gen_rtx_PLUS (Pmode, s390_get_thread_pointer (),
11441                                        GEN_INT (TARGET_THREAD_SSP_OFFSET)));
11442#endif
11443  if (TARGET_64BIT)
11444    emit_insn (gen_stack_protect_testdi (operands[0], operands[1]));
11445  else
11446    emit_insn (gen_stack_protect_testsi (operands[0], operands[1]));
11447
11448  cc_reg = gen_rtx_REG (CCZmode, CC_REGNUM);
11449  test = gen_rtx_EQ (VOIDmode, cc_reg, const0_rtx);
11450  emit_jump_insn (gen_cbranchcc4 (test, cc_reg, const0_rtx, operands[2]));
11451  DONE;
11452})
11453
11454(define_insn "stack_protect_test<mode>"
11455  [(set (reg:CCZ CC_REGNUM)
11456        (unspec:CCZ [(match_operand:DSI 0 "memory_operand" "Q")
11457		     (match_operand:DSI 1 "memory_operand" "Q")] UNSPEC_SP_TEST))]
11458  ""
11459  "clc\t%O0(%G0,%R0),%S1"
11460  [(set_attr "op_type" "SS")])
11461
11462; This is used in s390_emit_prologue in order to prevent insns
11463; adjusting the stack pointer to be moved over insns writing stack
11464; slots using a copy of the stack pointer in a different register.
11465(define_insn "stack_tie"
11466  [(set (match_operand:BLK 0 "memory_operand" "+m")
11467        (unspec:BLK [(match_dup 0)] UNSPEC_TIE))]
11468  ""
11469  ""
11470  [(set_attr "length" "0")])
11471
11472
11473(define_insn "stack_restore_from_fpr"
11474  [(set (reg:DI STACK_REGNUM)
11475	(match_operand:DI 0 "register_operand" "f"))
11476   (clobber (mem:BLK (scratch)))]
11477  "TARGET_Z10"
11478  "lgdr\t%%r15,%0"
11479  [(set_attr "op_type"  "RRE")])
11480
11481;
11482; Data prefetch patterns
11483;
11484
11485(define_insn "prefetch"
11486  [(prefetch (match_operand 0    "address_operand"   "ZT,X")
11487	     (match_operand:SI 1 "const_int_operand" " n,n")
11488	     (match_operand:SI 2 "const_int_operand" " n,n"))]
11489  "TARGET_Z10"
11490{
11491  switch (which_alternative)
11492    {
11493      case 0:
11494        return INTVAL (operands[1]) == 1 ? "pfd\t2,%a0" : "pfd\t1,%a0";
11495      case 1:
11496        if (larl_operand (operands[0], Pmode))
11497	  return INTVAL (operands[1]) == 1 ? "pfdrl\t2,%a0" : "pfdrl\t1,%a0";
11498	  /* fallthrough */
11499      default:
11500
11501        /* This might be reached for symbolic operands with an odd
11502           addend.  We simply omit the prefetch for such rare cases.  */
11503
11504        return "";
11505     }
11506}
11507  [(set_attr "type" "load,larl")
11508   (set_attr "op_type" "RXY,RIL")
11509   (set_attr "z10prop" "z10_super")
11510   (set_attr "z196prop" "z196_alone")
11511   (set_attr "relative_long" "yes")])
11512
11513
11514;
11515; Byte swap instructions
11516;
11517
11518; FIXME: There is also mvcin but we cannot use it since src and target
11519; may overlap.
11520; lrvr, lrv, strv, lrvgr, lrvg, strvg
11521(define_insn "bswap<mode>2"
11522  [(set (match_operand:GPR 0            "nonimmediate_operand" "=d,d,T")
11523	(bswap:GPR (match_operand:GPR 1 "nonimmediate_operand" " d,T,d")))]
11524  ""
11525  "@
11526   lrv<g>r\t%0,%1
11527   lrv<g>\t%0,%1
11528   strv<g>\t%1,%0"
11529  [(set_attr "type" "*,load,store")
11530   (set_attr "op_type" "RRE,RXY,RXY")
11531   (set_attr "z10prop" "z10_super")])
11532
11533(define_insn "bswaphi2"
11534  [(set (match_operand:HI 0           "nonimmediate_operand" "=d,d,T")
11535	(bswap:HI (match_operand:HI 1 "nonimmediate_operand" " d,T,d")))]
11536  ""
11537  "@
11538   #
11539   lrvh\t%0,%1
11540   strvh\t%1,%0"
11541  [(set_attr "type" "*,load,store")
11542   (set_attr "op_type" "RRE,RXY,RXY")
11543   (set_attr "z10prop" "z10_super")])
11544
11545(define_split
11546  [(set (match_operand:HI 0           "register_operand" "")
11547	(bswap:HI (match_operand:HI 1 "register_operand" "")))]
11548  ""
11549  [(set (match_dup 2) (bswap:SI (match_dup 3)))
11550   (set (match_dup 2) (lshiftrt:SI (match_dup 2) (const_int 16)))]
11551{
11552  operands[2] = simplify_gen_subreg (SImode, operands[0], HImode, 0);
11553  operands[3] = simplify_gen_subreg (SImode, operands[1], HImode, 0);
11554})
11555
11556
11557;
11558; Population count instruction
11559;
11560
11561(define_insn "*popcountdi_z15_cc"
11562  [(set (reg CC_REGNUM)
11563	(compare (popcount:DI (match_operand:DI 1 "register_operand" "d"))
11564		 (const_int 0)))
11565   (set (match_operand:DI 0 "register_operand" "=d")
11566	(match_dup 1))]
11567  "TARGET_Z15 && s390_match_ccmode (insn, CCTmode)"
11568  "popcnt\t%0,%1,8"
11569  [(set_attr "op_type" "RRF")])
11570
11571(define_insn "*popcountdi_z15_cconly"
11572  [(set (reg CC_REGNUM)
11573	(compare (popcount:DI (match_operand:DI 1 "register_operand" "d"))
11574		 (const_int 0)))
11575   (clobber (match_scratch:DI 0 "=d"))]
11576  "TARGET_Z15 && s390_match_ccmode(insn, CCTmode)"
11577  "popcnt\t%0,%1,8"
11578  [(set_attr "op_type" "RRF")])
11579
11580(define_insn "*popcountdi_z15"
11581  [(set (match_operand:DI 0 "register_operand" "=d")
11582	(popcount:DI (match_operand:DI 1 "register_operand" "d")))
11583   (clobber (reg:CC CC_REGNUM))]
11584  "TARGET_Z15"
11585  "popcnt\t%0,%1,8"
11586  [(set_attr "op_type" "RRF")])
11587
11588; The pre-z15 popcount instruction counts the bits of op1 in 8 byte
11589; portions and stores the result in the corresponding bytes in op0.
11590(define_insn "*popcount<mode>_z196"
11591  [(set (match_operand:INT 0 "register_operand" "=d")
11592	(unspec:INT [(match_operand:INT 1 "register_operand" "d")] UNSPEC_POPCNT))
11593   (clobber (reg:CC CC_REGNUM))]
11594  "TARGET_Z196"
11595  "popcnt\t%0,%1"
11596  [(set_attr "op_type" "RRE")])
11597
11598(define_expand "popcountdi2_z196"
11599  [; popcnt op0, op1
11600   (parallel [(set (match_operand:DI 0 "register_operand" "")
11601		   (unspec:DI [(match_operand:DI 1 "register_operand")]
11602			      UNSPEC_POPCNT))
11603	      (clobber (reg:CC CC_REGNUM))])
11604   ; sllg op2, op0, 32
11605   (set (match_dup 2) (ashift:DI (match_dup 0) (const_int 32)))
11606   ; agr op0, op2
11607   (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 2)))
11608	      (clobber (reg:CC CC_REGNUM))])
11609   ; sllg op2, op0, 16
11610   (set (match_dup 2)
11611	(ashift:DI (match_dup 0) (const_int 16)))
11612   ; agr op0, op2
11613   (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 2)))
11614	      (clobber (reg:CC CC_REGNUM))])
11615   ; sllg op2, op0, 8
11616   (set (match_dup 2) (ashift:DI (match_dup 0) (const_int 8)))
11617   ; agr op0, op2
11618   (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 2)))
11619	      (clobber (reg:CC CC_REGNUM))])
11620   ; srlg op0, op0, 56
11621   (set (match_dup 0) (lshiftrt:DI (match_dup 0) (const_int 56)))]
11622  "TARGET_Z196"
11623  "operands[2] = gen_reg_rtx (DImode);")
11624
11625(define_expand "popcountdi2"
11626  [(parallel
11627    [(set (match_operand:DI 0 "register_operand" "")
11628	  (popcount:DI (match_operand:DI 1 "register_operand")))
11629     (clobber (reg:CC CC_REGNUM))])]
11630  "TARGET_Z196"
11631{
11632  if (!TARGET_Z15)
11633    {
11634      emit_insn (gen_popcountdi2_z196 (operands[0], operands[1]));
11635      DONE;
11636    }
11637 })
11638
11639(define_expand "popcountsi2_z196"
11640  [; popcnt op0, op1
11641   (parallel [(set (match_operand:SI 0 "register_operand" "")
11642		   (unspec:SI [(match_operand:SI 1 "register_operand")]
11643			      UNSPEC_POPCNT))
11644	      (clobber (reg:CC CC_REGNUM))])
11645   ; sllk op2, op0, 16
11646   (set (match_dup 2)
11647	(ashift:SI (match_dup 0) (const_int 16)))
11648   ; ar op0, op2
11649   (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
11650	      (clobber (reg:CC CC_REGNUM))])
11651   ; sllk op2, op0, 8
11652   (set (match_dup 2) (ashift:SI (match_dup 0) (const_int 8)))
11653   ; ar op0, op2
11654   (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
11655	      (clobber (reg:CC CC_REGNUM))])
11656   ; srl op0, op0, 24
11657   (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 24)))]
11658  "TARGET_Z196"
11659  "operands[2] = gen_reg_rtx (SImode);")
11660
11661; popcount always counts on the full 64 bit. With the z196 version
11662; counting bits per byte we just ignore the upper 4 bytes.  With the
11663; z15 version we have to zero out the upper 32 bits first.
11664(define_expand "popcountsi2"
11665  [(set (match_dup 2)
11666	(zero_extend:DI (match_operand:SI 1 "register_operand")))
11667   (parallel [(set (match_dup 3) (popcount:DI (match_dup 2)))
11668	      (clobber (reg:CC CC_REGNUM))])
11669   (set (match_operand:SI 0 "register_operand")
11670	(subreg:SI (match_dup 3) 4))]
11671  "TARGET_Z196"
11672{
11673  if (!TARGET_Z15)
11674    {
11675      emit_insn (gen_popcountsi2_z196 (operands[0], operands[1]));
11676      DONE;
11677    }
11678  else
11679    {
11680      operands[2] = gen_reg_rtx (DImode);
11681      operands[3] = gen_reg_rtx (DImode);
11682    }
11683})
11684
11685(define_expand "popcounthi2_z196"
11686  [; popcnt op2, op1
11687   (parallel [(set (match_dup 2)
11688		   (unspec:HI [(match_operand:HI 1 "register_operand")]
11689			      UNSPEC_POPCNT))
11690	      (clobber (reg:CC CC_REGNUM))])
11691   ; lr op3, op2
11692   (set (match_dup 3) (subreg:SI (match_dup 2) 0))
11693   ; srl op4, op3, 8
11694   (set (match_dup 4) (lshiftrt:SI (match_dup 3) (const_int 8)))
11695   ; ar op3, op4
11696   (parallel [(set (match_dup 3) (plus:SI (match_dup 3) (match_dup 4)))
11697	      (clobber (reg:CC CC_REGNUM))])
11698   ; llgc op0, op3
11699   (parallel [(set (match_operand:HI 0 "register_operand" "")
11700		   (and:HI (subreg:HI (match_dup 3) 2) (const_int 255)))
11701	      (clobber (reg:CC CC_REGNUM))])]
11702  "TARGET_Z196"
11703{
11704  operands[2] = gen_reg_rtx (HImode);
11705  operands[3] = gen_reg_rtx (SImode);
11706  operands[4] = gen_reg_rtx (SImode);
11707})
11708
11709(define_expand "popcounthi2"
11710  [(set (match_dup 2)
11711	(zero_extend:DI (match_operand:HI 1 "register_operand")))
11712   (parallel [(set (match_dup 3) (popcount:DI (match_dup 2)))
11713	      (clobber (reg:CC CC_REGNUM))])
11714   (set (match_operand:HI 0 "register_operand")
11715	(subreg:HI (match_dup 3) 6))]
11716  "TARGET_Z196"
11717{
11718  if (!TARGET_Z15)
11719    {
11720      emit_insn (gen_popcounthi2_z196 (operands[0], operands[1]));
11721      DONE;
11722    }
11723  else
11724    {
11725      operands[2] = gen_reg_rtx (DImode);
11726      operands[3] = gen_reg_rtx (DImode);
11727    }
11728})
11729
11730; For popcount on a single byte the old z196 style popcount
11731; instruction is ideal.  Since it anyway does a byte-wise popcount we
11732; just use it instead of zero extending the QImode input to DImode and
11733; using the z15 popcount variant.
11734(define_expand "popcountqi2"
11735  [; popcnt op0, op1
11736   (parallel [(set (match_operand:QI 0 "register_operand" "")
11737		   (unspec:QI [(match_operand:QI 1 "register_operand")]
11738			      UNSPEC_POPCNT))
11739	      (clobber (reg:CC CC_REGNUM))])]
11740  "TARGET_Z196"
11741  "")
11742
11743;;
11744;;- Copy sign instructions
11745;;
11746
11747(define_insn "copysign<mode>3"
11748  [(set (match_operand:FP 0 "register_operand" "=f")
11749      (unspec:FP [(match_operand:FP 1 "register_operand" "<fT0>")
11750                  (match_operand:FP 2 "register_operand" "f")]
11751                  UNSPEC_COPYSIGN))]
11752  "TARGET_Z196"
11753  "cpsdr\t%0,%2,%1"
11754  [(set_attr "op_type"  "RRF")
11755   (set_attr "type"     "fsimp<mode>")])
11756
11757
11758;;
11759;;- Transactional execution instructions
11760;;
11761
11762; This splitter helps combine to make use of CC directly when
11763; comparing the integer result of a tbegin builtin with a constant.
11764; The unspec is already removed by canonicalize_comparison. So this
11765; splitters only job is to turn the PARALLEL into separate insns
11766; again.  Unfortunately this only works with the very first cc/int
11767; compare since combine is not able to deal with data flow across
11768; basic block boundaries.
11769
11770; It needs to be an insn pattern as well since combine does not apply
11771; the splitter directly.  Combine would only use it if it actually
11772; would reduce the number of instructions.
11773(define_insn_and_split "*ccraw_to_int"
11774  [(set (pc)
11775	(if_then_else
11776	 (match_operator 0 "s390_eqne_operator"
11777			 [(reg:CCRAW CC_REGNUM)
11778			  (match_operand 1 "const_int_operand" "")])
11779	 (label_ref (match_operand 2 "" ""))
11780	 (pc)))
11781   (set (match_operand:SI 3 "register_operand" "=d")
11782	(unspec:SI [(reg:CCRAW CC_REGNUM)] UNSPEC_CC_TO_INT))]
11783  ""
11784  "#"
11785  ""
11786  [(set (match_dup 3)
11787	(unspec:SI [(reg:CCRAW CC_REGNUM)] UNSPEC_CC_TO_INT))
11788   (set (pc)
11789	(if_then_else (match_op_dup 0 [(reg:CCRAW CC_REGNUM) (match_dup 1)])
11790		      (label_ref (match_dup 2))
11791		      (pc)))]
11792  "")
11793
11794; Non-constrained transaction begin
11795
11796(define_expand "tbegin"
11797  [(match_operand:SI 0 "register_operand" "")
11798   (match_operand:BLK 1 "memory_operand" "")]
11799  "TARGET_HTM"
11800{
11801  s390_expand_tbegin (operands[0], operands[1], NULL_RTX, true);
11802  DONE;
11803})
11804
11805(define_expand "tbegin_nofloat"
11806  [(match_operand:SI 0 "register_operand" "")
11807   (match_operand:BLK 1 "memory_operand" "")]
11808  "TARGET_HTM"
11809{
11810  s390_expand_tbegin (operands[0], operands[1], NULL_RTX, false);
11811  DONE;
11812})
11813
11814(define_expand "tbegin_retry"
11815  [(match_operand:SI 0 "register_operand" "")
11816   (match_operand:BLK 1 "memory_operand" "")
11817   (match_operand:SI 2 "general_operand" "")]
11818  "TARGET_HTM"
11819{
11820  s390_expand_tbegin (operands[0], operands[1], operands[2], true);
11821  DONE;
11822})
11823
11824(define_expand "tbegin_retry_nofloat"
11825  [(match_operand:SI 0 "register_operand" "")
11826   (match_operand:BLK 1 "memory_operand" "")
11827   (match_operand:SI 2 "general_operand" "")]
11828  "TARGET_HTM"
11829{
11830  s390_expand_tbegin (operands[0], operands[1], operands[2], false);
11831  DONE;
11832})
11833
11834; Clobber VRs since they don't get restored
11835(define_insn "tbegin_1_z13"
11836  [(set (reg:CCRAW CC_REGNUM)
11837	(unspec_volatile:CCRAW [(match_operand 0 "const_int_operand" "D")]
11838			       UNSPECV_TBEGIN))
11839   (set (match_operand:BLK 1 "memory_operand" "=Q")
11840	(unspec_volatile:BLK [(match_dup 0)] UNSPECV_TBEGIN_TDB))
11841   (clobber (reg:TI 16)) (clobber (reg:TI 38))
11842   (clobber (reg:TI 17)) (clobber (reg:TI 39))
11843   (clobber (reg:TI 18)) (clobber (reg:TI 40))
11844   (clobber (reg:TI 19)) (clobber (reg:TI 41))
11845   (clobber (reg:TI 20)) (clobber (reg:TI 42))
11846   (clobber (reg:TI 21)) (clobber (reg:TI 43))
11847   (clobber (reg:TI 22)) (clobber (reg:TI 44))
11848   (clobber (reg:TI 23)) (clobber (reg:TI 45))
11849   (clobber (reg:TI 24)) (clobber (reg:TI 46))
11850   (clobber (reg:TI 25)) (clobber (reg:TI 47))
11851   (clobber (reg:TI 26)) (clobber (reg:TI 48))
11852   (clobber (reg:TI 27)) (clobber (reg:TI 49))
11853   (clobber (reg:TI 28)) (clobber (reg:TI 50))
11854   (clobber (reg:TI 29)) (clobber (reg:TI 51))
11855   (clobber (reg:TI 30)) (clobber (reg:TI 52))
11856   (clobber (reg:TI 31)) (clobber (reg:TI 53))]
11857; CONST_OK_FOR_CONSTRAINT_P does not work with D constraint since D is
11858; not supposed to be used for immediates (see genpreds.c).
11859  "TARGET_VX && INTVAL (operands[0]) >= 0 && INTVAL (operands[0]) <= 0xffff"
11860  "tbegin\t%1,%x0"
11861  [(set_attr "op_type" "SIL")])
11862
11863(define_insn "tbegin_1"
11864  [(set (reg:CCRAW CC_REGNUM)
11865	(unspec_volatile:CCRAW [(match_operand 0 "const_int_operand" "D")]
11866			       UNSPECV_TBEGIN))
11867   (set (match_operand:BLK 1 "memory_operand" "=Q")
11868	(unspec_volatile:BLK [(match_dup 0)] UNSPECV_TBEGIN_TDB))
11869   (clobber (reg:DF 16))
11870   (clobber (reg:DF 17))
11871   (clobber (reg:DF 18))
11872   (clobber (reg:DF 19))
11873   (clobber (reg:DF 20))
11874   (clobber (reg:DF 21))
11875   (clobber (reg:DF 22))
11876   (clobber (reg:DF 23))
11877   (clobber (reg:DF 24))
11878   (clobber (reg:DF 25))
11879   (clobber (reg:DF 26))
11880   (clobber (reg:DF 27))
11881   (clobber (reg:DF 28))
11882   (clobber (reg:DF 29))
11883   (clobber (reg:DF 30))
11884   (clobber (reg:DF 31))]
11885; CONST_OK_FOR_CONSTRAINT_P does not work with D constraint since D is
11886; not supposed to be used for immediates (see genpreds.c).
11887  "TARGET_HTM && INTVAL (operands[0]) >= 0 && INTVAL (operands[0]) <= 0xffff"
11888  "tbegin\t%1,%x0"
11889  [(set_attr "op_type" "SIL")])
11890
11891; Same as above but without the FPR clobbers
11892(define_insn "tbegin_nofloat_1"
11893  [(set (reg:CCRAW CC_REGNUM)
11894	(unspec_volatile:CCRAW [(match_operand 0 "const_int_operand" "D")]
11895			       UNSPECV_TBEGIN))
11896   (set (match_operand:BLK 1 "memory_operand" "=Q")
11897	(unspec_volatile:BLK [(match_dup 0)] UNSPECV_TBEGIN_TDB))]
11898  "TARGET_HTM && INTVAL (operands[0]) >= 0 && INTVAL (operands[0]) <= 0xffff"
11899  "tbegin\t%1,%x0"
11900  [(set_attr "op_type" "SIL")])
11901
11902
11903; Constrained transaction begin
11904
11905(define_expand "tbeginc"
11906  [(set (reg:CCRAW CC_REGNUM)
11907	(unspec_volatile:CCRAW [(const_int TBEGINC_MASK)]
11908			       UNSPECV_TBEGINC))]
11909  "TARGET_HTM"
11910  "")
11911
11912(define_insn "*tbeginc_1"
11913  [(set (reg:CCRAW CC_REGNUM)
11914	(unspec_volatile:CCRAW [(match_operand 0 "const_int_operand" " D")]
11915			       UNSPECV_TBEGINC))]
11916  "TARGET_HTM && INTVAL (operands[0]) >= 0 && INTVAL (operands[0]) <= 0xffff"
11917  "tbeginc\t0,%x0"
11918  [(set_attr "op_type" "SIL")])
11919
11920; Transaction end
11921
11922(define_expand "tend"
11923  [(set (reg:CCRAW CC_REGNUM)
11924	(unspec_volatile:CCRAW [(const_int 0)] UNSPECV_TEND))
11925   (set (match_operand:SI 0 "register_operand" "")
11926	(unspec:SI [(reg:CCRAW CC_REGNUM)] UNSPEC_CC_TO_INT))]
11927  "TARGET_HTM"
11928  "")
11929
11930(define_insn "*tend_1"
11931  [(set (reg:CCRAW CC_REGNUM)
11932	(unspec_volatile:CCRAW [(const_int 0)] UNSPECV_TEND))]
11933  "TARGET_HTM"
11934  "tend"
11935  [(set_attr "op_type" "S")])
11936
11937; Transaction abort
11938
11939(define_expand "tabort"
11940  [(unspec_volatile [(match_operand:SI 0 "nonmemory_operand" "")]
11941		    UNSPECV_TABORT)]
11942  "TARGET_HTM && operands != NULL"
11943{
11944  if (CONST_INT_P (operands[0])
11945      && INTVAL (operands[0]) >= 0 && INTVAL (operands[0]) <= 255)
11946    {
11947      error ("invalid transaction abort code: %wd (values in range 0 "
11948	     "through 255 are reserved)", INTVAL (operands[0]));
11949      FAIL;
11950    }
11951})
11952
11953(define_insn "*tabort_1"
11954  [(unspec_volatile [(match_operand:SI 0 "nonmemory_operand" "aJ")]
11955		    UNSPECV_TABORT)]
11956  "TARGET_HTM && operands != NULL"
11957  "tabort\t%Y0"
11958  [(set_attr "op_type" "S")])
11959
11960(define_insn "*tabort_1_plus"
11961  [(unspec_volatile [(plus:SI (match_operand:SI 0 "register_operand"  "a")
11962			      (match_operand:SI 1 "const_int_operand" "J"))]
11963		    UNSPECV_TABORT)]
11964  "TARGET_HTM && operands != NULL
11965   && CONST_OK_FOR_CONSTRAINT_P (INTVAL (operands[1]), 'J', \"J\")"
11966  "tabort\t%1(%0)"
11967  [(set_attr "op_type" "S")])
11968
11969; Transaction extract nesting depth
11970
11971(define_insn "etnd"
11972  [(set (match_operand:SI 0 "register_operand" "=d")
11973	(unspec_volatile:SI [(const_int 0)] UNSPECV_ETND))]
11974  "TARGET_HTM"
11975  "etnd\t%0"
11976  [(set_attr "op_type" "RRE")])
11977
11978; Non-transactional store
11979
11980(define_insn "ntstg"
11981  [(set (match_operand:DI 0 "memory_operand" "=T")
11982	(unspec_volatile:DI [(match_operand:DI 1 "register_operand" "d")]
11983			    UNSPECV_NTSTG))]
11984  "TARGET_HTM"
11985  "ntstg\t%1,%0"
11986  [(set_attr "op_type" "RXY")])
11987
11988; Transaction perform processor assist
11989
11990(define_expand "tx_assist"
11991  [(unspec_volatile [(match_operand:SI 0 "register_operand" "")
11992		     (reg:SI GPR0_REGNUM)
11993		     (const_int PPA_TX_ABORT)]
11994		    UNSPECV_PPA)]
11995  "TARGET_HTM"
11996  "")
11997
11998(define_insn "*ppa"
11999  [(unspec_volatile [(match_operand:SI 0 "register_operand" "d")
12000		     (match_operand:SI 1 "register_operand" "d")
12001		     (match_operand 2 "const_int_operand" "I")]
12002		    UNSPECV_PPA)]
12003  "(TARGET_ZEC12 || TARGET_HTM) && INTVAL (operands[2]) < 16"
12004  "ppa\t%0,%1,%2"
12005  [(set_attr "op_type" "RRF")])
12006
12007
12008; Set and get floating point control register
12009
12010(define_insn "sfpc"
12011  [(unspec_volatile [(match_operand:SI 0 "register_operand" "d")]
12012		    UNSPECV_SFPC)]
12013  "TARGET_HARD_FLOAT"
12014  "sfpc\t%0")
12015
12016(define_insn "efpc"
12017  [(set (match_operand:SI 0 "register_operand" "=d")
12018	(unspec_volatile:SI [(const_int 0)] UNSPECV_EFPC))]
12019  "TARGET_HARD_FLOAT"
12020  "efpc\t%0")
12021
12022
12023; Load count to block boundary
12024
12025(define_insn "lcbb"
12026  [(set (match_operand:SI             0 "register_operand"  "=d")
12027	(unspec:SI [(match_operand    1 "address_operand" "ZR")
12028		    (match_operand:SI 2 "immediate_operand"  "C")] UNSPEC_LCBB))
12029   (clobber (reg:CC CC_REGNUM))]
12030  "TARGET_Z13"
12031  "lcbb\t%0,%a1,%b2"
12032  [(set_attr "op_type" "VRX")])
12033
12034; Handle -fsplit-stack.
12035
12036(define_expand "split_stack_prologue"
12037  [(const_int 0)]
12038  ""
12039{
12040  s390_expand_split_stack_prologue ();
12041  DONE;
12042})
12043
12044;; If there are operand 0 bytes available on the stack, jump to
12045;; operand 1.
12046
12047(define_expand "split_stack_space_check"
12048  [(set (pc) (if_then_else
12049	      (ltu (minus (reg 15)
12050			  (match_operand 0 "register_operand"))
12051		   (unspec [(const_int 0)] UNSPEC_STACK_CHECK))
12052	      (label_ref (match_operand 1))
12053	      (pc)))]
12054  ""
12055{
12056  /* Offset from thread pointer to __private_ss.  */
12057  int psso = TARGET_64BIT ? 0x38 : 0x20;
12058  rtx tp = s390_get_thread_pointer ();
12059  rtx guard = gen_rtx_MEM (Pmode, plus_constant (Pmode, tp, psso));
12060  rtx reg = gen_reg_rtx (Pmode);
12061  rtx cc;
12062  if (TARGET_64BIT)
12063    emit_insn (gen_subdi3 (reg, stack_pointer_rtx, operands[0]));
12064  else
12065    emit_insn (gen_subsi3 (reg, stack_pointer_rtx, operands[0]));
12066  cc = s390_emit_compare (GT, reg, guard);
12067  s390_emit_jump (operands[1], cc);
12068
12069  DONE;
12070})
12071
12072;; Call to __morestack used by the split stack support
12073
12074; The insn has 3 parts:
12075; 1. A jump to the call done label. The jump will be done as part of
12076;    __morestack and will not be explicitly emitted to the insn stream.
12077; 2. The call of __morestack including a use for r1 which is supposed to
12078;    point to the parameter block for __morestack.
12079; 3. 3 USES whose values together with the call done label will be
12080;    used to emit the parameter block to the .rodata section. This
12081;    needs to be tied into the same insn as 1. since the call done
12082;    label is emitted also as part of the parm block.  In order to
12083;    allow the edge to the BB with the call done label to be
12084;    redirected both need to make use of the same label_ref.
12085
12086(define_insn "@split_stack_call<mode>"
12087  [(set (pc) (label_ref (match_operand 2 "" "")))     ; call done label
12088   (set (reg:P 1) (unspec_volatile [(match_operand 0 "bras_sym_operand" "X")
12089				    (reg:P 1)]
12090				   UNSPECV_SPLIT_STACK_CALL))
12091   (use (label_ref (match_operand 1 "" "X")))         ; parm block label
12092   (use (match_operand 3 "const_int_operand" "X"))    ; frame size
12093   (use (match_operand 4 "const_int_operand" "X"))]   ; arg size
12094  ""
12095{
12096  s390_output_split_stack_data (operands[1], operands[2], operands[3], operands[4]);
12097  return "jg\t%0";
12098}
12099  [(set_attr "op_type" "RIL")
12100   (set_attr "type"  "branch")])
12101
12102; As above but with a conditional jump
12103
12104(define_insn "@split_stack_cond_call<mode>"
12105  [(set (pc)
12106	(if_then_else
12107	  (match_operand 5 "" "")                     ; condition
12108	  (label_ref (match_operand 2 "" ""))         ; call done label
12109	  (pc)))
12110   (set (reg:P 1) (unspec_volatile [(match_operand 0 "bras_sym_operand" "X")
12111				    (reg:P 1)]
12112				   UNSPECV_SPLIT_STACK_CALL))
12113   (use (label_ref (match_operand 1 "" "X")))         ; parm block label
12114   (use (match_operand 3 "const_int_operand" "X"))    ; frame size
12115   (use (match_operand 4 "const_int_operand" "X"))]   ; arg size
12116  ""
12117{
12118  s390_output_split_stack_data (operands[1], operands[2], operands[3], operands[4]);
12119  return "jg%C5\t%0";
12120}
12121  [(set_attr "op_type" "RIL")
12122   (set_attr "type"  "branch")])
12123
12124
12125(define_insn "osc_break"
12126  [(unspec_volatile [(const_int 0)] UNSPECV_OSC_BREAK)]
12127  ""
12128  "bcr\t7,%%r0"
12129  [(set_attr "op_type" "RR")])
12130
12131(define_expand "speculation_barrier"
12132  [(unspec_volatile [(reg:SI GPR0_REGNUM)
12133		     (reg:SI GPR0_REGNUM)
12134		     (const_int PPA_OOO_BARRIER)]
12135		    UNSPECV_PPA)]
12136  "TARGET_ZEC12"
12137  "")
12138