]> git.ipfire.org Git - thirdparty/gcc.git/blob - gcc/config/s390/s390.md
Update copyright years.
[thirdparty/gcc.git] / gcc / config / s390 / s390.md
1 ;;- Machine description for GNU compiler -- S/390 / zSeries version.
2 ;; Copyright (C) 1999-2020 Free Software Foundation, Inc.
3 ;; Contributed by Hartmut Penner (hpenner@de.ibm.com) and
4 ;; Ulrich Weigand (uweigand@de.ibm.com) and
5 ;; Andreas Krebbel (Andreas.Krebbel@de.ibm.com)
6
7 ;; This file is part of GCC.
8
9 ;; GCC is free software; you can redistribute it and/or modify it under
10 ;; the terms of the GNU General Public License as published by the Free
11 ;; Software Foundation; either version 3, or (at your option) any later
12 ;; version.
13
14 ;; GCC is distributed in the hope that it will be useful, but WITHOUT ANY
15 ;; WARRANTY; without even the implied warranty of MERCHANTABILITY or
16 ;; FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
17 ;; for more details.
18
19 ;; You should have received a copy of the GNU General Public License
20 ;; along with GCC; see the file COPYING3. If not see
21 ;; <http://www.gnu.org/licenses/>.
22
23 ;;
24 ;; See constraints.md for a description of constraints specific to s390.
25 ;;
26
27 ;; Special formats used for outputting 390 instructions.
28 ;;
29 ;; %C: print opcode suffix for branch condition.
30 ;; %D: print opcode suffix for inverse branch condition.
31 ;; %J: print tls_load/tls_gdcall/tls_ldcall suffix
32 ;; %G: print the size of the operand in bytes.
33 ;; %O: print only the displacement of a memory reference.
34 ;; %R: print only the base register of a memory reference.
35 ;; %S: print S-type memory reference (base+displacement).
36 ;; %N: print the second word of a DImode operand.
37 ;; %M: print the second word of a TImode operand.
38 ;; %Y: print shift count operand.
39 ;;
40 ;; %b: print integer X as if it's an unsigned byte.
41 ;; %c: print integer X as if it's an signed byte.
42 ;; %x: print integer X as if it's an unsigned halfword.
43 ;; %h: print integer X as if it's a signed halfword.
44 ;; %i: print the first nonzero HImode part of X.
45 ;; %j: print the first HImode part unequal to -1 of X.
46 ;; %k: print the first nonzero SImode part of X.
47 ;; %m: print the first SImode part unequal to -1 of X.
48 ;; %o: print integer X as if it's an unsigned 32bit word.
49 ;;
50 ;; We have a special constraint for pattern matching.
51 ;;
52 ;; s_operand -- Matches a valid S operand in a RS, SI or SS type instruction.
53 ;;
54
55 ;;
56 ;; UNSPEC usage
57 ;;
58
59 (define_c_enum "unspec" [
60 ; Miscellaneous
61 UNSPEC_ROUND
62 UNSPEC_ICM
63 UNSPEC_TIE
64
65 ; Convert CC into a str comparison result and copy it into an
66 ; integer register
67 ; cc0->0, cc1->1, cc2->-1, (cc3->-1)
68 UNSPEC_STRCMPCC_TO_INT
69
70 ; Copy CC as is into the lower 2 bits of an integer register
71 UNSPEC_CC_TO_INT
72
73 ; The right hand side of an setmem
74 UNSPEC_REPLICATE_BYTE
75
76 ; GOT/PLT and lt-relative accesses
77 UNSPEC_LTREL_OFFSET
78 UNSPEC_POOL_OFFSET
79 UNSPEC_GOTENT
80 UNSPEC_GOT
81 UNSPEC_GOTOFF
82 UNSPEC_PLT
83 UNSPEC_PLTOFF
84
85 ; Literal pool
86 UNSPEC_RELOAD_BASE
87 UNSPEC_MAIN_BASE
88 UNSPEC_LTREF
89 UNSPEC_INSN
90 UNSPEC_EXECUTE
91 UNSPEC_EXECUTE_JUMP
92
93 ; Atomic Support
94 UNSPEC_MB
95 UNSPEC_MOVA
96
97 ; TLS relocation specifiers
98 UNSPEC_TLSGD
99 UNSPEC_TLSLDM
100 UNSPEC_NTPOFF
101 UNSPEC_DTPOFF
102 UNSPEC_GOTNTPOFF
103 UNSPEC_INDNTPOFF
104
105 ; TLS support
106 UNSPEC_TLSLDM_NTPOFF
107 UNSPEC_TLS_LOAD
108 UNSPEC_GET_TP
109
110 ; String Functions
111 UNSPEC_SRST
112 UNSPEC_MVST
113
114 ; Stack Smashing Protector
115 UNSPEC_SP_SET
116 UNSPEC_SP_TEST
117
118 ; Split stack support
119 UNSPEC_STACK_CHECK
120
121 ; Test Data Class (TDC)
122 UNSPEC_TDC_INSN
123
124 ; Byte-wise Population Count
125 UNSPEC_POPCNT
126 UNSPEC_COPYSIGN
127
128 ; Load FP Integer
129 UNSPEC_FPINT_FLOOR
130 UNSPEC_FPINT_BTRUNC
131 UNSPEC_FPINT_ROUND
132 UNSPEC_FPINT_CEIL
133 UNSPEC_FPINT_NEARBYINT
134 UNSPEC_FPINT_RINT
135
136 UNSPEC_LCBB
137
138 ; Vector
139 UNSPEC_VEC_SMULT_HI
140 UNSPEC_VEC_UMULT_HI
141 UNSPEC_VEC_SMULT_LO
142 UNSPEC_VEC_SMULT_EVEN
143 UNSPEC_VEC_UMULT_EVEN
144 UNSPEC_VEC_SMULT_ODD
145 UNSPEC_VEC_UMULT_ODD
146
147 UNSPEC_VEC_VMAL
148 UNSPEC_VEC_VMAH
149 UNSPEC_VEC_VMALH
150 UNSPEC_VEC_VMAE
151 UNSPEC_VEC_VMALE
152 UNSPEC_VEC_VMAO
153 UNSPEC_VEC_VMALO
154
155 UNSPEC_VEC_GATHER
156 UNSPEC_VEC_EXTRACT
157 UNSPEC_VEC_INSERT_AND_ZERO
158 UNSPEC_VEC_LOAD_BNDRY
159 UNSPEC_VEC_LOAD_LEN
160 UNSPEC_VEC_LOAD_LEN_R
161 UNSPEC_VEC_MERGEH
162 UNSPEC_VEC_MERGEL
163 UNSPEC_VEC_PACK
164 UNSPEC_VEC_PACK_SATURATE
165 UNSPEC_VEC_PACK_SATURATE_CC
166 UNSPEC_VEC_PACK_SATURATE_GENCC
167 UNSPEC_VEC_PACK_UNSIGNED_SATURATE
168 UNSPEC_VEC_PACK_UNSIGNED_SATURATE_CC
169 UNSPEC_VEC_PACK_UNSIGNED_SATURATE_GENCC
170 UNSPEC_VEC_PERM
171 UNSPEC_VEC_PERMI
172 UNSPEC_VEC_EXTEND
173 UNSPEC_VEC_STORE_LEN
174 UNSPEC_VEC_STORE_LEN_R
175 UNSPEC_VEC_VBPERM
176 UNSPEC_VEC_UNPACKH
177 UNSPEC_VEC_UNPACKH_L
178 UNSPEC_VEC_UNPACKL
179 UNSPEC_VEC_UNPACKL_L
180 UNSPEC_VEC_ADDC
181 UNSPEC_VEC_ADDE_U128
182 UNSPEC_VEC_ADDEC_U128
183 UNSPEC_VEC_AVG
184 UNSPEC_VEC_AVGU
185 UNSPEC_VEC_CHECKSUM
186 UNSPEC_VEC_GFMSUM
187 UNSPEC_VEC_GFMSUM_128
188 UNSPEC_VEC_GFMSUM_ACCUM
189 UNSPEC_VEC_GFMSUM_ACCUM_128
190 UNSPEC_VEC_SET
191
192 UNSPEC_VEC_VSUMG
193 UNSPEC_VEC_VSUMQ
194 UNSPEC_VEC_VSUM
195 UNSPEC_VEC_RL_MASK
196 UNSPEC_VEC_SLL
197 UNSPEC_VEC_SLB
198 UNSPEC_VEC_SLDBYTE
199 UNSPEC_VEC_SLDBIT
200 UNSPEC_VEC_SRDBIT
201 UNSPEC_VEC_SRAL
202 UNSPEC_VEC_SRAB
203 UNSPEC_VEC_SRL
204 UNSPEC_VEC_SRLB
205
206 UNSPEC_VEC_SUBC
207 UNSPEC_VEC_SUBE_U128
208 UNSPEC_VEC_SUBEC_U128
209
210 UNSPEC_VEC_TEST_MASK
211
212 UNSPEC_VEC_VFAE
213 UNSPEC_VEC_VFAECC
214
215 UNSPEC_VEC_VFEE
216 UNSPEC_VEC_VFEECC
217 UNSPEC_VEC_VFENE
218 UNSPEC_VEC_VFENECC
219
220 UNSPEC_VEC_VISTR
221 UNSPEC_VEC_VISTRCC
222
223 UNSPEC_VEC_VSTRC
224 UNSPEC_VEC_VSTRCCC
225
226 UNSPEC_VEC_VSTRS
227 UNSPEC_VEC_VSTRSCC
228
229 UNSPEC_VEC_VCDGB
230 UNSPEC_VEC_VCDLGB
231
232 UNSPEC_VEC_VCGDB
233 UNSPEC_VEC_VCLGDB
234
235 UNSPEC_VEC_VFI
236
237 UNSPEC_VEC_VFLL ; vector fp load lengthened
238 UNSPEC_VEC_VFLR ; vector fp load rounded
239
240 UNSPEC_VEC_VFTCI
241 UNSPEC_VEC_VFTCICC
242
243 UNSPEC_VEC_MSUM
244
245 UNSPEC_VEC_VFMIN
246 UNSPEC_VEC_VFMAX
247
248 UNSPEC_VEC_ELTSWAP
249 ])
250
251 ;;
252 ;; UNSPEC_VOLATILE usage
253 ;;
254
255 (define_c_enum "unspecv" [
256 ; Blockage
257 UNSPECV_BLOCKAGE
258
259 ; TPF Support
260 UNSPECV_TPF_PROLOGUE
261 UNSPECV_TPF_EPILOGUE
262
263 ; Literal pool
264 UNSPECV_POOL
265 UNSPECV_POOL_SECTION
266 UNSPECV_POOL_ALIGN
267 UNSPECV_POOL_ENTRY
268 UNSPECV_MAIN_POOL
269
270 ; TLS support
271 UNSPECV_SET_TP
272
273 ; Atomic Support
274 UNSPECV_CAS
275 UNSPECV_ATOMIC_OP
276
277 ; Non-branch nops used for compare-and-branch adjustments on z10
278 UNSPECV_NOP_LR_0
279 UNSPECV_NOP_LR_1
280
281 ; Hotpatching (unremovable NOPs)
282 UNSPECV_NOP_2_BYTE
283 UNSPECV_NOP_4_BYTE
284 UNSPECV_NOP_6_BYTE
285
286 ; Transactional Execution support
287 UNSPECV_TBEGIN
288 UNSPECV_TBEGIN_TDB
289 UNSPECV_TBEGINC
290 UNSPECV_TEND
291 UNSPECV_TABORT
292 UNSPECV_ETND
293 UNSPECV_NTSTG
294 UNSPECV_PPA
295
296 ; Set and get floating point control register
297 UNSPECV_SFPC
298 UNSPECV_EFPC
299
300 ; Split stack support
301 UNSPECV_SPLIT_STACK_CALL
302
303 UNSPECV_OSC_BREAK
304 ])
305
306 ;;
307 ;; Registers
308 ;;
309
310 ; Registers with special meaning
311
312 (define_constants
313 [
314 ; Sibling call register.
315 (SIBCALL_REGNUM 1)
316 ; A call-clobbered reg which can be used in indirect branch thunks
317 (INDIRECT_BRANCH_THUNK_REGNUM 1)
318 ; Literal pool base register.
319 (BASE_REGNUM 13)
320 ; Return address register.
321 (RETURN_REGNUM 14)
322 ; Stack pointer register.
323 (STACK_REGNUM 15)
324 ; Condition code register.
325 (CC_REGNUM 33)
326 ; Thread local storage pointer register.
327 (TP_REGNUM 36)
328 ])
329
330 ; Hardware register names
331
332 (define_constants
333 [
334 ; General purpose registers
335 (GPR0_REGNUM 0)
336 (GPR1_REGNUM 1)
337 (GPR2_REGNUM 2)
338 (GPR6_REGNUM 6)
339 ; Floating point registers.
340 (FPR0_REGNUM 16)
341 (FPR1_REGNUM 20)
342 (FPR2_REGNUM 17)
343 (FPR3_REGNUM 21)
344 (FPR4_REGNUM 18)
345 (FPR5_REGNUM 22)
346 (FPR6_REGNUM 19)
347 (FPR7_REGNUM 23)
348 (FPR8_REGNUM 24)
349 (FPR9_REGNUM 28)
350 (FPR10_REGNUM 25)
351 (FPR11_REGNUM 29)
352 (FPR12_REGNUM 26)
353 (FPR13_REGNUM 30)
354 (FPR14_REGNUM 27)
355 (FPR15_REGNUM 31)
356 (VR0_REGNUM 16)
357 (VR16_REGNUM 38)
358 (VR23_REGNUM 45)
359 (VR24_REGNUM 46)
360 (VR31_REGNUM 53)
361 ])
362
363 ; Rounding modes for binary floating point numbers
364 (define_constants
365 [(BFP_RND_CURRENT 0)
366 (BFP_RND_NEAREST_TIE_AWAY_FROM_0 1)
367 (BFP_RND_PREP_FOR_SHORT_PREC 3)
368 (BFP_RND_NEAREST_TIE_TO_EVEN 4)
369 (BFP_RND_TOWARD_0 5)
370 (BFP_RND_TOWARD_INF 6)
371 (BFP_RND_TOWARD_MINF 7)])
372
373 ; Rounding modes for decimal floating point numbers
374 ; 1-7 were introduced with the floating point extension facility
375 ; available with z196
376 ; With these rounding modes (1-7) a quantum exception might occur
377 ; which is suppressed for the other modes.
378 (define_constants
379 [(DFP_RND_CURRENT 0)
380 (DFP_RND_NEAREST_TIE_AWAY_FROM_0_QUANTEXC 1)
381 (DFP_RND_CURRENT_QUANTEXC 2)
382 (DFP_RND_PREP_FOR_SHORT_PREC_QUANTEXC 3)
383 (DFP_RND_NEAREST_TIE_TO_EVEN_QUANTEXC 4)
384 (DFP_RND_TOWARD_0_QUANTEXC 5)
385 (DFP_RND_TOWARD_INF_QUANTEXC 6)
386 (DFP_RND_TOWARD_MINF_QUANTEXC 7)
387 (DFP_RND_NEAREST_TIE_TO_EVEN 8)
388 (DFP_RND_TOWARD_0 9)
389 (DFP_RND_TOWARD_INF 10)
390 (DFP_RND_TOWARD_MINF 11)
391 (DFP_RND_NEAREST_TIE_AWAY_FROM_0 12)
392 (DFP_RND_NEAREST_TIE_TO_0 13)
393 (DFP_RND_AWAY_FROM_0 14)
394 (DFP_RND_PREP_FOR_SHORT_PREC 15)])
395
396 ;;
397 ;; PFPO GPR0 argument format
398 ;;
399
400 (define_constants
401 [
402 ; PFPO operation type
403 (PFPO_CONVERT 0x1000000)
404 ; PFPO operand types
405 (PFPO_OP_TYPE_SF 0x5)
406 (PFPO_OP_TYPE_DF 0x6)
407 (PFPO_OP_TYPE_TF 0x7)
408 (PFPO_OP_TYPE_SD 0x8)
409 (PFPO_OP_TYPE_DD 0x9)
410 (PFPO_OP_TYPE_TD 0xa)
411 ; Bitposition of operand types
412 (PFPO_OP0_TYPE_SHIFT 16)
413 (PFPO_OP1_TYPE_SHIFT 8)
414 ; Decide whether current DFP or BFD rounding mode should be used
415 ; for the conversion.
416 (PFPO_RND_MODE_DFP 0)
417 (PFPO_RND_MODE_BFP 1)
418 ])
419
420 ;; PPA constants
421
422 ; Immediate values which can be used as the third operand to the
423 ; perform processor assist instruction
424
425 (define_constants
426 [(PPA_TX_ABORT 1)
427 (PPA_OOO_BARRIER 15)])
428
429 ; Immediate operands for tbegin and tbeginc
430 (define_constants [(TBEGIN_MASK 65292)]) ; 0xff0c
431 (define_constants [(TBEGINC_MASK 65288)]) ; 0xff08
432
433 ;; Instruction operand type as used in the Principles of Operation.
434 ;; Used to determine defaults for length and other attribute values.
435
436 (define_attr "op_type"
437 "NN,E,RR,RRE,RX,RS,RSI,RI,SI,S,SS,SSE,RXE,RSE,RIL,RIE,RXY,RSY,SIY,RRF,SIL,RRS,RIS,VRI,VRR,VRS,VRV,VRX,VSI"
438 (const_string "NN"))
439
440 ;; Instruction type attribute used for scheduling.
441
442 (define_attr "type" "none,integer,load,lr,la,larl,lm,stm,
443 cs,vs,store,sem,idiv,
444 imulhi,imulsi,imuldi,
445 branch,jsr,fsimptf,fsimpdf,fsimpsf,fhex,
446 floadtf,floaddf,floadsf,fstoredf,fstoresf,
447 fmultf,fmuldf,fmulsf,fdivtf,fdivdf,fdivsf,
448 ftoi,fsqrttf,fsqrtdf,fsqrtsf,
449 fmadddf,fmaddsf,
450 ftrunctf,ftruncdf, ftruncsd, ftruncdd,
451 itoftf, itofdf, itofsf, itofdd, itoftd,
452 fdivdd, fdivtd, floaddd, floadsd, fmuldd, fmultd,
453 fsimpdd, fsimpsd, fsimptd, fstoredd, fstoresd,
454 ftoidfp, other"
455 (cond [(eq_attr "op_type" "NN") (const_string "other")
456 (eq_attr "op_type" "SS") (const_string "cs")]
457 (const_string "integer")))
458
459 ;; Another attribute used for scheduling purposes:
460 ;; agen: Instruction uses the address generation unit
461 ;; reg: Instruction does not use the agen unit
462
463 (define_attr "atype" "agen,reg"
464 (if_then_else (eq_attr "op_type" "E,RR,RI,RRE,RSI,RIL,RIE,RRF")
465 (const_string "reg")
466 (const_string "agen")))
467
468 ;; Properties concerning Z10 execution grouping and value forwarding.
469 ;; z10_super: instruction is superscalar.
470 ;; z10_super_c: instruction is superscalar and meets the condition of z10_c.
471 ;; z10_fwd: The instruction reads the value of an operand and stores it into a
472 ;; target register. It can forward this value to a second instruction that reads
473 ;; the same register if that second instruction is issued in the same group.
474 ;; z10_rec: The instruction is in the T pipeline and reads a register. If the
475 ;; instruction in the S pipe writes to the register, then the T instruction
476 ;; can immediately read the new value.
477 ;; z10_fr: union of Z10_fwd and z10_rec.
478 ;; z10_c: second operand of instruction is a register and read with complemented bits.
479 ;;
480 ;; An additional suffix A1, A3, or E1 indicates the respective AGI bypass.
481
482
483 (define_attr "z10prop" "none,
484 z10_super, z10_super_E1, z10_super_A1, z10_super_c, z10_super_c_E1,
485 z10_fwd, z10_fwd_A1, z10_fwd_A3, z10_fwd_E1,
486 z10_rec,
487 z10_fr, z10_fr_A3, z10_fr_E1,
488 z10_c"
489 (const_string "none"))
490
491 ;; Properties concerning Z196 decoding
492 ;; z196_alone: must group alone
493 ;; z196_end: ends a group
494 ;; z196_cracked: instruction is cracked or expanded
495 (define_attr "z196prop" "none,
496 z196_alone, z196_ends,
497 z196_cracked"
498 (const_string "none"))
499
500 ; mnemonics which only get defined through if_then_else currently
501 ; don't get added to the list values automatically and hence need to
502 ; be listed here.
503 (define_attr "mnemonic" "b,bas,basr,bc,bcr_flush,unknown" (const_string "unknown"))
504
505 ;; Length in bytes.
506
507 (define_attr "length" ""
508 (cond [(eq_attr "op_type" "E,RR") (const_int 2)
509 (eq_attr "op_type" "RX,RI,RRE,RS,RSI,S,SI,RRF") (const_int 4)]
510 (const_int 6)))
511
512
513 ;; Processor type. This attribute must exactly match the processor_type
514 ;; enumeration in s390.h.
515
516 (define_attr "cpu" "z900,z990,z9_109,z9_ec,z10,z196,zEC12,z13,z14,z15"
517 (const (symbol_ref "s390_tune_attr")))
518
519 (define_attr "cpu_facility"
520 "standard,ieee,zarch,cpu_zarch,longdisp,extimm,dfp,z10,z196,zEC12,vx,z13,z14,vxe,z15,vxe2"
521 (const_string "standard"))
522
523 (define_attr "enabled" ""
524 (cond [(eq_attr "cpu_facility" "standard")
525 (const_int 1)
526
527 (and (eq_attr "cpu_facility" "ieee")
528 (match_test "TARGET_CPU_IEEE_FLOAT"))
529 (const_int 1)
530
531 (and (eq_attr "cpu_facility" "zarch")
532 (match_test "TARGET_ZARCH"))
533 (const_int 1)
534
535 (and (eq_attr "cpu_facility" "longdisp")
536 (match_test "TARGET_LONG_DISPLACEMENT"))
537 (const_int 1)
538
539 (and (eq_attr "cpu_facility" "extimm")
540 (match_test "TARGET_EXTIMM"))
541 (const_int 1)
542
543 (and (eq_attr "cpu_facility" "dfp")
544 (match_test "TARGET_DFP"))
545 (const_int 1)
546
547 (eq_attr "cpu_facility" "cpu_zarch")
548 (const_int 1)
549
550 (and (eq_attr "cpu_facility" "z10")
551 (match_test "TARGET_Z10"))
552 (const_int 1)
553
554 (and (eq_attr "cpu_facility" "z196")
555 (match_test "TARGET_Z196"))
556 (const_int 1)
557
558 (and (eq_attr "cpu_facility" "zEC12")
559 (match_test "TARGET_ZEC12"))
560 (const_int 1)
561
562 (and (eq_attr "cpu_facility" "vx")
563 (match_test "TARGET_VX"))
564 (const_int 1)
565
566 (and (eq_attr "cpu_facility" "z13")
567 (match_test "TARGET_Z13"))
568 (const_int 1)
569
570 (and (eq_attr "cpu_facility" "z14")
571 (match_test "TARGET_Z14"))
572 (const_int 1)
573
574 (and (eq_attr "cpu_facility" "vxe")
575 (match_test "TARGET_VXE"))
576 (const_int 1)
577
578 (and (eq_attr "cpu_facility" "z15")
579 (match_test "TARGET_Z15"))
580 (const_int 1)
581
582 (and (eq_attr "cpu_facility" "vxe2")
583 (match_test "TARGET_VXE2"))
584 (const_int 1)
585 ]
586 (const_int 0)))
587
588 ;; Whether an instruction supports relative long addressing.
589 ;; Currently this corresponds to RIL-b and RIL-c instruction formats,
590 ;; but having a separate attribute, as opposed to reusing op_type,
591 ;; provides additional flexibility.
592
593 (define_attr "relative_long" "no,yes" (const_string "no"))
594
595 ;; Pipeline description for z900.
596 (include "2064.md")
597
598 ;; Pipeline description for z990, z9-109 and z9-ec.
599 (include "2084.md")
600
601 ;; Pipeline description for z10
602 (include "2097.md")
603
604 ;; Pipeline description for z196
605 (include "2817.md")
606
607 ;; Pipeline description for zEC12
608 (include "2827.md")
609
610 ;; Pipeline description for z13
611 (include "2964.md")
612
613 ;; Pipeline description for z14
614 (include "3906.md")
615
616 ;; Pipeline description for z15
617 (include "8561.md")
618
619 ;; Predicates
620 (include "predicates.md")
621
622 ;; Constraint definitions
623 (include "constraints.md")
624
625 ;; Other includes
626 (include "tpf.md")
627
628 ;; Iterators
629
630 (define_mode_iterator ALL [TI DI SI HI QI TF DF SF TD DD SD V1QI V2QI V4QI V8QI V16QI V1HI V2HI V4HI V8HI V1SI V2SI V4SI V1DI V2DI V1SF V2SF V4SF V1TI V1DF V2DF V1TF])
631
632 ;; These mode iterators allow floating point patterns to be generated from the
633 ;; same template.
634 (define_mode_iterator FP_ALL [TF DF SF (TD "TARGET_HARD_DFP") (DD "TARGET_HARD_DFP")
635 (SD "TARGET_HARD_DFP")])
636 (define_mode_iterator FP [TF DF SF (TD "TARGET_HARD_DFP") (DD "TARGET_HARD_DFP")])
637 (define_mode_iterator BFP [TF DF SF])
638 (define_mode_iterator DFP [TD DD])
639 (define_mode_iterator DFP_ALL [TD DD SD])
640 (define_mode_iterator DSF [DF SF])
641 (define_mode_iterator SD_SF [SF SD])
642 (define_mode_iterator DD_DF [DF DD])
643 (define_mode_iterator TD_TF [TF TD])
644
645 ; 32 bit int<->fp conversion instructions are available since VXE2 (z15).
646 (define_mode_iterator VX_CONV_BFP [DF (SF "TARGET_VXE2")])
647 (define_mode_iterator VX_CONV_INT [DI (SI "TARGET_VXE2")])
648
649 ;; These mode iterators allow 31-bit and 64-bit GPR patterns to be generated
650 ;; from the same template.
651 (define_mode_iterator GPR [(DI "TARGET_ZARCH") SI])
652 (define_mode_iterator DGPR [(TI "TARGET_ZARCH") DI SI])
653 (define_mode_iterator DSI [DI SI])
654 (define_mode_iterator TDI [TI DI])
655
656 ;; These mode iterators allow :P to be used for patterns that operate on
657 ;; pointer-sized quantities. Exactly one of the two alternatives will match.
658 (define_mode_iterator P [(DI "TARGET_64BIT") (SI "!TARGET_64BIT")])
659
660 ;; These macros refer to the actual word_mode of the configuration.
661 ;; This is equal to Pmode except on 31-bit machines in zarch mode.
662 (define_mode_iterator DW [(TI "TARGET_ZARCH") (DI "!TARGET_ZARCH")])
663 (define_mode_iterator W [(DI "TARGET_ZARCH") (SI "!TARGET_ZARCH")])
664
665 ;; Used by the umul pattern to express modes having half the size.
666 (define_mode_attr DWH [(TI "DI") (DI "SI")])
667 (define_mode_attr dwh [(TI "di") (DI "si")])
668
669 ;; This mode iterator allows the QI and HI patterns to be defined from
670 ;; the same template.
671 (define_mode_iterator HQI [HI QI])
672
673 ;; This mode iterator allows the integer patterns to be defined from the
674 ;; same template.
675 (define_mode_iterator INT [(DI "TARGET_ZARCH") SI HI QI])
676 (define_mode_iterator DINT [(TI "TARGET_ZARCH") DI SI HI QI])
677 (define_mode_iterator SINT [SI HI QI])
678
679 ;; This iterator allows some 'ashift' and 'lshiftrt' pattern to be defined from
680 ;; the same template.
681 (define_code_iterator SHIFT [ashift lshiftrt])
682
683 ;; This iterator allows r[ox]sbg to be defined with the same template
684 (define_code_iterator IXOR [ior xor])
685
686 ;; This is used for merging the nand/nor and and/or with complement patterns
687 (define_code_iterator ANDOR [and ior])
688 (define_code_attr bitops_name [(and "and") (ior "or")])
689 (define_code_attr inv_bitops_name [(and "or") (ior "and")])
690 (define_code_attr inv_no [(and "o") (ior "n")])
691
692 ;; This iterator is used to expand the patterns for the nearest
693 ;; integer functions.
694 (define_int_iterator FPINT [UNSPEC_FPINT_FLOOR UNSPEC_FPINT_BTRUNC
695 UNSPEC_FPINT_ROUND UNSPEC_FPINT_CEIL
696 UNSPEC_FPINT_NEARBYINT])
697 (define_int_attr fpint_name [(UNSPEC_FPINT_FLOOR "floor")
698 (UNSPEC_FPINT_BTRUNC "btrunc")
699 (UNSPEC_FPINT_ROUND "round")
700 (UNSPEC_FPINT_CEIL "ceil")
701 (UNSPEC_FPINT_NEARBYINT "nearbyint")])
702 (define_int_attr fpint_roundingmode [(UNSPEC_FPINT_FLOOR "7")
703 (UNSPEC_FPINT_BTRUNC "5")
704 (UNSPEC_FPINT_ROUND "1")
705 (UNSPEC_FPINT_CEIL "6")
706 (UNSPEC_FPINT_NEARBYINT "0")])
707
708 ;; This iterator and attribute allow to combine most atomic operations.
709 (define_code_iterator ATOMIC [and ior xor plus minus mult])
710 (define_code_iterator ATOMIC_Z196 [and ior xor plus])
711 (define_code_attr atomic [(and "and") (ior "or") (xor "xor")
712 (plus "add") (minus "sub") (mult "nand")])
713 (define_code_attr noxa [(and "n") (ior "o") (xor "x") (plus "a")])
714
715 ;; In FP templates, a string like "lt<de>br" will expand to "ltxbr" in
716 ;; TF/TDmode, "ltdbr" in DF/DDmode, and "ltebr" in SF/SDmode.
717 (define_mode_attr xde [(TF "x") (DF "d") (SF "e") (TD "x") (DD "d") (SD "e") (V4SF "e") (V2DF "d")])
718
719 ;; In FP templates, a <dee> in "m<dee><bt>r" will expand to "mx<bt>r" in
720 ;; TF/TDmode, "md<bt>r" in DF/DDmode, "mee<bt>r" in SFmode and "me<bt>r in
721 ;; SDmode.
722 (define_mode_attr xdee [(TF "x") (DF "d") (SF "ee") (TD "x") (DD "d") (SD "e")])
723
724 ;; In FP templates, "<RRe>" will expand to "RRE" in TFmode and "RR" otherwise.
725 ;; Likewise for "<RXe>".
726 (define_mode_attr RRe [(TF "RRE") (DF "RR") (SF "RR")])
727 (define_mode_attr RXe [(TF "RXE") (DF "RX") (SF "RX")])
728
729 ;; The decimal floating point variants of add, sub, div and mul support 3
730 ;; fp register operands. The following attributes allow to merge the bfp and
731 ;; dfp variants in a single insn definition.
732
733 ;; These mode attributes are supposed to be used in the `enabled' insn
734 ;; attribute to disable certain alternatives for certain modes.
735 (define_mode_attr nBFP [(TF "0") (DF "0") (SF "0") (TD "*") (DD "*") (DD "*")])
736 (define_mode_attr nDFP [(TF "*") (DF "*") (SF "*") (TD "0") (DD "0") (DD "0")])
737 (define_mode_attr DSF [(TF "0") (DF "*") (SF "*") (TD "0") (DD "0") (SD "0")])
738 (define_mode_attr DFDI [(TF "0") (DF "*") (SF "0")
739 (TD "0") (DD "0") (DD "0")
740 (TI "0") (DI "*") (SI "0")])
741 (define_mode_attr SFSI [(TF "0") (DF "0") (SF "*")
742 (TD "0") (DD "0") (DD "0")
743 (TI "0") (DI "0") (SI "*")])
744 (define_mode_attr DF [(TF "0") (DF "*") (SF "0")
745 (TD "0") (DD "0") (DD "0")
746 (TI "0") (DI "0") (SI "0")])
747 (define_mode_attr SF [(TF "0") (DF "0") (SF "*")
748 (TD "0") (DD "0") (DD "0")
749 (TI "0") (DI "0") (SI "0")])
750
751 ;; This attribute is used in the operand constraint list
752 ;; for instructions dealing with the sign bit of 32 or 64bit fp values.
753 ;; TFmode values are represented by a fp register pair. Since the
754 ;; sign bit instructions only handle single source and target fp registers
755 ;; these instructions can only be used for TFmode values if the source and
756 ;; target operand uses the same fp register.
757 (define_mode_attr fT0 [(TF "0") (DF "f") (SF "f")])
758
759 ;; This attribute adds b for bfp instructions and t for dfp instructions and is used
760 ;; within instruction mnemonics.
761 (define_mode_attr bt [(TF "b") (DF "b") (SF "b") (TD "t") (DD "t") (SD "t")])
762
763 ;; This attribute is used within instruction mnemonics. It evaluates to d for dfp
764 ;; modes and to an empty string for bfp modes.
765 (define_mode_attr _d [(TF "") (DF "") (SF "") (TD "d") (DD "d") (SD "d")])
766
767 ;; In GPR and P templates, a constraint like "<d0>" will expand to "d" in DImode
768 ;; and "0" in SImode. This allows to combine instructions of which the 31bit
769 ;; version only operates on one register.
770 (define_mode_attr d0 [(DI "d") (SI "0")])
771
772 ;; In combination with d0 this allows to combine instructions of which the 31bit
773 ;; version only operates on one register. The DImode version needs an additional
774 ;; register for the assembler output.
775 (define_mode_attr 1 [(DI "%1,") (SI "")])
776
777 ;; In SHIFT templates, a string like "s<lr>dl" will expand to "sldl" in
778 ;; 'ashift' and "srdl" in 'lshiftrt'.
779 (define_code_attr lr [(ashift "l") (lshiftrt "r")])
780
781 ;; In SHIFT templates, this attribute holds the correct standard name for the
782 ;; pattern itself and the corresponding function calls.
783 (define_code_attr shift [(ashift "ashl") (lshiftrt "lshr")])
784
785 ;; This attribute handles differences in the instruction 'type' and will result
786 ;; in "RRE" for DImode and "RR" for SImode.
787 (define_mode_attr E [(DI "E") (SI "")])
788
789 ;; This attribute handles differences in the instruction 'type' and makes RX<Y>
790 ;; to result in "RXY" for DImode and "RX" for SImode.
791 (define_mode_attr Y [(DI "Y") (SI "")])
792
793 ;; This attribute handles differences in the instruction 'type' and will result
794 ;; in "RSE" for TImode and "RS" for DImode.
795 (define_mode_attr TE [(TI "E") (DI "")])
796
797 ;; In GPR templates, a string like "lc<g>r" will expand to "lcgr" in DImode
798 ;; and "lcr" in SImode.
799 (define_mode_attr g [(DI "g") (SI "")])
800
801 ;; In GPR templates, a string like "sl<y>" will expand to "slg" in DImode
802 ;; and "sly" in SImode. This is useful because on 64bit the ..g instructions
803 ;; were enhanced with long displacements whereas 31bit instructions got a ..y
804 ;; variant for long displacements.
805 (define_mode_attr y [(DI "g") (SI "y")])
806
807 ;; In DW templates, a string like "cds<g>" will expand to "cdsg" in TImode
808 ;; and "cds" in DImode.
809 (define_mode_attr tg [(TI "g") (DI "")])
810
811 ;; In TDI templates, a string like "c<d>sg".
812 (define_mode_attr td [(TI "d") (DI "")])
813
814 ;; In GPR templates, a string like "c<gf>dbr" will expand to "cgdbr" in DImode
815 ;; and "cfdbr" in SImode.
816 (define_mode_attr gf [(DI "g") (SI "f")])
817
818 ;; In GPR templates, a string like sll<gk> will expand to sllg for DI
819 ;; and sllk for SI. This way it is possible to merge the new z196 SI
820 ;; 3 operands shift instructions into the existing patterns.
821 (define_mode_attr gk [(DI "g") (SI "k")])
822
823 ;; ICM mask required to load MODE value into the lowest subreg
824 ;; of a SImode register.
825 (define_mode_attr icm_lo [(HI "3") (QI "1")])
826
827 ;; In HQI templates, a string like "llg<hc>" will expand to "llgh" in
828 ;; HImode and "llgc" in QImode.
829 (define_mode_attr hc [(HI "h") (QI "c")])
830
831 ;; In P templates, the mode <DBL> will expand to "TI" in DImode and "DI"
832 ;; in SImode.
833 (define_mode_attr DBL [(DI "TI") (SI "DI")])
834
835 ;; This attribute expands to DF for TFmode and to DD for TDmode . It is
836 ;; used for Txmode splitters splitting a Txmode copy into 2 Dxmode copies.
837 (define_mode_attr HALF_TMODE [(TF "DF") (TD "DD")])
838
839 ;; Maximum unsigned integer that fits in MODE.
840 (define_mode_attr max_uint [(HI "65535") (QI "255")])
841
842 ;; Start and end field computations for RISBG et al.
843 (define_mode_attr bfstart [(DI "s") (SI "t")])
844 (define_mode_attr bfend [(DI "e") (SI "f")])
845
846 ;; In place of GET_MODE_BITSIZE (<MODE>mode)
847 (define_mode_attr bitsize [(DI "64") (SI "32") (HI "16") (QI "8")])
848 ;; 64 - bitsize
849 (define_mode_attr bitoff [(DI "0") (SI "32") (HI "48") (QI "56")])
850 (define_mode_attr bitoff_plus [(DI "") (SI "32+") (HI "48+") (QI "56+")])
851
852 ;; In place of GET_MODE_SIZE (<MODE>mode)
853 (define_mode_attr modesize [(DI "8") (SI "4")])
854
855 ;; Allow return and simple_return to be defined from a single template.
856 (define_code_iterator ANY_RETURN [return simple_return])
857
858
859
860 ; Condition code modes generated by vector fp comparisons. These will
861 ; be used also in single element mode.
862 (define_mode_iterator VFCMP [CCVEQ CCVFH CCVFHE])
863 ; Used with VFCMP to expand part of the mnemonic
864 ; For fp we have a mismatch: eq in the insn name - e in asm
865 (define_mode_attr asm_fcmp [(CCVEQ "e") (CCVFH "h") (CCVFHE "he")])
866 (define_mode_attr insn_cmp [(CCVEQ "eq") (CCVIH "h") (CCVIHU "hl") (CCVFH "h") (CCVFHE "he")])
867
868 ;; Subst pattern definitions
869 (include "subst.md")
870
871 (include "vector.md")
872
873 ;;
874 ;;- Compare instructions.
875 ;;
876
877 ; Test-under-Mask instructions
878
879 (define_insn "*tmqi_mem"
880 [(set (reg CC_REGNUM)
881 (compare (and:QI (match_operand:QI 0 "memory_operand" "Q,S")
882 (match_operand:QI 1 "immediate_operand" "n,n"))
883 (match_operand:QI 2 "immediate_operand" "n,n")))]
884 "s390_match_ccmode (insn, s390_tm_ccmode (operands[1], operands[2], false))"
885 "@
886 tm\t%S0,%b1
887 tmy\t%S0,%b1"
888 [(set_attr "op_type" "SI,SIY")
889 (set_attr "cpu_facility" "*,longdisp")
890 (set_attr "z10prop" "z10_super,z10_super")])
891
892 (define_insn "*tmdi_reg"
893 [(set (reg CC_REGNUM)
894 (compare (and:DI (match_operand:DI 0 "nonimmediate_operand" "d,d,d,d")
895 (match_operand:DI 1 "immediate_operand"
896 "N0HD0,N1HD0,N2HD0,N3HD0"))
897 (match_operand:DI 2 "immediate_operand" "n,n,n,n")))]
898 "TARGET_ZARCH
899 && s390_match_ccmode (insn, s390_tm_ccmode (operands[1], operands[2], true))
900 && s390_single_part (operands[1], DImode, HImode, 0) >= 0"
901 "@
902 tmhh\t%0,%i1
903 tmhl\t%0,%i1
904 tmlh\t%0,%i1
905 tmll\t%0,%i1"
906 [(set_attr "op_type" "RI")
907 (set_attr "z10prop" "z10_super,z10_super,z10_super,z10_super")])
908
909 (define_insn "*tmsi_reg"
910 [(set (reg CC_REGNUM)
911 (compare (and:SI (match_operand:SI 0 "nonimmediate_operand" "d,d")
912 (match_operand:SI 1 "immediate_operand" "N0HS0,N1HS0"))
913 (match_operand:SI 2 "immediate_operand" "n,n")))]
914 "s390_match_ccmode (insn, s390_tm_ccmode (operands[1], operands[2], true))
915 && s390_single_part (operands[1], SImode, HImode, 0) >= 0"
916 "@
917 tmh\t%0,%i1
918 tml\t%0,%i1"
919 [(set_attr "op_type" "RI")
920 (set_attr "z10prop" "z10_super,z10_super")])
921
922 (define_insn "*tm<mode>_full"
923 [(set (reg CC_REGNUM)
924 (compare (match_operand:HQI 0 "register_operand" "d")
925 (match_operand:HQI 1 "immediate_operand" "n")))]
926 "s390_match_ccmode (insn, s390_tm_ccmode (constm1_rtx, operands[1], true))"
927 "tml\t%0,<max_uint>"
928 [(set_attr "op_type" "RI")
929 (set_attr "z10prop" "z10_super")])
930
931
932 ;
933 ; Load-and-Test instructions
934 ;
935
936 ; tst(di|si) instruction pattern(s).
937
938 (define_insn "*tstdi_sign"
939 [(set (reg CC_REGNUM)
940 (compare
941 (ashiftrt:DI
942 (ashift:DI
943 (subreg:DI (match_operand:SI 0 "nonimmediate_operand" "d,T") 0)
944 (const_int 32)) (const_int 32))
945 (match_operand:DI 1 "const0_operand" "")))
946 (set (match_operand:DI 2 "register_operand" "=d,d")
947 (sign_extend:DI (match_dup 0)))]
948 "s390_match_ccmode(insn, CCSmode) && TARGET_ZARCH"
949 "ltgfr\t%2,%0
950 ltgf\t%2,%0"
951 [(set_attr "op_type" "RRE,RXY")
952 (set_attr "cpu_facility" "*,z10")
953 (set_attr "z10prop" "z10_super_E1,z10_super_E1") ])
954
955 ; ltr, lt, ltgr, ltg
956 (define_insn "*tst<mode>_extimm"
957 [(set (reg CC_REGNUM)
958 (compare (match_operand:GPR 0 "nonimmediate_operand" "d,T")
959 (match_operand:GPR 1 "const0_operand" "")))
960 (set (match_operand:GPR 2 "register_operand" "=d,d")
961 (match_dup 0))]
962 "s390_match_ccmode(insn, CCSmode) && TARGET_EXTIMM"
963 "@
964 lt<g>r\t%2,%0
965 lt<g>\t%2,%0"
966 [(set_attr "op_type" "RR<E>,RXY")
967 (set_attr "z10prop" "z10_fr_E1,z10_fwd_A3") ])
968
969 ; Peephole to combine a load-and-test from volatile memory which combine does
970 ; not do.
971 (define_peephole2
972 [(set (match_operand:GPR 0 "register_operand")
973 (match_operand:GPR 2 "memory_operand"))
974 (set (reg CC_REGNUM)
975 (compare (match_dup 0) (match_operand:GPR 1 "const0_operand")))]
976 "s390_match_ccmode(insn, CCSmode) && TARGET_EXTIMM
977 && GENERAL_REG_P (operands[0])
978 && satisfies_constraint_T (operands[2])
979 && !contains_constant_pool_address_p (operands[2])"
980 [(parallel
981 [(set (reg:CCS CC_REGNUM)
982 (compare:CCS (match_dup 2) (match_dup 1)))
983 (set (match_dup 0) (match_dup 2))])])
984
985 ; ltr, lt, ltgr, ltg
986 (define_insn "*tst<mode>_cconly_extimm"
987 [(set (reg CC_REGNUM)
988 (compare (match_operand:GPR 0 "nonimmediate_operand" "d,T")
989 (match_operand:GPR 1 "const0_operand" "")))
990 (clobber (match_scratch:GPR 2 "=X,d"))]
991 "s390_match_ccmode(insn, CCSmode) && TARGET_EXTIMM"
992 "@
993 lt<g>r\t%0,%0
994 lt<g>\t%2,%0"
995 [(set_attr "op_type" "RR<E>,RXY")
996 (set_attr "z10prop" "z10_fr_E1,z10_fwd_A3")])
997
998 (define_insn "*tstdi"
999 [(set (reg CC_REGNUM)
1000 (compare (match_operand:DI 0 "register_operand" "d")
1001 (match_operand:DI 1 "const0_operand" "")))
1002 (set (match_operand:DI 2 "register_operand" "=d")
1003 (match_dup 0))]
1004 "s390_match_ccmode(insn, CCSmode) && TARGET_ZARCH && !TARGET_EXTIMM"
1005 "ltgr\t%2,%0"
1006 [(set_attr "op_type" "RRE")
1007 (set_attr "z10prop" "z10_fr_E1")])
1008
1009 (define_insn "*tstsi"
1010 [(set (reg CC_REGNUM)
1011 (compare (match_operand:SI 0 "nonimmediate_operand" "d,Q,S")
1012 (match_operand:SI 1 "const0_operand" "")))
1013 (set (match_operand:SI 2 "register_operand" "=d,d,d")
1014 (match_dup 0))]
1015 "s390_match_ccmode(insn, CCSmode) && !TARGET_EXTIMM"
1016 "@
1017 ltr\t%2,%0
1018 icm\t%2,15,%S0
1019 icmy\t%2,15,%S0"
1020 [(set_attr "op_type" "RR,RS,RSY")
1021 (set_attr "cpu_facility" "*,*,longdisp")
1022 (set_attr "z10prop" "z10_fr_E1,z10_super_E1,z10_super_E1")])
1023
1024 (define_insn "*tstsi_cconly"
1025 [(set (reg CC_REGNUM)
1026 (compare (match_operand:SI 0 "nonimmediate_operand" "d,Q,S")
1027 (match_operand:SI 1 "const0_operand" "")))
1028 (clobber (match_scratch:SI 2 "=X,d,d"))]
1029 "s390_match_ccmode(insn, CCSmode)"
1030 "@
1031 ltr\t%0,%0
1032 icm\t%2,15,%S0
1033 icmy\t%2,15,%S0"
1034 [(set_attr "op_type" "RR,RS,RSY")
1035 (set_attr "cpu_facility" "*,*,longdisp")
1036 (set_attr "z10prop" "z10_fr_E1,z10_super_E1,z10_super_E1")])
1037
1038 (define_insn "*tstdi_cconly_31"
1039 [(set (reg CC_REGNUM)
1040 (compare (match_operand:DI 0 "register_operand" "d")
1041 (match_operand:DI 1 "const0_operand" "")))]
1042 "s390_match_ccmode(insn, CCSmode) && !TARGET_ZARCH"
1043 "srda\t%0,0"
1044 [(set_attr "op_type" "RS")
1045 (set_attr "atype" "reg")])
1046
1047 ; ltr, ltgr
1048 (define_insn "*tst<mode>_cconly2"
1049 [(set (reg CC_REGNUM)
1050 (compare (match_operand:GPR 0 "register_operand" "d")
1051 (match_operand:GPR 1 "const0_operand" "")))]
1052 "s390_match_ccmode(insn, CCSmode)"
1053 "lt<g>r\t%0,%0"
1054 [(set_attr "op_type" "RR<E>")
1055 (set_attr "z10prop" "z10_fr_E1")])
1056
1057 ; tst(hi|qi) instruction pattern(s).
1058
1059 (define_insn "*tst<mode>CCT"
1060 [(set (reg CC_REGNUM)
1061 (compare (match_operand:HQI 0 "nonimmediate_operand" "?Q,?S,d")
1062 (match_operand:HQI 1 "const0_operand" "")))
1063 (set (match_operand:HQI 2 "register_operand" "=d,d,0")
1064 (match_dup 0))]
1065 "s390_match_ccmode(insn, CCTmode)"
1066 "@
1067 icm\t%2,<icm_lo>,%S0
1068 icmy\t%2,<icm_lo>,%S0
1069 tml\t%0,<max_uint>"
1070 [(set_attr "op_type" "RS,RSY,RI")
1071 (set_attr "cpu_facility" "*,longdisp,*")
1072 (set_attr "z10prop" "z10_super_E1,z10_super_E1,z10_super")])
1073
1074 (define_insn "*tsthiCCT_cconly"
1075 [(set (reg CC_REGNUM)
1076 (compare (match_operand:HI 0 "nonimmediate_operand" "Q,S,d")
1077 (match_operand:HI 1 "const0_operand" "")))
1078 (clobber (match_scratch:HI 2 "=d,d,X"))]
1079 "s390_match_ccmode(insn, CCTmode)"
1080 "@
1081 icm\t%2,3,%S0
1082 icmy\t%2,3,%S0
1083 tml\t%0,65535"
1084 [(set_attr "op_type" "RS,RSY,RI")
1085 (set_attr "cpu_facility" "*,longdisp,*")
1086 (set_attr "z10prop" "z10_super_E1,z10_super_E1,z10_super")])
1087
1088 (define_insn "*tstqiCCT_cconly"
1089 [(set (reg CC_REGNUM)
1090 (compare (match_operand:QI 0 "nonimmediate_operand" "?Q,?S,d")
1091 (match_operand:QI 1 "const0_operand" "")))]
1092 "s390_match_ccmode(insn, CCTmode)"
1093 "@
1094 cli\t%S0,0
1095 cliy\t%S0,0
1096 tml\t%0,255"
1097 [(set_attr "op_type" "SI,SIY,RI")
1098 (set_attr "cpu_facility" "*,longdisp,*")
1099 (set_attr "z10prop" "z10_super,z10_super,z10_super")])
1100
1101 (define_insn "*tst<mode>"
1102 [(set (reg CC_REGNUM)
1103 (compare (match_operand:HQI 0 "s_operand" "Q,S")
1104 (match_operand:HQI 1 "const0_operand" "")))
1105 (set (match_operand:HQI 2 "register_operand" "=d,d")
1106 (match_dup 0))]
1107 "s390_match_ccmode(insn, CCSmode)"
1108 "@
1109 icm\t%2,<icm_lo>,%S0
1110 icmy\t%2,<icm_lo>,%S0"
1111 [(set_attr "op_type" "RS,RSY")
1112 (set_attr "cpu_facility" "*,longdisp")
1113 (set_attr "z10prop" "z10_super_E1,z10_super_E1")])
1114
1115 (define_insn "*tst<mode>_cconly"
1116 [(set (reg CC_REGNUM)
1117 (compare (match_operand:HQI 0 "s_operand" "Q,S")
1118 (match_operand:HQI 1 "const0_operand" "")))
1119 (clobber (match_scratch:HQI 2 "=d,d"))]
1120 "s390_match_ccmode(insn, CCSmode)"
1121 "@
1122 icm\t%2,<icm_lo>,%S0
1123 icmy\t%2,<icm_lo>,%S0"
1124 [(set_attr "op_type" "RS,RSY")
1125 (set_attr "cpu_facility" "*,longdisp")
1126 (set_attr "z10prop" "z10_super_E1,z10_super_E1")])
1127
1128
1129 ; Compare (equality) instructions
1130
1131 (define_insn "*cmpdi_cct"
1132 [(set (reg CC_REGNUM)
1133 (compare (match_operand:DI 0 "nonimmediate_operand" "%d,d,d,d,Q")
1134 (match_operand:DI 1 "general_operand" "d,K,Os,T,BQ")))]
1135 "s390_match_ccmode (insn, CCTmode) && TARGET_ZARCH"
1136 "@
1137 cgr\t%0,%1
1138 cghi\t%0,%h1
1139 cgfi\t%0,%1
1140 cg\t%0,%1
1141 #"
1142 [(set_attr "op_type" "RRE,RI,RIL,RXY,SS")
1143 (set_attr "z10prop" "z10_super_c,z10_super,z10_super,z10_super,*")])
1144
1145 (define_insn "*cmpsi_cct"
1146 [(set (reg CC_REGNUM)
1147 (compare (match_operand:SI 0 "nonimmediate_operand" "%d,d,d,d,d,Q")
1148 (match_operand:SI 1 "general_operand" "d,K,Os,R,T,BQ")))]
1149 "s390_match_ccmode (insn, CCTmode)"
1150 "@
1151 cr\t%0,%1
1152 chi\t%0,%h1
1153 cfi\t%0,%1
1154 c\t%0,%1
1155 cy\t%0,%1
1156 #"
1157 [(set_attr "op_type" "RR,RI,RIL,RX,RXY,SS")
1158 (set_attr "cpu_facility" "*,*,*,*,longdisp,*")
1159 (set_attr "z10prop" "z10_super_c,z10_super,z10_super,z10_super,z10_super,*")])
1160
1161 ; Compare (signed) instructions
1162
1163 (define_insn "*cmpdi_ccs_sign"
1164 [(set (reg CC_REGNUM)
1165 (compare (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand"
1166 "d,T,b"))
1167 (match_operand:DI 0 "register_operand" "d, d,d")))]
1168 "s390_match_ccmode(insn, CCSRmode) && TARGET_ZARCH"
1169 "@
1170 cgfr\t%0,%1
1171 cgf\t%0,%1
1172 cgfrl\t%0,%1"
1173 [(set_attr "op_type" "RRE,RXY,RIL")
1174 (set_attr "z10prop" "z10_c,*,*")
1175 (set_attr "type" "*,*,larl")
1176 (set_attr "relative_long" "*,*,yes")])
1177
1178
1179
1180 (define_insn "*cmpsi_ccs_sign"
1181 [(set (reg CC_REGNUM)
1182 (compare (sign_extend:SI (match_operand:HI 1 "memory_operand" "R,T,b"))
1183 (match_operand:SI 0 "register_operand" "d,d,d")))]
1184 "s390_match_ccmode(insn, CCSRmode)"
1185 "@
1186 ch\t%0,%1
1187 chy\t%0,%1
1188 chrl\t%0,%1"
1189 [(set_attr "op_type" "RX,RXY,RIL")
1190 (set_attr "cpu_facility" "*,longdisp,z10")
1191 (set_attr "type" "*,*,larl")
1192 (set_attr "z196prop" "z196_cracked,z196_cracked,z196_cracked")
1193 (set_attr "relative_long" "*,*,yes")])
1194
1195 (define_insn "*cmphi_ccs_z10"
1196 [(set (reg CC_REGNUM)
1197 (compare (match_operand:HI 0 "s_operand" "Q")
1198 (match_operand:HI 1 "immediate_operand" "K")))]
1199 "s390_match_ccmode(insn, CCSmode) && TARGET_Z10"
1200 "chhsi\t%0,%1"
1201 [(set_attr "op_type" "SIL")
1202 (set_attr "z196prop" "z196_cracked")])
1203
1204 (define_insn "*cmpdi_ccs_signhi_rl"
1205 [(set (reg CC_REGNUM)
1206 (compare (sign_extend:DI (match_operand:HI 1 "memory_operand" "T,b"))
1207 (match_operand:GPR 0 "register_operand" "d,d")))]
1208 "s390_match_ccmode(insn, CCSRmode) && TARGET_Z10"
1209 "@
1210 cgh\t%0,%1
1211 cghrl\t%0,%1"
1212 [(set_attr "op_type" "RXY,RIL")
1213 (set_attr "type" "*,larl")
1214 (set_attr "relative_long" "*,yes")])
1215
1216 ; cr, chi, cfi, c, cy, cgr, cghi, cgfi, cg, chsi, cghsi, crl, cgrl
1217 (define_insn "*cmp<mode>_ccs"
1218 [(set (reg CC_REGNUM)
1219 (compare (match_operand:GPR 0 "nonimmediate_operand"
1220 "d,d,Q, d,d,d,d")
1221 (match_operand:GPR 1 "general_operand"
1222 "d,K,K,Os,R,T,b")))]
1223 "s390_match_ccmode(insn, CCSmode)"
1224 "@
1225 c<g>r\t%0,%1
1226 c<g>hi\t%0,%h1
1227 c<g>hsi\t%0,%h1
1228 c<g>fi\t%0,%1
1229 c<g>\t%0,%1
1230 c<y>\t%0,%1
1231 c<g>rl\t%0,%1"
1232 [(set_attr "op_type" "RR<E>,RI,SIL,RIL,RX<Y>,RXY,RIL")
1233 (set_attr "cpu_facility" "*,*,z10,extimm,*,longdisp,z10")
1234 (set_attr "type" "*,*,*,*,*,*,larl")
1235 (set_attr "z10prop" "z10_super_c,z10_super,z10_super,z10_super,z10_super,z10_super,z10_super")
1236 (set_attr "relative_long" "*,*,*,*,*,*,yes")])
1237
1238
1239 ; Compare (unsigned) instructions
1240
1241 (define_insn "*cmpsi_ccu_zerohi_rlsi"
1242 [(set (reg CC_REGNUM)
1243 (compare (zero_extend:SI (mem:HI (match_operand:SI 1
1244 "larl_operand" "X")))
1245 (match_operand:SI 0 "register_operand" "d")))]
1246 "s390_match_ccmode(insn, CCURmode) && TARGET_Z10"
1247 "clhrl\t%0,%1"
1248 [(set_attr "op_type" "RIL")
1249 (set_attr "type" "larl")
1250 (set_attr "z10prop" "z10_super")
1251 (set_attr "relative_long" "yes")])
1252
1253 ; clhrl, clghrl
1254 (define_insn "*cmp<GPR:mode>_ccu_zerohi_rldi"
1255 [(set (reg CC_REGNUM)
1256 (compare (zero_extend:GPR (mem:HI (match_operand:DI 1
1257 "larl_operand" "X")))
1258 (match_operand:GPR 0 "register_operand" "d")))]
1259 "s390_match_ccmode(insn, CCURmode) && TARGET_Z10"
1260 "cl<g>hrl\t%0,%1"
1261 [(set_attr "op_type" "RIL")
1262 (set_attr "type" "larl")
1263 (set_attr "z10prop" "z10_super")
1264 (set_attr "relative_long" "yes")])
1265
1266 (define_insn "*cmpdi_ccu_zero"
1267 [(set (reg CC_REGNUM)
1268 (compare (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand"
1269 "d,T,b"))
1270 (match_operand:DI 0 "register_operand" "d,d,d")))]
1271 "s390_match_ccmode (insn, CCURmode) && TARGET_ZARCH"
1272 "@
1273 clgfr\t%0,%1
1274 clgf\t%0,%1
1275 clgfrl\t%0,%1"
1276 [(set_attr "op_type" "RRE,RXY,RIL")
1277 (set_attr "cpu_facility" "*,*,z10")
1278 (set_attr "type" "*,*,larl")
1279 (set_attr "z10prop" "z10_super_c,z10_super_E1,z10_super")
1280 (set_attr "relative_long" "*,*,yes")])
1281
1282 (define_insn "*cmpdi_ccu"
1283 [(set (reg CC_REGNUM)
1284 (compare (match_operand:DI 0 "nonimmediate_operand"
1285 "d, d,d,Q,d, Q,BQ")
1286 (match_operand:DI 1 "general_operand"
1287 "d,Op,b,D,T,BQ,Q")))]
1288 "s390_match_ccmode (insn, CCUmode) && TARGET_ZARCH"
1289 "@
1290 clgr\t%0,%1
1291 clgfi\t%0,%1
1292 clgrl\t%0,%1
1293 clghsi\t%0,%x1
1294 clg\t%0,%1
1295 #
1296 #"
1297 [(set_attr "op_type" "RRE,RIL,RIL,SIL,RXY,SS,SS")
1298 (set_attr "cpu_facility" "*,extimm,z10,z10,*,*,*")
1299 (set_attr "type" "*,*,larl,*,*,*,*")
1300 (set_attr "z10prop" "z10_super_c,z10_super,z10_super,z10_super,z10_super,*,*")
1301 (set_attr "relative_long" "*,*,yes,*,*,*,*")])
1302
1303 (define_insn "*cmpsi_ccu"
1304 [(set (reg CC_REGNUM)
1305 (compare (match_operand:SI 0 "nonimmediate_operand" "d, d,d,Q,d,d, Q,BQ")
1306 (match_operand:SI 1 "general_operand" "d,Os,b,D,R,T,BQ, Q")))]
1307 "s390_match_ccmode (insn, CCUmode)"
1308 "@
1309 clr\t%0,%1
1310 clfi\t%0,%o1
1311 clrl\t%0,%1
1312 clfhsi\t%0,%x1
1313 cl\t%0,%1
1314 cly\t%0,%1
1315 #
1316 #"
1317 [(set_attr "op_type" "RR,RIL,RIL,SIL,RX,RXY,SS,SS")
1318 (set_attr "cpu_facility" "*,extimm,z10,z10,*,longdisp,*,*")
1319 (set_attr "type" "*,*,larl,*,*,*,*,*")
1320 (set_attr "z10prop" "z10_super_c,z10_super,z10_super,z10_super,z10_super,z10_super,*,*")
1321 (set_attr "relative_long" "*,*,yes,*,*,*,*,*")])
1322
1323 (define_insn "*cmphi_ccu"
1324 [(set (reg CC_REGNUM)
1325 (compare (match_operand:HI 0 "nonimmediate_operand" "d,d,Q,Q,BQ")
1326 (match_operand:HI 1 "general_operand" "Q,S,D,BQ,Q")))]
1327 "s390_match_ccmode (insn, CCUmode)
1328 && !register_operand (operands[1], HImode)"
1329 "@
1330 clm\t%0,3,%S1
1331 clmy\t%0,3,%S1
1332 clhhsi\t%0,%1
1333 #
1334 #"
1335 [(set_attr "op_type" "RS,RSY,SIL,SS,SS")
1336 (set_attr "cpu_facility" "*,longdisp,z10,*,*")
1337 (set_attr "z10prop" "*,*,z10_super,*,*")])
1338
1339 (define_insn "*cmpqi_ccu"
1340 [(set (reg CC_REGNUM)
1341 (compare (match_operand:QI 0 "nonimmediate_operand" "d,d,Q,S,Q,BQ")
1342 (match_operand:QI 1 "general_operand" "Q,S,n,n,BQ,Q")))]
1343 "s390_match_ccmode (insn, CCUmode)
1344 && !register_operand (operands[1], QImode)"
1345 "@
1346 clm\t%0,1,%S1
1347 clmy\t%0,1,%S1
1348 cli\t%S0,%b1
1349 cliy\t%S0,%b1
1350 #
1351 #"
1352 [(set_attr "op_type" "RS,RSY,SI,SIY,SS,SS")
1353 (set_attr "cpu_facility" "*,longdisp,*,longdisp,*,*")
1354 (set_attr "z10prop" "*,*,z10_super,z10_super,*,*")])
1355
1356
1357 ; Block compare (CLC) instruction patterns.
1358
1359 (define_insn "*clc"
1360 [(set (reg CC_REGNUM)
1361 (compare (match_operand:BLK 0 "memory_operand" "Q")
1362 (match_operand:BLK 1 "memory_operand" "Q")))
1363 (use (match_operand 2 "const_int_operand" "n"))]
1364 "s390_match_ccmode (insn, CCUmode)
1365 && INTVAL (operands[2]) >= 1 && INTVAL (operands[2]) <= 256"
1366 "clc\t%O0(%2,%R0),%S1"
1367 [(set_attr "op_type" "SS")])
1368
1369 (define_split
1370 [(set (reg CC_REGNUM)
1371 (compare (match_operand 0 "memory_operand" "")
1372 (match_operand 1 "memory_operand" "")))]
1373 "reload_completed
1374 && s390_match_ccmode (insn, CCUmode)
1375 && GET_MODE (operands[0]) == GET_MODE (operands[1])
1376 && GET_MODE_SIZE (GET_MODE (operands[0])) > 0"
1377 [(parallel
1378 [(set (match_dup 0) (match_dup 1))
1379 (use (match_dup 2))])]
1380 {
1381 operands[2] = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[0])));
1382 operands[0] = adjust_address (operands[0], BLKmode, 0);
1383 operands[1] = adjust_address (operands[1], BLKmode, 0);
1384
1385 operands[1] = gen_rtx_COMPARE (GET_MODE (SET_DEST (PATTERN (curr_insn))),
1386 operands[0], operands[1]);
1387 operands[0] = SET_DEST (PATTERN (curr_insn));
1388 })
1389
1390
1391 ; (TF|DF|SF|TD|DD|SD) instructions
1392
1393
1394 ; FIXME: load and test instructions turn SNaN into QNaN what is not
1395 ; acceptable if the target will be used afterwards. On the other hand
1396 ; they are quite convenient for implementing comparisons with 0.0. So
1397 ; try to enable them via splitter/peephole if the value isn't needed anymore.
1398 ; See testcases: load-and-test-fp-1.c and load-and-test-fp-2.c
1399
1400 ; ltxbr, ltdbr, ltebr, ltxtr, ltdtr
1401 (define_insn "*cmp<mode>_ccs_0"
1402 [(set (reg CC_REGNUM)
1403 (compare (match_operand:FP 0 "register_operand" "f")
1404 (match_operand:FP 1 "const0_operand" "")))
1405 (clobber (match_operand:FP 2 "register_operand" "=0"))]
1406 "s390_match_ccmode(insn, CCSmode) && TARGET_HARD_FLOAT"
1407 "lt<xde><bt>r\t%0,%0"
1408 [(set_attr "op_type" "RRE")
1409 (set_attr "type" "fsimp<mode>")])
1410
1411 ; VX: TFmode in FPR pairs: use cxbr instead of wfcxb
1412 ; cxtr, cdtr, cxbr, cdbr, cebr, cdb, ceb, wfcsb, wfcdb
1413 (define_insn "*cmp<mode>_ccs"
1414 [(set (reg CC_REGNUM)
1415 (compare (match_operand:FP 0 "register_operand" "f,f,v,v")
1416 (match_operand:FP 1 "general_operand" "f,R,v,v")))]
1417 "s390_match_ccmode(insn, CCSmode) && TARGET_HARD_FLOAT"
1418 "@
1419 c<xde><bt>r\t%0,%1
1420 c<xde>b\t%0,%1
1421 wfcdb\t%0,%1
1422 wfcsb\t%0,%1"
1423 [(set_attr "op_type" "RRE,RXE,VRR,VRR")
1424 (set_attr "cpu_facility" "*,*,vx,vxe")
1425 (set_attr "enabled" "*,<DSF>,<DF>,<SF>")])
1426
1427 (define_insn "*cmp<mode>_ccsfps"
1428 [(set (reg CC_REGNUM)
1429 (compare (match_operand:FP 0 "register_operand" "f,f,v,v")
1430 (match_operand:FP 1 "general_operand" "f,R,v,v")))]
1431 "s390_match_ccmode (insn, CCSFPSmode) && TARGET_HARD_FLOAT"
1432 "@
1433 k<xde><bt>r\t%0,%1
1434 k<xde>b\t%0,%1
1435 wfkdb\t%0,%1
1436 wfksb\t%0,%1"
1437 [(set_attr "op_type" "RRE,RXE,VRR,VRR")
1438 (set_attr "cpu_facility" "*,*,vx,vxe")
1439 (set_attr "enabled" "*,<DSF>,<DF>,<SF>")])
1440
1441 ; Compare and Branch instructions
1442
1443 ; cij, cgij, crj, cgrj, cfi, cgfi, cr, cgr
1444 ; The following instructions do a complementary access of their second
1445 ; operand (z01 only): crj_c, cgrjc, cr, cgr
1446 (define_insn "*cmp_and_br_signed_<mode>"
1447 [(set (pc)
1448 (if_then_else (match_operator 0 "s390_signed_integer_comparison"
1449 [(match_operand:GPR 1 "register_operand" "d,d")
1450 (match_operand:GPR 2 "nonmemory_operand" "d,C")])
1451 (label_ref (match_operand 3 "" ""))
1452 (pc)))
1453 (clobber (reg:CC CC_REGNUM))]
1454 "TARGET_Z10 && !TARGET_AVOID_CMP_AND_BRANCH"
1455 {
1456 if (get_attr_length (insn) == 6)
1457 return which_alternative ?
1458 "c<g>ij%C0\t%1,%c2,%l3" : "c<g>rj%C0\t%1,%2,%l3";
1459 else
1460 return which_alternative ?
1461 "c<g>fi\t%1,%c2\;jg%C0\t%l3" : "c<g>r\t%1,%2\;jg%C0\t%l3";
1462 }
1463 [(set_attr "op_type" "RIE")
1464 (set_attr "type" "branch")
1465 (set_attr "z10prop" "z10_super_c,z10_super")
1466 (set (attr "length")
1467 (if_then_else (lt (abs (minus (pc) (match_dup 3))) (const_int 60000))
1468 (const_int 6) (const_int 12)))]) ; 8 byte for cr/jg
1469 ; 10 byte for cgr/jg
1470
1471 ; clij, clgij, clrj, clgrj, clfi, clgfi, clr, clgr
1472 ; The following instructions do a complementary access of their second
1473 ; operand (z10 only): clrj, clgrj, clr, clgr
1474 (define_insn "*cmp_and_br_unsigned_<mode>"
1475 [(set (pc)
1476 (if_then_else (match_operator 0 "s390_unsigned_integer_comparison"
1477 [(match_operand:GPR 1 "register_operand" "d,d")
1478 (match_operand:GPR 2 "nonmemory_operand" "d,I")])
1479 (label_ref (match_operand 3 "" ""))
1480 (pc)))
1481 (clobber (reg:CC CC_REGNUM))]
1482 "TARGET_Z10 && !TARGET_AVOID_CMP_AND_BRANCH"
1483 {
1484 if (get_attr_length (insn) == 6)
1485 return which_alternative ?
1486 "cl<g>ij%C0\t%1,%b2,%l3" : "cl<g>rj%C0\t%1,%2,%l3";
1487 else
1488 return which_alternative ?
1489 "cl<g>fi\t%1,%b2\;jg%C0\t%l3" : "cl<g>r\t%1,%2\;jg%C0\t%l3";
1490 }
1491 [(set_attr "op_type" "RIE")
1492 (set_attr "type" "branch")
1493 (set_attr "z10prop" "z10_super_c,z10_super")
1494 (set (attr "length")
1495 (if_then_else (lt (abs (minus (pc) (match_dup 3))) (const_int 60000))
1496 (const_int 6) (const_int 12)))]) ; 8 byte for clr/jg
1497 ; 10 byte for clgr/jg
1498
1499 ; And now the same two patterns as above but with a negated CC mask.
1500
1501 ; cij, cgij, crj, cgrj, cfi, cgfi, cr, cgr
1502 ; The following instructions do a complementary access of their second
1503 ; operand (z01 only): crj_c, cgrjc, cr, cgr
1504 (define_insn "*icmp_and_br_signed_<mode>"
1505 [(set (pc)
1506 (if_then_else (match_operator 0 "s390_signed_integer_comparison"
1507 [(match_operand:GPR 1 "register_operand" "d,d")
1508 (match_operand:GPR 2 "nonmemory_operand" "d,C")])
1509 (pc)
1510 (label_ref (match_operand 3 "" ""))))
1511 (clobber (reg:CC CC_REGNUM))]
1512 "TARGET_Z10 && !TARGET_AVOID_CMP_AND_BRANCH"
1513 {
1514 if (get_attr_length (insn) == 6)
1515 return which_alternative ?
1516 "c<g>ij%D0\t%1,%c2,%l3" : "c<g>rj%D0\t%1,%2,%l3";
1517 else
1518 return which_alternative ?
1519 "c<g>fi\t%1,%c2\;jg%D0\t%l3" : "c<g>r\t%1,%2\;jg%D0\t%l3";
1520 }
1521 [(set_attr "op_type" "RIE")
1522 (set_attr "type" "branch")
1523 (set_attr "z10prop" "z10_super_c,z10_super")
1524 (set (attr "length")
1525 (if_then_else (lt (abs (minus (pc) (match_dup 3))) (const_int 60000))
1526 (const_int 6) (const_int 12)))]) ; 8 byte for cr/jg
1527 ; 10 byte for cgr/jg
1528
1529 ; clij, clgij, clrj, clgrj, clfi, clgfi, clr, clgr
1530 ; The following instructions do a complementary access of their second
1531 ; operand (z10 only): clrj, clgrj, clr, clgr
1532 (define_insn "*icmp_and_br_unsigned_<mode>"
1533 [(set (pc)
1534 (if_then_else (match_operator 0 "s390_unsigned_integer_comparison"
1535 [(match_operand:GPR 1 "register_operand" "d,d")
1536 (match_operand:GPR 2 "nonmemory_operand" "d,I")])
1537 (pc)
1538 (label_ref (match_operand 3 "" ""))))
1539 (clobber (reg:CC CC_REGNUM))]
1540 "TARGET_Z10 && !TARGET_AVOID_CMP_AND_BRANCH"
1541 {
1542 if (get_attr_length (insn) == 6)
1543 return which_alternative ?
1544 "cl<g>ij%D0\t%1,%b2,%l3" : "cl<g>rj%D0\t%1,%2,%l3";
1545 else
1546 return which_alternative ?
1547 "cl<g>fi\t%1,%b2\;jg%D0\t%l3" : "cl<g>r\t%1,%2\;jg%D0\t%l3";
1548 }
1549 [(set_attr "op_type" "RIE")
1550 (set_attr "type" "branch")
1551 (set_attr "z10prop" "z10_super_c,z10_super")
1552 (set (attr "length")
1553 (if_then_else (lt (abs (minus (pc) (match_dup 3))) (const_int 60000))
1554 (const_int 6) (const_int 12)))]) ; 8 byte for clr/jg
1555 ; 10 byte for clgr/jg
1556
1557 ;;
1558 ;;- Move instructions.
1559 ;;
1560
1561 ;
1562 ; movti instruction pattern(s).
1563 ;
1564
1565
1566 ; Separate out the register pair alternative since constraints (P) are
1567 ; not able to deal with const_wide_int's. But predicates do.
1568 (define_insn "*movti_bigconst"
1569 [(set (match_operand:TI 0 "register_operand" "=d")
1570 (match_operand:TI 1 "reload_const_wide_int_operand" ""))]
1571 "TARGET_ZARCH"
1572 "#")
1573
1574 ; FIXME: More constants are possible by enabling jxx, jyy constraints
1575 ; for TImode (use double-int for the calculations)
1576 (define_insn "movti"
1577 [(set (match_operand:TI 0 "nonimmediate_operand" "=d,S,v, v, v,v,d,v,R,d, d, d, d, d,o")
1578 (match_operand:TI 1 "general_operand" " S,d,v,j00,jm1,d,v,R,v,K,NxHD0,Os,NxSD0,dT,d"))]
1579 "TARGET_ZARCH"
1580 "@
1581 lmg\t%0,%N0,%S1
1582 stmg\t%1,%N1,%S0
1583 vlr\t%v0,%v1
1584 vzero\t%v0
1585 vone\t%v0
1586 vlvgp\t%v0,%1,%N1
1587 #
1588 vl\t%v0,%1%A1
1589 vst\t%v1,%0%A0
1590 #
1591 #
1592 #
1593 #
1594 #
1595 #"
1596 [(set_attr "op_type" "RSY,RSY,VRR,VRI,VRI,VRR,*,VRX,VRX,*,*,*,*,*,*")
1597 (set_attr "type" "lm,stm,*,*,*,*,*,*,*,*,*,*,*,*,*")
1598 (set_attr "cpu_facility" "*,*,vx,vx,vx,vx,vx,vx,vx,*,*,*,extimm,*,*")])
1599
1600 (define_split
1601 [(set (match_operand:TI 0 "nonimmediate_operand" "")
1602 (match_operand:TI 1 "general_operand" ""))]
1603 "TARGET_ZARCH && reload_completed
1604 && !s_operand (operands[0], TImode)
1605 && !s_operand (operands[1], TImode)
1606 && s390_split_ok_p (operands[0], operands[1], TImode, 0)"
1607 [(set (match_dup 2) (match_dup 4))
1608 (set (match_dup 3) (match_dup 5))]
1609 {
1610 operands[2] = operand_subword (operands[0], 0, 0, TImode);
1611 operands[3] = operand_subword (operands[0], 1, 0, TImode);
1612 operands[4] = operand_subword (operands[1], 0, 0, TImode);
1613 operands[5] = operand_subword (operands[1], 1, 0, TImode);
1614 })
1615
1616 (define_split
1617 [(set (match_operand:TI 0 "nonimmediate_operand" "")
1618 (match_operand:TI 1 "general_operand" ""))]
1619 "TARGET_ZARCH && reload_completed
1620 && !s_operand (operands[0], TImode)
1621 && !s_operand (operands[1], TImode)
1622 && s390_split_ok_p (operands[0], operands[1], TImode, 1)"
1623 [(set (match_dup 2) (match_dup 4))
1624 (set (match_dup 3) (match_dup 5))]
1625 {
1626 operands[2] = operand_subword (operands[0], 1, 0, TImode);
1627 operands[3] = operand_subword (operands[0], 0, 0, TImode);
1628 operands[4] = operand_subword (operands[1], 1, 0, TImode);
1629 operands[5] = operand_subword (operands[1], 0, 0, TImode);
1630 })
1631
1632 ; Use part of the TImode target reg to perform the address
1633 ; calculation. If the TImode value is supposed to be copied into a VR
1634 ; this splitter is not necessary.
1635 (define_split
1636 [(set (match_operand:TI 0 "register_operand" "")
1637 (match_operand:TI 1 "memory_operand" ""))]
1638 "TARGET_ZARCH && reload_completed
1639 && !VECTOR_REG_P (operands[0])
1640 && !s_operand (operands[1], VOIDmode)"
1641 [(set (match_dup 0) (match_dup 1))]
1642 {
1643 rtx addr = operand_subword (operands[0], 1, 0, TImode);
1644 addr = gen_lowpart (Pmode, addr);
1645 s390_load_address (addr, XEXP (operands[1], 0));
1646 operands[1] = replace_equiv_address (operands[1], addr);
1647 })
1648
1649
1650 ; Split a VR -> GPR TImode move into 2 vector load GR from VR element.
1651 ; For the higher order bits we do simply a DImode move while the
1652 ; second part is done via vec extract. Both will end up as vlgvg.
1653 (define_split
1654 [(set (match_operand:TI 0 "register_operand" "")
1655 (match_operand:TI 1 "register_operand" ""))]
1656 "TARGET_VX && reload_completed
1657 && GENERAL_REG_P (operands[0])
1658 && VECTOR_REG_P (operands[1])"
1659 [(set (match_dup 2) (match_dup 4))
1660 (set (match_dup 3) (unspec:DI [(match_dup 5) (const_int 1)]
1661 UNSPEC_VEC_EXTRACT))]
1662 {
1663 operands[2] = operand_subword (operands[0], 0, 0, TImode);
1664 operands[3] = operand_subword (operands[0], 1, 0, TImode);
1665 operands[4] = gen_rtx_REG (DImode, REGNO (operands[1]));
1666 operands[5] = gen_rtx_REG (V2DImode, REGNO (operands[1]));
1667 })
1668
1669 ;
1670 ; Patterns used for secondary reloads
1671 ;
1672
1673 ; z10 provides move instructions accepting larl memory operands.
1674 ; Unfortunately there is no such variant for QI, TI and FP mode moves.
1675 ; These patterns are also used for unaligned SI and DI accesses.
1676
1677 (define_expand "reload<ALL:mode><P:mode>_tomem_z10"
1678 [(parallel [(match_operand:ALL 0 "memory_operand" "")
1679 (match_operand:ALL 1 "register_operand" "=d")
1680 (match_operand:P 2 "register_operand" "=&a")])]
1681 "TARGET_Z10"
1682 {
1683 s390_reload_symref_address (operands[1], operands[0], operands[2], 1);
1684 DONE;
1685 })
1686
1687 (define_expand "reload<ALL:mode><P:mode>_toreg_z10"
1688 [(parallel [(match_operand:ALL 0 "register_operand" "=d")
1689 (match_operand:ALL 1 "memory_operand" "")
1690 (match_operand:P 2 "register_operand" "=a")])]
1691 "TARGET_Z10"
1692 {
1693 s390_reload_symref_address (operands[0], operands[1], operands[2], 0);
1694 DONE;
1695 })
1696
1697 (define_expand "reload<P:mode>_larl_odd_addend_z10"
1698 [(parallel [(match_operand:P 0 "register_operand" "=d")
1699 (match_operand:P 1 "larl_operand" "")
1700 (match_operand:P 2 "register_operand" "=a")])]
1701 "TARGET_Z10"
1702 {
1703 s390_reload_larl_operand (operands[0], operands[1], operands[2]);
1704 DONE;
1705 })
1706
1707 ; Handles loading a PLUS (load address) expression
1708
1709 (define_expand "reload<mode>_plus"
1710 [(parallel [(match_operand:P 0 "register_operand" "=a")
1711 (match_operand:P 1 "s390_plus_operand" "")
1712 (match_operand:P 2 "register_operand" "=&a")])]
1713 ""
1714 {
1715 s390_expand_plus_operand (operands[0], operands[1], operands[2]);
1716 DONE;
1717 })
1718
1719 ; Not all the indirect memory access instructions support the full
1720 ; format (long disp + index + base). So whenever a move from/to such
1721 ; an address is required and the instruction cannot deal with it we do
1722 ; a load address into a scratch register first and use this as the new
1723 ; base register.
1724 ; This in particular is used for:
1725 ; - non-offsetable memory accesses for multiword moves
1726 ; - full vector reg moves with long displacements
1727
1728 (define_expand "reload<mode>_la_in"
1729 [(parallel [(match_operand 0 "register_operand" "")
1730 (match_operand 1 "" "")
1731 (match_operand:P 2 "register_operand" "=&a")])]
1732 ""
1733 {
1734 gcc_assert (MEM_P (operands[1]));
1735 s390_load_address (operands[2], find_replacement (&XEXP (operands[1], 0)));
1736 operands[1] = replace_equiv_address (operands[1], operands[2]);
1737 emit_move_insn (operands[0], operands[1]);
1738 DONE;
1739 })
1740
1741 (define_expand "reload<mode>_la_out"
1742 [(parallel [(match_operand 0 "" "")
1743 (match_operand 1 "register_operand" "")
1744 (match_operand:P 2 "register_operand" "=&a")])]
1745 ""
1746 {
1747 gcc_assert (MEM_P (operands[0]));
1748 s390_load_address (operands[2], find_replacement (&XEXP (operands[0], 0)));
1749 operands[0] = replace_equiv_address (operands[0], operands[2]);
1750 emit_move_insn (operands[0], operands[1]);
1751 DONE;
1752 })
1753
1754 (define_expand "reload<mode>_PIC_addr"
1755 [(parallel [(match_operand 0 "register_operand" "=d")
1756 (match_operand 1 "larl_operand" "")
1757 (match_operand:P 2 "register_operand" "=a")])]
1758 ""
1759 {
1760 rtx new_rtx = legitimize_pic_address (operands[1], operands[2]);
1761 emit_move_insn (operands[0], new_rtx);
1762 })
1763
1764 ;
1765 ; movdi instruction pattern(s).
1766 ;
1767
1768 (define_expand "movdi"
1769 [(set (match_operand:DI 0 "general_operand" "")
1770 (match_operand:DI 1 "general_operand" ""))]
1771 ""
1772 {
1773 /* Handle symbolic constants. */
1774 if (TARGET_64BIT
1775 && (SYMBOLIC_CONST (operands[1])
1776 || (GET_CODE (operands[1]) == PLUS
1777 && XEXP (operands[1], 0) == pic_offset_table_rtx
1778 && SYMBOLIC_CONST (XEXP (operands[1], 1)))))
1779 emit_symbolic_move (operands);
1780 })
1781
1782 (define_insn "*movdi_64"
1783 [(set (match_operand:DI 0 "nonimmediate_operand"
1784 "=d, d, d, d, d, d, d, d,f,d,d,d,d,d,T,!*f,!*f,!*f,!R,!T,b,Q,d,t,Q,t,v,v,v,d,v,R,d")
1785 (match_operand:DI 1 "general_operand"
1786 " K,N0HD0,N1HD0,N2HD0,N3HD0,Os,N0SD0,N1SD0,d,f,L,b,d,T,d, *f, R, T,*f,*f,d,K,t,d,t,Q,K,v,d,v,R,v,ZL"))]
1787 "TARGET_ZARCH"
1788 "@
1789 lghi\t%0,%h1
1790 llihh\t%0,%i1
1791 llihl\t%0,%i1
1792 llilh\t%0,%i1
1793 llill\t%0,%i1
1794 lgfi\t%0,%1
1795 llihf\t%0,%k1
1796 llilf\t%0,%k1
1797 ldgr\t%0,%1
1798 lgdr\t%0,%1
1799 lay\t%0,%a1
1800 lgrl\t%0,%1
1801 lgr\t%0,%1
1802 lg\t%0,%1
1803 stg\t%1,%0
1804 ldr\t%0,%1
1805 ld\t%0,%1
1806 ldy\t%0,%1
1807 std\t%1,%0
1808 stdy\t%1,%0
1809 stgrl\t%1,%0
1810 mvghi\t%0,%1
1811 #
1812 #
1813 stam\t%1,%N1,%S0
1814 lam\t%0,%N0,%S1
1815 vleig\t%v0,%h1,0
1816 vlr\t%v0,%v1
1817 vlvgg\t%v0,%1,0
1818 vlgvg\t%0,%v1,0
1819 vleg\t%v0,%1,0
1820 vsteg\t%v1,%0,0
1821 larl\t%0,%1"
1822 [(set_attr "op_type" "RI,RI,RI,RI,RI,RIL,RIL,RIL,RRE,RRE,RXY,RIL,RRE,RXY,
1823 RXY,RR,RX,RXY,RX,RXY,RIL,SIL,*,*,RS,RS,VRI,VRR,VRS,VRS,
1824 VRX,VRX,RIL")
1825 (set_attr "type" "*,*,*,*,*,*,*,*,floaddf,floaddf,la,larl,lr,load,store,
1826 floaddf,floaddf,floaddf,fstoredf,fstoredf,larl,*,*,*,*,
1827 *,*,*,*,*,*,*,larl")
1828 (set_attr "cpu_facility" "*,*,*,*,*,extimm,extimm,extimm,dfp,dfp,longdisp,
1829 z10,*,*,*,*,*,longdisp,*,longdisp,
1830 z10,z10,*,*,*,*,vx,vx,vx,vx,vx,vx,*")
1831 (set_attr "z10prop" "z10_fwd_A1,
1832 z10_fwd_E1,
1833 z10_fwd_E1,
1834 z10_fwd_E1,
1835 z10_fwd_E1,
1836 z10_fwd_A1,
1837 z10_fwd_E1,
1838 z10_fwd_E1,
1839 *,
1840 *,
1841 z10_fwd_A1,
1842 z10_fwd_A3,
1843 z10_fr_E1,
1844 z10_fwd_A3,
1845 z10_rec,
1846 *,
1847 *,
1848 *,
1849 *,
1850 *,
1851 z10_rec,
1852 z10_super,
1853 *,
1854 *,
1855 *,
1856 *,*,*,*,*,*,*,
1857 z10_super_A1")
1858 (set_attr "relative_long" "*,*,*,*,*,*,*,*,*,*,
1859 *,yes,*,*,*,*,*,*,*,*,
1860 yes,*,*,*,*,*,*,*,*,*,
1861 *,*,yes")
1862 ])
1863
1864 ; Splitters for loading TLS pointer from UNSPEC_GET_TP.
1865 ; UNSPEC_GET_TP is used instead of %a0:P, since the latter is a hard register,
1866 ; and those are not handled by Partial Redundancy Elimination (gcse.c), which
1867 ; results in generation of redundant thread pointer loads.
1868
1869 (define_insn_and_split "*get_tp_31"
1870 [(set (match_operand:SI 0 "register_operand" "=r")
1871 (unspec:SI [(match_operand:SI 1 "register_operand" "t")]
1872 UNSPEC_GET_TP))]
1873 ""
1874 "#"
1875 "&& reload_completed"
1876 [(set (match_dup 0) (match_dup 1))])
1877
1878 (define_insn_and_split "*get_tp_64"
1879 [(set (match_operand:DI 0 "register_operand" "=r")
1880 (unspec:DI [(match_operand:DI 1 "register_operand" "t")]
1881 UNSPEC_GET_TP))]
1882 "TARGET_ZARCH"
1883 "#"
1884 "&& reload_completed"
1885 [(set (match_dup 2) (match_dup 3))
1886 (set (match_dup 0) (ashift:DI (match_dup 0) (const_int 32)))
1887 (set (strict_low_part (match_dup 2)) (match_dup 4))]
1888 "operands[2] = gen_lowpart (SImode, operands[0]);
1889 s390_split_access_reg (operands[1], &operands[4], &operands[3]);")
1890
1891 ; Splitters for storing TLS pointer to %a0:DI.
1892
1893 (define_split
1894 [(set (match_operand:DI 0 "register_operand" "")
1895 (match_operand:DI 1 "register_operand" ""))]
1896 "TARGET_ZARCH && ACCESS_REG_P (operands[0]) && reload_completed
1897 && dead_or_set_p (insn, operands[1])"
1898 [(set (match_dup 3) (match_dup 2))
1899 (set (match_dup 1) (lshiftrt:DI (match_dup 1) (const_int 32)))
1900 (set (match_dup 4) (match_dup 2))]
1901 "operands[2] = gen_lowpart (SImode, operands[1]);
1902 s390_split_access_reg (operands[0], &operands[3], &operands[4]);")
1903
1904 (define_split
1905 [(set (match_operand:DI 0 "register_operand" "")
1906 (match_operand:DI 1 "register_operand" ""))]
1907 "TARGET_ZARCH && ACCESS_REG_P (operands[0]) && reload_completed
1908 && !dead_or_set_p (insn, operands[1])"
1909 [(set (match_dup 3) (match_dup 2))
1910 (set (match_dup 1) (rotate:DI (match_dup 1) (const_int 32)))
1911 (set (match_dup 4) (match_dup 2))
1912 (set (match_dup 1) (rotate:DI (match_dup 1) (const_int 32)))]
1913 "operands[2] = gen_lowpart (SImode, operands[1]);
1914 s390_split_access_reg (operands[0], &operands[3], &operands[4]);")
1915
1916 (define_insn "*movdi_31"
1917 [(set (match_operand:DI 0 "nonimmediate_operand"
1918 "=d,d,Q,S,d ,o,!*f,!*f,!*f,!R,!T,d")
1919 (match_operand:DI 1 "general_operand"
1920 " Q,S,d,d,dPT,d, *f, R, T,*f,*f,b"))]
1921 "!TARGET_ZARCH"
1922 "@
1923 lm\t%0,%N0,%S1
1924 lmy\t%0,%N0,%S1
1925 stm\t%1,%N1,%S0
1926 stmy\t%1,%N1,%S0
1927 #
1928 #
1929 ldr\t%0,%1
1930 ld\t%0,%1
1931 ldy\t%0,%1
1932 std\t%1,%0
1933 stdy\t%1,%0
1934 #"
1935 [(set_attr "op_type" "RS,RSY,RS,RSY,*,*,RR,RX,RXY,RX,RXY,*")
1936 (set_attr "type" "lm,lm,stm,stm,*,*,floaddf,floaddf,floaddf,fstoredf,fstoredf,*")
1937 (set_attr "cpu_facility" "*,longdisp,*,longdisp,*,*,*,*,longdisp,*,longdisp,z10")])
1938
1939 ; For a load from a symbol ref we can use one of the target registers
1940 ; together with larl to load the address.
1941 (define_split
1942 [(set (match_operand:DI 0 "register_operand" "")
1943 (match_operand:DI 1 "memory_operand" ""))]
1944 "!TARGET_ZARCH && reload_completed && TARGET_Z10
1945 && larl_operand (XEXP (operands[1], 0), SImode)"
1946 [(set (match_dup 2) (match_dup 3))
1947 (set (match_dup 0) (match_dup 1))]
1948 {
1949 operands[2] = operand_subword (operands[0], 1, 0, DImode);
1950 operands[3] = XEXP (operands[1], 0);
1951 operands[1] = replace_equiv_address (operands[1], operands[2]);
1952 })
1953
1954 (define_split
1955 [(set (match_operand:DI 0 "nonimmediate_operand" "")
1956 (match_operand:DI 1 "general_operand" ""))]
1957 "!TARGET_ZARCH && reload_completed
1958 && !s_operand (operands[0], DImode)
1959 && !s_operand (operands[1], DImode)
1960 && s390_split_ok_p (operands[0], operands[1], DImode, 0)"
1961 [(set (match_dup 2) (match_dup 4))
1962 (set (match_dup 3) (match_dup 5))]
1963 {
1964 operands[2] = operand_subword (operands[0], 0, 0, DImode);
1965 operands[3] = operand_subword (operands[0], 1, 0, DImode);
1966 operands[4] = operand_subword (operands[1], 0, 0, DImode);
1967 operands[5] = operand_subword (operands[1], 1, 0, DImode);
1968 })
1969
1970 (define_split
1971 [(set (match_operand:DI 0 "nonimmediate_operand" "")
1972 (match_operand:DI 1 "general_operand" ""))]
1973 "!TARGET_ZARCH && reload_completed
1974 && !s_operand (operands[0], DImode)
1975 && !s_operand (operands[1], DImode)
1976 && s390_split_ok_p (operands[0], operands[1], DImode, 1)"
1977 [(set (match_dup 2) (match_dup 4))
1978 (set (match_dup 3) (match_dup 5))]
1979 {
1980 operands[2] = operand_subword (operands[0], 1, 0, DImode);
1981 operands[3] = operand_subword (operands[0], 0, 0, DImode);
1982 operands[4] = operand_subword (operands[1], 1, 0, DImode);
1983 operands[5] = operand_subword (operands[1], 0, 0, DImode);
1984 })
1985
1986 (define_split
1987 [(set (match_operand:DI 0 "register_operand" "")
1988 (match_operand:DI 1 "memory_operand" ""))]
1989 "!TARGET_ZARCH && reload_completed
1990 && !FP_REG_P (operands[0])
1991 && !s_operand (operands[1], VOIDmode)"
1992 [(set (match_dup 0) (match_dup 1))]
1993 {
1994 rtx addr = operand_subword (operands[0], 1, 0, DImode);
1995 s390_load_address (addr, XEXP (operands[1], 0));
1996 operands[1] = replace_equiv_address (operands[1], addr);
1997 })
1998
1999 (define_peephole2
2000 [(set (match_operand:DI 0 "register_operand" "")
2001 (mem:DI (match_operand 1 "address_operand" "")))]
2002 "TARGET_ZARCH
2003 && !FP_REG_P (operands[0])
2004 && GET_CODE (operands[1]) == SYMBOL_REF
2005 && CONSTANT_POOL_ADDRESS_P (operands[1])
2006 && get_pool_mode (operands[1]) == DImode
2007 && legitimate_reload_constant_p (get_pool_constant (operands[1]))"
2008 [(set (match_dup 0) (match_dup 2))]
2009 "operands[2] = get_pool_constant (operands[1]);")
2010
2011 (define_insn "*la_64"
2012 [(set (match_operand:DI 0 "register_operand" "=d,d")
2013 (match_operand:QI 1 "address_operand" "ZR,ZT"))]
2014 "TARGET_64BIT"
2015 "@
2016 la\t%0,%a1
2017 lay\t%0,%a1"
2018 [(set_attr "op_type" "RX,RXY")
2019 (set_attr "type" "la")
2020 (set_attr "cpu_facility" "*,longdisp")
2021 (set_attr "z10prop" "z10_fwd_A1,z10_fwd_A1")])
2022
2023 (define_peephole2
2024 [(parallel
2025 [(set (match_operand:DI 0 "register_operand" "")
2026 (match_operand:QI 1 "address_operand" ""))
2027 (clobber (reg:CC CC_REGNUM))])]
2028 "TARGET_64BIT
2029 && preferred_la_operand_p (operands[1], const0_rtx)"
2030 [(set (match_dup 0) (match_dup 1))]
2031 "")
2032
2033 (define_peephole2
2034 [(set (match_operand:DI 0 "register_operand" "")
2035 (match_operand:DI 1 "register_operand" ""))
2036 (parallel
2037 [(set (match_dup 0)
2038 (plus:DI (match_dup 0)
2039 (match_operand:DI 2 "nonmemory_operand" "")))
2040 (clobber (reg:CC CC_REGNUM))])]
2041 "TARGET_64BIT
2042 && !reg_overlap_mentioned_p (operands[0], operands[2])
2043 && preferred_la_operand_p (operands[1], operands[2])"
2044 [(set (match_dup 0) (plus:DI (match_dup 1) (match_dup 2)))]
2045 "")
2046
2047 ;
2048 ; movsi instruction pattern(s).
2049 ;
2050
2051 (define_expand "movsi"
2052 [(set (match_operand:SI 0 "general_operand" "")
2053 (match_operand:SI 1 "general_operand" ""))]
2054 ""
2055 {
2056 /* Handle symbolic constants. */
2057 if (!TARGET_64BIT
2058 && (SYMBOLIC_CONST (operands[1])
2059 || (GET_CODE (operands[1]) == PLUS
2060 && XEXP (operands[1], 0) == pic_offset_table_rtx
2061 && SYMBOLIC_CONST (XEXP(operands[1], 1)))))
2062 emit_symbolic_move (operands);
2063 })
2064
2065 (define_insn "*movsi_larl"
2066 [(set (match_operand:SI 0 "register_operand" "=d")
2067 (match_operand:SI 1 "larl_operand" "X"))]
2068 "!TARGET_64BIT
2069 && !FP_REG_P (operands[0])"
2070 "larl\t%0,%1"
2071 [(set_attr "op_type" "RIL")
2072 (set_attr "type" "larl")
2073 (set_attr "z10prop" "z10_fwd_A1")
2074 (set_attr "relative_long" "yes")])
2075
2076 (define_insn "*movsi_zarch"
2077 [(set (match_operand:SI 0 "nonimmediate_operand"
2078 "=d, d, d, d,d,d,d,d,d,R,T,!*f,!*f,!*f,!*f,!*f,!R,!T,d,t,Q,b,Q,t,v,v,v,d,v,R")
2079 (match_operand:SI 1 "general_operand"
2080 " K,N0HS0,N1HS0,Os,L,b,d,R,T,d,d, *f, *f, R, R, T,*f,*f,t,d,t,d,K,Q,K,v,d,v,R,v"))]
2081 "TARGET_ZARCH"
2082 "@
2083 lhi\t%0,%h1
2084 llilh\t%0,%i1
2085 llill\t%0,%i1
2086 iilf\t%0,%o1
2087 lay\t%0,%a1
2088 lrl\t%0,%1
2089 lr\t%0,%1
2090 l\t%0,%1
2091 ly\t%0,%1
2092 st\t%1,%0
2093 sty\t%1,%0
2094 ldr\t%0,%1
2095 ler\t%0,%1
2096 lde\t%0,%1
2097 le\t%0,%1
2098 ley\t%0,%1
2099 ste\t%1,%0
2100 stey\t%1,%0
2101 ear\t%0,%1
2102 sar\t%0,%1
2103 stam\t%1,%1,%S0
2104 strl\t%1,%0
2105 mvhi\t%0,%1
2106 lam\t%0,%0,%S1
2107 vleif\t%v0,%h1,0
2108 vlr\t%v0,%v1
2109 vlvgf\t%v0,%1,0
2110 vlgvf\t%0,%v1,0
2111 vlef\t%v0,%1,0
2112 vstef\t%v1,%0,0"
2113 [(set_attr "op_type" "RI,RI,RI,RIL,RXY,RIL,RR,RX,RXY,RX,RXY,
2114 RR,RR,RXE,RX,RXY,RX,RXY,RRE,RRE,RS,RIL,SIL,RS,VRI,VRR,VRS,VRS,VRX,VRX")
2115 (set_attr "type" "*,
2116 *,
2117 *,
2118 *,
2119 la,
2120 larl,
2121 lr,
2122 load,
2123 load,
2124 store,
2125 store,
2126 floadsf,
2127 floadsf,
2128 floadsf,
2129 floadsf,
2130 floadsf,
2131 fstoresf,
2132 fstoresf,
2133 *,
2134 *,
2135 *,
2136 larl,
2137 *,
2138 *,*,*,*,*,*,*")
2139 (set_attr "cpu_facility" "*,*,*,extimm,longdisp,z10,*,*,longdisp,*,longdisp,
2140 vx,*,vx,*,longdisp,*,longdisp,*,*,*,z10,z10,*,vx,vx,vx,vx,vx,vx")
2141 (set_attr "z10prop" "z10_fwd_A1,
2142 z10_fwd_E1,
2143 z10_fwd_E1,
2144 z10_fwd_A1,
2145 z10_fwd_A1,
2146 z10_fwd_A3,
2147 z10_fr_E1,
2148 z10_fwd_A3,
2149 z10_fwd_A3,
2150 z10_rec,
2151 z10_rec,
2152 *,
2153 *,
2154 *,
2155 *,
2156 *,
2157 *,
2158 *,
2159 z10_super_E1,
2160 z10_super,
2161 *,
2162 z10_rec,
2163 z10_super,
2164 *,*,*,*,*,*,*")
2165 (set_attr "relative_long" "*,*,*,*,*,yes,*,*,*,*,
2166 *,*,*,*,*,*,*,*,*,*,
2167 *,yes,*,*,*,*,*,*,*,*")])
2168
2169 (define_insn "*movsi_esa"
2170 [(set (match_operand:SI 0 "nonimmediate_operand" "=d,d,d,R,!*f,!*f,!*f,!*f,!R,d,t,Q,t")
2171 (match_operand:SI 1 "general_operand" "K,d,R,d, *f, *f, R, R,*f,t,d,t,Q"))]
2172 "!TARGET_ZARCH"
2173 "@
2174 lhi\t%0,%h1
2175 lr\t%0,%1
2176 l\t%0,%1
2177 st\t%1,%0
2178 ldr\t%0,%1
2179 ler\t%0,%1
2180 lde\t%0,%1
2181 le\t%0,%1
2182 ste\t%1,%0
2183 ear\t%0,%1
2184 sar\t%0,%1
2185 stam\t%1,%1,%S0
2186 lam\t%0,%0,%S1"
2187 [(set_attr "op_type" "RI,RR,RX,RX,RR,RR,RXE,RX,RX,RRE,RRE,RS,RS")
2188 (set_attr "type" "*,lr,load,store,floadsf,floadsf,floadsf,floadsf,fstoresf,*,*,*,*")
2189 (set_attr "z10prop" "z10_fwd_A1,z10_fr_E1,z10_fwd_A3,z10_rec,*,*,*,*,*,z10_super_E1,
2190 z10_super,*,*")
2191 (set_attr "cpu_facility" "*,*,*,*,vx,*,vx,*,*,*,*,*,*")
2192 ])
2193
2194 (define_peephole2
2195 [(set (match_operand:SI 0 "register_operand" "")
2196 (mem:SI (match_operand 1 "address_operand" "")))]
2197 "!FP_REG_P (operands[0])
2198 && GET_CODE (operands[1]) == SYMBOL_REF
2199 && CONSTANT_POOL_ADDRESS_P (operands[1])
2200 && get_pool_mode (operands[1]) == SImode
2201 && legitimate_reload_constant_p (get_pool_constant (operands[1]))"
2202 [(set (match_dup 0) (match_dup 2))]
2203 "operands[2] = get_pool_constant (operands[1]);")
2204
2205 (define_insn "*la_31"
2206 [(set (match_operand:SI 0 "register_operand" "=d,d")
2207 (match_operand:QI 1 "address_operand" "ZR,ZT"))]
2208 "!TARGET_64BIT && legitimate_la_operand_p (operands[1])"
2209 "@
2210 la\t%0,%a1
2211 lay\t%0,%a1"
2212 [(set_attr "op_type" "RX,RXY")
2213 (set_attr "type" "la")
2214 (set_attr "cpu_facility" "*,longdisp")
2215 (set_attr "z10prop" "z10_fwd_A1,z10_fwd_A1")])
2216
2217 (define_peephole2
2218 [(parallel
2219 [(set (match_operand:SI 0 "register_operand" "")
2220 (match_operand:QI 1 "address_operand" ""))
2221 (clobber (reg:CC CC_REGNUM))])]
2222 "!TARGET_64BIT
2223 && preferred_la_operand_p (operands[1], const0_rtx)"
2224 [(set (match_dup 0) (match_dup 1))]
2225 "")
2226
2227 (define_peephole2
2228 [(set (match_operand:SI 0 "register_operand" "")
2229 (match_operand:SI 1 "register_operand" ""))
2230 (parallel
2231 [(set (match_dup 0)
2232 (plus:SI (match_dup 0)
2233 (match_operand:SI 2 "nonmemory_operand" "")))
2234 (clobber (reg:CC CC_REGNUM))])]
2235 "!TARGET_64BIT
2236 && !reg_overlap_mentioned_p (operands[0], operands[2])
2237 && preferred_la_operand_p (operands[1], operands[2])"
2238 [(set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))]
2239 "")
2240
2241 (define_insn "*la_31_and"
2242 [(set (match_operand:SI 0 "register_operand" "=d,d")
2243 (and:SI (match_operand:QI 1 "address_operand" "ZR,ZT")
2244 (const_int 2147483647)))]
2245 "!TARGET_64BIT"
2246 "@
2247 la\t%0,%a1
2248 lay\t%0,%a1"
2249 [(set_attr "op_type" "RX,RXY")
2250 (set_attr "type" "la")
2251 (set_attr "cpu_facility" "*,longdisp")
2252 (set_attr "z10prop" "z10_fwd_A1,z10_fwd_A1")])
2253
2254 (define_insn_and_split "*la_31_and_cc"
2255 [(set (match_operand:SI 0 "register_operand" "=d")
2256 (and:SI (match_operand:QI 1 "address_operand" "p")
2257 (const_int 2147483647)))
2258 (clobber (reg:CC CC_REGNUM))]
2259 "!TARGET_64BIT"
2260 "#"
2261 "&& reload_completed"
2262 [(set (match_dup 0)
2263 (and:SI (match_dup 1) (const_int 2147483647)))]
2264 ""
2265 [(set_attr "op_type" "RX")
2266 (set_attr "type" "la")])
2267
2268 (define_insn "force_la_31"
2269 [(set (match_operand:SI 0 "register_operand" "=d,d")
2270 (match_operand:QI 1 "address_operand" "ZR,ZT"))
2271 (use (const_int 0))]
2272 "!TARGET_64BIT"
2273 "@
2274 la\t%0,%a1
2275 lay\t%0,%a1"
2276 [(set_attr "op_type" "RX")
2277 (set_attr "type" "la")
2278 (set_attr "cpu_facility" "*,longdisp")
2279 (set_attr "z10prop" "z10_fwd_A1,z10_fwd_A1")])
2280
2281 ;
2282 ; movhi instruction pattern(s).
2283 ;
2284
2285 (define_expand "movhi"
2286 [(set (match_operand:HI 0 "nonimmediate_operand" "")
2287 (match_operand:HI 1 "general_operand" ""))]
2288 ""
2289 {
2290 /* Make it explicit that loading a register from memory
2291 always sign-extends (at least) to SImode. */
2292 if (optimize && can_create_pseudo_p ()
2293 && register_operand (operands[0], VOIDmode)
2294 && GET_CODE (operands[1]) == MEM)
2295 {
2296 rtx tmp = gen_reg_rtx (SImode);
2297 rtx ext = gen_rtx_SIGN_EXTEND (SImode, operands[1]);
2298 emit_insn (gen_rtx_SET (tmp, ext));
2299 operands[1] = gen_lowpart (HImode, tmp);
2300 }
2301 })
2302
2303 (define_insn "*movhi"
2304 [(set (match_operand:HI 0 "nonimmediate_operand" "=d,d,d,d,d,R,T,b,Q,v,v,v,d,v,R")
2305 (match_operand:HI 1 "general_operand" " d,n,R,T,b,d,d,d,K,K,v,d,v,R,v"))]
2306 ""
2307 "@
2308 lr\t%0,%1
2309 lhi\t%0,%h1
2310 lh\t%0,%1
2311 lhy\t%0,%1
2312 lhrl\t%0,%1
2313 sth\t%1,%0
2314 sthy\t%1,%0
2315 sthrl\t%1,%0
2316 mvhhi\t%0,%1
2317 vleih\t%v0,%h1,0
2318 vlr\t%v0,%v1
2319 vlvgh\t%v0,%1,0
2320 vlgvh\t%0,%v1,0
2321 vleh\t%v0,%1,0
2322 vsteh\t%v1,%0,0"
2323 [(set_attr "op_type" "RR,RI,RX,RXY,RIL,RX,RXY,RIL,SIL,VRI,VRR,VRS,VRS,VRX,VRX")
2324 (set_attr "type" "lr,*,*,*,larl,store,store,store,*,*,*,*,*,*,*")
2325 (set_attr "cpu_facility" "*,*,*,longdisp,z10,*,longdisp,z10,z10,vx,vx,vx,vx,vx,vx")
2326 (set_attr "z10prop" "z10_fr_E1,
2327 z10_fwd_A1,
2328 z10_super_E1,
2329 z10_super_E1,
2330 z10_super_E1,
2331 z10_rec,
2332 z10_rec,
2333 z10_rec,
2334 z10_super,*,*,*,*,*,*")
2335 (set_attr "relative_long" "*,*,*,*,yes,*,*,yes,*,*,*,*,*,*,*")])
2336
2337 (define_peephole2
2338 [(set (match_operand:HI 0 "register_operand" "")
2339 (mem:HI (match_operand 1 "address_operand" "")))]
2340 "GET_CODE (operands[1]) == SYMBOL_REF
2341 && CONSTANT_POOL_ADDRESS_P (operands[1])
2342 && get_pool_mode (operands[1]) == HImode
2343 && GET_CODE (get_pool_constant (operands[1])) == CONST_INT"
2344 [(set (match_dup 0) (match_dup 2))]
2345 "operands[2] = get_pool_constant (operands[1]);")
2346
2347 ;
2348 ; movqi instruction pattern(s).
2349 ;
2350
2351 (define_expand "movqi"
2352 [(set (match_operand:QI 0 "nonimmediate_operand" "")
2353 (match_operand:QI 1 "general_operand" ""))]
2354 ""
2355 {
2356 /* On z/Architecture, zero-extending from memory to register
2357 is just as fast as a QImode load. */
2358 if (TARGET_ZARCH && optimize && can_create_pseudo_p ()
2359 && register_operand (operands[0], VOIDmode)
2360 && GET_CODE (operands[1]) == MEM)
2361 {
2362 rtx tmp = gen_reg_rtx (DImode);
2363 rtx ext = gen_rtx_ZERO_EXTEND (DImode, operands[1]);
2364 emit_insn (gen_rtx_SET (tmp, ext));
2365 operands[1] = gen_lowpart (QImode, tmp);
2366 }
2367 })
2368
2369 (define_insn "*movqi"
2370 [(set (match_operand:QI 0 "nonimmediate_operand" "=d,d,d,d,R,T,Q,S,?Q,v,v,v,d,v,R")
2371 (match_operand:QI 1 "general_operand" " d,n,R,T,d,d,n,n,?Q,K,v,d,v,R,v"))]
2372 ""
2373 "@
2374 lr\t%0,%1
2375 lhi\t%0,%b1
2376 ic\t%0,%1
2377 icy\t%0,%1
2378 stc\t%1,%0
2379 stcy\t%1,%0
2380 mvi\t%S0,%b1
2381 mviy\t%S0,%b1
2382 #
2383 vleib\t%v0,%b1,0
2384 vlr\t%v0,%v1
2385 vlvgb\t%v0,%1,0
2386 vlgvb\t%0,%v1,0
2387 vleb\t%v0,%1,0
2388 vsteb\t%v1,%0,0"
2389 [(set_attr "op_type" "RR,RI,RX,RXY,RX,RXY,SI,SIY,SS,VRI,VRR,VRS,VRS,VRX,VRX")
2390 (set_attr "type" "lr,*,*,*,store,store,store,store,*,*,*,*,*,*,*")
2391 (set_attr "cpu_facility" "*,*,*,longdisp,*,longdisp,*,longdisp,*,vx,vx,vx,vx,vx,vx")
2392 (set_attr "z10prop" "z10_fr_E1,
2393 z10_fwd_A1,
2394 z10_super_E1,
2395 z10_super_E1,
2396 z10_rec,
2397 z10_rec,
2398 z10_super,
2399 z10_super,
2400 *,*,*,*,*,*,*")])
2401
2402 (define_peephole2
2403 [(set (match_operand:QI 0 "nonimmediate_operand" "")
2404 (mem:QI (match_operand 1 "address_operand" "")))]
2405 "GET_CODE (operands[1]) == SYMBOL_REF
2406 && CONSTANT_POOL_ADDRESS_P (operands[1])
2407 && get_pool_mode (operands[1]) == QImode
2408 && GET_CODE (get_pool_constant (operands[1])) == CONST_INT"
2409 [(set (match_dup 0) (match_dup 2))]
2410 "operands[2] = get_pool_constant (operands[1]);")
2411
2412 ;
2413 ; movstrictqi instruction pattern(s).
2414 ;
2415
2416 (define_insn "*movstrictqi"
2417 [(set (strict_low_part (match_operand:QI 0 "register_operand" "+d,d"))
2418 (match_operand:QI 1 "memory_operand" "R,T"))]
2419 ""
2420 "@
2421 ic\t%0,%1
2422 icy\t%0,%1"
2423 [(set_attr "op_type" "RX,RXY")
2424 (set_attr "cpu_facility" "*,longdisp")
2425 (set_attr "z10prop" "z10_super_E1,z10_super_E1")])
2426
2427 ;
2428 ; movstricthi instruction pattern(s).
2429 ;
2430
2431 (define_insn "*movstricthi"
2432 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+d,d"))
2433 (match_operand:HI 1 "memory_operand" "Q,S"))
2434 (clobber (reg:CC CC_REGNUM))]
2435 ""
2436 "@
2437 icm\t%0,3,%S1
2438 icmy\t%0,3,%S1"
2439 [(set_attr "op_type" "RS,RSY")
2440 (set_attr "cpu_facility" "*,longdisp")
2441 (set_attr "z10prop" "z10_super_E1,z10_super_E1")])
2442
2443 ;
2444 ; movstrictsi instruction pattern(s).
2445 ;
2446
2447 (define_insn "movstrictsi"
2448 [(set (strict_low_part (match_operand:SI 0 "register_operand" "+d,d,d,d"))
2449 (match_operand:SI 1 "general_operand" "d,R,T,t"))]
2450 "TARGET_ZARCH"
2451 "@
2452 lr\t%0,%1
2453 l\t%0,%1
2454 ly\t%0,%1
2455 ear\t%0,%1"
2456 [(set_attr "op_type" "RR,RX,RXY,RRE")
2457 (set_attr "type" "lr,load,load,*")
2458 (set_attr "cpu_facility" "*,*,longdisp,*")
2459 (set_attr "z10prop" "z10_fr_E1,z10_fwd_A3,z10_fwd_A3,z10_super_E1")])
2460
2461 ;
2462 ; mov(tf|td) instruction pattern(s).
2463 ;
2464
2465 (define_expand "mov<mode>"
2466 [(set (match_operand:TD_TF 0 "nonimmediate_operand" "")
2467 (match_operand:TD_TF 1 "general_operand" ""))]
2468 ""
2469 "")
2470
2471 (define_insn "*mov<mode>_64"
2472 [(set (match_operand:TD_TF 0 "nonimmediate_operand" "=f,f,f,o,d,S, d,o")
2473 (match_operand:TD_TF 1 "general_operand" " G,f,o,f,S,d,dT,d"))]
2474 "TARGET_ZARCH"
2475 "@
2476 lzxr\t%0
2477 lxr\t%0,%1
2478 #
2479 #
2480 lmg\t%0,%N0,%S1
2481 stmg\t%1,%N1,%S0
2482 #
2483 #"
2484 [(set_attr "op_type" "RRE,RRE,*,*,RSY,RSY,*,*")
2485 (set_attr "type" "fsimptf,fsimptf,*,*,lm,stm,*,*")
2486 (set_attr "cpu_facility" "z196,*,*,*,*,*,*,*")])
2487
2488 (define_insn "*mov<mode>_31"
2489 [(set (match_operand:TD_TF 0 "nonimmediate_operand" "=f,f,f,o")
2490 (match_operand:TD_TF 1 "general_operand" " G,f,o,f"))]
2491 "!TARGET_ZARCH"
2492 "@
2493 lzxr\t%0
2494 lxr\t%0,%1
2495 #
2496 #"
2497 [(set_attr "op_type" "RRE,RRE,*,*")
2498 (set_attr "type" "fsimptf,fsimptf,*,*")
2499 (set_attr "cpu_facility" "z196,*,*,*")])
2500
2501 ; TFmode in GPRs splitters
2502
2503 (define_split
2504 [(set (match_operand:TD_TF 0 "nonimmediate_operand" "")
2505 (match_operand:TD_TF 1 "general_operand" ""))]
2506 "TARGET_ZARCH && reload_completed
2507 && !s_operand (operands[0], <MODE>mode)
2508 && !s_operand (operands[1], <MODE>mode)
2509 && s390_split_ok_p (operands[0], operands[1], <MODE>mode, 0)"
2510 [(set (match_dup 2) (match_dup 4))
2511 (set (match_dup 3) (match_dup 5))]
2512 {
2513 operands[2] = operand_subword (operands[0], 0, 0, <MODE>mode);
2514 operands[3] = operand_subword (operands[0], 1, 0, <MODE>mode);
2515 operands[4] = operand_subword (operands[1], 0, 0, <MODE>mode);
2516 operands[5] = operand_subword (operands[1], 1, 0, <MODE>mode);
2517 })
2518
2519 (define_split
2520 [(set (match_operand:TD_TF 0 "nonimmediate_operand" "")
2521 (match_operand:TD_TF 1 "general_operand" ""))]
2522 "TARGET_ZARCH && reload_completed
2523 && !s_operand (operands[0], <MODE>mode)
2524 && !s_operand (operands[1], <MODE>mode)
2525 && s390_split_ok_p (operands[0], operands[1], <MODE>mode, 1)"
2526 [(set (match_dup 2) (match_dup 4))
2527 (set (match_dup 3) (match_dup 5))]
2528 {
2529 operands[2] = operand_subword (operands[0], 1, 0, <MODE>mode);
2530 operands[3] = operand_subword (operands[0], 0, 0, <MODE>mode);
2531 operands[4] = operand_subword (operands[1], 1, 0, <MODE>mode);
2532 operands[5] = operand_subword (operands[1], 0, 0, <MODE>mode);
2533 })
2534
2535 (define_split
2536 [(set (match_operand:TD_TF 0 "register_operand" "")
2537 (match_operand:TD_TF 1 "memory_operand" ""))]
2538 "TARGET_ZARCH && reload_completed
2539 && GENERAL_REG_P (operands[0])
2540 && !s_operand (operands[1], VOIDmode)"
2541 [(set (match_dup 0) (match_dup 1))]
2542 {
2543 rtx addr = operand_subword (operands[0], 1, 0, <MODE>mode);
2544 addr = gen_lowpart (Pmode, addr);
2545 s390_load_address (addr, XEXP (operands[1], 0));
2546 operands[1] = replace_equiv_address (operands[1], addr);
2547 })
2548
2549 ; TFmode in BFPs splitters
2550
2551 (define_split
2552 [(set (match_operand:TD_TF 0 "register_operand" "")
2553 (match_operand:TD_TF 1 "memory_operand" ""))]
2554 "reload_completed && offsettable_memref_p (operands[1])
2555 && FP_REG_P (operands[0])"
2556 [(set (match_dup 2) (match_dup 4))
2557 (set (match_dup 3) (match_dup 5))]
2558 {
2559 operands[2] = simplify_gen_subreg (<HALF_TMODE>mode, operands[0],
2560 <MODE>mode, 0);
2561 operands[3] = simplify_gen_subreg (<HALF_TMODE>mode, operands[0],
2562 <MODE>mode, 8);
2563 operands[4] = adjust_address_nv (operands[1], <HALF_TMODE>mode, 0);
2564 operands[5] = adjust_address_nv (operands[1], <HALF_TMODE>mode, 8);
2565 })
2566
2567 (define_split
2568 [(set (match_operand:TD_TF 0 "memory_operand" "")
2569 (match_operand:TD_TF 1 "register_operand" ""))]
2570 "reload_completed && offsettable_memref_p (operands[0])
2571 && FP_REG_P (operands[1])"
2572 [(set (match_dup 2) (match_dup 4))
2573 (set (match_dup 3) (match_dup 5))]
2574 {
2575 operands[2] = adjust_address_nv (operands[0], <HALF_TMODE>mode, 0);
2576 operands[3] = adjust_address_nv (operands[0], <HALF_TMODE>mode, 8);
2577 operands[4] = simplify_gen_subreg (<HALF_TMODE>mode, operands[1],
2578 <MODE>mode, 0);
2579 operands[5] = simplify_gen_subreg (<HALF_TMODE>mode, operands[1],
2580 <MODE>mode, 8);
2581 })
2582
2583 ;
2584 ; mov(df|dd) instruction pattern(s).
2585 ;
2586
2587 (define_expand "mov<mode>"
2588 [(set (match_operand:DD_DF 0 "nonimmediate_operand" "")
2589 (match_operand:DD_DF 1 "general_operand" ""))]
2590 ""
2591 "")
2592
2593 (define_insn "*mov<mode>_64dfp"
2594 [(set (match_operand:DD_DF 0 "nonimmediate_operand"
2595 "=f,f,f,d,f,f,R,T,d,d,d,d,b,T,v,v,v,d,v,R")
2596 (match_operand:DD_DF 1 "general_operand"
2597 " G,f,d,f,R,T,f,f,G,d,b,T,d,d,v,G,d,v,R,v"))]
2598 "TARGET_DFP"
2599 "@
2600 lzdr\t%0
2601 ldr\t%0,%1
2602 ldgr\t%0,%1
2603 lgdr\t%0,%1
2604 ld\t%0,%1
2605 ldy\t%0,%1
2606 std\t%1,%0
2607 stdy\t%1,%0
2608 lghi\t%0,0
2609 lgr\t%0,%1
2610 lgrl\t%0,%1
2611 lg\t%0,%1
2612 stgrl\t%1,%0
2613 stg\t%1,%0
2614 vlr\t%v0,%v1
2615 vleig\t%v0,0,0
2616 vlvgg\t%v0,%1,0
2617 vlgvg\t%0,%v1,0
2618 vleg\t%0,%1,0
2619 vsteg\t%1,%0,0"
2620 [(set_attr "op_type" "RRE,RR,RRE,RRE,RX,RXY,RX,RXY,RI,RRE,RIL,RXY,RIL,RXY,VRR,VRI,VRS,VRS,VRX,VRX")
2621 (set_attr "type" "fsimpdf,floaddf,floaddf,floaddf,floaddf,floaddf,
2622 fstoredf,fstoredf,*,lr,load,load,store,store,*,*,*,*,load,store")
2623 (set_attr "z10prop" "*,*,*,*,*,*,*,*,z10_fwd_A1,z10_fr_E1,z10_fwd_A3,z10_fwd_A3,z10_rec,z10_rec,*,*,*,*,*,*")
2624 (set_attr "cpu_facility" "z196,*,*,*,*,longdisp,*,longdisp,*,*,z10,*,z10,*,vx,vx,vx,vx,vx,vx")
2625 (set_attr "relative_long" "*,*,*,*,*,*,*,*,*,*,yes,*,yes,*,*,*,*,*,*,*")])
2626
2627 (define_insn "*mov<mode>_64"
2628 [(set (match_operand:DD_DF 0 "nonimmediate_operand" "=f,f,f,f,R,T,d,d,d,d,b,T")
2629 (match_operand:DD_DF 1 "general_operand" " G,f,R,T,f,f,G,d,b,T,d,d"))]
2630 "TARGET_ZARCH"
2631 "@
2632 lzdr\t%0
2633 ldr\t%0,%1
2634 ld\t%0,%1
2635 ldy\t%0,%1
2636 std\t%1,%0
2637 stdy\t%1,%0
2638 lghi\t%0,0
2639 lgr\t%0,%1
2640 lgrl\t%0,%1
2641 lg\t%0,%1
2642 stgrl\t%1,%0
2643 stg\t%1,%0"
2644 [(set_attr "op_type" "RRE,RR,RX,RXY,RX,RXY,RI,RRE,RIL,RXY,RIL,RXY")
2645 (set_attr "type" "fsimpdf,fload<mode>,fload<mode>,fload<mode>,
2646 fstore<mode>,fstore<mode>,*,lr,load,load,store,store")
2647 (set_attr "z10prop" "*,*,*,*,*,*,z10_fwd_A1,z10_fr_E1,z10_fwd_A3,z10_fwd_A3,z10_rec,z10_rec")
2648 (set_attr "cpu_facility" "z196,*,*,longdisp,*,longdisp,*,*,z10,*,z10,*")
2649 (set_attr "relative_long" "*,*,*,*,*,*,*,*,yes,*,*,*")])
2650
2651 (define_insn "*mov<mode>_31"
2652 [(set (match_operand:DD_DF 0 "nonimmediate_operand"
2653 "=f,f,f,f,R,T,d,d,Q,S, d,o")
2654 (match_operand:DD_DF 1 "general_operand"
2655 " G,f,R,T,f,f,Q,S,d,d,dPT,d"))]
2656 "!TARGET_ZARCH"
2657 "@
2658 lzdr\t%0
2659 ldr\t%0,%1
2660 ld\t%0,%1
2661 ldy\t%0,%1
2662 std\t%1,%0
2663 stdy\t%1,%0
2664 lm\t%0,%N0,%S1
2665 lmy\t%0,%N0,%S1
2666 stm\t%1,%N1,%S0
2667 stmy\t%1,%N1,%S0
2668 #
2669 #"
2670 [(set_attr "op_type" "RRE,RR,RX,RXY,RX,RXY,RS,RSY,RS,RSY,*,*")
2671 (set_attr "type" "fsimpdf,fload<mode>,fload<mode>,fload<mode>,
2672 fstore<mode>,fstore<mode>,lm,lm,stm,stm,*,*")
2673 (set_attr "cpu_facility" "z196,*,*,longdisp,*,longdisp,*,longdisp,*,longdisp,*,*")])
2674
2675 (define_split
2676 [(set (match_operand:DD_DF 0 "nonimmediate_operand" "")
2677 (match_operand:DD_DF 1 "general_operand" ""))]
2678 "!TARGET_ZARCH && reload_completed
2679 && !s_operand (operands[0], <MODE>mode)
2680 && !s_operand (operands[1], <MODE>mode)
2681 && s390_split_ok_p (operands[0], operands[1], <MODE>mode, 0)"
2682 [(set (match_dup 2) (match_dup 4))
2683 (set (match_dup 3) (match_dup 5))]
2684 {
2685 operands[2] = operand_subword (operands[0], 0, 0, <MODE>mode);
2686 operands[3] = operand_subword (operands[0], 1, 0, <MODE>mode);
2687 operands[4] = operand_subword (operands[1], 0, 0, <MODE>mode);
2688 operands[5] = operand_subword (operands[1], 1, 0, <MODE>mode);
2689 })
2690
2691 (define_split
2692 [(set (match_operand:DD_DF 0 "nonimmediate_operand" "")
2693 (match_operand:DD_DF 1 "general_operand" ""))]
2694 "!TARGET_ZARCH && reload_completed
2695 && !s_operand (operands[0], <MODE>mode)
2696 && !s_operand (operands[1], <MODE>mode)
2697 && s390_split_ok_p (operands[0], operands[1], <MODE>mode, 1)"
2698 [(set (match_dup 2) (match_dup 4))
2699 (set (match_dup 3) (match_dup 5))]
2700 {
2701 operands[2] = operand_subword (operands[0], 1, 0, <MODE>mode);
2702 operands[3] = operand_subword (operands[0], 0, 0, <MODE>mode);
2703 operands[4] = operand_subword (operands[1], 1, 0, <MODE>mode);
2704 operands[5] = operand_subword (operands[1], 0, 0, <MODE>mode);
2705 })
2706
2707 (define_split
2708 [(set (match_operand:DD_DF 0 "register_operand" "")
2709 (match_operand:DD_DF 1 "memory_operand" ""))]
2710 "!TARGET_ZARCH && reload_completed
2711 && !FP_REG_P (operands[0])
2712 && !s_operand (operands[1], VOIDmode)"
2713 [(set (match_dup 0) (match_dup 1))]
2714 {
2715 rtx addr = operand_subword (operands[0], 1, 0, <MODE>mode);
2716 s390_load_address (addr, XEXP (operands[1], 0));
2717 operands[1] = replace_equiv_address (operands[1], addr);
2718 })
2719
2720 ;
2721 ; mov(sf|sd) instruction pattern(s).
2722 ;
2723
2724 (define_insn "mov<mode>"
2725 [(set (match_operand:SD_SF 0 "nonimmediate_operand"
2726 "=f,f,f,f,f,f,R,T,d,d,d,d,d,b,R,T,v,v,v,d,v,R")
2727 (match_operand:SD_SF 1 "general_operand"
2728 " G,f,f,R,R,T,f,f,G,d,b,R,T,d,d,d,v,G,d,v,R,v"))]
2729 ""
2730 "@
2731 lzer\t%0
2732 ldr\t%0,%1
2733 ler\t%0,%1
2734 lde\t%0,%1
2735 le\t%0,%1
2736 ley\t%0,%1
2737 ste\t%1,%0
2738 stey\t%1,%0
2739 lhi\t%0,0
2740 lr\t%0,%1
2741 lrl\t%0,%1
2742 l\t%0,%1
2743 ly\t%0,%1
2744 strl\t%1,%0
2745 st\t%1,%0
2746 sty\t%1,%0
2747 vlr\t%v0,%v1
2748 vleif\t%v0,0,0
2749 vlvgf\t%v0,%1,0
2750 vlgvf\t%0,%v1,0
2751 vlef\t%0,%1,0
2752 vstef\t%1,%0,0"
2753 [(set_attr "op_type" "RRE,RR,RR,RXE,RX,RXY,RX,RXY,RI,RR,RIL,RX,RXY,RIL,RX,RXY,VRR,VRI,VRS,VRS,VRX,VRX")
2754 (set_attr "type" "fsimpsf,fsimpsf,fload<mode>,fload<mode>,fload<mode>,fload<mode>,
2755 fstore<mode>,fstore<mode>,*,lr,load,load,load,store,store,store,*,*,*,*,load,store")
2756 (set_attr "z10prop" "*,*,*,*,*,*,*,*,z10_fwd_A1,z10_fr_E1,z10_fr_E1,z10_fwd_A3,z10_fwd_A3,z10_rec,z10_rec,z10_rec,*,*,*,*,*,*")
2757 (set_attr "cpu_facility" "z196,vx,*,vx,*,longdisp,*,longdisp,*,*,z10,*,longdisp,z10,*,longdisp,vx,vx,vx,vx,vx,vx")
2758 (set_attr "relative_long" "*,*,*,*,*,*,*,*,*,*,yes,*,*,yes,*,*,*,*,*,*,*,*")])
2759
2760 ;
2761 ; movcc instruction pattern
2762 ;
2763
2764 (define_insn "movcc"
2765 [(set (match_operand:CC 0 "nonimmediate_operand" "=d,c,d,d,d,R,T")
2766 (match_operand:CC 1 "nonimmediate_operand" " d,d,c,R,T,d,d"))]
2767 ""
2768 "@
2769 lr\t%0,%1
2770 tmh\t%1,12288
2771 ipm\t%0
2772 l\t%0,%1
2773 ly\t%0,%1
2774 st\t%1,%0
2775 sty\t%1,%0"
2776 [(set_attr "op_type" "RR,RI,RRE,RX,RXY,RX,RXY")
2777 (set_attr "type" "lr,*,*,load,load,store,store")
2778 (set_attr "cpu_facility" "*,*,*,*,longdisp,*,longdisp")
2779 (set_attr "z10prop" "z10_fr_E1,z10_super,*,z10_fwd_A3,z10_fwd_A3,z10_rec,z10_rec")
2780 (set_attr "z196prop" "*,*,z196_ends,*,*,*,*")])
2781
2782 ;
2783 ; Block move (MVC) patterns.
2784 ;
2785
2786 (define_insn "*mvc"
2787 [(set (match_operand:BLK 0 "memory_operand" "=Q")
2788 (match_operand:BLK 1 "memory_operand" "Q"))
2789 (use (match_operand 2 "const_int_operand" "n"))]
2790 "INTVAL (operands[2]) >= 1 && INTVAL (operands[2]) <= 256"
2791 "mvc\t%O0(%2,%R0),%S1"
2792 [(set_attr "op_type" "SS")])
2793
2794 ; This splitter converts a QI to QI mode copy into a BLK mode copy in
2795 ; order to have it implemented with mvc.
2796
2797 (define_split
2798 [(set (match_operand:QI 0 "memory_operand" "")
2799 (match_operand:QI 1 "memory_operand" ""))]
2800 "reload_completed"
2801 [(parallel
2802 [(set (match_dup 0) (match_dup 1))
2803 (use (const_int 1))])]
2804 {
2805 operands[0] = adjust_address (operands[0], BLKmode, 0);
2806 operands[1] = adjust_address (operands[1], BLKmode, 0);
2807 })
2808
2809
2810 (define_peephole2
2811 [(parallel
2812 [(set (match_operand:BLK 0 "memory_operand" "")
2813 (match_operand:BLK 1 "memory_operand" ""))
2814 (use (match_operand 2 "const_int_operand" ""))])
2815 (parallel
2816 [(set (match_operand:BLK 3 "memory_operand" "")
2817 (match_operand:BLK 4 "memory_operand" ""))
2818 (use (match_operand 5 "const_int_operand" ""))])]
2819 "((INTVAL (operands[2]) > 16 && INTVAL (operands[5]) > 16)
2820 || (INTVAL (operands[2]) + INTVAL (operands[5]) <= 16))
2821 && s390_offset_p (operands[0], operands[3], operands[2])
2822 && s390_offset_p (operands[1], operands[4], operands[2])
2823 && !s390_overlap_p (operands[0], operands[1],
2824 INTVAL (operands[2]) + INTVAL (operands[5]))
2825 && INTVAL (operands[2]) + INTVAL (operands[5]) <= 256"
2826 [(parallel
2827 [(set (match_dup 6) (match_dup 7))
2828 (use (match_dup 8))])]
2829 "operands[6] = gen_rtx_MEM (BLKmode, XEXP (operands[0], 0));
2830 operands[7] = gen_rtx_MEM (BLKmode, XEXP (operands[1], 0));
2831 operands[8] = GEN_INT (INTVAL (operands[2]) + INTVAL (operands[5]));")
2832
2833 (define_peephole2
2834 [(parallel
2835 [(set (match_operand:BLK 0 "plus16_Q_operand" "")
2836 (match_operand:BLK 1 "plus16_Q_operand" ""))
2837 (use (match_operand 2 "const_int_operand" ""))])]
2838 "INTVAL (operands[2]) > 16 && INTVAL (operands[2]) <= 32"
2839 [(parallel
2840 [(set (match_dup 0) (match_dup 1))
2841 (use (const_int 16))])
2842 (parallel
2843 [(set (match_dup 3) (match_dup 4))
2844 (use (match_dup 5))])]
2845 "operands[3] = change_address (operands[0], VOIDmode,
2846 plus_constant (Pmode, XEXP (operands[0], 0), 16));
2847 operands[4] = change_address (operands[1], VOIDmode,
2848 plus_constant (Pmode, XEXP (operands[1], 0), 16));
2849 operands[5] = GEN_INT (INTVAL (operands[2]) - 16);")
2850
2851
2852 ;
2853 ; load_multiple pattern(s).
2854 ;
2855 ; ??? Due to reload problems with replacing registers inside match_parallel
2856 ; we currently support load_multiple/store_multiple only after reload.
2857 ;
2858
2859 (define_expand "load_multiple"
2860 [(match_par_dup 3 [(set (match_operand 0 "" "")
2861 (match_operand 1 "" ""))
2862 (use (match_operand 2 "" ""))])]
2863 "reload_completed"
2864 {
2865 machine_mode mode;
2866 int regno;
2867 int count;
2868 rtx from;
2869 int i, off;
2870
2871 /* Support only loading a constant number of fixed-point registers from
2872 memory and only bother with this if more than two */
2873 if (GET_CODE (operands[2]) != CONST_INT
2874 || INTVAL (operands[2]) < 2
2875 || INTVAL (operands[2]) > 16
2876 || GET_CODE (operands[1]) != MEM
2877 || GET_CODE (operands[0]) != REG
2878 || REGNO (operands[0]) >= 16)
2879 FAIL;
2880
2881 count = INTVAL (operands[2]);
2882 regno = REGNO (operands[0]);
2883 mode = GET_MODE (operands[0]);
2884 if (mode != SImode && (!TARGET_ZARCH || mode != DImode))
2885 FAIL;
2886
2887 operands[3] = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (count));
2888 if (!can_create_pseudo_p ())
2889 {
2890 if (GET_CODE (XEXP (operands[1], 0)) == REG)
2891 {
2892 from = XEXP (operands[1], 0);
2893 off = 0;
2894 }
2895 else if (GET_CODE (XEXP (operands[1], 0)) == PLUS
2896 && GET_CODE (XEXP (XEXP (operands[1], 0), 0)) == REG
2897 && GET_CODE (XEXP (XEXP (operands[1], 0), 1)) == CONST_INT)
2898 {
2899 from = XEXP (XEXP (operands[1], 0), 0);
2900 off = INTVAL (XEXP (XEXP (operands[1], 0), 1));
2901 }
2902 else
2903 FAIL;
2904 }
2905 else
2906 {
2907 from = force_reg (Pmode, XEXP (operands[1], 0));
2908 off = 0;
2909 }
2910
2911 for (i = 0; i < count; i++)
2912 XVECEXP (operands[3], 0, i)
2913 = gen_rtx_SET (gen_rtx_REG (mode, regno + i),
2914 change_address (operands[1], mode,
2915 plus_constant (Pmode, from,
2916 off + i * GET_MODE_SIZE (mode))));
2917 })
2918
2919 (define_insn "*load_multiple_di"
2920 [(match_parallel 0 "load_multiple_operation"
2921 [(set (match_operand:DI 1 "register_operand" "=r")
2922 (match_operand:DI 2 "s_operand" "S"))])]
2923 "reload_completed && TARGET_ZARCH"
2924 {
2925 int words = XVECLEN (operands[0], 0);
2926 operands[0] = gen_rtx_REG (DImode, REGNO (operands[1]) + words - 1);
2927 return "lmg\t%1,%0,%S2";
2928 }
2929 [(set_attr "op_type" "RSY")
2930 (set_attr "type" "lm")])
2931
2932 (define_insn "*load_multiple_si"
2933 [(match_parallel 0 "load_multiple_operation"
2934 [(set (match_operand:SI 1 "register_operand" "=r,r")
2935 (match_operand:SI 2 "s_operand" "Q,S"))])]
2936 "reload_completed"
2937 {
2938 int words = XVECLEN (operands[0], 0);
2939 operands[0] = gen_rtx_REG (SImode, REGNO (operands[1]) + words - 1);
2940 return which_alternative == 0 ? "lm\t%1,%0,%S2" : "lmy\t%1,%0,%S2";
2941 }
2942 [(set_attr "op_type" "RS,RSY")
2943 (set_attr "cpu_facility" "*,longdisp")
2944 (set_attr "type" "lm")])
2945
2946 ;
2947 ; store multiple pattern(s).
2948 ;
2949
2950 (define_expand "store_multiple"
2951 [(match_par_dup 3 [(set (match_operand 0 "" "")
2952 (match_operand 1 "" ""))
2953 (use (match_operand 2 "" ""))])]
2954 "reload_completed"
2955 {
2956 machine_mode mode;
2957 int regno;
2958 int count;
2959 rtx to;
2960 int i, off;
2961
2962 /* Support only storing a constant number of fixed-point registers to
2963 memory and only bother with this if more than two. */
2964 if (GET_CODE (operands[2]) != CONST_INT
2965 || INTVAL (operands[2]) < 2
2966 || INTVAL (operands[2]) > 16
2967 || GET_CODE (operands[0]) != MEM
2968 || GET_CODE (operands[1]) != REG
2969 || REGNO (operands[1]) >= 16)
2970 FAIL;
2971
2972 count = INTVAL (operands[2]);
2973 regno = REGNO (operands[1]);
2974 mode = GET_MODE (operands[1]);
2975 if (mode != SImode && (!TARGET_ZARCH || mode != DImode))
2976 FAIL;
2977
2978 operands[3] = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (count));
2979
2980 if (!can_create_pseudo_p ())
2981 {
2982 if (GET_CODE (XEXP (operands[0], 0)) == REG)
2983 {
2984 to = XEXP (operands[0], 0);
2985 off = 0;
2986 }
2987 else if (GET_CODE (XEXP (operands[0], 0)) == PLUS
2988 && GET_CODE (XEXP (XEXP (operands[0], 0), 0)) == REG
2989 && GET_CODE (XEXP (XEXP (operands[0], 0), 1)) == CONST_INT)
2990 {
2991 to = XEXP (XEXP (operands[0], 0), 0);
2992 off = INTVAL (XEXP (XEXP (operands[0], 0), 1));
2993 }
2994 else
2995 FAIL;
2996 }
2997 else
2998 {
2999 to = force_reg (Pmode, XEXP (operands[0], 0));
3000 off = 0;
3001 }
3002
3003 for (i = 0; i < count; i++)
3004 XVECEXP (operands[3], 0, i)
3005 = gen_rtx_SET (change_address (operands[0], mode,
3006 plus_constant (Pmode, to,
3007 off + i * GET_MODE_SIZE (mode))),
3008 gen_rtx_REG (mode, regno + i));
3009 })
3010
3011 (define_insn "*store_multiple_di"
3012 [(match_parallel 0 "store_multiple_operation"
3013 [(set (match_operand:DI 1 "s_operand" "=S")
3014 (match_operand:DI 2 "register_operand" "r"))])]
3015 "reload_completed && TARGET_ZARCH"
3016 {
3017 int words = XVECLEN (operands[0], 0);
3018 operands[0] = gen_rtx_REG (DImode, REGNO (operands[2]) + words - 1);
3019 return "stmg\t%2,%0,%S1";
3020 }
3021 [(set_attr "op_type" "RSY")
3022 (set_attr "type" "stm")])
3023
3024
3025 (define_insn "*store_multiple_si"
3026 [(match_parallel 0 "store_multiple_operation"
3027 [(set (match_operand:SI 1 "s_operand" "=Q,S")
3028 (match_operand:SI 2 "register_operand" "r,r"))])]
3029 "reload_completed"
3030 {
3031 int words = XVECLEN (operands[0], 0);
3032 operands[0] = gen_rtx_REG (SImode, REGNO (operands[2]) + words - 1);
3033 return which_alternative == 0 ? "stm\t%2,%0,%S1" : "stmy\t%2,%0,%S1";
3034 }
3035 [(set_attr "op_type" "RS,RSY")
3036 (set_attr "cpu_facility" "*,longdisp")
3037 (set_attr "type" "stm")])
3038
3039 ;;
3040 ;; String instructions.
3041 ;;
3042
3043 (define_insn "*execute_rl"
3044 [(match_parallel 0 "execute_operation"
3045 [(unspec [(match_operand 1 "register_operand" "a")
3046 (match_operand 2 "" "")
3047 (match_operand:SI 3 "larl_operand" "X")] UNSPEC_EXECUTE)])]
3048 "TARGET_Z10 && GET_MODE_CLASS (GET_MODE (operands[1])) == MODE_INT
3049 && GET_MODE_SIZE (GET_MODE (operands[1])) <= UNITS_PER_WORD"
3050 "exrl\t%1,%3"
3051 [(set_attr "op_type" "RIL")
3052 (set_attr "type" "cs")
3053 (set_attr "relative_long" "yes")])
3054
3055 (define_insn "*execute"
3056 [(match_parallel 0 "execute_operation"
3057 [(unspec [(match_operand 1 "register_operand" "a")
3058 (match_operand:BLK 2 "memory_operand" "R")
3059 (match_operand 3 "" "")] UNSPEC_EXECUTE)])]
3060 "GET_MODE_CLASS (GET_MODE (operands[1])) == MODE_INT
3061 && GET_MODE_SIZE (GET_MODE (operands[1])) <= UNITS_PER_WORD"
3062 "ex\t%1,%2"
3063 [(set_attr "op_type" "RX")
3064 (set_attr "type" "cs")])
3065
3066
3067 ;
3068 ; strlenM instruction pattern(s).
3069 ;
3070
3071 (define_expand "strlen<mode>"
3072 [(match_operand:P 0 "register_operand" "") ; result
3073 (match_operand:BLK 1 "memory_operand" "") ; input string
3074 (match_operand:SI 2 "immediate_operand" "") ; search character
3075 (match_operand:SI 3 "immediate_operand" "")] ; known alignment
3076 ""
3077 {
3078 if (!TARGET_VX || operands[2] != const0_rtx)
3079 emit_insn (gen_strlen_srst<mode> (operands[0], operands[1],
3080 operands[2], operands[3]));
3081 else
3082 s390_expand_vec_strlen (operands[0], operands[1], operands[3]);
3083
3084 DONE;
3085 })
3086
3087 (define_expand "strlen_srst<mode>"
3088 [(set (reg:SI 0) (match_operand:SI 2 "immediate_operand" ""))
3089 (parallel
3090 [(set (match_dup 4)
3091 (unspec:P [(const_int 0)
3092 (match_operand:BLK 1 "memory_operand" "")
3093 (reg:SI 0)
3094 (match_operand 3 "immediate_operand" "")] UNSPEC_SRST))
3095 (clobber (scratch:P))
3096 (clobber (reg:CC CC_REGNUM))])
3097 (parallel
3098 [(set (match_operand:P 0 "register_operand" "")
3099 (minus:P (match_dup 4) (match_dup 5)))
3100 (clobber (reg:CC CC_REGNUM))])]
3101 ""
3102 {
3103 operands[4] = gen_reg_rtx (Pmode);
3104 operands[5] = gen_reg_rtx (Pmode);
3105 emit_move_insn (operands[5], force_operand (XEXP (operands[1], 0), NULL_RTX));
3106 operands[1] = replace_equiv_address (operands[1], operands[5]);
3107 })
3108
3109 (define_insn "*strlen<mode>"
3110 [(set (match_operand:P 0 "register_operand" "=a")
3111 (unspec:P [(match_operand:P 2 "general_operand" "0")
3112 (mem:BLK (match_operand:P 3 "register_operand" "1"))
3113 (reg:SI 0)
3114 (match_operand 4 "immediate_operand" "")] UNSPEC_SRST))
3115 (clobber (match_scratch:P 1 "=a"))
3116 (clobber (reg:CC CC_REGNUM))]
3117 ""
3118 "srst\t%0,%1\;jo\t.-4"
3119 [(set_attr "length" "8")
3120 (set_attr "type" "vs")])
3121
3122 ;
3123 ; cmpstrM instruction pattern(s).
3124 ;
3125
3126 (define_expand "cmpstrsi"
3127 [(set (reg:SI 0) (const_int 0))
3128 (parallel
3129 [(clobber (match_operand 3 "" ""))
3130 (clobber (match_dup 4))
3131 (set (reg:CCU CC_REGNUM)
3132 (compare:CCU (match_operand:BLK 1 "memory_operand" "")
3133 (match_operand:BLK 2 "memory_operand" "")))
3134 (use (reg:SI 0))])
3135 (parallel
3136 [(set (match_operand:SI 0 "register_operand" "=d")
3137 (unspec:SI [(reg:CCU CC_REGNUM)] UNSPEC_STRCMPCC_TO_INT))
3138 (clobber (reg:CC CC_REGNUM))])]
3139 ""
3140 {
3141 /* As the result of CMPINT is inverted compared to what we need,
3142 we have to swap the operands. */
3143 rtx op1 = operands[2];
3144 rtx op2 = operands[1];
3145 rtx addr1 = gen_reg_rtx (Pmode);
3146 rtx addr2 = gen_reg_rtx (Pmode);
3147
3148 emit_move_insn (addr1, force_operand (XEXP (op1, 0), NULL_RTX));
3149 emit_move_insn (addr2, force_operand (XEXP (op2, 0), NULL_RTX));
3150 operands[1] = replace_equiv_address_nv (op1, addr1);
3151 operands[2] = replace_equiv_address_nv (op2, addr2);
3152 operands[3] = addr1;
3153 operands[4] = addr2;
3154 })
3155
3156 (define_insn "*cmpstr<mode>"
3157 [(clobber (match_operand:P 0 "register_operand" "=d"))
3158 (clobber (match_operand:P 1 "register_operand" "=d"))
3159 (set (reg:CCU CC_REGNUM)
3160 (compare:CCU (mem:BLK (match_operand:P 2 "register_operand" "0"))
3161 (mem:BLK (match_operand:P 3 "register_operand" "1"))))
3162 (use (reg:SI 0))]
3163 ""
3164 "clst\t%0,%1\;jo\t.-4"
3165 [(set_attr "length" "8")
3166 (set_attr "type" "vs")])
3167
3168 ;
3169 ; movstr instruction pattern.
3170 ;
3171
3172 (define_expand "movstr"
3173 [(match_operand 0 "register_operand" "")
3174 (match_operand 1 "memory_operand" "")
3175 (match_operand 2 "memory_operand" "")]
3176 ""
3177 {
3178 if (TARGET_64BIT)
3179 emit_insn (gen_movstrdi (operands[0], operands[1], operands[2]));
3180 else
3181 emit_insn (gen_movstrsi (operands[0], operands[1], operands[2]));
3182 DONE;
3183 })
3184
3185 (define_expand "movstr<P:mode>"
3186 [(set (reg:SI 0) (const_int 0))
3187 (parallel
3188 [(clobber (match_dup 3))
3189 (set (match_operand:BLK 1 "memory_operand" "")
3190 (match_operand:BLK 2 "memory_operand" ""))
3191 (set (match_operand:P 0 "register_operand" "")
3192 (unspec:P [(match_dup 1)
3193 (match_dup 2)
3194 (reg:SI 0)] UNSPEC_MVST))
3195 (clobber (reg:CC CC_REGNUM))])]
3196 ""
3197 {
3198 rtx addr1, addr2;
3199
3200 if (TARGET_VX && optimize_function_for_speed_p (cfun))
3201 {
3202 s390_expand_vec_movstr (operands[0], operands[1], operands[2]);
3203 DONE;
3204 }
3205
3206 addr1 = gen_reg_rtx (Pmode);
3207 addr2 = gen_reg_rtx (Pmode);
3208
3209 emit_move_insn (addr1, force_operand (XEXP (operands[1], 0), NULL_RTX));
3210 emit_move_insn (addr2, force_operand (XEXP (operands[2], 0), NULL_RTX));
3211 operands[1] = replace_equiv_address_nv (operands[1], addr1);
3212 operands[2] = replace_equiv_address_nv (operands[2], addr2);
3213 operands[3] = addr2;
3214 })
3215
3216 (define_insn "*movstr"
3217 [(clobber (match_operand:P 2 "register_operand" "=d"))
3218 (set (mem:BLK (match_operand:P 1 "register_operand" "0"))
3219 (mem:BLK (match_operand:P 3 "register_operand" "2")))
3220 (set (match_operand:P 0 "register_operand" "=d")
3221 (unspec:P [(mem:BLK (match_dup 1))
3222 (mem:BLK (match_dup 3))
3223 (reg:SI 0)] UNSPEC_MVST))
3224 (clobber (reg:CC CC_REGNUM))]
3225 ""
3226 "mvst\t%1,%2\;jo\t.-4"
3227 [(set_attr "length" "8")
3228 (set_attr "type" "vs")])
3229
3230
3231 ;
3232 ; cpymemM instruction pattern(s).
3233 ;
3234
3235 (define_expand "cpymem<mode>"
3236 [(set (match_operand:BLK 0 "memory_operand" "") ; destination
3237 (match_operand:BLK 1 "memory_operand" "")) ; source
3238 (use (match_operand:GPR 2 "general_operand" "")) ; count
3239 (match_operand 3 "" "")]
3240 ""
3241 {
3242 if (s390_expand_cpymem (operands[0], operands[1], operands[2]))
3243 DONE;
3244 else
3245 FAIL;
3246 })
3247
3248 ; Move a block that is up to 256 bytes in length.
3249 ; The block length is taken as (operands[2] % 256) + 1.
3250
3251 (define_expand "cpymem_short"
3252 [(parallel
3253 [(set (match_operand:BLK 0 "memory_operand" "")
3254 (match_operand:BLK 1 "memory_operand" ""))
3255 (use (match_operand 2 "nonmemory_operand" ""))
3256 (use (const:BLK (unspec:BLK [(const_int 0)] UNSPEC_INSN)))
3257 (clobber (match_dup 3))])]
3258 ""
3259 "operands[3] = gen_rtx_SCRATCH (Pmode);")
3260
3261 (define_insn "*cpymem_short"
3262 [(set (match_operand:BLK 0 "memory_operand" "=Q,Q,Q,Q")
3263 (match_operand:BLK 1 "memory_operand" "Q,Q,Q,Q"))
3264 (use (match_operand 2 "nonmemory_operand" "n,a,a,a"))
3265 (use (match_operand 3 "immediate_operand" "X,R,X,X"))
3266 (clobber (match_scratch:P 4 "=X,X,X,&a"))]
3267 "(GET_MODE (operands[2]) == Pmode || GET_MODE (operands[2]) == VOIDmode)"
3268 "#"
3269 [(set_attr "type" "cs")
3270 (set_attr "cpu_facility" "*,*,z10,cpu_zarch")])
3271
3272 (define_split
3273 [(set (match_operand:BLK 0 "memory_operand" "")
3274 (match_operand:BLK 1 "memory_operand" ""))
3275 (use (match_operand 2 "const_int_operand" ""))
3276 (use (match_operand 3 "immediate_operand" ""))
3277 (clobber (scratch))]
3278 "reload_completed"
3279 [(parallel
3280 [(set (match_dup 0) (match_dup 1))
3281 (use (match_dup 2))])]
3282 "operands[2] = GEN_INT ((INTVAL (operands[2]) & 0xff) + 1);")
3283
3284 (define_split
3285 [(set (match_operand:BLK 0 "memory_operand" "")
3286 (match_operand:BLK 1 "memory_operand" ""))
3287 (use (match_operand 2 "register_operand" ""))
3288 (use (match_operand 3 "memory_operand" ""))
3289 (clobber (scratch))]
3290 "reload_completed"
3291 [(parallel
3292 [(unspec [(match_dup 2) (match_dup 3)
3293 (const_int 0)] UNSPEC_EXECUTE)
3294 (set (match_dup 0) (match_dup 1))
3295 (use (const_int 1))])]
3296 "")
3297
3298 (define_split
3299 [(set (match_operand:BLK 0 "memory_operand" "")
3300 (match_operand:BLK 1 "memory_operand" ""))
3301 (use (match_operand 2 "register_operand" ""))
3302 (use (const:BLK (unspec:BLK [(const_int 0)] UNSPEC_INSN)))
3303 (clobber (scratch))]
3304 "TARGET_Z10 && reload_completed"
3305 [(parallel
3306 [(unspec [(match_dup 2) (const_int 0)
3307 (label_ref (match_dup 3))] UNSPEC_EXECUTE)
3308 (set (match_dup 0) (match_dup 1))
3309 (use (const_int 1))])]
3310 "operands[3] = gen_label_rtx ();")
3311
3312 (define_split
3313 [(set (match_operand:BLK 0 "memory_operand" "")
3314 (match_operand:BLK 1 "memory_operand" ""))
3315 (use (match_operand 2 "register_operand" ""))
3316 (use (const:BLK (unspec:BLK [(const_int 0)] UNSPEC_INSN)))
3317 (clobber (match_operand 3 "register_operand" ""))]
3318 "reload_completed"
3319 [(set (match_dup 3) (label_ref (match_dup 4)))
3320 (parallel
3321 [(unspec [(match_dup 2) (mem:BLK (match_dup 3))
3322 (label_ref (match_dup 4))] UNSPEC_EXECUTE)
3323 (set (match_dup 0) (match_dup 1))
3324 (use (const_int 1))])]
3325 "operands[4] = gen_label_rtx ();")
3326
3327 ; Move a block of arbitrary length.
3328
3329 (define_expand "cpymem_long"
3330 [(parallel
3331 [(clobber (match_dup 2))
3332 (clobber (match_dup 3))
3333 (set (match_operand:BLK 0 "memory_operand" "")
3334 (match_operand:BLK 1 "memory_operand" ""))
3335 (use (match_operand 2 "general_operand" ""))
3336 (use (match_dup 3))
3337 (clobber (reg:CC CC_REGNUM))])]
3338 ""
3339 {
3340 machine_mode sreg_mode = TARGET_ZARCH ? DImode : SImode;
3341 machine_mode dreg_mode = TARGET_ZARCH ? TImode : DImode;
3342 rtx reg0 = gen_reg_rtx (dreg_mode);
3343 rtx reg1 = gen_reg_rtx (dreg_mode);
3344 rtx addr0 = gen_lowpart (Pmode, gen_highpart (sreg_mode, reg0));
3345 rtx addr1 = gen_lowpart (Pmode, gen_highpart (sreg_mode, reg1));
3346 rtx len0 = gen_lowpart (Pmode, reg0);
3347 rtx len1 = gen_lowpart (Pmode, reg1);
3348
3349 emit_clobber (reg0);
3350 emit_move_insn (addr0, force_operand (XEXP (operands[0], 0), NULL_RTX));
3351 emit_move_insn (len0, operands[2]);
3352
3353 emit_clobber (reg1);
3354 emit_move_insn (addr1, force_operand (XEXP (operands[1], 0), NULL_RTX));
3355 emit_move_insn (len1, operands[2]);
3356
3357 operands[0] = replace_equiv_address_nv (operands[0], addr0);
3358 operands[1] = replace_equiv_address_nv (operands[1], addr1);
3359 operands[2] = reg0;
3360 operands[3] = reg1;
3361 })
3362
3363 (define_insn "*cpymem_long"
3364 [(clobber (match_operand:<DBL> 0 "register_operand" "=d"))
3365 (clobber (match_operand:<DBL> 1 "register_operand" "=d"))
3366 (set (mem:BLK (subreg:P (match_operand:<DBL> 2 "register_operand" "0") 0))
3367 (mem:BLK (subreg:P (match_operand:<DBL> 3 "register_operand" "1") 0)))
3368 (use (match_dup 2))
3369 (use (match_dup 3))
3370 (clobber (reg:CC CC_REGNUM))]
3371 "TARGET_64BIT || !TARGET_ZARCH"
3372 "mvcle\t%0,%1,0\;jo\t.-4"
3373 [(set_attr "length" "8")
3374 (set_attr "type" "vs")])
3375
3376 (define_insn "*cpymem_long_31z"
3377 [(clobber (match_operand:TI 0 "register_operand" "=d"))
3378 (clobber (match_operand:TI 1 "register_operand" "=d"))
3379 (set (mem:BLK (subreg:SI (match_operand:TI 2 "register_operand" "0") 4))
3380 (mem:BLK (subreg:SI (match_operand:TI 3 "register_operand" "1") 4)))
3381 (use (match_dup 2))
3382 (use (match_dup 3))
3383 (clobber (reg:CC CC_REGNUM))]
3384 "!TARGET_64BIT && TARGET_ZARCH"
3385 "mvcle\t%0,%1,0\;jo\t.-4"
3386 [(set_attr "length" "8")
3387 (set_attr "type" "vs")])
3388
3389
3390 ;
3391 ; Test data class.
3392 ;
3393
3394 (define_expand "signbit<mode>2"
3395 [(set (reg:CCZ CC_REGNUM)
3396 (unspec:CCZ [(match_operand:FP_ALL 1 "register_operand" "f")
3397 (match_dup 2)]
3398 UNSPEC_TDC_INSN))
3399 (set (match_operand:SI 0 "register_operand" "=d")
3400 (unspec:SI [(reg:CCZ CC_REGNUM)] UNSPEC_CC_TO_INT))]
3401 "TARGET_HARD_FLOAT"
3402 {
3403 operands[2] = GEN_INT (S390_TDC_SIGNBIT_SET);
3404 })
3405
3406 (define_expand "isinf<mode>2"
3407 [(set (reg:CCZ CC_REGNUM)
3408 (unspec:CCZ [(match_operand:FP_ALL 1 "register_operand" "f")
3409 (match_dup 2)]
3410 UNSPEC_TDC_INSN))
3411 (set (match_operand:SI 0 "register_operand" "=d")
3412 (unspec:SI [(reg:CCZ CC_REGNUM)] UNSPEC_CC_TO_INT))]
3413 "TARGET_HARD_FLOAT"
3414 {
3415 operands[2] = GEN_INT (S390_TDC_INFINITY);
3416 })
3417
3418 ; This extracts CC into a GPR properly shifted. The actual IPM
3419 ; instruction will be issued by reload. The constraint of operand 1
3420 ; forces reload to use a GPR. So reload will issue a movcc insn for
3421 ; copying CC into a GPR first.
3422 (define_insn_and_split "*cc_to_int"
3423 [(set (match_operand:SI 0 "nonimmediate_operand" "=d")
3424 (unspec:SI [(match_operand 1 "register_operand" "0")]
3425 UNSPEC_CC_TO_INT))]
3426 "operands != NULL"
3427 "#"
3428 "reload_completed"
3429 [(set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 28)))])
3430
3431 ; This insn is used to generate all variants of the Test Data Class
3432 ; instruction, namely tcxb, tcdb, and tceb. The insn's first operand
3433 ; is the register to be tested and the second one is the bit mask
3434 ; specifying the required test(s).
3435 ;
3436 ; tcxb, tcdb, tceb, tdcxt, tdcdt, tdcet
3437 (define_insn "*TDC_insn_<mode>"
3438 [(set (reg:CCZ CC_REGNUM)
3439 (unspec:CCZ [(match_operand:FP_ALL 0 "register_operand" "f")
3440 (match_operand:SI 1 "const_int_operand")] UNSPEC_TDC_INSN))]
3441 "TARGET_HARD_FLOAT"
3442 "t<_d>c<xde><bt>\t%0,%1"
3443 [(set_attr "op_type" "RXE")
3444 (set_attr "type" "fsimp<mode>")])
3445
3446
3447
3448 ;
3449 ; setmemM instruction pattern(s).
3450 ;
3451
3452 (define_expand "setmem<mode>"
3453 [(set (match_operand:BLK 0 "memory_operand" "")
3454 (match_operand:QI 2 "general_operand" ""))
3455 (use (match_operand:GPR 1 "general_operand" ""))
3456 (match_operand 3 "" "")]
3457 ""
3458 "s390_expand_setmem (operands[0], operands[1], operands[2]); DONE;")
3459
3460 ; Clear a block that is up to 256 bytes in length.
3461 ; The block length is taken as (operands[1] % 256) + 1.
3462
3463 (define_expand "clrmem_short"
3464 [(parallel
3465 [(set (match_operand:BLK 0 "memory_operand" "")
3466 (const_int 0))
3467 (use (match_operand 1 "nonmemory_operand" ""))
3468 (use (const:BLK (unspec:BLK [(const_int 0)] UNSPEC_INSN)))
3469 (clobber (match_dup 2))
3470 (clobber (reg:CC CC_REGNUM))])]
3471 ""
3472 "operands[2] = gen_rtx_SCRATCH (Pmode);")
3473
3474 (define_insn "*clrmem_short"
3475 [(set (match_operand:BLK 0 "memory_operand" "=Q,Q,Q,Q")
3476 (const_int 0))
3477 (use (match_operand 1 "nonmemory_operand" "n,a,a,a"))
3478 (use (match_operand 2 "immediate_operand" "X,R,X,X"))
3479 (clobber (match_scratch:P 3 "=X,X,X,&a"))
3480 (clobber (reg:CC CC_REGNUM))]
3481 "(GET_MODE (operands[1]) == Pmode || GET_MODE (operands[1]) == VOIDmode)"
3482 "#"
3483 [(set_attr "type" "cs")
3484 (set_attr "cpu_facility" "*,*,z10,cpu_zarch")])
3485
3486 (define_split
3487 [(set (match_operand:BLK 0 "memory_operand" "")
3488 (const_int 0))
3489 (use (match_operand 1 "const_int_operand" ""))
3490 (use (match_operand 2 "immediate_operand" ""))
3491 (clobber (scratch))
3492 (clobber (reg:CC CC_REGNUM))]
3493 "reload_completed"
3494 [(parallel
3495 [(set (match_dup 0) (const_int 0))
3496 (use (match_dup 1))
3497 (clobber (reg:CC CC_REGNUM))])]
3498 "operands[1] = GEN_INT ((INTVAL (operands[1]) & 0xff) + 1);")
3499
3500 (define_split
3501 [(set (match_operand:BLK 0 "memory_operand" "")
3502 (const_int 0))
3503 (use (match_operand 1 "register_operand" ""))
3504 (use (match_operand 2 "memory_operand" ""))
3505 (clobber (scratch))
3506 (clobber (reg:CC CC_REGNUM))]
3507 "reload_completed"
3508 [(parallel
3509 [(unspec [(match_dup 1) (match_dup 2)
3510 (const_int 0)] UNSPEC_EXECUTE)
3511 (set (match_dup 0) (const_int 0))
3512 (use (const_int 1))
3513 (clobber (reg:CC CC_REGNUM))])]
3514 "")
3515
3516 (define_split
3517 [(set (match_operand:BLK 0 "memory_operand" "")
3518 (const_int 0))
3519 (use (match_operand 1 "register_operand" ""))
3520 (use (const:BLK (unspec:BLK [(const_int 0)] UNSPEC_INSN)))
3521 (clobber (scratch))
3522 (clobber (reg:CC CC_REGNUM))]
3523 "TARGET_Z10 && reload_completed"
3524 [(parallel
3525 [(unspec [(match_dup 1) (const_int 0)
3526 (label_ref (match_dup 3))] UNSPEC_EXECUTE)
3527 (set (match_dup 0) (const_int 0))
3528 (use (const_int 1))
3529 (clobber (reg:CC CC_REGNUM))])]
3530 "operands[3] = gen_label_rtx ();")
3531
3532 (define_split
3533 [(set (match_operand:BLK 0 "memory_operand" "")
3534 (const_int 0))
3535 (use (match_operand 1 "register_operand" ""))
3536 (use (const:BLK (unspec:BLK [(const_int 0)] UNSPEC_INSN)))
3537 (clobber (match_operand 2 "register_operand" ""))
3538 (clobber (reg:CC CC_REGNUM))]
3539 "reload_completed"
3540 [(set (match_dup 2) (label_ref (match_dup 3)))
3541 (parallel
3542 [(unspec [(match_dup 1) (mem:BLK (match_dup 2))
3543 (label_ref (match_dup 3))] UNSPEC_EXECUTE)
3544 (set (match_dup 0) (const_int 0))
3545 (use (const_int 1))
3546 (clobber (reg:CC CC_REGNUM))])]
3547 "operands[3] = gen_label_rtx ();")
3548
3549 ; Initialize a block of arbitrary length with (operands[2] % 256).
3550
3551 (define_expand "setmem_long_<P:mode>"
3552 [(parallel
3553 [(clobber (match_dup 1))
3554 (set (match_operand:BLK 0 "memory_operand" "")
3555 (unspec:BLK [(match_operand:P 2 "setmem_operand" "")
3556 (match_dup 4)] UNSPEC_REPLICATE_BYTE))
3557 (use (match_dup 3))
3558 (clobber (reg:CC CC_REGNUM))])]
3559 ""
3560 {
3561 machine_mode sreg_mode = TARGET_ZARCH ? DImode : SImode;
3562 machine_mode dreg_mode = TARGET_ZARCH ? TImode : DImode;
3563 rtx reg0 = gen_reg_rtx (dreg_mode);
3564 rtx reg1 = gen_reg_rtx (dreg_mode);
3565 rtx addr0 = gen_lowpart (Pmode, gen_highpart (sreg_mode, reg0));
3566 rtx len0 = gen_lowpart (Pmode, reg0);
3567
3568 emit_clobber (reg0);
3569 emit_move_insn (addr0, force_operand (XEXP (operands[0], 0), NULL_RTX));
3570 emit_move_insn (len0, operands[1]);
3571
3572 emit_move_insn (reg1, const0_rtx);
3573
3574 operands[0] = replace_equiv_address_nv (operands[0], addr0);
3575 operands[1] = reg0;
3576 operands[3] = reg1;
3577 operands[4] = gen_lowpart (Pmode, operands[1]);
3578 })
3579
3580 ; Patterns for 31 bit + Esa and 64 bit + Zarch.
3581
3582 (define_insn "*setmem_long"
3583 [(clobber (match_operand:<DBL> 0 "register_operand" "=d"))
3584 (set (mem:BLK (subreg:P (match_operand:<DBL> 3 "register_operand" "0") 0))
3585 (unspec:BLK [(match_operand:P 2 "setmem_operand" "Y")
3586 (subreg:P (match_dup 3) <modesize>)]
3587 UNSPEC_REPLICATE_BYTE))
3588 (use (match_operand:<DBL> 1 "register_operand" "d"))
3589 (clobber (reg:CC CC_REGNUM))]
3590 "TARGET_64BIT || !TARGET_ZARCH"
3591 "mvcle\t%0,%1,%Y2\;jo\t.-4"
3592 [(set_attr "length" "8")
3593 (set_attr "type" "vs")])
3594
3595 (define_insn "*setmem_long_and"
3596 [(clobber (match_operand:<DBL> 0 "register_operand" "=d"))
3597 (set (mem:BLK (subreg:P (match_operand:<DBL> 3 "register_operand" "0") 0))
3598 (unspec:BLK [(zero_extend:P (match_operand:QI 2 "setmem_operand" "Y"))
3599 (subreg:P (match_dup 3) <modesize>)]
3600 UNSPEC_REPLICATE_BYTE))
3601 (use (match_operand:<DBL> 1 "register_operand" "d"))
3602 (clobber (reg:CC CC_REGNUM))]
3603 "(TARGET_64BIT || !TARGET_ZARCH)"
3604 "mvcle\t%0,%1,%Y2\;jo\t.-4"
3605 [(set_attr "length" "8")
3606 (set_attr "type" "vs")])
3607
3608 ; Variants for 31 bit + Zarch, necessary because of the odd in-register offsets
3609 ; of the SImode subregs.
3610
3611 (define_insn "*setmem_long_31z"
3612 [(clobber (match_operand:TI 0 "register_operand" "=d"))
3613 (set (mem:BLK (subreg:SI (match_operand:TI 3 "register_operand" "0") 4))
3614 (unspec:BLK [(match_operand:SI 2 "setmem_operand" "Y")
3615 (subreg:SI (match_dup 3) 12)] UNSPEC_REPLICATE_BYTE))
3616 (use (match_operand:TI 1 "register_operand" "d"))
3617 (clobber (reg:CC CC_REGNUM))]
3618 "!TARGET_64BIT && TARGET_ZARCH"
3619 "mvcle\t%0,%1,%Y2\;jo\t.-4"
3620 [(set_attr "length" "8")
3621 (set_attr "type" "vs")])
3622
3623 (define_insn "*setmem_long_and_31z"
3624 [(clobber (match_operand:TI 0 "register_operand" "=d"))
3625 (set (mem:BLK (subreg:SI (match_operand:TI 3 "register_operand" "0") 4))
3626 (unspec:BLK [(zero_extend:SI (match_operand:QI 2 "setmem_operand" "Y"))
3627 (subreg:SI (match_dup 3) 12)] UNSPEC_REPLICATE_BYTE))
3628 (use (match_operand:TI 1 "register_operand" "d"))
3629 (clobber (reg:CC CC_REGNUM))]
3630 "(!TARGET_64BIT && TARGET_ZARCH)"
3631 "mvcle\t%0,%1,%Y2\;jo\t.-4"
3632 [(set_attr "length" "8")
3633 (set_attr "type" "vs")])
3634
3635 ;
3636 ; cmpmemM instruction pattern(s).
3637 ;
3638
3639 (define_expand "cmpmemsi"
3640 [(set (match_operand:SI 0 "register_operand" "")
3641 (compare:SI (match_operand:BLK 1 "memory_operand" "")
3642 (match_operand:BLK 2 "memory_operand" "") ) )
3643 (use (match_operand:SI 3 "general_operand" ""))
3644 (use (match_operand:SI 4 "" ""))]
3645 ""
3646 {
3647 if (s390_expand_cmpmem (operands[0], operands[1],
3648 operands[2], operands[3]))
3649 DONE;
3650 else
3651 FAIL;
3652 })
3653
3654 ; Compare a block that is up to 256 bytes in length.
3655 ; The block length is taken as (operands[2] % 256) + 1.
3656
3657 (define_expand "cmpmem_short"
3658 [(parallel
3659 [(set (reg:CCU CC_REGNUM)
3660 (compare:CCU (match_operand:BLK 0 "memory_operand" "")
3661 (match_operand:BLK 1 "memory_operand" "")))
3662 (use (match_operand 2 "nonmemory_operand" ""))
3663 (use (const:BLK (unspec:BLK [(const_int 0)] UNSPEC_INSN)))
3664 (clobber (match_dup 3))])]
3665 ""
3666 "operands[3] = gen_rtx_SCRATCH (Pmode);")
3667
3668 (define_insn "*cmpmem_short"
3669 [(set (reg:CCU CC_REGNUM)
3670 (compare:CCU (match_operand:BLK 0 "memory_operand" "Q,Q,Q,Q")
3671 (match_operand:BLK 1 "memory_operand" "Q,Q,Q,Q")))
3672 (use (match_operand 2 "nonmemory_operand" "n,a,a,a"))
3673 (use (match_operand 3 "immediate_operand" "X,R,X,X"))
3674 (clobber (match_scratch:P 4 "=X,X,X,&a"))]
3675 "(GET_MODE (operands[2]) == Pmode || GET_MODE (operands[2]) == VOIDmode)"
3676 "#"
3677 [(set_attr "type" "cs")
3678 (set_attr "cpu_facility" "*,*,z10,cpu_zarch")])
3679
3680 (define_split
3681 [(set (reg:CCU CC_REGNUM)
3682 (compare:CCU (match_operand:BLK 0 "memory_operand" "")
3683 (match_operand:BLK 1 "memory_operand" "")))
3684 (use (match_operand 2 "const_int_operand" ""))
3685 (use (match_operand 3 "immediate_operand" ""))
3686 (clobber (scratch))]
3687 "reload_completed"
3688 [(parallel
3689 [(set (reg:CCU CC_REGNUM) (compare:CCU (match_dup 0) (match_dup 1)))
3690 (use (match_dup 2))])]
3691 "operands[2] = GEN_INT ((INTVAL (operands[2]) & 0xff) + 1);")
3692
3693 (define_split
3694 [(set (reg:CCU CC_REGNUM)
3695 (compare:CCU (match_operand:BLK 0 "memory_operand" "")
3696 (match_operand:BLK 1 "memory_operand" "")))
3697 (use (match_operand 2 "register_operand" ""))
3698 (use (match_operand 3 "memory_operand" ""))
3699 (clobber (scratch))]
3700 "reload_completed"
3701 [(parallel
3702 [(unspec [(match_dup 2) (match_dup 3)
3703 (const_int 0)] UNSPEC_EXECUTE)
3704 (set (reg:CCU CC_REGNUM) (compare:CCU (match_dup 0) (match_dup 1)))
3705 (use (const_int 1))])]
3706 "")
3707
3708 (define_split
3709 [(set (reg:CCU CC_REGNUM)
3710 (compare:CCU (match_operand:BLK 0 "memory_operand" "")
3711 (match_operand:BLK 1 "memory_operand" "")))
3712 (use (match_operand 2 "register_operand" ""))
3713 (use (const:BLK (unspec:BLK [(const_int 0)] UNSPEC_INSN)))
3714 (clobber (scratch))]
3715 "TARGET_Z10 && reload_completed"
3716 [(parallel
3717 [(unspec [(match_dup 2) (const_int 0)
3718 (label_ref (match_dup 4))] UNSPEC_EXECUTE)
3719 (set (reg:CCU CC_REGNUM) (compare:CCU (match_dup 0) (match_dup 1)))
3720 (use (const_int 1))])]
3721 "operands[4] = gen_label_rtx ();")
3722
3723 (define_split
3724 [(set (reg:CCU CC_REGNUM)
3725 (compare:CCU (match_operand:BLK 0 "memory_operand" "")
3726 (match_operand:BLK 1 "memory_operand" "")))
3727 (use (match_operand 2 "register_operand" ""))
3728 (use (const:BLK (unspec:BLK [(const_int 0)] UNSPEC_INSN)))
3729 (clobber (match_operand 3 "register_operand" ""))]
3730 "reload_completed"
3731 [(set (match_dup 3) (label_ref (match_dup 4)))
3732 (parallel
3733 [(unspec [(match_dup 2) (mem:BLK (match_dup 3))
3734 (label_ref (match_dup 4))] UNSPEC_EXECUTE)
3735 (set (reg:CCU CC_REGNUM) (compare:CCU (match_dup 0) (match_dup 1)))
3736 (use (const_int 1))])]
3737 "operands[4] = gen_label_rtx ();")
3738
3739 ; Compare a block of arbitrary length.
3740
3741 (define_expand "cmpmem_long"
3742 [(parallel
3743 [(clobber (match_dup 2))
3744 (clobber (match_dup 3))
3745 (set (reg:CCU CC_REGNUM)
3746 (compare:CCU (match_operand:BLK 0 "memory_operand" "")
3747 (match_operand:BLK 1 "memory_operand" "")))
3748 (use (match_operand 2 "general_operand" ""))
3749 (use (match_dup 3))])]
3750 ""
3751 {
3752 machine_mode sreg_mode = TARGET_ZARCH ? DImode : SImode;
3753 machine_mode dreg_mode = TARGET_ZARCH ? TImode : DImode;
3754 rtx reg0 = gen_reg_rtx (dreg_mode);
3755 rtx reg1 = gen_reg_rtx (dreg_mode);
3756 rtx addr0 = gen_lowpart (Pmode, gen_highpart (sreg_mode, reg0));
3757 rtx addr1 = gen_lowpart (Pmode, gen_highpart (sreg_mode, reg1));
3758 rtx len0 = gen_lowpart (Pmode, reg0);
3759 rtx len1 = gen_lowpart (Pmode, reg1);
3760
3761 emit_clobber (reg0);
3762 emit_move_insn (addr0, force_operand (XEXP (operands[0], 0), NULL_RTX));
3763 emit_move_insn (len0, operands[2]);
3764
3765 emit_clobber (reg1);
3766 emit_move_insn (addr1, force_operand (XEXP (operands[1], 0), NULL_RTX));
3767 emit_move_insn (len1, operands[2]);
3768
3769 operands[0] = replace_equiv_address_nv (operands[0], addr0);
3770 operands[1] = replace_equiv_address_nv (operands[1], addr1);
3771 operands[2] = reg0;
3772 operands[3] = reg1;
3773 })
3774
3775 (define_insn "*cmpmem_long"
3776 [(clobber (match_operand:<DBL> 0 "register_operand" "=d"))
3777 (clobber (match_operand:<DBL> 1 "register_operand" "=d"))
3778 (set (reg:CCU CC_REGNUM)
3779 (compare:CCU (mem:BLK (subreg:P (match_operand:<DBL> 2 "register_operand" "0") 0))
3780 (mem:BLK (subreg:P (match_operand:<DBL> 3 "register_operand" "1") 0))))
3781 (use (match_dup 2))
3782 (use (match_dup 3))]
3783 "TARGET_64BIT || !TARGET_ZARCH"
3784 "clcle\t%0,%1,0\;jo\t.-4"
3785 [(set_attr "length" "8")
3786 (set_attr "type" "vs")])
3787
3788 (define_insn "*cmpmem_long_31z"
3789 [(clobber (match_operand:TI 0 "register_operand" "=d"))
3790 (clobber (match_operand:TI 1 "register_operand" "=d"))
3791 (set (reg:CCU CC_REGNUM)
3792 (compare:CCU (mem:BLK (subreg:SI (match_operand:TI 2 "register_operand" "0") 4))
3793 (mem:BLK (subreg:SI (match_operand:TI 3 "register_operand" "1") 4))))
3794 (use (match_dup 2))
3795 (use (match_dup 3))]
3796 "!TARGET_64BIT && TARGET_ZARCH"
3797 "clcle\t%0,%1,0\;jo\t.-4"
3798 [(set_attr "op_type" "NN")
3799 (set_attr "type" "vs")
3800 (set_attr "length" "8")])
3801
3802 ; Convert CCUmode condition code to integer.
3803 ; Result is zero if EQ, positive if LTU, negative if GTU.
3804
3805 (define_insn_and_split "cmpint"
3806 [(set (match_operand:SI 0 "register_operand" "=d")
3807 (unspec:SI [(match_operand:CCU 1 "register_operand" "0")]
3808 UNSPEC_STRCMPCC_TO_INT))
3809 (clobber (reg:CC CC_REGNUM))]
3810 ""
3811 "#"
3812 "reload_completed"
3813 [(set (match_dup 0) (ashift:SI (match_dup 0) (const_int 2)))
3814 (parallel
3815 [(set (match_dup 0) (ashiftrt:SI (match_dup 0) (const_int 30)))
3816 (clobber (reg:CC CC_REGNUM))])])
3817
3818 (define_insn_and_split "*cmpint_cc"
3819 [(set (reg CC_REGNUM)
3820 (compare (unspec:SI [(match_operand:CCU 1 "register_operand" "0")]
3821 UNSPEC_STRCMPCC_TO_INT)
3822 (const_int 0)))
3823 (set (match_operand:SI 0 "register_operand" "=d")
3824 (unspec:SI [(match_dup 1)] UNSPEC_STRCMPCC_TO_INT))]
3825 "s390_match_ccmode (insn, CCSmode)"
3826 "#"
3827 "&& reload_completed"
3828 [(set (match_dup 0) (ashift:SI (match_dup 0) (const_int 2)))
3829 (parallel
3830 [(set (match_dup 2) (match_dup 3))
3831 (set (match_dup 0) (ashiftrt:SI (match_dup 0) (const_int 30)))])]
3832 {
3833 rtx result = gen_rtx_ASHIFTRT (SImode, operands[0], GEN_INT (30));
3834 operands[2] = SET_DEST (XVECEXP (PATTERN (curr_insn), 0, 0));
3835 operands[3] = gen_rtx_COMPARE (GET_MODE (operands[2]), result, const0_rtx);
3836 })
3837
3838 (define_insn_and_split "*cmpint_sign"
3839 [(set (match_operand:DI 0 "register_operand" "=d")
3840 (sign_extend:DI (unspec:SI [(match_operand:CCU 1 "register_operand" "0")]
3841 UNSPEC_STRCMPCC_TO_INT)))
3842 (clobber (reg:CC CC_REGNUM))]
3843 "TARGET_ZARCH"
3844 "#"
3845 "&& reload_completed"
3846 [(set (match_dup 0) (ashift:DI (match_dup 0) (const_int 34)))
3847 (parallel
3848 [(set (match_dup 0) (ashiftrt:DI (match_dup 0) (const_int 62)))
3849 (clobber (reg:CC CC_REGNUM))])])
3850
3851 (define_insn_and_split "*cmpint_sign_cc"
3852 [(set (reg CC_REGNUM)
3853 (compare (ashiftrt:DI (ashift:DI (subreg:DI
3854 (unspec:SI [(match_operand:CCU 1 "register_operand" "0")]
3855 UNSPEC_STRCMPCC_TO_INT) 0)
3856 (const_int 32)) (const_int 32))
3857 (const_int 0)))
3858 (set (match_operand:DI 0 "register_operand" "=d")
3859 (sign_extend:DI (unspec:SI [(match_dup 1)] UNSPEC_STRCMPCC_TO_INT)))]
3860 "s390_match_ccmode (insn, CCSmode) && TARGET_ZARCH"
3861 "#"
3862 "&& reload_completed"
3863 [(set (match_dup 0) (ashift:DI (match_dup 0) (const_int 34)))
3864 (parallel
3865 [(set (match_dup 2) (match_dup 3))
3866 (set (match_dup 0) (ashiftrt:DI (match_dup 0) (const_int 62)))])]
3867 {
3868 rtx result = gen_rtx_ASHIFTRT (DImode, operands[0], GEN_INT (62));
3869 operands[2] = SET_DEST (XVECEXP (PATTERN (curr_insn), 0, 0));
3870 operands[3] = gen_rtx_COMPARE (GET_MODE (operands[2]), result, const0_rtx);
3871 })
3872
3873
3874 ;;
3875 ;;- Conversion instructions.
3876 ;;
3877
3878 (define_insn "*sethighpartsi"
3879 [(set (match_operand:SI 0 "register_operand" "=d,d")
3880 (unspec:SI [(match_operand:BLK 1 "s_operand" "Q,S")
3881 (match_operand 2 "const_int_operand" "n,n")] UNSPEC_ICM))
3882 (clobber (reg:CC CC_REGNUM))]
3883 ""
3884 "@
3885 icm\t%0,%2,%S1
3886 icmy\t%0,%2,%S1"
3887 [(set_attr "op_type" "RS,RSY")
3888 (set_attr "cpu_facility" "*,longdisp")
3889 (set_attr "z10prop" "z10_super_E1,z10_super_E1")])
3890
3891 (define_insn "*sethighpartdi_64"
3892 [(set (match_operand:DI 0 "register_operand" "=d")
3893 (unspec:DI [(match_operand:BLK 1 "s_operand" "S")
3894 (match_operand 2 "const_int_operand" "n")] UNSPEC_ICM))
3895 (clobber (reg:CC CC_REGNUM))]
3896 "TARGET_ZARCH"
3897 "icmh\t%0,%2,%S1"
3898 [(set_attr "op_type" "RSY")
3899 (set_attr "z10prop" "z10_super")])
3900
3901 (define_insn "*sethighpartdi_31"
3902 [(set (match_operand:DI 0 "register_operand" "=d,d")
3903 (unspec:DI [(match_operand:BLK 1 "s_operand" "Q,S")
3904 (match_operand 2 "const_int_operand" "n,n")] UNSPEC_ICM))
3905 (clobber (reg:CC CC_REGNUM))]
3906 "!TARGET_ZARCH"
3907 "@
3908 icm\t%0,%2,%S1
3909 icmy\t%0,%2,%S1"
3910 [(set_attr "op_type" "RS,RSY")
3911 (set_attr "cpu_facility" "*,longdisp")
3912 (set_attr "z10prop" "z10_super_E1,z10_super_E1")])
3913
3914 ;
3915 ; extv instruction patterns
3916 ;
3917
3918 ; FIXME: This expander needs to be converted from DI to GPR as well
3919 ; after resolving some issues with it.
3920
3921 (define_expand "extzv"
3922 [(parallel
3923 [(set (match_operand:DI 0 "register_operand" "=d")
3924 (zero_extract:DI
3925 (match_operand:DI 1 "register_operand" "d")
3926 (match_operand 2 "const_int_operand" "") ; size
3927 (match_operand 3 "const_int_operand" ""))) ; start
3928 (clobber (reg:CC CC_REGNUM))])]
3929 "TARGET_Z10"
3930 {
3931 if (! EXTRACT_ARGS_IN_RANGE (INTVAL (operands[2]), INTVAL (operands[3]), 64))
3932 FAIL;
3933 /* Starting with zEC12 there is risbgn not clobbering CC. */
3934 if (TARGET_ZEC12)
3935 {
3936 emit_move_insn (operands[0],
3937 gen_rtx_ZERO_EXTRACT (DImode,
3938 operands[1],
3939 operands[2],
3940 operands[3]));
3941 DONE;
3942 }
3943 })
3944
3945 (define_insn "*extzv<mode><clobbercc_or_nocc>"
3946 [(set (match_operand:GPR 0 "register_operand" "=d")
3947 (zero_extract:GPR
3948 (match_operand:GPR 1 "register_operand" "d")
3949 (match_operand 2 "const_int_operand" "") ; size
3950 (match_operand 3 "const_int_operand" ""))) ; start
3951 ]
3952 "<z10_or_zEC12_cond>
3953 && EXTRACT_ARGS_IN_RANGE (INTVAL (operands[2]), INTVAL (operands[3]),
3954 GET_MODE_BITSIZE (<MODE>mode))"
3955 "<risbg_n>\t%0,%1,64-%2,128+63,<bitoff_plus>%3+%2" ; dst, src, start, end, shift
3956 [(set_attr "op_type" "RIE")
3957 (set_attr "z10prop" "z10_super_E1")])
3958
3959 ; 64 bit: (a & -16) | ((b >> 8) & 15)
3960 (define_insn "*extzvdi<clobbercc_or_nocc>_lshiftrt"
3961 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+d")
3962 (match_operand 1 "const_int_operand" "") ; size
3963 (match_operand 2 "const_int_operand" "")) ; start
3964 (lshiftrt:DI (match_operand:DI 3 "register_operand" "d")
3965 (match_operand:DI 4 "nonzero_shift_count_operand" "")))]
3966 "<z10_or_zEC12_cond>
3967 && EXTRACT_ARGS_IN_RANGE (INTVAL (operands[1]), INTVAL (operands[2]), 64)
3968 && 64 - UINTVAL (operands[4]) >= UINTVAL (operands[1])"
3969 "<risbg_n>\t%0,%3,%2,%2+%1-1,128-%2-%1-%4"
3970 [(set_attr "op_type" "RIE")
3971 (set_attr "z10prop" "z10_super_E1")])
3972
3973 ; 32 bit: (a & -16) | ((b >> 8) & 15)
3974 (define_insn "*<risbg_n>_ior_and_sr_ze"
3975 [(set (match_operand:SI 0 "register_operand" "=d")
3976 (ior:SI (and:SI
3977 (match_operand:SI 1 "register_operand" "0")
3978 (match_operand:SI 2 "const_int_operand" ""))
3979 (subreg:SI
3980 (zero_extract:DI
3981 (match_operand:DI 3 "register_operand" "d")
3982 (match_operand 4 "const_int_operand" "") ; size
3983 (match_operand 5 "const_int_operand" "")) ; start
3984 4)))]
3985 "<z10_or_zEC12_cond>
3986 && EXTRACT_ARGS_IN_RANGE (INTVAL (operands[4]), INTVAL (operands[5]), 64)
3987 && UINTVAL (operands[2]) == (HOST_WIDE_INT_M1U << UINTVAL (operands[4]))"
3988 "<risbg_n>\t%0,%3,64-%4,63,%4+%5"
3989 [(set_attr "op_type" "RIE")
3990 (set_attr "z10prop" "z10_super_E1")])
3991
3992 ; ((int)foo >> 10) & 1;
3993 (define_insn "*extract1bitdi<clobbercc_or_nocc>"
3994 [(set (match_operand:DI 0 "register_operand" "=d")
3995 (ne:DI (zero_extract:DI
3996 (match_operand:DI 1 "register_operand" "d")
3997 (const_int 1) ; size
3998 (match_operand 2 "const_int_operand" "")) ; start
3999 (const_int 0)))]
4000 "<z10_or_zEC12_cond>
4001 && EXTRACT_ARGS_IN_RANGE (1, INTVAL (operands[2]), 64)"
4002 "<risbg_n>\t%0,%1,64-1,128+63,%2+1" ; dst, src, start, end, shift
4003 [(set_attr "op_type" "RIE")
4004 (set_attr "z10prop" "z10_super_E1")])
4005
4006 (define_insn "*<risbg_n>_and_subregdi_rotr"
4007 [(set (match_operand:DI 0 "register_operand" "=d")
4008 (and:DI (subreg:DI
4009 (rotate:SINT (match_operand:SINT 1 "register_operand" "d")
4010 (match_operand:SINT 2 "const_int_operand" "")) 0)
4011 (match_operand:DI 3 "contiguous_bitmask_operand" "")))]
4012 "<z10_or_zEC12_cond>
4013 && (UINTVAL (operands[3])
4014 < (HOST_WIDE_INT_1U << (UINTVAL (operands[2]) & 0x3f)))"
4015 "<risbg_n>\t%0,%1,%s3,128+%e3,<bitoff_plus>%2" ; dst, src, start, end, shift
4016 [(set_attr "op_type" "RIE")
4017 (set_attr "z10prop" "z10_super_E1")])
4018
4019 (define_insn "*<risbg_n>_and_subregdi_rotl"
4020 [(set (match_operand:DI 0 "register_operand" "=d")
4021 (and:DI (subreg:DI
4022 (rotate:SINT (match_operand:SINT 1 "register_operand" "d")
4023 (match_operand:SINT 2 "const_int_operand" "")) 0)
4024 (match_operand:DI 3 "contiguous_bitmask_operand" "")))]
4025 "<z10_or_zEC12_cond>
4026 && !(UINTVAL (operands[3])
4027 & ((HOST_WIDE_INT_1U << (UINTVAL (operands[2]) & 0x3f)) - 1))"
4028 "<risbg_n>\t%0,%1,%s3,128+%e3,%2" ; dst, src, start, end, shift
4029 [(set_attr "op_type" "RIE")
4030 (set_attr "z10prop" "z10_super_E1")])
4031
4032 (define_insn "*<risbg_n>_di_and_rot"
4033 [(set (match_operand:DI 0 "register_operand" "=d")
4034 (and:DI (rotate:DI (match_operand:DI 1 "register_operand" "d")
4035 (match_operand:DI 2 "const_int_operand" ""))
4036 (match_operand:DI 3 "contiguous_bitmask_operand" "")))]
4037 "<z10_or_zEC12_cond>"
4038 "<risbg_n>\t%0,%1,%s3,128+%e3,%2" ; dst, src, start, end, shift
4039 [(set_attr "op_type" "RIE")
4040 (set_attr "z10prop" "z10_super_E1")])
4041
4042 (define_insn_and_split "*pre_z10_extzv<mode>"
4043 [(set (match_operand:GPR 0 "register_operand" "=d")
4044 (zero_extract:GPR (match_operand:QI 1 "s_operand" "S")
4045 (match_operand 2 "nonzero_shift_count_operand" "")
4046 (const_int 0)))
4047 (clobber (reg:CC CC_REGNUM))]
4048 "!TARGET_Z10"
4049 "#"
4050 "&& reload_completed"
4051 [(parallel
4052 [(set (match_dup 0) (unspec:GPR [(match_dup 1) (match_dup 3)] UNSPEC_ICM))
4053 (clobber (reg:CC CC_REGNUM))])
4054 (set (match_dup 0) (lshiftrt:GPR (match_dup 0) (match_dup 2)))]
4055 {
4056 int bitsize = INTVAL (operands[2]);
4057 int size = (bitsize - 1) / BITS_PER_UNIT + 1; /* round up */
4058 unsigned HOST_WIDE_INT mask
4059 = ((HOST_WIDE_INT_1U << size) - 1) << (GET_MODE_SIZE (SImode) - size);
4060
4061 operands[1] = adjust_address (operands[1], BLKmode, 0);
4062 set_mem_size (operands[1], size);
4063 operands[2] = GEN_INT (<GPR:bitsize> - bitsize);
4064 operands[3] = GEN_INT (mask);
4065 })
4066
4067 (define_insn_and_split "*pre_z10_extv<mode>"
4068 [(set (match_operand:GPR 0 "register_operand" "=d")
4069 (sign_extract:GPR (match_operand:QI 1 "s_operand" "S")
4070 (match_operand 2 "nonzero_shift_count_operand" "")
4071 (const_int 0)))
4072 (clobber (reg:CC CC_REGNUM))]
4073 ""
4074 "#"
4075 "&& reload_completed"
4076 [(parallel
4077 [(set (match_dup 0) (unspec:GPR [(match_dup 1) (match_dup 3)] UNSPEC_ICM))
4078 (clobber (reg:CC CC_REGNUM))])
4079 (parallel
4080 [(set (match_dup 0) (ashiftrt:GPR (match_dup 0) (match_dup 2)))
4081 (clobber (reg:CC CC_REGNUM))])]
4082 {
4083 int bitsize = INTVAL (operands[2]);
4084 int size = (bitsize - 1) / BITS_PER_UNIT + 1; /* round up */
4085 unsigned HOST_WIDE_INT mask
4086 = ((HOST_WIDE_INT_1U << size) - 1) << (GET_MODE_SIZE (SImode) - size);
4087
4088 operands[1] = adjust_address (operands[1], BLKmode, 0);
4089 set_mem_size (operands[1], size);
4090 operands[2] = GEN_INT (<GPR:bitsize> - bitsize);
4091 operands[3] = GEN_INT (mask);
4092 })
4093
4094 ;
4095 ; insv instruction patterns
4096 ;
4097
4098 (define_expand "insv"
4099 [(set (zero_extract (match_operand 0 "nonimmediate_operand" "")
4100 (match_operand 1 "const_int_operand" "")
4101 (match_operand 2 "const_int_operand" ""))
4102 (match_operand 3 "general_operand" ""))]
4103 ""
4104 {
4105 if (s390_expand_insv (operands[0], operands[1], operands[2], operands[3]))
4106 DONE;
4107 FAIL;
4108 })
4109
4110
4111 ; The normal RTL expansion will never generate a zero_extract where
4112 ; the location operand isn't word mode. However, we do this in the
4113 ; back-end when generating atomic operations. See s390_two_part_insv.
4114 (define_insn "*insv<mode><clobbercc_or_nocc>"
4115 [(set (zero_extract:GPR (match_operand:GPR 0 "nonimmediate_operand" "+d")
4116 (match_operand 1 "const_int_operand" "I") ; size
4117 (match_operand 2 "const_int_operand" "I")) ; pos
4118 (match_operand:GPR 3 "nonimmediate_operand" "d"))]
4119 "<z10_or_zEC12_cond>
4120 && EXTRACT_ARGS_IN_RANGE (INTVAL (operands[1]), INTVAL (operands[2]),
4121 GET_MODE_BITSIZE (<MODE>mode))
4122 && (INTVAL (operands[1]) + INTVAL (operands[2])) <= <bitsize>"
4123 "<risbg_n>\t%0,%3,<bitoff_plus>%2,<bitoff_plus>%2+%1-1,<bitsize>-%2-%1"
4124 [(set_attr "op_type" "RIE")
4125 (set_attr "z10prop" "z10_super_E1")])
4126
4127 ; and op1 with a mask being 1 for the selected bits and 0 for the rest
4128 ; and op3=op0 with a mask being 0 for the selected bits and 1 for the rest
4129 (define_insn "*insv<mode><clobbercc_or_nocc>_noshift"
4130 [(set (match_operand:GPR 0 "nonimmediate_operand" "=d,d")
4131 (ior:GPR (and:GPR (match_operand:GPR 1 "nonimmediate_operand" "d,0")
4132 (match_operand:GPR 2 "contiguous_bitmask_operand" ""))
4133 (and:GPR (match_operand:GPR 3 "nonimmediate_operand" "0,d")
4134 (match_operand:GPR 4 "const_int_operand" ""))))]
4135 "<z10_or_zEC12_cond> && INTVAL (operands[2]) == ~INTVAL (operands[4])"
4136 "@
4137 <risbg_n>\t%0,%1,%<bfstart>2,%<bfend>2,0
4138 <risbg_n>\t%0,%3,%<bfstart>4,%<bfend>4,0"
4139 [(set_attr "op_type" "RIE")
4140 (set_attr "z10prop" "z10_super_E1")])
4141
4142 (define_insn "*insv_z10_noshift_cc"
4143 [(set (reg CC_REGNUM)
4144 (compare
4145 (ior:DI
4146 (and:DI (match_operand:DI 1 "nonimmediate_operand" "d,0")
4147 (match_operand:DI 2 "contiguous_bitmask_operand" ""))
4148 (and:DI (match_operand:DI 3 "nonimmediate_operand" "0,d")
4149 (match_operand:DI 4 "const_int_operand" "")))
4150 (const_int 0)))
4151 (set (match_operand:DI 0 "nonimmediate_operand" "=d,d")
4152 (ior:DI (and:DI (match_dup 1) (match_dup 2))
4153 (and:DI (match_dup 3) (match_dup 4))))]
4154 "TARGET_Z10 && s390_match_ccmode (insn, CCSmode)
4155 && INTVAL (operands[2]) == ~INTVAL (operands[4])"
4156 "@
4157 risbg\t%0,%1,%s2,%e2,0
4158 risbg\t%0,%3,%s4,%e4,0"
4159 [(set_attr "op_type" "RIE")
4160 (set_attr "z10prop" "z10_super_E1")])
4161
4162 (define_insn "*insv_z10_noshift_cconly"
4163 [(set
4164 (reg CC_REGNUM)
4165 (compare
4166 (ior:DI
4167 (and:DI (match_operand:DI 1 "nonimmediate_operand" "d,0")
4168 (match_operand:DI 2 "contiguous_bitmask_operand" ""))
4169 (and:DI (match_operand:DI 3 "nonimmediate_operand" "0,d")
4170 (match_operand:DI 4 "const_int_operand" "")))
4171 (const_int 0)))
4172 (clobber (match_scratch:DI 0 "=d,d"))]
4173 "TARGET_Z10 && s390_match_ccmode (insn, CCSmode)
4174 && INTVAL (operands[2]) == ~INTVAL (operands[4])"
4175 "@
4176 risbg\t%0,%1,%s2,%e2,0
4177 risbg\t%0,%3,%s4,%e4,0"
4178 [(set_attr "op_type" "RIE")
4179 (set_attr "z10prop" "z10_super_E1")])
4180
4181 ; Implement appending Y on the left of S bits of X
4182 ; x = (y << s) | (x & ((1 << s) - 1))
4183 (define_insn "*insv<mode><clobbercc_or_nocc>_appendbitsleft"
4184 [(set (match_operand:GPR 0 "nonimmediate_operand" "=d")
4185 (ior:GPR (and:GPR (match_operand:GPR 1 "nonimmediate_operand" "0")
4186 (match_operand:GPR 2 "immediate_operand" ""))
4187 (ashift:GPR (match_operand:GPR 3 "nonimmediate_operand" "d")
4188 (match_operand:GPR 4 "nonzero_shift_count_operand" ""))))]
4189 "<z10_or_zEC12_cond>
4190 && UINTVAL (operands[2]) == (HOST_WIDE_INT_1U << UINTVAL (operands[4])) - 1"
4191 "<risbg_n>\t%0,%3,<bitoff>,64-%4-1,%4"
4192 [(set_attr "op_type" "RIE")
4193 (set_attr "z10prop" "z10_super_E1")])
4194
4195 ; a = ((i32)a & -16777216) | (((ui32)b) >> 8)
4196 (define_insn "*<risbg_n>_<mode>_ior_and_lshiftrt"
4197 [(set (match_operand:GPR 0 "register_operand" "=d")
4198 (ior:GPR (and:GPR
4199 (match_operand:GPR 1 "register_operand" "0")
4200 (match_operand:GPR 2 "const_int_operand" ""))
4201 (lshiftrt:GPR
4202 (match_operand:GPR 3 "register_operand" "d")
4203 (match_operand:GPR 4 "nonzero_shift_count_operand" ""))))]
4204 "<z10_or_zEC12_cond> && UINTVAL (operands[2])
4205 == (HOST_WIDE_INT_M1U
4206 << (GET_MODE_BITSIZE (<MODE>mode) - UINTVAL (operands[4])))"
4207 "<risbg_n>\t%0,%3,<bitoff_plus>%4,63,64-%4"
4208 [(set_attr "op_type" "RIE")
4209 (set_attr "z10prop" "z10_super_E1")])
4210
4211 ; (ui32)(((ui64)x) >> 48) | ((i32)y & -65536);
4212 (define_insn "*<risbg_n>_sidi_ior_and_lshiftrt"
4213 [(set (match_operand:SI 0 "register_operand" "=d")
4214 (ior:SI (and:SI
4215 (match_operand:SI 1 "register_operand" "0")
4216 (match_operand:SI 2 "const_int_operand" ""))
4217 (subreg:SI
4218 (lshiftrt:DI
4219 (match_operand:DI 3 "register_operand" "d")
4220 (match_operand:DI 4 "nonzero_shift_count_operand" "")) 4)))]
4221 "<z10_or_zEC12_cond>
4222 && UINTVAL (operands[2]) == ~(HOST_WIDE_INT_M1U >> UINTVAL (operands[4]))"
4223 "<risbg_n>\t%0,%3,%4,63,64-%4"
4224 [(set_attr "op_type" "RIE")
4225 (set_attr "z10prop" "z10_super_E1")])
4226
4227 ; (ui32)(((ui64)x) >> 12) & -4
4228 (define_insn "*trunc_sidi_and_subreg_lshrt<clobbercc_or_nocc>"
4229 [(set (match_operand:SI 0 "register_operand" "=d")
4230 (and:SI
4231 (subreg:SI (lshiftrt:DI
4232 (match_operand:DI 1 "register_operand" "d")
4233 (match_operand:DI 2 "nonzero_shift_count_operand" "")) 4)
4234 (match_operand:SI 3 "contiguous_bitmask_nowrap_operand" "")))]
4235 "<z10_or_zEC12_cond>"
4236 "<risbg_n>\t%0,%1,%t3,128+%f3,64-%2"
4237 [(set_attr "op_type" "RIE")
4238 (set_attr "z10prop" "z10_super_E1")])
4239
4240 ; z = (x << c) | (y >> d) with (x << c) and (y >> d) not overlapping after shifting
4241 ; -> z = y >> d; z = (x << c) | (z & ((1 << c) - 1))
4242 ; -> z = y >> d; z = risbg;
4243
4244 (define_split
4245 [(set (match_operand:GPR 0 "nonimmediate_operand" "")
4246 (ior:GPR (lshiftrt:GPR (match_operand:GPR 1 "nonimmediate_operand" "")
4247 (match_operand:GPR 2 "nonzero_shift_count_operand" ""))
4248 (ashift:GPR (match_operand:GPR 3 "nonimmediate_operand" "")
4249 (match_operand:GPR 4 "nonzero_shift_count_operand" ""))))]
4250 "TARGET_ZEC12 && UINTVAL (operands[2]) + UINTVAL (operands[4]) >= <bitsize>"
4251 [(set (match_dup 6)
4252 (lshiftrt:GPR (match_dup 1) (match_dup 2)))
4253 (set (match_dup 0)
4254 (ior:GPR (and:GPR (match_dup 6) (match_dup 5))
4255 (ashift:GPR (match_dup 3) (match_dup 4))))]
4256 {
4257 operands[5] = GEN_INT ((HOST_WIDE_INT_1U << UINTVAL (operands[4])) - 1);
4258 if (reg_overlap_mentioned_p (operands[0], operands[3]))
4259 {
4260 if (!can_create_pseudo_p ())
4261 FAIL;
4262 operands[6] = gen_reg_rtx (<MODE>mode);
4263 }
4264 else
4265 operands[6] = operands[0];
4266 })
4267
4268 (define_split
4269 [(parallel
4270 [(set (match_operand:GPR 0 "nonimmediate_operand" "")
4271 (ior:GPR (lshiftrt:GPR (match_operand:GPR 1 "nonimmediate_operand" "")
4272 (match_operand:GPR 2 "nonzero_shift_count_operand" ""))
4273 (ashift:GPR (match_operand:GPR 3 "nonimmediate_operand" "")
4274 (match_operand:GPR 4 "nonzero_shift_count_operand" ""))))
4275 (clobber (reg:CC CC_REGNUM))])]
4276 "TARGET_Z10 && !TARGET_ZEC12 && UINTVAL (operands[2]) + UINTVAL (operands[4]) >= <bitsize>"
4277 [(set (match_dup 6)
4278 (lshiftrt:GPR (match_dup 1) (match_dup 2)))
4279 (parallel
4280 [(set (match_dup 0)
4281 (ior:GPR (and:GPR (match_dup 6) (match_dup 5))
4282 (ashift:GPR (match_dup 3) (match_dup 4))))
4283 (clobber (reg:CC CC_REGNUM))])]
4284 {
4285 operands[5] = GEN_INT ((HOST_WIDE_INT_1U << UINTVAL (operands[4])) - 1);
4286 if (reg_overlap_mentioned_p (operands[0], operands[3]))
4287 {
4288 if (!can_create_pseudo_p ())
4289 FAIL;
4290 operands[6] = gen_reg_rtx (<MODE>mode);
4291 }
4292 else
4293 operands[6] = operands[0];
4294 })
4295
4296 ; rosbg, rxsbg
4297 (define_insn "*r<noxa>sbg_<mode>_noshift"
4298 [(set (match_operand:GPR 0 "nonimmediate_operand" "=d")
4299 (IXOR:GPR
4300 (and:GPR (match_operand:GPR 1 "nonimmediate_operand" "d")
4301 (match_operand:GPR 2 "contiguous_bitmask_operand" ""))
4302 (match_operand:GPR 3 "nonimmediate_operand" "0")))
4303 (clobber (reg:CC CC_REGNUM))]
4304 "TARGET_Z10"
4305 "r<noxa>sbg\t%0,%1,%<bfstart>2,%<bfend>2,0"
4306 [(set_attr "op_type" "RIE")])
4307
4308 ; rosbg, rxsbg
4309 (define_insn "*r<noxa>sbg_di_rotl"
4310 [(set (match_operand:DI 0 "nonimmediate_operand" "=d")
4311 (IXOR:DI
4312 (and:DI
4313 (rotate:DI
4314 (match_operand:DI 1 "nonimmediate_operand" "d")
4315 (match_operand:DI 3 "const_int_operand" ""))
4316 (match_operand:DI 2 "contiguous_bitmask_operand" ""))
4317 (match_operand:DI 4 "nonimmediate_operand" "0")))
4318 (clobber (reg:CC CC_REGNUM))]
4319 "TARGET_Z10"
4320 "r<noxa>sbg\t%0,%1,%s2,%e2,%b3"
4321 [(set_attr "op_type" "RIE")])
4322
4323 ; rosbg, rxsbg
4324 (define_insn "*r<noxa>sbg_<mode>_srl_bitmask"
4325 [(set (match_operand:GPR 0 "nonimmediate_operand" "=d")
4326 (IXOR:GPR
4327 (and:GPR
4328 (lshiftrt:GPR
4329 (match_operand:GPR 1 "nonimmediate_operand" "d")
4330 (match_operand:GPR 3 "nonzero_shift_count_operand" ""))
4331 (match_operand:GPR 2 "contiguous_bitmask_nowrap_operand" ""))
4332 (match_operand:GPR 4 "nonimmediate_operand" "0")))
4333 (clobber (reg:CC CC_REGNUM))]
4334 "TARGET_Z10
4335 && s390_extzv_shift_ok (<bitsize>, 64 - INTVAL (operands[3]),
4336 INTVAL (operands[2]))"
4337 {
4338 operands[3] = GEN_INT (64 - INTVAL (operands[3]));
4339 return "r<noxa>sbg\t%0,%1,%<bfstart>2,%<bfend>2,%3";
4340 }
4341 [(set_attr "op_type" "RIE")])
4342
4343 ; rosbg, rxsbg
4344 (define_insn "*r<noxa>sbg_<mode>_sll_bitmask"
4345 [(set (match_operand:GPR 0 "nonimmediate_operand" "=d")
4346 (IXOR:GPR
4347 (and:GPR
4348 (ashift:GPR
4349 (match_operand:GPR 1 "nonimmediate_operand" "d")
4350 (match_operand:GPR 3 "nonzero_shift_count_operand" ""))
4351 (match_operand:GPR 2 "contiguous_bitmask_nowrap_operand" ""))
4352 (match_operand:GPR 4 "nonimmediate_operand" "0")))
4353 (clobber (reg:CC CC_REGNUM))]
4354 "TARGET_Z10
4355 && s390_extzv_shift_ok (<bitsize>, INTVAL (operands[3]),
4356 INTVAL (operands[2]))"
4357 "r<noxa>sbg\t%0,%1,%<bfstart>2,%<bfend>2,%3"
4358 [(set_attr "op_type" "RIE")])
4359
4360 ;; unsigned {int,long} a, b
4361 ;; a = a | (b << const_int)
4362 ;; a = a ^ (b << const_int)
4363 ; rosbg, rxsbg
4364 (define_insn "*r<noxa>sbg_<mode>_sll"
4365 [(set (match_operand:GPR 0 "nonimmediate_operand" "=d")
4366 (IXOR:GPR
4367 (ashift:GPR
4368 (match_operand:GPR 1 "nonimmediate_operand" "d")
4369 (match_operand:GPR 2 "nonzero_shift_count_operand" ""))
4370 (match_operand:GPR 3 "nonimmediate_operand" "0")))
4371 (clobber (reg:CC CC_REGNUM))]
4372 "TARGET_Z10"
4373 {
4374 operands[3] = GEN_INT (63 - INTVAL (operands[2]));
4375 return "r<noxa>sbg\t%0,%1,<bitoff>,%3,%2";
4376 }
4377 [(set_attr "op_type" "RIE")])
4378
4379 ;; unsigned {int,long} a, b
4380 ;; a = a | (b >> const_int)
4381 ;; a = a ^ (b >> const_int)
4382 ; rosbg, rxsbg
4383 (define_insn "*r<noxa>sbg_<mode>_srl"
4384 [(set (match_operand:GPR 0 "nonimmediate_operand" "=d")
4385 (IXOR:GPR
4386 (lshiftrt:GPR
4387 (match_operand:GPR 1 "nonimmediate_operand" "d")
4388 (match_operand:GPR 2 "nonzero_shift_count_operand" ""))
4389 (match_operand:GPR 3 "nonimmediate_operand" "0")))
4390 (clobber (reg:CC CC_REGNUM))]
4391 "TARGET_Z10"
4392 {
4393 operands[3] = GEN_INT (64 - INTVAL (operands[2]));
4394 operands[2] = GEN_INT (<bitoff_plus> INTVAL (operands[2]));
4395 return "r<noxa>sbg\t%0,%1,%2,63,%3";
4396 }
4397 [(set_attr "op_type" "RIE")])
4398
4399 ; rosbg, rxsbg
4400 (define_insn "*r<noxa>sbg_sidi_srl"
4401 [(set (match_operand:SI 0 "nonimmediate_operand" "=d")
4402 (IXOR:SI
4403 (subreg:SI
4404 (zero_extract:DI
4405 (match_operand:DI 1 "nonimmediate_operand" "d")
4406 (const_int 32)
4407 (match_operand:DI 2 "immediate_operand" ""))
4408 4)
4409 (match_operand:SI 3 "nonimmediate_operand" "0")))
4410 (clobber (reg:CC CC_REGNUM))]
4411 "TARGET_Z10"
4412 {
4413 operands[2] = GEN_INT (32 + INTVAL (operands[2]));
4414 return "r<noxa>sbg\t%0,%1,32,63,%2";
4415 }
4416 [(set_attr "op_type" "RIE")])
4417
4418 ;; These two are generated by combine for s.bf &= val.
4419 ;; ??? For bitfields smaller than 32-bits, we wind up with SImode
4420 ;; shifts and ands, which results in some truly awful patterns
4421 ;; including subregs of operations. Rather unnecessisarily, IMO.
4422 ;; Instead of
4423 ;;
4424 ;; (set (zero_extract:DI (reg/v:DI 50 [ s ])
4425 ;; (const_int 24 [0x18])
4426 ;; (const_int 0 [0]))
4427 ;; (subreg:DI (and:SI (subreg:SI (lshiftrt:DI (reg/v:DI 50 [ s ])
4428 ;; (const_int 40 [0x28])) 4)
4429 ;; (reg:SI 4 %r4 [ y+4 ])) 0))
4430 ;;
4431 ;; we should instead generate
4432 ;;
4433 ;; (set (zero_extract:DI (reg/v:DI 50 [ s ])
4434 ;; (const_int 24 [0x18])
4435 ;; (const_int 0 [0]))
4436 ;; (and:DI (lshiftrt:DI (reg/v:DI 50 [ s ])
4437 ;; (const_int 40 [0x28]))
4438 ;; (subreg:DI (reg:SI 4 %r4 [ y+4 ]) 0)))
4439 ;;
4440 ;; by noticing that we can push down the outer paradoxical subreg
4441 ;; into the operation.
4442
4443 (define_insn "*insv_rnsbg_noshift"
4444 [(set (zero_extract:DI
4445 (match_operand:DI 0 "nonimmediate_operand" "+d")
4446 (match_operand 1 "const_int_operand" "")
4447 (match_operand 2 "const_int_operand" ""))
4448 (and:DI
4449 (match_dup 0)
4450 (match_operand:DI 3 "nonimmediate_operand" "d")))
4451 (clobber (reg:CC CC_REGNUM))]
4452 "TARGET_Z10
4453 && EXTRACT_ARGS_IN_RANGE (INTVAL (operands[1]), INTVAL (operands[2]), 64)
4454 && INTVAL (operands[1]) + INTVAL (operands[2]) == 64"
4455 "rnsbg\t%0,%3,%2,63,0"
4456 [(set_attr "op_type" "RIE")])
4457
4458 (define_insn "*insv_rnsbg_srl"
4459 [(set (zero_extract:DI
4460 (match_operand:DI 0 "nonimmediate_operand" "+d")
4461 (match_operand 1 "const_int_operand" "")
4462 (match_operand 2 "const_int_operand" ""))
4463 (and:DI
4464 (lshiftrt:DI
4465 (match_dup 0)
4466 (match_operand 3 "const_int_operand" ""))
4467 (match_operand:DI 4 "nonimmediate_operand" "d")))
4468 (clobber (reg:CC CC_REGNUM))]
4469 "TARGET_Z10
4470 && EXTRACT_ARGS_IN_RANGE (INTVAL (operands[1]), INTVAL (operands[2]), 64)
4471 && INTVAL (operands[3]) == 64 - INTVAL (operands[1]) - INTVAL (operands[2])"
4472 "rnsbg\t%0,%4,%2,%2+%1-1,%3"
4473 [(set_attr "op_type" "RIE")])
4474
4475 (define_insn "*insv<mode>_mem_reg"
4476 [(set (zero_extract:W (match_operand:QI 0 "memory_operand" "+Q,S")
4477 (match_operand 1 "const_int_operand" "n,n")
4478 (const_int 0))
4479 (match_operand:W 2 "register_operand" "d,d"))]
4480 "EXTRACT_ARGS_IN_RANGE (INTVAL (operands[1]), 0, 64)
4481 && INTVAL (operands[1]) > 0
4482 && INTVAL (operands[1]) <= GET_MODE_BITSIZE (SImode)
4483 && INTVAL (operands[1]) % BITS_PER_UNIT == 0"
4484 {
4485 int size = INTVAL (operands[1]) / BITS_PER_UNIT;
4486
4487 operands[1] = GEN_INT ((HOST_WIDE_INT_1U << size) - 1);
4488 return (which_alternative == 0) ? "stcm\t%2,%1,%S0"
4489 : "stcmy\t%2,%1,%S0";
4490 }
4491 [(set_attr "op_type" "RS,RSY")
4492 (set_attr "cpu_facility" "*,longdisp")
4493 (set_attr "z10prop" "z10_super,z10_super")])
4494
4495 (define_insn "*insvdi_mem_reghigh"
4496 [(set (zero_extract:DI (match_operand:QI 0 "memory_operand" "+S")
4497 (match_operand 1 "const_int_operand" "n")
4498 (const_int 0))
4499 (lshiftrt:DI (match_operand:DI 2 "register_operand" "d")
4500 (const_int 32)))]
4501 "TARGET_ZARCH
4502 && EXTRACT_ARGS_IN_RANGE (INTVAL (operands[1]), 0, 64)
4503 && INTVAL (operands[1]) > 0
4504 && INTVAL (operands[1]) <= GET_MODE_BITSIZE (SImode)
4505 && INTVAL (operands[1]) % BITS_PER_UNIT == 0"
4506 {
4507 int size = INTVAL (operands[1]) / BITS_PER_UNIT;
4508
4509 operands[1] = GEN_INT ((HOST_WIDE_INT_1U << size) - 1);
4510 return "stcmh\t%2,%1,%S0";
4511 }
4512 [(set_attr "op_type" "RSY")
4513 (set_attr "z10prop" "z10_super")])
4514
4515 (define_insn "*insvdi_reg_imm"
4516 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+d")
4517 (const_int 16)
4518 (match_operand 1 "const_int_operand" "n"))
4519 (match_operand:DI 2 "const_int_operand" "n"))]
4520 "TARGET_ZARCH
4521 && EXTRACT_ARGS_IN_RANGE (16, INTVAL (operands[1]), 64)
4522 && INTVAL (operands[1]) >= 0
4523 && INTVAL (operands[1]) < BITS_PER_WORD
4524 && INTVAL (operands[1]) % 16 == 0"
4525 {
4526 switch (BITS_PER_WORD - INTVAL (operands[1]))
4527 {
4528 case 64: return "iihh\t%0,%x2"; break;
4529 case 48: return "iihl\t%0,%x2"; break;
4530 case 32: return "iilh\t%0,%x2"; break;
4531 case 16: return "iill\t%0,%x2"; break;
4532 default: gcc_unreachable();
4533 }
4534 }
4535 [(set_attr "op_type" "RI")
4536 (set_attr "z10prop" "z10_super_E1")])
4537
4538 ; Update the left-most 32 bit of a DI.
4539 (define_insn "*insv_h_di_reg_extimm"
4540 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+d")
4541 (const_int 32)
4542 (const_int 0))
4543 (match_operand:DI 1 "const_int_operand" "n"))]
4544 "TARGET_EXTIMM"
4545 "iihf\t%0,%o1"
4546 [(set_attr "op_type" "RIL")
4547 (set_attr "z10prop" "z10_fwd_E1")])
4548
4549 ; Update the right-most 32 bit of a DI.
4550 (define_insn "*insv_l_di_reg_extimm"
4551 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+d")
4552 (const_int 32)
4553 (const_int 32))
4554 (match_operand:DI 1 "const_int_operand" "n"))]
4555 "TARGET_EXTIMM"
4556 "iilf\t%0,%o1"
4557 [(set_attr "op_type" "RIL")
4558 (set_attr "z10prop" "z10_fwd_A1")])
4559
4560 ;
4561 ; extendsidi2 instruction pattern(s).
4562 ;
4563
4564 (define_expand "extendsidi2"
4565 [(set (match_operand:DI 0 "register_operand" "")
4566 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "")))]
4567 ""
4568 {
4569 if (!TARGET_ZARCH)
4570 {
4571 emit_clobber (operands[0]);
4572 emit_move_insn (gen_highpart (SImode, operands[0]), operands[1]);
4573 emit_move_insn (gen_lowpart (SImode, operands[0]), const0_rtx);
4574 emit_insn (gen_ashrdi3 (operands[0], operands[0], GEN_INT (32)));
4575 DONE;
4576 }
4577 })
4578
4579 (define_insn "*extendsidi2"
4580 [(set (match_operand:DI 0 "register_operand" "=d,d,d")
4581 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "d,T,b")))]
4582 "TARGET_ZARCH"
4583 "@
4584 lgfr\t%0,%1
4585 lgf\t%0,%1
4586 lgfrl\t%0,%1"
4587 [(set_attr "op_type" "RRE,RXY,RIL")
4588 (set_attr "type" "*,*,larl")
4589 (set_attr "cpu_facility" "*,*,z10")
4590 (set_attr "z10prop" "z10_super_E1,z10_super_E1,z10_super_E1")
4591 (set_attr "relative_long" "*,*,yes")])
4592
4593 ;
4594 ; extend(hi|qi)(si|di)2 instruction pattern(s).
4595 ;
4596
4597 (define_expand "extend<HQI:mode><DSI:mode>2"
4598 [(set (match_operand:DSI 0 "register_operand" "")
4599 (sign_extend:DSI (match_operand:HQI 1 "nonimmediate_operand" "")))]
4600 ""
4601 {
4602 if (<DSI:MODE>mode == DImode && !TARGET_ZARCH)
4603 {
4604 rtx tmp = gen_reg_rtx (SImode);
4605 emit_insn (gen_extend<HQI:mode>si2 (tmp, operands[1]));
4606 emit_insn (gen_extendsidi2 (operands[0], tmp));
4607 DONE;
4608 }
4609 else if (!TARGET_EXTIMM)
4610 {
4611 rtx bitcount = GEN_INT (<DSI:bitsize> - <HQI:bitsize>);
4612
4613 operands[1] = gen_lowpart (<DSI:MODE>mode, operands[1]);
4614 emit_insn (gen_ashl<DSI:mode>3 (operands[0], operands[1], bitcount));
4615 emit_insn (gen_ashr<DSI:mode>3 (operands[0], operands[0], bitcount));
4616 DONE;
4617 }
4618 })
4619
4620 ;
4621 ; extendhidi2 instruction pattern(s).
4622 ;
4623
4624 (define_insn "*extendhidi2_extimm"
4625 [(set (match_operand:DI 0 "register_operand" "=d,d,d")
4626 (sign_extend:DI (match_operand:HI 1 "general_operand" "d,T,b")))]
4627 "TARGET_ZARCH && TARGET_EXTIMM"
4628 "@
4629 lghr\t%0,%1
4630 lgh\t%0,%1
4631 lghrl\t%0,%1"
4632 [(set_attr "op_type" "RRE,RXY,RIL")
4633 (set_attr "type" "*,*,larl")
4634 (set_attr "cpu_facility" "extimm,extimm,z10")
4635 (set_attr "z10prop" "z10_super_E1,z10_super_E1,z10_super_E1")
4636 (set_attr "relative_long" "*,*,yes")])
4637
4638 (define_insn "*extendhidi2"
4639 [(set (match_operand:DI 0 "register_operand" "=d")
4640 (sign_extend:DI (match_operand:HI 1 "memory_operand" "T")))]
4641 "TARGET_ZARCH"
4642 "lgh\t%0,%1"
4643 [(set_attr "op_type" "RXY")
4644 (set_attr "z10prop" "z10_super_E1")])
4645
4646 ;
4647 ; extendhisi2 instruction pattern(s).
4648 ;
4649
4650 (define_insn "*extendhisi2_extimm"
4651 [(set (match_operand:SI 0 "register_operand" "=d,d,d,d")
4652 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" " d,R,T,b")))]
4653 "TARGET_EXTIMM"
4654 "@
4655 lhr\t%0,%1
4656 lh\t%0,%1
4657 lhy\t%0,%1
4658 lhrl\t%0,%1"
4659 [(set_attr "op_type" "RRE,RX,RXY,RIL")
4660 (set_attr "type" "*,*,*,larl")
4661 (set_attr "cpu_facility" "extimm,extimm,extimm,z10")
4662 (set_attr "z10prop" "z10_super_E1,z10_super_E1,z10_super_E1,z10_super_E1")
4663 (set_attr "relative_long" "*,*,*,yes")])
4664
4665 (define_insn "*extendhisi2"
4666 [(set (match_operand:SI 0 "register_operand" "=d,d")
4667 (sign_extend:SI (match_operand:HI 1 "memory_operand" "R,T")))]
4668 "!TARGET_EXTIMM"
4669 "@
4670 lh\t%0,%1
4671 lhy\t%0,%1"
4672 [(set_attr "op_type" "RX,RXY")
4673 (set_attr "cpu_facility" "*,longdisp")
4674 (set_attr "z10prop" "z10_super_E1,z10_super_E1")])
4675
4676 ;
4677 ; extendqi(si|di)2 instruction pattern(s).
4678 ;
4679
4680 ; lbr, lgbr, lb, lgb
4681 (define_insn "*extendqi<mode>2_extimm"
4682 [(set (match_operand:GPR 0 "register_operand" "=d,d")
4683 (sign_extend:GPR (match_operand:QI 1 "nonimmediate_operand" "d,T")))]
4684 "TARGET_EXTIMM"
4685 "@
4686 l<g>br\t%0,%1
4687 l<g>b\t%0,%1"
4688 [(set_attr "op_type" "RRE,RXY")
4689 (set_attr "z10prop" "z10_super_E1,z10_super_E1")])
4690
4691 ; lb, lgb
4692 (define_insn "*extendqi<mode>2"
4693 [(set (match_operand:GPR 0 "register_operand" "=d")
4694 (sign_extend:GPR (match_operand:QI 1 "memory_operand" "T")))]
4695 "!TARGET_EXTIMM && TARGET_LONG_DISPLACEMENT"
4696 "l<g>b\t%0,%1"
4697 [(set_attr "op_type" "RXY")
4698 (set_attr "z10prop" "z10_super_E1")])
4699
4700 (define_insn_and_split "*extendqi<mode>2_short_displ"
4701 [(set (match_operand:GPR 0 "register_operand" "=d")
4702 (sign_extend:GPR (match_operand:QI 1 "s_operand" "Q")))
4703 (clobber (reg:CC CC_REGNUM))]
4704 "!TARGET_EXTIMM && !TARGET_LONG_DISPLACEMENT"
4705 "#"
4706 "&& reload_completed"
4707 [(parallel
4708 [(set (match_dup 0) (unspec:GPR [(match_dup 1) (const_int 8)] UNSPEC_ICM))
4709 (clobber (reg:CC CC_REGNUM))])
4710 (parallel
4711 [(set (match_dup 0) (ashiftrt:GPR (match_dup 0) (match_dup 2)))
4712 (clobber (reg:CC CC_REGNUM))])]
4713 {
4714 operands[1] = adjust_address (operands[1], BLKmode, 0);
4715 set_mem_size (operands[1], GET_MODE_SIZE (QImode));
4716 operands[2] = GEN_INT (<GPR:bitsize> - BITS_PER_UNIT);
4717 })
4718
4719 ;
4720 ; zero_extendsidi2 instruction pattern(s).
4721 ;
4722
4723 (define_expand "zero_extendsidi2"
4724 [(set (match_operand:DI 0 "register_operand" "")
4725 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "")))]
4726 ""
4727 {
4728 if (!TARGET_ZARCH)
4729 {
4730 emit_clobber (operands[0]);
4731 emit_move_insn (gen_lowpart (SImode, operands[0]), operands[1]);
4732 emit_move_insn (gen_highpart (SImode, operands[0]), const0_rtx);
4733 DONE;
4734 }
4735 })
4736
4737 (define_insn "*zero_extendsidi2"
4738 [(set (match_operand:DI 0 "register_operand" "=d,d,d")
4739 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "d,T,b")))]
4740 "TARGET_ZARCH"
4741 "@
4742 llgfr\t%0,%1
4743 llgf\t%0,%1
4744 llgfrl\t%0,%1"
4745 [(set_attr "op_type" "RRE,RXY,RIL")
4746 (set_attr "type" "*,*,larl")
4747 (set_attr "cpu_facility" "*,*,z10")
4748 (set_attr "z10prop" "z10_fwd_E1,z10_fwd_A3,z10_fwd_A3")
4749 (set_attr "relative_long" "*,*,yes")])
4750
4751 ;
4752 ; LLGT-type instructions (zero-extend from 31 bit to 64 bit).
4753 ;
4754
4755 (define_insn "*llgt_sidi"
4756 [(set (match_operand:DI 0 "register_operand" "=d")
4757 (and:DI (subreg:DI (match_operand:SI 1 "memory_operand" "T") 0)
4758 (const_int 2147483647)))]
4759 "TARGET_ZARCH"
4760 "llgt\t%0,%1"
4761 [(set_attr "op_type" "RXE")
4762 (set_attr "z10prop" "z10_super_E1")])
4763
4764 (define_insn_and_split "*llgt_sidi_split"
4765 [(set (match_operand:DI 0 "register_operand" "=d")
4766 (and:DI (subreg:DI (match_operand:SI 1 "memory_operand" "T") 0)
4767 (const_int 2147483647)))
4768 (clobber (reg:CC CC_REGNUM))]
4769 "TARGET_ZARCH"
4770 "#"
4771 "&& reload_completed"
4772 [(set (match_dup 0)
4773 (and:DI (subreg:DI (match_dup 1) 0)
4774 (const_int 2147483647)))]
4775 "")
4776
4777 (define_insn "*llgt_sisi"
4778 [(set (match_operand:SI 0 "register_operand" "=d,d")
4779 (and:SI (match_operand:SI 1 "nonimmediate_operand" "d,T")
4780 (const_int 2147483647)))]
4781 "TARGET_ZARCH"
4782 "@
4783 llgtr\t%0,%1
4784 llgt\t%0,%1"
4785 [(set_attr "op_type" "RRE,RXE")
4786 (set_attr "z10prop" "z10_super_E1,z10_super_E1")])
4787
4788 (define_insn "*llgt_didi"
4789 [(set (match_operand:DI 0 "register_operand" "=d,d")
4790 (and:DI (match_operand:DI 1 "nonimmediate_operand" "d,o")
4791 (const_int 2147483647)))]
4792 "TARGET_ZARCH"
4793 "@
4794 llgtr\t%0,%1
4795 llgt\t%0,%N1"
4796 [(set_attr "op_type" "RRE,RXE")
4797 (set_attr "z10prop" "z10_super_E1,z10_super_E1")])
4798
4799 (define_split
4800 [(set (match_operand:DSI 0 "register_operand" "")
4801 (and:DSI (match_operand:DSI 1 "nonimmediate_operand" "")
4802 (const_int 2147483647)))
4803 (clobber (reg:CC CC_REGNUM))]
4804 "TARGET_ZARCH && reload_completed"
4805 [(set (match_dup 0)
4806 (and:DSI (match_dup 1)
4807 (const_int 2147483647)))]
4808 "")
4809
4810 ;
4811 ; zero_extend(hi|qi)(si|di)2 instruction pattern(s).
4812 ;
4813
4814 (define_expand "zero_extend<mode>di2"
4815 [(set (match_operand:DI 0 "register_operand" "")
4816 (zero_extend:DI (match_operand:HQI 1 "nonimmediate_operand" "")))]
4817 ""
4818 {
4819 if (!TARGET_ZARCH)
4820 {
4821 rtx tmp = gen_reg_rtx (SImode);
4822 emit_insn (gen_zero_extend<mode>si2 (tmp, operands[1]));
4823 emit_insn (gen_zero_extendsidi2 (operands[0], tmp));
4824 DONE;
4825 }
4826 else if (!TARGET_EXTIMM)
4827 {
4828 rtx bitcount = GEN_INT (64 - <HQI:bitsize>);
4829 operands[1] = gen_lowpart (DImode, operands[1]);
4830 emit_insn (gen_ashldi3 (operands[0], operands[1], bitcount));
4831 emit_insn (gen_lshrdi3 (operands[0], operands[0], bitcount));
4832 DONE;
4833 }
4834 })
4835
4836 (define_expand "zero_extend<mode>si2"
4837 [(set (match_operand:SI 0 "register_operand" "")
4838 (zero_extend:SI (match_operand:HQI 1 "nonimmediate_operand" "")))]
4839 ""
4840 {
4841 if (!TARGET_EXTIMM)
4842 {
4843 operands[1] = gen_lowpart (SImode, operands[1]);
4844 emit_insn (gen_andsi3 (operands[0], operands[1],
4845 GEN_INT ((1 << <HQI:bitsize>) - 1)));
4846 DONE;
4847 }
4848 })
4849
4850 ; llhrl, llghrl
4851 (define_insn "*zero_extendhi<mode>2_z10"
4852 [(set (match_operand:GPR 0 "register_operand" "=d,d,d")
4853 (zero_extend:GPR (match_operand:HI 1 "nonimmediate_operand" "d,T,b")))]
4854 "TARGET_Z10"
4855 "@
4856 ll<g>hr\t%0,%1
4857 ll<g>h\t%0,%1
4858 ll<g>hrl\t%0,%1"
4859 [(set_attr "op_type" "RXY,RRE,RIL")
4860 (set_attr "type" "*,*,larl")
4861 (set_attr "cpu_facility" "*,*,z10")
4862 (set_attr "z10prop" "z10_super_E1,z10_fwd_A3,z10_fwd_A3")
4863 (set_attr "relative_long" "*,*,yes")])
4864
4865 ; llhr, llcr, llghr, llgcr, llh, llc, llgh, llgc
4866 (define_insn "*zero_extend<HQI:mode><GPR:mode>2_extimm"
4867 [(set (match_operand:GPR 0 "register_operand" "=d,d")
4868 (zero_extend:GPR (match_operand:HQI 1 "nonimmediate_operand" "d,T")))]
4869 "TARGET_EXTIMM"
4870 "@
4871 ll<g><hc>r\t%0,%1
4872 ll<g><hc>\t%0,%1"
4873 [(set_attr "op_type" "RRE,RXY")
4874 (set_attr "z10prop" "z10_super_E1,z10_fwd_A3")])
4875
4876 ; llgh, llgc
4877 (define_insn "*zero_extend<HQI:mode><GPR:mode>2"
4878 [(set (match_operand:GPR 0 "register_operand" "=d")
4879 (zero_extend:GPR (match_operand:HQI 1 "memory_operand" "T")))]
4880 "TARGET_ZARCH && !TARGET_EXTIMM"
4881 "llg<hc>\t%0,%1"
4882 [(set_attr "op_type" "RXY")
4883 (set_attr "z10prop" "z10_fwd_A3")])
4884
4885 (define_insn_and_split "*zero_extendhisi2_31"
4886 [(set (match_operand:SI 0 "register_operand" "=&d")
4887 (zero_extend:SI (match_operand:HI 1 "s_operand" "S")))
4888 (clobber (reg:CC CC_REGNUM))]
4889 "!TARGET_ZARCH"
4890 "#"
4891 "&& reload_completed"
4892 [(set (match_dup 0) (const_int 0))
4893 (parallel
4894 [(set (strict_low_part (match_dup 2)) (match_dup 1))
4895 (clobber (reg:CC CC_REGNUM))])]
4896 "operands[2] = gen_lowpart (HImode, operands[0]);")
4897
4898 (define_insn_and_split "*zero_extendqisi2_31"
4899 [(set (match_operand:SI 0 "register_operand" "=&d")
4900 (zero_extend:SI (match_operand:QI 1 "memory_operand" "T")))]
4901 "!TARGET_ZARCH"
4902 "#"
4903 "&& reload_completed"
4904 [(set (match_dup 0) (const_int 0))
4905 (set (strict_low_part (match_dup 2)) (match_dup 1))]
4906 "operands[2] = gen_lowpart (QImode, operands[0]);")
4907
4908 ;
4909 ; zero_extendqihi2 instruction pattern(s).
4910 ;
4911
4912 (define_expand "zero_extendqihi2"
4913 [(set (match_operand:HI 0 "register_operand" "")
4914 (zero_extend:HI (match_operand:QI 1 "register_operand" "")))]
4915 "TARGET_ZARCH && !TARGET_EXTIMM"
4916 {
4917 operands[1] = gen_lowpart (HImode, operands[1]);
4918 emit_insn (gen_andhi3 (operands[0], operands[1], GEN_INT (0xff)));
4919 DONE;
4920 })
4921
4922 (define_insn "*zero_extendqihi2_64"
4923 [(set (match_operand:HI 0 "register_operand" "=d")
4924 (zero_extend:HI (match_operand:QI 1 "memory_operand" "T")))]
4925 "TARGET_ZARCH && !TARGET_EXTIMM"
4926 "llgc\t%0,%1"
4927 [(set_attr "op_type" "RXY")
4928 (set_attr "z10prop" "z10_fwd_A3")])
4929
4930 (define_insn_and_split "*zero_extendqihi2_31"
4931 [(set (match_operand:HI 0 "register_operand" "=&d")
4932 (zero_extend:HI (match_operand:QI 1 "memory_operand" "T")))]
4933 "!TARGET_ZARCH"
4934 "#"
4935 "&& reload_completed"
4936 [(set (match_dup 0) (const_int 0))
4937 (set (strict_low_part (match_dup 2)) (match_dup 1))]
4938 "operands[2] = gen_lowpart (QImode, operands[0]);")
4939
4940 ;
4941 ; fixuns_trunc(dd|td|sf|df|tf)(si|di)2 expander
4942 ;
4943
4944 ; This is the only entry point for fixuns_trunc. It multiplexes the
4945 ; expansion to either the *_emu expanders below for pre z196 machines
4946 ; or emits the default pattern otherwise.
4947 (define_expand "fixuns_trunc<FP:mode><GPR:mode>2"
4948 [(parallel
4949 [(set (match_operand:GPR 0 "register_operand" "")
4950 (unsigned_fix:GPR (match_operand:FP 1 "register_operand" "")))
4951 (unspec:GPR [(match_dup 2)] UNSPEC_ROUND)
4952 (clobber (reg:CC CC_REGNUM))])]
4953 "TARGET_HARD_FLOAT"
4954 {
4955 if (!TARGET_Z196)
4956 {
4957 /* We don't provide emulation for TD|DD->SI. */
4958 if (GET_MODE_CLASS (<FP:MODE>mode) == MODE_DECIMAL_FLOAT
4959 && <GPR:MODE>mode == SImode)
4960 FAIL;
4961 emit_insn (gen_fixuns_trunc<FP:mode><GPR:mode>2_emu (operands[0],
4962 operands[1]));
4963 DONE;
4964 }
4965
4966 if (GET_MODE_CLASS (<FP:MODE>mode) == MODE_DECIMAL_FLOAT)
4967 operands[2] = GEN_INT (DFP_RND_TOWARD_0);
4968 else
4969 operands[2] = GEN_INT (BFP_RND_TOWARD_0);
4970 })
4971
4972 ; (sf|df|tf)->unsigned (si|di)
4973
4974 ; Emulate the unsigned conversion with the signed version for pre z196
4975 ; machines.
4976 (define_expand "fixuns_trunc<BFP:mode><GPR:mode>2_emu"
4977 [(parallel
4978 [(set (match_operand:GPR 0 "register_operand" "")
4979 (unsigned_fix:GPR (match_operand:BFP 1 "register_operand" "")))
4980 (unspec:GPR [(const_int BFP_RND_TOWARD_0)] UNSPEC_ROUND)
4981 (clobber (reg:CC CC_REGNUM))])]
4982 "!TARGET_Z196 && TARGET_HARD_FLOAT"
4983 {
4984 rtx_code_label *label1 = gen_label_rtx ();
4985 rtx_code_label *label2 = gen_label_rtx ();
4986 rtx temp = gen_reg_rtx (<BFP:MODE>mode);
4987 REAL_VALUE_TYPE cmp, sub;
4988
4989 operands[1] = force_reg (<BFP:MODE>mode, operands[1]);
4990 real_2expN (&cmp, <GPR:bitsize> - 1, <BFP:MODE>mode);
4991 real_2expN (&sub, <GPR:bitsize>, <BFP:MODE>mode);
4992
4993 emit_cmp_and_jump_insns (operands[1],
4994 const_double_from_real_value (cmp, <BFP:MODE>mode),
4995 LT, NULL_RTX, VOIDmode, 0, label1);
4996 emit_insn (gen_sub<BFP:mode>3 (temp, operands[1],
4997 const_double_from_real_value (sub, <BFP:MODE>mode)));
4998 emit_insn (gen_fix_trunc<BFP:mode><GPR:mode>2_bfp (operands[0], temp,
4999 GEN_INT (BFP_RND_TOWARD_MINF)));
5000 emit_jump (label2);
5001
5002 emit_label (label1);
5003 emit_insn (gen_fix_trunc<BFP:mode><GPR:mode>2_bfp (operands[0],
5004 operands[1],
5005 GEN_INT (BFP_RND_TOWARD_0)));
5006 emit_label (label2);
5007 DONE;
5008 })
5009
5010 ; dd->unsigned di
5011
5012 ; Emulate the unsigned conversion with the signed version for pre z196
5013 ; machines.
5014 (define_expand "fixuns_truncdddi2_emu"
5015 [(parallel
5016 [(set (match_operand:DI 0 "register_operand" "")
5017 (unsigned_fix:DI (match_operand:DD 1 "register_operand" "")))
5018 (unspec:DI [(const_int DFP_RND_TOWARD_0)] UNSPEC_ROUND)
5019 (clobber (reg:CC CC_REGNUM))])]
5020
5021 "!TARGET_Z196 && TARGET_HARD_DFP"
5022 {
5023 rtx_code_label *label1 = gen_label_rtx ();
5024 rtx_code_label *label2 = gen_label_rtx ();
5025 rtx temp = gen_reg_rtx (TDmode);
5026 REAL_VALUE_TYPE cmp, sub;
5027
5028 decimal_real_from_string (&cmp, "9223372036854775808.0"); /* 2^63 */
5029 decimal_real_from_string (&sub, "18446744073709551616.0"); /* 2^64 */
5030
5031 /* 2^63 can't be represented as 64bit DFP number with full precision. The
5032 solution is doing the check and the subtraction in TD mode and using a
5033 TD -> DI convert afterwards. */
5034 emit_insn (gen_extendddtd2 (temp, operands[1]));
5035 temp = force_reg (TDmode, temp);
5036 emit_cmp_and_jump_insns (temp,
5037 const_double_from_real_value (cmp, TDmode),
5038 LT, NULL_RTX, VOIDmode, 0, label1);
5039 emit_insn (gen_subtd3 (temp, temp,
5040 const_double_from_real_value (sub, TDmode)));
5041 emit_insn (gen_fix_trunctddi2_dfp (operands[0], temp,
5042 GEN_INT (DFP_RND_TOWARD_MINF)));
5043 emit_jump (label2);
5044
5045 emit_label (label1);
5046 emit_insn (gen_fix_truncdddi2_dfp (operands[0], operands[1],
5047 GEN_INT (DFP_RND_TOWARD_0)));
5048 emit_label (label2);
5049 DONE;
5050 })
5051
5052 ; td->unsigned di
5053
5054 ; Emulate the unsigned conversion with the signed version for pre z196
5055 ; machines.
5056 (define_expand "fixuns_trunctddi2_emu"
5057 [(parallel
5058 [(set (match_operand:DI 0 "register_operand" "")
5059 (unsigned_fix:DI (match_operand:TD 1 "register_operand" "")))
5060 (unspec:DI [(const_int DFP_RND_TOWARD_0)] UNSPEC_ROUND)
5061 (clobber (reg:CC CC_REGNUM))])]
5062
5063 "!TARGET_Z196 && TARGET_HARD_DFP"
5064 {
5065 rtx_code_label *label1 = gen_label_rtx ();
5066 rtx_code_label *label2 = gen_label_rtx ();
5067 rtx temp = gen_reg_rtx (TDmode);
5068 REAL_VALUE_TYPE cmp, sub;
5069
5070 operands[1] = force_reg (TDmode, operands[1]);
5071 decimal_real_from_string (&cmp, "9223372036854775808.0"); /* 2^63 */
5072 decimal_real_from_string (&sub, "18446744073709551616.0"); /* 2^64 */
5073
5074 emit_cmp_and_jump_insns (operands[1],
5075 const_double_from_real_value (cmp, TDmode),
5076 LT, NULL_RTX, VOIDmode, 0, label1);
5077 emit_insn (gen_subtd3 (temp, operands[1],
5078 const_double_from_real_value (sub, TDmode)));
5079 emit_insn (gen_fix_trunctddi2_dfp (operands[0], temp,
5080 GEN_INT (DFP_RND_TOWARD_MINF)));
5081 emit_jump (label2);
5082
5083 emit_label (label1);
5084 emit_insn (gen_fix_trunctddi2_dfp (operands[0], operands[1],
5085 GEN_INT (DFP_RND_TOWARD_0)));
5086 emit_label (label2);
5087 DONE;
5088 })
5089
5090 ; Just a dummy to make the code in the first expander a bit easier.
5091 (define_expand "fixuns_trunc<mode>si2_emu"
5092 [(parallel
5093 [(set (match_operand:SI 0 "register_operand" "")
5094 (unsigned_fix:SI (match_operand:DFP 1 "register_operand" "")))
5095 (unspec:DI [(const_int DFP_RND_TOWARD_0)] UNSPEC_ROUND)
5096 (clobber (reg:CC CC_REGNUM))])]
5097
5098 "!TARGET_Z196 && TARGET_HARD_DFP"
5099 {
5100 FAIL;
5101 })
5102
5103
5104 ; fixuns_trunc(tf|df|sf|td|dd)(di|si)2 instruction patterns.
5105
5106 ; df -> unsigned di, vxe2: sf -> unsigned si
5107 ; clgdbr, clfebr, wclgdb, wclfeb
5108 (define_insn "*fixuns_trunc<VX_CONV_BFP:mode><VX_CONV_INT:mode>2_z13"
5109 [(set (match_operand:VX_CONV_INT 0 "register_operand" "=d,v")
5110 (unsigned_fix:VX_CONV_INT (match_operand:VX_CONV_BFP 1 "register_operand" "f,v")))
5111 (unspec:DI [(match_operand:DI 2 "immediate_operand" "K,K")] UNSPEC_ROUND)
5112 (clobber (reg:CC CC_REGNUM))]
5113 "TARGET_VX && TARGET_HARD_FLOAT
5114 && GET_MODE_SIZE (<VX_CONV_INT:MODE>mode) == GET_MODE_SIZE (<VX_CONV_BFP:MODE>mode)"
5115 "@
5116 cl<VX_CONV_INT:gf><VX_CONV_BFP:xde>br\t%0,%h2,%1,0
5117 wcl<VX_CONV_INT:gf><VX_CONV_BFP:xde>b\t%v0,%v1,0,%h2"
5118 [(set_attr "op_type" "RRF,VRR")
5119 (set_attr "type" "ftoi")])
5120
5121 ; (dd|td|sf|df|tf)->unsigned (di|si)
5122 ; clfebr, clfdbr, clfxbr, clgebr, clgdbr, clgxbr
5123 ; clfdtr, clfxtr, clgdtr, clgxtr
5124 (define_insn "*fixuns_trunc<FP:mode><GPR:mode>2_z196"
5125 [(set (match_operand:GPR 0 "register_operand" "=d")
5126 (unsigned_fix:GPR (match_operand:FP 1 "register_operand" "f")))
5127 (unspec:GPR [(match_operand:GPR 2 "immediate_operand" "K")] UNSPEC_ROUND)
5128 (clobber (reg:CC CC_REGNUM))]
5129 "TARGET_Z196 && TARGET_HARD_FLOAT
5130 && (!TARGET_VX || <GPR:MODE>mode != DImode || <FP:MODE>mode != DFmode)"
5131 "cl<GPR:gf><FP:xde><FP:bt>r\t%0,%h2,%1,0"
5132 [(set_attr "op_type" "RRF")
5133 (set_attr "type" "ftoi")])
5134
5135 (define_expand "fix_trunc<DSF:mode><GPR:mode>2"
5136 [(set (match_operand:GPR 0 "register_operand" "")
5137 (fix:GPR (match_operand:DSF 1 "register_operand" "")))]
5138 "TARGET_HARD_FLOAT"
5139 {
5140 emit_insn (gen_fix_trunc<DSF:mode><GPR:mode>2_bfp (operands[0], operands[1],
5141 GEN_INT (BFP_RND_TOWARD_0)));
5142 DONE;
5143 })
5144
5145 ; df -> signed di, vxe2: sf -> signed si
5146 ; cgdbr, cfebr, wcgdb, wcfeb
5147 (define_insn "*fix_trunc<VX_CONV_BFP:mode><VX_CONV_INT:mode>2_bfp_z13"
5148 [(set (match_operand:VX_CONV_INT 0 "register_operand" "=d,v")
5149 (fix:VX_CONV_INT (match_operand:VX_CONV_BFP 1 "register_operand" "f,v")))
5150 (unspec:VX_CONV_INT [(match_operand:VX_CONV_INT 2 "immediate_operand" "K,K")] UNSPEC_ROUND)
5151 (clobber (reg:CC CC_REGNUM))]
5152 "TARGET_VX && TARGET_HARD_FLOAT
5153 && GET_MODE_SIZE (<VX_CONV_INT:MODE>mode) == GET_MODE_SIZE (<VX_CONV_BFP:MODE>mode)"
5154 "@
5155 c<VX_CONV_INT:gf><VX_CONV_BFP:xde>br\t%0,%h2,%1
5156 wc<VX_CONV_INT:gf><VX_CONV_BFP:xde>b\t%v0,%v1,0,%h2"
5157 [(set_attr "op_type" "RRE,VRR")
5158 (set_attr "type" "ftoi")])
5159
5160 ; cgxbr, cgdbr, cgebr, cfxbr, cfdbr, cfebr
5161 (define_insn "*fix_trunc<BFP:mode><GPR:mode>2_bfp"
5162 [(set (match_operand:GPR 0 "register_operand" "=d")
5163 (fix:GPR (match_operand:BFP 1 "register_operand" "f")))
5164 (unspec:GPR [(match_operand:GPR 2 "immediate_operand" "K")] UNSPEC_ROUND)
5165 (clobber (reg:CC CC_REGNUM))]
5166 "TARGET_HARD_FLOAT
5167 && (!TARGET_VX || <GPR:MODE>mode != DImode || <BFP:MODE>mode != DFmode)"
5168 "c<GPR:gf><BFP:xde>br\t%0,%h2,%1"
5169 [(set_attr "op_type" "RRE")
5170 (set_attr "type" "ftoi")])
5171
5172 (define_expand "fix_trunc<BFP:mode><GPR:mode>2_bfp"
5173 [(parallel
5174 [(set (match_operand:GPR 0 "register_operand" "=d")
5175 (fix:GPR (match_operand:BFP 1 "register_operand" "f")))
5176 (unspec:GPR [(match_operand:GPR 2 "immediate_operand" "K")] UNSPEC_ROUND)
5177 (clobber (reg:CC CC_REGNUM))])]
5178 "TARGET_HARD_FLOAT")
5179 ;
5180 ; fix_trunc(td|dd)di2 instruction pattern(s).
5181 ;
5182
5183 (define_expand "fix_trunc<mode>di2"
5184 [(set (match_operand:DI 0 "register_operand" "")
5185 (fix:DI (match_operand:DFP 1 "nonimmediate_operand" "")))]
5186 "TARGET_ZARCH && TARGET_HARD_DFP"
5187 {
5188 operands[1] = force_reg (<MODE>mode, operands[1]);
5189 emit_insn (gen_fix_trunc<mode>di2_dfp (operands[0], operands[1],
5190 GEN_INT (DFP_RND_TOWARD_0)));
5191 DONE;
5192 })
5193
5194 ; cgxtr, cgdtr
5195 (define_insn "fix_trunc<DFP:mode>di2_dfp"
5196 [(set (match_operand:DI 0 "register_operand" "=d")
5197 (fix:DI (match_operand:DFP 1 "register_operand" "f")))
5198 (unspec:DI [(match_operand:DI 2 "immediate_operand" "K")] UNSPEC_ROUND)
5199 (clobber (reg:CC CC_REGNUM))]
5200 "TARGET_ZARCH && TARGET_HARD_DFP"
5201 "cg<DFP:xde>tr\t%0,%h2,%1"
5202 [(set_attr "op_type" "RRF")
5203 (set_attr "type" "ftoidfp")])
5204
5205
5206 ;
5207 ; fix_trunctf(si|di)2 instruction pattern(s).
5208 ;
5209
5210 (define_expand "fix_trunctf<mode>2"
5211 [(parallel [(set (match_operand:GPR 0 "register_operand" "")
5212 (fix:GPR (match_operand:TF 1 "register_operand" "")))
5213 (unspec:GPR [(const_int BFP_RND_TOWARD_0)] UNSPEC_ROUND)
5214 (clobber (reg:CC CC_REGNUM))])]
5215 "TARGET_HARD_FLOAT"
5216 "")
5217
5218
5219 ;
5220 ; float(si|di)(tf|df|sf|td|dd)2 instruction pattern(s).
5221 ;
5222
5223 ; cxgbr, cdgbr, cegbr, cxgtr, cdgtr
5224 (define_insn "floatdi<mode>2"
5225 [(set (match_operand:FP 0 "register_operand" "=f,v")
5226 (float:FP (match_operand:DI 1 "register_operand" "d,v")))]
5227 "TARGET_ZARCH && TARGET_HARD_FLOAT"
5228 "@
5229 c<xde>g<bt>r\t%0,%1
5230 wcdgb\t%v0,%v1,0,0"
5231 [(set_attr "op_type" "RRE,VRR")
5232 (set_attr "type" "itof<mode>" )
5233 (set_attr "cpu_facility" "*,vx")
5234 (set_attr "enabled" "*,<DFDI>")])
5235
5236 ; cxfbr, cdfbr, cefbr, wcefb
5237 (define_insn "floatsi<mode>2"
5238 [(set (match_operand:BFP 0 "register_operand" "=f,v")
5239 (float:BFP (match_operand:SI 1 "register_operand" "d,v")))]
5240 "TARGET_HARD_FLOAT"
5241 "@
5242 c<xde>fbr\t%0,%1
5243 wcefb\t%v0,%v1,0,0"
5244 [(set_attr "op_type" "RRE,VRR")
5245 (set_attr "type" "itof<mode>" )
5246 (set_attr "cpu_facility" "*,vxe2")
5247 (set_attr "enabled" "*,<SFSI>")])
5248
5249 ; cxftr, cdftr
5250 (define_insn "floatsi<mode>2"
5251 [(set (match_operand:DFP 0 "register_operand" "=f")
5252 (float:DFP (match_operand:SI 1 "register_operand" "d")))]
5253 "TARGET_Z196 && TARGET_HARD_FLOAT"
5254 "c<xde>ftr\t%0,0,%1,0"
5255 [(set_attr "op_type" "RRE")
5256 (set_attr "type" "itof<mode>" )])
5257
5258 ;
5259 ; floatuns(si|di)(tf|df|sf|td|dd)2 instruction pattern(s).
5260 ;
5261
5262 (define_insn "*floatuns<VX_CONV_INT:mode><VX_CONV_BFP:mode>2_z13"
5263 [(set (match_operand:VX_CONV_BFP 0 "register_operand" "=f,v")
5264 (unsigned_float:VX_CONV_BFP (match_operand:VX_CONV_INT 1 "register_operand" "d,v")))]
5265 "TARGET_VX && TARGET_HARD_FLOAT
5266 && GET_MODE_SIZE (<VX_CONV_INT:MODE>mode) == GET_MODE_SIZE (<VX_CONV_BFP:MODE>mode)"
5267 "@
5268 c<VX_CONV_BFP:xde>l<VX_CONV_INT:gf>br\t%0,0,%1,0
5269 wc<VX_CONV_BFP:xde>l<VX_CONV_INT:gf>b\t%v0,%v1,0,0"
5270 [(set_attr "op_type" "RRE,VRR")
5271 (set_attr "type" "itofdf")])
5272
5273 ; cxlgbr, cdlgbr, celgbr, cxlgtr, cdlgtr
5274 ; cxlfbr, cdlfbr, celfbr, cxlftr, cdlftr
5275 (define_insn "*floatuns<GPR:mode><FP:mode>2"
5276 [(set (match_operand:FP 0 "register_operand" "=f")
5277 (unsigned_float:FP (match_operand:GPR 1 "register_operand" "d")))]
5278 "TARGET_Z196 && TARGET_HARD_FLOAT
5279 && (!TARGET_VX || <FP:MODE>mode != DFmode || <GPR:MODE>mode != DImode)"
5280 "c<FP:xde>l<GPR:gf><FP:bt>r\t%0,0,%1,0"
5281 [(set_attr "op_type" "RRE")
5282 (set_attr "type" "itof<FP:mode>")])
5283
5284 (define_expand "floatuns<GPR:mode><FP:mode>2"
5285 [(set (match_operand:FP 0 "register_operand" "")
5286 (unsigned_float:FP (match_operand:GPR 1 "register_operand" "")))]
5287 "TARGET_Z196 && TARGET_HARD_FLOAT")
5288
5289 ;
5290 ; truncdfsf2 instruction pattern(s).
5291 ;
5292
5293 (define_insn "truncdfsf2"
5294 [(set (match_operand:SF 0 "register_operand" "=f,v")
5295 (float_truncate:SF (match_operand:DF 1 "register_operand" "f,v")))]
5296 "TARGET_HARD_FLOAT"
5297 "@
5298 ledbr\t%0,%1
5299 wledb\t%v0,%v1,0,0" ; IEEE inexact exception not suppressed
5300 ; According to BFP rounding mode
5301 [(set_attr "op_type" "RRE,VRR")
5302 (set_attr "type" "ftruncdf")
5303 (set_attr "cpu_facility" "*,vx")])
5304
5305 ;
5306 ; trunctf(df|sf)2 instruction pattern(s).
5307 ;
5308
5309 ; ldxbr, lexbr
5310 (define_insn "trunctf<mode>2"
5311 [(set (match_operand:DSF 0 "register_operand" "=f")
5312 (float_truncate:DSF (match_operand:TF 1 "register_operand" "f")))
5313 (clobber (match_scratch:TF 2 "=f"))]
5314 "TARGET_HARD_FLOAT"
5315 "l<xde>xbr\t%2,%1\;l<xde>r\t%0,%2"
5316 [(set_attr "length" "6")
5317 (set_attr "type" "ftrunctf")])
5318
5319 ;
5320 ; trunctddd2 and truncddsd2 instruction pattern(s).
5321 ;
5322
5323
5324 (define_expand "trunctddd2"
5325 [(parallel
5326 [(set (match_operand:DD 0 "register_operand" "")
5327 (float_truncate:DD (match_operand:TD 1 "register_operand" "")))
5328 (unspec:DI [(const_int DFP_RND_CURRENT)] UNSPEC_ROUND)
5329 (clobber (scratch:TD))])]
5330 "TARGET_HARD_DFP")
5331
5332 (define_insn "*trunctddd2"
5333 [(set (match_operand:DD 0 "register_operand" "=f")
5334 (float_truncate:DD (match_operand:TD 1 "register_operand" "f")))
5335 (unspec:DI [(match_operand:DI 2 "const_mask_operand" "I")] UNSPEC_ROUND)
5336 (clobber (match_scratch:TD 3 "=f"))]
5337 "TARGET_HARD_DFP"
5338 "ldxtr\t%3,%2,%1,0\;ldr\t%0,%3"
5339 [(set_attr "length" "6")
5340 (set_attr "type" "ftruncdd")])
5341
5342 (define_insn "truncddsd2"
5343 [(set (match_operand:SD 0 "register_operand" "=f")
5344 (float_truncate:SD (match_operand:DD 1 "register_operand" "f")))]
5345 "TARGET_HARD_DFP"
5346 "ledtr\t%0,0,%1,0"
5347 [(set_attr "op_type" "RRF")
5348 (set_attr "type" "ftruncsd")])
5349
5350 (define_expand "trunctdsd2"
5351 [(parallel
5352 [(set (match_dup 2)
5353 (float_truncate:DD (match_operand:TD 1 "register_operand" "")))
5354 (unspec:DI [(const_int DFP_RND_PREP_FOR_SHORT_PREC)] UNSPEC_ROUND)
5355 (clobber (match_scratch:TD 3 ""))])
5356 (set (match_operand:SD 0 "register_operand" "")
5357 (float_truncate:SD (match_dup 2)))]
5358 "TARGET_HARD_DFP"
5359 {
5360 operands[2] = gen_reg_rtx (DDmode);
5361 })
5362
5363 ;
5364 ; extend(sf|df)(df|tf)2 instruction pattern(s).
5365 ;
5366
5367 ; wflls
5368 (define_insn "*extendsfdf2_z13"
5369 [(set (match_operand:DF 0 "register_operand" "=f,f,v")
5370 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "f,R,v")))]
5371 "TARGET_VX && TARGET_HARD_FLOAT"
5372 "@
5373 ldebr\t%0,%1
5374 ldeb\t%0,%1
5375 wldeb\t%v0,%v1"
5376 [(set_attr "op_type" "RRE,RXE,VRR")
5377 (set_attr "type" "fsimpdf, floaddf,fsimpdf")])
5378
5379 ; ldebr, ldeb, lxdbr, lxdb, lxebr, lxeb
5380 (define_insn "*extend<DSF:mode><BFP:mode>2"
5381 [(set (match_operand:BFP 0 "register_operand" "=f,f")
5382 (float_extend:BFP (match_operand:DSF 1 "nonimmediate_operand" "f,R")))]
5383 "TARGET_HARD_FLOAT
5384 && GET_MODE_SIZE (<BFP:MODE>mode) > GET_MODE_SIZE (<DSF:MODE>mode)
5385 && (!TARGET_VX || <BFP:MODE>mode != DFmode || <DSF:MODE>mode != SFmode)"
5386 "@
5387 l<BFP:xde><DSF:xde>br\t%0,%1
5388 l<BFP:xde><DSF:xde>b\t%0,%1"
5389 [(set_attr "op_type" "RRE,RXE")
5390 (set_attr "type" "fsimp<BFP:mode>, fload<BFP:mode>")])
5391
5392 (define_expand "extend<DSF:mode><BFP:mode>2"
5393 [(set (match_operand:BFP 0 "register_operand" "")
5394 (float_extend:BFP (match_operand:DSF 1 "nonimmediate_operand" "")))]
5395 "TARGET_HARD_FLOAT
5396 && GET_MODE_SIZE (<BFP:MODE>mode) > GET_MODE_SIZE (<DSF:MODE>mode)")
5397
5398 ;
5399 ; extendddtd2 and extendsddd2 instruction pattern(s).
5400 ;
5401
5402 (define_insn "extendddtd2"
5403 [(set (match_operand:TD 0 "register_operand" "=f")
5404 (float_extend:TD (match_operand:DD 1 "register_operand" "f")))]
5405 "TARGET_HARD_DFP"
5406 "lxdtr\t%0,%1,0"
5407 [(set_attr "op_type" "RRF")
5408 (set_attr "type" "fsimptf")])
5409
5410 (define_insn "extendsddd2"
5411 [(set (match_operand:DD 0 "register_operand" "=f")
5412 (float_extend:DD (match_operand:SD 1 "register_operand" "f")))]
5413 "TARGET_HARD_DFP"
5414 "ldetr\t%0,%1,0"
5415 [(set_attr "op_type" "RRF")
5416 (set_attr "type" "fsimptf")])
5417
5418 (define_expand "extendsdtd2"
5419 [(set (match_dup 2)
5420 (float_extend:DD (match_operand:SD 1 "register_operand" "")))
5421 (set (match_operand:TD 0 "register_operand" "")
5422 (float_extend:TD (match_dup 2)))]
5423 "TARGET_HARD_DFP"
5424 {
5425 operands[2] = gen_reg_rtx (DDmode);
5426 })
5427
5428 ; Binary Floating Point - load fp integer
5429
5430 ; Expanders for: floor, btrunc, round, ceil, and nearbyint
5431 ; For all of them the inexact exceptions are suppressed.
5432
5433 ; fiebra, fidbra, fixbra
5434 (define_insn "<FPINT:fpint_name><BFP:mode>2"
5435 [(set (match_operand:BFP 0 "register_operand" "=f")
5436 (unspec:BFP [(match_operand:BFP 1 "register_operand" "f")]
5437 FPINT))]
5438 "TARGET_Z196"
5439 "fi<BFP:xde>bra\t%0,<FPINT:fpint_roundingmode>,%1,4"
5440 [(set_attr "op_type" "RRF")
5441 (set_attr "type" "fsimp<BFP:mode>")])
5442
5443 ; rint is supposed to raise an inexact exception so we can use the
5444 ; older instructions.
5445
5446 ; fiebr, fidbr, fixbr
5447 (define_insn "rint<BFP:mode>2"
5448 [(set (match_operand:BFP 0 "register_operand" "=f")
5449 (unspec:BFP [(match_operand:BFP 1 "register_operand" "f")]
5450 UNSPEC_FPINT_RINT))]
5451 ""
5452 "fi<BFP:xde>br\t%0,0,%1"
5453 [(set_attr "op_type" "RRF")
5454 (set_attr "type" "fsimp<BFP:mode>")])
5455
5456
5457 ; Decimal Floating Point - load fp integer
5458
5459 ; fidtr, fixtr
5460 (define_insn "<FPINT:fpint_name><DFP:mode>2"
5461 [(set (match_operand:DFP 0 "register_operand" "=f")
5462 (unspec:DFP [(match_operand:DFP 1 "register_operand" "f")]
5463 FPINT))]
5464 "TARGET_HARD_DFP"
5465 "fi<DFP:xde>tr\t%0,<FPINT:fpint_roundingmode>,%1,4"
5466 [(set_attr "op_type" "RRF")
5467 (set_attr "type" "fsimp<DFP:mode>")])
5468
5469 ; fidtr, fixtr
5470 (define_insn "rint<DFP:mode>2"
5471 [(set (match_operand:DFP 0 "register_operand" "=f")
5472 (unspec:DFP [(match_operand:DFP 1 "register_operand" "f")]
5473 UNSPEC_FPINT_RINT))]
5474 "TARGET_HARD_DFP"
5475 "fi<DFP:xde>tr\t%0,0,%1,0"
5476 [(set_attr "op_type" "RRF")
5477 (set_attr "type" "fsimp<DFP:mode>")])
5478
5479 ;
5480 ; Binary <-> Decimal floating point trunc patterns
5481 ;
5482
5483 (define_insn "*trunc<BFP:mode><DFP_ALL:mode>2"
5484 [(set (reg:DFP_ALL FPR0_REGNUM)
5485 (float_truncate:DFP_ALL (reg:BFP FPR4_REGNUM)))
5486 (use (reg:SI GPR0_REGNUM))
5487 (clobber (reg:CC CC_REGNUM))
5488 (clobber (reg:SI GPR1_REGNUM))]
5489 "TARGET_HARD_DFP"
5490 "pfpo")
5491
5492 (define_insn "*trunc<DFP_ALL:mode><BFP:mode>2"
5493 [(set (reg:BFP FPR0_REGNUM)
5494 (float_truncate:BFP (reg:DFP_ALL FPR4_REGNUM)))
5495 (use (reg:SI GPR0_REGNUM))
5496 (clobber (reg:CC CC_REGNUM))
5497 (clobber (reg:SI GPR1_REGNUM))]
5498 "TARGET_HARD_DFP"
5499 "pfpo")
5500
5501 (define_expand "trunc<BFP:mode><DFP_ALL:mode>2"
5502 [(set (reg:BFP FPR4_REGNUM) (match_operand:BFP 1 "nonimmediate_operand" ""))
5503 (set (reg:SI GPR0_REGNUM) (match_dup 2))
5504 (parallel
5505 [(set (reg:DFP_ALL FPR0_REGNUM)
5506 (float_truncate:DFP_ALL (reg:BFP FPR4_REGNUM)))
5507 (use (reg:SI GPR0_REGNUM))
5508 (clobber (reg:CC CC_REGNUM))
5509 (clobber (reg:SI GPR1_REGNUM))])
5510 (set (match_operand:DFP_ALL 0 "nonimmediate_operand" "")
5511 (reg:DFP_ALL FPR0_REGNUM))]
5512 "TARGET_HARD_DFP
5513 && GET_MODE_SIZE (<BFP:MODE>mode) > GET_MODE_SIZE (<DFP_ALL:MODE>mode)"
5514 {
5515 HOST_WIDE_INT flags;
5516
5517 /* According to IEEE 754 2008 4.3 'Rounding-direction attributes' the
5518 rounding mode of the target format needs to be used. */
5519
5520 flags = (PFPO_CONVERT |
5521 PFPO_OP_TYPE_<DFP_ALL:MODE> << PFPO_OP0_TYPE_SHIFT |
5522 PFPO_OP_TYPE_<BFP:MODE> << PFPO_OP1_TYPE_SHIFT |
5523 PFPO_RND_MODE_DFP);
5524
5525 operands[2] = GEN_INT (flags);
5526 })
5527
5528 (define_expand "trunc<DFP_ALL:mode><BFP:mode>2"
5529 [(set (reg:DFP_ALL FPR4_REGNUM)
5530 (match_operand:DFP_ALL 1 "nonimmediate_operand" ""))
5531 (set (reg:SI GPR0_REGNUM) (match_dup 2))
5532 (parallel
5533 [(set (reg:BFP FPR0_REGNUM) (float_truncate:BFP (reg:DFP_ALL FPR4_REGNUM)))
5534 (use (reg:SI GPR0_REGNUM))
5535 (clobber (reg:CC CC_REGNUM))
5536 (clobber (reg:SI GPR1_REGNUM))])
5537 (set (match_operand:BFP 0 "nonimmediate_operand" "") (reg:BFP FPR0_REGNUM))]
5538 "TARGET_HARD_DFP
5539 && GET_MODE_SIZE (<DFP_ALL:MODE>mode) >= GET_MODE_SIZE (<BFP:MODE>mode)"
5540 {
5541 HOST_WIDE_INT flags;
5542
5543 /* According to IEEE 754 2008 4.3 'Rounding-direction attributes' the
5544 rounding mode of the target format needs to be used. */
5545
5546 flags = (PFPO_CONVERT |
5547 PFPO_OP_TYPE_<BFP:MODE> << PFPO_OP0_TYPE_SHIFT |
5548 PFPO_OP_TYPE_<DFP_ALL:MODE> << PFPO_OP1_TYPE_SHIFT |
5549 PFPO_RND_MODE_BFP);
5550
5551 operands[2] = GEN_INT (flags);
5552 })
5553
5554 ;
5555 ; Binary <-> Decimal floating point extend patterns
5556 ;
5557
5558 (define_insn "*extend<BFP:mode><DFP_ALL:mode>2"
5559 [(set (reg:DFP_ALL FPR0_REGNUM) (float_extend:DFP_ALL (reg:BFP FPR4_REGNUM)))
5560 (use (reg:SI GPR0_REGNUM))
5561 (clobber (reg:CC CC_REGNUM))
5562 (clobber (reg:SI GPR1_REGNUM))]
5563 "TARGET_HARD_DFP"
5564 "pfpo")
5565
5566 (define_insn "*extend<DFP_ALL:mode><BFP:mode>2"
5567 [(set (reg:BFP FPR0_REGNUM) (float_extend:BFP (reg:DFP_ALL FPR4_REGNUM)))
5568 (use (reg:SI GPR0_REGNUM))
5569 (clobber (reg:CC CC_REGNUM))
5570 (clobber (reg:SI GPR1_REGNUM))]
5571 "TARGET_HARD_DFP"
5572 "pfpo")
5573
5574 (define_expand "extend<BFP:mode><DFP_ALL:mode>2"
5575 [(set (reg:BFP FPR4_REGNUM) (match_operand:BFP 1 "nonimmediate_operand" ""))
5576 (set (reg:SI GPR0_REGNUM) (match_dup 2))
5577 (parallel
5578 [(set (reg:DFP_ALL FPR0_REGNUM)
5579 (float_extend:DFP_ALL (reg:BFP FPR4_REGNUM)))
5580 (use (reg:SI GPR0_REGNUM))
5581 (clobber (reg:CC CC_REGNUM))
5582 (clobber (reg:SI GPR1_REGNUM))])
5583 (set (match_operand:DFP_ALL 0 "nonimmediate_operand" "")
5584 (reg:DFP_ALL FPR0_REGNUM))]
5585 "TARGET_HARD_DFP
5586 && GET_MODE_SIZE (<BFP:MODE>mode) <= GET_MODE_SIZE (<DFP_ALL:MODE>mode)"
5587 {
5588 HOST_WIDE_INT flags;
5589
5590 /* According to IEEE 754 2008 4.3 'Rounding-direction attributes' the
5591 rounding mode of the target format needs to be used. */
5592
5593 flags = (PFPO_CONVERT |
5594 PFPO_OP_TYPE_<DFP_ALL:MODE> << PFPO_OP0_TYPE_SHIFT |
5595 PFPO_OP_TYPE_<BFP:MODE> << PFPO_OP1_TYPE_SHIFT |
5596 PFPO_RND_MODE_DFP);
5597
5598 operands[2] = GEN_INT (flags);
5599 })
5600
5601 (define_expand "extend<DFP_ALL:mode><BFP:mode>2"
5602 [(set (reg:DFP_ALL FPR4_REGNUM)
5603 (match_operand:DFP_ALL 1 "nonimmediate_operand" ""))
5604 (set (reg:SI GPR0_REGNUM) (match_dup 2))
5605 (parallel
5606 [(set (reg:BFP FPR0_REGNUM) (float_extend:BFP (reg:DFP_ALL FPR4_REGNUM)))
5607 (use (reg:SI GPR0_REGNUM))
5608 (clobber (reg:CC CC_REGNUM))
5609 (clobber (reg:SI GPR1_REGNUM))])
5610 (set (match_operand:BFP 0 "nonimmediate_operand" "") (reg:BFP FPR0_REGNUM))]
5611 "TARGET_HARD_DFP
5612 && GET_MODE_SIZE (<DFP_ALL:MODE>mode) < GET_MODE_SIZE (<BFP:MODE>mode)"
5613 {
5614 HOST_WIDE_INT flags;
5615
5616 /* According to IEEE 754 2008 4.3 'Rounding-direction attributes' the
5617 rounding mode of the target format needs to be used. */
5618
5619 flags = (PFPO_CONVERT |
5620 PFPO_OP_TYPE_<BFP:MODE> << PFPO_OP0_TYPE_SHIFT |
5621 PFPO_OP_TYPE_<DFP_ALL:MODE> << PFPO_OP1_TYPE_SHIFT |
5622 PFPO_RND_MODE_BFP);
5623
5624 operands[2] = GEN_INT (flags);
5625 })
5626
5627
5628 ;;
5629 ;; ARITHMETIC OPERATIONS
5630 ;;
5631 ; arithmetic operations set the ConditionCode,
5632 ; because of unpredictable Bits in Register for Halfword and Byte
5633 ; the ConditionCode can be set wrong in operations for Halfword and Byte
5634
5635 ;;
5636 ;;- Add instructions.
5637 ;;
5638
5639 ;
5640 ; addti3 instruction pattern(s).
5641 ;
5642
5643 (define_expand "addti3"
5644 [(parallel
5645 [(set (match_operand:TI 0 "register_operand" "")
5646 (plus:TI (match_operand:TI 1 "nonimmediate_operand" "")
5647 (match_operand:TI 2 "general_operand" "") ) )
5648 (clobber (reg:CC CC_REGNUM))])]
5649 "TARGET_ZARCH"
5650 {
5651 /* For z13 we have vaq which doesn't set CC. */
5652 if (TARGET_VX)
5653 {
5654 emit_insn (gen_rtx_SET (operands[0],
5655 gen_rtx_PLUS (TImode,
5656 copy_to_mode_reg (TImode, operands[1]),
5657 copy_to_mode_reg (TImode, operands[2]))));
5658 DONE;
5659 }
5660 })
5661
5662 (define_insn_and_split "*addti3"
5663 [(set (match_operand:TI 0 "register_operand" "=&d")
5664 (plus:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
5665 (match_operand:TI 2 "general_operand" "do") ) )
5666 (clobber (reg:CC CC_REGNUM))]
5667 "TARGET_ZARCH"
5668 "#"
5669 "&& reload_completed"
5670 [(parallel
5671 [(set (reg:CCL1 CC_REGNUM)
5672 (compare:CCL1 (plus:DI (match_dup 7) (match_dup 8))
5673 (match_dup 7)))
5674 (set (match_dup 6) (plus:DI (match_dup 7) (match_dup 8)))])
5675 (parallel
5676 [(set (match_dup 3) (plus:DI
5677 (plus:DI (ltu:DI (reg:CCL1 CC_REGNUM) (const_int 0))
5678 (match_dup 4)) (match_dup 5)))
5679 (clobber (reg:CC CC_REGNUM))])]
5680 "operands[3] = operand_subword (operands[0], 0, 0, TImode);
5681 operands[4] = operand_subword (operands[1], 0, 0, TImode);
5682 operands[5] = operand_subword (operands[2], 0, 0, TImode);
5683 operands[6] = operand_subword (operands[0], 1, 0, TImode);
5684 operands[7] = operand_subword (operands[1], 1, 0, TImode);
5685 operands[8] = operand_subword (operands[2], 1, 0, TImode);"
5686 [(set_attr "op_type" "*")
5687 (set_attr "cpu_facility" "*")])
5688
5689 ;
5690 ; adddi3 instruction pattern(s).
5691 ;
5692
5693 (define_expand "adddi3"
5694 [(parallel
5695 [(set (match_operand:DI 0 "nonimmediate_operand" "")
5696 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
5697 (match_operand:DI 2 "general_operand" "")))
5698 (clobber (reg:CC CC_REGNUM))])]
5699 ""
5700 "")
5701
5702 (define_insn "*adddi3_sign"
5703 [(set (match_operand:DI 0 "register_operand" "=d,d")
5704 (plus:DI (sign_extend:DI (match_operand:SI 2 "general_operand" "d,T"))
5705 (match_operand:DI 1 "register_operand" "0,0")))
5706 (clobber (reg:CC CC_REGNUM))]
5707 "TARGET_ZARCH"
5708 "@
5709 agfr\t%0,%2
5710 agf\t%0,%2"
5711 [(set_attr "op_type" "RRE,RXY")
5712 (set_attr "z196prop" "z196_cracked,z196_cracked")])
5713
5714 (define_insn "*adddi3_zero_cc"
5715 [(set (reg CC_REGNUM)
5716 (compare (plus:DI (zero_extend:DI (match_operand:SI 2 "general_operand" "d,T"))
5717 (match_operand:DI 1 "register_operand" "0,0"))
5718 (const_int 0)))
5719 (set (match_operand:DI 0 "register_operand" "=d,d")
5720 (plus:DI (zero_extend:DI (match_dup 2)) (match_dup 1)))]
5721 "s390_match_ccmode (insn, CCLmode) && TARGET_ZARCH"
5722 "@
5723 algfr\t%0,%2
5724 algf\t%0,%2"
5725 [(set_attr "op_type" "RRE,RXY")
5726 (set_attr "z10prop" "z10_super_E1,z10_super_E1")])
5727
5728 (define_insn "*adddi3_zero_cconly"
5729 [(set (reg CC_REGNUM)
5730 (compare (plus:DI (zero_extend:DI (match_operand:SI 2 "general_operand" "d,T"))
5731 (match_operand:DI 1 "register_operand" "0,0"))
5732 (const_int 0)))
5733 (clobber (match_scratch:DI 0 "=d,d"))]
5734 "s390_match_ccmode (insn, CCLmode) && TARGET_ZARCH"
5735 "@
5736 algfr\t%0,%2
5737 algf\t%0,%2"
5738 [(set_attr "op_type" "RRE,RXY")
5739 (set_attr "z10prop" "z10_super_E1,z10_super_E1")])
5740
5741 (define_insn "*adddi3_zero"
5742 [(set (match_operand:DI 0 "register_operand" "=d,d")
5743 (plus:DI (zero_extend:DI (match_operand:SI 2 "general_operand" "d,T"))
5744 (match_operand:DI 1 "register_operand" "0,0")))
5745 (clobber (reg:CC CC_REGNUM))]
5746 "TARGET_ZARCH"
5747 "@
5748 algfr\t%0,%2
5749 algf\t%0,%2"
5750 [(set_attr "op_type" "RRE,RXY")
5751 (set_attr "z10prop" "z10_super_E1,z10_super_E1")])
5752
5753 (define_insn_and_split "*adddi3_31z"
5754 [(set (match_operand:DI 0 "nonimmediate_operand" "=&d")
5755 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
5756 (match_operand:DI 2 "general_operand" "do") ) )
5757 (clobber (reg:CC CC_REGNUM))]
5758 "!TARGET_ZARCH"
5759 "#"
5760 "&& reload_completed"
5761 [(parallel
5762 [(set (reg:CCL1 CC_REGNUM)
5763 (compare:CCL1 (plus:SI (match_dup 7) (match_dup 8))
5764 (match_dup 7)))
5765 (set (match_dup 6) (plus:SI (match_dup 7) (match_dup 8)))])
5766 (parallel
5767 [(set (match_dup 3) (plus:SI
5768 (plus:SI (ltu:SI (reg:CCL1 CC_REGNUM) (const_int 0))
5769 (match_dup 4)) (match_dup 5)))
5770 (clobber (reg:CC CC_REGNUM))])]
5771 "operands[3] = operand_subword (operands[0], 0, 0, DImode);
5772 operands[4] = operand_subword (operands[1], 0, 0, DImode);
5773 operands[5] = operand_subword (operands[2], 0, 0, DImode);
5774 operands[6] = operand_subword (operands[0], 1, 0, DImode);
5775 operands[7] = operand_subword (operands[1], 1, 0, DImode);
5776 operands[8] = operand_subword (operands[2], 1, 0, DImode);")
5777
5778 ;
5779 ; addsi3 instruction pattern(s).
5780 ;
5781
5782 (define_expand "addsi3"
5783 [(parallel
5784 [(set (match_operand:SI 0 "nonimmediate_operand" "")
5785 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "")
5786 (match_operand:SI 2 "general_operand" "")))
5787 (clobber (reg:CC CC_REGNUM))])]
5788 ""
5789 "")
5790
5791 (define_insn "*addsi3_sign"
5792 [(set (match_operand:SI 0 "register_operand" "=d,d")
5793 (plus:SI (sign_extend:SI (match_operand:HI 2 "memory_operand" "R,T"))
5794 (match_operand:SI 1 "register_operand" "0,0")))
5795 (clobber (reg:CC CC_REGNUM))]
5796 ""
5797 "@
5798 ah\t%0,%2
5799 ahy\t%0,%2"
5800 [(set_attr "op_type" "RX,RXY")
5801 (set_attr "cpu_facility" "*,longdisp")
5802 (set_attr "z196prop" "z196_cracked,z196_cracked")])
5803
5804 ;
5805 ; add(di|si)3 instruction pattern(s).
5806 ;
5807
5808 ; ark, agrk, ar, ahi, ahik, aghik, alfi, slfi, a, ay, agr, aghi, algfi, slgfi, ag, asi, agsi
5809 (define_insn "*add<mode>3"
5810 [(set (match_operand:GPR 0 "nonimmediate_operand" "=d,d,d,d, d, d,d,d,S")
5811 (plus:GPR (match_operand:GPR 1 "nonimmediate_operand" "%0,d,0,d, 0, 0,0,0,0")
5812 (match_operand:GPR 2 "general_operand" " d,d,K,K,Op,On,R,T,C") ) )
5813 (clobber (reg:CC CC_REGNUM))]
5814 ""
5815 "@
5816 a<g>r\t%0,%2
5817 a<g>rk\t%0,%1,%2
5818 a<g>hi\t%0,%h2
5819 a<g>hik\t%0,%1,%h2
5820 al<g>fi\t%0,%2
5821 sl<g>fi\t%0,%n2
5822 a<g>\t%0,%2
5823 a<y>\t%0,%2
5824 a<g>si\t%0,%c2"
5825 [(set_attr "op_type" "RR<E>,RRF,RI,RIE,RIL,RIL,RX<Y>,RXY,SIY")
5826 (set_attr "cpu_facility" "*,z196,*,z196,extimm,extimm,*,longdisp,z10")
5827 (set_attr "z10prop" "z10_super_E1,*,z10_super_E1,*,z10_super_E1,z10_super_E1,
5828 z10_super_E1,z10_super_E1,z10_super_E1")])
5829
5830 ; alr, alfi, slfi, al, aly, alrk, alhsik, algr, algfi, slgfi, alg, alsi, algsi, algrk, alghsik
5831 (define_insn "*add<mode>3_carry1_cc"
5832 [(set (reg CC_REGNUM)
5833 (compare (plus:GPR (match_operand:GPR 1 "nonimmediate_operand" "%0,d, 0, 0,d,0,0,0")
5834 (match_operand:GPR 2 "general_operand" " d,d,Op,On,K,R,T,C"))
5835 (match_dup 1)))
5836 (set (match_operand:GPR 0 "nonimmediate_operand" "=d,d, d, d,d,d,d,d")
5837 (plus:GPR (match_dup 1) (match_dup 2)))]
5838 "s390_match_ccmode (insn, CCL1mode)"
5839 "@
5840 al<g>r\t%0,%2
5841 al<g>rk\t%0,%1,%2
5842 al<g>fi\t%0,%2
5843 sl<g>fi\t%0,%n2
5844 al<g>hsik\t%0,%1,%h2
5845 al<g>\t%0,%2
5846 al<y>\t%0,%2
5847 al<g>si\t%0,%c2"
5848 [(set_attr "op_type" "RR<E>,RRF,RIL,RIL,RIE,RX<Y>,RXY,SIY")
5849 (set_attr "cpu_facility" "*,z196,extimm,extimm,z196,*,longdisp,z10")
5850 (set_attr "z10prop" "z10_super_E1,*,z10_super_E1,z10_super_E1,*,
5851 z10_super_E1,z10_super_E1,z10_super_E1")])
5852
5853 ; alr, al, aly, algr, alg, alrk, algrk
5854 (define_insn "*add<mode>3_carry1_cconly"
5855 [(set (reg CC_REGNUM)
5856 (compare (plus:GPR (match_operand:GPR 1 "nonimmediate_operand" "%0,d,0,0")
5857 (match_operand:GPR 2 "general_operand" "d,d,R,T"))
5858 (match_dup 1)))
5859 (clobber (match_scratch:GPR 0 "=d,d,d,d"))]
5860 "s390_match_ccmode (insn, CCL1mode)"
5861 "@
5862 al<g>r\t%0,%2
5863 al<g>rk\t%0,%1,%2
5864 al<g>\t%0,%2
5865 al<y>\t%0,%2"
5866 [(set_attr "op_type" "RR<E>,RRF,RX<Y>,RXY")
5867 (set_attr "cpu_facility" "*,z196,*,longdisp")
5868 (set_attr "z10prop" "z10_super_E1,*,z10_super_E1,z10_super_E1")])
5869
5870 ; alr, alfi, slfi, al, aly, algr, algfi, slgfi, alg, alsi, algsi, alrk, algrk, alhsik, alghsik
5871 (define_insn "*add<mode>3_carry2_cc"
5872 [(set (reg CC_REGNUM)
5873 (compare (plus:GPR (match_operand:GPR 1 "nonimmediate_operand" "%0,d, 0, 0,d,0,0,0")
5874 (match_operand:GPR 2 "general_operand" " d,d,Op,On,K,R,T,C"))
5875 (match_dup 2)))
5876 (set (match_operand:GPR 0 "nonimmediate_operand" "=d,d, d, d,d,d,d,S")
5877 (plus:GPR (match_dup 1) (match_dup 2)))]
5878 "s390_match_ccmode (insn, CCL1mode)"
5879 "@
5880 al<g>r\t%0,%2
5881 al<g>rk\t%0,%1,%2
5882 al<g>fi\t%0,%2
5883 sl<g>fi\t%0,%n2
5884 al<g>hsik\t%0,%1,%h2
5885 al<g>\t%0,%2
5886 al<y>\t%0,%2
5887 al<g>si\t%0,%c2"
5888 [(set_attr "op_type" "RR<E>,RRF,RIL,RIL,RIE,RX<Y>,RXY,SIY")
5889 (set_attr "cpu_facility" "*,z196,extimm,extimm,z196,*,longdisp,z10")
5890 (set_attr "z10prop" "z10_super_E1,*,z10_super_E1,z10_super_E1,*,
5891 z10_super_E1,z10_super_E1,z10_super_E1")])
5892
5893 ; alr, al, aly, algr, alg, alrk, algrk
5894 (define_insn "*add<mode>3_carry2_cconly"
5895 [(set (reg CC_REGNUM)
5896 (compare (plus:GPR (match_operand:GPR 1 "nonimmediate_operand" "%0,d,0,0")
5897 (match_operand:GPR 2 "general_operand" "d,d,R,T"))
5898 (match_dup 2)))
5899 (clobber (match_scratch:GPR 0 "=d,d,d,d"))]
5900 "s390_match_ccmode (insn, CCL1mode)"
5901 "@
5902 al<g>r\t%0,%2
5903 al<g>rk\t%0,%1,%2
5904 al<g>\t%0,%2
5905 al<y>\t%0,%2"
5906 [(set_attr "op_type" "RR<E>,RRF,RX<Y>,RXY")
5907 (set_attr "cpu_facility" "*,z196,*,longdisp")
5908 (set_attr "z10prop" "z10_super_E1,*,z10_super_E1,z10_super_E1")])
5909
5910 ; alr, alfi, slfi, al, aly, algr, algfi, slgfi, alg, alsi, algsi, alrk, algrk, alhsik, alghsik
5911 (define_insn "*add<mode>3_cc"
5912 [(set (reg CC_REGNUM)
5913 (compare (plus:GPR (match_operand:GPR 1 "nonimmediate_operand" "%0,d, 0, 0,d,0,0,0")
5914 (match_operand:GPR 2 "general_operand" " d,d,Op,On,K,R,T,C"))
5915 (const_int 0)))
5916 (set (match_operand:GPR 0 "nonimmediate_operand" "=d,d, d, d,d,d,d,S")
5917 (plus:GPR (match_dup 1) (match_dup 2)))]
5918 "s390_match_ccmode (insn, CCLmode)"
5919 "@
5920 al<g>r\t%0,%2
5921 al<g>rk\t%0,%1,%2
5922 al<g>fi\t%0,%2
5923 sl<g>fi\t%0,%n2
5924 al<g>hsik\t%0,%1,%h2
5925 al<g>\t%0,%2
5926 al<y>\t%0,%2
5927 al<g>si\t%0,%c2"
5928 [(set_attr "op_type" "RR<E>,RRF,RIL,RIL,RIE,RX<Y>,RXY,SIY")
5929 (set_attr "cpu_facility" "*,z196,extimm,extimm,z196,*,longdisp,z10")
5930 (set_attr "z10prop" "z10_super_E1,*,z10_super_E1,z10_super_E1,
5931 *,z10_super_E1,z10_super_E1,z10_super_E1")])
5932
5933 ; alr, al, aly, algr, alg, alrk, algrk
5934 (define_insn "*add<mode>3_cconly"
5935 [(set (reg CC_REGNUM)
5936 (compare (plus:GPR (match_operand:GPR 1 "nonimmediate_operand" "%0,d,0,0")
5937 (match_operand:GPR 2 "general_operand" "d,d,R,T"))
5938 (const_int 0)))
5939 (clobber (match_scratch:GPR 0 "=d,d,d,d"))]
5940 "s390_match_ccmode (insn, CCLmode)"
5941 "@
5942 al<g>r\t%0,%2
5943 al<g>rk\t%0,%1,%2
5944 al<g>\t%0,%2
5945 al<y>\t%0,%2"
5946 [(set_attr "op_type" "RR<E>,RRF,RX<Y>,RXY")
5947 (set_attr "cpu_facility" "*,z196,*,longdisp")
5948 (set_attr "z10prop" "z10_super_E1,*,z10_super_E1,z10_super_E1")])
5949
5950 ; alr, al, aly, algr, alg, alrk, algrk
5951 (define_insn "*add<mode>3_cconly2"
5952 [(set (reg CC_REGNUM)
5953 (compare (match_operand:GPR 1 "nonimmediate_operand" "%0,d,0,0")
5954 (neg:GPR (match_operand:GPR 2 "general_operand" "d,d,R,T"))))
5955 (clobber (match_scratch:GPR 0 "=d,d,d,d"))]
5956 "s390_match_ccmode(insn, CCLmode)"
5957 "@
5958 al<g>r\t%0,%2
5959 al<g>rk\t%0,%1,%2
5960 al<g>\t%0,%2
5961 al<y>\t%0,%2"
5962 [(set_attr "op_type" "RR<E>,RRF,RX<Y>,RXY")
5963 (set_attr "cpu_facility" "*,z196,*,longdisp")
5964 (set_attr "z10prop" "z10_super_E1,*,z10_super_E1,z10_super_E1")])
5965
5966 ; ahi, afi, aghi, agfi, asi, agsi
5967 (define_insn "*add<mode>3_imm_cc"
5968 [(set (reg CC_REGNUM)
5969 (compare (plus:GPR (match_operand:GPR 1 "nonimmediate_operand" " 0, d,0, 0")
5970 (match_operand:GPR 2 "const_int_operand" " K, K,Os,C"))
5971 (const_int 0)))
5972 (set (match_operand:GPR 0 "nonimmediate_operand" "=d, d,d, S")
5973 (plus:GPR (match_dup 1) (match_dup 2)))]
5974 "s390_match_ccmode (insn, CCAmode)
5975 && (CONST_OK_FOR_CONSTRAINT_P (INTVAL (operands[2]), 'K', \"K\")
5976 || (CONST_OK_FOR_CONSTRAINT_P (INTVAL (operands[2]), 'O', \"Os\")
5977 /* Avoid INT32_MIN on 32 bit. */
5978 && (!TARGET_ZARCH || INTVAL (operands[2]) != -0x7fffffff - 1)))"
5979 "@
5980 a<g>hi\t%0,%h2
5981 a<g>hik\t%0,%1,%h2
5982 a<g>fi\t%0,%2
5983 a<g>si\t%0,%c2"
5984 [(set_attr "op_type" "RI,RIE,RIL,SIY")
5985 (set_attr "cpu_facility" "*,z196,extimm,z10")
5986 (set_attr "z10prop" "z10_super_E1,*,z10_super_E1,z10_super_E1")])
5987
5988 (define_insn "*adddi3_sign"
5989 [(set (match_operand:DI 0 "register_operand" "=d")
5990 (plus:DI (sign_extend:DI (match_operand:HI 2 "memory_operand" "T"))
5991 (match_operand:DI 1 "register_operand" "0")))
5992 (clobber (reg:CC CC_REGNUM))]
5993 "TARGET_Z14"
5994 "agh\t%0,%2"
5995 [(set_attr "op_type" "RXY")])
5996
5997
5998 ; Jump to label OP3 if OP1 + OP2 results in a signed overflow
5999
6000 ; addv_const_operand accepts all constants which can be handled
6001 ; without reloads. These will be handled primarily by
6002 ; "*addv<mode>3_ccoverflow_const" which doesn't provide a register
6003 ; alternative. Hence we have to match the operand exactly.
6004 ; For immediates we have to avoid the SIGN_EXTEND around OP2.
6005 (define_expand "addv<mode>4"
6006 [(parallel
6007 [(set (reg:CCO CC_REGNUM)
6008 (compare:CCO (plus:<DBL>
6009 (sign_extend:<DBL> (match_operand:GPR 1 "nonimmediate_operand"))
6010 (match_dup 4))
6011 (sign_extend:<DBL> (plus:GPR (match_dup 1)
6012 (match_operand:GPR 2 "general_operand")))))
6013 (set (match_operand:GPR 0 "nonimmediate_operand")
6014 (plus:GPR (match_dup 1) (match_dup 2)))])
6015 (set (pc)
6016 (if_then_else (ne (reg:CCO CC_REGNUM) (const_int 0))
6017 (label_ref (match_operand 3))
6018 (pc)))]
6019 ""
6020 {
6021 if (CONSTANT_P (operands[2])
6022 && !addv_const_operand (operands[2], GET_MODE (operands[2])))
6023 operands[2] = force_reg (<GPR:MODE>mode, operands[2]);
6024
6025 if (GET_MODE (operands[2]) != VOIDmode)
6026 operands[4] = gen_rtx_SIGN_EXTEND (<DBL>mode, operands[2]);
6027 else
6028 /* This is what CSE does when propagating a constant into the pattern. */
6029 operands[4] = simplify_unary_operation (SIGN_EXTEND, <GPR:DBL>mode, operands[2], <GPR:MODE>mode);
6030 })
6031
6032 ; ark, agrk, ar, ahi, ahik, aghik, a, ay, agr, aghi, ag, asi, agsi
6033 (define_insn "*addv<mode>3_ccoverflow"
6034 [(set (reg CC_REGNUM)
6035 (compare (plus:<DBL>
6036 (sign_extend:<DBL> (match_operand:GPR 1 "nonimmediate_operand" "%0,d,0,d,0,0,0"))
6037 (sign_extend:<DBL> (match_operand:GPR 2 "general_operand" " d,d,K,K,R,T,C")))
6038 (sign_extend:<DBL> (plus:GPR (match_dup 1) (match_dup 2)))))
6039 (set (match_operand:GPR 0 "nonimmediate_operand" "=d,d,d,d,d,d,S")
6040 (plus:GPR (match_dup 1) (match_dup 2)))]
6041 "s390_match_ccmode (insn, CCOmode)"
6042 "@
6043 a<g>r\t%0,%2
6044 a<g>rk\t%0,%1,%2
6045 a<g>hi\t%0,%h2
6046 a<g>hik\t%0,%1,%h2
6047 a<g>\t%0,%2
6048 a<y>\t%0,%2
6049 a<g>si\t%0,%c2"
6050 [(set_attr "op_type" "RR<E>,RRF,RI,RIE,RX<Y>,RXY,SIY")
6051 (set_attr "cpu_facility" "*,z196,*,z196,*,longdisp,z10")
6052 (set_attr "z10prop" "z10_super_E1,*,z10_super_E1,*,
6053 z10_super_E1,z10_super_E1,z10_super_E1")])
6054
6055 ; ahi, aghi, ahik, aghik, asi, agsi
6056 (define_insn "*addv<mode>3_ccoverflow_const"
6057 [(set (reg CC_REGNUM)
6058 (compare (plus:<DBL>
6059 (sign_extend:<DBL> (match_operand:GPR 1 "nonimmediate_operand" "%0,d,0"))
6060 (match_operand:<DBL> 2 "addv_const_operand" "K,K,C"))
6061 (sign_extend:<DBL> (plus:GPR (match_dup 1) (match_dup 2)))))
6062 (set (match_operand:GPR 0 "nonimmediate_operand" "=d,d,S")
6063 (plus:GPR (match_dup 1) (match_dup 2)))]
6064 "s390_match_ccmode (insn, CCOmode)"
6065 "@
6066 a<g>hi\t%0,%h2
6067 a<g>hik\t%0,%1,%h2
6068 a<g>si\t%0,%c2"
6069 [(set_attr "op_type" "RI,RIE,SIY")
6070 (set_attr "cpu_facility" "*,z196,z10")
6071 (set_attr "z10prop" "z10_super_E1,*,z10_super_E1")])
6072
6073
6074 ;
6075 ; add(tf|df|sf|td|dd)3 instruction pattern(s).
6076 ;
6077
6078 ; axbr, adbr, aebr, axb, adb, aeb, adtr, axtr
6079 ; FIXME: wfadb does not clobber cc
6080 (define_insn "add<mode>3"
6081 [(set (match_operand:FP 0 "register_operand" "=f,f,f,v,v")
6082 (plus:FP (match_operand:FP 1 "nonimmediate_operand" "%f,0,0,v,v")
6083 (match_operand:FP 2 "general_operand" "f,f,R,v,v")))
6084 (clobber (reg:CC CC_REGNUM))]
6085 "TARGET_HARD_FLOAT"
6086 "@
6087 a<xde>tr\t%0,%1,%2
6088 a<xde>br\t%0,%2
6089 a<xde>b\t%0,%2
6090 wfadb\t%v0,%v1,%v2
6091 wfasb\t%v0,%v1,%v2"
6092 [(set_attr "op_type" "RRF,RRE,RXE,VRR,VRR")
6093 (set_attr "type" "fsimp<mode>")
6094 (set_attr "cpu_facility" "*,*,*,vx,vxe")
6095 (set_attr "enabled" "<nBFP>,<nDFP>,<DSF>,<DF>,<SF>")])
6096
6097 ; axbr, adbr, aebr, axb, adb, aeb, adtr, axtr
6098 (define_insn "*add<mode>3_cc"
6099 [(set (reg CC_REGNUM)
6100 (compare (plus:FP (match_operand:FP 1 "nonimmediate_operand" "%f,0,0")
6101 (match_operand:FP 2 "general_operand" "f,f,R"))
6102 (match_operand:FP 3 "const0_operand" "")))
6103 (set (match_operand:FP 0 "register_operand" "=f,f,f")
6104 (plus:FP (match_dup 1) (match_dup 2)))]
6105 "s390_match_ccmode (insn, CCSmode) && TARGET_HARD_FLOAT"
6106 "@
6107 a<xde>tr\t%0,%1,%2
6108 a<xde>br\t%0,%2
6109 a<xde>b\t%0,%2"
6110 [(set_attr "op_type" "RRF,RRE,RXE")
6111 (set_attr "type" "fsimp<mode>")
6112 (set_attr "enabled" "<nBFP>,<nDFP>,<DSF>")])
6113
6114 ; axbr, adbr, aebr, axb, adb, aeb, adtr, axtr
6115 (define_insn "*add<mode>3_cconly"
6116 [(set (reg CC_REGNUM)
6117 (compare (plus:FP (match_operand:FP 1 "nonimmediate_operand" "%f,0,0")
6118 (match_operand:FP 2 "general_operand" "f,f,R"))
6119 (match_operand:FP 3 "const0_operand" "")))
6120 (clobber (match_scratch:FP 0 "=f,f,f"))]
6121 "s390_match_ccmode (insn, CCSmode) && TARGET_HARD_FLOAT"
6122 "@
6123 a<xde>tr\t%0,%1,%2
6124 a<xde>br\t%0,%2
6125 a<xde>b\t%0,%2"
6126 [(set_attr "op_type" "RRF,RRE,RXE")
6127 (set_attr "type" "fsimp<mode>")
6128 (set_attr "enabled" "<nBFP>,<nDFP>,<DSF>")])
6129
6130 ;
6131 ; Pointer add instruction patterns
6132 ;
6133
6134 ; This will match "*la_64"
6135 (define_expand "addptrdi3"
6136 [(set (match_operand:DI 0 "register_operand" "")
6137 (plus:DI (match_operand:DI 1 "register_operand" "")
6138 (match_operand:DI 2 "nonmemory_operand" "")))]
6139 "TARGET_64BIT"
6140 {
6141 if (GET_CODE (operands[2]) == CONST_INT)
6142 {
6143 HOST_WIDE_INT c = INTVAL (operands[2]);
6144
6145 if (!CONST_OK_FOR_CONSTRAINT_P (c, 'K', "K")
6146 && !CONST_OK_FOR_CONSTRAINT_P (c, 'O', "Os"))
6147 {
6148 operands[2] = force_const_mem (DImode, operands[2]);
6149 operands[2] = force_reg (DImode, operands[2]);
6150 }
6151 else if (!DISP_IN_RANGE (INTVAL (operands[2])))
6152 operands[2] = force_reg (DImode, operands[2]);
6153 }
6154 })
6155
6156 ; For 31 bit we have to prevent the generated pattern from matching
6157 ; normal ADDs since la only does a 31 bit add. This is supposed to
6158 ; match "force_la_31".
6159 (define_expand "addptrsi3"
6160 [(parallel
6161 [(set (match_operand:SI 0 "register_operand" "")
6162 (plus:SI (match_operand:SI 1 "register_operand" "")
6163 (match_operand:SI 2 "nonmemory_operand" "")))
6164 (use (const_int 0))])]
6165 "!TARGET_64BIT"
6166 {
6167 if (GET_CODE (operands[2]) == CONST_INT)
6168 {
6169 HOST_WIDE_INT c = INTVAL (operands[2]);
6170
6171 if (!CONST_OK_FOR_CONSTRAINT_P (c, 'K', "K")
6172 && !CONST_OK_FOR_CONSTRAINT_P (c, 'O', "Os"))
6173 {
6174 operands[2] = force_const_mem (SImode, operands[2]);
6175 operands[2] = force_reg (SImode, operands[2]);
6176 }
6177 else if (!DISP_IN_RANGE (INTVAL (operands[2])))
6178 operands[2] = force_reg (SImode, operands[2]);
6179 }
6180 })
6181
6182 ;;
6183 ;;- Subtract instructions.
6184 ;;
6185
6186 ;
6187 ; subti3 instruction pattern(s).
6188 ;
6189
6190 (define_expand "subti3"
6191 [(parallel
6192 [(set (match_operand:TI 0 "register_operand" "")
6193 (minus:TI (match_operand:TI 1 "register_operand" "")
6194 (match_operand:TI 2 "general_operand" "") ) )
6195 (clobber (reg:CC CC_REGNUM))])]
6196 "TARGET_ZARCH"
6197 {
6198 /* For z13 we have vsq which doesn't set CC. */
6199 if (TARGET_VX)
6200 {
6201 emit_insn (gen_rtx_SET (operands[0],
6202 gen_rtx_MINUS (TImode,
6203 operands[1],
6204 copy_to_mode_reg (TImode, operands[2]))));
6205 DONE;
6206 }
6207 })
6208
6209 (define_insn_and_split "*subti3"
6210 [(set (match_operand:TI 0 "register_operand" "=&d")
6211 (minus:TI (match_operand:TI 1 "register_operand" "0")
6212 (match_operand:TI 2 "general_operand" "do") ) )
6213 (clobber (reg:CC CC_REGNUM))]
6214 "TARGET_ZARCH"
6215 "#"
6216 "&& reload_completed"
6217 [(parallel
6218 [(set (reg:CCL2 CC_REGNUM)
6219 (compare:CCL2 (minus:DI (match_dup 7) (match_dup 8))
6220 (match_dup 7)))
6221 (set (match_dup 6) (minus:DI (match_dup 7) (match_dup 8)))])
6222 (parallel
6223 [(set (match_dup 3) (minus:DI (minus:DI (match_dup 4) (match_dup 5))
6224 (gtu:DI (reg:CCL2 CC_REGNUM) (const_int 0))))
6225 (clobber (reg:CC CC_REGNUM))])]
6226 "operands[3] = operand_subword (operands[0], 0, 0, TImode);
6227 operands[4] = operand_subword (operands[1], 0, 0, TImode);
6228 operands[5] = operand_subword (operands[2], 0, 0, TImode);
6229 operands[6] = operand_subword (operands[0], 1, 0, TImode);
6230 operands[7] = operand_subword (operands[1], 1, 0, TImode);
6231 operands[8] = operand_subword (operands[2], 1, 0, TImode);"
6232 [(set_attr "op_type" "*")
6233 (set_attr "cpu_facility" "*")])
6234
6235 ;
6236 ; subdi3 instruction pattern(s).
6237 ;
6238
6239 (define_expand "subdi3"
6240 [(parallel
6241 [(set (match_operand:DI 0 "register_operand" "")
6242 (minus:DI (match_operand:DI 1 "register_operand" "")
6243 (match_operand:DI 2 "general_operand" "")))
6244 (clobber (reg:CC CC_REGNUM))])]
6245 ""
6246 "")
6247
6248 (define_insn "*subdi3_sign"
6249 [(set (match_operand:DI 0 "register_operand" "=d,d")
6250 (minus:DI (match_operand:DI 1 "register_operand" "0,0")
6251 (sign_extend:DI (match_operand:SI 2 "general_operand" "d,T"))))
6252 (clobber (reg:CC CC_REGNUM))]
6253 "TARGET_ZARCH"
6254 "@
6255 sgfr\t%0,%2
6256 sgf\t%0,%2"
6257 [(set_attr "op_type" "RRE,RXY")
6258 (set_attr "z10prop" "z10_c,*")
6259 (set_attr "z196prop" "z196_cracked")])
6260
6261 (define_insn "*subdi3_zero_cc"
6262 [(set (reg CC_REGNUM)
6263 (compare (minus:DI (match_operand:DI 1 "register_operand" "0,0")
6264 (zero_extend:DI (match_operand:SI 2 "general_operand" "d,T")))
6265 (const_int 0)))
6266 (set (match_operand:DI 0 "register_operand" "=d,d")
6267 (minus:DI (match_dup 1) (zero_extend:DI (match_dup 2))))]
6268 "s390_match_ccmode (insn, CCLmode) && TARGET_ZARCH"
6269 "@
6270 slgfr\t%0,%2
6271 slgf\t%0,%2"
6272 [(set_attr "op_type" "RRE,RXY")
6273 (set_attr "z10prop" "z10_super_c_E1,z10_super_E1")])
6274
6275 (define_insn "*subdi3_zero_cconly"
6276 [(set (reg CC_REGNUM)
6277 (compare (minus:DI (match_operand:DI 1 "register_operand" "0,0")
6278 (zero_extend:DI (match_operand:SI 2 "general_operand" "d,T")))
6279 (const_int 0)))
6280 (clobber (match_scratch:DI 0 "=d,d"))]
6281 "s390_match_ccmode (insn, CCLmode) && TARGET_ZARCH"
6282 "@
6283 slgfr\t%0,%2
6284 slgf\t%0,%2"
6285 [(set_attr "op_type" "RRE,RXY")
6286 (set_attr "z10prop" "z10_super_c_E1,z10_super_E1")])
6287
6288 (define_insn "*subdi3_zero"
6289 [(set (match_operand:DI 0 "register_operand" "=d,d")
6290 (minus:DI (match_operand:DI 1 "register_operand" "0,0")
6291 (zero_extend:DI (match_operand:SI 2 "general_operand" "d,T"))))
6292 (clobber (reg:CC CC_REGNUM))]
6293 "TARGET_ZARCH"
6294 "@
6295 slgfr\t%0,%2
6296 slgf\t%0,%2"
6297 [(set_attr "op_type" "RRE,RXY")
6298 (set_attr "z10prop" "z10_super_c_E1,z10_super_E1")])
6299
6300 (define_insn_and_split "*subdi3_31z"
6301 [(set (match_operand:DI 0 "register_operand" "=&d")
6302 (minus:DI (match_operand:DI 1 "register_operand" "0")
6303 (match_operand:DI 2 "general_operand" "do") ) )
6304 (clobber (reg:CC CC_REGNUM))]
6305 "!TARGET_ZARCH"
6306 "#"
6307 "&& reload_completed"
6308 [(parallel
6309 [(set (reg:CCL2 CC_REGNUM)
6310 (compare:CCL2 (minus:SI (match_dup 7) (match_dup 8))
6311 (match_dup 7)))
6312 (set (match_dup 6) (minus:SI (match_dup 7) (match_dup 8)))])
6313 (parallel
6314 [(set (match_dup 3) (minus:SI (minus:SI (match_dup 4) (match_dup 5))
6315 (gtu:SI (reg:CCL2 CC_REGNUM) (const_int 0))))
6316 (clobber (reg:CC CC_REGNUM))])]
6317 "operands[3] = operand_subword (operands[0], 0, 0, DImode);
6318 operands[4] = operand_subword (operands[1], 0, 0, DImode);
6319 operands[5] = operand_subword (operands[2], 0, 0, DImode);
6320 operands[6] = operand_subword (operands[0], 1, 0, DImode);
6321 operands[7] = operand_subword (operands[1], 1, 0, DImode);
6322 operands[8] = operand_subword (operands[2], 1, 0, DImode);")
6323
6324 ;
6325 ; subsi3 instruction pattern(s).
6326 ;
6327
6328 (define_expand "subsi3"
6329 [(parallel
6330 [(set (match_operand:SI 0 "register_operand" "")
6331 (minus:SI (match_operand:SI 1 "register_operand" "")
6332 (match_operand:SI 2 "general_operand" "")))
6333 (clobber (reg:CC CC_REGNUM))])]
6334 ""
6335 "")
6336
6337 (define_insn "*subsi3_sign"
6338 [(set (match_operand:SI 0 "register_operand" "=d,d")
6339 (minus:SI (match_operand:SI 1 "register_operand" "0,0")
6340 (sign_extend:SI (match_operand:HI 2 "memory_operand" "R,T"))))
6341 (clobber (reg:CC CC_REGNUM))]
6342 ""
6343 "@
6344 sh\t%0,%2
6345 shy\t%0,%2"
6346 [(set_attr "op_type" "RX,RXY")
6347 (set_attr "cpu_facility" "*,longdisp")
6348 (set_attr "z196prop" "z196_cracked,z196_cracked")])
6349
6350 ;
6351 ; sub(di|si)3 instruction pattern(s).
6352 ;
6353
6354 ; sr, s, sy, sgr, sg, srk, sgrk
6355 (define_insn "*sub<mode>3"
6356 [(set (match_operand:GPR 0 "register_operand" "=d,d,d,d")
6357 (minus:GPR (match_operand:GPR 1 "register_operand" "0,d,0,0")
6358 (match_operand:GPR 2 "general_operand" "d,d,R,T") ) )
6359 (clobber (reg:CC CC_REGNUM))]
6360 ""
6361 "@
6362 s<g>r\t%0,%2
6363 s<g>rk\t%0,%1,%2
6364 s<g>\t%0,%2
6365 s<y>\t%0,%2"
6366 [(set_attr "op_type" "RR<E>,RRF,RX<Y>,RXY")
6367 (set_attr "cpu_facility" "*,z196,*,longdisp")
6368 (set_attr "z10prop" "z10_super_c_E1,*,z10_super_E1,z10_super_E1")])
6369
6370 ; slr, sl, sly, slgr, slg, slrk, slgrk
6371 (define_insn "*sub<mode>3_borrow_cc"
6372 [(set (reg CC_REGNUM)
6373 (compare (minus:GPR (match_operand:GPR 1 "register_operand" "0,d,0,0")
6374 (match_operand:GPR 2 "general_operand" "d,d,R,T"))
6375 (match_dup 1)))
6376 (set (match_operand:GPR 0 "register_operand" "=d,d,d,d")
6377 (minus:GPR (match_dup 1) (match_dup 2)))]
6378 "s390_match_ccmode (insn, CCL2mode)"
6379 "@
6380 sl<g>r\t%0,%2
6381 sl<g>rk\t%0,%1,%2
6382 sl<g>\t%0,%2
6383 sl<y>\t%0,%2"
6384 [(set_attr "op_type" "RR<E>,RRF,RX<Y>,RXY")
6385 (set_attr "cpu_facility" "*,z196,*,longdisp")
6386 (set_attr "z10prop" "z10_super_c_E1,*,z10_super_E1,z10_super_E1")])
6387
6388 ; slr, sl, sly, slgr, slg, slrk, slgrk
6389 (define_insn "*sub<mode>3_borrow_cconly"
6390 [(set (reg CC_REGNUM)
6391 (compare (minus:GPR (match_operand:GPR 1 "register_operand" "0,d,0,0")
6392 (match_operand:GPR 2 "general_operand" "d,d,R,T"))
6393 (match_dup 1)))
6394 (clobber (match_scratch:GPR 0 "=d,d,d,d"))]
6395 "s390_match_ccmode (insn, CCL2mode)"
6396 "@
6397 sl<g>r\t%0,%2
6398 sl<g>rk\t%0,%1,%2
6399 sl<g>\t%0,%2
6400 sl<y>\t%0,%2"
6401 [(set_attr "op_type" "RR<E>,RRF,RX<Y>,RXY")
6402 (set_attr "cpu_facility" "*,z196,*,longdisp")
6403 (set_attr "z10prop" "z10_super_c_E1,*,z10_super_E1,z10_super_E1")])
6404
6405 ; slr, sl, sly, slgr, slg, slrk, slgrk
6406 (define_insn "*sub<mode>3_cc"
6407 [(set (reg CC_REGNUM)
6408 (compare (minus:GPR (match_operand:GPR 1 "register_operand" "0,d,0,0")
6409 (match_operand:GPR 2 "general_operand" "d,d,R,T"))
6410 (const_int 0)))
6411 (set (match_operand:GPR 0 "register_operand" "=d,d,d,d")
6412 (minus:GPR (match_dup 1) (match_dup 2)))]
6413 "s390_match_ccmode (insn, CCLmode)"
6414 "@
6415 sl<g>r\t%0,%2
6416 sl<g>rk\t%0,%1,%2
6417 sl<g>\t%0,%2
6418 sl<y>\t%0,%2"
6419 [(set_attr "op_type" "RR<E>,RRF,RX<Y>,RXY")
6420 (set_attr "cpu_facility" "*,z196,*,longdisp")
6421 (set_attr "z10prop" "z10_super_c_E1,*,z10_super_E1,z10_super_E1")])
6422
6423 ; slr, sl, sly, slgr, slg, slrk, slgrk
6424 (define_insn "*sub<mode>3_cc2"
6425 [(set (reg CC_REGNUM)
6426 (compare (match_operand:GPR 1 "register_operand" "0,d,0,0")
6427 (match_operand:GPR 2 "general_operand" "d,d,R,T")))
6428 (set (match_operand:GPR 0 "register_operand" "=d,d,d,d")
6429 (minus:GPR (match_dup 1) (match_dup 2)))]
6430 "s390_match_ccmode (insn, CCL3mode)"
6431 "@
6432 sl<g>r\t%0,%2
6433 sl<g>rk\t%0,%1,%2
6434 sl<g>\t%0,%2
6435 sl<y>\t%0,%2"
6436 [(set_attr "op_type" "RR<E>,RRF,RX<Y>,RXY")
6437 (set_attr "cpu_facility" "*,z196,*,longdisp")
6438 (set_attr "z10prop" "z10_super_c_E1,*,z10_super_E1,z10_super_E1")])
6439
6440 ; slr, sl, sly, slgr, slg, slrk, slgrk
6441 (define_insn "*sub<mode>3_cconly"
6442 [(set (reg CC_REGNUM)
6443 (compare (minus:GPR (match_operand:GPR 1 "register_operand" "0,d,0,0")
6444 (match_operand:GPR 2 "general_operand" "d,d,R,T"))
6445 (const_int 0)))
6446 (clobber (match_scratch:GPR 0 "=d,d,d,d"))]
6447 "s390_match_ccmode (insn, CCLmode)"
6448 "@
6449 sl<g>r\t%0,%2
6450 sl<g>rk\t%0,%1,%2
6451 sl<g>\t%0,%2
6452 sl<y>\t%0,%2"
6453 [(set_attr "op_type" "RR<E>,RRF,RX<Y>,RXY")
6454 (set_attr "cpu_facility" "*,z196,*,longdisp")
6455 (set_attr "z10prop" "z10_super_c_E1,*,z10_super_E1,z10_super_E1")])
6456
6457
6458 ; slr, sl, sly, slgr, slg, slrk, slgrk
6459 (define_insn "*sub<mode>3_cconly2"
6460 [(set (reg CC_REGNUM)
6461 (compare (match_operand:GPR 1 "register_operand" "0,d,0,0")
6462 (match_operand:GPR 2 "general_operand" "d,d,R,T")))
6463 (clobber (match_scratch:GPR 0 "=d,d,d,d"))]
6464 "s390_match_ccmode (insn, CCL3mode)"
6465 "@
6466 sl<g>r\t%0,%2
6467 sl<g>rk\t%0,%1,%2
6468 sl<g>\t%0,%2
6469 sl<y>\t%0,%2"
6470 [(set_attr "op_type" "RR<E>,RRF,RX<Y>,RXY")
6471 (set_attr "cpu_facility" "*,z196,*,longdisp")
6472 (set_attr "z10prop" "z10_super_c_E1,*,z10_super_E1,z10_super_E1")])
6473
6474 (define_insn "*subdi3_sign"
6475 [(set (match_operand:DI 0 "register_operand" "=d")
6476 (minus:DI (match_operand:DI 1 "register_operand" "0")
6477 (sign_extend:DI (match_operand:HI 2 "memory_operand" "T"))))
6478 (clobber (reg:CC CC_REGNUM))]
6479 "TARGET_Z14"
6480 "sgh\t%0,%2"
6481 [(set_attr "op_type" "RXY")])
6482
6483 ; Jump to label OP3 if OP1 - OP2 results in a signed overflow
6484 (define_expand "subv<mode>4"
6485 [(parallel
6486 [(set (reg:CCO CC_REGNUM)
6487 (compare:CCO (minus:<DBL>
6488 (sign_extend:<DBL> (match_operand:GPR 1 "nonimmediate_operand"))
6489 (sign_extend:<DBL> (match_operand:GPR 2 "nonimmediate_operand")))
6490 (sign_extend:<DBL> (minus:GPR (match_dup 1) (match_dup 2)))))
6491 (set (match_operand:GPR 0 "nonimmediate_operand")
6492 (minus:GPR (match_dup 1) (match_dup 2)))])
6493 (set (pc)
6494 (if_then_else (ne (reg:CCO CC_REGNUM) (const_int 0))
6495 (label_ref (match_operand 3))
6496 (pc)))]
6497 "")
6498
6499 ; sr, s, sy, sgr, sg, srk, sgrk
6500 (define_insn "*subv<mode>3_ccoverflow"
6501 [(set (reg CC_REGNUM)
6502 (compare (minus:<DBL>
6503 (sign_extend:<DBL> (match_operand:GPR 1 "nonimmediate_operand" "0,d,0,0"))
6504 (sign_extend:<DBL> (match_operand:GPR 2 "nonimmediate_operand" "d,d,R,T")))
6505 (sign_extend:<DBL> (minus:GPR (match_dup 1) (match_dup 2)))))
6506 (set (match_operand:GPR 0 "register_operand" "=d,d,d,d")
6507 (minus:GPR (match_dup 1) (match_dup 2)))]
6508 "s390_match_ccmode (insn, CCOmode)"
6509 "@
6510 s<g>r\t%0,%2
6511 s<g>rk\t%0,%1,%2
6512 s<g>\t%0,%2
6513 s<y>\t%0,%2"
6514 [(set_attr "op_type" "RR<E>,RRF,RX<Y>,RXY")
6515 (set_attr "cpu_facility" "*,z196,*,longdisp")
6516 (set_attr "z10prop" "z10_super_c_E1,*,z10_super_E1,z10_super_E1")])
6517
6518
6519 ;
6520 ; sub(tf|df|sf|td|dd)3 instruction pattern(s).
6521 ;
6522
6523 ; FIXME: (clobber (match_scratch:CC 3 "=c,c,c,X,X")) does not work - why?
6524 ; sxbr, sdbr, sebr, sdb, seb, sxtr, sdtr
6525 (define_insn "sub<mode>3"
6526 [(set (match_operand:FP 0 "register_operand" "=f,f,f,v,v")
6527 (minus:FP (match_operand:FP 1 "register_operand" "f,0,0,v,v")
6528 (match_operand:FP 2 "general_operand" "f,f,R,v,v")))
6529 (clobber (reg:CC CC_REGNUM))]
6530 "TARGET_HARD_FLOAT"
6531 "@
6532 s<xde>tr\t%0,%1,%2
6533 s<xde>br\t%0,%2
6534 s<xde>b\t%0,%2
6535 wfsdb\t%v0,%v1,%v2
6536 wfssb\t%v0,%v1,%v2"
6537 [(set_attr "op_type" "RRF,RRE,RXE,VRR,VRR")
6538 (set_attr "type" "fsimp<mode>")
6539 (set_attr "cpu_facility" "*,*,*,vx,vxe")
6540 (set_attr "enabled" "<nBFP>,<nDFP>,<DSF>,<DF>,<SF>")])
6541
6542 ; sxbr, sdbr, sebr, sdb, seb, sxtr, sdtr
6543 (define_insn "*sub<mode>3_cc"
6544 [(set (reg CC_REGNUM)
6545 (compare (minus:FP (match_operand:FP 1 "nonimmediate_operand" "f,0,0")
6546 (match_operand:FP 2 "general_operand" "f,f,R"))
6547 (match_operand:FP 3 "const0_operand" "")))
6548 (set (match_operand:FP 0 "register_operand" "=f,f,f")
6549 (minus:FP (match_dup 1) (match_dup 2)))]
6550 "s390_match_ccmode (insn, CCSmode) && TARGET_HARD_FLOAT"
6551 "@
6552 s<xde>tr\t%0,%1,%2
6553 s<xde>br\t%0,%2
6554 s<xde>b\t%0,%2"
6555 [(set_attr "op_type" "RRF,RRE,RXE")
6556 (set_attr "type" "fsimp<mode>")
6557 (set_attr "enabled" "<nBFP>,<nDFP>,<DSF>")])
6558
6559 ; sxbr, sdbr, sebr, sdb, seb, sxtr, sdtr
6560 (define_insn "*sub<mode>3_cconly"
6561 [(set (reg CC_REGNUM)
6562 (compare (minus:FP (match_operand:FP 1 "nonimmediate_operand" "f,0,0")
6563 (match_operand:FP 2 "general_operand" "f,f,R"))
6564 (match_operand:FP 3 "const0_operand" "")))
6565 (clobber (match_scratch:FP 0 "=f,f,f"))]
6566 "s390_match_ccmode (insn, CCSmode) && TARGET_HARD_FLOAT"
6567 "@
6568 s<xde>tr\t%0,%1,%2
6569 s<xde>br\t%0,%2
6570 s<xde>b\t%0,%2"
6571 [(set_attr "op_type" "RRF,RRE,RXE")
6572 (set_attr "type" "fsimp<mode>")
6573 (set_attr "enabled" "<nBFP>,<nDFP>,<DSF>")])
6574
6575
6576 ;;
6577 ;;- Conditional add/subtract instructions.
6578 ;;
6579
6580 ;
6581 ; add(di|si)cc instruction pattern(s).
6582 ;
6583
6584 ; the following 4 patterns are used when the result of an add with
6585 ; carry is checked for an overflow condition
6586
6587 ; op1 + op2 + c < op1
6588
6589 ; alcr, alc, alcgr, alcg
6590 (define_insn "*add<mode>3_alc_carry1_cc"
6591 [(set (reg CC_REGNUM)
6592 (compare
6593 (plus:GPR (plus:GPR (match_operand:GPR 3 "s390_alc_comparison" "")
6594 (match_operand:GPR 1 "nonimmediate_operand" "%0,0"))
6595 (match_operand:GPR 2 "general_operand" "d,T"))
6596 (match_dup 1)))
6597 (set (match_operand:GPR 0 "register_operand" "=d,d")
6598 (plus:GPR (plus:GPR (match_dup 3) (match_dup 1)) (match_dup 2)))]
6599 "s390_match_ccmode (insn, CCL1mode)"
6600 "@
6601 alc<g>r\t%0,%2
6602 alc<g>\t%0,%2"
6603 [(set_attr "op_type" "RRE,RXY")
6604 (set_attr "z196prop" "z196_alone,z196_alone")])
6605
6606 ; alcr, alc, alcgr, alcg
6607 (define_insn "*add<mode>3_alc_carry1_cconly"
6608 [(set (reg CC_REGNUM)
6609 (compare
6610 (plus:GPR (plus:GPR (match_operand:GPR 3 "s390_alc_comparison" "")
6611 (match_operand:GPR 1 "nonimmediate_operand" "%0,0"))
6612 (match_operand:GPR 2 "general_operand" "d,T"))
6613 (match_dup 1)))
6614 (clobber (match_scratch:GPR 0 "=d,d"))]
6615 "s390_match_ccmode (insn, CCL1mode)"
6616 "@
6617 alc<g>r\t%0,%2
6618 alc<g>\t%0,%2"
6619 [(set_attr "op_type" "RRE,RXY")
6620 (set_attr "z196prop" "z196_alone,z196_alone")])
6621
6622 ; op1 + op2 + c < op2
6623
6624 ; alcr, alc, alcgr, alcg
6625 (define_insn "*add<mode>3_alc_carry2_cc"
6626 [(set (reg CC_REGNUM)
6627 (compare
6628 (plus:GPR (plus:GPR (match_operand:GPR 3 "s390_alc_comparison" "")
6629 (match_operand:GPR 1 "nonimmediate_operand" "%0,0"))
6630 (match_operand:GPR 2 "general_operand" "d,T"))
6631 (match_dup 2)))
6632 (set (match_operand:GPR 0 "register_operand" "=d,d")
6633 (plus:GPR (plus:GPR (match_dup 3) (match_dup 1)) (match_dup 2)))]
6634 "s390_match_ccmode (insn, CCL1mode)"
6635 "@
6636 alc<g>r\t%0,%2
6637 alc<g>\t%0,%2"
6638 [(set_attr "op_type" "RRE,RXY")])
6639
6640 ; alcr, alc, alcgr, alcg
6641 (define_insn "*add<mode>3_alc_carry2_cconly"
6642 [(set (reg CC_REGNUM)
6643 (compare
6644 (plus:GPR (plus:GPR (match_operand:GPR 3 "s390_alc_comparison" "")
6645 (match_operand:GPR 1 "nonimmediate_operand" "%0,0"))
6646 (match_operand:GPR 2 "general_operand" "d,T"))
6647 (match_dup 2)))
6648 (clobber (match_scratch:GPR 0 "=d,d"))]
6649 "s390_match_ccmode (insn, CCL1mode)"
6650 "@
6651 alc<g>r\t%0,%2
6652 alc<g>\t%0,%2"
6653 [(set_attr "op_type" "RRE,RXY")])
6654
6655 ; alcr, alc, alcgr, alcg
6656 (define_insn "*add<mode>3_alc_cc"
6657 [(set (reg CC_REGNUM)
6658 (compare
6659 (plus:GPR (plus:GPR (match_operand:GPR 3 "s390_alc_comparison" "")
6660 (match_operand:GPR 1 "nonimmediate_operand" "%0,0"))
6661 (match_operand:GPR 2 "general_operand" "d,T"))
6662 (const_int 0)))
6663 (set (match_operand:GPR 0 "register_operand" "=d,d")
6664 (plus:GPR (plus:GPR (match_dup 3) (match_dup 1)) (match_dup 2)))]
6665 "s390_match_ccmode (insn, CCLmode)"
6666 "@
6667 alc<g>r\t%0,%2
6668 alc<g>\t%0,%2"
6669 [(set_attr "op_type" "RRE,RXY")])
6670
6671 ; alcr, alc, alcgr, alcg
6672 (define_insn "*add<mode>3_alc"
6673 [(set (match_operand:GPR 0 "register_operand" "=d,d")
6674 (plus:GPR (plus:GPR (match_operand:GPR 3 "s390_alc_comparison" "")
6675 (match_operand:GPR 1 "nonimmediate_operand" "%0,0"))
6676 (match_operand:GPR 2 "general_operand" "d,T")))
6677 (clobber (reg:CC CC_REGNUM))]
6678 ""
6679 "@
6680 alc<g>r\t%0,%2
6681 alc<g>\t%0,%2"
6682 [(set_attr "op_type" "RRE,RXY")])
6683
6684 ; slbr, slb, slbgr, slbg
6685 (define_insn "*sub<mode>3_slb_cc"
6686 [(set (reg CC_REGNUM)
6687 (compare
6688 (minus:GPR (minus:GPR (match_operand:GPR 1 "nonimmediate_operand" "0,0")
6689 (match_operand:GPR 2 "general_operand" "d,T"))
6690 (match_operand:GPR 3 "s390_slb_comparison" ""))
6691 (const_int 0)))
6692 (set (match_operand:GPR 0 "register_operand" "=d,d")
6693 (minus:GPR (minus:GPR (match_dup 1) (match_dup 2)) (match_dup 3)))]
6694 "s390_match_ccmode (insn, CCLmode)"
6695 "@
6696 slb<g>r\t%0,%2
6697 slb<g>\t%0,%2"
6698 [(set_attr "op_type" "RRE,RXY")
6699 (set_attr "z10prop" "z10_c,*")])
6700
6701 ; slbr, slb, slbgr, slbg
6702 (define_insn "*sub<mode>3_slb"
6703 [(set (match_operand:GPR 0 "register_operand" "=d,d")
6704 (minus:GPR (minus:GPR (match_operand:GPR 1 "nonimmediate_operand" "0,0")
6705 (match_operand:GPR 2 "general_operand" "d,T"))
6706 (match_operand:GPR 3 "s390_slb_comparison" "")))
6707 (clobber (reg:CC CC_REGNUM))]
6708 ""
6709 "@
6710 slb<g>r\t%0,%2
6711 slb<g>\t%0,%2"
6712 [(set_attr "op_type" "RRE,RXY")
6713 (set_attr "z10prop" "z10_c,*")])
6714
6715 (define_expand "add<mode>cc"
6716 [(match_operand:GPR 0 "register_operand" "")
6717 (match_operand 1 "comparison_operator" "")
6718 (match_operand:GPR 2 "register_operand" "")
6719 (match_operand:GPR 3 "const_int_operand" "")]
6720 ""
6721 "if (!s390_expand_addcc (GET_CODE (operands[1]),
6722 XEXP (operands[1], 0), XEXP (operands[1], 1),
6723 operands[0], operands[2],
6724 operands[3])) FAIL; DONE;")
6725
6726 ;
6727 ; scond instruction pattern(s).
6728 ;
6729
6730 (define_insn_and_split "*scond<mode>"
6731 [(set (match_operand:GPR 0 "register_operand" "=&d")
6732 (match_operand:GPR 1 "s390_alc_comparison" ""))
6733 (clobber (reg:CC CC_REGNUM))]
6734 ""
6735 "#"
6736 "&& reload_completed"
6737 [(set (match_dup 0) (const_int 0))
6738 (parallel
6739 [(set (match_dup 0) (plus:GPR (plus:GPR (match_dup 1) (match_dup 0))
6740 (match_dup 0)))
6741 (clobber (reg:CC CC_REGNUM))])]
6742 "")
6743
6744 (define_insn_and_split "*scond<mode>_neg"
6745 [(set (match_operand:GPR 0 "register_operand" "=&d")
6746 (match_operand:GPR 1 "s390_slb_comparison" ""))
6747 (clobber (reg:CC CC_REGNUM))]
6748 ""
6749 "#"
6750 "&& reload_completed"
6751 [(set (match_dup 0) (const_int 0))
6752 (parallel
6753 [(set (match_dup 0) (minus:GPR (minus:GPR (match_dup 0) (match_dup 0))
6754 (match_dup 1)))
6755 (clobber (reg:CC CC_REGNUM))])
6756 (parallel
6757 [(set (match_dup 0) (neg:GPR (match_dup 0)))
6758 (clobber (reg:CC CC_REGNUM))])]
6759 "")
6760
6761
6762 (define_expand "cstore<mode>4"
6763 [(set (match_operand:SI 0 "register_operand" "")
6764 (match_operator:SI 1 "s390_scond_operator"
6765 [(match_operand:GPR 2 "register_operand" "")
6766 (match_operand:GPR 3 "general_operand" "")]))]
6767 ""
6768 "if (!s390_expand_addcc (GET_CODE (operands[1]), operands[2], operands[3],
6769 operands[0], const0_rtx, const1_rtx)) FAIL; DONE;")
6770
6771 (define_expand "cstorecc4"
6772 [(parallel
6773 [(set (match_operand:SI 0 "register_operand" "")
6774 (match_operator:SI 1 "s390_eqne_operator"
6775 [(match_operand 2 "cc_reg_operand")
6776 (match_operand 3 "const0_operand")]))
6777 (clobber (reg:CC CC_REGNUM))])]
6778 ""
6779 "machine_mode mode = GET_MODE (operands[2]);
6780 if (TARGET_Z196)
6781 {
6782 rtx cond, ite;
6783
6784 if (GET_CODE (operands[1]) == NE)
6785 cond = gen_rtx_NE (VOIDmode, operands[2], const0_rtx);
6786 else
6787 cond = gen_rtx_EQ (VOIDmode, operands[2], const0_rtx);
6788 ite = gen_rtx_IF_THEN_ELSE (SImode, cond, const1_rtx, const0_rtx);
6789 emit_insn (gen_rtx_SET (operands[0], ite));
6790 }
6791 else
6792 {
6793 if (mode != CCZ1mode)
6794 FAIL;
6795 emit_insn (gen_sne (operands[0], operands[2]));
6796 if (GET_CODE (operands[1]) == EQ)
6797 emit_insn (gen_xorsi3 (operands[0], operands[0], const1_rtx));
6798 }
6799 DONE;")
6800
6801 (define_insn_and_split "sne"
6802 [(set (match_operand:SI 0 "register_operand" "=d")
6803 (ne:SI (match_operand:CCZ1 1 "register_operand" "0")
6804 (const_int 0)))
6805 (clobber (reg:CC CC_REGNUM))]
6806 ""
6807 "#"
6808 "reload_completed"
6809 [(parallel
6810 [(set (match_dup 0) (ashiftrt:SI (match_dup 0) (const_int 28)))
6811 (clobber (reg:CC CC_REGNUM))])])
6812
6813 ; Such patterns get directly emitted by noce_emit_store_flag.
6814 (define_insn_and_split "*cstorecc<mode>_z13"
6815 [(set (match_operand:GPR 0 "register_operand" "=&d")
6816 (match_operator:GPR 1 "s390_comparison"
6817 [(match_operand 2 "cc_reg_operand" "c")
6818 (match_operand 3 "const_int_operand" "")]))]
6819 "TARGET_Z13"
6820 "#"
6821 "reload_completed"
6822 [(set (match_dup 0) (const_int 0))
6823 (set (match_dup 0)
6824 (if_then_else:GPR
6825 (match_op_dup 1 [(match_dup 2) (match_dup 3)])
6826 (const_int 1)
6827 (match_dup 0)))])
6828
6829 ;;
6830 ;; - Conditional move instructions (introduced with z196)
6831 ;;
6832
6833 (define_expand "mov<mode>cc"
6834 [(set (match_operand:GPR 0 "nonimmediate_operand" "")
6835 (if_then_else:GPR (match_operand 1 "comparison_operator" "")
6836 (match_operand:GPR 2 "loc_operand" "")
6837 (match_operand:GPR 3 "loc_operand" "")))]
6838 "TARGET_Z196"
6839 {
6840 if (!TARGET_Z13 && CONSTANT_P (operands[2]))
6841 operands[2] = force_reg (<MODE>mode, operands[2]);
6842
6843 if (!TARGET_Z13 && CONSTANT_P (operands[3]))
6844 operands[3] = force_reg (<MODE>mode, operands[3]);
6845
6846 /* Emit the comparison insn in case we do not already have a comparison result. */
6847 if (!s390_comparison (operands[1], VOIDmode))
6848 operands[1] = s390_emit_compare (GET_CODE (operands[1]),
6849 XEXP (operands[1], 0),
6850 XEXP (operands[1], 1));
6851 })
6852
6853 ;;
6854 ;; - We do not have instructions for QImode or HImode but still
6855 ;; enable load on condition/if conversion for them.
6856 (define_expand "mov<mode>cc"
6857 [(set (match_operand:HQI 0 "nonimmediate_operand" "")
6858 (if_then_else:HQI (match_operand 1 "comparison_operator" "")
6859 (match_operand:HQI 2 "loc_operand" "")
6860 (match_operand:HQI 3 "loc_operand" "")))]
6861 "TARGET_Z196"
6862 {
6863 /* Emit the comparison insn in case we do not already have a comparison
6864 result. */
6865 if (!s390_comparison (operands[1], VOIDmode))
6866 operands[1] = s390_emit_compare (GET_CODE (operands[1]),
6867 XEXP (operands[1], 0),
6868 XEXP (operands[1], 1));
6869
6870 rtx then = operands[2];
6871 rtx els = operands[3];
6872
6873 if ((!TARGET_Z13 && CONSTANT_P (then)) || MEM_P (then))
6874 then = force_reg (<MODE>mode, then);
6875 if ((!TARGET_Z13 && CONSTANT_P (els)) || MEM_P (els))
6876 els = force_reg (<MODE>mode, els);
6877
6878 if (!CONSTANT_P (then))
6879 then = simplify_gen_subreg (E_SImode, then, <MODE>mode, 0);
6880 if (!CONSTANT_P (els))
6881 els = simplify_gen_subreg (E_SImode, els, <MODE>mode, 0);
6882
6883 rtx tmp_target = gen_reg_rtx (E_SImode);
6884 emit_insn (gen_movsicc (tmp_target, operands[1], then, els));
6885 emit_move_insn (operands[0], gen_lowpart (<MODE>mode, tmp_target));
6886 DONE;
6887 })
6888
6889
6890
6891 ; locr, loc, stoc, locgr, locg, stocg, lochi, locghi, selr, selgr
6892 (define_insn "*mov<mode>cc"
6893 [(set (match_operand:GPR 0 "nonimmediate_operand" "=d,d,d,d,d,d,d,S,S")
6894 (if_then_else:GPR
6895 (match_operator 1 "s390_comparison"
6896 [(match_operand 2 "cc_reg_operand" " c,c,c,c,c,c,c,c,c")
6897 (match_operand 5 "const_int_operand" "")])
6898 (match_operand:GPR 3 "loc_operand" " d,0,d,S,0,K,0,d,0")
6899 (match_operand:GPR 4 "loc_operand" " 0,d,d,0,S,0,K,0,d")))]
6900 "TARGET_Z196"
6901 "@
6902 loc<g>r%C1\t%0,%3
6903 loc<g>r%D1\t%0,%4
6904 sel<g>r%C1\t%0,%3,%4
6905 loc<g>%C1\t%0,%3
6906 loc<g>%D1\t%0,%4
6907 loc<g>hi%C1\t%0,%h3
6908 loc<g>hi%D1\t%0,%h4
6909 stoc<g>%C1\t%3,%0
6910 stoc<g>%D1\t%4,%0"
6911 [(set_attr "op_type" "RRF,RRF,RRF,RSY,RSY,RIE,RIE,RSY,RSY")
6912 (set_attr "cpu_facility" "*,*,z15,*,*,z13,z13,*,*")])
6913
6914 ;;
6915 ;;- Multiply instructions.
6916 ;;
6917
6918 ;
6919 ; muldi3 instruction pattern(s).
6920 ;
6921
6922 (define_expand "muldi3"
6923 [(parallel
6924 [(set (match_operand:DI 0 "register_operand")
6925 (mult:DI (match_operand:DI 1 "nonimmediate_operand")
6926 (match_operand:DI 2 "general_operand")))
6927 (clobber (reg:CC CC_REGNUM))])]
6928 "TARGET_ZARCH")
6929
6930 (define_insn "*muldi3_sign"
6931 [(set (match_operand:DI 0 "register_operand" "=d,d")
6932 (mult:DI (sign_extend:DI (match_operand:SI 2 "general_operand" "d,T"))
6933 (match_operand:DI 1 "register_operand" "0,0")))]
6934 "TARGET_ZARCH"
6935 "@
6936 msgfr\t%0,%2
6937 msgf\t%0,%2"
6938 [(set_attr "op_type" "RRE,RXY")
6939 (set_attr "type" "imuldi")])
6940
6941 (define_insn "*muldi3"
6942 [(set (match_operand:DI 0 "register_operand" "=d,d,d,d,d")
6943 (mult:DI (match_operand:DI 1 "nonimmediate_operand" "%0,d,0,0,0")
6944 (match_operand:DI 2 "general_operand" "d,d,K,T,Os")))
6945 (clobber (match_scratch:CC 3 "=X,c,X,X,X"))]
6946 "TARGET_ZARCH"
6947 "@
6948 msgr\t%0,%2
6949 msgrkc\t%0,%1,%2
6950 mghi\t%0,%h2
6951 msg\t%0,%2
6952 msgfi\t%0,%2"
6953 [(set_attr "op_type" "RRE,RRF,RI,RXY,RIL")
6954 (set_attr "type" "imuldi")
6955 (set_attr "cpu_facility" "*,z14,*,*,z10")])
6956
6957 (define_insn "mulditi3"
6958 [(set (match_operand:TI 0 "register_operand" "=d,d")
6959 (mult:TI (sign_extend:TI
6960 (match_operand:DI 1 "register_operand" "%d,0"))
6961 (sign_extend:TI
6962 (match_operand:DI 2 "nonimmediate_operand" " d,T"))))]
6963 "TARGET_Z14"
6964 "@
6965 mgrk\t%0,%1,%2
6966 mg\t%0,%2"
6967 [(set_attr "op_type" "RRF,RXY")])
6968
6969 ; Combine likes op1 and op2 to be swapped sometimes.
6970 (define_insn "mulditi3_2"
6971 [(set (match_operand:TI 0 "register_operand" "=d,d")
6972 (mult:TI (sign_extend:TI
6973 (match_operand:DI 1 "nonimmediate_operand" "%d,T"))
6974 (sign_extend:TI
6975 (match_operand:DI 2 "register_operand" " d,0"))))]
6976 "TARGET_Z14"
6977 "@
6978 mgrk\t%0,%1,%2
6979 mg\t%0,%1"
6980 [(set_attr "op_type" "RRF,RXY")])
6981
6982 (define_insn "*muldi3_sign"
6983 [(set (match_operand:DI 0 "register_operand" "=d")
6984 (mult:DI (sign_extend:DI (match_operand:HI 2 "memory_operand" "T"))
6985 (match_operand:DI 1 "register_operand" "0")))]
6986 "TARGET_Z14"
6987 "mgh\t%0,%2"
6988 [(set_attr "op_type" "RXY")])
6989
6990
6991 ;
6992 ; mulsi3 instruction pattern(s).
6993 ;
6994
6995 (define_expand "mulsi3"
6996 [(parallel
6997 [(set (match_operand:SI 0 "register_operand" "=d,d,d,d,d,d")
6998 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%0,d,0,0,0,0")
6999 (match_operand:SI 2 "general_operand" "d,d,K,R,T,Os")))
7000 (clobber (reg:CC CC_REGNUM))])]
7001 "")
7002
7003 (define_insn "*mulsi3_sign"
7004 [(set (match_operand:SI 0 "register_operand" "=d,d")
7005 (mult:SI (sign_extend:SI (match_operand:HI 2 "memory_operand" "R,T"))
7006 (match_operand:SI 1 "register_operand" "0,0")))]
7007 ""
7008 "@
7009 mh\t%0,%2
7010 mhy\t%0,%2"
7011 [(set_attr "op_type" "RX,RXY")
7012 (set_attr "type" "imulhi")
7013 (set_attr "cpu_facility" "*,z10")])
7014
7015 (define_insn "*mulsi3"
7016 [(set (match_operand:SI 0 "register_operand" "=d,d,d,d,d,d")
7017 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%0,d,0,0,0,0")
7018 (match_operand:SI 2 "general_operand" "d,d,K,R,T,Os")))
7019 (clobber (match_scratch:CC 3 "=X,c,X,X,X,X"))]
7020 ""
7021 "@
7022 msr\t%0,%2
7023 msrkc\t%0,%1,%2
7024 mhi\t%0,%h2
7025 ms\t%0,%2
7026 msy\t%0,%2
7027 msfi\t%0,%2"
7028 [(set_attr "op_type" "RRE,RRF,RI,RX,RXY,RIL")
7029 (set_attr "type" "imulsi,*,imulhi,imulsi,imulsi,imulsi")
7030 (set_attr "cpu_facility" "*,z14,*,*,longdisp,z10")])
7031
7032 ;
7033 ; mulsidi3 instruction pattern(s).
7034 ;
7035
7036 (define_insn "mulsidi3"
7037 [(set (match_operand:DI 0 "register_operand" "=d,d,d")
7038 (mult:DI (sign_extend:DI
7039 (match_operand:SI 1 "register_operand" "%0,0,0"))
7040 (sign_extend:DI
7041 (match_operand:SI 2 "nonimmediate_operand" "d,R,T"))))]
7042 "!TARGET_ZARCH"
7043 "@
7044 mr\t%0,%2
7045 m\t%0,%2
7046 mfy\t%0,%2"
7047 [(set_attr "op_type" "RR,RX,RXY")
7048 (set_attr "type" "imulsi")
7049 (set_attr "cpu_facility" "*,*,z10")])
7050
7051 ; Jump to label OP3 if OP1 * OP2 results in a signed overflow
7052 (define_expand "mulv<mode>4"
7053 [(parallel
7054 [(set (reg:CCO CC_REGNUM)
7055 (compare:CCO (mult:<DBL>
7056 (sign_extend:<DBL> (match_operand:GPR 1 "register_operand"))
7057 (sign_extend:<DBL> (match_operand:GPR 2 "nonimmediate_operand")))
7058 (sign_extend:<DBL> (mult:GPR (match_dup 1) (match_dup 2)))))
7059 (set (match_operand:GPR 0 "register_operand")
7060 (mult:GPR (match_dup 1) (match_dup 2)))])
7061 (set (pc)
7062 (if_then_else (ne (reg:CCO CC_REGNUM) (const_int 0))
7063 (label_ref (match_operand 3))
7064 (pc)))]
7065 "TARGET_Z14")
7066
7067 ; msrkc, msc, msgrkc, msgc
7068 (define_insn "*mulv<mode>3_ccoverflow"
7069 [(set (reg CC_REGNUM)
7070 (compare (mult:<DBL>
7071 (sign_extend:<DBL> (match_operand:GPR 1 "register_operand" "%d,0"))
7072 (sign_extend:<DBL> (match_operand:GPR 2 "nonimmediate_operand" " d,T")))
7073 (sign_extend:<DBL> (mult:GPR (match_dup 1) (match_dup 2)))))
7074 (set (match_operand:GPR 0 "register_operand" "=d,d")
7075 (mult:GPR (match_dup 1) (match_dup 2)))]
7076 "s390_match_ccmode (insn, CCOmode) && TARGET_Z14"
7077 "@
7078 ms<g>rkc\t%0,%1,%2
7079 ms<g>c\t%0,%2"
7080 [(set_attr "op_type" "RRF,RXY")])
7081
7082
7083 ;
7084 ; umul instruction pattern(s).
7085 ;
7086
7087 ; mlr, ml, mlgr, mlg
7088 (define_insn "umul<dwh><mode>3"
7089 [(set (match_operand:DW 0 "register_operand" "=d,d")
7090 (mult:DW (zero_extend:DW
7091 (match_operand:<DWH> 1 "register_operand" "%0,0"))
7092 (zero_extend:DW
7093 (match_operand:<DWH> 2 "nonimmediate_operand" " d,T"))))]
7094 ""
7095 "@
7096 ml<tg>r\t%0,%2
7097 ml<tg>\t%0,%2"
7098 [(set_attr "op_type" "RRE,RXY")
7099 (set_attr "type" "imul<dwh>")])
7100
7101 ;
7102 ; mul(tf|df|sf|td|dd)3 instruction pattern(s).
7103 ;
7104
7105 ; mxbr, mdbr, meebr, mxb, mxb, meeb, mdtr, mxtr
7106 (define_insn "mul<mode>3"
7107 [(set (match_operand:FP 0 "register_operand" "=f,f,f,v,v")
7108 (mult:FP (match_operand:FP 1 "nonimmediate_operand" "%f,0,0,v,v")
7109 (match_operand:FP 2 "general_operand" "f,f,R,v,v")))]
7110 "TARGET_HARD_FLOAT"
7111 "@
7112 m<xdee>tr\t%0,%1,%2
7113 m<xdee>br\t%0,%2
7114 m<xdee>b\t%0,%2
7115 wfmdb\t%v0,%v1,%v2
7116 wfmsb\t%v0,%v1,%v2"
7117 [(set_attr "op_type" "RRF,RRE,RXE,VRR,VRR")
7118 (set_attr "type" "fmul<mode>")
7119 (set_attr "cpu_facility" "*,*,*,vx,vxe")
7120 (set_attr "enabled" "<nBFP>,<nDFP>,<DSF>,<DF>,<SF>")])
7121
7122 ; madbr, maebr, maxb, madb, maeb
7123 (define_insn "fma<mode>4"
7124 [(set (match_operand:DSF 0 "register_operand" "=f,f,v,v")
7125 (fma:DSF (match_operand:DSF 1 "nonimmediate_operand" "%f,f,v,v")
7126 (match_operand:DSF 2 "nonimmediate_operand" "f,R,v,v")
7127 (match_operand:DSF 3 "register_operand" "0,0,v,v")))]
7128 "TARGET_HARD_FLOAT"
7129 "@
7130 ma<xde>br\t%0,%1,%2
7131 ma<xde>b\t%0,%1,%2
7132 wfmadb\t%v0,%v1,%v2,%v3
7133 wfmasb\t%v0,%v1,%v2,%v3"
7134 [(set_attr "op_type" "RRE,RXE,VRR,VRR")
7135 (set_attr "type" "fmadd<mode>")
7136 (set_attr "cpu_facility" "*,*,vx,vxe")
7137 (set_attr "enabled" "*,*,<DF>,<SF>")])
7138
7139 ; msxbr, msdbr, msebr, msxb, msdb, mseb
7140 (define_insn "fms<mode>4"
7141 [(set (match_operand:DSF 0 "register_operand" "=f,f,v,v")
7142 (fma:DSF (match_operand:DSF 1 "nonimmediate_operand" "%f,f,v,v")
7143 (match_operand:DSF 2 "nonimmediate_operand" "f,R,v,v")
7144 (neg:DSF (match_operand:DSF 3 "register_operand" "0,0,v,v"))))]
7145 "TARGET_HARD_FLOAT"
7146 "@
7147 ms<xde>br\t%0,%1,%2
7148 ms<xde>b\t%0,%1,%2
7149 wfmsdb\t%v0,%v1,%v2,%v3
7150 wfmssb\t%v0,%v1,%v2,%v3"
7151 [(set_attr "op_type" "RRE,RXE,VRR,VRR")
7152 (set_attr "type" "fmadd<mode>")
7153 (set_attr "cpu_facility" "*,*,vx,vxe")
7154 (set_attr "enabled" "*,*,<DF>,<SF>")])
7155
7156 ;;
7157 ;;- Divide and modulo instructions.
7158 ;;
7159
7160 ;
7161 ; divmoddi4 instruction pattern(s).
7162 ;
7163
7164 (define_expand "divmoddi4"
7165 [(parallel [(set (match_operand:DI 0 "general_operand" "")
7166 (div:DI (match_operand:DI 1 "register_operand" "")
7167 (match_operand:DI 2 "general_operand" "")))
7168 (set (match_operand:DI 3 "general_operand" "")
7169 (mod:DI (match_dup 1) (match_dup 2)))])
7170 (clobber (match_dup 4))]
7171 "TARGET_ZARCH"
7172 {
7173 rtx div_equal, mod_equal;
7174 rtx_insn *insn;
7175
7176 div_equal = gen_rtx_DIV (DImode, operands[1], operands[2]);
7177 mod_equal = gen_rtx_MOD (DImode, operands[1], operands[2]);
7178
7179 operands[4] = gen_reg_rtx(TImode);
7180 emit_insn (gen_divmodtidi3 (operands[4], operands[1], operands[2]));
7181
7182 insn = emit_move_insn (operands[0], gen_lowpart (DImode, operands[4]));
7183 set_unique_reg_note (insn, REG_EQUAL, div_equal);
7184
7185 insn = emit_move_insn (operands[3], gen_highpart (DImode, operands[4]));
7186 set_unique_reg_note (insn, REG_EQUAL, mod_equal);
7187
7188 DONE;
7189 })
7190
7191 (define_insn "divmodtidi3"
7192 [(set (match_operand:TI 0 "register_operand" "=d,d")
7193 (ior:TI
7194 (ashift:TI
7195 (zero_extend:TI
7196 (mod:DI (match_operand:DI 1 "register_operand" "0,0")
7197 (match_operand:DI 2 "general_operand" "d,T")))
7198 (const_int 64))
7199 (zero_extend:TI (div:DI (match_dup 1) (match_dup 2)))))]
7200 "TARGET_ZARCH"
7201 "@
7202 dsgr\t%0,%2
7203 dsg\t%0,%2"
7204 [(set_attr "op_type" "RRE,RXY")
7205 (set_attr "type" "idiv")])
7206
7207 (define_insn "divmodtisi3"
7208 [(set (match_operand:TI 0 "register_operand" "=d,d")
7209 (ior:TI
7210 (ashift:TI
7211 (zero_extend:TI
7212 (mod:DI (match_operand:DI 1 "register_operand" "0,0")
7213 (sign_extend:DI
7214 (match_operand:SI 2 "nonimmediate_operand" "d,T"))))
7215 (const_int 64))
7216 (zero_extend:TI
7217 (div:DI (match_dup 1) (sign_extend:DI (match_dup 2))))))]
7218 "TARGET_ZARCH"
7219 "@
7220 dsgfr\t%0,%2
7221 dsgf\t%0,%2"
7222 [(set_attr "op_type" "RRE,RXY")
7223 (set_attr "type" "idiv")])
7224
7225 ;
7226 ; udivmoddi4 instruction pattern(s).
7227 ;
7228
7229 (define_expand "udivmoddi4"
7230 [(parallel [(set (match_operand:DI 0 "general_operand" "")
7231 (udiv:DI (match_operand:DI 1 "general_operand" "")
7232 (match_operand:DI 2 "nonimmediate_operand" "")))
7233 (set (match_operand:DI 3 "general_operand" "")
7234 (umod:DI (match_dup 1) (match_dup 2)))])
7235 (clobber (match_dup 4))]
7236 "TARGET_ZARCH"
7237 {
7238 rtx div_equal, mod_equal, equal;
7239 rtx_insn *insn;
7240
7241 div_equal = gen_rtx_UDIV (DImode, operands[1], operands[2]);
7242 mod_equal = gen_rtx_UMOD (DImode, operands[1], operands[2]);
7243 equal = gen_rtx_IOR (TImode,
7244 gen_rtx_ASHIFT (TImode,
7245 gen_rtx_ZERO_EXTEND (TImode, mod_equal),
7246 GEN_INT (64)),
7247 gen_rtx_ZERO_EXTEND (TImode, div_equal));
7248
7249 operands[4] = gen_reg_rtx(TImode);
7250 emit_clobber (operands[4]);
7251 emit_move_insn (gen_lowpart (DImode, operands[4]), operands[1]);
7252 emit_move_insn (gen_highpart (DImode, operands[4]), const0_rtx);
7253
7254 insn = emit_insn (gen_udivmodtidi3 (operands[4], operands[4], operands[2]));
7255 set_unique_reg_note (insn, REG_EQUAL, equal);
7256
7257 insn = emit_move_insn (operands[0], gen_lowpart (DImode, operands[4]));
7258 set_unique_reg_note (insn, REG_EQUAL, div_equal);
7259
7260 insn = emit_move_insn (operands[3], gen_highpart (DImode, operands[4]));
7261 set_unique_reg_note (insn, REG_EQUAL, mod_equal);
7262
7263 DONE;
7264 })
7265
7266 (define_insn "udivmodtidi3"
7267 [(set (match_operand:TI 0 "register_operand" "=d,d")
7268 (ior:TI
7269 (ashift:TI
7270 (zero_extend:TI
7271 (truncate:DI
7272 (umod:TI (match_operand:TI 1 "register_operand" "0,0")
7273 (zero_extend:TI
7274 (match_operand:DI 2 "nonimmediate_operand" "d,T")))))
7275 (const_int 64))
7276 (zero_extend:TI
7277 (truncate:DI
7278 (udiv:TI (match_dup 1) (zero_extend:TI (match_dup 2)))))))]
7279 "TARGET_ZARCH"
7280 "@
7281 dlgr\t%0,%2
7282 dlg\t%0,%2"
7283 [(set_attr "op_type" "RRE,RXY")
7284 (set_attr "type" "idiv")])
7285
7286 ;
7287 ; divmodsi4 instruction pattern(s).
7288 ;
7289
7290 (define_expand "divmodsi4"
7291 [(parallel [(set (match_operand:SI 0 "general_operand" "")
7292 (div:SI (match_operand:SI 1 "general_operand" "")
7293 (match_operand:SI 2 "nonimmediate_operand" "")))
7294 (set (match_operand:SI 3 "general_operand" "")
7295 (mod:SI (match_dup 1) (match_dup 2)))])
7296 (clobber (match_dup 4))]
7297 "!TARGET_ZARCH"
7298 {
7299 rtx div_equal, mod_equal, equal;
7300 rtx_insn *insn;
7301
7302 div_equal = gen_rtx_DIV (SImode, operands[1], operands[2]);
7303 mod_equal = gen_rtx_MOD (SImode, operands[1], operands[2]);
7304 equal = gen_rtx_IOR (DImode,
7305 gen_rtx_ASHIFT (DImode,
7306 gen_rtx_ZERO_EXTEND (DImode, mod_equal),
7307 GEN_INT (32)),
7308 gen_rtx_ZERO_EXTEND (DImode, div_equal));
7309
7310 operands[4] = gen_reg_rtx(DImode);
7311 emit_insn (gen_extendsidi2 (operands[4], operands[1]));
7312
7313 insn = emit_insn (gen_divmoddisi3 (operands[4], operands[4], operands[2]));
7314 set_unique_reg_note (insn, REG_EQUAL, equal);
7315
7316 insn = emit_move_insn (operands[0], gen_lowpart (SImode, operands[4]));
7317 set_unique_reg_note (insn, REG_EQUAL, div_equal);
7318
7319 insn = emit_move_insn (operands[3], gen_highpart (SImode, operands[4]));
7320 set_unique_reg_note (insn, REG_EQUAL, mod_equal);
7321
7322 DONE;
7323 })
7324
7325 (define_insn "divmoddisi3"
7326 [(set (match_operand:DI 0 "register_operand" "=d,d")
7327 (ior:DI
7328 (ashift:DI
7329 (zero_extend:DI
7330 (truncate:SI
7331 (mod:DI (match_operand:DI 1 "register_operand" "0,0")
7332 (sign_extend:DI
7333 (match_operand:SI 2 "nonimmediate_operand" "d,R")))))
7334 (const_int 32))
7335 (zero_extend:DI
7336 (truncate:SI
7337 (div:DI (match_dup 1) (sign_extend:DI (match_dup 2)))))))]
7338 "!TARGET_ZARCH"
7339 "@
7340 dr\t%0,%2
7341 d\t%0,%2"
7342 [(set_attr "op_type" "RR,RX")
7343 (set_attr "type" "idiv")])
7344
7345 ;
7346 ; udivsi3 and umodsi3 instruction pattern(s).
7347 ;
7348
7349 (define_expand "udivmodsi4"
7350 [(parallel [(set (match_operand:SI 0 "general_operand" "")
7351 (udiv:SI (match_operand:SI 1 "general_operand" "")
7352 (match_operand:SI 2 "nonimmediate_operand" "")))
7353 (set (match_operand:SI 3 "general_operand" "")
7354 (umod:SI (match_dup 1) (match_dup 2)))])
7355 (clobber (match_dup 4))]
7356 "!TARGET_ZARCH"
7357 {
7358 rtx div_equal, mod_equal, equal;
7359 rtx_insn *insn;
7360
7361 div_equal = gen_rtx_UDIV (SImode, operands[1], operands[2]);
7362 mod_equal = gen_rtx_UMOD (SImode, operands[1], operands[2]);
7363 equal = gen_rtx_IOR (DImode,
7364 gen_rtx_ASHIFT (DImode,
7365 gen_rtx_ZERO_EXTEND (DImode, mod_equal),
7366 GEN_INT (32)),
7367 gen_rtx_ZERO_EXTEND (DImode, div_equal));
7368
7369 operands[4] = gen_reg_rtx(DImode);
7370 emit_clobber (operands[4]);
7371 emit_move_insn (gen_lowpart (SImode, operands[4]), operands[1]);
7372 emit_move_insn (gen_highpart (SImode, operands[4]), const0_rtx);
7373
7374 insn = emit_insn (gen_udivmoddisi3 (operands[4], operands[4], operands[2]));
7375 set_unique_reg_note (insn, REG_EQUAL, equal);
7376
7377 insn = emit_move_insn (operands[0], gen_lowpart (SImode, operands[4]));
7378 set_unique_reg_note (insn, REG_EQUAL, div_equal);
7379
7380 insn = emit_move_insn (operands[3], gen_highpart (SImode, operands[4]));
7381 set_unique_reg_note (insn, REG_EQUAL, mod_equal);
7382
7383 DONE;
7384 })
7385
7386 (define_insn "udivmoddisi3"
7387 [(set (match_operand:DI 0 "register_operand" "=d,d")
7388 (ior:DI
7389 (ashift:DI
7390 (zero_extend:DI
7391 (truncate:SI
7392 (umod:DI (match_operand:DI 1 "register_operand" "0,0")
7393 (zero_extend:DI
7394 (match_operand:SI 2 "nonimmediate_operand" "d,T")))))
7395 (const_int 32))
7396 (zero_extend:DI
7397 (truncate:SI
7398 (udiv:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))))]
7399 "!TARGET_ZARCH"
7400 "@
7401 dlr\t%0,%2
7402 dl\t%0,%2"
7403 [(set_attr "op_type" "RRE,RXY")
7404 (set_attr "type" "idiv")])
7405
7406 ;
7407 ; div(df|sf)3 instruction pattern(s).
7408 ;
7409
7410 ; dxbr, ddbr, debr, dxb, ddb, deb, ddtr, dxtr
7411 (define_insn "div<mode>3"
7412 [(set (match_operand:FP 0 "register_operand" "=f,f,f,v,v")
7413 (div:FP (match_operand:FP 1 "register_operand" "f,0,0,v,v")
7414 (match_operand:FP 2 "general_operand" "f,f,R,v,v")))]
7415 "TARGET_HARD_FLOAT"
7416 "@
7417 d<xde>tr\t%0,%1,%2
7418 d<xde>br\t%0,%2
7419 d<xde>b\t%0,%2
7420 wfddb\t%v0,%v1,%v2
7421 wfdsb\t%v0,%v1,%v2"
7422 [(set_attr "op_type" "RRF,RRE,RXE,VRR,VRR")
7423 (set_attr "type" "fdiv<mode>")
7424 (set_attr "cpu_facility" "*,*,*,vx,vxe")
7425 (set_attr "enabled" "<nBFP>,<nDFP>,<DSF>,<DF>,<SF>")])
7426
7427
7428 ;;
7429 ;;- And instructions.
7430 ;;
7431
7432 (define_expand "and<mode>3"
7433 [(set (match_operand:INT 0 "nonimmediate_operand" "")
7434 (and:INT (match_operand:INT 1 "nonimmediate_operand" "")
7435 (match_operand:INT 2 "general_operand" "")))
7436 (clobber (reg:CC CC_REGNUM))]
7437 ""
7438 "s390_expand_logical_operator (AND, <MODE>mode, operands); DONE;")
7439
7440 ;
7441 ; anddi3 instruction pattern(s).
7442 ;
7443
7444 (define_insn "*anddi3_cc"
7445 [(set (reg CC_REGNUM)
7446 (compare
7447 (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,d,0, d")
7448 (match_operand:DI 2 "general_operand" " d,d,T,NxxDw"))
7449 (const_int 0)))
7450 (set (match_operand:DI 0 "register_operand" "=d,d,d, d")
7451 (and:DI (match_dup 1) (match_dup 2)))]
7452 "TARGET_ZARCH && s390_match_ccmode(insn, CCTmode)"
7453 "@
7454 ngr\t%0,%2
7455 ngrk\t%0,%1,%2
7456 ng\t%0,%2
7457 risbg\t%0,%1,%s2,128+%e2,0"
7458 [(set_attr "op_type" "RRE,RRF,RXY,RIE")
7459 (set_attr "cpu_facility" "*,z196,*,z10")
7460 (set_attr "z10prop" "z10_super_E1,*,z10_super_E1,z10_super_E1")])
7461
7462 (define_insn "*anddi3_cconly"
7463 [(set (reg CC_REGNUM)
7464 (compare
7465 (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,d,0, d")
7466 (match_operand:DI 2 "general_operand" " d,d,T,NxxDw"))
7467 (const_int 0)))
7468 (clobber (match_scratch:DI 0 "=d,d,d, d"))]
7469 "TARGET_ZARCH
7470 && s390_match_ccmode(insn, CCTmode)
7471 /* Do not steal TM patterns. */
7472 && s390_single_part (operands[2], DImode, HImode, 0) < 0"
7473 "@
7474 ngr\t%0,%2
7475 ngrk\t%0,%1,%2
7476 ng\t%0,%2
7477 risbg\t%0,%1,%s2,128+%e2,0"
7478 [(set_attr "op_type" "RRE,RRF,RXY,RIE")
7479 (set_attr "cpu_facility" "*,z196,*,z10")
7480 (set_attr "z10prop" "z10_super_E1,*,z10_super_E1,z10_super_E1")])
7481
7482 (define_insn "*anddi3"
7483 [(set (match_operand:DI 0 "nonimmediate_operand"
7484 "=d,d, d, d, d, d, d, d,d,d,d, d, AQ,Q")
7485 (and:DI
7486 (match_operand:DI 1 "nonimmediate_operand"
7487 "%d,o, 0, 0, 0, 0, 0, 0,0,d,0, d, 0,0")
7488 (match_operand:DI 2 "general_operand"
7489 "M, M,N0HDF,N1HDF,N2HDF,N3HDF,N0SDF,N1SDF,d,d,T,NxxDw,NxQDF,Q")))
7490 (clobber (reg:CC CC_REGNUM))]
7491 "TARGET_ZARCH && s390_logical_operator_ok_p (operands)"
7492 "@
7493 #
7494 #
7495 nihh\t%0,%j2
7496 nihl\t%0,%j2
7497 nilh\t%0,%j2
7498 nill\t%0,%j2
7499 nihf\t%0,%m2
7500 nilf\t%0,%m2
7501 ngr\t%0,%2
7502 ngrk\t%0,%1,%2
7503 ng\t%0,%2
7504 risbg\t%0,%1,%s2,128+%e2,0
7505 #
7506 #"
7507 [(set_attr "op_type" "RRE,RXE,RI,RI,RI,RI,RIL,RIL,RRE,RRF,RXY,RIE,SI,SS")
7508 (set_attr "cpu_facility" "*,*,*,*,*,*,extimm,extimm,*,z196,*,z10,*,*")
7509 (set_attr "z10prop" "*,
7510 *,
7511 z10_super_E1,
7512 z10_super_E1,
7513 z10_super_E1,
7514 z10_super_E1,
7515 z10_super_E1,
7516 z10_super_E1,
7517 z10_super_E1,
7518 *,
7519 z10_super_E1,
7520 z10_super_E1,
7521 *,
7522 *")])
7523
7524 (define_split
7525 [(set (match_operand:DI 0 "s_operand" "")
7526 (and:DI (match_dup 0) (match_operand:DI 1 "immediate_operand" "")))
7527 (clobber (reg:CC CC_REGNUM))]
7528 "reload_completed"
7529 [(parallel
7530 [(set (match_dup 0) (and:QI (match_dup 0) (match_dup 1)))
7531 (clobber (reg:CC CC_REGNUM))])]
7532 "s390_narrow_logical_operator (AND, &operands[0], &operands[1]);")
7533
7534 ;; These two are what combine generates for (ashift (zero_extract)).
7535 (define_insn "*extzv_<mode>_srl<clobbercc_or_nocc>"
7536 [(set (match_operand:GPR 0 "register_operand" "=d")
7537 (and:GPR (lshiftrt:GPR
7538 (match_operand:GPR 1 "register_operand" "d")
7539 (match_operand:GPR 2 "nonzero_shift_count_operand" ""))
7540 (match_operand:GPR 3 "contiguous_bitmask_nowrap_operand" "")))]
7541 "<z10_or_zEC12_cond>
7542 /* Note that even for the SImode pattern, the rotate is always DImode. */
7543 && s390_extzv_shift_ok (<bitsize>, -INTVAL (operands[2]),
7544 INTVAL (operands[3]))"
7545 "<risbg_n>\t%0,%1,%<bfstart>3,128+%<bfend>3,64-%2"
7546 [(set_attr "op_type" "RIE")
7547 (set_attr "z10prop" "z10_super_E1")])
7548
7549 (define_insn "*extzv_<mode>_sll<clobbercc_or_nocc>"
7550 [(set (match_operand:GPR 0 "register_operand" "=d")
7551 (and:GPR (ashift:GPR
7552 (match_operand:GPR 1 "register_operand" "d")
7553 (match_operand:GPR 2 "nonzero_shift_count_operand" ""))
7554 (match_operand:GPR 3 "contiguous_bitmask_nowrap_operand" "")))]
7555 "<z10_or_zEC12_cond>
7556 && s390_extzv_shift_ok (<bitsize>, INTVAL (operands[2]),
7557 INTVAL (operands[3]))"
7558 "<risbg_n>\t%0,%1,%<bfstart>3,128+%<bfend>3,%2"
7559 [(set_attr "op_type" "RIE")
7560 (set_attr "z10prop" "z10_super_E1")])
7561
7562
7563 ;
7564 ; andsi3 instruction pattern(s).
7565 ;
7566
7567 (define_insn "*andsi3_cc"
7568 [(set (reg CC_REGNUM)
7569 (compare
7570 (and:SI
7571 (match_operand:SI 1 "nonimmediate_operand" "%0,0,d,0,0, d")
7572 (match_operand:SI 2 "general_operand" "Os,d,d,R,T,NxxSq"))
7573 (const_int 0)))
7574 (set (match_operand:SI 0 "register_operand" "=d,d,d,d,d, d")
7575 (and:SI (match_dup 1) (match_dup 2)))]
7576 "s390_match_ccmode(insn, CCTmode)"
7577 "@
7578 nilf\t%0,%o2
7579 nr\t%0,%2
7580 nrk\t%0,%1,%2
7581 n\t%0,%2
7582 ny\t%0,%2
7583 risbg\t%0,%1,%t2,128+%f2,0"
7584 [(set_attr "op_type" "RIL,RR,RRF,RX,RXY,RIE")
7585 (set_attr "cpu_facility" "*,*,z196,*,longdisp,z10")
7586 (set_attr "z10prop" "z10_super_E1,z10_super_E1,*,
7587 z10_super_E1,z10_super_E1,z10_super_E1")])
7588
7589 (define_insn "*andsi3_cconly"
7590 [(set (reg CC_REGNUM)
7591 (compare
7592 (and:SI
7593 (match_operand:SI 1 "nonimmediate_operand" "%0,0,d,0,0, d")
7594 (match_operand:SI 2 "general_operand" "Os,d,d,R,T,NxxSq"))
7595 (const_int 0)))
7596 (clobber (match_scratch:SI 0 "=d,d,d,d,d, d"))]
7597 "s390_match_ccmode(insn, CCTmode)
7598 /* Do not steal TM patterns. */
7599 && s390_single_part (operands[2], SImode, HImode, 0) < 0"
7600 "@
7601 nilf\t%0,%o2
7602 nr\t%0,%2
7603 nrk\t%0,%1,%2
7604 n\t%0,%2
7605 ny\t%0,%2
7606 risbg\t%0,%1,%t2,128+%f2,0"
7607 [(set_attr "op_type" "RIL,RR,RRF,RX,RXY,RIE")
7608 (set_attr "cpu_facility" "*,*,z196,*,longdisp,z10")
7609 (set_attr "z10prop" "z10_super_E1,z10_super_E1,*,
7610 z10_super_E1,z10_super_E1,z10_super_E1")])
7611
7612 (define_insn "*andsi3_zarch"
7613 [(set (match_operand:SI 0 "nonimmediate_operand"
7614 "=d,d, d, d, d,d,d,d,d, d, AQ,Q")
7615 (and:SI (match_operand:SI 1 "nonimmediate_operand"
7616 "%d,o, 0, 0, 0,0,d,0,0, d, 0,0")
7617 (match_operand:SI 2 "general_operand"
7618 " M,M,N0HSF,N1HSF,Os,d,d,R,T,NxxSw,NxQSF,Q")))
7619 (clobber (reg:CC CC_REGNUM))]
7620 "TARGET_ZARCH && s390_logical_operator_ok_p (operands)"
7621 "@
7622 #
7623 #
7624 nilh\t%0,%j2
7625 nill\t%0,%j2
7626 nilf\t%0,%o2
7627 nr\t%0,%2
7628 nrk\t%0,%1,%2
7629 n\t%0,%2
7630 ny\t%0,%2
7631 risbg\t%0,%1,%t2,128+%f2,0
7632 #
7633 #"
7634 [(set_attr "op_type" "RRE,RXE,RI,RI,RIL,RR,RRF,RX,RXY,RIE,SI,SS")
7635 (set_attr "cpu_facility" "*,*,*,*,*,*,z196,*,longdisp,z10,*,*")
7636 (set_attr "z10prop" "*,
7637 *,
7638 z10_super_E1,
7639 z10_super_E1,
7640 z10_super_E1,
7641 z10_super_E1,
7642 *,
7643 z10_super_E1,
7644 z10_super_E1,
7645 z10_super_E1,
7646 *,
7647 *")])
7648
7649 (define_insn "*andsi3_esa"
7650 [(set (match_operand:SI 0 "nonimmediate_operand" "=d,d, AQ,Q")
7651 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0, 0,0")
7652 (match_operand:SI 2 "general_operand" " d,R,NxQSF,Q")))
7653 (clobber (reg:CC CC_REGNUM))]
7654 "!TARGET_ZARCH && s390_logical_operator_ok_p (operands)"
7655 "@
7656 nr\t%0,%2
7657 n\t%0,%2
7658 #
7659 #"
7660 [(set_attr "op_type" "RR,RX,SI,SS")
7661 (set_attr "z10prop" "z10_super_E1,z10_super_E1,*,*")])
7662
7663
7664 (define_split
7665 [(set (match_operand:SI 0 "s_operand" "")
7666 (and:SI (match_dup 0) (match_operand:SI 1 "immediate_operand" "")))
7667 (clobber (reg:CC CC_REGNUM))]
7668 "reload_completed"
7669 [(parallel
7670 [(set (match_dup 0) (and:QI (match_dup 0) (match_dup 1)))
7671 (clobber (reg:CC CC_REGNUM))])]
7672 "s390_narrow_logical_operator (AND, &operands[0], &operands[1]);")
7673
7674 ;
7675 ; andhi3 instruction pattern(s).
7676 ;
7677
7678 (define_insn "*andhi3_zarch"
7679 [(set (match_operand:HI 0 "nonimmediate_operand" "=d,d,d, AQ,Q")
7680 (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,d,0, 0,0")
7681 (match_operand:HI 2 "general_operand" " d,d,n,NxQHF,Q")))
7682 (clobber (reg:CC CC_REGNUM))]
7683 "TARGET_ZARCH && s390_logical_operator_ok_p (operands)"
7684 "@
7685 nr\t%0,%2
7686 nrk\t%0,%1,%2
7687 nill\t%0,%x2
7688 #
7689 #"
7690 [(set_attr "op_type" "RR,RRF,RI,SI,SS")
7691 (set_attr "cpu_facility" "*,z196,*,*,*")
7692 (set_attr "z10prop" "z10_super_E1,*,z10_super_E1,*,*")
7693 ])
7694
7695 (define_insn "*andhi3_esa"
7696 [(set (match_operand:HI 0 "nonimmediate_operand" "=d,AQ,Q")
7697 (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,0")
7698 (match_operand:HI 2 "general_operand" "d,NxQHF,Q")))
7699 (clobber (reg:CC CC_REGNUM))]
7700 "!TARGET_ZARCH && s390_logical_operator_ok_p (operands)"
7701 "@
7702 nr\t%0,%2
7703 #
7704 #"
7705 [(set_attr "op_type" "RR,SI,SS")
7706 (set_attr "z10prop" "z10_super_E1,*,*")
7707 ])
7708
7709 (define_split
7710 [(set (match_operand:HI 0 "s_operand" "")
7711 (and:HI (match_dup 0) (match_operand:HI 1 "immediate_operand" "")))
7712 (clobber (reg:CC CC_REGNUM))]
7713 "reload_completed"
7714 [(parallel
7715 [(set (match_dup 0) (and:QI (match_dup 0) (match_dup 1)))
7716 (clobber (reg:CC CC_REGNUM))])]
7717 "s390_narrow_logical_operator (AND, &operands[0], &operands[1]);")
7718
7719 ;
7720 ; andqi3 instruction pattern(s).
7721 ;
7722
7723 (define_insn "*andqi3_zarch"
7724 [(set (match_operand:QI 0 "nonimmediate_operand" "=d,d,d,Q,S,Q")
7725 (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,d,0,0,0,0")
7726 (match_operand:QI 2 "general_operand" " d,d,n,n,n,Q")))
7727 (clobber (reg:CC CC_REGNUM))]
7728 "TARGET_ZARCH && s390_logical_operator_ok_p (operands)"
7729 "@
7730 nr\t%0,%2
7731 nrk\t%0,%1,%2
7732 nill\t%0,%b2
7733 ni\t%S0,%b2
7734 niy\t%S0,%b2
7735 #"
7736 [(set_attr "op_type" "RR,RRF,RI,SI,SIY,SS")
7737 (set_attr "cpu_facility" "*,z196,*,*,longdisp,*")
7738 (set_attr "z10prop" "z10_super_E1,*,z10_super_E1,z10_super,z10_super,*")])
7739
7740 (define_insn "*andqi3_esa"
7741 [(set (match_operand:QI 0 "nonimmediate_operand" "=d,Q,Q")
7742 (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
7743 (match_operand:QI 2 "general_operand" "d,n,Q")))
7744 (clobber (reg:CC CC_REGNUM))]
7745 "!TARGET_ZARCH && s390_logical_operator_ok_p (operands)"
7746 "@
7747 nr\t%0,%2
7748 ni\t%S0,%b2
7749 #"
7750 [(set_attr "op_type" "RR,SI,SS")
7751 (set_attr "z10prop" "z10_super_E1,z10_super,*")])
7752
7753 ;
7754 ; And with complement
7755 ;
7756 ; c = ~b & a = (b & a) ^ a
7757
7758 (define_insn_and_split "*andc_split_<mode>"
7759 [(set (match_operand:GPR 0 "nonimmediate_operand" "")
7760 (and:GPR (not:GPR (match_operand:GPR 1 "nonimmediate_operand" ""))
7761 (match_operand:GPR 2 "general_operand" "")))
7762 (clobber (reg:CC CC_REGNUM))]
7763 "!TARGET_Z15
7764 && ! reload_completed
7765 && (GET_CODE (operands[0]) != MEM
7766 /* Ensure that s390_logical_operator_ok_p will succeed even
7767 on the split xor if (b & a) is stored into a pseudo. */
7768 || rtx_equal_p (operands[0], operands[2]))"
7769 "#"
7770 "&& 1"
7771 [
7772 (parallel
7773 [(set (match_dup 3) (and:GPR (match_dup 1) (match_dup 2)))
7774 (clobber (reg:CC CC_REGNUM))])
7775 (parallel
7776 [(set (match_dup 0) (xor:GPR (match_dup 3) (match_dup 2)))
7777 (clobber (reg:CC CC_REGNUM))])]
7778 {
7779 if (reg_overlap_mentioned_p (operands[0], operands[2]))
7780 operands[3] = gen_reg_rtx (<MODE>mode);
7781 else
7782 operands[3] = operands[0];
7783 })
7784
7785 ;
7786 ; Block and (NC) patterns.
7787 ;
7788
7789 (define_insn "*nc"
7790 [(set (match_operand:BLK 0 "memory_operand" "=Q")
7791 (and:BLK (match_dup 0)
7792 (match_operand:BLK 1 "memory_operand" "Q")))
7793 (use (match_operand 2 "const_int_operand" "n"))
7794 (clobber (reg:CC CC_REGNUM))]
7795 "INTVAL (operands[2]) >= 1 && INTVAL (operands[2]) <= 256"
7796 "nc\t%O0(%2,%R0),%S1"
7797 [(set_attr "op_type" "SS")
7798 (set_attr "z196prop" "z196_cracked")])
7799
7800 (define_split
7801 [(set (match_operand 0 "memory_operand" "")
7802 (and (match_dup 0)
7803 (match_operand 1 "memory_operand" "")))
7804 (clobber (reg:CC CC_REGNUM))]
7805 "reload_completed
7806 && GET_MODE (operands[0]) == GET_MODE (operands[1])
7807 && GET_MODE_SIZE (GET_MODE (operands[0])) > 0"
7808 [(parallel
7809 [(set (match_dup 0) (and:BLK (match_dup 0) (match_dup 1)))
7810 (use (match_dup 2))
7811 (clobber (reg:CC CC_REGNUM))])]
7812 {
7813 operands[2] = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[0])));
7814 operands[0] = adjust_address (operands[0], BLKmode, 0);
7815 operands[1] = adjust_address (operands[1], BLKmode, 0);
7816 })
7817
7818 (define_peephole2
7819 [(parallel
7820 [(set (match_operand:BLK 0 "memory_operand" "")
7821 (and:BLK (match_dup 0)
7822 (match_operand:BLK 1 "memory_operand" "")))
7823 (use (match_operand 2 "const_int_operand" ""))
7824 (clobber (reg:CC CC_REGNUM))])
7825 (parallel
7826 [(set (match_operand:BLK 3 "memory_operand" "")
7827 (and:BLK (match_dup 3)
7828 (match_operand:BLK 4 "memory_operand" "")))
7829 (use (match_operand 5 "const_int_operand" ""))
7830 (clobber (reg:CC CC_REGNUM))])]
7831 "s390_offset_p (operands[0], operands[3], operands[2])
7832 && s390_offset_p (operands[1], operands[4], operands[2])
7833 && !s390_overlap_p (operands[0], operands[1],
7834 INTVAL (operands[2]) + INTVAL (operands[5]))
7835 && INTVAL (operands[2]) + INTVAL (operands[5]) <= 256"
7836 [(parallel
7837 [(set (match_dup 6) (and:BLK (match_dup 6) (match_dup 7)))
7838 (use (match_dup 8))
7839 (clobber (reg:CC CC_REGNUM))])]
7840 "operands[6] = gen_rtx_MEM (BLKmode, XEXP (operands[0], 0));
7841 operands[7] = gen_rtx_MEM (BLKmode, XEXP (operands[1], 0));
7842 operands[8] = GEN_INT (INTVAL (operands[2]) + INTVAL (operands[5]));")
7843
7844
7845 ;;
7846 ;;- Bit set (inclusive or) instructions.
7847 ;;
7848
7849 (define_expand "ior<mode>3"
7850 [(set (match_operand:INT 0 "nonimmediate_operand" "")
7851 (ior:INT (match_operand:INT 1 "nonimmediate_operand" "")
7852 (match_operand:INT 2 "general_operand" "")))
7853 (clobber (reg:CC CC_REGNUM))]
7854 ""
7855 "s390_expand_logical_operator (IOR, <MODE>mode, operands); DONE;")
7856
7857 ;
7858 ; iordi3 instruction pattern(s).
7859 ;
7860
7861 (define_insn "*iordi3_cc"
7862 [(set (reg CC_REGNUM)
7863 (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,d,0")
7864 (match_operand:DI 2 "general_operand" " d,d,T"))
7865 (const_int 0)))
7866 (set (match_operand:DI 0 "register_operand" "=d,d,d")
7867 (ior:DI (match_dup 1) (match_dup 2)))]
7868 "s390_match_ccmode(insn, CCTmode) && TARGET_ZARCH"
7869 "@
7870 ogr\t%0,%2
7871 ogrk\t%0,%1,%2
7872 og\t%0,%2"
7873 [(set_attr "op_type" "RRE,RRF,RXY")
7874 (set_attr "cpu_facility" "*,z196,*")
7875 (set_attr "z10prop" "z10_super_E1,*,z10_super_E1")])
7876
7877 (define_insn "*iordi3_cconly"
7878 [(set (reg CC_REGNUM)
7879 (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,d,0")
7880 (match_operand:DI 2 "general_operand" " d,d,T"))
7881 (const_int 0)))
7882 (clobber (match_scratch:DI 0 "=d,d,d"))]
7883 "s390_match_ccmode(insn, CCTmode) && TARGET_ZARCH"
7884 "@
7885 ogr\t%0,%2
7886 ogrk\t%0,%1,%2
7887 og\t%0,%2"
7888 [(set_attr "op_type" "RRE,RRF,RXY")
7889 (set_attr "cpu_facility" "*,z196,*")
7890 (set_attr "z10prop" "z10_super_E1,*,z10_super_E1")])
7891
7892 (define_insn "*iordi3"
7893 [(set (match_operand:DI 0 "nonimmediate_operand"
7894 "=d, d, d, d, d, d,d,d,d, AQ,Q")
7895 (ior:DI (match_operand:DI 1 "nonimmediate_operand"
7896 " %0, 0, 0, 0, 0, 0,0,d,0, 0,0")
7897 (match_operand:DI 2 "general_operand"
7898 "N0HD0,N1HD0,N2HD0,N3HD0,N0SD0,N1SD0,d,d,T,NxQD0,Q")))
7899 (clobber (reg:CC CC_REGNUM))]
7900 "TARGET_ZARCH && s390_logical_operator_ok_p (operands)"
7901 "@
7902 oihh\t%0,%i2
7903 oihl\t%0,%i2
7904 oilh\t%0,%i2
7905 oill\t%0,%i2
7906 oihf\t%0,%k2
7907 oilf\t%0,%k2
7908 ogr\t%0,%2
7909 ogrk\t%0,%1,%2
7910 og\t%0,%2
7911 #
7912 #"
7913 [(set_attr "op_type" "RI,RI,RI,RI,RIL,RIL,RRE,RRF,RXY,SI,SS")
7914 (set_attr "cpu_facility" "*,*,*,*,extimm,extimm,*,z196,*,*,*")
7915 (set_attr "z10prop" "z10_super_E1,
7916 z10_super_E1,
7917 z10_super_E1,
7918 z10_super_E1,
7919 z10_super_E1,
7920 z10_super_E1,
7921 z10_super_E1,
7922 *,
7923 z10_super_E1,
7924 *,
7925 *")])
7926
7927 (define_split
7928 [(set (match_operand:DI 0 "s_operand" "")
7929 (ior:DI (match_dup 0) (match_operand:DI 1 "immediate_operand" "")))
7930 (clobber (reg:CC CC_REGNUM))]
7931 "reload_completed"
7932 [(parallel
7933 [(set (match_dup 0) (ior:QI (match_dup 0) (match_dup 1)))
7934 (clobber (reg:CC CC_REGNUM))])]
7935 "s390_narrow_logical_operator (IOR, &operands[0], &operands[1]);")
7936
7937 ;
7938 ; iorsi3 instruction pattern(s).
7939 ;
7940
7941 (define_insn "*iorsi3_cc"
7942 [(set (reg CC_REGNUM)
7943 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,d,0,0")
7944 (match_operand:SI 2 "general_operand" "Os,d,d,R,T"))
7945 (const_int 0)))
7946 (set (match_operand:SI 0 "register_operand" "=d,d,d,d,d")
7947 (ior:SI (match_dup 1) (match_dup 2)))]
7948 "s390_match_ccmode(insn, CCTmode)"
7949 "@
7950 oilf\t%0,%o2
7951 or\t%0,%2
7952 ork\t%0,%1,%2
7953 o\t%0,%2
7954 oy\t%0,%2"
7955 [(set_attr "op_type" "RIL,RR,RRF,RX,RXY")
7956 (set_attr "cpu_facility" "*,*,z196,*,longdisp")
7957 (set_attr "z10prop" "z10_super_E1,z10_super_E1,*,z10_super_E1,z10_super_E1")])
7958
7959 (define_insn "*iorsi3_cconly"
7960 [(set (reg CC_REGNUM)
7961 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,d,0,0")
7962 (match_operand:SI 2 "general_operand" "Os,d,d,R,T"))
7963 (const_int 0)))
7964 (clobber (match_scratch:SI 0 "=d,d,d,d,d"))]
7965 "s390_match_ccmode(insn, CCTmode)"
7966 "@
7967 oilf\t%0,%o2
7968 or\t%0,%2
7969 ork\t%0,%1,%2
7970 o\t%0,%2
7971 oy\t%0,%2"
7972 [(set_attr "op_type" "RIL,RR,RRF,RX,RXY")
7973 (set_attr "cpu_facility" "*,*,z196,*,longdisp")
7974 (set_attr "z10prop" "z10_super_E1,z10_super_E1,*,z10_super_E1,z10_super_E1")])
7975
7976 (define_insn "*iorsi3_zarch"
7977 [(set (match_operand:SI 0 "nonimmediate_operand" "=d, d, d,d,d,d,d, AQ,Q")
7978 (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0, 0, 0,0,d,0,0, 0,0")
7979 (match_operand:SI 2 "general_operand" "N0HS0,N1HS0,Os,d,d,R,T,NxQS0,Q")))
7980 (clobber (reg:CC CC_REGNUM))]
7981 "TARGET_ZARCH && s390_logical_operator_ok_p (operands)"
7982 "@
7983 oilh\t%0,%i2
7984 oill\t%0,%i2
7985 oilf\t%0,%o2
7986 or\t%0,%2
7987 ork\t%0,%1,%2
7988 o\t%0,%2
7989 oy\t%0,%2
7990 #
7991 #"
7992 [(set_attr "op_type" "RI,RI,RIL,RR,RRF,RX,RXY,SI,SS")
7993 (set_attr "cpu_facility" "*,*,*,*,z196,*,longdisp,*,*")
7994 (set_attr "z10prop" "z10_super_E1,
7995 z10_super_E1,
7996 z10_super_E1,
7997 z10_super_E1,
7998 *,
7999 z10_super_E1,
8000 z10_super_E1,
8001 *,
8002 *")])
8003
8004 (define_insn "*iorsi3_esa"
8005 [(set (match_operand:SI 0 "nonimmediate_operand" "=d,d,AQ,Q")
8006 (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,0,0")
8007 (match_operand:SI 2 "general_operand" "d,R,NxQS0,Q")))
8008 (clobber (reg:CC CC_REGNUM))]
8009 "!TARGET_ZARCH && s390_logical_operator_ok_p (operands)"
8010 "@
8011 or\t%0,%2
8012 o\t%0,%2
8013 #
8014 #"
8015 [(set_attr "op_type" "RR,RX,SI,SS")
8016 (set_attr "z10prop" "z10_super_E1,z10_super_E1,*,*")])
8017
8018 (define_split
8019 [(set (match_operand:SI 0 "s_operand" "")
8020 (ior:SI (match_dup 0) (match_operand:SI 1 "immediate_operand" "")))
8021 (clobber (reg:CC CC_REGNUM))]
8022 "reload_completed"
8023 [(parallel
8024 [(set (match_dup 0) (ior:QI (match_dup 0) (match_dup 1)))
8025 (clobber (reg:CC CC_REGNUM))])]
8026 "s390_narrow_logical_operator (IOR, &operands[0], &operands[1]);")
8027
8028 ;
8029 ; iorhi3 instruction pattern(s).
8030 ;
8031
8032 (define_insn "*iorhi3_zarch"
8033 [(set (match_operand:HI 0 "nonimmediate_operand" "=d,d,d, AQ,Q")
8034 (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,d,0, 0,0")
8035 (match_operand:HI 2 "general_operand" " d,d,n,NxQH0,Q")))
8036 (clobber (reg:CC CC_REGNUM))]
8037 "TARGET_ZARCH && s390_logical_operator_ok_p (operands)"
8038 "@
8039 or\t%0,%2
8040 ork\t%0,%1,%2
8041 oill\t%0,%x2
8042 #
8043 #"
8044 [(set_attr "op_type" "RR,RRF,RI,SI,SS")
8045 (set_attr "cpu_facility" "*,z196,*,*,*")
8046 (set_attr "z10prop" "z10_super_E1,*,z10_super_E1,*,*")])
8047
8048 (define_insn "*iorhi3_esa"
8049 [(set (match_operand:HI 0 "nonimmediate_operand" "=d,AQ,Q")
8050 (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,0")
8051 (match_operand:HI 2 "general_operand" "d,NxQH0,Q")))
8052 (clobber (reg:CC CC_REGNUM))]
8053 "!TARGET_ZARCH && s390_logical_operator_ok_p (operands)"
8054 "@
8055 or\t%0,%2
8056 #
8057 #"
8058 [(set_attr "op_type" "RR,SI,SS")
8059 (set_attr "z10prop" "z10_super_E1,*,*")])
8060
8061 (define_split
8062 [(set (match_operand:HI 0 "s_operand" "")
8063 (ior:HI (match_dup 0) (match_operand:HI 1 "immediate_operand" "")))
8064 (clobber (reg:CC CC_REGNUM))]
8065 "reload_completed"
8066 [(parallel
8067 [(set (match_dup 0) (ior:QI (match_dup 0) (match_dup 1)))
8068 (clobber (reg:CC CC_REGNUM))])]
8069 "s390_narrow_logical_operator (IOR, &operands[0], &operands[1]);")
8070
8071 ;
8072 ; iorqi3 instruction pattern(s).
8073 ;
8074
8075 (define_insn "*iorqi3_zarch"
8076 [(set (match_operand:QI 0 "nonimmediate_operand" "=d,d,d,Q,S,Q")
8077 (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,d,0,0,0,0")
8078 (match_operand:QI 2 "general_operand" " d,d,n,n,n,Q")))
8079 (clobber (reg:CC CC_REGNUM))]
8080 "TARGET_ZARCH && s390_logical_operator_ok_p (operands)"
8081 "@
8082 or\t%0,%2
8083 ork\t%0,%1,%2
8084 oill\t%0,%b2
8085 oi\t%S0,%b2
8086 oiy\t%S0,%b2
8087 #"
8088 [(set_attr "op_type" "RR,RRF,RI,SI,SIY,SS")
8089 (set_attr "cpu_facility" "*,z196,*,*,longdisp,*")
8090 (set_attr "z10prop" "z10_super_E1,*,z10_super_E1,
8091 z10_super,z10_super,*")])
8092
8093 (define_insn "*iorqi3_esa"
8094 [(set (match_operand:QI 0 "nonimmediate_operand" "=d,Q,Q")
8095 (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8096 (match_operand:QI 2 "general_operand" "d,n,Q")))
8097 (clobber (reg:CC CC_REGNUM))]
8098 "!TARGET_ZARCH && s390_logical_operator_ok_p (operands)"
8099 "@
8100 or\t%0,%2
8101 oi\t%S0,%b2
8102 #"
8103 [(set_attr "op_type" "RR,SI,SS")
8104 (set_attr "z10prop" "z10_super_E1,z10_super,*")])
8105
8106 ;
8107 ; And/Or with complement
8108 ;
8109
8110 ; ncrk, ncgrk, ocrk, ocgrk
8111 (define_insn "*<ANDOR:bitops_name>c<GPR:mode>_cc"
8112 [(set (reg CC_REGNUM)
8113 (compare
8114 (ANDOR:GPR (not:GPR (match_operand:GPR 1 "register_operand" "d"))
8115 (match_operand:GPR 2 "register_operand" "d"))
8116 (const_int 0)))
8117 (set (match_operand:GPR 0 "register_operand" "=d")
8118 (ANDOR:GPR (not:GPR (match_dup 1))
8119 (match_dup 2)))]
8120 "TARGET_Z15 && s390_match_ccmode(insn, CCTmode)"
8121 "<ANDOR:noxa>c<GPR:g>rk\t%0,%2,%1"
8122 [(set_attr "op_type" "RRF")])
8123
8124 ; ncrk, ncgrk, ocrk, ocgrk
8125 (define_insn "*<ANDOR:bitops_name>c<GPR:mode>_cconly"
8126 [(set (reg CC_REGNUM)
8127 (compare
8128 (ANDOR:GPR (not:GPR (match_operand:GPR 1 "register_operand" "d"))
8129 (match_operand:GPR 2 "register_operand" "d"))
8130 (const_int 0)))
8131 (clobber (match_scratch:GPR 0 "=d"))]
8132 "TARGET_Z15 && s390_match_ccmode(insn, CCTmode)"
8133 "<ANDOR:noxa>c<GPR:g>rk\t%0,%2,%1"
8134 [(set_attr "op_type" "RRF")])
8135
8136 ; ncrk, ncgrk, ocrk, ocgrk
8137 (define_insn "*<ANDOR:bitops_name>c<GPR:mode>"
8138 [(set (match_operand:GPR 0 "register_operand" "=d")
8139 (ANDOR:GPR (not:GPR (match_operand:GPR 1 "register_operand" "d"))
8140 (match_operand:GPR 2 "register_operand" "d")))
8141 (clobber (reg:CC CC_REGNUM))]
8142 "TARGET_Z15"
8143 "<ANDOR:noxa>c<GPR:g>rk\t%0,%2,%1"
8144 [(set_attr "op_type" "RRF")])
8145
8146 ;
8147 ;- Nand/Nor instructions.
8148 ;
8149
8150 ; nnrk, nngrk, nork, nogrk
8151 (define_insn "*n<ANDOR:inv_bitops_name><GPR:mode>_cc"
8152 [(set (reg CC_REGNUM)
8153 (compare
8154 (ANDOR:GPR (not:GPR (match_operand:GPR 1 "register_operand" "d"))
8155 (not:GPR (match_operand:GPR 2 "register_operand" "d")))
8156 (const_int 0)))
8157 (set (match_operand:GPR 0 "register_operand" "=d")
8158 (ANDOR:GPR (not:GPR (match_dup 1))
8159 (not:GPR (match_dup 2))))]
8160 "TARGET_Z15 && s390_match_ccmode(insn, CCTmode)"
8161 "n<ANDOR:inv_no><GPR:g>rk\t%0,%1,%2"
8162 [(set_attr "op_type" "RRF")])
8163
8164 ; nnrk, nngrk, nork, nogrk
8165 (define_insn "*n<ANDOR:inv_bitops_name><mode>_cconly"
8166 [(set (reg CC_REGNUM)
8167 (compare
8168 (ANDOR:GPR (not:GPR (match_operand:GPR 1 "register_operand" "d"))
8169 (not:GPR (match_operand:GPR 2 "register_operand" "d")))
8170 (const_int 0)))
8171 (clobber (match_scratch:GPR 0 "=d"))]
8172 "TARGET_Z15 && s390_match_ccmode(insn, CCTmode)"
8173 "n<ANDOR:inv_no><GPR:g>rk\t%0,%1,%2"
8174 [(set_attr "op_type" "RRF")])
8175
8176 ; nnrk, nngrk, nork, nogrk
8177 (define_insn "*n<ANDOR:inv_bitops_name><mode>"
8178 [(set (match_operand:GPR 0 "register_operand" "=d")
8179 (ANDOR:GPR (not:GPR (match_operand:GPR 1 "register_operand" "d"))
8180 (not:GPR (match_operand:GPR 2 "register_operand" "d"))))
8181 (clobber (reg:CC CC_REGNUM))]
8182 "TARGET_Z15"
8183 "n<ANDOR:inv_no><GPR:g>rk\t%0,%1,%2"
8184 [(set_attr "op_type" "RRF")])
8185
8186
8187 ;
8188 ; Block inclusive or (OC) patterns.
8189 ;
8190
8191 (define_insn "*oc"
8192 [(set (match_operand:BLK 0 "memory_operand" "=Q")
8193 (ior:BLK (match_dup 0)
8194 (match_operand:BLK 1 "memory_operand" "Q")))
8195 (use (match_operand 2 "const_int_operand" "n"))
8196 (clobber (reg:CC CC_REGNUM))]
8197 "INTVAL (operands[2]) >= 1 && INTVAL (operands[2]) <= 256"
8198 "oc\t%O0(%2,%R0),%S1"
8199 [(set_attr "op_type" "SS")
8200 (set_attr "z196prop" "z196_cracked")])
8201
8202 (define_split
8203 [(set (match_operand 0 "memory_operand" "")
8204 (ior (match_dup 0)
8205 (match_operand 1 "memory_operand" "")))
8206 (clobber (reg:CC CC_REGNUM))]
8207 "reload_completed
8208 && GET_MODE (operands[0]) == GET_MODE (operands[1])
8209 && GET_MODE_SIZE (GET_MODE (operands[0])) > 0"
8210 [(parallel
8211 [(set (match_dup 0) (ior:BLK (match_dup 0) (match_dup 1)))
8212 (use (match_dup 2))
8213 (clobber (reg:CC CC_REGNUM))])]
8214 {
8215 operands[2] = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[0])));
8216 operands[0] = adjust_address (operands[0], BLKmode, 0);
8217 operands[1] = adjust_address (operands[1], BLKmode, 0);
8218 })
8219
8220 (define_peephole2
8221 [(parallel
8222 [(set (match_operand:BLK 0 "memory_operand" "")
8223 (ior:BLK (match_dup 0)
8224 (match_operand:BLK 1 "memory_operand" "")))
8225 (use (match_operand 2 "const_int_operand" ""))
8226 (clobber (reg:CC CC_REGNUM))])
8227 (parallel
8228 [(set (match_operand:BLK 3 "memory_operand" "")
8229 (ior:BLK (match_dup 3)
8230 (match_operand:BLK 4 "memory_operand" "")))
8231 (use (match_operand 5 "const_int_operand" ""))
8232 (clobber (reg:CC CC_REGNUM))])]
8233 "s390_offset_p (operands[0], operands[3], operands[2])
8234 && s390_offset_p (operands[1], operands[4], operands[2])
8235 && !s390_overlap_p (operands[0], operands[1],
8236 INTVAL (operands[2]) + INTVAL (operands[5]))
8237 && INTVAL (operands[2]) + INTVAL (operands[5]) <= 256"
8238 [(parallel
8239 [(set (match_dup 6) (ior:BLK (match_dup 6) (match_dup 7)))
8240 (use (match_dup 8))
8241 (clobber (reg:CC CC_REGNUM))])]
8242 "operands[6] = gen_rtx_MEM (BLKmode, XEXP (operands[0], 0));
8243 operands[7] = gen_rtx_MEM (BLKmode, XEXP (operands[1], 0));
8244 operands[8] = GEN_INT (INTVAL (operands[2]) + INTVAL (operands[5]));")
8245
8246
8247 ;;
8248 ;;- Xor instructions.
8249 ;;
8250
8251 (define_expand "xor<mode>3"
8252 [(set (match_operand:INT 0 "nonimmediate_operand" "")
8253 (xor:INT (match_operand:INT 1 "nonimmediate_operand" "")
8254 (match_operand:INT 2 "general_operand" "")))
8255 (clobber (reg:CC CC_REGNUM))]
8256 ""
8257 "s390_expand_logical_operator (XOR, <MODE>mode, operands); DONE;")
8258
8259 ; Combine replaces (xor (x) (const_int -1)) with (not (x)) when doing
8260 ; simplifications. So its better to have something matching.
8261 (define_split
8262 [(set (match_operand:INT 0 "nonimmediate_operand" "")
8263 (not:INT (match_operand:INT 1 "nonimmediate_operand" "")))]
8264 ""
8265 [(parallel
8266 [(set (match_dup 0) (xor:INT (match_dup 1) (match_dup 2)))
8267 (clobber (reg:CC CC_REGNUM))])]
8268 {
8269 operands[2] = constm1_rtx;
8270 if (!s390_logical_operator_ok_p (operands))
8271 FAIL;
8272 })
8273
8274 ;
8275 ; xordi3 instruction pattern(s).
8276 ;
8277
8278 (define_insn "*xordi3_cc"
8279 [(set (reg CC_REGNUM)
8280 (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,d,0")
8281 (match_operand:DI 2 "general_operand" " d,d,T"))
8282 (const_int 0)))
8283 (set (match_operand:DI 0 "register_operand" "=d,d,d")
8284 (xor:DI (match_dup 1) (match_dup 2)))]
8285 "s390_match_ccmode(insn, CCTmode) && TARGET_ZARCH"
8286 "@
8287 xgr\t%0,%2
8288 xgrk\t%0,%1,%2
8289 xg\t%0,%2"
8290 [(set_attr "op_type" "RRE,RRF,RXY")
8291 (set_attr "cpu_facility" "*,z196,*")
8292 (set_attr "z10prop" "z10_super_E1,*,z10_super_E1")])
8293
8294 (define_insn "*xordi3_cconly"
8295 [(set (reg CC_REGNUM)
8296 (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,d,0")
8297 (match_operand:DI 2 "general_operand" " d,d,T"))
8298 (const_int 0)))
8299 (clobber (match_scratch:DI 0 "=d,d,d"))]
8300 "s390_match_ccmode(insn, CCTmode) && TARGET_ZARCH"
8301 "@
8302 xgr\t%0,%2
8303 xgrk\t%0,%1,%2
8304 xg\t%0,%2"
8305 [(set_attr "op_type" "RRE,RRF,RXY")
8306 (set_attr "cpu_facility" "*,z196,*")
8307 (set_attr "z10prop" "z10_super_E1,*,z10_super_E1")])
8308
8309 (define_insn "*xordi3"
8310 [(set (match_operand:DI 0 "nonimmediate_operand" "=d, d,d,d,d, AQ,Q")
8311 (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0, 0,0,d,0, 0,0")
8312 (match_operand:DI 2 "general_operand" "N0SD0,N1SD0,d,d,T,NxQD0,Q")))
8313 (clobber (reg:CC CC_REGNUM))]
8314 "TARGET_ZARCH && s390_logical_operator_ok_p (operands)"
8315 "@
8316 xihf\t%0,%k2
8317 xilf\t%0,%k2
8318 xgr\t%0,%2
8319 xgrk\t%0,%1,%2
8320 xg\t%0,%2
8321 #
8322 #"
8323 [(set_attr "op_type" "RIL,RIL,RRE,RRF,RXY,SI,SS")
8324 (set_attr "cpu_facility" "extimm,extimm,*,z196,*,*,*")
8325 (set_attr "z10prop" "z10_super_E1,z10_super_E1,z10_super_E1,
8326 *,z10_super_E1,*,*")])
8327
8328 (define_split
8329 [(set (match_operand:DI 0 "s_operand" "")
8330 (xor:DI (match_dup 0) (match_operand:DI 1 "immediate_operand" "")))
8331 (clobber (reg:CC CC_REGNUM))]
8332 "reload_completed"
8333 [(parallel
8334 [(set (match_dup 0) (xor:QI (match_dup 0) (match_dup 1)))
8335 (clobber (reg:CC CC_REGNUM))])]
8336 "s390_narrow_logical_operator (XOR, &operands[0], &operands[1]);")
8337
8338 ;
8339 ; xorsi3 instruction pattern(s).
8340 ;
8341
8342 (define_insn "*xorsi3_cc"
8343 [(set (reg CC_REGNUM)
8344 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,d,0,0")
8345 (match_operand:SI 2 "general_operand" "Os,d,d,R,T"))
8346 (const_int 0)))
8347 (set (match_operand:SI 0 "register_operand" "=d,d,d,d,d")
8348 (xor:SI (match_dup 1) (match_dup 2)))]
8349 "s390_match_ccmode(insn, CCTmode)"
8350 "@
8351 xilf\t%0,%o2
8352 xr\t%0,%2
8353 xrk\t%0,%1,%2
8354 x\t%0,%2
8355 xy\t%0,%2"
8356 [(set_attr "op_type" "RIL,RR,RRF,RX,RXY")
8357 (set_attr "cpu_facility" "*,*,z196,*,longdisp")
8358 (set_attr "z10prop" "z10_super_E1,z10_super_E1,*,
8359 z10_super_E1,z10_super_E1")])
8360
8361 (define_insn "*xorsi3_cconly"
8362 [(set (reg CC_REGNUM)
8363 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,d,0,0")
8364 (match_operand:SI 2 "general_operand" "Os,d,d,R,T"))
8365 (const_int 0)))
8366 (clobber (match_scratch:SI 0 "=d,d,d,d,d"))]
8367 "s390_match_ccmode(insn, CCTmode)"
8368 "@
8369 xilf\t%0,%o2
8370 xr\t%0,%2
8371 xrk\t%0,%1,%2
8372 x\t%0,%2
8373 xy\t%0,%2"
8374 [(set_attr "op_type" "RIL,RR,RRF,RX,RXY")
8375 (set_attr "cpu_facility" "*,*,z196,*,longdisp")
8376 (set_attr "z10prop" "z10_super_E1,z10_super_E1,*,
8377 z10_super_E1,z10_super_E1")])
8378
8379 (define_insn "*xorsi3"
8380 [(set (match_operand:SI 0 "nonimmediate_operand" "=d,d,d,d,d, AQ,Q")
8381 (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,d,0,0, 0,0")
8382 (match_operand:SI 2 "general_operand" "Os,d,d,R,T,NxQS0,Q")))
8383 (clobber (reg:CC CC_REGNUM))]
8384 "s390_logical_operator_ok_p (operands)"
8385 "@
8386 xilf\t%0,%o2
8387 xr\t%0,%2
8388 xrk\t%0,%1,%2
8389 x\t%0,%2
8390 xy\t%0,%2
8391 #
8392 #"
8393 [(set_attr "op_type" "RIL,RR,RRF,RX,RXY,SI,SS")
8394 (set_attr "cpu_facility" "*,*,z196,*,longdisp,*,*")
8395 (set_attr "z10prop" "z10_super_E1,z10_super_E1,*,
8396 z10_super_E1,z10_super_E1,*,*")])
8397
8398 (define_split
8399 [(set (match_operand:SI 0 "s_operand" "")
8400 (xor:SI (match_dup 0) (match_operand:SI 1 "immediate_operand" "")))
8401 (clobber (reg:CC CC_REGNUM))]
8402 "reload_completed"
8403 [(parallel
8404 [(set (match_dup 0) (xor:QI (match_dup 0) (match_dup 1)))
8405 (clobber (reg:CC CC_REGNUM))])]
8406 "s390_narrow_logical_operator (XOR, &operands[0], &operands[1]);")
8407
8408 ;
8409 ; xorhi3 instruction pattern(s).
8410 ;
8411
8412 (define_insn "*xorhi3"
8413 [(set (match_operand:HI 0 "nonimmediate_operand" "=d,d,d, AQ,Q")
8414 (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,d, 0,0")
8415 (match_operand:HI 2 "general_operand" "Os,d,d,NxQH0,Q")))
8416 (clobber (reg:CC CC_REGNUM))]
8417 "s390_logical_operator_ok_p (operands)"
8418 "@
8419 xilf\t%0,%x2
8420 xr\t%0,%2
8421 xrk\t%0,%1,%2
8422 #
8423 #"
8424 [(set_attr "op_type" "RIL,RR,RRF,SI,SS")
8425 (set_attr "cpu_facility" "*,*,z196,*,*")
8426 (set_attr "z10prop" "z10_super_E1,z10_super_E1,*,*,*")])
8427
8428 (define_split
8429 [(set (match_operand:HI 0 "s_operand" "")
8430 (xor:HI (match_dup 0) (match_operand:HI 1 "immediate_operand" "")))
8431 (clobber (reg:CC CC_REGNUM))]
8432 "reload_completed"
8433 [(parallel
8434 [(set (match_dup 0) (xor:QI (match_dup 0) (match_dup 1)))
8435 (clobber (reg:CC CC_REGNUM))])]
8436 "s390_narrow_logical_operator (XOR, &operands[0], &operands[1]);")
8437
8438 ;
8439 ; xorqi3 instruction pattern(s).
8440 ;
8441
8442 (define_insn "*xorqi3"
8443 [(set (match_operand:QI 0 "nonimmediate_operand" "=d,d,d,Q,S,Q")
8444 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,d,0,0,0")
8445 (match_operand:QI 2 "general_operand" "Os,d,d,n,n,Q")))
8446 (clobber (reg:CC CC_REGNUM))]
8447 "s390_logical_operator_ok_p (operands)"
8448 "@
8449 xilf\t%0,%b2
8450 xr\t%0,%2
8451 xrk\t%0,%1,%2
8452 xi\t%S0,%b2
8453 xiy\t%S0,%b2
8454 #"
8455 [(set_attr "op_type" "RIL,RR,RRF,SI,SIY,SS")
8456 (set_attr "cpu_facility" "*,*,z196,*,longdisp,*")
8457 (set_attr "z10prop" "z10_super_E1,z10_super_E1,*,z10_super,z10_super,*")])
8458
8459
8460 ;
8461 ; Block exclusive or (XC) patterns.
8462 ;
8463
8464 (define_insn "*xc"
8465 [(set (match_operand:BLK 0 "memory_operand" "=Q")
8466 (xor:BLK (match_dup 0)
8467 (match_operand:BLK 1 "memory_operand" "Q")))
8468 (use (match_operand 2 "const_int_operand" "n"))
8469 (clobber (reg:CC CC_REGNUM))]
8470 "INTVAL (operands[2]) >= 1 && INTVAL (operands[2]) <= 256"
8471 "xc\t%O0(%2,%R0),%S1"
8472 [(set_attr "op_type" "SS")])
8473
8474 (define_split
8475 [(set (match_operand 0 "memory_operand" "")
8476 (xor (match_dup 0)
8477 (match_operand 1 "memory_operand" "")))
8478 (clobber (reg:CC CC_REGNUM))]
8479 "reload_completed
8480 && GET_MODE (operands[0]) == GET_MODE (operands[1])
8481 && GET_MODE_SIZE (GET_MODE (operands[0])) > 0"
8482 [(parallel
8483 [(set (match_dup 0) (xor:BLK (match_dup 0) (match_dup 1)))
8484 (use (match_dup 2))
8485 (clobber (reg:CC CC_REGNUM))])]
8486 {
8487 operands[2] = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[0])));
8488 operands[0] = adjust_address (operands[0], BLKmode, 0);
8489 operands[1] = adjust_address (operands[1], BLKmode, 0);
8490 })
8491
8492 (define_peephole2
8493 [(parallel
8494 [(set (match_operand:BLK 0 "memory_operand" "")
8495 (xor:BLK (match_dup 0)
8496 (match_operand:BLK 1 "memory_operand" "")))
8497 (use (match_operand 2 "const_int_operand" ""))
8498 (clobber (reg:CC CC_REGNUM))])
8499 (parallel
8500 [(set (match_operand:BLK 3 "memory_operand" "")
8501 (xor:BLK (match_dup 3)
8502 (match_operand:BLK 4 "memory_operand" "")))
8503 (use (match_operand 5 "const_int_operand" ""))
8504 (clobber (reg:CC CC_REGNUM))])]
8505 "s390_offset_p (operands[0], operands[3], operands[2])
8506 && s390_offset_p (operands[1], operands[4], operands[2])
8507 && !s390_overlap_p (operands[0], operands[1],
8508 INTVAL (operands[2]) + INTVAL (operands[5]))
8509 && INTVAL (operands[2]) + INTVAL (operands[5]) <= 256"
8510 [(parallel
8511 [(set (match_dup 6) (xor:BLK (match_dup 6) (match_dup 7)))
8512 (use (match_dup 8))
8513 (clobber (reg:CC CC_REGNUM))])]
8514 "operands[6] = gen_rtx_MEM (BLKmode, XEXP (operands[0], 0));
8515 operands[7] = gen_rtx_MEM (BLKmode, XEXP (operands[1], 0));
8516 operands[8] = GEN_INT (INTVAL (operands[2]) + INTVAL (operands[5]));")
8517
8518 ;
8519 ; Block xor (XC) patterns with src == dest.
8520 ;
8521
8522 (define_insn "*xc_zero"
8523 [(set (match_operand:BLK 0 "memory_operand" "=Q")
8524 (const_int 0))
8525 (use (match_operand 1 "const_int_operand" "n"))
8526 (clobber (reg:CC CC_REGNUM))]
8527 "INTVAL (operands[1]) >= 1 && INTVAL (operands[1]) <= 256"
8528 "xc\t%O0(%1,%R0),%S0"
8529 [(set_attr "op_type" "SS")
8530 (set_attr "z196prop" "z196_cracked")])
8531
8532 (define_peephole2
8533 [(parallel
8534 [(set (match_operand:BLK 0 "memory_operand" "")
8535 (const_int 0))
8536 (use (match_operand 1 "const_int_operand" ""))
8537 (clobber (reg:CC CC_REGNUM))])
8538 (parallel
8539 [(set (match_operand:BLK 2 "memory_operand" "")
8540 (const_int 0))
8541 (use (match_operand 3 "const_int_operand" ""))
8542 (clobber (reg:CC CC_REGNUM))])]
8543 "s390_offset_p (operands[0], operands[2], operands[1])
8544 && INTVAL (operands[1]) + INTVAL (operands[3]) <= 256"
8545 [(parallel
8546 [(set (match_dup 4) (const_int 0))
8547 (use (match_dup 5))
8548 (clobber (reg:CC CC_REGNUM))])]
8549 "operands[4] = gen_rtx_MEM (BLKmode, XEXP (operands[0], 0));
8550 operands[5] = GEN_INT (INTVAL (operands[1]) + INTVAL (operands[3]));")
8551
8552 ;
8553 ;- Nxor instructions.
8554 ;
8555
8556 ; nxrk, nxgrk
8557 (define_insn "*nxor<GPR:mode>_cc"
8558 [(set (reg CC_REGNUM)
8559 (compare
8560 (not:GPR (xor:GPR (match_operand:GPR 1 "register_operand" "d")
8561 (match_operand:GPR 2 "register_operand" "d")))
8562 (const_int 0)))
8563 (set (match_operand:GPR 0 "register_operand" "=d")
8564 (xor:GPR (not:GPR (match_dup 1))
8565 (match_dup 2)))]
8566 "TARGET_Z15 && s390_match_ccmode(insn, CCTmode)"
8567 "nx<GPR:g>rk\t%0,%1,%2"
8568 [(set_attr "op_type" "RRF")])
8569
8570 ; nxrk, nxgrk
8571 (define_insn "*nxor<mode>_cconly"
8572 [(set (reg CC_REGNUM)
8573 (compare
8574 (not:GPR (xor:GPR (match_operand:GPR 1 "register_operand" "d")
8575 (match_operand:GPR 2 "register_operand" "d")))
8576 (const_int 0)))
8577 (clobber (match_scratch:GPR 0 "=d"))]
8578 "TARGET_Z15 && s390_match_ccmode(insn, CCTmode)"
8579 "nx<GPR:g>rk\t%0,%1,%2"
8580 [(set_attr "op_type" "RRF")])
8581
8582 ; nxrk, nxgrk
8583 (define_insn "*nxor<mode>"
8584 [(set (match_operand:GPR 0 "register_operand" "=d")
8585 (not:GPR (xor:GPR (match_operand:GPR 1 "register_operand" "d")
8586 (match_operand:GPR 2 "register_operand" "d"))))
8587 (clobber (reg:CC CC_REGNUM))]
8588 "TARGET_Z15"
8589 "nx<GPR:g>rk\t%0,%1,%2"
8590 [(set_attr "op_type" "RRF")])
8591
8592 ;;
8593 ;;- Negate instructions.
8594 ;;
8595
8596 ;
8597 ; neg(di|si)2 instruction pattern(s).
8598 ;
8599
8600 (define_expand "neg<mode>2"
8601 [(parallel
8602 [(set (match_operand:DSI 0 "register_operand" "=d")
8603 (neg:DSI (match_operand:DSI 1 "register_operand" "d")))
8604 (clobber (reg:CC CC_REGNUM))])]
8605 ""
8606 "")
8607
8608 (define_insn "*negdi2_sign_cc"
8609 [(set (reg CC_REGNUM)
8610 (compare (neg:DI (ashiftrt:DI (ashift:DI (subreg:DI
8611 (match_operand:SI 1 "register_operand" "d") 0)
8612 (const_int 32)) (const_int 32)))
8613 (const_int 0)))
8614 (set (match_operand:DI 0 "register_operand" "=d")
8615 (neg:DI (sign_extend:DI (match_dup 1))))]
8616 "TARGET_ZARCH && s390_match_ccmode (insn, CCAmode)"
8617 "lcgfr\t%0,%1"
8618 [(set_attr "op_type" "RRE")
8619 (set_attr "z10prop" "z10_c")])
8620
8621 (define_insn "*negdi2_sign"
8622 [(set (match_operand:DI 0 "register_operand" "=d")
8623 (neg:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "d"))))
8624 (clobber (reg:CC CC_REGNUM))]
8625 "TARGET_ZARCH"
8626 "lcgfr\t%0,%1"
8627 [(set_attr "op_type" "RRE")
8628 (set_attr "z10prop" "z10_c")])
8629
8630 ; lcr, lcgr
8631 (define_insn "*neg<mode>2_cc"
8632 [(set (reg CC_REGNUM)
8633 (compare (neg:GPR (match_operand:GPR 1 "register_operand" "d"))
8634 (const_int 0)))
8635 (set (match_operand:GPR 0 "register_operand" "=d")
8636 (neg:GPR (match_dup 1)))]
8637 "s390_match_ccmode (insn, CCAmode)"
8638 "lc<g>r\t%0,%1"
8639 [(set_attr "op_type" "RR<E>")
8640 (set_attr "z10prop" "z10_super_c_E1")])
8641
8642 ; lcr, lcgr
8643 (define_insn "*neg<mode>2_cconly"
8644 [(set (reg CC_REGNUM)
8645 (compare (neg:GPR (match_operand:GPR 1 "register_operand" "d"))
8646 (const_int 0)))
8647 (clobber (match_scratch:GPR 0 "=d"))]
8648 "s390_match_ccmode (insn, CCAmode)"
8649 "lc<g>r\t%0,%1"
8650 [(set_attr "op_type" "RR<E>")
8651 (set_attr "z10prop" "z10_super_c_E1")])
8652
8653 ; lcr, lcgr
8654 (define_insn "*neg<mode>2"
8655 [(set (match_operand:GPR 0 "register_operand" "=d")
8656 (neg:GPR (match_operand:GPR 1 "register_operand" "d")))
8657 (clobber (reg:CC CC_REGNUM))]
8658 ""
8659 "lc<g>r\t%0,%1"
8660 [(set_attr "op_type" "RR<E>")
8661 (set_attr "z10prop" "z10_super_c_E1")])
8662
8663 (define_insn "*negdi2_31"
8664 [(set (match_operand:DI 0 "register_operand" "=d")
8665 (neg:DI (match_operand:DI 1 "register_operand" "d")))
8666 (clobber (reg:CC CC_REGNUM))]
8667 "!TARGET_ZARCH"
8668 "#")
8669
8670 ; Split a DImode NEG on 31bit into 2 SImode NEGs
8671
8672 ; Doing the twos complement separately on the SImode parts does an
8673 ; unwanted +1 on the high part which needs to be subtracted afterwards
8674 ; ... unless the +1 on the low part created an overflow.
8675
8676 (define_split
8677 [(set (match_operand:DI 0 "register_operand" "")
8678 (neg:DI (match_operand:DI 1 "register_operand" "")))
8679 (clobber (reg:CC CC_REGNUM))]
8680 "!TARGET_ZARCH
8681 && (REGNO (operands[0]) == REGNO (operands[1])
8682 || s390_split_ok_p (operands[0], operands[1], DImode, 0))
8683 && reload_completed"
8684 [(parallel
8685 [(set (match_dup 2) (neg:SI (match_dup 3)))
8686 (clobber (reg:CC CC_REGNUM))])
8687 (parallel
8688 [(set (reg:CCAP CC_REGNUM)
8689 (compare:CCAP (neg:SI (match_dup 5)) (const_int 0)))
8690 (set (match_dup 4) (neg:SI (match_dup 5)))])
8691 (set (pc)
8692 (if_then_else (ne (reg:CCAP CC_REGNUM) (const_int 0))
8693 (pc)
8694 (label_ref (match_dup 6))))
8695 (parallel
8696 [(set (match_dup 2) (plus:SI (match_dup 2) (const_int -1)))
8697 (clobber (reg:CC CC_REGNUM))])
8698 (match_dup 6)]
8699 "operands[2] = operand_subword (operands[0], 0, 0, DImode);
8700 operands[3] = operand_subword (operands[1], 0, 0, DImode);
8701 operands[4] = operand_subword (operands[0], 1, 0, DImode);
8702 operands[5] = operand_subword (operands[1], 1, 0, DImode);
8703 operands[6] = gen_label_rtx ();")
8704
8705 ; Like above but first make a copy of the low part of the src operand
8706 ; since it might overlap with the high part of the destination.
8707
8708 (define_split
8709 [(set (match_operand:DI 0 "register_operand" "")
8710 (neg:DI (match_operand:DI 1 "register_operand" "")))
8711 (clobber (reg:CC CC_REGNUM))]
8712 "!TARGET_ZARCH
8713 && s390_split_ok_p (operands[0], operands[1], DImode, 1)
8714 && reload_completed"
8715 [; Make a backup of op5 first
8716 (set (match_dup 4) (match_dup 5))
8717 ; Setting op2 here might clobber op5
8718 (parallel
8719 [(set (match_dup 2) (neg:SI (match_dup 3)))
8720 (clobber (reg:CC CC_REGNUM))])
8721 (parallel
8722 [(set (reg:CCAP CC_REGNUM)
8723 (compare:CCAP (neg:SI (match_dup 4)) (const_int 0)))
8724 (set (match_dup 4) (neg:SI (match_dup 4)))])
8725 (set (pc)
8726 (if_then_else (ne (reg:CCAP CC_REGNUM) (const_int 0))
8727 (pc)
8728 (label_ref (match_dup 6))))
8729 (parallel
8730 [(set (match_dup 2) (plus:SI (match_dup 2) (const_int -1)))
8731 (clobber (reg:CC CC_REGNUM))])
8732 (match_dup 6)]
8733 "operands[2] = operand_subword (operands[0], 0, 0, DImode);
8734 operands[3] = operand_subword (operands[1], 0, 0, DImode);
8735 operands[4] = operand_subword (operands[0], 1, 0, DImode);
8736 operands[5] = operand_subword (operands[1], 1, 0, DImode);
8737 operands[6] = gen_label_rtx ();")
8738
8739 ;
8740 ; neg(df|sf)2 instruction pattern(s).
8741 ;
8742
8743 (define_expand "neg<mode>2"
8744 [(parallel
8745 [(set (match_operand:BFP 0 "register_operand")
8746 (neg:BFP (match_operand:BFP 1 "register_operand")))
8747 (clobber (reg:CC CC_REGNUM))])]
8748 "TARGET_HARD_FLOAT")
8749
8750 ; lcxbr, lcdbr, lcebr
8751 (define_insn "*neg<mode>2_cc"
8752 [(set (reg CC_REGNUM)
8753 (compare (neg:BFP (match_operand:BFP 1 "register_operand" "f"))
8754 (match_operand:BFP 2 "const0_operand" "")))
8755 (set (match_operand:BFP 0 "register_operand" "=f")
8756 (neg:BFP (match_dup 1)))]
8757 "s390_match_ccmode (insn, CCSmode) && TARGET_HARD_FLOAT"
8758 "lc<xde>br\t%0,%1"
8759 [(set_attr "op_type" "RRE")
8760 (set_attr "type" "fsimp<mode>")])
8761
8762 ; lcxbr, lcdbr, lcebr
8763 (define_insn "*neg<mode>2_cconly"
8764 [(set (reg CC_REGNUM)
8765 (compare (neg:BFP (match_operand:BFP 1 "register_operand" "f"))
8766 (match_operand:BFP 2 "const0_operand" "")))
8767 (clobber (match_scratch:BFP 0 "=f"))]
8768 "s390_match_ccmode (insn, CCSmode) && TARGET_HARD_FLOAT"
8769 "lc<xde>br\t%0,%1"
8770 [(set_attr "op_type" "RRE")
8771 (set_attr "type" "fsimp<mode>")])
8772
8773 ; lcdfr
8774 (define_insn "*neg<mode>2_nocc"
8775 [(set (match_operand:FP 0 "register_operand" "=f")
8776 (neg:FP (match_operand:FP 1 "register_operand" "<fT0>")))]
8777 "TARGET_DFP"
8778 "lcdfr\t%0,%1"
8779 [(set_attr "op_type" "RRE")
8780 (set_attr "type" "fsimp<mode>")])
8781
8782 ; lcxbr, lcdbr, lcebr
8783 ; FIXME: wflcdb does not clobber cc
8784 ; FIXME: Does wflcdb ever match here?
8785 (define_insn "*neg<mode>2"
8786 [(set (match_operand:BFP 0 "register_operand" "=f,v,v")
8787 (neg:BFP (match_operand:BFP 1 "register_operand" "f,v,v")))
8788 (clobber (reg:CC CC_REGNUM))]
8789 "TARGET_HARD_FLOAT"
8790 "@
8791 lc<xde>br\t%0,%1
8792 wflcdb\t%0,%1
8793 wflcsb\t%0,%1"
8794 [(set_attr "op_type" "RRE,VRR,VRR")
8795 (set_attr "cpu_facility" "*,vx,vxe")
8796 (set_attr "type" "fsimp<mode>,*,*")
8797 (set_attr "enabled" "*,<DF>,<SF>")])
8798
8799
8800 ;;
8801 ;;- Absolute value instructions.
8802 ;;
8803
8804 ;
8805 ; abs(di|si)2 instruction pattern(s).
8806 ;
8807
8808 (define_insn "*absdi2_sign_cc"
8809 [(set (reg CC_REGNUM)
8810 (compare (abs:DI (ashiftrt:DI (ashift:DI (subreg:DI
8811 (match_operand:SI 1 "register_operand" "d") 0)
8812 (const_int 32)) (const_int 32)))
8813 (const_int 0)))
8814 (set (match_operand:DI 0 "register_operand" "=d")
8815 (abs:DI (sign_extend:DI (match_dup 1))))]
8816 "TARGET_ZARCH && s390_match_ccmode (insn, CCAmode)"
8817 "lpgfr\t%0,%1"
8818 [(set_attr "op_type" "RRE")
8819 (set_attr "z10prop" "z10_c")])
8820
8821 (define_insn "*absdi2_sign"
8822 [(set (match_operand:DI 0 "register_operand" "=d")
8823 (abs:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "d"))))
8824 (clobber (reg:CC CC_REGNUM))]
8825 "TARGET_ZARCH"
8826 "lpgfr\t%0,%1"
8827 [(set_attr "op_type" "RRE")
8828 (set_attr "z10prop" "z10_c")])
8829
8830 ; lpr, lpgr
8831 (define_insn "*abs<mode>2_cc"
8832 [(set (reg CC_REGNUM)
8833 (compare (abs:GPR (match_operand:DI 1 "register_operand" "d"))
8834 (const_int 0)))
8835 (set (match_operand:GPR 0 "register_operand" "=d")
8836 (abs:GPR (match_dup 1)))]
8837 "s390_match_ccmode (insn, CCAmode)"
8838 "lp<g>r\t%0,%1"
8839 [(set_attr "op_type" "RR<E>")
8840 (set_attr "z10prop" "z10_c")])
8841
8842 ; lpr, lpgr
8843 (define_insn "*abs<mode>2_cconly"
8844 [(set (reg CC_REGNUM)
8845 (compare (abs:GPR (match_operand:GPR 1 "register_operand" "d"))
8846 (const_int 0)))
8847 (clobber (match_scratch:GPR 0 "=d"))]
8848 "s390_match_ccmode (insn, CCAmode)"
8849 "lp<g>r\t%0,%1"
8850 [(set_attr "op_type" "RR<E>")
8851 (set_attr "z10prop" "z10_c")])
8852
8853 ; lpr, lpgr
8854 (define_insn "abs<mode>2"
8855 [(set (match_operand:GPR 0 "register_operand" "=d")
8856 (abs:GPR (match_operand:GPR 1 "register_operand" "d")))
8857 (clobber (reg:CC CC_REGNUM))]
8858 ""
8859 "lp<g>r\t%0,%1"
8860 [(set_attr "op_type" "RR<E>")
8861 (set_attr "z10prop" "z10_c")])
8862
8863 ;
8864 ; abs(df|sf)2 instruction pattern(s).
8865 ;
8866
8867 (define_expand "abs<mode>2"
8868 [(parallel
8869 [(set (match_operand:BFP 0 "register_operand" "=f")
8870 (abs:BFP (match_operand:BFP 1 "register_operand" "f")))
8871 (clobber (reg:CC CC_REGNUM))])]
8872 "TARGET_HARD_FLOAT"
8873 "")
8874
8875 ; lpxbr, lpdbr, lpebr
8876 (define_insn "*abs<mode>2_cc"
8877 [(set (reg CC_REGNUM)
8878 (compare (abs:BFP (match_operand:BFP 1 "register_operand" "f"))
8879 (match_operand:BFP 2 "const0_operand" "")))
8880 (set (match_operand:BFP 0 "register_operand" "=f")
8881 (abs:BFP (match_dup 1)))]
8882 "s390_match_ccmode (insn, CCSmode) && TARGET_HARD_FLOAT"
8883 "lp<xde>br\t%0,%1"
8884 [(set_attr "op_type" "RRE")
8885 (set_attr "type" "fsimp<mode>")])
8886
8887 ; lpxbr, lpdbr, lpebr
8888 (define_insn "*abs<mode>2_cconly"
8889 [(set (reg CC_REGNUM)
8890 (compare (abs:BFP (match_operand:BFP 1 "register_operand" "f"))
8891 (match_operand:BFP 2 "const0_operand" "")))
8892 (clobber (match_scratch:BFP 0 "=f"))]
8893 "s390_match_ccmode (insn, CCSmode) && TARGET_HARD_FLOAT"
8894 "lp<xde>br\t%0,%1"
8895 [(set_attr "op_type" "RRE")
8896 (set_attr "type" "fsimp<mode>")])
8897
8898 ; lpdfr
8899 (define_insn "*abs<mode>2_nocc"
8900 [(set (match_operand:FP 0 "register_operand" "=f")
8901 (abs:FP (match_operand:FP 1 "register_operand" "<fT0>")))]
8902 "TARGET_DFP"
8903 "lpdfr\t%0,%1"
8904 [(set_attr "op_type" "RRE")
8905 (set_attr "type" "fsimp<mode>")])
8906
8907 ; lpxbr, lpdbr, lpebr
8908 ; FIXME: wflpdb does not clobber cc
8909 (define_insn "*abs<mode>2"
8910 [(set (match_operand:BFP 0 "register_operand" "=f,v")
8911 (abs:BFP (match_operand:BFP 1 "register_operand" "f,v")))
8912 (clobber (reg:CC CC_REGNUM))]
8913 "TARGET_HARD_FLOAT"
8914 "@
8915 lp<xde>br\t%0,%1
8916 wflpdb\t%0,%1"
8917 [(set_attr "op_type" "RRE,VRR")
8918 (set_attr "cpu_facility" "*,vx")
8919 (set_attr "type" "fsimp<mode>,*")
8920 (set_attr "enabled" "*,<DFDI>")])
8921
8922
8923 ;;
8924 ;;- Negated absolute value instructions
8925 ;;
8926
8927 ;
8928 ; Integer
8929 ;
8930
8931 (define_insn "*negabsdi2_sign_cc"
8932 [(set (reg CC_REGNUM)
8933 (compare (neg:DI (abs:DI (ashiftrt:DI (ashift:DI (subreg:DI
8934 (match_operand:SI 1 "register_operand" "d") 0)
8935 (const_int 32)) (const_int 32))))
8936 (const_int 0)))
8937 (set (match_operand:DI 0 "register_operand" "=d")
8938 (neg:DI (abs:DI (sign_extend:DI (match_dup 1)))))]
8939 "TARGET_ZARCH && s390_match_ccmode (insn, CCAmode)"
8940 "lngfr\t%0,%1"
8941 [(set_attr "op_type" "RRE")
8942 (set_attr "z10prop" "z10_c")])
8943
8944 (define_insn "*negabsdi2_sign"
8945 [(set (match_operand:DI 0 "register_operand" "=d")
8946 (neg:DI (abs:DI (sign_extend:DI
8947 (match_operand:SI 1 "register_operand" "d")))))
8948 (clobber (reg:CC CC_REGNUM))]
8949 "TARGET_ZARCH"
8950 "lngfr\t%0,%1"
8951 [(set_attr "op_type" "RRE")
8952 (set_attr "z10prop" "z10_c")])
8953
8954 ; lnr, lngr
8955 (define_insn "*negabs<mode>2_cc"
8956 [(set (reg CC_REGNUM)
8957 (compare (neg:GPR (abs:GPR (match_operand:GPR 1 "register_operand" "d")))
8958 (const_int 0)))
8959 (set (match_operand:GPR 0 "register_operand" "=d")
8960 (neg:GPR (abs:GPR (match_dup 1))))]
8961 "s390_match_ccmode (insn, CCAmode)"
8962 "ln<g>r\t%0,%1"
8963 [(set_attr "op_type" "RR<E>")
8964 (set_attr "z10prop" "z10_c")])
8965
8966 ; lnr, lngr
8967 (define_insn "*negabs<mode>2_cconly"
8968 [(set (reg CC_REGNUM)
8969 (compare (neg:GPR (abs:GPR (match_operand:GPR 1 "register_operand" "d")))
8970 (const_int 0)))
8971 (clobber (match_scratch:GPR 0 "=d"))]
8972 "s390_match_ccmode (insn, CCAmode)"
8973 "ln<g>r\t%0,%1"
8974 [(set_attr "op_type" "RR<E>")
8975 (set_attr "z10prop" "z10_c")])
8976
8977 ; lnr, lngr
8978 (define_insn "*negabs<mode>2"
8979 [(set (match_operand:GPR 0 "register_operand" "=d")
8980 (neg:GPR (abs:GPR (match_operand:GPR 1 "register_operand" "d"))))
8981 (clobber (reg:CC CC_REGNUM))]
8982 ""
8983 "ln<g>r\t%0,%1"
8984 [(set_attr "op_type" "RR<E>")
8985 (set_attr "z10prop" "z10_c")])
8986
8987 ;
8988 ; Floating point
8989 ;
8990
8991 ; lnxbr, lndbr, lnebr
8992 (define_insn "*negabs<mode>2_cc"
8993 [(set (reg CC_REGNUM)
8994 (compare (neg:BFP (abs:BFP (match_operand:BFP 1 "register_operand" "f")))
8995 (match_operand:BFP 2 "const0_operand" "")))
8996 (set (match_operand:BFP 0 "register_operand" "=f")
8997 (neg:BFP (abs:BFP (match_dup 1))))]
8998 "s390_match_ccmode (insn, CCSmode) && TARGET_HARD_FLOAT"
8999 "ln<xde>br\t%0,%1"
9000 [(set_attr "op_type" "RRE")
9001 (set_attr "type" "fsimp<mode>")])
9002
9003 ; lnxbr, lndbr, lnebr
9004 (define_insn "*negabs<mode>2_cconly"
9005 [(set (reg CC_REGNUM)
9006 (compare (neg:BFP (abs:BFP (match_operand:BFP 1 "register_operand" "f")))
9007 (match_operand:BFP 2 "const0_operand" "")))
9008 (clobber (match_scratch:BFP 0 "=f"))]
9009 "s390_match_ccmode (insn, CCSmode) && TARGET_HARD_FLOAT"
9010 "ln<xde>br\t%0,%1"
9011 [(set_attr "op_type" "RRE")
9012 (set_attr "type" "fsimp<mode>")])
9013
9014 ; lndfr
9015 (define_insn "*negabs<mode>2_nocc"
9016 [(set (match_operand:FP 0 "register_operand" "=f")
9017 (neg:FP (abs:FP (match_operand:FP 1 "register_operand" "<fT0>"))))]
9018 "TARGET_DFP"
9019 "lndfr\t%0,%1"
9020 [(set_attr "op_type" "RRE")
9021 (set_attr "type" "fsimp<mode>")])
9022
9023 ; lnxbr, lndbr, lnebr
9024 ; FIXME: wflndb does not clobber cc
9025 (define_insn "*negabs<mode>2"
9026 [(set (match_operand:BFP 0 "register_operand" "=f,v")
9027 (neg:BFP (abs:BFP (match_operand:BFP 1 "register_operand" "f,v"))))
9028 (clobber (reg:CC CC_REGNUM))]
9029 "TARGET_HARD_FLOAT"
9030 "@
9031 ln<xde>br\t%0,%1
9032 wflndb\t%0,%1"
9033 [(set_attr "op_type" "RRE,VRR")
9034 (set_attr "cpu_facility" "*,vx")
9035 (set_attr "type" "fsimp<mode>,*")
9036 (set_attr "enabled" "*,<DFDI>")])
9037
9038 ;;
9039 ;;- Square root instructions.
9040 ;;
9041
9042 ;
9043 ; sqrt(df|sf)2 instruction pattern(s).
9044 ;
9045
9046 ; sqxbr, sqdbr, sqebr, sqdb, sqeb
9047 (define_insn "sqrt<mode>2"
9048 [(set (match_operand:BFP 0 "register_operand" "=f,f,v")
9049 (sqrt:BFP (match_operand:BFP 1 "general_operand" "f,R,v")))]
9050 "TARGET_HARD_FLOAT"
9051 "@
9052 sq<xde>br\t%0,%1
9053 sq<xde>b\t%0,%1
9054 wfsqdb\t%v0,%v1"
9055 [(set_attr "op_type" "RRE,RXE,VRR")
9056 (set_attr "type" "fsqrt<mode>")
9057 (set_attr "cpu_facility" "*,*,vx")
9058 (set_attr "enabled" "*,<DSF>,<DFDI>")])
9059
9060
9061 ;;
9062 ;;- One complement instructions.
9063 ;;
9064
9065 ;
9066 ; one_cmpl(di|si|hi|qi)2 instruction pattern(s).
9067 ;
9068
9069 (define_expand "one_cmpl<mode>2"
9070 [(parallel
9071 [(set (match_operand:INT 0 "register_operand" "")
9072 (xor:INT (match_operand:INT 1 "register_operand" "")
9073 (const_int -1)))
9074 (clobber (reg:CC CC_REGNUM))])]
9075 ""
9076 "")
9077
9078
9079 ;;
9080 ;; Find leftmost bit instructions.
9081 ;;
9082
9083 (define_expand "clzdi2"
9084 [(set (match_operand:DI 0 "register_operand" "=d")
9085 (clz:DI (match_operand:DI 1 "register_operand" "d")))]
9086 "TARGET_EXTIMM && TARGET_ZARCH"
9087 {
9088 rtx_insn *insn;
9089 rtx clz_equal;
9090 rtx wide_reg = gen_reg_rtx (TImode);
9091 rtx msb = gen_rtx_CONST_INT (DImode, HOST_WIDE_INT_1U << 63);
9092
9093 clz_equal = gen_rtx_CLZ (DImode, operands[1]);
9094
9095 emit_insn (gen_clztidi2 (wide_reg, operands[1], msb));
9096
9097 insn = emit_move_insn (operands[0], gen_highpart (DImode, wide_reg));
9098 set_unique_reg_note (insn, REG_EQUAL, clz_equal);
9099
9100 DONE;
9101 })
9102
9103 ; CLZ result is in hard reg op0 - this is the high part of the target operand
9104 ; The source with the left-most one bit cleared is in hard reg op0 + 1 - the low part
9105 (define_insn "clztidi2"
9106 [(set (match_operand:TI 0 "register_operand" "=d")
9107 (ior:TI
9108 (ashift:TI (zero_extend:TI (clz:DI (match_operand:DI 1 "register_operand" "d")))
9109 (const_int 64))
9110 (zero_extend:TI
9111 (xor:DI (match_dup 1)
9112 (lshiftrt (match_operand:DI 2 "const_int_operand" "")
9113 (subreg:SI (clz:DI (match_dup 1)) 4))))))
9114 (clobber (reg:CC CC_REGNUM))]
9115 "UINTVAL (operands[2]) == HOST_WIDE_INT_1U << 63
9116 && TARGET_EXTIMM && TARGET_ZARCH"
9117 "flogr\t%0,%1"
9118 [(set_attr "op_type" "RRE")])
9119
9120
9121 ;;
9122 ;;- Rotate instructions.
9123 ;;
9124
9125 ;
9126 ; rotl(di|si)3 instruction pattern(s).
9127 ;
9128
9129 (define_expand "rotl<mode>3"
9130 [(set (match_operand:GPR 0 "register_operand" "")
9131 (rotate:GPR (match_operand:GPR 1 "register_operand" "")
9132 (match_operand:QI 2 "shift_count_operand" "")))]
9133 ""
9134 "")
9135
9136 ; rll, rllg
9137 (define_insn "*rotl<mode>3"
9138 [(set (match_operand:GPR 0 "register_operand" "=d")
9139 (rotate:GPR (match_operand:GPR 1 "register_operand" "d")
9140 (match_operand:QI 2 "shift_count_operand" "jsc")))]
9141 ""
9142 "rll<g>\t%0,%1,%Y2"
9143 [(set_attr "op_type" "RSE")
9144 (set_attr "atype" "reg")
9145 (set_attr "z10prop" "z10_super_E1")])
9146
9147
9148 ;;
9149 ;;- Shift instructions.
9150 ;;
9151
9152 ;
9153 ; (ashl|lshr)(di|si)3 instruction pattern(s).
9154 ; Left shifts and logical right shifts
9155
9156 (define_expand "<shift><mode>3"
9157 [(set (match_operand:DSI 0 "register_operand" "")
9158 (SHIFT:DSI (match_operand:DSI 1 "register_operand" "")
9159 (match_operand:QI 2 "shift_count_operand" "")))]
9160 ""
9161 "")
9162
9163 ; ESA 64 bit register pair shift with reg or imm shift count
9164 ; sldl, srdl
9165 (define_insn "*<shift>di3_31"
9166 [(set (match_operand:DI 0 "register_operand" "=d")
9167 (SHIFT:DI (match_operand:DI 1 "register_operand" "0")
9168 (match_operand:QI 2 "shift_count_operand" "jsc")))]
9169 "!TARGET_ZARCH"
9170 "s<lr>dl\t%0,%Y2"
9171 [(set_attr "op_type" "RS")
9172 (set_attr "atype" "reg")
9173 (set_attr "z196prop" "z196_cracked")])
9174
9175
9176 ; 64 bit register shift with reg or imm shift count
9177 ; sll, srl, sllg, srlg, sllk, srlk
9178 (define_insn "*<shift><mode>3"
9179 [(set (match_operand:GPR 0 "register_operand" "=d, d")
9180 (SHIFT:GPR (match_operand:GPR 1 "register_operand" "<d0>, d")
9181 (match_operand:QI 2 "shift_count_operand" "jsc,jsc")))]
9182 ""
9183 "@
9184 s<lr>l<g>\t%0,<1>%Y2
9185 s<lr>l<gk>\t%0,%1,%Y2"
9186 [(set_attr "op_type" "RS<E>,RSY")
9187 (set_attr "atype" "reg,reg")
9188 (set_attr "cpu_facility" "*,z196")
9189 (set_attr "z10prop" "z10_super_E1,*")])
9190
9191
9192 ;
9193 ; ashr(di|si)3 instruction pattern(s).
9194 ; Arithmetic right shifts
9195
9196 (define_expand "ashr<mode>3"
9197 [(parallel
9198 [(set (match_operand:DSI 0 "register_operand" "")
9199 (ashiftrt:DSI (match_operand:DSI 1 "register_operand" "")
9200 (match_operand:QI 2 "shift_count_operand" "")))
9201 (clobber (reg:CC CC_REGNUM))])]
9202 ""
9203 "")
9204
9205 ; FIXME: The number of alternatives is doubled here to match the fix
9206 ; number of 2 in the subst pattern for the (clobber (match_scratch...
9207 ; The right fix should be to support match_scratch in the output
9208 ; pattern of a define_subst.
9209 (define_insn "*ashrdi3_31<setcc><cconly>"
9210 [(set (match_operand:DI 0 "register_operand" "=d, d")
9211 (ashiftrt:DI (match_operand:DI 1 "register_operand" "0, 0")
9212 (match_operand:QI 2 "shift_count_operand" "jsc,jsc")))
9213 (clobber (reg:CC CC_REGNUM))]
9214 "!TARGET_ZARCH"
9215 "@
9216 srda\t%0,%Y2
9217 srda\t%0,%Y2"
9218 [(set_attr "op_type" "RS")
9219 (set_attr "atype" "reg")])
9220
9221
9222 ; sra, srag
9223 (define_insn "*ashr<mode>3<setcc><cconly>"
9224 [(set (match_operand:GPR 0 "register_operand" "=d, d")
9225 (ashiftrt:GPR (match_operand:GPR 1 "register_operand" "<d0>, d")
9226 (match_operand:QI 2 "shift_count_operand" "jsc,jsc")))
9227 (clobber (reg:CC CC_REGNUM))]
9228 ""
9229 "@
9230 sra<g>\t%0,<1>%Y2
9231 sra<gk>\t%0,%1,%Y2"
9232 [(set_attr "op_type" "RS<E>,RSY")
9233 (set_attr "atype" "reg")
9234 (set_attr "cpu_facility" "*,z196")
9235 (set_attr "z10prop" "z10_super_E1,*")])
9236
9237
9238 ;;
9239 ;; Branch instruction patterns.
9240 ;;
9241
9242 (define_expand "cbranch<mode>4"
9243 [(set (pc)
9244 (if_then_else (match_operator 0 "comparison_operator"
9245 [(match_operand:GPR 1 "register_operand" "")
9246 (match_operand:GPR 2 "general_operand" "")])
9247 (label_ref (match_operand 3 "" ""))
9248 (pc)))]
9249 ""
9250 "s390_emit_jump (operands[3],
9251 s390_emit_compare (GET_CODE (operands[0]), operands[1], operands[2]));
9252 DONE;")
9253
9254 (define_expand "cbranch<mode>4"
9255 [(set (pc)
9256 (if_then_else (match_operator 0 "comparison_operator"
9257 [(match_operand:FP 1 "register_operand" "")
9258 (match_operand:FP 2 "general_operand" "")])
9259 (label_ref (match_operand 3 "" ""))
9260 (pc)))]
9261 "TARGET_HARD_FLOAT"
9262 "s390_emit_jump (operands[3],
9263 s390_emit_compare (GET_CODE (operands[0]), operands[1], operands[2]));
9264 DONE;")
9265
9266 (define_expand "cbranchcc4"
9267 [(set (pc)
9268 (if_then_else (match_operator 0 "s390_comparison"
9269 [(match_operand 1 "cc_reg_operand" "")
9270 (match_operand 2 "const_int_operand" "")])
9271 (label_ref (match_operand 3 "" ""))
9272 (pc)))]
9273 ""
9274 "")
9275
9276
9277 ;;
9278 ;;- Conditional jump instructions.
9279 ;;
9280
9281 (define_insn "*cjump_64"
9282 [(set (pc)
9283 (if_then_else
9284 (match_operator 1 "s390_comparison" [(reg CC_REGNUM)
9285 (match_operand 2 "const_int_operand" "")])
9286 (label_ref (match_operand 0 "" ""))
9287 (pc)))]
9288 ""
9289 {
9290 if (get_attr_length (insn) == 4)
9291 return "j%C1\t%l0";
9292 else
9293 return "jg%C1\t%l0";
9294 }
9295 [(set_attr "op_type" "RI")
9296 (set_attr "type" "branch")
9297 (set (attr "length")
9298 (if_then_else (lt (abs (minus (pc) (match_dup 0))) (const_int 60000))
9299 (const_int 4) (const_int 6)))])
9300
9301 (define_insn "*cjump_long"
9302 [(set (pc)
9303 (if_then_else
9304 (match_operator 1 "s390_comparison" [(reg CC_REGNUM) (const_int 0)])
9305 (match_operand 0 "address_operand" "ZQZR")
9306 (pc)))]
9307 "!TARGET_INDIRECT_BRANCH_NOBP_JUMP"
9308 {
9309 if (get_attr_op_type (insn) == OP_TYPE_RR)
9310 return "b%C1r\t%0";
9311 else
9312 return "b%C1\t%a0";
9313 }
9314 [(set (attr "op_type")
9315 (if_then_else (match_operand 0 "register_operand" "")
9316 (const_string "RR") (const_string "RX")))
9317 (set (attr "mnemonic")
9318 (if_then_else (match_operand 0 "register_operand" "")
9319 (const_string "bcr") (const_string "bc")))
9320 (set_attr "type" "branch")
9321 (set_attr "atype" "agen")])
9322
9323 ;; A conditional return instruction.
9324 (define_insn "*c<code>"
9325 [(set (pc)
9326 (if_then_else
9327 (match_operator 0 "s390_comparison" [(reg CC_REGNUM) (const_int 0)])
9328 (ANY_RETURN)
9329 (pc)))]
9330 "s390_can_use_<code>_insn ()"
9331 {
9332 if (TARGET_INDIRECT_BRANCH_NOBP_RET)
9333 {
9334 s390_indirect_branch_via_thunk (RETURN_REGNUM,
9335 INVALID_REGNUM,
9336 operands[0],
9337 s390_indirect_branch_type_return);
9338 return "";
9339 }
9340 else
9341 return "b%C0r\t%%r14";
9342 }
9343 [(set (attr "op_type")
9344 (if_then_else (match_test "TARGET_INDIRECT_BRANCH_NOBP_RET")
9345 (const_string "RIL")
9346 (const_string "RR")))
9347 (set (attr "mnemonic")
9348 (if_then_else (match_test "TARGET_INDIRECT_BRANCH_NOBP_RET")
9349 (const_string "brcl")
9350 (const_string "bcr")))
9351 (set_attr "type" "jsr")
9352 (set_attr "atype" "agen")])
9353
9354 ;;
9355 ;;- Negated conditional jump instructions.
9356 ;;
9357
9358 (define_insn "*icjump_64"
9359 [(set (pc)
9360 (if_then_else
9361 (match_operator 1 "s390_comparison" [(reg CC_REGNUM) (const_int 0)])
9362 (pc)
9363 (label_ref (match_operand 0 "" ""))))]
9364 ""
9365 {
9366 if (get_attr_length (insn) == 4)
9367 return "j%D1\t%l0";
9368 else
9369 return "jg%D1\t%l0";
9370 }
9371 [(set_attr "op_type" "RI")
9372 (set_attr "type" "branch")
9373 (set (attr "length")
9374 (if_then_else (lt (abs (minus (pc) (match_dup 0))) (const_int 60000))
9375 (const_int 4) (const_int 6)))])
9376
9377 (define_insn "*icjump_long"
9378 [(set (pc)
9379 (if_then_else
9380 (match_operator 1 "s390_comparison" [(reg CC_REGNUM) (const_int 0)])
9381 (pc)
9382 (match_operand 0 "address_operand" "ZQZR")))]
9383 "!TARGET_INDIRECT_BRANCH_NOBP_JUMP"
9384 {
9385 if (get_attr_op_type (insn) == OP_TYPE_RR)
9386 return "b%D1r\t%0";
9387 else
9388 return "b%D1\t%a0";
9389 }
9390 [(set (attr "op_type")
9391 (if_then_else (match_operand 0 "register_operand" "")
9392 (const_string "RR") (const_string "RX")))
9393 (set (attr "mnemonic")
9394 (if_then_else (match_operand 0 "register_operand" "")
9395 (const_string "bcr") (const_string "bc")))
9396 (set_attr "type" "branch")
9397 (set_attr "atype" "agen")])
9398
9399 ;;
9400 ;;- Trap instructions.
9401 ;;
9402
9403 (define_insn "trap"
9404 [(trap_if (const_int 1) (const_int 0))]
9405 ""
9406 "j\t.+2"
9407 [(set_attr "op_type" "RI")
9408 (set_attr "type" "branch")])
9409
9410 (define_expand "ctrap<mode>4"
9411 [(trap_if (match_operator 0 "comparison_operator"
9412 [(match_operand:GPR 1 "register_operand" "")
9413 (match_operand:GPR 2 "general_operand" "")])
9414 (match_operand 3 "const0_operand" ""))]
9415 ""
9416 {
9417 rtx cond = s390_emit_compare (GET_CODE (operands[0]),
9418 operands[1], operands[2]);
9419 emit_insn (gen_condtrap (cond, XEXP (cond, 0)));
9420 DONE;
9421 })
9422
9423 (define_expand "ctrap<mode>4"
9424 [(trap_if (match_operator 0 "comparison_operator"
9425 [(match_operand:FP 1 "register_operand" "")
9426 (match_operand:FP 2 "general_operand" "")])
9427 (match_operand 3 "const0_operand" ""))]
9428 ""
9429 {
9430 rtx cond = s390_emit_compare (GET_CODE (operands[0]),
9431 operands[1], operands[2]);
9432 emit_insn (gen_condtrap (cond, XEXP (cond, 0)));
9433 DONE;
9434 })
9435
9436 (define_insn "condtrap"
9437 [(trap_if (match_operator 0 "s390_comparison"
9438 [(match_operand 1 "cc_reg_operand" "c")
9439 (const_int 0)])
9440 (const_int 0))]
9441 ""
9442 "j%C0\t.+2";
9443 [(set_attr "op_type" "RI")
9444 (set_attr "type" "branch")])
9445
9446 ; crt, cgrt, cit, cgit
9447 (define_insn "*cmp_and_trap_signed_int<mode>"
9448 [(trap_if (match_operator 0 "s390_signed_integer_comparison"
9449 [(match_operand:GPR 1 "register_operand" "d,d")
9450 (match_operand:GPR 2 "nonmemory_operand" "d,K")])
9451 (const_int 0))]
9452 "TARGET_Z10"
9453 "@
9454 c<g>rt%C0\t%1,%2
9455 c<g>it%C0\t%1,%h2"
9456 [(set_attr "op_type" "RRF,RIE")
9457 (set_attr "type" "branch")
9458 (set_attr "z10prop" "z10_super_c,z10_super")])
9459
9460 ; clrt, clgrt, clfit, clgit, clt, clgt
9461 (define_insn "*cmp_and_trap_unsigned_int<mode>"
9462 [(trap_if (match_operator 0 "s390_unsigned_integer_comparison"
9463 [(match_operand:GPR 1 "register_operand" "d,d,d")
9464 (match_operand:GPR 2 "general_operand" "d,D,T")])
9465 (const_int 0))]
9466 "TARGET_Z10"
9467 "@
9468 cl<g>rt%C0\t%1,%2
9469 cl<gf>it%C0\t%1,%x2
9470 cl<g>t%C0\t%1,%2"
9471 [(set_attr "op_type" "RRF,RIE,RSY")
9472 (set_attr "type" "branch")
9473 (set_attr "z10prop" "z10_super_c,z10_super,*")
9474 (set_attr "cpu_facility" "z10,z10,zEC12")])
9475
9476 ; lat, lgat
9477 (define_insn "*load_and_trap<mode>"
9478 [(trap_if (eq (match_operand:GPR 0 "memory_operand" "T")
9479 (const_int 0))
9480 (const_int 0))
9481 (set (match_operand:GPR 1 "register_operand" "=d")
9482 (match_dup 0))]
9483 "TARGET_ZEC12"
9484 "l<g>at\t%1,%0"
9485 [(set_attr "op_type" "RXY")])
9486
9487
9488 ;;
9489 ;;- Loop instructions.
9490 ;;
9491 ;; This is all complicated by the fact that since this is a jump insn
9492 ;; we must handle our own output reloads.
9493
9494 ;; branch on index
9495
9496 ; This splitter will be matched by combine and has to add the 2 moves
9497 ; necessary to load the compare and the increment values into a
9498 ; register pair as needed by brxle.
9499
9500 (define_insn_and_split "*brx_stage1_<GPR:mode>"
9501 [(set (pc)
9502 (if_then_else
9503 (match_operator 6 "s390_brx_operator"
9504 [(plus:GPR (match_operand:GPR 1 "register_operand" "")
9505 (match_operand:GPR 2 "general_operand" ""))
9506 (match_operand:GPR 3 "register_operand" "")])
9507 (label_ref (match_operand 0 "" ""))
9508 (pc)))
9509 (set (match_operand:GPR 4 "nonimmediate_operand" "")
9510 (plus:GPR (match_dup 1) (match_dup 2)))
9511 (clobber (match_scratch:GPR 5 ""))]
9512 ""
9513 "#"
9514 "!reload_completed && !reload_in_progress"
9515 [(set (match_dup 7) (match_dup 2)) ; the increment
9516 (set (match_dup 8) (match_dup 3)) ; the comparison value
9517 (parallel [(set (pc)
9518 (if_then_else
9519 (match_op_dup 6
9520 [(plus:GPR (match_dup 1) (match_dup 7))
9521 (match_dup 8)])
9522 (label_ref (match_dup 0))
9523 (pc)))
9524 (set (match_dup 4)
9525 (plus:GPR (match_dup 1) (match_dup 7)))
9526 (clobber (match_dup 5))
9527 (clobber (reg:CC CC_REGNUM))])]
9528 {
9529 rtx dreg = gen_reg_rtx (word_mode == DImode ? TImode : DImode);
9530 operands[7] = gen_lowpart (<GPR:MODE>mode,
9531 gen_highpart (word_mode, dreg));
9532 operands[8] = gen_lowpart (<GPR:MODE>mode,
9533 gen_lowpart (word_mode, dreg));
9534 })
9535
9536 ; brxlg, brxhg
9537
9538 (define_insn_and_split "*brxg_64bit"
9539 [(set (pc)
9540 (if_then_else
9541 (match_operator 5 "s390_brx_operator"
9542 [(plus:DI (match_operand:DI 1 "register_operand" "d,d,d")
9543 (subreg:DI (match_operand:TI 2 "register_operand" "d,d,d") 0))
9544 (subreg:DI (match_dup 2) 8)])
9545 (label_ref (match_operand 0 "" ""))
9546 (pc)))
9547 (set (match_operand:DI 3 "nonimmediate_operand" "=1,?X,?X")
9548 (plus:DI (match_dup 1)
9549 (subreg:DI (match_dup 2) 0)))
9550 (clobber (match_scratch:DI 4 "=X,&1,&?d"))
9551 (clobber (reg:CC CC_REGNUM))]
9552 "TARGET_ZARCH"
9553 {
9554 if (which_alternative != 0)
9555 return "#";
9556 else if (get_attr_length (insn) == 6)
9557 return "brx%E5g\t%1,%2,%l0";
9558 else
9559 return "agr\t%1,%2\;cgr\t%1,%M2\;jg%C5\t%l0";
9560 }
9561 "&& reload_completed
9562 && (!REG_P (operands[3])
9563 || !rtx_equal_p (operands[1], operands[3]))"
9564 [(set (match_dup 4) (match_dup 1))
9565 (parallel [(set (match_dup 4) (plus:DI (match_dup 4) (subreg:DI (match_dup 2) 0)))
9566 (clobber (reg:CC CC_REGNUM))])
9567 (set (reg:CCS CC_REGNUM) (compare:CCS (match_dup 4) (subreg:DI (match_dup 2) 8)))
9568 (set (match_dup 3) (match_dup 4))
9569 (set (pc) (if_then_else (match_op_dup 5 [(reg:CCS CC_REGNUM) (const_int 0)])
9570 (label_ref (match_dup 0))
9571 (pc)))]
9572 ""
9573 [(set_attr "op_type" "RIE")
9574 (set_attr "type" "branch")
9575 (set (attr "length")
9576 (if_then_else (lt (abs (minus (pc) (match_dup 0))) (const_int 60000))
9577 (const_int 6) (const_int 16)))])
9578
9579 ; brxle, brxh
9580
9581 (define_insn_and_split "*brx_64bit"
9582 [(set (pc)
9583 (if_then_else
9584 (match_operator 5 "s390_brx_operator"
9585 [(plus:SI (match_operand:SI 1 "register_operand" "d,d,d")
9586 (subreg:SI (match_operand:TI 2 "register_operand" "d,d,d") 4))
9587 (subreg:SI (match_dup 2) 12)])
9588 (label_ref (match_operand 0 "" ""))
9589 (pc)))
9590 (set (match_operand:SI 3 "nonimmediate_operand" "=1,?X,?X")
9591 (plus:SI (match_dup 1)
9592 (subreg:SI (match_dup 2) 4)))
9593 (clobber (match_scratch:SI 4 "=X,&1,&?d"))
9594 (clobber (reg:CC CC_REGNUM))]
9595 "TARGET_ZARCH"
9596 {
9597 if (which_alternative != 0)
9598 return "#";
9599 else if (get_attr_length (insn) == 6)
9600 return "brx%C5\t%1,%2,%l0";
9601 else
9602 return "ar\t%1,%2\;cr\t%1,%M2\;jg%C5\t%l0";
9603 }
9604 "&& reload_completed
9605 && (!REG_P (operands[3])
9606 || !rtx_equal_p (operands[1], operands[3]))"
9607 [(set (match_dup 4) (match_dup 1))
9608 (parallel [(set (match_dup 4) (plus:SI (match_dup 4) (subreg:SI (match_dup 2) 4)))
9609 (clobber (reg:CC CC_REGNUM))])
9610 (set (reg:CCS CC_REGNUM) (compare:CCS (match_dup 4) (subreg:SI (match_dup 2) 12)))
9611 (set (match_dup 3) (match_dup 4))
9612 (set (pc) (if_then_else (match_op_dup 5 [(reg:CCS CC_REGNUM) (const_int 0)])
9613 (label_ref (match_dup 0))
9614 (pc)))]
9615 ""
9616 [(set_attr "op_type" "RSI")
9617 (set_attr "type" "branch")
9618 (set (attr "length")
9619 (if_then_else (lt (abs (minus (pc) (match_dup 0))) (const_int 60000))
9620 (const_int 6) (const_int 14)))])
9621
9622 ; brxle, brxh
9623
9624 (define_insn_and_split "*brx_31bit"
9625 [(set (pc)
9626 (if_then_else
9627 (match_operator 5 "s390_brx_operator"
9628 [(plus:SI (match_operand:SI 1 "register_operand" "d,d,d")
9629 (subreg:SI (match_operand:DI 2 "register_operand" "d,d,d") 0))
9630 (subreg:SI (match_dup 2) 4)])
9631 (label_ref (match_operand 0 "" ""))
9632 (pc)))
9633 (set (match_operand:SI 3 "nonimmediate_operand" "=1,?X,?X")
9634 (plus:SI (match_dup 1)
9635 (subreg:SI (match_dup 2) 0)))
9636 (clobber (match_scratch:SI 4 "=X,&1,&?d"))
9637 (clobber (reg:CC CC_REGNUM))]
9638 "!TARGET_ZARCH"
9639 {
9640 if (which_alternative != 0)
9641 return "#";
9642 else if (get_attr_length (insn) == 6)
9643 return "brx%C5\t%1,%2,%l0";
9644 else
9645 return "ar\t%1,%2\;cr\t%1,%M2\;jg%C5\t%l0";
9646 }
9647 "&& reload_completed
9648 && (!REG_P (operands[3])
9649 || !rtx_equal_p (operands[1], operands[3]))"
9650 [(set (match_dup 4) (match_dup 1))
9651 (parallel [(set (match_dup 4) (plus:SI (match_dup 4) (subreg:SI (match_dup 2) 0)))
9652 (clobber (reg:CC CC_REGNUM))])
9653 (set (reg:CCS CC_REGNUM) (compare:CCS (match_dup 4) (subreg:SI (match_dup 2) 4)))
9654 (set (match_dup 3) (match_dup 4))
9655 (set (pc) (if_then_else (match_op_dup 5 [(reg:CCS CC_REGNUM) (const_int 0)])
9656 (label_ref (match_dup 0))
9657 (pc)))]
9658 ""
9659 [(set_attr "op_type" "RSI")
9660 (set_attr "type" "branch")
9661 (set (attr "length")
9662 (if_then_else (lt (abs (minus (pc) (match_dup 0))) (const_int 60000))
9663 (const_int 6) (const_int 14)))])
9664
9665
9666 ;; branch on count
9667
9668 (define_expand "doloop_end"
9669 [(use (match_operand 0 "" "")) ; loop pseudo
9670 (use (match_operand 1 "" ""))] ; label
9671 ""
9672 {
9673 if (GET_MODE (operands[0]) == SImode)
9674 emit_jump_insn (gen_doloop_si64 (operands[1], operands[0], operands[0]));
9675 else if (GET_MODE (operands[0]) == DImode && TARGET_ZARCH)
9676 emit_jump_insn (gen_doloop_di (operands[1], operands[0], operands[0]));
9677 else
9678 FAIL;
9679
9680 DONE;
9681 })
9682
9683 (define_insn_and_split "doloop_si64"
9684 [(set (pc)
9685 (if_then_else
9686 (ne (match_operand:SI 1 "register_operand" "d,d,d")
9687 (const_int 1))
9688 (label_ref (match_operand 0 "" ""))
9689 (pc)))
9690 (set (match_operand:SI 2 "nonimmediate_operand" "=1,?X,?X")
9691 (plus:SI (match_dup 1) (const_int -1)))
9692 (clobber (match_scratch:SI 3 "=X,&1,&?d"))
9693 (clobber (reg:CC CC_REGNUM))]
9694 ""
9695 {
9696 if (which_alternative != 0)
9697 return "#";
9698 else if (get_attr_length (insn) == 4)
9699 return "brct\t%1,%l0";
9700 else
9701 return "ahi\t%1,-1\;jgne\t%l0";
9702 }
9703 "&& reload_completed
9704 && (! REG_P (operands[2])
9705 || ! rtx_equal_p (operands[1], operands[2]))"
9706 [(set (match_dup 3) (match_dup 1))
9707 (parallel [(set (reg:CCAN CC_REGNUM)
9708 (compare:CCAN (plus:SI (match_dup 3) (const_int -1))
9709 (const_int 0)))
9710 (set (match_dup 3) (plus:SI (match_dup 3) (const_int -1)))])
9711 (set (match_dup 2) (match_dup 3))
9712 (set (pc) (if_then_else (ne (reg:CCAN CC_REGNUM) (const_int 0))
9713 (label_ref (match_dup 0))
9714 (pc)))]
9715 ""
9716 [(set_attr "op_type" "RI")
9717 ; Strictly speaking, the z10 properties are valid for brct only, however, it does not
9718 ; hurt us in the (rare) case of ahi.
9719 (set_attr "z10prop" "z10_super_E1")
9720 (set_attr "type" "branch")
9721 (set (attr "length")
9722 (if_then_else (lt (abs (minus (pc) (match_dup 0))) (const_int 60000))
9723 (const_int 4) (const_int 10)))])
9724
9725 (define_insn_and_split "doloop_di"
9726 [(set (pc)
9727 (if_then_else
9728 (ne (match_operand:DI 1 "register_operand" "d,d,d")
9729 (const_int 1))
9730 (label_ref (match_operand 0 "" ""))
9731 (pc)))
9732 (set (match_operand:DI 2 "nonimmediate_operand" "=1,?X,?X")
9733 (plus:DI (match_dup 1) (const_int -1)))
9734 (clobber (match_scratch:DI 3 "=X,&1,&?d"))
9735 (clobber (reg:CC CC_REGNUM))]
9736 "TARGET_ZARCH"
9737 {
9738 if (which_alternative != 0)
9739 return "#";
9740 else if (get_attr_length (insn) == 4)
9741 return "brctg\t%1,%l0";
9742 else
9743 return "aghi\t%1,-1\;jgne\t%l0";
9744 }
9745 "&& reload_completed
9746 && (! REG_P (operands[2])
9747 || ! rtx_equal_p (operands[1], operands[2]))"
9748 [(set (match_dup 3) (match_dup 1))
9749 (parallel [(set (reg:CCAN CC_REGNUM)
9750 (compare:CCAN (plus:DI (match_dup 3) (const_int -1))
9751 (const_int 0)))
9752 (set (match_dup 3) (plus:DI (match_dup 3) (const_int -1)))])
9753 (set (match_dup 2) (match_dup 3))
9754 (set (pc) (if_then_else (ne (reg:CCAN CC_REGNUM) (const_int 0))
9755 (label_ref (match_dup 0))
9756 (pc)))]
9757 ""
9758 [(set_attr "op_type" "RI")
9759 ; Strictly speaking, the z10 properties are valid for brct only, however, it does not
9760 ; hurt us in the (rare) case of ahi.
9761 (set_attr "z10prop" "z10_super_E1")
9762 (set_attr "type" "branch")
9763 (set (attr "length")
9764 (if_then_else (lt (abs (minus (pc) (match_dup 0))) (const_int 60000))
9765 (const_int 4) (const_int 10)))])
9766
9767 ;;
9768 ;;- Unconditional jump instructions.
9769 ;;
9770
9771 ;
9772 ; jump instruction pattern(s).
9773 ;
9774
9775 (define_expand "jump"
9776 [(match_operand 0 "" "")]
9777 ""
9778 "s390_emit_jump (operands[0], NULL_RTX); DONE;")
9779
9780 (define_insn "*jump64"
9781 [(set (pc) (label_ref (match_operand 0 "" "")))]
9782 ""
9783 {
9784 if (get_attr_length (insn) == 4)
9785 return "j\t%l0";
9786 else
9787 return "jg\t%l0";
9788 }
9789 [(set_attr "op_type" "RI")
9790 (set_attr "type" "branch")
9791 (set (attr "length")
9792 (if_then_else (lt (abs (minus (pc) (match_dup 0))) (const_int 60000))
9793 (const_int 4) (const_int 6)))])
9794
9795 ;
9796 ; indirect-jump instruction pattern(s).
9797 ;
9798
9799 (define_expand "indirect_jump"
9800 [(set (pc) (match_operand 0 "nonimmediate_operand" ""))]
9801 ""
9802 {
9803 if (address_operand (operands[0], GET_MODE (operands[0])))
9804 ;
9805 else if (TARGET_Z14
9806 && GET_MODE (operands[0]) == Pmode
9807 && memory_operand (operands[0], Pmode))
9808 ;
9809 else
9810 operands[0] = force_reg (Pmode, operands[0]);
9811
9812 if (TARGET_INDIRECT_BRANCH_NOBP_JUMP_THUNK)
9813 {
9814 operands[0] = force_reg (Pmode, operands[0]);
9815 if (TARGET_CPU_Z10)
9816 {
9817 if (TARGET_64BIT)
9818 emit_jump_insn (gen_indirect_jump_via_thunkdi_z10 (operands[0]));
9819 else
9820 emit_jump_insn (gen_indirect_jump_via_thunksi_z10 (operands[0]));
9821 }
9822 else
9823 {
9824 if (TARGET_64BIT)
9825 emit_jump_insn (gen_indirect_jump_via_thunkdi (operands[0]));
9826 else
9827 emit_jump_insn (gen_indirect_jump_via_thunksi (operands[0]));
9828 }
9829 DONE;
9830 }
9831
9832 if (TARGET_INDIRECT_BRANCH_NOBP_JUMP_INLINE_THUNK)
9833 {
9834 operands[0] = force_reg (Pmode, operands[0]);
9835 rtx label_ref = gen_rtx_LABEL_REF (VOIDmode, gen_label_rtx ());
9836 if (TARGET_CPU_Z10)
9837 {
9838 if (TARGET_64BIT)
9839 emit_jump_insn (gen_indirect_jump_via_inlinethunkdi_z10 (operands[0],
9840 label_ref));
9841 else
9842 emit_jump_insn (gen_indirect_jump_via_inlinethunksi_z10 (operands[0],
9843 label_ref));
9844 }
9845 else
9846 {
9847 if (TARGET_64BIT)
9848 emit_jump_insn (gen_indirect_jump_via_inlinethunkdi (operands[0],
9849 label_ref,
9850 force_reg (Pmode, label_ref)));
9851 else
9852 emit_jump_insn (gen_indirect_jump_via_inlinethunksi (operands[0],
9853 label_ref,
9854 force_reg (Pmode, label_ref)));
9855 }
9856 DONE;
9857 }
9858 })
9859
9860 (define_insn "*indirect_jump"
9861 [(set (pc)
9862 (match_operand 0 "address_operand" "ZR"))]
9863 "!TARGET_INDIRECT_BRANCH_NOBP_JUMP_THUNK"
9864 {
9865 if (get_attr_op_type (insn) == OP_TYPE_RR)
9866 return "br\t%0";
9867 else
9868 return "b\t%a0";
9869 }
9870 [(set (attr "op_type")
9871 (if_then_else (match_operand 0 "register_operand" "")
9872 (const_string "RR") (const_string "RX")))
9873 (set (attr "mnemonic")
9874 (if_then_else (match_operand 0 "register_operand" "")
9875 (const_string "br") (const_string "b")))
9876 (set_attr "type" "branch")
9877 (set_attr "atype" "agen")])
9878
9879 (define_insn "indirect_jump_via_thunk<mode>_z10"
9880 [(set (pc)
9881 (match_operand:P 0 "register_operand" "a"))]
9882 "TARGET_INDIRECT_BRANCH_NOBP_JUMP_THUNK
9883 && TARGET_CPU_Z10"
9884 {
9885 s390_indirect_branch_via_thunk (REGNO (operands[0]),
9886 INVALID_REGNUM,
9887 NULL_RTX,
9888 s390_indirect_branch_type_jump);
9889 return "";
9890 }
9891 [(set_attr "op_type" "RIL")
9892 (set_attr "mnemonic" "jg")
9893 (set_attr "type" "branch")
9894 (set_attr "atype" "agen")])
9895
9896 (define_insn "indirect_jump_via_thunk<mode>"
9897 [(set (pc)
9898 (match_operand:P 0 "register_operand" " a"))
9899 (clobber (reg:P INDIRECT_BRANCH_THUNK_REGNUM))]
9900 "TARGET_INDIRECT_BRANCH_NOBP_JUMP_THUNK
9901 && !TARGET_CPU_Z10"
9902 {
9903 s390_indirect_branch_via_thunk (REGNO (operands[0]),
9904 INVALID_REGNUM,
9905 NULL_RTX,
9906 s390_indirect_branch_type_jump);
9907 return "";
9908 }
9909 [(set_attr "op_type" "RIL")
9910 (set_attr "mnemonic" "jg")
9911 (set_attr "type" "branch")
9912 (set_attr "atype" "agen")])
9913
9914
9915 ; The label_ref is wrapped into an if_then_else in order to hide it
9916 ; from mark_jump_label. Without this the label_ref would become the
9917 ; ONLY jump target of that jump breaking the control flow graph.
9918 (define_insn "indirect_jump_via_inlinethunk<mode>_z10"
9919 [(unspec [(if_then_else (match_operand:P 1 "larl_operand" "X")
9920 (const_int 0)
9921 (const_int 0))
9922 (const_int 0)] UNSPEC_EXECUTE_JUMP)
9923 (set (pc) (match_operand:P 0 "register_operand" "a"))]
9924 "TARGET_INDIRECT_BRANCH_NOBP_JUMP_INLINE_THUNK
9925 && TARGET_CPU_Z10"
9926 {
9927 s390_indirect_branch_via_inline_thunk (operands[1]);
9928 return "";
9929 }
9930 [(set_attr "op_type" "RIL")
9931 (set_attr "type" "branch")
9932 (set_attr "length" "10")])
9933
9934 (define_insn "indirect_jump_via_inlinethunk<mode>"
9935 [(unspec [(if_then_else (match_operand:P 1 "larl_operand" "X")
9936 (const_int 0)
9937 (const_int 0))
9938 (match_operand:P 2 "register_operand" "a")] UNSPEC_EXECUTE_JUMP)
9939 (set (pc) (match_operand:P 0 "register_operand" "a"))]
9940 "TARGET_INDIRECT_BRANCH_NOBP_JUMP_INLINE_THUNK
9941 && !TARGET_CPU_Z10"
9942 {
9943 s390_indirect_branch_via_inline_thunk (operands[2]);
9944 return "";
9945 }
9946 [(set_attr "op_type" "RX")
9947 (set_attr "type" "branch")
9948 (set_attr "length" "8")])
9949
9950 ; FIXME: LRA does not appear to be able to deal with MEMs being
9951 ; checked against address constraints like ZR above. So make this a
9952 ; separate pattern for now.
9953 (define_insn "*indirect2_jump"
9954 [(set (pc)
9955 (match_operand 0 "nonimmediate_operand" "a,T"))]
9956 "!TARGET_INDIRECT_BRANCH_NOBP_JUMP"
9957 "@
9958 br\t%0
9959 bi\t%0"
9960 [(set_attr "op_type" "RR,RXY")
9961 (set_attr "type" "branch")
9962 (set_attr "atype" "agen")
9963 (set_attr "cpu_facility" "*,z14")])
9964
9965 ;
9966 ; casesi instruction pattern(s).
9967 ;
9968
9969 (define_expand "casesi_jump"
9970 [(parallel
9971 [(set (pc) (match_operand 0 "address_operand"))
9972 (use (label_ref (match_operand 1 "")))])]
9973 ""
9974 {
9975 if (TARGET_INDIRECT_BRANCH_NOBP_JUMP_THUNK)
9976 {
9977 operands[0] = force_reg (GET_MODE (operands[0]), operands[0]);
9978
9979 if (TARGET_CPU_Z10)
9980 {
9981 if (TARGET_64BIT)
9982 emit_jump_insn (gen_casesi_jump_via_thunkdi_z10 (operands[0],
9983 operands[1]));
9984 else
9985 emit_jump_insn (gen_casesi_jump_via_thunksi_z10 (operands[0],
9986 operands[1]));
9987 }
9988 else
9989 {
9990 if (TARGET_64BIT)
9991 emit_jump_insn (gen_casesi_jump_via_thunkdi (operands[0],
9992 operands[1]));
9993 else
9994 emit_jump_insn (gen_casesi_jump_via_thunksi (operands[0],
9995 operands[1]));
9996 }
9997 DONE;
9998 }
9999
10000 if (TARGET_INDIRECT_BRANCH_NOBP_JUMP_INLINE_THUNK)
10001 {
10002 operands[0] = force_reg (Pmode, operands[0]);
10003 rtx label_ref = gen_rtx_LABEL_REF (VOIDmode, gen_label_rtx ());
10004 if (TARGET_CPU_Z10)
10005 {
10006 if (TARGET_64BIT)
10007 emit_jump_insn (gen_casesi_jump_via_inlinethunkdi_z10 (operands[0],
10008 operands[1],
10009 label_ref));
10010 else
10011 emit_jump_insn (gen_casesi_jump_via_inlinethunksi_z10 (operands[0],
10012 operands[1],
10013 label_ref));
10014 }
10015 else
10016 {
10017 if (TARGET_64BIT)
10018 emit_jump_insn (gen_casesi_jump_via_inlinethunkdi (operands[0],
10019 operands[1],
10020 label_ref,
10021 force_reg (Pmode, label_ref)));
10022 else
10023 emit_jump_insn (gen_casesi_jump_via_inlinethunksi (operands[0],
10024 operands[1],
10025 label_ref,
10026 force_reg (Pmode, label_ref)));
10027 }
10028 DONE;
10029 }
10030 })
10031
10032 (define_insn "*casesi_jump"
10033 [(set (pc) (match_operand 0 "address_operand" "ZR"))
10034 (use (label_ref (match_operand 1 "" "")))]
10035 "!TARGET_INDIRECT_BRANCH_NOBP_JUMP_THUNK"
10036 {
10037 if (get_attr_op_type (insn) == OP_TYPE_RR)
10038 return "br\t%0";
10039 else
10040 return "b\t%a0";
10041 }
10042 [(set (attr "op_type")
10043 (if_then_else (match_operand 0 "register_operand" "")
10044 (const_string "RR") (const_string "RX")))
10045 (set (attr "mnemonic")
10046 (if_then_else (match_operand 0 "register_operand" "")
10047 (const_string "br") (const_string "b")))
10048 (set_attr "type" "branch")
10049 (set_attr "atype" "agen")])
10050
10051 (define_insn "casesi_jump_via_thunk<mode>_z10"
10052 [(set (pc) (match_operand:P 0 "register_operand" "a"))
10053 (use (label_ref (match_operand 1 "" "")))]
10054 "TARGET_INDIRECT_BRANCH_NOBP_JUMP_THUNK
10055 && TARGET_CPU_Z10"
10056 {
10057 s390_indirect_branch_via_thunk (REGNO (operands[0]),
10058 INVALID_REGNUM,
10059 NULL_RTX,
10060 s390_indirect_branch_type_jump);
10061 return "";
10062 }
10063 [(set_attr "op_type" "RIL")
10064 (set_attr "mnemonic" "jg")
10065 (set_attr "type" "branch")
10066 (set_attr "atype" "agen")])
10067
10068 (define_insn "casesi_jump_via_thunk<mode>"
10069 [(set (pc) (match_operand:P 0 "register_operand" "a"))
10070 (use (label_ref (match_operand 1 "" "")))
10071 (clobber (reg:P INDIRECT_BRANCH_THUNK_REGNUM))]
10072 "TARGET_INDIRECT_BRANCH_NOBP_JUMP_THUNK
10073 && !TARGET_CPU_Z10"
10074 {
10075 s390_indirect_branch_via_thunk (REGNO (operands[0]),
10076 INVALID_REGNUM,
10077 NULL_RTX,
10078 s390_indirect_branch_type_jump);
10079 return "";
10080 }
10081 [(set_attr "op_type" "RIL")
10082 (set_attr "mnemonic" "jg")
10083 (set_attr "type" "branch")
10084 (set_attr "atype" "agen")])
10085
10086
10087 ; The label_ref is wrapped into an if_then_else in order to hide it
10088 ; from mark_jump_label. Without this the label_ref would become the
10089 ; ONLY jump target of that jump breaking the control flow graph.
10090 (define_insn "casesi_jump_via_inlinethunk<mode>_z10"
10091 [(unspec [(if_then_else (match_operand:P 2 "larl_operand" "X")
10092 (const_int 0)
10093 (const_int 0))
10094 (const_int 0)] UNSPEC_EXECUTE_JUMP)
10095 (set (pc) (match_operand:P 0 "register_operand" "a"))
10096 (use (label_ref (match_operand 1 "" "")))]
10097 "TARGET_INDIRECT_BRANCH_NOBP_JUMP_INLINE_THUNK
10098 && TARGET_CPU_Z10"
10099 {
10100 s390_indirect_branch_via_inline_thunk (operands[2]);
10101 return "";
10102 }
10103 [(set_attr "op_type" "RIL")
10104 (set_attr "type" "cs")
10105 (set_attr "length" "10")])
10106
10107 (define_insn "casesi_jump_via_inlinethunk<mode>"
10108 [(unspec [(if_then_else (match_operand:P 2 "larl_operand" "X")
10109 (const_int 0)
10110 (const_int 0))
10111 (match_operand:P 3 "register_operand" "a")] UNSPEC_EXECUTE_JUMP)
10112 (set (pc) (match_operand:P 0 "register_operand" "a"))
10113 (use (label_ref (match_operand 1 "" "")))]
10114 "TARGET_INDIRECT_BRANCH_NOBP_JUMP_INLINE_THUNK
10115 && !TARGET_CPU_Z10"
10116 {
10117 s390_indirect_branch_via_inline_thunk (operands[3]);
10118 return "";
10119 }
10120 [(set_attr "op_type" "RX")
10121 (set_attr "type" "cs")
10122 (set_attr "length" "8")])
10123
10124 (define_expand "casesi"
10125 [(match_operand:SI 0 "general_operand" "")
10126 (match_operand:SI 1 "general_operand" "")
10127 (match_operand:SI 2 "general_operand" "")
10128 (label_ref (match_operand 3 "" ""))
10129 (label_ref (match_operand 4 "" ""))]
10130 ""
10131 {
10132 rtx index = gen_reg_rtx (SImode);
10133 rtx base = gen_reg_rtx (Pmode);
10134 rtx target = gen_reg_rtx (Pmode);
10135
10136 emit_move_insn (index, operands[0]);
10137 emit_insn (gen_subsi3 (index, index, operands[1]));
10138 emit_cmp_and_jump_insns (index, operands[2], GTU, NULL_RTX, SImode, 1,
10139 operands[4]);
10140
10141 if (Pmode != SImode)
10142 index = convert_to_mode (Pmode, index, 1);
10143 if (GET_CODE (index) != REG)
10144 index = copy_to_mode_reg (Pmode, index);
10145
10146 if (TARGET_64BIT)
10147 emit_insn (gen_ashldi3 (index, index, GEN_INT (3)));
10148 else
10149 emit_insn (gen_ashlsi3 (index, index, const2_rtx));
10150
10151 emit_move_insn (base, gen_rtx_LABEL_REF (Pmode, operands[3]));
10152
10153 index = gen_const_mem (Pmode, gen_rtx_PLUS (Pmode, base, index));
10154 emit_move_insn (target, index);
10155
10156 if (flag_pic)
10157 target = gen_rtx_PLUS (Pmode, base, target);
10158 emit_jump_insn (gen_casesi_jump (target, operands[3]));
10159
10160 DONE;
10161 })
10162
10163
10164 ;;
10165 ;;- Jump to subroutine.
10166 ;;
10167 ;;
10168
10169 ;
10170 ; untyped call instruction pattern(s).
10171 ;
10172
10173 ;; Call subroutine returning any type.
10174 (define_expand "untyped_call"
10175 [(parallel [(call (match_operand 0 "" "")
10176 (const_int 0))
10177 (match_operand 1 "" "")
10178 (match_operand 2 "" "")])]
10179 ""
10180 {
10181 int i;
10182
10183 emit_call_insn (gen_call (operands[0], const0_rtx, const0_rtx));
10184
10185 for (i = 0; i < XVECLEN (operands[2], 0); i++)
10186 {
10187 rtx set = XVECEXP (operands[2], 0, i);
10188 emit_move_insn (SET_DEST (set), SET_SRC (set));
10189 }
10190
10191 /* The optimizer does not know that the call sets the function value
10192 registers we stored in the result block. We avoid problems by
10193 claiming that all hard registers are used and clobbered at this
10194 point. */
10195 emit_insn (gen_blockage ());
10196
10197 DONE;
10198 })
10199
10200 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
10201 ;; all of memory. This blocks insns from being moved across this point.
10202
10203 (define_insn "blockage"
10204 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
10205 ""
10206 ""
10207 [(set_attr "type" "none")
10208 (set_attr "length" "0")])
10209
10210 ;
10211 ; sibcall patterns
10212 ;
10213
10214 (define_expand "sibcall"
10215 [(call (match_operand 0 "" "")
10216 (match_operand 1 "" ""))]
10217 ""
10218 {
10219 s390_emit_call (XEXP (operands[0], 0), NULL_RTX, NULL_RTX, NULL_RTX);
10220 DONE;
10221 })
10222
10223 (define_insn "*sibcall_br"
10224 [(call (mem:QI (reg SIBCALL_REGNUM))
10225 (match_operand 0 "const_int_operand" "n"))]
10226 "SIBLING_CALL_P (insn)
10227 && GET_MODE (XEXP (XEXP (PATTERN (insn), 0), 0)) == Pmode"
10228 {
10229 if (TARGET_INDIRECT_BRANCH_NOBP_CALL)
10230 {
10231 gcc_assert (TARGET_CPU_Z10);
10232 s390_indirect_branch_via_thunk (SIBCALL_REGNUM,
10233 INVALID_REGNUM,
10234 NULL_RTX,
10235 s390_indirect_branch_type_call);
10236 return "";
10237 }
10238 else
10239 return "br\t%%r1";
10240 }
10241 [(set (attr "op_type")
10242 (if_then_else (match_test "TARGET_INDIRECT_BRANCH_NOBP_CALL")
10243 (const_string "RIL")
10244 (const_string "RR")))
10245 (set (attr "mnemonic")
10246 (if_then_else (match_test "TARGET_INDIRECT_BRANCH_NOBP_CALL")
10247 (const_string "jg")
10248 (const_string "br")))
10249 (set_attr "type" "branch")
10250 (set_attr "atype" "agen")])
10251
10252 (define_insn "*sibcall_brc"
10253 [(call (mem:QI (match_operand 0 "bras_sym_operand" "X"))
10254 (match_operand 1 "const_int_operand" "n"))]
10255 "SIBLING_CALL_P (insn) && TARGET_SMALL_EXEC"
10256 "j\t%0"
10257 [(set_attr "op_type" "RI")
10258 (set_attr "type" "branch")])
10259
10260 (define_insn "*sibcall_brcl"
10261 [(call (mem:QI (match_operand 0 "bras_sym_operand" "X"))
10262 (match_operand 1 "const_int_operand" "n"))]
10263 "SIBLING_CALL_P (insn)"
10264 "jg\t%0"
10265 [(set_attr "op_type" "RIL")
10266 (set_attr "type" "branch")])
10267
10268 ;
10269 ; sibcall_value patterns
10270 ;
10271
10272 (define_expand "sibcall_value"
10273 [(set (match_operand 0 "" "")
10274 (call (match_operand 1 "" "")
10275 (match_operand 2 "" "")))]
10276 ""
10277 {
10278 s390_emit_call (XEXP (operands[1], 0), NULL_RTX, operands[0], NULL_RTX);
10279 DONE;
10280 })
10281
10282 (define_insn "*sibcall_value_br"
10283 [(set (match_operand 0 "" "")
10284 (call (mem:QI (reg SIBCALL_REGNUM))
10285 (match_operand 1 "const_int_operand" "n")))]
10286 "SIBLING_CALL_P (insn)
10287 && GET_MODE (XEXP (XEXP (XEXP (PATTERN (insn), 1), 0), 0)) == Pmode"
10288 {
10289 if (TARGET_INDIRECT_BRANCH_NOBP_CALL)
10290 {
10291 gcc_assert (TARGET_CPU_Z10);
10292 s390_indirect_branch_via_thunk (SIBCALL_REGNUM,
10293 INVALID_REGNUM,
10294 NULL_RTX,
10295 s390_indirect_branch_type_call);
10296 return "";
10297 }
10298 else
10299 return "br\t%%r1";
10300 }
10301 [(set (attr "op_type")
10302 (if_then_else (match_test "TARGET_INDIRECT_BRANCH_NOBP_CALL")
10303 (const_string "RIL")
10304 (const_string "RR")))
10305 (set (attr "mnemonic")
10306 (if_then_else (match_test "TARGET_INDIRECT_BRANCH_NOBP_CALL")
10307 (const_string "jg")
10308 (const_string "br")))
10309 (set_attr "type" "branch")
10310 (set_attr "atype" "agen")])
10311
10312 (define_insn "*sibcall_value_brc"
10313 [(set (match_operand 0 "" "")
10314 (call (mem:QI (match_operand 1 "bras_sym_operand" "X"))
10315 (match_operand 2 "const_int_operand" "n")))]
10316 "SIBLING_CALL_P (insn) && TARGET_SMALL_EXEC"
10317 "j\t%1"
10318 [(set_attr "op_type" "RI")
10319 (set_attr "type" "branch")])
10320
10321 (define_insn "*sibcall_value_brcl"
10322 [(set (match_operand 0 "" "")
10323 (call (mem:QI (match_operand 1 "bras_sym_operand" "X"))
10324 (match_operand 2 "const_int_operand" "n")))]
10325 "SIBLING_CALL_P (insn)"
10326 "jg\t%1"
10327 [(set_attr "op_type" "RIL")
10328 (set_attr "type" "branch")])
10329
10330
10331 ;
10332 ; call instruction pattern(s).
10333 ;
10334
10335 (define_expand "call"
10336 [(call (match_operand 0 "" "")
10337 (match_operand 1 "" ""))
10338 (use (match_operand 2 "" ""))]
10339 ""
10340 {
10341 s390_emit_call (XEXP (operands[0], 0), NULL_RTX, NULL_RTX,
10342 gen_rtx_REG (Pmode, RETURN_REGNUM));
10343 DONE;
10344 })
10345
10346 (define_insn "*bras"
10347 [(call (mem:QI (match_operand 0 "bras_sym_operand" "X"))
10348 (match_operand 1 "const_int_operand" "n"))
10349 (clobber (match_operand 2 "register_operand" "=r"))]
10350 "!SIBLING_CALL_P (insn)
10351 && TARGET_SMALL_EXEC
10352 && GET_MODE (operands[2]) == Pmode"
10353 "bras\t%2,%0"
10354 [(set_attr "op_type" "RI")
10355 (set_attr "type" "jsr")
10356 (set_attr "z196prop" "z196_cracked")])
10357
10358 (define_insn "*brasl"
10359 [(call (mem:QI (match_operand 0 "bras_sym_operand" "X"))
10360 (match_operand 1 "const_int_operand" "n"))
10361 (clobber (match_operand 2 "register_operand" "=r"))]
10362 "!SIBLING_CALL_P (insn)
10363
10364 && GET_MODE (operands[2]) == Pmode"
10365 "brasl\t%2,%0"
10366 [(set_attr "op_type" "RIL")
10367 (set_attr "type" "jsr")
10368 (set_attr "z196prop" "z196_cracked")
10369 (set_attr "relative_long" "yes")])
10370
10371 (define_insn "*basr"
10372 [(call (mem:QI (match_operand 0 "address_operand" "ZR"))
10373 (match_operand 1 "const_int_operand" "n"))
10374 (clobber (match_operand 2 "register_operand" "=r"))]
10375 "!TARGET_INDIRECT_BRANCH_NOBP_CALL
10376 && !SIBLING_CALL_P (insn)
10377 && GET_MODE (operands[2]) == Pmode"
10378 {
10379 if (get_attr_op_type (insn) == OP_TYPE_RR)
10380 return "basr\t%2,%0";
10381 else
10382 return "bas\t%2,%a0";
10383 }
10384 [(set (attr "op_type")
10385 (if_then_else (match_operand 0 "register_operand" "")
10386 (const_string "RR") (const_string "RX")))
10387 (set (attr "mnemonic")
10388 (if_then_else (match_operand 0 "register_operand" "")
10389 (const_string "basr") (const_string "bas")))
10390 (set_attr "type" "jsr")
10391 (set_attr "atype" "agen")
10392 (set_attr "z196prop" "z196_cracked")])
10393
10394 (define_insn "*basr_via_thunk<mode>_z10"
10395 [(call (mem:QI (match_operand:P 0 "register_operand" "a"))
10396 (match_operand 1 "const_int_operand" "n"))
10397 (clobber (match_operand:P 2 "register_operand" "=&r"))]
10398 "TARGET_INDIRECT_BRANCH_NOBP_CALL
10399 && TARGET_CPU_Z10
10400 && !SIBLING_CALL_P (insn)"
10401 {
10402 s390_indirect_branch_via_thunk (REGNO (operands[0]),
10403 REGNO (operands[2]),
10404 NULL_RTX,
10405 s390_indirect_branch_type_call);
10406 return "";
10407 }
10408 [(set_attr "op_type" "RIL")
10409 (set_attr "mnemonic" "brasl")
10410 (set_attr "type" "jsr")
10411 (set_attr "atype" "agen")
10412 (set_attr "z196prop" "z196_cracked")])
10413
10414 (define_insn "*basr_via_thunk<mode>"
10415 [(call (mem:QI (match_operand:P 0 "register_operand" "a"))
10416 (match_operand 1 "const_int_operand" "n"))
10417 (clobber (match_operand:P 2 "register_operand" "=&r"))
10418 (clobber (reg:P INDIRECT_BRANCH_THUNK_REGNUM))]
10419 "TARGET_INDIRECT_BRANCH_NOBP_CALL
10420 && !TARGET_CPU_Z10
10421 && !SIBLING_CALL_P (insn)"
10422 {
10423 s390_indirect_branch_via_thunk (REGNO (operands[0]),
10424 REGNO (operands[2]),
10425 NULL_RTX,
10426 s390_indirect_branch_type_call);
10427 return "";
10428 }
10429 [(set_attr "op_type" "RIL")
10430 (set_attr "mnemonic" "brasl")
10431 (set_attr "type" "jsr")
10432 (set_attr "atype" "agen")
10433 (set_attr "z196prop" "z196_cracked")])
10434
10435 ;
10436 ; call_value instruction pattern(s).
10437 ;
10438
10439 (define_expand "call_value"
10440 [(set (match_operand 0 "" "")
10441 (call (match_operand 1 "" "")
10442 (match_operand 2 "" "")))
10443 (use (match_operand 3 "" ""))]
10444 ""
10445 {
10446 s390_emit_call (XEXP (operands[1], 0), NULL_RTX, operands[0],
10447 gen_rtx_REG (Pmode, RETURN_REGNUM));
10448 DONE;
10449 })
10450
10451 (define_insn "*bras_r"
10452 [(set (match_operand 0 "" "")
10453 (call (mem:QI (match_operand 1 "bras_sym_operand" "X"))
10454 (match_operand:SI 2 "const_int_operand" "n")))
10455 (clobber (match_operand 3 "register_operand" "=r"))]
10456 "!SIBLING_CALL_P (insn)
10457 && TARGET_SMALL_EXEC
10458 && GET_MODE (operands[3]) == Pmode"
10459 "bras\t%3,%1"
10460 [(set_attr "op_type" "RI")
10461 (set_attr "type" "jsr")
10462 (set_attr "z196prop" "z196_cracked")])
10463
10464 (define_insn "*brasl_r"
10465 [(set (match_operand 0 "" "")
10466 (call (mem:QI (match_operand 1 "bras_sym_operand" "X"))
10467 (match_operand 2 "const_int_operand" "n")))
10468 (clobber (match_operand 3 "register_operand" "=r"))]
10469 "!SIBLING_CALL_P (insn)
10470
10471 && GET_MODE (operands[3]) == Pmode"
10472 "brasl\t%3,%1"
10473 [(set_attr "op_type" "RIL")
10474 (set_attr "type" "jsr")
10475 (set_attr "z196prop" "z196_cracked")
10476 (set_attr "relative_long" "yes")])
10477
10478 (define_insn "*basr_r"
10479 [(set (match_operand 0 "" "")
10480 (call (mem:QI (match_operand 1 "address_operand" "ZR"))
10481 (match_operand 2 "const_int_operand" "n")))
10482 (clobber (match_operand 3 "register_operand" "=r"))]
10483 "!TARGET_INDIRECT_BRANCH_NOBP_CALL
10484 && !SIBLING_CALL_P (insn)
10485 && GET_MODE (operands[3]) == Pmode"
10486 {
10487 if (get_attr_op_type (insn) == OP_TYPE_RR)
10488 return "basr\t%3,%1";
10489 else
10490 return "bas\t%3,%a1";
10491 }
10492 [(set (attr "op_type")
10493 (if_then_else (match_operand 1 "register_operand" "")
10494 (const_string "RR") (const_string "RX")))
10495 (set (attr "mnemonic")
10496 (if_then_else (match_operand 1 "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_r_via_thunk_z10"
10503 [(set (match_operand 0 "" "")
10504 (call (mem:QI (match_operand 1 "register_operand" "a"))
10505 (match_operand 2 "const_int_operand" "n")))
10506 (clobber (match_operand 3 "register_operand" "=&r"))]
10507 "TARGET_INDIRECT_BRANCH_NOBP_CALL
10508 && TARGET_CPU_Z10
10509 && !SIBLING_CALL_P (insn)
10510 && GET_MODE (operands[3]) == Pmode"
10511 {
10512 s390_indirect_branch_via_thunk (REGNO (operands[1]),
10513 REGNO (operands[3]),
10514 NULL_RTX,
10515 s390_indirect_branch_type_call);
10516 return "";
10517 }
10518 [(set_attr "op_type" "RIL")
10519 (set_attr "mnemonic" "brasl")
10520 (set_attr "type" "jsr")
10521 (set_attr "atype" "agen")
10522 (set_attr "z196prop" "z196_cracked")])
10523
10524 (define_insn "*basr_r_via_thunk"
10525 [(set (match_operand 0 "" "")
10526 (call (mem:QI (match_operand 1 "register_operand" "a"))
10527 (match_operand 2 "const_int_operand" "n")))
10528 (clobber (match_operand 3 "register_operand" "=&r"))
10529 (clobber (reg:P INDIRECT_BRANCH_THUNK_REGNUM))]
10530 "TARGET_INDIRECT_BRANCH_NOBP_CALL
10531 && !TARGET_CPU_Z10
10532 && !SIBLING_CALL_P (insn)
10533 && GET_MODE (operands[3]) == Pmode"
10534 {
10535 s390_indirect_branch_via_thunk (REGNO (operands[1]),
10536 REGNO (operands[3]),
10537 NULL_RTX,
10538 s390_indirect_branch_type_call);
10539 return "";
10540 }
10541 [(set_attr "op_type" "RIL")
10542 (set_attr "mnemonic" "brasl")
10543 (set_attr "type" "jsr")
10544 (set_attr "atype" "agen")
10545 (set_attr "z196prop" "z196_cracked")])
10546
10547 ;;
10548 ;;- Thread-local storage support.
10549 ;;
10550
10551 (define_expand "@get_thread_pointer<mode>"
10552 [(set (match_operand:P 0 "nonimmediate_operand" "")
10553 (unspec:P [(reg:P TP_REGNUM)] UNSPEC_GET_TP))]
10554 ""
10555 "")
10556
10557 (define_expand "set_thread_pointer<mode>"
10558 [(set (reg:P TP_REGNUM) (match_operand:P 0 "nonimmediate_operand" ""))
10559 (set (reg:P TP_REGNUM) (unspec_volatile:P [(reg:P TP_REGNUM)] UNSPECV_SET_TP))]
10560 ""
10561 "")
10562
10563 (define_insn "*set_tp"
10564 [(set (reg TP_REGNUM) (unspec_volatile [(reg TP_REGNUM)] UNSPECV_SET_TP))]
10565 ""
10566 ""
10567 [(set_attr "type" "none")
10568 (set_attr "length" "0")])
10569
10570 (define_insn "*tls_load_64"
10571 [(set (match_operand:DI 0 "register_operand" "=d")
10572 (unspec:DI [(match_operand:DI 1 "memory_operand" "T")
10573 (match_operand:DI 2 "" "")]
10574 UNSPEC_TLS_LOAD))]
10575 "TARGET_64BIT"
10576 "lg\t%0,%1%J2"
10577 [(set_attr "op_type" "RXE")
10578 (set_attr "z10prop" "z10_fwd_A3")])
10579
10580 (define_insn "*tls_load_31"
10581 [(set (match_operand:SI 0 "register_operand" "=d,d")
10582 (unspec:SI [(match_operand:SI 1 "memory_operand" "R,T")
10583 (match_operand:SI 2 "" "")]
10584 UNSPEC_TLS_LOAD))]
10585 "!TARGET_64BIT"
10586 "@
10587 l\t%0,%1%J2
10588 ly\t%0,%1%J2"
10589 [(set_attr "op_type" "RX,RXY")
10590 (set_attr "type" "load")
10591 (set_attr "cpu_facility" "*,longdisp")
10592 (set_attr "z10prop" "z10_fwd_A3,z10_fwd_A3")])
10593
10594 (define_insn "*bras_tls"
10595 [(set (match_operand 0 "" "")
10596 (call (mem:QI (match_operand 1 "bras_sym_operand" "X"))
10597 (match_operand 2 "const_int_operand" "n")))
10598 (clobber (match_operand 3 "register_operand" "=r"))
10599 (use (match_operand 4 "" ""))]
10600 "!SIBLING_CALL_P (insn)
10601 && TARGET_SMALL_EXEC
10602 && GET_MODE (operands[3]) == Pmode"
10603 "bras\t%3,%1%J4"
10604 [(set_attr "op_type" "RI")
10605 (set_attr "type" "jsr")
10606 (set_attr "z196prop" "z196_cracked")])
10607
10608 (define_insn "*brasl_tls"
10609 [(set (match_operand 0 "" "")
10610 (call (mem:QI (match_operand 1 "bras_sym_operand" "X"))
10611 (match_operand 2 "const_int_operand" "n")))
10612 (clobber (match_operand 3 "register_operand" "=r"))
10613 (use (match_operand 4 "" ""))]
10614 "!SIBLING_CALL_P (insn)
10615
10616 && GET_MODE (operands[3]) == Pmode"
10617 "brasl\t%3,%1%J4"
10618 [(set_attr "op_type" "RIL")
10619 (set_attr "type" "jsr")
10620 (set_attr "z196prop" "z196_cracked")
10621 (set_attr "relative_long" "yes")])
10622
10623 (define_insn "*basr_tls"
10624 [(set (match_operand 0 "" "")
10625 (call (mem:QI (match_operand 1 "address_operand" "ZR"))
10626 (match_operand 2 "const_int_operand" "n")))
10627 (clobber (match_operand 3 "register_operand" "=r"))
10628 (use (match_operand 4 "" ""))]
10629 "!SIBLING_CALL_P (insn) && GET_MODE (operands[3]) == Pmode"
10630 {
10631 if (get_attr_op_type (insn) == OP_TYPE_RR)
10632 return "basr\t%3,%1%J4";
10633 else
10634 return "bas\t%3,%a1%J4";
10635 }
10636 [(set (attr "op_type")
10637 (if_then_else (match_operand 1 "register_operand" "")
10638 (const_string "RR") (const_string "RX")))
10639 (set_attr "type" "jsr")
10640 (set_attr "atype" "agen")
10641 (set_attr "z196prop" "z196_cracked")])
10642
10643 ;;
10644 ;;- Atomic operations
10645 ;;
10646
10647 ;
10648 ; memory barrier patterns.
10649 ;
10650
10651 (define_expand "mem_thread_fence"
10652 [(match_operand:SI 0 "const_int_operand")] ;; model
10653 ""
10654 {
10655 /* Unless this is a SEQ_CST fence, the s390 memory model is strong
10656 enough not to require barriers of any kind. */
10657 if (is_mm_seq_cst (memmodel_from_int (INTVAL (operands[0]))))
10658 {
10659 rtx mem = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
10660 MEM_VOLATILE_P (mem) = 1;
10661 emit_insn (gen_mem_thread_fence_1 (mem));
10662 }
10663 DONE;
10664 })
10665
10666 ; Although bcr is superscalar on Z10, this variant will never
10667 ; become part of an execution group.
10668 ; With z196 we can make use of the fast-BCR-serialization facility.
10669 ; This allows for a slightly faster sync which is sufficient for our
10670 ; purposes.
10671 (define_insn "mem_thread_fence_1"
10672 [(set (match_operand:BLK 0 "" "")
10673 (unspec:BLK [(match_dup 0)] UNSPEC_MB))]
10674 ""
10675 {
10676 if (TARGET_Z196)
10677 return "bcr\t14,0";
10678 else
10679 return "bcr\t15,0";
10680 }
10681 [(set_attr "op_type" "RR")
10682 (set_attr "mnemonic" "bcr_flush")
10683 (set_attr "z196prop" "z196_alone")])
10684
10685 ;
10686 ; atomic load/store operations
10687 ;
10688
10689 ; Atomic loads need not examine the memory model at all.
10690 (define_expand "atomic_load<mode>"
10691 [(match_operand:DINT 0 "register_operand") ;; output
10692 (match_operand:DINT 1 "memory_operand") ;; memory
10693 (match_operand:SI 2 "const_int_operand")] ;; model
10694 ""
10695 {
10696 if (MEM_ALIGN (operands[1]) < GET_MODE_BITSIZE (GET_MODE (operands[1])))
10697 FAIL;
10698
10699 if (<MODE>mode == TImode)
10700 emit_insn (gen_atomic_loadti_1 (operands[0], operands[1]));
10701 else if (<MODE>mode == DImode && !TARGET_ZARCH)
10702 emit_insn (gen_atomic_loaddi_1 (operands[0], operands[1]));
10703 else
10704 emit_move_insn (operands[0], operands[1]);
10705 DONE;
10706 })
10707
10708 ; Different from movdi_31 in that we want no splitters.
10709 (define_insn "atomic_loaddi_1"
10710 [(set (match_operand:DI 0 "register_operand" "=d,d,!*f,!*f")
10711 (unspec:DI [(match_operand:DI 1 "memory_operand" "Q,S,R,T")]
10712 UNSPEC_MOVA))]
10713 "!TARGET_ZARCH"
10714 "@
10715 lm\t%0,%M0,%S1
10716 lmy\t%0,%M0,%S1
10717 ld\t%0,%1
10718 ldy\t%0,%1"
10719 [(set_attr "op_type" "RS,RSY,RS,RSY")
10720 (set_attr "cpu_facility" "*,longdisp,*,longdisp")
10721 (set_attr "type" "lm,lm,floaddf,floaddf")])
10722
10723 (define_insn "atomic_loadti_1"
10724 [(set (match_operand:TI 0 "register_operand" "=r")
10725 (unspec:TI [(match_operand:TI 1 "memory_operand" "T")]
10726 UNSPEC_MOVA))]
10727 "TARGET_ZARCH"
10728 "lpq\t%0,%1"
10729 [(set_attr "op_type" "RXY")
10730 (set_attr "type" "other")])
10731
10732 ; Atomic stores must(?) enforce sequential consistency.
10733 (define_expand "atomic_store<mode>"
10734 [(match_operand:DINT 0 "memory_operand") ;; memory
10735 (match_operand:DINT 1 "register_operand") ;; input
10736 (match_operand:SI 2 "const_int_operand")] ;; model
10737 ""
10738 {
10739 enum memmodel model = memmodel_from_int (INTVAL (operands[2]));
10740
10741 if (MEM_ALIGN (operands[0]) < GET_MODE_BITSIZE (GET_MODE (operands[0])))
10742 FAIL;
10743
10744 if (<MODE>mode == TImode)
10745 emit_insn (gen_atomic_storeti_1 (operands[0], operands[1]));
10746 else if (<MODE>mode == DImode && !TARGET_ZARCH)
10747 emit_insn (gen_atomic_storedi_1 (operands[0], operands[1]));
10748 else
10749 emit_move_insn (operands[0], operands[1]);
10750 if (is_mm_seq_cst (model))
10751 emit_insn (gen_mem_thread_fence (operands[2]));
10752 DONE;
10753 })
10754
10755 ; Different from movdi_31 in that we want no splitters.
10756 (define_insn "atomic_storedi_1"
10757 [(set (match_operand:DI 0 "memory_operand" "=Q,S,R,T")
10758 (unspec:DI [(match_operand:DI 1 "register_operand" "d,d,!*f,!*f")]
10759 UNSPEC_MOVA))]
10760 "!TARGET_ZARCH"
10761 "@
10762 stm\t%1,%N1,%S0
10763 stmy\t%1,%N1,%S0
10764 std %1,%0
10765 stdy %1,%0"
10766 [(set_attr "op_type" "RS,RSY,RS,RSY")
10767 (set_attr "cpu_facility" "*,longdisp,*,longdisp")
10768 (set_attr "type" "stm,stm,fstoredf,fstoredf")])
10769
10770 (define_insn "atomic_storeti_1"
10771 [(set (match_operand:TI 0 "memory_operand" "=T")
10772 (unspec:TI [(match_operand:TI 1 "register_operand" "r")]
10773 UNSPEC_MOVA))]
10774 "TARGET_ZARCH"
10775 "stpq\t%1,%0"
10776 [(set_attr "op_type" "RXY")
10777 (set_attr "type" "other")])
10778
10779 ;
10780 ; compare and swap patterns.
10781 ;
10782
10783 (define_expand "atomic_compare_and_swap<mode>"
10784 [(match_operand:SI 0 "register_operand") ;; bool success output
10785 (match_operand:DINT 1 "nonimmediate_operand");; oldval output
10786 (match_operand:DINT 2 "s_operand") ;; memory
10787 (match_operand:DINT 3 "general_operand") ;; expected intput
10788 (match_operand:DINT 4 "general_operand") ;; newval intput
10789 (match_operand:SI 5 "const_int_operand") ;; is_weak
10790 (match_operand:SI 6 "const_int_operand") ;; success model
10791 (match_operand:SI 7 "const_int_operand")] ;; failure model
10792 ""
10793 {
10794 if (GET_MODE_BITSIZE (<MODE>mode) >= 16
10795 && GET_MODE_BITSIZE (<MODE>mode) > MEM_ALIGN (operands[2]))
10796 FAIL;
10797
10798 s390_expand_cs (<MODE>mode, operands[0], operands[1], operands[2],
10799 operands[3], operands[4], INTVAL (operands[5]));
10800 DONE;})
10801
10802 (define_expand "atomic_compare_and_swap<mode>_internal"
10803 [(parallel
10804 [(set (match_operand:DGPR 0 "register_operand")
10805 (match_operand:DGPR 1 "s_operand"))
10806 (set (match_dup 1)
10807 (unspec_volatile:DGPR
10808 [(match_dup 1)
10809 (match_operand:DGPR 2 "register_operand")
10810 (match_operand:DGPR 3 "register_operand")]
10811 UNSPECV_CAS))
10812 (set (match_operand 4 "cc_reg_operand")
10813 (match_dup 5))])]
10814 "GET_MODE (operands[4]) == CCZmode
10815 || GET_MODE (operands[4]) == CCZ1mode"
10816 {
10817 operands[5]
10818 = gen_rtx_COMPARE (GET_MODE (operands[4]), operands[1], operands[2]);
10819 })
10820
10821 ; cdsg, csg
10822 (define_insn "*atomic_compare_and_swap<mode>_1"
10823 [(set (match_operand:TDI 0 "register_operand" "=r")
10824 (match_operand:TDI 1 "nonsym_memory_operand" "+S"))
10825 (set (match_dup 1)
10826 (unspec_volatile:TDI
10827 [(match_dup 1)
10828 (match_operand:TDI 2 "register_operand" "0")
10829 (match_operand:TDI 3 "register_operand" "r")]
10830 UNSPECV_CAS))
10831 (set (reg CC_REGNUM)
10832 (compare (match_dup 1) (match_dup 2)))]
10833 "TARGET_ZARCH
10834 && s390_match_ccmode (insn, CCZ1mode)"
10835 "c<td>sg\t%0,%3,%S1"
10836 [(set_attr "op_type" "RSY")
10837 (set_attr "type" "sem")])
10838
10839 ; cds, cdsy
10840 (define_insn "*atomic_compare_and_swapdi_2"
10841 [(set (match_operand:DI 0 "register_operand" "=r,r")
10842 (match_operand:DI 1 "nonsym_memory_operand" "+Q,S"))
10843 (set (match_dup 1)
10844 (unspec_volatile:DI
10845 [(match_dup 1)
10846 (match_operand:DI 2 "register_operand" "0,0")
10847 (match_operand:DI 3 "register_operand" "r,r")]
10848 UNSPECV_CAS))
10849 (set (reg CC_REGNUM)
10850 (compare (match_dup 1) (match_dup 2)))]
10851 "!TARGET_ZARCH
10852 && s390_match_ccmode (insn, CCZ1mode)"
10853 "@
10854 cds\t%0,%3,%S1
10855 cdsy\t%0,%3,%S1"
10856 [(set_attr "op_type" "RS,RSY")
10857 (set_attr "cpu_facility" "*,longdisp")
10858 (set_attr "type" "sem")])
10859
10860 ; cs, csy
10861 (define_insn "*atomic_compare_and_swapsi_3"
10862 [(set (match_operand:SI 0 "register_operand" "=r,r")
10863 (match_operand:SI 1 "nonsym_memory_operand" "+Q,S"))
10864 (set (match_dup 1)
10865 (unspec_volatile:SI
10866 [(match_dup 1)
10867 (match_operand:SI 2 "register_operand" "0,0")
10868 (match_operand:SI 3 "register_operand" "r,r")]
10869 UNSPECV_CAS))
10870 (set (reg CC_REGNUM)
10871 (compare (match_dup 1) (match_dup 2)))]
10872 "s390_match_ccmode (insn, CCZ1mode)"
10873 "@
10874 cs\t%0,%3,%S1
10875 csy\t%0,%3,%S1"
10876 [(set_attr "op_type" "RS,RSY")
10877 (set_attr "cpu_facility" "*,longdisp")
10878 (set_attr "type" "sem")])
10879
10880 ;
10881 ; Other atomic instruction patterns.
10882 ;
10883
10884 ; z196 load and add, xor, or and and instructions
10885
10886 (define_expand "atomic_fetch_<atomic><mode>"
10887 [(match_operand:GPR 0 "register_operand") ;; val out
10888 (ATOMIC_Z196:GPR
10889 (match_operand:GPR 1 "memory_operand") ;; memory
10890 (match_operand:GPR 2 "register_operand")) ;; val in
10891 (match_operand:SI 3 "const_int_operand")] ;; model
10892 "TARGET_Z196"
10893 {
10894 if (MEM_ALIGN (operands[1]) < GET_MODE_BITSIZE (GET_MODE (operands[1])))
10895 FAIL;
10896
10897 emit_insn (gen_atomic_fetch_<atomic><mode>_iaf
10898 (operands[0], operands[1], operands[2]));
10899 DONE;
10900 })
10901
10902 ; lan, lang, lao, laog, lax, laxg, laa, laag
10903 (define_insn "atomic_fetch_<atomic><mode>_iaf"
10904 [(set (match_operand:GPR 0 "register_operand" "=d")
10905 (match_operand:GPR 1 "memory_operand" "+S"))
10906 (set (match_dup 1)
10907 (unspec_volatile:GPR
10908 [(ATOMIC_Z196:GPR (match_dup 1)
10909 (match_operand:GPR 2 "general_operand" "d"))]
10910 UNSPECV_ATOMIC_OP))
10911 (clobber (reg:CC CC_REGNUM))]
10912 "TARGET_Z196"
10913 "la<noxa><g>\t%0,%2,%1"
10914 [(set_attr "op_type" "RSY")
10915 (set_attr "type" "sem")])
10916
10917 ;; For SImode and larger, the optabs.c code will do just fine in
10918 ;; expanding a compare-and-swap loop. For QI/HImode, we can do
10919 ;; better by expanding our own loop.
10920
10921 (define_expand "atomic_<atomic><mode>"
10922 [(ATOMIC:HQI
10923 (match_operand:HQI 0 "memory_operand") ;; memory
10924 (match_operand:HQI 1 "general_operand")) ;; val in
10925 (match_operand:SI 2 "const_int_operand")] ;; model
10926 ""
10927 {
10928 s390_expand_atomic (<MODE>mode, <CODE>, NULL_RTX, operands[0],
10929 operands[1], false);
10930 DONE;
10931 })
10932
10933 (define_expand "atomic_fetch_<atomic><mode>"
10934 [(match_operand:HQI 0 "register_operand") ;; val out
10935 (ATOMIC:HQI
10936 (match_operand:HQI 1 "memory_operand") ;; memory
10937 (match_operand:HQI 2 "general_operand")) ;; val in
10938 (match_operand:SI 3 "const_int_operand")] ;; model
10939 ""
10940 {
10941 s390_expand_atomic (<MODE>mode, <CODE>, operands[0], operands[1],
10942 operands[2], false);
10943 DONE;
10944 })
10945
10946 (define_expand "atomic_<atomic>_fetch<mode>"
10947 [(match_operand:HQI 0 "register_operand") ;; val out
10948 (ATOMIC:HQI
10949 (match_operand:HQI 1 "memory_operand") ;; memory
10950 (match_operand:HQI 2 "general_operand")) ;; val in
10951 (match_operand:SI 3 "const_int_operand")] ;; model
10952 ""
10953 {
10954 s390_expand_atomic (<MODE>mode, <CODE>, operands[0], operands[1],
10955 operands[2], true);
10956 DONE;
10957 })
10958
10959 ;; Pattern to implement atomic_exchange with a compare-and-swap loop. The code
10960 ;; generated by the middleend is not good.
10961 (define_expand "atomic_exchange<mode>"
10962 [(match_operand:DINT 0 "register_operand") ;; val out
10963 (match_operand:DINT 1 "s_operand") ;; memory
10964 (match_operand:DINT 2 "general_operand") ;; val in
10965 (match_operand:SI 3 "const_int_operand")] ;; model
10966 ""
10967 {
10968 if (<MODE>mode != QImode
10969 && MEM_ALIGN (operands[1]) < GET_MODE_BITSIZE (<MODE>mode))
10970 FAIL;
10971 if (<MODE>mode == HImode || <MODE>mode == QImode)
10972 s390_expand_atomic (<MODE>mode, SET, operands[0], operands[1], operands[2],
10973 false);
10974 else if (<MODE>mode == SImode || TARGET_ZARCH)
10975 s390_expand_atomic_exchange_tdsi (operands[0], operands[1], operands[2]);
10976 else
10977 FAIL;
10978 DONE;
10979 })
10980
10981 ;;
10982 ;;- Miscellaneous instructions.
10983 ;;
10984
10985 ;
10986 ; allocate stack instruction pattern(s).
10987 ;
10988
10989 (define_expand "allocate_stack"
10990 [(match_operand 0 "general_operand" "")
10991 (match_operand 1 "general_operand" "")]
10992 "TARGET_BACKCHAIN"
10993 {
10994 rtx temp = gen_reg_rtx (Pmode);
10995
10996 emit_move_insn (temp, s390_back_chain_rtx ());
10997 anti_adjust_stack (operands[1]);
10998 emit_move_insn (s390_back_chain_rtx (), temp);
10999
11000 emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
11001 DONE;
11002 })
11003
11004
11005 ;
11006 ; setjmp instruction pattern.
11007 ;
11008
11009 (define_expand "builtin_setjmp_receiver"
11010 [(match_operand 0 "" "")]
11011 "flag_pic"
11012 {
11013 emit_insn (s390_load_got ());
11014 emit_use (pic_offset_table_rtx);
11015 DONE;
11016 })
11017
11018 ;; These patterns say how to save and restore the stack pointer. We need not
11019 ;; save the stack pointer at function level since we are careful to
11020 ;; preserve the backchain. At block level, we have to restore the backchain
11021 ;; when we restore the stack pointer.
11022 ;;
11023 ;; For nonlocal gotos, we must save both the stack pointer and its
11024 ;; backchain and restore both. Note that in the nonlocal case, the
11025 ;; save area is a memory location.
11026
11027 (define_expand "save_stack_function"
11028 [(match_operand 0 "general_operand" "")
11029 (match_operand 1 "general_operand" "")]
11030 ""
11031 "DONE;")
11032
11033 (define_expand "restore_stack_function"
11034 [(match_operand 0 "general_operand" "")
11035 (match_operand 1 "general_operand" "")]
11036 ""
11037 "DONE;")
11038
11039 (define_expand "restore_stack_block"
11040 [(match_operand 0 "register_operand" "")
11041 (match_operand 1 "register_operand" "")]
11042 "TARGET_BACKCHAIN"
11043 {
11044 rtx temp = gen_reg_rtx (Pmode);
11045
11046 emit_move_insn (temp, s390_back_chain_rtx ());
11047 emit_move_insn (operands[0], operands[1]);
11048 emit_move_insn (s390_back_chain_rtx (), temp);
11049
11050 DONE;
11051 })
11052
11053 (define_expand "save_stack_nonlocal"
11054 [(match_operand 0 "memory_operand" "")
11055 (match_operand 1 "register_operand" "")]
11056 ""
11057 {
11058 rtx base = gen_rtx_REG (Pmode, BASE_REGNUM);
11059
11060 /* Copy the backchain to the first word, sp to the second and the
11061 literal pool base to the third. */
11062
11063 rtx save_bc = adjust_address (operands[0], Pmode, 0);
11064 rtx save_sp = adjust_address (operands[0], Pmode, GET_MODE_SIZE (Pmode));
11065 rtx save_bp = adjust_address (operands[0], Pmode, 2 * GET_MODE_SIZE (Pmode));
11066
11067 if (TARGET_BACKCHAIN)
11068 emit_move_insn (save_bc, force_reg (Pmode, s390_back_chain_rtx ()));
11069
11070 emit_move_insn (save_sp, operands[1]);
11071 emit_move_insn (save_bp, base);
11072
11073 DONE;
11074 })
11075
11076 (define_expand "restore_stack_nonlocal"
11077 [(match_operand 0 "register_operand" "")
11078 (match_operand 1 "memory_operand" "")]
11079 ""
11080 {
11081 rtx base = gen_rtx_REG (Pmode, BASE_REGNUM);
11082 rtx temp = NULL_RTX;
11083
11084 /* Restore the backchain from the first word, sp from the second and the
11085 literal pool base from the third. */
11086
11087 rtx save_bc = adjust_address (operands[1], Pmode, 0);
11088 rtx save_sp = adjust_address (operands[1], Pmode, GET_MODE_SIZE (Pmode));
11089 rtx save_bp = adjust_address (operands[1], Pmode, 2 * GET_MODE_SIZE (Pmode));
11090
11091 if (TARGET_BACKCHAIN)
11092 temp = force_reg (Pmode, save_bc);
11093
11094 emit_move_insn (base, save_bp);
11095 emit_move_insn (operands[0], save_sp);
11096
11097 if (temp)
11098 emit_move_insn (s390_back_chain_rtx (), temp);
11099
11100 emit_use (base);
11101 DONE;
11102 })
11103
11104 (define_expand "exception_receiver"
11105 [(const_int 0)]
11106 ""
11107 {
11108 s390_set_has_landing_pad_p (true);
11109 DONE;
11110 })
11111
11112 ;
11113 ; nop instruction pattern(s).
11114 ;
11115
11116 (define_insn "nop"
11117 [(const_int 0)]
11118 ""
11119 "nopr\t%%r0"
11120 [(set_attr "op_type" "RR")])
11121
11122 ; non-branch NOPs required for optimizing compare-and-branch patterns
11123 ; on z10
11124
11125 (define_insn "nop_lr0"
11126 [(unspec_volatile [(const_int 0)] UNSPECV_NOP_LR_0)]
11127 ""
11128 "lr\t0,0"
11129 [(set_attr "op_type" "RR")
11130 (set_attr "z10prop" "z10_fr_E1")])
11131
11132 (define_insn "nop_lr1"
11133 [(unspec_volatile [(const_int 0)] UNSPECV_NOP_LR_1)]
11134 ""
11135 "lr\t1,1"
11136 [(set_attr "op_type" "RR")])
11137
11138 ;;- Undeletable nops (used for hotpatching)
11139
11140 (define_insn "nop_2_byte"
11141 [(unspec_volatile [(const_int 0)] UNSPECV_NOP_2_BYTE)]
11142 ""
11143 "nopr\t%%r0"
11144 [(set_attr "op_type" "RR")])
11145
11146 (define_insn "nop_4_byte"
11147 [(unspec_volatile [(const_int 0)] UNSPECV_NOP_4_BYTE)]
11148 ""
11149 "nop\t0"
11150 [(set_attr "op_type" "RX")])
11151
11152 (define_insn "nop_6_byte"
11153 [(unspec_volatile [(const_int 0)] UNSPECV_NOP_6_BYTE)]
11154 ""
11155 "brcl\t0, 0"
11156 [(set_attr "op_type" "RIL")
11157 (set_attr "relative_long" "yes")])
11158
11159
11160 ;
11161 ; Special literal pool access instruction pattern(s).
11162 ;
11163
11164 (define_insn "*pool_entry"
11165 [(unspec_volatile [(match_operand 0 "consttable_operand" "X")]
11166 UNSPECV_POOL_ENTRY)]
11167 ""
11168 {
11169 machine_mode mode = GET_MODE (PATTERN (insn));
11170 unsigned int align = GET_MODE_BITSIZE (mode);
11171 s390_output_pool_entry (operands[0], mode, align);
11172 return "";
11173 }
11174 [(set (attr "length")
11175 (symbol_ref "GET_MODE_SIZE (GET_MODE (PATTERN (insn)))"))])
11176
11177 (define_insn "pool_align"
11178 [(unspec_volatile [(match_operand 0 "const_int_operand" "n")]
11179 UNSPECV_POOL_ALIGN)]
11180 ""
11181 ".align\t%0"
11182 [(set (attr "length") (symbol_ref "INTVAL (operands[0])"))])
11183
11184 (define_insn "pool_section_start"
11185 [(unspec_volatile [(const_int 1)] UNSPECV_POOL_SECTION)]
11186 ""
11187 {
11188 switch_to_section (targetm.asm_out.function_rodata_section
11189 (current_function_decl));
11190 return "";
11191 }
11192 [(set_attr "length" "0")])
11193
11194 (define_insn "pool_section_end"
11195 [(unspec_volatile [(const_int 0)] UNSPECV_POOL_SECTION)]
11196 ""
11197 {
11198 switch_to_section (current_function_section ());
11199 return "";
11200 }
11201 [(set_attr "length" "0")])
11202
11203 (define_insn "main_base_64"
11204 [(set (match_operand 0 "register_operand" "=a")
11205 (unspec [(label_ref (match_operand 1 "" ""))] UNSPEC_MAIN_BASE))]
11206 "GET_MODE (operands[0]) == Pmode"
11207 "larl\t%0,%1"
11208 [(set_attr "op_type" "RIL")
11209 (set_attr "type" "larl")
11210 (set_attr "z10prop" "z10_fwd_A1")
11211 (set_attr "relative_long" "yes")])
11212
11213 (define_insn "main_pool"
11214 [(set (match_operand 0 "register_operand" "=a")
11215 (unspec_volatile [(const_int 0)] UNSPECV_MAIN_POOL))]
11216 "GET_MODE (operands[0]) == Pmode"
11217 {
11218 gcc_unreachable ();
11219 }
11220 [(set (attr "type")
11221 (const_string "larl"))])
11222
11223 (define_insn "reload_base_64"
11224 [(set (match_operand 0 "register_operand" "=a")
11225 (unspec [(label_ref (match_operand 1 "" ""))] UNSPEC_RELOAD_BASE))]
11226 "GET_MODE (operands[0]) == Pmode"
11227 "larl\t%0,%1"
11228 [(set_attr "op_type" "RIL")
11229 (set_attr "type" "larl")
11230 (set_attr "z10prop" "z10_fwd_A1")])
11231
11232 (define_insn "pool"
11233 [(unspec_volatile [(match_operand 0 "const_int_operand" "n")] UNSPECV_POOL)]
11234 ""
11235 {
11236 gcc_unreachable ();
11237 }
11238 [(set (attr "length") (symbol_ref "INTVAL (operands[0])"))])
11239
11240 ;;
11241 ;; Insns related to generating the function prologue and epilogue.
11242 ;;
11243
11244
11245 (define_expand "prologue"
11246 [(use (const_int 0))]
11247 ""
11248 "s390_emit_prologue (); DONE;")
11249
11250 (define_expand "epilogue"
11251 [(use (const_int 1))]
11252 ""
11253 "s390_emit_epilogue (false); DONE;")
11254
11255 (define_expand "sibcall_epilogue"
11256 [(use (const_int 0))]
11257 ""
11258 "s390_emit_epilogue (true); DONE;")
11259
11260 ;; A direct return instruction, without using an epilogue.
11261 (define_insn "<code>"
11262 [(ANY_RETURN)]
11263 "s390_can_use_<code>_insn ()"
11264 {
11265 if (TARGET_INDIRECT_BRANCH_NOBP_RET)
11266 {
11267 /* The target is always r14 so there is no clobber
11268 of r1 needed for pre z10 targets. */
11269 s390_indirect_branch_via_thunk (RETURN_REGNUM,
11270 INVALID_REGNUM,
11271 NULL_RTX,
11272 s390_indirect_branch_type_return);
11273 return "";
11274 }
11275 else
11276 return "br\t%%r14";
11277 }
11278 [(set (attr "op_type")
11279 (if_then_else (match_test "TARGET_INDIRECT_BRANCH_NOBP_RET")
11280 (const_string "RIL")
11281 (const_string "RR")))
11282 (set (attr "mnemonic")
11283 (if_then_else (match_test "TARGET_INDIRECT_BRANCH_NOBP_RET")
11284 (const_string "jg")
11285 (const_string "br")))
11286 (set_attr "type" "jsr")
11287 (set_attr "atype" "agen")])
11288
11289
11290 (define_expand "return_use"
11291 [(parallel
11292 [(return)
11293 (use (match_operand 0 "register_operand" "a"))])]
11294 ""
11295 {
11296 if (!TARGET_CPU_Z10
11297 && TARGET_INDIRECT_BRANCH_NOBP_RET_OPTION)
11298 {
11299 if (TARGET_64BIT)
11300 emit_jump_insn (gen_returndi_prez10 (operands[0]));
11301 else
11302 emit_jump_insn (gen_returnsi_prez10 (operands[0]));
11303 DONE;
11304 }
11305 })
11306
11307 (define_insn "*return<mode>"
11308 [(return)
11309 (use (match_operand:P 0 "register_operand" "a"))]
11310 "TARGET_CPU_Z10 || !TARGET_INDIRECT_BRANCH_NOBP_RET_OPTION"
11311 {
11312 if (TARGET_INDIRECT_BRANCH_NOBP_RET)
11313 {
11314 s390_indirect_branch_via_thunk (REGNO (operands[0]),
11315 INVALID_REGNUM,
11316 NULL_RTX,
11317 s390_indirect_branch_type_return);
11318 return "";
11319 }
11320 else
11321 return "br\t%0";
11322 }
11323 [(set (attr "op_type")
11324 (if_then_else (match_test "TARGET_INDIRECT_BRANCH_NOBP_RET")
11325 (const_string "RIL")
11326 (const_string "RR")))
11327 (set (attr "mnemonic")
11328 (if_then_else (match_test "TARGET_INDIRECT_BRANCH_NOBP_RET")
11329 (const_string "jg")
11330 (const_string "br")))
11331 (set_attr "type" "jsr")
11332 (set_attr "atype" "agen")])
11333
11334 (define_insn "return<mode>_prez10"
11335 [(return)
11336 (use (match_operand:P 0 "register_operand" "a"))
11337 (clobber (reg:P INDIRECT_BRANCH_THUNK_REGNUM))]
11338 "!TARGET_CPU_Z10 && TARGET_INDIRECT_BRANCH_NOBP_RET_OPTION"
11339 {
11340 if (TARGET_INDIRECT_BRANCH_NOBP_RET)
11341 {
11342 s390_indirect_branch_via_thunk (REGNO (operands[0]),
11343 INVALID_REGNUM,
11344 NULL_RTX,
11345 s390_indirect_branch_type_return);
11346 return "";
11347 }
11348 else
11349 return "br\t%0";
11350 }
11351 [(set (attr "op_type")
11352 (if_then_else (match_test "TARGET_INDIRECT_BRANCH_NOBP_RET")
11353 (const_string "RIL")
11354 (const_string "RR")))
11355 (set (attr "mnemonic")
11356 (if_then_else (match_test "TARGET_INDIRECT_BRANCH_NOBP_RET")
11357 (const_string "jg")
11358 (const_string "br")))
11359 (set_attr "type" "jsr")
11360 (set_attr "atype" "agen")])
11361
11362
11363 ;; Instruction definition to extend a 31-bit pointer into a 64-bit
11364 ;; pointer. This is used for compatibility.
11365
11366 (define_expand "ptr_extend"
11367 [(set (match_operand:DI 0 "register_operand" "=r")
11368 (match_operand:SI 1 "register_operand" "r"))]
11369 "TARGET_64BIT"
11370 {
11371 emit_insn (gen_anddi3 (operands[0],
11372 gen_lowpart (DImode, operands[1]),
11373 GEN_INT (0x7fffffff)));
11374 DONE;
11375 })
11376
11377 ;; Instruction definition to expand eh_return macro to support
11378 ;; swapping in special linkage return addresses.
11379
11380 (define_expand "eh_return"
11381 [(use (match_operand 0 "register_operand" ""))]
11382 "TARGET_TPF"
11383 {
11384 s390_emit_tpf_eh_return (operands[0]);
11385 DONE;
11386 })
11387
11388 ;
11389 ; Stack Protector Patterns
11390 ;
11391
11392 (define_expand "stack_protect_set"
11393 [(set (match_operand 0 "memory_operand" "")
11394 (match_operand 1 "memory_operand" ""))]
11395 ""
11396 {
11397 #ifdef TARGET_THREAD_SSP_OFFSET
11398 operands[1]
11399 = gen_rtx_MEM (Pmode, gen_rtx_PLUS (Pmode, s390_get_thread_pointer (),
11400 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
11401 #endif
11402 if (TARGET_64BIT)
11403 emit_insn (gen_stack_protect_setdi (operands[0], operands[1]));
11404 else
11405 emit_insn (gen_stack_protect_setsi (operands[0], operands[1]));
11406
11407 DONE;
11408 })
11409
11410 (define_insn "stack_protect_set<mode>"
11411 [(set (match_operand:DSI 0 "memory_operand" "=Q")
11412 (unspec:DSI [(match_operand:DSI 1 "memory_operand" "Q")] UNSPEC_SP_SET))]
11413 ""
11414 "mvc\t%O0(%G0,%R0),%S1"
11415 [(set_attr "op_type" "SS")])
11416
11417 (define_expand "stack_protect_test"
11418 [(set (reg:CC CC_REGNUM)
11419 (compare (match_operand 0 "memory_operand" "")
11420 (match_operand 1 "memory_operand" "")))
11421 (match_operand 2 "" "")]
11422 ""
11423 {
11424 rtx cc_reg, test;
11425 #ifdef TARGET_THREAD_SSP_OFFSET
11426 operands[1]
11427 = gen_rtx_MEM (Pmode, gen_rtx_PLUS (Pmode, s390_get_thread_pointer (),
11428 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
11429 #endif
11430 if (TARGET_64BIT)
11431 emit_insn (gen_stack_protect_testdi (operands[0], operands[1]));
11432 else
11433 emit_insn (gen_stack_protect_testsi (operands[0], operands[1]));
11434
11435 cc_reg = gen_rtx_REG (CCZmode, CC_REGNUM);
11436 test = gen_rtx_EQ (VOIDmode, cc_reg, const0_rtx);
11437 emit_jump_insn (gen_cbranchcc4 (test, cc_reg, const0_rtx, operands[2]));
11438 DONE;
11439 })
11440
11441 (define_insn "stack_protect_test<mode>"
11442 [(set (reg:CCZ CC_REGNUM)
11443 (unspec:CCZ [(match_operand:DSI 0 "memory_operand" "Q")
11444 (match_operand:DSI 1 "memory_operand" "Q")] UNSPEC_SP_TEST))]
11445 ""
11446 "clc\t%O0(%G0,%R0),%S1"
11447 [(set_attr "op_type" "SS")])
11448
11449 ; This is used in s390_emit_prologue in order to prevent insns
11450 ; adjusting the stack pointer to be moved over insns writing stack
11451 ; slots using a copy of the stack pointer in a different register.
11452 (define_insn "stack_tie"
11453 [(set (match_operand:BLK 0 "memory_operand" "+m")
11454 (unspec:BLK [(match_dup 0)] UNSPEC_TIE))]
11455 ""
11456 ""
11457 [(set_attr "length" "0")])
11458
11459
11460 (define_insn "stack_restore_from_fpr"
11461 [(set (reg:DI STACK_REGNUM)
11462 (match_operand:DI 0 "register_operand" "f"))
11463 (clobber (mem:BLK (scratch)))]
11464 "TARGET_Z10"
11465 "lgdr\t%%r15,%0"
11466 [(set_attr "op_type" "RRE")])
11467
11468 ;
11469 ; Data prefetch patterns
11470 ;
11471
11472 (define_insn "prefetch"
11473 [(prefetch (match_operand 0 "address_operand" "ZT,X")
11474 (match_operand:SI 1 "const_int_operand" " n,n")
11475 (match_operand:SI 2 "const_int_operand" " n,n"))]
11476 "TARGET_Z10"
11477 {
11478 switch (which_alternative)
11479 {
11480 case 0:
11481 return INTVAL (operands[1]) == 1 ? "pfd\t2,%a0" : "pfd\t1,%a0";
11482 case 1:
11483 if (larl_operand (operands[0], Pmode))
11484 return INTVAL (operands[1]) == 1 ? "pfdrl\t2,%a0" : "pfdrl\t1,%a0";
11485 /* fallthrough */
11486 default:
11487
11488 /* This might be reached for symbolic operands with an odd
11489 addend. We simply omit the prefetch for such rare cases. */
11490
11491 return "";
11492 }
11493 }
11494 [(set_attr "type" "load,larl")
11495 (set_attr "op_type" "RXY,RIL")
11496 (set_attr "z10prop" "z10_super")
11497 (set_attr "z196prop" "z196_alone")
11498 (set_attr "relative_long" "yes")])
11499
11500
11501 ;
11502 ; Byte swap instructions
11503 ;
11504
11505 ; FIXME: There is also mvcin but we cannot use it since src and target
11506 ; may overlap.
11507 ; lrvr, lrv, strv, lrvgr, lrvg, strvg
11508 (define_insn "bswap<mode>2"
11509 [(set (match_operand:GPR 0 "nonimmediate_operand" "=d,d,T")
11510 (bswap:GPR (match_operand:GPR 1 "nonimmediate_operand" " d,T,d")))]
11511 ""
11512 "@
11513 lrv<g>r\t%0,%1
11514 lrv<g>\t%0,%1
11515 strv<g>\t%1,%0"
11516 [(set_attr "type" "*,load,store")
11517 (set_attr "op_type" "RRE,RXY,RXY")
11518 (set_attr "z10prop" "z10_super")])
11519
11520 (define_insn "bswaphi2"
11521 [(set (match_operand:HI 0 "nonimmediate_operand" "=d,d,T")
11522 (bswap:HI (match_operand:HI 1 "nonimmediate_operand" " d,T,d")))]
11523 ""
11524 "@
11525 #
11526 lrvh\t%0,%1
11527 strvh\t%1,%0"
11528 [(set_attr "type" "*,load,store")
11529 (set_attr "op_type" "RRE,RXY,RXY")
11530 (set_attr "z10prop" "z10_super")])
11531
11532 (define_split
11533 [(set (match_operand:HI 0 "register_operand" "")
11534 (bswap:HI (match_operand:HI 1 "register_operand" "")))]
11535 ""
11536 [(set (match_dup 2) (bswap:SI (match_dup 3)))
11537 (set (match_dup 2) (lshiftrt:SI (match_dup 2) (const_int 16)))]
11538 {
11539 operands[2] = simplify_gen_subreg (SImode, operands[0], HImode, 0);
11540 operands[3] = simplify_gen_subreg (SImode, operands[1], HImode, 0);
11541 })
11542
11543
11544 ;
11545 ; Population count instruction
11546 ;
11547
11548 (define_insn "*popcountdi_z15_cc"
11549 [(set (reg CC_REGNUM)
11550 (compare (popcount:DI (match_operand:DI 1 "register_operand" "d"))
11551 (const_int 0)))
11552 (set (match_operand:DI 0 "register_operand" "=d")
11553 (match_dup 1))]
11554 "TARGET_Z15 && s390_match_ccmode (insn, CCTmode)"
11555 "popcnt\t%0,%1,8"
11556 [(set_attr "op_type" "RRF")])
11557
11558 (define_insn "*popcountdi_z15_cconly"
11559 [(set (reg CC_REGNUM)
11560 (compare (popcount:DI (match_operand:DI 1 "register_operand" "d"))
11561 (const_int 0)))
11562 (clobber (match_scratch:DI 0 "=d"))]
11563 "TARGET_Z15 && s390_match_ccmode(insn, CCTmode)"
11564 "popcnt\t%0,%1,8"
11565 [(set_attr "op_type" "RRF")])
11566
11567 (define_insn "*popcountdi_z15"
11568 [(set (match_operand:DI 0 "register_operand" "=d")
11569 (popcount:DI (match_operand:DI 1 "register_operand" "d")))
11570 (clobber (reg:CC CC_REGNUM))]
11571 "TARGET_Z15"
11572 "popcnt\t%0,%1,8"
11573 [(set_attr "op_type" "RRF")])
11574
11575 ; The pre-z15 popcount instruction counts the bits of op1 in 8 byte
11576 ; portions and stores the result in the corresponding bytes in op0.
11577 (define_insn "*popcount<mode>_z196"
11578 [(set (match_operand:INT 0 "register_operand" "=d")
11579 (unspec:INT [(match_operand:INT 1 "register_operand" "d")] UNSPEC_POPCNT))
11580 (clobber (reg:CC CC_REGNUM))]
11581 "TARGET_Z196"
11582 "popcnt\t%0,%1"
11583 [(set_attr "op_type" "RRE")])
11584
11585 (define_expand "popcountdi2_z196"
11586 [; popcnt op0, op1
11587 (parallel [(set (match_operand:DI 0 "register_operand" "")
11588 (unspec:DI [(match_operand:DI 1 "register_operand")]
11589 UNSPEC_POPCNT))
11590 (clobber (reg:CC CC_REGNUM))])
11591 ; sllg op2, op0, 32
11592 (set (match_dup 2) (ashift:DI (match_dup 0) (const_int 32)))
11593 ; agr op0, op2
11594 (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 2)))
11595 (clobber (reg:CC CC_REGNUM))])
11596 ; sllg op2, op0, 16
11597 (set (match_dup 2)
11598 (ashift:DI (match_dup 0) (const_int 16)))
11599 ; agr op0, op2
11600 (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 2)))
11601 (clobber (reg:CC CC_REGNUM))])
11602 ; sllg op2, op0, 8
11603 (set (match_dup 2) (ashift:DI (match_dup 0) (const_int 8)))
11604 ; agr op0, op2
11605 (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 2)))
11606 (clobber (reg:CC CC_REGNUM))])
11607 ; srlg op0, op0, 56
11608 (set (match_dup 0) (lshiftrt:DI (match_dup 0) (const_int 56)))]
11609 "TARGET_Z196"
11610 "operands[2] = gen_reg_rtx (DImode);")
11611
11612 (define_expand "popcountdi2"
11613 [(parallel
11614 [(set (match_operand:DI 0 "register_operand" "")
11615 (popcount:DI (match_operand:DI 1 "register_operand")))
11616 (clobber (reg:CC CC_REGNUM))])]
11617 "TARGET_Z196"
11618 {
11619 if (!TARGET_Z15)
11620 {
11621 emit_insn (gen_popcountdi2_z196 (operands[0], operands[1]));
11622 DONE;
11623 }
11624 })
11625
11626 (define_expand "popcountsi2_z196"
11627 [; popcnt op0, op1
11628 (parallel [(set (match_operand:SI 0 "register_operand" "")
11629 (unspec:SI [(match_operand:SI 1 "register_operand")]
11630 UNSPEC_POPCNT))
11631 (clobber (reg:CC CC_REGNUM))])
11632 ; sllk op2, op0, 16
11633 (set (match_dup 2)
11634 (ashift:SI (match_dup 0) (const_int 16)))
11635 ; ar op0, op2
11636 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
11637 (clobber (reg:CC CC_REGNUM))])
11638 ; sllk op2, op0, 8
11639 (set (match_dup 2) (ashift:SI (match_dup 0) (const_int 8)))
11640 ; ar op0, op2
11641 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
11642 (clobber (reg:CC CC_REGNUM))])
11643 ; srl op0, op0, 24
11644 (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 24)))]
11645 "TARGET_Z196"
11646 "operands[2] = gen_reg_rtx (SImode);")
11647
11648 ; popcount always counts on the full 64 bit. With the z196 version
11649 ; counting bits per byte we just ignore the upper 4 bytes. With the
11650 ; z15 version we have to zero out the upper 32 bits first.
11651 (define_expand "popcountsi2"
11652 [(set (match_dup 2)
11653 (zero_extend:DI (match_operand:SI 1 "register_operand")))
11654 (parallel [(set (match_dup 3) (popcount:DI (match_dup 2)))
11655 (clobber (reg:CC CC_REGNUM))])
11656 (set (match_operand:SI 0 "register_operand")
11657 (subreg:SI (match_dup 3) 4))]
11658 "TARGET_Z196"
11659 {
11660 if (!TARGET_Z15)
11661 {
11662 emit_insn (gen_popcountsi2_z196 (operands[0], operands[1]));
11663 DONE;
11664 }
11665 else
11666 {
11667 operands[2] = gen_reg_rtx (DImode);
11668 operands[3] = gen_reg_rtx (DImode);
11669 }
11670 })
11671
11672 (define_expand "popcounthi2_z196"
11673 [; popcnt op0, op1
11674 (parallel [(set (match_operand:HI 0 "register_operand" "")
11675 (unspec:HI [(match_operand:HI 1 "register_operand")]
11676 UNSPEC_POPCNT))
11677 (clobber (reg:CC CC_REGNUM))])
11678 ; sllk op2, op0, 8
11679 (set (match_dup 2)
11680 (ashift:SI (match_dup 0) (const_int 8)))
11681 ; ar op0, op2
11682 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
11683 (clobber (reg:CC CC_REGNUM))])
11684 ; srl op0, op0, 8
11685 (set (match_dup 0) (lshiftrt:HI (match_dup 0) (const_int 8)))]
11686 "TARGET_Z196"
11687 "operands[2] = gen_reg_rtx (SImode);")
11688
11689 (define_expand "popcounthi2"
11690 [(set (match_dup 2)
11691 (zero_extend:DI (match_operand:HI 1 "register_operand")))
11692 (parallel [(set (match_dup 3) (popcount:DI (match_dup 2)))
11693 (clobber (reg:CC CC_REGNUM))])
11694 (set (match_operand:HI 0 "register_operand")
11695 (subreg:HI (match_dup 3) 6))]
11696 "TARGET_Z196"
11697 {
11698 if (!TARGET_Z15)
11699 {
11700 emit_insn (gen_popcounthi2_z196 (operands[0], operands[1]));
11701 DONE;
11702 }
11703 else
11704 {
11705 operands[2] = gen_reg_rtx (DImode);
11706 operands[3] = gen_reg_rtx (DImode);
11707 }
11708 })
11709
11710 ; For popcount on a single byte the old z196 style popcount
11711 ; instruction is ideal. Since it anyway does a byte-wise popcount we
11712 ; just use it instead of zero extending the QImode input to DImode and
11713 ; using the z15 popcount variant.
11714 (define_expand "popcountqi2"
11715 [; popcnt op0, op1
11716 (parallel [(set (match_operand:QI 0 "register_operand" "")
11717 (unspec:QI [(match_operand:QI 1 "register_operand")]
11718 UNSPEC_POPCNT))
11719 (clobber (reg:CC CC_REGNUM))])]
11720 "TARGET_Z196"
11721 "")
11722
11723 ;;
11724 ;;- Copy sign instructions
11725 ;;
11726
11727 (define_insn "copysign<mode>3"
11728 [(set (match_operand:FP 0 "register_operand" "=f")
11729 (unspec:FP [(match_operand:FP 1 "register_operand" "<fT0>")
11730 (match_operand:FP 2 "register_operand" "f")]
11731 UNSPEC_COPYSIGN))]
11732 "TARGET_Z196"
11733 "cpsdr\t%0,%2,%1"
11734 [(set_attr "op_type" "RRF")
11735 (set_attr "type" "fsimp<mode>")])
11736
11737
11738 ;;
11739 ;;- Transactional execution instructions
11740 ;;
11741
11742 ; This splitter helps combine to make use of CC directly when
11743 ; comparing the integer result of a tbegin builtin with a constant.
11744 ; The unspec is already removed by canonicalize_comparison. So this
11745 ; splitters only job is to turn the PARALLEL into separate insns
11746 ; again. Unfortunately this only works with the very first cc/int
11747 ; compare since combine is not able to deal with data flow across
11748 ; basic block boundaries.
11749
11750 ; It needs to be an insn pattern as well since combine does not apply
11751 ; the splitter directly. Combine would only use it if it actually
11752 ; would reduce the number of instructions.
11753 (define_insn_and_split "*ccraw_to_int"
11754 [(set (pc)
11755 (if_then_else
11756 (match_operator 0 "s390_eqne_operator"
11757 [(reg:CCRAW CC_REGNUM)
11758 (match_operand 1 "const_int_operand" "")])
11759 (label_ref (match_operand 2 "" ""))
11760 (pc)))
11761 (set (match_operand:SI 3 "register_operand" "=d")
11762 (unspec:SI [(reg:CCRAW CC_REGNUM)] UNSPEC_CC_TO_INT))]
11763 ""
11764 "#"
11765 ""
11766 [(set (match_dup 3)
11767 (unspec:SI [(reg:CCRAW CC_REGNUM)] UNSPEC_CC_TO_INT))
11768 (set (pc)
11769 (if_then_else (match_op_dup 0 [(reg:CCRAW CC_REGNUM) (match_dup 1)])
11770 (label_ref (match_dup 2))
11771 (pc)))]
11772 "")
11773
11774 ; Non-constrained transaction begin
11775
11776 (define_expand "tbegin"
11777 [(match_operand:SI 0 "register_operand" "")
11778 (match_operand:BLK 1 "memory_operand" "")]
11779 "TARGET_HTM"
11780 {
11781 s390_expand_tbegin (operands[0], operands[1], NULL_RTX, true);
11782 DONE;
11783 })
11784
11785 (define_expand "tbegin_nofloat"
11786 [(match_operand:SI 0 "register_operand" "")
11787 (match_operand:BLK 1 "memory_operand" "")]
11788 "TARGET_HTM"
11789 {
11790 s390_expand_tbegin (operands[0], operands[1], NULL_RTX, false);
11791 DONE;
11792 })
11793
11794 (define_expand "tbegin_retry"
11795 [(match_operand:SI 0 "register_operand" "")
11796 (match_operand:BLK 1 "memory_operand" "")
11797 (match_operand:SI 2 "general_operand" "")]
11798 "TARGET_HTM"
11799 {
11800 s390_expand_tbegin (operands[0], operands[1], operands[2], true);
11801 DONE;
11802 })
11803
11804 (define_expand "tbegin_retry_nofloat"
11805 [(match_operand:SI 0 "register_operand" "")
11806 (match_operand:BLK 1 "memory_operand" "")
11807 (match_operand:SI 2 "general_operand" "")]
11808 "TARGET_HTM"
11809 {
11810 s390_expand_tbegin (operands[0], operands[1], operands[2], false);
11811 DONE;
11812 })
11813
11814 ; Clobber VRs since they don't get restored
11815 (define_insn "tbegin_1_z13"
11816 [(set (reg:CCRAW CC_REGNUM)
11817 (unspec_volatile:CCRAW [(match_operand 0 "const_int_operand" "D")]
11818 UNSPECV_TBEGIN))
11819 (set (match_operand:BLK 1 "memory_operand" "=Q")
11820 (unspec_volatile:BLK [(match_dup 0)] UNSPECV_TBEGIN_TDB))
11821 (clobber (reg:TI 16)) (clobber (reg:TI 38))
11822 (clobber (reg:TI 17)) (clobber (reg:TI 39))
11823 (clobber (reg:TI 18)) (clobber (reg:TI 40))
11824 (clobber (reg:TI 19)) (clobber (reg:TI 41))
11825 (clobber (reg:TI 20)) (clobber (reg:TI 42))
11826 (clobber (reg:TI 21)) (clobber (reg:TI 43))
11827 (clobber (reg:TI 22)) (clobber (reg:TI 44))
11828 (clobber (reg:TI 23)) (clobber (reg:TI 45))
11829 (clobber (reg:TI 24)) (clobber (reg:TI 46))
11830 (clobber (reg:TI 25)) (clobber (reg:TI 47))
11831 (clobber (reg:TI 26)) (clobber (reg:TI 48))
11832 (clobber (reg:TI 27)) (clobber (reg:TI 49))
11833 (clobber (reg:TI 28)) (clobber (reg:TI 50))
11834 (clobber (reg:TI 29)) (clobber (reg:TI 51))
11835 (clobber (reg:TI 30)) (clobber (reg:TI 52))
11836 (clobber (reg:TI 31)) (clobber (reg:TI 53))]
11837 ; CONST_OK_FOR_CONSTRAINT_P does not work with D constraint since D is
11838 ; not supposed to be used for immediates (see genpreds.c).
11839 "TARGET_VX && INTVAL (operands[0]) >= 0 && INTVAL (operands[0]) <= 0xffff"
11840 "tbegin\t%1,%x0"
11841 [(set_attr "op_type" "SIL")])
11842
11843 (define_insn "tbegin_1"
11844 [(set (reg:CCRAW CC_REGNUM)
11845 (unspec_volatile:CCRAW [(match_operand 0 "const_int_operand" "D")]
11846 UNSPECV_TBEGIN))
11847 (set (match_operand:BLK 1 "memory_operand" "=Q")
11848 (unspec_volatile:BLK [(match_dup 0)] UNSPECV_TBEGIN_TDB))
11849 (clobber (reg:DF 16))
11850 (clobber (reg:DF 17))
11851 (clobber (reg:DF 18))
11852 (clobber (reg:DF 19))
11853 (clobber (reg:DF 20))
11854 (clobber (reg:DF 21))
11855 (clobber (reg:DF 22))
11856 (clobber (reg:DF 23))
11857 (clobber (reg:DF 24))
11858 (clobber (reg:DF 25))
11859 (clobber (reg:DF 26))
11860 (clobber (reg:DF 27))
11861 (clobber (reg:DF 28))
11862 (clobber (reg:DF 29))
11863 (clobber (reg:DF 30))
11864 (clobber (reg:DF 31))]
11865 ; CONST_OK_FOR_CONSTRAINT_P does not work with D constraint since D is
11866 ; not supposed to be used for immediates (see genpreds.c).
11867 "TARGET_HTM && INTVAL (operands[0]) >= 0 && INTVAL (operands[0]) <= 0xffff"
11868 "tbegin\t%1,%x0"
11869 [(set_attr "op_type" "SIL")])
11870
11871 ; Same as above but without the FPR clobbers
11872 (define_insn "tbegin_nofloat_1"
11873 [(set (reg:CCRAW CC_REGNUM)
11874 (unspec_volatile:CCRAW [(match_operand 0 "const_int_operand" "D")]
11875 UNSPECV_TBEGIN))
11876 (set (match_operand:BLK 1 "memory_operand" "=Q")
11877 (unspec_volatile:BLK [(match_dup 0)] UNSPECV_TBEGIN_TDB))]
11878 "TARGET_HTM && INTVAL (operands[0]) >= 0 && INTVAL (operands[0]) <= 0xffff"
11879 "tbegin\t%1,%x0"
11880 [(set_attr "op_type" "SIL")])
11881
11882
11883 ; Constrained transaction begin
11884
11885 (define_expand "tbeginc"
11886 [(set (reg:CCRAW CC_REGNUM)
11887 (unspec_volatile:CCRAW [(const_int TBEGINC_MASK)]
11888 UNSPECV_TBEGINC))]
11889 "TARGET_HTM"
11890 "")
11891
11892 (define_insn "*tbeginc_1"
11893 [(set (reg:CCRAW CC_REGNUM)
11894 (unspec_volatile:CCRAW [(match_operand 0 "const_int_operand" " D")]
11895 UNSPECV_TBEGINC))]
11896 "TARGET_HTM && INTVAL (operands[0]) >= 0 && INTVAL (operands[0]) <= 0xffff"
11897 "tbeginc\t0,%x0"
11898 [(set_attr "op_type" "SIL")])
11899
11900 ; Transaction end
11901
11902 (define_expand "tend"
11903 [(set (reg:CCRAW CC_REGNUM)
11904 (unspec_volatile:CCRAW [(const_int 0)] UNSPECV_TEND))
11905 (set (match_operand:SI 0 "register_operand" "")
11906 (unspec:SI [(reg:CCRAW CC_REGNUM)] UNSPEC_CC_TO_INT))]
11907 "TARGET_HTM"
11908 "")
11909
11910 (define_insn "*tend_1"
11911 [(set (reg:CCRAW CC_REGNUM)
11912 (unspec_volatile:CCRAW [(const_int 0)] UNSPECV_TEND))]
11913 "TARGET_HTM"
11914 "tend"
11915 [(set_attr "op_type" "S")])
11916
11917 ; Transaction abort
11918
11919 (define_expand "tabort"
11920 [(unspec_volatile [(match_operand:SI 0 "nonmemory_operand" "")]
11921 UNSPECV_TABORT)]
11922 "TARGET_HTM && operands != NULL"
11923 {
11924 if (CONST_INT_P (operands[0])
11925 && INTVAL (operands[0]) >= 0 && INTVAL (operands[0]) <= 255)
11926 {
11927 error ("invalid transaction abort code: %wd; values in range 0 "
11928 "through 255 are reserved", INTVAL (operands[0]));
11929 FAIL;
11930 }
11931 })
11932
11933 (define_insn "*tabort_1"
11934 [(unspec_volatile [(match_operand:SI 0 "nonmemory_operand" "aJ")]
11935 UNSPECV_TABORT)]
11936 "TARGET_HTM && operands != NULL"
11937 "tabort\t%Y0"
11938 [(set_attr "op_type" "S")])
11939
11940 (define_insn "*tabort_1_plus"
11941 [(unspec_volatile [(plus:SI (match_operand:SI 0 "register_operand" "a")
11942 (match_operand:SI 1 "const_int_operand" "J"))]
11943 UNSPECV_TABORT)]
11944 "TARGET_HTM && operands != NULL
11945 && CONST_OK_FOR_CONSTRAINT_P (INTVAL (operands[1]), 'J', \"J\")"
11946 "tabort\t%1(%0)"
11947 [(set_attr "op_type" "S")])
11948
11949 ; Transaction extract nesting depth
11950
11951 (define_insn "etnd"
11952 [(set (match_operand:SI 0 "register_operand" "=d")
11953 (unspec_volatile:SI [(const_int 0)] UNSPECV_ETND))]
11954 "TARGET_HTM"
11955 "etnd\t%0"
11956 [(set_attr "op_type" "RRE")])
11957
11958 ; Non-transactional store
11959
11960 (define_insn "ntstg"
11961 [(set (match_operand:DI 0 "memory_operand" "=T")
11962 (unspec_volatile:DI [(match_operand:DI 1 "register_operand" "d")]
11963 UNSPECV_NTSTG))]
11964 "TARGET_HTM"
11965 "ntstg\t%1,%0"
11966 [(set_attr "op_type" "RXY")])
11967
11968 ; Transaction perform processor assist
11969
11970 (define_expand "tx_assist"
11971 [(unspec_volatile [(match_operand:SI 0 "register_operand" "")
11972 (reg:SI GPR0_REGNUM)
11973 (const_int PPA_TX_ABORT)]
11974 UNSPECV_PPA)]
11975 "TARGET_HTM"
11976 "")
11977
11978 (define_insn "*ppa"
11979 [(unspec_volatile [(match_operand:SI 0 "register_operand" "d")
11980 (match_operand:SI 1 "register_operand" "d")
11981 (match_operand 2 "const_int_operand" "I")]
11982 UNSPECV_PPA)]
11983 "(TARGET_ZEC12 || TARGET_HTM) && INTVAL (operands[2]) < 16"
11984 "ppa\t%0,%1,%2"
11985 [(set_attr "op_type" "RRF")])
11986
11987
11988 ; Set and get floating point control register
11989
11990 (define_insn "sfpc"
11991 [(unspec_volatile [(match_operand:SI 0 "register_operand" "d")]
11992 UNSPECV_SFPC)]
11993 "TARGET_HARD_FLOAT"
11994 "sfpc\t%0")
11995
11996 (define_insn "efpc"
11997 [(set (match_operand:SI 0 "register_operand" "=d")
11998 (unspec_volatile:SI [(const_int 0)] UNSPECV_EFPC))]
11999 "TARGET_HARD_FLOAT"
12000 "efpc\t%0")
12001
12002
12003 ; Load count to block boundary
12004
12005 (define_insn "lcbb"
12006 [(set (match_operand:SI 0 "register_operand" "=d")
12007 (unspec:SI [(match_operand 1 "address_operand" "ZR")
12008 (match_operand:SI 2 "immediate_operand" "C")] UNSPEC_LCBB))
12009 (clobber (reg:CC CC_REGNUM))]
12010 "TARGET_Z13"
12011 "lcbb\t%0,%a1,%b2"
12012 [(set_attr "op_type" "VRX")])
12013
12014 ; Handle -fsplit-stack.
12015
12016 (define_expand "split_stack_prologue"
12017 [(const_int 0)]
12018 ""
12019 {
12020 s390_expand_split_stack_prologue ();
12021 DONE;
12022 })
12023
12024 ;; If there are operand 0 bytes available on the stack, jump to
12025 ;; operand 1.
12026
12027 (define_expand "split_stack_space_check"
12028 [(set (pc) (if_then_else
12029 (ltu (minus (reg 15)
12030 (match_operand 0 "register_operand"))
12031 (unspec [(const_int 0)] UNSPEC_STACK_CHECK))
12032 (label_ref (match_operand 1))
12033 (pc)))]
12034 ""
12035 {
12036 /* Offset from thread pointer to __private_ss. */
12037 int psso = TARGET_64BIT ? 0x38 : 0x20;
12038 rtx tp = s390_get_thread_pointer ();
12039 rtx guard = gen_rtx_MEM (Pmode, plus_constant (Pmode, tp, psso));
12040 rtx reg = gen_reg_rtx (Pmode);
12041 rtx cc;
12042 if (TARGET_64BIT)
12043 emit_insn (gen_subdi3 (reg, stack_pointer_rtx, operands[0]));
12044 else
12045 emit_insn (gen_subsi3 (reg, stack_pointer_rtx, operands[0]));
12046 cc = s390_emit_compare (GT, reg, guard);
12047 s390_emit_jump (operands[1], cc);
12048
12049 DONE;
12050 })
12051
12052 ;; Call to __morestack used by the split stack support
12053
12054 ; The insn has 3 parts:
12055 ; 1. A jump to the call done label. The jump will be done as part of
12056 ; __morestack and will not be explicitly emitted to the insn stream.
12057 ; 2. The call of __morestack including a use for r1 which is supposed to
12058 ; point to the parameter block for __morestack.
12059 ; 3. 3 USES whose values together with the call done label will be
12060 ; used to emit the parameter block to the .rodata section. This
12061 ; needs to be tied into the same insn as 1. since the call done
12062 ; label is emitted also as part of the parm block. In order to
12063 ; allow the edge to the BB with the call done label to be
12064 ; redirected both need to make use of the same label_ref.
12065
12066 (define_insn "@split_stack_call<mode>"
12067 [(set (pc) (label_ref (match_operand 2 "" ""))) ; call done label
12068 (set (reg:P 1) (unspec_volatile [(match_operand 0 "bras_sym_operand" "X")
12069 (reg:P 1)]
12070 UNSPECV_SPLIT_STACK_CALL))
12071 (use (label_ref (match_operand 1 "" "X"))) ; parm block label
12072 (use (match_operand 3 "const_int_operand" "X")) ; frame size
12073 (use (match_operand 4 "const_int_operand" "X"))] ; arg size
12074 ""
12075 {
12076 s390_output_split_stack_data (operands[1], operands[2], operands[3], operands[4]);
12077 return "jg\t%0";
12078 }
12079 [(set_attr "op_type" "RIL")
12080 (set_attr "type" "branch")])
12081
12082 ; As above but with a conditional jump
12083
12084 (define_insn "@split_stack_cond_call<mode>"
12085 [(set (pc)
12086 (if_then_else
12087 (match_operand 5 "" "") ; condition
12088 (label_ref (match_operand 2 "" "")) ; call done label
12089 (pc)))
12090 (set (reg:P 1) (unspec_volatile [(match_operand 0 "bras_sym_operand" "X")
12091 (reg:P 1)]
12092 UNSPECV_SPLIT_STACK_CALL))
12093 (use (label_ref (match_operand 1 "" "X"))) ; parm block label
12094 (use (match_operand 3 "const_int_operand" "X")) ; frame size
12095 (use (match_operand 4 "const_int_operand" "X"))] ; arg size
12096 ""
12097 {
12098 s390_output_split_stack_data (operands[1], operands[2], operands[3], operands[4]);
12099 return "jg%C5\t%0";
12100 }
12101 [(set_attr "op_type" "RIL")
12102 (set_attr "type" "branch")])
12103
12104
12105 (define_insn "osc_break"
12106 [(unspec_volatile [(const_int 0)] UNSPECV_OSC_BREAK)]
12107 ""
12108 "bcr\t7,%%r0"
12109 [(set_attr "op_type" "RR")])
12110
12111 (define_expand "speculation_barrier"
12112 [(unspec_volatile [(reg:SI GPR0_REGNUM)
12113 (reg:SI GPR0_REGNUM)
12114 (const_int PPA_OOO_BARRIER)]
12115 UNSPECV_PPA)]
12116 "TARGET_ZEC12"
12117 "")