libcpp, c, middle-end: Optimize initializers using #embed in C
[official-gcc.git] / gcc / config / s390 / s390.md
blob4a225ae24f3352536f891189e7bdbbfc870e45e0
1 ;;- Machine description for GNU compiler -- S/390 / zSeries version.
2 ;;  Copyright (C) 1999-2024 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)
7 ;; This file is part of GCC.
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.
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.
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/>.
24 ;; See constraints.md for a description of constraints specific to s390.
27 ;; Special formats used for outputting 390 instructions.
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.
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.
50 ;; We have a special constraint for pattern matching.
52 ;;   s_operand -- Matches a valid S operand in a RS, SI or SS type instruction.
56 ;; UNSPEC usage
59 (define_c_enum "unspec" [
60    ; Miscellaneous
61    UNSPEC_ROUND
62    UNSPEC_ICM
63    UNSPEC_TIE
64    UNSPEC_MVCRL
66    ; Convert CC into a str comparison result and copy it into an
67    ; integer register
68    ; cc0->0, cc1->1, cc2->-1, (cc3->-1)
69    UNSPEC_STRCMPCC_TO_INT
71    ; Copy CC as is into the lower 2 bits of an integer register
72    UNSPEC_CC_TO_INT
74    ; The right hand side of an setmem
75    UNSPEC_REPLICATE_BYTE
77    ; GOT/PLT and lt-relative accesses
78    UNSPEC_LTREL_OFFSET
79    UNSPEC_POOL_OFFSET
80    UNSPEC_GOTENT
81    UNSPEC_GOT
82    UNSPEC_GOTOFF
83    UNSPEC_PLT31
84    UNSPEC_PLTOFF
86    ; Literal pool
87    UNSPEC_RELOAD_BASE
88    UNSPEC_MAIN_BASE
89    UNSPEC_LTREF
90    UNSPEC_INSN
91    UNSPEC_EXECUTE
92    UNSPEC_EXECUTE_JUMP
94    ; Atomic Support
95    UNSPEC_MB
96    UNSPEC_MOVA
98    ; TLS relocation specifiers
99    UNSPEC_TLSGD
100    UNSPEC_TLSLDM
101    UNSPEC_NTPOFF
102    UNSPEC_DTPOFF
103    UNSPEC_GOTNTPOFF
104    UNSPEC_INDNTPOFF
106    ; TLS support
107    UNSPEC_TLSLDM_NTPOFF
108    UNSPEC_TLS_LOAD
109    UNSPEC_GET_TP
111    ; String Functions
112    UNSPEC_SRST
113    UNSPEC_MVST
115    ; Stack Smashing Protector
116    UNSPEC_SP_SET
117    UNSPEC_SP_TEST
119    ; Split stack support
120    UNSPEC_STACK_CHECK
122    ; Test Data Class (TDC)
123    UNSPEC_TDC_INSN
125    ; Byte-wise Population Count
126    UNSPEC_POPCNT
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
136    UNSPEC_LCBB
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
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
155    UNSPEC_VEC_GATHER
156    UNSPEC_VEC_INSERT_AND_ZERO
157    UNSPEC_VEC_LOAD_BNDRY
158    UNSPEC_VEC_LOAD_LEN
159    UNSPEC_VEC_LOAD_LEN_R
160    UNSPEC_VEC_PACK
161    UNSPEC_VEC_PACK_SATURATE
162    UNSPEC_VEC_PACK_SATURATE_CC
163    UNSPEC_VEC_PACK_SATURATE_GENCC
164    UNSPEC_VEC_PACK_UNSIGNED_SATURATE
165    UNSPEC_VEC_PACK_UNSIGNED_SATURATE_CC
166    UNSPEC_VEC_PACK_UNSIGNED_SATURATE_GENCC
167    UNSPEC_VEC_PERM
168    UNSPEC_VEC_EXTEND
169    UNSPEC_VEC_STORE_LEN
170    UNSPEC_VEC_STORE_LEN_R
171    UNSPEC_VEC_VBPERM
172    UNSPEC_VEC_UNPACKH
173    UNSPEC_VEC_UNPACKH_L
174    UNSPEC_VEC_UNPACKL
175    UNSPEC_VEC_UNPACKL_L
176    UNSPEC_VEC_ADDC
177    UNSPEC_VEC_ADDE_U128
178    UNSPEC_VEC_ADDEC_U128
179    UNSPEC_VEC_AVG
180    UNSPEC_VEC_AVGU
181    UNSPEC_VEC_CHECKSUM
182    UNSPEC_VEC_GFMSUM
183    UNSPEC_VEC_GFMSUM_128
184    UNSPEC_VEC_GFMSUM_ACCUM
185    UNSPEC_VEC_GFMSUM_ACCUM_128
186    UNSPEC_VEC_SET
188    UNSPEC_VEC_VSUMG
189    UNSPEC_VEC_VSUMQ
190    UNSPEC_VEC_VSUM
191    UNSPEC_VEC_RL_MASK
192    UNSPEC_VEC_SLL
193    UNSPEC_VEC_SLB
194    UNSPEC_VEC_SLDBYTE
195    UNSPEC_VEC_SLDBIT
196    UNSPEC_VEC_SRDBIT
197    UNSPEC_VEC_SRAL
198    UNSPEC_VEC_SRAB
199    UNSPEC_VEC_SRL
200    UNSPEC_VEC_SRLB
202    UNSPEC_VEC_SUBC
203    UNSPEC_VEC_SUBE_U128
204    UNSPEC_VEC_SUBEC_U128
206    UNSPEC_VEC_TEST_MASK
208    UNSPEC_VEC_VFAE
209    UNSPEC_VEC_VFAECC
211    UNSPEC_VEC_VFEE
212    UNSPEC_VEC_VFEECC
213    UNSPEC_VEC_VFENE
214    UNSPEC_VEC_VFENECC
216    UNSPEC_VEC_VISTR
217    UNSPEC_VEC_VISTRCC
219    UNSPEC_VEC_VSTRC
220    UNSPEC_VEC_VSTRCCC
222    UNSPEC_VEC_VSTRS
223    UNSPEC_VEC_VSTRSCC
225    UNSPEC_VEC_VCDGB
226    UNSPEC_VEC_VCDLGB
228    UNSPEC_VEC_VCGDB
229    UNSPEC_VEC_VCLGDB
231    UNSPEC_VEC_VFI
233    UNSPEC_VEC_VFLL        ; vector fp load lengthened
234    UNSPEC_VEC_VFLR        ; vector fp load rounded
236    UNSPEC_VEC_VFTCI
237    UNSPEC_VEC_VFTCICC
239    UNSPEC_VEC_MSUM
241    UNSPEC_VEC_VFMIN
242    UNSPEC_VEC_VFMAX
244    UNSPEC_TF_TO_FPRX2
246    UNSPEC_NNPA_VCLFNHS_V8HI
247    UNSPEC_NNPA_VCLFNLS_V8HI
248    UNSPEC_NNPA_VCRNFS_V8HI
250    UNSPEC_NNPA_VCFN_V8HI
251    UNSPEC_NNPA_VCNF_V8HI
255 ;; UNSPEC_VOLATILE usage
258 (define_c_enum "unspecv" [
259    ; Blockage
260    UNSPECV_BLOCKAGE
262    ; TPF Support
263    UNSPECV_TPF_PROLOGUE
264    UNSPECV_TPF_EPILOGUE
266    ; Literal pool
267    UNSPECV_POOL
268    UNSPECV_POOL_SECTION
269    UNSPECV_POOL_ALIGN
270    UNSPECV_POOL_ENTRY
271    UNSPECV_MAIN_POOL
273    ; TLS support
274    UNSPECV_SET_TP
276    ; Atomic Support
277    UNSPECV_CAS
278    UNSPECV_ATOMIC_OP
280    ; Non-branch nops used for compare-and-branch adjustments on z10
281    UNSPECV_NOP_LR_0
282    UNSPECV_NOP_LR_1
284    ; Hotpatching (unremovable NOPs)
285    UNSPECV_NOP_2_BYTE
286    UNSPECV_NOP_4_BYTE
287    UNSPECV_NOP_6_BYTE
289    ; Transactional Execution support
290    UNSPECV_TBEGIN
291    UNSPECV_TBEGIN_TDB
292    UNSPECV_TBEGINC
293    UNSPECV_TEND
294    UNSPECV_TABORT
295    UNSPECV_ETND
296    UNSPECV_NTSTG
297    UNSPECV_PPA
299    ; Set and get floating point control register
300    UNSPECV_SFPC
301    UNSPECV_EFPC
303    ; Split stack support
304    UNSPECV_SPLIT_STACK_CALL
306    UNSPECV_OSC_BREAK
307   ])
310 ;; Registers
313 ; Registers with special meaning
315 (define_constants
316   [
317    ; Sibling call register.
318    (SIBCALL_REGNUM               1)
319    ; A call-clobbered reg which can be used in indirect branch thunks
320    (INDIRECT_BRANCH_THUNK_REGNUM 1)
321    ; Literal pool base register.
322    (BASE_REGNUM                 13)
323    ; Return address register.
324    (RETURN_REGNUM               14)
325    ; Stack pointer register.
326    (STACK_REGNUM                15)
327    ; Condition code register.
328    (CC_REGNUM                   33)
329    ; Thread local storage pointer register.
330    (TP_REGNUM                   36)
331   ])
333 ; Hardware register names
335 (define_constants
336   [
337    ; General purpose registers
338    (GPR0_REGNUM                  0)
339    (GPR1_REGNUM                  1)
340    (GPR2_REGNUM                  2)
341    (GPR6_REGNUM                  6)
342    ; Floating point registers.
343    (FPR0_REGNUM                 16)
344    (FPR1_REGNUM                 20)
345    (FPR2_REGNUM                 17)
346    (FPR3_REGNUM                 21)
347    (FPR4_REGNUM                 18)
348    (FPR5_REGNUM                 22)
349    (FPR6_REGNUM                 19)
350    (FPR7_REGNUM                 23)
351    (FPR8_REGNUM                 24)
352    (FPR9_REGNUM                 28)
353    (FPR10_REGNUM                25)
354    (FPR11_REGNUM                29)
355    (FPR12_REGNUM                26)
356    (FPR13_REGNUM                30)
357    (FPR14_REGNUM                27)
358    (FPR15_REGNUM                31)
359    (VR0_REGNUM                  16)
360    (VR16_REGNUM                 38)
361    (VR23_REGNUM                 45)
362    (VR24_REGNUM                 46)
363    (VR31_REGNUM                 53)
364   ])
366 ; Rounding modes for binary floating point numbers
367 (define_constants
368   [(BFP_RND_CURRENT                 0)
369    (BFP_RND_NEAREST_TIE_AWAY_FROM_0 1)
370    (BFP_RND_PREP_FOR_SHORT_PREC     3)
371    (BFP_RND_NEAREST_TIE_TO_EVEN     4)
372    (BFP_RND_TOWARD_0                5)
373    (BFP_RND_TOWARD_INF              6)
374    (BFP_RND_TOWARD_MINF             7)])
376 ; Rounding modes for decimal floating point numbers
377 ; 1-7 were introduced with the floating point extension facility
378 ; available with z196
379 ; With these rounding modes (1-7) a quantum exception might occur
380 ; which is suppressed for the other modes.
381 (define_constants
382   [(DFP_RND_CURRENT                          0)
383    (DFP_RND_NEAREST_TIE_AWAY_FROM_0_QUANTEXC 1)
384    (DFP_RND_CURRENT_QUANTEXC                 2)
385    (DFP_RND_PREP_FOR_SHORT_PREC_QUANTEXC     3)
386    (DFP_RND_NEAREST_TIE_TO_EVEN_QUANTEXC     4)
387    (DFP_RND_TOWARD_0_QUANTEXC                5)
388    (DFP_RND_TOWARD_INF_QUANTEXC              6)
389    (DFP_RND_TOWARD_MINF_QUANTEXC             7)
390    (DFP_RND_NEAREST_TIE_TO_EVEN              8)
391    (DFP_RND_TOWARD_0                         9)
392    (DFP_RND_TOWARD_INF                      10)
393    (DFP_RND_TOWARD_MINF                     11)
394    (DFP_RND_NEAREST_TIE_AWAY_FROM_0         12)
395    (DFP_RND_NEAREST_TIE_TO_0                13)
396    (DFP_RND_AWAY_FROM_0                     14)
397    (DFP_RND_PREP_FOR_SHORT_PREC             15)])
400 ;; PFPO GPR0 argument format
403 (define_constants
404   [
405    ; PFPO operation type
406    (PFPO_CONVERT          0x1000000)
407    ; PFPO operand types
408    (PFPO_OP_TYPE_SF             0x5)
409    (PFPO_OP_TYPE_DF             0x6)
410    (PFPO_OP_TYPE_TF             0x7)
411    (PFPO_OP_TYPE_FPRX2          0x7)
412    (PFPO_OP_TYPE_SD             0x8)
413    (PFPO_OP_TYPE_DD             0x9)
414    (PFPO_OP_TYPE_TD             0xa)
415    ; Bitposition of operand types
416    (PFPO_OP0_TYPE_SHIFT          16)
417    (PFPO_OP1_TYPE_SHIFT           8)
418    ; Decide whether current DFP or BFD rounding mode should be used
419    ; for the conversion.
420    (PFPO_RND_MODE_DFP             0)
421    (PFPO_RND_MODE_BFP             1)
422   ])
424 ;; PPA constants
426 ; Immediate values which can be used as the third operand to the
427 ; perform processor assist instruction
429 (define_constants
430   [(PPA_TX_ABORT                 1)
431    (PPA_OOO_BARRIER             15)])
433 ; Immediate operands for tbegin and tbeginc
434 (define_constants [(TBEGIN_MASK  65292)]) ; 0xff0c
435 (define_constants [(TBEGINC_MASK 65288)]) ; 0xff08
437 ;; Instruction operand type as used in the Principles of Operation.
438 ;; Used to determine defaults for length and other attribute values.
440 (define_attr "op_type"
441   "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"
442   (const_string "NN"))
444 ;; Instruction type attribute used for scheduling.
446 (define_attr "type" "none,integer,load,lr,la,larl,lm,stm,
447                      cs,vs,store,sem,idiv,
448                      imulhi,imulsi,imuldi,
449                      branch,jsr,fsimptf,fsimpdf,fsimpsf,fhex,
450                      floadtf,floaddf,floadsf,fstoredf,fstoresf,
451                      fmultf,fmuldf,fmulsf,fdivtf,fdivdf,fdivsf,
452                      ftoi,fsqrttf,fsqrtdf,fsqrtsf,
453                      fmadddf,fmaddsf,
454                      ftrunctf,ftruncdf, ftruncsd, ftruncdd,
455                      itoftf, itofdf, itofsf, itofdd, itoftd,
456                      fdivdd, fdivtd, floaddd, floadsd, fmuldd, fmultd,
457                      fsimpdd, fsimpsd, fsimptd, fstoredd, fstoresd,
458                      ftoidfp, other"
459   (cond [(eq_attr "op_type" "NN")  (const_string "other")
460          (eq_attr "op_type" "SS")  (const_string "cs")]
461     (const_string "integer")))
463 ;; Another attribute used for scheduling purposes:
464 ;;   agen: Instruction uses the address generation unit
465 ;;   reg: Instruction does not use the agen unit
467 (define_attr "atype" "agen,reg"
468   (if_then_else (eq_attr "op_type" "E,RR,RI,RRE,RSI,RIL,RIE,RRF")
469                 (const_string "reg")
470                 (const_string "agen")))
472 ;; Properties concerning Z10 execution grouping and value forwarding.
473 ;; z10_super: instruction is superscalar.
474 ;; z10_super_c: instruction is superscalar and meets the condition of z10_c.
475 ;; z10_fwd: The instruction reads the value of an operand and stores it into a
476 ;;   target register.  It can forward this value to a second instruction that reads
477 ;;   the same register if that second instruction is issued in the same group.
478 ;; z10_rec: The instruction is in the T pipeline and reads a register. If the
479 ;;   instruction in the S pipe writes to the register, then the T instruction
480 ;;   can immediately read the new value.
481 ;; z10_fr: union of Z10_fwd and z10_rec.
482 ;; z10_c: second operand of instruction is a register and read with complemented bits.
484 ;; An additional suffix A1, A3, or E1 indicates the respective AGI bypass.
487 (define_attr "z10prop" "none,
488                         z10_super, z10_super_E1, z10_super_A1, z10_super_c, z10_super_c_E1,
489                         z10_fwd, z10_fwd_A1, z10_fwd_A3, z10_fwd_E1,
490                         z10_rec,
491                         z10_fr, z10_fr_A3, z10_fr_E1,
492                         z10_c"
493              (const_string "none"))
495 ;; Properties concerning Z196 decoding
496 ;; z196_alone: must group alone
497 ;; z196_end: ends a group
498 ;; z196_cracked: instruction is cracked or expanded
499 (define_attr "z196prop" "none,
500                          z196_alone, z196_ends,
501                          z196_cracked"
502              (const_string "none"))
504 ; mnemonics which only get defined through if_then_else currently
505 ; don't get added to the list values automatically and hence need to
506 ; be listed here.
507 (define_attr "mnemonic" "b,bas,basr,bc,bcr_flush,unknown" (const_string "unknown"))
509 ;; Length in bytes.
511 (define_attr "length" ""
512   (cond [(eq_attr "op_type" "E,RR")                       (const_int 2)
513          (eq_attr "op_type" "RX,RI,RRE,RS,RSI,S,SI,RRF")  (const_int 4)]
514     (const_int 6)))
517 ;; Processor type.  This attribute must exactly match the processor_type
518 ;; enumeration in s390.h.
520 (define_attr "cpu" "z900,z990,z9_109,z9_ec,z10,z196,zEC12,z13,z14,z15,z16"
521   (const (symbol_ref "s390_tune_attr")))
523 (define_attr "cpu_facility"
524   "standard,ieee,zarch,cpu_zarch,longdisp,extimm,dfp,z10,z196,zEC12,vx,z13,z14,vxe,z15,vxe2,z16,nnpa"
525   (const_string "standard"))
527 (define_attr "enabled" ""
528   (cond [(eq_attr "cpu_facility" "standard")
529          (const_int 1)
531          (and (eq_attr "cpu_facility" "ieee")
532               (match_test "TARGET_CPU_IEEE_FLOAT"))
533          (const_int 1)
535          (and (eq_attr "cpu_facility" "zarch")
536               (match_test "TARGET_ZARCH"))
537          (const_int 1)
539          (and (eq_attr "cpu_facility" "longdisp")
540               (match_test "TARGET_LONG_DISPLACEMENT"))
541          (const_int 1)
543          (and (eq_attr "cpu_facility" "extimm")
544               (match_test "TARGET_EXTIMM"))
545          (const_int 1)
547          (and (eq_attr "cpu_facility" "dfp")
548               (match_test "TARGET_DFP"))
549          (const_int 1)
551          (eq_attr "cpu_facility" "cpu_zarch")
552          (const_int 1)
554          (and (eq_attr "cpu_facility" "z10")
555               (match_test "TARGET_Z10"))
556          (const_int 1)
558          (and (eq_attr "cpu_facility" "z196")
559               (match_test "TARGET_Z196"))
560          (const_int 1)
562          (and (eq_attr "cpu_facility" "zEC12")
563               (match_test "TARGET_ZEC12"))
564          (const_int 1)
566          (and (eq_attr "cpu_facility" "vx")
567               (match_test "TARGET_VX"))
568          (const_int 1)
570          (and (eq_attr "cpu_facility" "z13")
571               (match_test "TARGET_Z13"))
572          (const_int 1)
574          (and (eq_attr "cpu_facility" "z14")
575               (match_test "TARGET_Z14"))
576          (const_int 1)
578          (and (eq_attr "cpu_facility" "vxe")
579               (match_test "TARGET_VXE"))
580          (const_int 1)
582          (and (eq_attr "cpu_facility" "z15")
583               (match_test "TARGET_Z15"))
584          (const_int 1)
586          (and (eq_attr "cpu_facility" "vxe2")
587               (match_test "TARGET_VXE2"))
588          (const_int 1)
590          (and (eq_attr "cpu_facility" "z16")
591               (match_test "TARGET_Z16"))
592          (const_int 1)
594          (and (eq_attr "cpu_facility" "nnpa")
595               (match_test "TARGET_NNPA"))
596          (const_int 1)
598         (const_int 0)))
600 ;; Whether an instruction supports relative long addressing.
601 ;; Currently this corresponds to RIL-b and RIL-c instruction formats,
602 ;; but having a separate attribute, as opposed to reusing op_type,
603 ;; provides additional flexibility.
605 (define_attr "relative_long" "no,yes" (const_string "no"))
607 (define_code_attr extend_insn [(sign_extend "extend") (zero_extend "zero_extend")])
608 (define_code_attr zero_extend [(sign_extend "") (zero_extend "l")])
609 (define_code_iterator any_extend [sign_extend zero_extend])
611 ;; Pipeline description for z900.
612 (include "2064.md")
614 ;; Pipeline description for z990, z9-109 and z9-ec.
615 (include "2084.md")
617 ;; Pipeline description for z10
618 (include "2097.md")
620 ;; Pipeline description for z196
621 (include "2817.md")
623 ;; Pipeline description for zEC12
624 (include "2827.md")
626 ;; Pipeline description for z13
627 (include "2964.md")
629 ;; Pipeline description for z14
630 (include "3906.md")
632 ;; Pipeline description for z15
633 (include "8561.md")
635 ;; Pipeline description for z16
636 (include "3931.md")
638 ;; Predicates
639 (include "predicates.md")
641 ;; Constraint definitions
642 (include "constraints.md")
644 ;; Other includes
645 (include "tpf.md")
647 ;; Iterators
649 (define_mode_iterator ALL [TI DI SI HI QI TF FPRX2 DF SF TD DD SD V1QI V2QI
650                            V4QI V8QI V16QI V1HI V2HI V4HI V8HI V1SI V2SI V4SI
651                            V1DI V2DI V1SF V2SF V4SF V1TI V1DF V2DF V1TF])
653 ;; These mode iterators allow floating point patterns to be generated from the
654 ;; same template.
655 (define_mode_iterator FP_ALL [(TF "!TARGET_VXE") (FPRX2 "TARGET_VXE") DF SF
656                               (TD "TARGET_HARD_DFP") (DD "TARGET_HARD_DFP")
657                               (SD "TARGET_HARD_DFP")])
658 (define_mode_iterator FP [(TF "!TARGET_VXE") (FPRX2 "TARGET_VXE") DF SF
659                           (TD "TARGET_HARD_DFP") (DD "TARGET_HARD_DFP")])
660 ;; Like FP, but without a condition on TF. Useful for expanders that must be
661 ;; the same for FP and VR variants of TF.
662 (define_mode_iterator FP_ANYTF [TF (FPRX2 "TARGET_VXE") DF SF
663                                 (TD "TARGET_HARD_DFP")
664                                 (DD "TARGET_HARD_DFP")])
665 (define_mode_iterator BFP [(TF "!TARGET_VXE") (FPRX2 "TARGET_VXE") DF SF])
666 (define_mode_iterator DFP [TD DD])
667 (define_mode_iterator DFP_ALL [TD DD SD])
668 (define_mode_iterator DSF [DF SF])
669 (define_mode_iterator SD_SF [SF SD])
670 (define_mode_iterator DD_DF [DF DD])
671 (define_mode_iterator TD_TF [(TF "!TARGET_VXE") (FPRX2 "TARGET_VXE") TD])
673 ; 32 bit int<->fp conversion instructions are available since VXE2 (z15).
674 (define_mode_iterator VX_CONV_BFP [DF (SF "TARGET_VXE2")])
676 ;; These mode iterators allow 31-bit and 64-bit GPR patterns to be generated
677 ;; from the same template.
678 (define_mode_iterator GPR [(DI "TARGET_ZARCH") SI])
679 (define_mode_iterator DGPR [(TI "TARGET_ZARCH") DI SI])
680 (define_mode_iterator DSI [DI SI])
681 (define_mode_iterator TDI [TI DI])
683 ;; These mode iterators allow :P to be used for patterns that operate on
684 ;; pointer-sized quantities.  Exactly one of the two alternatives will match.
685 (define_mode_iterator P [(DI "TARGET_64BIT") (SI "!TARGET_64BIT")])
687 ;; These macros refer to the actual word_mode of the configuration.
688 ;; This is equal to Pmode except on 31-bit machines in zarch mode.
689 (define_mode_iterator DW [(TI "TARGET_ZARCH") (DI "!TARGET_ZARCH")])
690 (define_mode_iterator W  [(DI "TARGET_ZARCH") (SI "!TARGET_ZARCH")])
692 ;; Used by the umul pattern to express modes having half the size.
693 (define_mode_attr DWH [(TI "DI") (DI "SI")])
694 (define_mode_attr dwh [(TI "di") (DI "si")])
696 ;; This mode iterator allows the QI and HI patterns to be defined from
697 ;; the same template.
698 (define_mode_iterator HQI [HI QI])
700 ;; This mode iterator allows the integer patterns to be defined from the
701 ;; same template.
702 (define_mode_iterator INT [(DI "TARGET_ZARCH") SI HI QI])
703 (define_mode_iterator DINT [(TI "TARGET_ZARCH") DI SI HI QI])
704 (define_mode_iterator SINT [SI HI QI])
706 ;; This iterator allows some 'ashift' and 'lshiftrt' pattern to be defined from
707 ;; the same template.
708 (define_code_iterator SHIFT [ashift lshiftrt])
710 ;; This iterator allows r[ox]sbg to be defined with the same template
711 (define_code_iterator IXOR [ior xor])
713 ;; This is used for merging the nand/nor and and/or with complement patterns
714 (define_code_iterator ANDOR [and ior])
715 (define_code_attr bitops_name [(and "and") (ior "or")])
716 (define_code_attr inv_bitops_name [(and "or") (ior "and")])
717 (define_code_attr inv_no [(and "o") (ior "n")])
719 ;; This iterator is used to expand the patterns for the nearest
720 ;; integer functions.
721 (define_int_iterator FPINT [UNSPEC_FPINT_FLOOR UNSPEC_FPINT_BTRUNC
722                             UNSPEC_FPINT_ROUND UNSPEC_FPINT_CEIL
723                             UNSPEC_FPINT_NEARBYINT])
724 (define_int_attr fpint_name [(UNSPEC_FPINT_FLOOR "floor")
725                              (UNSPEC_FPINT_BTRUNC "btrunc")
726                              (UNSPEC_FPINT_ROUND "round")
727                              (UNSPEC_FPINT_CEIL "ceil")
728                              (UNSPEC_FPINT_NEARBYINT "nearbyint")])
729 (define_int_attr fpint_roundingmode [(UNSPEC_FPINT_FLOOR "7")
730                                      (UNSPEC_FPINT_BTRUNC "5")
731                                      (UNSPEC_FPINT_ROUND "1")
732                                      (UNSPEC_FPINT_CEIL "6")
733                                      (UNSPEC_FPINT_NEARBYINT "0")])
735 ;; This iterator and attribute allow to combine most atomic operations.
736 (define_code_iterator ATOMIC [and ior xor plus minus mult])
737 (define_code_iterator ATOMIC_Z196 [and ior xor plus])
738 (define_code_attr atomic [(and "and") (ior "or") (xor "xor")
739                           (plus "add") (minus "sub") (mult "nand")])
740 (define_code_attr noxa [(and "n") (ior "o") (xor "x") (plus "a")])
742 ;; In FP templates, a string like "lt<de>br" will expand to "ltxbr" in
743 ;; TF/TDmode, "ltdbr" in DF/DDmode, and "ltebr" in SF/SDmode.
744 (define_mode_attr xde [(TF "x") (FPRX2 "x") (DF "d") (SF "e") (TD "x")
745                        (DD "d") (SD "e") (V4SF "e") (V2DF "d")])
747 ;; In FP templates, a <dee> in "m<dee><bt>r" will expand to "mx<bt>r" in
748 ;; TF/TDmode, "md<bt>r" in DF/DDmode, "mee<bt>r" in SFmode and "me<bt>r in
749 ;; SDmode.
750 (define_mode_attr xdee [(TF "x") (FPRX2 "x") (DF "d") (SF "ee") (TD "x") (DD "d") (SD "e")])
752 ;; The decimal floating point variants of add, sub, div and mul support 3
753 ;; fp register operands.  The following attributes allow to merge the bfp and
754 ;; dfp variants in a single insn definition.
756 ;; These mode attributes are supposed to be used in the `enabled' insn
757 ;; attribute to disable certain alternatives for certain modes.
758 (define_mode_attr nBFP [(TF "0") (FPRX2 "0") (DF "0") (SF "0") (TD "*")
759                         (DD "*") (DD "*")])
760 (define_mode_attr nDFP [(TF "*") (FPRX2 "*") (DF "*") (SF "*") (TD "0")
761                         (DD "0") (DD "0")])
762 (define_mode_attr DSF [(TF "0") (FPRX2 "0") (DF "*") (SF "*") (TD "0")
763                        (DD "0") (SD "0")])
764 (define_mode_attr DFDI [(TF "0") (FPRX2 "0") (DF "*") (SF "0")
765                         (TD "0") (DD "0") (DD "0")
766                         (TI "0") (DI "*") (SI "0")])
767 (define_mode_attr SFSI [(TF "0") (FPRX2 "0") (DF "0") (SF "*")
768                         (TD "0") (DD "0") (DD "0")
769                         (TI "0") (DI "0") (SI "*")])
770 (define_mode_attr DF [(TF "0") (FPRX2 "0") (DF "*") (SF "0")
771                       (TD "0") (DD "0") (DD "0")
772                       (TI "0") (DI "0") (SI "0")])
773 (define_mode_attr SF [(TF "0") (FPRX2 "0") (DF "0") (SF "*")
774                       (TD "0") (DD "0") (DD "0")
775                       (TI "0") (DI "0") (SI "0")])
777 ;; This attribute is used in the operand constraint list
778 ;; for instructions dealing with the sign bit of 32 or 64bit fp values.
779 ;; TFmode values are represented by a fp register pair.  Since the
780 ;; sign bit instructions only handle single source and target fp registers
781 ;; these instructions can only be used for TFmode values if the source and
782 ;; target operand uses the same fp register.
783 (define_mode_attr fT0 [(TF "0") (FPRX2 "0") (DF "f") (SF "f")])
785 ;; This attribute adds b for bfp instructions and t for dfp instructions and is used
786 ;; within instruction mnemonics.
787 (define_mode_attr bt [(TF "b") (FPRX2 "b") (DF "b") (SF "b") (TD "t") (DD "t")
788                       (SD "t")])
790 ;; This attribute is used within instruction mnemonics.  It evaluates to d for dfp
791 ;; modes and to an empty string for bfp modes.
792 (define_mode_attr _d [(TF "") (FPRX2 "") (DF "") (SF "") (TD "d") (DD "d")
793                       (SD "d")])
795 ;; In GPR and P templates, a constraint like "<d0>" will expand to "d" in DImode
796 ;; and "0" in SImode. This allows to combine instructions of which the 31bit
797 ;; version only operates on one register.
798 (define_mode_attr d0 [(DI "d") (SI "0")])
800 ;; In combination with d0 this allows to combine instructions of which the 31bit
801 ;; version only operates on one register. The DImode version needs an additional
802 ;; register for the assembler output.
803 (define_mode_attr 1 [(DI "%1,") (SI "")])
805 ;; In SHIFT templates, a string like "s<lr>dl" will expand to "sldl" in
806 ;; 'ashift' and "srdl" in 'lshiftrt'.
807 (define_code_attr lr [(ashift "l") (lshiftrt "r")])
809 ;; In SHIFT templates, this attribute holds the correct standard name for the
810 ;; pattern itself and the corresponding function calls.
811 (define_code_attr shift [(ashift "ashl") (lshiftrt "lshr")])
813 ;; This attribute handles differences in the instruction 'type' and will result
814 ;; in "RRE" for DImode and "RR" for SImode.
815 (define_mode_attr E [(DI "E") (SI "")])
817 ;; This attribute handles differences in the instruction 'type' and makes RX<Y>
818 ;; to result in "RXY" for DImode and "RX" for SImode.
819 (define_mode_attr Y [(DI "Y") (SI "")])
821 ;; This attribute handles differences in the instruction 'type' and will result
822 ;; in "RSE" for TImode and "RS" for DImode.
823 (define_mode_attr TE [(TI "E") (DI "")])
825 ;; In GPR templates, a string like "lc<g>r" will expand to "lcgr" in DImode
826 ;; and "lcr" in SImode.
827 (define_mode_attr g [(DI "g") (SI "")])
829 ;; In GPR templates, a string like "sl<y>" will expand to "slg" in DImode
830 ;; and "sly" in SImode. This is useful because on 64bit the ..g instructions
831 ;; were enhanced with long displacements whereas 31bit instructions got a ..y
832 ;; variant for long displacements.
833 (define_mode_attr y [(DI "g") (SI "y")])
835 ;; In DW templates, a string like "cds<g>" will expand to "cdsg" in TImode
836 ;; and "cds" in DImode.
837 (define_mode_attr tg [(TI "g") (DI "")])
839 ;; In TDI templates, a string like "c<d>sg".
840 (define_mode_attr td [(TI "d") (DI "")])
842 ;; In GPR templates, a string like "c<gf>dbr" will expand to "cgdbr" in DImode
843 ;; and "cfdbr" in SImode.
844 (define_mode_attr gf [(DI "g") (SI "f") (DF "g") (SF "f")])
846 ;; In GPR templates, a string like sll<gk> will expand to sllg for DI
847 ;; and sllk for SI.  This way it is possible to merge the new z196 SI
848 ;; 3 operands shift instructions into the existing patterns.
849 (define_mode_attr gk [(DI "g") (SI "k")])
851 ;; ICM mask required to load MODE value into the lowest subreg
852 ;; of a SImode register.
853 (define_mode_attr icm_lo [(HI "3") (QI "1")])
855 ;; In HQI templates, a string like "llg<hc>" will expand to "llgh" in
856 ;; HImode and "llgc" in QImode.
857 (define_mode_attr hc [(HI "h") (QI "c")])
859 ;; In P templates, the mode <DBL> will expand to "TI" in DImode and "DI"
860 ;; in SImode.
861 (define_mode_attr DBL [(DI "TI") (SI "DI")])
863 ;; This attribute expands to DF for TFmode and to DD for TDmode .  It is
864 ;; used for Txmode splitters splitting a Txmode copy into 2 Dxmode copies.
865 (define_mode_attr HALF_TMODE [(TF "DF") (FPRX2 "DF") (TD "DD")])
867 ;; Maximum unsigned integer that fits in MODE.
868 (define_mode_attr max_uint [(HI "65535") (QI "255")])
870 ;; Start and end field computations for RISBG et al.
871 (define_mode_attr bfstart [(DI "s") (SI "t")])
872 (define_mode_attr bfend   [(DI "e") (SI "f")])
874 ;; In place of GET_MODE_BITSIZE (<MODE>mode)
875 (define_mode_attr bitsize [(DI "64") (SI "32") (HI "16") (QI "8")])
876 ;; 64 - bitsize
877 (define_mode_attr bitoff [(DI "0") (SI "32") (HI "48") (QI "56")])
878 (define_mode_attr bitoff_plus [(DI "") (SI "32+") (HI "48+") (QI "56+")])
880 ;; In place of GET_MODE_SIZE (<MODE>mode)
881 (define_mode_attr modesize [(DI "8") (SI "4")])
883 ;; Allow return and simple_return to be defined from a single template.
884 (define_code_iterator ANY_RETURN [return simple_return])
886 ;; Facilitate dispatching TFmode expanders on z14+.
887 (define_mode_attr tf_fpr [(TF "_fpr") (FPRX2 "") (DF "") (SF "") (TD "")
888                           (DD "") (SD "")])
890 ;; Mode names as seen in type mode_attr values.
891 (define_mode_attr type [(TF "tf") (FPRX2 "tf") (DF "df") (SF "sf") (TD "td")
892                         (DD "dd") (SD "sd")])
895 ; Condition code modes generated by vector fp comparisons.  These will
896 ; be used also in single element mode.
897 (define_mode_iterator VFCMP [CCVEQ CCVFH CCVFHE])
898 ; Used with VFCMP to expand part of the mnemonic
899 ; For fp we have a mismatch: eq in the insn name - e in asm
900 (define_mode_attr asm_fcmp [(CCVEQ "e") (CCVFH "h") (CCVFHE "he")])
901 (define_mode_attr insn_cmp [(CCVEQ "eq") (CCVIH "h") (CCVIHU "hl") (CCVFH "h") (CCVFHE "he")])
903 ; Analogue to TOINTVEC / tointvec
904 (define_mode_attr TOINT [(TF "TI") (DF "DI") (SF "SI")])
905 (define_mode_attr toint [(TF "ti") (DF "di") (SF "si")])
907 ;; Subst pattern definitions
908 (include "subst.md")
910 (include "vector.md")
913 ;;- Compare instructions.
916 ; Test-under-Mask instructions
918 (define_insn "*tmqi_mem"
919   [(set (reg CC_REGNUM)
920         (compare (and:QI (match_operand:QI 0 "memory_operand" "Q,S")
921                          (match_operand:QI 1 "immediate_operand" "n,n"))
922                  (match_operand:QI 2 "immediate_operand" "n,n")))]
923   "s390_match_ccmode (insn, s390_tm_ccmode (operands[1], operands[2], false))"
924   "@
925    tm\t%S0,%b1
926    tmy\t%S0,%b1"
927   [(set_attr "op_type" "SI,SIY")
928    (set_attr "cpu_facility" "*,longdisp")
929    (set_attr "z10prop" "z10_super,z10_super")])
931 (define_insn "*tmdi_reg"
932   [(set (reg CC_REGNUM)
933         (compare (and:DI (match_operand:DI 0 "nonimmediate_operand" "d,d,d,d")
934                          (match_operand:DI 1 "immediate_operand"
935                                              "N0HD0,N1HD0,N2HD0,N3HD0"))
936                  (match_operand:DI 2 "immediate_operand" "n,n,n,n")))]
937   "TARGET_ZARCH
938    && s390_match_ccmode (insn, s390_tm_ccmode (operands[1], operands[2], true))
939    && s390_single_part (operands[1], DImode, HImode, 0) >= 0"
940   "@
941    tmhh\t%0,%i1
942    tmhl\t%0,%i1
943    tmlh\t%0,%i1
944    tmll\t%0,%i1"
945   [(set_attr "op_type" "RI")
946    (set_attr "z10prop" "z10_super,z10_super,z10_super,z10_super")])
948 (define_insn "*tmsi_reg"
949   [(set (reg CC_REGNUM)
950         (compare (and:SI (match_operand:SI 0 "nonimmediate_operand" "d,d")
951                          (match_operand:SI 1 "immediate_operand" "N0HS0,N1HS0"))
952                  (match_operand:SI 2 "immediate_operand" "n,n")))]
953   "s390_match_ccmode (insn, s390_tm_ccmode (operands[1], operands[2], true))
954    && s390_single_part (operands[1], SImode, HImode, 0) >= 0"
955   "@
956    tmh\t%0,%i1
957    tml\t%0,%i1"
958   [(set_attr "op_type" "RI")
959    (set_attr "z10prop" "z10_super,z10_super")])
961 (define_insn "*tm<mode>_full"
962   [(set (reg CC_REGNUM)
963         (compare (match_operand:HQI 0 "register_operand" "d")
964                  (match_operand:HQI 1 "immediate_operand" "n")))]
965   "s390_match_ccmode (insn, s390_tm_ccmode (constm1_rtx, operands[1], true))"
966   "tml\t%0,<max_uint>"
967   [(set_attr "op_type" "RI")
968    (set_attr "z10prop" "z10_super")])
972 ; Load-and-Test instructions
975 ; tst(di|si) instruction pattern(s).
977 (define_insn "*tstdi_sign"
978   [(set (reg CC_REGNUM)
979         (compare
980           (ashiftrt:DI
981             (ashift:DI
982               (subreg:DI (match_operand:SI 0 "nonimmediate_operand" "d,T") 0)
983               (const_int 32)) (const_int 32))
984           (match_operand:DI 1 "const0_operand" "")))
985    (set (match_operand:DI 2 "register_operand" "=d,d")
986         (sign_extend:DI (match_dup 0)))]
987   "s390_match_ccmode(insn, CCSmode) && TARGET_ZARCH"
988   "ltgfr\t%2,%0
989    ltgf\t%2,%0"
990   [(set_attr "op_type"      "RRE,RXY")
991    (set_attr "cpu_facility" "*,z10")
992    (set_attr "z10prop" "z10_super_E1,z10_super_E1") ])
994 ; ltr, lt, ltgr, ltg
995 (define_insn "*tst<mode>_extimm"
996   [(set (reg CC_REGNUM)
997         (compare (match_operand:GPR 0 "nonimmediate_operand" "d,T")
998                  (match_operand:GPR 1 "const0_operand" "")))
999    (set (match_operand:GPR 2 "register_operand" "=d,d")
1000         (match_dup 0))]
1001   "s390_match_ccmode(insn, CCSmode) && TARGET_EXTIMM"
1002   "@
1003    lt<g>r\t%2,%0
1004    lt<g>\t%2,%0"
1005   [(set_attr "op_type" "RR<E>,RXY")
1006    (set_attr "z10prop" "z10_fr_E1,z10_fwd_A3") ])
1008 ; Peephole to combine a load-and-test from volatile memory which combine does
1009 ; not do.
1010 (define_peephole2
1011   [(set (match_operand:GPR 0 "register_operand")
1012         (match_operand:GPR 2 "memory_operand"))
1013    (set (reg CC_REGNUM)
1014         (compare (match_dup 0) (match_operand:GPR 1 "const0_operand")))]
1015   "s390_match_ccmode (peep2_next_insn (1), CCSmode) && TARGET_EXTIMM
1016    && GENERAL_REG_P (operands[0])
1017    && satisfies_constraint_T (operands[2])
1018    && !contains_constant_pool_address_p (operands[2])"
1019   [(parallel
1020     [(set (reg:CCS CC_REGNUM)
1021           (compare:CCS (match_dup 2) (match_dup 1)))
1022      (set (match_dup 0) (match_dup 2))])])
1024 ; ltr, lt, ltgr, ltg
1025 (define_insn "*tst<mode>_cconly_extimm"
1026   [(set (reg CC_REGNUM)
1027         (compare (match_operand:GPR 0 "nonimmediate_operand" "d,T")
1028                  (match_operand:GPR 1 "const0_operand" "")))
1029    (clobber (match_scratch:GPR 2 "=X,d"))]
1030   "s390_match_ccmode(insn, CCSmode) && TARGET_EXTIMM"
1031   "@
1032    lt<g>r\t%0,%0
1033    lt<g>\t%2,%0"
1034   [(set_attr "op_type" "RR<E>,RXY")
1035    (set_attr "z10prop" "z10_fr_E1,z10_fwd_A3")])
1037 (define_insn "*tstdi"
1038   [(set (reg CC_REGNUM)
1039         (compare (match_operand:DI 0 "register_operand" "d")
1040                  (match_operand:DI 1 "const0_operand" "")))
1041    (set (match_operand:DI 2 "register_operand" "=d")
1042         (match_dup 0))]
1043   "s390_match_ccmode(insn, CCSmode) && TARGET_ZARCH && !TARGET_EXTIMM"
1044   "ltgr\t%2,%0"
1045   [(set_attr "op_type" "RRE")
1046    (set_attr "z10prop" "z10_fr_E1")])
1048 (define_insn "*tstsi"
1049   [(set (reg CC_REGNUM)
1050         (compare (match_operand:SI 0 "nonimmediate_operand" "d,Q,S")
1051                  (match_operand:SI 1 "const0_operand" "")))
1052    (set (match_operand:SI 2 "register_operand" "=d,d,d")
1053         (match_dup 0))]
1054   "s390_match_ccmode(insn, CCSmode) && !TARGET_EXTIMM"
1055   "@
1056    ltr\t%2,%0
1057    icm\t%2,15,%S0
1058    icmy\t%2,15,%S0"
1059   [(set_attr "op_type" "RR,RS,RSY")
1060    (set_attr "cpu_facility" "*,*,longdisp")
1061    (set_attr "z10prop" "z10_fr_E1,z10_super_E1,z10_super_E1")])
1063 (define_insn "*tstsi_cconly"
1064   [(set (reg CC_REGNUM)
1065         (compare (match_operand:SI 0 "nonimmediate_operand" "d,Q,S")
1066                  (match_operand:SI 1 "const0_operand" "")))
1067    (clobber (match_scratch:SI 2 "=X,d,d"))]
1068   "s390_match_ccmode(insn, CCSmode)"
1069   "@
1070    ltr\t%0,%0
1071    icm\t%2,15,%S0
1072    icmy\t%2,15,%S0"
1073   [(set_attr "op_type" "RR,RS,RSY")
1074    (set_attr "cpu_facility" "*,*,longdisp")
1075    (set_attr "z10prop" "z10_fr_E1,z10_super_E1,z10_super_E1")])
1077 (define_insn "*tstdi_cconly_31"
1078   [(set (reg CC_REGNUM)
1079         (compare (match_operand:DI 0 "register_operand" "d")
1080                  (match_operand:DI 1 "const0_operand" "")))]
1081   "s390_match_ccmode(insn, CCSmode) && !TARGET_ZARCH"
1082   "srda\t%0,0"
1083   [(set_attr "op_type" "RS")
1084    (set_attr "atype"   "reg")])
1086 ; ltr, ltgr
1087 (define_insn "*tst<mode>_cconly2"
1088   [(set (reg CC_REGNUM)
1089         (compare (match_operand:GPR 0 "register_operand" "d")
1090                  (match_operand:GPR 1 "const0_operand" "")))]
1091   "s390_match_ccmode(insn, CCSmode)"
1092   "lt<g>r\t%0,%0"
1093   [(set_attr "op_type" "RR<E>")
1094    (set_attr "z10prop" "z10_fr_E1")])
1096 ; tst(hi|qi) instruction pattern(s).
1098 (define_insn "*tst<mode>CCT"
1099   [(set (reg CC_REGNUM)
1100         (compare (match_operand:HQI 0 "nonimmediate_operand" "?Q,?S,d")
1101                  (match_operand:HQI 1 "const0_operand" "")))
1102    (set (match_operand:HQI 2 "register_operand" "=d,d,0")
1103         (match_dup 0))]
1104   "s390_match_ccmode(insn, CCTmode)"
1105   "@
1106    icm\t%2,<icm_lo>,%S0
1107    icmy\t%2,<icm_lo>,%S0
1108    tml\t%0,<max_uint>"
1109   [(set_attr "op_type" "RS,RSY,RI")
1110    (set_attr "cpu_facility" "*,longdisp,*")
1111    (set_attr "z10prop" "z10_super_E1,z10_super_E1,z10_super")])
1113 (define_insn "*tsthiCCT_cconly"
1114   [(set (reg CC_REGNUM)
1115         (compare (match_operand:HI 0 "nonimmediate_operand" "Q,S,d")
1116                  (match_operand:HI 1 "const0_operand" "")))
1117    (clobber (match_scratch:HI 2 "=d,d,X"))]
1118   "s390_match_ccmode(insn, CCTmode)"
1119   "@
1120    icm\t%2,3,%S0
1121    icmy\t%2,3,%S0
1122    tml\t%0,65535"
1123   [(set_attr "op_type" "RS,RSY,RI")
1124    (set_attr "cpu_facility" "*,longdisp,*")
1125    (set_attr "z10prop" "z10_super_E1,z10_super_E1,z10_super")])
1127 (define_insn "*tstqiCCT_cconly"
1128   [(set (reg CC_REGNUM)
1129         (compare (match_operand:QI 0 "nonimmediate_operand" "?Q,?S,d")
1130                  (match_operand:QI 1 "const0_operand" "")))]
1131   "s390_match_ccmode(insn, CCTmode)"
1132   "@
1133    cli\t%S0,0
1134    cliy\t%S0,0
1135    tml\t%0,255"
1136   [(set_attr "op_type" "SI,SIY,RI")
1137    (set_attr "cpu_facility" "*,longdisp,*")
1138    (set_attr "z10prop" "z10_super,z10_super,z10_super")])
1140 (define_insn "*tst<mode>"
1141   [(set (reg CC_REGNUM)
1142         (compare (match_operand:HQI 0 "s_operand" "Q,S")
1143                  (match_operand:HQI 1 "const0_operand" "")))
1144    (set (match_operand:HQI 2 "register_operand" "=d,d")
1145         (match_dup 0))]
1146   "s390_match_ccmode(insn, CCSmode)"
1147   "@
1148    icm\t%2,<icm_lo>,%S0
1149    icmy\t%2,<icm_lo>,%S0"
1150   [(set_attr "op_type" "RS,RSY")
1151    (set_attr "cpu_facility" "*,longdisp")
1152    (set_attr "z10prop" "z10_super_E1,z10_super_E1")])
1154 (define_insn "*tst<mode>_cconly"
1155   [(set (reg CC_REGNUM)
1156         (compare (match_operand:HQI 0 "s_operand" "Q,S")
1157                  (match_operand:HQI 1 "const0_operand" "")))
1158    (clobber (match_scratch:HQI 2 "=d,d"))]
1159   "s390_match_ccmode(insn, CCSmode)"
1160   "@
1161    icm\t%2,<icm_lo>,%S0
1162    icmy\t%2,<icm_lo>,%S0"
1163   [(set_attr "op_type" "RS,RSY")
1164    (set_attr "cpu_facility" "*,longdisp")
1165    (set_attr "z10prop" "z10_super_E1,z10_super_E1")])
1168 ; Compare (equality) instructions
1170 (define_insn "*cmpdi_cct"
1171   [(set (reg CC_REGNUM)
1172         (compare (match_operand:DI 0 "nonimmediate_operand" "%d,d,d,d,Q")
1173                  (match_operand:DI 1 "general_operand" "d,K,Os,T,BQ")))]
1174   "s390_match_ccmode (insn, CCTmode) && TARGET_ZARCH"
1175   "@
1176    cgr\t%0,%1
1177    cghi\t%0,%h1
1178    cgfi\t%0,%1
1179    cg\t%0,%1
1180    #"
1181   [(set_attr "op_type" "RRE,RI,RIL,RXY,SS")
1182    (set_attr "z10prop" "z10_super_c,z10_super,z10_super,z10_super,*")])
1184 (define_insn "*cmpsi_cct"
1185   [(set (reg CC_REGNUM)
1186         (compare (match_operand:SI 0 "nonimmediate_operand" "%d,d,d,d,d,Q")
1187                  (match_operand:SI 1 "general_operand" "d,K,Os,R,T,BQ")))]
1188   "s390_match_ccmode (insn, CCTmode)"
1189   "@
1190    cr\t%0,%1
1191    chi\t%0,%h1
1192    cfi\t%0,%1
1193    c\t%0,%1
1194    cy\t%0,%1
1195    #"
1196   [(set_attr "op_type" "RR,RI,RIL,RX,RXY,SS")
1197    (set_attr "cpu_facility" "*,*,*,*,longdisp,*")
1198    (set_attr "z10prop" "z10_super_c,z10_super,z10_super,z10_super,z10_super,*")])
1200 ; Compare (signed) instructions
1202 (define_insn "*cmpdi_ccs_sign"
1203   [(set (reg CC_REGNUM)
1204         (compare (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand"
1205                                                      "d,T,b"))
1206                  (match_operand:DI 0 "register_operand" "d, d,d")))]
1207   "s390_match_ccmode(insn, CCSRmode) && TARGET_ZARCH"
1208   "@
1209    cgfr\t%0,%1
1210    cgf\t%0,%1
1211    cgfrl\t%0,%1"
1212   [(set_attr "op_type"      "RRE,RXY,RIL")
1213    (set_attr "z10prop" "z10_c,*,*")
1214    (set_attr "type"         "*,*,larl")
1215    (set_attr "relative_long" "*,*,yes")])
1219 (define_insn "*cmpsi_ccs_sign"
1220   [(set (reg CC_REGNUM)
1221         (compare (sign_extend:SI (match_operand:HI 1 "memory_operand" "R,T,b"))
1222                  (match_operand:SI 0 "register_operand" "d,d,d")))]
1223   "s390_match_ccmode(insn, CCSRmode)"
1224   "@
1225    ch\t%0,%1
1226    chy\t%0,%1
1227    chrl\t%0,%1"
1228   [(set_attr "op_type"      "RX,RXY,RIL")
1229    (set_attr "cpu_facility" "*,longdisp,z10")
1230    (set_attr "type"         "*,*,larl")
1231    (set_attr "z196prop" "z196_cracked,z196_cracked,z196_cracked")
1232    (set_attr "relative_long" "*,*,yes")])
1234 (define_insn "*cmphi_ccs_z10"
1235   [(set (reg CC_REGNUM)
1236         (compare (match_operand:HI 0 "s_operand"         "Q")
1237                  (match_operand:HI 1 "immediate_operand" "K")))]
1238   "s390_match_ccmode(insn, CCSmode) && TARGET_Z10"
1239   "chhsi\t%0,%1"
1240   [(set_attr "op_type" "SIL")
1241    (set_attr "z196prop" "z196_cracked")])
1243 (define_insn "*cmpdi_ccs_signhi_rl"
1244   [(set (reg CC_REGNUM)
1245         (compare (sign_extend:DI (match_operand:HI 1 "memory_operand" "T,b"))
1246                  (match_operand:GPR 0 "register_operand"  "d,d")))]
1247   "s390_match_ccmode(insn, CCSRmode) && TARGET_Z10"
1248   "@
1249    cgh\t%0,%1
1250    cghrl\t%0,%1"
1251   [(set_attr "op_type" "RXY,RIL")
1252    (set_attr "type"    "*,larl")
1253    (set_attr "relative_long" "*,yes")])
1255 ; cr, chi, cfi, c, cy, cgr, cghi, cgfi, cg, chsi, cghsi, crl, cgrl
1256 (define_insn "*cmp<mode>_ccs"
1257   [(set (reg CC_REGNUM)
1258         (compare (match_operand:GPR 0 "nonimmediate_operand"
1259                                       "d,d,Q, d,d,d,d")
1260                  (match_operand:GPR 1 "general_operand"
1261                                       "d,K,K,Os,R,T,b")))]
1262   "s390_match_ccmode(insn, CCSmode)"
1263   "@
1264    c<g>r\t%0,%1
1265    c<g>hi\t%0,%h1
1266    c<g>hsi\t%0,%h1
1267    c<g>fi\t%0,%1
1268    c<g>\t%0,%1
1269    c<y>\t%0,%1
1270    c<g>rl\t%0,%1"
1271   [(set_attr "op_type" "RR<E>,RI,SIL,RIL,RX<Y>,RXY,RIL")
1272    (set_attr "cpu_facility" "*,*,z10,extimm,*,longdisp,z10")
1273    (set_attr "type" "*,*,*,*,*,*,larl")
1274    (set_attr "z10prop" "z10_super_c,z10_super,z10_super,z10_super,z10_super,z10_super,z10_super")
1275    (set_attr "relative_long" "*,*,*,*,*,*,yes")])
1278 ; Compare (unsigned) instructions
1280 (define_insn "*cmpsi_ccu_zerohi_rlsi"
1281   [(set (reg CC_REGNUM)
1282         (compare (zero_extend:SI (mem:HI (match_operand:SI 1
1283                                           "larl_operand" "X")))
1284                  (match_operand:SI 0 "register_operand" "d")))]
1285   "s390_match_ccmode(insn, CCURmode) && TARGET_Z10"
1286   "clhrl\t%0,%1"
1287   [(set_attr "op_type" "RIL")
1288    (set_attr "type"    "larl")
1289    (set_attr "z10prop" "z10_super")
1290    (set_attr "relative_long" "yes")])
1292 ; clhrl, clghrl
1293 (define_insn "*cmp<GPR:mode>_ccu_zerohi_rldi"
1294   [(set (reg CC_REGNUM)
1295         (compare (zero_extend:GPR (mem:HI (match_operand:DI 1
1296                                           "larl_operand" "X")))
1297                  (match_operand:GPR 0 "register_operand" "d")))]
1298   "s390_match_ccmode(insn, CCURmode) && TARGET_Z10"
1299   "cl<g>hrl\t%0,%1"
1300   [(set_attr "op_type" "RIL")
1301    (set_attr "type"    "larl")
1302    (set_attr "z10prop" "z10_super")
1303    (set_attr "relative_long" "yes")])
1305 (define_insn "*cmpdi_ccu_zero"
1306   [(set (reg CC_REGNUM)
1307         (compare (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand"
1308                                                         "d,T,b"))
1309                  (match_operand:DI 0 "register_operand" "d,d,d")))]
1310   "s390_match_ccmode (insn, CCURmode) && TARGET_ZARCH"
1311   "@
1312    clgfr\t%0,%1
1313    clgf\t%0,%1
1314    clgfrl\t%0,%1"
1315   [(set_attr "op_type"      "RRE,RXY,RIL")
1316    (set_attr "cpu_facility" "*,*,z10")
1317    (set_attr "type"         "*,*,larl")
1318    (set_attr "z10prop" "z10_super_c,z10_super_E1,z10_super")
1319    (set_attr "relative_long" "*,*,yes")])
1321 (define_insn "*cmpdi_ccu"
1322   [(set (reg CC_REGNUM)
1323         (compare (match_operand:DI 0 "nonimmediate_operand"
1324                                      "d, d,d,Q,d, Q,BQ")
1325                  (match_operand:DI 1 "general_operand"
1326                                      "d,Op,b,D,T,BQ,Q")))]
1327   "s390_match_ccmode (insn, CCUmode) && TARGET_ZARCH"
1328   "@
1329    clgr\t%0,%1
1330    clgfi\t%0,%1
1331    clgrl\t%0,%1
1332    clghsi\t%0,%x1
1333    clg\t%0,%1
1334    #
1335    #"
1336   [(set_attr "op_type" "RRE,RIL,RIL,SIL,RXY,SS,SS")
1337    (set_attr "cpu_facility" "*,extimm,z10,z10,*,*,*")
1338    (set_attr "type"         "*,*,larl,*,*,*,*")
1339    (set_attr "z10prop" "z10_super_c,z10_super,z10_super,z10_super,z10_super,*,*")
1340    (set_attr "relative_long" "*,*,yes,*,*,*,*")])
1342 (define_insn "*cmpsi_ccu"
1343   [(set (reg CC_REGNUM)
1344         (compare (match_operand:SI 0 "nonimmediate_operand" "d, d,d,Q,d,d, Q,BQ")
1345                  (match_operand:SI 1 "general_operand"      "d,Os,b,D,R,T,BQ, Q")))]
1346   "s390_match_ccmode (insn, CCUmode)"
1347   "@
1348    clr\t%0,%1
1349    clfi\t%0,%o1
1350    clrl\t%0,%1
1351    clfhsi\t%0,%x1
1352    cl\t%0,%1
1353    cly\t%0,%1
1354    #
1355    #"
1356   [(set_attr "op_type" "RR,RIL,RIL,SIL,RX,RXY,SS,SS")
1357    (set_attr "cpu_facility" "*,extimm,z10,z10,*,longdisp,*,*")
1358    (set_attr "type"         "*,*,larl,*,*,*,*,*")
1359    (set_attr "z10prop" "z10_super_c,z10_super,z10_super,z10_super,z10_super,z10_super,*,*")
1360    (set_attr "relative_long" "*,*,yes,*,*,*,*,*")])
1362 (define_insn "*cmphi_ccu"
1363   [(set (reg CC_REGNUM)
1364         (compare (match_operand:HI 0 "nonimmediate_operand" "d,d,Q,Q,BQ")
1365                  (match_operand:HI 1 "general_operand"      "Q,S,n,BQ,Q")))]
1366   "s390_match_ccmode (insn, CCUmode)
1367    && !register_operand (operands[1], HImode)"
1368   "@
1369    clm\t%0,3,%S1
1370    clmy\t%0,3,%S1
1371    clhhsi\t%0,%x1
1372    #
1373    #"
1374   [(set_attr "op_type" "RS,RSY,SIL,SS,SS")
1375    (set_attr "cpu_facility" "*,longdisp,z10,*,*")
1376    (set_attr "z10prop" "*,*,z10_super,*,*")])
1378 (define_insn "*cmpqi_ccu"
1379   [(set (reg CC_REGNUM)
1380         (compare (match_operand:QI 0 "nonimmediate_operand" "d,d,Q,S,Q,BQ")
1381                  (match_operand:QI 1 "general_operand" "Q,S,n,n,BQ,Q")))]
1382   "s390_match_ccmode (insn, CCUmode)
1383    && !register_operand (operands[1], QImode)"
1384   "@
1385    clm\t%0,1,%S1
1386    clmy\t%0,1,%S1
1387    cli\t%S0,%b1
1388    cliy\t%S0,%b1
1389    #
1390    #"
1391   [(set_attr "op_type" "RS,RSY,SI,SIY,SS,SS")
1392    (set_attr "cpu_facility" "*,longdisp,*,longdisp,*,*")
1393    (set_attr "z10prop" "*,*,z10_super,z10_super,*,*")])
1396 ; Block compare (CLC) instruction patterns.
1398 (define_insn "*clc"
1399   [(set (reg CC_REGNUM)
1400         (compare (match_operand:BLK 0 "memory_operand" "Q")
1401                  (match_operand:BLK 1 "memory_operand" "Q")))
1402    (use (match_operand 2 "const_int_operand" "n"))]
1403   "s390_match_ccmode (insn, CCUmode)
1404    && INTVAL (operands[2]) >= 1 && INTVAL (operands[2]) <= 256"
1405   "clc\t%O0(%2,%R0),%S1"
1406   [(set_attr "op_type" "SS")])
1408 (define_split
1409   [(set (reg CC_REGNUM)
1410         (compare (match_operand 0 "memory_operand" "")
1411                  (match_operand 1 "memory_operand" "")))]
1412   "reload_completed
1413    && s390_match_ccmode (insn, CCUmode)
1414    && GET_MODE (operands[0]) == GET_MODE (operands[1])
1415    && GET_MODE_SIZE (GET_MODE (operands[0])) > 0"
1416   [(parallel
1417     [(set (match_dup 0) (match_dup 1))
1418      (use (match_dup 2))])]
1420   operands[2] = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[0])));
1421   operands[0] = adjust_address (operands[0], BLKmode, 0);
1422   operands[1] = adjust_address (operands[1], BLKmode, 0);
1424   operands[1] = gen_rtx_COMPARE (GET_MODE (SET_DEST (PATTERN (curr_insn))),
1425                                  operands[0], operands[1]);
1426   operands[0] = SET_DEST (PATTERN (curr_insn));
1430 ; (TF|DF|SF|TD|DD|SD) instructions
1433 ; load and test instructions turn a signaling NaN into a quiet NaN.  Thus they
1434 ; may only be used if the target register is dead afterwards or if fast math
1435 ; is enabled.  The former is done via a peephole optimization.  Note, load and
1436 ; test instructions may only be used for (in)equality comparisons because
1437 ; relational comparisons must treat a quiet NaN like a signaling NaN which is
1438 ; not the case for load and test instructions.  For fast math insn
1439 ; "cmp<mode>_ccs_0_fastmath" applies.
1440 ; See testcases load-and-test-fp-{1,2}.c
1442 (define_peephole2
1443   [(set (match_operand:FP 0 "register_operand")
1444         (match_operand:FP 1 "const0_operand"))
1445    (set (reg:CCZ CC_REGNUM)
1446         (compare:CCZ (match_operand:FP 2 "register_operand")
1447                      (match_operand:FP 3 "register_operand")))]
1448   "TARGET_HARD_FLOAT
1449    && FP_REG_P (operands[2])
1450    && REGNO (operands[0]) == REGNO (operands[3])
1451    && peep2_reg_dead_p (2, operands[0])
1452    && peep2_reg_dead_p (2, operands[2])"
1453   [(parallel
1454     [(set (reg:CCZ CC_REGNUM)
1455           (compare:CCZ (match_dup 2) (match_dup 1)))
1456      (clobber (match_dup 2))])]
1457   "")
1459 ; ltxbr, ltdbr, ltebr, ltxtr, ltdtr
1460 (define_insn "*cmp<mode>_ccz_0"
1461   [(set (reg:CCZ CC_REGNUM)
1462         (compare:CCZ (match_operand:FP 0 "register_operand" "f")
1463                      (match_operand:FP 1 "const0_operand")))
1464    (clobber (match_operand:FP 2 "register_operand" "=0"))]
1465   "TARGET_HARD_FLOAT"
1466   "lt<xde><bt>r\t%0,%0"
1467    [(set_attr "op_type" "RRE")
1468     (set_attr "type" "fsimp<type>")])
1470 (define_insn "*cmp<mode>_ccs_0_fastmath"
1471   [(set (reg CC_REGNUM)
1472         (compare (match_operand:FP 0 "register_operand" "f")
1473                  (match_operand:FP 1 "const0_operand")))]
1474   "s390_match_ccmode (insn, CCSmode)
1475    && TARGET_HARD_FLOAT
1476    && !flag_trapping_math
1477    && !flag_signaling_nans"
1478   "lt<xde><bt>r\t%0,%0"
1479   [(set_attr "op_type" "RRE")
1480    (set_attr "type" "fsimp<type>")])
1482 ; VX: TFmode in FPR pairs: use cxbr instead of wfcxb
1483 ; cxtr, cdtr, cxbr, cdbr, cebr, cdb, ceb, wfcsb, wfcdb
1484 (define_insn "*cmp<mode>_ccs"
1485   [(set (reg CC_REGNUM)
1486         (compare (match_operand:FP 0 "register_operand" "f,f,v,v")
1487                  (match_operand:FP 1 "general_operand"  "f,R,v,v")))]
1488   "s390_match_ccmode(insn, CCSmode) && TARGET_HARD_FLOAT"
1489   "@
1490    c<xde><bt>r\t%0,%1
1491    c<xde>b\t%0,%1
1492    wfcdb\t%0,%1
1493    wfcsb\t%0,%1"
1494   [(set_attr "op_type" "RRE,RXE,VRR,VRR")
1495    (set_attr "cpu_facility" "*,*,vx,vxe")
1496    (set_attr "enabled" "*,<DSF>,<DF>,<SF>")])
1498 ; VX: TFmode in VR: use wfcxb
1499 (define_insn "*cmptf_ccs"
1500   [(set (reg CC_REGNUM)
1501         (compare (match_operand:TF 0 "register_operand" "v")
1502                  (match_operand:TF 1 "register_operand" "v")))]
1503   "s390_match_ccmode(insn, CCSmode) && TARGET_VXE"
1504   "wfcxb\t%0,%1"
1505   [(set_attr "op_type" "VRR")
1506    (set_attr "cpu_facility" "vxe")])
1508 ; VX: TFmode in FPR pairs: use kxbr instead of wfkxb
1509 ; kxtr, kdtr, kxbr, kdbr, kebr, kdb, keb, wfksb, wfkdb
1510 (define_insn "*cmp<mode>_ccsfps"
1511   [(set (reg CC_REGNUM)
1512         (compare (match_operand:FP 0 "register_operand" "f,f,v,v")
1513                  (match_operand:FP 1 "general_operand"  "f,R,v,v")))]
1514   "s390_match_ccmode (insn, CCSFPSmode) && TARGET_HARD_FLOAT"
1515   "@
1516    k<xde><bt>r\t%0,%1
1517    k<xde>b\t%0,%1
1518    wfkdb\t%0,%1
1519    wfksb\t%0,%1"
1520   [(set_attr "op_type" "RRE,RXE,VRR,VRR")
1521    (set_attr "cpu_facility" "*,*,vx,vxe")
1522    (set_attr "enabled" "*,<DSF>,<DF>,<SF>")])
1524 ; VX: TFmode in VR: use wfkxb
1525 (define_insn "*cmptf_ccsfps"
1526   [(set (reg CC_REGNUM)
1527         (compare (match_operand:TF 0 "register_operand" "v")
1528                  (match_operand:TF 1 "register_operand" "v")))]
1529   "s390_match_ccmode (insn, CCSFPSmode) && TARGET_VXE"
1530   "wfkxb\t%0,%1"
1531   [(set_attr "op_type" "VRR")
1532    (set_attr "cpu_facility" "vxe")])
1534 ; Compare and Branch instructions
1536 ; cij, cgij, crj, cgrj, cfi, cgfi, cr, cgr
1537 ; The following instructions do a complementary access of their second
1538 ; operand (z01 only): crj_c, cgrjc, cr, cgr
1539 (define_insn "*cmp_and_br_signed_<mode>"
1540   [(set (pc)
1541         (if_then_else (match_operator 0 "s390_signed_integer_comparison"
1542                         [(match_operand:GPR 1 "register_operand"  "d,d")
1543                          (match_operand:GPR 2 "nonmemory_operand" "d,C")])
1544                       (label_ref (match_operand 3 "" ""))
1545                       (pc)))
1546    (clobber (reg:CC CC_REGNUM))]
1547   "TARGET_Z10 && !TARGET_AVOID_CMP_AND_BRANCH"
1549   if (get_attr_length (insn) == 6)
1550     return which_alternative ?
1551       "c<g>ij%C0\t%1,%c2,%l3" : "c<g>rj%C0\t%1,%2,%l3";
1552   else
1553     return which_alternative ?
1554       "c<g>fi\t%1,%c2\;jg%C0\t%l3" : "c<g>r\t%1,%2\;jg%C0\t%l3";
1556   [(set_attr "op_type" "RIE")
1557    (set_attr "type"    "branch")
1558    (set_attr "z10prop" "z10_super_c,z10_super")
1559    (set (attr "length")
1560         (if_then_else (lt (abs (minus (pc) (match_dup 3))) (const_int 60000))
1561                       (const_int 6) (const_int 12)))]) ; 8 byte for cr/jg
1562                                                        ; 10 byte for cgr/jg
1564 ; clij, clgij, clrj, clgrj, clfi, clgfi, clr, clgr
1565 ; The following instructions do a complementary access of their second
1566 ; operand (z10 only): clrj, clgrj, clr, clgr
1567 (define_insn "*cmp_and_br_unsigned_<mode>"
1568   [(set (pc)
1569         (if_then_else (match_operator 0 "s390_unsigned_integer_comparison"
1570                         [(match_operand:GPR 1 "register_operand"  "d,d")
1571                          (match_operand:GPR 2 "nonmemory_operand" "d,I")])
1572                       (label_ref (match_operand 3 "" ""))
1573                       (pc)))
1574    (clobber (reg:CC CC_REGNUM))]
1575   "TARGET_Z10 && !TARGET_AVOID_CMP_AND_BRANCH"
1577   if (get_attr_length (insn) == 6)
1578     return which_alternative ?
1579       "cl<g>ij%C0\t%1,%b2,%l3" : "cl<g>rj%C0\t%1,%2,%l3";
1580   else
1581     return which_alternative ?
1582       "cl<g>fi\t%1,%b2\;jg%C0\t%l3" : "cl<g>r\t%1,%2\;jg%C0\t%l3";
1584   [(set_attr "op_type" "RIE")
1585    (set_attr "type"    "branch")
1586    (set_attr "z10prop" "z10_super_c,z10_super")
1587    (set (attr "length")
1588         (if_then_else (lt (abs (minus (pc) (match_dup 3))) (const_int 60000))
1589                       (const_int 6) (const_int 12)))]) ; 8 byte for clr/jg
1590                                                        ; 10 byte for clgr/jg
1592 ; And now the same two patterns as above but with a negated CC mask.
1594 ; cij, cgij, crj, cgrj, cfi, cgfi, cr, cgr
1595 ; The following instructions do a complementary access of their second
1596 ; operand (z01 only): crj_c, cgrjc, cr, cgr
1597 (define_insn "*icmp_and_br_signed_<mode>"
1598   [(set (pc)
1599         (if_then_else (match_operator 0 "s390_signed_integer_comparison"
1600                         [(match_operand:GPR 1 "register_operand"  "d,d")
1601                          (match_operand:GPR 2 "nonmemory_operand" "d,C")])
1602                       (pc)
1603                       (label_ref (match_operand 3 "" ""))))
1604    (clobber (reg:CC CC_REGNUM))]
1605   "TARGET_Z10 && !TARGET_AVOID_CMP_AND_BRANCH"
1607   if (get_attr_length (insn) == 6)
1608     return which_alternative ?
1609       "c<g>ij%D0\t%1,%c2,%l3" : "c<g>rj%D0\t%1,%2,%l3";
1610   else
1611     return which_alternative ?
1612       "c<g>fi\t%1,%c2\;jg%D0\t%l3" : "c<g>r\t%1,%2\;jg%D0\t%l3";
1614   [(set_attr "op_type" "RIE")
1615    (set_attr "type"    "branch")
1616    (set_attr "z10prop" "z10_super_c,z10_super")
1617    (set (attr "length")
1618         (if_then_else (lt (abs (minus (pc) (match_dup 3))) (const_int 60000))
1619                       (const_int 6) (const_int 12)))]) ; 8 byte for cr/jg
1620                                                        ; 10 byte for cgr/jg
1622 ; clij, clgij, clrj, clgrj, clfi, clgfi, clr, clgr
1623 ; The following instructions do a complementary access of their second
1624 ; operand (z10 only): clrj, clgrj, clr, clgr
1625 (define_insn "*icmp_and_br_unsigned_<mode>"
1626   [(set (pc)
1627         (if_then_else (match_operator 0 "s390_unsigned_integer_comparison"
1628                         [(match_operand:GPR 1 "register_operand"  "d,d")
1629                          (match_operand:GPR 2 "nonmemory_operand" "d,I")])
1630                       (pc)
1631                       (label_ref (match_operand 3 "" ""))))
1632    (clobber (reg:CC CC_REGNUM))]
1633   "TARGET_Z10 && !TARGET_AVOID_CMP_AND_BRANCH"
1635   if (get_attr_length (insn) == 6)
1636     return which_alternative ?
1637       "cl<g>ij%D0\t%1,%b2,%l3" : "cl<g>rj%D0\t%1,%2,%l3";
1638   else
1639     return which_alternative ?
1640       "cl<g>fi\t%1,%b2\;jg%D0\t%l3" : "cl<g>r\t%1,%2\;jg%D0\t%l3";
1642   [(set_attr "op_type" "RIE")
1643    (set_attr "type"    "branch")
1644    (set_attr "z10prop" "z10_super_c,z10_super")
1645    (set (attr "length")
1646         (if_then_else (lt (abs (minus (pc) (match_dup 3))) (const_int 60000))
1647                       (const_int 6) (const_int 12)))]) ; 8 byte for clr/jg
1648                                                        ; 10 byte for clgr/jg
1651 ;;- Move instructions.
1655 ; movti instruction pattern(s).
1659 ; Separate out the register pair alternative since constraints (P) are
1660 ; not able to deal with const_wide_int's.  But predicates do.
1661 (define_insn "*movti_bigconst"
1662   [(set (match_operand:TI 0 "register_operand"              "=d")
1663         (match_operand:TI 1 "reload_const_wide_int_operand" ""))]
1664   "TARGET_ZARCH"
1665   "#")
1667 ; FIXME: More constants are possible by enabling jxx, jyy constraints
1668 ; for TImode (use double-int for the calculations)
1669 (define_insn "movti"
1670   [(set (match_operand:TI 0 "nonimmediate_operand" "=d,S,v,  v,  v,  v,  v,  v,v,d,v,R,d,    d, d,    d, d,o")
1671         (match_operand:TI 1 "general_operand"      " S,d,v,j00,jm1,jyy,jxx,jzz,d,v,R,v,K,NxHD0,Os,NxSD0,dT,d"))]
1672   "TARGET_ZARCH"
1673   "@
1674    lmg\t%0,%N0,%S1
1675    stmg\t%1,%N1,%S0
1676    vlr\t%v0,%v1
1677    vzero\t%v0
1678    vone\t%v0
1679    vgbm\t%v0,%r1
1680    vgm\t%v0,%q1
1681    vrepi\t%v0,%p1
1682    vlvgp\t%v0,%1,%N1
1683    #
1684    vl\t%v0,%1%A1
1685    vst\t%v1,%0%A0
1686    #
1687    #
1688    #
1689    #
1690    #
1691    #"
1692   [(set_attr "op_type" "RSY,RSY,VRR,VRI,VRI,VRI,VRI,VRI,VRR,*,VRX,VRX,*,*,*,*,*,*")
1693    (set_attr "type" "lm,stm,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*")
1694    (set_attr "cpu_facility" "*,*,vx,vx,vx,vx,vx,vx,vx,vx,vx,vx,*,*,*,extimm,*,*")])
1696 (define_split
1697   [(set (match_operand:TI 0 "nonimmediate_operand" "")
1698         (match_operand:TI 1 "general_operand" ""))]
1699   "TARGET_ZARCH && reload_completed
1700    && s390_split_ok_p (operands[0], operands[1], TImode, 0)"
1701   [(set (match_dup 2) (match_dup 4))
1702    (set (match_dup 3) (match_dup 5))]
1704   operands[2] = operand_subword (operands[0], 0, 0, TImode);
1705   operands[3] = operand_subword (operands[0], 1, 0, TImode);
1706   operands[4] = operand_subword (operands[1], 0, 0, TImode);
1707   operands[5] = operand_subword (operands[1], 1, 0, TImode);
1710 (define_split
1711   [(set (match_operand:TI 0 "nonimmediate_operand" "")
1712         (match_operand:TI 1 "general_operand" ""))]
1713   "TARGET_ZARCH && reload_completed
1714    && s390_split_ok_p (operands[0], operands[1], TImode, 1)"
1715   [(set (match_dup 2) (match_dup 4))
1716    (set (match_dup 3) (match_dup 5))]
1718   operands[2] = operand_subword (operands[0], 1, 0, TImode);
1719   operands[3] = operand_subword (operands[0], 0, 0, TImode);
1720   operands[4] = operand_subword (operands[1], 1, 0, TImode);
1721   operands[5] = operand_subword (operands[1], 0, 0, TImode);
1724 ; Use part of the TImode target reg to perform the address
1725 ; calculation.  If the TImode value is supposed to be copied into a VR
1726 ; this splitter is not necessary.
1727 (define_split
1728   [(set (match_operand:TI 0 "register_operand" "")
1729         (match_operand:TI 1 "memory_operand" ""))]
1730   "TARGET_ZARCH && reload_completed
1731    && !VECTOR_REG_P (operands[0])
1732    && !s_operand (operands[1], VOIDmode)"
1733   [(set (match_dup 0) (match_dup 1))]
1735   rtx addr = operand_subword (operands[0], 1, 0, TImode);
1736   addr = gen_lowpart (Pmode, addr);
1737   s390_load_address (addr, XEXP (operands[1], 0));
1738   operands[1] = replace_equiv_address (operands[1], addr);
1742 ; Split a VR -> GPR TImode move into 2 vector load GR from VR element.
1743 ; For the higher order bits we do simply a DImode move while the
1744 ; second part is done via vec extract.  Both will end up as vlgvg.
1745 (define_split
1746   [(set (match_operand:TI 0 "register_operand" "")
1747         (match_operand:TI 1 "register_operand" ""))]
1748   "TARGET_VX && reload_completed
1749    && GENERAL_REG_P (operands[0])
1750    && VECTOR_REG_P (operands[1])"
1751   [(set (match_dup 2) (match_dup 4))
1752    (set (match_dup 3) (vec_select:DI (match_dup 5)
1753                        (parallel [(const_int 1)])))]
1755   operands[2] = operand_subword (operands[0], 0, 0, TImode);
1756   operands[3] = operand_subword (operands[0], 1, 0, TImode);
1757   operands[4] = gen_rtx_REG (DImode, REGNO (operands[1]));
1758   operands[5] = gen_rtx_REG (V2DImode, REGNO (operands[1]));
1762 ; Patterns used for secondary reloads
1765 ; z10 provides move instructions accepting larl memory operands.
1766 ; Unfortunately there is no such variant for QI, TI and FP mode moves.
1767 ; These patterns are also used for unaligned SI and DI accesses.
1769 (define_expand "reload<ALL:mode><P:mode>_tomem_z10"
1770   [(parallel [(match_operand:ALL 0 "memory_operand"   "")
1771               (match_operand:ALL 1 "register_operand" "=d")
1772               (match_operand:P   2 "register_operand" "=&a")])]
1773   "TARGET_Z10"
1775   s390_reload_symref_address (operands[1], operands[0], operands[2], 1);
1776   DONE;
1779 (define_expand "reload<ALL:mode><P:mode>_toreg_z10"
1780   [(parallel [(match_operand:ALL 0 "register_operand" "=d")
1781               (match_operand:ALL 1 "memory_operand"   "")
1782               (match_operand:P   2 "register_operand" "=a")])]
1783   "TARGET_Z10"
1785   s390_reload_symref_address (operands[0], operands[1], operands[2], 0);
1786   DONE;
1789 (define_expand "reload<P:mode>_larl_odd_addend_z10"
1790   [(parallel [(match_operand:P 0 "register_operand" "=d")
1791               (match_operand:P 1 "larl_operand"     "")
1792               (match_operand:P 2 "register_operand" "=a")])]
1793   "TARGET_Z10"
1795   s390_reload_larl_operand (operands[0], operands[1], operands[2]);
1796   DONE;
1799 ; Handles loading a PLUS (load address) expression
1801 (define_expand "reload<mode>_plus"
1802   [(parallel [(match_operand:P 0 "register_operand"  "=a")
1803               (match_operand:P 1 "s390_plus_operand" "")
1804               (match_operand:P 2 "register_operand"  "=&a")])]
1805   ""
1807   s390_expand_plus_operand (operands[0], operands[1], operands[2]);
1808   DONE;
1811 ; Not all the indirect memory access instructions support the full
1812 ; format (long disp + index + base).  So whenever a move from/to such
1813 ; an address is required and the instruction cannot deal with it we do
1814 ; a load address into a scratch register first and use this as the new
1815 ; base register.
1816 ; This in particular is used for:
1817 ; - non-offsetable memory accesses for multiword moves
1818 ; - full vector reg moves with long displacements
1820 (define_expand "reload<mode>_la_in"
1821   [(parallel [(match_operand 0   "register_operand" "")
1822               (match_operand 1   "" "")
1823               (match_operand:P 2 "register_operand" "=&a")])]
1824   ""
1826   gcc_assert (MEM_P (operands[1]));
1827   s390_load_address (operands[2], find_replacement (&XEXP (operands[1], 0)));
1828   operands[1] = replace_equiv_address (operands[1], operands[2]);
1829   emit_move_insn (operands[0], operands[1]);
1830   DONE;
1833 (define_expand "reload<mode>_la_out"
1834   [(parallel [(match_operand   0 "" "")
1835               (match_operand   1 "register_operand" "")
1836               (match_operand:P 2 "register_operand" "=&a")])]
1837   ""
1839   gcc_assert (MEM_P (operands[0]));
1840   s390_load_address (operands[2], find_replacement (&XEXP (operands[0], 0)));
1841   operands[0] = replace_equiv_address (operands[0], operands[2]);
1842   emit_move_insn (operands[0], operands[1]);
1843   DONE;
1846 (define_expand "reload<mode>_PIC_addr"
1847   [(parallel [(match_operand   0 "register_operand" "=d")
1848               (match_operand   1 "larl_operand"     "")
1849               (match_operand:P 2 "register_operand" "=a")])]
1850   ""
1852   rtx new_rtx = legitimize_pic_address (operands[1], operands[2]);
1853   emit_move_insn (operands[0], new_rtx);
1857 ; movdi instruction pattern(s).
1860 (define_expand "movdi"
1861   [(set (match_operand:DI 0 "general_operand" "")
1862         (match_operand:DI 1 "general_operand" ""))]
1863   ""
1865   /* Handle symbolic constants.  */
1866   if (TARGET_64BIT
1867       && (SYMBOLIC_CONST (operands[1])
1868           || (GET_CODE (operands[1]) == PLUS
1869               && XEXP (operands[1], 0) == pic_offset_table_rtx
1870               && SYMBOLIC_CONST (XEXP (operands[1], 1)))))
1871     emit_symbolic_move (operands);
1874 (define_insn "*movdi_64"
1875   [(set (match_operand:DI 0 "nonimmediate_operand"
1876          "=d,    d,    d,    d,    d, d,    d,    d,f,d,!*f,d,d,d,d,T,!*f,!*f,!*f,!R,!T,b,Q,d,t,Q,t,v,v,v,d,v,R,d")
1877         (match_operand:DI 1 "general_operand"
1878          " K,N0HD0,N1HD0,N2HD0,N3HD0,Os,N0SD0,N1SD0,d,f,j00,L,b,d,T,d, *f,  R,  T,*f,*f,d,K,t,d,t,Q,K,v,d,v,R,v,ZL"))]
1879   "TARGET_ZARCH"
1880   "@
1881    lghi\t%0,%h1
1882    llihh\t%0,%i1
1883    llihl\t%0,%i1
1884    llilh\t%0,%i1
1885    llill\t%0,%i1
1886    lgfi\t%0,%1
1887    llihf\t%0,%k1
1888    llilf\t%0,%k1
1889    ldgr\t%0,%1
1890    lgdr\t%0,%1
1891    lzdr\t%0
1892    lay\t%0,%a1
1893    lgrl\t%0,%1
1894    lgr\t%0,%1
1895    lg\t%0,%1
1896    stg\t%1,%0
1897    ldr\t%0,%1
1898    ld\t%0,%1
1899    ldy\t%0,%1
1900    std\t%1,%0
1901    stdy\t%1,%0
1902    stgrl\t%1,%0
1903    mvghi\t%0,%1
1904    #
1905    #
1906    stam\t%1,%N1,%S0
1907    lam\t%0,%N0,%S1
1908    vleig\t%v0,%h1,0
1909    vlr\t%v0,%v1
1910    vlvgg\t%v0,%1,0
1911    vlgvg\t%0,%v1,0
1912    vleg\t%v0,%1,0
1913    vsteg\t%v1,%0,0
1914    larl\t%0,%1%K1"
1915   [(set_attr "op_type" "RI,RI,RI,RI,RI,RIL,RIL,RIL,RRE,RRE,RRE,RXY,RIL,RRE,RXY,
1916                         RXY,RR,RX,RXY,RX,RXY,RIL,SIL,*,*,RS,RS,VRI,VRR,VRS,VRS,
1917                         VRX,VRX,RIL")
1918    (set_attr "type" "*,*,*,*,*,*,*,*,floaddf,floaddf,fsimpdf,la,larl,lr,load,store,
1919                      floaddf,floaddf,floaddf,fstoredf,fstoredf,larl,*,*,*,*,
1920                      *,*,*,*,*,*,*,larl")
1921    (set_attr "cpu_facility" "*,*,*,*,*,extimm,extimm,extimm,dfp,dfp,*,longdisp,
1922                              z10,*,*,*,*,*,longdisp,*,longdisp,
1923                              z10,z10,*,*,*,*,vx,vx,vx,vx,vx,vx,*")
1924    (set_attr "z10prop" "z10_fwd_A1,
1925                         z10_fwd_E1,
1926                         z10_fwd_E1,
1927                         z10_fwd_E1,
1928                         z10_fwd_E1,
1929                         z10_fwd_A1,
1930                         z10_fwd_E1,
1931                         z10_fwd_E1,
1932                         *,
1933                         *,
1934                         *,
1935                         z10_fwd_A1,
1936                         z10_fwd_A3,
1937                         z10_fr_E1,
1938                         z10_fwd_A3,
1939                         z10_rec,
1940                         *,
1941                         *,
1942                         *,
1943                         *,
1944                         *,
1945                         z10_rec,
1946                         z10_super,
1947                         *,
1948                         *,
1949                         *,
1950                         *,*,*,*,*,*,*,
1951                         z10_super_A1")
1952    (set_attr "relative_long" "*,*,*,*,*,*,*,*,*,*,*,
1953                               *,yes,*,*,*,*,*,*,*,*,
1954                               yes,*,*,*,*,*,*,*,*,*,
1955                               *,*,yes")
1958 ; Splitters for loading TLS pointer from UNSPEC_GET_TP.
1959 ; UNSPEC_GET_TP is used instead of %a0:P, since the latter is a hard register,
1960 ; and those are not handled by Partial Redundancy Elimination (gcse.cc), which
1961 ; results in generation of redundant thread pointer loads.
1963 (define_insn_and_split "*get_tp_31"
1964   [(set (match_operand:SI 0 "register_operand" "=r")
1965         (unspec:SI [(match_operand:SI 1 "register_operand" "t")]
1966                    UNSPEC_GET_TP))]
1967   ""
1968   "#"
1969   "&& reload_completed"
1970   [(set (match_dup 0) (match_dup 1))])
1972 (define_insn_and_split "*get_tp_64"
1973   [(set (match_operand:DI 0 "register_operand" "=r")
1974         (unspec:DI [(match_operand:DI 1 "register_operand" "t")]
1975                    UNSPEC_GET_TP))]
1976   "TARGET_ZARCH"
1977   "#"
1978   "&& reload_completed"
1979   [(set (match_dup 2) (match_dup 3))
1980    (set (match_dup 0) (ashift:DI (match_dup 0) (const_int 32)))
1981    (set (strict_low_part (match_dup 2)) (match_dup 4))]
1982   "operands[2] = gen_lowpart (SImode, operands[0]);
1983    s390_split_access_reg (operands[1], &operands[4], &operands[3]);")
1985 ; Splitters for storing TLS pointer to %a0:DI.
1987 (define_split
1988   [(set (match_operand:DI 0 "register_operand" "")
1989         (match_operand:DI 1 "register_operand" ""))]
1990   "TARGET_ZARCH && ACCESS_REG_P (operands[0]) && reload_completed
1991    && dead_or_set_p (insn, operands[1])"
1992   [(set (match_dup 3) (match_dup 2))
1993    (set (match_dup 1) (lshiftrt:DI (match_dup 1) (const_int 32)))
1994    (set (match_dup 4) (match_dup 2))]
1995   "operands[2] = gen_lowpart (SImode, operands[1]);
1996    s390_split_access_reg (operands[0], &operands[3], &operands[4]);")
1998 (define_split
1999   [(set (match_operand:DI 0 "register_operand" "")
2000         (match_operand:DI 1 "register_operand" ""))]
2001   "TARGET_ZARCH && ACCESS_REG_P (operands[0]) && reload_completed
2002    && !dead_or_set_p (insn, operands[1])"
2003   [(set (match_dup 3) (match_dup 2))
2004    (set (match_dup 1) (rotate:DI (match_dup 1) (const_int 32)))
2005    (set (match_dup 4) (match_dup 2))
2006    (set (match_dup 1) (rotate:DI (match_dup 1) (const_int 32)))]
2007   "operands[2] = gen_lowpart (SImode, operands[1]);
2008    s390_split_access_reg (operands[0], &operands[3], &operands[4]);")
2010 (define_insn "*movdi_31"
2011   [(set (match_operand:DI 0 "nonimmediate_operand"
2012                             "=d,d,Q,S,d  ,o,!*f,!*f,!*f,!*f,!R,!T,d")
2013         (match_operand:DI 1 "general_operand"
2014                             " Q,S,d,d,dPT,d, *f,  R,  T,j00,*f,*f,b"))]
2015   "!TARGET_ZARCH"
2016   "@
2017    lm\t%0,%N0,%S1
2018    lmy\t%0,%N0,%S1
2019    stm\t%1,%N1,%S0
2020    stmy\t%1,%N1,%S0
2021    #
2022    #
2023    ldr\t%0,%1
2024    ld\t%0,%1
2025    ldy\t%0,%1
2026    lzdr\t%0
2027    std\t%1,%0
2028    stdy\t%1,%0
2029    #"
2030   [(set_attr "op_type" "RS,RSY,RS,RSY,*,*,RR,RX,RXY,RRE,RX,RXY,*")
2031    (set_attr "type" "lm,lm,stm,stm,*,*,floaddf,floaddf,floaddf,fsimpdf,fstoredf,fstoredf,*")
2032    (set_attr "cpu_facility" "*,longdisp,*,longdisp,*,*,*,*,longdisp,*,*,longdisp,z10")])
2034 ; For a load from a symbol ref we can use one of the target registers
2035 ; together with larl to load the address.
2036 (define_split
2037   [(set (match_operand:DI 0 "register_operand" "")
2038         (match_operand:DI 1 "memory_operand" ""))]
2039   "!TARGET_ZARCH && reload_completed && TARGET_Z10
2040    && larl_operand (XEXP (operands[1], 0), SImode)"
2041   [(set (match_dup 2) (match_dup 3))
2042    (set (match_dup 0) (match_dup 1))]
2044   operands[2] = operand_subword (operands[0], 1, 0, DImode);
2045   operands[3] = XEXP (operands[1], 0);
2046   operands[1] = replace_equiv_address (operands[1], operands[2]);
2049 (define_split
2050   [(set (match_operand:DI 0 "nonimmediate_operand" "")
2051         (match_operand:DI 1 "general_operand" ""))]
2052   "!TARGET_ZARCH && reload_completed
2053    && !s_operand (operands[0], DImode)
2054    && !s_operand (operands[1], DImode)
2055    && s390_split_ok_p (operands[0], operands[1], DImode, 0)"
2056   [(set (match_dup 2) (match_dup 4))
2057    (set (match_dup 3) (match_dup 5))]
2059   operands[2] = operand_subword (operands[0], 0, 0, DImode);
2060   operands[3] = operand_subword (operands[0], 1, 0, DImode);
2061   operands[4] = operand_subword (operands[1], 0, 0, DImode);
2062   operands[5] = operand_subword (operands[1], 1, 0, DImode);
2065 (define_split
2066   [(set (match_operand:DI 0 "nonimmediate_operand" "")
2067         (match_operand:DI 1 "general_operand" ""))]
2068   "!TARGET_ZARCH && reload_completed
2069    && !s_operand (operands[0], DImode)
2070    && !s_operand (operands[1], DImode)
2071    && s390_split_ok_p (operands[0], operands[1], DImode, 1)"
2072   [(set (match_dup 2) (match_dup 4))
2073    (set (match_dup 3) (match_dup 5))]
2075   operands[2] = operand_subword (operands[0], 1, 0, DImode);
2076   operands[3] = operand_subword (operands[0], 0, 0, DImode);
2077   operands[4] = operand_subword (operands[1], 1, 0, DImode);
2078   operands[5] = operand_subword (operands[1], 0, 0, DImode);
2081 (define_split
2082   [(set (match_operand:DI 0 "register_operand" "")
2083         (match_operand:DI 1 "memory_operand" ""))]
2084   "!TARGET_ZARCH && reload_completed
2085    && !FP_REG_P (operands[0])
2086    && !s_operand (operands[1], VOIDmode)"
2087   [(set (match_dup 0) (match_dup 1))]
2089   rtx addr = operand_subword (operands[0], 1, 0, DImode);
2090   s390_load_address (addr, XEXP (operands[1], 0));
2091   operands[1] = replace_equiv_address (operands[1], addr);
2094 (define_peephole2
2095   [(set (match_operand:DI 0 "register_operand" "")
2096         (mem:DI (match_operand 1 "address_operand" "")))]
2097   "TARGET_ZARCH
2098    && !FP_REG_P (operands[0])
2099    && GET_CODE (operands[1]) == SYMBOL_REF
2100    && CONSTANT_POOL_ADDRESS_P (operands[1])
2101    && get_pool_mode (operands[1]) == DImode
2102    && legitimate_reload_constant_p (get_pool_constant (operands[1]))"
2103   [(set (match_dup 0) (match_dup 2))]
2104   "operands[2] = get_pool_constant (operands[1]);")
2106 (define_insn "*la_64"
2107   [(set (match_operand:DI 0 "register_operand" "=d,d")
2108         (match_operand:QI 1 "address_operand" "ZR,ZT"))]
2109   "TARGET_64BIT"
2110   "@
2111    la\t%0,%a1
2112    lay\t%0,%a1"
2113   [(set_attr "op_type" "RX,RXY")
2114    (set_attr "type"    "la")
2115    (set_attr "cpu_facility" "*,longdisp")
2116    (set_attr "z10prop" "z10_fwd_A1,z10_fwd_A1")])
2118 (define_peephole2
2119   [(parallel
2120     [(set (match_operand:DI 0 "register_operand" "")
2121           (match_operand:QI 1 "address_operand" ""))
2122      (clobber (reg:CC CC_REGNUM))])]
2123   "TARGET_64BIT
2124    && preferred_la_operand_p (operands[1], const0_rtx)"
2125   [(set (match_dup 0) (match_dup 1))]
2126   "")
2128 (define_peephole2
2129   [(set (match_operand:DI 0 "register_operand" "")
2130         (match_operand:DI 1 "register_operand" ""))
2131    (parallel
2132     [(set (match_dup 0)
2133           (plus:DI (match_dup 0)
2134                    (match_operand:DI 2 "nonmemory_operand" "")))
2135      (clobber (reg:CC CC_REGNUM))])]
2136   "TARGET_64BIT
2137    && !reg_overlap_mentioned_p (operands[0], operands[2])
2138    && preferred_la_operand_p (operands[1], operands[2])"
2139   [(set (match_dup 0) (plus:DI (match_dup 1) (match_dup 2)))]
2140   "")
2142 ; Split loading of 64-bit constants into GPRs into llihf + oilf -
2143 ; counterintuitively, using oilf is faster than iilf.  oilf clobbers
2144 ; cc, so cc must be dead.
2145 (define_peephole2
2146   [(set (match_operand:DI 0 "register_operand" "")
2147         (match_operand:DI 1 "memory_operand" ""))]
2148   "TARGET_64BIT
2149    && TARGET_EXTIMM
2150    && GENERAL_REG_P (operands[0])
2151    && s390_const_int_pool_entry_p (operands[1], nullptr)
2152    && peep2_reg_dead_p (1, gen_rtx_REG (CCmode, CC_REGNUM))"
2153   [(set (match_dup 0) (match_dup 2))
2154    (parallel
2155     [(set (match_dup 0) (ior:DI (match_dup 0) (match_dup 3)))
2156      (clobber (reg:CC CC_REGNUM))])]
2158   HOST_WIDE_INT val;
2159   bool ok = s390_const_int_pool_entry_p (operands[1], &val);
2160   gcc_assert (ok);
2161   operands[2] = GEN_INT (val & 0xFFFFFFFF00000000ULL);
2162   operands[3] = GEN_INT (val & 0x00000000FFFFFFFFULL);
2163   if (operands[2] == const0_rtx)
2164     {
2165       emit_move_insn (operands[0], operands[3]);
2166       DONE;
2167     }
2168   else if (operands[3] == const0_rtx)
2169     {
2170       emit_move_insn (operands[0], operands[2]);
2171       DONE;
2172     }
2176 ; movsi instruction pattern(s).
2179 (define_expand "movsi"
2180   [(set (match_operand:SI 0 "general_operand" "")
2181         (match_operand:SI 1 "general_operand" ""))]
2182   ""
2184   /* Handle symbolic constants.  */
2185   if (!TARGET_64BIT
2186       && (SYMBOLIC_CONST (operands[1])
2187           || (GET_CODE (operands[1]) == PLUS
2188               && XEXP (operands[1], 0) == pic_offset_table_rtx
2189               && SYMBOLIC_CONST (XEXP(operands[1], 1)))))
2190     emit_symbolic_move (operands);
2193 (define_insn "*movsi_larl"
2194   [(set (match_operand:SI 0 "register_operand" "=d")
2195         (match_operand:SI 1 "larl_operand" "X"))]
2196   "!TARGET_64BIT
2197    && !FP_REG_P (operands[0])"
2198   "larl\t%0,%1%K1"
2199    [(set_attr "op_type" "RIL")
2200     (set_attr "type"    "larl")
2201     (set_attr "z10prop" "z10_fwd_A1")
2202     (set_attr "relative_long" "yes")])
2204 (define_insn "*movsi_zarch"
2205   [(set (match_operand:SI 0 "nonimmediate_operand"
2206          "=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")
2207         (match_operand:SI 1 "general_operand"
2208          " 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"))]
2209   "TARGET_ZARCH"
2210   "@
2211    lhi\t%0,%h1
2212    llilh\t%0,%i1
2213    llill\t%0,%i1
2214    iilf\t%0,%o1
2215    lay\t%0,%a1
2216    lrl\t%0,%1
2217    lr\t%0,%1
2218    l\t%0,%1
2219    ly\t%0,%1
2220    st\t%1,%0
2221    sty\t%1,%0
2222    ldr\t%0,%1
2223    ler\t%0,%1
2224    lde\t%0,%1
2225    le\t%0,%1
2226    ley\t%0,%1
2227    ste\t%1,%0
2228    stey\t%1,%0
2229    ear\t%0,%1
2230    sar\t%0,%1
2231    stam\t%1,%1,%S0
2232    strl\t%1,%0
2233    mvhi\t%0,%1
2234    lam\t%0,%0,%S1
2235    vleif\t%v0,%h1,0
2236    vlr\t%v0,%v1
2237    vlvgf\t%v0,%1,0
2238    vlgvf\t%0,%v1,0
2239    vlef\t%v0,%1,0
2240    vstef\t%v1,%0,0"
2241   [(set_attr "op_type" "RI,RI,RI,RIL,RXY,RIL,RR,RX,RXY,RX,RXY,
2242                         RR,RR,RXE,RX,RXY,RX,RXY,RRE,RRE,RS,RIL,SIL,RS,VRI,VRR,VRS,VRS,VRX,VRX")
2243    (set_attr "type" "*,
2244                      *,
2245                      *,
2246                      *,
2247                      la,
2248                      larl,
2249                      lr,
2250                      load,
2251                      load,
2252                      store,
2253                      store,
2254                      floadsf,
2255                      floadsf,
2256                      floadsf,
2257                      floadsf,
2258                      floadsf,
2259                      fstoresf,
2260                      fstoresf,
2261                      *,
2262                      *,
2263                      *,
2264                      larl,
2265                      *,
2266                      *,*,*,*,*,*,*")
2267    (set_attr "cpu_facility" "*,*,*,extimm,longdisp,z10,*,*,longdisp,*,longdisp,
2268                              vx,*,vx,*,longdisp,*,longdisp,*,*,*,z10,z10,*,vx,vx,vx,vx,vx,vx")
2269    (set_attr "z10prop" "z10_fwd_A1,
2270                         z10_fwd_E1,
2271                         z10_fwd_E1,
2272                         z10_fwd_A1,
2273                         z10_fwd_A1,
2274                         z10_fwd_A3,
2275                         z10_fr_E1,
2276                         z10_fwd_A3,
2277                         z10_fwd_A3,
2278                         z10_rec,
2279                         z10_rec,
2280                         *,
2281                         *,
2282                         *,
2283                         *,
2284                         *,
2285                         *,
2286                         *,
2287                         z10_super_E1,
2288                         z10_super,
2289                         *,
2290                         z10_rec,
2291                         z10_super,
2292                         *,*,*,*,*,*,*")
2293    (set_attr "relative_long" "*,*,*,*,*,yes,*,*,*,*,
2294                               *,*,*,*,*,*,*,*,*,*,
2295                               *,yes,*,*,*,*,*,*,*,*")])
2297 (define_insn "*movsi_esa"
2298   [(set (match_operand:SI 0 "nonimmediate_operand" "=d,d,d,R,!*f,!*f,!*f,!*f,!R,d,t,Q,t")
2299         (match_operand:SI 1 "general_operand"       "K,d,R,d, *f, *f,  R,  R,*f,t,d,t,Q"))]
2300   "!TARGET_ZARCH"
2301   "@
2302    lhi\t%0,%h1
2303    lr\t%0,%1
2304    l\t%0,%1
2305    st\t%1,%0
2306    ldr\t%0,%1
2307    ler\t%0,%1
2308    lde\t%0,%1
2309    le\t%0,%1
2310    ste\t%1,%0
2311    ear\t%0,%1
2312    sar\t%0,%1
2313    stam\t%1,%1,%S0
2314    lam\t%0,%0,%S1"
2315   [(set_attr "op_type" "RI,RR,RX,RX,RR,RR,RXE,RX,RX,RRE,RRE,RS,RS")
2316    (set_attr "type" "*,lr,load,store,floadsf,floadsf,floadsf,floadsf,fstoresf,*,*,*,*")
2317    (set_attr "z10prop" "z10_fwd_A1,z10_fr_E1,z10_fwd_A3,z10_rec,*,*,*,*,*,z10_super_E1,
2318                         z10_super,*,*")
2319    (set_attr "cpu_facility" "*,*,*,*,vx,*,vx,*,*,*,*,*,*")
2322 (define_peephole2
2323   [(set (match_operand:SI 0 "register_operand" "")
2324         (mem:SI (match_operand 1 "address_operand" "")))]
2325   "!FP_REG_P (operands[0])
2326    && GET_CODE (operands[1]) == SYMBOL_REF
2327    && CONSTANT_POOL_ADDRESS_P (operands[1])
2328    && get_pool_mode (operands[1]) == SImode
2329    && legitimate_reload_constant_p (get_pool_constant (operands[1]))"
2330   [(set (match_dup 0) (match_dup 2))]
2331   "operands[2] = get_pool_constant (operands[1]);")
2333 (define_insn "*la_31"
2334   [(set (match_operand:SI 0 "register_operand" "=d,d")
2335         (match_operand:QI 1 "address_operand" "ZR,ZT"))]
2336   "!TARGET_64BIT && legitimate_la_operand_p (operands[1])"
2337   "@
2338    la\t%0,%a1
2339    lay\t%0,%a1"
2340   [(set_attr "op_type"  "RX,RXY")
2341    (set_attr "type"     "la")
2342    (set_attr "cpu_facility" "*,longdisp")
2343    (set_attr "z10prop" "z10_fwd_A1,z10_fwd_A1")])
2345 (define_peephole2
2346   [(parallel
2347     [(set (match_operand:SI 0 "register_operand" "")
2348           (match_operand:QI 1 "address_operand" ""))
2349      (clobber (reg:CC CC_REGNUM))])]
2350   "!TARGET_64BIT
2351    && preferred_la_operand_p (operands[1], const0_rtx)"
2352   [(set (match_dup 0) (match_dup 1))]
2353   "")
2355 (define_peephole2
2356   [(set (match_operand:SI 0 "register_operand" "")
2357         (match_operand:SI 1 "register_operand" ""))
2358    (parallel
2359     [(set (match_dup 0)
2360           (plus:SI (match_dup 0)
2361                    (match_operand:SI 2 "nonmemory_operand" "")))
2362      (clobber (reg:CC CC_REGNUM))])]
2363   "!TARGET_64BIT
2364    && !reg_overlap_mentioned_p (operands[0], operands[2])
2365    && preferred_la_operand_p (operands[1], operands[2])"
2366   [(set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))]
2367   "")
2369 (define_insn "*la_31_and"
2370   [(set (match_operand:SI 0 "register_operand" "=d,d")
2371         (and:SI (match_operand:QI 1 "address_operand" "ZR,ZT")
2372                 (const_int 2147483647)))]
2373   "!TARGET_64BIT"
2374   "@
2375    la\t%0,%a1
2376    lay\t%0,%a1"
2377   [(set_attr "op_type"  "RX,RXY")
2378    (set_attr "type"     "la")
2379    (set_attr "cpu_facility" "*,longdisp")
2380    (set_attr "z10prop" "z10_fwd_A1,z10_fwd_A1")])
2382 (define_insn_and_split "*la_31_and_cc"
2383   [(set (match_operand:SI 0 "register_operand" "=d")
2384         (and:SI (match_operand:QI 1 "address_operand" "p")
2385                 (const_int 2147483647)))
2386    (clobber (reg:CC CC_REGNUM))]
2387   "!TARGET_64BIT"
2388   "#"
2389   "&& reload_completed"
2390   [(set (match_dup 0)
2391         (and:SI (match_dup 1) (const_int 2147483647)))]
2392   ""
2393   [(set_attr "op_type"  "RX")
2394    (set_attr "type"     "la")])
2396 (define_insn "force_la_31"
2397   [(set (match_operand:SI 0 "register_operand" "=d,d")
2398         (match_operand:QI 1 "address_operand" "ZR,ZT"))
2399    (use (const_int 0))]
2400   "!TARGET_64BIT"
2401   "@
2402    la\t%0,%a1
2403    lay\t%0,%a1"
2404   [(set_attr "op_type"  "RX")
2405    (set_attr "type"     "la")
2406    (set_attr "cpu_facility" "*,longdisp")
2407    (set_attr "z10prop" "z10_fwd_A1,z10_fwd_A1")])
2410 ; movhi instruction pattern(s).
2413 (define_expand "movhi"
2414   [(set (match_operand:HI 0 "nonimmediate_operand" "")
2415         (match_operand:HI 1 "general_operand" ""))]
2416   ""
2418   /* Make it explicit that loading a register from memory
2419      always sign-extends (at least) to SImode.  */
2420   if (optimize && can_create_pseudo_p ()
2421       && register_operand (operands[0], VOIDmode)
2422       && GET_CODE (operands[1]) == MEM)
2423     {
2424       rtx tmp = gen_reg_rtx (SImode);
2425       rtx ext = gen_rtx_SIGN_EXTEND (SImode, operands[1]);
2426       emit_insn (gen_rtx_SET (tmp, ext));
2427       operands[1] = gen_lowpart (HImode, tmp);
2428     }
2431 (define_insn "*movhi"
2432   [(set (match_operand:HI 0 "nonimmediate_operand" "=d,d,d,d,d,R,T,b,Q,v,v,v,d,v,R")
2433         (match_operand:HI 1 "general_operand"      " d,n,R,T,b,d,d,d,K,K,v,d,v,R,v"))]
2434   ""
2435   "@
2436    lr\t%0,%1
2437    lhi\t%0,%h1
2438    lh\t%0,%1
2439    lhy\t%0,%1
2440    lhrl\t%0,%1
2441    sth\t%1,%0
2442    sthy\t%1,%0
2443    sthrl\t%1,%0
2444    mvhhi\t%0,%1
2445    vleih\t%v0,%h1,0
2446    vlr\t%v0,%v1
2447    vlvgh\t%v0,%1,0
2448    vlgvh\t%0,%v1,0
2449    vleh\t%v0,%1,0
2450    vsteh\t%v1,%0,0"
2451   [(set_attr "op_type"      "RR,RI,RX,RXY,RIL,RX,RXY,RIL,SIL,VRI,VRR,VRS,VRS,VRX,VRX")
2452    (set_attr "type"         "lr,*,*,*,larl,store,store,store,*,*,*,*,*,*,*")
2453    (set_attr "cpu_facility" "*,*,*,longdisp,z10,*,longdisp,z10,z10,vx,vx,vx,vx,vx,vx")
2454    (set_attr "z10prop" "z10_fr_E1,
2455                        z10_fwd_A1,
2456                        z10_super_E1,
2457                        z10_super_E1,
2458                        z10_super_E1,
2459                        z10_rec,
2460                        z10_rec,
2461                        z10_rec,
2462                        z10_super,*,*,*,*,*,*")
2463    (set_attr "relative_long" "*,*,*,*,yes,*,*,yes,*,*,*,*,*,*,*")])
2465 (define_peephole2
2466   [(set (match_operand:HI 0 "register_operand" "")
2467         (mem:HI (match_operand 1 "address_operand" "")))]
2468   "GET_CODE (operands[1]) == SYMBOL_REF
2469    && CONSTANT_POOL_ADDRESS_P (operands[1])
2470    && get_pool_mode (operands[1]) == HImode
2471    && GET_CODE (get_pool_constant (operands[1])) == CONST_INT"
2472   [(set (match_dup 0) (match_dup 2))]
2473   "operands[2] = get_pool_constant (operands[1]);")
2476 ; movqi instruction pattern(s).
2479 (define_expand "movqi"
2480   [(set (match_operand:QI 0 "nonimmediate_operand" "")
2481         (match_operand:QI 1 "general_operand" ""))]
2482   ""
2484   /* On z/Architecture, zero-extending from memory to register
2485      is just as fast as a QImode load.  */
2486   if (TARGET_ZARCH && optimize && can_create_pseudo_p ()
2487       && register_operand (operands[0], VOIDmode)
2488       && GET_CODE (operands[1]) == MEM)
2489     {
2490       rtx tmp = gen_reg_rtx (DImode);
2491       rtx ext = gen_rtx_ZERO_EXTEND (DImode, operands[1]);
2492       emit_insn (gen_rtx_SET (tmp, ext));
2493       operands[1] = gen_lowpart (QImode, tmp);
2494     }
2497 (define_insn "*movqi"
2498   [(set (match_operand:QI 0 "nonimmediate_operand" "=d,d,d,d,R,T,Q,S,?Q,v,v,v,d,v,R")
2499         (match_operand:QI 1 "general_operand"      " d,n,R,T,d,d,n,n,?Q,K,v,d,v,R,v"))]
2500   ""
2501   "@
2502    lr\t%0,%1
2503    lhi\t%0,%b1
2504    ic\t%0,%1
2505    icy\t%0,%1
2506    stc\t%1,%0
2507    stcy\t%1,%0
2508    mvi\t%S0,%b1
2509    mviy\t%S0,%b1
2510    #
2511    vleib\t%v0,%b1,0
2512    vlr\t%v0,%v1
2513    vlvgb\t%v0,%1,0
2514    vlgvb\t%0,%v1,0
2515    vleb\t%v0,%1,0
2516    vsteb\t%v1,%0,0"
2517   [(set_attr "op_type" "RR,RI,RX,RXY,RX,RXY,SI,SIY,SS,VRI,VRR,VRS,VRS,VRX,VRX")
2518    (set_attr "type" "lr,*,*,*,store,store,store,store,*,*,*,*,*,*,*")
2519    (set_attr "cpu_facility" "*,*,*,longdisp,*,longdisp,*,longdisp,*,vx,vx,vx,vx,vx,vx")
2520    (set_attr "z10prop" "z10_fr_E1,
2521                         z10_fwd_A1,
2522                         z10_super_E1,
2523                         z10_super_E1,
2524                         z10_rec,
2525                         z10_rec,
2526                         z10_super,
2527                         z10_super,
2528                         *,*,*,*,*,*,*")])
2530 (define_peephole2
2531   [(set (match_operand:QI 0 "nonimmediate_operand" "")
2532         (mem:QI (match_operand 1 "address_operand" "")))]
2533   "GET_CODE (operands[1]) == SYMBOL_REF
2534    && CONSTANT_POOL_ADDRESS_P (operands[1])
2535    && get_pool_mode (operands[1]) == QImode
2536    && GET_CODE (get_pool_constant (operands[1])) == CONST_INT"
2537   [(set (match_dup 0) (match_dup 2))]
2538   "operands[2] = get_pool_constant (operands[1]);")
2542 ; movstrict instruction pattern(s).
2545 (define_insn "movstrictqi"
2546   [(set (strict_low_part (match_operand:QI 0 "subreg_register_operand" "+d,d"))
2547                          (match_operand:QI 1 "memory_operand"           "R,T"))]
2548   ""
2549   "@
2550    ic\t%0,%1
2551    icy\t%0,%1"
2552   [(set_attr "op_type"  "RX,RXY")
2553    (set_attr "cpu_facility" "*,longdisp")
2554    (set_attr "z10prop" "z10_super_E1,z10_super_E1")])
2556 (define_insn "movstricthi"
2557   [(set (strict_low_part (match_operand:HI 0 "subreg_register_operand" "+d,d"))
2558                          (match_operand:HI 1 "memory_operand"           "Q,S"))
2559    (clobber (reg:CC CC_REGNUM))]
2560   ""
2561   "@
2562    icm\t%0,3,%S1
2563    icmy\t%0,3,%S1"
2564   [(set_attr "op_type" "RS,RSY")
2565    (set_attr "cpu_facility" "*,longdisp")
2566    (set_attr "z10prop" "z10_super_E1,z10_super_E1")])
2568 (define_insn "movstrictsi"
2569   [(set (strict_low_part (match_operand:SI 0 "subreg_register_operand" "+d,d,d,d"))
2570                          (match_operand:SI 1 "general_operand"          "d,R,T,t"))]
2571   "TARGET_ZARCH"
2572   "@
2573    lr\t%0,%1
2574    l\t%0,%1
2575    ly\t%0,%1
2576    ear\t%0,%1"
2577   [(set_attr "op_type" "RR,RX,RXY,RRE")
2578    (set_attr "type" "lr,load,load,*")
2579    (set_attr "cpu_facility" "*,*,longdisp,*")
2580    (set_attr "z10prop" "z10_fr_E1,z10_fwd_A3,z10_fwd_A3,z10_super_E1")])
2583 ; mov(tf|td) instruction pattern(s).
2586 (define_expand "mov<mode><tf_fpr>"
2587   [(set (match_operand:TD_TF 0 "nonimmediate_operand" "")
2588         (match_operand:TD_TF 1 "general_operand"      ""))]
2589   ""
2590   "")
2592 (define_insn "*mov<mode>_64"
2593   [(set (match_operand:TD_TF 0 "nonimmediate_operand" "=f,f,f,o,d,S, d,o")
2594         (match_operand:TD_TF 1 "general_operand"      " G,f,o,f,S,d,dT,d"))]
2595   "TARGET_ZARCH"
2596   "@
2597    lzxr\t%0
2598    lxr\t%0,%1
2599    #
2600    #
2601    lmg\t%0,%N0,%S1
2602    stmg\t%1,%N1,%S0
2603    #
2604    #"
2605   [(set_attr "op_type"      "RRE,RRE,*,*,RSY,RSY,*,*")
2606    (set_attr "type"         "fsimptf,fsimptf,*,*,lm,stm,*,*")
2607    (set_attr "cpu_facility" "z196,*,*,*,*,*,*,*")])
2609 (define_insn "*mov<mode>_31"
2610   [(set (match_operand:TD_TF 0 "nonimmediate_operand" "=f,f,f,o")
2611         (match_operand:TD_TF 1 "general_operand"      " G,f,o,f"))]
2612   "!TARGET_ZARCH"
2613   "@
2614    lzxr\t%0
2615    lxr\t%0,%1
2616    #
2617    #"
2618   [(set_attr "op_type"      "RRE,RRE,*,*")
2619    (set_attr "type"         "fsimptf,fsimptf,*,*")
2620    (set_attr "cpu_facility" "z196,*,*,*")])
2622 ; TFmode in GPRs splitters
2624 (define_split
2625   [(set (match_operand:TD_TF 0 "nonimmediate_operand" "")
2626         (match_operand:TD_TF 1 "general_operand"      ""))]
2627   "TARGET_ZARCH && reload_completed
2628    && !s_operand (operands[0], <MODE>mode)
2629    && !s_operand (operands[1], <MODE>mode)
2630    && s390_split_ok_p (operands[0], operands[1], <MODE>mode, 0)"
2631   [(set (match_dup 2) (match_dup 4))
2632    (set (match_dup 3) (match_dup 5))]
2634   operands[2] = operand_subword (operands[0], 0, 0, <MODE>mode);
2635   operands[3] = operand_subword (operands[0], 1, 0, <MODE>mode);
2636   operands[4] = operand_subword (operands[1], 0, 0, <MODE>mode);
2637   operands[5] = operand_subword (operands[1], 1, 0, <MODE>mode);
2640 (define_split
2641   [(set (match_operand:TD_TF 0 "nonimmediate_operand" "")
2642         (match_operand:TD_TF 1 "general_operand"      ""))]
2643   "TARGET_ZARCH && reload_completed
2644    && !s_operand (operands[0], <MODE>mode)
2645    && !s_operand (operands[1], <MODE>mode)
2646    && s390_split_ok_p (operands[0], operands[1], <MODE>mode, 1)"
2647   [(set (match_dup 2) (match_dup 4))
2648    (set (match_dup 3) (match_dup 5))]
2650   operands[2] = operand_subword (operands[0], 1, 0, <MODE>mode);
2651   operands[3] = operand_subword (operands[0], 0, 0, <MODE>mode);
2652   operands[4] = operand_subword (operands[1], 1, 0, <MODE>mode);
2653   operands[5] = operand_subword (operands[1], 0, 0, <MODE>mode);
2656 (define_split
2657   [(set (match_operand:TD_TF 0 "register_operand" "")
2658         (match_operand:TD_TF 1 "memory_operand"   ""))]
2659   "TARGET_ZARCH && reload_completed
2660    && GENERAL_REG_P (operands[0])
2661    && !s_operand (operands[1], VOIDmode)"
2662   [(set (match_dup 0) (match_dup 1))]
2664   rtx addr = operand_subword (operands[0], 1, 0, <MODE>mode);
2665   addr = gen_lowpart (Pmode, addr);
2666   s390_load_address (addr, XEXP (operands[1], 0));
2667   operands[1] = replace_equiv_address (operands[1], addr);
2670 ; TFmode in BFPs splitters
2672 (define_split
2673   [(set (match_operand:TD_TF 0 "register_operand" "")
2674         (match_operand:TD_TF 1 "memory_operand" ""))]
2675   "reload_completed && offsettable_memref_p (operands[1])
2676    && FP_REG_P (operands[0])"
2677   [(set (match_dup 2) (match_dup 4))
2678    (set (match_dup 3) (match_dup 5))]
2680   operands[2] = simplify_gen_subreg (<HALF_TMODE>mode, operands[0],
2681                                      <MODE>mode, 0);
2682   operands[3] = simplify_gen_subreg (<HALF_TMODE>mode, operands[0],
2683                                      <MODE>mode, 8);
2684   operands[4] = adjust_address_nv (operands[1], <HALF_TMODE>mode, 0);
2685   operands[5] = adjust_address_nv (operands[1], <HALF_TMODE>mode, 8);
2688 (define_split
2689   [(set (match_operand:TD_TF 0 "memory_operand" "")
2690         (match_operand:TD_TF 1 "register_operand" ""))]
2691   "reload_completed && offsettable_memref_p (operands[0])
2692    && FP_REG_P (operands[1])"
2693   [(set (match_dup 2) (match_dup 4))
2694    (set (match_dup 3) (match_dup 5))]
2696   operands[2] = adjust_address_nv (operands[0], <HALF_TMODE>mode, 0);
2697   operands[3] = adjust_address_nv (operands[0], <HALF_TMODE>mode, 8);
2698   operands[4] = simplify_gen_subreg (<HALF_TMODE>mode, operands[1],
2699                                      <MODE>mode, 0);
2700   operands[5] = simplify_gen_subreg (<HALF_TMODE>mode, operands[1],
2701                                      <MODE>mode, 8);
2705 ; mov(df|dd) instruction pattern(s).
2708 (define_expand "mov<mode>"
2709   [(set (match_operand:DD_DF 0 "nonimmediate_operand" "")
2710         (match_operand:DD_DF 1 "general_operand"  ""))]
2711   ""
2712   "")
2714 (define_insn "*mov<mode>_64dfp"
2715   [(set (match_operand:DD_DF 0 "nonimmediate_operand"
2716                                "=f,f,f,d,f,f,R,T,d,d,d,d,b,T,v,v,v,d,v,R")
2717         (match_operand:DD_DF 1 "general_operand"
2718                                " G,f,d,f,R,T,f,f,G,d,b,T,d,d,v,G,d,v,R,v"))]
2719   "TARGET_DFP"
2720   "@
2721    lzdr\t%0
2722    ldr\t%0,%1
2723    ldgr\t%0,%1
2724    lgdr\t%0,%1
2725    ld\t%0,%1
2726    ldy\t%0,%1
2727    std\t%1,%0
2728    stdy\t%1,%0
2729    lghi\t%0,0
2730    lgr\t%0,%1
2731    lgrl\t%0,%1
2732    lg\t%0,%1
2733    stgrl\t%1,%0
2734    stg\t%1,%0
2735    vlr\t%v0,%v1
2736    vleig\t%v0,0,0
2737    vlvgg\t%v0,%1,0
2738    vlgvg\t%0,%v1,0
2739    vleg\t%0,%1,0
2740    vsteg\t%1,%0,0"
2741   [(set_attr "op_type" "RRE,RR,RRE,RRE,RX,RXY,RX,RXY,RI,RRE,RIL,RXY,RIL,RXY,VRR,VRI,VRS,VRS,VRX,VRX")
2742    (set_attr "type" "fsimpdf,floaddf,floaddf,floaddf,floaddf,floaddf,
2743                      fstoredf,fstoredf,*,lr,load,load,store,store,*,*,*,*,load,store")
2744    (set_attr "z10prop" "*,*,*,*,*,*,*,*,z10_fwd_A1,z10_fr_E1,z10_fwd_A3,z10_fwd_A3,z10_rec,z10_rec,*,*,*,*,*,*")
2745    (set_attr "cpu_facility" "z196,*,*,*,*,longdisp,*,longdisp,*,*,z10,*,z10,*,vx,vx,vx,vx,vx,vx")
2746    (set_attr "relative_long" "*,*,*,*,*,*,*,*,*,*,yes,*,yes,*,*,*,*,*,*,*")])
2748 (define_insn "*mov<mode>_64"
2749   [(set (match_operand:DD_DF 0 "nonimmediate_operand" "=f,f,f,f,R,T,d,d,d,d,b,T")
2750         (match_operand:DD_DF 1 "general_operand"      " G,f,R,T,f,f,G,d,b,T,d,d"))]
2751   "TARGET_ZARCH"
2752   "@
2753    lzdr\t%0
2754    ldr\t%0,%1
2755    ld\t%0,%1
2756    ldy\t%0,%1
2757    std\t%1,%0
2758    stdy\t%1,%0
2759    lghi\t%0,0
2760    lgr\t%0,%1
2761    lgrl\t%0,%1
2762    lg\t%0,%1
2763    stgrl\t%1,%0
2764    stg\t%1,%0"
2765   [(set_attr "op_type" "RRE,RR,RX,RXY,RX,RXY,RI,RRE,RIL,RXY,RIL,RXY")
2766    (set_attr "type"    "fsimpdf,fload<mode>,fload<mode>,fload<mode>,
2767                         fstore<mode>,fstore<mode>,*,lr,load,load,store,store")
2768    (set_attr "z10prop" "*,*,*,*,*,*,z10_fwd_A1,z10_fr_E1,z10_fwd_A3,z10_fwd_A3,z10_rec,z10_rec")
2769    (set_attr "cpu_facility" "z196,*,*,longdisp,*,longdisp,*,*,z10,*,z10,*")
2770    (set_attr "relative_long" "*,*,*,*,*,*,*,*,yes,*,*,*")])
2772 (define_insn "*mov<mode>_31"
2773   [(set (match_operand:DD_DF 0 "nonimmediate_operand"
2774                                "=f,f,f,f,R,T,d,d,Q,S,  d,o")
2775         (match_operand:DD_DF 1 "general_operand"
2776                                " G,f,R,T,f,f,Q,S,d,d,dPT,d"))]
2777   "!TARGET_ZARCH"
2778   "@
2779    lzdr\t%0
2780    ldr\t%0,%1
2781    ld\t%0,%1
2782    ldy\t%0,%1
2783    std\t%1,%0
2784    stdy\t%1,%0
2785    lm\t%0,%N0,%S1
2786    lmy\t%0,%N0,%S1
2787    stm\t%1,%N1,%S0
2788    stmy\t%1,%N1,%S0
2789    #
2790    #"
2791   [(set_attr "op_type" "RRE,RR,RX,RXY,RX,RXY,RS,RSY,RS,RSY,*,*")
2792    (set_attr "type"    "fsimpdf,fload<mode>,fload<mode>,fload<mode>,
2793                         fstore<mode>,fstore<mode>,lm,lm,stm,stm,*,*")
2794    (set_attr "cpu_facility" "z196,*,*,longdisp,*,longdisp,*,longdisp,*,longdisp,*,*")])
2796 (define_split
2797   [(set (match_operand:DD_DF 0 "nonimmediate_operand" "")
2798         (match_operand:DD_DF 1 "general_operand" ""))]
2799   "!TARGET_ZARCH && reload_completed
2800    && !s_operand (operands[0], <MODE>mode)
2801    && !s_operand (operands[1], <MODE>mode)
2802    && s390_split_ok_p (operands[0], operands[1], <MODE>mode, 0)"
2803   [(set (match_dup 2) (match_dup 4))
2804    (set (match_dup 3) (match_dup 5))]
2806   operands[2] = operand_subword (operands[0], 0, 0, <MODE>mode);
2807   operands[3] = operand_subword (operands[0], 1, 0, <MODE>mode);
2808   operands[4] = operand_subword (operands[1], 0, 0, <MODE>mode);
2809   operands[5] = operand_subword (operands[1], 1, 0, <MODE>mode);
2812 (define_split
2813   [(set (match_operand:DD_DF 0 "nonimmediate_operand" "")
2814         (match_operand:DD_DF 1 "general_operand" ""))]
2815   "!TARGET_ZARCH && reload_completed
2816    && !s_operand (operands[0], <MODE>mode)
2817    && !s_operand (operands[1], <MODE>mode)
2818    && s390_split_ok_p (operands[0], operands[1], <MODE>mode, 1)"
2819   [(set (match_dup 2) (match_dup 4))
2820    (set (match_dup 3) (match_dup 5))]
2822   operands[2] = operand_subword (operands[0], 1, 0, <MODE>mode);
2823   operands[3] = operand_subword (operands[0], 0, 0, <MODE>mode);
2824   operands[4] = operand_subword (operands[1], 1, 0, <MODE>mode);
2825   operands[5] = operand_subword (operands[1], 0, 0, <MODE>mode);
2828 (define_split
2829   [(set (match_operand:DD_DF 0 "register_operand" "")
2830         (match_operand:DD_DF 1 "memory_operand" ""))]
2831   "!TARGET_ZARCH && reload_completed
2832    && !FP_REG_P (operands[0])
2833    && !s_operand (operands[1], VOIDmode)"
2834   [(set (match_dup 0) (match_dup 1))]
2836   rtx addr = operand_subword (operands[0], 1, 0, <MODE>mode);
2837   s390_load_address (addr, XEXP (operands[1], 0));
2838   operands[1] = replace_equiv_address (operands[1], addr);
2842 ; mov(sf|sd) instruction pattern(s).
2845 (define_insn "mov<mode>"
2846   [(set (match_operand:SD_SF 0 "nonimmediate_operand"
2847                                "=f,f,f,f,f,f,R,T,d,d,d,d,d,b,R,T,v,v,v,d,v,R")
2848         (match_operand:SD_SF 1 "general_operand"
2849                                " G,f,f,R,R,T,f,f,G,d,b,R,T,d,d,d,v,G,d,v,R,v"))]
2850   ""
2851   "@
2852    lzer\t%0
2853    ldr\t%0,%1
2854    ler\t%0,%1
2855    lde\t%0,%1
2856    le\t%0,%1
2857    ley\t%0,%1
2858    ste\t%1,%0
2859    stey\t%1,%0
2860    lhi\t%0,0
2861    lr\t%0,%1
2862    lrl\t%0,%1
2863    l\t%0,%1
2864    ly\t%0,%1
2865    strl\t%1,%0
2866    st\t%1,%0
2867    sty\t%1,%0
2868    vlr\t%v0,%v1
2869    vleif\t%v0,0,0
2870    vlvgf\t%v0,%1,0
2871    vlgvf\t%0,%v1,0
2872    vlef\t%0,%1,0
2873    vstef\t%1,%0,0"
2874   [(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")
2875    (set_attr "type"    "fsimpsf,fsimpsf,fload<mode>,fload<mode>,fload<mode>,fload<mode>,
2876                         fstore<mode>,fstore<mode>,*,lr,load,load,load,store,store,store,*,*,*,*,load,store")
2877    (set_attr "z10prop" "*,*,*,*,*,*,*,*,z10_fwd_A1,z10_fr_E1,z10_fr_E1,z10_fwd_A3,z10_fwd_A3,z10_rec,z10_rec,z10_rec,*,*,*,*,*,*")
2878    (set_attr "cpu_facility" "z196,vx,*,vx,*,longdisp,*,longdisp,*,*,z10,*,longdisp,z10,*,longdisp,vx,vx,vx,vx,vx,vx")
2879    (set_attr "relative_long" "*,*,*,*,*,*,*,*,*,*,yes,*,*,yes,*,*,*,*,*,*,*,*")])
2882 ; movcc instruction pattern
2885 (define_insn "movcc"
2886   [(set (match_operand:CC 0 "nonimmediate_operand" "=d,c,d,d,d,R,T")
2887         (match_operand:CC 1 "nonimmediate_operand" " d,d,c,R,T,d,d"))]
2888   ""
2889   "@
2890    lr\t%0,%1
2891    tmh\t%1,12288
2892    ipm\t%0
2893    l\t%0,%1
2894    ly\t%0,%1
2895    st\t%1,%0
2896    sty\t%1,%0"
2897   [(set_attr "op_type" "RR,RI,RRE,RX,RXY,RX,RXY")
2898    (set_attr "type" "lr,*,*,load,load,store,store")
2899    (set_attr "cpu_facility" "*,*,*,*,longdisp,*,longdisp")
2900    (set_attr "z10prop" "z10_fr_E1,z10_super,*,z10_fwd_A3,z10_fwd_A3,z10_rec,z10_rec")
2901    (set_attr "z196prop" "*,*,z196_ends,*,*,*,*")])
2904 ; Block move (MVC) patterns.
2907 (define_insn "*mvc"
2908   [(set (match_operand:BLK 0 "memory_operand" "=Q")
2909         (match_operand:BLK 1 "memory_operand" "Q"))
2910    (use (match_operand 2 "const_int_operand" "n"))]
2911   "INTVAL (operands[2]) >= 1 && INTVAL (operands[2]) <= 256"
2912   "mvc\t%O0(%2,%R0),%S1"
2913   [(set_attr "op_type" "SS")])
2915 ; This splitter converts a QI to QI mode copy into a BLK mode copy in
2916 ; order to have it implemented with mvc.
2918 (define_split
2919   [(set (match_operand:QI 0 "memory_operand" "")
2920         (match_operand:QI 1 "memory_operand" ""))]
2921   "reload_completed"
2922   [(parallel
2923     [(set (match_dup 0) (match_dup 1))
2924      (use (const_int 1))])]
2926   operands[0] = adjust_address (operands[0], BLKmode, 0);
2927   operands[1] = adjust_address (operands[1], BLKmode, 0);
2931 (define_peephole2
2932   [(parallel
2933     [(set (match_operand:BLK 0 "memory_operand" "")
2934           (match_operand:BLK 1 "memory_operand" ""))
2935      (use (match_operand 2 "const_int_operand" ""))])
2936    (parallel
2937     [(set (match_operand:BLK 3 "memory_operand" "")
2938           (match_operand:BLK 4 "memory_operand" ""))
2939      (use (match_operand 5 "const_int_operand" ""))])]
2940   "((INTVAL (operands[2]) > 16 && INTVAL (operands[5]) > 16)
2941     || (INTVAL (operands[2]) + INTVAL (operands[5]) <= 16))
2942    && s390_offset_p (operands[0], operands[3], operands[2])
2943    && s390_offset_p (operands[1], operands[4], operands[2])
2944    && !s390_overlap_p (operands[0], operands[1],
2945                        INTVAL (operands[2]) + INTVAL (operands[5]))
2946    && INTVAL (operands[2]) + INTVAL (operands[5]) <= 256"
2947   [(parallel
2948     [(set (match_dup 6) (match_dup 7))
2949      (use (match_dup 8))])]
2950   "operands[6] = gen_rtx_MEM (BLKmode, XEXP (operands[0], 0));
2951    operands[7] = gen_rtx_MEM (BLKmode, XEXP (operands[1], 0));
2952    operands[8] = GEN_INT (INTVAL (operands[2]) + INTVAL (operands[5]));")
2954 (define_peephole2
2955   [(parallel
2956     [(set (match_operand:BLK 0 "plus16_Q_operand" "")
2957           (match_operand:BLK 1 "plus16_Q_operand" ""))
2958      (use (match_operand 2 "const_int_operand" ""))])]
2959   "INTVAL (operands[2]) > 16 && INTVAL (operands[2]) <= 32"
2960   [(parallel
2961     [(set (match_dup 0) (match_dup 1))
2962      (use (const_int 16))])
2963    (parallel
2964     [(set (match_dup 3) (match_dup 4))
2965      (use (match_dup 5))])]
2966   "operands[3] = change_address (operands[0], VOIDmode,
2967                                  plus_constant (Pmode, XEXP (operands[0], 0), 16));
2968    operands[4] = change_address (operands[1], VOIDmode,
2969                                  plus_constant (Pmode, XEXP (operands[1], 0), 16));
2970    operands[5] = GEN_INT (INTVAL (operands[2]) - 16);")
2974 ; load_multiple pattern(s).
2976 ; ??? Due to reload problems with replacing registers inside match_parallel
2977 ; we currently support load_multiple/store_multiple only after reload.
2980 (define_expand "load_multiple"
2981   [(match_par_dup 3 [(set (match_operand 0 "" "")
2982                           (match_operand 1 "" ""))
2983                      (use (match_operand 2 "" ""))])]
2984   "reload_completed"
2986   machine_mode mode;
2987   int regno;
2988   int count;
2989   rtx from;
2990   int i, off;
2992   /* Support only loading a constant number of fixed-point registers from
2993      memory and only bother with this if more than two */
2994   if (GET_CODE (operands[2]) != CONST_INT
2995       || INTVAL (operands[2]) < 2
2996       || INTVAL (operands[2]) > 16
2997       || GET_CODE (operands[1]) != MEM
2998       || GET_CODE (operands[0]) != REG
2999       || REGNO (operands[0]) >= 16)
3000     FAIL;
3002   count = INTVAL (operands[2]);
3003   regno = REGNO (operands[0]);
3004   mode = GET_MODE (operands[0]);
3005   if (mode != SImode && (!TARGET_ZARCH || mode != DImode))
3006     FAIL;
3008   operands[3] = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (count));
3009   if (!can_create_pseudo_p ())
3010     {
3011       if (GET_CODE (XEXP (operands[1], 0)) == REG)
3012         {
3013           from = XEXP (operands[1], 0);
3014           off = 0;
3015         }
3016       else if (GET_CODE (XEXP (operands[1], 0)) == PLUS
3017                && GET_CODE (XEXP (XEXP (operands[1], 0), 0)) == REG
3018                && GET_CODE (XEXP (XEXP (operands[1], 0), 1)) == CONST_INT)
3019         {
3020           from = XEXP (XEXP (operands[1], 0), 0);
3021           off = INTVAL (XEXP (XEXP (operands[1], 0), 1));
3022         }
3023       else
3024         FAIL;
3025     }
3026   else
3027     {
3028       from = force_reg (Pmode, XEXP (operands[1], 0));
3029       off = 0;
3030     }
3032   for (i = 0; i < count; i++)
3033     XVECEXP (operands[3], 0, i)
3034       = gen_rtx_SET (gen_rtx_REG (mode, regno + i),
3035                      change_address (operands[1], mode,
3036                        plus_constant (Pmode, from,
3037                                       off + i * GET_MODE_SIZE (mode))));
3040 (define_insn "*load_multiple_di"
3041   [(match_parallel 0 "load_multiple_operation"
3042                    [(set (match_operand:DI 1 "register_operand" "=r")
3043                          (match_operand:DI 2 "s_operand" "S"))])]
3044   "reload_completed && TARGET_ZARCH"
3046   int words = XVECLEN (operands[0], 0);
3047   operands[0] = gen_rtx_REG (DImode, REGNO (operands[1]) + words - 1);
3048   return "lmg\t%1,%0,%S2";
3050    [(set_attr "op_type" "RSY")
3051     (set_attr "type"    "lm")])
3053 (define_insn "*load_multiple_si"
3054   [(match_parallel 0 "load_multiple_operation"
3055                    [(set (match_operand:SI 1 "register_operand" "=r,r")
3056                          (match_operand:SI 2 "s_operand" "Q,S"))])]
3057   "reload_completed"
3059   int words = XVECLEN (operands[0], 0);
3060   operands[0] = gen_rtx_REG (SImode, REGNO (operands[1]) + words - 1);
3061   return which_alternative == 0 ? "lm\t%1,%0,%S2" : "lmy\t%1,%0,%S2";
3063    [(set_attr "op_type" "RS,RSY")
3064     (set_attr "cpu_facility" "*,longdisp")
3065     (set_attr "type"    "lm")])
3068 ; store multiple pattern(s).
3071 (define_expand "store_multiple"
3072   [(match_par_dup 3 [(set (match_operand 0 "" "")
3073                           (match_operand 1 "" ""))
3074                      (use (match_operand 2 "" ""))])]
3075   "reload_completed"
3077   machine_mode mode;
3078   int regno;
3079   int count;
3080   rtx to;
3081   int i, off;
3083   /* Support only storing a constant number of fixed-point registers to
3084      memory and only bother with this if more than two.  */
3085   if (GET_CODE (operands[2]) != CONST_INT
3086       || INTVAL (operands[2]) < 2
3087       || INTVAL (operands[2]) > 16
3088       || GET_CODE (operands[0]) != MEM
3089       || GET_CODE (operands[1]) != REG
3090       || REGNO (operands[1]) >= 16)
3091     FAIL;
3093   count = INTVAL (operands[2]);
3094   regno = REGNO (operands[1]);
3095   mode = GET_MODE (operands[1]);
3096   if (mode != SImode && (!TARGET_ZARCH || mode != DImode))
3097     FAIL;
3099   operands[3] = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (count));
3101   if (!can_create_pseudo_p ())
3102     {
3103       if (GET_CODE (XEXP (operands[0], 0)) == REG)
3104         {
3105           to = XEXP (operands[0], 0);
3106           off = 0;
3107         }
3108       else if (GET_CODE (XEXP (operands[0], 0)) == PLUS
3109                && GET_CODE (XEXP (XEXP (operands[0], 0), 0)) == REG
3110                && GET_CODE (XEXP (XEXP (operands[0], 0), 1)) == CONST_INT)
3111         {
3112           to = XEXP (XEXP (operands[0], 0), 0);
3113           off = INTVAL (XEXP (XEXP (operands[0], 0), 1));
3114         }
3115       else
3116         FAIL;
3117     }
3118   else
3119     {
3120       to = force_reg (Pmode, XEXP (operands[0], 0));
3121       off = 0;
3122     }
3124   for (i = 0; i < count; i++)
3125     XVECEXP (operands[3], 0, i)
3126       = gen_rtx_SET (change_address (operands[0], mode,
3127                        plus_constant (Pmode, to,
3128                                       off + i * GET_MODE_SIZE (mode))),
3129                      gen_rtx_REG (mode, regno + i));
3132 (define_insn "*store_multiple_di"
3133   [(match_parallel 0 "store_multiple_operation"
3134                    [(set (match_operand:DI 1 "s_operand" "=S")
3135                          (match_operand:DI 2 "register_operand" "r"))])]
3136   "reload_completed && TARGET_ZARCH"
3138   int words = XVECLEN (operands[0], 0);
3139   operands[0] = gen_rtx_REG (DImode, REGNO (operands[2]) + words - 1);
3140   return "stmg\t%2,%0,%S1";
3142    [(set_attr "op_type" "RSY")
3143     (set_attr "type"    "stm")])
3146 (define_insn "*store_multiple_si"
3147   [(match_parallel 0 "store_multiple_operation"
3148                    [(set (match_operand:SI 1 "s_operand" "=Q,S")
3149                          (match_operand:SI 2 "register_operand" "r,r"))])]
3150   "reload_completed"
3152   int words = XVECLEN (operands[0], 0);
3153   operands[0] = gen_rtx_REG (SImode, REGNO (operands[2]) + words - 1);
3154   return which_alternative == 0 ? "stm\t%2,%0,%S1" : "stmy\t%2,%0,%S1";
3156    [(set_attr "op_type" "RS,RSY")
3157     (set_attr "cpu_facility" "*,longdisp")
3158     (set_attr "type"    "stm")])
3161 ;; String instructions.
3164 (define_insn "*execute_rl"
3165   [(match_parallel 0 "execute_operation"
3166     [(unspec [(match_operand 1    "register_operand" "a")
3167               (match_operand 2    "" "")
3168               (match_operand:SI 3 "larl_operand" "X")] UNSPEC_EXECUTE)])]
3169   "TARGET_Z10 && GET_MODE_CLASS (GET_MODE (operands[1])) == MODE_INT
3170    && GET_MODE_SIZE (GET_MODE (operands[1])) <= UNITS_PER_WORD"
3171   "exrl\t%1,%3"
3172   [(set_attr "op_type" "RIL")
3173    (set_attr "type"    "cs")
3174    (set_attr "relative_long" "yes")])
3176 (define_insn "*execute"
3177   [(match_parallel 0 "execute_operation"
3178     [(unspec [(match_operand 1 "register_operand" "a")
3179               (match_operand:BLK 2 "memory_operand" "R")
3180               (match_operand 3 "" "")] UNSPEC_EXECUTE)])]
3181   "GET_MODE_CLASS (GET_MODE (operands[1])) == MODE_INT
3182    && GET_MODE_SIZE (GET_MODE (operands[1])) <= UNITS_PER_WORD"
3183   "ex\t%1,%2"
3184   [(set_attr "op_type" "RX")
3185    (set_attr "type" "cs")])
3189 ; strlenM instruction pattern(s).
3192 (define_expand "strlen<mode>"
3193   [(match_operand:P   0 "register_operand" "")  ; result
3194    (match_operand:BLK 1 "memory_operand" "")    ; input string
3195    (match_operand:SI  2 "immediate_operand" "") ; search character
3196    (match_operand:SI  3 "immediate_operand" "")] ; known alignment
3197   ""
3199   if (!TARGET_VX || operands[2] != const0_rtx)
3200     emit_insn (gen_strlen_srst<mode> (operands[0], operands[1],
3201                                       operands[2], operands[3]));
3202   else
3203     s390_expand_vec_strlen (operands[0], operands[1], operands[3]);
3205   DONE;
3208 (define_expand "strlen_srst<mode>"
3209   [(set (reg:SI 0) (match_operand:SI 2 "immediate_operand" ""))
3210    (parallel
3211     [(set (match_dup 4)
3212           (unspec:P [(const_int 0)
3213                       (match_operand:BLK 1 "memory_operand" "")
3214                       (reg:SI 0)
3215                       (match_operand 3 "immediate_operand" "")] UNSPEC_SRST))
3216      (clobber (scratch:P))
3217      (clobber (reg:CC CC_REGNUM))])
3218    (parallel
3219     [(set (match_operand:P 0 "register_operand" "")
3220           (minus:P (match_dup 4) (match_dup 5)))
3221      (clobber (reg:CC CC_REGNUM))])]
3222   ""
3224   operands[4] = gen_reg_rtx (Pmode);
3225   operands[5] = gen_reg_rtx (Pmode);
3226   emit_move_insn (operands[5], force_operand (XEXP (operands[1], 0), NULL_RTX));
3227   operands[1] = replace_equiv_address (operands[1], operands[5]);
3230 (define_insn "*strlen<mode>"
3231   [(set (match_operand:P 0 "register_operand" "=a")
3232         (unspec:P [(match_operand:P 2 "general_operand" "0")
3233                     (mem:BLK (match_operand:P 3 "register_operand" "1"))
3234                     (reg:SI 0)
3235                     (match_operand 4 "immediate_operand" "")] UNSPEC_SRST))
3236    (clobber (match_scratch:P 1 "=a"))
3237    (clobber (reg:CC CC_REGNUM))]
3238   ""
3239   "srst\t%0,%1\;jo\t.-4"
3240   [(set_attr "length" "8")
3241    (set_attr "type" "vs")])
3244 ; cmpstrM instruction pattern(s).
3247 (define_expand "cmpstrsi"
3248   [(set (reg:SI 0) (const_int 0))
3249    (parallel
3250     [(clobber (match_operand 3 "" ""))
3251      (clobber (match_dup 4))
3252      (set (reg:CCU CC_REGNUM)
3253           (compare:CCU (match_operand:BLK 1 "memory_operand" "")
3254                        (match_operand:BLK 2 "memory_operand" "")))
3255      (use (reg:SI 0))])
3256    (parallel
3257     [(set (match_operand:SI 0 "register_operand" "=d")
3258           (unspec:SI [(reg:CCU CC_REGNUM)] UNSPEC_STRCMPCC_TO_INT))
3259      (clobber (reg:CC CC_REGNUM))])]
3260   ""
3262   /* As the result of CMPINT is inverted compared to what we need,
3263      we have to swap the operands.  */
3264   rtx op1 = operands[2];
3265   rtx op2 = operands[1];
3266   rtx addr1 = gen_reg_rtx (Pmode);
3267   rtx addr2 = gen_reg_rtx (Pmode);
3269   emit_move_insn (addr1, force_operand (XEXP (op1, 0), NULL_RTX));
3270   emit_move_insn (addr2, force_operand (XEXP (op2, 0), NULL_RTX));
3271   operands[1] = replace_equiv_address_nv (op1, addr1);
3272   operands[2] = replace_equiv_address_nv (op2, addr2);
3273   operands[3] = addr1;
3274   operands[4] = addr2;
3277 (define_insn "*cmpstr<mode>"
3278   [(clobber (match_operand:P 0 "register_operand" "=d"))
3279    (clobber (match_operand:P 1 "register_operand" "=d"))
3280    (set (reg:CCU CC_REGNUM)
3281         (compare:CCU (mem:BLK (match_operand:P 2 "register_operand" "0"))
3282                      (mem:BLK (match_operand:P 3 "register_operand" "1"))))
3283    (use (reg:SI 0))]
3284   ""
3285   "clst\t%0,%1\;jo\t.-4"
3286   [(set_attr "length" "8")
3287    (set_attr "type" "vs")])
3290 ; movstr instruction pattern.
3293 (define_expand "movstr"
3294   [(match_operand 0 "register_operand" "")
3295    (match_operand 1 "memory_operand" "")
3296    (match_operand 2 "memory_operand" "")]
3297   ""
3299   if (TARGET_64BIT)
3300     emit_insn (gen_movstrdi (operands[0], operands[1], operands[2]));
3301   else
3302     emit_insn (gen_movstrsi (operands[0], operands[1], operands[2]));
3303   DONE;
3306 (define_expand "movstr<P:mode>"
3307   [(set (reg:SI 0) (const_int 0))
3308    (parallel
3309     [(clobber (match_dup 3))
3310      (set (match_operand:BLK 1 "memory_operand" "")
3311           (match_operand:BLK 2 "memory_operand" ""))
3312      (set (match_operand:P 0 "register_operand" "")
3313           (unspec:P [(match_dup 1)
3314                    (match_dup 2)
3315                    (reg:SI 0)] UNSPEC_MVST))
3316      (clobber (reg:CC CC_REGNUM))])]
3317   ""
3319   rtx addr1, addr2;
3321   if (TARGET_VX && optimize_function_for_speed_p (cfun))
3322     {
3323       s390_expand_vec_movstr (operands[0], operands[1], operands[2]);
3324       DONE;
3325     }
3327   addr1 = gen_reg_rtx (Pmode);
3328   addr2 = gen_reg_rtx (Pmode);
3330   emit_move_insn (addr1, force_operand (XEXP (operands[1], 0), NULL_RTX));
3331   emit_move_insn (addr2, force_operand (XEXP (operands[2], 0), NULL_RTX));
3332   operands[1] = replace_equiv_address_nv (operands[1], addr1);
3333   operands[2] = replace_equiv_address_nv (operands[2], addr2);
3334   operands[3] = addr2;
3337 (define_insn "*movstr"
3338   [(clobber (match_operand:P 2 "register_operand" "=d"))
3339    (set (mem:BLK (match_operand:P 1 "register_operand" "0"))
3340         (mem:BLK (match_operand:P 3 "register_operand" "2")))
3341    (set (match_operand:P 0 "register_operand" "=d")
3342         (unspec:P [(mem:BLK (match_dup 1))
3343                  (mem:BLK (match_dup 3))
3344                  (reg:SI 0)] UNSPEC_MVST))
3345    (clobber (reg:CC CC_REGNUM))]
3346   ""
3347   "mvst\t%1,%2\;jo\t.-4"
3348   [(set_attr "length" "8")
3349    (set_attr "type" "vs")])
3353 ; cpymemM instruction pattern(s).
3356 (define_expand "cpymem<mode>"
3357   [(set (match_operand:BLK 0 "memory_operand" "")   ; destination
3358         (match_operand:BLK 1 "memory_operand" ""))  ; source
3359    (use (match_operand:GPR 2 "general_operand" "")) ; size
3360    (match_operand 3 "")  ; align
3361    (match_operand 4 "")  ; expected align
3362    (match_operand 5 "")  ; expected size
3363    (match_operand 6 "")  ; minimal size
3364    (match_operand 7 "")] ; maximal size
3365   ""
3367   if (s390_expand_cpymem (operands[0], operands[1], operands[2], operands[6], operands[7]))
3368     DONE;
3369   else
3370     FAIL;
3373 ; Move a block that is up to 256 bytes in length.
3374 ; The block length is taken as (operands[2] % 256) + 1.
3376 (define_expand "cpymem_short"
3377   [(parallel
3378     [(set (match_operand:BLK 0 "memory_operand" "")
3379           (match_operand:BLK 1 "memory_operand" ""))
3380      (use (match_operand 2 "nonmemory_operand" ""))
3381      (use (const:BLK (unspec:BLK [(const_int 0)] UNSPEC_INSN)))
3382      (clobber (match_dup 3))])]
3383   ""
3384   "operands[3] = gen_rtx_SCRATCH (Pmode);")
3386 (define_insn "*cpymem_short"
3387   [(set (match_operand:BLK 0 "memory_operand" "=Q,Q,Q,Q")
3388         (match_operand:BLK 1 "memory_operand" "Q,Q,Q,Q"))
3389    (use (match_operand 2 "nonmemory_operand" "n,a,a,a"))
3390    (use (match_operand 3 "immediate_operand" "X,R,X,X"))
3391    (clobber (match_scratch:P 4 "=X,X,X,&a"))]
3392   "(GET_MODE (operands[2]) == Pmode || GET_MODE (operands[2]) == VOIDmode)"
3393   "#"
3394   [(set_attr "type"         "cs")
3395    (set_attr "cpu_facility" "*,*,z10,cpu_zarch")])
3397 (define_split
3398   [(set (match_operand:BLK 0 "memory_operand" "")
3399         (match_operand:BLK 1 "memory_operand" ""))
3400    (use (match_operand 2 "const_int_operand" ""))
3401    (use (match_operand 3 "immediate_operand" ""))
3402    (clobber (scratch))]
3403   "reload_completed"
3404   [(parallel
3405     [(set (match_dup 0) (match_dup 1))
3406      (use (match_dup 2))])]
3407   "operands[2] = GEN_INT ((INTVAL (operands[2]) & 0xff) + 1);")
3409 (define_split
3410   [(set (match_operand:BLK 0 "memory_operand" "")
3411         (match_operand:BLK 1 "memory_operand" ""))
3412    (use (match_operand 2 "register_operand" ""))
3413    (use (match_operand 3 "memory_operand" ""))
3414    (clobber (scratch))]
3415   "reload_completed"
3416   [(parallel
3417     [(unspec [(match_dup 2) (match_dup 3)
3418               (const_int 0)] UNSPEC_EXECUTE)
3419      (set (match_dup 0) (match_dup 1))
3420      (use (const_int 1))])]
3421   "")
3423 (define_split
3424   [(set (match_operand:BLK 0 "memory_operand" "")
3425         (match_operand:BLK 1 "memory_operand" ""))
3426    (use (match_operand 2 "register_operand" ""))
3427    (use (const:BLK (unspec:BLK [(const_int 0)] UNSPEC_INSN)))
3428    (clobber (scratch))]
3429   "TARGET_Z10 && reload_completed"
3430   [(parallel
3431     [(unspec [(match_dup 2) (const_int 0)
3432               (label_ref (match_dup 3))] UNSPEC_EXECUTE)
3433      (set (match_dup 0) (match_dup 1))
3434      (use (const_int 1))])]
3435   "operands[3] = gen_label_rtx ();")
3437 (define_split
3438   [(set (match_operand:BLK 0 "memory_operand" "")
3439         (match_operand:BLK 1 "memory_operand" ""))
3440    (use (match_operand 2 "register_operand" ""))
3441    (use (const:BLK (unspec:BLK [(const_int 0)] UNSPEC_INSN)))
3442    (clobber (match_operand 3 "register_operand" ""))]
3443   "reload_completed"
3444   [(set (match_dup 3) (label_ref (match_dup 4)))
3445    (parallel
3446     [(unspec [(match_dup 2) (mem:BLK (match_dup 3))
3447               (label_ref (match_dup 4))] UNSPEC_EXECUTE)
3448      (set (match_dup 0) (match_dup 1))
3449      (use (const_int 1))])]
3450   "operands[4] = gen_label_rtx ();")
3452 ; Move a block of arbitrary length.
3454 (define_expand "cpymem_long"
3455   [(parallel
3456     [(clobber (match_dup 2))
3457      (clobber (match_dup 3))
3458      (set (match_operand:BLK 0 "memory_operand" "")
3459           (match_operand:BLK 1 "memory_operand" ""))
3460      (use (match_operand 2 "general_operand" ""))
3461      (use (match_dup 3))
3462      (clobber (reg:CC CC_REGNUM))])]
3463   ""
3465   machine_mode sreg_mode = TARGET_ZARCH ? DImode : SImode;
3466   machine_mode dreg_mode = TARGET_ZARCH ? TImode : DImode;
3467   rtx reg0 = gen_reg_rtx (dreg_mode);
3468   rtx reg1 = gen_reg_rtx (dreg_mode);
3469   rtx addr0 = gen_lowpart (Pmode, gen_highpart (sreg_mode, reg0));
3470   rtx addr1 = gen_lowpart (Pmode, gen_highpart (sreg_mode, reg1));
3471   rtx len0 = gen_lowpart (Pmode, reg0);
3472   rtx len1 = gen_lowpart (Pmode, reg1);
3474   emit_clobber (reg0);
3475   emit_move_insn (addr0, force_operand (XEXP (operands[0], 0), NULL_RTX));
3476   emit_move_insn (len0, operands[2]);
3478   emit_clobber (reg1);
3479   emit_move_insn (addr1, force_operand (XEXP (operands[1], 0), NULL_RTX));
3480   emit_move_insn (len1, operands[2]);
3482   operands[0] = replace_equiv_address_nv (operands[0], addr0);
3483   operands[1] = replace_equiv_address_nv (operands[1], addr1);
3484   operands[2] = reg0;
3485   operands[3] = reg1;
3488 (define_insn "*cpymem_long"
3489   [(clobber (match_operand:<DBL> 0 "register_operand" "=d"))
3490    (clobber (match_operand:<DBL> 1 "register_operand" "=d"))
3491    (set (mem:BLK (subreg:P (match_operand:<DBL> 2 "register_operand" "0") 0))
3492         (mem:BLK (subreg:P (match_operand:<DBL> 3 "register_operand" "1") 0)))
3493    (use (match_dup 2))
3494    (use (match_dup 3))
3495    (clobber (reg:CC CC_REGNUM))]
3496   "TARGET_64BIT || !TARGET_ZARCH"
3497   "mvcle\t%0,%1,0\;jo\t.-4"
3498   [(set_attr "length" "8")
3499    (set_attr "type" "vs")])
3501 (define_insn "*cpymem_long_31z"
3502   [(clobber (match_operand:TI 0 "register_operand" "=d"))
3503    (clobber (match_operand:TI 1 "register_operand" "=d"))
3504    (set (mem:BLK (subreg:SI (match_operand:TI 2 "register_operand" "0") 4))
3505         (mem:BLK (subreg:SI (match_operand:TI 3 "register_operand" "1") 4)))
3506    (use (match_dup 2))
3507    (use (match_dup 3))
3508    (clobber (reg:CC CC_REGNUM))]
3509   "!TARGET_64BIT && TARGET_ZARCH"
3510   "mvcle\t%0,%1,0\;jo\t.-4"
3511   [(set_attr "length" "8")
3512    (set_attr "type" "vs")])
3514 (define_expand "movmem<mode>"
3515   [(set (match_operand:BLK 0 "memory_operand")   ; destination
3516         (match_operand:BLK 1 "memory_operand"))  ; source
3517    (use (match_operand:GPR 2 "general_operand")) ; size
3518    (match_operand 3 "")  ; align
3519    (match_operand 4 "")  ; expected align
3520    (match_operand 5 "")  ; expected size
3521    (match_operand 6 "")  ; minimal size
3522    (match_operand 7 "")] ; maximal size
3523   ""
3525   if (s390_expand_movmem (operands[0], operands[1], operands[2], operands[6], operands[7]))
3526     DONE;
3527   else
3528     FAIL;
3531 (define_insn "*mvcrl"
3532   [(set (match_operand:BLK 0 "memory_operand" "=Q")
3533         (unspec:BLK [(match_operand:BLK 1 "memory_operand" "Q")
3534                      (reg:SI GPR0_REGNUM)]
3535                     UNSPEC_MVCRL))]
3536   "TARGET_Z15"
3537   "mvcrl\t%0,%1"
3538   [(set_attr "op_type" "SSE")])
3540 (define_expand "mvcrl"
3541   [(set (reg:SI GPR0_REGNUM) (match_operand:SI 2 "general_operand"))
3542    (set (match_operand:BLK 0 "memory_operand" "=Q")
3543         (unspec:BLK [(match_operand:BLK 1 "memory_operand" "Q")
3544                      (reg:SI GPR0_REGNUM)]
3545                     UNSPEC_MVCRL))]
3546   "TARGET_Z15"
3547   "")
3550 ; Test data class.
3553 (define_expand "signbit<mode>2<tf_fpr>"
3554   [(set (reg:CCZ CC_REGNUM)
3555         (unspec:CCZ [(match_operand:FP_ALL 1 "register_operand" "f")
3556                      (match_dup 2)]
3557                      UNSPEC_TDC_INSN))
3558    (set (match_operand:SI 0 "register_operand" "=d")
3559         (unspec:SI [(reg:CCZ CC_REGNUM)] UNSPEC_CC_TO_INT))]
3560   "TARGET_HARD_FLOAT"
3562   operands[2] = GEN_INT (S390_TDC_SIGNBIT_SET);
3565 (define_expand "isinf<mode>2<tf_fpr>"
3566   [(set (reg:CCZ CC_REGNUM)
3567         (unspec:CCZ [(match_operand:FP_ALL 1 "register_operand" "f")
3568                      (match_dup 2)]
3569                      UNSPEC_TDC_INSN))
3570    (set (match_operand:SI 0 "register_operand" "=d")
3571         (unspec:SI [(reg:CCZ CC_REGNUM)] UNSPEC_CC_TO_INT))]
3572   "TARGET_HARD_FLOAT"
3574   operands[2] = GEN_INT (S390_TDC_INFINITY);
3577 ; This extracts CC into a GPR properly shifted.  The actual IPM
3578 ; instruction will be issued by reload.  The constraint of operand 1
3579 ; forces reload to use a GPR.  So reload will issue a movcc insn for
3580 ; copying CC into a GPR first.
3581 (define_insn_and_split "*cc_to_int"
3582   [(set (match_operand:SI 0 "nonimmediate_operand"     "=d")
3583         (unspec:SI [(match_operand 1 "register_operand" "0")]
3584                    UNSPEC_CC_TO_INT))]
3585   ""
3586   "#"
3587   "reload_completed"
3588   [(set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 28)))])
3590 ; This insn is used to generate all variants of the Test Data Class
3591 ; instruction, namely tcxb, tcdb, and tceb.  The insn's first operand
3592 ; is the register to be tested and the second one is the bit mask
3593 ; specifying the required test(s).
3595 ; tcxb, tcdb, tceb, tdcxt, tdcdt, tdcet
3596 (define_insn "*TDC_insn_<mode>"
3597   [(set (reg:CCZ CC_REGNUM)
3598         (unspec:CCZ [(match_operand:FP_ALL 0 "register_operand" "f")
3599                      (match_operand:SI 1 "const_int_operand")] UNSPEC_TDC_INSN))]
3600   "TARGET_HARD_FLOAT"
3601   "t<_d>c<xde><bt>\t%0,%1"
3602    [(set_attr "op_type" "RXE")
3603     (set_attr "type"    "fsimp<type>")])
3608 ; setmemM instruction pattern(s).
3611 (define_expand "setmem<mode>"
3612   [(set (match_operand:BLK 0 "memory_operand" "")   ; destination
3613         (match_operand:QI 2 "general_operand" ""))  ; value
3614    (use (match_operand:GPR 1 "general_operand" "")) ; size
3615    (match_operand 3 "")  ; align
3616    (match_operand 4 "")  ; expected align
3617    (match_operand 5 "")  ; expected size
3618    (match_operand 6 "")  ; minimal size
3619    (match_operand 7 "")] ; maximal size
3620   ""
3621   "s390_expand_setmem (operands[0], operands[1], operands[2], operands[6], operands[7]); DONE;")
3623 ; Clear a block that is up to 256 bytes in length.
3624 ; The block length is taken as (operands[1] % 256) + 1.
3626 (define_expand "clrmem_short"
3627   [(parallel
3628     [(set (match_operand:BLK 0 "memory_operand" "")
3629           (const_int 0))
3630      (use (match_operand 1 "nonmemory_operand" ""))
3631      (use (const:BLK (unspec:BLK [(const_int 0)] UNSPEC_INSN)))
3632      (clobber (match_dup 2))
3633      (clobber (reg:CC CC_REGNUM))])]
3634   ""
3635   "operands[2] = gen_rtx_SCRATCH (Pmode);")
3637 (define_insn "*clrmem_short"
3638   [(set (match_operand:BLK 0 "memory_operand" "=Q,Q,Q,Q")
3639         (const_int 0))
3640    (use (match_operand 1 "nonmemory_operand" "n,a,a,a"))
3641    (use (match_operand 2 "immediate_operand" "X,R,X,X"))
3642    (clobber (match_scratch:P 3 "=X,X,X,&a"))
3643    (clobber (reg:CC CC_REGNUM))]
3644   "(GET_MODE (operands[1]) == Pmode || GET_MODE (operands[1]) == VOIDmode)"
3645   "#"
3646   [(set_attr "type" "cs")
3647    (set_attr "cpu_facility" "*,*,z10,cpu_zarch")])
3649 (define_split
3650   [(set (match_operand:BLK 0 "memory_operand" "")
3651         (const_int 0))
3652    (use (match_operand 1 "const_int_operand" ""))
3653    (use (match_operand 2 "immediate_operand" ""))
3654    (clobber (scratch))
3655    (clobber (reg:CC CC_REGNUM))]
3656   "reload_completed"
3657   [(parallel
3658     [(set (match_dup 0) (const_int 0))
3659      (use (match_dup 1))
3660      (clobber (reg:CC CC_REGNUM))])]
3661   "operands[1] = GEN_INT ((INTVAL (operands[1]) & 0xff) + 1);")
3663 (define_split
3664   [(set (match_operand:BLK 0 "memory_operand" "")
3665         (const_int 0))
3666    (use (match_operand 1 "register_operand" ""))
3667    (use (match_operand 2 "memory_operand" ""))
3668    (clobber (scratch))
3669    (clobber (reg:CC CC_REGNUM))]
3670   "reload_completed"
3671   [(parallel
3672     [(unspec [(match_dup 1) (match_dup 2)
3673               (const_int 0)] UNSPEC_EXECUTE)
3674      (set (match_dup 0) (const_int 0))
3675      (use (const_int 1))
3676      (clobber (reg:CC CC_REGNUM))])]
3677   "")
3679 (define_split
3680   [(set (match_operand:BLK 0 "memory_operand" "")
3681         (const_int 0))
3682    (use (match_operand 1 "register_operand" ""))
3683    (use (const:BLK (unspec:BLK [(const_int 0)] UNSPEC_INSN)))
3684    (clobber (scratch))
3685    (clobber (reg:CC CC_REGNUM))]
3686   "TARGET_Z10 && reload_completed"
3687   [(parallel
3688     [(unspec [(match_dup 1) (const_int 0)
3689               (label_ref (match_dup 3))] UNSPEC_EXECUTE)
3690      (set (match_dup 0) (const_int 0))
3691      (use (const_int 1))
3692      (clobber (reg:CC CC_REGNUM))])]
3693   "operands[3] = gen_label_rtx ();")
3695 (define_split
3696   [(set (match_operand:BLK 0 "memory_operand" "")
3697         (const_int 0))
3698    (use (match_operand 1 "register_operand" ""))
3699    (use (const:BLK (unspec:BLK [(const_int 0)] UNSPEC_INSN)))
3700    (clobber (match_operand 2 "register_operand" ""))
3701    (clobber (reg:CC CC_REGNUM))]
3702   "reload_completed"
3703   [(set (match_dup 2) (label_ref (match_dup 3)))
3704    (parallel
3705     [(unspec [(match_dup 1) (mem:BLK (match_dup 2))
3706               (label_ref (match_dup 3))] UNSPEC_EXECUTE)
3707      (set (match_dup 0) (const_int 0))
3708      (use (const_int 1))
3709      (clobber (reg:CC CC_REGNUM))])]
3710   "operands[3] = gen_label_rtx ();")
3712 ; Initialize a block of arbitrary length with (operands[2] % 256).
3714 (define_expand "setmem_long_<P:mode>"
3715   [(parallel
3716     [(clobber (match_dup 1))
3717      (set (match_operand:BLK 0 "memory_operand" "")
3718           (unspec:BLK [(match_operand:P 2 "setmem_operand" "")
3719                       (match_dup 4)] UNSPEC_REPLICATE_BYTE))
3720      (use (match_dup 3))
3721      (clobber (reg:CC CC_REGNUM))])]
3722   ""
3724   machine_mode sreg_mode = TARGET_ZARCH ? DImode : SImode;
3725   machine_mode dreg_mode = TARGET_ZARCH ? TImode : DImode;
3726   rtx reg0 = gen_reg_rtx (dreg_mode);
3727   rtx reg1 = gen_reg_rtx (dreg_mode);
3728   rtx addr0 = gen_lowpart (Pmode, gen_highpart (sreg_mode, reg0));
3729   rtx len0 = gen_lowpart (Pmode, reg0);
3731   emit_clobber (reg0);
3732   emit_move_insn (addr0, force_operand (XEXP (operands[0], 0), NULL_RTX));
3733   emit_move_insn (len0, operands[1]);
3735   emit_move_insn (reg1, const0_rtx);
3737   operands[0] = replace_equiv_address_nv (operands[0], addr0);
3738   operands[1] = reg0;
3739   operands[3] = reg1;
3740   operands[4] = gen_lowpart (Pmode, operands[1]);
3743 ; Patterns for 31 bit + Esa and 64 bit + Zarch.
3745 (define_insn "*setmem_long"
3746   [(clobber (match_operand:<DBL> 0 "register_operand" "=d"))
3747    (set (mem:BLK (subreg:P (match_operand:<DBL> 3 "register_operand" "0") 0))
3748         (unspec:BLK [(match_operand:P 2 "setmem_operand" "Y")
3749                      (subreg:P (match_dup 3) <modesize>)]
3750                      UNSPEC_REPLICATE_BYTE))
3751    (use (match_operand:<DBL> 1 "register_operand" "d"))
3752    (clobber (reg:CC CC_REGNUM))]
3753   "TARGET_64BIT || !TARGET_ZARCH"
3754   "mvcle\t%0,%1,%Y2\;jo\t.-4"
3755   [(set_attr "length" "8")
3756    (set_attr "type" "vs")])
3758 (define_insn "*setmem_long_and"
3759   [(clobber (match_operand:<DBL> 0 "register_operand" "=d"))
3760    (set (mem:BLK (subreg:P (match_operand:<DBL> 3 "register_operand" "0") 0))
3761         (unspec:BLK [(zero_extend:P (match_operand:QI 2 "setmem_operand" "Y"))
3762                     (subreg:P (match_dup 3) <modesize>)]
3763                     UNSPEC_REPLICATE_BYTE))
3764    (use (match_operand:<DBL> 1 "register_operand" "d"))
3765    (clobber (reg:CC CC_REGNUM))]
3766   "(TARGET_64BIT || !TARGET_ZARCH)"
3767   "mvcle\t%0,%1,%Y2\;jo\t.-4"
3768   [(set_attr "length" "8")
3769    (set_attr "type" "vs")])
3771 ; Variants for 31 bit + Zarch, necessary because of the odd in-register offsets
3772 ; of the SImode subregs.
3774 (define_insn "*setmem_long_31z"
3775   [(clobber (match_operand:TI 0 "register_operand" "=d"))
3776    (set (mem:BLK (subreg:SI (match_operand:TI 3 "register_operand" "0") 4))
3777         (unspec:BLK [(match_operand:SI 2 "setmem_operand" "Y")
3778                      (subreg:SI (match_dup 3) 12)] UNSPEC_REPLICATE_BYTE))
3779    (use (match_operand:TI 1 "register_operand" "d"))
3780    (clobber (reg:CC CC_REGNUM))]
3781   "!TARGET_64BIT && TARGET_ZARCH"
3782   "mvcle\t%0,%1,%Y2\;jo\t.-4"
3783   [(set_attr "length" "8")
3784    (set_attr "type" "vs")])
3786 (define_insn "*setmem_long_and_31z"
3787   [(clobber (match_operand:TI 0 "register_operand" "=d"))
3788    (set (mem:BLK (subreg:SI (match_operand:TI 3 "register_operand" "0") 4))
3789         (unspec:BLK [(zero_extend:SI (match_operand:QI 2 "setmem_operand" "Y"))
3790                     (subreg:SI (match_dup 3) 12)] UNSPEC_REPLICATE_BYTE))
3791    (use (match_operand:TI 1 "register_operand" "d"))
3792    (clobber (reg:CC CC_REGNUM))]
3793   "(!TARGET_64BIT && TARGET_ZARCH)"
3794   "mvcle\t%0,%1,%Y2\;jo\t.-4"
3795   [(set_attr "length" "8")
3796    (set_attr "type" "vs")])
3799 ; cmpmemM instruction pattern(s).
3802 (define_expand "cmpmemsi"
3803   [(set (match_operand:SI 0 "register_operand" "")
3804         (compare:SI (match_operand:BLK 1 "memory_operand" "")
3805                     (match_operand:BLK 2 "memory_operand" "") ) )
3806    (use (match_operand:SI 3 "general_operand" ""))
3807    (use (match_operand:SI 4 "" ""))]
3808   ""
3810   if (s390_expand_cmpmem (operands[0], operands[1],
3811                           operands[2], operands[3]))
3812     DONE;
3813   else
3814     FAIL;
3817 ; Compare a block that is up to 256 bytes in length.
3818 ; The block length is taken as (operands[2] % 256) + 1.
3820 (define_expand "cmpmem_short"
3821   [(parallel
3822     [(set (reg:CCU CC_REGNUM)
3823           (compare:CCU (match_operand:BLK 0 "memory_operand" "")
3824                        (match_operand:BLK 1 "memory_operand" "")))
3825      (use (match_operand 2 "nonmemory_operand" ""))
3826      (use (const:BLK (unspec:BLK [(const_int 0)] UNSPEC_INSN)))
3827      (clobber (match_dup 3))])]
3828   ""
3829   "operands[3] = gen_rtx_SCRATCH (Pmode);")
3831 (define_insn "*cmpmem_short"
3832   [(set (reg:CCU CC_REGNUM)
3833         (compare:CCU (match_operand:BLK 0 "memory_operand" "Q,Q,Q,Q")
3834                      (match_operand:BLK 1 "memory_operand" "Q,Q,Q,Q")))
3835    (use (match_operand 2 "nonmemory_operand" "n,a,a,a"))
3836    (use (match_operand 3 "immediate_operand" "X,R,X,X"))
3837    (clobber (match_scratch:P 4 "=X,X,X,&a"))]
3838   "(GET_MODE (operands[2]) == Pmode || GET_MODE (operands[2]) == VOIDmode)"
3839   "#"
3840   [(set_attr "type" "cs")
3841    (set_attr "cpu_facility" "*,*,z10,cpu_zarch")])
3843 (define_split
3844   [(set (reg:CCU CC_REGNUM)
3845         (compare:CCU (match_operand:BLK 0 "memory_operand" "")
3846                      (match_operand:BLK 1 "memory_operand" "")))
3847    (use (match_operand 2 "const_int_operand" ""))
3848    (use (match_operand 3 "immediate_operand" ""))
3849    (clobber (scratch))]
3850   "reload_completed"
3851   [(parallel
3852     [(set (reg:CCU CC_REGNUM) (compare:CCU (match_dup 0) (match_dup 1)))
3853      (use (match_dup 2))])]
3854   "operands[2] = GEN_INT ((INTVAL (operands[2]) & 0xff) + 1);")
3856 (define_split
3857   [(set (reg:CCU CC_REGNUM)
3858         (compare:CCU (match_operand:BLK 0 "memory_operand" "")
3859                      (match_operand:BLK 1 "memory_operand" "")))
3860    (use (match_operand 2 "register_operand" ""))
3861    (use (match_operand 3 "memory_operand" ""))
3862    (clobber (scratch))]
3863   "reload_completed"
3864   [(parallel
3865     [(unspec [(match_dup 2) (match_dup 3)
3866               (const_int 0)] UNSPEC_EXECUTE)
3867      (set (reg:CCU CC_REGNUM) (compare:CCU (match_dup 0) (match_dup 1)))
3868      (use (const_int 1))])]
3869   "")
3871 (define_split
3872   [(set (reg:CCU CC_REGNUM)
3873         (compare:CCU (match_operand:BLK 0 "memory_operand" "")
3874                      (match_operand:BLK 1 "memory_operand" "")))
3875    (use (match_operand 2 "register_operand" ""))
3876    (use (const:BLK (unspec:BLK [(const_int 0)] UNSPEC_INSN)))
3877    (clobber (scratch))]
3878   "TARGET_Z10 && reload_completed"
3879   [(parallel
3880     [(unspec [(match_dup 2) (const_int 0)
3881               (label_ref (match_dup 4))] UNSPEC_EXECUTE)
3882      (set (reg:CCU CC_REGNUM) (compare:CCU (match_dup 0) (match_dup 1)))
3883      (use (const_int 1))])]
3884   "operands[4] = gen_label_rtx ();")
3886 (define_split
3887   [(set (reg:CCU CC_REGNUM)
3888         (compare:CCU (match_operand:BLK 0 "memory_operand" "")
3889                      (match_operand:BLK 1 "memory_operand" "")))
3890    (use (match_operand 2 "register_operand" ""))
3891    (use (const:BLK (unspec:BLK [(const_int 0)] UNSPEC_INSN)))
3892    (clobber (match_operand 3 "register_operand" ""))]
3893   "reload_completed"
3894   [(set (match_dup 3) (label_ref (match_dup 4)))
3895    (parallel
3896     [(unspec [(match_dup 2) (mem:BLK (match_dup 3))
3897               (label_ref (match_dup 4))] UNSPEC_EXECUTE)
3898      (set (reg:CCU CC_REGNUM) (compare:CCU (match_dup 0) (match_dup 1)))
3899      (use (const_int 1))])]
3900   "operands[4] = gen_label_rtx ();")
3902 ; Compare a block of arbitrary length.
3904 (define_expand "cmpmem_long"
3905   [(parallel
3906     [(clobber (match_dup 2))
3907      (clobber (match_dup 3))
3908      (set (reg:CCU CC_REGNUM)
3909           (compare:CCU (match_operand:BLK 0 "memory_operand" "")
3910                        (match_operand:BLK 1 "memory_operand" "")))
3911      (use (match_operand 2 "general_operand" ""))
3912      (use (match_dup 3))])]
3913   ""
3915   machine_mode sreg_mode = TARGET_ZARCH ? DImode : SImode;
3916   machine_mode dreg_mode = TARGET_ZARCH ? TImode : DImode;
3917   rtx reg0 = gen_reg_rtx (dreg_mode);
3918   rtx reg1 = gen_reg_rtx (dreg_mode);
3919   rtx addr0 = gen_lowpart (Pmode, gen_highpart (sreg_mode, reg0));
3920   rtx addr1 = gen_lowpart (Pmode, gen_highpart (sreg_mode, reg1));
3921   rtx len0 = gen_lowpart (Pmode, reg0);
3922   rtx len1 = gen_lowpart (Pmode, reg1);
3924   emit_clobber (reg0);
3925   emit_move_insn (addr0, force_operand (XEXP (operands[0], 0), NULL_RTX));
3926   emit_move_insn (len0, operands[2]);
3928   emit_clobber (reg1);
3929   emit_move_insn (addr1, force_operand (XEXP (operands[1], 0), NULL_RTX));
3930   emit_move_insn (len1, operands[2]);
3932   operands[0] = replace_equiv_address_nv (operands[0], addr0);
3933   operands[1] = replace_equiv_address_nv (operands[1], addr1);
3934   operands[2] = reg0;
3935   operands[3] = reg1;
3938 (define_insn "*cmpmem_long"
3939   [(clobber (match_operand:<DBL> 0 "register_operand" "=d"))
3940    (clobber (match_operand:<DBL> 1 "register_operand" "=d"))
3941    (set (reg:CCU CC_REGNUM)
3942         (compare:CCU (mem:BLK (subreg:P (match_operand:<DBL> 2 "register_operand" "0") 0))
3943                      (mem:BLK (subreg:P (match_operand:<DBL> 3 "register_operand" "1") 0))))
3944    (use (match_dup 2))
3945    (use (match_dup 3))]
3946   "TARGET_64BIT || !TARGET_ZARCH"
3947   "clcle\t%0,%1,0\;jo\t.-4"
3948   [(set_attr "length" "8")
3949    (set_attr "type" "vs")])
3951 (define_insn "*cmpmem_long_31z"
3952   [(clobber (match_operand:TI 0 "register_operand" "=d"))
3953    (clobber (match_operand:TI 1 "register_operand" "=d"))
3954    (set (reg:CCU CC_REGNUM)
3955         (compare:CCU (mem:BLK (subreg:SI (match_operand:TI 2 "register_operand" "0") 4))
3956                      (mem:BLK (subreg:SI (match_operand:TI 3 "register_operand" "1") 4))))
3957    (use (match_dup 2))
3958    (use (match_dup 3))]
3959   "!TARGET_64BIT && TARGET_ZARCH"
3960   "clcle\t%0,%1,0\;jo\t.-4"
3961   [(set_attr "op_type" "NN")
3962    (set_attr "type"    "vs")
3963    (set_attr "length"  "8")])
3965 ; Convert CCUmode condition code to integer.
3966 ; Result is zero if EQ, positive if LTU, negative if GTU.
3968 (define_insn_and_split "cmpint"
3969   [(set (match_operand:SI 0 "register_operand" "=d")
3970         (unspec:SI [(match_operand:CCU 1 "register_operand" "0")]
3971                    UNSPEC_STRCMPCC_TO_INT))
3972    (clobber (reg:CC CC_REGNUM))]
3973   ""
3974   "#"
3975   "reload_completed"
3976   [(set (match_dup 0) (ashift:SI (match_dup 0) (const_int 2)))
3977    (parallel
3978     [(set (match_dup 0) (ashiftrt:SI (match_dup 0) (const_int 30)))
3979      (clobber (reg:CC CC_REGNUM))])])
3981 (define_insn_and_split "*cmpint_cc"
3982   [(set (reg CC_REGNUM)
3983         (compare (unspec:SI [(match_operand:CCU 1 "register_operand" "0")]
3984                             UNSPEC_STRCMPCC_TO_INT)
3985                  (const_int 0)))
3986    (set (match_operand:SI 0 "register_operand" "=d")
3987         (unspec:SI [(match_dup 1)] UNSPEC_STRCMPCC_TO_INT))]
3988   "s390_match_ccmode (insn, CCSmode)"
3989   "#"
3990   "&& reload_completed"
3991   [(set (match_dup 0) (ashift:SI (match_dup 0) (const_int 2)))
3992    (parallel
3993     [(set (match_dup 2) (match_dup 3))
3994      (set (match_dup 0) (ashiftrt:SI (match_dup 0) (const_int 30)))])]
3996   rtx result = gen_rtx_ASHIFTRT (SImode, operands[0], GEN_INT (30));
3997   operands[2] = SET_DEST (XVECEXP (PATTERN (curr_insn), 0, 0));
3998   operands[3] = gen_rtx_COMPARE (GET_MODE (operands[2]), result, const0_rtx);
4001 (define_insn_and_split "*cmpint_sign"
4002   [(set (match_operand:DI 0 "register_operand" "=d")
4003         (sign_extend:DI (unspec:SI [(match_operand:CCU 1 "register_operand" "0")]
4004                                    UNSPEC_STRCMPCC_TO_INT)))
4005    (clobber (reg:CC CC_REGNUM))]
4006   "TARGET_ZARCH"
4007   "#"
4008   "&& reload_completed"
4009   [(set (match_dup 0) (ashift:DI (match_dup 0) (const_int 34)))
4010    (parallel
4011     [(set (match_dup 0) (ashiftrt:DI (match_dup 0) (const_int 62)))
4012      (clobber (reg:CC CC_REGNUM))])])
4014 (define_insn_and_split "*cmpint_sign_cc"
4015   [(set (reg CC_REGNUM)
4016         (compare (ashiftrt:DI (ashift:DI (subreg:DI
4017                    (unspec:SI [(match_operand:CCU 1 "register_operand" "0")]
4018                               UNSPEC_STRCMPCC_TO_INT) 0)
4019                    (const_int 32)) (const_int 32))
4020                  (const_int 0)))
4021    (set (match_operand:DI 0 "register_operand" "=d")
4022         (sign_extend:DI (unspec:SI [(match_dup 1)] UNSPEC_STRCMPCC_TO_INT)))]
4023   "s390_match_ccmode (insn, CCSmode) && TARGET_ZARCH"
4024   "#"
4025   "&& reload_completed"
4026   [(set (match_dup 0) (ashift:DI (match_dup 0) (const_int 34)))
4027    (parallel
4028     [(set (match_dup 2) (match_dup 3))
4029      (set (match_dup 0) (ashiftrt:DI (match_dup 0) (const_int 62)))])]
4031   rtx result = gen_rtx_ASHIFTRT (DImode, operands[0], GEN_INT (62));
4032   operands[2] = SET_DEST (XVECEXP (PATTERN (curr_insn), 0, 0));
4033   operands[3] = gen_rtx_COMPARE (GET_MODE (operands[2]), result, const0_rtx);
4038 ;;- Conversion instructions.
4041 (define_insn "*sethighpartsi"
4042   [(set (match_operand:SI 0 "register_operand" "=d,d")
4043         (unspec:SI [(match_operand:BLK 1 "s_operand" "Q,S")
4044                     (match_operand 2 "const_int_operand" "n,n")] UNSPEC_ICM))
4045    (clobber (reg:CC CC_REGNUM))]
4046   ""
4047   "@
4048    icm\t%0,%2,%S1
4049    icmy\t%0,%2,%S1"
4050   [(set_attr "op_type" "RS,RSY")
4051    (set_attr "cpu_facility" "*,longdisp")
4052    (set_attr "z10prop" "z10_super_E1,z10_super_E1")])
4054 (define_insn "*sethighpartdi_64"
4055   [(set (match_operand:DI 0 "register_operand" "=d")
4056         (unspec:DI [(match_operand:BLK 1 "s_operand" "S")
4057                     (match_operand 2 "const_int_operand" "n")] UNSPEC_ICM))
4058    (clobber (reg:CC CC_REGNUM))]
4059   "TARGET_ZARCH"
4060   "icmh\t%0,%2,%S1"
4061   [(set_attr "op_type" "RSY")
4062    (set_attr "z10prop" "z10_super")])
4064 (define_insn "*sethighpartdi_31"
4065   [(set (match_operand:DI 0 "register_operand" "=d,d")
4066         (unspec:DI [(match_operand:BLK 1 "s_operand" "Q,S")
4067                     (match_operand 2 "const_int_operand" "n,n")] UNSPEC_ICM))
4068    (clobber (reg:CC CC_REGNUM))]
4069   "!TARGET_ZARCH"
4070   "@
4071    icm\t%0,%2,%S1
4072    icmy\t%0,%2,%S1"
4073   [(set_attr "op_type" "RS,RSY")
4074    (set_attr "cpu_facility" "*,longdisp")
4075    (set_attr "z10prop" "z10_super_E1,z10_super_E1")])
4078 ; extv instruction patterns
4081 ; FIXME: This expander needs to be converted from DI to GPR as well
4082 ; after resolving some issues with it.
4084 (define_expand "extzv"
4085   [(parallel
4086     [(set (match_operand:DI 0 "register_operand" "=d")
4087         (zero_extract:DI
4088          (match_operand:DI 1 "register_operand" "d")
4089          (match_operand 2 "const_int_operand" "")   ; size
4090          (match_operand 3 "const_int_operand" ""))) ; start
4091      (clobber (reg:CC CC_REGNUM))])]
4092   "TARGET_Z10"
4094   if (! EXTRACT_ARGS_IN_RANGE (INTVAL (operands[2]), INTVAL (operands[3]), 64))
4095     FAIL;
4096   /* Starting with zEC12 there is risbgn not clobbering CC.  */
4097   if (TARGET_ZEC12)
4098     {
4099       emit_move_insn (operands[0],
4100                     gen_rtx_ZERO_EXTRACT (DImode,
4101                                           operands[1],
4102                                           operands[2],
4103                                           operands[3]));
4104       DONE;
4105     }
4108 (define_insn "*extzv<mode><clobbercc_or_nocc>"
4109   [(set (match_operand:GPR 0 "register_operand" "=d")
4110       (zero_extract:GPR
4111         (match_operand:GPR 1 "register_operand" "d")
4112         (match_operand 2 "const_int_operand" "")   ; size
4113         (match_operand 3 "const_int_operand" ""))) ; start
4114   ]
4115   "<z10_or_zEC12_cond>
4116    && EXTRACT_ARGS_IN_RANGE (INTVAL (operands[2]), INTVAL (operands[3]),
4117                              GET_MODE_BITSIZE (<MODE>mode))"
4118   "<risbg_n>\t%0,%1,64-%2,128+63,<bitoff_plus>%3+%2" ; dst, src, start, end, shift
4119   [(set_attr "op_type" "RIE")
4120    (set_attr "z10prop" "z10_super_E1")])
4122 ; 64 bit: (a & -16) | ((b >> 8) & 15)
4123 (define_insn "*extzvdi<clobbercc_or_nocc>_lshiftrt"
4124   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+d")
4125                          (match_operand 1 "const_int_operand" "")  ; size
4126                          (match_operand 2 "const_int_operand" "")) ; start
4127         (lshiftrt:DI (match_operand:DI 3 "register_operand" "d")
4128                      (match_operand:DI 4 "nonzero_shift_count_operand" "")))]
4129   "<z10_or_zEC12_cond>
4130    && EXTRACT_ARGS_IN_RANGE (INTVAL (operands[1]), INTVAL (operands[2]), 64)
4131    && 64 - UINTVAL (operands[4]) >= UINTVAL (operands[1])"
4132   "<risbg_n>\t%0,%3,%2,%2+%1-1,128-%2-%1-%4"
4133   [(set_attr "op_type" "RIE")
4134    (set_attr "z10prop" "z10_super_E1")])
4136 ; (a & -16) | ((b >> 8) & 15)
4137 (define_insn "*<risbg_n>_ior_and_sr_ze<mode>"
4138   [(set (match_operand:DSI 0 "register_operand" "=d")
4139         (ior:DSI (and:DSI
4140                   (match_operand:DSI 1 "register_operand" "0")
4141                   (match_operand:DSI 2 "const_int_operand" ""))
4142                  (zero_extract:DSI
4143                   (match_operand:DSI 3 "register_operand" "d")
4144                   (match_operand 4 "const_int_operand" "")  ; size
4145                   (match_operand 5 "const_int_operand" "")) ; start
4146                   ))]
4147   "<z10_or_zEC12_cond>
4148    && EXTRACT_ARGS_IN_RANGE (INTVAL (operands[4]), INTVAL (operands[5]), <DSI:bitsize>)
4149    && UINTVAL (operands[2]) == (HOST_WIDE_INT_M1U << UINTVAL (operands[4]))"
4150   "<risbg_n>\t%0,%3,64-%4,63,(64-<DSI:bitsize>)+%4+%5"
4151   [(set_attr "op_type" "RIE")
4152    (set_attr "z10prop" "z10_super_E1")])
4154 ; ((int)foo >> 10) & 1;
4155 (define_insn "*extract1bitdi<clobbercc_or_nocc>"
4156   [(set (match_operand:DI 0 "register_operand" "=d")
4157         (ne:DI (zero_extract:DI
4158                 (match_operand:DI 1 "register_operand" "d")
4159                 (const_int 1)  ; size
4160                 (match_operand 2 "const_int_operand" "")) ; start
4161                (const_int 0)))]
4162   "<z10_or_zEC12_cond>
4163    && EXTRACT_ARGS_IN_RANGE (1, INTVAL (operands[2]), 64)"
4164   "<risbg_n>\t%0,%1,64-1,128+63,%2+1" ; dst, src, start, end, shift
4165   [(set_attr "op_type" "RIE")
4166    (set_attr "z10prop" "z10_super_E1")])
4168 (define_insn "*<risbg_n>_and_subregdi_rotr"
4169   [(set (match_operand:DI 0 "register_operand" "=d")
4170         (and:DI (subreg:DI
4171                  (rotate:SINT (match_operand:SINT 1 "register_operand" "d")
4172                              (match_operand:SINT 2 "const_int_operand" "")) 0)
4173                 (match_operand:DI 3 "contiguous_bitmask_operand" "")))]
4174   "<z10_or_zEC12_cond>
4175    && (UINTVAL (operands[3])
4176        < (HOST_WIDE_INT_1U << (UINTVAL (operands[2]) & 0x3f)))"
4177   "<risbg_n>\t%0,%1,%s3,128+%e3,<bitoff_plus>%2" ; dst, src, start, end, shift
4178   [(set_attr "op_type" "RIE")
4179    (set_attr "z10prop" "z10_super_E1")])
4181 (define_insn "*<risbg_n>_and_subregdi_rotl"
4182   [(set (match_operand:DI 0 "register_operand" "=d")
4183         (and:DI (subreg:DI
4184                  (rotate:SINT (match_operand:SINT 1 "register_operand" "d")
4185                              (match_operand:SINT 2 "const_int_operand" "")) 0)
4186                 (match_operand:DI 3 "contiguous_bitmask_operand" "")))]
4187   "<z10_or_zEC12_cond>
4188    && !(UINTVAL (operands[3])
4189         & ((HOST_WIDE_INT_1U << (UINTVAL (operands[2]) & 0x3f)) - 1))"
4190   "<risbg_n>\t%0,%1,%s3,128+%e3,%2" ; dst, src, start, end, shift
4191   [(set_attr "op_type" "RIE")
4192    (set_attr "z10prop" "z10_super_E1")])
4194 (define_insn "*<risbg_n>_di_and_rot"
4195   [(set (match_operand:DI 0 "register_operand" "=d")
4196         (and:DI (rotate:DI (match_operand:DI 1 "register_operand" "d")
4197                             (match_operand:DI 2 "const_int_operand" ""))
4198                 (match_operand:DI 3 "contiguous_bitmask_operand" "")))]
4199   "<z10_or_zEC12_cond>"
4200   "<risbg_n>\t%0,%1,%s3,128+%e3,%2" ; dst, src, start, end, shift
4201   [(set_attr "op_type" "RIE")
4202    (set_attr "z10prop" "z10_super_E1")])
4204 (define_insn_and_split "*pre_z10_extzv<mode>"
4205   [(set (match_operand:GPR 0 "register_operand" "=d")
4206         (zero_extract:GPR (match_operand:QI 1 "s_operand" "S")
4207                           (match_operand 2 "nonzero_shift_count_operand" "")
4208                           (const_int 0)))
4209    (clobber (reg:CC CC_REGNUM))]
4210   "!TARGET_Z10"
4211   "#"
4212   "&& reload_completed"
4213   [(parallel
4214     [(set (match_dup 0) (unspec:GPR [(match_dup 1) (match_dup 3)] UNSPEC_ICM))
4215      (clobber (reg:CC CC_REGNUM))])
4216    (set (match_dup 0) (lshiftrt:GPR (match_dup 0) (match_dup 2)))]
4218   int bitsize = INTVAL (operands[2]);
4219   int size = (bitsize - 1) / BITS_PER_UNIT + 1; /* round up */
4220   unsigned HOST_WIDE_INT mask
4221     = ((HOST_WIDE_INT_1U << size) - 1) << (GET_MODE_SIZE (SImode) - size);
4223   operands[1] = adjust_address (operands[1], BLKmode, 0);
4224   set_mem_size (operands[1], size);
4225   operands[2] = GEN_INT (<GPR:bitsize> - bitsize);
4226   operands[3] = GEN_INT (mask);
4229 (define_insn_and_split "*pre_z10_extv<mode>"
4230   [(set (match_operand:GPR 0 "register_operand" "=d")
4231         (sign_extract:GPR (match_operand:QI 1 "s_operand" "S")
4232                           (match_operand 2 "nonzero_shift_count_operand" "")
4233                           (const_int 0)))
4234    (clobber (reg:CC CC_REGNUM))]
4235   ""
4236   "#"
4237   "&& reload_completed"
4238   [(parallel
4239     [(set (match_dup 0) (unspec:GPR [(match_dup 1) (match_dup 3)] UNSPEC_ICM))
4240      (clobber (reg:CC CC_REGNUM))])
4241    (parallel
4242     [(set (match_dup 0) (ashiftrt:GPR (match_dup 0) (match_dup 2)))
4243      (clobber (reg:CC CC_REGNUM))])]
4245   int bitsize = INTVAL (operands[2]);
4246   int size = (bitsize - 1) / BITS_PER_UNIT + 1; /* round up */
4247   unsigned HOST_WIDE_INT mask
4248     = ((HOST_WIDE_INT_1U << size) - 1) << (GET_MODE_SIZE (SImode) - size);
4250   operands[1] = adjust_address (operands[1], BLKmode, 0);
4251   set_mem_size (operands[1], size);
4252   operands[2] = GEN_INT (<GPR:bitsize> - bitsize);
4253   operands[3] = GEN_INT (mask);
4257 ; insv instruction patterns
4260 (define_expand "insv"
4261   [(set (zero_extract (match_operand 0 "nonimmediate_operand" "")
4262                       (match_operand 1 "const_int_operand" "")
4263                       (match_operand 2 "const_int_operand" ""))
4264         (match_operand 3 "general_operand" ""))]
4265   ""
4267   if (s390_expand_insv (operands[0], operands[1], operands[2], operands[3]))
4268     DONE;
4269   FAIL;
4273 ; The normal RTL expansion will never generate a zero_extract where
4274 ; the location operand isn't word mode.  However, we do this in the
4275 ; back-end when generating atomic operations. See s390_two_part_insv.
4276 (define_insn "*insv<mode><clobbercc_or_nocc>"
4277   [(set (zero_extract:GPR (match_operand:GPR 0 "nonimmediate_operand" "+d")
4278                           (match_operand 1 "const_int_operand"    "I")  ; size
4279                           (match_operand 2 "const_int_operand"    "I")) ; pos
4280         (match_operand:GPR 3 "nonimmediate_operand" "d"))]
4281   "<z10_or_zEC12_cond>
4282    && EXTRACT_ARGS_IN_RANGE (INTVAL (operands[1]), INTVAL (operands[2]),
4283                              GET_MODE_BITSIZE (<MODE>mode))
4284    && (INTVAL (operands[1]) + INTVAL (operands[2])) <= <bitsize>"
4285   "<risbg_n>\t%0,%3,<bitoff_plus>%2,<bitoff_plus>%2+%1-1,<bitsize>-%2-%1"
4286   [(set_attr "op_type" "RIE")
4287    (set_attr "z10prop" "z10_super_E1")])
4289 ; and op1 with a mask being 1 for the selected bits and 0 for the rest
4290 ; and op3=op0 with a mask being 0 for the selected bits and 1 for the rest
4291 (define_insn "*insv<mode><clobbercc_or_nocc>_noshift"
4292   [(set (match_operand:GPR 0 "nonimmediate_operand" "=d,d")
4293         (ior:GPR (and:GPR (match_operand:GPR 1 "nonimmediate_operand" "d,0")
4294                           (match_operand:GPR 2 "contiguous_bitmask_operand" ""))
4295                  (and:GPR (match_operand:GPR 3 "nonimmediate_operand" "0,d")
4296                           (match_operand:GPR 4 "const_int_operand" ""))))]
4297   "<z10_or_zEC12_cond> && INTVAL (operands[2]) == ~INTVAL (operands[4])"
4298   "@
4299    <risbg_n>\t%0,%1,%<bfstart>2,%<bfend>2,0
4300    <risbg_n>\t%0,%3,%<bfstart>4,%<bfend>4,0"
4301   [(set_attr "op_type" "RIE")
4302    (set_attr "z10prop" "z10_super_E1")])
4304 (define_insn "*insv_z10_noshift_cc"
4305   [(set (reg CC_REGNUM)
4306        (compare
4307         (ior:DI
4308          (and:DI (match_operand:DI 1 "nonimmediate_operand" "d,0")
4309                   (match_operand:DI 2 "contiguous_bitmask_operand" ""))
4310          (and:DI (match_operand:DI 3 "nonimmediate_operand" "0,d")
4311                   (match_operand:DI 4 "const_int_operand" "")))
4312         (const_int 0)))
4313    (set (match_operand:DI 0 "nonimmediate_operand" "=d,d")
4314         (ior:DI (and:DI (match_dup 1) (match_dup 2))
4315                  (and:DI (match_dup 3) (match_dup 4))))]
4316   "TARGET_Z10 && s390_match_ccmode (insn, CCSmode)
4317    && INTVAL (operands[2]) == ~INTVAL (operands[4])"
4318   "@
4319    risbg\t%0,%1,%s2,%e2,0
4320    risbg\t%0,%3,%s4,%e4,0"
4321   [(set_attr "op_type" "RIE")
4322    (set_attr "z10prop" "z10_super_E1")])
4324 (define_insn "*insv_z10_noshift_cconly"
4325   [(set
4326     (reg CC_REGNUM)
4327     (compare
4328      (ior:DI
4329       (and:DI (match_operand:DI 1 "nonimmediate_operand" "d,0")
4330                (match_operand:DI 2 "contiguous_bitmask_operand" ""))
4331       (and:DI (match_operand:DI 3 "nonimmediate_operand" "0,d")
4332                (match_operand:DI 4 "const_int_operand" "")))
4333      (const_int 0)))
4334   (clobber (match_scratch:DI 0 "=d,d"))]
4335   "TARGET_Z10 && s390_match_ccmode (insn, CCSmode)
4336    && INTVAL (operands[2]) == ~INTVAL (operands[4])"
4337   "@
4338    risbg\t%0,%1,%s2,%e2,0
4339    risbg\t%0,%3,%s4,%e4,0"
4340   [(set_attr "op_type" "RIE")
4341    (set_attr "z10prop" "z10_super_E1")])
4343 ; Implement appending Y on the left of S bits of X
4344 ; x = (y << s) | (x & ((1 << s) - 1))
4345 (define_insn "*insv<mode><clobbercc_or_nocc>_appendbitsleft"
4346   [(set (match_operand:GPR 0 "nonimmediate_operand" "=d")
4347         (ior:GPR (and:GPR (match_operand:GPR 1 "nonimmediate_operand" "0")
4348                           (match_operand:GPR 2 "immediate_operand" ""))
4349                  (ashift:GPR (match_operand:GPR 3 "nonimmediate_operand" "d")
4350                              (match_operand:GPR 4 "nonzero_shift_count_operand" ""))))]
4351   "<z10_or_zEC12_cond>
4352    && UINTVAL (operands[2]) == (HOST_WIDE_INT_1U << UINTVAL (operands[4])) - 1"
4353   "<risbg_n>\t%0,%3,<bitoff>,64-%4-1,%4"
4354   [(set_attr "op_type" "RIE")
4355    (set_attr "z10prop" "z10_super_E1")])
4357 ; a = ((i32)a & -16777216) | (((ui32)b) >> 8)
4358 (define_insn "*<risbg_n>_<mode>_ior_and_lshiftrt"
4359   [(set (match_operand:GPR 0 "register_operand" "=d")
4360         (ior:GPR (and:GPR
4361                   (match_operand:GPR 1 "register_operand" "0")
4362                   (match_operand:GPR 2 "const_int_operand" ""))
4363                  (lshiftrt:GPR
4364                   (match_operand:GPR 3 "register_operand" "d")
4365                   (match_operand:GPR 4 "nonzero_shift_count_operand" ""))))]
4366   "<z10_or_zEC12_cond> && UINTVAL (operands[2])
4367    == (HOST_WIDE_INT_M1U
4368        << (GET_MODE_BITSIZE (<MODE>mode) - UINTVAL (operands[4])))"
4369   "<risbg_n>\t%0,%3,<bitoff_plus>%4,63,64-%4"
4370   [(set_attr "op_type" "RIE")
4371    (set_attr "z10prop" "z10_super_E1")])
4373 ; (ui32)(((ui64)x) >> 48) | ((i32)y & -65536);
4374 (define_insn "*<risbg_n>_sidi_ior_and_lshiftrt"
4375   [(set (match_operand:SI 0 "register_operand" "=d")
4376         (ior:SI (and:SI
4377                  (match_operand:SI 1 "register_operand" "0")
4378                  (match_operand:SI 2 "const_int_operand" ""))
4379                 (subreg:SI
4380                  (lshiftrt:DI
4381                   (match_operand:DI 3 "register_operand" "d")
4382                   (match_operand:DI 4 "nonzero_shift_count_operand" "")) 4)))]
4383   "<z10_or_zEC12_cond>
4384    && UINTVAL (operands[2]) == ~(HOST_WIDE_INT_M1U >> UINTVAL (operands[4]))"
4385   "<risbg_n>\t%0,%3,%4,63,64-%4"
4386   [(set_attr "op_type" "RIE")
4387    (set_attr "z10prop" "z10_super_E1")])
4389 ; (ui32)(((ui64)x) >> 12) & -4
4390 (define_insn "*trunc_sidi_and_subreg_lshrt<clobbercc_or_nocc>"
4391   [(set (match_operand:SI 0 "register_operand" "=d")
4392         (and:SI
4393          (subreg:SI (lshiftrt:DI
4394                      (match_operand:DI 1 "register_operand" "d")
4395                      (match_operand:DI 2 "nonzero_shift_count_operand" "")) 4)
4396          (match_operand:SI 3 "contiguous_bitmask_nowrap_operand" "")))]
4397   "<z10_or_zEC12_cond>"
4398   "<risbg_n>\t%0,%1,%t3,128+%f3,64-%2"
4399   [(set_attr "op_type" "RIE")
4400    (set_attr "z10prop" "z10_super_E1")])
4402 ; (ui32)(((ui64)x) >> 12) & -4
4403 (define_insn "*trunc_sidi_and_subreg_ze<clobbercc_or_nocc>"
4404   [(set (match_operand:SI 0 "register_operand" "=d")
4405         (and:SI
4406          (subreg:SI (zero_extract:DI
4407                      (match_operand:DI 1 "register_operand" "d")
4408                      (const_int 32)
4409                      (match_operand:SI 2 "nonzero_shift_count_operand" "")) 4)
4410          (match_operand:SI 3 "contiguous_bitmask_nowrap_operand" "")))]
4411   "<z10_or_zEC12_cond>"
4412   "<risbg_n>\t%0,%1,%t3,128+%f3,32+%2"
4413   [(set_attr "op_type" "RIE")
4414    (set_attr "z10prop" "z10_super_E1")])
4416 ; z = (x << c) | (y >> d) with (x << c) and (y >> d) not overlapping after shifting
4417 ;  -> z = y >> d; z = (x << c) | (z & ((1 << c) - 1))
4418 ;  -> z = y >> d; z = risbg;
4420 (define_split
4421   [(set (match_operand:GPR 0 "nonimmediate_operand" "")
4422         (ior:GPR (lshiftrt:GPR (match_operand:GPR 1 "nonimmediate_operand" "")
4423                                (match_operand:GPR 2 "nonzero_shift_count_operand" ""))
4424                  (ashift:GPR (match_operand:GPR 3 "nonimmediate_operand" "")
4425                              (match_operand:GPR 4 "nonzero_shift_count_operand" ""))))]
4426   "TARGET_ZEC12 && UINTVAL (operands[2]) + UINTVAL (operands[4]) >= <bitsize>"
4427   [(set (match_dup 6)
4428         (lshiftrt:GPR (match_dup 1) (match_dup 2)))
4429    (set (match_dup 0)
4430         (ior:GPR (and:GPR (match_dup 6) (match_dup 5))
4431                  (ashift:GPR (match_dup 3) (match_dup 4))))]
4433   operands[5] = GEN_INT ((HOST_WIDE_INT_1U << UINTVAL (operands[4])) - 1);
4434   if (reg_overlap_mentioned_p (operands[0], operands[3]))
4435     {
4436       if (!can_create_pseudo_p ())
4437         FAIL;
4438       operands[6] = gen_reg_rtx (<MODE>mode);
4439     }
4440   else
4441     operands[6] = operands[0];
4444 (define_split
4445   [(parallel
4446     [(set (match_operand:GPR 0 "nonimmediate_operand" "")
4447           (ior:GPR (lshiftrt:GPR (match_operand:GPR 1 "nonimmediate_operand" "")
4448                                  (match_operand:GPR 2 "nonzero_shift_count_operand" ""))
4449                    (ashift:GPR (match_operand:GPR 3 "nonimmediate_operand" "")
4450                                (match_operand:GPR 4 "nonzero_shift_count_operand" ""))))
4451      (clobber (reg:CC CC_REGNUM))])]
4452   "TARGET_Z10 && !TARGET_ZEC12 && UINTVAL (operands[2]) + UINTVAL (operands[4]) >= <bitsize>"
4453   [(set (match_dup 6)
4454         (lshiftrt:GPR (match_dup 1) (match_dup 2)))
4455    (parallel
4456     [(set (match_dup 0)
4457           (ior:GPR (and:GPR (match_dup 6) (match_dup 5))
4458                    (ashift:GPR (match_dup 3) (match_dup 4))))
4459      (clobber (reg:CC CC_REGNUM))])]
4461   operands[5] = GEN_INT ((HOST_WIDE_INT_1U << UINTVAL (operands[4])) - 1);
4462   if (reg_overlap_mentioned_p (operands[0], operands[3]))
4463     {
4464       if (!can_create_pseudo_p ())
4465         FAIL;
4466       operands[6] = gen_reg_rtx (<MODE>mode);
4467     }
4468   else
4469     operands[6] = operands[0];
4472 ; rosbg, rxsbg
4473 (define_insn "*r<noxa>sbg_<mode>_noshift"
4474   [(set (match_operand:GPR 0 "nonimmediate_operand" "=d")
4475         (IXOR:GPR
4476           (and:GPR (match_operand:GPR 1 "nonimmediate_operand" "d")
4477                    (match_operand:GPR 2 "contiguous_bitmask_operand" ""))
4478           (match_operand:GPR 3 "nonimmediate_operand" "0")))
4479    (clobber (reg:CC CC_REGNUM))]
4480   "TARGET_Z10"
4481   "r<noxa>sbg\t%0,%1,%<bfstart>2,%<bfend>2,0"
4482   [(set_attr "op_type" "RIE")])
4484 ; rosbg, rxsbg
4485 (define_insn "*r<noxa>sbg_di_rotl"
4486   [(set (match_operand:DI 0 "nonimmediate_operand" "=d")
4487         (IXOR:DI
4488           (and:DI
4489             (rotate:DI
4490               (match_operand:DI 1 "nonimmediate_operand" "d")
4491               (match_operand:DI 3 "const_int_operand" ""))
4492             (match_operand:DI 2 "contiguous_bitmask_operand" ""))
4493           (match_operand:DI 4 "nonimmediate_operand" "0")))
4494    (clobber (reg:CC CC_REGNUM))]
4495   "TARGET_Z10"
4496   "r<noxa>sbg\t%0,%1,%s2,%e2,%b3"
4497   [(set_attr "op_type" "RIE")])
4499 ; rosbg, rxsbg
4500 (define_insn "*r<noxa>sbg_<mode>_srl_bitmask"
4501   [(set (match_operand:GPR 0 "nonimmediate_operand" "=d")
4502         (IXOR:GPR
4503           (and:GPR
4504             (lshiftrt:GPR
4505               (match_operand:GPR 1 "nonimmediate_operand" "d")
4506               (match_operand:GPR 3 "nonzero_shift_count_operand" ""))
4507             (match_operand:GPR 2 "contiguous_bitmask_nowrap_operand" ""))
4508           (match_operand:GPR 4 "nonimmediate_operand" "0")))
4509    (clobber (reg:CC CC_REGNUM))]
4510   "TARGET_Z10
4511    && s390_extzv_shift_ok (<bitsize>, 64 - INTVAL (operands[3]),
4512                            INTVAL (operands[2]))"
4513   {
4514     operands[3] = GEN_INT (64 - INTVAL (operands[3]));
4515     return "r<noxa>sbg\t%0,%1,%<bfstart>2,%<bfend>2,%3";
4516   }
4517   [(set_attr "op_type" "RIE")])
4519 ; rosbg, rxsbg
4520 (define_insn "*r<noxa>sbg_<mode>_sll_bitmask"
4521   [(set (match_operand:GPR 0 "nonimmediate_operand" "=d")
4522         (IXOR:GPR
4523           (and:GPR
4524             (ashift:GPR
4525               (match_operand:GPR 1 "nonimmediate_operand" "d")
4526               (match_operand:GPR 3 "nonzero_shift_count_operand" ""))
4527             (match_operand:GPR 2 "contiguous_bitmask_nowrap_operand" ""))
4528           (match_operand:GPR 4 "nonimmediate_operand" "0")))
4529    (clobber (reg:CC CC_REGNUM))]
4530   "TARGET_Z10
4531    && s390_extzv_shift_ok (<bitsize>, INTVAL (operands[3]),
4532                            INTVAL (operands[2]))"
4533   "r<noxa>sbg\t%0,%1,%<bfstart>2,%<bfend>2,%3"
4534   [(set_attr "op_type" "RIE")])
4536 ;; unsigned {int,long} a, b
4537 ;; a = a | (b << const_int)
4538 ;; a = a ^ (b << const_int)
4539 ; rosbg, rxsbg
4540 (define_insn "*r<noxa>sbg_<mode>_sll"
4541   [(set (match_operand:GPR 0 "nonimmediate_operand" "=d")
4542         (IXOR:GPR
4543           (ashift:GPR
4544             (match_operand:GPR 1 "nonimmediate_operand" "d")
4545             (match_operand:GPR 2 "nonzero_shift_count_operand" ""))
4546           (match_operand:GPR 3 "nonimmediate_operand" "0")))
4547    (clobber (reg:CC CC_REGNUM))]
4548   "TARGET_Z10"
4549   {
4550     operands[3] = GEN_INT (63 - INTVAL (operands[2]));
4551     return "r<noxa>sbg\t%0,%1,<bitoff>,%3,%2";
4552   }
4553   [(set_attr "op_type" "RIE")])
4555 ;; unsigned {int,long} a, b
4556 ;; a = a | (b >> const_int)
4557 ;; a = a ^ (b >> const_int)
4558 ; rosbg, rxsbg
4559 (define_insn "*r<noxa>sbg_<mode>_srl"
4560   [(set (match_operand:GPR 0 "nonimmediate_operand" "=d")
4561         (IXOR:GPR
4562           (lshiftrt:GPR
4563             (match_operand:GPR 1 "nonimmediate_operand" "d")
4564             (match_operand:GPR 2 "nonzero_shift_count_operand" ""))
4565           (match_operand:GPR 3 "nonimmediate_operand" "0")))
4566    (clobber (reg:CC CC_REGNUM))]
4567   "TARGET_Z10"
4568   {
4569     operands[3] = GEN_INT (64 - INTVAL (operands[2]));
4570     operands[2] = GEN_INT (<bitoff_plus> INTVAL (operands[2]));
4571     return "r<noxa>sbg\t%0,%1,%2,63,%3";
4572   }
4573   [(set_attr "op_type" "RIE")])
4575 ; rosbg, rxsbg
4576 (define_insn "*r<noxa>sbg_sidi_srl"
4577   [(set (match_operand:SI 0 "nonimmediate_operand" "=d")
4578         (IXOR:SI
4579           (subreg:SI
4580             (zero_extract:DI
4581               (match_operand:DI 1 "nonimmediate_operand" "d")
4582               (const_int 32)
4583               (match_operand:DI 2 "immediate_operand" ""))
4584             4)
4585           (match_operand:SI 3 "nonimmediate_operand" "0")))
4586    (clobber (reg:CC CC_REGNUM))]
4587   "TARGET_Z10"
4588   {
4589     operands[2] = GEN_INT (32 + INTVAL (operands[2]));
4590     return "r<noxa>sbg\t%0,%1,32,63,%2";
4591   }
4592   [(set_attr "op_type" "RIE")])
4594 ;; These two are generated by combine for s.bf &= val.
4595 ;; ??? For bitfields smaller than 32-bits, we wind up with SImode
4596 ;; shifts and ands, which results in some truly awful patterns
4597 ;; including subregs of operations.  Rather unnecessisarily, IMO.
4598 ;; Instead of
4600 ;; (set (zero_extract:DI (reg/v:DI 50 [ s ])
4601 ;;        (const_int 24 [0x18])
4602 ;;        (const_int 0 [0]))
4603 ;;    (subreg:DI (and:SI (subreg:SI (lshiftrt:DI (reg/v:DI 50 [ s ])
4604 ;;                    (const_int 40 [0x28])) 4)
4605 ;;            (reg:SI 4 %r4 [ y+4 ])) 0))
4607 ;; we should instead generate
4609 ;; (set (zero_extract:DI (reg/v:DI 50 [ s ])
4610 ;;        (const_int 24 [0x18])
4611 ;;        (const_int 0 [0]))
4612 ;;    (and:DI (lshiftrt:DI (reg/v:DI 50 [ s ])
4613 ;;                    (const_int 40 [0x28]))
4614 ;;            (subreg:DI (reg:SI 4 %r4 [ y+4 ]) 0)))
4616 ;; by noticing that we can push down the outer paradoxical subreg
4617 ;; into the operation.
4619 (define_insn "*insv_rnsbg_noshift"
4620   [(set (zero_extract:DI
4621           (match_operand:DI 0 "nonimmediate_operand" "+d")
4622           (match_operand 1 "const_int_operand" "")
4623           (match_operand 2 "const_int_operand" ""))
4624         (and:DI
4625           (match_dup 0)
4626           (match_operand:DI 3 "nonimmediate_operand" "d")))
4627    (clobber (reg:CC CC_REGNUM))]
4628   "TARGET_Z10
4629    && EXTRACT_ARGS_IN_RANGE (INTVAL (operands[1]), INTVAL (operands[2]), 64)
4630    && INTVAL (operands[1]) + INTVAL (operands[2]) == 64"
4631   "rnsbg\t%0,%3,%2,63,0"
4632   [(set_attr "op_type" "RIE")])
4634 (define_insn "*insv_rnsbg_srl"
4635   [(set (zero_extract:DI
4636           (match_operand:DI 0 "nonimmediate_operand" "+d")
4637           (match_operand 1 "const_int_operand" "")
4638           (match_operand 2 "const_int_operand" ""))
4639         (and:DI
4640           (lshiftrt:DI
4641             (match_dup 0)
4642             (match_operand 3 "const_int_operand" ""))
4643           (match_operand:DI 4 "nonimmediate_operand" "d")))
4644    (clobber (reg:CC CC_REGNUM))]
4645   "TARGET_Z10
4646    && EXTRACT_ARGS_IN_RANGE (INTVAL (operands[1]), INTVAL (operands[2]), 64)
4647    && INTVAL (operands[3]) == 64 - INTVAL (operands[1]) - INTVAL (operands[2])"
4648   "rnsbg\t%0,%4,%2,%2+%1-1,%3"
4649   [(set_attr "op_type" "RIE")])
4651 (define_insn "*insv<mode>_mem_reg"
4652   [(set (zero_extract:W (match_operand:QI 0 "memory_operand" "+Q,S")
4653                         (match_operand 1 "const_int_operand" "n,n")
4654                         (const_int 0))
4655         (match_operand:W 2 "register_operand" "d,d"))]
4656   "EXTRACT_ARGS_IN_RANGE (INTVAL (operands[1]), 0, 64)
4657    && INTVAL (operands[1]) > 0
4658    && INTVAL (operands[1]) <= GET_MODE_BITSIZE (SImode)
4659    && INTVAL (operands[1]) % BITS_PER_UNIT == 0"
4661     int size = INTVAL (operands[1]) / BITS_PER_UNIT;
4663     operands[1] = GEN_INT ((HOST_WIDE_INT_1U << size) - 1);
4664     return (which_alternative == 0) ? "stcm\t%2,%1,%S0"
4665                                     : "stcmy\t%2,%1,%S0";
4667   [(set_attr "op_type" "RS,RSY")
4668    (set_attr "cpu_facility" "*,longdisp")
4669    (set_attr "z10prop" "z10_super,z10_super")])
4671 (define_insn "*insvdi_mem_reghigh"
4672   [(set (zero_extract:DI (match_operand:QI 0 "memory_operand" "+S")
4673                          (match_operand 1 "const_int_operand" "n")
4674                          (const_int 0))
4675         (lshiftrt:DI (match_operand:DI 2 "register_operand" "d")
4676                      (const_int 32)))]
4677   "TARGET_ZARCH
4678    && EXTRACT_ARGS_IN_RANGE (INTVAL (operands[1]), 0, 64)
4679    && INTVAL (operands[1]) > 0
4680    && INTVAL (operands[1]) <= GET_MODE_BITSIZE (SImode)
4681    && INTVAL (operands[1]) % BITS_PER_UNIT == 0"
4683     int size = INTVAL (operands[1]) / BITS_PER_UNIT;
4685     operands[1] = GEN_INT ((HOST_WIDE_INT_1U << size) - 1);
4686     return "stcmh\t%2,%1,%S0";
4688 [(set_attr "op_type" "RSY")
4689  (set_attr "z10prop" "z10_super")])
4691 (define_insn "*insvdi_reg_imm"
4692   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+d")
4693                          (const_int 16)
4694                          (match_operand 1 "const_int_operand" "n"))
4695         (match_operand:DI 2 "const_int_operand" "n"))]
4696   "TARGET_ZARCH
4697    && EXTRACT_ARGS_IN_RANGE (16, INTVAL (operands[1]), 64)
4698    && INTVAL (operands[1]) >= 0
4699    && INTVAL (operands[1]) < BITS_PER_WORD
4700    && INTVAL (operands[1]) % 16 == 0"
4702   switch (BITS_PER_WORD - INTVAL (operands[1]))
4703     {
4704       case 64: return "iihh\t%0,%x2"; break;
4705       case 48: return "iihl\t%0,%x2"; break;
4706       case 32: return "iilh\t%0,%x2"; break;
4707       case 16: return "iill\t%0,%x2"; break;
4708       default: gcc_unreachable();
4709     }
4711   [(set_attr "op_type" "RI")
4712    (set_attr "z10prop" "z10_super_E1")])
4714 ; Update the left-most 32 bit of a DI.
4715 (define_insn "*insv_h_di_reg_extimm"
4716   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+d")
4717                          (const_int 32)
4718                          (const_int 0))
4719         (match_operand:DI 1 "const_int_operand" "n"))]
4720   "TARGET_EXTIMM"
4721   "iihf\t%0,%o1"
4722   [(set_attr "op_type" "RIL")
4723    (set_attr "z10prop" "z10_fwd_E1")])
4725 ; Update the right-most 32 bit of a DI.
4726 (define_insn "*insv_l_di_reg_extimm"
4727   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+d")
4728                          (const_int 32)
4729                          (const_int 32))
4730         (match_operand:DI 1 "const_int_operand" "n"))]
4731   "TARGET_EXTIMM"
4732   "iilf\t%0,%o1"
4733   [(set_attr "op_type" "RIL")
4734    (set_attr "z10prop" "z10_fwd_A1")])
4737 ; extendsidi2 instruction pattern(s).
4740 (define_expand "extendsidi2"
4741   [(set (match_operand:DI 0 "register_operand" "")
4742         (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "")))]
4743   ""
4745   if (!TARGET_ZARCH)
4746     {
4747       emit_clobber (operands[0]);
4748       emit_move_insn (gen_highpart (SImode, operands[0]), operands[1]);
4749       emit_move_insn (gen_lowpart (SImode, operands[0]), const0_rtx);
4750       emit_insn (gen_ashrdi3 (operands[0], operands[0], GEN_INT (32)));
4751       DONE;
4752     }
4755 (define_insn "*extendsidi2"
4756   [(set (match_operand:DI 0 "register_operand" "=d,d,d")
4757         (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "d,T,b")))]
4758   "TARGET_ZARCH"
4759   "@
4760    lgfr\t%0,%1
4761    lgf\t%0,%1
4762    lgfrl\t%0,%1"
4763   [(set_attr "op_type"      "RRE,RXY,RIL")
4764    (set_attr "type"         "*,*,larl")
4765    (set_attr "cpu_facility" "*,*,z10")
4766    (set_attr "z10prop" "z10_super_E1,z10_super_E1,z10_super_E1")
4767    (set_attr "relative_long" "*,*,yes")])
4770 ; extend(hi|qi)(si|di)2 instruction pattern(s).
4773 (define_expand "extend<HQI:mode><DSI:mode>2"
4774   [(set (match_operand:DSI 0 "register_operand" "")
4775         (sign_extend:DSI (match_operand:HQI 1 "nonimmediate_operand" "")))]
4776   ""
4778   if (<DSI:MODE>mode == DImode && !TARGET_ZARCH)
4779     {
4780       rtx tmp = gen_reg_rtx (SImode);
4781       emit_insn (gen_extend<HQI:mode>si2 (tmp, operands[1]));
4782       emit_insn (gen_extendsidi2 (operands[0], tmp));
4783       DONE;
4784     }
4785   else if (!TARGET_EXTIMM)
4786     {
4787       rtx bitcount = GEN_INT (<DSI:bitsize> - <HQI:bitsize>);
4789       operands[1] = gen_lowpart (<DSI:MODE>mode, operands[1]);
4790       emit_insn (gen_ashl<DSI:mode>3 (operands[0], operands[1], bitcount));
4791       emit_insn (gen_ashr<DSI:mode>3 (operands[0], operands[0], bitcount));
4792       DONE;
4793     }
4797 ; extendhidi2 instruction pattern(s).
4800 (define_insn "*extendhidi2_extimm"
4801   [(set (match_operand:DI 0 "register_operand" "=d,d,d")
4802         (sign_extend:DI (match_operand:HI 1 "general_operand" "d,T,b")))]
4803   "TARGET_ZARCH && TARGET_EXTIMM"
4804   "@
4805    lghr\t%0,%1
4806    lgh\t%0,%1
4807    lghrl\t%0,%1"
4808   [(set_attr "op_type"      "RRE,RXY,RIL")
4809    (set_attr "type"         "*,*,larl")
4810    (set_attr "cpu_facility" "extimm,extimm,z10")
4811    (set_attr "z10prop" "z10_super_E1,z10_super_E1,z10_super_E1")
4812    (set_attr "relative_long" "*,*,yes")])
4814 (define_insn "*extendhidi2"
4815   [(set (match_operand:DI 0 "register_operand" "=d")
4816         (sign_extend:DI (match_operand:HI 1 "memory_operand" "T")))]
4817   "TARGET_ZARCH"
4818   "lgh\t%0,%1"
4819   [(set_attr "op_type" "RXY")
4820    (set_attr "z10prop" "z10_super_E1")])
4823 ; extendhisi2 instruction pattern(s).
4826 (define_insn "*extendhisi2_extimm"
4827   [(set (match_operand:SI 0 "register_operand" "=d,d,d,d")
4828         (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" " d,R,T,b")))]
4829   "TARGET_EXTIMM"
4830   "@
4831    lhr\t%0,%1
4832    lh\t%0,%1
4833    lhy\t%0,%1
4834    lhrl\t%0,%1"
4835   [(set_attr "op_type"      "RRE,RX,RXY,RIL")
4836    (set_attr "type"         "*,*,*,larl")
4837    (set_attr "cpu_facility" "extimm,extimm,extimm,z10")
4838    (set_attr "z10prop" "z10_super_E1,z10_super_E1,z10_super_E1,z10_super_E1")
4839    (set_attr "relative_long" "*,*,*,yes")])
4841 (define_insn "*extendhisi2"
4842   [(set (match_operand:SI 0 "register_operand" "=d,d")
4843         (sign_extend:SI (match_operand:HI 1 "memory_operand" "R,T")))]
4844   "!TARGET_EXTIMM"
4845   "@
4846    lh\t%0,%1
4847    lhy\t%0,%1"
4848   [(set_attr "op_type" "RX,RXY")
4849    (set_attr "cpu_facility" "*,longdisp")
4850    (set_attr "z10prop" "z10_super_E1,z10_super_E1")])
4853 ; extendqi(si|di)2 instruction pattern(s).
4856 ; lbr, lgbr, lb, lgb
4857 (define_insn "*extendqi<mode>2_extimm"
4858   [(set (match_operand:GPR 0 "register_operand" "=d,d")
4859         (sign_extend:GPR (match_operand:QI 1 "nonimmediate_operand" "d,T")))]
4860   "TARGET_EXTIMM"
4861   "@
4862    l<g>br\t%0,%1
4863    l<g>b\t%0,%1"
4864   [(set_attr "op_type" "RRE,RXY")
4865    (set_attr "z10prop" "z10_super_E1,z10_super_E1")])
4867 ; lb, lgb
4868 (define_insn "*extendqi<mode>2"
4869   [(set (match_operand:GPR 0 "register_operand" "=d")
4870         (sign_extend:GPR (match_operand:QI 1 "memory_operand" "T")))]
4871   "!TARGET_EXTIMM && TARGET_LONG_DISPLACEMENT"
4872   "l<g>b\t%0,%1"
4873   [(set_attr "op_type" "RXY")
4874    (set_attr "z10prop" "z10_super_E1")])
4876 (define_insn_and_split "*extendqi<mode>2_short_displ"
4877   [(set (match_operand:GPR 0 "register_operand" "=d")
4878         (sign_extend:GPR (match_operand:QI 1 "s_operand" "Q")))
4879    (clobber (reg:CC CC_REGNUM))]
4880   "!TARGET_EXTIMM && !TARGET_LONG_DISPLACEMENT"
4881   "#"
4882   "&& reload_completed"
4883   [(parallel
4884     [(set (match_dup 0) (unspec:GPR [(match_dup 1) (const_int 8)] UNSPEC_ICM))
4885      (clobber (reg:CC CC_REGNUM))])
4886    (parallel
4887     [(set (match_dup 0) (ashiftrt:GPR (match_dup 0) (match_dup 2)))
4888      (clobber (reg:CC CC_REGNUM))])]
4890   operands[1] = adjust_address (operands[1], BLKmode, 0);
4891   set_mem_size (operands[1], GET_MODE_SIZE (QImode));
4892   operands[2] = GEN_INT (<GPR:bitsize> - BITS_PER_UNIT);
4896 ; zero_extendsidi2 instruction pattern(s).
4899 (define_expand "zero_extendsidi2"
4900   [(set (match_operand:DI 0 "register_operand" "")
4901         (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "")))]
4902   ""
4904   if (!TARGET_ZARCH)
4905     {
4906       emit_clobber (operands[0]);
4907       emit_move_insn (gen_lowpart (SImode, operands[0]), operands[1]);
4908       emit_move_insn (gen_highpart (SImode, operands[0]), const0_rtx);
4909       DONE;
4910     }
4913 (define_insn "*zero_extendsidi2"
4914   [(set (match_operand:DI 0 "register_operand" "=d,d,d")
4915         (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "d,T,b")))]
4916   "TARGET_ZARCH"
4917   "@
4918    llgfr\t%0,%1
4919    llgf\t%0,%1
4920    llgfrl\t%0,%1"
4921   [(set_attr "op_type"      "RRE,RXY,RIL")
4922    (set_attr "type"         "*,*,larl")
4923    (set_attr "cpu_facility" "*,*,z10")
4924    (set_attr "z10prop" "z10_fwd_E1,z10_fwd_A3,z10_fwd_A3")
4925    (set_attr "relative_long" "*,*,yes")])
4928 ; LLGT-type instructions (zero-extend from 31 bit to 64 bit).
4931 (define_insn "*llgt_sidi"
4932   [(set (match_operand:DI 0 "register_operand" "=d")
4933         (and:DI (subreg:DI (match_operand:SI 1 "memory_operand" "T") 0)
4934                 (const_int 2147483647)))]
4935   "TARGET_ZARCH"
4936   "llgt\t%0,%1"
4937   [(set_attr "op_type"  "RXE")
4938    (set_attr "z10prop" "z10_super_E1")])
4940 (define_insn_and_split "*llgt_sidi_split"
4941   [(set (match_operand:DI 0 "register_operand" "=d")
4942         (and:DI (subreg:DI (match_operand:SI 1 "memory_operand" "T") 0)
4943                 (const_int 2147483647)))
4944    (clobber (reg:CC CC_REGNUM))]
4945   "TARGET_ZARCH"
4946   "#"
4947   "&& reload_completed"
4948   [(set (match_dup 0)
4949         (and:DI (subreg:DI (match_dup 1) 0)
4950                 (const_int 2147483647)))]
4951   "")
4953 (define_insn "*llgt_sisi"
4954   [(set (match_operand:SI 0 "register_operand" "=d,d")
4955         (and:SI (match_operand:SI 1 "nonimmediate_operand" "d,T")
4956                 (const_int 2147483647)))]
4957   "TARGET_ZARCH"
4958   "@
4959    llgtr\t%0,%1
4960    llgt\t%0,%1"
4961   [(set_attr "op_type"  "RRE,RXE")
4962    (set_attr "z10prop" "z10_super_E1,z10_super_E1")])
4964 (define_insn "*llgt_didi"
4965   [(set (match_operand:DI 0 "register_operand" "=d,d")
4966         (and:DI (match_operand:DI 1 "nonimmediate_operand" "d,o")
4967                 (const_int 2147483647)))]
4968   "TARGET_ZARCH"
4969   "@
4970    llgtr\t%0,%1
4971    llgt\t%0,%N1"
4972   [(set_attr "op_type"  "RRE,RXE")
4973    (set_attr "z10prop" "z10_super_E1,z10_super_E1")])
4975 (define_split
4976   [(set (match_operand:DSI 0 "register_operand" "")
4977         (and:DSI (match_operand:DSI 1 "nonimmediate_operand" "")
4978                  (const_int 2147483647)))
4979    (clobber (reg:CC CC_REGNUM))]
4980   "TARGET_ZARCH && reload_completed"
4981   [(set (match_dup 0)
4982         (and:DSI (match_dup 1)
4983                  (const_int 2147483647)))]
4984   "")
4987 ; zero_extend(hi|qi)(si|di)2 instruction pattern(s).
4990 (define_expand "zero_extend<mode>di2"
4991   [(set (match_operand:DI 0 "register_operand" "")
4992         (zero_extend:DI (match_operand:HQI 1 "nonimmediate_operand" "")))]
4993   ""
4995   if (!TARGET_ZARCH)
4996     {
4997       rtx tmp = gen_reg_rtx (SImode);
4998       emit_insn (gen_zero_extend<mode>si2 (tmp, operands[1]));
4999       emit_insn (gen_zero_extendsidi2 (operands[0], tmp));
5000       DONE;
5001     }
5002   else if (!TARGET_EXTIMM)
5003     {
5004       rtx bitcount = GEN_INT (64 - <HQI:bitsize>);
5005       operands[1] = gen_lowpart (DImode, operands[1]);
5006       emit_insn (gen_ashldi3 (operands[0], operands[1], bitcount));
5007       emit_insn (gen_lshrdi3 (operands[0], operands[0], bitcount));
5008       DONE;
5009     }
5012 (define_expand "zero_extend<mode>si2"
5013   [(set (match_operand:SI 0 "register_operand" "")
5014         (zero_extend:SI (match_operand:HQI 1 "nonimmediate_operand" "")))]
5015   ""
5017   if (!TARGET_EXTIMM)
5018     {
5019       operands[1] = gen_lowpart (SImode, operands[1]);
5020       emit_insn (gen_andsi3 (operands[0], operands[1],
5021                              GEN_INT ((1 << <HQI:bitsize>) - 1)));
5022       DONE;
5023     }
5026 ; llhrl, llghrl
5027 (define_insn "*zero_extendhi<mode>2_z10"
5028   [(set (match_operand:GPR 0 "register_operand" "=d,d,d")
5029         (zero_extend:GPR (match_operand:HI 1 "nonimmediate_operand" "d,T,b")))]
5030   "TARGET_Z10"
5031   "@
5032    ll<g>hr\t%0,%1
5033    ll<g>h\t%0,%1
5034    ll<g>hrl\t%0,%1"
5035   [(set_attr "op_type"      "RXY,RRE,RIL")
5036    (set_attr "type"         "*,*,larl")
5037    (set_attr "cpu_facility" "*,*,z10")
5038    (set_attr "z10prop" "z10_super_E1,z10_fwd_A3,z10_fwd_A3")
5039    (set_attr "relative_long" "*,*,yes")])
5041 ; llhr, llcr, llghr, llgcr, llh, llc, llgh, llgc
5042 (define_insn "*zero_extend<HQI:mode><GPR:mode>2_extimm"
5043   [(set (match_operand:GPR 0 "register_operand" "=d,d")
5044         (zero_extend:GPR (match_operand:HQI 1 "nonimmediate_operand" "d,T")))]
5045   "TARGET_EXTIMM"
5046   "@
5047    ll<g><hc>r\t%0,%1
5048    ll<g><hc>\t%0,%1"
5049   [(set_attr "op_type" "RRE,RXY")
5050    (set_attr "z10prop" "z10_super_E1,z10_fwd_A3")])
5052 ; llgh, llgc
5053 (define_insn "*zero_extend<HQI:mode><GPR:mode>2"
5054   [(set (match_operand:GPR 0 "register_operand" "=d")
5055         (zero_extend:GPR (match_operand:HQI 1 "memory_operand" "T")))]
5056   "TARGET_ZARCH && !TARGET_EXTIMM"
5057   "llg<hc>\t%0,%1"
5058   [(set_attr "op_type" "RXY")
5059    (set_attr "z10prop" "z10_fwd_A3")])
5061 (define_insn_and_split "*zero_extendhisi2_31"
5062   [(set (match_operand:SI 0 "register_operand" "=&d")
5063         (zero_extend:SI (match_operand:HI 1 "s_operand" "S")))
5064    (clobber (reg:CC CC_REGNUM))]
5065   "!TARGET_ZARCH"
5066   "#"
5067   "&& reload_completed"
5068   [(set (match_dup 0) (const_int 0))
5069    (parallel
5070     [(set (strict_low_part (match_dup 2)) (match_dup 1))
5071      (clobber (reg:CC CC_REGNUM))])]
5072   "operands[2] = gen_lowpart (HImode, operands[0]);")
5074 (define_insn_and_split "*zero_extendqisi2_31"
5075   [(set (match_operand:SI 0 "register_operand" "=&d")
5076         (zero_extend:SI (match_operand:QI 1 "memory_operand" "T")))]
5077   "!TARGET_ZARCH"
5078   "#"
5079   "&& reload_completed"
5080   [(set (match_dup 0) (const_int 0))
5081    (set (strict_low_part (match_dup 2)) (match_dup 1))]
5082   "operands[2] = gen_lowpart (QImode, operands[0]);")
5085 ; zero_extendqihi2 instruction pattern(s).
5088 (define_expand "zero_extendqihi2"
5089   [(set (match_operand:HI 0 "register_operand" "")
5090         (zero_extend:HI (match_operand:QI 1 "register_operand" "")))]
5091   "TARGET_ZARCH && !TARGET_EXTIMM"
5093   operands[1] = gen_lowpart (HImode, operands[1]);
5094   emit_insn (gen_andhi3 (operands[0], operands[1], GEN_INT (0xff)));
5095   DONE;
5098 (define_insn "*zero_extendqihi2_64"
5099   [(set (match_operand:HI 0 "register_operand" "=d")
5100         (zero_extend:HI (match_operand:QI 1 "memory_operand" "T")))]
5101   "TARGET_ZARCH && !TARGET_EXTIMM"
5102   "llgc\t%0,%1"
5103   [(set_attr "op_type" "RXY")
5104    (set_attr "z10prop" "z10_fwd_A3")])
5106 (define_insn_and_split "*zero_extendqihi2_31"
5107   [(set (match_operand:HI 0 "register_operand" "=&d")
5108         (zero_extend:HI (match_operand:QI 1 "memory_operand" "T")))]
5109   "!TARGET_ZARCH"
5110   "#"
5111   "&& reload_completed"
5112   [(set (match_dup 0) (const_int 0))
5113    (set (strict_low_part (match_dup 2)) (match_dup 1))]
5114   "operands[2] = gen_lowpart (QImode, operands[0]);")
5117 ; fixuns_trunc(dd|td|sf|df|tf)(si|di)2 expander
5120 ; This is the only entry point for fixuns_trunc.  It multiplexes the
5121 ; expansion to either the *_emu expanders below for pre z196 machines
5122 ; or emits the default pattern otherwise.
5123 (define_expand "fixuns_trunc<FP:mode><GPR:mode>2<FP:tf_fpr>"
5124   [(parallel
5125     [(set (match_operand:GPR 0 "register_operand" "")
5126           (unsigned_fix:GPR (match_operand:FP 1 "register_operand" "")))
5127      (unspec:GPR [(match_dup 2)] UNSPEC_ROUND)
5128      (clobber (reg:CC CC_REGNUM))])]
5129   "TARGET_HARD_FLOAT"
5131   if (!TARGET_Z196)
5132     {
5133       /* We don't provide emulation for TD|DD->SI.  */
5134       if (GET_MODE_CLASS (<FP:MODE>mode) == MODE_DECIMAL_FLOAT
5135           && <GPR:MODE>mode == SImode)
5136         FAIL;
5137       emit_insn (gen_fixuns_trunc<FP:mode><GPR:mode>2_emu (operands[0],
5138                                                                operands[1]));
5139       DONE;
5140     }
5142   if (GET_MODE_CLASS (<FP:MODE>mode) == MODE_DECIMAL_FLOAT)
5143     operands[2] = GEN_INT (DFP_RND_TOWARD_0);
5144   else
5145     operands[2] = GEN_INT (BFP_RND_TOWARD_0);
5148 ; (sf|df|tf)->unsigned (si|di)
5150 ; Emulate the unsigned conversion with the signed version for pre z196
5151 ; machines.
5152 (define_expand "fixuns_trunc<BFP:mode><GPR:mode>2_emu"
5153   [(parallel
5154     [(set (match_operand:GPR 0 "register_operand" "")
5155           (unsigned_fix:GPR (match_operand:BFP 1 "register_operand" "")))
5156      (unspec:GPR [(const_int BFP_RND_TOWARD_0)] UNSPEC_ROUND)
5157      (clobber (reg:CC CC_REGNUM))])]
5158   "!TARGET_Z196 && TARGET_HARD_FLOAT"
5160   rtx_code_label *label1 = gen_label_rtx ();
5161   rtx_code_label *label2 = gen_label_rtx ();
5162   rtx temp = gen_reg_rtx (<BFP:MODE>mode);
5163   REAL_VALUE_TYPE cmp, sub;
5165   operands[1] = force_reg (<BFP:MODE>mode, operands[1]);
5166   real_2expN (&cmp, <GPR:bitsize> - 1, <BFP:MODE>mode);
5167   real_2expN (&sub, <GPR:bitsize>, <BFP:MODE>mode);
5169   emit_cmp_and_jump_insns (operands[1],
5170                            const_double_from_real_value (cmp, <BFP:MODE>mode),
5171                            LT, NULL_RTX, VOIDmode, 0, label1);
5172   emit_insn (gen_sub<BFP:mode>3 (temp, operands[1],
5173                const_double_from_real_value (sub, <BFP:MODE>mode)));
5174   emit_insn (gen_fix_trunc<BFP:mode><GPR:mode>2_bfp (operands[0], temp,
5175                GEN_INT (BFP_RND_TOWARD_MINF)));
5176   emit_jump (label2);
5178   emit_label (label1);
5179   emit_insn (gen_fix_trunc<BFP:mode><GPR:mode>2_bfp (operands[0],
5180                                                          operands[1],
5181                                                          GEN_INT (BFP_RND_TOWARD_0)));
5182   emit_label (label2);
5183   DONE;
5186 ; dd->unsigned di
5188 ; Emulate the unsigned conversion with the signed version for pre z196
5189 ; machines.
5190 (define_expand "fixuns_truncdddi2_emu"
5191   [(parallel
5192     [(set (match_operand:DI 0 "register_operand" "")
5193           (unsigned_fix:DI (match_operand:DD 1 "register_operand" "")))
5194      (unspec:DI [(const_int DFP_RND_TOWARD_0)] UNSPEC_ROUND)
5195      (clobber (reg:CC CC_REGNUM))])]
5197   "!TARGET_Z196 && TARGET_HARD_DFP"
5199   rtx_code_label *label1 = gen_label_rtx ();
5200   rtx_code_label *label2 = gen_label_rtx ();
5201   rtx temp = gen_reg_rtx (TDmode);
5202   REAL_VALUE_TYPE cmp, sub;
5204   decimal_real_from_string (&cmp, "9223372036854775808.0");  /* 2^63 */
5205   decimal_real_from_string (&sub, "18446744073709551616.0"); /* 2^64 */
5207   /* 2^63 can't be represented as 64bit DFP number with full precision.  The
5208      solution is doing the check and the subtraction in TD mode and using a
5209      TD -> DI convert afterwards.  */
5210   emit_insn (gen_extendddtd2 (temp, operands[1]));
5211   temp = force_reg (TDmode, temp);
5212   emit_cmp_and_jump_insns (temp,
5213                            const_double_from_real_value (cmp, TDmode),
5214                            LT, NULL_RTX, VOIDmode, 0, label1);
5215   emit_insn (gen_subtd3 (temp, temp,
5216                          const_double_from_real_value (sub, TDmode)));
5217   emit_insn (gen_fix_trunctddi2_dfp (operands[0], temp,
5218                                      GEN_INT (DFP_RND_TOWARD_MINF)));
5219   emit_jump (label2);
5221   emit_label (label1);
5222   emit_insn (gen_fix_truncdddi2_dfp (operands[0], operands[1],
5223                                      GEN_INT (DFP_RND_TOWARD_0)));
5224   emit_label (label2);
5225   DONE;
5228 ; td->unsigned di
5230 ; Emulate the unsigned conversion with the signed version for pre z196
5231 ; machines.
5232 (define_expand "fixuns_trunctddi2_emu"
5233   [(parallel
5234     [(set (match_operand:DI 0 "register_operand" "")
5235           (unsigned_fix:DI (match_operand:TD 1 "register_operand" "")))
5236      (unspec:DI [(const_int DFP_RND_TOWARD_0)] UNSPEC_ROUND)
5237      (clobber (reg:CC CC_REGNUM))])]
5239   "!TARGET_Z196 && TARGET_HARD_DFP"
5241   rtx_code_label *label1 = gen_label_rtx ();
5242   rtx_code_label *label2 = gen_label_rtx ();
5243   rtx temp = gen_reg_rtx (TDmode);
5244   REAL_VALUE_TYPE cmp, sub;
5246   operands[1] = force_reg (TDmode, operands[1]);
5247   decimal_real_from_string (&cmp, "9223372036854775808.0");  /* 2^63 */
5248   decimal_real_from_string (&sub, "18446744073709551616.0"); /* 2^64 */
5250   emit_cmp_and_jump_insns (operands[1],
5251                            const_double_from_real_value (cmp, TDmode),
5252                            LT, NULL_RTX, VOIDmode, 0, label1);
5253   emit_insn (gen_subtd3 (temp, operands[1],
5254                          const_double_from_real_value (sub, TDmode)));
5255   emit_insn (gen_fix_trunctddi2_dfp (operands[0], temp,
5256                                      GEN_INT (DFP_RND_TOWARD_MINF)));
5257   emit_jump (label2);
5259   emit_label (label1);
5260   emit_insn (gen_fix_trunctddi2_dfp (operands[0], operands[1],
5261                                      GEN_INT (DFP_RND_TOWARD_0)));
5262   emit_label (label2);
5263   DONE;
5266 ; Just a dummy to make the code in the first expander a bit easier.
5267 (define_expand "fixuns_trunc<mode>si2_emu"
5268   [(parallel
5269     [(set (match_operand:SI 0 "register_operand" "")
5270           (unsigned_fix:SI (match_operand:DFP 1 "register_operand" "")))
5271      (unspec:DI [(const_int DFP_RND_TOWARD_0)] UNSPEC_ROUND)
5272      (clobber (reg:CC CC_REGNUM))])]
5274   "!TARGET_Z196 && TARGET_HARD_DFP"
5276    FAIL;
5277  })
5280 ; fixuns_trunc(tf|df|sf|td|dd)(di|si)2 instruction patterns.
5282 ; df -> unsigned di, vxe2: sf -> unsigned si
5283 ; clgdbr, clfebr, wclgdb, wclfeb
5284 (define_insn "*fixuns_trunc<mode><toint>2_z13"
5285   [(set (match_operand:<TOINT>                           0 "register_operand" "=d,v")
5286         (unsigned_fix:<TOINT> (match_operand:VX_CONV_BFP 1 "register_operand"  "f,v")))
5287    (unspec:DI [(match_operand:DI                         2 "immediate_operand" "K,K")] UNSPEC_ROUND)
5288    (clobber (reg:CC CC_REGNUM))]
5289   "TARGET_VX && TARGET_HARD_FLOAT"
5290   "@
5291    cl<gf><xde>br\t%0,%h2,%1,0
5292    wcl<gf><xde>b\t%v0,%v1,0,%h2"
5293   [(set_attr "op_type" "RRF,VRR")
5294    (set_attr "type"    "ftoi")])
5296 ; (dd|td|sf|df|tf)->unsigned (di|si)
5297 ; clfebr, clfdbr, clfxbr, clgebr, clgdbr, clgxbr
5298 ;         clfdtr, clfxtr,         clgdtr, clgxtr
5299 (define_insn "*fixuns_trunc<FP:mode><GPR:mode>2_z196"
5300   [(set (match_operand:GPR                  0 "register_operand" "=d")
5301         (unsigned_fix:GPR (match_operand:FP 1 "register_operand"  "f")))
5302    (unspec:GPR [(match_operand:GPR          2 "immediate_operand" "K")] UNSPEC_ROUND)
5303    (clobber (reg:CC CC_REGNUM))]
5304    "TARGET_Z196 && TARGET_HARD_FLOAT
5305     && (!TARGET_VX || <GPR:MODE>mode != DImode || <FP:MODE>mode != DFmode)"
5306    "cl<GPR:gf><FP:xde><FP:bt>r\t%0,%h2,%1,0"
5307    [(set_attr "op_type" "RRF")
5308     (set_attr "type"    "ftoi")])
5310 (define_expand "fix_trunc<DSF:mode><GPR:mode>2"
5311   [(set (match_operand:GPR 0 "register_operand" "")
5312         (fix:GPR (match_operand:DSF 1 "register_operand" "")))]
5313   "TARGET_HARD_FLOAT"
5315   emit_insn (gen_fix_trunc<DSF:mode><GPR:mode>2_bfp (operands[0], operands[1],
5316              GEN_INT (BFP_RND_TOWARD_0)));
5317   DONE;
5320 ; df -> signed di, vxe2: sf -> signed si
5321 ; cgdbr, cfebr, wcgdb, wcfeb
5322 (define_insn "*fix_trunc<mode><toint>2_bfp_z13"
5323   [(set (match_operand:<TOINT>                  0 "register_operand" "=d,v")
5324         (fix:<TOINT> (match_operand:VX_CONV_BFP 1 "register_operand"  "f,v")))
5325    (unspec:<TOINT> [(match_operand:<TOINT>      2 "immediate_operand" "K,K")] UNSPEC_ROUND)
5326    (clobber (reg:CC CC_REGNUM))]
5327   "TARGET_VX && TARGET_HARD_FLOAT"
5328   "@
5329    c<gf><xde>br\t%0,%h2,%1
5330    wc<gf><xde>b\t%v0,%v1,0,%h2"
5331   [(set_attr "op_type" "RRE,VRR")
5332    (set_attr "type"    "ftoi")])
5334 ; cgxbr, cgdbr, cgebr, cfxbr, cfdbr, cfebr
5335 (define_insn "*fix_trunc<BFP:mode><GPR:mode>2_bfp"
5336   [(set (match_operand:GPR          0 "register_operand" "=d")
5337         (fix:GPR (match_operand:BFP 1 "register_operand"  "f")))
5338    (unspec:GPR [(match_operand:GPR  2 "immediate_operand" "K")] UNSPEC_ROUND)
5339    (clobber (reg:CC CC_REGNUM))]
5340   "TARGET_HARD_FLOAT
5341     && (!TARGET_VX || <GPR:MODE>mode != DImode || <BFP:MODE>mode != DFmode)"
5342   "c<GPR:gf><BFP:xde>br\t%0,%h2,%1"
5343   [(set_attr "op_type" "RRE")
5344    (set_attr "type"    "ftoi")])
5346 (define_expand "fix_trunc<BFP:mode><GPR:mode>2_bfp"
5347   [(parallel
5348     [(set (match_operand:GPR          0 "register_operand" "=d")
5349           (fix:GPR (match_operand:BFP 1 "register_operand"  "f")))
5350      (unspec:GPR [(match_operand:GPR  2 "immediate_operand" "K")] UNSPEC_ROUND)
5351      (clobber (reg:CC CC_REGNUM))])]
5352   "TARGET_HARD_FLOAT")
5354 ; fix_trunc(td|dd)di2 instruction pattern(s).
5357 (define_expand "fix_trunc<mode>di2"
5358   [(set (match_operand:DI 0 "register_operand" "")
5359         (fix:DI (match_operand:DFP 1 "nonimmediate_operand" "")))]
5360   "TARGET_ZARCH && TARGET_HARD_DFP"
5362   operands[1] = force_reg (<MODE>mode, operands[1]);
5363   emit_insn (gen_fix_trunc<mode>di2_dfp (operands[0], operands[1],
5364       GEN_INT (DFP_RND_TOWARD_0)));
5365   DONE;
5368 ; cgxtr, cgdtr
5369 (define_insn "fix_trunc<DFP:mode>di2_dfp"
5370   [(set (match_operand:DI 0 "register_operand" "=d")
5371         (fix:DI (match_operand:DFP 1 "register_operand" "f")))
5372    (unspec:DI [(match_operand:DI 2 "immediate_operand" "K")] UNSPEC_ROUND)
5373    (clobber (reg:CC CC_REGNUM))]
5374   "TARGET_ZARCH && TARGET_HARD_DFP"
5375   "cg<DFP:xde>tr\t%0,%h2,%1"
5376   [(set_attr "op_type" "RRF")
5377    (set_attr "type"    "ftoidfp")])
5381 ; fix_trunctf(si|di)2 instruction pattern(s).
5384 (define_expand "fix_trunctf<mode>2_fpr"
5385   [(parallel [(set (match_operand:GPR 0 "register_operand" "")
5386                    (fix:GPR (match_operand:TF 1 "register_operand" "")))
5387               (unspec:GPR [(const_int BFP_RND_TOWARD_0)] UNSPEC_ROUND)
5388               (clobber (reg:CC CC_REGNUM))])]
5389   "TARGET_HARD_FLOAT && !TARGET_VXE"
5390   "")
5394 ; float(si|di)(tf|df|sf|td|dd)2 instruction pattern(s).
5397 ; cxgbr, cdgbr, cegbr, cxgtr, cdgtr
5398 (define_insn "floatdi<mode>2<tf_fpr>"
5399   [(set (match_operand:FP           0 "register_operand" "=f,v")
5400         (float:FP (match_operand:DI 1 "register_operand"  "d,v")))]
5401   "TARGET_ZARCH && TARGET_HARD_FLOAT"
5402   "@
5403    c<xde>g<bt>r\t%0,%1
5404    wcdgb\t%v0,%v1,0,0"
5405   [(set_attr "op_type"      "RRE,VRR")
5406    (set_attr "type"         "itof<type>" )
5407    (set_attr "cpu_facility" "*,vx")
5408    (set_attr "enabled"      "*,<DFDI>")])
5410 ; cxfbr, cdfbr, cefbr, wcefb
5411 (define_insn "floatsi<mode>2<tf_fpr>"
5412   [(set (match_operand:BFP           0 "register_operand" "=f,v")
5413         (float:BFP (match_operand:SI 1 "register_operand"  "d,v")))]
5414   "TARGET_HARD_FLOAT"
5415   "@
5416    c<xde>fbr\t%0,%1
5417    wcefb\t%v0,%v1,0,0"
5418   [(set_attr "op_type"      "RRE,VRR")
5419    (set_attr "type"         "itof<type>" )
5420    (set_attr "cpu_facility" "*,vxe2")
5421    (set_attr "enabled"      "*,<SFSI>")])
5423 ; cxftr, cdftr
5424 (define_insn "floatsi<mode>2"
5425   [(set (match_operand:DFP 0 "register_operand" "=f")
5426         (float:DFP (match_operand:SI 1 "register_operand" "d")))]
5427   "TARGET_Z196 && TARGET_HARD_FLOAT"
5428   "c<xde>ftr\t%0,0,%1,0"
5429   [(set_attr "op_type" "RRE")
5430    (set_attr "type"    "itof<type>")])
5433 ; floatuns(si|di)(tf|df|sf|td|dd)2 instruction pattern(s).
5436 (define_insn "*floatuns<toint><mode>2_z13"
5437   [(set (match_operand:VX_CONV_BFP                         0 "register_operand" "=f,v")
5438         (unsigned_float:VX_CONV_BFP (match_operand:<TOINT> 1 "register_operand"  "d,v")))]
5439   "TARGET_VX && TARGET_HARD_FLOAT"
5440   "@
5441    c<xde>l<gf>br\t%0,0,%1,0
5442    wc<xde>l<gf>b\t%v0,%v1,0,0"
5443   [(set_attr "op_type" "RRE,VRR")
5444    (set_attr "type"    "itofdf")])
5446 ; cxlgbr, cdlgbr, celgbr, cxlgtr, cdlgtr
5447 ; cxlfbr, cdlfbr, celfbr, cxlftr, cdlftr
5448 (define_insn "*floatuns<GPR:mode><FP:mode>2"
5449   [(set (match_operand:FP                     0 "register_operand" "=f")
5450         (unsigned_float:FP (match_operand:GPR 1 "register_operand"  "d")))]
5451   "TARGET_Z196 && TARGET_HARD_FLOAT
5452    && (!TARGET_VX || <FP:MODE>mode != DFmode || <GPR:MODE>mode != DImode)"
5453   "c<FP:xde>l<GPR:gf><FP:bt>r\t%0,0,%1,0"
5454   [(set_attr "op_type" "RRE")
5455    (set_attr "type"    "itof<FP:type>")])
5457 (define_expand "floatuns<GPR:mode><FP:mode>2<tf_fpr>"
5458   [(set (match_operand:FP                     0 "register_operand" "")
5459         (unsigned_float:FP (match_operand:GPR 1 "register_operand" "")))]
5460   "TARGET_Z196 && TARGET_HARD_FLOAT")
5463 ; truncdfsf2 instruction pattern(s).
5466 (define_insn "truncdfsf2"
5467   [(set (match_operand:SF                    0 "register_operand" "=f,v")
5468         (float_truncate:SF (match_operand:DF 1 "register_operand"  "f,v")))]
5469   "TARGET_HARD_FLOAT"
5470   "@
5471    ledbr\t%0,%1
5472    wledb\t%v0,%v1,0,0" ; IEEE inexact exception not suppressed
5473                        ; According to BFP rounding mode
5474   [(set_attr "op_type"      "RRE,VRR")
5475    (set_attr "type"         "ftruncdf")
5476    (set_attr "cpu_facility" "*,vx")])
5479 ; trunctf(df|sf)2 instruction pattern(s).
5482 ; ldxbr, lexbr
5483 (define_insn "trunctf<mode>2_fpr"
5484   [(set (match_operand:DSF 0 "register_operand" "=f")
5485         (float_truncate:DSF (match_operand:TF 1 "register_operand" "f")))
5486    (clobber (match_scratch:TF 2 "=f"))]
5487   "TARGET_HARD_FLOAT"
5488   "l<xde>xbr\t%2,%1\;l<xde>r\t%0,%2"
5489   [(set_attr "length" "6")
5490    (set_attr "type"   "ftrunctf")])
5493 ; trunctddd2 and truncddsd2 instruction pattern(s).
5497 (define_expand "trunctddd2"
5498   [(parallel
5499     [(set (match_operand:DD 0 "register_operand" "")
5500           (float_truncate:DD (match_operand:TD 1 "register_operand" "")))
5501      (unspec:DI [(const_int DFP_RND_CURRENT)] UNSPEC_ROUND)
5502      (clobber (scratch:TD))])]
5503   "TARGET_HARD_DFP")
5505 (define_insn "*trunctddd2"
5506   [(set (match_operand:DD 0 "register_operand" "=f")
5507         (float_truncate:DD (match_operand:TD 1 "register_operand" "f")))
5508    (unspec:DI [(match_operand:DI 2 "const_mask_operand" "I")] UNSPEC_ROUND)
5509    (clobber (match_scratch:TD 3 "=f"))]
5510   "TARGET_HARD_DFP"
5511   "ldxtr\t%3,%2,%1,0\;ldr\t%0,%3"
5512   [(set_attr "length"  "6")
5513    (set_attr "type"    "ftruncdd")])
5515 (define_insn "truncddsd2"
5516   [(set (match_operand:SD 0 "register_operand" "=f")
5517         (float_truncate:SD (match_operand:DD 1 "register_operand" "f")))]
5518   "TARGET_HARD_DFP"
5519   "ledtr\t%0,0,%1,0"
5520   [(set_attr "op_type" "RRF")
5521    (set_attr "type"    "ftruncsd")])
5523 (define_expand "trunctdsd2"
5524   [(parallel
5525     [(set (match_dup 2)
5526           (float_truncate:DD (match_operand:TD 1 "register_operand" "")))
5527      (unspec:DI [(const_int DFP_RND_PREP_FOR_SHORT_PREC)] UNSPEC_ROUND)
5528      (clobber (match_scratch:TD 3 ""))])
5529    (set (match_operand:SD 0 "register_operand" "")
5530         (float_truncate:SD (match_dup 2)))]
5531   "TARGET_HARD_DFP"
5533   operands[2] = gen_reg_rtx (DDmode);
5537 ; extend(sf|df)(df|tf)2 instruction pattern(s).
5540 ; wflls
5541 (define_insn "*extendsfdf2_z13"
5542   [(set (match_operand:DF                  0 "register_operand"     "=f,f,v")
5543         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand"  "f,R,v")))]
5544   "TARGET_VX && TARGET_HARD_FLOAT"
5545   "@
5546    ldebr\t%0,%1
5547    ldeb\t%0,%1
5548    wldeb\t%v0,%v1"
5549   [(set_attr "op_type" "RRE,RXE,VRR")
5550    (set_attr "type"    "fsimpdf, floaddf,fsimpdf")])
5552 ; ldebr, ldeb, lxdbr, lxdb, lxebr, lxeb
5553 (define_insn "*extend<DSF:mode><BFP:mode>2"
5554   [(set (match_operand:BFP                   0 "register_operand"     "=f,f")
5555         (float_extend:BFP (match_operand:DSF 1 "nonimmediate_operand"  "f,R")))]
5556   "TARGET_HARD_FLOAT
5557    && GET_MODE_SIZE (<BFP:MODE>mode) > GET_MODE_SIZE (<DSF:MODE>mode)
5558    && (!TARGET_VX || <BFP:MODE>mode != DFmode || <DSF:MODE>mode != SFmode)"
5559   "@
5560    l<BFP:xde><DSF:xde>br\t%0,%1
5561    l<BFP:xde><DSF:xde>b\t%0,%1"
5562   [(set_attr "op_type" "RRE,RXE")
5563    (set_attr "type"    "fsimp<BFP:type>, fload<BFP:type>")])
5565 (define_expand "extend<DSF:mode><BFP:mode>2<BFP:tf_fpr>"
5566   [(set (match_operand:BFP                   0 "register_operand"     "")
5567         (float_extend:BFP (match_operand:DSF 1 "nonimmediate_operand" "")))]
5568   "TARGET_HARD_FLOAT
5569    && GET_MODE_SIZE (<BFP:MODE>mode) > GET_MODE_SIZE (<DSF:MODE>mode)")
5572 ; extendddtd2 and extendsddd2 instruction pattern(s).
5575 (define_insn "extendddtd2"
5576   [(set (match_operand:TD 0 "register_operand" "=f")
5577         (float_extend:TD (match_operand:DD 1 "register_operand" "f")))]
5578   "TARGET_HARD_DFP"
5579   "lxdtr\t%0,%1,0"
5580   [(set_attr "op_type" "RRF")
5581    (set_attr "type"    "fsimptf")])
5583 (define_insn "extendsddd2"
5584   [(set (match_operand:DD 0 "register_operand" "=f")
5585         (float_extend:DD (match_operand:SD 1 "register_operand" "f")))]
5586   "TARGET_HARD_DFP"
5587   "ldetr\t%0,%1,0"
5588   [(set_attr "op_type" "RRF")
5589    (set_attr "type"    "fsimptf")])
5591 (define_expand "extendsdtd2"
5592   [(set (match_dup 2)
5593         (float_extend:DD (match_operand:SD 1 "register_operand" "")))
5594    (set (match_operand:TD 0 "register_operand" "")
5595         (float_extend:TD (match_dup 2)))]
5596   "TARGET_HARD_DFP"
5598   operands[2] = gen_reg_rtx (DDmode);
5601 ; Binary Floating Point - load fp integer
5603 ; Expanders for: floor, btrunc, round, ceil, and nearbyint
5604 ; For all of them the inexact exceptions are suppressed.
5606 ; fiebra, fidbra, fixbra
5607 (define_insn "<FPINT:fpint_name><BFP:mode>2<BFP:tf_fpr>"
5608   [(set (match_operand:BFP 0 "register_operand" "=f")
5609         (unspec:BFP [(match_operand:BFP 1 "register_operand" "f")]
5610                     FPINT))]
5611   "TARGET_Z196"
5612   "fi<BFP:xde>bra\t%0,<FPINT:fpint_roundingmode>,%1,4"
5613   [(set_attr "op_type"   "RRF")
5614    (set_attr "type"      "fsimp<BFP:type>")])
5616 ; rint is supposed to raise an inexact exception so we can use the
5617 ; older instructions.
5619 ; fiebr, fidbr, fixbr
5620 (define_insn "rint<BFP:mode>2<BFP:tf_fpr>"
5621   [(set (match_operand:BFP 0 "register_operand" "=f")
5622         (unspec:BFP [(match_operand:BFP 1 "register_operand" "f")]
5623                     UNSPEC_FPINT_RINT))]
5624   ""
5625   "fi<BFP:xde>br\t%0,0,%1"
5626   [(set_attr "op_type"   "RRF")
5627    (set_attr "type"      "fsimp<BFP:type>")])
5630 ; Decimal Floating Point - load fp integer
5632 ; fidtr, fixtr
5633 (define_insn "<FPINT:fpint_name><DFP:mode>2"
5634   [(set (match_operand:DFP 0 "register_operand" "=f")
5635         (unspec:DFP [(match_operand:DFP 1 "register_operand" "f")]
5636                     FPINT))]
5637   "TARGET_HARD_DFP"
5638   "fi<DFP:xde>tr\t%0,<FPINT:fpint_roundingmode>,%1,4"
5639   [(set_attr "op_type"   "RRF")
5640    (set_attr "type"      "fsimp<DFP:type>")])
5642 ; fidtr, fixtr
5643 (define_insn "rint<DFP:mode>2"
5644   [(set (match_operand:DFP 0 "register_operand" "=f")
5645         (unspec:DFP [(match_operand:DFP 1 "register_operand" "f")]
5646                     UNSPEC_FPINT_RINT))]
5647   "TARGET_HARD_DFP"
5648   "fi<DFP:xde>tr\t%0,0,%1,0"
5649   [(set_attr "op_type"   "RRF")
5650    (set_attr "type"      "fsimp<DFP:type>")])
5653 ; Binary <-> Decimal floating point trunc patterns
5656 (define_insn "*trunc<BFP:mode><DFP_ALL:mode>2"
5657   [(set (reg:DFP_ALL FPR0_REGNUM)
5658         (float_truncate:DFP_ALL (reg:BFP FPR4_REGNUM)))
5659    (use (reg:SI GPR0_REGNUM))
5660    (clobber (reg:CC CC_REGNUM))
5661    (clobber (reg:SI GPR1_REGNUM))]
5662   "TARGET_HARD_DFP"
5663   "pfpo")
5665 (define_insn "*trunc<DFP_ALL:mode><BFP:mode>2"
5666   [(set (reg:BFP FPR0_REGNUM)
5667         (float_truncate:BFP (reg:DFP_ALL FPR4_REGNUM)))
5668    (use (reg:SI GPR0_REGNUM))
5669    (clobber (reg:CC CC_REGNUM))
5670    (clobber (reg:SI GPR1_REGNUM))]
5671   "TARGET_HARD_DFP"
5672   "pfpo")
5674 (define_expand "trunc<BFP:mode><DFP_ALL:mode>2<BFP:tf_fpr>"
5675   [(set (reg:BFP FPR4_REGNUM) (match_operand:BFP 1 "nonimmediate_operand" ""))
5676    (set (reg:SI GPR0_REGNUM) (match_dup 2))
5677    (parallel
5678     [(set (reg:DFP_ALL FPR0_REGNUM)
5679           (float_truncate:DFP_ALL (reg:BFP FPR4_REGNUM)))
5680      (use (reg:SI GPR0_REGNUM))
5681      (clobber (reg:CC CC_REGNUM))
5682      (clobber (reg:SI GPR1_REGNUM))])
5683    (set (match_operand:DFP_ALL 0 "nonimmediate_operand" "")
5684         (reg:DFP_ALL FPR0_REGNUM))]
5685   "TARGET_HARD_DFP
5686    && GET_MODE_SIZE (<BFP:MODE>mode) > GET_MODE_SIZE (<DFP_ALL:MODE>mode)"
5688   HOST_WIDE_INT flags;
5690   /* According to IEEE 754 2008 4.3 'Rounding-direction attributes' the
5691      rounding mode of the target format needs to be used.  */
5693   flags = (PFPO_CONVERT |
5694            PFPO_OP_TYPE_<DFP_ALL:MODE> << PFPO_OP0_TYPE_SHIFT |
5695            PFPO_OP_TYPE_<BFP:MODE> << PFPO_OP1_TYPE_SHIFT |
5696            PFPO_RND_MODE_DFP);
5698   operands[2] = GEN_INT (flags);
5701 (define_expand "trunc<DFP_ALL:mode><BFP:mode>2<BFP:tf_fpr>"
5702   [(set (reg:DFP_ALL FPR4_REGNUM)
5703         (match_operand:DFP_ALL 1 "nonimmediate_operand" ""))
5704    (set (reg:SI GPR0_REGNUM) (match_dup 2))
5705    (parallel
5706     [(set (reg:BFP FPR0_REGNUM) (float_truncate:BFP (reg:DFP_ALL FPR4_REGNUM)))
5707      (use (reg:SI GPR0_REGNUM))
5708      (clobber (reg:CC CC_REGNUM))
5709      (clobber (reg:SI GPR1_REGNUM))])
5710    (set (match_operand:BFP 0 "nonimmediate_operand" "") (reg:BFP FPR0_REGNUM))]
5711   "TARGET_HARD_DFP
5712    && GET_MODE_SIZE (<DFP_ALL:MODE>mode) >= GET_MODE_SIZE (<BFP:MODE>mode)"
5714   HOST_WIDE_INT flags;
5716   /* According to IEEE 754 2008 4.3 'Rounding-direction attributes' the
5717      rounding mode of the target format needs to be used.  */
5719   flags = (PFPO_CONVERT |
5720            PFPO_OP_TYPE_<BFP:MODE> << PFPO_OP0_TYPE_SHIFT |
5721            PFPO_OP_TYPE_<DFP_ALL:MODE> << PFPO_OP1_TYPE_SHIFT |
5722            PFPO_RND_MODE_BFP);
5724   operands[2] = GEN_INT (flags);
5728 ; Binary <-> Decimal floating point extend patterns
5731 (define_insn "*extend<BFP:mode><DFP_ALL:mode>2"
5732   [(set (reg:DFP_ALL FPR0_REGNUM) (float_extend:DFP_ALL (reg:BFP FPR4_REGNUM)))
5733    (use (reg:SI GPR0_REGNUM))
5734    (clobber (reg:CC CC_REGNUM))
5735    (clobber (reg:SI GPR1_REGNUM))]
5736   "TARGET_HARD_DFP"
5737   "pfpo")
5739 (define_insn "*extend<DFP_ALL:mode><BFP:mode>2"
5740   [(set (reg:BFP FPR0_REGNUM) (float_extend:BFP (reg:DFP_ALL FPR4_REGNUM)))
5741    (use (reg:SI GPR0_REGNUM))
5742    (clobber (reg:CC CC_REGNUM))
5743    (clobber (reg:SI GPR1_REGNUM))]
5744   "TARGET_HARD_DFP"
5745   "pfpo")
5747 (define_expand "extend<BFP:mode><DFP_ALL:mode>2<BFP:tf_fpr>"
5748   [(set (reg:BFP FPR4_REGNUM) (match_operand:BFP 1 "nonimmediate_operand" ""))
5749    (set (reg:SI GPR0_REGNUM) (match_dup 2))
5750    (parallel
5751     [(set (reg:DFP_ALL FPR0_REGNUM)
5752           (float_extend:DFP_ALL (reg:BFP FPR4_REGNUM)))
5753      (use (reg:SI GPR0_REGNUM))
5754      (clobber (reg:CC CC_REGNUM))
5755      (clobber (reg:SI GPR1_REGNUM))])
5756    (set (match_operand:DFP_ALL 0 "nonimmediate_operand" "")
5757         (reg:DFP_ALL FPR0_REGNUM))]
5758   "TARGET_HARD_DFP
5759    && GET_MODE_SIZE (<BFP:MODE>mode) <= GET_MODE_SIZE (<DFP_ALL:MODE>mode)"
5761   HOST_WIDE_INT flags;
5763   /* According to IEEE 754 2008 4.3 'Rounding-direction attributes' the
5764      rounding mode of the target format needs to be used.  */
5766   flags = (PFPO_CONVERT |
5767            PFPO_OP_TYPE_<DFP_ALL:MODE> << PFPO_OP0_TYPE_SHIFT |
5768            PFPO_OP_TYPE_<BFP:MODE> << PFPO_OP1_TYPE_SHIFT |
5769            PFPO_RND_MODE_DFP);
5771   operands[2] = GEN_INT (flags);
5774 (define_expand "extend<DFP_ALL:mode><BFP:mode>2<BFP:tf_fpr>"
5775   [(set (reg:DFP_ALL FPR4_REGNUM)
5776         (match_operand:DFP_ALL 1 "nonimmediate_operand" ""))
5777    (set (reg:SI GPR0_REGNUM) (match_dup 2))
5778    (parallel
5779     [(set (reg:BFP FPR0_REGNUM) (float_extend:BFP (reg:DFP_ALL FPR4_REGNUM)))
5780      (use (reg:SI GPR0_REGNUM))
5781      (clobber (reg:CC CC_REGNUM))
5782      (clobber (reg:SI GPR1_REGNUM))])
5783    (set (match_operand:BFP 0 "nonimmediate_operand" "") (reg:BFP FPR0_REGNUM))]
5784   "TARGET_HARD_DFP
5785    && GET_MODE_SIZE (<DFP_ALL:MODE>mode) < GET_MODE_SIZE (<BFP:MODE>mode)"
5787   HOST_WIDE_INT flags;
5789   /* According to IEEE 754 2008 4.3 'Rounding-direction attributes' the
5790      rounding mode of the target format needs to be used.  */
5792   flags = (PFPO_CONVERT |
5793            PFPO_OP_TYPE_<BFP:MODE> << PFPO_OP0_TYPE_SHIFT |
5794            PFPO_OP_TYPE_<DFP_ALL:MODE> << PFPO_OP1_TYPE_SHIFT |
5795            PFPO_RND_MODE_BFP);
5797   operands[2] = GEN_INT (flags);
5802 ;; ARITHMETIC OPERATIONS
5804 ;  arithmetic operations set the ConditionCode,
5805 ;  because of unpredictable Bits in Register for Halfword and Byte
5806 ;  the ConditionCode can be set wrong in operations for Halfword and Byte
5809 ;;- Add instructions.
5813 ; addti3 instruction pattern(s).
5816 (define_expand "addti3"
5817   [(parallel
5818     [(set (match_operand:TI          0 "register_operand"     "")
5819           (plus:TI (match_operand:TI 1 "nonimmediate_operand" "")
5820                    (match_operand:TI 2 "general_operand"      "") ) )
5821      (clobber (reg:CC CC_REGNUM))])]
5822   "TARGET_ZARCH"
5824   /* For z13 we have vaq which doesn't set CC.  */
5825   if (TARGET_VX)
5826     {
5827       emit_insn (gen_rtx_SET (operands[0],
5828                               gen_rtx_PLUS (TImode,
5829                                             copy_to_mode_reg (TImode, operands[1]),
5830                                             copy_to_mode_reg (TImode, operands[2]))));
5831       DONE;
5832     }
5835 (define_insn_and_split "*addti3"
5836   [(set (match_operand:TI          0 "register_operand"    "=&d")
5837         (plus:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
5838                  (match_operand:TI 2 "general_operand"      "do") ) )
5839    (clobber (reg:CC CC_REGNUM))]
5840   "TARGET_ZARCH"
5841   "#"
5842   "&& reload_completed"
5843   [(parallel
5844     [(set (reg:CCL1 CC_REGNUM)
5845           (compare:CCL1 (plus:DI (match_dup 7) (match_dup 8))
5846                         (match_dup 7)))
5847      (set (match_dup 6) (plus:DI (match_dup 7) (match_dup 8)))])
5848    (parallel
5849     [(set (match_dup 3) (plus:DI
5850                           (plus:DI (ltu:DI (reg:CCL1 CC_REGNUM) (const_int 0))
5851                                    (match_dup 4)) (match_dup 5)))
5852      (clobber (reg:CC CC_REGNUM))])]
5853   "operands[3] = operand_subword (operands[0], 0, 0, TImode);
5854    operands[4] = operand_subword (operands[1], 0, 0, TImode);
5855    operands[5] = operand_subword (operands[2], 0, 0, TImode);
5856    operands[6] = operand_subword (operands[0], 1, 0, TImode);
5857    operands[7] = operand_subword (operands[1], 1, 0, TImode);
5858    operands[8] = operand_subword (operands[2], 1, 0, TImode);"
5859   [(set_attr "op_type"  "*")
5860    (set_attr "cpu_facility" "*")])
5863 ; adddi3 instruction pattern(s).
5866 (define_expand "adddi3"
5867   [(parallel
5868     [(set (match_operand:DI 0 "nonimmediate_operand" "")
5869           (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
5870                    (match_operand:DI 2 "general_operand" "")))
5871      (clobber (reg:CC CC_REGNUM))])]
5872   ""
5873   "")
5875 (define_insn "*adddi3_sign"
5876   [(set (match_operand:DI 0 "register_operand" "=d,d")
5877         (plus:DI (sign_extend:DI (match_operand:SI 2 "general_operand" "d,T"))
5878                  (match_operand:DI 1 "register_operand" "0,0")))
5879    (clobber (reg:CC CC_REGNUM))]
5880   "TARGET_ZARCH"
5881   "@
5882    agfr\t%0,%2
5883    agf\t%0,%2"
5884   [(set_attr "op_type"  "RRE,RXY")
5885    (set_attr "z196prop" "z196_cracked,z196_cracked")])
5887 (define_insn "*adddi3_zero_cc"
5888   [(set (reg CC_REGNUM)
5889         (compare (plus:DI (zero_extend:DI (match_operand:SI 2 "general_operand" "d,T"))
5890                           (match_operand:DI 1 "register_operand" "0,0"))
5891                  (const_int 0)))
5892    (set (match_operand:DI 0 "register_operand" "=d,d")
5893         (plus:DI (zero_extend:DI (match_dup 2)) (match_dup 1)))]
5894   "s390_match_ccmode (insn, CCLmode) && TARGET_ZARCH"
5895   "@
5896    algfr\t%0,%2
5897    algf\t%0,%2"
5898   [(set_attr "op_type"  "RRE,RXY")
5899    (set_attr "z10prop" "z10_super_E1,z10_super_E1")])
5901 (define_insn "*adddi3_zero_cconly"
5902   [(set (reg CC_REGNUM)
5903         (compare (plus:DI (zero_extend:DI (match_operand:SI 2 "general_operand" "d,T"))
5904                           (match_operand:DI 1 "register_operand" "0,0"))
5905                  (const_int 0)))
5906    (clobber (match_scratch:DI 0 "=d,d"))]
5907   "s390_match_ccmode (insn, CCLmode) && TARGET_ZARCH"
5908   "@
5909    algfr\t%0,%2
5910    algf\t%0,%2"
5911   [(set_attr "op_type"  "RRE,RXY")
5912    (set_attr "z10prop" "z10_super_E1,z10_super_E1")])
5914 (define_insn "*adddi3_zero"
5915   [(set (match_operand:DI 0 "register_operand" "=d,d")
5916         (plus:DI (zero_extend:DI (match_operand:SI 2 "general_operand" "d,T"))
5917                  (match_operand:DI 1 "register_operand" "0,0")))
5918    (clobber (reg:CC CC_REGNUM))]
5919   "TARGET_ZARCH"
5920   "@
5921    algfr\t%0,%2
5922    algf\t%0,%2"
5923   [(set_attr "op_type"  "RRE,RXY")
5924    (set_attr "z10prop" "z10_super_E1,z10_super_E1")])
5926 (define_insn_and_split "*adddi3_31z"
5927   [(set (match_operand:DI 0 "nonimmediate_operand" "=&d")
5928         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
5929                  (match_operand:DI 2 "general_operand" "do") ) )
5930    (clobber (reg:CC CC_REGNUM))]
5931   "!TARGET_ZARCH"
5932   "#"
5933   "&& reload_completed"
5934   [(parallel
5935     [(set (reg:CCL1 CC_REGNUM)
5936           (compare:CCL1 (plus:SI (match_dup 7) (match_dup 8))
5937                         (match_dup 7)))
5938      (set (match_dup 6) (plus:SI (match_dup 7) (match_dup 8)))])
5939    (parallel
5940     [(set (match_dup 3) (plus:SI
5941                           (plus:SI (ltu:SI (reg:CCL1 CC_REGNUM) (const_int 0))
5942                                    (match_dup 4)) (match_dup 5)))
5943      (clobber (reg:CC CC_REGNUM))])]
5944   "operands[3] = operand_subword (operands[0], 0, 0, DImode);
5945    operands[4] = operand_subword (operands[1], 0, 0, DImode);
5946    operands[5] = operand_subword (operands[2], 0, 0, DImode);
5947    operands[6] = operand_subword (operands[0], 1, 0, DImode);
5948    operands[7] = operand_subword (operands[1], 1, 0, DImode);
5949    operands[8] = operand_subword (operands[2], 1, 0, DImode);")
5952 ; addsi3 instruction pattern(s).
5955 (define_expand "addsi3"
5956   [(parallel
5957     [(set (match_operand:SI 0 "nonimmediate_operand" "")
5958           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "")
5959                    (match_operand:SI 2 "general_operand" "")))
5960      (clobber (reg:CC CC_REGNUM))])]
5961   ""
5962   "")
5964 (define_insn "*addsi3_sign"
5965   [(set (match_operand:SI 0 "register_operand" "=d,d")
5966         (plus:SI (sign_extend:SI (match_operand:HI 2 "memory_operand" "R,T"))
5967                  (match_operand:SI 1 "register_operand" "0,0")))
5968    (clobber (reg:CC CC_REGNUM))]
5969   ""
5970   "@
5971    ah\t%0,%2
5972    ahy\t%0,%2"
5973   [(set_attr "op_type"  "RX,RXY")
5974    (set_attr "cpu_facility" "*,longdisp")
5975    (set_attr "z196prop" "z196_cracked,z196_cracked")])
5978 ; add(di|si)3 instruction pattern(s).
5981 ; ark, agrk, ar, ahi, ahik, aghik, alfi, slfi, a, ay, agr, aghi, algfi, slgfi, ag, asi, agsi
5982 (define_insn "*add<mode>3"
5983   [(set (match_operand:GPR 0 "nonimmediate_operand"           "=d,d,d,d, d, d,d,d,S")
5984         (plus:GPR (match_operand:GPR 1 "nonimmediate_operand" "%0,d,0,d, 0, 0,0,0,0")
5985                   (match_operand:GPR 2 "general_operand"      " d,d,K,K,Op,On,R,T,C") ) )
5986    (clobber (reg:CC CC_REGNUM))]
5987   ""
5988   "@
5989    a<g>r\t%0,%2
5990    a<g>rk\t%0,%1,%2
5991    a<g>hi\t%0,%h2
5992    a<g>hik\t%0,%1,%h2
5993    al<g>fi\t%0,%2
5994    sl<g>fi\t%0,%n2
5995    a<g>\t%0,%2
5996    a<y>\t%0,%2
5997    a<g>si\t%0,%c2"
5998   [(set_attr "op_type"  "RR<E>,RRF,RI,RIE,RIL,RIL,RX<Y>,RXY,SIY")
5999    (set_attr "cpu_facility" "*,z196,*,z196,extimm,extimm,*,longdisp,z10")
6000    (set_attr "z10prop" "z10_super_E1,*,z10_super_E1,*,z10_super_E1,z10_super_E1,
6001                         z10_super_E1,z10_super_E1,z10_super_E1")])
6003 ; alr, alfi, slfi, al, aly, alrk, alhsik, algr, algfi, slgfi, alg, alsi, algsi, algrk, alghsik
6004 (define_insn "*add<mode>3_carry1_cc"
6005   [(set (reg CC_REGNUM)
6006         (compare (plus:GPR (match_operand:GPR 1 "nonimmediate_operand" "%0,d, 0, 0,d,0,0,0")
6007                            (match_operand:GPR 2 "general_operand"      " d,d,Op,On,K,R,T,C"))
6008                  (match_dup 1)))
6009    (set (match_operand:GPR 0 "nonimmediate_operand"                    "=d,d, d, d,d,d,d,d")
6010         (plus:GPR (match_dup 1) (match_dup 2)))]
6011   "s390_match_ccmode (insn, CCL1mode)"
6012   "@
6013    al<g>r\t%0,%2
6014    al<g>rk\t%0,%1,%2
6015    al<g>fi\t%0,%2
6016    sl<g>fi\t%0,%n2
6017    al<g>hsik\t%0,%1,%h2
6018    al<g>\t%0,%2
6019    al<y>\t%0,%2
6020    al<g>si\t%0,%c2"
6021   [(set_attr "op_type"      "RR<E>,RRF,RIL,RIL,RIE,RX<Y>,RXY,SIY")
6022    (set_attr "cpu_facility" "*,z196,extimm,extimm,z196,*,longdisp,z10")
6023    (set_attr "z10prop" "z10_super_E1,*,z10_super_E1,z10_super_E1,*,
6024                         z10_super_E1,z10_super_E1,z10_super_E1")])
6026 ; alr, al, aly, algr, alg, alrk, algrk
6027 (define_insn "*add<mode>3_carry1_cconly"
6028   [(set (reg CC_REGNUM)
6029         (compare (plus:GPR (match_operand:GPR 1 "nonimmediate_operand" "%0,d,0,0")
6030                            (match_operand:GPR 2 "general_operand"       "d,d,R,T"))
6031                  (match_dup 1)))
6032    (clobber (match_scratch:GPR 0                                       "=d,d,d,d"))]
6033   "s390_match_ccmode (insn, CCL1mode)"
6034   "@
6035    al<g>r\t%0,%2
6036    al<g>rk\t%0,%1,%2
6037    al<g>\t%0,%2
6038    al<y>\t%0,%2"
6039   [(set_attr "op_type"  "RR<E>,RRF,RX<Y>,RXY")
6040    (set_attr "cpu_facility" "*,z196,*,longdisp")
6041    (set_attr "z10prop" "z10_super_E1,*,z10_super_E1,z10_super_E1")])
6043 ; alr, alfi, slfi, al, aly, algr, algfi, slgfi, alg, alsi, algsi, alrk, algrk, alhsik, alghsik
6044 (define_insn "*add<mode>3_carry2_cc"
6045   [(set (reg CC_REGNUM)
6046         (compare (plus:GPR (match_operand:GPR 1 "nonimmediate_operand" "%0,d, 0, 0,d,0,0,0")
6047                            (match_operand:GPR 2 "general_operand"      " d,d,Op,On,K,R,T,C"))
6048                  (match_dup 2)))
6049    (set (match_operand:GPR 0 "nonimmediate_operand"                    "=d,d, d, d,d,d,d,S")
6050         (plus:GPR (match_dup 1) (match_dup 2)))]
6051   "s390_match_ccmode (insn, CCL1mode)"
6052   "@
6053    al<g>r\t%0,%2
6054    al<g>rk\t%0,%1,%2
6055    al<g>fi\t%0,%2
6056    sl<g>fi\t%0,%n2
6057    al<g>hsik\t%0,%1,%h2
6058    al<g>\t%0,%2
6059    al<y>\t%0,%2
6060    al<g>si\t%0,%c2"
6061   [(set_attr "op_type"  "RR<E>,RRF,RIL,RIL,RIE,RX<Y>,RXY,SIY")
6062    (set_attr "cpu_facility" "*,z196,extimm,extimm,z196,*,longdisp,z10")
6063    (set_attr "z10prop" "z10_super_E1,*,z10_super_E1,z10_super_E1,*,
6064                         z10_super_E1,z10_super_E1,z10_super_E1")])
6066 ; alr, al, aly, algr, alg, alrk, algrk
6067 (define_insn "*add<mode>3_carry2_cconly"
6068   [(set (reg CC_REGNUM)
6069         (compare (plus:GPR (match_operand:GPR 1 "nonimmediate_operand" "%0,d,0,0")
6070                            (match_operand:GPR 2 "general_operand"       "d,d,R,T"))
6071                  (match_dup 2)))
6072    (clobber (match_scratch:GPR 0                                       "=d,d,d,d"))]
6073   "s390_match_ccmode (insn, CCL1mode)"
6074   "@
6075    al<g>r\t%0,%2
6076    al<g>rk\t%0,%1,%2
6077    al<g>\t%0,%2
6078    al<y>\t%0,%2"
6079   [(set_attr "op_type"  "RR<E>,RRF,RX<Y>,RXY")
6080    (set_attr "cpu_facility" "*,z196,*,longdisp")
6081    (set_attr "z10prop" "z10_super_E1,*,z10_super_E1,z10_super_E1")])
6083 ; alr, alfi, slfi, al, aly, algr, algfi, slgfi, alg, alsi, algsi, alrk, algrk, alhsik, alghsik
6084 (define_insn "*add<mode>3_cc"
6085   [(set (reg CC_REGNUM)
6086         (compare (plus:GPR (match_operand:GPR 1 "nonimmediate_operand" "%0,d, 0, 0,d,0,0,0")
6087                            (match_operand:GPR 2 "general_operand"      " d,d,Op,On,K,R,T,C"))
6088                  (const_int 0)))
6089    (set (match_operand:GPR 0 "nonimmediate_operand"                    "=d,d, d, d,d,d,d,S")
6090         (plus:GPR (match_dup 1) (match_dup 2)))]
6091   "s390_match_ccmode (insn, CCLmode)"
6092   "@
6093    al<g>r\t%0,%2
6094    al<g>rk\t%0,%1,%2
6095    al<g>fi\t%0,%2
6096    sl<g>fi\t%0,%n2
6097    al<g>hsik\t%0,%1,%h2
6098    al<g>\t%0,%2
6099    al<y>\t%0,%2
6100    al<g>si\t%0,%c2"
6101   [(set_attr "op_type"  "RR<E>,RRF,RIL,RIL,RIE,RX<Y>,RXY,SIY")
6102    (set_attr "cpu_facility" "*,z196,extimm,extimm,z196,*,longdisp,z10")
6103    (set_attr "z10prop" "z10_super_E1,*,z10_super_E1,z10_super_E1,
6104                         *,z10_super_E1,z10_super_E1,z10_super_E1")])
6106 ; alr, al, aly, algr, alg, alrk, algrk
6107 (define_insn "*add<mode>3_cconly"
6108   [(set (reg CC_REGNUM)
6109         (compare (plus:GPR (match_operand:GPR 1 "nonimmediate_operand" "%0,d,0,0")
6110                            (match_operand:GPR 2 "general_operand"       "d,d,R,T"))
6111                  (const_int 0)))
6112    (clobber (match_scratch:GPR 0                                       "=d,d,d,d"))]
6113   "s390_match_ccmode (insn, CCLmode)"
6114   "@
6115    al<g>r\t%0,%2
6116    al<g>rk\t%0,%1,%2
6117    al<g>\t%0,%2
6118    al<y>\t%0,%2"
6119   [(set_attr "op_type"  "RR<E>,RRF,RX<Y>,RXY")
6120    (set_attr "cpu_facility" "*,z196,*,longdisp")
6121    (set_attr "z10prop" "z10_super_E1,*,z10_super_E1,z10_super_E1")])
6123 ; alr, al, aly, algr, alg, alrk, algrk
6124 (define_insn "*add<mode>3_cconly2"
6125   [(set (reg CC_REGNUM)
6126         (compare (match_operand:GPR 1 "nonimmediate_operand"    "%0,d,0,0")
6127                  (neg:GPR (match_operand:GPR 2 "general_operand" "d,d,R,T"))))
6128    (clobber (match_scratch:GPR 0                                "=d,d,d,d"))]
6129   "s390_match_ccmode(insn, CCLmode)"
6130   "@
6131    al<g>r\t%0,%2
6132    al<g>rk\t%0,%1,%2
6133    al<g>\t%0,%2
6134    al<y>\t%0,%2"
6135   [(set_attr "op_type"  "RR<E>,RRF,RX<Y>,RXY")
6136    (set_attr "cpu_facility" "*,z196,*,longdisp")
6137    (set_attr "z10prop" "z10_super_E1,*,z10_super_E1,z10_super_E1")])
6139 ; ahi, afi, aghi, agfi, asi, agsi
6140 (define_insn "*add<mode>3_imm_cc"
6141   [(set (reg CC_REGNUM)
6142         (compare (plus:GPR (match_operand:GPR 1 "nonimmediate_operand" " 0, d,0, 0")
6143                            (match_operand:GPR 2 "const_int_operand"    " K, K,Os,C"))
6144                  (const_int 0)))
6145    (set (match_operand:GPR 0 "nonimmediate_operand"                    "=d, d,d, S")
6146         (plus:GPR (match_dup 1) (match_dup 2)))]
6147   "s390_match_ccmode (insn, CCAmode)
6148    && (CONST_OK_FOR_CONSTRAINT_P (INTVAL (operands[2]), 'K', \"K\")
6149        || (CONST_OK_FOR_CONSTRAINT_P (INTVAL (operands[2]), 'O', \"Os\")
6150            /* Avoid INT32_MIN on 32 bit.  */
6151            && (!TARGET_ZARCH || INTVAL (operands[2]) != -0x7fffffff - 1)))"
6152   "@
6153    a<g>hi\t%0,%h2
6154    a<g>hik\t%0,%1,%h2
6155    a<g>fi\t%0,%2
6156    a<g>si\t%0,%c2"
6157   [(set_attr "op_type"      "RI,RIE,RIL,SIY")
6158    (set_attr "cpu_facility" "*,z196,extimm,z10")
6159    (set_attr "z10prop" "z10_super_E1,*,z10_super_E1,z10_super_E1")])
6161 (define_insn "*adddi3_sign"
6162   [(set (match_operand:DI                          0 "register_operand" "=d")
6163         (plus:DI (sign_extend:DI (match_operand:HI 2 "memory_operand"    "T"))
6164                  (match_operand:DI                 1 "register_operand"  "0")))
6165    (clobber (reg:CC CC_REGNUM))]
6166   "TARGET_Z14"
6167   "agh\t%0,%2"
6168   [(set_attr "op_type"  "RXY")])
6171 ; Jump to label OP3 if OP1 + OP2 results in a signed overflow
6173 ; addv_const_operand accepts all constants which can be handled
6174 ; without reloads.  These will be handled primarily by
6175 ; "*addv<mode>3_ccoverflow_const" which doesn't provide a register
6176 ; alternative.  Hence we have to match the operand exactly.
6177 ; For immediates we have to avoid the SIGN_EXTEND around OP2.
6178 (define_expand "addv<mode>4"
6179   [(parallel
6180     [(set (reg:CCO CC_REGNUM)
6181           (compare:CCO (plus:<DBL>
6182                         (sign_extend:<DBL> (match_operand:GPR 1 "nonimmediate_operand"))
6183                         (match_dup 4))
6184                        (sign_extend:<DBL> (plus:GPR (match_dup 1)
6185                                                     (match_operand:GPR 2 "general_operand")))))
6186      (set (match_operand:GPR 0 "nonimmediate_operand")
6187           (plus:GPR (match_dup 1) (match_dup 2)))])
6188    (set (pc)
6189         (if_then_else (ne (reg:CCO CC_REGNUM) (const_int 0))
6190                       (label_ref (match_operand 3))
6191                       (pc)))]
6192   ""
6194   if (CONSTANT_P (operands[2])
6195       && !addv_const_operand (operands[2], GET_MODE (operands[2])))
6196     operands[2] = force_reg (<GPR:MODE>mode, operands[2]);
6198   if (GET_MODE (operands[2]) != VOIDmode)
6199     operands[4] = gen_rtx_SIGN_EXTEND (<DBL>mode, operands[2]);
6200   else
6201     /* This is what CSE does when propagating a constant into the pattern.  */
6202     operands[4] = simplify_unary_operation (SIGN_EXTEND, <GPR:DBL>mode, operands[2], <GPR:MODE>mode);
6205 ; ark, agrk, ar, ahi, ahik, aghik, a, ay, agr, aghi, ag, asi, agsi
6206 (define_insn "*addv<mode>3_ccoverflow"
6207   [(set (reg CC_REGNUM)
6208         (compare (plus:<DBL>
6209                   (sign_extend:<DBL> (match_operand:GPR 1 "nonimmediate_operand" "%0,d,0,d,0,0,0"))
6210                   (sign_extend:<DBL> (match_operand:GPR 2 "general_operand"      " d,d,K,K,R,T,C")))
6211                  (sign_extend:<DBL> (plus:GPR (match_dup 1) (match_dup 2)))))
6212    (set (match_operand:GPR                              0 "nonimmediate_operand" "=d,d,d,d,d,d,S")
6213         (plus:GPR (match_dup 1) (match_dup 2)))]
6214   "s390_match_ccmode (insn, CCOmode)"
6215   "@
6216    a<g>r\t%0,%2
6217    a<g>rk\t%0,%1,%2
6218    a<g>hi\t%0,%h2
6219    a<g>hik\t%0,%1,%h2
6220    a<g>\t%0,%2
6221    a<y>\t%0,%2
6222    a<g>si\t%0,%c2"
6223   [(set_attr "op_type"  "RR<E>,RRF,RI,RIE,RX<Y>,RXY,SIY")
6224    (set_attr "cpu_facility" "*,z196,*,z196,*,longdisp,z10")
6225    (set_attr "z10prop" "z10_super_E1,*,z10_super_E1,*,
6226                         z10_super_E1,z10_super_E1,z10_super_E1")])
6228 ; ahi, aghi, ahik, aghik, asi, agsi
6229 (define_insn "*addv<mode>3_ccoverflow_const"
6230   [(set (reg CC_REGNUM)
6231         (compare (plus:<DBL>
6232                   (sign_extend:<DBL> (match_operand:GPR 1 "nonimmediate_operand" "%0,d,0"))
6233                   (match_operand:<DBL>                  2 "addv_const_operand"    "K,K,C"))
6234                  (sign_extend:<DBL> (plus:GPR (match_dup 1) (match_dup 2)))))
6235    (set (match_operand:GPR                              0 "nonimmediate_operand" "=d,d,S")
6236         (plus:GPR (match_dup 1) (match_dup 2)))]
6237   "s390_match_ccmode (insn, CCOmode)"
6238   "@
6239    a<g>hi\t%0,%h2
6240    a<g>hik\t%0,%1,%h2
6241    a<g>si\t%0,%c2"
6242   [(set_attr "op_type"  "RI,RIE,SIY")
6243    (set_attr "cpu_facility" "*,z196,z10")
6244    (set_attr "z10prop" "z10_super_E1,*,z10_super_E1")])
6248 ; add(tf|df|sf|td|dd)3 instruction pattern(s).
6251 ; axbr, adbr, aebr, axb, adb, aeb, adtr, axtr
6252 ; FIXME: wfadb does not clobber cc
6253 (define_insn "add<mode>3<tf_fpr>"
6254   [(set (match_operand:FP          0 "register_operand"     "=f,f,f,v,v")
6255         (plus:FP (match_operand:FP 1 "nonimmediate_operand" "%f,0,0,v,v")
6256                  (match_operand:FP 2 "general_operand"       "f,f,R,v,v")))
6257    (clobber (reg:CC CC_REGNUM))]
6258   "TARGET_HARD_FLOAT"
6259   "@
6260    a<xde>tr\t%0,%1,%2
6261    a<xde>br\t%0,%2
6262    a<xde>b\t%0,%2
6263    wfadb\t%v0,%v1,%v2
6264    wfasb\t%v0,%v1,%v2"
6265   [(set_attr "op_type"      "RRF,RRE,RXE,VRR,VRR")
6266    (set_attr "type"         "fsimp<type>")
6267    (set_attr "cpu_facility" "*,*,*,vx,vxe")
6268    (set_attr "enabled"      "<nBFP>,<nDFP>,<DSF>,<DF>,<SF>")])
6270 ; axbr, adbr, aebr, axb, adb, aeb, adtr, axtr
6271 (define_insn "*add<mode>3_cc"
6272   [(set (reg CC_REGNUM)
6273         (compare (plus:FP (match_operand:FP 1 "nonimmediate_operand" "%f,0,0")
6274                           (match_operand:FP 2 "general_operand"       "f,f,R"))
6275                  (match_operand:FP 3 "const0_operand" "")))
6276    (set (match_operand:FP 0 "register_operand" "=f,f,f")
6277         (plus:FP (match_dup 1) (match_dup 2)))]
6278   "s390_match_ccmode (insn, CCSmode) && TARGET_HARD_FLOAT"
6279   "@
6280    a<xde>tr\t%0,%1,%2
6281    a<xde>br\t%0,%2
6282    a<xde>b\t%0,%2"
6283   [(set_attr "op_type"  "RRF,RRE,RXE")
6284    (set_attr "type"     "fsimp<type>")
6285    (set_attr "enabled"  "<nBFP>,<nDFP>,<DSF>")])
6287 ; axbr, adbr, aebr, axb, adb, aeb, adtr, axtr
6288 (define_insn "*add<mode>3_cconly"
6289   [(set (reg CC_REGNUM)
6290         (compare (plus:FP (match_operand:FP 1 "nonimmediate_operand" "%f,0,0")
6291                           (match_operand:FP 2 "general_operand"       "f,f,R"))
6292                  (match_operand:FP 3 "const0_operand" "")))
6293    (clobber (match_scratch:FP 0 "=f,f,f"))]
6294   "s390_match_ccmode (insn, CCSmode) && TARGET_HARD_FLOAT"
6295   "@
6296    a<xde>tr\t%0,%1,%2
6297    a<xde>br\t%0,%2
6298    a<xde>b\t%0,%2"
6299   [(set_attr "op_type"  "RRF,RRE,RXE")
6300    (set_attr "type"     "fsimp<type>")
6301    (set_attr "enabled"  "<nBFP>,<nDFP>,<DSF>")])
6304 ; Pointer add instruction patterns
6307 ; This will match "*la_64"
6308 (define_expand "addptrdi3"
6309   [(set (match_operand:DI 0 "register_operand" "")
6310         (plus:DI (match_operand:DI 1 "register_operand" "")
6311                  (match_operand:DI 2 "nonmemory_operand" "")))]
6312   "TARGET_64BIT"
6314   if (GET_CODE (operands[2]) == CONST_INT)
6315     {
6316       HOST_WIDE_INT c = INTVAL (operands[2]);
6318       if (!CONST_OK_FOR_CONSTRAINT_P (c, 'K', "K")
6319           && !CONST_OK_FOR_CONSTRAINT_P (c, 'O', "Os"))
6320         {
6321           operands[2] = force_const_mem (DImode, operands[2]);
6322           operands[2] = force_reg (DImode, operands[2]);
6323         }
6324       else if (!DISP_IN_RANGE (INTVAL (operands[2])))
6325         operands[2] = force_reg (DImode, operands[2]);
6326     }
6329 ; For 31 bit we have to prevent the generated pattern from matching
6330 ; normal ADDs since la only does a 31 bit add.  This is supposed to
6331 ; match "force_la_31".
6332 (define_expand "addptrsi3"
6333   [(parallel
6334     [(set (match_operand:SI 0 "register_operand" "")
6335           (plus:SI (match_operand:SI 1 "register_operand" "")
6336                    (match_operand:SI 2 "nonmemory_operand" "")))
6337                    (use (const_int 0))])]
6338   "!TARGET_64BIT"
6340   if (GET_CODE (operands[2]) == CONST_INT)
6341     {
6342       HOST_WIDE_INT c = INTVAL (operands[2]);
6344       if (!CONST_OK_FOR_CONSTRAINT_P (c, 'K', "K")
6345           && !CONST_OK_FOR_CONSTRAINT_P (c, 'O', "Os"))
6346         {
6347           operands[2] = force_const_mem (SImode, operands[2]);
6348           operands[2] = force_reg (SImode, operands[2]);
6349         }
6350       else if (!DISP_IN_RANGE (INTVAL (operands[2])))
6351         operands[2] = force_reg (SImode, operands[2]);
6352     }
6356 ;;- Subtract instructions.
6360 ; subti3 instruction pattern(s).
6363 (define_expand "subti3"
6364   [(parallel
6365     [(set (match_operand:TI           0 "register_operand" "")
6366           (minus:TI (match_operand:TI 1 "register_operand" "")
6367                     (match_operand:TI 2 "general_operand"  "") ) )
6368      (clobber (reg:CC CC_REGNUM))])]
6369   "TARGET_ZARCH"
6371   /* For z13 we have vsq which doesn't set CC.  */
6372   if (TARGET_VX)
6373     {
6374       emit_insn (gen_rtx_SET (operands[0],
6375                               gen_rtx_MINUS (TImode,
6376                                             operands[1],
6377                                             copy_to_mode_reg (TImode, operands[2]))));
6378       DONE;
6379     }
6382 (define_insn_and_split "*subti3"
6383   [(set (match_operand:TI           0 "register_operand" "=&d")
6384         (minus:TI (match_operand:TI 1 "register_operand"   "0")
6385                   (match_operand:TI 2 "general_operand"   "do") ) )
6386    (clobber (reg:CC CC_REGNUM))]
6387   "TARGET_ZARCH"
6388   "#"
6389   "&& reload_completed"
6390   [(parallel
6391     [(set (reg:CCL2 CC_REGNUM)
6392           (compare:CCL2 (minus:DI (match_dup 7) (match_dup 8))
6393                         (match_dup 7)))
6394      (set (match_dup 6) (minus:DI (match_dup 7) (match_dup 8)))])
6395    (parallel
6396     [(set (match_dup 3) (minus:DI (minus:DI (match_dup 4) (match_dup 5))
6397                                   (gtu:DI (reg:CCL2 CC_REGNUM) (const_int 0))))
6398      (clobber (reg:CC CC_REGNUM))])]
6399   "operands[3] = operand_subword (operands[0], 0, 0, TImode);
6400    operands[4] = operand_subword (operands[1], 0, 0, TImode);
6401    operands[5] = operand_subword (operands[2], 0, 0, TImode);
6402    operands[6] = operand_subword (operands[0], 1, 0, TImode);
6403    operands[7] = operand_subword (operands[1], 1, 0, TImode);
6404    operands[8] = operand_subword (operands[2], 1, 0, TImode);"
6405   [(set_attr "op_type"      "*")
6406    (set_attr "cpu_facility" "*")])
6409 ; subdi3 instruction pattern(s).
6412 (define_expand "subdi3"
6413   [(parallel
6414     [(set (match_operand:DI 0 "register_operand" "")
6415           (minus:DI (match_operand:DI 1 "register_operand" "")
6416                     (match_operand:DI 2 "general_operand" "")))
6417      (clobber (reg:CC CC_REGNUM))])]
6418   ""
6419   "")
6421 (define_insn "*subdi3_sign"
6422   [(set (match_operand:DI 0 "register_operand" "=d,d")
6423         (minus:DI (match_operand:DI 1 "register_operand" "0,0")
6424                   (sign_extend:DI (match_operand:SI 2 "general_operand" "d,T"))))
6425    (clobber (reg:CC CC_REGNUM))]
6426   "TARGET_ZARCH"
6427   "@
6428    sgfr\t%0,%2
6429    sgf\t%0,%2"
6430   [(set_attr "op_type"  "RRE,RXY")
6431    (set_attr "z10prop" "z10_c,*")
6432    (set_attr "z196prop" "z196_cracked")])
6434 (define_insn "*subdi3_zero_cc"
6435   [(set (reg CC_REGNUM)
6436         (compare (minus:DI (match_operand:DI 1 "register_operand" "0,0")
6437                            (zero_extend:DI (match_operand:SI 2 "general_operand" "d,T")))
6438                  (const_int 0)))
6439    (set (match_operand:DI 0 "register_operand" "=d,d")
6440         (minus:DI (match_dup 1) (zero_extend:DI (match_dup 2))))]
6441   "s390_match_ccmode (insn, CCLmode) && TARGET_ZARCH"
6442   "@
6443    slgfr\t%0,%2
6444    slgf\t%0,%2"
6445   [(set_attr "op_type"  "RRE,RXY")
6446    (set_attr "z10prop" "z10_super_c_E1,z10_super_E1")])
6448 (define_insn "*subdi3_zero_cconly"
6449   [(set (reg CC_REGNUM)
6450         (compare (minus:DI (match_operand:DI 1 "register_operand" "0,0")
6451                            (zero_extend:DI (match_operand:SI 2 "general_operand" "d,T")))
6452                  (const_int 0)))
6453    (clobber (match_scratch:DI 0 "=d,d"))]
6454   "s390_match_ccmode (insn, CCLmode) && TARGET_ZARCH"
6455   "@
6456    slgfr\t%0,%2
6457    slgf\t%0,%2"
6458   [(set_attr "op_type"  "RRE,RXY")
6459    (set_attr "z10prop" "z10_super_c_E1,z10_super_E1")])
6461 (define_insn "*subdi3_zero"
6462   [(set (match_operand:DI 0 "register_operand" "=d,d")
6463         (minus:DI (match_operand:DI 1 "register_operand" "0,0")
6464                   (zero_extend:DI (match_operand:SI 2 "general_operand" "d,T"))))
6465    (clobber (reg:CC CC_REGNUM))]
6466   "TARGET_ZARCH"
6467   "@
6468    slgfr\t%0,%2
6469    slgf\t%0,%2"
6470   [(set_attr "op_type"  "RRE,RXY")
6471    (set_attr "z10prop" "z10_super_c_E1,z10_super_E1")])
6473 (define_insn_and_split "*subdi3_31z"
6474   [(set (match_operand:DI 0 "register_operand" "=&d")
6475         (minus:DI (match_operand:DI 1 "register_operand" "0")
6476                   (match_operand:DI 2 "general_operand" "do") ) )
6477    (clobber (reg:CC CC_REGNUM))]
6478   "!TARGET_ZARCH"
6479   "#"
6480   "&& reload_completed"
6481   [(parallel
6482     [(set (reg:CCL2 CC_REGNUM)
6483           (compare:CCL2 (minus:SI (match_dup 7) (match_dup 8))
6484                         (match_dup 7)))
6485      (set (match_dup 6) (minus:SI (match_dup 7) (match_dup 8)))])
6486    (parallel
6487     [(set (match_dup 3) (minus:SI (minus:SI (match_dup 4) (match_dup 5))
6488                                   (gtu:SI (reg:CCL2 CC_REGNUM) (const_int 0))))
6489      (clobber (reg:CC CC_REGNUM))])]
6490   "operands[3] = operand_subword (operands[0], 0, 0, DImode);
6491    operands[4] = operand_subword (operands[1], 0, 0, DImode);
6492    operands[5] = operand_subword (operands[2], 0, 0, DImode);
6493    operands[6] = operand_subword (operands[0], 1, 0, DImode);
6494    operands[7] = operand_subword (operands[1], 1, 0, DImode);
6495    operands[8] = operand_subword (operands[2], 1, 0, DImode);")
6498 ; subsi3 instruction pattern(s).
6501 (define_expand "subsi3"
6502   [(parallel
6503     [(set (match_operand:SI 0 "register_operand" "")
6504           (minus:SI (match_operand:SI 1 "register_operand" "")
6505                     (match_operand:SI 2 "general_operand" "")))
6506      (clobber (reg:CC CC_REGNUM))])]
6507   ""
6508   "")
6510 (define_insn "*subsi3_sign"
6511   [(set (match_operand:SI 0 "register_operand" "=d,d")
6512         (minus:SI (match_operand:SI 1 "register_operand" "0,0")
6513                   (sign_extend:SI (match_operand:HI 2 "memory_operand" "R,T"))))
6514    (clobber (reg:CC CC_REGNUM))]
6515   ""
6516   "@
6517    sh\t%0,%2
6518    shy\t%0,%2"
6519   [(set_attr "op_type"  "RX,RXY")
6520    (set_attr "cpu_facility" "*,longdisp")
6521    (set_attr "z196prop" "z196_cracked,z196_cracked")])
6524 ; sub(di|si)3 instruction pattern(s).
6527 ; sr, s, sy, sgr, sg, srk, sgrk
6528 (define_insn "*sub<mode>3"
6529   [(set (match_operand:GPR 0 "register_operand"           "=d,d,d,d")
6530         (minus:GPR (match_operand:GPR 1 "register_operand" "0,d,0,0")
6531                    (match_operand:GPR 2 "general_operand"  "d,d,R,T") ) )
6532    (clobber (reg:CC CC_REGNUM))]
6533   ""
6534   "@
6535    s<g>r\t%0,%2
6536    s<g>rk\t%0,%1,%2
6537    s<g>\t%0,%2
6538    s<y>\t%0,%2"
6539   [(set_attr "op_type"  "RR<E>,RRF,RX<Y>,RXY")
6540    (set_attr "cpu_facility" "*,z196,*,longdisp")
6541    (set_attr "z10prop" "z10_super_c_E1,*,z10_super_E1,z10_super_E1")])
6543 ; slr, sl, sly, slgr, slg, slrk, slgrk
6544 (define_insn "*sub<mode>3_borrow_cc"
6545   [(set (reg CC_REGNUM)
6546         (compare (minus:GPR (match_operand:GPR 1 "register_operand" "0,d,0,0")
6547                             (match_operand:GPR 2 "general_operand"  "d,d,R,T"))
6548                  (match_dup 1)))
6549    (set (match_operand:GPR 0 "register_operand"                    "=d,d,d,d")
6550         (minus:GPR (match_dup 1) (match_dup 2)))]
6551   "s390_match_ccmode (insn, CCL2mode)"
6552   "@
6553    sl<g>r\t%0,%2
6554    sl<g>rk\t%0,%1,%2
6555    sl<g>\t%0,%2
6556    sl<y>\t%0,%2"
6557   [(set_attr "op_type"  "RR<E>,RRF,RX<Y>,RXY")
6558    (set_attr "cpu_facility" "*,z196,*,longdisp")
6559    (set_attr "z10prop" "z10_super_c_E1,*,z10_super_E1,z10_super_E1")])
6561 ; slr, sl, sly, slgr, slg, slrk, slgrk
6562 (define_insn "*sub<mode>3_borrow_cconly"
6563   [(set (reg CC_REGNUM)
6564         (compare (minus:GPR (match_operand:GPR 1 "register_operand" "0,d,0,0")
6565                             (match_operand:GPR 2 "general_operand"  "d,d,R,T"))
6566                  (match_dup 1)))
6567    (clobber (match_scratch:GPR 0                                   "=d,d,d,d"))]
6568   "s390_match_ccmode (insn, CCL2mode)"
6569   "@
6570    sl<g>r\t%0,%2
6571    sl<g>rk\t%0,%1,%2
6572    sl<g>\t%0,%2
6573    sl<y>\t%0,%2"
6574   [(set_attr "op_type"  "RR<E>,RRF,RX<Y>,RXY")
6575    (set_attr "cpu_facility" "*,z196,*,longdisp")
6576    (set_attr "z10prop" "z10_super_c_E1,*,z10_super_E1,z10_super_E1")])
6578 ; slr, sl, sly, slgr, slg, slrk, slgrk
6579 (define_insn "*sub<mode>3_cc"
6580   [(set (reg CC_REGNUM)
6581         (compare (minus:GPR (match_operand:GPR 1 "register_operand" "0,d,0,0")
6582                             (match_operand:GPR 2 "general_operand"  "d,d,R,T"))
6583                  (const_int 0)))
6584    (set (match_operand:GPR 0 "register_operand"                    "=d,d,d,d")
6585         (minus:GPR (match_dup 1) (match_dup 2)))]
6586   "s390_match_ccmode (insn, CCLmode)"
6587   "@
6588    sl<g>r\t%0,%2
6589    sl<g>rk\t%0,%1,%2
6590    sl<g>\t%0,%2
6591    sl<y>\t%0,%2"
6592   [(set_attr "op_type"  "RR<E>,RRF,RX<Y>,RXY")
6593    (set_attr "cpu_facility" "*,z196,*,longdisp")
6594    (set_attr "z10prop" "z10_super_c_E1,*,z10_super_E1,z10_super_E1")])
6596 ; slr, sl, sly, slgr, slg, slrk, slgrk
6597 (define_insn "*sub<mode>3_cc2"
6598   [(set (reg CC_REGNUM)
6599         (compare (match_operand:GPR 1 "register_operand" "0,d,0,0")
6600                  (match_operand:GPR 2 "general_operand"  "d,d,R,T")))
6601    (set (match_operand:GPR 0 "register_operand"         "=d,d,d,d")
6602         (minus:GPR (match_dup 1) (match_dup 2)))]
6603   "s390_match_ccmode (insn, CCL3mode)"
6604   "@
6605    sl<g>r\t%0,%2
6606    sl<g>rk\t%0,%1,%2
6607    sl<g>\t%0,%2
6608    sl<y>\t%0,%2"
6609   [(set_attr "op_type"  "RR<E>,RRF,RX<Y>,RXY")
6610    (set_attr "cpu_facility" "*,z196,*,longdisp")
6611    (set_attr "z10prop" "z10_super_c_E1,*,z10_super_E1,z10_super_E1")])
6613 ; slr, sl, sly, slgr, slg, slrk, slgrk
6614 (define_insn "*sub<mode>3_cconly"
6615   [(set (reg CC_REGNUM)
6616         (compare (minus:GPR (match_operand:GPR 1 "register_operand" "0,d,0,0")
6617                             (match_operand:GPR 2 "general_operand"  "d,d,R,T"))
6618                  (const_int 0)))
6619    (clobber (match_scratch:GPR 0                                   "=d,d,d,d"))]
6620   "s390_match_ccmode (insn, CCLmode)"
6621   "@
6622    sl<g>r\t%0,%2
6623    sl<g>rk\t%0,%1,%2
6624    sl<g>\t%0,%2
6625    sl<y>\t%0,%2"
6626   [(set_attr "op_type"  "RR<E>,RRF,RX<Y>,RXY")
6627    (set_attr "cpu_facility" "*,z196,*,longdisp")
6628    (set_attr "z10prop" "z10_super_c_E1,*,z10_super_E1,z10_super_E1")])
6631 ; slr, sl, sly, slgr, slg, slrk, slgrk
6632 (define_insn "*sub<mode>3_cconly2"
6633   [(set (reg CC_REGNUM)
6634         (compare (match_operand:GPR 1 "register_operand" "0,d,0,0")
6635                  (match_operand:GPR 2 "general_operand"  "d,d,R,T")))
6636    (clobber (match_scratch:GPR 0                        "=d,d,d,d"))]
6637   "s390_match_ccmode (insn, CCL3mode)"
6638   "@
6639    sl<g>r\t%0,%2
6640    sl<g>rk\t%0,%1,%2
6641    sl<g>\t%0,%2
6642    sl<y>\t%0,%2"
6643   [(set_attr "op_type"  "RR<E>,RRF,RX<Y>,RXY")
6644    (set_attr "cpu_facility" "*,z196,*,longdisp")
6645    (set_attr "z10prop" "z10_super_c_E1,*,z10_super_E1,z10_super_E1")])
6647 (define_insn "*subdi3_sign"
6648   [(set (match_operand:DI                           0 "register_operand" "=d")
6649         (minus:DI (match_operand:DI                 1 "register_operand"  "0")
6650                   (sign_extend:DI (match_operand:HI 2 "memory_operand"    "T"))))
6651    (clobber (reg:CC CC_REGNUM))]
6652   "TARGET_Z14"
6653   "sgh\t%0,%2"
6654   [(set_attr "op_type"  "RXY")])
6656 ; Jump to label OP3 if OP1 - OP2 results in a signed overflow
6657 (define_expand "subv<mode>4"
6658   [(parallel
6659     [(set (reg:CCO CC_REGNUM)
6660           (compare:CCO (minus:<DBL>
6661                         (sign_extend:<DBL> (match_operand:GPR 1 "nonimmediate_operand"))
6662                         (sign_extend:<DBL> (match_operand:GPR 2 "nonimmediate_operand")))
6663                        (sign_extend:<DBL> (minus:GPR (match_dup 1) (match_dup 2)))))
6664      (set (match_operand:GPR                                  0 "nonimmediate_operand")
6665           (minus:GPR (match_dup 1) (match_dup 2)))])
6666    (set (pc)
6667         (if_then_else (ne (reg:CCO CC_REGNUM) (const_int 0))
6668                       (label_ref (match_operand 3))
6669                       (pc)))]
6670   "")
6672 ; sr, s, sy, sgr, sg, srk, sgrk
6673 (define_insn "*subv<mode>3_ccoverflow"
6674   [(set (reg CC_REGNUM)
6675         (compare (minus:<DBL>
6676                   (sign_extend:<DBL> (match_operand:GPR 1 "nonimmediate_operand" "0,d,0,0"))
6677                   (sign_extend:<DBL> (match_operand:GPR 2 "nonimmediate_operand" "d,d,R,T")))
6678                  (sign_extend:<DBL> (minus:GPR (match_dup 1) (match_dup 2)))))
6679    (set (match_operand:GPR                              0 "register_operand"    "=d,d,d,d")
6680         (minus:GPR (match_dup 1) (match_dup 2)))]
6681   "s390_match_ccmode (insn, CCOmode)"
6682   "@
6683    s<g>r\t%0,%2
6684    s<g>rk\t%0,%1,%2
6685    s<g>\t%0,%2
6686    s<y>\t%0,%2"
6687   [(set_attr "op_type"  "RR<E>,RRF,RX<Y>,RXY")
6688    (set_attr "cpu_facility" "*,z196,*,longdisp")
6689    (set_attr "z10prop" "z10_super_c_E1,*,z10_super_E1,z10_super_E1")])
6693 ; sub(tf|df|sf|td|dd)3 instruction pattern(s).
6696 ; FIXME: (clobber (match_scratch:CC 3 "=c,c,c,X,X")) does not work - why?
6697 ; sxbr, sdbr, sebr, sdb, seb, sxtr, sdtr
6698 (define_insn "sub<mode>3<tf_fpr>"
6699   [(set (match_operand:FP           0 "register_operand" "=f,f,f,v,v")
6700         (minus:FP (match_operand:FP 1 "register_operand"  "f,0,0,v,v")
6701                   (match_operand:FP 2 "general_operand"   "f,f,R,v,v")))
6702    (clobber (reg:CC CC_REGNUM))]
6703   "TARGET_HARD_FLOAT"
6704   "@
6705    s<xde>tr\t%0,%1,%2
6706    s<xde>br\t%0,%2
6707    s<xde>b\t%0,%2
6708    wfsdb\t%v0,%v1,%v2
6709    wfssb\t%v0,%v1,%v2"
6710   [(set_attr "op_type"      "RRF,RRE,RXE,VRR,VRR")
6711    (set_attr "type"         "fsimp<type>")
6712    (set_attr "cpu_facility" "*,*,*,vx,vxe")
6713    (set_attr "enabled"      "<nBFP>,<nDFP>,<DSF>,<DF>,<SF>")])
6715 ; sxbr, sdbr, sebr, sdb, seb, sxtr, sdtr
6716 (define_insn "*sub<mode>3_cc"
6717   [(set (reg CC_REGNUM)
6718         (compare (minus:FP (match_operand:FP 1 "nonimmediate_operand" "f,0,0")
6719                            (match_operand:FP 2 "general_operand"      "f,f,R"))
6720                  (match_operand:FP 3 "const0_operand" "")))
6721    (set (match_operand:FP 0 "register_operand" "=f,f,f")
6722         (minus:FP (match_dup 1) (match_dup 2)))]
6723   "s390_match_ccmode (insn, CCSmode) && TARGET_HARD_FLOAT"
6724   "@
6725    s<xde>tr\t%0,%1,%2
6726    s<xde>br\t%0,%2
6727    s<xde>b\t%0,%2"
6728   [(set_attr "op_type"  "RRF,RRE,RXE")
6729    (set_attr "type"     "fsimp<type>")
6730    (set_attr "enabled"  "<nBFP>,<nDFP>,<DSF>")])
6732 ; sxbr, sdbr, sebr, sdb, seb, sxtr, sdtr
6733 (define_insn "*sub<mode>3_cconly"
6734   [(set (reg CC_REGNUM)
6735         (compare (minus:FP (match_operand:FP 1 "nonimmediate_operand" "f,0,0")
6736                            (match_operand:FP 2 "general_operand"      "f,f,R"))
6737                  (match_operand:FP 3 "const0_operand" "")))
6738    (clobber (match_scratch:FP 0 "=f,f,f"))]
6739   "s390_match_ccmode (insn, CCSmode) && TARGET_HARD_FLOAT"
6740   "@
6741    s<xde>tr\t%0,%1,%2
6742    s<xde>br\t%0,%2
6743    s<xde>b\t%0,%2"
6744   [(set_attr "op_type"  "RRF,RRE,RXE")
6745    (set_attr "type"     "fsimp<type>")
6746    (set_attr "enabled"  "<nBFP>,<nDFP>,<DSF>")])
6750 ;;- Conditional add/subtract instructions.
6754 ; add(di|si)cc instruction pattern(s).
6757 ; the following 4 patterns are used when the result of an add with
6758 ; carry is checked for an overflow condition
6760 ; op1 + op2 + c < op1
6762 ; alcr, alc, alcgr, alcg
6763 (define_insn "*add<mode>3_alc_carry1_cc"
6764   [(set (reg CC_REGNUM)
6765         (compare
6766           (plus:GPR (plus:GPR (match_operand:GPR 3 "s390_alc_comparison" "")
6767                               (match_operand:GPR 1 "nonimmediate_operand" "%0,0"))
6768                     (match_operand:GPR 2 "general_operand" "d,T"))
6769           (match_dup 1)))
6770    (set (match_operand:GPR 0 "register_operand" "=d,d")
6771         (plus:GPR (plus:GPR (match_dup 3) (match_dup 1)) (match_dup 2)))]
6772   "s390_match_ccmode (insn, CCL1mode)"
6773   "@
6774    alc<g>r\t%0,%2
6775    alc<g>\t%0,%2"
6776   [(set_attr "op_type"  "RRE,RXY")
6777    (set_attr "z196prop" "z196_alone,z196_alone")])
6779 ; alcr, alc, alcgr, alcg
6780 (define_insn "*add<mode>3_alc_carry1_cconly"
6781   [(set (reg CC_REGNUM)
6782         (compare
6783           (plus:GPR (plus:GPR (match_operand:GPR 3 "s390_alc_comparison" "")
6784                               (match_operand:GPR 1 "nonimmediate_operand" "%0,0"))
6785                     (match_operand:GPR 2 "general_operand" "d,T"))
6786           (match_dup 1)))
6787    (clobber (match_scratch:GPR 0 "=d,d"))]
6788   "s390_match_ccmode (insn, CCL1mode)"
6789   "@
6790    alc<g>r\t%0,%2
6791    alc<g>\t%0,%2"
6792   [(set_attr "op_type"  "RRE,RXY")
6793    (set_attr "z196prop" "z196_alone,z196_alone")])
6795 ; op1 + op2 + c < op2
6797 ; alcr, alc, alcgr, alcg
6798 (define_insn "*add<mode>3_alc_carry2_cc"
6799   [(set (reg CC_REGNUM)
6800         (compare
6801           (plus:GPR (plus:GPR (match_operand:GPR 3 "s390_alc_comparison" "")
6802                               (match_operand:GPR 1 "nonimmediate_operand" "%0,0"))
6803                     (match_operand:GPR 2 "general_operand" "d,T"))
6804           (match_dup 2)))
6805    (set (match_operand:GPR 0 "register_operand" "=d,d")
6806         (plus:GPR (plus:GPR (match_dup 3) (match_dup 1)) (match_dup 2)))]
6807   "s390_match_ccmode (insn, CCL1mode)"
6808   "@
6809    alc<g>r\t%0,%2
6810    alc<g>\t%0,%2"
6811   [(set_attr "op_type"  "RRE,RXY")])
6813 ; alcr, alc, alcgr, alcg
6814 (define_insn "*add<mode>3_alc_carry2_cconly"
6815   [(set (reg CC_REGNUM)
6816         (compare
6817           (plus:GPR (plus:GPR (match_operand:GPR 3 "s390_alc_comparison" "")
6818                               (match_operand:GPR 1 "nonimmediate_operand" "%0,0"))
6819                     (match_operand:GPR 2 "general_operand" "d,T"))
6820           (match_dup 2)))
6821    (clobber (match_scratch:GPR 0 "=d,d"))]
6822   "s390_match_ccmode (insn, CCL1mode)"
6823   "@
6824    alc<g>r\t%0,%2
6825    alc<g>\t%0,%2"
6826   [(set_attr "op_type"  "RRE,RXY")])
6828 ; alcr, alc, alcgr, alcg
6829 (define_insn "*add<mode>3_alc_cc"
6830   [(set (reg CC_REGNUM)
6831         (compare
6832           (plus:GPR (plus:GPR (match_operand:GPR 3 "s390_alc_comparison" "")
6833                               (match_operand:GPR 1 "nonimmediate_operand" "%0,0"))
6834                     (match_operand:GPR 2 "general_operand" "d,T"))
6835           (const_int 0)))
6836    (set (match_operand:GPR 0 "register_operand" "=d,d")
6837         (plus:GPR (plus:GPR (match_dup 3) (match_dup 1)) (match_dup 2)))]
6838   "s390_match_ccmode (insn, CCLmode)"
6839   "@
6840    alc<g>r\t%0,%2
6841    alc<g>\t%0,%2"
6842   [(set_attr "op_type"  "RRE,RXY")])
6844 ; alcr, alc, alcgr, alcg
6845 (define_insn "*add<mode>3_alc"
6846   [(set (match_operand:GPR 0 "register_operand" "=d,d")
6847         (plus:GPR (plus:GPR (match_operand:GPR 3 "s390_alc_comparison" "")
6848                             (match_operand:GPR 1 "nonimmediate_operand" "%0,0"))
6849                   (match_operand:GPR 2 "general_operand" "d,T")))
6850    (clobber (reg:CC CC_REGNUM))]
6851   ""
6852   "@
6853    alc<g>r\t%0,%2
6854    alc<g>\t%0,%2"
6855   [(set_attr "op_type"  "RRE,RXY")])
6857 ; slbr, slb, slbgr, slbg
6858 (define_insn "*sub<mode>3_slb_cc"
6859   [(set (reg CC_REGNUM)
6860         (compare
6861           (minus:GPR (minus:GPR (match_operand:GPR 1 "nonimmediate_operand" "0,0")
6862                                 (match_operand:GPR 2 "general_operand" "d,T"))
6863                      (match_operand:GPR 3 "s390_slb_comparison" ""))
6864           (const_int 0)))
6865    (set (match_operand:GPR 0 "register_operand" "=d,d")
6866         (minus:GPR (minus:GPR (match_dup 1) (match_dup 2)) (match_dup 3)))]
6867   "s390_match_ccmode (insn, CCLmode)"
6868   "@
6869    slb<g>r\t%0,%2
6870    slb<g>\t%0,%2"
6871   [(set_attr "op_type"  "RRE,RXY")
6872    (set_attr "z10prop" "z10_c,*")])
6874 ; slbr, slb, slbgr, slbg
6875 (define_insn "*sub<mode>3_slb"
6876   [(set (match_operand:GPR 0 "register_operand" "=d,d")
6877         (minus:GPR (minus:GPR (match_operand:GPR 1 "nonimmediate_operand" "0,0")
6878                               (match_operand:GPR 2 "general_operand" "d,T"))
6879                    (match_operand:GPR 3 "s390_slb_comparison" "")))
6880    (clobber (reg:CC CC_REGNUM))]
6881   ""
6882   "@
6883    slb<g>r\t%0,%2
6884    slb<g>\t%0,%2"
6885   [(set_attr "op_type"  "RRE,RXY")
6886    (set_attr "z10prop" "z10_c,*")])
6888 (define_expand "add<mode>cc"
6889   [(match_operand:GPR 0 "register_operand" "")
6890    (match_operand 1 "comparison_operator" "")
6891    (match_operand:GPR 2 "register_operand" "")
6892    (match_operand:GPR 3 "const_int_operand" "")]
6893   ""
6894   "if (!s390_expand_addcc (GET_CODE (operands[1]),
6895                            XEXP (operands[1], 0), XEXP (operands[1], 1),
6896                            operands[0], operands[2],
6897                            operands[3])) FAIL; DONE;")
6900 ; scond instruction pattern(s).
6903 (define_insn_and_split "*scond<mode>"
6904   [(set (match_operand:GPR 0 "register_operand" "=&d")
6905         (match_operand:GPR 1 "s390_alc_comparison" ""))
6906    (clobber (reg:CC CC_REGNUM))]
6907   ""
6908   "#"
6909   "&& reload_completed"
6910   [(set (match_dup 0) (const_int 0))
6911    (parallel
6912     [(set (match_dup 0) (plus:GPR (plus:GPR (match_dup 1) (match_dup 0))
6913                                   (match_dup 0)))
6914      (clobber (reg:CC CC_REGNUM))])]
6915   "")
6917 (define_insn_and_split "*scond<mode>_neg"
6918   [(set (match_operand:GPR 0 "register_operand" "=&d")
6919         (match_operand:GPR 1 "s390_slb_comparison" ""))
6920    (clobber (reg:CC CC_REGNUM))]
6921   ""
6922   "#"
6923   "&& reload_completed"
6924   [(set (match_dup 0) (const_int 0))
6925    (parallel
6926     [(set (match_dup 0) (minus:GPR (minus:GPR (match_dup 0) (match_dup 0))
6927                                    (match_dup 1)))
6928      (clobber (reg:CC CC_REGNUM))])
6929    (parallel
6930     [(set (match_dup 0) (neg:GPR (match_dup 0)))
6931      (clobber (reg:CC CC_REGNUM))])]
6932   "")
6935 (define_expand "cstore<mode>4"
6936   [(set (match_operand:SI 0 "register_operand" "")
6937         (match_operator:SI 1 "s390_scond_operator"
6938          [(match_operand:GPR 2 "register_operand" "")
6939           (match_operand:GPR 3 "general_operand" "")]))]
6940   ""
6941   "if (!s390_expand_addcc (GET_CODE (operands[1]), operands[2], operands[3],
6942                            operands[0], const0_rtx, const1_rtx)) FAIL; DONE;")
6944 (define_expand "cstorecc4"
6945   [(parallel
6946     [(set (match_operand:SI 0 "register_operand" "")
6947           (match_operator:SI 1 "s390_eqne_operator"
6948            [(match_operand 2 "cc_reg_operand")
6949             (match_operand 3 "const_mask_operand")]))
6950      (clobber (reg:CC CC_REGNUM))])]
6951   ""
6952   "machine_mode mode = GET_MODE (operands[2]);
6953    if (TARGET_Z196)
6954      {
6955        rtx cond, ite;
6957        if (GET_CODE (operands[1]) == NE)
6958          cond = gen_rtx_NE (VOIDmode, operands[2], operands[3]);
6959        else
6960          cond = gen_rtx_EQ (VOIDmode, operands[2], operands[3]);
6961        ite = gen_rtx_IF_THEN_ELSE (SImode, cond, const1_rtx, const0_rtx);
6962        emit_insn (gen_rtx_SET (operands[0], ite));
6963      }
6964    else
6965      {
6966        if (mode != CCZ1mode || operands[3] != const0_rtx)
6967          FAIL;
6968        emit_insn (gen_sne (operands[0], operands[2]));
6969        if (GET_CODE (operands[1]) == EQ)
6970          emit_insn (gen_xorsi3 (operands[0], operands[0], const1_rtx));
6971      }
6972    DONE;")
6974 (define_insn_and_split "sne"
6975   [(set (match_operand:SI 0 "register_operand" "=d")
6976         (ne:SI (match_operand:CCZ1 1 "register_operand" "0")
6977                (const_int 0)))
6978    (clobber (reg:CC CC_REGNUM))]
6979   ""
6980   "#"
6981   "reload_completed"
6982   [(parallel
6983     [(set (match_dup 0) (ashiftrt:SI (match_dup 0) (const_int 28)))
6984      (clobber (reg:CC CC_REGNUM))])])
6986 ; Such patterns get directly emitted by noce_emit_store_flag.
6987 (define_insn_and_split "*cstorecc<mode>_z13"
6988   [(set (match_operand:GPR  0 "register_operand"                "=&d")
6989         (match_operator:GPR 1 "s390_comparison"
6990                             [(match_operand 2 "cc_reg_operand"    "c")
6991                              (match_operand 3 "const_int_operand"  "")]))]
6992   "TARGET_Z13"
6993   "#"
6994   "reload_completed"
6995   [(set (match_dup 0) (const_int 0))
6996    (set (match_dup 0)
6997         (if_then_else:GPR
6998          (match_op_dup 1 [(match_dup 2) (match_dup 3)])
6999          (const_int 1)
7000          (match_dup 0)))])
7003 ;; - Conditional move instructions (introduced with z196)
7006 (define_expand "mov<mode>cc"
7007   [(set (match_operand:GPR 0 "nonimmediate_operand" "")
7008         (if_then_else:GPR (match_operand 1 "comparison_operator" "")
7009                           (match_operand:GPR 2 "loc_operand" "")
7010                           (match_operand:GPR 3 "loc_operand" "")))]
7011   "TARGET_Z196"
7013   if (!TARGET_Z13 && CONSTANT_P (operands[2]))
7014     operands[2] = force_reg (<MODE>mode, operands[2]);
7016   if (!TARGET_Z13 && CONSTANT_P (operands[3]))
7017     operands[3] = force_reg (<MODE>mode, operands[3]);
7019   /* Emit the comparison insn in case we do not already have a comparison result.  */
7020   if (!s390_comparison (operands[1], VOIDmode))
7021     operands[1] = s390_emit_compare (GET_CODE (operands[1]),
7022                                      XEXP (operands[1], 0),
7023                                      XEXP (operands[1], 1));
7027 ;; - We do not have instructions for QImode or HImode but still
7028 ;;   enable load on condition/if conversion for them.
7029 (define_expand "mov<mode>cc"
7030  [(set (match_operand:HQI 0 "nonimmediate_operand" "")
7031         (if_then_else:HQI (match_operand 1 "comparison_operator" "")
7032                 (match_operand:HQI 2 "loc_operand" "")
7033                 (match_operand:HQI 3 "loc_operand" "")))]
7034  "TARGET_Z196"
7036   /* Emit the comparison insn in case we do not already have a comparison
7037      result. */
7038   if (!s390_comparison (operands[1], VOIDmode))
7039     operands[1] = s390_emit_compare (GET_CODE (operands[1]),
7040                               XEXP (operands[1], 0),
7041                               XEXP (operands[1], 1));
7043   rtx then = operands[2];
7044   rtx els = operands[3];
7046   if ((!TARGET_Z13 && CONSTANT_P (then)) || MEM_P (then))
7047         then = force_reg (<MODE>mode, then);
7048   if ((!TARGET_Z13 && CONSTANT_P (els)) || MEM_P (els))
7049         els = force_reg (<MODE>mode, els);
7051   if (!CONSTANT_P (then))
7052     then = simplify_gen_subreg (E_SImode, then, <MODE>mode, 0);
7053   if (!CONSTANT_P (els))
7054     els = simplify_gen_subreg (E_SImode, els, <MODE>mode, 0);
7056   rtx tmp_target = simplify_gen_subreg (E_SImode, operands[0], <MODE>mode, 0);
7058   emit_insn (gen_movsicc (tmp_target, operands[1], then, els));
7059   DONE;
7064 ; locr, loc, stoc, locgr, locg, stocg, lochi, locghi, selr, selgr
7065 (define_insn "*mov<mode>cc"
7066   [(set (match_operand:GPR 0 "nonimmediate_operand" "=d,d,d,d,d,d,d,S,S")
7067         (if_then_else:GPR
7068           (match_operator 1 "s390_comparison"
7069             [(match_operand 2 "cc_reg_operand"      " c,c,c,c,c,c,c,c,c")
7070              (match_operand 5 "const_int_operand"   "")])
7071           (match_operand:GPR 3 "loc_operand"        " d,0,d,S,0,K,0,d,0")
7072           (match_operand:GPR 4 "loc_operand"        " 0,d,d,0,S,0,K,0,d")))]
7073   "TARGET_Z196"
7074   "@
7075    loc<g>r%C1\t%0,%3
7076    loc<g>r%D1\t%0,%4
7077    sel<g>r%C1\t%0,%3,%4
7078    loc<g>%C1\t%0,%3
7079    loc<g>%D1\t%0,%4
7080    loc<g>hi%C1\t%0,%h3
7081    loc<g>hi%D1\t%0,%h4
7082    stoc<g>%C1\t%3,%0
7083    stoc<g>%D1\t%4,%0"
7084   [(set_attr "op_type" "RRF,RRF,RRF,RSY,RSY,RIE,RIE,RSY,RSY")
7085    (set_attr "cpu_facility" "*,*,z15,*,*,z13,z13,*,*")])
7088 ;;- Multiply instructions.
7092 ; muldi3 instruction pattern(s).
7095 (define_expand "muldi3"
7096   [(parallel
7097     [(set (match_operand:DI          0 "register_operand")
7098           (mult:DI (match_operand:DI 1 "nonimmediate_operand")
7099                    (match_operand:DI 2 "general_operand")))
7100      (clobber (reg:CC CC_REGNUM))])]
7101   "TARGET_ZARCH")
7103 (define_insn "*muldi3_sign"
7104   [(set (match_operand:DI 0 "register_operand" "=d,d")
7105         (mult:DI (sign_extend:DI (match_operand:SI 2 "general_operand" "d,T"))
7106                  (match_operand:DI 1 "register_operand" "0,0")))]
7107   "TARGET_ZARCH"
7108   "@
7109    msgfr\t%0,%2
7110    msgf\t%0,%2"
7111   [(set_attr "op_type"      "RRE,RXY")
7112    (set_attr "type"         "imuldi")])
7114 (define_insn "*muldi3"
7115   [(set (match_operand:DI          0 "register_operand"     "=d,d,d,d,d")
7116         (mult:DI (match_operand:DI 1 "nonimmediate_operand" "%0,d,0,0,0")
7117                  (match_operand:DI 2 "general_operand"       "d,d,K,T,Os")))
7118    (clobber (match_scratch:CC      3                        "=X,c,X,X,X"))]
7119   "TARGET_ZARCH"
7120   "@
7121    msgr\t%0,%2
7122    msgrkc\t%0,%1,%2
7123    mghi\t%0,%h2
7124    msg\t%0,%2
7125    msgfi\t%0,%2"
7126   [(set_attr "op_type"      "RRE,RRF,RI,RXY,RIL")
7127    (set_attr "type"         "imuldi")
7128    (set_attr "cpu_facility" "*,z14,*,*,z10")])
7130 (define_insn "mulditi3"
7131   [(set (match_operand:TI 0 "register_operand"               "=d,d")
7132         (mult:TI (sign_extend:TI
7133                   (match_operand:DI 1 "register_operand"     "%d,0"))
7134                  (sign_extend:TI
7135                   (match_operand:DI 2 "nonimmediate_operand" " d,T"))))]
7136   "TARGET_Z14"
7137   "@
7138    mgrk\t%0,%1,%2
7139    mg\t%0,%2"
7140   [(set_attr "op_type"  "RRF,RXY")])
7142 ; Combine likes op1 and op2 to be swapped sometimes.
7143 (define_insn "mulditi3_2"
7144   [(set (match_operand:TI 0 "register_operand"               "=d,d")
7145         (mult:TI (sign_extend:TI
7146                   (match_operand:DI 1 "nonimmediate_operand" "%d,T"))
7147                  (sign_extend:TI
7148                   (match_operand:DI 2 "register_operand"     " d,0"))))]
7149   "TARGET_Z14"
7150   "@
7151    mgrk\t%0,%1,%2
7152    mg\t%0,%1"
7153   [(set_attr "op_type"  "RRF,RXY")])
7155 (define_insn "*muldi3_sign"
7156   [(set (match_operand:DI                          0 "register_operand" "=d")
7157         (mult:DI (sign_extend:DI (match_operand:HI 2 "memory_operand"    "T"))
7158                  (match_operand:DI                 1 "register_operand"  "0")))]
7159   "TARGET_Z14"
7160   "mgh\t%0,%2"
7161   [(set_attr "op_type" "RXY")])
7165 ; mulsi3 instruction pattern(s).
7168 (define_expand "mulsi3"
7169   [(parallel
7170     [(set (match_operand:SI           0 "register_operand"     "=d,d,d,d,d,d")
7171           (mult:SI  (match_operand:SI 1 "nonimmediate_operand" "%0,d,0,0,0,0")
7172                     (match_operand:SI 2 "general_operand"       "d,d,K,R,T,Os")))
7173      (clobber (reg:CC CC_REGNUM))])]
7174   "")
7176 (define_insn "*mulsi3_sign"
7177   [(set (match_operand:SI 0 "register_operand" "=d,d")
7178         (mult:SI (sign_extend:SI (match_operand:HI 2 "memory_operand" "R,T"))
7179                  (match_operand:SI 1 "register_operand" "0,0")))]
7180   ""
7181   "@
7182    mh\t%0,%2
7183    mhy\t%0,%2"
7184   [(set_attr "op_type"      "RX,RXY")
7185    (set_attr "type"         "imulhi")
7186    (set_attr "cpu_facility" "*,z10")])
7188 (define_insn "*mulsi3"
7189   [(set (match_operand:SI           0 "register_operand"     "=d,d,d,d,d,d")
7190         (mult:SI  (match_operand:SI 1 "nonimmediate_operand" "%0,d,0,0,0,0")
7191                   (match_operand:SI 2 "general_operand"       "d,d,K,R,T,Os")))
7192    (clobber (match_scratch:CC       3                        "=X,c,X,X,X,X"))]
7193   ""
7194   "@
7195    msr\t%0,%2
7196    msrkc\t%0,%1,%2
7197    mhi\t%0,%h2
7198    ms\t%0,%2
7199    msy\t%0,%2
7200    msfi\t%0,%2"
7201   [(set_attr "op_type"      "RRE,RRF,RI,RX,RXY,RIL")
7202    (set_attr "type"         "imulsi,*,imulhi,imulsi,imulsi,imulsi")
7203    (set_attr "cpu_facility" "*,z14,*,*,longdisp,z10")])
7206 ; mulsidi3 instruction pattern(s).
7209 (define_insn "mulsidi3"
7210   [(set (match_operand:DI 0 "register_operand" "=d,d,d")
7211         (mult:DI (sign_extend:DI
7212                    (match_operand:SI 1 "register_operand" "%0,0,0"))
7213                  (sign_extend:DI
7214                    (match_operand:SI 2 "nonimmediate_operand" "d,R,T"))))]
7215   "!TARGET_ZARCH"
7216   "@
7217    mr\t%0,%2
7218    m\t%0,%2
7219    mfy\t%0,%2"
7220   [(set_attr "op_type"      "RR,RX,RXY")
7221    (set_attr "type"         "imulsi")
7222    (set_attr "cpu_facility" "*,*,z10")])
7224 ; Jump to label OP3 if OP1 * OP2 results in a signed overflow
7225 (define_expand "mulv<mode>4"
7226   [(parallel
7227     [(set (reg:CCO CC_REGNUM)
7228           (compare:CCO (mult:<DBL>
7229                          (sign_extend:<DBL> (match_operand:GPR 1 "register_operand"))
7230                          (sign_extend:<DBL> (match_operand:GPR 2 "nonimmediate_operand")))
7231                         (sign_extend:<DBL> (mult:GPR (match_dup 1) (match_dup 2)))))
7232      (set (match_operand:GPR 0 "register_operand")
7233           (mult:GPR (match_dup 1) (match_dup 2)))])
7234    (set (pc)
7235         (if_then_else (ne (reg:CCO CC_REGNUM) (const_int 0))
7236                       (label_ref (match_operand 3))
7237                       (pc)))]
7238   "TARGET_Z14")
7240 ; msrkc, msc, msgrkc, msgc
7241 (define_insn "*mulv<mode>3_ccoverflow"
7242   [(set (reg CC_REGNUM)
7243         (compare (mult:<DBL>
7244                   (sign_extend:<DBL> (match_operand:GPR 1 "register_operand"     "%d,0"))
7245                   (sign_extend:<DBL> (match_operand:GPR 2 "nonimmediate_operand" " d,T")))
7246                  (sign_extend:<DBL> (mult:GPR (match_dup 1) (match_dup 2)))))
7247    (set (match_operand:GPR                              0 "register_operand"     "=d,d")
7248         (mult:GPR (match_dup 1) (match_dup 2)))]
7249   "s390_match_ccmode (insn, CCOmode) && TARGET_Z14"
7250   "@
7251    ms<g>rkc\t%0,%1,%2
7252    ms<g>c\t%0,%2"
7253   [(set_attr "op_type"  "RRF,RXY")])
7257 ; umul instruction pattern(s).
7260 ; mlr, ml, mlgr, mlg
7261 (define_insn "umul<dwh><mode>3"
7262   [(set (match_operand:DW 0 "register_operand"                   "=d,d")
7263         (mult:DW (zero_extend:DW
7264                    (match_operand:<DWH> 1 "register_operand"     "%0,0"))
7265                  (zero_extend:DW
7266                    (match_operand:<DWH> 2 "nonimmediate_operand" " d,T"))))]
7267   ""
7268   "@
7269    ml<tg>r\t%0,%2
7270    ml<tg>\t%0,%2"
7271   [(set_attr "op_type"  "RRE,RXY")
7272    (set_attr "type"     "imul<dwh>")])
7275 ; mul(tf|df|sf|td|dd)3 instruction pattern(s).
7278 ; mxbr, mdbr, meebr, mxb, mxb, meeb, mdtr, mxtr
7279 (define_insn "mul<mode>3<tf_fpr>"
7280   [(set (match_operand:FP          0 "register_operand"     "=f,f,f,v,v")
7281         (mult:FP (match_operand:FP 1 "nonimmediate_operand" "%f,0,0,v,v")
7282                  (match_operand:FP 2 "general_operand"       "f,f,R,v,v")))]
7283   "TARGET_HARD_FLOAT"
7284   "@
7285    m<xdee>tr\t%0,%1,%2
7286    m<xdee>br\t%0,%2
7287    m<xdee>b\t%0,%2
7288    wfmdb\t%v0,%v1,%v2
7289    wfmsb\t%v0,%v1,%v2"
7290   [(set_attr "op_type"      "RRF,RRE,RXE,VRR,VRR")
7291    (set_attr "type"         "fmul<type>")
7292    (set_attr "cpu_facility" "*,*,*,vx,vxe")
7293    (set_attr "enabled"      "<nBFP>,<nDFP>,<DSF>,<DF>,<SF>")])
7295 ; madbr, maebr, maxb, madb, maeb
7296 (define_insn "fma<mode>4"
7297   [(set (match_operand:DSF          0 "register_operand"     "=f,f,v,v")
7298         (fma:DSF (match_operand:DSF 1 "nonimmediate_operand" "%f,f,v,v")
7299                  (match_operand:DSF 2 "nonimmediate_operand"  "f,R,v,v")
7300                  (match_operand:DSF 3 "register_operand"      "0,0,v,v")))]
7301   "TARGET_HARD_FLOAT && s390_fma_allowed_p (<MODE>mode)"
7302   "@
7303    ma<xde>br\t%0,%1,%2
7304    ma<xde>b\t%0,%1,%2
7305    wfmadb\t%v0,%v1,%v2,%v3
7306    wfmasb\t%v0,%v1,%v2,%v3"
7307   [(set_attr "op_type"      "RRE,RXE,VRR,VRR")
7308    (set_attr "type"         "fmadd<mode>")
7309    (set_attr "cpu_facility" "*,*,vx,vxe")
7310    (set_attr "enabled"      "*,*,<DF>,<SF>")])
7312 ; msxbr, msdbr, msebr, msxb, msdb, mseb
7313 (define_insn "fms<mode>4"
7314   [(set (match_operand:DSF                   0 "register_operand"     "=f,f,v,v")
7315         (fma:DSF (match_operand:DSF          1 "nonimmediate_operand" "%f,f,v,v")
7316                  (match_operand:DSF          2 "nonimmediate_operand"  "f,R,v,v")
7317                  (neg:DSF (match_operand:DSF 3 "register_operand"      "0,0,v,v"))))]
7318   "TARGET_HARD_FLOAT && s390_fma_allowed_p (<MODE>mode)"
7319   "@
7320    ms<xde>br\t%0,%1,%2
7321    ms<xde>b\t%0,%1,%2
7322    wfmsdb\t%v0,%v1,%v2,%v3
7323    wfmssb\t%v0,%v1,%v2,%v3"
7324   [(set_attr "op_type"      "RRE,RXE,VRR,VRR")
7325    (set_attr "type"         "fmadd<mode>")
7326    (set_attr "cpu_facility" "*,*,vx,vxe")
7327    (set_attr "enabled"      "*,*,<DF>,<SF>")])
7330 ;;- Divide and modulo instructions.
7334 ; divmoddi4 instruction pattern(s).
7337 (define_expand "divmoddi4"
7338   [(parallel [(set (match_operand:DI 0 "general_operand" "")
7339                    (div:DI (match_operand:DI 1 "register_operand" "")
7340                            (match_operand:DI 2 "general_operand" "")))
7341               (set (match_operand:DI 3 "general_operand" "")
7342                    (mod:DI (match_dup 1) (match_dup 2)))])
7343    (clobber (match_dup 4))]
7344   "TARGET_ZARCH"
7346   rtx div_equal, mod_equal;
7347   rtx_insn *insn;
7349   div_equal = gen_rtx_DIV (DImode, operands[1], operands[2]);
7350   mod_equal = gen_rtx_MOD (DImode, operands[1], operands[2]);
7352   operands[4] = gen_reg_rtx(TImode);
7353   emit_insn (gen_divmodtidi3 (operands[4], operands[1], operands[2]));
7355   insn = emit_move_insn (operands[0], gen_lowpart (DImode, operands[4]));
7356   set_unique_reg_note (insn, REG_EQUAL, div_equal);
7358   insn = emit_move_insn (operands[3], gen_highpart (DImode, operands[4]));
7359   set_unique_reg_note (insn, REG_EQUAL, mod_equal);
7361   DONE;
7364 (define_insn "divmodtidi3"
7365   [(set (match_operand:TI 0 "register_operand" "=d,d")
7366         (ior:TI
7367           (ashift:TI
7368             (zero_extend:TI
7369               (mod:DI (match_operand:DI 1 "register_operand" "0,0")
7370                       (match_operand:DI 2 "general_operand" "d,T")))
7371             (const_int 64))
7372           (zero_extend:TI (div:DI (match_dup 1) (match_dup 2)))))]
7373   "TARGET_ZARCH"
7374   "@
7375    dsgr\t%0,%2
7376    dsg\t%0,%2"
7377   [(set_attr "op_type"  "RRE,RXY")
7378    (set_attr "type"     "idiv")])
7380 (define_insn "divmodtisi3"
7381   [(set (match_operand:TI 0 "register_operand" "=d,d")
7382         (ior:TI
7383           (ashift:TI
7384             (zero_extend:TI
7385               (mod:DI (match_operand:DI 1 "register_operand" "0,0")
7386                       (sign_extend:DI
7387                         (match_operand:SI 2 "nonimmediate_operand" "d,T"))))
7388             (const_int 64))
7389           (zero_extend:TI
7390             (div:DI (match_dup 1) (sign_extend:DI (match_dup 2))))))]
7391   "TARGET_ZARCH"
7392   "@
7393    dsgfr\t%0,%2
7394    dsgf\t%0,%2"
7395   [(set_attr "op_type"  "RRE,RXY")
7396    (set_attr "type"     "idiv")])
7399 ; udivmoddi4 instruction pattern(s).
7402 (define_expand "udivmoddi4"
7403   [(parallel [(set (match_operand:DI 0 "general_operand" "")
7404                    (udiv:DI (match_operand:DI 1 "general_operand" "")
7405                             (match_operand:DI 2 "nonimmediate_operand" "")))
7406               (set (match_operand:DI 3 "general_operand" "")
7407                    (umod:DI (match_dup 1) (match_dup 2)))])
7408    (clobber (match_dup 4))]
7409   "TARGET_ZARCH"
7411   rtx div_equal, mod_equal, equal;
7412   rtx_insn *insn;
7414   div_equal = gen_rtx_UDIV (DImode, operands[1], operands[2]);
7415   mod_equal = gen_rtx_UMOD (DImode, operands[1], operands[2]);
7416   equal = gen_rtx_IOR (TImode,
7417                        gen_rtx_ASHIFT (TImode,
7418                                        gen_rtx_ZERO_EXTEND (TImode, mod_equal),
7419                                        GEN_INT (64)),
7420                        gen_rtx_ZERO_EXTEND (TImode, div_equal));
7422   operands[4] = gen_reg_rtx(TImode);
7423   emit_clobber (operands[4]);
7424   emit_move_insn (gen_lowpart (DImode, operands[4]), operands[1]);
7425   emit_move_insn (gen_highpart (DImode, operands[4]), const0_rtx);
7427   insn = emit_insn (gen_udivmodtidi3 (operands[4], operands[4], operands[2]));
7428   set_unique_reg_note (insn, REG_EQUAL, equal);
7430   insn = emit_move_insn (operands[0], gen_lowpart (DImode, operands[4]));
7431   set_unique_reg_note (insn, REG_EQUAL, div_equal);
7433   insn = emit_move_insn (operands[3], gen_highpart (DImode, operands[4]));
7434   set_unique_reg_note (insn, REG_EQUAL, mod_equal);
7436   DONE;
7439 (define_insn "udivmodtidi3"
7440   [(set (match_operand:TI 0 "register_operand" "=d,d")
7441         (ior:TI
7442           (ashift:TI
7443             (zero_extend:TI
7444               (truncate:DI
7445                 (umod:TI (match_operand:TI 1 "register_operand" "0,0")
7446                          (zero_extend:TI
7447                            (match_operand:DI 2 "nonimmediate_operand" "d,T")))))
7448             (const_int 64))
7449           (zero_extend:TI
7450             (truncate:DI
7451               (udiv:TI (match_dup 1) (zero_extend:TI (match_dup 2)))))))]
7452   "TARGET_ZARCH"
7453   "@
7454    dlgr\t%0,%2
7455    dlg\t%0,%2"
7456   [(set_attr "op_type"  "RRE,RXY")
7457    (set_attr "type"     "idiv")])
7460 ; divmodsi4 instruction pattern(s).
7463 (define_expand "divmodsi4"
7464   [(parallel [(set (match_operand:SI 0 "general_operand" "")
7465                    (div:SI (match_operand:SI 1 "general_operand" "")
7466                            (match_operand:SI 2 "nonimmediate_operand" "")))
7467               (set (match_operand:SI 3 "general_operand" "")
7468                    (mod:SI (match_dup 1) (match_dup 2)))])
7469    (clobber (match_dup 4))]
7470   "!TARGET_ZARCH"
7472   rtx div_equal, mod_equal, equal;
7473   rtx_insn *insn;
7475   div_equal = gen_rtx_DIV (SImode, operands[1], operands[2]);
7476   mod_equal = gen_rtx_MOD (SImode, operands[1], operands[2]);
7477   equal = gen_rtx_IOR (DImode,
7478                        gen_rtx_ASHIFT (DImode,
7479                                        gen_rtx_ZERO_EXTEND (DImode, mod_equal),
7480                                        GEN_INT (32)),
7481                        gen_rtx_ZERO_EXTEND (DImode, div_equal));
7483   operands[4] = gen_reg_rtx(DImode);
7484   emit_insn (gen_extendsidi2 (operands[4], operands[1]));
7486   insn = emit_insn (gen_divmoddisi3 (operands[4], operands[4], operands[2]));
7487   set_unique_reg_note (insn, REG_EQUAL, equal);
7489   insn = emit_move_insn (operands[0], gen_lowpart (SImode, operands[4]));
7490   set_unique_reg_note (insn, REG_EQUAL, div_equal);
7492   insn = emit_move_insn (operands[3], gen_highpart (SImode, operands[4]));
7493   set_unique_reg_note (insn, REG_EQUAL, mod_equal);
7495   DONE;
7498 (define_insn "divmoddisi3"
7499   [(set (match_operand:DI 0 "register_operand" "=d,d")
7500         (ior:DI
7501           (ashift:DI
7502             (zero_extend:DI
7503               (truncate:SI
7504                 (mod:DI (match_operand:DI 1 "register_operand" "0,0")
7505                         (sign_extend:DI
7506                           (match_operand:SI 2 "nonimmediate_operand" "d,R")))))
7507             (const_int 32))
7508           (zero_extend:DI
7509             (truncate:SI
7510               (div:DI (match_dup 1) (sign_extend:DI (match_dup 2)))))))]
7511   "!TARGET_ZARCH"
7512   "@
7513    dr\t%0,%2
7514    d\t%0,%2"
7515   [(set_attr "op_type"  "RR,RX")
7516    (set_attr "type"     "idiv")])
7519 ; udivsi3 and umodsi3 instruction pattern(s).
7522 (define_expand "udivmodsi4"
7523   [(parallel [(set (match_operand:SI 0 "general_operand" "")
7524                    (udiv:SI (match_operand:SI 1 "general_operand" "")
7525                             (match_operand:SI 2 "nonimmediate_operand" "")))
7526               (set (match_operand:SI 3 "general_operand" "")
7527                    (umod:SI (match_dup 1) (match_dup 2)))])
7528    (clobber (match_dup 4))]
7529   "!TARGET_ZARCH"
7531   rtx div_equal, mod_equal, equal;
7532   rtx_insn *insn;
7534   div_equal = gen_rtx_UDIV (SImode, operands[1], operands[2]);
7535   mod_equal = gen_rtx_UMOD (SImode, operands[1], operands[2]);
7536   equal = gen_rtx_IOR (DImode,
7537                        gen_rtx_ASHIFT (DImode,
7538                                        gen_rtx_ZERO_EXTEND (DImode, mod_equal),
7539                                        GEN_INT (32)),
7540                        gen_rtx_ZERO_EXTEND (DImode, div_equal));
7542   operands[4] = gen_reg_rtx(DImode);
7543   emit_clobber (operands[4]);
7544   emit_move_insn (gen_lowpart (SImode, operands[4]), operands[1]);
7545   emit_move_insn (gen_highpart (SImode, operands[4]), const0_rtx);
7547   insn = emit_insn (gen_udivmoddisi3 (operands[4], operands[4], operands[2]));
7548   set_unique_reg_note (insn, REG_EQUAL, equal);
7550   insn = emit_move_insn (operands[0], gen_lowpart (SImode, operands[4]));
7551   set_unique_reg_note (insn, REG_EQUAL, div_equal);
7553   insn = emit_move_insn (operands[3], gen_highpart (SImode, operands[4]));
7554   set_unique_reg_note (insn, REG_EQUAL, mod_equal);
7556   DONE;
7559 (define_insn "udivmoddisi3"
7560   [(set (match_operand:DI 0 "register_operand" "=d,d")
7561         (ior:DI
7562           (ashift:DI
7563             (zero_extend:DI
7564               (truncate:SI
7565                 (umod:DI (match_operand:DI 1 "register_operand" "0,0")
7566                          (zero_extend:DI
7567                            (match_operand:SI 2 "nonimmediate_operand" "d,T")))))
7568             (const_int 32))
7569           (zero_extend:DI
7570             (truncate:SI
7571               (udiv:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))))]
7572   "!TARGET_ZARCH"
7573   "@
7574    dlr\t%0,%2
7575    dl\t%0,%2"
7576   [(set_attr "op_type"  "RRE,RXY")
7577    (set_attr "type"     "idiv")])
7580 ; div(df|sf)3 instruction pattern(s).
7583 ; dxbr, ddbr, debr, ddb, deb, ddtr, dxtr
7584 (define_insn "div<mode>3<tf_fpr>"
7585   [(set (match_operand:FP         0 "register_operand" "=f,f,f,v,v")
7586         (div:FP (match_operand:FP 1 "register_operand"  "f,0,0,v,v")
7587                 (match_operand:FP 2 "general_operand"   "f,f,R,v,v")))]
7588   "TARGET_HARD_FLOAT"
7589   "@
7590    d<xde>tr\t%0,%1,%2
7591    d<xde>br\t%0,%2
7592    d<xde>b\t%0,%2
7593    wfddb\t%v0,%v1,%v2
7594    wfdsb\t%v0,%v1,%v2"
7595   [(set_attr "op_type"      "RRF,RRE,RXE,VRR,VRR")
7596    (set_attr "type"         "fdiv<type>")
7597    (set_attr "cpu_facility" "*,*,*,vx,vxe")
7598    (set_attr "enabled"      "<nBFP>,<nDFP>,<DSF>,<DF>,<SF>")])
7602 ;;- And instructions.
7605 (define_expand "and<mode>3"
7606   [(set (match_operand:INT 0 "nonimmediate_operand" "")
7607         (and:INT (match_operand:INT 1 "nonimmediate_operand" "")
7608                  (match_operand:INT 2 "general_operand" "")))
7609    (clobber (reg:CC CC_REGNUM))]
7610   ""
7611   "s390_expand_logical_operator (AND, <MODE>mode, operands); DONE;")
7614 ; anddi3 instruction pattern(s).
7617 (define_insn "*anddi3_cc"
7618   [(set (reg CC_REGNUM)
7619         (compare
7620           (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,d,0,    d")
7621                   (match_operand:DI 2 "general_operand"      " d,d,T,NxxDw"))
7622           (const_int 0)))
7623    (set (match_operand:DI 0 "register_operand"               "=d,d,d,    d")
7624         (and:DI (match_dup 1) (match_dup 2)))]
7625   "TARGET_ZARCH && s390_match_ccmode(insn, CCTmode)"
7626   "@
7627    ngr\t%0,%2
7628    ngrk\t%0,%1,%2
7629    ng\t%0,%2
7630    risbg\t%0,%1,%s2,128+%e2,0"
7631   [(set_attr "op_type"  "RRE,RRF,RXY,RIE")
7632    (set_attr "cpu_facility" "*,z196,*,z10")
7633    (set_attr "z10prop" "z10_super_E1,*,z10_super_E1,z10_super_E1")])
7635 (define_insn "*anddi3_cconly"
7636   [(set (reg CC_REGNUM)
7637         (compare
7638           (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,d,0,    d")
7639                   (match_operand:DI 2 "general_operand"      " d,d,T,NxxDw"))
7640                  (const_int 0)))
7641    (clobber (match_scratch:DI 0                              "=d,d,d,    d"))]
7642   "TARGET_ZARCH
7643    && s390_match_ccmode(insn, CCTmode)
7644    /* Do not steal TM patterns.  */
7645    && s390_single_part (operands[2], DImode, HImode, 0) < 0"
7646   "@
7647    ngr\t%0,%2
7648    ngrk\t%0,%1,%2
7649    ng\t%0,%2
7650    risbg\t%0,%1,%s2,128+%e2,0"
7651   [(set_attr "op_type"  "RRE,RRF,RXY,RIE")
7652    (set_attr "cpu_facility" "*,z196,*,z10")
7653    (set_attr "z10prop" "z10_super_E1,*,z10_super_E1,z10_super_E1")])
7655 (define_insn "*anddi3"
7656   [(set (match_operand:DI 0 "nonimmediate_operand"
7657             "=d,d,    d,    d,    d,    d,    d,    d,d,d,d,    d,   AQ,Q")
7658         (and:DI
7659           (match_operand:DI 1 "nonimmediate_operand"
7660             "%d,o,    0,    0,    0,    0,    0,    0,0,d,0,    d,    0,0")
7661           (match_operand:DI 2 "general_operand"
7662             "M, M,N0HDF,N1HDF,N2HDF,N3HDF,N0SDF,N1SDF,d,d,T,NxxDw,NxQDF,Q")))
7663    (clobber (reg:CC CC_REGNUM))]
7664   "TARGET_ZARCH && s390_logical_operator_ok_p (operands)"
7665   "@
7666    #
7667    #
7668    nihh\t%0,%j2
7669    nihl\t%0,%j2
7670    nilh\t%0,%j2
7671    nill\t%0,%j2
7672    nihf\t%0,%m2
7673    nilf\t%0,%m2
7674    ngr\t%0,%2
7675    ngrk\t%0,%1,%2
7676    ng\t%0,%2
7677    risbg\t%0,%1,%s2,128+%e2,0
7678    #
7679    #"
7680   [(set_attr "op_type" "RRE,RXE,RI,RI,RI,RI,RIL,RIL,RRE,RRF,RXY,RIE,SI,SS")
7681    (set_attr "cpu_facility" "*,*,*,*,*,*,extimm,extimm,*,z196,*,z10,*,*")
7682    (set_attr "z10prop" "*,
7683                         *,
7684                         z10_super_E1,
7685                         z10_super_E1,
7686                         z10_super_E1,
7687                         z10_super_E1,
7688                         z10_super_E1,
7689                         z10_super_E1,
7690                         z10_super_E1,
7691                         *,
7692                         z10_super_E1,
7693                         z10_super_E1,
7694                         *,
7695                         *")])
7697 (define_split
7698   [(set (match_operand:DI 0 "s_operand" "")
7699         (and:DI (match_dup 0) (match_operand:DI 1 "immediate_operand" "")))
7700    (clobber (reg:CC CC_REGNUM))]
7701   "reload_completed"
7702   [(parallel
7703     [(set (match_dup 0) (and:QI (match_dup 0) (match_dup 1)))
7704      (clobber (reg:CC CC_REGNUM))])]
7705   "s390_narrow_logical_operator (AND, &operands[0], &operands[1]);")
7707 ;; These two are what combine generates for (ashift (zero_extract)).
7708 (define_insn "*extzv_<mode>_srl<clobbercc_or_nocc>"
7709   [(set (match_operand:GPR 0 "register_operand" "=d")
7710         (and:GPR (lshiftrt:GPR
7711                    (match_operand:GPR 1 "register_operand" "d")
7712                    (match_operand:GPR 2 "nonzero_shift_count_operand" ""))
7713                 (match_operand:GPR 3 "contiguous_bitmask_nowrap_operand" "")))]
7714   "<z10_or_zEC12_cond>
7715    /* Note that even for the SImode pattern, the rotate is always DImode.  */
7716    && s390_extzv_shift_ok (<bitsize>, -INTVAL (operands[2]),
7717                            INTVAL (operands[3]))"
7718   "<risbg_n>\t%0,%1,%<bfstart>3,128+%<bfend>3,64-%2"
7719   [(set_attr "op_type" "RIE")
7720    (set_attr "z10prop" "z10_super_E1")])
7722 (define_insn "*extzv_<mode>_sll<clobbercc_or_nocc>"
7723   [(set (match_operand:GPR 0 "register_operand" "=d")
7724         (and:GPR (ashift:GPR
7725                   (match_operand:GPR 1 "register_operand" "d")
7726                   (match_operand:GPR 2 "nonzero_shift_count_operand" ""))
7727                 (match_operand:GPR 3 "contiguous_bitmask_nowrap_operand" "")))]
7728   "<z10_or_zEC12_cond>
7729    && s390_extzv_shift_ok (<bitsize>, INTVAL (operands[2]),
7730                            INTVAL (operands[3]))"
7731   "<risbg_n>\t%0,%1,%<bfstart>3,128+%<bfend>3,%2"
7732   [(set_attr "op_type" "RIE")
7733    (set_attr "z10prop" "z10_super_E1")])
7737 ; andsi3 instruction pattern(s).
7740 (define_insn "*andsi3_cc"
7741   [(set (reg CC_REGNUM)
7742         (compare
7743           (and:SI
7744             (match_operand:SI 1 "nonimmediate_operand" "%0,0,d,0,0,    d")
7745             (match_operand:SI 2 "general_operand"      "Os,d,d,R,T,NxxSq"))
7746           (const_int 0)))
7747    (set (match_operand:SI 0 "register_operand"         "=d,d,d,d,d,    d")
7748         (and:SI (match_dup 1) (match_dup 2)))]
7749   "s390_match_ccmode(insn, CCTmode)"
7750   "@
7751    nilf\t%0,%o2
7752    nr\t%0,%2
7753    nrk\t%0,%1,%2
7754    n\t%0,%2
7755    ny\t%0,%2
7756    risbg\t%0,%1,%t2,128+%f2,0"
7757   [(set_attr "op_type"  "RIL,RR,RRF,RX,RXY,RIE")
7758    (set_attr "cpu_facility" "*,*,z196,*,longdisp,z10")
7759    (set_attr "z10prop" "z10_super_E1,z10_super_E1,*,
7760                         z10_super_E1,z10_super_E1,z10_super_E1")])
7762 (define_insn "*andsi3_cconly"
7763   [(set (reg CC_REGNUM)
7764         (compare
7765           (and:SI
7766             (match_operand:SI 1 "nonimmediate_operand" "%0,0,d,0,0,    d")
7767             (match_operand:SI 2 "general_operand"      "Os,d,d,R,T,NxxSq"))
7768           (const_int 0)))
7769    (clobber (match_scratch:SI 0                        "=d,d,d,d,d,    d"))]
7770   "s390_match_ccmode(insn, CCTmode)
7771    /* Do not steal TM patterns.  */
7772    && s390_single_part (operands[2], SImode, HImode, 0) < 0"
7773   "@
7774    nilf\t%0,%o2
7775    nr\t%0,%2
7776    nrk\t%0,%1,%2
7777    n\t%0,%2
7778    ny\t%0,%2
7779    risbg\t%0,%1,%t2,128+%f2,0"
7780   [(set_attr "op_type"  "RIL,RR,RRF,RX,RXY,RIE")
7781    (set_attr "cpu_facility" "*,*,z196,*,longdisp,z10")
7782    (set_attr "z10prop" "z10_super_E1,z10_super_E1,*,
7783                         z10_super_E1,z10_super_E1,z10_super_E1")])
7785 (define_insn "*andsi3_zarch"
7786   [(set (match_operand:SI 0 "nonimmediate_operand"
7787                             "=d,d,    d,    d, d,d,d,d,d,    d,   AQ,Q")
7788         (and:SI (match_operand:SI 1 "nonimmediate_operand"
7789                             "%d,o,    0,    0, 0,0,d,0,0,    d,    0,0")
7790                 (match_operand:SI 2 "general_operand"
7791                             " M,M,N0HSF,N1HSF,Os,d,d,R,T,NxxSw,NxQSF,Q")))
7792    (clobber (reg:CC CC_REGNUM))]
7793   "TARGET_ZARCH && s390_logical_operator_ok_p (operands)"
7794   "@
7795    #
7796    #
7797    nilh\t%0,%j2
7798    nill\t%0,%j2
7799    nilf\t%0,%o2
7800    nr\t%0,%2
7801    nrk\t%0,%1,%2
7802    n\t%0,%2
7803    ny\t%0,%2
7804    risbg\t%0,%1,%t2,128+%f2,0
7805    #
7806    #"
7807   [(set_attr "op_type"  "RRE,RXE,RI,RI,RIL,RR,RRF,RX,RXY,RIE,SI,SS")
7808    (set_attr "cpu_facility" "*,*,*,*,*,*,z196,*,longdisp,z10,*,*")
7809    (set_attr "z10prop" "*,
7810                         *,
7811                         z10_super_E1,
7812                         z10_super_E1,
7813                         z10_super_E1,
7814                         z10_super_E1,
7815                         *,
7816                         z10_super_E1,
7817                         z10_super_E1,
7818                         z10_super_E1,
7819                         *,
7820                         *")])
7822 (define_insn "*andsi3_esa"
7823   [(set (match_operand:SI 0 "nonimmediate_operand"         "=d,d,   AQ,Q")
7824         (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,    0,0")
7825                 (match_operand:SI 2 "general_operand"      " d,R,NxQSF,Q")))
7826    (clobber (reg:CC CC_REGNUM))]
7827   "!TARGET_ZARCH && s390_logical_operator_ok_p (operands)"
7828   "@
7829    nr\t%0,%2
7830    n\t%0,%2
7831    #
7832    #"
7833   [(set_attr "op_type"  "RR,RX,SI,SS")
7834    (set_attr "z10prop" "z10_super_E1,z10_super_E1,*,*")])
7837 (define_split
7838   [(set (match_operand:SI 0 "s_operand" "")
7839         (and:SI (match_dup 0) (match_operand:SI 1 "immediate_operand" "")))
7840    (clobber (reg:CC CC_REGNUM))]
7841   "reload_completed"
7842   [(parallel
7843     [(set (match_dup 0) (and:QI (match_dup 0) (match_dup 1)))
7844      (clobber (reg:CC CC_REGNUM))])]
7845   "s390_narrow_logical_operator (AND, &operands[0], &operands[1]);")
7848 ; andhi3 instruction pattern(s).
7851 (define_insn "*andhi3_zarch"
7852   [(set (match_operand:HI 0 "nonimmediate_operand"         "=d,d,d,   AQ,Q")
7853         (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,d,0,    0,0")
7854                 (match_operand:HI 2 "general_operand"      " d,d,n,NxQHF,Q")))
7855    (clobber (reg:CC CC_REGNUM))]
7856   "TARGET_ZARCH && s390_logical_operator_ok_p (operands)"
7857   "@
7858    nr\t%0,%2
7859    nrk\t%0,%1,%2
7860    nill\t%0,%x2
7861    #
7862    #"
7863   [(set_attr "op_type"  "RR,RRF,RI,SI,SS")
7864    (set_attr "cpu_facility" "*,z196,*,*,*")
7865    (set_attr "z10prop" "z10_super_E1,*,z10_super_E1,*,*")
7868 (define_insn "*andhi3_esa"
7869   [(set (match_operand:HI 0 "nonimmediate_operand" "=d,AQ,Q")
7870         (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,0")
7871                 (match_operand:HI 2 "general_operand" "d,NxQHF,Q")))
7872    (clobber (reg:CC CC_REGNUM))]
7873   "!TARGET_ZARCH && s390_logical_operator_ok_p (operands)"
7874   "@
7875    nr\t%0,%2
7876    #
7877    #"
7878   [(set_attr "op_type"  "RR,SI,SS")
7879    (set_attr "z10prop" "z10_super_E1,*,*")
7882 (define_split
7883   [(set (match_operand:HI 0 "s_operand" "")
7884         (and:HI (match_dup 0) (match_operand:HI 1 "immediate_operand" "")))
7885    (clobber (reg:CC CC_REGNUM))]
7886   "reload_completed"
7887   [(parallel
7888     [(set (match_dup 0) (and:QI (match_dup 0) (match_dup 1)))
7889      (clobber (reg:CC CC_REGNUM))])]
7890   "s390_narrow_logical_operator (AND, &operands[0], &operands[1]);")
7893 ; andqi3 instruction pattern(s).
7896 (define_insn "*andqi3_zarch"
7897   [(set (match_operand:QI 0 "nonimmediate_operand"         "=d,d,d,Q,S,Q")
7898         (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,d,0,0,0,0")
7899                 (match_operand:QI 2 "general_operand"      " d,d,n,n,n,Q")))
7900    (clobber (reg:CC CC_REGNUM))]
7901   "TARGET_ZARCH && s390_logical_operator_ok_p (operands)"
7902   "@
7903    nr\t%0,%2
7904    nrk\t%0,%1,%2
7905    nill\t%0,%b2
7906    ni\t%S0,%b2
7907    niy\t%S0,%b2
7908    #"
7909   [(set_attr "op_type"  "RR,RRF,RI,SI,SIY,SS")
7910    (set_attr "cpu_facility" "*,z196,*,*,longdisp,*")
7911    (set_attr "z10prop" "z10_super_E1,*,z10_super_E1,z10_super,z10_super,*")])
7913 (define_insn "*andqi3_esa"
7914   [(set (match_operand:QI 0 "nonimmediate_operand" "=d,Q,Q")
7915         (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
7916                 (match_operand:QI 2 "general_operand" "d,n,Q")))
7917    (clobber (reg:CC CC_REGNUM))]
7918   "!TARGET_ZARCH && s390_logical_operator_ok_p (operands)"
7919   "@
7920    nr\t%0,%2
7921    ni\t%S0,%b2
7922    #"
7923   [(set_attr "op_type"  "RR,SI,SS")
7924    (set_attr "z10prop" "z10_super_E1,z10_super,*")])
7927 ; And with complement
7929 ; c = ~b & a = (b & a) ^ a
7931 (define_insn_and_split "*andc_split_<mode>"
7932   [(set (match_operand:GPR 0 "nonimmediate_operand" "")
7933         (and:GPR (not:GPR (match_operand:GPR 1 "nonimmediate_operand" ""))
7934                  (match_operand:GPR 2 "general_operand" "")))
7935    (clobber (reg:CC CC_REGNUM))]
7936   "!TARGET_Z15
7937    && ! reload_completed
7938    && (GET_CODE (operands[0]) != MEM
7939       /* Ensure that s390_logical_operator_ok_p will succeed even
7940          on the split xor if (b & a) is stored into a pseudo.  */
7941        || rtx_equal_p (operands[0], operands[2]))"
7942   "#"
7943   "&& 1"
7944   [
7945   (parallel
7946    [(set (match_dup 3) (and:GPR (match_dup 1) (match_dup 2)))
7947    (clobber (reg:CC CC_REGNUM))])
7948   (parallel
7949    [(set (match_dup 0) (xor:GPR (match_dup 3) (match_dup 2)))
7950    (clobber (reg:CC CC_REGNUM))])]
7952   if (reg_overlap_mentioned_p (operands[0], operands[2]))
7953     operands[3] = gen_reg_rtx (<MODE>mode);
7954   else
7955     operands[3] = operands[0];
7959 ; Block and (NC) patterns.
7962 (define_insn "*nc"
7963   [(set (match_operand:BLK 0 "memory_operand" "=Q")
7964         (and:BLK (match_dup 0)
7965                  (match_operand:BLK 1 "memory_operand" "Q")))
7966    (use (match_operand 2 "const_int_operand" "n"))
7967    (clobber (reg:CC CC_REGNUM))]
7968   "INTVAL (operands[2]) >= 1 && INTVAL (operands[2]) <= 256"
7969   "nc\t%O0(%2,%R0),%S1"
7970   [(set_attr "op_type" "SS")
7971    (set_attr "z196prop" "z196_cracked")])
7973 (define_split
7974   [(set (match_operand 0 "memory_operand" "")
7975         (and (match_dup 0)
7976              (match_operand 1 "memory_operand" "")))
7977    (clobber (reg:CC CC_REGNUM))]
7978   "reload_completed
7979    && GET_MODE (operands[0]) == GET_MODE (operands[1])
7980    && GET_MODE_SIZE (GET_MODE (operands[0])) > 0"
7981   [(parallel
7982     [(set (match_dup 0) (and:BLK (match_dup 0) (match_dup 1)))
7983      (use (match_dup 2))
7984      (clobber (reg:CC CC_REGNUM))])]
7986   operands[2] = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[0])));
7987   operands[0] = adjust_address (operands[0], BLKmode, 0);
7988   operands[1] = adjust_address (operands[1], BLKmode, 0);
7991 (define_peephole2
7992   [(parallel
7993     [(set (match_operand:BLK 0 "memory_operand" "")
7994           (and:BLK (match_dup 0)
7995                    (match_operand:BLK 1 "memory_operand" "")))
7996      (use (match_operand 2 "const_int_operand" ""))
7997      (clobber (reg:CC CC_REGNUM))])
7998    (parallel
7999     [(set (match_operand:BLK 3 "memory_operand" "")
8000           (and:BLK (match_dup 3)
8001                    (match_operand:BLK 4 "memory_operand" "")))
8002      (use (match_operand 5 "const_int_operand" ""))
8003      (clobber (reg:CC CC_REGNUM))])]
8004   "s390_offset_p (operands[0], operands[3], operands[2])
8005    && s390_offset_p (operands[1], operands[4], operands[2])
8006    && !s390_overlap_p (operands[0], operands[1],
8007                        INTVAL (operands[2]) + INTVAL (operands[5]))
8008    && INTVAL (operands[2]) + INTVAL (operands[5]) <= 256"
8009   [(parallel
8010     [(set (match_dup 6) (and:BLK (match_dup 6) (match_dup 7)))
8011      (use (match_dup 8))
8012      (clobber (reg:CC CC_REGNUM))])]
8013   "operands[6] = gen_rtx_MEM (BLKmode, XEXP (operands[0], 0));
8014    operands[7] = gen_rtx_MEM (BLKmode, XEXP (operands[1], 0));
8015    operands[8] = GEN_INT (INTVAL (operands[2]) + INTVAL (operands[5]));")
8019 ;;- Bit set (inclusive or) instructions.
8022 (define_expand "ior<mode>3"
8023   [(set (match_operand:INT 0 "nonimmediate_operand" "")
8024         (ior:INT (match_operand:INT 1 "nonimmediate_operand" "")
8025                  (match_operand:INT 2 "general_operand" "")))
8026    (clobber (reg:CC CC_REGNUM))]
8027   ""
8028   "s390_expand_logical_operator (IOR, <MODE>mode, operands); DONE;")
8031 ; iordi3 instruction pattern(s).
8034 (define_insn "*iordi3_cc"
8035   [(set (reg CC_REGNUM)
8036         (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,d,0")
8037                          (match_operand:DI 2 "general_operand"      " d,d,T"))
8038                  (const_int 0)))
8039    (set (match_operand:DI 0 "register_operand"                      "=d,d,d")
8040         (ior:DI (match_dup 1) (match_dup 2)))]
8041   "s390_match_ccmode(insn, CCTmode) && TARGET_ZARCH"
8042   "@
8043    ogr\t%0,%2
8044    ogrk\t%0,%1,%2
8045    og\t%0,%2"
8046   [(set_attr "op_type"  "RRE,RRF,RXY")
8047    (set_attr "cpu_facility" "*,z196,*")
8048    (set_attr "z10prop" "z10_super_E1,*,z10_super_E1")])
8050 (define_insn "*iordi3_cconly"
8051   [(set (reg CC_REGNUM)
8052         (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,d,0")
8053                          (match_operand:DI 2 "general_operand"      " d,d,T"))
8054                  (const_int 0)))
8055    (clobber (match_scratch:DI 0                                     "=d,d,d"))]
8056   "s390_match_ccmode(insn, CCTmode) && TARGET_ZARCH"
8057   "@
8058    ogr\t%0,%2
8059    ogrk\t%0,%1,%2
8060    og\t%0,%2"
8061   [(set_attr "op_type"  "RRE,RRF,RXY")
8062    (set_attr "cpu_facility" "*,z196,*")
8063    (set_attr "z10prop" "z10_super_E1,*,z10_super_E1")])
8065 (define_insn "*iordi3"
8066   [(set (match_operand:DI 0 "nonimmediate_operand"
8067                                "=d,    d,    d,    d,    d,    d,d,d,d,   AQ,Q")
8068         (ior:DI (match_operand:DI 1 "nonimmediate_operand"
8069                             "   %0,    0,    0,    0,    0,    0,0,d,0,    0,0")
8070                 (match_operand:DI 2 "general_operand"
8071                             "N0HD0,N1HD0,N2HD0,N3HD0,N0SD0,N1SD0,d,d,T,NxQD0,Q")))
8072    (clobber (reg:CC CC_REGNUM))]
8073   "TARGET_ZARCH && s390_logical_operator_ok_p (operands)"
8074   "@
8075    oihh\t%0,%i2
8076    oihl\t%0,%i2
8077    oilh\t%0,%i2
8078    oill\t%0,%i2
8079    oihf\t%0,%k2
8080    oilf\t%0,%k2
8081    ogr\t%0,%2
8082    ogrk\t%0,%1,%2
8083    og\t%0,%2
8084    #
8085    #"
8086   [(set_attr "op_type"  "RI,RI,RI,RI,RIL,RIL,RRE,RRF,RXY,SI,SS")
8087    (set_attr "cpu_facility" "*,*,*,*,extimm,extimm,*,z196,*,*,*")
8088    (set_attr "z10prop" "z10_super_E1,
8089                         z10_super_E1,
8090                         z10_super_E1,
8091                         z10_super_E1,
8092                         z10_super_E1,
8093                         z10_super_E1,
8094                         z10_super_E1,
8095                         *,
8096                         z10_super_E1,
8097                         *,
8098                         *")])
8100 (define_split
8101   [(set (match_operand:DI 0 "s_operand" "")
8102         (ior:DI (match_dup 0) (match_operand:DI 1 "immediate_operand" "")))
8103    (clobber (reg:CC CC_REGNUM))]
8104   "reload_completed"
8105   [(parallel
8106     [(set (match_dup 0) (ior:QI (match_dup 0) (match_dup 1)))
8107      (clobber (reg:CC CC_REGNUM))])]
8108   "s390_narrow_logical_operator (IOR, &operands[0], &operands[1]);")
8111 ; iorsi3 instruction pattern(s).
8114 (define_insn "*iorsi3_cc"
8115   [(set (reg CC_REGNUM)
8116         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,d,0,0")
8117                          (match_operand:SI 2 "general_operand"      "Os,d,d,R,T"))
8118                  (const_int 0)))
8119    (set (match_operand:SI 0 "register_operand"                      "=d,d,d,d,d")
8120         (ior:SI (match_dup 1) (match_dup 2)))]
8121   "s390_match_ccmode(insn, CCTmode)"
8122   "@
8123    oilf\t%0,%o2
8124    or\t%0,%2
8125    ork\t%0,%1,%2
8126    o\t%0,%2
8127    oy\t%0,%2"
8128   [(set_attr "op_type"  "RIL,RR,RRF,RX,RXY")
8129    (set_attr "cpu_facility" "*,*,z196,*,longdisp")
8130    (set_attr "z10prop" "z10_super_E1,z10_super_E1,*,z10_super_E1,z10_super_E1")])
8132 (define_insn "*iorsi3_cconly"
8133   [(set (reg CC_REGNUM)
8134         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,d,0,0")
8135                          (match_operand:SI 2 "general_operand"      "Os,d,d,R,T"))
8136                  (const_int 0)))
8137    (clobber (match_scratch:SI 0                                     "=d,d,d,d,d"))]
8138   "s390_match_ccmode(insn, CCTmode)"
8139   "@
8140    oilf\t%0,%o2
8141    or\t%0,%2
8142    ork\t%0,%1,%2
8143    o\t%0,%2
8144    oy\t%0,%2"
8145   [(set_attr "op_type"  "RIL,RR,RRF,RX,RXY")
8146    (set_attr "cpu_facility" "*,*,z196,*,longdisp")
8147    (set_attr "z10prop" "z10_super_E1,z10_super_E1,*,z10_super_E1,z10_super_E1")])
8149 (define_insn "*iorsi3_zarch"
8150   [(set (match_operand:SI 0 "nonimmediate_operand"         "=d,    d, d,d,d,d,d,   AQ,Q")
8151         (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,    0, 0,0,d,0,0,    0,0")
8152                 (match_operand:SI 2 "general_operand"   "N0HS0,N1HS0,Os,d,d,R,T,NxQS0,Q")))
8153    (clobber (reg:CC CC_REGNUM))]
8154   "TARGET_ZARCH && s390_logical_operator_ok_p (operands)"
8155   "@
8156    oilh\t%0,%i2
8157    oill\t%0,%i2
8158    oilf\t%0,%o2
8159    or\t%0,%2
8160    ork\t%0,%1,%2
8161    o\t%0,%2
8162    oy\t%0,%2
8163    #
8164    #"
8165   [(set_attr "op_type"  "RI,RI,RIL,RR,RRF,RX,RXY,SI,SS")
8166    (set_attr "cpu_facility" "*,*,*,*,z196,*,longdisp,*,*")
8167    (set_attr "z10prop" "z10_super_E1,
8168                         z10_super_E1,
8169                         z10_super_E1,
8170                         z10_super_E1,
8171                         *,
8172                         z10_super_E1,
8173                         z10_super_E1,
8174                         *,
8175                         *")])
8177 (define_insn "*iorsi3_esa"
8178   [(set (match_operand:SI 0 "nonimmediate_operand" "=d,d,AQ,Q")
8179         (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,0,0")
8180                 (match_operand:SI 2 "general_operand" "d,R,NxQS0,Q")))
8181    (clobber (reg:CC CC_REGNUM))]
8182   "!TARGET_ZARCH && s390_logical_operator_ok_p (operands)"
8183   "@
8184    or\t%0,%2
8185    o\t%0,%2
8186    #
8187    #"
8188   [(set_attr "op_type"  "RR,RX,SI,SS")
8189    (set_attr "z10prop" "z10_super_E1,z10_super_E1,*,*")])
8191 (define_split
8192   [(set (match_operand:SI 0 "s_operand" "")
8193         (ior:SI (match_dup 0) (match_operand:SI 1 "immediate_operand" "")))
8194    (clobber (reg:CC CC_REGNUM))]
8195   "reload_completed"
8196   [(parallel
8197     [(set (match_dup 0) (ior:QI (match_dup 0) (match_dup 1)))
8198      (clobber (reg:CC CC_REGNUM))])]
8199   "s390_narrow_logical_operator (IOR, &operands[0], &operands[1]);")
8202 ; iorhi3 instruction pattern(s).
8205 (define_insn "*iorhi3_zarch"
8206   [(set (match_operand:HI 0 "nonimmediate_operand"         "=d,d,d,   AQ,Q")
8207         (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,d,0,    0,0")
8208                 (match_operand:HI 2 "general_operand"      " d,d,n,NxQH0,Q")))
8209    (clobber (reg:CC CC_REGNUM))]
8210   "TARGET_ZARCH && s390_logical_operator_ok_p (operands)"
8211   "@
8212    or\t%0,%2
8213    ork\t%0,%1,%2
8214    oill\t%0,%x2
8215    #
8216    #"
8217   [(set_attr "op_type"  "RR,RRF,RI,SI,SS")
8218    (set_attr "cpu_facility" "*,z196,*,*,*")
8219    (set_attr "z10prop" "z10_super_E1,*,z10_super_E1,*,*")])
8221 (define_insn "*iorhi3_esa"
8222   [(set (match_operand:HI 0 "nonimmediate_operand" "=d,AQ,Q")
8223         (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,0")
8224                 (match_operand:HI 2 "general_operand" "d,NxQH0,Q")))
8225    (clobber (reg:CC CC_REGNUM))]
8226   "!TARGET_ZARCH && s390_logical_operator_ok_p (operands)"
8227   "@
8228    or\t%0,%2
8229    #
8230    #"
8231   [(set_attr "op_type"  "RR,SI,SS")
8232    (set_attr "z10prop" "z10_super_E1,*,*")])
8234 (define_split
8235   [(set (match_operand:HI 0 "s_operand" "")
8236         (ior:HI (match_dup 0) (match_operand:HI 1 "immediate_operand" "")))
8237    (clobber (reg:CC CC_REGNUM))]
8238   "reload_completed"
8239   [(parallel
8240     [(set (match_dup 0) (ior:QI (match_dup 0) (match_dup 1)))
8241      (clobber (reg:CC CC_REGNUM))])]
8242   "s390_narrow_logical_operator (IOR, &operands[0], &operands[1]);")
8245 ; iorqi3 instruction pattern(s).
8248 (define_insn "*iorqi3_zarch"
8249   [(set (match_operand:QI 0 "nonimmediate_operand"         "=d,d,d,Q,S,Q")
8250         (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,d,0,0,0,0")
8251                 (match_operand:QI 2 "general_operand"      " d,d,n,n,n,Q")))
8252    (clobber (reg:CC CC_REGNUM))]
8253   "TARGET_ZARCH && s390_logical_operator_ok_p (operands)"
8254   "@
8255    or\t%0,%2
8256    ork\t%0,%1,%2
8257    oill\t%0,%b2
8258    oi\t%S0,%b2
8259    oiy\t%S0,%b2
8260    #"
8261   [(set_attr "op_type" "RR,RRF,RI,SI,SIY,SS")
8262    (set_attr "cpu_facility" "*,z196,*,*,longdisp,*")
8263    (set_attr "z10prop" "z10_super_E1,*,z10_super_E1,
8264                         z10_super,z10_super,*")])
8266 (define_insn "*iorqi3_esa"
8267   [(set (match_operand:QI 0 "nonimmediate_operand" "=d,Q,Q")
8268         (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8269                 (match_operand:QI 2 "general_operand" "d,n,Q")))
8270    (clobber (reg:CC CC_REGNUM))]
8271   "!TARGET_ZARCH && s390_logical_operator_ok_p (operands)"
8272   "@
8273    or\t%0,%2
8274    oi\t%S0,%b2
8275    #"
8276   [(set_attr "op_type"  "RR,SI,SS")
8277    (set_attr "z10prop" "z10_super_E1,z10_super,*")])
8280 ; And/Or with complement
8283 ; ncrk, ncgrk, ocrk, ocgrk
8284 (define_insn "*<ANDOR:bitops_name>c<GPR:mode>_cc"
8285   [(set (reg CC_REGNUM)
8286         (compare
8287          (ANDOR:GPR (not:GPR (match_operand:GPR 1 "register_operand" "d"))
8288                     (match_operand:GPR 2 "register_operand" "d"))
8289          (const_int 0)))
8290    (set (match_operand:GPR 0 "register_operand" "=d")
8291         (ANDOR:GPR (not:GPR (match_dup 1))
8292                    (match_dup 2)))]
8293   "TARGET_Z15 && s390_match_ccmode(insn, CCTmode)"
8294   "<ANDOR:noxa>c<GPR:g>rk\t%0,%2,%1"
8295   [(set_attr "op_type" "RRF")])
8297 ; ncrk, ncgrk, ocrk, ocgrk
8298 (define_insn "*<ANDOR:bitops_name>c<GPR:mode>_cconly"
8299   [(set (reg CC_REGNUM)
8300         (compare
8301          (ANDOR:GPR (not:GPR (match_operand:GPR 1 "register_operand" "d"))
8302                     (match_operand:GPR 2 "register_operand" "d"))
8303          (const_int 0)))
8304    (clobber (match_scratch:GPR 0 "=d"))]
8305   "TARGET_Z15 && s390_match_ccmode(insn, CCTmode)"
8306   "<ANDOR:noxa>c<GPR:g>rk\t%0,%2,%1"
8307   [(set_attr "op_type" "RRF")])
8309 ; ncrk, ncgrk, ocrk, ocgrk
8310 (define_insn "*<ANDOR:bitops_name>c<GPR:mode>"
8311   [(set (match_operand:GPR 0 "register_operand" "=d")
8312         (ANDOR:GPR (not:GPR (match_operand:GPR 1 "register_operand" "d"))
8313                    (match_operand:GPR 2 "register_operand" "d")))
8314    (clobber (reg:CC CC_REGNUM))]
8315   "TARGET_Z15"
8316   "<ANDOR:noxa>c<GPR:g>rk\t%0,%2,%1"
8317   [(set_attr "op_type" "RRF")])
8320 ;- Nand/Nor instructions.
8323 ; nnrk, nngrk, nork, nogrk
8324 (define_insn "*n<ANDOR:inv_bitops_name><GPR:mode>_cc"
8325   [(set (reg CC_REGNUM)
8326         (compare
8327          (ANDOR:GPR (not:GPR (match_operand:GPR 1 "register_operand" "d"))
8328                     (not:GPR (match_operand:GPR 2 "register_operand" "d")))
8329          (const_int 0)))
8330    (set (match_operand:GPR 0 "register_operand" "=d")
8331         (ANDOR:GPR (not:GPR (match_dup 1))
8332                    (not:GPR (match_dup 2))))]
8333   "TARGET_Z15 && s390_match_ccmode(insn, CCTmode)"
8334   "n<ANDOR:inv_no><GPR:g>rk\t%0,%1,%2"
8335   [(set_attr "op_type" "RRF")])
8337 ; nnrk, nngrk, nork, nogrk
8338 (define_insn "*n<ANDOR:inv_bitops_name><mode>_cconly"
8339   [(set (reg CC_REGNUM)
8340         (compare
8341          (ANDOR:GPR (not:GPR (match_operand:GPR 1 "register_operand" "d"))
8342                     (not:GPR (match_operand:GPR 2 "register_operand" "d")))
8343          (const_int 0)))
8344    (clobber (match_scratch:GPR 0 "=d"))]
8345   "TARGET_Z15 && s390_match_ccmode(insn, CCTmode)"
8346   "n<ANDOR:inv_no><GPR:g>rk\t%0,%1,%2"
8347   [(set_attr "op_type" "RRF")])
8349 ; nnrk, nngrk, nork, nogrk
8350 (define_insn "*n<ANDOR:inv_bitops_name><mode>"
8351   [(set (match_operand:GPR 0 "register_operand" "=d")
8352         (ANDOR:GPR (not:GPR (match_operand:GPR 1 "register_operand" "d"))
8353                    (not:GPR (match_operand:GPR 2 "register_operand" "d"))))
8354    (clobber (reg:CC CC_REGNUM))]
8355   "TARGET_Z15"
8356   "n<ANDOR:inv_no><GPR:g>rk\t%0,%1,%2"
8357   [(set_attr "op_type" "RRF")])
8359 ; Use NAND for bit inversion
8360 (define_insn "*not<mode>"
8361   [(set (match_operand:GPR          0 "register_operand" "=d")
8362         (not:GPR (match_operand:GPR 1 "register_operand"  "d")))
8363    (clobber (reg:CC CC_REGNUM))]
8364   "TARGET_Z15"
8365   "nn<GPR:g>rk\t%0,%1,%1"
8366   [(set_attr "op_type" "RRF")])
8369 ; Block inclusive or (OC) patterns.
8372 (define_insn "*oc"
8373   [(set (match_operand:BLK 0 "memory_operand" "=Q")
8374         (ior:BLK (match_dup 0)
8375                  (match_operand:BLK 1 "memory_operand" "Q")))
8376    (use (match_operand 2 "const_int_operand" "n"))
8377    (clobber (reg:CC CC_REGNUM))]
8378   "INTVAL (operands[2]) >= 1 && INTVAL (operands[2]) <= 256"
8379   "oc\t%O0(%2,%R0),%S1"
8380   [(set_attr "op_type" "SS")
8381    (set_attr "z196prop" "z196_cracked")])
8383 (define_split
8384   [(set (match_operand 0 "memory_operand" "")
8385         (ior (match_dup 0)
8386              (match_operand 1 "memory_operand" "")))
8387    (clobber (reg:CC CC_REGNUM))]
8388   "reload_completed
8389    && GET_MODE (operands[0]) == GET_MODE (operands[1])
8390    && GET_MODE_SIZE (GET_MODE (operands[0])) > 0"
8391   [(parallel
8392     [(set (match_dup 0) (ior:BLK (match_dup 0) (match_dup 1)))
8393      (use (match_dup 2))
8394      (clobber (reg:CC CC_REGNUM))])]
8396   operands[2] = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[0])));
8397   operands[0] = adjust_address (operands[0], BLKmode, 0);
8398   operands[1] = adjust_address (operands[1], BLKmode, 0);
8401 (define_peephole2
8402   [(parallel
8403     [(set (match_operand:BLK 0 "memory_operand" "")
8404           (ior:BLK (match_dup 0)
8405                    (match_operand:BLK 1 "memory_operand" "")))
8406      (use (match_operand 2 "const_int_operand" ""))
8407      (clobber (reg:CC CC_REGNUM))])
8408    (parallel
8409     [(set (match_operand:BLK 3 "memory_operand" "")
8410           (ior:BLK (match_dup 3)
8411                    (match_operand:BLK 4 "memory_operand" "")))
8412      (use (match_operand 5 "const_int_operand" ""))
8413      (clobber (reg:CC CC_REGNUM))])]
8414   "s390_offset_p (operands[0], operands[3], operands[2])
8415    && s390_offset_p (operands[1], operands[4], operands[2])
8416    && !s390_overlap_p (operands[0], operands[1],
8417                        INTVAL (operands[2]) + INTVAL (operands[5]))
8418    && INTVAL (operands[2]) + INTVAL (operands[5]) <= 256"
8419   [(parallel
8420     [(set (match_dup 6) (ior:BLK (match_dup 6) (match_dup 7)))
8421      (use (match_dup 8))
8422      (clobber (reg:CC CC_REGNUM))])]
8423   "operands[6] = gen_rtx_MEM (BLKmode, XEXP (operands[0], 0));
8424    operands[7] = gen_rtx_MEM (BLKmode, XEXP (operands[1], 0));
8425    operands[8] = GEN_INT (INTVAL (operands[2]) + INTVAL (operands[5]));")
8429 ;;- Xor instructions.
8432 (define_expand "xor<mode>3"
8433   [(set (match_operand:INT 0 "nonimmediate_operand" "")
8434         (xor:INT (match_operand:INT 1 "nonimmediate_operand" "")
8435                  (match_operand:INT 2 "general_operand" "")))
8436    (clobber (reg:CC CC_REGNUM))]
8437   ""
8438   "s390_expand_logical_operator (XOR, <MODE>mode, operands); DONE;")
8440 ; Combine replaces (xor (x) (const_int -1)) with (not (x)) when doing
8441 ; simplifications.  So its better to have something matching.
8442 (define_split
8443   [(set (match_operand:INT 0 "nonimmediate_operand" "")
8444         (not:INT (match_operand:INT 1 "nonimmediate_operand" "")))]
8445   ""
8446   [(parallel
8447     [(set (match_dup 0) (xor:INT (match_dup 1) (match_dup 2)))
8448      (clobber (reg:CC CC_REGNUM))])]
8450   operands[2] = constm1_rtx;
8451   if (!s390_logical_operator_ok_p (operands))
8452     FAIL;
8456 ; xordi3 instruction pattern(s).
8459 (define_insn "*xordi3_cc"
8460   [(set (reg CC_REGNUM)
8461         (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,d,0")
8462                          (match_operand:DI 2 "general_operand"      " d,d,T"))
8463                  (const_int 0)))
8464    (set (match_operand:DI 0 "register_operand"                      "=d,d,d")
8465         (xor:DI (match_dup 1) (match_dup 2)))]
8466   "s390_match_ccmode(insn, CCTmode) && TARGET_ZARCH"
8467   "@
8468    xgr\t%0,%2
8469    xgrk\t%0,%1,%2
8470    xg\t%0,%2"
8471   [(set_attr "op_type" "RRE,RRF,RXY")
8472    (set_attr "cpu_facility" "*,z196,*")
8473    (set_attr "z10prop" "z10_super_E1,*,z10_super_E1")])
8475 (define_insn "*xordi3_cconly"
8476   [(set (reg CC_REGNUM)
8477         (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,d,0")
8478                          (match_operand:DI 2 "general_operand"      " d,d,T"))
8479                  (const_int 0)))
8480    (clobber (match_scratch:DI 0                                     "=d,d,d"))]
8481   "s390_match_ccmode(insn, CCTmode) && TARGET_ZARCH"
8482   "@
8483    xgr\t%0,%2
8484    xgrk\t%0,%1,%2
8485    xg\t%0,%2"
8486   [(set_attr "op_type" "RRE,RRF,RXY")
8487    (set_attr "cpu_facility" "*,z196,*")
8488    (set_attr "z10prop" "z10_super_E1,*,z10_super_E1")])
8490 (define_insn "*xordi3"
8491   [(set (match_operand:DI 0 "nonimmediate_operand"         "=d,    d,d,d,d,   AQ,Q")
8492         (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,    0,0,d,0,    0,0")
8493                 (match_operand:DI 2 "general_operand"   "N0SD0,N1SD0,d,d,T,NxQD0,Q")))
8494    (clobber (reg:CC CC_REGNUM))]
8495   "TARGET_ZARCH && s390_logical_operator_ok_p (operands)"
8496   "@
8497    xihf\t%0,%k2
8498    xilf\t%0,%k2
8499    xgr\t%0,%2
8500    xgrk\t%0,%1,%2
8501    xg\t%0,%2
8502    #
8503    #"
8504   [(set_attr "op_type"  "RIL,RIL,RRE,RRF,RXY,SI,SS")
8505    (set_attr "cpu_facility" "extimm,extimm,*,z196,*,*,*")
8506    (set_attr "z10prop" "z10_super_E1,z10_super_E1,z10_super_E1,
8507                         *,z10_super_E1,*,*")])
8509 (define_split
8510   [(set (match_operand:DI 0 "s_operand" "")
8511         (xor:DI (match_dup 0) (match_operand:DI 1 "immediate_operand" "")))
8512    (clobber (reg:CC CC_REGNUM))]
8513   "reload_completed"
8514   [(parallel
8515     [(set (match_dup 0) (xor:QI (match_dup 0) (match_dup 1)))
8516      (clobber (reg:CC CC_REGNUM))])]
8517   "s390_narrow_logical_operator (XOR, &operands[0], &operands[1]);")
8520 ; xorsi3 instruction pattern(s).
8523 (define_insn "*xorsi3_cc"
8524   [(set (reg CC_REGNUM)
8525         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,d,0,0")
8526                          (match_operand:SI 2 "general_operand"      "Os,d,d,R,T"))
8527                  (const_int 0)))
8528    (set (match_operand:SI 0 "register_operand"                      "=d,d,d,d,d")
8529         (xor:SI (match_dup 1) (match_dup 2)))]
8530   "s390_match_ccmode(insn, CCTmode)"
8531   "@
8532    xilf\t%0,%o2
8533    xr\t%0,%2
8534    xrk\t%0,%1,%2
8535    x\t%0,%2
8536    xy\t%0,%2"
8537   [(set_attr "op_type" "RIL,RR,RRF,RX,RXY")
8538    (set_attr "cpu_facility" "*,*,z196,*,longdisp")
8539    (set_attr "z10prop" "z10_super_E1,z10_super_E1,*,
8540                         z10_super_E1,z10_super_E1")])
8542 (define_insn "*xorsi3_cconly"
8543   [(set (reg CC_REGNUM)
8544         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,d,0,0")
8545                          (match_operand:SI 2 "general_operand"      "Os,d,d,R,T"))
8546                  (const_int 0)))
8547    (clobber (match_scratch:SI 0                                     "=d,d,d,d,d"))]
8548   "s390_match_ccmode(insn, CCTmode)"
8549   "@
8550    xilf\t%0,%o2
8551    xr\t%0,%2
8552    xrk\t%0,%1,%2
8553    x\t%0,%2
8554    xy\t%0,%2"
8555   [(set_attr "op_type" "RIL,RR,RRF,RX,RXY")
8556    (set_attr "cpu_facility" "*,*,z196,*,longdisp")
8557    (set_attr "z10prop" "z10_super_E1,z10_super_E1,*,
8558                         z10_super_E1,z10_super_E1")])
8560 (define_insn "*xorsi3"
8561   [(set (match_operand:SI 0 "nonimmediate_operand"         "=d,d,d,d,d,   AQ,Q")
8562         (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,d,0,0,    0,0")
8563                 (match_operand:SI 2 "general_operand"      "Os,d,d,R,T,NxQS0,Q")))
8564    (clobber (reg:CC CC_REGNUM))]
8565   "s390_logical_operator_ok_p (operands)"
8566   "@
8567    xilf\t%0,%o2
8568    xr\t%0,%2
8569    xrk\t%0,%1,%2
8570    x\t%0,%2
8571    xy\t%0,%2
8572    #
8573    #"
8574   [(set_attr "op_type"  "RIL,RR,RRF,RX,RXY,SI,SS")
8575    (set_attr "cpu_facility" "*,*,z196,*,longdisp,*,*")
8576    (set_attr "z10prop" "z10_super_E1,z10_super_E1,*,
8577                         z10_super_E1,z10_super_E1,*,*")])
8579 (define_split
8580   [(set (match_operand:SI 0 "s_operand" "")
8581         (xor:SI (match_dup 0) (match_operand:SI 1 "immediate_operand" "")))
8582    (clobber (reg:CC CC_REGNUM))]
8583   "reload_completed"
8584   [(parallel
8585     [(set (match_dup 0) (xor:QI (match_dup 0) (match_dup 1)))
8586      (clobber (reg:CC CC_REGNUM))])]
8587   "s390_narrow_logical_operator (XOR, &operands[0], &operands[1]);")
8590 ; xorhi3 instruction pattern(s).
8593 (define_insn "*xorhi3"
8594   [(set (match_operand:HI 0 "nonimmediate_operand"         "=d,d,d,   AQ,Q")
8595         (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,d,    0,0")
8596                 (match_operand:HI 2 "general_operand"      "Os,d,d,NxQH0,Q")))
8597    (clobber (reg:CC CC_REGNUM))]
8598   "s390_logical_operator_ok_p (operands)"
8599   "@
8600    xilf\t%0,%x2
8601    xr\t%0,%2
8602    xrk\t%0,%1,%2
8603    #
8604    #"
8605   [(set_attr "op_type"  "RIL,RR,RRF,SI,SS")
8606    (set_attr "cpu_facility" "*,*,z196,*,*")
8607    (set_attr "z10prop" "z10_super_E1,z10_super_E1,*,*,*")])
8609 (define_split
8610   [(set (match_operand:HI 0 "s_operand" "")
8611         (xor:HI (match_dup 0) (match_operand:HI 1 "immediate_operand" "")))
8612    (clobber (reg:CC CC_REGNUM))]
8613   "reload_completed"
8614   [(parallel
8615     [(set (match_dup 0) (xor:QI (match_dup 0) (match_dup 1)))
8616      (clobber (reg:CC CC_REGNUM))])]
8617   "s390_narrow_logical_operator (XOR, &operands[0], &operands[1]);")
8620 ; xorqi3 instruction pattern(s).
8623 (define_insn "*xorqi3"
8624   [(set (match_operand:QI 0 "nonimmediate_operand"         "=d,d,d,Q,S,Q")
8625         (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,d,0,0,0")
8626                 (match_operand:QI 2 "general_operand"      "Os,d,d,n,n,Q")))
8627    (clobber (reg:CC CC_REGNUM))]
8628   "s390_logical_operator_ok_p (operands)"
8629   "@
8630    xilf\t%0,%b2
8631    xr\t%0,%2
8632    xrk\t%0,%1,%2
8633    xi\t%S0,%b2
8634    xiy\t%S0,%b2
8635    #"
8636   [(set_attr "op_type"  "RIL,RR,RRF,SI,SIY,SS")
8637    (set_attr "cpu_facility" "*,*,z196,*,longdisp,*")
8638    (set_attr "z10prop" "z10_super_E1,z10_super_E1,*,z10_super,z10_super,*")])
8642 ; Block exclusive or (XC) patterns.
8645 (define_insn "*xc"
8646   [(set (match_operand:BLK 0 "memory_operand" "=Q")
8647         (xor:BLK (match_dup 0)
8648                  (match_operand:BLK 1 "memory_operand" "Q")))
8649    (use (match_operand 2 "const_int_operand" "n"))
8650    (clobber (reg:CC CC_REGNUM))]
8651   "INTVAL (operands[2]) >= 1 && INTVAL (operands[2]) <= 256"
8652   "xc\t%O0(%2,%R0),%S1"
8653   [(set_attr "op_type" "SS")])
8655 (define_split
8656   [(set (match_operand 0 "memory_operand" "")
8657         (xor (match_dup 0)
8658              (match_operand 1 "memory_operand" "")))
8659    (clobber (reg:CC CC_REGNUM))]
8660   "reload_completed
8661    && GET_MODE (operands[0]) == GET_MODE (operands[1])
8662    && GET_MODE_SIZE (GET_MODE (operands[0])) > 0"
8663   [(parallel
8664     [(set (match_dup 0) (xor:BLK (match_dup 0) (match_dup 1)))
8665      (use (match_dup 2))
8666      (clobber (reg:CC CC_REGNUM))])]
8668   operands[2] = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[0])));
8669   operands[0] = adjust_address (operands[0], BLKmode, 0);
8670   operands[1] = adjust_address (operands[1], BLKmode, 0);
8673 (define_peephole2
8674   [(parallel
8675     [(set (match_operand:BLK 0 "memory_operand" "")
8676           (xor:BLK (match_dup 0)
8677                    (match_operand:BLK 1 "memory_operand" "")))
8678      (use (match_operand 2 "const_int_operand" ""))
8679      (clobber (reg:CC CC_REGNUM))])
8680    (parallel
8681     [(set (match_operand:BLK 3 "memory_operand" "")
8682           (xor:BLK (match_dup 3)
8683                    (match_operand:BLK 4 "memory_operand" "")))
8684      (use (match_operand 5 "const_int_operand" ""))
8685      (clobber (reg:CC CC_REGNUM))])]
8686   "s390_offset_p (operands[0], operands[3], operands[2])
8687    && s390_offset_p (operands[1], operands[4], operands[2])
8688    && !s390_overlap_p (operands[0], operands[1],
8689                        INTVAL (operands[2]) + INTVAL (operands[5]))
8690    && INTVAL (operands[2]) + INTVAL (operands[5]) <= 256"
8691   [(parallel
8692     [(set (match_dup 6) (xor:BLK (match_dup 6) (match_dup 7)))
8693      (use (match_dup 8))
8694      (clobber (reg:CC CC_REGNUM))])]
8695   "operands[6] = gen_rtx_MEM (BLKmode, XEXP (operands[0], 0));
8696    operands[7] = gen_rtx_MEM (BLKmode, XEXP (operands[1], 0));
8697    operands[8] = GEN_INT (INTVAL (operands[2]) + INTVAL (operands[5]));")
8700 ; Block xor (XC) patterns with src == dest.
8703 (define_insn "*xc_zero"
8704   [(set (match_operand:BLK 0 "memory_operand" "=Q")
8705         (const_int 0))
8706    (use (match_operand 1 "const_int_operand" "n"))
8707    (clobber (reg:CC CC_REGNUM))]
8708   "INTVAL (operands[1]) >= 1 && INTVAL (operands[1]) <= 256"
8709   "xc\t%O0(%1,%R0),%S0"
8710   [(set_attr "op_type" "SS")
8711    (set_attr "z196prop" "z196_cracked")])
8713 (define_peephole2
8714   [(parallel
8715     [(set (match_operand:BLK 0 "memory_operand" "")
8716           (const_int 0))
8717      (use (match_operand 1 "const_int_operand" ""))
8718      (clobber (reg:CC CC_REGNUM))])
8719    (parallel
8720     [(set (match_operand:BLK 2 "memory_operand" "")
8721           (const_int 0))
8722      (use (match_operand 3 "const_int_operand" ""))
8723      (clobber (reg:CC CC_REGNUM))])]
8724   "s390_offset_p (operands[0], operands[2], operands[1])
8725    && INTVAL (operands[1]) + INTVAL (operands[3]) <= 256"
8726   [(parallel
8727     [(set (match_dup 4) (const_int 0))
8728      (use (match_dup 5))
8729      (clobber (reg:CC CC_REGNUM))])]
8730   "operands[4] = gen_rtx_MEM (BLKmode, XEXP (operands[0], 0));
8731    operands[5] = GEN_INT (INTVAL (operands[1]) + INTVAL (operands[3]));")
8734 ;- Nxor instructions.
8737 ; nxrk, nxgrk
8738 (define_insn "*nxor<GPR:mode>_cc"
8739   [(set (reg CC_REGNUM)
8740         (compare
8741          (not:GPR (xor:GPR (match_operand:GPR 1 "register_operand" "d")
8742                            (match_operand:GPR 2 "register_operand" "d")))
8743          (const_int 0)))
8744    (set (match_operand:GPR 0 "register_operand" "=d")
8745         (xor:GPR (not:GPR (match_dup 1))
8746                     (match_dup 2)))]
8747   "TARGET_Z15 && s390_match_ccmode(insn, CCTmode)"
8748   "nx<GPR:g>rk\t%0,%1,%2"
8749   [(set_attr "op_type" "RRF")])
8751 ; nxrk, nxgrk
8752 (define_insn "*nxor<mode>_cconly"
8753   [(set (reg CC_REGNUM)
8754         (compare
8755          (not:GPR (xor:GPR (match_operand:GPR 1 "register_operand" "d")
8756                            (match_operand:GPR 2 "register_operand" "d")))
8757          (const_int 0)))
8758    (clobber (match_scratch:GPR 0 "=d"))]
8759   "TARGET_Z15 && s390_match_ccmode(insn, CCTmode)"
8760   "nx<GPR:g>rk\t%0,%1,%2"
8761   [(set_attr "op_type" "RRF")])
8763 ; nxrk, nxgrk
8764 (define_insn "*nxor<mode>"
8765   [(set (match_operand:GPR 0 "register_operand" "=d")
8766         (not:GPR (xor:GPR (match_operand:GPR 1 "register_operand" "d")
8767                           (match_operand:GPR 2 "register_operand" "d"))))
8768    (clobber (reg:CC CC_REGNUM))]
8769   "TARGET_Z15"
8770   "nx<GPR:g>rk\t%0,%1,%2"
8771   [(set_attr "op_type" "RRF")])
8774 ;;- Negate instructions.
8778 ; neg(di|si)2 instruction pattern(s).
8781 (define_expand "neg<mode>2"
8782   [(parallel
8783     [(set (match_operand:DSI 0 "register_operand" "=d")
8784           (neg:DSI (match_operand:DSI 1 "register_operand" "d")))
8785      (clobber (reg:CC CC_REGNUM))])]
8786   ""
8787   "")
8789 (define_insn "*negdi2_sign_cc"
8790   [(set (reg CC_REGNUM)
8791         (compare (neg:DI (ashiftrt:DI (ashift:DI (subreg:DI
8792                            (match_operand:SI 1 "register_operand" "d") 0)
8793                            (const_int 32)) (const_int 32)))
8794                  (const_int 0)))
8795    (set (match_operand:DI 0 "register_operand" "=d")
8796         (neg:DI (sign_extend:DI (match_dup 1))))]
8797   "TARGET_ZARCH && s390_match_ccmode (insn, CCAmode)"
8798   "lcgfr\t%0,%1"
8799   [(set_attr "op_type"  "RRE")
8800    (set_attr "z10prop" "z10_c")])
8802 (define_insn "*negdi2_sign"
8803   [(set (match_operand:DI 0 "register_operand" "=d")
8804         (neg:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "d"))))
8805    (clobber (reg:CC CC_REGNUM))]
8806   "TARGET_ZARCH"
8807   "lcgfr\t%0,%1"
8808   [(set_attr "op_type"  "RRE")
8809    (set_attr "z10prop" "z10_c")])
8811 ; lcr, lcgr
8812 (define_insn "*neg<mode>2_cc"
8813   [(set (reg CC_REGNUM)
8814         (compare (neg:GPR (match_operand:GPR 1 "register_operand" "d"))
8815                  (const_int 0)))
8816    (set (match_operand:GPR 0 "register_operand" "=d")
8817         (neg:GPR (match_dup 1)))]
8818   "s390_match_ccmode (insn, CCAmode)"
8819   "lc<g>r\t%0,%1"
8820   [(set_attr "op_type"  "RR<E>")
8821    (set_attr "z10prop" "z10_super_c_E1")])
8823 ; lcr, lcgr
8824 (define_insn "*neg<mode>2_cconly"
8825   [(set (reg CC_REGNUM)
8826         (compare (neg:GPR (match_operand:GPR 1 "register_operand" "d"))
8827                  (const_int 0)))
8828    (clobber (match_scratch:GPR 0 "=d"))]
8829   "s390_match_ccmode (insn, CCAmode)"
8830   "lc<g>r\t%0,%1"
8831   [(set_attr "op_type"  "RR<E>")
8832    (set_attr "z10prop" "z10_super_c_E1")])
8834 ; lcr, lcgr
8835 (define_insn "*neg<mode>2"
8836   [(set (match_operand:GPR 0 "register_operand" "=d")
8837         (neg:GPR (match_operand:GPR 1 "register_operand" "d")))
8838    (clobber (reg:CC CC_REGNUM))]
8839   ""
8840   "lc<g>r\t%0,%1"
8841   [(set_attr "op_type"  "RR<E>")
8842    (set_attr "z10prop" "z10_super_c_E1")])
8844 (define_insn "*negdi2_31"
8845   [(set (match_operand:DI 0 "register_operand" "=d")
8846         (neg:DI (match_operand:DI 1 "register_operand" "d")))
8847    (clobber (reg:CC CC_REGNUM))]
8848   "!TARGET_ZARCH"
8849   "#")
8851 ; Split a DImode NEG on 31bit into 2 SImode NEGs
8853 ; Doing the twos complement separately on the SImode parts does an
8854 ; unwanted +1 on the high part which needs to be subtracted afterwards
8855 ; ... unless the +1 on the low part created an overflow.
8857 (define_split
8858   [(set (match_operand:DI 0 "register_operand" "")
8859         (neg:DI (match_operand:DI 1 "register_operand" "")))
8860    (clobber (reg:CC CC_REGNUM))]
8861   "!TARGET_ZARCH
8862    && reload_completed
8863    && ((REG_P (operands[0]) && REG_P (operands[1])
8864        && REGNO (operands[0]) == REGNO (operands[1]))
8865       || s390_split_ok_p (operands[0], operands[1], DImode, 0))"
8866   [(parallel
8867     [(set (match_dup 2) (neg:SI (match_dup 3)))
8868      (clobber (reg:CC CC_REGNUM))])
8869    (parallel
8870     [(set (reg:CCAP CC_REGNUM)
8871           (compare:CCAP (neg:SI (match_dup 5)) (const_int 0)))
8872      (set (match_dup 4) (neg:SI (match_dup 5)))])
8873    (set (pc)
8874         (if_then_else (ne (reg:CCAP CC_REGNUM) (const_int 0))
8875                       (pc)
8876                       (label_ref (match_dup 6))))
8877    (parallel
8878     [(set (match_dup 2) (plus:SI (match_dup 2) (const_int -1)))
8879      (clobber (reg:CC CC_REGNUM))])
8880    (match_dup 6)]
8881   "operands[2] = operand_subword (operands[0], 0, 0, DImode);
8882    operands[3] = operand_subword (operands[1], 0, 0, DImode);
8883    operands[4] = operand_subword (operands[0], 1, 0, DImode);
8884    operands[5] = operand_subword (operands[1], 1, 0, DImode);
8885    operands[6] = gen_label_rtx ();")
8887 ; Like above but first make a copy of the low part of the src operand
8888 ; since it might overlap with the high part of the destination.
8890 (define_split
8891   [(set (match_operand:DI 0 "register_operand" "")
8892         (neg:DI (match_operand:DI 1 "register_operand" "")))
8893    (clobber (reg:CC CC_REGNUM))]
8894   "!TARGET_ZARCH
8895    && s390_split_ok_p (operands[0], operands[1], DImode, 1)
8896    && reload_completed"
8897   [; Make a backup of op5 first
8898    (set (match_dup 4) (match_dup 5))
8899    ; Setting op2 here might clobber op5
8900    (parallel
8901     [(set (match_dup 2) (neg:SI (match_dup 3)))
8902      (clobber (reg:CC CC_REGNUM))])
8903    (parallel
8904     [(set (reg:CCAP CC_REGNUM)
8905           (compare:CCAP (neg:SI (match_dup 4)) (const_int 0)))
8906      (set (match_dup 4) (neg:SI (match_dup 4)))])
8907    (set (pc)
8908         (if_then_else (ne (reg:CCAP CC_REGNUM) (const_int 0))
8909                       (pc)
8910                       (label_ref (match_dup 6))))
8911    (parallel
8912     [(set (match_dup 2) (plus:SI (match_dup 2) (const_int -1)))
8913      (clobber (reg:CC CC_REGNUM))])
8914    (match_dup 6)]
8915   "operands[2] = operand_subword (operands[0], 0, 0, DImode);
8916    operands[3] = operand_subword (operands[1], 0, 0, DImode);
8917    operands[4] = operand_subword (operands[0], 1, 0, DImode);
8918    operands[5] = operand_subword (operands[1], 1, 0, DImode);
8919    operands[6] = gen_label_rtx ();")
8922 ; neg(tf|df|sf)2 instruction pattern(s).
8925 (define_expand "neg<mode>2<tf_fpr>"
8926   [(parallel
8927     [(set (match_operand:BFP          0 "register_operand")
8928           (neg:BFP (match_operand:BFP 1 "register_operand")))
8929      (clobber (reg:CC CC_REGNUM))])]
8930   "TARGET_HARD_FLOAT")
8932 ; lcxbr, lcdbr, lcebr
8933 (define_insn "*neg<mode>2_cc"
8934   [(set (reg CC_REGNUM)
8935         (compare (neg:BFP (match_operand:BFP 1 "register_operand" "f"))
8936                  (match_operand:BFP 2 "const0_operand" "")))
8937    (set (match_operand:BFP 0 "register_operand" "=f")
8938         (neg:BFP (match_dup 1)))]
8939   "s390_match_ccmode (insn, CCSmode) && TARGET_HARD_FLOAT"
8940   "lc<xde>br\t%0,%1"
8941   [(set_attr "op_type"  "RRE")
8942    (set_attr "type"     "fsimp<type>")])
8944 ; lcxbr, lcdbr, lcebr
8945 (define_insn "*neg<mode>2_cconly"
8946   [(set (reg CC_REGNUM)
8947         (compare (neg:BFP (match_operand:BFP 1 "register_operand" "f"))
8948                  (match_operand:BFP 2 "const0_operand" "")))
8949    (clobber (match_scratch:BFP 0 "=f"))]
8950   "s390_match_ccmode (insn, CCSmode) && TARGET_HARD_FLOAT"
8951   "lc<xde>br\t%0,%1"
8952   [(set_attr "op_type"  "RRE")
8953    (set_attr "type"     "fsimp<type>")])
8955 ; lcdfr
8956 (define_insn "*neg<mode>2_nocc"
8957   [(set (match_operand:FP 0 "register_operand"         "=f")
8958         (neg:FP (match_operand:FP 1 "register_operand" "<fT0>")))]
8959   "TARGET_DFP"
8960   "lcdfr\t%0,%1"
8961   [(set_attr "op_type"  "RRE")
8962    (set_attr "type"     "fsimp<type>")])
8964 ; lcxbr, lcdbr, lcebr
8965 ; FIXME: wflcdb does not clobber cc
8966 ; FIXME: Does wflcdb ever match here?
8967 (define_insn "*neg<mode>2"
8968   [(set (match_operand:BFP          0 "register_operand" "=f,v,v")
8969         (neg:BFP (match_operand:BFP 1 "register_operand"  "f,v,v")))
8970    (clobber (reg:CC CC_REGNUM))]
8971   "TARGET_HARD_FLOAT"
8972   "@
8973    lc<xde>br\t%0,%1
8974    wflcdb\t%0,%1
8975    wflcsb\t%0,%1"
8976   [(set_attr "op_type"      "RRE,VRR,VRR")
8977    (set_attr "cpu_facility" "*,vx,vxe")
8978    (set_attr "type"         "fsimp<type>,*,*")
8979    (set_attr "enabled"      "*,<DF>,<SF>")])
8983 ;;- Absolute value instructions.
8987 ; abs(di|si)2 instruction pattern(s).
8990 (define_insn "*absdi2_sign_cc"
8991   [(set (reg CC_REGNUM)
8992         (compare (abs:DI (ashiftrt:DI (ashift:DI (subreg:DI
8993                            (match_operand:SI 1 "register_operand" "d") 0)
8994                            (const_int 32)) (const_int 32)))
8995                  (const_int 0)))
8996    (set (match_operand:DI 0 "register_operand" "=d")
8997         (abs:DI (sign_extend:DI (match_dup 1))))]
8998   "TARGET_ZARCH && s390_match_ccmode (insn, CCAmode)"
8999   "lpgfr\t%0,%1"
9000   [(set_attr "op_type"  "RRE")
9001    (set_attr "z10prop" "z10_c")])
9003 (define_insn "*absdi2_sign"
9004   [(set (match_operand:DI 0 "register_operand" "=d")
9005         (abs:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "d"))))
9006    (clobber (reg:CC CC_REGNUM))]
9007   "TARGET_ZARCH"
9008   "lpgfr\t%0,%1"
9009   [(set_attr "op_type"  "RRE")
9010    (set_attr "z10prop" "z10_c")])
9012 ; lpr, lpgr
9013 (define_insn "*abs<mode>2_cc"
9014   [(set (reg CC_REGNUM)
9015         (compare (abs:GPR (match_operand:DI 1 "register_operand" "d"))
9016                  (const_int 0)))
9017    (set (match_operand:GPR 0 "register_operand" "=d")
9018         (abs:GPR (match_dup 1)))]
9019   "s390_match_ccmode (insn, CCAmode)"
9020   "lp<g>r\t%0,%1"
9021   [(set_attr "op_type"  "RR<E>")
9022    (set_attr "z10prop" "z10_c")])
9024 ; lpr, lpgr
9025 (define_insn "*abs<mode>2_cconly"
9026   [(set (reg CC_REGNUM)
9027         (compare (abs:GPR (match_operand:GPR 1 "register_operand" "d"))
9028                  (const_int 0)))
9029    (clobber (match_scratch:GPR 0 "=d"))]
9030   "s390_match_ccmode (insn, CCAmode)"
9031   "lp<g>r\t%0,%1"
9032   [(set_attr "op_type"  "RR<E>")
9033    (set_attr "z10prop" "z10_c")])
9035 ; lpr, lpgr
9036 (define_insn "abs<mode>2"
9037   [(set (match_operand:GPR 0 "register_operand" "=d")
9038         (abs:GPR (match_operand:GPR 1 "register_operand" "d")))
9039    (clobber (reg:CC CC_REGNUM))]
9040   ""
9041   "lp<g>r\t%0,%1"
9042   [(set_attr "op_type"  "RR<E>")
9043    (set_attr "z10prop" "z10_c")])
9046 ; abs(tf|df|sf)2 instruction pattern(s).
9049 (define_expand "abs<mode>2<tf_fpr>"
9050   [(parallel
9051     [(set (match_operand:BFP 0 "register_operand" "=f")
9052           (abs:BFP (match_operand:BFP 1 "register_operand" "f")))
9053      (clobber (reg:CC CC_REGNUM))])]
9054   "TARGET_HARD_FLOAT"
9055   "")
9057 ; lpxbr, lpdbr, lpebr
9058 (define_insn "*abs<mode>2_cc"
9059   [(set (reg CC_REGNUM)
9060         (compare (abs:BFP (match_operand:BFP 1 "register_operand" "f"))
9061                  (match_operand:BFP 2 "const0_operand" "")))
9062    (set (match_operand:BFP 0 "register_operand" "=f")
9063         (abs:BFP (match_dup 1)))]
9064   "s390_match_ccmode (insn, CCSmode) && TARGET_HARD_FLOAT"
9065   "lp<xde>br\t%0,%1"
9066   [(set_attr "op_type"  "RRE")
9067    (set_attr "type"     "fsimp<type>")])
9069 ; lpxbr, lpdbr, lpebr
9070 (define_insn "*abs<mode>2_cconly"
9071   [(set (reg CC_REGNUM)
9072         (compare (abs:BFP (match_operand:BFP 1 "register_operand" "f"))
9073                  (match_operand:BFP 2 "const0_operand" "")))
9074    (clobber (match_scratch:BFP 0 "=f"))]
9075   "s390_match_ccmode (insn, CCSmode) && TARGET_HARD_FLOAT"
9076   "lp<xde>br\t%0,%1"
9077   [(set_attr "op_type"  "RRE")
9078    (set_attr "type"     "fsimp<type>")])
9080 ; lpdfr
9081 (define_insn "*abs<mode>2_nocc"
9082   [(set (match_operand:FP 0 "register_operand"         "=f")
9083         (abs:FP (match_operand:FP 1 "register_operand" "<fT0>")))]
9084   "TARGET_DFP"
9085   "lpdfr\t%0,%1"
9086   [(set_attr "op_type"  "RRE")
9087    (set_attr "type"     "fsimp<type>")])
9089 ; lpxbr, lpdbr, lpebr
9090 ; FIXME: wflpdb does not clobber cc
9091 (define_insn "*abs<mode>2"
9092   [(set (match_operand:BFP          0 "register_operand" "=f,v")
9093         (abs:BFP (match_operand:BFP 1 "register_operand"  "f,v")))
9094    (clobber (reg:CC CC_REGNUM))]
9095   "TARGET_HARD_FLOAT"
9096   "@
9097     lp<xde>br\t%0,%1
9098     wflpdb\t%0,%1"
9099   [(set_attr "op_type"      "RRE,VRR")
9100    (set_attr "cpu_facility" "*,vx")
9101    (set_attr "type"         "fsimp<type>,*")
9102    (set_attr "enabled"      "*,<DFDI>")])
9106 ;;- Negated absolute value instructions
9110 ; Integer
9113 (define_insn "*negabsdi2_sign_cc"
9114   [(set (reg CC_REGNUM)
9115         (compare (neg:DI (abs:DI (ashiftrt:DI (ashift:DI (subreg:DI
9116                            (match_operand:SI 1 "register_operand" "d") 0)
9117                            (const_int 32)) (const_int 32))))
9118                  (const_int 0)))
9119    (set (match_operand:DI 0 "register_operand" "=d")
9120         (neg:DI (abs:DI (sign_extend:DI (match_dup 1)))))]
9121   "TARGET_ZARCH && s390_match_ccmode (insn, CCAmode)"
9122   "lngfr\t%0,%1"
9123   [(set_attr "op_type"  "RRE")
9124    (set_attr "z10prop" "z10_c")])
9126 (define_insn "*negabsdi2_sign"
9127   [(set (match_operand:DI 0 "register_operand" "=d")
9128         (neg:DI (abs:DI (sign_extend:DI
9129                           (match_operand:SI 1 "register_operand" "d")))))
9130    (clobber (reg:CC CC_REGNUM))]
9131   "TARGET_ZARCH"
9132   "lngfr\t%0,%1"
9133   [(set_attr "op_type" "RRE")
9134    (set_attr "z10prop" "z10_c")])
9136 ; lnr, lngr
9137 (define_insn "*negabs<mode>2_cc"
9138   [(set (reg CC_REGNUM)
9139         (compare (neg:GPR (abs:GPR (match_operand:GPR 1 "register_operand" "d")))
9140                  (const_int 0)))
9141    (set (match_operand:GPR 0 "register_operand" "=d")
9142         (neg:GPR (abs:GPR (match_dup 1))))]
9143   "s390_match_ccmode (insn, CCAmode)"
9144   "ln<g>r\t%0,%1"
9145   [(set_attr "op_type"  "RR<E>")
9146    (set_attr "z10prop" "z10_c")])
9148 ; lnr, lngr
9149 (define_insn "*negabs<mode>2_cconly"
9150   [(set (reg CC_REGNUM)
9151         (compare (neg:GPR (abs:GPR (match_operand:GPR 1 "register_operand" "d")))
9152                  (const_int 0)))
9153    (clobber (match_scratch:GPR 0 "=d"))]
9154   "s390_match_ccmode (insn, CCAmode)"
9155   "ln<g>r\t%0,%1"
9156   [(set_attr "op_type"  "RR<E>")
9157    (set_attr "z10prop" "z10_c")])
9159 ; lnr, lngr
9160 (define_insn "*negabs<mode>2"
9161   [(set (match_operand:GPR 0 "register_operand" "=d")
9162         (neg:GPR (abs:GPR (match_operand:GPR 1 "register_operand" "d"))))
9163    (clobber (reg:CC CC_REGNUM))]
9164   ""
9165   "ln<g>r\t%0,%1"
9166   [(set_attr "op_type" "RR<E>")
9167    (set_attr "z10prop" "z10_c")])
9170 ; Floating point
9173 ; lnxbr, lndbr, lnebr
9174 (define_insn "*negabs<mode>2_cc"
9175   [(set (reg CC_REGNUM)
9176         (compare (neg:BFP (abs:BFP (match_operand:BFP 1 "register_operand" "f")))
9177                  (match_operand:BFP 2 "const0_operand" "")))
9178    (set (match_operand:BFP 0 "register_operand" "=f")
9179         (neg:BFP (abs:BFP (match_dup 1))))]
9180   "s390_match_ccmode (insn, CCSmode) && TARGET_HARD_FLOAT"
9181   "ln<xde>br\t%0,%1"
9182   [(set_attr "op_type"  "RRE")
9183    (set_attr "type"     "fsimp<type>")])
9185 ; lnxbr, lndbr, lnebr
9186 (define_insn "*negabs<mode>2_cconly"
9187   [(set (reg CC_REGNUM)
9188         (compare (neg:BFP (abs:BFP (match_operand:BFP 1 "register_operand" "f")))
9189                  (match_operand:BFP 2 "const0_operand" "")))
9190    (clobber (match_scratch:BFP 0 "=f"))]
9191   "s390_match_ccmode (insn, CCSmode) && TARGET_HARD_FLOAT"
9192   "ln<xde>br\t%0,%1"
9193   [(set_attr "op_type"  "RRE")
9194    (set_attr "type"     "fsimp<type>")])
9196 ; lndfr
9197 (define_insn "*negabs<mode>2_nocc"
9198   [(set (match_operand:FP 0 "register_operand"                 "=f")
9199         (neg:FP (abs:FP (match_operand:FP 1 "register_operand" "<fT0>"))))]
9200   "TARGET_DFP"
9201   "lndfr\t%0,%1"
9202   [(set_attr "op_type"  "RRE")
9203    (set_attr "type"     "fsimp<type>")])
9205 ; lnxbr, lndbr, lnebr
9206 ; FIXME: wflndb does not clobber cc
9207 (define_insn "*negabs<mode>2"
9208   [(set (match_operand:BFP                   0 "register_operand" "=f,v")
9209         (neg:BFP (abs:BFP (match_operand:BFP 1 "register_operand"  "f,v"))))
9210    (clobber (reg:CC CC_REGNUM))]
9211   "TARGET_HARD_FLOAT"
9212   "@
9213    ln<xde>br\t%0,%1
9214    wflndb\t%0,%1"
9215   [(set_attr "op_type"      "RRE,VRR")
9216    (set_attr "cpu_facility" "*,vx")
9217    (set_attr "type"         "fsimp<type>,*")
9218    (set_attr "enabled"      "*,<DFDI>")])
9221 ;;- Square root instructions.
9225 ; sqrt(df|sf)2 instruction pattern(s).
9228 ; sqxbr, sqdbr, sqebr, sqdb, sqeb
9229 (define_insn "sqrt<mode>2<tf_fpr>"
9230   [(set (match_operand:BFP           0 "register_operand" "=f,f,v")
9231         (sqrt:BFP (match_operand:BFP 1 "general_operand"   "f,R,v")))]
9232   "TARGET_HARD_FLOAT"
9233   "@
9234    sq<xde>br\t%0,%1
9235    sq<xde>b\t%0,%1
9236    wfsqdb\t%v0,%v1"
9237   [(set_attr "op_type"      "RRE,RXE,VRR")
9238    (set_attr "type"         "fsqrt<type>")
9239    (set_attr "cpu_facility" "*,*,vx")
9240    (set_attr "enabled"      "*,<DSF>,<DFDI>")])
9244 ;;- One complement instructions.
9248 ; one_cmpl(di|si|hi|qi)2 instruction pattern(s).
9251 (define_expand "one_cmpl<mode>2"
9252   [(parallel
9253     [(set (match_operand:INT 0 "register_operand" "")
9254           (xor:INT (match_operand:INT 1 "register_operand" "")
9255                    (const_int -1)))
9256      (clobber (reg:CC CC_REGNUM))])]
9257   ""
9258   "")
9262 ;; Find leftmost bit instructions.
9265 (define_expand "clzdi2"
9266   [(set (match_operand:DI 0 "register_operand" "=d")
9267         (clz:DI (match_operand:DI 1 "register_operand" "d")))]
9268   "TARGET_EXTIMM && TARGET_ZARCH"
9270   rtx_insn *insn;
9271   rtx clz_equal;
9272   rtx wide_reg = gen_reg_rtx (TImode);
9273   rtx msb = gen_rtx_CONST_INT (DImode, HOST_WIDE_INT_1U << 63);
9275   clz_equal = gen_rtx_CLZ (DImode, operands[1]);
9277   emit_insn (gen_clztidi2 (wide_reg, operands[1], msb));
9279   insn = emit_move_insn (operands[0], gen_highpart (DImode, wide_reg));
9280   set_unique_reg_note (insn, REG_EQUAL, clz_equal);
9282   DONE;
9285 ; CLZ result is in hard reg op0 - this is the high part of the target operand
9286 ; The source with the left-most one bit cleared is in hard reg op0 + 1 - the low part
9287 (define_insn "clztidi2"
9288   [(set (match_operand:TI 0 "register_operand" "=d")
9289         (ior:TI
9290           (ashift:TI (zero_extend:TI (clz:DI (match_operand:DI 1 "register_operand" "d")))
9291                      (const_int 64))
9292           (zero_extend:TI
9293            (xor:DI (match_dup 1)
9294                    (lshiftrt (match_operand:DI 2 "const_int_operand" "")
9295                              (subreg:SI (clz:DI (match_dup 1)) 4))))))
9296    (clobber (reg:CC CC_REGNUM))]
9297   "UINTVAL (operands[2]) == HOST_WIDE_INT_1U << 63
9298    && TARGET_EXTIMM && TARGET_ZARCH"
9299   "flogr\t%0,%1"
9300   [(set_attr "op_type"  "RRE")])
9304 ;;- Rotate instructions.
9308 ; rotl(di|si)3 instruction pattern(s).
9311 (define_expand "rotl<mode>3"
9312   [(set (match_operand:GPR 0 "register_operand" "")
9313         (rotate:GPR (match_operand:GPR 1 "register_operand" "")
9314                     (match_operand:QI 2 "shift_count_operand" "")))]
9315   ""
9316   "")
9318 ; rll, rllg
9319 (define_insn "*rotl<mode>3"
9320   [(set (match_operand:GPR             0 "register_operand"  "=d")
9321         (rotate:GPR (match_operand:GPR 1 "register_operand"   "d")
9322                     (match_operand:QI  2 "shift_count_operand" "jsc")))]
9323   ""
9324   "rll<g>\t%0,%1,%Y2"
9325   [(set_attr "op_type"  "RSE")
9326    (set_attr "atype"    "reg")
9327    (set_attr "z10prop"  "z10_super_E1")])
9331 ;;- Shift instructions.
9335 ; (ashl|lshr)(di|si)3 instruction pattern(s).
9336 ; Left shifts and logical right shifts
9338 (define_expand "<shift><mode>3"
9339   [(set (match_operand:DSI 0 "register_operand" "")
9340         (SHIFT:DSI (match_operand:DSI 1 "register_operand" "")
9341                    (match_operand:QI 2 "shift_count_operand" "")))]
9342   ""
9343   "")
9345 ; ESA 64 bit register pair shift with reg or imm shift count
9346 ; sldl, srdl
9347 (define_insn "*<shift>di3_31"
9348   [(set (match_operand:DI 0 "register_operand"            "=d")
9349         (SHIFT:DI (match_operand:DI 1 "register_operand"   "0")
9350                   (match_operand:QI 2 "shift_count_operand" "jsc")))]
9351   "!TARGET_ZARCH"
9352   "s<lr>dl\t%0,%Y2"
9353   [(set_attr "op_type"  "RS")
9354    (set_attr "atype"    "reg")
9355    (set_attr "z196prop" "z196_cracked")])
9358 ; 64 bit register shift with reg or imm shift count
9359 ; sll, srl, sllg, srlg, sllk, srlk
9360 (define_insn "*<shift><mode>3"
9361   [(set (match_operand:GPR 0 "register_operand"              "=d, d")
9362         (SHIFT:GPR (match_operand:GPR 1 "register_operand" "<d0>, d")
9363                    (match_operand:QI 2 "shift_count_operand"   "jsc,jsc")))]
9364   ""
9365   "@
9366    s<lr>l<g>\t%0,<1>%Y2
9367    s<lr>l<gk>\t%0,%1,%Y2"
9368   [(set_attr "op_type"  "RS<E>,RSY")
9369    (set_attr "atype"    "reg,reg")
9370    (set_attr "cpu_facility" "*,z196")
9371    (set_attr "z10prop"  "z10_super_E1,*")])
9375 ; ashr(di|si)3 instruction pattern(s).
9376 ; Arithmetic right shifts
9378 (define_expand "ashr<mode>3"
9379   [(parallel
9380     [(set (match_operand:DSI 0 "register_operand" "")
9381           (ashiftrt:DSI (match_operand:DSI 1 "register_operand" "")
9382                         (match_operand:QI 2 "shift_count_operand" "")))
9383      (clobber (reg:CC CC_REGNUM))])]
9384   ""
9385   "")
9387 (define_insn "*ashrdi3_31<setcc><cconly>"
9388   [(set (match_operand:DI 0 "register_operand"               "=d")
9389         (ashiftrt:DI (match_operand:DI 1 "register_operand"   "0")
9390                      (match_operand:QI 2 "shift_count_operand" "jsc")))
9391    (clobber (reg:CC CC_REGNUM))]
9392   "!TARGET_ZARCH"
9393   "srda\t%0,%Y2"
9394   [(set_attr "op_type" "RS")
9395    (set_attr "atype"   "reg")])
9398 ; sra, srag
9399 (define_insn "*ashr<mode>3<setcc><cconly>"
9400   [(set (match_operand:GPR 0 "register_operand"                 "=d, d")
9401         (ashiftrt:GPR (match_operand:GPR 1 "register_operand" "<d0>, d")
9402                       (match_operand:QI 2 "shift_count_operand"   "jsc,jsc")))
9403    (clobber (reg:CC CC_REGNUM))]
9404   ""
9405   "@
9406    sra<g>\t%0,<1>%Y2
9407    sra<gk>\t%0,%1,%Y2"
9408   [(set_attr "op_type"  "RS<E>,RSY")
9409    (set_attr "atype"    "reg")
9410    (set_attr "cpu_facility" "*,z196")
9411    (set_attr "z10prop" "z10_super_E1,*")])
9415 ;; Branch instruction patterns.
9418 (define_expand "cbranch<mode>4"
9419   [(set (pc)
9420         (if_then_else (match_operator 0 "comparison_operator"
9421                        [(match_operand:GPR 1 "register_operand" "")
9422                         (match_operand:GPR 2 "general_operand" "")])
9423                       (label_ref (match_operand 3 "" ""))
9424                       (pc)))]
9425   ""
9426   "s390_emit_jump (operands[3],
9427     s390_emit_compare (GET_CODE (operands[0]), operands[1], operands[2]));
9428    DONE;")
9430 (define_expand "cbranch<mode>4"
9431   [(set (pc)
9432         (if_then_else (match_operator 0 "comparison_operator"
9433                        [(match_operand:FP_ANYTF 1 "register_operand" "")
9434                         (match_operand:FP_ANYTF 2 "general_operand" "")])
9435                       (label_ref (match_operand 3 "" ""))
9436                       (pc)))]
9437   "TARGET_HARD_FLOAT"
9438   "s390_emit_jump (operands[3],
9439     s390_emit_compare (GET_CODE (operands[0]), operands[1], operands[2]));
9440    DONE;")
9442 (define_expand "cbranchcc4"
9443   [(set (pc)
9444         (if_then_else (match_operator 0 "s390_comparison"
9445                        [(match_operand 1 "cc_reg_operand" "")
9446                         (match_operand 2 "const_int_operand" "")])
9447                       (label_ref (match_operand 3 "" ""))
9448                       (pc)))]
9449   ""
9450   "")
9454 ;;- Conditional jump instructions.
9457 (define_insn "*cjump_64"
9458   [(set (pc)
9459         (if_then_else
9460           (match_operator 1 "s390_comparison" [(reg CC_REGNUM)
9461                                                (match_operand 2 "const_int_operand" "")])
9462           (label_ref (match_operand 0 "" ""))
9463           (pc)))]
9464   ""
9466   if (get_attr_length (insn) == 4)
9467     return "j%C1\t%l0";
9468   else
9469     return "jg%C1\t%l0";
9471   [(set_attr "op_type" "RI")
9472    (set_attr "type"    "branch")
9473    (set (attr "length")
9474         (if_then_else (lt (abs (minus (pc) (match_dup 0))) (const_int 60000))
9475                       (const_int 4) (const_int 6)))])
9477 (define_insn "*cjump_long"
9478   [(set (pc)
9479         (if_then_else
9480           (match_operator 1 "s390_comparison" [(reg CC_REGNUM) (const_int 0)])
9481           (match_operand 0 "address_operand" "ZQZR")
9482           (pc)))]
9483   "!TARGET_INDIRECT_BRANCH_NOBP_JUMP"
9485   if (get_attr_op_type (insn) == OP_TYPE_RR)
9486     return "b%C1r\t%0";
9487   else
9488     return "b%C1\t%a0";
9490   [(set (attr "op_type")
9491         (if_then_else (match_operand 0 "register_operand" "")
9492                       (const_string "RR") (const_string "RX")))
9493    (set (attr "mnemonic")
9494         (if_then_else (match_operand 0 "register_operand" "")
9495                       (const_string "bcr") (const_string "bc")))
9496    (set_attr "type"  "branch")
9497    (set_attr "atype" "agen")])
9499 ;; A conditional return instruction.
9500 (define_insn "*c<code>"
9501   [(set (pc)
9502         (if_then_else
9503           (match_operator 0 "s390_comparison" [(reg CC_REGNUM) (const_int 0)])
9504           (ANY_RETURN)
9505           (pc)))]
9506   "s390_can_use_<code>_insn ()"
9508   if (TARGET_INDIRECT_BRANCH_NOBP_RET)
9509     {
9510       s390_indirect_branch_via_thunk (RETURN_REGNUM,
9511                                       INVALID_REGNUM,
9512                                       operands[0],
9513                                       s390_indirect_branch_type_return);
9514       return "";
9515     }
9516   else
9517     return "b%C0r\t%%r14";
9519   [(set (attr "op_type")
9520         (if_then_else (match_test "TARGET_INDIRECT_BRANCH_NOBP_RET")
9521                       (const_string "RIL")
9522                       (const_string "RR")))
9523    (set (attr "mnemonic")
9524         (if_then_else (match_test "TARGET_INDIRECT_BRANCH_NOBP_RET")
9525                       (const_string "brcl")
9526                       (const_string "bcr")))
9527    (set_attr "type"  "jsr")
9528    (set_attr "atype" "agen")])
9531 ;;- Negated conditional jump instructions.
9534 (define_insn "*icjump_64"
9535   [(set (pc)
9536         (if_then_else
9537           (match_operator 1 "s390_comparison" [(reg CC_REGNUM)
9538                                                (match_operand 2 "const_int_operand" "")])
9539           (pc)
9540           (label_ref (match_operand 0 "" ""))))]
9541   ""
9543   if (get_attr_length (insn) == 4)
9544     return "j%D1\t%l0";
9545   else
9546     return "jg%D1\t%l0";
9548   [(set_attr "op_type" "RI")
9549    (set_attr "type"    "branch")
9550    (set (attr "length")
9551         (if_then_else (lt (abs (minus (pc) (match_dup 0))) (const_int 60000))
9552                       (const_int 4) (const_int 6)))])
9554 (define_insn "*icjump_long"
9555   [(set (pc)
9556         (if_then_else
9557           (match_operator 1 "s390_comparison" [(reg CC_REGNUM) (const_int 0)])
9558           (pc)
9559           (match_operand 0 "address_operand" "ZQZR")))]
9560   "!TARGET_INDIRECT_BRANCH_NOBP_JUMP"
9562   if (get_attr_op_type (insn) == OP_TYPE_RR)
9563     return "b%D1r\t%0";
9564   else
9565     return "b%D1\t%a0";
9567   [(set (attr "op_type")
9568         (if_then_else (match_operand 0 "register_operand" "")
9569                       (const_string "RR") (const_string "RX")))
9570    (set (attr "mnemonic")
9571         (if_then_else (match_operand 0 "register_operand" "")
9572                       (const_string "bcr") (const_string "bc")))
9573    (set_attr "type"  "branch")
9574    (set_attr "atype" "agen")])
9577 ;;- Trap instructions.
9580 (define_insn "trap"
9581   [(trap_if (const_int 1) (const_int 0))]
9582   ""
9583   "j\t.+2"
9584   [(set_attr "op_type" "RI")
9585    (set_attr "type"  "branch")])
9587 (define_expand "ctrap<mode>4"
9588   [(trap_if (match_operator 0 "comparison_operator"
9589              [(match_operand:GPR 1 "register_operand" "")
9590               (match_operand:GPR 2 "general_operand" "")])
9591              (match_operand 3 "const0_operand" ""))]
9592   ""
9593   {
9594     rtx cond = s390_emit_compare (GET_CODE (operands[0]),
9595                                   operands[1], operands[2]);
9596     emit_insn (gen_condtrap (cond, XEXP (cond, 0)));
9597     DONE;
9598   })
9600 (define_expand "ctrap<mode>4"
9601   [(trap_if (match_operator 0 "comparison_operator"
9602              [(match_operand:FP 1 "register_operand" "")
9603               (match_operand:FP 2 "general_operand" "")])
9604              (match_operand 3 "const0_operand" ""))]
9605   ""
9606   {
9607     rtx cond = s390_emit_compare (GET_CODE (operands[0]),
9608                                   operands[1], operands[2]);
9609     emit_insn (gen_condtrap (cond, XEXP (cond, 0)));
9610     DONE;
9611   })
9613 (define_insn "condtrap"
9614   [(trap_if (match_operator 0 "s390_comparison"
9615              [(match_operand 1 "cc_reg_operand" "c")
9616               (const_int 0)])
9617             (const_int 0))]
9618   ""
9619   "j%C0\t.+2";
9620   [(set_attr "op_type" "RI")
9621    (set_attr "type"  "branch")])
9623 ; crt, cgrt, cit, cgit
9624 (define_insn "*cmp_and_trap_signed_int<mode>"
9625   [(trap_if (match_operator 0 "s390_signed_integer_comparison"
9626                [(match_operand:GPR 1 "register_operand"  "d,d")
9627                 (match_operand:GPR 2 "nonmemory_operand" "d,K")])
9628             (const_int 0))]
9629   "TARGET_Z10"
9630   "@
9631    c<g>rt%C0\t%1,%2
9632    c<g>it%C0\t%1,%h2"
9633   [(set_attr "op_type" "RRF,RIE")
9634    (set_attr "type"    "branch")
9635    (set_attr "z10prop" "z10_super_c,z10_super")])
9637 ; clrt, clgrt, clfit, clgit, clt, clgt
9638 (define_insn "*cmp_and_trap_unsigned_int<mode>"
9639   [(trap_if (match_operator 0 "s390_unsigned_integer_comparison"
9640                [(match_operand:GPR 1 "register_operand" "d,d,d")
9641                 (match_operand:GPR 2 "general_operand"  "d,D,S")])
9642             (const_int 0))]
9643   "TARGET_Z10"
9644   "@
9645    cl<g>rt%C0\t%1,%2
9646    cl<gf>it%C0\t%1,%x2
9647    cl<g>t%C0\t%1,%2"
9648   [(set_attr "op_type"      "RRF,RIE,RSY")
9649    (set_attr "type"         "branch")
9650    (set_attr "z10prop"      "z10_super_c,z10_super,*")
9651    (set_attr "cpu_facility" "z10,z10,zEC12")])
9653 ; lat, lgat
9654 (define_insn "*load_and_trap<mode>"
9655   [(trap_if (eq (match_operand:GPR 0 "memory_operand"  "T")
9656                 (const_int 0))
9657             (const_int 0))
9658    (set (match_operand:GPR 1 "register_operand" "=d")
9659         (match_dup 0))]
9660   "TARGET_ZEC12"
9661   "l<g>at\t%1,%0"
9662   [(set_attr "op_type" "RXY")])
9666 ;;- Loop instructions.
9668 ;;  This is all complicated by the fact that since this is a jump insn
9669 ;;  we must handle our own output reloads.
9671 ;; branch on index
9673 ; This splitter will be matched by combine and has to add the 2 moves
9674 ; necessary to load the compare and the increment values into a
9675 ; register pair as needed by brxle.
9677 (define_insn_and_split "*brx_stage1_<GPR:mode>"
9678   [(set (pc)
9679         (if_then_else
9680          (match_operator 6 "s390_brx_operator"
9681             [(plus:GPR (match_operand:GPR 1 "register_operand" "")
9682                        (match_operand:GPR 2 "general_operand"  ""))
9683              (match_operand:GPR 3 "register_operand" "")])
9684          (label_ref (match_operand 0 "" ""))
9685          (pc)))
9686    (set (match_operand:GPR 4 "nonimmediate_operand" "")
9687         (plus:GPR (match_dup 1) (match_dup 2)))
9688    (clobber (match_scratch:GPR 5 ""))]
9689   ""
9690   "#"
9691   "!reload_completed && !reload_in_progress"
9692   [(set (match_dup 7) (match_dup 2)) ; the increment
9693    (set (match_dup 8) (match_dup 3)) ; the comparison value
9694    (parallel [(set (pc)
9695                    (if_then_else
9696                     (match_op_dup 6
9697                        [(plus:GPR (match_dup 1) (match_dup 7))
9698                         (match_dup 8)])
9699                     (label_ref (match_dup 0))
9700                     (pc)))
9701               (set (match_dup 4)
9702                    (plus:GPR (match_dup 1) (match_dup 7)))
9703               (clobber (match_dup 5))
9704               (clobber (reg:CC CC_REGNUM))])]
9705   {
9706     rtx dreg = gen_reg_rtx (word_mode == DImode ? TImode : DImode);
9707     operands[7] = gen_lowpart (<GPR:MODE>mode,
9708                                gen_highpart (word_mode, dreg));
9709     operands[8] = gen_lowpart (<GPR:MODE>mode,
9710                                gen_lowpart (word_mode, dreg));
9711   })
9713 ; brxlg, brxhg
9715 (define_insn_and_split "*brxg_64bit"
9716   [(set (pc)
9717         (if_then_else
9718           (match_operator 5 "s390_brx_operator"
9719              [(plus:DI (match_operand:DI 1 "register_operand" "d,d,d")
9720                        (subreg:DI (match_operand:TI 2 "register_operand" "d,d,d") 0))
9721               (subreg:DI (match_dup 2) 8)])
9722           (label_ref (match_operand 0 "" ""))
9723           (pc)))
9724    (set (match_operand:DI 3 "nonimmediate_operand" "=1,?X,?X")
9725         (plus:DI (match_dup 1)
9726                  (subreg:DI (match_dup 2) 0)))
9727    (clobber (match_scratch:DI 4 "=X,&1,&?d"))
9728    (clobber (reg:CC CC_REGNUM))]
9729   "TARGET_ZARCH"
9731   if (which_alternative != 0)
9732     return "#";
9733   else if (get_attr_length (insn) == 6)
9734     return "brx%E5g\t%1,%2,%l0";
9735   else
9736     return "agr\t%1,%2\;cgr\t%1,%M2\;jg%C5\t%l0";
9738   "&& reload_completed
9739    && (!REG_P (operands[3])
9740        || !rtx_equal_p (operands[1], operands[3]))"
9741   [(set (match_dup 4) (match_dup 1))
9742    (parallel [(set (match_dup 4) (plus:DI (match_dup 4) (subreg:DI (match_dup 2) 0)))
9743               (clobber (reg:CC CC_REGNUM))])
9744    (set (reg:CCS CC_REGNUM) (compare:CCS (match_dup 4) (subreg:DI (match_dup 2) 8)))
9745    (set (match_dup 3) (match_dup 4))
9746    (set (pc) (if_then_else (match_op_dup 5 [(reg:CCS CC_REGNUM) (const_int 0)])
9747                            (label_ref (match_dup 0))
9748                            (pc)))]
9749   ""
9750   [(set_attr "op_type"  "RIE")
9751    (set_attr "type"  "branch")
9752    (set (attr "length")
9753         (if_then_else (lt (abs (minus (pc) (match_dup 0))) (const_int 60000))
9754                       (const_int 6) (const_int 16)))])
9756 ; brxle, brxh
9758 (define_insn_and_split "*brx_64bit"
9759   [(set (pc)
9760         (if_then_else
9761           (match_operator 5 "s390_brx_operator"
9762              [(plus:SI (match_operand:SI 1 "register_operand" "d,d,d")
9763                        (subreg:SI (match_operand:TI 2 "register_operand" "d,d,d") 4))
9764               (subreg:SI (match_dup 2) 12)])
9765           (label_ref (match_operand 0 "" ""))
9766           (pc)))
9767    (set (match_operand:SI 3 "nonimmediate_operand" "=1,?X,?X")
9768         (plus:SI (match_dup 1)
9769                  (subreg:SI (match_dup 2) 4)))
9770    (clobber (match_scratch:SI 4 "=X,&1,&?d"))
9771    (clobber (reg:CC CC_REGNUM))]
9772   "TARGET_ZARCH"
9774   if (which_alternative != 0)
9775     return "#";
9776   else if (get_attr_length (insn) == 6)
9777     return "brx%C5\t%1,%2,%l0";
9778   else
9779     return "ar\t%1,%2\;cr\t%1,%M2\;jg%C5\t%l0";
9781   "&& reload_completed
9782    && (!REG_P (operands[3])
9783        || !rtx_equal_p (operands[1], operands[3]))"
9784   [(set (match_dup 4) (match_dup 1))
9785    (parallel [(set (match_dup 4) (plus:SI (match_dup 4) (subreg:SI (match_dup 2) 4)))
9786               (clobber (reg:CC CC_REGNUM))])
9787    (set (reg:CCS CC_REGNUM) (compare:CCS (match_dup 4) (subreg:SI (match_dup 2) 12)))
9788    (set (match_dup 3) (match_dup 4))
9789    (set (pc) (if_then_else (match_op_dup 5 [(reg:CCS CC_REGNUM) (const_int 0)])
9790                            (label_ref (match_dup 0))
9791                            (pc)))]
9792   ""
9793   [(set_attr "op_type"  "RSI")
9794    (set_attr "type"  "branch")
9795    (set (attr "length")
9796         (if_then_else (lt (abs (minus (pc) (match_dup 0))) (const_int 60000))
9797                       (const_int 6) (const_int 14)))])
9799 ; brxle, brxh
9801 (define_insn_and_split "*brx_31bit"
9802   [(set (pc)
9803         (if_then_else
9804           (match_operator 5 "s390_brx_operator"
9805             [(plus:SI (match_operand:SI 1 "register_operand" "d,d,d")
9806                       (subreg:SI (match_operand:DI 2 "register_operand" "d,d,d") 0))
9807              (subreg:SI (match_dup 2) 4)])
9808           (label_ref (match_operand 0 "" ""))
9809           (pc)))
9810    (set (match_operand:SI 3 "nonimmediate_operand" "=1,?X,?X")
9811         (plus:SI (match_dup 1)
9812                  (subreg:SI (match_dup 2) 0)))
9813    (clobber (match_scratch:SI 4 "=X,&1,&?d"))
9814    (clobber (reg:CC CC_REGNUM))]
9815   "!TARGET_ZARCH"
9817   if (which_alternative != 0)
9818     return "#";
9819   else if (get_attr_length (insn) == 6)
9820     return "brx%C5\t%1,%2,%l0";
9821   else
9822     return "ar\t%1,%2\;cr\t%1,%M2\;jg%C5\t%l0";
9824   "&& reload_completed
9825    && (!REG_P (operands[3])
9826        || !rtx_equal_p (operands[1], operands[3]))"
9827   [(set (match_dup 4) (match_dup 1))
9828    (parallel [(set (match_dup 4) (plus:SI (match_dup 4) (subreg:SI (match_dup 2) 0)))
9829               (clobber (reg:CC CC_REGNUM))])
9830    (set (reg:CCS CC_REGNUM) (compare:CCS (match_dup 4) (subreg:SI (match_dup 2) 4)))
9831    (set (match_dup 3) (match_dup 4))
9832    (set (pc) (if_then_else (match_op_dup 5 [(reg:CCS CC_REGNUM) (const_int 0)])
9833                            (label_ref (match_dup 0))
9834                            (pc)))]
9835   ""
9836   [(set_attr "op_type"  "RSI")
9837    (set_attr "type"  "branch")
9838    (set (attr "length")
9839         (if_then_else (lt (abs (minus (pc) (match_dup 0))) (const_int 60000))
9840                       (const_int 6) (const_int 14)))])
9843 ;; branch on count
9845 (define_expand "doloop_end"
9846   [(use (match_operand 0 "" ""))        ; loop pseudo
9847    (use (match_operand 1 "" ""))]       ; label
9848   ""
9850   if (GET_MODE (operands[0]) == SImode)
9851     emit_jump_insn (gen_doloop_si64 (operands[1], operands[0], operands[0]));
9852   else if (GET_MODE (operands[0]) == DImode && TARGET_ZARCH)
9853     emit_jump_insn (gen_doloop_di (operands[1], operands[0], operands[0]));
9854   else
9855     FAIL;
9857   DONE;
9860 (define_insn_and_split "doloop_si64"
9861   [(set (pc)
9862         (if_then_else
9863           (ne (match_operand:SI 1 "register_operand" "d,d,d")
9864               (const_int 1))
9865           (label_ref (match_operand 0 "" ""))
9866           (pc)))
9867    (set (match_operand:SI 2 "nonimmediate_operand" "=1,?X,?X")
9868         (plus:SI (match_dup 1) (const_int -1)))
9869    (clobber (match_scratch:SI 3 "=X,&1,&?d"))
9870    (clobber (reg:CC CC_REGNUM))]
9871   ""
9873   if (which_alternative != 0)
9874     return "#";
9875   else if (get_attr_length (insn) == 4)
9876     return "brct\t%1,%l0";
9877   else
9878     return "ahi\t%1,-1\;jgne\t%l0";
9880   "&& reload_completed
9881    && (! REG_P (operands[2])
9882        || ! rtx_equal_p (operands[1], operands[2]))"
9883   [(set (match_dup 3) (match_dup 1))
9884    (parallel [(set (reg:CCAN CC_REGNUM)
9885                    (compare:CCAN (plus:SI (match_dup 3) (const_int -1))
9886                                  (const_int 0)))
9887               (set (match_dup 3) (plus:SI (match_dup 3) (const_int -1)))])
9888    (set (match_dup 2) (match_dup 3))
9889    (set (pc) (if_then_else (ne (reg:CCAN CC_REGNUM) (const_int 0))
9890                            (label_ref (match_dup 0))
9891                            (pc)))]
9892   ""
9893   [(set_attr "op_type"  "RI")
9894    ; Strictly speaking, the z10 properties are valid for brct only, however, it does not
9895    ; hurt us in the (rare) case of ahi.
9896    (set_attr "z10prop"  "z10_super_E1")
9897    (set_attr "type"  "branch")
9898    (set (attr "length")
9899         (if_then_else (lt (abs (minus (pc) (match_dup 0))) (const_int 60000))
9900                       (const_int 4) (const_int 10)))])
9902 (define_insn_and_split "doloop_di"
9903   [(set (pc)
9904         (if_then_else
9905           (ne (match_operand:DI 1 "register_operand" "d,d,d")
9906               (const_int 1))
9907           (label_ref (match_operand 0 "" ""))
9908           (pc)))
9909    (set (match_operand:DI 2 "nonimmediate_operand" "=1,?X,?X")
9910         (plus:DI (match_dup 1) (const_int -1)))
9911    (clobber (match_scratch:DI 3 "=X,&1,&?d"))
9912    (clobber (reg:CC CC_REGNUM))]
9913   "TARGET_ZARCH"
9915   if (which_alternative != 0)
9916     return "#";
9917   else if (get_attr_length (insn) == 4)
9918     return "brctg\t%1,%l0";
9919   else
9920     return "aghi\t%1,-1\;jgne\t%l0";
9922   "&& reload_completed
9923    && (! REG_P (operands[2])
9924        || ! rtx_equal_p (operands[1], operands[2]))"
9925   [(set (match_dup 3) (match_dup 1))
9926    (parallel [(set (reg:CCAN CC_REGNUM)
9927                    (compare:CCAN (plus:DI (match_dup 3) (const_int -1))
9928                                  (const_int 0)))
9929               (set (match_dup 3) (plus:DI (match_dup 3) (const_int -1)))])
9930    (set (match_dup 2) (match_dup 3))
9931    (set (pc) (if_then_else (ne (reg:CCAN CC_REGNUM) (const_int 0))
9932                            (label_ref (match_dup 0))
9933                            (pc)))]
9934   ""
9935   [(set_attr "op_type"  "RI")
9936    ; Strictly speaking, the z10 properties are valid for brct only, however, it does not
9937    ; hurt us in the (rare) case of ahi.
9938    (set_attr "z10prop"  "z10_super_E1")
9939    (set_attr "type"  "branch")
9940    (set (attr "length")
9941         (if_then_else (lt (abs (minus (pc) (match_dup 0))) (const_int 60000))
9942                       (const_int 4) (const_int 10)))])
9945 ;;- Unconditional jump instructions.
9949 ; jump instruction pattern(s).
9952 (define_expand "jump"
9953   [(match_operand 0 "" "")]
9954   ""
9955   "s390_emit_jump (operands[0], NULL_RTX); DONE;")
9957 (define_insn "*jump64"
9958   [(set (pc) (label_ref (match_operand 0 "" "")))]
9959   ""
9961   if (get_attr_length (insn) == 4)
9962     return "j\t%l0";
9963   else
9964     return "jg\t%l0";
9966   [(set_attr "op_type" "RI")
9967    (set_attr "type"  "branch")
9968    (set (attr "length")
9969         (if_then_else (lt (abs (minus (pc) (match_dup 0))) (const_int 60000))
9970                       (const_int 4) (const_int 6)))])
9973 ; indirect-jump instruction pattern(s).
9976 (define_expand "indirect_jump"
9977   [(set (pc) (match_operand 0 "nonimmediate_operand" ""))]
9978   ""
9980   if (address_operand (operands[0], GET_MODE (operands[0])))
9981     ;
9982   else if (TARGET_Z14
9983            && GET_MODE (operands[0]) == Pmode
9984            && memory_operand (operands[0], Pmode))
9985     ;
9986   else
9987     operands[0] = force_reg (Pmode, operands[0]);
9989   if (TARGET_INDIRECT_BRANCH_NOBP_JUMP_THUNK)
9990     {
9991       operands[0] = force_reg (Pmode, operands[0]);
9992       if (TARGET_CPU_Z10)
9993         {
9994           if (TARGET_64BIT)
9995             emit_jump_insn (gen_indirect_jump_via_thunkdi_z10 (operands[0]));
9996           else
9997             emit_jump_insn (gen_indirect_jump_via_thunksi_z10 (operands[0]));
9998         }
9999       else
10000         {
10001           if (TARGET_64BIT)
10002             emit_jump_insn (gen_indirect_jump_via_thunkdi (operands[0]));
10003           else
10004             emit_jump_insn (gen_indirect_jump_via_thunksi (operands[0]));
10005         }
10006       DONE;
10007     }
10009   if (TARGET_INDIRECT_BRANCH_NOBP_JUMP_INLINE_THUNK)
10010     {
10011       operands[0] = force_reg (Pmode, operands[0]);
10012       rtx label_ref = gen_rtx_LABEL_REF (VOIDmode, gen_label_rtx ());
10013       if (TARGET_CPU_Z10)
10014         {
10015           if (TARGET_64BIT)
10016             emit_jump_insn (gen_indirect_jump_via_inlinethunkdi_z10 (operands[0],
10017                                                                      label_ref));
10018           else
10019             emit_jump_insn (gen_indirect_jump_via_inlinethunksi_z10 (operands[0],
10020                                                                      label_ref));
10021         }
10022       else
10023         {
10024           if (TARGET_64BIT)
10025             emit_jump_insn (gen_indirect_jump_via_inlinethunkdi (operands[0],
10026                                                                  label_ref,
10027                                                                  force_reg (Pmode, label_ref)));
10028           else
10029             emit_jump_insn (gen_indirect_jump_via_inlinethunksi (operands[0],
10030                                                                  label_ref,
10031                                                                  force_reg (Pmode, label_ref)));
10032         }
10033       DONE;
10034     }
10037 (define_insn "*indirect_jump"
10038   [(set (pc)
10039         (match_operand 0 "address_operand" "ZR"))]
10040  "!TARGET_INDIRECT_BRANCH_NOBP_JUMP_THUNK"
10042   if (get_attr_op_type (insn) == OP_TYPE_RR)
10043     return "br\t%0";
10044   else
10045     return "b\t%a0";
10047  [(set (attr "op_type")
10048        (if_then_else (match_operand 0 "register_operand" "")
10049                      (const_string "RR") (const_string "RX")))
10050   (set (attr "mnemonic")
10051        (if_then_else (match_operand 0 "register_operand" "")
10052                      (const_string "br") (const_string "b")))
10053   (set_attr "type"  "branch")
10054   (set_attr "atype" "agen")])
10056 (define_insn "indirect_jump_via_thunk<mode>_z10"
10057   [(set (pc)
10058         (match_operand:P 0 "register_operand" "a"))]
10059  "TARGET_INDIRECT_BRANCH_NOBP_JUMP_THUNK
10060   && TARGET_CPU_Z10"
10062   s390_indirect_branch_via_thunk (REGNO (operands[0]),
10063                                   INVALID_REGNUM,
10064                                   NULL_RTX,
10065                                   s390_indirect_branch_type_jump);
10066   return "";
10068  [(set_attr "op_type"  "RIL")
10069   (set_attr "mnemonic" "jg")
10070   (set_attr "type"  "branch")
10071   (set_attr "atype" "agen")])
10073 (define_insn "indirect_jump_via_thunk<mode>"
10074   [(set (pc)
10075         (match_operand:P 0 "register_operand" " a"))
10076    (clobber (reg:P INDIRECT_BRANCH_THUNK_REGNUM))]
10077  "TARGET_INDIRECT_BRANCH_NOBP_JUMP_THUNK
10078   && !TARGET_CPU_Z10"
10080   s390_indirect_branch_via_thunk (REGNO (operands[0]),
10081                                   INVALID_REGNUM,
10082                                   NULL_RTX,
10083                                   s390_indirect_branch_type_jump);
10084   return "";
10086  [(set_attr "op_type"  "RIL")
10087   (set_attr "mnemonic" "jg")
10088   (set_attr "type"  "branch")
10089   (set_attr "atype" "agen")])
10092 ; The label_ref is wrapped into an if_then_else in order to hide it
10093 ; from mark_jump_label.  Without this the label_ref would become the
10094 ; ONLY jump target of that jump breaking the control flow graph.
10095 (define_insn "indirect_jump_via_inlinethunk<mode>_z10"
10096   [(unspec [(if_then_else (match_operand:P 1 "larl_operand" "X")
10097                           (const_int 0)
10098                           (const_int 0))
10099             (const_int 0)] UNSPEC_EXECUTE_JUMP)
10100    (set (pc) (match_operand:P 0 "register_operand" "a"))]
10101   "TARGET_INDIRECT_BRANCH_NOBP_JUMP_INLINE_THUNK
10102    && TARGET_CPU_Z10"
10104   s390_indirect_branch_via_inline_thunk (operands[1]);
10105   return "";
10107   [(set_attr "op_type" "RIL")
10108    (set_attr "type"    "branch")
10109    (set_attr "length"  "10")])
10111 (define_insn "indirect_jump_via_inlinethunk<mode>"
10112   [(unspec [(if_then_else (match_operand:P 1 "larl_operand" "X")
10113                           (const_int 0)
10114                           (const_int 0))
10115             (match_operand:P 2 "register_operand" "a")] UNSPEC_EXECUTE_JUMP)
10116    (set (pc) (match_operand:P 0 "register_operand" "a"))]
10117   "TARGET_INDIRECT_BRANCH_NOBP_JUMP_INLINE_THUNK
10118    && !TARGET_CPU_Z10"
10120   s390_indirect_branch_via_inline_thunk (operands[2]);
10121   return "";
10123   [(set_attr "op_type" "RX")
10124    (set_attr "type"    "branch")
10125    (set_attr "length"  "8")])
10127 ; FIXME: LRA does not appear to be able to deal with MEMs being
10128 ; checked against address constraints like ZR above.  So make this a
10129 ; separate pattern for now.
10130 (define_insn "*indirect2_jump"
10131   [(set (pc)
10132         (match_operand 0 "nonimmediate_operand" "a,T"))]
10133  "!TARGET_INDIRECT_BRANCH_NOBP_JUMP"
10134  "@
10135   br\t%0
10136   bi\t%0"
10137  [(set_attr "op_type" "RR,RXY")
10138   (set_attr "type"  "branch")
10139   (set_attr "atype" "agen")
10140   (set_attr "cpu_facility" "*,z14")])
10143 ; casesi instruction pattern(s).
10146 (define_expand "casesi_jump"
10147   [(parallel
10148     [(set (pc) (match_operand 0 "address_operand"))
10149      (use (label_ref (match_operand 1 "")))])]
10150   ""
10152   if (TARGET_INDIRECT_BRANCH_NOBP_JUMP_THUNK)
10153     {
10154       operands[0] = force_reg (GET_MODE (operands[0]), operands[0]);
10156       if (TARGET_CPU_Z10)
10157         {
10158           if (TARGET_64BIT)
10159             emit_jump_insn (gen_casesi_jump_via_thunkdi_z10 (operands[0],
10160                                                              operands[1]));
10161           else
10162             emit_jump_insn (gen_casesi_jump_via_thunksi_z10 (operands[0],
10163                                                              operands[1]));
10164         }
10165       else
10166         {
10167           if (TARGET_64BIT)
10168             emit_jump_insn (gen_casesi_jump_via_thunkdi (operands[0],
10169                                                          operands[1]));
10170           else
10171             emit_jump_insn (gen_casesi_jump_via_thunksi (operands[0],
10172                                                          operands[1]));
10173         }
10174       DONE;
10175     }
10177     if (TARGET_INDIRECT_BRANCH_NOBP_JUMP_INLINE_THUNK)
10178     {
10179       operands[0] = force_reg (Pmode, operands[0]);
10180       rtx label_ref = gen_rtx_LABEL_REF (VOIDmode, gen_label_rtx ());
10181       if (TARGET_CPU_Z10)
10182         {
10183           if (TARGET_64BIT)
10184             emit_jump_insn (gen_casesi_jump_via_inlinethunkdi_z10 (operands[0],
10185                                                                    operands[1],
10186                                                                    label_ref));
10187           else
10188             emit_jump_insn (gen_casesi_jump_via_inlinethunksi_z10 (operands[0],
10189                                                                    operands[1],
10190                                                                    label_ref));
10191         }
10192       else
10193         {
10194           if (TARGET_64BIT)
10195             emit_jump_insn (gen_casesi_jump_via_inlinethunkdi (operands[0],
10196                                                                operands[1],
10197                                                                label_ref,
10198                                                                force_reg (Pmode, label_ref)));
10199           else
10200             emit_jump_insn (gen_casesi_jump_via_inlinethunksi (operands[0],
10201                                                                operands[1],
10202                                                                label_ref,
10203                                                                force_reg (Pmode, label_ref)));
10204         }
10205       DONE;
10206     }
10209 (define_insn "*casesi_jump"
10210  [(set (pc) (match_operand 0 "address_operand" "ZR"))
10211   (use (label_ref (match_operand 1 "" "")))]
10212  "!TARGET_INDIRECT_BRANCH_NOBP_JUMP_THUNK"
10214   if (get_attr_op_type (insn) == OP_TYPE_RR)
10215     return "br\t%0";
10216   else
10217     return "b\t%a0";
10219   [(set (attr "op_type")
10220         (if_then_else (match_operand 0 "register_operand" "")
10221                       (const_string "RR") (const_string "RX")))
10222    (set (attr "mnemonic")
10223         (if_then_else (match_operand 0 "register_operand" "")
10224                       (const_string "br") (const_string "b")))
10225    (set_attr "type"  "branch")
10226    (set_attr "atype" "agen")])
10228 (define_insn "casesi_jump_via_thunk<mode>_z10"
10229  [(set (pc) (match_operand:P 0 "register_operand" "a"))
10230   (use (label_ref (match_operand 1 "" "")))]
10231  "TARGET_INDIRECT_BRANCH_NOBP_JUMP_THUNK
10232   && TARGET_CPU_Z10"
10234   s390_indirect_branch_via_thunk (REGNO (operands[0]),
10235                                   INVALID_REGNUM,
10236                                   NULL_RTX,
10237                                   s390_indirect_branch_type_jump);
10238   return "";
10240   [(set_attr "op_type" "RIL")
10241    (set_attr "mnemonic" "jg")
10242    (set_attr "type"  "branch")
10243    (set_attr "atype" "agen")])
10245 (define_insn "casesi_jump_via_thunk<mode>"
10246  [(set (pc) (match_operand:P 0 "register_operand" "a"))
10247   (use (label_ref (match_operand 1 "" "")))
10248   (clobber (reg:P INDIRECT_BRANCH_THUNK_REGNUM))]
10249  "TARGET_INDIRECT_BRANCH_NOBP_JUMP_THUNK
10250   && !TARGET_CPU_Z10"
10252   s390_indirect_branch_via_thunk (REGNO (operands[0]),
10253                                   INVALID_REGNUM,
10254                                   NULL_RTX,
10255                                   s390_indirect_branch_type_jump);
10256   return "";
10258   [(set_attr "op_type" "RIL")
10259    (set_attr "mnemonic" "jg")
10260    (set_attr "type"  "branch")
10261    (set_attr "atype" "agen")])
10264 ; The label_ref is wrapped into an if_then_else in order to hide it
10265 ; from mark_jump_label.  Without this the label_ref would become the
10266 ; ONLY jump target of that jump breaking the control flow graph.
10267 (define_insn "casesi_jump_via_inlinethunk<mode>_z10"
10268   [(unspec [(if_then_else (match_operand:P 2 "larl_operand" "X")
10269                           (const_int 0)
10270                           (const_int 0))
10271             (const_int 0)] UNSPEC_EXECUTE_JUMP)
10272    (set (pc) (match_operand:P 0 "register_operand" "a"))
10273    (use (label_ref (match_operand 1 "" "")))]
10274   "TARGET_INDIRECT_BRANCH_NOBP_JUMP_INLINE_THUNK
10275    && TARGET_CPU_Z10"
10277   s390_indirect_branch_via_inline_thunk (operands[2]);
10278   return "";
10280   [(set_attr "op_type" "RIL")
10281    (set_attr "type"    "cs")
10282    (set_attr "length"  "10")])
10284 (define_insn "casesi_jump_via_inlinethunk<mode>"
10285   [(unspec [(if_then_else (match_operand:P 2 "larl_operand" "X")
10286                           (const_int 0)
10287                           (const_int 0))
10288             (match_operand:P 3 "register_operand" "a")] UNSPEC_EXECUTE_JUMP)
10289    (set (pc) (match_operand:P 0 "register_operand" "a"))
10290    (use (label_ref (match_operand 1 "" "")))]
10291   "TARGET_INDIRECT_BRANCH_NOBP_JUMP_INLINE_THUNK
10292    && !TARGET_CPU_Z10"
10294   s390_indirect_branch_via_inline_thunk (operands[3]);
10295   return "";
10297   [(set_attr "op_type" "RX")
10298    (set_attr "type"    "cs")
10299    (set_attr "length"  "8")])
10301 (define_expand "casesi"
10302   [(match_operand:SI 0 "general_operand" "")
10303    (match_operand:SI 1 "general_operand" "")
10304    (match_operand:SI 2 "general_operand" "")
10305    (label_ref (match_operand 3 "" ""))
10306    (label_ref (match_operand 4 "" ""))]
10307   ""
10309    rtx index  = gen_reg_rtx (SImode);
10310    rtx base   = gen_reg_rtx (Pmode);
10311    rtx target = gen_reg_rtx (Pmode);
10313    emit_move_insn (index, operands[0]);
10314    emit_insn (gen_subsi3 (index, index, operands[1]));
10315    emit_cmp_and_jump_insns (index, operands[2], GTU, NULL_RTX, SImode, 1,
10316                             operands[4]);
10318    if (Pmode != SImode)
10319      index = convert_to_mode (Pmode, index, 1);
10320    if (GET_CODE (index) != REG)
10321      index = copy_to_mode_reg (Pmode, index);
10323    if (TARGET_64BIT)
10324        emit_insn (gen_ashldi3 (index, index, GEN_INT (3)));
10325    else
10326        emit_insn (gen_ashlsi3 (index, index, const2_rtx));
10328    emit_move_insn (base, gen_rtx_LABEL_REF (Pmode, operands[3]));
10330    index = gen_const_mem (Pmode, gen_rtx_PLUS (Pmode, base, index));
10331    emit_move_insn (target, index);
10333    if (flag_pic)
10334      target = gen_rtx_PLUS (Pmode, base, target);
10335    emit_jump_insn (gen_casesi_jump (target, operands[3]));
10337    DONE;
10342 ;;- Jump to subroutine.
10347 ; untyped call instruction pattern(s).
10350 ;; Call subroutine returning any type.
10351 (define_expand "untyped_call"
10352   [(parallel [(call (match_operand 0 "" "")
10353                     (const_int 0))
10354               (match_operand 1 "" "")
10355               (match_operand 2 "" "")])]
10356   ""
10358   int i;
10360   emit_call_insn (gen_call (operands[0], const0_rtx, const0_rtx));
10362   for (i = 0; i < XVECLEN (operands[2], 0); i++)
10363     {
10364       rtx set = XVECEXP (operands[2], 0, i);
10365       emit_move_insn (SET_DEST (set), SET_SRC (set));
10366     }
10368   /* The optimizer does not know that the call sets the function value
10369      registers we stored in the result block.  We avoid problems by
10370      claiming that all hard registers are used and clobbered at this
10371      point.  */
10372   emit_insn (gen_blockage ());
10374   DONE;
10377 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
10378 ;; all of memory.  This blocks insns from being moved across this point.
10380 (define_insn "blockage"
10381   [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
10382   ""
10383   ""
10384   [(set_attr "type"    "none")
10385    (set_attr "length"  "0")])
10388 ; sibcall patterns
10391 (define_expand "sibcall"
10392   [(call (match_operand 0 "" "")
10393          (match_operand 1 "" ""))]
10394   ""
10396   s390_emit_call (XEXP (operands[0], 0), NULL_RTX, NULL_RTX, NULL_RTX);
10397   DONE;
10400 (define_insn "*sibcall_br"
10401   [(call (mem:QI (reg SIBCALL_REGNUM))
10402          (match_operand 0 "const_int_operand" "n"))]
10403   "SIBLING_CALL_P (insn)
10404    && GET_MODE (XEXP (XEXP (PATTERN (insn), 0), 0)) == Pmode"
10406   if (TARGET_INDIRECT_BRANCH_NOBP_CALL)
10407     {
10408       gcc_assert (TARGET_CPU_Z10);
10409       s390_indirect_branch_via_thunk (SIBCALL_REGNUM,
10410                                       INVALID_REGNUM,
10411                                       NULL_RTX,
10412                                       s390_indirect_branch_type_call);
10413       return "";
10414     }
10415   else
10416     return "br\t%%r1";
10418  [(set (attr "op_type")
10419        (if_then_else (match_test "TARGET_INDIRECT_BRANCH_NOBP_CALL")
10420                      (const_string "RIL")
10421                      (const_string "RR")))
10422   (set (attr "mnemonic")
10423        (if_then_else (match_test "TARGET_INDIRECT_BRANCH_NOBP_CALL")
10424                      (const_string "jg")
10425                      (const_string "br")))
10426    (set_attr "type"  "branch")
10427    (set_attr "atype" "agen")])
10429 (define_insn "*sibcall_brc"
10430   [(call (mem:QI (match_operand 0 "bras_sym_operand" "X"))
10431          (match_operand 1 "const_int_operand" "n"))]
10432   "SIBLING_CALL_P (insn) && TARGET_SMALL_EXEC"
10433   "j\t%0%K0"
10434   [(set_attr "op_type" "RI")
10435    (set_attr "type"    "branch")])
10437 (define_insn "*sibcall_brcl"
10438   [(call (mem:QI (match_operand 0 "bras_sym_operand" "X"))
10439          (match_operand 1 "const_int_operand" "n"))]
10440   "SIBLING_CALL_P (insn)"
10441   "jg\t%0%K0"
10442   [(set_attr "op_type" "RIL")
10443    (set_attr "type"    "branch")])
10446 ; sibcall_value patterns
10449 (define_expand "sibcall_value"
10450   [(set (match_operand 0 "" "")
10451         (call (match_operand 1 "" "")
10452               (match_operand 2 "" "")))]
10453   ""
10455   s390_emit_call (XEXP (operands[1], 0), NULL_RTX, operands[0], NULL_RTX);
10456   DONE;
10459 (define_insn "*sibcall_value_br"
10460   [(set (match_operand 0 "" "")
10461         (call (mem:QI (reg SIBCALL_REGNUM))
10462               (match_operand 1 "const_int_operand" "n")))]
10463   "SIBLING_CALL_P (insn)
10464    && GET_MODE (XEXP (XEXP (XEXP (PATTERN (insn), 1), 0), 0)) == Pmode"
10466   if (TARGET_INDIRECT_BRANCH_NOBP_CALL)
10467     {
10468       gcc_assert (TARGET_CPU_Z10);
10469       s390_indirect_branch_via_thunk (SIBCALL_REGNUM,
10470                                       INVALID_REGNUM,
10471                                       NULL_RTX,
10472                                       s390_indirect_branch_type_call);
10473       return "";
10474     }
10475   else
10476     return "br\t%%r1";
10478   [(set (attr "op_type")
10479        (if_then_else (match_test "TARGET_INDIRECT_BRANCH_NOBP_CALL")
10480                      (const_string "RIL")
10481                      (const_string "RR")))
10482    (set (attr "mnemonic")
10483        (if_then_else (match_test "TARGET_INDIRECT_BRANCH_NOBP_CALL")
10484                      (const_string "jg")
10485                      (const_string "br")))
10486    (set_attr "type"  "branch")
10487    (set_attr "atype" "agen")])
10489 (define_insn "*sibcall_value_brc"
10490   [(set (match_operand 0 "" "")
10491         (call (mem:QI (match_operand 1 "bras_sym_operand" "X"))
10492               (match_operand 2 "const_int_operand" "n")))]
10493   "SIBLING_CALL_P (insn) && TARGET_SMALL_EXEC"
10494   "j\t%1%K1"
10495   [(set_attr "op_type" "RI")
10496    (set_attr "type"    "branch")])
10498 (define_insn "*sibcall_value_brcl"
10499   [(set (match_operand 0 "" "")
10500         (call (mem:QI (match_operand 1 "bras_sym_operand" "X"))
10501               (match_operand 2 "const_int_operand" "n")))]
10502   "SIBLING_CALL_P (insn)"
10503   "jg\t%1%K1"
10504   [(set_attr "op_type" "RIL")
10505    (set_attr "type"    "branch")])
10509 ; call instruction pattern(s).
10512 (define_expand "call"
10513   [(call (match_operand 0 "" "")
10514          (match_operand 1 "" ""))
10515    (use (match_operand 2 "" ""))]
10516   ""
10518   s390_emit_call (XEXP (operands[0], 0), NULL_RTX, NULL_RTX,
10519                   gen_rtx_REG (Pmode, RETURN_REGNUM));
10520   DONE;
10523 (define_insn "*bras"
10524   [(call (mem:QI (match_operand 0 "bras_sym_operand" "X"))
10525          (match_operand 1 "const_int_operand" "n"))
10526    (clobber (match_operand 2 "register_operand" "=r"))]
10527   "!SIBLING_CALL_P (insn)
10528    && TARGET_SMALL_EXEC
10529    && GET_MODE (operands[2]) == Pmode"
10530   "bras\t%2,%0%K0"
10531   [(set_attr "op_type" "RI")
10532    (set_attr "type"    "jsr")
10533    (set_attr "z196prop" "z196_cracked")])
10535 (define_insn "*brasl"
10536   [(call (mem:QI (match_operand 0 "bras_sym_operand" "X"))
10537          (match_operand 1 "const_int_operand" "n"))
10538    (clobber (match_operand 2 "register_operand" "=r"))]
10539   "!SIBLING_CALL_P (insn)
10541    && GET_MODE (operands[2]) == Pmode"
10542   "brasl\t%2,%0%K0"
10543   [(set_attr "op_type" "RIL")
10544    (set_attr "type"    "jsr")
10545    (set_attr "z196prop" "z196_cracked")
10546    (set_attr "relative_long" "yes")])
10548 (define_insn "*basr"
10549   [(call (mem:QI (match_operand 0 "address_operand" "ZR"))
10550          (match_operand 1 "const_int_operand" "n"))
10551    (clobber (match_operand 2 "register_operand" "=r"))]
10552   "!TARGET_INDIRECT_BRANCH_NOBP_CALL
10553    && !SIBLING_CALL_P (insn)
10554    && GET_MODE (operands[2]) == Pmode"
10556   if (get_attr_op_type (insn) == OP_TYPE_RR)
10557     return "basr\t%2,%0";
10558   else
10559     return "bas\t%2,%a0";
10561   [(set (attr "op_type")
10562         (if_then_else (match_operand 0 "register_operand" "")
10563                       (const_string "RR") (const_string "RX")))
10564    (set (attr "mnemonic")
10565         (if_then_else (match_operand 0 "register_operand" "")
10566                       (const_string "basr") (const_string "bas")))
10567    (set_attr "type"  "jsr")
10568    (set_attr "atype" "agen")
10569    (set_attr "z196prop" "z196_cracked")])
10571 (define_insn "*basr_via_thunk<mode>_z10"
10572   [(call (mem:QI (match_operand:P 0 "register_operand" "a"))
10573          (match_operand 1 "const_int_operand"          "n"))
10574    (clobber (match_operand:P 2 "register_operand"    "=&r"))]
10575   "TARGET_INDIRECT_BRANCH_NOBP_CALL
10576    && TARGET_CPU_Z10
10577    && !SIBLING_CALL_P (insn)"
10579   s390_indirect_branch_via_thunk (REGNO (operands[0]),
10580                                   REGNO (operands[2]),
10581                                   NULL_RTX,
10582                                   s390_indirect_branch_type_call);
10583   return "";
10585   [(set_attr "op_type" "RIL")
10586    (set_attr "mnemonic" "brasl")
10587    (set_attr "type"  "jsr")
10588    (set_attr "atype" "agen")
10589    (set_attr "z196prop" "z196_cracked")])
10591 (define_insn "*basr_via_thunk<mode>"
10592   [(call (mem:QI (match_operand:P 0 "register_operand" "a"))
10593          (match_operand 1 "const_int_operand"          "n"))
10594    (clobber (match_operand:P 2 "register_operand"    "=&r"))
10595    (clobber (reg:P INDIRECT_BRANCH_THUNK_REGNUM))]
10596   "TARGET_INDIRECT_BRANCH_NOBP_CALL
10597    && !TARGET_CPU_Z10
10598    && !SIBLING_CALL_P (insn)"
10600   s390_indirect_branch_via_thunk (REGNO (operands[0]),
10601                                   REGNO (operands[2]),
10602                                   NULL_RTX,
10603                                   s390_indirect_branch_type_call);
10604   return "";
10606   [(set_attr "op_type" "RIL")
10607    (set_attr "mnemonic" "brasl")
10608    (set_attr "type"  "jsr")
10609    (set_attr "atype" "agen")
10610    (set_attr "z196prop" "z196_cracked")])
10613 ; call_value instruction pattern(s).
10616 (define_expand "call_value"
10617   [(set (match_operand 0 "" "")
10618         (call (match_operand 1 "" "")
10619               (match_operand 2 "" "")))
10620    (use (match_operand 3 "" ""))]
10621   ""
10623   s390_emit_call (XEXP (operands[1], 0), NULL_RTX, operands[0],
10624                   gen_rtx_REG (Pmode, RETURN_REGNUM));
10625   DONE;
10628 (define_insn "*bras_r"
10629   [(set (match_operand 0 "" "")
10630         (call (mem:QI (match_operand 1 "bras_sym_operand" "X"))
10631               (match_operand:SI 2 "const_int_operand" "n")))
10632    (clobber (match_operand 3 "register_operand" "=r"))]
10633   "!SIBLING_CALL_P (insn)
10634    && TARGET_SMALL_EXEC
10635    && GET_MODE (operands[3]) == Pmode"
10636   "bras\t%3,%1%K1"
10637   [(set_attr "op_type" "RI")
10638    (set_attr "type"    "jsr")
10639    (set_attr "z196prop" "z196_cracked")])
10641 (define_insn "*brasl_r"
10642   [(set (match_operand 0 "" "")
10643         (call (mem:QI (match_operand 1 "bras_sym_operand" "X"))
10644               (match_operand 2 "const_int_operand" "n")))
10645    (clobber (match_operand 3 "register_operand" "=r"))]
10646   "!SIBLING_CALL_P (insn)
10648    && GET_MODE (operands[3]) == Pmode"
10649   "brasl\t%3,%1%K1"
10650   [(set_attr "op_type" "RIL")
10651    (set_attr "type"    "jsr")
10652    (set_attr "z196prop" "z196_cracked")
10653    (set_attr "relative_long" "yes")])
10655 (define_insn "*basr_r"
10656   [(set (match_operand 0 "" "")
10657         (call (mem:QI (match_operand 1 "address_operand" "ZR"))
10658               (match_operand 2 "const_int_operand" "n")))
10659    (clobber (match_operand 3 "register_operand" "=r"))]
10660   "!TARGET_INDIRECT_BRANCH_NOBP_CALL
10661    && !SIBLING_CALL_P (insn)
10662    && GET_MODE (operands[3]) == Pmode"
10664   if (get_attr_op_type (insn) == OP_TYPE_RR)
10665     return "basr\t%3,%1";
10666   else
10667     return "bas\t%3,%a1";
10669   [(set (attr "op_type")
10670         (if_then_else (match_operand 1 "register_operand" "")
10671                       (const_string "RR") (const_string "RX")))
10672    (set (attr "mnemonic")
10673         (if_then_else (match_operand 1 "register_operand" "")
10674                       (const_string "basr") (const_string "bas")))
10675    (set_attr "type"  "jsr")
10676    (set_attr "atype" "agen")
10677    (set_attr "z196prop" "z196_cracked")])
10679 (define_insn "*basr_r_via_thunk_z10"
10680   [(set (match_operand 0 "" "")
10681         (call (mem:QI (match_operand 1 "register_operand" "a"))
10682               (match_operand 2 "const_int_operand"        "n")))
10683    (clobber (match_operand 3 "register_operand"         "=&r"))]
10684   "TARGET_INDIRECT_BRANCH_NOBP_CALL
10685    && TARGET_CPU_Z10
10686    && !SIBLING_CALL_P (insn)
10687    && GET_MODE (operands[3]) == Pmode"
10689   s390_indirect_branch_via_thunk (REGNO (operands[1]),
10690                                   REGNO (operands[3]),
10691                                   NULL_RTX,
10692                                   s390_indirect_branch_type_call);
10693   return "";
10695   [(set_attr "op_type" "RIL")
10696    (set_attr "mnemonic" "brasl")
10697    (set_attr "type"  "jsr")
10698    (set_attr "atype" "agen")
10699    (set_attr "z196prop" "z196_cracked")])
10701 (define_insn "*basr_r_via_thunk"
10702   [(set (match_operand 0 "" "")
10703         (call (mem:QI (match_operand 1 "register_operand" "a"))
10704               (match_operand 2 "const_int_operand"        "n")))
10705    (clobber (match_operand 3 "register_operand"         "=&r"))
10706    (clobber (reg:P INDIRECT_BRANCH_THUNK_REGNUM))]
10707   "TARGET_INDIRECT_BRANCH_NOBP_CALL
10708    && !TARGET_CPU_Z10
10709    && !SIBLING_CALL_P (insn)
10710    && GET_MODE (operands[3]) == Pmode"
10712   s390_indirect_branch_via_thunk (REGNO (operands[1]),
10713                                   REGNO (operands[3]),
10714                                   NULL_RTX,
10715                                   s390_indirect_branch_type_call);
10716   return "";
10718   [(set_attr "op_type" "RIL")
10719    (set_attr "mnemonic"  "brasl")
10720    (set_attr "type"  "jsr")
10721    (set_attr "atype" "agen")
10722    (set_attr "z196prop" "z196_cracked")])
10725 ;;- Thread-local storage support.
10728 (define_expand "@get_thread_pointer<mode>"
10729   [(set (match_operand:P 0 "nonimmediate_operand" "")
10730         (unspec:P [(reg:P TP_REGNUM)] UNSPEC_GET_TP))]
10731   ""
10732   "")
10734 (define_expand "set_thread_pointer<mode>"
10735   [(set (reg:P TP_REGNUM) (match_operand:P 0 "nonimmediate_operand" ""))
10736    (set (reg:P TP_REGNUM) (unspec_volatile:P [(reg:P TP_REGNUM)] UNSPECV_SET_TP))]
10737   ""
10738   "")
10740 (define_insn "*set_tp"
10741   [(set (reg TP_REGNUM) (unspec_volatile [(reg TP_REGNUM)] UNSPECV_SET_TP))]
10742   ""
10743   ""
10744   [(set_attr "type" "none")
10745    (set_attr "length" "0")])
10747 (define_insn "*tls_load_64"
10748   [(set (match_operand:DI 0 "register_operand" "=d")
10749         (unspec:DI [(match_operand:DI 1 "memory_operand" "T")
10750                     (match_operand:DI 2 "" "")]
10751                    UNSPEC_TLS_LOAD))]
10752   "TARGET_64BIT"
10753   "lg\t%0,%1%J2"
10754   [(set_attr "op_type" "RXE")
10755    (set_attr "z10prop" "z10_fwd_A3")])
10757 (define_insn "*tls_load_31"
10758   [(set (match_operand:SI 0 "register_operand" "=d,d")
10759         (unspec:SI [(match_operand:SI 1 "memory_operand" "R,T")
10760                     (match_operand:SI 2 "" "")]
10761                    UNSPEC_TLS_LOAD))]
10762   "!TARGET_64BIT"
10763   "@
10764    l\t%0,%1%J2
10765    ly\t%0,%1%J2"
10766   [(set_attr "op_type" "RX,RXY")
10767    (set_attr "type" "load")
10768    (set_attr "cpu_facility" "*,longdisp")
10769    (set_attr "z10prop" "z10_fwd_A3,z10_fwd_A3")])
10771 (define_insn "*bras_tls"
10772   [(set (match_operand 0 "" "")
10773         (call (mem:QI (match_operand 1 "bras_sym_operand" "X"))
10774               (match_operand 2 "const_int_operand" "n")))
10775    (clobber (match_operand 3 "register_operand" "=r"))
10776    (use (match_operand 4 "" ""))]
10777   "!SIBLING_CALL_P (insn)
10778    && TARGET_SMALL_EXEC
10779    && GET_MODE (operands[3]) == Pmode"
10780   "bras\t%3,%1%K1%J4"
10781   [(set_attr "op_type" "RI")
10782    (set_attr "type"    "jsr")
10783    (set_attr "z196prop" "z196_cracked")])
10785 (define_insn "*brasl_tls"
10786   [(set (match_operand 0 "" "")
10787         (call (mem:QI (match_operand 1 "bras_sym_operand" "X"))
10788               (match_operand 2 "const_int_operand" "n")))
10789    (clobber (match_operand 3 "register_operand" "=r"))
10790    (use (match_operand 4 "" ""))]
10791   "!SIBLING_CALL_P (insn)
10793    && GET_MODE (operands[3]) == Pmode"
10794   "brasl\t%3,%1%K1%J4"
10795   [(set_attr "op_type" "RIL")
10796    (set_attr "type"    "jsr")
10797    (set_attr "z196prop" "z196_cracked")
10798    (set_attr "relative_long" "yes")])
10800 (define_insn "*basr_tls"
10801   [(set (match_operand 0 "" "")
10802         (call (mem:QI (match_operand 1 "address_operand" "ZR"))
10803               (match_operand 2 "const_int_operand" "n")))
10804    (clobber (match_operand 3 "register_operand" "=r"))
10805    (use (match_operand 4 "" ""))]
10806   "!SIBLING_CALL_P (insn) && GET_MODE (operands[3]) == Pmode"
10808   if (get_attr_op_type (insn) == OP_TYPE_RR)
10809     return "basr\t%3,%1%J4";
10810   else
10811     return "bas\t%3,%a1%J4";
10813   [(set (attr "op_type")
10814         (if_then_else (match_operand 1 "register_operand" "")
10815                       (const_string "RR") (const_string "RX")))
10816    (set_attr "type"  "jsr")
10817    (set_attr "atype" "agen")
10818    (set_attr "z196prop" "z196_cracked")])
10821 ;;- Atomic operations
10825 ; memory barrier patterns.
10828 (define_expand "mem_thread_fence"
10829   [(match_operand:SI 0 "const_int_operand")]            ;; model
10830   ""
10832   /* Unless this is a SEQ_CST fence, the s390 memory model is strong
10833      enough not to require barriers of any kind.  */
10834   if (is_mm_seq_cst (memmodel_from_int (INTVAL (operands[0]))))
10835     {
10836       rtx mem = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
10837       MEM_VOLATILE_P (mem) = 1;
10838       emit_insn (gen_mem_thread_fence_1 (mem));
10839     }
10840   DONE;
10843 ; Although bcr is superscalar on Z10, this variant will never
10844 ; become part of an execution group.
10845 ; With z196 we can make use of the fast-BCR-serialization facility.
10846 ; This allows for a slightly faster sync which is sufficient for our
10847 ; purposes.
10848 (define_insn "mem_thread_fence_1"
10849   [(set (match_operand:BLK 0 "" "")
10850         (unspec:BLK [(match_dup 0)] UNSPEC_MB))]
10851   ""
10853   if (TARGET_Z196)
10854     return "bcr\t14,0";
10855   else
10856     return "bcr\t15,0";
10858   [(set_attr "op_type" "RR")
10859    (set_attr "mnemonic" "bcr_flush")
10860    (set_attr "z196prop" "z196_alone")])
10863 ; atomic load/store operations
10866 ; Atomic loads need not examine the memory model at all.
10867 (define_expand "atomic_load<mode>"
10868   [(match_operand:DINT 0 "register_operand")    ;; output
10869    (match_operand:DINT 1 "memory_operand")      ;; memory
10870    (match_operand:SI 2 "const_int_operand")]    ;; model
10871   ""
10873   if (MEM_ALIGN (operands[1]) < GET_MODE_BITSIZE (GET_MODE (operands[1])))
10874     FAIL;
10876   if (<MODE>mode == TImode)
10877     emit_insn (gen_atomic_loadti_1 (operands[0], operands[1]));
10878   else if (<MODE>mode == DImode && !TARGET_ZARCH)
10879     emit_insn (gen_atomic_loaddi_1 (operands[0], operands[1]));
10880   else
10881     emit_move_insn (operands[0], operands[1]);
10882   DONE;
10885 ; Different from movdi_31 in that we want no splitters.
10886 (define_insn "atomic_loaddi_1"
10887   [(set (match_operand:DI 0 "register_operand" "=d,d,!*f,!*f")
10888         (unspec:DI [(match_operand:DI 1 "memory_operand" "Q,S,R,T")]
10889                    UNSPEC_MOVA))]
10890   "!TARGET_ZARCH"
10891   "@
10892    lm\t%0,%M0,%S1
10893    lmy\t%0,%M0,%S1
10894    ld\t%0,%1
10895    ldy\t%0,%1"
10896   [(set_attr "op_type" "RS,RSY,RS,RSY")
10897    (set_attr "cpu_facility" "*,longdisp,*,longdisp")
10898    (set_attr "type" "lm,lm,floaddf,floaddf")])
10900 (define_insn "atomic_loadti_1"
10901   [(set (match_operand:TI 0 "register_operand" "=r")
10902         (unspec:TI [(match_operand:TI 1 "memory_operand" "T")]
10903                    UNSPEC_MOVA))]
10904   "TARGET_ZARCH"
10905   "lpq\t%0,%1"
10906   [(set_attr "op_type" "RXY")
10907    (set_attr "type" "other")])
10909 ; Atomic stores must(?) enforce sequential consistency.
10910 (define_expand "atomic_store<mode>"
10911   [(match_operand:DINT 0 "memory_operand")      ;; memory
10912    (match_operand:DINT 1 "register_operand")    ;; input
10913    (match_operand:SI 2 "const_int_operand")]    ;; model
10914   ""
10916   enum memmodel model = memmodel_from_int (INTVAL (operands[2]));
10918   if (MEM_ALIGN (operands[0]) < GET_MODE_BITSIZE (GET_MODE (operands[0])))
10919     FAIL;
10921   if (<MODE>mode == TImode)
10922     emit_insn (gen_atomic_storeti_1 (operands[0], operands[1]));
10923   else if (<MODE>mode == DImode && !TARGET_ZARCH)
10924     emit_insn (gen_atomic_storedi_1 (operands[0], operands[1]));
10925   else
10926     emit_move_insn (operands[0], operands[1]);
10927   if (is_mm_seq_cst (model))
10928     emit_insn (gen_mem_thread_fence (operands[2]));
10929   DONE;
10932 ; Different from movdi_31 in that we want no splitters.
10933 (define_insn "atomic_storedi_1"
10934   [(set (match_operand:DI 0 "memory_operand" "=Q,S,R,T")
10935         (unspec:DI [(match_operand:DI 1 "register_operand" "d,d,!*f,!*f")]
10936                    UNSPEC_MOVA))]
10937   "!TARGET_ZARCH"
10938   "@
10939    stm\t%1,%N1,%S0
10940    stmy\t%1,%N1,%S0
10941    std %1,%0
10942    stdy %1,%0"
10943   [(set_attr "op_type" "RS,RSY,RS,RSY")
10944    (set_attr "cpu_facility" "*,longdisp,*,longdisp")
10945    (set_attr "type" "stm,stm,fstoredf,fstoredf")])
10947 (define_insn "atomic_storeti_1"
10948   [(set (match_operand:TI 0 "memory_operand" "=T")
10949         (unspec:TI [(match_operand:TI 1 "register_operand" "r")]
10950                    UNSPEC_MOVA))]
10951   "TARGET_ZARCH"
10952   "stpq\t%1,%0"
10953   [(set_attr "op_type" "RXY")
10954    (set_attr "type" "other")])
10957 ; compare and swap patterns.
10960 (define_expand "atomic_compare_and_swap<mode>"
10961   [(match_operand:SI 0 "register_operand")      ;; bool success output
10962    (match_operand:DINT 1 "nonimmediate_operand");; oldval output
10963    (match_operand:DINT 2 "s_operand")           ;; memory
10964    (match_operand:DINT 3 "general_operand")     ;; expected intput
10965    (match_operand:DINT 4 "general_operand")     ;; newval intput
10966    (match_operand:SI 5 "const_int_operand")     ;; is_weak
10967    (match_operand:SI 6 "const_int_operand")     ;; success model
10968    (match_operand:SI 7 "const_int_operand")]    ;; failure model
10969   ""
10971   if (GET_MODE_BITSIZE (<MODE>mode) >= 16
10972       && GET_MODE_BITSIZE (<MODE>mode) > MEM_ALIGN (operands[2]))
10973     FAIL;
10975   s390_expand_cs (<MODE>mode, operands[0], operands[1], operands[2],
10976                   operands[3], operands[4], INTVAL (operands[5]));
10977   DONE;})
10979 (define_expand "atomic_compare_and_swap<mode>_internal"
10980   [(parallel
10981      [(set (match_operand:DGPR 0 "register_operand")
10982            (match_operand:DGPR 1 "s_operand"))
10983       (set (match_dup 1)
10984            (unspec_volatile:DGPR
10985              [(match_dup 1)
10986               (match_operand:DGPR 2 "register_operand")
10987               (match_operand:DGPR 3 "register_operand")]
10988              UNSPECV_CAS))
10989       (set (match_operand 4 "cc_reg_operand")
10990            (match_dup 5))])]
10991   "GET_MODE (operands[4]) == CCZmode
10992    || GET_MODE (operands[4]) == CCZ1mode"
10994   operands[5]
10995     = gen_rtx_COMPARE (GET_MODE (operands[4]), operands[1], operands[2]);
10998 ; cdsg, csg
10999 (define_insn "*atomic_compare_and_swap<mode>_1"
11000   [(set (match_operand:TDI 0 "register_operand" "=r")
11001         (match_operand:TDI 1 "nonsym_memory_operand" "+S"))
11002    (set (match_dup 1)
11003         (unspec_volatile:TDI
11004           [(match_dup 1)
11005            (match_operand:TDI 2 "register_operand" "0")
11006            (match_operand:TDI 3 "register_operand" "r")]
11007           UNSPECV_CAS))
11008    (set (reg CC_REGNUM)
11009         (compare (match_dup 1) (match_dup 2)))]
11010   "TARGET_ZARCH
11011    && s390_match_ccmode (insn, CCZ1mode)"
11012   "c<td>sg\t%0,%3,%S1"
11013   [(set_attr "op_type" "RSY")
11014    (set_attr "type"   "sem")])
11016 ; cds, cdsy
11017 (define_insn "*atomic_compare_and_swapdi_2"
11018   [(set (match_operand:DI 0 "register_operand" "=r,r")
11019         (match_operand:DI 1 "nonsym_memory_operand" "+Q,S"))
11020    (set (match_dup 1)
11021         (unspec_volatile:DI
11022           [(match_dup 1)
11023            (match_operand:DI 2 "register_operand" "0,0")
11024            (match_operand:DI 3 "register_operand" "r,r")]
11025           UNSPECV_CAS))
11026    (set (reg CC_REGNUM)
11027         (compare (match_dup 1) (match_dup 2)))]
11028   "!TARGET_ZARCH
11029    && s390_match_ccmode (insn, CCZ1mode)"
11030   "@
11031    cds\t%0,%3,%S1
11032    cdsy\t%0,%3,%S1"
11033   [(set_attr "op_type" "RS,RSY")
11034    (set_attr "cpu_facility" "*,longdisp")
11035    (set_attr "type" "sem")])
11037 ; cs, csy
11038 (define_insn "*atomic_compare_and_swapsi_3"
11039   [(set (match_operand:SI 0 "register_operand" "=r,r")
11040         (match_operand:SI 1 "nonsym_memory_operand" "+Q,S"))
11041    (set (match_dup 1)
11042         (unspec_volatile:SI
11043           [(match_dup 1)
11044            (match_operand:SI 2 "register_operand" "0,0")
11045            (match_operand:SI 3 "register_operand" "r,r")]
11046           UNSPECV_CAS))
11047    (set (reg CC_REGNUM)
11048         (compare (match_dup 1) (match_dup 2)))]
11049   "s390_match_ccmode (insn, CCZ1mode)"
11050   "@
11051    cs\t%0,%3,%S1
11052    csy\t%0,%3,%S1"
11053   [(set_attr "op_type" "RS,RSY")
11054    (set_attr "cpu_facility" "*,longdisp")
11055    (set_attr "type"   "sem")])
11058 ; Other atomic instruction patterns.
11061 ; z196 load and add, xor, or and and instructions
11063 (define_expand "atomic_fetch_<atomic><mode>"
11064   [(match_operand:GPR 0 "register_operand")             ;; val out
11065    (ATOMIC_Z196:GPR
11066      (match_operand:GPR 1 "memory_operand")             ;; memory
11067      (match_operand:GPR 2 "register_operand"))          ;; val in
11068    (match_operand:SI 3 "const_int_operand")]            ;; model
11069   "TARGET_Z196"
11071   if (MEM_ALIGN (operands[1]) < GET_MODE_BITSIZE (GET_MODE (operands[1])))
11072     FAIL;
11074   emit_insn (gen_atomic_fetch_<atomic><mode>_iaf
11075              (operands[0], operands[1], operands[2]));
11076   DONE;
11079 ; lan, lang, lao, laog, lax, laxg, laa, laag
11080 (define_insn "atomic_fetch_<atomic><mode>_iaf"
11081   [(set (match_operand:GPR 0 "register_operand" "=d")
11082         (match_operand:GPR 1 "memory_operand" "+S"))
11083    (set (match_dup 1)
11084         (unspec_volatile:GPR
11085          [(ATOMIC_Z196:GPR (match_dup 1)
11086                            (match_operand:GPR 2 "general_operand" "d"))]
11087          UNSPECV_ATOMIC_OP))
11088    (clobber (reg:CC CC_REGNUM))]
11089   "TARGET_Z196"
11090   "la<noxa><g>\t%0,%2,%1"
11091   [(set_attr "op_type" "RSY")
11092    (set_attr "type" "sem")])
11094 ;; For SImode and larger, the optabs.cc code will do just fine in
11095 ;; expanding a compare-and-swap loop.  For QI/HImode, we can do
11096 ;; better by expanding our own loop.
11098 (define_expand "atomic_<atomic><mode>"
11099   [(ATOMIC:HQI
11100      (match_operand:HQI 0 "memory_operand")             ;; memory
11101      (match_operand:HQI 1 "general_operand"))           ;; val in
11102    (match_operand:SI 2 "const_int_operand")]            ;; model
11103   ""
11105   s390_expand_atomic (<MODE>mode, <CODE>, NULL_RTX, operands[0],
11106                        operands[1], false);
11107   DONE;
11110 (define_expand "atomic_fetch_<atomic><mode>"
11111   [(match_operand:HQI 0 "register_operand")             ;; val out
11112    (ATOMIC:HQI
11113      (match_operand:HQI 1 "memory_operand")             ;; memory
11114      (match_operand:HQI 2 "general_operand"))           ;; val in
11115    (match_operand:SI 3 "const_int_operand")]            ;; model
11116   ""
11118   s390_expand_atomic (<MODE>mode, <CODE>, operands[0], operands[1],
11119                       operands[2], false);
11120   DONE;
11123 (define_expand "atomic_<atomic>_fetch<mode>"
11124   [(match_operand:HQI 0 "register_operand")             ;; val out
11125    (ATOMIC:HQI
11126      (match_operand:HQI 1 "memory_operand")             ;; memory
11127      (match_operand:HQI 2 "general_operand"))           ;; val in
11128    (match_operand:SI 3 "const_int_operand")]            ;; model
11129   ""
11131   s390_expand_atomic (<MODE>mode, <CODE>, operands[0], operands[1],
11132                       operands[2], true);
11133   DONE;
11136 ;; Pattern to implement atomic_exchange with a compare-and-swap loop.  The code
11137 ;; generated by the middleend is not good.
11138 (define_expand "atomic_exchange<mode>"
11139   [(match_operand:DINT 0 "register_operand")            ;; val out
11140    (match_operand:DINT 1 "s_operand")                   ;; memory
11141    (match_operand:DINT 2 "general_operand")             ;; val in
11142    (match_operand:SI 3 "const_int_operand")]            ;; model
11143   ""
11145   if (<MODE>mode != QImode
11146       && MEM_ALIGN (operands[1]) < GET_MODE_BITSIZE (<MODE>mode))
11147     FAIL;
11148   if (<MODE>mode == HImode || <MODE>mode == QImode)
11149     s390_expand_atomic (<MODE>mode, SET, operands[0], operands[1], operands[2],
11150                         false);
11151   else if (<MODE>mode == SImode || TARGET_ZARCH)
11152     s390_expand_atomic_exchange_tdsi (operands[0], operands[1], operands[2]);
11153   else
11154     FAIL;
11155   DONE;
11159 ;;- Miscellaneous instructions.
11163 ; allocate stack instruction pattern(s).
11166 (define_expand "allocate_stack"
11167   [(match_operand 0 "general_operand" "")
11168    (match_operand 1 "general_operand" "")]
11169  "TARGET_BACKCHAIN"
11171   rtx temp = gen_reg_rtx (Pmode);
11173   emit_move_insn (temp, s390_back_chain_rtx ());
11175   if (flag_stack_clash_protection)
11176     anti_adjust_stack_and_probe_stack_clash (operands[1]);
11177   else
11178     anti_adjust_stack (operands[1]);
11180   emit_move_insn (s390_back_chain_rtx (), temp);
11182   emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
11183   DONE;
11184   })
11186 (define_expand "@probe_stack2<mode>"
11187   [(set (reg:CCZ CC_REGNUM)
11188         (compare:CCZ (reg:W 0)
11189                      (match_operand:W 0 "memory_operand")))
11190    (unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
11191   "")
11193 (define_expand "probe_stack"
11194   [(match_operand 0 "memory_operand")]
11195   ""
11197   emit_insn (gen_probe_stack2 (word_mode, operands[0]));
11198   DONE;
11202 ; setjmp instruction pattern.
11205 (define_expand "builtin_setjmp_receiver"
11206   [(match_operand 0 "" "")]
11207   "flag_pic"
11209   emit_insn (s390_load_got ());
11210   emit_use (pic_offset_table_rtx);
11211   DONE;
11214 ;; These patterns say how to save and restore the stack pointer.  We need not
11215 ;; save the stack pointer at function level since we are careful to
11216 ;; preserve the backchain.  At block level, we have to restore the backchain
11217 ;; when we restore the stack pointer.
11219 ;; For nonlocal gotos, we must save both the stack pointer and its
11220 ;; backchain and restore both.  Note that in the nonlocal case, the
11221 ;; save area is a memory location.
11223 (define_expand "save_stack_function"
11224   [(match_operand 0 "general_operand" "")
11225    (match_operand 1 "general_operand" "")]
11226   ""
11227   "DONE;")
11229 (define_expand "restore_stack_function"
11230   [(match_operand 0 "general_operand" "")
11231    (match_operand 1 "general_operand" "")]
11232   ""
11233   "DONE;")
11235 (define_expand "restore_stack_block"
11236   [(match_operand 0 "register_operand" "")
11237    (match_operand 1 "register_operand" "")]
11238   "TARGET_BACKCHAIN"
11240   rtx temp = gen_reg_rtx (Pmode);
11242   emit_move_insn (temp, s390_back_chain_rtx ());
11243   emit_move_insn (operands[0], operands[1]);
11244   emit_move_insn (s390_back_chain_rtx (), temp);
11246   DONE;
11249 (define_expand "save_stack_nonlocal"
11250   [(match_operand 0 "memory_operand" "")
11251    (match_operand 1 "register_operand" "")]
11252   ""
11254   rtx base = gen_rtx_REG (Pmode, BASE_REGNUM);
11256   /* Copy the backchain to the first word, sp to the second and the
11257      literal pool base to the third.  */
11259   rtx save_bc = adjust_address (operands[0], Pmode, 0);
11260   rtx save_sp = adjust_address (operands[0], Pmode, GET_MODE_SIZE (Pmode));
11261   rtx save_bp = adjust_address (operands[0], Pmode, 2 * GET_MODE_SIZE (Pmode));
11263   if (TARGET_BACKCHAIN)
11264     emit_move_insn (save_bc, force_reg (Pmode, s390_back_chain_rtx ()));
11266   emit_move_insn (save_sp, operands[1]);
11267   emit_move_insn (save_bp, base);
11269   DONE;
11272 (define_expand "restore_stack_nonlocal"
11273   [(match_operand 0 "register_operand" "")
11274    (match_operand 1 "memory_operand" "")]
11275   ""
11277   rtx base = gen_rtx_REG (Pmode, BASE_REGNUM);
11278   rtx temp = NULL_RTX;
11280   /* Restore the backchain from the first word, sp from the second and the
11281      literal pool base from the third.  */
11283   rtx save_bc = adjust_address (operands[1], Pmode, 0);
11284   rtx save_sp = adjust_address (operands[1], Pmode, GET_MODE_SIZE (Pmode));
11285   rtx save_bp = adjust_address (operands[1], Pmode, 2 * GET_MODE_SIZE (Pmode));
11287   if (TARGET_BACKCHAIN)
11288     temp = force_reg (Pmode, save_bc);
11290   emit_move_insn (base, save_bp);
11291   emit_move_insn (operands[0], save_sp);
11293   if (temp)
11294     emit_move_insn (s390_back_chain_rtx (), temp);
11296   emit_use (base);
11297   DONE;
11300 (define_expand "exception_receiver"
11301   [(const_int 0)]
11302   ""
11304   s390_set_has_landing_pad_p (true);
11305   DONE;
11309 ; nop instruction pattern(s).
11312 (define_insn "nop"
11313   [(const_int 0)]
11314   ""
11315   "nopr\t%%r0"
11316   [(set_attr "op_type" "RR")])
11318 ; non-branch NOPs required for optimizing compare-and-branch patterns
11319 ; on z10
11321 (define_insn "nop_lr0"
11322   [(unspec_volatile [(const_int 0)] UNSPECV_NOP_LR_0)]
11323   ""
11324   "lr\t0,0"
11325   [(set_attr "op_type" "RR")
11326    (set_attr "z10prop"  "z10_fr_E1")])
11328 (define_insn "nop_lr1"
11329   [(unspec_volatile [(const_int 0)] UNSPECV_NOP_LR_1)]
11330   ""
11331   "lr\t1,1"
11332   [(set_attr "op_type" "RR")])
11334 ;;- Undeletable nops (used for hotpatching)
11336 (define_insn "nop_2_byte"
11337   [(unspec_volatile [(const_int 0)] UNSPECV_NOP_2_BYTE)]
11338   ""
11339   "nopr\t%%r0"
11340   [(set_attr "op_type" "RR")])
11342 (define_insn "nop_4_byte"
11343   [(unspec_volatile [(const_int 0)] UNSPECV_NOP_4_BYTE)]
11344   ""
11345   "nop\t0"
11346   [(set_attr "op_type" "RX")])
11348 (define_insn "nop_6_byte"
11349   [(unspec_volatile [(const_int 0)] UNSPECV_NOP_6_BYTE)]
11350   ""
11351   "brcl\t0, 0"
11352   [(set_attr "op_type" "RIL")
11353    (set_attr "relative_long" "yes")])
11357 ; Special literal pool access instruction pattern(s).
11360 (define_insn "*pool_entry"
11361   [(unspec_volatile [(match_operand 0 "consttable_operand" "X")]
11362                     UNSPECV_POOL_ENTRY)]
11363   ""
11365   machine_mode mode = GET_MODE (PATTERN (insn));
11366   unsigned int align = GET_MODE_BITSIZE (mode);
11367   s390_output_pool_entry (operands[0], mode, align);
11368   return "";
11370   [(set (attr "length")
11371         (symbol_ref "GET_MODE_SIZE (GET_MODE (PATTERN (insn)))"))])
11373 (define_insn "pool_align"
11374   [(unspec_volatile [(match_operand 0 "const_int_operand" "n")]
11375                     UNSPECV_POOL_ALIGN)]
11376   ""
11377   ".align\t%0"
11378   [(set (attr "length") (symbol_ref "INTVAL (operands[0])"))])
11380 (define_insn "pool_section_start"
11381   [(unspec_volatile [(const_int 1)] UNSPECV_POOL_SECTION)]
11382   ""
11384   switch_to_section (targetm.asm_out.function_rodata_section
11385                  (current_function_decl, false));
11386   return "";
11388   [(set_attr "length" "0")])
11390 (define_insn "pool_section_end"
11391   [(unspec_volatile [(const_int 0)] UNSPECV_POOL_SECTION)]
11392   ""
11394   switch_to_section (current_function_section ());
11395   return "";
11397   [(set_attr "length" "0")])
11399 (define_insn "main_base_64"
11400   [(set (match_operand 0 "register_operand" "=a")
11401         (unspec [(label_ref (match_operand 1 "" ""))] UNSPEC_MAIN_BASE))]
11402   "GET_MODE (operands[0]) == Pmode"
11403   "larl\t%0,%1%K1"
11404   [(set_attr "op_type" "RIL")
11405    (set_attr "type"    "larl")
11406    (set_attr "z10prop" "z10_fwd_A1")
11407    (set_attr "relative_long" "yes")])
11409 (define_insn "main_pool"
11410   [(set (match_operand 0 "register_operand" "=a")
11411         (unspec_volatile [(const_int 0)] UNSPECV_MAIN_POOL))]
11412   "GET_MODE (operands[0]) == Pmode"
11414   gcc_unreachable ();
11416   [(set (attr "type")
11417         (const_string "larl"))])
11419 (define_insn "reload_base_64"
11420   [(set (match_operand 0 "register_operand" "=a")
11421         (unspec [(label_ref (match_operand 1 "" ""))] UNSPEC_RELOAD_BASE))]
11422   "GET_MODE (operands[0]) == Pmode"
11423   "larl\t%0,%1%K1"
11424   [(set_attr "op_type" "RIL")
11425    (set_attr "type"    "larl")
11426    (set_attr "z10prop" "z10_fwd_A1")])
11428 (define_insn "pool"
11429   [(unspec_volatile [(match_operand 0 "const_int_operand" "n")] UNSPECV_POOL)]
11430   ""
11432   gcc_unreachable ();
11434   [(set (attr "length") (symbol_ref "INTVAL (operands[0])"))])
11437 ;; Insns related to generating the function prologue and epilogue.
11441 (define_expand "prologue"
11442   [(use (const_int 0))]
11443   ""
11444   "s390_emit_prologue (); DONE;")
11446 (define_expand "epilogue"
11447   [(use (const_int 1))]
11448   ""
11449   "s390_emit_epilogue (false); DONE;")
11451 (define_expand "sibcall_epilogue"
11452   [(use (const_int 0))]
11453   ""
11454   "s390_emit_epilogue (true); DONE;")
11456 ;; A direct return instruction, without using an epilogue.
11457 (define_insn "<code>"
11458   [(ANY_RETURN)]
11459   "s390_can_use_<code>_insn ()"
11461   if (TARGET_INDIRECT_BRANCH_NOBP_RET)
11462     {
11463       /* The target is always r14 so there is no clobber
11464          of r1 needed for pre z10 targets.  */
11465       s390_indirect_branch_via_thunk (RETURN_REGNUM,
11466                                       INVALID_REGNUM,
11467                                       NULL_RTX,
11468                                       s390_indirect_branch_type_return);
11469       return "";
11470     }
11471   else
11472     return "br\t%%r14";
11474   [(set (attr "op_type")
11475         (if_then_else (match_test "TARGET_INDIRECT_BRANCH_NOBP_RET")
11476                       (const_string "RIL")
11477                       (const_string "RR")))
11478    (set (attr "mnemonic")
11479         (if_then_else (match_test "TARGET_INDIRECT_BRANCH_NOBP_RET")
11480                       (const_string "jg")
11481                       (const_string "br")))
11482    (set_attr "type"    "jsr")
11483    (set_attr "atype"   "agen")])
11486 (define_expand "return_use"
11487   [(parallel
11488     [(return)
11489      (use (match_operand 0 "register_operand" "a"))])]
11490   ""
11492   if (!TARGET_CPU_Z10
11493       && TARGET_INDIRECT_BRANCH_NOBP_RET_OPTION)
11494     {
11495       if (TARGET_64BIT)
11496         emit_jump_insn (gen_returndi_prez10 (operands[0]));
11497       else
11498         emit_jump_insn (gen_returnsi_prez10 (operands[0]));
11499       DONE;
11500     }
11503 (define_insn "*return<mode>"
11504   [(return)
11505    (use (match_operand:P 0 "register_operand" "a"))]
11506   "TARGET_CPU_Z10 || !TARGET_INDIRECT_BRANCH_NOBP_RET_OPTION"
11508   if (TARGET_INDIRECT_BRANCH_NOBP_RET)
11509     {
11510       s390_indirect_branch_via_thunk (REGNO (operands[0]),
11511                                       INVALID_REGNUM,
11512                                       NULL_RTX,
11513                                       s390_indirect_branch_type_return);
11514       return "";
11515     }
11516   else
11517     return "br\t%0";
11519   [(set (attr "op_type")
11520        (if_then_else (match_test "TARGET_INDIRECT_BRANCH_NOBP_RET")
11521                      (const_string "RIL")
11522                      (const_string "RR")))
11523    (set (attr "mnemonic")
11524        (if_then_else (match_test "TARGET_INDIRECT_BRANCH_NOBP_RET")
11525                      (const_string "jg")
11526                      (const_string "br")))
11527    (set_attr "type"    "jsr")
11528    (set_attr "atype"   "agen")])
11530 (define_insn "return<mode>_prez10"
11531   [(return)
11532    (use (match_operand:P 0 "register_operand" "a"))
11533    (clobber (reg:P INDIRECT_BRANCH_THUNK_REGNUM))]
11534   "!TARGET_CPU_Z10 && TARGET_INDIRECT_BRANCH_NOBP_RET_OPTION"
11536   if (TARGET_INDIRECT_BRANCH_NOBP_RET)
11537     {
11538       s390_indirect_branch_via_thunk (REGNO (operands[0]),
11539                                       INVALID_REGNUM,
11540                                       NULL_RTX,
11541                                       s390_indirect_branch_type_return);
11542       return "";
11543     }
11544   else
11545     return "br\t%0";
11547   [(set (attr "op_type")
11548        (if_then_else (match_test "TARGET_INDIRECT_BRANCH_NOBP_RET")
11549                      (const_string "RIL")
11550                      (const_string "RR")))
11551    (set (attr "mnemonic")
11552        (if_then_else (match_test "TARGET_INDIRECT_BRANCH_NOBP_RET")
11553                      (const_string "jg")
11554                      (const_string "br")))
11555    (set_attr "type"    "jsr")
11556    (set_attr "atype"   "agen")])
11559 ;; Instruction definition to extend a 31-bit pointer into a 64-bit
11560 ;; pointer. This is used for compatibility.
11562 (define_expand "ptr_extend"
11563   [(set (match_operand:DI 0 "register_operand" "=r")
11564         (match_operand:SI 1 "register_operand" "r"))]
11565   "TARGET_64BIT"
11567   emit_insn (gen_anddi3 (operands[0],
11568                          gen_lowpart (DImode, operands[1]),
11569                          GEN_INT (0x7fffffff)));
11570   DONE;
11573 ;; Instruction definition to expand eh_return macro to support
11574 ;; swapping in special linkage return addresses.
11576 (define_expand "eh_return"
11577   [(use (match_operand 0 "register_operand" ""))]
11578   "TARGET_TPF"
11580   s390_emit_tpf_eh_return (operands[0]);
11581   DONE;
11585 ; Stack Protector Patterns
11588 (define_expand "stack_protect_set"
11589   [(set (match_operand 0 "memory_operand" "")
11590         (match_operand 1 "memory_operand" ""))]
11591   ""
11593 #ifdef TARGET_THREAD_SSP_OFFSET
11594   operands[1]
11595     = gen_rtx_MEM (Pmode, gen_rtx_PLUS (Pmode, s390_get_thread_pointer (),
11596                                         GEN_INT (TARGET_THREAD_SSP_OFFSET)));
11597 #endif
11598   if (TARGET_64BIT)
11599     emit_insn (gen_stack_protect_setdi (operands[0], operands[1]));
11600   else
11601     emit_insn (gen_stack_protect_setsi (operands[0], operands[1]));
11603   DONE;
11606 (define_insn "stack_protect_set<mode>"
11607   [(set (match_operand:DSI 0 "memory_operand" "=Q")
11608         (unspec:DSI [(match_operand:DSI 1 "memory_operand" "Q")] UNSPEC_SP_SET))]
11609   ""
11610   "mvc\t%O0(%G0,%R0),%S1"
11611   [(set_attr "op_type" "SS")])
11613 (define_expand "stack_protect_test"
11614   [(set (reg:CC CC_REGNUM)
11615         (compare (match_operand 0 "memory_operand" "")
11616                  (match_operand 1 "memory_operand" "")))
11617    (match_operand 2 "" "")]
11618   ""
11620   rtx cc_reg, test;
11621 #ifdef TARGET_THREAD_SSP_OFFSET
11622   operands[1]
11623     = gen_rtx_MEM (Pmode, gen_rtx_PLUS (Pmode, s390_get_thread_pointer (),
11624                                         GEN_INT (TARGET_THREAD_SSP_OFFSET)));
11625 #endif
11626   if (TARGET_64BIT)
11627     emit_insn (gen_stack_protect_testdi (operands[0], operands[1]));
11628   else
11629     emit_insn (gen_stack_protect_testsi (operands[0], operands[1]));
11631   cc_reg = gen_rtx_REG (CCZmode, CC_REGNUM);
11632   test = gen_rtx_EQ (VOIDmode, cc_reg, const0_rtx);
11633   emit_jump_insn (gen_cbranchcc4 (test, cc_reg, const0_rtx, operands[2]));
11634   DONE;
11637 (define_insn "stack_protect_test<mode>"
11638   [(set (reg:CCZ CC_REGNUM)
11639         (unspec:CCZ [(match_operand:DSI 0 "memory_operand" "Q")
11640                      (match_operand:DSI 1 "memory_operand" "Q")] UNSPEC_SP_TEST))]
11641   ""
11642   "clc\t%O0(%G0,%R0),%S1"
11643   [(set_attr "op_type" "SS")])
11645 ; This is used in s390_emit_prologue in order to prevent insns
11646 ; adjusting the stack pointer to be moved over insns writing stack
11647 ; slots using a copy of the stack pointer in a different register.
11648 (define_insn "@stack_tie<mode>"
11649   [(set (match_operand:BLK 0 "memory_operand" "+m")
11650         (unspec:BLK [(match_dup 0)
11651                      (match_operand:P 1 "register_operand" "r")] UNSPEC_TIE))]
11652   ""
11653   ""
11654   [(set_attr "length" "0")])
11657 (define_insn "stack_restore_from_fpr"
11658   [(set (reg:DI STACK_REGNUM)
11659         (match_operand:DI 0 "register_operand" "f"))
11660    (clobber (mem:BLK (scratch)))]
11661   "TARGET_Z10"
11662   "lgdr\t%%r15,%0"
11663   [(set_attr "op_type"  "RRE")])
11666 ; Data prefetch patterns
11669 (define_insn "prefetch"
11670   [(prefetch (match_operand 0    "address_operand"   "ZT,X")
11671              (match_operand:SI 1 "const_int_operand" " n,n")
11672              (match_operand:SI 2 "const_int_operand" " n,n"))]
11673   "TARGET_Z10"
11675   switch (which_alternative)
11676     {
11677       case 0:
11678         return INTVAL (operands[1]) == 1 ? "pfd\t2,%a0" : "pfd\t1,%a0";
11679       case 1:
11680         if (larl_operand (operands[0], Pmode))
11681           return INTVAL (operands[1]) == 1 ? "pfdrl\t2,%a0" : "pfdrl\t1,%a0";
11682           /* fallthrough */
11683       default:
11685         /* This might be reached for symbolic operands with an odd
11686            addend.  We simply omit the prefetch for such rare cases.  */
11688         return "";
11689      }
11691   [(set_attr "type" "load,larl")
11692    (set_attr "op_type" "RXY,RIL")
11693    (set_attr "z10prop" "z10_super")
11694    (set_attr "z196prop" "z196_alone")
11695    (set_attr "relative_long" "yes")])
11699 ; Byte swap instructions
11702 ; FIXME: There is also mvcin but we cannot use it since src and target
11703 ; may overlap.
11704 ; lrvr, lrv, strv, lrvgr, lrvg, strvg
11705 (define_insn "bswap<mode>2"
11706   [(set (match_operand:GPR 0            "nonimmediate_operand" "=d,d,T")
11707         (bswap:GPR (match_operand:GPR 1 "nonimmediate_operand" " d,T,d")))]
11708   ""
11709   "@
11710    lrv<g>r\t%0,%1
11711    lrv<g>\t%0,%1
11712    strv<g>\t%1,%0"
11713   [(set_attr "type" "*,load,store")
11714    (set_attr "op_type" "RRE,RXY,RXY")
11715    (set_attr "z10prop" "z10_super")])
11717 (define_insn "bswaphi2"
11718   [(set (match_operand:HI 0           "nonimmediate_operand" "=d,d,T")
11719         (bswap:HI (match_operand:HI 1 "nonimmediate_operand" " d,T,d")))]
11720   ""
11721   "@
11722    #
11723    lrvh\t%0,%1
11724    strvh\t%1,%0"
11725   [(set_attr "type" "*,load,store")
11726    (set_attr "op_type" "RRE,RXY,RXY")
11727    (set_attr "z10prop" "z10_super")])
11729 (define_split
11730   [(set (match_operand:HI 0           "register_operand" "")
11731         (bswap:HI (match_operand:HI 1 "register_operand" "")))]
11732   ""
11733   [(set (match_dup 2) (bswap:SI (match_dup 3)))
11734    (set (match_dup 2) (lshiftrt:SI (match_dup 2) (const_int 16)))]
11736   operands[2] = simplify_gen_subreg (SImode, operands[0], HImode, 0);
11737   operands[3] = simplify_gen_subreg (SImode, operands[1], HImode, 0);
11742 ; Population count instruction
11745 (define_insn "*popcountdi_z15_cc"
11746   [(set (reg CC_REGNUM)
11747         (compare (popcount:DI (match_operand:DI 1 "register_operand" "d"))
11748                  (const_int 0)))
11749    (set (match_operand:DI 0 "register_operand" "=d")
11750         (match_dup 1))]
11751   "TARGET_Z15 && s390_match_ccmode (insn, CCTmode)"
11752   "popcnt\t%0,%1,8"
11753   [(set_attr "op_type" "RRF")])
11755 (define_insn "*popcountdi_z15_cconly"
11756   [(set (reg CC_REGNUM)
11757         (compare (popcount:DI (match_operand:DI 1 "register_operand" "d"))
11758                  (const_int 0)))
11759    (clobber (match_scratch:DI 0 "=d"))]
11760   "TARGET_Z15 && s390_match_ccmode(insn, CCTmode)"
11761   "popcnt\t%0,%1,8"
11762   [(set_attr "op_type" "RRF")])
11764 (define_insn "*popcountdi_z15"
11765   [(set (match_operand:DI 0 "register_operand" "=d")
11766         (popcount:DI (match_operand:DI 1 "register_operand" "d")))
11767    (clobber (reg:CC CC_REGNUM))]
11768   "TARGET_Z15"
11769   "popcnt\t%0,%1,8"
11770   [(set_attr "op_type" "RRF")])
11772 ; The pre-z15 popcount instruction counts the bits of op1 in 8 byte
11773 ; portions and stores the result in the corresponding bytes in op0.
11774 (define_insn "*popcount<mode>_z196"
11775   [(set (match_operand:INT 0 "register_operand" "=d")
11776         (unspec:INT [(match_operand:INT 1 "register_operand" "d")] UNSPEC_POPCNT))
11777    (clobber (reg:CC CC_REGNUM))]
11778   "TARGET_Z196"
11779   "popcnt\t%0,%1"
11780   [(set_attr "op_type" "RRE")])
11782 (define_expand "popcountdi2_z196"
11783   [; popcnt op0, op1
11784    (parallel [(set (match_operand:DI 0 "register_operand" "")
11785                    (unspec:DI [(match_operand:DI 1 "register_operand")]
11786                               UNSPEC_POPCNT))
11787               (clobber (reg:CC CC_REGNUM))])
11788    ; sllg op2, op0, 32
11789    (set (match_dup 2) (ashift:DI (match_dup 0) (const_int 32)))
11790    ; agr op0, op2
11791    (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 2)))
11792               (clobber (reg:CC CC_REGNUM))])
11793    ; sllg op2, op0, 16
11794    (set (match_dup 2)
11795         (ashift:DI (match_dup 0) (const_int 16)))
11796    ; agr op0, op2
11797    (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 2)))
11798               (clobber (reg:CC CC_REGNUM))])
11799    ; sllg op2, op0, 8
11800    (set (match_dup 2) (ashift:DI (match_dup 0) (const_int 8)))
11801    ; agr op0, op2
11802    (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 2)))
11803               (clobber (reg:CC CC_REGNUM))])
11804    ; srlg op0, op0, 56
11805    (set (match_dup 0) (lshiftrt:DI (match_dup 0) (const_int 56)))]
11806   "TARGET_Z196"
11807   "operands[2] = gen_reg_rtx (DImode);")
11809 (define_expand "popcountdi2"
11810   [(parallel
11811     [(set (match_operand:DI 0 "register_operand" "")
11812           (popcount:DI (match_operand:DI 1 "register_operand")))
11813      (clobber (reg:CC CC_REGNUM))])]
11814   "TARGET_Z196"
11816   if (!TARGET_Z15)
11817     {
11818       emit_insn (gen_popcountdi2_z196 (operands[0], operands[1]));
11819       DONE;
11820     }
11821  })
11823 (define_expand "popcountsi2_z196"
11824   [; popcnt op0, op1
11825    (parallel [(set (match_operand:SI 0 "register_operand" "")
11826                    (unspec:SI [(match_operand:SI 1 "register_operand")]
11827                               UNSPEC_POPCNT))
11828               (clobber (reg:CC CC_REGNUM))])
11829    ; sllk op2, op0, 16
11830    (set (match_dup 2)
11831         (ashift:SI (match_dup 0) (const_int 16)))
11832    ; ar op0, op2
11833    (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
11834               (clobber (reg:CC CC_REGNUM))])
11835    ; sllk op2, op0, 8
11836    (set (match_dup 2) (ashift:SI (match_dup 0) (const_int 8)))
11837    ; ar op0, op2
11838    (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
11839               (clobber (reg:CC CC_REGNUM))])
11840    ; srl op0, op0, 24
11841    (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 24)))]
11842   "TARGET_Z196"
11843   "operands[2] = gen_reg_rtx (SImode);")
11845 ; popcount always counts on the full 64 bit. With the z196 version
11846 ; counting bits per byte we just ignore the upper 4 bytes.  With the
11847 ; z15 version we have to zero out the upper 32 bits first.
11848 (define_expand "popcountsi2"
11849   [(set (match_dup 2)
11850         (zero_extend:DI (match_operand:SI 1 "register_operand")))
11851    (parallel [(set (match_dup 3) (popcount:DI (match_dup 2)))
11852               (clobber (reg:CC CC_REGNUM))])
11853    (set (match_operand:SI 0 "register_operand")
11854         (subreg:SI (match_dup 3) 4))]
11855   "TARGET_Z196"
11857   if (!TARGET_Z15)
11858     {
11859       emit_insn (gen_popcountsi2_z196 (operands[0], operands[1]));
11860       DONE;
11861     }
11862   else
11863     {
11864       operands[2] = gen_reg_rtx (DImode);
11865       operands[3] = gen_reg_rtx (DImode);
11866     }
11869 (define_expand "popcounthi2_z196"
11870   [; popcnt op2, op1
11871    (parallel [(set (match_dup 2)
11872                    (unspec:HI [(match_operand:HI 1 "register_operand")]
11873                               UNSPEC_POPCNT))
11874               (clobber (reg:CC CC_REGNUM))])
11875    ; lr op3, op2
11876    (set (match_dup 3) (subreg:SI (match_dup 2) 0))
11877    ; srl op4, op3, 8
11878    (set (match_dup 4) (lshiftrt:SI (match_dup 3) (const_int 8)))
11879    ; ar op3, op4
11880    (parallel [(set (match_dup 3) (plus:SI (match_dup 3) (match_dup 4)))
11881               (clobber (reg:CC CC_REGNUM))])
11882    ; llgc op0, op3
11883    (parallel [(set (match_operand:HI 0 "register_operand" "")
11884                    (and:HI (subreg:HI (match_dup 3) 2) (const_int 255)))
11885               (clobber (reg:CC CC_REGNUM))])]
11886   "TARGET_Z196"
11888   operands[2] = gen_reg_rtx (HImode);
11889   operands[3] = gen_reg_rtx (SImode);
11890   operands[4] = gen_reg_rtx (SImode);
11893 (define_expand "popcounthi2"
11894   [(set (match_dup 2)
11895         (zero_extend:DI (match_operand:HI 1 "register_operand")))
11896    (parallel [(set (match_dup 3) (popcount:DI (match_dup 2)))
11897               (clobber (reg:CC CC_REGNUM))])
11898    (set (match_operand:HI 0 "register_operand")
11899         (subreg:HI (match_dup 3) 6))]
11900   "TARGET_Z196"
11902   if (!TARGET_Z15)
11903     {
11904       emit_insn (gen_popcounthi2_z196 (operands[0], operands[1]));
11905       DONE;
11906     }
11907   else
11908     {
11909       operands[2] = gen_reg_rtx (DImode);
11910       operands[3] = gen_reg_rtx (DImode);
11911     }
11914 ; For popcount on a single byte the old z196 style popcount
11915 ; instruction is ideal.  Since it anyway does a byte-wise popcount we
11916 ; just use it instead of zero extending the QImode input to DImode and
11917 ; using the z15 popcount variant.
11918 (define_expand "popcountqi2"
11919   [; popcnt op0, op1
11920    (parallel [(set (match_operand:QI 0 "register_operand" "")
11921                    (unspec:QI [(match_operand:QI 1 "register_operand")]
11922                               UNSPEC_POPCNT))
11923               (clobber (reg:CC CC_REGNUM))])]
11924   "TARGET_Z196"
11925   "")
11928 ;;- Copy sign instructions
11931 (define_insn "copysign<mode>3<tf_fpr>"
11932   [(set (match_operand:FP 0 "register_operand" "=f")
11933         (copysign:FP (match_operand:FP 1 "register_operand" "<fT0>")
11934                      (match_operand:FP 2 "register_operand" "f")))]
11935   "TARGET_Z196"
11936   "cpsdr\t%0,%2,%1"
11937   [(set_attr "op_type"  "RRF")
11938    (set_attr "type"     "fsimp<type>")])
11942 ;;- Transactional execution instructions
11945 ; This splitter helps combine to make use of CC directly when
11946 ; comparing the integer result of a tbegin builtin with a constant.
11947 ; The unspec is already removed by canonicalize_comparison. So this
11948 ; splitters only job is to turn the PARALLEL into separate insns
11949 ; again.  Unfortunately this only works with the very first cc/int
11950 ; compare since combine is not able to deal with data flow across
11951 ; basic block boundaries.
11953 ; It needs to be an insn pattern as well since combine does not apply
11954 ; the splitter directly.  Combine would only use it if it actually
11955 ; would reduce the number of instructions.
11956 (define_insn_and_split "*ccraw_to_int"
11957   [(set (pc)
11958         (if_then_else
11959          (match_operator 0 "s390_eqne_operator"
11960                          [(reg:CCRAW CC_REGNUM)
11961                           (match_operand 1 "const_int_operand" "")])
11962          (label_ref (match_operand 2 "" ""))
11963          (pc)))
11964    (set (match_operand:SI 3 "register_operand" "=d")
11965         (unspec:SI [(reg:CCRAW CC_REGNUM)] UNSPEC_CC_TO_INT))]
11966   ""
11967   "#"
11968   ""
11969   [(set (match_dup 3)
11970         (unspec:SI [(reg:CCRAW CC_REGNUM)] UNSPEC_CC_TO_INT))
11971    (set (pc)
11972         (if_then_else (match_op_dup 0 [(reg:CCRAW CC_REGNUM) (match_dup 1)])
11973                       (label_ref (match_dup 2))
11974                       (pc)))]
11975   "")
11977 ; Non-constrained transaction begin
11979 (define_expand "tbegin"
11980   [(match_operand:SI 0 "register_operand" "")
11981    (match_operand:BLK 1 "memory_operand" "")]
11982   "TARGET_HTM"
11984   s390_expand_tbegin (operands[0], operands[1], NULL_RTX, true);
11985   DONE;
11988 (define_expand "tbegin_nofloat"
11989   [(match_operand:SI 0 "register_operand" "")
11990    (match_operand:BLK 1 "memory_operand" "")]
11991   "TARGET_HTM"
11993   s390_expand_tbegin (operands[0], operands[1], NULL_RTX, false);
11994   DONE;
11997 (define_expand "tbegin_retry"
11998   [(match_operand:SI 0 "register_operand" "")
11999    (match_operand:BLK 1 "memory_operand" "")
12000    (match_operand:SI 2 "general_operand" "")]
12001   "TARGET_HTM"
12003   s390_expand_tbegin (operands[0], operands[1], operands[2], true);
12004   DONE;
12007 (define_expand "tbegin_retry_nofloat"
12008   [(match_operand:SI 0 "register_operand" "")
12009    (match_operand:BLK 1 "memory_operand" "")
12010    (match_operand:SI 2 "general_operand" "")]
12011   "TARGET_HTM"
12013   s390_expand_tbegin (operands[0], operands[1], operands[2], false);
12014   DONE;
12017 ; Clobber VRs since they don't get restored
12018 (define_insn "tbegin_1_z13"
12019   [(set (reg:CCRAW CC_REGNUM)
12020         (unspec_volatile:CCRAW [(match_operand 0 "const_int_operand" "D")]
12021                                UNSPECV_TBEGIN))
12022    (set (match_operand:BLK 1 "memory_operand" "=Q")
12023         (unspec_volatile:BLK [(match_dup 0)] UNSPECV_TBEGIN_TDB))
12024    (clobber (reg:TI 16)) (clobber (reg:TI 38))
12025    (clobber (reg:TI 17)) (clobber (reg:TI 39))
12026    (clobber (reg:TI 18)) (clobber (reg:TI 40))
12027    (clobber (reg:TI 19)) (clobber (reg:TI 41))
12028    (clobber (reg:TI 20)) (clobber (reg:TI 42))
12029    (clobber (reg:TI 21)) (clobber (reg:TI 43))
12030    (clobber (reg:TI 22)) (clobber (reg:TI 44))
12031    (clobber (reg:TI 23)) (clobber (reg:TI 45))
12032    (clobber (reg:TI 24)) (clobber (reg:TI 46))
12033    (clobber (reg:TI 25)) (clobber (reg:TI 47))
12034    (clobber (reg:TI 26)) (clobber (reg:TI 48))
12035    (clobber (reg:TI 27)) (clobber (reg:TI 49))
12036    (clobber (reg:TI 28)) (clobber (reg:TI 50))
12037    (clobber (reg:TI 29)) (clobber (reg:TI 51))
12038    (clobber (reg:TI 30)) (clobber (reg:TI 52))
12039    (clobber (reg:TI 31)) (clobber (reg:TI 53))]
12040 ; CONST_OK_FOR_CONSTRAINT_P does not work with D constraint since D is
12041 ; not supposed to be used for immediates (see genpreds.cc).
12042   "TARGET_VX && INTVAL (operands[0]) >= 0 && INTVAL (operands[0]) <= 0xffff"
12043   "tbegin\t%1,%x0"
12044   [(set_attr "op_type" "SIL")])
12046 (define_insn "tbegin_1"
12047   [(set (reg:CCRAW CC_REGNUM)
12048         (unspec_volatile:CCRAW [(match_operand 0 "const_int_operand" "D")]
12049                                UNSPECV_TBEGIN))
12050    (set (match_operand:BLK 1 "memory_operand" "=Q")
12051         (unspec_volatile:BLK [(match_dup 0)] UNSPECV_TBEGIN_TDB))
12052    (clobber (reg:DF 16))
12053    (clobber (reg:DF 17))
12054    (clobber (reg:DF 18))
12055    (clobber (reg:DF 19))
12056    (clobber (reg:DF 20))
12057    (clobber (reg:DF 21))
12058    (clobber (reg:DF 22))
12059    (clobber (reg:DF 23))
12060    (clobber (reg:DF 24))
12061    (clobber (reg:DF 25))
12062    (clobber (reg:DF 26))
12063    (clobber (reg:DF 27))
12064    (clobber (reg:DF 28))
12065    (clobber (reg:DF 29))
12066    (clobber (reg:DF 30))
12067    (clobber (reg:DF 31))]
12068 ; CONST_OK_FOR_CONSTRAINT_P does not work with D constraint since D is
12069 ; not supposed to be used for immediates (see genpreds.cc).
12070   "TARGET_HTM && INTVAL (operands[0]) >= 0 && INTVAL (operands[0]) <= 0xffff"
12071   "tbegin\t%1,%x0"
12072   [(set_attr "op_type" "SIL")])
12074 ; Same as above but without the FPR clobbers
12075 (define_insn "tbegin_nofloat_1"
12076   [(set (reg:CCRAW CC_REGNUM)
12077         (unspec_volatile:CCRAW [(match_operand 0 "const_int_operand" "D")]
12078                                UNSPECV_TBEGIN))
12079    (set (match_operand:BLK 1 "memory_operand" "=Q")
12080         (unspec_volatile:BLK [(match_dup 0)] UNSPECV_TBEGIN_TDB))]
12081   "TARGET_HTM && INTVAL (operands[0]) >= 0 && INTVAL (operands[0]) <= 0xffff"
12082   "tbegin\t%1,%x0"
12083   [(set_attr "op_type" "SIL")])
12086 ; Constrained transaction begin
12088 (define_expand "tbeginc"
12089   [(set (reg:CCRAW CC_REGNUM)
12090         (unspec_volatile:CCRAW [(const_int TBEGINC_MASK)]
12091                                UNSPECV_TBEGINC))]
12092   "TARGET_HTM"
12093   "")
12095 (define_insn "*tbeginc_1"
12096   [(set (reg:CCRAW CC_REGNUM)
12097         (unspec_volatile:CCRAW [(match_operand 0 "const_int_operand" " D")]
12098                                UNSPECV_TBEGINC))]
12099   "TARGET_HTM && INTVAL (operands[0]) >= 0 && INTVAL (operands[0]) <= 0xffff"
12100   "tbeginc\t0,%x0"
12101   [(set_attr "op_type" "SIL")])
12103 ; Transaction end
12105 (define_expand "tend"
12106   [(set (reg:CCRAW CC_REGNUM)
12107         (unspec_volatile:CCRAW [(const_int 0)] UNSPECV_TEND))
12108    (set (match_operand:SI 0 "register_operand" "")
12109         (unspec:SI [(reg:CCRAW CC_REGNUM)] UNSPEC_CC_TO_INT))]
12110   "TARGET_HTM"
12111   "")
12113 (define_insn "*tend_1"
12114   [(set (reg:CCRAW CC_REGNUM)
12115         (unspec_volatile:CCRAW [(const_int 0)] UNSPECV_TEND))]
12116   "TARGET_HTM"
12117   "tend"
12118   [(set_attr "op_type" "S")])
12120 ; Transaction abort
12122 (define_expand "tabort"
12123   [(unspec_volatile [(match_operand:SI 0 "nonmemory_operand" "")]
12124                     UNSPECV_TABORT)]
12125   "TARGET_HTM"
12127   if (CONST_INT_P (operands[0])
12128       && INTVAL (operands[0]) >= 0 && INTVAL (operands[0]) <= 255)
12129     {
12130       error ("invalid transaction abort code: %wd (values in range 0 "
12131              "through 255 are reserved)", INTVAL (operands[0]));
12132       FAIL;
12133     }
12136 (define_insn "*tabort_1"
12137   [(unspec_volatile [(match_operand:SI 0 "nonmemory_operand" "aJ")]
12138                     UNSPECV_TABORT)]
12139   "TARGET_HTM"
12140   "tabort\t%Y0"
12141   [(set_attr "op_type" "S")])
12143 (define_insn "*tabort_1_plus"
12144   [(unspec_volatile [(plus:SI (match_operand:SI 0 "register_operand"  "a")
12145                               (match_operand:SI 1 "const_int_operand" "J"))]
12146                     UNSPECV_TABORT)]
12147   "TARGET_HTM && CONST_OK_FOR_CONSTRAINT_P (INTVAL (operands[1]), 'J', \"J\")"
12148   "tabort\t%1(%0)"
12149   [(set_attr "op_type" "S")])
12151 ; Transaction extract nesting depth
12153 (define_insn "etnd"
12154   [(set (match_operand:SI 0 "register_operand" "=d")
12155         (unspec_volatile:SI [(const_int 0)] UNSPECV_ETND))]
12156   "TARGET_HTM"
12157   "etnd\t%0"
12158   [(set_attr "op_type" "RRE")])
12160 ; Non-transactional store
12162 (define_insn "ntstg"
12163   [(set (match_operand:DI 0 "memory_operand" "=T")
12164         (unspec_volatile:DI [(match_operand:DI 1 "register_operand" "d")]
12165                             UNSPECV_NTSTG))]
12166   "TARGET_HTM"
12167   "ntstg\t%1,%0"
12168   [(set_attr "op_type" "RXY")])
12170 ; Transaction perform processor assist
12172 (define_expand "tx_assist"
12173   [(unspec_volatile [(match_operand:SI 0 "register_operand" "")
12174                      (reg:SI GPR0_REGNUM)
12175                      (const_int PPA_TX_ABORT)]
12176                     UNSPECV_PPA)]
12177   "TARGET_HTM"
12178   "")
12180 (define_insn "*ppa"
12181   [(unspec_volatile [(match_operand:SI 0 "register_operand" "d")
12182                      (match_operand:SI 1 "register_operand" "d")
12183                      (match_operand 2 "const_int_operand" "I")]
12184                     UNSPECV_PPA)]
12185   "(TARGET_ZEC12 || TARGET_HTM) && INTVAL (operands[2]) < 16"
12186   "ppa\t%0,%1,%2"
12187   [(set_attr "op_type" "RRF")])
12190 ; Set and get floating point control register
12192 (define_insn "sfpc"
12193   [(unspec_volatile [(match_operand:SI 0 "register_operand" "d")]
12194                     UNSPECV_SFPC)]
12195   "TARGET_HARD_FLOAT"
12196   "sfpc\t%0")
12198 (define_insn "efpc"
12199   [(set (match_operand:SI 0 "register_operand" "=d")
12200         (unspec_volatile:SI [(const_int 0)] UNSPECV_EFPC))]
12201   "TARGET_HARD_FLOAT"
12202   "efpc\t%0")
12205 ; Load count to block boundary
12207 (define_insn "lcbb"
12208   [(set (match_operand:SI             0 "register_operand"  "=d")
12209         (unspec:SI [(match_operand    1 "address_operand" "ZR")
12210                     (match_operand:SI 2 "immediate_operand"  "C")] UNSPEC_LCBB))
12211    (clobber (reg:CC CC_REGNUM))]
12212   "TARGET_Z13"
12213   "lcbb\t%0,%a1,%b2"
12214   [(set_attr "op_type" "VRX")])
12216 ; Handle -fsplit-stack.
12218 (define_expand "split_stack_prologue"
12219   [(const_int 0)]
12220   ""
12222   s390_expand_split_stack_prologue ();
12223   DONE;
12226 ;; If there are operand 0 bytes available on the stack, jump to
12227 ;; operand 1.
12229 (define_expand "split_stack_space_check"
12230   [(set (pc) (if_then_else
12231               (ltu (minus (reg 15)
12232                           (match_operand 0 "register_operand"))
12233                    (unspec [(const_int 0)] UNSPEC_STACK_CHECK))
12234               (label_ref (match_operand 1))
12235               (pc)))]
12236   ""
12238   /* Offset from thread pointer to __private_ss.  */
12239   int psso = TARGET_64BIT ? 0x38 : 0x20;
12240   rtx tp = s390_get_thread_pointer ();
12241   rtx guard = gen_rtx_MEM (Pmode, plus_constant (Pmode, tp, psso));
12242   rtx reg = gen_reg_rtx (Pmode);
12243   rtx cc;
12244   if (TARGET_64BIT)
12245     emit_insn (gen_subdi3 (reg, stack_pointer_rtx, operands[0]));
12246   else
12247     emit_insn (gen_subsi3 (reg, stack_pointer_rtx, operands[0]));
12248   cc = s390_emit_compare (GT, reg, guard);
12249   s390_emit_jump (operands[1], cc);
12251   DONE;
12254 ;; Call to __morestack used by the split stack support
12256 ; The insn has 3 parts:
12257 ; 1. A jump to the call done label. The jump will be done as part of
12258 ;    __morestack and will not be explicitly emitted to the insn stream.
12259 ; 2. The call of __morestack including a use for r1 which is supposed to
12260 ;    point to the parameter block for __morestack.
12261 ; 3. 3 USES whose values together with the call done label will be
12262 ;    used to emit the parameter block to the .rodata section. This
12263 ;    needs to be tied into the same insn as 1. since the call done
12264 ;    label is emitted also as part of the parm block.  In order to
12265 ;    allow the edge to the BB with the call done label to be
12266 ;    redirected both need to make use of the same label_ref.
12268 (define_insn "@split_stack_call<mode>"
12269   [(set (pc) (label_ref (match_operand 2 "" "")))     ; call done label
12270    (set (reg:P 1) (unspec_volatile:P [(match_operand 0 "bras_sym_operand" "X")
12271                                       (reg:P 1)]
12272                                      UNSPECV_SPLIT_STACK_CALL))
12273    (use (label_ref (match_operand 1 "" "X")))         ; parm block label
12274    (use (match_operand 3 "const_int_operand" "X"))    ; frame size
12275    (use (match_operand 4 "const_int_operand" "X"))]   ; arg size
12276   ""
12278   s390_output_split_stack_data (operands[1], operands[2], operands[3], operands[4]);
12279   return "jg\t%0%K0";
12281   [(set_attr "op_type" "RIL")
12282    (set_attr "type"  "branch")])
12284 ; As above but with a conditional jump
12286 (define_insn "@split_stack_cond_call<mode>"
12287   [(set (pc)
12288         (if_then_else
12289           (match_operand 5 "" "")                     ; condition
12290           (label_ref (match_operand 2 "" ""))         ; call done label
12291           (pc)))
12292    (set (reg:P 1) (unspec_volatile:P [(match_operand 0 "bras_sym_operand" "X")
12293                                       (reg:P 1)]
12294                                      UNSPECV_SPLIT_STACK_CALL))
12295    (use (label_ref (match_operand 1 "" "X")))         ; parm block label
12296    (use (match_operand 3 "const_int_operand" "X"))    ; frame size
12297    (use (match_operand 4 "const_int_operand" "X"))]   ; arg size
12298   ""
12300   s390_output_split_stack_data (operands[1], operands[2], operands[3], operands[4]);
12301   return "jg%C5\t%0";
12303   [(set_attr "op_type" "RIL")
12304    (set_attr "type"  "branch")])
12307 (define_insn "osc_break"
12308   [(unspec_volatile [(const_int 0)] UNSPECV_OSC_BREAK)]
12309   ""
12310   "bcr\t7,%%r0"
12311   [(set_attr "op_type" "RR")])
12313 (define_expand "speculation_barrier"
12314   [(unspec_volatile [(reg:SI GPR0_REGNUM)
12315                      (reg:SI GPR0_REGNUM)
12316                      (const_int PPA_OOO_BARRIER)]
12317                     UNSPECV_PPA)]
12318   "TARGET_ZEC12"
12319   "")
12321 (define_expand "rawmemchr<SINT:mode>"
12322   [(match_operand      0 "register_operand")
12323    (match_operand      1 "memory_operand")
12324    (match_operand:SINT 2 "const_int_operand")]
12325   "TARGET_VX"
12326   "s390_rawmemchr(<SINT:MODE>mode, operands[0], operands[1], operands[2]); DONE;")