S/390: Fix PR81534
[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 "*mov<mode>cc"
6604 [(set (match_operand:GPR 0 "nonimmediate_operand" "=d,d,d,d,d,d,S,S")
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")
6608 (match_operand 5 "const_int_operand" "")])
6609 (match_operand:GPR 3 "loc_operand" " d,0,S,0,K,0,d,0")
6610 (match_operand:GPR 4 "loc_operand" " 0,d,0,S,0,K,0,d")))]
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 [(set_attr "op_type" "RRF,RRF,RSY,RSY,RIE,RIE,RSY,RSY")
6622 (set_attr "cpu_facility" "*,*,*,*,z13,z13,*,*")])
6623
6624 ;;
6625 ;;- Multiply instructions.
6626 ;;
6627
6628 ;
6629 ; muldi3 instruction pattern(s).
6630 ;
6631
6632 (define_expand "muldi3"
6633 [(parallel
6634 [(set (match_operand:DI 0 "register_operand")
6635 (mult:DI (match_operand:DI 1 "nonimmediate_operand")
6636 (match_operand:DI 2 "general_operand")))
6637 (clobber (reg:CC CC_REGNUM))])]
6638 "TARGET_ZARCH")
6639
6640 (define_insn "*muldi3_sign"
6641 [(set (match_operand:DI 0 "register_operand" "=d,d")
6642 (mult:DI (sign_extend:DI (match_operand:SI 2 "general_operand" "d,T"))
6643 (match_operand:DI 1 "register_operand" "0,0")))]
6644 "TARGET_ZARCH"
6645 "@
6646 msgfr\t%0,%2
6647 msgf\t%0,%2"
6648 [(set_attr "op_type" "RRE,RXY")
6649 (set_attr "type" "imuldi")])
6650
6651 (define_insn "*muldi3"
6652 [(set (match_operand:DI 0 "register_operand" "=d,d,d,d,d")
6653 (mult:DI (match_operand:DI 1 "nonimmediate_operand" "%0,d,0,0,0")
6654 (match_operand:DI 2 "general_operand" "d,d,K,T,Os")))
6655 (clobber (match_scratch:CC 3 "=X,c,X,X,X"))]
6656 "TARGET_ZARCH"
6657 "@
6658 msgr\t%0,%2
6659 msgrkc\t%0,%1,%2
6660 mghi\t%0,%h2
6661 msg\t%0,%2
6662 msgfi\t%0,%2"
6663 [(set_attr "op_type" "RRE,RRF,RI,RXY,RIL")
6664 (set_attr "type" "imuldi")
6665 (set_attr "cpu_facility" "*,arch12,*,*,z10")])
6666
6667 (define_insn "mulditi3"
6668 [(set (match_operand:TI 0 "register_operand" "=d,d")
6669 (mult:TI (sign_extend:TI
6670 (match_operand:DI 1 "register_operand" "%d,0"))
6671 (sign_extend:TI
6672 (match_operand:DI 2 "nonimmediate_operand" " d,T"))))]
6673 "TARGET_ARCH12"
6674 "@
6675 mgrk\t%0,%1,%2
6676 mg\t%0,%2"
6677 [(set_attr "op_type" "RRF,RXY")])
6678
6679 ; Combine likes op1 and op2 to be swapped sometimes.
6680 (define_insn "mulditi3_2"
6681 [(set (match_operand:TI 0 "register_operand" "=d,d")
6682 (mult:TI (sign_extend:TI
6683 (match_operand:DI 1 "nonimmediate_operand" "%d,T"))
6684 (sign_extend:TI
6685 (match_operand:DI 2 "register_operand" " d,0"))))]
6686 "TARGET_ARCH12"
6687 "@
6688 mgrk\t%0,%1,%2
6689 mg\t%0,%1"
6690 [(set_attr "op_type" "RRF,RXY")])
6691
6692 (define_insn "*muldi3_sign"
6693 [(set (match_operand:DI 0 "register_operand" "=d")
6694 (mult:DI (sign_extend:DI (match_operand:HI 2 "memory_operand" "T"))
6695 (match_operand:DI 1 "register_operand" "0")))]
6696 "TARGET_ARCH12"
6697 "mgh\t%0,%2"
6698 [(set_attr "op_type" "RXY")])
6699
6700
6701 ;
6702 ; mulsi3 instruction pattern(s).
6703 ;
6704
6705 (define_expand "mulsi3"
6706 [(parallel
6707 [(set (match_operand:SI 0 "register_operand" "=d,d,d,d,d,d")
6708 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%0,d,0,0,0,0")
6709 (match_operand:SI 2 "general_operand" "d,d,K,R,T,Os")))
6710 (clobber (reg:CC CC_REGNUM))])]
6711 "")
6712
6713 (define_insn "*mulsi3_sign"
6714 [(set (match_operand:SI 0 "register_operand" "=d,d")
6715 (mult:SI (sign_extend:SI (match_operand:HI 2 "memory_operand" "R,T"))
6716 (match_operand:SI 1 "register_operand" "0,0")))]
6717 ""
6718 "@
6719 mh\t%0,%2
6720 mhy\t%0,%2"
6721 [(set_attr "op_type" "RX,RXY")
6722 (set_attr "type" "imulhi")
6723 (set_attr "cpu_facility" "*,z10")])
6724
6725 (define_insn "*mulsi3"
6726 [(set (match_operand:SI 0 "register_operand" "=d,d,d,d,d,d")
6727 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%0,d,0,0,0,0")
6728 (match_operand:SI 2 "general_operand" "d,d,K,R,T,Os")))
6729 (clobber (match_scratch:CC 3 "=X,c,X,X,X,X"))]
6730 ""
6731 "@
6732 msr\t%0,%2
6733 msrkc\t%0,%1,%2
6734 mhi\t%0,%h2
6735 ms\t%0,%2
6736 msy\t%0,%2
6737 msfi\t%0,%2"
6738 [(set_attr "op_type" "RRE,RRF,RI,RX,RXY,RIL")
6739 (set_attr "type" "imulsi,*,imulhi,imulsi,imulsi,imulsi")
6740 (set_attr "cpu_facility" "*,arch12,*,*,longdisp,z10")])
6741
6742 ;
6743 ; mulsidi3 instruction pattern(s).
6744 ;
6745
6746 (define_insn "mulsidi3"
6747 [(set (match_operand:DI 0 "register_operand" "=d,d,d")
6748 (mult:DI (sign_extend:DI
6749 (match_operand:SI 1 "register_operand" "%0,0,0"))
6750 (sign_extend:DI
6751 (match_operand:SI 2 "nonimmediate_operand" "d,R,T"))))]
6752 "!TARGET_ZARCH"
6753 "@
6754 mr\t%0,%2
6755 m\t%0,%2
6756 mfy\t%0,%2"
6757 [(set_attr "op_type" "RR,RX,RXY")
6758 (set_attr "type" "imulsi")
6759 (set_attr "cpu_facility" "*,*,z10")])
6760
6761 ;
6762 ; umul instruction pattern(s).
6763 ;
6764
6765 ; mlr, ml, mlgr, mlg
6766 (define_insn "umul<dwh><mode>3"
6767 [(set (match_operand:DW 0 "register_operand" "=d,d")
6768 (mult:DW (zero_extend:DW
6769 (match_operand:<DWH> 1 "register_operand" "%0,0"))
6770 (zero_extend:DW
6771 (match_operand:<DWH> 2 "nonimmediate_operand" " d,T"))))]
6772 "TARGET_CPU_ZARCH"
6773 "@
6774 ml<tg>r\t%0,%2
6775 ml<tg>\t%0,%2"
6776 [(set_attr "op_type" "RRE,RXY")
6777 (set_attr "type" "imul<dwh>")])
6778
6779 ;
6780 ; mul(tf|df|sf|td|dd)3 instruction pattern(s).
6781 ;
6782
6783 ; mxbr, mdbr, meebr, mxb, mxb, meeb, mdtr, mxtr
6784 (define_insn "mul<mode>3"
6785 [(set (match_operand:FP 0 "register_operand" "=f,f,f,v,v")
6786 (mult:FP (match_operand:FP 1 "nonimmediate_operand" "%f,0,0,v,v")
6787 (match_operand:FP 2 "general_operand" "f,f,R,v,v")))]
6788 "TARGET_HARD_FLOAT"
6789 "@
6790 m<xdee>tr\t%0,%1,%2
6791 m<xdee>br\t%0,%2
6792 m<xdee>b\t%0,%2
6793 wfmdb\t%v0,%v1,%v2
6794 wfmsb\t%v0,%v1,%v2"
6795 [(set_attr "op_type" "RRF,RRE,RXE,VRR,VRR")
6796 (set_attr "type" "fmul<mode>")
6797 (set_attr "cpu_facility" "*,*,*,vx,vxe")
6798 (set_attr "enabled" "<nBFP>,<nDFP>,<DSF>,<DF>,<SF>")])
6799
6800 ; madbr, maebr, maxb, madb, maeb
6801 (define_insn "fma<mode>4"
6802 [(set (match_operand:DSF 0 "register_operand" "=f,f,v,v")
6803 (fma:DSF (match_operand:DSF 1 "nonimmediate_operand" "%f,f,v,v")
6804 (match_operand:DSF 2 "nonimmediate_operand" "f,R,v,v")
6805 (match_operand:DSF 3 "register_operand" "0,0,v,v")))]
6806 "TARGET_HARD_FLOAT"
6807 "@
6808 ma<xde>br\t%0,%1,%2
6809 ma<xde>b\t%0,%1,%2
6810 wfmadb\t%v0,%v1,%v2,%v3
6811 wfmasb\t%v0,%v1,%v2,%v3"
6812 [(set_attr "op_type" "RRE,RXE,VRR,VRR")
6813 (set_attr "type" "fmadd<mode>")
6814 (set_attr "cpu_facility" "*,*,vx,vxe")
6815 (set_attr "enabled" "*,*,<DF>,<SF>")])
6816
6817 ; msxbr, msdbr, msebr, msxb, msdb, mseb
6818 (define_insn "fms<mode>4"
6819 [(set (match_operand:DSF 0 "register_operand" "=f,f,v,v")
6820 (fma:DSF (match_operand:DSF 1 "nonimmediate_operand" "%f,f,v,v")
6821 (match_operand:DSF 2 "nonimmediate_operand" "f,R,v,v")
6822 (neg:DSF (match_operand:DSF 3 "register_operand" "0,0,v,v"))))]
6823 "TARGET_HARD_FLOAT"
6824 "@
6825 ms<xde>br\t%0,%1,%2
6826 ms<xde>b\t%0,%1,%2
6827 wfmsdb\t%v0,%v1,%v2,%v3
6828 wfmssb\t%v0,%v1,%v2,%v3"
6829 [(set_attr "op_type" "RRE,RXE,VRR,VRR")
6830 (set_attr "type" "fmadd<mode>")
6831 (set_attr "cpu_facility" "*,*,vx,vxe")
6832 (set_attr "enabled" "*,*,<DF>,<SF>")])
6833
6834 ;;
6835 ;;- Divide and modulo instructions.
6836 ;;
6837
6838 ;
6839 ; divmoddi4 instruction pattern(s).
6840 ;
6841
6842 (define_expand "divmoddi4"
6843 [(parallel [(set (match_operand:DI 0 "general_operand" "")
6844 (div:DI (match_operand:DI 1 "register_operand" "")
6845 (match_operand:DI 2 "general_operand" "")))
6846 (set (match_operand:DI 3 "general_operand" "")
6847 (mod:DI (match_dup 1) (match_dup 2)))])
6848 (clobber (match_dup 4))]
6849 "TARGET_ZARCH"
6850 {
6851 rtx div_equal, mod_equal;
6852 rtx_insn *insn;
6853
6854 div_equal = gen_rtx_DIV (DImode, operands[1], operands[2]);
6855 mod_equal = gen_rtx_MOD (DImode, operands[1], operands[2]);
6856
6857 operands[4] = gen_reg_rtx(TImode);
6858 emit_insn (gen_divmodtidi3 (operands[4], operands[1], operands[2]));
6859
6860 insn = emit_move_insn (operands[0], gen_lowpart (DImode, operands[4]));
6861 set_unique_reg_note (insn, REG_EQUAL, div_equal);
6862
6863 insn = emit_move_insn (operands[3], gen_highpart (DImode, operands[4]));
6864 set_unique_reg_note (insn, REG_EQUAL, mod_equal);
6865
6866 DONE;
6867 })
6868
6869 (define_insn "divmodtidi3"
6870 [(set (match_operand:TI 0 "register_operand" "=d,d")
6871 (ior:TI
6872 (ashift:TI
6873 (zero_extend:TI
6874 (mod:DI (match_operand:DI 1 "register_operand" "0,0")
6875 (match_operand:DI 2 "general_operand" "d,T")))
6876 (const_int 64))
6877 (zero_extend:TI (div:DI (match_dup 1) (match_dup 2)))))]
6878 "TARGET_ZARCH"
6879 "@
6880 dsgr\t%0,%2
6881 dsg\t%0,%2"
6882 [(set_attr "op_type" "RRE,RXY")
6883 (set_attr "type" "idiv")])
6884
6885 (define_insn "divmodtisi3"
6886 [(set (match_operand:TI 0 "register_operand" "=d,d")
6887 (ior:TI
6888 (ashift:TI
6889 (zero_extend:TI
6890 (mod:DI (match_operand:DI 1 "register_operand" "0,0")
6891 (sign_extend:DI
6892 (match_operand:SI 2 "nonimmediate_operand" "d,T"))))
6893 (const_int 64))
6894 (zero_extend:TI
6895 (div:DI (match_dup 1) (sign_extend:DI (match_dup 2))))))]
6896 "TARGET_ZARCH"
6897 "@
6898 dsgfr\t%0,%2
6899 dsgf\t%0,%2"
6900 [(set_attr "op_type" "RRE,RXY")
6901 (set_attr "type" "idiv")])
6902
6903 ;
6904 ; udivmoddi4 instruction pattern(s).
6905 ;
6906
6907 (define_expand "udivmoddi4"
6908 [(parallel [(set (match_operand:DI 0 "general_operand" "")
6909 (udiv:DI (match_operand:DI 1 "general_operand" "")
6910 (match_operand:DI 2 "nonimmediate_operand" "")))
6911 (set (match_operand:DI 3 "general_operand" "")
6912 (umod:DI (match_dup 1) (match_dup 2)))])
6913 (clobber (match_dup 4))]
6914 "TARGET_ZARCH"
6915 {
6916 rtx div_equal, mod_equal, equal;
6917 rtx_insn *insn;
6918
6919 div_equal = gen_rtx_UDIV (DImode, operands[1], operands[2]);
6920 mod_equal = gen_rtx_UMOD (DImode, operands[1], operands[2]);
6921 equal = gen_rtx_IOR (TImode,
6922 gen_rtx_ASHIFT (TImode,
6923 gen_rtx_ZERO_EXTEND (TImode, mod_equal),
6924 GEN_INT (64)),
6925 gen_rtx_ZERO_EXTEND (TImode, div_equal));
6926
6927 operands[4] = gen_reg_rtx(TImode);
6928 emit_clobber (operands[4]);
6929 emit_move_insn (gen_lowpart (DImode, operands[4]), operands[1]);
6930 emit_move_insn (gen_highpart (DImode, operands[4]), const0_rtx);
6931
6932 insn = emit_insn (gen_udivmodtidi3 (operands[4], operands[4], operands[2]));
6933 set_unique_reg_note (insn, REG_EQUAL, equal);
6934
6935 insn = emit_move_insn (operands[0], gen_lowpart (DImode, operands[4]));
6936 set_unique_reg_note (insn, REG_EQUAL, div_equal);
6937
6938 insn = emit_move_insn (operands[3], gen_highpart (DImode, operands[4]));
6939 set_unique_reg_note (insn, REG_EQUAL, mod_equal);
6940
6941 DONE;
6942 })
6943
6944 (define_insn "udivmodtidi3"
6945 [(set (match_operand:TI 0 "register_operand" "=d,d")
6946 (ior:TI
6947 (ashift:TI
6948 (zero_extend:TI
6949 (truncate:DI
6950 (umod:TI (match_operand:TI 1 "register_operand" "0,0")
6951 (zero_extend:TI
6952 (match_operand:DI 2 "nonimmediate_operand" "d,T")))))
6953 (const_int 64))
6954 (zero_extend:TI
6955 (truncate:DI
6956 (udiv:TI (match_dup 1) (zero_extend:TI (match_dup 2)))))))]
6957 "TARGET_ZARCH"
6958 "@
6959 dlgr\t%0,%2
6960 dlg\t%0,%2"
6961 [(set_attr "op_type" "RRE,RXY")
6962 (set_attr "type" "idiv")])
6963
6964 ;
6965 ; divmodsi4 instruction pattern(s).
6966 ;
6967
6968 (define_expand "divmodsi4"
6969 [(parallel [(set (match_operand:SI 0 "general_operand" "")
6970 (div:SI (match_operand:SI 1 "general_operand" "")
6971 (match_operand:SI 2 "nonimmediate_operand" "")))
6972 (set (match_operand:SI 3 "general_operand" "")
6973 (mod:SI (match_dup 1) (match_dup 2)))])
6974 (clobber (match_dup 4))]
6975 "!TARGET_ZARCH"
6976 {
6977 rtx div_equal, mod_equal, equal;
6978 rtx_insn *insn;
6979
6980 div_equal = gen_rtx_DIV (SImode, operands[1], operands[2]);
6981 mod_equal = gen_rtx_MOD (SImode, operands[1], operands[2]);
6982 equal = gen_rtx_IOR (DImode,
6983 gen_rtx_ASHIFT (DImode,
6984 gen_rtx_ZERO_EXTEND (DImode, mod_equal),
6985 GEN_INT (32)),
6986 gen_rtx_ZERO_EXTEND (DImode, div_equal));
6987
6988 operands[4] = gen_reg_rtx(DImode);
6989 emit_insn (gen_extendsidi2 (operands[4], operands[1]));
6990
6991 insn = emit_insn (gen_divmoddisi3 (operands[4], operands[4], operands[2]));
6992 set_unique_reg_note (insn, REG_EQUAL, equal);
6993
6994 insn = emit_move_insn (operands[0], gen_lowpart (SImode, operands[4]));
6995 set_unique_reg_note (insn, REG_EQUAL, div_equal);
6996
6997 insn = emit_move_insn (operands[3], gen_highpart (SImode, operands[4]));
6998 set_unique_reg_note (insn, REG_EQUAL, mod_equal);
6999
7000 DONE;
7001 })
7002
7003 (define_insn "divmoddisi3"
7004 [(set (match_operand:DI 0 "register_operand" "=d,d")
7005 (ior:DI
7006 (ashift:DI
7007 (zero_extend:DI
7008 (truncate:SI
7009 (mod:DI (match_operand:DI 1 "register_operand" "0,0")
7010 (sign_extend:DI
7011 (match_operand:SI 2 "nonimmediate_operand" "d,R")))))
7012 (const_int 32))
7013 (zero_extend:DI
7014 (truncate:SI
7015 (div:DI (match_dup 1) (sign_extend:DI (match_dup 2)))))))]
7016 "!TARGET_ZARCH"
7017 "@
7018 dr\t%0,%2
7019 d\t%0,%2"
7020 [(set_attr "op_type" "RR,RX")
7021 (set_attr "type" "idiv")])
7022
7023 ;
7024 ; udivsi3 and umodsi3 instruction pattern(s).
7025 ;
7026
7027 (define_expand "udivmodsi4"
7028 [(parallel [(set (match_operand:SI 0 "general_operand" "")
7029 (udiv:SI (match_operand:SI 1 "general_operand" "")
7030 (match_operand:SI 2 "nonimmediate_operand" "")))
7031 (set (match_operand:SI 3 "general_operand" "")
7032 (umod:SI (match_dup 1) (match_dup 2)))])
7033 (clobber (match_dup 4))]
7034 "!TARGET_ZARCH && TARGET_CPU_ZARCH"
7035 {
7036 rtx div_equal, mod_equal, equal;
7037 rtx_insn *insn;
7038
7039 div_equal = gen_rtx_UDIV (SImode, operands[1], operands[2]);
7040 mod_equal = gen_rtx_UMOD (SImode, operands[1], operands[2]);
7041 equal = gen_rtx_IOR (DImode,
7042 gen_rtx_ASHIFT (DImode,
7043 gen_rtx_ZERO_EXTEND (DImode, mod_equal),
7044 GEN_INT (32)),
7045 gen_rtx_ZERO_EXTEND (DImode, div_equal));
7046
7047 operands[4] = gen_reg_rtx(DImode);
7048 emit_clobber (operands[4]);
7049 emit_move_insn (gen_lowpart (SImode, operands[4]), operands[1]);
7050 emit_move_insn (gen_highpart (SImode, operands[4]), const0_rtx);
7051
7052 insn = emit_insn (gen_udivmoddisi3 (operands[4], operands[4], operands[2]));
7053 set_unique_reg_note (insn, REG_EQUAL, equal);
7054
7055 insn = emit_move_insn (operands[0], gen_lowpart (SImode, operands[4]));
7056 set_unique_reg_note (insn, REG_EQUAL, div_equal);
7057
7058 insn = emit_move_insn (operands[3], gen_highpart (SImode, operands[4]));
7059 set_unique_reg_note (insn, REG_EQUAL, mod_equal);
7060
7061 DONE;
7062 })
7063
7064 (define_insn "udivmoddisi3"
7065 [(set (match_operand:DI 0 "register_operand" "=d,d")
7066 (ior:DI
7067 (ashift:DI
7068 (zero_extend:DI
7069 (truncate:SI
7070 (umod:DI (match_operand:DI 1 "register_operand" "0,0")
7071 (zero_extend:DI
7072 (match_operand:SI 2 "nonimmediate_operand" "d,T")))))
7073 (const_int 32))
7074 (zero_extend:DI
7075 (truncate:SI
7076 (udiv:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))))]
7077 "!TARGET_ZARCH && TARGET_CPU_ZARCH"
7078 "@
7079 dlr\t%0,%2
7080 dl\t%0,%2"
7081 [(set_attr "op_type" "RRE,RXY")
7082 (set_attr "type" "idiv")])
7083
7084 (define_expand "udivsi3"
7085 [(set (match_operand:SI 0 "register_operand" "=d")
7086 (udiv:SI (match_operand:SI 1 "general_operand" "")
7087 (match_operand:SI 2 "general_operand" "")))
7088 (clobber (match_dup 3))]
7089 "!TARGET_ZARCH && !TARGET_CPU_ZARCH"
7090 {
7091 rtx udiv_equal, umod_equal, equal;
7092 rtx_insn *insn;
7093
7094 udiv_equal = gen_rtx_UDIV (SImode, operands[1], operands[2]);
7095 umod_equal = gen_rtx_UMOD (SImode, operands[1], operands[2]);
7096 equal = gen_rtx_IOR (DImode,
7097 gen_rtx_ASHIFT (DImode,
7098 gen_rtx_ZERO_EXTEND (DImode, umod_equal),
7099 GEN_INT (32)),
7100 gen_rtx_ZERO_EXTEND (DImode, udiv_equal));
7101
7102 operands[3] = gen_reg_rtx (DImode);
7103
7104 if (CONSTANT_P (operands[2]))
7105 {
7106 if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0)
7107 {
7108 rtx_code_label *label1 = gen_label_rtx ();
7109
7110 operands[1] = make_safe_from (operands[1], operands[0]);
7111 emit_move_insn (operands[0], const0_rtx);
7112 emit_cmp_and_jump_insns (operands[1], operands[2], LT, NULL_RTX,
7113 SImode, 1, label1);
7114 emit_move_insn (operands[0], const1_rtx);
7115 emit_label (label1);
7116 }
7117 else
7118 {
7119 operands[2] = force_reg (SImode, operands[2]);
7120 operands[2] = make_safe_from (operands[2], operands[0]);
7121
7122 emit_insn (gen_zero_extendsidi2 (operands[3], operands[1]));
7123 insn = emit_insn (gen_divmoddisi3 (operands[3], operands[3],
7124 operands[2]));
7125 set_unique_reg_note (insn, REG_EQUAL, equal);
7126
7127 insn = emit_move_insn (operands[0],
7128 gen_lowpart (SImode, operands[3]));
7129 set_unique_reg_note (insn, REG_EQUAL, udiv_equal);
7130 }
7131 }
7132 else
7133 {
7134 rtx_code_label *label1 = gen_label_rtx ();
7135 rtx_code_label *label2 = gen_label_rtx ();
7136 rtx_code_label *label3 = gen_label_rtx ();
7137
7138 operands[1] = force_reg (SImode, operands[1]);
7139 operands[1] = make_safe_from (operands[1], operands[0]);
7140 operands[2] = force_reg (SImode, operands[2]);
7141 operands[2] = make_safe_from (operands[2], operands[0]);
7142
7143 emit_move_insn (operands[0], const0_rtx);
7144 emit_cmp_and_jump_insns (operands[2], operands[1], GT, NULL_RTX,
7145 SImode, 1, label3);
7146 emit_cmp_and_jump_insns (operands[2], const0_rtx, LT, NULL_RTX,
7147 SImode, 0, label2);
7148 emit_cmp_and_jump_insns (operands[2], const1_rtx, EQ, NULL_RTX,
7149 SImode, 0, label1);
7150 emit_insn (gen_zero_extendsidi2 (operands[3], operands[1]));
7151 insn = emit_insn (gen_divmoddisi3 (operands[3], operands[3],
7152 operands[2]));
7153 set_unique_reg_note (insn, REG_EQUAL, equal);
7154
7155 insn = emit_move_insn (operands[0],
7156 gen_lowpart (SImode, operands[3]));
7157 set_unique_reg_note (insn, REG_EQUAL, udiv_equal);
7158
7159 emit_jump (label3);
7160 emit_label (label1);
7161 emit_move_insn (operands[0], operands[1]);
7162 emit_jump (label3);
7163 emit_label (label2);
7164 emit_move_insn (operands[0], const1_rtx);
7165 emit_label (label3);
7166 }
7167 emit_move_insn (operands[0], operands[0]);
7168 DONE;
7169 })
7170
7171 (define_expand "umodsi3"
7172 [(set (match_operand:SI 0 "register_operand" "=d")
7173 (umod:SI (match_operand:SI 1 "nonimmediate_operand" "")
7174 (match_operand:SI 2 "nonimmediate_operand" "")))
7175 (clobber (match_dup 3))]
7176 "!TARGET_ZARCH && !TARGET_CPU_ZARCH"
7177 {
7178 rtx udiv_equal, umod_equal, equal;
7179 rtx_insn *insn;
7180
7181 udiv_equal = gen_rtx_UDIV (SImode, operands[1], operands[2]);
7182 umod_equal = gen_rtx_UMOD (SImode, operands[1], operands[2]);
7183 equal = gen_rtx_IOR (DImode,
7184 gen_rtx_ASHIFT (DImode,
7185 gen_rtx_ZERO_EXTEND (DImode, umod_equal),
7186 GEN_INT (32)),
7187 gen_rtx_ZERO_EXTEND (DImode, udiv_equal));
7188
7189 operands[3] = gen_reg_rtx (DImode);
7190
7191 if (CONSTANT_P (operands[2]))
7192 {
7193 if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) <= 0)
7194 {
7195 rtx_code_label *label1 = gen_label_rtx ();
7196
7197 operands[1] = make_safe_from (operands[1], operands[0]);
7198 emit_move_insn (operands[0], operands[1]);
7199 emit_cmp_and_jump_insns (operands[0], operands[2], LT, NULL_RTX,
7200 SImode, 1, label1);
7201 emit_insn (gen_abssi2 (operands[0], operands[2]));
7202 emit_insn (gen_addsi3 (operands[0], operands[0], operands[1]));
7203 emit_label (label1);
7204 }
7205 else
7206 {
7207 operands[2] = force_reg (SImode, operands[2]);
7208 operands[2] = make_safe_from (operands[2], operands[0]);
7209
7210 emit_insn (gen_zero_extendsidi2 (operands[3], operands[1]));
7211 insn = emit_insn (gen_divmoddisi3 (operands[3], operands[3],
7212 operands[2]));
7213 set_unique_reg_note (insn, REG_EQUAL, equal);
7214
7215 insn = emit_move_insn (operands[0],
7216 gen_highpart (SImode, operands[3]));
7217 set_unique_reg_note (insn, REG_EQUAL, umod_equal);
7218 }
7219 }
7220 else
7221 {
7222 rtx_code_label *label1 = gen_label_rtx ();
7223 rtx_code_label *label2 = gen_label_rtx ();
7224 rtx_code_label *label3 = gen_label_rtx ();
7225
7226 operands[1] = force_reg (SImode, operands[1]);
7227 operands[1] = make_safe_from (operands[1], operands[0]);
7228 operands[2] = force_reg (SImode, operands[2]);
7229 operands[2] = make_safe_from (operands[2], operands[0]);
7230
7231 emit_move_insn(operands[0], operands[1]);
7232 emit_cmp_and_jump_insns (operands[2], operands[1], GT, NULL_RTX,
7233 SImode, 1, label3);
7234 emit_cmp_and_jump_insns (operands[2], const0_rtx, LT, NULL_RTX,
7235 SImode, 0, label2);
7236 emit_cmp_and_jump_insns (operands[2], const1_rtx, EQ, NULL_RTX,
7237 SImode, 0, label1);
7238 emit_insn (gen_zero_extendsidi2 (operands[3], operands[1]));
7239 insn = emit_insn (gen_divmoddisi3 (operands[3], operands[3],
7240 operands[2]));
7241 set_unique_reg_note (insn, REG_EQUAL, equal);
7242
7243 insn = emit_move_insn (operands[0],
7244 gen_highpart (SImode, operands[3]));
7245 set_unique_reg_note (insn, REG_EQUAL, umod_equal);
7246
7247 emit_jump (label3);
7248 emit_label (label1);
7249 emit_move_insn (operands[0], const0_rtx);
7250 emit_jump (label3);
7251 emit_label (label2);
7252 emit_insn (gen_subsi3 (operands[0], operands[0], operands[2]));
7253 emit_label (label3);
7254 }
7255 DONE;
7256 })
7257
7258 ;
7259 ; div(df|sf)3 instruction pattern(s).
7260 ;
7261
7262 ; dxbr, ddbr, debr, dxb, ddb, deb, ddtr, dxtr
7263 (define_insn "div<mode>3"
7264 [(set (match_operand:FP 0 "register_operand" "=f,f,f,v,v")
7265 (div:FP (match_operand:FP 1 "register_operand" "f,0,0,v,v")
7266 (match_operand:FP 2 "general_operand" "f,f,R,v,v")))]
7267 "TARGET_HARD_FLOAT"
7268 "@
7269 d<xde>tr\t%0,%1,%2
7270 d<xde>br\t%0,%2
7271 d<xde>b\t%0,%2
7272 wfddb\t%v0,%v1,%v2
7273 wfdsb\t%v0,%v1,%v2"
7274 [(set_attr "op_type" "RRF,RRE,RXE,VRR,VRR")
7275 (set_attr "type" "fdiv<mode>")
7276 (set_attr "cpu_facility" "*,*,*,vx,vxe")
7277 (set_attr "enabled" "<nBFP>,<nDFP>,<DSF>,<DF>,<SF>")])
7278
7279
7280 ;;
7281 ;;- And instructions.
7282 ;;
7283
7284 (define_expand "and<mode>3"
7285 [(set (match_operand:INT 0 "nonimmediate_operand" "")
7286 (and:INT (match_operand:INT 1 "nonimmediate_operand" "")
7287 (match_operand:INT 2 "general_operand" "")))
7288 (clobber (reg:CC CC_REGNUM))]
7289 ""
7290 "s390_expand_logical_operator (AND, <MODE>mode, operands); DONE;")
7291
7292 ;
7293 ; anddi3 instruction pattern(s).
7294 ;
7295
7296 (define_insn "*anddi3_cc"
7297 [(set (reg CC_REGNUM)
7298 (compare
7299 (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,d,0, d")
7300 (match_operand:DI 2 "general_operand" " d,d,T,NxxDw"))
7301 (const_int 0)))
7302 (set (match_operand:DI 0 "register_operand" "=d,d,d, d")
7303 (and:DI (match_dup 1) (match_dup 2)))]
7304 "TARGET_ZARCH && s390_match_ccmode(insn, CCTmode)"
7305 "@
7306 ngr\t%0,%2
7307 ngrk\t%0,%1,%2
7308 ng\t%0,%2
7309 risbg\t%0,%1,%s2,128+%e2,0"
7310 [(set_attr "op_type" "RRE,RRF,RXY,RIE")
7311 (set_attr "cpu_facility" "*,z196,*,z10")
7312 (set_attr "z10prop" "z10_super_E1,*,z10_super_E1,z10_super_E1")])
7313
7314 (define_insn "*anddi3_cconly"
7315 [(set (reg CC_REGNUM)
7316 (compare
7317 (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,d,0, d")
7318 (match_operand:DI 2 "general_operand" " d,d,T,NxxDw"))
7319 (const_int 0)))
7320 (clobber (match_scratch:DI 0 "=d,d,d, d"))]
7321 "TARGET_ZARCH
7322 && s390_match_ccmode(insn, CCTmode)
7323 /* Do not steal TM patterns. */
7324 && s390_single_part (operands[2], DImode, HImode, 0) < 0"
7325 "@
7326 ngr\t%0,%2
7327 ngrk\t%0,%1,%2
7328 ng\t%0,%2
7329 risbg\t%0,%1,%s2,128+%e2,0"
7330 [(set_attr "op_type" "RRE,RRF,RXY,RIE")
7331 (set_attr "cpu_facility" "*,z196,*,z10")
7332 (set_attr "z10prop" "z10_super_E1,*,z10_super_E1,z10_super_E1")])
7333
7334 (define_insn "*anddi3"
7335 [(set (match_operand:DI 0 "nonimmediate_operand"
7336 "=d,d, d, d, d, d, d, d,d,d,d, d, AQ,Q")
7337 (and:DI
7338 (match_operand:DI 1 "nonimmediate_operand"
7339 "%d,o, 0, 0, 0, 0, 0, 0,0,d,0, d, 0,0")
7340 (match_operand:DI 2 "general_operand"
7341 "M, M,N0HDF,N1HDF,N2HDF,N3HDF,N0SDF,N1SDF,d,d,T,NxxDw,NxQDF,Q")))
7342 (clobber (reg:CC CC_REGNUM))]
7343 "TARGET_ZARCH && s390_logical_operator_ok_p (operands)"
7344 "@
7345 #
7346 #
7347 nihh\t%0,%j2
7348 nihl\t%0,%j2
7349 nilh\t%0,%j2
7350 nill\t%0,%j2
7351 nihf\t%0,%m2
7352 nilf\t%0,%m2
7353 ngr\t%0,%2
7354 ngrk\t%0,%1,%2
7355 ng\t%0,%2
7356 risbg\t%0,%1,%s2,128+%e2,0
7357 #
7358 #"
7359 [(set_attr "op_type" "RRE,RXE,RI,RI,RI,RI,RIL,RIL,RRE,RRF,RXY,RIE,SI,SS")
7360 (set_attr "cpu_facility" "*,*,*,*,*,*,extimm,extimm,*,z196,*,z10,*,*")
7361 (set_attr "z10prop" "*,
7362 *,
7363 z10_super_E1,
7364 z10_super_E1,
7365 z10_super_E1,
7366 z10_super_E1,
7367 z10_super_E1,
7368 z10_super_E1,
7369 z10_super_E1,
7370 *,
7371 z10_super_E1,
7372 z10_super_E1,
7373 *,
7374 *")])
7375
7376 (define_split
7377 [(set (match_operand:DI 0 "s_operand" "")
7378 (and:DI (match_dup 0) (match_operand:DI 1 "immediate_operand" "")))
7379 (clobber (reg:CC CC_REGNUM))]
7380 "reload_completed"
7381 [(parallel
7382 [(set (match_dup 0) (and:QI (match_dup 0) (match_dup 1)))
7383 (clobber (reg:CC CC_REGNUM))])]
7384 "s390_narrow_logical_operator (AND, &operands[0], &operands[1]);")
7385
7386 ;; These two are what combine generates for (ashift (zero_extract)).
7387 (define_insn "*extzv_<mode>_srl<clobbercc_or_nocc>"
7388 [(set (match_operand:GPR 0 "register_operand" "=d")
7389 (and:GPR (lshiftrt:GPR
7390 (match_operand:GPR 1 "register_operand" "d")
7391 (match_operand:GPR 2 "nonzero_shift_count_operand" ""))
7392 (match_operand:GPR 3 "contiguous_bitmask_nowrap_operand" "")))]
7393 "<z10_or_zEC12_cond>
7394 /* Note that even for the SImode pattern, the rotate is always DImode. */
7395 && s390_extzv_shift_ok (<bitsize>, -INTVAL (operands[2]),
7396 INTVAL (operands[3]))"
7397 "<risbg_n>\t%0,%1,%<bfstart>3,128+%<bfend>3,64-%2"
7398 [(set_attr "op_type" "RIE")
7399 (set_attr "z10prop" "z10_super_E1")])
7400
7401 (define_insn "*extzv_<mode>_sll<clobbercc_or_nocc>"
7402 [(set (match_operand:GPR 0 "register_operand" "=d")
7403 (and:GPR (ashift: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 && s390_extzv_shift_ok (<bitsize>, INTVAL (operands[2]),
7409 INTVAL (operands[3]))"
7410 "<risbg_n>\t%0,%1,%<bfstart>3,128+%<bfend>3,%2"
7411 [(set_attr "op_type" "RIE")
7412 (set_attr "z10prop" "z10_super_E1")])
7413
7414
7415 ;
7416 ; andsi3 instruction pattern(s).
7417 ;
7418
7419 (define_insn "*andsi3_cc"
7420 [(set (reg CC_REGNUM)
7421 (compare
7422 (and:SI
7423 (match_operand:SI 1 "nonimmediate_operand" "%0,0,d,0,0, d")
7424 (match_operand:SI 2 "general_operand" "Os,d,d,R,T,NxxSq"))
7425 (const_int 0)))
7426 (set (match_operand:SI 0 "register_operand" "=d,d,d,d,d, d")
7427 (and:SI (match_dup 1) (match_dup 2)))]
7428 "s390_match_ccmode(insn, CCTmode)"
7429 "@
7430 nilf\t%0,%o2
7431 nr\t%0,%2
7432 nrk\t%0,%1,%2
7433 n\t%0,%2
7434 ny\t%0,%2
7435 risbg\t%0,%1,%t2,128+%f2,0"
7436 [(set_attr "op_type" "RIL,RR,RRF,RX,RXY,RIE")
7437 (set_attr "cpu_facility" "*,*,z196,*,longdisp,z10")
7438 (set_attr "z10prop" "z10_super_E1,z10_super_E1,*,
7439 z10_super_E1,z10_super_E1,z10_super_E1")])
7440
7441 (define_insn "*andsi3_cconly"
7442 [(set (reg CC_REGNUM)
7443 (compare
7444 (and:SI
7445 (match_operand:SI 1 "nonimmediate_operand" "%0,0,d,0,0, d")
7446 (match_operand:SI 2 "general_operand" "Os,d,d,R,T,NxxSq"))
7447 (const_int 0)))
7448 (clobber (match_scratch:SI 0 "=d,d,d,d,d, d"))]
7449 "s390_match_ccmode(insn, CCTmode)
7450 /* Do not steal TM patterns. */
7451 && s390_single_part (operands[2], SImode, HImode, 0) < 0"
7452 "@
7453 nilf\t%0,%o2
7454 nr\t%0,%2
7455 nrk\t%0,%1,%2
7456 n\t%0,%2
7457 ny\t%0,%2
7458 risbg\t%0,%1,%t2,128+%f2,0"
7459 [(set_attr "op_type" "RIL,RR,RRF,RX,RXY,RIE")
7460 (set_attr "cpu_facility" "*,*,z196,*,longdisp,z10")
7461 (set_attr "z10prop" "z10_super_E1,z10_super_E1,*,
7462 z10_super_E1,z10_super_E1,z10_super_E1")])
7463
7464 (define_insn "*andsi3_zarch"
7465 [(set (match_operand:SI 0 "nonimmediate_operand"
7466 "=d,d, d, d, d,d,d,d,d, d, AQ,Q")
7467 (and:SI (match_operand:SI 1 "nonimmediate_operand"
7468 "%d,o, 0, 0, 0,0,d,0,0, d, 0,0")
7469 (match_operand:SI 2 "general_operand"
7470 " M,M,N0HSF,N1HSF,Os,d,d,R,T,NxxSw,NxQSF,Q")))
7471 (clobber (reg:CC CC_REGNUM))]
7472 "TARGET_ZARCH && s390_logical_operator_ok_p (operands)"
7473 "@
7474 #
7475 #
7476 nilh\t%0,%j2
7477 nill\t%0,%j2
7478 nilf\t%0,%o2
7479 nr\t%0,%2
7480 nrk\t%0,%1,%2
7481 n\t%0,%2
7482 ny\t%0,%2
7483 risbg\t%0,%1,%t2,128+%f2,0
7484 #
7485 #"
7486 [(set_attr "op_type" "RRE,RXE,RI,RI,RIL,RR,RRF,RX,RXY,RIE,SI,SS")
7487 (set_attr "cpu_facility" "*,*,*,*,*,*,z196,*,longdisp,z10,*,*")
7488 (set_attr "z10prop" "*,
7489 *,
7490 z10_super_E1,
7491 z10_super_E1,
7492 z10_super_E1,
7493 z10_super_E1,
7494 *,
7495 z10_super_E1,
7496 z10_super_E1,
7497 z10_super_E1,
7498 *,
7499 *")])
7500
7501 (define_insn "*andsi3_esa"
7502 [(set (match_operand:SI 0 "nonimmediate_operand" "=d,d, AQ,Q")
7503 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0, 0,0")
7504 (match_operand:SI 2 "general_operand" " d,R,NxQSF,Q")))
7505 (clobber (reg:CC CC_REGNUM))]
7506 "!TARGET_ZARCH && s390_logical_operator_ok_p (operands)"
7507 "@
7508 nr\t%0,%2
7509 n\t%0,%2
7510 #
7511 #"
7512 [(set_attr "op_type" "RR,RX,SI,SS")
7513 (set_attr "z10prop" "z10_super_E1,z10_super_E1,*,*")])
7514
7515
7516 (define_split
7517 [(set (match_operand:SI 0 "s_operand" "")
7518 (and:SI (match_dup 0) (match_operand:SI 1 "immediate_operand" "")))
7519 (clobber (reg:CC CC_REGNUM))]
7520 "reload_completed"
7521 [(parallel
7522 [(set (match_dup 0) (and:QI (match_dup 0) (match_dup 1)))
7523 (clobber (reg:CC CC_REGNUM))])]
7524 "s390_narrow_logical_operator (AND, &operands[0], &operands[1]);")
7525
7526 ;
7527 ; andhi3 instruction pattern(s).
7528 ;
7529
7530 (define_insn "*andhi3_zarch"
7531 [(set (match_operand:HI 0 "nonimmediate_operand" "=d,d,d, AQ,Q")
7532 (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,d,0, 0,0")
7533 (match_operand:HI 2 "general_operand" " d,d,n,NxQHF,Q")))
7534 (clobber (reg:CC CC_REGNUM))]
7535 "TARGET_ZARCH && s390_logical_operator_ok_p (operands)"
7536 "@
7537 nr\t%0,%2
7538 nrk\t%0,%1,%2
7539 nill\t%0,%x2
7540 #
7541 #"
7542 [(set_attr "op_type" "RR,RRF,RI,SI,SS")
7543 (set_attr "cpu_facility" "*,z196,*,*,*")
7544 (set_attr "z10prop" "z10_super_E1,*,z10_super_E1,*,*")
7545 ])
7546
7547 (define_insn "*andhi3_esa"
7548 [(set (match_operand:HI 0 "nonimmediate_operand" "=d,AQ,Q")
7549 (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,0")
7550 (match_operand:HI 2 "general_operand" "d,NxQHF,Q")))
7551 (clobber (reg:CC CC_REGNUM))]
7552 "!TARGET_ZARCH && s390_logical_operator_ok_p (operands)"
7553 "@
7554 nr\t%0,%2
7555 #
7556 #"
7557 [(set_attr "op_type" "RR,SI,SS")
7558 (set_attr "z10prop" "z10_super_E1,*,*")
7559 ])
7560
7561 (define_split
7562 [(set (match_operand:HI 0 "s_operand" "")
7563 (and:HI (match_dup 0) (match_operand:HI 1 "immediate_operand" "")))
7564 (clobber (reg:CC CC_REGNUM))]
7565 "reload_completed"
7566 [(parallel
7567 [(set (match_dup 0) (and:QI (match_dup 0) (match_dup 1)))
7568 (clobber (reg:CC CC_REGNUM))])]
7569 "s390_narrow_logical_operator (AND, &operands[0], &operands[1]);")
7570
7571 ;
7572 ; andqi3 instruction pattern(s).
7573 ;
7574
7575 (define_insn "*andqi3_zarch"
7576 [(set (match_operand:QI 0 "nonimmediate_operand" "=d,d,d,Q,S,Q")
7577 (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,d,0,0,0,0")
7578 (match_operand:QI 2 "general_operand" " d,d,n,n,n,Q")))
7579 (clobber (reg:CC CC_REGNUM))]
7580 "TARGET_ZARCH && s390_logical_operator_ok_p (operands)"
7581 "@
7582 nr\t%0,%2
7583 nrk\t%0,%1,%2
7584 nill\t%0,%b2
7585 ni\t%S0,%b2
7586 niy\t%S0,%b2
7587 #"
7588 [(set_attr "op_type" "RR,RRF,RI,SI,SIY,SS")
7589 (set_attr "cpu_facility" "*,z196,*,*,longdisp,*")
7590 (set_attr "z10prop" "z10_super_E1,*,z10_super_E1,z10_super,z10_super,*")])
7591
7592 (define_insn "*andqi3_esa"
7593 [(set (match_operand:QI 0 "nonimmediate_operand" "=d,Q,Q")
7594 (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
7595 (match_operand:QI 2 "general_operand" "d,n,Q")))
7596 (clobber (reg:CC CC_REGNUM))]
7597 "!TARGET_ZARCH && s390_logical_operator_ok_p (operands)"
7598 "@
7599 nr\t%0,%2
7600 ni\t%S0,%b2
7601 #"
7602 [(set_attr "op_type" "RR,SI,SS")
7603 (set_attr "z10prop" "z10_super_E1,z10_super,*")])
7604
7605 ;
7606 ; And with complement
7607 ;
7608 ; c = ~b & a = (b & a) ^ a
7609
7610 (define_insn_and_split "*andc_split_<mode>"
7611 [(set (match_operand:GPR 0 "nonimmediate_operand" "")
7612 (and:GPR (not:GPR (match_operand:GPR 1 "nonimmediate_operand" ""))
7613 (match_operand:GPR 2 "general_operand" "")))
7614 (clobber (reg:CC CC_REGNUM))]
7615 "! reload_completed
7616 && (GET_CODE (operands[0]) != MEM
7617 /* Ensure that s390_logical_operator_ok_p will succeed even
7618 on the split xor if (b & a) is stored into a pseudo. */
7619 || rtx_equal_p (operands[0], operands[2]))"
7620 "#"
7621 "&& 1"
7622 [
7623 (parallel
7624 [(set (match_dup 3) (and:GPR (match_dup 1) (match_dup 2)))
7625 (clobber (reg:CC CC_REGNUM))])
7626 (parallel
7627 [(set (match_dup 0) (xor:GPR (match_dup 3) (match_dup 2)))
7628 (clobber (reg:CC CC_REGNUM))])]
7629 {
7630 if (reg_overlap_mentioned_p (operands[0], operands[2]))
7631 operands[3] = gen_reg_rtx (<MODE>mode);
7632 else
7633 operands[3] = operands[0];
7634 })
7635
7636 ;
7637 ; Block and (NC) patterns.
7638 ;
7639
7640 (define_insn "*nc"
7641 [(set (match_operand:BLK 0 "memory_operand" "=Q")
7642 (and:BLK (match_dup 0)
7643 (match_operand:BLK 1 "memory_operand" "Q")))
7644 (use (match_operand 2 "const_int_operand" "n"))
7645 (clobber (reg:CC CC_REGNUM))]
7646 "INTVAL (operands[2]) >= 1 && INTVAL (operands[2]) <= 256"
7647 "nc\t%O0(%2,%R0),%S1"
7648 [(set_attr "op_type" "SS")
7649 (set_attr "z196prop" "z196_cracked")])
7650
7651 (define_split
7652 [(set (match_operand 0 "memory_operand" "")
7653 (and (match_dup 0)
7654 (match_operand 1 "memory_operand" "")))
7655 (clobber (reg:CC CC_REGNUM))]
7656 "reload_completed
7657 && GET_MODE (operands[0]) == GET_MODE (operands[1])
7658 && GET_MODE_SIZE (GET_MODE (operands[0])) > 0"
7659 [(parallel
7660 [(set (match_dup 0) (and:BLK (match_dup 0) (match_dup 1)))
7661 (use (match_dup 2))
7662 (clobber (reg:CC CC_REGNUM))])]
7663 {
7664 operands[2] = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[0])));
7665 operands[0] = adjust_address (operands[0], BLKmode, 0);
7666 operands[1] = adjust_address (operands[1], BLKmode, 0);
7667 })
7668
7669 (define_peephole2
7670 [(parallel
7671 [(set (match_operand:BLK 0 "memory_operand" "")
7672 (and:BLK (match_dup 0)
7673 (match_operand:BLK 1 "memory_operand" "")))
7674 (use (match_operand 2 "const_int_operand" ""))
7675 (clobber (reg:CC CC_REGNUM))])
7676 (parallel
7677 [(set (match_operand:BLK 3 "memory_operand" "")
7678 (and:BLK (match_dup 3)
7679 (match_operand:BLK 4 "memory_operand" "")))
7680 (use (match_operand 5 "const_int_operand" ""))
7681 (clobber (reg:CC CC_REGNUM))])]
7682 "s390_offset_p (operands[0], operands[3], operands[2])
7683 && s390_offset_p (operands[1], operands[4], operands[2])
7684 && !s390_overlap_p (operands[0], operands[1],
7685 INTVAL (operands[2]) + INTVAL (operands[5]))
7686 && INTVAL (operands[2]) + INTVAL (operands[5]) <= 256"
7687 [(parallel
7688 [(set (match_dup 6) (and:BLK (match_dup 6) (match_dup 7)))
7689 (use (match_dup 8))
7690 (clobber (reg:CC CC_REGNUM))])]
7691 "operands[6] = gen_rtx_MEM (BLKmode, XEXP (operands[0], 0));
7692 operands[7] = gen_rtx_MEM (BLKmode, XEXP (operands[1], 0));
7693 operands[8] = GEN_INT (INTVAL (operands[2]) + INTVAL (operands[5]));")
7694
7695
7696 ;;
7697 ;;- Bit set (inclusive or) instructions.
7698 ;;
7699
7700 (define_expand "ior<mode>3"
7701 [(set (match_operand:INT 0 "nonimmediate_operand" "")
7702 (ior:INT (match_operand:INT 1 "nonimmediate_operand" "")
7703 (match_operand:INT 2 "general_operand" "")))
7704 (clobber (reg:CC CC_REGNUM))]
7705 ""
7706 "s390_expand_logical_operator (IOR, <MODE>mode, operands); DONE;")
7707
7708 ;
7709 ; iordi3 instruction pattern(s).
7710 ;
7711
7712 (define_insn "*iordi3_cc"
7713 [(set (reg CC_REGNUM)
7714 (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,d,0")
7715 (match_operand:DI 2 "general_operand" " d,d,T"))
7716 (const_int 0)))
7717 (set (match_operand:DI 0 "register_operand" "=d,d,d")
7718 (ior:DI (match_dup 1) (match_dup 2)))]
7719 "s390_match_ccmode(insn, CCTmode) && TARGET_ZARCH"
7720 "@
7721 ogr\t%0,%2
7722 ogrk\t%0,%1,%2
7723 og\t%0,%2"
7724 [(set_attr "op_type" "RRE,RRF,RXY")
7725 (set_attr "cpu_facility" "*,z196,*")
7726 (set_attr "z10prop" "z10_super_E1,*,z10_super_E1")])
7727
7728 (define_insn "*iordi3_cconly"
7729 [(set (reg CC_REGNUM)
7730 (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,d,0")
7731 (match_operand:DI 2 "general_operand" " d,d,T"))
7732 (const_int 0)))
7733 (clobber (match_scratch:DI 0 "=d,d,d"))]
7734 "s390_match_ccmode(insn, CCTmode) && TARGET_ZARCH"
7735 "@
7736 ogr\t%0,%2
7737 ogrk\t%0,%1,%2
7738 og\t%0,%2"
7739 [(set_attr "op_type" "RRE,RRF,RXY")
7740 (set_attr "cpu_facility" "*,z196,*")
7741 (set_attr "z10prop" "z10_super_E1,*,z10_super_E1")])
7742
7743 (define_insn "*iordi3"
7744 [(set (match_operand:DI 0 "nonimmediate_operand"
7745 "=d, d, d, d, d, d,d,d,d, AQ,Q")
7746 (ior:DI (match_operand:DI 1 "nonimmediate_operand"
7747 " %0, 0, 0, 0, 0, 0,0,d,0, 0,0")
7748 (match_operand:DI 2 "general_operand"
7749 "N0HD0,N1HD0,N2HD0,N3HD0,N0SD0,N1SD0,d,d,T,NxQD0,Q")))
7750 (clobber (reg:CC CC_REGNUM))]
7751 "TARGET_ZARCH && s390_logical_operator_ok_p (operands)"
7752 "@
7753 oihh\t%0,%i2
7754 oihl\t%0,%i2
7755 oilh\t%0,%i2
7756 oill\t%0,%i2
7757 oihf\t%0,%k2
7758 oilf\t%0,%k2
7759 ogr\t%0,%2
7760 ogrk\t%0,%1,%2
7761 og\t%0,%2
7762 #
7763 #"
7764 [(set_attr "op_type" "RI,RI,RI,RI,RIL,RIL,RRE,RRF,RXY,SI,SS")
7765 (set_attr "cpu_facility" "*,*,*,*,extimm,extimm,*,z196,*,*,*")
7766 (set_attr "z10prop" "z10_super_E1,
7767 z10_super_E1,
7768 z10_super_E1,
7769 z10_super_E1,
7770 z10_super_E1,
7771 z10_super_E1,
7772 z10_super_E1,
7773 *,
7774 z10_super_E1,
7775 *,
7776 *")])
7777
7778 (define_split
7779 [(set (match_operand:DI 0 "s_operand" "")
7780 (ior:DI (match_dup 0) (match_operand:DI 1 "immediate_operand" "")))
7781 (clobber (reg:CC CC_REGNUM))]
7782 "reload_completed"
7783 [(parallel
7784 [(set (match_dup 0) (ior:QI (match_dup 0) (match_dup 1)))
7785 (clobber (reg:CC CC_REGNUM))])]
7786 "s390_narrow_logical_operator (IOR, &operands[0], &operands[1]);")
7787
7788 ;
7789 ; iorsi3 instruction pattern(s).
7790 ;
7791
7792 (define_insn "*iorsi3_cc"
7793 [(set (reg CC_REGNUM)
7794 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,d,0,0")
7795 (match_operand:SI 2 "general_operand" "Os,d,d,R,T"))
7796 (const_int 0)))
7797 (set (match_operand:SI 0 "register_operand" "=d,d,d,d,d")
7798 (ior:SI (match_dup 1) (match_dup 2)))]
7799 "s390_match_ccmode(insn, CCTmode)"
7800 "@
7801 oilf\t%0,%o2
7802 or\t%0,%2
7803 ork\t%0,%1,%2
7804 o\t%0,%2
7805 oy\t%0,%2"
7806 [(set_attr "op_type" "RIL,RR,RRF,RX,RXY")
7807 (set_attr "cpu_facility" "*,*,z196,*,longdisp")
7808 (set_attr "z10prop" "z10_super_E1,z10_super_E1,*,z10_super_E1,z10_super_E1")])
7809
7810 (define_insn "*iorsi3_cconly"
7811 [(set (reg CC_REGNUM)
7812 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,d,0,0")
7813 (match_operand:SI 2 "general_operand" "Os,d,d,R,T"))
7814 (const_int 0)))
7815 (clobber (match_scratch:SI 0 "=d,d,d,d,d"))]
7816 "s390_match_ccmode(insn, CCTmode)"
7817 "@
7818 oilf\t%0,%o2
7819 or\t%0,%2
7820 ork\t%0,%1,%2
7821 o\t%0,%2
7822 oy\t%0,%2"
7823 [(set_attr "op_type" "RIL,RR,RRF,RX,RXY")
7824 (set_attr "cpu_facility" "*,*,z196,*,longdisp")
7825 (set_attr "z10prop" "z10_super_E1,z10_super_E1,*,z10_super_E1,z10_super_E1")])
7826
7827 (define_insn "*iorsi3_zarch"
7828 [(set (match_operand:SI 0 "nonimmediate_operand" "=d, d, d,d,d,d,d, AQ,Q")
7829 (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0, 0, 0,0,d,0,0, 0,0")
7830 (match_operand:SI 2 "general_operand" "N0HS0,N1HS0,Os,d,d,R,T,NxQS0,Q")))
7831 (clobber (reg:CC CC_REGNUM))]
7832 "TARGET_ZARCH && s390_logical_operator_ok_p (operands)"
7833 "@
7834 oilh\t%0,%i2
7835 oill\t%0,%i2
7836 oilf\t%0,%o2
7837 or\t%0,%2
7838 ork\t%0,%1,%2
7839 o\t%0,%2
7840 oy\t%0,%2
7841 #
7842 #"
7843 [(set_attr "op_type" "RI,RI,RIL,RR,RRF,RX,RXY,SI,SS")
7844 (set_attr "cpu_facility" "*,*,*,*,z196,*,longdisp,*,*")
7845 (set_attr "z10prop" "z10_super_E1,
7846 z10_super_E1,
7847 z10_super_E1,
7848 z10_super_E1,
7849 *,
7850 z10_super_E1,
7851 z10_super_E1,
7852 *,
7853 *")])
7854
7855 (define_insn "*iorsi3_esa"
7856 [(set (match_operand:SI 0 "nonimmediate_operand" "=d,d,AQ,Q")
7857 (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,0,0")
7858 (match_operand:SI 2 "general_operand" "d,R,NxQS0,Q")))
7859 (clobber (reg:CC CC_REGNUM))]
7860 "!TARGET_ZARCH && s390_logical_operator_ok_p (operands)"
7861 "@
7862 or\t%0,%2
7863 o\t%0,%2
7864 #
7865 #"
7866 [(set_attr "op_type" "RR,RX,SI,SS")
7867 (set_attr "z10prop" "z10_super_E1,z10_super_E1,*,*")])
7868
7869 (define_split
7870 [(set (match_operand:SI 0 "s_operand" "")
7871 (ior:SI (match_dup 0) (match_operand:SI 1 "immediate_operand" "")))
7872 (clobber (reg:CC CC_REGNUM))]
7873 "reload_completed"
7874 [(parallel
7875 [(set (match_dup 0) (ior:QI (match_dup 0) (match_dup 1)))
7876 (clobber (reg:CC CC_REGNUM))])]
7877 "s390_narrow_logical_operator (IOR, &operands[0], &operands[1]);")
7878
7879 ;
7880 ; iorhi3 instruction pattern(s).
7881 ;
7882
7883 (define_insn "*iorhi3_zarch"
7884 [(set (match_operand:HI 0 "nonimmediate_operand" "=d,d,d, AQ,Q")
7885 (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,d,0, 0,0")
7886 (match_operand:HI 2 "general_operand" " d,d,n,NxQH0,Q")))
7887 (clobber (reg:CC CC_REGNUM))]
7888 "TARGET_ZARCH && s390_logical_operator_ok_p (operands)"
7889 "@
7890 or\t%0,%2
7891 ork\t%0,%1,%2
7892 oill\t%0,%x2
7893 #
7894 #"
7895 [(set_attr "op_type" "RR,RRF,RI,SI,SS")
7896 (set_attr "cpu_facility" "*,z196,*,*,*")
7897 (set_attr "z10prop" "z10_super_E1,*,z10_super_E1,*,*")])
7898
7899 (define_insn "*iorhi3_esa"
7900 [(set (match_operand:HI 0 "nonimmediate_operand" "=d,AQ,Q")
7901 (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,0")
7902 (match_operand:HI 2 "general_operand" "d,NxQH0,Q")))
7903 (clobber (reg:CC CC_REGNUM))]
7904 "!TARGET_ZARCH && s390_logical_operator_ok_p (operands)"
7905 "@
7906 or\t%0,%2
7907 #
7908 #"
7909 [(set_attr "op_type" "RR,SI,SS")
7910 (set_attr "z10prop" "z10_super_E1,*,*")])
7911
7912 (define_split
7913 [(set (match_operand:HI 0 "s_operand" "")
7914 (ior:HI (match_dup 0) (match_operand:HI 1 "immediate_operand" "")))
7915 (clobber (reg:CC CC_REGNUM))]
7916 "reload_completed"
7917 [(parallel
7918 [(set (match_dup 0) (ior:QI (match_dup 0) (match_dup 1)))
7919 (clobber (reg:CC CC_REGNUM))])]
7920 "s390_narrow_logical_operator (IOR, &operands[0], &operands[1]);")
7921
7922 ;
7923 ; iorqi3 instruction pattern(s).
7924 ;
7925
7926 (define_insn "*iorqi3_zarch"
7927 [(set (match_operand:QI 0 "nonimmediate_operand" "=d,d,d,Q,S,Q")
7928 (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,d,0,0,0,0")
7929 (match_operand:QI 2 "general_operand" " d,d,n,n,n,Q")))
7930 (clobber (reg:CC CC_REGNUM))]
7931 "TARGET_ZARCH && s390_logical_operator_ok_p (operands)"
7932 "@
7933 or\t%0,%2
7934 ork\t%0,%1,%2
7935 oill\t%0,%b2
7936 oi\t%S0,%b2
7937 oiy\t%S0,%b2
7938 #"
7939 [(set_attr "op_type" "RR,RRF,RI,SI,SIY,SS")
7940 (set_attr "cpu_facility" "*,z196,*,*,longdisp,*")
7941 (set_attr "z10prop" "z10_super_E1,*,z10_super_E1,
7942 z10_super,z10_super,*")])
7943
7944 (define_insn "*iorqi3_esa"
7945 [(set (match_operand:QI 0 "nonimmediate_operand" "=d,Q,Q")
7946 (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
7947 (match_operand:QI 2 "general_operand" "d,n,Q")))
7948 (clobber (reg:CC CC_REGNUM))]
7949 "!TARGET_ZARCH && s390_logical_operator_ok_p (operands)"
7950 "@
7951 or\t%0,%2
7952 oi\t%S0,%b2
7953 #"
7954 [(set_attr "op_type" "RR,SI,SS")
7955 (set_attr "z10prop" "z10_super_E1,z10_super,*")])
7956
7957 ;
7958 ; Block inclusive or (OC) patterns.
7959 ;
7960
7961 (define_insn "*oc"
7962 [(set (match_operand:BLK 0 "memory_operand" "=Q")
7963 (ior:BLK (match_dup 0)
7964 (match_operand:BLK 1 "memory_operand" "Q")))
7965 (use (match_operand 2 "const_int_operand" "n"))
7966 (clobber (reg:CC CC_REGNUM))]
7967 "INTVAL (operands[2]) >= 1 && INTVAL (operands[2]) <= 256"
7968 "oc\t%O0(%2,%R0),%S1"
7969 [(set_attr "op_type" "SS")
7970 (set_attr "z196prop" "z196_cracked")])
7971
7972 (define_split
7973 [(set (match_operand 0 "memory_operand" "")
7974 (ior (match_dup 0)
7975 (match_operand 1 "memory_operand" "")))
7976 (clobber (reg:CC CC_REGNUM))]
7977 "reload_completed
7978 && GET_MODE (operands[0]) == GET_MODE (operands[1])
7979 && GET_MODE_SIZE (GET_MODE (operands[0])) > 0"
7980 [(parallel
7981 [(set (match_dup 0) (ior:BLK (match_dup 0) (match_dup 1)))
7982 (use (match_dup 2))
7983 (clobber (reg:CC CC_REGNUM))])]
7984 {
7985 operands[2] = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[0])));
7986 operands[0] = adjust_address (operands[0], BLKmode, 0);
7987 operands[1] = adjust_address (operands[1], BLKmode, 0);
7988 })
7989
7990 (define_peephole2
7991 [(parallel
7992 [(set (match_operand:BLK 0 "memory_operand" "")
7993 (ior:BLK (match_dup 0)
7994 (match_operand:BLK 1 "memory_operand" "")))
7995 (use (match_operand 2 "const_int_operand" ""))
7996 (clobber (reg:CC CC_REGNUM))])
7997 (parallel
7998 [(set (match_operand:BLK 3 "memory_operand" "")
7999 (ior:BLK (match_dup 3)
8000 (match_operand:BLK 4 "memory_operand" "")))
8001 (use (match_operand 5 "const_int_operand" ""))
8002 (clobber (reg:CC CC_REGNUM))])]
8003 "s390_offset_p (operands[0], operands[3], operands[2])
8004 && s390_offset_p (operands[1], operands[4], operands[2])
8005 && !s390_overlap_p (operands[0], operands[1],
8006 INTVAL (operands[2]) + INTVAL (operands[5]))
8007 && INTVAL (operands[2]) + INTVAL (operands[5]) <= 256"
8008 [(parallel
8009 [(set (match_dup 6) (ior:BLK (match_dup 6) (match_dup 7)))
8010 (use (match_dup 8))
8011 (clobber (reg:CC CC_REGNUM))])]
8012 "operands[6] = gen_rtx_MEM (BLKmode, XEXP (operands[0], 0));
8013 operands[7] = gen_rtx_MEM (BLKmode, XEXP (operands[1], 0));
8014 operands[8] = GEN_INT (INTVAL (operands[2]) + INTVAL (operands[5]));")
8015
8016
8017 ;;
8018 ;;- Xor instructions.
8019 ;;
8020
8021 (define_expand "xor<mode>3"
8022 [(set (match_operand:INT 0 "nonimmediate_operand" "")
8023 (xor:INT (match_operand:INT 1 "nonimmediate_operand" "")
8024 (match_operand:INT 2 "general_operand" "")))
8025 (clobber (reg:CC CC_REGNUM))]
8026 ""
8027 "s390_expand_logical_operator (XOR, <MODE>mode, operands); DONE;")
8028
8029 ; Combine replaces (xor (x) (const_int -1)) with (not (x)) when doing
8030 ; simplifications. So its better to have something matching.
8031 (define_split
8032 [(set (match_operand:INT 0 "nonimmediate_operand" "")
8033 (not:INT (match_operand:INT 1 "nonimmediate_operand" "")))]
8034 ""
8035 [(parallel
8036 [(set (match_dup 0) (xor:INT (match_dup 1) (match_dup 2)))
8037 (clobber (reg:CC CC_REGNUM))])]
8038 {
8039 operands[2] = constm1_rtx;
8040 if (!s390_logical_operator_ok_p (operands))
8041 FAIL;
8042 })
8043
8044 ;
8045 ; xordi3 instruction pattern(s).
8046 ;
8047
8048 (define_insn "*xordi3_cc"
8049 [(set (reg CC_REGNUM)
8050 (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,d,0")
8051 (match_operand:DI 2 "general_operand" " d,d,T"))
8052 (const_int 0)))
8053 (set (match_operand:DI 0 "register_operand" "=d,d,d")
8054 (xor:DI (match_dup 1) (match_dup 2)))]
8055 "s390_match_ccmode(insn, CCTmode) && TARGET_ZARCH"
8056 "@
8057 xgr\t%0,%2
8058 xgrk\t%0,%1,%2
8059 xg\t%0,%2"
8060 [(set_attr "op_type" "RRE,RRF,RXY")
8061 (set_attr "cpu_facility" "*,z196,*")
8062 (set_attr "z10prop" "z10_super_E1,*,z10_super_E1")])
8063
8064 (define_insn "*xordi3_cconly"
8065 [(set (reg CC_REGNUM)
8066 (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,d,0")
8067 (match_operand:DI 2 "general_operand" " d,d,T"))
8068 (const_int 0)))
8069 (clobber (match_scratch:DI 0 "=d,d,d"))]
8070 "s390_match_ccmode(insn, CCTmode) && TARGET_ZARCH"
8071 "@
8072 xgr\t%0,%2
8073 xgrk\t%0,%1,%2
8074 xg\t%0,%2"
8075 [(set_attr "op_type" "RRE,RRF,RXY")
8076 (set_attr "cpu_facility" "*,z196,*")
8077 (set_attr "z10prop" "z10_super_E1,*,z10_super_E1")])
8078
8079 (define_insn "*xordi3"
8080 [(set (match_operand:DI 0 "nonimmediate_operand" "=d, d,d,d,d, AQ,Q")
8081 (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0, 0,0,d,0, 0,0")
8082 (match_operand:DI 2 "general_operand" "N0SD0,N1SD0,d,d,T,NxQD0,Q")))
8083 (clobber (reg:CC CC_REGNUM))]
8084 "TARGET_ZARCH && s390_logical_operator_ok_p (operands)"
8085 "@
8086 xihf\t%0,%k2
8087 xilf\t%0,%k2
8088 xgr\t%0,%2
8089 xgrk\t%0,%1,%2
8090 xg\t%0,%2
8091 #
8092 #"
8093 [(set_attr "op_type" "RIL,RIL,RRE,RRF,RXY,SI,SS")
8094 (set_attr "cpu_facility" "extimm,extimm,*,z196,*,*,*")
8095 (set_attr "z10prop" "z10_super_E1,z10_super_E1,z10_super_E1,
8096 *,z10_super_E1,*,*")])
8097
8098 (define_split
8099 [(set (match_operand:DI 0 "s_operand" "")
8100 (xor:DI (match_dup 0) (match_operand:DI 1 "immediate_operand" "")))
8101 (clobber (reg:CC CC_REGNUM))]
8102 "reload_completed"
8103 [(parallel
8104 [(set (match_dup 0) (xor:QI (match_dup 0) (match_dup 1)))
8105 (clobber (reg:CC CC_REGNUM))])]
8106 "s390_narrow_logical_operator (XOR, &operands[0], &operands[1]);")
8107
8108 ;
8109 ; xorsi3 instruction pattern(s).
8110 ;
8111
8112 (define_insn "*xorsi3_cc"
8113 [(set (reg CC_REGNUM)
8114 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,d,0,0")
8115 (match_operand:SI 2 "general_operand" "Os,d,d,R,T"))
8116 (const_int 0)))
8117 (set (match_operand:SI 0 "register_operand" "=d,d,d,d,d")
8118 (xor:SI (match_dup 1) (match_dup 2)))]
8119 "s390_match_ccmode(insn, CCTmode)"
8120 "@
8121 xilf\t%0,%o2
8122 xr\t%0,%2
8123 xrk\t%0,%1,%2
8124 x\t%0,%2
8125 xy\t%0,%2"
8126 [(set_attr "op_type" "RIL,RR,RRF,RX,RXY")
8127 (set_attr "cpu_facility" "*,*,z196,*,longdisp")
8128 (set_attr "z10prop" "z10_super_E1,z10_super_E1,*,
8129 z10_super_E1,z10_super_E1")])
8130
8131 (define_insn "*xorsi3_cconly"
8132 [(set (reg CC_REGNUM)
8133 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,d,0,0")
8134 (match_operand:SI 2 "general_operand" "Os,d,d,R,T"))
8135 (const_int 0)))
8136 (clobber (match_scratch:SI 0 "=d,d,d,d,d"))]
8137 "s390_match_ccmode(insn, CCTmode)"
8138 "@
8139 xilf\t%0,%o2
8140 xr\t%0,%2
8141 xrk\t%0,%1,%2
8142 x\t%0,%2
8143 xy\t%0,%2"
8144 [(set_attr "op_type" "RIL,RR,RRF,RX,RXY")
8145 (set_attr "cpu_facility" "*,*,z196,*,longdisp")
8146 (set_attr "z10prop" "z10_super_E1,z10_super_E1,*,
8147 z10_super_E1,z10_super_E1")])
8148
8149 (define_insn "*xorsi3"
8150 [(set (match_operand:SI 0 "nonimmediate_operand" "=d,d,d,d,d, AQ,Q")
8151 (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,d,0,0, 0,0")
8152 (match_operand:SI 2 "general_operand" "Os,d,d,R,T,NxQS0,Q")))
8153 (clobber (reg:CC CC_REGNUM))]
8154 "s390_logical_operator_ok_p (operands)"
8155 "@
8156 xilf\t%0,%o2
8157 xr\t%0,%2
8158 xrk\t%0,%1,%2
8159 x\t%0,%2
8160 xy\t%0,%2
8161 #
8162 #"
8163 [(set_attr "op_type" "RIL,RR,RRF,RX,RXY,SI,SS")
8164 (set_attr "cpu_facility" "*,*,z196,*,longdisp,*,*")
8165 (set_attr "z10prop" "z10_super_E1,z10_super_E1,*,
8166 z10_super_E1,z10_super_E1,*,*")])
8167
8168 (define_split
8169 [(set (match_operand:SI 0 "s_operand" "")
8170 (xor:SI (match_dup 0) (match_operand:SI 1 "immediate_operand" "")))
8171 (clobber (reg:CC CC_REGNUM))]
8172 "reload_completed"
8173 [(parallel
8174 [(set (match_dup 0) (xor:QI (match_dup 0) (match_dup 1)))
8175 (clobber (reg:CC CC_REGNUM))])]
8176 "s390_narrow_logical_operator (XOR, &operands[0], &operands[1]);")
8177
8178 ;
8179 ; xorhi3 instruction pattern(s).
8180 ;
8181
8182 (define_insn "*xorhi3"
8183 [(set (match_operand:HI 0 "nonimmediate_operand" "=d,d,d, AQ,Q")
8184 (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,d, 0,0")
8185 (match_operand:HI 2 "general_operand" "Os,d,d,NxQH0,Q")))
8186 (clobber (reg:CC CC_REGNUM))]
8187 "s390_logical_operator_ok_p (operands)"
8188 "@
8189 xilf\t%0,%x2
8190 xr\t%0,%2
8191 xrk\t%0,%1,%2
8192 #
8193 #"
8194 [(set_attr "op_type" "RIL,RR,RRF,SI,SS")
8195 (set_attr "cpu_facility" "*,*,z196,*,*")
8196 (set_attr "z10prop" "z10_super_E1,z10_super_E1,*,*,*")])
8197
8198 (define_split
8199 [(set (match_operand:HI 0 "s_operand" "")
8200 (xor:HI (match_dup 0) (match_operand:HI 1 "immediate_operand" "")))
8201 (clobber (reg:CC CC_REGNUM))]
8202 "reload_completed"
8203 [(parallel
8204 [(set (match_dup 0) (xor:QI (match_dup 0) (match_dup 1)))
8205 (clobber (reg:CC CC_REGNUM))])]
8206 "s390_narrow_logical_operator (XOR, &operands[0], &operands[1]);")
8207
8208 ;
8209 ; xorqi3 instruction pattern(s).
8210 ;
8211
8212 (define_insn "*xorqi3"
8213 [(set (match_operand:QI 0 "nonimmediate_operand" "=d,d,d,Q,S,Q")
8214 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,d,0,0,0")
8215 (match_operand:QI 2 "general_operand" "Os,d,d,n,n,Q")))
8216 (clobber (reg:CC CC_REGNUM))]
8217 "s390_logical_operator_ok_p (operands)"
8218 "@
8219 xilf\t%0,%b2
8220 xr\t%0,%2
8221 xrk\t%0,%1,%2
8222 xi\t%S0,%b2
8223 xiy\t%S0,%b2
8224 #"
8225 [(set_attr "op_type" "RIL,RR,RRF,SI,SIY,SS")
8226 (set_attr "cpu_facility" "*,*,z196,*,longdisp,*")
8227 (set_attr "z10prop" "z10_super_E1,z10_super_E1,*,z10_super,z10_super,*")])
8228
8229
8230 ;
8231 ; Block exclusive or (XC) patterns.
8232 ;
8233
8234 (define_insn "*xc"
8235 [(set (match_operand:BLK 0 "memory_operand" "=Q")
8236 (xor:BLK (match_dup 0)
8237 (match_operand:BLK 1 "memory_operand" "Q")))
8238 (use (match_operand 2 "const_int_operand" "n"))
8239 (clobber (reg:CC CC_REGNUM))]
8240 "INTVAL (operands[2]) >= 1 && INTVAL (operands[2]) <= 256"
8241 "xc\t%O0(%2,%R0),%S1"
8242 [(set_attr "op_type" "SS")])
8243
8244 (define_split
8245 [(set (match_operand 0 "memory_operand" "")
8246 (xor (match_dup 0)
8247 (match_operand 1 "memory_operand" "")))
8248 (clobber (reg:CC CC_REGNUM))]
8249 "reload_completed
8250 && GET_MODE (operands[0]) == GET_MODE (operands[1])
8251 && GET_MODE_SIZE (GET_MODE (operands[0])) > 0"
8252 [(parallel
8253 [(set (match_dup 0) (xor:BLK (match_dup 0) (match_dup 1)))
8254 (use (match_dup 2))
8255 (clobber (reg:CC CC_REGNUM))])]
8256 {
8257 operands[2] = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[0])));
8258 operands[0] = adjust_address (operands[0], BLKmode, 0);
8259 operands[1] = adjust_address (operands[1], BLKmode, 0);
8260 })
8261
8262 (define_peephole2
8263 [(parallel
8264 [(set (match_operand:BLK 0 "memory_operand" "")
8265 (xor:BLK (match_dup 0)
8266 (match_operand:BLK 1 "memory_operand" "")))
8267 (use (match_operand 2 "const_int_operand" ""))
8268 (clobber (reg:CC CC_REGNUM))])
8269 (parallel
8270 [(set (match_operand:BLK 3 "memory_operand" "")
8271 (xor:BLK (match_dup 3)
8272 (match_operand:BLK 4 "memory_operand" "")))
8273 (use (match_operand 5 "const_int_operand" ""))
8274 (clobber (reg:CC CC_REGNUM))])]
8275 "s390_offset_p (operands[0], operands[3], operands[2])
8276 && s390_offset_p (operands[1], operands[4], operands[2])
8277 && !s390_overlap_p (operands[0], operands[1],
8278 INTVAL (operands[2]) + INTVAL (operands[5]))
8279 && INTVAL (operands[2]) + INTVAL (operands[5]) <= 256"
8280 [(parallel
8281 [(set (match_dup 6) (xor:BLK (match_dup 6) (match_dup 7)))
8282 (use (match_dup 8))
8283 (clobber (reg:CC CC_REGNUM))])]
8284 "operands[6] = gen_rtx_MEM (BLKmode, XEXP (operands[0], 0));
8285 operands[7] = gen_rtx_MEM (BLKmode, XEXP (operands[1], 0));
8286 operands[8] = GEN_INT (INTVAL (operands[2]) + INTVAL (operands[5]));")
8287
8288 ;
8289 ; Block xor (XC) patterns with src == dest.
8290 ;
8291
8292 (define_insn "*xc_zero"
8293 [(set (match_operand:BLK 0 "memory_operand" "=Q")
8294 (const_int 0))
8295 (use (match_operand 1 "const_int_operand" "n"))
8296 (clobber (reg:CC CC_REGNUM))]
8297 "INTVAL (operands[1]) >= 1 && INTVAL (operands[1]) <= 256"
8298 "xc\t%O0(%1,%R0),%S0"
8299 [(set_attr "op_type" "SS")
8300 (set_attr "z196prop" "z196_cracked")])
8301
8302 (define_peephole2
8303 [(parallel
8304 [(set (match_operand:BLK 0 "memory_operand" "")
8305 (const_int 0))
8306 (use (match_operand 1 "const_int_operand" ""))
8307 (clobber (reg:CC CC_REGNUM))])
8308 (parallel
8309 [(set (match_operand:BLK 2 "memory_operand" "")
8310 (const_int 0))
8311 (use (match_operand 3 "const_int_operand" ""))
8312 (clobber (reg:CC CC_REGNUM))])]
8313 "s390_offset_p (operands[0], operands[2], operands[1])
8314 && INTVAL (operands[1]) + INTVAL (operands[3]) <= 256"
8315 [(parallel
8316 [(set (match_dup 4) (const_int 0))
8317 (use (match_dup 5))
8318 (clobber (reg:CC CC_REGNUM))])]
8319 "operands[4] = gen_rtx_MEM (BLKmode, XEXP (operands[0], 0));
8320 operands[5] = GEN_INT (INTVAL (operands[1]) + INTVAL (operands[3]));")
8321
8322
8323 ;;
8324 ;;- Negate instructions.
8325 ;;
8326
8327 ;
8328 ; neg(di|si)2 instruction pattern(s).
8329 ;
8330
8331 (define_expand "neg<mode>2"
8332 [(parallel
8333 [(set (match_operand:DSI 0 "register_operand" "=d")
8334 (neg:DSI (match_operand:DSI 1 "register_operand" "d")))
8335 (clobber (reg:CC CC_REGNUM))])]
8336 ""
8337 "")
8338
8339 (define_insn "*negdi2_sign_cc"
8340 [(set (reg CC_REGNUM)
8341 (compare (neg:DI (ashiftrt:DI (ashift:DI (subreg:DI
8342 (match_operand:SI 1 "register_operand" "d") 0)
8343 (const_int 32)) (const_int 32)))
8344 (const_int 0)))
8345 (set (match_operand:DI 0 "register_operand" "=d")
8346 (neg:DI (sign_extend:DI (match_dup 1))))]
8347 "TARGET_ZARCH && s390_match_ccmode (insn, CCAmode)"
8348 "lcgfr\t%0,%1"
8349 [(set_attr "op_type" "RRE")
8350 (set_attr "z10prop" "z10_c")])
8351
8352 (define_insn "*negdi2_sign"
8353 [(set (match_operand:DI 0 "register_operand" "=d")
8354 (neg:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "d"))))
8355 (clobber (reg:CC CC_REGNUM))]
8356 "TARGET_ZARCH"
8357 "lcgfr\t%0,%1"
8358 [(set_attr "op_type" "RRE")
8359 (set_attr "z10prop" "z10_c")])
8360
8361 ; lcr, lcgr
8362 (define_insn "*neg<mode>2_cc"
8363 [(set (reg CC_REGNUM)
8364 (compare (neg:GPR (match_operand:GPR 1 "register_operand" "d"))
8365 (const_int 0)))
8366 (set (match_operand:GPR 0 "register_operand" "=d")
8367 (neg:GPR (match_dup 1)))]
8368 "s390_match_ccmode (insn, CCAmode)"
8369 "lc<g>r\t%0,%1"
8370 [(set_attr "op_type" "RR<E>")
8371 (set_attr "z10prop" "z10_super_c_E1")])
8372
8373 ; lcr, lcgr
8374 (define_insn "*neg<mode>2_cconly"
8375 [(set (reg CC_REGNUM)
8376 (compare (neg:GPR (match_operand:GPR 1 "register_operand" "d"))
8377 (const_int 0)))
8378 (clobber (match_scratch:GPR 0 "=d"))]
8379 "s390_match_ccmode (insn, CCAmode)"
8380 "lc<g>r\t%0,%1"
8381 [(set_attr "op_type" "RR<E>")
8382 (set_attr "z10prop" "z10_super_c_E1")])
8383
8384 ; lcr, lcgr
8385 (define_insn "*neg<mode>2"
8386 [(set (match_operand:GPR 0 "register_operand" "=d")
8387 (neg:GPR (match_operand:GPR 1 "register_operand" "d")))
8388 (clobber (reg:CC CC_REGNUM))]
8389 ""
8390 "lc<g>r\t%0,%1"
8391 [(set_attr "op_type" "RR<E>")
8392 (set_attr "z10prop" "z10_super_c_E1")])
8393
8394 (define_insn "*negdi2_31"
8395 [(set (match_operand:DI 0 "register_operand" "=d")
8396 (neg:DI (match_operand:DI 1 "register_operand" "d")))
8397 (clobber (reg:CC CC_REGNUM))]
8398 "!TARGET_ZARCH"
8399 "#")
8400
8401 ; Split a DImode NEG on 31bit into 2 SImode NEGs
8402
8403 ; Doing the twos complement separately on the SImode parts does an
8404 ; unwanted +1 on the high part which needs to be subtracted afterwards
8405 ; ... unless the +1 on the low part created an overflow.
8406
8407 (define_split
8408 [(set (match_operand:DI 0 "register_operand" "")
8409 (neg:DI (match_operand:DI 1 "register_operand" "")))
8410 (clobber (reg:CC CC_REGNUM))]
8411 "!TARGET_ZARCH
8412 && (REGNO (operands[0]) == REGNO (operands[1])
8413 || s390_split_ok_p (operands[0], operands[1], DImode, 0))
8414 && reload_completed"
8415 [(parallel
8416 [(set (match_dup 2) (neg:SI (match_dup 3)))
8417 (clobber (reg:CC CC_REGNUM))])
8418 (parallel
8419 [(set (reg:CCAP CC_REGNUM)
8420 (compare:CCAP (neg:SI (match_dup 5)) (const_int 0)))
8421 (set (match_dup 4) (neg:SI (match_dup 5)))])
8422 (set (pc)
8423 (if_then_else (ne (reg:CCAP CC_REGNUM) (const_int 0))
8424 (pc)
8425 (label_ref (match_dup 6))))
8426 (parallel
8427 [(set (match_dup 2) (plus:SI (match_dup 2) (const_int -1)))
8428 (clobber (reg:CC CC_REGNUM))])
8429 (match_dup 6)]
8430 "operands[2] = operand_subword (operands[0], 0, 0, DImode);
8431 operands[3] = operand_subword (operands[1], 0, 0, DImode);
8432 operands[4] = operand_subword (operands[0], 1, 0, DImode);
8433 operands[5] = operand_subword (operands[1], 1, 0, DImode);
8434 operands[6] = gen_label_rtx ();")
8435
8436 ; Like above but first make a copy of the low part of the src operand
8437 ; since it might overlap with the high part of the destination.
8438
8439 (define_split
8440 [(set (match_operand:DI 0 "register_operand" "")
8441 (neg:DI (match_operand:DI 1 "register_operand" "")))
8442 (clobber (reg:CC CC_REGNUM))]
8443 "!TARGET_ZARCH
8444 && s390_split_ok_p (operands[0], operands[1], DImode, 1)
8445 && reload_completed"
8446 [; Make a backup of op5 first
8447 (set (match_dup 4) (match_dup 5))
8448 ; Setting op2 here might clobber op5
8449 (parallel
8450 [(set (match_dup 2) (neg:SI (match_dup 3)))
8451 (clobber (reg:CC CC_REGNUM))])
8452 (parallel
8453 [(set (reg:CCAP CC_REGNUM)
8454 (compare:CCAP (neg:SI (match_dup 4)) (const_int 0)))
8455 (set (match_dup 4) (neg:SI (match_dup 4)))])
8456 (set (pc)
8457 (if_then_else (ne (reg:CCAP CC_REGNUM) (const_int 0))
8458 (pc)
8459 (label_ref (match_dup 6))))
8460 (parallel
8461 [(set (match_dup 2) (plus:SI (match_dup 2) (const_int -1)))
8462 (clobber (reg:CC CC_REGNUM))])
8463 (match_dup 6)]
8464 "operands[2] = operand_subword (operands[0], 0, 0, DImode);
8465 operands[3] = operand_subword (operands[1], 0, 0, DImode);
8466 operands[4] = operand_subword (operands[0], 1, 0, DImode);
8467 operands[5] = operand_subword (operands[1], 1, 0, DImode);
8468 operands[6] = gen_label_rtx ();")
8469
8470 ;
8471 ; neg(df|sf)2 instruction pattern(s).
8472 ;
8473
8474 (define_expand "neg<mode>2"
8475 [(parallel
8476 [(set (match_operand:BFP 0 "register_operand")
8477 (neg:BFP (match_operand:BFP 1 "register_operand")))
8478 (clobber (reg:CC CC_REGNUM))])]
8479 "TARGET_HARD_FLOAT")
8480
8481 ; lcxbr, lcdbr, lcebr
8482 (define_insn "*neg<mode>2_cc"
8483 [(set (reg CC_REGNUM)
8484 (compare (neg:BFP (match_operand:BFP 1 "register_operand" "f"))
8485 (match_operand:BFP 2 "const0_operand" "")))
8486 (set (match_operand:BFP 0 "register_operand" "=f")
8487 (neg:BFP (match_dup 1)))]
8488 "s390_match_ccmode (insn, CCSmode) && TARGET_HARD_FLOAT"
8489 "lc<xde>br\t%0,%1"
8490 [(set_attr "op_type" "RRE")
8491 (set_attr "type" "fsimp<mode>")])
8492
8493 ; lcxbr, lcdbr, lcebr
8494 (define_insn "*neg<mode>2_cconly"
8495 [(set (reg CC_REGNUM)
8496 (compare (neg:BFP (match_operand:BFP 1 "register_operand" "f"))
8497 (match_operand:BFP 2 "const0_operand" "")))
8498 (clobber (match_scratch:BFP 0 "=f"))]
8499 "s390_match_ccmode (insn, CCSmode) && TARGET_HARD_FLOAT"
8500 "lc<xde>br\t%0,%1"
8501 [(set_attr "op_type" "RRE")
8502 (set_attr "type" "fsimp<mode>")])
8503
8504 ; lcdfr
8505 (define_insn "*neg<mode>2_nocc"
8506 [(set (match_operand:FP 0 "register_operand" "=f")
8507 (neg:FP (match_operand:FP 1 "register_operand" "<fT0>")))]
8508 "TARGET_DFP"
8509 "lcdfr\t%0,%1"
8510 [(set_attr "op_type" "RRE")
8511 (set_attr "type" "fsimp<mode>")])
8512
8513 ; lcxbr, lcdbr, lcebr
8514 ; FIXME: wflcdb does not clobber cc
8515 ; FIXME: Does wflcdb ever match here?
8516 (define_insn "*neg<mode>2"
8517 [(set (match_operand:BFP 0 "register_operand" "=f,v,v")
8518 (neg:BFP (match_operand:BFP 1 "register_operand" "f,v,v")))
8519 (clobber (reg:CC CC_REGNUM))]
8520 "TARGET_HARD_FLOAT"
8521 "@
8522 lc<xde>br\t%0,%1
8523 wflcdb\t%0,%1
8524 wflcsb\t%0,%1"
8525 [(set_attr "op_type" "RRE,VRR,VRR")
8526 (set_attr "cpu_facility" "*,vx,vxe")
8527 (set_attr "type" "fsimp<mode>,*,*")
8528 (set_attr "enabled" "*,<DF>,<SF>")])
8529
8530
8531 ;;
8532 ;;- Absolute value instructions.
8533 ;;
8534
8535 ;
8536 ; abs(di|si)2 instruction pattern(s).
8537 ;
8538
8539 (define_insn "*absdi2_sign_cc"
8540 [(set (reg CC_REGNUM)
8541 (compare (abs:DI (ashiftrt:DI (ashift:DI (subreg:DI
8542 (match_operand:SI 1 "register_operand" "d") 0)
8543 (const_int 32)) (const_int 32)))
8544 (const_int 0)))
8545 (set (match_operand:DI 0 "register_operand" "=d")
8546 (abs:DI (sign_extend:DI (match_dup 1))))]
8547 "TARGET_ZARCH && s390_match_ccmode (insn, CCAmode)"
8548 "lpgfr\t%0,%1"
8549 [(set_attr "op_type" "RRE")
8550 (set_attr "z10prop" "z10_c")])
8551
8552 (define_insn "*absdi2_sign"
8553 [(set (match_operand:DI 0 "register_operand" "=d")
8554 (abs:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "d"))))
8555 (clobber (reg:CC CC_REGNUM))]
8556 "TARGET_ZARCH"
8557 "lpgfr\t%0,%1"
8558 [(set_attr "op_type" "RRE")
8559 (set_attr "z10prop" "z10_c")])
8560
8561 ; lpr, lpgr
8562 (define_insn "*abs<mode>2_cc"
8563 [(set (reg CC_REGNUM)
8564 (compare (abs:GPR (match_operand:DI 1 "register_operand" "d"))
8565 (const_int 0)))
8566 (set (match_operand:GPR 0 "register_operand" "=d")
8567 (abs:GPR (match_dup 1)))]
8568 "s390_match_ccmode (insn, CCAmode)"
8569 "lp<g>r\t%0,%1"
8570 [(set_attr "op_type" "RR<E>")
8571 (set_attr "z10prop" "z10_c")])
8572
8573 ; lpr, lpgr
8574 (define_insn "*abs<mode>2_cconly"
8575 [(set (reg CC_REGNUM)
8576 (compare (abs:GPR (match_operand:GPR 1 "register_operand" "d"))
8577 (const_int 0)))
8578 (clobber (match_scratch:GPR 0 "=d"))]
8579 "s390_match_ccmode (insn, CCAmode)"
8580 "lp<g>r\t%0,%1"
8581 [(set_attr "op_type" "RR<E>")
8582 (set_attr "z10prop" "z10_c")])
8583
8584 ; lpr, lpgr
8585 (define_insn "abs<mode>2"
8586 [(set (match_operand:GPR 0 "register_operand" "=d")
8587 (abs:GPR (match_operand:GPR 1 "register_operand" "d")))
8588 (clobber (reg:CC CC_REGNUM))]
8589 ""
8590 "lp<g>r\t%0,%1"
8591 [(set_attr "op_type" "RR<E>")
8592 (set_attr "z10prop" "z10_c")])
8593
8594 ;
8595 ; abs(df|sf)2 instruction pattern(s).
8596 ;
8597
8598 (define_expand "abs<mode>2"
8599 [(parallel
8600 [(set (match_operand:BFP 0 "register_operand" "=f")
8601 (abs:BFP (match_operand:BFP 1 "register_operand" "f")))
8602 (clobber (reg:CC CC_REGNUM))])]
8603 "TARGET_HARD_FLOAT"
8604 "")
8605
8606 ; lpxbr, lpdbr, lpebr
8607 (define_insn "*abs<mode>2_cc"
8608 [(set (reg CC_REGNUM)
8609 (compare (abs:BFP (match_operand:BFP 1 "register_operand" "f"))
8610 (match_operand:BFP 2 "const0_operand" "")))
8611 (set (match_operand:BFP 0 "register_operand" "=f")
8612 (abs:BFP (match_dup 1)))]
8613 "s390_match_ccmode (insn, CCSmode) && TARGET_HARD_FLOAT"
8614 "lp<xde>br\t%0,%1"
8615 [(set_attr "op_type" "RRE")
8616 (set_attr "type" "fsimp<mode>")])
8617
8618 ; lpxbr, lpdbr, lpebr
8619 (define_insn "*abs<mode>2_cconly"
8620 [(set (reg CC_REGNUM)
8621 (compare (abs:BFP (match_operand:BFP 1 "register_operand" "f"))
8622 (match_operand:BFP 2 "const0_operand" "")))
8623 (clobber (match_scratch:BFP 0 "=f"))]
8624 "s390_match_ccmode (insn, CCSmode) && TARGET_HARD_FLOAT"
8625 "lp<xde>br\t%0,%1"
8626 [(set_attr "op_type" "RRE")
8627 (set_attr "type" "fsimp<mode>")])
8628
8629 ; lpdfr
8630 (define_insn "*abs<mode>2_nocc"
8631 [(set (match_operand:FP 0 "register_operand" "=f")
8632 (abs:FP (match_operand:FP 1 "register_operand" "<fT0>")))]
8633 "TARGET_DFP"
8634 "lpdfr\t%0,%1"
8635 [(set_attr "op_type" "RRE")
8636 (set_attr "type" "fsimp<mode>")])
8637
8638 ; lpxbr, lpdbr, lpebr
8639 ; FIXME: wflpdb does not clobber cc
8640 (define_insn "*abs<mode>2"
8641 [(set (match_operand:BFP 0 "register_operand" "=f,v")
8642 (abs:BFP (match_operand:BFP 1 "register_operand" "f,v")))
8643 (clobber (reg:CC CC_REGNUM))]
8644 "TARGET_HARD_FLOAT"
8645 "@
8646 lp<xde>br\t%0,%1
8647 wflpdb\t%0,%1"
8648 [(set_attr "op_type" "RRE,VRR")
8649 (set_attr "cpu_facility" "*,vx")
8650 (set_attr "type" "fsimp<mode>,*")
8651 (set_attr "enabled" "*,<DFDI>")])
8652
8653
8654 ;;
8655 ;;- Negated absolute value instructions
8656 ;;
8657
8658 ;
8659 ; Integer
8660 ;
8661
8662 (define_insn "*negabsdi2_sign_cc"
8663 [(set (reg CC_REGNUM)
8664 (compare (neg:DI (abs:DI (ashiftrt:DI (ashift:DI (subreg:DI
8665 (match_operand:SI 1 "register_operand" "d") 0)
8666 (const_int 32)) (const_int 32))))
8667 (const_int 0)))
8668 (set (match_operand:DI 0 "register_operand" "=d")
8669 (neg:DI (abs:DI (sign_extend:DI (match_dup 1)))))]
8670 "TARGET_ZARCH && s390_match_ccmode (insn, CCAmode)"
8671 "lngfr\t%0,%1"
8672 [(set_attr "op_type" "RRE")
8673 (set_attr "z10prop" "z10_c")])
8674
8675 (define_insn "*negabsdi2_sign"
8676 [(set (match_operand:DI 0 "register_operand" "=d")
8677 (neg:DI (abs:DI (sign_extend:DI
8678 (match_operand:SI 1 "register_operand" "d")))))
8679 (clobber (reg:CC CC_REGNUM))]
8680 "TARGET_ZARCH"
8681 "lngfr\t%0,%1"
8682 [(set_attr "op_type" "RRE")
8683 (set_attr "z10prop" "z10_c")])
8684
8685 ; lnr, lngr
8686 (define_insn "*negabs<mode>2_cc"
8687 [(set (reg CC_REGNUM)
8688 (compare (neg:GPR (abs:GPR (match_operand:GPR 1 "register_operand" "d")))
8689 (const_int 0)))
8690 (set (match_operand:GPR 0 "register_operand" "=d")
8691 (neg:GPR (abs:GPR (match_dup 1))))]
8692 "s390_match_ccmode (insn, CCAmode)"
8693 "ln<g>r\t%0,%1"
8694 [(set_attr "op_type" "RR<E>")
8695 (set_attr "z10prop" "z10_c")])
8696
8697 ; lnr, lngr
8698 (define_insn "*negabs<mode>2_cconly"
8699 [(set (reg CC_REGNUM)
8700 (compare (neg:GPR (abs:GPR (match_operand:GPR 1 "register_operand" "d")))
8701 (const_int 0)))
8702 (clobber (match_scratch:GPR 0 "=d"))]
8703 "s390_match_ccmode (insn, CCAmode)"
8704 "ln<g>r\t%0,%1"
8705 [(set_attr "op_type" "RR<E>")
8706 (set_attr "z10prop" "z10_c")])
8707
8708 ; lnr, lngr
8709 (define_insn "*negabs<mode>2"
8710 [(set (match_operand:GPR 0 "register_operand" "=d")
8711 (neg:GPR (abs:GPR (match_operand:GPR 1 "register_operand" "d"))))
8712 (clobber (reg:CC CC_REGNUM))]
8713 ""
8714 "ln<g>r\t%0,%1"
8715 [(set_attr "op_type" "RR<E>")
8716 (set_attr "z10prop" "z10_c")])
8717
8718 ;
8719 ; Floating point
8720 ;
8721
8722 ; lnxbr, lndbr, lnebr
8723 (define_insn "*negabs<mode>2_cc"
8724 [(set (reg CC_REGNUM)
8725 (compare (neg:BFP (abs:BFP (match_operand:BFP 1 "register_operand" "f")))
8726 (match_operand:BFP 2 "const0_operand" "")))
8727 (set (match_operand:BFP 0 "register_operand" "=f")
8728 (neg:BFP (abs:BFP (match_dup 1))))]
8729 "s390_match_ccmode (insn, CCSmode) && TARGET_HARD_FLOAT"
8730 "ln<xde>br\t%0,%1"
8731 [(set_attr "op_type" "RRE")
8732 (set_attr "type" "fsimp<mode>")])
8733
8734 ; lnxbr, lndbr, lnebr
8735 (define_insn "*negabs<mode>2_cconly"
8736 [(set (reg CC_REGNUM)
8737 (compare (neg:BFP (abs:BFP (match_operand:BFP 1 "register_operand" "f")))
8738 (match_operand:BFP 2 "const0_operand" "")))
8739 (clobber (match_scratch:BFP 0 "=f"))]
8740 "s390_match_ccmode (insn, CCSmode) && TARGET_HARD_FLOAT"
8741 "ln<xde>br\t%0,%1"
8742 [(set_attr "op_type" "RRE")
8743 (set_attr "type" "fsimp<mode>")])
8744
8745 ; lndfr
8746 (define_insn "*negabs<mode>2_nocc"
8747 [(set (match_operand:FP 0 "register_operand" "=f")
8748 (neg:FP (abs:FP (match_operand:BFP 1 "register_operand" "<fT0>"))))]
8749 "TARGET_DFP"
8750 "lndfr\t%0,%1"
8751 [(set_attr "op_type" "RRE")
8752 (set_attr "type" "fsimp<mode>")])
8753
8754 ; lnxbr, lndbr, lnebr
8755 ; FIXME: wflndb does not clobber cc
8756 (define_insn "*negabs<mode>2"
8757 [(set (match_operand:BFP 0 "register_operand" "=f,v")
8758 (neg:BFP (abs:BFP (match_operand:BFP 1 "register_operand" "f,v"))))
8759 (clobber (reg:CC CC_REGNUM))]
8760 "TARGET_HARD_FLOAT"
8761 "@
8762 ln<xde>br\t%0,%1
8763 wflndb\t%0,%1"
8764 [(set_attr "op_type" "RRE,VRR")
8765 (set_attr "cpu_facility" "*,vx")
8766 (set_attr "type" "fsimp<mode>,*")
8767 (set_attr "enabled" "*,<DFDI>")])
8768
8769 ;;
8770 ;;- Square root instructions.
8771 ;;
8772
8773 ;
8774 ; sqrt(df|sf)2 instruction pattern(s).
8775 ;
8776
8777 ; sqxbr, sqdbr, sqebr, sqdb, sqeb
8778 (define_insn "sqrt<mode>2"
8779 [(set (match_operand:BFP 0 "register_operand" "=f,f,v")
8780 (sqrt:BFP (match_operand:BFP 1 "general_operand" "f,R,v")))]
8781 "TARGET_HARD_FLOAT"
8782 "@
8783 sq<xde>br\t%0,%1
8784 sq<xde>b\t%0,%1
8785 wfsqdb\t%v0,%v1"
8786 [(set_attr "op_type" "RRE,RXE,VRR")
8787 (set_attr "type" "fsqrt<mode>")
8788 (set_attr "cpu_facility" "*,*,vx")
8789 (set_attr "enabled" "*,<DSF>,<DFDI>")])
8790
8791
8792 ;;
8793 ;;- One complement instructions.
8794 ;;
8795
8796 ;
8797 ; one_cmpl(di|si|hi|qi)2 instruction pattern(s).
8798 ;
8799
8800 (define_expand "one_cmpl<mode>2"
8801 [(parallel
8802 [(set (match_operand:INT 0 "register_operand" "")
8803 (xor:INT (match_operand:INT 1 "register_operand" "")
8804 (const_int -1)))
8805 (clobber (reg:CC CC_REGNUM))])]
8806 ""
8807 "")
8808
8809
8810 ;;
8811 ;; Find leftmost bit instructions.
8812 ;;
8813
8814 (define_expand "clzdi2"
8815 [(set (match_operand:DI 0 "register_operand" "=d")
8816 (clz:DI (match_operand:DI 1 "register_operand" "d")))]
8817 "TARGET_EXTIMM && TARGET_ZARCH"
8818 {
8819 rtx_insn *insn;
8820 rtx clz_equal;
8821 rtx wide_reg = gen_reg_rtx (TImode);
8822 rtx msb = gen_rtx_CONST_INT (DImode, HOST_WIDE_INT_1U << 63);
8823
8824 clz_equal = gen_rtx_CLZ (DImode, operands[1]);
8825
8826 emit_insn (gen_clztidi2 (wide_reg, operands[1], msb));
8827
8828 insn = emit_move_insn (operands[0], gen_highpart (DImode, wide_reg));
8829 set_unique_reg_note (insn, REG_EQUAL, clz_equal);
8830
8831 DONE;
8832 })
8833
8834 (define_insn "clztidi2"
8835 [(set (match_operand:TI 0 "register_operand" "=d")
8836 (ior:TI
8837 (ashift:TI
8838 (zero_extend:TI
8839 (xor:DI (match_operand:DI 1 "register_operand" "d")
8840 (lshiftrt (match_operand:DI 2 "const_int_operand" "")
8841 (subreg:SI (clz:DI (match_dup 1)) 4))))
8842
8843 (const_int 64))
8844 (zero_extend:TI (clz:DI (match_dup 1)))))
8845 (clobber (reg:CC CC_REGNUM))]
8846 "UINTVAL (operands[2]) == HOST_WIDE_INT_1U << 63
8847 && TARGET_EXTIMM && TARGET_ZARCH"
8848 "flogr\t%0,%1"
8849 [(set_attr "op_type" "RRE")])
8850
8851
8852 ;;
8853 ;;- Rotate instructions.
8854 ;;
8855
8856 ;
8857 ; rotl(di|si)3 instruction pattern(s).
8858 ;
8859
8860 (define_expand "rotl<mode>3"
8861 [(set (match_operand:GPR 0 "register_operand" "")
8862 (rotate:GPR (match_operand:GPR 1 "register_operand" "")
8863 (match_operand:SI 2 "nonmemory_operand" "")))]
8864 "TARGET_CPU_ZARCH"
8865 "")
8866
8867 ; rll, rllg
8868 (define_insn "*rotl<mode>3<addr_style_op><masked_op>"
8869 [(set (match_operand:GPR 0 "register_operand" "=d")
8870 (rotate:GPR (match_operand:GPR 1 "register_operand" "d")
8871 (match_operand:SI 2 "nonmemory_operand" "an")))]
8872 "TARGET_CPU_ZARCH"
8873 "rll<g>\t%0,%1,<addr_style_op_ops>"
8874 [(set_attr "op_type" "RSE")
8875 (set_attr "atype" "reg")
8876 (set_attr "z10prop" "z10_super_E1")])
8877
8878
8879 ;;
8880 ;;- Shift instructions.
8881 ;;
8882
8883 ;
8884 ; (ashl|lshr)(di|si)3 instruction pattern(s).
8885 ; Left shifts and logical right shifts
8886
8887 (define_expand "<shift><mode>3"
8888 [(set (match_operand:DSI 0 "register_operand" "")
8889 (SHIFT:DSI (match_operand:DSI 1 "register_operand" "")
8890 (match_operand:SI 2 "nonmemory_operand" "")))]
8891 ""
8892 "")
8893
8894 ; ESA 64 bit register pair shift with reg or imm shift count
8895 ; sldl, srdl
8896 (define_insn "*<shift>di3_31<addr_style_op><masked_op>"
8897 [(set (match_operand:DI 0 "register_operand" "=d")
8898 (SHIFT:DI (match_operand:DI 1 "register_operand" "0")
8899 (match_operand:SI 2 "nonmemory_operand" "an")))]
8900 "!TARGET_ZARCH"
8901 "s<lr>dl\t%0,<addr_style_op_ops>"
8902 [(set_attr "op_type" "RS")
8903 (set_attr "atype" "reg")
8904 (set_attr "z196prop" "z196_cracked")])
8905
8906
8907 ; 64 bit register shift with reg or imm shift count
8908 ; sll, srl, sllg, srlg, sllk, srlk
8909 (define_insn "*<shift><mode>3<addr_style_op><masked_op>"
8910 [(set (match_operand:GPR 0 "register_operand" "=d, d")
8911 (SHIFT:GPR (match_operand:GPR 1 "register_operand" "<d0>, d")
8912 (match_operand:SI 2 "nonmemory_operand" "an,an")))]
8913 ""
8914 "@
8915 s<lr>l<g>\t%0,<1><addr_style_op_ops>
8916 s<lr>l<gk>\t%0,%1,<addr_style_op_ops>"
8917 [(set_attr "op_type" "RS<E>,RSY")
8918 (set_attr "atype" "reg,reg")
8919 (set_attr "cpu_facility" "*,z196")
8920 (set_attr "z10prop" "z10_super_E1,*")])
8921
8922 ;
8923 ; ashr(di|si)3 instruction pattern(s).
8924 ; Arithmetic right shifts
8925
8926 (define_expand "ashr<mode>3"
8927 [(parallel
8928 [(set (match_operand:DSI 0 "register_operand" "")
8929 (ashiftrt:DSI (match_operand:DSI 1 "register_operand" "")
8930 (match_operand:SI 2 "nonmemory_operand" "")))
8931 (clobber (reg:CC CC_REGNUM))])]
8932 ""
8933 "")
8934
8935 ; FIXME: The number of alternatives is doubled here to match the fix
8936 ; number of 2 in the subst pattern for the (clobber (match_scratch...
8937 ; The right fix should be to support match_scratch in the output
8938 ; pattern of a define_subst.
8939 (define_insn "*ashrdi3_31<addr_style_op_cc><masked_op_cc><setcc><cconly>"
8940 [(set (match_operand:DI 0 "register_operand" "=d, d")
8941 (ashiftrt:DI (match_operand:DI 1 "register_operand" "0, 0")
8942 (match_operand:SI 2 "nonmemory_operand" "an,an")))
8943 (clobber (reg:CC CC_REGNUM))]
8944 "!TARGET_ZARCH"
8945 "@
8946 srda\t%0,<addr_style_op_cc_ops>
8947 srda\t%0,<addr_style_op_cc_ops>"
8948 [(set_attr "op_type" "RS")
8949 (set_attr "atype" "reg")])
8950
8951
8952 ; sra, srag
8953 (define_insn "*ashr<mode>3<addr_style_op_cc><masked_op_cc><setcc><cconly>"
8954 [(set (match_operand:GPR 0 "register_operand" "=d, d")
8955 (ashiftrt:GPR (match_operand:GPR 1 "register_operand" "<d0>, d")
8956 (match_operand:SI 2 "nonmemory_operand" "an,an")))
8957 (clobber (reg:CC CC_REGNUM))]
8958 ""
8959 "@
8960 sra<g>\t%0,<1><addr_style_op_cc_ops>
8961 sra<gk>\t%0,%1,<addr_style_op_cc_ops>"
8962 [(set_attr "op_type" "RS<E>,RSY")
8963 (set_attr "atype" "reg")
8964 (set_attr "cpu_facility" "*,z196")
8965 (set_attr "z10prop" "z10_super_E1,*")])
8966
8967
8968 ;;
8969 ;; Branch instruction patterns.
8970 ;;
8971
8972 (define_expand "cbranch<mode>4"
8973 [(set (pc)
8974 (if_then_else (match_operator 0 "comparison_operator"
8975 [(match_operand:GPR 1 "register_operand" "")
8976 (match_operand:GPR 2 "general_operand" "")])
8977 (label_ref (match_operand 3 "" ""))
8978 (pc)))]
8979 ""
8980 "s390_emit_jump (operands[3],
8981 s390_emit_compare (GET_CODE (operands[0]), operands[1], operands[2]));
8982 DONE;")
8983
8984 (define_expand "cbranch<mode>4"
8985 [(set (pc)
8986 (if_then_else (match_operator 0 "comparison_operator"
8987 [(match_operand:FP 1 "register_operand" "")
8988 (match_operand:FP 2 "general_operand" "")])
8989 (label_ref (match_operand 3 "" ""))
8990 (pc)))]
8991 "TARGET_HARD_FLOAT"
8992 "s390_emit_jump (operands[3],
8993 s390_emit_compare (GET_CODE (operands[0]), operands[1], operands[2]));
8994 DONE;")
8995
8996 (define_expand "cbranchcc4"
8997 [(set (pc)
8998 (if_then_else (match_operator 0 "s390_comparison"
8999 [(match_operand 1 "cc_reg_operand" "")
9000 (match_operand 2 "const_int_operand" "")])
9001 (label_ref (match_operand 3 "" ""))
9002 (pc)))]
9003 ""
9004 "")
9005
9006
9007 ;;
9008 ;;- Conditional jump instructions.
9009 ;;
9010
9011 (define_insn "*cjump_64"
9012 [(set (pc)
9013 (if_then_else
9014 (match_operator 1 "s390_comparison" [(reg CC_REGNUM)
9015 (match_operand 2 "const_int_operand" "")])
9016 (label_ref (match_operand 0 "" ""))
9017 (pc)))]
9018 "TARGET_CPU_ZARCH"
9019 {
9020 if (get_attr_length (insn) == 4)
9021 return "j%C1\t%l0";
9022 else
9023 return "jg%C1\t%l0";
9024 }
9025 [(set_attr "op_type" "RI")
9026 (set_attr "type" "branch")
9027 (set (attr "length")
9028 (if_then_else (lt (abs (minus (pc) (match_dup 0))) (const_int 60000))
9029 (const_int 4) (const_int 6)))])
9030
9031 (define_insn "*cjump_31"
9032 [(set (pc)
9033 (if_then_else
9034 (match_operator 1 "s390_comparison" [(reg CC_REGNUM)
9035 (match_operand 2 "const_int_operand" "")])
9036 (label_ref (match_operand 0 "" ""))
9037 (pc)))]
9038 "!TARGET_CPU_ZARCH"
9039 {
9040 gcc_assert (get_attr_length (insn) == 4);
9041 return "j%C1\t%l0";
9042 }
9043 [(set_attr "op_type" "RI")
9044 (set_attr "type" "branch")
9045 (set (attr "length")
9046 (if_then_else (not (match_test "flag_pic"))
9047 (if_then_else (lt (abs (minus (pc) (match_dup 0))) (const_int 60000))
9048 (const_int 4) (const_int 6))
9049 (if_then_else (lt (abs (minus (pc) (match_dup 0))) (const_int 60000))
9050 (const_int 4) (const_int 8))))])
9051
9052 (define_insn "*cjump_long"
9053 [(set (pc)
9054 (if_then_else
9055 (match_operator 1 "s390_comparison" [(reg CC_REGNUM) (const_int 0)])
9056 (match_operand 0 "address_operand" "ZQZR")
9057 (pc)))]
9058 ""
9059 {
9060 if (get_attr_op_type (insn) == OP_TYPE_RR)
9061 return "b%C1r\t%0";
9062 else
9063 return "b%C1\t%a0";
9064 }
9065 [(set (attr "op_type")
9066 (if_then_else (match_operand 0 "register_operand" "")
9067 (const_string "RR") (const_string "RX")))
9068 (set_attr "type" "branch")
9069 (set_attr "atype" "agen")])
9070
9071 ;; A conditional return instruction.
9072 (define_insn "*c<code>"
9073 [(set (pc)
9074 (if_then_else
9075 (match_operator 0 "s390_comparison" [(reg CC_REGNUM) (const_int 0)])
9076 (ANY_RETURN)
9077 (pc)))]
9078 "s390_can_use_<code>_insn ()"
9079 "b%C0r\t%%r14"
9080 [(set_attr "op_type" "RR")
9081 (set_attr "type" "jsr")
9082 (set_attr "atype" "agen")])
9083
9084 ;;
9085 ;;- Negated conditional jump instructions.
9086 ;;
9087
9088 (define_insn "*icjump_64"
9089 [(set (pc)
9090 (if_then_else
9091 (match_operator 1 "s390_comparison" [(reg CC_REGNUM) (const_int 0)])
9092 (pc)
9093 (label_ref (match_operand 0 "" ""))))]
9094 "TARGET_CPU_ZARCH"
9095 {
9096 if (get_attr_length (insn) == 4)
9097 return "j%D1\t%l0";
9098 else
9099 return "jg%D1\t%l0";
9100 }
9101 [(set_attr "op_type" "RI")
9102 (set_attr "type" "branch")
9103 (set (attr "length")
9104 (if_then_else (lt (abs (minus (pc) (match_dup 0))) (const_int 60000))
9105 (const_int 4) (const_int 6)))])
9106
9107 (define_insn "*icjump_31"
9108 [(set (pc)
9109 (if_then_else
9110 (match_operator 1 "s390_comparison" [(reg CC_REGNUM) (const_int 0)])
9111 (pc)
9112 (label_ref (match_operand 0 "" ""))))]
9113 "!TARGET_CPU_ZARCH"
9114 {
9115 gcc_assert (get_attr_length (insn) == 4);
9116 return "j%D1\t%l0";
9117 }
9118 [(set_attr "op_type" "RI")
9119 (set_attr "type" "branch")
9120 (set (attr "length")
9121 (if_then_else (not (match_test "flag_pic"))
9122 (if_then_else (lt (abs (minus (pc) (match_dup 0))) (const_int 60000))
9123 (const_int 4) (const_int 6))
9124 (if_then_else (lt (abs (minus (pc) (match_dup 0))) (const_int 60000))
9125 (const_int 4) (const_int 8))))])
9126
9127 (define_insn "*icjump_long"
9128 [(set (pc)
9129 (if_then_else
9130 (match_operator 1 "s390_comparison" [(reg CC_REGNUM) (const_int 0)])
9131 (pc)
9132 (match_operand 0 "address_operand" "ZQZR")))]
9133 ""
9134 {
9135 if (get_attr_op_type (insn) == OP_TYPE_RR)
9136 return "b%D1r\t%0";
9137 else
9138 return "b%D1\t%a0";
9139 }
9140 [(set (attr "op_type")
9141 (if_then_else (match_operand 0 "register_operand" "")
9142 (const_string "RR") (const_string "RX")))
9143 (set_attr "type" "branch")
9144 (set_attr "atype" "agen")])
9145
9146 ;;
9147 ;;- Trap instructions.
9148 ;;
9149
9150 (define_insn "trap"
9151 [(trap_if (const_int 1) (const_int 0))]
9152 ""
9153 "j\t.+2"
9154 [(set_attr "op_type" "RI")
9155 (set_attr "type" "branch")])
9156
9157 (define_expand "ctrap<mode>4"
9158 [(trap_if (match_operator 0 "comparison_operator"
9159 [(match_operand:GPR 1 "register_operand" "")
9160 (match_operand:GPR 2 "general_operand" "")])
9161 (match_operand 3 "const0_operand" ""))]
9162 ""
9163 {
9164 rtx cond = s390_emit_compare (GET_CODE (operands[0]),
9165 operands[1], operands[2]);
9166 emit_insn (gen_condtrap (cond, XEXP (cond, 0)));
9167 DONE;
9168 })
9169
9170 (define_expand "ctrap<mode>4"
9171 [(trap_if (match_operator 0 "comparison_operator"
9172 [(match_operand:FP 1 "register_operand" "")
9173 (match_operand:FP 2 "general_operand" "")])
9174 (match_operand 3 "const0_operand" ""))]
9175 ""
9176 {
9177 rtx cond = s390_emit_compare (GET_CODE (operands[0]),
9178 operands[1], operands[2]);
9179 emit_insn (gen_condtrap (cond, XEXP (cond, 0)));
9180 DONE;
9181 })
9182
9183 (define_insn "condtrap"
9184 [(trap_if (match_operator 0 "s390_comparison"
9185 [(match_operand 1 "cc_reg_operand" "c")
9186 (const_int 0)])
9187 (const_int 0))]
9188 ""
9189 "j%C0\t.+2";
9190 [(set_attr "op_type" "RI")
9191 (set_attr "type" "branch")])
9192
9193 ; crt, cgrt, cit, cgit
9194 (define_insn "*cmp_and_trap_signed_int<mode>"
9195 [(trap_if (match_operator 0 "s390_signed_integer_comparison"
9196 [(match_operand:GPR 1 "register_operand" "d,d")
9197 (match_operand:GPR 2 "nonmemory_operand" "d,K")])
9198 (const_int 0))]
9199 "TARGET_Z10"
9200 "@
9201 c<g>rt%C0\t%1,%2
9202 c<g>it%C0\t%1,%h2"
9203 [(set_attr "op_type" "RRF,RIE")
9204 (set_attr "type" "branch")
9205 (set_attr "z10prop" "z10_super_c,z10_super")])
9206
9207 ; clrt, clgrt, clfit, clgit, clt, clgt
9208 (define_insn "*cmp_and_trap_unsigned_int<mode>"
9209 [(trap_if (match_operator 0 "s390_unsigned_integer_comparison"
9210 [(match_operand:GPR 1 "register_operand" "d,d,d")
9211 (match_operand:GPR 2 "general_operand" "d,D,T")])
9212 (const_int 0))]
9213 "TARGET_Z10"
9214 "@
9215 cl<g>rt%C0\t%1,%2
9216 cl<gf>it%C0\t%1,%x2
9217 cl<g>t%C0\t%1,%2"
9218 [(set_attr "op_type" "RRF,RIE,RSY")
9219 (set_attr "type" "branch")
9220 (set_attr "z10prop" "z10_super_c,z10_super,*")
9221 (set_attr "cpu_facility" "z10,z10,zEC12")])
9222
9223 ; lat, lgat
9224 (define_insn "*load_and_trap<mode>"
9225 [(trap_if (eq (match_operand:GPR 0 "memory_operand" "T")
9226 (const_int 0))
9227 (const_int 0))
9228 (set (match_operand:GPR 1 "register_operand" "=d")
9229 (match_dup 0))]
9230 "TARGET_ZEC12"
9231 "l<g>at\t%1,%0"
9232 [(set_attr "op_type" "RXY")])
9233
9234
9235 ;;
9236 ;;- Loop instructions.
9237 ;;
9238 ;; This is all complicated by the fact that since this is a jump insn
9239 ;; we must handle our own output reloads.
9240
9241 ;; branch on index
9242
9243 ; This splitter will be matched by combine and has to add the 2 moves
9244 ; necessary to load the compare and the increment values into a
9245 ; register pair as needed by brxle.
9246
9247 (define_insn_and_split "*brx_stage1_<GPR:mode>"
9248 [(set (pc)
9249 (if_then_else
9250 (match_operator 6 "s390_brx_operator"
9251 [(plus:GPR (match_operand:GPR 1 "register_operand" "")
9252 (match_operand:GPR 2 "general_operand" ""))
9253 (match_operand:GPR 3 "register_operand" "")])
9254 (label_ref (match_operand 0 "" ""))
9255 (pc)))
9256 (set (match_operand:GPR 4 "nonimmediate_operand" "")
9257 (plus:GPR (match_dup 1) (match_dup 2)))
9258 (clobber (match_scratch:GPR 5 ""))]
9259 "TARGET_CPU_ZARCH"
9260 "#"
9261 "!reload_completed && !reload_in_progress"
9262 [(set (match_dup 7) (match_dup 2)) ; the increment
9263 (set (match_dup 8) (match_dup 3)) ; the comparison value
9264 (parallel [(set (pc)
9265 (if_then_else
9266 (match_op_dup 6
9267 [(plus:GPR (match_dup 1) (match_dup 7))
9268 (match_dup 8)])
9269 (label_ref (match_dup 0))
9270 (pc)))
9271 (set (match_dup 4)
9272 (plus:GPR (match_dup 1) (match_dup 7)))
9273 (clobber (match_dup 5))
9274 (clobber (reg:CC CC_REGNUM))])]
9275 {
9276 rtx dreg = gen_reg_rtx (word_mode == DImode ? TImode : DImode);
9277 operands[7] = gen_lowpart (<GPR:MODE>mode,
9278 gen_highpart (word_mode, dreg));
9279 operands[8] = gen_lowpart (<GPR:MODE>mode,
9280 gen_lowpart (word_mode, dreg));
9281 })
9282
9283 ; brxlg, brxhg
9284
9285 (define_insn_and_split "*brxg_64bit"
9286 [(set (pc)
9287 (if_then_else
9288 (match_operator 5 "s390_brx_operator"
9289 [(plus:DI (match_operand:DI 1 "register_operand" "d,d,d")
9290 (subreg:DI (match_operand:TI 2 "register_operand" "d,d,d") 0))
9291 (subreg:DI (match_dup 2) 8)])
9292 (label_ref (match_operand 0 "" ""))
9293 (pc)))
9294 (set (match_operand:DI 3 "nonimmediate_operand" "=1,?X,?X")
9295 (plus:DI (match_dup 1)
9296 (subreg:DI (match_dup 2) 0)))
9297 (clobber (match_scratch:DI 4 "=X,&1,&?d"))
9298 (clobber (reg:CC CC_REGNUM))]
9299 "TARGET_ZARCH"
9300 {
9301 if (which_alternative != 0)
9302 return "#";
9303 else if (get_attr_length (insn) == 6)
9304 return "brx%E5g\t%1,%2,%l0";
9305 else
9306 return "agr\t%1,%2\;cgr\t%1,%M2\;jg%C5\t%l0";
9307 }
9308 "&& reload_completed
9309 && (!REG_P (operands[3])
9310 || !rtx_equal_p (operands[1], operands[3]))"
9311 [(set (match_dup 4) (match_dup 1))
9312 (parallel [(set (match_dup 4) (plus:DI (match_dup 4) (subreg:DI (match_dup 2) 0)))
9313 (clobber (reg:CC CC_REGNUM))])
9314 (set (reg:CCS CC_REGNUM) (compare:CCS (match_dup 4) (subreg:DI (match_dup 2) 8)))
9315 (set (match_dup 3) (match_dup 4))
9316 (set (pc) (if_then_else (match_op_dup 5 [(reg:CCS CC_REGNUM) (const_int 0)])
9317 (label_ref (match_dup 0))
9318 (pc)))]
9319 ""
9320 [(set_attr "op_type" "RIE")
9321 (set_attr "type" "branch")
9322 (set (attr "length")
9323 (if_then_else (lt (abs (minus (pc) (match_dup 0))) (const_int 60000))
9324 (const_int 6) (const_int 16)))])
9325
9326 ; brxle, brxh
9327
9328 (define_insn_and_split "*brx_64bit"
9329 [(set (pc)
9330 (if_then_else
9331 (match_operator 5 "s390_brx_operator"
9332 [(plus:SI (match_operand:SI 1 "register_operand" "d,d,d")
9333 (subreg:SI (match_operand:TI 2 "register_operand" "d,d,d") 4))
9334 (subreg:SI (match_dup 2) 12)])
9335 (label_ref (match_operand 0 "" ""))
9336 (pc)))
9337 (set (match_operand:SI 3 "nonimmediate_operand" "=1,?X,?X")
9338 (plus:SI (match_dup 1)
9339 (subreg:SI (match_dup 2) 4)))
9340 (clobber (match_scratch:SI 4 "=X,&1,&?d"))
9341 (clobber (reg:CC CC_REGNUM))]
9342 "TARGET_ZARCH"
9343 {
9344 if (which_alternative != 0)
9345 return "#";
9346 else if (get_attr_length (insn) == 6)
9347 return "brx%C5\t%1,%2,%l0";
9348 else
9349 return "ar\t%1,%2\;cr\t%1,%M2\;jg%C5\t%l0";
9350 }
9351 "&& reload_completed
9352 && (!REG_P (operands[3])
9353 || !rtx_equal_p (operands[1], operands[3]))"
9354 [(set (match_dup 4) (match_dup 1))
9355 (parallel [(set (match_dup 4) (plus:SI (match_dup 4) (subreg:SI (match_dup 2) 4)))
9356 (clobber (reg:CC CC_REGNUM))])
9357 (set (reg:CCS CC_REGNUM) (compare:CCS (match_dup 4) (subreg:SI (match_dup 2) 12)))
9358 (set (match_dup 3) (match_dup 4))
9359 (set (pc) (if_then_else (match_op_dup 5 [(reg:CCS CC_REGNUM) (const_int 0)])
9360 (label_ref (match_dup 0))
9361 (pc)))]
9362 ""
9363 [(set_attr "op_type" "RSI")
9364 (set_attr "type" "branch")
9365 (set (attr "length")
9366 (if_then_else (lt (abs (minus (pc) (match_dup 0))) (const_int 60000))
9367 (const_int 6) (const_int 14)))])
9368
9369 ; brxle, brxh
9370
9371 (define_insn_and_split "*brx_31bit"
9372 [(set (pc)
9373 (if_then_else
9374 (match_operator 5 "s390_brx_operator"
9375 [(plus:SI (match_operand:SI 1 "register_operand" "d,d,d")
9376 (subreg:SI (match_operand:DI 2 "register_operand" "d,d,d") 0))
9377 (subreg:SI (match_dup 2) 4)])
9378 (label_ref (match_operand 0 "" ""))
9379 (pc)))
9380 (set (match_operand:SI 3 "nonimmediate_operand" "=1,?X,?X")
9381 (plus:SI (match_dup 1)
9382 (subreg:SI (match_dup 2) 0)))
9383 (clobber (match_scratch:SI 4 "=X,&1,&?d"))
9384 (clobber (reg:CC CC_REGNUM))]
9385 "!TARGET_ZARCH && TARGET_CPU_ZARCH"
9386 {
9387 if (which_alternative != 0)
9388 return "#";
9389 else if (get_attr_length (insn) == 6)
9390 return "brx%C5\t%1,%2,%l0";
9391 else
9392 return "ar\t%1,%2\;cr\t%1,%M2\;jg%C5\t%l0";
9393 }
9394 "&& reload_completed
9395 && (!REG_P (operands[3])
9396 || !rtx_equal_p (operands[1], operands[3]))"
9397 [(set (match_dup 4) (match_dup 1))
9398 (parallel [(set (match_dup 4) (plus:SI (match_dup 4) (subreg:SI (match_dup 2) 0)))
9399 (clobber (reg:CC CC_REGNUM))])
9400 (set (reg:CCS CC_REGNUM) (compare:CCS (match_dup 4) (subreg:SI (match_dup 2) 4)))
9401 (set (match_dup 3) (match_dup 4))
9402 (set (pc) (if_then_else (match_op_dup 5 [(reg:CCS CC_REGNUM) (const_int 0)])
9403 (label_ref (match_dup 0))
9404 (pc)))]
9405 ""
9406 [(set_attr "op_type" "RSI")
9407 (set_attr "type" "branch")
9408 (set (attr "length")
9409 (if_then_else (lt (abs (minus (pc) (match_dup 0))) (const_int 60000))
9410 (const_int 6) (const_int 14)))])
9411
9412
9413 ;; branch on count
9414
9415 (define_expand "doloop_end"
9416 [(use (match_operand 0 "" "")) ; loop pseudo
9417 (use (match_operand 1 "" ""))] ; label
9418 ""
9419 {
9420 if (GET_MODE (operands[0]) == SImode && !TARGET_CPU_ZARCH)
9421 emit_jump_insn (gen_doloop_si31 (operands[1], operands[0], operands[0]));
9422 else if (GET_MODE (operands[0]) == SImode && TARGET_CPU_ZARCH)
9423 emit_jump_insn (gen_doloop_si64 (operands[1], operands[0], operands[0]));
9424 else if (GET_MODE (operands[0]) == DImode && TARGET_ZARCH)
9425 emit_jump_insn (gen_doloop_di (operands[1], operands[0], operands[0]));
9426 else
9427 FAIL;
9428
9429 DONE;
9430 })
9431
9432 (define_insn_and_split "doloop_si64"
9433 [(set (pc)
9434 (if_then_else
9435 (ne (match_operand:SI 1 "register_operand" "d,d,d")
9436 (const_int 1))
9437 (label_ref (match_operand 0 "" ""))
9438 (pc)))
9439 (set (match_operand:SI 2 "nonimmediate_operand" "=1,?X,?X")
9440 (plus:SI (match_dup 1) (const_int -1)))
9441 (clobber (match_scratch:SI 3 "=X,&1,&?d"))
9442 (clobber (reg:CC CC_REGNUM))]
9443 "TARGET_CPU_ZARCH"
9444 {
9445 if (which_alternative != 0)
9446 return "#";
9447 else if (get_attr_length (insn) == 4)
9448 return "brct\t%1,%l0";
9449 else
9450 return "ahi\t%1,-1\;jgne\t%l0";
9451 }
9452 "&& reload_completed
9453 && (! REG_P (operands[2])
9454 || ! rtx_equal_p (operands[1], operands[2]))"
9455 [(set (match_dup 3) (match_dup 1))
9456 (parallel [(set (reg:CCAN CC_REGNUM)
9457 (compare:CCAN (plus:SI (match_dup 3) (const_int -1))
9458 (const_int 0)))
9459 (set (match_dup 3) (plus:SI (match_dup 3) (const_int -1)))])
9460 (set (match_dup 2) (match_dup 3))
9461 (set (pc) (if_then_else (ne (reg:CCAN CC_REGNUM) (const_int 0))
9462 (label_ref (match_dup 0))
9463 (pc)))]
9464 ""
9465 [(set_attr "op_type" "RI")
9466 ; Strictly speaking, the z10 properties are valid for brct only, however, it does not
9467 ; hurt us in the (rare) case of ahi.
9468 (set_attr "z10prop" "z10_super_E1")
9469 (set_attr "type" "branch")
9470 (set (attr "length")
9471 (if_then_else (lt (abs (minus (pc) (match_dup 0))) (const_int 60000))
9472 (const_int 4) (const_int 10)))])
9473
9474 (define_insn_and_split "doloop_si31"
9475 [(set (pc)
9476 (if_then_else
9477 (ne (match_operand:SI 1 "register_operand" "d,d,d")
9478 (const_int 1))
9479 (label_ref (match_operand 0 "" ""))
9480 (pc)))
9481 (set (match_operand:SI 2 "nonimmediate_operand" "=1,?X,?X")
9482 (plus:SI (match_dup 1) (const_int -1)))
9483 (clobber (match_scratch:SI 3 "=X,&1,&?d"))
9484 (clobber (reg:CC CC_REGNUM))]
9485 "!TARGET_CPU_ZARCH"
9486 {
9487 if (which_alternative != 0)
9488 return "#";
9489 else if (get_attr_length (insn) == 4)
9490 return "brct\t%1,%l0";
9491 else
9492 gcc_unreachable ();
9493 }
9494 "&& reload_completed
9495 && (! REG_P (operands[2])
9496 || ! rtx_equal_p (operands[1], operands[2]))"
9497 [(set (match_dup 3) (match_dup 1))
9498 (parallel [(set (reg:CCAN CC_REGNUM)
9499 (compare:CCAN (plus:SI (match_dup 3) (const_int -1))
9500 (const_int 0)))
9501 (set (match_dup 3) (plus:SI (match_dup 3) (const_int -1)))])
9502 (set (match_dup 2) (match_dup 3))
9503 (set (pc) (if_then_else (ne (reg:CCAN CC_REGNUM) (const_int 0))
9504 (label_ref (match_dup 0))
9505 (pc)))]
9506 ""
9507 [(set_attr "op_type" "RI")
9508 ; Strictly speaking, the z10 properties are valid for brct only, however, it does not
9509 ; hurt us in the (rare) case of ahi.
9510 (set_attr "z10prop" "z10_super_E1")
9511 (set_attr "type" "branch")
9512 (set (attr "length")
9513 (if_then_else (not (match_test "flag_pic"))
9514 (if_then_else (lt (abs (minus (pc) (match_dup 0))) (const_int 60000))
9515 (const_int 4) (const_int 6))
9516 (if_then_else (lt (abs (minus (pc) (match_dup 0))) (const_int 60000))
9517 (const_int 4) (const_int 8))))])
9518
9519 (define_insn "*doloop_si_long"
9520 [(set (pc)
9521 (if_then_else
9522 (ne (match_operand:SI 1 "register_operand" "d")
9523 (const_int 1))
9524 (match_operand 0 "address_operand" "ZR")
9525 (pc)))
9526 (set (match_operand:SI 2 "register_operand" "=1")
9527 (plus:SI (match_dup 1) (const_int -1)))
9528 (clobber (match_scratch:SI 3 "=X"))
9529 (clobber (reg:CC CC_REGNUM))]
9530 "!TARGET_CPU_ZARCH"
9531 {
9532 if (get_attr_op_type (insn) == OP_TYPE_RR)
9533 return "bctr\t%1,%0";
9534 else
9535 return "bct\t%1,%a0";
9536 }
9537 [(set (attr "op_type")
9538 (if_then_else (match_operand 0 "register_operand" "")
9539 (const_string "RR") (const_string "RX")))
9540 (set_attr "type" "branch")
9541 (set_attr "atype" "agen")
9542 (set_attr "z10prop" "z10_c")
9543 (set_attr "z196prop" "z196_cracked")])
9544
9545 (define_insn_and_split "doloop_di"
9546 [(set (pc)
9547 (if_then_else
9548 (ne (match_operand:DI 1 "register_operand" "d,d,d")
9549 (const_int 1))
9550 (label_ref (match_operand 0 "" ""))
9551 (pc)))
9552 (set (match_operand:DI 2 "nonimmediate_operand" "=1,?X,?X")
9553 (plus:DI (match_dup 1) (const_int -1)))
9554 (clobber (match_scratch:DI 3 "=X,&1,&?d"))
9555 (clobber (reg:CC CC_REGNUM))]
9556 "TARGET_ZARCH"
9557 {
9558 if (which_alternative != 0)
9559 return "#";
9560 else if (get_attr_length (insn) == 4)
9561 return "brctg\t%1,%l0";
9562 else
9563 return "aghi\t%1,-1\;jgne\t%l0";
9564 }
9565 "&& reload_completed
9566 && (! REG_P (operands[2])
9567 || ! rtx_equal_p (operands[1], operands[2]))"
9568 [(set (match_dup 3) (match_dup 1))
9569 (parallel [(set (reg:CCAN CC_REGNUM)
9570 (compare:CCAN (plus:DI (match_dup 3) (const_int -1))
9571 (const_int 0)))
9572 (set (match_dup 3) (plus:DI (match_dup 3) (const_int -1)))])
9573 (set (match_dup 2) (match_dup 3))
9574 (set (pc) (if_then_else (ne (reg:CCAN CC_REGNUM) (const_int 0))
9575 (label_ref (match_dup 0))
9576 (pc)))]
9577 ""
9578 [(set_attr "op_type" "RI")
9579 ; Strictly speaking, the z10 properties are valid for brct only, however, it does not
9580 ; hurt us in the (rare) case of ahi.
9581 (set_attr "z10prop" "z10_super_E1")
9582 (set_attr "type" "branch")
9583 (set (attr "length")
9584 (if_then_else (lt (abs (minus (pc) (match_dup 0))) (const_int 60000))
9585 (const_int 4) (const_int 10)))])
9586
9587 ;;
9588 ;;- Unconditional jump instructions.
9589 ;;
9590
9591 ;
9592 ; jump instruction pattern(s).
9593 ;
9594
9595 (define_expand "jump"
9596 [(match_operand 0 "" "")]
9597 ""
9598 "s390_emit_jump (operands[0], NULL_RTX); DONE;")
9599
9600 (define_insn "*jump64"
9601 [(set (pc) (label_ref (match_operand 0 "" "")))]
9602 "TARGET_CPU_ZARCH"
9603 {
9604 if (get_attr_length (insn) == 4)
9605 return "j\t%l0";
9606 else
9607 return "jg\t%l0";
9608 }
9609 [(set_attr "op_type" "RI")
9610 (set_attr "type" "branch")
9611 (set (attr "length")
9612 (if_then_else (lt (abs (minus (pc) (match_dup 0))) (const_int 60000))
9613 (const_int 4) (const_int 6)))])
9614
9615 (define_insn "*jump31"
9616 [(set (pc) (label_ref (match_operand 0 "" "")))]
9617 "!TARGET_CPU_ZARCH"
9618 {
9619 gcc_assert (get_attr_length (insn) == 4);
9620 return "j\t%l0";
9621 }
9622 [(set_attr "op_type" "RI")
9623 (set_attr "type" "branch")
9624 (set (attr "length")
9625 (if_then_else (not (match_test "flag_pic"))
9626 (if_then_else (lt (abs (minus (pc) (match_dup 0))) (const_int 60000))
9627 (const_int 4) (const_int 6))
9628 (if_then_else (lt (abs (minus (pc) (match_dup 0))) (const_int 60000))
9629 (const_int 4) (const_int 8))))])
9630
9631 ;
9632 ; indirect-jump instruction pattern(s).
9633 ;
9634
9635 (define_expand "indirect_jump"
9636 [(set (pc) (match_operand 0 "nonimmediate_operand" ""))]
9637 ""
9638 {
9639 if (address_operand (operands[0], GET_MODE (operands[0])))
9640 ;
9641 else if (TARGET_ARCH12
9642 && GET_MODE (operands[0]) == Pmode
9643 && memory_operand (operands[0], Pmode))
9644 ;
9645 else
9646 operands[0] = force_reg (Pmode, operands[0]);
9647 })
9648
9649 ; The first constraint must be an "extra address constraint" in order
9650 ; to trigger address reloading in LRA/reload
9651 (define_insn "*indirect_jump"
9652 [(set (pc)
9653 (match_operand 0 "address_operand" "ZR,a"))]
9654 ""
9655 "@
9656 b\t%a0
9657 br\t%0"
9658 [(set_attr "op_type" "RX,RR")
9659 (set_attr "type" "branch")
9660 (set_attr "atype" "agen")
9661 (set_attr "cpu_facility" "*")])
9662
9663 ; FIXME: LRA does not appear to be able to deal with MEMs being
9664 ; checked against address constraints like ZR above. So make this a
9665 ; separate pattern for now.
9666 (define_insn "*indirect2_jump"
9667 [(set (pc)
9668 (match_operand 0 "nonimmediate_operand" "a,T"))]
9669 ""
9670 "@
9671 br\t%0
9672 bi\t%0"
9673 [(set_attr "op_type" "RR,RXY")
9674 (set_attr "type" "branch")
9675 (set_attr "atype" "agen")
9676 (set_attr "cpu_facility" "*,arch12")])
9677
9678 ;
9679 ; casesi instruction pattern(s).
9680 ;
9681
9682 (define_insn "casesi_jump"
9683 [(set (pc) (match_operand 0 "address_operand" "ZR"))
9684 (use (label_ref (match_operand 1 "" "")))]
9685 ""
9686 {
9687 if (get_attr_op_type (insn) == OP_TYPE_RR)
9688 return "br\t%0";
9689 else
9690 return "b\t%a0";
9691 }
9692 [(set (attr "op_type")
9693 (if_then_else (match_operand 0 "register_operand" "")
9694 (const_string "RR") (const_string "RX")))
9695 (set_attr "type" "branch")
9696 (set_attr "atype" "agen")])
9697
9698 (define_expand "casesi"
9699 [(match_operand:SI 0 "general_operand" "")
9700 (match_operand:SI 1 "general_operand" "")
9701 (match_operand:SI 2 "general_operand" "")
9702 (label_ref (match_operand 3 "" ""))
9703 (label_ref (match_operand 4 "" ""))]
9704 ""
9705 {
9706 rtx index = gen_reg_rtx (SImode);
9707 rtx base = gen_reg_rtx (Pmode);
9708 rtx target = gen_reg_rtx (Pmode);
9709
9710 emit_move_insn (index, operands[0]);
9711 emit_insn (gen_subsi3 (index, index, operands[1]));
9712 emit_cmp_and_jump_insns (index, operands[2], GTU, NULL_RTX, SImode, 1,
9713 operands[4]);
9714
9715 if (Pmode != SImode)
9716 index = convert_to_mode (Pmode, index, 1);
9717 if (GET_CODE (index) != REG)
9718 index = copy_to_mode_reg (Pmode, index);
9719
9720 if (TARGET_64BIT)
9721 emit_insn (gen_ashldi3 (index, index, GEN_INT (3)));
9722 else
9723 emit_insn (gen_ashlsi3 (index, index, const2_rtx));
9724
9725 emit_move_insn (base, gen_rtx_LABEL_REF (Pmode, operands[3]));
9726
9727 index = gen_const_mem (Pmode, gen_rtx_PLUS (Pmode, base, index));
9728 emit_move_insn (target, index);
9729
9730 if (flag_pic)
9731 target = gen_rtx_PLUS (Pmode, base, target);
9732 emit_jump_insn (gen_casesi_jump (target, operands[3]));
9733
9734 DONE;
9735 })
9736
9737
9738 ;;
9739 ;;- Jump to subroutine.
9740 ;;
9741 ;;
9742
9743 ;
9744 ; untyped call instruction pattern(s).
9745 ;
9746
9747 ;; Call subroutine returning any type.
9748 (define_expand "untyped_call"
9749 [(parallel [(call (match_operand 0 "" "")
9750 (const_int 0))
9751 (match_operand 1 "" "")
9752 (match_operand 2 "" "")])]
9753 ""
9754 {
9755 int i;
9756
9757 emit_call_insn (gen_call (operands[0], const0_rtx, const0_rtx));
9758
9759 for (i = 0; i < XVECLEN (operands[2], 0); i++)
9760 {
9761 rtx set = XVECEXP (operands[2], 0, i);
9762 emit_move_insn (SET_DEST (set), SET_SRC (set));
9763 }
9764
9765 /* The optimizer does not know that the call sets the function value
9766 registers we stored in the result block. We avoid problems by
9767 claiming that all hard registers are used and clobbered at this
9768 point. */
9769 emit_insn (gen_blockage ());
9770
9771 DONE;
9772 })
9773
9774 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
9775 ;; all of memory. This blocks insns from being moved across this point.
9776
9777 (define_insn "blockage"
9778 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
9779 ""
9780 ""
9781 [(set_attr "type" "none")
9782 (set_attr "length" "0")])
9783
9784 ;
9785 ; sibcall patterns
9786 ;
9787
9788 (define_expand "sibcall"
9789 [(call (match_operand 0 "" "")
9790 (match_operand 1 "" ""))]
9791 ""
9792 {
9793 s390_emit_call (XEXP (operands[0], 0), NULL_RTX, NULL_RTX, NULL_RTX);
9794 DONE;
9795 })
9796
9797 (define_insn "*sibcall_br"
9798 [(call (mem:QI (reg SIBCALL_REGNUM))
9799 (match_operand 0 "const_int_operand" "n"))]
9800 "SIBLING_CALL_P (insn)
9801 && GET_MODE (XEXP (XEXP (PATTERN (insn), 0), 0)) == Pmode"
9802 "br\t%%r1"
9803 [(set_attr "op_type" "RR")
9804 (set_attr "type" "branch")
9805 (set_attr "atype" "agen")])
9806
9807 (define_insn "*sibcall_brc"
9808 [(call (mem:QI (match_operand 0 "bras_sym_operand" "X"))
9809 (match_operand 1 "const_int_operand" "n"))]
9810 "SIBLING_CALL_P (insn) && TARGET_SMALL_EXEC"
9811 "j\t%0"
9812 [(set_attr "op_type" "RI")
9813 (set_attr "type" "branch")])
9814
9815 (define_insn "*sibcall_brcl"
9816 [(call (mem:QI (match_operand 0 "bras_sym_operand" "X"))
9817 (match_operand 1 "const_int_operand" "n"))]
9818 "SIBLING_CALL_P (insn) && TARGET_CPU_ZARCH"
9819 "jg\t%0"
9820 [(set_attr "op_type" "RIL")
9821 (set_attr "type" "branch")])
9822
9823 ;
9824 ; sibcall_value patterns
9825 ;
9826
9827 (define_expand "sibcall_value"
9828 [(set (match_operand 0 "" "")
9829 (call (match_operand 1 "" "")
9830 (match_operand 2 "" "")))]
9831 ""
9832 {
9833 s390_emit_call (XEXP (operands[1], 0), NULL_RTX, operands[0], NULL_RTX);
9834 DONE;
9835 })
9836
9837 (define_insn "*sibcall_value_br"
9838 [(set (match_operand 0 "" "")
9839 (call (mem:QI (reg SIBCALL_REGNUM))
9840 (match_operand 1 "const_int_operand" "n")))]
9841 "SIBLING_CALL_P (insn)
9842 && GET_MODE (XEXP (XEXP (XEXP (PATTERN (insn), 1), 0), 0)) == Pmode"
9843 "br\t%%r1"
9844 [(set_attr "op_type" "RR")
9845 (set_attr "type" "branch")
9846 (set_attr "atype" "agen")])
9847
9848 (define_insn "*sibcall_value_brc"
9849 [(set (match_operand 0 "" "")
9850 (call (mem:QI (match_operand 1 "bras_sym_operand" "X"))
9851 (match_operand 2 "const_int_operand" "n")))]
9852 "SIBLING_CALL_P (insn) && TARGET_SMALL_EXEC"
9853 "j\t%1"
9854 [(set_attr "op_type" "RI")
9855 (set_attr "type" "branch")])
9856
9857 (define_insn "*sibcall_value_brcl"
9858 [(set (match_operand 0 "" "")
9859 (call (mem:QI (match_operand 1 "bras_sym_operand" "X"))
9860 (match_operand 2 "const_int_operand" "n")))]
9861 "SIBLING_CALL_P (insn) && TARGET_CPU_ZARCH"
9862 "jg\t%1"
9863 [(set_attr "op_type" "RIL")
9864 (set_attr "type" "branch")])
9865
9866
9867 ;
9868 ; call instruction pattern(s).
9869 ;
9870
9871 (define_expand "call"
9872 [(call (match_operand 0 "" "")
9873 (match_operand 1 "" ""))
9874 (use (match_operand 2 "" ""))]
9875 ""
9876 {
9877 s390_emit_call (XEXP (operands[0], 0), NULL_RTX, NULL_RTX,
9878 gen_rtx_REG (Pmode, RETURN_REGNUM));
9879 DONE;
9880 })
9881
9882 (define_insn "*bras"
9883 [(call (mem:QI (match_operand 0 "bras_sym_operand" "X"))
9884 (match_operand 1 "const_int_operand" "n"))
9885 (clobber (match_operand 2 "register_operand" "=r"))]
9886 "!SIBLING_CALL_P (insn)
9887 && TARGET_SMALL_EXEC
9888 && GET_MODE (operands[2]) == Pmode"
9889 "bras\t%2,%0"
9890 [(set_attr "op_type" "RI")
9891 (set_attr "type" "jsr")
9892 (set_attr "z196prop" "z196_cracked")])
9893
9894 (define_insn "*brasl"
9895 [(call (mem:QI (match_operand 0 "bras_sym_operand" "X"))
9896 (match_operand 1 "const_int_operand" "n"))
9897 (clobber (match_operand 2 "register_operand" "=r"))]
9898 "!SIBLING_CALL_P (insn)
9899 && TARGET_CPU_ZARCH
9900 && GET_MODE (operands[2]) == Pmode"
9901 "brasl\t%2,%0"
9902 [(set_attr "op_type" "RIL")
9903 (set_attr "type" "jsr")
9904 (set_attr "z196prop" "z196_cracked")])
9905
9906 (define_insn "*basr"
9907 [(call (mem:QI (match_operand 0 "address_operand" "ZR"))
9908 (match_operand 1 "const_int_operand" "n"))
9909 (clobber (match_operand 2 "register_operand" "=r"))]
9910 "!SIBLING_CALL_P (insn) && GET_MODE (operands[2]) == Pmode"
9911 {
9912 if (get_attr_op_type (insn) == OP_TYPE_RR)
9913 return "basr\t%2,%0";
9914 else
9915 return "bas\t%2,%a0";
9916 }
9917 [(set (attr "op_type")
9918 (if_then_else (match_operand 0 "register_operand" "")
9919 (const_string "RR") (const_string "RX")))
9920 (set_attr "type" "jsr")
9921 (set_attr "atype" "agen")
9922 (set_attr "z196prop" "z196_cracked")])
9923
9924 ;
9925 ; call_value instruction pattern(s).
9926 ;
9927
9928 (define_expand "call_value"
9929 [(set (match_operand 0 "" "")
9930 (call (match_operand 1 "" "")
9931 (match_operand 2 "" "")))
9932 (use (match_operand 3 "" ""))]
9933 ""
9934 {
9935 s390_emit_call (XEXP (operands[1], 0), NULL_RTX, operands[0],
9936 gen_rtx_REG (Pmode, RETURN_REGNUM));
9937 DONE;
9938 })
9939
9940 (define_insn "*bras_r"
9941 [(set (match_operand 0 "" "")
9942 (call (mem:QI (match_operand 1 "bras_sym_operand" "X"))
9943 (match_operand:SI 2 "const_int_operand" "n")))
9944 (clobber (match_operand 3 "register_operand" "=r"))]
9945 "!SIBLING_CALL_P (insn)
9946 && TARGET_SMALL_EXEC
9947 && GET_MODE (operands[3]) == Pmode"
9948 "bras\t%3,%1"
9949 [(set_attr "op_type" "RI")
9950 (set_attr "type" "jsr")
9951 (set_attr "z196prop" "z196_cracked")])
9952
9953 (define_insn "*brasl_r"
9954 [(set (match_operand 0 "" "")
9955 (call (mem:QI (match_operand 1 "bras_sym_operand" "X"))
9956 (match_operand 2 "const_int_operand" "n")))
9957 (clobber (match_operand 3 "register_operand" "=r"))]
9958 "!SIBLING_CALL_P (insn)
9959 && TARGET_CPU_ZARCH
9960 && GET_MODE (operands[3]) == Pmode"
9961 "brasl\t%3,%1"
9962 [(set_attr "op_type" "RIL")
9963 (set_attr "type" "jsr")
9964 (set_attr "z196prop" "z196_cracked")])
9965
9966 (define_insn "*basr_r"
9967 [(set (match_operand 0 "" "")
9968 (call (mem:QI (match_operand 1 "address_operand" "ZR"))
9969 (match_operand 2 "const_int_operand" "n")))
9970 (clobber (match_operand 3 "register_operand" "=r"))]
9971 "!SIBLING_CALL_P (insn) && GET_MODE (operands[3]) == Pmode"
9972 {
9973 if (get_attr_op_type (insn) == OP_TYPE_RR)
9974 return "basr\t%3,%1";
9975 else
9976 return "bas\t%3,%a1";
9977 }
9978 [(set (attr "op_type")
9979 (if_then_else (match_operand 1 "register_operand" "")
9980 (const_string "RR") (const_string "RX")))
9981 (set_attr "type" "jsr")
9982 (set_attr "atype" "agen")
9983 (set_attr "z196prop" "z196_cracked")])
9984
9985 ;;
9986 ;;- Thread-local storage support.
9987 ;;
9988
9989 (define_expand "get_thread_pointer<mode>"
9990 [(set (match_operand:P 0 "nonimmediate_operand" "") (reg:P TP_REGNUM))]
9991 ""
9992 "")
9993
9994 (define_expand "set_thread_pointer<mode>"
9995 [(set (reg:P TP_REGNUM) (match_operand:P 0 "nonimmediate_operand" ""))
9996 (set (reg:P TP_REGNUM) (unspec_volatile:P [(reg:P TP_REGNUM)] UNSPECV_SET_TP))]
9997 ""
9998 "")
9999
10000 (define_insn "*set_tp"
10001 [(set (reg TP_REGNUM) (unspec_volatile [(reg TP_REGNUM)] UNSPECV_SET_TP))]
10002 ""
10003 ""
10004 [(set_attr "type" "none")
10005 (set_attr "length" "0")])
10006
10007 (define_insn "*tls_load_64"
10008 [(set (match_operand:DI 0 "register_operand" "=d")
10009 (unspec:DI [(match_operand:DI 1 "memory_operand" "T")
10010 (match_operand:DI 2 "" "")]
10011 UNSPEC_TLS_LOAD))]
10012 "TARGET_64BIT"
10013 "lg\t%0,%1%J2"
10014 [(set_attr "op_type" "RXE")
10015 (set_attr "z10prop" "z10_fwd_A3")])
10016
10017 (define_insn "*tls_load_31"
10018 [(set (match_operand:SI 0 "register_operand" "=d,d")
10019 (unspec:SI [(match_operand:SI 1 "memory_operand" "R,T")
10020 (match_operand:SI 2 "" "")]
10021 UNSPEC_TLS_LOAD))]
10022 "!TARGET_64BIT"
10023 "@
10024 l\t%0,%1%J2
10025 ly\t%0,%1%J2"
10026 [(set_attr "op_type" "RX,RXY")
10027 (set_attr "type" "load")
10028 (set_attr "cpu_facility" "*,longdisp")
10029 (set_attr "z10prop" "z10_fwd_A3,z10_fwd_A3")])
10030
10031 (define_insn "*bras_tls"
10032 [(set (match_operand 0 "" "")
10033 (call (mem:QI (match_operand 1 "bras_sym_operand" "X"))
10034 (match_operand 2 "const_int_operand" "n")))
10035 (clobber (match_operand 3 "register_operand" "=r"))
10036 (use (match_operand 4 "" ""))]
10037 "!SIBLING_CALL_P (insn)
10038 && TARGET_SMALL_EXEC
10039 && GET_MODE (operands[3]) == Pmode"
10040 "bras\t%3,%1%J4"
10041 [(set_attr "op_type" "RI")
10042 (set_attr "type" "jsr")
10043 (set_attr "z196prop" "z196_cracked")])
10044
10045 (define_insn "*brasl_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_CPU_ZARCH
10053 && GET_MODE (operands[3]) == Pmode"
10054 "brasl\t%3,%1%J4"
10055 [(set_attr "op_type" "RIL")
10056 (set_attr "type" "jsr")
10057 (set_attr "z196prop" "z196_cracked")])
10058
10059 (define_insn "*basr_tls"
10060 [(set (match_operand 0 "" "")
10061 (call (mem:QI (match_operand 1 "address_operand" "ZR"))
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) && GET_MODE (operands[3]) == Pmode"
10066 {
10067 if (get_attr_op_type (insn) == OP_TYPE_RR)
10068 return "basr\t%3,%1%J4";
10069 else
10070 return "bas\t%3,%a1%J4";
10071 }
10072 [(set (attr "op_type")
10073 (if_then_else (match_operand 1 "register_operand" "")
10074 (const_string "RR") (const_string "RX")))
10075 (set_attr "type" "jsr")
10076 (set_attr "atype" "agen")
10077 (set_attr "z196prop" "z196_cracked")])
10078
10079 ;;
10080 ;;- Atomic operations
10081 ;;
10082
10083 ;
10084 ; memory barrier patterns.
10085 ;
10086
10087 (define_expand "mem_signal_fence"
10088 [(match_operand:SI 0 "const_int_operand")] ;; model
10089 ""
10090 {
10091 /* The s390 memory model is strong enough not to require any
10092 barrier in order to synchronize a thread with itself. */
10093 DONE;
10094 })
10095
10096 (define_expand "mem_thread_fence"
10097 [(match_operand:SI 0 "const_int_operand")] ;; model
10098 ""
10099 {
10100 /* Unless this is a SEQ_CST fence, the s390 memory model is strong
10101 enough not to require barriers of any kind. */
10102 if (is_mm_seq_cst (memmodel_from_int (INTVAL (operands[0]))))
10103 {
10104 rtx mem = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
10105 MEM_VOLATILE_P (mem) = 1;
10106 emit_insn (gen_mem_thread_fence_1 (mem));
10107 }
10108 DONE;
10109 })
10110
10111 ; Although bcr is superscalar on Z10, this variant will never
10112 ; become part of an execution group.
10113 ; With z196 we can make use of the fast-BCR-serialization facility.
10114 ; This allows for a slightly faster sync which is sufficient for our
10115 ; purposes.
10116 (define_insn "mem_thread_fence_1"
10117 [(set (match_operand:BLK 0 "" "")
10118 (unspec:BLK [(match_dup 0)] UNSPEC_MB))]
10119 ""
10120 {
10121 if (TARGET_Z196)
10122 return "bcr\t14,0";
10123 else
10124 return "bcr\t15,0";
10125 }
10126 [(set_attr "op_type" "RR")
10127 (set_attr "mnemonic" "bcr_flush")
10128 (set_attr "z196prop" "z196_alone")])
10129
10130 ;
10131 ; atomic load/store operations
10132 ;
10133
10134 ; Atomic loads need not examine the memory model at all.
10135 (define_expand "atomic_load<mode>"
10136 [(match_operand:DINT 0 "register_operand") ;; output
10137 (match_operand:DINT 1 "memory_operand") ;; memory
10138 (match_operand:SI 2 "const_int_operand")] ;; model
10139 ""
10140 {
10141 if (MEM_ALIGN (operands[1]) < GET_MODE_BITSIZE (GET_MODE (operands[1])))
10142 FAIL;
10143
10144 if (<MODE>mode == TImode)
10145 emit_insn (gen_atomic_loadti_1 (operands[0], operands[1]));
10146 else if (<MODE>mode == DImode && !TARGET_ZARCH)
10147 emit_insn (gen_atomic_loaddi_1 (operands[0], operands[1]));
10148 else
10149 emit_move_insn (operands[0], operands[1]);
10150 DONE;
10151 })
10152
10153 ; Different from movdi_31 in that we want no splitters.
10154 (define_insn "atomic_loaddi_1"
10155 [(set (match_operand:DI 0 "register_operand" "=d,d,!*f,!*f")
10156 (unspec:DI [(match_operand:DI 1 "memory_operand" "Q,S,R,T")]
10157 UNSPEC_MOVA))]
10158 "!TARGET_ZARCH"
10159 "@
10160 lm\t%0,%M0,%S1
10161 lmy\t%0,%M0,%S1
10162 ld\t%0,%1
10163 ldy\t%0,%1"
10164 [(set_attr "op_type" "RS,RSY,RS,RSY")
10165 (set_attr "cpu_facility" "*,longdisp,*,longdisp")
10166 (set_attr "type" "lm,lm,floaddf,floaddf")])
10167
10168 (define_insn "atomic_loadti_1"
10169 [(set (match_operand:TI 0 "register_operand" "=r")
10170 (unspec:TI [(match_operand:TI 1 "memory_operand" "T")]
10171 UNSPEC_MOVA))]
10172 "TARGET_ZARCH"
10173 "lpq\t%0,%1"
10174 [(set_attr "op_type" "RXY")
10175 (set_attr "type" "other")])
10176
10177 ; Atomic stores must(?) enforce sequential consistency.
10178 (define_expand "atomic_store<mode>"
10179 [(match_operand:DINT 0 "memory_operand") ;; memory
10180 (match_operand:DINT 1 "register_operand") ;; input
10181 (match_operand:SI 2 "const_int_operand")] ;; model
10182 ""
10183 {
10184 enum memmodel model = memmodel_from_int (INTVAL (operands[2]));
10185
10186 if (MEM_ALIGN (operands[0]) < GET_MODE_BITSIZE (GET_MODE (operands[0])))
10187 FAIL;
10188
10189 if (<MODE>mode == TImode)
10190 emit_insn (gen_atomic_storeti_1 (operands[0], operands[1]));
10191 else if (<MODE>mode == DImode && !TARGET_ZARCH)
10192 emit_insn (gen_atomic_storedi_1 (operands[0], operands[1]));
10193 else
10194 emit_move_insn (operands[0], operands[1]);
10195 if (is_mm_seq_cst (model))
10196 emit_insn (gen_mem_thread_fence (operands[2]));
10197 DONE;
10198 })
10199
10200 ; Different from movdi_31 in that we want no splitters.
10201 (define_insn "atomic_storedi_1"
10202 [(set (match_operand:DI 0 "memory_operand" "=Q,S,R,T")
10203 (unspec:DI [(match_operand:DI 1 "register_operand" "d,d,!*f,!*f")]
10204 UNSPEC_MOVA))]
10205 "!TARGET_ZARCH"
10206 "@
10207 stm\t%1,%N1,%S0
10208 stmy\t%1,%N1,%S0
10209 std %1,%0
10210 stdy %1,%0"
10211 [(set_attr "op_type" "RS,RSY,RS,RSY")
10212 (set_attr "cpu_facility" "*,longdisp,*,longdisp")
10213 (set_attr "type" "stm,stm,fstoredf,fstoredf")])
10214
10215 (define_insn "atomic_storeti_1"
10216 [(set (match_operand:TI 0 "memory_operand" "=T")
10217 (unspec:TI [(match_operand:TI 1 "register_operand" "r")]
10218 UNSPEC_MOVA))]
10219 "TARGET_ZARCH"
10220 "stpq\t%1,%0"
10221 [(set_attr "op_type" "RXY")
10222 (set_attr "type" "other")])
10223
10224 ;
10225 ; compare and swap patterns.
10226 ;
10227
10228 (define_expand "atomic_compare_and_swap<mode>"
10229 [(match_operand:SI 0 "register_operand") ;; bool success output
10230 (match_operand:DINT 1 "nonimmediate_operand");; oldval output
10231 (match_operand:DINT 2 "s_operand") ;; memory
10232 (match_operand:DINT 3 "general_operand") ;; expected intput
10233 (match_operand:DINT 4 "general_operand") ;; newval intput
10234 (match_operand:SI 5 "const_int_operand") ;; is_weak
10235 (match_operand:SI 6 "const_int_operand") ;; success model
10236 (match_operand:SI 7 "const_int_operand")] ;; failure model
10237 ""
10238 {
10239 if (GET_MODE_BITSIZE (<MODE>mode) >= 16
10240 && GET_MODE_BITSIZE (<MODE>mode) > MEM_ALIGN (operands[2]))
10241 FAIL;
10242
10243 s390_expand_cs (<MODE>mode, operands[0], operands[1], operands[2],
10244 operands[3], operands[4], INTVAL (operands[5]));
10245 DONE;})
10246
10247 (define_expand "atomic_compare_and_swap<mode>_internal"
10248 [(parallel
10249 [(set (match_operand:DGPR 0 "register_operand")
10250 (match_operand:DGPR 1 "s_operand"))
10251 (set (match_dup 1)
10252 (unspec_volatile:DGPR
10253 [(match_dup 1)
10254 (match_operand:DGPR 2 "register_operand")
10255 (match_operand:DGPR 3 "register_operand")]
10256 UNSPECV_CAS))
10257 (set (match_operand 4 "cc_reg_operand")
10258 (match_dup 5))])]
10259 "GET_MODE (operands[4]) == CCZmode
10260 || GET_MODE (operands[4]) == CCZ1mode"
10261 {
10262 operands[5]
10263 = gen_rtx_COMPARE (GET_MODE (operands[4]), operands[1], operands[2]);
10264 })
10265
10266 ; cdsg, csg
10267 (define_insn "*atomic_compare_and_swap<mode>_1"
10268 [(set (match_operand:TDI 0 "register_operand" "=r")
10269 (match_operand:TDI 1 "memory_operand" "+S"))
10270 (set (match_dup 1)
10271 (unspec_volatile:TDI
10272 [(match_dup 1)
10273 (match_operand:TDI 2 "register_operand" "0")
10274 (match_operand:TDI 3 "register_operand" "r")]
10275 UNSPECV_CAS))
10276 (set (reg CC_REGNUM)
10277 (compare (match_dup 1) (match_dup 2)))]
10278 "TARGET_ZARCH
10279 && s390_match_ccmode (insn, CCZ1mode)"
10280 "c<td>sg\t%0,%3,%S1"
10281 [(set_attr "op_type" "RSY")
10282 (set_attr "type" "sem")])
10283
10284 ; cds, cdsy
10285 (define_insn "*atomic_compare_and_swapdi_2"
10286 [(set (match_operand:DI 0 "register_operand" "=r,r")
10287 (match_operand:DI 1 "memory_operand" "+Q,S"))
10288 (set (match_dup 1)
10289 (unspec_volatile:DI
10290 [(match_dup 1)
10291 (match_operand:DI 2 "register_operand" "0,0")
10292 (match_operand:DI 3 "register_operand" "r,r")]
10293 UNSPECV_CAS))
10294 (set (reg CC_REGNUM)
10295 (compare (match_dup 1) (match_dup 2)))]
10296 "!TARGET_ZARCH
10297 && s390_match_ccmode (insn, CCZ1mode)"
10298 "@
10299 cds\t%0,%3,%S1
10300 cdsy\t%0,%3,%S1"
10301 [(set_attr "op_type" "RS,RSY")
10302 (set_attr "cpu_facility" "*,longdisp")
10303 (set_attr "type" "sem")])
10304
10305 ; cs, csy
10306 (define_insn "*atomic_compare_and_swapsi_3"
10307 [(set (match_operand:SI 0 "register_operand" "=r,r")
10308 (match_operand:SI 1 "memory_operand" "+Q,S"))
10309 (set (match_dup 1)
10310 (unspec_volatile:SI
10311 [(match_dup 1)
10312 (match_operand:SI 2 "register_operand" "0,0")
10313 (match_operand:SI 3 "register_operand" "r,r")]
10314 UNSPECV_CAS))
10315 (set (reg CC_REGNUM)
10316 (compare (match_dup 1) (match_dup 2)))]
10317 "s390_match_ccmode (insn, CCZ1mode)"
10318 "@
10319 cs\t%0,%3,%S1
10320 csy\t%0,%3,%S1"
10321 [(set_attr "op_type" "RS,RSY")
10322 (set_attr "cpu_facility" "*,longdisp")
10323 (set_attr "type" "sem")])
10324
10325 ;
10326 ; Other atomic instruction patterns.
10327 ;
10328
10329 ; z196 load and add, xor, or and and instructions
10330
10331 (define_expand "atomic_fetch_<atomic><mode>"
10332 [(match_operand:GPR 0 "register_operand") ;; val out
10333 (ATOMIC_Z196:GPR
10334 (match_operand:GPR 1 "memory_operand") ;; memory
10335 (match_operand:GPR 2 "register_operand")) ;; val in
10336 (match_operand:SI 3 "const_int_operand")] ;; model
10337 "TARGET_Z196"
10338 {
10339 if (MEM_ALIGN (operands[1]) < GET_MODE_BITSIZE (GET_MODE (operands[1])))
10340 FAIL;
10341
10342 emit_insn (gen_atomic_fetch_<atomic><mode>_iaf
10343 (operands[0], operands[1], operands[2]));
10344 DONE;
10345 })
10346
10347 ; lan, lang, lao, laog, lax, laxg, laa, laag
10348 (define_insn "atomic_fetch_<atomic><mode>_iaf"
10349 [(set (match_operand:GPR 0 "register_operand" "=d")
10350 (match_operand:GPR 1 "memory_operand" "+S"))
10351 (set (match_dup 1)
10352 (unspec_volatile:GPR
10353 [(ATOMIC_Z196:GPR (match_dup 1)
10354 (match_operand:GPR 2 "general_operand" "d"))]
10355 UNSPECV_ATOMIC_OP))
10356 (clobber (reg:CC CC_REGNUM))]
10357 "TARGET_Z196"
10358 "la<noxa><g>\t%0,%2,%1"
10359 [(set_attr "op_type" "RSY")
10360 (set_attr "type" "sem")])
10361
10362 ;; For SImode and larger, the optabs.c code will do just fine in
10363 ;; expanding a compare-and-swap loop. For QI/HImode, we can do
10364 ;; better by expanding our own loop.
10365
10366 (define_expand "atomic_<atomic><mode>"
10367 [(ATOMIC:HQI
10368 (match_operand:HQI 0 "memory_operand") ;; memory
10369 (match_operand:HQI 1 "general_operand")) ;; val in
10370 (match_operand:SI 2 "const_int_operand")] ;; model
10371 ""
10372 {
10373 s390_expand_atomic (<MODE>mode, <CODE>, NULL_RTX, operands[0],
10374 operands[1], false);
10375 DONE;
10376 })
10377
10378 (define_expand "atomic_fetch_<atomic><mode>"
10379 [(match_operand:HQI 0 "register_operand") ;; val out
10380 (ATOMIC:HQI
10381 (match_operand:HQI 1 "memory_operand") ;; memory
10382 (match_operand:HQI 2 "general_operand")) ;; val in
10383 (match_operand:SI 3 "const_int_operand")] ;; model
10384 ""
10385 {
10386 s390_expand_atomic (<MODE>mode, <CODE>, operands[0], operands[1],
10387 operands[2], false);
10388 DONE;
10389 })
10390
10391 (define_expand "atomic_<atomic>_fetch<mode>"
10392 [(match_operand:HQI 0 "register_operand") ;; val out
10393 (ATOMIC:HQI
10394 (match_operand:HQI 1 "memory_operand") ;; memory
10395 (match_operand:HQI 2 "general_operand")) ;; val in
10396 (match_operand:SI 3 "const_int_operand")] ;; model
10397 ""
10398 {
10399 s390_expand_atomic (<MODE>mode, <CODE>, operands[0], operands[1],
10400 operands[2], true);
10401 DONE;
10402 })
10403
10404 ;; Pattern to implement atomic_exchange with a compare-and-swap loop. The code
10405 ;; generated by the middleend is not good.
10406 (define_expand "atomic_exchange<mode>"
10407 [(match_operand:DINT 0 "register_operand") ;; val out
10408 (match_operand:DINT 1 "s_operand") ;; memory
10409 (match_operand:DINT 2 "general_operand") ;; val in
10410 (match_operand:SI 3 "const_int_operand")] ;; model
10411 ""
10412 {
10413 if (<MODE>mode != QImode
10414 && MEM_ALIGN (operands[1]) < GET_MODE_BITSIZE (<MODE>mode))
10415 FAIL;
10416 if (<MODE>mode == HImode || <MODE>mode == QImode)
10417 s390_expand_atomic (<MODE>mode, SET, operands[0], operands[1], operands[2],
10418 false);
10419 else if (<MODE>mode == SImode || TARGET_ZARCH)
10420 s390_expand_atomic_exchange_tdsi (operands[0], operands[1], operands[2]);
10421 else
10422 FAIL;
10423 DONE;
10424 })
10425
10426 ;;
10427 ;;- Miscellaneous instructions.
10428 ;;
10429
10430 ;
10431 ; allocate stack instruction pattern(s).
10432 ;
10433
10434 (define_expand "allocate_stack"
10435 [(match_operand 0 "general_operand" "")
10436 (match_operand 1 "general_operand" "")]
10437 "TARGET_BACKCHAIN"
10438 {
10439 rtx temp = gen_reg_rtx (Pmode);
10440
10441 emit_move_insn (temp, s390_back_chain_rtx ());
10442 anti_adjust_stack (operands[1]);
10443 emit_move_insn (s390_back_chain_rtx (), temp);
10444
10445 emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
10446 DONE;
10447 })
10448
10449
10450 ;
10451 ; setjmp instruction pattern.
10452 ;
10453
10454 (define_expand "builtin_setjmp_receiver"
10455 [(match_operand 0 "" "")]
10456 "flag_pic"
10457 {
10458 emit_insn (s390_load_got ());
10459 emit_use (pic_offset_table_rtx);
10460 DONE;
10461 })
10462
10463 ;; These patterns say how to save and restore the stack pointer. We need not
10464 ;; save the stack pointer at function level since we are careful to
10465 ;; preserve the backchain. At block level, we have to restore the backchain
10466 ;; when we restore the stack pointer.
10467 ;;
10468 ;; For nonlocal gotos, we must save both the stack pointer and its
10469 ;; backchain and restore both. Note that in the nonlocal case, the
10470 ;; save area is a memory location.
10471
10472 (define_expand "save_stack_function"
10473 [(match_operand 0 "general_operand" "")
10474 (match_operand 1 "general_operand" "")]
10475 ""
10476 "DONE;")
10477
10478 (define_expand "restore_stack_function"
10479 [(match_operand 0 "general_operand" "")
10480 (match_operand 1 "general_operand" "")]
10481 ""
10482 "DONE;")
10483
10484 (define_expand "restore_stack_block"
10485 [(match_operand 0 "register_operand" "")
10486 (match_operand 1 "register_operand" "")]
10487 "TARGET_BACKCHAIN"
10488 {
10489 rtx temp = gen_reg_rtx (Pmode);
10490
10491 emit_move_insn (temp, s390_back_chain_rtx ());
10492 emit_move_insn (operands[0], operands[1]);
10493 emit_move_insn (s390_back_chain_rtx (), temp);
10494
10495 DONE;
10496 })
10497
10498 (define_expand "save_stack_nonlocal"
10499 [(match_operand 0 "memory_operand" "")
10500 (match_operand 1 "register_operand" "")]
10501 ""
10502 {
10503 rtx base = gen_rtx_REG (Pmode, BASE_REGNUM);
10504
10505 /* Copy the backchain to the first word, sp to the second and the
10506 literal pool base to the third. */
10507
10508 rtx save_bc = adjust_address (operands[0], Pmode, 0);
10509 rtx save_sp = adjust_address (operands[0], Pmode, GET_MODE_SIZE (Pmode));
10510 rtx save_bp = adjust_address (operands[0], Pmode, 2 * GET_MODE_SIZE (Pmode));
10511
10512 if (TARGET_BACKCHAIN)
10513 emit_move_insn (save_bc, force_reg (Pmode, s390_back_chain_rtx ()));
10514
10515 emit_move_insn (save_sp, operands[1]);
10516 emit_move_insn (save_bp, base);
10517
10518 DONE;
10519 })
10520
10521 (define_expand "restore_stack_nonlocal"
10522 [(match_operand 0 "register_operand" "")
10523 (match_operand 1 "memory_operand" "")]
10524 ""
10525 {
10526 rtx base = gen_rtx_REG (Pmode, BASE_REGNUM);
10527 rtx temp = NULL_RTX;
10528
10529 /* Restore the backchain from the first word, sp from the second and the
10530 literal pool base from the third. */
10531
10532 rtx save_bc = adjust_address (operands[1], Pmode, 0);
10533 rtx save_sp = adjust_address (operands[1], Pmode, GET_MODE_SIZE (Pmode));
10534 rtx save_bp = adjust_address (operands[1], Pmode, 2 * GET_MODE_SIZE (Pmode));
10535
10536 if (TARGET_BACKCHAIN)
10537 temp = force_reg (Pmode, save_bc);
10538
10539 emit_move_insn (base, save_bp);
10540 emit_move_insn (operands[0], save_sp);
10541
10542 if (temp)
10543 emit_move_insn (s390_back_chain_rtx (), temp);
10544
10545 emit_use (base);
10546 DONE;
10547 })
10548
10549 (define_expand "exception_receiver"
10550 [(const_int 0)]
10551 ""
10552 {
10553 s390_set_has_landing_pad_p (true);
10554 DONE;
10555 })
10556
10557 ;
10558 ; nop instruction pattern(s).
10559 ;
10560
10561 (define_insn "nop"
10562 [(const_int 0)]
10563 ""
10564 "lr\t0,0"
10565 [(set_attr "op_type" "RR")
10566 (set_attr "z10prop" "z10_fr_E1")])
10567
10568 (define_insn "nop1"
10569 [(const_int 1)]
10570 ""
10571 "lr\t1,1"
10572 [(set_attr "op_type" "RR")])
10573
10574 ;;- Undeletable nops (used for hotpatching)
10575
10576 (define_insn "nop_2_byte"
10577 [(unspec_volatile [(const_int 0)] UNSPECV_NOP_2_BYTE)]
10578 ""
10579 "nopr\t%%r0"
10580 [(set_attr "op_type" "RR")])
10581
10582 (define_insn "nop_4_byte"
10583 [(unspec_volatile [(const_int 0)] UNSPECV_NOP_4_BYTE)]
10584 ""
10585 "nop\t0"
10586 [(set_attr "op_type" "RX")])
10587
10588 (define_insn "nop_6_byte"
10589 [(unspec_volatile [(const_int 0)] UNSPECV_NOP_6_BYTE)]
10590 "TARGET_CPU_ZARCH"
10591 "brcl\t0, 0"
10592 [(set_attr "op_type" "RIL")])
10593
10594
10595 ;
10596 ; Special literal pool access instruction pattern(s).
10597 ;
10598
10599 (define_insn "*pool_entry"
10600 [(unspec_volatile [(match_operand 0 "consttable_operand" "X")]
10601 UNSPECV_POOL_ENTRY)]
10602 ""
10603 {
10604 machine_mode mode = GET_MODE (PATTERN (insn));
10605 unsigned int align = GET_MODE_BITSIZE (mode);
10606 s390_output_pool_entry (operands[0], mode, align);
10607 return "";
10608 }
10609 [(set (attr "length")
10610 (symbol_ref "GET_MODE_SIZE (GET_MODE (PATTERN (insn)))"))])
10611
10612 (define_insn "pool_align"
10613 [(unspec_volatile [(match_operand 0 "const_int_operand" "n")]
10614 UNSPECV_POOL_ALIGN)]
10615 ""
10616 ".align\t%0"
10617 [(set (attr "length") (symbol_ref "INTVAL (operands[0])"))])
10618
10619 (define_insn "pool_section_start"
10620 [(unspec_volatile [(const_int 1)] UNSPECV_POOL_SECTION)]
10621 ""
10622 {
10623 switch_to_section (targetm.asm_out.function_rodata_section
10624 (current_function_decl));
10625 return "";
10626 }
10627 [(set_attr "length" "0")])
10628
10629 (define_insn "pool_section_end"
10630 [(unspec_volatile [(const_int 0)] UNSPECV_POOL_SECTION)]
10631 ""
10632 {
10633 switch_to_section (current_function_section ());
10634 return "";
10635 }
10636 [(set_attr "length" "0")])
10637
10638 (define_insn "main_base_31_small"
10639 [(set (match_operand 0 "register_operand" "=a")
10640 (unspec [(label_ref (match_operand 1 "" ""))] UNSPEC_MAIN_BASE))]
10641 "!TARGET_CPU_ZARCH && GET_MODE (operands[0]) == Pmode"
10642 "basr\t%0,0"
10643 [(set_attr "op_type" "RR")
10644 (set_attr "type" "la")
10645 (set_attr "z196prop" "z196_cracked")])
10646
10647 (define_insn "main_base_31_large"
10648 [(set (match_operand 0 "register_operand" "=a")
10649 (unspec [(label_ref (match_operand 1 "" ""))] UNSPEC_MAIN_BASE))
10650 (set (pc) (label_ref (match_operand 2 "" "")))]
10651 "!TARGET_CPU_ZARCH && GET_MODE (operands[0]) == Pmode"
10652 "bras\t%0,%2"
10653 [(set_attr "op_type" "RI")
10654 (set_attr "z196prop" "z196_cracked")])
10655
10656 (define_insn "main_base_64"
10657 [(set (match_operand 0 "register_operand" "=a")
10658 (unspec [(label_ref (match_operand 1 "" ""))] UNSPEC_MAIN_BASE))]
10659 "TARGET_CPU_ZARCH && GET_MODE (operands[0]) == Pmode"
10660 "larl\t%0,%1"
10661 [(set_attr "op_type" "RIL")
10662 (set_attr "type" "larl")
10663 (set_attr "z10prop" "z10_fwd_A1")])
10664
10665 (define_insn "main_pool"
10666 [(set (match_operand 0 "register_operand" "=a")
10667 (unspec_volatile [(const_int 0)] UNSPECV_MAIN_POOL))]
10668 "GET_MODE (operands[0]) == Pmode"
10669 {
10670 gcc_unreachable ();
10671 }
10672 [(set (attr "type")
10673 (if_then_else (match_test "TARGET_CPU_ZARCH")
10674 (const_string "larl") (const_string "la")))])
10675
10676 (define_insn "reload_base_31"
10677 [(set (match_operand 0 "register_operand" "=a")
10678 (unspec [(label_ref (match_operand 1 "" ""))] UNSPEC_RELOAD_BASE))]
10679 "!TARGET_CPU_ZARCH && GET_MODE (operands[0]) == Pmode"
10680 "basr\t%0,0\;la\t%0,%1-.(%0)"
10681 [(set_attr "length" "6")
10682 (set_attr "type" "la")
10683 (set_attr "z196prop" "z196_cracked")])
10684
10685 (define_insn "reload_base_64"
10686 [(set (match_operand 0 "register_operand" "=a")
10687 (unspec [(label_ref (match_operand 1 "" ""))] UNSPEC_RELOAD_BASE))]
10688 "TARGET_CPU_ZARCH && GET_MODE (operands[0]) == Pmode"
10689 "larl\t%0,%1"
10690 [(set_attr "op_type" "RIL")
10691 (set_attr "type" "larl")
10692 (set_attr "z10prop" "z10_fwd_A1")])
10693
10694 (define_insn "pool"
10695 [(unspec_volatile [(match_operand 0 "const_int_operand" "n")] UNSPECV_POOL)]
10696 ""
10697 {
10698 gcc_unreachable ();
10699 }
10700 [(set (attr "length") (symbol_ref "INTVAL (operands[0])"))])
10701
10702 ;;
10703 ;; Insns related to generating the function prologue and epilogue.
10704 ;;
10705
10706
10707 (define_expand "prologue"
10708 [(use (const_int 0))]
10709 ""
10710 "s390_emit_prologue (); DONE;")
10711
10712 (define_expand "epilogue"
10713 [(use (const_int 1))]
10714 ""
10715 "s390_emit_epilogue (false); DONE;")
10716
10717 (define_expand "sibcall_epilogue"
10718 [(use (const_int 0))]
10719 ""
10720 "s390_emit_epilogue (true); DONE;")
10721
10722 ;; A direct return instruction, without using an epilogue.
10723 (define_insn "<code>"
10724 [(ANY_RETURN)]
10725 "s390_can_use_<code>_insn ()"
10726 "br\t%%r14"
10727 [(set_attr "op_type" "RR")
10728 (set_attr "type" "jsr")
10729 (set_attr "atype" "agen")])
10730
10731 (define_insn "*return"
10732 [(return)
10733 (use (match_operand 0 "register_operand" "a"))]
10734 "GET_MODE (operands[0]) == Pmode"
10735 "br\t%0"
10736 [(set_attr "op_type" "RR")
10737 (set_attr "type" "jsr")
10738 (set_attr "atype" "agen")])
10739
10740
10741 ;; Instruction definition to extend a 31-bit pointer into a 64-bit
10742 ;; pointer. This is used for compatibility.
10743
10744 (define_expand "ptr_extend"
10745 [(set (match_operand:DI 0 "register_operand" "=r")
10746 (match_operand:SI 1 "register_operand" "r"))]
10747 "TARGET_64BIT"
10748 {
10749 emit_insn (gen_anddi3 (operands[0],
10750 gen_lowpart (DImode, operands[1]),
10751 GEN_INT (0x7fffffff)));
10752 DONE;
10753 })
10754
10755 ;; Instruction definition to expand eh_return macro to support
10756 ;; swapping in special linkage return addresses.
10757
10758 (define_expand "eh_return"
10759 [(use (match_operand 0 "register_operand" ""))]
10760 "TARGET_TPF"
10761 {
10762 s390_emit_tpf_eh_return (operands[0]);
10763 DONE;
10764 })
10765
10766 ;
10767 ; Stack Protector Patterns
10768 ;
10769
10770 (define_expand "stack_protect_set"
10771 [(set (match_operand 0 "memory_operand" "")
10772 (match_operand 1 "memory_operand" ""))]
10773 ""
10774 {
10775 #ifdef TARGET_THREAD_SSP_OFFSET
10776 operands[1]
10777 = gen_rtx_MEM (Pmode, gen_rtx_PLUS (Pmode, s390_get_thread_pointer (),
10778 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
10779 #endif
10780 if (TARGET_64BIT)
10781 emit_insn (gen_stack_protect_setdi (operands[0], operands[1]));
10782 else
10783 emit_insn (gen_stack_protect_setsi (operands[0], operands[1]));
10784
10785 DONE;
10786 })
10787
10788 (define_insn "stack_protect_set<mode>"
10789 [(set (match_operand:DSI 0 "memory_operand" "=Q")
10790 (unspec:DSI [(match_operand:DSI 1 "memory_operand" "Q")] UNSPEC_SP_SET))]
10791 ""
10792 "mvc\t%O0(%G0,%R0),%S1"
10793 [(set_attr "op_type" "SS")])
10794
10795 (define_expand "stack_protect_test"
10796 [(set (reg:CC CC_REGNUM)
10797 (compare (match_operand 0 "memory_operand" "")
10798 (match_operand 1 "memory_operand" "")))
10799 (match_operand 2 "" "")]
10800 ""
10801 {
10802 rtx cc_reg, test;
10803 #ifdef TARGET_THREAD_SSP_OFFSET
10804 operands[1]
10805 = gen_rtx_MEM (Pmode, gen_rtx_PLUS (Pmode, s390_get_thread_pointer (),
10806 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
10807 #endif
10808 if (TARGET_64BIT)
10809 emit_insn (gen_stack_protect_testdi (operands[0], operands[1]));
10810 else
10811 emit_insn (gen_stack_protect_testsi (operands[0], operands[1]));
10812
10813 cc_reg = gen_rtx_REG (CCZmode, CC_REGNUM);
10814 test = gen_rtx_EQ (VOIDmode, cc_reg, const0_rtx);
10815 emit_jump_insn (gen_cbranchcc4 (test, cc_reg, const0_rtx, operands[2]));
10816 DONE;
10817 })
10818
10819 (define_insn "stack_protect_test<mode>"
10820 [(set (reg:CCZ CC_REGNUM)
10821 (unspec:CCZ [(match_operand:DSI 0 "memory_operand" "Q")
10822 (match_operand:DSI 1 "memory_operand" "Q")] UNSPEC_SP_TEST))]
10823 ""
10824 "clc\t%O0(%G0,%R0),%S1"
10825 [(set_attr "op_type" "SS")])
10826
10827 ; This is used in s390_emit_prologue in order to prevent insns
10828 ; adjusting the stack pointer to be moved over insns writing stack
10829 ; slots using a copy of the stack pointer in a different register.
10830 (define_insn "stack_tie"
10831 [(set (match_operand:BLK 0 "memory_operand" "+m")
10832 (unspec:BLK [(match_dup 0)] UNSPEC_TIE))]
10833 ""
10834 ""
10835 [(set_attr "length" "0")])
10836
10837
10838 (define_insn "stack_restore_from_fpr"
10839 [(set (reg:DI STACK_REGNUM)
10840 (match_operand:DI 0 "register_operand" "f"))
10841 (clobber (mem:BLK (scratch)))]
10842 "TARGET_Z10"
10843 "lgdr\t%%r15,%0"
10844 [(set_attr "op_type" "RRE")])
10845
10846 ;
10847 ; Data prefetch patterns
10848 ;
10849
10850 (define_insn "prefetch"
10851 [(prefetch (match_operand 0 "address_operand" "ZT,X")
10852 (match_operand:SI 1 "const_int_operand" " n,n")
10853 (match_operand:SI 2 "const_int_operand" " n,n"))]
10854 "TARGET_Z10"
10855 {
10856 switch (which_alternative)
10857 {
10858 case 0:
10859 return INTVAL (operands[1]) == 1 ? "pfd\t2,%a0" : "pfd\t1,%a0";
10860 case 1:
10861 if (larl_operand (operands[0], Pmode))
10862 return INTVAL (operands[1]) == 1 ? "pfdrl\t2,%a0" : "pfdrl\t1,%a0";
10863 /* fallthrough */
10864 default:
10865
10866 /* This might be reached for symbolic operands with an odd
10867 addend. We simply omit the prefetch for such rare cases. */
10868
10869 return "";
10870 }
10871 }
10872 [(set_attr "type" "load,larl")
10873 (set_attr "op_type" "RXY,RIL")
10874 (set_attr "z10prop" "z10_super")
10875 (set_attr "z196prop" "z196_alone")])
10876
10877
10878 ;
10879 ; Byte swap instructions
10880 ;
10881
10882 ; FIXME: There is also mvcin but we cannot use it since src and target
10883 ; may overlap.
10884 ; lrvr, lrv, strv, lrvgr, lrvg, strvg
10885 (define_insn "bswap<mode>2"
10886 [(set (match_operand:GPR 0 "nonimmediate_operand" "=d,d,T")
10887 (bswap:GPR (match_operand:GPR 1 "nonimmediate_operand" " d,T,d")))]
10888 "TARGET_CPU_ZARCH"
10889 "@
10890 lrv<g>r\t%0,%1
10891 lrv<g>\t%0,%1
10892 strv<g>\t%1,%0"
10893 [(set_attr "type" "*,load,store")
10894 (set_attr "op_type" "RRE,RXY,RXY")
10895 (set_attr "z10prop" "z10_super")])
10896
10897 (define_insn "bswaphi2"
10898 [(set (match_operand:HI 0 "nonimmediate_operand" "=d,d,T")
10899 (bswap:HI (match_operand:HI 1 "nonimmediate_operand" " d,T,d")))]
10900 "TARGET_CPU_ZARCH"
10901 "@
10902 #
10903 lrvh\t%0,%1
10904 strvh\t%1,%0"
10905 [(set_attr "type" "*,load,store")
10906 (set_attr "op_type" "RRE,RXY,RXY")
10907 (set_attr "z10prop" "z10_super")])
10908
10909 (define_split
10910 [(set (match_operand:HI 0 "register_operand" "")
10911 (bswap:HI (match_operand:HI 1 "register_operand" "")))]
10912 "TARGET_CPU_ZARCH"
10913 [(set (match_dup 2) (bswap:SI (match_dup 3)))
10914 (set (match_dup 2) (lshiftrt:SI (match_dup 2) (const_int 16)))]
10915 {
10916 operands[2] = simplify_gen_subreg (SImode, operands[0], HImode, 0);
10917 operands[3] = simplify_gen_subreg (SImode, operands[1], HImode, 0);
10918 })
10919
10920
10921 ;
10922 ; Population count instruction
10923 ;
10924
10925 ; The S/390 popcount instruction counts the bits of op1 in 8 byte
10926 ; portions and stores the result in the corresponding bytes in op0.
10927 (define_insn "*popcount<mode>"
10928 [(set (match_operand:INT 0 "register_operand" "=d")
10929 (unspec:INT [(match_operand:INT 1 "register_operand" "d")] UNSPEC_POPCNT))
10930 (clobber (reg:CC CC_REGNUM))]
10931 "TARGET_Z196"
10932 "popcnt\t%0,%1"
10933 [(set_attr "op_type" "RRE")])
10934
10935 (define_expand "popcountdi2"
10936 [; popcnt op0, op1
10937 (parallel [(set (match_operand:DI 0 "register_operand" "")
10938 (unspec:DI [(match_operand:DI 1 "register_operand")]
10939 UNSPEC_POPCNT))
10940 (clobber (reg:CC CC_REGNUM))])
10941 ; sllg op2, op0, 32
10942 (set (match_dup 2) (ashift:DI (match_dup 0) (const_int 32)))
10943 ; agr op0, op2
10944 (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 2)))
10945 (clobber (reg:CC CC_REGNUM))])
10946 ; sllg op2, op0, 16
10947 (set (match_dup 2)
10948 (ashift:DI (match_dup 0) (const_int 16)))
10949 ; agr op0, op2
10950 (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 2)))
10951 (clobber (reg:CC CC_REGNUM))])
10952 ; sllg op2, op0, 8
10953 (set (match_dup 2) (ashift:DI (match_dup 0) (const_int 8)))
10954 ; agr op0, op2
10955 (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 2)))
10956 (clobber (reg:CC CC_REGNUM))])
10957 ; srlg op0, op0, 56
10958 (set (match_dup 0) (lshiftrt:DI (match_dup 0) (const_int 56)))]
10959 "TARGET_Z196 && TARGET_64BIT"
10960 "operands[2] = gen_reg_rtx (DImode);")
10961
10962 (define_expand "popcountsi2"
10963 [; popcnt op0, op1
10964 (parallel [(set (match_operand:SI 0 "register_operand" "")
10965 (unspec:SI [(match_operand:SI 1 "register_operand")]
10966 UNSPEC_POPCNT))
10967 (clobber (reg:CC CC_REGNUM))])
10968 ; sllk op2, op0, 16
10969 (set (match_dup 2)
10970 (ashift:SI (match_dup 0) (const_int 16)))
10971 ; ar op0, op2
10972 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
10973 (clobber (reg:CC CC_REGNUM))])
10974 ; sllk op2, op0, 8
10975 (set (match_dup 2) (ashift:SI (match_dup 0) (const_int 8)))
10976 ; ar op0, op2
10977 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
10978 (clobber (reg:CC CC_REGNUM))])
10979 ; srl op0, op0, 24
10980 (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 24)))]
10981 "TARGET_Z196"
10982 "operands[2] = gen_reg_rtx (SImode);")
10983
10984 (define_expand "popcounthi2"
10985 [; popcnt op0, op1
10986 (parallel [(set (match_operand:HI 0 "register_operand" "")
10987 (unspec:HI [(match_operand:HI 1 "register_operand")]
10988 UNSPEC_POPCNT))
10989 (clobber (reg:CC CC_REGNUM))])
10990 ; sllk op2, op0, 8
10991 (set (match_dup 2)
10992 (ashift:SI (match_dup 0) (const_int 8)))
10993 ; ar op0, op2
10994 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
10995 (clobber (reg:CC CC_REGNUM))])
10996 ; srl op0, op0, 8
10997 (set (match_dup 0) (lshiftrt:HI (match_dup 0) (const_int 8)))]
10998 "TARGET_Z196"
10999 "operands[2] = gen_reg_rtx (SImode);")
11000
11001 (define_expand "popcountqi2"
11002 [; popcnt op0, op1
11003 (parallel [(set (match_operand:QI 0 "register_operand" "")
11004 (unspec:QI [(match_operand:QI 1 "register_operand")]
11005 UNSPEC_POPCNT))
11006 (clobber (reg:CC CC_REGNUM))])]
11007 "TARGET_Z196"
11008 "")
11009
11010 ;;
11011 ;;- Copy sign instructions
11012 ;;
11013
11014 (define_insn "copysign<mode>3"
11015 [(set (match_operand:FP 0 "register_operand" "=f")
11016 (unspec:FP [(match_operand:FP 1 "register_operand" "<fT0>")
11017 (match_operand:FP 2 "register_operand" "f")]
11018 UNSPEC_COPYSIGN))]
11019 "TARGET_Z196"
11020 "cpsdr\t%0,%2,%1"
11021 [(set_attr "op_type" "RRF")
11022 (set_attr "type" "fsimp<mode>")])
11023
11024
11025 ;;
11026 ;;- Transactional execution instructions
11027 ;;
11028
11029 ; This splitter helps combine to make use of CC directly when
11030 ; comparing the integer result of a tbegin builtin with a constant.
11031 ; The unspec is already removed by canonicalize_comparison. So this
11032 ; splitters only job is to turn the PARALLEL into separate insns
11033 ; again. Unfortunately this only works with the very first cc/int
11034 ; compare since combine is not able to deal with data flow across
11035 ; basic block boundaries.
11036
11037 ; It needs to be an insn pattern as well since combine does not apply
11038 ; the splitter directly. Combine would only use it if it actually
11039 ; would reduce the number of instructions.
11040 (define_insn_and_split "*ccraw_to_int"
11041 [(set (pc)
11042 (if_then_else
11043 (match_operator 0 "s390_eqne_operator"
11044 [(reg:CCRAW CC_REGNUM)
11045 (match_operand 1 "const_int_operand" "")])
11046 (label_ref (match_operand 2 "" ""))
11047 (pc)))
11048 (set (match_operand:SI 3 "register_operand" "=d")
11049 (unspec:SI [(reg:CCRAW CC_REGNUM)] UNSPEC_CC_TO_INT))]
11050 ""
11051 "#"
11052 ""
11053 [(set (match_dup 3)
11054 (unspec:SI [(reg:CCRAW CC_REGNUM)] UNSPEC_CC_TO_INT))
11055 (set (pc)
11056 (if_then_else (match_op_dup 0 [(reg:CCRAW CC_REGNUM) (match_dup 1)])
11057 (label_ref (match_dup 2))
11058 (pc)))]
11059 "")
11060
11061 ; Non-constrained transaction begin
11062
11063 (define_expand "tbegin"
11064 [(match_operand:SI 0 "register_operand" "")
11065 (match_operand:BLK 1 "memory_operand" "")]
11066 "TARGET_HTM"
11067 {
11068 s390_expand_tbegin (operands[0], operands[1], NULL_RTX, true);
11069 DONE;
11070 })
11071
11072 (define_expand "tbegin_nofloat"
11073 [(match_operand:SI 0 "register_operand" "")
11074 (match_operand:BLK 1 "memory_operand" "")]
11075 "TARGET_HTM"
11076 {
11077 s390_expand_tbegin (operands[0], operands[1], NULL_RTX, false);
11078 DONE;
11079 })
11080
11081 (define_expand "tbegin_retry"
11082 [(match_operand:SI 0 "register_operand" "")
11083 (match_operand:BLK 1 "memory_operand" "")
11084 (match_operand:SI 2 "general_operand" "")]
11085 "TARGET_HTM"
11086 {
11087 s390_expand_tbegin (operands[0], operands[1], operands[2], true);
11088 DONE;
11089 })
11090
11091 (define_expand "tbegin_retry_nofloat"
11092 [(match_operand:SI 0 "register_operand" "")
11093 (match_operand:BLK 1 "memory_operand" "")
11094 (match_operand:SI 2 "general_operand" "")]
11095 "TARGET_HTM"
11096 {
11097 s390_expand_tbegin (operands[0], operands[1], operands[2], false);
11098 DONE;
11099 })
11100
11101 ; Clobber VRs since they don't get restored
11102 (define_insn "tbegin_1_z13"
11103 [(set (reg:CCRAW CC_REGNUM)
11104 (unspec_volatile:CCRAW [(match_operand 0 "const_int_operand" "D")]
11105 UNSPECV_TBEGIN))
11106 (set (match_operand:BLK 1 "memory_operand" "=Q")
11107 (unspec_volatile:BLK [(match_dup 0)] UNSPECV_TBEGIN_TDB))
11108 (clobber (reg:TI 16)) (clobber (reg:TI 38))
11109 (clobber (reg:TI 17)) (clobber (reg:TI 39))
11110 (clobber (reg:TI 18)) (clobber (reg:TI 40))
11111 (clobber (reg:TI 19)) (clobber (reg:TI 41))
11112 (clobber (reg:TI 20)) (clobber (reg:TI 42))
11113 (clobber (reg:TI 21)) (clobber (reg:TI 43))
11114 (clobber (reg:TI 22)) (clobber (reg:TI 44))
11115 (clobber (reg:TI 23)) (clobber (reg:TI 45))
11116 (clobber (reg:TI 24)) (clobber (reg:TI 46))
11117 (clobber (reg:TI 25)) (clobber (reg:TI 47))
11118 (clobber (reg:TI 26)) (clobber (reg:TI 48))
11119 (clobber (reg:TI 27)) (clobber (reg:TI 49))
11120 (clobber (reg:TI 28)) (clobber (reg:TI 50))
11121 (clobber (reg:TI 29)) (clobber (reg:TI 51))
11122 (clobber (reg:TI 30)) (clobber (reg:TI 52))
11123 (clobber (reg:TI 31)) (clobber (reg:TI 53))]
11124 ; CONST_OK_FOR_CONSTRAINT_P does not work with D constraint since D is
11125 ; not supposed to be used for immediates (see genpreds.c).
11126 "TARGET_VX && INTVAL (operands[0]) >= 0 && INTVAL (operands[0]) <= 0xffff"
11127 "tbegin\t%1,%x0"
11128 [(set_attr "op_type" "SIL")])
11129
11130 (define_insn "tbegin_1"
11131 [(set (reg:CCRAW CC_REGNUM)
11132 (unspec_volatile:CCRAW [(match_operand 0 "const_int_operand" "D")]
11133 UNSPECV_TBEGIN))
11134 (set (match_operand:BLK 1 "memory_operand" "=Q")
11135 (unspec_volatile:BLK [(match_dup 0)] UNSPECV_TBEGIN_TDB))
11136 (clobber (reg:DF 16))
11137 (clobber (reg:DF 17))
11138 (clobber (reg:DF 18))
11139 (clobber (reg:DF 19))
11140 (clobber (reg:DF 20))
11141 (clobber (reg:DF 21))
11142 (clobber (reg:DF 22))
11143 (clobber (reg:DF 23))
11144 (clobber (reg:DF 24))
11145 (clobber (reg:DF 25))
11146 (clobber (reg:DF 26))
11147 (clobber (reg:DF 27))
11148 (clobber (reg:DF 28))
11149 (clobber (reg:DF 29))
11150 (clobber (reg:DF 30))
11151 (clobber (reg:DF 31))]
11152 ; CONST_OK_FOR_CONSTRAINT_P does not work with D constraint since D is
11153 ; not supposed to be used for immediates (see genpreds.c).
11154 "TARGET_HTM && INTVAL (operands[0]) >= 0 && INTVAL (operands[0]) <= 0xffff"
11155 "tbegin\t%1,%x0"
11156 [(set_attr "op_type" "SIL")])
11157
11158 ; Same as above but without the FPR clobbers
11159 (define_insn "tbegin_nofloat_1"
11160 [(set (reg:CCRAW CC_REGNUM)
11161 (unspec_volatile:CCRAW [(match_operand 0 "const_int_operand" "D")]
11162 UNSPECV_TBEGIN))
11163 (set (match_operand:BLK 1 "memory_operand" "=Q")
11164 (unspec_volatile:BLK [(match_dup 0)] UNSPECV_TBEGIN_TDB))]
11165 "TARGET_HTM && INTVAL (operands[0]) >= 0 && INTVAL (operands[0]) <= 0xffff"
11166 "tbegin\t%1,%x0"
11167 [(set_attr "op_type" "SIL")])
11168
11169
11170 ; Constrained transaction begin
11171
11172 (define_expand "tbeginc"
11173 [(set (reg:CCRAW CC_REGNUM)
11174 (unspec_volatile:CCRAW [(const_int TBEGINC_MASK)]
11175 UNSPECV_TBEGINC))]
11176 "TARGET_HTM"
11177 "")
11178
11179 (define_insn "*tbeginc_1"
11180 [(set (reg:CCRAW CC_REGNUM)
11181 (unspec_volatile:CCRAW [(match_operand 0 "const_int_operand" " D")]
11182 UNSPECV_TBEGINC))]
11183 "TARGET_HTM && INTVAL (operands[0]) >= 0 && INTVAL (operands[0]) <= 0xffff"
11184 "tbeginc\t0,%x0"
11185 [(set_attr "op_type" "SIL")])
11186
11187 ; Transaction end
11188
11189 (define_expand "tend"
11190 [(set (reg:CCRAW CC_REGNUM)
11191 (unspec_volatile:CCRAW [(const_int 0)] UNSPECV_TEND))
11192 (set (match_operand:SI 0 "register_operand" "")
11193 (unspec:SI [(reg:CCRAW CC_REGNUM)] UNSPEC_CC_TO_INT))]
11194 "TARGET_HTM"
11195 "")
11196
11197 (define_insn "*tend_1"
11198 [(set (reg:CCRAW CC_REGNUM)
11199 (unspec_volatile:CCRAW [(const_int 0)] UNSPECV_TEND))]
11200 "TARGET_HTM"
11201 "tend"
11202 [(set_attr "op_type" "S")])
11203
11204 ; Transaction abort
11205
11206 (define_expand "tabort"
11207 [(unspec_volatile [(match_operand:SI 0 "nonmemory_operand" "")]
11208 UNSPECV_TABORT)]
11209 "TARGET_HTM && operands != NULL"
11210 {
11211 if (CONST_INT_P (operands[0])
11212 && INTVAL (operands[0]) >= 0 && INTVAL (operands[0]) <= 255)
11213 {
11214 error ("invalid transaction abort code: " HOST_WIDE_INT_PRINT_DEC
11215 ". Values in range 0 through 255 are reserved.",
11216 INTVAL (operands[0]));
11217 FAIL;
11218 }
11219 })
11220
11221 (define_insn "*tabort_1"
11222 [(unspec_volatile [(match_operand:SI 0 "nonmemory_operand" "aJ")]
11223 UNSPECV_TABORT)]
11224 "TARGET_HTM && operands != NULL"
11225 "tabort\t%Y0"
11226 [(set_attr "op_type" "S")])
11227
11228 (define_insn "*tabort_1_plus"
11229 [(unspec_volatile [(plus:SI (match_operand:SI 0 "register_operand" "a")
11230 (match_operand:SI 1 "const_int_operand" "J"))]
11231 UNSPECV_TABORT)]
11232 "TARGET_HTM && operands != NULL
11233 && CONST_OK_FOR_CONSTRAINT_P (INTVAL (operands[1]), 'J', \"J\")"
11234 "tabort\t%1(%0)"
11235 [(set_attr "op_type" "S")])
11236
11237 ; Transaction extract nesting depth
11238
11239 (define_insn "etnd"
11240 [(set (match_operand:SI 0 "register_operand" "=d")
11241 (unspec_volatile:SI [(const_int 0)] UNSPECV_ETND))]
11242 "TARGET_HTM"
11243 "etnd\t%0"
11244 [(set_attr "op_type" "RRE")])
11245
11246 ; Non-transactional store
11247
11248 (define_insn "ntstg"
11249 [(set (match_operand:DI 0 "memory_operand" "=T")
11250 (unspec_volatile:DI [(match_operand:DI 1 "register_operand" "d")]
11251 UNSPECV_NTSTG))]
11252 "TARGET_HTM"
11253 "ntstg\t%1,%0"
11254 [(set_attr "op_type" "RXY")])
11255
11256 ; Transaction perform processor assist
11257
11258 (define_expand "tx_assist"
11259 [(unspec_volatile [(match_operand:SI 0 "register_operand" "")
11260 (reg:SI GPR0_REGNUM)
11261 (const_int 1)]
11262 UNSPECV_PPA)]
11263 "TARGET_HTM"
11264 "")
11265
11266 (define_insn "*ppa"
11267 [(unspec_volatile [(match_operand:SI 0 "register_operand" "d")
11268 (match_operand:SI 1 "register_operand" "d")
11269 (match_operand 2 "const_int_operand" "I")]
11270 UNSPECV_PPA)]
11271 "TARGET_HTM && INTVAL (operands[2]) < 16"
11272 "ppa\t%0,%1,%2"
11273 [(set_attr "op_type" "RRF")])
11274
11275
11276 ; Set and get floating point control register
11277
11278 (define_insn "sfpc"
11279 [(unspec_volatile [(match_operand:SI 0 "register_operand" "d")]
11280 UNSPECV_SFPC)]
11281 "TARGET_HARD_FLOAT"
11282 "sfpc\t%0")
11283
11284 (define_insn "efpc"
11285 [(set (match_operand:SI 0 "register_operand" "=d")
11286 (unspec_volatile:SI [(const_int 0)] UNSPECV_EFPC))]
11287 "TARGET_HARD_FLOAT"
11288 "efpc\t%0")
11289
11290
11291 ; Load count to block boundary
11292
11293 (define_insn "lcbb"
11294 [(set (match_operand:SI 0 "register_operand" "=d")
11295 (unspec:SI [(match_operand 1 "address_operand" "ZR")
11296 (match_operand:SI 2 "immediate_operand" "C")] UNSPEC_LCBB))
11297 (clobber (reg:CC CC_REGNUM))]
11298 "TARGET_Z13"
11299 "lcbb\t%0,%a1,%b2"
11300 [(set_attr "op_type" "VRX")])
11301
11302 ; Handle -fsplit-stack.
11303
11304 (define_expand "split_stack_prologue"
11305 [(const_int 0)]
11306 ""
11307 {
11308 s390_expand_split_stack_prologue ();
11309 DONE;
11310 })
11311
11312 ;; If there are operand 0 bytes available on the stack, jump to
11313 ;; operand 1.
11314
11315 (define_expand "split_stack_space_check"
11316 [(set (pc) (if_then_else
11317 (ltu (minus (reg 15)
11318 (match_operand 0 "register_operand"))
11319 (unspec [(const_int 0)] UNSPEC_STACK_CHECK))
11320 (label_ref (match_operand 1))
11321 (pc)))]
11322 ""
11323 {
11324 /* Offset from thread pointer to __private_ss. */
11325 int psso = TARGET_64BIT ? 0x38 : 0x20;
11326 rtx tp = s390_get_thread_pointer ();
11327 rtx guard = gen_rtx_MEM (Pmode, plus_constant (Pmode, tp, psso));
11328 rtx reg = gen_reg_rtx (Pmode);
11329 rtx cc;
11330 if (TARGET_64BIT)
11331 emit_insn (gen_subdi3 (reg, stack_pointer_rtx, operands[0]));
11332 else
11333 emit_insn (gen_subsi3 (reg, stack_pointer_rtx, operands[0]));
11334 cc = s390_emit_compare (GT, reg, guard);
11335 s390_emit_jump (operands[1], cc);
11336
11337 DONE;
11338 })
11339
11340 ;; __morestack parameter block for split stack prologue. Parameters are:
11341 ;; parameter block label, label to be called by __morestack, frame size,
11342 ;; stack parameter size.
11343
11344 (define_insn "split_stack_data"
11345 [(unspec_volatile [(match_operand 0 "" "X")
11346 (match_operand 1 "" "X")
11347 (match_operand 2 "const_int_operand" "X")
11348 (match_operand 3 "const_int_operand" "X")]
11349 UNSPECV_SPLIT_STACK_DATA)]
11350 "TARGET_CPU_ZARCH"
11351 {
11352 switch_to_section (targetm.asm_out.function_rodata_section
11353 (current_function_decl));
11354
11355 if (TARGET_64BIT)
11356 output_asm_insn (".align\t8", operands);
11357 else
11358 output_asm_insn (".align\t4", operands);
11359 (*targetm.asm_out.internal_label) (asm_out_file, "L",
11360 CODE_LABEL_NUMBER (operands[0]));
11361 if (TARGET_64BIT)
11362 {
11363 output_asm_insn (".quad\t%2", operands);
11364 output_asm_insn (".quad\t%3", operands);
11365 output_asm_insn (".quad\t%1-%0", operands);
11366 }
11367 else
11368 {
11369 output_asm_insn (".long\t%2", operands);
11370 output_asm_insn (".long\t%3", operands);
11371 output_asm_insn (".long\t%1-%0", operands);
11372 }
11373
11374 switch_to_section (current_function_section ());
11375 return "";
11376 }
11377 [(set_attr "length" "0")])
11378
11379
11380 ;; A jg with minimal fuss for use in split stack prologue.
11381
11382 (define_expand "split_stack_call"
11383 [(match_operand 0 "bras_sym_operand" "X")
11384 (match_operand 1 "" "")]
11385 "TARGET_CPU_ZARCH"
11386 {
11387 if (TARGET_64BIT)
11388 emit_jump_insn (gen_split_stack_call_di (operands[0], operands[1]));
11389 else
11390 emit_jump_insn (gen_split_stack_call_si (operands[0], operands[1]));
11391 DONE;
11392 })
11393
11394 (define_insn "split_stack_call_<mode>"
11395 [(set (pc) (label_ref (match_operand 1 "" "")))
11396 (set (reg:P 1) (unspec_volatile [(match_operand 0 "bras_sym_operand" "X")
11397 (reg:P 1)]
11398 UNSPECV_SPLIT_STACK_CALL))]
11399 "TARGET_CPU_ZARCH"
11400 "jg\t%0"
11401 [(set_attr "op_type" "RIL")
11402 (set_attr "type" "branch")])
11403
11404 ;; Also a conditional one.
11405
11406 (define_expand "split_stack_cond_call"
11407 [(match_operand 0 "bras_sym_operand" "X")
11408 (match_operand 1 "" "")
11409 (match_operand 2 "" "")]
11410 "TARGET_CPU_ZARCH"
11411 {
11412 if (TARGET_64BIT)
11413 emit_jump_insn (gen_split_stack_cond_call_di (operands[0], operands[1], operands[2]));
11414 else
11415 emit_jump_insn (gen_split_stack_cond_call_si (operands[0], operands[1], operands[2]));
11416 DONE;
11417 })
11418
11419 (define_insn "split_stack_cond_call_<mode>"
11420 [(set (pc)
11421 (if_then_else
11422 (match_operand 1 "" "")
11423 (label_ref (match_operand 2 "" ""))
11424 (pc)))
11425 (set (reg:P 1) (unspec_volatile [(match_operand 0 "bras_sym_operand" "X")
11426 (reg:P 1)]
11427 UNSPECV_SPLIT_STACK_CALL))]
11428 "TARGET_CPU_ZARCH"
11429 "jg%C1\t%0"
11430 [(set_attr "op_type" "RIL")
11431 (set_attr "type" "branch")])
11432
11433 (define_insn "osc_break"
11434 [(unspec_volatile [(const_int 0)] UNSPECV_OSC_BREAK)]
11435 ""
11436 "bcr\t7,%%r0"
11437 [(set_attr "op_type" "RR")])