S/390: Fix PR80725.
[gcc.git] / gcc / config / s390 / s390.md
1 ;;- Machine description for GNU compiler -- S/390 / zSeries version.
2 ;; Copyright (C) 1999-2017 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_LTREL_BASE
79 UNSPEC_POOL_OFFSET
80 UNSPEC_GOTENT
81 UNSPEC_GOT
82 UNSPEC_GOTOFF
83 UNSPEC_PLT
84 UNSPEC_PLTOFF
85
86 ; Literal pool
87 UNSPEC_RELOAD_BASE
88 UNSPEC_MAIN_BASE
89 UNSPEC_LTREF
90 UNSPEC_INSN
91 UNSPEC_EXECUTE
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
109 ; String Functions
110 UNSPEC_SRST
111 UNSPEC_MVST
112
113 ; Stack Smashing Protector
114 UNSPEC_SP_SET
115 UNSPEC_SP_TEST
116
117 ; Split stack support
118 UNSPEC_STACK_CHECK
119
120 ; Test Data Class (TDC)
121 UNSPEC_TDC_INSN
122
123 ; Population Count
124 UNSPEC_POPCNT
125 UNSPEC_COPYSIGN
126
127 ; Load FP Integer
128 UNSPEC_FPINT_FLOOR
129 UNSPEC_FPINT_BTRUNC
130 UNSPEC_FPINT_ROUND
131 UNSPEC_FPINT_CEIL
132 UNSPEC_FPINT_NEARBYINT
133 UNSPEC_FPINT_RINT
134
135 UNSPEC_LCBB
136
137 ; Vector
138 UNSPEC_VEC_SMULT_HI
139 UNSPEC_VEC_UMULT_HI
140 UNSPEC_VEC_SMULT_LO
141 UNSPEC_VEC_SMULT_EVEN
142 UNSPEC_VEC_UMULT_EVEN
143 UNSPEC_VEC_SMULT_ODD
144 UNSPEC_VEC_UMULT_ODD
145
146 UNSPEC_VEC_VMAL
147 UNSPEC_VEC_VMAH
148 UNSPEC_VEC_VMALH
149 UNSPEC_VEC_VMAE
150 UNSPEC_VEC_VMALE
151 UNSPEC_VEC_VMAO
152 UNSPEC_VEC_VMALO
153
154 UNSPEC_VEC_GATHER
155 UNSPEC_VEC_EXTRACT
156 UNSPEC_VEC_INSERT_AND_ZERO
157 UNSPEC_VEC_LOAD_BNDRY
158 UNSPEC_VEC_LOAD_LEN
159 UNSPEC_VEC_LOAD_LEN_R
160 UNSPEC_VEC_MERGEH
161 UNSPEC_VEC_MERGEL
162 UNSPEC_VEC_PACK
163 UNSPEC_VEC_PACK_SATURATE
164 UNSPEC_VEC_PACK_SATURATE_CC
165 UNSPEC_VEC_PACK_SATURATE_GENCC
166 UNSPEC_VEC_PACK_UNSIGNED_SATURATE
167 UNSPEC_VEC_PACK_UNSIGNED_SATURATE_CC
168 UNSPEC_VEC_PACK_UNSIGNED_SATURATE_GENCC
169 UNSPEC_VEC_PERM
170 UNSPEC_VEC_PERMI
171 UNSPEC_VEC_EXTEND
172 UNSPEC_VEC_STORE_LEN
173 UNSPEC_VEC_STORE_LEN_R
174 UNSPEC_VEC_VBPERM
175 UNSPEC_VEC_UNPACKH
176 UNSPEC_VEC_UNPACKH_L
177 UNSPEC_VEC_UNPACKL
178 UNSPEC_VEC_UNPACKL_L
179 UNSPEC_VEC_ADDC
180 UNSPEC_VEC_ADDE_U128
181 UNSPEC_VEC_ADDEC_U128
182 UNSPEC_VEC_AVG
183 UNSPEC_VEC_AVGU
184 UNSPEC_VEC_CHECKSUM
185 UNSPEC_VEC_GFMSUM
186 UNSPEC_VEC_GFMSUM_128
187 UNSPEC_VEC_GFMSUM_ACCUM
188 UNSPEC_VEC_GFMSUM_ACCUM_128
189 UNSPEC_VEC_SET
190
191 UNSPEC_VEC_VSUMG
192 UNSPEC_VEC_VSUMQ
193 UNSPEC_VEC_VSUM
194 UNSPEC_VEC_RL_MASK
195 UNSPEC_VEC_SLL
196 UNSPEC_VEC_SLB
197 UNSPEC_VEC_SLDB
198 UNSPEC_VEC_SRAL
199 UNSPEC_VEC_SRAB
200 UNSPEC_VEC_SRL
201 UNSPEC_VEC_SRLB
202
203 UNSPEC_VEC_SUBC
204 UNSPEC_VEC_SUBE_U128
205 UNSPEC_VEC_SUBEC_U128
206
207 UNSPEC_VEC_TEST_MASK
208
209 UNSPEC_VEC_VFAE
210 UNSPEC_VEC_VFAECC
211
212 UNSPEC_VEC_VFEE
213 UNSPEC_VEC_VFEECC
214 UNSPEC_VEC_VFENE
215 UNSPEC_VEC_VFENECC
216
217 UNSPEC_VEC_VISTR
218 UNSPEC_VEC_VISTRCC
219
220 UNSPEC_VEC_VSTRC
221 UNSPEC_VEC_VSTRCCC
222
223 UNSPEC_VEC_VCDGB
224 UNSPEC_VEC_VCDLGB
225
226 UNSPEC_VEC_VCGDB
227 UNSPEC_VEC_VCLGDB
228
229 UNSPEC_VEC_VFI
230
231 UNSPEC_VEC_VFLL ; vector fp load lengthened
232 UNSPEC_VEC_VFLR ; vector fp load rounded
233
234 UNSPEC_VEC_VFTCI
235 UNSPEC_VEC_VFTCICC
236
237 UNSPEC_VEC_MSUM
238
239 UNSPEC_VEC_VFMIN
240 UNSPEC_VEC_VFMAX
241 ])
242
243 ;;
244 ;; UNSPEC_VOLATILE usage
245 ;;
246
247 (define_c_enum "unspecv" [
248 ; Blockage
249 UNSPECV_BLOCKAGE
250
251 ; TPF Support
252 UNSPECV_TPF_PROLOGUE
253 UNSPECV_TPF_EPILOGUE
254
255 ; Literal pool
256 UNSPECV_POOL
257 UNSPECV_POOL_SECTION
258 UNSPECV_POOL_ALIGN
259 UNSPECV_POOL_ENTRY
260 UNSPECV_MAIN_POOL
261
262 ; TLS support
263 UNSPECV_SET_TP
264
265 ; Atomic Support
266 UNSPECV_CAS
267 UNSPECV_ATOMIC_OP
268
269 ; Hotpatching (unremovable NOPs)
270 UNSPECV_NOP_2_BYTE
271 UNSPECV_NOP_4_BYTE
272 UNSPECV_NOP_6_BYTE
273
274 ; Transactional Execution support
275 UNSPECV_TBEGIN
276 UNSPECV_TBEGIN_TDB
277 UNSPECV_TBEGINC
278 UNSPECV_TEND
279 UNSPECV_TABORT
280 UNSPECV_ETND
281 UNSPECV_NTSTG
282 UNSPECV_PPA
283
284 ; Set and get floating point control register
285 UNSPECV_SFPC
286 UNSPECV_EFPC
287
288 ; Split stack support
289 UNSPECV_SPLIT_STACK_CALL
290 UNSPECV_SPLIT_STACK_DATA
291
292 UNSPECV_OSC_BREAK
293 ])
294
295 ;;
296 ;; Registers
297 ;;
298
299 ; Registers with special meaning
300
301 (define_constants
302 [
303 ; Sibling call register.
304 (SIBCALL_REGNUM 1)
305 ; Literal pool base register.
306 (BASE_REGNUM 13)
307 ; Return address register.
308 (RETURN_REGNUM 14)
309 ; Stack pointer register.
310 (STACK_REGNUM 15)
311 ; Condition code register.
312 (CC_REGNUM 33)
313 ; Thread local storage pointer register.
314 (TP_REGNUM 36)
315 ])
316
317 ; Hardware register names
318
319 (define_constants
320 [
321 ; General purpose registers
322 (GPR0_REGNUM 0)
323 (GPR1_REGNUM 1)
324 (GPR2_REGNUM 2)
325 (GPR6_REGNUM 6)
326 ; Floating point registers.
327 (FPR0_REGNUM 16)
328 (FPR1_REGNUM 20)
329 (FPR2_REGNUM 17)
330 (FPR3_REGNUM 21)
331 (FPR4_REGNUM 18)
332 (FPR5_REGNUM 22)
333 (FPR6_REGNUM 19)
334 (FPR7_REGNUM 23)
335 (FPR8_REGNUM 24)
336 (FPR9_REGNUM 28)
337 (FPR10_REGNUM 25)
338 (FPR11_REGNUM 29)
339 (FPR12_REGNUM 26)
340 (FPR13_REGNUM 30)
341 (FPR14_REGNUM 27)
342 (FPR15_REGNUM 31)
343 (VR0_REGNUM 16)
344 (VR16_REGNUM 38)
345 (VR23_REGNUM 45)
346 (VR24_REGNUM 46)
347 (VR31_REGNUM 53)
348 ])
349
350 ; Rounding modes for binary floating point numbers
351 (define_constants
352 [(BFP_RND_CURRENT 0)
353 (BFP_RND_NEAREST_TIE_AWAY_FROM_0 1)
354 (BFP_RND_PREP_FOR_SHORT_PREC 3)
355 (BFP_RND_NEAREST_TIE_TO_EVEN 4)
356 (BFP_RND_TOWARD_0 5)
357 (BFP_RND_TOWARD_INF 6)
358 (BFP_RND_TOWARD_MINF 7)])
359
360 ; Rounding modes for decimal floating point numbers
361 ; 1-7 were introduced with the floating point extension facility
362 ; available with z196
363 ; With these rounding modes (1-7) a quantum exception might occur
364 ; which is suppressed for the other modes.
365 (define_constants
366 [(DFP_RND_CURRENT 0)
367 (DFP_RND_NEAREST_TIE_AWAY_FROM_0_QUANTEXC 1)
368 (DFP_RND_CURRENT_QUANTEXC 2)
369 (DFP_RND_PREP_FOR_SHORT_PREC_QUANTEXC 3)
370 (DFP_RND_NEAREST_TIE_TO_EVEN_QUANTEXC 4)
371 (DFP_RND_TOWARD_0_QUANTEXC 5)
372 (DFP_RND_TOWARD_INF_QUANTEXC 6)
373 (DFP_RND_TOWARD_MINF_QUANTEXC 7)
374 (DFP_RND_NEAREST_TIE_TO_EVEN 8)
375 (DFP_RND_TOWARD_0 9)
376 (DFP_RND_TOWARD_INF 10)
377 (DFP_RND_TOWARD_MINF 11)
378 (DFP_RND_NEAREST_TIE_AWAY_FROM_0 12)
379 (DFP_RND_NEAREST_TIE_TO_0 13)
380 (DFP_RND_AWAY_FROM_0 14)
381 (DFP_RND_PREP_FOR_SHORT_PREC 15)])
382
383 ;;
384 ;; PFPO GPR0 argument format
385 ;;
386
387 (define_constants
388 [
389 ; PFPO operation type
390 (PFPO_CONVERT 0x1000000)
391 ; PFPO operand types
392 (PFPO_OP_TYPE_SF 0x5)
393 (PFPO_OP_TYPE_DF 0x6)
394 (PFPO_OP_TYPE_TF 0x7)
395 (PFPO_OP_TYPE_SD 0x8)
396 (PFPO_OP_TYPE_DD 0x9)
397 (PFPO_OP_TYPE_TD 0xa)
398 ; Bitposition of operand types
399 (PFPO_OP0_TYPE_SHIFT 16)
400 (PFPO_OP1_TYPE_SHIFT 8)
401 ])
402
403 ; Immediate operands for tbegin and tbeginc
404 (define_constants [(TBEGIN_MASK 65292)]) ; 0xff0c
405 (define_constants [(TBEGINC_MASK 65288)]) ; 0xff08
406
407 ;; Instruction operand type as used in the Principles of Operation.
408 ;; Used to determine defaults for length and other attribute values.
409
410 (define_attr "op_type"
411 "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"
412 (const_string "NN"))
413
414 ;; Instruction type attribute used for scheduling.
415
416 (define_attr "type" "none,integer,load,lr,la,larl,lm,stm,
417 cs,vs,store,sem,idiv,
418 imulhi,imulsi,imuldi,
419 branch,jsr,fsimptf,fsimpdf,fsimpsf,fhex,
420 floadtf,floaddf,floadsf,fstoredf,fstoresf,
421 fmultf,fmuldf,fmulsf,fdivtf,fdivdf,fdivsf,
422 ftoi,fsqrttf,fsqrtdf,fsqrtsf,
423 fmadddf,fmaddsf,
424 ftrunctf,ftruncdf, ftruncsd, ftruncdd,
425 itoftf, itofdf, itofsf, itofdd, itoftd,
426 fdivdd, fdivtd, floaddd, floadsd, fmuldd, fmultd,
427 fsimpdd, fsimpsd, fsimptd, fstoredd, fstoresd,
428 ftoidfp, other"
429 (cond [(eq_attr "op_type" "NN") (const_string "other")
430 (eq_attr "op_type" "SS") (const_string "cs")]
431 (const_string "integer")))
432
433 ;; Another attribute used for scheduling purposes:
434 ;; agen: Instruction uses the address generation unit
435 ;; reg: Instruction does not use the agen unit
436
437 (define_attr "atype" "agen,reg"
438 (if_then_else (eq_attr "op_type" "E,RR,RI,RRE,RSI,RIL,RIE,RRF")
439 (const_string "reg")
440 (const_string "agen")))
441
442 ;; Properties concerning Z10 execution grouping and value forwarding.
443 ;; z10_super: instruction is superscalar.
444 ;; z10_super_c: instruction is superscalar and meets the condition of z10_c.
445 ;; z10_fwd: The instruction reads the value of an operand and stores it into a
446 ;; target register. It can forward this value to a second instruction that reads
447 ;; the same register if that second instruction is issued in the same group.
448 ;; z10_rec: The instruction is in the T pipeline and reads a register. If the
449 ;; instruction in the S pipe writes to the register, then the T instruction
450 ;; can immediately read the new value.
451 ;; z10_fr: union of Z10_fwd and z10_rec.
452 ;; z10_c: second operand of instruction is a register and read with complemented bits.
453 ;;
454 ;; An additional suffix A1, A3, or E1 indicates the respective AGI bypass.
455
456
457 (define_attr "z10prop" "none,
458 z10_super, z10_super_E1, z10_super_A1, z10_super_c, z10_super_c_E1,
459 z10_fwd, z10_fwd_A1, z10_fwd_A3, z10_fwd_E1,
460 z10_rec,
461 z10_fr, z10_fr_A3, z10_fr_E1,
462 z10_c"
463 (const_string "none"))
464
465 ;; Properties concerning Z196 decoding
466 ;; z196_alone: must group alone
467 ;; z196_end: ends a group
468 ;; z196_cracked: instruction is cracked or expanded
469 (define_attr "z196prop" "none,
470 z196_alone, z196_ends,
471 z196_cracked"
472 (const_string "none"))
473
474 (define_attr "mnemonic" "bcr_flush,unknown" (const_string "unknown"))
475
476 ;; Length in bytes.
477
478 (define_attr "length" ""
479 (cond [(eq_attr "op_type" "E,RR") (const_int 2)
480 (eq_attr "op_type" "RX,RI,RRE,RS,RSI,S,SI,RRF") (const_int 4)]
481 (const_int 6)))
482
483
484 ;; Processor type. This attribute must exactly match the processor_type
485 ;; enumeration in s390.h. The current machine description does not
486 ;; distinguish between g5 and g6, but there are differences between the two
487 ;; CPUs could in theory be modeled.
488
489 (define_attr "cpu" "g5,g6,z900,z990,z9_109,z9_ec,z10,z196,zEC12,z13,arch12"
490 (const (symbol_ref "s390_tune_attr")))
491
492 (define_attr "cpu_facility"
493 "standard,ieee,zarch,cpu_zarch,longdisp,extimm,dfp,z10,z196,zEC12,vx,z13,arch12,vxe"
494 (const_string "standard"))
495
496 (define_attr "enabled" ""
497 (cond [(eq_attr "cpu_facility" "standard")
498 (const_int 1)
499
500 (and (eq_attr "cpu_facility" "ieee")
501 (match_test "TARGET_CPU_IEEE_FLOAT"))
502 (const_int 1)
503
504 (and (eq_attr "cpu_facility" "zarch")
505 (match_test "TARGET_ZARCH"))
506 (const_int 1)
507
508 (and (eq_attr "cpu_facility" "longdisp")
509 (match_test "TARGET_LONG_DISPLACEMENT"))
510 (const_int 1)
511
512 (and (eq_attr "cpu_facility" "extimm")
513 (match_test "TARGET_EXTIMM"))
514 (const_int 1)
515
516 (and (eq_attr "cpu_facility" "dfp")
517 (match_test "TARGET_DFP"))
518 (const_int 1)
519
520 (and (eq_attr "cpu_facility" "cpu_zarch")
521 (match_test "TARGET_CPU_ZARCH"))
522 (const_int 1)
523
524 (and (eq_attr "cpu_facility" "z10")
525 (match_test "TARGET_Z10"))
526 (const_int 1)
527
528 (and (eq_attr "cpu_facility" "z196")
529 (match_test "TARGET_Z196"))
530 (const_int 1)
531
532 (and (eq_attr "cpu_facility" "zEC12")
533 (match_test "TARGET_ZEC12"))
534 (const_int 1)
535
536 (and (eq_attr "cpu_facility" "vx")
537 (match_test "TARGET_VX"))
538 (const_int 1)
539
540 (and (eq_attr "cpu_facility" "z13")
541 (match_test "TARGET_Z13"))
542 (const_int 1)
543
544 (and (eq_attr "cpu_facility" "arch12")
545 (match_test "TARGET_ARCH12"))
546 (const_int 1)
547
548 (and (eq_attr "cpu_facility" "vxe")
549 (match_test "TARGET_VXE"))
550 (const_int 1)
551 ]
552 (const_int 0)))
553
554 ;; Pipeline description for z900. For lack of anything better,
555 ;; this description is also used for the g5 and g6.
556 (include "2064.md")
557
558 ;; Pipeline description for z990, z9-109 and z9-ec.
559 (include "2084.md")
560
561 ;; Pipeline description for z10
562 (include "2097.md")
563
564 ;; Pipeline description for z196
565 (include "2817.md")
566
567 ;; Pipeline description for zEC12
568 (include "2827.md")
569
570 ;; Pipeline description for z13
571 (include "2964.md")
572
573 ;; Predicates
574 (include "predicates.md")
575
576 ;; Constraint definitions
577 (include "constraints.md")
578
579 ;; Other includes
580 (include "tpf.md")
581
582 ;; Iterators
583
584 (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])
585
586 ;; These mode iterators allow floating point patterns to be generated from the
587 ;; same template.
588 (define_mode_iterator FP_ALL [TF DF SF (TD "TARGET_HARD_DFP") (DD "TARGET_HARD_DFP")
589 (SD "TARGET_HARD_DFP")])
590 (define_mode_iterator FP [TF DF SF (TD "TARGET_HARD_DFP") (DD "TARGET_HARD_DFP")])
591 (define_mode_iterator BFP [TF DF SF])
592 (define_mode_iterator DFP [TD DD])
593 (define_mode_iterator DFP_ALL [TD DD SD])
594 (define_mode_iterator DSF [DF SF])
595 (define_mode_iterator SD_SF [SF SD])
596 (define_mode_iterator DD_DF [DF DD])
597 (define_mode_iterator TD_TF [TF TD])
598
599 ;; These mode iterators allow 31-bit and 64-bit GPR patterns to be generated
600 ;; from the same template.
601 (define_mode_iterator GPR [(DI "TARGET_ZARCH") SI])
602 (define_mode_iterator DGPR [(TI "TARGET_ZARCH") DI SI])
603 (define_mode_iterator DSI [DI SI])
604 (define_mode_iterator TDI [TI DI])
605
606 ;; These mode iterators allow :P to be used for patterns that operate on
607 ;; pointer-sized quantities. Exactly one of the two alternatives will match.
608 (define_mode_iterator P [(DI "TARGET_64BIT") (SI "!TARGET_64BIT")])
609
610 ;; These macros refer to the actual word_mode of the configuration.
611 ;; This is equal to Pmode except on 31-bit machines in zarch mode.
612 (define_mode_iterator DW [(TI "TARGET_ZARCH") (DI "!TARGET_ZARCH")])
613 (define_mode_iterator W [(DI "TARGET_ZARCH") (SI "!TARGET_ZARCH")])
614
615 ;; Used by the umul pattern to express modes having half the size.
616 (define_mode_attr DWH [(TI "DI") (DI "SI")])
617 (define_mode_attr dwh [(TI "di") (DI "si")])
618
619 ;; This mode iterator allows the QI and HI patterns to be defined from
620 ;; the same template.
621 (define_mode_iterator HQI [HI QI])
622
623 ;; This mode iterator allows the integer patterns to be defined from the
624 ;; same template.
625 (define_mode_iterator INT [(DI "TARGET_ZARCH") SI HI QI])
626 (define_mode_iterator DINT [(TI "TARGET_ZARCH") DI SI HI QI])
627 (define_mode_iterator SINT [SI HI QI])
628
629 ;; This iterator allows some 'ashift' and 'lshiftrt' pattern to be defined from
630 ;; the same template.
631 (define_code_iterator SHIFT [ashift lshiftrt])
632
633 ;; This iterator allows r[ox]sbg to be defined with the same template
634 (define_code_iterator IXOR [ior xor])
635
636 ;; This iterator is used to expand the patterns for the nearest
637 ;; integer functions.
638 (define_int_iterator FPINT [UNSPEC_FPINT_FLOOR UNSPEC_FPINT_BTRUNC
639 UNSPEC_FPINT_ROUND UNSPEC_FPINT_CEIL
640 UNSPEC_FPINT_NEARBYINT])
641 (define_int_attr fpint_name [(UNSPEC_FPINT_FLOOR "floor")
642 (UNSPEC_FPINT_BTRUNC "btrunc")
643 (UNSPEC_FPINT_ROUND "round")
644 (UNSPEC_FPINT_CEIL "ceil")
645 (UNSPEC_FPINT_NEARBYINT "nearbyint")])
646 (define_int_attr fpint_roundingmode [(UNSPEC_FPINT_FLOOR "7")
647 (UNSPEC_FPINT_BTRUNC "5")
648 (UNSPEC_FPINT_ROUND "1")
649 (UNSPEC_FPINT_CEIL "6")
650 (UNSPEC_FPINT_NEARBYINT "0")])
651
652 ;; This iterator and attribute allow to combine most atomic operations.
653 (define_code_iterator ATOMIC [and ior xor plus minus mult])
654 (define_code_iterator ATOMIC_Z196 [and ior xor plus])
655 (define_code_attr atomic [(and "and") (ior "or") (xor "xor")
656 (plus "add") (minus "sub") (mult "nand")])
657 (define_code_attr noxa [(and "n") (ior "o") (xor "x") (plus "a")])
658
659 ;; In FP templates, a string like "lt<de>br" will expand to "ltxbr" in
660 ;; TF/TDmode, "ltdbr" in DF/DDmode, and "ltebr" in SF/SDmode.
661 (define_mode_attr xde [(TF "x") (DF "d") (SF "e") (TD "x") (DD "d") (SD "e")])
662
663 ;; In FP templates, a <dee> in "m<dee><bt>r" will expand to "mx<bt>r" in
664 ;; TF/TDmode, "md<bt>r" in DF/DDmode, "mee<bt>r" in SFmode and "me<bt>r in
665 ;; SDmode.
666 (define_mode_attr xdee [(TF "x") (DF "d") (SF "ee") (TD "x") (DD "d") (SD "e")])
667
668 ;; In FP templates, "<RRe>" will expand to "RRE" in TFmode and "RR" otherwise.
669 ;; Likewise for "<RXe>".
670 (define_mode_attr RRe [(TF "RRE") (DF "RR") (SF "RR")])
671 (define_mode_attr RXe [(TF "RXE") (DF "RX") (SF "RX")])
672
673 ;; The decimal floating point variants of add, sub, div and mul support 3
674 ;; fp register operands. The following attributes allow to merge the bfp and
675 ;; dfp variants in a single insn definition.
676
677 ;; These mode attributes are supposed to be used in the `enabled' insn
678 ;; attribute to disable certain alternatives for certain modes.
679 (define_mode_attr nBFP [(TF "0") (DF "0") (SF "0") (TD "*") (DD "*") (DD "*")])
680 (define_mode_attr nDFP [(TF "*") (DF "*") (SF "*") (TD "0") (DD "0") (DD "0")])
681 (define_mode_attr DSF [(TF "0") (DF "*") (SF "*") (TD "0") (DD "0") (SD "0")])
682 (define_mode_attr DFDI [(TF "0") (DF "*") (SF "0")
683 (TD "0") (DD "0") (DD "0")
684 (TI "0") (DI "*") (SI "0")])
685 (define_mode_attr DF [(TF "0") (DF "*") (SF "0")
686 (TD "0") (DD "0") (DD "0")
687 (TI "0") (DI "0") (SI "0")])
688 (define_mode_attr SF [(TF "0") (DF "0") (SF "*")
689 (TD "0") (DD "0") (DD "0")
690 (TI "0") (DI "0") (SI "0")])
691
692 ;; This attribute is used in the operand constraint list
693 ;; for instructions dealing with the sign bit of 32 or 64bit fp values.
694 ;; TFmode values are represented by a fp register pair. Since the
695 ;; sign bit instructions only handle single source and target fp registers
696 ;; these instructions can only be used for TFmode values if the source and
697 ;; target operand uses the same fp register.
698 (define_mode_attr fT0 [(TF "0") (DF "f") (SF "f")])
699
700 ;; This attribute adds b for bfp instructions and t for dfp instructions and is used
701 ;; within instruction mnemonics.
702 (define_mode_attr bt [(TF "b") (DF "b") (SF "b") (TD "t") (DD "t") (SD "t")])
703
704 ;; This attribute is used within instruction mnemonics. It evaluates to d for dfp
705 ;; modes and to an empty string for bfp modes.
706 (define_mode_attr _d [(TF "") (DF "") (SF "") (TD "d") (DD "d") (SD "d")])
707
708 ;; In GPR and P templates, a constraint like "<d0>" will expand to "d" in DImode
709 ;; and "0" in SImode. This allows to combine instructions of which the 31bit
710 ;; version only operates on one register.
711 (define_mode_attr d0 [(DI "d") (SI "0")])
712
713 ;; In combination with d0 this allows to combine instructions of which the 31bit
714 ;; version only operates on one register. The DImode version needs an additional
715 ;; register for the assembler output.
716 (define_mode_attr 1 [(DI "%1,") (SI "")])
717
718 ;; In SHIFT templates, a string like "s<lr>dl" will expand to "sldl" in
719 ;; 'ashift' and "srdl" in 'lshiftrt'.
720 (define_code_attr lr [(ashift "l") (lshiftrt "r")])
721
722 ;; In SHIFT templates, this attribute holds the correct standard name for the
723 ;; pattern itself and the corresponding function calls.
724 (define_code_attr shift [(ashift "ashl") (lshiftrt "lshr")])
725
726 ;; This attribute handles differences in the instruction 'type' and will result
727 ;; in "RRE" for DImode and "RR" for SImode.
728 (define_mode_attr E [(DI "E") (SI "")])
729
730 ;; This attribute handles differences in the instruction 'type' and makes RX<Y>
731 ;; to result in "RXY" for DImode and "RX" for SImode.
732 (define_mode_attr Y [(DI "Y") (SI "")])
733
734 ;; This attribute handles differences in the instruction 'type' and will result
735 ;; in "RSE" for TImode and "RS" for DImode.
736 (define_mode_attr TE [(TI "E") (DI "")])
737
738 ;; In GPR templates, a string like "lc<g>r" will expand to "lcgr" in DImode
739 ;; and "lcr" in SImode.
740 (define_mode_attr g [(DI "g") (SI "")])
741
742 ;; In GPR templates, a string like "sl<y>" will expand to "slg" in DImode
743 ;; and "sly" in SImode. This is useful because on 64bit the ..g instructions
744 ;; were enhanced with long displacements whereas 31bit instructions got a ..y
745 ;; variant for long displacements.
746 (define_mode_attr y [(DI "g") (SI "y")])
747
748 ;; In DW templates, a string like "cds<g>" will expand to "cdsg" in TImode
749 ;; and "cds" in DImode.
750 (define_mode_attr tg [(TI "g") (DI "")])
751
752 ;; In TDI templates, a string like "c<d>sg".
753 (define_mode_attr td [(TI "d") (DI "")])
754
755 ;; In GPR templates, a string like "c<gf>dbr" will expand to "cgdbr" in DImode
756 ;; and "cfdbr" in SImode.
757 (define_mode_attr gf [(DI "g") (SI "f")])
758
759 ;; In GPR templates, a string like sll<gk> will expand to sllg for DI
760 ;; and sllk for SI. This way it is possible to merge the new z196 SI
761 ;; 3 operands shift instructions into the existing patterns.
762 (define_mode_attr gk [(DI "g") (SI "k")])
763
764 ;; ICM mask required to load MODE value into the lowest subreg
765 ;; of a SImode register.
766 (define_mode_attr icm_lo [(HI "3") (QI "1")])
767
768 ;; In HQI templates, a string like "llg<hc>" will expand to "llgh" in
769 ;; HImode and "llgc" in QImode.
770 (define_mode_attr hc [(HI "h") (QI "c")])
771
772 ;; In P templates, the mode <DBL> will expand to "TI" in DImode and "DI"
773 ;; in SImode.
774 (define_mode_attr DBL [(DI "TI") (SI "DI")])
775
776 ;; This attribute expands to DF for TFmode and to DD for TDmode . It is
777 ;; used for Txmode splitters splitting a Txmode copy into 2 Dxmode copies.
778 (define_mode_attr HALF_TMODE [(TF "DF") (TD "DD")])
779
780 ;; Maximum unsigned integer that fits in MODE.
781 (define_mode_attr max_uint [(HI "65535") (QI "255")])
782
783 ;; Start and end field computations for RISBG et al.
784 (define_mode_attr bfstart [(DI "s") (SI "t")])
785 (define_mode_attr bfend [(DI "e") (SI "f")])
786
787 ;; In place of GET_MODE_BITSIZE (<MODE>mode)
788 (define_mode_attr bitsize [(DI "64") (SI "32") (HI "16") (QI "8")])
789 ;; 64 - bitsize
790 (define_mode_attr bitoff [(DI "0") (SI "32") (HI "48") (QI "56")])
791 (define_mode_attr bitoff_plus [(DI "") (SI "32+") (HI "48+") (QI "56+")])
792
793 ;; In place of GET_MODE_SIZE (<MODE>mode)
794 (define_mode_attr modesize [(DI "8") (SI "4")])
795
796 ;; Allow return and simple_return to be defined from a single template.
797 (define_code_iterator ANY_RETURN [return simple_return])
798
799
800
801 ; Condition code modes generated by vector fp comparisons. These will
802 ; be used also in single element mode.
803 (define_mode_iterator VFCMP [CCVEQ CCVFH CCVFHE])
804 ; Used with VFCMP to expand part of the mnemonic
805 ; For fp we have a mismatch: eq in the insn name - e in asm
806 (define_mode_attr asm_fcmp [(CCVEQ "e") (CCVFH "h") (CCVFHE "he")])
807 (define_mode_attr insn_cmp [(CCVEQ "eq") (CCVIH "h") (CCVIHU "hl") (CCVFH "h") (CCVFHE "he")])
808
809 ;; Subst pattern definitions
810 (include "subst.md")
811
812 (include "vector.md")
813
814 ;;
815 ;;- Compare instructions.
816 ;;
817
818 ; Test-under-Mask instructions
819
820 (define_insn "*tmqi_mem"
821 [(set (reg CC_REGNUM)
822 (compare (and:QI (match_operand:QI 0 "memory_operand" "Q,S")
823 (match_operand:QI 1 "immediate_operand" "n,n"))
824 (match_operand:QI 2 "immediate_operand" "n,n")))]
825 "s390_match_ccmode (insn, s390_tm_ccmode (operands[1], operands[2], false))"
826 "@
827 tm\t%S0,%b1
828 tmy\t%S0,%b1"
829 [(set_attr "op_type" "SI,SIY")
830 (set_attr "cpu_facility" "*,longdisp")
831 (set_attr "z10prop" "z10_super,z10_super")])
832
833 (define_insn "*tmdi_reg"
834 [(set (reg CC_REGNUM)
835 (compare (and:DI (match_operand:DI 0 "nonimmediate_operand" "d,d,d,d")
836 (match_operand:DI 1 "immediate_operand"
837 "N0HD0,N1HD0,N2HD0,N3HD0"))
838 (match_operand:DI 2 "immediate_operand" "n,n,n,n")))]
839 "TARGET_ZARCH
840 && s390_match_ccmode (insn, s390_tm_ccmode (operands[1], operands[2], true))
841 && s390_single_part (operands[1], DImode, HImode, 0) >= 0"
842 "@
843 tmhh\t%0,%i1
844 tmhl\t%0,%i1
845 tmlh\t%0,%i1
846 tmll\t%0,%i1"
847 [(set_attr "op_type" "RI")
848 (set_attr "z10prop" "z10_super,z10_super,z10_super,z10_super")])
849
850 (define_insn "*tmsi_reg"
851 [(set (reg CC_REGNUM)
852 (compare (and:SI (match_operand:SI 0 "nonimmediate_operand" "d,d")
853 (match_operand:SI 1 "immediate_operand" "N0HS0,N1HS0"))
854 (match_operand:SI 2 "immediate_operand" "n,n")))]
855 "s390_match_ccmode (insn, s390_tm_ccmode (operands[1], operands[2], true))
856 && s390_single_part (operands[1], SImode, HImode, 0) >= 0"
857 "@
858 tmh\t%0,%i1
859 tml\t%0,%i1"
860 [(set_attr "op_type" "RI")
861 (set_attr "z10prop" "z10_super,z10_super")])
862
863 (define_insn "*tm<mode>_full"
864 [(set (reg CC_REGNUM)
865 (compare (match_operand:HQI 0 "register_operand" "d")
866 (match_operand:HQI 1 "immediate_operand" "n")))]
867 "s390_match_ccmode (insn, s390_tm_ccmode (constm1_rtx, operands[1], true))"
868 "tml\t%0,<max_uint>"
869 [(set_attr "op_type" "RI")
870 (set_attr "z10prop" "z10_super")])
871
872
873 ;
874 ; Load-and-Test instructions
875 ;
876
877 ; tst(di|si) instruction pattern(s).
878
879 (define_insn "*tstdi_sign"
880 [(set (reg CC_REGNUM)
881 (compare
882 (ashiftrt:DI
883 (ashift:DI
884 (subreg:DI (match_operand:SI 0 "nonimmediate_operand" "d,T") 0)
885 (const_int 32)) (const_int 32))
886 (match_operand:DI 1 "const0_operand" "")))
887 (set (match_operand:DI 2 "register_operand" "=d,d")
888 (sign_extend:DI (match_dup 0)))]
889 "s390_match_ccmode(insn, CCSmode) && TARGET_ZARCH"
890 "ltgfr\t%2,%0
891 ltgf\t%2,%0"
892 [(set_attr "op_type" "RRE,RXY")
893 (set_attr "cpu_facility" "*,z10")
894 (set_attr "z10prop" "z10_super_E1,z10_super_E1") ])
895
896 ; ltr, lt, ltgr, ltg
897 (define_insn "*tst<mode>_extimm"
898 [(set (reg CC_REGNUM)
899 (compare (match_operand:GPR 0 "nonimmediate_operand" "d,T")
900 (match_operand:GPR 1 "const0_operand" "")))
901 (set (match_operand:GPR 2 "register_operand" "=d,d")
902 (match_dup 0))]
903 "s390_match_ccmode(insn, CCSmode) && TARGET_EXTIMM"
904 "@
905 lt<g>r\t%2,%0
906 lt<g>\t%2,%0"
907 [(set_attr "op_type" "RR<E>,RXY")
908 (set_attr "z10prop" "z10_fr_E1,z10_fwd_A3") ])
909
910 ; Peephole to combine a load-and-test from volatile memory which combine does
911 ; not do.
912 (define_peephole2
913 [(set (match_operand:GPR 0 "register_operand")
914 (match_operand:GPR 2 "memory_operand"))
915 (set (reg CC_REGNUM)
916 (compare (match_dup 0) (match_operand:GPR 1 "const0_operand")))]
917 "s390_match_ccmode(insn, CCSmode) && TARGET_EXTIMM
918 && GENERAL_REG_P (operands[0])
919 && satisfies_constraint_T (operands[2])"
920 [(parallel
921 [(set (reg:CCS CC_REGNUM)
922 (compare:CCS (match_dup 2) (match_dup 1)))
923 (set (match_dup 0) (match_dup 2))])])
924
925 ; ltr, lt, ltgr, ltg
926 (define_insn "*tst<mode>_cconly_extimm"
927 [(set (reg CC_REGNUM)
928 (compare (match_operand:GPR 0 "nonimmediate_operand" "d,T")
929 (match_operand:GPR 1 "const0_operand" "")))
930 (clobber (match_scratch:GPR 2 "=X,d"))]
931 "s390_match_ccmode(insn, CCSmode) && TARGET_EXTIMM"
932 "@
933 lt<g>r\t%0,%0
934 lt<g>\t%2,%0"
935 [(set_attr "op_type" "RR<E>,RXY")
936 (set_attr "z10prop" "z10_fr_E1,z10_fwd_A3")])
937
938 (define_insn "*tstdi"
939 [(set (reg CC_REGNUM)
940 (compare (match_operand:DI 0 "register_operand" "d")
941 (match_operand:DI 1 "const0_operand" "")))
942 (set (match_operand:DI 2 "register_operand" "=d")
943 (match_dup 0))]
944 "s390_match_ccmode(insn, CCSmode) && TARGET_ZARCH && !TARGET_EXTIMM"
945 "ltgr\t%2,%0"
946 [(set_attr "op_type" "RRE")
947 (set_attr "z10prop" "z10_fr_E1")])
948
949 (define_insn "*tstsi"
950 [(set (reg CC_REGNUM)
951 (compare (match_operand:SI 0 "nonimmediate_operand" "d,Q,S")
952 (match_operand:SI 1 "const0_operand" "")))
953 (set (match_operand:SI 2 "register_operand" "=d,d,d")
954 (match_dup 0))]
955 "s390_match_ccmode(insn, CCSmode) && !TARGET_EXTIMM"
956 "@
957 ltr\t%2,%0
958 icm\t%2,15,%S0
959 icmy\t%2,15,%S0"
960 [(set_attr "op_type" "RR,RS,RSY")
961 (set_attr "cpu_facility" "*,*,longdisp")
962 (set_attr "z10prop" "z10_fr_E1,z10_super_E1,z10_super_E1")])
963
964 (define_insn "*tstsi_cconly"
965 [(set (reg CC_REGNUM)
966 (compare (match_operand:SI 0 "nonimmediate_operand" "d,Q,S")
967 (match_operand:SI 1 "const0_operand" "")))
968 (clobber (match_scratch:SI 2 "=X,d,d"))]
969 "s390_match_ccmode(insn, CCSmode)"
970 "@
971 ltr\t%0,%0
972 icm\t%2,15,%S0
973 icmy\t%2,15,%S0"
974 [(set_attr "op_type" "RR,RS,RSY")
975 (set_attr "cpu_facility" "*,*,longdisp")
976 (set_attr "z10prop" "z10_fr_E1,z10_super_E1,z10_super_E1")])
977
978 (define_insn "*tstdi_cconly_31"
979 [(set (reg CC_REGNUM)
980 (compare (match_operand:DI 0 "register_operand" "d")
981 (match_operand:DI 1 "const0_operand" "")))]
982 "s390_match_ccmode(insn, CCSmode) && !TARGET_ZARCH"
983 "srda\t%0,0"
984 [(set_attr "op_type" "RS")
985 (set_attr "atype" "reg")])
986
987 ; ltr, ltgr
988 (define_insn "*tst<mode>_cconly2"
989 [(set (reg CC_REGNUM)
990 (compare (match_operand:GPR 0 "register_operand" "d")
991 (match_operand:GPR 1 "const0_operand" "")))]
992 "s390_match_ccmode(insn, CCSmode)"
993 "lt<g>r\t%0,%0"
994 [(set_attr "op_type" "RR<E>")
995 (set_attr "z10prop" "z10_fr_E1")])
996
997 ; tst(hi|qi) instruction pattern(s).
998
999 (define_insn "*tst<mode>CCT"
1000 [(set (reg CC_REGNUM)
1001 (compare (match_operand:HQI 0 "nonimmediate_operand" "?Q,?S,d")
1002 (match_operand:HQI 1 "const0_operand" "")))
1003 (set (match_operand:HQI 2 "register_operand" "=d,d,0")
1004 (match_dup 0))]
1005 "s390_match_ccmode(insn, CCTmode)"
1006 "@
1007 icm\t%2,<icm_lo>,%S0
1008 icmy\t%2,<icm_lo>,%S0
1009 tml\t%0,<max_uint>"
1010 [(set_attr "op_type" "RS,RSY,RI")
1011 (set_attr "cpu_facility" "*,longdisp,*")
1012 (set_attr "z10prop" "z10_super_E1,z10_super_E1,z10_super")])
1013
1014 (define_insn "*tsthiCCT_cconly"
1015 [(set (reg CC_REGNUM)
1016 (compare (match_operand:HI 0 "nonimmediate_operand" "Q,S,d")
1017 (match_operand:HI 1 "const0_operand" "")))
1018 (clobber (match_scratch:HI 2 "=d,d,X"))]
1019 "s390_match_ccmode(insn, CCTmode)"
1020 "@
1021 icm\t%2,3,%S0
1022 icmy\t%2,3,%S0
1023 tml\t%0,65535"
1024 [(set_attr "op_type" "RS,RSY,RI")
1025 (set_attr "cpu_facility" "*,longdisp,*")
1026 (set_attr "z10prop" "z10_super_E1,z10_super_E1,z10_super")])
1027
1028 (define_insn "*tstqiCCT_cconly"
1029 [(set (reg CC_REGNUM)
1030 (compare (match_operand:QI 0 "nonimmediate_operand" "?Q,?S,d")
1031 (match_operand:QI 1 "const0_operand" "")))]
1032 "s390_match_ccmode(insn, CCTmode)"
1033 "@
1034 cli\t%S0,0
1035 cliy\t%S0,0
1036 tml\t%0,255"
1037 [(set_attr "op_type" "SI,SIY,RI")
1038 (set_attr "cpu_facility" "*,longdisp,*")
1039 (set_attr "z10prop" "z10_super,z10_super,z10_super")])
1040
1041 (define_insn "*tst<mode>"
1042 [(set (reg CC_REGNUM)
1043 (compare (match_operand:HQI 0 "s_operand" "Q,S")
1044 (match_operand:HQI 1 "const0_operand" "")))
1045 (set (match_operand:HQI 2 "register_operand" "=d,d")
1046 (match_dup 0))]
1047 "s390_match_ccmode(insn, CCSmode)"
1048 "@
1049 icm\t%2,<icm_lo>,%S0
1050 icmy\t%2,<icm_lo>,%S0"
1051 [(set_attr "op_type" "RS,RSY")
1052 (set_attr "cpu_facility" "*,longdisp")
1053 (set_attr "z10prop" "z10_super_E1,z10_super_E1")])
1054
1055 (define_insn "*tst<mode>_cconly"
1056 [(set (reg CC_REGNUM)
1057 (compare (match_operand:HQI 0 "s_operand" "Q,S")
1058 (match_operand:HQI 1 "const0_operand" "")))
1059 (clobber (match_scratch:HQI 2 "=d,d"))]
1060 "s390_match_ccmode(insn, CCSmode)"
1061 "@
1062 icm\t%2,<icm_lo>,%S0
1063 icmy\t%2,<icm_lo>,%S0"
1064 [(set_attr "op_type" "RS,RSY")
1065 (set_attr "cpu_facility" "*,longdisp")
1066 (set_attr "z10prop" "z10_super_E1,z10_super_E1")])
1067
1068
1069 ; Compare (equality) instructions
1070
1071 (define_insn "*cmpdi_cct"
1072 [(set (reg CC_REGNUM)
1073 (compare (match_operand:DI 0 "nonimmediate_operand" "%d,d,d,d,Q")
1074 (match_operand:DI 1 "general_operand" "d,K,Os,T,BQ")))]
1075 "s390_match_ccmode (insn, CCTmode) && TARGET_ZARCH"
1076 "@
1077 cgr\t%0,%1
1078 cghi\t%0,%h1
1079 cgfi\t%0,%1
1080 cg\t%0,%1
1081 #"
1082 [(set_attr "op_type" "RRE,RI,RIL,RXY,SS")
1083 (set_attr "z10prop" "z10_super_c,z10_super,z10_super,z10_super,*")])
1084
1085 (define_insn "*cmpsi_cct"
1086 [(set (reg CC_REGNUM)
1087 (compare (match_operand:SI 0 "nonimmediate_operand" "%d,d,d,d,d,Q")
1088 (match_operand:SI 1 "general_operand" "d,K,Os,R,T,BQ")))]
1089 "s390_match_ccmode (insn, CCTmode)"
1090 "@
1091 cr\t%0,%1
1092 chi\t%0,%h1
1093 cfi\t%0,%1
1094 c\t%0,%1
1095 cy\t%0,%1
1096 #"
1097 [(set_attr "op_type" "RR,RI,RIL,RX,RXY,SS")
1098 (set_attr "cpu_facility" "*,*,*,*,longdisp,*")
1099 (set_attr "z10prop" "z10_super_c,z10_super,z10_super,z10_super,z10_super,*")])
1100
1101 ; Compare (signed) instructions
1102
1103 (define_insn "*cmpdi_ccs_sign"
1104 [(set (reg CC_REGNUM)
1105 (compare (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand"
1106 "d,T,b"))
1107 (match_operand:DI 0 "register_operand" "d, d,d")))]
1108 "s390_match_ccmode(insn, CCSRmode) && TARGET_ZARCH"
1109 "@
1110 cgfr\t%0,%1
1111 cgf\t%0,%1
1112 cgfrl\t%0,%1"
1113 [(set_attr "op_type" "RRE,RXY,RIL")
1114 (set_attr "z10prop" "z10_c,*,*")
1115 (set_attr "type" "*,*,larl")])
1116
1117
1118
1119 (define_insn "*cmpsi_ccs_sign"
1120 [(set (reg CC_REGNUM)
1121 (compare (sign_extend:SI (match_operand:HI 1 "memory_operand" "R,T,b"))
1122 (match_operand:SI 0 "register_operand" "d,d,d")))]
1123 "s390_match_ccmode(insn, CCSRmode)"
1124 "@
1125 ch\t%0,%1
1126 chy\t%0,%1
1127 chrl\t%0,%1"
1128 [(set_attr "op_type" "RX,RXY,RIL")
1129 (set_attr "cpu_facility" "*,longdisp,z10")
1130 (set_attr "type" "*,*,larl")
1131 (set_attr "z196prop" "z196_cracked,z196_cracked,z196_cracked")])
1132
1133 (define_insn "*cmphi_ccs_z10"
1134 [(set (reg CC_REGNUM)
1135 (compare (match_operand:HI 0 "s_operand" "Q")
1136 (match_operand:HI 1 "immediate_operand" "K")))]
1137 "s390_match_ccmode(insn, CCSmode) && TARGET_Z10"
1138 "chhsi\t%0,%1"
1139 [(set_attr "op_type" "SIL")
1140 (set_attr "z196prop" "z196_cracked")])
1141
1142 (define_insn "*cmpdi_ccs_signhi_rl"
1143 [(set (reg CC_REGNUM)
1144 (compare (sign_extend:DI (match_operand:HI 1 "memory_operand" "T,b"))
1145 (match_operand:GPR 0 "register_operand" "d,d")))]
1146 "s390_match_ccmode(insn, CCSRmode) && TARGET_Z10"
1147 "@
1148 cgh\t%0,%1
1149 cghrl\t%0,%1"
1150 [(set_attr "op_type" "RXY,RIL")
1151 (set_attr "type" "*,larl")])
1152
1153 ; cr, chi, cfi, c, cy, cgr, cghi, cgfi, cg, chsi, cghsi, crl, cgrl
1154 (define_insn "*cmp<mode>_ccs"
1155 [(set (reg CC_REGNUM)
1156 (compare (match_operand:GPR 0 "nonimmediate_operand"
1157 "d,d,Q, d,d,d,d")
1158 (match_operand:GPR 1 "general_operand"
1159 "d,K,K,Os,R,T,b")))]
1160 "s390_match_ccmode(insn, CCSmode)"
1161 "@
1162 c<g>r\t%0,%1
1163 c<g>hi\t%0,%h1
1164 c<g>hsi\t%0,%h1
1165 c<g>fi\t%0,%1
1166 c<g>\t%0,%1
1167 c<y>\t%0,%1
1168 c<g>rl\t%0,%1"
1169 [(set_attr "op_type" "RR<E>,RI,SIL,RIL,RX<Y>,RXY,RIL")
1170 (set_attr "cpu_facility" "*,*,z10,extimm,*,longdisp,z10")
1171 (set_attr "type" "*,*,*,*,*,*,larl")
1172 (set_attr "z10prop" "z10_super_c,z10_super,z10_super,z10_super,z10_super,z10_super,z10_super")])
1173
1174
1175 ; Compare (unsigned) instructions
1176
1177 (define_insn "*cmpsi_ccu_zerohi_rlsi"
1178 [(set (reg CC_REGNUM)
1179 (compare (zero_extend:SI (mem:HI (match_operand:SI 1
1180 "larl_operand" "X")))
1181 (match_operand:SI 0 "register_operand" "d")))]
1182 "s390_match_ccmode(insn, CCURmode) && TARGET_Z10"
1183 "clhrl\t%0,%1"
1184 [(set_attr "op_type" "RIL")
1185 (set_attr "type" "larl")
1186 (set_attr "z10prop" "z10_super")])
1187
1188 ; clhrl, clghrl
1189 (define_insn "*cmp<GPR:mode>_ccu_zerohi_rldi"
1190 [(set (reg CC_REGNUM)
1191 (compare (zero_extend:GPR (mem:HI (match_operand:DI 1
1192 "larl_operand" "X")))
1193 (match_operand:GPR 0 "register_operand" "d")))]
1194 "s390_match_ccmode(insn, CCURmode) && TARGET_Z10"
1195 "cl<g>hrl\t%0,%1"
1196 [(set_attr "op_type" "RIL")
1197 (set_attr "type" "larl")
1198 (set_attr "z10prop" "z10_super")])
1199
1200 (define_insn "*cmpdi_ccu_zero"
1201 [(set (reg CC_REGNUM)
1202 (compare (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand"
1203 "d,T,b"))
1204 (match_operand:DI 0 "register_operand" "d,d,d")))]
1205 "s390_match_ccmode (insn, CCURmode) && TARGET_ZARCH"
1206 "@
1207 clgfr\t%0,%1
1208 clgf\t%0,%1
1209 clgfrl\t%0,%1"
1210 [(set_attr "op_type" "RRE,RXY,RIL")
1211 (set_attr "cpu_facility" "*,*,z10")
1212 (set_attr "type" "*,*,larl")
1213 (set_attr "z10prop" "z10_super_c,z10_super_E1,z10_super")])
1214
1215 (define_insn "*cmpdi_ccu"
1216 [(set (reg CC_REGNUM)
1217 (compare (match_operand:DI 0 "nonimmediate_operand"
1218 "d, d,d,Q,d, Q,BQ")
1219 (match_operand:DI 1 "general_operand"
1220 "d,Op,b,D,T,BQ,Q")))]
1221 "s390_match_ccmode (insn, CCUmode) && TARGET_ZARCH"
1222 "@
1223 clgr\t%0,%1
1224 clgfi\t%0,%1
1225 clgrl\t%0,%1
1226 clghsi\t%0,%x1
1227 clg\t%0,%1
1228 #
1229 #"
1230 [(set_attr "op_type" "RRE,RIL,RIL,SIL,RXY,SS,SS")
1231 (set_attr "cpu_facility" "*,extimm,z10,z10,*,*,*")
1232 (set_attr "type" "*,*,larl,*,*,*,*")
1233 (set_attr "z10prop" "z10_super_c,z10_super,z10_super,z10_super,z10_super,*,*")])
1234
1235 (define_insn "*cmpsi_ccu"
1236 [(set (reg CC_REGNUM)
1237 (compare (match_operand:SI 0 "nonimmediate_operand" "d, d,d,Q,d,d, Q,BQ")
1238 (match_operand:SI 1 "general_operand" "d,Os,b,D,R,T,BQ, Q")))]
1239 "s390_match_ccmode (insn, CCUmode)"
1240 "@
1241 clr\t%0,%1
1242 clfi\t%0,%o1
1243 clrl\t%0,%1
1244 clfhsi\t%0,%x1
1245 cl\t%0,%1
1246 cly\t%0,%1
1247 #
1248 #"
1249 [(set_attr "op_type" "RR,RIL,RIL,SIL,RX,RXY,SS,SS")
1250 (set_attr "cpu_facility" "*,extimm,z10,z10,*,longdisp,*,*")
1251 (set_attr "type" "*,*,larl,*,*,*,*,*")
1252 (set_attr "z10prop" "z10_super_c,z10_super,z10_super,z10_super,z10_super,z10_super,*,*")])
1253
1254 (define_insn "*cmphi_ccu"
1255 [(set (reg CC_REGNUM)
1256 (compare (match_operand:HI 0 "nonimmediate_operand" "d,d,Q,Q,BQ")
1257 (match_operand:HI 1 "general_operand" "Q,S,D,BQ,Q")))]
1258 "s390_match_ccmode (insn, CCUmode)
1259 && !register_operand (operands[1], HImode)"
1260 "@
1261 clm\t%0,3,%S1
1262 clmy\t%0,3,%S1
1263 clhhsi\t%0,%1
1264 #
1265 #"
1266 [(set_attr "op_type" "RS,RSY,SIL,SS,SS")
1267 (set_attr "cpu_facility" "*,longdisp,z10,*,*")
1268 (set_attr "z10prop" "*,*,z10_super,*,*")])
1269
1270 (define_insn "*cmpqi_ccu"
1271 [(set (reg CC_REGNUM)
1272 (compare (match_operand:QI 0 "nonimmediate_operand" "d,d,Q,S,Q,BQ")
1273 (match_operand:QI 1 "general_operand" "Q,S,n,n,BQ,Q")))]
1274 "s390_match_ccmode (insn, CCUmode)
1275 && !register_operand (operands[1], QImode)"
1276 "@
1277 clm\t%0,1,%S1
1278 clmy\t%0,1,%S1
1279 cli\t%S0,%b1
1280 cliy\t%S0,%b1
1281 #
1282 #"
1283 [(set_attr "op_type" "RS,RSY,SI,SIY,SS,SS")
1284 (set_attr "cpu_facility" "*,longdisp,*,longdisp,*,*")
1285 (set_attr "z10prop" "*,*,z10_super,z10_super,*,*")])
1286
1287
1288 ; Block compare (CLC) instruction patterns.
1289
1290 (define_insn "*clc"
1291 [(set (reg CC_REGNUM)
1292 (compare (match_operand:BLK 0 "memory_operand" "Q")
1293 (match_operand:BLK 1 "memory_operand" "Q")))
1294 (use (match_operand 2 "const_int_operand" "n"))]
1295 "s390_match_ccmode (insn, CCUmode)
1296 && INTVAL (operands[2]) >= 1 && INTVAL (operands[2]) <= 256"
1297 "clc\t%O0(%2,%R0),%S1"
1298 [(set_attr "op_type" "SS")])
1299
1300 (define_split
1301 [(set (reg CC_REGNUM)
1302 (compare (match_operand 0 "memory_operand" "")
1303 (match_operand 1 "memory_operand" "")))]
1304 "reload_completed
1305 && s390_match_ccmode (insn, CCUmode)
1306 && GET_MODE (operands[0]) == GET_MODE (operands[1])
1307 && GET_MODE_SIZE (GET_MODE (operands[0])) > 0"
1308 [(parallel
1309 [(set (match_dup 0) (match_dup 1))
1310 (use (match_dup 2))])]
1311 {
1312 operands[2] = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[0])));
1313 operands[0] = adjust_address (operands[0], BLKmode, 0);
1314 operands[1] = adjust_address (operands[1], BLKmode, 0);
1315
1316 operands[1] = gen_rtx_COMPARE (GET_MODE (SET_DEST (PATTERN (curr_insn))),
1317 operands[0], operands[1]);
1318 operands[0] = SET_DEST (PATTERN (curr_insn));
1319 })
1320
1321
1322 ; (TF|DF|SF|TD|DD|SD) instructions
1323
1324
1325 ; load and test instructions turn SNaN into QNaN what is not
1326 ; acceptable if the target will be used afterwards. On the other hand
1327 ; they are quite convenient for implementing comparisons with 0.0. So
1328 ; try to enable them via splitter if the value isn't needed anymore.
1329
1330 ; ltxbr, ltdbr, ltebr, ltxtr, ltdtr
1331 (define_insn "*cmp<mode>_ccs_0"
1332 [(set (reg CC_REGNUM)
1333 (compare (match_operand:FP 0 "register_operand" "f")
1334 (match_operand:FP 1 "const0_operand" "")))
1335 (clobber (match_operand:FP 2 "register_operand" "=0"))]
1336 "s390_match_ccmode(insn, CCSmode) && TARGET_HARD_FLOAT"
1337 "lt<xde><bt>r\t%0,%0"
1338 [(set_attr "op_type" "RRE")
1339 (set_attr "type" "fsimp<mode>")])
1340
1341 (define_split
1342 [(set (match_operand 0 "cc_reg_operand")
1343 (compare (match_operand:FP 1 "register_operand")
1344 (match_operand:FP 2 "const0_operand")))]
1345 "TARGET_HARD_FLOAT && REG_P (operands[1]) && dead_or_set_p (insn, operands[1])"
1346 [(parallel
1347 [(set (match_dup 0) (match_dup 3))
1348 (clobber (match_dup 1))])]
1349 {
1350 /* s390_match_ccmode requires the compare to have the same CC mode
1351 as the CC destination register. */
1352 operands[3] = gen_rtx_COMPARE (GET_MODE (operands[0]),
1353 operands[1], operands[2]);
1354 })
1355
1356
1357 ; VX: TFmode in FPR pairs: use cxbr instead of wfcxb
1358 ; cxtr, cdtr, cxbr, cdbr, cebr, cdb, ceb, wfcsb, wfcdb
1359 (define_insn "*cmp<mode>_ccs"
1360 [(set (reg CC_REGNUM)
1361 (compare (match_operand:FP 0 "register_operand" "f,f,v,v")
1362 (match_operand:FP 1 "general_operand" "f,R,v,v")))]
1363 "s390_match_ccmode(insn, CCSmode) && TARGET_HARD_FLOAT"
1364 "@
1365 c<xde><bt>r\t%0,%1
1366 c<xde>b\t%0,%1
1367 wfcdb\t%0,%1
1368 wfcsb\t%0,%1"
1369 [(set_attr "op_type" "RRE,RXE,VRR,VRR")
1370 (set_attr "cpu_facility" "*,*,vx,vxe")
1371 (set_attr "enabled" "*,<DSF>,<DF>,<SF>")])
1372
1373 ; Compare and Branch instructions
1374
1375 ; cij, cgij, crj, cgrj, cfi, cgfi, cr, cgr
1376 ; The following instructions do a complementary access of their second
1377 ; operand (z01 only): crj_c, cgrjc, cr, cgr
1378 (define_insn "*cmp_and_br_signed_<mode>"
1379 [(set (pc)
1380 (if_then_else (match_operator 0 "s390_signed_integer_comparison"
1381 [(match_operand:GPR 1 "register_operand" "d,d")
1382 (match_operand:GPR 2 "nonmemory_operand" "d,C")])
1383 (label_ref (match_operand 3 "" ""))
1384 (pc)))
1385 (clobber (reg:CC CC_REGNUM))]
1386 "TARGET_Z10 && !TARGET_AVOID_CMP_AND_BRANCH"
1387 {
1388 if (get_attr_length (insn) == 6)
1389 return which_alternative ?
1390 "c<g>ij%C0\t%1,%c2,%l3" : "c<g>rj%C0\t%1,%2,%l3";
1391 else
1392 return which_alternative ?
1393 "c<g>fi\t%1,%c2\;jg%C0\t%l3" : "c<g>r\t%1,%2\;jg%C0\t%l3";
1394 }
1395 [(set_attr "op_type" "RIE")
1396 (set_attr "type" "branch")
1397 (set_attr "z10prop" "z10_super_c,z10_super")
1398 (set (attr "length")
1399 (if_then_else (lt (abs (minus (pc) (match_dup 3))) (const_int 60000))
1400 (const_int 6) (const_int 12)))]) ; 8 byte for cr/jg
1401 ; 10 byte for cgr/jg
1402
1403 ; clij, clgij, clrj, clgrj, clfi, clgfi, clr, clgr
1404 ; The following instructions do a complementary access of their second
1405 ; operand (z10 only): clrj, clgrj, clr, clgr
1406 (define_insn "*cmp_and_br_unsigned_<mode>"
1407 [(set (pc)
1408 (if_then_else (match_operator 0 "s390_unsigned_integer_comparison"
1409 [(match_operand:GPR 1 "register_operand" "d,d")
1410 (match_operand:GPR 2 "nonmemory_operand" "d,I")])
1411 (label_ref (match_operand 3 "" ""))
1412 (pc)))
1413 (clobber (reg:CC CC_REGNUM))]
1414 "TARGET_Z10 && !TARGET_AVOID_CMP_AND_BRANCH"
1415 {
1416 if (get_attr_length (insn) == 6)
1417 return which_alternative ?
1418 "cl<g>ij%C0\t%1,%b2,%l3" : "cl<g>rj%C0\t%1,%2,%l3";
1419 else
1420 return which_alternative ?
1421 "cl<g>fi\t%1,%b2\;jg%C0\t%l3" : "cl<g>r\t%1,%2\;jg%C0\t%l3";
1422 }
1423 [(set_attr "op_type" "RIE")
1424 (set_attr "type" "branch")
1425 (set_attr "z10prop" "z10_super_c,z10_super")
1426 (set (attr "length")
1427 (if_then_else (lt (abs (minus (pc) (match_dup 3))) (const_int 60000))
1428 (const_int 6) (const_int 12)))]) ; 8 byte for clr/jg
1429 ; 10 byte for clgr/jg
1430
1431 ; And now the same two patterns as above but with a negated CC mask.
1432
1433 ; cij, cgij, crj, cgrj, cfi, cgfi, cr, cgr
1434 ; The following instructions do a complementary access of their second
1435 ; operand (z01 only): crj_c, cgrjc, cr, cgr
1436 (define_insn "*icmp_and_br_signed_<mode>"
1437 [(set (pc)
1438 (if_then_else (match_operator 0 "s390_signed_integer_comparison"
1439 [(match_operand:GPR 1 "register_operand" "d,d")
1440 (match_operand:GPR 2 "nonmemory_operand" "d,C")])
1441 (pc)
1442 (label_ref (match_operand 3 "" ""))))
1443 (clobber (reg:CC CC_REGNUM))]
1444 "TARGET_Z10 && !TARGET_AVOID_CMP_AND_BRANCH"
1445 {
1446 if (get_attr_length (insn) == 6)
1447 return which_alternative ?
1448 "c<g>ij%D0\t%1,%c2,%l3" : "c<g>rj%D0\t%1,%2,%l3";
1449 else
1450 return which_alternative ?
1451 "c<g>fi\t%1,%c2\;jg%D0\t%l3" : "c<g>r\t%1,%2\;jg%D0\t%l3";
1452 }
1453 [(set_attr "op_type" "RIE")
1454 (set_attr "type" "branch")
1455 (set_attr "z10prop" "z10_super_c,z10_super")
1456 (set (attr "length")
1457 (if_then_else (lt (abs (minus (pc) (match_dup 3))) (const_int 60000))
1458 (const_int 6) (const_int 12)))]) ; 8 byte for cr/jg
1459 ; 10 byte for cgr/jg
1460
1461 ; clij, clgij, clrj, clgrj, clfi, clgfi, clr, clgr
1462 ; The following instructions do a complementary access of their second
1463 ; operand (z10 only): clrj, clgrj, clr, clgr
1464 (define_insn "*icmp_and_br_unsigned_<mode>"
1465 [(set (pc)
1466 (if_then_else (match_operator 0 "s390_unsigned_integer_comparison"
1467 [(match_operand:GPR 1 "register_operand" "d,d")
1468 (match_operand:GPR 2 "nonmemory_operand" "d,I")])
1469 (pc)
1470 (label_ref (match_operand 3 "" ""))))
1471 (clobber (reg:CC CC_REGNUM))]
1472 "TARGET_Z10 && !TARGET_AVOID_CMP_AND_BRANCH"
1473 {
1474 if (get_attr_length (insn) == 6)
1475 return which_alternative ?
1476 "cl<g>ij%D0\t%1,%b2,%l3" : "cl<g>rj%D0\t%1,%2,%l3";
1477 else
1478 return which_alternative ?
1479 "cl<g>fi\t%1,%b2\;jg%D0\t%l3" : "cl<g>r\t%1,%2\;jg%D0\t%l3";
1480 }
1481 [(set_attr "op_type" "RIE")
1482 (set_attr "type" "branch")
1483 (set_attr "z10prop" "z10_super_c,z10_super")
1484 (set (attr "length")
1485 (if_then_else (lt (abs (minus (pc) (match_dup 3))) (const_int 60000))
1486 (const_int 6) (const_int 12)))]) ; 8 byte for clr/jg
1487 ; 10 byte for clgr/jg
1488
1489 ;;
1490 ;;- Move instructions.
1491 ;;
1492
1493 ;
1494 ; movti instruction pattern(s).
1495 ;
1496
1497
1498 ; Separate out the register pair alternative since constraints (P) are
1499 ; not able to deal with const_wide_int's. But predicates do.
1500 (define_insn "*movti_bigconst"
1501 [(set (match_operand:TI 0 "register_operand" "=d")
1502 (match_operand:TI 1 "reload_const_wide_int_operand" ""))]
1503 "TARGET_ZARCH"
1504 "#")
1505
1506 ; FIXME: More constants are possible by enabling jxx, jyy constraints
1507 ; for TImode (use double-int for the calculations)
1508 (define_insn "movti"
1509 [(set (match_operand:TI 0 "nonimmediate_operand" "=d,S,v, v, v,v,d,v,R, d,o")
1510 (match_operand:TI 1 "general_operand" " S,d,v,j00,jm1,d,v,R,v,dT,d"))]
1511 "TARGET_ZARCH"
1512 "@
1513 lmg\t%0,%N0,%S1
1514 stmg\t%1,%N1,%S0
1515 vlr\t%v0,%v1
1516 vzero\t%v0
1517 vone\t%v0
1518 vlvgp\t%v0,%1,%N1
1519 #
1520 vl\t%v0,%1
1521 vst\t%v1,%0
1522 #
1523 #"
1524 [(set_attr "op_type" "RSY,RSY,VRR,VRI,VRI,VRR,*,VRX,VRX,*,*")
1525 (set_attr "type" "lm,stm,*,*,*,*,*,*,*,*,*")
1526 (set_attr "cpu_facility" "*,*,vx,vx,vx,vx,vx,vx,vx,*,*")])
1527
1528 (define_split
1529 [(set (match_operand:TI 0 "nonimmediate_operand" "")
1530 (match_operand:TI 1 "general_operand" ""))]
1531 "TARGET_ZARCH && reload_completed
1532 && !s_operand (operands[0], TImode)
1533 && !s_operand (operands[1], TImode)
1534 && s390_split_ok_p (operands[0], operands[1], TImode, 0)"
1535 [(set (match_dup 2) (match_dup 4))
1536 (set (match_dup 3) (match_dup 5))]
1537 {
1538 operands[2] = operand_subword (operands[0], 0, 0, TImode);
1539 operands[3] = operand_subword (operands[0], 1, 0, TImode);
1540 operands[4] = operand_subword (operands[1], 0, 0, TImode);
1541 operands[5] = operand_subword (operands[1], 1, 0, TImode);
1542 })
1543
1544 (define_split
1545 [(set (match_operand:TI 0 "nonimmediate_operand" "")
1546 (match_operand:TI 1 "general_operand" ""))]
1547 "TARGET_ZARCH && reload_completed
1548 && !s_operand (operands[0], TImode)
1549 && !s_operand (operands[1], TImode)
1550 && s390_split_ok_p (operands[0], operands[1], TImode, 1)"
1551 [(set (match_dup 2) (match_dup 4))
1552 (set (match_dup 3) (match_dup 5))]
1553 {
1554 operands[2] = operand_subword (operands[0], 1, 0, TImode);
1555 operands[3] = operand_subword (operands[0], 0, 0, TImode);
1556 operands[4] = operand_subword (operands[1], 1, 0, TImode);
1557 operands[5] = operand_subword (operands[1], 0, 0, TImode);
1558 })
1559
1560 ; Use part of the TImode target reg to perform the address
1561 ; calculation. If the TImode value is supposed to be copied into a VR
1562 ; this splitter is not necessary.
1563 (define_split
1564 [(set (match_operand:TI 0 "register_operand" "")
1565 (match_operand:TI 1 "memory_operand" ""))]
1566 "TARGET_ZARCH && reload_completed
1567 && !VECTOR_REG_P (operands[0])
1568 && !s_operand (operands[1], VOIDmode)"
1569 [(set (match_dup 0) (match_dup 1))]
1570 {
1571 rtx addr = operand_subword (operands[0], 1, 0, TImode);
1572 addr = gen_lowpart (Pmode, addr);
1573 s390_load_address (addr, XEXP (operands[1], 0));
1574 operands[1] = replace_equiv_address (operands[1], addr);
1575 })
1576
1577
1578 ; Split a VR -> GPR TImode move into 2 vector load GR from VR element.
1579 ; For the higher order bits we do simply a DImode move while the
1580 ; second part is done via vec extract. Both will end up as vlgvg.
1581 (define_split
1582 [(set (match_operand:TI 0 "register_operand" "")
1583 (match_operand:TI 1 "register_operand" ""))]
1584 "TARGET_VX && reload_completed
1585 && GENERAL_REG_P (operands[0])
1586 && VECTOR_REG_P (operands[1])"
1587 [(set (match_dup 2) (match_dup 4))
1588 (set (match_dup 3) (unspec:DI [(match_dup 5) (const_int 1)]
1589 UNSPEC_VEC_EXTRACT))]
1590 {
1591 operands[2] = operand_subword (operands[0], 0, 0, TImode);
1592 operands[3] = operand_subword (operands[0], 1, 0, TImode);
1593 operands[4] = gen_rtx_REG (DImode, REGNO (operands[1]));
1594 operands[5] = gen_rtx_REG (V2DImode, REGNO (operands[1]));
1595 })
1596
1597 ;
1598 ; Patterns used for secondary reloads
1599 ;
1600
1601 ; z10 provides move instructions accepting larl memory operands.
1602 ; Unfortunately there is no such variant for QI, TI and FP mode moves.
1603 ; These patterns are also used for unaligned SI and DI accesses.
1604
1605 (define_expand "reload<ALL:mode><P:mode>_tomem_z10"
1606 [(parallel [(match_operand:ALL 0 "memory_operand" "")
1607 (match_operand:ALL 1 "register_operand" "=d")
1608 (match_operand:P 2 "register_operand" "=&a")])]
1609 "TARGET_Z10"
1610 {
1611 s390_reload_symref_address (operands[1], operands[0], operands[2], 1);
1612 DONE;
1613 })
1614
1615 (define_expand "reload<ALL:mode><P:mode>_toreg_z10"
1616 [(parallel [(match_operand:ALL 0 "register_operand" "=d")
1617 (match_operand:ALL 1 "memory_operand" "")
1618 (match_operand:P 2 "register_operand" "=a")])]
1619 "TARGET_Z10"
1620 {
1621 s390_reload_symref_address (operands[0], operands[1], operands[2], 0);
1622 DONE;
1623 })
1624
1625 (define_expand "reload<P:mode>_larl_odd_addend_z10"
1626 [(parallel [(match_operand:P 0 "register_operand" "=d")
1627 (match_operand:P 1 "larl_operand" "")
1628 (match_operand:P 2 "register_operand" "=a")])]
1629 "TARGET_Z10"
1630 {
1631 s390_reload_larl_operand (operands[0], operands[1], operands[2]);
1632 DONE;
1633 })
1634
1635 ; Handles loading a PLUS (load address) expression
1636
1637 (define_expand "reload<mode>_plus"
1638 [(parallel [(match_operand:P 0 "register_operand" "=a")
1639 (match_operand:P 1 "s390_plus_operand" "")
1640 (match_operand:P 2 "register_operand" "=&a")])]
1641 ""
1642 {
1643 s390_expand_plus_operand (operands[0], operands[1], operands[2]);
1644 DONE;
1645 })
1646
1647 ; Not all the indirect memory access instructions support the full
1648 ; format (long disp + index + base). So whenever a move from/to such
1649 ; an address is required and the instruction cannot deal with it we do
1650 ; a load address into a scratch register first and use this as the new
1651 ; base register.
1652 ; This in particular is used for:
1653 ; - non-offsetable memory accesses for multiword moves
1654 ; - full vector reg moves with long displacements
1655
1656 (define_expand "reload<mode>_la_in"
1657 [(parallel [(match_operand 0 "register_operand" "")
1658 (match_operand 1 "" "")
1659 (match_operand:P 2 "register_operand" "=&a")])]
1660 ""
1661 {
1662 gcc_assert (MEM_P (operands[1]));
1663 s390_load_address (operands[2], find_replacement (&XEXP (operands[1], 0)));
1664 operands[1] = replace_equiv_address (operands[1], operands[2]);
1665 emit_move_insn (operands[0], operands[1]);
1666 DONE;
1667 })
1668
1669 (define_expand "reload<mode>_la_out"
1670 [(parallel [(match_operand 0 "" "")
1671 (match_operand 1 "register_operand" "")
1672 (match_operand:P 2 "register_operand" "=&a")])]
1673 ""
1674 {
1675 gcc_assert (MEM_P (operands[0]));
1676 s390_load_address (operands[2], find_replacement (&XEXP (operands[0], 0)));
1677 operands[0] = replace_equiv_address (operands[0], operands[2]);
1678 emit_move_insn (operands[0], operands[1]);
1679 DONE;
1680 })
1681
1682 (define_expand "reload<mode>_PIC_addr"
1683 [(parallel [(match_operand 0 "register_operand" "=d")
1684 (match_operand 1 "larl_operand" "")
1685 (match_operand:P 2 "register_operand" "=a")])]
1686 ""
1687 {
1688 rtx new_rtx = legitimize_pic_address (operands[1], operands[2]);
1689 emit_move_insn (operands[0], new_rtx);
1690 })
1691
1692 ;
1693 ; movdi instruction pattern(s).
1694 ;
1695
1696 (define_expand "movdi"
1697 [(set (match_operand:DI 0 "general_operand" "")
1698 (match_operand:DI 1 "general_operand" ""))]
1699 ""
1700 {
1701 /* Handle symbolic constants. */
1702 if (TARGET_64BIT
1703 && (SYMBOLIC_CONST (operands[1])
1704 || (GET_CODE (operands[1]) == PLUS
1705 && XEXP (operands[1], 0) == pic_offset_table_rtx
1706 && SYMBOLIC_CONST (XEXP (operands[1], 1)))))
1707 emit_symbolic_move (operands);
1708 })
1709
1710 (define_insn "*movdi_larl"
1711 [(set (match_operand:DI 0 "register_operand" "=d")
1712 (match_operand:DI 1 "larl_operand" "X"))]
1713 "TARGET_64BIT
1714 && !FP_REG_P (operands[0])"
1715 "larl\t%0,%1"
1716 [(set_attr "op_type" "RIL")
1717 (set_attr "type" "larl")
1718 (set_attr "z10prop" "z10_super_A1")])
1719
1720 (define_insn "*movdi_64"
1721 [(set (match_operand:DI 0 "nonimmediate_operand"
1722 "=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")
1723 (match_operand:DI 1 "general_operand"
1724 " 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"))]
1725 "TARGET_ZARCH"
1726 "@
1727 lghi\t%0,%h1
1728 llihh\t%0,%i1
1729 llihl\t%0,%i1
1730 llilh\t%0,%i1
1731 llill\t%0,%i1
1732 lgfi\t%0,%1
1733 llihf\t%0,%k1
1734 llilf\t%0,%k1
1735 ldgr\t%0,%1
1736 lgdr\t%0,%1
1737 lay\t%0,%a1
1738 lgrl\t%0,%1
1739 lgr\t%0,%1
1740 lg\t%0,%1
1741 stg\t%1,%0
1742 ldr\t%0,%1
1743 ld\t%0,%1
1744 ldy\t%0,%1
1745 std\t%1,%0
1746 stdy\t%1,%0
1747 stgrl\t%1,%0
1748 mvghi\t%0,%1
1749 #
1750 #
1751 stam\t%1,%N1,%S0
1752 lam\t%0,%N0,%S1
1753 vleig\t%v0,%h1,0
1754 vlr\t%v0,%v1
1755 vlvgg\t%v0,%1,0
1756 vlgvg\t%0,%v1,0
1757 vleg\t%v0,%1,0
1758 vsteg\t%v1,%0,0"
1759 [(set_attr "op_type" "RI,RI,RI,RI,RI,RIL,RIL,RIL,RRE,RRE,RXY,RIL,RRE,RXY,
1760 RXY,RR,RX,RXY,RX,RXY,RIL,SIL,*,*,RS,RS,VRI,VRR,VRS,VRS,VRX,VRX")
1761 (set_attr "type" "*,*,*,*,*,*,*,*,floaddf,floaddf,la,larl,lr,load,store,
1762 floaddf,floaddf,floaddf,fstoredf,fstoredf,larl,*,*,*,*,
1763 *,*,*,*,*,*,*")
1764 (set_attr "cpu_facility" "*,*,*,*,*,extimm,extimm,extimm,dfp,dfp,longdisp,
1765 z10,*,*,*,*,*,longdisp,*,longdisp,
1766 z10,z10,*,*,*,*,vx,vx,vx,vx,vx,vx")
1767 (set_attr "z10prop" "z10_fwd_A1,
1768 z10_fwd_E1,
1769 z10_fwd_E1,
1770 z10_fwd_E1,
1771 z10_fwd_E1,
1772 z10_fwd_A1,
1773 z10_fwd_E1,
1774 z10_fwd_E1,
1775 *,
1776 *,
1777 z10_fwd_A1,
1778 z10_fwd_A3,
1779 z10_fr_E1,
1780 z10_fwd_A3,
1781 z10_rec,
1782 *,
1783 *,
1784 *,
1785 *,
1786 *,
1787 z10_rec,
1788 z10_super,
1789 *,
1790 *,
1791 *,
1792 *,*,*,*,*,*,*")
1793 ])
1794
1795 (define_split
1796 [(set (match_operand:DI 0 "register_operand" "")
1797 (match_operand:DI 1 "register_operand" ""))]
1798 "TARGET_ZARCH && ACCESS_REG_P (operands[1])"
1799 [(set (match_dup 2) (match_dup 3))
1800 (set (match_dup 0) (ashift:DI (match_dup 0) (const_int 32)))
1801 (set (strict_low_part (match_dup 2)) (match_dup 4))]
1802 "operands[2] = gen_lowpart (SImode, operands[0]);
1803 s390_split_access_reg (operands[1], &operands[4], &operands[3]);")
1804
1805 (define_split
1806 [(set (match_operand:DI 0 "register_operand" "")
1807 (match_operand:DI 1 "register_operand" ""))]
1808 "TARGET_ZARCH && ACCESS_REG_P (operands[0])
1809 && dead_or_set_p (insn, operands[1])"
1810 [(set (match_dup 3) (match_dup 2))
1811 (set (match_dup 1) (lshiftrt:DI (match_dup 1) (const_int 32)))
1812 (set (match_dup 4) (match_dup 2))]
1813 "operands[2] = gen_lowpart (SImode, operands[1]);
1814 s390_split_access_reg (operands[0], &operands[3], &operands[4]);")
1815
1816 (define_split
1817 [(set (match_operand:DI 0 "register_operand" "")
1818 (match_operand:DI 1 "register_operand" ""))]
1819 "TARGET_ZARCH && ACCESS_REG_P (operands[0])
1820 && !dead_or_set_p (insn, operands[1])"
1821 [(set (match_dup 3) (match_dup 2))
1822 (set (match_dup 1) (rotate:DI (match_dup 1) (const_int 32)))
1823 (set (match_dup 4) (match_dup 2))
1824 (set (match_dup 1) (rotate:DI (match_dup 1) (const_int 32)))]
1825 "operands[2] = gen_lowpart (SImode, operands[1]);
1826 s390_split_access_reg (operands[0], &operands[3], &operands[4]);")
1827
1828 (define_insn "*movdi_31"
1829 [(set (match_operand:DI 0 "nonimmediate_operand"
1830 "=d,d,Q,S,d ,o,!*f,!*f,!*f,!R,!T,d")
1831 (match_operand:DI 1 "general_operand"
1832 " Q,S,d,d,dPT,d, *f, R, T,*f,*f,b"))]
1833 "!TARGET_ZARCH"
1834 "@
1835 lm\t%0,%N0,%S1
1836 lmy\t%0,%N0,%S1
1837 stm\t%1,%N1,%S0
1838 stmy\t%1,%N1,%S0
1839 #
1840 #
1841 ldr\t%0,%1
1842 ld\t%0,%1
1843 ldy\t%0,%1
1844 std\t%1,%0
1845 stdy\t%1,%0
1846 #"
1847 [(set_attr "op_type" "RS,RSY,RS,RSY,*,*,RR,RX,RXY,RX,RXY,*")
1848 (set_attr "type" "lm,lm,stm,stm,*,*,floaddf,floaddf,floaddf,fstoredf,fstoredf,*")
1849 (set_attr "cpu_facility" "*,longdisp,*,longdisp,*,*,*,*,longdisp,*,longdisp,z10")])
1850
1851 ; For a load from a symbol ref we can use one of the target registers
1852 ; together with larl to load the address.
1853 (define_split
1854 [(set (match_operand:DI 0 "register_operand" "")
1855 (match_operand:DI 1 "memory_operand" ""))]
1856 "!TARGET_ZARCH && reload_completed && TARGET_Z10
1857 && larl_operand (XEXP (operands[1], 0), SImode)"
1858 [(set (match_dup 2) (match_dup 3))
1859 (set (match_dup 0) (match_dup 1))]
1860 {
1861 operands[2] = operand_subword (operands[0], 1, 0, DImode);
1862 operands[3] = XEXP (operands[1], 0);
1863 operands[1] = replace_equiv_address (operands[1], operands[2]);
1864 })
1865
1866 (define_split
1867 [(set (match_operand:DI 0 "nonimmediate_operand" "")
1868 (match_operand:DI 1 "general_operand" ""))]
1869 "!TARGET_ZARCH && reload_completed
1870 && !s_operand (operands[0], DImode)
1871 && !s_operand (operands[1], DImode)
1872 && s390_split_ok_p (operands[0], operands[1], DImode, 0)"
1873 [(set (match_dup 2) (match_dup 4))
1874 (set (match_dup 3) (match_dup 5))]
1875 {
1876 operands[2] = operand_subword (operands[0], 0, 0, DImode);
1877 operands[3] = operand_subword (operands[0], 1, 0, DImode);
1878 operands[4] = operand_subword (operands[1], 0, 0, DImode);
1879 operands[5] = operand_subword (operands[1], 1, 0, DImode);
1880 })
1881
1882 (define_split
1883 [(set (match_operand:DI 0 "nonimmediate_operand" "")
1884 (match_operand:DI 1 "general_operand" ""))]
1885 "!TARGET_ZARCH && reload_completed
1886 && !s_operand (operands[0], DImode)
1887 && !s_operand (operands[1], DImode)
1888 && s390_split_ok_p (operands[0], operands[1], DImode, 1)"
1889 [(set (match_dup 2) (match_dup 4))
1890 (set (match_dup 3) (match_dup 5))]
1891 {
1892 operands[2] = operand_subword (operands[0], 1, 0, DImode);
1893 operands[3] = operand_subword (operands[0], 0, 0, DImode);
1894 operands[4] = operand_subword (operands[1], 1, 0, DImode);
1895 operands[5] = operand_subword (operands[1], 0, 0, DImode);
1896 })
1897
1898 (define_split
1899 [(set (match_operand:DI 0 "register_operand" "")
1900 (match_operand:DI 1 "memory_operand" ""))]
1901 "!TARGET_ZARCH && reload_completed
1902 && !FP_REG_P (operands[0])
1903 && !s_operand (operands[1], VOIDmode)"
1904 [(set (match_dup 0) (match_dup 1))]
1905 {
1906 rtx addr = operand_subword (operands[0], 1, 0, DImode);
1907 s390_load_address (addr, XEXP (operands[1], 0));
1908 operands[1] = replace_equiv_address (operands[1], addr);
1909 })
1910
1911 (define_peephole2
1912 [(set (match_operand:DI 0 "register_operand" "")
1913 (mem:DI (match_operand 1 "address_operand" "")))]
1914 "TARGET_ZARCH
1915 && !FP_REG_P (operands[0])
1916 && GET_CODE (operands[1]) == SYMBOL_REF
1917 && CONSTANT_POOL_ADDRESS_P (operands[1])
1918 && get_pool_mode (operands[1]) == DImode
1919 && legitimate_reload_constant_p (get_pool_constant (operands[1]))"
1920 [(set (match_dup 0) (match_dup 2))]
1921 "operands[2] = get_pool_constant (operands[1]);")
1922
1923 (define_insn "*la_64"
1924 [(set (match_operand:DI 0 "register_operand" "=d,d")
1925 (match_operand:QI 1 "address_operand" "ZR,ZT"))]
1926 "TARGET_64BIT"
1927 "@
1928 la\t%0,%a1
1929 lay\t%0,%a1"
1930 [(set_attr "op_type" "RX,RXY")
1931 (set_attr "type" "la")
1932 (set_attr "cpu_facility" "*,longdisp")
1933 (set_attr "z10prop" "z10_fwd_A1,z10_fwd_A1")])
1934
1935 (define_peephole2
1936 [(parallel
1937 [(set (match_operand:DI 0 "register_operand" "")
1938 (match_operand:QI 1 "address_operand" ""))
1939 (clobber (reg:CC CC_REGNUM))])]
1940 "TARGET_64BIT
1941 && preferred_la_operand_p (operands[1], const0_rtx)"
1942 [(set (match_dup 0) (match_dup 1))]
1943 "")
1944
1945 (define_peephole2
1946 [(set (match_operand:DI 0 "register_operand" "")
1947 (match_operand:DI 1 "register_operand" ""))
1948 (parallel
1949 [(set (match_dup 0)
1950 (plus:DI (match_dup 0)
1951 (match_operand:DI 2 "nonmemory_operand" "")))
1952 (clobber (reg:CC CC_REGNUM))])]
1953 "TARGET_64BIT
1954 && !reg_overlap_mentioned_p (operands[0], operands[2])
1955 && preferred_la_operand_p (operands[1], operands[2])"
1956 [(set (match_dup 0) (plus:DI (match_dup 1) (match_dup 2)))]
1957 "")
1958
1959 ;
1960 ; movsi instruction pattern(s).
1961 ;
1962
1963 (define_expand "movsi"
1964 [(set (match_operand:SI 0 "general_operand" "")
1965 (match_operand:SI 1 "general_operand" ""))]
1966 ""
1967 {
1968 /* Handle symbolic constants. */
1969 if (!TARGET_64BIT
1970 && (SYMBOLIC_CONST (operands[1])
1971 || (GET_CODE (operands[1]) == PLUS
1972 && XEXP (operands[1], 0) == pic_offset_table_rtx
1973 && SYMBOLIC_CONST (XEXP(operands[1], 1)))))
1974 emit_symbolic_move (operands);
1975 })
1976
1977 (define_insn "*movsi_larl"
1978 [(set (match_operand:SI 0 "register_operand" "=d")
1979 (match_operand:SI 1 "larl_operand" "X"))]
1980 "!TARGET_64BIT && TARGET_CPU_ZARCH
1981 && !FP_REG_P (operands[0])"
1982 "larl\t%0,%1"
1983 [(set_attr "op_type" "RIL")
1984 (set_attr "type" "larl")
1985 (set_attr "z10prop" "z10_fwd_A1")])
1986
1987 (define_insn "*movsi_zarch"
1988 [(set (match_operand:SI 0 "nonimmediate_operand"
1989 "=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")
1990 (match_operand:SI 1 "general_operand"
1991 " 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"))]
1992 "TARGET_ZARCH"
1993 "@
1994 lhi\t%0,%h1
1995 llilh\t%0,%i1
1996 llill\t%0,%i1
1997 iilf\t%0,%o1
1998 lay\t%0,%a1
1999 lrl\t%0,%1
2000 lr\t%0,%1
2001 l\t%0,%1
2002 ly\t%0,%1
2003 st\t%1,%0
2004 sty\t%1,%0
2005 ldr\t%0,%1
2006 ler\t%0,%1
2007 lde\t%0,%1
2008 le\t%0,%1
2009 ley\t%0,%1
2010 ste\t%1,%0
2011 stey\t%1,%0
2012 ear\t%0,%1
2013 sar\t%0,%1
2014 stam\t%1,%1,%S0
2015 strl\t%1,%0
2016 mvhi\t%0,%1
2017 lam\t%0,%0,%S1
2018 vleif\t%v0,%h1,0
2019 vlr\t%v0,%v1
2020 vlvgf\t%v0,%1,0
2021 vlgvf\t%0,%v1,0
2022 vlef\t%v0,%1,0
2023 vstef\t%v1,%0,0"
2024 [(set_attr "op_type" "RI,RI,RI,RIL,RXY,RIL,RR,RX,RXY,RX,RXY,
2025 RR,RR,RXE,RX,RXY,RX,RXY,RRE,RRE,RS,RIL,SIL,RS,VRI,VRR,VRS,VRS,VRX,VRX")
2026 (set_attr "type" "*,
2027 *,
2028 *,
2029 *,
2030 la,
2031 larl,
2032 lr,
2033 load,
2034 load,
2035 store,
2036 store,
2037 floadsf,
2038 floadsf,
2039 floadsf,
2040 floadsf,
2041 floadsf,
2042 fstoresf,
2043 fstoresf,
2044 *,
2045 *,
2046 *,
2047 larl,
2048 *,
2049 *,*,*,*,*,*,*")
2050 (set_attr "cpu_facility" "*,*,*,extimm,longdisp,z10,*,*,longdisp,*,longdisp,
2051 vx,*,vx,*,longdisp,*,longdisp,*,*,*,z10,z10,*,vx,vx,vx,vx,vx,vx")
2052 (set_attr "z10prop" "z10_fwd_A1,
2053 z10_fwd_E1,
2054 z10_fwd_E1,
2055 z10_fwd_A1,
2056 z10_fwd_A1,
2057 z10_fwd_A3,
2058 z10_fr_E1,
2059 z10_fwd_A3,
2060 z10_fwd_A3,
2061 z10_rec,
2062 z10_rec,
2063 *,
2064 *,
2065 *,
2066 *,
2067 *,
2068 *,
2069 *,
2070 z10_super_E1,
2071 z10_super,
2072 *,
2073 z10_rec,
2074 z10_super,
2075 *,*,*,*,*,*,*")])
2076
2077 (define_insn "*movsi_esa"
2078 [(set (match_operand:SI 0 "nonimmediate_operand" "=d,d,d,R,!*f,!*f,!*f,!*f,!R,d,t,Q,t")
2079 (match_operand:SI 1 "general_operand" "K,d,R,d, *f, *f, R, R,*f,t,d,t,Q"))]
2080 "!TARGET_ZARCH"
2081 "@
2082 lhi\t%0,%h1
2083 lr\t%0,%1
2084 l\t%0,%1
2085 st\t%1,%0
2086 ldr\t%0,%1
2087 ler\t%0,%1
2088 lde\t%0,%1
2089 le\t%0,%1
2090 ste\t%1,%0
2091 ear\t%0,%1
2092 sar\t%0,%1
2093 stam\t%1,%1,%S0
2094 lam\t%0,%0,%S1"
2095 [(set_attr "op_type" "RI,RR,RX,RX,RR,RR,RXE,RX,RX,RRE,RRE,RS,RS")
2096 (set_attr "type" "*,lr,load,store,floadsf,floadsf,floadsf,floadsf,fstoresf,*,*,*,*")
2097 (set_attr "z10prop" "z10_fwd_A1,z10_fr_E1,z10_fwd_A3,z10_rec,*,*,*,*,*,z10_super_E1,
2098 z10_super,*,*")
2099 (set_attr "cpu_facility" "*,*,*,*,vx,*,vx,*,*,*,*,*,*")
2100 ])
2101
2102 (define_peephole2
2103 [(set (match_operand:SI 0 "register_operand" "")
2104 (mem:SI (match_operand 1 "address_operand" "")))]
2105 "!FP_REG_P (operands[0])
2106 && GET_CODE (operands[1]) == SYMBOL_REF
2107 && CONSTANT_POOL_ADDRESS_P (operands[1])
2108 && get_pool_mode (operands[1]) == SImode
2109 && legitimate_reload_constant_p (get_pool_constant (operands[1]))"
2110 [(set (match_dup 0) (match_dup 2))]
2111 "operands[2] = get_pool_constant (operands[1]);")
2112
2113 (define_insn "*la_31"
2114 [(set (match_operand:SI 0 "register_operand" "=d,d")
2115 (match_operand:QI 1 "address_operand" "ZR,ZT"))]
2116 "!TARGET_64BIT && legitimate_la_operand_p (operands[1])"
2117 "@
2118 la\t%0,%a1
2119 lay\t%0,%a1"
2120 [(set_attr "op_type" "RX,RXY")
2121 (set_attr "type" "la")
2122 (set_attr "cpu_facility" "*,longdisp")
2123 (set_attr "z10prop" "z10_fwd_A1,z10_fwd_A1")])
2124
2125 (define_peephole2
2126 [(parallel
2127 [(set (match_operand:SI 0 "register_operand" "")
2128 (match_operand:QI 1 "address_operand" ""))
2129 (clobber (reg:CC CC_REGNUM))])]
2130 "!TARGET_64BIT
2131 && preferred_la_operand_p (operands[1], const0_rtx)"
2132 [(set (match_dup 0) (match_dup 1))]
2133 "")
2134
2135 (define_peephole2
2136 [(set (match_operand:SI 0 "register_operand" "")
2137 (match_operand:SI 1 "register_operand" ""))
2138 (parallel
2139 [(set (match_dup 0)
2140 (plus:SI (match_dup 0)
2141 (match_operand:SI 2 "nonmemory_operand" "")))
2142 (clobber (reg:CC CC_REGNUM))])]
2143 "!TARGET_64BIT
2144 && !reg_overlap_mentioned_p (operands[0], operands[2])
2145 && preferred_la_operand_p (operands[1], operands[2])"
2146 [(set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))]
2147 "")
2148
2149 (define_insn "*la_31_and"
2150 [(set (match_operand:SI 0 "register_operand" "=d,d")
2151 (and:SI (match_operand:QI 1 "address_operand" "ZR,ZT")
2152 (const_int 2147483647)))]
2153 "!TARGET_64BIT"
2154 "@
2155 la\t%0,%a1
2156 lay\t%0,%a1"
2157 [(set_attr "op_type" "RX,RXY")
2158 (set_attr "type" "la")
2159 (set_attr "cpu_facility" "*,longdisp")
2160 (set_attr "z10prop" "z10_fwd_A1,z10_fwd_A1")])
2161
2162 (define_insn_and_split "*la_31_and_cc"
2163 [(set (match_operand:SI 0 "register_operand" "=d")
2164 (and:SI (match_operand:QI 1 "address_operand" "p")
2165 (const_int 2147483647)))
2166 (clobber (reg:CC CC_REGNUM))]
2167 "!TARGET_64BIT"
2168 "#"
2169 "&& reload_completed"
2170 [(set (match_dup 0)
2171 (and:SI (match_dup 1) (const_int 2147483647)))]
2172 ""
2173 [(set_attr "op_type" "RX")
2174 (set_attr "type" "la")])
2175
2176 (define_insn "force_la_31"
2177 [(set (match_operand:SI 0 "register_operand" "=d,d")
2178 (match_operand:QI 1 "address_operand" "ZR,ZT"))
2179 (use (const_int 0))]
2180 "!TARGET_64BIT"
2181 "@
2182 la\t%0,%a1
2183 lay\t%0,%a1"
2184 [(set_attr "op_type" "RX")
2185 (set_attr "type" "la")
2186 (set_attr "cpu_facility" "*,longdisp")
2187 (set_attr "z10prop" "z10_fwd_A1,z10_fwd_A1")])
2188
2189 ;
2190 ; movhi instruction pattern(s).
2191 ;
2192
2193 (define_expand "movhi"
2194 [(set (match_operand:HI 0 "nonimmediate_operand" "")
2195 (match_operand:HI 1 "general_operand" ""))]
2196 ""
2197 {
2198 /* Make it explicit that loading a register from memory
2199 always sign-extends (at least) to SImode. */
2200 if (optimize && can_create_pseudo_p ()
2201 && register_operand (operands[0], VOIDmode)
2202 && GET_CODE (operands[1]) == MEM)
2203 {
2204 rtx tmp = gen_reg_rtx (SImode);
2205 rtx ext = gen_rtx_SIGN_EXTEND (SImode, operands[1]);
2206 emit_insn (gen_rtx_SET (tmp, ext));
2207 operands[1] = gen_lowpart (HImode, tmp);
2208 }
2209 })
2210
2211 (define_insn "*movhi"
2212 [(set (match_operand:HI 0 "nonimmediate_operand" "=d,d,d,d,d,R,T,b,Q,v,v,v,d,v,R")
2213 (match_operand:HI 1 "general_operand" " d,n,R,T,b,d,d,d,K,K,v,d,v,R,v"))]
2214 ""
2215 "@
2216 lr\t%0,%1
2217 lhi\t%0,%h1
2218 lh\t%0,%1
2219 lhy\t%0,%1
2220 lhrl\t%0,%1
2221 sth\t%1,%0
2222 sthy\t%1,%0
2223 sthrl\t%1,%0
2224 mvhhi\t%0,%1
2225 vleih\t%v0,%h1,0
2226 vlr\t%v0,%v1
2227 vlvgh\t%v0,%1,0
2228 vlgvh\t%0,%v1,0
2229 vleh\t%v0,%1,0
2230 vsteh\t%v1,%0,0"
2231 [(set_attr "op_type" "RR,RI,RX,RXY,RIL,RX,RXY,RIL,SIL,VRI,VRR,VRS,VRS,VRX,VRX")
2232 (set_attr "type" "lr,*,*,*,larl,store,store,store,*,*,*,*,*,*,*")
2233 (set_attr "cpu_facility" "*,*,*,longdisp,z10,*,longdisp,z10,z10,vx,vx,vx,vx,vx,vx")
2234 (set_attr "z10prop" "z10_fr_E1,
2235 z10_fwd_A1,
2236 z10_super_E1,
2237 z10_super_E1,
2238 z10_super_E1,
2239 z10_rec,
2240 z10_rec,
2241 z10_rec,
2242 z10_super,*,*,*,*,*,*")])
2243
2244 (define_peephole2
2245 [(set (match_operand:HI 0 "register_operand" "")
2246 (mem:HI (match_operand 1 "address_operand" "")))]
2247 "GET_CODE (operands[1]) == SYMBOL_REF
2248 && CONSTANT_POOL_ADDRESS_P (operands[1])
2249 && get_pool_mode (operands[1]) == HImode
2250 && GET_CODE (get_pool_constant (operands[1])) == CONST_INT"
2251 [(set (match_dup 0) (match_dup 2))]
2252 "operands[2] = get_pool_constant (operands[1]);")
2253
2254 ;
2255 ; movqi instruction pattern(s).
2256 ;
2257
2258 (define_expand "movqi"
2259 [(set (match_operand:QI 0 "nonimmediate_operand" "")
2260 (match_operand:QI 1 "general_operand" ""))]
2261 ""
2262 {
2263 /* On z/Architecture, zero-extending from memory to register
2264 is just as fast as a QImode load. */
2265 if (TARGET_ZARCH && optimize && can_create_pseudo_p ()
2266 && register_operand (operands[0], VOIDmode)
2267 && GET_CODE (operands[1]) == MEM)
2268 {
2269 rtx tmp = gen_reg_rtx (DImode);
2270 rtx ext = gen_rtx_ZERO_EXTEND (DImode, operands[1]);
2271 emit_insn (gen_rtx_SET (tmp, ext));
2272 operands[1] = gen_lowpart (QImode, tmp);
2273 }
2274 })
2275
2276 (define_insn "*movqi"
2277 [(set (match_operand:QI 0 "nonimmediate_operand" "=d,d,d,d,R,T,Q,S,?Q,v,v,v,d,v,R")
2278 (match_operand:QI 1 "general_operand" " d,n,R,T,d,d,n,n,?Q,K,v,d,v,R,v"))]
2279 ""
2280 "@
2281 lr\t%0,%1
2282 lhi\t%0,%b1
2283 ic\t%0,%1
2284 icy\t%0,%1
2285 stc\t%1,%0
2286 stcy\t%1,%0
2287 mvi\t%S0,%b1
2288 mviy\t%S0,%b1
2289 #
2290 vleib\t%v0,%b1,0
2291 vlr\t%v0,%v1
2292 vlvgb\t%v0,%1,0
2293 vlgvb\t%0,%v1,0
2294 vleb\t%v0,%1,0
2295 vsteb\t%v1,%0,0"
2296 [(set_attr "op_type" "RR,RI,RX,RXY,RX,RXY,SI,SIY,SS,VRI,VRR,VRS,VRS,VRX,VRX")
2297 (set_attr "type" "lr,*,*,*,store,store,store,store,*,*,*,*,*,*,*")
2298 (set_attr "cpu_facility" "*,*,*,longdisp,*,longdisp,*,longdisp,*,vx,vx,vx,vx,vx,vx")
2299 (set_attr "z10prop" "z10_fr_E1,
2300 z10_fwd_A1,
2301 z10_super_E1,
2302 z10_super_E1,
2303 z10_rec,
2304 z10_rec,
2305 z10_super,
2306 z10_super,
2307 *,*,*,*,*,*,*")])
2308
2309 (define_peephole2
2310 [(set (match_operand:QI 0 "nonimmediate_operand" "")
2311 (mem:QI (match_operand 1 "address_operand" "")))]
2312 "GET_CODE (operands[1]) == SYMBOL_REF
2313 && CONSTANT_POOL_ADDRESS_P (operands[1])
2314 && get_pool_mode (operands[1]) == QImode
2315 && GET_CODE (get_pool_constant (operands[1])) == CONST_INT"
2316 [(set (match_dup 0) (match_dup 2))]
2317 "operands[2] = get_pool_constant (operands[1]);")
2318
2319 ;
2320 ; movstrictqi instruction pattern(s).
2321 ;
2322
2323 (define_insn "*movstrictqi"
2324 [(set (strict_low_part (match_operand:QI 0 "register_operand" "+d,d"))
2325 (match_operand:QI 1 "memory_operand" "R,T"))]
2326 ""
2327 "@
2328 ic\t%0,%1
2329 icy\t%0,%1"
2330 [(set_attr "op_type" "RX,RXY")
2331 (set_attr "cpu_facility" "*,longdisp")
2332 (set_attr "z10prop" "z10_super_E1,z10_super_E1")])
2333
2334 ;
2335 ; movstricthi instruction pattern(s).
2336 ;
2337
2338 (define_insn "*movstricthi"
2339 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+d,d"))
2340 (match_operand:HI 1 "memory_operand" "Q,S"))
2341 (clobber (reg:CC CC_REGNUM))]
2342 ""
2343 "@
2344 icm\t%0,3,%S1
2345 icmy\t%0,3,%S1"
2346 [(set_attr "op_type" "RS,RSY")
2347 (set_attr "cpu_facility" "*,longdisp")
2348 (set_attr "z10prop" "z10_super_E1,z10_super_E1")])
2349
2350 ;
2351 ; movstrictsi instruction pattern(s).
2352 ;
2353
2354 (define_insn "movstrictsi"
2355 [(set (strict_low_part (match_operand:SI 0 "register_operand" "+d,d,d,d"))
2356 (match_operand:SI 1 "general_operand" "d,R,T,t"))]
2357 "TARGET_ZARCH"
2358 "@
2359 lr\t%0,%1
2360 l\t%0,%1
2361 ly\t%0,%1
2362 ear\t%0,%1"
2363 [(set_attr "op_type" "RR,RX,RXY,RRE")
2364 (set_attr "type" "lr,load,load,*")
2365 (set_attr "cpu_facility" "*,*,longdisp,*")
2366 (set_attr "z10prop" "z10_fr_E1,z10_fwd_A3,z10_fwd_A3,z10_super_E1")])
2367
2368 ;
2369 ; mov(tf|td) instruction pattern(s).
2370 ;
2371
2372 (define_expand "mov<mode>"
2373 [(set (match_operand:TD_TF 0 "nonimmediate_operand" "")
2374 (match_operand:TD_TF 1 "general_operand" ""))]
2375 ""
2376 "")
2377
2378 (define_insn "*mov<mode>_64"
2379 [(set (match_operand:TD_TF 0 "nonimmediate_operand" "=f,f,f,o,d,S, d,o")
2380 (match_operand:TD_TF 1 "general_operand" " G,f,o,f,S,d,dT,d"))]
2381 "TARGET_ZARCH"
2382 "@
2383 lzxr\t%0
2384 lxr\t%0,%1
2385 #
2386 #
2387 lmg\t%0,%N0,%S1
2388 stmg\t%1,%N1,%S0
2389 #
2390 #"
2391 [(set_attr "op_type" "RRE,RRE,*,*,RSY,RSY,*,*")
2392 (set_attr "type" "fsimptf,fsimptf,*,*,lm,stm,*,*")
2393 (set_attr "cpu_facility" "z196,*,*,*,*,*,*,*")])
2394
2395 (define_insn "*mov<mode>_31"
2396 [(set (match_operand:TD_TF 0 "nonimmediate_operand" "=f,f,f,o")
2397 (match_operand:TD_TF 1 "general_operand" " G,f,o,f"))]
2398 "!TARGET_ZARCH"
2399 "@
2400 lzxr\t%0
2401 lxr\t%0,%1
2402 #
2403 #"
2404 [(set_attr "op_type" "RRE,RRE,*,*")
2405 (set_attr "type" "fsimptf,fsimptf,*,*")
2406 (set_attr "cpu_facility" "z196,*,*,*")])
2407
2408 ; TFmode in GPRs splitters
2409
2410 (define_split
2411 [(set (match_operand:TD_TF 0 "nonimmediate_operand" "")
2412 (match_operand:TD_TF 1 "general_operand" ""))]
2413 "TARGET_ZARCH && reload_completed
2414 && !s_operand (operands[0], <MODE>mode)
2415 && !s_operand (operands[1], <MODE>mode)
2416 && s390_split_ok_p (operands[0], operands[1], <MODE>mode, 0)"
2417 [(set (match_dup 2) (match_dup 4))
2418 (set (match_dup 3) (match_dup 5))]
2419 {
2420 operands[2] = operand_subword (operands[0], 0, 0, <MODE>mode);
2421 operands[3] = operand_subword (operands[0], 1, 0, <MODE>mode);
2422 operands[4] = operand_subword (operands[1], 0, 0, <MODE>mode);
2423 operands[5] = operand_subword (operands[1], 1, 0, <MODE>mode);
2424 })
2425
2426 (define_split
2427 [(set (match_operand:TD_TF 0 "nonimmediate_operand" "")
2428 (match_operand:TD_TF 1 "general_operand" ""))]
2429 "TARGET_ZARCH && reload_completed
2430 && !s_operand (operands[0], <MODE>mode)
2431 && !s_operand (operands[1], <MODE>mode)
2432 && s390_split_ok_p (operands[0], operands[1], <MODE>mode, 1)"
2433 [(set (match_dup 2) (match_dup 4))
2434 (set (match_dup 3) (match_dup 5))]
2435 {
2436 operands[2] = operand_subword (operands[0], 1, 0, <MODE>mode);
2437 operands[3] = operand_subword (operands[0], 0, 0, <MODE>mode);
2438 operands[4] = operand_subword (operands[1], 1, 0, <MODE>mode);
2439 operands[5] = operand_subword (operands[1], 0, 0, <MODE>mode);
2440 })
2441
2442 (define_split
2443 [(set (match_operand:TD_TF 0 "register_operand" "")
2444 (match_operand:TD_TF 1 "memory_operand" ""))]
2445 "TARGET_ZARCH && reload_completed
2446 && GENERAL_REG_P (operands[0])
2447 && !s_operand (operands[1], VOIDmode)"
2448 [(set (match_dup 0) (match_dup 1))]
2449 {
2450 rtx addr = operand_subword (operands[0], 1, 0, <MODE>mode);
2451 addr = gen_lowpart (Pmode, addr);
2452 s390_load_address (addr, XEXP (operands[1], 0));
2453 operands[1] = replace_equiv_address (operands[1], addr);
2454 })
2455
2456 ; TFmode in BFPs splitters
2457
2458 (define_split
2459 [(set (match_operand:TD_TF 0 "register_operand" "")
2460 (match_operand:TD_TF 1 "memory_operand" ""))]
2461 "reload_completed && offsettable_memref_p (operands[1])
2462 && FP_REG_P (operands[0])"
2463 [(set (match_dup 2) (match_dup 4))
2464 (set (match_dup 3) (match_dup 5))]
2465 {
2466 operands[2] = simplify_gen_subreg (<HALF_TMODE>mode, operands[0],
2467 <MODE>mode, 0);
2468 operands[3] = simplify_gen_subreg (<HALF_TMODE>mode, operands[0],
2469 <MODE>mode, 8);
2470 operands[4] = adjust_address_nv (operands[1], <HALF_TMODE>mode, 0);
2471 operands[5] = adjust_address_nv (operands[1], <HALF_TMODE>mode, 8);
2472 })
2473
2474 (define_split
2475 [(set (match_operand:TD_TF 0 "memory_operand" "")
2476 (match_operand:TD_TF 1 "register_operand" ""))]
2477 "reload_completed && offsettable_memref_p (operands[0])
2478 && FP_REG_P (operands[1])"
2479 [(set (match_dup 2) (match_dup 4))
2480 (set (match_dup 3) (match_dup 5))]
2481 {
2482 operands[2] = adjust_address_nv (operands[0], <HALF_TMODE>mode, 0);
2483 operands[3] = adjust_address_nv (operands[0], <HALF_TMODE>mode, 8);
2484 operands[4] = simplify_gen_subreg (<HALF_TMODE>mode, operands[1],
2485 <MODE>mode, 0);
2486 operands[5] = simplify_gen_subreg (<HALF_TMODE>mode, operands[1],
2487 <MODE>mode, 8);
2488 })
2489
2490 ;
2491 ; mov(df|dd) instruction pattern(s).
2492 ;
2493
2494 (define_expand "mov<mode>"
2495 [(set (match_operand:DD_DF 0 "nonimmediate_operand" "")
2496 (match_operand:DD_DF 1 "general_operand" ""))]
2497 ""
2498 "")
2499
2500 (define_insn "*mov<mode>_64dfp"
2501 [(set (match_operand:DD_DF 0 "nonimmediate_operand"
2502 "=f,f,f,d,f,f,R,T,d,d,d,d,b,T,v,v,v,d,v,R")
2503 (match_operand:DD_DF 1 "general_operand"
2504 " G,f,d,f,R,T,f,f,G,d,b,T,d,d,v,G,d,v,R,v"))]
2505 "TARGET_DFP"
2506 "@
2507 lzdr\t%0
2508 ldr\t%0,%1
2509 ldgr\t%0,%1
2510 lgdr\t%0,%1
2511 ld\t%0,%1
2512 ldy\t%0,%1
2513 std\t%1,%0
2514 stdy\t%1,%0
2515 lghi\t%0,0
2516 lgr\t%0,%1
2517 lgrl\t%0,%1
2518 lg\t%0,%1
2519 stgrl\t%1,%0
2520 stg\t%1,%0
2521 vlr\t%v0,%v1
2522 vleig\t%v0,0,0
2523 vlvgg\t%v0,%1,0
2524 vlgvg\t%0,%v1,0
2525 vleg\t%0,%1,0
2526 vsteg\t%1,%0,0"
2527 [(set_attr "op_type" "RRE,RR,RRE,RRE,RX,RXY,RX,RXY,RI,RRE,RIL,RXY,RIL,RXY,VRR,VRI,VRS,VRS,VRX,VRX")
2528 (set_attr "type" "fsimpdf,floaddf,floaddf,floaddf,floaddf,floaddf,
2529 fstoredf,fstoredf,*,lr,load,load,store,store,*,*,*,*,load,store")
2530 (set_attr "z10prop" "*,*,*,*,*,*,*,*,z10_fwd_A1,z10_fr_E1,z10_fwd_A3,z10_fwd_A3,z10_rec,z10_rec,*,*,*,*,*,*")
2531 (set_attr "cpu_facility" "z196,*,*,*,*,longdisp,*,longdisp,*,*,z10,*,z10,*,vx,vx,vx,vx,vx,vx")])
2532
2533 (define_insn "*mov<mode>_64"
2534 [(set (match_operand:DD_DF 0 "nonimmediate_operand" "=f,f,f,f,R,T,d,d,d,d,b,T")
2535 (match_operand:DD_DF 1 "general_operand" " G,f,R,T,f,f,G,d,b,T,d,d"))]
2536 "TARGET_ZARCH"
2537 "@
2538 lzdr\t%0
2539 ldr\t%0,%1
2540 ld\t%0,%1
2541 ldy\t%0,%1
2542 std\t%1,%0
2543 stdy\t%1,%0
2544 lghi\t%0,0
2545 lgr\t%0,%1
2546 lgrl\t%0,%1
2547 lg\t%0,%1
2548 stgrl\t%1,%0
2549 stg\t%1,%0"
2550 [(set_attr "op_type" "RRE,RR,RX,RXY,RX,RXY,RI,RRE,RIL,RXY,RIL,RXY")
2551 (set_attr "type" "fsimpdf,fload<mode>,fload<mode>,fload<mode>,
2552 fstore<mode>,fstore<mode>,*,lr,load,load,store,store")
2553 (set_attr "z10prop" "*,*,*,*,*,*,z10_fwd_A1,z10_fr_E1,z10_fwd_A3,z10_fwd_A3,z10_rec,z10_rec")
2554 (set_attr "cpu_facility" "z196,*,*,longdisp,*,longdisp,*,*,z10,*,z10,*")])
2555
2556 (define_insn "*mov<mode>_31"
2557 [(set (match_operand:DD_DF 0 "nonimmediate_operand"
2558 "=f,f,f,f,R,T,d,d,Q,S, d,o")
2559 (match_operand:DD_DF 1 "general_operand"
2560 " G,f,R,T,f,f,Q,S,d,d,dPT,d"))]
2561 "!TARGET_ZARCH"
2562 "@
2563 lzdr\t%0
2564 ldr\t%0,%1
2565 ld\t%0,%1
2566 ldy\t%0,%1
2567 std\t%1,%0
2568 stdy\t%1,%0
2569 lm\t%0,%N0,%S1
2570 lmy\t%0,%N0,%S1
2571 stm\t%1,%N1,%S0
2572 stmy\t%1,%N1,%S0
2573 #
2574 #"
2575 [(set_attr "op_type" "RRE,RR,RX,RXY,RX,RXY,RS,RSY,RS,RSY,*,*")
2576 (set_attr "type" "fsimpdf,fload<mode>,fload<mode>,fload<mode>,
2577 fstore<mode>,fstore<mode>,lm,lm,stm,stm,*,*")
2578 (set_attr "cpu_facility" "z196,*,*,longdisp,*,longdisp,*,longdisp,*,longdisp,*,*")])
2579
2580 (define_split
2581 [(set (match_operand:DD_DF 0 "nonimmediate_operand" "")
2582 (match_operand:DD_DF 1 "general_operand" ""))]
2583 "!TARGET_ZARCH && reload_completed
2584 && !s_operand (operands[0], <MODE>mode)
2585 && !s_operand (operands[1], <MODE>mode)
2586 && s390_split_ok_p (operands[0], operands[1], <MODE>mode, 0)"
2587 [(set (match_dup 2) (match_dup 4))
2588 (set (match_dup 3) (match_dup 5))]
2589 {
2590 operands[2] = operand_subword (operands[0], 0, 0, <MODE>mode);
2591 operands[3] = operand_subword (operands[0], 1, 0, <MODE>mode);
2592 operands[4] = operand_subword (operands[1], 0, 0, <MODE>mode);
2593 operands[5] = operand_subword (operands[1], 1, 0, <MODE>mode);
2594 })
2595
2596 (define_split
2597 [(set (match_operand:DD_DF 0 "nonimmediate_operand" "")
2598 (match_operand:DD_DF 1 "general_operand" ""))]
2599 "!TARGET_ZARCH && reload_completed
2600 && !s_operand (operands[0], <MODE>mode)
2601 && !s_operand (operands[1], <MODE>mode)
2602 && s390_split_ok_p (operands[0], operands[1], <MODE>mode, 1)"
2603 [(set (match_dup 2) (match_dup 4))
2604 (set (match_dup 3) (match_dup 5))]
2605 {
2606 operands[2] = operand_subword (operands[0], 1, 0, <MODE>mode);
2607 operands[3] = operand_subword (operands[0], 0, 0, <MODE>mode);
2608 operands[4] = operand_subword (operands[1], 1, 0, <MODE>mode);
2609 operands[5] = operand_subword (operands[1], 0, 0, <MODE>mode);
2610 })
2611
2612 (define_split
2613 [(set (match_operand:DD_DF 0 "register_operand" "")
2614 (match_operand:DD_DF 1 "memory_operand" ""))]
2615 "!TARGET_ZARCH && reload_completed
2616 && !FP_REG_P (operands[0])
2617 && !s_operand (operands[1], VOIDmode)"
2618 [(set (match_dup 0) (match_dup 1))]
2619 {
2620 rtx addr = operand_subword (operands[0], 1, 0, <MODE>mode);
2621 s390_load_address (addr, XEXP (operands[1], 0));
2622 operands[1] = replace_equiv_address (operands[1], addr);
2623 })
2624
2625 ;
2626 ; mov(sf|sd) instruction pattern(s).
2627 ;
2628
2629 (define_insn "mov<mode>"
2630 [(set (match_operand:SD_SF 0 "nonimmediate_operand"
2631 "=f,f,f,f,f,f,R,T,d,d,d,d,d,b,R,T,v,v,v,d,v,R")
2632 (match_operand:SD_SF 1 "general_operand"
2633 " G,f,f,R,R,T,f,f,G,d,b,R,T,d,d,d,v,G,d,v,R,v"))]
2634 ""
2635 "@
2636 lzer\t%0
2637 ldr\t%0,%1
2638 ler\t%0,%1
2639 lde\t%0,%1
2640 le\t%0,%1
2641 ley\t%0,%1
2642 ste\t%1,%0
2643 stey\t%1,%0
2644 lhi\t%0,0
2645 lr\t%0,%1
2646 lrl\t%0,%1
2647 l\t%0,%1
2648 ly\t%0,%1
2649 strl\t%1,%0
2650 st\t%1,%0
2651 sty\t%1,%0
2652 vlr\t%v0,%v1
2653 vleif\t%v0,0,0
2654 vlvgf\t%v0,%1,0
2655 vlgvf\t%0,%v1,0
2656 vlef\t%0,%1,0
2657 vstef\t%1,%0,0"
2658 [(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")
2659 (set_attr "type" "fsimpsf,fsimpsf,fload<mode>,fload<mode>,fload<mode>,fload<mode>,
2660 fstore<mode>,fstore<mode>,*,lr,load,load,load,store,store,store,*,*,*,*,load,store")
2661 (set_attr "z10prop" "*,*,*,*,*,*,*,*,z10_fwd_A1,z10_fr_E1,z10_fr_E1,z10_fwd_A3,z10_fwd_A3,z10_rec,z10_rec,z10_rec,*,*,*,*,*,*")
2662 (set_attr "cpu_facility" "z196,vx,*,vx,*,longdisp,*,longdisp,*,*,z10,*,longdisp,z10,*,longdisp,vx,vx,vx,vx,vx,vx")])
2663
2664 ;
2665 ; movcc instruction pattern
2666 ;
2667
2668 (define_insn "movcc"
2669 [(set (match_operand:CC 0 "nonimmediate_operand" "=d,c,d,d,d,R,T")
2670 (match_operand:CC 1 "nonimmediate_operand" " d,d,c,R,T,d,d"))]
2671 ""
2672 "@
2673 lr\t%0,%1
2674 tmh\t%1,12288
2675 ipm\t%0
2676 l\t%0,%1
2677 ly\t%0,%1
2678 st\t%1,%0
2679 sty\t%1,%0"
2680 [(set_attr "op_type" "RR,RI,RRE,RX,RXY,RX,RXY")
2681 (set_attr "type" "lr,*,*,load,load,store,store")
2682 (set_attr "cpu_facility" "*,*,*,*,longdisp,*,longdisp")
2683 (set_attr "z10prop" "z10_fr_E1,z10_super,*,z10_fwd_A3,z10_fwd_A3,z10_rec,z10_rec")
2684 (set_attr "z196prop" "*,*,z196_ends,*,*,*,*")])
2685
2686 ;
2687 ; Block move (MVC) patterns.
2688 ;
2689
2690 (define_insn "*mvc"
2691 [(set (match_operand:BLK 0 "memory_operand" "=Q")
2692 (match_operand:BLK 1 "memory_operand" "Q"))
2693 (use (match_operand 2 "const_int_operand" "n"))]
2694 "INTVAL (operands[2]) >= 1 && INTVAL (operands[2]) <= 256"
2695 "mvc\t%O0(%2,%R0),%S1"
2696 [(set_attr "op_type" "SS")])
2697
2698 ; This splitter converts a QI to QI mode copy into a BLK mode copy in
2699 ; order to have it implemented with mvc.
2700
2701 (define_split
2702 [(set (match_operand:QI 0 "memory_operand" "")
2703 (match_operand:QI 1 "memory_operand" ""))]
2704 "reload_completed"
2705 [(parallel
2706 [(set (match_dup 0) (match_dup 1))
2707 (use (const_int 1))])]
2708 {
2709 operands[0] = adjust_address (operands[0], BLKmode, 0);
2710 operands[1] = adjust_address (operands[1], BLKmode, 0);
2711 })
2712
2713
2714 (define_peephole2
2715 [(parallel
2716 [(set (match_operand:BLK 0 "memory_operand" "")
2717 (match_operand:BLK 1 "memory_operand" ""))
2718 (use (match_operand 2 "const_int_operand" ""))])
2719 (parallel
2720 [(set (match_operand:BLK 3 "memory_operand" "")
2721 (match_operand:BLK 4 "memory_operand" ""))
2722 (use (match_operand 5 "const_int_operand" ""))])]
2723 "s390_offset_p (operands[0], operands[3], operands[2])
2724 && s390_offset_p (operands[1], operands[4], operands[2])
2725 && !s390_overlap_p (operands[0], operands[1],
2726 INTVAL (operands[2]) + INTVAL (operands[5]))
2727 && INTVAL (operands[2]) + INTVAL (operands[5]) <= 256"
2728 [(parallel
2729 [(set (match_dup 6) (match_dup 7))
2730 (use (match_dup 8))])]
2731 "operands[6] = gen_rtx_MEM (BLKmode, XEXP (operands[0], 0));
2732 operands[7] = gen_rtx_MEM (BLKmode, XEXP (operands[1], 0));
2733 operands[8] = GEN_INT (INTVAL (operands[2]) + INTVAL (operands[5]));")
2734
2735
2736 ;
2737 ; load_multiple pattern(s).
2738 ;
2739 ; ??? Due to reload problems with replacing registers inside match_parallel
2740 ; we currently support load_multiple/store_multiple only after reload.
2741 ;
2742
2743 (define_expand "load_multiple"
2744 [(match_par_dup 3 [(set (match_operand 0 "" "")
2745 (match_operand 1 "" ""))
2746 (use (match_operand 2 "" ""))])]
2747 "reload_completed"
2748 {
2749 machine_mode mode;
2750 int regno;
2751 int count;
2752 rtx from;
2753 int i, off;
2754
2755 /* Support only loading a constant number of fixed-point registers from
2756 memory and only bother with this if more than two */
2757 if (GET_CODE (operands[2]) != CONST_INT
2758 || INTVAL (operands[2]) < 2
2759 || INTVAL (operands[2]) > 16
2760 || GET_CODE (operands[1]) != MEM
2761 || GET_CODE (operands[0]) != REG
2762 || REGNO (operands[0]) >= 16)
2763 FAIL;
2764
2765 count = INTVAL (operands[2]);
2766 regno = REGNO (operands[0]);
2767 mode = GET_MODE (operands[0]);
2768 if (mode != SImode && (!TARGET_ZARCH || mode != DImode))
2769 FAIL;
2770
2771 operands[3] = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (count));
2772 if (!can_create_pseudo_p ())
2773 {
2774 if (GET_CODE (XEXP (operands[1], 0)) == REG)
2775 {
2776 from = XEXP (operands[1], 0);
2777 off = 0;
2778 }
2779 else if (GET_CODE (XEXP (operands[1], 0)) == PLUS
2780 && GET_CODE (XEXP (XEXP (operands[1], 0), 0)) == REG
2781 && GET_CODE (XEXP (XEXP (operands[1], 0), 1)) == CONST_INT)
2782 {
2783 from = XEXP (XEXP (operands[1], 0), 0);
2784 off = INTVAL (XEXP (XEXP (operands[1], 0), 1));
2785 }
2786 else
2787 FAIL;
2788 }
2789 else
2790 {
2791 from = force_reg (Pmode, XEXP (operands[1], 0));
2792 off = 0;
2793 }
2794
2795 for (i = 0; i < count; i++)
2796 XVECEXP (operands[3], 0, i)
2797 = gen_rtx_SET (gen_rtx_REG (mode, regno + i),
2798 change_address (operands[1], mode,
2799 plus_constant (Pmode, from,
2800 off + i * GET_MODE_SIZE (mode))));
2801 })
2802
2803 (define_insn "*load_multiple_di"
2804 [(match_parallel 0 "load_multiple_operation"
2805 [(set (match_operand:DI 1 "register_operand" "=r")
2806 (match_operand:DI 2 "s_operand" "S"))])]
2807 "reload_completed && TARGET_ZARCH"
2808 {
2809 int words = XVECLEN (operands[0], 0);
2810 operands[0] = gen_rtx_REG (DImode, REGNO (operands[1]) + words - 1);
2811 return "lmg\t%1,%0,%S2";
2812 }
2813 [(set_attr "op_type" "RSY")
2814 (set_attr "type" "lm")])
2815
2816 (define_insn "*load_multiple_si"
2817 [(match_parallel 0 "load_multiple_operation"
2818 [(set (match_operand:SI 1 "register_operand" "=r,r")
2819 (match_operand:SI 2 "s_operand" "Q,S"))])]
2820 "reload_completed"
2821 {
2822 int words = XVECLEN (operands[0], 0);
2823 operands[0] = gen_rtx_REG (SImode, REGNO (operands[1]) + words - 1);
2824 return which_alternative == 0 ? "lm\t%1,%0,%S2" : "lmy\t%1,%0,%S2";
2825 }
2826 [(set_attr "op_type" "RS,RSY")
2827 (set_attr "cpu_facility" "*,longdisp")
2828 (set_attr "type" "lm")])
2829
2830 ;
2831 ; store multiple pattern(s).
2832 ;
2833
2834 (define_expand "store_multiple"
2835 [(match_par_dup 3 [(set (match_operand 0 "" "")
2836 (match_operand 1 "" ""))
2837 (use (match_operand 2 "" ""))])]
2838 "reload_completed"
2839 {
2840 machine_mode mode;
2841 int regno;
2842 int count;
2843 rtx to;
2844 int i, off;
2845
2846 /* Support only storing a constant number of fixed-point registers to
2847 memory and only bother with this if more than two. */
2848 if (GET_CODE (operands[2]) != CONST_INT
2849 || INTVAL (operands[2]) < 2
2850 || INTVAL (operands[2]) > 16
2851 || GET_CODE (operands[0]) != MEM
2852 || GET_CODE (operands[1]) != REG
2853 || REGNO (operands[1]) >= 16)
2854 FAIL;
2855
2856 count = INTVAL (operands[2]);
2857 regno = REGNO (operands[1]);
2858 mode = GET_MODE (operands[1]);
2859 if (mode != SImode && (!TARGET_ZARCH || mode != DImode))
2860 FAIL;
2861
2862 operands[3] = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (count));
2863
2864 if (!can_create_pseudo_p ())
2865 {
2866 if (GET_CODE (XEXP (operands[0], 0)) == REG)
2867 {
2868 to = XEXP (operands[0], 0);
2869 off = 0;
2870 }
2871 else if (GET_CODE (XEXP (operands[0], 0)) == PLUS
2872 && GET_CODE (XEXP (XEXP (operands[0], 0), 0)) == REG
2873 && GET_CODE (XEXP (XEXP (operands[0], 0), 1)) == CONST_INT)
2874 {
2875 to = XEXP (XEXP (operands[0], 0), 0);
2876 off = INTVAL (XEXP (XEXP (operands[0], 0), 1));
2877 }
2878 else
2879 FAIL;
2880 }
2881 else
2882 {
2883 to = force_reg (Pmode, XEXP (operands[0], 0));
2884 off = 0;
2885 }
2886
2887 for (i = 0; i < count; i++)
2888 XVECEXP (operands[3], 0, i)
2889 = gen_rtx_SET (change_address (operands[0], mode,
2890 plus_constant (Pmode, to,
2891 off + i * GET_MODE_SIZE (mode))),
2892 gen_rtx_REG (mode, regno + i));
2893 })
2894
2895 (define_insn "*store_multiple_di"
2896 [(match_parallel 0 "store_multiple_operation"
2897 [(set (match_operand:DI 1 "s_operand" "=S")
2898 (match_operand:DI 2 "register_operand" "r"))])]
2899 "reload_completed && TARGET_ZARCH"
2900 {
2901 int words = XVECLEN (operands[0], 0);
2902 operands[0] = gen_rtx_REG (DImode, REGNO (operands[2]) + words - 1);
2903 return "stmg\t%2,%0,%S1";
2904 }
2905 [(set_attr "op_type" "RSY")
2906 (set_attr "type" "stm")])
2907
2908
2909 (define_insn "*store_multiple_si"
2910 [(match_parallel 0 "store_multiple_operation"
2911 [(set (match_operand:SI 1 "s_operand" "=Q,S")
2912 (match_operand:SI 2 "register_operand" "r,r"))])]
2913 "reload_completed"
2914 {
2915 int words = XVECLEN (operands[0], 0);
2916 operands[0] = gen_rtx_REG (SImode, REGNO (operands[2]) + words - 1);
2917 return which_alternative == 0 ? "stm\t%2,%0,%S1" : "stmy\t%2,%0,%S1";
2918 }
2919 [(set_attr "op_type" "RS,RSY")
2920 (set_attr "cpu_facility" "*,longdisp")
2921 (set_attr "type" "stm")])
2922
2923 ;;
2924 ;; String instructions.
2925 ;;
2926
2927 (define_insn "*execute_rl"
2928 [(match_parallel 0 "execute_operation"
2929 [(unspec [(match_operand 1 "register_operand" "a")
2930 (match_operand 2 "" "")
2931 (match_operand:SI 3 "larl_operand" "X")] UNSPEC_EXECUTE)])]
2932 "TARGET_Z10 && GET_MODE_CLASS (GET_MODE (operands[1])) == MODE_INT
2933 && GET_MODE_SIZE (GET_MODE (operands[1])) <= UNITS_PER_WORD"
2934 "exrl\t%1,%3"
2935 [(set_attr "op_type" "RIL")
2936 (set_attr "type" "cs")])
2937
2938 (define_insn "*execute"
2939 [(match_parallel 0 "execute_operation"
2940 [(unspec [(match_operand 1 "register_operand" "a")
2941 (match_operand:BLK 2 "memory_operand" "R")
2942 (match_operand 3 "" "")] UNSPEC_EXECUTE)])]
2943 "GET_MODE_CLASS (GET_MODE (operands[1])) == MODE_INT
2944 && GET_MODE_SIZE (GET_MODE (operands[1])) <= UNITS_PER_WORD"
2945 "ex\t%1,%2"
2946 [(set_attr "op_type" "RX")
2947 (set_attr "type" "cs")])
2948
2949
2950 ;
2951 ; strlenM instruction pattern(s).
2952 ;
2953
2954 (define_expand "strlen<mode>"
2955 [(match_operand:P 0 "register_operand" "") ; result
2956 (match_operand:BLK 1 "memory_operand" "") ; input string
2957 (match_operand:SI 2 "immediate_operand" "") ; search character
2958 (match_operand:SI 3 "immediate_operand" "")] ; known alignment
2959 ""
2960 {
2961 if (!TARGET_VX || operands[2] != const0_rtx)
2962 emit_insn (gen_strlen_srst<mode> (operands[0], operands[1],
2963 operands[2], operands[3]));
2964 else
2965 s390_expand_vec_strlen (operands[0], operands[1], operands[3]);
2966
2967 DONE;
2968 })
2969
2970 (define_expand "strlen_srst<mode>"
2971 [(set (reg:SI 0) (match_operand:SI 2 "immediate_operand" ""))
2972 (parallel
2973 [(set (match_dup 4)
2974 (unspec:P [(const_int 0)
2975 (match_operand:BLK 1 "memory_operand" "")
2976 (reg:SI 0)
2977 (match_operand 3 "immediate_operand" "")] UNSPEC_SRST))
2978 (clobber (scratch:P))
2979 (clobber (reg:CC CC_REGNUM))])
2980 (parallel
2981 [(set (match_operand:P 0 "register_operand" "")
2982 (minus:P (match_dup 4) (match_dup 5)))
2983 (clobber (reg:CC CC_REGNUM))])]
2984 ""
2985 {
2986 operands[4] = gen_reg_rtx (Pmode);
2987 operands[5] = gen_reg_rtx (Pmode);
2988 emit_move_insn (operands[5], force_operand (XEXP (operands[1], 0), NULL_RTX));
2989 operands[1] = replace_equiv_address (operands[1], operands[5]);
2990 })
2991
2992 (define_insn "*strlen<mode>"
2993 [(set (match_operand:P 0 "register_operand" "=a")
2994 (unspec:P [(match_operand:P 2 "general_operand" "0")
2995 (mem:BLK (match_operand:P 3 "register_operand" "1"))
2996 (reg:SI 0)
2997 (match_operand 4 "immediate_operand" "")] UNSPEC_SRST))
2998 (clobber (match_scratch:P 1 "=a"))
2999 (clobber (reg:CC CC_REGNUM))]
3000 ""
3001 "srst\t%0,%1\;jo\t.-4"
3002 [(set_attr "length" "8")
3003 (set_attr "type" "vs")])
3004
3005 ;
3006 ; cmpstrM instruction pattern(s).
3007 ;
3008
3009 (define_expand "cmpstrsi"
3010 [(set (reg:SI 0) (const_int 0))
3011 (parallel
3012 [(clobber (match_operand 3 "" ""))
3013 (clobber (match_dup 4))
3014 (set (reg:CCU CC_REGNUM)
3015 (compare:CCU (match_operand:BLK 1 "memory_operand" "")
3016 (match_operand:BLK 2 "memory_operand" "")))
3017 (use (reg:SI 0))])
3018 (parallel
3019 [(set (match_operand:SI 0 "register_operand" "=d")
3020 (unspec:SI [(reg:CCU CC_REGNUM)] UNSPEC_STRCMPCC_TO_INT))
3021 (clobber (reg:CC CC_REGNUM))])]
3022 ""
3023 {
3024 /* As the result of CMPINT is inverted compared to what we need,
3025 we have to swap the operands. */
3026 rtx op1 = operands[2];
3027 rtx op2 = operands[1];
3028 rtx addr1 = gen_reg_rtx (Pmode);
3029 rtx addr2 = gen_reg_rtx (Pmode);
3030
3031 emit_move_insn (addr1, force_operand (XEXP (op1, 0), NULL_RTX));
3032 emit_move_insn (addr2, force_operand (XEXP (op2, 0), NULL_RTX));
3033 operands[1] = replace_equiv_address_nv (op1, addr1);
3034 operands[2] = replace_equiv_address_nv (op2, addr2);
3035 operands[3] = addr1;
3036 operands[4] = addr2;
3037 })
3038
3039 (define_insn "*cmpstr<mode>"
3040 [(clobber (match_operand:P 0 "register_operand" "=d"))
3041 (clobber (match_operand:P 1 "register_operand" "=d"))
3042 (set (reg:CCU CC_REGNUM)
3043 (compare:CCU (mem:BLK (match_operand:P 2 "register_operand" "0"))
3044 (mem:BLK (match_operand:P 3 "register_operand" "1"))))
3045 (use (reg:SI 0))]
3046 ""
3047 "clst\t%0,%1\;jo\t.-4"
3048 [(set_attr "length" "8")
3049 (set_attr "type" "vs")])
3050
3051 ;
3052 ; movstr instruction pattern.
3053 ;
3054
3055 (define_expand "movstr"
3056 [(match_operand 0 "register_operand" "")
3057 (match_operand 1 "memory_operand" "")
3058 (match_operand 2 "memory_operand" "")]
3059 ""
3060 {
3061 if (TARGET_64BIT)
3062 emit_insn (gen_movstrdi (operands[0], operands[1], operands[2]));
3063 else
3064 emit_insn (gen_movstrsi (operands[0], operands[1], operands[2]));
3065 DONE;
3066 })
3067
3068 (define_expand "movstr<P:mode>"
3069 [(set (reg:SI 0) (const_int 0))
3070 (parallel
3071 [(clobber (match_dup 3))
3072 (set (match_operand:BLK 1 "memory_operand" "")
3073 (match_operand:BLK 2 "memory_operand" ""))
3074 (set (match_operand:P 0 "register_operand" "")
3075 (unspec:P [(match_dup 1)
3076 (match_dup 2)
3077 (reg:SI 0)] UNSPEC_MVST))
3078 (clobber (reg:CC CC_REGNUM))])]
3079 ""
3080 {
3081 rtx addr1, addr2;
3082
3083 if (TARGET_VX && optimize_function_for_speed_p (cfun))
3084 {
3085 s390_expand_vec_movstr (operands[0], operands[1], operands[2]);
3086 DONE;
3087 }
3088
3089 addr1 = gen_reg_rtx (Pmode);
3090 addr2 = gen_reg_rtx (Pmode);
3091
3092 emit_move_insn (addr1, force_operand (XEXP (operands[1], 0), NULL_RTX));
3093 emit_move_insn (addr2, force_operand (XEXP (operands[2], 0), NULL_RTX));
3094 operands[1] = replace_equiv_address_nv (operands[1], addr1);
3095 operands[2] = replace_equiv_address_nv (operands[2], addr2);
3096 operands[3] = addr2;
3097 })
3098
3099 (define_insn "*movstr"
3100 [(clobber (match_operand:P 2 "register_operand" "=d"))
3101 (set (mem:BLK (match_operand:P 1 "register_operand" "0"))
3102 (mem:BLK (match_operand:P 3 "register_operand" "2")))
3103 (set (match_operand:P 0 "register_operand" "=d")
3104 (unspec:P [(mem:BLK (match_dup 1))
3105 (mem:BLK (match_dup 3))
3106 (reg:SI 0)] UNSPEC_MVST))
3107 (clobber (reg:CC CC_REGNUM))]
3108 ""
3109 "mvst\t%1,%2\;jo\t.-4"
3110 [(set_attr "length" "8")
3111 (set_attr "type" "vs")])
3112
3113
3114 ;
3115 ; movmemM instruction pattern(s).
3116 ;
3117
3118 (define_expand "movmem<mode>"
3119 [(set (match_operand:BLK 0 "memory_operand" "") ; destination
3120 (match_operand:BLK 1 "memory_operand" "")) ; source
3121 (use (match_operand:GPR 2 "general_operand" "")) ; count
3122 (match_operand 3 "" "")]
3123 ""
3124 {
3125 if (s390_expand_movmem (operands[0], operands[1], operands[2]))
3126 DONE;
3127 else
3128 FAIL;
3129 })
3130
3131 ; Move a block that is up to 256 bytes in length.
3132 ; The block length is taken as (operands[2] % 256) + 1.
3133
3134 (define_expand "movmem_short"
3135 [(parallel
3136 [(set (match_operand:BLK 0 "memory_operand" "")
3137 (match_operand:BLK 1 "memory_operand" ""))
3138 (use (match_operand 2 "nonmemory_operand" ""))
3139 (use (const:BLK (unspec:BLK [(const_int 0)] UNSPEC_INSN)))
3140 (clobber (match_dup 3))])]
3141 ""
3142 "operands[3] = gen_rtx_SCRATCH (Pmode);")
3143
3144 (define_insn "*movmem_short"
3145 [(set (match_operand:BLK 0 "memory_operand" "=Q,Q,Q,Q")
3146 (match_operand:BLK 1 "memory_operand" "Q,Q,Q,Q"))
3147 (use (match_operand 2 "nonmemory_operand" "n,a,a,a"))
3148 (use (match_operand 3 "immediate_operand" "X,R,X,X"))
3149 (clobber (match_scratch:P 4 "=X,X,X,&a"))]
3150 "(GET_MODE (operands[2]) == Pmode || GET_MODE (operands[2]) == VOIDmode)"
3151 "#"
3152 [(set_attr "type" "cs")
3153 (set_attr "cpu_facility" "*,*,z10,cpu_zarch")])
3154
3155 (define_split
3156 [(set (match_operand:BLK 0 "memory_operand" "")
3157 (match_operand:BLK 1 "memory_operand" ""))
3158 (use (match_operand 2 "const_int_operand" ""))
3159 (use (match_operand 3 "immediate_operand" ""))
3160 (clobber (scratch))]
3161 "reload_completed"
3162 [(parallel
3163 [(set (match_dup 0) (match_dup 1))
3164 (use (match_dup 2))])]
3165 "operands[2] = GEN_INT ((INTVAL (operands[2]) & 0xff) + 1);")
3166
3167 (define_split
3168 [(set (match_operand:BLK 0 "memory_operand" "")
3169 (match_operand:BLK 1 "memory_operand" ""))
3170 (use (match_operand 2 "register_operand" ""))
3171 (use (match_operand 3 "memory_operand" ""))
3172 (clobber (scratch))]
3173 "reload_completed"
3174 [(parallel
3175 [(unspec [(match_dup 2) (match_dup 3)
3176 (const_int 0)] UNSPEC_EXECUTE)
3177 (set (match_dup 0) (match_dup 1))
3178 (use (const_int 1))])]
3179 "")
3180
3181 (define_split
3182 [(set (match_operand:BLK 0 "memory_operand" "")
3183 (match_operand:BLK 1 "memory_operand" ""))
3184 (use (match_operand 2 "register_operand" ""))
3185 (use (const:BLK (unspec:BLK [(const_int 0)] UNSPEC_INSN)))
3186 (clobber (scratch))]
3187 "TARGET_Z10 && reload_completed"
3188 [(parallel
3189 [(unspec [(match_dup 2) (const_int 0)
3190 (label_ref (match_dup 3))] UNSPEC_EXECUTE)
3191 (set (match_dup 0) (match_dup 1))
3192 (use (const_int 1))])]
3193 "operands[3] = gen_label_rtx ();")
3194
3195 (define_split
3196 [(set (match_operand:BLK 0 "memory_operand" "")
3197 (match_operand:BLK 1 "memory_operand" ""))
3198 (use (match_operand 2 "register_operand" ""))
3199 (use (const:BLK (unspec:BLK [(const_int 0)] UNSPEC_INSN)))
3200 (clobber (match_operand 3 "register_operand" ""))]
3201 "reload_completed && TARGET_CPU_ZARCH"
3202 [(set (match_dup 3) (label_ref (match_dup 4)))
3203 (parallel
3204 [(unspec [(match_dup 2) (mem:BLK (match_dup 3))
3205 (label_ref (match_dup 4))] UNSPEC_EXECUTE)
3206 (set (match_dup 0) (match_dup 1))
3207 (use (const_int 1))])]
3208 "operands[4] = gen_label_rtx ();")
3209
3210 ; Move a block of arbitrary length.
3211
3212 (define_expand "movmem_long"
3213 [(parallel
3214 [(clobber (match_dup 2))
3215 (clobber (match_dup 3))
3216 (set (match_operand:BLK 0 "memory_operand" "")
3217 (match_operand:BLK 1 "memory_operand" ""))
3218 (use (match_operand 2 "general_operand" ""))
3219 (use (match_dup 3))
3220 (clobber (reg:CC CC_REGNUM))])]
3221 ""
3222 {
3223 machine_mode sreg_mode = TARGET_ZARCH ? DImode : SImode;
3224 machine_mode dreg_mode = TARGET_ZARCH ? TImode : DImode;
3225 rtx reg0 = gen_reg_rtx (dreg_mode);
3226 rtx reg1 = gen_reg_rtx (dreg_mode);
3227 rtx addr0 = gen_lowpart (Pmode, gen_highpart (sreg_mode, reg0));
3228 rtx addr1 = gen_lowpart (Pmode, gen_highpart (sreg_mode, reg1));
3229 rtx len0 = gen_lowpart (Pmode, reg0);
3230 rtx len1 = gen_lowpart (Pmode, reg1);
3231
3232 emit_clobber (reg0);
3233 emit_move_insn (addr0, force_operand (XEXP (operands[0], 0), NULL_RTX));
3234 emit_move_insn (len0, operands[2]);
3235
3236 emit_clobber (reg1);
3237 emit_move_insn (addr1, force_operand (XEXP (operands[1], 0), NULL_RTX));
3238 emit_move_insn (len1, operands[2]);
3239
3240 operands[0] = replace_equiv_address_nv (operands[0], addr0);
3241 operands[1] = replace_equiv_address_nv (operands[1], addr1);
3242 operands[2] = reg0;
3243 operands[3] = reg1;
3244 })
3245
3246 (define_insn "*movmem_long"
3247 [(clobber (match_operand:<DBL> 0 "register_operand" "=d"))
3248 (clobber (match_operand:<DBL> 1 "register_operand" "=d"))
3249 (set (mem:BLK (subreg:P (match_operand:<DBL> 2 "register_operand" "0") 0))
3250 (mem:BLK (subreg:P (match_operand:<DBL> 3 "register_operand" "1") 0)))
3251 (use (match_dup 2))
3252 (use (match_dup 3))
3253 (clobber (reg:CC CC_REGNUM))]
3254 "TARGET_64BIT || !TARGET_ZARCH"
3255 "mvcle\t%0,%1,0\;jo\t.-4"
3256 [(set_attr "length" "8")
3257 (set_attr "type" "vs")])
3258
3259 (define_insn "*movmem_long_31z"
3260 [(clobber (match_operand:TI 0 "register_operand" "=d"))
3261 (clobber (match_operand:TI 1 "register_operand" "=d"))
3262 (set (mem:BLK (subreg:SI (match_operand:TI 2 "register_operand" "0") 4))
3263 (mem:BLK (subreg:SI (match_operand:TI 3 "register_operand" "1") 4)))
3264 (use (match_dup 2))
3265 (use (match_dup 3))
3266 (clobber (reg:CC CC_REGNUM))]
3267 "!TARGET_64BIT && TARGET_ZARCH"
3268 "mvcle\t%0,%1,0\;jo\t.-4"
3269 [(set_attr "length" "8")
3270 (set_attr "type" "vs")])
3271
3272
3273 ;
3274 ; Test data class.
3275 ;
3276
3277 (define_expand "signbit<mode>2"
3278 [(set (reg:CCZ CC_REGNUM)
3279 (unspec:CCZ [(match_operand:FP_ALL 1 "register_operand" "f")
3280 (match_dup 2)]
3281 UNSPEC_TDC_INSN))
3282 (set (match_operand:SI 0 "register_operand" "=d")
3283 (unspec:SI [(reg:CCZ CC_REGNUM)] UNSPEC_CC_TO_INT))]
3284 "TARGET_HARD_FLOAT"
3285 {
3286 operands[2] = GEN_INT (S390_TDC_SIGNBIT_SET);
3287 })
3288
3289 (define_expand "isinf<mode>2"
3290 [(set (reg:CCZ CC_REGNUM)
3291 (unspec:CCZ [(match_operand:FP_ALL 1 "register_operand" "f")
3292 (match_dup 2)]
3293 UNSPEC_TDC_INSN))
3294 (set (match_operand:SI 0 "register_operand" "=d")
3295 (unspec:SI [(reg:CCZ CC_REGNUM)] UNSPEC_CC_TO_INT))]
3296 "TARGET_HARD_FLOAT"
3297 {
3298 operands[2] = GEN_INT (S390_TDC_INFINITY);
3299 })
3300
3301 ; This extracts CC into a GPR properly shifted. The actual IPM
3302 ; instruction will be issued by reload. The constraint of operand 1
3303 ; forces reload to use a GPR. So reload will issue a movcc insn for
3304 ; copying CC into a GPR first.
3305 (define_insn_and_split "*cc_to_int"
3306 [(set (match_operand:SI 0 "nonimmediate_operand" "=d")
3307 (unspec:SI [(match_operand 1 "register_operand" "0")]
3308 UNSPEC_CC_TO_INT))]
3309 "operands != NULL"
3310 "#"
3311 "reload_completed"
3312 [(set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 28)))])
3313
3314 ; This insn is used to generate all variants of the Test Data Class
3315 ; instruction, namely tcxb, tcdb, and tceb. The insn's first operand
3316 ; is the register to be tested and the second one is the bit mask
3317 ; specifying the required test(s).
3318 ;
3319 ; tcxb, tcdb, tceb, tdcxt, tdcdt, tdcet
3320 (define_insn "*TDC_insn_<mode>"
3321 [(set (reg:CCZ CC_REGNUM)
3322 (unspec:CCZ [(match_operand:FP_ALL 0 "register_operand" "f")
3323 (match_operand:SI 1 "const_int_operand")] UNSPEC_TDC_INSN))]
3324 "TARGET_HARD_FLOAT"
3325 "t<_d>c<xde><bt>\t%0,%1"
3326 [(set_attr "op_type" "RXE")
3327 (set_attr "type" "fsimp<mode>")])
3328
3329
3330
3331 ;
3332 ; setmemM instruction pattern(s).
3333 ;
3334
3335 (define_expand "setmem<mode>"
3336 [(set (match_operand:BLK 0 "memory_operand" "")
3337 (match_operand:QI 2 "general_operand" ""))
3338 (use (match_operand:GPR 1 "general_operand" ""))
3339 (match_operand 3 "" "")]
3340 ""
3341 "s390_expand_setmem (operands[0], operands[1], operands[2]); DONE;")
3342
3343 ; Clear a block that is up to 256 bytes in length.
3344 ; The block length is taken as (operands[1] % 256) + 1.
3345
3346 (define_expand "clrmem_short"
3347 [(parallel
3348 [(set (match_operand:BLK 0 "memory_operand" "")
3349 (const_int 0))
3350 (use (match_operand 1 "nonmemory_operand" ""))
3351 (use (const:BLK (unspec:BLK [(const_int 0)] UNSPEC_INSN)))
3352 (clobber (match_dup 2))
3353 (clobber (reg:CC CC_REGNUM))])]
3354 ""
3355 "operands[2] = gen_rtx_SCRATCH (Pmode);")
3356
3357 (define_insn "*clrmem_short"
3358 [(set (match_operand:BLK 0 "memory_operand" "=Q,Q,Q,Q")
3359 (const_int 0))
3360 (use (match_operand 1 "nonmemory_operand" "n,a,a,a"))
3361 (use (match_operand 2 "immediate_operand" "X,R,X,X"))
3362 (clobber (match_scratch:P 3 "=X,X,X,&a"))
3363 (clobber (reg:CC CC_REGNUM))]
3364 "(GET_MODE (operands[1]) == Pmode || GET_MODE (operands[1]) == VOIDmode)"
3365 "#"
3366 [(set_attr "type" "cs")
3367 (set_attr "cpu_facility" "*,*,z10,cpu_zarch")])
3368
3369 (define_split
3370 [(set (match_operand:BLK 0 "memory_operand" "")
3371 (const_int 0))
3372 (use (match_operand 1 "const_int_operand" ""))
3373 (use (match_operand 2 "immediate_operand" ""))
3374 (clobber (scratch))
3375 (clobber (reg:CC CC_REGNUM))]
3376 "reload_completed"
3377 [(parallel
3378 [(set (match_dup 0) (const_int 0))
3379 (use (match_dup 1))
3380 (clobber (reg:CC CC_REGNUM))])]
3381 "operands[1] = GEN_INT ((INTVAL (operands[1]) & 0xff) + 1);")
3382
3383 (define_split
3384 [(set (match_operand:BLK 0 "memory_operand" "")
3385 (const_int 0))
3386 (use (match_operand 1 "register_operand" ""))
3387 (use (match_operand 2 "memory_operand" ""))
3388 (clobber (scratch))
3389 (clobber (reg:CC CC_REGNUM))]
3390 "reload_completed"
3391 [(parallel
3392 [(unspec [(match_dup 1) (match_dup 2)
3393 (const_int 0)] UNSPEC_EXECUTE)
3394 (set (match_dup 0) (const_int 0))
3395 (use (const_int 1))
3396 (clobber (reg:CC CC_REGNUM))])]
3397 "")
3398
3399 (define_split
3400 [(set (match_operand:BLK 0 "memory_operand" "")
3401 (const_int 0))
3402 (use (match_operand 1 "register_operand" ""))
3403 (use (const:BLK (unspec:BLK [(const_int 0)] UNSPEC_INSN)))
3404 (clobber (scratch))
3405 (clobber (reg:CC CC_REGNUM))]
3406 "TARGET_Z10 && reload_completed"
3407 [(parallel
3408 [(unspec [(match_dup 1) (const_int 0)
3409 (label_ref (match_dup 3))] UNSPEC_EXECUTE)
3410 (set (match_dup 0) (const_int 0))
3411 (use (const_int 1))
3412 (clobber (reg:CC CC_REGNUM))])]
3413 "operands[3] = gen_label_rtx ();")
3414
3415 (define_split
3416 [(set (match_operand:BLK 0 "memory_operand" "")
3417 (const_int 0))
3418 (use (match_operand 1 "register_operand" ""))
3419 (use (const:BLK (unspec:BLK [(const_int 0)] UNSPEC_INSN)))
3420 (clobber (match_operand 2 "register_operand" ""))
3421 (clobber (reg:CC CC_REGNUM))]
3422 "reload_completed && TARGET_CPU_ZARCH"
3423 [(set (match_dup 2) (label_ref (match_dup 3)))
3424 (parallel
3425 [(unspec [(match_dup 1) (mem:BLK (match_dup 2))
3426 (label_ref (match_dup 3))] UNSPEC_EXECUTE)
3427 (set (match_dup 0) (const_int 0))
3428 (use (const_int 1))
3429 (clobber (reg:CC CC_REGNUM))])]
3430 "operands[3] = gen_label_rtx ();")
3431
3432 ; Initialize a block of arbitrary length with (operands[2] % 256).
3433
3434 (define_expand "setmem_long_<P:mode>"
3435 [(parallel
3436 [(clobber (match_dup 1))
3437 (set (match_operand:BLK 0 "memory_operand" "")
3438 (unspec:BLK [(match_operand:P 2 "setmem_operand" "")
3439 (match_dup 4)] UNSPEC_REPLICATE_BYTE))
3440 (use (match_dup 3))
3441 (clobber (reg:CC CC_REGNUM))])]
3442 ""
3443 {
3444 machine_mode sreg_mode = TARGET_ZARCH ? DImode : SImode;
3445 machine_mode dreg_mode = TARGET_ZARCH ? TImode : DImode;
3446 rtx reg0 = gen_reg_rtx (dreg_mode);
3447 rtx reg1 = gen_reg_rtx (dreg_mode);
3448 rtx addr0 = gen_lowpart (Pmode, gen_highpart (sreg_mode, reg0));
3449 rtx len0 = gen_lowpart (Pmode, reg0);
3450
3451 emit_clobber (reg0);
3452 emit_move_insn (addr0, force_operand (XEXP (operands[0], 0), NULL_RTX));
3453 emit_move_insn (len0, operands[1]);
3454
3455 emit_move_insn (reg1, const0_rtx);
3456
3457 operands[0] = replace_equiv_address_nv (operands[0], addr0);
3458 operands[1] = reg0;
3459 operands[3] = reg1;
3460 operands[4] = gen_lowpart (Pmode, operands[1]);
3461 })
3462
3463 ; Patterns for 31 bit + Esa and 64 bit + Zarch.
3464
3465 (define_insn "*setmem_long"
3466 [(clobber (match_operand:<DBL> 0 "register_operand" "=d"))
3467 (set (mem:BLK (subreg:P (match_operand:<DBL> 3 "register_operand" "0") 0))
3468 (unspec:BLK [(match_operand:P 2 "setmem_operand" "Y")
3469 (subreg:P (match_dup 3) <modesize>)]
3470 UNSPEC_REPLICATE_BYTE))
3471 (use (match_operand:<DBL> 1 "register_operand" "d"))
3472 (clobber (reg:CC CC_REGNUM))]
3473 "TARGET_64BIT || !TARGET_ZARCH"
3474 "mvcle\t%0,%1,%Y2\;jo\t.-4"
3475 [(set_attr "length" "8")
3476 (set_attr "type" "vs")])
3477
3478 (define_insn "*setmem_long_and"
3479 [(clobber (match_operand:<DBL> 0 "register_operand" "=d"))
3480 (set (mem:BLK (subreg:P (match_operand:<DBL> 3 "register_operand" "0") 0))
3481 (unspec:BLK [(zero_extend:P (match_operand:QI 2 "setmem_operand" "Y"))
3482 (subreg:P (match_dup 3) <modesize>)]
3483 UNSPEC_REPLICATE_BYTE))
3484 (use (match_operand:<DBL> 1 "register_operand" "d"))
3485 (clobber (reg:CC CC_REGNUM))]
3486 "(TARGET_64BIT || !TARGET_ZARCH)"
3487 "mvcle\t%0,%1,%Y2\;jo\t.-4"
3488 [(set_attr "length" "8")
3489 (set_attr "type" "vs")])
3490
3491 ; Variants for 31 bit + Zarch, necessary because of the odd in-register offsets
3492 ; of the SImode subregs.
3493
3494 (define_insn "*setmem_long_31z"
3495 [(clobber (match_operand:TI 0 "register_operand" "=d"))
3496 (set (mem:BLK (subreg:SI (match_operand:TI 3 "register_operand" "0") 4))
3497 (unspec:BLK [(match_operand:SI 2 "setmem_operand" "Y")
3498 (subreg:SI (match_dup 3) 12)] UNSPEC_REPLICATE_BYTE))
3499 (use (match_operand:TI 1 "register_operand" "d"))
3500 (clobber (reg:CC CC_REGNUM))]
3501 "!TARGET_64BIT && TARGET_ZARCH"
3502 "mvcle\t%0,%1,%Y2\;jo\t.-4"
3503 [(set_attr "length" "8")
3504 (set_attr "type" "vs")])
3505
3506 (define_insn "*setmem_long_and_31z"
3507 [(clobber (match_operand:TI 0 "register_operand" "=d"))
3508 (set (mem:BLK (subreg:SI (match_operand:TI 3 "register_operand" "0") 4))
3509 (unspec:BLK [(zero_extend:SI (match_operand:QI 2 "setmem_operand" "Y"))
3510 (subreg:SI (match_dup 3) 12)] UNSPEC_REPLICATE_BYTE))
3511 (use (match_operand:TI 1 "register_operand" "d"))
3512 (clobber (reg:CC CC_REGNUM))]
3513 "(!TARGET_64BIT && TARGET_ZARCH)"
3514 "mvcle\t%0,%1,%Y2\;jo\t.-4"
3515 [(set_attr "length" "8")
3516 (set_attr "type" "vs")])
3517
3518 ;
3519 ; cmpmemM instruction pattern(s).
3520 ;
3521
3522 (define_expand "cmpmemsi"
3523 [(set (match_operand:SI 0 "register_operand" "")
3524 (compare:SI (match_operand:BLK 1 "memory_operand" "")
3525 (match_operand:BLK 2 "memory_operand" "") ) )
3526 (use (match_operand:SI 3 "general_operand" ""))
3527 (use (match_operand:SI 4 "" ""))]
3528 ""
3529 {
3530 if (s390_expand_cmpmem (operands[0], operands[1],
3531 operands[2], operands[3]))
3532 DONE;
3533 else
3534 FAIL;
3535 })
3536
3537 ; Compare a block that is up to 256 bytes in length.
3538 ; The block length is taken as (operands[2] % 256) + 1.
3539
3540 (define_expand "cmpmem_short"
3541 [(parallel
3542 [(set (reg:CCU CC_REGNUM)
3543 (compare:CCU (match_operand:BLK 0 "memory_operand" "")
3544 (match_operand:BLK 1 "memory_operand" "")))
3545 (use (match_operand 2 "nonmemory_operand" ""))
3546 (use (const:BLK (unspec:BLK [(const_int 0)] UNSPEC_INSN)))
3547 (clobber (match_dup 3))])]
3548 ""
3549 "operands[3] = gen_rtx_SCRATCH (Pmode);")
3550
3551 (define_insn "*cmpmem_short"
3552 [(set (reg:CCU CC_REGNUM)
3553 (compare:CCU (match_operand:BLK 0 "memory_operand" "Q,Q,Q,Q")
3554 (match_operand:BLK 1 "memory_operand" "Q,Q,Q,Q")))
3555 (use (match_operand 2 "nonmemory_operand" "n,a,a,a"))
3556 (use (match_operand 3 "immediate_operand" "X,R,X,X"))
3557 (clobber (match_scratch:P 4 "=X,X,X,&a"))]
3558 "(GET_MODE (operands[2]) == Pmode || GET_MODE (operands[2]) == VOIDmode)"
3559 "#"
3560 [(set_attr "type" "cs")
3561 (set_attr "cpu_facility" "*,*,z10,cpu_zarch")])
3562
3563 (define_split
3564 [(set (reg:CCU CC_REGNUM)
3565 (compare:CCU (match_operand:BLK 0 "memory_operand" "")
3566 (match_operand:BLK 1 "memory_operand" "")))
3567 (use (match_operand 2 "const_int_operand" ""))
3568 (use (match_operand 3 "immediate_operand" ""))
3569 (clobber (scratch))]
3570 "reload_completed"
3571 [(parallel
3572 [(set (reg:CCU CC_REGNUM) (compare:CCU (match_dup 0) (match_dup 1)))
3573 (use (match_dup 2))])]
3574 "operands[2] = GEN_INT ((INTVAL (operands[2]) & 0xff) + 1);")
3575
3576 (define_split
3577 [(set (reg:CCU CC_REGNUM)
3578 (compare:CCU (match_operand:BLK 0 "memory_operand" "")
3579 (match_operand:BLK 1 "memory_operand" "")))
3580 (use (match_operand 2 "register_operand" ""))
3581 (use (match_operand 3 "memory_operand" ""))
3582 (clobber (scratch))]
3583 "reload_completed"
3584 [(parallel
3585 [(unspec [(match_dup 2) (match_dup 3)
3586 (const_int 0)] UNSPEC_EXECUTE)
3587 (set (reg:CCU CC_REGNUM) (compare:CCU (match_dup 0) (match_dup 1)))
3588 (use (const_int 1))])]
3589 "")
3590
3591 (define_split
3592 [(set (reg:CCU CC_REGNUM)
3593 (compare:CCU (match_operand:BLK 0 "memory_operand" "")
3594 (match_operand:BLK 1 "memory_operand" "")))
3595 (use (match_operand 2 "register_operand" ""))
3596 (use (const:BLK (unspec:BLK [(const_int 0)] UNSPEC_INSN)))
3597 (clobber (scratch))]
3598 "TARGET_Z10 && reload_completed"
3599 [(parallel
3600 [(unspec [(match_dup 2) (const_int 0)
3601 (label_ref (match_dup 4))] UNSPEC_EXECUTE)
3602 (set (reg:CCU CC_REGNUM) (compare:CCU (match_dup 0) (match_dup 1)))
3603 (use (const_int 1))])]
3604 "operands[4] = gen_label_rtx ();")
3605
3606 (define_split
3607 [(set (reg:CCU CC_REGNUM)
3608 (compare:CCU (match_operand:BLK 0 "memory_operand" "")
3609 (match_operand:BLK 1 "memory_operand" "")))
3610 (use (match_operand 2 "register_operand" ""))
3611 (use (const:BLK (unspec:BLK [(const_int 0)] UNSPEC_INSN)))
3612 (clobber (match_operand 3 "register_operand" ""))]
3613 "reload_completed && TARGET_CPU_ZARCH"
3614 [(set (match_dup 3) (label_ref (match_dup 4)))
3615 (parallel
3616 [(unspec [(match_dup 2) (mem:BLK (match_dup 3))
3617 (label_ref (match_dup 4))] UNSPEC_EXECUTE)
3618 (set (reg:CCU CC_REGNUM) (compare:CCU (match_dup 0) (match_dup 1)))
3619 (use (const_int 1))])]
3620 "operands[4] = gen_label_rtx ();")
3621
3622 ; Compare a block of arbitrary length.
3623
3624 (define_expand "cmpmem_long"
3625 [(parallel
3626 [(clobber (match_dup 2))
3627 (clobber (match_dup 3))
3628 (set (reg:CCU CC_REGNUM)
3629 (compare:CCU (match_operand:BLK 0 "memory_operand" "")
3630 (match_operand:BLK 1 "memory_operand" "")))
3631 (use (match_operand 2 "general_operand" ""))
3632 (use (match_dup 3))])]
3633 ""
3634 {
3635 machine_mode sreg_mode = TARGET_ZARCH ? DImode : SImode;
3636 machine_mode dreg_mode = TARGET_ZARCH ? TImode : DImode;
3637 rtx reg0 = gen_reg_rtx (dreg_mode);
3638 rtx reg1 = gen_reg_rtx (dreg_mode);
3639 rtx addr0 = gen_lowpart (Pmode, gen_highpart (sreg_mode, reg0));
3640 rtx addr1 = gen_lowpart (Pmode, gen_highpart (sreg_mode, reg1));
3641 rtx len0 = gen_lowpart (Pmode, reg0);
3642 rtx len1 = gen_lowpart (Pmode, reg1);
3643
3644 emit_clobber (reg0);
3645 emit_move_insn (addr0, force_operand (XEXP (operands[0], 0), NULL_RTX));
3646 emit_move_insn (len0, operands[2]);
3647
3648 emit_clobber (reg1);
3649 emit_move_insn (addr1, force_operand (XEXP (operands[1], 0), NULL_RTX));
3650 emit_move_insn (len1, operands[2]);
3651
3652 operands[0] = replace_equiv_address_nv (operands[0], addr0);
3653 operands[1] = replace_equiv_address_nv (operands[1], addr1);
3654 operands[2] = reg0;
3655 operands[3] = reg1;
3656 })
3657
3658 (define_insn "*cmpmem_long"
3659 [(clobber (match_operand:<DBL> 0 "register_operand" "=d"))
3660 (clobber (match_operand:<DBL> 1 "register_operand" "=d"))
3661 (set (reg:CCU CC_REGNUM)
3662 (compare:CCU (mem:BLK (subreg:P (match_operand:<DBL> 2 "register_operand" "0") 0))
3663 (mem:BLK (subreg:P (match_operand:<DBL> 3 "register_operand" "1") 0))))
3664 (use (match_dup 2))
3665 (use (match_dup 3))]
3666 "TARGET_64BIT || !TARGET_ZARCH"
3667 "clcle\t%0,%1,0\;jo\t.-4"
3668 [(set_attr "length" "8")
3669 (set_attr "type" "vs")])
3670
3671 (define_insn "*cmpmem_long_31z"
3672 [(clobber (match_operand:TI 0 "register_operand" "=d"))
3673 (clobber (match_operand:TI 1 "register_operand" "=d"))
3674 (set (reg:CCU CC_REGNUM)
3675 (compare:CCU (mem:BLK (subreg:SI (match_operand:TI 2 "register_operand" "0") 4))
3676 (mem:BLK (subreg:SI (match_operand:TI 3 "register_operand" "1") 4))))
3677 (use (match_dup 2))
3678 (use (match_dup 3))]
3679 "!TARGET_64BIT && TARGET_ZARCH"
3680 "clcle\t%0,%1,0\;jo\t.-4"
3681 [(set_attr "op_type" "NN")
3682 (set_attr "type" "vs")
3683 (set_attr "length" "8")])
3684
3685 ; Convert CCUmode condition code to integer.
3686 ; Result is zero if EQ, positive if LTU, negative if GTU.
3687
3688 (define_insn_and_split "cmpint"
3689 [(set (match_operand:SI 0 "register_operand" "=d")
3690 (unspec:SI [(match_operand:CCU 1 "register_operand" "0")]
3691 UNSPEC_STRCMPCC_TO_INT))
3692 (clobber (reg:CC CC_REGNUM))]
3693 ""
3694 "#"
3695 "reload_completed"
3696 [(set (match_dup 0) (ashift:SI (match_dup 0) (const_int 2)))
3697 (parallel
3698 [(set (match_dup 0) (ashiftrt:SI (match_dup 0) (const_int 30)))
3699 (clobber (reg:CC CC_REGNUM))])])
3700
3701 (define_insn_and_split "*cmpint_cc"
3702 [(set (reg CC_REGNUM)
3703 (compare (unspec:SI [(match_operand:CCU 1 "register_operand" "0")]
3704 UNSPEC_STRCMPCC_TO_INT)
3705 (const_int 0)))
3706 (set (match_operand:SI 0 "register_operand" "=d")
3707 (unspec:SI [(match_dup 1)] UNSPEC_STRCMPCC_TO_INT))]
3708 "s390_match_ccmode (insn, CCSmode)"
3709 "#"
3710 "&& reload_completed"
3711 [(set (match_dup 0) (ashift:SI (match_dup 0) (const_int 2)))
3712 (parallel
3713 [(set (match_dup 2) (match_dup 3))
3714 (set (match_dup 0) (ashiftrt:SI (match_dup 0) (const_int 30)))])]
3715 {
3716 rtx result = gen_rtx_ASHIFTRT (SImode, operands[0], GEN_INT (30));
3717 operands[2] = SET_DEST (XVECEXP (PATTERN (curr_insn), 0, 0));
3718 operands[3] = gen_rtx_COMPARE (GET_MODE (operands[2]), result, const0_rtx);
3719 })
3720
3721 (define_insn_and_split "*cmpint_sign"
3722 [(set (match_operand:DI 0 "register_operand" "=d")
3723 (sign_extend:DI (unspec:SI [(match_operand:CCU 1 "register_operand" "0")]
3724 UNSPEC_STRCMPCC_TO_INT)))
3725 (clobber (reg:CC CC_REGNUM))]
3726 "TARGET_ZARCH"
3727 "#"
3728 "&& reload_completed"
3729 [(set (match_dup 0) (ashift:DI (match_dup 0) (const_int 34)))
3730 (parallel
3731 [(set (match_dup 0) (ashiftrt:DI (match_dup 0) (const_int 62)))
3732 (clobber (reg:CC CC_REGNUM))])])
3733
3734 (define_insn_and_split "*cmpint_sign_cc"
3735 [(set (reg CC_REGNUM)
3736 (compare (ashiftrt:DI (ashift:DI (subreg:DI
3737 (unspec:SI [(match_operand:CCU 1 "register_operand" "0")]
3738 UNSPEC_STRCMPCC_TO_INT) 0)
3739 (const_int 32)) (const_int 32))
3740 (const_int 0)))
3741 (set (match_operand:DI 0 "register_operand" "=d")
3742 (sign_extend:DI (unspec:SI [(match_dup 1)] UNSPEC_STRCMPCC_TO_INT)))]
3743 "s390_match_ccmode (insn, CCSmode) && TARGET_ZARCH"
3744 "#"
3745 "&& reload_completed"
3746 [(set (match_dup 0) (ashift:DI (match_dup 0) (const_int 34)))
3747 (parallel
3748 [(set (match_dup 2) (match_dup 3))
3749 (set (match_dup 0) (ashiftrt:DI (match_dup 0) (const_int 62)))])]
3750 {
3751 rtx result = gen_rtx_ASHIFTRT (DImode, operands[0], GEN_INT (62));
3752 operands[2] = SET_DEST (XVECEXP (PATTERN (curr_insn), 0, 0));
3753 operands[3] = gen_rtx_COMPARE (GET_MODE (operands[2]), result, const0_rtx);
3754 })
3755
3756
3757 ;;
3758 ;;- Conversion instructions.
3759 ;;
3760
3761 (define_insn "*sethighpartsi"
3762 [(set (match_operand:SI 0 "register_operand" "=d,d")
3763 (unspec:SI [(match_operand:BLK 1 "s_operand" "Q,S")
3764 (match_operand 2 "const_int_operand" "n,n")] UNSPEC_ICM))
3765 (clobber (reg:CC CC_REGNUM))]
3766 ""
3767 "@
3768 icm\t%0,%2,%S1
3769 icmy\t%0,%2,%S1"
3770 [(set_attr "op_type" "RS,RSY")
3771 (set_attr "cpu_facility" "*,longdisp")
3772 (set_attr "z10prop" "z10_super_E1,z10_super_E1")])
3773
3774 (define_insn "*sethighpartdi_64"
3775 [(set (match_operand:DI 0 "register_operand" "=d")
3776 (unspec:DI [(match_operand:BLK 1 "s_operand" "S")
3777 (match_operand 2 "const_int_operand" "n")] UNSPEC_ICM))
3778 (clobber (reg:CC CC_REGNUM))]
3779 "TARGET_ZARCH"
3780 "icmh\t%0,%2,%S1"
3781 [(set_attr "op_type" "RSY")
3782 (set_attr "z10prop" "z10_super")])
3783
3784 (define_insn "*sethighpartdi_31"
3785 [(set (match_operand:DI 0 "register_operand" "=d,d")
3786 (unspec:DI [(match_operand:BLK 1 "s_operand" "Q,S")
3787 (match_operand 2 "const_int_operand" "n,n")] UNSPEC_ICM))
3788 (clobber (reg:CC CC_REGNUM))]
3789 "!TARGET_ZARCH"
3790 "@
3791 icm\t%0,%2,%S1
3792 icmy\t%0,%2,%S1"
3793 [(set_attr "op_type" "RS,RSY")
3794 (set_attr "cpu_facility" "*,longdisp")
3795 (set_attr "z10prop" "z10_super_E1,z10_super_E1")])
3796
3797 ;
3798 ; extv instruction patterns
3799 ;
3800
3801 ; FIXME: This expander needs to be converted from DI to GPR as well
3802 ; after resolving some issues with it.
3803
3804 (define_expand "extzv"
3805 [(parallel
3806 [(set (match_operand:DI 0 "register_operand" "=d")
3807 (zero_extract:DI
3808 (match_operand:DI 1 "register_operand" "d")
3809 (match_operand 2 "const_int_operand" "") ; size
3810 (match_operand 3 "const_int_operand" ""))) ; start
3811 (clobber (reg:CC CC_REGNUM))])]
3812 "TARGET_Z10"
3813 {
3814 if (! EXTRACT_ARGS_IN_RANGE (INTVAL (operands[2]), INTVAL (operands[3]), 64))
3815 FAIL;
3816 /* Starting with zEC12 there is risbgn not clobbering CC. */
3817 if (TARGET_ZEC12)
3818 {
3819 emit_move_insn (operands[0],
3820 gen_rtx_ZERO_EXTRACT (DImode,
3821 operands[1],
3822 operands[2],
3823 operands[3]));
3824 DONE;
3825 }
3826 })
3827
3828 (define_insn "*extzv<mode><clobbercc_or_nocc>"
3829 [(set (match_operand:GPR 0 "register_operand" "=d")
3830 (zero_extract:GPR
3831 (match_operand:GPR 1 "register_operand" "d")
3832 (match_operand 2 "const_int_operand" "") ; size
3833 (match_operand 3 "const_int_operand" ""))) ; start
3834 ]
3835 "<z10_or_zEC12_cond>
3836 && EXTRACT_ARGS_IN_RANGE (INTVAL (operands[2]), INTVAL (operands[3]),
3837 GET_MODE_BITSIZE (<MODE>mode))"
3838 "<risbg_n>\t%0,%1,64-%2,128+63,<bitoff_plus>%3+%2" ; dst, src, start, end, shift
3839 [(set_attr "op_type" "RIE")
3840 (set_attr "z10prop" "z10_super_E1")])
3841
3842 ; 64 bit: (a & -16) | ((b >> 8) & 15)
3843 (define_insn "*extzvdi<clobbercc_or_nocc>_lshiftrt"
3844 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+d")
3845 (match_operand 1 "const_int_operand" "") ; size
3846 (match_operand 2 "const_int_operand" "")) ; start
3847 (lshiftrt:DI (match_operand:DI 3 "register_operand" "d")
3848 (match_operand:DI 4 "nonzero_shift_count_operand" "")))]
3849 "<z10_or_zEC12_cond>
3850 && EXTRACT_ARGS_IN_RANGE (INTVAL (operands[1]), INTVAL (operands[2]), 64)
3851 && 64 - UINTVAL (operands[4]) >= UINTVAL (operands[1])"
3852 "<risbg_n>\t%0,%3,%2,%2+%1-1,128-%2-%1-%4"
3853 [(set_attr "op_type" "RIE")
3854 (set_attr "z10prop" "z10_super_E1")])
3855
3856 ; 32 bit: (a & -16) | ((b >> 8) & 15)
3857 (define_insn "*<risbg_n>_ior_and_sr_ze"
3858 [(set (match_operand:SI 0 "register_operand" "=d")
3859 (ior:SI (and:SI
3860 (match_operand:SI 1 "register_operand" "0")
3861 (match_operand:SI 2 "const_int_operand" ""))
3862 (subreg:SI
3863 (zero_extract:DI
3864 (match_operand:DI 3 "register_operand" "d")
3865 (match_operand 4 "const_int_operand" "") ; size
3866 (match_operand 5 "const_int_operand" "")) ; start
3867 4)))]
3868 "<z10_or_zEC12_cond>
3869 && EXTRACT_ARGS_IN_RANGE (INTVAL (operands[4]), INTVAL (operands[5]), 64)
3870 && UINTVAL (operands[2]) == (~(0ULL) << UINTVAL (operands[4]))"
3871 "<risbg_n>\t%0,%3,64-%4,63,%4+%5"
3872 [(set_attr "op_type" "RIE")
3873 (set_attr "z10prop" "z10_super_E1")])
3874
3875 ; ((int)foo >> 10) & 1;
3876 (define_insn "*extract1bitdi<clobbercc_or_nocc>"
3877 [(set (match_operand:DI 0 "register_operand" "=d")
3878 (ne:DI (zero_extract:DI
3879 (match_operand:DI 1 "register_operand" "d")
3880 (const_int 1) ; size
3881 (match_operand 2 "const_int_operand" "")) ; start
3882 (const_int 0)))]
3883 "<z10_or_zEC12_cond>
3884 && EXTRACT_ARGS_IN_RANGE (1, INTVAL (operands[2]), 64)"
3885 "<risbg_n>\t%0,%1,64-1,128+63,%2+1" ; dst, src, start, end, shift
3886 [(set_attr "op_type" "RIE")
3887 (set_attr "z10prop" "z10_super_E1")])
3888
3889 (define_insn "*<risbg_n>_and_subregdi_rotr"
3890 [(set (match_operand:DI 0 "register_operand" "=d")
3891 (and:DI (subreg:DI
3892 (rotate:SINT (match_operand:SINT 1 "register_operand" "d")
3893 (match_operand:SINT 2 "const_int_operand" "")) 0)
3894 (match_operand:DI 3 "contiguous_bitmask_operand" "")))]
3895 "<z10_or_zEC12_cond>
3896 && UINTVAL (operands[3]) < (1ULL << (UINTVAL (operands[2]) & 0x3f))"
3897 "<risbg_n>\t%0,%1,%s3,128+%e3,<bitoff_plus>%2" ; dst, src, start, end, shift
3898 [(set_attr "op_type" "RIE")
3899 (set_attr "z10prop" "z10_super_E1")])
3900
3901 (define_insn "*<risbg_n>_and_subregdi_rotl"
3902 [(set (match_operand:DI 0 "register_operand" "=d")
3903 (and:DI (subreg:DI
3904 (rotate:SINT (match_operand:SINT 1 "register_operand" "d")
3905 (match_operand:SINT 2 "const_int_operand" "")) 0)
3906 (match_operand:DI 3 "contiguous_bitmask_operand" "")))]
3907 "<z10_or_zEC12_cond>
3908 && !(UINTVAL (operands[3]) & ((1ULL << (UINTVAL (operands[2]) & 0x3f)) - 1))"
3909 "<risbg_n>\t%0,%1,%s3,128+%e3,%2" ; dst, src, start, end, shift
3910 [(set_attr "op_type" "RIE")
3911 (set_attr "z10prop" "z10_super_E1")])
3912
3913 (define_insn "*<risbg_n>_di_and_rot"
3914 [(set (match_operand:DI 0 "register_operand" "=d")
3915 (and:DI (rotate:DI (match_operand:DI 1 "register_operand" "d")
3916 (match_operand:DI 2 "const_int_operand" ""))
3917 (match_operand:DI 3 "contiguous_bitmask_operand" "")))]
3918 "<z10_or_zEC12_cond>"
3919 "<risbg_n>\t%0,%1,%s3,128+%e3,%2" ; dst, src, start, end, shift
3920 [(set_attr "op_type" "RIE")
3921 (set_attr "z10prop" "z10_super_E1")])
3922
3923 (define_insn_and_split "*pre_z10_extzv<mode>"
3924 [(set (match_operand:GPR 0 "register_operand" "=d")
3925 (zero_extract:GPR (match_operand:QI 1 "s_operand" "S")
3926 (match_operand 2 "nonzero_shift_count_operand" "")
3927 (const_int 0)))
3928 (clobber (reg:CC CC_REGNUM))]
3929 "!TARGET_Z10"
3930 "#"
3931 "&& reload_completed"
3932 [(parallel
3933 [(set (match_dup 0) (unspec:GPR [(match_dup 1) (match_dup 3)] UNSPEC_ICM))
3934 (clobber (reg:CC CC_REGNUM))])
3935 (set (match_dup 0) (lshiftrt:GPR (match_dup 0) (match_dup 2)))]
3936 {
3937 int bitsize = INTVAL (operands[2]);
3938 int size = (bitsize - 1) / BITS_PER_UNIT + 1; /* round up */
3939 int mask = ((1ul << size) - 1) << (GET_MODE_SIZE (SImode) - size);
3940
3941 operands[1] = adjust_address (operands[1], BLKmode, 0);
3942 set_mem_size (operands[1], size);
3943 operands[2] = GEN_INT (<GPR:bitsize> - bitsize);
3944 operands[3] = GEN_INT (mask);
3945 })
3946
3947 (define_insn_and_split "*pre_z10_extv<mode>"
3948 [(set (match_operand:GPR 0 "register_operand" "=d")
3949 (sign_extract:GPR (match_operand:QI 1 "s_operand" "S")
3950 (match_operand 2 "nonzero_shift_count_operand" "")
3951 (const_int 0)))
3952 (clobber (reg:CC CC_REGNUM))]
3953 ""
3954 "#"
3955 "&& reload_completed"
3956 [(parallel
3957 [(set (match_dup 0) (unspec:GPR [(match_dup 1) (match_dup 3)] UNSPEC_ICM))
3958 (clobber (reg:CC CC_REGNUM))])
3959 (parallel
3960 [(set (match_dup 0) (ashiftrt:GPR (match_dup 0) (match_dup 2)))
3961 (clobber (reg:CC CC_REGNUM))])]
3962 {
3963 int bitsize = INTVAL (operands[2]);
3964 int size = (bitsize - 1) / BITS_PER_UNIT + 1; /* round up */
3965 int mask = ((1ul << size) - 1) << (GET_MODE_SIZE (SImode) - size);
3966
3967 operands[1] = adjust_address (operands[1], BLKmode, 0);
3968 set_mem_size (operands[1], size);
3969 operands[2] = GEN_INT (<GPR:bitsize> - bitsize);
3970 operands[3] = GEN_INT (mask);
3971 })
3972
3973 ;
3974 ; insv instruction patterns
3975 ;
3976
3977 (define_expand "insv"
3978 [(set (zero_extract (match_operand 0 "nonimmediate_operand" "")
3979 (match_operand 1 "const_int_operand" "")
3980 (match_operand 2 "const_int_operand" ""))
3981 (match_operand 3 "general_operand" ""))]
3982 ""
3983 {
3984 if (s390_expand_insv (operands[0], operands[1], operands[2], operands[3]))
3985 DONE;
3986 FAIL;
3987 })
3988
3989
3990 ; The normal RTL expansion will never generate a zero_extract where
3991 ; the location operand isn't word mode. However, we do this in the
3992 ; back-end when generating atomic operations. See s390_two_part_insv.
3993 (define_insn "*insv<mode><clobbercc_or_nocc>"
3994 [(set (zero_extract:GPR (match_operand:GPR 0 "nonimmediate_operand" "+d")
3995 (match_operand 1 "const_int_operand" "I") ; size
3996 (match_operand 2 "const_int_operand" "I")) ; pos
3997 (match_operand:GPR 3 "nonimmediate_operand" "d"))]
3998 "<z10_or_zEC12_cond>
3999 && EXTRACT_ARGS_IN_RANGE (INTVAL (operands[1]), INTVAL (operands[2]),
4000 GET_MODE_BITSIZE (<MODE>mode))
4001 && (INTVAL (operands[1]) + INTVAL (operands[2])) <= <bitsize>"
4002 "<risbg_n>\t%0,%3,<bitoff_plus>%2,<bitoff_plus>%2+%1-1,<bitsize>-%2-%1"
4003 [(set_attr "op_type" "RIE")
4004 (set_attr "z10prop" "z10_super_E1")])
4005
4006 ; and op1 with a mask being 1 for the selected bits and 0 for the rest
4007 ; and op3=op0 with a mask being 0 for the selected bits and 1 for the rest
4008 (define_insn "*insv<mode><clobbercc_or_nocc>_noshift"
4009 [(set (match_operand:GPR 0 "nonimmediate_operand" "=d,d")
4010 (ior:GPR (and:GPR (match_operand:GPR 1 "nonimmediate_operand" "d,0")
4011 (match_operand:GPR 2 "contiguous_bitmask_operand" ""))
4012 (and:GPR (match_operand:GPR 3 "nonimmediate_operand" "0,d")
4013 (match_operand:GPR 4 "const_int_operand" ""))))]
4014 "<z10_or_zEC12_cond> && INTVAL (operands[2]) == ~INTVAL (operands[4])"
4015 "@
4016 <risbg_n>\t%0,%1,%<bfstart>2,%<bfend>2,0
4017 <risbg_n>\t%0,%3,%<bfstart>4,%<bfend>4,0"
4018 [(set_attr "op_type" "RIE")
4019 (set_attr "z10prop" "z10_super_E1")])
4020
4021 (define_insn "*insv_z10_noshift_cc"
4022 [(set (reg CC_REGNUM)
4023 (compare
4024 (ior:DI
4025 (and:DI (match_operand:DI 1 "nonimmediate_operand" "d,0")
4026 (match_operand:DI 2 "contiguous_bitmask_operand" ""))
4027 (and:DI (match_operand:DI 3 "nonimmediate_operand" "0,d")
4028 (match_operand:DI 4 "const_int_operand" "")))
4029 (const_int 0)))
4030 (set (match_operand:DI 0 "nonimmediate_operand" "=d,d")
4031 (ior:DI (and:DI (match_dup 1) (match_dup 2))
4032 (and:DI (match_dup 3) (match_dup 4))))]
4033 "TARGET_Z10 && s390_match_ccmode (insn, CCSmode)
4034 && INTVAL (operands[2]) == ~INTVAL (operands[4])"
4035 "@
4036 risbg\t%0,%1,%s2,%e2,0
4037 risbg\t%0,%3,%s4,%e4,0"
4038 [(set_attr "op_type" "RIE")
4039 (set_attr "z10prop" "z10_super_E1")])
4040
4041 (define_insn "*insv_z10_noshift_cconly"
4042 [(set
4043 (reg CC_REGNUM)
4044 (compare
4045 (ior:DI
4046 (and:DI (match_operand:DI 1 "nonimmediate_operand" "d,0")
4047 (match_operand:DI 2 "contiguous_bitmask_operand" ""))
4048 (and:DI (match_operand:DI 3 "nonimmediate_operand" "0,d")
4049 (match_operand:DI 4 "const_int_operand" "")))
4050 (const_int 0)))
4051 (clobber (match_scratch:DI 0 "=d,d"))]
4052 "TARGET_Z10 && s390_match_ccmode (insn, CCSmode)
4053 && INTVAL (operands[2]) == ~INTVAL (operands[4])"
4054 "@
4055 risbg\t%0,%1,%s2,%e2,0
4056 risbg\t%0,%3,%s4,%e4,0"
4057 [(set_attr "op_type" "RIE")
4058 (set_attr "z10prop" "z10_super_E1")])
4059
4060 ; Implement appending Y on the left of S bits of X
4061 ; x = (y << s) | (x & ((1 << s) - 1))
4062 (define_insn "*insv<mode><clobbercc_or_nocc>_appendbitsleft"
4063 [(set (match_operand:GPR 0 "nonimmediate_operand" "=d")
4064 (ior:GPR (and:GPR (match_operand:GPR 1 "nonimmediate_operand" "0")
4065 (match_operand:GPR 2 "immediate_operand" ""))
4066 (ashift:GPR (match_operand:GPR 3 "nonimmediate_operand" "d")
4067 (match_operand:GPR 4 "nonzero_shift_count_operand" ""))))]
4068 "<z10_or_zEC12_cond>
4069 && UINTVAL (operands[2]) == (1UL << UINTVAL (operands[4])) - 1"
4070 "<risbg_n>\t%0,%3,<bitoff>,64-%4-1,%4"
4071 [(set_attr "op_type" "RIE")
4072 (set_attr "z10prop" "z10_super_E1")])
4073
4074 ; a = ((i32)a & -16777216) | (((ui32)b) >> 8)
4075 (define_insn "*<risbg_n>_<mode>_ior_and_lshiftrt"
4076 [(set (match_operand:GPR 0 "register_operand" "=d")
4077 (ior:GPR (and:GPR
4078 (match_operand:GPR 1 "register_operand" "0")
4079 (match_operand:GPR 2 "const_int_operand" ""))
4080 (lshiftrt:GPR
4081 (match_operand:GPR 3 "register_operand" "d")
4082 (match_operand:GPR 4 "nonzero_shift_count_operand" ""))))]
4083 "<z10_or_zEC12_cond> && UINTVAL (operands[2])
4084 == (~(0ULL) << (GET_MODE_BITSIZE (<MODE>mode) - UINTVAL (operands[4])))"
4085 "<risbg_n>\t%0,%3,<bitoff_plus>%4,63,64-%4"
4086 [(set_attr "op_type" "RIE")
4087 (set_attr "z10prop" "z10_super_E1")])
4088
4089 ; (ui32)(((ui64)x) >> 48) | ((i32)y & -65536);
4090 (define_insn "*<risbg_n>_sidi_ior_and_lshiftrt"
4091 [(set (match_operand:SI 0 "register_operand" "=d")
4092 (ior:SI (and:SI
4093 (match_operand:SI 1 "register_operand" "0")
4094 (match_operand:SI 2 "const_int_operand" ""))
4095 (subreg:SI
4096 (lshiftrt:DI
4097 (match_operand:DI 3 "register_operand" "d")
4098 (match_operand:DI 4 "nonzero_shift_count_operand" "")) 4)))]
4099 "<z10_or_zEC12_cond>
4100 && UINTVAL (operands[2]) == ~(~(0ULL) >> UINTVAL (operands[4]))"
4101 "<risbg_n>\t%0,%3,%4,63,64-%4"
4102 [(set_attr "op_type" "RIE")
4103 (set_attr "z10prop" "z10_super_E1")])
4104
4105 ; (ui32)(((ui64)x) >> 12) & -4
4106 (define_insn "*trunc_sidi_and_subreg_lshrt<clobbercc_or_nocc>"
4107 [(set (match_operand:SI 0 "register_operand" "=d")
4108 (and:SI
4109 (subreg:SI (lshiftrt:DI
4110 (match_operand:DI 1 "register_operand" "d")
4111 (match_operand:DI 2 "nonzero_shift_count_operand" "")) 4)
4112 (match_operand:SI 3 "contiguous_bitmask_nowrap_operand" "")))]
4113 "<z10_or_zEC12_cond>"
4114 "<risbg_n>\t%0,%1,%t3,128+%f3,64-%2"
4115 [(set_attr "op_type" "RIE")
4116 (set_attr "z10prop" "z10_super_E1")])
4117
4118 ; z = (x << c) | (y >> d) with (x << c) and (y >> d) not overlapping after shifting
4119 ; -> z = y >> d; z = (x << c) | (z & ((1 << c) - 1))
4120 ; -> z = y >> d; z = risbg;
4121
4122 (define_split
4123 [(set (match_operand:GPR 0 "nonimmediate_operand" "")
4124 (ior:GPR (lshiftrt:GPR (match_operand:GPR 1 "nonimmediate_operand" "")
4125 (match_operand:GPR 2 "nonzero_shift_count_operand" ""))
4126 (ashift:GPR (match_operand:GPR 3 "nonimmediate_operand" "")
4127 (match_operand:GPR 4 "nonzero_shift_count_operand" ""))))]
4128 "TARGET_ZEC12 && UINTVAL (operands[2]) + UINTVAL (operands[4]) >= <bitsize>"
4129 [(set (match_dup 6)
4130 (lshiftrt:GPR (match_dup 1) (match_dup 2)))
4131 (set (match_dup 0)
4132 (ior:GPR (and:GPR (match_dup 6) (match_dup 5))
4133 (ashift:GPR (match_dup 3) (match_dup 4))))]
4134 {
4135 operands[5] = GEN_INT ((1UL << UINTVAL (operands[4])) - 1);
4136 if (reg_overlap_mentioned_p (operands[0], operands[3]))
4137 {
4138 if (!can_create_pseudo_p ())
4139 FAIL;
4140 operands[6] = gen_reg_rtx (<MODE>mode);
4141 }
4142 else
4143 operands[6] = operands[0];
4144 })
4145
4146 (define_split
4147 [(parallel
4148 [(set (match_operand:GPR 0 "nonimmediate_operand" "")
4149 (ior:GPR (lshiftrt:GPR (match_operand:GPR 1 "nonimmediate_operand" "")
4150 (match_operand:GPR 2 "nonzero_shift_count_operand" ""))
4151 (ashift:GPR (match_operand:GPR 3 "nonimmediate_operand" "")
4152 (match_operand:GPR 4 "nonzero_shift_count_operand" ""))))
4153 (clobber (reg:CC CC_REGNUM))])]
4154 "TARGET_Z10 && !TARGET_ZEC12 && UINTVAL (operands[2]) + UINTVAL (operands[4]) >= <bitsize>"
4155 [(set (match_dup 6)
4156 (lshiftrt:GPR (match_dup 1) (match_dup 2)))
4157 (parallel
4158 [(set (match_dup 0)
4159 (ior:GPR (and:GPR (match_dup 6) (match_dup 5))
4160 (ashift:GPR (match_dup 3) (match_dup 4))))
4161 (clobber (reg:CC CC_REGNUM))])]
4162 {
4163 operands[5] = GEN_INT ((1UL << UINTVAL (operands[4])) - 1);
4164 if (reg_overlap_mentioned_p (operands[0], operands[3]))
4165 {
4166 if (!can_create_pseudo_p ())
4167 FAIL;
4168 operands[6] = gen_reg_rtx (<MODE>mode);
4169 }
4170 else
4171 operands[6] = operands[0];
4172 })
4173
4174 ; rosbg, rxsbg
4175 (define_insn "*r<noxa>sbg_<mode>_noshift"
4176 [(set (match_operand:GPR 0 "nonimmediate_operand" "=d")
4177 (IXOR:GPR
4178 (and:GPR (match_operand:GPR 1 "nonimmediate_operand" "d")
4179 (match_operand:GPR 2 "contiguous_bitmask_operand" ""))
4180 (match_operand:GPR 3 "nonimmediate_operand" "0")))
4181 (clobber (reg:CC CC_REGNUM))]
4182 "TARGET_Z10"
4183 "r<noxa>sbg\t%0,%1,%<bfstart>2,%<bfend>2,0"
4184 [(set_attr "op_type" "RIE")])
4185
4186 ; rosbg, rxsbg
4187 (define_insn "*r<noxa>sbg_di_rotl"
4188 [(set (match_operand:DI 0 "nonimmediate_operand" "=d")
4189 (IXOR:DI
4190 (and:DI
4191 (rotate:DI
4192 (match_operand:DI 1 "nonimmediate_operand" "d")
4193 (match_operand:DI 3 "const_int_operand" ""))
4194 (match_operand:DI 2 "contiguous_bitmask_operand" ""))
4195 (match_operand:DI 4 "nonimmediate_operand" "0")))
4196 (clobber (reg:CC CC_REGNUM))]
4197 "TARGET_Z10"
4198 "r<noxa>sbg\t%0,%1,%<bfstart>2,%<bfend>2,%b3"
4199 [(set_attr "op_type" "RIE")])
4200
4201 ; rosbg, rxsbg
4202 (define_insn "*r<noxa>sbg_<mode>_srl_bitmask"
4203 [(set (match_operand:GPR 0 "nonimmediate_operand" "=d")
4204 (IXOR:GPR
4205 (and:GPR
4206 (lshiftrt:GPR
4207 (match_operand:GPR 1 "nonimmediate_operand" "d")
4208 (match_operand:GPR 3 "nonzero_shift_count_operand" ""))
4209 (match_operand:GPR 2 "contiguous_bitmask_nowrap_operand" ""))
4210 (match_operand:GPR 4 "nonimmediate_operand" "0")))
4211 (clobber (reg:CC CC_REGNUM))]
4212 "TARGET_Z10
4213 && s390_extzv_shift_ok (<bitsize>, 64 - INTVAL (operands[3]),
4214 INTVAL (operands[2]))"
4215 "r<noxa>sbg\t%0,%1,%<bfstart>2,%<bfend>2,64-%3"
4216 [(set_attr "op_type" "RIE")])
4217
4218 ; rosbg, rxsbg
4219 (define_insn "*r<noxa>sbg_<mode>_sll_bitmask"
4220 [(set (match_operand:GPR 0 "nonimmediate_operand" "=d")
4221 (IXOR:GPR
4222 (and:GPR
4223 (ashift:GPR
4224 (match_operand:GPR 1 "nonimmediate_operand" "d")
4225 (match_operand:GPR 3 "nonzero_shift_count_operand" ""))
4226 (match_operand:GPR 2 "contiguous_bitmask_nowrap_operand" ""))
4227 (match_operand:GPR 4 "nonimmediate_operand" "0")))
4228 (clobber (reg:CC CC_REGNUM))]
4229 "TARGET_Z10
4230 && s390_extzv_shift_ok (<bitsize>, INTVAL (operands[3]),
4231 INTVAL (operands[2]))"
4232 "r<noxa>sbg\t%0,%1,%<bfstart>2,%<bfend>2,%3"
4233 [(set_attr "op_type" "RIE")])
4234
4235 ;; unsigned {int,long} a, b
4236 ;; a = a | (b << const_int)
4237 ;; a = a ^ (b << const_int)
4238 ; rosbg, rxsbg
4239 (define_insn "*r<noxa>sbg_<mode>_sll"
4240 [(set (match_operand:GPR 0 "nonimmediate_operand" "=d")
4241 (IXOR:GPR
4242 (ashift:GPR
4243 (match_operand:GPR 1 "nonimmediate_operand" "d")
4244 (match_operand:GPR 2 "nonzero_shift_count_operand" ""))
4245 (match_operand:GPR 3 "nonimmediate_operand" "0")))
4246 (clobber (reg:CC CC_REGNUM))]
4247 "TARGET_Z10"
4248 "r<noxa>sbg\t%0,%1,<bitoff>,63-%2,%2"
4249 [(set_attr "op_type" "RIE")])
4250
4251 ;; unsigned {int,long} a, b
4252 ;; a = a | (b >> const_int)
4253 ;; a = a ^ (b >> const_int)
4254 ; rosbg, rxsbg
4255 (define_insn "*r<noxa>sbg_<mode>_srl"
4256 [(set (match_operand:GPR 0 "nonimmediate_operand" "=d")
4257 (IXOR:GPR
4258 (lshiftrt:GPR
4259 (match_operand:GPR 1 "nonimmediate_operand" "d")
4260 (match_operand:GPR 2 "nonzero_shift_count_operand" ""))
4261 (match_operand:GPR 3 "nonimmediate_operand" "0")))
4262 (clobber (reg:CC CC_REGNUM))]
4263 "TARGET_Z10"
4264 "r<noxa>sbg\t%0,%1,<bitoff_plus>%2,63,64-%2"
4265 [(set_attr "op_type" "RIE")])
4266
4267 ;; These two are generated by combine for s.bf &= val.
4268 ;; ??? For bitfields smaller than 32-bits, we wind up with SImode
4269 ;; shifts and ands, which results in some truly awful patterns
4270 ;; including subregs of operations. Rather unnecessisarily, IMO.
4271 ;; Instead of
4272 ;;
4273 ;; (set (zero_extract:DI (reg/v:DI 50 [ s ])
4274 ;; (const_int 24 [0x18])
4275 ;; (const_int 0 [0]))
4276 ;; (subreg:DI (and:SI (subreg:SI (lshiftrt:DI (reg/v:DI 50 [ s ])
4277 ;; (const_int 40 [0x28])) 4)
4278 ;; (reg:SI 4 %r4 [ y+4 ])) 0))
4279 ;;
4280 ;; we should instead generate
4281 ;;
4282 ;; (set (zero_extract:DI (reg/v:DI 50 [ s ])
4283 ;; (const_int 24 [0x18])
4284 ;; (const_int 0 [0]))
4285 ;; (and:DI (lshiftrt:DI (reg/v:DI 50 [ s ])
4286 ;; (const_int 40 [0x28]))
4287 ;; (subreg:DI (reg:SI 4 %r4 [ y+4 ]) 0)))
4288 ;;
4289 ;; by noticing that we can push down the outer paradoxical subreg
4290 ;; into the operation.
4291
4292 (define_insn "*insv_rnsbg_noshift"
4293 [(set (zero_extract:DI
4294 (match_operand:DI 0 "nonimmediate_operand" "+d")
4295 (match_operand 1 "const_int_operand" "")
4296 (match_operand 2 "const_int_operand" ""))
4297 (and:DI
4298 (match_dup 0)
4299 (match_operand:DI 3 "nonimmediate_operand" "d")))
4300 (clobber (reg:CC CC_REGNUM))]
4301 "TARGET_Z10
4302 && EXTRACT_ARGS_IN_RANGE (INTVAL (operands[1]), INTVAL (operands[2]), 64)
4303 && INTVAL (operands[1]) + INTVAL (operands[2]) == 64"
4304 "rnsbg\t%0,%3,%2,63,0"
4305 [(set_attr "op_type" "RIE")])
4306
4307 (define_insn "*insv_rnsbg_srl"
4308 [(set (zero_extract:DI
4309 (match_operand:DI 0 "nonimmediate_operand" "+d")
4310 (match_operand 1 "const_int_operand" "")
4311 (match_operand 2 "const_int_operand" ""))
4312 (and:DI
4313 (lshiftrt:DI
4314 (match_dup 0)
4315 (match_operand 3 "const_int_operand" ""))
4316 (match_operand:DI 4 "nonimmediate_operand" "d")))
4317 (clobber (reg:CC CC_REGNUM))]
4318 "TARGET_Z10
4319 && EXTRACT_ARGS_IN_RANGE (INTVAL (operands[1]), INTVAL (operands[2]), 64)
4320 && INTVAL (operands[3]) == 64 - INTVAL (operands[1]) - INTVAL (operands[2])"
4321 "rnsbg\t%0,%4,%2,%2+%1-1,%3"
4322 [(set_attr "op_type" "RIE")])
4323
4324 (define_insn "*insv<mode>_mem_reg"
4325 [(set (zero_extract:W (match_operand:QI 0 "memory_operand" "+Q,S")
4326 (match_operand 1 "const_int_operand" "n,n")
4327 (const_int 0))
4328 (match_operand:W 2 "register_operand" "d,d"))]
4329 "EXTRACT_ARGS_IN_RANGE (INTVAL (operands[1]), 0, 64)
4330 && INTVAL (operands[1]) > 0
4331 && INTVAL (operands[1]) <= GET_MODE_BITSIZE (SImode)
4332 && INTVAL (operands[1]) % BITS_PER_UNIT == 0"
4333 {
4334 int size = INTVAL (operands[1]) / BITS_PER_UNIT;
4335
4336 operands[1] = GEN_INT ((1ul << size) - 1);
4337 return (which_alternative == 0) ? "stcm\t%2,%1,%S0"
4338 : "stcmy\t%2,%1,%S0";
4339 }
4340 [(set_attr "op_type" "RS,RSY")
4341 (set_attr "cpu_facility" "*,longdisp")
4342 (set_attr "z10prop" "z10_super,z10_super")])
4343
4344 (define_insn "*insvdi_mem_reghigh"
4345 [(set (zero_extract:DI (match_operand:QI 0 "memory_operand" "+S")
4346 (match_operand 1 "const_int_operand" "n")
4347 (const_int 0))
4348 (lshiftrt:DI (match_operand:DI 2 "register_operand" "d")
4349 (const_int 32)))]
4350 "TARGET_ZARCH
4351 && EXTRACT_ARGS_IN_RANGE (INTVAL (operands[1]), 0, 64)
4352 && INTVAL (operands[1]) > 0
4353 && INTVAL (operands[1]) <= GET_MODE_BITSIZE (SImode)
4354 && INTVAL (operands[1]) % BITS_PER_UNIT == 0"
4355 {
4356 int size = INTVAL (operands[1]) / BITS_PER_UNIT;
4357
4358 operands[1] = GEN_INT ((1ul << size) - 1);
4359 return "stcmh\t%2,%1,%S0";
4360 }
4361 [(set_attr "op_type" "RSY")
4362 (set_attr "z10prop" "z10_super")])
4363
4364 (define_insn "*insvdi_reg_imm"
4365 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+d")
4366 (const_int 16)
4367 (match_operand 1 "const_int_operand" "n"))
4368 (match_operand:DI 2 "const_int_operand" "n"))]
4369 "TARGET_ZARCH
4370 && EXTRACT_ARGS_IN_RANGE (16, INTVAL (operands[1]), 64)
4371 && INTVAL (operands[1]) >= 0
4372 && INTVAL (operands[1]) < BITS_PER_WORD
4373 && INTVAL (operands[1]) % 16 == 0"
4374 {
4375 switch (BITS_PER_WORD - INTVAL (operands[1]))
4376 {
4377 case 64: return "iihh\t%0,%x2"; break;
4378 case 48: return "iihl\t%0,%x2"; break;
4379 case 32: return "iilh\t%0,%x2"; break;
4380 case 16: return "iill\t%0,%x2"; break;
4381 default: gcc_unreachable();
4382 }
4383 }
4384 [(set_attr "op_type" "RI")
4385 (set_attr "z10prop" "z10_super_E1")])
4386
4387 ; Update the left-most 32 bit of a DI.
4388 (define_insn "*insv_h_di_reg_extimm"
4389 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+d")
4390 (const_int 32)
4391 (const_int 0))
4392 (match_operand:DI 1 "const_int_operand" "n"))]
4393 "TARGET_EXTIMM"
4394 "iihf\t%0,%o1"
4395 [(set_attr "op_type" "RIL")
4396 (set_attr "z10prop" "z10_fwd_E1")])
4397
4398 ; Update the right-most 32 bit of a DI.
4399 (define_insn "*insv_l_di_reg_extimm"
4400 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+d")
4401 (const_int 32)
4402 (const_int 32))
4403 (match_operand:DI 1 "const_int_operand" "n"))]
4404 "TARGET_EXTIMM"
4405 "iilf\t%0,%o1"
4406 [(set_attr "op_type" "RIL")
4407 (set_attr "z10prop" "z10_fwd_A1")])
4408
4409 ;
4410 ; extendsidi2 instruction pattern(s).
4411 ;
4412
4413 (define_expand "extendsidi2"
4414 [(set (match_operand:DI 0 "register_operand" "")
4415 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "")))]
4416 ""
4417 {
4418 if (!TARGET_ZARCH)
4419 {
4420 emit_clobber (operands[0]);
4421 emit_move_insn (gen_highpart (SImode, operands[0]), operands[1]);
4422 emit_move_insn (gen_lowpart (SImode, operands[0]), const0_rtx);
4423 emit_insn (gen_ashrdi3 (operands[0], operands[0], GEN_INT (32)));
4424 DONE;
4425 }
4426 })
4427
4428 (define_insn "*extendsidi2"
4429 [(set (match_operand:DI 0 "register_operand" "=d,d,d")
4430 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "d,T,b")))]
4431 "TARGET_ZARCH"
4432 "@
4433 lgfr\t%0,%1
4434 lgf\t%0,%1
4435 lgfrl\t%0,%1"
4436 [(set_attr "op_type" "RRE,RXY,RIL")
4437 (set_attr "type" "*,*,larl")
4438 (set_attr "cpu_facility" "*,*,z10")
4439 (set_attr "z10prop" "z10_super_E1,z10_super_E1,z10_super_E1")])
4440
4441 ;
4442 ; extend(hi|qi)(si|di)2 instruction pattern(s).
4443 ;
4444
4445 (define_expand "extend<HQI:mode><DSI:mode>2"
4446 [(set (match_operand:DSI 0 "register_operand" "")
4447 (sign_extend:DSI (match_operand:HQI 1 "nonimmediate_operand" "")))]
4448 ""
4449 {
4450 if (<DSI:MODE>mode == DImode && !TARGET_ZARCH)
4451 {
4452 rtx tmp = gen_reg_rtx (SImode);
4453 emit_insn (gen_extend<HQI:mode>si2 (tmp, operands[1]));
4454 emit_insn (gen_extendsidi2 (operands[0], tmp));
4455 DONE;
4456 }
4457 else if (!TARGET_EXTIMM)
4458 {
4459 rtx bitcount = GEN_INT (<DSI:bitsize> - <HQI:bitsize>);
4460
4461 operands[1] = gen_lowpart (<DSI:MODE>mode, operands[1]);
4462 emit_insn (gen_ashl<DSI:mode>3 (operands[0], operands[1], bitcount));
4463 emit_insn (gen_ashr<DSI:mode>3 (operands[0], operands[0], bitcount));
4464 DONE;
4465 }
4466 })
4467
4468 ;
4469 ; extendhidi2 instruction pattern(s).
4470 ;
4471
4472 (define_insn "*extendhidi2_extimm"
4473 [(set (match_operand:DI 0 "register_operand" "=d,d,d")
4474 (sign_extend:DI (match_operand:HI 1 "general_operand" "d,T,b")))]
4475 "TARGET_ZARCH && TARGET_EXTIMM"
4476 "@
4477 lghr\t%0,%1
4478 lgh\t%0,%1
4479 lghrl\t%0,%1"
4480 [(set_attr "op_type" "RRE,RXY,RIL")
4481 (set_attr "type" "*,*,larl")
4482 (set_attr "cpu_facility" "extimm,extimm,z10")
4483 (set_attr "z10prop" "z10_super_E1,z10_super_E1,z10_super_E1")])
4484
4485 (define_insn "*extendhidi2"
4486 [(set (match_operand:DI 0 "register_operand" "=d")
4487 (sign_extend:DI (match_operand:HI 1 "memory_operand" "T")))]
4488 "TARGET_ZARCH"
4489 "lgh\t%0,%1"
4490 [(set_attr "op_type" "RXY")
4491 (set_attr "z10prop" "z10_super_E1")])
4492
4493 ;
4494 ; extendhisi2 instruction pattern(s).
4495 ;
4496
4497 (define_insn "*extendhisi2_extimm"
4498 [(set (match_operand:SI 0 "register_operand" "=d,d,d,d")
4499 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" " d,R,T,b")))]
4500 "TARGET_EXTIMM"
4501 "@
4502 lhr\t%0,%1
4503 lh\t%0,%1
4504 lhy\t%0,%1
4505 lhrl\t%0,%1"
4506 [(set_attr "op_type" "RRE,RX,RXY,RIL")
4507 (set_attr "type" "*,*,*,larl")
4508 (set_attr "cpu_facility" "extimm,extimm,extimm,z10")
4509 (set_attr "z10prop" "z10_super_E1,z10_super_E1,z10_super_E1,z10_super_E1")])
4510
4511 (define_insn "*extendhisi2"
4512 [(set (match_operand:SI 0 "register_operand" "=d,d")
4513 (sign_extend:SI (match_operand:HI 1 "memory_operand" "R,T")))]
4514 "!TARGET_EXTIMM"
4515 "@
4516 lh\t%0,%1
4517 lhy\t%0,%1"
4518 [(set_attr "op_type" "RX,RXY")
4519 (set_attr "cpu_facility" "*,longdisp")
4520 (set_attr "z10prop" "z10_super_E1,z10_super_E1")])
4521
4522 ;
4523 ; extendqi(si|di)2 instruction pattern(s).
4524 ;
4525
4526 ; lbr, lgbr, lb, lgb
4527 (define_insn "*extendqi<mode>2_extimm"
4528 [(set (match_operand:GPR 0 "register_operand" "=d,d")
4529 (sign_extend:GPR (match_operand:QI 1 "nonimmediate_operand" "d,T")))]
4530 "TARGET_EXTIMM"
4531 "@
4532 l<g>br\t%0,%1
4533 l<g>b\t%0,%1"
4534 [(set_attr "op_type" "RRE,RXY")
4535 (set_attr "z10prop" "z10_super_E1,z10_super_E1")])
4536
4537 ; lb, lgb
4538 (define_insn "*extendqi<mode>2"
4539 [(set (match_operand:GPR 0 "register_operand" "=d")
4540 (sign_extend:GPR (match_operand:QI 1 "memory_operand" "T")))]
4541 "!TARGET_EXTIMM && TARGET_LONG_DISPLACEMENT"
4542 "l<g>b\t%0,%1"
4543 [(set_attr "op_type" "RXY")
4544 (set_attr "z10prop" "z10_super_E1")])
4545
4546 (define_insn_and_split "*extendqi<mode>2_short_displ"
4547 [(set (match_operand:GPR 0 "register_operand" "=d")
4548 (sign_extend:GPR (match_operand:QI 1 "s_operand" "Q")))
4549 (clobber (reg:CC CC_REGNUM))]
4550 "!TARGET_EXTIMM && !TARGET_LONG_DISPLACEMENT"
4551 "#"
4552 "&& reload_completed"
4553 [(parallel
4554 [(set (match_dup 0) (unspec:GPR [(match_dup 1) (const_int 8)] UNSPEC_ICM))
4555 (clobber (reg:CC CC_REGNUM))])
4556 (parallel
4557 [(set (match_dup 0) (ashiftrt:GPR (match_dup 0) (match_dup 2)))
4558 (clobber (reg:CC CC_REGNUM))])]
4559 {
4560 operands[1] = adjust_address (operands[1], BLKmode, 0);
4561 set_mem_size (operands[1], GET_MODE_SIZE (QImode));
4562 operands[2] = GEN_INT (<GPR:bitsize> - BITS_PER_UNIT);
4563 })
4564
4565 ;
4566 ; zero_extendsidi2 instruction pattern(s).
4567 ;
4568
4569 (define_expand "zero_extendsidi2"
4570 [(set (match_operand:DI 0 "register_operand" "")
4571 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "")))]
4572 ""
4573 {
4574 if (!TARGET_ZARCH)
4575 {
4576 emit_clobber (operands[0]);
4577 emit_move_insn (gen_lowpart (SImode, operands[0]), operands[1]);
4578 emit_move_insn (gen_highpart (SImode, operands[0]), const0_rtx);
4579 DONE;
4580 }
4581 })
4582
4583 (define_insn "*zero_extendsidi2"
4584 [(set (match_operand:DI 0 "register_operand" "=d,d,d")
4585 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "d,T,b")))]
4586 "TARGET_ZARCH"
4587 "@
4588 llgfr\t%0,%1
4589 llgf\t%0,%1
4590 llgfrl\t%0,%1"
4591 [(set_attr "op_type" "RRE,RXY,RIL")
4592 (set_attr "type" "*,*,larl")
4593 (set_attr "cpu_facility" "*,*,z10")
4594 (set_attr "z10prop" "z10_fwd_E1,z10_fwd_A3,z10_fwd_A3")])
4595
4596 ;
4597 ; LLGT-type instructions (zero-extend from 31 bit to 64 bit).
4598 ;
4599
4600 (define_insn "*llgt_sidi"
4601 [(set (match_operand:DI 0 "register_operand" "=d")
4602 (and:DI (subreg:DI (match_operand:SI 1 "memory_operand" "T") 0)
4603 (const_int 2147483647)))]
4604 "TARGET_ZARCH"
4605 "llgt\t%0,%1"
4606 [(set_attr "op_type" "RXE")
4607 (set_attr "z10prop" "z10_super_E1")])
4608
4609 (define_insn_and_split "*llgt_sidi_split"
4610 [(set (match_operand:DI 0 "register_operand" "=d")
4611 (and:DI (subreg:DI (match_operand:SI 1 "memory_operand" "T") 0)
4612 (const_int 2147483647)))
4613 (clobber (reg:CC CC_REGNUM))]
4614 "TARGET_ZARCH"
4615 "#"
4616 "&& reload_completed"
4617 [(set (match_dup 0)
4618 (and:DI (subreg:DI (match_dup 1) 0)
4619 (const_int 2147483647)))]
4620 "")
4621
4622 (define_insn "*llgt_sisi"
4623 [(set (match_operand:SI 0 "register_operand" "=d,d")
4624 (and:SI (match_operand:SI 1 "nonimmediate_operand" "d,T")
4625 (const_int 2147483647)))]
4626 "TARGET_ZARCH"
4627 "@
4628 llgtr\t%0,%1
4629 llgt\t%0,%1"
4630 [(set_attr "op_type" "RRE,RXE")
4631 (set_attr "z10prop" "z10_super_E1,z10_super_E1")])
4632
4633 (define_insn "*llgt_didi"
4634 [(set (match_operand:DI 0 "register_operand" "=d,d")
4635 (and:DI (match_operand:DI 1 "nonimmediate_operand" "d,o")
4636 (const_int 2147483647)))]
4637 "TARGET_ZARCH"
4638 "@
4639 llgtr\t%0,%1
4640 llgt\t%0,%N1"
4641 [(set_attr "op_type" "RRE,RXE")
4642 (set_attr "z10prop" "z10_super_E1,z10_super_E1")])
4643
4644 (define_split
4645 [(set (match_operand:DSI 0 "register_operand" "")
4646 (and:DSI (match_operand:DSI 1 "nonimmediate_operand" "")
4647 (const_int 2147483647)))
4648 (clobber (reg:CC CC_REGNUM))]
4649 "TARGET_ZARCH && reload_completed"
4650 [(set (match_dup 0)
4651 (and:DSI (match_dup 1)
4652 (const_int 2147483647)))]
4653 "")
4654
4655 ;
4656 ; zero_extend(hi|qi)(si|di)2 instruction pattern(s).
4657 ;
4658
4659 (define_expand "zero_extend<mode>di2"
4660 [(set (match_operand:DI 0 "register_operand" "")
4661 (zero_extend:DI (match_operand:HQI 1 "nonimmediate_operand" "")))]
4662 ""
4663 {
4664 if (!TARGET_ZARCH)
4665 {
4666 rtx tmp = gen_reg_rtx (SImode);
4667 emit_insn (gen_zero_extend<mode>si2 (tmp, operands[1]));
4668 emit_insn (gen_zero_extendsidi2 (operands[0], tmp));
4669 DONE;
4670 }
4671 else if (!TARGET_EXTIMM)
4672 {
4673 rtx bitcount = GEN_INT (64 - <HQI:bitsize>);
4674 operands[1] = gen_lowpart (DImode, operands[1]);
4675 emit_insn (gen_ashldi3 (operands[0], operands[1], bitcount));
4676 emit_insn (gen_lshrdi3 (operands[0], operands[0], bitcount));
4677 DONE;
4678 }
4679 })
4680
4681 (define_expand "zero_extend<mode>si2"
4682 [(set (match_operand:SI 0 "register_operand" "")
4683 (zero_extend:SI (match_operand:HQI 1 "nonimmediate_operand" "")))]
4684 ""
4685 {
4686 if (!TARGET_EXTIMM)
4687 {
4688 operands[1] = gen_lowpart (SImode, operands[1]);
4689 emit_insn (gen_andsi3 (operands[0], operands[1],
4690 GEN_INT ((1 << <HQI:bitsize>) - 1)));
4691 DONE;
4692 }
4693 })
4694
4695 ; llhrl, llghrl
4696 (define_insn "*zero_extendhi<mode>2_z10"
4697 [(set (match_operand:GPR 0 "register_operand" "=d,d,d")
4698 (zero_extend:GPR (match_operand:HI 1 "nonimmediate_operand" "d,T,b")))]
4699 "TARGET_Z10"
4700 "@
4701 ll<g>hr\t%0,%1
4702 ll<g>h\t%0,%1
4703 ll<g>hrl\t%0,%1"
4704 [(set_attr "op_type" "RXY,RRE,RIL")
4705 (set_attr "type" "*,*,larl")
4706 (set_attr "cpu_facility" "*,*,z10")
4707 (set_attr "z10prop" "z10_super_E1,z10_fwd_A3,z10_fwd_A3")])
4708
4709 ; llhr, llcr, llghr, llgcr, llh, llc, llgh, llgc
4710 (define_insn "*zero_extend<HQI:mode><GPR:mode>2_extimm"
4711 [(set (match_operand:GPR 0 "register_operand" "=d,d")
4712 (zero_extend:GPR (match_operand:HQI 1 "nonimmediate_operand" "d,T")))]
4713 "TARGET_EXTIMM"
4714 "@
4715 ll<g><hc>r\t%0,%1
4716 ll<g><hc>\t%0,%1"
4717 [(set_attr "op_type" "RRE,RXY")
4718 (set_attr "z10prop" "z10_super_E1,z10_fwd_A3")])
4719
4720 ; llgh, llgc
4721 (define_insn "*zero_extend<HQI:mode><GPR:mode>2"
4722 [(set (match_operand:GPR 0 "register_operand" "=d")
4723 (zero_extend:GPR (match_operand:HQI 1 "memory_operand" "T")))]
4724 "TARGET_ZARCH && !TARGET_EXTIMM"
4725 "llg<hc>\t%0,%1"
4726 [(set_attr "op_type" "RXY")
4727 (set_attr "z10prop" "z10_fwd_A3")])
4728
4729 (define_insn_and_split "*zero_extendhisi2_31"
4730 [(set (match_operand:SI 0 "register_operand" "=&d")
4731 (zero_extend:SI (match_operand:HI 1 "s_operand" "S")))
4732 (clobber (reg:CC CC_REGNUM))]
4733 "!TARGET_ZARCH"
4734 "#"
4735 "&& reload_completed"
4736 [(set (match_dup 0) (const_int 0))
4737 (parallel
4738 [(set (strict_low_part (match_dup 2)) (match_dup 1))
4739 (clobber (reg:CC CC_REGNUM))])]
4740 "operands[2] = gen_lowpart (HImode, operands[0]);")
4741
4742 (define_insn_and_split "*zero_extendqisi2_31"
4743 [(set (match_operand:SI 0 "register_operand" "=&d")
4744 (zero_extend:SI (match_operand:QI 1 "memory_operand" "T")))]
4745 "!TARGET_ZARCH"
4746 "#"
4747 "&& reload_completed"
4748 [(set (match_dup 0) (const_int 0))
4749 (set (strict_low_part (match_dup 2)) (match_dup 1))]
4750 "operands[2] = gen_lowpart (QImode, operands[0]);")
4751
4752 ;
4753 ; zero_extendqihi2 instruction pattern(s).
4754 ;
4755
4756 (define_expand "zero_extendqihi2"
4757 [(set (match_operand:HI 0 "register_operand" "")
4758 (zero_extend:HI (match_operand:QI 1 "register_operand" "")))]
4759 "TARGET_ZARCH && !TARGET_EXTIMM"
4760 {
4761 operands[1] = gen_lowpart (HImode, operands[1]);
4762 emit_insn (gen_andhi3 (operands[0], operands[1], GEN_INT (0xff)));
4763 DONE;
4764 })
4765
4766 (define_insn "*zero_extendqihi2_64"
4767 [(set (match_operand:HI 0 "register_operand" "=d")
4768 (zero_extend:HI (match_operand:QI 1 "memory_operand" "T")))]
4769 "TARGET_ZARCH && !TARGET_EXTIMM"
4770 "llgc\t%0,%1"
4771 [(set_attr "op_type" "RXY")
4772 (set_attr "z10prop" "z10_fwd_A3")])
4773
4774 (define_insn_and_split "*zero_extendqihi2_31"
4775 [(set (match_operand:HI 0 "register_operand" "=&d")
4776 (zero_extend:HI (match_operand:QI 1 "memory_operand" "T")))]
4777 "!TARGET_ZARCH"
4778 "#"
4779 "&& reload_completed"
4780 [(set (match_dup 0) (const_int 0))
4781 (set (strict_low_part (match_dup 2)) (match_dup 1))]
4782 "operands[2] = gen_lowpart (QImode, operands[0]);")
4783
4784 ;
4785 ; fixuns_trunc(dd|td|sf|df|tf)(si|di)2 expander
4786 ;
4787
4788 ; This is the only entry point for fixuns_trunc. It multiplexes the
4789 ; expansion to either the *_emu expanders below for pre z196 machines
4790 ; or emits the default pattern otherwise.
4791 (define_expand "fixuns_trunc<FP:mode><GPR:mode>2"
4792 [(parallel
4793 [(set (match_operand:GPR 0 "register_operand" "")
4794 (unsigned_fix:GPR (match_operand:FP 1 "register_operand" "")))
4795 (unspec:GPR [(match_dup 2)] UNSPEC_ROUND)
4796 (clobber (reg:CC CC_REGNUM))])]
4797 "TARGET_HARD_FLOAT"
4798 {
4799 if (!TARGET_Z196)
4800 {
4801 /* We don't provide emulation for TD|DD->SI. */
4802 if (GET_MODE_CLASS (<FP:MODE>mode) == MODE_DECIMAL_FLOAT
4803 && <GPR:MODE>mode == SImode)
4804 FAIL;
4805 emit_insn (gen_fixuns_trunc<FP:mode><GPR:mode>2_emu (operands[0],
4806 operands[1]));
4807 DONE;
4808 }
4809
4810 if (GET_MODE_CLASS (<FP:MODE>mode) == MODE_DECIMAL_FLOAT)
4811 operands[2] = GEN_INT (DFP_RND_TOWARD_0);
4812 else
4813 operands[2] = GEN_INT (BFP_RND_TOWARD_0);
4814 })
4815
4816 ; (sf|df|tf)->unsigned (si|di)
4817
4818 ; Emulate the unsigned conversion with the signed version for pre z196
4819 ; machines.
4820 (define_expand "fixuns_trunc<BFP:mode><GPR:mode>2_emu"
4821 [(parallel
4822 [(set (match_operand:GPR 0 "register_operand" "")
4823 (unsigned_fix:GPR (match_operand:BFP 1 "register_operand" "")))
4824 (unspec:GPR [(const_int BFP_RND_TOWARD_0)] UNSPEC_ROUND)
4825 (clobber (reg:CC CC_REGNUM))])]
4826 "!TARGET_Z196 && TARGET_HARD_FLOAT"
4827 {
4828 rtx_code_label *label1 = gen_label_rtx ();
4829 rtx_code_label *label2 = gen_label_rtx ();
4830 rtx temp = gen_reg_rtx (<BFP:MODE>mode);
4831 REAL_VALUE_TYPE cmp, sub;
4832
4833 operands[1] = force_reg (<BFP:MODE>mode, operands[1]);
4834 real_2expN (&cmp, <GPR:bitsize> - 1, <BFP:MODE>mode);
4835 real_2expN (&sub, <GPR:bitsize>, <BFP:MODE>mode);
4836
4837 emit_cmp_and_jump_insns (operands[1],
4838 const_double_from_real_value (cmp, <BFP:MODE>mode),
4839 LT, NULL_RTX, VOIDmode, 0, label1);
4840 emit_insn (gen_sub<BFP:mode>3 (temp, operands[1],
4841 const_double_from_real_value (sub, <BFP:MODE>mode)));
4842 emit_insn (gen_fix_trunc<BFP:mode><GPR:mode>2_bfp (operands[0], temp,
4843 GEN_INT (BFP_RND_TOWARD_MINF)));
4844 emit_jump (label2);
4845
4846 emit_label (label1);
4847 emit_insn (gen_fix_trunc<BFP:mode><GPR:mode>2_bfp (operands[0],
4848 operands[1],
4849 GEN_INT (BFP_RND_TOWARD_0)));
4850 emit_label (label2);
4851 DONE;
4852 })
4853
4854 ; dd->unsigned di
4855
4856 ; Emulate the unsigned conversion with the signed version for pre z196
4857 ; machines.
4858 (define_expand "fixuns_truncdddi2_emu"
4859 [(parallel
4860 [(set (match_operand:DI 0 "register_operand" "")
4861 (unsigned_fix:DI (match_operand:DD 1 "register_operand" "")))
4862 (unspec:DI [(const_int DFP_RND_TOWARD_0)] UNSPEC_ROUND)
4863 (clobber (reg:CC CC_REGNUM))])]
4864
4865 "!TARGET_Z196 && TARGET_HARD_DFP"
4866 {
4867 rtx_code_label *label1 = gen_label_rtx ();
4868 rtx_code_label *label2 = gen_label_rtx ();
4869 rtx temp = gen_reg_rtx (TDmode);
4870 REAL_VALUE_TYPE cmp, sub;
4871
4872 decimal_real_from_string (&cmp, "9223372036854775808.0"); /* 2^63 */
4873 decimal_real_from_string (&sub, "18446744073709551616.0"); /* 2^64 */
4874
4875 /* 2^63 can't be represented as 64bit DFP number with full precision. The
4876 solution is doing the check and the subtraction in TD mode and using a
4877 TD -> DI convert afterwards. */
4878 emit_insn (gen_extendddtd2 (temp, operands[1]));
4879 temp = force_reg (TDmode, temp);
4880 emit_cmp_and_jump_insns (temp,
4881 const_double_from_real_value (cmp, TDmode),
4882 LT, NULL_RTX, VOIDmode, 0, label1);
4883 emit_insn (gen_subtd3 (temp, temp,
4884 const_double_from_real_value (sub, TDmode)));
4885 emit_insn (gen_fix_trunctddi2_dfp (operands[0], temp,
4886 GEN_INT (DFP_RND_TOWARD_MINF)));
4887 emit_jump (label2);
4888
4889 emit_label (label1);
4890 emit_insn (gen_fix_truncdddi2_dfp (operands[0], operands[1],
4891 GEN_INT (DFP_RND_TOWARD_0)));
4892 emit_label (label2);
4893 DONE;
4894 })
4895
4896 ; td->unsigned di
4897
4898 ; Emulate the unsigned conversion with the signed version for pre z196
4899 ; machines.
4900 (define_expand "fixuns_trunctddi2_emu"
4901 [(parallel
4902 [(set (match_operand:DI 0 "register_operand" "")
4903 (unsigned_fix:DI (match_operand:TD 1 "register_operand" "")))
4904 (unspec:DI [(const_int DFP_RND_TOWARD_0)] UNSPEC_ROUND)
4905 (clobber (reg:CC CC_REGNUM))])]
4906
4907 "!TARGET_Z196 && TARGET_HARD_DFP"
4908 {
4909 rtx_code_label *label1 = gen_label_rtx ();
4910 rtx_code_label *label2 = gen_label_rtx ();
4911 rtx temp = gen_reg_rtx (TDmode);
4912 REAL_VALUE_TYPE cmp, sub;
4913
4914 operands[1] = force_reg (TDmode, operands[1]);
4915 decimal_real_from_string (&cmp, "9223372036854775808.0"); /* 2^63 */
4916 decimal_real_from_string (&sub, "18446744073709551616.0"); /* 2^64 */
4917
4918 emit_cmp_and_jump_insns (operands[1],
4919 const_double_from_real_value (cmp, TDmode),
4920 LT, NULL_RTX, VOIDmode, 0, label1);
4921 emit_insn (gen_subtd3 (temp, operands[1],
4922 const_double_from_real_value (sub, TDmode)));
4923 emit_insn (gen_fix_trunctddi2_dfp (operands[0], temp,
4924 GEN_INT (DFP_RND_TOWARD_MINF)));
4925 emit_jump (label2);
4926
4927 emit_label (label1);
4928 emit_insn (gen_fix_trunctddi2_dfp (operands[0], operands[1],
4929 GEN_INT (DFP_RND_TOWARD_0)));
4930 emit_label (label2);
4931 DONE;
4932 })
4933
4934 ; Just a dummy to make the code in the first expander a bit easier.
4935 (define_expand "fixuns_trunc<mode>si2_emu"
4936 [(parallel
4937 [(set (match_operand:SI 0 "register_operand" "")
4938 (unsigned_fix:SI (match_operand:DFP 1 "register_operand" "")))
4939 (unspec:DI [(const_int DFP_RND_TOWARD_0)] UNSPEC_ROUND)
4940 (clobber (reg:CC CC_REGNUM))])]
4941
4942 "!TARGET_Z196 && TARGET_HARD_DFP"
4943 {
4944 FAIL;
4945 })
4946
4947
4948 ; fixuns_trunc(tf|df|sf|td|dd)(di|si)2 instruction patterns.
4949
4950 ; df -> unsigned di
4951 (define_insn "*fixuns_truncdfdi2_vx"
4952 [(set (match_operand:DI 0 "register_operand" "=d,v")
4953 (unsigned_fix:DI (match_operand:DF 1 "register_operand" "f,v")))
4954 (unspec:DI [(match_operand:DI 2 "immediate_operand" "K,K")] UNSPEC_ROUND)
4955 (clobber (reg:CC CC_REGNUM))]
4956 "TARGET_VX && TARGET_HARD_FLOAT"
4957 "@
4958 clgdbr\t%0,%h2,%1,0
4959 wclgdb\t%v0,%v1,0,%h2"
4960 [(set_attr "op_type" "RRF,VRR")
4961 (set_attr "type" "ftoi")])
4962
4963 ; (dd|td|sf|df|tf)->unsigned (di|si)
4964 ; clfebr, clfdbr, clfxbr, clgebr, clgdbr, clgxbr
4965 ; clfdtr, clfxtr, clgdtr, clgxtr
4966 (define_insn "*fixuns_trunc<FP:mode><GPR:mode>2_z196"
4967 [(set (match_operand:GPR 0 "register_operand" "=d")
4968 (unsigned_fix:GPR (match_operand:FP 1 "register_operand" "f")))
4969 (unspec:GPR [(match_operand:GPR 2 "immediate_operand" "K")] UNSPEC_ROUND)
4970 (clobber (reg:CC CC_REGNUM))]
4971 "TARGET_Z196 && TARGET_HARD_FLOAT
4972 && (!TARGET_VX || <GPR:MODE>mode != DImode || <FP:MODE>mode != DFmode)"
4973 "cl<GPR:gf><FP:xde><FP:bt>r\t%0,%h2,%1,0"
4974 [(set_attr "op_type" "RRF")
4975 (set_attr "type" "ftoi")])
4976
4977 (define_expand "fix_trunc<DSF:mode><GPR:mode>2"
4978 [(set (match_operand:GPR 0 "register_operand" "")
4979 (fix:GPR (match_operand:DSF 1 "register_operand" "")))]
4980 "TARGET_HARD_FLOAT"
4981 {
4982 emit_insn (gen_fix_trunc<DSF:mode><GPR:mode>2_bfp (operands[0], operands[1],
4983 GEN_INT (BFP_RND_TOWARD_0)));
4984 DONE;
4985 })
4986
4987 (define_insn "*fix_truncdfdi2_bfp_z13"
4988 [(set (match_operand:DI 0 "register_operand" "=d,v")
4989 (fix:DI (match_operand:DF 1 "register_operand" "f,v")))
4990 (unspec:DI [(match_operand:DI 2 "immediate_operand" "K,K")] UNSPEC_ROUND)
4991 (clobber (reg:CC CC_REGNUM))]
4992 "TARGET_VX && TARGET_HARD_FLOAT"
4993 "@
4994 cgdbr\t%0,%h2,%1
4995 wcgdb\t%v0,%v1,0,%h2"
4996 [(set_attr "op_type" "RRE,VRR")
4997 (set_attr "type" "ftoi")])
4998
4999 ; cgxbr, cgdbr, cgebr, cfxbr, cfdbr, cfebr
5000 (define_insn "*fix_trunc<BFP:mode><GPR:mode>2_bfp"
5001 [(set (match_operand:GPR 0 "register_operand" "=d")
5002 (fix:GPR (match_operand:BFP 1 "register_operand" "f")))
5003 (unspec:GPR [(match_operand:GPR 2 "immediate_operand" "K")] UNSPEC_ROUND)
5004 (clobber (reg:CC CC_REGNUM))]
5005 "TARGET_HARD_FLOAT
5006 && (!TARGET_VX || <GPR:MODE>mode != DImode || <BFP:MODE>mode != DFmode)"
5007 "c<GPR:gf><BFP:xde>br\t%0,%h2,%1"
5008 [(set_attr "op_type" "RRE")
5009 (set_attr "type" "ftoi")])
5010
5011 (define_expand "fix_trunc<BFP:mode><GPR:mode>2_bfp"
5012 [(parallel
5013 [(set (match_operand:GPR 0 "register_operand" "=d")
5014 (fix:GPR (match_operand:BFP 1 "register_operand" "f")))
5015 (unspec:GPR [(match_operand:GPR 2 "immediate_operand" "K")] UNSPEC_ROUND)
5016 (clobber (reg:CC CC_REGNUM))])]
5017 "TARGET_HARD_FLOAT")
5018 ;
5019 ; fix_trunc(td|dd)di2 instruction pattern(s).
5020 ;
5021
5022 (define_expand "fix_trunc<mode>di2"
5023 [(set (match_operand:DI 0 "register_operand" "")
5024 (fix:DI (match_operand:DFP 1 "nonimmediate_operand" "")))]
5025 "TARGET_ZARCH && TARGET_HARD_DFP"
5026 {
5027 operands[1] = force_reg (<MODE>mode, operands[1]);
5028 emit_insn (gen_fix_trunc<mode>di2_dfp (operands[0], operands[1],
5029 GEN_INT (DFP_RND_TOWARD_0)));
5030 DONE;
5031 })
5032
5033 ; cgxtr, cgdtr
5034 (define_insn "fix_trunc<DFP:mode>di2_dfp"
5035 [(set (match_operand:DI 0 "register_operand" "=d")
5036 (fix:DI (match_operand:DFP 1 "register_operand" "f")))
5037 (unspec:DI [(match_operand:DI 2 "immediate_operand" "K")] UNSPEC_ROUND)
5038 (clobber (reg:CC CC_REGNUM))]
5039 "TARGET_ZARCH && TARGET_HARD_DFP"
5040 "cg<DFP:xde>tr\t%0,%h2,%1"
5041 [(set_attr "op_type" "RRF")
5042 (set_attr "type" "ftoidfp")])
5043
5044
5045 ;
5046 ; fix_trunctf(si|di)2 instruction pattern(s).
5047 ;
5048
5049 (define_expand "fix_trunctf<mode>2"
5050 [(parallel [(set (match_operand:GPR 0 "register_operand" "")
5051 (fix:GPR (match_operand:TF 1 "register_operand" "")))
5052 (unspec:GPR [(const_int BFP_RND_TOWARD_0)] UNSPEC_ROUND)
5053 (clobber (reg:CC CC_REGNUM))])]
5054 "TARGET_HARD_FLOAT"
5055 "")
5056
5057
5058 ;
5059 ; float(si|di)(tf|df|sf|td|dd)2 instruction pattern(s).
5060 ;
5061
5062 ; cxgbr, cdgbr, cegbr, cxgtr, cdgtr
5063 (define_insn "floatdi<mode>2"
5064 [(set (match_operand:FP 0 "register_operand" "=f,v")
5065 (float:FP (match_operand:DI 1 "register_operand" "d,v")))]
5066 "TARGET_ZARCH && TARGET_HARD_FLOAT"
5067 "@
5068 c<xde>g<bt>r\t%0,%1
5069 wcdgb\t%v0,%v1,0,0"
5070 [(set_attr "op_type" "RRE,VRR")
5071 (set_attr "type" "itof<mode>" )
5072 (set_attr "cpu_facility" "*,vx")
5073 (set_attr "enabled" "*,<DFDI>")])
5074
5075 ; cxfbr, cdfbr, cefbr
5076 (define_insn "floatsi<mode>2"
5077 [(set (match_operand:BFP 0 "register_operand" "=f")
5078 (float:BFP (match_operand:SI 1 "register_operand" "d")))]
5079 "TARGET_HARD_FLOAT"
5080 "c<xde>fbr\t%0,%1"
5081 [(set_attr "op_type" "RRE")
5082 (set_attr "type" "itof<mode>" )])
5083
5084 ; cxftr, cdftr
5085 (define_insn "floatsi<mode>2"
5086 [(set (match_operand:DFP 0 "register_operand" "=f")
5087 (float:DFP (match_operand:SI 1 "register_operand" "d")))]
5088 "TARGET_Z196 && TARGET_HARD_FLOAT"
5089 "c<xde>ftr\t%0,0,%1,0"
5090 [(set_attr "op_type" "RRE")
5091 (set_attr "type" "itof<mode>" )])
5092
5093 ;
5094 ; floatuns(si|di)(tf|df|sf|td|dd)2 instruction pattern(s).
5095 ;
5096
5097 (define_insn "*floatunsdidf2_z13"
5098 [(set (match_operand:DF 0 "register_operand" "=f,v")
5099 (unsigned_float:DF (match_operand:DI 1 "register_operand" "d,v")))]
5100 "TARGET_VX && TARGET_HARD_FLOAT"
5101 "@
5102 cdlgbr\t%0,0,%1,0
5103 wcdlgb\t%v0,%v1,0,0"
5104 [(set_attr "op_type" "RRE,VRR")
5105 (set_attr "type" "itofdf")])
5106
5107 ; cxlgbr, cdlgbr, celgbr, cxlgtr, cdlgtr
5108 ; cxlfbr, cdlfbr, celfbr, cxlftr, cdlftr
5109 (define_insn "*floatuns<GPR:mode><FP:mode>2"
5110 [(set (match_operand:FP 0 "register_operand" "=f")
5111 (unsigned_float:FP (match_operand:GPR 1 "register_operand" "d")))]
5112 "TARGET_Z196 && TARGET_HARD_FLOAT
5113 && (!TARGET_VX || <FP:MODE>mode != DFmode || <GPR:MODE>mode != DImode)"
5114 "c<FP:xde>l<GPR:gf><FP:bt>r\t%0,0,%1,0"
5115 [(set_attr "op_type" "RRE")
5116 (set_attr "type" "itof<FP:mode>")])
5117
5118 (define_expand "floatuns<GPR:mode><FP:mode>2"
5119 [(set (match_operand:FP 0 "register_operand" "")
5120 (unsigned_float:FP (match_operand:GPR 1 "register_operand" "")))]
5121 "TARGET_Z196 && TARGET_HARD_FLOAT")
5122
5123 ;
5124 ; truncdfsf2 instruction pattern(s).
5125 ;
5126
5127 (define_insn "truncdfsf2"
5128 [(set (match_operand:SF 0 "register_operand" "=f,v")
5129 (float_truncate:SF (match_operand:DF 1 "register_operand" "f,v")))]
5130 "TARGET_HARD_FLOAT"
5131 "@
5132 ledbr\t%0,%1
5133 wledb\t%v0,%v1,0,0" ; IEEE inexact exception not suppressed
5134 ; According to BFP rounding mode
5135 [(set_attr "op_type" "RRE,VRR")
5136 (set_attr "type" "ftruncdf")
5137 (set_attr "cpu_facility" "*,vx")])
5138
5139 ;
5140 ; trunctf(df|sf)2 instruction pattern(s).
5141 ;
5142
5143 ; ldxbr, lexbr
5144 (define_insn "trunctf<mode>2"
5145 [(set (match_operand:DSF 0 "register_operand" "=f")
5146 (float_truncate:DSF (match_operand:TF 1 "register_operand" "f")))
5147 (clobber (match_scratch:TF 2 "=f"))]
5148 "TARGET_HARD_FLOAT"
5149 "l<xde>xbr\t%2,%1\;l<xde>r\t%0,%2"
5150 [(set_attr "length" "6")
5151 (set_attr "type" "ftrunctf")])
5152
5153 ;
5154 ; trunctddd2 and truncddsd2 instruction pattern(s).
5155 ;
5156
5157
5158 (define_expand "trunctddd2"
5159 [(parallel
5160 [(set (match_operand:DD 0 "register_operand" "")
5161 (float_truncate:DD (match_operand:TD 1 "register_operand" "")))
5162 (unspec:DI [(const_int DFP_RND_CURRENT)] UNSPEC_ROUND)
5163 (clobber (scratch:TD))])]
5164 "TARGET_HARD_DFP")
5165
5166 (define_insn "*trunctddd2"
5167 [(set (match_operand:DD 0 "register_operand" "=f")
5168 (float_truncate:DD (match_operand:TD 1 "register_operand" "f")))
5169 (unspec:DI [(match_operand:DI 2 "const_mask_operand" "I")] UNSPEC_ROUND)
5170 (clobber (match_scratch:TD 3 "=f"))]
5171 "TARGET_HARD_DFP"
5172 "ldxtr\t%3,%2,%1,0\;ldr\t%0,%3"
5173 [(set_attr "length" "6")
5174 (set_attr "type" "ftruncdd")])
5175
5176 (define_insn "truncddsd2"
5177 [(set (match_operand:SD 0 "register_operand" "=f")
5178 (float_truncate:SD (match_operand:DD 1 "register_operand" "f")))]
5179 "TARGET_HARD_DFP"
5180 "ledtr\t%0,0,%1,0"
5181 [(set_attr "op_type" "RRF")
5182 (set_attr "type" "ftruncsd")])
5183
5184 (define_expand "trunctdsd2"
5185 [(parallel
5186 [(set (match_dup 2)
5187 (float_truncate:DD (match_operand:TD 1 "register_operand" "")))
5188 (unspec:DI [(const_int DFP_RND_PREP_FOR_SHORT_PREC)] UNSPEC_ROUND)
5189 (clobber (match_scratch:TD 3 ""))])
5190 (set (match_operand:SD 0 "register_operand" "")
5191 (float_truncate:SD (match_dup 2)))]
5192 "TARGET_HARD_DFP"
5193 {
5194 operands[2] = gen_reg_rtx (DDmode);
5195 })
5196
5197 ;
5198 ; extend(sf|df)(df|tf)2 instruction pattern(s).
5199 ;
5200
5201 ; wflls
5202 (define_insn "*extendsfdf2_z13"
5203 [(set (match_operand:DF 0 "register_operand" "=f,f,v")
5204 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "f,R,v")))]
5205 "TARGET_VX && TARGET_HARD_FLOAT"
5206 "@
5207 ldebr\t%0,%1
5208 ldeb\t%0,%1
5209 wldeb\t%v0,%v1"
5210 [(set_attr "op_type" "RRE,RXE,VRR")
5211 (set_attr "type" "fsimpdf, floaddf,fsimpdf")])
5212
5213 ; ldebr, ldeb, lxdbr, lxdb, lxebr, lxeb
5214 (define_insn "*extend<DSF:mode><BFP:mode>2"
5215 [(set (match_operand:BFP 0 "register_operand" "=f,f")
5216 (float_extend:BFP (match_operand:DSF 1 "nonimmediate_operand" "f,R")))]
5217 "TARGET_HARD_FLOAT
5218 && GET_MODE_SIZE (<BFP:MODE>mode) > GET_MODE_SIZE (<DSF:MODE>mode)
5219 && (!TARGET_VX || <BFP:MODE>mode != DFmode || <DSF:MODE>mode != SFmode)"
5220 "@
5221 l<BFP:xde><DSF:xde>br\t%0,%1
5222 l<BFP:xde><DSF:xde>b\t%0,%1"
5223 [(set_attr "op_type" "RRE,RXE")
5224 (set_attr "type" "fsimp<BFP:mode>, fload<BFP:mode>")])
5225
5226 (define_expand "extend<DSF:mode><BFP:mode>2"
5227 [(set (match_operand:BFP 0 "register_operand" "")
5228 (float_extend:BFP (match_operand:DSF 1 "nonimmediate_operand" "")))]
5229 "TARGET_HARD_FLOAT
5230 && GET_MODE_SIZE (<BFP:MODE>mode) > GET_MODE_SIZE (<DSF:MODE>mode)")
5231
5232 ;
5233 ; extendddtd2 and extendsddd2 instruction pattern(s).
5234 ;
5235
5236 (define_insn "extendddtd2"
5237 [(set (match_operand:TD 0 "register_operand" "=f")
5238 (float_extend:TD (match_operand:DD 1 "register_operand" "f")))]
5239 "TARGET_HARD_DFP"
5240 "lxdtr\t%0,%1,0"
5241 [(set_attr "op_type" "RRF")
5242 (set_attr "type" "fsimptf")])
5243
5244 (define_insn "extendsddd2"
5245 [(set (match_operand:DD 0 "register_operand" "=f")
5246 (float_extend:DD (match_operand:SD 1 "register_operand" "f")))]
5247 "TARGET_HARD_DFP"
5248 "ldetr\t%0,%1,0"
5249 [(set_attr "op_type" "RRF")
5250 (set_attr "type" "fsimptf")])
5251
5252 (define_expand "extendsdtd2"
5253 [(set (match_dup 2)
5254 (float_extend:DD (match_operand:SD 1 "register_operand" "")))
5255 (set (match_operand:TD 0 "register_operand" "")
5256 (float_extend:TD (match_dup 2)))]
5257 "TARGET_HARD_DFP"
5258 {
5259 operands[2] = gen_reg_rtx (DDmode);
5260 })
5261
5262 ; Binary Floating Point - load fp integer
5263
5264 ; Expanders for: floor, btrunc, round, ceil, and nearbyint
5265 ; For all of them the inexact exceptions are suppressed.
5266
5267 ; fiebra, fidbra, fixbra
5268 (define_insn "<FPINT:fpint_name><BFP:mode>2"
5269 [(set (match_operand:BFP 0 "register_operand" "=f")
5270 (unspec:BFP [(match_operand:BFP 1 "register_operand" "f")]
5271 FPINT))]
5272 "TARGET_Z196"
5273 "fi<BFP:xde>bra\t%0,<FPINT:fpint_roundingmode>,%1,4"
5274 [(set_attr "op_type" "RRF")
5275 (set_attr "type" "fsimp<BFP:mode>")])
5276
5277 ; rint is supposed to raise an inexact exception so we can use the
5278 ; older instructions.
5279
5280 ; fiebr, fidbr, fixbr
5281 (define_insn "rint<BFP:mode>2"
5282 [(set (match_operand:BFP 0 "register_operand" "=f")
5283 (unspec:BFP [(match_operand:BFP 1 "register_operand" "f")]
5284 UNSPEC_FPINT_RINT))]
5285 ""
5286 "fi<BFP:xde>br\t%0,0,%1"
5287 [(set_attr "op_type" "RRF")
5288 (set_attr "type" "fsimp<BFP:mode>")])
5289
5290
5291 ; Decimal Floating Point - load fp integer
5292
5293 ; fidtr, fixtr
5294 (define_insn "<FPINT:fpint_name><DFP:mode>2"
5295 [(set (match_operand:DFP 0 "register_operand" "=f")
5296 (unspec:DFP [(match_operand:DFP 1 "register_operand" "f")]
5297 FPINT))]
5298 "TARGET_HARD_DFP"
5299 "fi<DFP:xde>tr\t%0,<FPINT:fpint_roundingmode>,%1,4"
5300 [(set_attr "op_type" "RRF")
5301 (set_attr "type" "fsimp<DFP:mode>")])
5302
5303 ; fidtr, fixtr
5304 (define_insn "rint<DFP:mode>2"
5305 [(set (match_operand:DFP 0 "register_operand" "=f")
5306 (unspec:DFP [(match_operand:DFP 1 "register_operand" "f")]
5307 UNSPEC_FPINT_RINT))]
5308 "TARGET_HARD_DFP"
5309 "fi<DFP:xde>tr\t%0,0,%1,0"
5310 [(set_attr "op_type" "RRF")
5311 (set_attr "type" "fsimp<DFP:mode>")])
5312
5313 ;
5314 ; Binary <-> Decimal floating point trunc patterns
5315 ;
5316
5317 (define_insn "*trunc<BFP:mode><DFP_ALL:mode>2"
5318 [(set (reg:DFP_ALL FPR0_REGNUM)
5319 (float_truncate:DFP_ALL (reg:BFP FPR4_REGNUM)))
5320 (use (reg:SI GPR0_REGNUM))
5321 (clobber (reg:CC CC_REGNUM))
5322 (clobber (reg:SI GPR1_REGNUM))]
5323 "TARGET_HARD_DFP"
5324 "pfpo")
5325
5326 (define_insn "*trunc<DFP_ALL:mode><BFP:mode>2"
5327 [(set (reg:BFP FPR0_REGNUM)
5328 (float_truncate:BFP (reg:DFP_ALL FPR4_REGNUM)))
5329 (use (reg:SI GPR0_REGNUM))
5330 (clobber (reg:CC CC_REGNUM))
5331 (clobber (reg:SI GPR1_REGNUM))]
5332 "TARGET_HARD_DFP"
5333 "pfpo")
5334
5335 (define_expand "trunc<BFP:mode><DFP_ALL:mode>2"
5336 [(set (reg:BFP FPR4_REGNUM) (match_operand:BFP 1 "nonimmediate_operand" ""))
5337 (set (reg:SI GPR0_REGNUM) (match_dup 2))
5338 (parallel
5339 [(set (reg:DFP_ALL FPR0_REGNUM)
5340 (float_truncate:DFP_ALL (reg:BFP FPR4_REGNUM)))
5341 (use (reg:SI GPR0_REGNUM))
5342 (clobber (reg:CC CC_REGNUM))
5343 (clobber (reg:SI GPR1_REGNUM))])
5344 (set (match_operand:DFP_ALL 0 "nonimmediate_operand" "")
5345 (reg:DFP_ALL FPR0_REGNUM))]
5346 "TARGET_HARD_DFP
5347 && GET_MODE_SIZE (<BFP:MODE>mode) > GET_MODE_SIZE (<DFP_ALL:MODE>mode)"
5348 {
5349 HOST_WIDE_INT flags;
5350
5351 flags = (PFPO_CONVERT |
5352 PFPO_OP_TYPE_<DFP_ALL:MODE> << PFPO_OP0_TYPE_SHIFT |
5353 PFPO_OP_TYPE_<BFP:MODE> << PFPO_OP1_TYPE_SHIFT);
5354
5355 operands[2] = GEN_INT (flags);
5356 })
5357
5358 (define_expand "trunc<DFP_ALL:mode><BFP:mode>2"
5359 [(set (reg:DFP_ALL FPR4_REGNUM)
5360 (match_operand:DFP_ALL 1 "nonimmediate_operand" ""))
5361 (set (reg:SI GPR0_REGNUM) (match_dup 2))
5362 (parallel
5363 [(set (reg:BFP FPR0_REGNUM) (float_truncate:BFP (reg:DFP_ALL FPR4_REGNUM)))
5364 (use (reg:SI GPR0_REGNUM))
5365 (clobber (reg:CC CC_REGNUM))
5366 (clobber (reg:SI GPR1_REGNUM))])
5367 (set (match_operand:BFP 0 "nonimmediate_operand" "") (reg:BFP FPR0_REGNUM))]
5368 "TARGET_HARD_DFP
5369 && GET_MODE_SIZE (<DFP_ALL:MODE>mode) >= GET_MODE_SIZE (<BFP:MODE>mode)"
5370 {
5371 HOST_WIDE_INT flags;
5372
5373 flags = (PFPO_CONVERT |
5374 PFPO_OP_TYPE_<BFP:MODE> << PFPO_OP0_TYPE_SHIFT |
5375 PFPO_OP_TYPE_<DFP_ALL:MODE> << PFPO_OP1_TYPE_SHIFT);
5376
5377 operands[2] = GEN_INT (flags);
5378 })
5379
5380 ;
5381 ; Binary <-> Decimal floating point extend patterns
5382 ;
5383
5384 (define_insn "*extend<BFP:mode><DFP_ALL:mode>2"
5385 [(set (reg:DFP_ALL FPR0_REGNUM) (float_extend:DFP_ALL (reg:BFP FPR4_REGNUM)))
5386 (use (reg:SI GPR0_REGNUM))
5387 (clobber (reg:CC CC_REGNUM))
5388 (clobber (reg:SI GPR1_REGNUM))]
5389 "TARGET_HARD_DFP"
5390 "pfpo")
5391
5392 (define_insn "*extend<DFP_ALL:mode><BFP:mode>2"
5393 [(set (reg:BFP FPR0_REGNUM) (float_extend:BFP (reg:DFP_ALL FPR4_REGNUM)))
5394 (use (reg:SI GPR0_REGNUM))
5395 (clobber (reg:CC CC_REGNUM))
5396 (clobber (reg:SI GPR1_REGNUM))]
5397 "TARGET_HARD_DFP"
5398 "pfpo")
5399
5400 (define_expand "extend<BFP:mode><DFP_ALL:mode>2"
5401 [(set (reg:BFP FPR4_REGNUM) (match_operand:BFP 1 "nonimmediate_operand" ""))
5402 (set (reg:SI GPR0_REGNUM) (match_dup 2))
5403 (parallel
5404 [(set (reg:DFP_ALL FPR0_REGNUM)
5405 (float_extend:DFP_ALL (reg:BFP FPR4_REGNUM)))
5406 (use (reg:SI GPR0_REGNUM))
5407 (clobber (reg:CC CC_REGNUM))
5408 (clobber (reg:SI GPR1_REGNUM))])
5409 (set (match_operand:DFP_ALL 0 "nonimmediate_operand" "")
5410 (reg:DFP_ALL FPR0_REGNUM))]
5411 "TARGET_HARD_DFP
5412 && GET_MODE_SIZE (<BFP:MODE>mode) <= GET_MODE_SIZE (<DFP_ALL:MODE>mode)"
5413 {
5414 HOST_WIDE_INT flags;
5415
5416 flags = (PFPO_CONVERT |
5417 PFPO_OP_TYPE_<DFP_ALL:MODE> << PFPO_OP0_TYPE_SHIFT |
5418 PFPO_OP_TYPE_<BFP:MODE> << PFPO_OP1_TYPE_SHIFT);
5419
5420 operands[2] = GEN_INT (flags);
5421 })
5422
5423 (define_expand "extend<DFP_ALL:mode><BFP:mode>2"
5424 [(set (reg:DFP_ALL FPR4_REGNUM)
5425 (match_operand:DFP_ALL 1 "nonimmediate_operand" ""))
5426 (set (reg:SI GPR0_REGNUM) (match_dup 2))
5427 (parallel
5428 [(set (reg:BFP FPR0_REGNUM) (float_extend:BFP (reg:DFP_ALL FPR4_REGNUM)))
5429 (use (reg:SI GPR0_REGNUM))
5430 (clobber (reg:CC CC_REGNUM))
5431 (clobber (reg:SI GPR1_REGNUM))])
5432 (set (match_operand:BFP 0 "nonimmediate_operand" "") (reg:BFP FPR0_REGNUM))]
5433 "TARGET_HARD_DFP
5434 && GET_MODE_SIZE (<DFP_ALL:MODE>mode) < GET_MODE_SIZE (<BFP:MODE>mode)"
5435 {
5436 HOST_WIDE_INT flags;
5437
5438 flags = (PFPO_CONVERT |
5439 PFPO_OP_TYPE_<BFP:MODE> << PFPO_OP0_TYPE_SHIFT |
5440 PFPO_OP_TYPE_<DFP_ALL:MODE> << PFPO_OP1_TYPE_SHIFT);
5441
5442 operands[2] = GEN_INT (flags);
5443 })
5444
5445
5446 ;;
5447 ;; ARITHMETIC OPERATIONS
5448 ;;
5449 ; arithmetic operations set the ConditionCode,
5450 ; because of unpredictable Bits in Register for Halfword and Byte
5451 ; the ConditionCode can be set wrong in operations for Halfword and Byte
5452
5453 ;;
5454 ;;- Add instructions.
5455 ;;
5456
5457 ;
5458 ; addti3 instruction pattern(s).
5459 ;
5460
5461 (define_expand "addti3"
5462 [(parallel
5463 [(set (match_operand:TI 0 "register_operand" "")
5464 (plus:TI (match_operand:TI 1 "nonimmediate_operand" "")
5465 (match_operand:TI 2 "general_operand" "") ) )
5466 (clobber (reg:CC CC_REGNUM))])]
5467 "TARGET_ZARCH"
5468 {
5469 /* For z13 we have vaq which doesn't set CC. */
5470 if (TARGET_VX)
5471 {
5472 emit_insn (gen_rtx_SET (operands[0],
5473 gen_rtx_PLUS (TImode,
5474 copy_to_mode_reg (TImode, operands[1]),
5475 copy_to_mode_reg (TImode, operands[2]))));
5476 DONE;
5477 }
5478 })
5479
5480 (define_insn_and_split "*addti3"
5481 [(set (match_operand:TI 0 "register_operand" "=&d")
5482 (plus:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
5483 (match_operand:TI 2 "general_operand" "do") ) )
5484 (clobber (reg:CC CC_REGNUM))]
5485 "TARGET_ZARCH"
5486 "#"
5487 "&& reload_completed"
5488 [(parallel
5489 [(set (reg:CCL1 CC_REGNUM)
5490 (compare:CCL1 (plus:DI (match_dup 7) (match_dup 8))
5491 (match_dup 7)))
5492 (set (match_dup 6) (plus:DI (match_dup 7) (match_dup 8)))])
5493 (parallel
5494 [(set (match_dup 3) (plus:DI
5495 (plus:DI (ltu:DI (reg:CCL1 CC_REGNUM) (const_int 0))
5496 (match_dup 4)) (match_dup 5)))
5497 (clobber (reg:CC CC_REGNUM))])]
5498 "operands[3] = operand_subword (operands[0], 0, 0, TImode);
5499 operands[4] = operand_subword (operands[1], 0, 0, TImode);
5500 operands[5] = operand_subword (operands[2], 0, 0, TImode);
5501 operands[6] = operand_subword (operands[0], 1, 0, TImode);
5502 operands[7] = operand_subword (operands[1], 1, 0, TImode);
5503 operands[8] = operand_subword (operands[2], 1, 0, TImode);"
5504 [(set_attr "op_type" "*")
5505 (set_attr "cpu_facility" "*")])
5506
5507 ;
5508 ; adddi3 instruction pattern(s).
5509 ;
5510
5511 (define_expand "adddi3"
5512 [(parallel
5513 [(set (match_operand:DI 0 "nonimmediate_operand" "")
5514 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
5515 (match_operand:DI 2 "general_operand" "")))
5516 (clobber (reg:CC CC_REGNUM))])]
5517 ""
5518 "")
5519
5520 (define_insn "*adddi3_sign"
5521 [(set (match_operand:DI 0 "register_operand" "=d,d")
5522 (plus:DI (sign_extend:DI (match_operand:SI 2 "general_operand" "d,T"))
5523 (match_operand:DI 1 "register_operand" "0,0")))
5524 (clobber (reg:CC CC_REGNUM))]
5525 "TARGET_ZARCH"
5526 "@
5527 agfr\t%0,%2
5528 agf\t%0,%2"
5529 [(set_attr "op_type" "RRE,RXY")
5530 (set_attr "z196prop" "z196_cracked,z196_cracked")])
5531
5532 (define_insn "*adddi3_zero_cc"
5533 [(set (reg CC_REGNUM)
5534 (compare (plus:DI (zero_extend:DI (match_operand:SI 2 "general_operand" "d,T"))
5535 (match_operand:DI 1 "register_operand" "0,0"))
5536 (const_int 0)))
5537 (set (match_operand:DI 0 "register_operand" "=d,d")
5538 (plus:DI (zero_extend:DI (match_dup 2)) (match_dup 1)))]
5539 "s390_match_ccmode (insn, CCLmode) && TARGET_ZARCH"
5540 "@
5541 algfr\t%0,%2
5542 algf\t%0,%2"
5543 [(set_attr "op_type" "RRE,RXY")
5544 (set_attr "z10prop" "z10_super_E1,z10_super_E1")])
5545
5546 (define_insn "*adddi3_zero_cconly"
5547 [(set (reg CC_REGNUM)
5548 (compare (plus:DI (zero_extend:DI (match_operand:SI 2 "general_operand" "d,T"))
5549 (match_operand:DI 1 "register_operand" "0,0"))
5550 (const_int 0)))
5551 (clobber (match_scratch:DI 0 "=d,d"))]
5552 "s390_match_ccmode (insn, CCLmode) && TARGET_ZARCH"
5553 "@
5554 algfr\t%0,%2
5555 algf\t%0,%2"
5556 [(set_attr "op_type" "RRE,RXY")
5557 (set_attr "z10prop" "z10_super_E1,z10_super_E1")])
5558
5559 (define_insn "*adddi3_zero"
5560 [(set (match_operand:DI 0 "register_operand" "=d,d")
5561 (plus:DI (zero_extend:DI (match_operand:SI 2 "general_operand" "d,T"))
5562 (match_operand:DI 1 "register_operand" "0,0")))
5563 (clobber (reg:CC CC_REGNUM))]
5564 "TARGET_ZARCH"
5565 "@
5566 algfr\t%0,%2
5567 algf\t%0,%2"
5568 [(set_attr "op_type" "RRE,RXY")
5569 (set_attr "z10prop" "z10_super_E1,z10_super_E1")])
5570
5571 (define_insn_and_split "*adddi3_31z"
5572 [(set (match_operand:DI 0 "nonimmediate_operand" "=&d")
5573 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
5574 (match_operand:DI 2 "general_operand" "do") ) )
5575 (clobber (reg:CC CC_REGNUM))]
5576 "!TARGET_ZARCH && TARGET_CPU_ZARCH"
5577 "#"
5578 "&& reload_completed"
5579 [(parallel
5580 [(set (reg:CCL1 CC_REGNUM)
5581 (compare:CCL1 (plus:SI (match_dup 7) (match_dup 8))
5582 (match_dup 7)))
5583 (set (match_dup 6) (plus:SI (match_dup 7) (match_dup 8)))])
5584 (parallel
5585 [(set (match_dup 3) (plus:SI
5586 (plus:SI (ltu:SI (reg:CCL1 CC_REGNUM) (const_int 0))
5587 (match_dup 4)) (match_dup 5)))
5588 (clobber (reg:CC CC_REGNUM))])]
5589 "operands[3] = operand_subword (operands[0], 0, 0, DImode);
5590 operands[4] = operand_subword (operands[1], 0, 0, DImode);
5591 operands[5] = operand_subword (operands[2], 0, 0, DImode);
5592 operands[6] = operand_subword (operands[0], 1, 0, DImode);
5593 operands[7] = operand_subword (operands[1], 1, 0, DImode);
5594 operands[8] = operand_subword (operands[2], 1, 0, DImode);")
5595
5596 (define_insn_and_split "*adddi3_31"
5597 [(set (match_operand:DI 0 "nonimmediate_operand" "=&d")
5598 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
5599 (match_operand:DI 2 "general_operand" "do") ) )
5600 (clobber (reg:CC CC_REGNUM))]
5601 "!TARGET_CPU_ZARCH"
5602 "#"
5603 "&& reload_completed"
5604 [(parallel
5605 [(set (match_dup 3) (plus:SI (match_dup 4) (match_dup 5)))
5606 (clobber (reg:CC CC_REGNUM))])
5607 (parallel
5608 [(set (reg:CCL1 CC_REGNUM)
5609 (compare:CCL1 (plus:SI (match_dup 7) (match_dup 8))
5610 (match_dup 7)))
5611 (set (match_dup 6) (plus:SI (match_dup 7) (match_dup 8)))])
5612 (set (pc)
5613 (if_then_else (ltu (reg:CCL1 CC_REGNUM) (const_int 0))
5614 (pc)
5615 (label_ref (match_dup 9))))
5616 (parallel
5617 [(set (match_dup 3) (plus:SI (match_dup 3) (const_int 1)))
5618 (clobber (reg:CC CC_REGNUM))])
5619 (match_dup 9)]
5620 "operands[3] = operand_subword (operands[0], 0, 0, DImode);
5621 operands[4] = operand_subword (operands[1], 0, 0, DImode);
5622 operands[5] = operand_subword (operands[2], 0, 0, DImode);
5623 operands[6] = operand_subword (operands[0], 1, 0, DImode);
5624 operands[7] = operand_subword (operands[1], 1, 0, DImode);
5625 operands[8] = operand_subword (operands[2], 1, 0, DImode);
5626 operands[9] = gen_label_rtx ();")
5627
5628 ;
5629 ; addsi3 instruction pattern(s).
5630 ;
5631
5632 (define_expand "addsi3"
5633 [(parallel
5634 [(set (match_operand:SI 0 "nonimmediate_operand" "")
5635 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "")
5636 (match_operand:SI 2 "general_operand" "")))
5637 (clobber (reg:CC CC_REGNUM))])]
5638 ""
5639 "")
5640
5641 (define_insn "*addsi3_sign"
5642 [(set (match_operand:SI 0 "register_operand" "=d,d")
5643 (plus:SI (sign_extend:SI (match_operand:HI 2 "memory_operand" "R,T"))
5644 (match_operand:SI 1 "register_operand" "0,0")))
5645 (clobber (reg:CC CC_REGNUM))]
5646 ""
5647 "@
5648 ah\t%0,%2
5649 ahy\t%0,%2"
5650 [(set_attr "op_type" "RX,RXY")
5651 (set_attr "cpu_facility" "*,longdisp")
5652 (set_attr "z196prop" "z196_cracked,z196_cracked")])
5653
5654 ;
5655 ; add(di|si)3 instruction pattern(s).
5656 ;
5657
5658 ; ark, agrk, ar, ahi, ahik, aghik, alfi, slfi, a, ay, agr, aghi, algfi, slgfi, ag, asi, agsi
5659 (define_insn "*add<mode>3"
5660 [(set (match_operand:GPR 0 "nonimmediate_operand" "=d,d,d,d, d, d,d,d,S")
5661 (plus:GPR (match_operand:GPR 1 "nonimmediate_operand" "%0,d,0,d, 0, 0,0,0,0")
5662 (match_operand:GPR 2 "general_operand" " d,d,K,K,Op,On,R,T,C") ) )
5663 (clobber (reg:CC CC_REGNUM))]
5664 ""
5665 "@
5666 a<g>r\t%0,%2
5667 a<g>rk\t%0,%1,%2
5668 a<g>hi\t%0,%h2
5669 a<g>hik\t%0,%1,%h2
5670 al<g>fi\t%0,%2
5671 sl<g>fi\t%0,%n2
5672 a<g>\t%0,%2
5673 a<y>\t%0,%2
5674 a<g>si\t%0,%c2"
5675 [(set_attr "op_type" "RR<E>,RRF,RI,RIE,RIL,RIL,RX<Y>,RXY,SIY")
5676 (set_attr "cpu_facility" "*,z196,*,z196,extimm,extimm,*,longdisp,z10")
5677 (set_attr "z10prop" "z10_super_E1,*,z10_super_E1,*,z10_super_E1,z10_super_E1,
5678 z10_super_E1,z10_super_E1,z10_super_E1")])
5679
5680 ; alr, alfi, slfi, al, aly, alrk, alhsik, algr, algfi, slgfi, alg, alsi, algsi, algrk, alghsik
5681 (define_insn "*add<mode>3_carry1_cc"
5682 [(set (reg CC_REGNUM)
5683 (compare (plus:GPR (match_operand:GPR 1 "nonimmediate_operand" "%0,d, 0, 0,d,0,0,0")
5684 (match_operand:GPR 2 "general_operand" " d,d,Op,On,K,R,T,C"))
5685 (match_dup 1)))
5686 (set (match_operand:GPR 0 "nonimmediate_operand" "=d,d, d, d,d,d,d,d")
5687 (plus:GPR (match_dup 1) (match_dup 2)))]
5688 "s390_match_ccmode (insn, CCL1mode)"
5689 "@
5690 al<g>r\t%0,%2
5691 al<g>rk\t%0,%1,%2
5692 al<g>fi\t%0,%2
5693 sl<g>fi\t%0,%n2
5694 al<g>hsik\t%0,%1,%h2
5695 al<g>\t%0,%2
5696 al<y>\t%0,%2
5697 al<g>si\t%0,%c2"
5698 [(set_attr "op_type" "RR<E>,RRF,RIL,RIL,RIE,RX<Y>,RXY,SIY")
5699 (set_attr "cpu_facility" "*,z196,extimm,extimm,z196,*,longdisp,z10")
5700 (set_attr "z10prop" "z10_super_E1,*,z10_super_E1,z10_super_E1,*,
5701 z10_super_E1,z10_super_E1,z10_super_E1")])
5702
5703 ; alr, al, aly, algr, alg, alrk, algrk
5704 (define_insn "*add<mode>3_carry1_cconly"
5705 [(set (reg CC_REGNUM)
5706 (compare (plus:GPR (match_operand:GPR 1 "nonimmediate_operand" "%0,d,0,0")
5707 (match_operand:GPR 2 "general_operand" "d,d,R,T"))
5708 (match_dup 1)))
5709 (clobber (match_scratch:GPR 0 "=d,d,d,d"))]
5710 "s390_match_ccmode (insn, CCL1mode)"
5711 "@
5712 al<g>r\t%0,%2
5713 al<g>rk\t%0,%1,%2
5714 al<g>\t%0,%2
5715 al<y>\t%0,%2"
5716 [(set_attr "op_type" "RR<E>,RRF,RX<Y>,RXY")
5717 (set_attr "cpu_facility" "*,z196,*,longdisp")
5718 (set_attr "z10prop" "z10_super_E1,*,z10_super_E1,z10_super_E1")])
5719
5720 ; alr, alfi, slfi, al, aly, algr, algfi, slgfi, alg, alsi, algsi, alrk, algrk, alhsik, alghsik
5721 (define_insn "*add<mode>3_carry2_cc"
5722 [(set (reg CC_REGNUM)
5723 (compare (plus:GPR (match_operand:GPR 1 "nonimmediate_operand" "%0,d, 0, 0,d,0,0,0")
5724 (match_operand:GPR 2 "general_operand" " d,d,Op,On,K,R,T,C"))
5725 (match_dup 2)))
5726 (set (match_operand:GPR 0 "nonimmediate_operand" "=d,d, d, d,d,d,d,S")
5727 (plus:GPR (match_dup 1) (match_dup 2)))]
5728 "s390_match_ccmode (insn, CCL1mode)"
5729 "@
5730 al<g>r\t%0,%2
5731 al<g>rk\t%0,%1,%2
5732 al<g>fi\t%0,%2
5733 sl<g>fi\t%0,%n2
5734 al<g>hsik\t%0,%1,%h2
5735 al<g>\t%0,%2
5736 al<y>\t%0,%2
5737 al<g>si\t%0,%c2"
5738 [(set_attr "op_type" "RR<E>,RRF,RIL,RIL,RIE,RX<Y>,RXY,SIY")
5739 (set_attr "cpu_facility" "*,z196,extimm,extimm,z196,*,longdisp,z10")
5740 (set_attr "z10prop" "z10_super_E1,*,z10_super_E1,z10_super_E1,*,
5741 z10_super_E1,z10_super_E1,z10_super_E1")])
5742
5743 ; alr, al, aly, algr, alg, alrk, algrk
5744 (define_insn "*add<mode>3_carry2_cconly"
5745 [(set (reg CC_REGNUM)
5746 (compare (plus:GPR (match_operand:GPR 1 "nonimmediate_operand" "%0,d,0,0")
5747 (match_operand:GPR 2 "general_operand" "d,d,R,T"))
5748 (match_dup 2)))
5749 (clobber (match_scratch:GPR 0 "=d,d,d,d"))]
5750 "s390_match_ccmode (insn, CCL1mode)"
5751 "@
5752 al<g>r\t%0,%2
5753 al<g>rk\t%0,%1,%2
5754 al<g>\t%0,%2
5755 al<y>\t%0,%2"
5756 [(set_attr "op_type" "RR<E>,RRF,RX<Y>,RXY")
5757 (set_attr "cpu_facility" "*,z196,*,longdisp")
5758 (set_attr "z10prop" "z10_super_E1,*,z10_super_E1,z10_super_E1")])
5759
5760 ; alr, alfi, slfi, al, aly, algr, algfi, slgfi, alg, alsi, algsi, alrk, algrk, alhsik, alghsik
5761 (define_insn "*add<mode>3_cc"
5762 [(set (reg CC_REGNUM)
5763 (compare (plus:GPR (match_operand:GPR 1 "nonimmediate_operand" "%0,d, 0, 0,d,0,0,0")
5764 (match_operand:GPR 2 "general_operand" " d,d,Op,On,K,R,T,C"))
5765 (const_int 0)))
5766 (set (match_operand:GPR 0 "nonimmediate_operand" "=d,d, d, d,d,d,d,S")
5767 (plus:GPR (match_dup 1) (match_dup 2)))]
5768 "s390_match_ccmode (insn, CCLmode)"
5769 "@
5770 al<g>r\t%0,%2
5771 al<g>rk\t%0,%1,%2
5772 al<g>fi\t%0,%2
5773 sl<g>fi\t%0,%n2
5774 al<g>hsik\t%0,%1,%h2
5775 al<g>\t%0,%2
5776 al<y>\t%0,%2
5777 al<g>si\t%0,%c2"
5778 [(set_attr "op_type" "RR<E>,RRF,RIL,RIL,RIE,RX<Y>,RXY,SIY")
5779 (set_attr "cpu_facility" "*,z196,extimm,extimm,z196,*,longdisp,z10")
5780 (set_attr "z10prop" "z10_super_E1,*,z10_super_E1,z10_super_E1,
5781 *,z10_super_E1,z10_super_E1,z10_super_E1")])
5782
5783 ; alr, al, aly, algr, alg, alrk, algrk
5784 (define_insn "*add<mode>3_cconly"
5785 [(set (reg CC_REGNUM)
5786 (compare (plus:GPR (match_operand:GPR 1 "nonimmediate_operand" "%0,d,0,0")
5787 (match_operand:GPR 2 "general_operand" "d,d,R,T"))
5788 (const_int 0)))
5789 (clobber (match_scratch:GPR 0 "=d,d,d,d"))]
5790 "s390_match_ccmode (insn, CCLmode)"
5791 "@
5792 al<g>r\t%0,%2
5793 al<g>rk\t%0,%1,%2
5794 al<g>\t%0,%2
5795 al<y>\t%0,%2"
5796 [(set_attr "op_type" "RR<E>,RRF,RX<Y>,RXY")
5797 (set_attr "cpu_facility" "*,z196,*,longdisp")
5798 (set_attr "z10prop" "z10_super_E1,*,z10_super_E1,z10_super_E1")])
5799
5800 ; alr, al, aly, algr, alg, alrk, algrk
5801 (define_insn "*add<mode>3_cconly2"
5802 [(set (reg CC_REGNUM)
5803 (compare (match_operand:GPR 1 "nonimmediate_operand" "%0,d,0,0")
5804 (neg:GPR (match_operand:GPR 2 "general_operand" "d,d,R,T"))))
5805 (clobber (match_scratch:GPR 0 "=d,d,d,d"))]
5806 "s390_match_ccmode(insn, CCLmode)"
5807 "@
5808 al<g>r\t%0,%2
5809 al<g>rk\t%0,%1,%2
5810 al<g>\t%0,%2
5811 al<y>\t%0,%2"
5812 [(set_attr "op_type" "RR<E>,RRF,RX<Y>,RXY")
5813 (set_attr "cpu_facility" "*,z196,*,longdisp")
5814 (set_attr "z10prop" "z10_super_E1,*,z10_super_E1,z10_super_E1")])
5815
5816 ; ahi, afi, aghi, agfi, asi, agsi
5817 (define_insn "*add<mode>3_imm_cc"
5818 [(set (reg CC_REGNUM)
5819 (compare (plus:GPR (match_operand:GPR 1 "nonimmediate_operand" " 0, d,0, 0")
5820 (match_operand:GPR 2 "const_int_operand" " K, K,Os,C"))
5821 (const_int 0)))
5822 (set (match_operand:GPR 0 "nonimmediate_operand" "=d, d,d, S")
5823 (plus:GPR (match_dup 1) (match_dup 2)))]
5824 "s390_match_ccmode (insn, CCAmode)
5825 && (CONST_OK_FOR_CONSTRAINT_P (INTVAL (operands[2]), 'K', \"K\")
5826 || (CONST_OK_FOR_CONSTRAINT_P (INTVAL (operands[2]), 'O', \"Os\")
5827 /* Avoid INT32_MIN on 32 bit. */
5828 && (!TARGET_ZARCH || INTVAL (operands[2]) != -0x7fffffff - 1)))"
5829 "@
5830 a<g>hi\t%0,%h2
5831 a<g>hik\t%0,%1,%h2
5832 a<g>fi\t%0,%2
5833 a<g>si\t%0,%c2"
5834 [(set_attr "op_type" "RI,RIE,RIL,SIY")
5835 (set_attr "cpu_facility" "*,z196,extimm,z10")
5836 (set_attr "z10prop" "z10_super_E1,*,z10_super_E1,z10_super_E1")])
5837
5838 (define_insn "*adddi3_sign"
5839 [(set (match_operand:DI 0 "register_operand" "=d")
5840 (plus:DI (sign_extend:DI (match_operand:HI 2 "memory_operand" "T"))
5841 (match_operand:DI 1 "register_operand" "0")))
5842 (clobber (reg:CC CC_REGNUM))]
5843 "TARGET_ARCH12"
5844 "agh\t%0,%2"
5845 [(set_attr "op_type" "RXY")])
5846
5847 ;
5848 ; add(tf|df|sf|td|dd)3 instruction pattern(s).
5849 ;
5850
5851 ; axbr, adbr, aebr, axb, adb, aeb, adtr, axtr
5852 ; FIXME: wfadb does not clobber cc
5853 (define_insn "add<mode>3"
5854 [(set (match_operand:FP 0 "register_operand" "=f,f,f,v,v")
5855 (plus:FP (match_operand:FP 1 "nonimmediate_operand" "%f,0,0,v,v")
5856 (match_operand:FP 2 "general_operand" "f,f,R,v,v")))
5857 (clobber (reg:CC CC_REGNUM))]
5858 "TARGET_HARD_FLOAT"
5859 "@
5860 a<xde>tr\t%0,%1,%2
5861 a<xde>br\t%0,%2
5862 a<xde>b\t%0,%2
5863 wfadb\t%v0,%v1,%v2
5864 wfasb\t%v0,%v1,%v2"
5865 [(set_attr "op_type" "RRF,RRE,RXE,VRR,VRR")
5866 (set_attr "type" "fsimp<mode>")
5867 (set_attr "cpu_facility" "*,*,*,vx,vxe")
5868 (set_attr "enabled" "<nBFP>,<nDFP>,<DSF>,<DF>,<SF>")])
5869
5870 ; axbr, adbr, aebr, axb, adb, aeb, adtr, axtr
5871 (define_insn "*add<mode>3_cc"
5872 [(set (reg CC_REGNUM)
5873 (compare (plus:FP (match_operand:FP 1 "nonimmediate_operand" "%f,0,0")
5874 (match_operand:FP 2 "general_operand" "f,f,R"))
5875 (match_operand:FP 3 "const0_operand" "")))
5876 (set (match_operand:FP 0 "register_operand" "=f,f,f")
5877 (plus:FP (match_dup 1) (match_dup 2)))]
5878 "s390_match_ccmode (insn, CCSmode) && TARGET_HARD_FLOAT"
5879 "@
5880 a<xde>tr\t%0,%1,%2
5881 a<xde>br\t%0,%2
5882 a<xde>b\t%0,%2"
5883 [(set_attr "op_type" "RRF,RRE,RXE")
5884 (set_attr "type" "fsimp<mode>")
5885 (set_attr "enabled" "<nBFP>,<nDFP>,<DSF>")])
5886
5887 ; axbr, adbr, aebr, axb, adb, aeb, adtr, axtr
5888 (define_insn "*add<mode>3_cconly"
5889 [(set (reg CC_REGNUM)
5890 (compare (plus:FP (match_operand:FP 1 "nonimmediate_operand" "%f,0,0")
5891 (match_operand:FP 2 "general_operand" "f,f,R"))
5892 (match_operand:FP 3 "const0_operand" "")))
5893 (clobber (match_scratch:FP 0 "=f,f,f"))]
5894 "s390_match_ccmode (insn, CCSmode) && TARGET_HARD_FLOAT"
5895 "@
5896 a<xde>tr\t%0,%1,%2
5897 a<xde>br\t%0,%2
5898 a<xde>b\t%0,%2"
5899 [(set_attr "op_type" "RRF,RRE,RXE")
5900 (set_attr "type" "fsimp<mode>")
5901 (set_attr "enabled" "<nBFP>,<nDFP>,<DSF>")])
5902
5903 ;
5904 ; Pointer add instruction patterns
5905 ;
5906
5907 ; This will match "*la_64"
5908 (define_expand "addptrdi3"
5909 [(set (match_operand:DI 0 "register_operand" "")
5910 (plus:DI (match_operand:DI 1 "register_operand" "")
5911 (match_operand:DI 2 "nonmemory_operand" "")))]
5912 "TARGET_64BIT"
5913 {
5914 if (GET_CODE (operands[2]) == CONST_INT)
5915 {
5916 HOST_WIDE_INT c = INTVAL (operands[2]);
5917
5918 if (!CONST_OK_FOR_CONSTRAINT_P (c, 'K', "K")
5919 && !CONST_OK_FOR_CONSTRAINT_P (c, 'O', "Os"))
5920 {
5921 operands[2] = force_const_mem (DImode, operands[2]);
5922 operands[2] = force_reg (DImode, operands[2]);
5923 }
5924 else if (!DISP_IN_RANGE (INTVAL (operands[2])))
5925 operands[2] = force_reg (DImode, operands[2]);
5926 }
5927 })
5928
5929 ; For 31 bit we have to prevent the generated pattern from matching
5930 ; normal ADDs since la only does a 31 bit add. This is supposed to
5931 ; match "force_la_31".
5932 (define_expand "addptrsi3"
5933 [(parallel
5934 [(set (match_operand:SI 0 "register_operand" "")
5935 (plus:SI (match_operand:SI 1 "register_operand" "")
5936 (match_operand:SI 2 "nonmemory_operand" "")))
5937 (use (const_int 0))])]
5938 "!TARGET_64BIT"
5939 {
5940 if (GET_CODE (operands[2]) == CONST_INT)
5941 {
5942 HOST_WIDE_INT c = INTVAL (operands[2]);
5943
5944 if (!CONST_OK_FOR_CONSTRAINT_P (c, 'K', "K")
5945 && !CONST_OK_FOR_CONSTRAINT_P (c, 'O', "Os"))
5946 {
5947 operands[2] = force_const_mem (SImode, operands[2]);
5948 operands[2] = force_reg (SImode, operands[2]);
5949 }
5950 else if (!DISP_IN_RANGE (INTVAL (operands[2])))
5951 operands[2] = force_reg (SImode, operands[2]);
5952 }
5953 })
5954
5955 ;;
5956 ;;- Subtract instructions.
5957 ;;
5958
5959 ;
5960 ; subti3 instruction pattern(s).
5961 ;
5962
5963 (define_expand "subti3"
5964 [(parallel
5965 [(set (match_operand:TI 0 "register_operand" "")
5966 (minus:TI (match_operand:TI 1 "register_operand" "")
5967 (match_operand:TI 2 "general_operand" "") ) )
5968 (clobber (reg:CC CC_REGNUM))])]
5969 "TARGET_ZARCH"
5970 {
5971 /* For z13 we have vsq which doesn't set CC. */
5972 if (TARGET_VX)
5973 {
5974 emit_insn (gen_rtx_SET (operands[0],
5975 gen_rtx_MINUS (TImode,
5976 operands[1],
5977 copy_to_mode_reg (TImode, operands[2]))));
5978 DONE;
5979 }
5980 })
5981
5982 (define_insn_and_split "*subti3"
5983 [(set (match_operand:TI 0 "register_operand" "=&d")
5984 (minus:TI (match_operand:TI 1 "register_operand" "0")
5985 (match_operand:TI 2 "general_operand" "do") ) )
5986 (clobber (reg:CC CC_REGNUM))]
5987 "TARGET_ZARCH"
5988 "#"
5989 "&& reload_completed"
5990 [(parallel
5991 [(set (reg:CCL2 CC_REGNUM)
5992 (compare:CCL2 (minus:DI (match_dup 7) (match_dup 8))
5993 (match_dup 7)))
5994 (set (match_dup 6) (minus:DI (match_dup 7) (match_dup 8)))])
5995 (parallel
5996 [(set (match_dup 3) (minus:DI (minus:DI (match_dup 4) (match_dup 5))
5997 (gtu:DI (reg:CCL2 CC_REGNUM) (const_int 0))))
5998 (clobber (reg:CC CC_REGNUM))])]
5999 "operands[3] = operand_subword (operands[0], 0, 0, TImode);
6000 operands[4] = operand_subword (operands[1], 0, 0, TImode);
6001 operands[5] = operand_subword (operands[2], 0, 0, TImode);
6002 operands[6] = operand_subword (operands[0], 1, 0, TImode);
6003 operands[7] = operand_subword (operands[1], 1, 0, TImode);
6004 operands[8] = operand_subword (operands[2], 1, 0, TImode);"
6005 [(set_attr "op_type" "*")
6006 (set_attr "cpu_facility" "*")])
6007
6008 ;
6009 ; subdi3 instruction pattern(s).
6010 ;
6011
6012 (define_expand "subdi3"
6013 [(parallel
6014 [(set (match_operand:DI 0 "register_operand" "")
6015 (minus:DI (match_operand:DI 1 "register_operand" "")
6016 (match_operand:DI 2 "general_operand" "")))
6017 (clobber (reg:CC CC_REGNUM))])]
6018 ""
6019 "")
6020
6021 (define_insn "*subdi3_sign"
6022 [(set (match_operand:DI 0 "register_operand" "=d,d")
6023 (minus:DI (match_operand:DI 1 "register_operand" "0,0")
6024 (sign_extend:DI (match_operand:SI 2 "general_operand" "d,T"))))
6025 (clobber (reg:CC CC_REGNUM))]
6026 "TARGET_ZARCH"
6027 "@
6028 sgfr\t%0,%2
6029 sgf\t%0,%2"
6030 [(set_attr "op_type" "RRE,RXY")
6031 (set_attr "z10prop" "z10_c,*")
6032 (set_attr "z196prop" "z196_cracked")])
6033
6034 (define_insn "*subdi3_zero_cc"
6035 [(set (reg CC_REGNUM)
6036 (compare (minus:DI (match_operand:DI 1 "register_operand" "0,0")
6037 (zero_extend:DI (match_operand:SI 2 "general_operand" "d,T")))
6038 (const_int 0)))
6039 (set (match_operand:DI 0 "register_operand" "=d,d")
6040 (minus:DI (match_dup 1) (zero_extend:DI (match_dup 2))))]
6041 "s390_match_ccmode (insn, CCLmode) && TARGET_ZARCH"
6042 "@
6043 slgfr\t%0,%2
6044 slgf\t%0,%2"
6045 [(set_attr "op_type" "RRE,RXY")
6046 (set_attr "z10prop" "z10_super_c_E1,z10_super_E1")])
6047
6048 (define_insn "*subdi3_zero_cconly"
6049 [(set (reg CC_REGNUM)
6050 (compare (minus:DI (match_operand:DI 1 "register_operand" "0,0")
6051 (zero_extend:DI (match_operand:SI 2 "general_operand" "d,T")))
6052 (const_int 0)))
6053 (clobber (match_scratch:DI 0 "=d,d"))]
6054 "s390_match_ccmode (insn, CCLmode) && TARGET_ZARCH"
6055 "@
6056 slgfr\t%0,%2
6057 slgf\t%0,%2"
6058 [(set_attr "op_type" "RRE,RXY")
6059 (set_attr "z10prop" "z10_super_c_E1,z10_super_E1")])
6060
6061 (define_insn "*subdi3_zero"
6062 [(set (match_operand:DI 0 "register_operand" "=d,d")
6063 (minus:DI (match_operand:DI 1 "register_operand" "0,0")
6064 (zero_extend:DI (match_operand:SI 2 "general_operand" "d,T"))))
6065 (clobber (reg:CC CC_REGNUM))]
6066 "TARGET_ZARCH"
6067 "@
6068 slgfr\t%0,%2
6069 slgf\t%0,%2"
6070 [(set_attr "op_type" "RRE,RXY")
6071 (set_attr "z10prop" "z10_super_c_E1,z10_super_E1")])
6072
6073 (define_insn_and_split "*subdi3_31z"
6074 [(set (match_operand:DI 0 "register_operand" "=&d")
6075 (minus:DI (match_operand:DI 1 "register_operand" "0")
6076 (match_operand:DI 2 "general_operand" "do") ) )
6077 (clobber (reg:CC CC_REGNUM))]
6078 "!TARGET_ZARCH && TARGET_CPU_ZARCH"
6079 "#"
6080 "&& reload_completed"
6081 [(parallel
6082 [(set (reg:CCL2 CC_REGNUM)
6083 (compare:CCL2 (minus:SI (match_dup 7) (match_dup 8))
6084 (match_dup 7)))
6085 (set (match_dup 6) (minus:SI (match_dup 7) (match_dup 8)))])
6086 (parallel
6087 [(set (match_dup 3) (minus:SI (minus:SI (match_dup 4) (match_dup 5))
6088 (gtu:SI (reg:CCL2 CC_REGNUM) (const_int 0))))
6089 (clobber (reg:CC CC_REGNUM))])]
6090 "operands[3] = operand_subword (operands[0], 0, 0, DImode);
6091 operands[4] = operand_subword (operands[1], 0, 0, DImode);
6092 operands[5] = operand_subword (operands[2], 0, 0, DImode);
6093 operands[6] = operand_subword (operands[0], 1, 0, DImode);
6094 operands[7] = operand_subword (operands[1], 1, 0, DImode);
6095 operands[8] = operand_subword (operands[2], 1, 0, DImode);")
6096
6097 (define_insn_and_split "*subdi3_31"
6098 [(set (match_operand:DI 0 "register_operand" "=&d")
6099 (minus:DI (match_operand:DI 1 "register_operand" "0")
6100 (match_operand:DI 2 "general_operand" "do") ) )
6101 (clobber (reg:CC CC_REGNUM))]
6102 "!TARGET_CPU_ZARCH"
6103 "#"
6104 "&& reload_completed"
6105 [(parallel
6106 [(set (match_dup 3) (minus:SI (match_dup 4) (match_dup 5)))
6107 (clobber (reg:CC CC_REGNUM))])
6108 (parallel
6109 [(set (reg:CCL2 CC_REGNUM)
6110 (compare:CCL2 (minus:SI (match_dup 7) (match_dup 8))
6111 (match_dup 7)))
6112 (set (match_dup 6) (minus:SI (match_dup 7) (match_dup 8)))])
6113 (set (pc)
6114 (if_then_else (gtu (reg:CCL2 CC_REGNUM) (const_int 0))
6115 (pc)
6116 (label_ref (match_dup 9))))
6117 (parallel
6118 [(set (match_dup 3) (plus:SI (match_dup 3) (const_int -1)))
6119 (clobber (reg:CC CC_REGNUM))])
6120 (match_dup 9)]
6121 "operands[3] = operand_subword (operands[0], 0, 0, DImode);
6122 operands[4] = operand_subword (operands[1], 0, 0, DImode);
6123 operands[5] = operand_subword (operands[2], 0, 0, DImode);
6124 operands[6] = operand_subword (operands[0], 1, 0, DImode);
6125 operands[7] = operand_subword (operands[1], 1, 0, DImode);
6126 operands[8] = operand_subword (operands[2], 1, 0, DImode);
6127 operands[9] = gen_label_rtx ();")
6128
6129 ;
6130 ; subsi3 instruction pattern(s).
6131 ;
6132
6133 (define_expand "subsi3"
6134 [(parallel
6135 [(set (match_operand:SI 0 "register_operand" "")
6136 (minus:SI (match_operand:SI 1 "register_operand" "")
6137 (match_operand:SI 2 "general_operand" "")))
6138 (clobber (reg:CC CC_REGNUM))])]
6139 ""
6140 "")
6141
6142 (define_insn "*subsi3_sign"
6143 [(set (match_operand:SI 0 "register_operand" "=d,d")
6144 (minus:SI (match_operand:SI 1 "register_operand" "0,0")
6145 (sign_extend:SI (match_operand:HI 2 "memory_operand" "R,T"))))
6146 (clobber (reg:CC CC_REGNUM))]
6147 ""
6148 "@
6149 sh\t%0,%2
6150 shy\t%0,%2"
6151 [(set_attr "op_type" "RX,RXY")
6152 (set_attr "cpu_facility" "*,longdisp")
6153 (set_attr "z196prop" "z196_cracked,z196_cracked")])
6154
6155 ;
6156 ; sub(di|si)3 instruction pattern(s).
6157 ;
6158
6159 ; sr, s, sy, sgr, sg, srk, sgrk
6160 (define_insn "*sub<mode>3"
6161 [(set (match_operand:GPR 0 "register_operand" "=d,d,d,d")
6162 (minus:GPR (match_operand:GPR 1 "register_operand" "0,d,0,0")
6163 (match_operand:GPR 2 "general_operand" "d,d,R,T") ) )
6164 (clobber (reg:CC CC_REGNUM))]
6165 ""
6166 "@
6167 s<g>r\t%0,%2
6168 s<g>rk\t%0,%1,%2
6169 s<g>\t%0,%2
6170 s<y>\t%0,%2"
6171 [(set_attr "op_type" "RR<E>,RRF,RX<Y>,RXY")
6172 (set_attr "cpu_facility" "*,z196,*,longdisp")
6173 (set_attr "z10prop" "z10_super_c_E1,*,z10_super_E1,z10_super_E1")])
6174
6175 ; slr, sl, sly, slgr, slg, slrk, slgrk
6176 (define_insn "*sub<mode>3_borrow_cc"
6177 [(set (reg CC_REGNUM)
6178 (compare (minus:GPR (match_operand:GPR 1 "register_operand" "0,d,0,0")
6179 (match_operand:GPR 2 "general_operand" "d,d,R,T"))
6180 (match_dup 1)))
6181 (set (match_operand:GPR 0 "register_operand" "=d,d,d,d")
6182 (minus:GPR (match_dup 1) (match_dup 2)))]
6183 "s390_match_ccmode (insn, CCL2mode)"
6184 "@
6185 sl<g>r\t%0,%2
6186 sl<g>rk\t%0,%1,%2
6187 sl<g>\t%0,%2
6188 sl<y>\t%0,%2"
6189 [(set_attr "op_type" "RR<E>,RRF,RX<Y>,RXY")
6190 (set_attr "cpu_facility" "*,z196,*,longdisp")
6191 (set_attr "z10prop" "z10_super_c_E1,*,z10_super_E1,z10_super_E1")])
6192
6193 ; slr, sl, sly, slgr, slg, slrk, slgrk
6194 (define_insn "*sub<mode>3_borrow_cconly"
6195 [(set (reg CC_REGNUM)
6196 (compare (minus:GPR (match_operand:GPR 1 "register_operand" "0,d,0,0")
6197 (match_operand:GPR 2 "general_operand" "d,d,R,T"))
6198 (match_dup 1)))
6199 (clobber (match_scratch:GPR 0 "=d,d,d,d"))]
6200 "s390_match_ccmode (insn, CCL2mode)"
6201 "@
6202 sl<g>r\t%0,%2
6203 sl<g>rk\t%0,%1,%2
6204 sl<g>\t%0,%2
6205 sl<y>\t%0,%2"
6206 [(set_attr "op_type" "RR<E>,RRF,RX<Y>,RXY")
6207 (set_attr "cpu_facility" "*,z196,*,longdisp")
6208 (set_attr "z10prop" "z10_super_c_E1,*,z10_super_E1,z10_super_E1")])
6209
6210 ; slr, sl, sly, slgr, slg, slrk, slgrk
6211 (define_insn "*sub<mode>3_cc"
6212 [(set (reg CC_REGNUM)
6213 (compare (minus:GPR (match_operand:GPR 1 "register_operand" "0,d,0,0")
6214 (match_operand:GPR 2 "general_operand" "d,d,R,T"))
6215 (const_int 0)))
6216 (set (match_operand:GPR 0 "register_operand" "=d,d,d,d")
6217 (minus:GPR (match_dup 1) (match_dup 2)))]
6218 "s390_match_ccmode (insn, CCLmode)"
6219 "@
6220 sl<g>r\t%0,%2
6221 sl<g>rk\t%0,%1,%2
6222 sl<g>\t%0,%2
6223 sl<y>\t%0,%2"
6224 [(set_attr "op_type" "RR<E>,RRF,RX<Y>,RXY")
6225 (set_attr "cpu_facility" "*,z196,*,longdisp")
6226 (set_attr "z10prop" "z10_super_c_E1,*,z10_super_E1,z10_super_E1")])
6227
6228 ; slr, sl, sly, slgr, slg, slrk, slgrk
6229 (define_insn "*sub<mode>3_cc2"
6230 [(set (reg CC_REGNUM)
6231 (compare (match_operand:GPR 1 "register_operand" "0,d,0,0")
6232 (match_operand:GPR 2 "general_operand" "d,d,R,T")))
6233 (set (match_operand:GPR 0 "register_operand" "=d,d,d,d")
6234 (minus:GPR (match_dup 1) (match_dup 2)))]
6235 "s390_match_ccmode (insn, CCL3mode)"
6236 "@
6237 sl<g>r\t%0,%2
6238 sl<g>rk\t%0,%1,%2
6239 sl<g>\t%0,%2
6240 sl<y>\t%0,%2"
6241 [(set_attr "op_type" "RR<E>,RRF,RX<Y>,RXY")
6242 (set_attr "cpu_facility" "*,z196,*,longdisp")
6243 (set_attr "z10prop" "z10_super_c_E1,*,z10_super_E1,z10_super_E1")])
6244
6245 ; slr, sl, sly, slgr, slg, slrk, slgrk
6246 (define_insn "*sub<mode>3_cconly"
6247 [(set (reg CC_REGNUM)
6248 (compare (minus:GPR (match_operand:GPR 1 "register_operand" "0,d,0,0")
6249 (match_operand:GPR 2 "general_operand" "d,d,R,T"))
6250 (const_int 0)))
6251 (clobber (match_scratch:GPR 0 "=d,d,d,d"))]
6252 "s390_match_ccmode (insn, CCLmode)"
6253 "@
6254 sl<g>r\t%0,%2
6255 sl<g>rk\t%0,%1,%2
6256 sl<g>\t%0,%2
6257 sl<y>\t%0,%2"
6258 [(set_attr "op_type" "RR<E>,RRF,RX<Y>,RXY")
6259 (set_attr "cpu_facility" "*,z196,*,longdisp")
6260 (set_attr "z10prop" "z10_super_c_E1,*,z10_super_E1,z10_super_E1")])
6261
6262
6263 ; slr, sl, sly, slgr, slg, slrk, slgrk
6264 (define_insn "*sub<mode>3_cconly2"
6265 [(set (reg CC_REGNUM)
6266 (compare (match_operand:GPR 1 "register_operand" "0,d,0,0")
6267 (match_operand:GPR 2 "general_operand" "d,d,R,T")))
6268 (clobber (match_scratch:GPR 0 "=d,d,d,d"))]
6269 "s390_match_ccmode (insn, CCL3mode)"
6270 "@
6271 sl<g>r\t%0,%2
6272 sl<g>rk\t%0,%1,%2
6273 sl<g>\t%0,%2
6274 sl<y>\t%0,%2"
6275 [(set_attr "op_type" "RR<E>,RRF,RX<Y>,RXY")
6276 (set_attr "cpu_facility" "*,z196,*,longdisp")
6277 (set_attr "z10prop" "z10_super_c_E1,*,z10_super_E1,z10_super_E1")])
6278
6279 (define_insn "*subdi3_sign"
6280 [(set (match_operand:DI 0 "register_operand" "=d")
6281 (minus:DI (match_operand:DI 1 "register_operand" "0")
6282 (sign_extend:DI (match_operand:HI 2 "memory_operand" "T"))))
6283 (clobber (reg:CC CC_REGNUM))]
6284 "TARGET_ARCH12"
6285 "sgh\t%0,%2"
6286 [(set_attr "op_type" "RXY")])
6287
6288
6289 ;
6290 ; sub(tf|df|sf|td|dd)3 instruction pattern(s).
6291 ;
6292
6293 ; FIXME: (clobber (match_scratch:CC 3 "=c,c,c,X,X")) does not work - why?
6294 ; sxbr, sdbr, sebr, sdb, seb, sxtr, sdtr
6295 (define_insn "sub<mode>3"
6296 [(set (match_operand:FP 0 "register_operand" "=f,f,f,v,v")
6297 (minus:FP (match_operand:FP 1 "register_operand" "f,0,0,v,v")
6298 (match_operand:FP 2 "general_operand" "f,f,R,v,v")))
6299 (clobber (reg:CC CC_REGNUM))]
6300 "TARGET_HARD_FLOAT"
6301 "@
6302 s<xde>tr\t%0,%1,%2
6303 s<xde>br\t%0,%2
6304 s<xde>b\t%0,%2
6305 wfsdb\t%v0,%v1,%v2
6306 wfssb\t%v0,%v1,%v2"
6307 [(set_attr "op_type" "RRF,RRE,RXE,VRR,VRR")
6308 (set_attr "type" "fsimp<mode>")
6309 (set_attr "cpu_facility" "*,*,*,vx,vxe")
6310 (set_attr "enabled" "<nBFP>,<nDFP>,<DSF>,<DF>,<SF>")])
6311
6312 ; sxbr, sdbr, sebr, sdb, seb, sxtr, sdtr
6313 (define_insn "*sub<mode>3_cc"
6314 [(set (reg CC_REGNUM)
6315 (compare (minus:FP (match_operand:FP 1 "nonimmediate_operand" "f,0,0")
6316 (match_operand:FP 2 "general_operand" "f,f,R"))
6317 (match_operand:FP 3 "const0_operand" "")))
6318 (set (match_operand:FP 0 "register_operand" "=f,f,f")
6319 (minus:FP (match_dup 1) (match_dup 2)))]
6320 "s390_match_ccmode (insn, CCSmode) && TARGET_HARD_FLOAT"
6321 "@
6322 s<xde>tr\t%0,%1,%2
6323 s<xde>br\t%0,%2
6324 s<xde>b\t%0,%2"
6325 [(set_attr "op_type" "RRF,RRE,RXE")
6326 (set_attr "type" "fsimp<mode>")
6327 (set_attr "enabled" "<nBFP>,<nDFP>,<DSF>")])
6328
6329 ; sxbr, sdbr, sebr, sdb, seb, sxtr, sdtr
6330 (define_insn "*sub<mode>3_cconly"
6331 [(set (reg CC_REGNUM)
6332 (compare (minus:FP (match_operand:FP 1 "nonimmediate_operand" "f,0,0")
6333 (match_operand:FP 2 "general_operand" "f,f,R"))
6334 (match_operand:FP 3 "const0_operand" "")))
6335 (clobber (match_scratch:FP 0 "=f,f,f"))]
6336 "s390_match_ccmode (insn, CCSmode) && TARGET_HARD_FLOAT"
6337 "@
6338 s<xde>tr\t%0,%1,%2
6339 s<xde>br\t%0,%2
6340 s<xde>b\t%0,%2"
6341 [(set_attr "op_type" "RRF,RRE,RXE")
6342 (set_attr "type" "fsimp<mode>")
6343 (set_attr "enabled" "<nBFP>,<nDFP>,<DSF>")])
6344
6345
6346 ;;
6347 ;;- Conditional add/subtract instructions.
6348 ;;
6349
6350 ;
6351 ; add(di|si)cc instruction pattern(s).
6352 ;
6353
6354 ; the following 4 patterns are used when the result of an add with
6355 ; carry is checked for an overflow condition
6356
6357 ; op1 + op2 + c < op1
6358
6359 ; alcr, alc, alcgr, alcg
6360 (define_insn "*add<mode>3_alc_carry1_cc"
6361 [(set (reg CC_REGNUM)
6362 (compare
6363 (plus:GPR (plus:GPR (match_operand:GPR 3 "s390_alc_comparison" "")
6364 (match_operand:GPR 1 "nonimmediate_operand" "%0,0"))
6365 (match_operand:GPR 2 "general_operand" "d,T"))
6366 (match_dup 1)))
6367 (set (match_operand:GPR 0 "register_operand" "=d,d")
6368 (plus:GPR (plus:GPR (match_dup 3) (match_dup 1)) (match_dup 2)))]
6369 "s390_match_ccmode (insn, CCL1mode) && TARGET_CPU_ZARCH"
6370 "@
6371 alc<g>r\t%0,%2
6372 alc<g>\t%0,%2"
6373 [(set_attr "op_type" "RRE,RXY")
6374 (set_attr "z196prop" "z196_alone,z196_alone")])
6375
6376 ; alcr, alc, alcgr, alcg
6377 (define_insn "*add<mode>3_alc_carry1_cconly"
6378 [(set (reg CC_REGNUM)
6379 (compare
6380 (plus:GPR (plus:GPR (match_operand:GPR 3 "s390_alc_comparison" "")
6381 (match_operand:GPR 1 "nonimmediate_operand" "%0,0"))
6382 (match_operand:GPR 2 "general_operand" "d,T"))
6383 (match_dup 1)))
6384 (clobber (match_scratch:GPR 0 "=d,d"))]
6385 "s390_match_ccmode (insn, CCL1mode) && TARGET_CPU_ZARCH"
6386 "@
6387 alc<g>r\t%0,%2
6388 alc<g>\t%0,%2"
6389 [(set_attr "op_type" "RRE,RXY")
6390 (set_attr "z196prop" "z196_alone,z196_alone")])
6391
6392 ; op1 + op2 + c < op2
6393
6394 ; alcr, alc, alcgr, alcg
6395 (define_insn "*add<mode>3_alc_carry2_cc"
6396 [(set (reg CC_REGNUM)
6397 (compare
6398 (plus:GPR (plus:GPR (match_operand:GPR 3 "s390_alc_comparison" "")
6399 (match_operand:GPR 1 "nonimmediate_operand" "%0,0"))
6400 (match_operand:GPR 2 "general_operand" "d,T"))
6401 (match_dup 2)))
6402 (set (match_operand:GPR 0 "register_operand" "=d,d")
6403 (plus:GPR (plus:GPR (match_dup 3) (match_dup 1)) (match_dup 2)))]
6404 "s390_match_ccmode (insn, CCL1mode) && TARGET_CPU_ZARCH"
6405 "@
6406 alc<g>r\t%0,%2
6407 alc<g>\t%0,%2"
6408 [(set_attr "op_type" "RRE,RXY")])
6409
6410 ; alcr, alc, alcgr, alcg
6411 (define_insn "*add<mode>3_alc_carry2_cconly"
6412 [(set (reg CC_REGNUM)
6413 (compare
6414 (plus:GPR (plus:GPR (match_operand:GPR 3 "s390_alc_comparison" "")
6415 (match_operand:GPR 1 "nonimmediate_operand" "%0,0"))
6416 (match_operand:GPR 2 "general_operand" "d,T"))
6417 (match_dup 2)))
6418 (clobber (match_scratch:GPR 0 "=d,d"))]
6419 "s390_match_ccmode (insn, CCL1mode) && TARGET_CPU_ZARCH"
6420 "@
6421 alc<g>r\t%0,%2
6422 alc<g>\t%0,%2"
6423 [(set_attr "op_type" "RRE,RXY")])
6424
6425 ; alcr, alc, alcgr, alcg
6426 (define_insn "*add<mode>3_alc_cc"
6427 [(set (reg CC_REGNUM)
6428 (compare
6429 (plus:GPR (plus:GPR (match_operand:GPR 3 "s390_alc_comparison" "")
6430 (match_operand:GPR 1 "nonimmediate_operand" "%0,0"))
6431 (match_operand:GPR 2 "general_operand" "d,T"))
6432 (const_int 0)))
6433 (set (match_operand:GPR 0 "register_operand" "=d,d")
6434 (plus:GPR (plus:GPR (match_dup 3) (match_dup 1)) (match_dup 2)))]
6435 "s390_match_ccmode (insn, CCLmode) && TARGET_CPU_ZARCH"
6436 "@
6437 alc<g>r\t%0,%2
6438 alc<g>\t%0,%2"
6439 [(set_attr "op_type" "RRE,RXY")])
6440
6441 ; alcr, alc, alcgr, alcg
6442 (define_insn "*add<mode>3_alc"
6443 [(set (match_operand:GPR 0 "register_operand" "=d,d")
6444 (plus:GPR (plus:GPR (match_operand:GPR 3 "s390_alc_comparison" "")
6445 (match_operand:GPR 1 "nonimmediate_operand" "%0,0"))
6446 (match_operand:GPR 2 "general_operand" "d,T")))
6447 (clobber (reg:CC CC_REGNUM))]
6448 "TARGET_CPU_ZARCH"
6449 "@
6450 alc<g>r\t%0,%2
6451 alc<g>\t%0,%2"
6452 [(set_attr "op_type" "RRE,RXY")])
6453
6454 ; slbr, slb, slbgr, slbg
6455 (define_insn "*sub<mode>3_slb_cc"
6456 [(set (reg CC_REGNUM)
6457 (compare
6458 (minus:GPR (minus:GPR (match_operand:GPR 1 "nonimmediate_operand" "0,0")
6459 (match_operand:GPR 2 "general_operand" "d,T"))
6460 (match_operand:GPR 3 "s390_slb_comparison" ""))
6461 (const_int 0)))
6462 (set (match_operand:GPR 0 "register_operand" "=d,d")
6463 (minus:GPR (minus:GPR (match_dup 1) (match_dup 2)) (match_dup 3)))]
6464 "s390_match_ccmode (insn, CCLmode) && TARGET_CPU_ZARCH"
6465 "@
6466 slb<g>r\t%0,%2
6467 slb<g>\t%0,%2"
6468 [(set_attr "op_type" "RRE,RXY")
6469 (set_attr "z10prop" "z10_c,*")])
6470
6471 ; slbr, slb, slbgr, slbg
6472 (define_insn "*sub<mode>3_slb"
6473 [(set (match_operand:GPR 0 "register_operand" "=d,d")
6474 (minus:GPR (minus:GPR (match_operand:GPR 1 "nonimmediate_operand" "0,0")
6475 (match_operand:GPR 2 "general_operand" "d,T"))
6476 (match_operand:GPR 3 "s390_slb_comparison" "")))
6477 (clobber (reg:CC CC_REGNUM))]
6478 "TARGET_CPU_ZARCH"
6479 "@
6480 slb<g>r\t%0,%2
6481 slb<g>\t%0,%2"
6482 [(set_attr "op_type" "RRE,RXY")
6483 (set_attr "z10prop" "z10_c,*")])
6484
6485 (define_expand "add<mode>cc"
6486 [(match_operand:GPR 0 "register_operand" "")
6487 (match_operand 1 "comparison_operator" "")
6488 (match_operand:GPR 2 "register_operand" "")
6489 (match_operand:GPR 3 "const_int_operand" "")]
6490 "TARGET_CPU_ZARCH"
6491 "if (!s390_expand_addcc (GET_CODE (operands[1]),
6492 XEXP (operands[1], 0), XEXP (operands[1], 1),
6493 operands[0], operands[2],
6494 operands[3])) FAIL; DONE;")
6495
6496 ;
6497 ; scond instruction pattern(s).
6498 ;
6499
6500 (define_insn_and_split "*scond<mode>"
6501 [(set (match_operand:GPR 0 "register_operand" "=&d")
6502 (match_operand:GPR 1 "s390_alc_comparison" ""))
6503 (clobber (reg:CC CC_REGNUM))]
6504 "TARGET_CPU_ZARCH"
6505 "#"
6506 "&& reload_completed"
6507 [(set (match_dup 0) (const_int 0))
6508 (parallel
6509 [(set (match_dup 0) (plus:GPR (plus:GPR (match_dup 1) (match_dup 0))
6510 (match_dup 0)))
6511 (clobber (reg:CC CC_REGNUM))])]
6512 "")
6513
6514 (define_insn_and_split "*scond<mode>_neg"
6515 [(set (match_operand:GPR 0 "register_operand" "=&d")
6516 (match_operand:GPR 1 "s390_slb_comparison" ""))
6517 (clobber (reg:CC CC_REGNUM))]
6518 "TARGET_CPU_ZARCH"
6519 "#"
6520 "&& reload_completed"
6521 [(set (match_dup 0) (const_int 0))
6522 (parallel
6523 [(set (match_dup 0) (minus:GPR (minus:GPR (match_dup 0) (match_dup 0))
6524 (match_dup 1)))
6525 (clobber (reg:CC CC_REGNUM))])
6526 (parallel
6527 [(set (match_dup 0) (neg:GPR (match_dup 0)))
6528 (clobber (reg:CC CC_REGNUM))])]
6529 "")
6530
6531
6532 (define_expand "cstore<mode>4"
6533 [(set (match_operand:SI 0 "register_operand" "")
6534 (match_operator:SI 1 "s390_scond_operator"
6535 [(match_operand:GPR 2 "register_operand" "")
6536 (match_operand:GPR 3 "general_operand" "")]))]
6537 "TARGET_CPU_ZARCH"
6538 "if (!s390_expand_addcc (GET_CODE (operands[1]), operands[2], operands[3],
6539 operands[0], const0_rtx, const1_rtx)) FAIL; DONE;")
6540
6541 (define_expand "cstorecc4"
6542 [(parallel
6543 [(set (match_operand:SI 0 "register_operand" "")
6544 (match_operator:SI 1 "s390_eqne_operator"
6545 [(match_operand 2 "cc_reg_operand")
6546 (match_operand 3 "const0_operand")]))
6547 (clobber (reg:CC CC_REGNUM))])]
6548 ""
6549 "machine_mode mode = GET_MODE (operands[2]);
6550 if (TARGET_Z196)
6551 {
6552 rtx cond, ite;
6553
6554 if (GET_CODE (operands[1]) == NE)
6555 cond = gen_rtx_NE (VOIDmode, operands[2], const0_rtx);
6556 else
6557 cond = gen_rtx_EQ (VOIDmode, operands[2], const0_rtx);
6558 ite = gen_rtx_IF_THEN_ELSE (SImode, cond, const1_rtx, const0_rtx);
6559 emit_insn (gen_rtx_SET (operands[0], ite));
6560 }
6561 else
6562 {
6563 if (mode != CCZ1mode)
6564 FAIL;
6565 emit_insn (gen_sne (operands[0], operands[2]));
6566 if (GET_CODE (operands[1]) == EQ)
6567 emit_insn (gen_xorsi3 (operands[0], operands[0], const1_rtx));
6568 }
6569 DONE;")
6570
6571 (define_insn_and_split "sne"
6572 [(set (match_operand:SI 0 "register_operand" "=d")
6573 (ne:SI (match_operand:CCZ1 1 "register_operand" "0")
6574 (const_int 0)))
6575 (clobber (reg:CC CC_REGNUM))]
6576 ""
6577 "#"
6578 "reload_completed"
6579 [(parallel
6580 [(set (match_dup 0) (ashiftrt:SI (match_dup 0) (const_int 28)))
6581 (clobber (reg:CC CC_REGNUM))])])
6582
6583
6584 ;;
6585 ;; - Conditional move instructions (introduced with z196)
6586 ;;
6587
6588 (define_expand "mov<mode>cc"
6589 [(set (match_operand:GPR 0 "nonimmediate_operand" "")
6590 (if_then_else:GPR (match_operand 1 "comparison_operator" "")
6591 (match_operand:GPR 2 "nonimmediate_operand" "")
6592 (match_operand:GPR 3 "nonimmediate_operand" "")))]
6593 "TARGET_Z196"
6594 {
6595 /* Emit the comparison insn in case we do not already have a comparison result. */
6596 if (!s390_comparison (operands[1], VOIDmode))
6597 operands[1] = s390_emit_compare (GET_CODE (operands[1]),
6598 XEXP (operands[1], 0),
6599 XEXP (operands[1], 1));
6600 })
6601
6602 ; locr, loc, stoc, locgr, locg, stocg, lochi, locghi
6603 (define_insn_and_split "*mov<mode>cc"
6604 [(set (match_operand:GPR 0 "nonimmediate_operand" "=d,d,d,d,d,d,S,S,&d")
6605 (if_then_else:GPR
6606 (match_operator 1 "s390_comparison"
6607 [(match_operand 2 "cc_reg_operand" " c,c,c,c,c,c,c,c,c")
6608 (match_operand 5 "const_int_operand" "")])
6609 (match_operand:GPR 3 "loc_operand" " d,0,S,0,K,0,d,0,S")
6610 (match_operand:GPR 4 "loc_operand" " 0,d,0,S,0,K,0,d,S")))]
6611 "TARGET_Z196"
6612 "@
6613 loc<g>r%C1\t%0,%3
6614 loc<g>r%D1\t%0,%4
6615 loc<g>%C1\t%0,%3
6616 loc<g>%D1\t%0,%4
6617 loc<g>hi%C1\t%0,%h3
6618 loc<g>hi%D1\t%0,%h4
6619 stoc<g>%C1\t%3,%0
6620 stoc<g>%D1\t%4,%0
6621 #"
6622 "&& reload_completed
6623 && MEM_P (operands[3]) && MEM_P (operands[4])"
6624 [(set (match_dup 0)
6625 (if_then_else:GPR
6626 (match_op_dup 1 [(match_dup 2) (const_int 0)])
6627 (match_dup 3)
6628 (match_dup 0)))
6629 (set (match_dup 0)
6630 (if_then_else:GPR
6631 (match_op_dup 1 [(match_dup 2) (const_int 0)])
6632 (match_dup 0)
6633 (match_dup 4)))]
6634 ""
6635 [(set_attr "op_type" "RRF,RRF,RSY,RSY,RIE,RIE,RSY,RSY,*")
6636 (set_attr "cpu_facility" "*,*,*,*,z13,z13,*,*,*")])
6637
6638 ;;
6639 ;;- Multiply instructions.
6640 ;;
6641
6642 ;
6643 ; muldi3 instruction pattern(s).
6644 ;
6645
6646 (define_expand "muldi3"
6647 [(parallel
6648 [(set (match_operand:DI 0 "register_operand")
6649 (mult:DI (match_operand:DI 1 "nonimmediate_operand")
6650 (match_operand:DI 2 "general_operand")))
6651 (clobber (reg:CC CC_REGNUM))])]
6652 "TARGET_ZARCH")
6653
6654 (define_insn "*muldi3_sign"
6655 [(set (match_operand:DI 0 "register_operand" "=d,d")
6656 (mult:DI (sign_extend:DI (match_operand:SI 2 "general_operand" "d,T"))
6657 (match_operand:DI 1 "register_operand" "0,0")))]
6658 "TARGET_ZARCH"
6659 "@
6660 msgfr\t%0,%2
6661 msgf\t%0,%2"
6662 [(set_attr "op_type" "RRE,RXY")
6663 (set_attr "type" "imuldi")])
6664
6665 (define_insn "*muldi3"
6666 [(set (match_operand:DI 0 "register_operand" "=d,d,d,d,d")
6667 (mult:DI (match_operand:DI 1 "nonimmediate_operand" "%0,d,0,0,0")
6668 (match_operand:DI 2 "general_operand" "d,d,K,T,Os")))
6669 (clobber (match_scratch:CC 3 "=X,c,X,X,X"))]
6670 "TARGET_ZARCH"
6671 "@
6672 msgr\t%0,%2
6673 msgrkc\t%0,%1,%2
6674 mghi\t%0,%h2
6675 msg\t%0,%2
6676 msgfi\t%0,%2"
6677 [(set_attr "op_type" "RRE,RRF,RI,RXY,RIL")
6678 (set_attr "type" "imuldi")
6679 (set_attr "cpu_facility" "*,arch12,*,*,z10")])
6680
6681 (define_insn "mulditi3"
6682 [(set (match_operand:TI 0 "register_operand" "=d,d")
6683 (mult:TI (sign_extend:TI
6684 (match_operand:DI 1 "register_operand" "%d,0"))
6685 (sign_extend:TI
6686 (match_operand:DI 2 "nonimmediate_operand" " d,T"))))]
6687 "TARGET_ARCH12"
6688 "@
6689 mgrk\t%0,%1,%2
6690 mg\t%0,%2"
6691 [(set_attr "op_type" "RRF,RXY")])
6692
6693 ; Combine likes op1 and op2 to be swapped sometimes.
6694 (define_insn "mulditi3_2"
6695 [(set (match_operand:TI 0 "register_operand" "=d,d")
6696 (mult:TI (sign_extend:TI
6697 (match_operand:DI 1 "nonimmediate_operand" "%d,T"))
6698 (sign_extend:TI
6699 (match_operand:DI 2 "register_operand" " d,0"))))]
6700 "TARGET_ARCH12"
6701 "@
6702 mgrk\t%0,%1,%2
6703 mg\t%0,%1"
6704 [(set_attr "op_type" "RRF,RXY")])
6705
6706 (define_insn "*muldi3_sign"
6707 [(set (match_operand:DI 0 "register_operand" "=d")
6708 (mult:DI (sign_extend:DI (match_operand:HI 2 "memory_operand" "T"))
6709 (match_operand:DI 1 "register_operand" "0")))]
6710 "TARGET_ARCH12"
6711 "mgh\t%0,%2"
6712 [(set_attr "op_type" "RXY")])
6713
6714
6715 ;
6716 ; mulsi3 instruction pattern(s).
6717 ;
6718
6719 (define_expand "mulsi3"
6720 [(parallel
6721 [(set (match_operand:SI 0 "register_operand" "=d,d,d,d,d,d")
6722 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%0,d,0,0,0,0")
6723 (match_operand:SI 2 "general_operand" "d,d,K,R,T,Os")))
6724 (clobber (reg:CC CC_REGNUM))])]
6725 "")
6726
6727 (define_insn "*mulsi3_sign"
6728 [(set (match_operand:SI 0 "register_operand" "=d,d")
6729 (mult:SI (sign_extend:SI (match_operand:HI 2 "memory_operand" "R,T"))
6730 (match_operand:SI 1 "register_operand" "0,0")))]
6731 ""
6732 "@
6733 mh\t%0,%2
6734 mhy\t%0,%2"
6735 [(set_attr "op_type" "RX,RXY")
6736 (set_attr "type" "imulhi")
6737 (set_attr "cpu_facility" "*,z10")])
6738
6739 (define_insn "*mulsi3"
6740 [(set (match_operand:SI 0 "register_operand" "=d,d,d,d,d,d")
6741 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%0,d,0,0,0,0")
6742 (match_operand:SI 2 "general_operand" "d,d,K,R,T,Os")))
6743 (clobber (match_scratch:CC 3 "=X,c,X,X,X,X"))]
6744 ""
6745 "@
6746 msr\t%0,%2
6747 msrkc\t%0,%1,%2
6748 mhi\t%0,%h2
6749 ms\t%0,%2
6750 msy\t%0,%2
6751 msfi\t%0,%2"
6752 [(set_attr "op_type" "RRE,RRF,RI,RX,RXY,RIL")
6753 (set_attr "type" "imulsi,*,imulhi,imulsi,imulsi,imulsi")
6754 (set_attr "cpu_facility" "*,arch12,*,*,longdisp,z10")])
6755
6756 ;
6757 ; mulsidi3 instruction pattern(s).
6758 ;
6759
6760 (define_insn "mulsidi3"
6761 [(set (match_operand:DI 0 "register_operand" "=d,d,d")
6762 (mult:DI (sign_extend:DI
6763 (match_operand:SI 1 "register_operand" "%0,0,0"))
6764 (sign_extend:DI
6765 (match_operand:SI 2 "nonimmediate_operand" "d,R,T"))))]
6766 "!TARGET_ZARCH"
6767 "@
6768 mr\t%0,%2
6769 m\t%0,%2
6770 mfy\t%0,%2"
6771 [(set_attr "op_type" "RR,RX,RXY")
6772 (set_attr "type" "imulsi")
6773 (set_attr "cpu_facility" "*,*,z10")])
6774
6775 ;
6776 ; umul instruction pattern(s).
6777 ;
6778
6779 ; mlr, ml, mlgr, mlg
6780 (define_insn "umul<dwh><mode>3"
6781 [(set (match_operand:DW 0 "register_operand" "=d,d")
6782 (mult:DW (zero_extend:DW
6783 (match_operand:<DWH> 1 "register_operand" "%0,0"))
6784 (zero_extend:DW
6785 (match_operand:<DWH> 2 "nonimmediate_operand" " d,T"))))]
6786 "TARGET_CPU_ZARCH"
6787 "@
6788 ml<tg>r\t%0,%2
6789 ml<tg>\t%0,%2"
6790 [(set_attr "op_type" "RRE,RXY")
6791 (set_attr "type" "imul<dwh>")])
6792
6793 ;
6794 ; mul(tf|df|sf|td|dd)3 instruction pattern(s).
6795 ;
6796
6797 ; mxbr, mdbr, meebr, mxb, mxb, meeb, mdtr, mxtr
6798 (define_insn "mul<mode>3"
6799 [(set (match_operand:FP 0 "register_operand" "=f,f,f,v,v")
6800 (mult:FP (match_operand:FP 1 "nonimmediate_operand" "%f,0,0,v,v")
6801 (match_operand:FP 2 "general_operand" "f,f,R,v,v")))]
6802 "TARGET_HARD_FLOAT"
6803 "@
6804 m<xdee>tr\t%0,%1,%2
6805 m<xdee>br\t%0,%2
6806 m<xdee>b\t%0,%2
6807 wfmdb\t%v0,%v1,%v2
6808 wfmsb\t%v0,%v1,%v2"
6809 [(set_attr "op_type" "RRF,RRE,RXE,VRR,VRR")
6810 (set_attr "type" "fmul<mode>")
6811 (set_attr "cpu_facility" "*,*,*,vx,vxe")
6812 (set_attr "enabled" "<nBFP>,<nDFP>,<DSF>,<DF>,<SF>")])
6813
6814 ; madbr, maebr, maxb, madb, maeb
6815 (define_insn "fma<mode>4"
6816 [(set (match_operand:DSF 0 "register_operand" "=f,f,v,v")
6817 (fma:DSF (match_operand:DSF 1 "nonimmediate_operand" "%f,f,v,v")
6818 (match_operand:DSF 2 "nonimmediate_operand" "f,R,v,v")
6819 (match_operand:DSF 3 "register_operand" "0,0,v,v")))]
6820 "TARGET_HARD_FLOAT"
6821 "@
6822 ma<xde>br\t%0,%1,%2
6823 ma<xde>b\t%0,%1,%2
6824 wfmadb\t%v0,%v1,%v2,%v3
6825 wfmasb\t%v0,%v1,%v2,%v3"
6826 [(set_attr "op_type" "RRE,RXE,VRR,VRR")
6827 (set_attr "type" "fmadd<mode>")
6828 (set_attr "cpu_facility" "*,*,vx,vxe")
6829 (set_attr "enabled" "*,*,<DF>,<SF>")])
6830
6831 ; msxbr, msdbr, msebr, msxb, msdb, mseb
6832 (define_insn "fms<mode>4"
6833 [(set (match_operand:DSF 0 "register_operand" "=f,f,v,v")
6834 (fma:DSF (match_operand:DSF 1 "nonimmediate_operand" "%f,f,v,v")
6835 (match_operand:DSF 2 "nonimmediate_operand" "f,R,v,v")
6836 (neg:DSF (match_operand:DSF 3 "register_operand" "0,0,v,v"))))]
6837 "TARGET_HARD_FLOAT"
6838 "@
6839 ms<xde>br\t%0,%1,%2
6840 ms<xde>b\t%0,%1,%2
6841 wfmsdb\t%v0,%v1,%v2,%v3
6842 wfmssb\t%v0,%v1,%v2,%v3"
6843 [(set_attr "op_type" "RRE,RXE,VRR,VRR")
6844 (set_attr "type" "fmadd<mode>")
6845 (set_attr "cpu_facility" "*,*,vx,vxe")
6846 (set_attr "enabled" "*,*,<DF>,<SF>")])
6847
6848 ;;
6849 ;;- Divide and modulo instructions.
6850 ;;
6851
6852 ;
6853 ; divmoddi4 instruction pattern(s).
6854 ;
6855
6856 (define_expand "divmoddi4"
6857 [(parallel [(set (match_operand:DI 0 "general_operand" "")
6858 (div:DI (match_operand:DI 1 "register_operand" "")
6859 (match_operand:DI 2 "general_operand" "")))
6860 (set (match_operand:DI 3 "general_operand" "")
6861 (mod:DI (match_dup 1) (match_dup 2)))])
6862 (clobber (match_dup 4))]
6863 "TARGET_ZARCH"
6864 {
6865 rtx div_equal, mod_equal;
6866 rtx_insn *insn;
6867
6868 div_equal = gen_rtx_DIV (DImode, operands[1], operands[2]);
6869 mod_equal = gen_rtx_MOD (DImode, operands[1], operands[2]);
6870
6871 operands[4] = gen_reg_rtx(TImode);
6872 emit_insn (gen_divmodtidi3 (operands[4], operands[1], operands[2]));
6873
6874 insn = emit_move_insn (operands[0], gen_lowpart (DImode, operands[4]));
6875 set_unique_reg_note (insn, REG_EQUAL, div_equal);
6876
6877 insn = emit_move_insn (operands[3], gen_highpart (DImode, operands[4]));
6878 set_unique_reg_note (insn, REG_EQUAL, mod_equal);
6879
6880 DONE;
6881 })
6882
6883 (define_insn "divmodtidi3"
6884 [(set (match_operand:TI 0 "register_operand" "=d,d")
6885 (ior:TI
6886 (ashift:TI
6887 (zero_extend:TI
6888 (mod:DI (match_operand:DI 1 "register_operand" "0,0")
6889 (match_operand:DI 2 "general_operand" "d,T")))
6890 (const_int 64))
6891 (zero_extend:TI (div:DI (match_dup 1) (match_dup 2)))))]
6892 "TARGET_ZARCH"
6893 "@
6894 dsgr\t%0,%2
6895 dsg\t%0,%2"
6896 [(set_attr "op_type" "RRE,RXY")
6897 (set_attr "type" "idiv")])
6898
6899 (define_insn "divmodtisi3"
6900 [(set (match_operand:TI 0 "register_operand" "=d,d")
6901 (ior:TI
6902 (ashift:TI
6903 (zero_extend:TI
6904 (mod:DI (match_operand:DI 1 "register_operand" "0,0")
6905 (sign_extend:DI
6906 (match_operand:SI 2 "nonimmediate_operand" "d,T"))))
6907 (const_int 64))
6908 (zero_extend:TI
6909 (div:DI (match_dup 1) (sign_extend:DI (match_dup 2))))))]
6910 "TARGET_ZARCH"
6911 "@
6912 dsgfr\t%0,%2
6913 dsgf\t%0,%2"
6914 [(set_attr "op_type" "RRE,RXY")
6915 (set_attr "type" "idiv")])
6916
6917 ;
6918 ; udivmoddi4 instruction pattern(s).
6919 ;
6920
6921 (define_expand "udivmoddi4"
6922 [(parallel [(set (match_operand:DI 0 "general_operand" "")
6923 (udiv:DI (match_operand:DI 1 "general_operand" "")
6924 (match_operand:DI 2 "nonimmediate_operand" "")))
6925 (set (match_operand:DI 3 "general_operand" "")
6926 (umod:DI (match_dup 1) (match_dup 2)))])
6927 (clobber (match_dup 4))]
6928 "TARGET_ZARCH"
6929 {
6930 rtx div_equal, mod_equal, equal;
6931 rtx_insn *insn;
6932
6933 div_equal = gen_rtx_UDIV (DImode, operands[1], operands[2]);
6934 mod_equal = gen_rtx_UMOD (DImode, operands[1], operands[2]);
6935 equal = gen_rtx_IOR (TImode,
6936 gen_rtx_ASHIFT (TImode,
6937 gen_rtx_ZERO_EXTEND (TImode, mod_equal),
6938 GEN_INT (64)),
6939 gen_rtx_ZERO_EXTEND (TImode, div_equal));
6940
6941 operands[4] = gen_reg_rtx(TImode);
6942 emit_clobber (operands[4]);
6943 emit_move_insn (gen_lowpart (DImode, operands[4]), operands[1]);
6944 emit_move_insn (gen_highpart (DImode, operands[4]), const0_rtx);
6945
6946 insn = emit_insn (gen_udivmodtidi3 (operands[4], operands[4], operands[2]));
6947 set_unique_reg_note (insn, REG_EQUAL, equal);
6948
6949 insn = emit_move_insn (operands[0], gen_lowpart (DImode, operands[4]));
6950 set_unique_reg_note (insn, REG_EQUAL, div_equal);
6951
6952 insn = emit_move_insn (operands[3], gen_highpart (DImode, operands[4]));
6953 set_unique_reg_note (insn, REG_EQUAL, mod_equal);
6954
6955 DONE;
6956 })
6957
6958 (define_insn "udivmodtidi3"
6959 [(set (match_operand:TI 0 "register_operand" "=d,d")
6960 (ior:TI
6961 (ashift:TI
6962 (zero_extend:TI
6963 (truncate:DI
6964 (umod:TI (match_operand:TI 1 "register_operand" "0,0")
6965 (zero_extend:TI
6966 (match_operand:DI 2 "nonimmediate_operand" "d,T")))))
6967 (const_int 64))
6968 (zero_extend:TI
6969 (truncate:DI
6970 (udiv:TI (match_dup 1) (zero_extend:TI (match_dup 2)))))))]
6971 "TARGET_ZARCH"
6972 "@
6973 dlgr\t%0,%2
6974 dlg\t%0,%2"
6975 [(set_attr "op_type" "RRE,RXY")
6976 (set_attr "type" "idiv")])
6977
6978 ;
6979 ; divmodsi4 instruction pattern(s).
6980 ;
6981
6982 (define_expand "divmodsi4"
6983 [(parallel [(set (match_operand:SI 0 "general_operand" "")
6984 (div:SI (match_operand:SI 1 "general_operand" "")
6985 (match_operand:SI 2 "nonimmediate_operand" "")))
6986 (set (match_operand:SI 3 "general_operand" "")
6987 (mod:SI (match_dup 1) (match_dup 2)))])
6988 (clobber (match_dup 4))]
6989 "!TARGET_ZARCH"
6990 {
6991 rtx div_equal, mod_equal, equal;
6992 rtx_insn *insn;
6993
6994 div_equal = gen_rtx_DIV (SImode, operands[1], operands[2]);
6995 mod_equal = gen_rtx_MOD (SImode, operands[1], operands[2]);
6996 equal = gen_rtx_IOR (DImode,
6997 gen_rtx_ASHIFT (DImode,
6998 gen_rtx_ZERO_EXTEND (DImode, mod_equal),
6999 GEN_INT (32)),
7000 gen_rtx_ZERO_EXTEND (DImode, div_equal));
7001
7002 operands[4] = gen_reg_rtx(DImode);
7003 emit_insn (gen_extendsidi2 (operands[4], operands[1]));
7004
7005 insn = emit_insn (gen_divmoddisi3 (operands[4], operands[4], operands[2]));
7006 set_unique_reg_note (insn, REG_EQUAL, equal);
7007
7008 insn = emit_move_insn (operands[0], gen_lowpart (SImode, operands[4]));
7009 set_unique_reg_note (insn, REG_EQUAL, div_equal);
7010
7011 insn = emit_move_insn (operands[3], gen_highpart (SImode, operands[4]));
7012 set_unique_reg_note (insn, REG_EQUAL, mod_equal);
7013
7014 DONE;
7015 })
7016
7017 (define_insn "divmoddisi3"
7018 [(set (match_operand:DI 0 "register_operand" "=d,d")
7019 (ior:DI
7020 (ashift:DI
7021 (zero_extend:DI
7022 (truncate:SI
7023 (mod:DI (match_operand:DI 1 "register_operand" "0,0")
7024 (sign_extend:DI
7025 (match_operand:SI 2 "nonimmediate_operand" "d,R")))))
7026 (const_int 32))
7027 (zero_extend:DI
7028 (truncate:SI
7029 (div:DI (match_dup 1) (sign_extend:DI (match_dup 2)))))))]
7030 "!TARGET_ZARCH"
7031 "@
7032 dr\t%0,%2
7033 d\t%0,%2"
7034 [(set_attr "op_type" "RR,RX")
7035 (set_attr "type" "idiv")])
7036
7037 ;
7038 ; udivsi3 and umodsi3 instruction pattern(s).
7039 ;
7040
7041 (define_expand "udivmodsi4"
7042 [(parallel [(set (match_operand:SI 0 "general_operand" "")
7043 (udiv:SI (match_operand:SI 1 "general_operand" "")
7044 (match_operand:SI 2 "nonimmediate_operand" "")))
7045 (set (match_operand:SI 3 "general_operand" "")
7046 (umod:SI (match_dup 1) (match_dup 2)))])
7047 (clobber (match_dup 4))]
7048 "!TARGET_ZARCH && TARGET_CPU_ZARCH"
7049 {
7050 rtx div_equal, mod_equal, equal;
7051 rtx_insn *insn;
7052
7053 div_equal = gen_rtx_UDIV (SImode, operands[1], operands[2]);
7054 mod_equal = gen_rtx_UMOD (SImode, operands[1], operands[2]);
7055 equal = gen_rtx_IOR (DImode,
7056 gen_rtx_ASHIFT (DImode,
7057 gen_rtx_ZERO_EXTEND (DImode, mod_equal),
7058 GEN_INT (32)),
7059 gen_rtx_ZERO_EXTEND (DImode, div_equal));
7060
7061 operands[4] = gen_reg_rtx(DImode);
7062 emit_clobber (operands[4]);
7063 emit_move_insn (gen_lowpart (SImode, operands[4]), operands[1]);
7064 emit_move_insn (gen_highpart (SImode, operands[4]), const0_rtx);
7065
7066 insn = emit_insn (gen_udivmoddisi3 (operands[4], operands[4], operands[2]));
7067 set_unique_reg_note (insn, REG_EQUAL, equal);
7068
7069 insn = emit_move_insn (operands[0], gen_lowpart (SImode, operands[4]));
7070 set_unique_reg_note (insn, REG_EQUAL, div_equal);
7071
7072 insn = emit_move_insn (operands[3], gen_highpart (SImode, operands[4]));
7073 set_unique_reg_note (insn, REG_EQUAL, mod_equal);
7074
7075 DONE;
7076 })
7077
7078 (define_insn "udivmoddisi3"
7079 [(set (match_operand:DI 0 "register_operand" "=d,d")
7080 (ior:DI
7081 (ashift:DI
7082 (zero_extend:DI
7083 (truncate:SI
7084 (umod:DI (match_operand:DI 1 "register_operand" "0,0")
7085 (zero_extend:DI
7086 (match_operand:SI 2 "nonimmediate_operand" "d,T")))))
7087 (const_int 32))
7088 (zero_extend:DI
7089 (truncate:SI
7090 (udiv:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))))]
7091 "!TARGET_ZARCH && TARGET_CPU_ZARCH"
7092 "@
7093 dlr\t%0,%2
7094 dl\t%0,%2"
7095 [(set_attr "op_type" "RRE,RXY")
7096 (set_attr "type" "idiv")])
7097
7098 (define_expand "udivsi3"
7099 [(set (match_operand:SI 0 "register_operand" "=d")
7100 (udiv:SI (match_operand:SI 1 "general_operand" "")
7101 (match_operand:SI 2 "general_operand" "")))
7102 (clobber (match_dup 3))]
7103 "!TARGET_ZARCH && !TARGET_CPU_ZARCH"
7104 {
7105 rtx udiv_equal, umod_equal, equal;
7106 rtx_insn *insn;
7107
7108 udiv_equal = gen_rtx_UDIV (SImode, operands[1], operands[2]);
7109 umod_equal = gen_rtx_UMOD (SImode, operands[1], operands[2]);
7110 equal = gen_rtx_IOR (DImode,
7111 gen_rtx_ASHIFT (DImode,
7112 gen_rtx_ZERO_EXTEND (DImode, umod_equal),
7113 GEN_INT (32)),
7114 gen_rtx_ZERO_EXTEND (DImode, udiv_equal));
7115
7116 operands[3] = gen_reg_rtx (DImode);
7117
7118 if (CONSTANT_P (operands[2]))
7119 {
7120 if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0)
7121 {
7122 rtx_code_label *label1 = gen_label_rtx ();
7123
7124 operands[1] = make_safe_from (operands[1], operands[0]);
7125 emit_move_insn (operands[0], const0_rtx);
7126 emit_cmp_and_jump_insns (operands[1], operands[2], LT, NULL_RTX,
7127 SImode, 1, label1);
7128 emit_move_insn (operands[0], const1_rtx);
7129 emit_label (label1);
7130 }
7131 else
7132 {
7133 operands[2] = force_reg (SImode, operands[2]);
7134 operands[2] = make_safe_from (operands[2], operands[0]);
7135
7136 emit_insn (gen_zero_extendsidi2 (operands[3], operands[1]));
7137 insn = emit_insn (gen_divmoddisi3 (operands[3], operands[3],
7138 operands[2]));
7139 set_unique_reg_note (insn, REG_EQUAL, equal);
7140
7141 insn = emit_move_insn (operands[0],
7142 gen_lowpart (SImode, operands[3]));
7143 set_unique_reg_note (insn, REG_EQUAL, udiv_equal);
7144 }
7145 }
7146 else
7147 {
7148 rtx_code_label *label1 = gen_label_rtx ();
7149 rtx_code_label *label2 = gen_label_rtx ();
7150 rtx_code_label *label3 = gen_label_rtx ();
7151
7152 operands[1] = force_reg (SImode, operands[1]);
7153 operands[1] = make_safe_from (operands[1], operands[0]);
7154 operands[2] = force_reg (SImode, operands[2]);
7155 operands[2] = make_safe_from (operands[2], operands[0]);
7156
7157 emit_move_insn (operands[0], const0_rtx);
7158 emit_cmp_and_jump_insns (operands[2], operands[1], GT, NULL_RTX,
7159 SImode, 1, label3);
7160 emit_cmp_and_jump_insns (operands[2], const0_rtx, LT, NULL_RTX,
7161 SImode, 0, label2);
7162 emit_cmp_and_jump_insns (operands[2], const1_rtx, EQ, NULL_RTX,
7163 SImode, 0, label1);
7164 emit_insn (gen_zero_extendsidi2 (operands[3], operands[1]));
7165 insn = emit_insn (gen_divmoddisi3 (operands[3], operands[3],
7166 operands[2]));
7167 set_unique_reg_note (insn, REG_EQUAL, equal);
7168
7169 insn = emit_move_insn (operands[0],
7170 gen_lowpart (SImode, operands[3]));
7171 set_unique_reg_note (insn, REG_EQUAL, udiv_equal);
7172
7173 emit_jump (label3);
7174 emit_label (label1);
7175 emit_move_insn (operands[0], operands[1]);
7176 emit_jump (label3);
7177 emit_label (label2);
7178 emit_move_insn (operands[0], const1_rtx);
7179 emit_label (label3);
7180 }
7181 emit_move_insn (operands[0], operands[0]);
7182 DONE;
7183 })
7184
7185 (define_expand "umodsi3"
7186 [(set (match_operand:SI 0 "register_operand" "=d")
7187 (umod:SI (match_operand:SI 1 "nonimmediate_operand" "")
7188 (match_operand:SI 2 "nonimmediate_operand" "")))
7189 (clobber (match_dup 3))]
7190 "!TARGET_ZARCH && !TARGET_CPU_ZARCH"
7191 {
7192 rtx udiv_equal, umod_equal, equal;
7193 rtx_insn *insn;
7194
7195 udiv_equal = gen_rtx_UDIV (SImode, operands[1], operands[2]);
7196 umod_equal = gen_rtx_UMOD (SImode, operands[1], operands[2]);
7197 equal = gen_rtx_IOR (DImode,
7198 gen_rtx_ASHIFT (DImode,
7199 gen_rtx_ZERO_EXTEND (DImode, umod_equal),
7200 GEN_INT (32)),
7201 gen_rtx_ZERO_EXTEND (DImode, udiv_equal));
7202
7203 operands[3] = gen_reg_rtx (DImode);
7204
7205 if (CONSTANT_P (operands[2]))
7206 {
7207 if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) <= 0)
7208 {
7209 rtx_code_label *label1 = gen_label_rtx ();
7210
7211 operands[1] = make_safe_from (operands[1], operands[0]);
7212 emit_move_insn (operands[0], operands[1]);
7213 emit_cmp_and_jump_insns (operands[0], operands[2], LT, NULL_RTX,
7214 SImode, 1, label1);
7215 emit_insn (gen_abssi2 (operands[0], operands[2]));
7216 emit_insn (gen_addsi3 (operands[0], operands[0], operands[1]));
7217 emit_label (label1);
7218 }
7219 else
7220 {
7221 operands[2] = force_reg (SImode, operands[2]);
7222 operands[2] = make_safe_from (operands[2], operands[0]);
7223
7224 emit_insn (gen_zero_extendsidi2 (operands[3], operands[1]));
7225 insn = emit_insn (gen_divmoddisi3 (operands[3], operands[3],
7226 operands[2]));
7227 set_unique_reg_note (insn, REG_EQUAL, equal);
7228
7229 insn = emit_move_insn (operands[0],
7230 gen_highpart (SImode, operands[3]));
7231 set_unique_reg_note (insn, REG_EQUAL, umod_equal);
7232 }
7233 }
7234 else
7235 {
7236 rtx_code_label *label1 = gen_label_rtx ();
7237 rtx_code_label *label2 = gen_label_rtx ();
7238 rtx_code_label *label3 = gen_label_rtx ();
7239
7240 operands[1] = force_reg (SImode, operands[1]);
7241 operands[1] = make_safe_from (operands[1], operands[0]);
7242 operands[2] = force_reg (SImode, operands[2]);
7243 operands[2] = make_safe_from (operands[2], operands[0]);
7244
7245 emit_move_insn(operands[0], operands[1]);
7246 emit_cmp_and_jump_insns (operands[2], operands[1], GT, NULL_RTX,
7247 SImode, 1, label3);
7248 emit_cmp_and_jump_insns (operands[2], const0_rtx, LT, NULL_RTX,
7249 SImode, 0, label2);
7250 emit_cmp_and_jump_insns (operands[2], const1_rtx, EQ, NULL_RTX,
7251 SImode, 0, label1);
7252 emit_insn (gen_zero_extendsidi2 (operands[3], operands[1]));
7253 insn = emit_insn (gen_divmoddisi3 (operands[3], operands[3],
7254 operands[2]));
7255 set_unique_reg_note (insn, REG_EQUAL, equal);
7256
7257 insn = emit_move_insn (operands[0],
7258 gen_highpart (SImode, operands[3]));
7259 set_unique_reg_note (insn, REG_EQUAL, umod_equal);
7260
7261 emit_jump (label3);
7262 emit_label (label1);
7263 emit_move_insn (operands[0], const0_rtx);
7264 emit_jump (label3);
7265 emit_label (label2);
7266 emit_insn (gen_subsi3 (operands[0], operands[0], operands[2]));
7267 emit_label (label3);
7268 }
7269 DONE;
7270 })
7271
7272 ;
7273 ; div(df|sf)3 instruction pattern(s).
7274 ;
7275
7276 ; dxbr, ddbr, debr, dxb, ddb, deb, ddtr, dxtr
7277 (define_insn "div<mode>3"
7278 [(set (match_operand:FP 0 "register_operand" "=f,f,f,v,v")
7279 (div:FP (match_operand:FP 1 "register_operand" "f,0,0,v,v")
7280 (match_operand:FP 2 "general_operand" "f,f,R,v,v")))]
7281 "TARGET_HARD_FLOAT"
7282 "@
7283 d<xde>tr\t%0,%1,%2
7284 d<xde>br\t%0,%2
7285 d<xde>b\t%0,%2
7286 wfddb\t%v0,%v1,%v2
7287 wfdsb\t%v0,%v1,%v2"
7288 [(set_attr "op_type" "RRF,RRE,RXE,VRR,VRR")
7289 (set_attr "type" "fdiv<mode>")
7290 (set_attr "cpu_facility" "*,*,*,vx,vxe")
7291 (set_attr "enabled" "<nBFP>,<nDFP>,<DSF>,<DF>,<SF>")])
7292
7293
7294 ;;
7295 ;;- And instructions.
7296 ;;
7297
7298 (define_expand "and<mode>3"
7299 [(set (match_operand:INT 0 "nonimmediate_operand" "")
7300 (and:INT (match_operand:INT 1 "nonimmediate_operand" "")
7301 (match_operand:INT 2 "general_operand" "")))
7302 (clobber (reg:CC CC_REGNUM))]
7303 ""
7304 "s390_expand_logical_operator (AND, <MODE>mode, operands); DONE;")
7305
7306 ;
7307 ; anddi3 instruction pattern(s).
7308 ;
7309
7310 (define_insn "*anddi3_cc"
7311 [(set (reg CC_REGNUM)
7312 (compare
7313 (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,d,0, d")
7314 (match_operand:DI 2 "general_operand" " d,d,T,NxxDw"))
7315 (const_int 0)))
7316 (set (match_operand:DI 0 "register_operand" "=d,d,d, d")
7317 (and:DI (match_dup 1) (match_dup 2)))]
7318 "TARGET_ZARCH && s390_match_ccmode(insn, CCTmode)"
7319 "@
7320 ngr\t%0,%2
7321 ngrk\t%0,%1,%2
7322 ng\t%0,%2
7323 risbg\t%0,%1,%s2,128+%e2,0"
7324 [(set_attr "op_type" "RRE,RRF,RXY,RIE")
7325 (set_attr "cpu_facility" "*,z196,*,z10")
7326 (set_attr "z10prop" "z10_super_E1,*,z10_super_E1,z10_super_E1")])
7327
7328 (define_insn "*anddi3_cconly"
7329 [(set (reg CC_REGNUM)
7330 (compare
7331 (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,d,0, d")
7332 (match_operand:DI 2 "general_operand" " d,d,T,NxxDw"))
7333 (const_int 0)))
7334 (clobber (match_scratch:DI 0 "=d,d,d, d"))]
7335 "TARGET_ZARCH
7336 && s390_match_ccmode(insn, CCTmode)
7337 /* Do not steal TM patterns. */
7338 && s390_single_part (operands[2], DImode, HImode, 0) < 0"
7339 "@
7340 ngr\t%0,%2
7341 ngrk\t%0,%1,%2
7342 ng\t%0,%2
7343 risbg\t%0,%1,%s2,128+%e2,0"
7344 [(set_attr "op_type" "RRE,RRF,RXY,RIE")
7345 (set_attr "cpu_facility" "*,z196,*,z10")
7346 (set_attr "z10prop" "z10_super_E1,*,z10_super_E1,z10_super_E1")])
7347
7348 (define_insn "*anddi3"
7349 [(set (match_operand:DI 0 "nonimmediate_operand"
7350 "=d,d, d, d, d, d, d, d,d,d,d, d, AQ,Q")
7351 (and:DI
7352 (match_operand:DI 1 "nonimmediate_operand"
7353 "%d,o, 0, 0, 0, 0, 0, 0,0,d,0, d, 0,0")
7354 (match_operand:DI 2 "general_operand"
7355 "M, M,N0HDF,N1HDF,N2HDF,N3HDF,N0SDF,N1SDF,d,d,T,NxxDw,NxQDF,Q")))
7356 (clobber (reg:CC CC_REGNUM))]
7357 "TARGET_ZARCH && s390_logical_operator_ok_p (operands)"
7358 "@
7359 #
7360 #
7361 nihh\t%0,%j2
7362 nihl\t%0,%j2
7363 nilh\t%0,%j2
7364 nill\t%0,%j2
7365 nihf\t%0,%m2
7366 nilf\t%0,%m2
7367 ngr\t%0,%2
7368 ngrk\t%0,%1,%2
7369 ng\t%0,%2
7370 risbg\t%0,%1,%s2,128+%e2,0
7371 #
7372 #"
7373 [(set_attr "op_type" "RRE,RXE,RI,RI,RI,RI,RIL,RIL,RRE,RRF,RXY,RIE,SI,SS")
7374 (set_attr "cpu_facility" "*,*,*,*,*,*,extimm,extimm,*,z196,*,z10,*,*")
7375 (set_attr "z10prop" "*,
7376 *,
7377 z10_super_E1,
7378 z10_super_E1,
7379 z10_super_E1,
7380 z10_super_E1,
7381 z10_super_E1,
7382 z10_super_E1,
7383 z10_super_E1,
7384 *,
7385 z10_super_E1,
7386 z10_super_E1,
7387 *,
7388 *")])
7389
7390 (define_split
7391 [(set (match_operand:DI 0 "s_operand" "")
7392 (and:DI (match_dup 0) (match_operand:DI 1 "immediate_operand" "")))
7393 (clobber (reg:CC CC_REGNUM))]
7394 "reload_completed"
7395 [(parallel
7396 [(set (match_dup 0) (and:QI (match_dup 0) (match_dup 1)))
7397 (clobber (reg:CC CC_REGNUM))])]
7398 "s390_narrow_logical_operator (AND, &operands[0], &operands[1]);")
7399
7400 ;; These two are what combine generates for (ashift (zero_extract)).
7401 (define_insn "*extzv_<mode>_srl<clobbercc_or_nocc>"
7402 [(set (match_operand:GPR 0 "register_operand" "=d")
7403 (and:GPR (lshiftrt:GPR
7404 (match_operand:GPR 1 "register_operand" "d")
7405 (match_operand:GPR 2 "nonzero_shift_count_operand" ""))
7406 (match_operand:GPR 3 "contiguous_bitmask_nowrap_operand" "")))]
7407 "<z10_or_zEC12_cond>
7408 /* Note that even for the SImode pattern, the rotate is always DImode. */
7409 && s390_extzv_shift_ok (<bitsize>, -INTVAL (operands[2]),
7410 INTVAL (operands[3]))"
7411 "<risbg_n>\t%0,%1,%<bfstart>3,128+%<bfend>3,64-%2"
7412 [(set_attr "op_type" "RIE")
7413 (set_attr "z10prop" "z10_super_E1")])
7414
7415 (define_insn "*extzv_<mode>_sll<clobbercc_or_nocc>"
7416 [(set (match_operand:GPR 0 "register_operand" "=d")
7417 (and:GPR (ashift:GPR
7418 (match_operand:GPR 1 "register_operand" "d")
7419 (match_operand:GPR 2 "nonzero_shift_count_operand" ""))
7420 (match_operand:GPR 3 "contiguous_bitmask_nowrap_operand" "")))]
7421 "<z10_or_zEC12_cond>
7422 && s390_extzv_shift_ok (<bitsize>, INTVAL (operands[2]),
7423 INTVAL (operands[3]))"
7424 "<risbg_n>\t%0,%1,%<bfstart>3,128+%<bfend>3,%2"
7425 [(set_attr "op_type" "RIE")
7426 (set_attr "z10prop" "z10_super_E1")])
7427
7428
7429 ;
7430 ; andsi3 instruction pattern(s).
7431 ;
7432
7433 (define_insn "*andsi3_cc"
7434 [(set (reg CC_REGNUM)
7435 (compare
7436 (and:SI
7437 (match_operand:SI 1 "nonimmediate_operand" "%0,0,d,0,0, d")
7438 (match_operand:SI 2 "general_operand" "Os,d,d,R,T,NxxSq"))
7439 (const_int 0)))
7440 (set (match_operand:SI 0 "register_operand" "=d,d,d,d,d, d")
7441 (and:SI (match_dup 1) (match_dup 2)))]
7442 "s390_match_ccmode(insn, CCTmode)"
7443 "@
7444 nilf\t%0,%o2
7445 nr\t%0,%2
7446 nrk\t%0,%1,%2
7447 n\t%0,%2
7448 ny\t%0,%2
7449 risbg\t%0,%1,%t2,128+%f2,0"
7450 [(set_attr "op_type" "RIL,RR,RRF,RX,RXY,RIE")
7451 (set_attr "cpu_facility" "*,*,z196,*,longdisp,z10")
7452 (set_attr "z10prop" "z10_super_E1,z10_super_E1,*,
7453 z10_super_E1,z10_super_E1,z10_super_E1")])
7454
7455 (define_insn "*andsi3_cconly"
7456 [(set (reg CC_REGNUM)
7457 (compare
7458 (and:SI
7459 (match_operand:SI 1 "nonimmediate_operand" "%0,0,d,0,0, d")
7460 (match_operand:SI 2 "general_operand" "Os,d,d,R,T,NxxSq"))
7461 (const_int 0)))
7462 (clobber (match_scratch:SI 0 "=d,d,d,d,d, d"))]
7463 "s390_match_ccmode(insn, CCTmode)
7464 /* Do not steal TM patterns. */
7465 && s390_single_part (operands[2], SImode, HImode, 0) < 0"
7466 "@
7467 nilf\t%0,%o2
7468 nr\t%0,%2
7469 nrk\t%0,%1,%2
7470 n\t%0,%2
7471 ny\t%0,%2
7472 risbg\t%0,%1,%t2,128+%f2,0"
7473 [(set_attr "op_type" "RIL,RR,RRF,RX,RXY,RIE")
7474 (set_attr "cpu_facility" "*,*,z196,*,longdisp,z10")
7475 (set_attr "z10prop" "z10_super_E1,z10_super_E1,*,
7476 z10_super_E1,z10_super_E1,z10_super_E1")])
7477
7478 (define_insn "*andsi3_zarch"
7479 [(set (match_operand:SI 0 "nonimmediate_operand"
7480 "=d,d, d, d, d,d,d,d,d, d, AQ,Q")
7481 (and:SI (match_operand:SI 1 "nonimmediate_operand"
7482 "%d,o, 0, 0, 0,0,d,0,0, d, 0,0")
7483 (match_operand:SI 2 "general_operand"
7484 " M,M,N0HSF,N1HSF,Os,d,d,R,T,NxxSw,NxQSF,Q")))
7485 (clobber (reg:CC CC_REGNUM))]
7486 "TARGET_ZARCH && s390_logical_operator_ok_p (operands)"
7487 "@
7488 #
7489 #
7490 nilh\t%0,%j2
7491 nill\t%0,%j2
7492 nilf\t%0,%o2
7493 nr\t%0,%2
7494 nrk\t%0,%1,%2
7495 n\t%0,%2
7496 ny\t%0,%2
7497 risbg\t%0,%1,%t2,128+%f2,0
7498 #
7499 #"
7500 [(set_attr "op_type" "RRE,RXE,RI,RI,RIL,RR,RRF,RX,RXY,RIE,SI,SS")
7501 (set_attr "cpu_facility" "*,*,*,*,*,*,z196,*,longdisp,z10,*,*")
7502 (set_attr "z10prop" "*,
7503 *,
7504 z10_super_E1,
7505 z10_super_E1,
7506 z10_super_E1,
7507 z10_super_E1,
7508 *,
7509 z10_super_E1,
7510 z10_super_E1,
7511 z10_super_E1,
7512 *,
7513 *")])
7514
7515 (define_insn "*andsi3_esa"
7516 [(set (match_operand:SI 0 "nonimmediate_operand" "=d,d, AQ,Q")
7517 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0, 0,0")
7518 (match_operand:SI 2 "general_operand" " d,R,NxQSF,Q")))
7519 (clobber (reg:CC CC_REGNUM))]
7520 "!TARGET_ZARCH && s390_logical_operator_ok_p (operands)"
7521 "@
7522 nr\t%0,%2
7523 n\t%0,%2
7524 #
7525 #"
7526 [(set_attr "op_type" "RR,RX,SI,SS")
7527 (set_attr "z10prop" "z10_super_E1,z10_super_E1,*,*")])
7528
7529
7530 (define_split
7531 [(set (match_operand:SI 0 "s_operand" "")
7532 (and:SI (match_dup 0) (match_operand:SI 1 "immediate_operand" "")))
7533 (clobber (reg:CC CC_REGNUM))]
7534 "reload_completed"
7535 [(parallel
7536 [(set (match_dup 0) (and:QI (match_dup 0) (match_dup 1)))
7537 (clobber (reg:CC CC_REGNUM))])]
7538 "s390_narrow_logical_operator (AND, &operands[0], &operands[1]);")
7539
7540 ;
7541 ; andhi3 instruction pattern(s).
7542 ;
7543
7544 (define_insn "*andhi3_zarch"
7545 [(set (match_operand:HI 0 "nonimmediate_operand" "=d,d,d, AQ,Q")
7546 (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,d,0, 0,0")
7547 (match_operand:HI 2 "general_operand" " d,d,n,NxQHF,Q")))
7548 (clobber (reg:CC CC_REGNUM))]
7549 "TARGET_ZARCH && s390_logical_operator_ok_p (operands)"
7550 "@
7551 nr\t%0,%2
7552 nrk\t%0,%1,%2
7553 nill\t%0,%x2
7554 #
7555 #"
7556 [(set_attr "op_type" "RR,RRF,RI,SI,SS")
7557 (set_attr "cpu_facility" "*,z196,*,*,*")
7558 (set_attr "z10prop" "z10_super_E1,*,z10_super_E1,*,*")
7559 ])
7560
7561 (define_insn "*andhi3_esa"
7562 [(set (match_operand:HI 0 "nonimmediate_operand" "=d,AQ,Q")
7563 (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,0")
7564 (match_operand:HI 2 "general_operand" "d,NxQHF,Q")))
7565 (clobber (reg:CC CC_REGNUM))]
7566 "!TARGET_ZARCH && s390_logical_operator_ok_p (operands)"
7567 "@
7568 nr\t%0,%2
7569 #
7570 #"
7571 [(set_attr "op_type" "RR,SI,SS")
7572 (set_attr "z10prop" "z10_super_E1,*,*")
7573 ])
7574
7575 (define_split
7576 [(set (match_operand:HI 0 "s_operand" "")
7577 (and:HI (match_dup 0) (match_operand:HI 1 "immediate_operand" "")))
7578 (clobber (reg:CC CC_REGNUM))]
7579 "reload_completed"
7580 [(parallel
7581 [(set (match_dup 0) (and:QI (match_dup 0) (match_dup 1)))
7582 (clobber (reg:CC CC_REGNUM))])]
7583 "s390_narrow_logical_operator (AND, &operands[0], &operands[1]);")
7584
7585 ;
7586 ; andqi3 instruction pattern(s).
7587 ;
7588
7589 (define_insn "*andqi3_zarch"
7590 [(set (match_operand:QI 0 "nonimmediate_operand" "=d,d,d,Q,S,Q")
7591 (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,d,0,0,0,0")
7592 (match_operand:QI 2 "general_operand" " d,d,n,n,n,Q")))
7593 (clobber (reg:CC CC_REGNUM))]
7594 "TARGET_ZARCH && s390_logical_operator_ok_p (operands)"
7595 "@
7596 nr\t%0,%2
7597 nrk\t%0,%1,%2
7598 nill\t%0,%b2
7599 ni\t%S0,%b2
7600 niy\t%S0,%b2
7601 #"
7602 [(set_attr "op_type" "RR,RRF,RI,SI,SIY,SS")
7603 (set_attr "cpu_facility" "*,z196,*,*,longdisp,*")
7604 (set_attr "z10prop" "z10_super_E1,*,z10_super_E1,z10_super,z10_super,*")])
7605
7606 (define_insn "*andqi3_esa"
7607 [(set (match_operand:QI 0 "nonimmediate_operand" "=d,Q,Q")
7608 (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
7609 (match_operand:QI 2 "general_operand" "d,n,Q")))
7610 (clobber (reg:CC CC_REGNUM))]
7611 "!TARGET_ZARCH && s390_logical_operator_ok_p (operands)"
7612 "@
7613 nr\t%0,%2
7614 ni\t%S0,%b2
7615 #"
7616 [(set_attr "op_type" "RR,SI,SS")
7617 (set_attr "z10prop" "z10_super_E1,z10_super,*")])
7618
7619 ;
7620 ; And with complement
7621 ;
7622 ; c = ~b & a = (b & a) ^ a
7623
7624 (define_insn_and_split "*andc_split_<mode>"
7625 [(set (match_operand:GPR 0 "nonimmediate_operand" "")
7626 (and:GPR (not:GPR (match_operand:GPR 1 "nonimmediate_operand" ""))
7627 (match_operand:GPR 2 "general_operand" "")))
7628 (clobber (reg:CC CC_REGNUM))]
7629 "! reload_completed
7630 && (GET_CODE (operands[0]) != MEM
7631 /* Ensure that s390_logical_operator_ok_p will succeed even
7632 on the split xor if (b & a) is stored into a pseudo. */
7633 || rtx_equal_p (operands[0], operands[2]))"
7634 "#"
7635 "&& 1"
7636 [
7637 (parallel
7638 [(set (match_dup 3) (and:GPR (match_dup 1) (match_dup 2)))
7639 (clobber (reg:CC CC_REGNUM))])
7640 (parallel
7641 [(set (match_dup 0) (xor:GPR (match_dup 3) (match_dup 2)))
7642 (clobber (reg:CC CC_REGNUM))])]
7643 {
7644 if (reg_overlap_mentioned_p (operands[0], operands[2]))
7645 operands[3] = gen_reg_rtx (<MODE>mode);
7646 else
7647 operands[3] = operands[0];
7648 })
7649
7650 ;
7651 ; Block and (NC) patterns.
7652 ;
7653
7654 (define_insn "*nc"
7655 [(set (match_operand:BLK 0 "memory_operand" "=Q")
7656 (and:BLK (match_dup 0)
7657 (match_operand:BLK 1 "memory_operand" "Q")))
7658 (use (match_operand 2 "const_int_operand" "n"))
7659 (clobber (reg:CC CC_REGNUM))]
7660 "INTVAL (operands[2]) >= 1 && INTVAL (operands[2]) <= 256"
7661 "nc\t%O0(%2,%R0),%S1"
7662 [(set_attr "op_type" "SS")
7663 (set_attr "z196prop" "z196_cracked")])
7664
7665 (define_split
7666 [(set (match_operand 0 "memory_operand" "")
7667 (and (match_dup 0)
7668 (match_operand 1 "memory_operand" "")))
7669 (clobber (reg:CC CC_REGNUM))]
7670 "reload_completed
7671 && GET_MODE (operands[0]) == GET_MODE (operands[1])
7672 && GET_MODE_SIZE (GET_MODE (operands[0])) > 0"
7673 [(parallel
7674 [(set (match_dup 0) (and:BLK (match_dup 0) (match_dup 1)))
7675 (use (match_dup 2))
7676 (clobber (reg:CC CC_REGNUM))])]
7677 {
7678 operands[2] = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[0])));
7679 operands[0] = adjust_address (operands[0], BLKmode, 0);
7680 operands[1] = adjust_address (operands[1], BLKmode, 0);
7681 })
7682
7683 (define_peephole2
7684 [(parallel
7685 [(set (match_operand:BLK 0 "memory_operand" "")
7686 (and:BLK (match_dup 0)
7687 (match_operand:BLK 1 "memory_operand" "")))
7688 (use (match_operand 2 "const_int_operand" ""))
7689 (clobber (reg:CC CC_REGNUM))])
7690 (parallel
7691 [(set (match_operand:BLK 3 "memory_operand" "")
7692 (and:BLK (match_dup 3)
7693 (match_operand:BLK 4 "memory_operand" "")))
7694 (use (match_operand 5 "const_int_operand" ""))
7695 (clobber (reg:CC CC_REGNUM))])]
7696 "s390_offset_p (operands[0], operands[3], operands[2])
7697 && s390_offset_p (operands[1], operands[4], operands[2])
7698 && !s390_overlap_p (operands[0], operands[1],
7699 INTVAL (operands[2]) + INTVAL (operands[5]))
7700 && INTVAL (operands[2]) + INTVAL (operands[5]) <= 256"
7701 [(parallel
7702 [(set (match_dup 6) (and:BLK (match_dup 6) (match_dup 7)))
7703 (use (match_dup 8))
7704 (clobber (reg:CC CC_REGNUM))])]
7705 "operands[6] = gen_rtx_MEM (BLKmode, XEXP (operands[0], 0));
7706 operands[7] = gen_rtx_MEM (BLKmode, XEXP (operands[1], 0));
7707 operands[8] = GEN_INT (INTVAL (operands[2]) + INTVAL (operands[5]));")
7708
7709
7710 ;;
7711 ;;- Bit set (inclusive or) instructions.
7712 ;;
7713
7714 (define_expand "ior<mode>3"
7715 [(set (match_operand:INT 0 "nonimmediate_operand" "")
7716 (ior:INT (match_operand:INT 1 "nonimmediate_operand" "")
7717 (match_operand:INT 2 "general_operand" "")))
7718 (clobber (reg:CC CC_REGNUM))]
7719 ""
7720 "s390_expand_logical_operator (IOR, <MODE>mode, operands); DONE;")
7721
7722 ;
7723 ; iordi3 instruction pattern(s).
7724 ;
7725
7726 (define_insn "*iordi3_cc"
7727 [(set (reg CC_REGNUM)
7728 (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,d,0")
7729 (match_operand:DI 2 "general_operand" " d,d,T"))
7730 (const_int 0)))
7731 (set (match_operand:DI 0 "register_operand" "=d,d,d")
7732 (ior:DI (match_dup 1) (match_dup 2)))]
7733 "s390_match_ccmode(insn, CCTmode) && TARGET_ZARCH"
7734 "@
7735 ogr\t%0,%2
7736 ogrk\t%0,%1,%2
7737 og\t%0,%2"
7738 [(set_attr "op_type" "RRE,RRF,RXY")
7739 (set_attr "cpu_facility" "*,z196,*")
7740 (set_attr "z10prop" "z10_super_E1,*,z10_super_E1")])
7741
7742 (define_insn "*iordi3_cconly"
7743 [(set (reg CC_REGNUM)
7744 (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,d,0")
7745 (match_operand:DI 2 "general_operand" " d,d,T"))
7746 (const_int 0)))
7747 (clobber (match_scratch:DI 0 "=d,d,d"))]
7748 "s390_match_ccmode(insn, CCTmode) && TARGET_ZARCH"
7749 "@
7750 ogr\t%0,%2
7751 ogrk\t%0,%1,%2
7752 og\t%0,%2"
7753 [(set_attr "op_type" "RRE,RRF,RXY")
7754 (set_attr "cpu_facility" "*,z196,*")
7755 (set_attr "z10prop" "z10_super_E1,*,z10_super_E1")])
7756
7757 (define_insn "*iordi3"
7758 [(set (match_operand:DI 0 "nonimmediate_operand"
7759 "=d, d, d, d, d, d,d,d,d, AQ,Q")
7760 (ior:DI (match_operand:DI 1 "nonimmediate_operand"
7761 " %0, 0, 0, 0, 0, 0,0,d,0, 0,0")
7762 (match_operand:DI 2 "general_operand"
7763 "N0HD0,N1HD0,N2HD0,N3HD0,N0SD0,N1SD0,d,d,T,NxQD0,Q")))
7764 (clobber (reg:CC CC_REGNUM))]
7765 "TARGET_ZARCH && s390_logical_operator_ok_p (operands)"
7766 "@
7767 oihh\t%0,%i2
7768 oihl\t%0,%i2
7769 oilh\t%0,%i2
7770 oill\t%0,%i2
7771 oihf\t%0,%k2
7772 oilf\t%0,%k2
7773 ogr\t%0,%2
7774 ogrk\t%0,%1,%2
7775 og\t%0,%2
7776 #
7777 #"
7778 [(set_attr "op_type" "RI,RI,RI,RI,RIL,RIL,RRE,RRF,RXY,SI,SS")
7779 (set_attr "cpu_facility" "*,*,*,*,extimm,extimm,*,z196,*,*,*")
7780 (set_attr "z10prop" "z10_super_E1,
7781 z10_super_E1,
7782 z10_super_E1,
7783 z10_super_E1,
7784 z10_super_E1,
7785 z10_super_E1,
7786 z10_super_E1,
7787 *,
7788 z10_super_E1,
7789 *,
7790 *")])
7791
7792 (define_split
7793 [(set (match_operand:DI 0 "s_operand" "")
7794 (ior:DI (match_dup 0) (match_operand:DI 1 "immediate_operand" "")))
7795 (clobber (reg:CC CC_REGNUM))]
7796 "reload_completed"
7797 [(parallel
7798 [(set (match_dup 0) (ior:QI (match_dup 0) (match_dup 1)))
7799 (clobber (reg:CC CC_REGNUM))])]
7800 "s390_narrow_logical_operator (IOR, &operands[0], &operands[1]);")
7801
7802 ;
7803 ; iorsi3 instruction pattern(s).
7804 ;
7805
7806 (define_insn "*iorsi3_cc"
7807 [(set (reg CC_REGNUM)
7808 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,d,0,0")
7809 (match_operand:SI 2 "general_operand" "Os,d,d,R,T"))
7810 (const_int 0)))
7811 (set (match_operand:SI 0 "register_operand" "=d,d,d,d,d")
7812 (ior:SI (match_dup 1) (match_dup 2)))]
7813 "s390_match_ccmode(insn, CCTmode)"
7814 "@
7815 oilf\t%0,%o2
7816 or\t%0,%2
7817 ork\t%0,%1,%2
7818 o\t%0,%2
7819 oy\t%0,%2"
7820 [(set_attr "op_type" "RIL,RR,RRF,RX,RXY")
7821 (set_attr "cpu_facility" "*,*,z196,*,longdisp")
7822 (set_attr "z10prop" "z10_super_E1,z10_super_E1,*,z10_super_E1,z10_super_E1")])
7823
7824 (define_insn "*iorsi3_cconly"
7825 [(set (reg CC_REGNUM)
7826 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,d,0,0")
7827 (match_operand:SI 2 "general_operand" "Os,d,d,R,T"))
7828 (const_int 0)))
7829 (clobber (match_scratch:SI 0 "=d,d,d,d,d"))]
7830 "s390_match_ccmode(insn, CCTmode)"
7831 "@
7832 oilf\t%0,%o2
7833 or\t%0,%2
7834 ork\t%0,%1,%2
7835 o\t%0,%2
7836 oy\t%0,%2"
7837 [(set_attr "op_type" "RIL,RR,RRF,RX,RXY")
7838 (set_attr "cpu_facility" "*,*,z196,*,longdisp")
7839 (set_attr "z10prop" "z10_super_E1,z10_super_E1,*,z10_super_E1,z10_super_E1")])
7840
7841 (define_insn "*iorsi3_zarch"
7842 [(set (match_operand:SI 0 "nonimmediate_operand" "=d, d, d,d,d,d,d, AQ,Q")
7843 (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0, 0, 0,0,d,0,0, 0,0")
7844 (match_operand:SI 2 "general_operand" "N0HS0,N1HS0,Os,d,d,R,T,NxQS0,Q")))
7845 (clobber (reg:CC CC_REGNUM))]
7846 "TARGET_ZARCH && s390_logical_operator_ok_p (operands)"
7847 "@
7848 oilh\t%0,%i2
7849 oill\t%0,%i2
7850 oilf\t%0,%o2
7851 or\t%0,%2
7852 ork\t%0,%1,%2
7853 o\t%0,%2
7854 oy\t%0,%2
7855 #
7856 #"
7857 [(set_attr "op_type" "RI,RI,RIL,RR,RRF,RX,RXY,SI,SS")
7858 (set_attr "cpu_facility" "*,*,*,*,z196,*,longdisp,*,*")
7859 (set_attr "z10prop" "z10_super_E1,
7860 z10_super_E1,
7861 z10_super_E1,
7862 z10_super_E1,
7863 *,
7864 z10_super_E1,
7865 z10_super_E1,
7866 *,
7867 *")])
7868
7869 (define_insn "*iorsi3_esa"
7870 [(set (match_operand:SI 0 "nonimmediate_operand" "=d,d,AQ,Q")
7871 (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,0,0")
7872 (match_operand:SI 2 "general_operand" "d,R,NxQS0,Q")))
7873 (clobber (reg:CC CC_REGNUM))]
7874 "!TARGET_ZARCH && s390_logical_operator_ok_p (operands)"
7875 "@
7876 or\t%0,%2
7877 o\t%0,%2
7878 #
7879 #"
7880 [(set_attr "op_type" "RR,RX,SI,SS")
7881 (set_attr "z10prop" "z10_super_E1,z10_super_E1,*,*")])
7882
7883 (define_split
7884 [(set (match_operand:SI 0 "s_operand" "")
7885 (ior:SI (match_dup 0) (match_operand:SI 1 "immediate_operand" "")))
7886 (clobber (reg:CC CC_REGNUM))]
7887 "reload_completed"
7888 [(parallel
7889 [(set (match_dup 0) (ior:QI (match_dup 0) (match_dup 1)))
7890 (clobber (reg:CC CC_REGNUM))])]
7891 "s390_narrow_logical_operator (IOR, &operands[0], &operands[1]);")
7892
7893 ;
7894 ; iorhi3 instruction pattern(s).
7895 ;
7896
7897 (define_insn "*iorhi3_zarch"
7898 [(set (match_operand:HI 0 "nonimmediate_operand" "=d,d,d, AQ,Q")
7899 (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,d,0, 0,0")
7900 (match_operand:HI 2 "general_operand" " d,d,n,NxQH0,Q")))
7901 (clobber (reg:CC CC_REGNUM))]
7902 "TARGET_ZARCH && s390_logical_operator_ok_p (operands)"
7903 "@
7904 or\t%0,%2
7905 ork\t%0,%1,%2
7906 oill\t%0,%x2
7907 #
7908 #"
7909 [(set_attr "op_type" "RR,RRF,RI,SI,SS")
7910 (set_attr "cpu_facility" "*,z196,*,*,*")
7911 (set_attr "z10prop" "z10_super_E1,*,z10_super_E1,*,*")])
7912
7913 (define_insn "*iorhi3_esa"
7914 [(set (match_operand:HI 0 "nonimmediate_operand" "=d,AQ,Q")
7915 (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,0")
7916 (match_operand:HI 2 "general_operand" "d,NxQH0,Q")))
7917 (clobber (reg:CC CC_REGNUM))]
7918 "!TARGET_ZARCH && s390_logical_operator_ok_p (operands)"
7919 "@
7920 or\t%0,%2
7921 #
7922 #"
7923 [(set_attr "op_type" "RR,SI,SS")
7924 (set_attr "z10prop" "z10_super_E1,*,*")])
7925
7926 (define_split
7927 [(set (match_operand:HI 0 "s_operand" "")
7928 (ior:HI (match_dup 0) (match_operand:HI 1 "immediate_operand" "")))
7929 (clobber (reg:CC CC_REGNUM))]
7930 "reload_completed"
7931 [(parallel
7932 [(set (match_dup 0) (ior:QI (match_dup 0) (match_dup 1)))
7933 (clobber (reg:CC CC_REGNUM))])]
7934 "s390_narrow_logical_operator (IOR, &operands[0], &operands[1]);")
7935
7936 ;
7937 ; iorqi3 instruction pattern(s).
7938 ;
7939
7940 (define_insn "*iorqi3_zarch"
7941 [(set (match_operand:QI 0 "nonimmediate_operand" "=d,d,d,Q,S,Q")
7942 (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,d,0,0,0,0")
7943 (match_operand:QI 2 "general_operand" " d,d,n,n,n,Q")))
7944 (clobber (reg:CC CC_REGNUM))]
7945 "TARGET_ZARCH && s390_logical_operator_ok_p (operands)"
7946 "@
7947 or\t%0,%2
7948 ork\t%0,%1,%2
7949 oill\t%0,%b2
7950 oi\t%S0,%b2
7951 oiy\t%S0,%b2
7952 #"
7953 [(set_attr "op_type" "RR,RRF,RI,SI,SIY,SS")
7954 (set_attr "cpu_facility" "*,z196,*,*,longdisp,*")
7955 (set_attr "z10prop" "z10_super_E1,*,z10_super_E1,
7956 z10_super,z10_super,*")])
7957
7958 (define_insn "*iorqi3_esa"
7959 [(set (match_operand:QI 0 "nonimmediate_operand" "=d,Q,Q")
7960 (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
7961 (match_operand:QI 2 "general_operand" "d,n,Q")))
7962 (clobber (reg:CC CC_REGNUM))]
7963 "!TARGET_ZARCH && s390_logical_operator_ok_p (operands)"
7964 "@
7965 or\t%0,%2
7966 oi\t%S0,%b2
7967 #"
7968 [(set_attr "op_type" "RR,SI,SS")
7969 (set_attr "z10prop" "z10_super_E1,z10_super,*")])
7970
7971 ;
7972 ; Block inclusive or (OC) patterns.
7973 ;
7974
7975 (define_insn "*oc"
7976 [(set (match_operand:BLK 0 "memory_operand" "=Q")
7977 (ior:BLK (match_dup 0)
7978 (match_operand:BLK 1 "memory_operand" "Q")))
7979 (use (match_operand 2 "const_int_operand" "n"))
7980 (clobber (reg:CC CC_REGNUM))]
7981 "INTVAL (operands[2]) >= 1 && INTVAL (operands[2]) <= 256"
7982 "oc\t%O0(%2,%R0),%S1"
7983 [(set_attr "op_type" "SS")
7984 (set_attr "z196prop" "z196_cracked")])
7985
7986 (define_split
7987 [(set (match_operand 0 "memory_operand" "")
7988 (ior (match_dup 0)
7989 (match_operand 1 "memory_operand" "")))
7990 (clobber (reg:CC CC_REGNUM))]
7991 "reload_completed
7992 && GET_MODE (operands[0]) == GET_MODE (operands[1])
7993 && GET_MODE_SIZE (GET_MODE (operands[0])) > 0"
7994 [(parallel
7995 [(set (match_dup 0) (ior:BLK (match_dup 0) (match_dup 1)))
7996 (use (match_dup 2))
7997 (clobber (reg:CC CC_REGNUM))])]
7998 {
7999 operands[2] = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[0])));
8000 operands[0] = adjust_address (operands[0], BLKmode, 0);
8001 operands[1] = adjust_address (operands[1], BLKmode, 0);
8002 })
8003
8004 (define_peephole2
8005 [(parallel
8006 [(set (match_operand:BLK 0 "memory_operand" "")
8007 (ior:BLK (match_dup 0)
8008 (match_operand:BLK 1 "memory_operand" "")))
8009 (use (match_operand 2 "const_int_operand" ""))
8010 (clobber (reg:CC CC_REGNUM))])
8011 (parallel
8012 [(set (match_operand:BLK 3 "memory_operand" "")
8013 (ior:BLK (match_dup 3)
8014 (match_operand:BLK 4 "memory_operand" "")))
8015 (use (match_operand 5 "const_int_operand" ""))
8016 (clobber (reg:CC CC_REGNUM))])]
8017 "s390_offset_p (operands[0], operands[3], operands[2])
8018 && s390_offset_p (operands[1], operands[4], operands[2])
8019 && !s390_overlap_p (operands[0], operands[1],
8020 INTVAL (operands[2]) + INTVAL (operands[5]))
8021 && INTVAL (operands[2]) + INTVAL (operands[5]) <= 256"
8022 [(parallel
8023 [(set (match_dup 6) (ior:BLK (match_dup 6) (match_dup 7)))
8024 (use (match_dup 8))
8025 (clobber (reg:CC CC_REGNUM))])]
8026 "operands[6] = gen_rtx_MEM (BLKmode, XEXP (operands[0], 0));
8027 operands[7] = gen_rtx_MEM (BLKmode, XEXP (operands[1], 0));
8028 operands[8] = GEN_INT (INTVAL (operands[2]) + INTVAL (operands[5]));")
8029
8030
8031 ;;
8032 ;;- Xor instructions.
8033 ;;
8034
8035 (define_expand "xor<mode>3"
8036 [(set (match_operand:INT 0 "nonimmediate_operand" "")
8037 (xor:INT (match_operand:INT 1 "nonimmediate_operand" "")
8038 (match_operand:INT 2 "general_operand" "")))
8039 (clobber (reg:CC CC_REGNUM))]
8040 ""
8041 "s390_expand_logical_operator (XOR, <MODE>mode, operands); DONE;")
8042
8043 ; Combine replaces (xor (x) (const_int -1)) with (not (x)) when doing
8044 ; simplifications. So its better to have something matching.
8045 (define_split
8046 [(set (match_operand:INT 0 "nonimmediate_operand" "")
8047 (not:INT (match_operand:INT 1 "nonimmediate_operand" "")))]
8048 ""
8049 [(parallel
8050 [(set (match_dup 0) (xor:INT (match_dup 1) (match_dup 2)))
8051 (clobber (reg:CC CC_REGNUM))])]
8052 {
8053 operands[2] = constm1_rtx;
8054 if (!s390_logical_operator_ok_p (operands))
8055 FAIL;
8056 })
8057
8058 ;
8059 ; xordi3 instruction pattern(s).
8060 ;
8061
8062 (define_insn "*xordi3_cc"
8063 [(set (reg CC_REGNUM)
8064 (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,d,0")
8065 (match_operand:DI 2 "general_operand" " d,d,T"))
8066 (const_int 0)))
8067 (set (match_operand:DI 0 "register_operand" "=d,d,d")
8068 (xor:DI (match_dup 1) (match_dup 2)))]
8069 "s390_match_ccmode(insn, CCTmode) && TARGET_ZARCH"
8070 "@
8071 xgr\t%0,%2
8072 xgrk\t%0,%1,%2
8073 xg\t%0,%2"
8074 [(set_attr "op_type" "RRE,RRF,RXY")
8075 (set_attr "cpu_facility" "*,z196,*")
8076 (set_attr "z10prop" "z10_super_E1,*,z10_super_E1")])
8077
8078 (define_insn "*xordi3_cconly"
8079 [(set (reg CC_REGNUM)
8080 (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,d,0")
8081 (match_operand:DI 2 "general_operand" " d,d,T"))
8082 (const_int 0)))
8083 (clobber (match_scratch:DI 0 "=d,d,d"))]
8084 "s390_match_ccmode(insn, CCTmode) && TARGET_ZARCH"
8085 "@
8086 xgr\t%0,%2
8087 xgrk\t%0,%1,%2
8088 xg\t%0,%2"
8089 [(set_attr "op_type" "RRE,RRF,RXY")
8090 (set_attr "cpu_facility" "*,z196,*")
8091 (set_attr "z10prop" "z10_super_E1,*,z10_super_E1")])
8092
8093 (define_insn "*xordi3"
8094 [(set (match_operand:DI 0 "nonimmediate_operand" "=d, d,d,d,d, AQ,Q")
8095 (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0, 0,0,d,0, 0,0")
8096 (match_operand:DI 2 "general_operand" "N0SD0,N1SD0,d,d,T,NxQD0,Q")))
8097 (clobber (reg:CC CC_REGNUM))]
8098 "TARGET_ZARCH && s390_logical_operator_ok_p (operands)"
8099 "@
8100 xihf\t%0,%k2
8101 xilf\t%0,%k2
8102 xgr\t%0,%2
8103 xgrk\t%0,%1,%2
8104 xg\t%0,%2
8105 #
8106 #"
8107 [(set_attr "op_type" "RIL,RIL,RRE,RRF,RXY,SI,SS")
8108 (set_attr "cpu_facility" "extimm,extimm,*,z196,*,*,*")
8109 (set_attr "z10prop" "z10_super_E1,z10_super_E1,z10_super_E1,
8110 *,z10_super_E1,*,*")])
8111
8112 (define_split
8113 [(set (match_operand:DI 0 "s_operand" "")
8114 (xor:DI (match_dup 0) (match_operand:DI 1 "immediate_operand" "")))
8115 (clobber (reg:CC CC_REGNUM))]
8116 "reload_completed"
8117 [(parallel
8118 [(set (match_dup 0) (xor:QI (match_dup 0) (match_dup 1)))
8119 (clobber (reg:CC CC_REGNUM))])]
8120 "s390_narrow_logical_operator (XOR, &operands[0], &operands[1]);")
8121
8122 ;
8123 ; xorsi3 instruction pattern(s).
8124 ;
8125
8126 (define_insn "*xorsi3_cc"
8127 [(set (reg CC_REGNUM)
8128 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,d,0,0")
8129 (match_operand:SI 2 "general_operand" "Os,d,d,R,T"))
8130 (const_int 0)))
8131 (set (match_operand:SI 0 "register_operand" "=d,d,d,d,d")
8132 (xor:SI (match_dup 1) (match_dup 2)))]
8133 "s390_match_ccmode(insn, CCTmode)"
8134 "@
8135 xilf\t%0,%o2
8136 xr\t%0,%2
8137 xrk\t%0,%1,%2
8138 x\t%0,%2
8139 xy\t%0,%2"
8140 [(set_attr "op_type" "RIL,RR,RRF,RX,RXY")
8141 (set_attr "cpu_facility" "*,*,z196,*,longdisp")
8142 (set_attr "z10prop" "z10_super_E1,z10_super_E1,*,
8143 z10_super_E1,z10_super_E1")])
8144
8145 (define_insn "*xorsi3_cconly"
8146 [(set (reg CC_REGNUM)
8147 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,d,0,0")
8148 (match_operand:SI 2 "general_operand" "Os,d,d,R,T"))
8149 (const_int 0)))
8150 (clobber (match_scratch:SI 0 "=d,d,d,d,d"))]
8151 "s390_match_ccmode(insn, CCTmode)"
8152 "@
8153 xilf\t%0,%o2
8154 xr\t%0,%2
8155 xrk\t%0,%1,%2
8156 x\t%0,%2
8157 xy\t%0,%2"
8158 [(set_attr "op_type" "RIL,RR,RRF,RX,RXY")
8159 (set_attr "cpu_facility" "*,*,z196,*,longdisp")
8160 (set_attr "z10prop" "z10_super_E1,z10_super_E1,*,
8161 z10_super_E1,z10_super_E1")])
8162
8163 (define_insn "*xorsi3"
8164 [(set (match_operand:SI 0 "nonimmediate_operand" "=d,d,d,d,d, AQ,Q")
8165 (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,d,0,0, 0,0")
8166 (match_operand:SI 2 "general_operand" "Os,d,d,R,T,NxQS0,Q")))
8167 (clobber (reg:CC CC_REGNUM))]
8168 "s390_logical_operator_ok_p (operands)"
8169 "@
8170 xilf\t%0,%o2
8171 xr\t%0,%2
8172 xrk\t%0,%1,%2
8173 x\t%0,%2
8174 xy\t%0,%2
8175 #
8176 #"
8177 [(set_attr "op_type" "RIL,RR,RRF,RX,RXY,SI,SS")
8178 (set_attr "cpu_facility" "*,*,z196,*,longdisp,*,*")
8179 (set_attr "z10prop" "z10_super_E1,z10_super_E1,*,
8180 z10_super_E1,z10_super_E1,*,*")])
8181
8182 (define_split
8183 [(set (match_operand:SI 0 "s_operand" "")
8184 (xor:SI (match_dup 0) (match_operand:SI 1 "immediate_operand" "")))
8185 (clobber (reg:CC CC_REGNUM))]
8186 "reload_completed"
8187 [(parallel
8188 [(set (match_dup 0) (xor:QI (match_dup 0) (match_dup 1)))
8189 (clobber (reg:CC CC_REGNUM))])]
8190 "s390_narrow_logical_operator (XOR, &operands[0], &operands[1]);")
8191
8192 ;
8193 ; xorhi3 instruction pattern(s).
8194 ;
8195
8196 (define_insn "*xorhi3"
8197 [(set (match_operand:HI 0 "nonimmediate_operand" "=d,d,d, AQ,Q")
8198 (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,d, 0,0")
8199 (match_operand:HI 2 "general_operand" "Os,d,d,NxQH0,Q")))
8200 (clobber (reg:CC CC_REGNUM))]
8201 "s390_logical_operator_ok_p (operands)"
8202 "@
8203 xilf\t%0,%x2
8204 xr\t%0,%2
8205 xrk\t%0,%1,%2
8206 #
8207 #"
8208 [(set_attr "op_type" "RIL,RR,RRF,SI,SS")
8209 (set_attr "cpu_facility" "*,*,z196,*,*")
8210 (set_attr "z10prop" "z10_super_E1,z10_super_E1,*,*,*")])
8211
8212 (define_split
8213 [(set (match_operand:HI 0 "s_operand" "")
8214 (xor:HI (match_dup 0) (match_operand:HI 1 "immediate_operand" "")))
8215 (clobber (reg:CC CC_REGNUM))]
8216 "reload_completed"
8217 [(parallel
8218 [(set (match_dup 0) (xor:QI (match_dup 0) (match_dup 1)))
8219 (clobber (reg:CC CC_REGNUM))])]
8220 "s390_narrow_logical_operator (XOR, &operands[0], &operands[1]);")
8221
8222 ;
8223 ; xorqi3 instruction pattern(s).
8224 ;
8225
8226 (define_insn "*xorqi3"
8227 [(set (match_operand:QI 0 "nonimmediate_operand" "=d,d,d,Q,S,Q")
8228 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,d,0,0,0")
8229 (match_operand:QI 2 "general_operand" "Os,d,d,n,n,Q")))
8230 (clobber (reg:CC CC_REGNUM))]
8231 "s390_logical_operator_ok_p (operands)"
8232 "@
8233 xilf\t%0,%b2
8234 xr\t%0,%2
8235 xrk\t%0,%1,%2
8236 xi\t%S0,%b2
8237 xiy\t%S0,%b2
8238 #"
8239 [(set_attr "op_type" "RIL,RR,RRF,SI,SIY,SS")
8240 (set_attr "cpu_facility" "*,*,z196,*,longdisp,*")
8241 (set_attr "z10prop" "z10_super_E1,z10_super_E1,*,z10_super,z10_super,*")])
8242
8243
8244 ;
8245 ; Block exclusive or (XC) patterns.
8246 ;
8247
8248 (define_insn "*xc"
8249 [(set (match_operand:BLK 0 "memory_operand" "=Q")
8250 (xor:BLK (match_dup 0)
8251 (match_operand:BLK 1 "memory_operand" "Q")))
8252 (use (match_operand 2 "const_int_operand" "n"))
8253 (clobber (reg:CC CC_REGNUM))]
8254 "INTVAL (operands[2]) >= 1 && INTVAL (operands[2]) <= 256"
8255 "xc\t%O0(%2,%R0),%S1"
8256 [(set_attr "op_type" "SS")])
8257
8258 (define_split
8259 [(set (match_operand 0 "memory_operand" "")
8260 (xor (match_dup 0)
8261 (match_operand 1 "memory_operand" "")))
8262 (clobber (reg:CC CC_REGNUM))]
8263 "reload_completed
8264 && GET_MODE (operands[0]) == GET_MODE (operands[1])
8265 && GET_MODE_SIZE (GET_MODE (operands[0])) > 0"
8266 [(parallel
8267 [(set (match_dup 0) (xor:BLK (match_dup 0) (match_dup 1)))
8268 (use (match_dup 2))
8269 (clobber (reg:CC CC_REGNUM))])]
8270 {
8271 operands[2] = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[0])));
8272 operands[0] = adjust_address (operands[0], BLKmode, 0);
8273 operands[1] = adjust_address (operands[1], BLKmode, 0);
8274 })
8275
8276 (define_peephole2
8277 [(parallel
8278 [(set (match_operand:BLK 0 "memory_operand" "")
8279 (xor:BLK (match_dup 0)
8280 (match_operand:BLK 1 "memory_operand" "")))
8281 (use (match_operand 2 "const_int_operand" ""))
8282 (clobber (reg:CC CC_REGNUM))])
8283 (parallel
8284 [(set (match_operand:BLK 3 "memory_operand" "")
8285 (xor:BLK (match_dup 3)
8286 (match_operand:BLK 4 "memory_operand" "")))
8287 (use (match_operand 5 "const_int_operand" ""))
8288 (clobber (reg:CC CC_REGNUM))])]
8289 "s390_offset_p (operands[0], operands[3], operands[2])
8290 && s390_offset_p (operands[1], operands[4], operands[2])
8291 && !s390_overlap_p (operands[0], operands[1],
8292 INTVAL (operands[2]) + INTVAL (operands[5]))
8293 && INTVAL (operands[2]) + INTVAL (operands[5]) <= 256"
8294 [(parallel
8295 [(set (match_dup 6) (xor:BLK (match_dup 6) (match_dup 7)))
8296 (use (match_dup 8))
8297 (clobber (reg:CC CC_REGNUM))])]
8298 "operands[6] = gen_rtx_MEM (BLKmode, XEXP (operands[0], 0));
8299 operands[7] = gen_rtx_MEM (BLKmode, XEXP (operands[1], 0));
8300 operands[8] = GEN_INT (INTVAL (operands[2]) + INTVAL (operands[5]));")
8301
8302 ;
8303 ; Block xor (XC) patterns with src == dest.
8304 ;
8305
8306 (define_insn "*xc_zero"
8307 [(set (match_operand:BLK 0 "memory_operand" "=Q")
8308 (const_int 0))
8309 (use (match_operand 1 "const_int_operand" "n"))
8310 (clobber (reg:CC CC_REGNUM))]
8311 "INTVAL (operands[1]) >= 1 && INTVAL (operands[1]) <= 256"
8312 "xc\t%O0(%1,%R0),%S0"
8313 [(set_attr "op_type" "SS")
8314 (set_attr "z196prop" "z196_cracked")])
8315
8316 (define_peephole2
8317 [(parallel
8318 [(set (match_operand:BLK 0 "memory_operand" "")
8319 (const_int 0))
8320 (use (match_operand 1 "const_int_operand" ""))
8321 (clobber (reg:CC CC_REGNUM))])
8322 (parallel
8323 [(set (match_operand:BLK 2 "memory_operand" "")
8324 (const_int 0))
8325 (use (match_operand 3 "const_int_operand" ""))
8326 (clobber (reg:CC CC_REGNUM))])]
8327 "s390_offset_p (operands[0], operands[2], operands[1])
8328 && INTVAL (operands[1]) + INTVAL (operands[3]) <= 256"
8329 [(parallel
8330 [(set (match_dup 4) (const_int 0))
8331 (use (match_dup 5))
8332 (clobber (reg:CC CC_REGNUM))])]
8333 "operands[4] = gen_rtx_MEM (BLKmode, XEXP (operands[0], 0));
8334 operands[5] = GEN_INT (INTVAL (operands[1]) + INTVAL (operands[3]));")
8335
8336
8337 ;;
8338 ;;- Negate instructions.
8339 ;;
8340
8341 ;
8342 ; neg(di|si)2 instruction pattern(s).
8343 ;
8344
8345 (define_expand "neg<mode>2"
8346 [(parallel
8347 [(set (match_operand:DSI 0 "register_operand" "=d")
8348 (neg:DSI (match_operand:DSI 1 "register_operand" "d")))
8349 (clobber (reg:CC CC_REGNUM))])]
8350 ""
8351 "")
8352
8353 (define_insn "*negdi2_sign_cc"
8354 [(set (reg CC_REGNUM)
8355 (compare (neg:DI (ashiftrt:DI (ashift:DI (subreg:DI
8356 (match_operand:SI 1 "register_operand" "d") 0)
8357 (const_int 32)) (const_int 32)))
8358 (const_int 0)))
8359 (set (match_operand:DI 0 "register_operand" "=d")
8360 (neg:DI (sign_extend:DI (match_dup 1))))]
8361 "TARGET_ZARCH && s390_match_ccmode (insn, CCAmode)"
8362 "lcgfr\t%0,%1"
8363 [(set_attr "op_type" "RRE")
8364 (set_attr "z10prop" "z10_c")])
8365
8366 (define_insn "*negdi2_sign"
8367 [(set (match_operand:DI 0 "register_operand" "=d")
8368 (neg:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "d"))))
8369 (clobber (reg:CC CC_REGNUM))]
8370 "TARGET_ZARCH"
8371 "lcgfr\t%0,%1"
8372 [(set_attr "op_type" "RRE")
8373 (set_attr "z10prop" "z10_c")])
8374
8375 ; lcr, lcgr
8376 (define_insn "*neg<mode>2_cc"
8377 [(set (reg CC_REGNUM)
8378 (compare (neg:GPR (match_operand:GPR 1 "register_operand" "d"))
8379 (const_int 0)))
8380 (set (match_operand:GPR 0 "register_operand" "=d")
8381 (neg:GPR (match_dup 1)))]
8382 "s390_match_ccmode (insn, CCAmode)"
8383 "lc<g>r\t%0,%1"
8384 [(set_attr "op_type" "RR<E>")
8385 (set_attr "z10prop" "z10_super_c_E1")])
8386
8387 ; lcr, lcgr
8388 (define_insn "*neg<mode>2_cconly"
8389 [(set (reg CC_REGNUM)
8390 (compare (neg:GPR (match_operand:GPR 1 "register_operand" "d"))
8391 (const_int 0)))
8392 (clobber (match_scratch:GPR 0 "=d"))]
8393 "s390_match_ccmode (insn, CCAmode)"
8394 "lc<g>r\t%0,%1"
8395 [(set_attr "op_type" "RR<E>")
8396 (set_attr "z10prop" "z10_super_c_E1")])
8397
8398 ; lcr, lcgr
8399 (define_insn "*neg<mode>2"
8400 [(set (match_operand:GPR 0 "register_operand" "=d")
8401 (neg:GPR (match_operand:GPR 1 "register_operand" "d")))
8402 (clobber (reg:CC CC_REGNUM))]
8403 ""
8404 "lc<g>r\t%0,%1"
8405 [(set_attr "op_type" "RR<E>")
8406 (set_attr "z10prop" "z10_super_c_E1")])
8407
8408 (define_insn "*negdi2_31"
8409 [(set (match_operand:DI 0 "register_operand" "=d")
8410 (neg:DI (match_operand:DI 1 "register_operand" "d")))
8411 (clobber (reg:CC CC_REGNUM))]
8412 "!TARGET_ZARCH"
8413 "#")
8414
8415 ; Split a DImode NEG on 31bit into 2 SImode NEGs
8416
8417 ; Doing the twos complement separately on the SImode parts does an
8418 ; unwanted +1 on the high part which needs to be subtracted afterwards
8419 ; ... unless the +1 on the low part created an overflow.
8420
8421 (define_split
8422 [(set (match_operand:DI 0 "register_operand" "")
8423 (neg:DI (match_operand:DI 1 "register_operand" "")))
8424 (clobber (reg:CC CC_REGNUM))]
8425 "!TARGET_ZARCH
8426 && (REGNO (operands[0]) == REGNO (operands[1])
8427 || s390_split_ok_p (operands[0], operands[1], DImode, 0))
8428 && reload_completed"
8429 [(parallel
8430 [(set (match_dup 2) (neg:SI (match_dup 3)))
8431 (clobber (reg:CC CC_REGNUM))])
8432 (parallel
8433 [(set (reg:CCAP CC_REGNUM)
8434 (compare:CCAP (neg:SI (match_dup 5)) (const_int 0)))
8435 (set (match_dup 4) (neg:SI (match_dup 5)))])
8436 (set (pc)
8437 (if_then_else (ne (reg:CCAP CC_REGNUM) (const_int 0))
8438 (pc)
8439 (label_ref (match_dup 6))))
8440 (parallel
8441 [(set (match_dup 2) (plus:SI (match_dup 2) (const_int -1)))
8442 (clobber (reg:CC CC_REGNUM))])
8443 (match_dup 6)]
8444 "operands[2] = operand_subword (operands[0], 0, 0, DImode);
8445 operands[3] = operand_subword (operands[1], 0, 0, DImode);
8446 operands[4] = operand_subword (operands[0], 1, 0, DImode);
8447 operands[5] = operand_subword (operands[1], 1, 0, DImode);
8448 operands[6] = gen_label_rtx ();")
8449
8450 ; Like above but first make a copy of the low part of the src operand
8451 ; since it might overlap with the high part of the destination.
8452
8453 (define_split
8454 [(set (match_operand:DI 0 "register_operand" "")
8455 (neg:DI (match_operand:DI 1 "register_operand" "")))
8456 (clobber (reg:CC CC_REGNUM))]
8457 "!TARGET_ZARCH
8458 && s390_split_ok_p (operands[0], operands[1], DImode, 1)
8459 && reload_completed"
8460 [; Make a backup of op5 first
8461 (set (match_dup 4) (match_dup 5))
8462 ; Setting op2 here might clobber op5
8463 (parallel
8464 [(set (match_dup 2) (neg:SI (match_dup 3)))
8465 (clobber (reg:CC CC_REGNUM))])
8466 (parallel
8467 [(set (reg:CCAP CC_REGNUM)
8468 (compare:CCAP (neg:SI (match_dup 4)) (const_int 0)))
8469 (set (match_dup 4) (neg:SI (match_dup 4)))])
8470 (set (pc)
8471 (if_then_else (ne (reg:CCAP CC_REGNUM) (const_int 0))
8472 (pc)
8473 (label_ref (match_dup 6))))
8474 (parallel
8475 [(set (match_dup 2) (plus:SI (match_dup 2) (const_int -1)))
8476 (clobber (reg:CC CC_REGNUM))])
8477 (match_dup 6)]
8478 "operands[2] = operand_subword (operands[0], 0, 0, DImode);
8479 operands[3] = operand_subword (operands[1], 0, 0, DImode);
8480 operands[4] = operand_subword (operands[0], 1, 0, DImode);
8481 operands[5] = operand_subword (operands[1], 1, 0, DImode);
8482 operands[6] = gen_label_rtx ();")
8483
8484 ;
8485 ; neg(df|sf)2 instruction pattern(s).
8486 ;
8487
8488 (define_expand "neg<mode>2"
8489 [(parallel
8490 [(set (match_operand:BFP 0 "register_operand")
8491 (neg:BFP (match_operand:BFP 1 "register_operand")))
8492 (clobber (reg:CC CC_REGNUM))])]
8493 "TARGET_HARD_FLOAT")
8494
8495 ; lcxbr, lcdbr, lcebr
8496 (define_insn "*neg<mode>2_cc"
8497 [(set (reg CC_REGNUM)
8498 (compare (neg:BFP (match_operand:BFP 1 "register_operand" "f"))
8499 (match_operand:BFP 2 "const0_operand" "")))
8500 (set (match_operand:BFP 0 "register_operand" "=f")
8501 (neg:BFP (match_dup 1)))]
8502 "s390_match_ccmode (insn, CCSmode) && TARGET_HARD_FLOAT"
8503 "lc<xde>br\t%0,%1"
8504 [(set_attr "op_type" "RRE")
8505 (set_attr "type" "fsimp<mode>")])
8506
8507 ; lcxbr, lcdbr, lcebr
8508 (define_insn "*neg<mode>2_cconly"
8509 [(set (reg CC_REGNUM)
8510 (compare (neg:BFP (match_operand:BFP 1 "register_operand" "f"))
8511 (match_operand:BFP 2 "const0_operand" "")))
8512 (clobber (match_scratch:BFP 0 "=f"))]
8513 "s390_match_ccmode (insn, CCSmode) && TARGET_HARD_FLOAT"
8514 "lc<xde>br\t%0,%1"
8515 [(set_attr "op_type" "RRE")
8516 (set_attr "type" "fsimp<mode>")])
8517
8518 ; lcdfr
8519 (define_insn "*neg<mode>2_nocc"
8520 [(set (match_operand:FP 0 "register_operand" "=f")
8521 (neg:FP (match_operand:FP 1 "register_operand" "<fT0>")))]
8522 "TARGET_DFP"
8523 "lcdfr\t%0,%1"
8524 [(set_attr "op_type" "RRE")
8525 (set_attr "type" "fsimp<mode>")])
8526
8527 ; lcxbr, lcdbr, lcebr
8528 ; FIXME: wflcdb does not clobber cc
8529 ; FIXME: Does wflcdb ever match here?
8530 (define_insn "*neg<mode>2"
8531 [(set (match_operand:BFP 0 "register_operand" "=f,v,v")
8532 (neg:BFP (match_operand:BFP 1 "register_operand" "f,v,v")))
8533 (clobber (reg:CC CC_REGNUM))]
8534 "TARGET_HARD_FLOAT"
8535 "@
8536 lc<xde>br\t%0,%1
8537 wflcdb\t%0,%1
8538 wflcsb\t%0,%1"
8539 [(set_attr "op_type" "RRE,VRR,VRR")
8540 (set_attr "cpu_facility" "*,vx,vxe")
8541 (set_attr "type" "fsimp<mode>,*,*")
8542 (set_attr "enabled" "*,<DF>,<SF>")])
8543
8544
8545 ;;
8546 ;;- Absolute value instructions.
8547 ;;
8548
8549 ;
8550 ; abs(di|si)2 instruction pattern(s).
8551 ;
8552
8553 (define_insn "*absdi2_sign_cc"
8554 [(set (reg CC_REGNUM)
8555 (compare (abs:DI (ashiftrt:DI (ashift:DI (subreg:DI
8556 (match_operand:SI 1 "register_operand" "d") 0)
8557 (const_int 32)) (const_int 32)))
8558 (const_int 0)))
8559 (set (match_operand:DI 0 "register_operand" "=d")
8560 (abs:DI (sign_extend:DI (match_dup 1))))]
8561 "TARGET_ZARCH && s390_match_ccmode (insn, CCAmode)"
8562 "lpgfr\t%0,%1"
8563 [(set_attr "op_type" "RRE")
8564 (set_attr "z10prop" "z10_c")])
8565
8566 (define_insn "*absdi2_sign"
8567 [(set (match_operand:DI 0 "register_operand" "=d")
8568 (abs:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "d"))))
8569 (clobber (reg:CC CC_REGNUM))]
8570 "TARGET_ZARCH"
8571 "lpgfr\t%0,%1"
8572 [(set_attr "op_type" "RRE")
8573 (set_attr "z10prop" "z10_c")])
8574
8575 ; lpr, lpgr
8576 (define_insn "*abs<mode>2_cc"
8577 [(set (reg CC_REGNUM)
8578 (compare (abs:GPR (match_operand:DI 1 "register_operand" "d"))
8579 (const_int 0)))
8580 (set (match_operand:GPR 0 "register_operand" "=d")
8581 (abs:GPR (match_dup 1)))]
8582 "s390_match_ccmode (insn, CCAmode)"
8583 "lp<g>r\t%0,%1"
8584 [(set_attr "op_type" "RR<E>")
8585 (set_attr "z10prop" "z10_c")])
8586
8587 ; lpr, lpgr
8588 (define_insn "*abs<mode>2_cconly"
8589 [(set (reg CC_REGNUM)
8590 (compare (abs:GPR (match_operand:GPR 1 "register_operand" "d"))
8591 (const_int 0)))
8592 (clobber (match_scratch:GPR 0 "=d"))]
8593 "s390_match_ccmode (insn, CCAmode)"
8594 "lp<g>r\t%0,%1"
8595 [(set_attr "op_type" "RR<E>")
8596 (set_attr "z10prop" "z10_c")])
8597
8598 ; lpr, lpgr
8599 (define_insn "abs<mode>2"
8600 [(set (match_operand:GPR 0 "register_operand" "=d")
8601 (abs:GPR (match_operand:GPR 1 "register_operand" "d")))
8602 (clobber (reg:CC CC_REGNUM))]
8603 ""
8604 "lp<g>r\t%0,%1"
8605 [(set_attr "op_type" "RR<E>")
8606 (set_attr "z10prop" "z10_c")])
8607
8608 ;
8609 ; abs(df|sf)2 instruction pattern(s).
8610 ;
8611
8612 (define_expand "abs<mode>2"
8613 [(parallel
8614 [(set (match_operand:BFP 0 "register_operand" "=f")
8615 (abs:BFP (match_operand:BFP 1 "register_operand" "f")))
8616 (clobber (reg:CC CC_REGNUM))])]
8617 "TARGET_HARD_FLOAT"
8618 "")
8619
8620 ; lpxbr, lpdbr, lpebr
8621 (define_insn "*abs<mode>2_cc"
8622 [(set (reg CC_REGNUM)
8623 (compare (abs:BFP (match_operand:BFP 1 "register_operand" "f"))
8624 (match_operand:BFP 2 "const0_operand" "")))
8625 (set (match_operand:BFP 0 "register_operand" "=f")
8626 (abs:BFP (match_dup 1)))]
8627 "s390_match_ccmode (insn, CCSmode) && TARGET_HARD_FLOAT"
8628 "lp<xde>br\t%0,%1"
8629 [(set_attr "op_type" "RRE")
8630 (set_attr "type" "fsimp<mode>")])
8631
8632 ; lpxbr, lpdbr, lpebr
8633 (define_insn "*abs<mode>2_cconly"
8634 [(set (reg CC_REGNUM)
8635 (compare (abs:BFP (match_operand:BFP 1 "register_operand" "f"))
8636 (match_operand:BFP 2 "const0_operand" "")))
8637 (clobber (match_scratch:BFP 0 "=f"))]
8638 "s390_match_ccmode (insn, CCSmode) && TARGET_HARD_FLOAT"
8639 "lp<xde>br\t%0,%1"
8640 [(set_attr "op_type" "RRE")
8641 (set_attr "type" "fsimp<mode>")])
8642
8643 ; lpdfr
8644 (define_insn "*abs<mode>2_nocc"
8645 [(set (match_operand:FP 0 "register_operand" "=f")
8646 (abs:FP (match_operand:FP 1 "register_operand" "<fT0>")))]
8647 "TARGET_DFP"
8648 "lpdfr\t%0,%1"
8649 [(set_attr "op_type" "RRE")
8650 (set_attr "type" "fsimp<mode>")])
8651
8652 ; lpxbr, lpdbr, lpebr
8653 ; FIXME: wflpdb does not clobber cc
8654 (define_insn "*abs<mode>2"
8655 [(set (match_operand:BFP 0 "register_operand" "=f,v")
8656 (abs:BFP (match_operand:BFP 1 "register_operand" "f,v")))
8657 (clobber (reg:CC CC_REGNUM))]
8658 "TARGET_HARD_FLOAT"
8659 "@
8660 lp<xde>br\t%0,%1
8661 wflpdb\t%0,%1"
8662 [(set_attr "op_type" "RRE,VRR")
8663 (set_attr "cpu_facility" "*,vx")
8664 (set_attr "type" "fsimp<mode>,*")
8665 (set_attr "enabled" "*,<DFDI>")])
8666
8667
8668 ;;
8669 ;;- Negated absolute value instructions
8670 ;;
8671
8672 ;
8673 ; Integer
8674 ;
8675
8676 (define_insn "*negabsdi2_sign_cc"
8677 [(set (reg CC_REGNUM)
8678 (compare (neg:DI (abs:DI (ashiftrt:DI (ashift:DI (subreg:DI
8679 (match_operand:SI 1 "register_operand" "d") 0)
8680 (const_int 32)) (const_int 32))))
8681 (const_int 0)))
8682 (set (match_operand:DI 0 "register_operand" "=d")
8683 (neg:DI (abs:DI (sign_extend:DI (match_dup 1)))))]
8684 "TARGET_ZARCH && s390_match_ccmode (insn, CCAmode)"
8685 "lngfr\t%0,%1"
8686 [(set_attr "op_type" "RRE")
8687 (set_attr "z10prop" "z10_c")])
8688
8689 (define_insn "*negabsdi2_sign"
8690 [(set (match_operand:DI 0 "register_operand" "=d")
8691 (neg:DI (abs:DI (sign_extend:DI
8692 (match_operand:SI 1 "register_operand" "d")))))
8693 (clobber (reg:CC CC_REGNUM))]
8694 "TARGET_ZARCH"
8695 "lngfr\t%0,%1"
8696 [(set_attr "op_type" "RRE")
8697 (set_attr "z10prop" "z10_c")])
8698
8699 ; lnr, lngr
8700 (define_insn "*negabs<mode>2_cc"
8701 [(set (reg CC_REGNUM)
8702 (compare (neg:GPR (abs:GPR (match_operand:GPR 1 "register_operand" "d")))
8703 (const_int 0)))
8704 (set (match_operand:GPR 0 "register_operand" "=d")
8705 (neg:GPR (abs:GPR (match_dup 1))))]
8706 "s390_match_ccmode (insn, CCAmode)"
8707 "ln<g>r\t%0,%1"
8708 [(set_attr "op_type" "RR<E>")
8709 (set_attr "z10prop" "z10_c")])
8710
8711 ; lnr, lngr
8712 (define_insn "*negabs<mode>2_cconly"
8713 [(set (reg CC_REGNUM)
8714 (compare (neg:GPR (abs:GPR (match_operand:GPR 1 "register_operand" "d")))
8715 (const_int 0)))
8716 (clobber (match_scratch:GPR 0 "=d"))]
8717 "s390_match_ccmode (insn, CCAmode)"
8718 "ln<g>r\t%0,%1"
8719 [(set_attr "op_type" "RR<E>")
8720 (set_attr "z10prop" "z10_c")])
8721
8722 ; lnr, lngr
8723 (define_insn "*negabs<mode>2"
8724 [(set (match_operand:GPR 0 "register_operand" "=d")
8725 (neg:GPR (abs:GPR (match_operand:GPR 1 "register_operand" "d"))))
8726 (clobber (reg:CC CC_REGNUM))]
8727 ""
8728 "ln<g>r\t%0,%1"
8729 [(set_attr "op_type" "RR<E>")
8730 (set_attr "z10prop" "z10_c")])
8731
8732 ;
8733 ; Floating point
8734 ;
8735
8736 ; lnxbr, lndbr, lnebr
8737 (define_insn "*negabs<mode>2_cc"
8738 [(set (reg CC_REGNUM)
8739 (compare (neg:BFP (abs:BFP (match_operand:BFP 1 "register_operand" "f")))
8740 (match_operand:BFP 2 "const0_operand" "")))
8741 (set (match_operand:BFP 0 "register_operand" "=f")
8742 (neg:BFP (abs:BFP (match_dup 1))))]
8743 "s390_match_ccmode (insn, CCSmode) && TARGET_HARD_FLOAT"
8744 "ln<xde>br\t%0,%1"
8745 [(set_attr "op_type" "RRE")
8746 (set_attr "type" "fsimp<mode>")])
8747
8748 ; lnxbr, lndbr, lnebr
8749 (define_insn "*negabs<mode>2_cconly"
8750 [(set (reg CC_REGNUM)
8751 (compare (neg:BFP (abs:BFP (match_operand:BFP 1 "register_operand" "f")))
8752 (match_operand:BFP 2 "const0_operand" "")))
8753 (clobber (match_scratch:BFP 0 "=f"))]
8754 "s390_match_ccmode (insn, CCSmode) && TARGET_HARD_FLOAT"
8755 "ln<xde>br\t%0,%1"
8756 [(set_attr "op_type" "RRE")
8757 (set_attr "type" "fsimp<mode>")])
8758
8759 ; lndfr
8760 (define_insn "*negabs<mode>2_nocc"
8761 [(set (match_operand:FP 0 "register_operand" "=f")
8762 (neg:FP (abs:FP (match_operand:BFP 1 "register_operand" "<fT0>"))))]
8763 "TARGET_DFP"
8764 "lndfr\t%0,%1"
8765 [(set_attr "op_type" "RRE")
8766 (set_attr "type" "fsimp<mode>")])
8767
8768 ; lnxbr, lndbr, lnebr
8769 ; FIXME: wflndb does not clobber cc
8770 (define_insn "*negabs<mode>2"
8771 [(set (match_operand:BFP 0 "register_operand" "=f,v")
8772 (neg:BFP (abs:BFP (match_operand:BFP 1 "register_operand" "f,v"))))
8773 (clobber (reg:CC CC_REGNUM))]
8774 "TARGET_HARD_FLOAT"
8775 "@
8776 ln<xde>br\t%0,%1
8777 wflndb\t%0,%1"
8778 [(set_attr "op_type" "RRE,VRR")
8779 (set_attr "cpu_facility" "*,vx")
8780 (set_attr "type" "fsimp<mode>,*")
8781 (set_attr "enabled" "*,<DFDI>")])
8782
8783 ;;
8784 ;;- Square root instructions.
8785 ;;
8786
8787 ;
8788 ; sqrt(df|sf)2 instruction pattern(s).
8789 ;
8790
8791 ; sqxbr, sqdbr, sqebr, sqdb, sqeb
8792 (define_insn "sqrt<mode>2"
8793 [(set (match_operand:BFP 0 "register_operand" "=f,f,v")
8794 (sqrt:BFP (match_operand:BFP 1 "general_operand" "f,R,v")))]
8795 "TARGET_HARD_FLOAT"
8796 "@
8797 sq<xde>br\t%0,%1
8798 sq<xde>b\t%0,%1
8799 wfsqdb\t%v0,%v1"
8800 [(set_attr "op_type" "RRE,RXE,VRR")
8801 (set_attr "type" "fsqrt<mode>")
8802 (set_attr "cpu_facility" "*,*,vx")
8803 (set_attr "enabled" "*,<DSF>,<DFDI>")])
8804
8805
8806 ;;
8807 ;;- One complement instructions.
8808 ;;
8809
8810 ;
8811 ; one_cmpl(di|si|hi|qi)2 instruction pattern(s).
8812 ;
8813
8814 (define_expand "one_cmpl<mode>2"
8815 [(parallel
8816 [(set (match_operand:INT 0 "register_operand" "")
8817 (xor:INT (match_operand:INT 1 "register_operand" "")
8818 (const_int -1)))
8819 (clobber (reg:CC CC_REGNUM))])]
8820 ""
8821 "")
8822
8823
8824 ;;
8825 ;; Find leftmost bit instructions.
8826 ;;
8827
8828 (define_expand "clzdi2"
8829 [(set (match_operand:DI 0 "register_operand" "=d")
8830 (clz:DI (match_operand:DI 1 "register_operand" "d")))]
8831 "TARGET_EXTIMM && TARGET_ZARCH"
8832 {
8833 rtx_insn *insn;
8834 rtx clz_equal;
8835 rtx wide_reg = gen_reg_rtx (TImode);
8836 rtx msb = gen_rtx_CONST_INT (DImode, HOST_WIDE_INT_1U << 63);
8837
8838 clz_equal = gen_rtx_CLZ (DImode, operands[1]);
8839
8840 emit_insn (gen_clztidi2 (wide_reg, operands[1], msb));
8841
8842 insn = emit_move_insn (operands[0], gen_highpart (DImode, wide_reg));
8843 set_unique_reg_note (insn, REG_EQUAL, clz_equal);
8844
8845 DONE;
8846 })
8847
8848 (define_insn "clztidi2"
8849 [(set (match_operand:TI 0 "register_operand" "=d")
8850 (ior:TI
8851 (ashift:TI
8852 (zero_extend:TI
8853 (xor:DI (match_operand:DI 1 "register_operand" "d")
8854 (lshiftrt (match_operand:DI 2 "const_int_operand" "")
8855 (subreg:SI (clz:DI (match_dup 1)) 4))))
8856
8857 (const_int 64))
8858 (zero_extend:TI (clz:DI (match_dup 1)))))
8859 (clobber (reg:CC CC_REGNUM))]
8860 "UINTVAL (operands[2]) == HOST_WIDE_INT_1U << 63
8861 && TARGET_EXTIMM && TARGET_ZARCH"
8862 "flogr\t%0,%1"
8863 [(set_attr "op_type" "RRE")])
8864
8865
8866 ;;
8867 ;;- Rotate instructions.
8868 ;;
8869
8870 ;
8871 ; rotl(di|si)3 instruction pattern(s).
8872 ;
8873
8874 (define_expand "rotl<mode>3"
8875 [(set (match_operand:GPR 0 "register_operand" "")
8876 (rotate:GPR (match_operand:GPR 1 "register_operand" "")
8877 (match_operand:SI 2 "nonmemory_operand" "")))]
8878 "TARGET_CPU_ZARCH"
8879 "")
8880
8881 ; rll, rllg
8882 (define_insn "*rotl<mode>3<addr_style_op><masked_op>"
8883 [(set (match_operand:GPR 0 "register_operand" "=d")
8884 (rotate:GPR (match_operand:GPR 1 "register_operand" "d")
8885 (match_operand:SI 2 "nonmemory_operand" "an")))]
8886 "TARGET_CPU_ZARCH"
8887 "rll<g>\t%0,%1,<addr_style_op_ops>"
8888 [(set_attr "op_type" "RSE")
8889 (set_attr "atype" "reg")
8890 (set_attr "z10prop" "z10_super_E1")])
8891
8892
8893 ;;
8894 ;;- Shift instructions.
8895 ;;
8896
8897 ;
8898 ; (ashl|lshr)(di|si)3 instruction pattern(s).
8899 ; Left shifts and logical right shifts
8900
8901 (define_expand "<shift><mode>3"
8902 [(set (match_operand:DSI 0 "register_operand" "")
8903 (SHIFT:DSI (match_operand:DSI 1 "register_operand" "")
8904 (match_operand:SI 2 "nonmemory_operand" "")))]
8905 ""
8906 "")
8907
8908 ; ESA 64 bit register pair shift with reg or imm shift count
8909 ; sldl, srdl
8910 (define_insn "*<shift>di3_31<addr_style_op><masked_op>"
8911 [(set (match_operand:DI 0 "register_operand" "=d")
8912 (SHIFT:DI (match_operand:DI 1 "register_operand" "0")
8913 (match_operand:SI 2 "nonmemory_operand" "an")))]
8914 "!TARGET_ZARCH"
8915 "s<lr>dl\t%0,<addr_style_op_ops>"
8916 [(set_attr "op_type" "RS")
8917 (set_attr "atype" "reg")
8918 (set_attr "z196prop" "z196_cracked")])
8919
8920
8921 ; 64 bit register shift with reg or imm shift count
8922 ; sll, srl, sllg, srlg, sllk, srlk
8923 (define_insn "*<shift><mode>3<addr_style_op><masked_op>"
8924 [(set (match_operand:GPR 0 "register_operand" "=d, d")
8925 (SHIFT:GPR (match_operand:GPR 1 "register_operand" "<d0>, d")
8926 (match_operand:SI 2 "nonmemory_operand" "an,an")))]
8927 ""
8928 "@
8929 s<lr>l<g>\t%0,<1><addr_style_op_ops>
8930 s<lr>l<gk>\t%0,%1,<addr_style_op_ops>"
8931 [(set_attr "op_type" "RS<E>,RSY")
8932 (set_attr "atype" "reg,reg")
8933 (set_attr "cpu_facility" "*,z196")
8934 (set_attr "z10prop" "z10_super_E1,*")])
8935
8936 ;
8937 ; ashr(di|si)3 instruction pattern(s).
8938 ; Arithmetic right shifts
8939
8940 (define_expand "ashr<mode>3"
8941 [(parallel
8942 [(set (match_operand:DSI 0 "register_operand" "")
8943 (ashiftrt:DSI (match_operand:DSI 1 "register_operand" "")
8944 (match_operand:SI 2 "nonmemory_operand" "")))
8945 (clobber (reg:CC CC_REGNUM))])]
8946 ""
8947 "")
8948
8949 ; FIXME: The number of alternatives is doubled here to match the fix
8950 ; number of 2 in the subst pattern for the (clobber (match_scratch...
8951 ; The right fix should be to support match_scratch in the output
8952 ; pattern of a define_subst.
8953 (define_insn "*ashrdi3_31<addr_style_op_cc><masked_op_cc><setcc><cconly>"
8954 [(set (match_operand:DI 0 "register_operand" "=d, d")
8955 (ashiftrt:DI (match_operand:DI 1 "register_operand" "0, 0")
8956 (match_operand:SI 2 "nonmemory_operand" "an,an")))
8957 (clobber (reg:CC CC_REGNUM))]
8958 "!TARGET_ZARCH"
8959 "@
8960 srda\t%0,<addr_style_op_cc_ops>
8961 srda\t%0,<addr_style_op_cc_ops>"
8962 [(set_attr "op_type" "RS")
8963 (set_attr "atype" "reg")])
8964
8965
8966 ; sra, srag
8967 (define_insn "*ashr<mode>3<addr_style_op_cc><masked_op_cc><setcc><cconly>"
8968 [(set (match_operand:GPR 0 "register_operand" "=d, d")
8969 (ashiftrt:GPR (match_operand:GPR 1 "register_operand" "<d0>, d")
8970 (match_operand:SI 2 "nonmemory_operand" "an,an")))
8971 (clobber (reg:CC CC_REGNUM))]
8972 ""
8973 "@
8974 sra<g>\t%0,<1><addr_style_op_cc_ops>
8975 sra<gk>\t%0,%1,<addr_style_op_cc_ops>"
8976 [(set_attr "op_type" "RS<E>,RSY")
8977 (set_attr "atype" "reg")
8978 (set_attr "cpu_facility" "*,z196")
8979 (set_attr "z10prop" "z10_super_E1,*")])
8980
8981
8982 ;;
8983 ;; Branch instruction patterns.
8984 ;;
8985
8986 (define_expand "cbranch<mode>4"
8987 [(set (pc)
8988 (if_then_else (match_operator 0 "comparison_operator"
8989 [(match_operand:GPR 1 "register_operand" "")
8990 (match_operand:GPR 2 "general_operand" "")])
8991 (label_ref (match_operand 3 "" ""))
8992 (pc)))]
8993 ""
8994 "s390_emit_jump (operands[3],
8995 s390_emit_compare (GET_CODE (operands[0]), operands[1], operands[2]));
8996 DONE;")
8997
8998 (define_expand "cbranch<mode>4"
8999 [(set (pc)
9000 (if_then_else (match_operator 0 "comparison_operator"
9001 [(match_operand:FP 1 "register_operand" "")
9002 (match_operand:FP 2 "general_operand" "")])
9003 (label_ref (match_operand 3 "" ""))
9004 (pc)))]
9005 "TARGET_HARD_FLOAT"
9006 "s390_emit_jump (operands[3],
9007 s390_emit_compare (GET_CODE (operands[0]), operands[1], operands[2]));
9008 DONE;")
9009
9010 (define_expand "cbranchcc4"
9011 [(set (pc)
9012 (if_then_else (match_operator 0 "s390_comparison"
9013 [(match_operand 1 "cc_reg_operand" "")
9014 (match_operand 2 "const_int_operand" "")])
9015 (label_ref (match_operand 3 "" ""))
9016 (pc)))]
9017 ""
9018 "")
9019
9020
9021 ;;
9022 ;;- Conditional jump instructions.
9023 ;;
9024
9025 (define_insn "*cjump_64"
9026 [(set (pc)
9027 (if_then_else
9028 (match_operator 1 "s390_comparison" [(reg CC_REGNUM)
9029 (match_operand 2 "const_int_operand" "")])
9030 (label_ref (match_operand 0 "" ""))
9031 (pc)))]
9032 "TARGET_CPU_ZARCH"
9033 {
9034 if (get_attr_length (insn) == 4)
9035 return "j%C1\t%l0";
9036 else
9037 return "jg%C1\t%l0";
9038 }
9039 [(set_attr "op_type" "RI")
9040 (set_attr "type" "branch")
9041 (set (attr "length")
9042 (if_then_else (lt (abs (minus (pc) (match_dup 0))) (const_int 60000))
9043 (const_int 4) (const_int 6)))])
9044
9045 (define_insn "*cjump_31"
9046 [(set (pc)
9047 (if_then_else
9048 (match_operator 1 "s390_comparison" [(reg CC_REGNUM)
9049 (match_operand 2 "const_int_operand" "")])
9050 (label_ref (match_operand 0 "" ""))
9051 (pc)))]
9052 "!TARGET_CPU_ZARCH"
9053 {
9054 gcc_assert (get_attr_length (insn) == 4);
9055 return "j%C1\t%l0";
9056 }
9057 [(set_attr "op_type" "RI")
9058 (set_attr "type" "branch")
9059 (set (attr "length")
9060 (if_then_else (not (match_test "flag_pic"))
9061 (if_then_else (lt (abs (minus (pc) (match_dup 0))) (const_int 60000))
9062 (const_int 4) (const_int 6))
9063 (if_then_else (lt (abs (minus (pc) (match_dup 0))) (const_int 60000))
9064 (const_int 4) (const_int 8))))])
9065
9066 (define_insn "*cjump_long"
9067 [(set (pc)
9068 (if_then_else
9069 (match_operator 1 "s390_comparison" [(reg CC_REGNUM) (const_int 0)])
9070 (match_operand 0 "address_operand" "ZQZR")
9071 (pc)))]
9072 ""
9073 {
9074 if (get_attr_op_type (insn) == OP_TYPE_RR)
9075 return "b%C1r\t%0";
9076 else
9077 return "b%C1\t%a0";
9078 }
9079 [(set (attr "op_type")
9080 (if_then_else (match_operand 0 "register_operand" "")
9081 (const_string "RR") (const_string "RX")))
9082 (set_attr "type" "branch")
9083 (set_attr "atype" "agen")])
9084
9085 ;; A conditional return instruction.
9086 (define_insn "*c<code>"
9087 [(set (pc)
9088 (if_then_else
9089 (match_operator 0 "s390_comparison" [(reg CC_REGNUM) (const_int 0)])
9090 (ANY_RETURN)
9091 (pc)))]
9092 "s390_can_use_<code>_insn ()"
9093 "b%C0r\t%%r14"
9094 [(set_attr "op_type" "RR")
9095 (set_attr "type" "jsr")
9096 (set_attr "atype" "agen")])
9097
9098 ;;
9099 ;;- Negated conditional jump instructions.
9100 ;;
9101
9102 (define_insn "*icjump_64"
9103 [(set (pc)
9104 (if_then_else
9105 (match_operator 1 "s390_comparison" [(reg CC_REGNUM) (const_int 0)])
9106 (pc)
9107 (label_ref (match_operand 0 "" ""))))]
9108 "TARGET_CPU_ZARCH"
9109 {
9110 if (get_attr_length (insn) == 4)
9111 return "j%D1\t%l0";
9112 else
9113 return "jg%D1\t%l0";
9114 }
9115 [(set_attr "op_type" "RI")
9116 (set_attr "type" "branch")
9117 (set (attr "length")
9118 (if_then_else (lt (abs (minus (pc) (match_dup 0))) (const_int 60000))
9119 (const_int 4) (const_int 6)))])
9120
9121 (define_insn "*icjump_31"
9122 [(set (pc)
9123 (if_then_else
9124 (match_operator 1 "s390_comparison" [(reg CC_REGNUM) (const_int 0)])
9125 (pc)
9126 (label_ref (match_operand 0 "" ""))))]
9127 "!TARGET_CPU_ZARCH"
9128 {
9129 gcc_assert (get_attr_length (insn) == 4);
9130 return "j%D1\t%l0";
9131 }
9132 [(set_attr "op_type" "RI")
9133 (set_attr "type" "branch")
9134 (set (attr "length")
9135 (if_then_else (not (match_test "flag_pic"))
9136 (if_then_else (lt (abs (minus (pc) (match_dup 0))) (const_int 60000))
9137 (const_int 4) (const_int 6))
9138 (if_then_else (lt (abs (minus (pc) (match_dup 0))) (const_int 60000))
9139 (const_int 4) (const_int 8))))])
9140
9141 (define_insn "*icjump_long"
9142 [(set (pc)
9143 (if_then_else
9144 (match_operator 1 "s390_comparison" [(reg CC_REGNUM) (const_int 0)])
9145 (pc)
9146 (match_operand 0 "address_operand" "ZQZR")))]
9147 ""
9148 {
9149 if (get_attr_op_type (insn) == OP_TYPE_RR)
9150 return "b%D1r\t%0";
9151 else
9152 return "b%D1\t%a0";
9153 }
9154 [(set (attr "op_type")
9155 (if_then_else (match_operand 0 "register_operand" "")
9156 (const_string "RR") (const_string "RX")))
9157 (set_attr "type" "branch")
9158 (set_attr "atype" "agen")])
9159
9160 ;;
9161 ;;- Trap instructions.
9162 ;;
9163
9164 (define_insn "trap"
9165 [(trap_if (const_int 1) (const_int 0))]
9166 ""
9167 "j\t.+2"
9168 [(set_attr "op_type" "RI")
9169 (set_attr "type" "branch")])
9170
9171 (define_expand "ctrap<mode>4"
9172 [(trap_if (match_operator 0 "comparison_operator"
9173 [(match_operand:GPR 1 "register_operand" "")
9174 (match_operand:GPR 2 "general_operand" "")])
9175 (match_operand 3 "const0_operand" ""))]
9176 ""
9177 {
9178 rtx cond = s390_emit_compare (GET_CODE (operands[0]),
9179 operands[1], operands[2]);
9180 emit_insn (gen_condtrap (cond, XEXP (cond, 0)));
9181 DONE;
9182 })
9183
9184 (define_expand "ctrap<mode>4"
9185 [(trap_if (match_operator 0 "comparison_operator"
9186 [(match_operand:FP 1 "register_operand" "")
9187 (match_operand:FP 2 "general_operand" "")])
9188 (match_operand 3 "const0_operand" ""))]
9189 ""
9190 {
9191 rtx cond = s390_emit_compare (GET_CODE (operands[0]),
9192 operands[1], operands[2]);
9193 emit_insn (gen_condtrap (cond, XEXP (cond, 0)));
9194 DONE;
9195 })
9196
9197 (define_insn "condtrap"
9198 [(trap_if (match_operator 0 "s390_comparison"
9199 [(match_operand 1 "cc_reg_operand" "c")
9200 (const_int 0)])
9201 (const_int 0))]
9202 ""
9203 "j%C0\t.+2";
9204 [(set_attr "op_type" "RI")
9205 (set_attr "type" "branch")])
9206
9207 ; crt, cgrt, cit, cgit
9208 (define_insn "*cmp_and_trap_signed_int<mode>"
9209 [(trap_if (match_operator 0 "s390_signed_integer_comparison"
9210 [(match_operand:GPR 1 "register_operand" "d,d")
9211 (match_operand:GPR 2 "nonmemory_operand" "d,K")])
9212 (const_int 0))]
9213 "TARGET_Z10"
9214 "@
9215 c<g>rt%C0\t%1,%2
9216 c<g>it%C0\t%1,%h2"
9217 [(set_attr "op_type" "RRF,RIE")
9218 (set_attr "type" "branch")
9219 (set_attr "z10prop" "z10_super_c,z10_super")])
9220
9221 ; clrt, clgrt, clfit, clgit, clt, clgt
9222 (define_insn "*cmp_and_trap_unsigned_int<mode>"
9223 [(trap_if (match_operator 0 "s390_unsigned_integer_comparison"
9224 [(match_operand:GPR 1 "register_operand" "d,d,d")
9225 (match_operand:GPR 2 "general_operand" "d,D,T")])
9226 (const_int 0))]
9227 "TARGET_Z10"
9228 "@
9229 cl<g>rt%C0\t%1,%2
9230 cl<gf>it%C0\t%1,%x2
9231 cl<g>t%C0\t%1,%2"
9232 [(set_attr "op_type" "RRF,RIE,RSY")
9233 (set_attr "type" "branch")
9234 (set_attr "z10prop" "z10_super_c,z10_super,*")
9235 (set_attr "cpu_facility" "z10,z10,zEC12")])
9236
9237 ; lat, lgat
9238 (define_insn "*load_and_trap<mode>"
9239 [(trap_if (eq (match_operand:GPR 0 "memory_operand" "T")
9240 (const_int 0))
9241 (const_int 0))
9242 (set (match_operand:GPR 1 "register_operand" "=d")
9243 (match_dup 0))]
9244 "TARGET_ZEC12"
9245 "l<g>at\t%1,%0"
9246 [(set_attr "op_type" "RXY")])
9247
9248
9249 ;;
9250 ;;- Loop instructions.
9251 ;;
9252 ;; This is all complicated by the fact that since this is a jump insn
9253 ;; we must handle our own output reloads.
9254
9255 ;; branch on index
9256
9257 ; This splitter will be matched by combine and has to add the 2 moves
9258 ; necessary to load the compare and the increment values into a
9259 ; register pair as needed by brxle.
9260
9261 (define_insn_and_split "*brx_stage1_<GPR:mode>"
9262 [(set (pc)
9263 (if_then_else
9264 (match_operator 6 "s390_brx_operator"
9265 [(plus:GPR (match_operand:GPR 1 "register_operand" "")
9266 (match_operand:GPR 2 "general_operand" ""))
9267 (match_operand:GPR 3 "register_operand" "")])
9268 (label_ref (match_operand 0 "" ""))
9269 (pc)))
9270 (set (match_operand:GPR 4 "nonimmediate_operand" "")
9271 (plus:GPR (match_dup 1) (match_dup 2)))
9272 (clobber (match_scratch:GPR 5 ""))]
9273 "TARGET_CPU_ZARCH"
9274 "#"
9275 "!reload_completed && !reload_in_progress"
9276 [(set (match_dup 7) (match_dup 2)) ; the increment
9277 (set (match_dup 8) (match_dup 3)) ; the comparison value
9278 (parallel [(set (pc)
9279 (if_then_else
9280 (match_op_dup 6
9281 [(plus:GPR (match_dup 1) (match_dup 7))
9282 (match_dup 8)])
9283 (label_ref (match_dup 0))
9284 (pc)))
9285 (set (match_dup 4)
9286 (plus:GPR (match_dup 1) (match_dup 7)))
9287 (clobber (match_dup 5))
9288 (clobber (reg:CC CC_REGNUM))])]
9289 {
9290 rtx dreg = gen_reg_rtx (word_mode == DImode ? TImode : DImode);
9291 operands[7] = gen_lowpart (<GPR:MODE>mode,
9292 gen_highpart (word_mode, dreg));
9293 operands[8] = gen_lowpart (<GPR:MODE>mode,
9294 gen_lowpart (word_mode, dreg));
9295 })
9296
9297 ; brxlg, brxhg
9298
9299 (define_insn_and_split "*brxg_64bit"
9300 [(set (pc)
9301 (if_then_else
9302 (match_operator 5 "s390_brx_operator"
9303 [(plus:DI (match_operand:DI 1 "register_operand" "d,d,d")
9304 (subreg:DI (match_operand:TI 2 "register_operand" "d,d,d") 0))
9305 (subreg:DI (match_dup 2) 8)])
9306 (label_ref (match_operand 0 "" ""))
9307 (pc)))
9308 (set (match_operand:DI 3 "nonimmediate_operand" "=1,?X,?X")
9309 (plus:DI (match_dup 1)
9310 (subreg:DI (match_dup 2) 0)))
9311 (clobber (match_scratch:DI 4 "=X,&1,&?d"))
9312 (clobber (reg:CC CC_REGNUM))]
9313 "TARGET_ZARCH"
9314 {
9315 if (which_alternative != 0)
9316 return "#";
9317 else if (get_attr_length (insn) == 6)
9318 return "brx%E5g\t%1,%2,%l0";
9319 else
9320 return "agr\t%1,%2\;cgr\t%1,%M2\;jg%C5\t%l0";
9321 }
9322 "&& reload_completed
9323 && (!REG_P (operands[3])
9324 || !rtx_equal_p (operands[1], operands[3]))"
9325 [(set (match_dup 4) (match_dup 1))
9326 (parallel [(set (match_dup 4) (plus:DI (match_dup 4) (subreg:DI (match_dup 2) 0)))
9327 (clobber (reg:CC CC_REGNUM))])
9328 (set (reg:CCS CC_REGNUM) (compare:CCS (match_dup 4) (subreg:DI (match_dup 2) 8)))
9329 (set (match_dup 3) (match_dup 4))
9330 (set (pc) (if_then_else (match_op_dup 5 [(reg:CCS CC_REGNUM) (const_int 0)])
9331 (label_ref (match_dup 0))
9332 (pc)))]
9333 ""
9334 [(set_attr "op_type" "RIE")
9335 (set_attr "type" "branch")
9336 (set (attr "length")
9337 (if_then_else (lt (abs (minus (pc) (match_dup 0))) (const_int 60000))
9338 (const_int 6) (const_int 16)))])
9339
9340 ; brxle, brxh
9341
9342 (define_insn_and_split "*brx_64bit"
9343 [(set (pc)
9344 (if_then_else
9345 (match_operator 5 "s390_brx_operator"
9346 [(plus:SI (match_operand:SI 1 "register_operand" "d,d,d")
9347 (subreg:SI (match_operand:TI 2 "register_operand" "d,d,d") 4))
9348 (subreg:SI (match_dup 2) 12)])
9349 (label_ref (match_operand 0 "" ""))
9350 (pc)))
9351 (set (match_operand:SI 3 "nonimmediate_operand" "=1,?X,?X")
9352 (plus:SI (match_dup 1)
9353 (subreg:SI (match_dup 2) 4)))
9354 (clobber (match_scratch:SI 4 "=X,&1,&?d"))
9355 (clobber (reg:CC CC_REGNUM))]
9356 "TARGET_ZARCH"
9357 {
9358 if (which_alternative != 0)
9359 return "#";
9360 else if (get_attr_length (insn) == 6)
9361 return "brx%C5\t%1,%2,%l0";
9362 else
9363 return "ar\t%1,%2\;cr\t%1,%M2\;jg%C5\t%l0";
9364 }
9365 "&& reload_completed
9366 && (!REG_P (operands[3])
9367 || !rtx_equal_p (operands[1], operands[3]))"
9368 [(set (match_dup 4) (match_dup 1))
9369 (parallel [(set (match_dup 4) (plus:SI (match_dup 4) (subreg:SI (match_dup 2) 4)))
9370 (clobber (reg:CC CC_REGNUM))])
9371 (set (reg:CCS CC_REGNUM) (compare:CCS (match_dup 4) (subreg:SI (match_dup 2) 12)))
9372 (set (match_dup 3) (match_dup 4))
9373 (set (pc) (if_then_else (match_op_dup 5 [(reg:CCS CC_REGNUM) (const_int 0)])
9374 (label_ref (match_dup 0))
9375 (pc)))]
9376 ""
9377 [(set_attr "op_type" "RSI")
9378 (set_attr "type" "branch")
9379 (set (attr "length")
9380 (if_then_else (lt (abs (minus (pc) (match_dup 0))) (const_int 60000))
9381 (const_int 6) (const_int 14)))])
9382
9383 ; brxle, brxh
9384
9385 (define_insn_and_split "*brx_31bit"
9386 [(set (pc)
9387 (if_then_else
9388 (match_operator 5 "s390_brx_operator"
9389 [(plus:SI (match_operand:SI 1 "register_operand" "d,d,d")
9390 (subreg:SI (match_operand:DI 2 "register_operand" "d,d,d") 0))
9391 (subreg:SI (match_dup 2) 4)])
9392 (label_ref (match_operand 0 "" ""))
9393 (pc)))
9394 (set (match_operand:SI 3 "nonimmediate_operand" "=1,?X,?X")
9395 (plus:SI (match_dup 1)
9396 (subreg:SI (match_dup 2) 0)))
9397 (clobber (match_scratch:SI 4 "=X,&1,&?d"))
9398 (clobber (reg:CC CC_REGNUM))]
9399 "!TARGET_ZARCH && TARGET_CPU_ZARCH"
9400 {
9401 if (which_alternative != 0)
9402 return "#";
9403 else if (get_attr_length (insn) == 6)
9404 return "brx%C5\t%1,%2,%l0";
9405 else
9406 return "ar\t%1,%2\;cr\t%1,%M2\;jg%C5\t%l0";
9407 }
9408 "&& reload_completed
9409 && (!REG_P (operands[3])
9410 || !rtx_equal_p (operands[1], operands[3]))"
9411 [(set (match_dup 4) (match_dup 1))
9412 (parallel [(set (match_dup 4) (plus:SI (match_dup 4) (subreg:SI (match_dup 2) 0)))
9413 (clobber (reg:CC CC_REGNUM))])
9414 (set (reg:CCS CC_REGNUM) (compare:CCS (match_dup 4) (subreg:SI (match_dup 2) 4)))
9415 (set (match_dup 3) (match_dup 4))
9416 (set (pc) (if_then_else (match_op_dup 5 [(reg:CCS CC_REGNUM) (const_int 0)])
9417 (label_ref (match_dup 0))
9418 (pc)))]
9419 ""
9420 [(set_attr "op_type" "RSI")
9421 (set_attr "type" "branch")
9422 (set (attr "length")
9423 (if_then_else (lt (abs (minus (pc) (match_dup 0))) (const_int 60000))
9424 (const_int 6) (const_int 14)))])
9425
9426
9427 ;; branch on count
9428
9429 (define_expand "doloop_end"
9430 [(use (match_operand 0 "" "")) ; loop pseudo
9431 (use (match_operand 1 "" ""))] ; label
9432 ""
9433 {
9434 if (GET_MODE (operands[0]) == SImode && !TARGET_CPU_ZARCH)
9435 emit_jump_insn (gen_doloop_si31 (operands[1], operands[0], operands[0]));
9436 else if (GET_MODE (operands[0]) == SImode && TARGET_CPU_ZARCH)
9437 emit_jump_insn (gen_doloop_si64 (operands[1], operands[0], operands[0]));
9438 else if (GET_MODE (operands[0]) == DImode && TARGET_ZARCH)
9439 emit_jump_insn (gen_doloop_di (operands[1], operands[0], operands[0]));
9440 else
9441 FAIL;
9442
9443 DONE;
9444 })
9445
9446 (define_insn_and_split "doloop_si64"
9447 [(set (pc)
9448 (if_then_else
9449 (ne (match_operand:SI 1 "register_operand" "d,d,d")
9450 (const_int 1))
9451 (label_ref (match_operand 0 "" ""))
9452 (pc)))
9453 (set (match_operand:SI 2 "nonimmediate_operand" "=1,?X,?X")
9454 (plus:SI (match_dup 1) (const_int -1)))
9455 (clobber (match_scratch:SI 3 "=X,&1,&?d"))
9456 (clobber (reg:CC CC_REGNUM))]
9457 "TARGET_CPU_ZARCH"
9458 {
9459 if (which_alternative != 0)
9460 return "#";
9461 else if (get_attr_length (insn) == 4)
9462 return "brct\t%1,%l0";
9463 else
9464 return "ahi\t%1,-1\;jgne\t%l0";
9465 }
9466 "&& reload_completed
9467 && (! REG_P (operands[2])
9468 || ! rtx_equal_p (operands[1], operands[2]))"
9469 [(set (match_dup 3) (match_dup 1))
9470 (parallel [(set (reg:CCAN CC_REGNUM)
9471 (compare:CCAN (plus:SI (match_dup 3) (const_int -1))
9472 (const_int 0)))
9473 (set (match_dup 3) (plus:SI (match_dup 3) (const_int -1)))])
9474 (set (match_dup 2) (match_dup 3))
9475 (set (pc) (if_then_else (ne (reg:CCAN CC_REGNUM) (const_int 0))
9476 (label_ref (match_dup 0))
9477 (pc)))]
9478 ""
9479 [(set_attr "op_type" "RI")
9480 ; Strictly speaking, the z10 properties are valid for brct only, however, it does not
9481 ; hurt us in the (rare) case of ahi.
9482 (set_attr "z10prop" "z10_super_E1")
9483 (set_attr "type" "branch")
9484 (set (attr "length")
9485 (if_then_else (lt (abs (minus (pc) (match_dup 0))) (const_int 60000))
9486 (const_int 4) (const_int 10)))])
9487
9488 (define_insn_and_split "doloop_si31"
9489 [(set (pc)
9490 (if_then_else
9491 (ne (match_operand:SI 1 "register_operand" "d,d,d")
9492 (const_int 1))
9493 (label_ref (match_operand 0 "" ""))
9494 (pc)))
9495 (set (match_operand:SI 2 "nonimmediate_operand" "=1,?X,?X")
9496 (plus:SI (match_dup 1) (const_int -1)))
9497 (clobber (match_scratch:SI 3 "=X,&1,&?d"))
9498 (clobber (reg:CC CC_REGNUM))]
9499 "!TARGET_CPU_ZARCH"
9500 {
9501 if (which_alternative != 0)
9502 return "#";
9503 else if (get_attr_length (insn) == 4)
9504 return "brct\t%1,%l0";
9505 else
9506 gcc_unreachable ();
9507 }
9508 "&& reload_completed
9509 && (! REG_P (operands[2])
9510 || ! rtx_equal_p (operands[1], operands[2]))"
9511 [(set (match_dup 3) (match_dup 1))
9512 (parallel [(set (reg:CCAN CC_REGNUM)
9513 (compare:CCAN (plus:SI (match_dup 3) (const_int -1))
9514 (const_int 0)))
9515 (set (match_dup 3) (plus:SI (match_dup 3) (const_int -1)))])
9516 (set (match_dup 2) (match_dup 3))
9517 (set (pc) (if_then_else (ne (reg:CCAN CC_REGNUM) (const_int 0))
9518 (label_ref (match_dup 0))
9519 (pc)))]
9520 ""
9521 [(set_attr "op_type" "RI")
9522 ; Strictly speaking, the z10 properties are valid for brct only, however, it does not
9523 ; hurt us in the (rare) case of ahi.
9524 (set_attr "z10prop" "z10_super_E1")
9525 (set_attr "type" "branch")
9526 (set (attr "length")
9527 (if_then_else (not (match_test "flag_pic"))
9528 (if_then_else (lt (abs (minus (pc) (match_dup 0))) (const_int 60000))
9529 (const_int 4) (const_int 6))
9530 (if_then_else (lt (abs (minus (pc) (match_dup 0))) (const_int 60000))
9531 (const_int 4) (const_int 8))))])
9532
9533 (define_insn "*doloop_si_long"
9534 [(set (pc)
9535 (if_then_else
9536 (ne (match_operand:SI 1 "register_operand" "d")
9537 (const_int 1))
9538 (match_operand 0 "address_operand" "ZR")
9539 (pc)))
9540 (set (match_operand:SI 2 "register_operand" "=1")
9541 (plus:SI (match_dup 1) (const_int -1)))
9542 (clobber (match_scratch:SI 3 "=X"))
9543 (clobber (reg:CC CC_REGNUM))]
9544 "!TARGET_CPU_ZARCH"
9545 {
9546 if (get_attr_op_type (insn) == OP_TYPE_RR)
9547 return "bctr\t%1,%0";
9548 else
9549 return "bct\t%1,%a0";
9550 }
9551 [(set (attr "op_type")
9552 (if_then_else (match_operand 0 "register_operand" "")
9553 (const_string "RR") (const_string "RX")))
9554 (set_attr "type" "branch")
9555 (set_attr "atype" "agen")
9556 (set_attr "z10prop" "z10_c")
9557 (set_attr "z196prop" "z196_cracked")])
9558
9559 (define_insn_and_split "doloop_di"
9560 [(set (pc)
9561 (if_then_else
9562 (ne (match_operand:DI 1 "register_operand" "d,d,d")
9563 (const_int 1))
9564 (label_ref (match_operand 0 "" ""))
9565 (pc)))
9566 (set (match_operand:DI 2 "nonimmediate_operand" "=1,?X,?X")
9567 (plus:DI (match_dup 1) (const_int -1)))
9568 (clobber (match_scratch:DI 3 "=X,&1,&?d"))
9569 (clobber (reg:CC CC_REGNUM))]
9570 "TARGET_ZARCH"
9571 {
9572 if (which_alternative != 0)
9573 return "#";
9574 else if (get_attr_length (insn) == 4)
9575 return "brctg\t%1,%l0";
9576 else
9577 return "aghi\t%1,-1\;jgne\t%l0";
9578 }
9579 "&& reload_completed
9580 && (! REG_P (operands[2])
9581 || ! rtx_equal_p (operands[1], operands[2]))"
9582 [(set (match_dup 3) (match_dup 1))
9583 (parallel [(set (reg:CCAN CC_REGNUM)
9584 (compare:CCAN (plus:DI (match_dup 3) (const_int -1))
9585 (const_int 0)))
9586 (set (match_dup 3) (plus:DI (match_dup 3) (const_int -1)))])
9587 (set (match_dup 2) (match_dup 3))
9588 (set (pc) (if_then_else (ne (reg:CCAN CC_REGNUM) (const_int 0))
9589 (label_ref (match_dup 0))
9590 (pc)))]
9591 ""
9592 [(set_attr "op_type" "RI")
9593 ; Strictly speaking, the z10 properties are valid for brct only, however, it does not
9594 ; hurt us in the (rare) case of ahi.
9595 (set_attr "z10prop" "z10_super_E1")
9596 (set_attr "type" "branch")
9597 (set (attr "length")
9598 (if_then_else (lt (abs (minus (pc) (match_dup 0))) (const_int 60000))
9599 (const_int 4) (const_int 10)))])
9600
9601 ;;
9602 ;;- Unconditional jump instructions.
9603 ;;
9604
9605 ;
9606 ; jump instruction pattern(s).
9607 ;
9608
9609 (define_expand "jump"
9610 [(match_operand 0 "" "")]
9611 ""
9612 "s390_emit_jump (operands[0], NULL_RTX); DONE;")
9613
9614 (define_insn "*jump64"
9615 [(set (pc) (label_ref (match_operand 0 "" "")))]
9616 "TARGET_CPU_ZARCH"
9617 {
9618 if (get_attr_length (insn) == 4)
9619 return "j\t%l0";
9620 else
9621 return "jg\t%l0";
9622 }
9623 [(set_attr "op_type" "RI")
9624 (set_attr "type" "branch")
9625 (set (attr "length")
9626 (if_then_else (lt (abs (minus (pc) (match_dup 0))) (const_int 60000))
9627 (const_int 4) (const_int 6)))])
9628
9629 (define_insn "*jump31"
9630 [(set (pc) (label_ref (match_operand 0 "" "")))]
9631 "!TARGET_CPU_ZARCH"
9632 {
9633 gcc_assert (get_attr_length (insn) == 4);
9634 return "j\t%l0";
9635 }
9636 [(set_attr "op_type" "RI")
9637 (set_attr "type" "branch")
9638 (set (attr "length")
9639 (if_then_else (not (match_test "flag_pic"))
9640 (if_then_else (lt (abs (minus (pc) (match_dup 0))) (const_int 60000))
9641 (const_int 4) (const_int 6))
9642 (if_then_else (lt (abs (minus (pc) (match_dup 0))) (const_int 60000))
9643 (const_int 4) (const_int 8))))])
9644
9645 ;
9646 ; indirect-jump instruction pattern(s).
9647 ;
9648
9649 (define_expand "indirect_jump"
9650 [(set (pc) (match_operand 0 "nonimmediate_operand" ""))]
9651 ""
9652 {
9653 if (address_operand (operands[0], GET_MODE (operands[0])))
9654 ;
9655 else if (TARGET_ARCH12
9656 && GET_MODE (operands[0]) == Pmode
9657 && memory_operand (operands[0], Pmode))
9658 ;
9659 else
9660 operands[0] = force_reg (Pmode, operands[0]);
9661 })
9662
9663 ; The first constraint must be an "extra address constraint" in order
9664 ; to trigger address reloading in LRA/reload
9665 (define_insn "*indirect_jump"
9666 [(set (pc)
9667 (match_operand 0 "address_operand" "ZR,a"))]
9668 ""
9669 "@
9670 b\t%a0
9671 br\t%0"
9672 [(set_attr "op_type" "RX,RR")
9673 (set_attr "type" "branch")
9674 (set_attr "atype" "agen")
9675 (set_attr "cpu_facility" "*")])
9676
9677 ; FIXME: LRA does not appear to be able to deal with MEMs being
9678 ; checked against address constraints like ZR above. So make this a
9679 ; separate pattern for now.
9680 (define_insn "*indirect2_jump"
9681 [(set (pc)
9682 (match_operand 0 "nonimmediate_operand" "a,T"))]
9683 ""
9684 "@
9685 br\t%0
9686 bi\t%0"
9687 [(set_attr "op_type" "RR,RXY")
9688 (set_attr "type" "branch")
9689 (set_attr "atype" "agen")
9690 (set_attr "cpu_facility" "*,arch12")])
9691
9692 ;
9693 ; casesi instruction pattern(s).
9694 ;
9695
9696 (define_insn "casesi_jump"
9697 [(set (pc) (match_operand 0 "address_operand" "ZR"))
9698 (use (label_ref (match_operand 1 "" "")))]
9699 ""
9700 {
9701 if (get_attr_op_type (insn) == OP_TYPE_RR)
9702 return "br\t%0";
9703 else
9704 return "b\t%a0";
9705 }
9706 [(set (attr "op_type")
9707 (if_then_else (match_operand 0 "register_operand" "")
9708 (const_string "RR") (const_string "RX")))
9709 (set_attr "type" "branch")
9710 (set_attr "atype" "agen")])
9711
9712 (define_expand "casesi"
9713 [(match_operand:SI 0 "general_operand" "")
9714 (match_operand:SI 1 "general_operand" "")
9715 (match_operand:SI 2 "general_operand" "")
9716 (label_ref (match_operand 3 "" ""))
9717 (label_ref (match_operand 4 "" ""))]
9718 ""
9719 {
9720 rtx index = gen_reg_rtx (SImode);
9721 rtx base = gen_reg_rtx (Pmode);
9722 rtx target = gen_reg_rtx (Pmode);
9723
9724 emit_move_insn (index, operands[0]);
9725 emit_insn (gen_subsi3 (index, index, operands[1]));
9726 emit_cmp_and_jump_insns (index, operands[2], GTU, NULL_RTX, SImode, 1,
9727 operands[4]);
9728
9729 if (Pmode != SImode)
9730 index = convert_to_mode (Pmode, index, 1);
9731 if (GET_CODE (index) != REG)
9732 index = copy_to_mode_reg (Pmode, index);
9733
9734 if (TARGET_64BIT)
9735 emit_insn (gen_ashldi3 (index, index, GEN_INT (3)));
9736 else
9737 emit_insn (gen_ashlsi3 (index, index, const2_rtx));
9738
9739 emit_move_insn (base, gen_rtx_LABEL_REF (Pmode, operands[3]));
9740
9741 index = gen_const_mem (Pmode, gen_rtx_PLUS (Pmode, base, index));
9742 emit_move_insn (target, index);
9743
9744 if (flag_pic)
9745 target = gen_rtx_PLUS (Pmode, base, target);
9746 emit_jump_insn (gen_casesi_jump (target, operands[3]));
9747
9748 DONE;
9749 })
9750
9751
9752 ;;
9753 ;;- Jump to subroutine.
9754 ;;
9755 ;;
9756
9757 ;
9758 ; untyped call instruction pattern(s).
9759 ;
9760
9761 ;; Call subroutine returning any type.
9762 (define_expand "untyped_call"
9763 [(parallel [(call (match_operand 0 "" "")
9764 (const_int 0))
9765 (match_operand 1 "" "")
9766 (match_operand 2 "" "")])]
9767 ""
9768 {
9769 int i;
9770
9771 emit_call_insn (gen_call (operands[0], const0_rtx, const0_rtx));
9772
9773 for (i = 0; i < XVECLEN (operands[2], 0); i++)
9774 {
9775 rtx set = XVECEXP (operands[2], 0, i);
9776 emit_move_insn (SET_DEST (set), SET_SRC (set));
9777 }
9778
9779 /* The optimizer does not know that the call sets the function value
9780 registers we stored in the result block. We avoid problems by
9781 claiming that all hard registers are used and clobbered at this
9782 point. */
9783 emit_insn (gen_blockage ());
9784
9785 DONE;
9786 })
9787
9788 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
9789 ;; all of memory. This blocks insns from being moved across this point.
9790
9791 (define_insn "blockage"
9792 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
9793 ""
9794 ""
9795 [(set_attr "type" "none")
9796 (set_attr "length" "0")])
9797
9798 ;
9799 ; sibcall patterns
9800 ;
9801
9802 (define_expand "sibcall"
9803 [(call (match_operand 0 "" "")
9804 (match_operand 1 "" ""))]
9805 ""
9806 {
9807 s390_emit_call (XEXP (operands[0], 0), NULL_RTX, NULL_RTX, NULL_RTX);
9808 DONE;
9809 })
9810
9811 (define_insn "*sibcall_br"
9812 [(call (mem:QI (reg SIBCALL_REGNUM))
9813 (match_operand 0 "const_int_operand" "n"))]
9814 "SIBLING_CALL_P (insn)
9815 && GET_MODE (XEXP (XEXP (PATTERN (insn), 0), 0)) == Pmode"
9816 "br\t%%r1"
9817 [(set_attr "op_type" "RR")
9818 (set_attr "type" "branch")
9819 (set_attr "atype" "agen")])
9820
9821 (define_insn "*sibcall_brc"
9822 [(call (mem:QI (match_operand 0 "bras_sym_operand" "X"))
9823 (match_operand 1 "const_int_operand" "n"))]
9824 "SIBLING_CALL_P (insn) && TARGET_SMALL_EXEC"
9825 "j\t%0"
9826 [(set_attr "op_type" "RI")
9827 (set_attr "type" "branch")])
9828
9829 (define_insn "*sibcall_brcl"
9830 [(call (mem:QI (match_operand 0 "bras_sym_operand" "X"))
9831 (match_operand 1 "const_int_operand" "n"))]
9832 "SIBLING_CALL_P (insn) && TARGET_CPU_ZARCH"
9833 "jg\t%0"
9834 [(set_attr "op_type" "RIL")
9835 (set_attr "type" "branch")])
9836
9837 ;
9838 ; sibcall_value patterns
9839 ;
9840
9841 (define_expand "sibcall_value"
9842 [(set (match_operand 0 "" "")
9843 (call (match_operand 1 "" "")
9844 (match_operand 2 "" "")))]
9845 ""
9846 {
9847 s390_emit_call (XEXP (operands[1], 0), NULL_RTX, operands[0], NULL_RTX);
9848 DONE;
9849 })
9850
9851 (define_insn "*sibcall_value_br"
9852 [(set (match_operand 0 "" "")
9853 (call (mem:QI (reg SIBCALL_REGNUM))
9854 (match_operand 1 "const_int_operand" "n")))]
9855 "SIBLING_CALL_P (insn)
9856 && GET_MODE (XEXP (XEXP (XEXP (PATTERN (insn), 1), 0), 0)) == Pmode"
9857 "br\t%%r1"
9858 [(set_attr "op_type" "RR")
9859 (set_attr "type" "branch")
9860 (set_attr "atype" "agen")])
9861
9862 (define_insn "*sibcall_value_brc"
9863 [(set (match_operand 0 "" "")
9864 (call (mem:QI (match_operand 1 "bras_sym_operand" "X"))
9865 (match_operand 2 "const_int_operand" "n")))]
9866 "SIBLING_CALL_P (insn) && TARGET_SMALL_EXEC"
9867 "j\t%1"
9868 [(set_attr "op_type" "RI")
9869 (set_attr "type" "branch")])
9870
9871 (define_insn "*sibcall_value_brcl"
9872 [(set (match_operand 0 "" "")
9873 (call (mem:QI (match_operand 1 "bras_sym_operand" "X"))
9874 (match_operand 2 "const_int_operand" "n")))]
9875 "SIBLING_CALL_P (insn) && TARGET_CPU_ZARCH"
9876 "jg\t%1"
9877 [(set_attr "op_type" "RIL")
9878 (set_attr "type" "branch")])
9879
9880
9881 ;
9882 ; call instruction pattern(s).
9883 ;
9884
9885 (define_expand "call"
9886 [(call (match_operand 0 "" "")
9887 (match_operand 1 "" ""))
9888 (use (match_operand 2 "" ""))]
9889 ""
9890 {
9891 s390_emit_call (XEXP (operands[0], 0), NULL_RTX, NULL_RTX,
9892 gen_rtx_REG (Pmode, RETURN_REGNUM));
9893 DONE;
9894 })
9895
9896 (define_insn "*bras"
9897 [(call (mem:QI (match_operand 0 "bras_sym_operand" "X"))
9898 (match_operand 1 "const_int_operand" "n"))
9899 (clobber (match_operand 2 "register_operand" "=r"))]
9900 "!SIBLING_CALL_P (insn)
9901 && TARGET_SMALL_EXEC
9902 && GET_MODE (operands[2]) == Pmode"
9903 "bras\t%2,%0"
9904 [(set_attr "op_type" "RI")
9905 (set_attr "type" "jsr")
9906 (set_attr "z196prop" "z196_cracked")])
9907
9908 (define_insn "*brasl"
9909 [(call (mem:QI (match_operand 0 "bras_sym_operand" "X"))
9910 (match_operand 1 "const_int_operand" "n"))
9911 (clobber (match_operand 2 "register_operand" "=r"))]
9912 "!SIBLING_CALL_P (insn)
9913 && TARGET_CPU_ZARCH
9914 && GET_MODE (operands[2]) == Pmode"
9915 "brasl\t%2,%0"
9916 [(set_attr "op_type" "RIL")
9917 (set_attr "type" "jsr")
9918 (set_attr "z196prop" "z196_cracked")])
9919
9920 (define_insn "*basr"
9921 [(call (mem:QI (match_operand 0 "address_operand" "ZR"))
9922 (match_operand 1 "const_int_operand" "n"))
9923 (clobber (match_operand 2 "register_operand" "=r"))]
9924 "!SIBLING_CALL_P (insn) && GET_MODE (operands[2]) == Pmode"
9925 {
9926 if (get_attr_op_type (insn) == OP_TYPE_RR)
9927 return "basr\t%2,%0";
9928 else
9929 return "bas\t%2,%a0";
9930 }
9931 [(set (attr "op_type")
9932 (if_then_else (match_operand 0 "register_operand" "")
9933 (const_string "RR") (const_string "RX")))
9934 (set_attr "type" "jsr")
9935 (set_attr "atype" "agen")
9936 (set_attr "z196prop" "z196_cracked")])
9937
9938 ;
9939 ; call_value instruction pattern(s).
9940 ;
9941
9942 (define_expand "call_value"
9943 [(set (match_operand 0 "" "")
9944 (call (match_operand 1 "" "")
9945 (match_operand 2 "" "")))
9946 (use (match_operand 3 "" ""))]
9947 ""
9948 {
9949 s390_emit_call (XEXP (operands[1], 0), NULL_RTX, operands[0],
9950 gen_rtx_REG (Pmode, RETURN_REGNUM));
9951 DONE;
9952 })
9953
9954 (define_insn "*bras_r"
9955 [(set (match_operand 0 "" "")
9956 (call (mem:QI (match_operand 1 "bras_sym_operand" "X"))
9957 (match_operand:SI 2 "const_int_operand" "n")))
9958 (clobber (match_operand 3 "register_operand" "=r"))]
9959 "!SIBLING_CALL_P (insn)
9960 && TARGET_SMALL_EXEC
9961 && GET_MODE (operands[3]) == Pmode"
9962 "bras\t%3,%1"
9963 [(set_attr "op_type" "RI")
9964 (set_attr "type" "jsr")
9965 (set_attr "z196prop" "z196_cracked")])
9966
9967 (define_insn "*brasl_r"
9968 [(set (match_operand 0 "" "")
9969 (call (mem:QI (match_operand 1 "bras_sym_operand" "X"))
9970 (match_operand 2 "const_int_operand" "n")))
9971 (clobber (match_operand 3 "register_operand" "=r"))]
9972 "!SIBLING_CALL_P (insn)
9973 && TARGET_CPU_ZARCH
9974 && GET_MODE (operands[3]) == Pmode"
9975 "brasl\t%3,%1"
9976 [(set_attr "op_type" "RIL")
9977 (set_attr "type" "jsr")
9978 (set_attr "z196prop" "z196_cracked")])
9979
9980 (define_insn "*basr_r"
9981 [(set (match_operand 0 "" "")
9982 (call (mem:QI (match_operand 1 "address_operand" "ZR"))
9983 (match_operand 2 "const_int_operand" "n")))
9984 (clobber (match_operand 3 "register_operand" "=r"))]
9985 "!SIBLING_CALL_P (insn) && GET_MODE (operands[3]) == Pmode"
9986 {
9987 if (get_attr_op_type (insn) == OP_TYPE_RR)
9988 return "basr\t%3,%1";
9989 else
9990 return "bas\t%3,%a1";
9991 }
9992 [(set (attr "op_type")
9993 (if_then_else (match_operand 1 "register_operand" "")
9994 (const_string "RR") (const_string "RX")))
9995 (set_attr "type" "jsr")
9996 (set_attr "atype" "agen")
9997 (set_attr "z196prop" "z196_cracked")])
9998
9999 ;;
10000 ;;- Thread-local storage support.
10001 ;;
10002
10003 (define_expand "get_thread_pointer<mode>"
10004 [(set (match_operand:P 0 "nonimmediate_operand" "") (reg:P TP_REGNUM))]
10005 ""
10006 "")
10007
10008 (define_expand "set_thread_pointer<mode>"
10009 [(set (reg:P TP_REGNUM) (match_operand:P 0 "nonimmediate_operand" ""))
10010 (set (reg:P TP_REGNUM) (unspec_volatile:P [(reg:P TP_REGNUM)] UNSPECV_SET_TP))]
10011 ""
10012 "")
10013
10014 (define_insn "*set_tp"
10015 [(set (reg TP_REGNUM) (unspec_volatile [(reg TP_REGNUM)] UNSPECV_SET_TP))]
10016 ""
10017 ""
10018 [(set_attr "type" "none")
10019 (set_attr "length" "0")])
10020
10021 (define_insn "*tls_load_64"
10022 [(set (match_operand:DI 0 "register_operand" "=d")
10023 (unspec:DI [(match_operand:DI 1 "memory_operand" "T")
10024 (match_operand:DI 2 "" "")]
10025 UNSPEC_TLS_LOAD))]
10026 "TARGET_64BIT"
10027 "lg\t%0,%1%J2"
10028 [(set_attr "op_type" "RXE")
10029 (set_attr "z10prop" "z10_fwd_A3")])
10030
10031 (define_insn "*tls_load_31"
10032 [(set (match_operand:SI 0 "register_operand" "=d,d")
10033 (unspec:SI [(match_operand:SI 1 "memory_operand" "R,T")
10034 (match_operand:SI 2 "" "")]
10035 UNSPEC_TLS_LOAD))]
10036 "!TARGET_64BIT"
10037 "@
10038 l\t%0,%1%J2
10039 ly\t%0,%1%J2"
10040 [(set_attr "op_type" "RX,RXY")
10041 (set_attr "type" "load")
10042 (set_attr "cpu_facility" "*,longdisp")
10043 (set_attr "z10prop" "z10_fwd_A3,z10_fwd_A3")])
10044
10045 (define_insn "*bras_tls"
10046 [(set (match_operand 0 "" "")
10047 (call (mem:QI (match_operand 1 "bras_sym_operand" "X"))
10048 (match_operand 2 "const_int_operand" "n")))
10049 (clobber (match_operand 3 "register_operand" "=r"))
10050 (use (match_operand 4 "" ""))]
10051 "!SIBLING_CALL_P (insn)
10052 && TARGET_SMALL_EXEC
10053 && GET_MODE (operands[3]) == Pmode"
10054 "bras\t%3,%1%J4"
10055 [(set_attr "op_type" "RI")
10056 (set_attr "type" "jsr")
10057 (set_attr "z196prop" "z196_cracked")])
10058
10059 (define_insn "*brasl_tls"
10060 [(set (match_operand 0 "" "")
10061 (call (mem:QI (match_operand 1 "bras_sym_operand" "X"))
10062 (match_operand 2 "const_int_operand" "n")))
10063 (clobber (match_operand 3 "register_operand" "=r"))
10064 (use (match_operand 4 "" ""))]
10065 "!SIBLING_CALL_P (insn)
10066 && TARGET_CPU_ZARCH
10067 && GET_MODE (operands[3]) == Pmode"
10068 "brasl\t%3,%1%J4"
10069 [(set_attr "op_type" "RIL")
10070 (set_attr "type" "jsr")
10071 (set_attr "z196prop" "z196_cracked")])
10072
10073 (define_insn "*basr_tls"
10074 [(set (match_operand 0 "" "")
10075 (call (mem:QI (match_operand 1 "address_operand" "ZR"))
10076 (match_operand 2 "const_int_operand" "n")))
10077 (clobber (match_operand 3 "register_operand" "=r"))
10078 (use (match_operand 4 "" ""))]
10079 "!SIBLING_CALL_P (insn) && GET_MODE (operands[3]) == Pmode"
10080 {
10081 if (get_attr_op_type (insn) == OP_TYPE_RR)
10082 return "basr\t%3,%1%J4";
10083 else
10084 return "bas\t%3,%a1%J4";
10085 }
10086 [(set (attr "op_type")
10087 (if_then_else (match_operand 1 "register_operand" "")
10088 (const_string "RR") (const_string "RX")))
10089 (set_attr "type" "jsr")
10090 (set_attr "atype" "agen")
10091 (set_attr "z196prop" "z196_cracked")])
10092
10093 ;;
10094 ;;- Atomic operations
10095 ;;
10096
10097 ;
10098 ; memory barrier patterns.
10099 ;
10100
10101 (define_expand "mem_signal_fence"
10102 [(match_operand:SI 0 "const_int_operand")] ;; model
10103 ""
10104 {
10105 /* The s390 memory model is strong enough not to require any
10106 barrier in order to synchronize a thread with itself. */
10107 DONE;
10108 })
10109
10110 (define_expand "mem_thread_fence"
10111 [(match_operand:SI 0 "const_int_operand")] ;; model
10112 ""
10113 {
10114 /* Unless this is a SEQ_CST fence, the s390 memory model is strong
10115 enough not to require barriers of any kind. */
10116 if (is_mm_seq_cst (memmodel_from_int (INTVAL (operands[0]))))
10117 {
10118 rtx mem = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
10119 MEM_VOLATILE_P (mem) = 1;
10120 emit_insn (gen_mem_thread_fence_1 (mem));
10121 }
10122 DONE;
10123 })
10124
10125 ; Although bcr is superscalar on Z10, this variant will never
10126 ; become part of an execution group.
10127 ; With z196 we can make use of the fast-BCR-serialization facility.
10128 ; This allows for a slightly faster sync which is sufficient for our
10129 ; purposes.
10130 (define_insn "mem_thread_fence_1"
10131 [(set (match_operand:BLK 0 "" "")
10132 (unspec:BLK [(match_dup 0)] UNSPEC_MB))]
10133 ""
10134 {
10135 if (TARGET_Z196)
10136 return "bcr\t14,0";
10137 else
10138 return "bcr\t15,0";
10139 }
10140 [(set_attr "op_type" "RR")
10141 (set_attr "mnemonic" "bcr_flush")
10142 (set_attr "z196prop" "z196_alone")])
10143
10144 ;
10145 ; atomic load/store operations
10146 ;
10147
10148 ; Atomic loads need not examine the memory model at all.
10149 (define_expand "atomic_load<mode>"
10150 [(match_operand:DINT 0 "register_operand") ;; output
10151 (match_operand:DINT 1 "memory_operand") ;; memory
10152 (match_operand:SI 2 "const_int_operand")] ;; model
10153 ""
10154 {
10155 if (MEM_ALIGN (operands[1]) < GET_MODE_BITSIZE (GET_MODE (operands[1])))
10156 FAIL;
10157
10158 if (<MODE>mode == TImode)
10159 emit_insn (gen_atomic_loadti_1 (operands[0], operands[1]));
10160 else if (<MODE>mode == DImode && !TARGET_ZARCH)
10161 emit_insn (gen_atomic_loaddi_1 (operands[0], operands[1]));
10162 else
10163 emit_move_insn (operands[0], operands[1]);
10164 DONE;
10165 })
10166
10167 ; Different from movdi_31 in that we want no splitters.
10168 (define_insn "atomic_loaddi_1"
10169 [(set (match_operand:DI 0 "register_operand" "=d,d,!*f,!*f")
10170 (unspec:DI [(match_operand:DI 1 "memory_operand" "Q,S,R,T")]
10171 UNSPEC_MOVA))]
10172 "!TARGET_ZARCH"
10173 "@
10174 lm\t%0,%M0,%S1
10175 lmy\t%0,%M0,%S1
10176 ld\t%0,%1
10177 ldy\t%0,%1"
10178 [(set_attr "op_type" "RS,RSY,RS,RSY")
10179 (set_attr "cpu_facility" "*,longdisp,*,longdisp")
10180 (set_attr "type" "lm,lm,floaddf,floaddf")])
10181
10182 (define_insn "atomic_loadti_1"
10183 [(set (match_operand:TI 0 "register_operand" "=r")
10184 (unspec:TI [(match_operand:TI 1 "memory_operand" "T")]
10185 UNSPEC_MOVA))]
10186 "TARGET_ZARCH"
10187 "lpq\t%0,%1"
10188 [(set_attr "op_type" "RXY")
10189 (set_attr "type" "other")])
10190
10191 ; Atomic stores must(?) enforce sequential consistency.
10192 (define_expand "atomic_store<mode>"
10193 [(match_operand:DINT 0 "memory_operand") ;; memory
10194 (match_operand:DINT 1 "register_operand") ;; input
10195 (match_operand:SI 2 "const_int_operand")] ;; model
10196 ""
10197 {
10198 enum memmodel model = memmodel_from_int (INTVAL (operands[2]));
10199
10200 if (MEM_ALIGN (operands[0]) < GET_MODE_BITSIZE (GET_MODE (operands[0])))
10201 FAIL;
10202
10203 if (<MODE>mode == TImode)
10204 emit_insn (gen_atomic_storeti_1 (operands[0], operands[1]));
10205 else if (<MODE>mode == DImode && !TARGET_ZARCH)
10206 emit_insn (gen_atomic_storedi_1 (operands[0], operands[1]));
10207 else
10208 emit_move_insn (operands[0], operands[1]);
10209 if (is_mm_seq_cst (model))
10210 emit_insn (gen_mem_thread_fence (operands[2]));
10211 DONE;
10212 })
10213
10214 ; Different from movdi_31 in that we want no splitters.
10215 (define_insn "atomic_storedi_1"
10216 [(set (match_operand:DI 0 "memory_operand" "=Q,S,R,T")
10217 (unspec:DI [(match_operand:DI 1 "register_operand" "d,d,!*f,!*f")]
10218 UNSPEC_MOVA))]
10219 "!TARGET_ZARCH"
10220 "@
10221 stm\t%1,%N1,%S0
10222 stmy\t%1,%N1,%S0
10223 std %1,%0
10224 stdy %1,%0"
10225 [(set_attr "op_type" "RS,RSY,RS,RSY")
10226 (set_attr "cpu_facility" "*,longdisp,*,longdisp")
10227 (set_attr "type" "stm,stm,fstoredf,fstoredf")])
10228
10229 (define_insn "atomic_storeti_1"
10230 [(set (match_operand:TI 0 "memory_operand" "=T")
10231 (unspec:TI [(match_operand:TI 1 "register_operand" "r")]
10232 UNSPEC_MOVA))]
10233 "TARGET_ZARCH"
10234 "stpq\t%1,%0"
10235 [(set_attr "op_type" "RXY")
10236 (set_attr "type" "other")])
10237
10238 ;
10239 ; compare and swap patterns.
10240 ;
10241
10242 (define_expand "atomic_compare_and_swap<mode>"
10243 [(match_operand:SI 0 "register_operand") ;; bool success output
10244 (match_operand:DINT 1 "nonimmediate_operand");; oldval output
10245 (match_operand:DINT 2 "s_operand") ;; memory
10246 (match_operand:DINT 3 "general_operand") ;; expected intput
10247 (match_operand:DINT 4 "general_operand") ;; newval intput
10248 (match_operand:SI 5 "const_int_operand") ;; is_weak
10249 (match_operand:SI 6 "const_int_operand") ;; success model
10250 (match_operand:SI 7 "const_int_operand")] ;; failure model
10251 ""
10252 {
10253 if (GET_MODE_BITSIZE (<MODE>mode) >= 16
10254 && GET_MODE_BITSIZE (<MODE>mode) > MEM_ALIGN (operands[2]))
10255 FAIL;
10256
10257 s390_expand_cs (<MODE>mode, operands[0], operands[1], operands[2],
10258 operands[3], operands[4], INTVAL (operands[5]));
10259 DONE;})
10260
10261 (define_expand "atomic_compare_and_swap<mode>_internal"
10262 [(parallel
10263 [(set (match_operand:DGPR 0 "register_operand")
10264 (match_operand:DGPR 1 "s_operand"))
10265 (set (match_dup 1)
10266 (unspec_volatile:DGPR
10267 [(match_dup 1)
10268 (match_operand:DGPR 2 "register_operand")
10269 (match_operand:DGPR 3 "register_operand")]
10270 UNSPECV_CAS))
10271 (set (match_operand 4 "cc_reg_operand")
10272 (match_dup 5))])]
10273 "GET_MODE (operands[4]) == CCZmode
10274 || GET_MODE (operands[4]) == CCZ1mode"
10275 {
10276 operands[5]
10277 = gen_rtx_COMPARE (GET_MODE (operands[4]), operands[1], operands[2]);
10278 })
10279
10280 ; cdsg, csg
10281 (define_insn "*atomic_compare_and_swap<mode>_1"
10282 [(set (match_operand:TDI 0 "register_operand" "=r")
10283 (match_operand:TDI 1 "s_operand" "+S"))
10284 (set (match_dup 1)
10285 (unspec_volatile:TDI
10286 [(match_dup 1)
10287 (match_operand:TDI 2 "register_operand" "0")
10288 (match_operand:TDI 3 "register_operand" "r")]
10289 UNSPECV_CAS))
10290 (set (reg CC_REGNUM)
10291 (compare (match_dup 1) (match_dup 2)))]
10292 "TARGET_ZARCH
10293 && s390_match_ccmode (insn, CCZ1mode)"
10294 "c<td>sg\t%0,%3,%S1"
10295 [(set_attr "op_type" "RSY")
10296 (set_attr "type" "sem")])
10297
10298 ; cds, cdsy
10299 (define_insn "*atomic_compare_and_swapdi_2"
10300 [(set (match_operand:DI 0 "register_operand" "=r,r")
10301 (match_operand:DI 1 "s_operand" "+Q,S"))
10302 (set (match_dup 1)
10303 (unspec_volatile:DI
10304 [(match_dup 1)
10305 (match_operand:DI 2 "register_operand" "0,0")
10306 (match_operand:DI 3 "register_operand" "r,r")]
10307 UNSPECV_CAS))
10308 (set (reg CC_REGNUM)
10309 (compare (match_dup 1) (match_dup 2)))]
10310 "!TARGET_ZARCH
10311 && s390_match_ccmode (insn, CCZ1mode)"
10312 "@
10313 cds\t%0,%3,%S1
10314 cdsy\t%0,%3,%S1"
10315 [(set_attr "op_type" "RS,RSY")
10316 (set_attr "cpu_facility" "*,longdisp")
10317 (set_attr "type" "sem")])
10318
10319 ; cs, csy
10320 (define_insn "*atomic_compare_and_swapsi_3"
10321 [(set (match_operand:SI 0 "register_operand" "=r,r")
10322 (match_operand:SI 1 "s_operand" "+Q,S"))
10323 (set (match_dup 1)
10324 (unspec_volatile:SI
10325 [(match_dup 1)
10326 (match_operand:SI 2 "register_operand" "0,0")
10327 (match_operand:SI 3 "register_operand" "r,r")]
10328 UNSPECV_CAS))
10329 (set (reg CC_REGNUM)
10330 (compare (match_dup 1) (match_dup 2)))]
10331 "s390_match_ccmode (insn, CCZ1mode)"
10332 "@
10333 cs\t%0,%3,%S1
10334 csy\t%0,%3,%S1"
10335 [(set_attr "op_type" "RS,RSY")
10336 (set_attr "cpu_facility" "*,longdisp")
10337 (set_attr "type" "sem")])
10338
10339 ;
10340 ; Other atomic instruction patterns.
10341 ;
10342
10343 ; z196 load and add, xor, or and and instructions
10344
10345 (define_expand "atomic_fetch_<atomic><mode>"
10346 [(match_operand:GPR 0 "register_operand") ;; val out
10347 (ATOMIC_Z196:GPR
10348 (match_operand:GPR 1 "memory_operand") ;; memory
10349 (match_operand:GPR 2 "register_operand")) ;; val in
10350 (match_operand:SI 3 "const_int_operand")] ;; model
10351 "TARGET_Z196"
10352 {
10353 if (MEM_ALIGN (operands[1]) < GET_MODE_BITSIZE (GET_MODE (operands[1])))
10354 FAIL;
10355
10356 emit_insn (gen_atomic_fetch_<atomic><mode>_iaf
10357 (operands[0], operands[1], operands[2]));
10358 DONE;
10359 })
10360
10361 ; lan, lang, lao, laog, lax, laxg, laa, laag
10362 (define_insn "atomic_fetch_<atomic><mode>_iaf"
10363 [(set (match_operand:GPR 0 "register_operand" "=d")
10364 (match_operand:GPR 1 "memory_operand" "+S"))
10365 (set (match_dup 1)
10366 (unspec_volatile:GPR
10367 [(ATOMIC_Z196:GPR (match_dup 1)
10368 (match_operand:GPR 2 "general_operand" "d"))]
10369 UNSPECV_ATOMIC_OP))
10370 (clobber (reg:CC CC_REGNUM))]
10371 "TARGET_Z196"
10372 "la<noxa><g>\t%0,%2,%1"
10373 [(set_attr "op_type" "RSY")
10374 (set_attr "type" "sem")])
10375
10376 ;; For SImode and larger, the optabs.c code will do just fine in
10377 ;; expanding a compare-and-swap loop. For QI/HImode, we can do
10378 ;; better by expanding our own loop.
10379
10380 (define_expand "atomic_<atomic><mode>"
10381 [(ATOMIC:HQI
10382 (match_operand:HQI 0 "memory_operand") ;; memory
10383 (match_operand:HQI 1 "general_operand")) ;; val in
10384 (match_operand:SI 2 "const_int_operand")] ;; model
10385 ""
10386 {
10387 s390_expand_atomic (<MODE>mode, <CODE>, NULL_RTX, operands[0],
10388 operands[1], false);
10389 DONE;
10390 })
10391
10392 (define_expand "atomic_fetch_<atomic><mode>"
10393 [(match_operand:HQI 0 "register_operand") ;; val out
10394 (ATOMIC:HQI
10395 (match_operand:HQI 1 "memory_operand") ;; memory
10396 (match_operand:HQI 2 "general_operand")) ;; val in
10397 (match_operand:SI 3 "const_int_operand")] ;; model
10398 ""
10399 {
10400 s390_expand_atomic (<MODE>mode, <CODE>, operands[0], operands[1],
10401 operands[2], false);
10402 DONE;
10403 })
10404
10405 (define_expand "atomic_<atomic>_fetch<mode>"
10406 [(match_operand:HQI 0 "register_operand") ;; val out
10407 (ATOMIC:HQI
10408 (match_operand:HQI 1 "memory_operand") ;; memory
10409 (match_operand:HQI 2 "general_operand")) ;; val in
10410 (match_operand:SI 3 "const_int_operand")] ;; model
10411 ""
10412 {
10413 s390_expand_atomic (<MODE>mode, <CODE>, operands[0], operands[1],
10414 operands[2], true);
10415 DONE;
10416 })
10417
10418 ;; Pattern to implement atomic_exchange with a compare-and-swap loop. The code
10419 ;; generated by the middleend is not good.
10420 (define_expand "atomic_exchange<mode>"
10421 [(match_operand:DINT 0 "register_operand") ;; val out
10422 (match_operand:DINT 1 "s_operand") ;; memory
10423 (match_operand:DINT 2 "general_operand") ;; val in
10424 (match_operand:SI 3 "const_int_operand")] ;; model
10425 ""
10426 {
10427 if (<MODE>mode != QImode
10428 && MEM_ALIGN (operands[1]) < GET_MODE_BITSIZE (<MODE>mode))
10429 FAIL;
10430 if (<MODE>mode == HImode || <MODE>mode == QImode)
10431 s390_expand_atomic (<MODE>mode, SET, operands[0], operands[1], operands[2],
10432 false);
10433 else if (<MODE>mode == SImode || TARGET_ZARCH)
10434 s390_expand_atomic_exchange_tdsi (operands[0], operands[1], operands[2]);
10435 else
10436 FAIL;
10437 DONE;
10438 })
10439
10440 ;;
10441 ;;- Miscellaneous instructions.
10442 ;;
10443
10444 ;
10445 ; allocate stack instruction pattern(s).
10446 ;
10447
10448 (define_expand "allocate_stack"
10449 [(match_operand 0 "general_operand" "")
10450 (match_operand 1 "general_operand" "")]
10451 "TARGET_BACKCHAIN"
10452 {
10453 rtx temp = gen_reg_rtx (Pmode);
10454
10455 emit_move_insn (temp, s390_back_chain_rtx ());
10456 anti_adjust_stack (operands[1]);
10457 emit_move_insn (s390_back_chain_rtx (), temp);
10458
10459 emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
10460 DONE;
10461 })
10462
10463
10464 ;
10465 ; setjmp instruction pattern.
10466 ;
10467
10468 (define_expand "builtin_setjmp_receiver"
10469 [(match_operand 0 "" "")]
10470 "flag_pic"
10471 {
10472 emit_insn (s390_load_got ());
10473 emit_use (pic_offset_table_rtx);
10474 DONE;
10475 })
10476
10477 ;; These patterns say how to save and restore the stack pointer. We need not
10478 ;; save the stack pointer at function level since we are careful to
10479 ;; preserve the backchain. At block level, we have to restore the backchain
10480 ;; when we restore the stack pointer.
10481 ;;
10482 ;; For nonlocal gotos, we must save both the stack pointer and its
10483 ;; backchain and restore both. Note that in the nonlocal case, the
10484 ;; save area is a memory location.
10485
10486 (define_expand "save_stack_function"
10487 [(match_operand 0 "general_operand" "")
10488 (match_operand 1 "general_operand" "")]
10489 ""
10490 "DONE;")
10491
10492 (define_expand "restore_stack_function"
10493 [(match_operand 0 "general_operand" "")
10494 (match_operand 1 "general_operand" "")]
10495 ""
10496 "DONE;")
10497
10498 (define_expand "restore_stack_block"
10499 [(match_operand 0 "register_operand" "")
10500 (match_operand 1 "register_operand" "")]
10501 "TARGET_BACKCHAIN"
10502 {
10503 rtx temp = gen_reg_rtx (Pmode);
10504
10505 emit_move_insn (temp, s390_back_chain_rtx ());
10506 emit_move_insn (operands[0], operands[1]);
10507 emit_move_insn (s390_back_chain_rtx (), temp);
10508
10509 DONE;
10510 })
10511
10512 (define_expand "save_stack_nonlocal"
10513 [(match_operand 0 "memory_operand" "")
10514 (match_operand 1 "register_operand" "")]
10515 ""
10516 {
10517 rtx base = gen_rtx_REG (Pmode, BASE_REGNUM);
10518
10519 /* Copy the backchain to the first word, sp to the second and the
10520 literal pool base to the third. */
10521
10522 rtx save_bc = adjust_address (operands[0], Pmode, 0);
10523 rtx save_sp = adjust_address (operands[0], Pmode, GET_MODE_SIZE (Pmode));
10524 rtx save_bp = adjust_address (operands[0], Pmode, 2 * GET_MODE_SIZE (Pmode));
10525
10526 if (TARGET_BACKCHAIN)
10527 emit_move_insn (save_bc, force_reg (Pmode, s390_back_chain_rtx ()));
10528
10529 emit_move_insn (save_sp, operands[1]);
10530 emit_move_insn (save_bp, base);
10531
10532 DONE;
10533 })
10534
10535 (define_expand "restore_stack_nonlocal"
10536 [(match_operand 0 "register_operand" "")
10537 (match_operand 1 "memory_operand" "")]
10538 ""
10539 {
10540 rtx base = gen_rtx_REG (Pmode, BASE_REGNUM);
10541 rtx temp = NULL_RTX;
10542
10543 /* Restore the backchain from the first word, sp from the second and the
10544 literal pool base from the third. */
10545
10546 rtx save_bc = adjust_address (operands[1], Pmode, 0);
10547 rtx save_sp = adjust_address (operands[1], Pmode, GET_MODE_SIZE (Pmode));
10548 rtx save_bp = adjust_address (operands[1], Pmode, 2 * GET_MODE_SIZE (Pmode));
10549
10550 if (TARGET_BACKCHAIN)
10551 temp = force_reg (Pmode, save_bc);
10552
10553 emit_move_insn (base, save_bp);
10554 emit_move_insn (operands[0], save_sp);
10555
10556 if (temp)
10557 emit_move_insn (s390_back_chain_rtx (), temp);
10558
10559 emit_use (base);
10560 DONE;
10561 })
10562
10563 (define_expand "exception_receiver"
10564 [(const_int 0)]
10565 ""
10566 {
10567 s390_set_has_landing_pad_p (true);
10568 DONE;
10569 })
10570
10571 ;
10572 ; nop instruction pattern(s).
10573 ;
10574
10575 (define_insn "nop"
10576 [(const_int 0)]
10577 ""
10578 "lr\t0,0"
10579 [(set_attr "op_type" "RR")
10580 (set_attr "z10prop" "z10_fr_E1")])
10581
10582 (define_insn "nop1"
10583 [(const_int 1)]
10584 ""
10585 "lr\t1,1"
10586 [(set_attr "op_type" "RR")])
10587
10588 ;;- Undeletable nops (used for hotpatching)
10589
10590 (define_insn "nop_2_byte"
10591 [(unspec_volatile [(const_int 0)] UNSPECV_NOP_2_BYTE)]
10592 ""
10593 "nopr\t%%r0"
10594 [(set_attr "op_type" "RR")])
10595
10596 (define_insn "nop_4_byte"
10597 [(unspec_volatile [(const_int 0)] UNSPECV_NOP_4_BYTE)]
10598 ""
10599 "nop\t0"
10600 [(set_attr "op_type" "RX")])
10601
10602 (define_insn "nop_6_byte"
10603 [(unspec_volatile [(const_int 0)] UNSPECV_NOP_6_BYTE)]
10604 "TARGET_CPU_ZARCH"
10605 "brcl\t0, 0"
10606 [(set_attr "op_type" "RIL")])
10607
10608
10609 ;
10610 ; Special literal pool access instruction pattern(s).
10611 ;
10612
10613 (define_insn "*pool_entry"
10614 [(unspec_volatile [(match_operand 0 "consttable_operand" "X")]
10615 UNSPECV_POOL_ENTRY)]
10616 ""
10617 {
10618 machine_mode mode = GET_MODE (PATTERN (insn));
10619 unsigned int align = GET_MODE_BITSIZE (mode);
10620 s390_output_pool_entry (operands[0], mode, align);
10621 return "";
10622 }
10623 [(set (attr "length")
10624 (symbol_ref "GET_MODE_SIZE (GET_MODE (PATTERN (insn)))"))])
10625
10626 (define_insn "pool_align"
10627 [(unspec_volatile [(match_operand 0 "const_int_operand" "n")]
10628 UNSPECV_POOL_ALIGN)]
10629 ""
10630 ".align\t%0"
10631 [(set (attr "length") (symbol_ref "INTVAL (operands[0])"))])
10632
10633 (define_insn "pool_section_start"
10634 [(unspec_volatile [(const_int 1)] UNSPECV_POOL_SECTION)]
10635 ""
10636 {
10637 switch_to_section (targetm.asm_out.function_rodata_section
10638 (current_function_decl));
10639 return "";
10640 }
10641 [(set_attr "length" "0")])
10642
10643 (define_insn "pool_section_end"
10644 [(unspec_volatile [(const_int 0)] UNSPECV_POOL_SECTION)]
10645 ""
10646 {
10647 switch_to_section (current_function_section ());
10648 return "";
10649 }
10650 [(set_attr "length" "0")])
10651
10652 (define_insn "main_base_31_small"
10653 [(set (match_operand 0 "register_operand" "=a")
10654 (unspec [(label_ref (match_operand 1 "" ""))] UNSPEC_MAIN_BASE))]
10655 "!TARGET_CPU_ZARCH && GET_MODE (operands[0]) == Pmode"
10656 "basr\t%0,0"
10657 [(set_attr "op_type" "RR")
10658 (set_attr "type" "la")
10659 (set_attr "z196prop" "z196_cracked")])
10660
10661 (define_insn "main_base_31_large"
10662 [(set (match_operand 0 "register_operand" "=a")
10663 (unspec [(label_ref (match_operand 1 "" ""))] UNSPEC_MAIN_BASE))
10664 (set (pc) (label_ref (match_operand 2 "" "")))]
10665 "!TARGET_CPU_ZARCH && GET_MODE (operands[0]) == Pmode"
10666 "bras\t%0,%2"
10667 [(set_attr "op_type" "RI")
10668 (set_attr "z196prop" "z196_cracked")])
10669
10670 (define_insn "main_base_64"
10671 [(set (match_operand 0 "register_operand" "=a")
10672 (unspec [(label_ref (match_operand 1 "" ""))] UNSPEC_MAIN_BASE))]
10673 "TARGET_CPU_ZARCH && GET_MODE (operands[0]) == Pmode"
10674 "larl\t%0,%1"
10675 [(set_attr "op_type" "RIL")
10676 (set_attr "type" "larl")
10677 (set_attr "z10prop" "z10_fwd_A1")])
10678
10679 (define_insn "main_pool"
10680 [(set (match_operand 0 "register_operand" "=a")
10681 (unspec_volatile [(const_int 0)] UNSPECV_MAIN_POOL))]
10682 "GET_MODE (operands[0]) == Pmode"
10683 {
10684 gcc_unreachable ();
10685 }
10686 [(set (attr "type")
10687 (if_then_else (match_test "TARGET_CPU_ZARCH")
10688 (const_string "larl") (const_string "la")))])
10689
10690 (define_insn "reload_base_31"
10691 [(set (match_operand 0 "register_operand" "=a")
10692 (unspec [(label_ref (match_operand 1 "" ""))] UNSPEC_RELOAD_BASE))]
10693 "!TARGET_CPU_ZARCH && GET_MODE (operands[0]) == Pmode"
10694 "basr\t%0,0\;la\t%0,%1-.(%0)"
10695 [(set_attr "length" "6")
10696 (set_attr "type" "la")
10697 (set_attr "z196prop" "z196_cracked")])
10698
10699 (define_insn "reload_base_64"
10700 [(set (match_operand 0 "register_operand" "=a")
10701 (unspec [(label_ref (match_operand 1 "" ""))] UNSPEC_RELOAD_BASE))]
10702 "TARGET_CPU_ZARCH && GET_MODE (operands[0]) == Pmode"
10703 "larl\t%0,%1"
10704 [(set_attr "op_type" "RIL")
10705 (set_attr "type" "larl")
10706 (set_attr "z10prop" "z10_fwd_A1")])
10707
10708 (define_insn "pool"
10709 [(unspec_volatile [(match_operand 0 "const_int_operand" "n")] UNSPECV_POOL)]
10710 ""
10711 {
10712 gcc_unreachable ();
10713 }
10714 [(set (attr "length") (symbol_ref "INTVAL (operands[0])"))])
10715
10716 ;;
10717 ;; Insns related to generating the function prologue and epilogue.
10718 ;;
10719
10720
10721 (define_expand "prologue"
10722 [(use (const_int 0))]
10723 ""
10724 "s390_emit_prologue (); DONE;")
10725
10726 (define_expand "epilogue"
10727 [(use (const_int 1))]
10728 ""
10729 "s390_emit_epilogue (false); DONE;")
10730
10731 (define_expand "sibcall_epilogue"
10732 [(use (const_int 0))]
10733 ""
10734 "s390_emit_epilogue (true); DONE;")
10735
10736 ;; A direct return instruction, without using an epilogue.
10737 (define_insn "<code>"
10738 [(ANY_RETURN)]
10739 "s390_can_use_<code>_insn ()"
10740 "br\t%%r14"
10741 [(set_attr "op_type" "RR")
10742 (set_attr "type" "jsr")
10743 (set_attr "atype" "agen")])
10744
10745 (define_insn "*return"
10746 [(return)
10747 (use (match_operand 0 "register_operand" "a"))]
10748 "GET_MODE (operands[0]) == Pmode"
10749 "br\t%0"
10750 [(set_attr "op_type" "RR")
10751 (set_attr "type" "jsr")
10752 (set_attr "atype" "agen")])
10753
10754
10755 ;; Instruction definition to extend a 31-bit pointer into a 64-bit
10756 ;; pointer. This is used for compatibility.
10757
10758 (define_expand "ptr_extend"
10759 [(set (match_operand:DI 0 "register_operand" "=r")
10760 (match_operand:SI 1 "register_operand" "r"))]
10761 "TARGET_64BIT"
10762 {
10763 emit_insn (gen_anddi3 (operands[0],
10764 gen_lowpart (DImode, operands[1]),
10765 GEN_INT (0x7fffffff)));
10766 DONE;
10767 })
10768
10769 ;; Instruction definition to expand eh_return macro to support
10770 ;; swapping in special linkage return addresses.
10771
10772 (define_expand "eh_return"
10773 [(use (match_operand 0 "register_operand" ""))]
10774 "TARGET_TPF"
10775 {
10776 s390_emit_tpf_eh_return (operands[0]);
10777 DONE;
10778 })
10779
10780 ;
10781 ; Stack Protector Patterns
10782 ;
10783
10784 (define_expand "stack_protect_set"
10785 [(set (match_operand 0 "memory_operand" "")
10786 (match_operand 1 "memory_operand" ""))]
10787 ""
10788 {
10789 #ifdef TARGET_THREAD_SSP_OFFSET
10790 operands[1]
10791 = gen_rtx_MEM (Pmode, gen_rtx_PLUS (Pmode, s390_get_thread_pointer (),
10792 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
10793 #endif
10794 if (TARGET_64BIT)
10795 emit_insn (gen_stack_protect_setdi (operands[0], operands[1]));
10796 else
10797 emit_insn (gen_stack_protect_setsi (operands[0], operands[1]));
10798
10799 DONE;
10800 })
10801
10802 (define_insn "stack_protect_set<mode>"
10803 [(set (match_operand:DSI 0 "memory_operand" "=Q")
10804 (unspec:DSI [(match_operand:DSI 1 "memory_operand" "Q")] UNSPEC_SP_SET))]
10805 ""
10806 "mvc\t%O0(%G0,%R0),%S1"
10807 [(set_attr "op_type" "SS")])
10808
10809 (define_expand "stack_protect_test"
10810 [(set (reg:CC CC_REGNUM)
10811 (compare (match_operand 0 "memory_operand" "")
10812 (match_operand 1 "memory_operand" "")))
10813 (match_operand 2 "" "")]
10814 ""
10815 {
10816 rtx cc_reg, test;
10817 #ifdef TARGET_THREAD_SSP_OFFSET
10818 operands[1]
10819 = gen_rtx_MEM (Pmode, gen_rtx_PLUS (Pmode, s390_get_thread_pointer (),
10820 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
10821 #endif
10822 if (TARGET_64BIT)
10823 emit_insn (gen_stack_protect_testdi (operands[0], operands[1]));
10824 else
10825 emit_insn (gen_stack_protect_testsi (operands[0], operands[1]));
10826
10827 cc_reg = gen_rtx_REG (CCZmode, CC_REGNUM);
10828 test = gen_rtx_EQ (VOIDmode, cc_reg, const0_rtx);
10829 emit_jump_insn (gen_cbranchcc4 (test, cc_reg, const0_rtx, operands[2]));
10830 DONE;
10831 })
10832
10833 (define_insn "stack_protect_test<mode>"
10834 [(set (reg:CCZ CC_REGNUM)
10835 (unspec:CCZ [(match_operand:DSI 0 "memory_operand" "Q")
10836 (match_operand:DSI 1 "memory_operand" "Q")] UNSPEC_SP_TEST))]
10837 ""
10838 "clc\t%O0(%G0,%R0),%S1"
10839 [(set_attr "op_type" "SS")])
10840
10841 ; This is used in s390_emit_prologue in order to prevent insns
10842 ; adjusting the stack pointer to be moved over insns writing stack
10843 ; slots using a copy of the stack pointer in a different register.
10844 (define_insn "stack_tie"
10845 [(set (match_operand:BLK 0 "memory_operand" "+m")
10846 (unspec:BLK [(match_dup 0)] UNSPEC_TIE))]
10847 ""
10848 ""
10849 [(set_attr "length" "0")])
10850
10851
10852 (define_insn "stack_restore_from_fpr"
10853 [(set (reg:DI STACK_REGNUM)
10854 (match_operand:DI 0 "register_operand" "f"))
10855 (clobber (mem:BLK (scratch)))]
10856 "TARGET_Z10"
10857 "lgdr\t%%r15,%0"
10858 [(set_attr "op_type" "RRE")])
10859
10860 ;
10861 ; Data prefetch patterns
10862 ;
10863
10864 (define_insn "prefetch"
10865 [(prefetch (match_operand 0 "address_operand" "ZT,X")
10866 (match_operand:SI 1 "const_int_operand" " n,n")
10867 (match_operand:SI 2 "const_int_operand" " n,n"))]
10868 "TARGET_Z10"
10869 {
10870 switch (which_alternative)
10871 {
10872 case 0:
10873 return INTVAL (operands[1]) == 1 ? "pfd\t2,%a0" : "pfd\t1,%a0";
10874 case 1:
10875 if (larl_operand (operands[0], Pmode))
10876 return INTVAL (operands[1]) == 1 ? "pfdrl\t2,%a0" : "pfdrl\t1,%a0";
10877 /* fallthrough */
10878 default:
10879
10880 /* This might be reached for symbolic operands with an odd
10881 addend. We simply omit the prefetch for such rare cases. */
10882
10883 return "";
10884 }
10885 }
10886 [(set_attr "type" "load,larl")
10887 (set_attr "op_type" "RXY,RIL")
10888 (set_attr "z10prop" "z10_super")
10889 (set_attr "z196prop" "z196_alone")])
10890
10891
10892 ;
10893 ; Byte swap instructions
10894 ;
10895
10896 ; FIXME: There is also mvcin but we cannot use it since src and target
10897 ; may overlap.
10898 ; lrvr, lrv, strv, lrvgr, lrvg, strvg
10899 (define_insn "bswap<mode>2"
10900 [(set (match_operand:GPR 0 "nonimmediate_operand" "=d,d,T")
10901 (bswap:GPR (match_operand:GPR 1 "nonimmediate_operand" " d,T,d")))]
10902 "TARGET_CPU_ZARCH"
10903 "@
10904 lrv<g>r\t%0,%1
10905 lrv<g>\t%0,%1
10906 strv<g>\t%1,%0"
10907 [(set_attr "type" "*,load,store")
10908 (set_attr "op_type" "RRE,RXY,RXY")
10909 (set_attr "z10prop" "z10_super")])
10910
10911 (define_insn "bswaphi2"
10912 [(set (match_operand:HI 0 "nonimmediate_operand" "=d,d,T")
10913 (bswap:HI (match_operand:HI 1 "nonimmediate_operand" " d,T,d")))]
10914 "TARGET_CPU_ZARCH"
10915 "@
10916 #
10917 lrvh\t%0,%1
10918 strvh\t%1,%0"
10919 [(set_attr "type" "*,load,store")
10920 (set_attr "op_type" "RRE,RXY,RXY")
10921 (set_attr "z10prop" "z10_super")])
10922
10923 (define_split
10924 [(set (match_operand:HI 0 "register_operand" "")
10925 (bswap:HI (match_operand:HI 1 "register_operand" "")))]
10926 "TARGET_CPU_ZARCH"
10927 [(set (match_dup 2) (bswap:SI (match_dup 3)))
10928 (set (match_dup 2) (lshiftrt:SI (match_dup 2) (const_int 16)))]
10929 {
10930 operands[2] = simplify_gen_subreg (SImode, operands[0], HImode, 0);
10931 operands[3] = simplify_gen_subreg (SImode, operands[1], HImode, 0);
10932 })
10933
10934
10935 ;
10936 ; Population count instruction
10937 ;
10938
10939 ; The S/390 popcount instruction counts the bits of op1 in 8 byte
10940 ; portions and stores the result in the corresponding bytes in op0.
10941 (define_insn "*popcount<mode>"
10942 [(set (match_operand:INT 0 "register_operand" "=d")
10943 (unspec:INT [(match_operand:INT 1 "register_operand" "d")] UNSPEC_POPCNT))
10944 (clobber (reg:CC CC_REGNUM))]
10945 "TARGET_Z196"
10946 "popcnt\t%0,%1"
10947 [(set_attr "op_type" "RRE")])
10948
10949 (define_expand "popcountdi2"
10950 [; popcnt op0, op1
10951 (parallel [(set (match_operand:DI 0 "register_operand" "")
10952 (unspec:DI [(match_operand:DI 1 "register_operand")]
10953 UNSPEC_POPCNT))
10954 (clobber (reg:CC CC_REGNUM))])
10955 ; sllg op2, op0, 32
10956 (set (match_dup 2) (ashift:DI (match_dup 0) (const_int 32)))
10957 ; agr op0, op2
10958 (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 2)))
10959 (clobber (reg:CC CC_REGNUM))])
10960 ; sllg op2, op0, 16
10961 (set (match_dup 2)
10962 (ashift:DI (match_dup 0) (const_int 16)))
10963 ; agr op0, op2
10964 (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 2)))
10965 (clobber (reg:CC CC_REGNUM))])
10966 ; sllg op2, op0, 8
10967 (set (match_dup 2) (ashift:DI (match_dup 0) (const_int 8)))
10968 ; agr op0, op2
10969 (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 2)))
10970 (clobber (reg:CC CC_REGNUM))])
10971 ; srlg op0, op0, 56
10972 (set (match_dup 0) (lshiftrt:DI (match_dup 0) (const_int 56)))]
10973 "TARGET_Z196 && TARGET_64BIT"
10974 "operands[2] = gen_reg_rtx (DImode);")
10975
10976 (define_expand "popcountsi2"
10977 [; popcnt op0, op1
10978 (parallel [(set (match_operand:SI 0 "register_operand" "")
10979 (unspec:SI [(match_operand:SI 1 "register_operand")]
10980 UNSPEC_POPCNT))
10981 (clobber (reg:CC CC_REGNUM))])
10982 ; sllk op2, op0, 16
10983 (set (match_dup 2)
10984 (ashift:SI (match_dup 0) (const_int 16)))
10985 ; ar op0, op2
10986 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
10987 (clobber (reg:CC CC_REGNUM))])
10988 ; sllk op2, op0, 8
10989 (set (match_dup 2) (ashift:SI (match_dup 0) (const_int 8)))
10990 ; ar op0, op2
10991 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
10992 (clobber (reg:CC CC_REGNUM))])
10993 ; srl op0, op0, 24
10994 (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 24)))]
10995 "TARGET_Z196"
10996 "operands[2] = gen_reg_rtx (SImode);")
10997
10998 (define_expand "popcounthi2"
10999 [; popcnt op0, op1
11000 (parallel [(set (match_operand:HI 0 "register_operand" "")
11001 (unspec:HI [(match_operand:HI 1 "register_operand")]
11002 UNSPEC_POPCNT))
11003 (clobber (reg:CC CC_REGNUM))])
11004 ; sllk op2, op0, 8
11005 (set (match_dup 2)
11006 (ashift:SI (match_dup 0) (const_int 8)))
11007 ; ar op0, op2
11008 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
11009 (clobber (reg:CC CC_REGNUM))])
11010 ; srl op0, op0, 8
11011 (set (match_dup 0) (lshiftrt:HI (match_dup 0) (const_int 8)))]
11012 "TARGET_Z196"
11013 "operands[2] = gen_reg_rtx (SImode);")
11014
11015 (define_expand "popcountqi2"
11016 [; popcnt op0, op1
11017 (parallel [(set (match_operand:QI 0 "register_operand" "")
11018 (unspec:QI [(match_operand:QI 1 "register_operand")]
11019 UNSPEC_POPCNT))
11020 (clobber (reg:CC CC_REGNUM))])]
11021 "TARGET_Z196"
11022 "")
11023
11024 ;;
11025 ;;- Copy sign instructions
11026 ;;
11027
11028 (define_insn "copysign<mode>3"
11029 [(set (match_operand:FP 0 "register_operand" "=f")
11030 (unspec:FP [(match_operand:FP 1 "register_operand" "<fT0>")
11031 (match_operand:FP 2 "register_operand" "f")]
11032 UNSPEC_COPYSIGN))]
11033 "TARGET_Z196"
11034 "cpsdr\t%0,%2,%1"
11035 [(set_attr "op_type" "RRF")
11036 (set_attr "type" "fsimp<mode>")])
11037
11038
11039 ;;
11040 ;;- Transactional execution instructions
11041 ;;
11042
11043 ; This splitter helps combine to make use of CC directly when
11044 ; comparing the integer result of a tbegin builtin with a constant.
11045 ; The unspec is already removed by canonicalize_comparison. So this
11046 ; splitters only job is to turn the PARALLEL into separate insns
11047 ; again. Unfortunately this only works with the very first cc/int
11048 ; compare since combine is not able to deal with data flow across
11049 ; basic block boundaries.
11050
11051 ; It needs to be an insn pattern as well since combine does not apply
11052 ; the splitter directly. Combine would only use it if it actually
11053 ; would reduce the number of instructions.
11054 (define_insn_and_split "*ccraw_to_int"
11055 [(set (pc)
11056 (if_then_else
11057 (match_operator 0 "s390_eqne_operator"
11058 [(reg:CCRAW CC_REGNUM)
11059 (match_operand 1 "const_int_operand" "")])
11060 (label_ref (match_operand 2 "" ""))
11061 (pc)))
11062 (set (match_operand:SI 3 "register_operand" "=d")
11063 (unspec:SI [(reg:CCRAW CC_REGNUM)] UNSPEC_CC_TO_INT))]
11064 ""
11065 "#"
11066 ""
11067 [(set (match_dup 3)
11068 (unspec:SI [(reg:CCRAW CC_REGNUM)] UNSPEC_CC_TO_INT))
11069 (set (pc)
11070 (if_then_else (match_op_dup 0 [(reg:CCRAW CC_REGNUM) (match_dup 1)])
11071 (label_ref (match_dup 2))
11072 (pc)))]
11073 "")
11074
11075 ; Non-constrained transaction begin
11076
11077 (define_expand "tbegin"
11078 [(match_operand:SI 0 "register_operand" "")
11079 (match_operand:BLK 1 "memory_operand" "")]
11080 "TARGET_HTM"
11081 {
11082 s390_expand_tbegin (operands[0], operands[1], NULL_RTX, true);
11083 DONE;
11084 })
11085
11086 (define_expand "tbegin_nofloat"
11087 [(match_operand:SI 0 "register_operand" "")
11088 (match_operand:BLK 1 "memory_operand" "")]
11089 "TARGET_HTM"
11090 {
11091 s390_expand_tbegin (operands[0], operands[1], NULL_RTX, false);
11092 DONE;
11093 })
11094
11095 (define_expand "tbegin_retry"
11096 [(match_operand:SI 0 "register_operand" "")
11097 (match_operand:BLK 1 "memory_operand" "")
11098 (match_operand:SI 2 "general_operand" "")]
11099 "TARGET_HTM"
11100 {
11101 s390_expand_tbegin (operands[0], operands[1], operands[2], true);
11102 DONE;
11103 })
11104
11105 (define_expand "tbegin_retry_nofloat"
11106 [(match_operand:SI 0 "register_operand" "")
11107 (match_operand:BLK 1 "memory_operand" "")
11108 (match_operand:SI 2 "general_operand" "")]
11109 "TARGET_HTM"
11110 {
11111 s390_expand_tbegin (operands[0], operands[1], operands[2], false);
11112 DONE;
11113 })
11114
11115 ; Clobber VRs since they don't get restored
11116 (define_insn "tbegin_1_z13"
11117 [(set (reg:CCRAW CC_REGNUM)
11118 (unspec_volatile:CCRAW [(match_operand 0 "const_int_operand" "D")]
11119 UNSPECV_TBEGIN))
11120 (set (match_operand:BLK 1 "memory_operand" "=Q")
11121 (unspec_volatile:BLK [(match_dup 0)] UNSPECV_TBEGIN_TDB))
11122 (clobber (reg:TI 16)) (clobber (reg:TI 38))
11123 (clobber (reg:TI 17)) (clobber (reg:TI 39))
11124 (clobber (reg:TI 18)) (clobber (reg:TI 40))
11125 (clobber (reg:TI 19)) (clobber (reg:TI 41))
11126 (clobber (reg:TI 20)) (clobber (reg:TI 42))
11127 (clobber (reg:TI 21)) (clobber (reg:TI 43))
11128 (clobber (reg:TI 22)) (clobber (reg:TI 44))
11129 (clobber (reg:TI 23)) (clobber (reg:TI 45))
11130 (clobber (reg:TI 24)) (clobber (reg:TI 46))
11131 (clobber (reg:TI 25)) (clobber (reg:TI 47))
11132 (clobber (reg:TI 26)) (clobber (reg:TI 48))
11133 (clobber (reg:TI 27)) (clobber (reg:TI 49))
11134 (clobber (reg:TI 28)) (clobber (reg:TI 50))
11135 (clobber (reg:TI 29)) (clobber (reg:TI 51))
11136 (clobber (reg:TI 30)) (clobber (reg:TI 52))
11137 (clobber (reg:TI 31)) (clobber (reg:TI 53))]
11138 ; CONST_OK_FOR_CONSTRAINT_P does not work with D constraint since D is
11139 ; not supposed to be used for immediates (see genpreds.c).
11140 "TARGET_VX && INTVAL (operands[0]) >= 0 && INTVAL (operands[0]) <= 0xffff"
11141 "tbegin\t%1,%x0"
11142 [(set_attr "op_type" "SIL")])
11143
11144 (define_insn "tbegin_1"
11145 [(set (reg:CCRAW CC_REGNUM)
11146 (unspec_volatile:CCRAW [(match_operand 0 "const_int_operand" "D")]
11147 UNSPECV_TBEGIN))
11148 (set (match_operand:BLK 1 "memory_operand" "=Q")
11149 (unspec_volatile:BLK [(match_dup 0)] UNSPECV_TBEGIN_TDB))
11150 (clobber (reg:DF 16))
11151 (clobber (reg:DF 17))
11152 (clobber (reg:DF 18))
11153 (clobber (reg:DF 19))
11154 (clobber (reg:DF 20))
11155 (clobber (reg:DF 21))
11156 (clobber (reg:DF 22))
11157 (clobber (reg:DF 23))
11158 (clobber (reg:DF 24))
11159 (clobber (reg:DF 25))
11160 (clobber (reg:DF 26))
11161 (clobber (reg:DF 27))
11162 (clobber (reg:DF 28))
11163 (clobber (reg:DF 29))
11164 (clobber (reg:DF 30))
11165 (clobber (reg:DF 31))]
11166 ; CONST_OK_FOR_CONSTRAINT_P does not work with D constraint since D is
11167 ; not supposed to be used for immediates (see genpreds.c).
11168 "TARGET_HTM && INTVAL (operands[0]) >= 0 && INTVAL (operands[0]) <= 0xffff"
11169 "tbegin\t%1,%x0"
11170 [(set_attr "op_type" "SIL")])
11171
11172 ; Same as above but without the FPR clobbers
11173 (define_insn "tbegin_nofloat_1"
11174 [(set (reg:CCRAW CC_REGNUM)
11175 (unspec_volatile:CCRAW [(match_operand 0 "const_int_operand" "D")]
11176 UNSPECV_TBEGIN))
11177 (set (match_operand:BLK 1 "memory_operand" "=Q")
11178 (unspec_volatile:BLK [(match_dup 0)] UNSPECV_TBEGIN_TDB))]
11179 "TARGET_HTM && INTVAL (operands[0]) >= 0 && INTVAL (operands[0]) <= 0xffff"
11180 "tbegin\t%1,%x0"
11181 [(set_attr "op_type" "SIL")])
11182
11183
11184 ; Constrained transaction begin
11185
11186 (define_expand "tbeginc"
11187 [(set (reg:CCRAW CC_REGNUM)
11188 (unspec_volatile:CCRAW [(const_int TBEGINC_MASK)]
11189 UNSPECV_TBEGINC))]
11190 "TARGET_HTM"
11191 "")
11192
11193 (define_insn "*tbeginc_1"
11194 [(set (reg:CCRAW CC_REGNUM)
11195 (unspec_volatile:CCRAW [(match_operand 0 "const_int_operand" " D")]
11196 UNSPECV_TBEGINC))]
11197 "TARGET_HTM && INTVAL (operands[0]) >= 0 && INTVAL (operands[0]) <= 0xffff"
11198 "tbeginc\t0,%x0"
11199 [(set_attr "op_type" "SIL")])
11200
11201 ; Transaction end
11202
11203 (define_expand "tend"
11204 [(set (reg:CCRAW CC_REGNUM)
11205 (unspec_volatile:CCRAW [(const_int 0)] UNSPECV_TEND))
11206 (set (match_operand:SI 0 "register_operand" "")
11207 (unspec:SI [(reg:CCRAW CC_REGNUM)] UNSPEC_CC_TO_INT))]
11208 "TARGET_HTM"
11209 "")
11210
11211 (define_insn "*tend_1"
11212 [(set (reg:CCRAW CC_REGNUM)
11213 (unspec_volatile:CCRAW [(const_int 0)] UNSPECV_TEND))]
11214 "TARGET_HTM"
11215 "tend"
11216 [(set_attr "op_type" "S")])
11217
11218 ; Transaction abort
11219
11220 (define_expand "tabort"
11221 [(unspec_volatile [(match_operand:SI 0 "nonmemory_operand" "")]
11222 UNSPECV_TABORT)]
11223 "TARGET_HTM && operands != NULL"
11224 {
11225 if (CONST_INT_P (operands[0])
11226 && INTVAL (operands[0]) >= 0 && INTVAL (operands[0]) <= 255)
11227 {
11228 error ("invalid transaction abort code: " HOST_WIDE_INT_PRINT_DEC
11229 ". Values in range 0 through 255 are reserved.",
11230 INTVAL (operands[0]));
11231 FAIL;
11232 }
11233 })
11234
11235 (define_insn "*tabort_1"
11236 [(unspec_volatile [(match_operand:SI 0 "nonmemory_operand" "aJ")]
11237 UNSPECV_TABORT)]
11238 "TARGET_HTM && operands != NULL"
11239 "tabort\t%Y0"
11240 [(set_attr "op_type" "S")])
11241
11242 (define_insn "*tabort_1_plus"
11243 [(unspec_volatile [(plus:SI (match_operand:SI 0 "register_operand" "a")
11244 (match_operand:SI 1 "const_int_operand" "J"))]
11245 UNSPECV_TABORT)]
11246 "TARGET_HTM && operands != NULL
11247 && CONST_OK_FOR_CONSTRAINT_P (INTVAL (operands[1]), 'J', \"J\")"
11248 "tabort\t%1(%0)"
11249 [(set_attr "op_type" "S")])
11250
11251 ; Transaction extract nesting depth
11252
11253 (define_insn "etnd"
11254 [(set (match_operand:SI 0 "register_operand" "=d")
11255 (unspec_volatile:SI [(const_int 0)] UNSPECV_ETND))]
11256 "TARGET_HTM"
11257 "etnd\t%0"
11258 [(set_attr "op_type" "RRE")])
11259
11260 ; Non-transactional store
11261
11262 (define_insn "ntstg"
11263 [(set (match_operand:DI 0 "memory_operand" "=T")
11264 (unspec_volatile:DI [(match_operand:DI 1 "register_operand" "d")]
11265 UNSPECV_NTSTG))]
11266 "TARGET_HTM"
11267 "ntstg\t%1,%0"
11268 [(set_attr "op_type" "RXY")])
11269
11270 ; Transaction perform processor assist
11271
11272 (define_expand "tx_assist"
11273 [(unspec_volatile [(match_operand:SI 0 "register_operand" "")
11274 (reg:SI GPR0_REGNUM)
11275 (const_int 1)]
11276 UNSPECV_PPA)]
11277 "TARGET_HTM"
11278 "")
11279
11280 (define_insn "*ppa"
11281 [(unspec_volatile [(match_operand:SI 0 "register_operand" "d")
11282 (match_operand:SI 1 "register_operand" "d")
11283 (match_operand 2 "const_int_operand" "I")]
11284 UNSPECV_PPA)]
11285 "TARGET_HTM && INTVAL (operands[2]) < 16"
11286 "ppa\t%0,%1,%2"
11287 [(set_attr "op_type" "RRF")])
11288
11289
11290 ; Set and get floating point control register
11291
11292 (define_insn "sfpc"
11293 [(unspec_volatile [(match_operand:SI 0 "register_operand" "d")]
11294 UNSPECV_SFPC)]
11295 "TARGET_HARD_FLOAT"
11296 "sfpc\t%0")
11297
11298 (define_insn "efpc"
11299 [(set (match_operand:SI 0 "register_operand" "=d")
11300 (unspec_volatile:SI [(const_int 0)] UNSPECV_EFPC))]
11301 "TARGET_HARD_FLOAT"
11302 "efpc\t%0")
11303
11304
11305 ; Load count to block boundary
11306
11307 (define_insn "lcbb"
11308 [(set (match_operand:SI 0 "register_operand" "=d")
11309 (unspec:SI [(match_operand 1 "address_operand" "ZR")
11310 (match_operand:SI 2 "immediate_operand" "C")] UNSPEC_LCBB))
11311 (clobber (reg:CC CC_REGNUM))]
11312 "TARGET_Z13"
11313 "lcbb\t%0,%a1,%b2"
11314 [(set_attr "op_type" "VRX")])
11315
11316 ; Handle -fsplit-stack.
11317
11318 (define_expand "split_stack_prologue"
11319 [(const_int 0)]
11320 ""
11321 {
11322 s390_expand_split_stack_prologue ();
11323 DONE;
11324 })
11325
11326 ;; If there are operand 0 bytes available on the stack, jump to
11327 ;; operand 1.
11328
11329 (define_expand "split_stack_space_check"
11330 [(set (pc) (if_then_else
11331 (ltu (minus (reg 15)
11332 (match_operand 0 "register_operand"))
11333 (unspec [(const_int 0)] UNSPEC_STACK_CHECK))
11334 (label_ref (match_operand 1))
11335 (pc)))]
11336 ""
11337 {
11338 /* Offset from thread pointer to __private_ss. */
11339 int psso = TARGET_64BIT ? 0x38 : 0x20;
11340 rtx tp = s390_get_thread_pointer ();
11341 rtx guard = gen_rtx_MEM (Pmode, plus_constant (Pmode, tp, psso));
11342 rtx reg = gen_reg_rtx (Pmode);
11343 rtx cc;
11344 if (TARGET_64BIT)
11345 emit_insn (gen_subdi3 (reg, stack_pointer_rtx, operands[0]));
11346 else
11347 emit_insn (gen_subsi3 (reg, stack_pointer_rtx, operands[0]));
11348 cc = s390_emit_compare (GT, reg, guard);
11349 s390_emit_jump (operands[1], cc);
11350
11351 DONE;
11352 })
11353
11354 ;; __morestack parameter block for split stack prologue. Parameters are:
11355 ;; parameter block label, label to be called by __morestack, frame size,
11356 ;; stack parameter size.
11357
11358 (define_insn "split_stack_data"
11359 [(unspec_volatile [(match_operand 0 "" "X")
11360 (match_operand 1 "" "X")
11361 (match_operand 2 "const_int_operand" "X")
11362 (match_operand 3 "const_int_operand" "X")]
11363 UNSPECV_SPLIT_STACK_DATA)]
11364 "TARGET_CPU_ZARCH"
11365 {
11366 switch_to_section (targetm.asm_out.function_rodata_section
11367 (current_function_decl));
11368
11369 if (TARGET_64BIT)
11370 output_asm_insn (".align\t8", operands);
11371 else
11372 output_asm_insn (".align\t4", operands);
11373 (*targetm.asm_out.internal_label) (asm_out_file, "L",
11374 CODE_LABEL_NUMBER (operands[0]));
11375 if (TARGET_64BIT)
11376 {
11377 output_asm_insn (".quad\t%2", operands);
11378 output_asm_insn (".quad\t%3", operands);
11379 output_asm_insn (".quad\t%1-%0", operands);
11380 }
11381 else
11382 {
11383 output_asm_insn (".long\t%2", operands);
11384 output_asm_insn (".long\t%3", operands);
11385 output_asm_insn (".long\t%1-%0", operands);
11386 }
11387
11388 switch_to_section (current_function_section ());
11389 return "";
11390 }
11391 [(set_attr "length" "0")])
11392
11393
11394 ;; A jg with minimal fuss for use in split stack prologue.
11395
11396 (define_expand "split_stack_call"
11397 [(match_operand 0 "bras_sym_operand" "X")
11398 (match_operand 1 "" "")]
11399 "TARGET_CPU_ZARCH"
11400 {
11401 if (TARGET_64BIT)
11402 emit_jump_insn (gen_split_stack_call_di (operands[0], operands[1]));
11403 else
11404 emit_jump_insn (gen_split_stack_call_si (operands[0], operands[1]));
11405 DONE;
11406 })
11407
11408 (define_insn "split_stack_call_<mode>"
11409 [(set (pc) (label_ref (match_operand 1 "" "")))
11410 (set (reg:P 1) (unspec_volatile [(match_operand 0 "bras_sym_operand" "X")
11411 (reg:P 1)]
11412 UNSPECV_SPLIT_STACK_CALL))]
11413 "TARGET_CPU_ZARCH"
11414 "jg\t%0"
11415 [(set_attr "op_type" "RIL")
11416 (set_attr "type" "branch")])
11417
11418 ;; Also a conditional one.
11419
11420 (define_expand "split_stack_cond_call"
11421 [(match_operand 0 "bras_sym_operand" "X")
11422 (match_operand 1 "" "")
11423 (match_operand 2 "" "")]
11424 "TARGET_CPU_ZARCH"
11425 {
11426 if (TARGET_64BIT)
11427 emit_jump_insn (gen_split_stack_cond_call_di (operands[0], operands[1], operands[2]));
11428 else
11429 emit_jump_insn (gen_split_stack_cond_call_si (operands[0], operands[1], operands[2]));
11430 DONE;
11431 })
11432
11433 (define_insn "split_stack_cond_call_<mode>"
11434 [(set (pc)
11435 (if_then_else
11436 (match_operand 1 "" "")
11437 (label_ref (match_operand 2 "" ""))
11438 (pc)))
11439 (set (reg:P 1) (unspec_volatile [(match_operand 0 "bras_sym_operand" "X")
11440 (reg:P 1)]
11441 UNSPECV_SPLIT_STACK_CALL))]
11442 "TARGET_CPU_ZARCH"
11443 "jg%C1\t%0"
11444 [(set_attr "op_type" "RIL")
11445 (set_attr "type" "branch")])
11446
11447 (define_insn "osc_break"
11448 [(unspec_volatile [(const_int 0)] UNSPECV_OSC_BREAK)]
11449 ""
11450 "bcr\t7,%%r0"
11451 [(set_attr "op_type" "RR")])