Daily bump.
[gcc.git] / gcc / config / s390 / s390.md
1 ;;- Machine description for GNU compiler -- S/390 / zSeries version.
2 ;; Copyright (C) 1999-2021 Free Software Foundation, Inc.
3 ;; Contributed by Hartmut Penner (hpenner@de.ibm.com) and
4 ;; Ulrich Weigand (uweigand@de.ibm.com) and
5 ;; Andreas Krebbel (Andreas.Krebbel@de.ibm.com)
6
7 ;; This file is part of GCC.
8
9 ;; GCC is free software; you can redistribute it and/or modify it under
10 ;; the terms of the GNU General Public License as published by the Free
11 ;; Software Foundation; either version 3, or (at your option) any later
12 ;; version.
13
14 ;; GCC is distributed in the hope that it will be useful, but WITHOUT ANY
15 ;; WARRANTY; without even the implied warranty of MERCHANTABILITY or
16 ;; FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
17 ;; for more details.
18
19 ;; You should have received a copy of the GNU General Public License
20 ;; along with GCC; see the file COPYING3. If not see
21 ;; <http://www.gnu.org/licenses/>.
22
23 ;;
24 ;; See constraints.md for a description of constraints specific to s390.
25 ;;
26
27 ;; Special formats used for outputting 390 instructions.
28 ;;
29 ;; %C: print opcode suffix for branch condition.
30 ;; %D: print opcode suffix for inverse branch condition.
31 ;; %J: print tls_load/tls_gdcall/tls_ldcall suffix
32 ;; %G: print the size of the operand in bytes.
33 ;; %O: print only the displacement of a memory reference.
34 ;; %R: print only the base register of a memory reference.
35 ;; %S: print S-type memory reference (base+displacement).
36 ;; %N: print the second word of a DImode operand.
37 ;; %M: print the second word of a TImode operand.
38 ;; %Y: print shift count operand.
39 ;;
40 ;; %b: print integer X as if it's an unsigned byte.
41 ;; %c: print integer X as if it's an signed byte.
42 ;; %x: print integer X as if it's an unsigned halfword.
43 ;; %h: print integer X as if it's a signed halfword.
44 ;; %i: print the first nonzero HImode part of X.
45 ;; %j: print the first HImode part unequal to -1 of X.
46 ;; %k: print the first nonzero SImode part of X.
47 ;; %m: print the first SImode part unequal to -1 of X.
48 ;; %o: print integer X as if it's an unsigned 32bit word.
49 ;;
50 ;; We have a special constraint for pattern matching.
51 ;;
52 ;; s_operand -- Matches a valid S operand in a RS, SI or SS type instruction.
53 ;;
54
55 ;;
56 ;; UNSPEC usage
57 ;;
58
59 (define_c_enum "unspec" [
60 ; Miscellaneous
61 UNSPEC_ROUND
62 UNSPEC_ICM
63 UNSPEC_TIE
64
65 ; Convert CC into a str comparison result and copy it into an
66 ; integer register
67 ; cc0->0, cc1->1, cc2->-1, (cc3->-1)
68 UNSPEC_STRCMPCC_TO_INT
69
70 ; Copy CC as is into the lower 2 bits of an integer register
71 UNSPEC_CC_TO_INT
72
73 ; The right hand side of an setmem
74 UNSPEC_REPLICATE_BYTE
75
76 ; GOT/PLT and lt-relative accesses
77 UNSPEC_LTREL_OFFSET
78 UNSPEC_POOL_OFFSET
79 UNSPEC_GOTENT
80 UNSPEC_GOT
81 UNSPEC_GOTOFF
82 UNSPEC_PLT
83 UNSPEC_PLTOFF
84
85 ; Literal pool
86 UNSPEC_RELOAD_BASE
87 UNSPEC_MAIN_BASE
88 UNSPEC_LTREF
89 UNSPEC_INSN
90 UNSPEC_EXECUTE
91 UNSPEC_EXECUTE_JUMP
92
93 ; Atomic Support
94 UNSPEC_MB
95 UNSPEC_MOVA
96
97 ; TLS relocation specifiers
98 UNSPEC_TLSGD
99 UNSPEC_TLSLDM
100 UNSPEC_NTPOFF
101 UNSPEC_DTPOFF
102 UNSPEC_GOTNTPOFF
103 UNSPEC_INDNTPOFF
104
105 ; TLS support
106 UNSPEC_TLSLDM_NTPOFF
107 UNSPEC_TLS_LOAD
108 UNSPEC_GET_TP
109
110 ; String Functions
111 UNSPEC_SRST
112 UNSPEC_MVST
113
114 ; Stack Smashing Protector
115 UNSPEC_SP_SET
116 UNSPEC_SP_TEST
117
118 ; Split stack support
119 UNSPEC_STACK_CHECK
120
121 ; Test Data Class (TDC)
122 UNSPEC_TDC_INSN
123
124 ; Byte-wise Population Count
125 UNSPEC_POPCNT
126 UNSPEC_COPYSIGN
127
128 ; Load FP Integer
129 UNSPEC_FPINT_FLOOR
130 UNSPEC_FPINT_BTRUNC
131 UNSPEC_FPINT_ROUND
132 UNSPEC_FPINT_CEIL
133 UNSPEC_FPINT_NEARBYINT
134 UNSPEC_FPINT_RINT
135
136 UNSPEC_LCBB
137
138 ; Vector
139 UNSPEC_VEC_SMULT_HI
140 UNSPEC_VEC_UMULT_HI
141 UNSPEC_VEC_SMULT_LO
142 UNSPEC_VEC_SMULT_EVEN
143 UNSPEC_VEC_UMULT_EVEN
144 UNSPEC_VEC_SMULT_ODD
145 UNSPEC_VEC_UMULT_ODD
146
147 UNSPEC_VEC_VMAL
148 UNSPEC_VEC_VMAH
149 UNSPEC_VEC_VMALH
150 UNSPEC_VEC_VMAE
151 UNSPEC_VEC_VMALE
152 UNSPEC_VEC_VMAO
153 UNSPEC_VEC_VMALO
154
155 UNSPEC_VEC_GATHER
156 UNSPEC_VEC_EXTRACT
157 UNSPEC_VEC_INSERT_AND_ZERO
158 UNSPEC_VEC_LOAD_BNDRY
159 UNSPEC_VEC_LOAD_LEN
160 UNSPEC_VEC_LOAD_LEN_R
161 UNSPEC_VEC_MERGEH
162 UNSPEC_VEC_MERGEL
163 UNSPEC_VEC_PACK
164 UNSPEC_VEC_PACK_SATURATE
165 UNSPEC_VEC_PACK_SATURATE_CC
166 UNSPEC_VEC_PACK_SATURATE_GENCC
167 UNSPEC_VEC_PACK_UNSIGNED_SATURATE
168 UNSPEC_VEC_PACK_UNSIGNED_SATURATE_CC
169 UNSPEC_VEC_PACK_UNSIGNED_SATURATE_GENCC
170 UNSPEC_VEC_PERM
171 UNSPEC_VEC_PERMI
172 UNSPEC_VEC_EXTEND
173 UNSPEC_VEC_STORE_LEN
174 UNSPEC_VEC_STORE_LEN_R
175 UNSPEC_VEC_VBPERM
176 UNSPEC_VEC_UNPACKH
177 UNSPEC_VEC_UNPACKH_L
178 UNSPEC_VEC_UNPACKL
179 UNSPEC_VEC_UNPACKL_L
180 UNSPEC_VEC_ADDC
181 UNSPEC_VEC_ADDE_U128
182 UNSPEC_VEC_ADDEC_U128
183 UNSPEC_VEC_AVG
184 UNSPEC_VEC_AVGU
185 UNSPEC_VEC_CHECKSUM
186 UNSPEC_VEC_GFMSUM
187 UNSPEC_VEC_GFMSUM_128
188 UNSPEC_VEC_GFMSUM_ACCUM
189 UNSPEC_VEC_GFMSUM_ACCUM_128
190 UNSPEC_VEC_SET
191
192 UNSPEC_VEC_VSUMG
193 UNSPEC_VEC_VSUMQ
194 UNSPEC_VEC_VSUM
195 UNSPEC_VEC_RL_MASK
196 UNSPEC_VEC_SLL
197 UNSPEC_VEC_SLB
198 UNSPEC_VEC_SLDBYTE
199 UNSPEC_VEC_SLDBIT
200 UNSPEC_VEC_SRDBIT
201 UNSPEC_VEC_SRAL
202 UNSPEC_VEC_SRAB
203 UNSPEC_VEC_SRL
204 UNSPEC_VEC_SRLB
205
206 UNSPEC_VEC_SUBC
207 UNSPEC_VEC_SUBE_U128
208 UNSPEC_VEC_SUBEC_U128
209
210 UNSPEC_VEC_TEST_MASK
211
212 UNSPEC_VEC_VFAE
213 UNSPEC_VEC_VFAECC
214
215 UNSPEC_VEC_VFEE
216 UNSPEC_VEC_VFEECC
217 UNSPEC_VEC_VFENE
218 UNSPEC_VEC_VFENECC
219
220 UNSPEC_VEC_VISTR
221 UNSPEC_VEC_VISTRCC
222
223 UNSPEC_VEC_VSTRC
224 UNSPEC_VEC_VSTRCCC
225
226 UNSPEC_VEC_VSTRS
227 UNSPEC_VEC_VSTRSCC
228
229 UNSPEC_VEC_VCDGB
230 UNSPEC_VEC_VCDLGB
231
232 UNSPEC_VEC_VCGDB
233 UNSPEC_VEC_VCLGDB
234
235 UNSPEC_VEC_VFI
236
237 UNSPEC_VEC_VFLL ; vector fp load lengthened
238 UNSPEC_VEC_VFLR ; vector fp load rounded
239
240 UNSPEC_VEC_VFTCI
241 UNSPEC_VEC_VFTCICC
242
243 UNSPEC_VEC_MSUM
244
245 UNSPEC_VEC_VFMIN
246 UNSPEC_VEC_VFMAX
247
248 UNSPEC_VEC_ELTSWAP
249 ])
250
251 ;;
252 ;; UNSPEC_VOLATILE usage
253 ;;
254
255 (define_c_enum "unspecv" [
256 ; Blockage
257 UNSPECV_BLOCKAGE
258
259 ; TPF Support
260 UNSPECV_TPF_PROLOGUE
261 UNSPECV_TPF_EPILOGUE
262
263 ; Literal pool
264 UNSPECV_POOL
265 UNSPECV_POOL_SECTION
266 UNSPECV_POOL_ALIGN
267 UNSPECV_POOL_ENTRY
268 UNSPECV_MAIN_POOL
269
270 ; TLS support
271 UNSPECV_SET_TP
272
273 ; Atomic Support
274 UNSPECV_CAS
275 UNSPECV_ATOMIC_OP
276
277 ; Non-branch nops used for compare-and-branch adjustments on z10
278 UNSPECV_NOP_LR_0
279 UNSPECV_NOP_LR_1
280
281 ; Hotpatching (unremovable NOPs)
282 UNSPECV_NOP_2_BYTE
283 UNSPECV_NOP_4_BYTE
284 UNSPECV_NOP_6_BYTE
285
286 ; Transactional Execution support
287 UNSPECV_TBEGIN
288 UNSPECV_TBEGIN_TDB
289 UNSPECV_TBEGINC
290 UNSPECV_TEND
291 UNSPECV_TABORT
292 UNSPECV_ETND
293 UNSPECV_NTSTG
294 UNSPECV_PPA
295
296 ; Set and get floating point control register
297 UNSPECV_SFPC
298 UNSPECV_EFPC
299
300 ; Split stack support
301 UNSPECV_SPLIT_STACK_CALL
302
303 UNSPECV_OSC_BREAK
304 ])
305
306 ;;
307 ;; Registers
308 ;;
309
310 ; Registers with special meaning
311
312 (define_constants
313 [
314 ; Sibling call register.
315 (SIBCALL_REGNUM 1)
316 ; A call-clobbered reg which can be used in indirect branch thunks
317 (INDIRECT_BRANCH_THUNK_REGNUM 1)
318 ; Literal pool base register.
319 (BASE_REGNUM 13)
320 ; Return address register.
321 (RETURN_REGNUM 14)
322 ; Stack pointer register.
323 (STACK_REGNUM 15)
324 ; Condition code register.
325 (CC_REGNUM 33)
326 ; Thread local storage pointer register.
327 (TP_REGNUM 36)
328 ])
329
330 ; Hardware register names
331
332 (define_constants
333 [
334 ; General purpose registers
335 (GPR0_REGNUM 0)
336 (GPR1_REGNUM 1)
337 (GPR2_REGNUM 2)
338 (GPR6_REGNUM 6)
339 ; Floating point registers.
340 (FPR0_REGNUM 16)
341 (FPR1_REGNUM 20)
342 (FPR2_REGNUM 17)
343 (FPR3_REGNUM 21)
344 (FPR4_REGNUM 18)
345 (FPR5_REGNUM 22)
346 (FPR6_REGNUM 19)
347 (FPR7_REGNUM 23)
348 (FPR8_REGNUM 24)
349 (FPR9_REGNUM 28)
350 (FPR10_REGNUM 25)
351 (FPR11_REGNUM 29)
352 (FPR12_REGNUM 26)
353 (FPR13_REGNUM 30)
354 (FPR14_REGNUM 27)
355 (FPR15_REGNUM 31)
356 (VR0_REGNUM 16)
357 (VR16_REGNUM 38)
358 (VR23_REGNUM 45)
359 (VR24_REGNUM 46)
360 (VR31_REGNUM 53)
361 ])
362
363 ; Rounding modes for binary floating point numbers
364 (define_constants
365 [(BFP_RND_CURRENT 0)
366 (BFP_RND_NEAREST_TIE_AWAY_FROM_0 1)
367 (BFP_RND_PREP_FOR_SHORT_PREC 3)
368 (BFP_RND_NEAREST_TIE_TO_EVEN 4)
369 (BFP_RND_TOWARD_0 5)
370 (BFP_RND_TOWARD_INF 6)
371 (BFP_RND_TOWARD_MINF 7)])
372
373 ; Rounding modes for decimal floating point numbers
374 ; 1-7 were introduced with the floating point extension facility
375 ; available with z196
376 ; With these rounding modes (1-7) a quantum exception might occur
377 ; which is suppressed for the other modes.
378 (define_constants
379 [(DFP_RND_CURRENT 0)
380 (DFP_RND_NEAREST_TIE_AWAY_FROM_0_QUANTEXC 1)
381 (DFP_RND_CURRENT_QUANTEXC 2)
382 (DFP_RND_PREP_FOR_SHORT_PREC_QUANTEXC 3)
383 (DFP_RND_NEAREST_TIE_TO_EVEN_QUANTEXC 4)
384 (DFP_RND_TOWARD_0_QUANTEXC 5)
385 (DFP_RND_TOWARD_INF_QUANTEXC 6)
386 (DFP_RND_TOWARD_MINF_QUANTEXC 7)
387 (DFP_RND_NEAREST_TIE_TO_EVEN 8)
388 (DFP_RND_TOWARD_0 9)
389 (DFP_RND_TOWARD_INF 10)
390 (DFP_RND_TOWARD_MINF 11)
391 (DFP_RND_NEAREST_TIE_AWAY_FROM_0 12)
392 (DFP_RND_NEAREST_TIE_TO_0 13)
393 (DFP_RND_AWAY_FROM_0 14)
394 (DFP_RND_PREP_FOR_SHORT_PREC 15)])
395
396 ;;
397 ;; PFPO GPR0 argument format
398 ;;
399
400 (define_constants
401 [
402 ; PFPO operation type
403 (PFPO_CONVERT 0x1000000)
404 ; PFPO operand types
405 (PFPO_OP_TYPE_SF 0x5)
406 (PFPO_OP_TYPE_DF 0x6)
407 (PFPO_OP_TYPE_TF 0x7)
408 (PFPO_OP_TYPE_FPRX2 0x7)
409 (PFPO_OP_TYPE_SD 0x8)
410 (PFPO_OP_TYPE_DD 0x9)
411 (PFPO_OP_TYPE_TD 0xa)
412 ; Bitposition of operand types
413 (PFPO_OP0_TYPE_SHIFT 16)
414 (PFPO_OP1_TYPE_SHIFT 8)
415 ; Decide whether current DFP or BFD rounding mode should be used
416 ; for the conversion.
417 (PFPO_RND_MODE_DFP 0)
418 (PFPO_RND_MODE_BFP 1)
419 ])
420
421 ;; PPA constants
422
423 ; Immediate values which can be used as the third operand to the
424 ; perform processor assist instruction
425
426 (define_constants
427 [(PPA_TX_ABORT 1)
428 (PPA_OOO_BARRIER 15)])
429
430 ; Immediate operands for tbegin and tbeginc
431 (define_constants [(TBEGIN_MASK 65292)]) ; 0xff0c
432 (define_constants [(TBEGINC_MASK 65288)]) ; 0xff08
433
434 ;; Instruction operand type as used in the Principles of Operation.
435 ;; Used to determine defaults for length and other attribute values.
436
437 (define_attr "op_type"
438 "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"
439 (const_string "NN"))
440
441 ;; Instruction type attribute used for scheduling.
442
443 (define_attr "type" "none,integer,load,lr,la,larl,lm,stm,
444 cs,vs,store,sem,idiv,
445 imulhi,imulsi,imuldi,
446 branch,jsr,fsimptf,fsimpdf,fsimpsf,fhex,
447 floadtf,floaddf,floadsf,fstoredf,fstoresf,
448 fmultf,fmuldf,fmulsf,fdivtf,fdivdf,fdivsf,
449 ftoi,fsqrttf,fsqrtdf,fsqrtsf,
450 fmadddf,fmaddsf,
451 ftrunctf,ftruncdf, ftruncsd, ftruncdd,
452 itoftf, itofdf, itofsf, itofdd, itoftd,
453 fdivdd, fdivtd, floaddd, floadsd, fmuldd, fmultd,
454 fsimpdd, fsimpsd, fsimptd, fstoredd, fstoresd,
455 ftoidfp, other"
456 (cond [(eq_attr "op_type" "NN") (const_string "other")
457 (eq_attr "op_type" "SS") (const_string "cs")]
458 (const_string "integer")))
459
460 ;; Another attribute used for scheduling purposes:
461 ;; agen: Instruction uses the address generation unit
462 ;; reg: Instruction does not use the agen unit
463
464 (define_attr "atype" "agen,reg"
465 (if_then_else (eq_attr "op_type" "E,RR,RI,RRE,RSI,RIL,RIE,RRF")
466 (const_string "reg")
467 (const_string "agen")))
468
469 ;; Properties concerning Z10 execution grouping and value forwarding.
470 ;; z10_super: instruction is superscalar.
471 ;; z10_super_c: instruction is superscalar and meets the condition of z10_c.
472 ;; z10_fwd: The instruction reads the value of an operand and stores it into a
473 ;; target register. It can forward this value to a second instruction that reads
474 ;; the same register if that second instruction is issued in the same group.
475 ;; z10_rec: The instruction is in the T pipeline and reads a register. If the
476 ;; instruction in the S pipe writes to the register, then the T instruction
477 ;; can immediately read the new value.
478 ;; z10_fr: union of Z10_fwd and z10_rec.
479 ;; z10_c: second operand of instruction is a register and read with complemented bits.
480 ;;
481 ;; An additional suffix A1, A3, or E1 indicates the respective AGI bypass.
482
483
484 (define_attr "z10prop" "none,
485 z10_super, z10_super_E1, z10_super_A1, z10_super_c, z10_super_c_E1,
486 z10_fwd, z10_fwd_A1, z10_fwd_A3, z10_fwd_E1,
487 z10_rec,
488 z10_fr, z10_fr_A3, z10_fr_E1,
489 z10_c"
490 (const_string "none"))
491
492 ;; Properties concerning Z196 decoding
493 ;; z196_alone: must group alone
494 ;; z196_end: ends a group
495 ;; z196_cracked: instruction is cracked or expanded
496 (define_attr "z196prop" "none,
497 z196_alone, z196_ends,
498 z196_cracked"
499 (const_string "none"))
500
501 ; mnemonics which only get defined through if_then_else currently
502 ; don't get added to the list values automatically and hence need to
503 ; be listed here.
504 (define_attr "mnemonic" "b,bas,basr,bc,bcr_flush,unknown" (const_string "unknown"))
505
506 ;; Length in bytes.
507
508 (define_attr "length" ""
509 (cond [(eq_attr "op_type" "E,RR") (const_int 2)
510 (eq_attr "op_type" "RX,RI,RRE,RS,RSI,S,SI,RRF") (const_int 4)]
511 (const_int 6)))
512
513
514 ;; Processor type. This attribute must exactly match the processor_type
515 ;; enumeration in s390.h.
516
517 (define_attr "cpu" "z900,z990,z9_109,z9_ec,z10,z196,zEC12,z13,z14,z15"
518 (const (symbol_ref "s390_tune_attr")))
519
520 (define_attr "cpu_facility"
521 "standard,ieee,zarch,cpu_zarch,longdisp,extimm,dfp,z10,z196,zEC12,vx,z13,z14,vxe,z15,vxe2"
522 (const_string "standard"))
523
524 (define_attr "enabled" ""
525 (cond [(eq_attr "cpu_facility" "standard")
526 (const_int 1)
527
528 (and (eq_attr "cpu_facility" "ieee")
529 (match_test "TARGET_CPU_IEEE_FLOAT"))
530 (const_int 1)
531
532 (and (eq_attr "cpu_facility" "zarch")
533 (match_test "TARGET_ZARCH"))
534 (const_int 1)
535
536 (and (eq_attr "cpu_facility" "longdisp")
537 (match_test "TARGET_LONG_DISPLACEMENT"))
538 (const_int 1)
539
540 (and (eq_attr "cpu_facility" "extimm")
541 (match_test "TARGET_EXTIMM"))
542 (const_int 1)
543
544 (and (eq_attr "cpu_facility" "dfp")
545 (match_test "TARGET_DFP"))
546 (const_int 1)
547
548 (eq_attr "cpu_facility" "cpu_zarch")
549 (const_int 1)
550
551 (and (eq_attr "cpu_facility" "z10")
552 (match_test "TARGET_Z10"))
553 (const_int 1)
554
555 (and (eq_attr "cpu_facility" "z196")
556 (match_test "TARGET_Z196"))
557 (const_int 1)
558
559 (and (eq_attr "cpu_facility" "zEC12")
560 (match_test "TARGET_ZEC12"))
561 (const_int 1)
562
563 (and (eq_attr "cpu_facility" "vx")
564 (match_test "TARGET_VX"))
565 (const_int 1)
566
567 (and (eq_attr "cpu_facility" "z13")
568 (match_test "TARGET_Z13"))
569 (const_int 1)
570
571 (and (eq_attr "cpu_facility" "z14")
572 (match_test "TARGET_Z14"))
573 (const_int 1)
574
575 (and (eq_attr "cpu_facility" "vxe")
576 (match_test "TARGET_VXE"))
577 (const_int 1)
578
579 (and (eq_attr "cpu_facility" "z15")
580 (match_test "TARGET_Z15"))
581 (const_int 1)
582
583 (and (eq_attr "cpu_facility" "vxe2")
584 (match_test "TARGET_VXE2"))
585 (const_int 1)
586 ]
587 (const_int 0)))
588
589 ;; Whether an instruction supports relative long addressing.
590 ;; Currently this corresponds to RIL-b and RIL-c instruction formats,
591 ;; but having a separate attribute, as opposed to reusing op_type,
592 ;; provides additional flexibility.
593
594 (define_attr "relative_long" "no,yes" (const_string "no"))
595
596 ;; Pipeline description for z900.
597 (include "2064.md")
598
599 ;; Pipeline description for z990, z9-109 and z9-ec.
600 (include "2084.md")
601
602 ;; Pipeline description for z10
603 (include "2097.md")
604
605 ;; Pipeline description for z196
606 (include "2817.md")
607
608 ;; Pipeline description for zEC12
609 (include "2827.md")
610
611 ;; Pipeline description for z13
612 (include "2964.md")
613
614 ;; Pipeline description for z14
615 (include "3906.md")
616
617 ;; Pipeline description for z15
618 (include "8561.md")
619
620 ;; Predicates
621 (include "predicates.md")
622
623 ;; Constraint definitions
624 (include "constraints.md")
625
626 ;; Other includes
627 (include "tpf.md")
628
629 ;; Iterators
630
631 (define_mode_iterator ALL [TI DI SI HI QI TF FPRX2 DF SF TD DD SD V1QI V2QI
632 V4QI V8QI V16QI V1HI V2HI V4HI V8HI V1SI V2SI V4SI
633 V1DI V2DI V1SF V2SF V4SF V1TI V1DF V2DF V1TF])
634
635 ;; These mode iterators allow floating point patterns to be generated from the
636 ;; same template.
637 (define_mode_iterator FP_ALL [(TF "!TARGET_VXE") (FPRX2 "TARGET_VXE") DF SF
638 (TD "TARGET_HARD_DFP") (DD "TARGET_HARD_DFP")
639 (SD "TARGET_HARD_DFP")])
640 (define_mode_iterator FP [(TF "!TARGET_VXE") (FPRX2 "TARGET_VXE") DF SF
641 (TD "TARGET_HARD_DFP") (DD "TARGET_HARD_DFP")])
642 ;; Like FP, but without a condition on TF. Useful for expanders that must be
643 ;; the same for FP and VR variants of TF.
644 (define_mode_iterator FP_ANYTF [TF (FPRX2 "TARGET_VXE") DF SF
645 (TD "TARGET_HARD_DFP")
646 (DD "TARGET_HARD_DFP")])
647 (define_mode_iterator BFP [(TF "!TARGET_VXE") (FPRX2 "TARGET_VXE") DF SF])
648 (define_mode_iterator DFP [TD DD])
649 (define_mode_iterator DFP_ALL [TD DD SD])
650 (define_mode_iterator DSF [DF SF])
651 (define_mode_iterator SD_SF [SF SD])
652 (define_mode_iterator DD_DF [DF DD])
653 (define_mode_iterator TD_TF [(TF "!TARGET_VXE") (FPRX2 "TARGET_VXE") TD])
654
655 ; 32 bit int<->fp conversion instructions are available since VXE2 (z15).
656 (define_mode_iterator VX_CONV_BFP [DF (SF "TARGET_VXE2")])
657 (define_mode_iterator VX_CONV_INT [DI (SI "TARGET_VXE2")])
658
659 ;; These mode iterators allow 31-bit and 64-bit GPR patterns to be generated
660 ;; from the same template.
661 (define_mode_iterator GPR [(DI "TARGET_ZARCH") SI])
662 (define_mode_iterator DGPR [(TI "TARGET_ZARCH") DI SI])
663 (define_mode_iterator DSI [DI SI])
664 (define_mode_iterator TDI [TI DI])
665
666 ;; These mode iterators allow :P to be used for patterns that operate on
667 ;; pointer-sized quantities. Exactly one of the two alternatives will match.
668 (define_mode_iterator P [(DI "TARGET_64BIT") (SI "!TARGET_64BIT")])
669
670 ;; These macros refer to the actual word_mode of the configuration.
671 ;; This is equal to Pmode except on 31-bit machines in zarch mode.
672 (define_mode_iterator DW [(TI "TARGET_ZARCH") (DI "!TARGET_ZARCH")])
673 (define_mode_iterator W [(DI "TARGET_ZARCH") (SI "!TARGET_ZARCH")])
674
675 ;; Used by the umul pattern to express modes having half the size.
676 (define_mode_attr DWH [(TI "DI") (DI "SI")])
677 (define_mode_attr dwh [(TI "di") (DI "si")])
678
679 ;; This mode iterator allows the QI and HI patterns to be defined from
680 ;; the same template.
681 (define_mode_iterator HQI [HI QI])
682
683 ;; This mode iterator allows the integer patterns to be defined from the
684 ;; same template.
685 (define_mode_iterator INT [(DI "TARGET_ZARCH") SI HI QI])
686 (define_mode_iterator DINT [(TI "TARGET_ZARCH") DI SI HI QI])
687 (define_mode_iterator SINT [SI HI QI])
688
689 ;; This iterator allows some 'ashift' and 'lshiftrt' pattern to be defined from
690 ;; the same template.
691 (define_code_iterator SHIFT [ashift lshiftrt])
692
693 ;; This iterator allows r[ox]sbg to be defined with the same template
694 (define_code_iterator IXOR [ior xor])
695
696 ;; This is used for merging the nand/nor and and/or with complement patterns
697 (define_code_iterator ANDOR [and ior])
698 (define_code_attr bitops_name [(and "and") (ior "or")])
699 (define_code_attr inv_bitops_name [(and "or") (ior "and")])
700 (define_code_attr inv_no [(and "o") (ior "n")])
701
702 ;; This iterator is used to expand the patterns for the nearest
703 ;; integer functions.
704 (define_int_iterator FPINT [UNSPEC_FPINT_FLOOR UNSPEC_FPINT_BTRUNC
705 UNSPEC_FPINT_ROUND UNSPEC_FPINT_CEIL
706 UNSPEC_FPINT_NEARBYINT])
707 (define_int_attr fpint_name [(UNSPEC_FPINT_FLOOR "floor")
708 (UNSPEC_FPINT_BTRUNC "btrunc")
709 (UNSPEC_FPINT_ROUND "round")
710 (UNSPEC_FPINT_CEIL "ceil")
711 (UNSPEC_FPINT_NEARBYINT "nearbyint")])
712 (define_int_attr fpint_roundingmode [(UNSPEC_FPINT_FLOOR "7")
713 (UNSPEC_FPINT_BTRUNC "5")
714 (UNSPEC_FPINT_ROUND "1")
715 (UNSPEC_FPINT_CEIL "6")
716 (UNSPEC_FPINT_NEARBYINT "0")])
717
718 ;; This iterator and attribute allow to combine most atomic operations.
719 (define_code_iterator ATOMIC [and ior xor plus minus mult])
720 (define_code_iterator ATOMIC_Z196 [and ior xor plus])
721 (define_code_attr atomic [(and "and") (ior "or") (xor "xor")
722 (plus "add") (minus "sub") (mult "nand")])
723 (define_code_attr noxa [(and "n") (ior "o") (xor "x") (plus "a")])
724
725 ;; In FP templates, a string like "lt<de>br" will expand to "ltxbr" in
726 ;; TF/TDmode, "ltdbr" in DF/DDmode, and "ltebr" in SF/SDmode.
727 (define_mode_attr xde [(TF "x") (FPRX2 "x") (DF "d") (SF "e") (TD "x")
728 (DD "d") (SD "e") (V4SF "e") (V2DF "d")])
729
730 ;; In FP templates, a <dee> in "m<dee><bt>r" will expand to "mx<bt>r" in
731 ;; TF/TDmode, "md<bt>r" in DF/DDmode, "mee<bt>r" in SFmode and "me<bt>r in
732 ;; SDmode.
733 (define_mode_attr xdee [(TF "x") (DF "d") (SF "ee") (TD "x") (DD "d") (SD "e")])
734
735 ;; The decimal floating point variants of add, sub, div and mul support 3
736 ;; fp register operands. The following attributes allow to merge the bfp and
737 ;; dfp variants in a single insn definition.
738
739 ;; These mode attributes are supposed to be used in the `enabled' insn
740 ;; attribute to disable certain alternatives for certain modes.
741 (define_mode_attr nBFP [(TF "0") (FPRX2 "0") (DF "0") (SF "0") (TD "*")
742 (DD "*") (DD "*")])
743 (define_mode_attr nDFP [(TF "*") (FPRX2 "*") (DF "*") (SF "*") (TD "0")
744 (DD "0") (DD "0")])
745 (define_mode_attr DSF [(TF "0") (FPRX2 "0") (DF "*") (SF "*") (TD "0")
746 (DD "0") (SD "0")])
747 (define_mode_attr DFDI [(TF "0") (FPRX2 "0") (DF "*") (SF "0")
748 (TD "0") (DD "0") (DD "0")
749 (TI "0") (DI "*") (SI "0")])
750 (define_mode_attr SFSI [(TF "0") (FPRX2 "0") (DF "0") (SF "*")
751 (TD "0") (DD "0") (DD "0")
752 (TI "0") (DI "0") (SI "*")])
753 (define_mode_attr DF [(TF "0") (FPRX2 "0") (DF "*") (SF "0")
754 (TD "0") (DD "0") (DD "0")
755 (TI "0") (DI "0") (SI "0")])
756 (define_mode_attr SF [(TF "0") (FPRX2 "0") (DF "0") (SF "*")
757 (TD "0") (DD "0") (DD "0")
758 (TI "0") (DI "0") (SI "0")])
759
760 ;; This attribute is used in the operand constraint list
761 ;; for instructions dealing with the sign bit of 32 or 64bit fp values.
762 ;; TFmode values are represented by a fp register pair. Since the
763 ;; sign bit instructions only handle single source and target fp registers
764 ;; these instructions can only be used for TFmode values if the source and
765 ;; target operand uses the same fp register.
766 (define_mode_attr fT0 [(TF "0") (FPRX2 "0") (DF "f") (SF "f")])
767
768 ;; This attribute adds b for bfp instructions and t for dfp instructions and is used
769 ;; within instruction mnemonics.
770 (define_mode_attr bt [(TF "b") (FPRX2 "b") (DF "b") (SF "b") (TD "t") (DD "t")
771 (SD "t")])
772
773 ;; This attribute is used within instruction mnemonics. It evaluates to d for dfp
774 ;; modes and to an empty string for bfp modes.
775 (define_mode_attr _d [(TF "") (FPRX2 "") (DF "") (SF "") (TD "d") (DD "d")
776 (SD "d")])
777
778 ;; In GPR and P templates, a constraint like "<d0>" will expand to "d" in DImode
779 ;; and "0" in SImode. This allows to combine instructions of which the 31bit
780 ;; version only operates on one register.
781 (define_mode_attr d0 [(DI "d") (SI "0")])
782
783 ;; In combination with d0 this allows to combine instructions of which the 31bit
784 ;; version only operates on one register. The DImode version needs an additional
785 ;; register for the assembler output.
786 (define_mode_attr 1 [(DI "%1,") (SI "")])
787
788 ;; In SHIFT templates, a string like "s<lr>dl" will expand to "sldl" in
789 ;; 'ashift' and "srdl" in 'lshiftrt'.
790 (define_code_attr lr [(ashift "l") (lshiftrt "r")])
791
792 ;; In SHIFT templates, this attribute holds the correct standard name for the
793 ;; pattern itself and the corresponding function calls.
794 (define_code_attr shift [(ashift "ashl") (lshiftrt "lshr")])
795
796 ;; This attribute handles differences in the instruction 'type' and will result
797 ;; in "RRE" for DImode and "RR" for SImode.
798 (define_mode_attr E [(DI "E") (SI "")])
799
800 ;; This attribute handles differences in the instruction 'type' and makes RX<Y>
801 ;; to result in "RXY" for DImode and "RX" for SImode.
802 (define_mode_attr Y [(DI "Y") (SI "")])
803
804 ;; This attribute handles differences in the instruction 'type' and will result
805 ;; in "RSE" for TImode and "RS" for DImode.
806 (define_mode_attr TE [(TI "E") (DI "")])
807
808 ;; In GPR templates, a string like "lc<g>r" will expand to "lcgr" in DImode
809 ;; and "lcr" in SImode.
810 (define_mode_attr g [(DI "g") (SI "")])
811
812 ;; In GPR templates, a string like "sl<y>" will expand to "slg" in DImode
813 ;; and "sly" in SImode. This is useful because on 64bit the ..g instructions
814 ;; were enhanced with long displacements whereas 31bit instructions got a ..y
815 ;; variant for long displacements.
816 (define_mode_attr y [(DI "g") (SI "y")])
817
818 ;; In DW templates, a string like "cds<g>" will expand to "cdsg" in TImode
819 ;; and "cds" in DImode.
820 (define_mode_attr tg [(TI "g") (DI "")])
821
822 ;; In TDI templates, a string like "c<d>sg".
823 (define_mode_attr td [(TI "d") (DI "")])
824
825 ;; In GPR templates, a string like "c<gf>dbr" will expand to "cgdbr" in DImode
826 ;; and "cfdbr" in SImode.
827 (define_mode_attr gf [(DI "g") (SI "f")])
828
829 ;; In GPR templates, a string like sll<gk> will expand to sllg for DI
830 ;; and sllk for SI. This way it is possible to merge the new z196 SI
831 ;; 3 operands shift instructions into the existing patterns.
832 (define_mode_attr gk [(DI "g") (SI "k")])
833
834 ;; ICM mask required to load MODE value into the lowest subreg
835 ;; of a SImode register.
836 (define_mode_attr icm_lo [(HI "3") (QI "1")])
837
838 ;; In HQI templates, a string like "llg<hc>" will expand to "llgh" in
839 ;; HImode and "llgc" in QImode.
840 (define_mode_attr hc [(HI "h") (QI "c")])
841
842 ;; In P templates, the mode <DBL> will expand to "TI" in DImode and "DI"
843 ;; in SImode.
844 (define_mode_attr DBL [(DI "TI") (SI "DI")])
845
846 ;; This attribute expands to DF for TFmode and to DD for TDmode . It is
847 ;; used for Txmode splitters splitting a Txmode copy into 2 Dxmode copies.
848 (define_mode_attr HALF_TMODE [(TF "DF") (FPRX2 "DF") (TD "DD")])
849
850 ;; Maximum unsigned integer that fits in MODE.
851 (define_mode_attr max_uint [(HI "65535") (QI "255")])
852
853 ;; Start and end field computations for RISBG et al.
854 (define_mode_attr bfstart [(DI "s") (SI "t")])
855 (define_mode_attr bfend [(DI "e") (SI "f")])
856
857 ;; In place of GET_MODE_BITSIZE (<MODE>mode)
858 (define_mode_attr bitsize [(DI "64") (SI "32") (HI "16") (QI "8")])
859 ;; 64 - bitsize
860 (define_mode_attr bitoff [(DI "0") (SI "32") (HI "48") (QI "56")])
861 (define_mode_attr bitoff_plus [(DI "") (SI "32+") (HI "48+") (QI "56+")])
862
863 ;; In place of GET_MODE_SIZE (<MODE>mode)
864 (define_mode_attr modesize [(DI "8") (SI "4")])
865
866 ;; Allow return and simple_return to be defined from a single template.
867 (define_code_iterator ANY_RETURN [return simple_return])
868
869 ;; Facilitate dispatching TFmode expanders on z14+.
870 (define_mode_attr tf_fpr [(TF "_fpr") (FPRX2 "") (DF "") (SF "") (TD "")
871 (DD "") (SD "")])
872
873 ;; Mode names as seen in type mode_attr values.
874 (define_mode_attr type [(TF "tf") (FPRX2 "tf") (DF "df") (SF "sf") (TD "td")
875 (DD "dd") (SD "sd")])
876
877
878 ; Condition code modes generated by vector fp comparisons. These will
879 ; be used also in single element mode.
880 (define_mode_iterator VFCMP [CCVEQ CCVFH CCVFHE])
881 ; Used with VFCMP to expand part of the mnemonic
882 ; For fp we have a mismatch: eq in the insn name - e in asm
883 (define_mode_attr asm_fcmp [(CCVEQ "e") (CCVFH "h") (CCVFHE "he")])
884 (define_mode_attr insn_cmp [(CCVEQ "eq") (CCVIH "h") (CCVIHU "hl") (CCVFH "h") (CCVFHE "he")])
885
886 ;; Subst pattern definitions
887 (include "subst.md")
888
889 (include "vector.md")
890
891 ;;
892 ;;- Compare instructions.
893 ;;
894
895 ; Test-under-Mask instructions
896
897 (define_insn "*tmqi_mem"
898 [(set (reg CC_REGNUM)
899 (compare (and:QI (match_operand:QI 0 "memory_operand" "Q,S")
900 (match_operand:QI 1 "immediate_operand" "n,n"))
901 (match_operand:QI 2 "immediate_operand" "n,n")))]
902 "s390_match_ccmode (insn, s390_tm_ccmode (operands[1], operands[2], false))"
903 "@
904 tm\t%S0,%b1
905 tmy\t%S0,%b1"
906 [(set_attr "op_type" "SI,SIY")
907 (set_attr "cpu_facility" "*,longdisp")
908 (set_attr "z10prop" "z10_super,z10_super")])
909
910 (define_insn "*tmdi_reg"
911 [(set (reg CC_REGNUM)
912 (compare (and:DI (match_operand:DI 0 "nonimmediate_operand" "d,d,d,d")
913 (match_operand:DI 1 "immediate_operand"
914 "N0HD0,N1HD0,N2HD0,N3HD0"))
915 (match_operand:DI 2 "immediate_operand" "n,n,n,n")))]
916 "TARGET_ZARCH
917 && s390_match_ccmode (insn, s390_tm_ccmode (operands[1], operands[2], true))
918 && s390_single_part (operands[1], DImode, HImode, 0) >= 0"
919 "@
920 tmhh\t%0,%i1
921 tmhl\t%0,%i1
922 tmlh\t%0,%i1
923 tmll\t%0,%i1"
924 [(set_attr "op_type" "RI")
925 (set_attr "z10prop" "z10_super,z10_super,z10_super,z10_super")])
926
927 (define_insn "*tmsi_reg"
928 [(set (reg CC_REGNUM)
929 (compare (and:SI (match_operand:SI 0 "nonimmediate_operand" "d,d")
930 (match_operand:SI 1 "immediate_operand" "N0HS0,N1HS0"))
931 (match_operand:SI 2 "immediate_operand" "n,n")))]
932 "s390_match_ccmode (insn, s390_tm_ccmode (operands[1], operands[2], true))
933 && s390_single_part (operands[1], SImode, HImode, 0) >= 0"
934 "@
935 tmh\t%0,%i1
936 tml\t%0,%i1"
937 [(set_attr "op_type" "RI")
938 (set_attr "z10prop" "z10_super,z10_super")])
939
940 (define_insn "*tm<mode>_full"
941 [(set (reg CC_REGNUM)
942 (compare (match_operand:HQI 0 "register_operand" "d")
943 (match_operand:HQI 1 "immediate_operand" "n")))]
944 "s390_match_ccmode (insn, s390_tm_ccmode (constm1_rtx, operands[1], true))"
945 "tml\t%0,<max_uint>"
946 [(set_attr "op_type" "RI")
947 (set_attr "z10prop" "z10_super")])
948
949
950 ;
951 ; Load-and-Test instructions
952 ;
953
954 ; tst(di|si) instruction pattern(s).
955
956 (define_insn "*tstdi_sign"
957 [(set (reg CC_REGNUM)
958 (compare
959 (ashiftrt:DI
960 (ashift:DI
961 (subreg:DI (match_operand:SI 0 "nonimmediate_operand" "d,T") 0)
962 (const_int 32)) (const_int 32))
963 (match_operand:DI 1 "const0_operand" "")))
964 (set (match_operand:DI 2 "register_operand" "=d,d")
965 (sign_extend:DI (match_dup 0)))]
966 "s390_match_ccmode(insn, CCSmode) && TARGET_ZARCH"
967 "ltgfr\t%2,%0
968 ltgf\t%2,%0"
969 [(set_attr "op_type" "RRE,RXY")
970 (set_attr "cpu_facility" "*,z10")
971 (set_attr "z10prop" "z10_super_E1,z10_super_E1") ])
972
973 ; ltr, lt, ltgr, ltg
974 (define_insn "*tst<mode>_extimm"
975 [(set (reg CC_REGNUM)
976 (compare (match_operand:GPR 0 "nonimmediate_operand" "d,T")
977 (match_operand:GPR 1 "const0_operand" "")))
978 (set (match_operand:GPR 2 "register_operand" "=d,d")
979 (match_dup 0))]
980 "s390_match_ccmode(insn, CCSmode) && TARGET_EXTIMM"
981 "@
982 lt<g>r\t%2,%0
983 lt<g>\t%2,%0"
984 [(set_attr "op_type" "RR<E>,RXY")
985 (set_attr "z10prop" "z10_fr_E1,z10_fwd_A3") ])
986
987 ; Peephole to combine a load-and-test from volatile memory which combine does
988 ; not do.
989 (define_peephole2
990 [(set (match_operand:GPR 0 "register_operand")
991 (match_operand:GPR 2 "memory_operand"))
992 (set (reg CC_REGNUM)
993 (compare (match_dup 0) (match_operand:GPR 1 "const0_operand")))]
994 "s390_match_ccmode(insn, CCSmode) && TARGET_EXTIMM
995 && GENERAL_REG_P (operands[0])
996 && satisfies_constraint_T (operands[2])
997 && !contains_constant_pool_address_p (operands[2])"
998 [(parallel
999 [(set (reg:CCS CC_REGNUM)
1000 (compare:CCS (match_dup 2) (match_dup 1)))
1001 (set (match_dup 0) (match_dup 2))])])
1002
1003 ; ltr, lt, ltgr, ltg
1004 (define_insn "*tst<mode>_cconly_extimm"
1005 [(set (reg CC_REGNUM)
1006 (compare (match_operand:GPR 0 "nonimmediate_operand" "d,T")
1007 (match_operand:GPR 1 "const0_operand" "")))
1008 (clobber (match_scratch:GPR 2 "=X,d"))]
1009 "s390_match_ccmode(insn, CCSmode) && TARGET_EXTIMM"
1010 "@
1011 lt<g>r\t%0,%0
1012 lt<g>\t%2,%0"
1013 [(set_attr "op_type" "RR<E>,RXY")
1014 (set_attr "z10prop" "z10_fr_E1,z10_fwd_A3")])
1015
1016 (define_insn "*tstdi"
1017 [(set (reg CC_REGNUM)
1018 (compare (match_operand:DI 0 "register_operand" "d")
1019 (match_operand:DI 1 "const0_operand" "")))
1020 (set (match_operand:DI 2 "register_operand" "=d")
1021 (match_dup 0))]
1022 "s390_match_ccmode(insn, CCSmode) && TARGET_ZARCH && !TARGET_EXTIMM"
1023 "ltgr\t%2,%0"
1024 [(set_attr "op_type" "RRE")
1025 (set_attr "z10prop" "z10_fr_E1")])
1026
1027 (define_insn "*tstsi"
1028 [(set (reg CC_REGNUM)
1029 (compare (match_operand:SI 0 "nonimmediate_operand" "d,Q,S")
1030 (match_operand:SI 1 "const0_operand" "")))
1031 (set (match_operand:SI 2 "register_operand" "=d,d,d")
1032 (match_dup 0))]
1033 "s390_match_ccmode(insn, CCSmode) && !TARGET_EXTIMM"
1034 "@
1035 ltr\t%2,%0
1036 icm\t%2,15,%S0
1037 icmy\t%2,15,%S0"
1038 [(set_attr "op_type" "RR,RS,RSY")
1039 (set_attr "cpu_facility" "*,*,longdisp")
1040 (set_attr "z10prop" "z10_fr_E1,z10_super_E1,z10_super_E1")])
1041
1042 (define_insn "*tstsi_cconly"
1043 [(set (reg CC_REGNUM)
1044 (compare (match_operand:SI 0 "nonimmediate_operand" "d,Q,S")
1045 (match_operand:SI 1 "const0_operand" "")))
1046 (clobber (match_scratch:SI 2 "=X,d,d"))]
1047 "s390_match_ccmode(insn, CCSmode)"
1048 "@
1049 ltr\t%0,%0
1050 icm\t%2,15,%S0
1051 icmy\t%2,15,%S0"
1052 [(set_attr "op_type" "RR,RS,RSY")
1053 (set_attr "cpu_facility" "*,*,longdisp")
1054 (set_attr "z10prop" "z10_fr_E1,z10_super_E1,z10_super_E1")])
1055
1056 (define_insn "*tstdi_cconly_31"
1057 [(set (reg CC_REGNUM)
1058 (compare (match_operand:DI 0 "register_operand" "d")
1059 (match_operand:DI 1 "const0_operand" "")))]
1060 "s390_match_ccmode(insn, CCSmode) && !TARGET_ZARCH"
1061 "srda\t%0,0"
1062 [(set_attr "op_type" "RS")
1063 (set_attr "atype" "reg")])
1064
1065 ; ltr, ltgr
1066 (define_insn "*tst<mode>_cconly2"
1067 [(set (reg CC_REGNUM)
1068 (compare (match_operand:GPR 0 "register_operand" "d")
1069 (match_operand:GPR 1 "const0_operand" "")))]
1070 "s390_match_ccmode(insn, CCSmode)"
1071 "lt<g>r\t%0,%0"
1072 [(set_attr "op_type" "RR<E>")
1073 (set_attr "z10prop" "z10_fr_E1")])
1074
1075 ; tst(hi|qi) instruction pattern(s).
1076
1077 (define_insn "*tst<mode>CCT"
1078 [(set (reg CC_REGNUM)
1079 (compare (match_operand:HQI 0 "nonimmediate_operand" "?Q,?S,d")
1080 (match_operand:HQI 1 "const0_operand" "")))
1081 (set (match_operand:HQI 2 "register_operand" "=d,d,0")
1082 (match_dup 0))]
1083 "s390_match_ccmode(insn, CCTmode)"
1084 "@
1085 icm\t%2,<icm_lo>,%S0
1086 icmy\t%2,<icm_lo>,%S0
1087 tml\t%0,<max_uint>"
1088 [(set_attr "op_type" "RS,RSY,RI")
1089 (set_attr "cpu_facility" "*,longdisp,*")
1090 (set_attr "z10prop" "z10_super_E1,z10_super_E1,z10_super")])
1091
1092 (define_insn "*tsthiCCT_cconly"
1093 [(set (reg CC_REGNUM)
1094 (compare (match_operand:HI 0 "nonimmediate_operand" "Q,S,d")
1095 (match_operand:HI 1 "const0_operand" "")))
1096 (clobber (match_scratch:HI 2 "=d,d,X"))]
1097 "s390_match_ccmode(insn, CCTmode)"
1098 "@
1099 icm\t%2,3,%S0
1100 icmy\t%2,3,%S0
1101 tml\t%0,65535"
1102 [(set_attr "op_type" "RS,RSY,RI")
1103 (set_attr "cpu_facility" "*,longdisp,*")
1104 (set_attr "z10prop" "z10_super_E1,z10_super_E1,z10_super")])
1105
1106 (define_insn "*tstqiCCT_cconly"
1107 [(set (reg CC_REGNUM)
1108 (compare (match_operand:QI 0 "nonimmediate_operand" "?Q,?S,d")
1109 (match_operand:QI 1 "const0_operand" "")))]
1110 "s390_match_ccmode(insn, CCTmode)"
1111 "@
1112 cli\t%S0,0
1113 cliy\t%S0,0
1114 tml\t%0,255"
1115 [(set_attr "op_type" "SI,SIY,RI")
1116 (set_attr "cpu_facility" "*,longdisp,*")
1117 (set_attr "z10prop" "z10_super,z10_super,z10_super")])
1118
1119 (define_insn "*tst<mode>"
1120 [(set (reg CC_REGNUM)
1121 (compare (match_operand:HQI 0 "s_operand" "Q,S")
1122 (match_operand:HQI 1 "const0_operand" "")))
1123 (set (match_operand:HQI 2 "register_operand" "=d,d")
1124 (match_dup 0))]
1125 "s390_match_ccmode(insn, CCSmode)"
1126 "@
1127 icm\t%2,<icm_lo>,%S0
1128 icmy\t%2,<icm_lo>,%S0"
1129 [(set_attr "op_type" "RS,RSY")
1130 (set_attr "cpu_facility" "*,longdisp")
1131 (set_attr "z10prop" "z10_super_E1,z10_super_E1")])
1132
1133 (define_insn "*tst<mode>_cconly"
1134 [(set (reg CC_REGNUM)
1135 (compare (match_operand:HQI 0 "s_operand" "Q,S")
1136 (match_operand:HQI 1 "const0_operand" "")))
1137 (clobber (match_scratch:HQI 2 "=d,d"))]
1138 "s390_match_ccmode(insn, CCSmode)"
1139 "@
1140 icm\t%2,<icm_lo>,%S0
1141 icmy\t%2,<icm_lo>,%S0"
1142 [(set_attr "op_type" "RS,RSY")
1143 (set_attr "cpu_facility" "*,longdisp")
1144 (set_attr "z10prop" "z10_super_E1,z10_super_E1")])
1145
1146
1147 ; Compare (equality) instructions
1148
1149 (define_insn "*cmpdi_cct"
1150 [(set (reg CC_REGNUM)
1151 (compare (match_operand:DI 0 "nonimmediate_operand" "%d,d,d,d,Q")
1152 (match_operand:DI 1 "general_operand" "d,K,Os,T,BQ")))]
1153 "s390_match_ccmode (insn, CCTmode) && TARGET_ZARCH"
1154 "@
1155 cgr\t%0,%1
1156 cghi\t%0,%h1
1157 cgfi\t%0,%1
1158 cg\t%0,%1
1159 #"
1160 [(set_attr "op_type" "RRE,RI,RIL,RXY,SS")
1161 (set_attr "z10prop" "z10_super_c,z10_super,z10_super,z10_super,*")])
1162
1163 (define_insn "*cmpsi_cct"
1164 [(set (reg CC_REGNUM)
1165 (compare (match_operand:SI 0 "nonimmediate_operand" "%d,d,d,d,d,Q")
1166 (match_operand:SI 1 "general_operand" "d,K,Os,R,T,BQ")))]
1167 "s390_match_ccmode (insn, CCTmode)"
1168 "@
1169 cr\t%0,%1
1170 chi\t%0,%h1
1171 cfi\t%0,%1
1172 c\t%0,%1
1173 cy\t%0,%1
1174 #"
1175 [(set_attr "op_type" "RR,RI,RIL,RX,RXY,SS")
1176 (set_attr "cpu_facility" "*,*,*,*,longdisp,*")
1177 (set_attr "z10prop" "z10_super_c,z10_super,z10_super,z10_super,z10_super,*")])
1178
1179 ; Compare (signed) instructions
1180
1181 (define_insn "*cmpdi_ccs_sign"
1182 [(set (reg CC_REGNUM)
1183 (compare (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand"
1184 "d,T,b"))
1185 (match_operand:DI 0 "register_operand" "d, d,d")))]
1186 "s390_match_ccmode(insn, CCSRmode) && TARGET_ZARCH"
1187 "@
1188 cgfr\t%0,%1
1189 cgf\t%0,%1
1190 cgfrl\t%0,%1"
1191 [(set_attr "op_type" "RRE,RXY,RIL")
1192 (set_attr "z10prop" "z10_c,*,*")
1193 (set_attr "type" "*,*,larl")
1194 (set_attr "relative_long" "*,*,yes")])
1195
1196
1197
1198 (define_insn "*cmpsi_ccs_sign"
1199 [(set (reg CC_REGNUM)
1200 (compare (sign_extend:SI (match_operand:HI 1 "memory_operand" "R,T,b"))
1201 (match_operand:SI 0 "register_operand" "d,d,d")))]
1202 "s390_match_ccmode(insn, CCSRmode)"
1203 "@
1204 ch\t%0,%1
1205 chy\t%0,%1
1206 chrl\t%0,%1"
1207 [(set_attr "op_type" "RX,RXY,RIL")
1208 (set_attr "cpu_facility" "*,longdisp,z10")
1209 (set_attr "type" "*,*,larl")
1210 (set_attr "z196prop" "z196_cracked,z196_cracked,z196_cracked")
1211 (set_attr "relative_long" "*,*,yes")])
1212
1213 (define_insn "*cmphi_ccs_z10"
1214 [(set (reg CC_REGNUM)
1215 (compare (match_operand:HI 0 "s_operand" "Q")
1216 (match_operand:HI 1 "immediate_operand" "K")))]
1217 "s390_match_ccmode(insn, CCSmode) && TARGET_Z10"
1218 "chhsi\t%0,%1"
1219 [(set_attr "op_type" "SIL")
1220 (set_attr "z196prop" "z196_cracked")])
1221
1222 (define_insn "*cmpdi_ccs_signhi_rl"
1223 [(set (reg CC_REGNUM)
1224 (compare (sign_extend:DI (match_operand:HI 1 "memory_operand" "T,b"))
1225 (match_operand:GPR 0 "register_operand" "d,d")))]
1226 "s390_match_ccmode(insn, CCSRmode) && TARGET_Z10"
1227 "@
1228 cgh\t%0,%1
1229 cghrl\t%0,%1"
1230 [(set_attr "op_type" "RXY,RIL")
1231 (set_attr "type" "*,larl")
1232 (set_attr "relative_long" "*,yes")])
1233
1234 ; cr, chi, cfi, c, cy, cgr, cghi, cgfi, cg, chsi, cghsi, crl, cgrl
1235 (define_insn "*cmp<mode>_ccs"
1236 [(set (reg CC_REGNUM)
1237 (compare (match_operand:GPR 0 "nonimmediate_operand"
1238 "d,d,Q, d,d,d,d")
1239 (match_operand:GPR 1 "general_operand"
1240 "d,K,K,Os,R,T,b")))]
1241 "s390_match_ccmode(insn, CCSmode)"
1242 "@
1243 c<g>r\t%0,%1
1244 c<g>hi\t%0,%h1
1245 c<g>hsi\t%0,%h1
1246 c<g>fi\t%0,%1
1247 c<g>\t%0,%1
1248 c<y>\t%0,%1
1249 c<g>rl\t%0,%1"
1250 [(set_attr "op_type" "RR<E>,RI,SIL,RIL,RX<Y>,RXY,RIL")
1251 (set_attr "cpu_facility" "*,*,z10,extimm,*,longdisp,z10")
1252 (set_attr "type" "*,*,*,*,*,*,larl")
1253 (set_attr "z10prop" "z10_super_c,z10_super,z10_super,z10_super,z10_super,z10_super,z10_super")
1254 (set_attr "relative_long" "*,*,*,*,*,*,yes")])
1255
1256
1257 ; Compare (unsigned) instructions
1258
1259 (define_insn "*cmpsi_ccu_zerohi_rlsi"
1260 [(set (reg CC_REGNUM)
1261 (compare (zero_extend:SI (mem:HI (match_operand:SI 1
1262 "larl_operand" "X")))
1263 (match_operand:SI 0 "register_operand" "d")))]
1264 "s390_match_ccmode(insn, CCURmode) && TARGET_Z10"
1265 "clhrl\t%0,%1"
1266 [(set_attr "op_type" "RIL")
1267 (set_attr "type" "larl")
1268 (set_attr "z10prop" "z10_super")
1269 (set_attr "relative_long" "yes")])
1270
1271 ; clhrl, clghrl
1272 (define_insn "*cmp<GPR:mode>_ccu_zerohi_rldi"
1273 [(set (reg CC_REGNUM)
1274 (compare (zero_extend:GPR (mem:HI (match_operand:DI 1
1275 "larl_operand" "X")))
1276 (match_operand:GPR 0 "register_operand" "d")))]
1277 "s390_match_ccmode(insn, CCURmode) && TARGET_Z10"
1278 "cl<g>hrl\t%0,%1"
1279 [(set_attr "op_type" "RIL")
1280 (set_attr "type" "larl")
1281 (set_attr "z10prop" "z10_super")
1282 (set_attr "relative_long" "yes")])
1283
1284 (define_insn "*cmpdi_ccu_zero"
1285 [(set (reg CC_REGNUM)
1286 (compare (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand"
1287 "d,T,b"))
1288 (match_operand:DI 0 "register_operand" "d,d,d")))]
1289 "s390_match_ccmode (insn, CCURmode) && TARGET_ZARCH"
1290 "@
1291 clgfr\t%0,%1
1292 clgf\t%0,%1
1293 clgfrl\t%0,%1"
1294 [(set_attr "op_type" "RRE,RXY,RIL")
1295 (set_attr "cpu_facility" "*,*,z10")
1296 (set_attr "type" "*,*,larl")
1297 (set_attr "z10prop" "z10_super_c,z10_super_E1,z10_super")
1298 (set_attr "relative_long" "*,*,yes")])
1299
1300 (define_insn "*cmpdi_ccu"
1301 [(set (reg CC_REGNUM)
1302 (compare (match_operand:DI 0 "nonimmediate_operand"
1303 "d, d,d,Q,d, Q,BQ")
1304 (match_operand:DI 1 "general_operand"
1305 "d,Op,b,D,T,BQ,Q")))]
1306 "s390_match_ccmode (insn, CCUmode) && TARGET_ZARCH"
1307 "@
1308 clgr\t%0,%1
1309 clgfi\t%0,%1
1310 clgrl\t%0,%1
1311 clghsi\t%0,%x1
1312 clg\t%0,%1
1313 #
1314 #"
1315 [(set_attr "op_type" "RRE,RIL,RIL,SIL,RXY,SS,SS")
1316 (set_attr "cpu_facility" "*,extimm,z10,z10,*,*,*")
1317 (set_attr "type" "*,*,larl,*,*,*,*")
1318 (set_attr "z10prop" "z10_super_c,z10_super,z10_super,z10_super,z10_super,*,*")
1319 (set_attr "relative_long" "*,*,yes,*,*,*,*")])
1320
1321 (define_insn "*cmpsi_ccu"
1322 [(set (reg CC_REGNUM)
1323 (compare (match_operand:SI 0 "nonimmediate_operand" "d, d,d,Q,d,d, Q,BQ")
1324 (match_operand:SI 1 "general_operand" "d,Os,b,D,R,T,BQ, Q")))]
1325 "s390_match_ccmode (insn, CCUmode)"
1326 "@
1327 clr\t%0,%1
1328 clfi\t%0,%o1
1329 clrl\t%0,%1
1330 clfhsi\t%0,%x1
1331 cl\t%0,%1
1332 cly\t%0,%1
1333 #
1334 #"
1335 [(set_attr "op_type" "RR,RIL,RIL,SIL,RX,RXY,SS,SS")
1336 (set_attr "cpu_facility" "*,extimm,z10,z10,*,longdisp,*,*")
1337 (set_attr "type" "*,*,larl,*,*,*,*,*")
1338 (set_attr "z10prop" "z10_super_c,z10_super,z10_super,z10_super,z10_super,z10_super,*,*")
1339 (set_attr "relative_long" "*,*,yes,*,*,*,*,*")])
1340
1341 (define_insn "*cmphi_ccu"
1342 [(set (reg CC_REGNUM)
1343 (compare (match_operand:HI 0 "nonimmediate_operand" "d,d,Q,Q,BQ")
1344 (match_operand:HI 1 "general_operand" "Q,S,D,BQ,Q")))]
1345 "s390_match_ccmode (insn, CCUmode)
1346 && !register_operand (operands[1], HImode)"
1347 "@
1348 clm\t%0,3,%S1
1349 clmy\t%0,3,%S1
1350 clhhsi\t%0,%1
1351 #
1352 #"
1353 [(set_attr "op_type" "RS,RSY,SIL,SS,SS")
1354 (set_attr "cpu_facility" "*,longdisp,z10,*,*")
1355 (set_attr "z10prop" "*,*,z10_super,*,*")])
1356
1357 (define_insn "*cmpqi_ccu"
1358 [(set (reg CC_REGNUM)
1359 (compare (match_operand:QI 0 "nonimmediate_operand" "d,d,Q,S,Q,BQ")
1360 (match_operand:QI 1 "general_operand" "Q,S,n,n,BQ,Q")))]
1361 "s390_match_ccmode (insn, CCUmode)
1362 && !register_operand (operands[1], QImode)"
1363 "@
1364 clm\t%0,1,%S1
1365 clmy\t%0,1,%S1
1366 cli\t%S0,%b1
1367 cliy\t%S0,%b1
1368 #
1369 #"
1370 [(set_attr "op_type" "RS,RSY,SI,SIY,SS,SS")
1371 (set_attr "cpu_facility" "*,longdisp,*,longdisp,*,*")
1372 (set_attr "z10prop" "*,*,z10_super,z10_super,*,*")])
1373
1374
1375 ; Block compare (CLC) instruction patterns.
1376
1377 (define_insn "*clc"
1378 [(set (reg CC_REGNUM)
1379 (compare (match_operand:BLK 0 "memory_operand" "Q")
1380 (match_operand:BLK 1 "memory_operand" "Q")))
1381 (use (match_operand 2 "const_int_operand" "n"))]
1382 "s390_match_ccmode (insn, CCUmode)
1383 && INTVAL (operands[2]) >= 1 && INTVAL (operands[2]) <= 256"
1384 "clc\t%O0(%2,%R0),%S1"
1385 [(set_attr "op_type" "SS")])
1386
1387 (define_split
1388 [(set (reg CC_REGNUM)
1389 (compare (match_operand 0 "memory_operand" "")
1390 (match_operand 1 "memory_operand" "")))]
1391 "reload_completed
1392 && s390_match_ccmode (insn, CCUmode)
1393 && GET_MODE (operands[0]) == GET_MODE (operands[1])
1394 && GET_MODE_SIZE (GET_MODE (operands[0])) > 0"
1395 [(parallel
1396 [(set (match_dup 0) (match_dup 1))
1397 (use (match_dup 2))])]
1398 {
1399 operands[2] = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[0])));
1400 operands[0] = adjust_address (operands[0], BLKmode, 0);
1401 operands[1] = adjust_address (operands[1], BLKmode, 0);
1402
1403 operands[1] = gen_rtx_COMPARE (GET_MODE (SET_DEST (PATTERN (curr_insn))),
1404 operands[0], operands[1]);
1405 operands[0] = SET_DEST (PATTERN (curr_insn));
1406 })
1407
1408
1409 ; (TF|DF|SF|TD|DD|SD) instructions
1410
1411
1412 ; load and test instructions turn a signaling NaN into a quiet NaN. Thus they
1413 ; may only be used if the target register is dead afterwards or if fast math
1414 ; is enabled. The former is done via a peephole optimization. Note, load and
1415 ; test instructions may only be used for (in)equality comparisons because
1416 ; relational comparisons must treat a quiet NaN like a signaling NaN which is
1417 ; not the case for load and test instructions. For fast math insn
1418 ; "cmp<mode>_ccs_0_fastmath" applies.
1419 ; See testcases load-and-test-fp-{1,2}.c
1420
1421 (define_peephole2
1422 [(set (match_operand:FP 0 "register_operand")
1423 (match_operand:FP 1 "const0_operand"))
1424 (set (reg:CCZ CC_REGNUM)
1425 (compare:CCZ (match_operand:FP 2 "register_operand")
1426 (match_operand:FP 3 "register_operand")))]
1427 "TARGET_HARD_FLOAT
1428 && FP_REG_P (operands[2])
1429 && REGNO (operands[0]) == REGNO (operands[3])
1430 && peep2_reg_dead_p (2, operands[0])
1431 && peep2_reg_dead_p (2, operands[2])"
1432 [(parallel
1433 [(set (reg:CCZ CC_REGNUM)
1434 (compare:CCZ (match_dup 2) (match_dup 1)))
1435 (clobber (match_dup 2))])]
1436 "")
1437
1438 ; ltxbr, ltdbr, ltebr, ltxtr, ltdtr
1439 (define_insn "*cmp<mode>_ccz_0"
1440 [(set (reg:CCZ CC_REGNUM)
1441 (compare:CCZ (match_operand:FP 0 "register_operand" "f")
1442 (match_operand:FP 1 "const0_operand")))
1443 (clobber (match_operand:FP 2 "register_operand" "=0"))]
1444 "TARGET_HARD_FLOAT"
1445 "lt<xde><bt>r\t%0,%0"
1446 [(set_attr "op_type" "RRE")
1447 (set_attr "type" "fsimp<type>")])
1448
1449 (define_insn "*cmp<mode>_ccs_0_fastmath"
1450 [(set (reg CC_REGNUM)
1451 (compare (match_operand:FP 0 "register_operand" "f")
1452 (match_operand:FP 1 "const0_operand")))]
1453 "s390_match_ccmode (insn, CCSmode)
1454 && TARGET_HARD_FLOAT
1455 && !flag_trapping_math
1456 && !flag_signaling_nans"
1457 "lt<xde><bt>r\t%0,%0"
1458 [(set_attr "op_type" "RRE")
1459 (set_attr "type" "fsimp<type>")])
1460
1461 ; VX: TFmode in FPR pairs: use cxbr instead of wfcxb
1462 ; cxtr, cdtr, cxbr, cdbr, cebr, cdb, ceb, wfcsb, wfcdb
1463 (define_insn "*cmp<mode>_ccs"
1464 [(set (reg CC_REGNUM)
1465 (compare (match_operand:FP 0 "register_operand" "f,f,v,v")
1466 (match_operand:FP 1 "general_operand" "f,R,v,v")))]
1467 "s390_match_ccmode(insn, CCSmode) && TARGET_HARD_FLOAT"
1468 "@
1469 c<xde><bt>r\t%0,%1
1470 c<xde>b\t%0,%1
1471 wfcdb\t%0,%1
1472 wfcsb\t%0,%1"
1473 [(set_attr "op_type" "RRE,RXE,VRR,VRR")
1474 (set_attr "cpu_facility" "*,*,vx,vxe")
1475 (set_attr "enabled" "*,<DSF>,<DF>,<SF>")])
1476
1477 ; VX: TFmode in VR: use wfcxb
1478 (define_insn "*cmptf_ccs"
1479 [(set (reg CC_REGNUM)
1480 (compare (match_operand:TF 0 "register_operand" "v")
1481 (match_operand:TF 1 "register_operand" "v")))]
1482 "s390_match_ccmode(insn, CCSmode) && TARGET_VXE"
1483 "wfcxb\t%0,%1"
1484 [(set_attr "op_type" "VRR")
1485 (set_attr "cpu_facility" "vxe")])
1486
1487 ; VX: TFmode in FPR pairs: use kxbr instead of wfkxb
1488 ; kxtr, kdtr, kxbr, kdbr, kebr, kdb, keb, wfksb, wfkdb
1489 (define_insn "*cmp<mode>_ccsfps"
1490 [(set (reg CC_REGNUM)
1491 (compare (match_operand:FP 0 "register_operand" "f,f,v,v")
1492 (match_operand:FP 1 "general_operand" "f,R,v,v")))]
1493 "s390_match_ccmode (insn, CCSFPSmode) && TARGET_HARD_FLOAT"
1494 "@
1495 k<xde><bt>r\t%0,%1
1496 k<xde>b\t%0,%1
1497 wfkdb\t%0,%1
1498 wfksb\t%0,%1"
1499 [(set_attr "op_type" "RRE,RXE,VRR,VRR")
1500 (set_attr "cpu_facility" "*,*,vx,vxe")
1501 (set_attr "enabled" "*,<DSF>,<DF>,<SF>")])
1502
1503 ; VX: TFmode in VR: use wfkxb
1504 (define_insn "*cmptf_ccsfps"
1505 [(set (reg CC_REGNUM)
1506 (compare (match_operand:TF 0 "register_operand" "v")
1507 (match_operand:TF 1 "register_operand" "v")))]
1508 "s390_match_ccmode (insn, CCSFPSmode) && TARGET_VXE"
1509 "wfkxb\t%0,%1"
1510 [(set_attr "op_type" "VRR")
1511 (set_attr "cpu_facility" "vxe")])
1512
1513 ; Compare and Branch instructions
1514
1515 ; cij, cgij, crj, cgrj, cfi, cgfi, cr, cgr
1516 ; The following instructions do a complementary access of their second
1517 ; operand (z01 only): crj_c, cgrjc, cr, cgr
1518 (define_insn "*cmp_and_br_signed_<mode>"
1519 [(set (pc)
1520 (if_then_else (match_operator 0 "s390_signed_integer_comparison"
1521 [(match_operand:GPR 1 "register_operand" "d,d")
1522 (match_operand:GPR 2 "nonmemory_operand" "d,C")])
1523 (label_ref (match_operand 3 "" ""))
1524 (pc)))
1525 (clobber (reg:CC CC_REGNUM))]
1526 "TARGET_Z10 && !TARGET_AVOID_CMP_AND_BRANCH"
1527 {
1528 if (get_attr_length (insn) == 6)
1529 return which_alternative ?
1530 "c<g>ij%C0\t%1,%c2,%l3" : "c<g>rj%C0\t%1,%2,%l3";
1531 else
1532 return which_alternative ?
1533 "c<g>fi\t%1,%c2\;jg%C0\t%l3" : "c<g>r\t%1,%2\;jg%C0\t%l3";
1534 }
1535 [(set_attr "op_type" "RIE")
1536 (set_attr "type" "branch")
1537 (set_attr "z10prop" "z10_super_c,z10_super")
1538 (set (attr "length")
1539 (if_then_else (lt (abs (minus (pc) (match_dup 3))) (const_int 60000))
1540 (const_int 6) (const_int 12)))]) ; 8 byte for cr/jg
1541 ; 10 byte for cgr/jg
1542
1543 ; clij, clgij, clrj, clgrj, clfi, clgfi, clr, clgr
1544 ; The following instructions do a complementary access of their second
1545 ; operand (z10 only): clrj, clgrj, clr, clgr
1546 (define_insn "*cmp_and_br_unsigned_<mode>"
1547 [(set (pc)
1548 (if_then_else (match_operator 0 "s390_unsigned_integer_comparison"
1549 [(match_operand:GPR 1 "register_operand" "d,d")
1550 (match_operand:GPR 2 "nonmemory_operand" "d,I")])
1551 (label_ref (match_operand 3 "" ""))
1552 (pc)))
1553 (clobber (reg:CC CC_REGNUM))]
1554 "TARGET_Z10 && !TARGET_AVOID_CMP_AND_BRANCH"
1555 {
1556 if (get_attr_length (insn) == 6)
1557 return which_alternative ?
1558 "cl<g>ij%C0\t%1,%b2,%l3" : "cl<g>rj%C0\t%1,%2,%l3";
1559 else
1560 return which_alternative ?
1561 "cl<g>fi\t%1,%b2\;jg%C0\t%l3" : "cl<g>r\t%1,%2\;jg%C0\t%l3";
1562 }
1563 [(set_attr "op_type" "RIE")
1564 (set_attr "type" "branch")
1565 (set_attr "z10prop" "z10_super_c,z10_super")
1566 (set (attr "length")
1567 (if_then_else (lt (abs (minus (pc) (match_dup 3))) (const_int 60000))
1568 (const_int 6) (const_int 12)))]) ; 8 byte for clr/jg
1569 ; 10 byte for clgr/jg
1570
1571 ; And now the same two patterns as above but with a negated CC mask.
1572
1573 ; cij, cgij, crj, cgrj, cfi, cgfi, cr, cgr
1574 ; The following instructions do a complementary access of their second
1575 ; operand (z01 only): crj_c, cgrjc, cr, cgr
1576 (define_insn "*icmp_and_br_signed_<mode>"
1577 [(set (pc)
1578 (if_then_else (match_operator 0 "s390_signed_integer_comparison"
1579 [(match_operand:GPR 1 "register_operand" "d,d")
1580 (match_operand:GPR 2 "nonmemory_operand" "d,C")])
1581 (pc)
1582 (label_ref (match_operand 3 "" ""))))
1583 (clobber (reg:CC CC_REGNUM))]
1584 "TARGET_Z10 && !TARGET_AVOID_CMP_AND_BRANCH"
1585 {
1586 if (get_attr_length (insn) == 6)
1587 return which_alternative ?
1588 "c<g>ij%D0\t%1,%c2,%l3" : "c<g>rj%D0\t%1,%2,%l3";
1589 else
1590 return which_alternative ?
1591 "c<g>fi\t%1,%c2\;jg%D0\t%l3" : "c<g>r\t%1,%2\;jg%D0\t%l3";
1592 }
1593 [(set_attr "op_type" "RIE")
1594 (set_attr "type" "branch")
1595 (set_attr "z10prop" "z10_super_c,z10_super")
1596 (set (attr "length")
1597 (if_then_else (lt (abs (minus (pc) (match_dup 3))) (const_int 60000))
1598 (const_int 6) (const_int 12)))]) ; 8 byte for cr/jg
1599 ; 10 byte for cgr/jg
1600
1601 ; clij, clgij, clrj, clgrj, clfi, clgfi, clr, clgr
1602 ; The following instructions do a complementary access of their second
1603 ; operand (z10 only): clrj, clgrj, clr, clgr
1604 (define_insn "*icmp_and_br_unsigned_<mode>"
1605 [(set (pc)
1606 (if_then_else (match_operator 0 "s390_unsigned_integer_comparison"
1607 [(match_operand:GPR 1 "register_operand" "d,d")
1608 (match_operand:GPR 2 "nonmemory_operand" "d,I")])
1609 (pc)
1610 (label_ref (match_operand 3 "" ""))))
1611 (clobber (reg:CC CC_REGNUM))]
1612 "TARGET_Z10 && !TARGET_AVOID_CMP_AND_BRANCH"
1613 {
1614 if (get_attr_length (insn) == 6)
1615 return which_alternative ?
1616 "cl<g>ij%D0\t%1,%b2,%l3" : "cl<g>rj%D0\t%1,%2,%l3";
1617 else
1618 return which_alternative ?
1619 "cl<g>fi\t%1,%b2\;jg%D0\t%l3" : "cl<g>r\t%1,%2\;jg%D0\t%l3";
1620 }
1621 [(set_attr "op_type" "RIE")
1622 (set_attr "type" "branch")
1623 (set_attr "z10prop" "z10_super_c,z10_super")
1624 (set (attr "length")
1625 (if_then_else (lt (abs (minus (pc) (match_dup 3))) (const_int 60000))
1626 (const_int 6) (const_int 12)))]) ; 8 byte for clr/jg
1627 ; 10 byte for clgr/jg
1628
1629 ;;
1630 ;;- Move instructions.
1631 ;;
1632
1633 ;
1634 ; movti instruction pattern(s).
1635 ;
1636
1637
1638 ; Separate out the register pair alternative since constraints (P) are
1639 ; not able to deal with const_wide_int's. But predicates do.
1640 (define_insn "*movti_bigconst"
1641 [(set (match_operand:TI 0 "register_operand" "=d")
1642 (match_operand:TI 1 "reload_const_wide_int_operand" ""))]
1643 "TARGET_ZARCH"
1644 "#")
1645
1646 ; FIXME: More constants are possible by enabling jxx, jyy constraints
1647 ; for TImode (use double-int for the calculations)
1648 (define_insn "movti"
1649 [(set (match_operand:TI 0 "nonimmediate_operand" "=d,S,v, v, v,v,d,v,R,d, d, d, d, d,o")
1650 (match_operand:TI 1 "general_operand" " S,d,v,j00,jm1,d,v,R,v,K,NxHD0,Os,NxSD0,dT,d"))]
1651 "TARGET_ZARCH"
1652 "@
1653 lmg\t%0,%N0,%S1
1654 stmg\t%1,%N1,%S0
1655 vlr\t%v0,%v1
1656 vzero\t%v0
1657 vone\t%v0
1658 vlvgp\t%v0,%1,%N1
1659 #
1660 vl\t%v0,%1%A1
1661 vst\t%v1,%0%A0
1662 #
1663 #
1664 #
1665 #
1666 #
1667 #"
1668 [(set_attr "op_type" "RSY,RSY,VRR,VRI,VRI,VRR,*,VRX,VRX,*,*,*,*,*,*")
1669 (set_attr "type" "lm,stm,*,*,*,*,*,*,*,*,*,*,*,*,*")
1670 (set_attr "cpu_facility" "*,*,vx,vx,vx,vx,vx,vx,vx,*,*,*,extimm,*,*")])
1671
1672 (define_split
1673 [(set (match_operand:TI 0 "nonimmediate_operand" "")
1674 (match_operand:TI 1 "general_operand" ""))]
1675 "TARGET_ZARCH && reload_completed
1676 && !s_operand (operands[0], TImode)
1677 && !s_operand (operands[1], TImode)
1678 && s390_split_ok_p (operands[0], operands[1], TImode, 0)"
1679 [(set (match_dup 2) (match_dup 4))
1680 (set (match_dup 3) (match_dup 5))]
1681 {
1682 operands[2] = operand_subword (operands[0], 0, 0, TImode);
1683 operands[3] = operand_subword (operands[0], 1, 0, TImode);
1684 operands[4] = operand_subword (operands[1], 0, 0, TImode);
1685 operands[5] = operand_subword (operands[1], 1, 0, TImode);
1686 })
1687
1688 (define_split
1689 [(set (match_operand:TI 0 "nonimmediate_operand" "")
1690 (match_operand:TI 1 "general_operand" ""))]
1691 "TARGET_ZARCH && reload_completed
1692 && !s_operand (operands[0], TImode)
1693 && !s_operand (operands[1], TImode)
1694 && s390_split_ok_p (operands[0], operands[1], TImode, 1)"
1695 [(set (match_dup 2) (match_dup 4))
1696 (set (match_dup 3) (match_dup 5))]
1697 {
1698 operands[2] = operand_subword (operands[0], 1, 0, TImode);
1699 operands[3] = operand_subword (operands[0], 0, 0, TImode);
1700 operands[4] = operand_subword (operands[1], 1, 0, TImode);
1701 operands[5] = operand_subword (operands[1], 0, 0, TImode);
1702 })
1703
1704 ; Use part of the TImode target reg to perform the address
1705 ; calculation. If the TImode value is supposed to be copied into a VR
1706 ; this splitter is not necessary.
1707 (define_split
1708 [(set (match_operand:TI 0 "register_operand" "")
1709 (match_operand:TI 1 "memory_operand" ""))]
1710 "TARGET_ZARCH && reload_completed
1711 && !VECTOR_REG_P (operands[0])
1712 && !s_operand (operands[1], VOIDmode)"
1713 [(set (match_dup 0) (match_dup 1))]
1714 {
1715 rtx addr = operand_subword (operands[0], 1, 0, TImode);
1716 addr = gen_lowpart (Pmode, addr);
1717 s390_load_address (addr, XEXP (operands[1], 0));
1718 operands[1] = replace_equiv_address (operands[1], addr);
1719 })
1720
1721
1722 ; Split a VR -> GPR TImode move into 2 vector load GR from VR element.
1723 ; For the higher order bits we do simply a DImode move while the
1724 ; second part is done via vec extract. Both will end up as vlgvg.
1725 (define_split
1726 [(set (match_operand:TI 0 "register_operand" "")
1727 (match_operand:TI 1 "register_operand" ""))]
1728 "TARGET_VX && reload_completed
1729 && GENERAL_REG_P (operands[0])
1730 && VECTOR_REG_P (operands[1])"
1731 [(set (match_dup 2) (match_dup 4))
1732 (set (match_dup 3) (unspec:DI [(match_dup 5) (const_int 1)]
1733 UNSPEC_VEC_EXTRACT))]
1734 {
1735 operands[2] = operand_subword (operands[0], 0, 0, TImode);
1736 operands[3] = operand_subword (operands[0], 1, 0, TImode);
1737 operands[4] = gen_rtx_REG (DImode, REGNO (operands[1]));
1738 operands[5] = gen_rtx_REG (V2DImode, REGNO (operands[1]));
1739 })
1740
1741 ;
1742 ; Patterns used for secondary reloads
1743 ;
1744
1745 ; z10 provides move instructions accepting larl memory operands.
1746 ; Unfortunately there is no such variant for QI, TI and FP mode moves.
1747 ; These patterns are also used for unaligned SI and DI accesses.
1748
1749 (define_expand "reload<ALL:mode><P:mode>_tomem_z10"
1750 [(parallel [(match_operand:ALL 0 "memory_operand" "")
1751 (match_operand:ALL 1 "register_operand" "=d")
1752 (match_operand:P 2 "register_operand" "=&a")])]
1753 "TARGET_Z10"
1754 {
1755 s390_reload_symref_address (operands[1], operands[0], operands[2], 1);
1756 DONE;
1757 })
1758
1759 (define_expand "reload<ALL:mode><P:mode>_toreg_z10"
1760 [(parallel [(match_operand:ALL 0 "register_operand" "=d")
1761 (match_operand:ALL 1 "memory_operand" "")
1762 (match_operand:P 2 "register_operand" "=a")])]
1763 "TARGET_Z10"
1764 {
1765 s390_reload_symref_address (operands[0], operands[1], operands[2], 0);
1766 DONE;
1767 })
1768
1769 (define_expand "reload<P:mode>_larl_odd_addend_z10"
1770 [(parallel [(match_operand:P 0 "register_operand" "=d")
1771 (match_operand:P 1 "larl_operand" "")
1772 (match_operand:P 2 "register_operand" "=a")])]
1773 "TARGET_Z10"
1774 {
1775 s390_reload_larl_operand (operands[0], operands[1], operands[2]);
1776 DONE;
1777 })
1778
1779 ; Handles loading a PLUS (load address) expression
1780
1781 (define_expand "reload<mode>_plus"
1782 [(parallel [(match_operand:P 0 "register_operand" "=a")
1783 (match_operand:P 1 "s390_plus_operand" "")
1784 (match_operand:P 2 "register_operand" "=&a")])]
1785 ""
1786 {
1787 s390_expand_plus_operand (operands[0], operands[1], operands[2]);
1788 DONE;
1789 })
1790
1791 ; Not all the indirect memory access instructions support the full
1792 ; format (long disp + index + base). So whenever a move from/to such
1793 ; an address is required and the instruction cannot deal with it we do
1794 ; a load address into a scratch register first and use this as the new
1795 ; base register.
1796 ; This in particular is used for:
1797 ; - non-offsetable memory accesses for multiword moves
1798 ; - full vector reg moves with long displacements
1799
1800 (define_expand "reload<mode>_la_in"
1801 [(parallel [(match_operand 0 "register_operand" "")
1802 (match_operand 1 "" "")
1803 (match_operand:P 2 "register_operand" "=&a")])]
1804 ""
1805 {
1806 gcc_assert (MEM_P (operands[1]));
1807 s390_load_address (operands[2], find_replacement (&XEXP (operands[1], 0)));
1808 operands[1] = replace_equiv_address (operands[1], operands[2]);
1809 emit_move_insn (operands[0], operands[1]);
1810 DONE;
1811 })
1812
1813 (define_expand "reload<mode>_la_out"
1814 [(parallel [(match_operand 0 "" "")
1815 (match_operand 1 "register_operand" "")
1816 (match_operand:P 2 "register_operand" "=&a")])]
1817 ""
1818 {
1819 gcc_assert (MEM_P (operands[0]));
1820 s390_load_address (operands[2], find_replacement (&XEXP (operands[0], 0)));
1821 operands[0] = replace_equiv_address (operands[0], operands[2]);
1822 emit_move_insn (operands[0], operands[1]);
1823 DONE;
1824 })
1825
1826 (define_expand "reload<mode>_PIC_addr"
1827 [(parallel [(match_operand 0 "register_operand" "=d")
1828 (match_operand 1 "larl_operand" "")
1829 (match_operand:P 2 "register_operand" "=a")])]
1830 ""
1831 {
1832 rtx new_rtx = legitimize_pic_address (operands[1], operands[2]);
1833 emit_move_insn (operands[0], new_rtx);
1834 })
1835
1836 ;
1837 ; movdi instruction pattern(s).
1838 ;
1839
1840 (define_expand "movdi"
1841 [(set (match_operand:DI 0 "general_operand" "")
1842 (match_operand:DI 1 "general_operand" ""))]
1843 ""
1844 {
1845 /* Handle symbolic constants. */
1846 if (TARGET_64BIT
1847 && (SYMBOLIC_CONST (operands[1])
1848 || (GET_CODE (operands[1]) == PLUS
1849 && XEXP (operands[1], 0) == pic_offset_table_rtx
1850 && SYMBOLIC_CONST (XEXP (operands[1], 1)))))
1851 emit_symbolic_move (operands);
1852 })
1853
1854 (define_insn "*movdi_64"
1855 [(set (match_operand:DI 0 "nonimmediate_operand"
1856 "=d, d, d, d, d, d, d, d,f,d,d,d,d,d,T,!*f,!*f,!*f,!R,!T,b,Q,d,t,Q,t,v,v,v,d,v,R,d")
1857 (match_operand:DI 1 "general_operand"
1858 " K,N0HD0,N1HD0,N2HD0,N3HD0,Os,N0SD0,N1SD0,d,f,L,b,d,T,d, *f, R, T,*f,*f,d,K,t,d,t,Q,K,v,d,v,R,v,ZL"))]
1859 "TARGET_ZARCH"
1860 "@
1861 lghi\t%0,%h1
1862 llihh\t%0,%i1
1863 llihl\t%0,%i1
1864 llilh\t%0,%i1
1865 llill\t%0,%i1
1866 lgfi\t%0,%1
1867 llihf\t%0,%k1
1868 llilf\t%0,%k1
1869 ldgr\t%0,%1
1870 lgdr\t%0,%1
1871 lay\t%0,%a1
1872 lgrl\t%0,%1
1873 lgr\t%0,%1
1874 lg\t%0,%1
1875 stg\t%1,%0
1876 ldr\t%0,%1
1877 ld\t%0,%1
1878 ldy\t%0,%1
1879 std\t%1,%0
1880 stdy\t%1,%0
1881 stgrl\t%1,%0
1882 mvghi\t%0,%1
1883 #
1884 #
1885 stam\t%1,%N1,%S0
1886 lam\t%0,%N0,%S1
1887 vleig\t%v0,%h1,0
1888 vlr\t%v0,%v1
1889 vlvgg\t%v0,%1,0
1890 vlgvg\t%0,%v1,0
1891 vleg\t%v0,%1,0
1892 vsteg\t%v1,%0,0
1893 larl\t%0,%1"
1894 [(set_attr "op_type" "RI,RI,RI,RI,RI,RIL,RIL,RIL,RRE,RRE,RXY,RIL,RRE,RXY,
1895 RXY,RR,RX,RXY,RX,RXY,RIL,SIL,*,*,RS,RS,VRI,VRR,VRS,VRS,
1896 VRX,VRX,RIL")
1897 (set_attr "type" "*,*,*,*,*,*,*,*,floaddf,floaddf,la,larl,lr,load,store,
1898 floaddf,floaddf,floaddf,fstoredf,fstoredf,larl,*,*,*,*,
1899 *,*,*,*,*,*,*,larl")
1900 (set_attr "cpu_facility" "*,*,*,*,*,extimm,extimm,extimm,dfp,dfp,longdisp,
1901 z10,*,*,*,*,*,longdisp,*,longdisp,
1902 z10,z10,*,*,*,*,vx,vx,vx,vx,vx,vx,*")
1903 (set_attr "z10prop" "z10_fwd_A1,
1904 z10_fwd_E1,
1905 z10_fwd_E1,
1906 z10_fwd_E1,
1907 z10_fwd_E1,
1908 z10_fwd_A1,
1909 z10_fwd_E1,
1910 z10_fwd_E1,
1911 *,
1912 *,
1913 z10_fwd_A1,
1914 z10_fwd_A3,
1915 z10_fr_E1,
1916 z10_fwd_A3,
1917 z10_rec,
1918 *,
1919 *,
1920 *,
1921 *,
1922 *,
1923 z10_rec,
1924 z10_super,
1925 *,
1926 *,
1927 *,
1928 *,*,*,*,*,*,*,
1929 z10_super_A1")
1930 (set_attr "relative_long" "*,*,*,*,*,*,*,*,*,*,
1931 *,yes,*,*,*,*,*,*,*,*,
1932 yes,*,*,*,*,*,*,*,*,*,
1933 *,*,yes")
1934 ])
1935
1936 ; Splitters for loading TLS pointer from UNSPEC_GET_TP.
1937 ; UNSPEC_GET_TP is used instead of %a0:P, since the latter is a hard register,
1938 ; and those are not handled by Partial Redundancy Elimination (gcse.c), which
1939 ; results in generation of redundant thread pointer loads.
1940
1941 (define_insn_and_split "*get_tp_31"
1942 [(set (match_operand:SI 0 "register_operand" "=r")
1943 (unspec:SI [(match_operand:SI 1 "register_operand" "t")]
1944 UNSPEC_GET_TP))]
1945 ""
1946 "#"
1947 "&& reload_completed"
1948 [(set (match_dup 0) (match_dup 1))])
1949
1950 (define_insn_and_split "*get_tp_64"
1951 [(set (match_operand:DI 0 "register_operand" "=r")
1952 (unspec:DI [(match_operand:DI 1 "register_operand" "t")]
1953 UNSPEC_GET_TP))]
1954 "TARGET_ZARCH"
1955 "#"
1956 "&& reload_completed"
1957 [(set (match_dup 2) (match_dup 3))
1958 (set (match_dup 0) (ashift:DI (match_dup 0) (const_int 32)))
1959 (set (strict_low_part (match_dup 2)) (match_dup 4))]
1960 "operands[2] = gen_lowpart (SImode, operands[0]);
1961 s390_split_access_reg (operands[1], &operands[4], &operands[3]);")
1962
1963 ; Splitters for storing TLS pointer to %a0:DI.
1964
1965 (define_split
1966 [(set (match_operand:DI 0 "register_operand" "")
1967 (match_operand:DI 1 "register_operand" ""))]
1968 "TARGET_ZARCH && ACCESS_REG_P (operands[0]) && reload_completed
1969 && dead_or_set_p (insn, operands[1])"
1970 [(set (match_dup 3) (match_dup 2))
1971 (set (match_dup 1) (lshiftrt:DI (match_dup 1) (const_int 32)))
1972 (set (match_dup 4) (match_dup 2))]
1973 "operands[2] = gen_lowpart (SImode, operands[1]);
1974 s390_split_access_reg (operands[0], &operands[3], &operands[4]);")
1975
1976 (define_split
1977 [(set (match_operand:DI 0 "register_operand" "")
1978 (match_operand:DI 1 "register_operand" ""))]
1979 "TARGET_ZARCH && ACCESS_REG_P (operands[0]) && reload_completed
1980 && !dead_or_set_p (insn, operands[1])"
1981 [(set (match_dup 3) (match_dup 2))
1982 (set (match_dup 1) (rotate:DI (match_dup 1) (const_int 32)))
1983 (set (match_dup 4) (match_dup 2))
1984 (set (match_dup 1) (rotate:DI (match_dup 1) (const_int 32)))]
1985 "operands[2] = gen_lowpart (SImode, operands[1]);
1986 s390_split_access_reg (operands[0], &operands[3], &operands[4]);")
1987
1988 (define_insn "*movdi_31"
1989 [(set (match_operand:DI 0 "nonimmediate_operand"
1990 "=d,d,Q,S,d ,o,!*f,!*f,!*f,!R,!T,d")
1991 (match_operand:DI 1 "general_operand"
1992 " Q,S,d,d,dPT,d, *f, R, T,*f,*f,b"))]
1993 "!TARGET_ZARCH"
1994 "@
1995 lm\t%0,%N0,%S1
1996 lmy\t%0,%N0,%S1
1997 stm\t%1,%N1,%S0
1998 stmy\t%1,%N1,%S0
1999 #
2000 #
2001 ldr\t%0,%1
2002 ld\t%0,%1
2003 ldy\t%0,%1
2004 std\t%1,%0
2005 stdy\t%1,%0
2006 #"
2007 [(set_attr "op_type" "RS,RSY,RS,RSY,*,*,RR,RX,RXY,RX,RXY,*")
2008 (set_attr "type" "lm,lm,stm,stm,*,*,floaddf,floaddf,floaddf,fstoredf,fstoredf,*")
2009 (set_attr "cpu_facility" "*,longdisp,*,longdisp,*,*,*,*,longdisp,*,longdisp,z10")])
2010
2011 ; For a load from a symbol ref we can use one of the target registers
2012 ; together with larl to load the address.
2013 (define_split
2014 [(set (match_operand:DI 0 "register_operand" "")
2015 (match_operand:DI 1 "memory_operand" ""))]
2016 "!TARGET_ZARCH && reload_completed && TARGET_Z10
2017 && larl_operand (XEXP (operands[1], 0), SImode)"
2018 [(set (match_dup 2) (match_dup 3))
2019 (set (match_dup 0) (match_dup 1))]
2020 {
2021 operands[2] = operand_subword (operands[0], 1, 0, DImode);
2022 operands[3] = XEXP (operands[1], 0);
2023 operands[1] = replace_equiv_address (operands[1], operands[2]);
2024 })
2025
2026 (define_split
2027 [(set (match_operand:DI 0 "nonimmediate_operand" "")
2028 (match_operand:DI 1 "general_operand" ""))]
2029 "!TARGET_ZARCH && reload_completed
2030 && !s_operand (operands[0], DImode)
2031 && !s_operand (operands[1], DImode)
2032 && s390_split_ok_p (operands[0], operands[1], DImode, 0)"
2033 [(set (match_dup 2) (match_dup 4))
2034 (set (match_dup 3) (match_dup 5))]
2035 {
2036 operands[2] = operand_subword (operands[0], 0, 0, DImode);
2037 operands[3] = operand_subword (operands[0], 1, 0, DImode);
2038 operands[4] = operand_subword (operands[1], 0, 0, DImode);
2039 operands[5] = operand_subword (operands[1], 1, 0, DImode);
2040 })
2041
2042 (define_split
2043 [(set (match_operand:DI 0 "nonimmediate_operand" "")
2044 (match_operand:DI 1 "general_operand" ""))]
2045 "!TARGET_ZARCH && reload_completed
2046 && !s_operand (operands[0], DImode)
2047 && !s_operand (operands[1], DImode)
2048 && s390_split_ok_p (operands[0], operands[1], DImode, 1)"
2049 [(set (match_dup 2) (match_dup 4))
2050 (set (match_dup 3) (match_dup 5))]
2051 {
2052 operands[2] = operand_subword (operands[0], 1, 0, DImode);
2053 operands[3] = operand_subword (operands[0], 0, 0, DImode);
2054 operands[4] = operand_subword (operands[1], 1, 0, DImode);
2055 operands[5] = operand_subword (operands[1], 0, 0, DImode);
2056 })
2057
2058 (define_split
2059 [(set (match_operand:DI 0 "register_operand" "")
2060 (match_operand:DI 1 "memory_operand" ""))]
2061 "!TARGET_ZARCH && reload_completed
2062 && !FP_REG_P (operands[0])
2063 && !s_operand (operands[1], VOIDmode)"
2064 [(set (match_dup 0) (match_dup 1))]
2065 {
2066 rtx addr = operand_subword (operands[0], 1, 0, DImode);
2067 s390_load_address (addr, XEXP (operands[1], 0));
2068 operands[1] = replace_equiv_address (operands[1], addr);
2069 })
2070
2071 (define_peephole2
2072 [(set (match_operand:DI 0 "register_operand" "")
2073 (mem:DI (match_operand 1 "address_operand" "")))]
2074 "TARGET_ZARCH
2075 && !FP_REG_P (operands[0])
2076 && GET_CODE (operands[1]) == SYMBOL_REF
2077 && CONSTANT_POOL_ADDRESS_P (operands[1])
2078 && get_pool_mode (operands[1]) == DImode
2079 && legitimate_reload_constant_p (get_pool_constant (operands[1]))"
2080 [(set (match_dup 0) (match_dup 2))]
2081 "operands[2] = get_pool_constant (operands[1]);")
2082
2083 (define_insn "*la_64"
2084 [(set (match_operand:DI 0 "register_operand" "=d,d")
2085 (match_operand:QI 1 "address_operand" "ZR,ZT"))]
2086 "TARGET_64BIT"
2087 "@
2088 la\t%0,%a1
2089 lay\t%0,%a1"
2090 [(set_attr "op_type" "RX,RXY")
2091 (set_attr "type" "la")
2092 (set_attr "cpu_facility" "*,longdisp")
2093 (set_attr "z10prop" "z10_fwd_A1,z10_fwd_A1")])
2094
2095 (define_peephole2
2096 [(parallel
2097 [(set (match_operand:DI 0 "register_operand" "")
2098 (match_operand:QI 1 "address_operand" ""))
2099 (clobber (reg:CC CC_REGNUM))])]
2100 "TARGET_64BIT
2101 && preferred_la_operand_p (operands[1], const0_rtx)"
2102 [(set (match_dup 0) (match_dup 1))]
2103 "")
2104
2105 (define_peephole2
2106 [(set (match_operand:DI 0 "register_operand" "")
2107 (match_operand:DI 1 "register_operand" ""))
2108 (parallel
2109 [(set (match_dup 0)
2110 (plus:DI (match_dup 0)
2111 (match_operand:DI 2 "nonmemory_operand" "")))
2112 (clobber (reg:CC CC_REGNUM))])]
2113 "TARGET_64BIT
2114 && !reg_overlap_mentioned_p (operands[0], operands[2])
2115 && preferred_la_operand_p (operands[1], operands[2])"
2116 [(set (match_dup 0) (plus:DI (match_dup 1) (match_dup 2)))]
2117 "")
2118
2119 ; Split loading of 64-bit constants into GPRs into llihf + oilf -
2120 ; counterintuitively, using oilf is faster than iilf. oilf clobbers
2121 ; cc, so cc must be dead.
2122 (define_peephole2
2123 [(set (match_operand:DI 0 "register_operand" "")
2124 (match_operand:DI 1 "memory_operand" ""))]
2125 "TARGET_64BIT
2126 && TARGET_EXTIMM
2127 && GENERAL_REG_P (operands[0])
2128 && s390_const_int_pool_entry_p (operands[1], nullptr)
2129 && peep2_reg_dead_p (1, gen_rtx_REG (CCmode, CC_REGNUM))"
2130 [(set (match_dup 0) (match_dup 2))
2131 (parallel
2132 [(set (match_dup 0) (ior:DI (match_dup 0) (match_dup 3)))
2133 (clobber (reg:CC CC_REGNUM))])]
2134 {
2135 HOST_WIDE_INT val;
2136 bool ok = s390_const_int_pool_entry_p (operands[1], &val);
2137 gcc_assert (ok);
2138 operands[2] = GEN_INT (val & 0xFFFFFFFF00000000ULL);
2139 operands[3] = GEN_INT (val & 0x00000000FFFFFFFFULL);
2140 })
2141
2142 ;
2143 ; movsi instruction pattern(s).
2144 ;
2145
2146 (define_expand "movsi"
2147 [(set (match_operand:SI 0 "general_operand" "")
2148 (match_operand:SI 1 "general_operand" ""))]
2149 ""
2150 {
2151 /* Handle symbolic constants. */
2152 if (!TARGET_64BIT
2153 && (SYMBOLIC_CONST (operands[1])
2154 || (GET_CODE (operands[1]) == PLUS
2155 && XEXP (operands[1], 0) == pic_offset_table_rtx
2156 && SYMBOLIC_CONST (XEXP(operands[1], 1)))))
2157 emit_symbolic_move (operands);
2158 })
2159
2160 (define_insn "*movsi_larl"
2161 [(set (match_operand:SI 0 "register_operand" "=d")
2162 (match_operand:SI 1 "larl_operand" "X"))]
2163 "!TARGET_64BIT
2164 && !FP_REG_P (operands[0])"
2165 "larl\t%0,%1"
2166 [(set_attr "op_type" "RIL")
2167 (set_attr "type" "larl")
2168 (set_attr "z10prop" "z10_fwd_A1")
2169 (set_attr "relative_long" "yes")])
2170
2171 (define_insn "*movsi_zarch"
2172 [(set (match_operand:SI 0 "nonimmediate_operand"
2173 "=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")
2174 (match_operand:SI 1 "general_operand"
2175 " 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"))]
2176 "TARGET_ZARCH"
2177 "@
2178 lhi\t%0,%h1
2179 llilh\t%0,%i1
2180 llill\t%0,%i1
2181 iilf\t%0,%o1
2182 lay\t%0,%a1
2183 lrl\t%0,%1
2184 lr\t%0,%1
2185 l\t%0,%1
2186 ly\t%0,%1
2187 st\t%1,%0
2188 sty\t%1,%0
2189 ldr\t%0,%1
2190 ler\t%0,%1
2191 lde\t%0,%1
2192 le\t%0,%1
2193 ley\t%0,%1
2194 ste\t%1,%0
2195 stey\t%1,%0
2196 ear\t%0,%1
2197 sar\t%0,%1
2198 stam\t%1,%1,%S0
2199 strl\t%1,%0
2200 mvhi\t%0,%1
2201 lam\t%0,%0,%S1
2202 vleif\t%v0,%h1,0
2203 vlr\t%v0,%v1
2204 vlvgf\t%v0,%1,0
2205 vlgvf\t%0,%v1,0
2206 vlef\t%v0,%1,0
2207 vstef\t%v1,%0,0"
2208 [(set_attr "op_type" "RI,RI,RI,RIL,RXY,RIL,RR,RX,RXY,RX,RXY,
2209 RR,RR,RXE,RX,RXY,RX,RXY,RRE,RRE,RS,RIL,SIL,RS,VRI,VRR,VRS,VRS,VRX,VRX")
2210 (set_attr "type" "*,
2211 *,
2212 *,
2213 *,
2214 la,
2215 larl,
2216 lr,
2217 load,
2218 load,
2219 store,
2220 store,
2221 floadsf,
2222 floadsf,
2223 floadsf,
2224 floadsf,
2225 floadsf,
2226 fstoresf,
2227 fstoresf,
2228 *,
2229 *,
2230 *,
2231 larl,
2232 *,
2233 *,*,*,*,*,*,*")
2234 (set_attr "cpu_facility" "*,*,*,extimm,longdisp,z10,*,*,longdisp,*,longdisp,
2235 vx,*,vx,*,longdisp,*,longdisp,*,*,*,z10,z10,*,vx,vx,vx,vx,vx,vx")
2236 (set_attr "z10prop" "z10_fwd_A1,
2237 z10_fwd_E1,
2238 z10_fwd_E1,
2239 z10_fwd_A1,
2240 z10_fwd_A1,
2241 z10_fwd_A3,
2242 z10_fr_E1,
2243 z10_fwd_A3,
2244 z10_fwd_A3,
2245 z10_rec,
2246 z10_rec,
2247 *,
2248 *,
2249 *,
2250 *,
2251 *,
2252 *,
2253 *,
2254 z10_super_E1,
2255 z10_super,
2256 *,
2257 z10_rec,
2258 z10_super,
2259 *,*,*,*,*,*,*")
2260 (set_attr "relative_long" "*,*,*,*,*,yes,*,*,*,*,
2261 *,*,*,*,*,*,*,*,*,*,
2262 *,yes,*,*,*,*,*,*,*,*")])
2263
2264 (define_insn "*movsi_esa"
2265 [(set (match_operand:SI 0 "nonimmediate_operand" "=d,d,d,R,!*f,!*f,!*f,!*f,!R,d,t,Q,t")
2266 (match_operand:SI 1 "general_operand" "K,d,R,d, *f, *f, R, R,*f,t,d,t,Q"))]
2267 "!TARGET_ZARCH"
2268 "@
2269 lhi\t%0,%h1
2270 lr\t%0,%1
2271 l\t%0,%1
2272 st\t%1,%0
2273 ldr\t%0,%1
2274 ler\t%0,%1
2275 lde\t%0,%1
2276 le\t%0,%1
2277 ste\t%1,%0
2278 ear\t%0,%1
2279 sar\t%0,%1
2280 stam\t%1,%1,%S0
2281 lam\t%0,%0,%S1"
2282 [(set_attr "op_type" "RI,RR,RX,RX,RR,RR,RXE,RX,RX,RRE,RRE,RS,RS")
2283 (set_attr "type" "*,lr,load,store,floadsf,floadsf,floadsf,floadsf,fstoresf,*,*,*,*")
2284 (set_attr "z10prop" "z10_fwd_A1,z10_fr_E1,z10_fwd_A3,z10_rec,*,*,*,*,*,z10_super_E1,
2285 z10_super,*,*")
2286 (set_attr "cpu_facility" "*,*,*,*,vx,*,vx,*,*,*,*,*,*")
2287 ])
2288
2289 (define_peephole2
2290 [(set (match_operand:SI 0 "register_operand" "")
2291 (mem:SI (match_operand 1 "address_operand" "")))]
2292 "!FP_REG_P (operands[0])
2293 && GET_CODE (operands[1]) == SYMBOL_REF
2294 && CONSTANT_POOL_ADDRESS_P (operands[1])
2295 && get_pool_mode (operands[1]) == SImode
2296 && legitimate_reload_constant_p (get_pool_constant (operands[1]))"
2297 [(set (match_dup 0) (match_dup 2))]
2298 "operands[2] = get_pool_constant (operands[1]);")
2299
2300 (define_insn "*la_31"
2301 [(set (match_operand:SI 0 "register_operand" "=d,d")
2302 (match_operand:QI 1 "address_operand" "ZR,ZT"))]
2303 "!TARGET_64BIT && legitimate_la_operand_p (operands[1])"
2304 "@
2305 la\t%0,%a1
2306 lay\t%0,%a1"
2307 [(set_attr "op_type" "RX,RXY")
2308 (set_attr "type" "la")
2309 (set_attr "cpu_facility" "*,longdisp")
2310 (set_attr "z10prop" "z10_fwd_A1,z10_fwd_A1")])
2311
2312 (define_peephole2
2313 [(parallel
2314 [(set (match_operand:SI 0 "register_operand" "")
2315 (match_operand:QI 1 "address_operand" ""))
2316 (clobber (reg:CC CC_REGNUM))])]
2317 "!TARGET_64BIT
2318 && preferred_la_operand_p (operands[1], const0_rtx)"
2319 [(set (match_dup 0) (match_dup 1))]
2320 "")
2321
2322 (define_peephole2
2323 [(set (match_operand:SI 0 "register_operand" "")
2324 (match_operand:SI 1 "register_operand" ""))
2325 (parallel
2326 [(set (match_dup 0)
2327 (plus:SI (match_dup 0)
2328 (match_operand:SI 2 "nonmemory_operand" "")))
2329 (clobber (reg:CC CC_REGNUM))])]
2330 "!TARGET_64BIT
2331 && !reg_overlap_mentioned_p (operands[0], operands[2])
2332 && preferred_la_operand_p (operands[1], operands[2])"
2333 [(set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))]
2334 "")
2335
2336 (define_insn "*la_31_and"
2337 [(set (match_operand:SI 0 "register_operand" "=d,d")
2338 (and:SI (match_operand:QI 1 "address_operand" "ZR,ZT")
2339 (const_int 2147483647)))]
2340 "!TARGET_64BIT"
2341 "@
2342 la\t%0,%a1
2343 lay\t%0,%a1"
2344 [(set_attr "op_type" "RX,RXY")
2345 (set_attr "type" "la")
2346 (set_attr "cpu_facility" "*,longdisp")
2347 (set_attr "z10prop" "z10_fwd_A1,z10_fwd_A1")])
2348
2349 (define_insn_and_split "*la_31_and_cc"
2350 [(set (match_operand:SI 0 "register_operand" "=d")
2351 (and:SI (match_operand:QI 1 "address_operand" "p")
2352 (const_int 2147483647)))
2353 (clobber (reg:CC CC_REGNUM))]
2354 "!TARGET_64BIT"
2355 "#"
2356 "&& reload_completed"
2357 [(set (match_dup 0)
2358 (and:SI (match_dup 1) (const_int 2147483647)))]
2359 ""
2360 [(set_attr "op_type" "RX")
2361 (set_attr "type" "la")])
2362
2363 (define_insn "force_la_31"
2364 [(set (match_operand:SI 0 "register_operand" "=d,d")
2365 (match_operand:QI 1 "address_operand" "ZR,ZT"))
2366 (use (const_int 0))]
2367 "!TARGET_64BIT"
2368 "@
2369 la\t%0,%a1
2370 lay\t%0,%a1"
2371 [(set_attr "op_type" "RX")
2372 (set_attr "type" "la")
2373 (set_attr "cpu_facility" "*,longdisp")
2374 (set_attr "z10prop" "z10_fwd_A1,z10_fwd_A1")])
2375
2376 ;
2377 ; movhi instruction pattern(s).
2378 ;
2379
2380 (define_expand "movhi"
2381 [(set (match_operand:HI 0 "nonimmediate_operand" "")
2382 (match_operand:HI 1 "general_operand" ""))]
2383 ""
2384 {
2385 /* Make it explicit that loading a register from memory
2386 always sign-extends (at least) to SImode. */
2387 if (optimize && can_create_pseudo_p ()
2388 && register_operand (operands[0], VOIDmode)
2389 && GET_CODE (operands[1]) == MEM)
2390 {
2391 rtx tmp = gen_reg_rtx (SImode);
2392 rtx ext = gen_rtx_SIGN_EXTEND (SImode, operands[1]);
2393 emit_insn (gen_rtx_SET (tmp, ext));
2394 operands[1] = gen_lowpart (HImode, tmp);
2395 }
2396 })
2397
2398 (define_insn "*movhi"
2399 [(set (match_operand:HI 0 "nonimmediate_operand" "=d,d,d,d,d,R,T,b,Q,v,v,v,d,v,R")
2400 (match_operand:HI 1 "general_operand" " d,n,R,T,b,d,d,d,K,K,v,d,v,R,v"))]
2401 ""
2402 "@
2403 lr\t%0,%1
2404 lhi\t%0,%h1
2405 lh\t%0,%1
2406 lhy\t%0,%1
2407 lhrl\t%0,%1
2408 sth\t%1,%0
2409 sthy\t%1,%0
2410 sthrl\t%1,%0
2411 mvhhi\t%0,%1
2412 vleih\t%v0,%h1,0
2413 vlr\t%v0,%v1
2414 vlvgh\t%v0,%1,0
2415 vlgvh\t%0,%v1,0
2416 vleh\t%v0,%1,0
2417 vsteh\t%v1,%0,0"
2418 [(set_attr "op_type" "RR,RI,RX,RXY,RIL,RX,RXY,RIL,SIL,VRI,VRR,VRS,VRS,VRX,VRX")
2419 (set_attr "type" "lr,*,*,*,larl,store,store,store,*,*,*,*,*,*,*")
2420 (set_attr "cpu_facility" "*,*,*,longdisp,z10,*,longdisp,z10,z10,vx,vx,vx,vx,vx,vx")
2421 (set_attr "z10prop" "z10_fr_E1,
2422 z10_fwd_A1,
2423 z10_super_E1,
2424 z10_super_E1,
2425 z10_super_E1,
2426 z10_rec,
2427 z10_rec,
2428 z10_rec,
2429 z10_super,*,*,*,*,*,*")
2430 (set_attr "relative_long" "*,*,*,*,yes,*,*,yes,*,*,*,*,*,*,*")])
2431
2432 (define_peephole2
2433 [(set (match_operand:HI 0 "register_operand" "")
2434 (mem:HI (match_operand 1 "address_operand" "")))]
2435 "GET_CODE (operands[1]) == SYMBOL_REF
2436 && CONSTANT_POOL_ADDRESS_P (operands[1])
2437 && get_pool_mode (operands[1]) == HImode
2438 && GET_CODE (get_pool_constant (operands[1])) == CONST_INT"
2439 [(set (match_dup 0) (match_dup 2))]
2440 "operands[2] = get_pool_constant (operands[1]);")
2441
2442 ;
2443 ; movqi instruction pattern(s).
2444 ;
2445
2446 (define_expand "movqi"
2447 [(set (match_operand:QI 0 "nonimmediate_operand" "")
2448 (match_operand:QI 1 "general_operand" ""))]
2449 ""
2450 {
2451 /* On z/Architecture, zero-extending from memory to register
2452 is just as fast as a QImode load. */
2453 if (TARGET_ZARCH && optimize && can_create_pseudo_p ()
2454 && register_operand (operands[0], VOIDmode)
2455 && GET_CODE (operands[1]) == MEM)
2456 {
2457 rtx tmp = gen_reg_rtx (DImode);
2458 rtx ext = gen_rtx_ZERO_EXTEND (DImode, operands[1]);
2459 emit_insn (gen_rtx_SET (tmp, ext));
2460 operands[1] = gen_lowpart (QImode, tmp);
2461 }
2462 })
2463
2464 (define_insn "*movqi"
2465 [(set (match_operand:QI 0 "nonimmediate_operand" "=d,d,d,d,R,T,Q,S,?Q,v,v,v,d,v,R")
2466 (match_operand:QI 1 "general_operand" " d,n,R,T,d,d,n,n,?Q,K,v,d,v,R,v"))]
2467 ""
2468 "@
2469 lr\t%0,%1
2470 lhi\t%0,%b1
2471 ic\t%0,%1
2472 icy\t%0,%1
2473 stc\t%1,%0
2474 stcy\t%1,%0
2475 mvi\t%S0,%b1
2476 mviy\t%S0,%b1
2477 #
2478 vleib\t%v0,%b1,0
2479 vlr\t%v0,%v1
2480 vlvgb\t%v0,%1,0
2481 vlgvb\t%0,%v1,0
2482 vleb\t%v0,%1,0
2483 vsteb\t%v1,%0,0"
2484 [(set_attr "op_type" "RR,RI,RX,RXY,RX,RXY,SI,SIY,SS,VRI,VRR,VRS,VRS,VRX,VRX")
2485 (set_attr "type" "lr,*,*,*,store,store,store,store,*,*,*,*,*,*,*")
2486 (set_attr "cpu_facility" "*,*,*,longdisp,*,longdisp,*,longdisp,*,vx,vx,vx,vx,vx,vx")
2487 (set_attr "z10prop" "z10_fr_E1,
2488 z10_fwd_A1,
2489 z10_super_E1,
2490 z10_super_E1,
2491 z10_rec,
2492 z10_rec,
2493 z10_super,
2494 z10_super,
2495 *,*,*,*,*,*,*")])
2496
2497 (define_peephole2
2498 [(set (match_operand:QI 0 "nonimmediate_operand" "")
2499 (mem:QI (match_operand 1 "address_operand" "")))]
2500 "GET_CODE (operands[1]) == SYMBOL_REF
2501 && CONSTANT_POOL_ADDRESS_P (operands[1])
2502 && get_pool_mode (operands[1]) == QImode
2503 && GET_CODE (get_pool_constant (operands[1])) == CONST_INT"
2504 [(set (match_dup 0) (match_dup 2))]
2505 "operands[2] = get_pool_constant (operands[1]);")
2506
2507 ;
2508 ; movstrictqi instruction pattern(s).
2509 ;
2510
2511 (define_insn "movstrictqi"
2512 [(set (strict_low_part (match_operand:QI 0 "register_operand" "+d,d"))
2513 (match_operand:QI 1 "memory_operand" "R,T"))]
2514 ""
2515 "@
2516 ic\t%0,%1
2517 icy\t%0,%1"
2518 [(set_attr "op_type" "RX,RXY")
2519 (set_attr "cpu_facility" "*,longdisp")
2520 (set_attr "z10prop" "z10_super_E1,z10_super_E1")])
2521
2522 ;
2523 ; movstricthi instruction pattern(s).
2524 ;
2525
2526 (define_insn "movstricthi"
2527 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+d,d"))
2528 (match_operand:HI 1 "memory_operand" "Q,S"))
2529 (clobber (reg:CC CC_REGNUM))]
2530 ""
2531 "@
2532 icm\t%0,3,%S1
2533 icmy\t%0,3,%S1"
2534 [(set_attr "op_type" "RS,RSY")
2535 (set_attr "cpu_facility" "*,longdisp")
2536 (set_attr "z10prop" "z10_super_E1,z10_super_E1")])
2537
2538 ;
2539 ; movstrictsi instruction pattern(s).
2540 ;
2541
2542 (define_insn "movstrictsi"
2543 [(set (strict_low_part (match_operand:SI 0 "register_operand" "+d,d,d,d"))
2544 (match_operand:SI 1 "general_operand" "d,R,T,t"))]
2545 "TARGET_ZARCH"
2546 "@
2547 lr\t%0,%1
2548 l\t%0,%1
2549 ly\t%0,%1
2550 ear\t%0,%1"
2551 [(set_attr "op_type" "RR,RX,RXY,RRE")
2552 (set_attr "type" "lr,load,load,*")
2553 (set_attr "cpu_facility" "*,*,longdisp,*")
2554 (set_attr "z10prop" "z10_fr_E1,z10_fwd_A3,z10_fwd_A3,z10_super_E1")])
2555
2556 ;
2557 ; mov(tf|td) instruction pattern(s).
2558 ;
2559
2560 (define_expand "mov<mode><tf_fpr>"
2561 [(set (match_operand:TD_TF 0 "nonimmediate_operand" "")
2562 (match_operand:TD_TF 1 "general_operand" ""))]
2563 ""
2564 "")
2565
2566 (define_insn "*mov<mode>_64"
2567 [(set (match_operand:TD_TF 0 "nonimmediate_operand" "=f,f,f,o,d,S, d,o")
2568 (match_operand:TD_TF 1 "general_operand" " G,f,o,f,S,d,dT,d"))]
2569 "TARGET_ZARCH"
2570 "@
2571 lzxr\t%0
2572 lxr\t%0,%1
2573 #
2574 #
2575 lmg\t%0,%N0,%S1
2576 stmg\t%1,%N1,%S0
2577 #
2578 #"
2579 [(set_attr "op_type" "RRE,RRE,*,*,RSY,RSY,*,*")
2580 (set_attr "type" "fsimptf,fsimptf,*,*,lm,stm,*,*")
2581 (set_attr "cpu_facility" "z196,*,*,*,*,*,*,*")])
2582
2583 (define_insn "*mov<mode>_31"
2584 [(set (match_operand:TD_TF 0 "nonimmediate_operand" "=f,f,f,o")
2585 (match_operand:TD_TF 1 "general_operand" " G,f,o,f"))]
2586 "!TARGET_ZARCH"
2587 "@
2588 lzxr\t%0
2589 lxr\t%0,%1
2590 #
2591 #"
2592 [(set_attr "op_type" "RRE,RRE,*,*")
2593 (set_attr "type" "fsimptf,fsimptf,*,*")
2594 (set_attr "cpu_facility" "z196,*,*,*")])
2595
2596 ; TFmode in GPRs splitters
2597
2598 (define_split
2599 [(set (match_operand:TD_TF 0 "nonimmediate_operand" "")
2600 (match_operand:TD_TF 1 "general_operand" ""))]
2601 "TARGET_ZARCH && reload_completed
2602 && !s_operand (operands[0], <MODE>mode)
2603 && !s_operand (operands[1], <MODE>mode)
2604 && s390_split_ok_p (operands[0], operands[1], <MODE>mode, 0)"
2605 [(set (match_dup 2) (match_dup 4))
2606 (set (match_dup 3) (match_dup 5))]
2607 {
2608 operands[2] = operand_subword (operands[0], 0, 0, <MODE>mode);
2609 operands[3] = operand_subword (operands[0], 1, 0, <MODE>mode);
2610 operands[4] = operand_subword (operands[1], 0, 0, <MODE>mode);
2611 operands[5] = operand_subword (operands[1], 1, 0, <MODE>mode);
2612 })
2613
2614 (define_split
2615 [(set (match_operand:TD_TF 0 "nonimmediate_operand" "")
2616 (match_operand:TD_TF 1 "general_operand" ""))]
2617 "TARGET_ZARCH && reload_completed
2618 && !s_operand (operands[0], <MODE>mode)
2619 && !s_operand (operands[1], <MODE>mode)
2620 && s390_split_ok_p (operands[0], operands[1], <MODE>mode, 1)"
2621 [(set (match_dup 2) (match_dup 4))
2622 (set (match_dup 3) (match_dup 5))]
2623 {
2624 operands[2] = operand_subword (operands[0], 1, 0, <MODE>mode);
2625 operands[3] = operand_subword (operands[0], 0, 0, <MODE>mode);
2626 operands[4] = operand_subword (operands[1], 1, 0, <MODE>mode);
2627 operands[5] = operand_subword (operands[1], 0, 0, <MODE>mode);
2628 })
2629
2630 (define_split
2631 [(set (match_operand:TD_TF 0 "register_operand" "")
2632 (match_operand:TD_TF 1 "memory_operand" ""))]
2633 "TARGET_ZARCH && reload_completed
2634 && GENERAL_REG_P (operands[0])
2635 && !s_operand (operands[1], VOIDmode)"
2636 [(set (match_dup 0) (match_dup 1))]
2637 {
2638 rtx addr = operand_subword (operands[0], 1, 0, <MODE>mode);
2639 addr = gen_lowpart (Pmode, addr);
2640 s390_load_address (addr, XEXP (operands[1], 0));
2641 operands[1] = replace_equiv_address (operands[1], addr);
2642 })
2643
2644 ; TFmode in BFPs splitters
2645
2646 (define_split
2647 [(set (match_operand:TD_TF 0 "register_operand" "")
2648 (match_operand:TD_TF 1 "memory_operand" ""))]
2649 "reload_completed && offsettable_memref_p (operands[1])
2650 && FP_REG_P (operands[0])"
2651 [(set (match_dup 2) (match_dup 4))
2652 (set (match_dup 3) (match_dup 5))]
2653 {
2654 operands[2] = simplify_gen_subreg (<HALF_TMODE>mode, operands[0],
2655 <MODE>mode, 0);
2656 operands[3] = simplify_gen_subreg (<HALF_TMODE>mode, operands[0],
2657 <MODE>mode, 8);
2658 operands[4] = adjust_address_nv (operands[1], <HALF_TMODE>mode, 0);
2659 operands[5] = adjust_address_nv (operands[1], <HALF_TMODE>mode, 8);
2660 })
2661
2662 (define_split
2663 [(set (match_operand:TD_TF 0 "memory_operand" "")
2664 (match_operand:TD_TF 1 "register_operand" ""))]
2665 "reload_completed && offsettable_memref_p (operands[0])
2666 && FP_REG_P (operands[1])"
2667 [(set (match_dup 2) (match_dup 4))
2668 (set (match_dup 3) (match_dup 5))]
2669 {
2670 operands[2] = adjust_address_nv (operands[0], <HALF_TMODE>mode, 0);
2671 operands[3] = adjust_address_nv (operands[0], <HALF_TMODE>mode, 8);
2672 operands[4] = simplify_gen_subreg (<HALF_TMODE>mode, operands[1],
2673 <MODE>mode, 0);
2674 operands[5] = simplify_gen_subreg (<HALF_TMODE>mode, operands[1],
2675 <MODE>mode, 8);
2676 })
2677
2678 ;
2679 ; mov(df|dd) instruction pattern(s).
2680 ;
2681
2682 (define_expand "mov<mode>"
2683 [(set (match_operand:DD_DF 0 "nonimmediate_operand" "")
2684 (match_operand:DD_DF 1 "general_operand" ""))]
2685 ""
2686 "")
2687
2688 (define_insn "*mov<mode>_64dfp"
2689 [(set (match_operand:DD_DF 0 "nonimmediate_operand"
2690 "=f,f,f,d,f,f,R,T,d,d,d,d,b,T,v,v,v,d,v,R")
2691 (match_operand:DD_DF 1 "general_operand"
2692 " G,f,d,f,R,T,f,f,G,d,b,T,d,d,v,G,d,v,R,v"))]
2693 "TARGET_DFP"
2694 "@
2695 lzdr\t%0
2696 ldr\t%0,%1
2697 ldgr\t%0,%1
2698 lgdr\t%0,%1
2699 ld\t%0,%1
2700 ldy\t%0,%1
2701 std\t%1,%0
2702 stdy\t%1,%0
2703 lghi\t%0,0
2704 lgr\t%0,%1
2705 lgrl\t%0,%1
2706 lg\t%0,%1
2707 stgrl\t%1,%0
2708 stg\t%1,%0
2709 vlr\t%v0,%v1
2710 vleig\t%v0,0,0
2711 vlvgg\t%v0,%1,0
2712 vlgvg\t%0,%v1,0
2713 vleg\t%0,%1,0
2714 vsteg\t%1,%0,0"
2715 [(set_attr "op_type" "RRE,RR,RRE,RRE,RX,RXY,RX,RXY,RI,RRE,RIL,RXY,RIL,RXY,VRR,VRI,VRS,VRS,VRX,VRX")
2716 (set_attr "type" "fsimpdf,floaddf,floaddf,floaddf,floaddf,floaddf,
2717 fstoredf,fstoredf,*,lr,load,load,store,store,*,*,*,*,load,store")
2718 (set_attr "z10prop" "*,*,*,*,*,*,*,*,z10_fwd_A1,z10_fr_E1,z10_fwd_A3,z10_fwd_A3,z10_rec,z10_rec,*,*,*,*,*,*")
2719 (set_attr "cpu_facility" "z196,*,*,*,*,longdisp,*,longdisp,*,*,z10,*,z10,*,vx,vx,vx,vx,vx,vx")
2720 (set_attr "relative_long" "*,*,*,*,*,*,*,*,*,*,yes,*,yes,*,*,*,*,*,*,*")])
2721
2722 (define_insn "*mov<mode>_64"
2723 [(set (match_operand:DD_DF 0 "nonimmediate_operand" "=f,f,f,f,R,T,d,d,d,d,b,T")
2724 (match_operand:DD_DF 1 "general_operand" " G,f,R,T,f,f,G,d,b,T,d,d"))]
2725 "TARGET_ZARCH"
2726 "@
2727 lzdr\t%0
2728 ldr\t%0,%1
2729 ld\t%0,%1
2730 ldy\t%0,%1
2731 std\t%1,%0
2732 stdy\t%1,%0
2733 lghi\t%0,0
2734 lgr\t%0,%1
2735 lgrl\t%0,%1
2736 lg\t%0,%1
2737 stgrl\t%1,%0
2738 stg\t%1,%0"
2739 [(set_attr "op_type" "RRE,RR,RX,RXY,RX,RXY,RI,RRE,RIL,RXY,RIL,RXY")
2740 (set_attr "type" "fsimpdf,fload<mode>,fload<mode>,fload<mode>,
2741 fstore<mode>,fstore<mode>,*,lr,load,load,store,store")
2742 (set_attr "z10prop" "*,*,*,*,*,*,z10_fwd_A1,z10_fr_E1,z10_fwd_A3,z10_fwd_A3,z10_rec,z10_rec")
2743 (set_attr "cpu_facility" "z196,*,*,longdisp,*,longdisp,*,*,z10,*,z10,*")
2744 (set_attr "relative_long" "*,*,*,*,*,*,*,*,yes,*,*,*")])
2745
2746 (define_insn "*mov<mode>_31"
2747 [(set (match_operand:DD_DF 0 "nonimmediate_operand"
2748 "=f,f,f,f,R,T,d,d,Q,S, d,o")
2749 (match_operand:DD_DF 1 "general_operand"
2750 " G,f,R,T,f,f,Q,S,d,d,dPT,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 lm\t%0,%N0,%S1
2760 lmy\t%0,%N0,%S1
2761 stm\t%1,%N1,%S0
2762 stmy\t%1,%N1,%S0
2763 #
2764 #"
2765 [(set_attr "op_type" "RRE,RR,RX,RXY,RX,RXY,RS,RSY,RS,RSY,*,*")
2766 (set_attr "type" "fsimpdf,fload<mode>,fload<mode>,fload<mode>,
2767 fstore<mode>,fstore<mode>,lm,lm,stm,stm,*,*")
2768 (set_attr "cpu_facility" "z196,*,*,longdisp,*,longdisp,*,longdisp,*,longdisp,*,*")])
2769
2770 (define_split
2771 [(set (match_operand:DD_DF 0 "nonimmediate_operand" "")
2772 (match_operand:DD_DF 1 "general_operand" ""))]
2773 "!TARGET_ZARCH && reload_completed
2774 && !s_operand (operands[0], <MODE>mode)
2775 && !s_operand (operands[1], <MODE>mode)
2776 && s390_split_ok_p (operands[0], operands[1], <MODE>mode, 0)"
2777 [(set (match_dup 2) (match_dup 4))
2778 (set (match_dup 3) (match_dup 5))]
2779 {
2780 operands[2] = operand_subword (operands[0], 0, 0, <MODE>mode);
2781 operands[3] = operand_subword (operands[0], 1, 0, <MODE>mode);
2782 operands[4] = operand_subword (operands[1], 0, 0, <MODE>mode);
2783 operands[5] = operand_subword (operands[1], 1, 0, <MODE>mode);
2784 })
2785
2786 (define_split
2787 [(set (match_operand:DD_DF 0 "nonimmediate_operand" "")
2788 (match_operand:DD_DF 1 "general_operand" ""))]
2789 "!TARGET_ZARCH && reload_completed
2790 && !s_operand (operands[0], <MODE>mode)
2791 && !s_operand (operands[1], <MODE>mode)
2792 && s390_split_ok_p (operands[0], operands[1], <MODE>mode, 1)"
2793 [(set (match_dup 2) (match_dup 4))
2794 (set (match_dup 3) (match_dup 5))]
2795 {
2796 operands[2] = operand_subword (operands[0], 1, 0, <MODE>mode);
2797 operands[3] = operand_subword (operands[0], 0, 0, <MODE>mode);
2798 operands[4] = operand_subword (operands[1], 1, 0, <MODE>mode);
2799 operands[5] = operand_subword (operands[1], 0, 0, <MODE>mode);
2800 })
2801
2802 (define_split
2803 [(set (match_operand:DD_DF 0 "register_operand" "")
2804 (match_operand:DD_DF 1 "memory_operand" ""))]
2805 "!TARGET_ZARCH && reload_completed
2806 && !FP_REG_P (operands[0])
2807 && !s_operand (operands[1], VOIDmode)"
2808 [(set (match_dup 0) (match_dup 1))]
2809 {
2810 rtx addr = operand_subword (operands[0], 1, 0, <MODE>mode);
2811 s390_load_address (addr, XEXP (operands[1], 0));
2812 operands[1] = replace_equiv_address (operands[1], addr);
2813 })
2814
2815 ;
2816 ; mov(sf|sd) instruction pattern(s).
2817 ;
2818
2819 (define_insn "mov<mode>"
2820 [(set (match_operand:SD_SF 0 "nonimmediate_operand"
2821 "=f,f,f,f,f,f,R,T,d,d,d,d,d,b,R,T,v,v,v,d,v,R")
2822 (match_operand:SD_SF 1 "general_operand"
2823 " G,f,f,R,R,T,f,f,G,d,b,R,T,d,d,d,v,G,d,v,R,v"))]
2824 ""
2825 "@
2826 lzer\t%0
2827 ldr\t%0,%1
2828 ler\t%0,%1
2829 lde\t%0,%1
2830 le\t%0,%1
2831 ley\t%0,%1
2832 ste\t%1,%0
2833 stey\t%1,%0
2834 lhi\t%0,0
2835 lr\t%0,%1
2836 lrl\t%0,%1
2837 l\t%0,%1
2838 ly\t%0,%1
2839 strl\t%1,%0
2840 st\t%1,%0
2841 sty\t%1,%0
2842 vlr\t%v0,%v1
2843 vleif\t%v0,0,0
2844 vlvgf\t%v0,%1,0
2845 vlgvf\t%0,%v1,0
2846 vlef\t%0,%1,0
2847 vstef\t%1,%0,0"
2848 [(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")
2849 (set_attr "type" "fsimpsf,fsimpsf,fload<mode>,fload<mode>,fload<mode>,fload<mode>,
2850 fstore<mode>,fstore<mode>,*,lr,load,load,load,store,store,store,*,*,*,*,load,store")
2851 (set_attr "z10prop" "*,*,*,*,*,*,*,*,z10_fwd_A1,z10_fr_E1,z10_fr_E1,z10_fwd_A3,z10_fwd_A3,z10_rec,z10_rec,z10_rec,*,*,*,*,*,*")
2852 (set_attr "cpu_facility" "z196,vx,*,vx,*,longdisp,*,longdisp,*,*,z10,*,longdisp,z10,*,longdisp,vx,vx,vx,vx,vx,vx")
2853 (set_attr "relative_long" "*,*,*,*,*,*,*,*,*,*,yes,*,*,yes,*,*,*,*,*,*,*,*")])
2854
2855 ;
2856 ; movcc instruction pattern
2857 ;
2858
2859 (define_insn "movcc"
2860 [(set (match_operand:CC 0 "nonimmediate_operand" "=d,c,d,d,d,R,T")
2861 (match_operand:CC 1 "nonimmediate_operand" " d,d,c,R,T,d,d"))]
2862 ""
2863 "@
2864 lr\t%0,%1
2865 tmh\t%1,12288
2866 ipm\t%0
2867 l\t%0,%1
2868 ly\t%0,%1
2869 st\t%1,%0
2870 sty\t%1,%0"
2871 [(set_attr "op_type" "RR,RI,RRE,RX,RXY,RX,RXY")
2872 (set_attr "type" "lr,*,*,load,load,store,store")
2873 (set_attr "cpu_facility" "*,*,*,*,longdisp,*,longdisp")
2874 (set_attr "z10prop" "z10_fr_E1,z10_super,*,z10_fwd_A3,z10_fwd_A3,z10_rec,z10_rec")
2875 (set_attr "z196prop" "*,*,z196_ends,*,*,*,*")])
2876
2877 ;
2878 ; Block move (MVC) patterns.
2879 ;
2880
2881 (define_insn "*mvc"
2882 [(set (match_operand:BLK 0 "memory_operand" "=Q")
2883 (match_operand:BLK 1 "memory_operand" "Q"))
2884 (use (match_operand 2 "const_int_operand" "n"))]
2885 "INTVAL (operands[2]) >= 1 && INTVAL (operands[2]) <= 256"
2886 "mvc\t%O0(%2,%R0),%S1"
2887 [(set_attr "op_type" "SS")])
2888
2889 ; This splitter converts a QI to QI mode copy into a BLK mode copy in
2890 ; order to have it implemented with mvc.
2891
2892 (define_split
2893 [(set (match_operand:QI 0 "memory_operand" "")
2894 (match_operand:QI 1 "memory_operand" ""))]
2895 "reload_completed"
2896 [(parallel
2897 [(set (match_dup 0) (match_dup 1))
2898 (use (const_int 1))])]
2899 {
2900 operands[0] = adjust_address (operands[0], BLKmode, 0);
2901 operands[1] = adjust_address (operands[1], BLKmode, 0);
2902 })
2903
2904
2905 (define_peephole2
2906 [(parallel
2907 [(set (match_operand:BLK 0 "memory_operand" "")
2908 (match_operand:BLK 1 "memory_operand" ""))
2909 (use (match_operand 2 "const_int_operand" ""))])
2910 (parallel
2911 [(set (match_operand:BLK 3 "memory_operand" "")
2912 (match_operand:BLK 4 "memory_operand" ""))
2913 (use (match_operand 5 "const_int_operand" ""))])]
2914 "((INTVAL (operands[2]) > 16 && INTVAL (operands[5]) > 16)
2915 || (INTVAL (operands[2]) + INTVAL (operands[5]) <= 16))
2916 && s390_offset_p (operands[0], operands[3], operands[2])
2917 && s390_offset_p (operands[1], operands[4], operands[2])
2918 && !s390_overlap_p (operands[0], operands[1],
2919 INTVAL (operands[2]) + INTVAL (operands[5]))
2920 && INTVAL (operands[2]) + INTVAL (operands[5]) <= 256"
2921 [(parallel
2922 [(set (match_dup 6) (match_dup 7))
2923 (use (match_dup 8))])]
2924 "operands[6] = gen_rtx_MEM (BLKmode, XEXP (operands[0], 0));
2925 operands[7] = gen_rtx_MEM (BLKmode, XEXP (operands[1], 0));
2926 operands[8] = GEN_INT (INTVAL (operands[2]) + INTVAL (operands[5]));")
2927
2928 (define_peephole2
2929 [(parallel
2930 [(set (match_operand:BLK 0 "plus16_Q_operand" "")
2931 (match_operand:BLK 1 "plus16_Q_operand" ""))
2932 (use (match_operand 2 "const_int_operand" ""))])]
2933 "INTVAL (operands[2]) > 16 && INTVAL (operands[2]) <= 32"
2934 [(parallel
2935 [(set (match_dup 0) (match_dup 1))
2936 (use (const_int 16))])
2937 (parallel
2938 [(set (match_dup 3) (match_dup 4))
2939 (use (match_dup 5))])]
2940 "operands[3] = change_address (operands[0], VOIDmode,
2941 plus_constant (Pmode, XEXP (operands[0], 0), 16));
2942 operands[4] = change_address (operands[1], VOIDmode,
2943 plus_constant (Pmode, XEXP (operands[1], 0), 16));
2944 operands[5] = GEN_INT (INTVAL (operands[2]) - 16);")
2945
2946
2947 ;
2948 ; load_multiple pattern(s).
2949 ;
2950 ; ??? Due to reload problems with replacing registers inside match_parallel
2951 ; we currently support load_multiple/store_multiple only after reload.
2952 ;
2953
2954 (define_expand "load_multiple"
2955 [(match_par_dup 3 [(set (match_operand 0 "" "")
2956 (match_operand 1 "" ""))
2957 (use (match_operand 2 "" ""))])]
2958 "reload_completed"
2959 {
2960 machine_mode mode;
2961 int regno;
2962 int count;
2963 rtx from;
2964 int i, off;
2965
2966 /* Support only loading a constant number of fixed-point registers from
2967 memory and only bother with this if more than two */
2968 if (GET_CODE (operands[2]) != CONST_INT
2969 || INTVAL (operands[2]) < 2
2970 || INTVAL (operands[2]) > 16
2971 || GET_CODE (operands[1]) != MEM
2972 || GET_CODE (operands[0]) != REG
2973 || REGNO (operands[0]) >= 16)
2974 FAIL;
2975
2976 count = INTVAL (operands[2]);
2977 regno = REGNO (operands[0]);
2978 mode = GET_MODE (operands[0]);
2979 if (mode != SImode && (!TARGET_ZARCH || mode != DImode))
2980 FAIL;
2981
2982 operands[3] = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (count));
2983 if (!can_create_pseudo_p ())
2984 {
2985 if (GET_CODE (XEXP (operands[1], 0)) == REG)
2986 {
2987 from = XEXP (operands[1], 0);
2988 off = 0;
2989 }
2990 else if (GET_CODE (XEXP (operands[1], 0)) == PLUS
2991 && GET_CODE (XEXP (XEXP (operands[1], 0), 0)) == REG
2992 && GET_CODE (XEXP (XEXP (operands[1], 0), 1)) == CONST_INT)
2993 {
2994 from = XEXP (XEXP (operands[1], 0), 0);
2995 off = INTVAL (XEXP (XEXP (operands[1], 0), 1));
2996 }
2997 else
2998 FAIL;
2999 }
3000 else
3001 {
3002 from = force_reg (Pmode, XEXP (operands[1], 0));
3003 off = 0;
3004 }
3005
3006 for (i = 0; i < count; i++)
3007 XVECEXP (operands[3], 0, i)
3008 = gen_rtx_SET (gen_rtx_REG (mode, regno + i),
3009 change_address (operands[1], mode,
3010 plus_constant (Pmode, from,
3011 off + i * GET_MODE_SIZE (mode))));
3012 })
3013
3014 (define_insn "*load_multiple_di"
3015 [(match_parallel 0 "load_multiple_operation"
3016 [(set (match_operand:DI 1 "register_operand" "=r")
3017 (match_operand:DI 2 "s_operand" "S"))])]
3018 "reload_completed && TARGET_ZARCH"
3019 {
3020 int words = XVECLEN (operands[0], 0);
3021 operands[0] = gen_rtx_REG (DImode, REGNO (operands[1]) + words - 1);
3022 return "lmg\t%1,%0,%S2";
3023 }
3024 [(set_attr "op_type" "RSY")
3025 (set_attr "type" "lm")])
3026
3027 (define_insn "*load_multiple_si"
3028 [(match_parallel 0 "load_multiple_operation"
3029 [(set (match_operand:SI 1 "register_operand" "=r,r")
3030 (match_operand:SI 2 "s_operand" "Q,S"))])]
3031 "reload_completed"
3032 {
3033 int words = XVECLEN (operands[0], 0);
3034 operands[0] = gen_rtx_REG (SImode, REGNO (operands[1]) + words - 1);
3035 return which_alternative == 0 ? "lm\t%1,%0,%S2" : "lmy\t%1,%0,%S2";
3036 }
3037 [(set_attr "op_type" "RS,RSY")
3038 (set_attr "cpu_facility" "*,longdisp")
3039 (set_attr "type" "lm")])
3040
3041 ;
3042 ; store multiple pattern(s).
3043 ;
3044
3045 (define_expand "store_multiple"
3046 [(match_par_dup 3 [(set (match_operand 0 "" "")
3047 (match_operand 1 "" ""))
3048 (use (match_operand 2 "" ""))])]
3049 "reload_completed"
3050 {
3051 machine_mode mode;
3052 int regno;
3053 int count;
3054 rtx to;
3055 int i, off;
3056
3057 /* Support only storing a constant number of fixed-point registers to
3058 memory and only bother with this if more than two. */
3059 if (GET_CODE (operands[2]) != CONST_INT
3060 || INTVAL (operands[2]) < 2
3061 || INTVAL (operands[2]) > 16
3062 || GET_CODE (operands[0]) != MEM
3063 || GET_CODE (operands[1]) != REG
3064 || REGNO (operands[1]) >= 16)
3065 FAIL;
3066
3067 count = INTVAL (operands[2]);
3068 regno = REGNO (operands[1]);
3069 mode = GET_MODE (operands[1]);
3070 if (mode != SImode && (!TARGET_ZARCH || mode != DImode))
3071 FAIL;
3072
3073 operands[3] = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (count));
3074
3075 if (!can_create_pseudo_p ())
3076 {
3077 if (GET_CODE (XEXP (operands[0], 0)) == REG)
3078 {
3079 to = XEXP (operands[0], 0);
3080 off = 0;
3081 }
3082 else if (GET_CODE (XEXP (operands[0], 0)) == PLUS
3083 && GET_CODE (XEXP (XEXP (operands[0], 0), 0)) == REG
3084 && GET_CODE (XEXP (XEXP (operands[0], 0), 1)) == CONST_INT)
3085 {
3086 to = XEXP (XEXP (operands[0], 0), 0);
3087 off = INTVAL (XEXP (XEXP (operands[0], 0), 1));
3088 }
3089 else
3090 FAIL;
3091 }
3092 else
3093 {
3094 to = force_reg (Pmode, XEXP (operands[0], 0));
3095 off = 0;
3096 }
3097
3098 for (i = 0; i < count; i++)
3099 XVECEXP (operands[3], 0, i)
3100 = gen_rtx_SET (change_address (operands[0], mode,
3101 plus_constant (Pmode, to,
3102 off + i * GET_MODE_SIZE (mode))),
3103 gen_rtx_REG (mode, regno + i));
3104 })
3105
3106 (define_insn "*store_multiple_di"
3107 [(match_parallel 0 "store_multiple_operation"
3108 [(set (match_operand:DI 1 "s_operand" "=S")
3109 (match_operand:DI 2 "register_operand" "r"))])]
3110 "reload_completed && TARGET_ZARCH"
3111 {
3112 int words = XVECLEN (operands[0], 0);
3113 operands[0] = gen_rtx_REG (DImode, REGNO (operands[2]) + words - 1);
3114 return "stmg\t%2,%0,%S1";
3115 }
3116 [(set_attr "op_type" "RSY")
3117 (set_attr "type" "stm")])
3118
3119
3120 (define_insn "*store_multiple_si"
3121 [(match_parallel 0 "store_multiple_operation"
3122 [(set (match_operand:SI 1 "s_operand" "=Q,S")
3123 (match_operand:SI 2 "register_operand" "r,r"))])]
3124 "reload_completed"
3125 {
3126 int words = XVECLEN (operands[0], 0);
3127 operands[0] = gen_rtx_REG (SImode, REGNO (operands[2]) + words - 1);
3128 return which_alternative == 0 ? "stm\t%2,%0,%S1" : "stmy\t%2,%0,%S1";
3129 }
3130 [(set_attr "op_type" "RS,RSY")
3131 (set_attr "cpu_facility" "*,longdisp")
3132 (set_attr "type" "stm")])
3133
3134 ;;
3135 ;; String instructions.
3136 ;;
3137
3138 (define_insn "*execute_rl"
3139 [(match_parallel 0 "execute_operation"
3140 [(unspec [(match_operand 1 "register_operand" "a")
3141 (match_operand 2 "" "")
3142 (match_operand:SI 3 "larl_operand" "X")] UNSPEC_EXECUTE)])]
3143 "TARGET_Z10 && GET_MODE_CLASS (GET_MODE (operands[1])) == MODE_INT
3144 && GET_MODE_SIZE (GET_MODE (operands[1])) <= UNITS_PER_WORD"
3145 "exrl\t%1,%3"
3146 [(set_attr "op_type" "RIL")
3147 (set_attr "type" "cs")
3148 (set_attr "relative_long" "yes")])
3149
3150 (define_insn "*execute"
3151 [(match_parallel 0 "execute_operation"
3152 [(unspec [(match_operand 1 "register_operand" "a")
3153 (match_operand:BLK 2 "memory_operand" "R")
3154 (match_operand 3 "" "")] UNSPEC_EXECUTE)])]
3155 "GET_MODE_CLASS (GET_MODE (operands[1])) == MODE_INT
3156 && GET_MODE_SIZE (GET_MODE (operands[1])) <= UNITS_PER_WORD"
3157 "ex\t%1,%2"
3158 [(set_attr "op_type" "RX")
3159 (set_attr "type" "cs")])
3160
3161
3162 ;
3163 ; strlenM instruction pattern(s).
3164 ;
3165
3166 (define_expand "strlen<mode>"
3167 [(match_operand:P 0 "register_operand" "") ; result
3168 (match_operand:BLK 1 "memory_operand" "") ; input string
3169 (match_operand:SI 2 "immediate_operand" "") ; search character
3170 (match_operand:SI 3 "immediate_operand" "")] ; known alignment
3171 ""
3172 {
3173 if (!TARGET_VX || operands[2] != const0_rtx)
3174 emit_insn (gen_strlen_srst<mode> (operands[0], operands[1],
3175 operands[2], operands[3]));
3176 else
3177 s390_expand_vec_strlen (operands[0], operands[1], operands[3]);
3178
3179 DONE;
3180 })
3181
3182 (define_expand "strlen_srst<mode>"
3183 [(set (reg:SI 0) (match_operand:SI 2 "immediate_operand" ""))
3184 (parallel
3185 [(set (match_dup 4)
3186 (unspec:P [(const_int 0)
3187 (match_operand:BLK 1 "memory_operand" "")
3188 (reg:SI 0)
3189 (match_operand 3 "immediate_operand" "")] UNSPEC_SRST))
3190 (clobber (scratch:P))
3191 (clobber (reg:CC CC_REGNUM))])
3192 (parallel
3193 [(set (match_operand:P 0 "register_operand" "")
3194 (minus:P (match_dup 4) (match_dup 5)))
3195 (clobber (reg:CC CC_REGNUM))])]
3196 ""
3197 {
3198 operands[4] = gen_reg_rtx (Pmode);
3199 operands[5] = gen_reg_rtx (Pmode);
3200 emit_move_insn (operands[5], force_operand (XEXP (operands[1], 0), NULL_RTX));
3201 operands[1] = replace_equiv_address (operands[1], operands[5]);
3202 })
3203
3204 (define_insn "*strlen<mode>"
3205 [(set (match_operand:P 0 "register_operand" "=a")
3206 (unspec:P [(match_operand:P 2 "general_operand" "0")
3207 (mem:BLK (match_operand:P 3 "register_operand" "1"))
3208 (reg:SI 0)
3209 (match_operand 4 "immediate_operand" "")] UNSPEC_SRST))
3210 (clobber (match_scratch:P 1 "=a"))
3211 (clobber (reg:CC CC_REGNUM))]
3212 ""
3213 "srst\t%0,%1\;jo\t.-4"
3214 [(set_attr "length" "8")
3215 (set_attr "type" "vs")])
3216
3217 ;
3218 ; cmpstrM instruction pattern(s).
3219 ;
3220
3221 (define_expand "cmpstrsi"
3222 [(set (reg:SI 0) (const_int 0))
3223 (parallel
3224 [(clobber (match_operand 3 "" ""))
3225 (clobber (match_dup 4))
3226 (set (reg:CCU CC_REGNUM)
3227 (compare:CCU (match_operand:BLK 1 "memory_operand" "")
3228 (match_operand:BLK 2 "memory_operand" "")))
3229 (use (reg:SI 0))])
3230 (parallel
3231 [(set (match_operand:SI 0 "register_operand" "=d")
3232 (unspec:SI [(reg:CCU CC_REGNUM)] UNSPEC_STRCMPCC_TO_INT))
3233 (clobber (reg:CC CC_REGNUM))])]
3234 ""
3235 {
3236 /* As the result of CMPINT is inverted compared to what we need,
3237 we have to swap the operands. */
3238 rtx op1 = operands[2];
3239 rtx op2 = operands[1];
3240 rtx addr1 = gen_reg_rtx (Pmode);
3241 rtx addr2 = gen_reg_rtx (Pmode);
3242
3243 emit_move_insn (addr1, force_operand (XEXP (op1, 0), NULL_RTX));
3244 emit_move_insn (addr2, force_operand (XEXP (op2, 0), NULL_RTX));
3245 operands[1] = replace_equiv_address_nv (op1, addr1);
3246 operands[2] = replace_equiv_address_nv (op2, addr2);
3247 operands[3] = addr1;
3248 operands[4] = addr2;
3249 })
3250
3251 (define_insn "*cmpstr<mode>"
3252 [(clobber (match_operand:P 0 "register_operand" "=d"))
3253 (clobber (match_operand:P 1 "register_operand" "=d"))
3254 (set (reg:CCU CC_REGNUM)
3255 (compare:CCU (mem:BLK (match_operand:P 2 "register_operand" "0"))
3256 (mem:BLK (match_operand:P 3 "register_operand" "1"))))
3257 (use (reg:SI 0))]
3258 ""
3259 "clst\t%0,%1\;jo\t.-4"
3260 [(set_attr "length" "8")
3261 (set_attr "type" "vs")])
3262
3263 ;
3264 ; movstr instruction pattern.
3265 ;
3266
3267 (define_expand "movstr"
3268 [(match_operand 0 "register_operand" "")
3269 (match_operand 1 "memory_operand" "")
3270 (match_operand 2 "memory_operand" "")]
3271 ""
3272 {
3273 if (TARGET_64BIT)
3274 emit_insn (gen_movstrdi (operands[0], operands[1], operands[2]));
3275 else
3276 emit_insn (gen_movstrsi (operands[0], operands[1], operands[2]));
3277 DONE;
3278 })
3279
3280 (define_expand "movstr<P:mode>"
3281 [(set (reg:SI 0) (const_int 0))
3282 (parallel
3283 [(clobber (match_dup 3))
3284 (set (match_operand:BLK 1 "memory_operand" "")
3285 (match_operand:BLK 2 "memory_operand" ""))
3286 (set (match_operand:P 0 "register_operand" "")
3287 (unspec:P [(match_dup 1)
3288 (match_dup 2)
3289 (reg:SI 0)] UNSPEC_MVST))
3290 (clobber (reg:CC CC_REGNUM))])]
3291 ""
3292 {
3293 rtx addr1, addr2;
3294
3295 if (TARGET_VX && optimize_function_for_speed_p (cfun))
3296 {
3297 s390_expand_vec_movstr (operands[0], operands[1], operands[2]);
3298 DONE;
3299 }
3300
3301 addr1 = gen_reg_rtx (Pmode);
3302 addr2 = gen_reg_rtx (Pmode);
3303
3304 emit_move_insn (addr1, force_operand (XEXP (operands[1], 0), NULL_RTX));
3305 emit_move_insn (addr2, force_operand (XEXP (operands[2], 0), NULL_RTX));
3306 operands[1] = replace_equiv_address_nv (operands[1], addr1);
3307 operands[2] = replace_equiv_address_nv (operands[2], addr2);
3308 operands[3] = addr2;
3309 })
3310
3311 (define_insn "*movstr"
3312 [(clobber (match_operand:P 2 "register_operand" "=d"))
3313 (set (mem:BLK (match_operand:P 1 "register_operand" "0"))
3314 (mem:BLK (match_operand:P 3 "register_operand" "2")))
3315 (set (match_operand:P 0 "register_operand" "=d")
3316 (unspec:P [(mem:BLK (match_dup 1))
3317 (mem:BLK (match_dup 3))
3318 (reg:SI 0)] UNSPEC_MVST))
3319 (clobber (reg:CC CC_REGNUM))]
3320 ""
3321 "mvst\t%1,%2\;jo\t.-4"
3322 [(set_attr "length" "8")
3323 (set_attr "type" "vs")])
3324
3325
3326 ;
3327 ; cpymemM instruction pattern(s).
3328 ;
3329
3330 (define_expand "cpymem<mode>"
3331 [(set (match_operand:BLK 0 "memory_operand" "") ; destination
3332 (match_operand:BLK 1 "memory_operand" "")) ; source
3333 (use (match_operand:GPR 2 "general_operand" "")) ; count
3334 (match_operand 3 "" "")]
3335 ""
3336 {
3337 if (s390_expand_cpymem (operands[0], operands[1], operands[2]))
3338 DONE;
3339 else
3340 FAIL;
3341 })
3342
3343 ; Move a block that is up to 256 bytes in length.
3344 ; The block length is taken as (operands[2] % 256) + 1.
3345
3346 (define_expand "cpymem_short"
3347 [(parallel
3348 [(set (match_operand:BLK 0 "memory_operand" "")
3349 (match_operand:BLK 1 "memory_operand" ""))
3350 (use (match_operand 2 "nonmemory_operand" ""))
3351 (use (const:BLK (unspec:BLK [(const_int 0)] UNSPEC_INSN)))
3352 (clobber (match_dup 3))])]
3353 ""
3354 "operands[3] = gen_rtx_SCRATCH (Pmode);")
3355
3356 (define_insn "*cpymem_short"
3357 [(set (match_operand:BLK 0 "memory_operand" "=Q,Q,Q,Q")
3358 (match_operand:BLK 1 "memory_operand" "Q,Q,Q,Q"))
3359 (use (match_operand 2 "nonmemory_operand" "n,a,a,a"))
3360 (use (match_operand 3 "immediate_operand" "X,R,X,X"))
3361 (clobber (match_scratch:P 4 "=X,X,X,&a"))]
3362 "(GET_MODE (operands[2]) == Pmode || GET_MODE (operands[2]) == VOIDmode)"
3363 "#"
3364 [(set_attr "type" "cs")
3365 (set_attr "cpu_facility" "*,*,z10,cpu_zarch")])
3366
3367 (define_split
3368 [(set (match_operand:BLK 0 "memory_operand" "")
3369 (match_operand:BLK 1 "memory_operand" ""))
3370 (use (match_operand 2 "const_int_operand" ""))
3371 (use (match_operand 3 "immediate_operand" ""))
3372 (clobber (scratch))]
3373 "reload_completed"
3374 [(parallel
3375 [(set (match_dup 0) (match_dup 1))
3376 (use (match_dup 2))])]
3377 "operands[2] = GEN_INT ((INTVAL (operands[2]) & 0xff) + 1);")
3378
3379 (define_split
3380 [(set (match_operand:BLK 0 "memory_operand" "")
3381 (match_operand:BLK 1 "memory_operand" ""))
3382 (use (match_operand 2 "register_operand" ""))
3383 (use (match_operand 3 "memory_operand" ""))
3384 (clobber (scratch))]
3385 "reload_completed"
3386 [(parallel
3387 [(unspec [(match_dup 2) (match_dup 3)
3388 (const_int 0)] UNSPEC_EXECUTE)
3389 (set (match_dup 0) (match_dup 1))
3390 (use (const_int 1))])]
3391 "")
3392
3393 (define_split
3394 [(set (match_operand:BLK 0 "memory_operand" "")
3395 (match_operand:BLK 1 "memory_operand" ""))
3396 (use (match_operand 2 "register_operand" ""))
3397 (use (const:BLK (unspec:BLK [(const_int 0)] UNSPEC_INSN)))
3398 (clobber (scratch))]
3399 "TARGET_Z10 && reload_completed"
3400 [(parallel
3401 [(unspec [(match_dup 2) (const_int 0)
3402 (label_ref (match_dup 3))] UNSPEC_EXECUTE)
3403 (set (match_dup 0) (match_dup 1))
3404 (use (const_int 1))])]
3405 "operands[3] = gen_label_rtx ();")
3406
3407 (define_split
3408 [(set (match_operand:BLK 0 "memory_operand" "")
3409 (match_operand:BLK 1 "memory_operand" ""))
3410 (use (match_operand 2 "register_operand" ""))
3411 (use (const:BLK (unspec:BLK [(const_int 0)] UNSPEC_INSN)))
3412 (clobber (match_operand 3 "register_operand" ""))]
3413 "reload_completed"
3414 [(set (match_dup 3) (label_ref (match_dup 4)))
3415 (parallel
3416 [(unspec [(match_dup 2) (mem:BLK (match_dup 3))
3417 (label_ref (match_dup 4))] UNSPEC_EXECUTE)
3418 (set (match_dup 0) (match_dup 1))
3419 (use (const_int 1))])]
3420 "operands[4] = gen_label_rtx ();")
3421
3422 ; Move a block of arbitrary length.
3423
3424 (define_expand "cpymem_long"
3425 [(parallel
3426 [(clobber (match_dup 2))
3427 (clobber (match_dup 3))
3428 (set (match_operand:BLK 0 "memory_operand" "")
3429 (match_operand:BLK 1 "memory_operand" ""))
3430 (use (match_operand 2 "general_operand" ""))
3431 (use (match_dup 3))
3432 (clobber (reg:CC CC_REGNUM))])]
3433 ""
3434 {
3435 machine_mode sreg_mode = TARGET_ZARCH ? DImode : SImode;
3436 machine_mode dreg_mode = TARGET_ZARCH ? TImode : DImode;
3437 rtx reg0 = gen_reg_rtx (dreg_mode);
3438 rtx reg1 = gen_reg_rtx (dreg_mode);
3439 rtx addr0 = gen_lowpart (Pmode, gen_highpart (sreg_mode, reg0));
3440 rtx addr1 = gen_lowpart (Pmode, gen_highpart (sreg_mode, reg1));
3441 rtx len0 = gen_lowpart (Pmode, reg0);
3442 rtx len1 = gen_lowpart (Pmode, reg1);
3443
3444 emit_clobber (reg0);
3445 emit_move_insn (addr0, force_operand (XEXP (operands[0], 0), NULL_RTX));
3446 emit_move_insn (len0, operands[2]);
3447
3448 emit_clobber (reg1);
3449 emit_move_insn (addr1, force_operand (XEXP (operands[1], 0), NULL_RTX));
3450 emit_move_insn (len1, operands[2]);
3451
3452 operands[0] = replace_equiv_address_nv (operands[0], addr0);
3453 operands[1] = replace_equiv_address_nv (operands[1], addr1);
3454 operands[2] = reg0;
3455 operands[3] = reg1;
3456 })
3457
3458 (define_insn "*cpymem_long"
3459 [(clobber (match_operand:<DBL> 0 "register_operand" "=d"))
3460 (clobber (match_operand:<DBL> 1 "register_operand" "=d"))
3461 (set (mem:BLK (subreg:P (match_operand:<DBL> 2 "register_operand" "0") 0))
3462 (mem:BLK (subreg:P (match_operand:<DBL> 3 "register_operand" "1") 0)))
3463 (use (match_dup 2))
3464 (use (match_dup 3))
3465 (clobber (reg:CC CC_REGNUM))]
3466 "TARGET_64BIT || !TARGET_ZARCH"
3467 "mvcle\t%0,%1,0\;jo\t.-4"
3468 [(set_attr "length" "8")
3469 (set_attr "type" "vs")])
3470
3471 (define_insn "*cpymem_long_31z"
3472 [(clobber (match_operand:TI 0 "register_operand" "=d"))
3473 (clobber (match_operand:TI 1 "register_operand" "=d"))
3474 (set (mem:BLK (subreg:SI (match_operand:TI 2 "register_operand" "0") 4))
3475 (mem:BLK (subreg:SI (match_operand:TI 3 "register_operand" "1") 4)))
3476 (use (match_dup 2))
3477 (use (match_dup 3))
3478 (clobber (reg:CC CC_REGNUM))]
3479 "!TARGET_64BIT && TARGET_ZARCH"
3480 "mvcle\t%0,%1,0\;jo\t.-4"
3481 [(set_attr "length" "8")
3482 (set_attr "type" "vs")])
3483
3484
3485 ;
3486 ; Test data class.
3487 ;
3488
3489 (define_expand "signbit<mode>2<tf_fpr>"
3490 [(set (reg:CCZ CC_REGNUM)
3491 (unspec:CCZ [(match_operand:FP_ALL 1 "register_operand" "f")
3492 (match_dup 2)]
3493 UNSPEC_TDC_INSN))
3494 (set (match_operand:SI 0 "register_operand" "=d")
3495 (unspec:SI [(reg:CCZ CC_REGNUM)] UNSPEC_CC_TO_INT))]
3496 "TARGET_HARD_FLOAT"
3497 {
3498 operands[2] = GEN_INT (S390_TDC_SIGNBIT_SET);
3499 })
3500
3501 (define_expand "isinf<mode>2<tf_fpr>"
3502 [(set (reg:CCZ CC_REGNUM)
3503 (unspec:CCZ [(match_operand:FP_ALL 1 "register_operand" "f")
3504 (match_dup 2)]
3505 UNSPEC_TDC_INSN))
3506 (set (match_operand:SI 0 "register_operand" "=d")
3507 (unspec:SI [(reg:CCZ CC_REGNUM)] UNSPEC_CC_TO_INT))]
3508 "TARGET_HARD_FLOAT"
3509 {
3510 operands[2] = GEN_INT (S390_TDC_INFINITY);
3511 })
3512
3513 ; This extracts CC into a GPR properly shifted. The actual IPM
3514 ; instruction will be issued by reload. The constraint of operand 1
3515 ; forces reload to use a GPR. So reload will issue a movcc insn for
3516 ; copying CC into a GPR first.
3517 (define_insn_and_split "*cc_to_int"
3518 [(set (match_operand:SI 0 "nonimmediate_operand" "=d")
3519 (unspec:SI [(match_operand 1 "register_operand" "0")]
3520 UNSPEC_CC_TO_INT))]
3521 "operands != NULL"
3522 "#"
3523 "reload_completed"
3524 [(set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 28)))])
3525
3526 ; This insn is used to generate all variants of the Test Data Class
3527 ; instruction, namely tcxb, tcdb, and tceb. The insn's first operand
3528 ; is the register to be tested and the second one is the bit mask
3529 ; specifying the required test(s).
3530 ;
3531 ; tcxb, tcdb, tceb, tdcxt, tdcdt, tdcet
3532 (define_insn "*TDC_insn_<mode>"
3533 [(set (reg:CCZ CC_REGNUM)
3534 (unspec:CCZ [(match_operand:FP_ALL 0 "register_operand" "f")
3535 (match_operand:SI 1 "const_int_operand")] UNSPEC_TDC_INSN))]
3536 "TARGET_HARD_FLOAT"
3537 "t<_d>c<xde><bt>\t%0,%1"
3538 [(set_attr "op_type" "RXE")
3539 (set_attr "type" "fsimp<type>")])
3540
3541
3542
3543 ;
3544 ; setmemM instruction pattern(s).
3545 ;
3546
3547 (define_expand "setmem<mode>"
3548 [(set (match_operand:BLK 0 "memory_operand" "")
3549 (match_operand:QI 2 "general_operand" ""))
3550 (use (match_operand:GPR 1 "general_operand" ""))
3551 (match_operand 3 "" "")]
3552 ""
3553 "s390_expand_setmem (operands[0], operands[1], operands[2]); DONE;")
3554
3555 ; Clear a block that is up to 256 bytes in length.
3556 ; The block length is taken as (operands[1] % 256) + 1.
3557
3558 (define_expand "clrmem_short"
3559 [(parallel
3560 [(set (match_operand:BLK 0 "memory_operand" "")
3561 (const_int 0))
3562 (use (match_operand 1 "nonmemory_operand" ""))
3563 (use (const:BLK (unspec:BLK [(const_int 0)] UNSPEC_INSN)))
3564 (clobber (match_dup 2))
3565 (clobber (reg:CC CC_REGNUM))])]
3566 ""
3567 "operands[2] = gen_rtx_SCRATCH (Pmode);")
3568
3569 (define_insn "*clrmem_short"
3570 [(set (match_operand:BLK 0 "memory_operand" "=Q,Q,Q,Q")
3571 (const_int 0))
3572 (use (match_operand 1 "nonmemory_operand" "n,a,a,a"))
3573 (use (match_operand 2 "immediate_operand" "X,R,X,X"))
3574 (clobber (match_scratch:P 3 "=X,X,X,&a"))
3575 (clobber (reg:CC CC_REGNUM))]
3576 "(GET_MODE (operands[1]) == Pmode || GET_MODE (operands[1]) == VOIDmode)"
3577 "#"
3578 [(set_attr "type" "cs")
3579 (set_attr "cpu_facility" "*,*,z10,cpu_zarch")])
3580
3581 (define_split
3582 [(set (match_operand:BLK 0 "memory_operand" "")
3583 (const_int 0))
3584 (use (match_operand 1 "const_int_operand" ""))
3585 (use (match_operand 2 "immediate_operand" ""))
3586 (clobber (scratch))
3587 (clobber (reg:CC CC_REGNUM))]
3588 "reload_completed"
3589 [(parallel
3590 [(set (match_dup 0) (const_int 0))
3591 (use (match_dup 1))
3592 (clobber (reg:CC CC_REGNUM))])]
3593 "operands[1] = GEN_INT ((INTVAL (operands[1]) & 0xff) + 1);")
3594
3595 (define_split
3596 [(set (match_operand:BLK 0 "memory_operand" "")
3597 (const_int 0))
3598 (use (match_operand 1 "register_operand" ""))
3599 (use (match_operand 2 "memory_operand" ""))
3600 (clobber (scratch))
3601 (clobber (reg:CC CC_REGNUM))]
3602 "reload_completed"
3603 [(parallel
3604 [(unspec [(match_dup 1) (match_dup 2)
3605 (const_int 0)] UNSPEC_EXECUTE)
3606 (set (match_dup 0) (const_int 0))
3607 (use (const_int 1))
3608 (clobber (reg:CC CC_REGNUM))])]
3609 "")
3610
3611 (define_split
3612 [(set (match_operand:BLK 0 "memory_operand" "")
3613 (const_int 0))
3614 (use (match_operand 1 "register_operand" ""))
3615 (use (const:BLK (unspec:BLK [(const_int 0)] UNSPEC_INSN)))
3616 (clobber (scratch))
3617 (clobber (reg:CC CC_REGNUM))]
3618 "TARGET_Z10 && reload_completed"
3619 [(parallel
3620 [(unspec [(match_dup 1) (const_int 0)
3621 (label_ref (match_dup 3))] UNSPEC_EXECUTE)
3622 (set (match_dup 0) (const_int 0))
3623 (use (const_int 1))
3624 (clobber (reg:CC CC_REGNUM))])]
3625 "operands[3] = gen_label_rtx ();")
3626
3627 (define_split
3628 [(set (match_operand:BLK 0 "memory_operand" "")
3629 (const_int 0))
3630 (use (match_operand 1 "register_operand" ""))
3631 (use (const:BLK (unspec:BLK [(const_int 0)] UNSPEC_INSN)))
3632 (clobber (match_operand 2 "register_operand" ""))
3633 (clobber (reg:CC CC_REGNUM))]
3634 "reload_completed"
3635 [(set (match_dup 2) (label_ref (match_dup 3)))
3636 (parallel
3637 [(unspec [(match_dup 1) (mem:BLK (match_dup 2))
3638 (label_ref (match_dup 3))] UNSPEC_EXECUTE)
3639 (set (match_dup 0) (const_int 0))
3640 (use (const_int 1))
3641 (clobber (reg:CC CC_REGNUM))])]
3642 "operands[3] = gen_label_rtx ();")
3643
3644 ; Initialize a block of arbitrary length with (operands[2] % 256).
3645
3646 (define_expand "setmem_long_<P:mode>"
3647 [(parallel
3648 [(clobber (match_dup 1))
3649 (set (match_operand:BLK 0 "memory_operand" "")
3650 (unspec:BLK [(match_operand:P 2 "setmem_operand" "")
3651 (match_dup 4)] UNSPEC_REPLICATE_BYTE))
3652 (use (match_dup 3))
3653 (clobber (reg:CC CC_REGNUM))])]
3654 ""
3655 {
3656 machine_mode sreg_mode = TARGET_ZARCH ? DImode : SImode;
3657 machine_mode dreg_mode = TARGET_ZARCH ? TImode : DImode;
3658 rtx reg0 = gen_reg_rtx (dreg_mode);
3659 rtx reg1 = gen_reg_rtx (dreg_mode);
3660 rtx addr0 = gen_lowpart (Pmode, gen_highpart (sreg_mode, reg0));
3661 rtx len0 = gen_lowpart (Pmode, reg0);
3662
3663 emit_clobber (reg0);
3664 emit_move_insn (addr0, force_operand (XEXP (operands[0], 0), NULL_RTX));
3665 emit_move_insn (len0, operands[1]);
3666
3667 emit_move_insn (reg1, const0_rtx);
3668
3669 operands[0] = replace_equiv_address_nv (operands[0], addr0);
3670 operands[1] = reg0;
3671 operands[3] = reg1;
3672 operands[4] = gen_lowpart (Pmode, operands[1]);
3673 })
3674
3675 ; Patterns for 31 bit + Esa and 64 bit + Zarch.
3676
3677 (define_insn "*setmem_long"
3678 [(clobber (match_operand:<DBL> 0 "register_operand" "=d"))
3679 (set (mem:BLK (subreg:P (match_operand:<DBL> 3 "register_operand" "0") 0))
3680 (unspec:BLK [(match_operand:P 2 "setmem_operand" "Y")
3681 (subreg:P (match_dup 3) <modesize>)]
3682 UNSPEC_REPLICATE_BYTE))
3683 (use (match_operand:<DBL> 1 "register_operand" "d"))
3684 (clobber (reg:CC CC_REGNUM))]
3685 "TARGET_64BIT || !TARGET_ZARCH"
3686 "mvcle\t%0,%1,%Y2\;jo\t.-4"
3687 [(set_attr "length" "8")
3688 (set_attr "type" "vs")])
3689
3690 (define_insn "*setmem_long_and"
3691 [(clobber (match_operand:<DBL> 0 "register_operand" "=d"))
3692 (set (mem:BLK (subreg:P (match_operand:<DBL> 3 "register_operand" "0") 0))
3693 (unspec:BLK [(zero_extend:P (match_operand:QI 2 "setmem_operand" "Y"))
3694 (subreg:P (match_dup 3) <modesize>)]
3695 UNSPEC_REPLICATE_BYTE))
3696 (use (match_operand:<DBL> 1 "register_operand" "d"))
3697 (clobber (reg:CC CC_REGNUM))]
3698 "(TARGET_64BIT || !TARGET_ZARCH)"
3699 "mvcle\t%0,%1,%Y2\;jo\t.-4"
3700 [(set_attr "length" "8")
3701 (set_attr "type" "vs")])
3702
3703 ; Variants for 31 bit + Zarch, necessary because of the odd in-register offsets
3704 ; of the SImode subregs.
3705
3706 (define_insn "*setmem_long_31z"
3707 [(clobber (match_operand:TI 0 "register_operand" "=d"))
3708 (set (mem:BLK (subreg:SI (match_operand:TI 3 "register_operand" "0") 4))
3709 (unspec:BLK [(match_operand:SI 2 "setmem_operand" "Y")
3710 (subreg:SI (match_dup 3) 12)] UNSPEC_REPLICATE_BYTE))
3711 (use (match_operand:TI 1 "register_operand" "d"))
3712 (clobber (reg:CC CC_REGNUM))]
3713 "!TARGET_64BIT && TARGET_ZARCH"
3714 "mvcle\t%0,%1,%Y2\;jo\t.-4"
3715 [(set_attr "length" "8")
3716 (set_attr "type" "vs")])
3717
3718 (define_insn "*setmem_long_and_31z"
3719 [(clobber (match_operand:TI 0 "register_operand" "=d"))
3720 (set (mem:BLK (subreg:SI (match_operand:TI 3 "register_operand" "0") 4))
3721 (unspec:BLK [(zero_extend:SI (match_operand:QI 2 "setmem_operand" "Y"))
3722 (subreg:SI (match_dup 3) 12)] UNSPEC_REPLICATE_BYTE))
3723 (use (match_operand:TI 1 "register_operand" "d"))
3724 (clobber (reg:CC CC_REGNUM))]
3725 "(!TARGET_64BIT && TARGET_ZARCH)"
3726 "mvcle\t%0,%1,%Y2\;jo\t.-4"
3727 [(set_attr "length" "8")
3728 (set_attr "type" "vs")])
3729
3730 ;
3731 ; cmpmemM instruction pattern(s).
3732 ;
3733
3734 (define_expand "cmpmemsi"
3735 [(set (match_operand:SI 0 "register_operand" "")
3736 (compare:SI (match_operand:BLK 1 "memory_operand" "")
3737 (match_operand:BLK 2 "memory_operand" "") ) )
3738 (use (match_operand:SI 3 "general_operand" ""))
3739 (use (match_operand:SI 4 "" ""))]
3740 ""
3741 {
3742 if (s390_expand_cmpmem (operands[0], operands[1],
3743 operands[2], operands[3]))
3744 DONE;
3745 else
3746 FAIL;
3747 })
3748
3749 ; Compare a block that is up to 256 bytes in length.
3750 ; The block length is taken as (operands[2] % 256) + 1.
3751
3752 (define_expand "cmpmem_short"
3753 [(parallel
3754 [(set (reg:CCU CC_REGNUM)
3755 (compare:CCU (match_operand:BLK 0 "memory_operand" "")
3756 (match_operand:BLK 1 "memory_operand" "")))
3757 (use (match_operand 2 "nonmemory_operand" ""))
3758 (use (const:BLK (unspec:BLK [(const_int 0)] UNSPEC_INSN)))
3759 (clobber (match_dup 3))])]
3760 ""
3761 "operands[3] = gen_rtx_SCRATCH (Pmode);")
3762
3763 (define_insn "*cmpmem_short"
3764 [(set (reg:CCU CC_REGNUM)
3765 (compare:CCU (match_operand:BLK 0 "memory_operand" "Q,Q,Q,Q")
3766 (match_operand:BLK 1 "memory_operand" "Q,Q,Q,Q")))
3767 (use (match_operand 2 "nonmemory_operand" "n,a,a,a"))
3768 (use (match_operand 3 "immediate_operand" "X,R,X,X"))
3769 (clobber (match_scratch:P 4 "=X,X,X,&a"))]
3770 "(GET_MODE (operands[2]) == Pmode || GET_MODE (operands[2]) == VOIDmode)"
3771 "#"
3772 [(set_attr "type" "cs")
3773 (set_attr "cpu_facility" "*,*,z10,cpu_zarch")])
3774
3775 (define_split
3776 [(set (reg:CCU CC_REGNUM)
3777 (compare:CCU (match_operand:BLK 0 "memory_operand" "")
3778 (match_operand:BLK 1 "memory_operand" "")))
3779 (use (match_operand 2 "const_int_operand" ""))
3780 (use (match_operand 3 "immediate_operand" ""))
3781 (clobber (scratch))]
3782 "reload_completed"
3783 [(parallel
3784 [(set (reg:CCU CC_REGNUM) (compare:CCU (match_dup 0) (match_dup 1)))
3785 (use (match_dup 2))])]
3786 "operands[2] = GEN_INT ((INTVAL (operands[2]) & 0xff) + 1);")
3787
3788 (define_split
3789 [(set (reg:CCU CC_REGNUM)
3790 (compare:CCU (match_operand:BLK 0 "memory_operand" "")
3791 (match_operand:BLK 1 "memory_operand" "")))
3792 (use (match_operand 2 "register_operand" ""))
3793 (use (match_operand 3 "memory_operand" ""))
3794 (clobber (scratch))]
3795 "reload_completed"
3796 [(parallel
3797 [(unspec [(match_dup 2) (match_dup 3)
3798 (const_int 0)] UNSPEC_EXECUTE)
3799 (set (reg:CCU CC_REGNUM) (compare:CCU (match_dup 0) (match_dup 1)))
3800 (use (const_int 1))])]
3801 "")
3802
3803 (define_split
3804 [(set (reg:CCU CC_REGNUM)
3805 (compare:CCU (match_operand:BLK 0 "memory_operand" "")
3806 (match_operand:BLK 1 "memory_operand" "")))
3807 (use (match_operand 2 "register_operand" ""))
3808 (use (const:BLK (unspec:BLK [(const_int 0)] UNSPEC_INSN)))
3809 (clobber (scratch))]
3810 "TARGET_Z10 && reload_completed"
3811 [(parallel
3812 [(unspec [(match_dup 2) (const_int 0)
3813 (label_ref (match_dup 4))] UNSPEC_EXECUTE)
3814 (set (reg:CCU CC_REGNUM) (compare:CCU (match_dup 0) (match_dup 1)))
3815 (use (const_int 1))])]
3816 "operands[4] = gen_label_rtx ();")
3817
3818 (define_split
3819 [(set (reg:CCU CC_REGNUM)
3820 (compare:CCU (match_operand:BLK 0 "memory_operand" "")
3821 (match_operand:BLK 1 "memory_operand" "")))
3822 (use (match_operand 2 "register_operand" ""))
3823 (use (const:BLK (unspec:BLK [(const_int 0)] UNSPEC_INSN)))
3824 (clobber (match_operand 3 "register_operand" ""))]
3825 "reload_completed"
3826 [(set (match_dup 3) (label_ref (match_dup 4)))
3827 (parallel
3828 [(unspec [(match_dup 2) (mem:BLK (match_dup 3))
3829 (label_ref (match_dup 4))] UNSPEC_EXECUTE)
3830 (set (reg:CCU CC_REGNUM) (compare:CCU (match_dup 0) (match_dup 1)))
3831 (use (const_int 1))])]
3832 "operands[4] = gen_label_rtx ();")
3833
3834 ; Compare a block of arbitrary length.
3835
3836 (define_expand "cmpmem_long"
3837 [(parallel
3838 [(clobber (match_dup 2))
3839 (clobber (match_dup 3))
3840 (set (reg:CCU CC_REGNUM)
3841 (compare:CCU (match_operand:BLK 0 "memory_operand" "")
3842 (match_operand:BLK 1 "memory_operand" "")))
3843 (use (match_operand 2 "general_operand" ""))
3844 (use (match_dup 3))])]
3845 ""
3846 {
3847 machine_mode sreg_mode = TARGET_ZARCH ? DImode : SImode;
3848 machine_mode dreg_mode = TARGET_ZARCH ? TImode : DImode;
3849 rtx reg0 = gen_reg_rtx (dreg_mode);
3850 rtx reg1 = gen_reg_rtx (dreg_mode);
3851 rtx addr0 = gen_lowpart (Pmode, gen_highpart (sreg_mode, reg0));
3852 rtx addr1 = gen_lowpart (Pmode, gen_highpart (sreg_mode, reg1));
3853 rtx len0 = gen_lowpart (Pmode, reg0);
3854 rtx len1 = gen_lowpart (Pmode, reg1);
3855
3856 emit_clobber (reg0);
3857 emit_move_insn (addr0, force_operand (XEXP (operands[0], 0), NULL_RTX));
3858 emit_move_insn (len0, operands[2]);
3859
3860 emit_clobber (reg1);
3861 emit_move_insn (addr1, force_operand (XEXP (operands[1], 0), NULL_RTX));
3862 emit_move_insn (len1, operands[2]);
3863
3864 operands[0] = replace_equiv_address_nv (operands[0], addr0);
3865 operands[1] = replace_equiv_address_nv (operands[1], addr1);
3866 operands[2] = reg0;
3867 operands[3] = reg1;
3868 })
3869
3870 (define_insn "*cmpmem_long"
3871 [(clobber (match_operand:<DBL> 0 "register_operand" "=d"))
3872 (clobber (match_operand:<DBL> 1 "register_operand" "=d"))
3873 (set (reg:CCU CC_REGNUM)
3874 (compare:CCU (mem:BLK (subreg:P (match_operand:<DBL> 2 "register_operand" "0") 0))
3875 (mem:BLK (subreg:P (match_operand:<DBL> 3 "register_operand" "1") 0))))
3876 (use (match_dup 2))
3877 (use (match_dup 3))]
3878 "TARGET_64BIT || !TARGET_ZARCH"
3879 "clcle\t%0,%1,0\;jo\t.-4"
3880 [(set_attr "length" "8")
3881 (set_attr "type" "vs")])
3882
3883 (define_insn "*cmpmem_long_31z"
3884 [(clobber (match_operand:TI 0 "register_operand" "=d"))
3885 (clobber (match_operand:TI 1 "register_operand" "=d"))
3886 (set (reg:CCU CC_REGNUM)
3887 (compare:CCU (mem:BLK (subreg:SI (match_operand:TI 2 "register_operand" "0") 4))
3888 (mem:BLK (subreg:SI (match_operand:TI 3 "register_operand" "1") 4))))
3889 (use (match_dup 2))
3890 (use (match_dup 3))]
3891 "!TARGET_64BIT && TARGET_ZARCH"
3892 "clcle\t%0,%1,0\;jo\t.-4"
3893 [(set_attr "op_type" "NN")
3894 (set_attr "type" "vs")
3895 (set_attr "length" "8")])
3896
3897 ; Convert CCUmode condition code to integer.
3898 ; Result is zero if EQ, positive if LTU, negative if GTU.
3899
3900 (define_insn_and_split "cmpint"
3901 [(set (match_operand:SI 0 "register_operand" "=d")
3902 (unspec:SI [(match_operand:CCU 1 "register_operand" "0")]
3903 UNSPEC_STRCMPCC_TO_INT))
3904 (clobber (reg:CC CC_REGNUM))]
3905 ""
3906 "#"
3907 "reload_completed"
3908 [(set (match_dup 0) (ashift:SI (match_dup 0) (const_int 2)))
3909 (parallel
3910 [(set (match_dup 0) (ashiftrt:SI (match_dup 0) (const_int 30)))
3911 (clobber (reg:CC CC_REGNUM))])])
3912
3913 (define_insn_and_split "*cmpint_cc"
3914 [(set (reg CC_REGNUM)
3915 (compare (unspec:SI [(match_operand:CCU 1 "register_operand" "0")]
3916 UNSPEC_STRCMPCC_TO_INT)
3917 (const_int 0)))
3918 (set (match_operand:SI 0 "register_operand" "=d")
3919 (unspec:SI [(match_dup 1)] UNSPEC_STRCMPCC_TO_INT))]
3920 "s390_match_ccmode (insn, CCSmode)"
3921 "#"
3922 "&& reload_completed"
3923 [(set (match_dup 0) (ashift:SI (match_dup 0) (const_int 2)))
3924 (parallel
3925 [(set (match_dup 2) (match_dup 3))
3926 (set (match_dup 0) (ashiftrt:SI (match_dup 0) (const_int 30)))])]
3927 {
3928 rtx result = gen_rtx_ASHIFTRT (SImode, operands[0], GEN_INT (30));
3929 operands[2] = SET_DEST (XVECEXP (PATTERN (curr_insn), 0, 0));
3930 operands[3] = gen_rtx_COMPARE (GET_MODE (operands[2]), result, const0_rtx);
3931 })
3932
3933 (define_insn_and_split "*cmpint_sign"
3934 [(set (match_operand:DI 0 "register_operand" "=d")
3935 (sign_extend:DI (unspec:SI [(match_operand:CCU 1 "register_operand" "0")]
3936 UNSPEC_STRCMPCC_TO_INT)))
3937 (clobber (reg:CC CC_REGNUM))]
3938 "TARGET_ZARCH"
3939 "#"
3940 "&& reload_completed"
3941 [(set (match_dup 0) (ashift:DI (match_dup 0) (const_int 34)))
3942 (parallel
3943 [(set (match_dup 0) (ashiftrt:DI (match_dup 0) (const_int 62)))
3944 (clobber (reg:CC CC_REGNUM))])])
3945
3946 (define_insn_and_split "*cmpint_sign_cc"
3947 [(set (reg CC_REGNUM)
3948 (compare (ashiftrt:DI (ashift:DI (subreg:DI
3949 (unspec:SI [(match_operand:CCU 1 "register_operand" "0")]
3950 UNSPEC_STRCMPCC_TO_INT) 0)
3951 (const_int 32)) (const_int 32))
3952 (const_int 0)))
3953 (set (match_operand:DI 0 "register_operand" "=d")
3954 (sign_extend:DI (unspec:SI [(match_dup 1)] UNSPEC_STRCMPCC_TO_INT)))]
3955 "s390_match_ccmode (insn, CCSmode) && TARGET_ZARCH"
3956 "#"
3957 "&& reload_completed"
3958 [(set (match_dup 0) (ashift:DI (match_dup 0) (const_int 34)))
3959 (parallel
3960 [(set (match_dup 2) (match_dup 3))
3961 (set (match_dup 0) (ashiftrt:DI (match_dup 0) (const_int 62)))])]
3962 {
3963 rtx result = gen_rtx_ASHIFTRT (DImode, operands[0], GEN_INT (62));
3964 operands[2] = SET_DEST (XVECEXP (PATTERN (curr_insn), 0, 0));
3965 operands[3] = gen_rtx_COMPARE (GET_MODE (operands[2]), result, const0_rtx);
3966 })
3967
3968
3969 ;;
3970 ;;- Conversion instructions.
3971 ;;
3972
3973 (define_insn "*sethighpartsi"
3974 [(set (match_operand:SI 0 "register_operand" "=d,d")
3975 (unspec:SI [(match_operand:BLK 1 "s_operand" "Q,S")
3976 (match_operand 2 "const_int_operand" "n,n")] UNSPEC_ICM))
3977 (clobber (reg:CC CC_REGNUM))]
3978 ""
3979 "@
3980 icm\t%0,%2,%S1
3981 icmy\t%0,%2,%S1"
3982 [(set_attr "op_type" "RS,RSY")
3983 (set_attr "cpu_facility" "*,longdisp")
3984 (set_attr "z10prop" "z10_super_E1,z10_super_E1")])
3985
3986 (define_insn "*sethighpartdi_64"
3987 [(set (match_operand:DI 0 "register_operand" "=d")
3988 (unspec:DI [(match_operand:BLK 1 "s_operand" "S")
3989 (match_operand 2 "const_int_operand" "n")] UNSPEC_ICM))
3990 (clobber (reg:CC CC_REGNUM))]
3991 "TARGET_ZARCH"
3992 "icmh\t%0,%2,%S1"
3993 [(set_attr "op_type" "RSY")
3994 (set_attr "z10prop" "z10_super")])
3995
3996 (define_insn "*sethighpartdi_31"
3997 [(set (match_operand:DI 0 "register_operand" "=d,d")
3998 (unspec:DI [(match_operand:BLK 1 "s_operand" "Q,S")
3999 (match_operand 2 "const_int_operand" "n,n")] UNSPEC_ICM))
4000 (clobber (reg:CC CC_REGNUM))]
4001 "!TARGET_ZARCH"
4002 "@
4003 icm\t%0,%2,%S1
4004 icmy\t%0,%2,%S1"
4005 [(set_attr "op_type" "RS,RSY")
4006 (set_attr "cpu_facility" "*,longdisp")
4007 (set_attr "z10prop" "z10_super_E1,z10_super_E1")])
4008
4009 ;
4010 ; extv instruction patterns
4011 ;
4012
4013 ; FIXME: This expander needs to be converted from DI to GPR as well
4014 ; after resolving some issues with it.
4015
4016 (define_expand "extzv"
4017 [(parallel
4018 [(set (match_operand:DI 0 "register_operand" "=d")
4019 (zero_extract:DI
4020 (match_operand:DI 1 "register_operand" "d")
4021 (match_operand 2 "const_int_operand" "") ; size
4022 (match_operand 3 "const_int_operand" ""))) ; start
4023 (clobber (reg:CC CC_REGNUM))])]
4024 "TARGET_Z10"
4025 {
4026 if (! EXTRACT_ARGS_IN_RANGE (INTVAL (operands[2]), INTVAL (operands[3]), 64))
4027 FAIL;
4028 /* Starting with zEC12 there is risbgn not clobbering CC. */
4029 if (TARGET_ZEC12)
4030 {
4031 emit_move_insn (operands[0],
4032 gen_rtx_ZERO_EXTRACT (DImode,
4033 operands[1],
4034 operands[2],
4035 operands[3]));
4036 DONE;
4037 }
4038 })
4039
4040 (define_insn "*extzv<mode><clobbercc_or_nocc>"
4041 [(set (match_operand:GPR 0 "register_operand" "=d")
4042 (zero_extract:GPR
4043 (match_operand:GPR 1 "register_operand" "d")
4044 (match_operand 2 "const_int_operand" "") ; size
4045 (match_operand 3 "const_int_operand" ""))) ; start
4046 ]
4047 "<z10_or_zEC12_cond>
4048 && EXTRACT_ARGS_IN_RANGE (INTVAL (operands[2]), INTVAL (operands[3]),
4049 GET_MODE_BITSIZE (<MODE>mode))"
4050 "<risbg_n>\t%0,%1,64-%2,128+63,<bitoff_plus>%3+%2" ; dst, src, start, end, shift
4051 [(set_attr "op_type" "RIE")
4052 (set_attr "z10prop" "z10_super_E1")])
4053
4054 ; 64 bit: (a & -16) | ((b >> 8) & 15)
4055 (define_insn "*extzvdi<clobbercc_or_nocc>_lshiftrt"
4056 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+d")
4057 (match_operand 1 "const_int_operand" "") ; size
4058 (match_operand 2 "const_int_operand" "")) ; start
4059 (lshiftrt:DI (match_operand:DI 3 "register_operand" "d")
4060 (match_operand:DI 4 "nonzero_shift_count_operand" "")))]
4061 "<z10_or_zEC12_cond>
4062 && EXTRACT_ARGS_IN_RANGE (INTVAL (operands[1]), INTVAL (operands[2]), 64)
4063 && 64 - UINTVAL (operands[4]) >= UINTVAL (operands[1])"
4064 "<risbg_n>\t%0,%3,%2,%2+%1-1,128-%2-%1-%4"
4065 [(set_attr "op_type" "RIE")
4066 (set_attr "z10prop" "z10_super_E1")])
4067
4068 ; (a & -16) | ((b >> 8) & 15)
4069 (define_insn "*<risbg_n>_ior_and_sr_ze<mode>"
4070 [(set (match_operand:DSI 0 "register_operand" "=d")
4071 (ior:DSI (and:DSI
4072 (match_operand:DSI 1 "register_operand" "0")
4073 (match_operand:DSI 2 "const_int_operand" ""))
4074 (zero_extract:DSI
4075 (match_operand:DSI 3 "register_operand" "d")
4076 (match_operand 4 "const_int_operand" "") ; size
4077 (match_operand 5 "const_int_operand" "")) ; start
4078 ))]
4079 "<z10_or_zEC12_cond>
4080 && EXTRACT_ARGS_IN_RANGE (INTVAL (operands[4]), INTVAL (operands[5]), <DSI:bitsize>)
4081 && UINTVAL (operands[2]) == (HOST_WIDE_INT_M1U << UINTVAL (operands[4]))"
4082 "<risbg_n>\t%0,%3,64-%4,63,(64-<DSI:bitsize>)+%4+%5"
4083 [(set_attr "op_type" "RIE")
4084 (set_attr "z10prop" "z10_super_E1")])
4085
4086 ; ((int)foo >> 10) & 1;
4087 (define_insn "*extract1bitdi<clobbercc_or_nocc>"
4088 [(set (match_operand:DI 0 "register_operand" "=d")
4089 (ne:DI (zero_extract:DI
4090 (match_operand:DI 1 "register_operand" "d")
4091 (const_int 1) ; size
4092 (match_operand 2 "const_int_operand" "")) ; start
4093 (const_int 0)))]
4094 "<z10_or_zEC12_cond>
4095 && EXTRACT_ARGS_IN_RANGE (1, INTVAL (operands[2]), 64)"
4096 "<risbg_n>\t%0,%1,64-1,128+63,%2+1" ; dst, src, start, end, shift
4097 [(set_attr "op_type" "RIE")
4098 (set_attr "z10prop" "z10_super_E1")])
4099
4100 (define_insn "*<risbg_n>_and_subregdi_rotr"
4101 [(set (match_operand:DI 0 "register_operand" "=d")
4102 (and:DI (subreg:DI
4103 (rotate:SINT (match_operand:SINT 1 "register_operand" "d")
4104 (match_operand:SINT 2 "const_int_operand" "")) 0)
4105 (match_operand:DI 3 "contiguous_bitmask_operand" "")))]
4106 "<z10_or_zEC12_cond>
4107 && (UINTVAL (operands[3])
4108 < (HOST_WIDE_INT_1U << (UINTVAL (operands[2]) & 0x3f)))"
4109 "<risbg_n>\t%0,%1,%s3,128+%e3,<bitoff_plus>%2" ; dst, src, start, end, shift
4110 [(set_attr "op_type" "RIE")
4111 (set_attr "z10prop" "z10_super_E1")])
4112
4113 (define_insn "*<risbg_n>_and_subregdi_rotl"
4114 [(set (match_operand:DI 0 "register_operand" "=d")
4115 (and:DI (subreg:DI
4116 (rotate:SINT (match_operand:SINT 1 "register_operand" "d")
4117 (match_operand:SINT 2 "const_int_operand" "")) 0)
4118 (match_operand:DI 3 "contiguous_bitmask_operand" "")))]
4119 "<z10_or_zEC12_cond>
4120 && !(UINTVAL (operands[3])
4121 & ((HOST_WIDE_INT_1U << (UINTVAL (operands[2]) & 0x3f)) - 1))"
4122 "<risbg_n>\t%0,%1,%s3,128+%e3,%2" ; dst, src, start, end, shift
4123 [(set_attr "op_type" "RIE")
4124 (set_attr "z10prop" "z10_super_E1")])
4125
4126 (define_insn "*<risbg_n>_di_and_rot"
4127 [(set (match_operand:DI 0 "register_operand" "=d")
4128 (and:DI (rotate:DI (match_operand:DI 1 "register_operand" "d")
4129 (match_operand:DI 2 "const_int_operand" ""))
4130 (match_operand:DI 3 "contiguous_bitmask_operand" "")))]
4131 "<z10_or_zEC12_cond>"
4132 "<risbg_n>\t%0,%1,%s3,128+%e3,%2" ; dst, src, start, end, shift
4133 [(set_attr "op_type" "RIE")
4134 (set_attr "z10prop" "z10_super_E1")])
4135
4136 (define_insn_and_split "*pre_z10_extzv<mode>"
4137 [(set (match_operand:GPR 0 "register_operand" "=d")
4138 (zero_extract:GPR (match_operand:QI 1 "s_operand" "S")
4139 (match_operand 2 "nonzero_shift_count_operand" "")
4140 (const_int 0)))
4141 (clobber (reg:CC CC_REGNUM))]
4142 "!TARGET_Z10"
4143 "#"
4144 "&& reload_completed"
4145 [(parallel
4146 [(set (match_dup 0) (unspec:GPR [(match_dup 1) (match_dup 3)] UNSPEC_ICM))
4147 (clobber (reg:CC CC_REGNUM))])
4148 (set (match_dup 0) (lshiftrt:GPR (match_dup 0) (match_dup 2)))]
4149 {
4150 int bitsize = INTVAL (operands[2]);
4151 int size = (bitsize - 1) / BITS_PER_UNIT + 1; /* round up */
4152 unsigned HOST_WIDE_INT mask
4153 = ((HOST_WIDE_INT_1U << size) - 1) << (GET_MODE_SIZE (SImode) - size);
4154
4155 operands[1] = adjust_address (operands[1], BLKmode, 0);
4156 set_mem_size (operands[1], size);
4157 operands[2] = GEN_INT (<GPR:bitsize> - bitsize);
4158 operands[3] = GEN_INT (mask);
4159 })
4160
4161 (define_insn_and_split "*pre_z10_extv<mode>"
4162 [(set (match_operand:GPR 0 "register_operand" "=d")
4163 (sign_extract:GPR (match_operand:QI 1 "s_operand" "S")
4164 (match_operand 2 "nonzero_shift_count_operand" "")
4165 (const_int 0)))
4166 (clobber (reg:CC CC_REGNUM))]
4167 ""
4168 "#"
4169 "&& reload_completed"
4170 [(parallel
4171 [(set (match_dup 0) (unspec:GPR [(match_dup 1) (match_dup 3)] UNSPEC_ICM))
4172 (clobber (reg:CC CC_REGNUM))])
4173 (parallel
4174 [(set (match_dup 0) (ashiftrt:GPR (match_dup 0) (match_dup 2)))
4175 (clobber (reg:CC CC_REGNUM))])]
4176 {
4177 int bitsize = INTVAL (operands[2]);
4178 int size = (bitsize - 1) / BITS_PER_UNIT + 1; /* round up */
4179 unsigned HOST_WIDE_INT mask
4180 = ((HOST_WIDE_INT_1U << size) - 1) << (GET_MODE_SIZE (SImode) - size);
4181
4182 operands[1] = adjust_address (operands[1], BLKmode, 0);
4183 set_mem_size (operands[1], size);
4184 operands[2] = GEN_INT (<GPR:bitsize> - bitsize);
4185 operands[3] = GEN_INT (mask);
4186 })
4187
4188 ;
4189 ; insv instruction patterns
4190 ;
4191
4192 (define_expand "insv"
4193 [(set (zero_extract (match_operand 0 "nonimmediate_operand" "")
4194 (match_operand 1 "const_int_operand" "")
4195 (match_operand 2 "const_int_operand" ""))
4196 (match_operand 3 "general_operand" ""))]
4197 ""
4198 {
4199 if (s390_expand_insv (operands[0], operands[1], operands[2], operands[3]))
4200 DONE;
4201 FAIL;
4202 })
4203
4204
4205 ; The normal RTL expansion will never generate a zero_extract where
4206 ; the location operand isn't word mode. However, we do this in the
4207 ; back-end when generating atomic operations. See s390_two_part_insv.
4208 (define_insn "*insv<mode><clobbercc_or_nocc>"
4209 [(set (zero_extract:GPR (match_operand:GPR 0 "nonimmediate_operand" "+d")
4210 (match_operand 1 "const_int_operand" "I") ; size
4211 (match_operand 2 "const_int_operand" "I")) ; pos
4212 (match_operand:GPR 3 "nonimmediate_operand" "d"))]
4213 "<z10_or_zEC12_cond>
4214 && EXTRACT_ARGS_IN_RANGE (INTVAL (operands[1]), INTVAL (operands[2]),
4215 GET_MODE_BITSIZE (<MODE>mode))
4216 && (INTVAL (operands[1]) + INTVAL (operands[2])) <= <bitsize>"
4217 "<risbg_n>\t%0,%3,<bitoff_plus>%2,<bitoff_plus>%2+%1-1,<bitsize>-%2-%1"
4218 [(set_attr "op_type" "RIE")
4219 (set_attr "z10prop" "z10_super_E1")])
4220
4221 ; and op1 with a mask being 1 for the selected bits and 0 for the rest
4222 ; and op3=op0 with a mask being 0 for the selected bits and 1 for the rest
4223 (define_insn "*insv<mode><clobbercc_or_nocc>_noshift"
4224 [(set (match_operand:GPR 0 "nonimmediate_operand" "=d,d")
4225 (ior:GPR (and:GPR (match_operand:GPR 1 "nonimmediate_operand" "d,0")
4226 (match_operand:GPR 2 "contiguous_bitmask_operand" ""))
4227 (and:GPR (match_operand:GPR 3 "nonimmediate_operand" "0,d")
4228 (match_operand:GPR 4 "const_int_operand" ""))))]
4229 "<z10_or_zEC12_cond> && INTVAL (operands[2]) == ~INTVAL (operands[4])"
4230 "@
4231 <risbg_n>\t%0,%1,%<bfstart>2,%<bfend>2,0
4232 <risbg_n>\t%0,%3,%<bfstart>4,%<bfend>4,0"
4233 [(set_attr "op_type" "RIE")
4234 (set_attr "z10prop" "z10_super_E1")])
4235
4236 (define_insn "*insv_z10_noshift_cc"
4237 [(set (reg CC_REGNUM)
4238 (compare
4239 (ior:DI
4240 (and:DI (match_operand:DI 1 "nonimmediate_operand" "d,0")
4241 (match_operand:DI 2 "contiguous_bitmask_operand" ""))
4242 (and:DI (match_operand:DI 3 "nonimmediate_operand" "0,d")
4243 (match_operand:DI 4 "const_int_operand" "")))
4244 (const_int 0)))
4245 (set (match_operand:DI 0 "nonimmediate_operand" "=d,d")
4246 (ior:DI (and:DI (match_dup 1) (match_dup 2))
4247 (and:DI (match_dup 3) (match_dup 4))))]
4248 "TARGET_Z10 && s390_match_ccmode (insn, CCSmode)
4249 && INTVAL (operands[2]) == ~INTVAL (operands[4])"
4250 "@
4251 risbg\t%0,%1,%s2,%e2,0
4252 risbg\t%0,%3,%s4,%e4,0"
4253 [(set_attr "op_type" "RIE")
4254 (set_attr "z10prop" "z10_super_E1")])
4255
4256 (define_insn "*insv_z10_noshift_cconly"
4257 [(set
4258 (reg CC_REGNUM)
4259 (compare
4260 (ior:DI
4261 (and:DI (match_operand:DI 1 "nonimmediate_operand" "d,0")
4262 (match_operand:DI 2 "contiguous_bitmask_operand" ""))
4263 (and:DI (match_operand:DI 3 "nonimmediate_operand" "0,d")
4264 (match_operand:DI 4 "const_int_operand" "")))
4265 (const_int 0)))
4266 (clobber (match_scratch:DI 0 "=d,d"))]
4267 "TARGET_Z10 && s390_match_ccmode (insn, CCSmode)
4268 && INTVAL (operands[2]) == ~INTVAL (operands[4])"
4269 "@
4270 risbg\t%0,%1,%s2,%e2,0
4271 risbg\t%0,%3,%s4,%e4,0"
4272 [(set_attr "op_type" "RIE")
4273 (set_attr "z10prop" "z10_super_E1")])
4274
4275 ; Implement appending Y on the left of S bits of X
4276 ; x = (y << s) | (x & ((1 << s) - 1))
4277 (define_insn "*insv<mode><clobbercc_or_nocc>_appendbitsleft"
4278 [(set (match_operand:GPR 0 "nonimmediate_operand" "=d")
4279 (ior:GPR (and:GPR (match_operand:GPR 1 "nonimmediate_operand" "0")
4280 (match_operand:GPR 2 "immediate_operand" ""))
4281 (ashift:GPR (match_operand:GPR 3 "nonimmediate_operand" "d")
4282 (match_operand:GPR 4 "nonzero_shift_count_operand" ""))))]
4283 "<z10_or_zEC12_cond>
4284 && UINTVAL (operands[2]) == (HOST_WIDE_INT_1U << UINTVAL (operands[4])) - 1"
4285 "<risbg_n>\t%0,%3,<bitoff>,64-%4-1,%4"
4286 [(set_attr "op_type" "RIE")
4287 (set_attr "z10prop" "z10_super_E1")])
4288
4289 ; a = ((i32)a & -16777216) | (((ui32)b) >> 8)
4290 (define_insn "*<risbg_n>_<mode>_ior_and_lshiftrt"
4291 [(set (match_operand:GPR 0 "register_operand" "=d")
4292 (ior:GPR (and:GPR
4293 (match_operand:GPR 1 "register_operand" "0")
4294 (match_operand:GPR 2 "const_int_operand" ""))
4295 (lshiftrt:GPR
4296 (match_operand:GPR 3 "register_operand" "d")
4297 (match_operand:GPR 4 "nonzero_shift_count_operand" ""))))]
4298 "<z10_or_zEC12_cond> && UINTVAL (operands[2])
4299 == (HOST_WIDE_INT_M1U
4300 << (GET_MODE_BITSIZE (<MODE>mode) - UINTVAL (operands[4])))"
4301 "<risbg_n>\t%0,%3,<bitoff_plus>%4,63,64-%4"
4302 [(set_attr "op_type" "RIE")
4303 (set_attr "z10prop" "z10_super_E1")])
4304
4305 ; (ui32)(((ui64)x) >> 48) | ((i32)y & -65536);
4306 (define_insn "*<risbg_n>_sidi_ior_and_lshiftrt"
4307 [(set (match_operand:SI 0 "register_operand" "=d")
4308 (ior:SI (and:SI
4309 (match_operand:SI 1 "register_operand" "0")
4310 (match_operand:SI 2 "const_int_operand" ""))
4311 (subreg:SI
4312 (lshiftrt:DI
4313 (match_operand:DI 3 "register_operand" "d")
4314 (match_operand:DI 4 "nonzero_shift_count_operand" "")) 4)))]
4315 "<z10_or_zEC12_cond>
4316 && UINTVAL (operands[2]) == ~(HOST_WIDE_INT_M1U >> UINTVAL (operands[4]))"
4317 "<risbg_n>\t%0,%3,%4,63,64-%4"
4318 [(set_attr "op_type" "RIE")
4319 (set_attr "z10prop" "z10_super_E1")])
4320
4321 ; (ui32)(((ui64)x) >> 12) & -4
4322 (define_insn "*trunc_sidi_and_subreg_lshrt<clobbercc_or_nocc>"
4323 [(set (match_operand:SI 0 "register_operand" "=d")
4324 (and:SI
4325 (subreg:SI (lshiftrt:DI
4326 (match_operand:DI 1 "register_operand" "d")
4327 (match_operand:DI 2 "nonzero_shift_count_operand" "")) 4)
4328 (match_operand:SI 3 "contiguous_bitmask_nowrap_operand" "")))]
4329 "<z10_or_zEC12_cond>"
4330 "<risbg_n>\t%0,%1,%t3,128+%f3,64-%2"
4331 [(set_attr "op_type" "RIE")
4332 (set_attr "z10prop" "z10_super_E1")])
4333
4334 ; (ui32)(((ui64)x) >> 12) & -4
4335 (define_insn "*trunc_sidi_and_subreg_ze<clobbercc_or_nocc>"
4336 [(set (match_operand:SI 0 "register_operand" "=d")
4337 (and:SI
4338 (subreg:SI (zero_extract:DI
4339 (match_operand:DI 1 "register_operand" "d")
4340 (const_int 32)
4341 (match_operand:SI 2 "nonzero_shift_count_operand" "")) 4)
4342 (match_operand:SI 3 "contiguous_bitmask_nowrap_operand" "")))]
4343 "<z10_or_zEC12_cond>"
4344 "<risbg_n>\t%0,%1,%t3,128+%f3,32+%2"
4345 [(set_attr "op_type" "RIE")
4346 (set_attr "z10prop" "z10_super_E1")])
4347
4348 ; z = (x << c) | (y >> d) with (x << c) and (y >> d) not overlapping after shifting
4349 ; -> z = y >> d; z = (x << c) | (z & ((1 << c) - 1))
4350 ; -> z = y >> d; z = risbg;
4351
4352 (define_split
4353 [(set (match_operand:GPR 0 "nonimmediate_operand" "")
4354 (ior:GPR (lshiftrt:GPR (match_operand:GPR 1 "nonimmediate_operand" "")
4355 (match_operand:GPR 2 "nonzero_shift_count_operand" ""))
4356 (ashift:GPR (match_operand:GPR 3 "nonimmediate_operand" "")
4357 (match_operand:GPR 4 "nonzero_shift_count_operand" ""))))]
4358 "TARGET_ZEC12 && UINTVAL (operands[2]) + UINTVAL (operands[4]) >= <bitsize>"
4359 [(set (match_dup 6)
4360 (lshiftrt:GPR (match_dup 1) (match_dup 2)))
4361 (set (match_dup 0)
4362 (ior:GPR (and:GPR (match_dup 6) (match_dup 5))
4363 (ashift:GPR (match_dup 3) (match_dup 4))))]
4364 {
4365 operands[5] = GEN_INT ((HOST_WIDE_INT_1U << UINTVAL (operands[4])) - 1);
4366 if (reg_overlap_mentioned_p (operands[0], operands[3]))
4367 {
4368 if (!can_create_pseudo_p ())
4369 FAIL;
4370 operands[6] = gen_reg_rtx (<MODE>mode);
4371 }
4372 else
4373 operands[6] = operands[0];
4374 })
4375
4376 (define_split
4377 [(parallel
4378 [(set (match_operand:GPR 0 "nonimmediate_operand" "")
4379 (ior:GPR (lshiftrt:GPR (match_operand:GPR 1 "nonimmediate_operand" "")
4380 (match_operand:GPR 2 "nonzero_shift_count_operand" ""))
4381 (ashift:GPR (match_operand:GPR 3 "nonimmediate_operand" "")
4382 (match_operand:GPR 4 "nonzero_shift_count_operand" ""))))
4383 (clobber (reg:CC CC_REGNUM))])]
4384 "TARGET_Z10 && !TARGET_ZEC12 && UINTVAL (operands[2]) + UINTVAL (operands[4]) >= <bitsize>"
4385 [(set (match_dup 6)
4386 (lshiftrt:GPR (match_dup 1) (match_dup 2)))
4387 (parallel
4388 [(set (match_dup 0)
4389 (ior:GPR (and:GPR (match_dup 6) (match_dup 5))
4390 (ashift:GPR (match_dup 3) (match_dup 4))))
4391 (clobber (reg:CC CC_REGNUM))])]
4392 {
4393 operands[5] = GEN_INT ((HOST_WIDE_INT_1U << UINTVAL (operands[4])) - 1);
4394 if (reg_overlap_mentioned_p (operands[0], operands[3]))
4395 {
4396 if (!can_create_pseudo_p ())
4397 FAIL;
4398 operands[6] = gen_reg_rtx (<MODE>mode);
4399 }
4400 else
4401 operands[6] = operands[0];
4402 })
4403
4404 ; rosbg, rxsbg
4405 (define_insn "*r<noxa>sbg_<mode>_noshift"
4406 [(set (match_operand:GPR 0 "nonimmediate_operand" "=d")
4407 (IXOR:GPR
4408 (and:GPR (match_operand:GPR 1 "nonimmediate_operand" "d")
4409 (match_operand:GPR 2 "contiguous_bitmask_operand" ""))
4410 (match_operand:GPR 3 "nonimmediate_operand" "0")))
4411 (clobber (reg:CC CC_REGNUM))]
4412 "TARGET_Z10"
4413 "r<noxa>sbg\t%0,%1,%<bfstart>2,%<bfend>2,0"
4414 [(set_attr "op_type" "RIE")])
4415
4416 ; rosbg, rxsbg
4417 (define_insn "*r<noxa>sbg_di_rotl"
4418 [(set (match_operand:DI 0 "nonimmediate_operand" "=d")
4419 (IXOR:DI
4420 (and:DI
4421 (rotate:DI
4422 (match_operand:DI 1 "nonimmediate_operand" "d")
4423 (match_operand:DI 3 "const_int_operand" ""))
4424 (match_operand:DI 2 "contiguous_bitmask_operand" ""))
4425 (match_operand:DI 4 "nonimmediate_operand" "0")))
4426 (clobber (reg:CC CC_REGNUM))]
4427 "TARGET_Z10"
4428 "r<noxa>sbg\t%0,%1,%s2,%e2,%b3"
4429 [(set_attr "op_type" "RIE")])
4430
4431 ; rosbg, rxsbg
4432 (define_insn "*r<noxa>sbg_<mode>_srl_bitmask"
4433 [(set (match_operand:GPR 0 "nonimmediate_operand" "=d")
4434 (IXOR:GPR
4435 (and:GPR
4436 (lshiftrt:GPR
4437 (match_operand:GPR 1 "nonimmediate_operand" "d")
4438 (match_operand:GPR 3 "nonzero_shift_count_operand" ""))
4439 (match_operand:GPR 2 "contiguous_bitmask_nowrap_operand" ""))
4440 (match_operand:GPR 4 "nonimmediate_operand" "0")))
4441 (clobber (reg:CC CC_REGNUM))]
4442 "TARGET_Z10
4443 && s390_extzv_shift_ok (<bitsize>, 64 - INTVAL (operands[3]),
4444 INTVAL (operands[2]))"
4445 {
4446 operands[3] = GEN_INT (64 - INTVAL (operands[3]));
4447 return "r<noxa>sbg\t%0,%1,%<bfstart>2,%<bfend>2,%3";
4448 }
4449 [(set_attr "op_type" "RIE")])
4450
4451 ; rosbg, rxsbg
4452 (define_insn "*r<noxa>sbg_<mode>_sll_bitmask"
4453 [(set (match_operand:GPR 0 "nonimmediate_operand" "=d")
4454 (IXOR:GPR
4455 (and:GPR
4456 (ashift:GPR
4457 (match_operand:GPR 1 "nonimmediate_operand" "d")
4458 (match_operand:GPR 3 "nonzero_shift_count_operand" ""))
4459 (match_operand:GPR 2 "contiguous_bitmask_nowrap_operand" ""))
4460 (match_operand:GPR 4 "nonimmediate_operand" "0")))
4461 (clobber (reg:CC CC_REGNUM))]
4462 "TARGET_Z10
4463 && s390_extzv_shift_ok (<bitsize>, INTVAL (operands[3]),
4464 INTVAL (operands[2]))"
4465 "r<noxa>sbg\t%0,%1,%<bfstart>2,%<bfend>2,%3"
4466 [(set_attr "op_type" "RIE")])
4467
4468 ;; unsigned {int,long} a, b
4469 ;; a = a | (b << const_int)
4470 ;; a = a ^ (b << const_int)
4471 ; rosbg, rxsbg
4472 (define_insn "*r<noxa>sbg_<mode>_sll"
4473 [(set (match_operand:GPR 0 "nonimmediate_operand" "=d")
4474 (IXOR:GPR
4475 (ashift:GPR
4476 (match_operand:GPR 1 "nonimmediate_operand" "d")
4477 (match_operand:GPR 2 "nonzero_shift_count_operand" ""))
4478 (match_operand:GPR 3 "nonimmediate_operand" "0")))
4479 (clobber (reg:CC CC_REGNUM))]
4480 "TARGET_Z10"
4481 {
4482 operands[3] = GEN_INT (63 - INTVAL (operands[2]));
4483 return "r<noxa>sbg\t%0,%1,<bitoff>,%3,%2";
4484 }
4485 [(set_attr "op_type" "RIE")])
4486
4487 ;; unsigned {int,long} a, b
4488 ;; a = a | (b >> const_int)
4489 ;; a = a ^ (b >> const_int)
4490 ; rosbg, rxsbg
4491 (define_insn "*r<noxa>sbg_<mode>_srl"
4492 [(set (match_operand:GPR 0 "nonimmediate_operand" "=d")
4493 (IXOR:GPR
4494 (lshiftrt:GPR
4495 (match_operand:GPR 1 "nonimmediate_operand" "d")
4496 (match_operand:GPR 2 "nonzero_shift_count_operand" ""))
4497 (match_operand:GPR 3 "nonimmediate_operand" "0")))
4498 (clobber (reg:CC CC_REGNUM))]
4499 "TARGET_Z10"
4500 {
4501 operands[3] = GEN_INT (64 - INTVAL (operands[2]));
4502 operands[2] = GEN_INT (<bitoff_plus> INTVAL (operands[2]));
4503 return "r<noxa>sbg\t%0,%1,%2,63,%3";
4504 }
4505 [(set_attr "op_type" "RIE")])
4506
4507 ; rosbg, rxsbg
4508 (define_insn "*r<noxa>sbg_sidi_srl"
4509 [(set (match_operand:SI 0 "nonimmediate_operand" "=d")
4510 (IXOR:SI
4511 (subreg:SI
4512 (zero_extract:DI
4513 (match_operand:DI 1 "nonimmediate_operand" "d")
4514 (const_int 32)
4515 (match_operand:DI 2 "immediate_operand" ""))
4516 4)
4517 (match_operand:SI 3 "nonimmediate_operand" "0")))
4518 (clobber (reg:CC CC_REGNUM))]
4519 "TARGET_Z10"
4520 {
4521 operands[2] = GEN_INT (32 + INTVAL (operands[2]));
4522 return "r<noxa>sbg\t%0,%1,32,63,%2";
4523 }
4524 [(set_attr "op_type" "RIE")])
4525
4526 ;; These two are generated by combine for s.bf &= val.
4527 ;; ??? For bitfields smaller than 32-bits, we wind up with SImode
4528 ;; shifts and ands, which results in some truly awful patterns
4529 ;; including subregs of operations. Rather unnecessisarily, IMO.
4530 ;; Instead of
4531 ;;
4532 ;; (set (zero_extract:DI (reg/v:DI 50 [ s ])
4533 ;; (const_int 24 [0x18])
4534 ;; (const_int 0 [0]))
4535 ;; (subreg:DI (and:SI (subreg:SI (lshiftrt:DI (reg/v:DI 50 [ s ])
4536 ;; (const_int 40 [0x28])) 4)
4537 ;; (reg:SI 4 %r4 [ y+4 ])) 0))
4538 ;;
4539 ;; we should instead generate
4540 ;;
4541 ;; (set (zero_extract:DI (reg/v:DI 50 [ s ])
4542 ;; (const_int 24 [0x18])
4543 ;; (const_int 0 [0]))
4544 ;; (and:DI (lshiftrt:DI (reg/v:DI 50 [ s ])
4545 ;; (const_int 40 [0x28]))
4546 ;; (subreg:DI (reg:SI 4 %r4 [ y+4 ]) 0)))
4547 ;;
4548 ;; by noticing that we can push down the outer paradoxical subreg
4549 ;; into the operation.
4550
4551 (define_insn "*insv_rnsbg_noshift"
4552 [(set (zero_extract:DI
4553 (match_operand:DI 0 "nonimmediate_operand" "+d")
4554 (match_operand 1 "const_int_operand" "")
4555 (match_operand 2 "const_int_operand" ""))
4556 (and:DI
4557 (match_dup 0)
4558 (match_operand:DI 3 "nonimmediate_operand" "d")))
4559 (clobber (reg:CC CC_REGNUM))]
4560 "TARGET_Z10
4561 && EXTRACT_ARGS_IN_RANGE (INTVAL (operands[1]), INTVAL (operands[2]), 64)
4562 && INTVAL (operands[1]) + INTVAL (operands[2]) == 64"
4563 "rnsbg\t%0,%3,%2,63,0"
4564 [(set_attr "op_type" "RIE")])
4565
4566 (define_insn "*insv_rnsbg_srl"
4567 [(set (zero_extract:DI
4568 (match_operand:DI 0 "nonimmediate_operand" "+d")
4569 (match_operand 1 "const_int_operand" "")
4570 (match_operand 2 "const_int_operand" ""))
4571 (and:DI
4572 (lshiftrt:DI
4573 (match_dup 0)
4574 (match_operand 3 "const_int_operand" ""))
4575 (match_operand:DI 4 "nonimmediate_operand" "d")))
4576 (clobber (reg:CC CC_REGNUM))]
4577 "TARGET_Z10
4578 && EXTRACT_ARGS_IN_RANGE (INTVAL (operands[1]), INTVAL (operands[2]), 64)
4579 && INTVAL (operands[3]) == 64 - INTVAL (operands[1]) - INTVAL (operands[2])"
4580 "rnsbg\t%0,%4,%2,%2+%1-1,%3"
4581 [(set_attr "op_type" "RIE")])
4582
4583 (define_insn "*insv<mode>_mem_reg"
4584 [(set (zero_extract:W (match_operand:QI 0 "memory_operand" "+Q,S")
4585 (match_operand 1 "const_int_operand" "n,n")
4586 (const_int 0))
4587 (match_operand:W 2 "register_operand" "d,d"))]
4588 "EXTRACT_ARGS_IN_RANGE (INTVAL (operands[1]), 0, 64)
4589 && INTVAL (operands[1]) > 0
4590 && INTVAL (operands[1]) <= GET_MODE_BITSIZE (SImode)
4591 && INTVAL (operands[1]) % BITS_PER_UNIT == 0"
4592 {
4593 int size = INTVAL (operands[1]) / BITS_PER_UNIT;
4594
4595 operands[1] = GEN_INT ((HOST_WIDE_INT_1U << size) - 1);
4596 return (which_alternative == 0) ? "stcm\t%2,%1,%S0"
4597 : "stcmy\t%2,%1,%S0";
4598 }
4599 [(set_attr "op_type" "RS,RSY")
4600 (set_attr "cpu_facility" "*,longdisp")
4601 (set_attr "z10prop" "z10_super,z10_super")])
4602
4603 (define_insn "*insvdi_mem_reghigh"
4604 [(set (zero_extract:DI (match_operand:QI 0 "memory_operand" "+S")
4605 (match_operand 1 "const_int_operand" "n")
4606 (const_int 0))
4607 (lshiftrt:DI (match_operand:DI 2 "register_operand" "d")
4608 (const_int 32)))]
4609 "TARGET_ZARCH
4610 && EXTRACT_ARGS_IN_RANGE (INTVAL (operands[1]), 0, 64)
4611 && INTVAL (operands[1]) > 0
4612 && INTVAL (operands[1]) <= GET_MODE_BITSIZE (SImode)
4613 && INTVAL (operands[1]) % BITS_PER_UNIT == 0"
4614 {
4615 int size = INTVAL (operands[1]) / BITS_PER_UNIT;
4616
4617 operands[1] = GEN_INT ((HOST_WIDE_INT_1U << size) - 1);
4618 return "stcmh\t%2,%1,%S0";
4619 }
4620 [(set_attr "op_type" "RSY")
4621 (set_attr "z10prop" "z10_super")])
4622
4623 (define_insn "*insvdi_reg_imm"
4624 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+d")
4625 (const_int 16)
4626 (match_operand 1 "const_int_operand" "n"))
4627 (match_operand:DI 2 "const_int_operand" "n"))]
4628 "TARGET_ZARCH
4629 && EXTRACT_ARGS_IN_RANGE (16, INTVAL (operands[1]), 64)
4630 && INTVAL (operands[1]) >= 0
4631 && INTVAL (operands[1]) < BITS_PER_WORD
4632 && INTVAL (operands[1]) % 16 == 0"
4633 {
4634 switch (BITS_PER_WORD - INTVAL (operands[1]))
4635 {
4636 case 64: return "iihh\t%0,%x2"; break;
4637 case 48: return "iihl\t%0,%x2"; break;
4638 case 32: return "iilh\t%0,%x2"; break;
4639 case 16: return "iill\t%0,%x2"; break;
4640 default: gcc_unreachable();
4641 }
4642 }
4643 [(set_attr "op_type" "RI")
4644 (set_attr "z10prop" "z10_super_E1")])
4645
4646 ; Update the left-most 32 bit of a DI.
4647 (define_insn "*insv_h_di_reg_extimm"
4648 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+d")
4649 (const_int 32)
4650 (const_int 0))
4651 (match_operand:DI 1 "const_int_operand" "n"))]
4652 "TARGET_EXTIMM"
4653 "iihf\t%0,%o1"
4654 [(set_attr "op_type" "RIL")
4655 (set_attr "z10prop" "z10_fwd_E1")])
4656
4657 ; Update the right-most 32 bit of a DI.
4658 (define_insn "*insv_l_di_reg_extimm"
4659 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+d")
4660 (const_int 32)
4661 (const_int 32))
4662 (match_operand:DI 1 "const_int_operand" "n"))]
4663 "TARGET_EXTIMM"
4664 "iilf\t%0,%o1"
4665 [(set_attr "op_type" "RIL")
4666 (set_attr "z10prop" "z10_fwd_A1")])
4667
4668 ;
4669 ; extendsidi2 instruction pattern(s).
4670 ;
4671
4672 (define_expand "extendsidi2"
4673 [(set (match_operand:DI 0 "register_operand" "")
4674 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "")))]
4675 ""
4676 {
4677 if (!TARGET_ZARCH)
4678 {
4679 emit_clobber (operands[0]);
4680 emit_move_insn (gen_highpart (SImode, operands[0]), operands[1]);
4681 emit_move_insn (gen_lowpart (SImode, operands[0]), const0_rtx);
4682 emit_insn (gen_ashrdi3 (operands[0], operands[0], GEN_INT (32)));
4683 DONE;
4684 }
4685 })
4686
4687 (define_insn "*extendsidi2"
4688 [(set (match_operand:DI 0 "register_operand" "=d,d,d")
4689 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "d,T,b")))]
4690 "TARGET_ZARCH"
4691 "@
4692 lgfr\t%0,%1
4693 lgf\t%0,%1
4694 lgfrl\t%0,%1"
4695 [(set_attr "op_type" "RRE,RXY,RIL")
4696 (set_attr "type" "*,*,larl")
4697 (set_attr "cpu_facility" "*,*,z10")
4698 (set_attr "z10prop" "z10_super_E1,z10_super_E1,z10_super_E1")
4699 (set_attr "relative_long" "*,*,yes")])
4700
4701 ;
4702 ; extend(hi|qi)(si|di)2 instruction pattern(s).
4703 ;
4704
4705 (define_expand "extend<HQI:mode><DSI:mode>2"
4706 [(set (match_operand:DSI 0 "register_operand" "")
4707 (sign_extend:DSI (match_operand:HQI 1 "nonimmediate_operand" "")))]
4708 ""
4709 {
4710 if (<DSI:MODE>mode == DImode && !TARGET_ZARCH)
4711 {
4712 rtx tmp = gen_reg_rtx (SImode);
4713 emit_insn (gen_extend<HQI:mode>si2 (tmp, operands[1]));
4714 emit_insn (gen_extendsidi2 (operands[0], tmp));
4715 DONE;
4716 }
4717 else if (!TARGET_EXTIMM)
4718 {
4719 rtx bitcount = GEN_INT (<DSI:bitsize> - <HQI:bitsize>);
4720
4721 operands[1] = gen_lowpart (<DSI:MODE>mode, operands[1]);
4722 emit_insn (gen_ashl<DSI:mode>3 (operands[0], operands[1], bitcount));
4723 emit_insn (gen_ashr<DSI:mode>3 (operands[0], operands[0], bitcount));
4724 DONE;
4725 }
4726 })
4727
4728 ;
4729 ; extendhidi2 instruction pattern(s).
4730 ;
4731
4732 (define_insn "*extendhidi2_extimm"
4733 [(set (match_operand:DI 0 "register_operand" "=d,d,d")
4734 (sign_extend:DI (match_operand:HI 1 "general_operand" "d,T,b")))]
4735 "TARGET_ZARCH && TARGET_EXTIMM"
4736 "@
4737 lghr\t%0,%1
4738 lgh\t%0,%1
4739 lghrl\t%0,%1"
4740 [(set_attr "op_type" "RRE,RXY,RIL")
4741 (set_attr "type" "*,*,larl")
4742 (set_attr "cpu_facility" "extimm,extimm,z10")
4743 (set_attr "z10prop" "z10_super_E1,z10_super_E1,z10_super_E1")
4744 (set_attr "relative_long" "*,*,yes")])
4745
4746 (define_insn "*extendhidi2"
4747 [(set (match_operand:DI 0 "register_operand" "=d")
4748 (sign_extend:DI (match_operand:HI 1 "memory_operand" "T")))]
4749 "TARGET_ZARCH"
4750 "lgh\t%0,%1"
4751 [(set_attr "op_type" "RXY")
4752 (set_attr "z10prop" "z10_super_E1")])
4753
4754 ;
4755 ; extendhisi2 instruction pattern(s).
4756 ;
4757
4758 (define_insn "*extendhisi2_extimm"
4759 [(set (match_operand:SI 0 "register_operand" "=d,d,d,d")
4760 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" " d,R,T,b")))]
4761 "TARGET_EXTIMM"
4762 "@
4763 lhr\t%0,%1
4764 lh\t%0,%1
4765 lhy\t%0,%1
4766 lhrl\t%0,%1"
4767 [(set_attr "op_type" "RRE,RX,RXY,RIL")
4768 (set_attr "type" "*,*,*,larl")
4769 (set_attr "cpu_facility" "extimm,extimm,extimm,z10")
4770 (set_attr "z10prop" "z10_super_E1,z10_super_E1,z10_super_E1,z10_super_E1")
4771 (set_attr "relative_long" "*,*,*,yes")])
4772
4773 (define_insn "*extendhisi2"
4774 [(set (match_operand:SI 0 "register_operand" "=d,d")
4775 (sign_extend:SI (match_operand:HI 1 "memory_operand" "R,T")))]
4776 "!TARGET_EXTIMM"
4777 "@
4778 lh\t%0,%1
4779 lhy\t%0,%1"
4780 [(set_attr "op_type" "RX,RXY")
4781 (set_attr "cpu_facility" "*,longdisp")
4782 (set_attr "z10prop" "z10_super_E1,z10_super_E1")])
4783
4784 ;
4785 ; extendqi(si|di)2 instruction pattern(s).
4786 ;
4787
4788 ; lbr, lgbr, lb, lgb
4789 (define_insn "*extendqi<mode>2_extimm"
4790 [(set (match_operand:GPR 0 "register_operand" "=d,d")
4791 (sign_extend:GPR (match_operand:QI 1 "nonimmediate_operand" "d,T")))]
4792 "TARGET_EXTIMM"
4793 "@
4794 l<g>br\t%0,%1
4795 l<g>b\t%0,%1"
4796 [(set_attr "op_type" "RRE,RXY")
4797 (set_attr "z10prop" "z10_super_E1,z10_super_E1")])
4798
4799 ; lb, lgb
4800 (define_insn "*extendqi<mode>2"
4801 [(set (match_operand:GPR 0 "register_operand" "=d")
4802 (sign_extend:GPR (match_operand:QI 1 "memory_operand" "T")))]
4803 "!TARGET_EXTIMM && TARGET_LONG_DISPLACEMENT"
4804 "l<g>b\t%0,%1"
4805 [(set_attr "op_type" "RXY")
4806 (set_attr "z10prop" "z10_super_E1")])
4807
4808 (define_insn_and_split "*extendqi<mode>2_short_displ"
4809 [(set (match_operand:GPR 0 "register_operand" "=d")
4810 (sign_extend:GPR (match_operand:QI 1 "s_operand" "Q")))
4811 (clobber (reg:CC CC_REGNUM))]
4812 "!TARGET_EXTIMM && !TARGET_LONG_DISPLACEMENT"
4813 "#"
4814 "&& reload_completed"
4815 [(parallel
4816 [(set (match_dup 0) (unspec:GPR [(match_dup 1) (const_int 8)] UNSPEC_ICM))
4817 (clobber (reg:CC CC_REGNUM))])
4818 (parallel
4819 [(set (match_dup 0) (ashiftrt:GPR (match_dup 0) (match_dup 2)))
4820 (clobber (reg:CC CC_REGNUM))])]
4821 {
4822 operands[1] = adjust_address (operands[1], BLKmode, 0);
4823 set_mem_size (operands[1], GET_MODE_SIZE (QImode));
4824 operands[2] = GEN_INT (<GPR:bitsize> - BITS_PER_UNIT);
4825 })
4826
4827 ;
4828 ; zero_extendsidi2 instruction pattern(s).
4829 ;
4830
4831 (define_expand "zero_extendsidi2"
4832 [(set (match_operand:DI 0 "register_operand" "")
4833 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "")))]
4834 ""
4835 {
4836 if (!TARGET_ZARCH)
4837 {
4838 emit_clobber (operands[0]);
4839 emit_move_insn (gen_lowpart (SImode, operands[0]), operands[1]);
4840 emit_move_insn (gen_highpart (SImode, operands[0]), const0_rtx);
4841 DONE;
4842 }
4843 })
4844
4845 (define_insn "*zero_extendsidi2"
4846 [(set (match_operand:DI 0 "register_operand" "=d,d,d")
4847 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "d,T,b")))]
4848 "TARGET_ZARCH"
4849 "@
4850 llgfr\t%0,%1
4851 llgf\t%0,%1
4852 llgfrl\t%0,%1"
4853 [(set_attr "op_type" "RRE,RXY,RIL")
4854 (set_attr "type" "*,*,larl")
4855 (set_attr "cpu_facility" "*,*,z10")
4856 (set_attr "z10prop" "z10_fwd_E1,z10_fwd_A3,z10_fwd_A3")
4857 (set_attr "relative_long" "*,*,yes")])
4858
4859 ;
4860 ; LLGT-type instructions (zero-extend from 31 bit to 64 bit).
4861 ;
4862
4863 (define_insn "*llgt_sidi"
4864 [(set (match_operand:DI 0 "register_operand" "=d")
4865 (and:DI (subreg:DI (match_operand:SI 1 "memory_operand" "T") 0)
4866 (const_int 2147483647)))]
4867 "TARGET_ZARCH"
4868 "llgt\t%0,%1"
4869 [(set_attr "op_type" "RXE")
4870 (set_attr "z10prop" "z10_super_E1")])
4871
4872 (define_insn_and_split "*llgt_sidi_split"
4873 [(set (match_operand:DI 0 "register_operand" "=d")
4874 (and:DI (subreg:DI (match_operand:SI 1 "memory_operand" "T") 0)
4875 (const_int 2147483647)))
4876 (clobber (reg:CC CC_REGNUM))]
4877 "TARGET_ZARCH"
4878 "#"
4879 "&& reload_completed"
4880 [(set (match_dup 0)
4881 (and:DI (subreg:DI (match_dup 1) 0)
4882 (const_int 2147483647)))]
4883 "")
4884
4885 (define_insn "*llgt_sisi"
4886 [(set (match_operand:SI 0 "register_operand" "=d,d")
4887 (and:SI (match_operand:SI 1 "nonimmediate_operand" "d,T")
4888 (const_int 2147483647)))]
4889 "TARGET_ZARCH"
4890 "@
4891 llgtr\t%0,%1
4892 llgt\t%0,%1"
4893 [(set_attr "op_type" "RRE,RXE")
4894 (set_attr "z10prop" "z10_super_E1,z10_super_E1")])
4895
4896 (define_insn "*llgt_didi"
4897 [(set (match_operand:DI 0 "register_operand" "=d,d")
4898 (and:DI (match_operand:DI 1 "nonimmediate_operand" "d,o")
4899 (const_int 2147483647)))]
4900 "TARGET_ZARCH"
4901 "@
4902 llgtr\t%0,%1
4903 llgt\t%0,%N1"
4904 [(set_attr "op_type" "RRE,RXE")
4905 (set_attr "z10prop" "z10_super_E1,z10_super_E1")])
4906
4907 (define_split
4908 [(set (match_operand:DSI 0 "register_operand" "")
4909 (and:DSI (match_operand:DSI 1 "nonimmediate_operand" "")
4910 (const_int 2147483647)))
4911 (clobber (reg:CC CC_REGNUM))]
4912 "TARGET_ZARCH && reload_completed"
4913 [(set (match_dup 0)
4914 (and:DSI (match_dup 1)
4915 (const_int 2147483647)))]
4916 "")
4917
4918 ;
4919 ; zero_extend(hi|qi)(si|di)2 instruction pattern(s).
4920 ;
4921
4922 (define_expand "zero_extend<mode>di2"
4923 [(set (match_operand:DI 0 "register_operand" "")
4924 (zero_extend:DI (match_operand:HQI 1 "nonimmediate_operand" "")))]
4925 ""
4926 {
4927 if (!TARGET_ZARCH)
4928 {
4929 rtx tmp = gen_reg_rtx (SImode);
4930 emit_insn (gen_zero_extend<mode>si2 (tmp, operands[1]));
4931 emit_insn (gen_zero_extendsidi2 (operands[0], tmp));
4932 DONE;
4933 }
4934 else if (!TARGET_EXTIMM)
4935 {
4936 rtx bitcount = GEN_INT (64 - <HQI:bitsize>);
4937 operands[1] = gen_lowpart (DImode, operands[1]);
4938 emit_insn (gen_ashldi3 (operands[0], operands[1], bitcount));
4939 emit_insn (gen_lshrdi3 (operands[0], operands[0], bitcount));
4940 DONE;
4941 }
4942 })
4943
4944 (define_expand "zero_extend<mode>si2"
4945 [(set (match_operand:SI 0 "register_operand" "")
4946 (zero_extend:SI (match_operand:HQI 1 "nonimmediate_operand" "")))]
4947 ""
4948 {
4949 if (!TARGET_EXTIMM)
4950 {
4951 operands[1] = gen_lowpart (SImode, operands[1]);
4952 emit_insn (gen_andsi3 (operands[0], operands[1],
4953 GEN_INT ((1 << <HQI:bitsize>) - 1)));
4954 DONE;
4955 }
4956 })
4957
4958 ; llhrl, llghrl
4959 (define_insn "*zero_extendhi<mode>2_z10"
4960 [(set (match_operand:GPR 0 "register_operand" "=d,d,d")
4961 (zero_extend:GPR (match_operand:HI 1 "nonimmediate_operand" "d,T,b")))]
4962 "TARGET_Z10"
4963 "@
4964 ll<g>hr\t%0,%1
4965 ll<g>h\t%0,%1
4966 ll<g>hrl\t%0,%1"
4967 [(set_attr "op_type" "RXY,RRE,RIL")
4968 (set_attr "type" "*,*,larl")
4969 (set_attr "cpu_facility" "*,*,z10")
4970 (set_attr "z10prop" "z10_super_E1,z10_fwd_A3,z10_fwd_A3")
4971 (set_attr "relative_long" "*,*,yes")])
4972
4973 ; llhr, llcr, llghr, llgcr, llh, llc, llgh, llgc
4974 (define_insn "*zero_extend<HQI:mode><GPR:mode>2_extimm"
4975 [(set (match_operand:GPR 0 "register_operand" "=d,d")
4976 (zero_extend:GPR (match_operand:HQI 1 "nonimmediate_operand" "d,T")))]
4977 "TARGET_EXTIMM"
4978 "@
4979 ll<g><hc>r\t%0,%1
4980 ll<g><hc>\t%0,%1"
4981 [(set_attr "op_type" "RRE,RXY")
4982 (set_attr "z10prop" "z10_super_E1,z10_fwd_A3")])
4983
4984 ; llgh, llgc
4985 (define_insn "*zero_extend<HQI:mode><GPR:mode>2"
4986 [(set (match_operand:GPR 0 "register_operand" "=d")
4987 (zero_extend:GPR (match_operand:HQI 1 "memory_operand" "T")))]
4988 "TARGET_ZARCH && !TARGET_EXTIMM"
4989 "llg<hc>\t%0,%1"
4990 [(set_attr "op_type" "RXY")
4991 (set_attr "z10prop" "z10_fwd_A3")])
4992
4993 (define_insn_and_split "*zero_extendhisi2_31"
4994 [(set (match_operand:SI 0 "register_operand" "=&d")
4995 (zero_extend:SI (match_operand:HI 1 "s_operand" "S")))
4996 (clobber (reg:CC CC_REGNUM))]
4997 "!TARGET_ZARCH"
4998 "#"
4999 "&& reload_completed"
5000 [(set (match_dup 0) (const_int 0))
5001 (parallel
5002 [(set (strict_low_part (match_dup 2)) (match_dup 1))
5003 (clobber (reg:CC CC_REGNUM))])]
5004 "operands[2] = gen_lowpart (HImode, operands[0]);")
5005
5006 (define_insn_and_split "*zero_extendqisi2_31"
5007 [(set (match_operand:SI 0 "register_operand" "=&d")
5008 (zero_extend:SI (match_operand:QI 1 "memory_operand" "T")))]
5009 "!TARGET_ZARCH"
5010 "#"
5011 "&& reload_completed"
5012 [(set (match_dup 0) (const_int 0))
5013 (set (strict_low_part (match_dup 2)) (match_dup 1))]
5014 "operands[2] = gen_lowpart (QImode, operands[0]);")
5015
5016 ;
5017 ; zero_extendqihi2 instruction pattern(s).
5018 ;
5019
5020 (define_expand "zero_extendqihi2"
5021 [(set (match_operand:HI 0 "register_operand" "")
5022 (zero_extend:HI (match_operand:QI 1 "register_operand" "")))]
5023 "TARGET_ZARCH && !TARGET_EXTIMM"
5024 {
5025 operands[1] = gen_lowpart (HImode, operands[1]);
5026 emit_insn (gen_andhi3 (operands[0], operands[1], GEN_INT (0xff)));
5027 DONE;
5028 })
5029
5030 (define_insn "*zero_extendqihi2_64"
5031 [(set (match_operand:HI 0 "register_operand" "=d")
5032 (zero_extend:HI (match_operand:QI 1 "memory_operand" "T")))]
5033 "TARGET_ZARCH && !TARGET_EXTIMM"
5034 "llgc\t%0,%1"
5035 [(set_attr "op_type" "RXY")
5036 (set_attr "z10prop" "z10_fwd_A3")])
5037
5038 (define_insn_and_split "*zero_extendqihi2_31"
5039 [(set (match_operand:HI 0 "register_operand" "=&d")
5040 (zero_extend:HI (match_operand:QI 1 "memory_operand" "T")))]
5041 "!TARGET_ZARCH"
5042 "#"
5043 "&& reload_completed"
5044 [(set (match_dup 0) (const_int 0))
5045 (set (strict_low_part (match_dup 2)) (match_dup 1))]
5046 "operands[2] = gen_lowpart (QImode, operands[0]);")
5047
5048 ;
5049 ; fixuns_trunc(dd|td|sf|df|tf)(si|di)2 expander
5050 ;
5051
5052 ; This is the only entry point for fixuns_trunc. It multiplexes the
5053 ; expansion to either the *_emu expanders below for pre z196 machines
5054 ; or emits the default pattern otherwise.
5055 (define_expand "fixuns_trunc<FP:mode><GPR:mode>2<FP:tf_fpr>"
5056 [(parallel
5057 [(set (match_operand:GPR 0 "register_operand" "")
5058 (unsigned_fix:GPR (match_operand:FP 1 "register_operand" "")))
5059 (unspec:GPR [(match_dup 2)] UNSPEC_ROUND)
5060 (clobber (reg:CC CC_REGNUM))])]
5061 "TARGET_HARD_FLOAT"
5062 {
5063 if (!TARGET_Z196)
5064 {
5065 /* We don't provide emulation for TD|DD->SI. */
5066 if (GET_MODE_CLASS (<FP:MODE>mode) == MODE_DECIMAL_FLOAT
5067 && <GPR:MODE>mode == SImode)
5068 FAIL;
5069 emit_insn (gen_fixuns_trunc<FP:mode><GPR:mode>2_emu (operands[0],
5070 operands[1]));
5071 DONE;
5072 }
5073
5074 if (GET_MODE_CLASS (<FP:MODE>mode) == MODE_DECIMAL_FLOAT)
5075 operands[2] = GEN_INT (DFP_RND_TOWARD_0);
5076 else
5077 operands[2] = GEN_INT (BFP_RND_TOWARD_0);
5078 })
5079
5080 ; (sf|df|tf)->unsigned (si|di)
5081
5082 ; Emulate the unsigned conversion with the signed version for pre z196
5083 ; machines.
5084 (define_expand "fixuns_trunc<BFP:mode><GPR:mode>2_emu"
5085 [(parallel
5086 [(set (match_operand:GPR 0 "register_operand" "")
5087 (unsigned_fix:GPR (match_operand:BFP 1 "register_operand" "")))
5088 (unspec:GPR [(const_int BFP_RND_TOWARD_0)] UNSPEC_ROUND)
5089 (clobber (reg:CC CC_REGNUM))])]
5090 "!TARGET_Z196 && TARGET_HARD_FLOAT"
5091 {
5092 rtx_code_label *label1 = gen_label_rtx ();
5093 rtx_code_label *label2 = gen_label_rtx ();
5094 rtx temp = gen_reg_rtx (<BFP:MODE>mode);
5095 REAL_VALUE_TYPE cmp, sub;
5096
5097 operands[1] = force_reg (<BFP:MODE>mode, operands[1]);
5098 real_2expN (&cmp, <GPR:bitsize> - 1, <BFP:MODE>mode);
5099 real_2expN (&sub, <GPR:bitsize>, <BFP:MODE>mode);
5100
5101 emit_cmp_and_jump_insns (operands[1],
5102 const_double_from_real_value (cmp, <BFP:MODE>mode),
5103 LT, NULL_RTX, VOIDmode, 0, label1);
5104 emit_insn (gen_sub<BFP:mode>3 (temp, operands[1],
5105 const_double_from_real_value (sub, <BFP:MODE>mode)));
5106 emit_insn (gen_fix_trunc<BFP:mode><GPR:mode>2_bfp (operands[0], temp,
5107 GEN_INT (BFP_RND_TOWARD_MINF)));
5108 emit_jump (label2);
5109
5110 emit_label (label1);
5111 emit_insn (gen_fix_trunc<BFP:mode><GPR:mode>2_bfp (operands[0],
5112 operands[1],
5113 GEN_INT (BFP_RND_TOWARD_0)));
5114 emit_label (label2);
5115 DONE;
5116 })
5117
5118 ; dd->unsigned di
5119
5120 ; Emulate the unsigned conversion with the signed version for pre z196
5121 ; machines.
5122 (define_expand "fixuns_truncdddi2_emu"
5123 [(parallel
5124 [(set (match_operand:DI 0 "register_operand" "")
5125 (unsigned_fix:DI (match_operand:DD 1 "register_operand" "")))
5126 (unspec:DI [(const_int DFP_RND_TOWARD_0)] UNSPEC_ROUND)
5127 (clobber (reg:CC CC_REGNUM))])]
5128
5129 "!TARGET_Z196 && TARGET_HARD_DFP"
5130 {
5131 rtx_code_label *label1 = gen_label_rtx ();
5132 rtx_code_label *label2 = gen_label_rtx ();
5133 rtx temp = gen_reg_rtx (TDmode);
5134 REAL_VALUE_TYPE cmp, sub;
5135
5136 decimal_real_from_string (&cmp, "9223372036854775808.0"); /* 2^63 */
5137 decimal_real_from_string (&sub, "18446744073709551616.0"); /* 2^64 */
5138
5139 /* 2^63 can't be represented as 64bit DFP number with full precision. The
5140 solution is doing the check and the subtraction in TD mode and using a
5141 TD -> DI convert afterwards. */
5142 emit_insn (gen_extendddtd2 (temp, operands[1]));
5143 temp = force_reg (TDmode, temp);
5144 emit_cmp_and_jump_insns (temp,
5145 const_double_from_real_value (cmp, TDmode),
5146 LT, NULL_RTX, VOIDmode, 0, label1);
5147 emit_insn (gen_subtd3 (temp, temp,
5148 const_double_from_real_value (sub, TDmode)));
5149 emit_insn (gen_fix_trunctddi2_dfp (operands[0], temp,
5150 GEN_INT (DFP_RND_TOWARD_MINF)));
5151 emit_jump (label2);
5152
5153 emit_label (label1);
5154 emit_insn (gen_fix_truncdddi2_dfp (operands[0], operands[1],
5155 GEN_INT (DFP_RND_TOWARD_0)));
5156 emit_label (label2);
5157 DONE;
5158 })
5159
5160 ; td->unsigned di
5161
5162 ; Emulate the unsigned conversion with the signed version for pre z196
5163 ; machines.
5164 (define_expand "fixuns_trunctddi2_emu"
5165 [(parallel
5166 [(set (match_operand:DI 0 "register_operand" "")
5167 (unsigned_fix:DI (match_operand:TD 1 "register_operand" "")))
5168 (unspec:DI [(const_int DFP_RND_TOWARD_0)] UNSPEC_ROUND)
5169 (clobber (reg:CC CC_REGNUM))])]
5170
5171 "!TARGET_Z196 && TARGET_HARD_DFP"
5172 {
5173 rtx_code_label *label1 = gen_label_rtx ();
5174 rtx_code_label *label2 = gen_label_rtx ();
5175 rtx temp = gen_reg_rtx (TDmode);
5176 REAL_VALUE_TYPE cmp, sub;
5177
5178 operands[1] = force_reg (TDmode, operands[1]);
5179 decimal_real_from_string (&cmp, "9223372036854775808.0"); /* 2^63 */
5180 decimal_real_from_string (&sub, "18446744073709551616.0"); /* 2^64 */
5181
5182 emit_cmp_and_jump_insns (operands[1],
5183 const_double_from_real_value (cmp, TDmode),
5184 LT, NULL_RTX, VOIDmode, 0, label1);
5185 emit_insn (gen_subtd3 (temp, operands[1],
5186 const_double_from_real_value (sub, TDmode)));
5187 emit_insn (gen_fix_trunctddi2_dfp (operands[0], temp,
5188 GEN_INT (DFP_RND_TOWARD_MINF)));
5189 emit_jump (label2);
5190
5191 emit_label (label1);
5192 emit_insn (gen_fix_trunctddi2_dfp (operands[0], operands[1],
5193 GEN_INT (DFP_RND_TOWARD_0)));
5194 emit_label (label2);
5195 DONE;
5196 })
5197
5198 ; Just a dummy to make the code in the first expander a bit easier.
5199 (define_expand "fixuns_trunc<mode>si2_emu"
5200 [(parallel
5201 [(set (match_operand:SI 0 "register_operand" "")
5202 (unsigned_fix:SI (match_operand:DFP 1 "register_operand" "")))
5203 (unspec:DI [(const_int DFP_RND_TOWARD_0)] UNSPEC_ROUND)
5204 (clobber (reg:CC CC_REGNUM))])]
5205
5206 "!TARGET_Z196 && TARGET_HARD_DFP"
5207 {
5208 FAIL;
5209 })
5210
5211
5212 ; fixuns_trunc(tf|df|sf|td|dd)(di|si)2 instruction patterns.
5213
5214 ; df -> unsigned di, vxe2: sf -> unsigned si
5215 ; clgdbr, clfebr, wclgdb, wclfeb
5216 (define_insn "*fixuns_trunc<VX_CONV_BFP:mode><VX_CONV_INT:mode>2_z13"
5217 [(set (match_operand:VX_CONV_INT 0 "register_operand" "=d,v")
5218 (unsigned_fix:VX_CONV_INT (match_operand:VX_CONV_BFP 1 "register_operand" "f,v")))
5219 (unspec:DI [(match_operand:DI 2 "immediate_operand" "K,K")] UNSPEC_ROUND)
5220 (clobber (reg:CC CC_REGNUM))]
5221 "TARGET_VX && TARGET_HARD_FLOAT
5222 && GET_MODE_SIZE (<VX_CONV_INT:MODE>mode) == GET_MODE_SIZE (<VX_CONV_BFP:MODE>mode)"
5223 "@
5224 cl<VX_CONV_INT:gf><VX_CONV_BFP:xde>br\t%0,%h2,%1,0
5225 wcl<VX_CONV_INT:gf><VX_CONV_BFP:xde>b\t%v0,%v1,0,%h2"
5226 [(set_attr "op_type" "RRF,VRR")
5227 (set_attr "type" "ftoi")])
5228
5229 ; (dd|td|sf|df|tf)->unsigned (di|si)
5230 ; clfebr, clfdbr, clfxbr, clgebr, clgdbr, clgxbr
5231 ; clfdtr, clfxtr, clgdtr, clgxtr
5232 (define_insn "*fixuns_trunc<FP:mode><GPR:mode>2_z196"
5233 [(set (match_operand:GPR 0 "register_operand" "=d")
5234 (unsigned_fix:GPR (match_operand:FP 1 "register_operand" "f")))
5235 (unspec:GPR [(match_operand:GPR 2 "immediate_operand" "K")] UNSPEC_ROUND)
5236 (clobber (reg:CC CC_REGNUM))]
5237 "TARGET_Z196 && TARGET_HARD_FLOAT
5238 && (!TARGET_VX || <GPR:MODE>mode != DImode || <FP:MODE>mode != DFmode)"
5239 "cl<GPR:gf><FP:xde><FP:bt>r\t%0,%h2,%1,0"
5240 [(set_attr "op_type" "RRF")
5241 (set_attr "type" "ftoi")])
5242
5243 (define_expand "fix_trunc<DSF:mode><GPR:mode>2"
5244 [(set (match_operand:GPR 0 "register_operand" "")
5245 (fix:GPR (match_operand:DSF 1 "register_operand" "")))]
5246 "TARGET_HARD_FLOAT"
5247 {
5248 emit_insn (gen_fix_trunc<DSF:mode><GPR:mode>2_bfp (operands[0], operands[1],
5249 GEN_INT (BFP_RND_TOWARD_0)));
5250 DONE;
5251 })
5252
5253 ; df -> signed di, vxe2: sf -> signed si
5254 ; cgdbr, cfebr, wcgdb, wcfeb
5255 (define_insn "*fix_trunc<VX_CONV_BFP:mode><VX_CONV_INT:mode>2_bfp_z13"
5256 [(set (match_operand:VX_CONV_INT 0 "register_operand" "=d,v")
5257 (fix:VX_CONV_INT (match_operand:VX_CONV_BFP 1 "register_operand" "f,v")))
5258 (unspec:VX_CONV_INT [(match_operand:VX_CONV_INT 2 "immediate_operand" "K,K")] UNSPEC_ROUND)
5259 (clobber (reg:CC CC_REGNUM))]
5260 "TARGET_VX && TARGET_HARD_FLOAT
5261 && GET_MODE_SIZE (<VX_CONV_INT:MODE>mode) == GET_MODE_SIZE (<VX_CONV_BFP:MODE>mode)"
5262 "@
5263 c<VX_CONV_INT:gf><VX_CONV_BFP:xde>br\t%0,%h2,%1
5264 wc<VX_CONV_INT:gf><VX_CONV_BFP:xde>b\t%v0,%v1,0,%h2"
5265 [(set_attr "op_type" "RRE,VRR")
5266 (set_attr "type" "ftoi")])
5267
5268 ; cgxbr, cgdbr, cgebr, cfxbr, cfdbr, cfebr
5269 (define_insn "*fix_trunc<BFP:mode><GPR:mode>2_bfp"
5270 [(set (match_operand:GPR 0 "register_operand" "=d")
5271 (fix:GPR (match_operand:BFP 1 "register_operand" "f")))
5272 (unspec:GPR [(match_operand:GPR 2 "immediate_operand" "K")] UNSPEC_ROUND)
5273 (clobber (reg:CC CC_REGNUM))]
5274 "TARGET_HARD_FLOAT
5275 && (!TARGET_VX || <GPR:MODE>mode != DImode || <BFP:MODE>mode != DFmode)"
5276 "c<GPR:gf><BFP:xde>br\t%0,%h2,%1"
5277 [(set_attr "op_type" "RRE")
5278 (set_attr "type" "ftoi")])
5279
5280 (define_expand "fix_trunc<BFP:mode><GPR:mode>2_bfp"
5281 [(parallel
5282 [(set (match_operand:GPR 0 "register_operand" "=d")
5283 (fix:GPR (match_operand:BFP 1 "register_operand" "f")))
5284 (unspec:GPR [(match_operand:GPR 2 "immediate_operand" "K")] UNSPEC_ROUND)
5285 (clobber (reg:CC CC_REGNUM))])]
5286 "TARGET_HARD_FLOAT")
5287 ;
5288 ; fix_trunc(td|dd)di2 instruction pattern(s).
5289 ;
5290
5291 (define_expand "fix_trunc<mode>di2"
5292 [(set (match_operand:DI 0 "register_operand" "")
5293 (fix:DI (match_operand:DFP 1 "nonimmediate_operand" "")))]
5294 "TARGET_ZARCH && TARGET_HARD_DFP"
5295 {
5296 operands[1] = force_reg (<MODE>mode, operands[1]);
5297 emit_insn (gen_fix_trunc<mode>di2_dfp (operands[0], operands[1],
5298 GEN_INT (DFP_RND_TOWARD_0)));
5299 DONE;
5300 })
5301
5302 ; cgxtr, cgdtr
5303 (define_insn "fix_trunc<DFP:mode>di2_dfp"
5304 [(set (match_operand:DI 0 "register_operand" "=d")
5305 (fix:DI (match_operand:DFP 1 "register_operand" "f")))
5306 (unspec:DI [(match_operand:DI 2 "immediate_operand" "K")] UNSPEC_ROUND)
5307 (clobber (reg:CC CC_REGNUM))]
5308 "TARGET_ZARCH && TARGET_HARD_DFP"
5309 "cg<DFP:xde>tr\t%0,%h2,%1"
5310 [(set_attr "op_type" "RRF")
5311 (set_attr "type" "ftoidfp")])
5312
5313
5314 ;
5315 ; fix_trunctf(si|di)2 instruction pattern(s).
5316 ;
5317
5318 (define_expand "fix_trunctf<mode>2_fpr"
5319 [(parallel [(set (match_operand:GPR 0 "register_operand" "")
5320 (fix:GPR (match_operand:TF 1 "register_operand" "")))
5321 (unspec:GPR [(const_int BFP_RND_TOWARD_0)] UNSPEC_ROUND)
5322 (clobber (reg:CC CC_REGNUM))])]
5323 "TARGET_HARD_FLOAT && !TARGET_VXE"
5324 "")
5325
5326
5327 ;
5328 ; float(si|di)(tf|df|sf|td|dd)2 instruction pattern(s).
5329 ;
5330
5331 ; cxgbr, cdgbr, cegbr, cxgtr, cdgtr
5332 (define_insn "floatdi<mode>2<tf_fpr>"
5333 [(set (match_operand:FP 0 "register_operand" "=f,v")
5334 (float:FP (match_operand:DI 1 "register_operand" "d,v")))]
5335 "TARGET_ZARCH && TARGET_HARD_FLOAT"
5336 "@
5337 c<xde>g<bt>r\t%0,%1
5338 wcdgb\t%v0,%v1,0,0"
5339 [(set_attr "op_type" "RRE,VRR")
5340 (set_attr "type" "itof<type>" )
5341 (set_attr "cpu_facility" "*,vx")
5342 (set_attr "enabled" "*,<DFDI>")])
5343
5344 ; cxfbr, cdfbr, cefbr, wcefb
5345 (define_insn "floatsi<mode>2<tf_fpr>"
5346 [(set (match_operand:BFP 0 "register_operand" "=f,v")
5347 (float:BFP (match_operand:SI 1 "register_operand" "d,v")))]
5348 "TARGET_HARD_FLOAT"
5349 "@
5350 c<xde>fbr\t%0,%1
5351 wcefb\t%v0,%v1,0,0"
5352 [(set_attr "op_type" "RRE,VRR")
5353 (set_attr "type" "itof<type>" )
5354 (set_attr "cpu_facility" "*,vxe2")
5355 (set_attr "enabled" "*,<SFSI>")])
5356
5357 ; cxftr, cdftr
5358 (define_insn "floatsi<mode>2"
5359 [(set (match_operand:DFP 0 "register_operand" "=f")
5360 (float:DFP (match_operand:SI 1 "register_operand" "d")))]
5361 "TARGET_Z196 && TARGET_HARD_FLOAT"
5362 "c<xde>ftr\t%0,0,%1,0"
5363 [(set_attr "op_type" "RRE")
5364 (set_attr "type" "itof<type>")])
5365
5366 ;
5367 ; floatuns(si|di)(tf|df|sf|td|dd)2 instruction pattern(s).
5368 ;
5369
5370 (define_insn "*floatuns<VX_CONV_INT:mode><VX_CONV_BFP:mode>2_z13"
5371 [(set (match_operand:VX_CONV_BFP 0 "register_operand" "=f,v")
5372 (unsigned_float:VX_CONV_BFP (match_operand:VX_CONV_INT 1 "register_operand" "d,v")))]
5373 "TARGET_VX && TARGET_HARD_FLOAT
5374 && GET_MODE_SIZE (<VX_CONV_INT:MODE>mode) == GET_MODE_SIZE (<VX_CONV_BFP:MODE>mode)"
5375 "@
5376 c<VX_CONV_BFP:xde>l<VX_CONV_INT:gf>br\t%0,0,%1,0
5377 wc<VX_CONV_BFP:xde>l<VX_CONV_INT:gf>b\t%v0,%v1,0,0"
5378 [(set_attr "op_type" "RRE,VRR")
5379 (set_attr "type" "itofdf")])
5380
5381 ; cxlgbr, cdlgbr, celgbr, cxlgtr, cdlgtr
5382 ; cxlfbr, cdlfbr, celfbr, cxlftr, cdlftr
5383 (define_insn "*floatuns<GPR:mode><FP:mode>2"
5384 [(set (match_operand:FP 0 "register_operand" "=f")
5385 (unsigned_float:FP (match_operand:GPR 1 "register_operand" "d")))]
5386 "TARGET_Z196 && TARGET_HARD_FLOAT
5387 && (!TARGET_VX || <FP:MODE>mode != DFmode || <GPR:MODE>mode != DImode)"
5388 "c<FP:xde>l<GPR:gf><FP:bt>r\t%0,0,%1,0"
5389 [(set_attr "op_type" "RRE")
5390 (set_attr "type" "itof<FP:type>")])
5391
5392 (define_expand "floatuns<GPR:mode><FP:mode>2<tf_fpr>"
5393 [(set (match_operand:FP 0 "register_operand" "")
5394 (unsigned_float:FP (match_operand:GPR 1 "register_operand" "")))]
5395 "TARGET_Z196 && TARGET_HARD_FLOAT")
5396
5397 ;
5398 ; truncdfsf2 instruction pattern(s).
5399 ;
5400
5401 (define_insn "truncdfsf2"
5402 [(set (match_operand:SF 0 "register_operand" "=f,v")
5403 (float_truncate:SF (match_operand:DF 1 "register_operand" "f,v")))]
5404 "TARGET_HARD_FLOAT"
5405 "@
5406 ledbr\t%0,%1
5407 wledb\t%v0,%v1,0,0" ; IEEE inexact exception not suppressed
5408 ; According to BFP rounding mode
5409 [(set_attr "op_type" "RRE,VRR")
5410 (set_attr "type" "ftruncdf")
5411 (set_attr "cpu_facility" "*,vx")])
5412
5413 ;
5414 ; trunctf(df|sf)2 instruction pattern(s).
5415 ;
5416
5417 ; ldxbr, lexbr
5418 (define_insn "trunctf<mode>2_fpr"
5419 [(set (match_operand:DSF 0 "register_operand" "=f")
5420 (float_truncate:DSF (match_operand:TF 1 "register_operand" "f")))
5421 (clobber (match_scratch:TF 2 "=f"))]
5422 "TARGET_HARD_FLOAT"
5423 "l<xde>xbr\t%2,%1\;l<xde>r\t%0,%2"
5424 [(set_attr "length" "6")
5425 (set_attr "type" "ftrunctf")])
5426
5427 ;
5428 ; trunctddd2 and truncddsd2 instruction pattern(s).
5429 ;
5430
5431
5432 (define_expand "trunctddd2"
5433 [(parallel
5434 [(set (match_operand:DD 0 "register_operand" "")
5435 (float_truncate:DD (match_operand:TD 1 "register_operand" "")))
5436 (unspec:DI [(const_int DFP_RND_CURRENT)] UNSPEC_ROUND)
5437 (clobber (scratch:TD))])]
5438 "TARGET_HARD_DFP")
5439
5440 (define_insn "*trunctddd2"
5441 [(set (match_operand:DD 0 "register_operand" "=f")
5442 (float_truncate:DD (match_operand:TD 1 "register_operand" "f")))
5443 (unspec:DI [(match_operand:DI 2 "const_mask_operand" "I")] UNSPEC_ROUND)
5444 (clobber (match_scratch:TD 3 "=f"))]
5445 "TARGET_HARD_DFP"
5446 "ldxtr\t%3,%2,%1,0\;ldr\t%0,%3"
5447 [(set_attr "length" "6")
5448 (set_attr "type" "ftruncdd")])
5449
5450 (define_insn "truncddsd2"
5451 [(set (match_operand:SD 0 "register_operand" "=f")
5452 (float_truncate:SD (match_operand:DD 1 "register_operand" "f")))]
5453 "TARGET_HARD_DFP"
5454 "ledtr\t%0,0,%1,0"
5455 [(set_attr "op_type" "RRF")
5456 (set_attr "type" "ftruncsd")])
5457
5458 (define_expand "trunctdsd2"
5459 [(parallel
5460 [(set (match_dup 2)
5461 (float_truncate:DD (match_operand:TD 1 "register_operand" "")))
5462 (unspec:DI [(const_int DFP_RND_PREP_FOR_SHORT_PREC)] UNSPEC_ROUND)
5463 (clobber (match_scratch:TD 3 ""))])
5464 (set (match_operand:SD 0 "register_operand" "")
5465 (float_truncate:SD (match_dup 2)))]
5466 "TARGET_HARD_DFP"
5467 {
5468 operands[2] = gen_reg_rtx (DDmode);
5469 })
5470
5471 ;
5472 ; extend(sf|df)(df|tf)2 instruction pattern(s).
5473 ;
5474
5475 ; wflls
5476 (define_insn "*extendsfdf2_z13"
5477 [(set (match_operand:DF 0 "register_operand" "=f,f,v")
5478 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "f,R,v")))]
5479 "TARGET_VX && TARGET_HARD_FLOAT"
5480 "@
5481 ldebr\t%0,%1
5482 ldeb\t%0,%1
5483 wldeb\t%v0,%v1"
5484 [(set_attr "op_type" "RRE,RXE,VRR")
5485 (set_attr "type" "fsimpdf, floaddf,fsimpdf")])
5486
5487 ; ldebr, ldeb, lxdbr, lxdb, lxebr, lxeb
5488 (define_insn "*extend<DSF:mode><BFP:mode>2"
5489 [(set (match_operand:BFP 0 "register_operand" "=f,f")
5490 (float_extend:BFP (match_operand:DSF 1 "nonimmediate_operand" "f,R")))]
5491 "TARGET_HARD_FLOAT
5492 && GET_MODE_SIZE (<BFP:MODE>mode) > GET_MODE_SIZE (<DSF:MODE>mode)
5493 && (!TARGET_VX || <BFP:MODE>mode != DFmode || <DSF:MODE>mode != SFmode)"
5494 "@
5495 l<BFP:xde><DSF:xde>br\t%0,%1
5496 l<BFP:xde><DSF:xde>b\t%0,%1"
5497 [(set_attr "op_type" "RRE,RXE")
5498 (set_attr "type" "fsimp<BFP:type>, fload<BFP:type>")])
5499
5500 (define_expand "extend<DSF:mode><BFP:mode>2<BFP:tf_fpr>"
5501 [(set (match_operand:BFP 0 "register_operand" "")
5502 (float_extend:BFP (match_operand:DSF 1 "nonimmediate_operand" "")))]
5503 "TARGET_HARD_FLOAT
5504 && GET_MODE_SIZE (<BFP:MODE>mode) > GET_MODE_SIZE (<DSF:MODE>mode)")
5505
5506 ;
5507 ; extendddtd2 and extendsddd2 instruction pattern(s).
5508 ;
5509
5510 (define_insn "extendddtd2"
5511 [(set (match_operand:TD 0 "register_operand" "=f")
5512 (float_extend:TD (match_operand:DD 1 "register_operand" "f")))]
5513 "TARGET_HARD_DFP"
5514 "lxdtr\t%0,%1,0"
5515 [(set_attr "op_type" "RRF")
5516 (set_attr "type" "fsimptf")])
5517
5518 (define_insn "extendsddd2"
5519 [(set (match_operand:DD 0 "register_operand" "=f")
5520 (float_extend:DD (match_operand:SD 1 "register_operand" "f")))]
5521 "TARGET_HARD_DFP"
5522 "ldetr\t%0,%1,0"
5523 [(set_attr "op_type" "RRF")
5524 (set_attr "type" "fsimptf")])
5525
5526 (define_expand "extendsdtd2"
5527 [(set (match_dup 2)
5528 (float_extend:DD (match_operand:SD 1 "register_operand" "")))
5529 (set (match_operand:TD 0 "register_operand" "")
5530 (float_extend:TD (match_dup 2)))]
5531 "TARGET_HARD_DFP"
5532 {
5533 operands[2] = gen_reg_rtx (DDmode);
5534 })
5535
5536 ; Binary Floating Point - load fp integer
5537
5538 ; Expanders for: floor, btrunc, round, ceil, and nearbyint
5539 ; For all of them the inexact exceptions are suppressed.
5540
5541 ; fiebra, fidbra, fixbra
5542 (define_insn "<FPINT:fpint_name><BFP:mode>2<BFP:tf_fpr>"
5543 [(set (match_operand:BFP 0 "register_operand" "=f")
5544 (unspec:BFP [(match_operand:BFP 1 "register_operand" "f")]
5545 FPINT))]
5546 "TARGET_Z196"
5547 "fi<BFP:xde>bra\t%0,<FPINT:fpint_roundingmode>,%1,4"
5548 [(set_attr "op_type" "RRF")
5549 (set_attr "type" "fsimp<BFP:type>")])
5550
5551 ; rint is supposed to raise an inexact exception so we can use the
5552 ; older instructions.
5553
5554 ; fiebr, fidbr, fixbr
5555 (define_insn "rint<BFP:mode>2<BFP:tf_fpr>"
5556 [(set (match_operand:BFP 0 "register_operand" "=f")
5557 (unspec:BFP [(match_operand:BFP 1 "register_operand" "f")]
5558 UNSPEC_FPINT_RINT))]
5559 ""
5560 "fi<BFP:xde>br\t%0,0,%1"
5561 [(set_attr "op_type" "RRF")
5562 (set_attr "type" "fsimp<BFP:type>")])
5563
5564
5565 ; Decimal Floating Point - load fp integer
5566
5567 ; fidtr, fixtr
5568 (define_insn "<FPINT:fpint_name><DFP:mode>2"
5569 [(set (match_operand:DFP 0 "register_operand" "=f")
5570 (unspec:DFP [(match_operand:DFP 1 "register_operand" "f")]
5571 FPINT))]
5572 "TARGET_HARD_DFP"
5573 "fi<DFP:xde>tr\t%0,<FPINT:fpint_roundingmode>,%1,4"
5574 [(set_attr "op_type" "RRF")
5575 (set_attr "type" "fsimp<DFP:type>")])
5576
5577 ; fidtr, fixtr
5578 (define_insn "rint<DFP:mode>2"
5579 [(set (match_operand:DFP 0 "register_operand" "=f")
5580 (unspec:DFP [(match_operand:DFP 1 "register_operand" "f")]
5581 UNSPEC_FPINT_RINT))]
5582 "TARGET_HARD_DFP"
5583 "fi<DFP:xde>tr\t%0,0,%1,0"
5584 [(set_attr "op_type" "RRF")
5585 (set_attr "type" "fsimp<DFP:type>")])
5586
5587 ;
5588 ; Binary <-> Decimal floating point trunc patterns
5589 ;
5590
5591 (define_insn "*trunc<BFP:mode><DFP_ALL:mode>2"
5592 [(set (reg:DFP_ALL FPR0_REGNUM)
5593 (float_truncate:DFP_ALL (reg:BFP FPR4_REGNUM)))
5594 (use (reg:SI GPR0_REGNUM))
5595 (clobber (reg:CC CC_REGNUM))
5596 (clobber (reg:SI GPR1_REGNUM))]
5597 "TARGET_HARD_DFP"
5598 "pfpo")
5599
5600 (define_insn "*trunc<DFP_ALL:mode><BFP:mode>2"
5601 [(set (reg:BFP FPR0_REGNUM)
5602 (float_truncate:BFP (reg:DFP_ALL FPR4_REGNUM)))
5603 (use (reg:SI GPR0_REGNUM))
5604 (clobber (reg:CC CC_REGNUM))
5605 (clobber (reg:SI GPR1_REGNUM))]
5606 "TARGET_HARD_DFP"
5607 "pfpo")
5608
5609 (define_expand "trunc<BFP:mode><DFP_ALL:mode>2<BFP:tf_fpr>"
5610 [(set (reg:BFP FPR4_REGNUM) (match_operand:BFP 1 "nonimmediate_operand" ""))
5611 (set (reg:SI GPR0_REGNUM) (match_dup 2))
5612 (parallel
5613 [(set (reg:DFP_ALL FPR0_REGNUM)
5614 (float_truncate:DFP_ALL (reg:BFP FPR4_REGNUM)))
5615 (use (reg:SI GPR0_REGNUM))
5616 (clobber (reg:CC CC_REGNUM))
5617 (clobber (reg:SI GPR1_REGNUM))])
5618 (set (match_operand:DFP_ALL 0 "nonimmediate_operand" "")
5619 (reg:DFP_ALL FPR0_REGNUM))]
5620 "TARGET_HARD_DFP
5621 && GET_MODE_SIZE (<BFP:MODE>mode) > GET_MODE_SIZE (<DFP_ALL:MODE>mode)"
5622 {
5623 HOST_WIDE_INT flags;
5624
5625 /* According to IEEE 754 2008 4.3 'Rounding-direction attributes' the
5626 rounding mode of the target format needs to be used. */
5627
5628 flags = (PFPO_CONVERT |
5629 PFPO_OP_TYPE_<DFP_ALL:MODE> << PFPO_OP0_TYPE_SHIFT |
5630 PFPO_OP_TYPE_<BFP:MODE> << PFPO_OP1_TYPE_SHIFT |
5631 PFPO_RND_MODE_DFP);
5632
5633 operands[2] = GEN_INT (flags);
5634 })
5635
5636 (define_expand "trunc<DFP_ALL:mode><BFP:mode>2<BFP:tf_fpr>"
5637 [(set (reg:DFP_ALL FPR4_REGNUM)
5638 (match_operand:DFP_ALL 1 "nonimmediate_operand" ""))
5639 (set (reg:SI GPR0_REGNUM) (match_dup 2))
5640 (parallel
5641 [(set (reg:BFP FPR0_REGNUM) (float_truncate:BFP (reg:DFP_ALL FPR4_REGNUM)))
5642 (use (reg:SI GPR0_REGNUM))
5643 (clobber (reg:CC CC_REGNUM))
5644 (clobber (reg:SI GPR1_REGNUM))])
5645 (set (match_operand:BFP 0 "nonimmediate_operand" "") (reg:BFP FPR0_REGNUM))]
5646 "TARGET_HARD_DFP
5647 && GET_MODE_SIZE (<DFP_ALL:MODE>mode) >= GET_MODE_SIZE (<BFP:MODE>mode)"
5648 {
5649 HOST_WIDE_INT flags;
5650
5651 /* According to IEEE 754 2008 4.3 'Rounding-direction attributes' the
5652 rounding mode of the target format needs to be used. */
5653
5654 flags = (PFPO_CONVERT |
5655 PFPO_OP_TYPE_<BFP:MODE> << PFPO_OP0_TYPE_SHIFT |
5656 PFPO_OP_TYPE_<DFP_ALL:MODE> << PFPO_OP1_TYPE_SHIFT |
5657 PFPO_RND_MODE_BFP);
5658
5659 operands[2] = GEN_INT (flags);
5660 })
5661
5662 ;
5663 ; Binary <-> Decimal floating point extend patterns
5664 ;
5665
5666 (define_insn "*extend<BFP:mode><DFP_ALL:mode>2"
5667 [(set (reg:DFP_ALL FPR0_REGNUM) (float_extend:DFP_ALL (reg:BFP 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")
5673
5674 (define_insn "*extend<DFP_ALL:mode><BFP:mode>2"
5675 [(set (reg:BFP FPR0_REGNUM) (float_extend:BFP (reg:DFP_ALL FPR4_REGNUM)))
5676 (use (reg:SI GPR0_REGNUM))
5677 (clobber (reg:CC CC_REGNUM))
5678 (clobber (reg:SI GPR1_REGNUM))]
5679 "TARGET_HARD_DFP"
5680 "pfpo")
5681
5682 (define_expand "extend<BFP:mode><DFP_ALL:mode>2<BFP:tf_fpr>"
5683 [(set (reg:BFP FPR4_REGNUM) (match_operand:BFP 1 "nonimmediate_operand" ""))
5684 (set (reg:SI GPR0_REGNUM) (match_dup 2))
5685 (parallel
5686 [(set (reg:DFP_ALL FPR0_REGNUM)
5687 (float_extend:DFP_ALL (reg:BFP FPR4_REGNUM)))
5688 (use (reg:SI GPR0_REGNUM))
5689 (clobber (reg:CC CC_REGNUM))
5690 (clobber (reg:SI GPR1_REGNUM))])
5691 (set (match_operand:DFP_ALL 0 "nonimmediate_operand" "")
5692 (reg:DFP_ALL FPR0_REGNUM))]
5693 "TARGET_HARD_DFP
5694 && GET_MODE_SIZE (<BFP:MODE>mode) <= GET_MODE_SIZE (<DFP_ALL:MODE>mode)"
5695 {
5696 HOST_WIDE_INT flags;
5697
5698 /* According to IEEE 754 2008 4.3 'Rounding-direction attributes' the
5699 rounding mode of the target format needs to be used. */
5700
5701 flags = (PFPO_CONVERT |
5702 PFPO_OP_TYPE_<DFP_ALL:MODE> << PFPO_OP0_TYPE_SHIFT |
5703 PFPO_OP_TYPE_<BFP:MODE> << PFPO_OP1_TYPE_SHIFT |
5704 PFPO_RND_MODE_DFP);
5705
5706 operands[2] = GEN_INT (flags);
5707 })
5708
5709 (define_expand "extend<DFP_ALL:mode><BFP:mode>2<BFP:tf_fpr>"
5710 [(set (reg:DFP_ALL FPR4_REGNUM)
5711 (match_operand:DFP_ALL 1 "nonimmediate_operand" ""))
5712 (set (reg:SI GPR0_REGNUM) (match_dup 2))
5713 (parallel
5714 [(set (reg:BFP FPR0_REGNUM) (float_extend:BFP (reg:DFP_ALL FPR4_REGNUM)))
5715 (use (reg:SI GPR0_REGNUM))
5716 (clobber (reg:CC CC_REGNUM))
5717 (clobber (reg:SI GPR1_REGNUM))])
5718 (set (match_operand:BFP 0 "nonimmediate_operand" "") (reg:BFP FPR0_REGNUM))]
5719 "TARGET_HARD_DFP
5720 && GET_MODE_SIZE (<DFP_ALL:MODE>mode) < GET_MODE_SIZE (<BFP:MODE>mode)"
5721 {
5722 HOST_WIDE_INT flags;
5723
5724 /* According to IEEE 754 2008 4.3 'Rounding-direction attributes' the
5725 rounding mode of the target format needs to be used. */
5726
5727 flags = (PFPO_CONVERT |
5728 PFPO_OP_TYPE_<BFP:MODE> << PFPO_OP0_TYPE_SHIFT |
5729 PFPO_OP_TYPE_<DFP_ALL:MODE> << PFPO_OP1_TYPE_SHIFT |
5730 PFPO_RND_MODE_BFP);
5731
5732 operands[2] = GEN_INT (flags);
5733 })
5734
5735
5736 ;;
5737 ;; ARITHMETIC OPERATIONS
5738 ;;
5739 ; arithmetic operations set the ConditionCode,
5740 ; because of unpredictable Bits in Register for Halfword and Byte
5741 ; the ConditionCode can be set wrong in operations for Halfword and Byte
5742
5743 ;;
5744 ;;- Add instructions.
5745 ;;
5746
5747 ;
5748 ; addti3 instruction pattern(s).
5749 ;
5750
5751 (define_expand "addti3"
5752 [(parallel
5753 [(set (match_operand:TI 0 "register_operand" "")
5754 (plus:TI (match_operand:TI 1 "nonimmediate_operand" "")
5755 (match_operand:TI 2 "general_operand" "") ) )
5756 (clobber (reg:CC CC_REGNUM))])]
5757 "TARGET_ZARCH"
5758 {
5759 /* For z13 we have vaq which doesn't set CC. */
5760 if (TARGET_VX)
5761 {
5762 emit_insn (gen_rtx_SET (operands[0],
5763 gen_rtx_PLUS (TImode,
5764 copy_to_mode_reg (TImode, operands[1]),
5765 copy_to_mode_reg (TImode, operands[2]))));
5766 DONE;
5767 }
5768 })
5769
5770 (define_insn_and_split "*addti3"
5771 [(set (match_operand:TI 0 "register_operand" "=&d")
5772 (plus:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
5773 (match_operand:TI 2 "general_operand" "do") ) )
5774 (clobber (reg:CC CC_REGNUM))]
5775 "TARGET_ZARCH"
5776 "#"
5777 "&& reload_completed"
5778 [(parallel
5779 [(set (reg:CCL1 CC_REGNUM)
5780 (compare:CCL1 (plus:DI (match_dup 7) (match_dup 8))
5781 (match_dup 7)))
5782 (set (match_dup 6) (plus:DI (match_dup 7) (match_dup 8)))])
5783 (parallel
5784 [(set (match_dup 3) (plus:DI
5785 (plus:DI (ltu:DI (reg:CCL1 CC_REGNUM) (const_int 0))
5786 (match_dup 4)) (match_dup 5)))
5787 (clobber (reg:CC CC_REGNUM))])]
5788 "operands[3] = operand_subword (operands[0], 0, 0, TImode);
5789 operands[4] = operand_subword (operands[1], 0, 0, TImode);
5790 operands[5] = operand_subword (operands[2], 0, 0, TImode);
5791 operands[6] = operand_subword (operands[0], 1, 0, TImode);
5792 operands[7] = operand_subword (operands[1], 1, 0, TImode);
5793 operands[8] = operand_subword (operands[2], 1, 0, TImode);"
5794 [(set_attr "op_type" "*")
5795 (set_attr "cpu_facility" "*")])
5796
5797 ;
5798 ; adddi3 instruction pattern(s).
5799 ;
5800
5801 (define_expand "adddi3"
5802 [(parallel
5803 [(set (match_operand:DI 0 "nonimmediate_operand" "")
5804 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
5805 (match_operand:DI 2 "general_operand" "")))
5806 (clobber (reg:CC CC_REGNUM))])]
5807 ""
5808 "")
5809
5810 (define_insn "*adddi3_sign"
5811 [(set (match_operand:DI 0 "register_operand" "=d,d")
5812 (plus:DI (sign_extend:DI (match_operand:SI 2 "general_operand" "d,T"))
5813 (match_operand:DI 1 "register_operand" "0,0")))
5814 (clobber (reg:CC CC_REGNUM))]
5815 "TARGET_ZARCH"
5816 "@
5817 agfr\t%0,%2
5818 agf\t%0,%2"
5819 [(set_attr "op_type" "RRE,RXY")
5820 (set_attr "z196prop" "z196_cracked,z196_cracked")])
5821
5822 (define_insn "*adddi3_zero_cc"
5823 [(set (reg CC_REGNUM)
5824 (compare (plus:DI (zero_extend:DI (match_operand:SI 2 "general_operand" "d,T"))
5825 (match_operand:DI 1 "register_operand" "0,0"))
5826 (const_int 0)))
5827 (set (match_operand:DI 0 "register_operand" "=d,d")
5828 (plus:DI (zero_extend:DI (match_dup 2)) (match_dup 1)))]
5829 "s390_match_ccmode (insn, CCLmode) && TARGET_ZARCH"
5830 "@
5831 algfr\t%0,%2
5832 algf\t%0,%2"
5833 [(set_attr "op_type" "RRE,RXY")
5834 (set_attr "z10prop" "z10_super_E1,z10_super_E1")])
5835
5836 (define_insn "*adddi3_zero_cconly"
5837 [(set (reg CC_REGNUM)
5838 (compare (plus:DI (zero_extend:DI (match_operand:SI 2 "general_operand" "d,T"))
5839 (match_operand:DI 1 "register_operand" "0,0"))
5840 (const_int 0)))
5841 (clobber (match_scratch:DI 0 "=d,d"))]
5842 "s390_match_ccmode (insn, CCLmode) && TARGET_ZARCH"
5843 "@
5844 algfr\t%0,%2
5845 algf\t%0,%2"
5846 [(set_attr "op_type" "RRE,RXY")
5847 (set_attr "z10prop" "z10_super_E1,z10_super_E1")])
5848
5849 (define_insn "*adddi3_zero"
5850 [(set (match_operand:DI 0 "register_operand" "=d,d")
5851 (plus:DI (zero_extend:DI (match_operand:SI 2 "general_operand" "d,T"))
5852 (match_operand:DI 1 "register_operand" "0,0")))
5853 (clobber (reg:CC CC_REGNUM))]
5854 "TARGET_ZARCH"
5855 "@
5856 algfr\t%0,%2
5857 algf\t%0,%2"
5858 [(set_attr "op_type" "RRE,RXY")
5859 (set_attr "z10prop" "z10_super_E1,z10_super_E1")])
5860
5861 (define_insn_and_split "*adddi3_31z"
5862 [(set (match_operand:DI 0 "nonimmediate_operand" "=&d")
5863 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
5864 (match_operand:DI 2 "general_operand" "do") ) )
5865 (clobber (reg:CC CC_REGNUM))]
5866 "!TARGET_ZARCH"
5867 "#"
5868 "&& reload_completed"
5869 [(parallel
5870 [(set (reg:CCL1 CC_REGNUM)
5871 (compare:CCL1 (plus:SI (match_dup 7) (match_dup 8))
5872 (match_dup 7)))
5873 (set (match_dup 6) (plus:SI (match_dup 7) (match_dup 8)))])
5874 (parallel
5875 [(set (match_dup 3) (plus:SI
5876 (plus:SI (ltu:SI (reg:CCL1 CC_REGNUM) (const_int 0))
5877 (match_dup 4)) (match_dup 5)))
5878 (clobber (reg:CC CC_REGNUM))])]
5879 "operands[3] = operand_subword (operands[0], 0, 0, DImode);
5880 operands[4] = operand_subword (operands[1], 0, 0, DImode);
5881 operands[5] = operand_subword (operands[2], 0, 0, DImode);
5882 operands[6] = operand_subword (operands[0], 1, 0, DImode);
5883 operands[7] = operand_subword (operands[1], 1, 0, DImode);
5884 operands[8] = operand_subword (operands[2], 1, 0, DImode);")
5885
5886 ;
5887 ; addsi3 instruction pattern(s).
5888 ;
5889
5890 (define_expand "addsi3"
5891 [(parallel
5892 [(set (match_operand:SI 0 "nonimmediate_operand" "")
5893 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "")
5894 (match_operand:SI 2 "general_operand" "")))
5895 (clobber (reg:CC CC_REGNUM))])]
5896 ""
5897 "")
5898
5899 (define_insn "*addsi3_sign"
5900 [(set (match_operand:SI 0 "register_operand" "=d,d")
5901 (plus:SI (sign_extend:SI (match_operand:HI 2 "memory_operand" "R,T"))
5902 (match_operand:SI 1 "register_operand" "0,0")))
5903 (clobber (reg:CC CC_REGNUM))]
5904 ""
5905 "@
5906 ah\t%0,%2
5907 ahy\t%0,%2"
5908 [(set_attr "op_type" "RX,RXY")
5909 (set_attr "cpu_facility" "*,longdisp")
5910 (set_attr "z196prop" "z196_cracked,z196_cracked")])
5911
5912 ;
5913 ; add(di|si)3 instruction pattern(s).
5914 ;
5915
5916 ; ark, agrk, ar, ahi, ahik, aghik, alfi, slfi, a, ay, agr, aghi, algfi, slgfi, ag, asi, agsi
5917 (define_insn "*add<mode>3"
5918 [(set (match_operand:GPR 0 "nonimmediate_operand" "=d,d,d,d, d, d,d,d,S")
5919 (plus:GPR (match_operand:GPR 1 "nonimmediate_operand" "%0,d,0,d, 0, 0,0,0,0")
5920 (match_operand:GPR 2 "general_operand" " d,d,K,K,Op,On,R,T,C") ) )
5921 (clobber (reg:CC CC_REGNUM))]
5922 ""
5923 "@
5924 a<g>r\t%0,%2
5925 a<g>rk\t%0,%1,%2
5926 a<g>hi\t%0,%h2
5927 a<g>hik\t%0,%1,%h2
5928 al<g>fi\t%0,%2
5929 sl<g>fi\t%0,%n2
5930 a<g>\t%0,%2
5931 a<y>\t%0,%2
5932 a<g>si\t%0,%c2"
5933 [(set_attr "op_type" "RR<E>,RRF,RI,RIE,RIL,RIL,RX<Y>,RXY,SIY")
5934 (set_attr "cpu_facility" "*,z196,*,z196,extimm,extimm,*,longdisp,z10")
5935 (set_attr "z10prop" "z10_super_E1,*,z10_super_E1,*,z10_super_E1,z10_super_E1,
5936 z10_super_E1,z10_super_E1,z10_super_E1")])
5937
5938 ; alr, alfi, slfi, al, aly, alrk, alhsik, algr, algfi, slgfi, alg, alsi, algsi, algrk, alghsik
5939 (define_insn "*add<mode>3_carry1_cc"
5940 [(set (reg CC_REGNUM)
5941 (compare (plus:GPR (match_operand:GPR 1 "nonimmediate_operand" "%0,d, 0, 0,d,0,0,0")
5942 (match_operand:GPR 2 "general_operand" " d,d,Op,On,K,R,T,C"))
5943 (match_dup 1)))
5944 (set (match_operand:GPR 0 "nonimmediate_operand" "=d,d, d, d,d,d,d,d")
5945 (plus:GPR (match_dup 1) (match_dup 2)))]
5946 "s390_match_ccmode (insn, CCL1mode)"
5947 "@
5948 al<g>r\t%0,%2
5949 al<g>rk\t%0,%1,%2
5950 al<g>fi\t%0,%2
5951 sl<g>fi\t%0,%n2
5952 al<g>hsik\t%0,%1,%h2
5953 al<g>\t%0,%2
5954 al<y>\t%0,%2
5955 al<g>si\t%0,%c2"
5956 [(set_attr "op_type" "RR<E>,RRF,RIL,RIL,RIE,RX<Y>,RXY,SIY")
5957 (set_attr "cpu_facility" "*,z196,extimm,extimm,z196,*,longdisp,z10")
5958 (set_attr "z10prop" "z10_super_E1,*,z10_super_E1,z10_super_E1,*,
5959 z10_super_E1,z10_super_E1,z10_super_E1")])
5960
5961 ; alr, al, aly, algr, alg, alrk, algrk
5962 (define_insn "*add<mode>3_carry1_cconly"
5963 [(set (reg CC_REGNUM)
5964 (compare (plus:GPR (match_operand:GPR 1 "nonimmediate_operand" "%0,d,0,0")
5965 (match_operand:GPR 2 "general_operand" "d,d,R,T"))
5966 (match_dup 1)))
5967 (clobber (match_scratch:GPR 0 "=d,d,d,d"))]
5968 "s390_match_ccmode (insn, CCL1mode)"
5969 "@
5970 al<g>r\t%0,%2
5971 al<g>rk\t%0,%1,%2
5972 al<g>\t%0,%2
5973 al<y>\t%0,%2"
5974 [(set_attr "op_type" "RR<E>,RRF,RX<Y>,RXY")
5975 (set_attr "cpu_facility" "*,z196,*,longdisp")
5976 (set_attr "z10prop" "z10_super_E1,*,z10_super_E1,z10_super_E1")])
5977
5978 ; alr, alfi, slfi, al, aly, algr, algfi, slgfi, alg, alsi, algsi, alrk, algrk, alhsik, alghsik
5979 (define_insn "*add<mode>3_carry2_cc"
5980 [(set (reg CC_REGNUM)
5981 (compare (plus:GPR (match_operand:GPR 1 "nonimmediate_operand" "%0,d, 0, 0,d,0,0,0")
5982 (match_operand:GPR 2 "general_operand" " d,d,Op,On,K,R,T,C"))
5983 (match_dup 2)))
5984 (set (match_operand:GPR 0 "nonimmediate_operand" "=d,d, d, d,d,d,d,S")
5985 (plus:GPR (match_dup 1) (match_dup 2)))]
5986 "s390_match_ccmode (insn, CCL1mode)"
5987 "@
5988 al<g>r\t%0,%2
5989 al<g>rk\t%0,%1,%2
5990 al<g>fi\t%0,%2
5991 sl<g>fi\t%0,%n2
5992 al<g>hsik\t%0,%1,%h2
5993 al<g>\t%0,%2
5994 al<y>\t%0,%2
5995 al<g>si\t%0,%c2"
5996 [(set_attr "op_type" "RR<E>,RRF,RIL,RIL,RIE,RX<Y>,RXY,SIY")
5997 (set_attr "cpu_facility" "*,z196,extimm,extimm,z196,*,longdisp,z10")
5998 (set_attr "z10prop" "z10_super_E1,*,z10_super_E1,z10_super_E1,*,
5999 z10_super_E1,z10_super_E1,z10_super_E1")])
6000
6001 ; alr, al, aly, algr, alg, alrk, algrk
6002 (define_insn "*add<mode>3_carry2_cconly"
6003 [(set (reg CC_REGNUM)
6004 (compare (plus:GPR (match_operand:GPR 1 "nonimmediate_operand" "%0,d,0,0")
6005 (match_operand:GPR 2 "general_operand" "d,d,R,T"))
6006 (match_dup 2)))
6007 (clobber (match_scratch:GPR 0 "=d,d,d,d"))]
6008 "s390_match_ccmode (insn, CCL1mode)"
6009 "@
6010 al<g>r\t%0,%2
6011 al<g>rk\t%0,%1,%2
6012 al<g>\t%0,%2
6013 al<y>\t%0,%2"
6014 [(set_attr "op_type" "RR<E>,RRF,RX<Y>,RXY")
6015 (set_attr "cpu_facility" "*,z196,*,longdisp")
6016 (set_attr "z10prop" "z10_super_E1,*,z10_super_E1,z10_super_E1")])
6017
6018 ; alr, alfi, slfi, al, aly, algr, algfi, slgfi, alg, alsi, algsi, alrk, algrk, alhsik, alghsik
6019 (define_insn "*add<mode>3_cc"
6020 [(set (reg CC_REGNUM)
6021 (compare (plus:GPR (match_operand:GPR 1 "nonimmediate_operand" "%0,d, 0, 0,d,0,0,0")
6022 (match_operand:GPR 2 "general_operand" " d,d,Op,On,K,R,T,C"))
6023 (const_int 0)))
6024 (set (match_operand:GPR 0 "nonimmediate_operand" "=d,d, d, d,d,d,d,S")
6025 (plus:GPR (match_dup 1) (match_dup 2)))]
6026 "s390_match_ccmode (insn, CCLmode)"
6027 "@
6028 al<g>r\t%0,%2
6029 al<g>rk\t%0,%1,%2
6030 al<g>fi\t%0,%2
6031 sl<g>fi\t%0,%n2
6032 al<g>hsik\t%0,%1,%h2
6033 al<g>\t%0,%2
6034 al<y>\t%0,%2
6035 al<g>si\t%0,%c2"
6036 [(set_attr "op_type" "RR<E>,RRF,RIL,RIL,RIE,RX<Y>,RXY,SIY")
6037 (set_attr "cpu_facility" "*,z196,extimm,extimm,z196,*,longdisp,z10")
6038 (set_attr "z10prop" "z10_super_E1,*,z10_super_E1,z10_super_E1,
6039 *,z10_super_E1,z10_super_E1,z10_super_E1")])
6040
6041 ; alr, al, aly, algr, alg, alrk, algrk
6042 (define_insn "*add<mode>3_cconly"
6043 [(set (reg CC_REGNUM)
6044 (compare (plus:GPR (match_operand:GPR 1 "nonimmediate_operand" "%0,d,0,0")
6045 (match_operand:GPR 2 "general_operand" "d,d,R,T"))
6046 (const_int 0)))
6047 (clobber (match_scratch:GPR 0 "=d,d,d,d"))]
6048 "s390_match_ccmode (insn, CCLmode)"
6049 "@
6050 al<g>r\t%0,%2
6051 al<g>rk\t%0,%1,%2
6052 al<g>\t%0,%2
6053 al<y>\t%0,%2"
6054 [(set_attr "op_type" "RR<E>,RRF,RX<Y>,RXY")
6055 (set_attr "cpu_facility" "*,z196,*,longdisp")
6056 (set_attr "z10prop" "z10_super_E1,*,z10_super_E1,z10_super_E1")])
6057
6058 ; alr, al, aly, algr, alg, alrk, algrk
6059 (define_insn "*add<mode>3_cconly2"
6060 [(set (reg CC_REGNUM)
6061 (compare (match_operand:GPR 1 "nonimmediate_operand" "%0,d,0,0")
6062 (neg:GPR (match_operand:GPR 2 "general_operand" "d,d,R,T"))))
6063 (clobber (match_scratch:GPR 0 "=d,d,d,d"))]
6064 "s390_match_ccmode(insn, CCLmode)"
6065 "@
6066 al<g>r\t%0,%2
6067 al<g>rk\t%0,%1,%2
6068 al<g>\t%0,%2
6069 al<y>\t%0,%2"
6070 [(set_attr "op_type" "RR<E>,RRF,RX<Y>,RXY")
6071 (set_attr "cpu_facility" "*,z196,*,longdisp")
6072 (set_attr "z10prop" "z10_super_E1,*,z10_super_E1,z10_super_E1")])
6073
6074 ; ahi, afi, aghi, agfi, asi, agsi
6075 (define_insn "*add<mode>3_imm_cc"
6076 [(set (reg CC_REGNUM)
6077 (compare (plus:GPR (match_operand:GPR 1 "nonimmediate_operand" " 0, d,0, 0")
6078 (match_operand:GPR 2 "const_int_operand" " K, K,Os,C"))
6079 (const_int 0)))
6080 (set (match_operand:GPR 0 "nonimmediate_operand" "=d, d,d, S")
6081 (plus:GPR (match_dup 1) (match_dup 2)))]
6082 "s390_match_ccmode (insn, CCAmode)
6083 && (CONST_OK_FOR_CONSTRAINT_P (INTVAL (operands[2]), 'K', \"K\")
6084 || (CONST_OK_FOR_CONSTRAINT_P (INTVAL (operands[2]), 'O', \"Os\")
6085 /* Avoid INT32_MIN on 32 bit. */
6086 && (!TARGET_ZARCH || INTVAL (operands[2]) != -0x7fffffff - 1)))"
6087 "@
6088 a<g>hi\t%0,%h2
6089 a<g>hik\t%0,%1,%h2
6090 a<g>fi\t%0,%2
6091 a<g>si\t%0,%c2"
6092 [(set_attr "op_type" "RI,RIE,RIL,SIY")
6093 (set_attr "cpu_facility" "*,z196,extimm,z10")
6094 (set_attr "z10prop" "z10_super_E1,*,z10_super_E1,z10_super_E1")])
6095
6096 (define_insn "*adddi3_sign"
6097 [(set (match_operand:DI 0 "register_operand" "=d")
6098 (plus:DI (sign_extend:DI (match_operand:HI 2 "memory_operand" "T"))
6099 (match_operand:DI 1 "register_operand" "0")))
6100 (clobber (reg:CC CC_REGNUM))]
6101 "TARGET_Z14"
6102 "agh\t%0,%2"
6103 [(set_attr "op_type" "RXY")])
6104
6105
6106 ; Jump to label OP3 if OP1 + OP2 results in a signed overflow
6107
6108 ; addv_const_operand accepts all constants which can be handled
6109 ; without reloads. These will be handled primarily by
6110 ; "*addv<mode>3_ccoverflow_const" which doesn't provide a register
6111 ; alternative. Hence we have to match the operand exactly.
6112 ; For immediates we have to avoid the SIGN_EXTEND around OP2.
6113 (define_expand "addv<mode>4"
6114 [(parallel
6115 [(set (reg:CCO CC_REGNUM)
6116 (compare:CCO (plus:<DBL>
6117 (sign_extend:<DBL> (match_operand:GPR 1 "nonimmediate_operand"))
6118 (match_dup 4))
6119 (sign_extend:<DBL> (plus:GPR (match_dup 1)
6120 (match_operand:GPR 2 "general_operand")))))
6121 (set (match_operand:GPR 0 "nonimmediate_operand")
6122 (plus:GPR (match_dup 1) (match_dup 2)))])
6123 (set (pc)
6124 (if_then_else (ne (reg:CCO CC_REGNUM) (const_int 0))
6125 (label_ref (match_operand 3))
6126 (pc)))]
6127 ""
6128 {
6129 if (CONSTANT_P (operands[2])
6130 && !addv_const_operand (operands[2], GET_MODE (operands[2])))
6131 operands[2] = force_reg (<GPR:MODE>mode, operands[2]);
6132
6133 if (GET_MODE (operands[2]) != VOIDmode)
6134 operands[4] = gen_rtx_SIGN_EXTEND (<DBL>mode, operands[2]);
6135 else
6136 /* This is what CSE does when propagating a constant into the pattern. */
6137 operands[4] = simplify_unary_operation (SIGN_EXTEND, <GPR:DBL>mode, operands[2], <GPR:MODE>mode);
6138 })
6139
6140 ; ark, agrk, ar, ahi, ahik, aghik, a, ay, agr, aghi, ag, asi, agsi
6141 (define_insn "*addv<mode>3_ccoverflow"
6142 [(set (reg CC_REGNUM)
6143 (compare (plus:<DBL>
6144 (sign_extend:<DBL> (match_operand:GPR 1 "nonimmediate_operand" "%0,d,0,d,0,0,0"))
6145 (sign_extend:<DBL> (match_operand:GPR 2 "general_operand" " d,d,K,K,R,T,C")))
6146 (sign_extend:<DBL> (plus:GPR (match_dup 1) (match_dup 2)))))
6147 (set (match_operand:GPR 0 "nonimmediate_operand" "=d,d,d,d,d,d,S")
6148 (plus:GPR (match_dup 1) (match_dup 2)))]
6149 "s390_match_ccmode (insn, CCOmode)"
6150 "@
6151 a<g>r\t%0,%2
6152 a<g>rk\t%0,%1,%2
6153 a<g>hi\t%0,%h2
6154 a<g>hik\t%0,%1,%h2
6155 a<g>\t%0,%2
6156 a<y>\t%0,%2
6157 a<g>si\t%0,%c2"
6158 [(set_attr "op_type" "RR<E>,RRF,RI,RIE,RX<Y>,RXY,SIY")
6159 (set_attr "cpu_facility" "*,z196,*,z196,*,longdisp,z10")
6160 (set_attr "z10prop" "z10_super_E1,*,z10_super_E1,*,
6161 z10_super_E1,z10_super_E1,z10_super_E1")])
6162
6163 ; ahi, aghi, ahik, aghik, asi, agsi
6164 (define_insn "*addv<mode>3_ccoverflow_const"
6165 [(set (reg CC_REGNUM)
6166 (compare (plus:<DBL>
6167 (sign_extend:<DBL> (match_operand:GPR 1 "nonimmediate_operand" "%0,d,0"))
6168 (match_operand:<DBL> 2 "addv_const_operand" "K,K,C"))
6169 (sign_extend:<DBL> (plus:GPR (match_dup 1) (match_dup 2)))))
6170 (set (match_operand:GPR 0 "nonimmediate_operand" "=d,d,S")
6171 (plus:GPR (match_dup 1) (match_dup 2)))]
6172 "s390_match_ccmode (insn, CCOmode)"
6173 "@
6174 a<g>hi\t%0,%h2
6175 a<g>hik\t%0,%1,%h2
6176 a<g>si\t%0,%c2"
6177 [(set_attr "op_type" "RI,RIE,SIY")
6178 (set_attr "cpu_facility" "*,z196,z10")
6179 (set_attr "z10prop" "z10_super_E1,*,z10_super_E1")])
6180
6181
6182 ;
6183 ; add(tf|df|sf|td|dd)3 instruction pattern(s).
6184 ;
6185
6186 ; axbr, adbr, aebr, axb, adb, aeb, adtr, axtr
6187 ; FIXME: wfadb does not clobber cc
6188 (define_insn "add<mode>3<tf_fpr>"
6189 [(set (match_operand:FP 0 "register_operand" "=f,f,f,v,v")
6190 (plus:FP (match_operand:FP 1 "nonimmediate_operand" "%f,0,0,v,v")
6191 (match_operand:FP 2 "general_operand" "f,f,R,v,v")))
6192 (clobber (reg:CC CC_REGNUM))]
6193 "TARGET_HARD_FLOAT"
6194 "@
6195 a<xde>tr\t%0,%1,%2
6196 a<xde>br\t%0,%2
6197 a<xde>b\t%0,%2
6198 wfadb\t%v0,%v1,%v2
6199 wfasb\t%v0,%v1,%v2"
6200 [(set_attr "op_type" "RRF,RRE,RXE,VRR,VRR")
6201 (set_attr "type" "fsimp<type>")
6202 (set_attr "cpu_facility" "*,*,*,vx,vxe")
6203 (set_attr "enabled" "<nBFP>,<nDFP>,<DSF>,<DF>,<SF>")])
6204
6205 ; axbr, adbr, aebr, axb, adb, aeb, adtr, axtr
6206 (define_insn "*add<mode>3_cc"
6207 [(set (reg CC_REGNUM)
6208 (compare (plus:FP (match_operand:FP 1 "nonimmediate_operand" "%f,0,0")
6209 (match_operand:FP 2 "general_operand" "f,f,R"))
6210 (match_operand:FP 3 "const0_operand" "")))
6211 (set (match_operand:FP 0 "register_operand" "=f,f,f")
6212 (plus:FP (match_dup 1) (match_dup 2)))]
6213 "s390_match_ccmode (insn, CCSmode) && TARGET_HARD_FLOAT"
6214 "@
6215 a<xde>tr\t%0,%1,%2
6216 a<xde>br\t%0,%2
6217 a<xde>b\t%0,%2"
6218 [(set_attr "op_type" "RRF,RRE,RXE")
6219 (set_attr "type" "fsimp<type>")
6220 (set_attr "enabled" "<nBFP>,<nDFP>,<DSF>")])
6221
6222 ; axbr, adbr, aebr, axb, adb, aeb, adtr, axtr
6223 (define_insn "*add<mode>3_cconly"
6224 [(set (reg CC_REGNUM)
6225 (compare (plus:FP (match_operand:FP 1 "nonimmediate_operand" "%f,0,0")
6226 (match_operand:FP 2 "general_operand" "f,f,R"))
6227 (match_operand:FP 3 "const0_operand" "")))
6228 (clobber (match_scratch:FP 0 "=f,f,f"))]
6229 "s390_match_ccmode (insn, CCSmode) && TARGET_HARD_FLOAT"
6230 "@
6231 a<xde>tr\t%0,%1,%2
6232 a<xde>br\t%0,%2
6233 a<xde>b\t%0,%2"
6234 [(set_attr "op_type" "RRF,RRE,RXE")
6235 (set_attr "type" "fsimp<type>")
6236 (set_attr "enabled" "<nBFP>,<nDFP>,<DSF>")])
6237
6238 ;
6239 ; Pointer add instruction patterns
6240 ;
6241
6242 ; This will match "*la_64"
6243 (define_expand "addptrdi3"
6244 [(set (match_operand:DI 0 "register_operand" "")
6245 (plus:DI (match_operand:DI 1 "register_operand" "")
6246 (match_operand:DI 2 "nonmemory_operand" "")))]
6247 "TARGET_64BIT"
6248 {
6249 if (GET_CODE (operands[2]) == CONST_INT)
6250 {
6251 HOST_WIDE_INT c = INTVAL (operands[2]);
6252
6253 if (!CONST_OK_FOR_CONSTRAINT_P (c, 'K', "K")
6254 && !CONST_OK_FOR_CONSTRAINT_P (c, 'O', "Os"))
6255 {
6256 operands[2] = force_const_mem (DImode, operands[2]);
6257 operands[2] = force_reg (DImode, operands[2]);
6258 }
6259 else if (!DISP_IN_RANGE (INTVAL (operands[2])))
6260 operands[2] = force_reg (DImode, operands[2]);
6261 }
6262 })
6263
6264 ; For 31 bit we have to prevent the generated pattern from matching
6265 ; normal ADDs since la only does a 31 bit add. This is supposed to
6266 ; match "force_la_31".
6267 (define_expand "addptrsi3"
6268 [(parallel
6269 [(set (match_operand:SI 0 "register_operand" "")
6270 (plus:SI (match_operand:SI 1 "register_operand" "")
6271 (match_operand:SI 2 "nonmemory_operand" "")))
6272 (use (const_int 0))])]
6273 "!TARGET_64BIT"
6274 {
6275 if (GET_CODE (operands[2]) == CONST_INT)
6276 {
6277 HOST_WIDE_INT c = INTVAL (operands[2]);
6278
6279 if (!CONST_OK_FOR_CONSTRAINT_P (c, 'K', "K")
6280 && !CONST_OK_FOR_CONSTRAINT_P (c, 'O', "Os"))
6281 {
6282 operands[2] = force_const_mem (SImode, operands[2]);
6283 operands[2] = force_reg (SImode, operands[2]);
6284 }
6285 else if (!DISP_IN_RANGE (INTVAL (operands[2])))
6286 operands[2] = force_reg (SImode, operands[2]);
6287 }
6288 })
6289
6290 ;;
6291 ;;- Subtract instructions.
6292 ;;
6293
6294 ;
6295 ; subti3 instruction pattern(s).
6296 ;
6297
6298 (define_expand "subti3"
6299 [(parallel
6300 [(set (match_operand:TI 0 "register_operand" "")
6301 (minus:TI (match_operand:TI 1 "register_operand" "")
6302 (match_operand:TI 2 "general_operand" "") ) )
6303 (clobber (reg:CC CC_REGNUM))])]
6304 "TARGET_ZARCH"
6305 {
6306 /* For z13 we have vsq which doesn't set CC. */
6307 if (TARGET_VX)
6308 {
6309 emit_insn (gen_rtx_SET (operands[0],
6310 gen_rtx_MINUS (TImode,
6311 operands[1],
6312 copy_to_mode_reg (TImode, operands[2]))));
6313 DONE;
6314 }
6315 })
6316
6317 (define_insn_and_split "*subti3"
6318 [(set (match_operand:TI 0 "register_operand" "=&d")
6319 (minus:TI (match_operand:TI 1 "register_operand" "0")
6320 (match_operand:TI 2 "general_operand" "do") ) )
6321 (clobber (reg:CC CC_REGNUM))]
6322 "TARGET_ZARCH"
6323 "#"
6324 "&& reload_completed"
6325 [(parallel
6326 [(set (reg:CCL2 CC_REGNUM)
6327 (compare:CCL2 (minus:DI (match_dup 7) (match_dup 8))
6328 (match_dup 7)))
6329 (set (match_dup 6) (minus:DI (match_dup 7) (match_dup 8)))])
6330 (parallel
6331 [(set (match_dup 3) (minus:DI (minus:DI (match_dup 4) (match_dup 5))
6332 (gtu:DI (reg:CCL2 CC_REGNUM) (const_int 0))))
6333 (clobber (reg:CC CC_REGNUM))])]
6334 "operands[3] = operand_subword (operands[0], 0, 0, TImode);
6335 operands[4] = operand_subword (operands[1], 0, 0, TImode);
6336 operands[5] = operand_subword (operands[2], 0, 0, TImode);
6337 operands[6] = operand_subword (operands[0], 1, 0, TImode);
6338 operands[7] = operand_subword (operands[1], 1, 0, TImode);
6339 operands[8] = operand_subword (operands[2], 1, 0, TImode);"
6340 [(set_attr "op_type" "*")
6341 (set_attr "cpu_facility" "*")])
6342
6343 ;
6344 ; subdi3 instruction pattern(s).
6345 ;
6346
6347 (define_expand "subdi3"
6348 [(parallel
6349 [(set (match_operand:DI 0 "register_operand" "")
6350 (minus:DI (match_operand:DI 1 "register_operand" "")
6351 (match_operand:DI 2 "general_operand" "")))
6352 (clobber (reg:CC CC_REGNUM))])]
6353 ""
6354 "")
6355
6356 (define_insn "*subdi3_sign"
6357 [(set (match_operand:DI 0 "register_operand" "=d,d")
6358 (minus:DI (match_operand:DI 1 "register_operand" "0,0")
6359 (sign_extend:DI (match_operand:SI 2 "general_operand" "d,T"))))
6360 (clobber (reg:CC CC_REGNUM))]
6361 "TARGET_ZARCH"
6362 "@
6363 sgfr\t%0,%2
6364 sgf\t%0,%2"
6365 [(set_attr "op_type" "RRE,RXY")
6366 (set_attr "z10prop" "z10_c,*")
6367 (set_attr "z196prop" "z196_cracked")])
6368
6369 (define_insn "*subdi3_zero_cc"
6370 [(set (reg CC_REGNUM)
6371 (compare (minus:DI (match_operand:DI 1 "register_operand" "0,0")
6372 (zero_extend:DI (match_operand:SI 2 "general_operand" "d,T")))
6373 (const_int 0)))
6374 (set (match_operand:DI 0 "register_operand" "=d,d")
6375 (minus:DI (match_dup 1) (zero_extend:DI (match_dup 2))))]
6376 "s390_match_ccmode (insn, CCLmode) && TARGET_ZARCH"
6377 "@
6378 slgfr\t%0,%2
6379 slgf\t%0,%2"
6380 [(set_attr "op_type" "RRE,RXY")
6381 (set_attr "z10prop" "z10_super_c_E1,z10_super_E1")])
6382
6383 (define_insn "*subdi3_zero_cconly"
6384 [(set (reg CC_REGNUM)
6385 (compare (minus:DI (match_operand:DI 1 "register_operand" "0,0")
6386 (zero_extend:DI (match_operand:SI 2 "general_operand" "d,T")))
6387 (const_int 0)))
6388 (clobber (match_scratch:DI 0 "=d,d"))]
6389 "s390_match_ccmode (insn, CCLmode) && TARGET_ZARCH"
6390 "@
6391 slgfr\t%0,%2
6392 slgf\t%0,%2"
6393 [(set_attr "op_type" "RRE,RXY")
6394 (set_attr "z10prop" "z10_super_c_E1,z10_super_E1")])
6395
6396 (define_insn "*subdi3_zero"
6397 [(set (match_operand:DI 0 "register_operand" "=d,d")
6398 (minus:DI (match_operand:DI 1 "register_operand" "0,0")
6399 (zero_extend:DI (match_operand:SI 2 "general_operand" "d,T"))))
6400 (clobber (reg:CC CC_REGNUM))]
6401 "TARGET_ZARCH"
6402 "@
6403 slgfr\t%0,%2
6404 slgf\t%0,%2"
6405 [(set_attr "op_type" "RRE,RXY")
6406 (set_attr "z10prop" "z10_super_c_E1,z10_super_E1")])
6407
6408 (define_insn_and_split "*subdi3_31z"
6409 [(set (match_operand:DI 0 "register_operand" "=&d")
6410 (minus:DI (match_operand:DI 1 "register_operand" "0")
6411 (match_operand:DI 2 "general_operand" "do") ) )
6412 (clobber (reg:CC CC_REGNUM))]
6413 "!TARGET_ZARCH"
6414 "#"
6415 "&& reload_completed"
6416 [(parallel
6417 [(set (reg:CCL2 CC_REGNUM)
6418 (compare:CCL2 (minus:SI (match_dup 7) (match_dup 8))
6419 (match_dup 7)))
6420 (set (match_dup 6) (minus:SI (match_dup 7) (match_dup 8)))])
6421 (parallel
6422 [(set (match_dup 3) (minus:SI (minus:SI (match_dup 4) (match_dup 5))
6423 (gtu:SI (reg:CCL2 CC_REGNUM) (const_int 0))))
6424 (clobber (reg:CC CC_REGNUM))])]
6425 "operands[3] = operand_subword (operands[0], 0, 0, DImode);
6426 operands[4] = operand_subword (operands[1], 0, 0, DImode);
6427 operands[5] = operand_subword (operands[2], 0, 0, DImode);
6428 operands[6] = operand_subword (operands[0], 1, 0, DImode);
6429 operands[7] = operand_subword (operands[1], 1, 0, DImode);
6430 operands[8] = operand_subword (operands[2], 1, 0, DImode);")
6431
6432 ;
6433 ; subsi3 instruction pattern(s).
6434 ;
6435
6436 (define_expand "subsi3"
6437 [(parallel
6438 [(set (match_operand:SI 0 "register_operand" "")
6439 (minus:SI (match_operand:SI 1 "register_operand" "")
6440 (match_operand:SI 2 "general_operand" "")))
6441 (clobber (reg:CC CC_REGNUM))])]
6442 ""
6443 "")
6444
6445 (define_insn "*subsi3_sign"
6446 [(set (match_operand:SI 0 "register_operand" "=d,d")
6447 (minus:SI (match_operand:SI 1 "register_operand" "0,0")
6448 (sign_extend:SI (match_operand:HI 2 "memory_operand" "R,T"))))
6449 (clobber (reg:CC CC_REGNUM))]
6450 ""
6451 "@
6452 sh\t%0,%2
6453 shy\t%0,%2"
6454 [(set_attr "op_type" "RX,RXY")
6455 (set_attr "cpu_facility" "*,longdisp")
6456 (set_attr "z196prop" "z196_cracked,z196_cracked")])
6457
6458 ;
6459 ; sub(di|si)3 instruction pattern(s).
6460 ;
6461
6462 ; sr, s, sy, sgr, sg, srk, sgrk
6463 (define_insn "*sub<mode>3"
6464 [(set (match_operand:GPR 0 "register_operand" "=d,d,d,d")
6465 (minus:GPR (match_operand:GPR 1 "register_operand" "0,d,0,0")
6466 (match_operand:GPR 2 "general_operand" "d,d,R,T") ) )
6467 (clobber (reg:CC CC_REGNUM))]
6468 ""
6469 "@
6470 s<g>r\t%0,%2
6471 s<g>rk\t%0,%1,%2
6472 s<g>\t%0,%2
6473 s<y>\t%0,%2"
6474 [(set_attr "op_type" "RR<E>,RRF,RX<Y>,RXY")
6475 (set_attr "cpu_facility" "*,z196,*,longdisp")
6476 (set_attr "z10prop" "z10_super_c_E1,*,z10_super_E1,z10_super_E1")])
6477
6478 ; slr, sl, sly, slgr, slg, slrk, slgrk
6479 (define_insn "*sub<mode>3_borrow_cc"
6480 [(set (reg CC_REGNUM)
6481 (compare (minus:GPR (match_operand:GPR 1 "register_operand" "0,d,0,0")
6482 (match_operand:GPR 2 "general_operand" "d,d,R,T"))
6483 (match_dup 1)))
6484 (set (match_operand:GPR 0 "register_operand" "=d,d,d,d")
6485 (minus:GPR (match_dup 1) (match_dup 2)))]
6486 "s390_match_ccmode (insn, CCL2mode)"
6487 "@
6488 sl<g>r\t%0,%2
6489 sl<g>rk\t%0,%1,%2
6490 sl<g>\t%0,%2
6491 sl<y>\t%0,%2"
6492 [(set_attr "op_type" "RR<E>,RRF,RX<Y>,RXY")
6493 (set_attr "cpu_facility" "*,z196,*,longdisp")
6494 (set_attr "z10prop" "z10_super_c_E1,*,z10_super_E1,z10_super_E1")])
6495
6496 ; slr, sl, sly, slgr, slg, slrk, slgrk
6497 (define_insn "*sub<mode>3_borrow_cconly"
6498 [(set (reg CC_REGNUM)
6499 (compare (minus:GPR (match_operand:GPR 1 "register_operand" "0,d,0,0")
6500 (match_operand:GPR 2 "general_operand" "d,d,R,T"))
6501 (match_dup 1)))
6502 (clobber (match_scratch:GPR 0 "=d,d,d,d"))]
6503 "s390_match_ccmode (insn, CCL2mode)"
6504 "@
6505 sl<g>r\t%0,%2
6506 sl<g>rk\t%0,%1,%2
6507 sl<g>\t%0,%2
6508 sl<y>\t%0,%2"
6509 [(set_attr "op_type" "RR<E>,RRF,RX<Y>,RXY")
6510 (set_attr "cpu_facility" "*,z196,*,longdisp")
6511 (set_attr "z10prop" "z10_super_c_E1,*,z10_super_E1,z10_super_E1")])
6512
6513 ; slr, sl, sly, slgr, slg, slrk, slgrk
6514 (define_insn "*sub<mode>3_cc"
6515 [(set (reg CC_REGNUM)
6516 (compare (minus:GPR (match_operand:GPR 1 "register_operand" "0,d,0,0")
6517 (match_operand:GPR 2 "general_operand" "d,d,R,T"))
6518 (const_int 0)))
6519 (set (match_operand:GPR 0 "register_operand" "=d,d,d,d")
6520 (minus:GPR (match_dup 1) (match_dup 2)))]
6521 "s390_match_ccmode (insn, CCLmode)"
6522 "@
6523 sl<g>r\t%0,%2
6524 sl<g>rk\t%0,%1,%2
6525 sl<g>\t%0,%2
6526 sl<y>\t%0,%2"
6527 [(set_attr "op_type" "RR<E>,RRF,RX<Y>,RXY")
6528 (set_attr "cpu_facility" "*,z196,*,longdisp")
6529 (set_attr "z10prop" "z10_super_c_E1,*,z10_super_E1,z10_super_E1")])
6530
6531 ; slr, sl, sly, slgr, slg, slrk, slgrk
6532 (define_insn "*sub<mode>3_cc2"
6533 [(set (reg CC_REGNUM)
6534 (compare (match_operand:GPR 1 "register_operand" "0,d,0,0")
6535 (match_operand:GPR 2 "general_operand" "d,d,R,T")))
6536 (set (match_operand:GPR 0 "register_operand" "=d,d,d,d")
6537 (minus:GPR (match_dup 1) (match_dup 2)))]
6538 "s390_match_ccmode (insn, CCL3mode)"
6539 "@
6540 sl<g>r\t%0,%2
6541 sl<g>rk\t%0,%1,%2
6542 sl<g>\t%0,%2
6543 sl<y>\t%0,%2"
6544 [(set_attr "op_type" "RR<E>,RRF,RX<Y>,RXY")
6545 (set_attr "cpu_facility" "*,z196,*,longdisp")
6546 (set_attr "z10prop" "z10_super_c_E1,*,z10_super_E1,z10_super_E1")])
6547
6548 ; slr, sl, sly, slgr, slg, slrk, slgrk
6549 (define_insn "*sub<mode>3_cconly"
6550 [(set (reg CC_REGNUM)
6551 (compare (minus:GPR (match_operand:GPR 1 "register_operand" "0,d,0,0")
6552 (match_operand:GPR 2 "general_operand" "d,d,R,T"))
6553 (const_int 0)))
6554 (clobber (match_scratch:GPR 0 "=d,d,d,d"))]
6555 "s390_match_ccmode (insn, CCLmode)"
6556 "@
6557 sl<g>r\t%0,%2
6558 sl<g>rk\t%0,%1,%2
6559 sl<g>\t%0,%2
6560 sl<y>\t%0,%2"
6561 [(set_attr "op_type" "RR<E>,RRF,RX<Y>,RXY")
6562 (set_attr "cpu_facility" "*,z196,*,longdisp")
6563 (set_attr "z10prop" "z10_super_c_E1,*,z10_super_E1,z10_super_E1")])
6564
6565
6566 ; slr, sl, sly, slgr, slg, slrk, slgrk
6567 (define_insn "*sub<mode>3_cconly2"
6568 [(set (reg CC_REGNUM)
6569 (compare (match_operand:GPR 1 "register_operand" "0,d,0,0")
6570 (match_operand:GPR 2 "general_operand" "d,d,R,T")))
6571 (clobber (match_scratch:GPR 0 "=d,d,d,d"))]
6572 "s390_match_ccmode (insn, CCL3mode)"
6573 "@
6574 sl<g>r\t%0,%2
6575 sl<g>rk\t%0,%1,%2
6576 sl<g>\t%0,%2
6577 sl<y>\t%0,%2"
6578 [(set_attr "op_type" "RR<E>,RRF,RX<Y>,RXY")
6579 (set_attr "cpu_facility" "*,z196,*,longdisp")
6580 (set_attr "z10prop" "z10_super_c_E1,*,z10_super_E1,z10_super_E1")])
6581
6582 (define_insn "*subdi3_sign"
6583 [(set (match_operand:DI 0 "register_operand" "=d")
6584 (minus:DI (match_operand:DI 1 "register_operand" "0")
6585 (sign_extend:DI (match_operand:HI 2 "memory_operand" "T"))))
6586 (clobber (reg:CC CC_REGNUM))]
6587 "TARGET_Z14"
6588 "sgh\t%0,%2"
6589 [(set_attr "op_type" "RXY")])
6590
6591 ; Jump to label OP3 if OP1 - OP2 results in a signed overflow
6592 (define_expand "subv<mode>4"
6593 [(parallel
6594 [(set (reg:CCO CC_REGNUM)
6595 (compare:CCO (minus:<DBL>
6596 (sign_extend:<DBL> (match_operand:GPR 1 "nonimmediate_operand"))
6597 (sign_extend:<DBL> (match_operand:GPR 2 "nonimmediate_operand")))
6598 (sign_extend:<DBL> (minus:GPR (match_dup 1) (match_dup 2)))))
6599 (set (match_operand:GPR 0 "nonimmediate_operand")
6600 (minus:GPR (match_dup 1) (match_dup 2)))])
6601 (set (pc)
6602 (if_then_else (ne (reg:CCO CC_REGNUM) (const_int 0))
6603 (label_ref (match_operand 3))
6604 (pc)))]
6605 "")
6606
6607 ; sr, s, sy, sgr, sg, srk, sgrk
6608 (define_insn "*subv<mode>3_ccoverflow"
6609 [(set (reg CC_REGNUM)
6610 (compare (minus:<DBL>
6611 (sign_extend:<DBL> (match_operand:GPR 1 "nonimmediate_operand" "0,d,0,0"))
6612 (sign_extend:<DBL> (match_operand:GPR 2 "nonimmediate_operand" "d,d,R,T")))
6613 (sign_extend:<DBL> (minus:GPR (match_dup 1) (match_dup 2)))))
6614 (set (match_operand:GPR 0 "register_operand" "=d,d,d,d")
6615 (minus:GPR (match_dup 1) (match_dup 2)))]
6616 "s390_match_ccmode (insn, CCOmode)"
6617 "@
6618 s<g>r\t%0,%2
6619 s<g>rk\t%0,%1,%2
6620 s<g>\t%0,%2
6621 s<y>\t%0,%2"
6622 [(set_attr "op_type" "RR<E>,RRF,RX<Y>,RXY")
6623 (set_attr "cpu_facility" "*,z196,*,longdisp")
6624 (set_attr "z10prop" "z10_super_c_E1,*,z10_super_E1,z10_super_E1")])
6625
6626
6627 ;
6628 ; sub(tf|df|sf|td|dd)3 instruction pattern(s).
6629 ;
6630
6631 ; FIXME: (clobber (match_scratch:CC 3 "=c,c,c,X,X")) does not work - why?
6632 ; sxbr, sdbr, sebr, sdb, seb, sxtr, sdtr
6633 (define_insn "sub<mode>3<tf_fpr>"
6634 [(set (match_operand:FP 0 "register_operand" "=f,f,f,v,v")
6635 (minus:FP (match_operand:FP 1 "register_operand" "f,0,0,v,v")
6636 (match_operand:FP 2 "general_operand" "f,f,R,v,v")))
6637 (clobber (reg:CC CC_REGNUM))]
6638 "TARGET_HARD_FLOAT"
6639 "@
6640 s<xde>tr\t%0,%1,%2
6641 s<xde>br\t%0,%2
6642 s<xde>b\t%0,%2
6643 wfsdb\t%v0,%v1,%v2
6644 wfssb\t%v0,%v1,%v2"
6645 [(set_attr "op_type" "RRF,RRE,RXE,VRR,VRR")
6646 (set_attr "type" "fsimp<type>")
6647 (set_attr "cpu_facility" "*,*,*,vx,vxe")
6648 (set_attr "enabled" "<nBFP>,<nDFP>,<DSF>,<DF>,<SF>")])
6649
6650 ; sxbr, sdbr, sebr, sdb, seb, sxtr, sdtr
6651 (define_insn "*sub<mode>3_cc"
6652 [(set (reg CC_REGNUM)
6653 (compare (minus:FP (match_operand:FP 1 "nonimmediate_operand" "f,0,0")
6654 (match_operand:FP 2 "general_operand" "f,f,R"))
6655 (match_operand:FP 3 "const0_operand" "")))
6656 (set (match_operand:FP 0 "register_operand" "=f,f,f")
6657 (minus:FP (match_dup 1) (match_dup 2)))]
6658 "s390_match_ccmode (insn, CCSmode) && TARGET_HARD_FLOAT"
6659 "@
6660 s<xde>tr\t%0,%1,%2
6661 s<xde>br\t%0,%2
6662 s<xde>b\t%0,%2"
6663 [(set_attr "op_type" "RRF,RRE,RXE")
6664 (set_attr "type" "fsimp<type>")
6665 (set_attr "enabled" "<nBFP>,<nDFP>,<DSF>")])
6666
6667 ; sxbr, sdbr, sebr, sdb, seb, sxtr, sdtr
6668 (define_insn "*sub<mode>3_cconly"
6669 [(set (reg CC_REGNUM)
6670 (compare (minus:FP (match_operand:FP 1 "nonimmediate_operand" "f,0,0")
6671 (match_operand:FP 2 "general_operand" "f,f,R"))
6672 (match_operand:FP 3 "const0_operand" "")))
6673 (clobber (match_scratch:FP 0 "=f,f,f"))]
6674 "s390_match_ccmode (insn, CCSmode) && TARGET_HARD_FLOAT"
6675 "@
6676 s<xde>tr\t%0,%1,%2
6677 s<xde>br\t%0,%2
6678 s<xde>b\t%0,%2"
6679 [(set_attr "op_type" "RRF,RRE,RXE")
6680 (set_attr "type" "fsimp<type>")
6681 (set_attr "enabled" "<nBFP>,<nDFP>,<DSF>")])
6682
6683
6684 ;;
6685 ;;- Conditional add/subtract instructions.
6686 ;;
6687
6688 ;
6689 ; add(di|si)cc instruction pattern(s).
6690 ;
6691
6692 ; the following 4 patterns are used when the result of an add with
6693 ; carry is checked for an overflow condition
6694
6695 ; op1 + op2 + c < op1
6696
6697 ; alcr, alc, alcgr, alcg
6698 (define_insn "*add<mode>3_alc_carry1_cc"
6699 [(set (reg CC_REGNUM)
6700 (compare
6701 (plus:GPR (plus:GPR (match_operand:GPR 3 "s390_alc_comparison" "")
6702 (match_operand:GPR 1 "nonimmediate_operand" "%0,0"))
6703 (match_operand:GPR 2 "general_operand" "d,T"))
6704 (match_dup 1)))
6705 (set (match_operand:GPR 0 "register_operand" "=d,d")
6706 (plus:GPR (plus:GPR (match_dup 3) (match_dup 1)) (match_dup 2)))]
6707 "s390_match_ccmode (insn, CCL1mode)"
6708 "@
6709 alc<g>r\t%0,%2
6710 alc<g>\t%0,%2"
6711 [(set_attr "op_type" "RRE,RXY")
6712 (set_attr "z196prop" "z196_alone,z196_alone")])
6713
6714 ; alcr, alc, alcgr, alcg
6715 (define_insn "*add<mode>3_alc_carry1_cconly"
6716 [(set (reg CC_REGNUM)
6717 (compare
6718 (plus:GPR (plus:GPR (match_operand:GPR 3 "s390_alc_comparison" "")
6719 (match_operand:GPR 1 "nonimmediate_operand" "%0,0"))
6720 (match_operand:GPR 2 "general_operand" "d,T"))
6721 (match_dup 1)))
6722 (clobber (match_scratch:GPR 0 "=d,d"))]
6723 "s390_match_ccmode (insn, CCL1mode)"
6724 "@
6725 alc<g>r\t%0,%2
6726 alc<g>\t%0,%2"
6727 [(set_attr "op_type" "RRE,RXY")
6728 (set_attr "z196prop" "z196_alone,z196_alone")])
6729
6730 ; op1 + op2 + c < op2
6731
6732 ; alcr, alc, alcgr, alcg
6733 (define_insn "*add<mode>3_alc_carry2_cc"
6734 [(set (reg CC_REGNUM)
6735 (compare
6736 (plus:GPR (plus:GPR (match_operand:GPR 3 "s390_alc_comparison" "")
6737 (match_operand:GPR 1 "nonimmediate_operand" "%0,0"))
6738 (match_operand:GPR 2 "general_operand" "d,T"))
6739 (match_dup 2)))
6740 (set (match_operand:GPR 0 "register_operand" "=d,d")
6741 (plus:GPR (plus:GPR (match_dup 3) (match_dup 1)) (match_dup 2)))]
6742 "s390_match_ccmode (insn, CCL1mode)"
6743 "@
6744 alc<g>r\t%0,%2
6745 alc<g>\t%0,%2"
6746 [(set_attr "op_type" "RRE,RXY")])
6747
6748 ; alcr, alc, alcgr, alcg
6749 (define_insn "*add<mode>3_alc_carry2_cconly"
6750 [(set (reg CC_REGNUM)
6751 (compare
6752 (plus:GPR (plus:GPR (match_operand:GPR 3 "s390_alc_comparison" "")
6753 (match_operand:GPR 1 "nonimmediate_operand" "%0,0"))
6754 (match_operand:GPR 2 "general_operand" "d,T"))
6755 (match_dup 2)))
6756 (clobber (match_scratch:GPR 0 "=d,d"))]
6757 "s390_match_ccmode (insn, CCL1mode)"
6758 "@
6759 alc<g>r\t%0,%2
6760 alc<g>\t%0,%2"
6761 [(set_attr "op_type" "RRE,RXY")])
6762
6763 ; alcr, alc, alcgr, alcg
6764 (define_insn "*add<mode>3_alc_cc"
6765 [(set (reg CC_REGNUM)
6766 (compare
6767 (plus:GPR (plus:GPR (match_operand:GPR 3 "s390_alc_comparison" "")
6768 (match_operand:GPR 1 "nonimmediate_operand" "%0,0"))
6769 (match_operand:GPR 2 "general_operand" "d,T"))
6770 (const_int 0)))
6771 (set (match_operand:GPR 0 "register_operand" "=d,d")
6772 (plus:GPR (plus:GPR (match_dup 3) (match_dup 1)) (match_dup 2)))]
6773 "s390_match_ccmode (insn, CCLmode)"
6774 "@
6775 alc<g>r\t%0,%2
6776 alc<g>\t%0,%2"
6777 [(set_attr "op_type" "RRE,RXY")])
6778
6779 ; alcr, alc, alcgr, alcg
6780 (define_insn "*add<mode>3_alc"
6781 [(set (match_operand:GPR 0 "register_operand" "=d,d")
6782 (plus:GPR (plus:GPR (match_operand:GPR 3 "s390_alc_comparison" "")
6783 (match_operand:GPR 1 "nonimmediate_operand" "%0,0"))
6784 (match_operand:GPR 2 "general_operand" "d,T")))
6785 (clobber (reg:CC CC_REGNUM))]
6786 ""
6787 "@
6788 alc<g>r\t%0,%2
6789 alc<g>\t%0,%2"
6790 [(set_attr "op_type" "RRE,RXY")])
6791
6792 ; slbr, slb, slbgr, slbg
6793 (define_insn "*sub<mode>3_slb_cc"
6794 [(set (reg CC_REGNUM)
6795 (compare
6796 (minus:GPR (minus:GPR (match_operand:GPR 1 "nonimmediate_operand" "0,0")
6797 (match_operand:GPR 2 "general_operand" "d,T"))
6798 (match_operand:GPR 3 "s390_slb_comparison" ""))
6799 (const_int 0)))
6800 (set (match_operand:GPR 0 "register_operand" "=d,d")
6801 (minus:GPR (minus:GPR (match_dup 1) (match_dup 2)) (match_dup 3)))]
6802 "s390_match_ccmode (insn, CCLmode)"
6803 "@
6804 slb<g>r\t%0,%2
6805 slb<g>\t%0,%2"
6806 [(set_attr "op_type" "RRE,RXY")
6807 (set_attr "z10prop" "z10_c,*")])
6808
6809 ; slbr, slb, slbgr, slbg
6810 (define_insn "*sub<mode>3_slb"
6811 [(set (match_operand:GPR 0 "register_operand" "=d,d")
6812 (minus:GPR (minus:GPR (match_operand:GPR 1 "nonimmediate_operand" "0,0")
6813 (match_operand:GPR 2 "general_operand" "d,T"))
6814 (match_operand:GPR 3 "s390_slb_comparison" "")))
6815 (clobber (reg:CC CC_REGNUM))]
6816 ""
6817 "@
6818 slb<g>r\t%0,%2
6819 slb<g>\t%0,%2"
6820 [(set_attr "op_type" "RRE,RXY")
6821 (set_attr "z10prop" "z10_c,*")])
6822
6823 (define_expand "add<mode>cc"
6824 [(match_operand:GPR 0 "register_operand" "")
6825 (match_operand 1 "comparison_operator" "")
6826 (match_operand:GPR 2 "register_operand" "")
6827 (match_operand:GPR 3 "const_int_operand" "")]
6828 ""
6829 "if (!s390_expand_addcc (GET_CODE (operands[1]),
6830 XEXP (operands[1], 0), XEXP (operands[1], 1),
6831 operands[0], operands[2],
6832 operands[3])) FAIL; DONE;")
6833
6834 ;
6835 ; scond instruction pattern(s).
6836 ;
6837
6838 (define_insn_and_split "*scond<mode>"
6839 [(set (match_operand:GPR 0 "register_operand" "=&d")
6840 (match_operand:GPR 1 "s390_alc_comparison" ""))
6841 (clobber (reg:CC CC_REGNUM))]
6842 ""
6843 "#"
6844 "&& reload_completed"
6845 [(set (match_dup 0) (const_int 0))
6846 (parallel
6847 [(set (match_dup 0) (plus:GPR (plus:GPR (match_dup 1) (match_dup 0))
6848 (match_dup 0)))
6849 (clobber (reg:CC CC_REGNUM))])]
6850 "")
6851
6852 (define_insn_and_split "*scond<mode>_neg"
6853 [(set (match_operand:GPR 0 "register_operand" "=&d")
6854 (match_operand:GPR 1 "s390_slb_comparison" ""))
6855 (clobber (reg:CC CC_REGNUM))]
6856 ""
6857 "#"
6858 "&& reload_completed"
6859 [(set (match_dup 0) (const_int 0))
6860 (parallel
6861 [(set (match_dup 0) (minus:GPR (minus:GPR (match_dup 0) (match_dup 0))
6862 (match_dup 1)))
6863 (clobber (reg:CC CC_REGNUM))])
6864 (parallel
6865 [(set (match_dup 0) (neg:GPR (match_dup 0)))
6866 (clobber (reg:CC CC_REGNUM))])]
6867 "")
6868
6869
6870 (define_expand "cstore<mode>4"
6871 [(set (match_operand:SI 0 "register_operand" "")
6872 (match_operator:SI 1 "s390_scond_operator"
6873 [(match_operand:GPR 2 "register_operand" "")
6874 (match_operand:GPR 3 "general_operand" "")]))]
6875 ""
6876 "if (!s390_expand_addcc (GET_CODE (operands[1]), operands[2], operands[3],
6877 operands[0], const0_rtx, const1_rtx)) FAIL; DONE;")
6878
6879 (define_expand "cstorecc4"
6880 [(parallel
6881 [(set (match_operand:SI 0 "register_operand" "")
6882 (match_operator:SI 1 "s390_eqne_operator"
6883 [(match_operand 2 "cc_reg_operand")
6884 (match_operand 3 "const0_operand")]))
6885 (clobber (reg:CC CC_REGNUM))])]
6886 ""
6887 "machine_mode mode = GET_MODE (operands[2]);
6888 if (TARGET_Z196)
6889 {
6890 rtx cond, ite;
6891
6892 if (GET_CODE (operands[1]) == NE)
6893 cond = gen_rtx_NE (VOIDmode, operands[2], const0_rtx);
6894 else
6895 cond = gen_rtx_EQ (VOIDmode, operands[2], const0_rtx);
6896 ite = gen_rtx_IF_THEN_ELSE (SImode, cond, const1_rtx, const0_rtx);
6897 emit_insn (gen_rtx_SET (operands[0], ite));
6898 }
6899 else
6900 {
6901 if (mode != CCZ1mode)
6902 FAIL;
6903 emit_insn (gen_sne (operands[0], operands[2]));
6904 if (GET_CODE (operands[1]) == EQ)
6905 emit_insn (gen_xorsi3 (operands[0], operands[0], const1_rtx));
6906 }
6907 DONE;")
6908
6909 (define_insn_and_split "sne"
6910 [(set (match_operand:SI 0 "register_operand" "=d")
6911 (ne:SI (match_operand:CCZ1 1 "register_operand" "0")
6912 (const_int 0)))
6913 (clobber (reg:CC CC_REGNUM))]
6914 ""
6915 "#"
6916 "reload_completed"
6917 [(parallel
6918 [(set (match_dup 0) (ashiftrt:SI (match_dup 0) (const_int 28)))
6919 (clobber (reg:CC CC_REGNUM))])])
6920
6921 ; Such patterns get directly emitted by noce_emit_store_flag.
6922 (define_insn_and_split "*cstorecc<mode>_z13"
6923 [(set (match_operand:GPR 0 "register_operand" "=&d")
6924 (match_operator:GPR 1 "s390_comparison"
6925 [(match_operand 2 "cc_reg_operand" "c")
6926 (match_operand 3 "const_int_operand" "")]))]
6927 "TARGET_Z13"
6928 "#"
6929 "reload_completed"
6930 [(set (match_dup 0) (const_int 0))
6931 (set (match_dup 0)
6932 (if_then_else:GPR
6933 (match_op_dup 1 [(match_dup 2) (match_dup 3)])
6934 (const_int 1)
6935 (match_dup 0)))])
6936
6937 ;;
6938 ;; - Conditional move instructions (introduced with z196)
6939 ;;
6940
6941 (define_expand "mov<mode>cc"
6942 [(set (match_operand:GPR 0 "nonimmediate_operand" "")
6943 (if_then_else:GPR (match_operand 1 "comparison_operator" "")
6944 (match_operand:GPR 2 "loc_operand" "")
6945 (match_operand:GPR 3 "loc_operand" "")))]
6946 "TARGET_Z196"
6947 {
6948 if (!TARGET_Z13 && CONSTANT_P (operands[2]))
6949 operands[2] = force_reg (<MODE>mode, operands[2]);
6950
6951 if (!TARGET_Z13 && CONSTANT_P (operands[3]))
6952 operands[3] = force_reg (<MODE>mode, operands[3]);
6953
6954 /* Emit the comparison insn in case we do not already have a comparison result. */
6955 if (!s390_comparison (operands[1], VOIDmode))
6956 operands[1] = s390_emit_compare (GET_CODE (operands[1]),
6957 XEXP (operands[1], 0),
6958 XEXP (operands[1], 1));
6959 })
6960
6961 ;;
6962 ;; - We do not have instructions for QImode or HImode but still
6963 ;; enable load on condition/if conversion for them.
6964 (define_expand "mov<mode>cc"
6965 [(set (match_operand:HQI 0 "nonimmediate_operand" "")
6966 (if_then_else:HQI (match_operand 1 "comparison_operator" "")
6967 (match_operand:HQI 2 "loc_operand" "")
6968 (match_operand:HQI 3 "loc_operand" "")))]
6969 "TARGET_Z196"
6970 {
6971 /* Emit the comparison insn in case we do not already have a comparison
6972 result. */
6973 if (!s390_comparison (operands[1], VOIDmode))
6974 operands[1] = s390_emit_compare (GET_CODE (operands[1]),
6975 XEXP (operands[1], 0),
6976 XEXP (operands[1], 1));
6977
6978 rtx then = operands[2];
6979 rtx els = operands[3];
6980
6981 if ((!TARGET_Z13 && CONSTANT_P (then)) || MEM_P (then))
6982 then = force_reg (<MODE>mode, then);
6983 if ((!TARGET_Z13 && CONSTANT_P (els)) || MEM_P (els))
6984 els = force_reg (<MODE>mode, els);
6985
6986 if (!CONSTANT_P (then))
6987 then = simplify_gen_subreg (E_SImode, then, <MODE>mode, 0);
6988 if (!CONSTANT_P (els))
6989 els = simplify_gen_subreg (E_SImode, els, <MODE>mode, 0);
6990
6991 rtx tmp_target = gen_reg_rtx (E_SImode);
6992 emit_insn (gen_movsicc (tmp_target, operands[1], then, els));
6993 emit_move_insn (operands[0], gen_lowpart (<MODE>mode, tmp_target));
6994 DONE;
6995 })
6996
6997
6998
6999 ; locr, loc, stoc, locgr, locg, stocg, lochi, locghi, selr, selgr
7000 (define_insn "*mov<mode>cc"
7001 [(set (match_operand:GPR 0 "nonimmediate_operand" "=d,d,d,d,d,d,d,S,S")
7002 (if_then_else:GPR
7003 (match_operator 1 "s390_comparison"
7004 [(match_operand 2 "cc_reg_operand" " c,c,c,c,c,c,c,c,c")
7005 (match_operand 5 "const_int_operand" "")])
7006 (match_operand:GPR 3 "loc_operand" " d,0,d,S,0,K,0,d,0")
7007 (match_operand:GPR 4 "loc_operand" " 0,d,d,0,S,0,K,0,d")))]
7008 "TARGET_Z196"
7009 "@
7010 loc<g>r%C1\t%0,%3
7011 loc<g>r%D1\t%0,%4
7012 sel<g>r%C1\t%0,%3,%4
7013 loc<g>%C1\t%0,%3
7014 loc<g>%D1\t%0,%4
7015 loc<g>hi%C1\t%0,%h3
7016 loc<g>hi%D1\t%0,%h4
7017 stoc<g>%C1\t%3,%0
7018 stoc<g>%D1\t%4,%0"
7019 [(set_attr "op_type" "RRF,RRF,RRF,RSY,RSY,RIE,RIE,RSY,RSY")
7020 (set_attr "cpu_facility" "*,*,z15,*,*,z13,z13,*,*")])
7021
7022 ;;
7023 ;;- Multiply instructions.
7024 ;;
7025
7026 ;
7027 ; muldi3 instruction pattern(s).
7028 ;
7029
7030 (define_expand "muldi3"
7031 [(parallel
7032 [(set (match_operand:DI 0 "register_operand")
7033 (mult:DI (match_operand:DI 1 "nonimmediate_operand")
7034 (match_operand:DI 2 "general_operand")))
7035 (clobber (reg:CC CC_REGNUM))])]
7036 "TARGET_ZARCH")
7037
7038 (define_insn "*muldi3_sign"
7039 [(set (match_operand:DI 0 "register_operand" "=d,d")
7040 (mult:DI (sign_extend:DI (match_operand:SI 2 "general_operand" "d,T"))
7041 (match_operand:DI 1 "register_operand" "0,0")))]
7042 "TARGET_ZARCH"
7043 "@
7044 msgfr\t%0,%2
7045 msgf\t%0,%2"
7046 [(set_attr "op_type" "RRE,RXY")
7047 (set_attr "type" "imuldi")])
7048
7049 (define_insn "*muldi3"
7050 [(set (match_operand:DI 0 "register_operand" "=d,d,d,d,d")
7051 (mult:DI (match_operand:DI 1 "nonimmediate_operand" "%0,d,0,0,0")
7052 (match_operand:DI 2 "general_operand" "d,d,K,T,Os")))
7053 (clobber (match_scratch:CC 3 "=X,c,X,X,X"))]
7054 "TARGET_ZARCH"
7055 "@
7056 msgr\t%0,%2
7057 msgrkc\t%0,%1,%2
7058 mghi\t%0,%h2
7059 msg\t%0,%2
7060 msgfi\t%0,%2"
7061 [(set_attr "op_type" "RRE,RRF,RI,RXY,RIL")
7062 (set_attr "type" "imuldi")
7063 (set_attr "cpu_facility" "*,z14,*,*,z10")])
7064
7065 (define_insn "mulditi3"
7066 [(set (match_operand:TI 0 "register_operand" "=d,d")
7067 (mult:TI (sign_extend:TI
7068 (match_operand:DI 1 "register_operand" "%d,0"))
7069 (sign_extend:TI
7070 (match_operand:DI 2 "nonimmediate_operand" " d,T"))))]
7071 "TARGET_Z14"
7072 "@
7073 mgrk\t%0,%1,%2
7074 mg\t%0,%2"
7075 [(set_attr "op_type" "RRF,RXY")])
7076
7077 ; Combine likes op1 and op2 to be swapped sometimes.
7078 (define_insn "mulditi3_2"
7079 [(set (match_operand:TI 0 "register_operand" "=d,d")
7080 (mult:TI (sign_extend:TI
7081 (match_operand:DI 1 "nonimmediate_operand" "%d,T"))
7082 (sign_extend:TI
7083 (match_operand:DI 2 "register_operand" " d,0"))))]
7084 "TARGET_Z14"
7085 "@
7086 mgrk\t%0,%1,%2
7087 mg\t%0,%1"
7088 [(set_attr "op_type" "RRF,RXY")])
7089
7090 (define_insn "*muldi3_sign"
7091 [(set (match_operand:DI 0 "register_operand" "=d")
7092 (mult:DI (sign_extend:DI (match_operand:HI 2 "memory_operand" "T"))
7093 (match_operand:DI 1 "register_operand" "0")))]
7094 "TARGET_Z14"
7095 "mgh\t%0,%2"
7096 [(set_attr "op_type" "RXY")])
7097
7098
7099 ;
7100 ; mulsi3 instruction pattern(s).
7101 ;
7102
7103 (define_expand "mulsi3"
7104 [(parallel
7105 [(set (match_operand:SI 0 "register_operand" "=d,d,d,d,d,d")
7106 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%0,d,0,0,0,0")
7107 (match_operand:SI 2 "general_operand" "d,d,K,R,T,Os")))
7108 (clobber (reg:CC CC_REGNUM))])]
7109 "")
7110
7111 (define_insn "*mulsi3_sign"
7112 [(set (match_operand:SI 0 "register_operand" "=d,d")
7113 (mult:SI (sign_extend:SI (match_operand:HI 2 "memory_operand" "R,T"))
7114 (match_operand:SI 1 "register_operand" "0,0")))]
7115 ""
7116 "@
7117 mh\t%0,%2
7118 mhy\t%0,%2"
7119 [(set_attr "op_type" "RX,RXY")
7120 (set_attr "type" "imulhi")
7121 (set_attr "cpu_facility" "*,z10")])
7122
7123 (define_insn "*mulsi3"
7124 [(set (match_operand:SI 0 "register_operand" "=d,d,d,d,d,d")
7125 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%0,d,0,0,0,0")
7126 (match_operand:SI 2 "general_operand" "d,d,K,R,T,Os")))
7127 (clobber (match_scratch:CC 3 "=X,c,X,X,X,X"))]
7128 ""
7129 "@
7130 msr\t%0,%2
7131 msrkc\t%0,%1,%2
7132 mhi\t%0,%h2
7133 ms\t%0,%2
7134 msy\t%0,%2
7135 msfi\t%0,%2"
7136 [(set_attr "op_type" "RRE,RRF,RI,RX,RXY,RIL")
7137 (set_attr "type" "imulsi,*,imulhi,imulsi,imulsi,imulsi")
7138 (set_attr "cpu_facility" "*,z14,*,*,longdisp,z10")])
7139
7140 ;
7141 ; mulsidi3 instruction pattern(s).
7142 ;
7143
7144 (define_insn "mulsidi3"
7145 [(set (match_operand:DI 0 "register_operand" "=d,d,d")
7146 (mult:DI (sign_extend:DI
7147 (match_operand:SI 1 "register_operand" "%0,0,0"))
7148 (sign_extend:DI
7149 (match_operand:SI 2 "nonimmediate_operand" "d,R,T"))))]
7150 "!TARGET_ZARCH"
7151 "@
7152 mr\t%0,%2
7153 m\t%0,%2
7154 mfy\t%0,%2"
7155 [(set_attr "op_type" "RR,RX,RXY")
7156 (set_attr "type" "imulsi")
7157 (set_attr "cpu_facility" "*,*,z10")])
7158
7159 ; Jump to label OP3 if OP1 * OP2 results in a signed overflow
7160 (define_expand "mulv<mode>4"
7161 [(parallel
7162 [(set (reg:CCO CC_REGNUM)
7163 (compare:CCO (mult:<DBL>
7164 (sign_extend:<DBL> (match_operand:GPR 1 "register_operand"))
7165 (sign_extend:<DBL> (match_operand:GPR 2 "nonimmediate_operand")))
7166 (sign_extend:<DBL> (mult:GPR (match_dup 1) (match_dup 2)))))
7167 (set (match_operand:GPR 0 "register_operand")
7168 (mult:GPR (match_dup 1) (match_dup 2)))])
7169 (set (pc)
7170 (if_then_else (ne (reg:CCO CC_REGNUM) (const_int 0))
7171 (label_ref (match_operand 3))
7172 (pc)))]
7173 "TARGET_Z14")
7174
7175 ; msrkc, msc, msgrkc, msgc
7176 (define_insn "*mulv<mode>3_ccoverflow"
7177 [(set (reg CC_REGNUM)
7178 (compare (mult:<DBL>
7179 (sign_extend:<DBL> (match_operand:GPR 1 "register_operand" "%d,0"))
7180 (sign_extend:<DBL> (match_operand:GPR 2 "nonimmediate_operand" " d,T")))
7181 (sign_extend:<DBL> (mult:GPR (match_dup 1) (match_dup 2)))))
7182 (set (match_operand:GPR 0 "register_operand" "=d,d")
7183 (mult:GPR (match_dup 1) (match_dup 2)))]
7184 "s390_match_ccmode (insn, CCOmode) && TARGET_Z14"
7185 "@
7186 ms<g>rkc\t%0,%1,%2
7187 ms<g>c\t%0,%2"
7188 [(set_attr "op_type" "RRF,RXY")])
7189
7190
7191 ;
7192 ; umul instruction pattern(s).
7193 ;
7194
7195 ; mlr, ml, mlgr, mlg
7196 (define_insn "umul<dwh><mode>3"
7197 [(set (match_operand:DW 0 "register_operand" "=d,d")
7198 (mult:DW (zero_extend:DW
7199 (match_operand:<DWH> 1 "register_operand" "%0,0"))
7200 (zero_extend:DW
7201 (match_operand:<DWH> 2 "nonimmediate_operand" " d,T"))))]
7202 ""
7203 "@
7204 ml<tg>r\t%0,%2
7205 ml<tg>\t%0,%2"
7206 [(set_attr "op_type" "RRE,RXY")
7207 (set_attr "type" "imul<dwh>")])
7208
7209 ;
7210 ; mul(tf|df|sf|td|dd)3 instruction pattern(s).
7211 ;
7212
7213 ; mxbr, mdbr, meebr, mxb, mxb, meeb, mdtr, mxtr
7214 (define_insn "mul<mode>3<tf_fpr>"
7215 [(set (match_operand:FP 0 "register_operand" "=f,f,f,v,v")
7216 (mult:FP (match_operand:FP 1 "nonimmediate_operand" "%f,0,0,v,v")
7217 (match_operand:FP 2 "general_operand" "f,f,R,v,v")))]
7218 "TARGET_HARD_FLOAT"
7219 "@
7220 m<xdee>tr\t%0,%1,%2
7221 m<xdee>br\t%0,%2
7222 m<xdee>b\t%0,%2
7223 wfmdb\t%v0,%v1,%v2
7224 wfmsb\t%v0,%v1,%v2"
7225 [(set_attr "op_type" "RRF,RRE,RXE,VRR,VRR")
7226 (set_attr "type" "fmul<type>")
7227 (set_attr "cpu_facility" "*,*,*,vx,vxe")
7228 (set_attr "enabled" "<nBFP>,<nDFP>,<DSF>,<DF>,<SF>")])
7229
7230 ; madbr, maebr, maxb, madb, maeb
7231 (define_insn "fma<mode>4"
7232 [(set (match_operand:DSF 0 "register_operand" "=f,f,v,v")
7233 (fma:DSF (match_operand:DSF 1 "nonimmediate_operand" "%f,f,v,v")
7234 (match_operand:DSF 2 "nonimmediate_operand" "f,R,v,v")
7235 (match_operand:DSF 3 "register_operand" "0,0,v,v")))]
7236 "TARGET_HARD_FLOAT && s390_fma_allowed_p (<MODE>mode)"
7237 "@
7238 ma<xde>br\t%0,%1,%2
7239 ma<xde>b\t%0,%1,%2
7240 wfmadb\t%v0,%v1,%v2,%v3
7241 wfmasb\t%v0,%v1,%v2,%v3"
7242 [(set_attr "op_type" "RRE,RXE,VRR,VRR")
7243 (set_attr "type" "fmadd<mode>")
7244 (set_attr "cpu_facility" "*,*,vx,vxe")
7245 (set_attr "enabled" "*,*,<DF>,<SF>")])
7246
7247 ; msxbr, msdbr, msebr, msxb, msdb, mseb
7248 (define_insn "fms<mode>4"
7249 [(set (match_operand:DSF 0 "register_operand" "=f,f,v,v")
7250 (fma:DSF (match_operand:DSF 1 "nonimmediate_operand" "%f,f,v,v")
7251 (match_operand:DSF 2 "nonimmediate_operand" "f,R,v,v")
7252 (neg:DSF (match_operand:DSF 3 "register_operand" "0,0,v,v"))))]
7253 "TARGET_HARD_FLOAT && s390_fma_allowed_p (<MODE>mode)"
7254 "@
7255 ms<xde>br\t%0,%1,%2
7256 ms<xde>b\t%0,%1,%2
7257 wfmsdb\t%v0,%v1,%v2,%v3
7258 wfmssb\t%v0,%v1,%v2,%v3"
7259 [(set_attr "op_type" "RRE,RXE,VRR,VRR")
7260 (set_attr "type" "fmadd<mode>")
7261 (set_attr "cpu_facility" "*,*,vx,vxe")
7262 (set_attr "enabled" "*,*,<DF>,<SF>")])
7263
7264 ;;
7265 ;;- Divide and modulo instructions.
7266 ;;
7267
7268 ;
7269 ; divmoddi4 instruction pattern(s).
7270 ;
7271
7272 (define_expand "divmoddi4"
7273 [(parallel [(set (match_operand:DI 0 "general_operand" "")
7274 (div:DI (match_operand:DI 1 "register_operand" "")
7275 (match_operand:DI 2 "general_operand" "")))
7276 (set (match_operand:DI 3 "general_operand" "")
7277 (mod:DI (match_dup 1) (match_dup 2)))])
7278 (clobber (match_dup 4))]
7279 "TARGET_ZARCH"
7280 {
7281 rtx div_equal, mod_equal;
7282 rtx_insn *insn;
7283
7284 div_equal = gen_rtx_DIV (DImode, operands[1], operands[2]);
7285 mod_equal = gen_rtx_MOD (DImode, operands[1], operands[2]);
7286
7287 operands[4] = gen_reg_rtx(TImode);
7288 emit_insn (gen_divmodtidi3 (operands[4], operands[1], operands[2]));
7289
7290 insn = emit_move_insn (operands[0], gen_lowpart (DImode, operands[4]));
7291 set_unique_reg_note (insn, REG_EQUAL, div_equal);
7292
7293 insn = emit_move_insn (operands[3], gen_highpart (DImode, operands[4]));
7294 set_unique_reg_note (insn, REG_EQUAL, mod_equal);
7295
7296 DONE;
7297 })
7298
7299 (define_insn "divmodtidi3"
7300 [(set (match_operand:TI 0 "register_operand" "=d,d")
7301 (ior:TI
7302 (ashift:TI
7303 (zero_extend:TI
7304 (mod:DI (match_operand:DI 1 "register_operand" "0,0")
7305 (match_operand:DI 2 "general_operand" "d,T")))
7306 (const_int 64))
7307 (zero_extend:TI (div:DI (match_dup 1) (match_dup 2)))))]
7308 "TARGET_ZARCH"
7309 "@
7310 dsgr\t%0,%2
7311 dsg\t%0,%2"
7312 [(set_attr "op_type" "RRE,RXY")
7313 (set_attr "type" "idiv")])
7314
7315 (define_insn "divmodtisi3"
7316 [(set (match_operand:TI 0 "register_operand" "=d,d")
7317 (ior:TI
7318 (ashift:TI
7319 (zero_extend:TI
7320 (mod:DI (match_operand:DI 1 "register_operand" "0,0")
7321 (sign_extend:DI
7322 (match_operand:SI 2 "nonimmediate_operand" "d,T"))))
7323 (const_int 64))
7324 (zero_extend:TI
7325 (div:DI (match_dup 1) (sign_extend:DI (match_dup 2))))))]
7326 "TARGET_ZARCH"
7327 "@
7328 dsgfr\t%0,%2
7329 dsgf\t%0,%2"
7330 [(set_attr "op_type" "RRE,RXY")
7331 (set_attr "type" "idiv")])
7332
7333 ;
7334 ; udivmoddi4 instruction pattern(s).
7335 ;
7336
7337 (define_expand "udivmoddi4"
7338 [(parallel [(set (match_operand:DI 0 "general_operand" "")
7339 (udiv:DI (match_operand:DI 1 "general_operand" "")
7340 (match_operand:DI 2 "nonimmediate_operand" "")))
7341 (set (match_operand:DI 3 "general_operand" "")
7342 (umod:DI (match_dup 1) (match_dup 2)))])
7343 (clobber (match_dup 4))]
7344 "TARGET_ZARCH"
7345 {
7346 rtx div_equal, mod_equal, equal;
7347 rtx_insn *insn;
7348
7349 div_equal = gen_rtx_UDIV (DImode, operands[1], operands[2]);
7350 mod_equal = gen_rtx_UMOD (DImode, operands[1], operands[2]);
7351 equal = gen_rtx_IOR (TImode,
7352 gen_rtx_ASHIFT (TImode,
7353 gen_rtx_ZERO_EXTEND (TImode, mod_equal),
7354 GEN_INT (64)),
7355 gen_rtx_ZERO_EXTEND (TImode, div_equal));
7356
7357 operands[4] = gen_reg_rtx(TImode);
7358 emit_clobber (operands[4]);
7359 emit_move_insn (gen_lowpart (DImode, operands[4]), operands[1]);
7360 emit_move_insn (gen_highpart (DImode, operands[4]), const0_rtx);
7361
7362 insn = emit_insn (gen_udivmodtidi3 (operands[4], operands[4], operands[2]));
7363 set_unique_reg_note (insn, REG_EQUAL, equal);
7364
7365 insn = emit_move_insn (operands[0], gen_lowpart (DImode, operands[4]));
7366 set_unique_reg_note (insn, REG_EQUAL, div_equal);
7367
7368 insn = emit_move_insn (operands[3], gen_highpart (DImode, operands[4]));
7369 set_unique_reg_note (insn, REG_EQUAL, mod_equal);
7370
7371 DONE;
7372 })
7373
7374 (define_insn "udivmodtidi3"
7375 [(set (match_operand:TI 0 "register_operand" "=d,d")
7376 (ior:TI
7377 (ashift:TI
7378 (zero_extend:TI
7379 (truncate:DI
7380 (umod:TI (match_operand:TI 1 "register_operand" "0,0")
7381 (zero_extend:TI
7382 (match_operand:DI 2 "nonimmediate_operand" "d,T")))))
7383 (const_int 64))
7384 (zero_extend:TI
7385 (truncate:DI
7386 (udiv:TI (match_dup 1) (zero_extend:TI (match_dup 2)))))))]
7387 "TARGET_ZARCH"
7388 "@
7389 dlgr\t%0,%2
7390 dlg\t%0,%2"
7391 [(set_attr "op_type" "RRE,RXY")
7392 (set_attr "type" "idiv")])
7393
7394 ;
7395 ; divmodsi4 instruction pattern(s).
7396 ;
7397
7398 (define_expand "divmodsi4"
7399 [(parallel [(set (match_operand:SI 0 "general_operand" "")
7400 (div:SI (match_operand:SI 1 "general_operand" "")
7401 (match_operand:SI 2 "nonimmediate_operand" "")))
7402 (set (match_operand:SI 3 "general_operand" "")
7403 (mod:SI (match_dup 1) (match_dup 2)))])
7404 (clobber (match_dup 4))]
7405 "!TARGET_ZARCH"
7406 {
7407 rtx div_equal, mod_equal, equal;
7408 rtx_insn *insn;
7409
7410 div_equal = gen_rtx_DIV (SImode, operands[1], operands[2]);
7411 mod_equal = gen_rtx_MOD (SImode, operands[1], operands[2]);
7412 equal = gen_rtx_IOR (DImode,
7413 gen_rtx_ASHIFT (DImode,
7414 gen_rtx_ZERO_EXTEND (DImode, mod_equal),
7415 GEN_INT (32)),
7416 gen_rtx_ZERO_EXTEND (DImode, div_equal));
7417
7418 operands[4] = gen_reg_rtx(DImode);
7419 emit_insn (gen_extendsidi2 (operands[4], operands[1]));
7420
7421 insn = emit_insn (gen_divmoddisi3 (operands[4], operands[4], operands[2]));
7422 set_unique_reg_note (insn, REG_EQUAL, equal);
7423
7424 insn = emit_move_insn (operands[0], gen_lowpart (SImode, operands[4]));
7425 set_unique_reg_note (insn, REG_EQUAL, div_equal);
7426
7427 insn = emit_move_insn (operands[3], gen_highpart (SImode, operands[4]));
7428 set_unique_reg_note (insn, REG_EQUAL, mod_equal);
7429
7430 DONE;
7431 })
7432
7433 (define_insn "divmoddisi3"
7434 [(set (match_operand:DI 0 "register_operand" "=d,d")
7435 (ior:DI
7436 (ashift:DI
7437 (zero_extend:DI
7438 (truncate:SI
7439 (mod:DI (match_operand:DI 1 "register_operand" "0,0")
7440 (sign_extend:DI
7441 (match_operand:SI 2 "nonimmediate_operand" "d,R")))))
7442 (const_int 32))
7443 (zero_extend:DI
7444 (truncate:SI
7445 (div:DI (match_dup 1) (sign_extend:DI (match_dup 2)))))))]
7446 "!TARGET_ZARCH"
7447 "@
7448 dr\t%0,%2
7449 d\t%0,%2"
7450 [(set_attr "op_type" "RR,RX")
7451 (set_attr "type" "idiv")])
7452
7453 ;
7454 ; udivsi3 and umodsi3 instruction pattern(s).
7455 ;
7456
7457 (define_expand "udivmodsi4"
7458 [(parallel [(set (match_operand:SI 0 "general_operand" "")
7459 (udiv:SI (match_operand:SI 1 "general_operand" "")
7460 (match_operand:SI 2 "nonimmediate_operand" "")))
7461 (set (match_operand:SI 3 "general_operand" "")
7462 (umod:SI (match_dup 1) (match_dup 2)))])
7463 (clobber (match_dup 4))]
7464 "!TARGET_ZARCH"
7465 {
7466 rtx div_equal, mod_equal, equal;
7467 rtx_insn *insn;
7468
7469 div_equal = gen_rtx_UDIV (SImode, operands[1], operands[2]);
7470 mod_equal = gen_rtx_UMOD (SImode, operands[1], operands[2]);
7471 equal = gen_rtx_IOR (DImode,
7472 gen_rtx_ASHIFT (DImode,
7473 gen_rtx_ZERO_EXTEND (DImode, mod_equal),
7474 GEN_INT (32)),
7475 gen_rtx_ZERO_EXTEND (DImode, div_equal));
7476
7477 operands[4] = gen_reg_rtx(DImode);
7478 emit_clobber (operands[4]);
7479 emit_move_insn (gen_lowpart (SImode, operands[4]), operands[1]);
7480 emit_move_insn (gen_highpart (SImode, operands[4]), const0_rtx);
7481
7482 insn = emit_insn (gen_udivmoddisi3 (operands[4], operands[4], operands[2]));
7483 set_unique_reg_note (insn, REG_EQUAL, equal);
7484
7485 insn = emit_move_insn (operands[0], gen_lowpart (SImode, operands[4]));
7486 set_unique_reg_note (insn, REG_EQUAL, div_equal);
7487
7488 insn = emit_move_insn (operands[3], gen_highpart (SImode, operands[4]));
7489 set_unique_reg_note (insn, REG_EQUAL, mod_equal);
7490
7491 DONE;
7492 })
7493
7494 (define_insn "udivmoddisi3"
7495 [(set (match_operand:DI 0 "register_operand" "=d,d")
7496 (ior:DI
7497 (ashift:DI
7498 (zero_extend:DI
7499 (truncate:SI
7500 (umod:DI (match_operand:DI 1 "register_operand" "0,0")
7501 (zero_extend:DI
7502 (match_operand:SI 2 "nonimmediate_operand" "d,T")))))
7503 (const_int 32))
7504 (zero_extend:DI
7505 (truncate:SI
7506 (udiv:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))))]
7507 "!TARGET_ZARCH"
7508 "@
7509 dlr\t%0,%2
7510 dl\t%0,%2"
7511 [(set_attr "op_type" "RRE,RXY")
7512 (set_attr "type" "idiv")])
7513
7514 ;
7515 ; div(df|sf)3 instruction pattern(s).
7516 ;
7517
7518 ; dxbr, ddbr, debr, dxb, ddb, deb, ddtr, dxtr
7519 (define_insn "div<mode>3<tf_fpr>"
7520 [(set (match_operand:FP 0 "register_operand" "=f,f,f,v,v")
7521 (div:FP (match_operand:FP 1 "register_operand" "f,0,0,v,v")
7522 (match_operand:FP 2 "general_operand" "f,f,R,v,v")))]
7523 "TARGET_HARD_FLOAT"
7524 "@
7525 d<xde>tr\t%0,%1,%2
7526 d<xde>br\t%0,%2
7527 d<xde>b\t%0,%2
7528 wfddb\t%v0,%v1,%v2
7529 wfdsb\t%v0,%v1,%v2"
7530 [(set_attr "op_type" "RRF,RRE,RXE,VRR,VRR")
7531 (set_attr "type" "fdiv<type>")
7532 (set_attr "cpu_facility" "*,*,*,vx,vxe")
7533 (set_attr "enabled" "<nBFP>,<nDFP>,<DSF>,<DF>,<SF>")])
7534
7535
7536 ;;
7537 ;;- And instructions.
7538 ;;
7539
7540 (define_expand "and<mode>3"
7541 [(set (match_operand:INT 0 "nonimmediate_operand" "")
7542 (and:INT (match_operand:INT 1 "nonimmediate_operand" "")
7543 (match_operand:INT 2 "general_operand" "")))
7544 (clobber (reg:CC CC_REGNUM))]
7545 ""
7546 "s390_expand_logical_operator (AND, <MODE>mode, operands); DONE;")
7547
7548 ;
7549 ; anddi3 instruction pattern(s).
7550 ;
7551
7552 (define_insn "*anddi3_cc"
7553 [(set (reg CC_REGNUM)
7554 (compare
7555 (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,d,0, d")
7556 (match_operand:DI 2 "general_operand" " d,d,T,NxxDw"))
7557 (const_int 0)))
7558 (set (match_operand:DI 0 "register_operand" "=d,d,d, d")
7559 (and:DI (match_dup 1) (match_dup 2)))]
7560 "TARGET_ZARCH && s390_match_ccmode(insn, CCTmode)"
7561 "@
7562 ngr\t%0,%2
7563 ngrk\t%0,%1,%2
7564 ng\t%0,%2
7565 risbg\t%0,%1,%s2,128+%e2,0"
7566 [(set_attr "op_type" "RRE,RRF,RXY,RIE")
7567 (set_attr "cpu_facility" "*,z196,*,z10")
7568 (set_attr "z10prop" "z10_super_E1,*,z10_super_E1,z10_super_E1")])
7569
7570 (define_insn "*anddi3_cconly"
7571 [(set (reg CC_REGNUM)
7572 (compare
7573 (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,d,0, d")
7574 (match_operand:DI 2 "general_operand" " d,d,T,NxxDw"))
7575 (const_int 0)))
7576 (clobber (match_scratch:DI 0 "=d,d,d, d"))]
7577 "TARGET_ZARCH
7578 && s390_match_ccmode(insn, CCTmode)
7579 /* Do not steal TM patterns. */
7580 && s390_single_part (operands[2], DImode, HImode, 0) < 0"
7581 "@
7582 ngr\t%0,%2
7583 ngrk\t%0,%1,%2
7584 ng\t%0,%2
7585 risbg\t%0,%1,%s2,128+%e2,0"
7586 [(set_attr "op_type" "RRE,RRF,RXY,RIE")
7587 (set_attr "cpu_facility" "*,z196,*,z10")
7588 (set_attr "z10prop" "z10_super_E1,*,z10_super_E1,z10_super_E1")])
7589
7590 (define_insn "*anddi3"
7591 [(set (match_operand:DI 0 "nonimmediate_operand"
7592 "=d,d, d, d, d, d, d, d,d,d,d, d, AQ,Q")
7593 (and:DI
7594 (match_operand:DI 1 "nonimmediate_operand"
7595 "%d,o, 0, 0, 0, 0, 0, 0,0,d,0, d, 0,0")
7596 (match_operand:DI 2 "general_operand"
7597 "M, M,N0HDF,N1HDF,N2HDF,N3HDF,N0SDF,N1SDF,d,d,T,NxxDw,NxQDF,Q")))
7598 (clobber (reg:CC CC_REGNUM))]
7599 "TARGET_ZARCH && s390_logical_operator_ok_p (operands)"
7600 "@
7601 #
7602 #
7603 nihh\t%0,%j2
7604 nihl\t%0,%j2
7605 nilh\t%0,%j2
7606 nill\t%0,%j2
7607 nihf\t%0,%m2
7608 nilf\t%0,%m2
7609 ngr\t%0,%2
7610 ngrk\t%0,%1,%2
7611 ng\t%0,%2
7612 risbg\t%0,%1,%s2,128+%e2,0
7613 #
7614 #"
7615 [(set_attr "op_type" "RRE,RXE,RI,RI,RI,RI,RIL,RIL,RRE,RRF,RXY,RIE,SI,SS")
7616 (set_attr "cpu_facility" "*,*,*,*,*,*,extimm,extimm,*,z196,*,z10,*,*")
7617 (set_attr "z10prop" "*,
7618 *,
7619 z10_super_E1,
7620 z10_super_E1,
7621 z10_super_E1,
7622 z10_super_E1,
7623 z10_super_E1,
7624 z10_super_E1,
7625 z10_super_E1,
7626 *,
7627 z10_super_E1,
7628 z10_super_E1,
7629 *,
7630 *")])
7631
7632 (define_split
7633 [(set (match_operand:DI 0 "s_operand" "")
7634 (and:DI (match_dup 0) (match_operand:DI 1 "immediate_operand" "")))
7635 (clobber (reg:CC CC_REGNUM))]
7636 "reload_completed"
7637 [(parallel
7638 [(set (match_dup 0) (and:QI (match_dup 0) (match_dup 1)))
7639 (clobber (reg:CC CC_REGNUM))])]
7640 "s390_narrow_logical_operator (AND, &operands[0], &operands[1]);")
7641
7642 ;; These two are what combine generates for (ashift (zero_extract)).
7643 (define_insn "*extzv_<mode>_srl<clobbercc_or_nocc>"
7644 [(set (match_operand:GPR 0 "register_operand" "=d")
7645 (and:GPR (lshiftrt:GPR
7646 (match_operand:GPR 1 "register_operand" "d")
7647 (match_operand:GPR 2 "nonzero_shift_count_operand" ""))
7648 (match_operand:GPR 3 "contiguous_bitmask_nowrap_operand" "")))]
7649 "<z10_or_zEC12_cond>
7650 /* Note that even for the SImode pattern, the rotate is always DImode. */
7651 && s390_extzv_shift_ok (<bitsize>, -INTVAL (operands[2]),
7652 INTVAL (operands[3]))"
7653 "<risbg_n>\t%0,%1,%<bfstart>3,128+%<bfend>3,64-%2"
7654 [(set_attr "op_type" "RIE")
7655 (set_attr "z10prop" "z10_super_E1")])
7656
7657 (define_insn "*extzv_<mode>_sll<clobbercc_or_nocc>"
7658 [(set (match_operand:GPR 0 "register_operand" "=d")
7659 (and:GPR (ashift:GPR
7660 (match_operand:GPR 1 "register_operand" "d")
7661 (match_operand:GPR 2 "nonzero_shift_count_operand" ""))
7662 (match_operand:GPR 3 "contiguous_bitmask_nowrap_operand" "")))]
7663 "<z10_or_zEC12_cond>
7664 && s390_extzv_shift_ok (<bitsize>, INTVAL (operands[2]),
7665 INTVAL (operands[3]))"
7666 "<risbg_n>\t%0,%1,%<bfstart>3,128+%<bfend>3,%2"
7667 [(set_attr "op_type" "RIE")
7668 (set_attr "z10prop" "z10_super_E1")])
7669
7670
7671 ;
7672 ; andsi3 instruction pattern(s).
7673 ;
7674
7675 (define_insn "*andsi3_cc"
7676 [(set (reg CC_REGNUM)
7677 (compare
7678 (and:SI
7679 (match_operand:SI 1 "nonimmediate_operand" "%0,0,d,0,0, d")
7680 (match_operand:SI 2 "general_operand" "Os,d,d,R,T,NxxSq"))
7681 (const_int 0)))
7682 (set (match_operand:SI 0 "register_operand" "=d,d,d,d,d, d")
7683 (and:SI (match_dup 1) (match_dup 2)))]
7684 "s390_match_ccmode(insn, CCTmode)"
7685 "@
7686 nilf\t%0,%o2
7687 nr\t%0,%2
7688 nrk\t%0,%1,%2
7689 n\t%0,%2
7690 ny\t%0,%2
7691 risbg\t%0,%1,%t2,128+%f2,0"
7692 [(set_attr "op_type" "RIL,RR,RRF,RX,RXY,RIE")
7693 (set_attr "cpu_facility" "*,*,z196,*,longdisp,z10")
7694 (set_attr "z10prop" "z10_super_E1,z10_super_E1,*,
7695 z10_super_E1,z10_super_E1,z10_super_E1")])
7696
7697 (define_insn "*andsi3_cconly"
7698 [(set (reg CC_REGNUM)
7699 (compare
7700 (and:SI
7701 (match_operand:SI 1 "nonimmediate_operand" "%0,0,d,0,0, d")
7702 (match_operand:SI 2 "general_operand" "Os,d,d,R,T,NxxSq"))
7703 (const_int 0)))
7704 (clobber (match_scratch:SI 0 "=d,d,d,d,d, d"))]
7705 "s390_match_ccmode(insn, CCTmode)
7706 /* Do not steal TM patterns. */
7707 && s390_single_part (operands[2], SImode, HImode, 0) < 0"
7708 "@
7709 nilf\t%0,%o2
7710 nr\t%0,%2
7711 nrk\t%0,%1,%2
7712 n\t%0,%2
7713 ny\t%0,%2
7714 risbg\t%0,%1,%t2,128+%f2,0"
7715 [(set_attr "op_type" "RIL,RR,RRF,RX,RXY,RIE")
7716 (set_attr "cpu_facility" "*,*,z196,*,longdisp,z10")
7717 (set_attr "z10prop" "z10_super_E1,z10_super_E1,*,
7718 z10_super_E1,z10_super_E1,z10_super_E1")])
7719
7720 (define_insn "*andsi3_zarch"
7721 [(set (match_operand:SI 0 "nonimmediate_operand"
7722 "=d,d, d, d, d,d,d,d,d, d, AQ,Q")
7723 (and:SI (match_operand:SI 1 "nonimmediate_operand"
7724 "%d,o, 0, 0, 0,0,d,0,0, d, 0,0")
7725 (match_operand:SI 2 "general_operand"
7726 " M,M,N0HSF,N1HSF,Os,d,d,R,T,NxxSw,NxQSF,Q")))
7727 (clobber (reg:CC CC_REGNUM))]
7728 "TARGET_ZARCH && s390_logical_operator_ok_p (operands)"
7729 "@
7730 #
7731 #
7732 nilh\t%0,%j2
7733 nill\t%0,%j2
7734 nilf\t%0,%o2
7735 nr\t%0,%2
7736 nrk\t%0,%1,%2
7737 n\t%0,%2
7738 ny\t%0,%2
7739 risbg\t%0,%1,%t2,128+%f2,0
7740 #
7741 #"
7742 [(set_attr "op_type" "RRE,RXE,RI,RI,RIL,RR,RRF,RX,RXY,RIE,SI,SS")
7743 (set_attr "cpu_facility" "*,*,*,*,*,*,z196,*,longdisp,z10,*,*")
7744 (set_attr "z10prop" "*,
7745 *,
7746 z10_super_E1,
7747 z10_super_E1,
7748 z10_super_E1,
7749 z10_super_E1,
7750 *,
7751 z10_super_E1,
7752 z10_super_E1,
7753 z10_super_E1,
7754 *,
7755 *")])
7756
7757 (define_insn "*andsi3_esa"
7758 [(set (match_operand:SI 0 "nonimmediate_operand" "=d,d, AQ,Q")
7759 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0, 0,0")
7760 (match_operand:SI 2 "general_operand" " d,R,NxQSF,Q")))
7761 (clobber (reg:CC CC_REGNUM))]
7762 "!TARGET_ZARCH && s390_logical_operator_ok_p (operands)"
7763 "@
7764 nr\t%0,%2
7765 n\t%0,%2
7766 #
7767 #"
7768 [(set_attr "op_type" "RR,RX,SI,SS")
7769 (set_attr "z10prop" "z10_super_E1,z10_super_E1,*,*")])
7770
7771
7772 (define_split
7773 [(set (match_operand:SI 0 "s_operand" "")
7774 (and:SI (match_dup 0) (match_operand:SI 1 "immediate_operand" "")))
7775 (clobber (reg:CC CC_REGNUM))]
7776 "reload_completed"
7777 [(parallel
7778 [(set (match_dup 0) (and:QI (match_dup 0) (match_dup 1)))
7779 (clobber (reg:CC CC_REGNUM))])]
7780 "s390_narrow_logical_operator (AND, &operands[0], &operands[1]);")
7781
7782 ;
7783 ; andhi3 instruction pattern(s).
7784 ;
7785
7786 (define_insn "*andhi3_zarch"
7787 [(set (match_operand:HI 0 "nonimmediate_operand" "=d,d,d, AQ,Q")
7788 (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,d,0, 0,0")
7789 (match_operand:HI 2 "general_operand" " d,d,n,NxQHF,Q")))
7790 (clobber (reg:CC CC_REGNUM))]
7791 "TARGET_ZARCH && s390_logical_operator_ok_p (operands)"
7792 "@
7793 nr\t%0,%2
7794 nrk\t%0,%1,%2
7795 nill\t%0,%x2
7796 #
7797 #"
7798 [(set_attr "op_type" "RR,RRF,RI,SI,SS")
7799 (set_attr "cpu_facility" "*,z196,*,*,*")
7800 (set_attr "z10prop" "z10_super_E1,*,z10_super_E1,*,*")
7801 ])
7802
7803 (define_insn "*andhi3_esa"
7804 [(set (match_operand:HI 0 "nonimmediate_operand" "=d,AQ,Q")
7805 (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,0")
7806 (match_operand:HI 2 "general_operand" "d,NxQHF,Q")))
7807 (clobber (reg:CC CC_REGNUM))]
7808 "!TARGET_ZARCH && s390_logical_operator_ok_p (operands)"
7809 "@
7810 nr\t%0,%2
7811 #
7812 #"
7813 [(set_attr "op_type" "RR,SI,SS")
7814 (set_attr "z10prop" "z10_super_E1,*,*")
7815 ])
7816
7817 (define_split
7818 [(set (match_operand:HI 0 "s_operand" "")
7819 (and:HI (match_dup 0) (match_operand:HI 1 "immediate_operand" "")))
7820 (clobber (reg:CC CC_REGNUM))]
7821 "reload_completed"
7822 [(parallel
7823 [(set (match_dup 0) (and:QI (match_dup 0) (match_dup 1)))
7824 (clobber (reg:CC CC_REGNUM))])]
7825 "s390_narrow_logical_operator (AND, &operands[0], &operands[1]);")
7826
7827 ;
7828 ; andqi3 instruction pattern(s).
7829 ;
7830
7831 (define_insn "*andqi3_zarch"
7832 [(set (match_operand:QI 0 "nonimmediate_operand" "=d,d,d,Q,S,Q")
7833 (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,d,0,0,0,0")
7834 (match_operand:QI 2 "general_operand" " d,d,n,n,n,Q")))
7835 (clobber (reg:CC CC_REGNUM))]
7836 "TARGET_ZARCH && s390_logical_operator_ok_p (operands)"
7837 "@
7838 nr\t%0,%2
7839 nrk\t%0,%1,%2
7840 nill\t%0,%b2
7841 ni\t%S0,%b2
7842 niy\t%S0,%b2
7843 #"
7844 [(set_attr "op_type" "RR,RRF,RI,SI,SIY,SS")
7845 (set_attr "cpu_facility" "*,z196,*,*,longdisp,*")
7846 (set_attr "z10prop" "z10_super_E1,*,z10_super_E1,z10_super,z10_super,*")])
7847
7848 (define_insn "*andqi3_esa"
7849 [(set (match_operand:QI 0 "nonimmediate_operand" "=d,Q,Q")
7850 (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
7851 (match_operand:QI 2 "general_operand" "d,n,Q")))
7852 (clobber (reg:CC CC_REGNUM))]
7853 "!TARGET_ZARCH && s390_logical_operator_ok_p (operands)"
7854 "@
7855 nr\t%0,%2
7856 ni\t%S0,%b2
7857 #"
7858 [(set_attr "op_type" "RR,SI,SS")
7859 (set_attr "z10prop" "z10_super_E1,z10_super,*")])
7860
7861 ;
7862 ; And with complement
7863 ;
7864 ; c = ~b & a = (b & a) ^ a
7865
7866 (define_insn_and_split "*andc_split_<mode>"
7867 [(set (match_operand:GPR 0 "nonimmediate_operand" "")
7868 (and:GPR (not:GPR (match_operand:GPR 1 "nonimmediate_operand" ""))
7869 (match_operand:GPR 2 "general_operand" "")))
7870 (clobber (reg:CC CC_REGNUM))]
7871 "!TARGET_Z15
7872 && ! reload_completed
7873 && (GET_CODE (operands[0]) != MEM
7874 /* Ensure that s390_logical_operator_ok_p will succeed even
7875 on the split xor if (b & a) is stored into a pseudo. */
7876 || rtx_equal_p (operands[0], operands[2]))"
7877 "#"
7878 "&& 1"
7879 [
7880 (parallel
7881 [(set (match_dup 3) (and:GPR (match_dup 1) (match_dup 2)))
7882 (clobber (reg:CC CC_REGNUM))])
7883 (parallel
7884 [(set (match_dup 0) (xor:GPR (match_dup 3) (match_dup 2)))
7885 (clobber (reg:CC CC_REGNUM))])]
7886 {
7887 if (reg_overlap_mentioned_p (operands[0], operands[2]))
7888 operands[3] = gen_reg_rtx (<MODE>mode);
7889 else
7890 operands[3] = operands[0];
7891 })
7892
7893 ;
7894 ; Block and (NC) patterns.
7895 ;
7896
7897 (define_insn "*nc"
7898 [(set (match_operand:BLK 0 "memory_operand" "=Q")
7899 (and:BLK (match_dup 0)
7900 (match_operand:BLK 1 "memory_operand" "Q")))
7901 (use (match_operand 2 "const_int_operand" "n"))
7902 (clobber (reg:CC CC_REGNUM))]
7903 "INTVAL (operands[2]) >= 1 && INTVAL (operands[2]) <= 256"
7904 "nc\t%O0(%2,%R0),%S1"
7905 [(set_attr "op_type" "SS")
7906 (set_attr "z196prop" "z196_cracked")])
7907
7908 (define_split
7909 [(set (match_operand 0 "memory_operand" "")
7910 (and (match_dup 0)
7911 (match_operand 1 "memory_operand" "")))
7912 (clobber (reg:CC CC_REGNUM))]
7913 "reload_completed
7914 && GET_MODE (operands[0]) == GET_MODE (operands[1])
7915 && GET_MODE_SIZE (GET_MODE (operands[0])) > 0"
7916 [(parallel
7917 [(set (match_dup 0) (and:BLK (match_dup 0) (match_dup 1)))
7918 (use (match_dup 2))
7919 (clobber (reg:CC CC_REGNUM))])]
7920 {
7921 operands[2] = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[0])));
7922 operands[0] = adjust_address (operands[0], BLKmode, 0);
7923 operands[1] = adjust_address (operands[1], BLKmode, 0);
7924 })
7925
7926 (define_peephole2
7927 [(parallel
7928 [(set (match_operand:BLK 0 "memory_operand" "")
7929 (and:BLK (match_dup 0)
7930 (match_operand:BLK 1 "memory_operand" "")))
7931 (use (match_operand 2 "const_int_operand" ""))
7932 (clobber (reg:CC CC_REGNUM))])
7933 (parallel
7934 [(set (match_operand:BLK 3 "memory_operand" "")
7935 (and:BLK (match_dup 3)
7936 (match_operand:BLK 4 "memory_operand" "")))
7937 (use (match_operand 5 "const_int_operand" ""))
7938 (clobber (reg:CC CC_REGNUM))])]
7939 "s390_offset_p (operands[0], operands[3], operands[2])
7940 && s390_offset_p (operands[1], operands[4], operands[2])
7941 && !s390_overlap_p (operands[0], operands[1],
7942 INTVAL (operands[2]) + INTVAL (operands[5]))
7943 && INTVAL (operands[2]) + INTVAL (operands[5]) <= 256"
7944 [(parallel
7945 [(set (match_dup 6) (and:BLK (match_dup 6) (match_dup 7)))
7946 (use (match_dup 8))
7947 (clobber (reg:CC CC_REGNUM))])]
7948 "operands[6] = gen_rtx_MEM (BLKmode, XEXP (operands[0], 0));
7949 operands[7] = gen_rtx_MEM (BLKmode, XEXP (operands[1], 0));
7950 operands[8] = GEN_INT (INTVAL (operands[2]) + INTVAL (operands[5]));")
7951
7952
7953 ;;
7954 ;;- Bit set (inclusive or) instructions.
7955 ;;
7956
7957 (define_expand "ior<mode>3"
7958 [(set (match_operand:INT 0 "nonimmediate_operand" "")
7959 (ior:INT (match_operand:INT 1 "nonimmediate_operand" "")
7960 (match_operand:INT 2 "general_operand" "")))
7961 (clobber (reg:CC CC_REGNUM))]
7962 ""
7963 "s390_expand_logical_operator (IOR, <MODE>mode, operands); DONE;")
7964
7965 ;
7966 ; iordi3 instruction pattern(s).
7967 ;
7968
7969 (define_insn "*iordi3_cc"
7970 [(set (reg CC_REGNUM)
7971 (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,d,0")
7972 (match_operand:DI 2 "general_operand" " d,d,T"))
7973 (const_int 0)))
7974 (set (match_operand:DI 0 "register_operand" "=d,d,d")
7975 (ior:DI (match_dup 1) (match_dup 2)))]
7976 "s390_match_ccmode(insn, CCTmode) && TARGET_ZARCH"
7977 "@
7978 ogr\t%0,%2
7979 ogrk\t%0,%1,%2
7980 og\t%0,%2"
7981 [(set_attr "op_type" "RRE,RRF,RXY")
7982 (set_attr "cpu_facility" "*,z196,*")
7983 (set_attr "z10prop" "z10_super_E1,*,z10_super_E1")])
7984
7985 (define_insn "*iordi3_cconly"
7986 [(set (reg CC_REGNUM)
7987 (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,d,0")
7988 (match_operand:DI 2 "general_operand" " d,d,T"))
7989 (const_int 0)))
7990 (clobber (match_scratch:DI 0 "=d,d,d"))]
7991 "s390_match_ccmode(insn, CCTmode) && TARGET_ZARCH"
7992 "@
7993 ogr\t%0,%2
7994 ogrk\t%0,%1,%2
7995 og\t%0,%2"
7996 [(set_attr "op_type" "RRE,RRF,RXY")
7997 (set_attr "cpu_facility" "*,z196,*")
7998 (set_attr "z10prop" "z10_super_E1,*,z10_super_E1")])
7999
8000 (define_insn "*iordi3"
8001 [(set (match_operand:DI 0 "nonimmediate_operand"
8002 "=d, d, d, d, d, d,d,d,d, AQ,Q")
8003 (ior:DI (match_operand:DI 1 "nonimmediate_operand"
8004 " %0, 0, 0, 0, 0, 0,0,d,0, 0,0")
8005 (match_operand:DI 2 "general_operand"
8006 "N0HD0,N1HD0,N2HD0,N3HD0,N0SD0,N1SD0,d,d,T,NxQD0,Q")))
8007 (clobber (reg:CC CC_REGNUM))]
8008 "TARGET_ZARCH && s390_logical_operator_ok_p (operands)"
8009 "@
8010 oihh\t%0,%i2
8011 oihl\t%0,%i2
8012 oilh\t%0,%i2
8013 oill\t%0,%i2
8014 oihf\t%0,%k2
8015 oilf\t%0,%k2
8016 ogr\t%0,%2
8017 ogrk\t%0,%1,%2
8018 og\t%0,%2
8019 #
8020 #"
8021 [(set_attr "op_type" "RI,RI,RI,RI,RIL,RIL,RRE,RRF,RXY,SI,SS")
8022 (set_attr "cpu_facility" "*,*,*,*,extimm,extimm,*,z196,*,*,*")
8023 (set_attr "z10prop" "z10_super_E1,
8024 z10_super_E1,
8025 z10_super_E1,
8026 z10_super_E1,
8027 z10_super_E1,
8028 z10_super_E1,
8029 z10_super_E1,
8030 *,
8031 z10_super_E1,
8032 *,
8033 *")])
8034
8035 (define_split
8036 [(set (match_operand:DI 0 "s_operand" "")
8037 (ior:DI (match_dup 0) (match_operand:DI 1 "immediate_operand" "")))
8038 (clobber (reg:CC CC_REGNUM))]
8039 "reload_completed"
8040 [(parallel
8041 [(set (match_dup 0) (ior:QI (match_dup 0) (match_dup 1)))
8042 (clobber (reg:CC CC_REGNUM))])]
8043 "s390_narrow_logical_operator (IOR, &operands[0], &operands[1]);")
8044
8045 ;
8046 ; iorsi3 instruction pattern(s).
8047 ;
8048
8049 (define_insn "*iorsi3_cc"
8050 [(set (reg CC_REGNUM)
8051 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,d,0,0")
8052 (match_operand:SI 2 "general_operand" "Os,d,d,R,T"))
8053 (const_int 0)))
8054 (set (match_operand:SI 0 "register_operand" "=d,d,d,d,d")
8055 (ior:SI (match_dup 1) (match_dup 2)))]
8056 "s390_match_ccmode(insn, CCTmode)"
8057 "@
8058 oilf\t%0,%o2
8059 or\t%0,%2
8060 ork\t%0,%1,%2
8061 o\t%0,%2
8062 oy\t%0,%2"
8063 [(set_attr "op_type" "RIL,RR,RRF,RX,RXY")
8064 (set_attr "cpu_facility" "*,*,z196,*,longdisp")
8065 (set_attr "z10prop" "z10_super_E1,z10_super_E1,*,z10_super_E1,z10_super_E1")])
8066
8067 (define_insn "*iorsi3_cconly"
8068 [(set (reg CC_REGNUM)
8069 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,d,0,0")
8070 (match_operand:SI 2 "general_operand" "Os,d,d,R,T"))
8071 (const_int 0)))
8072 (clobber (match_scratch:SI 0 "=d,d,d,d,d"))]
8073 "s390_match_ccmode(insn, CCTmode)"
8074 "@
8075 oilf\t%0,%o2
8076 or\t%0,%2
8077 ork\t%0,%1,%2
8078 o\t%0,%2
8079 oy\t%0,%2"
8080 [(set_attr "op_type" "RIL,RR,RRF,RX,RXY")
8081 (set_attr "cpu_facility" "*,*,z196,*,longdisp")
8082 (set_attr "z10prop" "z10_super_E1,z10_super_E1,*,z10_super_E1,z10_super_E1")])
8083
8084 (define_insn "*iorsi3_zarch"
8085 [(set (match_operand:SI 0 "nonimmediate_operand" "=d, d, d,d,d,d,d, AQ,Q")
8086 (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0, 0, 0,0,d,0,0, 0,0")
8087 (match_operand:SI 2 "general_operand" "N0HS0,N1HS0,Os,d,d,R,T,NxQS0,Q")))
8088 (clobber (reg:CC CC_REGNUM))]
8089 "TARGET_ZARCH && s390_logical_operator_ok_p (operands)"
8090 "@
8091 oilh\t%0,%i2
8092 oill\t%0,%i2
8093 oilf\t%0,%o2
8094 or\t%0,%2
8095 ork\t%0,%1,%2
8096 o\t%0,%2
8097 oy\t%0,%2
8098 #
8099 #"
8100 [(set_attr "op_type" "RI,RI,RIL,RR,RRF,RX,RXY,SI,SS")
8101 (set_attr "cpu_facility" "*,*,*,*,z196,*,longdisp,*,*")
8102 (set_attr "z10prop" "z10_super_E1,
8103 z10_super_E1,
8104 z10_super_E1,
8105 z10_super_E1,
8106 *,
8107 z10_super_E1,
8108 z10_super_E1,
8109 *,
8110 *")])
8111
8112 (define_insn "*iorsi3_esa"
8113 [(set (match_operand:SI 0 "nonimmediate_operand" "=d,d,AQ,Q")
8114 (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,0,0")
8115 (match_operand:SI 2 "general_operand" "d,R,NxQS0,Q")))
8116 (clobber (reg:CC CC_REGNUM))]
8117 "!TARGET_ZARCH && s390_logical_operator_ok_p (operands)"
8118 "@
8119 or\t%0,%2
8120 o\t%0,%2
8121 #
8122 #"
8123 [(set_attr "op_type" "RR,RX,SI,SS")
8124 (set_attr "z10prop" "z10_super_E1,z10_super_E1,*,*")])
8125
8126 (define_split
8127 [(set (match_operand:SI 0 "s_operand" "")
8128 (ior:SI (match_dup 0) (match_operand:SI 1 "immediate_operand" "")))
8129 (clobber (reg:CC CC_REGNUM))]
8130 "reload_completed"
8131 [(parallel
8132 [(set (match_dup 0) (ior:QI (match_dup 0) (match_dup 1)))
8133 (clobber (reg:CC CC_REGNUM))])]
8134 "s390_narrow_logical_operator (IOR, &operands[0], &operands[1]);")
8135
8136 ;
8137 ; iorhi3 instruction pattern(s).
8138 ;
8139
8140 (define_insn "*iorhi3_zarch"
8141 [(set (match_operand:HI 0 "nonimmediate_operand" "=d,d,d, AQ,Q")
8142 (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,d,0, 0,0")
8143 (match_operand:HI 2 "general_operand" " d,d,n,NxQH0,Q")))
8144 (clobber (reg:CC CC_REGNUM))]
8145 "TARGET_ZARCH && s390_logical_operator_ok_p (operands)"
8146 "@
8147 or\t%0,%2
8148 ork\t%0,%1,%2
8149 oill\t%0,%x2
8150 #
8151 #"
8152 [(set_attr "op_type" "RR,RRF,RI,SI,SS")
8153 (set_attr "cpu_facility" "*,z196,*,*,*")
8154 (set_attr "z10prop" "z10_super_E1,*,z10_super_E1,*,*")])
8155
8156 (define_insn "*iorhi3_esa"
8157 [(set (match_operand:HI 0 "nonimmediate_operand" "=d,AQ,Q")
8158 (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,0")
8159 (match_operand:HI 2 "general_operand" "d,NxQH0,Q")))
8160 (clobber (reg:CC CC_REGNUM))]
8161 "!TARGET_ZARCH && s390_logical_operator_ok_p (operands)"
8162 "@
8163 or\t%0,%2
8164 #
8165 #"
8166 [(set_attr "op_type" "RR,SI,SS")
8167 (set_attr "z10prop" "z10_super_E1,*,*")])
8168
8169 (define_split
8170 [(set (match_operand:HI 0 "s_operand" "")
8171 (ior:HI (match_dup 0) (match_operand:HI 1 "immediate_operand" "")))
8172 (clobber (reg:CC CC_REGNUM))]
8173 "reload_completed"
8174 [(parallel
8175 [(set (match_dup 0) (ior:QI (match_dup 0) (match_dup 1)))
8176 (clobber (reg:CC CC_REGNUM))])]
8177 "s390_narrow_logical_operator (IOR, &operands[0], &operands[1]);")
8178
8179 ;
8180 ; iorqi3 instruction pattern(s).
8181 ;
8182
8183 (define_insn "*iorqi3_zarch"
8184 [(set (match_operand:QI 0 "nonimmediate_operand" "=d,d,d,Q,S,Q")
8185 (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,d,0,0,0,0")
8186 (match_operand:QI 2 "general_operand" " d,d,n,n,n,Q")))
8187 (clobber (reg:CC CC_REGNUM))]
8188 "TARGET_ZARCH && s390_logical_operator_ok_p (operands)"
8189 "@
8190 or\t%0,%2
8191 ork\t%0,%1,%2
8192 oill\t%0,%b2
8193 oi\t%S0,%b2
8194 oiy\t%S0,%b2
8195 #"
8196 [(set_attr "op_type" "RR,RRF,RI,SI,SIY,SS")
8197 (set_attr "cpu_facility" "*,z196,*,*,longdisp,*")
8198 (set_attr "z10prop" "z10_super_E1,*,z10_super_E1,
8199 z10_super,z10_super,*")])
8200
8201 (define_insn "*iorqi3_esa"
8202 [(set (match_operand:QI 0 "nonimmediate_operand" "=d,Q,Q")
8203 (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8204 (match_operand:QI 2 "general_operand" "d,n,Q")))
8205 (clobber (reg:CC CC_REGNUM))]
8206 "!TARGET_ZARCH && s390_logical_operator_ok_p (operands)"
8207 "@
8208 or\t%0,%2
8209 oi\t%S0,%b2
8210 #"
8211 [(set_attr "op_type" "RR,SI,SS")
8212 (set_attr "z10prop" "z10_super_E1,z10_super,*")])
8213
8214 ;
8215 ; And/Or with complement
8216 ;
8217
8218 ; ncrk, ncgrk, ocrk, ocgrk
8219 (define_insn "*<ANDOR:bitops_name>c<GPR:mode>_cc"
8220 [(set (reg CC_REGNUM)
8221 (compare
8222 (ANDOR:GPR (not:GPR (match_operand:GPR 1 "register_operand" "d"))
8223 (match_operand:GPR 2 "register_operand" "d"))
8224 (const_int 0)))
8225 (set (match_operand:GPR 0 "register_operand" "=d")
8226 (ANDOR:GPR (not:GPR (match_dup 1))
8227 (match_dup 2)))]
8228 "TARGET_Z15 && s390_match_ccmode(insn, CCTmode)"
8229 "<ANDOR:noxa>c<GPR:g>rk\t%0,%2,%1"
8230 [(set_attr "op_type" "RRF")])
8231
8232 ; ncrk, ncgrk, ocrk, ocgrk
8233 (define_insn "*<ANDOR:bitops_name>c<GPR:mode>_cconly"
8234 [(set (reg CC_REGNUM)
8235 (compare
8236 (ANDOR:GPR (not:GPR (match_operand:GPR 1 "register_operand" "d"))
8237 (match_operand:GPR 2 "register_operand" "d"))
8238 (const_int 0)))
8239 (clobber (match_scratch:GPR 0 "=d"))]
8240 "TARGET_Z15 && s390_match_ccmode(insn, CCTmode)"
8241 "<ANDOR:noxa>c<GPR:g>rk\t%0,%2,%1"
8242 [(set_attr "op_type" "RRF")])
8243
8244 ; ncrk, ncgrk, ocrk, ocgrk
8245 (define_insn "*<ANDOR:bitops_name>c<GPR:mode>"
8246 [(set (match_operand:GPR 0 "register_operand" "=d")
8247 (ANDOR:GPR (not:GPR (match_operand:GPR 1 "register_operand" "d"))
8248 (match_operand:GPR 2 "register_operand" "d")))
8249 (clobber (reg:CC CC_REGNUM))]
8250 "TARGET_Z15"
8251 "<ANDOR:noxa>c<GPR:g>rk\t%0,%2,%1"
8252 [(set_attr "op_type" "RRF")])
8253
8254 ;
8255 ;- Nand/Nor instructions.
8256 ;
8257
8258 ; nnrk, nngrk, nork, nogrk
8259 (define_insn "*n<ANDOR:inv_bitops_name><GPR:mode>_cc"
8260 [(set (reg CC_REGNUM)
8261 (compare
8262 (ANDOR:GPR (not:GPR (match_operand:GPR 1 "register_operand" "d"))
8263 (not:GPR (match_operand:GPR 2 "register_operand" "d")))
8264 (const_int 0)))
8265 (set (match_operand:GPR 0 "register_operand" "=d")
8266 (ANDOR:GPR (not:GPR (match_dup 1))
8267 (not:GPR (match_dup 2))))]
8268 "TARGET_Z15 && s390_match_ccmode(insn, CCTmode)"
8269 "n<ANDOR:inv_no><GPR:g>rk\t%0,%1,%2"
8270 [(set_attr "op_type" "RRF")])
8271
8272 ; nnrk, nngrk, nork, nogrk
8273 (define_insn "*n<ANDOR:inv_bitops_name><mode>_cconly"
8274 [(set (reg CC_REGNUM)
8275 (compare
8276 (ANDOR:GPR (not:GPR (match_operand:GPR 1 "register_operand" "d"))
8277 (not:GPR (match_operand:GPR 2 "register_operand" "d")))
8278 (const_int 0)))
8279 (clobber (match_scratch:GPR 0 "=d"))]
8280 "TARGET_Z15 && s390_match_ccmode(insn, CCTmode)"
8281 "n<ANDOR:inv_no><GPR:g>rk\t%0,%1,%2"
8282 [(set_attr "op_type" "RRF")])
8283
8284 ; nnrk, nngrk, nork, nogrk
8285 (define_insn "*n<ANDOR:inv_bitops_name><mode>"
8286 [(set (match_operand:GPR 0 "register_operand" "=d")
8287 (ANDOR:GPR (not:GPR (match_operand:GPR 1 "register_operand" "d"))
8288 (not:GPR (match_operand:GPR 2 "register_operand" "d"))))
8289 (clobber (reg:CC CC_REGNUM))]
8290 "TARGET_Z15"
8291 "n<ANDOR:inv_no><GPR:g>rk\t%0,%1,%2"
8292 [(set_attr "op_type" "RRF")])
8293
8294
8295 ;
8296 ; Block inclusive or (OC) patterns.
8297 ;
8298
8299 (define_insn "*oc"
8300 [(set (match_operand:BLK 0 "memory_operand" "=Q")
8301 (ior:BLK (match_dup 0)
8302 (match_operand:BLK 1 "memory_operand" "Q")))
8303 (use (match_operand 2 "const_int_operand" "n"))
8304 (clobber (reg:CC CC_REGNUM))]
8305 "INTVAL (operands[2]) >= 1 && INTVAL (operands[2]) <= 256"
8306 "oc\t%O0(%2,%R0),%S1"
8307 [(set_attr "op_type" "SS")
8308 (set_attr "z196prop" "z196_cracked")])
8309
8310 (define_split
8311 [(set (match_operand 0 "memory_operand" "")
8312 (ior (match_dup 0)
8313 (match_operand 1 "memory_operand" "")))
8314 (clobber (reg:CC CC_REGNUM))]
8315 "reload_completed
8316 && GET_MODE (operands[0]) == GET_MODE (operands[1])
8317 && GET_MODE_SIZE (GET_MODE (operands[0])) > 0"
8318 [(parallel
8319 [(set (match_dup 0) (ior:BLK (match_dup 0) (match_dup 1)))
8320 (use (match_dup 2))
8321 (clobber (reg:CC CC_REGNUM))])]
8322 {
8323 operands[2] = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[0])));
8324 operands[0] = adjust_address (operands[0], BLKmode, 0);
8325 operands[1] = adjust_address (operands[1], BLKmode, 0);
8326 })
8327
8328 (define_peephole2
8329 [(parallel
8330 [(set (match_operand:BLK 0 "memory_operand" "")
8331 (ior:BLK (match_dup 0)
8332 (match_operand:BLK 1 "memory_operand" "")))
8333 (use (match_operand 2 "const_int_operand" ""))
8334 (clobber (reg:CC CC_REGNUM))])
8335 (parallel
8336 [(set (match_operand:BLK 3 "memory_operand" "")
8337 (ior:BLK (match_dup 3)
8338 (match_operand:BLK 4 "memory_operand" "")))
8339 (use (match_operand 5 "const_int_operand" ""))
8340 (clobber (reg:CC CC_REGNUM))])]
8341 "s390_offset_p (operands[0], operands[3], operands[2])
8342 && s390_offset_p (operands[1], operands[4], operands[2])
8343 && !s390_overlap_p (operands[0], operands[1],
8344 INTVAL (operands[2]) + INTVAL (operands[5]))
8345 && INTVAL (operands[2]) + INTVAL (operands[5]) <= 256"
8346 [(parallel
8347 [(set (match_dup 6) (ior:BLK (match_dup 6) (match_dup 7)))
8348 (use (match_dup 8))
8349 (clobber (reg:CC CC_REGNUM))])]
8350 "operands[6] = gen_rtx_MEM (BLKmode, XEXP (operands[0], 0));
8351 operands[7] = gen_rtx_MEM (BLKmode, XEXP (operands[1], 0));
8352 operands[8] = GEN_INT (INTVAL (operands[2]) + INTVAL (operands[5]));")
8353
8354
8355 ;;
8356 ;;- Xor instructions.
8357 ;;
8358
8359 (define_expand "xor<mode>3"
8360 [(set (match_operand:INT 0 "nonimmediate_operand" "")
8361 (xor:INT (match_operand:INT 1 "nonimmediate_operand" "")
8362 (match_operand:INT 2 "general_operand" "")))
8363 (clobber (reg:CC CC_REGNUM))]
8364 ""
8365 "s390_expand_logical_operator (XOR, <MODE>mode, operands); DONE;")
8366
8367 ; Combine replaces (xor (x) (const_int -1)) with (not (x)) when doing
8368 ; simplifications. So its better to have something matching.
8369 (define_split
8370 [(set (match_operand:INT 0 "nonimmediate_operand" "")
8371 (not:INT (match_operand:INT 1 "nonimmediate_operand" "")))]
8372 ""
8373 [(parallel
8374 [(set (match_dup 0) (xor:INT (match_dup 1) (match_dup 2)))
8375 (clobber (reg:CC CC_REGNUM))])]
8376 {
8377 operands[2] = constm1_rtx;
8378 if (!s390_logical_operator_ok_p (operands))
8379 FAIL;
8380 })
8381
8382 ;
8383 ; xordi3 instruction pattern(s).
8384 ;
8385
8386 (define_insn "*xordi3_cc"
8387 [(set (reg CC_REGNUM)
8388 (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,d,0")
8389 (match_operand:DI 2 "general_operand" " d,d,T"))
8390 (const_int 0)))
8391 (set (match_operand:DI 0 "register_operand" "=d,d,d")
8392 (xor:DI (match_dup 1) (match_dup 2)))]
8393 "s390_match_ccmode(insn, CCTmode) && TARGET_ZARCH"
8394 "@
8395 xgr\t%0,%2
8396 xgrk\t%0,%1,%2
8397 xg\t%0,%2"
8398 [(set_attr "op_type" "RRE,RRF,RXY")
8399 (set_attr "cpu_facility" "*,z196,*")
8400 (set_attr "z10prop" "z10_super_E1,*,z10_super_E1")])
8401
8402 (define_insn "*xordi3_cconly"
8403 [(set (reg CC_REGNUM)
8404 (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,d,0")
8405 (match_operand:DI 2 "general_operand" " d,d,T"))
8406 (const_int 0)))
8407 (clobber (match_scratch:DI 0 "=d,d,d"))]
8408 "s390_match_ccmode(insn, CCTmode) && TARGET_ZARCH"
8409 "@
8410 xgr\t%0,%2
8411 xgrk\t%0,%1,%2
8412 xg\t%0,%2"
8413 [(set_attr "op_type" "RRE,RRF,RXY")
8414 (set_attr "cpu_facility" "*,z196,*")
8415 (set_attr "z10prop" "z10_super_E1,*,z10_super_E1")])
8416
8417 (define_insn "*xordi3"
8418 [(set (match_operand:DI 0 "nonimmediate_operand" "=d, d,d,d,d, AQ,Q")
8419 (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0, 0,0,d,0, 0,0")
8420 (match_operand:DI 2 "general_operand" "N0SD0,N1SD0,d,d,T,NxQD0,Q")))
8421 (clobber (reg:CC CC_REGNUM))]
8422 "TARGET_ZARCH && s390_logical_operator_ok_p (operands)"
8423 "@
8424 xihf\t%0,%k2
8425 xilf\t%0,%k2
8426 xgr\t%0,%2
8427 xgrk\t%0,%1,%2
8428 xg\t%0,%2
8429 #
8430 #"
8431 [(set_attr "op_type" "RIL,RIL,RRE,RRF,RXY,SI,SS")
8432 (set_attr "cpu_facility" "extimm,extimm,*,z196,*,*,*")
8433 (set_attr "z10prop" "z10_super_E1,z10_super_E1,z10_super_E1,
8434 *,z10_super_E1,*,*")])
8435
8436 (define_split
8437 [(set (match_operand:DI 0 "s_operand" "")
8438 (xor:DI (match_dup 0) (match_operand:DI 1 "immediate_operand" "")))
8439 (clobber (reg:CC CC_REGNUM))]
8440 "reload_completed"
8441 [(parallel
8442 [(set (match_dup 0) (xor:QI (match_dup 0) (match_dup 1)))
8443 (clobber (reg:CC CC_REGNUM))])]
8444 "s390_narrow_logical_operator (XOR, &operands[0], &operands[1]);")
8445
8446 ;
8447 ; xorsi3 instruction pattern(s).
8448 ;
8449
8450 (define_insn "*xorsi3_cc"
8451 [(set (reg CC_REGNUM)
8452 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,d,0,0")
8453 (match_operand:SI 2 "general_operand" "Os,d,d,R,T"))
8454 (const_int 0)))
8455 (set (match_operand:SI 0 "register_operand" "=d,d,d,d,d")
8456 (xor:SI (match_dup 1) (match_dup 2)))]
8457 "s390_match_ccmode(insn, CCTmode)"
8458 "@
8459 xilf\t%0,%o2
8460 xr\t%0,%2
8461 xrk\t%0,%1,%2
8462 x\t%0,%2
8463 xy\t%0,%2"
8464 [(set_attr "op_type" "RIL,RR,RRF,RX,RXY")
8465 (set_attr "cpu_facility" "*,*,z196,*,longdisp")
8466 (set_attr "z10prop" "z10_super_E1,z10_super_E1,*,
8467 z10_super_E1,z10_super_E1")])
8468
8469 (define_insn "*xorsi3_cconly"
8470 [(set (reg CC_REGNUM)
8471 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,d,0,0")
8472 (match_operand:SI 2 "general_operand" "Os,d,d,R,T"))
8473 (const_int 0)))
8474 (clobber (match_scratch:SI 0 "=d,d,d,d,d"))]
8475 "s390_match_ccmode(insn, CCTmode)"
8476 "@
8477 xilf\t%0,%o2
8478 xr\t%0,%2
8479 xrk\t%0,%1,%2
8480 x\t%0,%2
8481 xy\t%0,%2"
8482 [(set_attr "op_type" "RIL,RR,RRF,RX,RXY")
8483 (set_attr "cpu_facility" "*,*,z196,*,longdisp")
8484 (set_attr "z10prop" "z10_super_E1,z10_super_E1,*,
8485 z10_super_E1,z10_super_E1")])
8486
8487 (define_insn "*xorsi3"
8488 [(set (match_operand:SI 0 "nonimmediate_operand" "=d,d,d,d,d, AQ,Q")
8489 (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,d,0,0, 0,0")
8490 (match_operand:SI 2 "general_operand" "Os,d,d,R,T,NxQS0,Q")))
8491 (clobber (reg:CC CC_REGNUM))]
8492 "s390_logical_operator_ok_p (operands)"
8493 "@
8494 xilf\t%0,%o2
8495 xr\t%0,%2
8496 xrk\t%0,%1,%2
8497 x\t%0,%2
8498 xy\t%0,%2
8499 #
8500 #"
8501 [(set_attr "op_type" "RIL,RR,RRF,RX,RXY,SI,SS")
8502 (set_attr "cpu_facility" "*,*,z196,*,longdisp,*,*")
8503 (set_attr "z10prop" "z10_super_E1,z10_super_E1,*,
8504 z10_super_E1,z10_super_E1,*,*")])
8505
8506 (define_split
8507 [(set (match_operand:SI 0 "s_operand" "")
8508 (xor:SI (match_dup 0) (match_operand:SI 1 "immediate_operand" "")))
8509 (clobber (reg:CC CC_REGNUM))]
8510 "reload_completed"
8511 [(parallel
8512 [(set (match_dup 0) (xor:QI (match_dup 0) (match_dup 1)))
8513 (clobber (reg:CC CC_REGNUM))])]
8514 "s390_narrow_logical_operator (XOR, &operands[0], &operands[1]);")
8515
8516 ;
8517 ; xorhi3 instruction pattern(s).
8518 ;
8519
8520 (define_insn "*xorhi3"
8521 [(set (match_operand:HI 0 "nonimmediate_operand" "=d,d,d, AQ,Q")
8522 (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,d, 0,0")
8523 (match_operand:HI 2 "general_operand" "Os,d,d,NxQH0,Q")))
8524 (clobber (reg:CC CC_REGNUM))]
8525 "s390_logical_operator_ok_p (operands)"
8526 "@
8527 xilf\t%0,%x2
8528 xr\t%0,%2
8529 xrk\t%0,%1,%2
8530 #
8531 #"
8532 [(set_attr "op_type" "RIL,RR,RRF,SI,SS")
8533 (set_attr "cpu_facility" "*,*,z196,*,*")
8534 (set_attr "z10prop" "z10_super_E1,z10_super_E1,*,*,*")])
8535
8536 (define_split
8537 [(set (match_operand:HI 0 "s_operand" "")
8538 (xor:HI (match_dup 0) (match_operand:HI 1 "immediate_operand" "")))
8539 (clobber (reg:CC CC_REGNUM))]
8540 "reload_completed"
8541 [(parallel
8542 [(set (match_dup 0) (xor:QI (match_dup 0) (match_dup 1)))
8543 (clobber (reg:CC CC_REGNUM))])]
8544 "s390_narrow_logical_operator (XOR, &operands[0], &operands[1]);")
8545
8546 ;
8547 ; xorqi3 instruction pattern(s).
8548 ;
8549
8550 (define_insn "*xorqi3"
8551 [(set (match_operand:QI 0 "nonimmediate_operand" "=d,d,d,Q,S,Q")
8552 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,d,0,0,0")
8553 (match_operand:QI 2 "general_operand" "Os,d,d,n,n,Q")))
8554 (clobber (reg:CC CC_REGNUM))]
8555 "s390_logical_operator_ok_p (operands)"
8556 "@
8557 xilf\t%0,%b2
8558 xr\t%0,%2
8559 xrk\t%0,%1,%2
8560 xi\t%S0,%b2
8561 xiy\t%S0,%b2
8562 #"
8563 [(set_attr "op_type" "RIL,RR,RRF,SI,SIY,SS")
8564 (set_attr "cpu_facility" "*,*,z196,*,longdisp,*")
8565 (set_attr "z10prop" "z10_super_E1,z10_super_E1,*,z10_super,z10_super,*")])
8566
8567
8568 ;
8569 ; Block exclusive or (XC) patterns.
8570 ;
8571
8572 (define_insn "*xc"
8573 [(set (match_operand:BLK 0 "memory_operand" "=Q")
8574 (xor:BLK (match_dup 0)
8575 (match_operand:BLK 1 "memory_operand" "Q")))
8576 (use (match_operand 2 "const_int_operand" "n"))
8577 (clobber (reg:CC CC_REGNUM))]
8578 "INTVAL (operands[2]) >= 1 && INTVAL (operands[2]) <= 256"
8579 "xc\t%O0(%2,%R0),%S1"
8580 [(set_attr "op_type" "SS")])
8581
8582 (define_split
8583 [(set (match_operand 0 "memory_operand" "")
8584 (xor (match_dup 0)
8585 (match_operand 1 "memory_operand" "")))
8586 (clobber (reg:CC CC_REGNUM))]
8587 "reload_completed
8588 && GET_MODE (operands[0]) == GET_MODE (operands[1])
8589 && GET_MODE_SIZE (GET_MODE (operands[0])) > 0"
8590 [(parallel
8591 [(set (match_dup 0) (xor:BLK (match_dup 0) (match_dup 1)))
8592 (use (match_dup 2))
8593 (clobber (reg:CC CC_REGNUM))])]
8594 {
8595 operands[2] = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[0])));
8596 operands[0] = adjust_address (operands[0], BLKmode, 0);
8597 operands[1] = adjust_address (operands[1], BLKmode, 0);
8598 })
8599
8600 (define_peephole2
8601 [(parallel
8602 [(set (match_operand:BLK 0 "memory_operand" "")
8603 (xor:BLK (match_dup 0)
8604 (match_operand:BLK 1 "memory_operand" "")))
8605 (use (match_operand 2 "const_int_operand" ""))
8606 (clobber (reg:CC CC_REGNUM))])
8607 (parallel
8608 [(set (match_operand:BLK 3 "memory_operand" "")
8609 (xor:BLK (match_dup 3)
8610 (match_operand:BLK 4 "memory_operand" "")))
8611 (use (match_operand 5 "const_int_operand" ""))
8612 (clobber (reg:CC CC_REGNUM))])]
8613 "s390_offset_p (operands[0], operands[3], operands[2])
8614 && s390_offset_p (operands[1], operands[4], operands[2])
8615 && !s390_overlap_p (operands[0], operands[1],
8616 INTVAL (operands[2]) + INTVAL (operands[5]))
8617 && INTVAL (operands[2]) + INTVAL (operands[5]) <= 256"
8618 [(parallel
8619 [(set (match_dup 6) (xor:BLK (match_dup 6) (match_dup 7)))
8620 (use (match_dup 8))
8621 (clobber (reg:CC CC_REGNUM))])]
8622 "operands[6] = gen_rtx_MEM (BLKmode, XEXP (operands[0], 0));
8623 operands[7] = gen_rtx_MEM (BLKmode, XEXP (operands[1], 0));
8624 operands[8] = GEN_INT (INTVAL (operands[2]) + INTVAL (operands[5]));")
8625
8626 ;
8627 ; Block xor (XC) patterns with src == dest.
8628 ;
8629
8630 (define_insn "*xc_zero"
8631 [(set (match_operand:BLK 0 "memory_operand" "=Q")
8632 (const_int 0))
8633 (use (match_operand 1 "const_int_operand" "n"))
8634 (clobber (reg:CC CC_REGNUM))]
8635 "INTVAL (operands[1]) >= 1 && INTVAL (operands[1]) <= 256"
8636 "xc\t%O0(%1,%R0),%S0"
8637 [(set_attr "op_type" "SS")
8638 (set_attr "z196prop" "z196_cracked")])
8639
8640 (define_peephole2
8641 [(parallel
8642 [(set (match_operand:BLK 0 "memory_operand" "")
8643 (const_int 0))
8644 (use (match_operand 1 "const_int_operand" ""))
8645 (clobber (reg:CC CC_REGNUM))])
8646 (parallel
8647 [(set (match_operand:BLK 2 "memory_operand" "")
8648 (const_int 0))
8649 (use (match_operand 3 "const_int_operand" ""))
8650 (clobber (reg:CC CC_REGNUM))])]
8651 "s390_offset_p (operands[0], operands[2], operands[1])
8652 && INTVAL (operands[1]) + INTVAL (operands[3]) <= 256"
8653 [(parallel
8654 [(set (match_dup 4) (const_int 0))
8655 (use (match_dup 5))
8656 (clobber (reg:CC CC_REGNUM))])]
8657 "operands[4] = gen_rtx_MEM (BLKmode, XEXP (operands[0], 0));
8658 operands[5] = GEN_INT (INTVAL (operands[1]) + INTVAL (operands[3]));")
8659
8660 ;
8661 ;- Nxor instructions.
8662 ;
8663
8664 ; nxrk, nxgrk
8665 (define_insn "*nxor<GPR:mode>_cc"
8666 [(set (reg CC_REGNUM)
8667 (compare
8668 (not:GPR (xor:GPR (match_operand:GPR 1 "register_operand" "d")
8669 (match_operand:GPR 2 "register_operand" "d")))
8670 (const_int 0)))
8671 (set (match_operand:GPR 0 "register_operand" "=d")
8672 (xor:GPR (not:GPR (match_dup 1))
8673 (match_dup 2)))]
8674 "TARGET_Z15 && s390_match_ccmode(insn, CCTmode)"
8675 "nx<GPR:g>rk\t%0,%1,%2"
8676 [(set_attr "op_type" "RRF")])
8677
8678 ; nxrk, nxgrk
8679 (define_insn "*nxor<mode>_cconly"
8680 [(set (reg CC_REGNUM)
8681 (compare
8682 (not:GPR (xor:GPR (match_operand:GPR 1 "register_operand" "d")
8683 (match_operand:GPR 2 "register_operand" "d")))
8684 (const_int 0)))
8685 (clobber (match_scratch:GPR 0 "=d"))]
8686 "TARGET_Z15 && s390_match_ccmode(insn, CCTmode)"
8687 "nx<GPR:g>rk\t%0,%1,%2"
8688 [(set_attr "op_type" "RRF")])
8689
8690 ; nxrk, nxgrk
8691 (define_insn "*nxor<mode>"
8692 [(set (match_operand:GPR 0 "register_operand" "=d")
8693 (not:GPR (xor:GPR (match_operand:GPR 1 "register_operand" "d")
8694 (match_operand:GPR 2 "register_operand" "d"))))
8695 (clobber (reg:CC CC_REGNUM))]
8696 "TARGET_Z15"
8697 "nx<GPR:g>rk\t%0,%1,%2"
8698 [(set_attr "op_type" "RRF")])
8699
8700 ;;
8701 ;;- Negate instructions.
8702 ;;
8703
8704 ;
8705 ; neg(di|si)2 instruction pattern(s).
8706 ;
8707
8708 (define_expand "neg<mode>2"
8709 [(parallel
8710 [(set (match_operand:DSI 0 "register_operand" "=d")
8711 (neg:DSI (match_operand:DSI 1 "register_operand" "d")))
8712 (clobber (reg:CC CC_REGNUM))])]
8713 ""
8714 "")
8715
8716 (define_insn "*negdi2_sign_cc"
8717 [(set (reg CC_REGNUM)
8718 (compare (neg:DI (ashiftrt:DI (ashift:DI (subreg:DI
8719 (match_operand:SI 1 "register_operand" "d") 0)
8720 (const_int 32)) (const_int 32)))
8721 (const_int 0)))
8722 (set (match_operand:DI 0 "register_operand" "=d")
8723 (neg:DI (sign_extend:DI (match_dup 1))))]
8724 "TARGET_ZARCH && s390_match_ccmode (insn, CCAmode)"
8725 "lcgfr\t%0,%1"
8726 [(set_attr "op_type" "RRE")
8727 (set_attr "z10prop" "z10_c")])
8728
8729 (define_insn "*negdi2_sign"
8730 [(set (match_operand:DI 0 "register_operand" "=d")
8731 (neg:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "d"))))
8732 (clobber (reg:CC CC_REGNUM))]
8733 "TARGET_ZARCH"
8734 "lcgfr\t%0,%1"
8735 [(set_attr "op_type" "RRE")
8736 (set_attr "z10prop" "z10_c")])
8737
8738 ; lcr, lcgr
8739 (define_insn "*neg<mode>2_cc"
8740 [(set (reg CC_REGNUM)
8741 (compare (neg:GPR (match_operand:GPR 1 "register_operand" "d"))
8742 (const_int 0)))
8743 (set (match_operand:GPR 0 "register_operand" "=d")
8744 (neg:GPR (match_dup 1)))]
8745 "s390_match_ccmode (insn, CCAmode)"
8746 "lc<g>r\t%0,%1"
8747 [(set_attr "op_type" "RR<E>")
8748 (set_attr "z10prop" "z10_super_c_E1")])
8749
8750 ; lcr, lcgr
8751 (define_insn "*neg<mode>2_cconly"
8752 [(set (reg CC_REGNUM)
8753 (compare (neg:GPR (match_operand:GPR 1 "register_operand" "d"))
8754 (const_int 0)))
8755 (clobber (match_scratch:GPR 0 "=d"))]
8756 "s390_match_ccmode (insn, CCAmode)"
8757 "lc<g>r\t%0,%1"
8758 [(set_attr "op_type" "RR<E>")
8759 (set_attr "z10prop" "z10_super_c_E1")])
8760
8761 ; lcr, lcgr
8762 (define_insn "*neg<mode>2"
8763 [(set (match_operand:GPR 0 "register_operand" "=d")
8764 (neg:GPR (match_operand:GPR 1 "register_operand" "d")))
8765 (clobber (reg:CC CC_REGNUM))]
8766 ""
8767 "lc<g>r\t%0,%1"
8768 [(set_attr "op_type" "RR<E>")
8769 (set_attr "z10prop" "z10_super_c_E1")])
8770
8771 (define_insn "*negdi2_31"
8772 [(set (match_operand:DI 0 "register_operand" "=d")
8773 (neg:DI (match_operand:DI 1 "register_operand" "d")))
8774 (clobber (reg:CC CC_REGNUM))]
8775 "!TARGET_ZARCH"
8776 "#")
8777
8778 ; Split a DImode NEG on 31bit into 2 SImode NEGs
8779
8780 ; Doing the twos complement separately on the SImode parts does an
8781 ; unwanted +1 on the high part which needs to be subtracted afterwards
8782 ; ... unless the +1 on the low part created an overflow.
8783
8784 (define_split
8785 [(set (match_operand:DI 0 "register_operand" "")
8786 (neg:DI (match_operand:DI 1 "register_operand" "")))
8787 (clobber (reg:CC CC_REGNUM))]
8788 "!TARGET_ZARCH
8789 && (REGNO (operands[0]) == REGNO (operands[1])
8790 || s390_split_ok_p (operands[0], operands[1], DImode, 0))
8791 && reload_completed"
8792 [(parallel
8793 [(set (match_dup 2) (neg:SI (match_dup 3)))
8794 (clobber (reg:CC CC_REGNUM))])
8795 (parallel
8796 [(set (reg:CCAP CC_REGNUM)
8797 (compare:CCAP (neg:SI (match_dup 5)) (const_int 0)))
8798 (set (match_dup 4) (neg:SI (match_dup 5)))])
8799 (set (pc)
8800 (if_then_else (ne (reg:CCAP CC_REGNUM) (const_int 0))
8801 (pc)
8802 (label_ref (match_dup 6))))
8803 (parallel
8804 [(set (match_dup 2) (plus:SI (match_dup 2) (const_int -1)))
8805 (clobber (reg:CC CC_REGNUM))])
8806 (match_dup 6)]
8807 "operands[2] = operand_subword (operands[0], 0, 0, DImode);
8808 operands[3] = operand_subword (operands[1], 0, 0, DImode);
8809 operands[4] = operand_subword (operands[0], 1, 0, DImode);
8810 operands[5] = operand_subword (operands[1], 1, 0, DImode);
8811 operands[6] = gen_label_rtx ();")
8812
8813 ; Like above but first make a copy of the low part of the src operand
8814 ; since it might overlap with the high part of the destination.
8815
8816 (define_split
8817 [(set (match_operand:DI 0 "register_operand" "")
8818 (neg:DI (match_operand:DI 1 "register_operand" "")))
8819 (clobber (reg:CC CC_REGNUM))]
8820 "!TARGET_ZARCH
8821 && s390_split_ok_p (operands[0], operands[1], DImode, 1)
8822 && reload_completed"
8823 [; Make a backup of op5 first
8824 (set (match_dup 4) (match_dup 5))
8825 ; Setting op2 here might clobber op5
8826 (parallel
8827 [(set (match_dup 2) (neg:SI (match_dup 3)))
8828 (clobber (reg:CC CC_REGNUM))])
8829 (parallel
8830 [(set (reg:CCAP CC_REGNUM)
8831 (compare:CCAP (neg:SI (match_dup 4)) (const_int 0)))
8832 (set (match_dup 4) (neg:SI (match_dup 4)))])
8833 (set (pc)
8834 (if_then_else (ne (reg:CCAP CC_REGNUM) (const_int 0))
8835 (pc)
8836 (label_ref (match_dup 6))))
8837 (parallel
8838 [(set (match_dup 2) (plus:SI (match_dup 2) (const_int -1)))
8839 (clobber (reg:CC CC_REGNUM))])
8840 (match_dup 6)]
8841 "operands[2] = operand_subword (operands[0], 0, 0, DImode);
8842 operands[3] = operand_subword (operands[1], 0, 0, DImode);
8843 operands[4] = operand_subword (operands[0], 1, 0, DImode);
8844 operands[5] = operand_subword (operands[1], 1, 0, DImode);
8845 operands[6] = gen_label_rtx ();")
8846
8847 ;
8848 ; neg(tf|df|sf)2 instruction pattern(s).
8849 ;
8850
8851 (define_expand "neg<mode>2<tf_fpr>"
8852 [(parallel
8853 [(set (match_operand:BFP 0 "register_operand")
8854 (neg:BFP (match_operand:BFP 1 "register_operand")))
8855 (clobber (reg:CC CC_REGNUM))])]
8856 "TARGET_HARD_FLOAT")
8857
8858 ; lcxbr, lcdbr, lcebr
8859 (define_insn "*neg<mode>2_cc"
8860 [(set (reg CC_REGNUM)
8861 (compare (neg:BFP (match_operand:BFP 1 "register_operand" "f"))
8862 (match_operand:BFP 2 "const0_operand" "")))
8863 (set (match_operand:BFP 0 "register_operand" "=f")
8864 (neg:BFP (match_dup 1)))]
8865 "s390_match_ccmode (insn, CCSmode) && TARGET_HARD_FLOAT"
8866 "lc<xde>br\t%0,%1"
8867 [(set_attr "op_type" "RRE")
8868 (set_attr "type" "fsimp<type>")])
8869
8870 ; lcxbr, lcdbr, lcebr
8871 (define_insn "*neg<mode>2_cconly"
8872 [(set (reg CC_REGNUM)
8873 (compare (neg:BFP (match_operand:BFP 1 "register_operand" "f"))
8874 (match_operand:BFP 2 "const0_operand" "")))
8875 (clobber (match_scratch:BFP 0 "=f"))]
8876 "s390_match_ccmode (insn, CCSmode) && TARGET_HARD_FLOAT"
8877 "lc<xde>br\t%0,%1"
8878 [(set_attr "op_type" "RRE")
8879 (set_attr "type" "fsimp<type>")])
8880
8881 ; lcdfr
8882 (define_insn "*neg<mode>2_nocc"
8883 [(set (match_operand:FP 0 "register_operand" "=f")
8884 (neg:FP (match_operand:FP 1 "register_operand" "<fT0>")))]
8885 "TARGET_DFP"
8886 "lcdfr\t%0,%1"
8887 [(set_attr "op_type" "RRE")
8888 (set_attr "type" "fsimp<type>")])
8889
8890 ; lcxbr, lcdbr, lcebr
8891 ; FIXME: wflcdb does not clobber cc
8892 ; FIXME: Does wflcdb ever match here?
8893 (define_insn "*neg<mode>2"
8894 [(set (match_operand:BFP 0 "register_operand" "=f,v,v")
8895 (neg:BFP (match_operand:BFP 1 "register_operand" "f,v,v")))
8896 (clobber (reg:CC CC_REGNUM))]
8897 "TARGET_HARD_FLOAT"
8898 "@
8899 lc<xde>br\t%0,%1
8900 wflcdb\t%0,%1
8901 wflcsb\t%0,%1"
8902 [(set_attr "op_type" "RRE,VRR,VRR")
8903 (set_attr "cpu_facility" "*,vx,vxe")
8904 (set_attr "type" "fsimp<type>,*,*")
8905 (set_attr "enabled" "*,<DF>,<SF>")])
8906
8907
8908 ;;
8909 ;;- Absolute value instructions.
8910 ;;
8911
8912 ;
8913 ; abs(di|si)2 instruction pattern(s).
8914 ;
8915
8916 (define_insn "*absdi2_sign_cc"
8917 [(set (reg CC_REGNUM)
8918 (compare (abs:DI (ashiftrt:DI (ashift:DI (subreg:DI
8919 (match_operand:SI 1 "register_operand" "d") 0)
8920 (const_int 32)) (const_int 32)))
8921 (const_int 0)))
8922 (set (match_operand:DI 0 "register_operand" "=d")
8923 (abs:DI (sign_extend:DI (match_dup 1))))]
8924 "TARGET_ZARCH && s390_match_ccmode (insn, CCAmode)"
8925 "lpgfr\t%0,%1"
8926 [(set_attr "op_type" "RRE")
8927 (set_attr "z10prop" "z10_c")])
8928
8929 (define_insn "*absdi2_sign"
8930 [(set (match_operand:DI 0 "register_operand" "=d")
8931 (abs:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "d"))))
8932 (clobber (reg:CC CC_REGNUM))]
8933 "TARGET_ZARCH"
8934 "lpgfr\t%0,%1"
8935 [(set_attr "op_type" "RRE")
8936 (set_attr "z10prop" "z10_c")])
8937
8938 ; lpr, lpgr
8939 (define_insn "*abs<mode>2_cc"
8940 [(set (reg CC_REGNUM)
8941 (compare (abs:GPR (match_operand:DI 1 "register_operand" "d"))
8942 (const_int 0)))
8943 (set (match_operand:GPR 0 "register_operand" "=d")
8944 (abs:GPR (match_dup 1)))]
8945 "s390_match_ccmode (insn, CCAmode)"
8946 "lp<g>r\t%0,%1"
8947 [(set_attr "op_type" "RR<E>")
8948 (set_attr "z10prop" "z10_c")])
8949
8950 ; lpr, lpgr
8951 (define_insn "*abs<mode>2_cconly"
8952 [(set (reg CC_REGNUM)
8953 (compare (abs:GPR (match_operand:GPR 1 "register_operand" "d"))
8954 (const_int 0)))
8955 (clobber (match_scratch:GPR 0 "=d"))]
8956 "s390_match_ccmode (insn, CCAmode)"
8957 "lp<g>r\t%0,%1"
8958 [(set_attr "op_type" "RR<E>")
8959 (set_attr "z10prop" "z10_c")])
8960
8961 ; lpr, lpgr
8962 (define_insn "abs<mode>2"
8963 [(set (match_operand:GPR 0 "register_operand" "=d")
8964 (abs:GPR (match_operand:GPR 1 "register_operand" "d")))
8965 (clobber (reg:CC CC_REGNUM))]
8966 ""
8967 "lp<g>r\t%0,%1"
8968 [(set_attr "op_type" "RR<E>")
8969 (set_attr "z10prop" "z10_c")])
8970
8971 ;
8972 ; abs(tf|df|sf)2 instruction pattern(s).
8973 ;
8974
8975 (define_expand "abs<mode>2<tf_fpr>"
8976 [(parallel
8977 [(set (match_operand:BFP 0 "register_operand" "=f")
8978 (abs:BFP (match_operand:BFP 1 "register_operand" "f")))
8979 (clobber (reg:CC CC_REGNUM))])]
8980 "TARGET_HARD_FLOAT"
8981 "")
8982
8983 ; lpxbr, lpdbr, lpebr
8984 (define_insn "*abs<mode>2_cc"
8985 [(set (reg CC_REGNUM)
8986 (compare (abs:BFP (match_operand:BFP 1 "register_operand" "f"))
8987 (match_operand:BFP 2 "const0_operand" "")))
8988 (set (match_operand:BFP 0 "register_operand" "=f")
8989 (abs:BFP (match_dup 1)))]
8990 "s390_match_ccmode (insn, CCSmode) && TARGET_HARD_FLOAT"
8991 "lp<xde>br\t%0,%1"
8992 [(set_attr "op_type" "RRE")
8993 (set_attr "type" "fsimp<type>")])
8994
8995 ; lpxbr, lpdbr, lpebr
8996 (define_insn "*abs<mode>2_cconly"
8997 [(set (reg CC_REGNUM)
8998 (compare (abs:BFP (match_operand:BFP 1 "register_operand" "f"))
8999 (match_operand:BFP 2 "const0_operand" "")))
9000 (clobber (match_scratch:BFP 0 "=f"))]
9001 "s390_match_ccmode (insn, CCSmode) && TARGET_HARD_FLOAT"
9002 "lp<xde>br\t%0,%1"
9003 [(set_attr "op_type" "RRE")
9004 (set_attr "type" "fsimp<type>")])
9005
9006 ; lpdfr
9007 (define_insn "*abs<mode>2_nocc"
9008 [(set (match_operand:FP 0 "register_operand" "=f")
9009 (abs:FP (match_operand:FP 1 "register_operand" "<fT0>")))]
9010 "TARGET_DFP"
9011 "lpdfr\t%0,%1"
9012 [(set_attr "op_type" "RRE")
9013 (set_attr "type" "fsimp<type>")])
9014
9015 ; lpxbr, lpdbr, lpebr
9016 ; FIXME: wflpdb does not clobber cc
9017 (define_insn "*abs<mode>2"
9018 [(set (match_operand:BFP 0 "register_operand" "=f,v")
9019 (abs:BFP (match_operand:BFP 1 "register_operand" "f,v")))
9020 (clobber (reg:CC CC_REGNUM))]
9021 "TARGET_HARD_FLOAT"
9022 "@
9023 lp<xde>br\t%0,%1
9024 wflpdb\t%0,%1"
9025 [(set_attr "op_type" "RRE,VRR")
9026 (set_attr "cpu_facility" "*,vx")
9027 (set_attr "type" "fsimp<type>,*")
9028 (set_attr "enabled" "*,<DFDI>")])
9029
9030
9031 ;;
9032 ;;- Negated absolute value instructions
9033 ;;
9034
9035 ;
9036 ; Integer
9037 ;
9038
9039 (define_insn "*negabsdi2_sign_cc"
9040 [(set (reg CC_REGNUM)
9041 (compare (neg:DI (abs:DI (ashiftrt:DI (ashift:DI (subreg:DI
9042 (match_operand:SI 1 "register_operand" "d") 0)
9043 (const_int 32)) (const_int 32))))
9044 (const_int 0)))
9045 (set (match_operand:DI 0 "register_operand" "=d")
9046 (neg:DI (abs:DI (sign_extend:DI (match_dup 1)))))]
9047 "TARGET_ZARCH && s390_match_ccmode (insn, CCAmode)"
9048 "lngfr\t%0,%1"
9049 [(set_attr "op_type" "RRE")
9050 (set_attr "z10prop" "z10_c")])
9051
9052 (define_insn "*negabsdi2_sign"
9053 [(set (match_operand:DI 0 "register_operand" "=d")
9054 (neg:DI (abs:DI (sign_extend:DI
9055 (match_operand:SI 1 "register_operand" "d")))))
9056 (clobber (reg:CC CC_REGNUM))]
9057 "TARGET_ZARCH"
9058 "lngfr\t%0,%1"
9059 [(set_attr "op_type" "RRE")
9060 (set_attr "z10prop" "z10_c")])
9061
9062 ; lnr, lngr
9063 (define_insn "*negabs<mode>2_cc"
9064 [(set (reg CC_REGNUM)
9065 (compare (neg:GPR (abs:GPR (match_operand:GPR 1 "register_operand" "d")))
9066 (const_int 0)))
9067 (set (match_operand:GPR 0 "register_operand" "=d")
9068 (neg:GPR (abs:GPR (match_dup 1))))]
9069 "s390_match_ccmode (insn, CCAmode)"
9070 "ln<g>r\t%0,%1"
9071 [(set_attr "op_type" "RR<E>")
9072 (set_attr "z10prop" "z10_c")])
9073
9074 ; lnr, lngr
9075 (define_insn "*negabs<mode>2_cconly"
9076 [(set (reg CC_REGNUM)
9077 (compare (neg:GPR (abs:GPR (match_operand:GPR 1 "register_operand" "d")))
9078 (const_int 0)))
9079 (clobber (match_scratch:GPR 0 "=d"))]
9080 "s390_match_ccmode (insn, CCAmode)"
9081 "ln<g>r\t%0,%1"
9082 [(set_attr "op_type" "RR<E>")
9083 (set_attr "z10prop" "z10_c")])
9084
9085 ; lnr, lngr
9086 (define_insn "*negabs<mode>2"
9087 [(set (match_operand:GPR 0 "register_operand" "=d")
9088 (neg:GPR (abs:GPR (match_operand:GPR 1 "register_operand" "d"))))
9089 (clobber (reg:CC CC_REGNUM))]
9090 ""
9091 "ln<g>r\t%0,%1"
9092 [(set_attr "op_type" "RR<E>")
9093 (set_attr "z10prop" "z10_c")])
9094
9095 ;
9096 ; Floating point
9097 ;
9098
9099 ; lnxbr, lndbr, lnebr
9100 (define_insn "*negabs<mode>2_cc"
9101 [(set (reg CC_REGNUM)
9102 (compare (neg:BFP (abs:BFP (match_operand:BFP 1 "register_operand" "f")))
9103 (match_operand:BFP 2 "const0_operand" "")))
9104 (set (match_operand:BFP 0 "register_operand" "=f")
9105 (neg:BFP (abs:BFP (match_dup 1))))]
9106 "s390_match_ccmode (insn, CCSmode) && TARGET_HARD_FLOAT"
9107 "ln<xde>br\t%0,%1"
9108 [(set_attr "op_type" "RRE")
9109 (set_attr "type" "fsimp<type>")])
9110
9111 ; lnxbr, lndbr, lnebr
9112 (define_insn "*negabs<mode>2_cconly"
9113 [(set (reg CC_REGNUM)
9114 (compare (neg:BFP (abs:BFP (match_operand:BFP 1 "register_operand" "f")))
9115 (match_operand:BFP 2 "const0_operand" "")))
9116 (clobber (match_scratch:BFP 0 "=f"))]
9117 "s390_match_ccmode (insn, CCSmode) && TARGET_HARD_FLOAT"
9118 "ln<xde>br\t%0,%1"
9119 [(set_attr "op_type" "RRE")
9120 (set_attr "type" "fsimp<type>")])
9121
9122 ; lndfr
9123 (define_insn "*negabs<mode>2_nocc"
9124 [(set (match_operand:FP 0 "register_operand" "=f")
9125 (neg:FP (abs:FP (match_operand:FP 1 "register_operand" "<fT0>"))))]
9126 "TARGET_DFP"
9127 "lndfr\t%0,%1"
9128 [(set_attr "op_type" "RRE")
9129 (set_attr "type" "fsimp<type>")])
9130
9131 ; lnxbr, lndbr, lnebr
9132 ; FIXME: wflndb does not clobber cc
9133 (define_insn "*negabs<mode>2"
9134 [(set (match_operand:BFP 0 "register_operand" "=f,v")
9135 (neg:BFP (abs:BFP (match_operand:BFP 1 "register_operand" "f,v"))))
9136 (clobber (reg:CC CC_REGNUM))]
9137 "TARGET_HARD_FLOAT"
9138 "@
9139 ln<xde>br\t%0,%1
9140 wflndb\t%0,%1"
9141 [(set_attr "op_type" "RRE,VRR")
9142 (set_attr "cpu_facility" "*,vx")
9143 (set_attr "type" "fsimp<type>,*")
9144 (set_attr "enabled" "*,<DFDI>")])
9145
9146 ;;
9147 ;;- Square root instructions.
9148 ;;
9149
9150 ;
9151 ; sqrt(df|sf)2 instruction pattern(s).
9152 ;
9153
9154 ; sqxbr, sqdbr, sqebr, sqdb, sqeb
9155 (define_insn "sqrt<mode>2<tf_fpr>"
9156 [(set (match_operand:BFP 0 "register_operand" "=f,f,v")
9157 (sqrt:BFP (match_operand:BFP 1 "general_operand" "f,R,v")))]
9158 "TARGET_HARD_FLOAT"
9159 "@
9160 sq<xde>br\t%0,%1
9161 sq<xde>b\t%0,%1
9162 wfsqdb\t%v0,%v1"
9163 [(set_attr "op_type" "RRE,RXE,VRR")
9164 (set_attr "type" "fsqrt<type>")
9165 (set_attr "cpu_facility" "*,*,vx")
9166 (set_attr "enabled" "*,<DSF>,<DFDI>")])
9167
9168
9169 ;;
9170 ;;- One complement instructions.
9171 ;;
9172
9173 ;
9174 ; one_cmpl(di|si|hi|qi)2 instruction pattern(s).
9175 ;
9176
9177 (define_expand "one_cmpl<mode>2"
9178 [(parallel
9179 [(set (match_operand:INT 0 "register_operand" "")
9180 (xor:INT (match_operand:INT 1 "register_operand" "")
9181 (const_int -1)))
9182 (clobber (reg:CC CC_REGNUM))])]
9183 ""
9184 "")
9185
9186
9187 ;;
9188 ;; Find leftmost bit instructions.
9189 ;;
9190
9191 (define_expand "clzdi2"
9192 [(set (match_operand:DI 0 "register_operand" "=d")
9193 (clz:DI (match_operand:DI 1 "register_operand" "d")))]
9194 "TARGET_EXTIMM && TARGET_ZARCH"
9195 {
9196 rtx_insn *insn;
9197 rtx clz_equal;
9198 rtx wide_reg = gen_reg_rtx (TImode);
9199 rtx msb = gen_rtx_CONST_INT (DImode, HOST_WIDE_INT_1U << 63);
9200
9201 clz_equal = gen_rtx_CLZ (DImode, operands[1]);
9202
9203 emit_insn (gen_clztidi2 (wide_reg, operands[1], msb));
9204
9205 insn = emit_move_insn (operands[0], gen_highpart (DImode, wide_reg));
9206 set_unique_reg_note (insn, REG_EQUAL, clz_equal);
9207
9208 DONE;
9209 })
9210
9211 ; CLZ result is in hard reg op0 - this is the high part of the target operand
9212 ; The source with the left-most one bit cleared is in hard reg op0 + 1 - the low part
9213 (define_insn "clztidi2"
9214 [(set (match_operand:TI 0 "register_operand" "=d")
9215 (ior:TI
9216 (ashift:TI (zero_extend:TI (clz:DI (match_operand:DI 1 "register_operand" "d")))
9217 (const_int 64))
9218 (zero_extend:TI
9219 (xor:DI (match_dup 1)
9220 (lshiftrt (match_operand:DI 2 "const_int_operand" "")
9221 (subreg:SI (clz:DI (match_dup 1)) 4))))))
9222 (clobber (reg:CC CC_REGNUM))]
9223 "UINTVAL (operands[2]) == HOST_WIDE_INT_1U << 63
9224 && TARGET_EXTIMM && TARGET_ZARCH"
9225 "flogr\t%0,%1"
9226 [(set_attr "op_type" "RRE")])
9227
9228
9229 ;;
9230 ;;- Rotate instructions.
9231 ;;
9232
9233 ;
9234 ; rotl(di|si)3 instruction pattern(s).
9235 ;
9236
9237 (define_expand "rotl<mode>3"
9238 [(set (match_operand:GPR 0 "register_operand" "")
9239 (rotate:GPR (match_operand:GPR 1 "register_operand" "")
9240 (match_operand:QI 2 "shift_count_operand" "")))]
9241 ""
9242 "")
9243
9244 ; rll, rllg
9245 (define_insn "*rotl<mode>3"
9246 [(set (match_operand:GPR 0 "register_operand" "=d")
9247 (rotate:GPR (match_operand:GPR 1 "register_operand" "d")
9248 (match_operand:QI 2 "shift_count_operand" "jsc")))]
9249 ""
9250 "rll<g>\t%0,%1,%Y2"
9251 [(set_attr "op_type" "RSE")
9252 (set_attr "atype" "reg")
9253 (set_attr "z10prop" "z10_super_E1")])
9254
9255
9256 ;;
9257 ;;- Shift instructions.
9258 ;;
9259
9260 ;
9261 ; (ashl|lshr)(di|si)3 instruction pattern(s).
9262 ; Left shifts and logical right shifts
9263
9264 (define_expand "<shift><mode>3"
9265 [(set (match_operand:DSI 0 "register_operand" "")
9266 (SHIFT:DSI (match_operand:DSI 1 "register_operand" "")
9267 (match_operand:QI 2 "shift_count_operand" "")))]
9268 ""
9269 "")
9270
9271 ; ESA 64 bit register pair shift with reg or imm shift count
9272 ; sldl, srdl
9273 (define_insn "*<shift>di3_31"
9274 [(set (match_operand:DI 0 "register_operand" "=d")
9275 (SHIFT:DI (match_operand:DI 1 "register_operand" "0")
9276 (match_operand:QI 2 "shift_count_operand" "jsc")))]
9277 "!TARGET_ZARCH"
9278 "s<lr>dl\t%0,%Y2"
9279 [(set_attr "op_type" "RS")
9280 (set_attr "atype" "reg")
9281 (set_attr "z196prop" "z196_cracked")])
9282
9283
9284 ; 64 bit register shift with reg or imm shift count
9285 ; sll, srl, sllg, srlg, sllk, srlk
9286 (define_insn "*<shift><mode>3"
9287 [(set (match_operand:GPR 0 "register_operand" "=d, d")
9288 (SHIFT:GPR (match_operand:GPR 1 "register_operand" "<d0>, d")
9289 (match_operand:QI 2 "shift_count_operand" "jsc,jsc")))]
9290 ""
9291 "@
9292 s<lr>l<g>\t%0,<1>%Y2
9293 s<lr>l<gk>\t%0,%1,%Y2"
9294 [(set_attr "op_type" "RS<E>,RSY")
9295 (set_attr "atype" "reg,reg")
9296 (set_attr "cpu_facility" "*,z196")
9297 (set_attr "z10prop" "z10_super_E1,*")])
9298
9299
9300 ;
9301 ; ashr(di|si)3 instruction pattern(s).
9302 ; Arithmetic right shifts
9303
9304 (define_expand "ashr<mode>3"
9305 [(parallel
9306 [(set (match_operand:DSI 0 "register_operand" "")
9307 (ashiftrt:DSI (match_operand:DSI 1 "register_operand" "")
9308 (match_operand:QI 2 "shift_count_operand" "")))
9309 (clobber (reg:CC CC_REGNUM))])]
9310 ""
9311 "")
9312
9313 ; FIXME: The number of alternatives is doubled here to match the fix
9314 ; number of 2 in the subst pattern for the (clobber (match_scratch...
9315 ; The right fix should be to support match_scratch in the output
9316 ; pattern of a define_subst.
9317 (define_insn "*ashrdi3_31<setcc><cconly>"
9318 [(set (match_operand:DI 0 "register_operand" "=d, d")
9319 (ashiftrt:DI (match_operand:DI 1 "register_operand" "0, 0")
9320 (match_operand:QI 2 "shift_count_operand" "jsc,jsc")))
9321 (clobber (reg:CC CC_REGNUM))]
9322 "!TARGET_ZARCH"
9323 "@
9324 srda\t%0,%Y2
9325 srda\t%0,%Y2"
9326 [(set_attr "op_type" "RS")
9327 (set_attr "atype" "reg")])
9328
9329
9330 ; sra, srag
9331 (define_insn "*ashr<mode>3<setcc><cconly>"
9332 [(set (match_operand:GPR 0 "register_operand" "=d, d")
9333 (ashiftrt:GPR (match_operand:GPR 1 "register_operand" "<d0>, d")
9334 (match_operand:QI 2 "shift_count_operand" "jsc,jsc")))
9335 (clobber (reg:CC CC_REGNUM))]
9336 ""
9337 "@
9338 sra<g>\t%0,<1>%Y2
9339 sra<gk>\t%0,%1,%Y2"
9340 [(set_attr "op_type" "RS<E>,RSY")
9341 (set_attr "atype" "reg")
9342 (set_attr "cpu_facility" "*,z196")
9343 (set_attr "z10prop" "z10_super_E1,*")])
9344
9345
9346 ;;
9347 ;; Branch instruction patterns.
9348 ;;
9349
9350 (define_expand "cbranch<mode>4"
9351 [(set (pc)
9352 (if_then_else (match_operator 0 "comparison_operator"
9353 [(match_operand:GPR 1 "register_operand" "")
9354 (match_operand:GPR 2 "general_operand" "")])
9355 (label_ref (match_operand 3 "" ""))
9356 (pc)))]
9357 ""
9358 "s390_emit_jump (operands[3],
9359 s390_emit_compare (GET_CODE (operands[0]), operands[1], operands[2]));
9360 DONE;")
9361
9362 (define_expand "cbranch<mode>4"
9363 [(set (pc)
9364 (if_then_else (match_operator 0 "comparison_operator"
9365 [(match_operand:FP_ANYTF 1 "register_operand" "")
9366 (match_operand:FP_ANYTF 2 "general_operand" "")])
9367 (label_ref (match_operand 3 "" ""))
9368 (pc)))]
9369 "TARGET_HARD_FLOAT"
9370 "s390_emit_jump (operands[3],
9371 s390_emit_compare (GET_CODE (operands[0]), operands[1], operands[2]));
9372 DONE;")
9373
9374 (define_expand "cbranchcc4"
9375 [(set (pc)
9376 (if_then_else (match_operator 0 "s390_comparison"
9377 [(match_operand 1 "cc_reg_operand" "")
9378 (match_operand 2 "const_int_operand" "")])
9379 (label_ref (match_operand 3 "" ""))
9380 (pc)))]
9381 ""
9382 "")
9383
9384
9385 ;;
9386 ;;- Conditional jump instructions.
9387 ;;
9388
9389 (define_insn "*cjump_64"
9390 [(set (pc)
9391 (if_then_else
9392 (match_operator 1 "s390_comparison" [(reg CC_REGNUM)
9393 (match_operand 2 "const_int_operand" "")])
9394 (label_ref (match_operand 0 "" ""))
9395 (pc)))]
9396 ""
9397 {
9398 if (get_attr_length (insn) == 4)
9399 return "j%C1\t%l0";
9400 else
9401 return "jg%C1\t%l0";
9402 }
9403 [(set_attr "op_type" "RI")
9404 (set_attr "type" "branch")
9405 (set (attr "length")
9406 (if_then_else (lt (abs (minus (pc) (match_dup 0))) (const_int 60000))
9407 (const_int 4) (const_int 6)))])
9408
9409 (define_insn "*cjump_long"
9410 [(set (pc)
9411 (if_then_else
9412 (match_operator 1 "s390_comparison" [(reg CC_REGNUM) (const_int 0)])
9413 (match_operand 0 "address_operand" "ZQZR")
9414 (pc)))]
9415 "!TARGET_INDIRECT_BRANCH_NOBP_JUMP"
9416 {
9417 if (get_attr_op_type (insn) == OP_TYPE_RR)
9418 return "b%C1r\t%0";
9419 else
9420 return "b%C1\t%a0";
9421 }
9422 [(set (attr "op_type")
9423 (if_then_else (match_operand 0 "register_operand" "")
9424 (const_string "RR") (const_string "RX")))
9425 (set (attr "mnemonic")
9426 (if_then_else (match_operand 0 "register_operand" "")
9427 (const_string "bcr") (const_string "bc")))
9428 (set_attr "type" "branch")
9429 (set_attr "atype" "agen")])
9430
9431 ;; A conditional return instruction.
9432 (define_insn "*c<code>"
9433 [(set (pc)
9434 (if_then_else
9435 (match_operator 0 "s390_comparison" [(reg CC_REGNUM) (const_int 0)])
9436 (ANY_RETURN)
9437 (pc)))]
9438 "s390_can_use_<code>_insn ()"
9439 {
9440 if (TARGET_INDIRECT_BRANCH_NOBP_RET)
9441 {
9442 s390_indirect_branch_via_thunk (RETURN_REGNUM,
9443 INVALID_REGNUM,
9444 operands[0],
9445 s390_indirect_branch_type_return);
9446 return "";
9447 }
9448 else
9449 return "b%C0r\t%%r14";
9450 }
9451 [(set (attr "op_type")
9452 (if_then_else (match_test "TARGET_INDIRECT_BRANCH_NOBP_RET")
9453 (const_string "RIL")
9454 (const_string "RR")))
9455 (set (attr "mnemonic")
9456 (if_then_else (match_test "TARGET_INDIRECT_BRANCH_NOBP_RET")
9457 (const_string "brcl")
9458 (const_string "bcr")))
9459 (set_attr "type" "jsr")
9460 (set_attr "atype" "agen")])
9461
9462 ;;
9463 ;;- Negated conditional jump instructions.
9464 ;;
9465
9466 (define_insn "*icjump_64"
9467 [(set (pc)
9468 (if_then_else
9469 (match_operator 1 "s390_comparison" [(reg CC_REGNUM) (const_int 0)])
9470 (pc)
9471 (label_ref (match_operand 0 "" ""))))]
9472 ""
9473 {
9474 if (get_attr_length (insn) == 4)
9475 return "j%D1\t%l0";
9476 else
9477 return "jg%D1\t%l0";
9478 }
9479 [(set_attr "op_type" "RI")
9480 (set_attr "type" "branch")
9481 (set (attr "length")
9482 (if_then_else (lt (abs (minus (pc) (match_dup 0))) (const_int 60000))
9483 (const_int 4) (const_int 6)))])
9484
9485 (define_insn "*icjump_long"
9486 [(set (pc)
9487 (if_then_else
9488 (match_operator 1 "s390_comparison" [(reg CC_REGNUM) (const_int 0)])
9489 (pc)
9490 (match_operand 0 "address_operand" "ZQZR")))]
9491 "!TARGET_INDIRECT_BRANCH_NOBP_JUMP"
9492 {
9493 if (get_attr_op_type (insn) == OP_TYPE_RR)
9494 return "b%D1r\t%0";
9495 else
9496 return "b%D1\t%a0";
9497 }
9498 [(set (attr "op_type")
9499 (if_then_else (match_operand 0 "register_operand" "")
9500 (const_string "RR") (const_string "RX")))
9501 (set (attr "mnemonic")
9502 (if_then_else (match_operand 0 "register_operand" "")
9503 (const_string "bcr") (const_string "bc")))
9504 (set_attr "type" "branch")
9505 (set_attr "atype" "agen")])
9506
9507 ;;
9508 ;;- Trap instructions.
9509 ;;
9510
9511 (define_insn "trap"
9512 [(trap_if (const_int 1) (const_int 0))]
9513 ""
9514 "j\t.+2"
9515 [(set_attr "op_type" "RI")
9516 (set_attr "type" "branch")])
9517
9518 (define_expand "ctrap<mode>4"
9519 [(trap_if (match_operator 0 "comparison_operator"
9520 [(match_operand:GPR 1 "register_operand" "")
9521 (match_operand:GPR 2 "general_operand" "")])
9522 (match_operand 3 "const0_operand" ""))]
9523 ""
9524 {
9525 rtx cond = s390_emit_compare (GET_CODE (operands[0]),
9526 operands[1], operands[2]);
9527 emit_insn (gen_condtrap (cond, XEXP (cond, 0)));
9528 DONE;
9529 })
9530
9531 (define_expand "ctrap<mode>4"
9532 [(trap_if (match_operator 0 "comparison_operator"
9533 [(match_operand:FP 1 "register_operand" "")
9534 (match_operand:FP 2 "general_operand" "")])
9535 (match_operand 3 "const0_operand" ""))]
9536 ""
9537 {
9538 rtx cond = s390_emit_compare (GET_CODE (operands[0]),
9539 operands[1], operands[2]);
9540 emit_insn (gen_condtrap (cond, XEXP (cond, 0)));
9541 DONE;
9542 })
9543
9544 (define_insn "condtrap"
9545 [(trap_if (match_operator 0 "s390_comparison"
9546 [(match_operand 1 "cc_reg_operand" "c")
9547 (const_int 0)])
9548 (const_int 0))]
9549 ""
9550 "j%C0\t.+2";
9551 [(set_attr "op_type" "RI")
9552 (set_attr "type" "branch")])
9553
9554 ; crt, cgrt, cit, cgit
9555 (define_insn "*cmp_and_trap_signed_int<mode>"
9556 [(trap_if (match_operator 0 "s390_signed_integer_comparison"
9557 [(match_operand:GPR 1 "register_operand" "d,d")
9558 (match_operand:GPR 2 "nonmemory_operand" "d,K")])
9559 (const_int 0))]
9560 "TARGET_Z10"
9561 "@
9562 c<g>rt%C0\t%1,%2
9563 c<g>it%C0\t%1,%h2"
9564 [(set_attr "op_type" "RRF,RIE")
9565 (set_attr "type" "branch")
9566 (set_attr "z10prop" "z10_super_c,z10_super")])
9567
9568 ; clrt, clgrt, clfit, clgit, clt, clgt
9569 (define_insn "*cmp_and_trap_unsigned_int<mode>"
9570 [(trap_if (match_operator 0 "s390_unsigned_integer_comparison"
9571 [(match_operand:GPR 1 "register_operand" "d,d,d")
9572 (match_operand:GPR 2 "general_operand" "d,D,T")])
9573 (const_int 0))]
9574 "TARGET_Z10"
9575 "@
9576 cl<g>rt%C0\t%1,%2
9577 cl<gf>it%C0\t%1,%x2
9578 cl<g>t%C0\t%1,%2"
9579 [(set_attr "op_type" "RRF,RIE,RSY")
9580 (set_attr "type" "branch")
9581 (set_attr "z10prop" "z10_super_c,z10_super,*")
9582 (set_attr "cpu_facility" "z10,z10,zEC12")])
9583
9584 ; lat, lgat
9585 (define_insn "*load_and_trap<mode>"
9586 [(trap_if (eq (match_operand:GPR 0 "memory_operand" "T")
9587 (const_int 0))
9588 (const_int 0))
9589 (set (match_operand:GPR 1 "register_operand" "=d")
9590 (match_dup 0))]
9591 "TARGET_ZEC12"
9592 "l<g>at\t%1,%0"
9593 [(set_attr "op_type" "RXY")])
9594
9595
9596 ;;
9597 ;;- Loop instructions.
9598 ;;
9599 ;; This is all complicated by the fact that since this is a jump insn
9600 ;; we must handle our own output reloads.
9601
9602 ;; branch on index
9603
9604 ; This splitter will be matched by combine and has to add the 2 moves
9605 ; necessary to load the compare and the increment values into a
9606 ; register pair as needed by brxle.
9607
9608 (define_insn_and_split "*brx_stage1_<GPR:mode>"
9609 [(set (pc)
9610 (if_then_else
9611 (match_operator 6 "s390_brx_operator"
9612 [(plus:GPR (match_operand:GPR 1 "register_operand" "")
9613 (match_operand:GPR 2 "general_operand" ""))
9614 (match_operand:GPR 3 "register_operand" "")])
9615 (label_ref (match_operand 0 "" ""))
9616 (pc)))
9617 (set (match_operand:GPR 4 "nonimmediate_operand" "")
9618 (plus:GPR (match_dup 1) (match_dup 2)))
9619 (clobber (match_scratch:GPR 5 ""))]
9620 ""
9621 "#"
9622 "!reload_completed && !reload_in_progress"
9623 [(set (match_dup 7) (match_dup 2)) ; the increment
9624 (set (match_dup 8) (match_dup 3)) ; the comparison value
9625 (parallel [(set (pc)
9626 (if_then_else
9627 (match_op_dup 6
9628 [(plus:GPR (match_dup 1) (match_dup 7))
9629 (match_dup 8)])
9630 (label_ref (match_dup 0))
9631 (pc)))
9632 (set (match_dup 4)
9633 (plus:GPR (match_dup 1) (match_dup 7)))
9634 (clobber (match_dup 5))
9635 (clobber (reg:CC CC_REGNUM))])]
9636 {
9637 rtx dreg = gen_reg_rtx (word_mode == DImode ? TImode : DImode);
9638 operands[7] = gen_lowpart (<GPR:MODE>mode,
9639 gen_highpart (word_mode, dreg));
9640 operands[8] = gen_lowpart (<GPR:MODE>mode,
9641 gen_lowpart (word_mode, dreg));
9642 })
9643
9644 ; brxlg, brxhg
9645
9646 (define_insn_and_split "*brxg_64bit"
9647 [(set (pc)
9648 (if_then_else
9649 (match_operator 5 "s390_brx_operator"
9650 [(plus:DI (match_operand:DI 1 "register_operand" "d,d,d")
9651 (subreg:DI (match_operand:TI 2 "register_operand" "d,d,d") 0))
9652 (subreg:DI (match_dup 2) 8)])
9653 (label_ref (match_operand 0 "" ""))
9654 (pc)))
9655 (set (match_operand:DI 3 "nonimmediate_operand" "=1,?X,?X")
9656 (plus:DI (match_dup 1)
9657 (subreg:DI (match_dup 2) 0)))
9658 (clobber (match_scratch:DI 4 "=X,&1,&?d"))
9659 (clobber (reg:CC CC_REGNUM))]
9660 "TARGET_ZARCH"
9661 {
9662 if (which_alternative != 0)
9663 return "#";
9664 else if (get_attr_length (insn) == 6)
9665 return "brx%E5g\t%1,%2,%l0";
9666 else
9667 return "agr\t%1,%2\;cgr\t%1,%M2\;jg%C5\t%l0";
9668 }
9669 "&& reload_completed
9670 && (!REG_P (operands[3])
9671 || !rtx_equal_p (operands[1], operands[3]))"
9672 [(set (match_dup 4) (match_dup 1))
9673 (parallel [(set (match_dup 4) (plus:DI (match_dup 4) (subreg:DI (match_dup 2) 0)))
9674 (clobber (reg:CC CC_REGNUM))])
9675 (set (reg:CCS CC_REGNUM) (compare:CCS (match_dup 4) (subreg:DI (match_dup 2) 8)))
9676 (set (match_dup 3) (match_dup 4))
9677 (set (pc) (if_then_else (match_op_dup 5 [(reg:CCS CC_REGNUM) (const_int 0)])
9678 (label_ref (match_dup 0))
9679 (pc)))]
9680 ""
9681 [(set_attr "op_type" "RIE")
9682 (set_attr "type" "branch")
9683 (set (attr "length")
9684 (if_then_else (lt (abs (minus (pc) (match_dup 0))) (const_int 60000))
9685 (const_int 6) (const_int 16)))])
9686
9687 ; brxle, brxh
9688
9689 (define_insn_and_split "*brx_64bit"
9690 [(set (pc)
9691 (if_then_else
9692 (match_operator 5 "s390_brx_operator"
9693 [(plus:SI (match_operand:SI 1 "register_operand" "d,d,d")
9694 (subreg:SI (match_operand:TI 2 "register_operand" "d,d,d") 4))
9695 (subreg:SI (match_dup 2) 12)])
9696 (label_ref (match_operand 0 "" ""))
9697 (pc)))
9698 (set (match_operand:SI 3 "nonimmediate_operand" "=1,?X,?X")
9699 (plus:SI (match_dup 1)
9700 (subreg:SI (match_dup 2) 4)))
9701 (clobber (match_scratch:SI 4 "=X,&1,&?d"))
9702 (clobber (reg:CC CC_REGNUM))]
9703 "TARGET_ZARCH"
9704 {
9705 if (which_alternative != 0)
9706 return "#";
9707 else if (get_attr_length (insn) == 6)
9708 return "brx%C5\t%1,%2,%l0";
9709 else
9710 return "ar\t%1,%2\;cr\t%1,%M2\;jg%C5\t%l0";
9711 }
9712 "&& reload_completed
9713 && (!REG_P (operands[3])
9714 || !rtx_equal_p (operands[1], operands[3]))"
9715 [(set (match_dup 4) (match_dup 1))
9716 (parallel [(set (match_dup 4) (plus:SI (match_dup 4) (subreg:SI (match_dup 2) 4)))
9717 (clobber (reg:CC CC_REGNUM))])
9718 (set (reg:CCS CC_REGNUM) (compare:CCS (match_dup 4) (subreg:SI (match_dup 2) 12)))
9719 (set (match_dup 3) (match_dup 4))
9720 (set (pc) (if_then_else (match_op_dup 5 [(reg:CCS CC_REGNUM) (const_int 0)])
9721 (label_ref (match_dup 0))
9722 (pc)))]
9723 ""
9724 [(set_attr "op_type" "RSI")
9725 (set_attr "type" "branch")
9726 (set (attr "length")
9727 (if_then_else (lt (abs (minus (pc) (match_dup 0))) (const_int 60000))
9728 (const_int 6) (const_int 14)))])
9729
9730 ; brxle, brxh
9731
9732 (define_insn_and_split "*brx_31bit"
9733 [(set (pc)
9734 (if_then_else
9735 (match_operator 5 "s390_brx_operator"
9736 [(plus:SI (match_operand:SI 1 "register_operand" "d,d,d")
9737 (subreg:SI (match_operand:DI 2 "register_operand" "d,d,d") 0))
9738 (subreg:SI (match_dup 2) 4)])
9739 (label_ref (match_operand 0 "" ""))
9740 (pc)))
9741 (set (match_operand:SI 3 "nonimmediate_operand" "=1,?X,?X")
9742 (plus:SI (match_dup 1)
9743 (subreg:SI (match_dup 2) 0)))
9744 (clobber (match_scratch:SI 4 "=X,&1,&?d"))
9745 (clobber (reg:CC CC_REGNUM))]
9746 "!TARGET_ZARCH"
9747 {
9748 if (which_alternative != 0)
9749 return "#";
9750 else if (get_attr_length (insn) == 6)
9751 return "brx%C5\t%1,%2,%l0";
9752 else
9753 return "ar\t%1,%2\;cr\t%1,%M2\;jg%C5\t%l0";
9754 }
9755 "&& reload_completed
9756 && (!REG_P (operands[3])
9757 || !rtx_equal_p (operands[1], operands[3]))"
9758 [(set (match_dup 4) (match_dup 1))
9759 (parallel [(set (match_dup 4) (plus:SI (match_dup 4) (subreg:SI (match_dup 2) 0)))
9760 (clobber (reg:CC CC_REGNUM))])
9761 (set (reg:CCS CC_REGNUM) (compare:CCS (match_dup 4) (subreg:SI (match_dup 2) 4)))
9762 (set (match_dup 3) (match_dup 4))
9763 (set (pc) (if_then_else (match_op_dup 5 [(reg:CCS CC_REGNUM) (const_int 0)])
9764 (label_ref (match_dup 0))
9765 (pc)))]
9766 ""
9767 [(set_attr "op_type" "RSI")
9768 (set_attr "type" "branch")
9769 (set (attr "length")
9770 (if_then_else (lt (abs (minus (pc) (match_dup 0))) (const_int 60000))
9771 (const_int 6) (const_int 14)))])
9772
9773
9774 ;; branch on count
9775
9776 (define_expand "doloop_end"
9777 [(use (match_operand 0 "" "")) ; loop pseudo
9778 (use (match_operand 1 "" ""))] ; label
9779 ""
9780 {
9781 if (GET_MODE (operands[0]) == SImode)
9782 emit_jump_insn (gen_doloop_si64 (operands[1], operands[0], operands[0]));
9783 else if (GET_MODE (operands[0]) == DImode && TARGET_ZARCH)
9784 emit_jump_insn (gen_doloop_di (operands[1], operands[0], operands[0]));
9785 else
9786 FAIL;
9787
9788 DONE;
9789 })
9790
9791 (define_insn_and_split "doloop_si64"
9792 [(set (pc)
9793 (if_then_else
9794 (ne (match_operand:SI 1 "register_operand" "d,d,d")
9795 (const_int 1))
9796 (label_ref (match_operand 0 "" ""))
9797 (pc)))
9798 (set (match_operand:SI 2 "nonimmediate_operand" "=1,?X,?X")
9799 (plus:SI (match_dup 1) (const_int -1)))
9800 (clobber (match_scratch:SI 3 "=X,&1,&?d"))
9801 (clobber (reg:CC CC_REGNUM))]
9802 ""
9803 {
9804 if (which_alternative != 0)
9805 return "#";
9806 else if (get_attr_length (insn) == 4)
9807 return "brct\t%1,%l0";
9808 else
9809 return "ahi\t%1,-1\;jgne\t%l0";
9810 }
9811 "&& reload_completed
9812 && (! REG_P (operands[2])
9813 || ! rtx_equal_p (operands[1], operands[2]))"
9814 [(set (match_dup 3) (match_dup 1))
9815 (parallel [(set (reg:CCAN CC_REGNUM)
9816 (compare:CCAN (plus:SI (match_dup 3) (const_int -1))
9817 (const_int 0)))
9818 (set (match_dup 3) (plus:SI (match_dup 3) (const_int -1)))])
9819 (set (match_dup 2) (match_dup 3))
9820 (set (pc) (if_then_else (ne (reg:CCAN CC_REGNUM) (const_int 0))
9821 (label_ref (match_dup 0))
9822 (pc)))]
9823 ""
9824 [(set_attr "op_type" "RI")
9825 ; Strictly speaking, the z10 properties are valid for brct only, however, it does not
9826 ; hurt us in the (rare) case of ahi.
9827 (set_attr "z10prop" "z10_super_E1")
9828 (set_attr "type" "branch")
9829 (set (attr "length")
9830 (if_then_else (lt (abs (minus (pc) (match_dup 0))) (const_int 60000))
9831 (const_int 4) (const_int 10)))])
9832
9833 (define_insn_and_split "doloop_di"
9834 [(set (pc)
9835 (if_then_else
9836 (ne (match_operand:DI 1 "register_operand" "d,d,d")
9837 (const_int 1))
9838 (label_ref (match_operand 0 "" ""))
9839 (pc)))
9840 (set (match_operand:DI 2 "nonimmediate_operand" "=1,?X,?X")
9841 (plus:DI (match_dup 1) (const_int -1)))
9842 (clobber (match_scratch:DI 3 "=X,&1,&?d"))
9843 (clobber (reg:CC CC_REGNUM))]
9844 "TARGET_ZARCH"
9845 {
9846 if (which_alternative != 0)
9847 return "#";
9848 else if (get_attr_length (insn) == 4)
9849 return "brctg\t%1,%l0";
9850 else
9851 return "aghi\t%1,-1\;jgne\t%l0";
9852 }
9853 "&& reload_completed
9854 && (! REG_P (operands[2])
9855 || ! rtx_equal_p (operands[1], operands[2]))"
9856 [(set (match_dup 3) (match_dup 1))
9857 (parallel [(set (reg:CCAN CC_REGNUM)
9858 (compare:CCAN (plus:DI (match_dup 3) (const_int -1))
9859 (const_int 0)))
9860 (set (match_dup 3) (plus:DI (match_dup 3) (const_int -1)))])
9861 (set (match_dup 2) (match_dup 3))
9862 (set (pc) (if_then_else (ne (reg:CCAN CC_REGNUM) (const_int 0))
9863 (label_ref (match_dup 0))
9864 (pc)))]
9865 ""
9866 [(set_attr "op_type" "RI")
9867 ; Strictly speaking, the z10 properties are valid for brct only, however, it does not
9868 ; hurt us in the (rare) case of ahi.
9869 (set_attr "z10prop" "z10_super_E1")
9870 (set_attr "type" "branch")
9871 (set (attr "length")
9872 (if_then_else (lt (abs (minus (pc) (match_dup 0))) (const_int 60000))
9873 (const_int 4) (const_int 10)))])
9874
9875 ;;
9876 ;;- Unconditional jump instructions.
9877 ;;
9878
9879 ;
9880 ; jump instruction pattern(s).
9881 ;
9882
9883 (define_expand "jump"
9884 [(match_operand 0 "" "")]
9885 ""
9886 "s390_emit_jump (operands[0], NULL_RTX); DONE;")
9887
9888 (define_insn "*jump64"
9889 [(set (pc) (label_ref (match_operand 0 "" "")))]
9890 ""
9891 {
9892 if (get_attr_length (insn) == 4)
9893 return "j\t%l0";
9894 else
9895 return "jg\t%l0";
9896 }
9897 [(set_attr "op_type" "RI")
9898 (set_attr "type" "branch")
9899 (set (attr "length")
9900 (if_then_else (lt (abs (minus (pc) (match_dup 0))) (const_int 60000))
9901 (const_int 4) (const_int 6)))])
9902
9903 ;
9904 ; indirect-jump instruction pattern(s).
9905 ;
9906
9907 (define_expand "indirect_jump"
9908 [(set (pc) (match_operand 0 "nonimmediate_operand" ""))]
9909 ""
9910 {
9911 if (address_operand (operands[0], GET_MODE (operands[0])))
9912 ;
9913 else if (TARGET_Z14
9914 && GET_MODE (operands[0]) == Pmode
9915 && memory_operand (operands[0], Pmode))
9916 ;
9917 else
9918 operands[0] = force_reg (Pmode, operands[0]);
9919
9920 if (TARGET_INDIRECT_BRANCH_NOBP_JUMP_THUNK)
9921 {
9922 operands[0] = force_reg (Pmode, operands[0]);
9923 if (TARGET_CPU_Z10)
9924 {
9925 if (TARGET_64BIT)
9926 emit_jump_insn (gen_indirect_jump_via_thunkdi_z10 (operands[0]));
9927 else
9928 emit_jump_insn (gen_indirect_jump_via_thunksi_z10 (operands[0]));
9929 }
9930 else
9931 {
9932 if (TARGET_64BIT)
9933 emit_jump_insn (gen_indirect_jump_via_thunkdi (operands[0]));
9934 else
9935 emit_jump_insn (gen_indirect_jump_via_thunksi (operands[0]));
9936 }
9937 DONE;
9938 }
9939
9940 if (TARGET_INDIRECT_BRANCH_NOBP_JUMP_INLINE_THUNK)
9941 {
9942 operands[0] = force_reg (Pmode, operands[0]);
9943 rtx label_ref = gen_rtx_LABEL_REF (VOIDmode, gen_label_rtx ());
9944 if (TARGET_CPU_Z10)
9945 {
9946 if (TARGET_64BIT)
9947 emit_jump_insn (gen_indirect_jump_via_inlinethunkdi_z10 (operands[0],
9948 label_ref));
9949 else
9950 emit_jump_insn (gen_indirect_jump_via_inlinethunksi_z10 (operands[0],
9951 label_ref));
9952 }
9953 else
9954 {
9955 if (TARGET_64BIT)
9956 emit_jump_insn (gen_indirect_jump_via_inlinethunkdi (operands[0],
9957 label_ref,
9958 force_reg (Pmode, label_ref)));
9959 else
9960 emit_jump_insn (gen_indirect_jump_via_inlinethunksi (operands[0],
9961 label_ref,
9962 force_reg (Pmode, label_ref)));
9963 }
9964 DONE;
9965 }
9966 })
9967
9968 (define_insn "*indirect_jump"
9969 [(set (pc)
9970 (match_operand 0 "address_operand" "ZR"))]
9971 "!TARGET_INDIRECT_BRANCH_NOBP_JUMP_THUNK"
9972 {
9973 if (get_attr_op_type (insn) == OP_TYPE_RR)
9974 return "br\t%0";
9975 else
9976 return "b\t%a0";
9977 }
9978 [(set (attr "op_type")
9979 (if_then_else (match_operand 0 "register_operand" "")
9980 (const_string "RR") (const_string "RX")))
9981 (set (attr "mnemonic")
9982 (if_then_else (match_operand 0 "register_operand" "")
9983 (const_string "br") (const_string "b")))
9984 (set_attr "type" "branch")
9985 (set_attr "atype" "agen")])
9986
9987 (define_insn "indirect_jump_via_thunk<mode>_z10"
9988 [(set (pc)
9989 (match_operand:P 0 "register_operand" "a"))]
9990 "TARGET_INDIRECT_BRANCH_NOBP_JUMP_THUNK
9991 && TARGET_CPU_Z10"
9992 {
9993 s390_indirect_branch_via_thunk (REGNO (operands[0]),
9994 INVALID_REGNUM,
9995 NULL_RTX,
9996 s390_indirect_branch_type_jump);
9997 return "";
9998 }
9999 [(set_attr "op_type" "RIL")
10000 (set_attr "mnemonic" "jg")
10001 (set_attr "type" "branch")
10002 (set_attr "atype" "agen")])
10003
10004 (define_insn "indirect_jump_via_thunk<mode>"
10005 [(set (pc)
10006 (match_operand:P 0 "register_operand" " a"))
10007 (clobber (reg:P INDIRECT_BRANCH_THUNK_REGNUM))]
10008 "TARGET_INDIRECT_BRANCH_NOBP_JUMP_THUNK
10009 && !TARGET_CPU_Z10"
10010 {
10011 s390_indirect_branch_via_thunk (REGNO (operands[0]),
10012 INVALID_REGNUM,
10013 NULL_RTX,
10014 s390_indirect_branch_type_jump);
10015 return "";
10016 }
10017 [(set_attr "op_type" "RIL")
10018 (set_attr "mnemonic" "jg")
10019 (set_attr "type" "branch")
10020 (set_attr "atype" "agen")])
10021
10022
10023 ; The label_ref is wrapped into an if_then_else in order to hide it
10024 ; from mark_jump_label. Without this the label_ref would become the
10025 ; ONLY jump target of that jump breaking the control flow graph.
10026 (define_insn "indirect_jump_via_inlinethunk<mode>_z10"
10027 [(unspec [(if_then_else (match_operand:P 1 "larl_operand" "X")
10028 (const_int 0)
10029 (const_int 0))
10030 (const_int 0)] UNSPEC_EXECUTE_JUMP)
10031 (set (pc) (match_operand:P 0 "register_operand" "a"))]
10032 "TARGET_INDIRECT_BRANCH_NOBP_JUMP_INLINE_THUNK
10033 && TARGET_CPU_Z10"
10034 {
10035 s390_indirect_branch_via_inline_thunk (operands[1]);
10036 return "";
10037 }
10038 [(set_attr "op_type" "RIL")
10039 (set_attr "type" "branch")
10040 (set_attr "length" "10")])
10041
10042 (define_insn "indirect_jump_via_inlinethunk<mode>"
10043 [(unspec [(if_then_else (match_operand:P 1 "larl_operand" "X")
10044 (const_int 0)
10045 (const_int 0))
10046 (match_operand:P 2 "register_operand" "a")] UNSPEC_EXECUTE_JUMP)
10047 (set (pc) (match_operand:P 0 "register_operand" "a"))]
10048 "TARGET_INDIRECT_BRANCH_NOBP_JUMP_INLINE_THUNK
10049 && !TARGET_CPU_Z10"
10050 {
10051 s390_indirect_branch_via_inline_thunk (operands[2]);
10052 return "";
10053 }
10054 [(set_attr "op_type" "RX")
10055 (set_attr "type" "branch")
10056 (set_attr "length" "8")])
10057
10058 ; FIXME: LRA does not appear to be able to deal with MEMs being
10059 ; checked against address constraints like ZR above. So make this a
10060 ; separate pattern for now.
10061 (define_insn "*indirect2_jump"
10062 [(set (pc)
10063 (match_operand 0 "nonimmediate_operand" "a,T"))]
10064 "!TARGET_INDIRECT_BRANCH_NOBP_JUMP"
10065 "@
10066 br\t%0
10067 bi\t%0"
10068 [(set_attr "op_type" "RR,RXY")
10069 (set_attr "type" "branch")
10070 (set_attr "atype" "agen")
10071 (set_attr "cpu_facility" "*,z14")])
10072
10073 ;
10074 ; casesi instruction pattern(s).
10075 ;
10076
10077 (define_expand "casesi_jump"
10078 [(parallel
10079 [(set (pc) (match_operand 0 "address_operand"))
10080 (use (label_ref (match_operand 1 "")))])]
10081 ""
10082 {
10083 if (TARGET_INDIRECT_BRANCH_NOBP_JUMP_THUNK)
10084 {
10085 operands[0] = force_reg (GET_MODE (operands[0]), operands[0]);
10086
10087 if (TARGET_CPU_Z10)
10088 {
10089 if (TARGET_64BIT)
10090 emit_jump_insn (gen_casesi_jump_via_thunkdi_z10 (operands[0],
10091 operands[1]));
10092 else
10093 emit_jump_insn (gen_casesi_jump_via_thunksi_z10 (operands[0],
10094 operands[1]));
10095 }
10096 else
10097 {
10098 if (TARGET_64BIT)
10099 emit_jump_insn (gen_casesi_jump_via_thunkdi (operands[0],
10100 operands[1]));
10101 else
10102 emit_jump_insn (gen_casesi_jump_via_thunksi (operands[0],
10103 operands[1]));
10104 }
10105 DONE;
10106 }
10107
10108 if (TARGET_INDIRECT_BRANCH_NOBP_JUMP_INLINE_THUNK)
10109 {
10110 operands[0] = force_reg (Pmode, operands[0]);
10111 rtx label_ref = gen_rtx_LABEL_REF (VOIDmode, gen_label_rtx ());
10112 if (TARGET_CPU_Z10)
10113 {
10114 if (TARGET_64BIT)
10115 emit_jump_insn (gen_casesi_jump_via_inlinethunkdi_z10 (operands[0],
10116 operands[1],
10117 label_ref));
10118 else
10119 emit_jump_insn (gen_casesi_jump_via_inlinethunksi_z10 (operands[0],
10120 operands[1],
10121 label_ref));
10122 }
10123 else
10124 {
10125 if (TARGET_64BIT)
10126 emit_jump_insn (gen_casesi_jump_via_inlinethunkdi (operands[0],
10127 operands[1],
10128 label_ref,
10129 force_reg (Pmode, label_ref)));
10130 else
10131 emit_jump_insn (gen_casesi_jump_via_inlinethunksi (operands[0],
10132 operands[1],
10133 label_ref,
10134 force_reg (Pmode, label_ref)));
10135 }
10136 DONE;
10137 }
10138 })
10139
10140 (define_insn "*casesi_jump"
10141 [(set (pc) (match_operand 0 "address_operand" "ZR"))
10142 (use (label_ref (match_operand 1 "" "")))]
10143 "!TARGET_INDIRECT_BRANCH_NOBP_JUMP_THUNK"
10144 {
10145 if (get_attr_op_type (insn) == OP_TYPE_RR)
10146 return "br\t%0";
10147 else
10148 return "b\t%a0";
10149 }
10150 [(set (attr "op_type")
10151 (if_then_else (match_operand 0 "register_operand" "")
10152 (const_string "RR") (const_string "RX")))
10153 (set (attr "mnemonic")
10154 (if_then_else (match_operand 0 "register_operand" "")
10155 (const_string "br") (const_string "b")))
10156 (set_attr "type" "branch")
10157 (set_attr "atype" "agen")])
10158
10159 (define_insn "casesi_jump_via_thunk<mode>_z10"
10160 [(set (pc) (match_operand:P 0 "register_operand" "a"))
10161 (use (label_ref (match_operand 1 "" "")))]
10162 "TARGET_INDIRECT_BRANCH_NOBP_JUMP_THUNK
10163 && TARGET_CPU_Z10"
10164 {
10165 s390_indirect_branch_via_thunk (REGNO (operands[0]),
10166 INVALID_REGNUM,
10167 NULL_RTX,
10168 s390_indirect_branch_type_jump);
10169 return "";
10170 }
10171 [(set_attr "op_type" "RIL")
10172 (set_attr "mnemonic" "jg")
10173 (set_attr "type" "branch")
10174 (set_attr "atype" "agen")])
10175
10176 (define_insn "casesi_jump_via_thunk<mode>"
10177 [(set (pc) (match_operand:P 0 "register_operand" "a"))
10178 (use (label_ref (match_operand 1 "" "")))
10179 (clobber (reg:P INDIRECT_BRANCH_THUNK_REGNUM))]
10180 "TARGET_INDIRECT_BRANCH_NOBP_JUMP_THUNK
10181 && !TARGET_CPU_Z10"
10182 {
10183 s390_indirect_branch_via_thunk (REGNO (operands[0]),
10184 INVALID_REGNUM,
10185 NULL_RTX,
10186 s390_indirect_branch_type_jump);
10187 return "";
10188 }
10189 [(set_attr "op_type" "RIL")
10190 (set_attr "mnemonic" "jg")
10191 (set_attr "type" "branch")
10192 (set_attr "atype" "agen")])
10193
10194
10195 ; The label_ref is wrapped into an if_then_else in order to hide it
10196 ; from mark_jump_label. Without this the label_ref would become the
10197 ; ONLY jump target of that jump breaking the control flow graph.
10198 (define_insn "casesi_jump_via_inlinethunk<mode>_z10"
10199 [(unspec [(if_then_else (match_operand:P 2 "larl_operand" "X")
10200 (const_int 0)
10201 (const_int 0))
10202 (const_int 0)] UNSPEC_EXECUTE_JUMP)
10203 (set (pc) (match_operand:P 0 "register_operand" "a"))
10204 (use (label_ref (match_operand 1 "" "")))]
10205 "TARGET_INDIRECT_BRANCH_NOBP_JUMP_INLINE_THUNK
10206 && TARGET_CPU_Z10"
10207 {
10208 s390_indirect_branch_via_inline_thunk (operands[2]);
10209 return "";
10210 }
10211 [(set_attr "op_type" "RIL")
10212 (set_attr "type" "cs")
10213 (set_attr "length" "10")])
10214
10215 (define_insn "casesi_jump_via_inlinethunk<mode>"
10216 [(unspec [(if_then_else (match_operand:P 2 "larl_operand" "X")
10217 (const_int 0)
10218 (const_int 0))
10219 (match_operand:P 3 "register_operand" "a")] UNSPEC_EXECUTE_JUMP)
10220 (set (pc) (match_operand:P 0 "register_operand" "a"))
10221 (use (label_ref (match_operand 1 "" "")))]
10222 "TARGET_INDIRECT_BRANCH_NOBP_JUMP_INLINE_THUNK
10223 && !TARGET_CPU_Z10"
10224 {
10225 s390_indirect_branch_via_inline_thunk (operands[3]);
10226 return "";
10227 }
10228 [(set_attr "op_type" "RX")
10229 (set_attr "type" "cs")
10230 (set_attr "length" "8")])
10231
10232 (define_expand "casesi"
10233 [(match_operand:SI 0 "general_operand" "")
10234 (match_operand:SI 1 "general_operand" "")
10235 (match_operand:SI 2 "general_operand" "")
10236 (label_ref (match_operand 3 "" ""))
10237 (label_ref (match_operand 4 "" ""))]
10238 ""
10239 {
10240 rtx index = gen_reg_rtx (SImode);
10241 rtx base = gen_reg_rtx (Pmode);
10242 rtx target = gen_reg_rtx (Pmode);
10243
10244 emit_move_insn (index, operands[0]);
10245 emit_insn (gen_subsi3 (index, index, operands[1]));
10246 emit_cmp_and_jump_insns (index, operands[2], GTU, NULL_RTX, SImode, 1,
10247 operands[4]);
10248
10249 if (Pmode != SImode)
10250 index = convert_to_mode (Pmode, index, 1);
10251 if (GET_CODE (index) != REG)
10252 index = copy_to_mode_reg (Pmode, index);
10253
10254 if (TARGET_64BIT)
10255 emit_insn (gen_ashldi3 (index, index, GEN_INT (3)));
10256 else
10257 emit_insn (gen_ashlsi3 (index, index, const2_rtx));
10258
10259 emit_move_insn (base, gen_rtx_LABEL_REF (Pmode, operands[3]));
10260
10261 index = gen_const_mem (Pmode, gen_rtx_PLUS (Pmode, base, index));
10262 emit_move_insn (target, index);
10263
10264 if (flag_pic)
10265 target = gen_rtx_PLUS (Pmode, base, target);
10266 emit_jump_insn (gen_casesi_jump (target, operands[3]));
10267
10268 DONE;
10269 })
10270
10271
10272 ;;
10273 ;;- Jump to subroutine.
10274 ;;
10275 ;;
10276
10277 ;
10278 ; untyped call instruction pattern(s).
10279 ;
10280
10281 ;; Call subroutine returning any type.
10282 (define_expand "untyped_call"
10283 [(parallel [(call (match_operand 0 "" "")
10284 (const_int 0))
10285 (match_operand 1 "" "")
10286 (match_operand 2 "" "")])]
10287 ""
10288 {
10289 int i;
10290
10291 emit_call_insn (gen_call (operands[0], const0_rtx, const0_rtx));
10292
10293 for (i = 0; i < XVECLEN (operands[2], 0); i++)
10294 {
10295 rtx set = XVECEXP (operands[2], 0, i);
10296 emit_move_insn (SET_DEST (set), SET_SRC (set));
10297 }
10298
10299 /* The optimizer does not know that the call sets the function value
10300 registers we stored in the result block. We avoid problems by
10301 claiming that all hard registers are used and clobbered at this
10302 point. */
10303 emit_insn (gen_blockage ());
10304
10305 DONE;
10306 })
10307
10308 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
10309 ;; all of memory. This blocks insns from being moved across this point.
10310
10311 (define_insn "blockage"
10312 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
10313 ""
10314 ""
10315 [(set_attr "type" "none")
10316 (set_attr "length" "0")])
10317
10318 ;
10319 ; sibcall patterns
10320 ;
10321
10322 (define_expand "sibcall"
10323 [(call (match_operand 0 "" "")
10324 (match_operand 1 "" ""))]
10325 ""
10326 {
10327 s390_emit_call (XEXP (operands[0], 0), NULL_RTX, NULL_RTX, NULL_RTX);
10328 DONE;
10329 })
10330
10331 (define_insn "*sibcall_br"
10332 [(call (mem:QI (reg SIBCALL_REGNUM))
10333 (match_operand 0 "const_int_operand" "n"))]
10334 "SIBLING_CALL_P (insn)
10335 && GET_MODE (XEXP (XEXP (PATTERN (insn), 0), 0)) == Pmode"
10336 {
10337 if (TARGET_INDIRECT_BRANCH_NOBP_CALL)
10338 {
10339 gcc_assert (TARGET_CPU_Z10);
10340 s390_indirect_branch_via_thunk (SIBCALL_REGNUM,
10341 INVALID_REGNUM,
10342 NULL_RTX,
10343 s390_indirect_branch_type_call);
10344 return "";
10345 }
10346 else
10347 return "br\t%%r1";
10348 }
10349 [(set (attr "op_type")
10350 (if_then_else (match_test "TARGET_INDIRECT_BRANCH_NOBP_CALL")
10351 (const_string "RIL")
10352 (const_string "RR")))
10353 (set (attr "mnemonic")
10354 (if_then_else (match_test "TARGET_INDIRECT_BRANCH_NOBP_CALL")
10355 (const_string "jg")
10356 (const_string "br")))
10357 (set_attr "type" "branch")
10358 (set_attr "atype" "agen")])
10359
10360 (define_insn "*sibcall_brc"
10361 [(call (mem:QI (match_operand 0 "bras_sym_operand" "X"))
10362 (match_operand 1 "const_int_operand" "n"))]
10363 "SIBLING_CALL_P (insn) && TARGET_SMALL_EXEC"
10364 "j\t%0"
10365 [(set_attr "op_type" "RI")
10366 (set_attr "type" "branch")])
10367
10368 (define_insn "*sibcall_brcl"
10369 [(call (mem:QI (match_operand 0 "bras_sym_operand" "X"))
10370 (match_operand 1 "const_int_operand" "n"))]
10371 "SIBLING_CALL_P (insn)"
10372 "jg\t%0"
10373 [(set_attr "op_type" "RIL")
10374 (set_attr "type" "branch")])
10375
10376 ;
10377 ; sibcall_value patterns
10378 ;
10379
10380 (define_expand "sibcall_value"
10381 [(set (match_operand 0 "" "")
10382 (call (match_operand 1 "" "")
10383 (match_operand 2 "" "")))]
10384 ""
10385 {
10386 s390_emit_call (XEXP (operands[1], 0), NULL_RTX, operands[0], NULL_RTX);
10387 DONE;
10388 })
10389
10390 (define_insn "*sibcall_value_br"
10391 [(set (match_operand 0 "" "")
10392 (call (mem:QI (reg SIBCALL_REGNUM))
10393 (match_operand 1 "const_int_operand" "n")))]
10394 "SIBLING_CALL_P (insn)
10395 && GET_MODE (XEXP (XEXP (XEXP (PATTERN (insn), 1), 0), 0)) == Pmode"
10396 {
10397 if (TARGET_INDIRECT_BRANCH_NOBP_CALL)
10398 {
10399 gcc_assert (TARGET_CPU_Z10);
10400 s390_indirect_branch_via_thunk (SIBCALL_REGNUM,
10401 INVALID_REGNUM,
10402 NULL_RTX,
10403 s390_indirect_branch_type_call);
10404 return "";
10405 }
10406 else
10407 return "br\t%%r1";
10408 }
10409 [(set (attr "op_type")
10410 (if_then_else (match_test "TARGET_INDIRECT_BRANCH_NOBP_CALL")
10411 (const_string "RIL")
10412 (const_string "RR")))
10413 (set (attr "mnemonic")
10414 (if_then_else (match_test "TARGET_INDIRECT_BRANCH_NOBP_CALL")
10415 (const_string "jg")
10416 (const_string "br")))
10417 (set_attr "type" "branch")
10418 (set_attr "atype" "agen")])
10419
10420 (define_insn "*sibcall_value_brc"
10421 [(set (match_operand 0 "" "")
10422 (call (mem:QI (match_operand 1 "bras_sym_operand" "X"))
10423 (match_operand 2 "const_int_operand" "n")))]
10424 "SIBLING_CALL_P (insn) && TARGET_SMALL_EXEC"
10425 "j\t%1"
10426 [(set_attr "op_type" "RI")
10427 (set_attr "type" "branch")])
10428
10429 (define_insn "*sibcall_value_brcl"
10430 [(set (match_operand 0 "" "")
10431 (call (mem:QI (match_operand 1 "bras_sym_operand" "X"))
10432 (match_operand 2 "const_int_operand" "n")))]
10433 "SIBLING_CALL_P (insn)"
10434 "jg\t%1"
10435 [(set_attr "op_type" "RIL")
10436 (set_attr "type" "branch")])
10437
10438
10439 ;
10440 ; call instruction pattern(s).
10441 ;
10442
10443 (define_expand "call"
10444 [(call (match_operand 0 "" "")
10445 (match_operand 1 "" ""))
10446 (use (match_operand 2 "" ""))]
10447 ""
10448 {
10449 s390_emit_call (XEXP (operands[0], 0), NULL_RTX, NULL_RTX,
10450 gen_rtx_REG (Pmode, RETURN_REGNUM));
10451 DONE;
10452 })
10453
10454 (define_insn "*bras"
10455 [(call (mem:QI (match_operand 0 "bras_sym_operand" "X"))
10456 (match_operand 1 "const_int_operand" "n"))
10457 (clobber (match_operand 2 "register_operand" "=r"))]
10458 "!SIBLING_CALL_P (insn)
10459 && TARGET_SMALL_EXEC
10460 && GET_MODE (operands[2]) == Pmode"
10461 "bras\t%2,%0"
10462 [(set_attr "op_type" "RI")
10463 (set_attr "type" "jsr")
10464 (set_attr "z196prop" "z196_cracked")])
10465
10466 (define_insn "*brasl"
10467 [(call (mem:QI (match_operand 0 "bras_sym_operand" "X"))
10468 (match_operand 1 "const_int_operand" "n"))
10469 (clobber (match_operand 2 "register_operand" "=r"))]
10470 "!SIBLING_CALL_P (insn)
10471
10472 && GET_MODE (operands[2]) == Pmode"
10473 "brasl\t%2,%0"
10474 [(set_attr "op_type" "RIL")
10475 (set_attr "type" "jsr")
10476 (set_attr "z196prop" "z196_cracked")
10477 (set_attr "relative_long" "yes")])
10478
10479 (define_insn "*basr"
10480 [(call (mem:QI (match_operand 0 "address_operand" "ZR"))
10481 (match_operand 1 "const_int_operand" "n"))
10482 (clobber (match_operand 2 "register_operand" "=r"))]
10483 "!TARGET_INDIRECT_BRANCH_NOBP_CALL
10484 && !SIBLING_CALL_P (insn)
10485 && GET_MODE (operands[2]) == Pmode"
10486 {
10487 if (get_attr_op_type (insn) == OP_TYPE_RR)
10488 return "basr\t%2,%0";
10489 else
10490 return "bas\t%2,%a0";
10491 }
10492 [(set (attr "op_type")
10493 (if_then_else (match_operand 0 "register_operand" "")
10494 (const_string "RR") (const_string "RX")))
10495 (set (attr "mnemonic")
10496 (if_then_else (match_operand 0 "register_operand" "")
10497 (const_string "basr") (const_string "bas")))
10498 (set_attr "type" "jsr")
10499 (set_attr "atype" "agen")
10500 (set_attr "z196prop" "z196_cracked")])
10501
10502 (define_insn "*basr_via_thunk<mode>_z10"
10503 [(call (mem:QI (match_operand:P 0 "register_operand" "a"))
10504 (match_operand 1 "const_int_operand" "n"))
10505 (clobber (match_operand:P 2 "register_operand" "=&r"))]
10506 "TARGET_INDIRECT_BRANCH_NOBP_CALL
10507 && TARGET_CPU_Z10
10508 && !SIBLING_CALL_P (insn)"
10509 {
10510 s390_indirect_branch_via_thunk (REGNO (operands[0]),
10511 REGNO (operands[2]),
10512 NULL_RTX,
10513 s390_indirect_branch_type_call);
10514 return "";
10515 }
10516 [(set_attr "op_type" "RIL")
10517 (set_attr "mnemonic" "brasl")
10518 (set_attr "type" "jsr")
10519 (set_attr "atype" "agen")
10520 (set_attr "z196prop" "z196_cracked")])
10521
10522 (define_insn "*basr_via_thunk<mode>"
10523 [(call (mem:QI (match_operand:P 0 "register_operand" "a"))
10524 (match_operand 1 "const_int_operand" "n"))
10525 (clobber (match_operand:P 2 "register_operand" "=&r"))
10526 (clobber (reg:P INDIRECT_BRANCH_THUNK_REGNUM))]
10527 "TARGET_INDIRECT_BRANCH_NOBP_CALL
10528 && !TARGET_CPU_Z10
10529 && !SIBLING_CALL_P (insn)"
10530 {
10531 s390_indirect_branch_via_thunk (REGNO (operands[0]),
10532 REGNO (operands[2]),
10533 NULL_RTX,
10534 s390_indirect_branch_type_call);
10535 return "";
10536 }
10537 [(set_attr "op_type" "RIL")
10538 (set_attr "mnemonic" "brasl")
10539 (set_attr "type" "jsr")
10540 (set_attr "atype" "agen")
10541 (set_attr "z196prop" "z196_cracked")])
10542
10543 ;
10544 ; call_value instruction pattern(s).
10545 ;
10546
10547 (define_expand "call_value"
10548 [(set (match_operand 0 "" "")
10549 (call (match_operand 1 "" "")
10550 (match_operand 2 "" "")))
10551 (use (match_operand 3 "" ""))]
10552 ""
10553 {
10554 s390_emit_call (XEXP (operands[1], 0), NULL_RTX, operands[0],
10555 gen_rtx_REG (Pmode, RETURN_REGNUM));
10556 DONE;
10557 })
10558
10559 (define_insn "*bras_r"
10560 [(set (match_operand 0 "" "")
10561 (call (mem:QI (match_operand 1 "bras_sym_operand" "X"))
10562 (match_operand:SI 2 "const_int_operand" "n")))
10563 (clobber (match_operand 3 "register_operand" "=r"))]
10564 "!SIBLING_CALL_P (insn)
10565 && TARGET_SMALL_EXEC
10566 && GET_MODE (operands[3]) == Pmode"
10567 "bras\t%3,%1"
10568 [(set_attr "op_type" "RI")
10569 (set_attr "type" "jsr")
10570 (set_attr "z196prop" "z196_cracked")])
10571
10572 (define_insn "*brasl_r"
10573 [(set (match_operand 0 "" "")
10574 (call (mem:QI (match_operand 1 "bras_sym_operand" "X"))
10575 (match_operand 2 "const_int_operand" "n")))
10576 (clobber (match_operand 3 "register_operand" "=r"))]
10577 "!SIBLING_CALL_P (insn)
10578
10579 && GET_MODE (operands[3]) == Pmode"
10580 "brasl\t%3,%1"
10581 [(set_attr "op_type" "RIL")
10582 (set_attr "type" "jsr")
10583 (set_attr "z196prop" "z196_cracked")
10584 (set_attr "relative_long" "yes")])
10585
10586 (define_insn "*basr_r"
10587 [(set (match_operand 0 "" "")
10588 (call (mem:QI (match_operand 1 "address_operand" "ZR"))
10589 (match_operand 2 "const_int_operand" "n")))
10590 (clobber (match_operand 3 "register_operand" "=r"))]
10591 "!TARGET_INDIRECT_BRANCH_NOBP_CALL
10592 && !SIBLING_CALL_P (insn)
10593 && GET_MODE (operands[3]) == Pmode"
10594 {
10595 if (get_attr_op_type (insn) == OP_TYPE_RR)
10596 return "basr\t%3,%1";
10597 else
10598 return "bas\t%3,%a1";
10599 }
10600 [(set (attr "op_type")
10601 (if_then_else (match_operand 1 "register_operand" "")
10602 (const_string "RR") (const_string "RX")))
10603 (set (attr "mnemonic")
10604 (if_then_else (match_operand 1 "register_operand" "")
10605 (const_string "basr") (const_string "bas")))
10606 (set_attr "type" "jsr")
10607 (set_attr "atype" "agen")
10608 (set_attr "z196prop" "z196_cracked")])
10609
10610 (define_insn "*basr_r_via_thunk_z10"
10611 [(set (match_operand 0 "" "")
10612 (call (mem:QI (match_operand 1 "register_operand" "a"))
10613 (match_operand 2 "const_int_operand" "n")))
10614 (clobber (match_operand 3 "register_operand" "=&r"))]
10615 "TARGET_INDIRECT_BRANCH_NOBP_CALL
10616 && TARGET_CPU_Z10
10617 && !SIBLING_CALL_P (insn)
10618 && GET_MODE (operands[3]) == Pmode"
10619 {
10620 s390_indirect_branch_via_thunk (REGNO (operands[1]),
10621 REGNO (operands[3]),
10622 NULL_RTX,
10623 s390_indirect_branch_type_call);
10624 return "";
10625 }
10626 [(set_attr "op_type" "RIL")
10627 (set_attr "mnemonic" "brasl")
10628 (set_attr "type" "jsr")
10629 (set_attr "atype" "agen")
10630 (set_attr "z196prop" "z196_cracked")])
10631
10632 (define_insn "*basr_r_via_thunk"
10633 [(set (match_operand 0 "" "")
10634 (call (mem:QI (match_operand 1 "register_operand" "a"))
10635 (match_operand 2 "const_int_operand" "n")))
10636 (clobber (match_operand 3 "register_operand" "=&r"))
10637 (clobber (reg:P INDIRECT_BRANCH_THUNK_REGNUM))]
10638 "TARGET_INDIRECT_BRANCH_NOBP_CALL
10639 && !TARGET_CPU_Z10
10640 && !SIBLING_CALL_P (insn)
10641 && GET_MODE (operands[3]) == Pmode"
10642 {
10643 s390_indirect_branch_via_thunk (REGNO (operands[1]),
10644 REGNO (operands[3]),
10645 NULL_RTX,
10646 s390_indirect_branch_type_call);
10647 return "";
10648 }
10649 [(set_attr "op_type" "RIL")
10650 (set_attr "mnemonic" "brasl")
10651 (set_attr "type" "jsr")
10652 (set_attr "atype" "agen")
10653 (set_attr "z196prop" "z196_cracked")])
10654
10655 ;;
10656 ;;- Thread-local storage support.
10657 ;;
10658
10659 (define_expand "@get_thread_pointer<mode>"
10660 [(set (match_operand:P 0 "nonimmediate_operand" "")
10661 (unspec:P [(reg:P TP_REGNUM)] UNSPEC_GET_TP))]
10662 ""
10663 "")
10664
10665 (define_expand "set_thread_pointer<mode>"
10666 [(set (reg:P TP_REGNUM) (match_operand:P 0 "nonimmediate_operand" ""))
10667 (set (reg:P TP_REGNUM) (unspec_volatile:P [(reg:P TP_REGNUM)] UNSPECV_SET_TP))]
10668 ""
10669 "")
10670
10671 (define_insn "*set_tp"
10672 [(set (reg TP_REGNUM) (unspec_volatile [(reg TP_REGNUM)] UNSPECV_SET_TP))]
10673 ""
10674 ""
10675 [(set_attr "type" "none")
10676 (set_attr "length" "0")])
10677
10678 (define_insn "*tls_load_64"
10679 [(set (match_operand:DI 0 "register_operand" "=d")
10680 (unspec:DI [(match_operand:DI 1 "memory_operand" "T")
10681 (match_operand:DI 2 "" "")]
10682 UNSPEC_TLS_LOAD))]
10683 "TARGET_64BIT"
10684 "lg\t%0,%1%J2"
10685 [(set_attr "op_type" "RXE")
10686 (set_attr "z10prop" "z10_fwd_A3")])
10687
10688 (define_insn "*tls_load_31"
10689 [(set (match_operand:SI 0 "register_operand" "=d,d")
10690 (unspec:SI [(match_operand:SI 1 "memory_operand" "R,T")
10691 (match_operand:SI 2 "" "")]
10692 UNSPEC_TLS_LOAD))]
10693 "!TARGET_64BIT"
10694 "@
10695 l\t%0,%1%J2
10696 ly\t%0,%1%J2"
10697 [(set_attr "op_type" "RX,RXY")
10698 (set_attr "type" "load")
10699 (set_attr "cpu_facility" "*,longdisp")
10700 (set_attr "z10prop" "z10_fwd_A3,z10_fwd_A3")])
10701
10702 (define_insn "*bras_tls"
10703 [(set (match_operand 0 "" "")
10704 (call (mem:QI (match_operand 1 "bras_sym_operand" "X"))
10705 (match_operand 2 "const_int_operand" "n")))
10706 (clobber (match_operand 3 "register_operand" "=r"))
10707 (use (match_operand 4 "" ""))]
10708 "!SIBLING_CALL_P (insn)
10709 && TARGET_SMALL_EXEC
10710 && GET_MODE (operands[3]) == Pmode"
10711 "bras\t%3,%1%J4"
10712 [(set_attr "op_type" "RI")
10713 (set_attr "type" "jsr")
10714 (set_attr "z196prop" "z196_cracked")])
10715
10716 (define_insn "*brasl_tls"
10717 [(set (match_operand 0 "" "")
10718 (call (mem:QI (match_operand 1 "bras_sym_operand" "X"))
10719 (match_operand 2 "const_int_operand" "n")))
10720 (clobber (match_operand 3 "register_operand" "=r"))
10721 (use (match_operand 4 "" ""))]
10722 "!SIBLING_CALL_P (insn)
10723
10724 && GET_MODE (operands[3]) == Pmode"
10725 "brasl\t%3,%1%J4"
10726 [(set_attr "op_type" "RIL")
10727 (set_attr "type" "jsr")
10728 (set_attr "z196prop" "z196_cracked")
10729 (set_attr "relative_long" "yes")])
10730
10731 (define_insn "*basr_tls"
10732 [(set (match_operand 0 "" "")
10733 (call (mem:QI (match_operand 1 "address_operand" "ZR"))
10734 (match_operand 2 "const_int_operand" "n")))
10735 (clobber (match_operand 3 "register_operand" "=r"))
10736 (use (match_operand 4 "" ""))]
10737 "!SIBLING_CALL_P (insn) && GET_MODE (operands[3]) == Pmode"
10738 {
10739 if (get_attr_op_type (insn) == OP_TYPE_RR)
10740 return "basr\t%3,%1%J4";
10741 else
10742 return "bas\t%3,%a1%J4";
10743 }
10744 [(set (attr "op_type")
10745 (if_then_else (match_operand 1 "register_operand" "")
10746 (const_string "RR") (const_string "RX")))
10747 (set_attr "type" "jsr")
10748 (set_attr "atype" "agen")
10749 (set_attr "z196prop" "z196_cracked")])
10750
10751 ;;
10752 ;;- Atomic operations
10753 ;;
10754
10755 ;
10756 ; memory barrier patterns.
10757 ;
10758
10759 (define_expand "mem_thread_fence"
10760 [(match_operand:SI 0 "const_int_operand")] ;; model
10761 ""
10762 {
10763 /* Unless this is a SEQ_CST fence, the s390 memory model is strong
10764 enough not to require barriers of any kind. */
10765 if (is_mm_seq_cst (memmodel_from_int (INTVAL (operands[0]))))
10766 {
10767 rtx mem = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
10768 MEM_VOLATILE_P (mem) = 1;
10769 emit_insn (gen_mem_thread_fence_1 (mem));
10770 }
10771 DONE;
10772 })
10773
10774 ; Although bcr is superscalar on Z10, this variant will never
10775 ; become part of an execution group.
10776 ; With z196 we can make use of the fast-BCR-serialization facility.
10777 ; This allows for a slightly faster sync which is sufficient for our
10778 ; purposes.
10779 (define_insn "mem_thread_fence_1"
10780 [(set (match_operand:BLK 0 "" "")
10781 (unspec:BLK [(match_dup 0)] UNSPEC_MB))]
10782 ""
10783 {
10784 if (TARGET_Z196)
10785 return "bcr\t14,0";
10786 else
10787 return "bcr\t15,0";
10788 }
10789 [(set_attr "op_type" "RR")
10790 (set_attr "mnemonic" "bcr_flush")
10791 (set_attr "z196prop" "z196_alone")])
10792
10793 ;
10794 ; atomic load/store operations
10795 ;
10796
10797 ; Atomic loads need not examine the memory model at all.
10798 (define_expand "atomic_load<mode>"
10799 [(match_operand:DINT 0 "register_operand") ;; output
10800 (match_operand:DINT 1 "memory_operand") ;; memory
10801 (match_operand:SI 2 "const_int_operand")] ;; model
10802 ""
10803 {
10804 if (MEM_ALIGN (operands[1]) < GET_MODE_BITSIZE (GET_MODE (operands[1])))
10805 FAIL;
10806
10807 if (<MODE>mode == TImode)
10808 emit_insn (gen_atomic_loadti_1 (operands[0], operands[1]));
10809 else if (<MODE>mode == DImode && !TARGET_ZARCH)
10810 emit_insn (gen_atomic_loaddi_1 (operands[0], operands[1]));
10811 else
10812 emit_move_insn (operands[0], operands[1]);
10813 DONE;
10814 })
10815
10816 ; Different from movdi_31 in that we want no splitters.
10817 (define_insn "atomic_loaddi_1"
10818 [(set (match_operand:DI 0 "register_operand" "=d,d,!*f,!*f")
10819 (unspec:DI [(match_operand:DI 1 "memory_operand" "Q,S,R,T")]
10820 UNSPEC_MOVA))]
10821 "!TARGET_ZARCH"
10822 "@
10823 lm\t%0,%M0,%S1
10824 lmy\t%0,%M0,%S1
10825 ld\t%0,%1
10826 ldy\t%0,%1"
10827 [(set_attr "op_type" "RS,RSY,RS,RSY")
10828 (set_attr "cpu_facility" "*,longdisp,*,longdisp")
10829 (set_attr "type" "lm,lm,floaddf,floaddf")])
10830
10831 (define_insn "atomic_loadti_1"
10832 [(set (match_operand:TI 0 "register_operand" "=r")
10833 (unspec:TI [(match_operand:TI 1 "memory_operand" "T")]
10834 UNSPEC_MOVA))]
10835 "TARGET_ZARCH"
10836 "lpq\t%0,%1"
10837 [(set_attr "op_type" "RXY")
10838 (set_attr "type" "other")])
10839
10840 ; Atomic stores must(?) enforce sequential consistency.
10841 (define_expand "atomic_store<mode>"
10842 [(match_operand:DINT 0 "memory_operand") ;; memory
10843 (match_operand:DINT 1 "register_operand") ;; input
10844 (match_operand:SI 2 "const_int_operand")] ;; model
10845 ""
10846 {
10847 enum memmodel model = memmodel_from_int (INTVAL (operands[2]));
10848
10849 if (MEM_ALIGN (operands[0]) < GET_MODE_BITSIZE (GET_MODE (operands[0])))
10850 FAIL;
10851
10852 if (<MODE>mode == TImode)
10853 emit_insn (gen_atomic_storeti_1 (operands[0], operands[1]));
10854 else if (<MODE>mode == DImode && !TARGET_ZARCH)
10855 emit_insn (gen_atomic_storedi_1 (operands[0], operands[1]));
10856 else
10857 emit_move_insn (operands[0], operands[1]);
10858 if (is_mm_seq_cst (model))
10859 emit_insn (gen_mem_thread_fence (operands[2]));
10860 DONE;
10861 })
10862
10863 ; Different from movdi_31 in that we want no splitters.
10864 (define_insn "atomic_storedi_1"
10865 [(set (match_operand:DI 0 "memory_operand" "=Q,S,R,T")
10866 (unspec:DI [(match_operand:DI 1 "register_operand" "d,d,!*f,!*f")]
10867 UNSPEC_MOVA))]
10868 "!TARGET_ZARCH"
10869 "@
10870 stm\t%1,%N1,%S0
10871 stmy\t%1,%N1,%S0
10872 std %1,%0
10873 stdy %1,%0"
10874 [(set_attr "op_type" "RS,RSY,RS,RSY")
10875 (set_attr "cpu_facility" "*,longdisp,*,longdisp")
10876 (set_attr "type" "stm,stm,fstoredf,fstoredf")])
10877
10878 (define_insn "atomic_storeti_1"
10879 [(set (match_operand:TI 0 "memory_operand" "=T")
10880 (unspec:TI [(match_operand:TI 1 "register_operand" "r")]
10881 UNSPEC_MOVA))]
10882 "TARGET_ZARCH"
10883 "stpq\t%1,%0"
10884 [(set_attr "op_type" "RXY")
10885 (set_attr "type" "other")])
10886
10887 ;
10888 ; compare and swap patterns.
10889 ;
10890
10891 (define_expand "atomic_compare_and_swap<mode>"
10892 [(match_operand:SI 0 "register_operand") ;; bool success output
10893 (match_operand:DINT 1 "nonimmediate_operand");; oldval output
10894 (match_operand:DINT 2 "s_operand") ;; memory
10895 (match_operand:DINT 3 "general_operand") ;; expected intput
10896 (match_operand:DINT 4 "general_operand") ;; newval intput
10897 (match_operand:SI 5 "const_int_operand") ;; is_weak
10898 (match_operand:SI 6 "const_int_operand") ;; success model
10899 (match_operand:SI 7 "const_int_operand")] ;; failure model
10900 ""
10901 {
10902 if (GET_MODE_BITSIZE (<MODE>mode) >= 16
10903 && GET_MODE_BITSIZE (<MODE>mode) > MEM_ALIGN (operands[2]))
10904 FAIL;
10905
10906 s390_expand_cs (<MODE>mode, operands[0], operands[1], operands[2],
10907 operands[3], operands[4], INTVAL (operands[5]));
10908 DONE;})
10909
10910 (define_expand "atomic_compare_and_swap<mode>_internal"
10911 [(parallel
10912 [(set (match_operand:DGPR 0 "register_operand")
10913 (match_operand:DGPR 1 "s_operand"))
10914 (set (match_dup 1)
10915 (unspec_volatile:DGPR
10916 [(match_dup 1)
10917 (match_operand:DGPR 2 "register_operand")
10918 (match_operand:DGPR 3 "register_operand")]
10919 UNSPECV_CAS))
10920 (set (match_operand 4 "cc_reg_operand")
10921 (match_dup 5))])]
10922 "GET_MODE (operands[4]) == CCZmode
10923 || GET_MODE (operands[4]) == CCZ1mode"
10924 {
10925 operands[5]
10926 = gen_rtx_COMPARE (GET_MODE (operands[4]), operands[1], operands[2]);
10927 })
10928
10929 ; cdsg, csg
10930 (define_insn "*atomic_compare_and_swap<mode>_1"
10931 [(set (match_operand:TDI 0 "register_operand" "=r")
10932 (match_operand:TDI 1 "nonsym_memory_operand" "+S"))
10933 (set (match_dup 1)
10934 (unspec_volatile:TDI
10935 [(match_dup 1)
10936 (match_operand:TDI 2 "register_operand" "0")
10937 (match_operand:TDI 3 "register_operand" "r")]
10938 UNSPECV_CAS))
10939 (set (reg CC_REGNUM)
10940 (compare (match_dup 1) (match_dup 2)))]
10941 "TARGET_ZARCH
10942 && s390_match_ccmode (insn, CCZ1mode)"
10943 "c<td>sg\t%0,%3,%S1"
10944 [(set_attr "op_type" "RSY")
10945 (set_attr "type" "sem")])
10946
10947 ; cds, cdsy
10948 (define_insn "*atomic_compare_and_swapdi_2"
10949 [(set (match_operand:DI 0 "register_operand" "=r,r")
10950 (match_operand:DI 1 "nonsym_memory_operand" "+Q,S"))
10951 (set (match_dup 1)
10952 (unspec_volatile:DI
10953 [(match_dup 1)
10954 (match_operand:DI 2 "register_operand" "0,0")
10955 (match_operand:DI 3 "register_operand" "r,r")]
10956 UNSPECV_CAS))
10957 (set (reg CC_REGNUM)
10958 (compare (match_dup 1) (match_dup 2)))]
10959 "!TARGET_ZARCH
10960 && s390_match_ccmode (insn, CCZ1mode)"
10961 "@
10962 cds\t%0,%3,%S1
10963 cdsy\t%0,%3,%S1"
10964 [(set_attr "op_type" "RS,RSY")
10965 (set_attr "cpu_facility" "*,longdisp")
10966 (set_attr "type" "sem")])
10967
10968 ; cs, csy
10969 (define_insn "*atomic_compare_and_swapsi_3"
10970 [(set (match_operand:SI 0 "register_operand" "=r,r")
10971 (match_operand:SI 1 "nonsym_memory_operand" "+Q,S"))
10972 (set (match_dup 1)
10973 (unspec_volatile:SI
10974 [(match_dup 1)
10975 (match_operand:SI 2 "register_operand" "0,0")
10976 (match_operand:SI 3 "register_operand" "r,r")]
10977 UNSPECV_CAS))
10978 (set (reg CC_REGNUM)
10979 (compare (match_dup 1) (match_dup 2)))]
10980 "s390_match_ccmode (insn, CCZ1mode)"
10981 "@
10982 cs\t%0,%3,%S1
10983 csy\t%0,%3,%S1"
10984 [(set_attr "op_type" "RS,RSY")
10985 (set_attr "cpu_facility" "*,longdisp")
10986 (set_attr "type" "sem")])
10987
10988 ;
10989 ; Other atomic instruction patterns.
10990 ;
10991
10992 ; z196 load and add, xor, or and and instructions
10993
10994 (define_expand "atomic_fetch_<atomic><mode>"
10995 [(match_operand:GPR 0 "register_operand") ;; val out
10996 (ATOMIC_Z196:GPR
10997 (match_operand:GPR 1 "memory_operand") ;; memory
10998 (match_operand:GPR 2 "register_operand")) ;; val in
10999 (match_operand:SI 3 "const_int_operand")] ;; model
11000 "TARGET_Z196"
11001 {
11002 if (MEM_ALIGN (operands[1]) < GET_MODE_BITSIZE (GET_MODE (operands[1])))
11003 FAIL;
11004
11005 emit_insn (gen_atomic_fetch_<atomic><mode>_iaf
11006 (operands[0], operands[1], operands[2]));
11007 DONE;
11008 })
11009
11010 ; lan, lang, lao, laog, lax, laxg, laa, laag
11011 (define_insn "atomic_fetch_<atomic><mode>_iaf"
11012 [(set (match_operand:GPR 0 "register_operand" "=d")
11013 (match_operand:GPR 1 "memory_operand" "+S"))
11014 (set (match_dup 1)
11015 (unspec_volatile:GPR
11016 [(ATOMIC_Z196:GPR (match_dup 1)
11017 (match_operand:GPR 2 "general_operand" "d"))]
11018 UNSPECV_ATOMIC_OP))
11019 (clobber (reg:CC CC_REGNUM))]
11020 "TARGET_Z196"
11021 "la<noxa><g>\t%0,%2,%1"
11022 [(set_attr "op_type" "RSY")
11023 (set_attr "type" "sem")])
11024
11025 ;; For SImode and larger, the optabs.c code will do just fine in
11026 ;; expanding a compare-and-swap loop. For QI/HImode, we can do
11027 ;; better by expanding our own loop.
11028
11029 (define_expand "atomic_<atomic><mode>"
11030 [(ATOMIC:HQI
11031 (match_operand:HQI 0 "memory_operand") ;; memory
11032 (match_operand:HQI 1 "general_operand")) ;; val in
11033 (match_operand:SI 2 "const_int_operand")] ;; model
11034 ""
11035 {
11036 s390_expand_atomic (<MODE>mode, <CODE>, NULL_RTX, operands[0],
11037 operands[1], false);
11038 DONE;
11039 })
11040
11041 (define_expand "atomic_fetch_<atomic><mode>"
11042 [(match_operand:HQI 0 "register_operand") ;; val out
11043 (ATOMIC:HQI
11044 (match_operand:HQI 1 "memory_operand") ;; memory
11045 (match_operand:HQI 2 "general_operand")) ;; val in
11046 (match_operand:SI 3 "const_int_operand")] ;; model
11047 ""
11048 {
11049 s390_expand_atomic (<MODE>mode, <CODE>, operands[0], operands[1],
11050 operands[2], false);
11051 DONE;
11052 })
11053
11054 (define_expand "atomic_<atomic>_fetch<mode>"
11055 [(match_operand:HQI 0 "register_operand") ;; val out
11056 (ATOMIC:HQI
11057 (match_operand:HQI 1 "memory_operand") ;; memory
11058 (match_operand:HQI 2 "general_operand")) ;; val in
11059 (match_operand:SI 3 "const_int_operand")] ;; model
11060 ""
11061 {
11062 s390_expand_atomic (<MODE>mode, <CODE>, operands[0], operands[1],
11063 operands[2], true);
11064 DONE;
11065 })
11066
11067 ;; Pattern to implement atomic_exchange with a compare-and-swap loop. The code
11068 ;; generated by the middleend is not good.
11069 (define_expand "atomic_exchange<mode>"
11070 [(match_operand:DINT 0 "register_operand") ;; val out
11071 (match_operand:DINT 1 "s_operand") ;; memory
11072 (match_operand:DINT 2 "general_operand") ;; val in
11073 (match_operand:SI 3 "const_int_operand")] ;; model
11074 ""
11075 {
11076 if (<MODE>mode != QImode
11077 && MEM_ALIGN (operands[1]) < GET_MODE_BITSIZE (<MODE>mode))
11078 FAIL;
11079 if (<MODE>mode == HImode || <MODE>mode == QImode)
11080 s390_expand_atomic (<MODE>mode, SET, operands[0], operands[1], operands[2],
11081 false);
11082 else if (<MODE>mode == SImode || TARGET_ZARCH)
11083 s390_expand_atomic_exchange_tdsi (operands[0], operands[1], operands[2]);
11084 else
11085 FAIL;
11086 DONE;
11087 })
11088
11089 ;;
11090 ;;- Miscellaneous instructions.
11091 ;;
11092
11093 ;
11094 ; allocate stack instruction pattern(s).
11095 ;
11096
11097 (define_expand "allocate_stack"
11098 [(match_operand 0 "general_operand" "")
11099 (match_operand 1 "general_operand" "")]
11100 "TARGET_BACKCHAIN"
11101 {
11102 rtx temp = gen_reg_rtx (Pmode);
11103
11104 emit_move_insn (temp, s390_back_chain_rtx ());
11105
11106 if (flag_stack_clash_protection)
11107 anti_adjust_stack_and_probe_stack_clash (operands[1]);
11108 else
11109 anti_adjust_stack (operands[1]);
11110
11111 emit_move_insn (s390_back_chain_rtx (), temp);
11112
11113 emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
11114 DONE;
11115 })
11116
11117 (define_expand "@probe_stack2<mode>"
11118 [(set (reg:CCZ CC_REGNUM)
11119 (compare:CCZ (reg:W 0)
11120 (match_operand:W 0 "memory_operand")))
11121 (unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
11122 "")
11123
11124 (define_expand "probe_stack"
11125 [(match_operand 0 "memory_operand")]
11126 ""
11127 {
11128 emit_insn (gen_probe_stack2 (word_mode, operands[0]));
11129 DONE;
11130 })
11131
11132 ;
11133 ; setjmp instruction pattern.
11134 ;
11135
11136 (define_expand "builtin_setjmp_receiver"
11137 [(match_operand 0 "" "")]
11138 "flag_pic"
11139 {
11140 emit_insn (s390_load_got ());
11141 emit_use (pic_offset_table_rtx);
11142 DONE;
11143 })
11144
11145 ;; These patterns say how to save and restore the stack pointer. We need not
11146 ;; save the stack pointer at function level since we are careful to
11147 ;; preserve the backchain. At block level, we have to restore the backchain
11148 ;; when we restore the stack pointer.
11149 ;;
11150 ;; For nonlocal gotos, we must save both the stack pointer and its
11151 ;; backchain and restore both. Note that in the nonlocal case, the
11152 ;; save area is a memory location.
11153
11154 (define_expand "save_stack_function"
11155 [(match_operand 0 "general_operand" "")
11156 (match_operand 1 "general_operand" "")]
11157 ""
11158 "DONE;")
11159
11160 (define_expand "restore_stack_function"
11161 [(match_operand 0 "general_operand" "")
11162 (match_operand 1 "general_operand" "")]
11163 ""
11164 "DONE;")
11165
11166 (define_expand "restore_stack_block"
11167 [(match_operand 0 "register_operand" "")
11168 (match_operand 1 "register_operand" "")]
11169 "TARGET_BACKCHAIN"
11170 {
11171 rtx temp = gen_reg_rtx (Pmode);
11172
11173 emit_move_insn (temp, s390_back_chain_rtx ());
11174 emit_move_insn (operands[0], operands[1]);
11175 emit_move_insn (s390_back_chain_rtx (), temp);
11176
11177 DONE;
11178 })
11179
11180 (define_expand "save_stack_nonlocal"
11181 [(match_operand 0 "memory_operand" "")
11182 (match_operand 1 "register_operand" "")]
11183 ""
11184 {
11185 rtx base = gen_rtx_REG (Pmode, BASE_REGNUM);
11186
11187 /* Copy the backchain to the first word, sp to the second and the
11188 literal pool base to the third. */
11189
11190 rtx save_bc = adjust_address (operands[0], Pmode, 0);
11191 rtx save_sp = adjust_address (operands[0], Pmode, GET_MODE_SIZE (Pmode));
11192 rtx save_bp = adjust_address (operands[0], Pmode, 2 * GET_MODE_SIZE (Pmode));
11193
11194 if (TARGET_BACKCHAIN)
11195 emit_move_insn (save_bc, force_reg (Pmode, s390_back_chain_rtx ()));
11196
11197 emit_move_insn (save_sp, operands[1]);
11198 emit_move_insn (save_bp, base);
11199
11200 DONE;
11201 })
11202
11203 (define_expand "restore_stack_nonlocal"
11204 [(match_operand 0 "register_operand" "")
11205 (match_operand 1 "memory_operand" "")]
11206 ""
11207 {
11208 rtx base = gen_rtx_REG (Pmode, BASE_REGNUM);
11209 rtx temp = NULL_RTX;
11210
11211 /* Restore the backchain from the first word, sp from the second and the
11212 literal pool base from the third. */
11213
11214 rtx save_bc = adjust_address (operands[1], Pmode, 0);
11215 rtx save_sp = adjust_address (operands[1], Pmode, GET_MODE_SIZE (Pmode));
11216 rtx save_bp = adjust_address (operands[1], Pmode, 2 * GET_MODE_SIZE (Pmode));
11217
11218 if (TARGET_BACKCHAIN)
11219 temp = force_reg (Pmode, save_bc);
11220
11221 emit_move_insn (base, save_bp);
11222 emit_move_insn (operands[0], save_sp);
11223
11224 if (temp)
11225 emit_move_insn (s390_back_chain_rtx (), temp);
11226
11227 emit_use (base);
11228 DONE;
11229 })
11230
11231 (define_expand "exception_receiver"
11232 [(const_int 0)]
11233 ""
11234 {
11235 s390_set_has_landing_pad_p (true);
11236 DONE;
11237 })
11238
11239 ;
11240 ; nop instruction pattern(s).
11241 ;
11242
11243 (define_insn "nop"
11244 [(const_int 0)]
11245 ""
11246 "nopr\t%%r0"
11247 [(set_attr "op_type" "RR")])
11248
11249 ; non-branch NOPs required for optimizing compare-and-branch patterns
11250 ; on z10
11251
11252 (define_insn "nop_lr0"
11253 [(unspec_volatile [(const_int 0)] UNSPECV_NOP_LR_0)]
11254 ""
11255 "lr\t0,0"
11256 [(set_attr "op_type" "RR")
11257 (set_attr "z10prop" "z10_fr_E1")])
11258
11259 (define_insn "nop_lr1"
11260 [(unspec_volatile [(const_int 0)] UNSPECV_NOP_LR_1)]
11261 ""
11262 "lr\t1,1"
11263 [(set_attr "op_type" "RR")])
11264
11265 ;;- Undeletable nops (used for hotpatching)
11266
11267 (define_insn "nop_2_byte"
11268 [(unspec_volatile [(const_int 0)] UNSPECV_NOP_2_BYTE)]
11269 ""
11270 "nopr\t%%r0"
11271 [(set_attr "op_type" "RR")])
11272
11273 (define_insn "nop_4_byte"
11274 [(unspec_volatile [(const_int 0)] UNSPECV_NOP_4_BYTE)]
11275 ""
11276 "nop\t0"
11277 [(set_attr "op_type" "RX")])
11278
11279 (define_insn "nop_6_byte"
11280 [(unspec_volatile [(const_int 0)] UNSPECV_NOP_6_BYTE)]
11281 ""
11282 "brcl\t0, 0"
11283 [(set_attr "op_type" "RIL")
11284 (set_attr "relative_long" "yes")])
11285
11286
11287 ;
11288 ; Special literal pool access instruction pattern(s).
11289 ;
11290
11291 (define_insn "*pool_entry"
11292 [(unspec_volatile [(match_operand 0 "consttable_operand" "X")]
11293 UNSPECV_POOL_ENTRY)]
11294 ""
11295 {
11296 machine_mode mode = GET_MODE (PATTERN (insn));
11297 unsigned int align = GET_MODE_BITSIZE (mode);
11298 s390_output_pool_entry (operands[0], mode, align);
11299 return "";
11300 }
11301 [(set (attr "length")
11302 (symbol_ref "GET_MODE_SIZE (GET_MODE (PATTERN (insn)))"))])
11303
11304 (define_insn "pool_align"
11305 [(unspec_volatile [(match_operand 0 "const_int_operand" "n")]
11306 UNSPECV_POOL_ALIGN)]
11307 ""
11308 ".align\t%0"
11309 [(set (attr "length") (symbol_ref "INTVAL (operands[0])"))])
11310
11311 (define_insn "pool_section_start"
11312 [(unspec_volatile [(const_int 1)] UNSPECV_POOL_SECTION)]
11313 ""
11314 {
11315 switch_to_section (targetm.asm_out.function_rodata_section
11316 (current_function_decl, false));
11317 return "";
11318 }
11319 [(set_attr "length" "0")])
11320
11321 (define_insn "pool_section_end"
11322 [(unspec_volatile [(const_int 0)] UNSPECV_POOL_SECTION)]
11323 ""
11324 {
11325 switch_to_section (current_function_section ());
11326 return "";
11327 }
11328 [(set_attr "length" "0")])
11329
11330 (define_insn "main_base_64"
11331 [(set (match_operand 0 "register_operand" "=a")
11332 (unspec [(label_ref (match_operand 1 "" ""))] UNSPEC_MAIN_BASE))]
11333 "GET_MODE (operands[0]) == Pmode"
11334 "larl\t%0,%1"
11335 [(set_attr "op_type" "RIL")
11336 (set_attr "type" "larl")
11337 (set_attr "z10prop" "z10_fwd_A1")
11338 (set_attr "relative_long" "yes")])
11339
11340 (define_insn "main_pool"
11341 [(set (match_operand 0 "register_operand" "=a")
11342 (unspec_volatile [(const_int 0)] UNSPECV_MAIN_POOL))]
11343 "GET_MODE (operands[0]) == Pmode"
11344 {
11345 gcc_unreachable ();
11346 }
11347 [(set (attr "type")
11348 (const_string "larl"))])
11349
11350 (define_insn "reload_base_64"
11351 [(set (match_operand 0 "register_operand" "=a")
11352 (unspec [(label_ref (match_operand 1 "" ""))] UNSPEC_RELOAD_BASE))]
11353 "GET_MODE (operands[0]) == Pmode"
11354 "larl\t%0,%1"
11355 [(set_attr "op_type" "RIL")
11356 (set_attr "type" "larl")
11357 (set_attr "z10prop" "z10_fwd_A1")])
11358
11359 (define_insn "pool"
11360 [(unspec_volatile [(match_operand 0 "const_int_operand" "n")] UNSPECV_POOL)]
11361 ""
11362 {
11363 gcc_unreachable ();
11364 }
11365 [(set (attr "length") (symbol_ref "INTVAL (operands[0])"))])
11366
11367 ;;
11368 ;; Insns related to generating the function prologue and epilogue.
11369 ;;
11370
11371
11372 (define_expand "prologue"
11373 [(use (const_int 0))]
11374 ""
11375 "s390_emit_prologue (); DONE;")
11376
11377 (define_expand "epilogue"
11378 [(use (const_int 1))]
11379 ""
11380 "s390_emit_epilogue (false); DONE;")
11381
11382 (define_expand "sibcall_epilogue"
11383 [(use (const_int 0))]
11384 ""
11385 "s390_emit_epilogue (true); DONE;")
11386
11387 ;; A direct return instruction, without using an epilogue.
11388 (define_insn "<code>"
11389 [(ANY_RETURN)]
11390 "s390_can_use_<code>_insn ()"
11391 {
11392 if (TARGET_INDIRECT_BRANCH_NOBP_RET)
11393 {
11394 /* The target is always r14 so there is no clobber
11395 of r1 needed for pre z10 targets. */
11396 s390_indirect_branch_via_thunk (RETURN_REGNUM,
11397 INVALID_REGNUM,
11398 NULL_RTX,
11399 s390_indirect_branch_type_return);
11400 return "";
11401 }
11402 else
11403 return "br\t%%r14";
11404 }
11405 [(set (attr "op_type")
11406 (if_then_else (match_test "TARGET_INDIRECT_BRANCH_NOBP_RET")
11407 (const_string "RIL")
11408 (const_string "RR")))
11409 (set (attr "mnemonic")
11410 (if_then_else (match_test "TARGET_INDIRECT_BRANCH_NOBP_RET")
11411 (const_string "jg")
11412 (const_string "br")))
11413 (set_attr "type" "jsr")
11414 (set_attr "atype" "agen")])
11415
11416
11417 (define_expand "return_use"
11418 [(parallel
11419 [(return)
11420 (use (match_operand 0 "register_operand" "a"))])]
11421 ""
11422 {
11423 if (!TARGET_CPU_Z10
11424 && TARGET_INDIRECT_BRANCH_NOBP_RET_OPTION)
11425 {
11426 if (TARGET_64BIT)
11427 emit_jump_insn (gen_returndi_prez10 (operands[0]));
11428 else
11429 emit_jump_insn (gen_returnsi_prez10 (operands[0]));
11430 DONE;
11431 }
11432 })
11433
11434 (define_insn "*return<mode>"
11435 [(return)
11436 (use (match_operand:P 0 "register_operand" "a"))]
11437 "TARGET_CPU_Z10 || !TARGET_INDIRECT_BRANCH_NOBP_RET_OPTION"
11438 {
11439 if (TARGET_INDIRECT_BRANCH_NOBP_RET)
11440 {
11441 s390_indirect_branch_via_thunk (REGNO (operands[0]),
11442 INVALID_REGNUM,
11443 NULL_RTX,
11444 s390_indirect_branch_type_return);
11445 return "";
11446 }
11447 else
11448 return "br\t%0";
11449 }
11450 [(set (attr "op_type")
11451 (if_then_else (match_test "TARGET_INDIRECT_BRANCH_NOBP_RET")
11452 (const_string "RIL")
11453 (const_string "RR")))
11454 (set (attr "mnemonic")
11455 (if_then_else (match_test "TARGET_INDIRECT_BRANCH_NOBP_RET")
11456 (const_string "jg")
11457 (const_string "br")))
11458 (set_attr "type" "jsr")
11459 (set_attr "atype" "agen")])
11460
11461 (define_insn "return<mode>_prez10"
11462 [(return)
11463 (use (match_operand:P 0 "register_operand" "a"))
11464 (clobber (reg:P INDIRECT_BRANCH_THUNK_REGNUM))]
11465 "!TARGET_CPU_Z10 && TARGET_INDIRECT_BRANCH_NOBP_RET_OPTION"
11466 {
11467 if (TARGET_INDIRECT_BRANCH_NOBP_RET)
11468 {
11469 s390_indirect_branch_via_thunk (REGNO (operands[0]),
11470 INVALID_REGNUM,
11471 NULL_RTX,
11472 s390_indirect_branch_type_return);
11473 return "";
11474 }
11475 else
11476 return "br\t%0";
11477 }
11478 [(set (attr "op_type")
11479 (if_then_else (match_test "TARGET_INDIRECT_BRANCH_NOBP_RET")
11480 (const_string "RIL")
11481 (const_string "RR")))
11482 (set (attr "mnemonic")
11483 (if_then_else (match_test "TARGET_INDIRECT_BRANCH_NOBP_RET")
11484 (const_string "jg")
11485 (const_string "br")))
11486 (set_attr "type" "jsr")
11487 (set_attr "atype" "agen")])
11488
11489
11490 ;; Instruction definition to extend a 31-bit pointer into a 64-bit
11491 ;; pointer. This is used for compatibility.
11492
11493 (define_expand "ptr_extend"
11494 [(set (match_operand:DI 0 "register_operand" "=r")
11495 (match_operand:SI 1 "register_operand" "r"))]
11496 "TARGET_64BIT"
11497 {
11498 emit_insn (gen_anddi3 (operands[0],
11499 gen_lowpart (DImode, operands[1]),
11500 GEN_INT (0x7fffffff)));
11501 DONE;
11502 })
11503
11504 ;; Instruction definition to expand eh_return macro to support
11505 ;; swapping in special linkage return addresses.
11506
11507 (define_expand "eh_return"
11508 [(use (match_operand 0 "register_operand" ""))]
11509 "TARGET_TPF"
11510 {
11511 s390_emit_tpf_eh_return (operands[0]);
11512 DONE;
11513 })
11514
11515 ;
11516 ; Stack Protector Patterns
11517 ;
11518
11519 (define_expand "stack_protect_set"
11520 [(set (match_operand 0 "memory_operand" "")
11521 (match_operand 1 "memory_operand" ""))]
11522 ""
11523 {
11524 #ifdef TARGET_THREAD_SSP_OFFSET
11525 operands[1]
11526 = gen_rtx_MEM (Pmode, gen_rtx_PLUS (Pmode, s390_get_thread_pointer (),
11527 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
11528 #endif
11529 if (TARGET_64BIT)
11530 emit_insn (gen_stack_protect_setdi (operands[0], operands[1]));
11531 else
11532 emit_insn (gen_stack_protect_setsi (operands[0], operands[1]));
11533
11534 DONE;
11535 })
11536
11537 (define_insn "stack_protect_set<mode>"
11538 [(set (match_operand:DSI 0 "memory_operand" "=Q")
11539 (unspec:DSI [(match_operand:DSI 1 "memory_operand" "Q")] UNSPEC_SP_SET))]
11540 ""
11541 "mvc\t%O0(%G0,%R0),%S1"
11542 [(set_attr "op_type" "SS")])
11543
11544 (define_expand "stack_protect_test"
11545 [(set (reg:CC CC_REGNUM)
11546 (compare (match_operand 0 "memory_operand" "")
11547 (match_operand 1 "memory_operand" "")))
11548 (match_operand 2 "" "")]
11549 ""
11550 {
11551 rtx cc_reg, test;
11552 #ifdef TARGET_THREAD_SSP_OFFSET
11553 operands[1]
11554 = gen_rtx_MEM (Pmode, gen_rtx_PLUS (Pmode, s390_get_thread_pointer (),
11555 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
11556 #endif
11557 if (TARGET_64BIT)
11558 emit_insn (gen_stack_protect_testdi (operands[0], operands[1]));
11559 else
11560 emit_insn (gen_stack_protect_testsi (operands[0], operands[1]));
11561
11562 cc_reg = gen_rtx_REG (CCZmode, CC_REGNUM);
11563 test = gen_rtx_EQ (VOIDmode, cc_reg, const0_rtx);
11564 emit_jump_insn (gen_cbranchcc4 (test, cc_reg, const0_rtx, operands[2]));
11565 DONE;
11566 })
11567
11568 (define_insn "stack_protect_test<mode>"
11569 [(set (reg:CCZ CC_REGNUM)
11570 (unspec:CCZ [(match_operand:DSI 0 "memory_operand" "Q")
11571 (match_operand:DSI 1 "memory_operand" "Q")] UNSPEC_SP_TEST))]
11572 ""
11573 "clc\t%O0(%G0,%R0),%S1"
11574 [(set_attr "op_type" "SS")])
11575
11576 ; This is used in s390_emit_prologue in order to prevent insns
11577 ; adjusting the stack pointer to be moved over insns writing stack
11578 ; slots using a copy of the stack pointer in a different register.
11579 (define_insn "stack_tie"
11580 [(set (match_operand:BLK 0 "memory_operand" "+m")
11581 (unspec:BLK [(match_dup 0)] UNSPEC_TIE))]
11582 ""
11583 ""
11584 [(set_attr "length" "0")])
11585
11586
11587 (define_insn "stack_restore_from_fpr"
11588 [(set (reg:DI STACK_REGNUM)
11589 (match_operand:DI 0 "register_operand" "f"))
11590 (clobber (mem:BLK (scratch)))]
11591 "TARGET_Z10"
11592 "lgdr\t%%r15,%0"
11593 [(set_attr "op_type" "RRE")])
11594
11595 ;
11596 ; Data prefetch patterns
11597 ;
11598
11599 (define_insn "prefetch"
11600 [(prefetch (match_operand 0 "address_operand" "ZT,X")
11601 (match_operand:SI 1 "const_int_operand" " n,n")
11602 (match_operand:SI 2 "const_int_operand" " n,n"))]
11603 "TARGET_Z10"
11604 {
11605 switch (which_alternative)
11606 {
11607 case 0:
11608 return INTVAL (operands[1]) == 1 ? "pfd\t2,%a0" : "pfd\t1,%a0";
11609 case 1:
11610 if (larl_operand (operands[0], Pmode))
11611 return INTVAL (operands[1]) == 1 ? "pfdrl\t2,%a0" : "pfdrl\t1,%a0";
11612 /* fallthrough */
11613 default:
11614
11615 /* This might be reached for symbolic operands with an odd
11616 addend. We simply omit the prefetch for such rare cases. */
11617
11618 return "";
11619 }
11620 }
11621 [(set_attr "type" "load,larl")
11622 (set_attr "op_type" "RXY,RIL")
11623 (set_attr "z10prop" "z10_super")
11624 (set_attr "z196prop" "z196_alone")
11625 (set_attr "relative_long" "yes")])
11626
11627
11628 ;
11629 ; Byte swap instructions
11630 ;
11631
11632 ; FIXME: There is also mvcin but we cannot use it since src and target
11633 ; may overlap.
11634 ; lrvr, lrv, strv, lrvgr, lrvg, strvg
11635 (define_insn "bswap<mode>2"
11636 [(set (match_operand:GPR 0 "nonimmediate_operand" "=d,d,T")
11637 (bswap:GPR (match_operand:GPR 1 "nonimmediate_operand" " d,T,d")))]
11638 ""
11639 "@
11640 lrv<g>r\t%0,%1
11641 lrv<g>\t%0,%1
11642 strv<g>\t%1,%0"
11643 [(set_attr "type" "*,load,store")
11644 (set_attr "op_type" "RRE,RXY,RXY")
11645 (set_attr "z10prop" "z10_super")])
11646
11647 (define_insn "bswaphi2"
11648 [(set (match_operand:HI 0 "nonimmediate_operand" "=d,d,T")
11649 (bswap:HI (match_operand:HI 1 "nonimmediate_operand" " d,T,d")))]
11650 ""
11651 "@
11652 #
11653 lrvh\t%0,%1
11654 strvh\t%1,%0"
11655 [(set_attr "type" "*,load,store")
11656 (set_attr "op_type" "RRE,RXY,RXY")
11657 (set_attr "z10prop" "z10_super")])
11658
11659 (define_split
11660 [(set (match_operand:HI 0 "register_operand" "")
11661 (bswap:HI (match_operand:HI 1 "register_operand" "")))]
11662 ""
11663 [(set (match_dup 2) (bswap:SI (match_dup 3)))
11664 (set (match_dup 2) (lshiftrt:SI (match_dup 2) (const_int 16)))]
11665 {
11666 operands[2] = simplify_gen_subreg (SImode, operands[0], HImode, 0);
11667 operands[3] = simplify_gen_subreg (SImode, operands[1], HImode, 0);
11668 })
11669
11670
11671 ;
11672 ; Population count instruction
11673 ;
11674
11675 (define_insn "*popcountdi_z15_cc"
11676 [(set (reg CC_REGNUM)
11677 (compare (popcount:DI (match_operand:DI 1 "register_operand" "d"))
11678 (const_int 0)))
11679 (set (match_operand:DI 0 "register_operand" "=d")
11680 (match_dup 1))]
11681 "TARGET_Z15 && s390_match_ccmode (insn, CCTmode)"
11682 "popcnt\t%0,%1,8"
11683 [(set_attr "op_type" "RRF")])
11684
11685 (define_insn "*popcountdi_z15_cconly"
11686 [(set (reg CC_REGNUM)
11687 (compare (popcount:DI (match_operand:DI 1 "register_operand" "d"))
11688 (const_int 0)))
11689 (clobber (match_scratch:DI 0 "=d"))]
11690 "TARGET_Z15 && s390_match_ccmode(insn, CCTmode)"
11691 "popcnt\t%0,%1,8"
11692 [(set_attr "op_type" "RRF")])
11693
11694 (define_insn "*popcountdi_z15"
11695 [(set (match_operand:DI 0 "register_operand" "=d")
11696 (popcount:DI (match_operand:DI 1 "register_operand" "d")))
11697 (clobber (reg:CC CC_REGNUM))]
11698 "TARGET_Z15"
11699 "popcnt\t%0,%1,8"
11700 [(set_attr "op_type" "RRF")])
11701
11702 ; The pre-z15 popcount instruction counts the bits of op1 in 8 byte
11703 ; portions and stores the result in the corresponding bytes in op0.
11704 (define_insn "*popcount<mode>_z196"
11705 [(set (match_operand:INT 0 "register_operand" "=d")
11706 (unspec:INT [(match_operand:INT 1 "register_operand" "d")] UNSPEC_POPCNT))
11707 (clobber (reg:CC CC_REGNUM))]
11708 "TARGET_Z196"
11709 "popcnt\t%0,%1"
11710 [(set_attr "op_type" "RRE")])
11711
11712 (define_expand "popcountdi2_z196"
11713 [; popcnt op0, op1
11714 (parallel [(set (match_operand:DI 0 "register_operand" "")
11715 (unspec:DI [(match_operand:DI 1 "register_operand")]
11716 UNSPEC_POPCNT))
11717 (clobber (reg:CC CC_REGNUM))])
11718 ; sllg op2, op0, 32
11719 (set (match_dup 2) (ashift:DI (match_dup 0) (const_int 32)))
11720 ; agr op0, op2
11721 (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 2)))
11722 (clobber (reg:CC CC_REGNUM))])
11723 ; sllg op2, op0, 16
11724 (set (match_dup 2)
11725 (ashift:DI (match_dup 0) (const_int 16)))
11726 ; agr op0, op2
11727 (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 2)))
11728 (clobber (reg:CC CC_REGNUM))])
11729 ; sllg op2, op0, 8
11730 (set (match_dup 2) (ashift:DI (match_dup 0) (const_int 8)))
11731 ; agr op0, op2
11732 (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 2)))
11733 (clobber (reg:CC CC_REGNUM))])
11734 ; srlg op0, op0, 56
11735 (set (match_dup 0) (lshiftrt:DI (match_dup 0) (const_int 56)))]
11736 "TARGET_Z196"
11737 "operands[2] = gen_reg_rtx (DImode);")
11738
11739 (define_expand "popcountdi2"
11740 [(parallel
11741 [(set (match_operand:DI 0 "register_operand" "")
11742 (popcount:DI (match_operand:DI 1 "register_operand")))
11743 (clobber (reg:CC CC_REGNUM))])]
11744 "TARGET_Z196"
11745 {
11746 if (!TARGET_Z15)
11747 {
11748 emit_insn (gen_popcountdi2_z196 (operands[0], operands[1]));
11749 DONE;
11750 }
11751 })
11752
11753 (define_expand "popcountsi2_z196"
11754 [; popcnt op0, op1
11755 (parallel [(set (match_operand:SI 0 "register_operand" "")
11756 (unspec:SI [(match_operand:SI 1 "register_operand")]
11757 UNSPEC_POPCNT))
11758 (clobber (reg:CC CC_REGNUM))])
11759 ; sllk op2, op0, 16
11760 (set (match_dup 2)
11761 (ashift:SI (match_dup 0) (const_int 16)))
11762 ; ar op0, op2
11763 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
11764 (clobber (reg:CC CC_REGNUM))])
11765 ; sllk op2, op0, 8
11766 (set (match_dup 2) (ashift:SI (match_dup 0) (const_int 8)))
11767 ; ar op0, op2
11768 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
11769 (clobber (reg:CC CC_REGNUM))])
11770 ; srl op0, op0, 24
11771 (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 24)))]
11772 "TARGET_Z196"
11773 "operands[2] = gen_reg_rtx (SImode);")
11774
11775 ; popcount always counts on the full 64 bit. With the z196 version
11776 ; counting bits per byte we just ignore the upper 4 bytes. With the
11777 ; z15 version we have to zero out the upper 32 bits first.
11778 (define_expand "popcountsi2"
11779 [(set (match_dup 2)
11780 (zero_extend:DI (match_operand:SI 1 "register_operand")))
11781 (parallel [(set (match_dup 3) (popcount:DI (match_dup 2)))
11782 (clobber (reg:CC CC_REGNUM))])
11783 (set (match_operand:SI 0 "register_operand")
11784 (subreg:SI (match_dup 3) 4))]
11785 "TARGET_Z196"
11786 {
11787 if (!TARGET_Z15)
11788 {
11789 emit_insn (gen_popcountsi2_z196 (operands[0], operands[1]));
11790 DONE;
11791 }
11792 else
11793 {
11794 operands[2] = gen_reg_rtx (DImode);
11795 operands[3] = gen_reg_rtx (DImode);
11796 }
11797 })
11798
11799 (define_expand "popcounthi2_z196"
11800 [; popcnt op2, op1
11801 (parallel [(set (match_dup 2)
11802 (unspec:HI [(match_operand:HI 1 "register_operand")]
11803 UNSPEC_POPCNT))
11804 (clobber (reg:CC CC_REGNUM))])
11805 ; lr op3, op2
11806 (set (match_dup 3) (subreg:SI (match_dup 2) 0))
11807 ; srl op4, op3, 8
11808 (set (match_dup 4) (lshiftrt:SI (match_dup 3) (const_int 8)))
11809 ; ar op3, op4
11810 (parallel [(set (match_dup 3) (plus:SI (match_dup 3) (match_dup 4)))
11811 (clobber (reg:CC CC_REGNUM))])
11812 ; llgc op0, op3
11813 (parallel [(set (match_operand:HI 0 "register_operand" "")
11814 (and:HI (subreg:HI (match_dup 3) 2) (const_int 255)))
11815 (clobber (reg:CC CC_REGNUM))])]
11816 "TARGET_Z196"
11817 {
11818 operands[2] = gen_reg_rtx (HImode);
11819 operands[3] = gen_reg_rtx (SImode);
11820 operands[4] = gen_reg_rtx (SImode);
11821 })
11822
11823 (define_expand "popcounthi2"
11824 [(set (match_dup 2)
11825 (zero_extend:DI (match_operand:HI 1 "register_operand")))
11826 (parallel [(set (match_dup 3) (popcount:DI (match_dup 2)))
11827 (clobber (reg:CC CC_REGNUM))])
11828 (set (match_operand:HI 0 "register_operand")
11829 (subreg:HI (match_dup 3) 6))]
11830 "TARGET_Z196"
11831 {
11832 if (!TARGET_Z15)
11833 {
11834 emit_insn (gen_popcounthi2_z196 (operands[0], operands[1]));
11835 DONE;
11836 }
11837 else
11838 {
11839 operands[2] = gen_reg_rtx (DImode);
11840 operands[3] = gen_reg_rtx (DImode);
11841 }
11842 })
11843
11844 ; For popcount on a single byte the old z196 style popcount
11845 ; instruction is ideal. Since it anyway does a byte-wise popcount we
11846 ; just use it instead of zero extending the QImode input to DImode and
11847 ; using the z15 popcount variant.
11848 (define_expand "popcountqi2"
11849 [; popcnt op0, op1
11850 (parallel [(set (match_operand:QI 0 "register_operand" "")
11851 (unspec:QI [(match_operand:QI 1 "register_operand")]
11852 UNSPEC_POPCNT))
11853 (clobber (reg:CC CC_REGNUM))])]
11854 "TARGET_Z196"
11855 "")
11856
11857 ;;
11858 ;;- Copy sign instructions
11859 ;;
11860
11861 (define_insn "copysign<mode>3<tf_fpr>"
11862 [(set (match_operand:FP 0 "register_operand" "=f")
11863 (unspec:FP [(match_operand:FP 1 "register_operand" "<fT0>")
11864 (match_operand:FP 2 "register_operand" "f")]
11865 UNSPEC_COPYSIGN))]
11866 "TARGET_Z196"
11867 "cpsdr\t%0,%2,%1"
11868 [(set_attr "op_type" "RRF")
11869 (set_attr "type" "fsimp<type>")])
11870
11871
11872 ;;
11873 ;;- Transactional execution instructions
11874 ;;
11875
11876 ; This splitter helps combine to make use of CC directly when
11877 ; comparing the integer result of a tbegin builtin with a constant.
11878 ; The unspec is already removed by canonicalize_comparison. So this
11879 ; splitters only job is to turn the PARALLEL into separate insns
11880 ; again. Unfortunately this only works with the very first cc/int
11881 ; compare since combine is not able to deal with data flow across
11882 ; basic block boundaries.
11883
11884 ; It needs to be an insn pattern as well since combine does not apply
11885 ; the splitter directly. Combine would only use it if it actually
11886 ; would reduce the number of instructions.
11887 (define_insn_and_split "*ccraw_to_int"
11888 [(set (pc)
11889 (if_then_else
11890 (match_operator 0 "s390_eqne_operator"
11891 [(reg:CCRAW CC_REGNUM)
11892 (match_operand 1 "const_int_operand" "")])
11893 (label_ref (match_operand 2 "" ""))
11894 (pc)))
11895 (set (match_operand:SI 3 "register_operand" "=d")
11896 (unspec:SI [(reg:CCRAW CC_REGNUM)] UNSPEC_CC_TO_INT))]
11897 ""
11898 "#"
11899 ""
11900 [(set (match_dup 3)
11901 (unspec:SI [(reg:CCRAW CC_REGNUM)] UNSPEC_CC_TO_INT))
11902 (set (pc)
11903 (if_then_else (match_op_dup 0 [(reg:CCRAW CC_REGNUM) (match_dup 1)])
11904 (label_ref (match_dup 2))
11905 (pc)))]
11906 "")
11907
11908 ; Non-constrained transaction begin
11909
11910 (define_expand "tbegin"
11911 [(match_operand:SI 0 "register_operand" "")
11912 (match_operand:BLK 1 "memory_operand" "")]
11913 "TARGET_HTM"
11914 {
11915 s390_expand_tbegin (operands[0], operands[1], NULL_RTX, true);
11916 DONE;
11917 })
11918
11919 (define_expand "tbegin_nofloat"
11920 [(match_operand:SI 0 "register_operand" "")
11921 (match_operand:BLK 1 "memory_operand" "")]
11922 "TARGET_HTM"
11923 {
11924 s390_expand_tbegin (operands[0], operands[1], NULL_RTX, false);
11925 DONE;
11926 })
11927
11928 (define_expand "tbegin_retry"
11929 [(match_operand:SI 0 "register_operand" "")
11930 (match_operand:BLK 1 "memory_operand" "")
11931 (match_operand:SI 2 "general_operand" "")]
11932 "TARGET_HTM"
11933 {
11934 s390_expand_tbegin (operands[0], operands[1], operands[2], true);
11935 DONE;
11936 })
11937
11938 (define_expand "tbegin_retry_nofloat"
11939 [(match_operand:SI 0 "register_operand" "")
11940 (match_operand:BLK 1 "memory_operand" "")
11941 (match_operand:SI 2 "general_operand" "")]
11942 "TARGET_HTM"
11943 {
11944 s390_expand_tbegin (operands[0], operands[1], operands[2], false);
11945 DONE;
11946 })
11947
11948 ; Clobber VRs since they don't get restored
11949 (define_insn "tbegin_1_z13"
11950 [(set (reg:CCRAW CC_REGNUM)
11951 (unspec_volatile:CCRAW [(match_operand 0 "const_int_operand" "D")]
11952 UNSPECV_TBEGIN))
11953 (set (match_operand:BLK 1 "memory_operand" "=Q")
11954 (unspec_volatile:BLK [(match_dup 0)] UNSPECV_TBEGIN_TDB))
11955 (clobber (reg:TI 16)) (clobber (reg:TI 38))
11956 (clobber (reg:TI 17)) (clobber (reg:TI 39))
11957 (clobber (reg:TI 18)) (clobber (reg:TI 40))
11958 (clobber (reg:TI 19)) (clobber (reg:TI 41))
11959 (clobber (reg:TI 20)) (clobber (reg:TI 42))
11960 (clobber (reg:TI 21)) (clobber (reg:TI 43))
11961 (clobber (reg:TI 22)) (clobber (reg:TI 44))
11962 (clobber (reg:TI 23)) (clobber (reg:TI 45))
11963 (clobber (reg:TI 24)) (clobber (reg:TI 46))
11964 (clobber (reg:TI 25)) (clobber (reg:TI 47))
11965 (clobber (reg:TI 26)) (clobber (reg:TI 48))
11966 (clobber (reg:TI 27)) (clobber (reg:TI 49))
11967 (clobber (reg:TI 28)) (clobber (reg:TI 50))
11968 (clobber (reg:TI 29)) (clobber (reg:TI 51))
11969 (clobber (reg:TI 30)) (clobber (reg:TI 52))
11970 (clobber (reg:TI 31)) (clobber (reg:TI 53))]
11971 ; CONST_OK_FOR_CONSTRAINT_P does not work with D constraint since D is
11972 ; not supposed to be used for immediates (see genpreds.c).
11973 "TARGET_VX && INTVAL (operands[0]) >= 0 && INTVAL (operands[0]) <= 0xffff"
11974 "tbegin\t%1,%x0"
11975 [(set_attr "op_type" "SIL")])
11976
11977 (define_insn "tbegin_1"
11978 [(set (reg:CCRAW CC_REGNUM)
11979 (unspec_volatile:CCRAW [(match_operand 0 "const_int_operand" "D")]
11980 UNSPECV_TBEGIN))
11981 (set (match_operand:BLK 1 "memory_operand" "=Q")
11982 (unspec_volatile:BLK [(match_dup 0)] UNSPECV_TBEGIN_TDB))
11983 (clobber (reg:DF 16))
11984 (clobber (reg:DF 17))
11985 (clobber (reg:DF 18))
11986 (clobber (reg:DF 19))
11987 (clobber (reg:DF 20))
11988 (clobber (reg:DF 21))
11989 (clobber (reg:DF 22))
11990 (clobber (reg:DF 23))
11991 (clobber (reg:DF 24))
11992 (clobber (reg:DF 25))
11993 (clobber (reg:DF 26))
11994 (clobber (reg:DF 27))
11995 (clobber (reg:DF 28))
11996 (clobber (reg:DF 29))
11997 (clobber (reg:DF 30))
11998 (clobber (reg:DF 31))]
11999 ; CONST_OK_FOR_CONSTRAINT_P does not work with D constraint since D is
12000 ; not supposed to be used for immediates (see genpreds.c).
12001 "TARGET_HTM && INTVAL (operands[0]) >= 0 && INTVAL (operands[0]) <= 0xffff"
12002 "tbegin\t%1,%x0"
12003 [(set_attr "op_type" "SIL")])
12004
12005 ; Same as above but without the FPR clobbers
12006 (define_insn "tbegin_nofloat_1"
12007 [(set (reg:CCRAW CC_REGNUM)
12008 (unspec_volatile:CCRAW [(match_operand 0 "const_int_operand" "D")]
12009 UNSPECV_TBEGIN))
12010 (set (match_operand:BLK 1 "memory_operand" "=Q")
12011 (unspec_volatile:BLK [(match_dup 0)] UNSPECV_TBEGIN_TDB))]
12012 "TARGET_HTM && INTVAL (operands[0]) >= 0 && INTVAL (operands[0]) <= 0xffff"
12013 "tbegin\t%1,%x0"
12014 [(set_attr "op_type" "SIL")])
12015
12016
12017 ; Constrained transaction begin
12018
12019 (define_expand "tbeginc"
12020 [(set (reg:CCRAW CC_REGNUM)
12021 (unspec_volatile:CCRAW [(const_int TBEGINC_MASK)]
12022 UNSPECV_TBEGINC))]
12023 "TARGET_HTM"
12024 "")
12025
12026 (define_insn "*tbeginc_1"
12027 [(set (reg:CCRAW CC_REGNUM)
12028 (unspec_volatile:CCRAW [(match_operand 0 "const_int_operand" " D")]
12029 UNSPECV_TBEGINC))]
12030 "TARGET_HTM && INTVAL (operands[0]) >= 0 && INTVAL (operands[0]) <= 0xffff"
12031 "tbeginc\t0,%x0"
12032 [(set_attr "op_type" "SIL")])
12033
12034 ; Transaction end
12035
12036 (define_expand "tend"
12037 [(set (reg:CCRAW CC_REGNUM)
12038 (unspec_volatile:CCRAW [(const_int 0)] UNSPECV_TEND))
12039 (set (match_operand:SI 0 "register_operand" "")
12040 (unspec:SI [(reg:CCRAW CC_REGNUM)] UNSPEC_CC_TO_INT))]
12041 "TARGET_HTM"
12042 "")
12043
12044 (define_insn "*tend_1"
12045 [(set (reg:CCRAW CC_REGNUM)
12046 (unspec_volatile:CCRAW [(const_int 0)] UNSPECV_TEND))]
12047 "TARGET_HTM"
12048 "tend"
12049 [(set_attr "op_type" "S")])
12050
12051 ; Transaction abort
12052
12053 (define_expand "tabort"
12054 [(unspec_volatile [(match_operand:SI 0 "nonmemory_operand" "")]
12055 UNSPECV_TABORT)]
12056 "TARGET_HTM && operands != NULL"
12057 {
12058 if (CONST_INT_P (operands[0])
12059 && INTVAL (operands[0]) >= 0 && INTVAL (operands[0]) <= 255)
12060 {
12061 error ("invalid transaction abort code: %wd (values in range 0 "
12062 "through 255 are reserved)", INTVAL (operands[0]));
12063 FAIL;
12064 }
12065 })
12066
12067 (define_insn "*tabort_1"
12068 [(unspec_volatile [(match_operand:SI 0 "nonmemory_operand" "aJ")]
12069 UNSPECV_TABORT)]
12070 "TARGET_HTM && operands != NULL"
12071 "tabort\t%Y0"
12072 [(set_attr "op_type" "S")])
12073
12074 (define_insn "*tabort_1_plus"
12075 [(unspec_volatile [(plus:SI (match_operand:SI 0 "register_operand" "a")
12076 (match_operand:SI 1 "const_int_operand" "J"))]
12077 UNSPECV_TABORT)]
12078 "TARGET_HTM && operands != NULL
12079 && CONST_OK_FOR_CONSTRAINT_P (INTVAL (operands[1]), 'J', \"J\")"
12080 "tabort\t%1(%0)"
12081 [(set_attr "op_type" "S")])
12082
12083 ; Transaction extract nesting depth
12084
12085 (define_insn "etnd"
12086 [(set (match_operand:SI 0 "register_operand" "=d")
12087 (unspec_volatile:SI [(const_int 0)] UNSPECV_ETND))]
12088 "TARGET_HTM"
12089 "etnd\t%0"
12090 [(set_attr "op_type" "RRE")])
12091
12092 ; Non-transactional store
12093
12094 (define_insn "ntstg"
12095 [(set (match_operand:DI 0 "memory_operand" "=T")
12096 (unspec_volatile:DI [(match_operand:DI 1 "register_operand" "d")]
12097 UNSPECV_NTSTG))]
12098 "TARGET_HTM"
12099 "ntstg\t%1,%0"
12100 [(set_attr "op_type" "RXY")])
12101
12102 ; Transaction perform processor assist
12103
12104 (define_expand "tx_assist"
12105 [(unspec_volatile [(match_operand:SI 0 "register_operand" "")
12106 (reg:SI GPR0_REGNUM)
12107 (const_int PPA_TX_ABORT)]
12108 UNSPECV_PPA)]
12109 "TARGET_HTM"
12110 "")
12111
12112 (define_insn "*ppa"
12113 [(unspec_volatile [(match_operand:SI 0 "register_operand" "d")
12114 (match_operand:SI 1 "register_operand" "d")
12115 (match_operand 2 "const_int_operand" "I")]
12116 UNSPECV_PPA)]
12117 "(TARGET_ZEC12 || TARGET_HTM) && INTVAL (operands[2]) < 16"
12118 "ppa\t%0,%1,%2"
12119 [(set_attr "op_type" "RRF")])
12120
12121
12122 ; Set and get floating point control register
12123
12124 (define_insn "sfpc"
12125 [(unspec_volatile [(match_operand:SI 0 "register_operand" "d")]
12126 UNSPECV_SFPC)]
12127 "TARGET_HARD_FLOAT"
12128 "sfpc\t%0")
12129
12130 (define_insn "efpc"
12131 [(set (match_operand:SI 0 "register_operand" "=d")
12132 (unspec_volatile:SI [(const_int 0)] UNSPECV_EFPC))]
12133 "TARGET_HARD_FLOAT"
12134 "efpc\t%0")
12135
12136
12137 ; Load count to block boundary
12138
12139 (define_insn "lcbb"
12140 [(set (match_operand:SI 0 "register_operand" "=d")
12141 (unspec:SI [(match_operand 1 "address_operand" "ZR")
12142 (match_operand:SI 2 "immediate_operand" "C")] UNSPEC_LCBB))
12143 (clobber (reg:CC CC_REGNUM))]
12144 "TARGET_Z13"
12145 "lcbb\t%0,%a1,%b2"
12146 [(set_attr "op_type" "VRX")])
12147
12148 ; Handle -fsplit-stack.
12149
12150 (define_expand "split_stack_prologue"
12151 [(const_int 0)]
12152 ""
12153 {
12154 s390_expand_split_stack_prologue ();
12155 DONE;
12156 })
12157
12158 ;; If there are operand 0 bytes available on the stack, jump to
12159 ;; operand 1.
12160
12161 (define_expand "split_stack_space_check"
12162 [(set (pc) (if_then_else
12163 (ltu (minus (reg 15)
12164 (match_operand 0 "register_operand"))
12165 (unspec [(const_int 0)] UNSPEC_STACK_CHECK))
12166 (label_ref (match_operand 1))
12167 (pc)))]
12168 ""
12169 {
12170 /* Offset from thread pointer to __private_ss. */
12171 int psso = TARGET_64BIT ? 0x38 : 0x20;
12172 rtx tp = s390_get_thread_pointer ();
12173 rtx guard = gen_rtx_MEM (Pmode, plus_constant (Pmode, tp, psso));
12174 rtx reg = gen_reg_rtx (Pmode);
12175 rtx cc;
12176 if (TARGET_64BIT)
12177 emit_insn (gen_subdi3 (reg, stack_pointer_rtx, operands[0]));
12178 else
12179 emit_insn (gen_subsi3 (reg, stack_pointer_rtx, operands[0]));
12180 cc = s390_emit_compare (GT, reg, guard);
12181 s390_emit_jump (operands[1], cc);
12182
12183 DONE;
12184 })
12185
12186 ;; Call to __morestack used by the split stack support
12187
12188 ; The insn has 3 parts:
12189 ; 1. A jump to the call done label. The jump will be done as part of
12190 ; __morestack and will not be explicitly emitted to the insn stream.
12191 ; 2. The call of __morestack including a use for r1 which is supposed to
12192 ; point to the parameter block for __morestack.
12193 ; 3. 3 USES whose values together with the call done label will be
12194 ; used to emit the parameter block to the .rodata section. This
12195 ; needs to be tied into the same insn as 1. since the call done
12196 ; label is emitted also as part of the parm block. In order to
12197 ; allow the edge to the BB with the call done label to be
12198 ; redirected both need to make use of the same label_ref.
12199
12200 (define_insn "@split_stack_call<mode>"
12201 [(set (pc) (label_ref (match_operand 2 "" ""))) ; call done label
12202 (set (reg:P 1) (unspec_volatile [(match_operand 0 "bras_sym_operand" "X")
12203 (reg:P 1)]
12204 UNSPECV_SPLIT_STACK_CALL))
12205 (use (label_ref (match_operand 1 "" "X"))) ; parm block label
12206 (use (match_operand 3 "const_int_operand" "X")) ; frame size
12207 (use (match_operand 4 "const_int_operand" "X"))] ; arg size
12208 ""
12209 {
12210 s390_output_split_stack_data (operands[1], operands[2], operands[3], operands[4]);
12211 return "jg\t%0";
12212 }
12213 [(set_attr "op_type" "RIL")
12214 (set_attr "type" "branch")])
12215
12216 ; As above but with a conditional jump
12217
12218 (define_insn "@split_stack_cond_call<mode>"
12219 [(set (pc)
12220 (if_then_else
12221 (match_operand 5 "" "") ; condition
12222 (label_ref (match_operand 2 "" "")) ; call done label
12223 (pc)))
12224 (set (reg:P 1) (unspec_volatile [(match_operand 0 "bras_sym_operand" "X")
12225 (reg:P 1)]
12226 UNSPECV_SPLIT_STACK_CALL))
12227 (use (label_ref (match_operand 1 "" "X"))) ; parm block label
12228 (use (match_operand 3 "const_int_operand" "X")) ; frame size
12229 (use (match_operand 4 "const_int_operand" "X"))] ; arg size
12230 ""
12231 {
12232 s390_output_split_stack_data (operands[1], operands[2], operands[3], operands[4]);
12233 return "jg%C5\t%0";
12234 }
12235 [(set_attr "op_type" "RIL")
12236 (set_attr "type" "branch")])
12237
12238
12239 (define_insn "osc_break"
12240 [(unspec_volatile [(const_int 0)] UNSPECV_OSC_BREAK)]
12241 ""
12242 "bcr\t7,%%r0"
12243 [(set_attr "op_type" "RR")])
12244
12245 (define_expand "speculation_barrier"
12246 [(unspec_volatile [(reg:SI GPR0_REGNUM)
12247 (reg:SI GPR0_REGNUM)
12248 (const_int PPA_OOO_BARRIER)]
12249 UNSPECV_PPA)]
12250 "TARGET_ZEC12"
12251 "")