S/390: Improve support of 128 bit vectors in GPRs
[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_MERGEH
160 UNSPEC_VEC_MERGEL
161 UNSPEC_VEC_PACK
162 UNSPEC_VEC_PACK_SATURATE
163 UNSPEC_VEC_PACK_SATURATE_CC
164 UNSPEC_VEC_PACK_SATURATE_GENCC
165 UNSPEC_VEC_PACK_UNSIGNED_SATURATE
166 UNSPEC_VEC_PACK_UNSIGNED_SATURATE_CC
167 UNSPEC_VEC_PACK_UNSIGNED_SATURATE_GENCC
168 UNSPEC_VEC_PERM
169 UNSPEC_VEC_PERMI
170 UNSPEC_VEC_EXTEND
171 UNSPEC_VEC_STORE_LEN
172 UNSPEC_VEC_UNPACKH
173 UNSPEC_VEC_UNPACKH_L
174 UNSPEC_VEC_UNPACKL
175 UNSPEC_VEC_UNPACKL_L
176 UNSPEC_VEC_ADDC
177 UNSPEC_VEC_ADDE_U128
178 UNSPEC_VEC_ADDEC_U128
179 UNSPEC_VEC_AVG
180 UNSPEC_VEC_AVGU
181 UNSPEC_VEC_CHECKSUM
182 UNSPEC_VEC_GFMSUM
183 UNSPEC_VEC_GFMSUM_128
184 UNSPEC_VEC_GFMSUM_ACCUM
185 UNSPEC_VEC_GFMSUM_ACCUM_128
186 UNSPEC_VEC_SET
187
188 UNSPEC_VEC_VSUMG
189 UNSPEC_VEC_VSUMQ
190 UNSPEC_VEC_VSUM
191 UNSPEC_VEC_RL_MASK
192 UNSPEC_VEC_SLL
193 UNSPEC_VEC_SLB
194 UNSPEC_VEC_SLDB
195 UNSPEC_VEC_SRAL
196 UNSPEC_VEC_SRAB
197 UNSPEC_VEC_SRL
198 UNSPEC_VEC_SRLB
199
200 UNSPEC_VEC_SUBC
201 UNSPEC_VEC_SUBE_U128
202 UNSPEC_VEC_SUBEC_U128
203
204 UNSPEC_VEC_TEST_MASK
205
206 UNSPEC_VEC_VFAE
207 UNSPEC_VEC_VFAECC
208
209 UNSPEC_VEC_VFEE
210 UNSPEC_VEC_VFEECC
211 UNSPEC_VEC_VFENE
212 UNSPEC_VEC_VFENECC
213
214 UNSPEC_VEC_VISTR
215 UNSPEC_VEC_VISTRCC
216
217 UNSPEC_VEC_VSTRC
218 UNSPEC_VEC_VSTRCCC
219
220 UNSPEC_VEC_VCDGB
221 UNSPEC_VEC_VCDLGB
222
223 UNSPEC_VEC_VCGDB
224 UNSPEC_VEC_VCLGDB
225
226 UNSPEC_VEC_VFIDB
227
228 UNSPEC_VEC_VLDEB
229 UNSPEC_VEC_VLEDB
230
231 UNSPEC_VEC_VFTCIDB
232 UNSPEC_VEC_VFTCIDBCC
233 ])
234
235 ;;
236 ;; UNSPEC_VOLATILE usage
237 ;;
238
239 (define_c_enum "unspecv" [
240 ; Blockage
241 UNSPECV_BLOCKAGE
242
243 ; TPF Support
244 UNSPECV_TPF_PROLOGUE
245 UNSPECV_TPF_EPILOGUE
246
247 ; Literal pool
248 UNSPECV_POOL
249 UNSPECV_POOL_SECTION
250 UNSPECV_POOL_ALIGN
251 UNSPECV_POOL_ENTRY
252 UNSPECV_MAIN_POOL
253
254 ; TLS support
255 UNSPECV_SET_TP
256
257 ; Atomic Support
258 UNSPECV_CAS
259 UNSPECV_ATOMIC_OP
260
261 ; Hotpatching (unremovable NOPs)
262 UNSPECV_NOP_2_BYTE
263 UNSPECV_NOP_4_BYTE
264 UNSPECV_NOP_6_BYTE
265
266 ; Transactional Execution support
267 UNSPECV_TBEGIN
268 UNSPECV_TBEGIN_TDB
269 UNSPECV_TBEGINC
270 UNSPECV_TEND
271 UNSPECV_TABORT
272 UNSPECV_ETND
273 UNSPECV_NTSTG
274 UNSPECV_PPA
275
276 ; Set and get floating point control register
277 UNSPECV_SFPC
278 UNSPECV_EFPC
279
280 ; Split stack support
281 UNSPECV_SPLIT_STACK_CALL
282 UNSPECV_SPLIT_STACK_DATA
283
284 UNSPECV_OSC_BREAK
285 ])
286
287 ;;
288 ;; Registers
289 ;;
290
291 ; Registers with special meaning
292
293 (define_constants
294 [
295 ; Sibling call register.
296 (SIBCALL_REGNUM 1)
297 ; Literal pool base register.
298 (BASE_REGNUM 13)
299 ; Return address register.
300 (RETURN_REGNUM 14)
301 ; Stack pointer register.
302 (STACK_REGNUM 15)
303 ; Condition code register.
304 (CC_REGNUM 33)
305 ; Thread local storage pointer register.
306 (TP_REGNUM 36)
307 ])
308
309 ; Hardware register names
310
311 (define_constants
312 [
313 ; General purpose registers
314 (GPR0_REGNUM 0)
315 (GPR1_REGNUM 1)
316 (GPR2_REGNUM 2)
317 (GPR6_REGNUM 6)
318 ; Floating point registers.
319 (FPR0_REGNUM 16)
320 (FPR1_REGNUM 20)
321 (FPR2_REGNUM 17)
322 (FPR3_REGNUM 21)
323 (FPR4_REGNUM 18)
324 (FPR5_REGNUM 22)
325 (FPR6_REGNUM 19)
326 (FPR7_REGNUM 23)
327 (FPR8_REGNUM 24)
328 (FPR9_REGNUM 28)
329 (FPR10_REGNUM 25)
330 (FPR11_REGNUM 29)
331 (FPR12_REGNUM 26)
332 (FPR13_REGNUM 30)
333 (FPR14_REGNUM 27)
334 (FPR15_REGNUM 31)
335 (VR0_REGNUM 16)
336 (VR16_REGNUM 38)
337 (VR23_REGNUM 45)
338 (VR24_REGNUM 46)
339 (VR31_REGNUM 53)
340 ])
341
342 ; Rounding modes for binary floating point numbers
343 (define_constants
344 [(BFP_RND_CURRENT 0)
345 (BFP_RND_NEAREST_TIE_AWAY_FROM_0 1)
346 (BFP_RND_PREP_FOR_SHORT_PREC 3)
347 (BFP_RND_NEAREST_TIE_TO_EVEN 4)
348 (BFP_RND_TOWARD_0 5)
349 (BFP_RND_TOWARD_INF 6)
350 (BFP_RND_TOWARD_MINF 7)])
351
352 ; Rounding modes for decimal floating point numbers
353 ; 1-7 were introduced with the floating point extension facility
354 ; available with z196
355 ; With these rounding modes (1-7) a quantum exception might occur
356 ; which is suppressed for the other modes.
357 (define_constants
358 [(DFP_RND_CURRENT 0)
359 (DFP_RND_NEAREST_TIE_AWAY_FROM_0_QUANTEXC 1)
360 (DFP_RND_CURRENT_QUANTEXC 2)
361 (DFP_RND_PREP_FOR_SHORT_PREC_QUANTEXC 3)
362 (DFP_RND_NEAREST_TIE_TO_EVEN_QUANTEXC 4)
363 (DFP_RND_TOWARD_0_QUANTEXC 5)
364 (DFP_RND_TOWARD_INF_QUANTEXC 6)
365 (DFP_RND_TOWARD_MINF_QUANTEXC 7)
366 (DFP_RND_NEAREST_TIE_TO_EVEN 8)
367 (DFP_RND_TOWARD_0 9)
368 (DFP_RND_TOWARD_INF 10)
369 (DFP_RND_TOWARD_MINF 11)
370 (DFP_RND_NEAREST_TIE_AWAY_FROM_0 12)
371 (DFP_RND_NEAREST_TIE_TO_0 13)
372 (DFP_RND_AWAY_FROM_0 14)
373 (DFP_RND_PREP_FOR_SHORT_PREC 15)])
374
375 ;;
376 ;; PFPO GPR0 argument format
377 ;;
378
379 (define_constants
380 [
381 ; PFPO operation type
382 (PFPO_CONVERT 0x1000000)
383 ; PFPO operand types
384 (PFPO_OP_TYPE_SF 0x5)
385 (PFPO_OP_TYPE_DF 0x6)
386 (PFPO_OP_TYPE_TF 0x7)
387 (PFPO_OP_TYPE_SD 0x8)
388 (PFPO_OP_TYPE_DD 0x9)
389 (PFPO_OP_TYPE_TD 0xa)
390 ; Bitposition of operand types
391 (PFPO_OP0_TYPE_SHIFT 16)
392 (PFPO_OP1_TYPE_SHIFT 8)
393 ])
394
395 ; Immediate operands for tbegin and tbeginc
396 (define_constants [(TBEGIN_MASK 65292)]) ; 0xff0c
397 (define_constants [(TBEGINC_MASK 65288)]) ; 0xff08
398
399 ;; Instruction operand type as used in the Principles of Operation.
400 ;; Used to determine defaults for length and other attribute values.
401
402 (define_attr "op_type"
403 "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"
404 (const_string "NN"))
405
406 ;; Instruction type attribute used for scheduling.
407
408 (define_attr "type" "none,integer,load,lr,la,larl,lm,stm,
409 cs,vs,store,sem,idiv,
410 imulhi,imulsi,imuldi,
411 branch,jsr,fsimptf,fsimpdf,fsimpsf,fhex,
412 floadtf,floaddf,floadsf,fstoredf,fstoresf,
413 fmultf,fmuldf,fmulsf,fdivtf,fdivdf,fdivsf,
414 ftoi,fsqrttf,fsqrtdf,fsqrtsf,
415 fmadddf,fmaddsf,
416 ftrunctf,ftruncdf, ftruncsd, ftruncdd,
417 itoftf, itofdf, itofsf, itofdd, itoftd,
418 fdivdd, fdivtd, floaddd, floadsd, fmuldd, fmultd,
419 fsimpdd, fsimpsd, fsimptd, fstoredd, fstoresd,
420 ftoidfp, other"
421 (cond [(eq_attr "op_type" "NN") (const_string "other")
422 (eq_attr "op_type" "SS") (const_string "cs")]
423 (const_string "integer")))
424
425 ;; Another attribute used for scheduling purposes:
426 ;; agen: Instruction uses the address generation unit
427 ;; reg: Instruction does not use the agen unit
428
429 (define_attr "atype" "agen,reg"
430 (if_then_else (eq_attr "op_type" "E,RR,RI,RRE,RSI,RIL,RIE,RRF")
431 (const_string "reg")
432 (const_string "agen")))
433
434 ;; Properties concerning Z10 execution grouping and value forwarding.
435 ;; z10_super: instruction is superscalar.
436 ;; z10_super_c: instruction is superscalar and meets the condition of z10_c.
437 ;; z10_fwd: The instruction reads the value of an operand and stores it into a
438 ;; target register. It can forward this value to a second instruction that reads
439 ;; the same register if that second instruction is issued in the same group.
440 ;; z10_rec: The instruction is in the T pipeline and reads a register. If the
441 ;; instruction in the S pipe writes to the register, then the T instruction
442 ;; can immediately read the new value.
443 ;; z10_fr: union of Z10_fwd and z10_rec.
444 ;; z10_c: second operand of instruction is a register and read with complemented bits.
445 ;;
446 ;; An additional suffix A1, A3, or E1 indicates the respective AGI bypass.
447
448
449 (define_attr "z10prop" "none,
450 z10_super, z10_super_E1, z10_super_A1, z10_super_c, z10_super_c_E1,
451 z10_fwd, z10_fwd_A1, z10_fwd_A3, z10_fwd_E1,
452 z10_rec,
453 z10_fr, z10_fr_A3, z10_fr_E1,
454 z10_c"
455 (const_string "none"))
456
457 ;; Properties concerning Z196 decoding
458 ;; z196_alone: must group alone
459 ;; z196_end: ends a group
460 ;; z196_cracked: instruction is cracked or expanded
461 (define_attr "z196prop" "none,
462 z196_alone, z196_ends,
463 z196_cracked"
464 (const_string "none"))
465
466 (define_attr "mnemonic" "bcr_flush,unknown" (const_string "unknown"))
467
468 ;; Length in bytes.
469
470 (define_attr "length" ""
471 (cond [(eq_attr "op_type" "E,RR") (const_int 2)
472 (eq_attr "op_type" "RX,RI,RRE,RS,RSI,S,SI,RRF") (const_int 4)]
473 (const_int 6)))
474
475
476 ;; Processor type. This attribute must exactly match the processor_type
477 ;; enumeration in s390.h. The current machine description does not
478 ;; distinguish between g5 and g6, but there are differences between the two
479 ;; CPUs could in theory be modeled.
480
481 (define_attr "cpu" "g5,g6,z900,z990,z9_109,z9_ec,z10,z196,zEC12,z13"
482 (const (symbol_ref "s390_tune_attr")))
483
484 (define_attr "cpu_facility"
485 "standard,ieee,zarch,cpu_zarch,longdisp,extimm,dfp,z10,z196,zEC12,vx,z13"
486 (const_string "standard"))
487
488 (define_attr "enabled" ""
489 (cond [(eq_attr "cpu_facility" "standard")
490 (const_int 1)
491
492 (and (eq_attr "cpu_facility" "ieee")
493 (match_test "TARGET_CPU_IEEE_FLOAT"))
494 (const_int 1)
495
496 (and (eq_attr "cpu_facility" "zarch")
497 (match_test "TARGET_ZARCH"))
498 (const_int 1)
499
500 (and (eq_attr "cpu_facility" "longdisp")
501 (match_test "TARGET_LONG_DISPLACEMENT"))
502 (const_int 1)
503
504 (and (eq_attr "cpu_facility" "extimm")
505 (match_test "TARGET_EXTIMM"))
506 (const_int 1)
507
508 (and (eq_attr "cpu_facility" "dfp")
509 (match_test "TARGET_DFP"))
510 (const_int 1)
511
512 (and (eq_attr "cpu_facility" "cpu_zarch")
513 (match_test "TARGET_CPU_ZARCH"))
514 (const_int 1)
515
516 (and (eq_attr "cpu_facility" "z10")
517 (match_test "TARGET_Z10"))
518 (const_int 1)
519
520 (and (eq_attr "cpu_facility" "z196")
521 (match_test "TARGET_Z196"))
522 (const_int 1)
523
524 (and (eq_attr "cpu_facility" "zEC12")
525 (match_test "TARGET_ZEC12"))
526 (const_int 1)
527
528 (and (eq_attr "cpu_facility" "vx")
529 (match_test "TARGET_VX"))
530 (const_int 1)
531
532 (and (eq_attr "cpu_facility" "z13")
533 (match_test "TARGET_Z13"))
534 (const_int 1)
535 ]
536 (const_int 0)))
537
538 ;; Pipeline description for z900. For lack of anything better,
539 ;; this description is also used for the g5 and g6.
540 (include "2064.md")
541
542 ;; Pipeline description for z990, z9-109 and z9-ec.
543 (include "2084.md")
544
545 ;; Pipeline description for z10
546 (include "2097.md")
547
548 ;; Pipeline description for z196
549 (include "2817.md")
550
551 ;; Pipeline description for zEC12
552 (include "2827.md")
553
554 ;; Pipeline description for z13
555 (include "2964.md")
556
557 ;; Predicates
558 (include "predicates.md")
559
560 ;; Constraint definitions
561 (include "constraints.md")
562
563 ;; Other includes
564 (include "tpf.md")
565
566 ;; Iterators
567
568 (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])
569
570 ;; These mode iterators allow floating point patterns to be generated from the
571 ;; same template.
572 (define_mode_iterator FP_ALL [TF DF SF (TD "TARGET_HARD_DFP") (DD "TARGET_HARD_DFP")
573 (SD "TARGET_HARD_DFP")])
574 (define_mode_iterator FP [TF DF SF (TD "TARGET_HARD_DFP") (DD "TARGET_HARD_DFP")])
575 (define_mode_iterator BFP [TF DF SF])
576 (define_mode_iterator DFP [TD DD])
577 (define_mode_iterator DFP_ALL [TD DD SD])
578 (define_mode_iterator DSF [DF SF])
579 (define_mode_iterator SD_SF [SF SD])
580 (define_mode_iterator DD_DF [DF DD])
581 (define_mode_iterator TD_TF [TF TD])
582
583 ;; These mode iterators allow 31-bit and 64-bit GPR patterns to be generated
584 ;; from the same template.
585 (define_mode_iterator GPR [(DI "TARGET_ZARCH") SI])
586 (define_mode_iterator DGPR [(TI "TARGET_ZARCH") DI SI])
587 (define_mode_iterator DSI [DI SI])
588 (define_mode_iterator TDI [TI DI])
589
590 ;; These mode iterators allow :P to be used for patterns that operate on
591 ;; pointer-sized quantities. Exactly one of the two alternatives will match.
592 (define_mode_iterator P [(DI "TARGET_64BIT") (SI "!TARGET_64BIT")])
593
594 ;; These macros refer to the actual word_mode of the configuration.
595 ;; This is equal to Pmode except on 31-bit machines in zarch mode.
596 (define_mode_iterator DW [(TI "TARGET_ZARCH") (DI "!TARGET_ZARCH")])
597 (define_mode_iterator W [(DI "TARGET_ZARCH") (SI "!TARGET_ZARCH")])
598
599 ;; Used by the umul pattern to express modes having half the size.
600 (define_mode_attr DWH [(TI "DI") (DI "SI")])
601 (define_mode_attr dwh [(TI "di") (DI "si")])
602
603 ;; This mode iterator allows the QI and HI patterns to be defined from
604 ;; the same template.
605 (define_mode_iterator HQI [HI QI])
606
607 ;; This mode iterator allows the integer patterns to be defined from the
608 ;; same template.
609 (define_mode_iterator INT [(DI "TARGET_ZARCH") SI HI QI])
610 (define_mode_iterator DINT [(TI "TARGET_ZARCH") DI SI HI QI])
611 (define_mode_iterator SINT [SI HI QI])
612
613 ;; This iterator allows some 'ashift' and 'lshiftrt' pattern to be defined from
614 ;; the same template.
615 (define_code_iterator SHIFT [ashift lshiftrt])
616
617 ;; This iterator allows r[ox]sbg to be defined with the same template
618 (define_code_iterator IXOR [ior xor])
619
620 ;; This iterator is used to expand the patterns for the nearest
621 ;; integer functions.
622 (define_int_iterator FPINT [UNSPEC_FPINT_FLOOR UNSPEC_FPINT_BTRUNC
623 UNSPEC_FPINT_ROUND UNSPEC_FPINT_CEIL
624 UNSPEC_FPINT_NEARBYINT])
625 (define_int_attr fpint_name [(UNSPEC_FPINT_FLOOR "floor")
626 (UNSPEC_FPINT_BTRUNC "btrunc")
627 (UNSPEC_FPINT_ROUND "round")
628 (UNSPEC_FPINT_CEIL "ceil")
629 (UNSPEC_FPINT_NEARBYINT "nearbyint")])
630 (define_int_attr fpint_roundingmode [(UNSPEC_FPINT_FLOOR "7")
631 (UNSPEC_FPINT_BTRUNC "5")
632 (UNSPEC_FPINT_ROUND "1")
633 (UNSPEC_FPINT_CEIL "6")
634 (UNSPEC_FPINT_NEARBYINT "0")])
635
636 ;; This iterator and attribute allow to combine most atomic operations.
637 (define_code_iterator ATOMIC [and ior xor plus minus mult])
638 (define_code_iterator ATOMIC_Z196 [and ior xor plus])
639 (define_code_attr atomic [(and "and") (ior "or") (xor "xor")
640 (plus "add") (minus "sub") (mult "nand")])
641 (define_code_attr noxa [(and "n") (ior "o") (xor "x") (plus "a")])
642
643 ;; In FP templates, a string like "lt<de>br" will expand to "ltxbr" in
644 ;; TF/TDmode, "ltdbr" in DF/DDmode, and "ltebr" in SF/SDmode.
645 (define_mode_attr xde [(TF "x") (DF "d") (SF "e") (TD "x") (DD "d") (SD "e")])
646
647 ;; In FP templates, a <dee> in "m<dee><bt>r" will expand to "mx<bt>r" in
648 ;; TF/TDmode, "md<bt>r" in DF/DDmode, "mee<bt>r" in SFmode and "me<bt>r in
649 ;; SDmode.
650 (define_mode_attr xdee [(TF "x") (DF "d") (SF "ee") (TD "x") (DD "d") (SD "e")])
651
652 ;; In FP templates, "<RRe>" will expand to "RRE" in TFmode and "RR" otherwise.
653 ;; Likewise for "<RXe>".
654 (define_mode_attr RRe [(TF "RRE") (DF "RR") (SF "RR")])
655 (define_mode_attr RXe [(TF "RXE") (DF "RX") (SF "RX")])
656
657 ;; The decimal floating point variants of add, sub, div and mul support 3
658 ;; fp register operands. The following attributes allow to merge the bfp and
659 ;; dfp variants in a single insn definition.
660
661 ;; These mode attributes are supposed to be used in the `enabled' insn
662 ;; attribute to disable certain alternatives for certain modes.
663 (define_mode_attr nBFP [(TF "0") (DF "0") (SF "0") (TD "*") (DD "*") (DD "*")])
664 (define_mode_attr nDFP [(TF "*") (DF "*") (SF "*") (TD "0") (DD "0") (DD "0")])
665 (define_mode_attr DSF [(TF "0") (DF "*") (SF "*") (TD "0") (DD "0") (SD "0")])
666 (define_mode_attr DFDI [(TF "0") (DF "*") (SF "0")
667 (TD "0") (DD "0") (DD "0")
668 (TI "0") (DI "*") (SI "0")])
669
670 ;; This attribute is used in the operand constraint list
671 ;; for instructions dealing with the sign bit of 32 or 64bit fp values.
672 ;; TFmode values are represented by a fp register pair. Since the
673 ;; sign bit instructions only handle single source and target fp registers
674 ;; these instructions can only be used for TFmode values if the source and
675 ;; target operand uses the same fp register.
676 (define_mode_attr fT0 [(TF "0") (DF "f") (SF "f")])
677
678 ;; This attribute adds b for bfp instructions and t for dfp instructions and is used
679 ;; within instruction mnemonics.
680 (define_mode_attr bt [(TF "b") (DF "b") (SF "b") (TD "t") (DD "t") (SD "t")])
681
682 ;; This attribute is used within instruction mnemonics. It evaluates to d for dfp
683 ;; modes and to an empty string for bfp modes.
684 (define_mode_attr _d [(TF "") (DF "") (SF "") (TD "d") (DD "d") (SD "d")])
685
686 ;; In GPR and P templates, a constraint like "<d0>" will expand to "d" in DImode
687 ;; and "0" in SImode. This allows to combine instructions of which the 31bit
688 ;; version only operates on one register.
689 (define_mode_attr d0 [(DI "d") (SI "0")])
690
691 ;; In combination with d0 this allows to combine instructions of which the 31bit
692 ;; version only operates on one register. The DImode version needs an additional
693 ;; register for the assembler output.
694 (define_mode_attr 1 [(DI "%1,") (SI "")])
695
696 ;; In SHIFT templates, a string like "s<lr>dl" will expand to "sldl" in
697 ;; 'ashift' and "srdl" in 'lshiftrt'.
698 (define_code_attr lr [(ashift "l") (lshiftrt "r")])
699
700 ;; In SHIFT templates, this attribute holds the correct standard name for the
701 ;; pattern itself and the corresponding function calls.
702 (define_code_attr shift [(ashift "ashl") (lshiftrt "lshr")])
703
704 ;; This attribute handles differences in the instruction 'type' and will result
705 ;; in "RRE" for DImode and "RR" for SImode.
706 (define_mode_attr E [(DI "E") (SI "")])
707
708 ;; This attribute handles differences in the instruction 'type' and makes RX<Y>
709 ;; to result in "RXY" for DImode and "RX" for SImode.
710 (define_mode_attr Y [(DI "Y") (SI "")])
711
712 ;; This attribute handles differences in the instruction 'type' and will result
713 ;; in "RSE" for TImode and "RS" for DImode.
714 (define_mode_attr TE [(TI "E") (DI "")])
715
716 ;; In GPR templates, a string like "lc<g>r" will expand to "lcgr" in DImode
717 ;; and "lcr" in SImode.
718 (define_mode_attr g [(DI "g") (SI "")])
719
720 ;; In GPR templates, a string like "sl<y>" will expand to "slg" in DImode
721 ;; and "sly" in SImode. This is useful because on 64bit the ..g instructions
722 ;; were enhanced with long displacements whereas 31bit instructions got a ..y
723 ;; variant for long displacements.
724 (define_mode_attr y [(DI "g") (SI "y")])
725
726 ;; In DW templates, a string like "cds<g>" will expand to "cdsg" in TImode
727 ;; and "cds" in DImode.
728 (define_mode_attr tg [(TI "g") (DI "")])
729
730 ;; In TDI templates, a string like "c<d>sg".
731 (define_mode_attr td [(TI "d") (DI "")])
732
733 ;; In GPR templates, a string like "c<gf>dbr" will expand to "cgdbr" in DImode
734 ;; and "cfdbr" in SImode.
735 (define_mode_attr gf [(DI "g") (SI "f")])
736
737 ;; In GPR templates, a string like sll<gk> will expand to sllg for DI
738 ;; and sllk for SI. This way it is possible to merge the new z196 SI
739 ;; 3 operands shift instructions into the existing patterns.
740 (define_mode_attr gk [(DI "g") (SI "k")])
741
742 ;; ICM mask required to load MODE value into the lowest subreg
743 ;; of a SImode register.
744 (define_mode_attr icm_lo [(HI "3") (QI "1")])
745
746 ;; In HQI templates, a string like "llg<hc>" will expand to "llgh" in
747 ;; HImode and "llgc" in QImode.
748 (define_mode_attr hc [(HI "h") (QI "c")])
749
750 ;; In P templates, the mode <DBL> will expand to "TI" in DImode and "DI"
751 ;; in SImode.
752 (define_mode_attr DBL [(DI "TI") (SI "DI")])
753
754 ;; This attribute expands to DF for TFmode and to DD for TDmode . It is
755 ;; used for Txmode splitters splitting a Txmode copy into 2 Dxmode copies.
756 (define_mode_attr HALF_TMODE [(TF "DF") (TD "DD")])
757
758 ;; Maximum unsigned integer that fits in MODE.
759 (define_mode_attr max_uint [(HI "65535") (QI "255")])
760
761 ;; Start and end field computations for RISBG et al.
762 (define_mode_attr bfstart [(DI "s") (SI "t")])
763 (define_mode_attr bfend [(DI "e") (SI "f")])
764
765 ;; In place of GET_MODE_BITSIZE (<MODE>mode)
766 (define_mode_attr bitsize [(DI "64") (SI "32") (HI "16") (QI "8")])
767 ;; 64 - bitsize
768 (define_mode_attr bitoff [(DI "0") (SI "32") (HI "48") (QI "56")])
769 (define_mode_attr bitoff_plus [(DI "") (SI "32+") (HI "48+") (QI "56+")])
770
771 ;; In place of GET_MODE_SIZE (<MODE>mode)
772 (define_mode_attr modesize [(DI "8") (SI "4")])
773
774 ;; Allow return and simple_return to be defined from a single template.
775 (define_code_iterator ANY_RETURN [return simple_return])
776
777
778
779 ; Condition code modes generated by vector fp comparisons. These will
780 ; be used also in single element mode.
781 (define_mode_iterator VFCMP [CCVEQ CCVFH CCVFHE])
782 ; Used with VFCMP to expand part of the mnemonic
783 ; For fp we have a mismatch: eq in the insn name - e in asm
784 (define_mode_attr asm_fcmp [(CCVEQ "e") (CCVFH "h") (CCVFHE "he")])
785 (define_mode_attr insn_cmp [(CCVEQ "eq") (CCVIH "h") (CCVIHU "hl") (CCVFH "h") (CCVFHE "he")])
786
787 ;; Subst pattern definitions
788 (include "subst.md")
789
790 (include "vector.md")
791
792 ;;
793 ;;- Compare instructions.
794 ;;
795
796 ; Test-under-Mask instructions
797
798 (define_insn "*tmqi_mem"
799 [(set (reg CC_REGNUM)
800 (compare (and:QI (match_operand:QI 0 "memory_operand" "Q,S")
801 (match_operand:QI 1 "immediate_operand" "n,n"))
802 (match_operand:QI 2 "immediate_operand" "n,n")))]
803 "s390_match_ccmode (insn, s390_tm_ccmode (operands[1], operands[2], false))"
804 "@
805 tm\t%S0,%b1
806 tmy\t%S0,%b1"
807 [(set_attr "op_type" "SI,SIY")
808 (set_attr "cpu_facility" "*,longdisp")
809 (set_attr "z10prop" "z10_super,z10_super")])
810
811 (define_insn "*tmdi_reg"
812 [(set (reg CC_REGNUM)
813 (compare (and:DI (match_operand:DI 0 "nonimmediate_operand" "d,d,d,d")
814 (match_operand:DI 1 "immediate_operand"
815 "N0HD0,N1HD0,N2HD0,N3HD0"))
816 (match_operand:DI 2 "immediate_operand" "n,n,n,n")))]
817 "TARGET_ZARCH
818 && s390_match_ccmode (insn, s390_tm_ccmode (operands[1], operands[2], true))
819 && s390_single_part (operands[1], DImode, HImode, 0) >= 0"
820 "@
821 tmhh\t%0,%i1
822 tmhl\t%0,%i1
823 tmlh\t%0,%i1
824 tmll\t%0,%i1"
825 [(set_attr "op_type" "RI")
826 (set_attr "z10prop" "z10_super,z10_super,z10_super,z10_super")])
827
828 (define_insn "*tmsi_reg"
829 [(set (reg CC_REGNUM)
830 (compare (and:SI (match_operand:SI 0 "nonimmediate_operand" "d,d")
831 (match_operand:SI 1 "immediate_operand" "N0HS0,N1HS0"))
832 (match_operand:SI 2 "immediate_operand" "n,n")))]
833 "s390_match_ccmode (insn, s390_tm_ccmode (operands[1], operands[2], true))
834 && s390_single_part (operands[1], SImode, HImode, 0) >= 0"
835 "@
836 tmh\t%0,%i1
837 tml\t%0,%i1"
838 [(set_attr "op_type" "RI")
839 (set_attr "z10prop" "z10_super,z10_super")])
840
841 (define_insn "*tm<mode>_full"
842 [(set (reg CC_REGNUM)
843 (compare (match_operand:HQI 0 "register_operand" "d")
844 (match_operand:HQI 1 "immediate_operand" "n")))]
845 "s390_match_ccmode (insn, s390_tm_ccmode (constm1_rtx, operands[1], true))"
846 "tml\t%0,<max_uint>"
847 [(set_attr "op_type" "RI")
848 (set_attr "z10prop" "z10_super")])
849
850
851 ;
852 ; Load-and-Test instructions
853 ;
854
855 ; tst(di|si) instruction pattern(s).
856
857 (define_insn "*tstdi_sign"
858 [(set (reg CC_REGNUM)
859 (compare
860 (ashiftrt:DI
861 (ashift:DI
862 (subreg:DI (match_operand:SI 0 "nonimmediate_operand" "d,T") 0)
863 (const_int 32)) (const_int 32))
864 (match_operand:DI 1 "const0_operand" "")))
865 (set (match_operand:DI 2 "register_operand" "=d,d")
866 (sign_extend:DI (match_dup 0)))]
867 "s390_match_ccmode(insn, CCSmode) && TARGET_ZARCH"
868 "ltgfr\t%2,%0
869 ltgf\t%2,%0"
870 [(set_attr "op_type" "RRE,RXY")
871 (set_attr "cpu_facility" "*,z10")
872 (set_attr "z10prop" "z10_super_E1,z10_super_E1") ])
873
874 ; ltr, lt, ltgr, ltg
875 (define_insn "*tst<mode>_extimm"
876 [(set (reg CC_REGNUM)
877 (compare (match_operand:GPR 0 "nonimmediate_operand" "d,T")
878 (match_operand:GPR 1 "const0_operand" "")))
879 (set (match_operand:GPR 2 "register_operand" "=d,d")
880 (match_dup 0))]
881 "s390_match_ccmode(insn, CCSmode) && TARGET_EXTIMM"
882 "@
883 lt<g>r\t%2,%0
884 lt<g>\t%2,%0"
885 [(set_attr "op_type" "RR<E>,RXY")
886 (set_attr "z10prop" "z10_fr_E1,z10_fwd_A3") ])
887
888 ; ltr, lt, ltgr, ltg
889 (define_insn "*tst<mode>_cconly_extimm"
890 [(set (reg CC_REGNUM)
891 (compare (match_operand:GPR 0 "nonimmediate_operand" "d,T")
892 (match_operand:GPR 1 "const0_operand" "")))
893 (clobber (match_scratch:GPR 2 "=X,d"))]
894 "s390_match_ccmode(insn, CCSmode) && TARGET_EXTIMM"
895 "@
896 lt<g>r\t%0,%0
897 lt<g>\t%2,%0"
898 [(set_attr "op_type" "RR<E>,RXY")
899 (set_attr "z10prop" "z10_fr_E1,z10_fwd_A3")])
900
901 (define_insn "*tstdi"
902 [(set (reg CC_REGNUM)
903 (compare (match_operand:DI 0 "register_operand" "d")
904 (match_operand:DI 1 "const0_operand" "")))
905 (set (match_operand:DI 2 "register_operand" "=d")
906 (match_dup 0))]
907 "s390_match_ccmode(insn, CCSmode) && TARGET_ZARCH && !TARGET_EXTIMM"
908 "ltgr\t%2,%0"
909 [(set_attr "op_type" "RRE")
910 (set_attr "z10prop" "z10_fr_E1")])
911
912 (define_insn "*tstsi"
913 [(set (reg CC_REGNUM)
914 (compare (match_operand:SI 0 "nonimmediate_operand" "d,Q,S")
915 (match_operand:SI 1 "const0_operand" "")))
916 (set (match_operand:SI 2 "register_operand" "=d,d,d")
917 (match_dup 0))]
918 "s390_match_ccmode(insn, CCSmode) && !TARGET_EXTIMM"
919 "@
920 ltr\t%2,%0
921 icm\t%2,15,%S0
922 icmy\t%2,15,%S0"
923 [(set_attr "op_type" "RR,RS,RSY")
924 (set_attr "cpu_facility" "*,*,longdisp")
925 (set_attr "z10prop" "z10_fr_E1,z10_super_E1,z10_super_E1")])
926
927 (define_insn "*tstsi_cconly"
928 [(set (reg CC_REGNUM)
929 (compare (match_operand:SI 0 "nonimmediate_operand" "d,Q,S")
930 (match_operand:SI 1 "const0_operand" "")))
931 (clobber (match_scratch:SI 2 "=X,d,d"))]
932 "s390_match_ccmode(insn, CCSmode)"
933 "@
934 ltr\t%0,%0
935 icm\t%2,15,%S0
936 icmy\t%2,15,%S0"
937 [(set_attr "op_type" "RR,RS,RSY")
938 (set_attr "cpu_facility" "*,*,longdisp")
939 (set_attr "z10prop" "z10_fr_E1,z10_super_E1,z10_super_E1")])
940
941 (define_insn "*tstdi_cconly_31"
942 [(set (reg CC_REGNUM)
943 (compare (match_operand:DI 0 "register_operand" "d")
944 (match_operand:DI 1 "const0_operand" "")))]
945 "s390_match_ccmode(insn, CCSmode) && !TARGET_ZARCH"
946 "srda\t%0,0"
947 [(set_attr "op_type" "RS")
948 (set_attr "atype" "reg")])
949
950 ; ltr, ltgr
951 (define_insn "*tst<mode>_cconly2"
952 [(set (reg CC_REGNUM)
953 (compare (match_operand:GPR 0 "register_operand" "d")
954 (match_operand:GPR 1 "const0_operand" "")))]
955 "s390_match_ccmode(insn, CCSmode)"
956 "lt<g>r\t%0,%0"
957 [(set_attr "op_type" "RR<E>")
958 (set_attr "z10prop" "z10_fr_E1")])
959
960 ; tst(hi|qi) instruction pattern(s).
961
962 (define_insn "*tst<mode>CCT"
963 [(set (reg CC_REGNUM)
964 (compare (match_operand:HQI 0 "nonimmediate_operand" "?Q,?S,d")
965 (match_operand:HQI 1 "const0_operand" "")))
966 (set (match_operand:HQI 2 "register_operand" "=d,d,0")
967 (match_dup 0))]
968 "s390_match_ccmode(insn, CCTmode)"
969 "@
970 icm\t%2,<icm_lo>,%S0
971 icmy\t%2,<icm_lo>,%S0
972 tml\t%0,<max_uint>"
973 [(set_attr "op_type" "RS,RSY,RI")
974 (set_attr "cpu_facility" "*,longdisp,*")
975 (set_attr "z10prop" "z10_super_E1,z10_super_E1,z10_super")])
976
977 (define_insn "*tsthiCCT_cconly"
978 [(set (reg CC_REGNUM)
979 (compare (match_operand:HI 0 "nonimmediate_operand" "Q,S,d")
980 (match_operand:HI 1 "const0_operand" "")))
981 (clobber (match_scratch:HI 2 "=d,d,X"))]
982 "s390_match_ccmode(insn, CCTmode)"
983 "@
984 icm\t%2,3,%S0
985 icmy\t%2,3,%S0
986 tml\t%0,65535"
987 [(set_attr "op_type" "RS,RSY,RI")
988 (set_attr "cpu_facility" "*,longdisp,*")
989 (set_attr "z10prop" "z10_super_E1,z10_super_E1,z10_super")])
990
991 (define_insn "*tstqiCCT_cconly"
992 [(set (reg CC_REGNUM)
993 (compare (match_operand:QI 0 "nonimmediate_operand" "?Q,?S,d")
994 (match_operand:QI 1 "const0_operand" "")))]
995 "s390_match_ccmode(insn, CCTmode)"
996 "@
997 cli\t%S0,0
998 cliy\t%S0,0
999 tml\t%0,255"
1000 [(set_attr "op_type" "SI,SIY,RI")
1001 (set_attr "cpu_facility" "*,longdisp,*")
1002 (set_attr "z10prop" "z10_super,z10_super,z10_super")])
1003
1004 (define_insn "*tst<mode>"
1005 [(set (reg CC_REGNUM)
1006 (compare (match_operand:HQI 0 "s_operand" "Q,S")
1007 (match_operand:HQI 1 "const0_operand" "")))
1008 (set (match_operand:HQI 2 "register_operand" "=d,d")
1009 (match_dup 0))]
1010 "s390_match_ccmode(insn, CCSmode)"
1011 "@
1012 icm\t%2,<icm_lo>,%S0
1013 icmy\t%2,<icm_lo>,%S0"
1014 [(set_attr "op_type" "RS,RSY")
1015 (set_attr "cpu_facility" "*,longdisp")
1016 (set_attr "z10prop" "z10_super_E1,z10_super_E1")])
1017
1018 (define_insn "*tst<mode>_cconly"
1019 [(set (reg CC_REGNUM)
1020 (compare (match_operand:HQI 0 "s_operand" "Q,S")
1021 (match_operand:HQI 1 "const0_operand" "")))
1022 (clobber (match_scratch:HQI 2 "=d,d"))]
1023 "s390_match_ccmode(insn, CCSmode)"
1024 "@
1025 icm\t%2,<icm_lo>,%S0
1026 icmy\t%2,<icm_lo>,%S0"
1027 [(set_attr "op_type" "RS,RSY")
1028 (set_attr "cpu_facility" "*,longdisp")
1029 (set_attr "z10prop" "z10_super_E1,z10_super_E1")])
1030
1031
1032 ; Compare (equality) instructions
1033
1034 (define_insn "*cmpdi_cct"
1035 [(set (reg CC_REGNUM)
1036 (compare (match_operand:DI 0 "nonimmediate_operand" "%d,d,d,d,Q")
1037 (match_operand:DI 1 "general_operand" "d,K,Os,T,BQ")))]
1038 "s390_match_ccmode (insn, CCTmode) && TARGET_ZARCH"
1039 "@
1040 cgr\t%0,%1
1041 cghi\t%0,%h1
1042 cgfi\t%0,%1
1043 cg\t%0,%1
1044 #"
1045 [(set_attr "op_type" "RRE,RI,RIL,RXY,SS")
1046 (set_attr "z10prop" "z10_super_c,z10_super,z10_super,z10_super,*")])
1047
1048 (define_insn "*cmpsi_cct"
1049 [(set (reg CC_REGNUM)
1050 (compare (match_operand:SI 0 "nonimmediate_operand" "%d,d,d,d,d,Q")
1051 (match_operand:SI 1 "general_operand" "d,K,Os,R,T,BQ")))]
1052 "s390_match_ccmode (insn, CCTmode)"
1053 "@
1054 cr\t%0,%1
1055 chi\t%0,%h1
1056 cfi\t%0,%1
1057 c\t%0,%1
1058 cy\t%0,%1
1059 #"
1060 [(set_attr "op_type" "RR,RI,RIL,RX,RXY,SS")
1061 (set_attr "cpu_facility" "*,*,*,*,longdisp,*")
1062 (set_attr "z10prop" "z10_super_c,z10_super,z10_super,z10_super,z10_super,*")])
1063
1064 ; Compare (signed) instructions
1065
1066 (define_insn "*cmpdi_ccs_sign"
1067 [(set (reg CC_REGNUM)
1068 (compare (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand"
1069 "d,T,b"))
1070 (match_operand:DI 0 "register_operand" "d, d,d")))]
1071 "s390_match_ccmode(insn, CCSRmode) && TARGET_ZARCH"
1072 "@
1073 cgfr\t%0,%1
1074 cgf\t%0,%1
1075 cgfrl\t%0,%1"
1076 [(set_attr "op_type" "RRE,RXY,RIL")
1077 (set_attr "z10prop" "z10_c,*,*")
1078 (set_attr "type" "*,*,larl")])
1079
1080
1081
1082 (define_insn "*cmpsi_ccs_sign"
1083 [(set (reg CC_REGNUM)
1084 (compare (sign_extend:SI (match_operand:HI 1 "memory_operand" "R,T,b"))
1085 (match_operand:SI 0 "register_operand" "d,d,d")))]
1086 "s390_match_ccmode(insn, CCSRmode)"
1087 "@
1088 ch\t%0,%1
1089 chy\t%0,%1
1090 chrl\t%0,%1"
1091 [(set_attr "op_type" "RX,RXY,RIL")
1092 (set_attr "cpu_facility" "*,longdisp,z10")
1093 (set_attr "type" "*,*,larl")
1094 (set_attr "z196prop" "z196_cracked,z196_cracked,z196_cracked")])
1095
1096 (define_insn "*cmphi_ccs_z10"
1097 [(set (reg CC_REGNUM)
1098 (compare (match_operand:HI 0 "s_operand" "Q")
1099 (match_operand:HI 1 "immediate_operand" "K")))]
1100 "s390_match_ccmode(insn, CCSmode) && TARGET_Z10"
1101 "chhsi\t%0,%1"
1102 [(set_attr "op_type" "SIL")
1103 (set_attr "z196prop" "z196_cracked")])
1104
1105 (define_insn "*cmpdi_ccs_signhi_rl"
1106 [(set (reg CC_REGNUM)
1107 (compare (sign_extend:DI (match_operand:HI 1 "memory_operand" "T,b"))
1108 (match_operand:GPR 0 "register_operand" "d,d")))]
1109 "s390_match_ccmode(insn, CCSRmode) && TARGET_Z10"
1110 "@
1111 cgh\t%0,%1
1112 cghrl\t%0,%1"
1113 [(set_attr "op_type" "RXY,RIL")
1114 (set_attr "type" "*,larl")])
1115
1116 ; cr, chi, cfi, c, cy, cgr, cghi, cgfi, cg, chsi, cghsi, crl, cgrl
1117 (define_insn "*cmp<mode>_ccs"
1118 [(set (reg CC_REGNUM)
1119 (compare (match_operand:GPR 0 "nonimmediate_operand"
1120 "d,d,Q, d,d,d,d")
1121 (match_operand:GPR 1 "general_operand"
1122 "d,K,K,Os,R,T,b")))]
1123 "s390_match_ccmode(insn, CCSmode)"
1124 "@
1125 c<g>r\t%0,%1
1126 c<g>hi\t%0,%h1
1127 c<g>hsi\t%0,%h1
1128 c<g>fi\t%0,%1
1129 c<g>\t%0,%1
1130 c<y>\t%0,%1
1131 c<g>rl\t%0,%1"
1132 [(set_attr "op_type" "RR<E>,RI,SIL,RIL,RX<Y>,RXY,RIL")
1133 (set_attr "cpu_facility" "*,*,z10,extimm,*,longdisp,z10")
1134 (set_attr "type" "*,*,*,*,*,*,larl")
1135 (set_attr "z10prop" "z10_super_c,z10_super,z10_super,z10_super,z10_super,z10_super,z10_super")])
1136
1137
1138 ; Compare (unsigned) instructions
1139
1140 (define_insn "*cmpsi_ccu_zerohi_rlsi"
1141 [(set (reg CC_REGNUM)
1142 (compare (zero_extend:SI (mem:HI (match_operand:SI 1
1143 "larl_operand" "X")))
1144 (match_operand:SI 0 "register_operand" "d")))]
1145 "s390_match_ccmode(insn, CCURmode) && TARGET_Z10"
1146 "clhrl\t%0,%1"
1147 [(set_attr "op_type" "RIL")
1148 (set_attr "type" "larl")
1149 (set_attr "z10prop" "z10_super")])
1150
1151 ; clhrl, clghrl
1152 (define_insn "*cmp<GPR:mode>_ccu_zerohi_rldi"
1153 [(set (reg CC_REGNUM)
1154 (compare (zero_extend:GPR (mem:HI (match_operand:DI 1
1155 "larl_operand" "X")))
1156 (match_operand:GPR 0 "register_operand" "d")))]
1157 "s390_match_ccmode(insn, CCURmode) && TARGET_Z10"
1158 "cl<g>hrl\t%0,%1"
1159 [(set_attr "op_type" "RIL")
1160 (set_attr "type" "larl")
1161 (set_attr "z10prop" "z10_super")])
1162
1163 (define_insn "*cmpdi_ccu_zero"
1164 [(set (reg CC_REGNUM)
1165 (compare (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand"
1166 "d,T,b"))
1167 (match_operand:DI 0 "register_operand" "d,d,d")))]
1168 "s390_match_ccmode (insn, CCURmode) && TARGET_ZARCH"
1169 "@
1170 clgfr\t%0,%1
1171 clgf\t%0,%1
1172 clgfrl\t%0,%1"
1173 [(set_attr "op_type" "RRE,RXY,RIL")
1174 (set_attr "cpu_facility" "*,*,z10")
1175 (set_attr "type" "*,*,larl")
1176 (set_attr "z10prop" "z10_super_c,z10_super_E1,z10_super")])
1177
1178 (define_insn "*cmpdi_ccu"
1179 [(set (reg CC_REGNUM)
1180 (compare (match_operand:DI 0 "nonimmediate_operand"
1181 "d, d,d,Q,d, Q,BQ")
1182 (match_operand:DI 1 "general_operand"
1183 "d,Op,b,D,T,BQ,Q")))]
1184 "s390_match_ccmode (insn, CCUmode) && TARGET_ZARCH"
1185 "@
1186 clgr\t%0,%1
1187 clgfi\t%0,%1
1188 clgrl\t%0,%1
1189 clghsi\t%0,%x1
1190 clg\t%0,%1
1191 #
1192 #"
1193 [(set_attr "op_type" "RRE,RIL,RIL,SIL,RXY,SS,SS")
1194 (set_attr "cpu_facility" "*,extimm,z10,z10,*,*,*")
1195 (set_attr "type" "*,*,larl,*,*,*,*")
1196 (set_attr "z10prop" "z10_super_c,z10_super,z10_super,z10_super,z10_super,*,*")])
1197
1198 (define_insn "*cmpsi_ccu"
1199 [(set (reg CC_REGNUM)
1200 (compare (match_operand:SI 0 "nonimmediate_operand" "d, d,d,Q,d,d, Q,BQ")
1201 (match_operand:SI 1 "general_operand" "d,Os,b,D,R,T,BQ, Q")))]
1202 "s390_match_ccmode (insn, CCUmode)"
1203 "@
1204 clr\t%0,%1
1205 clfi\t%0,%o1
1206 clrl\t%0,%1
1207 clfhsi\t%0,%x1
1208 cl\t%0,%1
1209 cly\t%0,%1
1210 #
1211 #"
1212 [(set_attr "op_type" "RR,RIL,RIL,SIL,RX,RXY,SS,SS")
1213 (set_attr "cpu_facility" "*,extimm,z10,z10,*,longdisp,*,*")
1214 (set_attr "type" "*,*,larl,*,*,*,*,*")
1215 (set_attr "z10prop" "z10_super_c,z10_super,z10_super,z10_super,z10_super,z10_super,*,*")])
1216
1217 (define_insn "*cmphi_ccu"
1218 [(set (reg CC_REGNUM)
1219 (compare (match_operand:HI 0 "nonimmediate_operand" "d,d,Q,Q,BQ")
1220 (match_operand:HI 1 "general_operand" "Q,S,D,BQ,Q")))]
1221 "s390_match_ccmode (insn, CCUmode)
1222 && !register_operand (operands[1], HImode)"
1223 "@
1224 clm\t%0,3,%S1
1225 clmy\t%0,3,%S1
1226 clhhsi\t%0,%1
1227 #
1228 #"
1229 [(set_attr "op_type" "RS,RSY,SIL,SS,SS")
1230 (set_attr "cpu_facility" "*,longdisp,z10,*,*")
1231 (set_attr "z10prop" "*,*,z10_super,*,*")])
1232
1233 (define_insn "*cmpqi_ccu"
1234 [(set (reg CC_REGNUM)
1235 (compare (match_operand:QI 0 "nonimmediate_operand" "d,d,Q,S,Q,BQ")
1236 (match_operand:QI 1 "general_operand" "Q,S,n,n,BQ,Q")))]
1237 "s390_match_ccmode (insn, CCUmode)
1238 && !register_operand (operands[1], QImode)"
1239 "@
1240 clm\t%0,1,%S1
1241 clmy\t%0,1,%S1
1242 cli\t%S0,%b1
1243 cliy\t%S0,%b1
1244 #
1245 #"
1246 [(set_attr "op_type" "RS,RSY,SI,SIY,SS,SS")
1247 (set_attr "cpu_facility" "*,longdisp,*,longdisp,*,*")
1248 (set_attr "z10prop" "*,*,z10_super,z10_super,*,*")])
1249
1250
1251 ; Block compare (CLC) instruction patterns.
1252
1253 (define_insn "*clc"
1254 [(set (reg CC_REGNUM)
1255 (compare (match_operand:BLK 0 "memory_operand" "Q")
1256 (match_operand:BLK 1 "memory_operand" "Q")))
1257 (use (match_operand 2 "const_int_operand" "n"))]
1258 "s390_match_ccmode (insn, CCUmode)
1259 && INTVAL (operands[2]) >= 1 && INTVAL (operands[2]) <= 256"
1260 "clc\t%O0(%2,%R0),%S1"
1261 [(set_attr "op_type" "SS")])
1262
1263 (define_split
1264 [(set (reg CC_REGNUM)
1265 (compare (match_operand 0 "memory_operand" "")
1266 (match_operand 1 "memory_operand" "")))]
1267 "reload_completed
1268 && s390_match_ccmode (insn, CCUmode)
1269 && GET_MODE (operands[0]) == GET_MODE (operands[1])
1270 && GET_MODE_SIZE (GET_MODE (operands[0])) > 0"
1271 [(parallel
1272 [(set (match_dup 0) (match_dup 1))
1273 (use (match_dup 2))])]
1274 {
1275 operands[2] = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[0])));
1276 operands[0] = adjust_address (operands[0], BLKmode, 0);
1277 operands[1] = adjust_address (operands[1], BLKmode, 0);
1278
1279 operands[1] = gen_rtx_COMPARE (GET_MODE (SET_DEST (PATTERN (curr_insn))),
1280 operands[0], operands[1]);
1281 operands[0] = SET_DEST (PATTERN (curr_insn));
1282 })
1283
1284
1285 ; (TF|DF|SF|TD|DD|SD) instructions
1286
1287
1288 ; load and test instructions turn SNaN into QNaN what is not
1289 ; acceptable if the target will be used afterwards. On the other hand
1290 ; they are quite convenient for implementing comparisons with 0.0. So
1291 ; try to enable them via splitter if the value isn't needed anymore.
1292
1293 ; ltxbr, ltdbr, ltebr, ltxtr, ltdtr
1294 (define_insn "*cmp<mode>_ccs_0"
1295 [(set (reg CC_REGNUM)
1296 (compare (match_operand:FP 0 "register_operand" "f")
1297 (match_operand:FP 1 "const0_operand" "")))
1298 (clobber (match_operand:FP 2 "register_operand" "=0"))]
1299 "s390_match_ccmode(insn, CCSmode) && TARGET_HARD_FLOAT"
1300 "lt<xde><bt>r\t%0,%0"
1301 [(set_attr "op_type" "RRE")
1302 (set_attr "type" "fsimp<mode>")])
1303
1304 (define_split
1305 [(set (match_operand 0 "cc_reg_operand")
1306 (compare (match_operand:FP 1 "register_operand")
1307 (match_operand:FP 2 "const0_operand")))]
1308 "TARGET_HARD_FLOAT && REG_P (operands[1]) && dead_or_set_p (insn, operands[1])"
1309 [(parallel
1310 [(set (match_dup 0) (match_dup 3))
1311 (clobber (match_dup 1))])]
1312 {
1313 /* s390_match_ccmode requires the compare to have the same CC mode
1314 as the CC destination register. */
1315 operands[3] = gen_rtx_COMPARE (GET_MODE (operands[0]),
1316 operands[1], operands[2]);
1317 })
1318
1319
1320 ; cxtr, cxbr, cdtr, cdbr, cebr, cdb, ceb
1321 (define_insn "*cmp<mode>_ccs"
1322 [(set (reg CC_REGNUM)
1323 (compare (match_operand:FP 0 "register_operand" "f,f")
1324 (match_operand:FP 1 "general_operand" "f,R")))]
1325 "s390_match_ccmode(insn, CCSmode) && TARGET_HARD_FLOAT"
1326 "@
1327 c<xde><bt>r\t%0,%1
1328 c<xde>b\t%0,%1"
1329 [(set_attr "op_type" "RRE,RXE")
1330 (set_attr "type" "fsimp<mode>")
1331 (set_attr "enabled" "*,<DSF>")])
1332
1333 ; wfcedbs, wfchdbs, wfchedbs
1334 (define_insn "*vec_cmp<insn_cmp>df_cconly"
1335 [(set (reg:VFCMP CC_REGNUM)
1336 (compare:VFCMP (match_operand:DF 0 "register_operand" "v")
1337 (match_operand:DF 1 "register_operand" "v")))
1338 (clobber (match_scratch:V2DI 2 "=v"))]
1339 "TARGET_VX && TARGET_HARD_FLOAT"
1340 "wfc<asm_fcmp>dbs\t%v2,%v0,%v1"
1341 [(set_attr "op_type" "VRR")])
1342
1343 ; Compare and Branch instructions
1344
1345 ; cij, cgij, crj, cgrj, cfi, cgfi, cr, cgr
1346 ; The following instructions do a complementary access of their second
1347 ; operand (z01 only): crj_c, cgrjc, cr, cgr
1348 (define_insn "*cmp_and_br_signed_<mode>"
1349 [(set (pc)
1350 (if_then_else (match_operator 0 "s390_signed_integer_comparison"
1351 [(match_operand:GPR 1 "register_operand" "d,d")
1352 (match_operand:GPR 2 "nonmemory_operand" "d,C")])
1353 (label_ref (match_operand 3 "" ""))
1354 (pc)))
1355 (clobber (reg:CC CC_REGNUM))]
1356 "TARGET_Z10 && !TARGET_AVOID_CMP_AND_BRANCH"
1357 {
1358 if (get_attr_length (insn) == 6)
1359 return which_alternative ?
1360 "c<g>ij%C0\t%1,%c2,%l3" : "c<g>rj%C0\t%1,%2,%l3";
1361 else
1362 return which_alternative ?
1363 "c<g>fi\t%1,%c2\;jg%C0\t%l3" : "c<g>r\t%1,%2\;jg%C0\t%l3";
1364 }
1365 [(set_attr "op_type" "RIE")
1366 (set_attr "type" "branch")
1367 (set_attr "z10prop" "z10_super_c,z10_super")
1368 (set (attr "length")
1369 (if_then_else (lt (abs (minus (pc) (match_dup 3))) (const_int 60000))
1370 (const_int 6) (const_int 12)))]) ; 8 byte for cr/jg
1371 ; 10 byte for cgr/jg
1372
1373 ; clij, clgij, clrj, clgrj, clfi, clgfi, clr, clgr
1374 ; The following instructions do a complementary access of their second
1375 ; operand (z10 only): clrj, clgrj, clr, clgr
1376 (define_insn "*cmp_and_br_unsigned_<mode>"
1377 [(set (pc)
1378 (if_then_else (match_operator 0 "s390_unsigned_integer_comparison"
1379 [(match_operand:GPR 1 "register_operand" "d,d")
1380 (match_operand:GPR 2 "nonmemory_operand" "d,I")])
1381 (label_ref (match_operand 3 "" ""))
1382 (pc)))
1383 (clobber (reg:CC CC_REGNUM))]
1384 "TARGET_Z10 && !TARGET_AVOID_CMP_AND_BRANCH"
1385 {
1386 if (get_attr_length (insn) == 6)
1387 return which_alternative ?
1388 "cl<g>ij%C0\t%1,%b2,%l3" : "cl<g>rj%C0\t%1,%2,%l3";
1389 else
1390 return which_alternative ?
1391 "cl<g>fi\t%1,%b2\;jg%C0\t%l3" : "cl<g>r\t%1,%2\;jg%C0\t%l3";
1392 }
1393 [(set_attr "op_type" "RIE")
1394 (set_attr "type" "branch")
1395 (set_attr "z10prop" "z10_super_c,z10_super")
1396 (set (attr "length")
1397 (if_then_else (lt (abs (minus (pc) (match_dup 3))) (const_int 60000))
1398 (const_int 6) (const_int 12)))]) ; 8 byte for clr/jg
1399 ; 10 byte for clgr/jg
1400
1401 ; And now the same two patterns as above but with a negated CC mask.
1402
1403 ; cij, cgij, crj, cgrj, cfi, cgfi, cr, cgr
1404 ; The following instructions do a complementary access of their second
1405 ; operand (z01 only): crj_c, cgrjc, cr, cgr
1406 (define_insn "*icmp_and_br_signed_<mode>"
1407 [(set (pc)
1408 (if_then_else (match_operator 0 "s390_signed_integer_comparison"
1409 [(match_operand:GPR 1 "register_operand" "d,d")
1410 (match_operand:GPR 2 "nonmemory_operand" "d,C")])
1411 (pc)
1412 (label_ref (match_operand 3 "" ""))))
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 "c<g>ij%D0\t%1,%c2,%l3" : "c<g>rj%D0\t%1,%2,%l3";
1419 else
1420 return which_alternative ?
1421 "c<g>fi\t%1,%c2\;jg%D0\t%l3" : "c<g>r\t%1,%2\;jg%D0\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 cr/jg
1429 ; 10 byte for cgr/jg
1430
1431 ; clij, clgij, clrj, clgrj, clfi, clgfi, clr, clgr
1432 ; The following instructions do a complementary access of their second
1433 ; operand (z10 only): clrj, clgrj, clr, clgr
1434 (define_insn "*icmp_and_br_unsigned_<mode>"
1435 [(set (pc)
1436 (if_then_else (match_operator 0 "s390_unsigned_integer_comparison"
1437 [(match_operand:GPR 1 "register_operand" "d,d")
1438 (match_operand:GPR 2 "nonmemory_operand" "d,I")])
1439 (pc)
1440 (label_ref (match_operand 3 "" ""))))
1441 (clobber (reg:CC CC_REGNUM))]
1442 "TARGET_Z10 && !TARGET_AVOID_CMP_AND_BRANCH"
1443 {
1444 if (get_attr_length (insn) == 6)
1445 return which_alternative ?
1446 "cl<g>ij%D0\t%1,%b2,%l3" : "cl<g>rj%D0\t%1,%2,%l3";
1447 else
1448 return which_alternative ?
1449 "cl<g>fi\t%1,%b2\;jg%D0\t%l3" : "cl<g>r\t%1,%2\;jg%D0\t%l3";
1450 }
1451 [(set_attr "op_type" "RIE")
1452 (set_attr "type" "branch")
1453 (set_attr "z10prop" "z10_super_c,z10_super")
1454 (set (attr "length")
1455 (if_then_else (lt (abs (minus (pc) (match_dup 3))) (const_int 60000))
1456 (const_int 6) (const_int 12)))]) ; 8 byte for clr/jg
1457 ; 10 byte for clgr/jg
1458
1459 ;;
1460 ;;- Move instructions.
1461 ;;
1462
1463 ;
1464 ; movti instruction pattern(s).
1465 ;
1466
1467 ; FIXME: More constants are possible by enabling jxx, jyy constraints
1468 ; for TImode (use double-int for the calculations)
1469 (define_insn "movti"
1470 [(set (match_operand:TI 0 "nonimmediate_operand" "=d,S,v, v, v,v,d,v,R, d,o")
1471 (match_operand:TI 1 "general_operand" " S,d,v,j00,jm1,d,v,R,v,dPT,d"))]
1472 "TARGET_ZARCH"
1473 "@
1474 lmg\t%0,%N0,%S1
1475 stmg\t%1,%N1,%S0
1476 vlr\t%v0,%v1
1477 vzero\t%v0
1478 vone\t%v0
1479 vlvgp\t%v0,%1,%N1
1480 #
1481 vl\t%v0,%1
1482 vst\t%v1,%0
1483 #
1484 #"
1485 [(set_attr "op_type" "RSY,RSY,VRR,VRI,VRI,VRR,*,VRX,VRX,*,*")
1486 (set_attr "type" "lm,stm,*,*,*,*,*,*,*,*,*")
1487 (set_attr "cpu_facility" "*,*,vx,vx,vx,vx,vx,vx,vx,*,*")])
1488
1489 (define_split
1490 [(set (match_operand:TI 0 "nonimmediate_operand" "")
1491 (match_operand:TI 1 "general_operand" ""))]
1492 "TARGET_ZARCH && reload_completed
1493 && !s_operand (operands[0], TImode)
1494 && !s_operand (operands[1], TImode)
1495 && s390_split_ok_p (operands[0], operands[1], TImode, 0)"
1496 [(set (match_dup 2) (match_dup 4))
1497 (set (match_dup 3) (match_dup 5))]
1498 {
1499 operands[2] = operand_subword (operands[0], 0, 0, TImode);
1500 operands[3] = operand_subword (operands[0], 1, 0, TImode);
1501 operands[4] = operand_subword (operands[1], 0, 0, TImode);
1502 operands[5] = operand_subword (operands[1], 1, 0, TImode);
1503 })
1504
1505 (define_split
1506 [(set (match_operand:TI 0 "nonimmediate_operand" "")
1507 (match_operand:TI 1 "general_operand" ""))]
1508 "TARGET_ZARCH && reload_completed
1509 && !s_operand (operands[0], TImode)
1510 && !s_operand (operands[1], TImode)
1511 && s390_split_ok_p (operands[0], operands[1], TImode, 1)"
1512 [(set (match_dup 2) (match_dup 4))
1513 (set (match_dup 3) (match_dup 5))]
1514 {
1515 operands[2] = operand_subword (operands[0], 1, 0, TImode);
1516 operands[3] = operand_subword (operands[0], 0, 0, TImode);
1517 operands[4] = operand_subword (operands[1], 1, 0, TImode);
1518 operands[5] = operand_subword (operands[1], 0, 0, TImode);
1519 })
1520
1521 ; Use part of the TImode target reg to perform the address
1522 ; calculation. If the TImode value is supposed to be copied into a VR
1523 ; this splitter is not necessary.
1524 (define_split
1525 [(set (match_operand:TI 0 "register_operand" "")
1526 (match_operand:TI 1 "memory_operand" ""))]
1527 "TARGET_ZARCH && reload_completed
1528 && !VECTOR_REG_P (operands[0])
1529 && !s_operand (operands[1], VOIDmode)"
1530 [(set (match_dup 0) (match_dup 1))]
1531 {
1532 rtx addr = operand_subword (operands[0], 1, 0, TImode);
1533 addr = gen_lowpart (Pmode, addr);
1534 s390_load_address (addr, XEXP (operands[1], 0));
1535 operands[1] = replace_equiv_address (operands[1], addr);
1536 })
1537
1538
1539 ; Split a VR -> GPR TImode move into 2 vector load GR from VR element.
1540 ; For the higher order bits we do simply a DImode move while the
1541 ; second part is done via vec extract. Both will end up as vlgvg.
1542 (define_split
1543 [(set (match_operand:TI 0 "register_operand" "")
1544 (match_operand:TI 1 "register_operand" ""))]
1545 "TARGET_VX && reload_completed
1546 && GENERAL_REG_P (operands[0])
1547 && VECTOR_REG_P (operands[1])"
1548 [(set (match_dup 2) (match_dup 4))
1549 (set (match_dup 3) (unspec:DI [(match_dup 5) (const_int 1)]
1550 UNSPEC_VEC_EXTRACT))]
1551 {
1552 operands[2] = operand_subword (operands[0], 0, 0, TImode);
1553 operands[3] = operand_subword (operands[0], 1, 0, TImode);
1554 operands[4] = gen_rtx_REG (DImode, REGNO (operands[1]));
1555 operands[5] = gen_rtx_REG (V2DImode, REGNO (operands[1]));
1556 })
1557
1558 ;
1559 ; Patterns used for secondary reloads
1560 ;
1561
1562 ; z10 provides move instructions accepting larl memory operands.
1563 ; Unfortunately there is no such variant for QI, TI and FP mode moves.
1564 ; These patterns are also used for unaligned SI and DI accesses.
1565
1566 (define_expand "reload<ALL:mode><P:mode>_tomem_z10"
1567 [(parallel [(match_operand:ALL 0 "memory_operand" "")
1568 (match_operand:ALL 1 "register_operand" "=d")
1569 (match_operand:P 2 "register_operand" "=&a")])]
1570 "TARGET_Z10"
1571 {
1572 s390_reload_symref_address (operands[1], operands[0], operands[2], 1);
1573 DONE;
1574 })
1575
1576 (define_expand "reload<ALL:mode><P:mode>_toreg_z10"
1577 [(parallel [(match_operand:ALL 0 "register_operand" "=d")
1578 (match_operand:ALL 1 "memory_operand" "")
1579 (match_operand:P 2 "register_operand" "=a")])]
1580 "TARGET_Z10"
1581 {
1582 s390_reload_symref_address (operands[0], operands[1], operands[2], 0);
1583 DONE;
1584 })
1585
1586 (define_expand "reload<P:mode>_larl_odd_addend_z10"
1587 [(parallel [(match_operand:P 0 "register_operand" "=d")
1588 (match_operand:P 1 "larl_operand" "")
1589 (match_operand:P 2 "register_operand" "=a")])]
1590 "TARGET_Z10"
1591 {
1592 s390_reload_larl_operand (operands[0], operands[1], operands[2]);
1593 DONE;
1594 })
1595
1596 ; Handles loading a PLUS (load address) expression
1597
1598 (define_expand "reload<mode>_plus"
1599 [(parallel [(match_operand:P 0 "register_operand" "=a")
1600 (match_operand:P 1 "s390_plus_operand" "")
1601 (match_operand:P 2 "register_operand" "=&a")])]
1602 ""
1603 {
1604 s390_expand_plus_operand (operands[0], operands[1], operands[2]);
1605 DONE;
1606 })
1607
1608 ; Not all the indirect memory access instructions support the full
1609 ; format (long disp + index + base). So whenever a move from/to such
1610 ; an address is required and the instruction cannot deal with it we do
1611 ; a load address into a scratch register first and use this as the new
1612 ; base register.
1613 ; This in particular is used for:
1614 ; - non-offsetable memory accesses for multiword moves
1615 ; - full vector reg moves with long displacements
1616
1617 (define_expand "reload<mode>_la_in"
1618 [(parallel [(match_operand 0 "register_operand" "")
1619 (match_operand 1 "" "")
1620 (match_operand:P 2 "register_operand" "=&a")])]
1621 ""
1622 {
1623 gcc_assert (MEM_P (operands[1]));
1624 s390_load_address (operands[2], find_replacement (&XEXP (operands[1], 0)));
1625 operands[1] = replace_equiv_address (operands[1], operands[2]);
1626 emit_move_insn (operands[0], operands[1]);
1627 DONE;
1628 })
1629
1630 (define_expand "reload<mode>_la_out"
1631 [(parallel [(match_operand 0 "" "")
1632 (match_operand 1 "register_operand" "")
1633 (match_operand:P 2 "register_operand" "=&a")])]
1634 ""
1635 {
1636 gcc_assert (MEM_P (operands[0]));
1637 s390_load_address (operands[2], find_replacement (&XEXP (operands[0], 0)));
1638 operands[0] = replace_equiv_address (operands[0], operands[2]);
1639 emit_move_insn (operands[0], operands[1]);
1640 DONE;
1641 })
1642
1643 (define_expand "reload<mode>_PIC_addr"
1644 [(parallel [(match_operand 0 "register_operand" "=d")
1645 (match_operand 1 "larl_operand" "")
1646 (match_operand:P 2 "register_operand" "=a")])]
1647 ""
1648 {
1649 rtx new_rtx = legitimize_pic_address (operands[1], operands[2]);
1650 emit_move_insn (operands[0], new_rtx);
1651 })
1652
1653 ;
1654 ; movdi instruction pattern(s).
1655 ;
1656
1657 (define_expand "movdi"
1658 [(set (match_operand:DI 0 "general_operand" "")
1659 (match_operand:DI 1 "general_operand" ""))]
1660 ""
1661 {
1662 /* Handle symbolic constants. */
1663 if (TARGET_64BIT
1664 && (SYMBOLIC_CONST (operands[1])
1665 || (GET_CODE (operands[1]) == PLUS
1666 && XEXP (operands[1], 0) == pic_offset_table_rtx
1667 && SYMBOLIC_CONST (XEXP (operands[1], 1)))))
1668 emit_symbolic_move (operands);
1669 })
1670
1671 (define_insn "*movdi_larl"
1672 [(set (match_operand:DI 0 "register_operand" "=d")
1673 (match_operand:DI 1 "larl_operand" "X"))]
1674 "TARGET_64BIT
1675 && !FP_REG_P (operands[0])"
1676 "larl\t%0,%1"
1677 [(set_attr "op_type" "RIL")
1678 (set_attr "type" "larl")
1679 (set_attr "z10prop" "z10_super_A1")])
1680
1681 (define_insn "*movdi_64"
1682 [(set (match_operand:DI 0 "nonimmediate_operand"
1683 "=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")
1684 (match_operand:DI 1 "general_operand"
1685 " 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"))]
1686 "TARGET_ZARCH"
1687 "@
1688 lghi\t%0,%h1
1689 llihh\t%0,%i1
1690 llihl\t%0,%i1
1691 llilh\t%0,%i1
1692 llill\t%0,%i1
1693 lgfi\t%0,%1
1694 llihf\t%0,%k1
1695 llilf\t%0,%k1
1696 ldgr\t%0,%1
1697 lgdr\t%0,%1
1698 lay\t%0,%a1
1699 lgrl\t%0,%1
1700 lgr\t%0,%1
1701 lg\t%0,%1
1702 stg\t%1,%0
1703 ldr\t%0,%1
1704 ld\t%0,%1
1705 ldy\t%0,%1
1706 std\t%1,%0
1707 stdy\t%1,%0
1708 stgrl\t%1,%0
1709 mvghi\t%0,%1
1710 #
1711 #
1712 stam\t%1,%N1,%S0
1713 lam\t%0,%N0,%S1
1714 vleig\t%v0,%h1,0
1715 vlr\t%v0,%v1
1716 vlvgg\t%v0,%1,0
1717 vlgvg\t%0,%v1,0
1718 vleg\t%v0,%1,0
1719 vsteg\t%v1,%0,0"
1720 [(set_attr "op_type" "RI,RI,RI,RI,RI,RIL,RIL,RIL,RRE,RRE,RXY,RIL,RRE,RXY,
1721 RXY,RR,RX,RXY,RX,RXY,RIL,SIL,*,*,RS,RS,VRI,VRR,VRS,VRS,VRX,VRX")
1722 (set_attr "type" "*,*,*,*,*,*,*,*,floaddf,floaddf,la,larl,lr,load,store,
1723 floaddf,floaddf,floaddf,fstoredf,fstoredf,larl,*,*,*,*,
1724 *,*,*,*,*,*,*")
1725 (set_attr "cpu_facility" "*,*,*,*,*,extimm,extimm,extimm,dfp,dfp,longdisp,
1726 z10,*,*,*,*,*,longdisp,*,longdisp,
1727 z10,z10,*,*,*,*,vx,vx,vx,vx,vx,vx")
1728 (set_attr "z10prop" "z10_fwd_A1,
1729 z10_fwd_E1,
1730 z10_fwd_E1,
1731 z10_fwd_E1,
1732 z10_fwd_E1,
1733 z10_fwd_A1,
1734 z10_fwd_E1,
1735 z10_fwd_E1,
1736 *,
1737 *,
1738 z10_fwd_A1,
1739 z10_fwd_A3,
1740 z10_fr_E1,
1741 z10_fwd_A3,
1742 z10_rec,
1743 *,
1744 *,
1745 *,
1746 *,
1747 *,
1748 z10_rec,
1749 z10_super,
1750 *,
1751 *,
1752 *,
1753 *,*,*,*,*,*,*")
1754 ])
1755
1756 (define_split
1757 [(set (match_operand:DI 0 "register_operand" "")
1758 (match_operand:DI 1 "register_operand" ""))]
1759 "TARGET_ZARCH && ACCESS_REG_P (operands[1])"
1760 [(set (match_dup 2) (match_dup 3))
1761 (set (match_dup 0) (ashift:DI (match_dup 0) (const_int 32)))
1762 (set (strict_low_part (match_dup 2)) (match_dup 4))]
1763 "operands[2] = gen_lowpart (SImode, operands[0]);
1764 s390_split_access_reg (operands[1], &operands[4], &operands[3]);")
1765
1766 (define_split
1767 [(set (match_operand:DI 0 "register_operand" "")
1768 (match_operand:DI 1 "register_operand" ""))]
1769 "TARGET_ZARCH && ACCESS_REG_P (operands[0])
1770 && dead_or_set_p (insn, operands[1])"
1771 [(set (match_dup 3) (match_dup 2))
1772 (set (match_dup 1) (lshiftrt:DI (match_dup 1) (const_int 32)))
1773 (set (match_dup 4) (match_dup 2))]
1774 "operands[2] = gen_lowpart (SImode, operands[1]);
1775 s390_split_access_reg (operands[0], &operands[3], &operands[4]);")
1776
1777 (define_split
1778 [(set (match_operand:DI 0 "register_operand" "")
1779 (match_operand:DI 1 "register_operand" ""))]
1780 "TARGET_ZARCH && ACCESS_REG_P (operands[0])
1781 && !dead_or_set_p (insn, operands[1])"
1782 [(set (match_dup 3) (match_dup 2))
1783 (set (match_dup 1) (rotate:DI (match_dup 1) (const_int 32)))
1784 (set (match_dup 4) (match_dup 2))
1785 (set (match_dup 1) (rotate:DI (match_dup 1) (const_int 32)))]
1786 "operands[2] = gen_lowpart (SImode, operands[1]);
1787 s390_split_access_reg (operands[0], &operands[3], &operands[4]);")
1788
1789 (define_insn "*movdi_31"
1790 [(set (match_operand:DI 0 "nonimmediate_operand"
1791 "=d,d,Q,S,d ,o,!*f,!*f,!*f,!R,!T,d")
1792 (match_operand:DI 1 "general_operand"
1793 " Q,S,d,d,dPT,d, *f, R, T,*f,*f,b"))]
1794 "!TARGET_ZARCH"
1795 "@
1796 lm\t%0,%N0,%S1
1797 lmy\t%0,%N0,%S1
1798 stm\t%1,%N1,%S0
1799 stmy\t%1,%N1,%S0
1800 #
1801 #
1802 ldr\t%0,%1
1803 ld\t%0,%1
1804 ldy\t%0,%1
1805 std\t%1,%0
1806 stdy\t%1,%0
1807 #"
1808 [(set_attr "op_type" "RS,RSY,RS,RSY,*,*,RR,RX,RXY,RX,RXY,*")
1809 (set_attr "type" "lm,lm,stm,stm,*,*,floaddf,floaddf,floaddf,fstoredf,fstoredf,*")
1810 (set_attr "cpu_facility" "*,longdisp,*,longdisp,*,*,*,*,longdisp,*,longdisp,z10")])
1811
1812 ; For a load from a symbol ref we can use one of the target registers
1813 ; together with larl to load the address.
1814 (define_split
1815 [(set (match_operand:DI 0 "register_operand" "")
1816 (match_operand:DI 1 "memory_operand" ""))]
1817 "!TARGET_ZARCH && reload_completed && TARGET_Z10
1818 && larl_operand (XEXP (operands[1], 0), SImode)"
1819 [(set (match_dup 2) (match_dup 3))
1820 (set (match_dup 0) (match_dup 1))]
1821 {
1822 operands[2] = operand_subword (operands[0], 1, 0, DImode);
1823 operands[3] = XEXP (operands[1], 0);
1824 operands[1] = replace_equiv_address (operands[1], operands[2]);
1825 })
1826
1827 (define_split
1828 [(set (match_operand:DI 0 "nonimmediate_operand" "")
1829 (match_operand:DI 1 "general_operand" ""))]
1830 "!TARGET_ZARCH && reload_completed
1831 && !s_operand (operands[0], DImode)
1832 && !s_operand (operands[1], DImode)
1833 && s390_split_ok_p (operands[0], operands[1], DImode, 0)"
1834 [(set (match_dup 2) (match_dup 4))
1835 (set (match_dup 3) (match_dup 5))]
1836 {
1837 operands[2] = operand_subword (operands[0], 0, 0, DImode);
1838 operands[3] = operand_subword (operands[0], 1, 0, DImode);
1839 operands[4] = operand_subword (operands[1], 0, 0, DImode);
1840 operands[5] = operand_subword (operands[1], 1, 0, DImode);
1841 })
1842
1843 (define_split
1844 [(set (match_operand:DI 0 "nonimmediate_operand" "")
1845 (match_operand:DI 1 "general_operand" ""))]
1846 "!TARGET_ZARCH && reload_completed
1847 && !s_operand (operands[0], DImode)
1848 && !s_operand (operands[1], DImode)
1849 && s390_split_ok_p (operands[0], operands[1], DImode, 1)"
1850 [(set (match_dup 2) (match_dup 4))
1851 (set (match_dup 3) (match_dup 5))]
1852 {
1853 operands[2] = operand_subword (operands[0], 1, 0, DImode);
1854 operands[3] = operand_subword (operands[0], 0, 0, DImode);
1855 operands[4] = operand_subword (operands[1], 1, 0, DImode);
1856 operands[5] = operand_subword (operands[1], 0, 0, DImode);
1857 })
1858
1859 (define_split
1860 [(set (match_operand:DI 0 "register_operand" "")
1861 (match_operand:DI 1 "memory_operand" ""))]
1862 "!TARGET_ZARCH && reload_completed
1863 && !FP_REG_P (operands[0])
1864 && !s_operand (operands[1], VOIDmode)"
1865 [(set (match_dup 0) (match_dup 1))]
1866 {
1867 rtx addr = operand_subword (operands[0], 1, 0, DImode);
1868 s390_load_address (addr, XEXP (operands[1], 0));
1869 operands[1] = replace_equiv_address (operands[1], addr);
1870 })
1871
1872 (define_peephole2
1873 [(set (match_operand:DI 0 "register_operand" "")
1874 (mem:DI (match_operand 1 "address_operand" "")))]
1875 "TARGET_ZARCH
1876 && !FP_REG_P (operands[0])
1877 && GET_CODE (operands[1]) == SYMBOL_REF
1878 && CONSTANT_POOL_ADDRESS_P (operands[1])
1879 && get_pool_mode (operands[1]) == DImode
1880 && legitimate_reload_constant_p (get_pool_constant (operands[1]))"
1881 [(set (match_dup 0) (match_dup 2))]
1882 "operands[2] = get_pool_constant (operands[1]);")
1883
1884 (define_insn "*la_64"
1885 [(set (match_operand:DI 0 "register_operand" "=d,d")
1886 (match_operand:QI 1 "address_operand" "ZR,ZT"))]
1887 "TARGET_64BIT"
1888 "@
1889 la\t%0,%a1
1890 lay\t%0,%a1"
1891 [(set_attr "op_type" "RX,RXY")
1892 (set_attr "type" "la")
1893 (set_attr "cpu_facility" "*,longdisp")
1894 (set_attr "z10prop" "z10_fwd_A1,z10_fwd_A1")])
1895
1896 (define_peephole2
1897 [(parallel
1898 [(set (match_operand:DI 0 "register_operand" "")
1899 (match_operand:QI 1 "address_operand" ""))
1900 (clobber (reg:CC CC_REGNUM))])]
1901 "TARGET_64BIT
1902 && preferred_la_operand_p (operands[1], const0_rtx)"
1903 [(set (match_dup 0) (match_dup 1))]
1904 "")
1905
1906 (define_peephole2
1907 [(set (match_operand:DI 0 "register_operand" "")
1908 (match_operand:DI 1 "register_operand" ""))
1909 (parallel
1910 [(set (match_dup 0)
1911 (plus:DI (match_dup 0)
1912 (match_operand:DI 2 "nonmemory_operand" "")))
1913 (clobber (reg:CC CC_REGNUM))])]
1914 "TARGET_64BIT
1915 && !reg_overlap_mentioned_p (operands[0], operands[2])
1916 && preferred_la_operand_p (operands[1], operands[2])"
1917 [(set (match_dup 0) (plus:DI (match_dup 1) (match_dup 2)))]
1918 "")
1919
1920 ;
1921 ; movsi instruction pattern(s).
1922 ;
1923
1924 (define_expand "movsi"
1925 [(set (match_operand:SI 0 "general_operand" "")
1926 (match_operand:SI 1 "general_operand" ""))]
1927 ""
1928 {
1929 /* Handle symbolic constants. */
1930 if (!TARGET_64BIT
1931 && (SYMBOLIC_CONST (operands[1])
1932 || (GET_CODE (operands[1]) == PLUS
1933 && XEXP (operands[1], 0) == pic_offset_table_rtx
1934 && SYMBOLIC_CONST (XEXP(operands[1], 1)))))
1935 emit_symbolic_move (operands);
1936 })
1937
1938 (define_insn "*movsi_larl"
1939 [(set (match_operand:SI 0 "register_operand" "=d")
1940 (match_operand:SI 1 "larl_operand" "X"))]
1941 "!TARGET_64BIT && TARGET_CPU_ZARCH
1942 && !FP_REG_P (operands[0])"
1943 "larl\t%0,%1"
1944 [(set_attr "op_type" "RIL")
1945 (set_attr "type" "larl")
1946 (set_attr "z10prop" "z10_fwd_A1")])
1947
1948 (define_insn "*movsi_zarch"
1949 [(set (match_operand:SI 0 "nonimmediate_operand"
1950 "=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")
1951 (match_operand:SI 1 "general_operand"
1952 " 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"))]
1953 "TARGET_ZARCH"
1954 "@
1955 lhi\t%0,%h1
1956 llilh\t%0,%i1
1957 llill\t%0,%i1
1958 iilf\t%0,%o1
1959 lay\t%0,%a1
1960 lrl\t%0,%1
1961 lr\t%0,%1
1962 l\t%0,%1
1963 ly\t%0,%1
1964 st\t%1,%0
1965 sty\t%1,%0
1966 ldr\t%0,%1
1967 ler\t%0,%1
1968 lde\t%0,%1
1969 le\t%0,%1
1970 ley\t%0,%1
1971 ste\t%1,%0
1972 stey\t%1,%0
1973 ear\t%0,%1
1974 sar\t%0,%1
1975 stam\t%1,%1,%S0
1976 strl\t%1,%0
1977 mvhi\t%0,%1
1978 lam\t%0,%0,%S1
1979 vleif\t%v0,%h1,0
1980 vlr\t%v0,%v1
1981 vlvgf\t%v0,%1,0
1982 vlgvf\t%0,%v1,0
1983 vlef\t%v0,%1,0
1984 vstef\t%v1,%0,0"
1985 [(set_attr "op_type" "RI,RI,RI,RIL,RXY,RIL,RR,RX,RXY,RX,RXY,
1986 RR,RR,RXE,RX,RXY,RX,RXY,RRE,RRE,RS,RIL,SIL,RS,VRI,VRR,VRS,VRS,VRX,VRX")
1987 (set_attr "type" "*,
1988 *,
1989 *,
1990 *,
1991 la,
1992 larl,
1993 lr,
1994 load,
1995 load,
1996 store,
1997 store,
1998 floadsf,
1999 floadsf,
2000 floadsf,
2001 floadsf,
2002 floadsf,
2003 fstoresf,
2004 fstoresf,
2005 *,
2006 *,
2007 *,
2008 larl,
2009 *,
2010 *,*,*,*,*,*,*")
2011 (set_attr "cpu_facility" "*,*,*,extimm,longdisp,z10,*,*,longdisp,*,longdisp,
2012 vx,*,vx,*,longdisp,*,longdisp,*,*,*,z10,z10,*,vx,vx,vx,vx,vx,vx")
2013 (set_attr "z10prop" "z10_fwd_A1,
2014 z10_fwd_E1,
2015 z10_fwd_E1,
2016 z10_fwd_A1,
2017 z10_fwd_A1,
2018 z10_fwd_A3,
2019 z10_fr_E1,
2020 z10_fwd_A3,
2021 z10_fwd_A3,
2022 z10_rec,
2023 z10_rec,
2024 *,
2025 *,
2026 *,
2027 *,
2028 *,
2029 *,
2030 *,
2031 z10_super_E1,
2032 z10_super,
2033 *,
2034 z10_rec,
2035 z10_super,
2036 *,*,*,*,*,*,*")])
2037
2038 (define_insn "*movsi_esa"
2039 [(set (match_operand:SI 0 "nonimmediate_operand" "=d,d,d,R,!*f,!*f,!*f,!*f,!R,d,t,Q,t")
2040 (match_operand:SI 1 "general_operand" "K,d,R,d, *f, *f, R, R,*f,t,d,t,Q"))]
2041 "!TARGET_ZARCH"
2042 "@
2043 lhi\t%0,%h1
2044 lr\t%0,%1
2045 l\t%0,%1
2046 st\t%1,%0
2047 ldr\t%0,%1
2048 ler\t%0,%1
2049 lde\t%0,%1
2050 le\t%0,%1
2051 ste\t%1,%0
2052 ear\t%0,%1
2053 sar\t%0,%1
2054 stam\t%1,%1,%S0
2055 lam\t%0,%0,%S1"
2056 [(set_attr "op_type" "RI,RR,RX,RX,RR,RR,RXE,RX,RX,RRE,RRE,RS,RS")
2057 (set_attr "type" "*,lr,load,store,floadsf,floadsf,floadsf,floadsf,fstoresf,*,*,*,*")
2058 (set_attr "z10prop" "z10_fwd_A1,z10_fr_E1,z10_fwd_A3,z10_rec,*,*,*,*,*,z10_super_E1,
2059 z10_super,*,*")
2060 (set_attr "cpu_facility" "*,*,*,*,vx,*,vx,*,*,*,*,*,*")
2061 ])
2062
2063 (define_peephole2
2064 [(set (match_operand:SI 0 "register_operand" "")
2065 (mem:SI (match_operand 1 "address_operand" "")))]
2066 "!FP_REG_P (operands[0])
2067 && GET_CODE (operands[1]) == SYMBOL_REF
2068 && CONSTANT_POOL_ADDRESS_P (operands[1])
2069 && get_pool_mode (operands[1]) == SImode
2070 && legitimate_reload_constant_p (get_pool_constant (operands[1]))"
2071 [(set (match_dup 0) (match_dup 2))]
2072 "operands[2] = get_pool_constant (operands[1]);")
2073
2074 (define_insn "*la_31"
2075 [(set (match_operand:SI 0 "register_operand" "=d,d")
2076 (match_operand:QI 1 "address_operand" "ZR,ZT"))]
2077 "!TARGET_64BIT && legitimate_la_operand_p (operands[1])"
2078 "@
2079 la\t%0,%a1
2080 lay\t%0,%a1"
2081 [(set_attr "op_type" "RX,RXY")
2082 (set_attr "type" "la")
2083 (set_attr "cpu_facility" "*,longdisp")
2084 (set_attr "z10prop" "z10_fwd_A1,z10_fwd_A1")])
2085
2086 (define_peephole2
2087 [(parallel
2088 [(set (match_operand:SI 0 "register_operand" "")
2089 (match_operand:QI 1 "address_operand" ""))
2090 (clobber (reg:CC CC_REGNUM))])]
2091 "!TARGET_64BIT
2092 && preferred_la_operand_p (operands[1], const0_rtx)"
2093 [(set (match_dup 0) (match_dup 1))]
2094 "")
2095
2096 (define_peephole2
2097 [(set (match_operand:SI 0 "register_operand" "")
2098 (match_operand:SI 1 "register_operand" ""))
2099 (parallel
2100 [(set (match_dup 0)
2101 (plus:SI (match_dup 0)
2102 (match_operand:SI 2 "nonmemory_operand" "")))
2103 (clobber (reg:CC CC_REGNUM))])]
2104 "!TARGET_64BIT
2105 && !reg_overlap_mentioned_p (operands[0], operands[2])
2106 && preferred_la_operand_p (operands[1], operands[2])"
2107 [(set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))]
2108 "")
2109
2110 (define_insn "*la_31_and"
2111 [(set (match_operand:SI 0 "register_operand" "=d,d")
2112 (and:SI (match_operand:QI 1 "address_operand" "ZR,ZT")
2113 (const_int 2147483647)))]
2114 "!TARGET_64BIT"
2115 "@
2116 la\t%0,%a1
2117 lay\t%0,%a1"
2118 [(set_attr "op_type" "RX,RXY")
2119 (set_attr "type" "la")
2120 (set_attr "cpu_facility" "*,longdisp")
2121 (set_attr "z10prop" "z10_fwd_A1,z10_fwd_A1")])
2122
2123 (define_insn_and_split "*la_31_and_cc"
2124 [(set (match_operand:SI 0 "register_operand" "=d")
2125 (and:SI (match_operand:QI 1 "address_operand" "p")
2126 (const_int 2147483647)))
2127 (clobber (reg:CC CC_REGNUM))]
2128 "!TARGET_64BIT"
2129 "#"
2130 "&& reload_completed"
2131 [(set (match_dup 0)
2132 (and:SI (match_dup 1) (const_int 2147483647)))]
2133 ""
2134 [(set_attr "op_type" "RX")
2135 (set_attr "type" "la")])
2136
2137 (define_insn "force_la_31"
2138 [(set (match_operand:SI 0 "register_operand" "=d,d")
2139 (match_operand:QI 1 "address_operand" "ZR,ZT"))
2140 (use (const_int 0))]
2141 "!TARGET_64BIT"
2142 "@
2143 la\t%0,%a1
2144 lay\t%0,%a1"
2145 [(set_attr "op_type" "RX")
2146 (set_attr "type" "la")
2147 (set_attr "cpu_facility" "*,longdisp")
2148 (set_attr "z10prop" "z10_fwd_A1,z10_fwd_A1")])
2149
2150 ;
2151 ; movhi instruction pattern(s).
2152 ;
2153
2154 (define_expand "movhi"
2155 [(set (match_operand:HI 0 "nonimmediate_operand" "")
2156 (match_operand:HI 1 "general_operand" ""))]
2157 ""
2158 {
2159 /* Make it explicit that loading a register from memory
2160 always sign-extends (at least) to SImode. */
2161 if (optimize && can_create_pseudo_p ()
2162 && register_operand (operands[0], VOIDmode)
2163 && GET_CODE (operands[1]) == MEM)
2164 {
2165 rtx tmp = gen_reg_rtx (SImode);
2166 rtx ext = gen_rtx_SIGN_EXTEND (SImode, operands[1]);
2167 emit_insn (gen_rtx_SET (tmp, ext));
2168 operands[1] = gen_lowpart (HImode, tmp);
2169 }
2170 })
2171
2172 (define_insn "*movhi"
2173 [(set (match_operand:HI 0 "nonimmediate_operand" "=d,d,d,d,d,R,T,b,Q,v,v,v,d,v,R")
2174 (match_operand:HI 1 "general_operand" " d,n,R,T,b,d,d,d,K,K,v,d,v,R,v"))]
2175 ""
2176 "@
2177 lr\t%0,%1
2178 lhi\t%0,%h1
2179 lh\t%0,%1
2180 lhy\t%0,%1
2181 lhrl\t%0,%1
2182 sth\t%1,%0
2183 sthy\t%1,%0
2184 sthrl\t%1,%0
2185 mvhhi\t%0,%1
2186 vleih\t%v0,%h1,0
2187 vlr\t%v0,%v1
2188 vlvgh\t%v0,%1,0
2189 vlgvh\t%0,%v1,0
2190 vleh\t%v0,%1,0
2191 vsteh\t%v1,%0,0"
2192 [(set_attr "op_type" "RR,RI,RX,RXY,RIL,RX,RXY,RIL,SIL,VRI,VRR,VRS,VRS,VRX,VRX")
2193 (set_attr "type" "lr,*,*,*,larl,store,store,store,*,*,*,*,*,*,*")
2194 (set_attr "cpu_facility" "*,*,*,longdisp,z10,*,longdisp,z10,z10,vx,vx,vx,vx,vx,vx")
2195 (set_attr "z10prop" "z10_fr_E1,
2196 z10_fwd_A1,
2197 z10_super_E1,
2198 z10_super_E1,
2199 z10_super_E1,
2200 z10_rec,
2201 z10_rec,
2202 z10_rec,
2203 z10_super,*,*,*,*,*,*")])
2204
2205 (define_peephole2
2206 [(set (match_operand:HI 0 "register_operand" "")
2207 (mem:HI (match_operand 1 "address_operand" "")))]
2208 "GET_CODE (operands[1]) == SYMBOL_REF
2209 && CONSTANT_POOL_ADDRESS_P (operands[1])
2210 && get_pool_mode (operands[1]) == HImode
2211 && GET_CODE (get_pool_constant (operands[1])) == CONST_INT"
2212 [(set (match_dup 0) (match_dup 2))]
2213 "operands[2] = get_pool_constant (operands[1]);")
2214
2215 ;
2216 ; movqi instruction pattern(s).
2217 ;
2218
2219 (define_expand "movqi"
2220 [(set (match_operand:QI 0 "nonimmediate_operand" "")
2221 (match_operand:QI 1 "general_operand" ""))]
2222 ""
2223 {
2224 /* On z/Architecture, zero-extending from memory to register
2225 is just as fast as a QImode load. */
2226 if (TARGET_ZARCH && optimize && can_create_pseudo_p ()
2227 && register_operand (operands[0], VOIDmode)
2228 && GET_CODE (operands[1]) == MEM)
2229 {
2230 rtx tmp = gen_reg_rtx (DImode);
2231 rtx ext = gen_rtx_ZERO_EXTEND (DImode, operands[1]);
2232 emit_insn (gen_rtx_SET (tmp, ext));
2233 operands[1] = gen_lowpart (QImode, tmp);
2234 }
2235 })
2236
2237 (define_insn "*movqi"
2238 [(set (match_operand:QI 0 "nonimmediate_operand" "=d,d,d,d,R,T,Q,S,?Q,v,v,v,d,v,R")
2239 (match_operand:QI 1 "general_operand" " d,n,R,T,d,d,n,n,?Q,K,v,d,v,R,v"))]
2240 ""
2241 "@
2242 lr\t%0,%1
2243 lhi\t%0,%b1
2244 ic\t%0,%1
2245 icy\t%0,%1
2246 stc\t%1,%0
2247 stcy\t%1,%0
2248 mvi\t%S0,%b1
2249 mviy\t%S0,%b1
2250 #
2251 vleib\t%v0,%b1,0
2252 vlr\t%v0,%v1
2253 vlvgb\t%v0,%1,0
2254 vlgvb\t%0,%v1,0
2255 vleb\t%v0,%1,0
2256 vsteb\t%v1,%0,0"
2257 [(set_attr "op_type" "RR,RI,RX,RXY,RX,RXY,SI,SIY,SS,VRI,VRR,VRS,VRS,VRX,VRX")
2258 (set_attr "type" "lr,*,*,*,store,store,store,store,*,*,*,*,*,*,*")
2259 (set_attr "cpu_facility" "*,*,*,longdisp,*,longdisp,*,longdisp,*,vx,vx,vx,vx,vx,vx")
2260 (set_attr "z10prop" "z10_fr_E1,
2261 z10_fwd_A1,
2262 z10_super_E1,
2263 z10_super_E1,
2264 z10_rec,
2265 z10_rec,
2266 z10_super,
2267 z10_super,
2268 *,*,*,*,*,*,*")])
2269
2270 (define_peephole2
2271 [(set (match_operand:QI 0 "nonimmediate_operand" "")
2272 (mem:QI (match_operand 1 "address_operand" "")))]
2273 "GET_CODE (operands[1]) == SYMBOL_REF
2274 && CONSTANT_POOL_ADDRESS_P (operands[1])
2275 && get_pool_mode (operands[1]) == QImode
2276 && GET_CODE (get_pool_constant (operands[1])) == CONST_INT"
2277 [(set (match_dup 0) (match_dup 2))]
2278 "operands[2] = get_pool_constant (operands[1]);")
2279
2280 ;
2281 ; movstrictqi instruction pattern(s).
2282 ;
2283
2284 (define_insn "*movstrictqi"
2285 [(set (strict_low_part (match_operand:QI 0 "register_operand" "+d,d"))
2286 (match_operand:QI 1 "memory_operand" "R,T"))]
2287 ""
2288 "@
2289 ic\t%0,%1
2290 icy\t%0,%1"
2291 [(set_attr "op_type" "RX,RXY")
2292 (set_attr "cpu_facility" "*,longdisp")
2293 (set_attr "z10prop" "z10_super_E1,z10_super_E1")])
2294
2295 ;
2296 ; movstricthi instruction pattern(s).
2297 ;
2298
2299 (define_insn "*movstricthi"
2300 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+d,d"))
2301 (match_operand:HI 1 "memory_operand" "Q,S"))
2302 (clobber (reg:CC CC_REGNUM))]
2303 ""
2304 "@
2305 icm\t%0,3,%S1
2306 icmy\t%0,3,%S1"
2307 [(set_attr "op_type" "RS,RSY")
2308 (set_attr "cpu_facility" "*,longdisp")
2309 (set_attr "z10prop" "z10_super_E1,z10_super_E1")])
2310
2311 ;
2312 ; movstrictsi instruction pattern(s).
2313 ;
2314
2315 (define_insn "movstrictsi"
2316 [(set (strict_low_part (match_operand:SI 0 "register_operand" "+d,d,d,d"))
2317 (match_operand:SI 1 "general_operand" "d,R,T,t"))]
2318 "TARGET_ZARCH"
2319 "@
2320 lr\t%0,%1
2321 l\t%0,%1
2322 ly\t%0,%1
2323 ear\t%0,%1"
2324 [(set_attr "op_type" "RR,RX,RXY,RRE")
2325 (set_attr "type" "lr,load,load,*")
2326 (set_attr "cpu_facility" "*,*,longdisp,*")
2327 (set_attr "z10prop" "z10_fr_E1,z10_fwd_A3,z10_fwd_A3,z10_super_E1")])
2328
2329 ;
2330 ; mov(tf|td) instruction pattern(s).
2331 ;
2332
2333 (define_expand "mov<mode>"
2334 [(set (match_operand:TD_TF 0 "nonimmediate_operand" "")
2335 (match_operand:TD_TF 1 "general_operand" ""))]
2336 ""
2337 "")
2338
2339 (define_insn "*mov<mode>_64"
2340 [(set (match_operand:TD_TF 0 "nonimmediate_operand" "=f,f,f,o,d,S, d,o")
2341 (match_operand:TD_TF 1 "general_operand" " G,f,o,f,S,d,dT,d"))]
2342 "TARGET_ZARCH"
2343 "@
2344 lzxr\t%0
2345 lxr\t%0,%1
2346 #
2347 #
2348 lmg\t%0,%N0,%S1
2349 stmg\t%1,%N1,%S0
2350 #
2351 #"
2352 [(set_attr "op_type" "RRE,RRE,*,*,RSY,RSY,*,*")
2353 (set_attr "type" "fsimptf,fsimptf,*,*,lm,stm,*,*")
2354 (set_attr "cpu_facility" "z196,*,*,*,*,*,*,*")])
2355
2356 (define_insn "*mov<mode>_31"
2357 [(set (match_operand:TD_TF 0 "nonimmediate_operand" "=f,f,f,o")
2358 (match_operand:TD_TF 1 "general_operand" " G,f,o,f"))]
2359 "!TARGET_ZARCH"
2360 "@
2361 lzxr\t%0
2362 lxr\t%0,%1
2363 #
2364 #"
2365 [(set_attr "op_type" "RRE,RRE,*,*")
2366 (set_attr "type" "fsimptf,fsimptf,*,*")
2367 (set_attr "cpu_facility" "z196,*,*,*")])
2368
2369 ; TFmode in GPRs splitters
2370
2371 (define_split
2372 [(set (match_operand:TD_TF 0 "nonimmediate_operand" "")
2373 (match_operand:TD_TF 1 "general_operand" ""))]
2374 "TARGET_ZARCH && reload_completed
2375 && !s_operand (operands[0], <MODE>mode)
2376 && !s_operand (operands[1], <MODE>mode)
2377 && s390_split_ok_p (operands[0], operands[1], <MODE>mode, 0)"
2378 [(set (match_dup 2) (match_dup 4))
2379 (set (match_dup 3) (match_dup 5))]
2380 {
2381 operands[2] = operand_subword (operands[0], 0, 0, <MODE>mode);
2382 operands[3] = operand_subword (operands[0], 1, 0, <MODE>mode);
2383 operands[4] = operand_subword (operands[1], 0, 0, <MODE>mode);
2384 operands[5] = operand_subword (operands[1], 1, 0, <MODE>mode);
2385 })
2386
2387 (define_split
2388 [(set (match_operand:TD_TF 0 "nonimmediate_operand" "")
2389 (match_operand:TD_TF 1 "general_operand" ""))]
2390 "TARGET_ZARCH && reload_completed
2391 && !s_operand (operands[0], <MODE>mode)
2392 && !s_operand (operands[1], <MODE>mode)
2393 && s390_split_ok_p (operands[0], operands[1], <MODE>mode, 1)"
2394 [(set (match_dup 2) (match_dup 4))
2395 (set (match_dup 3) (match_dup 5))]
2396 {
2397 operands[2] = operand_subword (operands[0], 1, 0, <MODE>mode);
2398 operands[3] = operand_subword (operands[0], 0, 0, <MODE>mode);
2399 operands[4] = operand_subword (operands[1], 1, 0, <MODE>mode);
2400 operands[5] = operand_subword (operands[1], 0, 0, <MODE>mode);
2401 })
2402
2403 (define_split
2404 [(set (match_operand:TD_TF 0 "register_operand" "")
2405 (match_operand:TD_TF 1 "memory_operand" ""))]
2406 "TARGET_ZARCH && reload_completed
2407 && GENERAL_REG_P (operands[0])
2408 && !s_operand (operands[1], VOIDmode)"
2409 [(set (match_dup 0) (match_dup 1))]
2410 {
2411 rtx addr = operand_subword (operands[0], 1, 0, <MODE>mode);
2412 addr = gen_lowpart (Pmode, addr);
2413 s390_load_address (addr, XEXP (operands[1], 0));
2414 operands[1] = replace_equiv_address (operands[1], addr);
2415 })
2416
2417 ; TFmode in BFPs splitters
2418
2419 (define_split
2420 [(set (match_operand:TD_TF 0 "register_operand" "")
2421 (match_operand:TD_TF 1 "memory_operand" ""))]
2422 "reload_completed && offsettable_memref_p (operands[1])
2423 && FP_REG_P (operands[0])"
2424 [(set (match_dup 2) (match_dup 4))
2425 (set (match_dup 3) (match_dup 5))]
2426 {
2427 operands[2] = simplify_gen_subreg (<HALF_TMODE>mode, operands[0],
2428 <MODE>mode, 0);
2429 operands[3] = simplify_gen_subreg (<HALF_TMODE>mode, operands[0],
2430 <MODE>mode, 8);
2431 operands[4] = adjust_address_nv (operands[1], <HALF_TMODE>mode, 0);
2432 operands[5] = adjust_address_nv (operands[1], <HALF_TMODE>mode, 8);
2433 })
2434
2435 (define_split
2436 [(set (match_operand:TD_TF 0 "memory_operand" "")
2437 (match_operand:TD_TF 1 "register_operand" ""))]
2438 "reload_completed && offsettable_memref_p (operands[0])
2439 && FP_REG_P (operands[1])"
2440 [(set (match_dup 2) (match_dup 4))
2441 (set (match_dup 3) (match_dup 5))]
2442 {
2443 operands[2] = adjust_address_nv (operands[0], <HALF_TMODE>mode, 0);
2444 operands[3] = adjust_address_nv (operands[0], <HALF_TMODE>mode, 8);
2445 operands[4] = simplify_gen_subreg (<HALF_TMODE>mode, operands[1],
2446 <MODE>mode, 0);
2447 operands[5] = simplify_gen_subreg (<HALF_TMODE>mode, operands[1],
2448 <MODE>mode, 8);
2449 })
2450
2451 ;
2452 ; mov(df|dd) instruction pattern(s).
2453 ;
2454
2455 (define_expand "mov<mode>"
2456 [(set (match_operand:DD_DF 0 "nonimmediate_operand" "")
2457 (match_operand:DD_DF 1 "general_operand" ""))]
2458 ""
2459 "")
2460
2461 (define_insn "*mov<mode>_64dfp"
2462 [(set (match_operand:DD_DF 0 "nonimmediate_operand"
2463 "=f,f,f,d,f,f,R,T,d,d,d,d,b,T,v,v,d,v,R")
2464 (match_operand:DD_DF 1 "general_operand"
2465 " G,f,d,f,R,T,f,f,G,d,b,T,d,d,v,d,v,R,v"))]
2466 "TARGET_DFP"
2467 "@
2468 lzdr\t%0
2469 ldr\t%0,%1
2470 ldgr\t%0,%1
2471 lgdr\t%0,%1
2472 ld\t%0,%1
2473 ldy\t%0,%1
2474 std\t%1,%0
2475 stdy\t%1,%0
2476 lghi\t%0,0
2477 lgr\t%0,%1
2478 lgrl\t%0,%1
2479 lg\t%0,%1
2480 stgrl\t%1,%0
2481 stg\t%1,%0
2482 vlr\t%v0,%v1
2483 vlvgg\t%v0,%1,0
2484 vlgvg\t%0,%v1,0
2485 vleg\t%0,%1,0
2486 vsteg\t%1,%0,0"
2487 [(set_attr "op_type" "RRE,RR,RRE,RRE,RX,RXY,RX,RXY,RI,RRE,RIL,RXY,RIL,RXY,VRR,VRS,VRS,VRX,VRX")
2488 (set_attr "type" "fsimpdf,floaddf,floaddf,floaddf,floaddf,floaddf,
2489 fstoredf,fstoredf,*,lr,load,load,store,store,*,*,*,load,store")
2490 (set_attr "z10prop" "*,*,*,*,*,*,*,*,z10_fwd_A1,z10_fr_E1,z10_fwd_A3,z10_fwd_A3,z10_rec,z10_rec,*,*,*,*,*")
2491 (set_attr "cpu_facility" "z196,*,*,*,*,longdisp,*,longdisp,*,*,z10,*,z10,*,vx,vx,vx,vx,vx")])
2492
2493 (define_insn "*mov<mode>_64"
2494 [(set (match_operand:DD_DF 0 "nonimmediate_operand" "=f,f,f,f,R,T,d,d,d,d,b,T,v,v,R")
2495 (match_operand:DD_DF 1 "general_operand" " G,f,R,T,f,f,G,d,b,T,d,d,v,R,v"))]
2496 "TARGET_ZARCH"
2497 "@
2498 lzdr\t%0
2499 ldr\t%0,%1
2500 ld\t%0,%1
2501 ldy\t%0,%1
2502 std\t%1,%0
2503 stdy\t%1,%0
2504 lghi\t%0,0
2505 lgr\t%0,%1
2506 lgrl\t%0,%1
2507 lg\t%0,%1
2508 stgrl\t%1,%0
2509 stg\t%1,%0
2510 vlr\t%v0,%v1
2511 vleg\t%v0,%1,0
2512 vsteg\t%v1,%0,0"
2513 [(set_attr "op_type" "RRE,RR,RX,RXY,RX,RXY,RI,RRE,RIL,RXY,RIL,RXY,VRR,VRX,VRX")
2514 (set_attr "type" "fsimpdf,fload<mode>,fload<mode>,fload<mode>,
2515 fstore<mode>,fstore<mode>,*,lr,load,load,store,store,*,load,store")
2516 (set_attr "z10prop" "*,*,*,*,*,*,z10_fwd_A1,z10_fr_E1,z10_fwd_A3,z10_fwd_A3,z10_rec,z10_rec,*,*,*")
2517 (set_attr "cpu_facility" "z196,*,*,longdisp,*,longdisp,*,*,z10,*,z10,*,vx,vx,vx")])
2518
2519 (define_insn "*mov<mode>_31"
2520 [(set (match_operand:DD_DF 0 "nonimmediate_operand"
2521 "=f,f,f,f,R,T,d,d,Q,S, d,o")
2522 (match_operand:DD_DF 1 "general_operand"
2523 " G,f,R,T,f,f,Q,S,d,d,dPT,d"))]
2524 "!TARGET_ZARCH"
2525 "@
2526 lzdr\t%0
2527 ldr\t%0,%1
2528 ld\t%0,%1
2529 ldy\t%0,%1
2530 std\t%1,%0
2531 stdy\t%1,%0
2532 lm\t%0,%N0,%S1
2533 lmy\t%0,%N0,%S1
2534 stm\t%1,%N1,%S0
2535 stmy\t%1,%N1,%S0
2536 #
2537 #"
2538 [(set_attr "op_type" "RRE,RR,RX,RXY,RX,RXY,RS,RSY,RS,RSY,*,*")
2539 (set_attr "type" "fsimpdf,fload<mode>,fload<mode>,fload<mode>,
2540 fstore<mode>,fstore<mode>,lm,lm,stm,stm,*,*")
2541 (set_attr "cpu_facility" "z196,*,*,longdisp,*,longdisp,*,longdisp,*,longdisp,*,*")])
2542
2543 (define_split
2544 [(set (match_operand:DD_DF 0 "nonimmediate_operand" "")
2545 (match_operand:DD_DF 1 "general_operand" ""))]
2546 "!TARGET_ZARCH && reload_completed
2547 && !s_operand (operands[0], <MODE>mode)
2548 && !s_operand (operands[1], <MODE>mode)
2549 && s390_split_ok_p (operands[0], operands[1], <MODE>mode, 0)"
2550 [(set (match_dup 2) (match_dup 4))
2551 (set (match_dup 3) (match_dup 5))]
2552 {
2553 operands[2] = operand_subword (operands[0], 0, 0, <MODE>mode);
2554 operands[3] = operand_subword (operands[0], 1, 0, <MODE>mode);
2555 operands[4] = operand_subword (operands[1], 0, 0, <MODE>mode);
2556 operands[5] = operand_subword (operands[1], 1, 0, <MODE>mode);
2557 })
2558
2559 (define_split
2560 [(set (match_operand:DD_DF 0 "nonimmediate_operand" "")
2561 (match_operand:DD_DF 1 "general_operand" ""))]
2562 "!TARGET_ZARCH && reload_completed
2563 && !s_operand (operands[0], <MODE>mode)
2564 && !s_operand (operands[1], <MODE>mode)
2565 && s390_split_ok_p (operands[0], operands[1], <MODE>mode, 1)"
2566 [(set (match_dup 2) (match_dup 4))
2567 (set (match_dup 3) (match_dup 5))]
2568 {
2569 operands[2] = operand_subword (operands[0], 1, 0, <MODE>mode);
2570 operands[3] = operand_subword (operands[0], 0, 0, <MODE>mode);
2571 operands[4] = operand_subword (operands[1], 1, 0, <MODE>mode);
2572 operands[5] = operand_subword (operands[1], 0, 0, <MODE>mode);
2573 })
2574
2575 (define_split
2576 [(set (match_operand:DD_DF 0 "register_operand" "")
2577 (match_operand:DD_DF 1 "memory_operand" ""))]
2578 "!TARGET_ZARCH && reload_completed
2579 && !FP_REG_P (operands[0])
2580 && !s_operand (operands[1], VOIDmode)"
2581 [(set (match_dup 0) (match_dup 1))]
2582 {
2583 rtx addr = operand_subword (operands[0], 1, 0, <MODE>mode);
2584 s390_load_address (addr, XEXP (operands[1], 0));
2585 operands[1] = replace_equiv_address (operands[1], addr);
2586 })
2587
2588 ;
2589 ; mov(sf|sd) instruction pattern(s).
2590 ;
2591
2592 (define_insn "mov<mode>"
2593 [(set (match_operand:SD_SF 0 "nonimmediate_operand"
2594 "=f,f,f,f,f,f,R,T,d,d,d,d,d,b,R,T,v,v,v,d,v,R")
2595 (match_operand:SD_SF 1 "general_operand"
2596 " G,f,f,R,R,T,f,f,G,d,b,R,T,d,d,d,v,G,d,v,R,v"))]
2597 ""
2598 "@
2599 lzer\t%0
2600 ldr\t%0,%1
2601 ler\t%0,%1
2602 lde\t%0,%1
2603 le\t%0,%1
2604 ley\t%0,%1
2605 ste\t%1,%0
2606 stey\t%1,%0
2607 lhi\t%0,0
2608 lr\t%0,%1
2609 lrl\t%0,%1
2610 l\t%0,%1
2611 ly\t%0,%1
2612 strl\t%1,%0
2613 st\t%1,%0
2614 sty\t%1,%0
2615 vlr\t%v0,%v1
2616 vleif\t%v0,0
2617 vlvgf\t%v0,%1,0
2618 vlgvf\t%0,%v1,0
2619 vleg\t%0,%1,0
2620 vsteg\t%1,%0,0"
2621 [(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")
2622 (set_attr "type" "fsimpsf,fsimpsf,fload<mode>,fload<mode>,fload<mode>,fload<mode>,
2623 fstore<mode>,fstore<mode>,*,lr,load,load,load,store,store,store,*,*,*,*,load,store")
2624 (set_attr "z10prop" "*,*,*,*,*,*,*,*,z10_fwd_A1,z10_fr_E1,z10_fr_E1,z10_fwd_A3,z10_fwd_A3,z10_rec,z10_rec,z10_rec,*,*,*,*,*,*")
2625 (set_attr "cpu_facility" "z196,vx,*,vx,*,longdisp,*,longdisp,*,*,z10,*,longdisp,z10,*,longdisp,vx,vx,vx,vx,vx,vx")])
2626
2627 ;
2628 ; movcc instruction pattern
2629 ;
2630
2631 (define_insn "movcc"
2632 [(set (match_operand:CC 0 "nonimmediate_operand" "=d,c,d,d,d,R,T")
2633 (match_operand:CC 1 "nonimmediate_operand" " d,d,c,R,T,d,d"))]
2634 ""
2635 "@
2636 lr\t%0,%1
2637 tmh\t%1,12288
2638 ipm\t%0
2639 l\t%0,%1
2640 ly\t%0,%1
2641 st\t%1,%0
2642 sty\t%1,%0"
2643 [(set_attr "op_type" "RR,RI,RRE,RX,RXY,RX,RXY")
2644 (set_attr "type" "lr,*,*,load,load,store,store")
2645 (set_attr "cpu_facility" "*,*,*,*,longdisp,*,longdisp")
2646 (set_attr "z10prop" "z10_fr_E1,z10_super,*,z10_fwd_A3,z10_fwd_A3,z10_rec,z10_rec")
2647 (set_attr "z196prop" "*,*,z196_ends,*,*,*,*")])
2648
2649 ;
2650 ; Block move (MVC) patterns.
2651 ;
2652
2653 (define_insn "*mvc"
2654 [(set (match_operand:BLK 0 "memory_operand" "=Q")
2655 (match_operand:BLK 1 "memory_operand" "Q"))
2656 (use (match_operand 2 "const_int_operand" "n"))]
2657 "INTVAL (operands[2]) >= 1 && INTVAL (operands[2]) <= 256"
2658 "mvc\t%O0(%2,%R0),%S1"
2659 [(set_attr "op_type" "SS")])
2660
2661 ; This splitter converts a QI to QI mode copy into a BLK mode copy in
2662 ; order to have it implemented with mvc.
2663
2664 (define_split
2665 [(set (match_operand:QI 0 "memory_operand" "")
2666 (match_operand:QI 1 "memory_operand" ""))]
2667 "reload_completed"
2668 [(parallel
2669 [(set (match_dup 0) (match_dup 1))
2670 (use (const_int 1))])]
2671 {
2672 operands[0] = adjust_address (operands[0], BLKmode, 0);
2673 operands[1] = adjust_address (operands[1], BLKmode, 0);
2674 })
2675
2676
2677 (define_peephole2
2678 [(parallel
2679 [(set (match_operand:BLK 0 "memory_operand" "")
2680 (match_operand:BLK 1 "memory_operand" ""))
2681 (use (match_operand 2 "const_int_operand" ""))])
2682 (parallel
2683 [(set (match_operand:BLK 3 "memory_operand" "")
2684 (match_operand:BLK 4 "memory_operand" ""))
2685 (use (match_operand 5 "const_int_operand" ""))])]
2686 "s390_offset_p (operands[0], operands[3], operands[2])
2687 && s390_offset_p (operands[1], operands[4], operands[2])
2688 && !s390_overlap_p (operands[0], operands[1],
2689 INTVAL (operands[2]) + INTVAL (operands[5]))
2690 && INTVAL (operands[2]) + INTVAL (operands[5]) <= 256"
2691 [(parallel
2692 [(set (match_dup 6) (match_dup 7))
2693 (use (match_dup 8))])]
2694 "operands[6] = gen_rtx_MEM (BLKmode, XEXP (operands[0], 0));
2695 operands[7] = gen_rtx_MEM (BLKmode, XEXP (operands[1], 0));
2696 operands[8] = GEN_INT (INTVAL (operands[2]) + INTVAL (operands[5]));")
2697
2698
2699 ;
2700 ; load_multiple pattern(s).
2701 ;
2702 ; ??? Due to reload problems with replacing registers inside match_parallel
2703 ; we currently support load_multiple/store_multiple only after reload.
2704 ;
2705
2706 (define_expand "load_multiple"
2707 [(match_par_dup 3 [(set (match_operand 0 "" "")
2708 (match_operand 1 "" ""))
2709 (use (match_operand 2 "" ""))])]
2710 "reload_completed"
2711 {
2712 machine_mode mode;
2713 int regno;
2714 int count;
2715 rtx from;
2716 int i, off;
2717
2718 /* Support only loading a constant number of fixed-point registers from
2719 memory and only bother with this if more than two */
2720 if (GET_CODE (operands[2]) != CONST_INT
2721 || INTVAL (operands[2]) < 2
2722 || INTVAL (operands[2]) > 16
2723 || GET_CODE (operands[1]) != MEM
2724 || GET_CODE (operands[0]) != REG
2725 || REGNO (operands[0]) >= 16)
2726 FAIL;
2727
2728 count = INTVAL (operands[2]);
2729 regno = REGNO (operands[0]);
2730 mode = GET_MODE (operands[0]);
2731 if (mode != SImode && (!TARGET_ZARCH || mode != DImode))
2732 FAIL;
2733
2734 operands[3] = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (count));
2735 if (!can_create_pseudo_p ())
2736 {
2737 if (GET_CODE (XEXP (operands[1], 0)) == REG)
2738 {
2739 from = XEXP (operands[1], 0);
2740 off = 0;
2741 }
2742 else if (GET_CODE (XEXP (operands[1], 0)) == PLUS
2743 && GET_CODE (XEXP (XEXP (operands[1], 0), 0)) == REG
2744 && GET_CODE (XEXP (XEXP (operands[1], 0), 1)) == CONST_INT)
2745 {
2746 from = XEXP (XEXP (operands[1], 0), 0);
2747 off = INTVAL (XEXP (XEXP (operands[1], 0), 1));
2748 }
2749 else
2750 FAIL;
2751 }
2752 else
2753 {
2754 from = force_reg (Pmode, XEXP (operands[1], 0));
2755 off = 0;
2756 }
2757
2758 for (i = 0; i < count; i++)
2759 XVECEXP (operands[3], 0, i)
2760 = gen_rtx_SET (gen_rtx_REG (mode, regno + i),
2761 change_address (operands[1], mode,
2762 plus_constant (Pmode, from,
2763 off + i * GET_MODE_SIZE (mode))));
2764 })
2765
2766 (define_insn "*load_multiple_di"
2767 [(match_parallel 0 "load_multiple_operation"
2768 [(set (match_operand:DI 1 "register_operand" "=r")
2769 (match_operand:DI 2 "s_operand" "S"))])]
2770 "reload_completed && TARGET_ZARCH"
2771 {
2772 int words = XVECLEN (operands[0], 0);
2773 operands[0] = gen_rtx_REG (DImode, REGNO (operands[1]) + words - 1);
2774 return "lmg\t%1,%0,%S2";
2775 }
2776 [(set_attr "op_type" "RSY")
2777 (set_attr "type" "lm")])
2778
2779 (define_insn "*load_multiple_si"
2780 [(match_parallel 0 "load_multiple_operation"
2781 [(set (match_operand:SI 1 "register_operand" "=r,r")
2782 (match_operand:SI 2 "s_operand" "Q,S"))])]
2783 "reload_completed"
2784 {
2785 int words = XVECLEN (operands[0], 0);
2786 operands[0] = gen_rtx_REG (SImode, REGNO (operands[1]) + words - 1);
2787 return which_alternative == 0 ? "lm\t%1,%0,%S2" : "lmy\t%1,%0,%S2";
2788 }
2789 [(set_attr "op_type" "RS,RSY")
2790 (set_attr "cpu_facility" "*,longdisp")
2791 (set_attr "type" "lm")])
2792
2793 ;
2794 ; store multiple pattern(s).
2795 ;
2796
2797 (define_expand "store_multiple"
2798 [(match_par_dup 3 [(set (match_operand 0 "" "")
2799 (match_operand 1 "" ""))
2800 (use (match_operand 2 "" ""))])]
2801 "reload_completed"
2802 {
2803 machine_mode mode;
2804 int regno;
2805 int count;
2806 rtx to;
2807 int i, off;
2808
2809 /* Support only storing a constant number of fixed-point registers to
2810 memory and only bother with this if more than two. */
2811 if (GET_CODE (operands[2]) != CONST_INT
2812 || INTVAL (operands[2]) < 2
2813 || INTVAL (operands[2]) > 16
2814 || GET_CODE (operands[0]) != MEM
2815 || GET_CODE (operands[1]) != REG
2816 || REGNO (operands[1]) >= 16)
2817 FAIL;
2818
2819 count = INTVAL (operands[2]);
2820 regno = REGNO (operands[1]);
2821 mode = GET_MODE (operands[1]);
2822 if (mode != SImode && (!TARGET_ZARCH || mode != DImode))
2823 FAIL;
2824
2825 operands[3] = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (count));
2826
2827 if (!can_create_pseudo_p ())
2828 {
2829 if (GET_CODE (XEXP (operands[0], 0)) == REG)
2830 {
2831 to = XEXP (operands[0], 0);
2832 off = 0;
2833 }
2834 else if (GET_CODE (XEXP (operands[0], 0)) == PLUS
2835 && GET_CODE (XEXP (XEXP (operands[0], 0), 0)) == REG
2836 && GET_CODE (XEXP (XEXP (operands[0], 0), 1)) == CONST_INT)
2837 {
2838 to = XEXP (XEXP (operands[0], 0), 0);
2839 off = INTVAL (XEXP (XEXP (operands[0], 0), 1));
2840 }
2841 else
2842 FAIL;
2843 }
2844 else
2845 {
2846 to = force_reg (Pmode, XEXP (operands[0], 0));
2847 off = 0;
2848 }
2849
2850 for (i = 0; i < count; i++)
2851 XVECEXP (operands[3], 0, i)
2852 = gen_rtx_SET (change_address (operands[0], mode,
2853 plus_constant (Pmode, to,
2854 off + i * GET_MODE_SIZE (mode))),
2855 gen_rtx_REG (mode, regno + i));
2856 })
2857
2858 (define_insn "*store_multiple_di"
2859 [(match_parallel 0 "store_multiple_operation"
2860 [(set (match_operand:DI 1 "s_operand" "=S")
2861 (match_operand:DI 2 "register_operand" "r"))])]
2862 "reload_completed && TARGET_ZARCH"
2863 {
2864 int words = XVECLEN (operands[0], 0);
2865 operands[0] = gen_rtx_REG (DImode, REGNO (operands[2]) + words - 1);
2866 return "stmg\t%2,%0,%S1";
2867 }
2868 [(set_attr "op_type" "RSY")
2869 (set_attr "type" "stm")])
2870
2871
2872 (define_insn "*store_multiple_si"
2873 [(match_parallel 0 "store_multiple_operation"
2874 [(set (match_operand:SI 1 "s_operand" "=Q,S")
2875 (match_operand:SI 2 "register_operand" "r,r"))])]
2876 "reload_completed"
2877 {
2878 int words = XVECLEN (operands[0], 0);
2879 operands[0] = gen_rtx_REG (SImode, REGNO (operands[2]) + words - 1);
2880 return which_alternative == 0 ? "stm\t%2,%0,%S1" : "stmy\t%2,%0,%S1";
2881 }
2882 [(set_attr "op_type" "RS,RSY")
2883 (set_attr "cpu_facility" "*,longdisp")
2884 (set_attr "type" "stm")])
2885
2886 ;;
2887 ;; String instructions.
2888 ;;
2889
2890 (define_insn "*execute_rl"
2891 [(match_parallel 0 "execute_operation"
2892 [(unspec [(match_operand 1 "register_operand" "a")
2893 (match_operand 2 "" "")
2894 (match_operand:SI 3 "larl_operand" "X")] UNSPEC_EXECUTE)])]
2895 "TARGET_Z10 && GET_MODE_CLASS (GET_MODE (operands[1])) == MODE_INT
2896 && GET_MODE_SIZE (GET_MODE (operands[1])) <= UNITS_PER_WORD"
2897 "exrl\t%1,%3"
2898 [(set_attr "op_type" "RIL")
2899 (set_attr "type" "cs")])
2900
2901 (define_insn "*execute"
2902 [(match_parallel 0 "execute_operation"
2903 [(unspec [(match_operand 1 "register_operand" "a")
2904 (match_operand:BLK 2 "memory_operand" "R")
2905 (match_operand 3 "" "")] UNSPEC_EXECUTE)])]
2906 "GET_MODE_CLASS (GET_MODE (operands[1])) == MODE_INT
2907 && GET_MODE_SIZE (GET_MODE (operands[1])) <= UNITS_PER_WORD"
2908 "ex\t%1,%2"
2909 [(set_attr "op_type" "RX")
2910 (set_attr "type" "cs")])
2911
2912
2913 ;
2914 ; strlenM instruction pattern(s).
2915 ;
2916
2917 (define_expand "strlen<mode>"
2918 [(match_operand:P 0 "register_operand" "") ; result
2919 (match_operand:BLK 1 "memory_operand" "") ; input string
2920 (match_operand:SI 2 "immediate_operand" "") ; search character
2921 (match_operand:SI 3 "immediate_operand" "")] ; known alignment
2922 ""
2923 {
2924 if (!TARGET_VX || operands[2] != const0_rtx)
2925 emit_insn (gen_strlen_srst<mode> (operands[0], operands[1],
2926 operands[2], operands[3]));
2927 else
2928 s390_expand_vec_strlen (operands[0], operands[1], operands[3]);
2929
2930 DONE;
2931 })
2932
2933 (define_expand "strlen_srst<mode>"
2934 [(set (reg:SI 0) (match_operand:SI 2 "immediate_operand" ""))
2935 (parallel
2936 [(set (match_dup 4)
2937 (unspec:P [(const_int 0)
2938 (match_operand:BLK 1 "memory_operand" "")
2939 (reg:SI 0)
2940 (match_operand 3 "immediate_operand" "")] UNSPEC_SRST))
2941 (clobber (scratch:P))
2942 (clobber (reg:CC CC_REGNUM))])
2943 (parallel
2944 [(set (match_operand:P 0 "register_operand" "")
2945 (minus:P (match_dup 4) (match_dup 5)))
2946 (clobber (reg:CC CC_REGNUM))])]
2947 ""
2948 {
2949 operands[4] = gen_reg_rtx (Pmode);
2950 operands[5] = gen_reg_rtx (Pmode);
2951 emit_move_insn (operands[5], force_operand (XEXP (operands[1], 0), NULL_RTX));
2952 operands[1] = replace_equiv_address (operands[1], operands[5]);
2953 })
2954
2955 (define_insn "*strlen<mode>"
2956 [(set (match_operand:P 0 "register_operand" "=a")
2957 (unspec:P [(match_operand:P 2 "general_operand" "0")
2958 (mem:BLK (match_operand:P 3 "register_operand" "1"))
2959 (reg:SI 0)
2960 (match_operand 4 "immediate_operand" "")] UNSPEC_SRST))
2961 (clobber (match_scratch:P 1 "=a"))
2962 (clobber (reg:CC CC_REGNUM))]
2963 ""
2964 "srst\t%0,%1\;jo\t.-4"
2965 [(set_attr "length" "8")
2966 (set_attr "type" "vs")])
2967
2968 ;
2969 ; cmpstrM instruction pattern(s).
2970 ;
2971
2972 (define_expand "cmpstrsi"
2973 [(set (reg:SI 0) (const_int 0))
2974 (parallel
2975 [(clobber (match_operand 3 "" ""))
2976 (clobber (match_dup 4))
2977 (set (reg:CCU CC_REGNUM)
2978 (compare:CCU (match_operand:BLK 1 "memory_operand" "")
2979 (match_operand:BLK 2 "memory_operand" "")))
2980 (use (reg:SI 0))])
2981 (parallel
2982 [(set (match_operand:SI 0 "register_operand" "=d")
2983 (unspec:SI [(reg:CCU CC_REGNUM)] UNSPEC_STRCMPCC_TO_INT))
2984 (clobber (reg:CC CC_REGNUM))])]
2985 ""
2986 {
2987 /* As the result of CMPINT is inverted compared to what we need,
2988 we have to swap the operands. */
2989 rtx op1 = operands[2];
2990 rtx op2 = operands[1];
2991 rtx addr1 = gen_reg_rtx (Pmode);
2992 rtx addr2 = gen_reg_rtx (Pmode);
2993
2994 emit_move_insn (addr1, force_operand (XEXP (op1, 0), NULL_RTX));
2995 emit_move_insn (addr2, force_operand (XEXP (op2, 0), NULL_RTX));
2996 operands[1] = replace_equiv_address_nv (op1, addr1);
2997 operands[2] = replace_equiv_address_nv (op2, addr2);
2998 operands[3] = addr1;
2999 operands[4] = addr2;
3000 })
3001
3002 (define_insn "*cmpstr<mode>"
3003 [(clobber (match_operand:P 0 "register_operand" "=d"))
3004 (clobber (match_operand:P 1 "register_operand" "=d"))
3005 (set (reg:CCU CC_REGNUM)
3006 (compare:CCU (mem:BLK (match_operand:P 2 "register_operand" "0"))
3007 (mem:BLK (match_operand:P 3 "register_operand" "1"))))
3008 (use (reg:SI 0))]
3009 ""
3010 "clst\t%0,%1\;jo\t.-4"
3011 [(set_attr "length" "8")
3012 (set_attr "type" "vs")])
3013
3014 ;
3015 ; movstr instruction pattern.
3016 ;
3017
3018 (define_expand "movstr"
3019 [(match_operand 0 "register_operand" "")
3020 (match_operand 1 "memory_operand" "")
3021 (match_operand 2 "memory_operand" "")]
3022 ""
3023 {
3024 if (TARGET_64BIT)
3025 emit_insn (gen_movstrdi (operands[0], operands[1], operands[2]));
3026 else
3027 emit_insn (gen_movstrsi (operands[0], operands[1], operands[2]));
3028 DONE;
3029 })
3030
3031 (define_expand "movstr<P:mode>"
3032 [(set (reg:SI 0) (const_int 0))
3033 (parallel
3034 [(clobber (match_dup 3))
3035 (set (match_operand:BLK 1 "memory_operand" "")
3036 (match_operand:BLK 2 "memory_operand" ""))
3037 (set (match_operand:P 0 "register_operand" "")
3038 (unspec:P [(match_dup 1)
3039 (match_dup 2)
3040 (reg:SI 0)] UNSPEC_MVST))
3041 (clobber (reg:CC CC_REGNUM))])]
3042 ""
3043 {
3044 rtx addr1, addr2;
3045
3046 if (TARGET_VX && optimize_function_for_speed_p (cfun))
3047 {
3048 s390_expand_vec_movstr (operands[0], operands[1], operands[2]);
3049 DONE;
3050 }
3051
3052 addr1 = gen_reg_rtx (Pmode);
3053 addr2 = gen_reg_rtx (Pmode);
3054
3055 emit_move_insn (addr1, force_operand (XEXP (operands[1], 0), NULL_RTX));
3056 emit_move_insn (addr2, force_operand (XEXP (operands[2], 0), NULL_RTX));
3057 operands[1] = replace_equiv_address_nv (operands[1], addr1);
3058 operands[2] = replace_equiv_address_nv (operands[2], addr2);
3059 operands[3] = addr2;
3060 })
3061
3062 (define_insn "*movstr"
3063 [(clobber (match_operand:P 2 "register_operand" "=d"))
3064 (set (mem:BLK (match_operand:P 1 "register_operand" "0"))
3065 (mem:BLK (match_operand:P 3 "register_operand" "2")))
3066 (set (match_operand:P 0 "register_operand" "=d")
3067 (unspec:P [(mem:BLK (match_dup 1))
3068 (mem:BLK (match_dup 3))
3069 (reg:SI 0)] UNSPEC_MVST))
3070 (clobber (reg:CC CC_REGNUM))]
3071 ""
3072 "mvst\t%1,%2\;jo\t.-4"
3073 [(set_attr "length" "8")
3074 (set_attr "type" "vs")])
3075
3076
3077 ;
3078 ; movmemM instruction pattern(s).
3079 ;
3080
3081 (define_expand "movmem<mode>"
3082 [(set (match_operand:BLK 0 "memory_operand" "") ; destination
3083 (match_operand:BLK 1 "memory_operand" "")) ; source
3084 (use (match_operand:GPR 2 "general_operand" "")) ; count
3085 (match_operand 3 "" "")]
3086 ""
3087 {
3088 if (s390_expand_movmem (operands[0], operands[1], operands[2]))
3089 DONE;
3090 else
3091 FAIL;
3092 })
3093
3094 ; Move a block that is up to 256 bytes in length.
3095 ; The block length is taken as (operands[2] % 256) + 1.
3096
3097 (define_expand "movmem_short"
3098 [(parallel
3099 [(set (match_operand:BLK 0 "memory_operand" "")
3100 (match_operand:BLK 1 "memory_operand" ""))
3101 (use (match_operand 2 "nonmemory_operand" ""))
3102 (use (const:BLK (unspec:BLK [(const_int 0)] UNSPEC_INSN)))
3103 (clobber (match_dup 3))])]
3104 ""
3105 "operands[3] = gen_rtx_SCRATCH (Pmode);")
3106
3107 (define_insn "*movmem_short"
3108 [(set (match_operand:BLK 0 "memory_operand" "=Q,Q,Q,Q")
3109 (match_operand:BLK 1 "memory_operand" "Q,Q,Q,Q"))
3110 (use (match_operand 2 "nonmemory_operand" "n,a,a,a"))
3111 (use (match_operand 3 "immediate_operand" "X,R,X,X"))
3112 (clobber (match_scratch:P 4 "=X,X,X,&a"))]
3113 "(GET_MODE (operands[2]) == Pmode || GET_MODE (operands[2]) == VOIDmode)"
3114 "#"
3115 [(set_attr "type" "cs")
3116 (set_attr "cpu_facility" "*,*,z10,cpu_zarch")])
3117
3118 (define_split
3119 [(set (match_operand:BLK 0 "memory_operand" "")
3120 (match_operand:BLK 1 "memory_operand" ""))
3121 (use (match_operand 2 "const_int_operand" ""))
3122 (use (match_operand 3 "immediate_operand" ""))
3123 (clobber (scratch))]
3124 "reload_completed"
3125 [(parallel
3126 [(set (match_dup 0) (match_dup 1))
3127 (use (match_dup 2))])]
3128 "operands[2] = GEN_INT ((INTVAL (operands[2]) & 0xff) + 1);")
3129
3130 (define_split
3131 [(set (match_operand:BLK 0 "memory_operand" "")
3132 (match_operand:BLK 1 "memory_operand" ""))
3133 (use (match_operand 2 "register_operand" ""))
3134 (use (match_operand 3 "memory_operand" ""))
3135 (clobber (scratch))]
3136 "reload_completed"
3137 [(parallel
3138 [(unspec [(match_dup 2) (match_dup 3)
3139 (const_int 0)] UNSPEC_EXECUTE)
3140 (set (match_dup 0) (match_dup 1))
3141 (use (const_int 1))])]
3142 "")
3143
3144 (define_split
3145 [(set (match_operand:BLK 0 "memory_operand" "")
3146 (match_operand:BLK 1 "memory_operand" ""))
3147 (use (match_operand 2 "register_operand" ""))
3148 (use (const:BLK (unspec:BLK [(const_int 0)] UNSPEC_INSN)))
3149 (clobber (scratch))]
3150 "TARGET_Z10 && reload_completed"
3151 [(parallel
3152 [(unspec [(match_dup 2) (const_int 0)
3153 (label_ref (match_dup 3))] UNSPEC_EXECUTE)
3154 (set (match_dup 0) (match_dup 1))
3155 (use (const_int 1))])]
3156 "operands[3] = gen_label_rtx ();")
3157
3158 (define_split
3159 [(set (match_operand:BLK 0 "memory_operand" "")
3160 (match_operand:BLK 1 "memory_operand" ""))
3161 (use (match_operand 2 "register_operand" ""))
3162 (use (const:BLK (unspec:BLK [(const_int 0)] UNSPEC_INSN)))
3163 (clobber (match_operand 3 "register_operand" ""))]
3164 "reload_completed && TARGET_CPU_ZARCH"
3165 [(set (match_dup 3) (label_ref (match_dup 4)))
3166 (parallel
3167 [(unspec [(match_dup 2) (mem:BLK (match_dup 3))
3168 (label_ref (match_dup 4))] UNSPEC_EXECUTE)
3169 (set (match_dup 0) (match_dup 1))
3170 (use (const_int 1))])]
3171 "operands[4] = gen_label_rtx ();")
3172
3173 ; Move a block of arbitrary length.
3174
3175 (define_expand "movmem_long"
3176 [(parallel
3177 [(clobber (match_dup 2))
3178 (clobber (match_dup 3))
3179 (set (match_operand:BLK 0 "memory_operand" "")
3180 (match_operand:BLK 1 "memory_operand" ""))
3181 (use (match_operand 2 "general_operand" ""))
3182 (use (match_dup 3))
3183 (clobber (reg:CC CC_REGNUM))])]
3184 ""
3185 {
3186 machine_mode sreg_mode = TARGET_ZARCH ? DImode : SImode;
3187 machine_mode dreg_mode = TARGET_ZARCH ? TImode : DImode;
3188 rtx reg0 = gen_reg_rtx (dreg_mode);
3189 rtx reg1 = gen_reg_rtx (dreg_mode);
3190 rtx addr0 = gen_lowpart (Pmode, gen_highpart (sreg_mode, reg0));
3191 rtx addr1 = gen_lowpart (Pmode, gen_highpart (sreg_mode, reg1));
3192 rtx len0 = gen_lowpart (Pmode, reg0);
3193 rtx len1 = gen_lowpart (Pmode, reg1);
3194
3195 emit_clobber (reg0);
3196 emit_move_insn (addr0, force_operand (XEXP (operands[0], 0), NULL_RTX));
3197 emit_move_insn (len0, operands[2]);
3198
3199 emit_clobber (reg1);
3200 emit_move_insn (addr1, force_operand (XEXP (operands[1], 0), NULL_RTX));
3201 emit_move_insn (len1, operands[2]);
3202
3203 operands[0] = replace_equiv_address_nv (operands[0], addr0);
3204 operands[1] = replace_equiv_address_nv (operands[1], addr1);
3205 operands[2] = reg0;
3206 operands[3] = reg1;
3207 })
3208
3209 (define_insn "*movmem_long"
3210 [(clobber (match_operand:<DBL> 0 "register_operand" "=d"))
3211 (clobber (match_operand:<DBL> 1 "register_operand" "=d"))
3212 (set (mem:BLK (subreg:P (match_operand:<DBL> 2 "register_operand" "0") 0))
3213 (mem:BLK (subreg:P (match_operand:<DBL> 3 "register_operand" "1") 0)))
3214 (use (match_dup 2))
3215 (use (match_dup 3))
3216 (clobber (reg:CC CC_REGNUM))]
3217 "TARGET_64BIT || !TARGET_ZARCH"
3218 "mvcle\t%0,%1,0\;jo\t.-4"
3219 [(set_attr "length" "8")
3220 (set_attr "type" "vs")])
3221
3222 (define_insn "*movmem_long_31z"
3223 [(clobber (match_operand:TI 0 "register_operand" "=d"))
3224 (clobber (match_operand:TI 1 "register_operand" "=d"))
3225 (set (mem:BLK (subreg:SI (match_operand:TI 2 "register_operand" "0") 4))
3226 (mem:BLK (subreg:SI (match_operand:TI 3 "register_operand" "1") 4)))
3227 (use (match_dup 2))
3228 (use (match_dup 3))
3229 (clobber (reg:CC CC_REGNUM))]
3230 "!TARGET_64BIT && TARGET_ZARCH"
3231 "mvcle\t%0,%1,0\;jo\t.-4"
3232 [(set_attr "length" "8")
3233 (set_attr "type" "vs")])
3234
3235
3236 ;
3237 ; Test data class.
3238 ;
3239
3240 (define_expand "signbit<mode>2"
3241 [(set (reg:CCZ CC_REGNUM)
3242 (unspec:CCZ [(match_operand:FP_ALL 1 "register_operand" "f")
3243 (match_dup 2)]
3244 UNSPEC_TDC_INSN))
3245 (set (match_operand:SI 0 "register_operand" "=d")
3246 (unspec:SI [(reg:CCZ CC_REGNUM)] UNSPEC_CC_TO_INT))]
3247 "TARGET_HARD_FLOAT"
3248 {
3249 operands[2] = GEN_INT (S390_TDC_SIGNBIT_SET);
3250 })
3251
3252 (define_expand "isinf<mode>2"
3253 [(set (reg:CCZ CC_REGNUM)
3254 (unspec:CCZ [(match_operand:FP_ALL 1 "register_operand" "f")
3255 (match_dup 2)]
3256 UNSPEC_TDC_INSN))
3257 (set (match_operand:SI 0 "register_operand" "=d")
3258 (unspec:SI [(reg:CCZ CC_REGNUM)] UNSPEC_CC_TO_INT))]
3259 "TARGET_HARD_FLOAT"
3260 {
3261 operands[2] = GEN_INT (S390_TDC_INFINITY);
3262 })
3263
3264 ; This extracts CC into a GPR properly shifted. The actual IPM
3265 ; instruction will be issued by reload. The constraint of operand 1
3266 ; forces reload to use a GPR. So reload will issue a movcc insn for
3267 ; copying CC into a GPR first.
3268 (define_insn_and_split "*cc_to_int"
3269 [(set (match_operand:SI 0 "nonimmediate_operand" "=d")
3270 (unspec:SI [(match_operand 1 "register_operand" "0")]
3271 UNSPEC_CC_TO_INT))]
3272 "operands != NULL"
3273 "#"
3274 "reload_completed"
3275 [(set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 28)))])
3276
3277 ; This insn is used to generate all variants of the Test Data Class
3278 ; instruction, namely tcxb, tcdb, and tceb. The insn's first operand
3279 ; is the register to be tested and the second one is the bit mask
3280 ; specifying the required test(s).
3281 ;
3282 ; tcxb, tcdb, tceb, tdcxt, tdcdt, tdcet
3283 (define_insn "*TDC_insn_<mode>"
3284 [(set (reg:CCZ CC_REGNUM)
3285 (unspec:CCZ [(match_operand:FP_ALL 0 "register_operand" "f")
3286 (match_operand:SI 1 "const_int_operand")] UNSPEC_TDC_INSN))]
3287 "TARGET_HARD_FLOAT"
3288 "t<_d>c<xde><bt>\t%0,%1"
3289 [(set_attr "op_type" "RXE")
3290 (set_attr "type" "fsimp<mode>")])
3291
3292
3293
3294 ;
3295 ; setmemM instruction pattern(s).
3296 ;
3297
3298 (define_expand "setmem<mode>"
3299 [(set (match_operand:BLK 0 "memory_operand" "")
3300 (match_operand:QI 2 "general_operand" ""))
3301 (use (match_operand:GPR 1 "general_operand" ""))
3302 (match_operand 3 "" "")]
3303 ""
3304 "s390_expand_setmem (operands[0], operands[1], operands[2]); DONE;")
3305
3306 ; Clear a block that is up to 256 bytes in length.
3307 ; The block length is taken as (operands[1] % 256) + 1.
3308
3309 (define_expand "clrmem_short"
3310 [(parallel
3311 [(set (match_operand:BLK 0 "memory_operand" "")
3312 (const_int 0))
3313 (use (match_operand 1 "nonmemory_operand" ""))
3314 (use (const:BLK (unspec:BLK [(const_int 0)] UNSPEC_INSN)))
3315 (clobber (match_dup 2))
3316 (clobber (reg:CC CC_REGNUM))])]
3317 ""
3318 "operands[2] = gen_rtx_SCRATCH (Pmode);")
3319
3320 (define_insn "*clrmem_short"
3321 [(set (match_operand:BLK 0 "memory_operand" "=Q,Q,Q,Q")
3322 (const_int 0))
3323 (use (match_operand 1 "nonmemory_operand" "n,a,a,a"))
3324 (use (match_operand 2 "immediate_operand" "X,R,X,X"))
3325 (clobber (match_scratch:P 3 "=X,X,X,&a"))
3326 (clobber (reg:CC CC_REGNUM))]
3327 "(GET_MODE (operands[1]) == Pmode || GET_MODE (operands[1]) == VOIDmode)"
3328 "#"
3329 [(set_attr "type" "cs")
3330 (set_attr "cpu_facility" "*,*,z10,cpu_zarch")])
3331
3332 (define_split
3333 [(set (match_operand:BLK 0 "memory_operand" "")
3334 (const_int 0))
3335 (use (match_operand 1 "const_int_operand" ""))
3336 (use (match_operand 2 "immediate_operand" ""))
3337 (clobber (scratch))
3338 (clobber (reg:CC CC_REGNUM))]
3339 "reload_completed"
3340 [(parallel
3341 [(set (match_dup 0) (const_int 0))
3342 (use (match_dup 1))
3343 (clobber (reg:CC CC_REGNUM))])]
3344 "operands[1] = GEN_INT ((INTVAL (operands[1]) & 0xff) + 1);")
3345
3346 (define_split
3347 [(set (match_operand:BLK 0 "memory_operand" "")
3348 (const_int 0))
3349 (use (match_operand 1 "register_operand" ""))
3350 (use (match_operand 2 "memory_operand" ""))
3351 (clobber (scratch))
3352 (clobber (reg:CC CC_REGNUM))]
3353 "reload_completed"
3354 [(parallel
3355 [(unspec [(match_dup 1) (match_dup 2)
3356 (const_int 0)] UNSPEC_EXECUTE)
3357 (set (match_dup 0) (const_int 0))
3358 (use (const_int 1))
3359 (clobber (reg:CC CC_REGNUM))])]
3360 "")
3361
3362 (define_split
3363 [(set (match_operand:BLK 0 "memory_operand" "")
3364 (const_int 0))
3365 (use (match_operand 1 "register_operand" ""))
3366 (use (const:BLK (unspec:BLK [(const_int 0)] UNSPEC_INSN)))
3367 (clobber (scratch))
3368 (clobber (reg:CC CC_REGNUM))]
3369 "TARGET_Z10 && reload_completed"
3370 [(parallel
3371 [(unspec [(match_dup 1) (const_int 0)
3372 (label_ref (match_dup 3))] UNSPEC_EXECUTE)
3373 (set (match_dup 0) (const_int 0))
3374 (use (const_int 1))
3375 (clobber (reg:CC CC_REGNUM))])]
3376 "operands[3] = gen_label_rtx ();")
3377
3378 (define_split
3379 [(set (match_operand:BLK 0 "memory_operand" "")
3380 (const_int 0))
3381 (use (match_operand 1 "register_operand" ""))
3382 (use (const:BLK (unspec:BLK [(const_int 0)] UNSPEC_INSN)))
3383 (clobber (match_operand 2 "register_operand" ""))
3384 (clobber (reg:CC CC_REGNUM))]
3385 "reload_completed && TARGET_CPU_ZARCH"
3386 [(set (match_dup 2) (label_ref (match_dup 3)))
3387 (parallel
3388 [(unspec [(match_dup 1) (mem:BLK (match_dup 2))
3389 (label_ref (match_dup 3))] UNSPEC_EXECUTE)
3390 (set (match_dup 0) (const_int 0))
3391 (use (const_int 1))
3392 (clobber (reg:CC CC_REGNUM))])]
3393 "operands[3] = gen_label_rtx ();")
3394
3395 ; Initialize a block of arbitrary length with (operands[2] % 256).
3396
3397 (define_expand "setmem_long_<P:mode>"
3398 [(parallel
3399 [(clobber (match_dup 1))
3400 (set (match_operand:BLK 0 "memory_operand" "")
3401 (unspec:BLK [(match_operand:P 2 "setmem_operand" "")
3402 (match_dup 4)] UNSPEC_REPLICATE_BYTE))
3403 (use (match_dup 3))
3404 (clobber (reg:CC CC_REGNUM))])]
3405 ""
3406 {
3407 machine_mode sreg_mode = TARGET_ZARCH ? DImode : SImode;
3408 machine_mode dreg_mode = TARGET_ZARCH ? TImode : DImode;
3409 rtx reg0 = gen_reg_rtx (dreg_mode);
3410 rtx reg1 = gen_reg_rtx (dreg_mode);
3411 rtx addr0 = gen_lowpart (Pmode, gen_highpart (sreg_mode, reg0));
3412 rtx len0 = gen_lowpart (Pmode, reg0);
3413
3414 emit_clobber (reg0);
3415 emit_move_insn (addr0, force_operand (XEXP (operands[0], 0), NULL_RTX));
3416 emit_move_insn (len0, operands[1]);
3417
3418 emit_move_insn (reg1, const0_rtx);
3419
3420 operands[0] = replace_equiv_address_nv (operands[0], addr0);
3421 operands[1] = reg0;
3422 operands[3] = reg1;
3423 operands[4] = gen_lowpart (Pmode, operands[1]);
3424 })
3425
3426 ; Patterns for 31 bit + Esa and 64 bit + Zarch.
3427
3428 (define_insn "*setmem_long"
3429 [(clobber (match_operand:<DBL> 0 "register_operand" "=d"))
3430 (set (mem:BLK (subreg:P (match_operand:<DBL> 3 "register_operand" "0") 0))
3431 (unspec:BLK [(match_operand:P 2 "setmem_operand" "Y")
3432 (subreg:P (match_dup 3) <modesize>)]
3433 UNSPEC_REPLICATE_BYTE))
3434 (use (match_operand:<DBL> 1 "register_operand" "d"))
3435 (clobber (reg:CC CC_REGNUM))]
3436 "TARGET_64BIT || !TARGET_ZARCH"
3437 "mvcle\t%0,%1,%Y2\;jo\t.-4"
3438 [(set_attr "length" "8")
3439 (set_attr "type" "vs")])
3440
3441 (define_insn "*setmem_long_and"
3442 [(clobber (match_operand:<DBL> 0 "register_operand" "=d"))
3443 (set (mem:BLK (subreg:P (match_operand:<DBL> 3 "register_operand" "0") 0))
3444 (unspec:BLK [(zero_extend:P (match_operand:QI 2 "setmem_operand" "Y"))
3445 (subreg:P (match_dup 3) <modesize>)]
3446 UNSPEC_REPLICATE_BYTE))
3447 (use (match_operand:<DBL> 1 "register_operand" "d"))
3448 (clobber (reg:CC CC_REGNUM))]
3449 "(TARGET_64BIT || !TARGET_ZARCH)"
3450 "mvcle\t%0,%1,%Y2\;jo\t.-4"
3451 [(set_attr "length" "8")
3452 (set_attr "type" "vs")])
3453
3454 ; Variants for 31 bit + Zarch, necessary because of the odd in-register offsets
3455 ; of the SImode subregs.
3456
3457 (define_insn "*setmem_long_31z"
3458 [(clobber (match_operand:TI 0 "register_operand" "=d"))
3459 (set (mem:BLK (subreg:SI (match_operand:TI 3 "register_operand" "0") 4))
3460 (unspec:BLK [(match_operand:SI 2 "setmem_operand" "Y")
3461 (subreg:SI (match_dup 3) 12)] UNSPEC_REPLICATE_BYTE))
3462 (use (match_operand:TI 1 "register_operand" "d"))
3463 (clobber (reg:CC CC_REGNUM))]
3464 "!TARGET_64BIT && TARGET_ZARCH"
3465 "mvcle\t%0,%1,%Y2\;jo\t.-4"
3466 [(set_attr "length" "8")
3467 (set_attr "type" "vs")])
3468
3469 (define_insn "*setmem_long_and_31z"
3470 [(clobber (match_operand:TI 0 "register_operand" "=d"))
3471 (set (mem:BLK (subreg:SI (match_operand:TI 3 "register_operand" "0") 4))
3472 (unspec:BLK [(zero_extend:SI (match_operand:QI 2 "setmem_operand" "Y"))
3473 (subreg:SI (match_dup 3) 12)] UNSPEC_REPLICATE_BYTE))
3474 (use (match_operand:TI 1 "register_operand" "d"))
3475 (clobber (reg:CC CC_REGNUM))]
3476 "(!TARGET_64BIT && TARGET_ZARCH)"
3477 "mvcle\t%0,%1,%Y2\;jo\t.-4"
3478 [(set_attr "length" "8")
3479 (set_attr "type" "vs")])
3480
3481 ;
3482 ; cmpmemM instruction pattern(s).
3483 ;
3484
3485 (define_expand "cmpmemsi"
3486 [(set (match_operand:SI 0 "register_operand" "")
3487 (compare:SI (match_operand:BLK 1 "memory_operand" "")
3488 (match_operand:BLK 2 "memory_operand" "") ) )
3489 (use (match_operand:SI 3 "general_operand" ""))
3490 (use (match_operand:SI 4 "" ""))]
3491 ""
3492 {
3493 if (s390_expand_cmpmem (operands[0], operands[1],
3494 operands[2], operands[3]))
3495 DONE;
3496 else
3497 FAIL;
3498 })
3499
3500 ; Compare a block that is up to 256 bytes in length.
3501 ; The block length is taken as (operands[2] % 256) + 1.
3502
3503 (define_expand "cmpmem_short"
3504 [(parallel
3505 [(set (reg:CCU CC_REGNUM)
3506 (compare:CCU (match_operand:BLK 0 "memory_operand" "")
3507 (match_operand:BLK 1 "memory_operand" "")))
3508 (use (match_operand 2 "nonmemory_operand" ""))
3509 (use (const:BLK (unspec:BLK [(const_int 0)] UNSPEC_INSN)))
3510 (clobber (match_dup 3))])]
3511 ""
3512 "operands[3] = gen_rtx_SCRATCH (Pmode);")
3513
3514 (define_insn "*cmpmem_short"
3515 [(set (reg:CCU CC_REGNUM)
3516 (compare:CCU (match_operand:BLK 0 "memory_operand" "Q,Q,Q,Q")
3517 (match_operand:BLK 1 "memory_operand" "Q,Q,Q,Q")))
3518 (use (match_operand 2 "nonmemory_operand" "n,a,a,a"))
3519 (use (match_operand 3 "immediate_operand" "X,R,X,X"))
3520 (clobber (match_scratch:P 4 "=X,X,X,&a"))]
3521 "(GET_MODE (operands[2]) == Pmode || GET_MODE (operands[2]) == VOIDmode)"
3522 "#"
3523 [(set_attr "type" "cs")
3524 (set_attr "cpu_facility" "*,*,z10,cpu_zarch")])
3525
3526 (define_split
3527 [(set (reg:CCU CC_REGNUM)
3528 (compare:CCU (match_operand:BLK 0 "memory_operand" "")
3529 (match_operand:BLK 1 "memory_operand" "")))
3530 (use (match_operand 2 "const_int_operand" ""))
3531 (use (match_operand 3 "immediate_operand" ""))
3532 (clobber (scratch))]
3533 "reload_completed"
3534 [(parallel
3535 [(set (reg:CCU CC_REGNUM) (compare:CCU (match_dup 0) (match_dup 1)))
3536 (use (match_dup 2))])]
3537 "operands[2] = GEN_INT ((INTVAL (operands[2]) & 0xff) + 1);")
3538
3539 (define_split
3540 [(set (reg:CCU CC_REGNUM)
3541 (compare:CCU (match_operand:BLK 0 "memory_operand" "")
3542 (match_operand:BLK 1 "memory_operand" "")))
3543 (use (match_operand 2 "register_operand" ""))
3544 (use (match_operand 3 "memory_operand" ""))
3545 (clobber (scratch))]
3546 "reload_completed"
3547 [(parallel
3548 [(unspec [(match_dup 2) (match_dup 3)
3549 (const_int 0)] UNSPEC_EXECUTE)
3550 (set (reg:CCU CC_REGNUM) (compare:CCU (match_dup 0) (match_dup 1)))
3551 (use (const_int 1))])]
3552 "")
3553
3554 (define_split
3555 [(set (reg:CCU CC_REGNUM)
3556 (compare:CCU (match_operand:BLK 0 "memory_operand" "")
3557 (match_operand:BLK 1 "memory_operand" "")))
3558 (use (match_operand 2 "register_operand" ""))
3559 (use (const:BLK (unspec:BLK [(const_int 0)] UNSPEC_INSN)))
3560 (clobber (scratch))]
3561 "TARGET_Z10 && reload_completed"
3562 [(parallel
3563 [(unspec [(match_dup 2) (const_int 0)
3564 (label_ref (match_dup 4))] UNSPEC_EXECUTE)
3565 (set (reg:CCU CC_REGNUM) (compare:CCU (match_dup 0) (match_dup 1)))
3566 (use (const_int 1))])]
3567 "operands[4] = gen_label_rtx ();")
3568
3569 (define_split
3570 [(set (reg:CCU CC_REGNUM)
3571 (compare:CCU (match_operand:BLK 0 "memory_operand" "")
3572 (match_operand:BLK 1 "memory_operand" "")))
3573 (use (match_operand 2 "register_operand" ""))
3574 (use (const:BLK (unspec:BLK [(const_int 0)] UNSPEC_INSN)))
3575 (clobber (match_operand 3 "register_operand" ""))]
3576 "reload_completed && TARGET_CPU_ZARCH"
3577 [(set (match_dup 3) (label_ref (match_dup 4)))
3578 (parallel
3579 [(unspec [(match_dup 2) (mem:BLK (match_dup 3))
3580 (label_ref (match_dup 4))] UNSPEC_EXECUTE)
3581 (set (reg:CCU CC_REGNUM) (compare:CCU (match_dup 0) (match_dup 1)))
3582 (use (const_int 1))])]
3583 "operands[4] = gen_label_rtx ();")
3584
3585 ; Compare a block of arbitrary length.
3586
3587 (define_expand "cmpmem_long"
3588 [(parallel
3589 [(clobber (match_dup 2))
3590 (clobber (match_dup 3))
3591 (set (reg:CCU CC_REGNUM)
3592 (compare:CCU (match_operand:BLK 0 "memory_operand" "")
3593 (match_operand:BLK 1 "memory_operand" "")))
3594 (use (match_operand 2 "general_operand" ""))
3595 (use (match_dup 3))])]
3596 ""
3597 {
3598 machine_mode sreg_mode = TARGET_ZARCH ? DImode : SImode;
3599 machine_mode dreg_mode = TARGET_ZARCH ? TImode : DImode;
3600 rtx reg0 = gen_reg_rtx (dreg_mode);
3601 rtx reg1 = gen_reg_rtx (dreg_mode);
3602 rtx addr0 = gen_lowpart (Pmode, gen_highpart (sreg_mode, reg0));
3603 rtx addr1 = gen_lowpart (Pmode, gen_highpart (sreg_mode, reg1));
3604 rtx len0 = gen_lowpart (Pmode, reg0);
3605 rtx len1 = gen_lowpart (Pmode, reg1);
3606
3607 emit_clobber (reg0);
3608 emit_move_insn (addr0, force_operand (XEXP (operands[0], 0), NULL_RTX));
3609 emit_move_insn (len0, operands[2]);
3610
3611 emit_clobber (reg1);
3612 emit_move_insn (addr1, force_operand (XEXP (operands[1], 0), NULL_RTX));
3613 emit_move_insn (len1, operands[2]);
3614
3615 operands[0] = replace_equiv_address_nv (operands[0], addr0);
3616 operands[1] = replace_equiv_address_nv (operands[1], addr1);
3617 operands[2] = reg0;
3618 operands[3] = reg1;
3619 })
3620
3621 (define_insn "*cmpmem_long"
3622 [(clobber (match_operand:<DBL> 0 "register_operand" "=d"))
3623 (clobber (match_operand:<DBL> 1 "register_operand" "=d"))
3624 (set (reg:CCU CC_REGNUM)
3625 (compare:CCU (mem:BLK (subreg:P (match_operand:<DBL> 2 "register_operand" "0") 0))
3626 (mem:BLK (subreg:P (match_operand:<DBL> 3 "register_operand" "1") 0))))
3627 (use (match_dup 2))
3628 (use (match_dup 3))]
3629 "TARGET_64BIT || !TARGET_ZARCH"
3630 "clcle\t%0,%1,0\;jo\t.-4"
3631 [(set_attr "length" "8")
3632 (set_attr "type" "vs")])
3633
3634 (define_insn "*cmpmem_long_31z"
3635 [(clobber (match_operand:TI 0 "register_operand" "=d"))
3636 (clobber (match_operand:TI 1 "register_operand" "=d"))
3637 (set (reg:CCU CC_REGNUM)
3638 (compare:CCU (mem:BLK (subreg:SI (match_operand:TI 2 "register_operand" "0") 4))
3639 (mem:BLK (subreg:SI (match_operand:TI 3 "register_operand" "1") 4))))
3640 (use (match_dup 2))
3641 (use (match_dup 3))]
3642 "!TARGET_64BIT && TARGET_ZARCH"
3643 "clcle\t%0,%1,0\;jo\t.-4"
3644 [(set_attr "op_type" "NN")
3645 (set_attr "type" "vs")
3646 (set_attr "length" "8")])
3647
3648 ; Convert CCUmode condition code to integer.
3649 ; Result is zero if EQ, positive if LTU, negative if GTU.
3650
3651 (define_insn_and_split "cmpint"
3652 [(set (match_operand:SI 0 "register_operand" "=d")
3653 (unspec:SI [(match_operand:CCU 1 "register_operand" "0")]
3654 UNSPEC_STRCMPCC_TO_INT))
3655 (clobber (reg:CC CC_REGNUM))]
3656 ""
3657 "#"
3658 "reload_completed"
3659 [(set (match_dup 0) (ashift:SI (match_dup 0) (const_int 2)))
3660 (parallel
3661 [(set (match_dup 0) (ashiftrt:SI (match_dup 0) (const_int 30)))
3662 (clobber (reg:CC CC_REGNUM))])])
3663
3664 (define_insn_and_split "*cmpint_cc"
3665 [(set (reg CC_REGNUM)
3666 (compare (unspec:SI [(match_operand:CCU 1 "register_operand" "0")]
3667 UNSPEC_STRCMPCC_TO_INT)
3668 (const_int 0)))
3669 (set (match_operand:SI 0 "register_operand" "=d")
3670 (unspec:SI [(match_dup 1)] UNSPEC_STRCMPCC_TO_INT))]
3671 "s390_match_ccmode (insn, CCSmode)"
3672 "#"
3673 "&& reload_completed"
3674 [(set (match_dup 0) (ashift:SI (match_dup 0) (const_int 2)))
3675 (parallel
3676 [(set (match_dup 2) (match_dup 3))
3677 (set (match_dup 0) (ashiftrt:SI (match_dup 0) (const_int 30)))])]
3678 {
3679 rtx result = gen_rtx_ASHIFTRT (SImode, operands[0], GEN_INT (30));
3680 operands[2] = SET_DEST (XVECEXP (PATTERN (curr_insn), 0, 0));
3681 operands[3] = gen_rtx_COMPARE (GET_MODE (operands[2]), result, const0_rtx);
3682 })
3683
3684 (define_insn_and_split "*cmpint_sign"
3685 [(set (match_operand:DI 0 "register_operand" "=d")
3686 (sign_extend:DI (unspec:SI [(match_operand:CCU 1 "register_operand" "0")]
3687 UNSPEC_STRCMPCC_TO_INT)))
3688 (clobber (reg:CC CC_REGNUM))]
3689 "TARGET_ZARCH"
3690 "#"
3691 "&& reload_completed"
3692 [(set (match_dup 0) (ashift:DI (match_dup 0) (const_int 34)))
3693 (parallel
3694 [(set (match_dup 0) (ashiftrt:DI (match_dup 0) (const_int 62)))
3695 (clobber (reg:CC CC_REGNUM))])])
3696
3697 (define_insn_and_split "*cmpint_sign_cc"
3698 [(set (reg CC_REGNUM)
3699 (compare (ashiftrt:DI (ashift:DI (subreg:DI
3700 (unspec:SI [(match_operand:CCU 1 "register_operand" "0")]
3701 UNSPEC_STRCMPCC_TO_INT) 0)
3702 (const_int 32)) (const_int 32))
3703 (const_int 0)))
3704 (set (match_operand:DI 0 "register_operand" "=d")
3705 (sign_extend:DI (unspec:SI [(match_dup 1)] UNSPEC_STRCMPCC_TO_INT)))]
3706 "s390_match_ccmode (insn, CCSmode) && TARGET_ZARCH"
3707 "#"
3708 "&& reload_completed"
3709 [(set (match_dup 0) (ashift:DI (match_dup 0) (const_int 34)))
3710 (parallel
3711 [(set (match_dup 2) (match_dup 3))
3712 (set (match_dup 0) (ashiftrt:DI (match_dup 0) (const_int 62)))])]
3713 {
3714 rtx result = gen_rtx_ASHIFTRT (DImode, operands[0], GEN_INT (62));
3715 operands[2] = SET_DEST (XVECEXP (PATTERN (curr_insn), 0, 0));
3716 operands[3] = gen_rtx_COMPARE (GET_MODE (operands[2]), result, const0_rtx);
3717 })
3718
3719
3720 ;;
3721 ;;- Conversion instructions.
3722 ;;
3723
3724 (define_insn "*sethighpartsi"
3725 [(set (match_operand:SI 0 "register_operand" "=d,d")
3726 (unspec:SI [(match_operand:BLK 1 "s_operand" "Q,S")
3727 (match_operand 2 "const_int_operand" "n,n")] UNSPEC_ICM))
3728 (clobber (reg:CC CC_REGNUM))]
3729 ""
3730 "@
3731 icm\t%0,%2,%S1
3732 icmy\t%0,%2,%S1"
3733 [(set_attr "op_type" "RS,RSY")
3734 (set_attr "cpu_facility" "*,longdisp")
3735 (set_attr "z10prop" "z10_super_E1,z10_super_E1")])
3736
3737 (define_insn "*sethighpartdi_64"
3738 [(set (match_operand:DI 0 "register_operand" "=d")
3739 (unspec:DI [(match_operand:BLK 1 "s_operand" "S")
3740 (match_operand 2 "const_int_operand" "n")] UNSPEC_ICM))
3741 (clobber (reg:CC CC_REGNUM))]
3742 "TARGET_ZARCH"
3743 "icmh\t%0,%2,%S1"
3744 [(set_attr "op_type" "RSY")
3745 (set_attr "z10prop" "z10_super")])
3746
3747 (define_insn "*sethighpartdi_31"
3748 [(set (match_operand:DI 0 "register_operand" "=d,d")
3749 (unspec:DI [(match_operand:BLK 1 "s_operand" "Q,S")
3750 (match_operand 2 "const_int_operand" "n,n")] UNSPEC_ICM))
3751 (clobber (reg:CC CC_REGNUM))]
3752 "!TARGET_ZARCH"
3753 "@
3754 icm\t%0,%2,%S1
3755 icmy\t%0,%2,%S1"
3756 [(set_attr "op_type" "RS,RSY")
3757 (set_attr "cpu_facility" "*,longdisp")
3758 (set_attr "z10prop" "z10_super_E1,z10_super_E1")])
3759
3760 ;
3761 ; extv instruction patterns
3762 ;
3763
3764 ; FIXME: This expander needs to be converted from DI to GPR as well
3765 ; after resolving some issues with it.
3766
3767 (define_expand "extzv"
3768 [(parallel
3769 [(set (match_operand:DI 0 "register_operand" "=d")
3770 (zero_extract:DI
3771 (match_operand:DI 1 "register_operand" "d")
3772 (match_operand 2 "const_int_operand" "") ; size
3773 (match_operand 3 "const_int_operand" ""))) ; start
3774 (clobber (reg:CC CC_REGNUM))])]
3775 "TARGET_Z10"
3776 {
3777 if (! EXTRACT_ARGS_IN_RANGE (INTVAL (operands[2]), INTVAL (operands[3]), 64))
3778 FAIL;
3779 /* Starting with zEC12 there is risbgn not clobbering CC. */
3780 if (TARGET_ZEC12)
3781 {
3782 emit_move_insn (operands[0],
3783 gen_rtx_ZERO_EXTRACT (DImode,
3784 operands[1],
3785 operands[2],
3786 operands[3]));
3787 DONE;
3788 }
3789 })
3790
3791 (define_insn "*extzv<mode><clobbercc_or_nocc>"
3792 [(set (match_operand:GPR 0 "register_operand" "=d")
3793 (zero_extract:GPR
3794 (match_operand:GPR 1 "register_operand" "d")
3795 (match_operand 2 "const_int_operand" "") ; size
3796 (match_operand 3 "const_int_operand" ""))) ; start
3797 ]
3798 "<z10_or_zEC12_cond>
3799 && EXTRACT_ARGS_IN_RANGE (INTVAL (operands[2]), INTVAL (operands[3]),
3800 GET_MODE_BITSIZE (<MODE>mode))"
3801 "<risbg_n>\t%0,%1,64-%2,128+63,<bitoff_plus>%3+%2" ; dst, src, start, end, shift
3802 [(set_attr "op_type" "RIE")
3803 (set_attr "z10prop" "z10_super_E1")])
3804
3805 ; 64 bit: (a & -16) | ((b >> 8) & 15)
3806 (define_insn "*extzvdi<clobbercc_or_nocc>_lshiftrt"
3807 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+d")
3808 (match_operand 1 "const_int_operand" "") ; size
3809 (match_operand 2 "const_int_operand" "")) ; start
3810 (lshiftrt:DI (match_operand:DI 3 "register_operand" "d")
3811 (match_operand:DI 4 "nonzero_shift_count_operand" "")))]
3812 "<z10_or_zEC12_cond>
3813 && EXTRACT_ARGS_IN_RANGE (INTVAL (operands[1]), INTVAL (operands[2]), 64)
3814 && 64 - UINTVAL (operands[4]) >= UINTVAL (operands[1])"
3815 "<risbg_n>\t%0,%3,%2,%2+%1-1,128-%2-%1-%4"
3816 [(set_attr "op_type" "RIE")
3817 (set_attr "z10prop" "z10_super_E1")])
3818
3819 ; 32 bit: (a & -16) | ((b >> 8) & 15)
3820 (define_insn "*<risbg_n>_ior_and_sr_ze"
3821 [(set (match_operand:SI 0 "register_operand" "=d")
3822 (ior:SI (and:SI
3823 (match_operand:SI 1 "register_operand" "0")
3824 (match_operand:SI 2 "const_int_operand" ""))
3825 (subreg:SI
3826 (zero_extract:DI
3827 (match_operand:DI 3 "register_operand" "d")
3828 (match_operand 4 "const_int_operand" "") ; size
3829 (match_operand 5 "const_int_operand" "")) ; start
3830 4)))]
3831 "<z10_or_zEC12_cond>
3832 && EXTRACT_ARGS_IN_RANGE (INTVAL (operands[4]), INTVAL (operands[5]), 64)
3833 && UINTVAL (operands[2]) == (~(0ULL) << UINTVAL (operands[4]))"
3834 "<risbg_n>\t%0,%3,64-%4,63,%4+%5"
3835 [(set_attr "op_type" "RIE")
3836 (set_attr "z10prop" "z10_super_E1")])
3837
3838 ; ((int)foo >> 10) & 1;
3839 (define_insn "*extract1bitdi<clobbercc_or_nocc>"
3840 [(set (match_operand:DI 0 "register_operand" "=d")
3841 (ne:DI (zero_extract:DI
3842 (match_operand:DI 1 "register_operand" "d")
3843 (const_int 1) ; size
3844 (match_operand 2 "const_int_operand" "")) ; start
3845 (const_int 0)))]
3846 "<z10_or_zEC12_cond>
3847 && EXTRACT_ARGS_IN_RANGE (1, INTVAL (operands[2]), 64)"
3848 "<risbg_n>\t%0,%1,64-1,128+63,%2+1" ; dst, src, start, end, shift
3849 [(set_attr "op_type" "RIE")
3850 (set_attr "z10prop" "z10_super_E1")])
3851
3852 (define_insn "*<risbg_n>_and_subregdi_rotr"
3853 [(set (match_operand:DI 0 "register_operand" "=d")
3854 (and:DI (subreg:DI
3855 (rotate:SINT (match_operand:SINT 1 "register_operand" "d")
3856 (match_operand:SINT 2 "const_int_operand" "")) 0)
3857 (match_operand:DI 3 "contiguous_bitmask_operand" "")))]
3858 "<z10_or_zEC12_cond>
3859 && UINTVAL (operands[3]) < (1ULL << (UINTVAL (operands[2]) & 0x3f))"
3860 "<risbg_n>\t%0,%1,%s3,128+%e3,<bitoff_plus>%2" ; dst, src, start, end, shift
3861 [(set_attr "op_type" "RIE")
3862 (set_attr "z10prop" "z10_super_E1")])
3863
3864 (define_insn "*<risbg_n>_and_subregdi_rotl"
3865 [(set (match_operand:DI 0 "register_operand" "=d")
3866 (and:DI (subreg:DI
3867 (rotate:SINT (match_operand:SINT 1 "register_operand" "d")
3868 (match_operand:SINT 2 "const_int_operand" "")) 0)
3869 (match_operand:DI 3 "contiguous_bitmask_operand" "")))]
3870 "<z10_or_zEC12_cond>
3871 && !(UINTVAL (operands[3]) & ((1ULL << (UINTVAL (operands[2]) & 0x3f)) - 1))"
3872 "<risbg_n>\t%0,%1,%s3,128+%e3,%2" ; dst, src, start, end, shift
3873 [(set_attr "op_type" "RIE")
3874 (set_attr "z10prop" "z10_super_E1")])
3875
3876 (define_insn "*<risbg_n>_di_and_rot"
3877 [(set (match_operand:DI 0 "register_operand" "=d")
3878 (and:DI (rotate:DI (match_operand:DI 1 "register_operand" "d")
3879 (match_operand:DI 2 "const_int_operand" ""))
3880 (match_operand:DI 3 "contiguous_bitmask_operand" "")))]
3881 "<z10_or_zEC12_cond>"
3882 "<risbg_n>\t%0,%1,%s3,128+%e3,%2" ; dst, src, start, end, shift
3883 [(set_attr "op_type" "RIE")
3884 (set_attr "z10prop" "z10_super_E1")])
3885
3886 (define_insn_and_split "*pre_z10_extzv<mode>"
3887 [(set (match_operand:GPR 0 "register_operand" "=d")
3888 (zero_extract:GPR (match_operand:QI 1 "s_operand" "S")
3889 (match_operand 2 "nonzero_shift_count_operand" "")
3890 (const_int 0)))
3891 (clobber (reg:CC CC_REGNUM))]
3892 "!TARGET_Z10"
3893 "#"
3894 "&& reload_completed"
3895 [(parallel
3896 [(set (match_dup 0) (unspec:GPR [(match_dup 1) (match_dup 3)] UNSPEC_ICM))
3897 (clobber (reg:CC CC_REGNUM))])
3898 (set (match_dup 0) (lshiftrt:GPR (match_dup 0) (match_dup 2)))]
3899 {
3900 int bitsize = INTVAL (operands[2]);
3901 int size = (bitsize - 1) / BITS_PER_UNIT + 1; /* round up */
3902 int mask = ((1ul << size) - 1) << (GET_MODE_SIZE (SImode) - size);
3903
3904 operands[1] = adjust_address (operands[1], BLKmode, 0);
3905 set_mem_size (operands[1], size);
3906 operands[2] = GEN_INT (<GPR:bitsize> - bitsize);
3907 operands[3] = GEN_INT (mask);
3908 })
3909
3910 (define_insn_and_split "*pre_z10_extv<mode>"
3911 [(set (match_operand:GPR 0 "register_operand" "=d")
3912 (sign_extract:GPR (match_operand:QI 1 "s_operand" "S")
3913 (match_operand 2 "nonzero_shift_count_operand" "")
3914 (const_int 0)))
3915 (clobber (reg:CC CC_REGNUM))]
3916 ""
3917 "#"
3918 "&& reload_completed"
3919 [(parallel
3920 [(set (match_dup 0) (unspec:GPR [(match_dup 1) (match_dup 3)] UNSPEC_ICM))
3921 (clobber (reg:CC CC_REGNUM))])
3922 (parallel
3923 [(set (match_dup 0) (ashiftrt:GPR (match_dup 0) (match_dup 2)))
3924 (clobber (reg:CC CC_REGNUM))])]
3925 {
3926 int bitsize = INTVAL (operands[2]);
3927 int size = (bitsize - 1) / BITS_PER_UNIT + 1; /* round up */
3928 int mask = ((1ul << size) - 1) << (GET_MODE_SIZE (SImode) - size);
3929
3930 operands[1] = adjust_address (operands[1], BLKmode, 0);
3931 set_mem_size (operands[1], size);
3932 operands[2] = GEN_INT (<GPR:bitsize> - bitsize);
3933 operands[3] = GEN_INT (mask);
3934 })
3935
3936 ;
3937 ; insv instruction patterns
3938 ;
3939
3940 (define_expand "insv"
3941 [(set (zero_extract (match_operand 0 "nonimmediate_operand" "")
3942 (match_operand 1 "const_int_operand" "")
3943 (match_operand 2 "const_int_operand" ""))
3944 (match_operand 3 "general_operand" ""))]
3945 ""
3946 {
3947 if (s390_expand_insv (operands[0], operands[1], operands[2], operands[3]))
3948 DONE;
3949 FAIL;
3950 })
3951
3952
3953 ; The normal RTL expansion will never generate a zero_extract where
3954 ; the location operand isn't word mode. However, we do this in the
3955 ; back-end when generating atomic operations. See s390_two_part_insv.
3956 (define_insn "*insv<mode><clobbercc_or_nocc>"
3957 [(set (zero_extract:GPR (match_operand:GPR 0 "nonimmediate_operand" "+d")
3958 (match_operand 1 "const_int_operand" "I") ; size
3959 (match_operand 2 "const_int_operand" "I")) ; pos
3960 (match_operand:GPR 3 "nonimmediate_operand" "d"))]
3961 "<z10_or_zEC12_cond>
3962 && EXTRACT_ARGS_IN_RANGE (INTVAL (operands[1]), INTVAL (operands[2]),
3963 GET_MODE_BITSIZE (<MODE>mode))
3964 && (INTVAL (operands[1]) + INTVAL (operands[2])) <= <bitsize>"
3965 "<risbg_n>\t%0,%3,<bitoff_plus>%2,<bitoff_plus>%2+%1-1,<bitsize>-%2-%1"
3966 [(set_attr "op_type" "RIE")
3967 (set_attr "z10prop" "z10_super_E1")])
3968
3969 ; and op1 with a mask being 1 for the selected bits and 0 for the rest
3970 ; and op3=op0 with a mask being 0 for the selected bits and 1 for the rest
3971 (define_insn "*insv<mode><clobbercc_or_nocc>_noshift"
3972 [(set (match_operand:GPR 0 "nonimmediate_operand" "=d,d")
3973 (ior:GPR (and:GPR (match_operand:GPR 1 "nonimmediate_operand" "d,0")
3974 (match_operand:GPR 2 "contiguous_bitmask_operand" ""))
3975 (and:GPR (match_operand:GPR 3 "nonimmediate_operand" "0,d")
3976 (match_operand:GPR 4 "const_int_operand" ""))))]
3977 "<z10_or_zEC12_cond> && INTVAL (operands[2]) == ~INTVAL (operands[4])"
3978 "@
3979 <risbg_n>\t%0,%1,%<bfstart>2,%<bfend>2,0
3980 <risbg_n>\t%0,%3,%<bfstart>4,%<bfend>4,0"
3981 [(set_attr "op_type" "RIE")
3982 (set_attr "z10prop" "z10_super_E1")])
3983
3984 (define_insn "*insv_z10_noshift_cc"
3985 [(set (reg CC_REGNUM)
3986 (compare
3987 (ior:DI
3988 (and:DI (match_operand:DI 1 "nonimmediate_operand" "d,0")
3989 (match_operand:DI 2 "contiguous_bitmask_operand" ""))
3990 (and:DI (match_operand:DI 3 "nonimmediate_operand" "0,d")
3991 (match_operand:DI 4 "const_int_operand" "")))
3992 (const_int 0)))
3993 (set (match_operand:DI 0 "nonimmediate_operand" "=d,d")
3994 (ior:DI (and:DI (match_dup 1) (match_dup 2))
3995 (and:DI (match_dup 3) (match_dup 4))))]
3996 "TARGET_Z10 && s390_match_ccmode (insn, CCSmode)
3997 && INTVAL (operands[2]) == ~INTVAL (operands[4])"
3998 "@
3999 risbg\t%0,%1,%s2,%e2,0
4000 risbg\t%0,%3,%s4,%e4,0"
4001 [(set_attr "op_type" "RIE")
4002 (set_attr "z10prop" "z10_super_E1")])
4003
4004 (define_insn "*insv_z10_noshift_cconly"
4005 [(set
4006 (reg CC_REGNUM)
4007 (compare
4008 (ior:DI
4009 (and:DI (match_operand:DI 1 "nonimmediate_operand" "d,0")
4010 (match_operand:DI 2 "contiguous_bitmask_operand" ""))
4011 (and:DI (match_operand:DI 3 "nonimmediate_operand" "0,d")
4012 (match_operand:DI 4 "const_int_operand" "")))
4013 (const_int 0)))
4014 (clobber (match_scratch:DI 0 "=d,d"))]
4015 "TARGET_Z10 && s390_match_ccmode (insn, CCSmode)
4016 && INTVAL (operands[2]) == ~INTVAL (operands[4])"
4017 "@
4018 risbg\t%0,%1,%s2,%e2,0
4019 risbg\t%0,%3,%s4,%e4,0"
4020 [(set_attr "op_type" "RIE")
4021 (set_attr "z10prop" "z10_super_E1")])
4022
4023 ; Implement appending Y on the left of S bits of X
4024 ; x = (y << s) | (x & ((1 << s) - 1))
4025 (define_insn "*insv<mode><clobbercc_or_nocc>_appendbitsleft"
4026 [(set (match_operand:GPR 0 "nonimmediate_operand" "=d")
4027 (ior:GPR (and:GPR (match_operand:GPR 1 "nonimmediate_operand" "0")
4028 (match_operand:GPR 2 "immediate_operand" ""))
4029 (ashift:GPR (match_operand:GPR 3 "nonimmediate_operand" "d")
4030 (match_operand:GPR 4 "nonzero_shift_count_operand" ""))))]
4031 "<z10_or_zEC12_cond>
4032 && UINTVAL (operands[2]) == (1UL << UINTVAL (operands[4])) - 1"
4033 "<risbg_n>\t%0,%3,<bitoff>,64-%4-1,%4"
4034 [(set_attr "op_type" "RIE")
4035 (set_attr "z10prop" "z10_super_E1")])
4036
4037 ; a = ((i32)a & -16777216) | (((ui32)b) >> 8)
4038 (define_insn "*<risbg_n>_<mode>_ior_and_lshiftrt"
4039 [(set (match_operand:GPR 0 "register_operand" "=d")
4040 (ior:GPR (and:GPR
4041 (match_operand:GPR 1 "register_operand" "0")
4042 (match_operand:GPR 2 "const_int_operand" ""))
4043 (lshiftrt:GPR
4044 (match_operand:GPR 3 "register_operand" "d")
4045 (match_operand:GPR 4 "nonzero_shift_count_operand" ""))))]
4046 "<z10_or_zEC12_cond> && UINTVAL (operands[2])
4047 == (~(0ULL) << (GET_MODE_BITSIZE (<MODE>mode) - UINTVAL (operands[4])))"
4048 "<risbg_n>\t%0,%3,<bitoff_plus>%4,63,64-%4"
4049 [(set_attr "op_type" "RIE")
4050 (set_attr "z10prop" "z10_super_E1")])
4051
4052 ; (ui32)(((ui64)x) >> 48) | ((i32)y & -65536);
4053 (define_insn "*<risbg_n>_sidi_ior_and_lshiftrt"
4054 [(set (match_operand:SI 0 "register_operand" "=d")
4055 (ior:SI (and:SI
4056 (match_operand:SI 1 "register_operand" "0")
4057 (match_operand:SI 2 "const_int_operand" ""))
4058 (subreg:SI
4059 (lshiftrt:DI
4060 (match_operand:DI 3 "register_operand" "d")
4061 (match_operand:DI 4 "nonzero_shift_count_operand" "")) 4)))]
4062 "<z10_or_zEC12_cond>
4063 && UINTVAL (operands[2]) == ~(~(0ULL) >> UINTVAL (operands[4]))"
4064 "<risbg_n>\t%0,%3,%4,63,64-%4"
4065 [(set_attr "op_type" "RIE")
4066 (set_attr "z10prop" "z10_super_E1")])
4067
4068 ; (ui32)(((ui64)x) >> 12) & -4
4069 (define_insn "*trunc_sidi_and_subreg_lshrt<clobbercc_or_nocc>"
4070 [(set (match_operand:SI 0 "register_operand" "=d")
4071 (and:SI
4072 (subreg:SI (lshiftrt:DI
4073 (match_operand:DI 1 "register_operand" "d")
4074 (match_operand:DI 2 "nonzero_shift_count_operand" "")) 4)
4075 (match_operand:SI 3 "contiguous_bitmask_nowrap_operand" "")))]
4076 "<z10_or_zEC12_cond>"
4077 "<risbg_n>\t%0,%1,%t3,128+%f3,64-%2"
4078 [(set_attr "op_type" "RIE")
4079 (set_attr "z10prop" "z10_super_E1")])
4080
4081 ; z = (x << c) | (y >> d) with (x << c) and (y >> d) not overlapping after shifting
4082 ; -> z = y >> d; z = (x << c) | (z & ((1 << c) - 1))
4083 ; -> z = y >> d; z = risbg;
4084
4085 (define_split
4086 [(set (match_operand:GPR 0 "nonimmediate_operand" "")
4087 (ior:GPR (lshiftrt:GPR (match_operand:GPR 1 "nonimmediate_operand" "")
4088 (match_operand:GPR 2 "nonzero_shift_count_operand" ""))
4089 (ashift:GPR (match_operand:GPR 3 "nonimmediate_operand" "")
4090 (match_operand:GPR 4 "nonzero_shift_count_operand" ""))))]
4091 "TARGET_ZEC12 && UINTVAL (operands[2]) + UINTVAL (operands[4]) >= <bitsize>"
4092 [(set (match_dup 6)
4093 (lshiftrt:GPR (match_dup 1) (match_dup 2)))
4094 (set (match_dup 0)
4095 (ior:GPR (and:GPR (match_dup 6) (match_dup 5))
4096 (ashift:GPR (match_dup 3) (match_dup 4))))]
4097 {
4098 operands[5] = GEN_INT ((1UL << UINTVAL (operands[4])) - 1);
4099 if (reg_overlap_mentioned_p (operands[0], operands[3]))
4100 {
4101 if (!can_create_pseudo_p ())
4102 FAIL;
4103 operands[6] = gen_reg_rtx (<MODE>mode);
4104 }
4105 else
4106 operands[6] = operands[0];
4107 })
4108
4109 (define_split
4110 [(parallel
4111 [(set (match_operand:GPR 0 "nonimmediate_operand" "")
4112 (ior:GPR (lshiftrt:GPR (match_operand:GPR 1 "nonimmediate_operand" "")
4113 (match_operand:GPR 2 "nonzero_shift_count_operand" ""))
4114 (ashift:GPR (match_operand:GPR 3 "nonimmediate_operand" "")
4115 (match_operand:GPR 4 "nonzero_shift_count_operand" ""))))
4116 (clobber (reg:CC CC_REGNUM))])]
4117 "TARGET_Z10 && !TARGET_ZEC12 && UINTVAL (operands[2]) + UINTVAL (operands[4]) >= <bitsize>"
4118 [(set (match_dup 6)
4119 (lshiftrt:GPR (match_dup 1) (match_dup 2)))
4120 (parallel
4121 [(set (match_dup 0)
4122 (ior:GPR (and:GPR (match_dup 6) (match_dup 5))
4123 (ashift:GPR (match_dup 3) (match_dup 4))))
4124 (clobber (reg:CC CC_REGNUM))])]
4125 {
4126 operands[5] = GEN_INT ((1UL << UINTVAL (operands[4])) - 1);
4127 if (reg_overlap_mentioned_p (operands[0], operands[3]))
4128 {
4129 if (!can_create_pseudo_p ())
4130 FAIL;
4131 operands[6] = gen_reg_rtx (<MODE>mode);
4132 }
4133 else
4134 operands[6] = operands[0];
4135 })
4136
4137 ; rosbg, rxsbg
4138 (define_insn "*r<noxa>sbg_<mode>_noshift"
4139 [(set (match_operand:GPR 0 "nonimmediate_operand" "=d")
4140 (IXOR:GPR
4141 (and:GPR (match_operand:GPR 1 "nonimmediate_operand" "d")
4142 (match_operand:GPR 2 "contiguous_bitmask_operand" ""))
4143 (match_operand:GPR 3 "nonimmediate_operand" "0")))
4144 (clobber (reg:CC CC_REGNUM))]
4145 "TARGET_Z10"
4146 "r<noxa>sbg\t%0,%1,%<bfstart>2,%<bfend>2,0"
4147 [(set_attr "op_type" "RIE")])
4148
4149 ; rosbg, rxsbg
4150 (define_insn "*r<noxa>sbg_di_rotl"
4151 [(set (match_operand:DI 0 "nonimmediate_operand" "=d")
4152 (IXOR:DI
4153 (and:DI
4154 (rotate:DI
4155 (match_operand:DI 1 "nonimmediate_operand" "d")
4156 (match_operand:DI 3 "const_int_operand" ""))
4157 (match_operand:DI 2 "contiguous_bitmask_operand" ""))
4158 (match_operand:DI 4 "nonimmediate_operand" "0")))
4159 (clobber (reg:CC CC_REGNUM))]
4160 "TARGET_Z10"
4161 "r<noxa>sbg\t%0,%1,%<bfstart>2,%<bfend>2,%b3"
4162 [(set_attr "op_type" "RIE")])
4163
4164 ; rosbg, rxsbg
4165 (define_insn "*r<noxa>sbg_<mode>_srl_bitmask"
4166 [(set (match_operand:GPR 0 "nonimmediate_operand" "=d")
4167 (IXOR:GPR
4168 (and:GPR
4169 (lshiftrt:GPR
4170 (match_operand:GPR 1 "nonimmediate_operand" "d")
4171 (match_operand:GPR 3 "nonzero_shift_count_operand" ""))
4172 (match_operand:GPR 2 "contiguous_bitmask_nowrap_operand" ""))
4173 (match_operand:GPR 4 "nonimmediate_operand" "0")))
4174 (clobber (reg:CC CC_REGNUM))]
4175 "TARGET_Z10
4176 && s390_extzv_shift_ok (<bitsize>, 64 - INTVAL (operands[3]),
4177 INTVAL (operands[2]))"
4178 "r<noxa>sbg\t%0,%1,%<bfstart>2,%<bfend>2,64-%3"
4179 [(set_attr "op_type" "RIE")])
4180
4181 ; rosbg, rxsbg
4182 (define_insn "*r<noxa>sbg_<mode>_sll_bitmask"
4183 [(set (match_operand:GPR 0 "nonimmediate_operand" "=d")
4184 (IXOR:GPR
4185 (and:GPR
4186 (ashift:GPR
4187 (match_operand:GPR 1 "nonimmediate_operand" "d")
4188 (match_operand:GPR 3 "nonzero_shift_count_operand" ""))
4189 (match_operand:GPR 2 "contiguous_bitmask_nowrap_operand" ""))
4190 (match_operand:GPR 4 "nonimmediate_operand" "0")))
4191 (clobber (reg:CC CC_REGNUM))]
4192 "TARGET_Z10
4193 && s390_extzv_shift_ok (<bitsize>, INTVAL (operands[3]),
4194 INTVAL (operands[2]))"
4195 "r<noxa>sbg\t%0,%1,%<bfstart>2,%<bfend>2,%3"
4196 [(set_attr "op_type" "RIE")])
4197
4198 ;; unsigned {int,long} a, b
4199 ;; a = a | (b << const_int)
4200 ;; a = a ^ (b << const_int)
4201 ; rosbg, rxsbg
4202 (define_insn "*r<noxa>sbg_<mode>_sll"
4203 [(set (match_operand:GPR 0 "nonimmediate_operand" "=d")
4204 (IXOR:GPR
4205 (ashift:GPR
4206 (match_operand:GPR 1 "nonimmediate_operand" "d")
4207 (match_operand:GPR 2 "nonzero_shift_count_operand" ""))
4208 (match_operand:GPR 3 "nonimmediate_operand" "0")))
4209 (clobber (reg:CC CC_REGNUM))]
4210 "TARGET_Z10"
4211 "r<noxa>sbg\t%0,%1,<bitoff>,63-%2,%2"
4212 [(set_attr "op_type" "RIE")])
4213
4214 ;; unsigned {int,long} a, b
4215 ;; a = a | (b >> const_int)
4216 ;; a = a ^ (b >> const_int)
4217 ; rosbg, rxsbg
4218 (define_insn "*r<noxa>sbg_<mode>_srl"
4219 [(set (match_operand:GPR 0 "nonimmediate_operand" "=d")
4220 (IXOR:GPR
4221 (lshiftrt:GPR
4222 (match_operand:GPR 1 "nonimmediate_operand" "d")
4223 (match_operand:GPR 2 "nonzero_shift_count_operand" ""))
4224 (match_operand:GPR 3 "nonimmediate_operand" "0")))
4225 (clobber (reg:CC CC_REGNUM))]
4226 "TARGET_Z10"
4227 "r<noxa>sbg\t%0,%1,<bitoff_plus>%2,63,64-%2"
4228 [(set_attr "op_type" "RIE")])
4229
4230 ;; These two are generated by combine for s.bf &= val.
4231 ;; ??? For bitfields smaller than 32-bits, we wind up with SImode
4232 ;; shifts and ands, which results in some truly awful patterns
4233 ;; including subregs of operations. Rather unnecessisarily, IMO.
4234 ;; Instead of
4235 ;;
4236 ;; (set (zero_extract:DI (reg/v:DI 50 [ s ])
4237 ;; (const_int 24 [0x18])
4238 ;; (const_int 0 [0]))
4239 ;; (subreg:DI (and:SI (subreg:SI (lshiftrt:DI (reg/v:DI 50 [ s ])
4240 ;; (const_int 40 [0x28])) 4)
4241 ;; (reg:SI 4 %r4 [ y+4 ])) 0))
4242 ;;
4243 ;; we should instead generate
4244 ;;
4245 ;; (set (zero_extract:DI (reg/v:DI 50 [ s ])
4246 ;; (const_int 24 [0x18])
4247 ;; (const_int 0 [0]))
4248 ;; (and:DI (lshiftrt:DI (reg/v:DI 50 [ s ])
4249 ;; (const_int 40 [0x28]))
4250 ;; (subreg:DI (reg:SI 4 %r4 [ y+4 ]) 0)))
4251 ;;
4252 ;; by noticing that we can push down the outer paradoxical subreg
4253 ;; into the operation.
4254
4255 (define_insn "*insv_rnsbg_noshift"
4256 [(set (zero_extract:DI
4257 (match_operand:DI 0 "nonimmediate_operand" "+d")
4258 (match_operand 1 "const_int_operand" "")
4259 (match_operand 2 "const_int_operand" ""))
4260 (and:DI
4261 (match_dup 0)
4262 (match_operand:DI 3 "nonimmediate_operand" "d")))
4263 (clobber (reg:CC CC_REGNUM))]
4264 "TARGET_Z10
4265 && EXTRACT_ARGS_IN_RANGE (INTVAL (operands[1]), INTVAL (operands[2]), 64)
4266 && INTVAL (operands[1]) + INTVAL (operands[2]) == 64"
4267 "rnsbg\t%0,%3,%2,63,0"
4268 [(set_attr "op_type" "RIE")])
4269
4270 (define_insn "*insv_rnsbg_srl"
4271 [(set (zero_extract:DI
4272 (match_operand:DI 0 "nonimmediate_operand" "+d")
4273 (match_operand 1 "const_int_operand" "")
4274 (match_operand 2 "const_int_operand" ""))
4275 (and:DI
4276 (lshiftrt:DI
4277 (match_dup 0)
4278 (match_operand 3 "const_int_operand" ""))
4279 (match_operand:DI 4 "nonimmediate_operand" "d")))
4280 (clobber (reg:CC CC_REGNUM))]
4281 "TARGET_Z10
4282 && EXTRACT_ARGS_IN_RANGE (INTVAL (operands[1]), INTVAL (operands[2]), 64)
4283 && INTVAL (operands[3]) == 64 - INTVAL (operands[1]) - INTVAL (operands[2])"
4284 "rnsbg\t%0,%4,%2,%2+%1-1,%3"
4285 [(set_attr "op_type" "RIE")])
4286
4287 (define_insn "*insv<mode>_mem_reg"
4288 [(set (zero_extract:W (match_operand:QI 0 "memory_operand" "+Q,S")
4289 (match_operand 1 "const_int_operand" "n,n")
4290 (const_int 0))
4291 (match_operand:W 2 "register_operand" "d,d"))]
4292 "EXTRACT_ARGS_IN_RANGE (INTVAL (operands[1]), 0, 64)
4293 && INTVAL (operands[1]) > 0
4294 && INTVAL (operands[1]) <= GET_MODE_BITSIZE (SImode)
4295 && INTVAL (operands[1]) % BITS_PER_UNIT == 0"
4296 {
4297 int size = INTVAL (operands[1]) / BITS_PER_UNIT;
4298
4299 operands[1] = GEN_INT ((1ul << size) - 1);
4300 return (which_alternative == 0) ? "stcm\t%2,%1,%S0"
4301 : "stcmy\t%2,%1,%S0";
4302 }
4303 [(set_attr "op_type" "RS,RSY")
4304 (set_attr "cpu_facility" "*,longdisp")
4305 (set_attr "z10prop" "z10_super,z10_super")])
4306
4307 (define_insn "*insvdi_mem_reghigh"
4308 [(set (zero_extract:DI (match_operand:QI 0 "memory_operand" "+S")
4309 (match_operand 1 "const_int_operand" "n")
4310 (const_int 0))
4311 (lshiftrt:DI (match_operand:DI 2 "register_operand" "d")
4312 (const_int 32)))]
4313 "TARGET_ZARCH
4314 && EXTRACT_ARGS_IN_RANGE (INTVAL (operands[1]), 0, 64)
4315 && INTVAL (operands[1]) > 0
4316 && INTVAL (operands[1]) <= GET_MODE_BITSIZE (SImode)
4317 && INTVAL (operands[1]) % BITS_PER_UNIT == 0"
4318 {
4319 int size = INTVAL (operands[1]) / BITS_PER_UNIT;
4320
4321 operands[1] = GEN_INT ((1ul << size) - 1);
4322 return "stcmh\t%2,%1,%S0";
4323 }
4324 [(set_attr "op_type" "RSY")
4325 (set_attr "z10prop" "z10_super")])
4326
4327 (define_insn "*insvdi_reg_imm"
4328 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+d")
4329 (const_int 16)
4330 (match_operand 1 "const_int_operand" "n"))
4331 (match_operand:DI 2 "const_int_operand" "n"))]
4332 "TARGET_ZARCH
4333 && EXTRACT_ARGS_IN_RANGE (16, INTVAL (operands[1]), 64)
4334 && INTVAL (operands[1]) >= 0
4335 && INTVAL (operands[1]) < BITS_PER_WORD
4336 && INTVAL (operands[1]) % 16 == 0"
4337 {
4338 switch (BITS_PER_WORD - INTVAL (operands[1]))
4339 {
4340 case 64: return "iihh\t%0,%x2"; break;
4341 case 48: return "iihl\t%0,%x2"; break;
4342 case 32: return "iilh\t%0,%x2"; break;
4343 case 16: return "iill\t%0,%x2"; break;
4344 default: gcc_unreachable();
4345 }
4346 }
4347 [(set_attr "op_type" "RI")
4348 (set_attr "z10prop" "z10_super_E1")])
4349
4350 ; Update the left-most 32 bit of a DI.
4351 (define_insn "*insv_h_di_reg_extimm"
4352 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+d")
4353 (const_int 32)
4354 (const_int 0))
4355 (match_operand:DI 1 "const_int_operand" "n"))]
4356 "TARGET_EXTIMM"
4357 "iihf\t%0,%o1"
4358 [(set_attr "op_type" "RIL")
4359 (set_attr "z10prop" "z10_fwd_E1")])
4360
4361 ; Update the right-most 32 bit of a DI.
4362 (define_insn "*insv_l_di_reg_extimm"
4363 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+d")
4364 (const_int 32)
4365 (const_int 32))
4366 (match_operand:DI 1 "const_int_operand" "n"))]
4367 "TARGET_EXTIMM"
4368 "iilf\t%0,%o1"
4369 [(set_attr "op_type" "RIL")
4370 (set_attr "z10prop" "z10_fwd_A1")])
4371
4372 ;
4373 ; extendsidi2 instruction pattern(s).
4374 ;
4375
4376 (define_expand "extendsidi2"
4377 [(set (match_operand:DI 0 "register_operand" "")
4378 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "")))]
4379 ""
4380 {
4381 if (!TARGET_ZARCH)
4382 {
4383 emit_clobber (operands[0]);
4384 emit_move_insn (gen_highpart (SImode, operands[0]), operands[1]);
4385 emit_move_insn (gen_lowpart (SImode, operands[0]), const0_rtx);
4386 emit_insn (gen_ashrdi3 (operands[0], operands[0], GEN_INT (32)));
4387 DONE;
4388 }
4389 })
4390
4391 (define_insn "*extendsidi2"
4392 [(set (match_operand:DI 0 "register_operand" "=d,d,d")
4393 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "d,T,b")))]
4394 "TARGET_ZARCH"
4395 "@
4396 lgfr\t%0,%1
4397 lgf\t%0,%1
4398 lgfrl\t%0,%1"
4399 [(set_attr "op_type" "RRE,RXY,RIL")
4400 (set_attr "type" "*,*,larl")
4401 (set_attr "cpu_facility" "*,*,z10")
4402 (set_attr "z10prop" "z10_super_E1,z10_super_E1,z10_super_E1")])
4403
4404 ;
4405 ; extend(hi|qi)(si|di)2 instruction pattern(s).
4406 ;
4407
4408 (define_expand "extend<HQI:mode><DSI:mode>2"
4409 [(set (match_operand:DSI 0 "register_operand" "")
4410 (sign_extend:DSI (match_operand:HQI 1 "nonimmediate_operand" "")))]
4411 ""
4412 {
4413 if (<DSI:MODE>mode == DImode && !TARGET_ZARCH)
4414 {
4415 rtx tmp = gen_reg_rtx (SImode);
4416 emit_insn (gen_extend<HQI:mode>si2 (tmp, operands[1]));
4417 emit_insn (gen_extendsidi2 (operands[0], tmp));
4418 DONE;
4419 }
4420 else if (!TARGET_EXTIMM)
4421 {
4422 rtx bitcount = GEN_INT (<DSI:bitsize> - <HQI:bitsize>);
4423
4424 operands[1] = gen_lowpart (<DSI:MODE>mode, operands[1]);
4425 emit_insn (gen_ashl<DSI:mode>3 (operands[0], operands[1], bitcount));
4426 emit_insn (gen_ashr<DSI:mode>3 (operands[0], operands[0], bitcount));
4427 DONE;
4428 }
4429 })
4430
4431 ;
4432 ; extendhidi2 instruction pattern(s).
4433 ;
4434
4435 (define_insn "*extendhidi2_extimm"
4436 [(set (match_operand:DI 0 "register_operand" "=d,d,d")
4437 (sign_extend:DI (match_operand:HI 1 "general_operand" "d,T,b")))]
4438 "TARGET_ZARCH && TARGET_EXTIMM"
4439 "@
4440 lghr\t%0,%1
4441 lgh\t%0,%1
4442 lghrl\t%0,%1"
4443 [(set_attr "op_type" "RRE,RXY,RIL")
4444 (set_attr "type" "*,*,larl")
4445 (set_attr "cpu_facility" "extimm,extimm,z10")
4446 (set_attr "z10prop" "z10_super_E1,z10_super_E1,z10_super_E1")])
4447
4448 (define_insn "*extendhidi2"
4449 [(set (match_operand:DI 0 "register_operand" "=d")
4450 (sign_extend:DI (match_operand:HI 1 "memory_operand" "T")))]
4451 "TARGET_ZARCH"
4452 "lgh\t%0,%1"
4453 [(set_attr "op_type" "RXY")
4454 (set_attr "z10prop" "z10_super_E1")])
4455
4456 ;
4457 ; extendhisi2 instruction pattern(s).
4458 ;
4459
4460 (define_insn "*extendhisi2_extimm"
4461 [(set (match_operand:SI 0 "register_operand" "=d,d,d,d")
4462 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" " d,R,T,b")))]
4463 "TARGET_EXTIMM"
4464 "@
4465 lhr\t%0,%1
4466 lh\t%0,%1
4467 lhy\t%0,%1
4468 lhrl\t%0,%1"
4469 [(set_attr "op_type" "RRE,RX,RXY,RIL")
4470 (set_attr "type" "*,*,*,larl")
4471 (set_attr "cpu_facility" "extimm,extimm,extimm,z10")
4472 (set_attr "z10prop" "z10_super_E1,z10_super_E1,z10_super_E1,z10_super_E1")])
4473
4474 (define_insn "*extendhisi2"
4475 [(set (match_operand:SI 0 "register_operand" "=d,d")
4476 (sign_extend:SI (match_operand:HI 1 "memory_operand" "R,T")))]
4477 "!TARGET_EXTIMM"
4478 "@
4479 lh\t%0,%1
4480 lhy\t%0,%1"
4481 [(set_attr "op_type" "RX,RXY")
4482 (set_attr "cpu_facility" "*,longdisp")
4483 (set_attr "z10prop" "z10_super_E1,z10_super_E1")])
4484
4485 ;
4486 ; extendqi(si|di)2 instruction pattern(s).
4487 ;
4488
4489 ; lbr, lgbr, lb, lgb
4490 (define_insn "*extendqi<mode>2_extimm"
4491 [(set (match_operand:GPR 0 "register_operand" "=d,d")
4492 (sign_extend:GPR (match_operand:QI 1 "nonimmediate_operand" "d,T")))]
4493 "TARGET_EXTIMM"
4494 "@
4495 l<g>br\t%0,%1
4496 l<g>b\t%0,%1"
4497 [(set_attr "op_type" "RRE,RXY")
4498 (set_attr "z10prop" "z10_super_E1,z10_super_E1")])
4499
4500 ; lb, lgb
4501 (define_insn "*extendqi<mode>2"
4502 [(set (match_operand:GPR 0 "register_operand" "=d")
4503 (sign_extend:GPR (match_operand:QI 1 "memory_operand" "T")))]
4504 "!TARGET_EXTIMM && TARGET_LONG_DISPLACEMENT"
4505 "l<g>b\t%0,%1"
4506 [(set_attr "op_type" "RXY")
4507 (set_attr "z10prop" "z10_super_E1")])
4508
4509 (define_insn_and_split "*extendqi<mode>2_short_displ"
4510 [(set (match_operand:GPR 0 "register_operand" "=d")
4511 (sign_extend:GPR (match_operand:QI 1 "s_operand" "Q")))
4512 (clobber (reg:CC CC_REGNUM))]
4513 "!TARGET_EXTIMM && !TARGET_LONG_DISPLACEMENT"
4514 "#"
4515 "&& reload_completed"
4516 [(parallel
4517 [(set (match_dup 0) (unspec:GPR [(match_dup 1) (const_int 8)] UNSPEC_ICM))
4518 (clobber (reg:CC CC_REGNUM))])
4519 (parallel
4520 [(set (match_dup 0) (ashiftrt:GPR (match_dup 0) (match_dup 2)))
4521 (clobber (reg:CC CC_REGNUM))])]
4522 {
4523 operands[1] = adjust_address (operands[1], BLKmode, 0);
4524 set_mem_size (operands[1], GET_MODE_SIZE (QImode));
4525 operands[2] = GEN_INT (<GPR:bitsize> - BITS_PER_UNIT);
4526 })
4527
4528 ;
4529 ; zero_extendsidi2 instruction pattern(s).
4530 ;
4531
4532 (define_expand "zero_extendsidi2"
4533 [(set (match_operand:DI 0 "register_operand" "")
4534 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "")))]
4535 ""
4536 {
4537 if (!TARGET_ZARCH)
4538 {
4539 emit_clobber (operands[0]);
4540 emit_move_insn (gen_lowpart (SImode, operands[0]), operands[1]);
4541 emit_move_insn (gen_highpart (SImode, operands[0]), const0_rtx);
4542 DONE;
4543 }
4544 })
4545
4546 (define_insn "*zero_extendsidi2"
4547 [(set (match_operand:DI 0 "register_operand" "=d,d,d")
4548 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "d,T,b")))]
4549 "TARGET_ZARCH"
4550 "@
4551 llgfr\t%0,%1
4552 llgf\t%0,%1
4553 llgfrl\t%0,%1"
4554 [(set_attr "op_type" "RRE,RXY,RIL")
4555 (set_attr "type" "*,*,larl")
4556 (set_attr "cpu_facility" "*,*,z10")
4557 (set_attr "z10prop" "z10_fwd_E1,z10_fwd_A3,z10_fwd_A3")])
4558
4559 ;
4560 ; LLGT-type instructions (zero-extend from 31 bit to 64 bit).
4561 ;
4562
4563 (define_insn "*llgt_sidi"
4564 [(set (match_operand:DI 0 "register_operand" "=d")
4565 (and:DI (subreg:DI (match_operand:SI 1 "memory_operand" "T") 0)
4566 (const_int 2147483647)))]
4567 "TARGET_ZARCH"
4568 "llgt\t%0,%1"
4569 [(set_attr "op_type" "RXE")
4570 (set_attr "z10prop" "z10_super_E1")])
4571
4572 (define_insn_and_split "*llgt_sidi_split"
4573 [(set (match_operand:DI 0 "register_operand" "=d")
4574 (and:DI (subreg:DI (match_operand:SI 1 "memory_operand" "T") 0)
4575 (const_int 2147483647)))
4576 (clobber (reg:CC CC_REGNUM))]
4577 "TARGET_ZARCH"
4578 "#"
4579 "&& reload_completed"
4580 [(set (match_dup 0)
4581 (and:DI (subreg:DI (match_dup 1) 0)
4582 (const_int 2147483647)))]
4583 "")
4584
4585 (define_insn "*llgt_sisi"
4586 [(set (match_operand:SI 0 "register_operand" "=d,d")
4587 (and:SI (match_operand:SI 1 "nonimmediate_operand" "d,T")
4588 (const_int 2147483647)))]
4589 "TARGET_ZARCH"
4590 "@
4591 llgtr\t%0,%1
4592 llgt\t%0,%1"
4593 [(set_attr "op_type" "RRE,RXE")
4594 (set_attr "z10prop" "z10_super_E1,z10_super_E1")])
4595
4596 (define_insn "*llgt_didi"
4597 [(set (match_operand:DI 0 "register_operand" "=d,d")
4598 (and:DI (match_operand:DI 1 "nonimmediate_operand" "d,o")
4599 (const_int 2147483647)))]
4600 "TARGET_ZARCH"
4601 "@
4602 llgtr\t%0,%1
4603 llgt\t%0,%N1"
4604 [(set_attr "op_type" "RRE,RXE")
4605 (set_attr "z10prop" "z10_super_E1,z10_super_E1")])
4606
4607 (define_split
4608 [(set (match_operand:DSI 0 "register_operand" "")
4609 (and:DSI (match_operand:DSI 1 "nonimmediate_operand" "")
4610 (const_int 2147483647)))
4611 (clobber (reg:CC CC_REGNUM))]
4612 "TARGET_ZARCH && reload_completed"
4613 [(set (match_dup 0)
4614 (and:DSI (match_dup 1)
4615 (const_int 2147483647)))]
4616 "")
4617
4618 ;
4619 ; zero_extend(hi|qi)(si|di)2 instruction pattern(s).
4620 ;
4621
4622 (define_expand "zero_extend<mode>di2"
4623 [(set (match_operand:DI 0 "register_operand" "")
4624 (zero_extend:DI (match_operand:HQI 1 "nonimmediate_operand" "")))]
4625 ""
4626 {
4627 if (!TARGET_ZARCH)
4628 {
4629 rtx tmp = gen_reg_rtx (SImode);
4630 emit_insn (gen_zero_extend<mode>si2 (tmp, operands[1]));
4631 emit_insn (gen_zero_extendsidi2 (operands[0], tmp));
4632 DONE;
4633 }
4634 else if (!TARGET_EXTIMM)
4635 {
4636 rtx bitcount = GEN_INT (64 - <HQI:bitsize>);
4637 operands[1] = gen_lowpart (DImode, operands[1]);
4638 emit_insn (gen_ashldi3 (operands[0], operands[1], bitcount));
4639 emit_insn (gen_lshrdi3 (operands[0], operands[0], bitcount));
4640 DONE;
4641 }
4642 })
4643
4644 (define_expand "zero_extend<mode>si2"
4645 [(set (match_operand:SI 0 "register_operand" "")
4646 (zero_extend:SI (match_operand:HQI 1 "nonimmediate_operand" "")))]
4647 ""
4648 {
4649 if (!TARGET_EXTIMM)
4650 {
4651 operands[1] = gen_lowpart (SImode, operands[1]);
4652 emit_insn (gen_andsi3 (operands[0], operands[1],
4653 GEN_INT ((1 << <HQI:bitsize>) - 1)));
4654 DONE;
4655 }
4656 })
4657
4658 ; llhrl, llghrl
4659 (define_insn "*zero_extendhi<mode>2_z10"
4660 [(set (match_operand:GPR 0 "register_operand" "=d,d,d")
4661 (zero_extend:GPR (match_operand:HI 1 "nonimmediate_operand" "d,T,b")))]
4662 "TARGET_Z10"
4663 "@
4664 ll<g>hr\t%0,%1
4665 ll<g>h\t%0,%1
4666 ll<g>hrl\t%0,%1"
4667 [(set_attr "op_type" "RXY,RRE,RIL")
4668 (set_attr "type" "*,*,larl")
4669 (set_attr "cpu_facility" "*,*,z10")
4670 (set_attr "z10prop" "z10_super_E1,z10_fwd_A3,z10_fwd_A3")])
4671
4672 ; llhr, llcr, llghr, llgcr, llh, llc, llgh, llgc
4673 (define_insn "*zero_extend<HQI:mode><GPR:mode>2_extimm"
4674 [(set (match_operand:GPR 0 "register_operand" "=d,d")
4675 (zero_extend:GPR (match_operand:HQI 1 "nonimmediate_operand" "d,T")))]
4676 "TARGET_EXTIMM"
4677 "@
4678 ll<g><hc>r\t%0,%1
4679 ll<g><hc>\t%0,%1"
4680 [(set_attr "op_type" "RRE,RXY")
4681 (set_attr "z10prop" "z10_super_E1,z10_fwd_A3")])
4682
4683 ; llgh, llgc
4684 (define_insn "*zero_extend<HQI:mode><GPR:mode>2"
4685 [(set (match_operand:GPR 0 "register_operand" "=d")
4686 (zero_extend:GPR (match_operand:HQI 1 "memory_operand" "T")))]
4687 "TARGET_ZARCH && !TARGET_EXTIMM"
4688 "llg<hc>\t%0,%1"
4689 [(set_attr "op_type" "RXY")
4690 (set_attr "z10prop" "z10_fwd_A3")])
4691
4692 (define_insn_and_split "*zero_extendhisi2_31"
4693 [(set (match_operand:SI 0 "register_operand" "=&d")
4694 (zero_extend:SI (match_operand:HI 1 "s_operand" "S")))
4695 (clobber (reg:CC CC_REGNUM))]
4696 "!TARGET_ZARCH"
4697 "#"
4698 "&& reload_completed"
4699 [(set (match_dup 0) (const_int 0))
4700 (parallel
4701 [(set (strict_low_part (match_dup 2)) (match_dup 1))
4702 (clobber (reg:CC CC_REGNUM))])]
4703 "operands[2] = gen_lowpart (HImode, operands[0]);")
4704
4705 (define_insn_and_split "*zero_extendqisi2_31"
4706 [(set (match_operand:SI 0 "register_operand" "=&d")
4707 (zero_extend:SI (match_operand:QI 1 "memory_operand" "T")))]
4708 "!TARGET_ZARCH"
4709 "#"
4710 "&& reload_completed"
4711 [(set (match_dup 0) (const_int 0))
4712 (set (strict_low_part (match_dup 2)) (match_dup 1))]
4713 "operands[2] = gen_lowpart (QImode, operands[0]);")
4714
4715 ;
4716 ; zero_extendqihi2 instruction pattern(s).
4717 ;
4718
4719 (define_expand "zero_extendqihi2"
4720 [(set (match_operand:HI 0 "register_operand" "")
4721 (zero_extend:HI (match_operand:QI 1 "register_operand" "")))]
4722 "TARGET_ZARCH && !TARGET_EXTIMM"
4723 {
4724 operands[1] = gen_lowpart (HImode, operands[1]);
4725 emit_insn (gen_andhi3 (operands[0], operands[1], GEN_INT (0xff)));
4726 DONE;
4727 })
4728
4729 (define_insn "*zero_extendqihi2_64"
4730 [(set (match_operand:HI 0 "register_operand" "=d")
4731 (zero_extend:HI (match_operand:QI 1 "memory_operand" "T")))]
4732 "TARGET_ZARCH && !TARGET_EXTIMM"
4733 "llgc\t%0,%1"
4734 [(set_attr "op_type" "RXY")
4735 (set_attr "z10prop" "z10_fwd_A3")])
4736
4737 (define_insn_and_split "*zero_extendqihi2_31"
4738 [(set (match_operand:HI 0 "register_operand" "=&d")
4739 (zero_extend:HI (match_operand:QI 1 "memory_operand" "T")))]
4740 "!TARGET_ZARCH"
4741 "#"
4742 "&& reload_completed"
4743 [(set (match_dup 0) (const_int 0))
4744 (set (strict_low_part (match_dup 2)) (match_dup 1))]
4745 "operands[2] = gen_lowpart (QImode, operands[0]);")
4746
4747 ;
4748 ; fixuns_trunc(dd|td)di2 instruction pattern(s).
4749 ;
4750
4751 (define_expand "fixuns_truncdddi2"
4752 [(parallel
4753 [(set (match_operand:DI 0 "register_operand" "")
4754 (unsigned_fix:DI (match_operand:DD 1 "register_operand" "")))
4755 (unspec:DI [(const_int DFP_RND_TOWARD_0)] UNSPEC_ROUND)
4756 (clobber (reg:CC CC_REGNUM))])]
4757
4758 "TARGET_HARD_DFP"
4759 {
4760 if (!TARGET_Z196)
4761 {
4762 rtx_code_label *label1 = gen_label_rtx ();
4763 rtx_code_label *label2 = gen_label_rtx ();
4764 rtx temp = gen_reg_rtx (TDmode);
4765 REAL_VALUE_TYPE cmp, sub;
4766
4767 decimal_real_from_string (&cmp, "9223372036854775808.0"); /* 2^63 */
4768 decimal_real_from_string (&sub, "18446744073709551616.0"); /* 2^64 */
4769
4770 /* 2^63 can't be represented as 64bit DFP number with full precision. The
4771 solution is doing the check and the subtraction in TD mode and using a
4772 TD -> DI convert afterwards. */
4773 emit_insn (gen_extendddtd2 (temp, operands[1]));
4774 temp = force_reg (TDmode, temp);
4775 emit_cmp_and_jump_insns (temp,
4776 const_double_from_real_value (cmp, TDmode),
4777 LT, NULL_RTX, VOIDmode, 0, label1);
4778 emit_insn (gen_subtd3 (temp, temp,
4779 const_double_from_real_value (sub, TDmode)));
4780 emit_insn (gen_fix_trunctddi2_dfp (operands[0], temp,
4781 GEN_INT (DFP_RND_TOWARD_MINF)));
4782 emit_jump (label2);
4783
4784 emit_label (label1);
4785 emit_insn (gen_fix_truncdddi2_dfp (operands[0], operands[1],
4786 GEN_INT (DFP_RND_TOWARD_0)));
4787 emit_label (label2);
4788 DONE;
4789 }
4790 })
4791
4792 (define_expand "fixuns_trunctddi2"
4793 [(parallel
4794 [(set (match_operand:DI 0 "register_operand" "")
4795 (unsigned_fix:DI (match_operand:TD 1 "register_operand" "")))
4796 (unspec:DI [(const_int DFP_RND_TOWARD_0)] UNSPEC_ROUND)
4797 (clobber (reg:CC CC_REGNUM))])]
4798
4799 "TARGET_HARD_DFP"
4800 {
4801 if (!TARGET_Z196)
4802 {
4803 rtx_code_label *label1 = gen_label_rtx ();
4804 rtx_code_label *label2 = gen_label_rtx ();
4805 rtx temp = gen_reg_rtx (TDmode);
4806 REAL_VALUE_TYPE cmp, sub;
4807
4808 operands[1] = force_reg (TDmode, operands[1]);
4809 decimal_real_from_string (&cmp, "9223372036854775808.0"); /* 2^63 */
4810 decimal_real_from_string (&sub, "18446744073709551616.0"); /* 2^64 */
4811
4812 emit_cmp_and_jump_insns (operands[1],
4813 const_double_from_real_value (cmp, TDmode),
4814 LT, NULL_RTX, VOIDmode, 0, label1);
4815 emit_insn (gen_subtd3 (temp, operands[1],
4816 const_double_from_real_value (sub, TDmode)));
4817 emit_insn (gen_fix_trunctddi2_dfp (operands[0], temp,
4818 GEN_INT (DFP_RND_TOWARD_MINF)));
4819 emit_jump (label2);
4820
4821 emit_label (label1);
4822 emit_insn (gen_fix_trunctddi2_dfp (operands[0], operands[1],
4823 GEN_INT (DFP_RND_TOWARD_0)));
4824 emit_label (label2);
4825 DONE;
4826 }
4827 })
4828
4829 ;
4830 ; fixuns_trunc(sf|df|tf)(si|di)2 and fix_trunc(sf|df|tf)(si|di)2
4831 ; instruction pattern(s).
4832 ;
4833
4834 (define_expand "fixuns_trunc<BFP:mode><GPR:mode>2"
4835 [(parallel
4836 [(set (match_operand:GPR 0 "register_operand" "")
4837 (unsigned_fix:GPR (match_operand:BFP 1 "register_operand" "")))
4838 (unspec:GPR [(const_int BFP_RND_TOWARD_0)] UNSPEC_ROUND)
4839 (clobber (reg:CC CC_REGNUM))])]
4840 "TARGET_HARD_FLOAT"
4841 {
4842 if (!TARGET_Z196)
4843 {
4844 rtx_code_label *label1 = gen_label_rtx ();
4845 rtx_code_label *label2 = gen_label_rtx ();
4846 rtx temp = gen_reg_rtx (<BFP:MODE>mode);
4847 REAL_VALUE_TYPE cmp, sub;
4848
4849 operands[1] = force_reg (<BFP:MODE>mode, operands[1]);
4850 real_2expN (&cmp, <GPR:bitsize> - 1, <BFP:MODE>mode);
4851 real_2expN (&sub, <GPR:bitsize>, <BFP:MODE>mode);
4852
4853 emit_cmp_and_jump_insns (operands[1],
4854 const_double_from_real_value (cmp, <BFP:MODE>mode),
4855 LT, NULL_RTX, VOIDmode, 0, label1);
4856 emit_insn (gen_sub<BFP:mode>3 (temp, operands[1],
4857 const_double_from_real_value (sub, <BFP:MODE>mode)));
4858 emit_insn (gen_fix_trunc<BFP:mode><GPR:mode>2_bfp (operands[0], temp,
4859 GEN_INT (BFP_RND_TOWARD_MINF)));
4860 emit_jump (label2);
4861
4862 emit_label (label1);
4863 emit_insn (gen_fix_trunc<BFP:mode><GPR:mode>2_bfp (operands[0],
4864 operands[1], GEN_INT (BFP_RND_TOWARD_0)));
4865 emit_label (label2);
4866 DONE;
4867 }
4868 })
4869
4870 ; fixuns_trunc(td|dd)si2 expander
4871 (define_expand "fixuns_trunc<mode>si2"
4872 [(parallel
4873 [(set (match_operand:SI 0 "register_operand" "")
4874 (unsigned_fix:SI (match_operand:DFP 1 "register_operand" "")))
4875 (unspec:SI [(const_int DFP_RND_TOWARD_0)] UNSPEC_ROUND)
4876 (clobber (reg:CC CC_REGNUM))])]
4877 "TARGET_Z196 && TARGET_HARD_DFP"
4878 "")
4879
4880 ; fixuns_trunc(tf|df|sf|td|dd)(di|si)2 instruction patterns.
4881
4882 (define_insn "*fixuns_truncdfdi2_z13"
4883 [(set (match_operand:DI 0 "register_operand" "=d,v")
4884 (unsigned_fix:DI (match_operand:DF 1 "register_operand" "f,v")))
4885 (unspec:DI [(match_operand:DI 2 "immediate_operand" "K,K")] UNSPEC_ROUND)
4886 (clobber (reg:CC CC_REGNUM))]
4887 "TARGET_VX && TARGET_HARD_FLOAT"
4888 "@
4889 clgdbr\t%0,%h2,%1,0
4890 wclgdb\t%v0,%v1,0,%h2"
4891 [(set_attr "op_type" "RRF,VRR")
4892 (set_attr "type" "ftoi")])
4893
4894 ; clfebr, clfdbr, clfxbr, clgebr, clgdbr, clgxbr
4895 ; clfdtr, clfxtr, clgdtr, clgxtr
4896 (define_insn "*fixuns_trunc<FP:mode><GPR:mode>2_z196"
4897 [(set (match_operand:GPR 0 "register_operand" "=d")
4898 (unsigned_fix:GPR (match_operand:FP 1 "register_operand" "f")))
4899 (unspec:GPR [(match_operand:GPR 2 "immediate_operand" "K")] UNSPEC_ROUND)
4900 (clobber (reg:CC CC_REGNUM))]
4901 "TARGET_Z196 && TARGET_HARD_FLOAT
4902 && (!TARGET_VX || <GPR:MODE>mode != DImode || <FP:MODE>mode != DFmode)"
4903 "cl<GPR:gf><FP:xde><FP:bt>r\t%0,%h2,%1,0"
4904 [(set_attr "op_type" "RRF")
4905 (set_attr "type" "ftoi")])
4906
4907 (define_expand "fix_trunc<DSF:mode><GPR:mode>2"
4908 [(set (match_operand:GPR 0 "register_operand" "")
4909 (fix:GPR (match_operand:DSF 1 "register_operand" "")))]
4910 "TARGET_HARD_FLOAT"
4911 {
4912 emit_insn (gen_fix_trunc<DSF:mode><GPR:mode>2_bfp (operands[0], operands[1],
4913 GEN_INT (BFP_RND_TOWARD_0)));
4914 DONE;
4915 })
4916
4917 (define_insn "*fix_truncdfdi2_bfp_z13"
4918 [(set (match_operand:DI 0 "register_operand" "=d,v")
4919 (fix:DI (match_operand:DF 1 "register_operand" "f,v")))
4920 (unspec:DI [(match_operand:DI 2 "immediate_operand" "K,K")] UNSPEC_ROUND)
4921 (clobber (reg:CC CC_REGNUM))]
4922 "TARGET_VX && TARGET_HARD_FLOAT"
4923 "@
4924 cgdbr\t%0,%h2,%1
4925 wcgdb\t%v0,%v1,0,%h2"
4926 [(set_attr "op_type" "RRE,VRR")
4927 (set_attr "type" "ftoi")])
4928
4929 ; cgxbr, cgdbr, cgebr, cfxbr, cfdbr, cfebr
4930 (define_insn "*fix_trunc<BFP:mode><GPR:mode>2_bfp"
4931 [(set (match_operand:GPR 0 "register_operand" "=d")
4932 (fix:GPR (match_operand:BFP 1 "register_operand" "f")))
4933 (unspec:GPR [(match_operand:GPR 2 "immediate_operand" "K")] UNSPEC_ROUND)
4934 (clobber (reg:CC CC_REGNUM))]
4935 "TARGET_HARD_FLOAT
4936 && (!TARGET_VX || <GPR:MODE>mode != DImode || <BFP:MODE>mode != DFmode)"
4937 "c<GPR:gf><BFP:xde>br\t%0,%h2,%1"
4938 [(set_attr "op_type" "RRE")
4939 (set_attr "type" "ftoi")])
4940
4941 (define_expand "fix_trunc<BFP:mode><GPR:mode>2_bfp"
4942 [(parallel
4943 [(set (match_operand:GPR 0 "register_operand" "=d")
4944 (fix:GPR (match_operand:BFP 1 "register_operand" "f")))
4945 (unspec:GPR [(match_operand:GPR 2 "immediate_operand" "K")] UNSPEC_ROUND)
4946 (clobber (reg:CC CC_REGNUM))])]
4947 "TARGET_HARD_FLOAT")
4948 ;
4949 ; fix_trunc(td|dd)di2 instruction pattern(s).
4950 ;
4951
4952 (define_expand "fix_trunc<mode>di2"
4953 [(set (match_operand:DI 0 "register_operand" "")
4954 (fix:DI (match_operand:DFP 1 "nonimmediate_operand" "")))]
4955 "TARGET_ZARCH && TARGET_HARD_DFP"
4956 {
4957 operands[1] = force_reg (<MODE>mode, operands[1]);
4958 emit_insn (gen_fix_trunc<mode>di2_dfp (operands[0], operands[1],
4959 GEN_INT (DFP_RND_TOWARD_0)));
4960 DONE;
4961 })
4962
4963 ; cgxtr, cgdtr
4964 (define_insn "fix_trunc<DFP:mode>di2_dfp"
4965 [(set (match_operand:DI 0 "register_operand" "=d")
4966 (fix:DI (match_operand:DFP 1 "register_operand" "f")))
4967 (unspec:DI [(match_operand:DI 2 "immediate_operand" "K")] UNSPEC_ROUND)
4968 (clobber (reg:CC CC_REGNUM))]
4969 "TARGET_ZARCH && TARGET_HARD_DFP"
4970 "cg<DFP:xde>tr\t%0,%h2,%1"
4971 [(set_attr "op_type" "RRF")
4972 (set_attr "type" "ftoidfp")])
4973
4974
4975 ;
4976 ; fix_trunctf(si|di)2 instruction pattern(s).
4977 ;
4978
4979 (define_expand "fix_trunctf<mode>2"
4980 [(parallel [(set (match_operand:GPR 0 "register_operand" "")
4981 (fix:GPR (match_operand:TF 1 "register_operand" "")))
4982 (unspec:GPR [(const_int BFP_RND_TOWARD_0)] UNSPEC_ROUND)
4983 (clobber (reg:CC CC_REGNUM))])]
4984 "TARGET_HARD_FLOAT"
4985 "")
4986
4987
4988 ;
4989 ; float(si|di)(tf|df|sf|td|dd)2 instruction pattern(s).
4990 ;
4991
4992 ; cxgbr, cdgbr, cegbr, cxgtr, cdgtr
4993 (define_insn "floatdi<mode>2"
4994 [(set (match_operand:FP 0 "register_operand" "=f,v")
4995 (float:FP (match_operand:DI 1 "register_operand" "d,v")))]
4996 "TARGET_ZARCH && TARGET_HARD_FLOAT"
4997 "@
4998 c<xde>g<bt>r\t%0,%1
4999 wcdgb\t%v0,%v1,0,0"
5000 [(set_attr "op_type" "RRE,VRR")
5001 (set_attr "type" "itof<mode>" )
5002 (set_attr "cpu_facility" "*,vx")
5003 (set_attr "enabled" "*,<DFDI>")])
5004
5005 ; cxfbr, cdfbr, cefbr
5006 (define_insn "floatsi<mode>2"
5007 [(set (match_operand:BFP 0 "register_operand" "=f")
5008 (float:BFP (match_operand:SI 1 "register_operand" "d")))]
5009 "TARGET_HARD_FLOAT"
5010 "c<xde>fbr\t%0,%1"
5011 [(set_attr "op_type" "RRE")
5012 (set_attr "type" "itof<mode>" )])
5013
5014 ; cxftr, cdftr
5015 (define_insn "floatsi<mode>2"
5016 [(set (match_operand:DFP 0 "register_operand" "=f")
5017 (float:DFP (match_operand:SI 1 "register_operand" "d")))]
5018 "TARGET_Z196 && TARGET_HARD_FLOAT"
5019 "c<xde>ftr\t%0,0,%1,0"
5020 [(set_attr "op_type" "RRE")
5021 (set_attr "type" "itof<mode>" )])
5022
5023 ;
5024 ; floatuns(si|di)(tf|df|sf|td|dd)2 instruction pattern(s).
5025 ;
5026
5027 (define_insn "*floatunsdidf2_z13"
5028 [(set (match_operand:DF 0 "register_operand" "=f,v")
5029 (unsigned_float:DF (match_operand:DI 1 "register_operand" "d,v")))]
5030 "TARGET_VX && TARGET_HARD_FLOAT"
5031 "@
5032 cdlgbr\t%0,0,%1,0
5033 wcdlgb\t%v0,%v1,0,0"
5034 [(set_attr "op_type" "RRE,VRR")
5035 (set_attr "type" "itofdf")])
5036
5037 ; cxlgbr, cdlgbr, celgbr, cxlgtr, cdlgtr
5038 ; cxlfbr, cdlfbr, celfbr, cxlftr, cdlftr
5039 (define_insn "*floatuns<GPR:mode><FP:mode>2"
5040 [(set (match_operand:FP 0 "register_operand" "=f")
5041 (unsigned_float:FP (match_operand:GPR 1 "register_operand" "d")))]
5042 "TARGET_Z196 && TARGET_HARD_FLOAT
5043 && (!TARGET_VX || <FP:MODE>mode != DFmode || <GPR:MODE>mode != DImode)"
5044 "c<FP:xde>l<GPR:gf><FP:bt>r\t%0,0,%1,0"
5045 [(set_attr "op_type" "RRE")
5046 (set_attr "type" "itof<FP:mode>")])
5047
5048 (define_expand "floatuns<GPR:mode><FP:mode>2"
5049 [(set (match_operand:FP 0 "register_operand" "")
5050 (unsigned_float:FP (match_operand:GPR 1 "register_operand" "")))]
5051 "TARGET_Z196 && TARGET_HARD_FLOAT")
5052
5053 ;
5054 ; truncdfsf2 instruction pattern(s).
5055 ;
5056
5057 (define_insn "truncdfsf2"
5058 [(set (match_operand:SF 0 "register_operand" "=f,v")
5059 (float_truncate:SF (match_operand:DF 1 "register_operand" "f,v")))]
5060 "TARGET_HARD_FLOAT"
5061 "@
5062 ledbr\t%0,%1
5063 wledb\t%v0,%v1,0,0" ; IEEE inexact exception not suppressed
5064 ; According to BFP rounding mode
5065 [(set_attr "op_type" "RRE,VRR")
5066 (set_attr "type" "ftruncdf")
5067 (set_attr "cpu_facility" "*,vx")])
5068
5069 ;
5070 ; trunctf(df|sf)2 instruction pattern(s).
5071 ;
5072
5073 ; ldxbr, lexbr
5074 (define_insn "trunctf<mode>2"
5075 [(set (match_operand:DSF 0 "register_operand" "=f")
5076 (float_truncate:DSF (match_operand:TF 1 "register_operand" "f")))
5077 (clobber (match_scratch:TF 2 "=f"))]
5078 "TARGET_HARD_FLOAT"
5079 "l<xde>xbr\t%2,%1\;l<xde>r\t%0,%2"
5080 [(set_attr "length" "6")
5081 (set_attr "type" "ftrunctf")])
5082
5083 ;
5084 ; trunctddd2 and truncddsd2 instruction pattern(s).
5085 ;
5086
5087
5088 (define_expand "trunctddd2"
5089 [(parallel
5090 [(set (match_operand:DD 0 "register_operand" "")
5091 (float_truncate:DD (match_operand:TD 1 "register_operand" "")))
5092 (unspec:DI [(const_int DFP_RND_CURRENT)] UNSPEC_ROUND)
5093 (clobber (scratch:TD))])]
5094 "TARGET_HARD_DFP")
5095
5096 (define_insn "*trunctddd2"
5097 [(set (match_operand:DD 0 "register_operand" "=f")
5098 (float_truncate:DD (match_operand:TD 1 "register_operand" "f")))
5099 (unspec:DI [(match_operand:DI 2 "const_mask_operand" "I")] UNSPEC_ROUND)
5100 (clobber (match_scratch:TD 3 "=f"))]
5101 "TARGET_HARD_DFP"
5102 "ldxtr\t%3,%2,%1,0\;ldr\t%0,%3"
5103 [(set_attr "length" "6")
5104 (set_attr "type" "ftruncdd")])
5105
5106 (define_insn "truncddsd2"
5107 [(set (match_operand:SD 0 "register_operand" "=f")
5108 (float_truncate:SD (match_operand:DD 1 "register_operand" "f")))]
5109 "TARGET_HARD_DFP"
5110 "ledtr\t%0,0,%1,0"
5111 [(set_attr "op_type" "RRF")
5112 (set_attr "type" "ftruncsd")])
5113
5114 (define_expand "trunctdsd2"
5115 [(parallel
5116 [(set (match_dup 2)
5117 (float_truncate:DD (match_operand:TD 1 "register_operand" "")))
5118 (unspec:DI [(const_int DFP_RND_PREP_FOR_SHORT_PREC)] UNSPEC_ROUND)
5119 (clobber (match_scratch:TD 3 ""))])
5120 (set (match_operand:SD 0 "register_operand" "")
5121 (float_truncate:SD (match_dup 2)))]
5122 "TARGET_HARD_DFP"
5123 {
5124 operands[2] = gen_reg_rtx (DDmode);
5125 })
5126
5127 ;
5128 ; extend(sf|df)(df|tf)2 instruction pattern(s).
5129 ;
5130
5131 (define_insn "*extendsfdf2_z13"
5132 [(set (match_operand:DF 0 "register_operand" "=f,f,v")
5133 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "f,R,v")))]
5134 "TARGET_VX && TARGET_HARD_FLOAT"
5135 "@
5136 ldebr\t%0,%1
5137 ldeb\t%0,%1
5138 wldeb\t%v0,%v1"
5139 [(set_attr "op_type" "RRE,RXE,VRR")
5140 (set_attr "type" "fsimpdf, floaddf,fsimpdf")])
5141
5142 ; ldebr, ldeb, lxdbr, lxdb, lxebr, lxeb
5143 (define_insn "*extend<DSF:mode><BFP:mode>2"
5144 [(set (match_operand:BFP 0 "register_operand" "=f,f")
5145 (float_extend:BFP (match_operand:DSF 1 "nonimmediate_operand" "f,R")))]
5146 "TARGET_HARD_FLOAT
5147 && GET_MODE_SIZE (<BFP:MODE>mode) > GET_MODE_SIZE (<DSF:MODE>mode)
5148 && (!TARGET_VX || <BFP:MODE>mode != DFmode || <DSF:MODE>mode != SFmode)"
5149 "@
5150 l<BFP:xde><DSF:xde>br\t%0,%1
5151 l<BFP:xde><DSF:xde>b\t%0,%1"
5152 [(set_attr "op_type" "RRE,RXE")
5153 (set_attr "type" "fsimp<BFP:mode>, fload<BFP:mode>")])
5154
5155 (define_expand "extend<DSF:mode><BFP:mode>2"
5156 [(set (match_operand:BFP 0 "register_operand" "")
5157 (float_extend:BFP (match_operand:DSF 1 "nonimmediate_operand" "")))]
5158 "TARGET_HARD_FLOAT
5159 && GET_MODE_SIZE (<BFP:MODE>mode) > GET_MODE_SIZE (<DSF:MODE>mode)")
5160
5161 ;
5162 ; extendddtd2 and extendsddd2 instruction pattern(s).
5163 ;
5164
5165 (define_insn "extendddtd2"
5166 [(set (match_operand:TD 0 "register_operand" "=f")
5167 (float_extend:TD (match_operand:DD 1 "register_operand" "f")))]
5168 "TARGET_HARD_DFP"
5169 "lxdtr\t%0,%1,0"
5170 [(set_attr "op_type" "RRF")
5171 (set_attr "type" "fsimptf")])
5172
5173 (define_insn "extendsddd2"
5174 [(set (match_operand:DD 0 "register_operand" "=f")
5175 (float_extend:DD (match_operand:SD 1 "register_operand" "f")))]
5176 "TARGET_HARD_DFP"
5177 "ldetr\t%0,%1,0"
5178 [(set_attr "op_type" "RRF")
5179 (set_attr "type" "fsimptf")])
5180
5181 (define_expand "extendsdtd2"
5182 [(set (match_dup 2)
5183 (float_extend:DD (match_operand:SD 1 "register_operand" "")))
5184 (set (match_operand:TD 0 "register_operand" "")
5185 (float_extend:TD (match_dup 2)))]
5186 "TARGET_HARD_DFP"
5187 {
5188 operands[2] = gen_reg_rtx (DDmode);
5189 })
5190
5191 ; Binary Floating Point - load fp integer
5192
5193 ; Expanders for: floor, btrunc, round, ceil, and nearbyint
5194 ; For all of them the inexact exceptions are suppressed.
5195
5196 ; fiebra, fidbra, fixbra
5197 (define_insn "<FPINT:fpint_name><BFP:mode>2"
5198 [(set (match_operand:BFP 0 "register_operand" "=f")
5199 (unspec:BFP [(match_operand:BFP 1 "register_operand" "f")]
5200 FPINT))]
5201 "TARGET_Z196"
5202 "fi<BFP:xde>bra\t%0,<FPINT:fpint_roundingmode>,%1,4"
5203 [(set_attr "op_type" "RRF")
5204 (set_attr "type" "fsimp<BFP:mode>")])
5205
5206 ; rint is supposed to raise an inexact exception so we can use the
5207 ; older instructions.
5208
5209 ; fiebr, fidbr, fixbr
5210 (define_insn "rint<BFP:mode>2"
5211 [(set (match_operand:BFP 0 "register_operand" "=f")
5212 (unspec:BFP [(match_operand:BFP 1 "register_operand" "f")]
5213 UNSPEC_FPINT_RINT))]
5214 ""
5215 "fi<BFP:xde>br\t%0,0,%1"
5216 [(set_attr "op_type" "RRF")
5217 (set_attr "type" "fsimp<BFP:mode>")])
5218
5219
5220 ; Decimal Floating Point - load fp integer
5221
5222 ; fidtr, fixtr
5223 (define_insn "<FPINT:fpint_name><DFP:mode>2"
5224 [(set (match_operand:DFP 0 "register_operand" "=f")
5225 (unspec:DFP [(match_operand:DFP 1 "register_operand" "f")]
5226 FPINT))]
5227 "TARGET_HARD_DFP"
5228 "fi<DFP:xde>tr\t%0,<FPINT:fpint_roundingmode>,%1,4"
5229 [(set_attr "op_type" "RRF")
5230 (set_attr "type" "fsimp<DFP:mode>")])
5231
5232 ; fidtr, fixtr
5233 (define_insn "rint<DFP:mode>2"
5234 [(set (match_operand:DFP 0 "register_operand" "=f")
5235 (unspec:DFP [(match_operand:DFP 1 "register_operand" "f")]
5236 UNSPEC_FPINT_RINT))]
5237 "TARGET_HARD_DFP"
5238 "fi<DFP:xde>tr\t%0,0,%1,0"
5239 [(set_attr "op_type" "RRF")
5240 (set_attr "type" "fsimp<DFP:mode>")])
5241
5242 ;
5243 ; Binary <-> Decimal floating point trunc patterns
5244 ;
5245
5246 (define_insn "*trunc<BFP:mode><DFP_ALL:mode>2"
5247 [(set (reg:DFP_ALL FPR0_REGNUM)
5248 (float_truncate:DFP_ALL (reg:BFP FPR4_REGNUM)))
5249 (use (reg:SI GPR0_REGNUM))
5250 (clobber (reg:CC CC_REGNUM))
5251 (clobber (reg:SI GPR1_REGNUM))]
5252 "TARGET_HARD_DFP"
5253 "pfpo")
5254
5255 (define_insn "*trunc<DFP_ALL:mode><BFP:mode>2"
5256 [(set (reg:BFP FPR0_REGNUM)
5257 (float_truncate:BFP (reg:DFP_ALL FPR4_REGNUM)))
5258 (use (reg:SI GPR0_REGNUM))
5259 (clobber (reg:CC CC_REGNUM))
5260 (clobber (reg:SI GPR1_REGNUM))]
5261 "TARGET_HARD_DFP"
5262 "pfpo")
5263
5264 (define_expand "trunc<BFP:mode><DFP_ALL:mode>2"
5265 [(set (reg:BFP FPR4_REGNUM) (match_operand:BFP 1 "nonimmediate_operand" ""))
5266 (set (reg:SI GPR0_REGNUM) (match_dup 2))
5267 (parallel
5268 [(set (reg:DFP_ALL FPR0_REGNUM)
5269 (float_truncate:DFP_ALL (reg:BFP FPR4_REGNUM)))
5270 (use (reg:SI GPR0_REGNUM))
5271 (clobber (reg:CC CC_REGNUM))
5272 (clobber (reg:SI GPR1_REGNUM))])
5273 (set (match_operand:DFP_ALL 0 "nonimmediate_operand" "")
5274 (reg:DFP_ALL FPR0_REGNUM))]
5275 "TARGET_HARD_DFP
5276 && GET_MODE_SIZE (<BFP:MODE>mode) > GET_MODE_SIZE (<DFP_ALL:MODE>mode)"
5277 {
5278 HOST_WIDE_INT flags;
5279
5280 flags = (PFPO_CONVERT |
5281 PFPO_OP_TYPE_<DFP_ALL:MODE> << PFPO_OP0_TYPE_SHIFT |
5282 PFPO_OP_TYPE_<BFP:MODE> << PFPO_OP1_TYPE_SHIFT);
5283
5284 operands[2] = GEN_INT (flags);
5285 })
5286
5287 (define_expand "trunc<DFP_ALL:mode><BFP:mode>2"
5288 [(set (reg:DFP_ALL FPR4_REGNUM)
5289 (match_operand:DFP_ALL 1 "nonimmediate_operand" ""))
5290 (set (reg:SI GPR0_REGNUM) (match_dup 2))
5291 (parallel
5292 [(set (reg:BFP FPR0_REGNUM) (float_truncate:BFP (reg:DFP_ALL FPR4_REGNUM)))
5293 (use (reg:SI GPR0_REGNUM))
5294 (clobber (reg:CC CC_REGNUM))
5295 (clobber (reg:SI GPR1_REGNUM))])
5296 (set (match_operand:BFP 0 "nonimmediate_operand" "") (reg:BFP FPR0_REGNUM))]
5297 "TARGET_HARD_DFP
5298 && GET_MODE_SIZE (<DFP_ALL:MODE>mode) >= GET_MODE_SIZE (<BFP:MODE>mode)"
5299 {
5300 HOST_WIDE_INT flags;
5301
5302 flags = (PFPO_CONVERT |
5303 PFPO_OP_TYPE_<BFP:MODE> << PFPO_OP0_TYPE_SHIFT |
5304 PFPO_OP_TYPE_<DFP_ALL:MODE> << PFPO_OP1_TYPE_SHIFT);
5305
5306 operands[2] = GEN_INT (flags);
5307 })
5308
5309 ;
5310 ; Binary <-> Decimal floating point extend patterns
5311 ;
5312
5313 (define_insn "*extend<BFP:mode><DFP_ALL:mode>2"
5314 [(set (reg:DFP_ALL FPR0_REGNUM) (float_extend:DFP_ALL (reg:BFP FPR4_REGNUM)))
5315 (use (reg:SI GPR0_REGNUM))
5316 (clobber (reg:CC CC_REGNUM))
5317 (clobber (reg:SI GPR1_REGNUM))]
5318 "TARGET_HARD_DFP"
5319 "pfpo")
5320
5321 (define_insn "*extend<DFP_ALL:mode><BFP:mode>2"
5322 [(set (reg:BFP FPR0_REGNUM) (float_extend:BFP (reg:DFP_ALL FPR4_REGNUM)))
5323 (use (reg:SI GPR0_REGNUM))
5324 (clobber (reg:CC CC_REGNUM))
5325 (clobber (reg:SI GPR1_REGNUM))]
5326 "TARGET_HARD_DFP"
5327 "pfpo")
5328
5329 (define_expand "extend<BFP:mode><DFP_ALL:mode>2"
5330 [(set (reg:BFP FPR4_REGNUM) (match_operand:BFP 1 "nonimmediate_operand" ""))
5331 (set (reg:SI GPR0_REGNUM) (match_dup 2))
5332 (parallel
5333 [(set (reg:DFP_ALL FPR0_REGNUM)
5334 (float_extend:DFP_ALL (reg:BFP FPR4_REGNUM)))
5335 (use (reg:SI GPR0_REGNUM))
5336 (clobber (reg:CC CC_REGNUM))
5337 (clobber (reg:SI GPR1_REGNUM))])
5338 (set (match_operand:DFP_ALL 0 "nonimmediate_operand" "")
5339 (reg:DFP_ALL FPR0_REGNUM))]
5340 "TARGET_HARD_DFP
5341 && GET_MODE_SIZE (<BFP:MODE>mode) <= GET_MODE_SIZE (<DFP_ALL:MODE>mode)"
5342 {
5343 HOST_WIDE_INT flags;
5344
5345 flags = (PFPO_CONVERT |
5346 PFPO_OP_TYPE_<DFP_ALL:MODE> << PFPO_OP0_TYPE_SHIFT |
5347 PFPO_OP_TYPE_<BFP:MODE> << PFPO_OP1_TYPE_SHIFT);
5348
5349 operands[2] = GEN_INT (flags);
5350 })
5351
5352 (define_expand "extend<DFP_ALL:mode><BFP:mode>2"
5353 [(set (reg:DFP_ALL FPR4_REGNUM)
5354 (match_operand:DFP_ALL 1 "nonimmediate_operand" ""))
5355 (set (reg:SI GPR0_REGNUM) (match_dup 2))
5356 (parallel
5357 [(set (reg:BFP FPR0_REGNUM) (float_extend:BFP (reg:DFP_ALL FPR4_REGNUM)))
5358 (use (reg:SI GPR0_REGNUM))
5359 (clobber (reg:CC CC_REGNUM))
5360 (clobber (reg:SI GPR1_REGNUM))])
5361 (set (match_operand:BFP 0 "nonimmediate_operand" "") (reg:BFP FPR0_REGNUM))]
5362 "TARGET_HARD_DFP
5363 && GET_MODE_SIZE (<DFP_ALL:MODE>mode) < GET_MODE_SIZE (<BFP:MODE>mode)"
5364 {
5365 HOST_WIDE_INT flags;
5366
5367 flags = (PFPO_CONVERT |
5368 PFPO_OP_TYPE_<BFP:MODE> << PFPO_OP0_TYPE_SHIFT |
5369 PFPO_OP_TYPE_<DFP_ALL:MODE> << PFPO_OP1_TYPE_SHIFT);
5370
5371 operands[2] = GEN_INT (flags);
5372 })
5373
5374
5375 ;;
5376 ;; ARITHMETIC OPERATIONS
5377 ;;
5378 ; arithmetic operations set the ConditionCode,
5379 ; because of unpredictable Bits in Register for Halfword and Byte
5380 ; the ConditionCode can be set wrong in operations for Halfword and Byte
5381
5382 ;;
5383 ;;- Add instructions.
5384 ;;
5385
5386 ;
5387 ; addti3 instruction pattern(s).
5388 ;
5389
5390 (define_expand "addti3"
5391 [(parallel
5392 [(set (match_operand:TI 0 "register_operand" "")
5393 (plus:TI (match_operand:TI 1 "nonimmediate_operand" "")
5394 (match_operand:TI 2 "general_operand" "") ) )
5395 (clobber (reg:CC CC_REGNUM))])]
5396 "TARGET_ZARCH"
5397 {
5398 /* For z13 we have vaq which doesn't set CC. */
5399 if (TARGET_VX)
5400 {
5401 emit_insn (gen_rtx_SET (operands[0],
5402 gen_rtx_PLUS (TImode,
5403 copy_to_mode_reg (TImode, operands[1]),
5404 copy_to_mode_reg (TImode, operands[2]))));
5405 DONE;
5406 }
5407 })
5408
5409 (define_insn_and_split "*addti3"
5410 [(set (match_operand:TI 0 "register_operand" "=&d")
5411 (plus:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
5412 (match_operand:TI 2 "general_operand" "do") ) )
5413 (clobber (reg:CC CC_REGNUM))]
5414 "TARGET_ZARCH"
5415 "#"
5416 "&& reload_completed"
5417 [(parallel
5418 [(set (reg:CCL1 CC_REGNUM)
5419 (compare:CCL1 (plus:DI (match_dup 7) (match_dup 8))
5420 (match_dup 7)))
5421 (set (match_dup 6) (plus:DI (match_dup 7) (match_dup 8)))])
5422 (parallel
5423 [(set (match_dup 3) (plus:DI
5424 (plus:DI (ltu:DI (reg:CCL1 CC_REGNUM) (const_int 0))
5425 (match_dup 4)) (match_dup 5)))
5426 (clobber (reg:CC CC_REGNUM))])]
5427 "operands[3] = operand_subword (operands[0], 0, 0, TImode);
5428 operands[4] = operand_subword (operands[1], 0, 0, TImode);
5429 operands[5] = operand_subword (operands[2], 0, 0, TImode);
5430 operands[6] = operand_subword (operands[0], 1, 0, TImode);
5431 operands[7] = operand_subword (operands[1], 1, 0, TImode);
5432 operands[8] = operand_subword (operands[2], 1, 0, TImode);"
5433 [(set_attr "op_type" "*")
5434 (set_attr "cpu_facility" "*")])
5435
5436 ;
5437 ; adddi3 instruction pattern(s).
5438 ;
5439
5440 (define_expand "adddi3"
5441 [(parallel
5442 [(set (match_operand:DI 0 "nonimmediate_operand" "")
5443 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
5444 (match_operand:DI 2 "general_operand" "")))
5445 (clobber (reg:CC CC_REGNUM))])]
5446 ""
5447 "")
5448
5449 (define_insn "*adddi3_sign"
5450 [(set (match_operand:DI 0 "register_operand" "=d,d")
5451 (plus:DI (sign_extend:DI (match_operand:SI 2 "general_operand" "d,T"))
5452 (match_operand:DI 1 "register_operand" "0,0")))
5453 (clobber (reg:CC CC_REGNUM))]
5454 "TARGET_ZARCH"
5455 "@
5456 agfr\t%0,%2
5457 agf\t%0,%2"
5458 [(set_attr "op_type" "RRE,RXY")
5459 (set_attr "z196prop" "z196_cracked,z196_cracked")])
5460
5461 (define_insn "*adddi3_zero_cc"
5462 [(set (reg CC_REGNUM)
5463 (compare (plus:DI (zero_extend:DI (match_operand:SI 2 "general_operand" "d,T"))
5464 (match_operand:DI 1 "register_operand" "0,0"))
5465 (const_int 0)))
5466 (set (match_operand:DI 0 "register_operand" "=d,d")
5467 (plus:DI (zero_extend:DI (match_dup 2)) (match_dup 1)))]
5468 "s390_match_ccmode (insn, CCLmode) && TARGET_ZARCH"
5469 "@
5470 algfr\t%0,%2
5471 algf\t%0,%2"
5472 [(set_attr "op_type" "RRE,RXY")
5473 (set_attr "z10prop" "z10_super_E1,z10_super_E1")])
5474
5475 (define_insn "*adddi3_zero_cconly"
5476 [(set (reg CC_REGNUM)
5477 (compare (plus:DI (zero_extend:DI (match_operand:SI 2 "general_operand" "d,T"))
5478 (match_operand:DI 1 "register_operand" "0,0"))
5479 (const_int 0)))
5480 (clobber (match_scratch:DI 0 "=d,d"))]
5481 "s390_match_ccmode (insn, CCLmode) && TARGET_ZARCH"
5482 "@
5483 algfr\t%0,%2
5484 algf\t%0,%2"
5485 [(set_attr "op_type" "RRE,RXY")
5486 (set_attr "z10prop" "z10_super_E1,z10_super_E1")])
5487
5488 (define_insn "*adddi3_zero"
5489 [(set (match_operand:DI 0 "register_operand" "=d,d")
5490 (plus:DI (zero_extend:DI (match_operand:SI 2 "general_operand" "d,T"))
5491 (match_operand:DI 1 "register_operand" "0,0")))
5492 (clobber (reg:CC CC_REGNUM))]
5493 "TARGET_ZARCH"
5494 "@
5495 algfr\t%0,%2
5496 algf\t%0,%2"
5497 [(set_attr "op_type" "RRE,RXY")
5498 (set_attr "z10prop" "z10_super_E1,z10_super_E1")])
5499
5500 (define_insn_and_split "*adddi3_31z"
5501 [(set (match_operand:DI 0 "nonimmediate_operand" "=&d")
5502 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
5503 (match_operand:DI 2 "general_operand" "do") ) )
5504 (clobber (reg:CC CC_REGNUM))]
5505 "!TARGET_ZARCH && TARGET_CPU_ZARCH"
5506 "#"
5507 "&& reload_completed"
5508 [(parallel
5509 [(set (reg:CCL1 CC_REGNUM)
5510 (compare:CCL1 (plus:SI (match_dup 7) (match_dup 8))
5511 (match_dup 7)))
5512 (set (match_dup 6) (plus:SI (match_dup 7) (match_dup 8)))])
5513 (parallel
5514 [(set (match_dup 3) (plus:SI
5515 (plus:SI (ltu:SI (reg:CCL1 CC_REGNUM) (const_int 0))
5516 (match_dup 4)) (match_dup 5)))
5517 (clobber (reg:CC CC_REGNUM))])]
5518 "operands[3] = operand_subword (operands[0], 0, 0, DImode);
5519 operands[4] = operand_subword (operands[1], 0, 0, DImode);
5520 operands[5] = operand_subword (operands[2], 0, 0, DImode);
5521 operands[6] = operand_subword (operands[0], 1, 0, DImode);
5522 operands[7] = operand_subword (operands[1], 1, 0, DImode);
5523 operands[8] = operand_subword (operands[2], 1, 0, DImode);")
5524
5525 (define_insn_and_split "*adddi3_31"
5526 [(set (match_operand:DI 0 "nonimmediate_operand" "=&d")
5527 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
5528 (match_operand:DI 2 "general_operand" "do") ) )
5529 (clobber (reg:CC CC_REGNUM))]
5530 "!TARGET_CPU_ZARCH"
5531 "#"
5532 "&& reload_completed"
5533 [(parallel
5534 [(set (match_dup 3) (plus:SI (match_dup 4) (match_dup 5)))
5535 (clobber (reg:CC CC_REGNUM))])
5536 (parallel
5537 [(set (reg:CCL1 CC_REGNUM)
5538 (compare:CCL1 (plus:SI (match_dup 7) (match_dup 8))
5539 (match_dup 7)))
5540 (set (match_dup 6) (plus:SI (match_dup 7) (match_dup 8)))])
5541 (set (pc)
5542 (if_then_else (ltu (reg:CCL1 CC_REGNUM) (const_int 0))
5543 (pc)
5544 (label_ref (match_dup 9))))
5545 (parallel
5546 [(set (match_dup 3) (plus:SI (match_dup 3) (const_int 1)))
5547 (clobber (reg:CC CC_REGNUM))])
5548 (match_dup 9)]
5549 "operands[3] = operand_subword (operands[0], 0, 0, DImode);
5550 operands[4] = operand_subword (operands[1], 0, 0, DImode);
5551 operands[5] = operand_subword (operands[2], 0, 0, DImode);
5552 operands[6] = operand_subword (operands[0], 1, 0, DImode);
5553 operands[7] = operand_subword (operands[1], 1, 0, DImode);
5554 operands[8] = operand_subword (operands[2], 1, 0, DImode);
5555 operands[9] = gen_label_rtx ();")
5556
5557 ;
5558 ; addsi3 instruction pattern(s).
5559 ;
5560
5561 (define_expand "addsi3"
5562 [(parallel
5563 [(set (match_operand:SI 0 "nonimmediate_operand" "")
5564 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "")
5565 (match_operand:SI 2 "general_operand" "")))
5566 (clobber (reg:CC CC_REGNUM))])]
5567 ""
5568 "")
5569
5570 (define_insn "*addsi3_sign"
5571 [(set (match_operand:SI 0 "register_operand" "=d,d")
5572 (plus:SI (sign_extend:SI (match_operand:HI 2 "memory_operand" "R,T"))
5573 (match_operand:SI 1 "register_operand" "0,0")))
5574 (clobber (reg:CC CC_REGNUM))]
5575 ""
5576 "@
5577 ah\t%0,%2
5578 ahy\t%0,%2"
5579 [(set_attr "op_type" "RX,RXY")
5580 (set_attr "cpu_facility" "*,longdisp")
5581 (set_attr "z196prop" "z196_cracked,z196_cracked")])
5582
5583 ;
5584 ; add(di|si)3 instruction pattern(s).
5585 ;
5586
5587 ; ark, agrk, ar, ahi, ahik, aghik, alfi, slfi, a, ay, agr, aghi, algfi, slgfi, ag, asi, agsi
5588 (define_insn "*add<mode>3"
5589 [(set (match_operand:GPR 0 "nonimmediate_operand" "=d,d,d,d, d, d,d,d,S")
5590 (plus:GPR (match_operand:GPR 1 "nonimmediate_operand" "%0,d,0,d, 0, 0,0,0,0")
5591 (match_operand:GPR 2 "general_operand" " d,d,K,K,Op,On,R,T,C") ) )
5592 (clobber (reg:CC CC_REGNUM))]
5593 ""
5594 "@
5595 a<g>r\t%0,%2
5596 a<g>rk\t%0,%1,%2
5597 a<g>hi\t%0,%h2
5598 a<g>hik\t%0,%1,%h2
5599 al<g>fi\t%0,%2
5600 sl<g>fi\t%0,%n2
5601 a<g>\t%0,%2
5602 a<y>\t%0,%2
5603 a<g>si\t%0,%c2"
5604 [(set_attr "op_type" "RR<E>,RRF,RI,RIE,RIL,RIL,RX<Y>,RXY,SIY")
5605 (set_attr "cpu_facility" "*,z196,*,z196,extimm,extimm,*,longdisp,z10")
5606 (set_attr "z10prop" "z10_super_E1,*,z10_super_E1,*,z10_super_E1,z10_super_E1,
5607 z10_super_E1,z10_super_E1,z10_super_E1")])
5608
5609 ; alr, alfi, slfi, al, aly, alrk, alhsik, algr, algfi, slgfi, alg, alsi, algsi, algrk, alghsik
5610 (define_insn "*add<mode>3_carry1_cc"
5611 [(set (reg CC_REGNUM)
5612 (compare (plus:GPR (match_operand:GPR 1 "nonimmediate_operand" "%0,d, 0, 0,d,0,0,0")
5613 (match_operand:GPR 2 "general_operand" " d,d,Op,On,K,R,T,C"))
5614 (match_dup 1)))
5615 (set (match_operand:GPR 0 "nonimmediate_operand" "=d,d, d, d,d,d,d,d")
5616 (plus:GPR (match_dup 1) (match_dup 2)))]
5617 "s390_match_ccmode (insn, CCL1mode)"
5618 "@
5619 al<g>r\t%0,%2
5620 al<g>rk\t%0,%1,%2
5621 al<g>fi\t%0,%2
5622 sl<g>fi\t%0,%n2
5623 al<g>hsik\t%0,%1,%h2
5624 al<g>\t%0,%2
5625 al<y>\t%0,%2
5626 al<g>si\t%0,%c2"
5627 [(set_attr "op_type" "RR<E>,RRF,RIL,RIL,RIE,RX<Y>,RXY,SIY")
5628 (set_attr "cpu_facility" "*,z196,extimm,extimm,z196,*,longdisp,z10")
5629 (set_attr "z10prop" "z10_super_E1,*,z10_super_E1,z10_super_E1,*,
5630 z10_super_E1,z10_super_E1,z10_super_E1")])
5631
5632 ; alr, al, aly, algr, alg, alrk, algrk
5633 (define_insn "*add<mode>3_carry1_cconly"
5634 [(set (reg CC_REGNUM)
5635 (compare (plus:GPR (match_operand:GPR 1 "nonimmediate_operand" "%0,d,0,0")
5636 (match_operand:GPR 2 "general_operand" "d,d,R,T"))
5637 (match_dup 1)))
5638 (clobber (match_scratch:GPR 0 "=d,d,d,d"))]
5639 "s390_match_ccmode (insn, CCL1mode)"
5640 "@
5641 al<g>r\t%0,%2
5642 al<g>rk\t%0,%1,%2
5643 al<g>\t%0,%2
5644 al<y>\t%0,%2"
5645 [(set_attr "op_type" "RR<E>,RRF,RX<Y>,RXY")
5646 (set_attr "cpu_facility" "*,z196,*,longdisp")
5647 (set_attr "z10prop" "z10_super_E1,*,z10_super_E1,z10_super_E1")])
5648
5649 ; alr, alfi, slfi, al, aly, algr, algfi, slgfi, alg, alsi, algsi, alrk, algrk, alhsik, alghsik
5650 (define_insn "*add<mode>3_carry2_cc"
5651 [(set (reg CC_REGNUM)
5652 (compare (plus:GPR (match_operand:GPR 1 "nonimmediate_operand" "%0,d, 0, 0,d,0,0,0")
5653 (match_operand:GPR 2 "general_operand" " d,d,Op,On,K,R,T,C"))
5654 (match_dup 2)))
5655 (set (match_operand:GPR 0 "nonimmediate_operand" "=d,d, d, d,d,d,d,S")
5656 (plus:GPR (match_dup 1) (match_dup 2)))]
5657 "s390_match_ccmode (insn, CCL1mode)"
5658 "@
5659 al<g>r\t%0,%2
5660 al<g>rk\t%0,%1,%2
5661 al<g>fi\t%0,%2
5662 sl<g>fi\t%0,%n2
5663 al<g>hsik\t%0,%1,%h2
5664 al<g>\t%0,%2
5665 al<y>\t%0,%2
5666 al<g>si\t%0,%c2"
5667 [(set_attr "op_type" "RR<E>,RRF,RIL,RIL,RIE,RX<Y>,RXY,SIY")
5668 (set_attr "cpu_facility" "*,z196,extimm,extimm,z196,*,longdisp,z10")
5669 (set_attr "z10prop" "z10_super_E1,*,z10_super_E1,z10_super_E1,*,
5670 z10_super_E1,z10_super_E1,z10_super_E1")])
5671
5672 ; alr, al, aly, algr, alg, alrk, algrk
5673 (define_insn "*add<mode>3_carry2_cconly"
5674 [(set (reg CC_REGNUM)
5675 (compare (plus:GPR (match_operand:GPR 1 "nonimmediate_operand" "%0,d,0,0")
5676 (match_operand:GPR 2 "general_operand" "d,d,R,T"))
5677 (match_dup 2)))
5678 (clobber (match_scratch:GPR 0 "=d,d,d,d"))]
5679 "s390_match_ccmode (insn, CCL1mode)"
5680 "@
5681 al<g>r\t%0,%2
5682 al<g>rk\t%0,%1,%2
5683 al<g>\t%0,%2
5684 al<y>\t%0,%2"
5685 [(set_attr "op_type" "RR<E>,RRF,RX<Y>,RXY")
5686 (set_attr "cpu_facility" "*,z196,*,longdisp")
5687 (set_attr "z10prop" "z10_super_E1,*,z10_super_E1,z10_super_E1")])
5688
5689 ; alr, alfi, slfi, al, aly, algr, algfi, slgfi, alg, alsi, algsi, alrk, algrk, alhsik, alghsik
5690 (define_insn "*add<mode>3_cc"
5691 [(set (reg CC_REGNUM)
5692 (compare (plus:GPR (match_operand:GPR 1 "nonimmediate_operand" "%0,d, 0, 0,d,0,0,0")
5693 (match_operand:GPR 2 "general_operand" " d,d,Op,On,K,R,T,C"))
5694 (const_int 0)))
5695 (set (match_operand:GPR 0 "nonimmediate_operand" "=d,d, d, d,d,d,d,S")
5696 (plus:GPR (match_dup 1) (match_dup 2)))]
5697 "s390_match_ccmode (insn, CCLmode)"
5698 "@
5699 al<g>r\t%0,%2
5700 al<g>rk\t%0,%1,%2
5701 al<g>fi\t%0,%2
5702 sl<g>fi\t%0,%n2
5703 al<g>hsik\t%0,%1,%h2
5704 al<g>\t%0,%2
5705 al<y>\t%0,%2
5706 al<g>si\t%0,%c2"
5707 [(set_attr "op_type" "RR<E>,RRF,RIL,RIL,RIE,RX<Y>,RXY,SIY")
5708 (set_attr "cpu_facility" "*,z196,extimm,extimm,z196,*,longdisp,z10")
5709 (set_attr "z10prop" "z10_super_E1,*,z10_super_E1,z10_super_E1,
5710 *,z10_super_E1,z10_super_E1,z10_super_E1")])
5711
5712 ; alr, al, aly, algr, alg, alrk, algrk
5713 (define_insn "*add<mode>3_cconly"
5714 [(set (reg CC_REGNUM)
5715 (compare (plus:GPR (match_operand:GPR 1 "nonimmediate_operand" "%0,d,0,0")
5716 (match_operand:GPR 2 "general_operand" "d,d,R,T"))
5717 (const_int 0)))
5718 (clobber (match_scratch:GPR 0 "=d,d,d,d"))]
5719 "s390_match_ccmode (insn, CCLmode)"
5720 "@
5721 al<g>r\t%0,%2
5722 al<g>rk\t%0,%1,%2
5723 al<g>\t%0,%2
5724 al<y>\t%0,%2"
5725 [(set_attr "op_type" "RR<E>,RRF,RX<Y>,RXY")
5726 (set_attr "cpu_facility" "*,z196,*,longdisp")
5727 (set_attr "z10prop" "z10_super_E1,*,z10_super_E1,z10_super_E1")])
5728
5729 ; alr, al, aly, algr, alg, alrk, algrk
5730 (define_insn "*add<mode>3_cconly2"
5731 [(set (reg CC_REGNUM)
5732 (compare (match_operand:GPR 1 "nonimmediate_operand" "%0,d,0,0")
5733 (neg:GPR (match_operand:GPR 2 "general_operand" "d,d,R,T"))))
5734 (clobber (match_scratch:GPR 0 "=d,d,d,d"))]
5735 "s390_match_ccmode(insn, CCLmode)"
5736 "@
5737 al<g>r\t%0,%2
5738 al<g>rk\t%0,%1,%2
5739 al<g>\t%0,%2
5740 al<y>\t%0,%2"
5741 [(set_attr "op_type" "RR<E>,RRF,RX<Y>,RXY")
5742 (set_attr "cpu_facility" "*,z196,*,longdisp")
5743 (set_attr "z10prop" "z10_super_E1,*,z10_super_E1,z10_super_E1")])
5744
5745 ; ahi, afi, aghi, agfi, asi, agsi
5746 (define_insn "*add<mode>3_imm_cc"
5747 [(set (reg CC_REGNUM)
5748 (compare (plus:GPR (match_operand:GPR 1 "nonimmediate_operand" " 0, d,0, 0")
5749 (match_operand:GPR 2 "const_int_operand" " K, K,Os,C"))
5750 (const_int 0)))
5751 (set (match_operand:GPR 0 "nonimmediate_operand" "=d, d,d, S")
5752 (plus:GPR (match_dup 1) (match_dup 2)))]
5753 "s390_match_ccmode (insn, CCAmode)
5754 && (CONST_OK_FOR_CONSTRAINT_P (INTVAL (operands[2]), 'K', \"K\")
5755 || (CONST_OK_FOR_CONSTRAINT_P (INTVAL (operands[2]), 'O', \"Os\")
5756 /* Avoid INT32_MIN on 32 bit. */
5757 && (!TARGET_ZARCH || INTVAL (operands[2]) != -0x7fffffff - 1)))"
5758 "@
5759 a<g>hi\t%0,%h2
5760 a<g>hik\t%0,%1,%h2
5761 a<g>fi\t%0,%2
5762 a<g>si\t%0,%c2"
5763 [(set_attr "op_type" "RI,RIE,RIL,SIY")
5764 (set_attr "cpu_facility" "*,z196,extimm,z10")
5765 (set_attr "z10prop" "z10_super_E1,*,z10_super_E1,z10_super_E1")])
5766
5767 ;
5768 ; add(tf|df|sf|td|dd)3 instruction pattern(s).
5769 ;
5770
5771 ; axbr, adbr, aebr, axb, adb, aeb, adtr, axtr
5772 ; FIXME: wfadb does not clobber cc
5773 (define_insn "add<mode>3"
5774 [(set (match_operand:FP 0 "register_operand" "=f,f,f,v")
5775 (plus:FP (match_operand:FP 1 "nonimmediate_operand" "%f,0,0,v")
5776 (match_operand:FP 2 "general_operand" "f,f,R,v")))
5777 (clobber (reg:CC CC_REGNUM))]
5778 "TARGET_HARD_FLOAT"
5779 "@
5780 a<xde>tr\t%0,%1,%2
5781 a<xde>br\t%0,%2
5782 a<xde>b\t%0,%2
5783 wfadb\t%v0,%v1,%v2"
5784 [(set_attr "op_type" "RRF,RRE,RXE,VRR")
5785 (set_attr "type" "fsimp<mode>")
5786 (set_attr "cpu_facility" "*,*,*,vx")
5787 (set_attr "enabled" "<nBFP>,<nDFP>,<DSF>,<DFDI>")])
5788
5789 ; axbr, adbr, aebr, axb, adb, aeb, adtr, axtr
5790 (define_insn "*add<mode>3_cc"
5791 [(set (reg CC_REGNUM)
5792 (compare (plus:FP (match_operand:FP 1 "nonimmediate_operand" "%f,0,0")
5793 (match_operand:FP 2 "general_operand" "f,f,R"))
5794 (match_operand:FP 3 "const0_operand" "")))
5795 (set (match_operand:FP 0 "register_operand" "=f,f,f")
5796 (plus:FP (match_dup 1) (match_dup 2)))]
5797 "s390_match_ccmode (insn, CCSmode) && TARGET_HARD_FLOAT"
5798 "@
5799 a<xde>tr\t%0,%1,%2
5800 a<xde>br\t%0,%2
5801 a<xde>b\t%0,%2"
5802 [(set_attr "op_type" "RRF,RRE,RXE")
5803 (set_attr "type" "fsimp<mode>")
5804 (set_attr "enabled" "<nBFP>,<nDFP>,<DSF>")])
5805
5806 ; axbr, adbr, aebr, axb, adb, aeb, adtr, axtr
5807 (define_insn "*add<mode>3_cconly"
5808 [(set (reg CC_REGNUM)
5809 (compare (plus:FP (match_operand:FP 1 "nonimmediate_operand" "%f,0,0")
5810 (match_operand:FP 2 "general_operand" "f,f,R"))
5811 (match_operand:FP 3 "const0_operand" "")))
5812 (clobber (match_scratch:FP 0 "=f,f,f"))]
5813 "s390_match_ccmode (insn, CCSmode) && TARGET_HARD_FLOAT"
5814 "@
5815 a<xde>tr\t%0,%1,%2
5816 a<xde>br\t%0,%2
5817 a<xde>b\t%0,%2"
5818 [(set_attr "op_type" "RRF,RRE,RXE")
5819 (set_attr "type" "fsimp<mode>")
5820 (set_attr "enabled" "<nBFP>,<nDFP>,<DSF>")])
5821
5822 ;
5823 ; Pointer add instruction patterns
5824 ;
5825
5826 ; This will match "*la_64"
5827 (define_expand "addptrdi3"
5828 [(set (match_operand:DI 0 "register_operand" "")
5829 (plus:DI (match_operand:DI 1 "register_operand" "")
5830 (match_operand:DI 2 "nonmemory_operand" "")))]
5831 "TARGET_64BIT"
5832 {
5833 if (GET_CODE (operands[2]) == CONST_INT)
5834 {
5835 HOST_WIDE_INT c = INTVAL (operands[2]);
5836
5837 if (!CONST_OK_FOR_CONSTRAINT_P (c, 'K', "K")
5838 && !CONST_OK_FOR_CONSTRAINT_P (c, 'O', "Os"))
5839 {
5840 operands[2] = force_const_mem (DImode, operands[2]);
5841 operands[2] = force_reg (DImode, operands[2]);
5842 }
5843 else if (!DISP_IN_RANGE (INTVAL (operands[2])))
5844 operands[2] = force_reg (DImode, operands[2]);
5845 }
5846 })
5847
5848 ; For 31 bit we have to prevent the generated pattern from matching
5849 ; normal ADDs since la only does a 31 bit add. This is supposed to
5850 ; match "force_la_31".
5851 (define_expand "addptrsi3"
5852 [(parallel
5853 [(set (match_operand:SI 0 "register_operand" "")
5854 (plus:SI (match_operand:SI 1 "register_operand" "")
5855 (match_operand:SI 2 "nonmemory_operand" "")))
5856 (use (const_int 0))])]
5857 "!TARGET_64BIT"
5858 {
5859 if (GET_CODE (operands[2]) == CONST_INT)
5860 {
5861 HOST_WIDE_INT c = INTVAL (operands[2]);
5862
5863 if (!CONST_OK_FOR_CONSTRAINT_P (c, 'K', "K")
5864 && !CONST_OK_FOR_CONSTRAINT_P (c, 'O', "Os"))
5865 {
5866 operands[2] = force_const_mem (SImode, operands[2]);
5867 operands[2] = force_reg (SImode, operands[2]);
5868 }
5869 else if (!DISP_IN_RANGE (INTVAL (operands[2])))
5870 operands[2] = force_reg (SImode, operands[2]);
5871 }
5872 })
5873
5874 ;;
5875 ;;- Subtract instructions.
5876 ;;
5877
5878 ;
5879 ; subti3 instruction pattern(s).
5880 ;
5881
5882 (define_expand "subti3"
5883 [(parallel
5884 [(set (match_operand:TI 0 "register_operand" "")
5885 (minus:TI (match_operand:TI 1 "register_operand" "")
5886 (match_operand:TI 2 "general_operand" "") ) )
5887 (clobber (reg:CC CC_REGNUM))])]
5888 "TARGET_ZARCH"
5889 {
5890 /* For z13 we have vsq which doesn't set CC. */
5891 if (TARGET_VX)
5892 {
5893 emit_insn (gen_rtx_SET (operands[0],
5894 gen_rtx_MINUS (TImode,
5895 operands[1],
5896 copy_to_mode_reg (TImode, operands[2]))));
5897 DONE;
5898 }
5899 })
5900
5901 (define_insn_and_split "*subti3"
5902 [(set (match_operand:TI 0 "register_operand" "=&d")
5903 (minus:TI (match_operand:TI 1 "register_operand" "0")
5904 (match_operand:TI 2 "general_operand" "do") ) )
5905 (clobber (reg:CC CC_REGNUM))]
5906 "TARGET_ZARCH"
5907 "#"
5908 "&& reload_completed"
5909 [(parallel
5910 [(set (reg:CCL2 CC_REGNUM)
5911 (compare:CCL2 (minus:DI (match_dup 7) (match_dup 8))
5912 (match_dup 7)))
5913 (set (match_dup 6) (minus:DI (match_dup 7) (match_dup 8)))])
5914 (parallel
5915 [(set (match_dup 3) (minus:DI (minus:DI (match_dup 4) (match_dup 5))
5916 (gtu:DI (reg:CCL2 CC_REGNUM) (const_int 0))))
5917 (clobber (reg:CC CC_REGNUM))])]
5918 "operands[3] = operand_subword (operands[0], 0, 0, TImode);
5919 operands[4] = operand_subword (operands[1], 0, 0, TImode);
5920 operands[5] = operand_subword (operands[2], 0, 0, TImode);
5921 operands[6] = operand_subword (operands[0], 1, 0, TImode);
5922 operands[7] = operand_subword (operands[1], 1, 0, TImode);
5923 operands[8] = operand_subword (operands[2], 1, 0, TImode);"
5924 [(set_attr "op_type" "*")
5925 (set_attr "cpu_facility" "*")])
5926
5927 ;
5928 ; subdi3 instruction pattern(s).
5929 ;
5930
5931 (define_expand "subdi3"
5932 [(parallel
5933 [(set (match_operand:DI 0 "register_operand" "")
5934 (minus:DI (match_operand:DI 1 "register_operand" "")
5935 (match_operand:DI 2 "general_operand" "")))
5936 (clobber (reg:CC CC_REGNUM))])]
5937 ""
5938 "")
5939
5940 (define_insn "*subdi3_sign"
5941 [(set (match_operand:DI 0 "register_operand" "=d,d")
5942 (minus:DI (match_operand:DI 1 "register_operand" "0,0")
5943 (sign_extend:DI (match_operand:SI 2 "general_operand" "d,T"))))
5944 (clobber (reg:CC CC_REGNUM))]
5945 "TARGET_ZARCH"
5946 "@
5947 sgfr\t%0,%2
5948 sgf\t%0,%2"
5949 [(set_attr "op_type" "RRE,RXY")
5950 (set_attr "z10prop" "z10_c,*")
5951 (set_attr "z196prop" "z196_cracked")])
5952
5953 (define_insn "*subdi3_zero_cc"
5954 [(set (reg CC_REGNUM)
5955 (compare (minus:DI (match_operand:DI 1 "register_operand" "0,0")
5956 (zero_extend:DI (match_operand:SI 2 "general_operand" "d,T")))
5957 (const_int 0)))
5958 (set (match_operand:DI 0 "register_operand" "=d,d")
5959 (minus:DI (match_dup 1) (zero_extend:DI (match_dup 2))))]
5960 "s390_match_ccmode (insn, CCLmode) && TARGET_ZARCH"
5961 "@
5962 slgfr\t%0,%2
5963 slgf\t%0,%2"
5964 [(set_attr "op_type" "RRE,RXY")
5965 (set_attr "z10prop" "z10_super_c_E1,z10_super_E1")])
5966
5967 (define_insn "*subdi3_zero_cconly"
5968 [(set (reg CC_REGNUM)
5969 (compare (minus:DI (match_operand:DI 1 "register_operand" "0,0")
5970 (zero_extend:DI (match_operand:SI 2 "general_operand" "d,T")))
5971 (const_int 0)))
5972 (clobber (match_scratch:DI 0 "=d,d"))]
5973 "s390_match_ccmode (insn, CCLmode) && TARGET_ZARCH"
5974 "@
5975 slgfr\t%0,%2
5976 slgf\t%0,%2"
5977 [(set_attr "op_type" "RRE,RXY")
5978 (set_attr "z10prop" "z10_super_c_E1,z10_super_E1")])
5979
5980 (define_insn "*subdi3_zero"
5981 [(set (match_operand:DI 0 "register_operand" "=d,d")
5982 (minus:DI (match_operand:DI 1 "register_operand" "0,0")
5983 (zero_extend:DI (match_operand:SI 2 "general_operand" "d,T"))))
5984 (clobber (reg:CC CC_REGNUM))]
5985 "TARGET_ZARCH"
5986 "@
5987 slgfr\t%0,%2
5988 slgf\t%0,%2"
5989 [(set_attr "op_type" "RRE,RXY")
5990 (set_attr "z10prop" "z10_super_c_E1,z10_super_E1")])
5991
5992 (define_insn_and_split "*subdi3_31z"
5993 [(set (match_operand:DI 0 "register_operand" "=&d")
5994 (minus:DI (match_operand:DI 1 "register_operand" "0")
5995 (match_operand:DI 2 "general_operand" "do") ) )
5996 (clobber (reg:CC CC_REGNUM))]
5997 "!TARGET_ZARCH && TARGET_CPU_ZARCH"
5998 "#"
5999 "&& reload_completed"
6000 [(parallel
6001 [(set (reg:CCL2 CC_REGNUM)
6002 (compare:CCL2 (minus:SI (match_dup 7) (match_dup 8))
6003 (match_dup 7)))
6004 (set (match_dup 6) (minus:SI (match_dup 7) (match_dup 8)))])
6005 (parallel
6006 [(set (match_dup 3) (minus:SI (minus:SI (match_dup 4) (match_dup 5))
6007 (gtu:SI (reg:CCL2 CC_REGNUM) (const_int 0))))
6008 (clobber (reg:CC CC_REGNUM))])]
6009 "operands[3] = operand_subword (operands[0], 0, 0, DImode);
6010 operands[4] = operand_subword (operands[1], 0, 0, DImode);
6011 operands[5] = operand_subword (operands[2], 0, 0, DImode);
6012 operands[6] = operand_subword (operands[0], 1, 0, DImode);
6013 operands[7] = operand_subword (operands[1], 1, 0, DImode);
6014 operands[8] = operand_subword (operands[2], 1, 0, DImode);")
6015
6016 (define_insn_and_split "*subdi3_31"
6017 [(set (match_operand:DI 0 "register_operand" "=&d")
6018 (minus:DI (match_operand:DI 1 "register_operand" "0")
6019 (match_operand:DI 2 "general_operand" "do") ) )
6020 (clobber (reg:CC CC_REGNUM))]
6021 "!TARGET_CPU_ZARCH"
6022 "#"
6023 "&& reload_completed"
6024 [(parallel
6025 [(set (match_dup 3) (minus:SI (match_dup 4) (match_dup 5)))
6026 (clobber (reg:CC CC_REGNUM))])
6027 (parallel
6028 [(set (reg:CCL2 CC_REGNUM)
6029 (compare:CCL2 (minus:SI (match_dup 7) (match_dup 8))
6030 (match_dup 7)))
6031 (set (match_dup 6) (minus:SI (match_dup 7) (match_dup 8)))])
6032 (set (pc)
6033 (if_then_else (gtu (reg:CCL2 CC_REGNUM) (const_int 0))
6034 (pc)
6035 (label_ref (match_dup 9))))
6036 (parallel
6037 [(set (match_dup 3) (plus:SI (match_dup 3) (const_int -1)))
6038 (clobber (reg:CC CC_REGNUM))])
6039 (match_dup 9)]
6040 "operands[3] = operand_subword (operands[0], 0, 0, DImode);
6041 operands[4] = operand_subword (operands[1], 0, 0, DImode);
6042 operands[5] = operand_subword (operands[2], 0, 0, DImode);
6043 operands[6] = operand_subword (operands[0], 1, 0, DImode);
6044 operands[7] = operand_subword (operands[1], 1, 0, DImode);
6045 operands[8] = operand_subword (operands[2], 1, 0, DImode);
6046 operands[9] = gen_label_rtx ();")
6047
6048 ;
6049 ; subsi3 instruction pattern(s).
6050 ;
6051
6052 (define_expand "subsi3"
6053 [(parallel
6054 [(set (match_operand:SI 0 "register_operand" "")
6055 (minus:SI (match_operand:SI 1 "register_operand" "")
6056 (match_operand:SI 2 "general_operand" "")))
6057 (clobber (reg:CC CC_REGNUM))])]
6058 ""
6059 "")
6060
6061 (define_insn "*subsi3_sign"
6062 [(set (match_operand:SI 0 "register_operand" "=d,d")
6063 (minus:SI (match_operand:SI 1 "register_operand" "0,0")
6064 (sign_extend:SI (match_operand:HI 2 "memory_operand" "R,T"))))
6065 (clobber (reg:CC CC_REGNUM))]
6066 ""
6067 "@
6068 sh\t%0,%2
6069 shy\t%0,%2"
6070 [(set_attr "op_type" "RX,RXY")
6071 (set_attr "cpu_facility" "*,longdisp")
6072 (set_attr "z196prop" "z196_cracked,z196_cracked")])
6073
6074 ;
6075 ; sub(di|si)3 instruction pattern(s).
6076 ;
6077
6078 ; sr, s, sy, sgr, sg, srk, sgrk
6079 (define_insn "*sub<mode>3"
6080 [(set (match_operand:GPR 0 "register_operand" "=d,d,d,d")
6081 (minus:GPR (match_operand:GPR 1 "register_operand" "0,d,0,0")
6082 (match_operand:GPR 2 "general_operand" "d,d,R,T") ) )
6083 (clobber (reg:CC CC_REGNUM))]
6084 ""
6085 "@
6086 s<g>r\t%0,%2
6087 s<g>rk\t%0,%1,%2
6088 s<g>\t%0,%2
6089 s<y>\t%0,%2"
6090 [(set_attr "op_type" "RR<E>,RRF,RX<Y>,RXY")
6091 (set_attr "cpu_facility" "*,z196,*,longdisp")
6092 (set_attr "z10prop" "z10_super_c_E1,*,z10_super_E1,z10_super_E1")])
6093
6094 ; slr, sl, sly, slgr, slg, slrk, slgrk
6095 (define_insn "*sub<mode>3_borrow_cc"
6096 [(set (reg CC_REGNUM)
6097 (compare (minus:GPR (match_operand:GPR 1 "register_operand" "0,d,0,0")
6098 (match_operand:GPR 2 "general_operand" "d,d,R,T"))
6099 (match_dup 1)))
6100 (set (match_operand:GPR 0 "register_operand" "=d,d,d,d")
6101 (minus:GPR (match_dup 1) (match_dup 2)))]
6102 "s390_match_ccmode (insn, CCL2mode)"
6103 "@
6104 sl<g>r\t%0,%2
6105 sl<g>rk\t%0,%1,%2
6106 sl<g>\t%0,%2
6107 sl<y>\t%0,%2"
6108 [(set_attr "op_type" "RR<E>,RRF,RX<Y>,RXY")
6109 (set_attr "cpu_facility" "*,z196,*,longdisp")
6110 (set_attr "z10prop" "z10_super_c_E1,*,z10_super_E1,z10_super_E1")])
6111
6112 ; slr, sl, sly, slgr, slg, slrk, slgrk
6113 (define_insn "*sub<mode>3_borrow_cconly"
6114 [(set (reg CC_REGNUM)
6115 (compare (minus:GPR (match_operand:GPR 1 "register_operand" "0,d,0,0")
6116 (match_operand:GPR 2 "general_operand" "d,d,R,T"))
6117 (match_dup 1)))
6118 (clobber (match_scratch:GPR 0 "=d,d,d,d"))]
6119 "s390_match_ccmode (insn, CCL2mode)"
6120 "@
6121 sl<g>r\t%0,%2
6122 sl<g>rk\t%0,%1,%2
6123 sl<g>\t%0,%2
6124 sl<y>\t%0,%2"
6125 [(set_attr "op_type" "RR<E>,RRF,RX<Y>,RXY")
6126 (set_attr "cpu_facility" "*,z196,*,longdisp")
6127 (set_attr "z10prop" "z10_super_c_E1,*,z10_super_E1,z10_super_E1")])
6128
6129 ; slr, sl, sly, slgr, slg, slrk, slgrk
6130 (define_insn "*sub<mode>3_cc"
6131 [(set (reg CC_REGNUM)
6132 (compare (minus:GPR (match_operand:GPR 1 "register_operand" "0,d,0,0")
6133 (match_operand:GPR 2 "general_operand" "d,d,R,T"))
6134 (const_int 0)))
6135 (set (match_operand:GPR 0 "register_operand" "=d,d,d,d")
6136 (minus:GPR (match_dup 1) (match_dup 2)))]
6137 "s390_match_ccmode (insn, CCLmode)"
6138 "@
6139 sl<g>r\t%0,%2
6140 sl<g>rk\t%0,%1,%2
6141 sl<g>\t%0,%2
6142 sl<y>\t%0,%2"
6143 [(set_attr "op_type" "RR<E>,RRF,RX<Y>,RXY")
6144 (set_attr "cpu_facility" "*,z196,*,longdisp")
6145 (set_attr "z10prop" "z10_super_c_E1,*,z10_super_E1,z10_super_E1")])
6146
6147 ; slr, sl, sly, slgr, slg, slrk, slgrk
6148 (define_insn "*sub<mode>3_cc2"
6149 [(set (reg CC_REGNUM)
6150 (compare (match_operand:GPR 1 "register_operand" "0,d,0,0")
6151 (match_operand:GPR 2 "general_operand" "d,d,R,T")))
6152 (set (match_operand:GPR 0 "register_operand" "=d,d,d,d")
6153 (minus:GPR (match_dup 1) (match_dup 2)))]
6154 "s390_match_ccmode (insn, CCL3mode)"
6155 "@
6156 sl<g>r\t%0,%2
6157 sl<g>rk\t%0,%1,%2
6158 sl<g>\t%0,%2
6159 sl<y>\t%0,%2"
6160 [(set_attr "op_type" "RR<E>,RRF,RX<Y>,RXY")
6161 (set_attr "cpu_facility" "*,z196,*,longdisp")
6162 (set_attr "z10prop" "z10_super_c_E1,*,z10_super_E1,z10_super_E1")])
6163
6164 ; slr, sl, sly, slgr, slg, slrk, slgrk
6165 (define_insn "*sub<mode>3_cconly"
6166 [(set (reg CC_REGNUM)
6167 (compare (minus:GPR (match_operand:GPR 1 "register_operand" "0,d,0,0")
6168 (match_operand:GPR 2 "general_operand" "d,d,R,T"))
6169 (const_int 0)))
6170 (clobber (match_scratch:GPR 0 "=d,d,d,d"))]
6171 "s390_match_ccmode (insn, CCLmode)"
6172 "@
6173 sl<g>r\t%0,%2
6174 sl<g>rk\t%0,%1,%2
6175 sl<g>\t%0,%2
6176 sl<y>\t%0,%2"
6177 [(set_attr "op_type" "RR<E>,RRF,RX<Y>,RXY")
6178 (set_attr "cpu_facility" "*,z196,*,longdisp")
6179 (set_attr "z10prop" "z10_super_c_E1,*,z10_super_E1,z10_super_E1")])
6180
6181
6182 ; slr, sl, sly, slgr, slg, slrk, slgrk
6183 (define_insn "*sub<mode>3_cconly2"
6184 [(set (reg CC_REGNUM)
6185 (compare (match_operand:GPR 1 "register_operand" "0,d,0,0")
6186 (match_operand:GPR 2 "general_operand" "d,d,R,T")))
6187 (clobber (match_scratch:GPR 0 "=d,d,d,d"))]
6188 "s390_match_ccmode (insn, CCL3mode)"
6189 "@
6190 sl<g>r\t%0,%2
6191 sl<g>rk\t%0,%1,%2
6192 sl<g>\t%0,%2
6193 sl<y>\t%0,%2"
6194 [(set_attr "op_type" "RR<E>,RRF,RX<Y>,RXY")
6195 (set_attr "cpu_facility" "*,z196,*,longdisp")
6196 (set_attr "z10prop" "z10_super_c_E1,*,z10_super_E1,z10_super_E1")])
6197
6198
6199 ;
6200 ; sub(tf|df|sf|td|dd)3 instruction pattern(s).
6201 ;
6202
6203 ; sxbr, sdbr, sebr, sdb, seb, sxtr, sdtr
6204 (define_insn "sub<mode>3"
6205 [(set (match_operand:FP 0 "register_operand" "=f,f,f,v")
6206 (minus:FP (match_operand:FP 1 "register_operand" "f,0,0,v")
6207 (match_operand:FP 2 "general_operand" "f,f,R,v")))
6208 (clobber (reg:CC CC_REGNUM))]
6209 "TARGET_HARD_FLOAT"
6210 "@
6211 s<xde>tr\t%0,%1,%2
6212 s<xde>br\t%0,%2
6213 s<xde>b\t%0,%2
6214 wfsdb\t%v0,%v1,%v2"
6215 [(set_attr "op_type" "RRF,RRE,RXE,VRR")
6216 (set_attr "type" "fsimp<mode>")
6217 (set_attr "cpu_facility" "*,*,*,vx")
6218 (set_attr "enabled" "<nBFP>,<nDFP>,<DSF>,<DFDI>")])
6219
6220 ; sxbr, sdbr, sebr, sdb, seb, sxtr, sdtr
6221 (define_insn "*sub<mode>3_cc"
6222 [(set (reg CC_REGNUM)
6223 (compare (minus:FP (match_operand:FP 1 "nonimmediate_operand" "f,0,0")
6224 (match_operand:FP 2 "general_operand" "f,f,R"))
6225 (match_operand:FP 3 "const0_operand" "")))
6226 (set (match_operand:FP 0 "register_operand" "=f,f,f")
6227 (minus:FP (match_dup 1) (match_dup 2)))]
6228 "s390_match_ccmode (insn, CCSmode) && TARGET_HARD_FLOAT"
6229 "@
6230 s<xde>tr\t%0,%1,%2
6231 s<xde>br\t%0,%2
6232 s<xde>b\t%0,%2"
6233 [(set_attr "op_type" "RRF,RRE,RXE")
6234 (set_attr "type" "fsimp<mode>")
6235 (set_attr "enabled" "<nBFP>,<nDFP>,<DSF>")])
6236
6237 ; sxbr, sdbr, sebr, sdb, seb, sxtr, sdtr
6238 (define_insn "*sub<mode>3_cconly"
6239 [(set (reg CC_REGNUM)
6240 (compare (minus:FP (match_operand:FP 1 "nonimmediate_operand" "f,0,0")
6241 (match_operand:FP 2 "general_operand" "f,f,R"))
6242 (match_operand:FP 3 "const0_operand" "")))
6243 (clobber (match_scratch:FP 0 "=f,f,f"))]
6244 "s390_match_ccmode (insn, CCSmode) && TARGET_HARD_FLOAT"
6245 "@
6246 s<xde>tr\t%0,%1,%2
6247 s<xde>br\t%0,%2
6248 s<xde>b\t%0,%2"
6249 [(set_attr "op_type" "RRF,RRE,RXE")
6250 (set_attr "type" "fsimp<mode>")
6251 (set_attr "enabled" "<nBFP>,<nDFP>,<DSF>")])
6252
6253
6254 ;;
6255 ;;- Conditional add/subtract instructions.
6256 ;;
6257
6258 ;
6259 ; add(di|si)cc instruction pattern(s).
6260 ;
6261
6262 ; the following 4 patterns are used when the result of an add with
6263 ; carry is checked for an overflow condition
6264
6265 ; op1 + op2 + c < op1
6266
6267 ; alcr, alc, alcgr, alcg
6268 (define_insn "*add<mode>3_alc_carry1_cc"
6269 [(set (reg CC_REGNUM)
6270 (compare
6271 (plus:GPR (plus:GPR (match_operand:GPR 3 "s390_alc_comparison" "")
6272 (match_operand:GPR 1 "nonimmediate_operand" "%0,0"))
6273 (match_operand:GPR 2 "general_operand" "d,T"))
6274 (match_dup 1)))
6275 (set (match_operand:GPR 0 "register_operand" "=d,d")
6276 (plus:GPR (plus:GPR (match_dup 3) (match_dup 1)) (match_dup 2)))]
6277 "s390_match_ccmode (insn, CCL1mode) && TARGET_CPU_ZARCH"
6278 "@
6279 alc<g>r\t%0,%2
6280 alc<g>\t%0,%2"
6281 [(set_attr "op_type" "RRE,RXY")
6282 (set_attr "z196prop" "z196_alone,z196_alone")])
6283
6284 ; alcr, alc, alcgr, alcg
6285 (define_insn "*add<mode>3_alc_carry1_cconly"
6286 [(set (reg CC_REGNUM)
6287 (compare
6288 (plus:GPR (plus:GPR (match_operand:GPR 3 "s390_alc_comparison" "")
6289 (match_operand:GPR 1 "nonimmediate_operand" "%0,0"))
6290 (match_operand:GPR 2 "general_operand" "d,T"))
6291 (match_dup 1)))
6292 (clobber (match_scratch:GPR 0 "=d,d"))]
6293 "s390_match_ccmode (insn, CCL1mode) && TARGET_CPU_ZARCH"
6294 "@
6295 alc<g>r\t%0,%2
6296 alc<g>\t%0,%2"
6297 [(set_attr "op_type" "RRE,RXY")
6298 (set_attr "z196prop" "z196_alone,z196_alone")])
6299
6300 ; op1 + op2 + c < op2
6301
6302 ; alcr, alc, alcgr, alcg
6303 (define_insn "*add<mode>3_alc_carry2_cc"
6304 [(set (reg CC_REGNUM)
6305 (compare
6306 (plus:GPR (plus:GPR (match_operand:GPR 3 "s390_alc_comparison" "")
6307 (match_operand:GPR 1 "nonimmediate_operand" "%0,0"))
6308 (match_operand:GPR 2 "general_operand" "d,T"))
6309 (match_dup 2)))
6310 (set (match_operand:GPR 0 "register_operand" "=d,d")
6311 (plus:GPR (plus:GPR (match_dup 3) (match_dup 1)) (match_dup 2)))]
6312 "s390_match_ccmode (insn, CCL1mode) && TARGET_CPU_ZARCH"
6313 "@
6314 alc<g>r\t%0,%2
6315 alc<g>\t%0,%2"
6316 [(set_attr "op_type" "RRE,RXY")])
6317
6318 ; alcr, alc, alcgr, alcg
6319 (define_insn "*add<mode>3_alc_carry2_cconly"
6320 [(set (reg CC_REGNUM)
6321 (compare
6322 (plus:GPR (plus:GPR (match_operand:GPR 3 "s390_alc_comparison" "")
6323 (match_operand:GPR 1 "nonimmediate_operand" "%0,0"))
6324 (match_operand:GPR 2 "general_operand" "d,T"))
6325 (match_dup 2)))
6326 (clobber (match_scratch:GPR 0 "=d,d"))]
6327 "s390_match_ccmode (insn, CCL1mode) && TARGET_CPU_ZARCH"
6328 "@
6329 alc<g>r\t%0,%2
6330 alc<g>\t%0,%2"
6331 [(set_attr "op_type" "RRE,RXY")])
6332
6333 ; alcr, alc, alcgr, alcg
6334 (define_insn "*add<mode>3_alc_cc"
6335 [(set (reg CC_REGNUM)
6336 (compare
6337 (plus:GPR (plus:GPR (match_operand:GPR 3 "s390_alc_comparison" "")
6338 (match_operand:GPR 1 "nonimmediate_operand" "%0,0"))
6339 (match_operand:GPR 2 "general_operand" "d,T"))
6340 (const_int 0)))
6341 (set (match_operand:GPR 0 "register_operand" "=d,d")
6342 (plus:GPR (plus:GPR (match_dup 3) (match_dup 1)) (match_dup 2)))]
6343 "s390_match_ccmode (insn, CCLmode) && TARGET_CPU_ZARCH"
6344 "@
6345 alc<g>r\t%0,%2
6346 alc<g>\t%0,%2"
6347 [(set_attr "op_type" "RRE,RXY")])
6348
6349 ; alcr, alc, alcgr, alcg
6350 (define_insn "*add<mode>3_alc"
6351 [(set (match_operand:GPR 0 "register_operand" "=d,d")
6352 (plus:GPR (plus:GPR (match_operand:GPR 3 "s390_alc_comparison" "")
6353 (match_operand:GPR 1 "nonimmediate_operand" "%0,0"))
6354 (match_operand:GPR 2 "general_operand" "d,T")))
6355 (clobber (reg:CC CC_REGNUM))]
6356 "TARGET_CPU_ZARCH"
6357 "@
6358 alc<g>r\t%0,%2
6359 alc<g>\t%0,%2"
6360 [(set_attr "op_type" "RRE,RXY")])
6361
6362 ; slbr, slb, slbgr, slbg
6363 (define_insn "*sub<mode>3_slb_cc"
6364 [(set (reg CC_REGNUM)
6365 (compare
6366 (minus:GPR (minus:GPR (match_operand:GPR 1 "nonimmediate_operand" "0,0")
6367 (match_operand:GPR 2 "general_operand" "d,T"))
6368 (match_operand:GPR 3 "s390_slb_comparison" ""))
6369 (const_int 0)))
6370 (set (match_operand:GPR 0 "register_operand" "=d,d")
6371 (minus:GPR (minus:GPR (match_dup 1) (match_dup 2)) (match_dup 3)))]
6372 "s390_match_ccmode (insn, CCLmode) && TARGET_CPU_ZARCH"
6373 "@
6374 slb<g>r\t%0,%2
6375 slb<g>\t%0,%2"
6376 [(set_attr "op_type" "RRE,RXY")
6377 (set_attr "z10prop" "z10_c,*")])
6378
6379 ; slbr, slb, slbgr, slbg
6380 (define_insn "*sub<mode>3_slb"
6381 [(set (match_operand:GPR 0 "register_operand" "=d,d")
6382 (minus:GPR (minus:GPR (match_operand:GPR 1 "nonimmediate_operand" "0,0")
6383 (match_operand:GPR 2 "general_operand" "d,T"))
6384 (match_operand:GPR 3 "s390_slb_comparison" "")))
6385 (clobber (reg:CC CC_REGNUM))]
6386 "TARGET_CPU_ZARCH"
6387 "@
6388 slb<g>r\t%0,%2
6389 slb<g>\t%0,%2"
6390 [(set_attr "op_type" "RRE,RXY")
6391 (set_attr "z10prop" "z10_c,*")])
6392
6393 (define_expand "add<mode>cc"
6394 [(match_operand:GPR 0 "register_operand" "")
6395 (match_operand 1 "comparison_operator" "")
6396 (match_operand:GPR 2 "register_operand" "")
6397 (match_operand:GPR 3 "const_int_operand" "")]
6398 "TARGET_CPU_ZARCH"
6399 "if (!s390_expand_addcc (GET_CODE (operands[1]),
6400 XEXP (operands[1], 0), XEXP (operands[1], 1),
6401 operands[0], operands[2],
6402 operands[3])) FAIL; DONE;")
6403
6404 ;
6405 ; scond instruction pattern(s).
6406 ;
6407
6408 (define_insn_and_split "*scond<mode>"
6409 [(set (match_operand:GPR 0 "register_operand" "=&d")
6410 (match_operand:GPR 1 "s390_alc_comparison" ""))
6411 (clobber (reg:CC CC_REGNUM))]
6412 "TARGET_CPU_ZARCH"
6413 "#"
6414 "&& reload_completed"
6415 [(set (match_dup 0) (const_int 0))
6416 (parallel
6417 [(set (match_dup 0) (plus:GPR (plus:GPR (match_dup 1) (match_dup 0))
6418 (match_dup 0)))
6419 (clobber (reg:CC CC_REGNUM))])]
6420 "")
6421
6422 (define_insn_and_split "*scond<mode>_neg"
6423 [(set (match_operand:GPR 0 "register_operand" "=&d")
6424 (match_operand:GPR 1 "s390_slb_comparison" ""))
6425 (clobber (reg:CC CC_REGNUM))]
6426 "TARGET_CPU_ZARCH"
6427 "#"
6428 "&& reload_completed"
6429 [(set (match_dup 0) (const_int 0))
6430 (parallel
6431 [(set (match_dup 0) (minus:GPR (minus:GPR (match_dup 0) (match_dup 0))
6432 (match_dup 1)))
6433 (clobber (reg:CC CC_REGNUM))])
6434 (parallel
6435 [(set (match_dup 0) (neg:GPR (match_dup 0)))
6436 (clobber (reg:CC CC_REGNUM))])]
6437 "")
6438
6439
6440 (define_expand "cstore<mode>4"
6441 [(set (match_operand:SI 0 "register_operand" "")
6442 (match_operator:SI 1 "s390_scond_operator"
6443 [(match_operand:GPR 2 "register_operand" "")
6444 (match_operand:GPR 3 "general_operand" "")]))]
6445 "TARGET_CPU_ZARCH"
6446 "if (!s390_expand_addcc (GET_CODE (operands[1]), operands[2], operands[3],
6447 operands[0], const0_rtx, const1_rtx)) FAIL; DONE;")
6448
6449 (define_expand "cstorecc4"
6450 [(parallel
6451 [(set (match_operand:SI 0 "register_operand" "")
6452 (match_operator:SI 1 "s390_eqne_operator"
6453 [(match_operand:CCZ1 2 "register_operand")
6454 (match_operand 3 "const0_operand")]))
6455 (clobber (reg:CC CC_REGNUM))])]
6456 ""
6457 "emit_insn (gen_sne (operands[0], operands[2]));
6458 if (GET_CODE (operands[1]) == EQ)
6459 emit_insn (gen_xorsi3 (operands[0], operands[0], const1_rtx));
6460 DONE;")
6461
6462 (define_insn_and_split "sne"
6463 [(set (match_operand:SI 0 "register_operand" "=d")
6464 (ne:SI (match_operand:CCZ1 1 "register_operand" "0")
6465 (const_int 0)))
6466 (clobber (reg:CC CC_REGNUM))]
6467 ""
6468 "#"
6469 "reload_completed"
6470 [(parallel
6471 [(set (match_dup 0) (ashiftrt:SI (match_dup 0) (const_int 28)))
6472 (clobber (reg:CC CC_REGNUM))])])
6473
6474
6475 ;;
6476 ;; - Conditional move instructions (introduced with z196)
6477 ;;
6478
6479 (define_expand "mov<mode>cc"
6480 [(set (match_operand:GPR 0 "nonimmediate_operand" "")
6481 (if_then_else:GPR (match_operand 1 "comparison_operator" "")
6482 (match_operand:GPR 2 "nonimmediate_operand" "")
6483 (match_operand:GPR 3 "nonimmediate_operand" "")))]
6484 "TARGET_Z196"
6485 {
6486 /* Emit the comparison insn in case we do not already have a comparison result. */
6487 if (!s390_comparison (operands[1], VOIDmode))
6488 operands[1] = s390_emit_compare (GET_CODE (operands[1]),
6489 XEXP (operands[1], 0),
6490 XEXP (operands[1], 1));
6491 })
6492
6493 ; locr, loc, stoc, locgr, locg, stocg, lochi, locghi
6494 (define_insn_and_split "*mov<mode>cc"
6495 [(set (match_operand:GPR 0 "nonimmediate_operand" "=d,d,d,d,d,d,S,S,&d")
6496 (if_then_else:GPR
6497 (match_operator 1 "s390_comparison"
6498 [(match_operand 2 "cc_reg_operand" " c,c,c,c,c,c,c,c,c")
6499 (match_operand 5 "const_int_operand" "")])
6500 (match_operand:GPR 3 "loc_operand" " d,0,S,0,K,0,d,0,S")
6501 (match_operand:GPR 4 "loc_operand" " 0,d,0,S,0,K,0,d,S")))]
6502 "TARGET_Z196"
6503 "@
6504 loc<g>r%C1\t%0,%3
6505 loc<g>r%D1\t%0,%4
6506 loc<g>%C1\t%0,%3
6507 loc<g>%D1\t%0,%4
6508 loc<g>hi%C1\t%0,%h3
6509 loc<g>hi%D1\t%0,%h4
6510 stoc<g>%C1\t%3,%0
6511 stoc<g>%D1\t%4,%0
6512 #"
6513 "&& reload_completed
6514 && MEM_P (operands[3]) && MEM_P (operands[4])"
6515 [(set (match_dup 0)
6516 (if_then_else:GPR
6517 (match_op_dup 1 [(match_dup 2) (const_int 0)])
6518 (match_dup 3)
6519 (match_dup 0)))
6520 (set (match_dup 0)
6521 (if_then_else:GPR
6522 (match_op_dup 1 [(match_dup 2) (const_int 0)])
6523 (match_dup 0)
6524 (match_dup 4)))]
6525 ""
6526 [(set_attr "op_type" "RRF,RRF,RSY,RSY,RIE,RIE,RSY,RSY,*")
6527 (set_attr "cpu_facility" "*,*,*,*,z13,z13,*,*,*")])
6528
6529 ;;
6530 ;;- Multiply instructions.
6531 ;;
6532
6533 ;
6534 ; muldi3 instruction pattern(s).
6535 ;
6536
6537 (define_insn "*muldi3_sign"
6538 [(set (match_operand:DI 0 "register_operand" "=d,d")
6539 (mult:DI (sign_extend:DI (match_operand:SI 2 "general_operand" "d,T"))
6540 (match_operand:DI 1 "register_operand" "0,0")))]
6541 "TARGET_ZARCH"
6542 "@
6543 msgfr\t%0,%2
6544 msgf\t%0,%2"
6545 [(set_attr "op_type" "RRE,RXY")
6546 (set_attr "type" "imuldi")])
6547
6548 (define_insn "muldi3"
6549 [(set (match_operand:DI 0 "register_operand" "=d,d,d,d")
6550 (mult:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,0")
6551 (match_operand:DI 2 "general_operand" "d,K,T,Os")))]
6552 "TARGET_ZARCH"
6553 "@
6554 msgr\t%0,%2
6555 mghi\t%0,%h2
6556 msg\t%0,%2
6557 msgfi\t%0,%2"
6558 [(set_attr "op_type" "RRE,RI,RXY,RIL")
6559 (set_attr "type" "imuldi")
6560 (set_attr "cpu_facility" "*,*,*,z10")])
6561
6562 ;
6563 ; mulsi3 instruction pattern(s).
6564 ;
6565
6566 (define_insn "*mulsi3_sign"
6567 [(set (match_operand:SI 0 "register_operand" "=d,d")
6568 (mult:SI (sign_extend:SI (match_operand:HI 2 "memory_operand" "R,T"))
6569 (match_operand:SI 1 "register_operand" "0,0")))]
6570 ""
6571 "@
6572 mh\t%0,%2
6573 mhy\t%0,%2"
6574 [(set_attr "op_type" "RX,RXY")
6575 (set_attr "type" "imulhi")
6576 (set_attr "cpu_facility" "*,z10")])
6577
6578 (define_insn "mulsi3"
6579 [(set (match_operand:SI 0 "register_operand" "=d,d,d,d,d")
6580 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,0,0,0")
6581 (match_operand:SI 2 "general_operand" "d,K,R,T,Os")))]
6582 ""
6583 "@
6584 msr\t%0,%2
6585 mhi\t%0,%h2
6586 ms\t%0,%2
6587 msy\t%0,%2
6588 msfi\t%0,%2"
6589 [(set_attr "op_type" "RRE,RI,RX,RXY,RIL")
6590 (set_attr "type" "imulsi,imulhi,imulsi,imulsi,imulsi")
6591 (set_attr "cpu_facility" "*,*,*,longdisp,z10")])
6592
6593 ;
6594 ; mulsidi3 instruction pattern(s).
6595 ;
6596
6597 (define_insn "mulsidi3"
6598 [(set (match_operand:DI 0 "register_operand" "=d,d,d")
6599 (mult:DI (sign_extend:DI
6600 (match_operand:SI 1 "register_operand" "%0,0,0"))
6601 (sign_extend:DI
6602 (match_operand:SI 2 "nonimmediate_operand" "d,R,T"))))]
6603 "!TARGET_ZARCH"
6604 "@
6605 mr\t%0,%2
6606 m\t%0,%2
6607 mfy\t%0,%2"
6608 [(set_attr "op_type" "RR,RX,RXY")
6609 (set_attr "type" "imulsi")
6610 (set_attr "cpu_facility" "*,*,z10")])
6611
6612 ;
6613 ; umul instruction pattern(s).
6614 ;
6615
6616 ; mlr, ml, mlgr, mlg
6617 (define_insn "umul<dwh><mode>3"
6618 [(set (match_operand:DW 0 "register_operand" "=d,d")
6619 (mult:DW (zero_extend:DW
6620 (match_operand:<DWH> 1 "register_operand" "%0,0"))
6621 (zero_extend:DW
6622 (match_operand:<DWH> 2 "nonimmediate_operand" " d,T"))))]
6623 "TARGET_CPU_ZARCH"
6624 "@
6625 ml<tg>r\t%0,%2
6626 ml<tg>\t%0,%2"
6627 [(set_attr "op_type" "RRE,RXY")
6628 (set_attr "type" "imul<dwh>")])
6629
6630 ;
6631 ; mul(tf|df|sf|td|dd)3 instruction pattern(s).
6632 ;
6633
6634 ; mxbr, mdbr, meebr, mxb, mxb, meeb, mdtr, mxtr
6635 (define_insn "mul<mode>3"
6636 [(set (match_operand:FP 0 "register_operand" "=f,f,f,v")
6637 (mult:FP (match_operand:FP 1 "nonimmediate_operand" "%f,0,0,v")
6638 (match_operand:FP 2 "general_operand" "f,f,R,v")))]
6639 "TARGET_HARD_FLOAT"
6640 "@
6641 m<xdee>tr\t%0,%1,%2
6642 m<xdee>br\t%0,%2
6643 m<xdee>b\t%0,%2
6644 wfmdb\t%v0,%v1,%v2"
6645 [(set_attr "op_type" "RRF,RRE,RXE,VRR")
6646 (set_attr "type" "fmul<mode>")
6647 (set_attr "cpu_facility" "*,*,*,vx")
6648 (set_attr "enabled" "<nBFP>,<nDFP>,<DSF>,<DFDI>")])
6649
6650 ; madbr, maebr, maxb, madb, maeb
6651 (define_insn "fma<mode>4"
6652 [(set (match_operand:DSF 0 "register_operand" "=f,f,v")
6653 (fma:DSF (match_operand:DSF 1 "nonimmediate_operand" "%f,f,v")
6654 (match_operand:DSF 2 "nonimmediate_operand" "f,R,v")
6655 (match_operand:DSF 3 "register_operand" "0,0,v")))]
6656 "TARGET_HARD_FLOAT"
6657 "@
6658 ma<xde>br\t%0,%1,%2
6659 ma<xde>b\t%0,%1,%2
6660 wfmadb\t%v0,%v1,%v2,%v3"
6661 [(set_attr "op_type" "RRE,RXE,VRR")
6662 (set_attr "type" "fmadd<mode>")
6663 (set_attr "cpu_facility" "*,*,vx")
6664 (set_attr "enabled" "*,*,<DFDI>")])
6665
6666 ; msxbr, msdbr, msebr, msxb, msdb, mseb
6667 (define_insn "fms<mode>4"
6668 [(set (match_operand:DSF 0 "register_operand" "=f,f,v")
6669 (fma:DSF (match_operand:DSF 1 "nonimmediate_operand" "%f,f,v")
6670 (match_operand:DSF 2 "nonimmediate_operand" "f,R,v")
6671 (neg:DSF (match_operand:DSF 3 "register_operand" "0,0,v"))))]
6672 "TARGET_HARD_FLOAT"
6673 "@
6674 ms<xde>br\t%0,%1,%2
6675 ms<xde>b\t%0,%1,%2
6676 wfmsdb\t%v0,%v1,%v2,%v3"
6677 [(set_attr "op_type" "RRE,RXE,VRR")
6678 (set_attr "type" "fmadd<mode>")
6679 (set_attr "cpu_facility" "*,*,vx")
6680 (set_attr "enabled" "*,*,<DFDI>")])
6681
6682 ;;
6683 ;;- Divide and modulo instructions.
6684 ;;
6685
6686 ;
6687 ; divmoddi4 instruction pattern(s).
6688 ;
6689
6690 (define_expand "divmoddi4"
6691 [(parallel [(set (match_operand:DI 0 "general_operand" "")
6692 (div:DI (match_operand:DI 1 "register_operand" "")
6693 (match_operand:DI 2 "general_operand" "")))
6694 (set (match_operand:DI 3 "general_operand" "")
6695 (mod:DI (match_dup 1) (match_dup 2)))])
6696 (clobber (match_dup 4))]
6697 "TARGET_ZARCH"
6698 {
6699 rtx div_equal, mod_equal;
6700 rtx_insn *insn;
6701
6702 div_equal = gen_rtx_DIV (DImode, operands[1], operands[2]);
6703 mod_equal = gen_rtx_MOD (DImode, operands[1], operands[2]);
6704
6705 operands[4] = gen_reg_rtx(TImode);
6706 emit_insn (gen_divmodtidi3 (operands[4], operands[1], operands[2]));
6707
6708 insn = emit_move_insn (operands[0], gen_lowpart (DImode, operands[4]));
6709 set_unique_reg_note (insn, REG_EQUAL, div_equal);
6710
6711 insn = emit_move_insn (operands[3], gen_highpart (DImode, operands[4]));
6712 set_unique_reg_note (insn, REG_EQUAL, mod_equal);
6713
6714 DONE;
6715 })
6716
6717 (define_insn "divmodtidi3"
6718 [(set (match_operand:TI 0 "register_operand" "=d,d")
6719 (ior:TI
6720 (ashift:TI
6721 (zero_extend:TI
6722 (mod:DI (match_operand:DI 1 "register_operand" "0,0")
6723 (match_operand:DI 2 "general_operand" "d,T")))
6724 (const_int 64))
6725 (zero_extend:TI (div:DI (match_dup 1) (match_dup 2)))))]
6726 "TARGET_ZARCH"
6727 "@
6728 dsgr\t%0,%2
6729 dsg\t%0,%2"
6730 [(set_attr "op_type" "RRE,RXY")
6731 (set_attr "type" "idiv")])
6732
6733 (define_insn "divmodtisi3"
6734 [(set (match_operand:TI 0 "register_operand" "=d,d")
6735 (ior:TI
6736 (ashift:TI
6737 (zero_extend:TI
6738 (mod:DI (match_operand:DI 1 "register_operand" "0,0")
6739 (sign_extend:DI
6740 (match_operand:SI 2 "nonimmediate_operand" "d,T"))))
6741 (const_int 64))
6742 (zero_extend:TI
6743 (div:DI (match_dup 1) (sign_extend:DI (match_dup 2))))))]
6744 "TARGET_ZARCH"
6745 "@
6746 dsgfr\t%0,%2
6747 dsgf\t%0,%2"
6748 [(set_attr "op_type" "RRE,RXY")
6749 (set_attr "type" "idiv")])
6750
6751 ;
6752 ; udivmoddi4 instruction pattern(s).
6753 ;
6754
6755 (define_expand "udivmoddi4"
6756 [(parallel [(set (match_operand:DI 0 "general_operand" "")
6757 (udiv:DI (match_operand:DI 1 "general_operand" "")
6758 (match_operand:DI 2 "nonimmediate_operand" "")))
6759 (set (match_operand:DI 3 "general_operand" "")
6760 (umod:DI (match_dup 1) (match_dup 2)))])
6761 (clobber (match_dup 4))]
6762 "TARGET_ZARCH"
6763 {
6764 rtx div_equal, mod_equal, equal;
6765 rtx_insn *insn;
6766
6767 div_equal = gen_rtx_UDIV (DImode, operands[1], operands[2]);
6768 mod_equal = gen_rtx_UMOD (DImode, operands[1], operands[2]);
6769 equal = gen_rtx_IOR (TImode,
6770 gen_rtx_ASHIFT (TImode,
6771 gen_rtx_ZERO_EXTEND (TImode, mod_equal),
6772 GEN_INT (64)),
6773 gen_rtx_ZERO_EXTEND (TImode, div_equal));
6774
6775 operands[4] = gen_reg_rtx(TImode);
6776 emit_clobber (operands[4]);
6777 emit_move_insn (gen_lowpart (DImode, operands[4]), operands[1]);
6778 emit_move_insn (gen_highpart (DImode, operands[4]), const0_rtx);
6779
6780 insn = emit_insn (gen_udivmodtidi3 (operands[4], operands[4], operands[2]));
6781 set_unique_reg_note (insn, REG_EQUAL, equal);
6782
6783 insn = emit_move_insn (operands[0], gen_lowpart (DImode, operands[4]));
6784 set_unique_reg_note (insn, REG_EQUAL, div_equal);
6785
6786 insn = emit_move_insn (operands[3], gen_highpart (DImode, operands[4]));
6787 set_unique_reg_note (insn, REG_EQUAL, mod_equal);
6788
6789 DONE;
6790 })
6791
6792 (define_insn "udivmodtidi3"
6793 [(set (match_operand:TI 0 "register_operand" "=d,d")
6794 (ior:TI
6795 (ashift:TI
6796 (zero_extend:TI
6797 (truncate:DI
6798 (umod:TI (match_operand:TI 1 "register_operand" "0,0")
6799 (zero_extend:TI
6800 (match_operand:DI 2 "nonimmediate_operand" "d,T")))))
6801 (const_int 64))
6802 (zero_extend:TI
6803 (truncate:DI
6804 (udiv:TI (match_dup 1) (zero_extend:TI (match_dup 2)))))))]
6805 "TARGET_ZARCH"
6806 "@
6807 dlgr\t%0,%2
6808 dlg\t%0,%2"
6809 [(set_attr "op_type" "RRE,RXY")
6810 (set_attr "type" "idiv")])
6811
6812 ;
6813 ; divmodsi4 instruction pattern(s).
6814 ;
6815
6816 (define_expand "divmodsi4"
6817 [(parallel [(set (match_operand:SI 0 "general_operand" "")
6818 (div:SI (match_operand:SI 1 "general_operand" "")
6819 (match_operand:SI 2 "nonimmediate_operand" "")))
6820 (set (match_operand:SI 3 "general_operand" "")
6821 (mod:SI (match_dup 1) (match_dup 2)))])
6822 (clobber (match_dup 4))]
6823 "!TARGET_ZARCH"
6824 {
6825 rtx div_equal, mod_equal, equal;
6826 rtx_insn *insn;
6827
6828 div_equal = gen_rtx_DIV (SImode, operands[1], operands[2]);
6829 mod_equal = gen_rtx_MOD (SImode, operands[1], operands[2]);
6830 equal = gen_rtx_IOR (DImode,
6831 gen_rtx_ASHIFT (DImode,
6832 gen_rtx_ZERO_EXTEND (DImode, mod_equal),
6833 GEN_INT (32)),
6834 gen_rtx_ZERO_EXTEND (DImode, div_equal));
6835
6836 operands[4] = gen_reg_rtx(DImode);
6837 emit_insn (gen_extendsidi2 (operands[4], operands[1]));
6838
6839 insn = emit_insn (gen_divmoddisi3 (operands[4], operands[4], operands[2]));
6840 set_unique_reg_note (insn, REG_EQUAL, equal);
6841
6842 insn = emit_move_insn (operands[0], gen_lowpart (SImode, operands[4]));
6843 set_unique_reg_note (insn, REG_EQUAL, div_equal);
6844
6845 insn = emit_move_insn (operands[3], gen_highpart (SImode, operands[4]));
6846 set_unique_reg_note (insn, REG_EQUAL, mod_equal);
6847
6848 DONE;
6849 })
6850
6851 (define_insn "divmoddisi3"
6852 [(set (match_operand:DI 0 "register_operand" "=d,d")
6853 (ior:DI
6854 (ashift:DI
6855 (zero_extend:DI
6856 (truncate:SI
6857 (mod:DI (match_operand:DI 1 "register_operand" "0,0")
6858 (sign_extend:DI
6859 (match_operand:SI 2 "nonimmediate_operand" "d,R")))))
6860 (const_int 32))
6861 (zero_extend:DI
6862 (truncate:SI
6863 (div:DI (match_dup 1) (sign_extend:DI (match_dup 2)))))))]
6864 "!TARGET_ZARCH"
6865 "@
6866 dr\t%0,%2
6867 d\t%0,%2"
6868 [(set_attr "op_type" "RR,RX")
6869 (set_attr "type" "idiv")])
6870
6871 ;
6872 ; udivsi3 and umodsi3 instruction pattern(s).
6873 ;
6874
6875 (define_expand "udivmodsi4"
6876 [(parallel [(set (match_operand:SI 0 "general_operand" "")
6877 (udiv:SI (match_operand:SI 1 "general_operand" "")
6878 (match_operand:SI 2 "nonimmediate_operand" "")))
6879 (set (match_operand:SI 3 "general_operand" "")
6880 (umod:SI (match_dup 1) (match_dup 2)))])
6881 (clobber (match_dup 4))]
6882 "!TARGET_ZARCH && TARGET_CPU_ZARCH"
6883 {
6884 rtx div_equal, mod_equal, equal;
6885 rtx_insn *insn;
6886
6887 div_equal = gen_rtx_UDIV (SImode, operands[1], operands[2]);
6888 mod_equal = gen_rtx_UMOD (SImode, operands[1], operands[2]);
6889 equal = gen_rtx_IOR (DImode,
6890 gen_rtx_ASHIFT (DImode,
6891 gen_rtx_ZERO_EXTEND (DImode, mod_equal),
6892 GEN_INT (32)),
6893 gen_rtx_ZERO_EXTEND (DImode, div_equal));
6894
6895 operands[4] = gen_reg_rtx(DImode);
6896 emit_clobber (operands[4]);
6897 emit_move_insn (gen_lowpart (SImode, operands[4]), operands[1]);
6898 emit_move_insn (gen_highpart (SImode, operands[4]), const0_rtx);
6899
6900 insn = emit_insn (gen_udivmoddisi3 (operands[4], operands[4], operands[2]));
6901 set_unique_reg_note (insn, REG_EQUAL, equal);
6902
6903 insn = emit_move_insn (operands[0], gen_lowpart (SImode, operands[4]));
6904 set_unique_reg_note (insn, REG_EQUAL, div_equal);
6905
6906 insn = emit_move_insn (operands[3], gen_highpart (SImode, operands[4]));
6907 set_unique_reg_note (insn, REG_EQUAL, mod_equal);
6908
6909 DONE;
6910 })
6911
6912 (define_insn "udivmoddisi3"
6913 [(set (match_operand:DI 0 "register_operand" "=d,d")
6914 (ior:DI
6915 (ashift:DI
6916 (zero_extend:DI
6917 (truncate:SI
6918 (umod:DI (match_operand:DI 1 "register_operand" "0,0")
6919 (zero_extend:DI
6920 (match_operand:SI 2 "nonimmediate_operand" "d,T")))))
6921 (const_int 32))
6922 (zero_extend:DI
6923 (truncate:SI
6924 (udiv:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))))]
6925 "!TARGET_ZARCH && TARGET_CPU_ZARCH"
6926 "@
6927 dlr\t%0,%2
6928 dl\t%0,%2"
6929 [(set_attr "op_type" "RRE,RXY")
6930 (set_attr "type" "idiv")])
6931
6932 (define_expand "udivsi3"
6933 [(set (match_operand:SI 0 "register_operand" "=d")
6934 (udiv:SI (match_operand:SI 1 "general_operand" "")
6935 (match_operand:SI 2 "general_operand" "")))
6936 (clobber (match_dup 3))]
6937 "!TARGET_ZARCH && !TARGET_CPU_ZARCH"
6938 {
6939 rtx udiv_equal, umod_equal, equal;
6940 rtx_insn *insn;
6941
6942 udiv_equal = gen_rtx_UDIV (SImode, operands[1], operands[2]);
6943 umod_equal = gen_rtx_UMOD (SImode, operands[1], operands[2]);
6944 equal = gen_rtx_IOR (DImode,
6945 gen_rtx_ASHIFT (DImode,
6946 gen_rtx_ZERO_EXTEND (DImode, umod_equal),
6947 GEN_INT (32)),
6948 gen_rtx_ZERO_EXTEND (DImode, udiv_equal));
6949
6950 operands[3] = gen_reg_rtx (DImode);
6951
6952 if (CONSTANT_P (operands[2]))
6953 {
6954 if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0)
6955 {
6956 rtx_code_label *label1 = gen_label_rtx ();
6957
6958 operands[1] = make_safe_from (operands[1], operands[0]);
6959 emit_move_insn (operands[0], const0_rtx);
6960 emit_cmp_and_jump_insns (operands[1], operands[2], LT, NULL_RTX,
6961 SImode, 1, label1);
6962 emit_move_insn (operands[0], const1_rtx);
6963 emit_label (label1);
6964 }
6965 else
6966 {
6967 operands[2] = force_reg (SImode, operands[2]);
6968 operands[2] = make_safe_from (operands[2], operands[0]);
6969
6970 emit_insn (gen_zero_extendsidi2 (operands[3], operands[1]));
6971 insn = emit_insn (gen_divmoddisi3 (operands[3], operands[3],
6972 operands[2]));
6973 set_unique_reg_note (insn, REG_EQUAL, equal);
6974
6975 insn = emit_move_insn (operands[0],
6976 gen_lowpart (SImode, operands[3]));
6977 set_unique_reg_note (insn, REG_EQUAL, udiv_equal);
6978 }
6979 }
6980 else
6981 {
6982 rtx_code_label *label1 = gen_label_rtx ();
6983 rtx_code_label *label2 = gen_label_rtx ();
6984 rtx_code_label *label3 = gen_label_rtx ();
6985
6986 operands[1] = force_reg (SImode, operands[1]);
6987 operands[1] = make_safe_from (operands[1], operands[0]);
6988 operands[2] = force_reg (SImode, operands[2]);
6989 operands[2] = make_safe_from (operands[2], operands[0]);
6990
6991 emit_move_insn (operands[0], const0_rtx);
6992 emit_cmp_and_jump_insns (operands[2], operands[1], GT, NULL_RTX,
6993 SImode, 1, label3);
6994 emit_cmp_and_jump_insns (operands[2], const0_rtx, LT, NULL_RTX,
6995 SImode, 0, label2);
6996 emit_cmp_and_jump_insns (operands[2], const1_rtx, EQ, NULL_RTX,
6997 SImode, 0, label1);
6998 emit_insn (gen_zero_extendsidi2 (operands[3], operands[1]));
6999 insn = emit_insn (gen_divmoddisi3 (operands[3], operands[3],
7000 operands[2]));
7001 set_unique_reg_note (insn, REG_EQUAL, equal);
7002
7003 insn = emit_move_insn (operands[0],
7004 gen_lowpart (SImode, operands[3]));
7005 set_unique_reg_note (insn, REG_EQUAL, udiv_equal);
7006
7007 emit_jump (label3);
7008 emit_label (label1);
7009 emit_move_insn (operands[0], operands[1]);
7010 emit_jump (label3);
7011 emit_label (label2);
7012 emit_move_insn (operands[0], const1_rtx);
7013 emit_label (label3);
7014 }
7015 emit_move_insn (operands[0], operands[0]);
7016 DONE;
7017 })
7018
7019 (define_expand "umodsi3"
7020 [(set (match_operand:SI 0 "register_operand" "=d")
7021 (umod:SI (match_operand:SI 1 "nonimmediate_operand" "")
7022 (match_operand:SI 2 "nonimmediate_operand" "")))
7023 (clobber (match_dup 3))]
7024 "!TARGET_ZARCH && !TARGET_CPU_ZARCH"
7025 {
7026 rtx udiv_equal, umod_equal, equal;
7027 rtx_insn *insn;
7028
7029 udiv_equal = gen_rtx_UDIV (SImode, operands[1], operands[2]);
7030 umod_equal = gen_rtx_UMOD (SImode, operands[1], operands[2]);
7031 equal = gen_rtx_IOR (DImode,
7032 gen_rtx_ASHIFT (DImode,
7033 gen_rtx_ZERO_EXTEND (DImode, umod_equal),
7034 GEN_INT (32)),
7035 gen_rtx_ZERO_EXTEND (DImode, udiv_equal));
7036
7037 operands[3] = gen_reg_rtx (DImode);
7038
7039 if (CONSTANT_P (operands[2]))
7040 {
7041 if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) <= 0)
7042 {
7043 rtx_code_label *label1 = gen_label_rtx ();
7044
7045 operands[1] = make_safe_from (operands[1], operands[0]);
7046 emit_move_insn (operands[0], operands[1]);
7047 emit_cmp_and_jump_insns (operands[0], operands[2], LT, NULL_RTX,
7048 SImode, 1, label1);
7049 emit_insn (gen_abssi2 (operands[0], operands[2]));
7050 emit_insn (gen_addsi3 (operands[0], operands[0], operands[1]));
7051 emit_label (label1);
7052 }
7053 else
7054 {
7055 operands[2] = force_reg (SImode, operands[2]);
7056 operands[2] = make_safe_from (operands[2], operands[0]);
7057
7058 emit_insn (gen_zero_extendsidi2 (operands[3], operands[1]));
7059 insn = emit_insn (gen_divmoddisi3 (operands[3], operands[3],
7060 operands[2]));
7061 set_unique_reg_note (insn, REG_EQUAL, equal);
7062
7063 insn = emit_move_insn (operands[0],
7064 gen_highpart (SImode, operands[3]));
7065 set_unique_reg_note (insn, REG_EQUAL, umod_equal);
7066 }
7067 }
7068 else
7069 {
7070 rtx_code_label *label1 = gen_label_rtx ();
7071 rtx_code_label *label2 = gen_label_rtx ();
7072 rtx_code_label *label3 = gen_label_rtx ();
7073
7074 operands[1] = force_reg (SImode, operands[1]);
7075 operands[1] = make_safe_from (operands[1], operands[0]);
7076 operands[2] = force_reg (SImode, operands[2]);
7077 operands[2] = make_safe_from (operands[2], operands[0]);
7078
7079 emit_move_insn(operands[0], operands[1]);
7080 emit_cmp_and_jump_insns (operands[2], operands[1], GT, NULL_RTX,
7081 SImode, 1, label3);
7082 emit_cmp_and_jump_insns (operands[2], const0_rtx, LT, NULL_RTX,
7083 SImode, 0, label2);
7084 emit_cmp_and_jump_insns (operands[2], const1_rtx, EQ, NULL_RTX,
7085 SImode, 0, label1);
7086 emit_insn (gen_zero_extendsidi2 (operands[3], operands[1]));
7087 insn = emit_insn (gen_divmoddisi3 (operands[3], operands[3],
7088 operands[2]));
7089 set_unique_reg_note (insn, REG_EQUAL, equal);
7090
7091 insn = emit_move_insn (operands[0],
7092 gen_highpart (SImode, operands[3]));
7093 set_unique_reg_note (insn, REG_EQUAL, umod_equal);
7094
7095 emit_jump (label3);
7096 emit_label (label1);
7097 emit_move_insn (operands[0], const0_rtx);
7098 emit_jump (label3);
7099 emit_label (label2);
7100 emit_insn (gen_subsi3 (operands[0], operands[0], operands[2]));
7101 emit_label (label3);
7102 }
7103 DONE;
7104 })
7105
7106 ;
7107 ; div(df|sf)3 instruction pattern(s).
7108 ;
7109
7110 ; dxbr, ddbr, debr, dxb, ddb, deb, ddtr, dxtr
7111 (define_insn "div<mode>3"
7112 [(set (match_operand:FP 0 "register_operand" "=f,f,f,v")
7113 (div:FP (match_operand:FP 1 "register_operand" "f,0,0,v")
7114 (match_operand:FP 2 "general_operand" "f,f,R,v")))]
7115 "TARGET_HARD_FLOAT"
7116 "@
7117 d<xde>tr\t%0,%1,%2
7118 d<xde>br\t%0,%2
7119 d<xde>b\t%0,%2
7120 wfddb\t%v0,%v1,%v2"
7121 [(set_attr "op_type" "RRF,RRE,RXE,VRR")
7122 (set_attr "type" "fdiv<mode>")
7123 (set_attr "cpu_facility" "*,*,*,vx")
7124 (set_attr "enabled" "<nBFP>,<nDFP>,<DSF>,<DFDI>")])
7125
7126
7127 ;;
7128 ;;- And instructions.
7129 ;;
7130
7131 (define_expand "and<mode>3"
7132 [(set (match_operand:INT 0 "nonimmediate_operand" "")
7133 (and:INT (match_operand:INT 1 "nonimmediate_operand" "")
7134 (match_operand:INT 2 "general_operand" "")))
7135 (clobber (reg:CC CC_REGNUM))]
7136 ""
7137 "s390_expand_logical_operator (AND, <MODE>mode, operands); DONE;")
7138
7139 ;
7140 ; anddi3 instruction pattern(s).
7141 ;
7142
7143 (define_insn "*anddi3_cc"
7144 [(set (reg CC_REGNUM)
7145 (compare
7146 (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,d,0, d")
7147 (match_operand:DI 2 "general_operand" " d,d,T,NxxDw"))
7148 (const_int 0)))
7149 (set (match_operand:DI 0 "register_operand" "=d,d,d, d")
7150 (and:DI (match_dup 1) (match_dup 2)))]
7151 "TARGET_ZARCH && s390_match_ccmode(insn, CCTmode)"
7152 "@
7153 ngr\t%0,%2
7154 ngrk\t%0,%1,%2
7155 ng\t%0,%2
7156 risbg\t%0,%1,%s2,128+%e2,0"
7157 [(set_attr "op_type" "RRE,RRF,RXY,RIE")
7158 (set_attr "cpu_facility" "*,z196,*,z10")
7159 (set_attr "z10prop" "z10_super_E1,*,z10_super_E1,z10_super_E1")])
7160
7161 (define_insn "*anddi3_cconly"
7162 [(set (reg CC_REGNUM)
7163 (compare
7164 (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,d,0, d")
7165 (match_operand:DI 2 "general_operand" " d,d,T,NxxDw"))
7166 (const_int 0)))
7167 (clobber (match_scratch:DI 0 "=d,d,d, d"))]
7168 "TARGET_ZARCH
7169 && s390_match_ccmode(insn, CCTmode)
7170 /* Do not steal TM patterns. */
7171 && s390_single_part (operands[2], DImode, HImode, 0) < 0"
7172 "@
7173 ngr\t%0,%2
7174 ngrk\t%0,%1,%2
7175 ng\t%0,%2
7176 risbg\t%0,%1,%s2,128+%e2,0"
7177 [(set_attr "op_type" "RRE,RRF,RXY,RIE")
7178 (set_attr "cpu_facility" "*,z196,*,z10")
7179 (set_attr "z10prop" "z10_super_E1,*,z10_super_E1,z10_super_E1")])
7180
7181 (define_insn "*anddi3"
7182 [(set (match_operand:DI 0 "nonimmediate_operand"
7183 "=d,d, d, d, d, d, d, d,d,d,d, d, AQ,Q")
7184 (and:DI
7185 (match_operand:DI 1 "nonimmediate_operand"
7186 "%d,o, 0, 0, 0, 0, 0, 0,0,d,0, d, 0,0")
7187 (match_operand:DI 2 "general_operand"
7188 "M, M,N0HDF,N1HDF,N2HDF,N3HDF,N0SDF,N1SDF,d,d,T,NxxDw,NxQDF,Q")))
7189 (clobber (reg:CC CC_REGNUM))]
7190 "TARGET_ZARCH && s390_logical_operator_ok_p (operands)"
7191 "@
7192 #
7193 #
7194 nihh\t%0,%j2
7195 nihl\t%0,%j2
7196 nilh\t%0,%j2
7197 nill\t%0,%j2
7198 nihf\t%0,%m2
7199 nilf\t%0,%m2
7200 ngr\t%0,%2
7201 ngrk\t%0,%1,%2
7202 ng\t%0,%2
7203 risbg\t%0,%1,%s2,128+%e2,0
7204 #
7205 #"
7206 [(set_attr "op_type" "RRE,RXE,RI,RI,RI,RI,RIL,RIL,RRE,RRF,RXY,RIE,SI,SS")
7207 (set_attr "cpu_facility" "*,*,*,*,*,*,extimm,extimm,*,z196,*,z10,*,*")
7208 (set_attr "z10prop" "*,
7209 *,
7210 z10_super_E1,
7211 z10_super_E1,
7212 z10_super_E1,
7213 z10_super_E1,
7214 z10_super_E1,
7215 z10_super_E1,
7216 z10_super_E1,
7217 *,
7218 z10_super_E1,
7219 z10_super_E1,
7220 *,
7221 *")])
7222
7223 (define_split
7224 [(set (match_operand:DI 0 "s_operand" "")
7225 (and:DI (match_dup 0) (match_operand:DI 1 "immediate_operand" "")))
7226 (clobber (reg:CC CC_REGNUM))]
7227 "reload_completed"
7228 [(parallel
7229 [(set (match_dup 0) (and:QI (match_dup 0) (match_dup 1)))
7230 (clobber (reg:CC CC_REGNUM))])]
7231 "s390_narrow_logical_operator (AND, &operands[0], &operands[1]);")
7232
7233 ;; These two are what combine generates for (ashift (zero_extract)).
7234 (define_insn "*extzv_<mode>_srl<clobbercc_or_nocc>"
7235 [(set (match_operand:GPR 0 "register_operand" "=d")
7236 (and:GPR (lshiftrt:GPR
7237 (match_operand:GPR 1 "register_operand" "d")
7238 (match_operand:GPR 2 "nonzero_shift_count_operand" ""))
7239 (match_operand:GPR 3 "contiguous_bitmask_nowrap_operand" "")))]
7240 "<z10_or_zEC12_cond>
7241 /* Note that even for the SImode pattern, the rotate is always DImode. */
7242 && s390_extzv_shift_ok (<bitsize>, -INTVAL (operands[2]),
7243 INTVAL (operands[3]))"
7244 "<risbg_n>\t%0,%1,%<bfstart>3,128+%<bfend>3,64-%2"
7245 [(set_attr "op_type" "RIE")
7246 (set_attr "z10prop" "z10_super_E1")])
7247
7248 (define_insn "*extzv_<mode>_sll<clobbercc_or_nocc>"
7249 [(set (match_operand:GPR 0 "register_operand" "=d")
7250 (and:GPR (ashift:GPR
7251 (match_operand:GPR 1 "register_operand" "d")
7252 (match_operand:GPR 2 "nonzero_shift_count_operand" ""))
7253 (match_operand:GPR 3 "contiguous_bitmask_nowrap_operand" "")))]
7254 "<z10_or_zEC12_cond>
7255 && s390_extzv_shift_ok (<bitsize>, INTVAL (operands[2]),
7256 INTVAL (operands[3]))"
7257 "<risbg_n>\t%0,%1,%<bfstart>3,128+%<bfend>3,%2"
7258 [(set_attr "op_type" "RIE")
7259 (set_attr "z10prop" "z10_super_E1")])
7260
7261
7262 ;
7263 ; andsi3 instruction pattern(s).
7264 ;
7265
7266 (define_insn "*andsi3_cc"
7267 [(set (reg CC_REGNUM)
7268 (compare
7269 (and:SI
7270 (match_operand:SI 1 "nonimmediate_operand" "%0,0,d,0,0, d")
7271 (match_operand:SI 2 "general_operand" "Os,d,d,R,T,NxxSq"))
7272 (const_int 0)))
7273 (set (match_operand:SI 0 "register_operand" "=d,d,d,d,d, d")
7274 (and:SI (match_dup 1) (match_dup 2)))]
7275 "s390_match_ccmode(insn, CCTmode)"
7276 "@
7277 nilf\t%0,%o2
7278 nr\t%0,%2
7279 nrk\t%0,%1,%2
7280 n\t%0,%2
7281 ny\t%0,%2
7282 risbg\t%0,%1,%t2,128+%f2,0"
7283 [(set_attr "op_type" "RIL,RR,RRF,RX,RXY,RIE")
7284 (set_attr "cpu_facility" "*,*,z196,*,longdisp,z10")
7285 (set_attr "z10prop" "z10_super_E1,z10_super_E1,*,
7286 z10_super_E1,z10_super_E1,z10_super_E1")])
7287
7288 (define_insn "*andsi3_cconly"
7289 [(set (reg CC_REGNUM)
7290 (compare
7291 (and:SI
7292 (match_operand:SI 1 "nonimmediate_operand" "%0,0,d,0,0, d")
7293 (match_operand:SI 2 "general_operand" "Os,d,d,R,T,NxxSq"))
7294 (const_int 0)))
7295 (clobber (match_scratch:SI 0 "=d,d,d,d,d, d"))]
7296 "s390_match_ccmode(insn, CCTmode)
7297 /* Do not steal TM patterns. */
7298 && s390_single_part (operands[2], SImode, HImode, 0) < 0"
7299 "@
7300 nilf\t%0,%o2
7301 nr\t%0,%2
7302 nrk\t%0,%1,%2
7303 n\t%0,%2
7304 ny\t%0,%2
7305 risbg\t%0,%1,%t2,128+%f2,0"
7306 [(set_attr "op_type" "RIL,RR,RRF,RX,RXY,RIE")
7307 (set_attr "cpu_facility" "*,*,z196,*,longdisp,z10")
7308 (set_attr "z10prop" "z10_super_E1,z10_super_E1,*,
7309 z10_super_E1,z10_super_E1,z10_super_E1")])
7310
7311 (define_insn "*andsi3_zarch"
7312 [(set (match_operand:SI 0 "nonimmediate_operand"
7313 "=d,d, d, d, d,d,d,d,d, d, AQ,Q")
7314 (and:SI (match_operand:SI 1 "nonimmediate_operand"
7315 "%d,o, 0, 0, 0,0,d,0,0, d, 0,0")
7316 (match_operand:SI 2 "general_operand"
7317 " M,M,N0HSF,N1HSF,Os,d,d,R,T,NxxSw,NxQSF,Q")))
7318 (clobber (reg:CC CC_REGNUM))]
7319 "TARGET_ZARCH && s390_logical_operator_ok_p (operands)"
7320 "@
7321 #
7322 #
7323 nilh\t%0,%j2
7324 nill\t%0,%j2
7325 nilf\t%0,%o2
7326 nr\t%0,%2
7327 nrk\t%0,%1,%2
7328 n\t%0,%2
7329 ny\t%0,%2
7330 risbg\t%0,%1,%t2,128+%f2,0
7331 #
7332 #"
7333 [(set_attr "op_type" "RRE,RXE,RI,RI,RIL,RR,RRF,RX,RXY,RIE,SI,SS")
7334 (set_attr "cpu_facility" "*,*,*,*,*,*,z196,*,longdisp,z10,*,*")
7335 (set_attr "z10prop" "*,
7336 *,
7337 z10_super_E1,
7338 z10_super_E1,
7339 z10_super_E1,
7340 z10_super_E1,
7341 *,
7342 z10_super_E1,
7343 z10_super_E1,
7344 z10_super_E1,
7345 *,
7346 *")])
7347
7348 (define_insn "*andsi3_esa"
7349 [(set (match_operand:SI 0 "nonimmediate_operand" "=d,d, AQ,Q")
7350 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0, 0,0")
7351 (match_operand:SI 2 "general_operand" " d,R,NxQSF,Q")))
7352 (clobber (reg:CC CC_REGNUM))]
7353 "!TARGET_ZARCH && s390_logical_operator_ok_p (operands)"
7354 "@
7355 nr\t%0,%2
7356 n\t%0,%2
7357 #
7358 #"
7359 [(set_attr "op_type" "RR,RX,SI,SS")
7360 (set_attr "z10prop" "z10_super_E1,z10_super_E1,*,*")])
7361
7362
7363 (define_split
7364 [(set (match_operand:SI 0 "s_operand" "")
7365 (and:SI (match_dup 0) (match_operand:SI 1 "immediate_operand" "")))
7366 (clobber (reg:CC CC_REGNUM))]
7367 "reload_completed"
7368 [(parallel
7369 [(set (match_dup 0) (and:QI (match_dup 0) (match_dup 1)))
7370 (clobber (reg:CC CC_REGNUM))])]
7371 "s390_narrow_logical_operator (AND, &operands[0], &operands[1]);")
7372
7373 ;
7374 ; andhi3 instruction pattern(s).
7375 ;
7376
7377 (define_insn "*andhi3_zarch"
7378 [(set (match_operand:HI 0 "nonimmediate_operand" "=d,d,d, AQ,Q")
7379 (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,d,0, 0,0")
7380 (match_operand:HI 2 "general_operand" " d,d,n,NxQHF,Q")))
7381 (clobber (reg:CC CC_REGNUM))]
7382 "TARGET_ZARCH && s390_logical_operator_ok_p (operands)"
7383 "@
7384 nr\t%0,%2
7385 nrk\t%0,%1,%2
7386 nill\t%0,%x2
7387 #
7388 #"
7389 [(set_attr "op_type" "RR,RRF,RI,SI,SS")
7390 (set_attr "cpu_facility" "*,z196,*,*,*")
7391 (set_attr "z10prop" "z10_super_E1,*,z10_super_E1,*,*")
7392 ])
7393
7394 (define_insn "*andhi3_esa"
7395 [(set (match_operand:HI 0 "nonimmediate_operand" "=d,AQ,Q")
7396 (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,0")
7397 (match_operand:HI 2 "general_operand" "d,NxQHF,Q")))
7398 (clobber (reg:CC CC_REGNUM))]
7399 "!TARGET_ZARCH && s390_logical_operator_ok_p (operands)"
7400 "@
7401 nr\t%0,%2
7402 #
7403 #"
7404 [(set_attr "op_type" "RR,SI,SS")
7405 (set_attr "z10prop" "z10_super_E1,*,*")
7406 ])
7407
7408 (define_split
7409 [(set (match_operand:HI 0 "s_operand" "")
7410 (and:HI (match_dup 0) (match_operand:HI 1 "immediate_operand" "")))
7411 (clobber (reg:CC CC_REGNUM))]
7412 "reload_completed"
7413 [(parallel
7414 [(set (match_dup 0) (and:QI (match_dup 0) (match_dup 1)))
7415 (clobber (reg:CC CC_REGNUM))])]
7416 "s390_narrow_logical_operator (AND, &operands[0], &operands[1]);")
7417
7418 ;
7419 ; andqi3 instruction pattern(s).
7420 ;
7421
7422 (define_insn "*andqi3_zarch"
7423 [(set (match_operand:QI 0 "nonimmediate_operand" "=d,d,d,Q,S,Q")
7424 (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,d,0,0,0,0")
7425 (match_operand:QI 2 "general_operand" " d,d,n,n,n,Q")))
7426 (clobber (reg:CC CC_REGNUM))]
7427 "TARGET_ZARCH && s390_logical_operator_ok_p (operands)"
7428 "@
7429 nr\t%0,%2
7430 nrk\t%0,%1,%2
7431 nill\t%0,%b2
7432 ni\t%S0,%b2
7433 niy\t%S0,%b2
7434 #"
7435 [(set_attr "op_type" "RR,RRF,RI,SI,SIY,SS")
7436 (set_attr "cpu_facility" "*,z196,*,*,longdisp,*")
7437 (set_attr "z10prop" "z10_super_E1,*,z10_super_E1,z10_super,z10_super,*")])
7438
7439 (define_insn "*andqi3_esa"
7440 [(set (match_operand:QI 0 "nonimmediate_operand" "=d,Q,Q")
7441 (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
7442 (match_operand:QI 2 "general_operand" "d,n,Q")))
7443 (clobber (reg:CC CC_REGNUM))]
7444 "!TARGET_ZARCH && s390_logical_operator_ok_p (operands)"
7445 "@
7446 nr\t%0,%2
7447 ni\t%S0,%b2
7448 #"
7449 [(set_attr "op_type" "RR,SI,SS")
7450 (set_attr "z10prop" "z10_super_E1,z10_super,*")])
7451
7452 ;
7453 ; And with complement
7454 ;
7455 ; c = ~b & a = (b & a) ^ a
7456
7457 (define_insn_and_split "*andc_split_<mode>"
7458 [(set (match_operand:GPR 0 "nonimmediate_operand" "")
7459 (and:GPR (not:GPR (match_operand:GPR 1 "nonimmediate_operand" ""))
7460 (match_operand:GPR 2 "general_operand" "")))
7461 (clobber (reg:CC CC_REGNUM))]
7462 "! reload_completed
7463 && (GET_CODE (operands[0]) != MEM
7464 /* Ensure that s390_logical_operator_ok_p will succeed even
7465 on the split xor if (b & a) is stored into a pseudo. */
7466 || rtx_equal_p (operands[0], operands[2]))"
7467 "#"
7468 "&& 1"
7469 [
7470 (parallel
7471 [(set (match_dup 3) (and:GPR (match_dup 1) (match_dup 2)))
7472 (clobber (reg:CC CC_REGNUM))])
7473 (parallel
7474 [(set (match_dup 0) (xor:GPR (match_dup 3) (match_dup 2)))
7475 (clobber (reg:CC CC_REGNUM))])]
7476 {
7477 if (reg_overlap_mentioned_p (operands[0], operands[2]))
7478 operands[3] = gen_reg_rtx (<MODE>mode);
7479 else
7480 operands[3] = operands[0];
7481 })
7482
7483 ;
7484 ; Block and (NC) patterns.
7485 ;
7486
7487 (define_insn "*nc"
7488 [(set (match_operand:BLK 0 "memory_operand" "=Q")
7489 (and:BLK (match_dup 0)
7490 (match_operand:BLK 1 "memory_operand" "Q")))
7491 (use (match_operand 2 "const_int_operand" "n"))
7492 (clobber (reg:CC CC_REGNUM))]
7493 "INTVAL (operands[2]) >= 1 && INTVAL (operands[2]) <= 256"
7494 "nc\t%O0(%2,%R0),%S1"
7495 [(set_attr "op_type" "SS")
7496 (set_attr "z196prop" "z196_cracked")])
7497
7498 (define_split
7499 [(set (match_operand 0 "memory_operand" "")
7500 (and (match_dup 0)
7501 (match_operand 1 "memory_operand" "")))
7502 (clobber (reg:CC CC_REGNUM))]
7503 "reload_completed
7504 && GET_MODE (operands[0]) == GET_MODE (operands[1])
7505 && GET_MODE_SIZE (GET_MODE (operands[0])) > 0"
7506 [(parallel
7507 [(set (match_dup 0) (and:BLK (match_dup 0) (match_dup 1)))
7508 (use (match_dup 2))
7509 (clobber (reg:CC CC_REGNUM))])]
7510 {
7511 operands[2] = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[0])));
7512 operands[0] = adjust_address (operands[0], BLKmode, 0);
7513 operands[1] = adjust_address (operands[1], BLKmode, 0);
7514 })
7515
7516 (define_peephole2
7517 [(parallel
7518 [(set (match_operand:BLK 0 "memory_operand" "")
7519 (and:BLK (match_dup 0)
7520 (match_operand:BLK 1 "memory_operand" "")))
7521 (use (match_operand 2 "const_int_operand" ""))
7522 (clobber (reg:CC CC_REGNUM))])
7523 (parallel
7524 [(set (match_operand:BLK 3 "memory_operand" "")
7525 (and:BLK (match_dup 3)
7526 (match_operand:BLK 4 "memory_operand" "")))
7527 (use (match_operand 5 "const_int_operand" ""))
7528 (clobber (reg:CC CC_REGNUM))])]
7529 "s390_offset_p (operands[0], operands[3], operands[2])
7530 && s390_offset_p (operands[1], operands[4], operands[2])
7531 && !s390_overlap_p (operands[0], operands[1],
7532 INTVAL (operands[2]) + INTVAL (operands[5]))
7533 && INTVAL (operands[2]) + INTVAL (operands[5]) <= 256"
7534 [(parallel
7535 [(set (match_dup 6) (and:BLK (match_dup 6) (match_dup 7)))
7536 (use (match_dup 8))
7537 (clobber (reg:CC CC_REGNUM))])]
7538 "operands[6] = gen_rtx_MEM (BLKmode, XEXP (operands[0], 0));
7539 operands[7] = gen_rtx_MEM (BLKmode, XEXP (operands[1], 0));
7540 operands[8] = GEN_INT (INTVAL (operands[2]) + INTVAL (operands[5]));")
7541
7542
7543 ;;
7544 ;;- Bit set (inclusive or) instructions.
7545 ;;
7546
7547 (define_expand "ior<mode>3"
7548 [(set (match_operand:INT 0 "nonimmediate_operand" "")
7549 (ior:INT (match_operand:INT 1 "nonimmediate_operand" "")
7550 (match_operand:INT 2 "general_operand" "")))
7551 (clobber (reg:CC CC_REGNUM))]
7552 ""
7553 "s390_expand_logical_operator (IOR, <MODE>mode, operands); DONE;")
7554
7555 ;
7556 ; iordi3 instruction pattern(s).
7557 ;
7558
7559 (define_insn "*iordi3_cc"
7560 [(set (reg CC_REGNUM)
7561 (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,d,0")
7562 (match_operand:DI 2 "general_operand" " d,d,T"))
7563 (const_int 0)))
7564 (set (match_operand:DI 0 "register_operand" "=d,d,d")
7565 (ior:DI (match_dup 1) (match_dup 2)))]
7566 "s390_match_ccmode(insn, CCTmode) && TARGET_ZARCH"
7567 "@
7568 ogr\t%0,%2
7569 ogrk\t%0,%1,%2
7570 og\t%0,%2"
7571 [(set_attr "op_type" "RRE,RRF,RXY")
7572 (set_attr "cpu_facility" "*,z196,*")
7573 (set_attr "z10prop" "z10_super_E1,*,z10_super_E1")])
7574
7575 (define_insn "*iordi3_cconly"
7576 [(set (reg CC_REGNUM)
7577 (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,d,0")
7578 (match_operand:DI 2 "general_operand" " d,d,T"))
7579 (const_int 0)))
7580 (clobber (match_scratch:DI 0 "=d,d,d"))]
7581 "s390_match_ccmode(insn, CCTmode) && TARGET_ZARCH"
7582 "@
7583 ogr\t%0,%2
7584 ogrk\t%0,%1,%2
7585 og\t%0,%2"
7586 [(set_attr "op_type" "RRE,RRF,RXY")
7587 (set_attr "cpu_facility" "*,z196,*")
7588 (set_attr "z10prop" "z10_super_E1,*,z10_super_E1")])
7589
7590 (define_insn "*iordi3"
7591 [(set (match_operand:DI 0 "nonimmediate_operand"
7592 "=d, d, d, d, d, d,d,d,d, AQ,Q")
7593 (ior:DI (match_operand:DI 1 "nonimmediate_operand"
7594 " %0, 0, 0, 0, 0, 0,0,d,0, 0,0")
7595 (match_operand:DI 2 "general_operand"
7596 "N0HD0,N1HD0,N2HD0,N3HD0,N0SD0,N1SD0,d,d,T,NxQD0,Q")))
7597 (clobber (reg:CC CC_REGNUM))]
7598 "TARGET_ZARCH && s390_logical_operator_ok_p (operands)"
7599 "@
7600 oihh\t%0,%i2
7601 oihl\t%0,%i2
7602 oilh\t%0,%i2
7603 oill\t%0,%i2
7604 oihf\t%0,%k2
7605 oilf\t%0,%k2
7606 ogr\t%0,%2
7607 ogrk\t%0,%1,%2
7608 og\t%0,%2
7609 #
7610 #"
7611 [(set_attr "op_type" "RI,RI,RI,RI,RIL,RIL,RRE,RRF,RXY,SI,SS")
7612 (set_attr "cpu_facility" "*,*,*,*,extimm,extimm,*,z196,*,*,*")
7613 (set_attr "z10prop" "z10_super_E1,
7614 z10_super_E1,
7615 z10_super_E1,
7616 z10_super_E1,
7617 z10_super_E1,
7618 z10_super_E1,
7619 z10_super_E1,
7620 *,
7621 z10_super_E1,
7622 *,
7623 *")])
7624
7625 (define_split
7626 [(set (match_operand:DI 0 "s_operand" "")
7627 (ior:DI (match_dup 0) (match_operand:DI 1 "immediate_operand" "")))
7628 (clobber (reg:CC CC_REGNUM))]
7629 "reload_completed"
7630 [(parallel
7631 [(set (match_dup 0) (ior:QI (match_dup 0) (match_dup 1)))
7632 (clobber (reg:CC CC_REGNUM))])]
7633 "s390_narrow_logical_operator (IOR, &operands[0], &operands[1]);")
7634
7635 ;
7636 ; iorsi3 instruction pattern(s).
7637 ;
7638
7639 (define_insn "*iorsi3_cc"
7640 [(set (reg CC_REGNUM)
7641 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,d,0,0")
7642 (match_operand:SI 2 "general_operand" "Os,d,d,R,T"))
7643 (const_int 0)))
7644 (set (match_operand:SI 0 "register_operand" "=d,d,d,d,d")
7645 (ior:SI (match_dup 1) (match_dup 2)))]
7646 "s390_match_ccmode(insn, CCTmode)"
7647 "@
7648 oilf\t%0,%o2
7649 or\t%0,%2
7650 ork\t%0,%1,%2
7651 o\t%0,%2
7652 oy\t%0,%2"
7653 [(set_attr "op_type" "RIL,RR,RRF,RX,RXY")
7654 (set_attr "cpu_facility" "*,*,z196,*,longdisp")
7655 (set_attr "z10prop" "z10_super_E1,z10_super_E1,*,z10_super_E1,z10_super_E1")])
7656
7657 (define_insn "*iorsi3_cconly"
7658 [(set (reg CC_REGNUM)
7659 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,d,0,0")
7660 (match_operand:SI 2 "general_operand" "Os,d,d,R,T"))
7661 (const_int 0)))
7662 (clobber (match_scratch:SI 0 "=d,d,d,d,d"))]
7663 "s390_match_ccmode(insn, CCTmode)"
7664 "@
7665 oilf\t%0,%o2
7666 or\t%0,%2
7667 ork\t%0,%1,%2
7668 o\t%0,%2
7669 oy\t%0,%2"
7670 [(set_attr "op_type" "RIL,RR,RRF,RX,RXY")
7671 (set_attr "cpu_facility" "*,*,z196,*,longdisp")
7672 (set_attr "z10prop" "z10_super_E1,z10_super_E1,*,z10_super_E1,z10_super_E1")])
7673
7674 (define_insn "*iorsi3_zarch"
7675 [(set (match_operand:SI 0 "nonimmediate_operand" "=d, d, d,d,d,d,d, AQ,Q")
7676 (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0, 0, 0,0,d,0,0, 0,0")
7677 (match_operand:SI 2 "general_operand" "N0HS0,N1HS0,Os,d,d,R,T,NxQS0,Q")))
7678 (clobber (reg:CC CC_REGNUM))]
7679 "TARGET_ZARCH && s390_logical_operator_ok_p (operands)"
7680 "@
7681 oilh\t%0,%i2
7682 oill\t%0,%i2
7683 oilf\t%0,%o2
7684 or\t%0,%2
7685 ork\t%0,%1,%2
7686 o\t%0,%2
7687 oy\t%0,%2
7688 #
7689 #"
7690 [(set_attr "op_type" "RI,RI,RIL,RR,RRF,RX,RXY,SI,SS")
7691 (set_attr "cpu_facility" "*,*,*,*,z196,*,longdisp,*,*")
7692 (set_attr "z10prop" "z10_super_E1,
7693 z10_super_E1,
7694 z10_super_E1,
7695 z10_super_E1,
7696 *,
7697 z10_super_E1,
7698 z10_super_E1,
7699 *,
7700 *")])
7701
7702 (define_insn "*iorsi3_esa"
7703 [(set (match_operand:SI 0 "nonimmediate_operand" "=d,d,AQ,Q")
7704 (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,0,0")
7705 (match_operand:SI 2 "general_operand" "d,R,NxQS0,Q")))
7706 (clobber (reg:CC CC_REGNUM))]
7707 "!TARGET_ZARCH && s390_logical_operator_ok_p (operands)"
7708 "@
7709 or\t%0,%2
7710 o\t%0,%2
7711 #
7712 #"
7713 [(set_attr "op_type" "RR,RX,SI,SS")
7714 (set_attr "z10prop" "z10_super_E1,z10_super_E1,*,*")])
7715
7716 (define_split
7717 [(set (match_operand:SI 0 "s_operand" "")
7718 (ior:SI (match_dup 0) (match_operand:SI 1 "immediate_operand" "")))
7719 (clobber (reg:CC CC_REGNUM))]
7720 "reload_completed"
7721 [(parallel
7722 [(set (match_dup 0) (ior:QI (match_dup 0) (match_dup 1)))
7723 (clobber (reg:CC CC_REGNUM))])]
7724 "s390_narrow_logical_operator (IOR, &operands[0], &operands[1]);")
7725
7726 ;
7727 ; iorhi3 instruction pattern(s).
7728 ;
7729
7730 (define_insn "*iorhi3_zarch"
7731 [(set (match_operand:HI 0 "nonimmediate_operand" "=d,d,d, AQ,Q")
7732 (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,d,0, 0,0")
7733 (match_operand:HI 2 "general_operand" " d,d,n,NxQH0,Q")))
7734 (clobber (reg:CC CC_REGNUM))]
7735 "TARGET_ZARCH && s390_logical_operator_ok_p (operands)"
7736 "@
7737 or\t%0,%2
7738 ork\t%0,%1,%2
7739 oill\t%0,%x2
7740 #
7741 #"
7742 [(set_attr "op_type" "RR,RRF,RI,SI,SS")
7743 (set_attr "cpu_facility" "*,z196,*,*,*")
7744 (set_attr "z10prop" "z10_super_E1,*,z10_super_E1,*,*")])
7745
7746 (define_insn "*iorhi3_esa"
7747 [(set (match_operand:HI 0 "nonimmediate_operand" "=d,AQ,Q")
7748 (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,0")
7749 (match_operand:HI 2 "general_operand" "d,NxQH0,Q")))
7750 (clobber (reg:CC CC_REGNUM))]
7751 "!TARGET_ZARCH && s390_logical_operator_ok_p (operands)"
7752 "@
7753 or\t%0,%2
7754 #
7755 #"
7756 [(set_attr "op_type" "RR,SI,SS")
7757 (set_attr "z10prop" "z10_super_E1,*,*")])
7758
7759 (define_split
7760 [(set (match_operand:HI 0 "s_operand" "")
7761 (ior:HI (match_dup 0) (match_operand:HI 1 "immediate_operand" "")))
7762 (clobber (reg:CC CC_REGNUM))]
7763 "reload_completed"
7764 [(parallel
7765 [(set (match_dup 0) (ior:QI (match_dup 0) (match_dup 1)))
7766 (clobber (reg:CC CC_REGNUM))])]
7767 "s390_narrow_logical_operator (IOR, &operands[0], &operands[1]);")
7768
7769 ;
7770 ; iorqi3 instruction pattern(s).
7771 ;
7772
7773 (define_insn "*iorqi3_zarch"
7774 [(set (match_operand:QI 0 "nonimmediate_operand" "=d,d,d,Q,S,Q")
7775 (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,d,0,0,0,0")
7776 (match_operand:QI 2 "general_operand" " d,d,n,n,n,Q")))
7777 (clobber (reg:CC CC_REGNUM))]
7778 "TARGET_ZARCH && s390_logical_operator_ok_p (operands)"
7779 "@
7780 or\t%0,%2
7781 ork\t%0,%1,%2
7782 oill\t%0,%b2
7783 oi\t%S0,%b2
7784 oiy\t%S0,%b2
7785 #"
7786 [(set_attr "op_type" "RR,RRF,RI,SI,SIY,SS")
7787 (set_attr "cpu_facility" "*,z196,*,*,longdisp,*")
7788 (set_attr "z10prop" "z10_super_E1,*,z10_super_E1,
7789 z10_super,z10_super,*")])
7790
7791 (define_insn "*iorqi3_esa"
7792 [(set (match_operand:QI 0 "nonimmediate_operand" "=d,Q,Q")
7793 (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
7794 (match_operand:QI 2 "general_operand" "d,n,Q")))
7795 (clobber (reg:CC CC_REGNUM))]
7796 "!TARGET_ZARCH && s390_logical_operator_ok_p (operands)"
7797 "@
7798 or\t%0,%2
7799 oi\t%S0,%b2
7800 #"
7801 [(set_attr "op_type" "RR,SI,SS")
7802 (set_attr "z10prop" "z10_super_E1,z10_super,*")])
7803
7804 ;
7805 ; Block inclusive or (OC) patterns.
7806 ;
7807
7808 (define_insn "*oc"
7809 [(set (match_operand:BLK 0 "memory_operand" "=Q")
7810 (ior:BLK (match_dup 0)
7811 (match_operand:BLK 1 "memory_operand" "Q")))
7812 (use (match_operand 2 "const_int_operand" "n"))
7813 (clobber (reg:CC CC_REGNUM))]
7814 "INTVAL (operands[2]) >= 1 && INTVAL (operands[2]) <= 256"
7815 "oc\t%O0(%2,%R0),%S1"
7816 [(set_attr "op_type" "SS")
7817 (set_attr "z196prop" "z196_cracked")])
7818
7819 (define_split
7820 [(set (match_operand 0 "memory_operand" "")
7821 (ior (match_dup 0)
7822 (match_operand 1 "memory_operand" "")))
7823 (clobber (reg:CC CC_REGNUM))]
7824 "reload_completed
7825 && GET_MODE (operands[0]) == GET_MODE (operands[1])
7826 && GET_MODE_SIZE (GET_MODE (operands[0])) > 0"
7827 [(parallel
7828 [(set (match_dup 0) (ior:BLK (match_dup 0) (match_dup 1)))
7829 (use (match_dup 2))
7830 (clobber (reg:CC CC_REGNUM))])]
7831 {
7832 operands[2] = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[0])));
7833 operands[0] = adjust_address (operands[0], BLKmode, 0);
7834 operands[1] = adjust_address (operands[1], BLKmode, 0);
7835 })
7836
7837 (define_peephole2
7838 [(parallel
7839 [(set (match_operand:BLK 0 "memory_operand" "")
7840 (ior:BLK (match_dup 0)
7841 (match_operand:BLK 1 "memory_operand" "")))
7842 (use (match_operand 2 "const_int_operand" ""))
7843 (clobber (reg:CC CC_REGNUM))])
7844 (parallel
7845 [(set (match_operand:BLK 3 "memory_operand" "")
7846 (ior:BLK (match_dup 3)
7847 (match_operand:BLK 4 "memory_operand" "")))
7848 (use (match_operand 5 "const_int_operand" ""))
7849 (clobber (reg:CC CC_REGNUM))])]
7850 "s390_offset_p (operands[0], operands[3], operands[2])
7851 && s390_offset_p (operands[1], operands[4], operands[2])
7852 && !s390_overlap_p (operands[0], operands[1],
7853 INTVAL (operands[2]) + INTVAL (operands[5]))
7854 && INTVAL (operands[2]) + INTVAL (operands[5]) <= 256"
7855 [(parallel
7856 [(set (match_dup 6) (ior:BLK (match_dup 6) (match_dup 7)))
7857 (use (match_dup 8))
7858 (clobber (reg:CC CC_REGNUM))])]
7859 "operands[6] = gen_rtx_MEM (BLKmode, XEXP (operands[0], 0));
7860 operands[7] = gen_rtx_MEM (BLKmode, XEXP (operands[1], 0));
7861 operands[8] = GEN_INT (INTVAL (operands[2]) + INTVAL (operands[5]));")
7862
7863
7864 ;;
7865 ;;- Xor instructions.
7866 ;;
7867
7868 (define_expand "xor<mode>3"
7869 [(set (match_operand:INT 0 "nonimmediate_operand" "")
7870 (xor:INT (match_operand:INT 1 "nonimmediate_operand" "")
7871 (match_operand:INT 2 "general_operand" "")))
7872 (clobber (reg:CC CC_REGNUM))]
7873 ""
7874 "s390_expand_logical_operator (XOR, <MODE>mode, operands); DONE;")
7875
7876 ; Combine replaces (xor (x) (const_int -1)) with (not (x)) when doing
7877 ; simplifications. So its better to have something matching.
7878 (define_split
7879 [(set (match_operand:INT 0 "nonimmediate_operand" "")
7880 (not:INT (match_operand:INT 1 "nonimmediate_operand" "")))]
7881 ""
7882 [(parallel
7883 [(set (match_dup 0) (xor:INT (match_dup 1) (match_dup 2)))
7884 (clobber (reg:CC CC_REGNUM))])]
7885 {
7886 operands[2] = constm1_rtx;
7887 if (!s390_logical_operator_ok_p (operands))
7888 FAIL;
7889 })
7890
7891 ;
7892 ; xordi3 instruction pattern(s).
7893 ;
7894
7895 (define_insn "*xordi3_cc"
7896 [(set (reg CC_REGNUM)
7897 (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,d,0")
7898 (match_operand:DI 2 "general_operand" " d,d,T"))
7899 (const_int 0)))
7900 (set (match_operand:DI 0 "register_operand" "=d,d,d")
7901 (xor:DI (match_dup 1) (match_dup 2)))]
7902 "s390_match_ccmode(insn, CCTmode) && TARGET_ZARCH"
7903 "@
7904 xgr\t%0,%2
7905 xgrk\t%0,%1,%2
7906 xg\t%0,%2"
7907 [(set_attr "op_type" "RRE,RRF,RXY")
7908 (set_attr "cpu_facility" "*,z196,*")
7909 (set_attr "z10prop" "z10_super_E1,*,z10_super_E1")])
7910
7911 (define_insn "*xordi3_cconly"
7912 [(set (reg CC_REGNUM)
7913 (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,d,0")
7914 (match_operand:DI 2 "general_operand" " d,d,T"))
7915 (const_int 0)))
7916 (clobber (match_scratch:DI 0 "=d,d,d"))]
7917 "s390_match_ccmode(insn, CCTmode) && TARGET_ZARCH"
7918 "@
7919 xgr\t%0,%2
7920 xgrk\t%0,%1,%2
7921 xg\t%0,%2"
7922 [(set_attr "op_type" "RRE,RRF,RXY")
7923 (set_attr "cpu_facility" "*,z196,*")
7924 (set_attr "z10prop" "z10_super_E1,*,z10_super_E1")])
7925
7926 (define_insn "*xordi3"
7927 [(set (match_operand:DI 0 "nonimmediate_operand" "=d, d,d,d,d, AQ,Q")
7928 (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0, 0,0,d,0, 0,0")
7929 (match_operand:DI 2 "general_operand" "N0SD0,N1SD0,d,d,T,NxQD0,Q")))
7930 (clobber (reg:CC CC_REGNUM))]
7931 "TARGET_ZARCH && s390_logical_operator_ok_p (operands)"
7932 "@
7933 xihf\t%0,%k2
7934 xilf\t%0,%k2
7935 xgr\t%0,%2
7936 xgrk\t%0,%1,%2
7937 xg\t%0,%2
7938 #
7939 #"
7940 [(set_attr "op_type" "RIL,RIL,RRE,RRF,RXY,SI,SS")
7941 (set_attr "cpu_facility" "extimm,extimm,*,z196,*,*,*")
7942 (set_attr "z10prop" "z10_super_E1,z10_super_E1,z10_super_E1,
7943 *,z10_super_E1,*,*")])
7944
7945 (define_split
7946 [(set (match_operand:DI 0 "s_operand" "")
7947 (xor:DI (match_dup 0) (match_operand:DI 1 "immediate_operand" "")))
7948 (clobber (reg:CC CC_REGNUM))]
7949 "reload_completed"
7950 [(parallel
7951 [(set (match_dup 0) (xor:QI (match_dup 0) (match_dup 1)))
7952 (clobber (reg:CC CC_REGNUM))])]
7953 "s390_narrow_logical_operator (XOR, &operands[0], &operands[1]);")
7954
7955 ;
7956 ; xorsi3 instruction pattern(s).
7957 ;
7958
7959 (define_insn "*xorsi3_cc"
7960 [(set (reg CC_REGNUM)
7961 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,d,0,0")
7962 (match_operand:SI 2 "general_operand" "Os,d,d,R,T"))
7963 (const_int 0)))
7964 (set (match_operand:SI 0 "register_operand" "=d,d,d,d,d")
7965 (xor:SI (match_dup 1) (match_dup 2)))]
7966 "s390_match_ccmode(insn, CCTmode)"
7967 "@
7968 xilf\t%0,%o2
7969 xr\t%0,%2
7970 xrk\t%0,%1,%2
7971 x\t%0,%2
7972 xy\t%0,%2"
7973 [(set_attr "op_type" "RIL,RR,RRF,RX,RXY")
7974 (set_attr "cpu_facility" "*,*,z196,*,longdisp")
7975 (set_attr "z10prop" "z10_super_E1,z10_super_E1,*,
7976 z10_super_E1,z10_super_E1")])
7977
7978 (define_insn "*xorsi3_cconly"
7979 [(set (reg CC_REGNUM)
7980 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,d,0,0")
7981 (match_operand:SI 2 "general_operand" "Os,d,d,R,T"))
7982 (const_int 0)))
7983 (clobber (match_scratch:SI 0 "=d,d,d,d,d"))]
7984 "s390_match_ccmode(insn, CCTmode)"
7985 "@
7986 xilf\t%0,%o2
7987 xr\t%0,%2
7988 xrk\t%0,%1,%2
7989 x\t%0,%2
7990 xy\t%0,%2"
7991 [(set_attr "op_type" "RIL,RR,RRF,RX,RXY")
7992 (set_attr "cpu_facility" "*,*,z196,*,longdisp")
7993 (set_attr "z10prop" "z10_super_E1,z10_super_E1,*,
7994 z10_super_E1,z10_super_E1")])
7995
7996 (define_insn "*xorsi3"
7997 [(set (match_operand:SI 0 "nonimmediate_operand" "=d,d,d,d,d, AQ,Q")
7998 (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,d,0,0, 0,0")
7999 (match_operand:SI 2 "general_operand" "Os,d,d,R,T,NxQS0,Q")))
8000 (clobber (reg:CC CC_REGNUM))]
8001 "s390_logical_operator_ok_p (operands)"
8002 "@
8003 xilf\t%0,%o2
8004 xr\t%0,%2
8005 xrk\t%0,%1,%2
8006 x\t%0,%2
8007 xy\t%0,%2
8008 #
8009 #"
8010 [(set_attr "op_type" "RIL,RR,RRF,RX,RXY,SI,SS")
8011 (set_attr "cpu_facility" "*,*,z196,*,longdisp,*,*")
8012 (set_attr "z10prop" "z10_super_E1,z10_super_E1,*,
8013 z10_super_E1,z10_super_E1,*,*")])
8014
8015 (define_split
8016 [(set (match_operand:SI 0 "s_operand" "")
8017 (xor:SI (match_dup 0) (match_operand:SI 1 "immediate_operand" "")))
8018 (clobber (reg:CC CC_REGNUM))]
8019 "reload_completed"
8020 [(parallel
8021 [(set (match_dup 0) (xor:QI (match_dup 0) (match_dup 1)))
8022 (clobber (reg:CC CC_REGNUM))])]
8023 "s390_narrow_logical_operator (XOR, &operands[0], &operands[1]);")
8024
8025 ;
8026 ; xorhi3 instruction pattern(s).
8027 ;
8028
8029 (define_insn "*xorhi3"
8030 [(set (match_operand:HI 0 "nonimmediate_operand" "=d,d,d, AQ,Q")
8031 (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,d, 0,0")
8032 (match_operand:HI 2 "general_operand" "Os,d,d,NxQH0,Q")))
8033 (clobber (reg:CC CC_REGNUM))]
8034 "s390_logical_operator_ok_p (operands)"
8035 "@
8036 xilf\t%0,%x2
8037 xr\t%0,%2
8038 xrk\t%0,%1,%2
8039 #
8040 #"
8041 [(set_attr "op_type" "RIL,RR,RRF,SI,SS")
8042 (set_attr "cpu_facility" "*,*,z196,*,*")
8043 (set_attr "z10prop" "z10_super_E1,z10_super_E1,*,*,*")])
8044
8045 (define_split
8046 [(set (match_operand:HI 0 "s_operand" "")
8047 (xor:HI (match_dup 0) (match_operand:HI 1 "immediate_operand" "")))
8048 (clobber (reg:CC CC_REGNUM))]
8049 "reload_completed"
8050 [(parallel
8051 [(set (match_dup 0) (xor:QI (match_dup 0) (match_dup 1)))
8052 (clobber (reg:CC CC_REGNUM))])]
8053 "s390_narrow_logical_operator (XOR, &operands[0], &operands[1]);")
8054
8055 ;
8056 ; xorqi3 instruction pattern(s).
8057 ;
8058
8059 (define_insn "*xorqi3"
8060 [(set (match_operand:QI 0 "nonimmediate_operand" "=d,d,d,Q,S,Q")
8061 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,d,0,0,0")
8062 (match_operand:QI 2 "general_operand" "Os,d,d,n,n,Q")))
8063 (clobber (reg:CC CC_REGNUM))]
8064 "s390_logical_operator_ok_p (operands)"
8065 "@
8066 xilf\t%0,%b2
8067 xr\t%0,%2
8068 xrk\t%0,%1,%2
8069 xi\t%S0,%b2
8070 xiy\t%S0,%b2
8071 #"
8072 [(set_attr "op_type" "RIL,RR,RRF,SI,SIY,SS")
8073 (set_attr "cpu_facility" "*,*,z196,*,longdisp,*")
8074 (set_attr "z10prop" "z10_super_E1,z10_super_E1,*,z10_super,z10_super,*")])
8075
8076
8077 ;
8078 ; Block exclusive or (XC) patterns.
8079 ;
8080
8081 (define_insn "*xc"
8082 [(set (match_operand:BLK 0 "memory_operand" "=Q")
8083 (xor:BLK (match_dup 0)
8084 (match_operand:BLK 1 "memory_operand" "Q")))
8085 (use (match_operand 2 "const_int_operand" "n"))
8086 (clobber (reg:CC CC_REGNUM))]
8087 "INTVAL (operands[2]) >= 1 && INTVAL (operands[2]) <= 256"
8088 "xc\t%O0(%2,%R0),%S1"
8089 [(set_attr "op_type" "SS")])
8090
8091 (define_split
8092 [(set (match_operand 0 "memory_operand" "")
8093 (xor (match_dup 0)
8094 (match_operand 1 "memory_operand" "")))
8095 (clobber (reg:CC CC_REGNUM))]
8096 "reload_completed
8097 && GET_MODE (operands[0]) == GET_MODE (operands[1])
8098 && GET_MODE_SIZE (GET_MODE (operands[0])) > 0"
8099 [(parallel
8100 [(set (match_dup 0) (xor:BLK (match_dup 0) (match_dup 1)))
8101 (use (match_dup 2))
8102 (clobber (reg:CC CC_REGNUM))])]
8103 {
8104 operands[2] = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[0])));
8105 operands[0] = adjust_address (operands[0], BLKmode, 0);
8106 operands[1] = adjust_address (operands[1], BLKmode, 0);
8107 })
8108
8109 (define_peephole2
8110 [(parallel
8111 [(set (match_operand:BLK 0 "memory_operand" "")
8112 (xor:BLK (match_dup 0)
8113 (match_operand:BLK 1 "memory_operand" "")))
8114 (use (match_operand 2 "const_int_operand" ""))
8115 (clobber (reg:CC CC_REGNUM))])
8116 (parallel
8117 [(set (match_operand:BLK 3 "memory_operand" "")
8118 (xor:BLK (match_dup 3)
8119 (match_operand:BLK 4 "memory_operand" "")))
8120 (use (match_operand 5 "const_int_operand" ""))
8121 (clobber (reg:CC CC_REGNUM))])]
8122 "s390_offset_p (operands[0], operands[3], operands[2])
8123 && s390_offset_p (operands[1], operands[4], operands[2])
8124 && !s390_overlap_p (operands[0], operands[1],
8125 INTVAL (operands[2]) + INTVAL (operands[5]))
8126 && INTVAL (operands[2]) + INTVAL (operands[5]) <= 256"
8127 [(parallel
8128 [(set (match_dup 6) (xor:BLK (match_dup 6) (match_dup 7)))
8129 (use (match_dup 8))
8130 (clobber (reg:CC CC_REGNUM))])]
8131 "operands[6] = gen_rtx_MEM (BLKmode, XEXP (operands[0], 0));
8132 operands[7] = gen_rtx_MEM (BLKmode, XEXP (operands[1], 0));
8133 operands[8] = GEN_INT (INTVAL (operands[2]) + INTVAL (operands[5]));")
8134
8135 ;
8136 ; Block xor (XC) patterns with src == dest.
8137 ;
8138
8139 (define_insn "*xc_zero"
8140 [(set (match_operand:BLK 0 "memory_operand" "=Q")
8141 (const_int 0))
8142 (use (match_operand 1 "const_int_operand" "n"))
8143 (clobber (reg:CC CC_REGNUM))]
8144 "INTVAL (operands[1]) >= 1 && INTVAL (operands[1]) <= 256"
8145 "xc\t%O0(%1,%R0),%S0"
8146 [(set_attr "op_type" "SS")
8147 (set_attr "z196prop" "z196_cracked")])
8148
8149 (define_peephole2
8150 [(parallel
8151 [(set (match_operand:BLK 0 "memory_operand" "")
8152 (const_int 0))
8153 (use (match_operand 1 "const_int_operand" ""))
8154 (clobber (reg:CC CC_REGNUM))])
8155 (parallel
8156 [(set (match_operand:BLK 2 "memory_operand" "")
8157 (const_int 0))
8158 (use (match_operand 3 "const_int_operand" ""))
8159 (clobber (reg:CC CC_REGNUM))])]
8160 "s390_offset_p (operands[0], operands[2], operands[1])
8161 && INTVAL (operands[1]) + INTVAL (operands[3]) <= 256"
8162 [(parallel
8163 [(set (match_dup 4) (const_int 0))
8164 (use (match_dup 5))
8165 (clobber (reg:CC CC_REGNUM))])]
8166 "operands[4] = gen_rtx_MEM (BLKmode, XEXP (operands[0], 0));
8167 operands[5] = GEN_INT (INTVAL (operands[1]) + INTVAL (operands[3]));")
8168
8169
8170 ;;
8171 ;;- Negate instructions.
8172 ;;
8173
8174 ;
8175 ; neg(di|si)2 instruction pattern(s).
8176 ;
8177
8178 (define_expand "neg<mode>2"
8179 [(parallel
8180 [(set (match_operand:DSI 0 "register_operand" "=d")
8181 (neg:DSI (match_operand:DSI 1 "register_operand" "d")))
8182 (clobber (reg:CC CC_REGNUM))])]
8183 ""
8184 "")
8185
8186 (define_insn "*negdi2_sign_cc"
8187 [(set (reg CC_REGNUM)
8188 (compare (neg:DI (ashiftrt:DI (ashift:DI (subreg:DI
8189 (match_operand:SI 1 "register_operand" "d") 0)
8190 (const_int 32)) (const_int 32)))
8191 (const_int 0)))
8192 (set (match_operand:DI 0 "register_operand" "=d")
8193 (neg:DI (sign_extend:DI (match_dup 1))))]
8194 "TARGET_ZARCH && s390_match_ccmode (insn, CCAmode)"
8195 "lcgfr\t%0,%1"
8196 [(set_attr "op_type" "RRE")
8197 (set_attr "z10prop" "z10_c")])
8198
8199 (define_insn "*negdi2_sign"
8200 [(set (match_operand:DI 0 "register_operand" "=d")
8201 (neg:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "d"))))
8202 (clobber (reg:CC CC_REGNUM))]
8203 "TARGET_ZARCH"
8204 "lcgfr\t%0,%1"
8205 [(set_attr "op_type" "RRE")
8206 (set_attr "z10prop" "z10_c")])
8207
8208 ; lcr, lcgr
8209 (define_insn "*neg<mode>2_cc"
8210 [(set (reg CC_REGNUM)
8211 (compare (neg:GPR (match_operand:GPR 1 "register_operand" "d"))
8212 (const_int 0)))
8213 (set (match_operand:GPR 0 "register_operand" "=d")
8214 (neg:GPR (match_dup 1)))]
8215 "s390_match_ccmode (insn, CCAmode)"
8216 "lc<g>r\t%0,%1"
8217 [(set_attr "op_type" "RR<E>")
8218 (set_attr "z10prop" "z10_super_c_E1")])
8219
8220 ; lcr, lcgr
8221 (define_insn "*neg<mode>2_cconly"
8222 [(set (reg CC_REGNUM)
8223 (compare (neg:GPR (match_operand:GPR 1 "register_operand" "d"))
8224 (const_int 0)))
8225 (clobber (match_scratch:GPR 0 "=d"))]
8226 "s390_match_ccmode (insn, CCAmode)"
8227 "lc<g>r\t%0,%1"
8228 [(set_attr "op_type" "RR<E>")
8229 (set_attr "z10prop" "z10_super_c_E1")])
8230
8231 ; lcr, lcgr
8232 (define_insn "*neg<mode>2"
8233 [(set (match_operand:GPR 0 "register_operand" "=d")
8234 (neg:GPR (match_operand:GPR 1 "register_operand" "d")))
8235 (clobber (reg:CC CC_REGNUM))]
8236 ""
8237 "lc<g>r\t%0,%1"
8238 [(set_attr "op_type" "RR<E>")
8239 (set_attr "z10prop" "z10_super_c_E1")])
8240
8241 (define_insn "*negdi2_31"
8242 [(set (match_operand:DI 0 "register_operand" "=d")
8243 (neg:DI (match_operand:DI 1 "register_operand" "d")))
8244 (clobber (reg:CC CC_REGNUM))]
8245 "!TARGET_ZARCH"
8246 "#")
8247
8248 ; Split a DImode NEG on 31bit into 2 SImode NEGs
8249
8250 ; Doing the twos complement separately on the SImode parts does an
8251 ; unwanted +1 on the high part which needs to be subtracted afterwards
8252 ; ... unless the +1 on the low part created an overflow.
8253
8254 (define_split
8255 [(set (match_operand:DI 0 "register_operand" "")
8256 (neg:DI (match_operand:DI 1 "register_operand" "")))
8257 (clobber (reg:CC CC_REGNUM))]
8258 "!TARGET_ZARCH
8259 && (REGNO (operands[0]) == REGNO (operands[1])
8260 || s390_split_ok_p (operands[0], operands[1], DImode, 0))
8261 && reload_completed"
8262 [(parallel
8263 [(set (match_dup 2) (neg:SI (match_dup 3)))
8264 (clobber (reg:CC CC_REGNUM))])
8265 (parallel
8266 [(set (reg:CCAP CC_REGNUM)
8267 (compare:CCAP (neg:SI (match_dup 5)) (const_int 0)))
8268 (set (match_dup 4) (neg:SI (match_dup 5)))])
8269 (set (pc)
8270 (if_then_else (ne (reg:CCAP CC_REGNUM) (const_int 0))
8271 (pc)
8272 (label_ref (match_dup 6))))
8273 (parallel
8274 [(set (match_dup 2) (plus:SI (match_dup 2) (const_int -1)))
8275 (clobber (reg:CC CC_REGNUM))])
8276 (match_dup 6)]
8277 "operands[2] = operand_subword (operands[0], 0, 0, DImode);
8278 operands[3] = operand_subword (operands[1], 0, 0, DImode);
8279 operands[4] = operand_subword (operands[0], 1, 0, DImode);
8280 operands[5] = operand_subword (operands[1], 1, 0, DImode);
8281 operands[6] = gen_label_rtx ();")
8282
8283 ; Like above but first make a copy of the low part of the src operand
8284 ; since it might overlap with the high part of the destination.
8285
8286 (define_split
8287 [(set (match_operand:DI 0 "register_operand" "")
8288 (neg:DI (match_operand:DI 1 "register_operand" "")))
8289 (clobber (reg:CC CC_REGNUM))]
8290 "!TARGET_ZARCH
8291 && s390_split_ok_p (operands[0], operands[1], DImode, 1)
8292 && reload_completed"
8293 [; Make a backup of op5 first
8294 (set (match_dup 4) (match_dup 5))
8295 ; Setting op2 here might clobber op5
8296 (parallel
8297 [(set (match_dup 2) (neg:SI (match_dup 3)))
8298 (clobber (reg:CC CC_REGNUM))])
8299 (parallel
8300 [(set (reg:CCAP CC_REGNUM)
8301 (compare:CCAP (neg:SI (match_dup 4)) (const_int 0)))
8302 (set (match_dup 4) (neg:SI (match_dup 4)))])
8303 (set (pc)
8304 (if_then_else (ne (reg:CCAP CC_REGNUM) (const_int 0))
8305 (pc)
8306 (label_ref (match_dup 6))))
8307 (parallel
8308 [(set (match_dup 2) (plus:SI (match_dup 2) (const_int -1)))
8309 (clobber (reg:CC CC_REGNUM))])
8310 (match_dup 6)]
8311 "operands[2] = operand_subword (operands[0], 0, 0, DImode);
8312 operands[3] = operand_subword (operands[1], 0, 0, DImode);
8313 operands[4] = operand_subword (operands[0], 1, 0, DImode);
8314 operands[5] = operand_subword (operands[1], 1, 0, DImode);
8315 operands[6] = gen_label_rtx ();")
8316
8317 ;
8318 ; neg(df|sf)2 instruction pattern(s).
8319 ;
8320
8321 (define_expand "neg<mode>2"
8322 [(parallel
8323 [(set (match_operand:BFP 0 "register_operand" "=f")
8324 (neg:BFP (match_operand:BFP 1 "register_operand" "f")))
8325 (clobber (reg:CC CC_REGNUM))])]
8326 "TARGET_HARD_FLOAT"
8327 "")
8328
8329 ; lcxbr, lcdbr, lcebr
8330 (define_insn "*neg<mode>2_cc"
8331 [(set (reg CC_REGNUM)
8332 (compare (neg:BFP (match_operand:BFP 1 "register_operand" "f"))
8333 (match_operand:BFP 2 "const0_operand" "")))
8334 (set (match_operand:BFP 0 "register_operand" "=f")
8335 (neg:BFP (match_dup 1)))]
8336 "s390_match_ccmode (insn, CCSmode) && TARGET_HARD_FLOAT"
8337 "lc<xde>br\t%0,%1"
8338 [(set_attr "op_type" "RRE")
8339 (set_attr "type" "fsimp<mode>")])
8340
8341 ; lcxbr, lcdbr, lcebr
8342 (define_insn "*neg<mode>2_cconly"
8343 [(set (reg CC_REGNUM)
8344 (compare (neg:BFP (match_operand:BFP 1 "register_operand" "f"))
8345 (match_operand:BFP 2 "const0_operand" "")))
8346 (clobber (match_scratch:BFP 0 "=f"))]
8347 "s390_match_ccmode (insn, CCSmode) && TARGET_HARD_FLOAT"
8348 "lc<xde>br\t%0,%1"
8349 [(set_attr "op_type" "RRE")
8350 (set_attr "type" "fsimp<mode>")])
8351
8352 ; lcdfr
8353 (define_insn "*neg<mode>2_nocc"
8354 [(set (match_operand:FP 0 "register_operand" "=f")
8355 (neg:FP (match_operand:FP 1 "register_operand" "<fT0>")))]
8356 "TARGET_DFP"
8357 "lcdfr\t%0,%1"
8358 [(set_attr "op_type" "RRE")
8359 (set_attr "type" "fsimp<mode>")])
8360
8361 ; lcxbr, lcdbr, lcebr
8362 ; FIXME: wflcdb does not clobber cc
8363 (define_insn "*neg<mode>2"
8364 [(set (match_operand:BFP 0 "register_operand" "=f,v")
8365 (neg:BFP (match_operand:BFP 1 "register_operand" "f,v")))
8366 (clobber (reg:CC CC_REGNUM))]
8367 "TARGET_HARD_FLOAT"
8368 "@
8369 lc<xde>br\t%0,%1
8370 wflcdb\t%0,%1"
8371 [(set_attr "op_type" "RRE,VRR")
8372 (set_attr "cpu_facility" "*,vx")
8373 (set_attr "type" "fsimp<mode>,*")
8374 (set_attr "enabled" "*,<DFDI>")])
8375
8376
8377 ;;
8378 ;;- Absolute value instructions.
8379 ;;
8380
8381 ;
8382 ; abs(di|si)2 instruction pattern(s).
8383 ;
8384
8385 (define_insn "*absdi2_sign_cc"
8386 [(set (reg CC_REGNUM)
8387 (compare (abs:DI (ashiftrt:DI (ashift:DI (subreg:DI
8388 (match_operand:SI 1 "register_operand" "d") 0)
8389 (const_int 32)) (const_int 32)))
8390 (const_int 0)))
8391 (set (match_operand:DI 0 "register_operand" "=d")
8392 (abs:DI (sign_extend:DI (match_dup 1))))]
8393 "TARGET_ZARCH && s390_match_ccmode (insn, CCAmode)"
8394 "lpgfr\t%0,%1"
8395 [(set_attr "op_type" "RRE")
8396 (set_attr "z10prop" "z10_c")])
8397
8398 (define_insn "*absdi2_sign"
8399 [(set (match_operand:DI 0 "register_operand" "=d")
8400 (abs:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "d"))))
8401 (clobber (reg:CC CC_REGNUM))]
8402 "TARGET_ZARCH"
8403 "lpgfr\t%0,%1"
8404 [(set_attr "op_type" "RRE")
8405 (set_attr "z10prop" "z10_c")])
8406
8407 ; lpr, lpgr
8408 (define_insn "*abs<mode>2_cc"
8409 [(set (reg CC_REGNUM)
8410 (compare (abs:GPR (match_operand:DI 1 "register_operand" "d"))
8411 (const_int 0)))
8412 (set (match_operand:GPR 0 "register_operand" "=d")
8413 (abs:GPR (match_dup 1)))]
8414 "s390_match_ccmode (insn, CCAmode)"
8415 "lp<g>r\t%0,%1"
8416 [(set_attr "op_type" "RR<E>")
8417 (set_attr "z10prop" "z10_c")])
8418
8419 ; lpr, lpgr
8420 (define_insn "*abs<mode>2_cconly"
8421 [(set (reg CC_REGNUM)
8422 (compare (abs:GPR (match_operand:GPR 1 "register_operand" "d"))
8423 (const_int 0)))
8424 (clobber (match_scratch:GPR 0 "=d"))]
8425 "s390_match_ccmode (insn, CCAmode)"
8426 "lp<g>r\t%0,%1"
8427 [(set_attr "op_type" "RR<E>")
8428 (set_attr "z10prop" "z10_c")])
8429
8430 ; lpr, lpgr
8431 (define_insn "abs<mode>2"
8432 [(set (match_operand:GPR 0 "register_operand" "=d")
8433 (abs:GPR (match_operand:GPR 1 "register_operand" "d")))
8434 (clobber (reg:CC CC_REGNUM))]
8435 ""
8436 "lp<g>r\t%0,%1"
8437 [(set_attr "op_type" "RR<E>")
8438 (set_attr "z10prop" "z10_c")])
8439
8440 ;
8441 ; abs(df|sf)2 instruction pattern(s).
8442 ;
8443
8444 (define_expand "abs<mode>2"
8445 [(parallel
8446 [(set (match_operand:BFP 0 "register_operand" "=f")
8447 (abs:BFP (match_operand:BFP 1 "register_operand" "f")))
8448 (clobber (reg:CC CC_REGNUM))])]
8449 "TARGET_HARD_FLOAT"
8450 "")
8451
8452 ; lpxbr, lpdbr, lpebr
8453 (define_insn "*abs<mode>2_cc"
8454 [(set (reg CC_REGNUM)
8455 (compare (abs:BFP (match_operand:BFP 1 "register_operand" "f"))
8456 (match_operand:BFP 2 "const0_operand" "")))
8457 (set (match_operand:BFP 0 "register_operand" "=f")
8458 (abs:BFP (match_dup 1)))]
8459 "s390_match_ccmode (insn, CCSmode) && TARGET_HARD_FLOAT"
8460 "lp<xde>br\t%0,%1"
8461 [(set_attr "op_type" "RRE")
8462 (set_attr "type" "fsimp<mode>")])
8463
8464 ; lpxbr, lpdbr, lpebr
8465 (define_insn "*abs<mode>2_cconly"
8466 [(set (reg CC_REGNUM)
8467 (compare (abs:BFP (match_operand:BFP 1 "register_operand" "f"))
8468 (match_operand:BFP 2 "const0_operand" "")))
8469 (clobber (match_scratch:BFP 0 "=f"))]
8470 "s390_match_ccmode (insn, CCSmode) && TARGET_HARD_FLOAT"
8471 "lp<xde>br\t%0,%1"
8472 [(set_attr "op_type" "RRE")
8473 (set_attr "type" "fsimp<mode>")])
8474
8475 ; lpdfr
8476 (define_insn "*abs<mode>2_nocc"
8477 [(set (match_operand:FP 0 "register_operand" "=f")
8478 (abs:FP (match_operand:FP 1 "register_operand" "<fT0>")))]
8479 "TARGET_DFP"
8480 "lpdfr\t%0,%1"
8481 [(set_attr "op_type" "RRE")
8482 (set_attr "type" "fsimp<mode>")])
8483
8484 ; lpxbr, lpdbr, lpebr
8485 ; FIXME: wflpdb does not clobber cc
8486 (define_insn "*abs<mode>2"
8487 [(set (match_operand:BFP 0 "register_operand" "=f,v")
8488 (abs:BFP (match_operand:BFP 1 "register_operand" "f,v")))
8489 (clobber (reg:CC CC_REGNUM))]
8490 "TARGET_HARD_FLOAT"
8491 "@
8492 lp<xde>br\t%0,%1
8493 wflpdb\t%0,%1"
8494 [(set_attr "op_type" "RRE,VRR")
8495 (set_attr "cpu_facility" "*,vx")
8496 (set_attr "type" "fsimp<mode>,*")
8497 (set_attr "enabled" "*,<DFDI>")])
8498
8499
8500 ;;
8501 ;;- Negated absolute value instructions
8502 ;;
8503
8504 ;
8505 ; Integer
8506 ;
8507
8508 (define_insn "*negabsdi2_sign_cc"
8509 [(set (reg CC_REGNUM)
8510 (compare (neg:DI (abs:DI (ashiftrt:DI (ashift:DI (subreg:DI
8511 (match_operand:SI 1 "register_operand" "d") 0)
8512 (const_int 32)) (const_int 32))))
8513 (const_int 0)))
8514 (set (match_operand:DI 0 "register_operand" "=d")
8515 (neg:DI (abs:DI (sign_extend:DI (match_dup 1)))))]
8516 "TARGET_ZARCH && s390_match_ccmode (insn, CCAmode)"
8517 "lngfr\t%0,%1"
8518 [(set_attr "op_type" "RRE")
8519 (set_attr "z10prop" "z10_c")])
8520
8521 (define_insn "*negabsdi2_sign"
8522 [(set (match_operand:DI 0 "register_operand" "=d")
8523 (neg:DI (abs:DI (sign_extend:DI
8524 (match_operand:SI 1 "register_operand" "d")))))
8525 (clobber (reg:CC CC_REGNUM))]
8526 "TARGET_ZARCH"
8527 "lngfr\t%0,%1"
8528 [(set_attr "op_type" "RRE")
8529 (set_attr "z10prop" "z10_c")])
8530
8531 ; lnr, lngr
8532 (define_insn "*negabs<mode>2_cc"
8533 [(set (reg CC_REGNUM)
8534 (compare (neg:GPR (abs:GPR (match_operand:GPR 1 "register_operand" "d")))
8535 (const_int 0)))
8536 (set (match_operand:GPR 0 "register_operand" "=d")
8537 (neg:GPR (abs:GPR (match_dup 1))))]
8538 "s390_match_ccmode (insn, CCAmode)"
8539 "ln<g>r\t%0,%1"
8540 [(set_attr "op_type" "RR<E>")
8541 (set_attr "z10prop" "z10_c")])
8542
8543 ; lnr, lngr
8544 (define_insn "*negabs<mode>2_cconly"
8545 [(set (reg CC_REGNUM)
8546 (compare (neg:GPR (abs:GPR (match_operand:GPR 1 "register_operand" "d")))
8547 (const_int 0)))
8548 (clobber (match_scratch:GPR 0 "=d"))]
8549 "s390_match_ccmode (insn, CCAmode)"
8550 "ln<g>r\t%0,%1"
8551 [(set_attr "op_type" "RR<E>")
8552 (set_attr "z10prop" "z10_c")])
8553
8554 ; lnr, lngr
8555 (define_insn "*negabs<mode>2"
8556 [(set (match_operand:GPR 0 "register_operand" "=d")
8557 (neg:GPR (abs:GPR (match_operand:GPR 1 "register_operand" "d"))))
8558 (clobber (reg:CC CC_REGNUM))]
8559 ""
8560 "ln<g>r\t%0,%1"
8561 [(set_attr "op_type" "RR<E>")
8562 (set_attr "z10prop" "z10_c")])
8563
8564 ;
8565 ; Floating point
8566 ;
8567
8568 ; lnxbr, lndbr, lnebr
8569 (define_insn "*negabs<mode>2_cc"
8570 [(set (reg CC_REGNUM)
8571 (compare (neg:BFP (abs:BFP (match_operand:BFP 1 "register_operand" "f")))
8572 (match_operand:BFP 2 "const0_operand" "")))
8573 (set (match_operand:BFP 0 "register_operand" "=f")
8574 (neg:BFP (abs:BFP (match_dup 1))))]
8575 "s390_match_ccmode (insn, CCSmode) && TARGET_HARD_FLOAT"
8576 "ln<xde>br\t%0,%1"
8577 [(set_attr "op_type" "RRE")
8578 (set_attr "type" "fsimp<mode>")])
8579
8580 ; lnxbr, lndbr, lnebr
8581 (define_insn "*negabs<mode>2_cconly"
8582 [(set (reg CC_REGNUM)
8583 (compare (neg:BFP (abs:BFP (match_operand:BFP 1 "register_operand" "f")))
8584 (match_operand:BFP 2 "const0_operand" "")))
8585 (clobber (match_scratch:BFP 0 "=f"))]
8586 "s390_match_ccmode (insn, CCSmode) && TARGET_HARD_FLOAT"
8587 "ln<xde>br\t%0,%1"
8588 [(set_attr "op_type" "RRE")
8589 (set_attr "type" "fsimp<mode>")])
8590
8591 ; lndfr
8592 (define_insn "*negabs<mode>2_nocc"
8593 [(set (match_operand:FP 0 "register_operand" "=f")
8594 (neg:FP (abs:FP (match_operand:BFP 1 "register_operand" "<fT0>"))))]
8595 "TARGET_DFP"
8596 "lndfr\t%0,%1"
8597 [(set_attr "op_type" "RRE")
8598 (set_attr "type" "fsimp<mode>")])
8599
8600 ; lnxbr, lndbr, lnebr
8601 ; FIXME: wflndb does not clobber cc
8602 (define_insn "*negabs<mode>2"
8603 [(set (match_operand:BFP 0 "register_operand" "=f,v")
8604 (neg:BFP (abs:BFP (match_operand:BFP 1 "register_operand" "f,v"))))
8605 (clobber (reg:CC CC_REGNUM))]
8606 "TARGET_HARD_FLOAT"
8607 "@
8608 ln<xde>br\t%0,%1
8609 wflndb\t%0,%1"
8610 [(set_attr "op_type" "RRE,VRR")
8611 (set_attr "cpu_facility" "*,vx")
8612 (set_attr "type" "fsimp<mode>,*")
8613 (set_attr "enabled" "*,<DFDI>")])
8614
8615 ;;
8616 ;;- Square root instructions.
8617 ;;
8618
8619 ;
8620 ; sqrt(df|sf)2 instruction pattern(s).
8621 ;
8622
8623 ; sqxbr, sqdbr, sqebr, sqdb, sqeb
8624 (define_insn "sqrt<mode>2"
8625 [(set (match_operand:BFP 0 "register_operand" "=f,f,v")
8626 (sqrt:BFP (match_operand:BFP 1 "general_operand" "f,R,v")))]
8627 "TARGET_HARD_FLOAT"
8628 "@
8629 sq<xde>br\t%0,%1
8630 sq<xde>b\t%0,%1
8631 wfsqdb\t%v0,%v1"
8632 [(set_attr "op_type" "RRE,RXE,VRR")
8633 (set_attr "type" "fsqrt<mode>")
8634 (set_attr "cpu_facility" "*,*,vx")
8635 (set_attr "enabled" "*,<DSF>,<DFDI>")])
8636
8637
8638 ;;
8639 ;;- One complement instructions.
8640 ;;
8641
8642 ;
8643 ; one_cmpl(di|si|hi|qi)2 instruction pattern(s).
8644 ;
8645
8646 (define_expand "one_cmpl<mode>2"
8647 [(parallel
8648 [(set (match_operand:INT 0 "register_operand" "")
8649 (xor:INT (match_operand:INT 1 "register_operand" "")
8650 (const_int -1)))
8651 (clobber (reg:CC CC_REGNUM))])]
8652 ""
8653 "")
8654
8655
8656 ;;
8657 ;; Find leftmost bit instructions.
8658 ;;
8659
8660 (define_expand "clzdi2"
8661 [(set (match_operand:DI 0 "register_operand" "=d")
8662 (clz:DI (match_operand:DI 1 "register_operand" "d")))]
8663 "TARGET_EXTIMM && TARGET_ZARCH"
8664 {
8665 rtx_insn *insn;
8666 rtx clz_equal;
8667 rtx wide_reg = gen_reg_rtx (TImode);
8668 rtx msb = gen_rtx_CONST_INT (DImode, HOST_WIDE_INT_1U << 63);
8669
8670 clz_equal = gen_rtx_CLZ (DImode, operands[1]);
8671
8672 emit_insn (gen_clztidi2 (wide_reg, operands[1], msb));
8673
8674 insn = emit_move_insn (operands[0], gen_highpart (DImode, wide_reg));
8675 set_unique_reg_note (insn, REG_EQUAL, clz_equal);
8676
8677 DONE;
8678 })
8679
8680 (define_insn "clztidi2"
8681 [(set (match_operand:TI 0 "register_operand" "=d")
8682 (ior:TI
8683 (ashift:TI
8684 (zero_extend:TI
8685 (xor:DI (match_operand:DI 1 "register_operand" "d")
8686 (lshiftrt (match_operand:DI 2 "const_int_operand" "")
8687 (subreg:SI (clz:DI (match_dup 1)) 4))))
8688
8689 (const_int 64))
8690 (zero_extend:TI (clz:DI (match_dup 1)))))
8691 (clobber (reg:CC CC_REGNUM))]
8692 "UINTVAL (operands[2]) == HOST_WIDE_INT_1U << 63
8693 && TARGET_EXTIMM && TARGET_ZARCH"
8694 "flogr\t%0,%1"
8695 [(set_attr "op_type" "RRE")])
8696
8697
8698 ;;
8699 ;;- Rotate instructions.
8700 ;;
8701
8702 ;
8703 ; rotl(di|si)3 instruction pattern(s).
8704 ;
8705
8706 (define_expand "rotl<mode>3"
8707 [(set (match_operand:GPR 0 "register_operand" "")
8708 (rotate:GPR (match_operand:GPR 1 "register_operand" "")
8709 (match_operand:SI 2 "nonmemory_operand" "")))]
8710 "TARGET_CPU_ZARCH"
8711 "")
8712
8713 ; rll, rllg
8714 (define_insn "*rotl<mode>3<addr_style_op><masked_op>"
8715 [(set (match_operand:GPR 0 "register_operand" "=d")
8716 (rotate:GPR (match_operand:GPR 1 "register_operand" "d")
8717 (match_operand:SI 2 "nonmemory_operand" "an")))]
8718 "TARGET_CPU_ZARCH"
8719 "rll<g>\t%0,%1,<addr_style_op_ops>"
8720 [(set_attr "op_type" "RSE")
8721 (set_attr "atype" "reg")
8722 (set_attr "z10prop" "z10_super_E1")])
8723
8724
8725 ;;
8726 ;;- Shift instructions.
8727 ;;
8728
8729 ;
8730 ; (ashl|lshr)(di|si)3 instruction pattern(s).
8731 ; Left shifts and logical right shifts
8732
8733 (define_expand "<shift><mode>3"
8734 [(set (match_operand:DSI 0 "register_operand" "")
8735 (SHIFT:DSI (match_operand:DSI 1 "register_operand" "")
8736 (match_operand:SI 2 "nonmemory_operand" "")))]
8737 ""
8738 "")
8739
8740 ; ESA 64 bit register pair shift with reg or imm shift count
8741 ; sldl, srdl
8742 (define_insn "*<shift>di3_31<addr_style_op><masked_op>"
8743 [(set (match_operand:DI 0 "register_operand" "=d")
8744 (SHIFT:DI (match_operand:DI 1 "register_operand" "0")
8745 (match_operand:SI 2 "nonmemory_operand" "an")))]
8746 "!TARGET_ZARCH"
8747 "s<lr>dl\t%0,<addr_style_op_ops>"
8748 [(set_attr "op_type" "RS")
8749 (set_attr "atype" "reg")
8750 (set_attr "z196prop" "z196_cracked")])
8751
8752
8753 ; 64 bit register shift with reg or imm shift count
8754 ; sll, srl, sllg, srlg, sllk, srlk
8755 (define_insn "*<shift><mode>3<addr_style_op><masked_op>"
8756 [(set (match_operand:GPR 0 "register_operand" "=d, d")
8757 (SHIFT:GPR (match_operand:GPR 1 "register_operand" "<d0>, d")
8758 (match_operand:SI 2 "nonmemory_operand" "an,an")))]
8759 ""
8760 "@
8761 s<lr>l<g>\t%0,<1><addr_style_op_ops>
8762 s<lr>l<gk>\t%0,%1,<addr_style_op_ops>"
8763 [(set_attr "op_type" "RS<E>,RSY")
8764 (set_attr "atype" "reg,reg")
8765 (set_attr "cpu_facility" "*,z196")
8766 (set_attr "z10prop" "z10_super_E1,*")])
8767
8768 ;
8769 ; ashr(di|si)3 instruction pattern(s).
8770 ; Arithmetic right shifts
8771
8772 (define_expand "ashr<mode>3"
8773 [(parallel
8774 [(set (match_operand:DSI 0 "register_operand" "")
8775 (ashiftrt:DSI (match_operand:DSI 1 "register_operand" "")
8776 (match_operand:SI 2 "nonmemory_operand" "")))
8777 (clobber (reg:CC CC_REGNUM))])]
8778 ""
8779 "")
8780
8781 ; FIXME: The number of alternatives is doubled here to match the fix
8782 ; number of 2 in the subst pattern for the (clobber (match_scratch...
8783 ; The right fix should be to support match_scratch in the output
8784 ; pattern of a define_subst.
8785 (define_insn "*ashrdi3_31<addr_style_op_cc><masked_op_cc><setcc><cconly>"
8786 [(set (match_operand:DI 0 "register_operand" "=d, d")
8787 (ashiftrt:DI (match_operand:DI 1 "register_operand" "0, 0")
8788 (match_operand:SI 2 "nonmemory_operand" "an,an")))
8789 (clobber (reg:CC CC_REGNUM))]
8790 "!TARGET_ZARCH"
8791 "@
8792 srda\t%0,<addr_style_op_cc_ops>
8793 srda\t%0,<addr_style_op_cc_ops>"
8794 [(set_attr "op_type" "RS")
8795 (set_attr "atype" "reg")])
8796
8797
8798 ; sra, srag
8799 (define_insn "*ashr<mode>3<addr_style_op_cc><masked_op_cc><setcc><cconly>"
8800 [(set (match_operand:GPR 0 "register_operand" "=d, d")
8801 (ashiftrt:GPR (match_operand:GPR 1 "register_operand" "<d0>, d")
8802 (match_operand:SI 2 "nonmemory_operand" "an,an")))
8803 (clobber (reg:CC CC_REGNUM))]
8804 ""
8805 "@
8806 sra<g>\t%0,<1><addr_style_op_cc_ops>
8807 sra<gk>\t%0,%1,<addr_style_op_cc_ops>"
8808 [(set_attr "op_type" "RS<E>,RSY")
8809 (set_attr "atype" "reg")
8810 (set_attr "cpu_facility" "*,z196")
8811 (set_attr "z10prop" "z10_super_E1,*")])
8812
8813
8814 ;;
8815 ;; Branch instruction patterns.
8816 ;;
8817
8818 (define_expand "cbranch<mode>4"
8819 [(set (pc)
8820 (if_then_else (match_operator 0 "comparison_operator"
8821 [(match_operand:GPR 1 "register_operand" "")
8822 (match_operand:GPR 2 "general_operand" "")])
8823 (label_ref (match_operand 3 "" ""))
8824 (pc)))]
8825 ""
8826 "s390_emit_jump (operands[3],
8827 s390_emit_compare (GET_CODE (operands[0]), operands[1], operands[2]));
8828 DONE;")
8829
8830 (define_expand "cbranch<mode>4"
8831 [(set (pc)
8832 (if_then_else (match_operator 0 "comparison_operator"
8833 [(match_operand:FP 1 "register_operand" "")
8834 (match_operand:FP 2 "general_operand" "")])
8835 (label_ref (match_operand 3 "" ""))
8836 (pc)))]
8837 "TARGET_HARD_FLOAT"
8838 "s390_emit_jump (operands[3],
8839 s390_emit_compare (GET_CODE (operands[0]), operands[1], operands[2]));
8840 DONE;")
8841
8842 (define_expand "cbranchcc4"
8843 [(set (pc)
8844 (if_then_else (match_operator 0 "s390_comparison"
8845 [(match_operand 1 "cc_reg_operand" "")
8846 (match_operand 2 "const_int_operand" "")])
8847 (label_ref (match_operand 3 "" ""))
8848 (pc)))]
8849 ""
8850 "")
8851
8852
8853 ;;
8854 ;;- Conditional jump instructions.
8855 ;;
8856
8857 (define_insn "*cjump_64"
8858 [(set (pc)
8859 (if_then_else
8860 (match_operator 1 "s390_comparison" [(reg CC_REGNUM)
8861 (match_operand 2 "const_int_operand" "")])
8862 (label_ref (match_operand 0 "" ""))
8863 (pc)))]
8864 "TARGET_CPU_ZARCH"
8865 {
8866 if (get_attr_length (insn) == 4)
8867 return "j%C1\t%l0";
8868 else
8869 return "jg%C1\t%l0";
8870 }
8871 [(set_attr "op_type" "RI")
8872 (set_attr "type" "branch")
8873 (set (attr "length")
8874 (if_then_else (lt (abs (minus (pc) (match_dup 0))) (const_int 60000))
8875 (const_int 4) (const_int 6)))])
8876
8877 (define_insn "*cjump_31"
8878 [(set (pc)
8879 (if_then_else
8880 (match_operator 1 "s390_comparison" [(reg CC_REGNUM)
8881 (match_operand 2 "const_int_operand" "")])
8882 (label_ref (match_operand 0 "" ""))
8883 (pc)))]
8884 "!TARGET_CPU_ZARCH"
8885 {
8886 gcc_assert (get_attr_length (insn) == 4);
8887 return "j%C1\t%l0";
8888 }
8889 [(set_attr "op_type" "RI")
8890 (set_attr "type" "branch")
8891 (set (attr "length")
8892 (if_then_else (not (match_test "flag_pic"))
8893 (if_then_else (lt (abs (minus (pc) (match_dup 0))) (const_int 60000))
8894 (const_int 4) (const_int 6))
8895 (if_then_else (lt (abs (minus (pc) (match_dup 0))) (const_int 60000))
8896 (const_int 4) (const_int 8))))])
8897
8898 (define_insn "*cjump_long"
8899 [(set (pc)
8900 (if_then_else
8901 (match_operator 1 "s390_comparison" [(reg CC_REGNUM) (const_int 0)])
8902 (match_operand 0 "address_operand" "ZQZR")
8903 (pc)))]
8904 ""
8905 {
8906 if (get_attr_op_type (insn) == OP_TYPE_RR)
8907 return "b%C1r\t%0";
8908 else
8909 return "b%C1\t%a0";
8910 }
8911 [(set (attr "op_type")
8912 (if_then_else (match_operand 0 "register_operand" "")
8913 (const_string "RR") (const_string "RX")))
8914 (set_attr "type" "branch")
8915 (set_attr "atype" "agen")])
8916
8917 ;; A conditional return instruction.
8918 (define_insn "*c<code>"
8919 [(set (pc)
8920 (if_then_else
8921 (match_operator 0 "s390_comparison" [(reg CC_REGNUM) (const_int 0)])
8922 (ANY_RETURN)
8923 (pc)))]
8924 "s390_can_use_<code>_insn ()"
8925 "b%C0r\t%%r14"
8926 [(set_attr "op_type" "RR")
8927 (set_attr "type" "jsr")
8928 (set_attr "atype" "agen")])
8929
8930 ;;
8931 ;;- Negated conditional jump instructions.
8932 ;;
8933
8934 (define_insn "*icjump_64"
8935 [(set (pc)
8936 (if_then_else
8937 (match_operator 1 "s390_comparison" [(reg CC_REGNUM) (const_int 0)])
8938 (pc)
8939 (label_ref (match_operand 0 "" ""))))]
8940 "TARGET_CPU_ZARCH"
8941 {
8942 if (get_attr_length (insn) == 4)
8943 return "j%D1\t%l0";
8944 else
8945 return "jg%D1\t%l0";
8946 }
8947 [(set_attr "op_type" "RI")
8948 (set_attr "type" "branch")
8949 (set (attr "length")
8950 (if_then_else (lt (abs (minus (pc) (match_dup 0))) (const_int 60000))
8951 (const_int 4) (const_int 6)))])
8952
8953 (define_insn "*icjump_31"
8954 [(set (pc)
8955 (if_then_else
8956 (match_operator 1 "s390_comparison" [(reg CC_REGNUM) (const_int 0)])
8957 (pc)
8958 (label_ref (match_operand 0 "" ""))))]
8959 "!TARGET_CPU_ZARCH"
8960 {
8961 gcc_assert (get_attr_length (insn) == 4);
8962 return "j%D1\t%l0";
8963 }
8964 [(set_attr "op_type" "RI")
8965 (set_attr "type" "branch")
8966 (set (attr "length")
8967 (if_then_else (not (match_test "flag_pic"))
8968 (if_then_else (lt (abs (minus (pc) (match_dup 0))) (const_int 60000))
8969 (const_int 4) (const_int 6))
8970 (if_then_else (lt (abs (minus (pc) (match_dup 0))) (const_int 60000))
8971 (const_int 4) (const_int 8))))])
8972
8973 (define_insn "*icjump_long"
8974 [(set (pc)
8975 (if_then_else
8976 (match_operator 1 "s390_comparison" [(reg CC_REGNUM) (const_int 0)])
8977 (pc)
8978 (match_operand 0 "address_operand" "ZQZR")))]
8979 ""
8980 {
8981 if (get_attr_op_type (insn) == OP_TYPE_RR)
8982 return "b%D1r\t%0";
8983 else
8984 return "b%D1\t%a0";
8985 }
8986 [(set (attr "op_type")
8987 (if_then_else (match_operand 0 "register_operand" "")
8988 (const_string "RR") (const_string "RX")))
8989 (set_attr "type" "branch")
8990 (set_attr "atype" "agen")])
8991
8992 ;;
8993 ;;- Trap instructions.
8994 ;;
8995
8996 (define_insn "trap"
8997 [(trap_if (const_int 1) (const_int 0))]
8998 ""
8999 "j\t.+2"
9000 [(set_attr "op_type" "RI")
9001 (set_attr "type" "branch")])
9002
9003 (define_expand "ctrap<mode>4"
9004 [(trap_if (match_operator 0 "comparison_operator"
9005 [(match_operand:GPR 1 "register_operand" "")
9006 (match_operand:GPR 2 "general_operand" "")])
9007 (match_operand 3 "const0_operand" ""))]
9008 ""
9009 {
9010 rtx cond = s390_emit_compare (GET_CODE (operands[0]),
9011 operands[1], operands[2]);
9012 emit_insn (gen_condtrap (cond, XEXP (cond, 0)));
9013 DONE;
9014 })
9015
9016 (define_expand "ctrap<mode>4"
9017 [(trap_if (match_operator 0 "comparison_operator"
9018 [(match_operand:FP 1 "register_operand" "")
9019 (match_operand:FP 2 "general_operand" "")])
9020 (match_operand 3 "const0_operand" ""))]
9021 ""
9022 {
9023 rtx cond = s390_emit_compare (GET_CODE (operands[0]),
9024 operands[1], operands[2]);
9025 emit_insn (gen_condtrap (cond, XEXP (cond, 0)));
9026 DONE;
9027 })
9028
9029 (define_insn "condtrap"
9030 [(trap_if (match_operator 0 "s390_comparison"
9031 [(match_operand 1 "cc_reg_operand" "c")
9032 (const_int 0)])
9033 (const_int 0))]
9034 ""
9035 "j%C0\t.+2";
9036 [(set_attr "op_type" "RI")
9037 (set_attr "type" "branch")])
9038
9039 ; crt, cgrt, cit, cgit
9040 (define_insn "*cmp_and_trap_signed_int<mode>"
9041 [(trap_if (match_operator 0 "s390_signed_integer_comparison"
9042 [(match_operand:GPR 1 "register_operand" "d,d")
9043 (match_operand:GPR 2 "nonmemory_operand" "d,K")])
9044 (const_int 0))]
9045 "TARGET_Z10"
9046 "@
9047 c<g>rt%C0\t%1,%2
9048 c<g>it%C0\t%1,%h2"
9049 [(set_attr "op_type" "RRF,RIE")
9050 (set_attr "type" "branch")
9051 (set_attr "z10prop" "z10_super_c,z10_super")])
9052
9053 ; clrt, clgrt, clfit, clgit, clt, clgt
9054 (define_insn "*cmp_and_trap_unsigned_int<mode>"
9055 [(trap_if (match_operator 0 "s390_unsigned_integer_comparison"
9056 [(match_operand:GPR 1 "register_operand" "d,d,d")
9057 (match_operand:GPR 2 "general_operand" "d,D,T")])
9058 (const_int 0))]
9059 "TARGET_Z10"
9060 "@
9061 cl<g>rt%C0\t%1,%2
9062 cl<gf>it%C0\t%1,%x2
9063 cl<g>t%C0\t%1,%2"
9064 [(set_attr "op_type" "RRF,RIE,RSY")
9065 (set_attr "type" "branch")
9066 (set_attr "z10prop" "z10_super_c,z10_super,*")
9067 (set_attr "cpu_facility" "z10,z10,zEC12")])
9068
9069 ; lat, lgat
9070 (define_insn "*load_and_trap<mode>"
9071 [(trap_if (eq (match_operand:GPR 0 "memory_operand" "T")
9072 (const_int 0))
9073 (const_int 0))
9074 (set (match_operand:GPR 1 "register_operand" "=d")
9075 (match_dup 0))]
9076 "TARGET_ZEC12"
9077 "l<g>at\t%1,%0"
9078 [(set_attr "op_type" "RXY")])
9079
9080
9081 ;;
9082 ;;- Loop instructions.
9083 ;;
9084 ;; This is all complicated by the fact that since this is a jump insn
9085 ;; we must handle our own output reloads.
9086
9087 ;; branch on index
9088
9089 ; This splitter will be matched by combine and has to add the 2 moves
9090 ; necessary to load the compare and the increment values into a
9091 ; register pair as needed by brxle.
9092
9093 (define_insn_and_split "*brx_stage1_<GPR:mode>"
9094 [(set (pc)
9095 (if_then_else
9096 (match_operator 6 "s390_brx_operator"
9097 [(plus:GPR (match_operand:GPR 1 "register_operand" "")
9098 (match_operand:GPR 2 "general_operand" ""))
9099 (match_operand:GPR 3 "register_operand" "")])
9100 (label_ref (match_operand 0 "" ""))
9101 (pc)))
9102 (set (match_operand:GPR 4 "nonimmediate_operand" "")
9103 (plus:GPR (match_dup 1) (match_dup 2)))
9104 (clobber (match_scratch:GPR 5 ""))]
9105 "TARGET_CPU_ZARCH"
9106 "#"
9107 "!reload_completed && !reload_in_progress"
9108 [(set (match_dup 7) (match_dup 2)) ; the increment
9109 (set (match_dup 8) (match_dup 3)) ; the comparison value
9110 (parallel [(set (pc)
9111 (if_then_else
9112 (match_op_dup 6
9113 [(plus:GPR (match_dup 1) (match_dup 7))
9114 (match_dup 8)])
9115 (label_ref (match_dup 0))
9116 (pc)))
9117 (set (match_dup 4)
9118 (plus:GPR (match_dup 1) (match_dup 7)))
9119 (clobber (match_dup 5))
9120 (clobber (reg:CC CC_REGNUM))])]
9121 {
9122 rtx dreg = gen_reg_rtx (word_mode == DImode ? TImode : DImode);
9123 operands[7] = gen_lowpart (<GPR:MODE>mode,
9124 gen_highpart (word_mode, dreg));
9125 operands[8] = gen_lowpart (<GPR:MODE>mode,
9126 gen_lowpart (word_mode, dreg));
9127 })
9128
9129 ; brxlg, brxhg
9130
9131 (define_insn_and_split "*brxg_64bit"
9132 [(set (pc)
9133 (if_then_else
9134 (match_operator 5 "s390_brx_operator"
9135 [(plus:DI (match_operand:DI 1 "register_operand" "d,d,d")
9136 (subreg:DI (match_operand:TI 2 "register_operand" "d,d,d") 0))
9137 (subreg:DI (match_dup 2) 8)])
9138 (label_ref (match_operand 0 "" ""))
9139 (pc)))
9140 (set (match_operand:DI 3 "nonimmediate_operand" "=1,?X,?X")
9141 (plus:DI (match_dup 1)
9142 (subreg:DI (match_dup 2) 0)))
9143 (clobber (match_scratch:DI 4 "=X,&1,&?d"))
9144 (clobber (reg:CC CC_REGNUM))]
9145 "TARGET_ZARCH"
9146 {
9147 if (which_alternative != 0)
9148 return "#";
9149 else if (get_attr_length (insn) == 6)
9150 return "brx%E5g\t%1,%2,%l0";
9151 else
9152 return "agr\t%1,%2\;cgr\t%1,%M2\;jg%C5\t%l0";
9153 }
9154 "&& reload_completed
9155 && (!REG_P (operands[3])
9156 || !rtx_equal_p (operands[1], operands[3]))"
9157 [(set (match_dup 4) (match_dup 1))
9158 (parallel [(set (match_dup 4) (plus:DI (match_dup 4) (subreg:DI (match_dup 2) 0)))
9159 (clobber (reg:CC CC_REGNUM))])
9160 (set (reg:CCS CC_REGNUM) (compare:CCS (match_dup 4) (subreg:DI (match_dup 2) 8)))
9161 (set (match_dup 3) (match_dup 4))
9162 (set (pc) (if_then_else (match_op_dup 5 [(reg:CCS CC_REGNUM) (const_int 0)])
9163 (label_ref (match_dup 0))
9164 (pc)))]
9165 ""
9166 [(set_attr "op_type" "RIE")
9167 (set_attr "type" "branch")
9168 (set (attr "length")
9169 (if_then_else (lt (abs (minus (pc) (match_dup 0))) (const_int 60000))
9170 (const_int 6) (const_int 16)))])
9171
9172 ; brxle, brxh
9173
9174 (define_insn_and_split "*brx_64bit"
9175 [(set (pc)
9176 (if_then_else
9177 (match_operator 5 "s390_brx_operator"
9178 [(plus:SI (match_operand:SI 1 "register_operand" "d,d,d")
9179 (subreg:SI (match_operand:TI 2 "register_operand" "d,d,d") 4))
9180 (subreg:SI (match_dup 2) 12)])
9181 (label_ref (match_operand 0 "" ""))
9182 (pc)))
9183 (set (match_operand:SI 3 "nonimmediate_operand" "=1,?X,?X")
9184 (plus:SI (match_dup 1)
9185 (subreg:SI (match_dup 2) 4)))
9186 (clobber (match_scratch:SI 4 "=X,&1,&?d"))
9187 (clobber (reg:CC CC_REGNUM))]
9188 "TARGET_ZARCH"
9189 {
9190 if (which_alternative != 0)
9191 return "#";
9192 else if (get_attr_length (insn) == 6)
9193 return "brx%C5\t%1,%2,%l0";
9194 else
9195 return "ar\t%1,%2\;cr\t%1,%M2\;jg%C5\t%l0";
9196 }
9197 "&& reload_completed
9198 && (!REG_P (operands[3])
9199 || !rtx_equal_p (operands[1], operands[3]))"
9200 [(set (match_dup 4) (match_dup 1))
9201 (parallel [(set (match_dup 4) (plus:SI (match_dup 4) (subreg:SI (match_dup 2) 4)))
9202 (clobber (reg:CC CC_REGNUM))])
9203 (set (reg:CCS CC_REGNUM) (compare:CCS (match_dup 4) (subreg:SI (match_dup 2) 12)))
9204 (set (match_dup 3) (match_dup 4))
9205 (set (pc) (if_then_else (match_op_dup 5 [(reg:CCS CC_REGNUM) (const_int 0)])
9206 (label_ref (match_dup 0))
9207 (pc)))]
9208 ""
9209 [(set_attr "op_type" "RSI")
9210 (set_attr "type" "branch")
9211 (set (attr "length")
9212 (if_then_else (lt (abs (minus (pc) (match_dup 0))) (const_int 60000))
9213 (const_int 6) (const_int 14)))])
9214
9215 ; brxle, brxh
9216
9217 (define_insn_and_split "*brx_31bit"
9218 [(set (pc)
9219 (if_then_else
9220 (match_operator 5 "s390_brx_operator"
9221 [(plus:SI (match_operand:SI 1 "register_operand" "d,d,d")
9222 (subreg:SI (match_operand:DI 2 "register_operand" "d,d,d") 0))
9223 (subreg:SI (match_dup 2) 4)])
9224 (label_ref (match_operand 0 "" ""))
9225 (pc)))
9226 (set (match_operand:SI 3 "nonimmediate_operand" "=1,?X,?X")
9227 (plus:SI (match_dup 1)
9228 (subreg:SI (match_dup 2) 0)))
9229 (clobber (match_scratch:SI 4 "=X,&1,&?d"))
9230 (clobber (reg:CC CC_REGNUM))]
9231 "!TARGET_ZARCH && TARGET_CPU_ZARCH"
9232 {
9233 if (which_alternative != 0)
9234 return "#";
9235 else if (get_attr_length (insn) == 6)
9236 return "brx%C5\t%1,%2,%l0";
9237 else
9238 return "ar\t%1,%2\;cr\t%1,%M2\;jg%C5\t%l0";
9239 }
9240 "&& reload_completed
9241 && (!REG_P (operands[3])
9242 || !rtx_equal_p (operands[1], operands[3]))"
9243 [(set (match_dup 4) (match_dup 1))
9244 (parallel [(set (match_dup 4) (plus:SI (match_dup 4) (subreg:SI (match_dup 2) 0)))
9245 (clobber (reg:CC CC_REGNUM))])
9246 (set (reg:CCS CC_REGNUM) (compare:CCS (match_dup 4) (subreg:SI (match_dup 2) 4)))
9247 (set (match_dup 3) (match_dup 4))
9248 (set (pc) (if_then_else (match_op_dup 5 [(reg:CCS CC_REGNUM) (const_int 0)])
9249 (label_ref (match_dup 0))
9250 (pc)))]
9251 ""
9252 [(set_attr "op_type" "RSI")
9253 (set_attr "type" "branch")
9254 (set (attr "length")
9255 (if_then_else (lt (abs (minus (pc) (match_dup 0))) (const_int 60000))
9256 (const_int 6) (const_int 14)))])
9257
9258
9259 ;; branch on count
9260
9261 (define_expand "doloop_end"
9262 [(use (match_operand 0 "" "")) ; loop pseudo
9263 (use (match_operand 1 "" ""))] ; label
9264 ""
9265 {
9266 if (GET_MODE (operands[0]) == SImode && !TARGET_CPU_ZARCH)
9267 emit_jump_insn (gen_doloop_si31 (operands[1], operands[0], operands[0]));
9268 else if (GET_MODE (operands[0]) == SImode && TARGET_CPU_ZARCH)
9269 emit_jump_insn (gen_doloop_si64 (operands[1], operands[0], operands[0]));
9270 else if (GET_MODE (operands[0]) == DImode && TARGET_ZARCH)
9271 emit_jump_insn (gen_doloop_di (operands[1], operands[0], operands[0]));
9272 else
9273 FAIL;
9274
9275 DONE;
9276 })
9277
9278 (define_insn_and_split "doloop_si64"
9279 [(set (pc)
9280 (if_then_else
9281 (ne (match_operand:SI 1 "register_operand" "d,d,d")
9282 (const_int 1))
9283 (label_ref (match_operand 0 "" ""))
9284 (pc)))
9285 (set (match_operand:SI 2 "nonimmediate_operand" "=1,?X,?X")
9286 (plus:SI (match_dup 1) (const_int -1)))
9287 (clobber (match_scratch:SI 3 "=X,&1,&?d"))
9288 (clobber (reg:CC CC_REGNUM))]
9289 "TARGET_CPU_ZARCH"
9290 {
9291 if (which_alternative != 0)
9292 return "#";
9293 else if (get_attr_length (insn) == 4)
9294 return "brct\t%1,%l0";
9295 else
9296 return "ahi\t%1,-1\;jgne\t%l0";
9297 }
9298 "&& reload_completed
9299 && (! REG_P (operands[2])
9300 || ! rtx_equal_p (operands[1], operands[2]))"
9301 [(set (match_dup 3) (match_dup 1))
9302 (parallel [(set (reg:CCAN CC_REGNUM)
9303 (compare:CCAN (plus:SI (match_dup 3) (const_int -1))
9304 (const_int 0)))
9305 (set (match_dup 3) (plus:SI (match_dup 3) (const_int -1)))])
9306 (set (match_dup 2) (match_dup 3))
9307 (set (pc) (if_then_else (ne (reg:CCAN CC_REGNUM) (const_int 0))
9308 (label_ref (match_dup 0))
9309 (pc)))]
9310 ""
9311 [(set_attr "op_type" "RI")
9312 ; Strictly speaking, the z10 properties are valid for brct only, however, it does not
9313 ; hurt us in the (rare) case of ahi.
9314 (set_attr "z10prop" "z10_super_E1")
9315 (set_attr "type" "branch")
9316 (set (attr "length")
9317 (if_then_else (lt (abs (minus (pc) (match_dup 0))) (const_int 60000))
9318 (const_int 4) (const_int 10)))])
9319
9320 (define_insn_and_split "doloop_si31"
9321 [(set (pc)
9322 (if_then_else
9323 (ne (match_operand:SI 1 "register_operand" "d,d,d")
9324 (const_int 1))
9325 (label_ref (match_operand 0 "" ""))
9326 (pc)))
9327 (set (match_operand:SI 2 "nonimmediate_operand" "=1,?X,?X")
9328 (plus:SI (match_dup 1) (const_int -1)))
9329 (clobber (match_scratch:SI 3 "=X,&1,&?d"))
9330 (clobber (reg:CC CC_REGNUM))]
9331 "!TARGET_CPU_ZARCH"
9332 {
9333 if (which_alternative != 0)
9334 return "#";
9335 else if (get_attr_length (insn) == 4)
9336 return "brct\t%1,%l0";
9337 else
9338 gcc_unreachable ();
9339 }
9340 "&& reload_completed
9341 && (! REG_P (operands[2])
9342 || ! rtx_equal_p (operands[1], operands[2]))"
9343 [(set (match_dup 3) (match_dup 1))
9344 (parallel [(set (reg:CCAN CC_REGNUM)
9345 (compare:CCAN (plus:SI (match_dup 3) (const_int -1))
9346 (const_int 0)))
9347 (set (match_dup 3) (plus:SI (match_dup 3) (const_int -1)))])
9348 (set (match_dup 2) (match_dup 3))
9349 (set (pc) (if_then_else (ne (reg:CCAN CC_REGNUM) (const_int 0))
9350 (label_ref (match_dup 0))
9351 (pc)))]
9352 ""
9353 [(set_attr "op_type" "RI")
9354 ; Strictly speaking, the z10 properties are valid for brct only, however, it does not
9355 ; hurt us in the (rare) case of ahi.
9356 (set_attr "z10prop" "z10_super_E1")
9357 (set_attr "type" "branch")
9358 (set (attr "length")
9359 (if_then_else (not (match_test "flag_pic"))
9360 (if_then_else (lt (abs (minus (pc) (match_dup 0))) (const_int 60000))
9361 (const_int 4) (const_int 6))
9362 (if_then_else (lt (abs (minus (pc) (match_dup 0))) (const_int 60000))
9363 (const_int 4) (const_int 8))))])
9364
9365 (define_insn "*doloop_si_long"
9366 [(set (pc)
9367 (if_then_else
9368 (ne (match_operand:SI 1 "register_operand" "d")
9369 (const_int 1))
9370 (match_operand 0 "address_operand" "ZR")
9371 (pc)))
9372 (set (match_operand:SI 2 "register_operand" "=1")
9373 (plus:SI (match_dup 1) (const_int -1)))
9374 (clobber (match_scratch:SI 3 "=X"))
9375 (clobber (reg:CC CC_REGNUM))]
9376 "!TARGET_CPU_ZARCH"
9377 {
9378 if (get_attr_op_type (insn) == OP_TYPE_RR)
9379 return "bctr\t%1,%0";
9380 else
9381 return "bct\t%1,%a0";
9382 }
9383 [(set (attr "op_type")
9384 (if_then_else (match_operand 0 "register_operand" "")
9385 (const_string "RR") (const_string "RX")))
9386 (set_attr "type" "branch")
9387 (set_attr "atype" "agen")
9388 (set_attr "z10prop" "z10_c")
9389 (set_attr "z196prop" "z196_cracked")])
9390
9391 (define_insn_and_split "doloop_di"
9392 [(set (pc)
9393 (if_then_else
9394 (ne (match_operand:DI 1 "register_operand" "d,d,d")
9395 (const_int 1))
9396 (label_ref (match_operand 0 "" ""))
9397 (pc)))
9398 (set (match_operand:DI 2 "nonimmediate_operand" "=1,?X,?X")
9399 (plus:DI (match_dup 1) (const_int -1)))
9400 (clobber (match_scratch:DI 3 "=X,&1,&?d"))
9401 (clobber (reg:CC CC_REGNUM))]
9402 "TARGET_ZARCH"
9403 {
9404 if (which_alternative != 0)
9405 return "#";
9406 else if (get_attr_length (insn) == 4)
9407 return "brctg\t%1,%l0";
9408 else
9409 return "aghi\t%1,-1\;jgne\t%l0";
9410 }
9411 "&& reload_completed
9412 && (! REG_P (operands[2])
9413 || ! rtx_equal_p (operands[1], operands[2]))"
9414 [(set (match_dup 3) (match_dup 1))
9415 (parallel [(set (reg:CCAN CC_REGNUM)
9416 (compare:CCAN (plus:DI (match_dup 3) (const_int -1))
9417 (const_int 0)))
9418 (set (match_dup 3) (plus:DI (match_dup 3) (const_int -1)))])
9419 (set (match_dup 2) (match_dup 3))
9420 (set (pc) (if_then_else (ne (reg:CCAN CC_REGNUM) (const_int 0))
9421 (label_ref (match_dup 0))
9422 (pc)))]
9423 ""
9424 [(set_attr "op_type" "RI")
9425 ; Strictly speaking, the z10 properties are valid for brct only, however, it does not
9426 ; hurt us in the (rare) case of ahi.
9427 (set_attr "z10prop" "z10_super_E1")
9428 (set_attr "type" "branch")
9429 (set (attr "length")
9430 (if_then_else (lt (abs (minus (pc) (match_dup 0))) (const_int 60000))
9431 (const_int 4) (const_int 10)))])
9432
9433 ;;
9434 ;;- Unconditional jump instructions.
9435 ;;
9436
9437 ;
9438 ; jump instruction pattern(s).
9439 ;
9440
9441 (define_expand "jump"
9442 [(match_operand 0 "" "")]
9443 ""
9444 "s390_emit_jump (operands[0], NULL_RTX); DONE;")
9445
9446 (define_insn "*jump64"
9447 [(set (pc) (label_ref (match_operand 0 "" "")))]
9448 "TARGET_CPU_ZARCH"
9449 {
9450 if (get_attr_length (insn) == 4)
9451 return "j\t%l0";
9452 else
9453 return "jg\t%l0";
9454 }
9455 [(set_attr "op_type" "RI")
9456 (set_attr "type" "branch")
9457 (set (attr "length")
9458 (if_then_else (lt (abs (minus (pc) (match_dup 0))) (const_int 60000))
9459 (const_int 4) (const_int 6)))])
9460
9461 (define_insn "*jump31"
9462 [(set (pc) (label_ref (match_operand 0 "" "")))]
9463 "!TARGET_CPU_ZARCH"
9464 {
9465 gcc_assert (get_attr_length (insn) == 4);
9466 return "j\t%l0";
9467 }
9468 [(set_attr "op_type" "RI")
9469 (set_attr "type" "branch")
9470 (set (attr "length")
9471 (if_then_else (not (match_test "flag_pic"))
9472 (if_then_else (lt (abs (minus (pc) (match_dup 0))) (const_int 60000))
9473 (const_int 4) (const_int 6))
9474 (if_then_else (lt (abs (minus (pc) (match_dup 0))) (const_int 60000))
9475 (const_int 4) (const_int 8))))])
9476
9477 ;
9478 ; indirect-jump instruction pattern(s).
9479 ;
9480
9481 (define_insn "indirect_jump"
9482 [(set (pc) (match_operand 0 "address_operand" "ZR"))]
9483 ""
9484 {
9485 if (get_attr_op_type (insn) == OP_TYPE_RR)
9486 return "br\t%0";
9487 else
9488 return "b\t%a0";
9489 }
9490 [(set (attr "op_type")
9491 (if_then_else (match_operand 0 "register_operand" "")
9492 (const_string "RR") (const_string "RX")))
9493 (set_attr "type" "branch")
9494 (set_attr "atype" "agen")])
9495
9496 ;
9497 ; casesi instruction pattern(s).
9498 ;
9499
9500 (define_insn "casesi_jump"
9501 [(set (pc) (match_operand 0 "address_operand" "ZR"))
9502 (use (label_ref (match_operand 1 "" "")))]
9503 ""
9504 {
9505 if (get_attr_op_type (insn) == OP_TYPE_RR)
9506 return "br\t%0";
9507 else
9508 return "b\t%a0";
9509 }
9510 [(set (attr "op_type")
9511 (if_then_else (match_operand 0 "register_operand" "")
9512 (const_string "RR") (const_string "RX")))
9513 (set_attr "type" "branch")
9514 (set_attr "atype" "agen")])
9515
9516 (define_expand "casesi"
9517 [(match_operand:SI 0 "general_operand" "")
9518 (match_operand:SI 1 "general_operand" "")
9519 (match_operand:SI 2 "general_operand" "")
9520 (label_ref (match_operand 3 "" ""))
9521 (label_ref (match_operand 4 "" ""))]
9522 ""
9523 {
9524 rtx index = gen_reg_rtx (SImode);
9525 rtx base = gen_reg_rtx (Pmode);
9526 rtx target = gen_reg_rtx (Pmode);
9527
9528 emit_move_insn (index, operands[0]);
9529 emit_insn (gen_subsi3 (index, index, operands[1]));
9530 emit_cmp_and_jump_insns (index, operands[2], GTU, NULL_RTX, SImode, 1,
9531 operands[4]);
9532
9533 if (Pmode != SImode)
9534 index = convert_to_mode (Pmode, index, 1);
9535 if (GET_CODE (index) != REG)
9536 index = copy_to_mode_reg (Pmode, index);
9537
9538 if (TARGET_64BIT)
9539 emit_insn (gen_ashldi3 (index, index, GEN_INT (3)));
9540 else
9541 emit_insn (gen_ashlsi3 (index, index, const2_rtx));
9542
9543 emit_move_insn (base, gen_rtx_LABEL_REF (Pmode, operands[3]));
9544
9545 index = gen_const_mem (Pmode, gen_rtx_PLUS (Pmode, base, index));
9546 emit_move_insn (target, index);
9547
9548 if (flag_pic)
9549 target = gen_rtx_PLUS (Pmode, base, target);
9550 emit_jump_insn (gen_casesi_jump (target, operands[3]));
9551
9552 DONE;
9553 })
9554
9555
9556 ;;
9557 ;;- Jump to subroutine.
9558 ;;
9559 ;;
9560
9561 ;
9562 ; untyped call instruction pattern(s).
9563 ;
9564
9565 ;; Call subroutine returning any type.
9566 (define_expand "untyped_call"
9567 [(parallel [(call (match_operand 0 "" "")
9568 (const_int 0))
9569 (match_operand 1 "" "")
9570 (match_operand 2 "" "")])]
9571 ""
9572 {
9573 int i;
9574
9575 emit_call_insn (gen_call (operands[0], const0_rtx, const0_rtx));
9576
9577 for (i = 0; i < XVECLEN (operands[2], 0); i++)
9578 {
9579 rtx set = XVECEXP (operands[2], 0, i);
9580 emit_move_insn (SET_DEST (set), SET_SRC (set));
9581 }
9582
9583 /* The optimizer does not know that the call sets the function value
9584 registers we stored in the result block. We avoid problems by
9585 claiming that all hard registers are used and clobbered at this
9586 point. */
9587 emit_insn (gen_blockage ());
9588
9589 DONE;
9590 })
9591
9592 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
9593 ;; all of memory. This blocks insns from being moved across this point.
9594
9595 (define_insn "blockage"
9596 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
9597 ""
9598 ""
9599 [(set_attr "type" "none")
9600 (set_attr "length" "0")])
9601
9602 ;
9603 ; sibcall patterns
9604 ;
9605
9606 (define_expand "sibcall"
9607 [(call (match_operand 0 "" "")
9608 (match_operand 1 "" ""))]
9609 ""
9610 {
9611 s390_emit_call (XEXP (operands[0], 0), NULL_RTX, NULL_RTX, NULL_RTX);
9612 DONE;
9613 })
9614
9615 (define_insn "*sibcall_br"
9616 [(call (mem:QI (reg SIBCALL_REGNUM))
9617 (match_operand 0 "const_int_operand" "n"))]
9618 "SIBLING_CALL_P (insn)
9619 && GET_MODE (XEXP (XEXP (PATTERN (insn), 0), 0)) == Pmode"
9620 "br\t%%r1"
9621 [(set_attr "op_type" "RR")
9622 (set_attr "type" "branch")
9623 (set_attr "atype" "agen")])
9624
9625 (define_insn "*sibcall_brc"
9626 [(call (mem:QI (match_operand 0 "bras_sym_operand" "X"))
9627 (match_operand 1 "const_int_operand" "n"))]
9628 "SIBLING_CALL_P (insn) && TARGET_SMALL_EXEC"
9629 "j\t%0"
9630 [(set_attr "op_type" "RI")
9631 (set_attr "type" "branch")])
9632
9633 (define_insn "*sibcall_brcl"
9634 [(call (mem:QI (match_operand 0 "bras_sym_operand" "X"))
9635 (match_operand 1 "const_int_operand" "n"))]
9636 "SIBLING_CALL_P (insn) && TARGET_CPU_ZARCH"
9637 "jg\t%0"
9638 [(set_attr "op_type" "RIL")
9639 (set_attr "type" "branch")])
9640
9641 ;
9642 ; sibcall_value patterns
9643 ;
9644
9645 (define_expand "sibcall_value"
9646 [(set (match_operand 0 "" "")
9647 (call (match_operand 1 "" "")
9648 (match_operand 2 "" "")))]
9649 ""
9650 {
9651 s390_emit_call (XEXP (operands[1], 0), NULL_RTX, operands[0], NULL_RTX);
9652 DONE;
9653 })
9654
9655 (define_insn "*sibcall_value_br"
9656 [(set (match_operand 0 "" "")
9657 (call (mem:QI (reg SIBCALL_REGNUM))
9658 (match_operand 1 "const_int_operand" "n")))]
9659 "SIBLING_CALL_P (insn)
9660 && GET_MODE (XEXP (XEXP (XEXP (PATTERN (insn), 1), 0), 0)) == Pmode"
9661 "br\t%%r1"
9662 [(set_attr "op_type" "RR")
9663 (set_attr "type" "branch")
9664 (set_attr "atype" "agen")])
9665
9666 (define_insn "*sibcall_value_brc"
9667 [(set (match_operand 0 "" "")
9668 (call (mem:QI (match_operand 1 "bras_sym_operand" "X"))
9669 (match_operand 2 "const_int_operand" "n")))]
9670 "SIBLING_CALL_P (insn) && TARGET_SMALL_EXEC"
9671 "j\t%1"
9672 [(set_attr "op_type" "RI")
9673 (set_attr "type" "branch")])
9674
9675 (define_insn "*sibcall_value_brcl"
9676 [(set (match_operand 0 "" "")
9677 (call (mem:QI (match_operand 1 "bras_sym_operand" "X"))
9678 (match_operand 2 "const_int_operand" "n")))]
9679 "SIBLING_CALL_P (insn) && TARGET_CPU_ZARCH"
9680 "jg\t%1"
9681 [(set_attr "op_type" "RIL")
9682 (set_attr "type" "branch")])
9683
9684
9685 ;
9686 ; call instruction pattern(s).
9687 ;
9688
9689 (define_expand "call"
9690 [(call (match_operand 0 "" "")
9691 (match_operand 1 "" ""))
9692 (use (match_operand 2 "" ""))]
9693 ""
9694 {
9695 s390_emit_call (XEXP (operands[0], 0), NULL_RTX, NULL_RTX,
9696 gen_rtx_REG (Pmode, RETURN_REGNUM));
9697 DONE;
9698 })
9699
9700 (define_insn "*bras"
9701 [(call (mem:QI (match_operand 0 "bras_sym_operand" "X"))
9702 (match_operand 1 "const_int_operand" "n"))
9703 (clobber (match_operand 2 "register_operand" "=r"))]
9704 "!SIBLING_CALL_P (insn)
9705 && TARGET_SMALL_EXEC
9706 && GET_MODE (operands[2]) == Pmode"
9707 "bras\t%2,%0"
9708 [(set_attr "op_type" "RI")
9709 (set_attr "type" "jsr")
9710 (set_attr "z196prop" "z196_cracked")])
9711
9712 (define_insn "*brasl"
9713 [(call (mem:QI (match_operand 0 "bras_sym_operand" "X"))
9714 (match_operand 1 "const_int_operand" "n"))
9715 (clobber (match_operand 2 "register_operand" "=r"))]
9716 "!SIBLING_CALL_P (insn)
9717 && TARGET_CPU_ZARCH
9718 && GET_MODE (operands[2]) == Pmode"
9719 "brasl\t%2,%0"
9720 [(set_attr "op_type" "RIL")
9721 (set_attr "type" "jsr")
9722 (set_attr "z196prop" "z196_cracked")])
9723
9724 (define_insn "*basr"
9725 [(call (mem:QI (match_operand 0 "address_operand" "ZR"))
9726 (match_operand 1 "const_int_operand" "n"))
9727 (clobber (match_operand 2 "register_operand" "=r"))]
9728 "!SIBLING_CALL_P (insn) && GET_MODE (operands[2]) == Pmode"
9729 {
9730 if (get_attr_op_type (insn) == OP_TYPE_RR)
9731 return "basr\t%2,%0";
9732 else
9733 return "bas\t%2,%a0";
9734 }
9735 [(set (attr "op_type")
9736 (if_then_else (match_operand 0 "register_operand" "")
9737 (const_string "RR") (const_string "RX")))
9738 (set_attr "type" "jsr")
9739 (set_attr "atype" "agen")
9740 (set_attr "z196prop" "z196_cracked")])
9741
9742 ;
9743 ; call_value instruction pattern(s).
9744 ;
9745
9746 (define_expand "call_value"
9747 [(set (match_operand 0 "" "")
9748 (call (match_operand 1 "" "")
9749 (match_operand 2 "" "")))
9750 (use (match_operand 3 "" ""))]
9751 ""
9752 {
9753 s390_emit_call (XEXP (operands[1], 0), NULL_RTX, operands[0],
9754 gen_rtx_REG (Pmode, RETURN_REGNUM));
9755 DONE;
9756 })
9757
9758 (define_insn "*bras_r"
9759 [(set (match_operand 0 "" "")
9760 (call (mem:QI (match_operand 1 "bras_sym_operand" "X"))
9761 (match_operand:SI 2 "const_int_operand" "n")))
9762 (clobber (match_operand 3 "register_operand" "=r"))]
9763 "!SIBLING_CALL_P (insn)
9764 && TARGET_SMALL_EXEC
9765 && GET_MODE (operands[3]) == Pmode"
9766 "bras\t%3,%1"
9767 [(set_attr "op_type" "RI")
9768 (set_attr "type" "jsr")
9769 (set_attr "z196prop" "z196_cracked")])
9770
9771 (define_insn "*brasl_r"
9772 [(set (match_operand 0 "" "")
9773 (call (mem:QI (match_operand 1 "bras_sym_operand" "X"))
9774 (match_operand 2 "const_int_operand" "n")))
9775 (clobber (match_operand 3 "register_operand" "=r"))]
9776 "!SIBLING_CALL_P (insn)
9777 && TARGET_CPU_ZARCH
9778 && GET_MODE (operands[3]) == Pmode"
9779 "brasl\t%3,%1"
9780 [(set_attr "op_type" "RIL")
9781 (set_attr "type" "jsr")
9782 (set_attr "z196prop" "z196_cracked")])
9783
9784 (define_insn "*basr_r"
9785 [(set (match_operand 0 "" "")
9786 (call (mem:QI (match_operand 1 "address_operand" "ZR"))
9787 (match_operand 2 "const_int_operand" "n")))
9788 (clobber (match_operand 3 "register_operand" "=r"))]
9789 "!SIBLING_CALL_P (insn) && GET_MODE (operands[3]) == Pmode"
9790 {
9791 if (get_attr_op_type (insn) == OP_TYPE_RR)
9792 return "basr\t%3,%1";
9793 else
9794 return "bas\t%3,%a1";
9795 }
9796 [(set (attr "op_type")
9797 (if_then_else (match_operand 1 "register_operand" "")
9798 (const_string "RR") (const_string "RX")))
9799 (set_attr "type" "jsr")
9800 (set_attr "atype" "agen")
9801 (set_attr "z196prop" "z196_cracked")])
9802
9803 ;;
9804 ;;- Thread-local storage support.
9805 ;;
9806
9807 (define_expand "get_thread_pointer<mode>"
9808 [(set (match_operand:P 0 "nonimmediate_operand" "") (reg:P TP_REGNUM))]
9809 ""
9810 "")
9811
9812 (define_expand "set_thread_pointer<mode>"
9813 [(set (reg:P TP_REGNUM) (match_operand:P 0 "nonimmediate_operand" ""))
9814 (set (reg:P TP_REGNUM) (unspec_volatile:P [(reg:P TP_REGNUM)] UNSPECV_SET_TP))]
9815 ""
9816 "")
9817
9818 (define_insn "*set_tp"
9819 [(set (reg TP_REGNUM) (unspec_volatile [(reg TP_REGNUM)] UNSPECV_SET_TP))]
9820 ""
9821 ""
9822 [(set_attr "type" "none")
9823 (set_attr "length" "0")])
9824
9825 (define_insn "*tls_load_64"
9826 [(set (match_operand:DI 0 "register_operand" "=d")
9827 (unspec:DI [(match_operand:DI 1 "memory_operand" "T")
9828 (match_operand:DI 2 "" "")]
9829 UNSPEC_TLS_LOAD))]
9830 "TARGET_64BIT"
9831 "lg\t%0,%1%J2"
9832 [(set_attr "op_type" "RXE")
9833 (set_attr "z10prop" "z10_fwd_A3")])
9834
9835 (define_insn "*tls_load_31"
9836 [(set (match_operand:SI 0 "register_operand" "=d,d")
9837 (unspec:SI [(match_operand:SI 1 "memory_operand" "R,T")
9838 (match_operand:SI 2 "" "")]
9839 UNSPEC_TLS_LOAD))]
9840 "!TARGET_64BIT"
9841 "@
9842 l\t%0,%1%J2
9843 ly\t%0,%1%J2"
9844 [(set_attr "op_type" "RX,RXY")
9845 (set_attr "type" "load")
9846 (set_attr "cpu_facility" "*,longdisp")
9847 (set_attr "z10prop" "z10_fwd_A3,z10_fwd_A3")])
9848
9849 (define_insn "*bras_tls"
9850 [(set (match_operand 0 "" "")
9851 (call (mem:QI (match_operand 1 "bras_sym_operand" "X"))
9852 (match_operand 2 "const_int_operand" "n")))
9853 (clobber (match_operand 3 "register_operand" "=r"))
9854 (use (match_operand 4 "" ""))]
9855 "!SIBLING_CALL_P (insn)
9856 && TARGET_SMALL_EXEC
9857 && GET_MODE (operands[3]) == Pmode"
9858 "bras\t%3,%1%J4"
9859 [(set_attr "op_type" "RI")
9860 (set_attr "type" "jsr")
9861 (set_attr "z196prop" "z196_cracked")])
9862
9863 (define_insn "*brasl_tls"
9864 [(set (match_operand 0 "" "")
9865 (call (mem:QI (match_operand 1 "bras_sym_operand" "X"))
9866 (match_operand 2 "const_int_operand" "n")))
9867 (clobber (match_operand 3 "register_operand" "=r"))
9868 (use (match_operand 4 "" ""))]
9869 "!SIBLING_CALL_P (insn)
9870 && TARGET_CPU_ZARCH
9871 && GET_MODE (operands[3]) == Pmode"
9872 "brasl\t%3,%1%J4"
9873 [(set_attr "op_type" "RIL")
9874 (set_attr "type" "jsr")
9875 (set_attr "z196prop" "z196_cracked")])
9876
9877 (define_insn "*basr_tls"
9878 [(set (match_operand 0 "" "")
9879 (call (mem:QI (match_operand 1 "address_operand" "ZR"))
9880 (match_operand 2 "const_int_operand" "n")))
9881 (clobber (match_operand 3 "register_operand" "=r"))
9882 (use (match_operand 4 "" ""))]
9883 "!SIBLING_CALL_P (insn) && GET_MODE (operands[3]) == Pmode"
9884 {
9885 if (get_attr_op_type (insn) == OP_TYPE_RR)
9886 return "basr\t%3,%1%J4";
9887 else
9888 return "bas\t%3,%a1%J4";
9889 }
9890 [(set (attr "op_type")
9891 (if_then_else (match_operand 1 "register_operand" "")
9892 (const_string "RR") (const_string "RX")))
9893 (set_attr "type" "jsr")
9894 (set_attr "atype" "agen")
9895 (set_attr "z196prop" "z196_cracked")])
9896
9897 ;;
9898 ;;- Atomic operations
9899 ;;
9900
9901 ;
9902 ; memory barrier patterns.
9903 ;
9904
9905 (define_expand "mem_signal_fence"
9906 [(match_operand:SI 0 "const_int_operand")] ;; model
9907 ""
9908 {
9909 /* The s390 memory model is strong enough not to require any
9910 barrier in order to synchronize a thread with itself. */
9911 DONE;
9912 })
9913
9914 (define_expand "mem_thread_fence"
9915 [(match_operand:SI 0 "const_int_operand")] ;; model
9916 ""
9917 {
9918 /* Unless this is a SEQ_CST fence, the s390 memory model is strong
9919 enough not to require barriers of any kind. */
9920 if (is_mm_seq_cst (memmodel_from_int (INTVAL (operands[0]))))
9921 {
9922 rtx mem = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
9923 MEM_VOLATILE_P (mem) = 1;
9924 emit_insn (gen_mem_thread_fence_1 (mem));
9925 }
9926 DONE;
9927 })
9928
9929 ; Although bcr is superscalar on Z10, this variant will never
9930 ; become part of an execution group.
9931 ; With z196 we can make use of the fast-BCR-serialization facility.
9932 ; This allows for a slightly faster sync which is sufficient for our
9933 ; purposes.
9934 (define_insn "mem_thread_fence_1"
9935 [(set (match_operand:BLK 0 "" "")
9936 (unspec:BLK [(match_dup 0)] UNSPEC_MB))]
9937 ""
9938 {
9939 if (TARGET_Z196)
9940 return "bcr\t14,0";
9941 else
9942 return "bcr\t15,0";
9943 }
9944 [(set_attr "op_type" "RR")
9945 (set_attr "mnemonic" "bcr_flush")
9946 (set_attr "z196prop" "z196_alone")])
9947
9948 ;
9949 ; atomic load/store operations
9950 ;
9951
9952 ; Atomic loads need not examine the memory model at all.
9953 (define_expand "atomic_load<mode>"
9954 [(match_operand:DINT 0 "register_operand") ;; output
9955 (match_operand:DINT 1 "memory_operand") ;; memory
9956 (match_operand:SI 2 "const_int_operand")] ;; model
9957 ""
9958 {
9959 if (MEM_ALIGN (operands[1]) < GET_MODE_BITSIZE (GET_MODE (operands[1])))
9960 FAIL;
9961
9962 if (<MODE>mode == TImode)
9963 emit_insn (gen_atomic_loadti_1 (operands[0], operands[1]));
9964 else if (<MODE>mode == DImode && !TARGET_ZARCH)
9965 emit_insn (gen_atomic_loaddi_1 (operands[0], operands[1]));
9966 else
9967 emit_move_insn (operands[0], operands[1]);
9968 DONE;
9969 })
9970
9971 ; Different from movdi_31 in that we want no splitters.
9972 (define_insn "atomic_loaddi_1"
9973 [(set (match_operand:DI 0 "register_operand" "=d,d,!*f,!*f")
9974 (unspec:DI [(match_operand:DI 1 "memory_operand" "Q,S,R,T")]
9975 UNSPEC_MOVA))]
9976 "!TARGET_ZARCH"
9977 "@
9978 lm\t%0,%M0,%S1
9979 lmy\t%0,%M0,%S1
9980 ld\t%0,%1
9981 ldy\t%0,%1"
9982 [(set_attr "op_type" "RS,RSY,RS,RSY")
9983 (set_attr "cpu_facility" "*,longdisp,*,longdisp")
9984 (set_attr "type" "lm,lm,floaddf,floaddf")])
9985
9986 (define_insn "atomic_loadti_1"
9987 [(set (match_operand:TI 0 "register_operand" "=r")
9988 (unspec:TI [(match_operand:TI 1 "memory_operand" "T")]
9989 UNSPEC_MOVA))]
9990 "TARGET_ZARCH"
9991 "lpq\t%0,%1"
9992 [(set_attr "op_type" "RXY")
9993 (set_attr "type" "other")])
9994
9995 ; Atomic stores must(?) enforce sequential consistency.
9996 (define_expand "atomic_store<mode>"
9997 [(match_operand:DINT 0 "memory_operand") ;; memory
9998 (match_operand:DINT 1 "register_operand") ;; input
9999 (match_operand:SI 2 "const_int_operand")] ;; model
10000 ""
10001 {
10002 enum memmodel model = memmodel_from_int (INTVAL (operands[2]));
10003
10004 if (MEM_ALIGN (operands[0]) < GET_MODE_BITSIZE (GET_MODE (operands[0])))
10005 FAIL;
10006
10007 if (<MODE>mode == TImode)
10008 emit_insn (gen_atomic_storeti_1 (operands[0], operands[1]));
10009 else if (<MODE>mode == DImode && !TARGET_ZARCH)
10010 emit_insn (gen_atomic_storedi_1 (operands[0], operands[1]));
10011 else
10012 emit_move_insn (operands[0], operands[1]);
10013 if (is_mm_seq_cst (model))
10014 emit_insn (gen_mem_thread_fence (operands[2]));
10015 DONE;
10016 })
10017
10018 ; Different from movdi_31 in that we want no splitters.
10019 (define_insn "atomic_storedi_1"
10020 [(set (match_operand:DI 0 "memory_operand" "=Q,S,R,T")
10021 (unspec:DI [(match_operand:DI 1 "register_operand" "d,d,!*f,!*f")]
10022 UNSPEC_MOVA))]
10023 "!TARGET_ZARCH"
10024 "@
10025 stm\t%1,%N1,%S0
10026 stmy\t%1,%N1,%S0
10027 std %1,%0
10028 stdy %1,%0"
10029 [(set_attr "op_type" "RS,RSY,RS,RSY")
10030 (set_attr "cpu_facility" "*,longdisp,*,longdisp")
10031 (set_attr "type" "stm,stm,fstoredf,fstoredf")])
10032
10033 (define_insn "atomic_storeti_1"
10034 [(set (match_operand:TI 0 "memory_operand" "=T")
10035 (unspec:TI [(match_operand:TI 1 "register_operand" "r")]
10036 UNSPEC_MOVA))]
10037 "TARGET_ZARCH"
10038 "stpq\t%1,%0"
10039 [(set_attr "op_type" "RXY")
10040 (set_attr "type" "other")])
10041
10042 ;
10043 ; compare and swap patterns.
10044 ;
10045
10046 (define_expand "atomic_compare_and_swap<mode>"
10047 [(match_operand:SI 0 "register_operand") ;; bool success output
10048 (match_operand:DGPR 1 "nonimmediate_operand");; oldval output
10049 (match_operand:DGPR 2 "memory_operand") ;; memory
10050 (match_operand:DGPR 3 "register_operand") ;; expected intput
10051 (match_operand:DGPR 4 "register_operand") ;; newval intput
10052 (match_operand:SI 5 "const_int_operand") ;; is_weak
10053 (match_operand:SI 6 "const_int_operand") ;; success model
10054 (match_operand:SI 7 "const_int_operand")] ;; failure model
10055 ""
10056 {
10057 rtx cc, cmp, output = operands[1];
10058
10059 if (!register_operand (output, <MODE>mode))
10060 output = gen_reg_rtx (<MODE>mode);
10061
10062 if (MEM_ALIGN (operands[2]) < GET_MODE_BITSIZE (GET_MODE (operands[2])))
10063 FAIL;
10064
10065 emit_insn (gen_atomic_compare_and_swap<mode>_internal
10066 (output, operands[2], operands[3], operands[4]));
10067
10068 /* We deliberately accept non-register operands in the predicate
10069 to ensure the write back to the output operand happens *before*
10070 the store-flags code below. This makes it easier for combine
10071 to merge the store-flags code with a potential test-and-branch
10072 pattern following (immediately!) afterwards. */
10073 if (output != operands[1])
10074 emit_move_insn (operands[1], output);
10075
10076 cc = gen_rtx_REG (CCZ1mode, CC_REGNUM);
10077 cmp = gen_rtx_EQ (SImode, cc, const0_rtx);
10078 emit_insn (gen_cstorecc4 (operands[0], cmp, cc, const0_rtx));
10079 DONE;
10080 })
10081
10082 (define_expand "atomic_compare_and_swap<mode>"
10083 [(match_operand:SI 0 "register_operand") ;; bool success output
10084 (match_operand:HQI 1 "nonimmediate_operand") ;; oldval output
10085 (match_operand:HQI 2 "memory_operand") ;; memory
10086 (match_operand:HQI 3 "general_operand") ;; expected intput
10087 (match_operand:HQI 4 "general_operand") ;; newval intput
10088 (match_operand:SI 5 "const_int_operand") ;; is_weak
10089 (match_operand:SI 6 "const_int_operand") ;; success model
10090 (match_operand:SI 7 "const_int_operand")] ;; failure model
10091 ""
10092 {
10093 s390_expand_cs_hqi (<MODE>mode, operands[0], operands[1], operands[2],
10094 operands[3], operands[4], INTVAL (operands[5]));
10095 DONE;
10096 })
10097
10098 (define_expand "atomic_compare_and_swap<mode>_internal"
10099 [(parallel
10100 [(set (match_operand:DGPR 0 "register_operand")
10101 (match_operand:DGPR 1 "memory_operand"))
10102 (set (match_dup 1)
10103 (unspec_volatile:DGPR
10104 [(match_dup 1)
10105 (match_operand:DGPR 2 "register_operand")
10106 (match_operand:DGPR 3 "register_operand")]
10107 UNSPECV_CAS))
10108 (set (reg:CCZ1 CC_REGNUM)
10109 (compare:CCZ1 (match_dup 1) (match_dup 2)))])]
10110 "")
10111
10112 ; cdsg, csg
10113 (define_insn "*atomic_compare_and_swap<mode>_1"
10114 [(set (match_operand:TDI 0 "register_operand" "=r")
10115 (match_operand:TDI 1 "memory_operand" "+S"))
10116 (set (match_dup 1)
10117 (unspec_volatile:TDI
10118 [(match_dup 1)
10119 (match_operand:TDI 2 "register_operand" "0")
10120 (match_operand:TDI 3 "register_operand" "r")]
10121 UNSPECV_CAS))
10122 (set (reg:CCZ1 CC_REGNUM)
10123 (compare:CCZ1 (match_dup 1) (match_dup 2)))]
10124 "TARGET_ZARCH"
10125 "c<td>sg\t%0,%3,%S1"
10126 [(set_attr "op_type" "RSY")
10127 (set_attr "type" "sem")])
10128
10129 ; cds, cdsy
10130 (define_insn "*atomic_compare_and_swapdi_2"
10131 [(set (match_operand:DI 0 "register_operand" "=r,r")
10132 (match_operand:DI 1 "memory_operand" "+Q,S"))
10133 (set (match_dup 1)
10134 (unspec_volatile:DI
10135 [(match_dup 1)
10136 (match_operand:DI 2 "register_operand" "0,0")
10137 (match_operand:DI 3 "register_operand" "r,r")]
10138 UNSPECV_CAS))
10139 (set (reg:CCZ1 CC_REGNUM)
10140 (compare:CCZ1 (match_dup 1) (match_dup 2)))]
10141 "!TARGET_ZARCH"
10142 "@
10143 cds\t%0,%3,%S1
10144 cdsy\t%0,%3,%S1"
10145 [(set_attr "op_type" "RS,RSY")
10146 (set_attr "cpu_facility" "*,longdisp")
10147 (set_attr "type" "sem")])
10148
10149 ; cs, csy
10150 (define_insn "*atomic_compare_and_swapsi_3"
10151 [(set (match_operand:SI 0 "register_operand" "=r,r")
10152 (match_operand:SI 1 "memory_operand" "+Q,S"))
10153 (set (match_dup 1)
10154 (unspec_volatile:SI
10155 [(match_dup 1)
10156 (match_operand:SI 2 "register_operand" "0,0")
10157 (match_operand:SI 3 "register_operand" "r,r")]
10158 UNSPECV_CAS))
10159 (set (reg:CCZ1 CC_REGNUM)
10160 (compare:CCZ1 (match_dup 1) (match_dup 2)))]
10161 ""
10162 "@
10163 cs\t%0,%3,%S1
10164 csy\t%0,%3,%S1"
10165 [(set_attr "op_type" "RS,RSY")
10166 (set_attr "cpu_facility" "*,longdisp")
10167 (set_attr "type" "sem")])
10168
10169 ;
10170 ; Other atomic instruction patterns.
10171 ;
10172
10173 ; z196 load and add, xor, or and and instructions
10174
10175 (define_expand "atomic_fetch_<atomic><mode>"
10176 [(match_operand:GPR 0 "register_operand") ;; val out
10177 (ATOMIC_Z196:GPR
10178 (match_operand:GPR 1 "memory_operand") ;; memory
10179 (match_operand:GPR 2 "register_operand")) ;; val in
10180 (match_operand:SI 3 "const_int_operand")] ;; model
10181 "TARGET_Z196"
10182 {
10183 if (MEM_ALIGN (operands[1]) < GET_MODE_BITSIZE (GET_MODE (operands[1])))
10184 FAIL;
10185
10186 emit_insn (gen_atomic_fetch_<atomic><mode>_iaf
10187 (operands[0], operands[1], operands[2]));
10188 DONE;
10189 })
10190
10191 ; lan, lang, lao, laog, lax, laxg, laa, laag
10192 (define_insn "atomic_fetch_<atomic><mode>_iaf"
10193 [(set (match_operand:GPR 0 "register_operand" "=d")
10194 (match_operand:GPR 1 "memory_operand" "+S"))
10195 (set (match_dup 1)
10196 (unspec_volatile:GPR
10197 [(ATOMIC_Z196:GPR (match_dup 1)
10198 (match_operand:GPR 2 "general_operand" "d"))]
10199 UNSPECV_ATOMIC_OP))
10200 (clobber (reg:CC CC_REGNUM))]
10201 "TARGET_Z196"
10202 "la<noxa><g>\t%0,%2,%1"
10203 [(set_attr "op_type" "RSY")
10204 (set_attr "type" "sem")])
10205
10206 ;; For SImode and larger, the optabs.c code will do just fine in
10207 ;; expanding a compare-and-swap loop. For QI/HImode, we can do
10208 ;; better by expanding our own loop.
10209
10210 (define_expand "atomic_<atomic><mode>"
10211 [(ATOMIC:HQI
10212 (match_operand:HQI 0 "memory_operand") ;; memory
10213 (match_operand:HQI 1 "general_operand")) ;; val in
10214 (match_operand:SI 2 "const_int_operand")] ;; model
10215 ""
10216 {
10217 s390_expand_atomic (<MODE>mode, <CODE>, NULL_RTX, operands[0],
10218 operands[1], false);
10219 DONE;
10220 })
10221
10222 (define_expand "atomic_fetch_<atomic><mode>"
10223 [(match_operand:HQI 0 "register_operand") ;; val out
10224 (ATOMIC:HQI
10225 (match_operand:HQI 1 "memory_operand") ;; memory
10226 (match_operand:HQI 2 "general_operand")) ;; val in
10227 (match_operand:SI 3 "const_int_operand")] ;; model
10228 ""
10229 {
10230 s390_expand_atomic (<MODE>mode, <CODE>, operands[0], operands[1],
10231 operands[2], false);
10232 DONE;
10233 })
10234
10235 (define_expand "atomic_<atomic>_fetch<mode>"
10236 [(match_operand:HQI 0 "register_operand") ;; val out
10237 (ATOMIC:HQI
10238 (match_operand:HQI 1 "memory_operand") ;; memory
10239 (match_operand:HQI 2 "general_operand")) ;; val in
10240 (match_operand:SI 3 "const_int_operand")] ;; model
10241 ""
10242 {
10243 s390_expand_atomic (<MODE>mode, <CODE>, operands[0], operands[1],
10244 operands[2], true);
10245 DONE;
10246 })
10247
10248 (define_expand "atomic_exchange<mode>"
10249 [(match_operand:HQI 0 "register_operand") ;; val out
10250 (match_operand:HQI 1 "memory_operand") ;; memory
10251 (match_operand:HQI 2 "general_operand") ;; val in
10252 (match_operand:SI 3 "const_int_operand")] ;; model
10253 ""
10254 {
10255 s390_expand_atomic (<MODE>mode, SET, operands[0], operands[1],
10256 operands[2], false);
10257 DONE;
10258 })
10259
10260 ;;
10261 ;;- Miscellaneous instructions.
10262 ;;
10263
10264 ;
10265 ; allocate stack instruction pattern(s).
10266 ;
10267
10268 (define_expand "allocate_stack"
10269 [(match_operand 0 "general_operand" "")
10270 (match_operand 1 "general_operand" "")]
10271 "TARGET_BACKCHAIN"
10272 {
10273 rtx temp = gen_reg_rtx (Pmode);
10274
10275 emit_move_insn (temp, s390_back_chain_rtx ());
10276 anti_adjust_stack (operands[1]);
10277 emit_move_insn (s390_back_chain_rtx (), temp);
10278
10279 emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
10280 DONE;
10281 })
10282
10283
10284 ;
10285 ; setjmp instruction pattern.
10286 ;
10287
10288 (define_expand "builtin_setjmp_receiver"
10289 [(match_operand 0 "" "")]
10290 "flag_pic"
10291 {
10292 emit_insn (s390_load_got ());
10293 emit_use (pic_offset_table_rtx);
10294 DONE;
10295 })
10296
10297 ;; These patterns say how to save and restore the stack pointer. We need not
10298 ;; save the stack pointer at function level since we are careful to
10299 ;; preserve the backchain. At block level, we have to restore the backchain
10300 ;; when we restore the stack pointer.
10301 ;;
10302 ;; For nonlocal gotos, we must save both the stack pointer and its
10303 ;; backchain and restore both. Note that in the nonlocal case, the
10304 ;; save area is a memory location.
10305
10306 (define_expand "save_stack_function"
10307 [(match_operand 0 "general_operand" "")
10308 (match_operand 1 "general_operand" "")]
10309 ""
10310 "DONE;")
10311
10312 (define_expand "restore_stack_function"
10313 [(match_operand 0 "general_operand" "")
10314 (match_operand 1 "general_operand" "")]
10315 ""
10316 "DONE;")
10317
10318 (define_expand "restore_stack_block"
10319 [(match_operand 0 "register_operand" "")
10320 (match_operand 1 "register_operand" "")]
10321 "TARGET_BACKCHAIN"
10322 {
10323 rtx temp = gen_reg_rtx (Pmode);
10324
10325 emit_move_insn (temp, s390_back_chain_rtx ());
10326 emit_move_insn (operands[0], operands[1]);
10327 emit_move_insn (s390_back_chain_rtx (), temp);
10328
10329 DONE;
10330 })
10331
10332 (define_expand "save_stack_nonlocal"
10333 [(match_operand 0 "memory_operand" "")
10334 (match_operand 1 "register_operand" "")]
10335 ""
10336 {
10337 rtx base = gen_rtx_REG (Pmode, BASE_REGNUM);
10338
10339 /* Copy the backchain to the first word, sp to the second and the
10340 literal pool base to the third. */
10341
10342 rtx save_bc = adjust_address (operands[0], Pmode, 0);
10343 rtx save_sp = adjust_address (operands[0], Pmode, GET_MODE_SIZE (Pmode));
10344 rtx save_bp = adjust_address (operands[0], Pmode, 2 * GET_MODE_SIZE (Pmode));
10345
10346 if (TARGET_BACKCHAIN)
10347 emit_move_insn (save_bc, force_reg (Pmode, s390_back_chain_rtx ()));
10348
10349 emit_move_insn (save_sp, operands[1]);
10350 emit_move_insn (save_bp, base);
10351
10352 DONE;
10353 })
10354
10355 (define_expand "restore_stack_nonlocal"
10356 [(match_operand 0 "register_operand" "")
10357 (match_operand 1 "memory_operand" "")]
10358 ""
10359 {
10360 rtx base = gen_rtx_REG (Pmode, BASE_REGNUM);
10361 rtx temp = NULL_RTX;
10362
10363 /* Restore the backchain from the first word, sp from the second and the
10364 literal pool base from the third. */
10365
10366 rtx save_bc = adjust_address (operands[1], Pmode, 0);
10367 rtx save_sp = adjust_address (operands[1], Pmode, GET_MODE_SIZE (Pmode));
10368 rtx save_bp = adjust_address (operands[1], Pmode, 2 * GET_MODE_SIZE (Pmode));
10369
10370 if (TARGET_BACKCHAIN)
10371 temp = force_reg (Pmode, save_bc);
10372
10373 emit_move_insn (base, save_bp);
10374 emit_move_insn (operands[0], save_sp);
10375
10376 if (temp)
10377 emit_move_insn (s390_back_chain_rtx (), temp);
10378
10379 emit_use (base);
10380 DONE;
10381 })
10382
10383 (define_expand "exception_receiver"
10384 [(const_int 0)]
10385 ""
10386 {
10387 s390_set_has_landing_pad_p (true);
10388 DONE;
10389 })
10390
10391 ;
10392 ; nop instruction pattern(s).
10393 ;
10394
10395 (define_insn "nop"
10396 [(const_int 0)]
10397 ""
10398 "lr\t0,0"
10399 [(set_attr "op_type" "RR")
10400 (set_attr "z10prop" "z10_fr_E1")])
10401
10402 (define_insn "nop1"
10403 [(const_int 1)]
10404 ""
10405 "lr\t1,1"
10406 [(set_attr "op_type" "RR")])
10407
10408 ;;- Undeletable nops (used for hotpatching)
10409
10410 (define_insn "nop_2_byte"
10411 [(unspec_volatile [(const_int 0)] UNSPECV_NOP_2_BYTE)]
10412 ""
10413 "nopr\t%%r0"
10414 [(set_attr "op_type" "RR")])
10415
10416 (define_insn "nop_4_byte"
10417 [(unspec_volatile [(const_int 0)] UNSPECV_NOP_4_BYTE)]
10418 ""
10419 "nop\t0"
10420 [(set_attr "op_type" "RX")])
10421
10422 (define_insn "nop_6_byte"
10423 [(unspec_volatile [(const_int 0)] UNSPECV_NOP_6_BYTE)]
10424 "TARGET_CPU_ZARCH"
10425 "brcl\t0, 0"
10426 [(set_attr "op_type" "RIL")])
10427
10428
10429 ;
10430 ; Special literal pool access instruction pattern(s).
10431 ;
10432
10433 (define_insn "*pool_entry"
10434 [(unspec_volatile [(match_operand 0 "consttable_operand" "X")]
10435 UNSPECV_POOL_ENTRY)]
10436 ""
10437 {
10438 machine_mode mode = GET_MODE (PATTERN (insn));
10439 unsigned int align = GET_MODE_BITSIZE (mode);
10440 s390_output_pool_entry (operands[0], mode, align);
10441 return "";
10442 }
10443 [(set (attr "length")
10444 (symbol_ref "GET_MODE_SIZE (GET_MODE (PATTERN (insn)))"))])
10445
10446 (define_insn "pool_align"
10447 [(unspec_volatile [(match_operand 0 "const_int_operand" "n")]
10448 UNSPECV_POOL_ALIGN)]
10449 ""
10450 ".align\t%0"
10451 [(set (attr "length") (symbol_ref "INTVAL (operands[0])"))])
10452
10453 (define_insn "pool_section_start"
10454 [(unspec_volatile [(const_int 1)] UNSPECV_POOL_SECTION)]
10455 ""
10456 {
10457 switch_to_section (targetm.asm_out.function_rodata_section
10458 (current_function_decl));
10459 return "";
10460 }
10461 [(set_attr "length" "0")])
10462
10463 (define_insn "pool_section_end"
10464 [(unspec_volatile [(const_int 0)] UNSPECV_POOL_SECTION)]
10465 ""
10466 {
10467 switch_to_section (current_function_section ());
10468 return "";
10469 }
10470 [(set_attr "length" "0")])
10471
10472 (define_insn "main_base_31_small"
10473 [(set (match_operand 0 "register_operand" "=a")
10474 (unspec [(label_ref (match_operand 1 "" ""))] UNSPEC_MAIN_BASE))]
10475 "!TARGET_CPU_ZARCH && GET_MODE (operands[0]) == Pmode"
10476 "basr\t%0,0"
10477 [(set_attr "op_type" "RR")
10478 (set_attr "type" "la")
10479 (set_attr "z196prop" "z196_cracked")])
10480
10481 (define_insn "main_base_31_large"
10482 [(set (match_operand 0 "register_operand" "=a")
10483 (unspec [(label_ref (match_operand 1 "" ""))] UNSPEC_MAIN_BASE))
10484 (set (pc) (label_ref (match_operand 2 "" "")))]
10485 "!TARGET_CPU_ZARCH && GET_MODE (operands[0]) == Pmode"
10486 "bras\t%0,%2"
10487 [(set_attr "op_type" "RI")
10488 (set_attr "z196prop" "z196_cracked")])
10489
10490 (define_insn "main_base_64"
10491 [(set (match_operand 0 "register_operand" "=a")
10492 (unspec [(label_ref (match_operand 1 "" ""))] UNSPEC_MAIN_BASE))]
10493 "TARGET_CPU_ZARCH && GET_MODE (operands[0]) == Pmode"
10494 "larl\t%0,%1"
10495 [(set_attr "op_type" "RIL")
10496 (set_attr "type" "larl")
10497 (set_attr "z10prop" "z10_fwd_A1")])
10498
10499 (define_insn "main_pool"
10500 [(set (match_operand 0 "register_operand" "=a")
10501 (unspec_volatile [(const_int 0)] UNSPECV_MAIN_POOL))]
10502 "GET_MODE (operands[0]) == Pmode"
10503 {
10504 gcc_unreachable ();
10505 }
10506 [(set (attr "type")
10507 (if_then_else (match_test "TARGET_CPU_ZARCH")
10508 (const_string "larl") (const_string "la")))])
10509
10510 (define_insn "reload_base_31"
10511 [(set (match_operand 0 "register_operand" "=a")
10512 (unspec [(label_ref (match_operand 1 "" ""))] UNSPEC_RELOAD_BASE))]
10513 "!TARGET_CPU_ZARCH && GET_MODE (operands[0]) == Pmode"
10514 "basr\t%0,0\;la\t%0,%1-.(%0)"
10515 [(set_attr "length" "6")
10516 (set_attr "type" "la")
10517 (set_attr "z196prop" "z196_cracked")])
10518
10519 (define_insn "reload_base_64"
10520 [(set (match_operand 0 "register_operand" "=a")
10521 (unspec [(label_ref (match_operand 1 "" ""))] UNSPEC_RELOAD_BASE))]
10522 "TARGET_CPU_ZARCH && GET_MODE (operands[0]) == Pmode"
10523 "larl\t%0,%1"
10524 [(set_attr "op_type" "RIL")
10525 (set_attr "type" "larl")
10526 (set_attr "z10prop" "z10_fwd_A1")])
10527
10528 (define_insn "pool"
10529 [(unspec_volatile [(match_operand 0 "const_int_operand" "n")] UNSPECV_POOL)]
10530 ""
10531 {
10532 gcc_unreachable ();
10533 }
10534 [(set (attr "length") (symbol_ref "INTVAL (operands[0])"))])
10535
10536 ;;
10537 ;; Insns related to generating the function prologue and epilogue.
10538 ;;
10539
10540
10541 (define_expand "prologue"
10542 [(use (const_int 0))]
10543 ""
10544 "s390_emit_prologue (); DONE;")
10545
10546 (define_expand "epilogue"
10547 [(use (const_int 1))]
10548 ""
10549 "s390_emit_epilogue (false); DONE;")
10550
10551 (define_expand "sibcall_epilogue"
10552 [(use (const_int 0))]
10553 ""
10554 "s390_emit_epilogue (true); DONE;")
10555
10556 ;; A direct return instruction, without using an epilogue.
10557 (define_insn "<code>"
10558 [(ANY_RETURN)]
10559 "s390_can_use_<code>_insn ()"
10560 "br\t%%r14"
10561 [(set_attr "op_type" "RR")
10562 (set_attr "type" "jsr")
10563 (set_attr "atype" "agen")])
10564
10565 (define_insn "*return"
10566 [(return)
10567 (use (match_operand 0 "register_operand" "a"))]
10568 "GET_MODE (operands[0]) == Pmode"
10569 "br\t%0"
10570 [(set_attr "op_type" "RR")
10571 (set_attr "type" "jsr")
10572 (set_attr "atype" "agen")])
10573
10574
10575 ;; Instruction definition to extend a 31-bit pointer into a 64-bit
10576 ;; pointer. This is used for compatibility.
10577
10578 (define_expand "ptr_extend"
10579 [(set (match_operand:DI 0 "register_operand" "=r")
10580 (match_operand:SI 1 "register_operand" "r"))]
10581 "TARGET_64BIT"
10582 {
10583 emit_insn (gen_anddi3 (operands[0],
10584 gen_lowpart (DImode, operands[1]),
10585 GEN_INT (0x7fffffff)));
10586 DONE;
10587 })
10588
10589 ;; Instruction definition to expand eh_return macro to support
10590 ;; swapping in special linkage return addresses.
10591
10592 (define_expand "eh_return"
10593 [(use (match_operand 0 "register_operand" ""))]
10594 "TARGET_TPF"
10595 {
10596 s390_emit_tpf_eh_return (operands[0]);
10597 DONE;
10598 })
10599
10600 ;
10601 ; Stack Protector Patterns
10602 ;
10603
10604 (define_expand "stack_protect_set"
10605 [(set (match_operand 0 "memory_operand" "")
10606 (match_operand 1 "memory_operand" ""))]
10607 ""
10608 {
10609 #ifdef TARGET_THREAD_SSP_OFFSET
10610 operands[1]
10611 = gen_rtx_MEM (Pmode, gen_rtx_PLUS (Pmode, s390_get_thread_pointer (),
10612 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
10613 #endif
10614 if (TARGET_64BIT)
10615 emit_insn (gen_stack_protect_setdi (operands[0], operands[1]));
10616 else
10617 emit_insn (gen_stack_protect_setsi (operands[0], operands[1]));
10618
10619 DONE;
10620 })
10621
10622 (define_insn "stack_protect_set<mode>"
10623 [(set (match_operand:DSI 0 "memory_operand" "=Q")
10624 (unspec:DSI [(match_operand:DSI 1 "memory_operand" "Q")] UNSPEC_SP_SET))]
10625 ""
10626 "mvc\t%O0(%G0,%R0),%S1"
10627 [(set_attr "op_type" "SS")])
10628
10629 (define_expand "stack_protect_test"
10630 [(set (reg:CC CC_REGNUM)
10631 (compare (match_operand 0 "memory_operand" "")
10632 (match_operand 1 "memory_operand" "")))
10633 (match_operand 2 "" "")]
10634 ""
10635 {
10636 rtx cc_reg, test;
10637 #ifdef TARGET_THREAD_SSP_OFFSET
10638 operands[1]
10639 = gen_rtx_MEM (Pmode, gen_rtx_PLUS (Pmode, s390_get_thread_pointer (),
10640 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
10641 #endif
10642 if (TARGET_64BIT)
10643 emit_insn (gen_stack_protect_testdi (operands[0], operands[1]));
10644 else
10645 emit_insn (gen_stack_protect_testsi (operands[0], operands[1]));
10646
10647 cc_reg = gen_rtx_REG (CCZmode, CC_REGNUM);
10648 test = gen_rtx_EQ (VOIDmode, cc_reg, const0_rtx);
10649 emit_jump_insn (gen_cbranchcc4 (test, cc_reg, const0_rtx, operands[2]));
10650 DONE;
10651 })
10652
10653 (define_insn "stack_protect_test<mode>"
10654 [(set (reg:CCZ CC_REGNUM)
10655 (unspec:CCZ [(match_operand:DSI 0 "memory_operand" "Q")
10656 (match_operand:DSI 1 "memory_operand" "Q")] UNSPEC_SP_TEST))]
10657 ""
10658 "clc\t%O0(%G0,%R0),%S1"
10659 [(set_attr "op_type" "SS")])
10660
10661 ; This is used in s390_emit_prologue in order to prevent insns
10662 ; adjusting the stack pointer to be moved over insns writing stack
10663 ; slots using a copy of the stack pointer in a different register.
10664 (define_insn "stack_tie"
10665 [(set (match_operand:BLK 0 "memory_operand" "+m")
10666 (unspec:BLK [(match_dup 0)] UNSPEC_TIE))]
10667 ""
10668 ""
10669 [(set_attr "length" "0")])
10670
10671
10672 (define_insn "stack_restore_from_fpr"
10673 [(set (reg:DI STACK_REGNUM)
10674 (match_operand:DI 0 "register_operand" "f"))
10675 (clobber (mem:BLK (scratch)))]
10676 "TARGET_Z10"
10677 "lgdr\t%%r15,%0"
10678 [(set_attr "op_type" "RRE")])
10679
10680 ;
10681 ; Data prefetch patterns
10682 ;
10683
10684 (define_insn "prefetch"
10685 [(prefetch (match_operand 0 "address_operand" "ZT,X")
10686 (match_operand:SI 1 "const_int_operand" " n,n")
10687 (match_operand:SI 2 "const_int_operand" " n,n"))]
10688 "TARGET_Z10"
10689 {
10690 switch (which_alternative)
10691 {
10692 case 0:
10693 return INTVAL (operands[1]) == 1 ? "pfd\t2,%a0" : "pfd\t1,%a0";
10694 case 1:
10695 if (larl_operand (operands[0], Pmode))
10696 return INTVAL (operands[1]) == 1 ? "pfdrl\t2,%a0" : "pfdrl\t1,%a0";
10697 /* fallthrough */
10698 default:
10699
10700 /* This might be reached for symbolic operands with an odd
10701 addend. We simply omit the prefetch for such rare cases. */
10702
10703 return "";
10704 }
10705 }
10706 [(set_attr "type" "load,larl")
10707 (set_attr "op_type" "RXY,RIL")
10708 (set_attr "z10prop" "z10_super")
10709 (set_attr "z196prop" "z196_alone")])
10710
10711
10712 ;
10713 ; Byte swap instructions
10714 ;
10715
10716 ; FIXME: There is also mvcin but we cannot use it since src and target
10717 ; may overlap.
10718 ; lrvr, lrv, strv, lrvgr, lrvg, strvg
10719 (define_insn "bswap<mode>2"
10720 [(set (match_operand:GPR 0 "nonimmediate_operand" "=d,d,T")
10721 (bswap:GPR (match_operand:GPR 1 "nonimmediate_operand" " d,T,d")))]
10722 "TARGET_CPU_ZARCH"
10723 "@
10724 lrv<g>r\t%0,%1
10725 lrv<g>\t%0,%1
10726 strv<g>\t%1,%0"
10727 [(set_attr "type" "*,load,store")
10728 (set_attr "op_type" "RRE,RXY,RXY")
10729 (set_attr "z10prop" "z10_super")])
10730
10731 (define_insn "bswaphi2"
10732 [(set (match_operand:HI 0 "nonimmediate_operand" "=d,d,T")
10733 (bswap:HI (match_operand:HI 1 "nonimmediate_operand" " d,T,d")))]
10734 "TARGET_CPU_ZARCH"
10735 "@
10736 #
10737 lrvh\t%0,%1
10738 strvh\t%1,%0"
10739 [(set_attr "type" "*,load,store")
10740 (set_attr "op_type" "RRE,RXY,RXY")
10741 (set_attr "z10prop" "z10_super")])
10742
10743 (define_split
10744 [(set (match_operand:HI 0 "register_operand" "")
10745 (bswap:HI (match_operand:HI 1 "register_operand" "")))]
10746 "TARGET_CPU_ZARCH"
10747 [(set (match_dup 2) (bswap:SI (match_dup 3)))
10748 (set (match_dup 2) (lshiftrt:SI (match_dup 2) (const_int 16)))]
10749 {
10750 operands[2] = simplify_gen_subreg (SImode, operands[0], HImode, 0);
10751 operands[3] = simplify_gen_subreg (SImode, operands[1], HImode, 0);
10752 })
10753
10754
10755 ;
10756 ; Population count instruction
10757 ;
10758
10759 ; The S/390 popcount instruction counts the bits of op1 in 8 byte
10760 ; portions and stores the result in the corresponding bytes in op0.
10761 (define_insn "*popcount<mode>"
10762 [(set (match_operand:INT 0 "register_operand" "=d")
10763 (unspec:INT [(match_operand:INT 1 "register_operand" "d")] UNSPEC_POPCNT))
10764 (clobber (reg:CC CC_REGNUM))]
10765 "TARGET_Z196"
10766 "popcnt\t%0,%1"
10767 [(set_attr "op_type" "RRE")])
10768
10769 (define_expand "popcountdi2"
10770 [; popcnt op0, op1
10771 (parallel [(set (match_operand:DI 0 "register_operand" "")
10772 (unspec:DI [(match_operand:DI 1 "register_operand")]
10773 UNSPEC_POPCNT))
10774 (clobber (reg:CC CC_REGNUM))])
10775 ; sllg op2, op0, 32
10776 (set (match_dup 2) (ashift:DI (match_dup 0) (const_int 32)))
10777 ; agr op0, op2
10778 (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 2)))
10779 (clobber (reg:CC CC_REGNUM))])
10780 ; sllg op2, op0, 16
10781 (set (match_dup 2)
10782 (ashift:DI (match_dup 0) (const_int 16)))
10783 ; agr op0, op2
10784 (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 2)))
10785 (clobber (reg:CC CC_REGNUM))])
10786 ; sllg op2, op0, 8
10787 (set (match_dup 2) (ashift:DI (match_dup 0) (const_int 8)))
10788 ; agr op0, op2
10789 (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 2)))
10790 (clobber (reg:CC CC_REGNUM))])
10791 ; srlg op0, op0, 56
10792 (set (match_dup 0) (lshiftrt:DI (match_dup 0) (const_int 56)))]
10793 "TARGET_Z196 && TARGET_64BIT"
10794 "operands[2] = gen_reg_rtx (DImode);")
10795
10796 (define_expand "popcountsi2"
10797 [; popcnt op0, op1
10798 (parallel [(set (match_operand:SI 0 "register_operand" "")
10799 (unspec:SI [(match_operand:SI 1 "register_operand")]
10800 UNSPEC_POPCNT))
10801 (clobber (reg:CC CC_REGNUM))])
10802 ; sllk op2, op0, 16
10803 (set (match_dup 2)
10804 (ashift:SI (match_dup 0) (const_int 16)))
10805 ; ar op0, op2
10806 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
10807 (clobber (reg:CC CC_REGNUM))])
10808 ; sllk op2, op0, 8
10809 (set (match_dup 2) (ashift:SI (match_dup 0) (const_int 8)))
10810 ; ar op0, op2
10811 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
10812 (clobber (reg:CC CC_REGNUM))])
10813 ; srl op0, op0, 24
10814 (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 24)))]
10815 "TARGET_Z196"
10816 "operands[2] = gen_reg_rtx (SImode);")
10817
10818 (define_expand "popcounthi2"
10819 [; popcnt op0, op1
10820 (parallel [(set (match_operand:HI 0 "register_operand" "")
10821 (unspec:HI [(match_operand:HI 1 "register_operand")]
10822 UNSPEC_POPCNT))
10823 (clobber (reg:CC CC_REGNUM))])
10824 ; sllk op2, op0, 8
10825 (set (match_dup 2)
10826 (ashift:SI (match_dup 0) (const_int 8)))
10827 ; ar op0, op2
10828 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
10829 (clobber (reg:CC CC_REGNUM))])
10830 ; srl op0, op0, 8
10831 (set (match_dup 0) (lshiftrt:HI (match_dup 0) (const_int 8)))]
10832 "TARGET_Z196"
10833 "operands[2] = gen_reg_rtx (SImode);")
10834
10835 (define_expand "popcountqi2"
10836 [; popcnt op0, op1
10837 (parallel [(set (match_operand:QI 0 "register_operand" "")
10838 (unspec:QI [(match_operand:QI 1 "register_operand")]
10839 UNSPEC_POPCNT))
10840 (clobber (reg:CC CC_REGNUM))])]
10841 "TARGET_Z196"
10842 "")
10843
10844 ;;
10845 ;;- Copy sign instructions
10846 ;;
10847
10848 (define_insn "copysign<mode>3"
10849 [(set (match_operand:FP 0 "register_operand" "=f")
10850 (unspec:FP [(match_operand:FP 1 "register_operand" "<fT0>")
10851 (match_operand:FP 2 "register_operand" "f")]
10852 UNSPEC_COPYSIGN))]
10853 "TARGET_Z196"
10854 "cpsdr\t%0,%2,%1"
10855 [(set_attr "op_type" "RRF")
10856 (set_attr "type" "fsimp<mode>")])
10857
10858
10859 ;;
10860 ;;- Transactional execution instructions
10861 ;;
10862
10863 ; This splitter helps combine to make use of CC directly when
10864 ; comparing the integer result of a tbegin builtin with a constant.
10865 ; The unspec is already removed by canonicalize_comparison. So this
10866 ; splitters only job is to turn the PARALLEL into separate insns
10867 ; again. Unfortunately this only works with the very first cc/int
10868 ; compare since combine is not able to deal with data flow across
10869 ; basic block boundaries.
10870
10871 ; It needs to be an insn pattern as well since combine does not apply
10872 ; the splitter directly. Combine would only use it if it actually
10873 ; would reduce the number of instructions.
10874 (define_insn_and_split "*ccraw_to_int"
10875 [(set (pc)
10876 (if_then_else
10877 (match_operator 0 "s390_eqne_operator"
10878 [(reg:CCRAW CC_REGNUM)
10879 (match_operand 1 "const_int_operand" "")])
10880 (label_ref (match_operand 2 "" ""))
10881 (pc)))
10882 (set (match_operand:SI 3 "register_operand" "=d")
10883 (unspec:SI [(reg:CCRAW CC_REGNUM)] UNSPEC_CC_TO_INT))]
10884 ""
10885 "#"
10886 ""
10887 [(set (match_dup 3)
10888 (unspec:SI [(reg:CCRAW CC_REGNUM)] UNSPEC_CC_TO_INT))
10889 (set (pc)
10890 (if_then_else (match_op_dup 0 [(reg:CCRAW CC_REGNUM) (match_dup 1)])
10891 (label_ref (match_dup 2))
10892 (pc)))]
10893 "")
10894
10895 ; Non-constrained transaction begin
10896
10897 (define_expand "tbegin"
10898 [(match_operand:SI 0 "register_operand" "")
10899 (match_operand:BLK 1 "memory_operand" "")]
10900 "TARGET_HTM"
10901 {
10902 s390_expand_tbegin (operands[0], operands[1], NULL_RTX, true);
10903 DONE;
10904 })
10905
10906 (define_expand "tbegin_nofloat"
10907 [(match_operand:SI 0 "register_operand" "")
10908 (match_operand:BLK 1 "memory_operand" "")]
10909 "TARGET_HTM"
10910 {
10911 s390_expand_tbegin (operands[0], operands[1], NULL_RTX, false);
10912 DONE;
10913 })
10914
10915 (define_expand "tbegin_retry"
10916 [(match_operand:SI 0 "register_operand" "")
10917 (match_operand:BLK 1 "memory_operand" "")
10918 (match_operand:SI 2 "general_operand" "")]
10919 "TARGET_HTM"
10920 {
10921 s390_expand_tbegin (operands[0], operands[1], operands[2], true);
10922 DONE;
10923 })
10924
10925 (define_expand "tbegin_retry_nofloat"
10926 [(match_operand:SI 0 "register_operand" "")
10927 (match_operand:BLK 1 "memory_operand" "")
10928 (match_operand:SI 2 "general_operand" "")]
10929 "TARGET_HTM"
10930 {
10931 s390_expand_tbegin (operands[0], operands[1], operands[2], false);
10932 DONE;
10933 })
10934
10935 ; Clobber VRs since they don't get restored
10936 (define_insn "tbegin_1_z13"
10937 [(set (reg:CCRAW CC_REGNUM)
10938 (unspec_volatile:CCRAW [(match_operand 0 "const_int_operand" "D")]
10939 UNSPECV_TBEGIN))
10940 (set (match_operand:BLK 1 "memory_operand" "=Q")
10941 (unspec_volatile:BLK [(match_dup 0)] UNSPECV_TBEGIN_TDB))
10942 (clobber (reg:TI 16)) (clobber (reg:TI 38))
10943 (clobber (reg:TI 17)) (clobber (reg:TI 39))
10944 (clobber (reg:TI 18)) (clobber (reg:TI 40))
10945 (clobber (reg:TI 19)) (clobber (reg:TI 41))
10946 (clobber (reg:TI 20)) (clobber (reg:TI 42))
10947 (clobber (reg:TI 21)) (clobber (reg:TI 43))
10948 (clobber (reg:TI 22)) (clobber (reg:TI 44))
10949 (clobber (reg:TI 23)) (clobber (reg:TI 45))
10950 (clobber (reg:TI 24)) (clobber (reg:TI 46))
10951 (clobber (reg:TI 25)) (clobber (reg:TI 47))
10952 (clobber (reg:TI 26)) (clobber (reg:TI 48))
10953 (clobber (reg:TI 27)) (clobber (reg:TI 49))
10954 (clobber (reg:TI 28)) (clobber (reg:TI 50))
10955 (clobber (reg:TI 29)) (clobber (reg:TI 51))
10956 (clobber (reg:TI 30)) (clobber (reg:TI 52))
10957 (clobber (reg:TI 31)) (clobber (reg:TI 53))]
10958 ; CONST_OK_FOR_CONSTRAINT_P does not work with D constraint since D is
10959 ; not supposed to be used for immediates (see genpreds.c).
10960 "TARGET_VX && INTVAL (operands[0]) >= 0 && INTVAL (operands[0]) <= 0xffff"
10961 "tbegin\t%1,%x0"
10962 [(set_attr "op_type" "SIL")])
10963
10964 (define_insn "tbegin_1"
10965 [(set (reg:CCRAW CC_REGNUM)
10966 (unspec_volatile:CCRAW [(match_operand 0 "const_int_operand" "D")]
10967 UNSPECV_TBEGIN))
10968 (set (match_operand:BLK 1 "memory_operand" "=Q")
10969 (unspec_volatile:BLK [(match_dup 0)] UNSPECV_TBEGIN_TDB))
10970 (clobber (reg:DF 16))
10971 (clobber (reg:DF 17))
10972 (clobber (reg:DF 18))
10973 (clobber (reg:DF 19))
10974 (clobber (reg:DF 20))
10975 (clobber (reg:DF 21))
10976 (clobber (reg:DF 22))
10977 (clobber (reg:DF 23))
10978 (clobber (reg:DF 24))
10979 (clobber (reg:DF 25))
10980 (clobber (reg:DF 26))
10981 (clobber (reg:DF 27))
10982 (clobber (reg:DF 28))
10983 (clobber (reg:DF 29))
10984 (clobber (reg:DF 30))
10985 (clobber (reg:DF 31))]
10986 ; CONST_OK_FOR_CONSTRAINT_P does not work with D constraint since D is
10987 ; not supposed to be used for immediates (see genpreds.c).
10988 "TARGET_HTM && INTVAL (operands[0]) >= 0 && INTVAL (operands[0]) <= 0xffff"
10989 "tbegin\t%1,%x0"
10990 [(set_attr "op_type" "SIL")])
10991
10992 ; Same as above but without the FPR clobbers
10993 (define_insn "tbegin_nofloat_1"
10994 [(set (reg:CCRAW CC_REGNUM)
10995 (unspec_volatile:CCRAW [(match_operand 0 "const_int_operand" "D")]
10996 UNSPECV_TBEGIN))
10997 (set (match_operand:BLK 1 "memory_operand" "=Q")
10998 (unspec_volatile:BLK [(match_dup 0)] UNSPECV_TBEGIN_TDB))]
10999 "TARGET_HTM && INTVAL (operands[0]) >= 0 && INTVAL (operands[0]) <= 0xffff"
11000 "tbegin\t%1,%x0"
11001 [(set_attr "op_type" "SIL")])
11002
11003
11004 ; Constrained transaction begin
11005
11006 (define_expand "tbeginc"
11007 [(set (reg:CCRAW CC_REGNUM)
11008 (unspec_volatile:CCRAW [(const_int TBEGINC_MASK)]
11009 UNSPECV_TBEGINC))]
11010 "TARGET_HTM"
11011 "")
11012
11013 (define_insn "*tbeginc_1"
11014 [(set (reg:CCRAW CC_REGNUM)
11015 (unspec_volatile:CCRAW [(match_operand 0 "const_int_operand" " D")]
11016 UNSPECV_TBEGINC))]
11017 "TARGET_HTM && INTVAL (operands[0]) >= 0 && INTVAL (operands[0]) <= 0xffff"
11018 "tbeginc\t0,%x0"
11019 [(set_attr "op_type" "SIL")])
11020
11021 ; Transaction end
11022
11023 (define_expand "tend"
11024 [(set (reg:CCRAW CC_REGNUM)
11025 (unspec_volatile:CCRAW [(const_int 0)] UNSPECV_TEND))
11026 (set (match_operand:SI 0 "register_operand" "")
11027 (unspec:SI [(reg:CCRAW CC_REGNUM)] UNSPEC_CC_TO_INT))]
11028 "TARGET_HTM"
11029 "")
11030
11031 (define_insn "*tend_1"
11032 [(set (reg:CCRAW CC_REGNUM)
11033 (unspec_volatile:CCRAW [(const_int 0)] UNSPECV_TEND))]
11034 "TARGET_HTM"
11035 "tend"
11036 [(set_attr "op_type" "S")])
11037
11038 ; Transaction abort
11039
11040 (define_expand "tabort"
11041 [(unspec_volatile [(match_operand:SI 0 "nonmemory_operand" "")]
11042 UNSPECV_TABORT)]
11043 "TARGET_HTM && operands != NULL"
11044 {
11045 if (CONST_INT_P (operands[0])
11046 && INTVAL (operands[0]) >= 0 && INTVAL (operands[0]) <= 255)
11047 {
11048 error ("invalid transaction abort code: " HOST_WIDE_INT_PRINT_DEC
11049 ". Values in range 0 through 255 are reserved.",
11050 INTVAL (operands[0]));
11051 FAIL;
11052 }
11053 })
11054
11055 (define_insn "*tabort_1"
11056 [(unspec_volatile [(match_operand:SI 0 "nonmemory_operand" "aJ")]
11057 UNSPECV_TABORT)]
11058 "TARGET_HTM && operands != NULL"
11059 "tabort\t%Y0"
11060 [(set_attr "op_type" "S")])
11061
11062 (define_insn "*tabort_1_plus"
11063 [(unspec_volatile [(plus:SI (match_operand:SI 0 "register_operand" "a")
11064 (match_operand:SI 1 "const_int_operand" "J"))]
11065 UNSPECV_TABORT)]
11066 "TARGET_HTM && operands != NULL
11067 && CONST_OK_FOR_CONSTRAINT_P (INTVAL (operands[1]), 'J', \"J\")"
11068 "tabort\t%1(%0)"
11069 [(set_attr "op_type" "S")])
11070
11071 ; Transaction extract nesting depth
11072
11073 (define_insn "etnd"
11074 [(set (match_operand:SI 0 "register_operand" "=d")
11075 (unspec_volatile:SI [(const_int 0)] UNSPECV_ETND))]
11076 "TARGET_HTM"
11077 "etnd\t%0"
11078 [(set_attr "op_type" "RRE")])
11079
11080 ; Non-transactional store
11081
11082 (define_insn "ntstg"
11083 [(set (match_operand:DI 0 "memory_operand" "=T")
11084 (unspec_volatile:DI [(match_operand:DI 1 "register_operand" "d")]
11085 UNSPECV_NTSTG))]
11086 "TARGET_HTM"
11087 "ntstg\t%1,%0"
11088 [(set_attr "op_type" "RXY")])
11089
11090 ; Transaction perform processor assist
11091
11092 (define_expand "tx_assist"
11093 [(unspec_volatile [(match_operand:SI 0 "register_operand" "")
11094 (reg:SI GPR0_REGNUM)
11095 (const_int 1)]
11096 UNSPECV_PPA)]
11097 "TARGET_HTM"
11098 "")
11099
11100 (define_insn "*ppa"
11101 [(unspec_volatile [(match_operand:SI 0 "register_operand" "d")
11102 (match_operand:SI 1 "register_operand" "d")
11103 (match_operand 2 "const_int_operand" "I")]
11104 UNSPECV_PPA)]
11105 "TARGET_HTM && INTVAL (operands[2]) < 16"
11106 "ppa\t%0,%1,%2"
11107 [(set_attr "op_type" "RRF")])
11108
11109
11110 ; Set and get floating point control register
11111
11112 (define_insn "sfpc"
11113 [(unspec_volatile [(match_operand:SI 0 "register_operand" "d")]
11114 UNSPECV_SFPC)]
11115 "TARGET_HARD_FLOAT"
11116 "sfpc\t%0")
11117
11118 (define_insn "efpc"
11119 [(set (match_operand:SI 0 "register_operand" "=d")
11120 (unspec_volatile:SI [(const_int 0)] UNSPECV_EFPC))]
11121 "TARGET_HARD_FLOAT"
11122 "efpc\t%0")
11123
11124
11125 ; Load count to block boundary
11126
11127 (define_insn "lcbb"
11128 [(set (match_operand:SI 0 "register_operand" "=d")
11129 (unspec:SI [(match_operand 1 "address_operand" "ZR")
11130 (match_operand:SI 2 "immediate_operand" "C")] UNSPEC_LCBB))
11131 (clobber (reg:CC CC_REGNUM))]
11132 "TARGET_Z13"
11133 "lcbb\t%0,%a1,%b2"
11134 [(set_attr "op_type" "VRX")])
11135
11136 ; Handle -fsplit-stack.
11137
11138 (define_expand "split_stack_prologue"
11139 [(const_int 0)]
11140 ""
11141 {
11142 s390_expand_split_stack_prologue ();
11143 DONE;
11144 })
11145
11146 ;; If there are operand 0 bytes available on the stack, jump to
11147 ;; operand 1.
11148
11149 (define_expand "split_stack_space_check"
11150 [(set (pc) (if_then_else
11151 (ltu (minus (reg 15)
11152 (match_operand 0 "register_operand"))
11153 (unspec [(const_int 0)] UNSPEC_STACK_CHECK))
11154 (label_ref (match_operand 1))
11155 (pc)))]
11156 ""
11157 {
11158 /* Offset from thread pointer to __private_ss. */
11159 int psso = TARGET_64BIT ? 0x38 : 0x20;
11160 rtx tp = s390_get_thread_pointer ();
11161 rtx guard = gen_rtx_MEM (Pmode, plus_constant (Pmode, tp, psso));
11162 rtx reg = gen_reg_rtx (Pmode);
11163 rtx cc;
11164 if (TARGET_64BIT)
11165 emit_insn (gen_subdi3 (reg, stack_pointer_rtx, operands[0]));
11166 else
11167 emit_insn (gen_subsi3 (reg, stack_pointer_rtx, operands[0]));
11168 cc = s390_emit_compare (GT, reg, guard);
11169 s390_emit_jump (operands[1], cc);
11170
11171 DONE;
11172 })
11173
11174 ;; __morestack parameter block for split stack prologue. Parameters are:
11175 ;; parameter block label, label to be called by __morestack, frame size,
11176 ;; stack parameter size.
11177
11178 (define_insn "split_stack_data"
11179 [(unspec_volatile [(match_operand 0 "" "X")
11180 (match_operand 1 "" "X")
11181 (match_operand 2 "const_int_operand" "X")
11182 (match_operand 3 "const_int_operand" "X")]
11183 UNSPECV_SPLIT_STACK_DATA)]
11184 "TARGET_CPU_ZARCH"
11185 {
11186 switch_to_section (targetm.asm_out.function_rodata_section
11187 (current_function_decl));
11188
11189 if (TARGET_64BIT)
11190 output_asm_insn (".align\t8", operands);
11191 else
11192 output_asm_insn (".align\t4", operands);
11193 (*targetm.asm_out.internal_label) (asm_out_file, "L",
11194 CODE_LABEL_NUMBER (operands[0]));
11195 if (TARGET_64BIT)
11196 {
11197 output_asm_insn (".quad\t%2", operands);
11198 output_asm_insn (".quad\t%3", operands);
11199 output_asm_insn (".quad\t%1-%0", operands);
11200 }
11201 else
11202 {
11203 output_asm_insn (".long\t%2", operands);
11204 output_asm_insn (".long\t%3", operands);
11205 output_asm_insn (".long\t%1-%0", operands);
11206 }
11207
11208 switch_to_section (current_function_section ());
11209 return "";
11210 }
11211 [(set_attr "length" "0")])
11212
11213
11214 ;; A jg with minimal fuss for use in split stack prologue.
11215
11216 (define_expand "split_stack_call"
11217 [(match_operand 0 "bras_sym_operand" "X")
11218 (match_operand 1 "" "")]
11219 "TARGET_CPU_ZARCH"
11220 {
11221 if (TARGET_64BIT)
11222 emit_jump_insn (gen_split_stack_call_di (operands[0], operands[1]));
11223 else
11224 emit_jump_insn (gen_split_stack_call_si (operands[0], operands[1]));
11225 DONE;
11226 })
11227
11228 (define_insn "split_stack_call_<mode>"
11229 [(set (pc) (label_ref (match_operand 1 "" "")))
11230 (set (reg:P 1) (unspec_volatile [(match_operand 0 "bras_sym_operand" "X")
11231 (reg:P 1)]
11232 UNSPECV_SPLIT_STACK_CALL))]
11233 "TARGET_CPU_ZARCH"
11234 "jg\t%0"
11235 [(set_attr "op_type" "RIL")
11236 (set_attr "type" "branch")])
11237
11238 ;; Also a conditional one.
11239
11240 (define_expand "split_stack_cond_call"
11241 [(match_operand 0 "bras_sym_operand" "X")
11242 (match_operand 1 "" "")
11243 (match_operand 2 "" "")]
11244 "TARGET_CPU_ZARCH"
11245 {
11246 if (TARGET_64BIT)
11247 emit_jump_insn (gen_split_stack_cond_call_di (operands[0], operands[1], operands[2]));
11248 else
11249 emit_jump_insn (gen_split_stack_cond_call_si (operands[0], operands[1], operands[2]));
11250 DONE;
11251 })
11252
11253 (define_insn "split_stack_cond_call_<mode>"
11254 [(set (pc)
11255 (if_then_else
11256 (match_operand 1 "" "")
11257 (label_ref (match_operand 2 "" ""))
11258 (pc)))
11259 (set (reg:P 1) (unspec_volatile [(match_operand 0 "bras_sym_operand" "X")
11260 (reg:P 1)]
11261 UNSPECV_SPLIT_STACK_CALL))]
11262 "TARGET_CPU_ZARCH"
11263 "jg%C1\t%0"
11264 [(set_attr "op_type" "RIL")
11265 (set_attr "type" "branch")])
11266
11267 (define_insn "osc_break"
11268 [(unspec_volatile [(const_int 0)] UNSPECV_OSC_BREAK)]
11269 ""
11270 "bcr\t7,%%r0"
11271 [(set_attr "op_type" "RR")])