PR target/77822: S390: Validate argument range of {zero,sign}_extract.
[gcc.git] / gcc / config / s390 / s390.md
1 ;;- Machine description for GNU compiler -- S/390 / zSeries version.
2 ;; Copyright (C) 1999-2016 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,vec,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" "vec")
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 ; ltxbr, ltdbr, ltebr, ltxtr, ltdtr
1288 (define_insn "*cmp<mode>_ccs_0"
1289 [(set (reg CC_REGNUM)
1290 (compare (match_operand:FP 0 "register_operand" "f")
1291 (match_operand:FP 1 "const0_operand" "")))]
1292 "s390_match_ccmode(insn, CCSmode) && TARGET_HARD_FLOAT"
1293 "lt<xde><bt>r\t%0,%0"
1294 [(set_attr "op_type" "RRE")
1295 (set_attr "type" "fsimp<mode>")])
1296
1297 ; cxtr, cxbr, cdtr, cdbr, cebr, cdb, ceb
1298 (define_insn "*cmp<mode>_ccs"
1299 [(set (reg CC_REGNUM)
1300 (compare (match_operand:FP 0 "register_operand" "f,f")
1301 (match_operand:FP 1 "general_operand" "f,R")))]
1302 "s390_match_ccmode(insn, CCSmode) && TARGET_HARD_FLOAT"
1303 "@
1304 c<xde><bt>r\t%0,%1
1305 c<xde>b\t%0,%1"
1306 [(set_attr "op_type" "RRE,RXE")
1307 (set_attr "type" "fsimp<mode>")
1308 (set_attr "enabled" "*,<DSF>")])
1309
1310 ; wfcedbs, wfchdbs, wfchedbs
1311 (define_insn "*vec_cmp<insn_cmp>df_cconly"
1312 [(set (reg:VFCMP CC_REGNUM)
1313 (compare:VFCMP (match_operand:DF 0 "register_operand" "v")
1314 (match_operand:DF 1 "register_operand" "v")))
1315 (clobber (match_scratch:V2DI 2 "=v"))]
1316 "TARGET_VX && TARGET_HARD_FLOAT"
1317 "wfc<asm_fcmp>dbs\t%v2,%v0,%v1"
1318 [(set_attr "op_type" "VRR")])
1319
1320 ; Compare and Branch instructions
1321
1322 ; cij, cgij, crj, cgrj, cfi, cgfi, cr, cgr
1323 ; The following instructions do a complementary access of their second
1324 ; operand (z01 only): crj_c, cgrjc, cr, cgr
1325 (define_insn "*cmp_and_br_signed_<mode>"
1326 [(set (pc)
1327 (if_then_else (match_operator 0 "s390_signed_integer_comparison"
1328 [(match_operand:GPR 1 "register_operand" "d,d")
1329 (match_operand:GPR 2 "nonmemory_operand" "d,C")])
1330 (label_ref (match_operand 3 "" ""))
1331 (pc)))
1332 (clobber (reg:CC CC_REGNUM))]
1333 "TARGET_Z10 && !TARGET_AVOID_CMP_AND_BRANCH"
1334 {
1335 if (get_attr_length (insn) == 6)
1336 return which_alternative ?
1337 "c<g>ij%C0\t%1,%c2,%l3" : "c<g>rj%C0\t%1,%2,%l3";
1338 else
1339 return which_alternative ?
1340 "c<g>fi\t%1,%c2\;jg%C0\t%l3" : "c<g>r\t%1,%2\;jg%C0\t%l3";
1341 }
1342 [(set_attr "op_type" "RIE")
1343 (set_attr "type" "branch")
1344 (set_attr "z10prop" "z10_super_c,z10_super")
1345 (set (attr "length")
1346 (if_then_else (lt (abs (minus (pc) (match_dup 3))) (const_int 60000))
1347 (const_int 6) (const_int 12)))]) ; 8 byte for cr/jg
1348 ; 10 byte for cgr/jg
1349
1350 ; clij, clgij, clrj, clgrj, clfi, clgfi, clr, clgr
1351 ; The following instructions do a complementary access of their second
1352 ; operand (z10 only): clrj, clgrj, clr, clgr
1353 (define_insn "*cmp_and_br_unsigned_<mode>"
1354 [(set (pc)
1355 (if_then_else (match_operator 0 "s390_unsigned_integer_comparison"
1356 [(match_operand:GPR 1 "register_operand" "d,d")
1357 (match_operand:GPR 2 "nonmemory_operand" "d,I")])
1358 (label_ref (match_operand 3 "" ""))
1359 (pc)))
1360 (clobber (reg:CC CC_REGNUM))]
1361 "TARGET_Z10 && !TARGET_AVOID_CMP_AND_BRANCH"
1362 {
1363 if (get_attr_length (insn) == 6)
1364 return which_alternative ?
1365 "cl<g>ij%C0\t%1,%b2,%l3" : "cl<g>rj%C0\t%1,%2,%l3";
1366 else
1367 return which_alternative ?
1368 "cl<g>fi\t%1,%b2\;jg%C0\t%l3" : "cl<g>r\t%1,%2\;jg%C0\t%l3";
1369 }
1370 [(set_attr "op_type" "RIE")
1371 (set_attr "type" "branch")
1372 (set_attr "z10prop" "z10_super_c,z10_super")
1373 (set (attr "length")
1374 (if_then_else (lt (abs (minus (pc) (match_dup 3))) (const_int 60000))
1375 (const_int 6) (const_int 12)))]) ; 8 byte for clr/jg
1376 ; 10 byte for clgr/jg
1377
1378 ; And now the same two patterns as above but with a negated CC mask.
1379
1380 ; cij, cgij, crj, cgrj, cfi, cgfi, cr, cgr
1381 ; The following instructions do a complementary access of their second
1382 ; operand (z01 only): crj_c, cgrjc, cr, cgr
1383 (define_insn "*icmp_and_br_signed_<mode>"
1384 [(set (pc)
1385 (if_then_else (match_operator 0 "s390_signed_integer_comparison"
1386 [(match_operand:GPR 1 "register_operand" "d,d")
1387 (match_operand:GPR 2 "nonmemory_operand" "d,C")])
1388 (pc)
1389 (label_ref (match_operand 3 "" ""))))
1390 (clobber (reg:CC CC_REGNUM))]
1391 "TARGET_Z10 && !TARGET_AVOID_CMP_AND_BRANCH"
1392 {
1393 if (get_attr_length (insn) == 6)
1394 return which_alternative ?
1395 "c<g>ij%D0\t%1,%c2,%l3" : "c<g>rj%D0\t%1,%2,%l3";
1396 else
1397 return which_alternative ?
1398 "c<g>fi\t%1,%c2\;jg%D0\t%l3" : "c<g>r\t%1,%2\;jg%D0\t%l3";
1399 }
1400 [(set_attr "op_type" "RIE")
1401 (set_attr "type" "branch")
1402 (set_attr "z10prop" "z10_super_c,z10_super")
1403 (set (attr "length")
1404 (if_then_else (lt (abs (minus (pc) (match_dup 3))) (const_int 60000))
1405 (const_int 6) (const_int 12)))]) ; 8 byte for cr/jg
1406 ; 10 byte for cgr/jg
1407
1408 ; clij, clgij, clrj, clgrj, clfi, clgfi, clr, clgr
1409 ; The following instructions do a complementary access of their second
1410 ; operand (z10 only): clrj, clgrj, clr, clgr
1411 (define_insn "*icmp_and_br_unsigned_<mode>"
1412 [(set (pc)
1413 (if_then_else (match_operator 0 "s390_unsigned_integer_comparison"
1414 [(match_operand:GPR 1 "register_operand" "d,d")
1415 (match_operand:GPR 2 "nonmemory_operand" "d,I")])
1416 (pc)
1417 (label_ref (match_operand 3 "" ""))))
1418 (clobber (reg:CC CC_REGNUM))]
1419 "TARGET_Z10 && !TARGET_AVOID_CMP_AND_BRANCH"
1420 {
1421 if (get_attr_length (insn) == 6)
1422 return which_alternative ?
1423 "cl<g>ij%D0\t%1,%b2,%l3" : "cl<g>rj%D0\t%1,%2,%l3";
1424 else
1425 return which_alternative ?
1426 "cl<g>fi\t%1,%b2\;jg%D0\t%l3" : "cl<g>r\t%1,%2\;jg%D0\t%l3";
1427 }
1428 [(set_attr "op_type" "RIE")
1429 (set_attr "type" "branch")
1430 (set_attr "z10prop" "z10_super_c,z10_super")
1431 (set (attr "length")
1432 (if_then_else (lt (abs (minus (pc) (match_dup 3))) (const_int 60000))
1433 (const_int 6) (const_int 12)))]) ; 8 byte for clr/jg
1434 ; 10 byte for clgr/jg
1435
1436 ;;
1437 ;;- Move instructions.
1438 ;;
1439
1440 ;
1441 ; movti instruction pattern(s).
1442 ;
1443
1444 ; FIXME: More constants are possible by enabling jxx, jyy constraints
1445 ; for TImode (use double-int for the calculations)
1446 (define_insn "movti"
1447 [(set (match_operand:TI 0 "nonimmediate_operand" "=d,S,v, v, v,v,d,v,R, d,o")
1448 (match_operand:TI 1 "general_operand" " S,d,v,j00,jm1,d,v,R,v,dPT,d"))]
1449 "TARGET_ZARCH"
1450 "@
1451 lmg\t%0,%N0,%S1
1452 stmg\t%1,%N1,%S0
1453 vlr\t%v0,%v1
1454 vzero\t%v0
1455 vone\t%v0
1456 vlvgp\t%v0,%1,%N1
1457 #
1458 vl\t%v0,%1
1459 vst\t%v1,%0
1460 #
1461 #"
1462 [(set_attr "op_type" "RSY,RSY,VRR,VRI,VRI,VRR,*,VRX,VRX,*,*")
1463 (set_attr "type" "lm,stm,*,*,*,*,*,*,*,*,*")
1464 (set_attr "cpu_facility" "*,*,vec,vec,vec,vec,vec,vec,vec,*,*")])
1465
1466 (define_split
1467 [(set (match_operand:TI 0 "nonimmediate_operand" "")
1468 (match_operand:TI 1 "general_operand" ""))]
1469 "TARGET_ZARCH && reload_completed
1470 && s390_split_ok_p (operands[0], operands[1], TImode, 0)"
1471 [(set (match_dup 2) (match_dup 4))
1472 (set (match_dup 3) (match_dup 5))]
1473 {
1474 operands[2] = operand_subword (operands[0], 0, 0, TImode);
1475 operands[3] = operand_subword (operands[0], 1, 0, TImode);
1476 operands[4] = operand_subword (operands[1], 0, 0, TImode);
1477 operands[5] = operand_subword (operands[1], 1, 0, TImode);
1478 })
1479
1480 (define_split
1481 [(set (match_operand:TI 0 "nonimmediate_operand" "")
1482 (match_operand:TI 1 "general_operand" ""))]
1483 "TARGET_ZARCH && reload_completed
1484 && s390_split_ok_p (operands[0], operands[1], TImode, 1)"
1485 [(set (match_dup 2) (match_dup 4))
1486 (set (match_dup 3) (match_dup 5))]
1487 {
1488 operands[2] = operand_subword (operands[0], 1, 0, TImode);
1489 operands[3] = operand_subword (operands[0], 0, 0, TImode);
1490 operands[4] = operand_subword (operands[1], 1, 0, TImode);
1491 operands[5] = operand_subword (operands[1], 0, 0, TImode);
1492 })
1493
1494 ; Use part of the TImode target reg to perform the address
1495 ; calculation. If the TImode value is supposed to be copied into a VR
1496 ; this splitter is not necessary.
1497 (define_split
1498 [(set (match_operand:TI 0 "register_operand" "")
1499 (match_operand:TI 1 "memory_operand" ""))]
1500 "TARGET_ZARCH && reload_completed
1501 && !VECTOR_REG_P (operands[0])
1502 && !s_operand (operands[1], VOIDmode)"
1503 [(set (match_dup 0) (match_dup 1))]
1504 {
1505 rtx addr = operand_subword (operands[0], 1, 0, TImode);
1506 addr = gen_lowpart (Pmode, addr);
1507 s390_load_address (addr, XEXP (operands[1], 0));
1508 operands[1] = replace_equiv_address (operands[1], addr);
1509 })
1510
1511
1512 ; Split a VR -> GPR TImode move into 2 vector load GR from VR element.
1513 ; For the higher order bits we do simply a DImode move while the
1514 ; second part is done via vec extract. Both will end up as vlgvg.
1515 (define_split
1516 [(set (match_operand:TI 0 "register_operand" "")
1517 (match_operand:TI 1 "register_operand" ""))]
1518 "TARGET_VX && reload_completed
1519 && GENERAL_REG_P (operands[0])
1520 && VECTOR_REG_P (operands[1])"
1521 [(set (match_dup 2) (match_dup 4))
1522 (set (match_dup 3) (unspec:DI [(match_dup 5) (const_int 1)]
1523 UNSPEC_VEC_EXTRACT))]
1524 {
1525 operands[2] = operand_subword (operands[0], 0, 0, TImode);
1526 operands[3] = operand_subword (operands[0], 1, 0, TImode);
1527 operands[4] = gen_rtx_REG (DImode, REGNO (operands[1]));
1528 operands[5] = gen_rtx_REG (V2DImode, REGNO (operands[1]));
1529 })
1530
1531 ;
1532 ; Patterns used for secondary reloads
1533 ;
1534
1535 ; z10 provides move instructions accepting larl memory operands.
1536 ; Unfortunately there is no such variant for QI, TI and FP mode moves.
1537 ; These patterns are also used for unaligned SI and DI accesses.
1538
1539 (define_expand "reload<ALL:mode><P:mode>_tomem_z10"
1540 [(parallel [(match_operand:ALL 0 "memory_operand" "")
1541 (match_operand:ALL 1 "register_operand" "=d")
1542 (match_operand:P 2 "register_operand" "=&a")])]
1543 "TARGET_Z10"
1544 {
1545 s390_reload_symref_address (operands[1], operands[0], operands[2], 1);
1546 DONE;
1547 })
1548
1549 (define_expand "reload<ALL:mode><P:mode>_toreg_z10"
1550 [(parallel [(match_operand:ALL 0 "register_operand" "=d")
1551 (match_operand:ALL 1 "memory_operand" "")
1552 (match_operand:P 2 "register_operand" "=a")])]
1553 "TARGET_Z10"
1554 {
1555 s390_reload_symref_address (operands[0], operands[1], operands[2], 0);
1556 DONE;
1557 })
1558
1559 (define_expand "reload<P:mode>_larl_odd_addend_z10"
1560 [(parallel [(match_operand:P 0 "register_operand" "=d")
1561 (match_operand:P 1 "larl_operand" "")
1562 (match_operand:P 2 "register_operand" "=a")])]
1563 "TARGET_Z10"
1564 {
1565 s390_reload_larl_operand (operands[0], operands[1], operands[2]);
1566 DONE;
1567 })
1568
1569 ; Handles loading a PLUS (load address) expression
1570
1571 (define_expand "reload<mode>_plus"
1572 [(parallel [(match_operand:P 0 "register_operand" "=a")
1573 (match_operand:P 1 "s390_plus_operand" "")
1574 (match_operand:P 2 "register_operand" "=&a")])]
1575 ""
1576 {
1577 s390_expand_plus_operand (operands[0], operands[1], operands[2]);
1578 DONE;
1579 })
1580
1581 ; Not all the indirect memory access instructions support the full
1582 ; format (long disp + index + base). So whenever a move from/to such
1583 ; an address is required and the instruction cannot deal with it we do
1584 ; a load address into a scratch register first and use this as the new
1585 ; base register.
1586 ; This in particular is used for:
1587 ; - non-offsetable memory accesses for multiword moves
1588 ; - full vector reg moves with long displacements
1589
1590 (define_expand "reload<mode>_la_in"
1591 [(parallel [(match_operand 0 "register_operand" "")
1592 (match_operand 1 "" "")
1593 (match_operand:P 2 "register_operand" "=&a")])]
1594 ""
1595 {
1596 gcc_assert (MEM_P (operands[1]));
1597 s390_load_address (operands[2], find_replacement (&XEXP (operands[1], 0)));
1598 operands[1] = replace_equiv_address (operands[1], operands[2]);
1599 emit_move_insn (operands[0], operands[1]);
1600 DONE;
1601 })
1602
1603 (define_expand "reload<mode>_la_out"
1604 [(parallel [(match_operand 0 "" "")
1605 (match_operand 1 "register_operand" "")
1606 (match_operand:P 2 "register_operand" "=&a")])]
1607 ""
1608 {
1609 gcc_assert (MEM_P (operands[0]));
1610 s390_load_address (operands[2], find_replacement (&XEXP (operands[0], 0)));
1611 operands[0] = replace_equiv_address (operands[0], operands[2]);
1612 emit_move_insn (operands[0], operands[1]);
1613 DONE;
1614 })
1615
1616 (define_expand "reload<mode>_PIC_addr"
1617 [(parallel [(match_operand 0 "register_operand" "=d")
1618 (match_operand 1 "larl_operand" "")
1619 (match_operand:P 2 "register_operand" "=a")])]
1620 ""
1621 {
1622 rtx new_rtx = legitimize_pic_address (operands[1], operands[2]);
1623 emit_move_insn (operands[0], new_rtx);
1624 })
1625
1626 ;
1627 ; movdi instruction pattern(s).
1628 ;
1629
1630 (define_expand "movdi"
1631 [(set (match_operand:DI 0 "general_operand" "")
1632 (match_operand:DI 1 "general_operand" ""))]
1633 ""
1634 {
1635 /* Handle symbolic constants. */
1636 if (TARGET_64BIT
1637 && (SYMBOLIC_CONST (operands[1])
1638 || (GET_CODE (operands[1]) == PLUS
1639 && XEXP (operands[1], 0) == pic_offset_table_rtx
1640 && SYMBOLIC_CONST (XEXP (operands[1], 1)))))
1641 emit_symbolic_move (operands);
1642 })
1643
1644 (define_insn "*movdi_larl"
1645 [(set (match_operand:DI 0 "register_operand" "=d")
1646 (match_operand:DI 1 "larl_operand" "X"))]
1647 "TARGET_64BIT
1648 && !FP_REG_P (operands[0])"
1649 "larl\t%0,%1"
1650 [(set_attr "op_type" "RIL")
1651 (set_attr "type" "larl")
1652 (set_attr "z10prop" "z10_super_A1")])
1653
1654 (define_insn "*movdi_64"
1655 [(set (match_operand:DI 0 "nonimmediate_operand"
1656 "=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")
1657 (match_operand:DI 1 "general_operand"
1658 " 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"))]
1659 "TARGET_ZARCH"
1660 "@
1661 lghi\t%0,%h1
1662 llihh\t%0,%i1
1663 llihl\t%0,%i1
1664 llilh\t%0,%i1
1665 llill\t%0,%i1
1666 lgfi\t%0,%1
1667 llihf\t%0,%k1
1668 llilf\t%0,%k1
1669 ldgr\t%0,%1
1670 lgdr\t%0,%1
1671 lay\t%0,%a1
1672 lgrl\t%0,%1
1673 lgr\t%0,%1
1674 lg\t%0,%1
1675 stg\t%1,%0
1676 ldr\t%0,%1
1677 ld\t%0,%1
1678 ldy\t%0,%1
1679 std\t%1,%0
1680 stdy\t%1,%0
1681 stgrl\t%1,%0
1682 mvghi\t%0,%1
1683 #
1684 #
1685 stam\t%1,%N1,%S0
1686 lam\t%0,%N0,%S1
1687 vleig\t%v0,%h1,0
1688 vlr\t%v0,%v1
1689 vlvgg\t%v0,%1,0
1690 vlgvg\t%0,%v1,0
1691 vleg\t%v0,%1,0
1692 vsteg\t%v1,%0,0"
1693 [(set_attr "op_type" "RI,RI,RI,RI,RI,RIL,RIL,RIL,RRE,RRE,RXY,RIL,RRE,RXY,
1694 RXY,RR,RX,RXY,RX,RXY,RIL,SIL,*,*,RS,RS,VRI,VRR,VRS,VRS,VRX,VRX")
1695 (set_attr "type" "*,*,*,*,*,*,*,*,floaddf,floaddf,la,larl,lr,load,store,
1696 floaddf,floaddf,floaddf,fstoredf,fstoredf,larl,*,*,*,*,
1697 *,*,*,*,*,*,*")
1698 (set_attr "cpu_facility" "*,*,*,*,*,extimm,extimm,extimm,dfp,dfp,longdisp,
1699 z10,*,*,*,*,*,longdisp,*,longdisp,
1700 z10,z10,*,*,*,*,vec,vec,vec,vec,vec,vec")
1701 (set_attr "z10prop" "z10_fwd_A1,
1702 z10_fwd_E1,
1703 z10_fwd_E1,
1704 z10_fwd_E1,
1705 z10_fwd_E1,
1706 z10_fwd_A1,
1707 z10_fwd_E1,
1708 z10_fwd_E1,
1709 *,
1710 *,
1711 z10_fwd_A1,
1712 z10_fwd_A3,
1713 z10_fr_E1,
1714 z10_fwd_A3,
1715 z10_rec,
1716 *,
1717 *,
1718 *,
1719 *,
1720 *,
1721 z10_rec,
1722 z10_super,
1723 *,
1724 *,
1725 *,
1726 *,*,*,*,*,*,*")
1727 ])
1728
1729 (define_split
1730 [(set (match_operand:DI 0 "register_operand" "")
1731 (match_operand:DI 1 "register_operand" ""))]
1732 "TARGET_ZARCH && ACCESS_REG_P (operands[1])"
1733 [(set (match_dup 2) (match_dup 3))
1734 (set (match_dup 0) (ashift:DI (match_dup 0) (const_int 32)))
1735 (set (strict_low_part (match_dup 2)) (match_dup 4))]
1736 "operands[2] = gen_lowpart (SImode, operands[0]);
1737 s390_split_access_reg (operands[1], &operands[4], &operands[3]);")
1738
1739 (define_split
1740 [(set (match_operand:DI 0 "register_operand" "")
1741 (match_operand:DI 1 "register_operand" ""))]
1742 "TARGET_ZARCH && ACCESS_REG_P (operands[0])
1743 && dead_or_set_p (insn, operands[1])"
1744 [(set (match_dup 3) (match_dup 2))
1745 (set (match_dup 1) (lshiftrt:DI (match_dup 1) (const_int 32)))
1746 (set (match_dup 4) (match_dup 2))]
1747 "operands[2] = gen_lowpart (SImode, operands[1]);
1748 s390_split_access_reg (operands[0], &operands[3], &operands[4]);")
1749
1750 (define_split
1751 [(set (match_operand:DI 0 "register_operand" "")
1752 (match_operand:DI 1 "register_operand" ""))]
1753 "TARGET_ZARCH && ACCESS_REG_P (operands[0])
1754 && !dead_or_set_p (insn, operands[1])"
1755 [(set (match_dup 3) (match_dup 2))
1756 (set (match_dup 1) (rotate:DI (match_dup 1) (const_int 32)))
1757 (set (match_dup 4) (match_dup 2))
1758 (set (match_dup 1) (rotate:DI (match_dup 1) (const_int 32)))]
1759 "operands[2] = gen_lowpart (SImode, operands[1]);
1760 s390_split_access_reg (operands[0], &operands[3], &operands[4]);")
1761
1762 (define_insn "*movdi_31"
1763 [(set (match_operand:DI 0 "nonimmediate_operand"
1764 "=d,d,Q,S,d ,o,!*f,!*f,!*f,!R,!T,d")
1765 (match_operand:DI 1 "general_operand"
1766 " Q,S,d,d,dPT,d, *f, R, T,*f,*f,b"))]
1767 "!TARGET_ZARCH"
1768 "@
1769 lm\t%0,%N0,%S1
1770 lmy\t%0,%N0,%S1
1771 stm\t%1,%N1,%S0
1772 stmy\t%1,%N1,%S0
1773 #
1774 #
1775 ldr\t%0,%1
1776 ld\t%0,%1
1777 ldy\t%0,%1
1778 std\t%1,%0
1779 stdy\t%1,%0
1780 #"
1781 [(set_attr "op_type" "RS,RSY,RS,RSY,*,*,RR,RX,RXY,RX,RXY,*")
1782 (set_attr "type" "lm,lm,stm,stm,*,*,floaddf,floaddf,floaddf,fstoredf,fstoredf,*")
1783 (set_attr "cpu_facility" "*,longdisp,*,longdisp,*,*,*,*,longdisp,*,longdisp,z10")])
1784
1785 ; For a load from a symbol ref we can use one of the target registers
1786 ; together with larl to load the address.
1787 (define_split
1788 [(set (match_operand:DI 0 "register_operand" "")
1789 (match_operand:DI 1 "memory_operand" ""))]
1790 "!TARGET_ZARCH && reload_completed && TARGET_Z10
1791 && larl_operand (XEXP (operands[1], 0), SImode)"
1792 [(set (match_dup 2) (match_dup 3))
1793 (set (match_dup 0) (match_dup 1))]
1794 {
1795 operands[2] = operand_subword (operands[0], 1, 0, DImode);
1796 operands[3] = XEXP (operands[1], 0);
1797 operands[1] = replace_equiv_address (operands[1], operands[2]);
1798 })
1799
1800 (define_split
1801 [(set (match_operand:DI 0 "nonimmediate_operand" "")
1802 (match_operand:DI 1 "general_operand" ""))]
1803 "!TARGET_ZARCH && reload_completed
1804 && s390_split_ok_p (operands[0], operands[1], DImode, 0)"
1805 [(set (match_dup 2) (match_dup 4))
1806 (set (match_dup 3) (match_dup 5))]
1807 {
1808 operands[2] = operand_subword (operands[0], 0, 0, DImode);
1809 operands[3] = operand_subword (operands[0], 1, 0, DImode);
1810 operands[4] = operand_subword (operands[1], 0, 0, DImode);
1811 operands[5] = operand_subword (operands[1], 1, 0, DImode);
1812 })
1813
1814 (define_split
1815 [(set (match_operand:DI 0 "nonimmediate_operand" "")
1816 (match_operand:DI 1 "general_operand" ""))]
1817 "!TARGET_ZARCH && reload_completed
1818 && s390_split_ok_p (operands[0], operands[1], DImode, 1)"
1819 [(set (match_dup 2) (match_dup 4))
1820 (set (match_dup 3) (match_dup 5))]
1821 {
1822 operands[2] = operand_subword (operands[0], 1, 0, DImode);
1823 operands[3] = operand_subword (operands[0], 0, 0, DImode);
1824 operands[4] = operand_subword (operands[1], 1, 0, DImode);
1825 operands[5] = operand_subword (operands[1], 0, 0, DImode);
1826 })
1827
1828 (define_split
1829 [(set (match_operand:DI 0 "register_operand" "")
1830 (match_operand:DI 1 "memory_operand" ""))]
1831 "!TARGET_ZARCH && reload_completed
1832 && !FP_REG_P (operands[0])
1833 && !s_operand (operands[1], VOIDmode)"
1834 [(set (match_dup 0) (match_dup 1))]
1835 {
1836 rtx addr = operand_subword (operands[0], 1, 0, DImode);
1837 s390_load_address (addr, XEXP (operands[1], 0));
1838 operands[1] = replace_equiv_address (operands[1], addr);
1839 })
1840
1841 (define_peephole2
1842 [(set (match_operand:DI 0 "register_operand" "")
1843 (mem:DI (match_operand 1 "address_operand" "")))]
1844 "TARGET_ZARCH
1845 && !FP_REG_P (operands[0])
1846 && GET_CODE (operands[1]) == SYMBOL_REF
1847 && CONSTANT_POOL_ADDRESS_P (operands[1])
1848 && get_pool_mode (operands[1]) == DImode
1849 && legitimate_reload_constant_p (get_pool_constant (operands[1]))"
1850 [(set (match_dup 0) (match_dup 2))]
1851 "operands[2] = get_pool_constant (operands[1]);")
1852
1853 (define_insn "*la_64"
1854 [(set (match_operand:DI 0 "register_operand" "=d,d")
1855 (match_operand:QI 1 "address_operand" "ZR,ZT"))]
1856 "TARGET_64BIT"
1857 "@
1858 la\t%0,%a1
1859 lay\t%0,%a1"
1860 [(set_attr "op_type" "RX,RXY")
1861 (set_attr "type" "la")
1862 (set_attr "cpu_facility" "*,longdisp")
1863 (set_attr "z10prop" "z10_fwd_A1,z10_fwd_A1")])
1864
1865 (define_peephole2
1866 [(parallel
1867 [(set (match_operand:DI 0 "register_operand" "")
1868 (match_operand:QI 1 "address_operand" ""))
1869 (clobber (reg:CC CC_REGNUM))])]
1870 "TARGET_64BIT
1871 && preferred_la_operand_p (operands[1], const0_rtx)"
1872 [(set (match_dup 0) (match_dup 1))]
1873 "")
1874
1875 (define_peephole2
1876 [(set (match_operand:DI 0 "register_operand" "")
1877 (match_operand:DI 1 "register_operand" ""))
1878 (parallel
1879 [(set (match_dup 0)
1880 (plus:DI (match_dup 0)
1881 (match_operand:DI 2 "nonmemory_operand" "")))
1882 (clobber (reg:CC CC_REGNUM))])]
1883 "TARGET_64BIT
1884 && !reg_overlap_mentioned_p (operands[0], operands[2])
1885 && preferred_la_operand_p (operands[1], operands[2])"
1886 [(set (match_dup 0) (plus:DI (match_dup 1) (match_dup 2)))]
1887 "")
1888
1889 ;
1890 ; movsi instruction pattern(s).
1891 ;
1892
1893 (define_expand "movsi"
1894 [(set (match_operand:SI 0 "general_operand" "")
1895 (match_operand:SI 1 "general_operand" ""))]
1896 ""
1897 {
1898 /* Handle symbolic constants. */
1899 if (!TARGET_64BIT
1900 && (SYMBOLIC_CONST (operands[1])
1901 || (GET_CODE (operands[1]) == PLUS
1902 && XEXP (operands[1], 0) == pic_offset_table_rtx
1903 && SYMBOLIC_CONST (XEXP(operands[1], 1)))))
1904 emit_symbolic_move (operands);
1905 })
1906
1907 (define_insn "*movsi_larl"
1908 [(set (match_operand:SI 0 "register_operand" "=d")
1909 (match_operand:SI 1 "larl_operand" "X"))]
1910 "!TARGET_64BIT && TARGET_CPU_ZARCH
1911 && !FP_REG_P (operands[0])"
1912 "larl\t%0,%1"
1913 [(set_attr "op_type" "RIL")
1914 (set_attr "type" "larl")
1915 (set_attr "z10prop" "z10_fwd_A1")])
1916
1917 (define_insn "*movsi_zarch"
1918 [(set (match_operand:SI 0 "nonimmediate_operand"
1919 "=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")
1920 (match_operand:SI 1 "general_operand"
1921 " 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"))]
1922 "TARGET_ZARCH"
1923 "@
1924 lhi\t%0,%h1
1925 llilh\t%0,%i1
1926 llill\t%0,%i1
1927 iilf\t%0,%o1
1928 lay\t%0,%a1
1929 lrl\t%0,%1
1930 lr\t%0,%1
1931 l\t%0,%1
1932 ly\t%0,%1
1933 st\t%1,%0
1934 sty\t%1,%0
1935 ldr\t%0,%1
1936 ler\t%0,%1
1937 lde\t%0,%1
1938 le\t%0,%1
1939 ley\t%0,%1
1940 ste\t%1,%0
1941 stey\t%1,%0
1942 ear\t%0,%1
1943 sar\t%0,%1
1944 stam\t%1,%1,%S0
1945 strl\t%1,%0
1946 mvhi\t%0,%1
1947 lam\t%0,%0,%S1
1948 vleif\t%v0,%h1,0
1949 vlr\t%v0,%v1
1950 vlvgf\t%v0,%1,0
1951 vlgvf\t%0,%v1,0
1952 vlef\t%v0,%1,0
1953 vstef\t%v1,%0,0"
1954 [(set_attr "op_type" "RI,RI,RI,RIL,RXY,RIL,RR,RX,RXY,RX,RXY,
1955 RR,RR,RXE,RX,RXY,RX,RXY,RRE,RRE,RS,RIL,SIL,RS,VRI,VRR,VRS,VRS,VRX,VRX")
1956 (set_attr "type" "*,
1957 *,
1958 *,
1959 *,
1960 la,
1961 larl,
1962 lr,
1963 load,
1964 load,
1965 store,
1966 store,
1967 floadsf,
1968 floadsf,
1969 floadsf,
1970 floadsf,
1971 floadsf,
1972 fstoresf,
1973 fstoresf,
1974 *,
1975 *,
1976 *,
1977 larl,
1978 *,
1979 *,*,*,*,*,*,*")
1980 (set_attr "cpu_facility" "*,*,*,extimm,longdisp,z10,*,*,longdisp,*,longdisp,
1981 vec,*,vec,*,longdisp,*,longdisp,*,*,*,z10,z10,*,vec,vec,vec,vec,vec,vec")
1982 (set_attr "z10prop" "z10_fwd_A1,
1983 z10_fwd_E1,
1984 z10_fwd_E1,
1985 z10_fwd_A1,
1986 z10_fwd_A1,
1987 z10_fwd_A3,
1988 z10_fr_E1,
1989 z10_fwd_A3,
1990 z10_fwd_A3,
1991 z10_rec,
1992 z10_rec,
1993 *,
1994 *,
1995 *,
1996 *,
1997 *,
1998 *,
1999 *,
2000 z10_super_E1,
2001 z10_super,
2002 *,
2003 z10_rec,
2004 z10_super,
2005 *,*,*,*,*,*,*")])
2006
2007 (define_insn "*movsi_esa"
2008 [(set (match_operand:SI 0 "nonimmediate_operand" "=d,d,d,R,!*f,!*f,!*f,!*f,!R,d,t,Q,t")
2009 (match_operand:SI 1 "general_operand" "K,d,R,d, *f, *f, R, R,*f,t,d,t,Q"))]
2010 "!TARGET_ZARCH"
2011 "@
2012 lhi\t%0,%h1
2013 lr\t%0,%1
2014 l\t%0,%1
2015 st\t%1,%0
2016 ldr\t%0,%1
2017 ler\t%0,%1
2018 lde\t%0,%1
2019 le\t%0,%1
2020 ste\t%1,%0
2021 ear\t%0,%1
2022 sar\t%0,%1
2023 stam\t%1,%1,%S0
2024 lam\t%0,%0,%S1"
2025 [(set_attr "op_type" "RI,RR,RX,RX,RR,RR,RXE,RX,RX,RRE,RRE,RS,RS")
2026 (set_attr "type" "*,lr,load,store,floadsf,floadsf,floadsf,floadsf,fstoresf,*,*,*,*")
2027 (set_attr "z10prop" "z10_fwd_A1,z10_fr_E1,z10_fwd_A3,z10_rec,*,*,*,*,*,z10_super_E1,
2028 z10_super,*,*")
2029 (set_attr "cpu_facility" "*,*,*,*,vec,*,vec,*,*,*,*,*,*")
2030 ])
2031
2032 (define_peephole2
2033 [(set (match_operand:SI 0 "register_operand" "")
2034 (mem:SI (match_operand 1 "address_operand" "")))]
2035 "!FP_REG_P (operands[0])
2036 && GET_CODE (operands[1]) == SYMBOL_REF
2037 && CONSTANT_POOL_ADDRESS_P (operands[1])
2038 && get_pool_mode (operands[1]) == SImode
2039 && legitimate_reload_constant_p (get_pool_constant (operands[1]))"
2040 [(set (match_dup 0) (match_dup 2))]
2041 "operands[2] = get_pool_constant (operands[1]);")
2042
2043 (define_insn "*la_31"
2044 [(set (match_operand:SI 0 "register_operand" "=d,d")
2045 (match_operand:QI 1 "address_operand" "ZR,ZT"))]
2046 "!TARGET_64BIT && legitimate_la_operand_p (operands[1])"
2047 "@
2048 la\t%0,%a1
2049 lay\t%0,%a1"
2050 [(set_attr "op_type" "RX,RXY")
2051 (set_attr "type" "la")
2052 (set_attr "cpu_facility" "*,longdisp")
2053 (set_attr "z10prop" "z10_fwd_A1,z10_fwd_A1")])
2054
2055 (define_peephole2
2056 [(parallel
2057 [(set (match_operand:SI 0 "register_operand" "")
2058 (match_operand:QI 1 "address_operand" ""))
2059 (clobber (reg:CC CC_REGNUM))])]
2060 "!TARGET_64BIT
2061 && preferred_la_operand_p (operands[1], const0_rtx)"
2062 [(set (match_dup 0) (match_dup 1))]
2063 "")
2064
2065 (define_peephole2
2066 [(set (match_operand:SI 0 "register_operand" "")
2067 (match_operand:SI 1 "register_operand" ""))
2068 (parallel
2069 [(set (match_dup 0)
2070 (plus:SI (match_dup 0)
2071 (match_operand:SI 2 "nonmemory_operand" "")))
2072 (clobber (reg:CC CC_REGNUM))])]
2073 "!TARGET_64BIT
2074 && !reg_overlap_mentioned_p (operands[0], operands[2])
2075 && preferred_la_operand_p (operands[1], operands[2])"
2076 [(set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))]
2077 "")
2078
2079 (define_insn "*la_31_and"
2080 [(set (match_operand:SI 0 "register_operand" "=d,d")
2081 (and:SI (match_operand:QI 1 "address_operand" "ZR,ZT")
2082 (const_int 2147483647)))]
2083 "!TARGET_64BIT"
2084 "@
2085 la\t%0,%a1
2086 lay\t%0,%a1"
2087 [(set_attr "op_type" "RX,RXY")
2088 (set_attr "type" "la")
2089 (set_attr "cpu_facility" "*,longdisp")
2090 (set_attr "z10prop" "z10_fwd_A1,z10_fwd_A1")])
2091
2092 (define_insn_and_split "*la_31_and_cc"
2093 [(set (match_operand:SI 0 "register_operand" "=d")
2094 (and:SI (match_operand:QI 1 "address_operand" "p")
2095 (const_int 2147483647)))
2096 (clobber (reg:CC CC_REGNUM))]
2097 "!TARGET_64BIT"
2098 "#"
2099 "&& reload_completed"
2100 [(set (match_dup 0)
2101 (and:SI (match_dup 1) (const_int 2147483647)))]
2102 ""
2103 [(set_attr "op_type" "RX")
2104 (set_attr "type" "la")])
2105
2106 (define_insn "force_la_31"
2107 [(set (match_operand:SI 0 "register_operand" "=d,d")
2108 (match_operand:QI 1 "address_operand" "ZR,ZT"))
2109 (use (const_int 0))]
2110 "!TARGET_64BIT"
2111 "@
2112 la\t%0,%a1
2113 lay\t%0,%a1"
2114 [(set_attr "op_type" "RX")
2115 (set_attr "type" "la")
2116 (set_attr "cpu_facility" "*,longdisp")
2117 (set_attr "z10prop" "z10_fwd_A1,z10_fwd_A1")])
2118
2119 ;
2120 ; movhi instruction pattern(s).
2121 ;
2122
2123 (define_expand "movhi"
2124 [(set (match_operand:HI 0 "nonimmediate_operand" "")
2125 (match_operand:HI 1 "general_operand" ""))]
2126 ""
2127 {
2128 /* Make it explicit that loading a register from memory
2129 always sign-extends (at least) to SImode. */
2130 if (optimize && can_create_pseudo_p ()
2131 && register_operand (operands[0], VOIDmode)
2132 && GET_CODE (operands[1]) == MEM)
2133 {
2134 rtx tmp = gen_reg_rtx (SImode);
2135 rtx ext = gen_rtx_SIGN_EXTEND (SImode, operands[1]);
2136 emit_insn (gen_rtx_SET (tmp, ext));
2137 operands[1] = gen_lowpart (HImode, tmp);
2138 }
2139 })
2140
2141 (define_insn "*movhi"
2142 [(set (match_operand:HI 0 "nonimmediate_operand" "=d,d,d,d,d,R,T,b,Q,v,v,v,d,v,R")
2143 (match_operand:HI 1 "general_operand" " d,n,R,T,b,d,d,d,K,K,v,d,v,R,v"))]
2144 ""
2145 "@
2146 lr\t%0,%1
2147 lhi\t%0,%h1
2148 lh\t%0,%1
2149 lhy\t%0,%1
2150 lhrl\t%0,%1
2151 sth\t%1,%0
2152 sthy\t%1,%0
2153 sthrl\t%1,%0
2154 mvhhi\t%0,%1
2155 vleih\t%v0,%h1,0
2156 vlr\t%v0,%v1
2157 vlvgh\t%v0,%1,0
2158 vlgvh\t%0,%v1,0
2159 vleh\t%v0,%1,0
2160 vsteh\t%v1,%0,0"
2161 [(set_attr "op_type" "RR,RI,RX,RXY,RIL,RX,RXY,RIL,SIL,VRI,VRR,VRS,VRS,VRX,VRX")
2162 (set_attr "type" "lr,*,*,*,larl,store,store,store,*,*,*,*,*,*,*")
2163 (set_attr "cpu_facility" "*,*,*,longdisp,z10,*,longdisp,z10,z10,vec,vec,vec,vec,vec,vec")
2164 (set_attr "z10prop" "z10_fr_E1,
2165 z10_fwd_A1,
2166 z10_super_E1,
2167 z10_super_E1,
2168 z10_super_E1,
2169 z10_rec,
2170 z10_rec,
2171 z10_rec,
2172 z10_super,*,*,*,*,*,*")])
2173
2174 (define_peephole2
2175 [(set (match_operand:HI 0 "register_operand" "")
2176 (mem:HI (match_operand 1 "address_operand" "")))]
2177 "GET_CODE (operands[1]) == SYMBOL_REF
2178 && CONSTANT_POOL_ADDRESS_P (operands[1])
2179 && get_pool_mode (operands[1]) == HImode
2180 && GET_CODE (get_pool_constant (operands[1])) == CONST_INT"
2181 [(set (match_dup 0) (match_dup 2))]
2182 "operands[2] = get_pool_constant (operands[1]);")
2183
2184 ;
2185 ; movqi instruction pattern(s).
2186 ;
2187
2188 (define_expand "movqi"
2189 [(set (match_operand:QI 0 "nonimmediate_operand" "")
2190 (match_operand:QI 1 "general_operand" ""))]
2191 ""
2192 {
2193 /* On z/Architecture, zero-extending from memory to register
2194 is just as fast as a QImode load. */
2195 if (TARGET_ZARCH && optimize && can_create_pseudo_p ()
2196 && register_operand (operands[0], VOIDmode)
2197 && GET_CODE (operands[1]) == MEM)
2198 {
2199 rtx tmp = gen_reg_rtx (DImode);
2200 rtx ext = gen_rtx_ZERO_EXTEND (DImode, operands[1]);
2201 emit_insn (gen_rtx_SET (tmp, ext));
2202 operands[1] = gen_lowpart (QImode, tmp);
2203 }
2204 })
2205
2206 (define_insn "*movqi"
2207 [(set (match_operand:QI 0 "nonimmediate_operand" "=d,d,d,d,R,T,Q,S,?Q,v,v,v,d,v,R")
2208 (match_operand:QI 1 "general_operand" " d,n,R,T,d,d,n,n,?Q,K,v,d,v,R,v"))]
2209 ""
2210 "@
2211 lr\t%0,%1
2212 lhi\t%0,%b1
2213 ic\t%0,%1
2214 icy\t%0,%1
2215 stc\t%1,%0
2216 stcy\t%1,%0
2217 mvi\t%S0,%b1
2218 mviy\t%S0,%b1
2219 #
2220 vleib\t%v0,%b1,0
2221 vlr\t%v0,%v1
2222 vlvgb\t%v0,%1,0
2223 vlgvb\t%0,%v1,0
2224 vleb\t%v0,%1,0
2225 vsteb\t%v1,%0,0"
2226 [(set_attr "op_type" "RR,RI,RX,RXY,RX,RXY,SI,SIY,SS,VRI,VRR,VRS,VRS,VRX,VRX")
2227 (set_attr "type" "lr,*,*,*,store,store,store,store,*,*,*,*,*,*,*")
2228 (set_attr "cpu_facility" "*,*,*,longdisp,*,longdisp,*,longdisp,*,vec,vec,vec,vec,vec,vec")
2229 (set_attr "z10prop" "z10_fr_E1,
2230 z10_fwd_A1,
2231 z10_super_E1,
2232 z10_super_E1,
2233 z10_rec,
2234 z10_rec,
2235 z10_super,
2236 z10_super,
2237 *,*,*,*,*,*,*")])
2238
2239 (define_peephole2
2240 [(set (match_operand:QI 0 "nonimmediate_operand" "")
2241 (mem:QI (match_operand 1 "address_operand" "")))]
2242 "GET_CODE (operands[1]) == SYMBOL_REF
2243 && CONSTANT_POOL_ADDRESS_P (operands[1])
2244 && get_pool_mode (operands[1]) == QImode
2245 && GET_CODE (get_pool_constant (operands[1])) == CONST_INT"
2246 [(set (match_dup 0) (match_dup 2))]
2247 "operands[2] = get_pool_constant (operands[1]);")
2248
2249 ;
2250 ; movstrictqi instruction pattern(s).
2251 ;
2252
2253 (define_insn "*movstrictqi"
2254 [(set (strict_low_part (match_operand:QI 0 "register_operand" "+d,d"))
2255 (match_operand:QI 1 "memory_operand" "R,T"))]
2256 ""
2257 "@
2258 ic\t%0,%1
2259 icy\t%0,%1"
2260 [(set_attr "op_type" "RX,RXY")
2261 (set_attr "cpu_facility" "*,longdisp")
2262 (set_attr "z10prop" "z10_super_E1,z10_super_E1")])
2263
2264 ;
2265 ; movstricthi instruction pattern(s).
2266 ;
2267
2268 (define_insn "*movstricthi"
2269 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+d,d"))
2270 (match_operand:HI 1 "memory_operand" "Q,S"))
2271 (clobber (reg:CC CC_REGNUM))]
2272 ""
2273 "@
2274 icm\t%0,3,%S1
2275 icmy\t%0,3,%S1"
2276 [(set_attr "op_type" "RS,RSY")
2277 (set_attr "cpu_facility" "*,longdisp")
2278 (set_attr "z10prop" "z10_super_E1,z10_super_E1")])
2279
2280 ;
2281 ; movstrictsi instruction pattern(s).
2282 ;
2283
2284 (define_insn "movstrictsi"
2285 [(set (strict_low_part (match_operand:SI 0 "register_operand" "+d,d,d,d"))
2286 (match_operand:SI 1 "general_operand" "d,R,T,t"))]
2287 "TARGET_ZARCH"
2288 "@
2289 lr\t%0,%1
2290 l\t%0,%1
2291 ly\t%0,%1
2292 ear\t%0,%1"
2293 [(set_attr "op_type" "RR,RX,RXY,RRE")
2294 (set_attr "type" "lr,load,load,*")
2295 (set_attr "cpu_facility" "*,*,longdisp,*")
2296 (set_attr "z10prop" "z10_fr_E1,z10_fwd_A3,z10_fwd_A3,z10_super_E1")])
2297
2298 ;
2299 ; mov(tf|td) instruction pattern(s).
2300 ;
2301
2302 (define_expand "mov<mode>"
2303 [(set (match_operand:TD_TF 0 "nonimmediate_operand" "")
2304 (match_operand:TD_TF 1 "general_operand" ""))]
2305 ""
2306 "")
2307
2308 (define_insn "*mov<mode>_64"
2309 [(set (match_operand:TD_TF 0 "nonimmediate_operand" "=f,f,f,o,d,S, d,o")
2310 (match_operand:TD_TF 1 "general_operand" " G,f,o,f,S,d,dT,d"))]
2311 "TARGET_ZARCH"
2312 "@
2313 lzxr\t%0
2314 lxr\t%0,%1
2315 #
2316 #
2317 lmg\t%0,%N0,%S1
2318 stmg\t%1,%N1,%S0
2319 #
2320 #"
2321 [(set_attr "op_type" "RRE,RRE,*,*,RSY,RSY,*,*")
2322 (set_attr "type" "fsimptf,fsimptf,*,*,lm,stm,*,*")
2323 (set_attr "cpu_facility" "z196,*,*,*,*,*,*,*")])
2324
2325 (define_insn "*mov<mode>_31"
2326 [(set (match_operand:TD_TF 0 "nonimmediate_operand" "=f,f,f,o")
2327 (match_operand:TD_TF 1 "general_operand" " G,f,o,f"))]
2328 "!TARGET_ZARCH"
2329 "@
2330 lzxr\t%0
2331 lxr\t%0,%1
2332 #
2333 #"
2334 [(set_attr "op_type" "RRE,RRE,*,*")
2335 (set_attr "type" "fsimptf,fsimptf,*,*")
2336 (set_attr "cpu_facility" "z196,*,*,*")])
2337
2338 ; TFmode in GPRs splitters
2339
2340 (define_split
2341 [(set (match_operand:TD_TF 0 "nonimmediate_operand" "")
2342 (match_operand:TD_TF 1 "general_operand" ""))]
2343 "TARGET_ZARCH && reload_completed
2344 && s390_split_ok_p (operands[0], operands[1], <MODE>mode, 0)"
2345 [(set (match_dup 2) (match_dup 4))
2346 (set (match_dup 3) (match_dup 5))]
2347 {
2348 operands[2] = operand_subword (operands[0], 0, 0, <MODE>mode);
2349 operands[3] = operand_subword (operands[0], 1, 0, <MODE>mode);
2350 operands[4] = operand_subword (operands[1], 0, 0, <MODE>mode);
2351 operands[5] = operand_subword (operands[1], 1, 0, <MODE>mode);
2352 })
2353
2354 (define_split
2355 [(set (match_operand:TD_TF 0 "nonimmediate_operand" "")
2356 (match_operand:TD_TF 1 "general_operand" ""))]
2357 "TARGET_ZARCH && reload_completed
2358 && s390_split_ok_p (operands[0], operands[1], <MODE>mode, 1)"
2359 [(set (match_dup 2) (match_dup 4))
2360 (set (match_dup 3) (match_dup 5))]
2361 {
2362 operands[2] = operand_subword (operands[0], 1, 0, <MODE>mode);
2363 operands[3] = operand_subword (operands[0], 0, 0, <MODE>mode);
2364 operands[4] = operand_subword (operands[1], 1, 0, <MODE>mode);
2365 operands[5] = operand_subword (operands[1], 0, 0, <MODE>mode);
2366 })
2367
2368 (define_split
2369 [(set (match_operand:TD_TF 0 "register_operand" "")
2370 (match_operand:TD_TF 1 "memory_operand" ""))]
2371 "TARGET_ZARCH && reload_completed
2372 && GENERAL_REG_P (operands[0])
2373 && !s_operand (operands[1], VOIDmode)"
2374 [(set (match_dup 0) (match_dup 1))]
2375 {
2376 rtx addr = operand_subword (operands[0], 1, 0, <MODE>mode);
2377 addr = gen_lowpart (Pmode, addr);
2378 s390_load_address (addr, XEXP (operands[1], 0));
2379 operands[1] = replace_equiv_address (operands[1], addr);
2380 })
2381
2382 ; TFmode in BFPs splitters
2383
2384 (define_split
2385 [(set (match_operand:TD_TF 0 "register_operand" "")
2386 (match_operand:TD_TF 1 "memory_operand" ""))]
2387 "reload_completed && offsettable_memref_p (operands[1])
2388 && FP_REG_P (operands[0])"
2389 [(set (match_dup 2) (match_dup 4))
2390 (set (match_dup 3) (match_dup 5))]
2391 {
2392 operands[2] = simplify_gen_subreg (<HALF_TMODE>mode, operands[0],
2393 <MODE>mode, 0);
2394 operands[3] = simplify_gen_subreg (<HALF_TMODE>mode, operands[0],
2395 <MODE>mode, 8);
2396 operands[4] = adjust_address_nv (operands[1], <HALF_TMODE>mode, 0);
2397 operands[5] = adjust_address_nv (operands[1], <HALF_TMODE>mode, 8);
2398 })
2399
2400 (define_split
2401 [(set (match_operand:TD_TF 0 "memory_operand" "")
2402 (match_operand:TD_TF 1 "register_operand" ""))]
2403 "reload_completed && offsettable_memref_p (operands[0])
2404 && FP_REG_P (operands[1])"
2405 [(set (match_dup 2) (match_dup 4))
2406 (set (match_dup 3) (match_dup 5))]
2407 {
2408 operands[2] = adjust_address_nv (operands[0], <HALF_TMODE>mode, 0);
2409 operands[3] = adjust_address_nv (operands[0], <HALF_TMODE>mode, 8);
2410 operands[4] = simplify_gen_subreg (<HALF_TMODE>mode, operands[1],
2411 <MODE>mode, 0);
2412 operands[5] = simplify_gen_subreg (<HALF_TMODE>mode, operands[1],
2413 <MODE>mode, 8);
2414 })
2415
2416 ;
2417 ; mov(df|dd) instruction pattern(s).
2418 ;
2419
2420 (define_expand "mov<mode>"
2421 [(set (match_operand:DD_DF 0 "nonimmediate_operand" "")
2422 (match_operand:DD_DF 1 "general_operand" ""))]
2423 ""
2424 "")
2425
2426 (define_insn "*mov<mode>_64dfp"
2427 [(set (match_operand:DD_DF 0 "nonimmediate_operand"
2428 "=f,f,f,d,f,f,R,T,d,d,d,d,b,T,v,v,d,v,R")
2429 (match_operand:DD_DF 1 "general_operand"
2430 " G,f,d,f,R,T,f,f,G,d,b,T,d,d,v,d,v,R,v"))]
2431 "TARGET_DFP"
2432 "@
2433 lzdr\t%0
2434 ldr\t%0,%1
2435 ldgr\t%0,%1
2436 lgdr\t%0,%1
2437 ld\t%0,%1
2438 ldy\t%0,%1
2439 std\t%1,%0
2440 stdy\t%1,%0
2441 lghi\t%0,0
2442 lgr\t%0,%1
2443 lgrl\t%0,%1
2444 lg\t%0,%1
2445 stgrl\t%1,%0
2446 stg\t%1,%0
2447 vlr\t%v0,%v1
2448 vlvgg\t%v0,%1,0
2449 vlgvg\t%0,%v1,0
2450 vleg\t%0,%1,0
2451 vsteg\t%1,%0,0"
2452 [(set_attr "op_type" "RRE,RR,RRE,RRE,RX,RXY,RX,RXY,RI,RRE,RIL,RXY,RIL,RXY,VRR,VRS,VRS,VRX,VRX")
2453 (set_attr "type" "fsimpdf,floaddf,floaddf,floaddf,floaddf,floaddf,
2454 fstoredf,fstoredf,*,lr,load,load,store,store,*,*,*,load,store")
2455 (set_attr "z10prop" "*,*,*,*,*,*,*,*,z10_fwd_A1,z10_fr_E1,z10_fwd_A3,z10_fwd_A3,z10_rec,z10_rec,*,*,*,*,*")
2456 (set_attr "cpu_facility" "z196,*,*,*,*,longdisp,*,longdisp,*,*,z10,*,z10,*,vec,vec,vec,vec,vec")])
2457
2458 (define_insn "*mov<mode>_64"
2459 [(set (match_operand:DD_DF 0 "nonimmediate_operand" "=f,f,f,f,R,T,d,d,d,d,b,T,v,v,R")
2460 (match_operand:DD_DF 1 "general_operand" " G,f,R,T,f,f,G,d,b,T,d,d,v,R,v"))]
2461 "TARGET_ZARCH"
2462 "@
2463 lzdr\t%0
2464 ldr\t%0,%1
2465 ld\t%0,%1
2466 ldy\t%0,%1
2467 std\t%1,%0
2468 stdy\t%1,%0
2469 lghi\t%0,0
2470 lgr\t%0,%1
2471 lgrl\t%0,%1
2472 lg\t%0,%1
2473 stgrl\t%1,%0
2474 stg\t%1,%0
2475 vlr\t%v0,%v1
2476 vleg\t%v0,%1,0
2477 vsteg\t%v1,%0,0"
2478 [(set_attr "op_type" "RRE,RR,RX,RXY,RX,RXY,RI,RRE,RIL,RXY,RIL,RXY,VRR,VRX,VRX")
2479 (set_attr "type" "fsimpdf,fload<mode>,fload<mode>,fload<mode>,
2480 fstore<mode>,fstore<mode>,*,lr,load,load,store,store,*,load,store")
2481 (set_attr "z10prop" "*,*,*,*,*,*,z10_fwd_A1,z10_fr_E1,z10_fwd_A3,z10_fwd_A3,z10_rec,z10_rec,*,*,*")
2482 (set_attr "cpu_facility" "z196,*,*,longdisp,*,longdisp,*,*,z10,*,z10,*,vec,vec,vec")])
2483
2484 (define_insn "*mov<mode>_31"
2485 [(set (match_operand:DD_DF 0 "nonimmediate_operand"
2486 "=f,f,f,f,R,T,d,d,Q,S, d,o")
2487 (match_operand:DD_DF 1 "general_operand"
2488 " G,f,R,T,f,f,Q,S,d,d,dPT,d"))]
2489 "!TARGET_ZARCH"
2490 "@
2491 lzdr\t%0
2492 ldr\t%0,%1
2493 ld\t%0,%1
2494 ldy\t%0,%1
2495 std\t%1,%0
2496 stdy\t%1,%0
2497 lm\t%0,%N0,%S1
2498 lmy\t%0,%N0,%S1
2499 stm\t%1,%N1,%S0
2500 stmy\t%1,%N1,%S0
2501 #
2502 #"
2503 [(set_attr "op_type" "RRE,RR,RX,RXY,RX,RXY,RS,RSY,RS,RSY,*,*")
2504 (set_attr "type" "fsimpdf,fload<mode>,fload<mode>,fload<mode>,
2505 fstore<mode>,fstore<mode>,lm,lm,stm,stm,*,*")
2506 (set_attr "cpu_facility" "z196,*,*,longdisp,*,longdisp,*,longdisp,*,longdisp,*,*")])
2507
2508 (define_split
2509 [(set (match_operand:DD_DF 0 "nonimmediate_operand" "")
2510 (match_operand:DD_DF 1 "general_operand" ""))]
2511 "!TARGET_ZARCH && reload_completed
2512 && s390_split_ok_p (operands[0], operands[1], <MODE>mode, 0)"
2513 [(set (match_dup 2) (match_dup 4))
2514 (set (match_dup 3) (match_dup 5))]
2515 {
2516 operands[2] = operand_subword (operands[0], 0, 0, <MODE>mode);
2517 operands[3] = operand_subword (operands[0], 1, 0, <MODE>mode);
2518 operands[4] = operand_subword (operands[1], 0, 0, <MODE>mode);
2519 operands[5] = operand_subword (operands[1], 1, 0, <MODE>mode);
2520 })
2521
2522 (define_split
2523 [(set (match_operand:DD_DF 0 "nonimmediate_operand" "")
2524 (match_operand:DD_DF 1 "general_operand" ""))]
2525 "!TARGET_ZARCH && reload_completed
2526 && s390_split_ok_p (operands[0], operands[1], <MODE>mode, 1)"
2527 [(set (match_dup 2) (match_dup 4))
2528 (set (match_dup 3) (match_dup 5))]
2529 {
2530 operands[2] = operand_subword (operands[0], 1, 0, <MODE>mode);
2531 operands[3] = operand_subword (operands[0], 0, 0, <MODE>mode);
2532 operands[4] = operand_subword (operands[1], 1, 0, <MODE>mode);
2533 operands[5] = operand_subword (operands[1], 0, 0, <MODE>mode);
2534 })
2535
2536 (define_split
2537 [(set (match_operand:DD_DF 0 "register_operand" "")
2538 (match_operand:DD_DF 1 "memory_operand" ""))]
2539 "!TARGET_ZARCH && reload_completed
2540 && !FP_REG_P (operands[0])
2541 && !s_operand (operands[1], VOIDmode)"
2542 [(set (match_dup 0) (match_dup 1))]
2543 {
2544 rtx addr = operand_subword (operands[0], 1, 0, <MODE>mode);
2545 s390_load_address (addr, XEXP (operands[1], 0));
2546 operands[1] = replace_equiv_address (operands[1], addr);
2547 })
2548
2549 ;
2550 ; mov(sf|sd) instruction pattern(s).
2551 ;
2552
2553 (define_insn "mov<mode>"
2554 [(set (match_operand:SD_SF 0 "nonimmediate_operand"
2555 "=f,f,f,f,f,f,R,T,d,d,d,d,d,b,R,T,v,v,v,d,v,R")
2556 (match_operand:SD_SF 1 "general_operand"
2557 " G,f,f,R,R,T,f,f,G,d,b,R,T,d,d,d,v,G,d,v,R,v"))]
2558 ""
2559 "@
2560 lzer\t%0
2561 ldr\t%0,%1
2562 ler\t%0,%1
2563 lde\t%0,%1
2564 le\t%0,%1
2565 ley\t%0,%1
2566 ste\t%1,%0
2567 stey\t%1,%0
2568 lhi\t%0,0
2569 lr\t%0,%1
2570 lrl\t%0,%1
2571 l\t%0,%1
2572 ly\t%0,%1
2573 strl\t%1,%0
2574 st\t%1,%0
2575 sty\t%1,%0
2576 vlr\t%v0,%v1
2577 vleif\t%v0,0
2578 vlvgf\t%v0,%1,0
2579 vlgvf\t%0,%v1,0
2580 vleg\t%0,%1,0
2581 vsteg\t%1,%0,0"
2582 [(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")
2583 (set_attr "type" "fsimpsf,fsimpsf,fload<mode>,fload<mode>,fload<mode>,fload<mode>,
2584 fstore<mode>,fstore<mode>,*,lr,load,load,load,store,store,store,*,*,*,*,load,store")
2585 (set_attr "z10prop" "*,*,*,*,*,*,*,*,z10_fwd_A1,z10_fr_E1,z10_fr_E1,z10_fwd_A3,z10_fwd_A3,z10_rec,z10_rec,z10_rec,*,*,*,*,*,*")
2586 (set_attr "cpu_facility" "z196,vec,*,vec,*,longdisp,*,longdisp,*,*,z10,*,longdisp,z10,*,longdisp,vec,vec,vec,vec,vec,vec")])
2587
2588 ;
2589 ; movcc instruction pattern
2590 ;
2591
2592 (define_insn "movcc"
2593 [(set (match_operand:CC 0 "nonimmediate_operand" "=d,c,d,d,d,R,T")
2594 (match_operand:CC 1 "nonimmediate_operand" " d,d,c,R,T,d,d"))]
2595 ""
2596 "@
2597 lr\t%0,%1
2598 tmh\t%1,12288
2599 ipm\t%0
2600 l\t%0,%1
2601 ly\t%0,%1
2602 st\t%1,%0
2603 sty\t%1,%0"
2604 [(set_attr "op_type" "RR,RI,RRE,RX,RXY,RX,RXY")
2605 (set_attr "type" "lr,*,*,load,load,store,store")
2606 (set_attr "cpu_facility" "*,*,*,*,longdisp,*,longdisp")
2607 (set_attr "z10prop" "z10_fr_E1,z10_super,*,z10_fwd_A3,z10_fwd_A3,z10_rec,z10_rec")
2608 (set_attr "z196prop" "*,*,z196_ends,*,*,*,*")])
2609
2610 ;
2611 ; Block move (MVC) patterns.
2612 ;
2613
2614 (define_insn "*mvc"
2615 [(set (match_operand:BLK 0 "memory_operand" "=Q")
2616 (match_operand:BLK 1 "memory_operand" "Q"))
2617 (use (match_operand 2 "const_int_operand" "n"))]
2618 "INTVAL (operands[2]) >= 1 && INTVAL (operands[2]) <= 256"
2619 "mvc\t%O0(%2,%R0),%S1"
2620 [(set_attr "op_type" "SS")])
2621
2622 ; This splitter converts a QI to QI mode copy into a BLK mode copy in
2623 ; order to have it implemented with mvc.
2624
2625 (define_split
2626 [(set (match_operand:QI 0 "memory_operand" "")
2627 (match_operand:QI 1 "memory_operand" ""))]
2628 "reload_completed"
2629 [(parallel
2630 [(set (match_dup 0) (match_dup 1))
2631 (use (const_int 1))])]
2632 {
2633 operands[0] = adjust_address (operands[0], BLKmode, 0);
2634 operands[1] = adjust_address (operands[1], BLKmode, 0);
2635 })
2636
2637
2638 (define_peephole2
2639 [(parallel
2640 [(set (match_operand:BLK 0 "memory_operand" "")
2641 (match_operand:BLK 1 "memory_operand" ""))
2642 (use (match_operand 2 "const_int_operand" ""))])
2643 (parallel
2644 [(set (match_operand:BLK 3 "memory_operand" "")
2645 (match_operand:BLK 4 "memory_operand" ""))
2646 (use (match_operand 5 "const_int_operand" ""))])]
2647 "s390_offset_p (operands[0], operands[3], operands[2])
2648 && s390_offset_p (operands[1], operands[4], operands[2])
2649 && !s390_overlap_p (operands[0], operands[1],
2650 INTVAL (operands[2]) + INTVAL (operands[5]))
2651 && INTVAL (operands[2]) + INTVAL (operands[5]) <= 256"
2652 [(parallel
2653 [(set (match_dup 6) (match_dup 7))
2654 (use (match_dup 8))])]
2655 "operands[6] = gen_rtx_MEM (BLKmode, XEXP (operands[0], 0));
2656 operands[7] = gen_rtx_MEM (BLKmode, XEXP (operands[1], 0));
2657 operands[8] = GEN_INT (INTVAL (operands[2]) + INTVAL (operands[5]));")
2658
2659
2660 ;
2661 ; load_multiple pattern(s).
2662 ;
2663 ; ??? Due to reload problems with replacing registers inside match_parallel
2664 ; we currently support load_multiple/store_multiple only after reload.
2665 ;
2666
2667 (define_expand "load_multiple"
2668 [(match_par_dup 3 [(set (match_operand 0 "" "")
2669 (match_operand 1 "" ""))
2670 (use (match_operand 2 "" ""))])]
2671 "reload_completed"
2672 {
2673 machine_mode mode;
2674 int regno;
2675 int count;
2676 rtx from;
2677 int i, off;
2678
2679 /* Support only loading a constant number of fixed-point registers from
2680 memory and only bother with this if more than two */
2681 if (GET_CODE (operands[2]) != CONST_INT
2682 || INTVAL (operands[2]) < 2
2683 || INTVAL (operands[2]) > 16
2684 || GET_CODE (operands[1]) != MEM
2685 || GET_CODE (operands[0]) != REG
2686 || REGNO (operands[0]) >= 16)
2687 FAIL;
2688
2689 count = INTVAL (operands[2]);
2690 regno = REGNO (operands[0]);
2691 mode = GET_MODE (operands[0]);
2692 if (mode != SImode && (!TARGET_ZARCH || mode != DImode))
2693 FAIL;
2694
2695 operands[3] = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (count));
2696 if (!can_create_pseudo_p ())
2697 {
2698 if (GET_CODE (XEXP (operands[1], 0)) == REG)
2699 {
2700 from = XEXP (operands[1], 0);
2701 off = 0;
2702 }
2703 else if (GET_CODE (XEXP (operands[1], 0)) == PLUS
2704 && GET_CODE (XEXP (XEXP (operands[1], 0), 0)) == REG
2705 && GET_CODE (XEXP (XEXP (operands[1], 0), 1)) == CONST_INT)
2706 {
2707 from = XEXP (XEXP (operands[1], 0), 0);
2708 off = INTVAL (XEXP (XEXP (operands[1], 0), 1));
2709 }
2710 else
2711 FAIL;
2712 }
2713 else
2714 {
2715 from = force_reg (Pmode, XEXP (operands[1], 0));
2716 off = 0;
2717 }
2718
2719 for (i = 0; i < count; i++)
2720 XVECEXP (operands[3], 0, i)
2721 = gen_rtx_SET (gen_rtx_REG (mode, regno + i),
2722 change_address (operands[1], mode,
2723 plus_constant (Pmode, from,
2724 off + i * GET_MODE_SIZE (mode))));
2725 })
2726
2727 (define_insn "*load_multiple_di"
2728 [(match_parallel 0 "load_multiple_operation"
2729 [(set (match_operand:DI 1 "register_operand" "=r")
2730 (match_operand:DI 2 "s_operand" "S"))])]
2731 "reload_completed && TARGET_ZARCH"
2732 {
2733 int words = XVECLEN (operands[0], 0);
2734 operands[0] = gen_rtx_REG (DImode, REGNO (operands[1]) + words - 1);
2735 return "lmg\t%1,%0,%S2";
2736 }
2737 [(set_attr "op_type" "RSY")
2738 (set_attr "type" "lm")])
2739
2740 (define_insn "*load_multiple_si"
2741 [(match_parallel 0 "load_multiple_operation"
2742 [(set (match_operand:SI 1 "register_operand" "=r,r")
2743 (match_operand:SI 2 "s_operand" "Q,S"))])]
2744 "reload_completed"
2745 {
2746 int words = XVECLEN (operands[0], 0);
2747 operands[0] = gen_rtx_REG (SImode, REGNO (operands[1]) + words - 1);
2748 return which_alternative == 0 ? "lm\t%1,%0,%S2" : "lmy\t%1,%0,%S2";
2749 }
2750 [(set_attr "op_type" "RS,RSY")
2751 (set_attr "cpu_facility" "*,longdisp")
2752 (set_attr "type" "lm")])
2753
2754 ;
2755 ; store multiple pattern(s).
2756 ;
2757
2758 (define_expand "store_multiple"
2759 [(match_par_dup 3 [(set (match_operand 0 "" "")
2760 (match_operand 1 "" ""))
2761 (use (match_operand 2 "" ""))])]
2762 "reload_completed"
2763 {
2764 machine_mode mode;
2765 int regno;
2766 int count;
2767 rtx to;
2768 int i, off;
2769
2770 /* Support only storing a constant number of fixed-point registers to
2771 memory and only bother with this if more than two. */
2772 if (GET_CODE (operands[2]) != CONST_INT
2773 || INTVAL (operands[2]) < 2
2774 || INTVAL (operands[2]) > 16
2775 || GET_CODE (operands[0]) != MEM
2776 || GET_CODE (operands[1]) != REG
2777 || REGNO (operands[1]) >= 16)
2778 FAIL;
2779
2780 count = INTVAL (operands[2]);
2781 regno = REGNO (operands[1]);
2782 mode = GET_MODE (operands[1]);
2783 if (mode != SImode && (!TARGET_ZARCH || mode != DImode))
2784 FAIL;
2785
2786 operands[3] = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (count));
2787
2788 if (!can_create_pseudo_p ())
2789 {
2790 if (GET_CODE (XEXP (operands[0], 0)) == REG)
2791 {
2792 to = XEXP (operands[0], 0);
2793 off = 0;
2794 }
2795 else if (GET_CODE (XEXP (operands[0], 0)) == PLUS
2796 && GET_CODE (XEXP (XEXP (operands[0], 0), 0)) == REG
2797 && GET_CODE (XEXP (XEXP (operands[0], 0), 1)) == CONST_INT)
2798 {
2799 to = XEXP (XEXP (operands[0], 0), 0);
2800 off = INTVAL (XEXP (XEXP (operands[0], 0), 1));
2801 }
2802 else
2803 FAIL;
2804 }
2805 else
2806 {
2807 to = force_reg (Pmode, XEXP (operands[0], 0));
2808 off = 0;
2809 }
2810
2811 for (i = 0; i < count; i++)
2812 XVECEXP (operands[3], 0, i)
2813 = gen_rtx_SET (change_address (operands[0], mode,
2814 plus_constant (Pmode, to,
2815 off + i * GET_MODE_SIZE (mode))),
2816 gen_rtx_REG (mode, regno + i));
2817 })
2818
2819 (define_insn "*store_multiple_di"
2820 [(match_parallel 0 "store_multiple_operation"
2821 [(set (match_operand:DI 1 "s_operand" "=S")
2822 (match_operand:DI 2 "register_operand" "r"))])]
2823 "reload_completed && TARGET_ZARCH"
2824 {
2825 int words = XVECLEN (operands[0], 0);
2826 operands[0] = gen_rtx_REG (DImode, REGNO (operands[2]) + words - 1);
2827 return "stmg\t%2,%0,%S1";
2828 }
2829 [(set_attr "op_type" "RSY")
2830 (set_attr "type" "stm")])
2831
2832
2833 (define_insn "*store_multiple_si"
2834 [(match_parallel 0 "store_multiple_operation"
2835 [(set (match_operand:SI 1 "s_operand" "=Q,S")
2836 (match_operand:SI 2 "register_operand" "r,r"))])]
2837 "reload_completed"
2838 {
2839 int words = XVECLEN (operands[0], 0);
2840 operands[0] = gen_rtx_REG (SImode, REGNO (operands[2]) + words - 1);
2841 return which_alternative == 0 ? "stm\t%2,%0,%S1" : "stmy\t%2,%0,%S1";
2842 }
2843 [(set_attr "op_type" "RS,RSY")
2844 (set_attr "cpu_facility" "*,longdisp")
2845 (set_attr "type" "stm")])
2846
2847 ;;
2848 ;; String instructions.
2849 ;;
2850
2851 (define_insn "*execute_rl"
2852 [(match_parallel 0 "execute_operation"
2853 [(unspec [(match_operand 1 "register_operand" "a")
2854 (match_operand 2 "" "")
2855 (match_operand:SI 3 "larl_operand" "X")] UNSPEC_EXECUTE)])]
2856 "TARGET_Z10 && GET_MODE_CLASS (GET_MODE (operands[1])) == MODE_INT
2857 && GET_MODE_SIZE (GET_MODE (operands[1])) <= UNITS_PER_WORD"
2858 "exrl\t%1,%3"
2859 [(set_attr "op_type" "RIL")
2860 (set_attr "type" "cs")])
2861
2862 (define_insn "*execute"
2863 [(match_parallel 0 "execute_operation"
2864 [(unspec [(match_operand 1 "register_operand" "a")
2865 (match_operand:BLK 2 "memory_operand" "R")
2866 (match_operand 3 "" "")] UNSPEC_EXECUTE)])]
2867 "GET_MODE_CLASS (GET_MODE (operands[1])) == MODE_INT
2868 && GET_MODE_SIZE (GET_MODE (operands[1])) <= UNITS_PER_WORD"
2869 "ex\t%1,%2"
2870 [(set_attr "op_type" "RX")
2871 (set_attr "type" "cs")])
2872
2873
2874 ;
2875 ; strlenM instruction pattern(s).
2876 ;
2877
2878 (define_expand "strlen<mode>"
2879 [(match_operand:P 0 "register_operand" "") ; result
2880 (match_operand:BLK 1 "memory_operand" "") ; input string
2881 (match_operand:SI 2 "immediate_operand" "") ; search character
2882 (match_operand:SI 3 "immediate_operand" "")] ; known alignment
2883 ""
2884 {
2885 if (!TARGET_VX || operands[2] != const0_rtx)
2886 emit_insn (gen_strlen_srst<mode> (operands[0], operands[1],
2887 operands[2], operands[3]));
2888 else
2889 s390_expand_vec_strlen (operands[0], operands[1], operands[3]);
2890
2891 DONE;
2892 })
2893
2894 (define_expand "strlen_srst<mode>"
2895 [(set (reg:SI 0) (match_operand:SI 2 "immediate_operand" ""))
2896 (parallel
2897 [(set (match_dup 4)
2898 (unspec:P [(const_int 0)
2899 (match_operand:BLK 1 "memory_operand" "")
2900 (reg:SI 0)
2901 (match_operand 3 "immediate_operand" "")] UNSPEC_SRST))
2902 (clobber (scratch:P))
2903 (clobber (reg:CC CC_REGNUM))])
2904 (parallel
2905 [(set (match_operand:P 0 "register_operand" "")
2906 (minus:P (match_dup 4) (match_dup 5)))
2907 (clobber (reg:CC CC_REGNUM))])]
2908 ""
2909 {
2910 operands[4] = gen_reg_rtx (Pmode);
2911 operands[5] = gen_reg_rtx (Pmode);
2912 emit_move_insn (operands[5], force_operand (XEXP (operands[1], 0), NULL_RTX));
2913 operands[1] = replace_equiv_address (operands[1], operands[5]);
2914 })
2915
2916 (define_insn "*strlen<mode>"
2917 [(set (match_operand:P 0 "register_operand" "=a")
2918 (unspec:P [(match_operand:P 2 "general_operand" "0")
2919 (mem:BLK (match_operand:P 3 "register_operand" "1"))
2920 (reg:SI 0)
2921 (match_operand 4 "immediate_operand" "")] UNSPEC_SRST))
2922 (clobber (match_scratch:P 1 "=a"))
2923 (clobber (reg:CC CC_REGNUM))]
2924 ""
2925 "srst\t%0,%1\;jo\t.-4"
2926 [(set_attr "length" "8")
2927 (set_attr "type" "vs")])
2928
2929 ;
2930 ; cmpstrM instruction pattern(s).
2931 ;
2932
2933 (define_expand "cmpstrsi"
2934 [(set (reg:SI 0) (const_int 0))
2935 (parallel
2936 [(clobber (match_operand 3 "" ""))
2937 (clobber (match_dup 4))
2938 (set (reg:CCU CC_REGNUM)
2939 (compare:CCU (match_operand:BLK 1 "memory_operand" "")
2940 (match_operand:BLK 2 "memory_operand" "")))
2941 (use (reg:SI 0))])
2942 (parallel
2943 [(set (match_operand:SI 0 "register_operand" "=d")
2944 (unspec:SI [(reg:CCU CC_REGNUM)] UNSPEC_STRCMPCC_TO_INT))
2945 (clobber (reg:CC CC_REGNUM))])]
2946 ""
2947 {
2948 /* As the result of CMPINT is inverted compared to what we need,
2949 we have to swap the operands. */
2950 rtx op1 = operands[2];
2951 rtx op2 = operands[1];
2952 rtx addr1 = gen_reg_rtx (Pmode);
2953 rtx addr2 = gen_reg_rtx (Pmode);
2954
2955 emit_move_insn (addr1, force_operand (XEXP (op1, 0), NULL_RTX));
2956 emit_move_insn (addr2, force_operand (XEXP (op2, 0), NULL_RTX));
2957 operands[1] = replace_equiv_address_nv (op1, addr1);
2958 operands[2] = replace_equiv_address_nv (op2, addr2);
2959 operands[3] = addr1;
2960 operands[4] = addr2;
2961 })
2962
2963 (define_insn "*cmpstr<mode>"
2964 [(clobber (match_operand:P 0 "register_operand" "=d"))
2965 (clobber (match_operand:P 1 "register_operand" "=d"))
2966 (set (reg:CCU CC_REGNUM)
2967 (compare:CCU (mem:BLK (match_operand:P 2 "register_operand" "0"))
2968 (mem:BLK (match_operand:P 3 "register_operand" "1"))))
2969 (use (reg:SI 0))]
2970 ""
2971 "clst\t%0,%1\;jo\t.-4"
2972 [(set_attr "length" "8")
2973 (set_attr "type" "vs")])
2974
2975 ;
2976 ; movstr instruction pattern.
2977 ;
2978
2979 (define_expand "movstr"
2980 [(match_operand 0 "register_operand" "")
2981 (match_operand 1 "memory_operand" "")
2982 (match_operand 2 "memory_operand" "")]
2983 ""
2984 {
2985 if (TARGET_64BIT)
2986 emit_insn (gen_movstrdi (operands[0], operands[1], operands[2]));
2987 else
2988 emit_insn (gen_movstrsi (operands[0], operands[1], operands[2]));
2989 DONE;
2990 })
2991
2992 (define_expand "movstr<P:mode>"
2993 [(set (reg:SI 0) (const_int 0))
2994 (parallel
2995 [(clobber (match_dup 3))
2996 (set (match_operand:BLK 1 "memory_operand" "")
2997 (match_operand:BLK 2 "memory_operand" ""))
2998 (set (match_operand:P 0 "register_operand" "")
2999 (unspec:P [(match_dup 1)
3000 (match_dup 2)
3001 (reg:SI 0)] UNSPEC_MVST))
3002 (clobber (reg:CC CC_REGNUM))])]
3003 ""
3004 {
3005 rtx addr1, addr2;
3006
3007 if (TARGET_VX && optimize_function_for_speed_p (cfun))
3008 {
3009 s390_expand_vec_movstr (operands[0], operands[1], operands[2]);
3010 DONE;
3011 }
3012
3013 addr1 = gen_reg_rtx (Pmode);
3014 addr2 = gen_reg_rtx (Pmode);
3015
3016 emit_move_insn (addr1, force_operand (XEXP (operands[1], 0), NULL_RTX));
3017 emit_move_insn (addr2, force_operand (XEXP (operands[2], 0), NULL_RTX));
3018 operands[1] = replace_equiv_address_nv (operands[1], addr1);
3019 operands[2] = replace_equiv_address_nv (operands[2], addr2);
3020 operands[3] = addr2;
3021 })
3022
3023 (define_insn "*movstr"
3024 [(clobber (match_operand:P 2 "register_operand" "=d"))
3025 (set (mem:BLK (match_operand:P 1 "register_operand" "0"))
3026 (mem:BLK (match_operand:P 3 "register_operand" "2")))
3027 (set (match_operand:P 0 "register_operand" "=d")
3028 (unspec:P [(mem:BLK (match_dup 1))
3029 (mem:BLK (match_dup 3))
3030 (reg:SI 0)] UNSPEC_MVST))
3031 (clobber (reg:CC CC_REGNUM))]
3032 ""
3033 "mvst\t%1,%2\;jo\t.-4"
3034 [(set_attr "length" "8")
3035 (set_attr "type" "vs")])
3036
3037
3038 ;
3039 ; movmemM instruction pattern(s).
3040 ;
3041
3042 (define_expand "movmem<mode>"
3043 [(set (match_operand:BLK 0 "memory_operand" "") ; destination
3044 (match_operand:BLK 1 "memory_operand" "")) ; source
3045 (use (match_operand:GPR 2 "general_operand" "")) ; count
3046 (match_operand 3 "" "")]
3047 ""
3048 {
3049 if (s390_expand_movmem (operands[0], operands[1], operands[2]))
3050 DONE;
3051 else
3052 FAIL;
3053 })
3054
3055 ; Move a block that is up to 256 bytes in length.
3056 ; The block length is taken as (operands[2] % 256) + 1.
3057
3058 (define_expand "movmem_short"
3059 [(parallel
3060 [(set (match_operand:BLK 0 "memory_operand" "")
3061 (match_operand:BLK 1 "memory_operand" ""))
3062 (use (match_operand 2 "nonmemory_operand" ""))
3063 (use (const:BLK (unspec:BLK [(const_int 0)] UNSPEC_INSN)))
3064 (clobber (match_dup 3))])]
3065 ""
3066 "operands[3] = gen_rtx_SCRATCH (Pmode);")
3067
3068 (define_insn "*movmem_short"
3069 [(set (match_operand:BLK 0 "memory_operand" "=Q,Q,Q,Q")
3070 (match_operand:BLK 1 "memory_operand" "Q,Q,Q,Q"))
3071 (use (match_operand 2 "nonmemory_operand" "n,a,a,a"))
3072 (use (match_operand 3 "immediate_operand" "X,R,X,X"))
3073 (clobber (match_scratch:P 4 "=X,X,X,&a"))]
3074 "(GET_MODE (operands[2]) == Pmode || GET_MODE (operands[2]) == VOIDmode)"
3075 "#"
3076 [(set_attr "type" "cs")
3077 (set_attr "cpu_facility" "*,*,z10,cpu_zarch")])
3078
3079 (define_split
3080 [(set (match_operand:BLK 0 "memory_operand" "")
3081 (match_operand:BLK 1 "memory_operand" ""))
3082 (use (match_operand 2 "const_int_operand" ""))
3083 (use (match_operand 3 "immediate_operand" ""))
3084 (clobber (scratch))]
3085 "reload_completed"
3086 [(parallel
3087 [(set (match_dup 0) (match_dup 1))
3088 (use (match_dup 2))])]
3089 "operands[2] = GEN_INT ((INTVAL (operands[2]) & 0xff) + 1);")
3090
3091 (define_split
3092 [(set (match_operand:BLK 0 "memory_operand" "")
3093 (match_operand:BLK 1 "memory_operand" ""))
3094 (use (match_operand 2 "register_operand" ""))
3095 (use (match_operand 3 "memory_operand" ""))
3096 (clobber (scratch))]
3097 "reload_completed"
3098 [(parallel
3099 [(unspec [(match_dup 2) (match_dup 3)
3100 (const_int 0)] UNSPEC_EXECUTE)
3101 (set (match_dup 0) (match_dup 1))
3102 (use (const_int 1))])]
3103 "")
3104
3105 (define_split
3106 [(set (match_operand:BLK 0 "memory_operand" "")
3107 (match_operand:BLK 1 "memory_operand" ""))
3108 (use (match_operand 2 "register_operand" ""))
3109 (use (const:BLK (unspec:BLK [(const_int 0)] UNSPEC_INSN)))
3110 (clobber (scratch))]
3111 "TARGET_Z10 && reload_completed"
3112 [(parallel
3113 [(unspec [(match_dup 2) (const_int 0)
3114 (label_ref (match_dup 3))] UNSPEC_EXECUTE)
3115 (set (match_dup 0) (match_dup 1))
3116 (use (const_int 1))])]
3117 "operands[3] = gen_label_rtx ();")
3118
3119 (define_split
3120 [(set (match_operand:BLK 0 "memory_operand" "")
3121 (match_operand:BLK 1 "memory_operand" ""))
3122 (use (match_operand 2 "register_operand" ""))
3123 (use (const:BLK (unspec:BLK [(const_int 0)] UNSPEC_INSN)))
3124 (clobber (match_operand 3 "register_operand" ""))]
3125 "reload_completed && TARGET_CPU_ZARCH"
3126 [(set (match_dup 3) (label_ref (match_dup 4)))
3127 (parallel
3128 [(unspec [(match_dup 2) (mem:BLK (match_dup 3))
3129 (label_ref (match_dup 4))] UNSPEC_EXECUTE)
3130 (set (match_dup 0) (match_dup 1))
3131 (use (const_int 1))])]
3132 "operands[4] = gen_label_rtx ();")
3133
3134 ; Move a block of arbitrary length.
3135
3136 (define_expand "movmem_long"
3137 [(parallel
3138 [(clobber (match_dup 2))
3139 (clobber (match_dup 3))
3140 (set (match_operand:BLK 0 "memory_operand" "")
3141 (match_operand:BLK 1 "memory_operand" ""))
3142 (use (match_operand 2 "general_operand" ""))
3143 (use (match_dup 3))
3144 (clobber (reg:CC CC_REGNUM))])]
3145 ""
3146 {
3147 machine_mode sreg_mode = TARGET_ZARCH ? DImode : SImode;
3148 machine_mode dreg_mode = TARGET_ZARCH ? TImode : DImode;
3149 rtx reg0 = gen_reg_rtx (dreg_mode);
3150 rtx reg1 = gen_reg_rtx (dreg_mode);
3151 rtx addr0 = gen_lowpart (Pmode, gen_highpart (sreg_mode, reg0));
3152 rtx addr1 = gen_lowpart (Pmode, gen_highpart (sreg_mode, reg1));
3153 rtx len0 = gen_lowpart (Pmode, reg0);
3154 rtx len1 = gen_lowpart (Pmode, reg1);
3155
3156 emit_clobber (reg0);
3157 emit_move_insn (addr0, force_operand (XEXP (operands[0], 0), NULL_RTX));
3158 emit_move_insn (len0, operands[2]);
3159
3160 emit_clobber (reg1);
3161 emit_move_insn (addr1, force_operand (XEXP (operands[1], 0), NULL_RTX));
3162 emit_move_insn (len1, operands[2]);
3163
3164 operands[0] = replace_equiv_address_nv (operands[0], addr0);
3165 operands[1] = replace_equiv_address_nv (operands[1], addr1);
3166 operands[2] = reg0;
3167 operands[3] = reg1;
3168 })
3169
3170 (define_insn "*movmem_long"
3171 [(clobber (match_operand:<DBL> 0 "register_operand" "=d"))
3172 (clobber (match_operand:<DBL> 1 "register_operand" "=d"))
3173 (set (mem:BLK (subreg:P (match_operand:<DBL> 2 "register_operand" "0") 0))
3174 (mem:BLK (subreg:P (match_operand:<DBL> 3 "register_operand" "1") 0)))
3175 (use (match_dup 2))
3176 (use (match_dup 3))
3177 (clobber (reg:CC CC_REGNUM))]
3178 "TARGET_64BIT || !TARGET_ZARCH"
3179 "mvcle\t%0,%1,0\;jo\t.-4"
3180 [(set_attr "length" "8")
3181 (set_attr "type" "vs")])
3182
3183 (define_insn "*movmem_long_31z"
3184 [(clobber (match_operand:TI 0 "register_operand" "=d"))
3185 (clobber (match_operand:TI 1 "register_operand" "=d"))
3186 (set (mem:BLK (subreg:SI (match_operand:TI 2 "register_operand" "0") 4))
3187 (mem:BLK (subreg:SI (match_operand:TI 3 "register_operand" "1") 4)))
3188 (use (match_dup 2))
3189 (use (match_dup 3))
3190 (clobber (reg:CC CC_REGNUM))]
3191 "!TARGET_64BIT && TARGET_ZARCH"
3192 "mvcle\t%0,%1,0\;jo\t.-4"
3193 [(set_attr "length" "8")
3194 (set_attr "type" "vs")])
3195
3196
3197 ;
3198 ; Test data class.
3199 ;
3200
3201 (define_expand "signbit<mode>2"
3202 [(set (reg:CCZ CC_REGNUM)
3203 (unspec:CCZ [(match_operand:FP_ALL 1 "register_operand" "f")
3204 (match_dup 2)]
3205 UNSPEC_TDC_INSN))
3206 (set (match_operand:SI 0 "register_operand" "=d")
3207 (unspec:SI [(reg:CCZ CC_REGNUM)] UNSPEC_CC_TO_INT))]
3208 "TARGET_HARD_FLOAT"
3209 {
3210 operands[2] = GEN_INT (S390_TDC_SIGNBIT_SET);
3211 })
3212
3213 (define_expand "isinf<mode>2"
3214 [(set (reg:CCZ CC_REGNUM)
3215 (unspec:CCZ [(match_operand:FP_ALL 1 "register_operand" "f")
3216 (match_dup 2)]
3217 UNSPEC_TDC_INSN))
3218 (set (match_operand:SI 0 "register_operand" "=d")
3219 (unspec:SI [(reg:CCZ CC_REGNUM)] UNSPEC_CC_TO_INT))]
3220 "TARGET_HARD_FLOAT"
3221 {
3222 operands[2] = GEN_INT (S390_TDC_INFINITY);
3223 })
3224
3225 ; This extracts CC into a GPR properly shifted. The actual IPM
3226 ; instruction will be issued by reload. The constraint of operand 1
3227 ; forces reload to use a GPR. So reload will issue a movcc insn for
3228 ; copying CC into a GPR first.
3229 (define_insn_and_split "*cc_to_int"
3230 [(set (match_operand:SI 0 "nonimmediate_operand" "=d")
3231 (unspec:SI [(match_operand 1 "register_operand" "0")]
3232 UNSPEC_CC_TO_INT))]
3233 "operands != NULL"
3234 "#"
3235 "reload_completed"
3236 [(set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 28)))])
3237
3238 ; This insn is used to generate all variants of the Test Data Class
3239 ; instruction, namely tcxb, tcdb, and tceb. The insn's first operand
3240 ; is the register to be tested and the second one is the bit mask
3241 ; specifying the required test(s).
3242 ;
3243 ; tcxb, tcdb, tceb, tdcxt, tdcdt, tdcet
3244 (define_insn "*TDC_insn_<mode>"
3245 [(set (reg:CCZ CC_REGNUM)
3246 (unspec:CCZ [(match_operand:FP_ALL 0 "register_operand" "f")
3247 (match_operand:SI 1 "const_int_operand")] UNSPEC_TDC_INSN))]
3248 "TARGET_HARD_FLOAT"
3249 "t<_d>c<xde><bt>\t%0,%1"
3250 [(set_attr "op_type" "RXE")
3251 (set_attr "type" "fsimp<mode>")])
3252
3253
3254
3255 ;
3256 ; setmemM instruction pattern(s).
3257 ;
3258
3259 (define_expand "setmem<mode>"
3260 [(set (match_operand:BLK 0 "memory_operand" "")
3261 (match_operand:QI 2 "general_operand" ""))
3262 (use (match_operand:GPR 1 "general_operand" ""))
3263 (match_operand 3 "" "")]
3264 ""
3265 "s390_expand_setmem (operands[0], operands[1], operands[2]); DONE;")
3266
3267 ; Clear a block that is up to 256 bytes in length.
3268 ; The block length is taken as (operands[1] % 256) + 1.
3269
3270 (define_expand "clrmem_short"
3271 [(parallel
3272 [(set (match_operand:BLK 0 "memory_operand" "")
3273 (const_int 0))
3274 (use (match_operand 1 "nonmemory_operand" ""))
3275 (use (const:BLK (unspec:BLK [(const_int 0)] UNSPEC_INSN)))
3276 (clobber (match_dup 2))
3277 (clobber (reg:CC CC_REGNUM))])]
3278 ""
3279 "operands[2] = gen_rtx_SCRATCH (Pmode);")
3280
3281 (define_insn "*clrmem_short"
3282 [(set (match_operand:BLK 0 "memory_operand" "=Q,Q,Q,Q")
3283 (const_int 0))
3284 (use (match_operand 1 "nonmemory_operand" "n,a,a,a"))
3285 (use (match_operand 2 "immediate_operand" "X,R,X,X"))
3286 (clobber (match_scratch:P 3 "=X,X,X,&a"))
3287 (clobber (reg:CC CC_REGNUM))]
3288 "(GET_MODE (operands[1]) == Pmode || GET_MODE (operands[1]) == VOIDmode)"
3289 "#"
3290 [(set_attr "type" "cs")
3291 (set_attr "cpu_facility" "*,*,z10,cpu_zarch")])
3292
3293 (define_split
3294 [(set (match_operand:BLK 0 "memory_operand" "")
3295 (const_int 0))
3296 (use (match_operand 1 "const_int_operand" ""))
3297 (use (match_operand 2 "immediate_operand" ""))
3298 (clobber (scratch))
3299 (clobber (reg:CC CC_REGNUM))]
3300 "reload_completed"
3301 [(parallel
3302 [(set (match_dup 0) (const_int 0))
3303 (use (match_dup 1))
3304 (clobber (reg:CC CC_REGNUM))])]
3305 "operands[1] = GEN_INT ((INTVAL (operands[1]) & 0xff) + 1);")
3306
3307 (define_split
3308 [(set (match_operand:BLK 0 "memory_operand" "")
3309 (const_int 0))
3310 (use (match_operand 1 "register_operand" ""))
3311 (use (match_operand 2 "memory_operand" ""))
3312 (clobber (scratch))
3313 (clobber (reg:CC CC_REGNUM))]
3314 "reload_completed"
3315 [(parallel
3316 [(unspec [(match_dup 1) (match_dup 2)
3317 (const_int 0)] UNSPEC_EXECUTE)
3318 (set (match_dup 0) (const_int 0))
3319 (use (const_int 1))
3320 (clobber (reg:CC CC_REGNUM))])]
3321 "")
3322
3323 (define_split
3324 [(set (match_operand:BLK 0 "memory_operand" "")
3325 (const_int 0))
3326 (use (match_operand 1 "register_operand" ""))
3327 (use (const:BLK (unspec:BLK [(const_int 0)] UNSPEC_INSN)))
3328 (clobber (scratch))
3329 (clobber (reg:CC CC_REGNUM))]
3330 "TARGET_Z10 && reload_completed"
3331 [(parallel
3332 [(unspec [(match_dup 1) (const_int 0)
3333 (label_ref (match_dup 3))] UNSPEC_EXECUTE)
3334 (set (match_dup 0) (const_int 0))
3335 (use (const_int 1))
3336 (clobber (reg:CC CC_REGNUM))])]
3337 "operands[3] = gen_label_rtx ();")
3338
3339 (define_split
3340 [(set (match_operand:BLK 0 "memory_operand" "")
3341 (const_int 0))
3342 (use (match_operand 1 "register_operand" ""))
3343 (use (const:BLK (unspec:BLK [(const_int 0)] UNSPEC_INSN)))
3344 (clobber (match_operand 2 "register_operand" ""))
3345 (clobber (reg:CC CC_REGNUM))]
3346 "reload_completed && TARGET_CPU_ZARCH"
3347 [(set (match_dup 2) (label_ref (match_dup 3)))
3348 (parallel
3349 [(unspec [(match_dup 1) (mem:BLK (match_dup 2))
3350 (label_ref (match_dup 3))] UNSPEC_EXECUTE)
3351 (set (match_dup 0) (const_int 0))
3352 (use (const_int 1))
3353 (clobber (reg:CC CC_REGNUM))])]
3354 "operands[3] = gen_label_rtx ();")
3355
3356 ; Initialize a block of arbitrary length with (operands[2] % 256).
3357
3358 (define_expand "setmem_long_<P:mode>"
3359 [(parallel
3360 [(clobber (match_dup 1))
3361 (set (match_operand:BLK 0 "memory_operand" "")
3362 (unspec:BLK [(match_operand:P 2 "setmem_operand" "")
3363 (match_dup 4)] UNSPEC_REPLICATE_BYTE))
3364 (use (match_dup 3))
3365 (clobber (reg:CC CC_REGNUM))])]
3366 ""
3367 {
3368 machine_mode sreg_mode = TARGET_ZARCH ? DImode : SImode;
3369 machine_mode dreg_mode = TARGET_ZARCH ? TImode : DImode;
3370 rtx reg0 = gen_reg_rtx (dreg_mode);
3371 rtx reg1 = gen_reg_rtx (dreg_mode);
3372 rtx addr0 = gen_lowpart (Pmode, gen_highpart (sreg_mode, reg0));
3373 rtx len0 = gen_lowpart (Pmode, reg0);
3374
3375 emit_clobber (reg0);
3376 emit_move_insn (addr0, force_operand (XEXP (operands[0], 0), NULL_RTX));
3377 emit_move_insn (len0, operands[1]);
3378
3379 emit_move_insn (reg1, const0_rtx);
3380
3381 operands[0] = replace_equiv_address_nv (operands[0], addr0);
3382 operands[1] = reg0;
3383 operands[3] = reg1;
3384 operands[4] = gen_lowpart (Pmode, operands[1]);
3385 })
3386
3387 ; Patterns for 31 bit + Esa and 64 bit + Zarch.
3388
3389 (define_insn "*setmem_long"
3390 [(clobber (match_operand:<DBL> 0 "register_operand" "=d"))
3391 (set (mem:BLK (subreg:P (match_operand:<DBL> 3 "register_operand" "0") 0))
3392 (unspec:BLK [(match_operand:P 2 "setmem_operand" "Y")
3393 (subreg:P (match_dup 3) <modesize>)]
3394 UNSPEC_REPLICATE_BYTE))
3395 (use (match_operand:<DBL> 1 "register_operand" "d"))
3396 (clobber (reg:CC CC_REGNUM))]
3397 "TARGET_64BIT || !TARGET_ZARCH"
3398 "mvcle\t%0,%1,%Y2\;jo\t.-4"
3399 [(set_attr "length" "8")
3400 (set_attr "type" "vs")])
3401
3402 (define_insn "*setmem_long_and"
3403 [(clobber (match_operand:<DBL> 0 "register_operand" "=d"))
3404 (set (mem:BLK (subreg:P (match_operand:<DBL> 3 "register_operand" "0") 0))
3405 (unspec:BLK [(and:P
3406 (match_operand:P 2 "setmem_operand" "Y")
3407 (match_operand:P 4 "const_int_operand" "n"))
3408 (subreg:P (match_dup 3) <modesize>)]
3409 UNSPEC_REPLICATE_BYTE))
3410 (use (match_operand:<DBL> 1 "register_operand" "d"))
3411 (clobber (reg:CC CC_REGNUM))]
3412 "(TARGET_64BIT || !TARGET_ZARCH) &&
3413 (INTVAL (operands[4]) & 255) == 255"
3414 "mvcle\t%0,%1,%Y2\;jo\t.-4"
3415 [(set_attr "length" "8")
3416 (set_attr "type" "vs")])
3417
3418 ; Variants for 31 bit + Zarch, necessary because of the odd in-register offsets
3419 ; of the SImode subregs.
3420
3421 (define_insn "*setmem_long_31z"
3422 [(clobber (match_operand:TI 0 "register_operand" "=d"))
3423 (set (mem:BLK (subreg:SI (match_operand:TI 3 "register_operand" "0") 4))
3424 (unspec:BLK [(match_operand:SI 2 "setmem_operand" "Y")
3425 (subreg:SI (match_dup 3) 12)] UNSPEC_REPLICATE_BYTE))
3426 (use (match_operand:TI 1 "register_operand" "d"))
3427 (clobber (reg:CC CC_REGNUM))]
3428 "!TARGET_64BIT && TARGET_ZARCH"
3429 "mvcle\t%0,%1,%Y2\;jo\t.-4"
3430 [(set_attr "length" "8")
3431 (set_attr "type" "vs")])
3432
3433 (define_insn "*setmem_long_and_31z"
3434 [(clobber (match_operand:TI 0 "register_operand" "=d"))
3435 (set (mem:BLK (subreg:SI (match_operand:TI 3 "register_operand" "0") 4))
3436 (unspec:BLK [(and:SI
3437 (match_operand:SI 2 "setmem_operand" "Y")
3438 (match_operand:SI 4 "const_int_operand" "n"))
3439 (subreg:SI (match_dup 3) 12)] UNSPEC_REPLICATE_BYTE))
3440 (use (match_operand:TI 1 "register_operand" "d"))
3441 (clobber (reg:CC CC_REGNUM))]
3442 "(!TARGET_64BIT && TARGET_ZARCH) &&
3443 (INTVAL (operands[4]) & 255) == 255"
3444 "mvcle\t%0,%1,%Y2\;jo\t.-4"
3445 [(set_attr "length" "8")
3446 (set_attr "type" "vs")])
3447
3448 ;
3449 ; cmpmemM instruction pattern(s).
3450 ;
3451
3452 (define_expand "cmpmemsi"
3453 [(set (match_operand:SI 0 "register_operand" "")
3454 (compare:SI (match_operand:BLK 1 "memory_operand" "")
3455 (match_operand:BLK 2 "memory_operand" "") ) )
3456 (use (match_operand:SI 3 "general_operand" ""))
3457 (use (match_operand:SI 4 "" ""))]
3458 ""
3459 {
3460 if (s390_expand_cmpmem (operands[0], operands[1],
3461 operands[2], operands[3]))
3462 DONE;
3463 else
3464 FAIL;
3465 })
3466
3467 ; Compare a block that is up to 256 bytes in length.
3468 ; The block length is taken as (operands[2] % 256) + 1.
3469
3470 (define_expand "cmpmem_short"
3471 [(parallel
3472 [(set (reg:CCU CC_REGNUM)
3473 (compare:CCU (match_operand:BLK 0 "memory_operand" "")
3474 (match_operand:BLK 1 "memory_operand" "")))
3475 (use (match_operand 2 "nonmemory_operand" ""))
3476 (use (const:BLK (unspec:BLK [(const_int 0)] UNSPEC_INSN)))
3477 (clobber (match_dup 3))])]
3478 ""
3479 "operands[3] = gen_rtx_SCRATCH (Pmode);")
3480
3481 (define_insn "*cmpmem_short"
3482 [(set (reg:CCU CC_REGNUM)
3483 (compare:CCU (match_operand:BLK 0 "memory_operand" "Q,Q,Q,Q")
3484 (match_operand:BLK 1 "memory_operand" "Q,Q,Q,Q")))
3485 (use (match_operand 2 "nonmemory_operand" "n,a,a,a"))
3486 (use (match_operand 3 "immediate_operand" "X,R,X,X"))
3487 (clobber (match_scratch:P 4 "=X,X,X,&a"))]
3488 "(GET_MODE (operands[2]) == Pmode || GET_MODE (operands[2]) == VOIDmode)"
3489 "#"
3490 [(set_attr "type" "cs")
3491 (set_attr "cpu_facility" "*,*,z10,cpu_zarch")])
3492
3493 (define_split
3494 [(set (reg:CCU CC_REGNUM)
3495 (compare:CCU (match_operand:BLK 0 "memory_operand" "")
3496 (match_operand:BLK 1 "memory_operand" "")))
3497 (use (match_operand 2 "const_int_operand" ""))
3498 (use (match_operand 3 "immediate_operand" ""))
3499 (clobber (scratch))]
3500 "reload_completed"
3501 [(parallel
3502 [(set (reg:CCU CC_REGNUM) (compare:CCU (match_dup 0) (match_dup 1)))
3503 (use (match_dup 2))])]
3504 "operands[2] = GEN_INT ((INTVAL (operands[2]) & 0xff) + 1);")
3505
3506 (define_split
3507 [(set (reg:CCU CC_REGNUM)
3508 (compare:CCU (match_operand:BLK 0 "memory_operand" "")
3509 (match_operand:BLK 1 "memory_operand" "")))
3510 (use (match_operand 2 "register_operand" ""))
3511 (use (match_operand 3 "memory_operand" ""))
3512 (clobber (scratch))]
3513 "reload_completed"
3514 [(parallel
3515 [(unspec [(match_dup 2) (match_dup 3)
3516 (const_int 0)] UNSPEC_EXECUTE)
3517 (set (reg:CCU CC_REGNUM) (compare:CCU (match_dup 0) (match_dup 1)))
3518 (use (const_int 1))])]
3519 "")
3520
3521 (define_split
3522 [(set (reg:CCU CC_REGNUM)
3523 (compare:CCU (match_operand:BLK 0 "memory_operand" "")
3524 (match_operand:BLK 1 "memory_operand" "")))
3525 (use (match_operand 2 "register_operand" ""))
3526 (use (const:BLK (unspec:BLK [(const_int 0)] UNSPEC_INSN)))
3527 (clobber (scratch))]
3528 "TARGET_Z10 && reload_completed"
3529 [(parallel
3530 [(unspec [(match_dup 2) (const_int 0)
3531 (label_ref (match_dup 4))] UNSPEC_EXECUTE)
3532 (set (reg:CCU CC_REGNUM) (compare:CCU (match_dup 0) (match_dup 1)))
3533 (use (const_int 1))])]
3534 "operands[4] = gen_label_rtx ();")
3535
3536 (define_split
3537 [(set (reg:CCU CC_REGNUM)
3538 (compare:CCU (match_operand:BLK 0 "memory_operand" "")
3539 (match_operand:BLK 1 "memory_operand" "")))
3540 (use (match_operand 2 "register_operand" ""))
3541 (use (const:BLK (unspec:BLK [(const_int 0)] UNSPEC_INSN)))
3542 (clobber (match_operand 3 "register_operand" ""))]
3543 "reload_completed && TARGET_CPU_ZARCH"
3544 [(set (match_dup 3) (label_ref (match_dup 4)))
3545 (parallel
3546 [(unspec [(match_dup 2) (mem:BLK (match_dup 3))
3547 (label_ref (match_dup 4))] UNSPEC_EXECUTE)
3548 (set (reg:CCU CC_REGNUM) (compare:CCU (match_dup 0) (match_dup 1)))
3549 (use (const_int 1))])]
3550 "operands[4] = gen_label_rtx ();")
3551
3552 ; Compare a block of arbitrary length.
3553
3554 (define_expand "cmpmem_long"
3555 [(parallel
3556 [(clobber (match_dup 2))
3557 (clobber (match_dup 3))
3558 (set (reg:CCU CC_REGNUM)
3559 (compare:CCU (match_operand:BLK 0 "memory_operand" "")
3560 (match_operand:BLK 1 "memory_operand" "")))
3561 (use (match_operand 2 "general_operand" ""))
3562 (use (match_dup 3))])]
3563 ""
3564 {
3565 machine_mode sreg_mode = TARGET_ZARCH ? DImode : SImode;
3566 machine_mode dreg_mode = TARGET_ZARCH ? TImode : DImode;
3567 rtx reg0 = gen_reg_rtx (dreg_mode);
3568 rtx reg1 = gen_reg_rtx (dreg_mode);
3569 rtx addr0 = gen_lowpart (Pmode, gen_highpart (sreg_mode, reg0));
3570 rtx addr1 = gen_lowpart (Pmode, gen_highpart (sreg_mode, reg1));
3571 rtx len0 = gen_lowpart (Pmode, reg0);
3572 rtx len1 = gen_lowpart (Pmode, reg1);
3573
3574 emit_clobber (reg0);
3575 emit_move_insn (addr0, force_operand (XEXP (operands[0], 0), NULL_RTX));
3576 emit_move_insn (len0, operands[2]);
3577
3578 emit_clobber (reg1);
3579 emit_move_insn (addr1, force_operand (XEXP (operands[1], 0), NULL_RTX));
3580 emit_move_insn (len1, operands[2]);
3581
3582 operands[0] = replace_equiv_address_nv (operands[0], addr0);
3583 operands[1] = replace_equiv_address_nv (operands[1], addr1);
3584 operands[2] = reg0;
3585 operands[3] = reg1;
3586 })
3587
3588 (define_insn "*cmpmem_long"
3589 [(clobber (match_operand:<DBL> 0 "register_operand" "=d"))
3590 (clobber (match_operand:<DBL> 1 "register_operand" "=d"))
3591 (set (reg:CCU CC_REGNUM)
3592 (compare:CCU (mem:BLK (subreg:P (match_operand:<DBL> 2 "register_operand" "0") 0))
3593 (mem:BLK (subreg:P (match_operand:<DBL> 3 "register_operand" "1") 0))))
3594 (use (match_dup 2))
3595 (use (match_dup 3))]
3596 "TARGET_64BIT || !TARGET_ZARCH"
3597 "clcle\t%0,%1,0\;jo\t.-4"
3598 [(set_attr "length" "8")
3599 (set_attr "type" "vs")])
3600
3601 (define_insn "*cmpmem_long_31z"
3602 [(clobber (match_operand:TI 0 "register_operand" "=d"))
3603 (clobber (match_operand:TI 1 "register_operand" "=d"))
3604 (set (reg:CCU CC_REGNUM)
3605 (compare:CCU (mem:BLK (subreg:SI (match_operand:TI 2 "register_operand" "0") 4))
3606 (mem:BLK (subreg:SI (match_operand:TI 3 "register_operand" "1") 4))))
3607 (use (match_dup 2))
3608 (use (match_dup 3))]
3609 "!TARGET_64BIT && TARGET_ZARCH"
3610 "clcle\t%0,%1,0\;jo\t.-4"
3611 [(set_attr "op_type" "NN")
3612 (set_attr "type" "vs")
3613 (set_attr "length" "8")])
3614
3615 ; Convert CCUmode condition code to integer.
3616 ; Result is zero if EQ, positive if LTU, negative if GTU.
3617
3618 (define_insn_and_split "cmpint"
3619 [(set (match_operand:SI 0 "register_operand" "=d")
3620 (unspec:SI [(match_operand:CCU 1 "register_operand" "0")]
3621 UNSPEC_STRCMPCC_TO_INT))
3622 (clobber (reg:CC CC_REGNUM))]
3623 ""
3624 "#"
3625 "reload_completed"
3626 [(set (match_dup 0) (ashift:SI (match_dup 0) (const_int 2)))
3627 (parallel
3628 [(set (match_dup 0) (ashiftrt:SI (match_dup 0) (const_int 30)))
3629 (clobber (reg:CC CC_REGNUM))])])
3630
3631 (define_insn_and_split "*cmpint_cc"
3632 [(set (reg CC_REGNUM)
3633 (compare (unspec:SI [(match_operand:CCU 1 "register_operand" "0")]
3634 UNSPEC_STRCMPCC_TO_INT)
3635 (const_int 0)))
3636 (set (match_operand:SI 0 "register_operand" "=d")
3637 (unspec:SI [(match_dup 1)] UNSPEC_STRCMPCC_TO_INT))]
3638 "s390_match_ccmode (insn, CCSmode)"
3639 "#"
3640 "&& reload_completed"
3641 [(set (match_dup 0) (ashift:SI (match_dup 0) (const_int 2)))
3642 (parallel
3643 [(set (match_dup 2) (match_dup 3))
3644 (set (match_dup 0) (ashiftrt:SI (match_dup 0) (const_int 30)))])]
3645 {
3646 rtx result = gen_rtx_ASHIFTRT (SImode, operands[0], GEN_INT (30));
3647 operands[2] = SET_DEST (XVECEXP (PATTERN (curr_insn), 0, 0));
3648 operands[3] = gen_rtx_COMPARE (GET_MODE (operands[2]), result, const0_rtx);
3649 })
3650
3651 (define_insn_and_split "*cmpint_sign"
3652 [(set (match_operand:DI 0 "register_operand" "=d")
3653 (sign_extend:DI (unspec:SI [(match_operand:CCU 1 "register_operand" "0")]
3654 UNSPEC_STRCMPCC_TO_INT)))
3655 (clobber (reg:CC CC_REGNUM))]
3656 "TARGET_ZARCH"
3657 "#"
3658 "&& reload_completed"
3659 [(set (match_dup 0) (ashift:DI (match_dup 0) (const_int 34)))
3660 (parallel
3661 [(set (match_dup 0) (ashiftrt:DI (match_dup 0) (const_int 62)))
3662 (clobber (reg:CC CC_REGNUM))])])
3663
3664 (define_insn_and_split "*cmpint_sign_cc"
3665 [(set (reg CC_REGNUM)
3666 (compare (ashiftrt:DI (ashift:DI (subreg:DI
3667 (unspec:SI [(match_operand:CCU 1 "register_operand" "0")]
3668 UNSPEC_STRCMPCC_TO_INT) 0)
3669 (const_int 32)) (const_int 32))
3670 (const_int 0)))
3671 (set (match_operand:DI 0 "register_operand" "=d")
3672 (sign_extend:DI (unspec:SI [(match_dup 1)] UNSPEC_STRCMPCC_TO_INT)))]
3673 "s390_match_ccmode (insn, CCSmode) && TARGET_ZARCH"
3674 "#"
3675 "&& reload_completed"
3676 [(set (match_dup 0) (ashift:DI (match_dup 0) (const_int 34)))
3677 (parallel
3678 [(set (match_dup 2) (match_dup 3))
3679 (set (match_dup 0) (ashiftrt:DI (match_dup 0) (const_int 62)))])]
3680 {
3681 rtx result = gen_rtx_ASHIFTRT (DImode, operands[0], GEN_INT (62));
3682 operands[2] = SET_DEST (XVECEXP (PATTERN (curr_insn), 0, 0));
3683 operands[3] = gen_rtx_COMPARE (GET_MODE (operands[2]), result, const0_rtx);
3684 })
3685
3686
3687 ;;
3688 ;;- Conversion instructions.
3689 ;;
3690
3691 (define_insn "*sethighpartsi"
3692 [(set (match_operand:SI 0 "register_operand" "=d,d")
3693 (unspec:SI [(match_operand:BLK 1 "s_operand" "Q,S")
3694 (match_operand 2 "const_int_operand" "n,n")] UNSPEC_ICM))
3695 (clobber (reg:CC CC_REGNUM))]
3696 ""
3697 "@
3698 icm\t%0,%2,%S1
3699 icmy\t%0,%2,%S1"
3700 [(set_attr "op_type" "RS,RSY")
3701 (set_attr "cpu_facility" "*,longdisp")
3702 (set_attr "z10prop" "z10_super_E1,z10_super_E1")])
3703
3704 (define_insn "*sethighpartdi_64"
3705 [(set (match_operand:DI 0 "register_operand" "=d")
3706 (unspec:DI [(match_operand:BLK 1 "s_operand" "S")
3707 (match_operand 2 "const_int_operand" "n")] UNSPEC_ICM))
3708 (clobber (reg:CC CC_REGNUM))]
3709 "TARGET_ZARCH"
3710 "icmh\t%0,%2,%S1"
3711 [(set_attr "op_type" "RSY")
3712 (set_attr "z10prop" "z10_super")])
3713
3714 (define_insn "*sethighpartdi_31"
3715 [(set (match_operand:DI 0 "register_operand" "=d,d")
3716 (unspec:DI [(match_operand:BLK 1 "s_operand" "Q,S")
3717 (match_operand 2 "const_int_operand" "n,n")] UNSPEC_ICM))
3718 (clobber (reg:CC CC_REGNUM))]
3719 "!TARGET_ZARCH"
3720 "@
3721 icm\t%0,%2,%S1
3722 icmy\t%0,%2,%S1"
3723 [(set_attr "op_type" "RS,RSY")
3724 (set_attr "cpu_facility" "*,longdisp")
3725 (set_attr "z10prop" "z10_super_E1,z10_super_E1")])
3726
3727 ;
3728 ; extv instruction patterns
3729 ;
3730
3731 ; FIXME: This expander needs to be converted from DI to GPR as well
3732 ; after resolving some issues with it.
3733
3734 (define_expand "extzv"
3735 [(parallel
3736 [(set (match_operand:DI 0 "register_operand" "=d")
3737 (zero_extract:DI
3738 (match_operand:DI 1 "register_operand" "d")
3739 (match_operand 2 "const_int_operand" "") ; size
3740 (match_operand 3 "const_int_operand" ""))) ; start
3741 (clobber (reg:CC CC_REGNUM))])]
3742 "TARGET_Z10"
3743 {
3744 if (! EXTRACT_ARGS_IN_RANGE (INTVAL (operands[2]), INTVAL (operands[3]), 64))
3745 FAIL;
3746 /* Starting with zEC12 there is risbgn not clobbering CC. */
3747 if (TARGET_ZEC12)
3748 {
3749 emit_move_insn (operands[0],
3750 gen_rtx_ZERO_EXTRACT (DImode,
3751 operands[1],
3752 operands[2],
3753 operands[3]));
3754 DONE;
3755 }
3756 })
3757
3758 (define_insn "*extzv<mode><clobbercc_or_nocc>"
3759 [(set (match_operand:GPR 0 "register_operand" "=d")
3760 (zero_extract:GPR
3761 (match_operand:GPR 1 "register_operand" "d")
3762 (match_operand 2 "const_int_operand" "") ; size
3763 (match_operand 3 "const_int_operand" ""))) ; start
3764 ]
3765 "<z10_or_zEC12_cond>
3766 && EXTRACT_ARGS_IN_RANGE (INTVAL (operands[2]), INTVAL (operands[3]),
3767 GET_MODE_BITSIZE (<MODE>mode))"
3768 "<risbg_n>\t%0,%1,64-%2,128+63,<bitoff_plus>%3+%2" ; dst, src, start, end, shift
3769 [(set_attr "op_type" "RIE")
3770 (set_attr "z10prop" "z10_super_E1")])
3771
3772 ; 64 bit: (a & -16) | ((b >> 8) & 15)
3773 (define_insn "*extzvdi<clobbercc_or_nocc>_lshiftrt"
3774 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+d")
3775 (match_operand 1 "const_int_operand" "") ; size
3776 (match_operand 2 "const_int_operand" "")) ; start
3777 (lshiftrt:DI (match_operand:DI 3 "register_operand" "d")
3778 (match_operand:DI 4 "nonzero_shift_count_operand" "")))]
3779 "<z10_or_zEC12_cond>
3780 && EXTRACT_ARGS_IN_RANGE (INTVAL (operands[1]), INTVAL (operands[2]), 64)
3781 && 64 - UINTVAL (operands[4]) >= UINTVAL (operands[1])"
3782 "<risbg_n>\t%0,%3,%2,%2+%1-1,128-%2-%1-%4"
3783 [(set_attr "op_type" "RIE")
3784 (set_attr "z10prop" "z10_super_E1")])
3785
3786 ; 32 bit: (a & -16) | ((b >> 8) & 15)
3787 (define_insn "*<risbg_n>_ior_and_sr_ze"
3788 [(set (match_operand:SI 0 "register_operand" "=d")
3789 (ior:SI (and:SI
3790 (match_operand:SI 1 "register_operand" "0")
3791 (match_operand:SI 2 "const_int_operand" ""))
3792 (subreg:SI
3793 (zero_extract:DI
3794 (match_operand:DI 3 "register_operand" "d")
3795 (match_operand 4 "const_int_operand" "") ; size
3796 (match_operand 5 "const_int_operand" "")) ; start
3797 4)))]
3798 "<z10_or_zEC12_cond>
3799 && EXTRACT_ARGS_IN_RANGE (INTVAL (operands[4]), INTVAL (operands[5]), 64)
3800 && UINTVAL (operands[2]) == (~(0ULL) << UINTVAL (operands[4]))"
3801 "<risbg_n>\t%0,%3,64-%4,63,%4+%5"
3802 [(set_attr "op_type" "RIE")
3803 (set_attr "z10prop" "z10_super_E1")])
3804
3805 ; ((int)foo >> 10) & 1;
3806 (define_insn "*extract1bitdi<clobbercc_or_nocc>"
3807 [(set (match_operand:DI 0 "register_operand" "=d")
3808 (ne:DI (zero_extract:DI
3809 (match_operand:DI 1 "register_operand" "d")
3810 (const_int 1) ; size
3811 (match_operand 2 "const_int_operand" "")) ; start
3812 (const_int 0)))]
3813 "<z10_or_zEC12_cond>
3814 && EXTRACT_ARGS_IN_RANGE (1, INTVAL (operands[2]), 64)"
3815 "<risbg_n>\t%0,%1,64-1,128+63,%2+1" ; dst, src, start, end, shift
3816 [(set_attr "op_type" "RIE")
3817 (set_attr "z10prop" "z10_super_E1")])
3818
3819 (define_insn "*<risbg_n>_and_subregdi_rotr"
3820 [(set (match_operand:DI 0 "register_operand" "=d")
3821 (and:DI (subreg:DI
3822 (rotate:SINT (match_operand:SINT 1 "register_operand" "d")
3823 (match_operand:SINT 2 "const_int_operand" "")) 0)
3824 (match_operand:DI 3 "contiguous_bitmask_operand" "")))]
3825 "<z10_or_zEC12_cond>
3826 && UINTVAL (operands[3]) < (1ULL << (UINTVAL (operands[2]) & 0x3f))"
3827 "<risbg_n>\t%0,%1,%s3,128+%e3,<bitoff_plus>%2" ; dst, src, start, end, shift
3828 [(set_attr "op_type" "RIE")
3829 (set_attr "z10prop" "z10_super_E1")])
3830
3831 (define_insn "*<risbg_n>_and_subregdi_rotl"
3832 [(set (match_operand:DI 0 "register_operand" "=d")
3833 (and:DI (subreg:DI
3834 (rotate:SINT (match_operand:SINT 1 "register_operand" "d")
3835 (match_operand:SINT 2 "const_int_operand" "")) 0)
3836 (match_operand:DI 3 "contiguous_bitmask_operand" "")))]
3837 "<z10_or_zEC12_cond>
3838 && !(UINTVAL (operands[3]) & ((1ULL << (UINTVAL (operands[2]) & 0x3f)) - 1))"
3839 "<risbg_n>\t%0,%1,%s3,128+%e3,%2" ; dst, src, start, end, shift
3840 [(set_attr "op_type" "RIE")
3841 (set_attr "z10prop" "z10_super_E1")])
3842
3843 (define_insn "*<risbg_n>_di_and_rot"
3844 [(set (match_operand:DI 0 "register_operand" "=d")
3845 (and:DI (rotate:DI (match_operand:DI 1 "register_operand" "d")
3846 (match_operand:DI 2 "const_int_operand" ""))
3847 (match_operand:DI 3 "contiguous_bitmask_operand" "")))]
3848 "<z10_or_zEC12_cond>"
3849 "<risbg_n>\t%0,%1,%s3,128+%e3,%2" ; dst, src, start, end, shift
3850 [(set_attr "op_type" "RIE")
3851 (set_attr "z10prop" "z10_super_E1")])
3852
3853 (define_insn_and_split "*pre_z10_extzv<mode>"
3854 [(set (match_operand:GPR 0 "register_operand" "=d")
3855 (zero_extract:GPR (match_operand:QI 1 "s_operand" "S")
3856 (match_operand 2 "nonzero_shift_count_operand" "")
3857 (const_int 0)))
3858 (clobber (reg:CC CC_REGNUM))]
3859 "!TARGET_Z10"
3860 "#"
3861 "&& reload_completed"
3862 [(parallel
3863 [(set (match_dup 0) (unspec:GPR [(match_dup 1) (match_dup 3)] UNSPEC_ICM))
3864 (clobber (reg:CC CC_REGNUM))])
3865 (set (match_dup 0) (lshiftrt:GPR (match_dup 0) (match_dup 2)))]
3866 {
3867 int bitsize = INTVAL (operands[2]);
3868 int size = (bitsize - 1) / BITS_PER_UNIT + 1; /* round up */
3869 int mask = ((1ul << size) - 1) << (GET_MODE_SIZE (SImode) - size);
3870
3871 operands[1] = adjust_address (operands[1], BLKmode, 0);
3872 set_mem_size (operands[1], size);
3873 operands[2] = GEN_INT (<GPR:bitsize> - bitsize);
3874 operands[3] = GEN_INT (mask);
3875 })
3876
3877 (define_insn_and_split "*pre_z10_extv<mode>"
3878 [(set (match_operand:GPR 0 "register_operand" "=d")
3879 (sign_extract:GPR (match_operand:QI 1 "s_operand" "S")
3880 (match_operand 2 "nonzero_shift_count_operand" "")
3881 (const_int 0)))
3882 (clobber (reg:CC CC_REGNUM))]
3883 ""
3884 "#"
3885 "&& reload_completed"
3886 [(parallel
3887 [(set (match_dup 0) (unspec:GPR [(match_dup 1) (match_dup 3)] UNSPEC_ICM))
3888 (clobber (reg:CC CC_REGNUM))])
3889 (parallel
3890 [(set (match_dup 0) (ashiftrt:GPR (match_dup 0) (match_dup 2)))
3891 (clobber (reg:CC CC_REGNUM))])]
3892 {
3893 int bitsize = INTVAL (operands[2]);
3894 int size = (bitsize - 1) / BITS_PER_UNIT + 1; /* round up */
3895 int mask = ((1ul << size) - 1) << (GET_MODE_SIZE (SImode) - size);
3896
3897 operands[1] = adjust_address (operands[1], BLKmode, 0);
3898 set_mem_size (operands[1], size);
3899 operands[2] = GEN_INT (<GPR:bitsize> - bitsize);
3900 operands[3] = GEN_INT (mask);
3901 })
3902
3903 ;
3904 ; insv instruction patterns
3905 ;
3906
3907 (define_expand "insv"
3908 [(set (zero_extract (match_operand 0 "nonimmediate_operand" "")
3909 (match_operand 1 "const_int_operand" "")
3910 (match_operand 2 "const_int_operand" ""))
3911 (match_operand 3 "general_operand" ""))]
3912 ""
3913 {
3914 if (s390_expand_insv (operands[0], operands[1], operands[2], operands[3]))
3915 DONE;
3916 FAIL;
3917 })
3918
3919
3920 ; The normal RTL expansion will never generate a zero_extract where
3921 ; the location operand isn't word mode. However, we do this in the
3922 ; back-end when generating atomic operations. See s390_two_part_insv.
3923 (define_insn "*insv<mode><clobbercc_or_nocc>"
3924 [(set (zero_extract:GPR (match_operand:GPR 0 "nonimmediate_operand" "+d")
3925 (match_operand 1 "const_int_operand" "I") ; size
3926 (match_operand 2 "const_int_operand" "I")) ; pos
3927 (match_operand:GPR 3 "nonimmediate_operand" "d"))]
3928 "<z10_or_zEC12_cond>
3929 && EXTRACT_ARGS_IN_RANGE (INTVAL (operands[1]), INTVAL (operands[2]),
3930 GET_MODE_BITSIZE (<MODE>mode))
3931 && (INTVAL (operands[1]) + INTVAL (operands[2])) <= <bitsize>"
3932 "<risbg_n>\t%0,%3,<bitoff_plus>%2,<bitoff_plus>%2+%1-1,<bitsize>-%2-%1"
3933 [(set_attr "op_type" "RIE")
3934 (set_attr "z10prop" "z10_super_E1")])
3935
3936 ; and op1 with a mask being 1 for the selected bits and 0 for the rest
3937 ; and op3=op0 with a mask being 0 for the selected bits and 1 for the rest
3938 (define_insn "*insv<mode><clobbercc_or_nocc>_noshift"
3939 [(set (match_operand:GPR 0 "nonimmediate_operand" "=d,d")
3940 (ior:GPR (and:GPR (match_operand:GPR 1 "nonimmediate_operand" "d,0")
3941 (match_operand:GPR 2 "contiguous_bitmask_operand" ""))
3942 (and:GPR (match_operand:GPR 3 "nonimmediate_operand" "0,d")
3943 (match_operand:GPR 4 "const_int_operand" ""))))]
3944 "<z10_or_zEC12_cond> && INTVAL (operands[2]) == ~INTVAL (operands[4])"
3945 "@
3946 <risbg_n>\t%0,%1,%<bfstart>2,%<bfend>2,0
3947 <risbg_n>\t%0,%3,%<bfstart>4,%<bfend>4,0"
3948 [(set_attr "op_type" "RIE")
3949 (set_attr "z10prop" "z10_super_E1")])
3950
3951 (define_insn "*insv_z10_noshift_cc"
3952 [(set (reg CC_REGNUM)
3953 (compare
3954 (ior:DI
3955 (and:DI (match_operand:DI 1 "nonimmediate_operand" "d,0")
3956 (match_operand:DI 2 "contiguous_bitmask_operand" ""))
3957 (and:DI (match_operand:DI 3 "nonimmediate_operand" "0,d")
3958 (match_operand:DI 4 "const_int_operand" "")))
3959 (const_int 0)))
3960 (set (match_operand:DI 0 "nonimmediate_operand" "=d,d")
3961 (ior:DI (and:DI (match_dup 1) (match_dup 2))
3962 (and:DI (match_dup 3) (match_dup 4))))]
3963 "TARGET_Z10 && s390_match_ccmode (insn, CCSmode)
3964 && INTVAL (operands[2]) == ~INTVAL (operands[4])"
3965 "@
3966 risbg\t%0,%1,%s2,%e2,0
3967 risbg\t%0,%3,%s4,%e4,0"
3968 [(set_attr "op_type" "RIE")
3969 (set_attr "z10prop" "z10_super_E1")])
3970
3971 (define_insn "*insv_z10_noshift_cconly"
3972 [(set
3973 (reg CC_REGNUM)
3974 (compare
3975 (ior:DI
3976 (and:DI (match_operand:DI 1 "nonimmediate_operand" "d,0")
3977 (match_operand:DI 2 "contiguous_bitmask_operand" ""))
3978 (and:DI (match_operand:DI 3 "nonimmediate_operand" "0,d")
3979 (match_operand:DI 4 "const_int_operand" "")))
3980 (const_int 0)))
3981 (clobber (match_scratch:DI 0 "=d,d"))]
3982 "TARGET_Z10 && s390_match_ccmode (insn, CCSmode)
3983 && INTVAL (operands[2]) == ~INTVAL (operands[4])"
3984 "@
3985 risbg\t%0,%1,%s2,%e2,0
3986 risbg\t%0,%3,%s4,%e4,0"
3987 [(set_attr "op_type" "RIE")
3988 (set_attr "z10prop" "z10_super_E1")])
3989
3990 ; Implement appending Y on the left of S bits of X
3991 ; x = (y << s) | (x & ((1 << s) - 1))
3992 (define_insn "*insv<mode><clobbercc_or_nocc>_appendbitsleft"
3993 [(set (match_operand:GPR 0 "nonimmediate_operand" "=d")
3994 (ior:GPR (and:GPR (match_operand:GPR 1 "nonimmediate_operand" "0")
3995 (match_operand:GPR 2 "immediate_operand" ""))
3996 (ashift:GPR (match_operand:GPR 3 "nonimmediate_operand" "d")
3997 (match_operand:GPR 4 "nonzero_shift_count_operand" ""))))]
3998 "<z10_or_zEC12_cond>
3999 && UINTVAL (operands[2]) == (1UL << UINTVAL (operands[4])) - 1"
4000 "<risbg_n>\t%0,%3,<bitoff>,64-%4-1,%4"
4001 [(set_attr "op_type" "RIE")
4002 (set_attr "z10prop" "z10_super_E1")])
4003
4004 ; a = ((i32)a & -16777216) | (((ui32)b) >> 8)
4005 (define_insn "*<risbg_n>_<mode>_ior_and_lshiftrt"
4006 [(set (match_operand:GPR 0 "register_operand" "=d")
4007 (ior:GPR (and:GPR
4008 (match_operand:GPR 1 "register_operand" "0")
4009 (match_operand:GPR 2 "const_int_operand" ""))
4010 (lshiftrt:GPR
4011 (match_operand:GPR 3 "register_operand" "d")
4012 (match_operand:GPR 4 "nonzero_shift_count_operand" ""))))]
4013 "<z10_or_zEC12_cond> && UINTVAL (operands[2])
4014 == (~(0ULL) << (GET_MODE_BITSIZE (<MODE>mode) - UINTVAL (operands[4])))"
4015 "<risbg_n>\t%0,%3,<bitoff_plus>%4,63,64-%4"
4016 [(set_attr "op_type" "RIE")
4017 (set_attr "z10prop" "z10_super_E1")])
4018
4019 ; (ui32)(((ui64)x) >> 48) | ((i32)y & -65536);
4020 (define_insn "*<risbg_n>_sidi_ior_and_lshiftrt"
4021 [(set (match_operand:SI 0 "register_operand" "=d")
4022 (ior:SI (and:SI
4023 (match_operand:SI 1 "register_operand" "0")
4024 (match_operand:SI 2 "const_int_operand" ""))
4025 (subreg:SI
4026 (lshiftrt:DI
4027 (match_operand:DI 3 "register_operand" "d")
4028 (match_operand:DI 4 "nonzero_shift_count_operand" "")) 4)))]
4029 "<z10_or_zEC12_cond>
4030 && UINTVAL (operands[2]) == ~(~(0ULL) >> UINTVAL (operands[4]))"
4031 "<risbg_n>\t%0,%3,%4,63,64-%4"
4032 [(set_attr "op_type" "RIE")
4033 (set_attr "z10prop" "z10_super_E1")])
4034
4035 ; (ui32)(((ui64)x) >> 12) & -4
4036 (define_insn "*trunc_sidi_and_subreg_lshrt<clobbercc_or_nocc>"
4037 [(set (match_operand:SI 0 "register_operand" "=d")
4038 (and:SI
4039 (subreg:SI (lshiftrt:DI
4040 (match_operand:DI 1 "register_operand" "d")
4041 (match_operand:DI 2 "nonzero_shift_count_operand" "")) 4)
4042 (match_operand:SI 3 "contiguous_bitmask_nowrap_operand" "")))]
4043 "<z10_or_zEC12_cond>"
4044 "<risbg_n>\t%0,%1,%t3,128+%f3,64-%2"
4045 [(set_attr "op_type" "RIE")
4046 (set_attr "z10prop" "z10_super_E1")])
4047
4048 ; z = (x << c) | (y >> d) with (x << c) and (y >> d) not overlapping after shifting
4049 ; -> z = y >> d; z = (x << c) | (z & ((1 << c) - 1))
4050 ; -> z = y >> d; z = risbg;
4051
4052 (define_split
4053 [(set (match_operand:GPR 0 "nonimmediate_operand" "")
4054 (ior:GPR (lshiftrt:GPR (match_operand:GPR 1 "nonimmediate_operand" "")
4055 (match_operand:GPR 2 "nonzero_shift_count_operand" ""))
4056 (ashift:GPR (match_operand:GPR 3 "nonimmediate_operand" "")
4057 (match_operand:GPR 4 "nonzero_shift_count_operand" ""))))]
4058 "TARGET_ZEC12 && UINTVAL (operands[2]) + UINTVAL (operands[4]) >= <bitsize>"
4059 [(set (match_dup 6)
4060 (lshiftrt:GPR (match_dup 1) (match_dup 2)))
4061 (set (match_dup 0)
4062 (ior:GPR (and:GPR (match_dup 6) (match_dup 5))
4063 (ashift:GPR (match_dup 3) (match_dup 4))))]
4064 {
4065 operands[5] = GEN_INT ((1UL << UINTVAL (operands[4])) - 1);
4066 if (reg_overlap_mentioned_p (operands[0], operands[3]))
4067 {
4068 if (!can_create_pseudo_p ())
4069 FAIL;
4070 operands[6] = gen_reg_rtx (<MODE>mode);
4071 }
4072 else
4073 operands[6] = operands[0];
4074 })
4075
4076 (define_split
4077 [(parallel
4078 [(set (match_operand:GPR 0 "nonimmediate_operand" "")
4079 (ior:GPR (lshiftrt:GPR (match_operand:GPR 1 "nonimmediate_operand" "")
4080 (match_operand:GPR 2 "nonzero_shift_count_operand" ""))
4081 (ashift:GPR (match_operand:GPR 3 "nonimmediate_operand" "")
4082 (match_operand:GPR 4 "nonzero_shift_count_operand" ""))))
4083 (clobber (reg:CC CC_REGNUM))])]
4084 "TARGET_Z10 && !TARGET_ZEC12 && UINTVAL (operands[2]) + UINTVAL (operands[4]) >= <bitsize>"
4085 [(set (match_dup 6)
4086 (lshiftrt:GPR (match_dup 1) (match_dup 2)))
4087 (parallel
4088 [(set (match_dup 0)
4089 (ior:GPR (and:GPR (match_dup 6) (match_dup 5))
4090 (ashift:GPR (match_dup 3) (match_dup 4))))
4091 (clobber (reg:CC CC_REGNUM))])]
4092 {
4093 operands[5] = GEN_INT ((1UL << UINTVAL (operands[4])) - 1);
4094 if (reg_overlap_mentioned_p (operands[0], operands[3]))
4095 {
4096 if (!can_create_pseudo_p ())
4097 FAIL;
4098 operands[6] = gen_reg_rtx (<MODE>mode);
4099 }
4100 else
4101 operands[6] = operands[0];
4102 })
4103
4104 (define_insn "*r<noxa>sbg_<mode>_noshift"
4105 [(set (match_operand:GPR 0 "nonimmediate_operand" "=d")
4106 (IXOR:GPR
4107 (and:GPR (match_operand:GPR 1 "nonimmediate_operand" "d")
4108 (match_operand:GPR 2 "contiguous_bitmask_operand" ""))
4109 (match_operand:GPR 3 "nonimmediate_operand" "0")))
4110 (clobber (reg:CC CC_REGNUM))]
4111 "TARGET_Z10"
4112 "r<noxa>sbg\t%0,%1,%<bfstart>2,%<bfend>2,0"
4113 [(set_attr "op_type" "RIE")])
4114
4115 (define_insn "*r<noxa>sbg_di_rotl"
4116 [(set (match_operand:DI 0 "nonimmediate_operand" "=d")
4117 (IXOR:DI
4118 (and:DI
4119 (rotate:DI
4120 (match_operand:DI 1 "nonimmediate_operand" "d")
4121 (match_operand:DI 3 "const_int_operand" ""))
4122 (match_operand:DI 2 "contiguous_bitmask_operand" ""))
4123 (match_operand:DI 4 "nonimmediate_operand" "0")))
4124 (clobber (reg:CC CC_REGNUM))]
4125 "TARGET_Z10"
4126 "r<noxa>sbg\t%0,%1,%<bfstart>2,%<bfend>2,%b3"
4127 [(set_attr "op_type" "RIE")])
4128
4129 (define_insn "*r<noxa>sbg_<mode>_srl_bitmask"
4130 [(set (match_operand:GPR 0 "nonimmediate_operand" "=d")
4131 (IXOR:GPR
4132 (and:GPR
4133 (lshiftrt:GPR
4134 (match_operand:GPR 1 "nonimmediate_operand" "d")
4135 (match_operand:GPR 3 "nonzero_shift_count_operand" ""))
4136 (match_operand:GPR 2 "contiguous_bitmask_operand" ""))
4137 (match_operand:GPR 4 "nonimmediate_operand" "0")))
4138 (clobber (reg:CC CC_REGNUM))]
4139 "TARGET_Z10
4140 && s390_extzv_shift_ok (<bitsize>, 64 - INTVAL (operands[3]),
4141 INTVAL (operands[2]))"
4142 "r<noxa>sbg\t%0,%1,%<bfstart>2,%<bfend>2,64-%3"
4143 [(set_attr "op_type" "RIE")])
4144
4145 (define_insn "*r<noxa>sbg_<mode>_sll_bitmask"
4146 [(set (match_operand:GPR 0 "nonimmediate_operand" "=d")
4147 (IXOR:GPR
4148 (and:GPR
4149 (ashift:GPR
4150 (match_operand:GPR 1 "nonimmediate_operand" "d")
4151 (match_operand:GPR 3 "nonzero_shift_count_operand" ""))
4152 (match_operand:GPR 2 "contiguous_bitmask_operand" ""))
4153 (match_operand:GPR 4 "nonimmediate_operand" "0")))
4154 (clobber (reg:CC CC_REGNUM))]
4155 "TARGET_Z10
4156 && s390_extzv_shift_ok (<bitsize>, INTVAL (operands[3]),
4157 INTVAL (operands[2]))"
4158 "r<noxa>sbg\t%0,%1,%<bfstart>2,%<bfend>2,%3"
4159 [(set_attr "op_type" "RIE")])
4160
4161 ;; unsigned {int,long} a, b
4162 ;; a = a | (b << const_int)
4163 ;; a = a ^ (b << const_int)
4164 (define_insn "*r<noxa>sbg_<mode>_sll"
4165 [(set (match_operand:GPR 0 "nonimmediate_operand" "=d")
4166 (IXOR:GPR
4167 (ashift:GPR
4168 (match_operand:GPR 1 "nonimmediate_operand" "d")
4169 (match_operand:GPR 2 "nonzero_shift_count_operand" ""))
4170 (match_operand:GPR 3 "nonimmediate_operand" "0")))
4171 (clobber (reg:CC CC_REGNUM))]
4172 "TARGET_Z10"
4173 "r<noxa>sbg\t%0,%1,<bitoff>,63-%2,%2"
4174 [(set_attr "op_type" "RIE")])
4175
4176 ;; unsigned {int,long} a, b
4177 ;; a = a | (b >> const_int)
4178 ;; a = a ^ (b >> const_int)
4179 (define_insn "*r<noxa>sbg_<mode>_srl"
4180 [(set (match_operand:GPR 0 "nonimmediate_operand" "=d")
4181 (IXOR:GPR
4182 (lshiftrt:GPR
4183 (match_operand:GPR 1 "nonimmediate_operand" "d")
4184 (match_operand:GPR 2 "nonzero_shift_count_operand" ""))
4185 (match_operand:GPR 3 "nonimmediate_operand" "0")))
4186 (clobber (reg:CC CC_REGNUM))]
4187 "TARGET_Z10"
4188 "r<noxa>sbg\t%0,%1,<bitoff_plus>%2,63,64-%2"
4189 [(set_attr "op_type" "RIE")])
4190
4191 ;; These two are generated by combine for s.bf &= val.
4192 ;; ??? For bitfields smaller than 32-bits, we wind up with SImode
4193 ;; shifts and ands, which results in some truly awful patterns
4194 ;; including subregs of operations. Rather unnecessisarily, IMO.
4195 ;; Instead of
4196 ;;
4197 ;; (set (zero_extract:DI (reg/v:DI 50 [ s ])
4198 ;; (const_int 24 [0x18])
4199 ;; (const_int 0 [0]))
4200 ;; (subreg:DI (and:SI (subreg:SI (lshiftrt:DI (reg/v:DI 50 [ s ])
4201 ;; (const_int 40 [0x28])) 4)
4202 ;; (reg:SI 4 %r4 [ y+4 ])) 0))
4203 ;;
4204 ;; we should instead generate
4205 ;;
4206 ;; (set (zero_extract:DI (reg/v:DI 50 [ s ])
4207 ;; (const_int 24 [0x18])
4208 ;; (const_int 0 [0]))
4209 ;; (and:DI (lshiftrt:DI (reg/v:DI 50 [ s ])
4210 ;; (const_int 40 [0x28]))
4211 ;; (subreg:DI (reg:SI 4 %r4 [ y+4 ]) 0)))
4212 ;;
4213 ;; by noticing that we can push down the outer paradoxical subreg
4214 ;; into the operation.
4215
4216 (define_insn "*insv_rnsbg_noshift"
4217 [(set (zero_extract:DI
4218 (match_operand:DI 0 "nonimmediate_operand" "+d")
4219 (match_operand 1 "const_int_operand" "")
4220 (match_operand 2 "const_int_operand" ""))
4221 (and:DI
4222 (match_dup 0)
4223 (match_operand:DI 3 "nonimmediate_operand" "d")))
4224 (clobber (reg:CC CC_REGNUM))]
4225 "TARGET_Z10
4226 && EXTRACT_ARGS_IN_RANGE (INTVAL (operands[1]), INTVAL (operands[2]), 64)
4227 && INTVAL (operands[1]) + INTVAL (operands[2]) == 64"
4228 "rnsbg\t%0,%3,%2,63,0"
4229 [(set_attr "op_type" "RIE")])
4230
4231 (define_insn "*insv_rnsbg_srl"
4232 [(set (zero_extract:DI
4233 (match_operand:DI 0 "nonimmediate_operand" "+d")
4234 (match_operand 1 "const_int_operand" "")
4235 (match_operand 2 "const_int_operand" ""))
4236 (and:DI
4237 (lshiftrt:DI
4238 (match_dup 0)
4239 (match_operand 3 "const_int_operand" ""))
4240 (match_operand:DI 4 "nonimmediate_operand" "d")))
4241 (clobber (reg:CC CC_REGNUM))]
4242 "TARGET_Z10
4243 && EXTRACT_ARGS_IN_RANGE (INTVAL (operands[1]), INTVAL (operands[2]), 64)
4244 && INTVAL (operands[3]) == 64 - INTVAL (operands[1]) - INTVAL (operands[2])"
4245 "rnsbg\t%0,%4,%2,%2+%1-1,%3"
4246 [(set_attr "op_type" "RIE")])
4247
4248 (define_insn "*insv<mode>_mem_reg"
4249 [(set (zero_extract:W (match_operand:QI 0 "memory_operand" "+Q,S")
4250 (match_operand 1 "const_int_operand" "n,n")
4251 (const_int 0))
4252 (match_operand:W 2 "register_operand" "d,d"))]
4253 "EXTRACT_ARGS_IN_RANGE (INTVAL (operands[1]), 0, 64)
4254 && INTVAL (operands[1]) > 0
4255 && INTVAL (operands[1]) <= GET_MODE_BITSIZE (SImode)
4256 && INTVAL (operands[1]) % BITS_PER_UNIT == 0"
4257 {
4258 int size = INTVAL (operands[1]) / BITS_PER_UNIT;
4259
4260 operands[1] = GEN_INT ((1ul << size) - 1);
4261 return (which_alternative == 0) ? "stcm\t%2,%1,%S0"
4262 : "stcmy\t%2,%1,%S0";
4263 }
4264 [(set_attr "op_type" "RS,RSY")
4265 (set_attr "cpu_facility" "*,longdisp")
4266 (set_attr "z10prop" "z10_super,z10_super")])
4267
4268 (define_insn "*insvdi_mem_reghigh"
4269 [(set (zero_extract:DI (match_operand:QI 0 "memory_operand" "+S")
4270 (match_operand 1 "const_int_operand" "n")
4271 (const_int 0))
4272 (lshiftrt:DI (match_operand:DI 2 "register_operand" "d")
4273 (const_int 32)))]
4274 "TARGET_ZARCH
4275 && EXTRACT_ARGS_IN_RANGE (INTVAL (operands[1]), 0, 64)
4276 && INTVAL (operands[1]) > 0
4277 && INTVAL (operands[1]) <= GET_MODE_BITSIZE (SImode)
4278 && INTVAL (operands[1]) % BITS_PER_UNIT == 0"
4279 {
4280 int size = INTVAL (operands[1]) / BITS_PER_UNIT;
4281
4282 operands[1] = GEN_INT ((1ul << size) - 1);
4283 return "stcmh\t%2,%1,%S0";
4284 }
4285 [(set_attr "op_type" "RSY")
4286 (set_attr "z10prop" "z10_super")])
4287
4288 (define_insn "*insvdi_reg_imm"
4289 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+d")
4290 (const_int 16)
4291 (match_operand 1 "const_int_operand" "n"))
4292 (match_operand:DI 2 "const_int_operand" "n"))]
4293 "TARGET_ZARCH
4294 && EXTRACT_ARGS_IN_RANGE (16, INTVAL (operands[1]), 64)
4295 && INTVAL (operands[1]) >= 0
4296 && INTVAL (operands[1]) < BITS_PER_WORD
4297 && INTVAL (operands[1]) % 16 == 0"
4298 {
4299 switch (BITS_PER_WORD - INTVAL (operands[1]))
4300 {
4301 case 64: return "iihh\t%0,%x2"; break;
4302 case 48: return "iihl\t%0,%x2"; break;
4303 case 32: return "iilh\t%0,%x2"; break;
4304 case 16: return "iill\t%0,%x2"; break;
4305 default: gcc_unreachable();
4306 }
4307 }
4308 [(set_attr "op_type" "RI")
4309 (set_attr "z10prop" "z10_super_E1")])
4310
4311 ; Update the left-most 32 bit of a DI.
4312 (define_insn "*insv_h_di_reg_extimm"
4313 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+d")
4314 (const_int 32)
4315 (const_int 0))
4316 (match_operand:DI 1 "const_int_operand" "n"))]
4317 "TARGET_EXTIMM"
4318 "iihf\t%0,%o1"
4319 [(set_attr "op_type" "RIL")
4320 (set_attr "z10prop" "z10_fwd_E1")])
4321
4322 ; Update the right-most 32 bit of a DI.
4323 (define_insn "*insv_l_di_reg_extimm"
4324 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+d")
4325 (const_int 32)
4326 (const_int 32))
4327 (match_operand:DI 1 "const_int_operand" "n"))]
4328 "TARGET_EXTIMM"
4329 "iilf\t%0,%o1"
4330 [(set_attr "op_type" "RIL")
4331 (set_attr "z10prop" "z10_fwd_A1")])
4332
4333 ;
4334 ; extendsidi2 instruction pattern(s).
4335 ;
4336
4337 (define_expand "extendsidi2"
4338 [(set (match_operand:DI 0 "register_operand" "")
4339 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "")))]
4340 ""
4341 {
4342 if (!TARGET_ZARCH)
4343 {
4344 emit_clobber (operands[0]);
4345 emit_move_insn (gen_highpart (SImode, operands[0]), operands[1]);
4346 emit_move_insn (gen_lowpart (SImode, operands[0]), const0_rtx);
4347 emit_insn (gen_ashrdi3 (operands[0], operands[0], GEN_INT (32)));
4348 DONE;
4349 }
4350 })
4351
4352 (define_insn "*extendsidi2"
4353 [(set (match_operand:DI 0 "register_operand" "=d,d,d")
4354 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "d,T,b")))]
4355 "TARGET_ZARCH"
4356 "@
4357 lgfr\t%0,%1
4358 lgf\t%0,%1
4359 lgfrl\t%0,%1"
4360 [(set_attr "op_type" "RRE,RXY,RIL")
4361 (set_attr "type" "*,*,larl")
4362 (set_attr "cpu_facility" "*,*,z10")
4363 (set_attr "z10prop" "z10_super_E1,z10_super_E1,z10_super_E1")])
4364
4365 ;
4366 ; extend(hi|qi)(si|di)2 instruction pattern(s).
4367 ;
4368
4369 (define_expand "extend<HQI:mode><DSI:mode>2"
4370 [(set (match_operand:DSI 0 "register_operand" "")
4371 (sign_extend:DSI (match_operand:HQI 1 "nonimmediate_operand" "")))]
4372 ""
4373 {
4374 if (<DSI:MODE>mode == DImode && !TARGET_ZARCH)
4375 {
4376 rtx tmp = gen_reg_rtx (SImode);
4377 emit_insn (gen_extend<HQI:mode>si2 (tmp, operands[1]));
4378 emit_insn (gen_extendsidi2 (operands[0], tmp));
4379 DONE;
4380 }
4381 else if (!TARGET_EXTIMM)
4382 {
4383 rtx bitcount = GEN_INT (<DSI:bitsize> - <HQI:bitsize>);
4384
4385 operands[1] = gen_lowpart (<DSI:MODE>mode, operands[1]);
4386 emit_insn (gen_ashl<DSI:mode>3 (operands[0], operands[1], bitcount));
4387 emit_insn (gen_ashr<DSI:mode>3 (operands[0], operands[0], bitcount));
4388 DONE;
4389 }
4390 })
4391
4392 ;
4393 ; extendhidi2 instruction pattern(s).
4394 ;
4395
4396 (define_insn "*extendhidi2_extimm"
4397 [(set (match_operand:DI 0 "register_operand" "=d,d,d")
4398 (sign_extend:DI (match_operand:HI 1 "general_operand" "d,T,b")))]
4399 "TARGET_ZARCH && TARGET_EXTIMM"
4400 "@
4401 lghr\t%0,%1
4402 lgh\t%0,%1
4403 lghrl\t%0,%1"
4404 [(set_attr "op_type" "RRE,RXY,RIL")
4405 (set_attr "type" "*,*,larl")
4406 (set_attr "cpu_facility" "extimm,extimm,z10")
4407 (set_attr "z10prop" "z10_super_E1,z10_super_E1,z10_super_E1")])
4408
4409 (define_insn "*extendhidi2"
4410 [(set (match_operand:DI 0 "register_operand" "=d")
4411 (sign_extend:DI (match_operand:HI 1 "memory_operand" "T")))]
4412 "TARGET_ZARCH"
4413 "lgh\t%0,%1"
4414 [(set_attr "op_type" "RXY")
4415 (set_attr "z10prop" "z10_super_E1")])
4416
4417 ;
4418 ; extendhisi2 instruction pattern(s).
4419 ;
4420
4421 (define_insn "*extendhisi2_extimm"
4422 [(set (match_operand:SI 0 "register_operand" "=d,d,d,d")
4423 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" " d,R,T,b")))]
4424 "TARGET_EXTIMM"
4425 "@
4426 lhr\t%0,%1
4427 lh\t%0,%1
4428 lhy\t%0,%1
4429 lhrl\t%0,%1"
4430 [(set_attr "op_type" "RRE,RX,RXY,RIL")
4431 (set_attr "type" "*,*,*,larl")
4432 (set_attr "cpu_facility" "extimm,extimm,extimm,z10")
4433 (set_attr "z10prop" "z10_super_E1,z10_super_E1,z10_super_E1,z10_super_E1")])
4434
4435 (define_insn "*extendhisi2"
4436 [(set (match_operand:SI 0 "register_operand" "=d,d")
4437 (sign_extend:SI (match_operand:HI 1 "memory_operand" "R,T")))]
4438 "!TARGET_EXTIMM"
4439 "@
4440 lh\t%0,%1
4441 lhy\t%0,%1"
4442 [(set_attr "op_type" "RX,RXY")
4443 (set_attr "cpu_facility" "*,longdisp")
4444 (set_attr "z10prop" "z10_super_E1,z10_super_E1")])
4445
4446 ;
4447 ; extendqi(si|di)2 instruction pattern(s).
4448 ;
4449
4450 ; lbr, lgbr, lb, lgb
4451 (define_insn "*extendqi<mode>2_extimm"
4452 [(set (match_operand:GPR 0 "register_operand" "=d,d")
4453 (sign_extend:GPR (match_operand:QI 1 "nonimmediate_operand" "d,T")))]
4454 "TARGET_EXTIMM"
4455 "@
4456 l<g>br\t%0,%1
4457 l<g>b\t%0,%1"
4458 [(set_attr "op_type" "RRE,RXY")
4459 (set_attr "z10prop" "z10_super_E1,z10_super_E1")])
4460
4461 ; lb, lgb
4462 (define_insn "*extendqi<mode>2"
4463 [(set (match_operand:GPR 0 "register_operand" "=d")
4464 (sign_extend:GPR (match_operand:QI 1 "memory_operand" "T")))]
4465 "!TARGET_EXTIMM && TARGET_LONG_DISPLACEMENT"
4466 "l<g>b\t%0,%1"
4467 [(set_attr "op_type" "RXY")
4468 (set_attr "z10prop" "z10_super_E1")])
4469
4470 (define_insn_and_split "*extendqi<mode>2_short_displ"
4471 [(set (match_operand:GPR 0 "register_operand" "=d")
4472 (sign_extend:GPR (match_operand:QI 1 "s_operand" "Q")))
4473 (clobber (reg:CC CC_REGNUM))]
4474 "!TARGET_EXTIMM && !TARGET_LONG_DISPLACEMENT"
4475 "#"
4476 "&& reload_completed"
4477 [(parallel
4478 [(set (match_dup 0) (unspec:GPR [(match_dup 1) (const_int 8)] UNSPEC_ICM))
4479 (clobber (reg:CC CC_REGNUM))])
4480 (parallel
4481 [(set (match_dup 0) (ashiftrt:GPR (match_dup 0) (match_dup 2)))
4482 (clobber (reg:CC CC_REGNUM))])]
4483 {
4484 operands[1] = adjust_address (operands[1], BLKmode, 0);
4485 set_mem_size (operands[1], GET_MODE_SIZE (QImode));
4486 operands[2] = GEN_INT (<GPR:bitsize> - BITS_PER_UNIT);
4487 })
4488
4489 ;
4490 ; zero_extendsidi2 instruction pattern(s).
4491 ;
4492
4493 (define_expand "zero_extendsidi2"
4494 [(set (match_operand:DI 0 "register_operand" "")
4495 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "")))]
4496 ""
4497 {
4498 if (!TARGET_ZARCH)
4499 {
4500 emit_clobber (operands[0]);
4501 emit_move_insn (gen_lowpart (SImode, operands[0]), operands[1]);
4502 emit_move_insn (gen_highpart (SImode, operands[0]), const0_rtx);
4503 DONE;
4504 }
4505 })
4506
4507 (define_insn "*zero_extendsidi2"
4508 [(set (match_operand:DI 0 "register_operand" "=d,d,d")
4509 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "d,T,b")))]
4510 "TARGET_ZARCH"
4511 "@
4512 llgfr\t%0,%1
4513 llgf\t%0,%1
4514 llgfrl\t%0,%1"
4515 [(set_attr "op_type" "RRE,RXY,RIL")
4516 (set_attr "type" "*,*,larl")
4517 (set_attr "cpu_facility" "*,*,z10")
4518 (set_attr "z10prop" "z10_fwd_E1,z10_fwd_A3,z10_fwd_A3")])
4519
4520 ;
4521 ; LLGT-type instructions (zero-extend from 31 bit to 64 bit).
4522 ;
4523
4524 (define_insn "*llgt_sidi"
4525 [(set (match_operand:DI 0 "register_operand" "=d")
4526 (and:DI (subreg:DI (match_operand:SI 1 "memory_operand" "T") 0)
4527 (const_int 2147483647)))]
4528 "TARGET_ZARCH"
4529 "llgt\t%0,%1"
4530 [(set_attr "op_type" "RXE")
4531 (set_attr "z10prop" "z10_super_E1")])
4532
4533 (define_insn_and_split "*llgt_sidi_split"
4534 [(set (match_operand:DI 0 "register_operand" "=d")
4535 (and:DI (subreg:DI (match_operand:SI 1 "memory_operand" "T") 0)
4536 (const_int 2147483647)))
4537 (clobber (reg:CC CC_REGNUM))]
4538 "TARGET_ZARCH"
4539 "#"
4540 "&& reload_completed"
4541 [(set (match_dup 0)
4542 (and:DI (subreg:DI (match_dup 1) 0)
4543 (const_int 2147483647)))]
4544 "")
4545
4546 (define_insn "*llgt_sisi"
4547 [(set (match_operand:SI 0 "register_operand" "=d,d")
4548 (and:SI (match_operand:SI 1 "nonimmediate_operand" "d,T")
4549 (const_int 2147483647)))]
4550 "TARGET_ZARCH"
4551 "@
4552 llgtr\t%0,%1
4553 llgt\t%0,%1"
4554 [(set_attr "op_type" "RRE,RXE")
4555 (set_attr "z10prop" "z10_super_E1,z10_super_E1")])
4556
4557 (define_insn "*llgt_didi"
4558 [(set (match_operand:DI 0 "register_operand" "=d,d")
4559 (and:DI (match_operand:DI 1 "nonimmediate_operand" "d,o")
4560 (const_int 2147483647)))]
4561 "TARGET_ZARCH"
4562 "@
4563 llgtr\t%0,%1
4564 llgt\t%0,%N1"
4565 [(set_attr "op_type" "RRE,RXE")
4566 (set_attr "z10prop" "z10_super_E1,z10_super_E1")])
4567
4568 (define_split
4569 [(set (match_operand:DSI 0 "register_operand" "")
4570 (and:DSI (match_operand:DSI 1 "nonimmediate_operand" "")
4571 (const_int 2147483647)))
4572 (clobber (reg:CC CC_REGNUM))]
4573 "TARGET_ZARCH && reload_completed"
4574 [(set (match_dup 0)
4575 (and:DSI (match_dup 1)
4576 (const_int 2147483647)))]
4577 "")
4578
4579 ;
4580 ; zero_extend(hi|qi)(si|di)2 instruction pattern(s).
4581 ;
4582
4583 (define_expand "zero_extend<mode>di2"
4584 [(set (match_operand:DI 0 "register_operand" "")
4585 (zero_extend:DI (match_operand:HQI 1 "nonimmediate_operand" "")))]
4586 ""
4587 {
4588 if (!TARGET_ZARCH)
4589 {
4590 rtx tmp = gen_reg_rtx (SImode);
4591 emit_insn (gen_zero_extend<mode>si2 (tmp, operands[1]));
4592 emit_insn (gen_zero_extendsidi2 (operands[0], tmp));
4593 DONE;
4594 }
4595 else if (!TARGET_EXTIMM)
4596 {
4597 rtx bitcount = GEN_INT (64 - <HQI:bitsize>);
4598 operands[1] = gen_lowpart (DImode, operands[1]);
4599 emit_insn (gen_ashldi3 (operands[0], operands[1], bitcount));
4600 emit_insn (gen_lshrdi3 (operands[0], operands[0], bitcount));
4601 DONE;
4602 }
4603 })
4604
4605 (define_expand "zero_extend<mode>si2"
4606 [(set (match_operand:SI 0 "register_operand" "")
4607 (zero_extend:SI (match_operand:HQI 1 "nonimmediate_operand" "")))]
4608 ""
4609 {
4610 if (!TARGET_EXTIMM)
4611 {
4612 operands[1] = gen_lowpart (SImode, operands[1]);
4613 emit_insn (gen_andsi3 (operands[0], operands[1],
4614 GEN_INT ((1 << <HQI:bitsize>) - 1)));
4615 DONE;
4616 }
4617 })
4618
4619 ; llhrl, llghrl
4620 (define_insn "*zero_extendhi<mode>2_z10"
4621 [(set (match_operand:GPR 0 "register_operand" "=d,d,d")
4622 (zero_extend:GPR (match_operand:HI 1 "nonimmediate_operand" "d,T,b")))]
4623 "TARGET_Z10"
4624 "@
4625 ll<g>hr\t%0,%1
4626 ll<g>h\t%0,%1
4627 ll<g>hrl\t%0,%1"
4628 [(set_attr "op_type" "RXY,RRE,RIL")
4629 (set_attr "type" "*,*,larl")
4630 (set_attr "cpu_facility" "*,*,z10")
4631 (set_attr "z10prop" "z10_super_E1,z10_fwd_A3,z10_fwd_A3")])
4632
4633 ; llhr, llcr, llghr, llgcr, llh, llc, llgh, llgc
4634 (define_insn "*zero_extend<HQI:mode><GPR:mode>2_extimm"
4635 [(set (match_operand:GPR 0 "register_operand" "=d,d")
4636 (zero_extend:GPR (match_operand:HQI 1 "nonimmediate_operand" "d,T")))]
4637 "TARGET_EXTIMM"
4638 "@
4639 ll<g><hc>r\t%0,%1
4640 ll<g><hc>\t%0,%1"
4641 [(set_attr "op_type" "RRE,RXY")
4642 (set_attr "z10prop" "z10_super_E1,z10_fwd_A3")])
4643
4644 ; llgh, llgc
4645 (define_insn "*zero_extend<HQI:mode><GPR:mode>2"
4646 [(set (match_operand:GPR 0 "register_operand" "=d")
4647 (zero_extend:GPR (match_operand:HQI 1 "memory_operand" "T")))]
4648 "TARGET_ZARCH && !TARGET_EXTIMM"
4649 "llg<hc>\t%0,%1"
4650 [(set_attr "op_type" "RXY")
4651 (set_attr "z10prop" "z10_fwd_A3")])
4652
4653 (define_insn_and_split "*zero_extendhisi2_31"
4654 [(set (match_operand:SI 0 "register_operand" "=&d")
4655 (zero_extend:SI (match_operand:HI 1 "s_operand" "S")))
4656 (clobber (reg:CC CC_REGNUM))]
4657 "!TARGET_ZARCH"
4658 "#"
4659 "&& reload_completed"
4660 [(set (match_dup 0) (const_int 0))
4661 (parallel
4662 [(set (strict_low_part (match_dup 2)) (match_dup 1))
4663 (clobber (reg:CC CC_REGNUM))])]
4664 "operands[2] = gen_lowpart (HImode, operands[0]);")
4665
4666 (define_insn_and_split "*zero_extendqisi2_31"
4667 [(set (match_operand:SI 0 "register_operand" "=&d")
4668 (zero_extend:SI (match_operand:QI 1 "memory_operand" "T")))]
4669 "!TARGET_ZARCH"
4670 "#"
4671 "&& reload_completed"
4672 [(set (match_dup 0) (const_int 0))
4673 (set (strict_low_part (match_dup 2)) (match_dup 1))]
4674 "operands[2] = gen_lowpart (QImode, operands[0]);")
4675
4676 ;
4677 ; zero_extendqihi2 instruction pattern(s).
4678 ;
4679
4680 (define_expand "zero_extendqihi2"
4681 [(set (match_operand:HI 0 "register_operand" "")
4682 (zero_extend:HI (match_operand:QI 1 "register_operand" "")))]
4683 "TARGET_ZARCH && !TARGET_EXTIMM"
4684 {
4685 operands[1] = gen_lowpart (HImode, operands[1]);
4686 emit_insn (gen_andhi3 (operands[0], operands[1], GEN_INT (0xff)));
4687 DONE;
4688 })
4689
4690 (define_insn "*zero_extendqihi2_64"
4691 [(set (match_operand:HI 0 "register_operand" "=d")
4692 (zero_extend:HI (match_operand:QI 1 "memory_operand" "T")))]
4693 "TARGET_ZARCH && !TARGET_EXTIMM"
4694 "llgc\t%0,%1"
4695 [(set_attr "op_type" "RXY")
4696 (set_attr "z10prop" "z10_fwd_A3")])
4697
4698 (define_insn_and_split "*zero_extendqihi2_31"
4699 [(set (match_operand:HI 0 "register_operand" "=&d")
4700 (zero_extend:HI (match_operand:QI 1 "memory_operand" "T")))]
4701 "!TARGET_ZARCH"
4702 "#"
4703 "&& reload_completed"
4704 [(set (match_dup 0) (const_int 0))
4705 (set (strict_low_part (match_dup 2)) (match_dup 1))]
4706 "operands[2] = gen_lowpart (QImode, operands[0]);")
4707
4708 ;
4709 ; fixuns_trunc(dd|td)di2 instruction pattern(s).
4710 ;
4711
4712 (define_expand "fixuns_truncdddi2"
4713 [(parallel
4714 [(set (match_operand:DI 0 "register_operand" "")
4715 (unsigned_fix:DI (match_operand:DD 1 "register_operand" "")))
4716 (unspec:DI [(const_int DFP_RND_TOWARD_0)] UNSPEC_ROUND)
4717 (clobber (reg:CC CC_REGNUM))])]
4718
4719 "TARGET_HARD_DFP"
4720 {
4721 if (!TARGET_Z196)
4722 {
4723 rtx_code_label *label1 = gen_label_rtx ();
4724 rtx_code_label *label2 = gen_label_rtx ();
4725 rtx temp = gen_reg_rtx (TDmode);
4726 REAL_VALUE_TYPE cmp, sub;
4727
4728 decimal_real_from_string (&cmp, "9223372036854775808.0"); /* 2^63 */
4729 decimal_real_from_string (&sub, "18446744073709551616.0"); /* 2^64 */
4730
4731 /* 2^63 can't be represented as 64bit DFP number with full precision. The
4732 solution is doing the check and the subtraction in TD mode and using a
4733 TD -> DI convert afterwards. */
4734 emit_insn (gen_extendddtd2 (temp, operands[1]));
4735 temp = force_reg (TDmode, temp);
4736 emit_cmp_and_jump_insns (temp,
4737 const_double_from_real_value (cmp, TDmode),
4738 LT, NULL_RTX, VOIDmode, 0, label1);
4739 emit_insn (gen_subtd3 (temp, temp,
4740 const_double_from_real_value (sub, TDmode)));
4741 emit_insn (gen_fix_trunctddi2_dfp (operands[0], temp,
4742 GEN_INT (DFP_RND_TOWARD_MINF)));
4743 emit_jump (label2);
4744
4745 emit_label (label1);
4746 emit_insn (gen_fix_truncdddi2_dfp (operands[0], operands[1],
4747 GEN_INT (DFP_RND_TOWARD_0)));
4748 emit_label (label2);
4749 DONE;
4750 }
4751 })
4752
4753 (define_expand "fixuns_trunctddi2"
4754 [(parallel
4755 [(set (match_operand:DI 0 "register_operand" "")
4756 (unsigned_fix:DI (match_operand:TD 1 "register_operand" "")))
4757 (unspec:DI [(const_int DFP_RND_TOWARD_0)] UNSPEC_ROUND)
4758 (clobber (reg:CC CC_REGNUM))])]
4759
4760 "TARGET_HARD_DFP"
4761 {
4762 if (!TARGET_Z196)
4763 {
4764 rtx_code_label *label1 = gen_label_rtx ();
4765 rtx_code_label *label2 = gen_label_rtx ();
4766 rtx temp = gen_reg_rtx (TDmode);
4767 REAL_VALUE_TYPE cmp, sub;
4768
4769 operands[1] = force_reg (TDmode, operands[1]);
4770 decimal_real_from_string (&cmp, "9223372036854775808.0"); /* 2^63 */
4771 decimal_real_from_string (&sub, "18446744073709551616.0"); /* 2^64 */
4772
4773 emit_cmp_and_jump_insns (operands[1],
4774 const_double_from_real_value (cmp, TDmode),
4775 LT, NULL_RTX, VOIDmode, 0, label1);
4776 emit_insn (gen_subtd3 (temp, operands[1],
4777 const_double_from_real_value (sub, TDmode)));
4778 emit_insn (gen_fix_trunctddi2_dfp (operands[0], temp,
4779 GEN_INT (DFP_RND_TOWARD_MINF)));
4780 emit_jump (label2);
4781
4782 emit_label (label1);
4783 emit_insn (gen_fix_trunctddi2_dfp (operands[0], operands[1],
4784 GEN_INT (DFP_RND_TOWARD_0)));
4785 emit_label (label2);
4786 DONE;
4787 }
4788 })
4789
4790 ;
4791 ; fixuns_trunc(sf|df|tf)(si|di)2 and fix_trunc(sf|df|tf)(si|di)2
4792 ; instruction pattern(s).
4793 ;
4794
4795 (define_expand "fixuns_trunc<BFP:mode><GPR:mode>2"
4796 [(parallel
4797 [(set (match_operand:GPR 0 "register_operand" "")
4798 (unsigned_fix:GPR (match_operand:BFP 1 "register_operand" "")))
4799 (unspec:GPR [(const_int BFP_RND_TOWARD_0)] UNSPEC_ROUND)
4800 (clobber (reg:CC CC_REGNUM))])]
4801 "TARGET_HARD_FLOAT"
4802 {
4803 if (!TARGET_Z196)
4804 {
4805 rtx_code_label *label1 = gen_label_rtx ();
4806 rtx_code_label *label2 = gen_label_rtx ();
4807 rtx temp = gen_reg_rtx (<BFP:MODE>mode);
4808 REAL_VALUE_TYPE cmp, sub;
4809
4810 operands[1] = force_reg (<BFP:MODE>mode, operands[1]);
4811 real_2expN (&cmp, <GPR:bitsize> - 1, <BFP:MODE>mode);
4812 real_2expN (&sub, <GPR:bitsize>, <BFP:MODE>mode);
4813
4814 emit_cmp_and_jump_insns (operands[1],
4815 const_double_from_real_value (cmp, <BFP:MODE>mode),
4816 LT, NULL_RTX, VOIDmode, 0, label1);
4817 emit_insn (gen_sub<BFP:mode>3 (temp, operands[1],
4818 const_double_from_real_value (sub, <BFP:MODE>mode)));
4819 emit_insn (gen_fix_trunc<BFP:mode><GPR:mode>2_bfp (operands[0], temp,
4820 GEN_INT (BFP_RND_TOWARD_MINF)));
4821 emit_jump (label2);
4822
4823 emit_label (label1);
4824 emit_insn (gen_fix_trunc<BFP:mode><GPR:mode>2_bfp (operands[0],
4825 operands[1], GEN_INT (BFP_RND_TOWARD_0)));
4826 emit_label (label2);
4827 DONE;
4828 }
4829 })
4830
4831 ; fixuns_trunc(td|dd)si2 expander
4832 (define_expand "fixuns_trunc<mode>si2"
4833 [(parallel
4834 [(set (match_operand:SI 0 "register_operand" "")
4835 (unsigned_fix:SI (match_operand:DFP 1 "register_operand" "")))
4836 (unspec:SI [(const_int DFP_RND_TOWARD_0)] UNSPEC_ROUND)
4837 (clobber (reg:CC CC_REGNUM))])]
4838 "TARGET_Z196 && TARGET_HARD_DFP"
4839 "")
4840
4841 ; fixuns_trunc(tf|df|sf|td|dd)(di|si)2 instruction patterns.
4842
4843 (define_insn "*fixuns_truncdfdi2_z13"
4844 [(set (match_operand:DI 0 "register_operand" "=d,v")
4845 (unsigned_fix:DI (match_operand:DF 1 "register_operand" "f,v")))
4846 (unspec:DI [(match_operand:DI 2 "immediate_operand" "K,K")] UNSPEC_ROUND)
4847 (clobber (reg:CC CC_REGNUM))]
4848 "TARGET_VX && TARGET_HARD_FLOAT"
4849 "@
4850 clgdbr\t%0,%h2,%1,0
4851 wclgdb\t%v0,%v1,0,%h2"
4852 [(set_attr "op_type" "RRF,VRR")
4853 (set_attr "type" "ftoi")])
4854
4855 ; clfebr, clfdbr, clfxbr, clgebr, clgdbr, clgxbr
4856 ; clfdtr, clfxtr, clgdtr, clgxtr
4857 (define_insn "*fixuns_trunc<FP:mode><GPR:mode>2_z196"
4858 [(set (match_operand:GPR 0 "register_operand" "=d")
4859 (unsigned_fix:GPR (match_operand:FP 1 "register_operand" "f")))
4860 (unspec:GPR [(match_operand:GPR 2 "immediate_operand" "K")] UNSPEC_ROUND)
4861 (clobber (reg:CC CC_REGNUM))]
4862 "TARGET_Z196 && TARGET_HARD_FLOAT
4863 && (!TARGET_VX || <GPR:MODE>mode != DImode || <FP:MODE>mode != DFmode)"
4864 "cl<GPR:gf><FP:xde><FP:bt>r\t%0,%h2,%1,0"
4865 [(set_attr "op_type" "RRF")
4866 (set_attr "type" "ftoi")])
4867
4868 (define_expand "fix_trunc<DSF:mode><GPR:mode>2"
4869 [(set (match_operand:GPR 0 "register_operand" "")
4870 (fix:GPR (match_operand:DSF 1 "register_operand" "")))]
4871 "TARGET_HARD_FLOAT"
4872 {
4873 emit_insn (gen_fix_trunc<DSF:mode><GPR:mode>2_bfp (operands[0], operands[1],
4874 GEN_INT (BFP_RND_TOWARD_0)));
4875 DONE;
4876 })
4877
4878 (define_insn "*fix_truncdfdi2_bfp_z13"
4879 [(set (match_operand:DI 0 "register_operand" "=d,v")
4880 (fix:DI (match_operand:DF 1 "register_operand" "f,v")))
4881 (unspec:DI [(match_operand:DI 2 "immediate_operand" "K,K")] UNSPEC_ROUND)
4882 (clobber (reg:CC CC_REGNUM))]
4883 "TARGET_VX && TARGET_HARD_FLOAT"
4884 "@
4885 cgdbr\t%0,%h2,%1
4886 wcgdb\t%v0,%v1,0,%h2"
4887 [(set_attr "op_type" "RRE,VRR")
4888 (set_attr "type" "ftoi")])
4889
4890 ; cgxbr, cgdbr, cgebr, cfxbr, cfdbr, cfebr
4891 (define_insn "*fix_trunc<BFP:mode><GPR:mode>2_bfp"
4892 [(set (match_operand:GPR 0 "register_operand" "=d")
4893 (fix:GPR (match_operand:BFP 1 "register_operand" "f")))
4894 (unspec:GPR [(match_operand:GPR 2 "immediate_operand" "K")] UNSPEC_ROUND)
4895 (clobber (reg:CC CC_REGNUM))]
4896 "TARGET_HARD_FLOAT
4897 && (!TARGET_VX || <GPR:MODE>mode != DImode || <BFP:MODE>mode != DFmode)"
4898 "c<GPR:gf><BFP:xde>br\t%0,%h2,%1"
4899 [(set_attr "op_type" "RRE")
4900 (set_attr "type" "ftoi")])
4901
4902 (define_expand "fix_trunc<BFP:mode><GPR:mode>2_bfp"
4903 [(parallel
4904 [(set (match_operand:GPR 0 "register_operand" "=d")
4905 (fix:GPR (match_operand:BFP 1 "register_operand" "f")))
4906 (unspec:GPR [(match_operand:GPR 2 "immediate_operand" "K")] UNSPEC_ROUND)
4907 (clobber (reg:CC CC_REGNUM))])]
4908 "TARGET_HARD_FLOAT")
4909 ;
4910 ; fix_trunc(td|dd)di2 instruction pattern(s).
4911 ;
4912
4913 (define_expand "fix_trunc<mode>di2"
4914 [(set (match_operand:DI 0 "register_operand" "")
4915 (fix:DI (match_operand:DFP 1 "nonimmediate_operand" "")))]
4916 "TARGET_ZARCH && TARGET_HARD_DFP"
4917 {
4918 operands[1] = force_reg (<MODE>mode, operands[1]);
4919 emit_insn (gen_fix_trunc<mode>di2_dfp (operands[0], operands[1],
4920 GEN_INT (DFP_RND_TOWARD_0)));
4921 DONE;
4922 })
4923
4924 ; cgxtr, cgdtr
4925 (define_insn "fix_trunc<DFP:mode>di2_dfp"
4926 [(set (match_operand:DI 0 "register_operand" "=d")
4927 (fix:DI (match_operand:DFP 1 "register_operand" "f")))
4928 (unspec:DI [(match_operand:DI 2 "immediate_operand" "K")] UNSPEC_ROUND)
4929 (clobber (reg:CC CC_REGNUM))]
4930 "TARGET_ZARCH && TARGET_HARD_DFP"
4931 "cg<DFP:xde>tr\t%0,%h2,%1"
4932 [(set_attr "op_type" "RRF")
4933 (set_attr "type" "ftoidfp")])
4934
4935
4936 ;
4937 ; fix_trunctf(si|di)2 instruction pattern(s).
4938 ;
4939
4940 (define_expand "fix_trunctf<mode>2"
4941 [(parallel [(set (match_operand:GPR 0 "register_operand" "")
4942 (fix:GPR (match_operand:TF 1 "register_operand" "")))
4943 (unspec:GPR [(const_int BFP_RND_TOWARD_0)] UNSPEC_ROUND)
4944 (clobber (reg:CC CC_REGNUM))])]
4945 "TARGET_HARD_FLOAT"
4946 "")
4947
4948
4949 ;
4950 ; float(si|di)(tf|df|sf|td|dd)2 instruction pattern(s).
4951 ;
4952
4953 ; cxgbr, cdgbr, cegbr, cxgtr, cdgtr
4954 (define_insn "floatdi<mode>2"
4955 [(set (match_operand:FP 0 "register_operand" "=f,v")
4956 (float:FP (match_operand:DI 1 "register_operand" "d,v")))]
4957 "TARGET_ZARCH && TARGET_HARD_FLOAT"
4958 "@
4959 c<xde>g<bt>r\t%0,%1
4960 wcdgb\t%v0,%v1,0,0"
4961 [(set_attr "op_type" "RRE,VRR")
4962 (set_attr "type" "itof<mode>" )
4963 (set_attr "cpu_facility" "*,vec")
4964 (set_attr "enabled" "*,<DFDI>")])
4965
4966 ; cxfbr, cdfbr, cefbr
4967 (define_insn "floatsi<mode>2"
4968 [(set (match_operand:BFP 0 "register_operand" "=f")
4969 (float:BFP (match_operand:SI 1 "register_operand" "d")))]
4970 "TARGET_HARD_FLOAT"
4971 "c<xde>fbr\t%0,%1"
4972 [(set_attr "op_type" "RRE")
4973 (set_attr "type" "itof<mode>" )])
4974
4975 ; cxftr, cdftr
4976 (define_insn "floatsi<mode>2"
4977 [(set (match_operand:DFP 0 "register_operand" "=f")
4978 (float:DFP (match_operand:SI 1 "register_operand" "d")))]
4979 "TARGET_Z196 && TARGET_HARD_FLOAT"
4980 "c<xde>ftr\t%0,0,%1,0"
4981 [(set_attr "op_type" "RRE")
4982 (set_attr "type" "itof<mode>" )])
4983
4984 ;
4985 ; floatuns(si|di)(tf|df|sf|td|dd)2 instruction pattern(s).
4986 ;
4987
4988 (define_insn "*floatunsdidf2_z13"
4989 [(set (match_operand:DF 0 "register_operand" "=f,v")
4990 (unsigned_float:DF (match_operand:DI 1 "register_operand" "d,v")))]
4991 "TARGET_VX && TARGET_HARD_FLOAT"
4992 "@
4993 cdlgbr\t%0,0,%1,0
4994 wcdlgb\t%v0,%v1,0,0"
4995 [(set_attr "op_type" "RRE,VRR")
4996 (set_attr "type" "itofdf")])
4997
4998 ; cxlgbr, cdlgbr, celgbr, cxlgtr, cdlgtr
4999 ; cxlfbr, cdlfbr, celfbr, cxlftr, cdlftr
5000 (define_insn "*floatuns<GPR:mode><FP:mode>2"
5001 [(set (match_operand:FP 0 "register_operand" "=f")
5002 (unsigned_float:FP (match_operand:GPR 1 "register_operand" "d")))]
5003 "TARGET_Z196 && TARGET_HARD_FLOAT
5004 && (!TARGET_VX || <FP:MODE>mode != DFmode || <GPR:MODE>mode != DImode)"
5005 "c<FP:xde>l<GPR:gf><FP:bt>r\t%0,0,%1,0"
5006 [(set_attr "op_type" "RRE")
5007 (set_attr "type" "itof<FP:mode>")])
5008
5009 (define_expand "floatuns<GPR:mode><FP:mode>2"
5010 [(set (match_operand:FP 0 "register_operand" "")
5011 (unsigned_float:FP (match_operand:GPR 1 "register_operand" "")))]
5012 "TARGET_Z196 && TARGET_HARD_FLOAT")
5013
5014 ;
5015 ; truncdfsf2 instruction pattern(s).
5016 ;
5017
5018 (define_insn "truncdfsf2"
5019 [(set (match_operand:SF 0 "register_operand" "=f,v")
5020 (float_truncate:SF (match_operand:DF 1 "register_operand" "f,v")))]
5021 "TARGET_HARD_FLOAT"
5022 "@
5023 ledbr\t%0,%1
5024 wledb\t%v0,%v1,0,0" ; IEEE inexact exception not suppressed
5025 ; According to BFP rounding mode
5026 [(set_attr "op_type" "RRE,VRR")
5027 (set_attr "type" "ftruncdf")
5028 (set_attr "cpu_facility" "*,vec")])
5029
5030 ;
5031 ; trunctf(df|sf)2 instruction pattern(s).
5032 ;
5033
5034 ; ldxbr, lexbr
5035 (define_insn "trunctf<mode>2"
5036 [(set (match_operand:DSF 0 "register_operand" "=f")
5037 (float_truncate:DSF (match_operand:TF 1 "register_operand" "f")))
5038 (clobber (match_scratch:TF 2 "=f"))]
5039 "TARGET_HARD_FLOAT"
5040 "l<xde>xbr\t%2,%1\;l<xde>r\t%0,%2"
5041 [(set_attr "length" "6")
5042 (set_attr "type" "ftrunctf")])
5043
5044 ;
5045 ; trunctddd2 and truncddsd2 instruction pattern(s).
5046 ;
5047
5048
5049 (define_expand "trunctddd2"
5050 [(parallel
5051 [(set (match_operand:DD 0 "register_operand" "")
5052 (float_truncate:DD (match_operand:TD 1 "register_operand" "")))
5053 (unspec:DI [(const_int DFP_RND_CURRENT)] UNSPEC_ROUND)
5054 (clobber (scratch:TD))])]
5055 "TARGET_HARD_DFP")
5056
5057 (define_insn "*trunctddd2"
5058 [(set (match_operand:DD 0 "register_operand" "=f")
5059 (float_truncate:DD (match_operand:TD 1 "register_operand" "f")))
5060 (unspec:DI [(match_operand:DI 2 "const_mask_operand" "I")] UNSPEC_ROUND)
5061 (clobber (match_scratch:TD 3 "=f"))]
5062 "TARGET_HARD_DFP"
5063 "ldxtr\t%3,%2,%1,0\;ldr\t%0,%3"
5064 [(set_attr "length" "6")
5065 (set_attr "type" "ftruncdd")])
5066
5067 (define_insn "truncddsd2"
5068 [(set (match_operand:SD 0 "register_operand" "=f")
5069 (float_truncate:SD (match_operand:DD 1 "register_operand" "f")))]
5070 "TARGET_HARD_DFP"
5071 "ledtr\t%0,0,%1,0"
5072 [(set_attr "op_type" "RRF")
5073 (set_attr "type" "ftruncsd")])
5074
5075 (define_expand "trunctdsd2"
5076 [(parallel
5077 [(set (match_dup 3)
5078 (float_truncate:DD (match_operand:TD 1 "register_operand" "")))
5079 (unspec:DI [(const_int DFP_RND_PREP_FOR_SHORT_PREC)] UNSPEC_ROUND)
5080 (clobber (match_scratch:TD 2 ""))])
5081 (set (match_operand:SD 0 "register_operand" "")
5082 (float_truncate:SD (match_dup 3)))]
5083 "TARGET_HARD_DFP"
5084 {
5085 operands[3] = gen_reg_rtx (DDmode);
5086 })
5087
5088 ;
5089 ; extend(sf|df)(df|tf)2 instruction pattern(s).
5090 ;
5091
5092 (define_insn "*extendsfdf2_z13"
5093 [(set (match_operand:DF 0 "register_operand" "=f,f,v")
5094 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "f,R,v")))]
5095 "TARGET_VX && TARGET_HARD_FLOAT"
5096 "@
5097 ldebr\t%0,%1
5098 ldeb\t%0,%1
5099 wldeb\t%v0,%v1"
5100 [(set_attr "op_type" "RRE,RXE,VRR")
5101 (set_attr "type" "fsimpdf, floaddf,fsimpdf")])
5102
5103 ; ldebr, ldeb, lxdbr, lxdb, lxebr, lxeb
5104 (define_insn "*extend<DSF:mode><BFP:mode>2"
5105 [(set (match_operand:BFP 0 "register_operand" "=f,f")
5106 (float_extend:BFP (match_operand:DSF 1 "nonimmediate_operand" "f,R")))]
5107 "TARGET_HARD_FLOAT
5108 && GET_MODE_SIZE (<BFP:MODE>mode) > GET_MODE_SIZE (<DSF:MODE>mode)
5109 && (!TARGET_VX || <BFP:MODE>mode != DFmode || <DSF:MODE>mode != SFmode)"
5110 "@
5111 l<BFP:xde><DSF:xde>br\t%0,%1
5112 l<BFP:xde><DSF:xde>b\t%0,%1"
5113 [(set_attr "op_type" "RRE,RXE")
5114 (set_attr "type" "fsimp<BFP:mode>, fload<BFP:mode>")])
5115
5116 (define_expand "extend<DSF:mode><BFP:mode>2"
5117 [(set (match_operand:BFP 0 "register_operand" "")
5118 (float_extend:BFP (match_operand:DSF 1 "nonimmediate_operand" "")))]
5119 "TARGET_HARD_FLOAT
5120 && GET_MODE_SIZE (<BFP:MODE>mode) > GET_MODE_SIZE (<DSF:MODE>mode)")
5121
5122 ;
5123 ; extendddtd2 and extendsddd2 instruction pattern(s).
5124 ;
5125
5126 (define_insn "extendddtd2"
5127 [(set (match_operand:TD 0 "register_operand" "=f")
5128 (float_extend:TD (match_operand:DD 1 "register_operand" "f")))]
5129 "TARGET_HARD_DFP"
5130 "lxdtr\t%0,%1,0"
5131 [(set_attr "op_type" "RRF")
5132 (set_attr "type" "fsimptf")])
5133
5134 (define_insn "extendsddd2"
5135 [(set (match_operand:DD 0 "register_operand" "=f")
5136 (float_extend:DD (match_operand:SD 1 "register_operand" "f")))]
5137 "TARGET_HARD_DFP"
5138 "ldetr\t%0,%1,0"
5139 [(set_attr "op_type" "RRF")
5140 (set_attr "type" "fsimptf")])
5141
5142 (define_expand "extendsdtd2"
5143 [(set (match_dup 2)
5144 (float_extend:DD (match_operand:SD 1 "register_operand" "")))
5145 (set (match_operand:TD 0 "register_operand" "")
5146 (float_extend:TD (match_dup 2)))]
5147 "TARGET_HARD_DFP"
5148 {
5149 operands[2] = gen_reg_rtx (DDmode);
5150 })
5151
5152 ; Binary Floating Point - load fp integer
5153
5154 ; Expanders for: floor, btrunc, round, ceil, and nearbyint
5155 ; For all of them the inexact exceptions are suppressed.
5156
5157 ; fiebra, fidbra, fixbra
5158 (define_insn "<FPINT:fpint_name><BFP:mode>2"
5159 [(set (match_operand:BFP 0 "register_operand" "=f")
5160 (unspec:BFP [(match_operand:BFP 1 "register_operand" "f")]
5161 FPINT))]
5162 "TARGET_Z196"
5163 "fi<BFP:xde>bra\t%0,<FPINT:fpint_roundingmode>,%1,4"
5164 [(set_attr "op_type" "RRF")
5165 (set_attr "type" "fsimp<BFP:mode>")])
5166
5167 ; rint is supposed to raise an inexact exception so we can use the
5168 ; older instructions.
5169
5170 ; fiebr, fidbr, fixbr
5171 (define_insn "rint<BFP:mode>2"
5172 [(set (match_operand:BFP 0 "register_operand" "=f")
5173 (unspec:BFP [(match_operand:BFP 1 "register_operand" "f")]
5174 UNSPEC_FPINT_RINT))]
5175 ""
5176 "fi<BFP:xde>br\t%0,0,%1"
5177 [(set_attr "op_type" "RRF")
5178 (set_attr "type" "fsimp<BFP:mode>")])
5179
5180
5181 ; Decimal Floating Point - load fp integer
5182
5183 ; fidtr, fixtr
5184 (define_insn "<FPINT:fpint_name><DFP:mode>2"
5185 [(set (match_operand:DFP 0 "register_operand" "=f")
5186 (unspec:DFP [(match_operand:DFP 1 "register_operand" "f")]
5187 FPINT))]
5188 "TARGET_HARD_DFP"
5189 "fi<DFP:xde>tr\t%0,<FPINT:fpint_roundingmode>,%1,4"
5190 [(set_attr "op_type" "RRF")
5191 (set_attr "type" "fsimp<DFP:mode>")])
5192
5193 ; fidtr, fixtr
5194 (define_insn "rint<DFP:mode>2"
5195 [(set (match_operand:DFP 0 "register_operand" "=f")
5196 (unspec:DFP [(match_operand:DFP 1 "register_operand" "f")]
5197 UNSPEC_FPINT_RINT))]
5198 "TARGET_HARD_DFP"
5199 "fi<DFP:xde>tr\t%0,0,%1,0"
5200 [(set_attr "op_type" "RRF")
5201 (set_attr "type" "fsimp<DFP:mode>")])
5202
5203 ;
5204 ; Binary <-> Decimal floating point trunc patterns
5205 ;
5206
5207 (define_insn "*trunc<BFP:mode><DFP_ALL:mode>2"
5208 [(set (reg:DFP_ALL FPR0_REGNUM)
5209 (float_truncate:DFP_ALL (reg:BFP FPR4_REGNUM)))
5210 (use (reg:SI GPR0_REGNUM))
5211 (clobber (reg:CC CC_REGNUM))
5212 (clobber (reg:SI GPR1_REGNUM))]
5213 "TARGET_HARD_DFP"
5214 "pfpo")
5215
5216 (define_insn "*trunc<DFP_ALL:mode><BFP:mode>2"
5217 [(set (reg:BFP FPR0_REGNUM)
5218 (float_truncate:BFP (reg:DFP_ALL FPR4_REGNUM)))
5219 (use (reg:SI GPR0_REGNUM))
5220 (clobber (reg:CC CC_REGNUM))
5221 (clobber (reg:SI GPR1_REGNUM))]
5222 "TARGET_HARD_DFP"
5223 "pfpo")
5224
5225 (define_expand "trunc<BFP:mode><DFP_ALL:mode>2"
5226 [(set (reg:BFP FPR4_REGNUM) (match_operand:BFP 1 "nonimmediate_operand" ""))
5227 (set (reg:SI GPR0_REGNUM) (match_dup 2))
5228 (parallel
5229 [(set (reg:DFP_ALL FPR0_REGNUM)
5230 (float_truncate:DFP_ALL (reg:BFP FPR4_REGNUM)))
5231 (use (reg:SI GPR0_REGNUM))
5232 (clobber (reg:CC CC_REGNUM))
5233 (clobber (reg:SI GPR1_REGNUM))])
5234 (set (match_operand:DFP_ALL 0 "nonimmediate_operand" "")
5235 (reg:DFP_ALL FPR0_REGNUM))]
5236 "TARGET_HARD_DFP
5237 && GET_MODE_SIZE (<BFP:MODE>mode) > GET_MODE_SIZE (<DFP_ALL:MODE>mode)"
5238 {
5239 HOST_WIDE_INT flags;
5240
5241 flags = (PFPO_CONVERT |
5242 PFPO_OP_TYPE_<DFP_ALL:MODE> << PFPO_OP0_TYPE_SHIFT |
5243 PFPO_OP_TYPE_<BFP:MODE> << PFPO_OP1_TYPE_SHIFT);
5244
5245 operands[2] = GEN_INT (flags);
5246 })
5247
5248 (define_expand "trunc<DFP_ALL:mode><BFP:mode>2"
5249 [(set (reg:DFP_ALL FPR4_REGNUM)
5250 (match_operand:DFP_ALL 1 "nonimmediate_operand" ""))
5251 (set (reg:SI GPR0_REGNUM) (match_dup 2))
5252 (parallel
5253 [(set (reg:BFP FPR0_REGNUM) (float_truncate:BFP (reg:DFP_ALL FPR4_REGNUM)))
5254 (use (reg:SI GPR0_REGNUM))
5255 (clobber (reg:CC CC_REGNUM))
5256 (clobber (reg:SI GPR1_REGNUM))])
5257 (set (match_operand:BFP 0 "nonimmediate_operand" "") (reg:BFP FPR0_REGNUM))]
5258 "TARGET_HARD_DFP
5259 && GET_MODE_SIZE (<DFP_ALL:MODE>mode) >= GET_MODE_SIZE (<BFP:MODE>mode)"
5260 {
5261 HOST_WIDE_INT flags;
5262
5263 flags = (PFPO_CONVERT |
5264 PFPO_OP_TYPE_<BFP:MODE> << PFPO_OP0_TYPE_SHIFT |
5265 PFPO_OP_TYPE_<DFP_ALL:MODE> << PFPO_OP1_TYPE_SHIFT);
5266
5267 operands[2] = GEN_INT (flags);
5268 })
5269
5270 ;
5271 ; Binary <-> Decimal floating point extend patterns
5272 ;
5273
5274 (define_insn "*extend<BFP:mode><DFP_ALL:mode>2"
5275 [(set (reg:DFP_ALL FPR0_REGNUM) (float_extend:DFP_ALL (reg:BFP FPR4_REGNUM)))
5276 (use (reg:SI GPR0_REGNUM))
5277 (clobber (reg:CC CC_REGNUM))
5278 (clobber (reg:SI GPR1_REGNUM))]
5279 "TARGET_HARD_DFP"
5280 "pfpo")
5281
5282 (define_insn "*extend<DFP_ALL:mode><BFP:mode>2"
5283 [(set (reg:BFP FPR0_REGNUM) (float_extend:BFP (reg:DFP_ALL FPR4_REGNUM)))
5284 (use (reg:SI GPR0_REGNUM))
5285 (clobber (reg:CC CC_REGNUM))
5286 (clobber (reg:SI GPR1_REGNUM))]
5287 "TARGET_HARD_DFP"
5288 "pfpo")
5289
5290 (define_expand "extend<BFP:mode><DFP_ALL:mode>2"
5291 [(set (reg:BFP FPR4_REGNUM) (match_operand:BFP 1 "nonimmediate_operand" ""))
5292 (set (reg:SI GPR0_REGNUM) (match_dup 2))
5293 (parallel
5294 [(set (reg:DFP_ALL FPR0_REGNUM)
5295 (float_extend:DFP_ALL (reg:BFP FPR4_REGNUM)))
5296 (use (reg:SI GPR0_REGNUM))
5297 (clobber (reg:CC CC_REGNUM))
5298 (clobber (reg:SI GPR1_REGNUM))])
5299 (set (match_operand:DFP_ALL 0 "nonimmediate_operand" "")
5300 (reg:DFP_ALL FPR0_REGNUM))]
5301 "TARGET_HARD_DFP
5302 && GET_MODE_SIZE (<BFP:MODE>mode) <= GET_MODE_SIZE (<DFP_ALL:MODE>mode)"
5303 {
5304 HOST_WIDE_INT flags;
5305
5306 flags = (PFPO_CONVERT |
5307 PFPO_OP_TYPE_<DFP_ALL:MODE> << PFPO_OP0_TYPE_SHIFT |
5308 PFPO_OP_TYPE_<BFP:MODE> << PFPO_OP1_TYPE_SHIFT);
5309
5310 operands[2] = GEN_INT (flags);
5311 })
5312
5313 (define_expand "extend<DFP_ALL:mode><BFP:mode>2"
5314 [(set (reg:DFP_ALL FPR4_REGNUM)
5315 (match_operand:DFP_ALL 1 "nonimmediate_operand" ""))
5316 (set (reg:SI GPR0_REGNUM) (match_dup 2))
5317 (parallel
5318 [(set (reg:BFP FPR0_REGNUM) (float_extend:BFP (reg:DFP_ALL FPR4_REGNUM)))
5319 (use (reg:SI GPR0_REGNUM))
5320 (clobber (reg:CC CC_REGNUM))
5321 (clobber (reg:SI GPR1_REGNUM))])
5322 (set (match_operand:BFP 0 "nonimmediate_operand" "") (reg:BFP FPR0_REGNUM))]
5323 "TARGET_HARD_DFP
5324 && GET_MODE_SIZE (<DFP_ALL:MODE>mode) < GET_MODE_SIZE (<BFP:MODE>mode)"
5325 {
5326 HOST_WIDE_INT flags;
5327
5328 flags = (PFPO_CONVERT |
5329 PFPO_OP_TYPE_<BFP:MODE> << PFPO_OP0_TYPE_SHIFT |
5330 PFPO_OP_TYPE_<DFP_ALL:MODE> << PFPO_OP1_TYPE_SHIFT);
5331
5332 operands[2] = GEN_INT (flags);
5333 })
5334
5335
5336 ;;
5337 ;; ARITHMETIC OPERATIONS
5338 ;;
5339 ; arithmetic operations set the ConditionCode,
5340 ; because of unpredictable Bits in Register for Halfword and Byte
5341 ; the ConditionCode can be set wrong in operations for Halfword and Byte
5342
5343 ;;
5344 ;;- Add instructions.
5345 ;;
5346
5347 ;
5348 ; addti3 instruction pattern(s).
5349 ;
5350
5351 (define_expand "addti3"
5352 [(parallel
5353 [(set (match_operand:TI 0 "register_operand" "")
5354 (plus:TI (match_operand:TI 1 "nonimmediate_operand" "")
5355 (match_operand:TI 2 "general_operand" "") ) )
5356 (clobber (reg:CC CC_REGNUM))])]
5357 "TARGET_ZARCH"
5358 {
5359 /* For z13 we have vaq which doesn't set CC. */
5360 if (TARGET_VX)
5361 {
5362 emit_insn (gen_rtx_SET (operands[0],
5363 gen_rtx_PLUS (TImode,
5364 copy_to_mode_reg (TImode, operands[1]),
5365 copy_to_mode_reg (TImode, operands[2]))));
5366 DONE;
5367 }
5368 })
5369
5370 (define_insn_and_split "*addti3"
5371 [(set (match_operand:TI 0 "register_operand" "=&d")
5372 (plus:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
5373 (match_operand:TI 2 "general_operand" "do") ) )
5374 (clobber (reg:CC CC_REGNUM))]
5375 "TARGET_ZARCH"
5376 "#"
5377 "&& reload_completed"
5378 [(parallel
5379 [(set (reg:CCL1 CC_REGNUM)
5380 (compare:CCL1 (plus:DI (match_dup 7) (match_dup 8))
5381 (match_dup 7)))
5382 (set (match_dup 6) (plus:DI (match_dup 7) (match_dup 8)))])
5383 (parallel
5384 [(set (match_dup 3) (plus:DI
5385 (plus:DI (ltu:DI (reg:CCL1 CC_REGNUM) (const_int 0))
5386 (match_dup 4)) (match_dup 5)))
5387 (clobber (reg:CC CC_REGNUM))])]
5388 "operands[3] = operand_subword (operands[0], 0, 0, TImode);
5389 operands[4] = operand_subword (operands[1], 0, 0, TImode);
5390 operands[5] = operand_subword (operands[2], 0, 0, TImode);
5391 operands[6] = operand_subword (operands[0], 1, 0, TImode);
5392 operands[7] = operand_subword (operands[1], 1, 0, TImode);
5393 operands[8] = operand_subword (operands[2], 1, 0, TImode);"
5394 [(set_attr "op_type" "*")
5395 (set_attr "cpu_facility" "*")])
5396
5397 ;
5398 ; adddi3 instruction pattern(s).
5399 ;
5400
5401 (define_expand "adddi3"
5402 [(parallel
5403 [(set (match_operand:DI 0 "nonimmediate_operand" "")
5404 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
5405 (match_operand:DI 2 "general_operand" "")))
5406 (clobber (reg:CC CC_REGNUM))])]
5407 ""
5408 "")
5409
5410 (define_insn "*adddi3_sign"
5411 [(set (match_operand:DI 0 "register_operand" "=d,d")
5412 (plus:DI (sign_extend:DI (match_operand:SI 2 "general_operand" "d,T"))
5413 (match_operand:DI 1 "register_operand" "0,0")))
5414 (clobber (reg:CC CC_REGNUM))]
5415 "TARGET_ZARCH"
5416 "@
5417 agfr\t%0,%2
5418 agf\t%0,%2"
5419 [(set_attr "op_type" "RRE,RXY")
5420 (set_attr "z196prop" "z196_cracked,z196_cracked")])
5421
5422 (define_insn "*adddi3_zero_cc"
5423 [(set (reg CC_REGNUM)
5424 (compare (plus:DI (zero_extend:DI (match_operand:SI 2 "general_operand" "d,T"))
5425 (match_operand:DI 1 "register_operand" "0,0"))
5426 (const_int 0)))
5427 (set (match_operand:DI 0 "register_operand" "=d,d")
5428 (plus:DI (zero_extend:DI (match_dup 2)) (match_dup 1)))]
5429 "s390_match_ccmode (insn, CCLmode) && TARGET_ZARCH"
5430 "@
5431 algfr\t%0,%2
5432 algf\t%0,%2"
5433 [(set_attr "op_type" "RRE,RXY")
5434 (set_attr "z10prop" "z10_super_E1,z10_super_E1")])
5435
5436 (define_insn "*adddi3_zero_cconly"
5437 [(set (reg CC_REGNUM)
5438 (compare (plus:DI (zero_extend:DI (match_operand:SI 2 "general_operand" "d,T"))
5439 (match_operand:DI 1 "register_operand" "0,0"))
5440 (const_int 0)))
5441 (clobber (match_scratch:DI 0 "=d,d"))]
5442 "s390_match_ccmode (insn, CCLmode) && TARGET_ZARCH"
5443 "@
5444 algfr\t%0,%2
5445 algf\t%0,%2"
5446 [(set_attr "op_type" "RRE,RXY")
5447 (set_attr "z10prop" "z10_super_E1,z10_super_E1")])
5448
5449 (define_insn "*adddi3_zero"
5450 [(set (match_operand:DI 0 "register_operand" "=d,d")
5451 (plus:DI (zero_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 algfr\t%0,%2
5457 algf\t%0,%2"
5458 [(set_attr "op_type" "RRE,RXY")
5459 (set_attr "z10prop" "z10_super_E1,z10_super_E1")])
5460
5461 (define_insn_and_split "*adddi3_31z"
5462 [(set (match_operand:DI 0 "nonimmediate_operand" "=&d")
5463 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
5464 (match_operand:DI 2 "general_operand" "do") ) )
5465 (clobber (reg:CC CC_REGNUM))]
5466 "!TARGET_ZARCH && TARGET_CPU_ZARCH"
5467 "#"
5468 "&& reload_completed"
5469 [(parallel
5470 [(set (reg:CCL1 CC_REGNUM)
5471 (compare:CCL1 (plus:SI (match_dup 7) (match_dup 8))
5472 (match_dup 7)))
5473 (set (match_dup 6) (plus:SI (match_dup 7) (match_dup 8)))])
5474 (parallel
5475 [(set (match_dup 3) (plus:SI
5476 (plus:SI (ltu:SI (reg:CCL1 CC_REGNUM) (const_int 0))
5477 (match_dup 4)) (match_dup 5)))
5478 (clobber (reg:CC CC_REGNUM))])]
5479 "operands[3] = operand_subword (operands[0], 0, 0, DImode);
5480 operands[4] = operand_subword (operands[1], 0, 0, DImode);
5481 operands[5] = operand_subword (operands[2], 0, 0, DImode);
5482 operands[6] = operand_subword (operands[0], 1, 0, DImode);
5483 operands[7] = operand_subword (operands[1], 1, 0, DImode);
5484 operands[8] = operand_subword (operands[2], 1, 0, DImode);")
5485
5486 (define_insn_and_split "*adddi3_31"
5487 [(set (match_operand:DI 0 "nonimmediate_operand" "=&d")
5488 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
5489 (match_operand:DI 2 "general_operand" "do") ) )
5490 (clobber (reg:CC CC_REGNUM))]
5491 "!TARGET_CPU_ZARCH"
5492 "#"
5493 "&& reload_completed"
5494 [(parallel
5495 [(set (match_dup 3) (plus:SI (match_dup 4) (match_dup 5)))
5496 (clobber (reg:CC CC_REGNUM))])
5497 (parallel
5498 [(set (reg:CCL1 CC_REGNUM)
5499 (compare:CCL1 (plus:SI (match_dup 7) (match_dup 8))
5500 (match_dup 7)))
5501 (set (match_dup 6) (plus:SI (match_dup 7) (match_dup 8)))])
5502 (set (pc)
5503 (if_then_else (ltu (reg:CCL1 CC_REGNUM) (const_int 0))
5504 (pc)
5505 (label_ref (match_dup 9))))
5506 (parallel
5507 [(set (match_dup 3) (plus:SI (match_dup 3) (const_int 1)))
5508 (clobber (reg:CC CC_REGNUM))])
5509 (match_dup 9)]
5510 "operands[3] = operand_subword (operands[0], 0, 0, DImode);
5511 operands[4] = operand_subword (operands[1], 0, 0, DImode);
5512 operands[5] = operand_subword (operands[2], 0, 0, DImode);
5513 operands[6] = operand_subword (operands[0], 1, 0, DImode);
5514 operands[7] = operand_subword (operands[1], 1, 0, DImode);
5515 operands[8] = operand_subword (operands[2], 1, 0, DImode);
5516 operands[9] = gen_label_rtx ();")
5517
5518 ;
5519 ; addsi3 instruction pattern(s).
5520 ;
5521
5522 (define_expand "addsi3"
5523 [(parallel
5524 [(set (match_operand:SI 0 "nonimmediate_operand" "")
5525 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "")
5526 (match_operand:SI 2 "general_operand" "")))
5527 (clobber (reg:CC CC_REGNUM))])]
5528 ""
5529 "")
5530
5531 (define_insn "*addsi3_sign"
5532 [(set (match_operand:SI 0 "register_operand" "=d,d")
5533 (plus:SI (sign_extend:SI (match_operand:HI 2 "memory_operand" "R,T"))
5534 (match_operand:SI 1 "register_operand" "0,0")))
5535 (clobber (reg:CC CC_REGNUM))]
5536 ""
5537 "@
5538 ah\t%0,%2
5539 ahy\t%0,%2"
5540 [(set_attr "op_type" "RX,RXY")
5541 (set_attr "cpu_facility" "*,longdisp")
5542 (set_attr "z196prop" "z196_cracked,z196_cracked")])
5543
5544 ;
5545 ; add(di|si)3 instruction pattern(s).
5546 ;
5547
5548 ; ark, agrk, ar, ahi, ahik, aghik, alfi, slfi, a, ay, agr, aghi, algfi, slgfi, ag, asi, agsi
5549 (define_insn "*add<mode>3"
5550 [(set (match_operand:GPR 0 "nonimmediate_operand" "=d,d,d,d, d, d,d,d,S")
5551 (plus:GPR (match_operand:GPR 1 "nonimmediate_operand" "%0,d,0,d, 0, 0,0,0,0")
5552 (match_operand:GPR 2 "general_operand" " d,d,K,K,Op,On,R,T,C") ) )
5553 (clobber (reg:CC CC_REGNUM))]
5554 ""
5555 "@
5556 a<g>r\t%0,%2
5557 a<g>rk\t%0,%1,%2
5558 a<g>hi\t%0,%h2
5559 a<g>hik\t%0,%1,%h2
5560 al<g>fi\t%0,%2
5561 sl<g>fi\t%0,%n2
5562 a<g>\t%0,%2
5563 a<y>\t%0,%2
5564 a<g>si\t%0,%c2"
5565 [(set_attr "op_type" "RR<E>,RRF,RI,RIE,RIL,RIL,RX<Y>,RXY,SIY")
5566 (set_attr "cpu_facility" "*,z196,*,z196,extimm,extimm,*,longdisp,z10")
5567 (set_attr "z10prop" "z10_super_E1,*,z10_super_E1,*,z10_super_E1,z10_super_E1,
5568 z10_super_E1,z10_super_E1,z10_super_E1")])
5569
5570 ; alr, alfi, slfi, al, aly, alrk, alhsik, algr, algfi, slgfi, alg, alsi, algsi, algrk, alghsik
5571 (define_insn "*add<mode>3_carry1_cc"
5572 [(set (reg CC_REGNUM)
5573 (compare (plus:GPR (match_operand:GPR 1 "nonimmediate_operand" "%0,d, 0, 0,d,0,0,0")
5574 (match_operand:GPR 2 "general_operand" " d,d,Op,On,K,R,T,C"))
5575 (match_dup 1)))
5576 (set (match_operand:GPR 0 "nonimmediate_operand" "=d,d, d, d,d,d,d,d")
5577 (plus:GPR (match_dup 1) (match_dup 2)))]
5578 "s390_match_ccmode (insn, CCL1mode)"
5579 "@
5580 al<g>r\t%0,%2
5581 al<g>rk\t%0,%1,%2
5582 al<g>fi\t%0,%2
5583 sl<g>fi\t%0,%n2
5584 al<g>hsik\t%0,%1,%h2
5585 al<g>\t%0,%2
5586 al<y>\t%0,%2
5587 al<g>si\t%0,%c2"
5588 [(set_attr "op_type" "RR<E>,RRF,RIL,RIL,RIE,RX<Y>,RXY,SIY")
5589 (set_attr "cpu_facility" "*,z196,extimm,extimm,z196,*,longdisp,z10")
5590 (set_attr "z10prop" "z10_super_E1,*,z10_super_E1,z10_super_E1,*,
5591 z10_super_E1,z10_super_E1,z10_super_E1")])
5592
5593 ; alr, al, aly, algr, alg, alrk, algrk
5594 (define_insn "*add<mode>3_carry1_cconly"
5595 [(set (reg CC_REGNUM)
5596 (compare (plus:GPR (match_operand:GPR 1 "nonimmediate_operand" "%0,d,0,0")
5597 (match_operand:GPR 2 "general_operand" "d,d,R,T"))
5598 (match_dup 1)))
5599 (clobber (match_scratch:GPR 0 "=d,d,d,d"))]
5600 "s390_match_ccmode (insn, CCL1mode)"
5601 "@
5602 al<g>r\t%0,%2
5603 al<g>rk\t%0,%1,%2
5604 al<g>\t%0,%2
5605 al<y>\t%0,%2"
5606 [(set_attr "op_type" "RR<E>,RRF,RX<Y>,RXY")
5607 (set_attr "cpu_facility" "*,z196,*,longdisp")
5608 (set_attr "z10prop" "z10_super_E1,*,z10_super_E1,z10_super_E1")])
5609
5610 ; alr, alfi, slfi, al, aly, algr, algfi, slgfi, alg, alsi, algsi, alrk, algrk, alhsik, alghsik
5611 (define_insn "*add<mode>3_carry2_cc"
5612 [(set (reg CC_REGNUM)
5613 (compare (plus:GPR (match_operand:GPR 1 "nonimmediate_operand" "%0,d, 0, 0,d,0,0,0")
5614 (match_operand:GPR 2 "general_operand" " d,d,Op,On,K,R,T,C"))
5615 (match_dup 2)))
5616 (set (match_operand:GPR 0 "nonimmediate_operand" "=d,d, d, d,d,d,d,S")
5617 (plus:GPR (match_dup 1) (match_dup 2)))]
5618 "s390_match_ccmode (insn, CCL1mode)"
5619 "@
5620 al<g>r\t%0,%2
5621 al<g>rk\t%0,%1,%2
5622 al<g>fi\t%0,%2
5623 sl<g>fi\t%0,%n2
5624 al<g>hsik\t%0,%1,%h2
5625 al<g>\t%0,%2
5626 al<y>\t%0,%2
5627 al<g>si\t%0,%c2"
5628 [(set_attr "op_type" "RR<E>,RRF,RIL,RIL,RIE,RX<Y>,RXY,SIY")
5629 (set_attr "cpu_facility" "*,z196,extimm,extimm,z196,*,longdisp,z10")
5630 (set_attr "z10prop" "z10_super_E1,*,z10_super_E1,z10_super_E1,*,
5631 z10_super_E1,z10_super_E1,z10_super_E1")])
5632
5633 ; alr, al, aly, algr, alg, alrk, algrk
5634 (define_insn "*add<mode>3_carry2_cconly"
5635 [(set (reg CC_REGNUM)
5636 (compare (plus:GPR (match_operand:GPR 1 "nonimmediate_operand" "%0,d,0,0")
5637 (match_operand:GPR 2 "general_operand" "d,d,R,T"))
5638 (match_dup 2)))
5639 (clobber (match_scratch:GPR 0 "=d,d,d,d"))]
5640 "s390_match_ccmode (insn, CCL1mode)"
5641 "@
5642 al<g>r\t%0,%2
5643 al<g>rk\t%0,%1,%2
5644 al<g>\t%0,%2
5645 al<y>\t%0,%2"
5646 [(set_attr "op_type" "RR<E>,RRF,RX<Y>,RXY")
5647 (set_attr "cpu_facility" "*,z196,*,longdisp")
5648 (set_attr "z10prop" "z10_super_E1,*,z10_super_E1,z10_super_E1")])
5649
5650 ; alr, alfi, slfi, al, aly, algr, algfi, slgfi, alg, alsi, algsi, alrk, algrk, alhsik, alghsik
5651 (define_insn "*add<mode>3_cc"
5652 [(set (reg CC_REGNUM)
5653 (compare (plus:GPR (match_operand:GPR 1 "nonimmediate_operand" "%0,d, 0, 0,d,0,0,0")
5654 (match_operand:GPR 2 "general_operand" " d,d,Op,On,K,R,T,C"))
5655 (const_int 0)))
5656 (set (match_operand:GPR 0 "nonimmediate_operand" "=d,d, d, d,d,d,d,S")
5657 (plus:GPR (match_dup 1) (match_dup 2)))]
5658 "s390_match_ccmode (insn, CCLmode)"
5659 "@
5660 al<g>r\t%0,%2
5661 al<g>rk\t%0,%1,%2
5662 al<g>fi\t%0,%2
5663 sl<g>fi\t%0,%n2
5664 al<g>hsik\t%0,%1,%h2
5665 al<g>\t%0,%2
5666 al<y>\t%0,%2
5667 al<g>si\t%0,%c2"
5668 [(set_attr "op_type" "RR<E>,RRF,RIL,RIL,RIE,RX<Y>,RXY,SIY")
5669 (set_attr "cpu_facility" "*,z196,extimm,extimm,z196,*,longdisp,z10")
5670 (set_attr "z10prop" "z10_super_E1,*,z10_super_E1,z10_super_E1,
5671 *,z10_super_E1,z10_super_E1,z10_super_E1")])
5672
5673 ; alr, al, aly, algr, alg, alrk, algrk
5674 (define_insn "*add<mode>3_cconly"
5675 [(set (reg CC_REGNUM)
5676 (compare (plus:GPR (match_operand:GPR 1 "nonimmediate_operand" "%0,d,0,0")
5677 (match_operand:GPR 2 "general_operand" "d,d,R,T"))
5678 (const_int 0)))
5679 (clobber (match_scratch:GPR 0 "=d,d,d,d"))]
5680 "s390_match_ccmode (insn, CCLmode)"
5681 "@
5682 al<g>r\t%0,%2
5683 al<g>rk\t%0,%1,%2
5684 al<g>\t%0,%2
5685 al<y>\t%0,%2"
5686 [(set_attr "op_type" "RR<E>,RRF,RX<Y>,RXY")
5687 (set_attr "cpu_facility" "*,z196,*,longdisp")
5688 (set_attr "z10prop" "z10_super_E1,*,z10_super_E1,z10_super_E1")])
5689
5690 ; alr, al, aly, algr, alg, alrk, algrk
5691 (define_insn "*add<mode>3_cconly2"
5692 [(set (reg CC_REGNUM)
5693 (compare (match_operand:GPR 1 "nonimmediate_operand" "%0,d,0,0")
5694 (neg:GPR (match_operand:GPR 2 "general_operand" "d,d,R,T"))))
5695 (clobber (match_scratch:GPR 0 "=d,d,d,d"))]
5696 "s390_match_ccmode(insn, CCLmode)"
5697 "@
5698 al<g>r\t%0,%2
5699 al<g>rk\t%0,%1,%2
5700 al<g>\t%0,%2
5701 al<y>\t%0,%2"
5702 [(set_attr "op_type" "RR<E>,RRF,RX<Y>,RXY")
5703 (set_attr "cpu_facility" "*,z196,*,longdisp")
5704 (set_attr "z10prop" "z10_super_E1,*,z10_super_E1,z10_super_E1")])
5705
5706 ; ahi, afi, aghi, agfi, asi, agsi
5707 (define_insn "*add<mode>3_imm_cc"
5708 [(set (reg CC_REGNUM)
5709 (compare (plus:GPR (match_operand:GPR 1 "nonimmediate_operand" " 0, d,0, 0")
5710 (match_operand:GPR 2 "const_int_operand" " K, K,Os,C"))
5711 (const_int 0)))
5712 (set (match_operand:GPR 0 "nonimmediate_operand" "=d, d,d, S")
5713 (plus:GPR (match_dup 1) (match_dup 2)))]
5714 "s390_match_ccmode (insn, CCAmode)
5715 && (CONST_OK_FOR_CONSTRAINT_P (INTVAL (operands[2]), 'K', \"K\")
5716 || (CONST_OK_FOR_CONSTRAINT_P (INTVAL (operands[2]), 'O', \"Os\")
5717 /* Avoid INT32_MIN on 32 bit. */
5718 && (!TARGET_ZARCH || INTVAL (operands[2]) != -0x7fffffff - 1)))"
5719 "@
5720 a<g>hi\t%0,%h2
5721 a<g>hik\t%0,%1,%h2
5722 a<g>fi\t%0,%2
5723 a<g>si\t%0,%c2"
5724 [(set_attr "op_type" "RI,RIE,RIL,SIY")
5725 (set_attr "cpu_facility" "*,z196,extimm,z10")
5726 (set_attr "z10prop" "z10_super_E1,*,z10_super_E1,z10_super_E1")])
5727
5728 ;
5729 ; add(tf|df|sf|td|dd)3 instruction pattern(s).
5730 ;
5731
5732 ; axbr, adbr, aebr, axb, adb, aeb, adtr, axtr
5733 ; FIXME: wfadb does not clobber cc
5734 (define_insn "add<mode>3"
5735 [(set (match_operand:FP 0 "register_operand" "=f,f,f,v")
5736 (plus:FP (match_operand:FP 1 "nonimmediate_operand" "%f,0,0,v")
5737 (match_operand:FP 2 "general_operand" "f,f,R,v")))
5738 (clobber (reg:CC CC_REGNUM))]
5739 "TARGET_HARD_FLOAT"
5740 "@
5741 a<xde>tr\t%0,%1,%2
5742 a<xde>br\t%0,%2
5743 a<xde>b\t%0,%2
5744 wfadb\t%v0,%v1,%v2"
5745 [(set_attr "op_type" "RRF,RRE,RXE,VRR")
5746 (set_attr "type" "fsimp<mode>")
5747 (set_attr "cpu_facility" "*,*,*,vec")
5748 (set_attr "enabled" "<nBFP>,<nDFP>,<DSF>,<DFDI>")])
5749
5750 ; axbr, adbr, aebr, axb, adb, aeb, adtr, axtr
5751 (define_insn "*add<mode>3_cc"
5752 [(set (reg CC_REGNUM)
5753 (compare (plus:FP (match_operand:FP 1 "nonimmediate_operand" "%f,0,0")
5754 (match_operand:FP 2 "general_operand" "f,f,R"))
5755 (match_operand:FP 3 "const0_operand" "")))
5756 (set (match_operand:FP 0 "register_operand" "=f,f,f")
5757 (plus:FP (match_dup 1) (match_dup 2)))]
5758 "s390_match_ccmode (insn, CCSmode) && TARGET_HARD_FLOAT"
5759 "@
5760 a<xde>tr\t%0,%1,%2
5761 a<xde>br\t%0,%2
5762 a<xde>b\t%0,%2"
5763 [(set_attr "op_type" "RRF,RRE,RXE")
5764 (set_attr "type" "fsimp<mode>")
5765 (set_attr "enabled" "<nBFP>,<nDFP>,<DSF>")])
5766
5767 ; axbr, adbr, aebr, axb, adb, aeb, adtr, axtr
5768 (define_insn "*add<mode>3_cconly"
5769 [(set (reg CC_REGNUM)
5770 (compare (plus:FP (match_operand:FP 1 "nonimmediate_operand" "%f,0,0")
5771 (match_operand:FP 2 "general_operand" "f,f,R"))
5772 (match_operand:FP 3 "const0_operand" "")))
5773 (clobber (match_scratch:FP 0 "=f,f,f"))]
5774 "s390_match_ccmode (insn, CCSmode) && TARGET_HARD_FLOAT"
5775 "@
5776 a<xde>tr\t%0,%1,%2
5777 a<xde>br\t%0,%2
5778 a<xde>b\t%0,%2"
5779 [(set_attr "op_type" "RRF,RRE,RXE")
5780 (set_attr "type" "fsimp<mode>")
5781 (set_attr "enabled" "<nBFP>,<nDFP>,<DSF>")])
5782
5783 ;
5784 ; Pointer add instruction patterns
5785 ;
5786
5787 ; This will match "*la_64"
5788 (define_expand "addptrdi3"
5789 [(set (match_operand:DI 0 "register_operand" "")
5790 (plus:DI (match_operand:DI 1 "register_operand" "")
5791 (match_operand:DI 2 "nonmemory_operand" "")))]
5792 "TARGET_64BIT"
5793 {
5794 if (GET_CODE (operands[2]) == CONST_INT)
5795 {
5796 HOST_WIDE_INT c = INTVAL (operands[2]);
5797
5798 if (!CONST_OK_FOR_CONSTRAINT_P (c, 'K', "K")
5799 && !CONST_OK_FOR_CONSTRAINT_P (c, 'O', "Os"))
5800 {
5801 operands[2] = force_const_mem (DImode, operands[2]);
5802 operands[2] = force_reg (DImode, operands[2]);
5803 }
5804 else if (!DISP_IN_RANGE (INTVAL (operands[2])))
5805 operands[2] = force_reg (DImode, operands[2]);
5806 }
5807 })
5808
5809 ; For 31 bit we have to prevent the generated pattern from matching
5810 ; normal ADDs since la only does a 31 bit add. This is supposed to
5811 ; match "force_la_31".
5812 (define_expand "addptrsi3"
5813 [(parallel
5814 [(set (match_operand:SI 0 "register_operand" "")
5815 (plus:SI (match_operand:SI 1 "register_operand" "")
5816 (match_operand:SI 2 "nonmemory_operand" "")))
5817 (use (const_int 0))])]
5818 "!TARGET_64BIT"
5819 {
5820 if (GET_CODE (operands[2]) == CONST_INT)
5821 {
5822 HOST_WIDE_INT c = INTVAL (operands[2]);
5823
5824 if (!CONST_OK_FOR_CONSTRAINT_P (c, 'K', "K")
5825 && !CONST_OK_FOR_CONSTRAINT_P (c, 'O', "Os"))
5826 {
5827 operands[2] = force_const_mem (SImode, operands[2]);
5828 operands[2] = force_reg (SImode, operands[2]);
5829 }
5830 else if (!DISP_IN_RANGE (INTVAL (operands[2])))
5831 operands[2] = force_reg (SImode, operands[2]);
5832 }
5833 })
5834
5835 ;;
5836 ;;- Subtract instructions.
5837 ;;
5838
5839 ;
5840 ; subti3 instruction pattern(s).
5841 ;
5842
5843 (define_expand "subti3"
5844 [(parallel
5845 [(set (match_operand:TI 0 "register_operand" "")
5846 (minus:TI (match_operand:TI 1 "register_operand" "")
5847 (match_operand:TI 2 "general_operand" "") ) )
5848 (clobber (reg:CC CC_REGNUM))])]
5849 "TARGET_ZARCH"
5850 {
5851 /* For z13 we have vsq which doesn't set CC. */
5852 if (TARGET_VX)
5853 {
5854 emit_insn (gen_rtx_SET (operands[0],
5855 gen_rtx_MINUS (TImode,
5856 operands[1],
5857 copy_to_mode_reg (TImode, operands[2]))));
5858 DONE;
5859 }
5860 })
5861
5862 (define_insn_and_split "*subti3"
5863 [(set (match_operand:TI 0 "register_operand" "=&d")
5864 (minus:TI (match_operand:TI 1 "register_operand" "0")
5865 (match_operand:TI 2 "general_operand" "do") ) )
5866 (clobber (reg:CC CC_REGNUM))]
5867 "TARGET_ZARCH"
5868 "#"
5869 "&& reload_completed"
5870 [(parallel
5871 [(set (reg:CCL2 CC_REGNUM)
5872 (compare:CCL2 (minus:DI (match_dup 7) (match_dup 8))
5873 (match_dup 7)))
5874 (set (match_dup 6) (minus:DI (match_dup 7) (match_dup 8)))])
5875 (parallel
5876 [(set (match_dup 3) (minus:DI (minus:DI (match_dup 4) (match_dup 5))
5877 (gtu:DI (reg:CCL2 CC_REGNUM) (const_int 0))))
5878 (clobber (reg:CC CC_REGNUM))])]
5879 "operands[3] = operand_subword (operands[0], 0, 0, TImode);
5880 operands[4] = operand_subword (operands[1], 0, 0, TImode);
5881 operands[5] = operand_subword (operands[2], 0, 0, TImode);
5882 operands[6] = operand_subword (operands[0], 1, 0, TImode);
5883 operands[7] = operand_subword (operands[1], 1, 0, TImode);
5884 operands[8] = operand_subword (operands[2], 1, 0, TImode);"
5885 [(set_attr "op_type" "*")
5886 (set_attr "cpu_facility" "*")])
5887
5888 ;
5889 ; subdi3 instruction pattern(s).
5890 ;
5891
5892 (define_expand "subdi3"
5893 [(parallel
5894 [(set (match_operand:DI 0 "register_operand" "")
5895 (minus:DI (match_operand:DI 1 "register_operand" "")
5896 (match_operand:DI 2 "general_operand" "")))
5897 (clobber (reg:CC CC_REGNUM))])]
5898 ""
5899 "")
5900
5901 (define_insn "*subdi3_sign"
5902 [(set (match_operand:DI 0 "register_operand" "=d,d")
5903 (minus:DI (match_operand:DI 1 "register_operand" "0,0")
5904 (sign_extend:DI (match_operand:SI 2 "general_operand" "d,T"))))
5905 (clobber (reg:CC CC_REGNUM))]
5906 "TARGET_ZARCH"
5907 "@
5908 sgfr\t%0,%2
5909 sgf\t%0,%2"
5910 [(set_attr "op_type" "RRE,RXY")
5911 (set_attr "z10prop" "z10_c,*")
5912 (set_attr "z196prop" "z196_cracked")])
5913
5914 (define_insn "*subdi3_zero_cc"
5915 [(set (reg CC_REGNUM)
5916 (compare (minus:DI (match_operand:DI 1 "register_operand" "0,0")
5917 (zero_extend:DI (match_operand:SI 2 "general_operand" "d,T")))
5918 (const_int 0)))
5919 (set (match_operand:DI 0 "register_operand" "=d,d")
5920 (minus:DI (match_dup 1) (zero_extend:DI (match_dup 2))))]
5921 "s390_match_ccmode (insn, CCLmode) && TARGET_ZARCH"
5922 "@
5923 slgfr\t%0,%2
5924 slgf\t%0,%2"
5925 [(set_attr "op_type" "RRE,RXY")
5926 (set_attr "z10prop" "z10_super_c_E1,z10_super_E1")])
5927
5928 (define_insn "*subdi3_zero_cconly"
5929 [(set (reg CC_REGNUM)
5930 (compare (minus:DI (match_operand:DI 1 "register_operand" "0,0")
5931 (zero_extend:DI (match_operand:SI 2 "general_operand" "d,T")))
5932 (const_int 0)))
5933 (clobber (match_scratch:DI 0 "=d,d"))]
5934 "s390_match_ccmode (insn, CCLmode) && TARGET_ZARCH"
5935 "@
5936 slgfr\t%0,%2
5937 slgf\t%0,%2"
5938 [(set_attr "op_type" "RRE,RXY")
5939 (set_attr "z10prop" "z10_super_c_E1,z10_super_E1")])
5940
5941 (define_insn "*subdi3_zero"
5942 [(set (match_operand:DI 0 "register_operand" "=d,d")
5943 (minus:DI (match_operand:DI 1 "register_operand" "0,0")
5944 (zero_extend:DI (match_operand:SI 2 "general_operand" "d,T"))))
5945 (clobber (reg:CC CC_REGNUM))]
5946 "TARGET_ZARCH"
5947 "@
5948 slgfr\t%0,%2
5949 slgf\t%0,%2"
5950 [(set_attr "op_type" "RRE,RXY")
5951 (set_attr "z10prop" "z10_super_c_E1,z10_super_E1")])
5952
5953 (define_insn_and_split "*subdi3_31z"
5954 [(set (match_operand:DI 0 "register_operand" "=&d")
5955 (minus:DI (match_operand:DI 1 "register_operand" "0")
5956 (match_operand:DI 2 "general_operand" "do") ) )
5957 (clobber (reg:CC CC_REGNUM))]
5958 "!TARGET_ZARCH && TARGET_CPU_ZARCH"
5959 "#"
5960 "&& reload_completed"
5961 [(parallel
5962 [(set (reg:CCL2 CC_REGNUM)
5963 (compare:CCL2 (minus:SI (match_dup 7) (match_dup 8))
5964 (match_dup 7)))
5965 (set (match_dup 6) (minus:SI (match_dup 7) (match_dup 8)))])
5966 (parallel
5967 [(set (match_dup 3) (minus:SI (minus:SI (match_dup 4) (match_dup 5))
5968 (gtu:SI (reg:CCL2 CC_REGNUM) (const_int 0))))
5969 (clobber (reg:CC CC_REGNUM))])]
5970 "operands[3] = operand_subword (operands[0], 0, 0, DImode);
5971 operands[4] = operand_subword (operands[1], 0, 0, DImode);
5972 operands[5] = operand_subword (operands[2], 0, 0, DImode);
5973 operands[6] = operand_subword (operands[0], 1, 0, DImode);
5974 operands[7] = operand_subword (operands[1], 1, 0, DImode);
5975 operands[8] = operand_subword (operands[2], 1, 0, DImode);")
5976
5977 (define_insn_and_split "*subdi3_31"
5978 [(set (match_operand:DI 0 "register_operand" "=&d")
5979 (minus:DI (match_operand:DI 1 "register_operand" "0")
5980 (match_operand:DI 2 "general_operand" "do") ) )
5981 (clobber (reg:CC CC_REGNUM))]
5982 "!TARGET_CPU_ZARCH"
5983 "#"
5984 "&& reload_completed"
5985 [(parallel
5986 [(set (match_dup 3) (minus:SI (match_dup 4) (match_dup 5)))
5987 (clobber (reg:CC CC_REGNUM))])
5988 (parallel
5989 [(set (reg:CCL2 CC_REGNUM)
5990 (compare:CCL2 (minus:SI (match_dup 7) (match_dup 8))
5991 (match_dup 7)))
5992 (set (match_dup 6) (minus:SI (match_dup 7) (match_dup 8)))])
5993 (set (pc)
5994 (if_then_else (gtu (reg:CCL2 CC_REGNUM) (const_int 0))
5995 (pc)
5996 (label_ref (match_dup 9))))
5997 (parallel
5998 [(set (match_dup 3) (plus:SI (match_dup 3) (const_int -1)))
5999 (clobber (reg:CC CC_REGNUM))])
6000 (match_dup 9)]
6001 "operands[3] = operand_subword (operands[0], 0, 0, DImode);
6002 operands[4] = operand_subword (operands[1], 0, 0, DImode);
6003 operands[5] = operand_subword (operands[2], 0, 0, DImode);
6004 operands[6] = operand_subword (operands[0], 1, 0, DImode);
6005 operands[7] = operand_subword (operands[1], 1, 0, DImode);
6006 operands[8] = operand_subword (operands[2], 1, 0, DImode);
6007 operands[9] = gen_label_rtx ();")
6008
6009 ;
6010 ; subsi3 instruction pattern(s).
6011 ;
6012
6013 (define_expand "subsi3"
6014 [(parallel
6015 [(set (match_operand:SI 0 "register_operand" "")
6016 (minus:SI (match_operand:SI 1 "register_operand" "")
6017 (match_operand:SI 2 "general_operand" "")))
6018 (clobber (reg:CC CC_REGNUM))])]
6019 ""
6020 "")
6021
6022 (define_insn "*subsi3_sign"
6023 [(set (match_operand:SI 0 "register_operand" "=d,d")
6024 (minus:SI (match_operand:SI 1 "register_operand" "0,0")
6025 (sign_extend:SI (match_operand:HI 2 "memory_operand" "R,T"))))
6026 (clobber (reg:CC CC_REGNUM))]
6027 ""
6028 "@
6029 sh\t%0,%2
6030 shy\t%0,%2"
6031 [(set_attr "op_type" "RX,RXY")
6032 (set_attr "cpu_facility" "*,longdisp")
6033 (set_attr "z196prop" "z196_cracked,z196_cracked")])
6034
6035 ;
6036 ; sub(di|si)3 instruction pattern(s).
6037 ;
6038
6039 ; sr, s, sy, sgr, sg, srk, sgrk
6040 (define_insn "*sub<mode>3"
6041 [(set (match_operand:GPR 0 "register_operand" "=d,d,d,d")
6042 (minus:GPR (match_operand:GPR 1 "register_operand" "0,d,0,0")
6043 (match_operand:GPR 2 "general_operand" "d,d,R,T") ) )
6044 (clobber (reg:CC CC_REGNUM))]
6045 ""
6046 "@
6047 s<g>r\t%0,%2
6048 s<g>rk\t%0,%1,%2
6049 s<g>\t%0,%2
6050 s<y>\t%0,%2"
6051 [(set_attr "op_type" "RR<E>,RRF,RX<Y>,RXY")
6052 (set_attr "cpu_facility" "*,z196,*,longdisp")
6053 (set_attr "z10prop" "z10_super_c_E1,*,z10_super_E1,z10_super_E1")])
6054
6055 ; slr, sl, sly, slgr, slg, slrk, slgrk
6056 (define_insn "*sub<mode>3_borrow_cc"
6057 [(set (reg CC_REGNUM)
6058 (compare (minus:GPR (match_operand:GPR 1 "register_operand" "0,d,0,0")
6059 (match_operand:GPR 2 "general_operand" "d,d,R,T"))
6060 (match_dup 1)))
6061 (set (match_operand:GPR 0 "register_operand" "=d,d,d,d")
6062 (minus:GPR (match_dup 1) (match_dup 2)))]
6063 "s390_match_ccmode (insn, CCL2mode)"
6064 "@
6065 sl<g>r\t%0,%2
6066 sl<g>rk\t%0,%1,%2
6067 sl<g>\t%0,%2
6068 sl<y>\t%0,%2"
6069 [(set_attr "op_type" "RR<E>,RRF,RX<Y>,RXY")
6070 (set_attr "cpu_facility" "*,z196,*,longdisp")
6071 (set_attr "z10prop" "z10_super_c_E1,*,z10_super_E1,z10_super_E1")])
6072
6073 ; slr, sl, sly, slgr, slg, slrk, slgrk
6074 (define_insn "*sub<mode>3_borrow_cconly"
6075 [(set (reg CC_REGNUM)
6076 (compare (minus:GPR (match_operand:GPR 1 "register_operand" "0,d,0,0")
6077 (match_operand:GPR 2 "general_operand" "d,d,R,T"))
6078 (match_dup 1)))
6079 (clobber (match_scratch:GPR 0 "=d,d,d,d"))]
6080 "s390_match_ccmode (insn, CCL2mode)"
6081 "@
6082 sl<g>r\t%0,%2
6083 sl<g>rk\t%0,%1,%2
6084 sl<g>\t%0,%2
6085 sl<y>\t%0,%2"
6086 [(set_attr "op_type" "RR<E>,RRF,RX<Y>,RXY")
6087 (set_attr "cpu_facility" "*,z196,*,longdisp")
6088 (set_attr "z10prop" "z10_super_c_E1,*,z10_super_E1,z10_super_E1")])
6089
6090 ; slr, sl, sly, slgr, slg, slrk, slgrk
6091 (define_insn "*sub<mode>3_cc"
6092 [(set (reg CC_REGNUM)
6093 (compare (minus:GPR (match_operand:GPR 1 "register_operand" "0,d,0,0")
6094 (match_operand:GPR 2 "general_operand" "d,d,R,T"))
6095 (const_int 0)))
6096 (set (match_operand:GPR 0 "register_operand" "=d,d,d,d")
6097 (minus:GPR (match_dup 1) (match_dup 2)))]
6098 "s390_match_ccmode (insn, CCLmode)"
6099 "@
6100 sl<g>r\t%0,%2
6101 sl<g>rk\t%0,%1,%2
6102 sl<g>\t%0,%2
6103 sl<y>\t%0,%2"
6104 [(set_attr "op_type" "RR<E>,RRF,RX<Y>,RXY")
6105 (set_attr "cpu_facility" "*,z196,*,longdisp")
6106 (set_attr "z10prop" "z10_super_c_E1,*,z10_super_E1,z10_super_E1")])
6107
6108 ; slr, sl, sly, slgr, slg, slrk, slgrk
6109 (define_insn "*sub<mode>3_cc2"
6110 [(set (reg CC_REGNUM)
6111 (compare (match_operand:GPR 1 "register_operand" "0,d,0,0")
6112 (match_operand:GPR 2 "general_operand" "d,d,R,T")))
6113 (set (match_operand:GPR 0 "register_operand" "=d,d,d,d")
6114 (minus:GPR (match_dup 1) (match_dup 2)))]
6115 "s390_match_ccmode (insn, CCL3mode)"
6116 "@
6117 sl<g>r\t%0,%2
6118 sl<g>rk\t%0,%1,%2
6119 sl<g>\t%0,%2
6120 sl<y>\t%0,%2"
6121 [(set_attr "op_type" "RR<E>,RRF,RX<Y>,RXY")
6122 (set_attr "cpu_facility" "*,z196,*,longdisp")
6123 (set_attr "z10prop" "z10_super_c_E1,*,z10_super_E1,z10_super_E1")])
6124
6125 ; slr, sl, sly, slgr, slg, slrk, slgrk
6126 (define_insn "*sub<mode>3_cconly"
6127 [(set (reg CC_REGNUM)
6128 (compare (minus:GPR (match_operand:GPR 1 "register_operand" "0,d,0,0")
6129 (match_operand:GPR 2 "general_operand" "d,d,R,T"))
6130 (const_int 0)))
6131 (clobber (match_scratch:GPR 0 "=d,d,d,d"))]
6132 "s390_match_ccmode (insn, CCLmode)"
6133 "@
6134 sl<g>r\t%0,%2
6135 sl<g>rk\t%0,%1,%2
6136 sl<g>\t%0,%2
6137 sl<y>\t%0,%2"
6138 [(set_attr "op_type" "RR<E>,RRF,RX<Y>,RXY")
6139 (set_attr "cpu_facility" "*,z196,*,longdisp")
6140 (set_attr "z10prop" "z10_super_c_E1,*,z10_super_E1,z10_super_E1")])
6141
6142
6143 ; slr, sl, sly, slgr, slg, slrk, slgrk
6144 (define_insn "*sub<mode>3_cconly2"
6145 [(set (reg CC_REGNUM)
6146 (compare (match_operand:GPR 1 "register_operand" "0,d,0,0")
6147 (match_operand:GPR 2 "general_operand" "d,d,R,T")))
6148 (clobber (match_scratch:GPR 0 "=d,d,d,d"))]
6149 "s390_match_ccmode (insn, CCL3mode)"
6150 "@
6151 sl<g>r\t%0,%2
6152 sl<g>rk\t%0,%1,%2
6153 sl<g>\t%0,%2
6154 sl<y>\t%0,%2"
6155 [(set_attr "op_type" "RR<E>,RRF,RX<Y>,RXY")
6156 (set_attr "cpu_facility" "*,z196,*,longdisp")
6157 (set_attr "z10prop" "z10_super_c_E1,*,z10_super_E1,z10_super_E1")])
6158
6159
6160 ;
6161 ; sub(tf|df|sf|td|dd)3 instruction pattern(s).
6162 ;
6163
6164 ; sxbr, sdbr, sebr, sdb, seb, sxtr, sdtr
6165 (define_insn "sub<mode>3"
6166 [(set (match_operand:FP 0 "register_operand" "=f,f,f,v")
6167 (minus:FP (match_operand:FP 1 "register_operand" "f,0,0,v")
6168 (match_operand:FP 2 "general_operand" "f,f,R,v")))
6169 (clobber (reg:CC CC_REGNUM))]
6170 "TARGET_HARD_FLOAT"
6171 "@
6172 s<xde>tr\t%0,%1,%2
6173 s<xde>br\t%0,%2
6174 s<xde>b\t%0,%2
6175 wfsdb\t%v0,%v1,%v2"
6176 [(set_attr "op_type" "RRF,RRE,RXE,VRR")
6177 (set_attr "type" "fsimp<mode>")
6178 (set_attr "cpu_facility" "*,*,*,vec")
6179 (set_attr "enabled" "<nBFP>,<nDFP>,<DSF>,<DFDI>")])
6180
6181 ; sxbr, sdbr, sebr, sdb, seb, sxtr, sdtr
6182 (define_insn "*sub<mode>3_cc"
6183 [(set (reg CC_REGNUM)
6184 (compare (minus:FP (match_operand:FP 1 "nonimmediate_operand" "f,0,0")
6185 (match_operand:FP 2 "general_operand" "f,f,R"))
6186 (match_operand:FP 3 "const0_operand" "")))
6187 (set (match_operand:FP 0 "register_operand" "=f,f,f")
6188 (minus:FP (match_dup 1) (match_dup 2)))]
6189 "s390_match_ccmode (insn, CCSmode) && TARGET_HARD_FLOAT"
6190 "@
6191 s<xde>tr\t%0,%1,%2
6192 s<xde>br\t%0,%2
6193 s<xde>b\t%0,%2"
6194 [(set_attr "op_type" "RRF,RRE,RXE")
6195 (set_attr "type" "fsimp<mode>")
6196 (set_attr "enabled" "<nBFP>,<nDFP>,<DSF>")])
6197
6198 ; sxbr, sdbr, sebr, sdb, seb, sxtr, sdtr
6199 (define_insn "*sub<mode>3_cconly"
6200 [(set (reg CC_REGNUM)
6201 (compare (minus:FP (match_operand:FP 1 "nonimmediate_operand" "f,0,0")
6202 (match_operand:FP 2 "general_operand" "f,f,R"))
6203 (match_operand:FP 3 "const0_operand" "")))
6204 (clobber (match_scratch:FP 0 "=f,f,f"))]
6205 "s390_match_ccmode (insn, CCSmode) && TARGET_HARD_FLOAT"
6206 "@
6207 s<xde>tr\t%0,%1,%2
6208 s<xde>br\t%0,%2
6209 s<xde>b\t%0,%2"
6210 [(set_attr "op_type" "RRF,RRE,RXE")
6211 (set_attr "type" "fsimp<mode>")
6212 (set_attr "enabled" "<nBFP>,<nDFP>,<DSF>")])
6213
6214
6215 ;;
6216 ;;- Conditional add/subtract instructions.
6217 ;;
6218
6219 ;
6220 ; add(di|si)cc instruction pattern(s).
6221 ;
6222
6223 ; the following 4 patterns are used when the result of an add with
6224 ; carry is checked for an overflow condition
6225
6226 ; op1 + op2 + c < op1
6227
6228 ; alcr, alc, alcgr, alcg
6229 (define_insn "*add<mode>3_alc_carry1_cc"
6230 [(set (reg CC_REGNUM)
6231 (compare
6232 (plus:GPR (plus:GPR (match_operand:GPR 3 "s390_alc_comparison" "")
6233 (match_operand:GPR 1 "nonimmediate_operand" "%0,0"))
6234 (match_operand:GPR 2 "general_operand" "d,T"))
6235 (match_dup 1)))
6236 (set (match_operand:GPR 0 "register_operand" "=d,d")
6237 (plus:GPR (plus:GPR (match_dup 3) (match_dup 1)) (match_dup 2)))]
6238 "s390_match_ccmode (insn, CCL1mode) && TARGET_CPU_ZARCH"
6239 "@
6240 alc<g>r\t%0,%2
6241 alc<g>\t%0,%2"
6242 [(set_attr "op_type" "RRE,RXY")
6243 (set_attr "z196prop" "z196_alone,z196_alone")])
6244
6245 ; alcr, alc, alcgr, alcg
6246 (define_insn "*add<mode>3_alc_carry1_cconly"
6247 [(set (reg CC_REGNUM)
6248 (compare
6249 (plus:GPR (plus:GPR (match_operand:GPR 3 "s390_alc_comparison" "")
6250 (match_operand:GPR 1 "nonimmediate_operand" "%0,0"))
6251 (match_operand:GPR 2 "general_operand" "d,T"))
6252 (match_dup 1)))
6253 (clobber (match_scratch:GPR 0 "=d,d"))]
6254 "s390_match_ccmode (insn, CCL1mode) && TARGET_CPU_ZARCH"
6255 "@
6256 alc<g>r\t%0,%2
6257 alc<g>\t%0,%2"
6258 [(set_attr "op_type" "RRE,RXY")
6259 (set_attr "z196prop" "z196_alone,z196_alone")])
6260
6261 ; op1 + op2 + c < op2
6262
6263 ; alcr, alc, alcgr, alcg
6264 (define_insn "*add<mode>3_alc_carry2_cc"
6265 [(set (reg CC_REGNUM)
6266 (compare
6267 (plus:GPR (plus:GPR (match_operand:GPR 3 "s390_alc_comparison" "")
6268 (match_operand:GPR 1 "nonimmediate_operand" "%0,0"))
6269 (match_operand:GPR 2 "general_operand" "d,T"))
6270 (match_dup 2)))
6271 (set (match_operand:GPR 0 "register_operand" "=d,d")
6272 (plus:GPR (plus:GPR (match_dup 3) (match_dup 1)) (match_dup 2)))]
6273 "s390_match_ccmode (insn, CCL1mode) && TARGET_CPU_ZARCH"
6274 "@
6275 alc<g>r\t%0,%2
6276 alc<g>\t%0,%2"
6277 [(set_attr "op_type" "RRE,RXY")])
6278
6279 ; alcr, alc, alcgr, alcg
6280 (define_insn "*add<mode>3_alc_carry2_cconly"
6281 [(set (reg CC_REGNUM)
6282 (compare
6283 (plus:GPR (plus:GPR (match_operand:GPR 3 "s390_alc_comparison" "")
6284 (match_operand:GPR 1 "nonimmediate_operand" "%0,0"))
6285 (match_operand:GPR 2 "general_operand" "d,T"))
6286 (match_dup 2)))
6287 (clobber (match_scratch:GPR 0 "=d,d"))]
6288 "s390_match_ccmode (insn, CCL1mode) && TARGET_CPU_ZARCH"
6289 "@
6290 alc<g>r\t%0,%2
6291 alc<g>\t%0,%2"
6292 [(set_attr "op_type" "RRE,RXY")])
6293
6294 ; alcr, alc, alcgr, alcg
6295 (define_insn "*add<mode>3_alc_cc"
6296 [(set (reg CC_REGNUM)
6297 (compare
6298 (plus:GPR (plus:GPR (match_operand:GPR 3 "s390_alc_comparison" "")
6299 (match_operand:GPR 1 "nonimmediate_operand" "%0,0"))
6300 (match_operand:GPR 2 "general_operand" "d,T"))
6301 (const_int 0)))
6302 (set (match_operand:GPR 0 "register_operand" "=d,d")
6303 (plus:GPR (plus:GPR (match_dup 3) (match_dup 1)) (match_dup 2)))]
6304 "s390_match_ccmode (insn, CCLmode) && TARGET_CPU_ZARCH"
6305 "@
6306 alc<g>r\t%0,%2
6307 alc<g>\t%0,%2"
6308 [(set_attr "op_type" "RRE,RXY")])
6309
6310 ; alcr, alc, alcgr, alcg
6311 (define_insn "*add<mode>3_alc"
6312 [(set (match_operand:GPR 0 "register_operand" "=d,d")
6313 (plus:GPR (plus:GPR (match_operand:GPR 3 "s390_alc_comparison" "")
6314 (match_operand:GPR 1 "nonimmediate_operand" "%0,0"))
6315 (match_operand:GPR 2 "general_operand" "d,T")))
6316 (clobber (reg:CC CC_REGNUM))]
6317 "TARGET_CPU_ZARCH"
6318 "@
6319 alc<g>r\t%0,%2
6320 alc<g>\t%0,%2"
6321 [(set_attr "op_type" "RRE,RXY")])
6322
6323 ; slbr, slb, slbgr, slbg
6324 (define_insn "*sub<mode>3_slb_cc"
6325 [(set (reg CC_REGNUM)
6326 (compare
6327 (minus:GPR (minus:GPR (match_operand:GPR 1 "nonimmediate_operand" "0,0")
6328 (match_operand:GPR 2 "general_operand" "d,T"))
6329 (match_operand:GPR 3 "s390_slb_comparison" ""))
6330 (const_int 0)))
6331 (set (match_operand:GPR 0 "register_operand" "=d,d")
6332 (minus:GPR (minus:GPR (match_dup 1) (match_dup 2)) (match_dup 3)))]
6333 "s390_match_ccmode (insn, CCLmode) && TARGET_CPU_ZARCH"
6334 "@
6335 slb<g>r\t%0,%2
6336 slb<g>\t%0,%2"
6337 [(set_attr "op_type" "RRE,RXY")
6338 (set_attr "z10prop" "z10_c,*")])
6339
6340 ; slbr, slb, slbgr, slbg
6341 (define_insn "*sub<mode>3_slb"
6342 [(set (match_operand:GPR 0 "register_operand" "=d,d")
6343 (minus:GPR (minus:GPR (match_operand:GPR 1 "nonimmediate_operand" "0,0")
6344 (match_operand:GPR 2 "general_operand" "d,T"))
6345 (match_operand:GPR 3 "s390_slb_comparison" "")))
6346 (clobber (reg:CC CC_REGNUM))]
6347 "TARGET_CPU_ZARCH"
6348 "@
6349 slb<g>r\t%0,%2
6350 slb<g>\t%0,%2"
6351 [(set_attr "op_type" "RRE,RXY")
6352 (set_attr "z10prop" "z10_c,*")])
6353
6354 (define_expand "add<mode>cc"
6355 [(match_operand:GPR 0 "register_operand" "")
6356 (match_operand 1 "comparison_operator" "")
6357 (match_operand:GPR 2 "register_operand" "")
6358 (match_operand:GPR 3 "const_int_operand" "")]
6359 "TARGET_CPU_ZARCH"
6360 "if (!s390_expand_addcc (GET_CODE (operands[1]),
6361 XEXP (operands[1], 0), XEXP (operands[1], 1),
6362 operands[0], operands[2],
6363 operands[3])) FAIL; DONE;")
6364
6365 ;
6366 ; scond instruction pattern(s).
6367 ;
6368
6369 (define_insn_and_split "*scond<mode>"
6370 [(set (match_operand:GPR 0 "register_operand" "=&d")
6371 (match_operand:GPR 1 "s390_alc_comparison" ""))
6372 (clobber (reg:CC CC_REGNUM))]
6373 "TARGET_CPU_ZARCH"
6374 "#"
6375 "&& reload_completed"
6376 [(set (match_dup 0) (const_int 0))
6377 (parallel
6378 [(set (match_dup 0) (plus:GPR (plus:GPR (match_dup 1) (match_dup 0))
6379 (match_dup 0)))
6380 (clobber (reg:CC CC_REGNUM))])]
6381 "")
6382
6383 (define_insn_and_split "*scond<mode>_neg"
6384 [(set (match_operand:GPR 0 "register_operand" "=&d")
6385 (match_operand:GPR 1 "s390_slb_comparison" ""))
6386 (clobber (reg:CC CC_REGNUM))]
6387 "TARGET_CPU_ZARCH"
6388 "#"
6389 "&& reload_completed"
6390 [(set (match_dup 0) (const_int 0))
6391 (parallel
6392 [(set (match_dup 0) (minus:GPR (minus:GPR (match_dup 0) (match_dup 0))
6393 (match_dup 1)))
6394 (clobber (reg:CC CC_REGNUM))])
6395 (parallel
6396 [(set (match_dup 0) (neg:GPR (match_dup 0)))
6397 (clobber (reg:CC CC_REGNUM))])]
6398 "")
6399
6400
6401 (define_expand "cstore<mode>4"
6402 [(set (match_operand:SI 0 "register_operand" "")
6403 (match_operator:SI 1 "s390_scond_operator"
6404 [(match_operand:GPR 2 "register_operand" "")
6405 (match_operand:GPR 3 "general_operand" "")]))]
6406 "TARGET_CPU_ZARCH"
6407 "if (!s390_expand_addcc (GET_CODE (operands[1]), operands[2], operands[3],
6408 operands[0], const0_rtx, const1_rtx)) FAIL; DONE;")
6409
6410 (define_expand "cstorecc4"
6411 [(parallel
6412 [(set (match_operand:SI 0 "register_operand" "")
6413 (match_operator:SI 1 "s390_eqne_operator"
6414 [(match_operand:CCZ1 2 "register_operand")
6415 (match_operand 3 "const0_operand")]))
6416 (clobber (reg:CC CC_REGNUM))])]
6417 ""
6418 "emit_insn (gen_sne (operands[0], operands[2]));
6419 if (GET_CODE (operands[1]) == EQ)
6420 emit_insn (gen_xorsi3 (operands[0], operands[0], const1_rtx));
6421 DONE;")
6422
6423 (define_insn_and_split "sne"
6424 [(set (match_operand:SI 0 "register_operand" "=d")
6425 (ne:SI (match_operand:CCZ1 1 "register_operand" "0")
6426 (const_int 0)))
6427 (clobber (reg:CC CC_REGNUM))]
6428 ""
6429 "#"
6430 "reload_completed"
6431 [(parallel
6432 [(set (match_dup 0) (ashiftrt:SI (match_dup 0) (const_int 28)))
6433 (clobber (reg:CC CC_REGNUM))])])
6434
6435
6436 ;;
6437 ;; - Conditional move instructions (introduced with z196)
6438 ;;
6439
6440 (define_expand "mov<mode>cc"
6441 [(set (match_operand:GPR 0 "nonimmediate_operand" "")
6442 (if_then_else:GPR (match_operand 1 "comparison_operator" "")
6443 (match_operand:GPR 2 "nonimmediate_operand" "")
6444 (match_operand:GPR 3 "nonimmediate_operand" "")))]
6445 "TARGET_Z196"
6446 {
6447 /* Emit the comparison insn in case we do not already have a comparison result. */
6448 if (!s390_comparison (operands[1], VOIDmode))
6449 operands[1] = s390_emit_compare (GET_CODE (operands[1]),
6450 XEXP (operands[1], 0),
6451 XEXP (operands[1], 1));
6452 })
6453
6454 ; locr, loc, stoc, locgr, locg, stocg, lochi, locghi
6455 (define_insn_and_split "*mov<mode>cc"
6456 [(set (match_operand:GPR 0 "nonimmediate_operand" "=d,d,d,d,d,d,S,S,&d")
6457 (if_then_else:GPR
6458 (match_operator 1 "s390_comparison"
6459 [(match_operand 2 "cc_reg_operand" " c,c,c,c,c,c,c,c,c")
6460 (match_operand 5 "const_int_operand" "")])
6461 (match_operand:GPR 3 "loc_operand" " d,0,S,0,K,0,d,0,S")
6462 (match_operand:GPR 4 "loc_operand" " 0,d,0,S,0,K,0,d,S")))]
6463 "TARGET_Z196"
6464 "@
6465 loc<g>r%C1\t%0,%3
6466 loc<g>r%D1\t%0,%4
6467 loc<g>%C1\t%0,%3
6468 loc<g>%D1\t%0,%4
6469 loc<g>hi%C1\t%0,%h3
6470 loc<g>hi%D1\t%0,%h4
6471 stoc<g>%C1\t%3,%0
6472 stoc<g>%D1\t%4,%0
6473 #"
6474 "&& reload_completed
6475 && MEM_P (operands[3]) && MEM_P (operands[4])"
6476 [(set (match_dup 0)
6477 (if_then_else:GPR
6478 (match_op_dup 1 [(match_dup 2) (const_int 0)])
6479 (match_dup 3)
6480 (match_dup 0)))
6481 (set (match_dup 0)
6482 (if_then_else:GPR
6483 (match_op_dup 1 [(match_dup 2) (const_int 0)])
6484 (match_dup 0)
6485 (match_dup 4)))]
6486 ""
6487 [(set_attr "op_type" "RRF,RRF,RSY,RSY,RIE,RIE,RSY,RSY,*")
6488 (set_attr "cpu_facility" "*,*,*,*,z13,z13,*,*,*")])
6489
6490 ;;
6491 ;;- Multiply instructions.
6492 ;;
6493
6494 ;
6495 ; muldi3 instruction pattern(s).
6496 ;
6497
6498 (define_insn "*muldi3_sign"
6499 [(set (match_operand:DI 0 "register_operand" "=d,d")
6500 (mult:DI (sign_extend:DI (match_operand:SI 2 "general_operand" "d,T"))
6501 (match_operand:DI 1 "register_operand" "0,0")))]
6502 "TARGET_ZARCH"
6503 "@
6504 msgfr\t%0,%2
6505 msgf\t%0,%2"
6506 [(set_attr "op_type" "RRE,RXY")
6507 (set_attr "type" "imuldi")])
6508
6509 (define_insn "muldi3"
6510 [(set (match_operand:DI 0 "register_operand" "=d,d,d,d")
6511 (mult:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,0")
6512 (match_operand:DI 2 "general_operand" "d,K,T,Os")))]
6513 "TARGET_ZARCH"
6514 "@
6515 msgr\t%0,%2
6516 mghi\t%0,%h2
6517 msg\t%0,%2
6518 msgfi\t%0,%2"
6519 [(set_attr "op_type" "RRE,RI,RXY,RIL")
6520 (set_attr "type" "imuldi")
6521 (set_attr "cpu_facility" "*,*,*,z10")])
6522
6523 ;
6524 ; mulsi3 instruction pattern(s).
6525 ;
6526
6527 (define_insn "*mulsi3_sign"
6528 [(set (match_operand:SI 0 "register_operand" "=d,d")
6529 (mult:SI (sign_extend:SI (match_operand:HI 2 "memory_operand" "R,T"))
6530 (match_operand:SI 1 "register_operand" "0,0")))]
6531 ""
6532 "@
6533 mh\t%0,%2
6534 mhy\t%0,%2"
6535 [(set_attr "op_type" "RX,RXY")
6536 (set_attr "type" "imulhi")
6537 (set_attr "cpu_facility" "*,z10")])
6538
6539 (define_insn "mulsi3"
6540 [(set (match_operand:SI 0 "register_operand" "=d,d,d,d,d")
6541 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,0,0,0")
6542 (match_operand:SI 2 "general_operand" "d,K,R,T,Os")))]
6543 ""
6544 "@
6545 msr\t%0,%2
6546 mhi\t%0,%h2
6547 ms\t%0,%2
6548 msy\t%0,%2
6549 msfi\t%0,%2"
6550 [(set_attr "op_type" "RRE,RI,RX,RXY,RIL")
6551 (set_attr "type" "imulsi,imulhi,imulsi,imulsi,imulsi")
6552 (set_attr "cpu_facility" "*,*,*,longdisp,z10")])
6553
6554 ;
6555 ; mulsidi3 instruction pattern(s).
6556 ;
6557
6558 (define_insn "mulsidi3"
6559 [(set (match_operand:DI 0 "register_operand" "=d,d,d")
6560 (mult:DI (sign_extend:DI
6561 (match_operand:SI 1 "register_operand" "%0,0,0"))
6562 (sign_extend:DI
6563 (match_operand:SI 2 "nonimmediate_operand" "d,R,T"))))]
6564 "!TARGET_ZARCH"
6565 "@
6566 mr\t%0,%2
6567 m\t%0,%2
6568 mfy\t%0,%2"
6569 [(set_attr "op_type" "RR,RX,RXY")
6570 (set_attr "type" "imulsi")
6571 (set_attr "cpu_facility" "*,*,z10")])
6572
6573 ;
6574 ; umul instruction pattern(s).
6575 ;
6576
6577 ; mlr, ml, mlgr, mlg
6578 (define_insn "umul<dwh><mode>3"
6579 [(set (match_operand:DW 0 "register_operand" "=d,d")
6580 (mult:DW (zero_extend:DW
6581 (match_operand:<DWH> 1 "register_operand" "%0,0"))
6582 (zero_extend:DW
6583 (match_operand:<DWH> 2 "nonimmediate_operand" " d,T"))))]
6584 "TARGET_CPU_ZARCH"
6585 "@
6586 ml<tg>r\t%0,%2
6587 ml<tg>\t%0,%2"
6588 [(set_attr "op_type" "RRE,RXY")
6589 (set_attr "type" "imul<dwh>")])
6590
6591 ;
6592 ; mul(tf|df|sf|td|dd)3 instruction pattern(s).
6593 ;
6594
6595 ; mxbr, mdbr, meebr, mxb, mxb, meeb, mdtr, mxtr
6596 (define_insn "mul<mode>3"
6597 [(set (match_operand:FP 0 "register_operand" "=f,f,f,v")
6598 (mult:FP (match_operand:FP 1 "nonimmediate_operand" "%f,0,0,v")
6599 (match_operand:FP 2 "general_operand" "f,f,R,v")))]
6600 "TARGET_HARD_FLOAT"
6601 "@
6602 m<xdee>tr\t%0,%1,%2
6603 m<xdee>br\t%0,%2
6604 m<xdee>b\t%0,%2
6605 wfmdb\t%v0,%v1,%v2"
6606 [(set_attr "op_type" "RRF,RRE,RXE,VRR")
6607 (set_attr "type" "fmul<mode>")
6608 (set_attr "cpu_facility" "*,*,*,vec")
6609 (set_attr "enabled" "<nBFP>,<nDFP>,<DSF>,<DFDI>")])
6610
6611 ; madbr, maebr, maxb, madb, maeb
6612 (define_insn "fma<mode>4"
6613 [(set (match_operand:DSF 0 "register_operand" "=f,f,v")
6614 (fma:DSF (match_operand:DSF 1 "nonimmediate_operand" "%f,f,v")
6615 (match_operand:DSF 2 "nonimmediate_operand" "f,R,v")
6616 (match_operand:DSF 3 "register_operand" "0,0,v")))]
6617 "TARGET_HARD_FLOAT"
6618 "@
6619 ma<xde>br\t%0,%1,%2
6620 ma<xde>b\t%0,%1,%2
6621 wfmadb\t%v0,%v1,%v2,%v3"
6622 [(set_attr "op_type" "RRE,RXE,VRR")
6623 (set_attr "type" "fmadd<mode>")
6624 (set_attr "cpu_facility" "*,*,vec")
6625 (set_attr "enabled" "*,*,<DFDI>")])
6626
6627 ; msxbr, msdbr, msebr, msxb, msdb, mseb
6628 (define_insn "fms<mode>4"
6629 [(set (match_operand:DSF 0 "register_operand" "=f,f,v")
6630 (fma:DSF (match_operand:DSF 1 "nonimmediate_operand" "%f,f,v")
6631 (match_operand:DSF 2 "nonimmediate_operand" "f,R,v")
6632 (neg:DSF (match_operand:DSF 3 "register_operand" "0,0,v"))))]
6633 "TARGET_HARD_FLOAT"
6634 "@
6635 ms<xde>br\t%0,%1,%2
6636 ms<xde>b\t%0,%1,%2
6637 wfmsdb\t%v0,%v1,%v2,%v3"
6638 [(set_attr "op_type" "RRE,RXE,VRR")
6639 (set_attr "type" "fmadd<mode>")
6640 (set_attr "cpu_facility" "*,*,vec")
6641 (set_attr "enabled" "*,*,<DFDI>")])
6642
6643 ;;
6644 ;;- Divide and modulo instructions.
6645 ;;
6646
6647 ;
6648 ; divmoddi4 instruction pattern(s).
6649 ;
6650
6651 (define_expand "divmoddi4"
6652 [(parallel [(set (match_operand:DI 0 "general_operand" "")
6653 (div:DI (match_operand:DI 1 "register_operand" "")
6654 (match_operand:DI 2 "general_operand" "")))
6655 (set (match_operand:DI 3 "general_operand" "")
6656 (mod:DI (match_dup 1) (match_dup 2)))])
6657 (clobber (match_dup 4))]
6658 "TARGET_ZARCH"
6659 {
6660 rtx div_equal, mod_equal;
6661 rtx_insn *insn;
6662
6663 div_equal = gen_rtx_DIV (DImode, operands[1], operands[2]);
6664 mod_equal = gen_rtx_MOD (DImode, operands[1], operands[2]);
6665
6666 operands[4] = gen_reg_rtx(TImode);
6667 emit_insn (gen_divmodtidi3 (operands[4], operands[1], operands[2]));
6668
6669 insn = emit_move_insn (operands[0], gen_lowpart (DImode, operands[4]));
6670 set_unique_reg_note (insn, REG_EQUAL, div_equal);
6671
6672 insn = emit_move_insn (operands[3], gen_highpart (DImode, operands[4]));
6673 set_unique_reg_note (insn, REG_EQUAL, mod_equal);
6674
6675 DONE;
6676 })
6677
6678 (define_insn "divmodtidi3"
6679 [(set (match_operand:TI 0 "register_operand" "=d,d")
6680 (ior:TI
6681 (ashift:TI
6682 (zero_extend:TI
6683 (mod:DI (match_operand:DI 1 "register_operand" "0,0")
6684 (match_operand:DI 2 "general_operand" "d,T")))
6685 (const_int 64))
6686 (zero_extend:TI (div:DI (match_dup 1) (match_dup 2)))))]
6687 "TARGET_ZARCH"
6688 "@
6689 dsgr\t%0,%2
6690 dsg\t%0,%2"
6691 [(set_attr "op_type" "RRE,RXY")
6692 (set_attr "type" "idiv")])
6693
6694 (define_insn "divmodtisi3"
6695 [(set (match_operand:TI 0 "register_operand" "=d,d")
6696 (ior:TI
6697 (ashift:TI
6698 (zero_extend:TI
6699 (mod:DI (match_operand:DI 1 "register_operand" "0,0")
6700 (sign_extend:DI
6701 (match_operand:SI 2 "nonimmediate_operand" "d,T"))))
6702 (const_int 64))
6703 (zero_extend:TI
6704 (div:DI (match_dup 1) (sign_extend:DI (match_dup 2))))))]
6705 "TARGET_ZARCH"
6706 "@
6707 dsgfr\t%0,%2
6708 dsgf\t%0,%2"
6709 [(set_attr "op_type" "RRE,RXY")
6710 (set_attr "type" "idiv")])
6711
6712 ;
6713 ; udivmoddi4 instruction pattern(s).
6714 ;
6715
6716 (define_expand "udivmoddi4"
6717 [(parallel [(set (match_operand:DI 0 "general_operand" "")
6718 (udiv:DI (match_operand:DI 1 "general_operand" "")
6719 (match_operand:DI 2 "nonimmediate_operand" "")))
6720 (set (match_operand:DI 3 "general_operand" "")
6721 (umod:DI (match_dup 1) (match_dup 2)))])
6722 (clobber (match_dup 4))]
6723 "TARGET_ZARCH"
6724 {
6725 rtx div_equal, mod_equal, equal;
6726 rtx_insn *insn;
6727
6728 div_equal = gen_rtx_UDIV (DImode, operands[1], operands[2]);
6729 mod_equal = gen_rtx_UMOD (DImode, operands[1], operands[2]);
6730 equal = gen_rtx_IOR (TImode,
6731 gen_rtx_ASHIFT (TImode,
6732 gen_rtx_ZERO_EXTEND (TImode, mod_equal),
6733 GEN_INT (64)),
6734 gen_rtx_ZERO_EXTEND (TImode, div_equal));
6735
6736 operands[4] = gen_reg_rtx(TImode);
6737 emit_clobber (operands[4]);
6738 emit_move_insn (gen_lowpart (DImode, operands[4]), operands[1]);
6739 emit_move_insn (gen_highpart (DImode, operands[4]), const0_rtx);
6740
6741 insn = emit_insn (gen_udivmodtidi3 (operands[4], operands[4], operands[2]));
6742 set_unique_reg_note (insn, REG_EQUAL, equal);
6743
6744 insn = emit_move_insn (operands[0], gen_lowpart (DImode, operands[4]));
6745 set_unique_reg_note (insn, REG_EQUAL, div_equal);
6746
6747 insn = emit_move_insn (operands[3], gen_highpart (DImode, operands[4]));
6748 set_unique_reg_note (insn, REG_EQUAL, mod_equal);
6749
6750 DONE;
6751 })
6752
6753 (define_insn "udivmodtidi3"
6754 [(set (match_operand:TI 0 "register_operand" "=d,d")
6755 (ior:TI
6756 (ashift:TI
6757 (zero_extend:TI
6758 (truncate:DI
6759 (umod:TI (match_operand:TI 1 "register_operand" "0,0")
6760 (zero_extend:TI
6761 (match_operand:DI 2 "nonimmediate_operand" "d,T")))))
6762 (const_int 64))
6763 (zero_extend:TI
6764 (truncate:DI
6765 (udiv:TI (match_dup 1) (zero_extend:TI (match_dup 2)))))))]
6766 "TARGET_ZARCH"
6767 "@
6768 dlgr\t%0,%2
6769 dlg\t%0,%2"
6770 [(set_attr "op_type" "RRE,RXY")
6771 (set_attr "type" "idiv")])
6772
6773 ;
6774 ; divmodsi4 instruction pattern(s).
6775 ;
6776
6777 (define_expand "divmodsi4"
6778 [(parallel [(set (match_operand:SI 0 "general_operand" "")
6779 (div:SI (match_operand:SI 1 "general_operand" "")
6780 (match_operand:SI 2 "nonimmediate_operand" "")))
6781 (set (match_operand:SI 3 "general_operand" "")
6782 (mod:SI (match_dup 1) (match_dup 2)))])
6783 (clobber (match_dup 4))]
6784 "!TARGET_ZARCH"
6785 {
6786 rtx div_equal, mod_equal, equal;
6787 rtx_insn *insn;
6788
6789 div_equal = gen_rtx_DIV (SImode, operands[1], operands[2]);
6790 mod_equal = gen_rtx_MOD (SImode, operands[1], operands[2]);
6791 equal = gen_rtx_IOR (DImode,
6792 gen_rtx_ASHIFT (DImode,
6793 gen_rtx_ZERO_EXTEND (DImode, mod_equal),
6794 GEN_INT (32)),
6795 gen_rtx_ZERO_EXTEND (DImode, div_equal));
6796
6797 operands[4] = gen_reg_rtx(DImode);
6798 emit_insn (gen_extendsidi2 (operands[4], operands[1]));
6799
6800 insn = emit_insn (gen_divmoddisi3 (operands[4], operands[4], operands[2]));
6801 set_unique_reg_note (insn, REG_EQUAL, equal);
6802
6803 insn = emit_move_insn (operands[0], gen_lowpart (SImode, operands[4]));
6804 set_unique_reg_note (insn, REG_EQUAL, div_equal);
6805
6806 insn = emit_move_insn (operands[3], gen_highpart (SImode, operands[4]));
6807 set_unique_reg_note (insn, REG_EQUAL, mod_equal);
6808
6809 DONE;
6810 })
6811
6812 (define_insn "divmoddisi3"
6813 [(set (match_operand:DI 0 "register_operand" "=d,d")
6814 (ior:DI
6815 (ashift:DI
6816 (zero_extend:DI
6817 (truncate:SI
6818 (mod:DI (match_operand:DI 1 "register_operand" "0,0")
6819 (sign_extend:DI
6820 (match_operand:SI 2 "nonimmediate_operand" "d,R")))))
6821 (const_int 32))
6822 (zero_extend:DI
6823 (truncate:SI
6824 (div:DI (match_dup 1) (sign_extend:DI (match_dup 2)))))))]
6825 "!TARGET_ZARCH"
6826 "@
6827 dr\t%0,%2
6828 d\t%0,%2"
6829 [(set_attr "op_type" "RR,RX")
6830 (set_attr "type" "idiv")])
6831
6832 ;
6833 ; udivsi3 and umodsi3 instruction pattern(s).
6834 ;
6835
6836 (define_expand "udivmodsi4"
6837 [(parallel [(set (match_operand:SI 0 "general_operand" "")
6838 (udiv:SI (match_operand:SI 1 "general_operand" "")
6839 (match_operand:SI 2 "nonimmediate_operand" "")))
6840 (set (match_operand:SI 3 "general_operand" "")
6841 (umod:SI (match_dup 1) (match_dup 2)))])
6842 (clobber (match_dup 4))]
6843 "!TARGET_ZARCH && TARGET_CPU_ZARCH"
6844 {
6845 rtx div_equal, mod_equal, equal;
6846 rtx_insn *insn;
6847
6848 div_equal = gen_rtx_UDIV (SImode, operands[1], operands[2]);
6849 mod_equal = gen_rtx_UMOD (SImode, operands[1], operands[2]);
6850 equal = gen_rtx_IOR (DImode,
6851 gen_rtx_ASHIFT (DImode,
6852 gen_rtx_ZERO_EXTEND (DImode, mod_equal),
6853 GEN_INT (32)),
6854 gen_rtx_ZERO_EXTEND (DImode, div_equal));
6855
6856 operands[4] = gen_reg_rtx(DImode);
6857 emit_clobber (operands[4]);
6858 emit_move_insn (gen_lowpart (SImode, operands[4]), operands[1]);
6859 emit_move_insn (gen_highpart (SImode, operands[4]), const0_rtx);
6860
6861 insn = emit_insn (gen_udivmoddisi3 (operands[4], operands[4], operands[2]));
6862 set_unique_reg_note (insn, REG_EQUAL, equal);
6863
6864 insn = emit_move_insn (operands[0], gen_lowpart (SImode, operands[4]));
6865 set_unique_reg_note (insn, REG_EQUAL, div_equal);
6866
6867 insn = emit_move_insn (operands[3], gen_highpart (SImode, operands[4]));
6868 set_unique_reg_note (insn, REG_EQUAL, mod_equal);
6869
6870 DONE;
6871 })
6872
6873 (define_insn "udivmoddisi3"
6874 [(set (match_operand:DI 0 "register_operand" "=d,d")
6875 (ior:DI
6876 (ashift:DI
6877 (zero_extend:DI
6878 (truncate:SI
6879 (umod:DI (match_operand:DI 1 "register_operand" "0,0")
6880 (zero_extend:DI
6881 (match_operand:SI 2 "nonimmediate_operand" "d,T")))))
6882 (const_int 32))
6883 (zero_extend:DI
6884 (truncate:SI
6885 (udiv:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))))]
6886 "!TARGET_ZARCH && TARGET_CPU_ZARCH"
6887 "@
6888 dlr\t%0,%2
6889 dl\t%0,%2"
6890 [(set_attr "op_type" "RRE,RXY")
6891 (set_attr "type" "idiv")])
6892
6893 (define_expand "udivsi3"
6894 [(set (match_operand:SI 0 "register_operand" "=d")
6895 (udiv:SI (match_operand:SI 1 "general_operand" "")
6896 (match_operand:SI 2 "general_operand" "")))
6897 (clobber (match_dup 3))]
6898 "!TARGET_ZARCH && !TARGET_CPU_ZARCH"
6899 {
6900 rtx udiv_equal, umod_equal, equal;
6901 rtx_insn *insn;
6902
6903 udiv_equal = gen_rtx_UDIV (SImode, operands[1], operands[2]);
6904 umod_equal = gen_rtx_UMOD (SImode, operands[1], operands[2]);
6905 equal = gen_rtx_IOR (DImode,
6906 gen_rtx_ASHIFT (DImode,
6907 gen_rtx_ZERO_EXTEND (DImode, umod_equal),
6908 GEN_INT (32)),
6909 gen_rtx_ZERO_EXTEND (DImode, udiv_equal));
6910
6911 operands[3] = gen_reg_rtx (DImode);
6912
6913 if (CONSTANT_P (operands[2]))
6914 {
6915 if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0)
6916 {
6917 rtx_code_label *label1 = gen_label_rtx ();
6918
6919 operands[1] = make_safe_from (operands[1], operands[0]);
6920 emit_move_insn (operands[0], const0_rtx);
6921 emit_cmp_and_jump_insns (operands[1], operands[2], LT, NULL_RTX,
6922 SImode, 1, label1);
6923 emit_move_insn (operands[0], const1_rtx);
6924 emit_label (label1);
6925 }
6926 else
6927 {
6928 operands[2] = force_reg (SImode, operands[2]);
6929 operands[2] = make_safe_from (operands[2], operands[0]);
6930
6931 emit_insn (gen_zero_extendsidi2 (operands[3], operands[1]));
6932 insn = emit_insn (gen_divmoddisi3 (operands[3], operands[3],
6933 operands[2]));
6934 set_unique_reg_note (insn, REG_EQUAL, equal);
6935
6936 insn = emit_move_insn (operands[0],
6937 gen_lowpart (SImode, operands[3]));
6938 set_unique_reg_note (insn, REG_EQUAL, udiv_equal);
6939 }
6940 }
6941 else
6942 {
6943 rtx_code_label *label1 = gen_label_rtx ();
6944 rtx_code_label *label2 = gen_label_rtx ();
6945 rtx_code_label *label3 = gen_label_rtx ();
6946
6947 operands[1] = force_reg (SImode, operands[1]);
6948 operands[1] = make_safe_from (operands[1], operands[0]);
6949 operands[2] = force_reg (SImode, operands[2]);
6950 operands[2] = make_safe_from (operands[2], operands[0]);
6951
6952 emit_move_insn (operands[0], const0_rtx);
6953 emit_cmp_and_jump_insns (operands[2], operands[1], GT, NULL_RTX,
6954 SImode, 1, label3);
6955 emit_cmp_and_jump_insns (operands[2], const0_rtx, LT, NULL_RTX,
6956 SImode, 0, label2);
6957 emit_cmp_and_jump_insns (operands[2], const1_rtx, EQ, NULL_RTX,
6958 SImode, 0, label1);
6959 emit_insn (gen_zero_extendsidi2 (operands[3], operands[1]));
6960 insn = emit_insn (gen_divmoddisi3 (operands[3], operands[3],
6961 operands[2]));
6962 set_unique_reg_note (insn, REG_EQUAL, equal);
6963
6964 insn = emit_move_insn (operands[0],
6965 gen_lowpart (SImode, operands[3]));
6966 set_unique_reg_note (insn, REG_EQUAL, udiv_equal);
6967
6968 emit_jump (label3);
6969 emit_label (label1);
6970 emit_move_insn (operands[0], operands[1]);
6971 emit_jump (label3);
6972 emit_label (label2);
6973 emit_move_insn (operands[0], const1_rtx);
6974 emit_label (label3);
6975 }
6976 emit_move_insn (operands[0], operands[0]);
6977 DONE;
6978 })
6979
6980 (define_expand "umodsi3"
6981 [(set (match_operand:SI 0 "register_operand" "=d")
6982 (umod:SI (match_operand:SI 1 "nonimmediate_operand" "")
6983 (match_operand:SI 2 "nonimmediate_operand" "")))
6984 (clobber (match_dup 3))]
6985 "!TARGET_ZARCH && !TARGET_CPU_ZARCH"
6986 {
6987 rtx udiv_equal, umod_equal, equal;
6988 rtx_insn *insn;
6989
6990 udiv_equal = gen_rtx_UDIV (SImode, operands[1], operands[2]);
6991 umod_equal = gen_rtx_UMOD (SImode, operands[1], operands[2]);
6992 equal = gen_rtx_IOR (DImode,
6993 gen_rtx_ASHIFT (DImode,
6994 gen_rtx_ZERO_EXTEND (DImode, umod_equal),
6995 GEN_INT (32)),
6996 gen_rtx_ZERO_EXTEND (DImode, udiv_equal));
6997
6998 operands[3] = gen_reg_rtx (DImode);
6999
7000 if (CONSTANT_P (operands[2]))
7001 {
7002 if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) <= 0)
7003 {
7004 rtx_code_label *label1 = gen_label_rtx ();
7005
7006 operands[1] = make_safe_from (operands[1], operands[0]);
7007 emit_move_insn (operands[0], operands[1]);
7008 emit_cmp_and_jump_insns (operands[0], operands[2], LT, NULL_RTX,
7009 SImode, 1, label1);
7010 emit_insn (gen_abssi2 (operands[0], operands[2]));
7011 emit_insn (gen_addsi3 (operands[0], operands[0], operands[1]));
7012 emit_label (label1);
7013 }
7014 else
7015 {
7016 operands[2] = force_reg (SImode, operands[2]);
7017 operands[2] = make_safe_from (operands[2], operands[0]);
7018
7019 emit_insn (gen_zero_extendsidi2 (operands[3], operands[1]));
7020 insn = emit_insn (gen_divmoddisi3 (operands[3], operands[3],
7021 operands[2]));
7022 set_unique_reg_note (insn, REG_EQUAL, equal);
7023
7024 insn = emit_move_insn (operands[0],
7025 gen_highpart (SImode, operands[3]));
7026 set_unique_reg_note (insn, REG_EQUAL, umod_equal);
7027 }
7028 }
7029 else
7030 {
7031 rtx_code_label *label1 = gen_label_rtx ();
7032 rtx_code_label *label2 = gen_label_rtx ();
7033 rtx_code_label *label3 = gen_label_rtx ();
7034
7035 operands[1] = force_reg (SImode, operands[1]);
7036 operands[1] = make_safe_from (operands[1], operands[0]);
7037 operands[2] = force_reg (SImode, operands[2]);
7038 operands[2] = make_safe_from (operands[2], operands[0]);
7039
7040 emit_move_insn(operands[0], operands[1]);
7041 emit_cmp_and_jump_insns (operands[2], operands[1], GT, NULL_RTX,
7042 SImode, 1, label3);
7043 emit_cmp_and_jump_insns (operands[2], const0_rtx, LT, NULL_RTX,
7044 SImode, 0, label2);
7045 emit_cmp_and_jump_insns (operands[2], const1_rtx, EQ, NULL_RTX,
7046 SImode, 0, label1);
7047 emit_insn (gen_zero_extendsidi2 (operands[3], operands[1]));
7048 insn = emit_insn (gen_divmoddisi3 (operands[3], operands[3],
7049 operands[2]));
7050 set_unique_reg_note (insn, REG_EQUAL, equal);
7051
7052 insn = emit_move_insn (operands[0],
7053 gen_highpart (SImode, operands[3]));
7054 set_unique_reg_note (insn, REG_EQUAL, umod_equal);
7055
7056 emit_jump (label3);
7057 emit_label (label1);
7058 emit_move_insn (operands[0], const0_rtx);
7059 emit_jump (label3);
7060 emit_label (label2);
7061 emit_insn (gen_subsi3 (operands[0], operands[0], operands[2]));
7062 emit_label (label3);
7063 }
7064 DONE;
7065 })
7066
7067 ;
7068 ; div(df|sf)3 instruction pattern(s).
7069 ;
7070
7071 ; dxbr, ddbr, debr, dxb, ddb, deb, ddtr, dxtr
7072 (define_insn "div<mode>3"
7073 [(set (match_operand:FP 0 "register_operand" "=f,f,f,v")
7074 (div:FP (match_operand:FP 1 "register_operand" "f,0,0,v")
7075 (match_operand:FP 2 "general_operand" "f,f,R,v")))]
7076 "TARGET_HARD_FLOAT"
7077 "@
7078 d<xde>tr\t%0,%1,%2
7079 d<xde>br\t%0,%2
7080 d<xde>b\t%0,%2
7081 wfddb\t%v0,%v1,%v2"
7082 [(set_attr "op_type" "RRF,RRE,RXE,VRR")
7083 (set_attr "type" "fdiv<mode>")
7084 (set_attr "cpu_facility" "*,*,*,vec")
7085 (set_attr "enabled" "<nBFP>,<nDFP>,<DSF>,<DFDI>")])
7086
7087
7088 ;;
7089 ;;- And instructions.
7090 ;;
7091
7092 (define_expand "and<mode>3"
7093 [(set (match_operand:INT 0 "nonimmediate_operand" "")
7094 (and:INT (match_operand:INT 1 "nonimmediate_operand" "")
7095 (match_operand:INT 2 "general_operand" "")))
7096 (clobber (reg:CC CC_REGNUM))]
7097 ""
7098 "s390_expand_logical_operator (AND, <MODE>mode, operands); DONE;")
7099
7100 ;
7101 ; anddi3 instruction pattern(s).
7102 ;
7103
7104 (define_insn "*anddi3_cc"
7105 [(set (reg CC_REGNUM)
7106 (compare
7107 (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,d,0, d")
7108 (match_operand:DI 2 "general_operand" " d,d,T,NxxDw"))
7109 (const_int 0)))
7110 (set (match_operand:DI 0 "register_operand" "=d,d,d, d")
7111 (and:DI (match_dup 1) (match_dup 2)))]
7112 "TARGET_ZARCH && s390_match_ccmode(insn, CCTmode)"
7113 "@
7114 ngr\t%0,%2
7115 ngrk\t%0,%1,%2
7116 ng\t%0,%2
7117 risbg\t%0,%1,%s2,128+%e2,0"
7118 [(set_attr "op_type" "RRE,RRF,RXY,RIE")
7119 (set_attr "cpu_facility" "*,z196,*,z10")
7120 (set_attr "z10prop" "z10_super_E1,*,z10_super_E1,z10_super_E1")])
7121
7122 (define_insn "*anddi3_cconly"
7123 [(set (reg CC_REGNUM)
7124 (compare
7125 (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,d,0, d")
7126 (match_operand:DI 2 "general_operand" " d,d,T,NxxDw"))
7127 (const_int 0)))
7128 (clobber (match_scratch:DI 0 "=d,d,d, d"))]
7129 "TARGET_ZARCH
7130 && s390_match_ccmode(insn, CCTmode)
7131 /* Do not steal TM patterns. */
7132 && s390_single_part (operands[2], DImode, HImode, 0) < 0"
7133 "@
7134 ngr\t%0,%2
7135 ngrk\t%0,%1,%2
7136 ng\t%0,%2
7137 risbg\t%0,%1,%s2,128+%e2,0"
7138 [(set_attr "op_type" "RRE,RRF,RXY,RIE")
7139 (set_attr "cpu_facility" "*,z196,*,z10")
7140 (set_attr "z10prop" "z10_super_E1,*,z10_super_E1,z10_super_E1")])
7141
7142 (define_insn "*anddi3"
7143 [(set (match_operand:DI 0 "nonimmediate_operand"
7144 "=d,d, d, d, d, d, d, d,d,d,d, d, AQ,Q")
7145 (and:DI
7146 (match_operand:DI 1 "nonimmediate_operand"
7147 "%d,o, 0, 0, 0, 0, 0, 0,0,d,0, d, 0,0")
7148 (match_operand:DI 2 "general_operand"
7149 "M, M,N0HDF,N1HDF,N2HDF,N3HDF,N0SDF,N1SDF,d,d,T,NxxDw,NxQDF,Q")))
7150 (clobber (reg:CC CC_REGNUM))]
7151 "TARGET_ZARCH && s390_logical_operator_ok_p (operands)"
7152 "@
7153 #
7154 #
7155 nihh\t%0,%j2
7156 nihl\t%0,%j2
7157 nilh\t%0,%j2
7158 nill\t%0,%j2
7159 nihf\t%0,%m2
7160 nilf\t%0,%m2
7161 ngr\t%0,%2
7162 ngrk\t%0,%1,%2
7163 ng\t%0,%2
7164 risbg\t%0,%1,%s2,128+%e2,0
7165 #
7166 #"
7167 [(set_attr "op_type" "RRE,RXE,RI,RI,RI,RI,RIL,RIL,RRE,RRF,RXY,RIE,SI,SS")
7168 (set_attr "cpu_facility" "*,*,*,*,*,*,extimm,extimm,*,z196,*,z10,*,*")
7169 (set_attr "z10prop" "*,
7170 *,
7171 z10_super_E1,
7172 z10_super_E1,
7173 z10_super_E1,
7174 z10_super_E1,
7175 z10_super_E1,
7176 z10_super_E1,
7177 z10_super_E1,
7178 *,
7179 z10_super_E1,
7180 z10_super_E1,
7181 *,
7182 *")])
7183
7184 (define_split
7185 [(set (match_operand:DI 0 "s_operand" "")
7186 (and:DI (match_dup 0) (match_operand:DI 1 "immediate_operand" "")))
7187 (clobber (reg:CC CC_REGNUM))]
7188 "reload_completed"
7189 [(parallel
7190 [(set (match_dup 0) (and:QI (match_dup 0) (match_dup 1)))
7191 (clobber (reg:CC CC_REGNUM))])]
7192 "s390_narrow_logical_operator (AND, &operands[0], &operands[1]);")
7193
7194 ;; These two are what combine generates for (ashift (zero_extract)).
7195 (define_insn "*extzv_<mode>_srl<clobbercc_or_nocc>"
7196 [(set (match_operand:GPR 0 "register_operand" "=d")
7197 (and:GPR (lshiftrt:GPR
7198 (match_operand:GPR 1 "register_operand" "d")
7199 (match_operand:GPR 2 "nonzero_shift_count_operand" ""))
7200 (match_operand:GPR 3 "contiguous_bitmask_operand" "")))]
7201 "<z10_or_zEC12_cond>
7202 /* Note that even for the SImode pattern, the rotate is always DImode. */
7203 && s390_extzv_shift_ok (<bitsize>, -INTVAL (operands[2]),
7204 INTVAL (operands[3]))"
7205 "<risbg_n>\t%0,%1,%<bfstart>3,128+%<bfend>3,64-%2"
7206 [(set_attr "op_type" "RIE")
7207 (set_attr "z10prop" "z10_super_E1")])
7208
7209 (define_insn "*extzv_<mode>_sll<clobbercc_or_nocc>"
7210 [(set (match_operand:GPR 0 "register_operand" "=d")
7211 (and:GPR (ashift:GPR
7212 (match_operand:GPR 1 "register_operand" "d")
7213 (match_operand:GPR 2 "nonzero_shift_count_operand" ""))
7214 (match_operand:GPR 3 "contiguous_bitmask_operand" "")))]
7215 "<z10_or_zEC12_cond>
7216 && s390_extzv_shift_ok (<bitsize>, INTVAL (operands[2]),
7217 INTVAL (operands[3]))"
7218 "<risbg_n>\t%0,%1,%<bfstart>3,128+%<bfend>3,%2"
7219 [(set_attr "op_type" "RIE")
7220 (set_attr "z10prop" "z10_super_E1")])
7221
7222
7223 ;
7224 ; andsi3 instruction pattern(s).
7225 ;
7226
7227 (define_insn "*andsi3_cc"
7228 [(set (reg CC_REGNUM)
7229 (compare
7230 (and:SI
7231 (match_operand:SI 1 "nonimmediate_operand" "%0,0,d,0,0, d")
7232 (match_operand:SI 2 "general_operand" "Os,d,d,R,T,NxxSq"))
7233 (const_int 0)))
7234 (set (match_operand:SI 0 "register_operand" "=d,d,d,d,d, d")
7235 (and:SI (match_dup 1) (match_dup 2)))]
7236 "s390_match_ccmode(insn, CCTmode)"
7237 "@
7238 nilf\t%0,%o2
7239 nr\t%0,%2
7240 nrk\t%0,%1,%2
7241 n\t%0,%2
7242 ny\t%0,%2
7243 risbg\t%0,%1,%t2,128+%f2,0"
7244 [(set_attr "op_type" "RIL,RR,RRF,RX,RXY,RIE")
7245 (set_attr "cpu_facility" "*,*,z196,*,longdisp,z10")
7246 (set_attr "z10prop" "z10_super_E1,z10_super_E1,*,
7247 z10_super_E1,z10_super_E1,z10_super_E1")])
7248
7249 (define_insn "*andsi3_cconly"
7250 [(set (reg CC_REGNUM)
7251 (compare
7252 (and:SI
7253 (match_operand:SI 1 "nonimmediate_operand" "%0,0,d,0,0, d")
7254 (match_operand:SI 2 "general_operand" "Os,d,d,R,T,NxxSq"))
7255 (const_int 0)))
7256 (clobber (match_scratch:SI 0 "=d,d,d,d,d, d"))]
7257 "s390_match_ccmode(insn, CCTmode)
7258 /* Do not steal TM patterns. */
7259 && s390_single_part (operands[2], SImode, HImode, 0) < 0"
7260 "@
7261 nilf\t%0,%o2
7262 nr\t%0,%2
7263 nrk\t%0,%1,%2
7264 n\t%0,%2
7265 ny\t%0,%2
7266 risbg\t%0,%1,%t2,128+%f2,0"
7267 [(set_attr "op_type" "RIL,RR,RRF,RX,RXY,RIE")
7268 (set_attr "cpu_facility" "*,*,z196,*,longdisp,z10")
7269 (set_attr "z10prop" "z10_super_E1,z10_super_E1,*,
7270 z10_super_E1,z10_super_E1,z10_super_E1")])
7271
7272 (define_insn "*andsi3_zarch"
7273 [(set (match_operand:SI 0 "nonimmediate_operand"
7274 "=d,d, d, d, d,d,d,d,d, d, AQ,Q")
7275 (and:SI (match_operand:SI 1 "nonimmediate_operand"
7276 "%d,o, 0, 0, 0,0,d,0,0, d, 0,0")
7277 (match_operand:SI 2 "general_operand"
7278 " M,M,N0HSF,N1HSF,Os,d,d,R,T,NxxSw,NxQSF,Q")))
7279 (clobber (reg:CC CC_REGNUM))]
7280 "TARGET_ZARCH && s390_logical_operator_ok_p (operands)"
7281 "@
7282 #
7283 #
7284 nilh\t%0,%j2
7285 nill\t%0,%j2
7286 nilf\t%0,%o2
7287 nr\t%0,%2
7288 nrk\t%0,%1,%2
7289 n\t%0,%2
7290 ny\t%0,%2
7291 risbg\t%0,%1,%t2,128+%f2,0
7292 #
7293 #"
7294 [(set_attr "op_type" "RRE,RXE,RI,RI,RIL,RR,RRF,RX,RXY,RIE,SI,SS")
7295 (set_attr "cpu_facility" "*,*,*,*,*,*,z196,*,longdisp,z10,*,*")
7296 (set_attr "z10prop" "*,
7297 *,
7298 z10_super_E1,
7299 z10_super_E1,
7300 z10_super_E1,
7301 z10_super_E1,
7302 *,
7303 z10_super_E1,
7304 z10_super_E1,
7305 z10_super_E1,
7306 *,
7307 *")])
7308
7309 (define_insn "*andsi3_esa"
7310 [(set (match_operand:SI 0 "nonimmediate_operand" "=d,d, AQ,Q")
7311 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0, 0,0")
7312 (match_operand:SI 2 "general_operand" " d,R,NxQSF,Q")))
7313 (clobber (reg:CC CC_REGNUM))]
7314 "!TARGET_ZARCH && s390_logical_operator_ok_p (operands)"
7315 "@
7316 nr\t%0,%2
7317 n\t%0,%2
7318 #
7319 #"
7320 [(set_attr "op_type" "RR,RX,SI,SS")
7321 (set_attr "z10prop" "z10_super_E1,z10_super_E1,*,*")])
7322
7323
7324 (define_split
7325 [(set (match_operand:SI 0 "s_operand" "")
7326 (and:SI (match_dup 0) (match_operand:SI 1 "immediate_operand" "")))
7327 (clobber (reg:CC CC_REGNUM))]
7328 "reload_completed"
7329 [(parallel
7330 [(set (match_dup 0) (and:QI (match_dup 0) (match_dup 1)))
7331 (clobber (reg:CC CC_REGNUM))])]
7332 "s390_narrow_logical_operator (AND, &operands[0], &operands[1]);")
7333
7334 ;
7335 ; andhi3 instruction pattern(s).
7336 ;
7337
7338 (define_insn "*andhi3_zarch"
7339 [(set (match_operand:HI 0 "nonimmediate_operand" "=d,d,d, AQ,Q")
7340 (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,d,0, 0,0")
7341 (match_operand:HI 2 "general_operand" " d,d,n,NxQHF,Q")))
7342 (clobber (reg:CC CC_REGNUM))]
7343 "TARGET_ZARCH && s390_logical_operator_ok_p (operands)"
7344 "@
7345 nr\t%0,%2
7346 nrk\t%0,%1,%2
7347 nill\t%0,%x2
7348 #
7349 #"
7350 [(set_attr "op_type" "RR,RRF,RI,SI,SS")
7351 (set_attr "cpu_facility" "*,z196,*,*,*")
7352 (set_attr "z10prop" "z10_super_E1,*,z10_super_E1,*,*")
7353 ])
7354
7355 (define_insn "*andhi3_esa"
7356 [(set (match_operand:HI 0 "nonimmediate_operand" "=d,AQ,Q")
7357 (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,0")
7358 (match_operand:HI 2 "general_operand" "d,NxQHF,Q")))
7359 (clobber (reg:CC CC_REGNUM))]
7360 "!TARGET_ZARCH && s390_logical_operator_ok_p (operands)"
7361 "@
7362 nr\t%0,%2
7363 #
7364 #"
7365 [(set_attr "op_type" "RR,SI,SS")
7366 (set_attr "z10prop" "z10_super_E1,*,*")
7367 ])
7368
7369 (define_split
7370 [(set (match_operand:HI 0 "s_operand" "")
7371 (and:HI (match_dup 0) (match_operand:HI 1 "immediate_operand" "")))
7372 (clobber (reg:CC CC_REGNUM))]
7373 "reload_completed"
7374 [(parallel
7375 [(set (match_dup 0) (and:QI (match_dup 0) (match_dup 1)))
7376 (clobber (reg:CC CC_REGNUM))])]
7377 "s390_narrow_logical_operator (AND, &operands[0], &operands[1]);")
7378
7379 ;
7380 ; andqi3 instruction pattern(s).
7381 ;
7382
7383 (define_insn "*andqi3_zarch"
7384 [(set (match_operand:QI 0 "nonimmediate_operand" "=d,d,d,Q,S,Q")
7385 (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,d,0,0,0,0")
7386 (match_operand:QI 2 "general_operand" " d,d,n,n,n,Q")))
7387 (clobber (reg:CC CC_REGNUM))]
7388 "TARGET_ZARCH && s390_logical_operator_ok_p (operands)"
7389 "@
7390 nr\t%0,%2
7391 nrk\t%0,%1,%2
7392 nill\t%0,%b2
7393 ni\t%S0,%b2
7394 niy\t%S0,%b2
7395 #"
7396 [(set_attr "op_type" "RR,RRF,RI,SI,SIY,SS")
7397 (set_attr "cpu_facility" "*,z196,*,*,longdisp,*")
7398 (set_attr "z10prop" "z10_super_E1,*,z10_super_E1,z10_super,z10_super,*")])
7399
7400 (define_insn "*andqi3_esa"
7401 [(set (match_operand:QI 0 "nonimmediate_operand" "=d,Q,Q")
7402 (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
7403 (match_operand:QI 2 "general_operand" "d,n,Q")))
7404 (clobber (reg:CC CC_REGNUM))]
7405 "!TARGET_ZARCH && s390_logical_operator_ok_p (operands)"
7406 "@
7407 nr\t%0,%2
7408 ni\t%S0,%b2
7409 #"
7410 [(set_attr "op_type" "RR,SI,SS")
7411 (set_attr "z10prop" "z10_super_E1,z10_super,*")])
7412
7413 ;
7414 ; And with complement
7415 ;
7416 ; c = ~b & a = (b & a) ^ a
7417
7418 (define_insn_and_split "*andc_split_<mode>"
7419 [(set (match_operand:GPR 0 "nonimmediate_operand" "")
7420 (and:GPR (not:GPR (match_operand:GPR 1 "nonimmediate_operand" ""))
7421 (match_operand:GPR 2 "general_operand" "")))
7422 (clobber (reg:CC CC_REGNUM))]
7423 "! reload_completed && s390_logical_operator_ok_p (operands)"
7424 "#"
7425 "&& 1"
7426 [
7427 (parallel
7428 [(set (match_dup 3) (and:GPR (match_dup 1) (match_dup 2)))
7429 (clobber (reg:CC CC_REGNUM))])
7430 (parallel
7431 [(set (match_dup 0) (xor:GPR (match_dup 3) (match_dup 2)))
7432 (clobber (reg:CC CC_REGNUM))])]
7433 {
7434 if (reg_overlap_mentioned_p (operands[0], operands[2]))
7435 operands[3] = gen_reg_rtx (<MODE>mode);
7436 else
7437 operands[3] = operands[0];
7438 })
7439
7440 ;
7441 ; Block and (NC) patterns.
7442 ;
7443
7444 (define_insn "*nc"
7445 [(set (match_operand:BLK 0 "memory_operand" "=Q")
7446 (and:BLK (match_dup 0)
7447 (match_operand:BLK 1 "memory_operand" "Q")))
7448 (use (match_operand 2 "const_int_operand" "n"))
7449 (clobber (reg:CC CC_REGNUM))]
7450 "INTVAL (operands[2]) >= 1 && INTVAL (operands[2]) <= 256"
7451 "nc\t%O0(%2,%R0),%S1"
7452 [(set_attr "op_type" "SS")
7453 (set_attr "z196prop" "z196_cracked")])
7454
7455 (define_split
7456 [(set (match_operand 0 "memory_operand" "")
7457 (and (match_dup 0)
7458 (match_operand 1 "memory_operand" "")))
7459 (clobber (reg:CC CC_REGNUM))]
7460 "reload_completed
7461 && GET_MODE (operands[0]) == GET_MODE (operands[1])
7462 && GET_MODE_SIZE (GET_MODE (operands[0])) > 0"
7463 [(parallel
7464 [(set (match_dup 0) (and:BLK (match_dup 0) (match_dup 1)))
7465 (use (match_dup 2))
7466 (clobber (reg:CC CC_REGNUM))])]
7467 {
7468 operands[2] = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[0])));
7469 operands[0] = adjust_address (operands[0], BLKmode, 0);
7470 operands[1] = adjust_address (operands[1], BLKmode, 0);
7471 })
7472
7473 (define_peephole2
7474 [(parallel
7475 [(set (match_operand:BLK 0 "memory_operand" "")
7476 (and:BLK (match_dup 0)
7477 (match_operand:BLK 1 "memory_operand" "")))
7478 (use (match_operand 2 "const_int_operand" ""))
7479 (clobber (reg:CC CC_REGNUM))])
7480 (parallel
7481 [(set (match_operand:BLK 3 "memory_operand" "")
7482 (and:BLK (match_dup 3)
7483 (match_operand:BLK 4 "memory_operand" "")))
7484 (use (match_operand 5 "const_int_operand" ""))
7485 (clobber (reg:CC CC_REGNUM))])]
7486 "s390_offset_p (operands[0], operands[3], operands[2])
7487 && s390_offset_p (operands[1], operands[4], operands[2])
7488 && !s390_overlap_p (operands[0], operands[1],
7489 INTVAL (operands[2]) + INTVAL (operands[5]))
7490 && INTVAL (operands[2]) + INTVAL (operands[5]) <= 256"
7491 [(parallel
7492 [(set (match_dup 6) (and:BLK (match_dup 6) (match_dup 7)))
7493 (use (match_dup 8))
7494 (clobber (reg:CC CC_REGNUM))])]
7495 "operands[6] = gen_rtx_MEM (BLKmode, XEXP (operands[0], 0));
7496 operands[7] = gen_rtx_MEM (BLKmode, XEXP (operands[1], 0));
7497 operands[8] = GEN_INT (INTVAL (operands[2]) + INTVAL (operands[5]));")
7498
7499
7500 ;;
7501 ;;- Bit set (inclusive or) instructions.
7502 ;;
7503
7504 (define_expand "ior<mode>3"
7505 [(set (match_operand:INT 0 "nonimmediate_operand" "")
7506 (ior:INT (match_operand:INT 1 "nonimmediate_operand" "")
7507 (match_operand:INT 2 "general_operand" "")))
7508 (clobber (reg:CC CC_REGNUM))]
7509 ""
7510 "s390_expand_logical_operator (IOR, <MODE>mode, operands); DONE;")
7511
7512 ;
7513 ; iordi3 instruction pattern(s).
7514 ;
7515
7516 (define_insn "*iordi3_cc"
7517 [(set (reg CC_REGNUM)
7518 (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,d,0")
7519 (match_operand:DI 2 "general_operand" " d,d,T"))
7520 (const_int 0)))
7521 (set (match_operand:DI 0 "register_operand" "=d,d,d")
7522 (ior:DI (match_dup 1) (match_dup 2)))]
7523 "s390_match_ccmode(insn, CCTmode) && TARGET_ZARCH"
7524 "@
7525 ogr\t%0,%2
7526 ogrk\t%0,%1,%2
7527 og\t%0,%2"
7528 [(set_attr "op_type" "RRE,RRF,RXY")
7529 (set_attr "cpu_facility" "*,z196,*")
7530 (set_attr "z10prop" "z10_super_E1,*,z10_super_E1")])
7531
7532 (define_insn "*iordi3_cconly"
7533 [(set (reg CC_REGNUM)
7534 (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,d,0")
7535 (match_operand:DI 2 "general_operand" " d,d,T"))
7536 (const_int 0)))
7537 (clobber (match_scratch:DI 0 "=d,d,d"))]
7538 "s390_match_ccmode(insn, CCTmode) && TARGET_ZARCH"
7539 "@
7540 ogr\t%0,%2
7541 ogrk\t%0,%1,%2
7542 og\t%0,%2"
7543 [(set_attr "op_type" "RRE,RRF,RXY")
7544 (set_attr "cpu_facility" "*,z196,*")
7545 (set_attr "z10prop" "z10_super_E1,*,z10_super_E1")])
7546
7547 (define_insn "*iordi3"
7548 [(set (match_operand:DI 0 "nonimmediate_operand"
7549 "=d, d, d, d, d, d,d,d,d, AQ,Q")
7550 (ior:DI (match_operand:DI 1 "nonimmediate_operand"
7551 " %0, 0, 0, 0, 0, 0,0,d,0, 0,0")
7552 (match_operand:DI 2 "general_operand"
7553 "N0HD0,N1HD0,N2HD0,N3HD0,N0SD0,N1SD0,d,d,T,NxQD0,Q")))
7554 (clobber (reg:CC CC_REGNUM))]
7555 "TARGET_ZARCH && s390_logical_operator_ok_p (operands)"
7556 "@
7557 oihh\t%0,%i2
7558 oihl\t%0,%i2
7559 oilh\t%0,%i2
7560 oill\t%0,%i2
7561 oihf\t%0,%k2
7562 oilf\t%0,%k2
7563 ogr\t%0,%2
7564 ogrk\t%0,%1,%2
7565 og\t%0,%2
7566 #
7567 #"
7568 [(set_attr "op_type" "RI,RI,RI,RI,RIL,RIL,RRE,RRF,RXY,SI,SS")
7569 (set_attr "cpu_facility" "*,*,*,*,extimm,extimm,*,z196,*,*,*")
7570 (set_attr "z10prop" "z10_super_E1,
7571 z10_super_E1,
7572 z10_super_E1,
7573 z10_super_E1,
7574 z10_super_E1,
7575 z10_super_E1,
7576 z10_super_E1,
7577 *,
7578 z10_super_E1,
7579 *,
7580 *")])
7581
7582 (define_split
7583 [(set (match_operand:DI 0 "s_operand" "")
7584 (ior:DI (match_dup 0) (match_operand:DI 1 "immediate_operand" "")))
7585 (clobber (reg:CC CC_REGNUM))]
7586 "reload_completed"
7587 [(parallel
7588 [(set (match_dup 0) (ior:QI (match_dup 0) (match_dup 1)))
7589 (clobber (reg:CC CC_REGNUM))])]
7590 "s390_narrow_logical_operator (IOR, &operands[0], &operands[1]);")
7591
7592 ;
7593 ; iorsi3 instruction pattern(s).
7594 ;
7595
7596 (define_insn "*iorsi3_cc"
7597 [(set (reg CC_REGNUM)
7598 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,d,0,0")
7599 (match_operand:SI 2 "general_operand" "Os,d,d,R,T"))
7600 (const_int 0)))
7601 (set (match_operand:SI 0 "register_operand" "=d,d,d,d,d")
7602 (ior:SI (match_dup 1) (match_dup 2)))]
7603 "s390_match_ccmode(insn, CCTmode)"
7604 "@
7605 oilf\t%0,%o2
7606 or\t%0,%2
7607 ork\t%0,%1,%2
7608 o\t%0,%2
7609 oy\t%0,%2"
7610 [(set_attr "op_type" "RIL,RR,RRF,RX,RXY")
7611 (set_attr "cpu_facility" "*,*,z196,*,longdisp")
7612 (set_attr "z10prop" "z10_super_E1,z10_super_E1,*,z10_super_E1,z10_super_E1")])
7613
7614 (define_insn "*iorsi3_cconly"
7615 [(set (reg CC_REGNUM)
7616 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,d,0,0")
7617 (match_operand:SI 2 "general_operand" "Os,d,d,R,T"))
7618 (const_int 0)))
7619 (clobber (match_scratch:SI 0 "=d,d,d,d,d"))]
7620 "s390_match_ccmode(insn, CCTmode)"
7621 "@
7622 oilf\t%0,%o2
7623 or\t%0,%2
7624 ork\t%0,%1,%2
7625 o\t%0,%2
7626 oy\t%0,%2"
7627 [(set_attr "op_type" "RIL,RR,RRF,RX,RXY")
7628 (set_attr "cpu_facility" "*,*,z196,*,longdisp")
7629 (set_attr "z10prop" "z10_super_E1,z10_super_E1,*,z10_super_E1,z10_super_E1")])
7630
7631 (define_insn "*iorsi3_zarch"
7632 [(set (match_operand:SI 0 "nonimmediate_operand" "=d, d, d,d,d,d,d, AQ,Q")
7633 (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0, 0, 0,0,d,0,0, 0,0")
7634 (match_operand:SI 2 "general_operand" "N0HS0,N1HS0,Os,d,d,R,T,NxQS0,Q")))
7635 (clobber (reg:CC CC_REGNUM))]
7636 "TARGET_ZARCH && s390_logical_operator_ok_p (operands)"
7637 "@
7638 oilh\t%0,%i2
7639 oill\t%0,%i2
7640 oilf\t%0,%o2
7641 or\t%0,%2
7642 ork\t%0,%1,%2
7643 o\t%0,%2
7644 oy\t%0,%2
7645 #
7646 #"
7647 [(set_attr "op_type" "RI,RI,RIL,RR,RRF,RX,RXY,SI,SS")
7648 (set_attr "cpu_facility" "*,*,*,*,z196,*,longdisp,*,*")
7649 (set_attr "z10prop" "z10_super_E1,
7650 z10_super_E1,
7651 z10_super_E1,
7652 z10_super_E1,
7653 *,
7654 z10_super_E1,
7655 z10_super_E1,
7656 *,
7657 *")])
7658
7659 (define_insn "*iorsi3_esa"
7660 [(set (match_operand:SI 0 "nonimmediate_operand" "=d,d,AQ,Q")
7661 (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,0,0")
7662 (match_operand:SI 2 "general_operand" "d,R,NxQS0,Q")))
7663 (clobber (reg:CC CC_REGNUM))]
7664 "!TARGET_ZARCH && s390_logical_operator_ok_p (operands)"
7665 "@
7666 or\t%0,%2
7667 o\t%0,%2
7668 #
7669 #"
7670 [(set_attr "op_type" "RR,RX,SI,SS")
7671 (set_attr "z10prop" "z10_super_E1,z10_super_E1,*,*")])
7672
7673 (define_split
7674 [(set (match_operand:SI 0 "s_operand" "")
7675 (ior:SI (match_dup 0) (match_operand:SI 1 "immediate_operand" "")))
7676 (clobber (reg:CC CC_REGNUM))]
7677 "reload_completed"
7678 [(parallel
7679 [(set (match_dup 0) (ior:QI (match_dup 0) (match_dup 1)))
7680 (clobber (reg:CC CC_REGNUM))])]
7681 "s390_narrow_logical_operator (IOR, &operands[0], &operands[1]);")
7682
7683 ;
7684 ; iorhi3 instruction pattern(s).
7685 ;
7686
7687 (define_insn "*iorhi3_zarch"
7688 [(set (match_operand:HI 0 "nonimmediate_operand" "=d,d,d, AQ,Q")
7689 (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,d,0, 0,0")
7690 (match_operand:HI 2 "general_operand" " d,d,n,NxQH0,Q")))
7691 (clobber (reg:CC CC_REGNUM))]
7692 "TARGET_ZARCH && s390_logical_operator_ok_p (operands)"
7693 "@
7694 or\t%0,%2
7695 ork\t%0,%1,%2
7696 oill\t%0,%x2
7697 #
7698 #"
7699 [(set_attr "op_type" "RR,RRF,RI,SI,SS")
7700 (set_attr "cpu_facility" "*,z196,*,*,*")
7701 (set_attr "z10prop" "z10_super_E1,*,z10_super_E1,*,*")])
7702
7703 (define_insn "*iorhi3_esa"
7704 [(set (match_operand:HI 0 "nonimmediate_operand" "=d,AQ,Q")
7705 (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,0")
7706 (match_operand:HI 2 "general_operand" "d,NxQH0,Q")))
7707 (clobber (reg:CC CC_REGNUM))]
7708 "!TARGET_ZARCH && s390_logical_operator_ok_p (operands)"
7709 "@
7710 or\t%0,%2
7711 #
7712 #"
7713 [(set_attr "op_type" "RR,SI,SS")
7714 (set_attr "z10prop" "z10_super_E1,*,*")])
7715
7716 (define_split
7717 [(set (match_operand:HI 0 "s_operand" "")
7718 (ior:HI (match_dup 0) (match_operand:HI 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 ; iorqi3 instruction pattern(s).
7728 ;
7729
7730 (define_insn "*iorqi3_zarch"
7731 [(set (match_operand:QI 0 "nonimmediate_operand" "=d,d,d,Q,S,Q")
7732 (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,d,0,0,0,0")
7733 (match_operand:QI 2 "general_operand" " d,d,n,n,n,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,%b2
7740 oi\t%S0,%b2
7741 oiy\t%S0,%b2
7742 #"
7743 [(set_attr "op_type" "RR,RRF,RI,SI,SIY,SS")
7744 (set_attr "cpu_facility" "*,z196,*,*,longdisp,*")
7745 (set_attr "z10prop" "z10_super_E1,*,z10_super_E1,
7746 z10_super,z10_super,*")])
7747
7748 (define_insn "*iorqi3_esa"
7749 [(set (match_operand:QI 0 "nonimmediate_operand" "=d,Q,Q")
7750 (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
7751 (match_operand:QI 2 "general_operand" "d,n,Q")))
7752 (clobber (reg:CC CC_REGNUM))]
7753 "!TARGET_ZARCH && s390_logical_operator_ok_p (operands)"
7754 "@
7755 or\t%0,%2
7756 oi\t%S0,%b2
7757 #"
7758 [(set_attr "op_type" "RR,SI,SS")
7759 (set_attr "z10prop" "z10_super_E1,z10_super,*")])
7760
7761 ;
7762 ; Block inclusive or (OC) patterns.
7763 ;
7764
7765 (define_insn "*oc"
7766 [(set (match_operand:BLK 0 "memory_operand" "=Q")
7767 (ior:BLK (match_dup 0)
7768 (match_operand:BLK 1 "memory_operand" "Q")))
7769 (use (match_operand 2 "const_int_operand" "n"))
7770 (clobber (reg:CC CC_REGNUM))]
7771 "INTVAL (operands[2]) >= 1 && INTVAL (operands[2]) <= 256"
7772 "oc\t%O0(%2,%R0),%S1"
7773 [(set_attr "op_type" "SS")
7774 (set_attr "z196prop" "z196_cracked")])
7775
7776 (define_split
7777 [(set (match_operand 0 "memory_operand" "")
7778 (ior (match_dup 0)
7779 (match_operand 1 "memory_operand" "")))
7780 (clobber (reg:CC CC_REGNUM))]
7781 "reload_completed
7782 && GET_MODE (operands[0]) == GET_MODE (operands[1])
7783 && GET_MODE_SIZE (GET_MODE (operands[0])) > 0"
7784 [(parallel
7785 [(set (match_dup 0) (ior:BLK (match_dup 0) (match_dup 1)))
7786 (use (match_dup 2))
7787 (clobber (reg:CC CC_REGNUM))])]
7788 {
7789 operands[2] = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[0])));
7790 operands[0] = adjust_address (operands[0], BLKmode, 0);
7791 operands[1] = adjust_address (operands[1], BLKmode, 0);
7792 })
7793
7794 (define_peephole2
7795 [(parallel
7796 [(set (match_operand:BLK 0 "memory_operand" "")
7797 (ior:BLK (match_dup 0)
7798 (match_operand:BLK 1 "memory_operand" "")))
7799 (use (match_operand 2 "const_int_operand" ""))
7800 (clobber (reg:CC CC_REGNUM))])
7801 (parallel
7802 [(set (match_operand:BLK 3 "memory_operand" "")
7803 (ior:BLK (match_dup 3)
7804 (match_operand:BLK 4 "memory_operand" "")))
7805 (use (match_operand 5 "const_int_operand" ""))
7806 (clobber (reg:CC CC_REGNUM))])]
7807 "s390_offset_p (operands[0], operands[3], operands[2])
7808 && s390_offset_p (operands[1], operands[4], operands[2])
7809 && !s390_overlap_p (operands[0], operands[1],
7810 INTVAL (operands[2]) + INTVAL (operands[5]))
7811 && INTVAL (operands[2]) + INTVAL (operands[5]) <= 256"
7812 [(parallel
7813 [(set (match_dup 6) (ior:BLK (match_dup 6) (match_dup 7)))
7814 (use (match_dup 8))
7815 (clobber (reg:CC CC_REGNUM))])]
7816 "operands[6] = gen_rtx_MEM (BLKmode, XEXP (operands[0], 0));
7817 operands[7] = gen_rtx_MEM (BLKmode, XEXP (operands[1], 0));
7818 operands[8] = GEN_INT (INTVAL (operands[2]) + INTVAL (operands[5]));")
7819
7820
7821 ;;
7822 ;;- Xor instructions.
7823 ;;
7824
7825 (define_expand "xor<mode>3"
7826 [(set (match_operand:INT 0 "nonimmediate_operand" "")
7827 (xor:INT (match_operand:INT 1 "nonimmediate_operand" "")
7828 (match_operand:INT 2 "general_operand" "")))
7829 (clobber (reg:CC CC_REGNUM))]
7830 ""
7831 "s390_expand_logical_operator (XOR, <MODE>mode, operands); DONE;")
7832
7833 ; Combine replaces (xor (x) (const_int -1)) with (not (x)) when doing
7834 ; simplifications. So its better to have something matching.
7835 (define_split
7836 [(set (match_operand:INT 0 "nonimmediate_operand" "")
7837 (not:INT (match_operand:INT 1 "nonimmediate_operand" "")))]
7838 ""
7839 [(parallel
7840 [(set (match_dup 0) (xor:INT (match_dup 1) (match_dup 2)))
7841 (clobber (reg:CC CC_REGNUM))])]
7842 {
7843 operands[2] = constm1_rtx;
7844 if (!s390_logical_operator_ok_p (operands))
7845 FAIL;
7846 })
7847
7848 ;
7849 ; xordi3 instruction pattern(s).
7850 ;
7851
7852 (define_insn "*xordi3_cc"
7853 [(set (reg CC_REGNUM)
7854 (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,d,0")
7855 (match_operand:DI 2 "general_operand" " d,d,T"))
7856 (const_int 0)))
7857 (set (match_operand:DI 0 "register_operand" "=d,d,d")
7858 (xor:DI (match_dup 1) (match_dup 2)))]
7859 "s390_match_ccmode(insn, CCTmode) && TARGET_ZARCH"
7860 "@
7861 xgr\t%0,%2
7862 xgrk\t%0,%1,%2
7863 xg\t%0,%2"
7864 [(set_attr "op_type" "RRE,RRF,RXY")
7865 (set_attr "cpu_facility" "*,z196,*")
7866 (set_attr "z10prop" "z10_super_E1,*,z10_super_E1")])
7867
7868 (define_insn "*xordi3_cconly"
7869 [(set (reg CC_REGNUM)
7870 (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,d,0")
7871 (match_operand:DI 2 "general_operand" " d,d,T"))
7872 (const_int 0)))
7873 (clobber (match_scratch:DI 0 "=d,d,d"))]
7874 "s390_match_ccmode(insn, CCTmode) && TARGET_ZARCH"
7875 "@
7876 xgr\t%0,%2
7877 xgrk\t%0,%1,%2
7878 xg\t%0,%2"
7879 [(set_attr "op_type" "RRE,RRF,RXY")
7880 (set_attr "cpu_facility" "*,z196,*")
7881 (set_attr "z10prop" "z10_super_E1,*,z10_super_E1")])
7882
7883 (define_insn "*xordi3"
7884 [(set (match_operand:DI 0 "nonimmediate_operand" "=d, d,d,d,d, AQ,Q")
7885 (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0, 0,0,d,0, 0,0")
7886 (match_operand:DI 2 "general_operand" "N0SD0,N1SD0,d,d,T,NxQD0,Q")))
7887 (clobber (reg:CC CC_REGNUM))]
7888 "TARGET_ZARCH && s390_logical_operator_ok_p (operands)"
7889 "@
7890 xihf\t%0,%k2
7891 xilf\t%0,%k2
7892 xgr\t%0,%2
7893 xgrk\t%0,%1,%2
7894 xg\t%0,%2
7895 #
7896 #"
7897 [(set_attr "op_type" "RIL,RIL,RRE,RRF,RXY,SI,SS")
7898 (set_attr "cpu_facility" "extimm,extimm,*,z196,*,*,*")
7899 (set_attr "z10prop" "z10_super_E1,z10_super_E1,z10_super_E1,
7900 *,z10_super_E1,*,*")])
7901
7902 (define_split
7903 [(set (match_operand:DI 0 "s_operand" "")
7904 (xor:DI (match_dup 0) (match_operand:DI 1 "immediate_operand" "")))
7905 (clobber (reg:CC CC_REGNUM))]
7906 "reload_completed"
7907 [(parallel
7908 [(set (match_dup 0) (xor:QI (match_dup 0) (match_dup 1)))
7909 (clobber (reg:CC CC_REGNUM))])]
7910 "s390_narrow_logical_operator (XOR, &operands[0], &operands[1]);")
7911
7912 ;
7913 ; xorsi3 instruction pattern(s).
7914 ;
7915
7916 (define_insn "*xorsi3_cc"
7917 [(set (reg CC_REGNUM)
7918 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,d,0,0")
7919 (match_operand:SI 2 "general_operand" "Os,d,d,R,T"))
7920 (const_int 0)))
7921 (set (match_operand:SI 0 "register_operand" "=d,d,d,d,d")
7922 (xor:SI (match_dup 1) (match_dup 2)))]
7923 "s390_match_ccmode(insn, CCTmode)"
7924 "@
7925 xilf\t%0,%o2
7926 xr\t%0,%2
7927 xrk\t%0,%1,%2
7928 x\t%0,%2
7929 xy\t%0,%2"
7930 [(set_attr "op_type" "RIL,RR,RRF,RX,RXY")
7931 (set_attr "cpu_facility" "*,*,z196,*,longdisp")
7932 (set_attr "z10prop" "z10_super_E1,z10_super_E1,*,
7933 z10_super_E1,z10_super_E1")])
7934
7935 (define_insn "*xorsi3_cconly"
7936 [(set (reg CC_REGNUM)
7937 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,d,0,0")
7938 (match_operand:SI 2 "general_operand" "Os,d,d,R,T"))
7939 (const_int 0)))
7940 (clobber (match_scratch:SI 0 "=d,d,d,d,d"))]
7941 "s390_match_ccmode(insn, CCTmode)"
7942 "@
7943 xilf\t%0,%o2
7944 xr\t%0,%2
7945 xrk\t%0,%1,%2
7946 x\t%0,%2
7947 xy\t%0,%2"
7948 [(set_attr "op_type" "RIL,RR,RRF,RX,RXY")
7949 (set_attr "cpu_facility" "*,*,z196,*,longdisp")
7950 (set_attr "z10prop" "z10_super_E1,z10_super_E1,*,
7951 z10_super_E1,z10_super_E1")])
7952
7953 (define_insn "*xorsi3"
7954 [(set (match_operand:SI 0 "nonimmediate_operand" "=d,d,d,d,d, AQ,Q")
7955 (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,d,0,0, 0,0")
7956 (match_operand:SI 2 "general_operand" "Os,d,d,R,T,NxQS0,Q")))
7957 (clobber (reg:CC CC_REGNUM))]
7958 "s390_logical_operator_ok_p (operands)"
7959 "@
7960 xilf\t%0,%o2
7961 xr\t%0,%2
7962 xrk\t%0,%1,%2
7963 x\t%0,%2
7964 xy\t%0,%2
7965 #
7966 #"
7967 [(set_attr "op_type" "RIL,RR,RRF,RX,RXY,SI,SS")
7968 (set_attr "cpu_facility" "*,*,z196,*,longdisp,*,*")
7969 (set_attr "z10prop" "z10_super_E1,z10_super_E1,*,
7970 z10_super_E1,z10_super_E1,*,*")])
7971
7972 (define_split
7973 [(set (match_operand:SI 0 "s_operand" "")
7974 (xor:SI (match_dup 0) (match_operand:SI 1 "immediate_operand" "")))
7975 (clobber (reg:CC CC_REGNUM))]
7976 "reload_completed"
7977 [(parallel
7978 [(set (match_dup 0) (xor:QI (match_dup 0) (match_dup 1)))
7979 (clobber (reg:CC CC_REGNUM))])]
7980 "s390_narrow_logical_operator (XOR, &operands[0], &operands[1]);")
7981
7982 ;
7983 ; xorhi3 instruction pattern(s).
7984 ;
7985
7986 (define_insn "*xorhi3"
7987 [(set (match_operand:HI 0 "nonimmediate_operand" "=d,d,d, AQ,Q")
7988 (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,d, 0,0")
7989 (match_operand:HI 2 "general_operand" "Os,d,d,NxQH0,Q")))
7990 (clobber (reg:CC CC_REGNUM))]
7991 "s390_logical_operator_ok_p (operands)"
7992 "@
7993 xilf\t%0,%x2
7994 xr\t%0,%2
7995 xrk\t%0,%1,%2
7996 #
7997 #"
7998 [(set_attr "op_type" "RIL,RR,RRF,SI,SS")
7999 (set_attr "cpu_facility" "*,*,z196,*,*")
8000 (set_attr "z10prop" "z10_super_E1,z10_super_E1,*,*,*")])
8001
8002 (define_split
8003 [(set (match_operand:HI 0 "s_operand" "")
8004 (xor:HI (match_dup 0) (match_operand:HI 1 "immediate_operand" "")))
8005 (clobber (reg:CC CC_REGNUM))]
8006 "reload_completed"
8007 [(parallel
8008 [(set (match_dup 0) (xor:QI (match_dup 0) (match_dup 1)))
8009 (clobber (reg:CC CC_REGNUM))])]
8010 "s390_narrow_logical_operator (XOR, &operands[0], &operands[1]);")
8011
8012 ;
8013 ; xorqi3 instruction pattern(s).
8014 ;
8015
8016 (define_insn "*xorqi3"
8017 [(set (match_operand:QI 0 "nonimmediate_operand" "=d,d,d,Q,S,Q")
8018 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,d,0,0,0")
8019 (match_operand:QI 2 "general_operand" "Os,d,d,n,n,Q")))
8020 (clobber (reg:CC CC_REGNUM))]
8021 "s390_logical_operator_ok_p (operands)"
8022 "@
8023 xilf\t%0,%b2
8024 xr\t%0,%2
8025 xrk\t%0,%1,%2
8026 xi\t%S0,%b2
8027 xiy\t%S0,%b2
8028 #"
8029 [(set_attr "op_type" "RIL,RR,RRF,SI,SIY,SS")
8030 (set_attr "cpu_facility" "*,*,z196,*,longdisp,*")
8031 (set_attr "z10prop" "z10_super_E1,z10_super_E1,*,z10_super,z10_super,*")])
8032
8033
8034 ;
8035 ; Block exclusive or (XC) patterns.
8036 ;
8037
8038 (define_insn "*xc"
8039 [(set (match_operand:BLK 0 "memory_operand" "=Q")
8040 (xor:BLK (match_dup 0)
8041 (match_operand:BLK 1 "memory_operand" "Q")))
8042 (use (match_operand 2 "const_int_operand" "n"))
8043 (clobber (reg:CC CC_REGNUM))]
8044 "INTVAL (operands[2]) >= 1 && INTVAL (operands[2]) <= 256"
8045 "xc\t%O0(%2,%R0),%S1"
8046 [(set_attr "op_type" "SS")])
8047
8048 (define_split
8049 [(set (match_operand 0 "memory_operand" "")
8050 (xor (match_dup 0)
8051 (match_operand 1 "memory_operand" "")))
8052 (clobber (reg:CC CC_REGNUM))]
8053 "reload_completed
8054 && GET_MODE (operands[0]) == GET_MODE (operands[1])
8055 && GET_MODE_SIZE (GET_MODE (operands[0])) > 0"
8056 [(parallel
8057 [(set (match_dup 0) (xor:BLK (match_dup 0) (match_dup 1)))
8058 (use (match_dup 2))
8059 (clobber (reg:CC CC_REGNUM))])]
8060 {
8061 operands[2] = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[0])));
8062 operands[0] = adjust_address (operands[0], BLKmode, 0);
8063 operands[1] = adjust_address (operands[1], BLKmode, 0);
8064 })
8065
8066 (define_peephole2
8067 [(parallel
8068 [(set (match_operand:BLK 0 "memory_operand" "")
8069 (xor:BLK (match_dup 0)
8070 (match_operand:BLK 1 "memory_operand" "")))
8071 (use (match_operand 2 "const_int_operand" ""))
8072 (clobber (reg:CC CC_REGNUM))])
8073 (parallel
8074 [(set (match_operand:BLK 3 "memory_operand" "")
8075 (xor:BLK (match_dup 3)
8076 (match_operand:BLK 4 "memory_operand" "")))
8077 (use (match_operand 5 "const_int_operand" ""))
8078 (clobber (reg:CC CC_REGNUM))])]
8079 "s390_offset_p (operands[0], operands[3], operands[2])
8080 && s390_offset_p (operands[1], operands[4], operands[2])
8081 && !s390_overlap_p (operands[0], operands[1],
8082 INTVAL (operands[2]) + INTVAL (operands[5]))
8083 && INTVAL (operands[2]) + INTVAL (operands[5]) <= 256"
8084 [(parallel
8085 [(set (match_dup 6) (xor:BLK (match_dup 6) (match_dup 7)))
8086 (use (match_dup 8))
8087 (clobber (reg:CC CC_REGNUM))])]
8088 "operands[6] = gen_rtx_MEM (BLKmode, XEXP (operands[0], 0));
8089 operands[7] = gen_rtx_MEM (BLKmode, XEXP (operands[1], 0));
8090 operands[8] = GEN_INT (INTVAL (operands[2]) + INTVAL (operands[5]));")
8091
8092 ;
8093 ; Block xor (XC) patterns with src == dest.
8094 ;
8095
8096 (define_insn "*xc_zero"
8097 [(set (match_operand:BLK 0 "memory_operand" "=Q")
8098 (const_int 0))
8099 (use (match_operand 1 "const_int_operand" "n"))
8100 (clobber (reg:CC CC_REGNUM))]
8101 "INTVAL (operands[1]) >= 1 && INTVAL (operands[1]) <= 256"
8102 "xc\t%O0(%1,%R0),%S0"
8103 [(set_attr "op_type" "SS")
8104 (set_attr "z196prop" "z196_cracked")])
8105
8106 (define_peephole2
8107 [(parallel
8108 [(set (match_operand:BLK 0 "memory_operand" "")
8109 (const_int 0))
8110 (use (match_operand 1 "const_int_operand" ""))
8111 (clobber (reg:CC CC_REGNUM))])
8112 (parallel
8113 [(set (match_operand:BLK 2 "memory_operand" "")
8114 (const_int 0))
8115 (use (match_operand 3 "const_int_operand" ""))
8116 (clobber (reg:CC CC_REGNUM))])]
8117 "s390_offset_p (operands[0], operands[2], operands[1])
8118 && INTVAL (operands[1]) + INTVAL (operands[3]) <= 256"
8119 [(parallel
8120 [(set (match_dup 4) (const_int 0))
8121 (use (match_dup 5))
8122 (clobber (reg:CC CC_REGNUM))])]
8123 "operands[4] = gen_rtx_MEM (BLKmode, XEXP (operands[0], 0));
8124 operands[5] = GEN_INT (INTVAL (operands[1]) + INTVAL (operands[3]));")
8125
8126
8127 ;;
8128 ;;- Negate instructions.
8129 ;;
8130
8131 ;
8132 ; neg(di|si)2 instruction pattern(s).
8133 ;
8134
8135 (define_expand "neg<mode>2"
8136 [(parallel
8137 [(set (match_operand:DSI 0 "register_operand" "=d")
8138 (neg:DSI (match_operand:DSI 1 "register_operand" "d")))
8139 (clobber (reg:CC CC_REGNUM))])]
8140 ""
8141 "")
8142
8143 (define_insn "*negdi2_sign_cc"
8144 [(set (reg CC_REGNUM)
8145 (compare (neg:DI (ashiftrt:DI (ashift:DI (subreg:DI
8146 (match_operand:SI 1 "register_operand" "d") 0)
8147 (const_int 32)) (const_int 32)))
8148 (const_int 0)))
8149 (set (match_operand:DI 0 "register_operand" "=d")
8150 (neg:DI (sign_extend:DI (match_dup 1))))]
8151 "TARGET_ZARCH && s390_match_ccmode (insn, CCAmode)"
8152 "lcgfr\t%0,%1"
8153 [(set_attr "op_type" "RRE")
8154 (set_attr "z10prop" "z10_c")])
8155
8156 (define_insn "*negdi2_sign"
8157 [(set (match_operand:DI 0 "register_operand" "=d")
8158 (neg:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "d"))))
8159 (clobber (reg:CC CC_REGNUM))]
8160 "TARGET_ZARCH"
8161 "lcgfr\t%0,%1"
8162 [(set_attr "op_type" "RRE")
8163 (set_attr "z10prop" "z10_c")])
8164
8165 ; lcr, lcgr
8166 (define_insn "*neg<mode>2_cc"
8167 [(set (reg CC_REGNUM)
8168 (compare (neg:GPR (match_operand:GPR 1 "register_operand" "d"))
8169 (const_int 0)))
8170 (set (match_operand:GPR 0 "register_operand" "=d")
8171 (neg:GPR (match_dup 1)))]
8172 "s390_match_ccmode (insn, CCAmode)"
8173 "lc<g>r\t%0,%1"
8174 [(set_attr "op_type" "RR<E>")
8175 (set_attr "z10prop" "z10_super_c_E1")])
8176
8177 ; lcr, lcgr
8178 (define_insn "*neg<mode>2_cconly"
8179 [(set (reg CC_REGNUM)
8180 (compare (neg:GPR (match_operand:GPR 1 "register_operand" "d"))
8181 (const_int 0)))
8182 (clobber (match_scratch:GPR 0 "=d"))]
8183 "s390_match_ccmode (insn, CCAmode)"
8184 "lc<g>r\t%0,%1"
8185 [(set_attr "op_type" "RR<E>")
8186 (set_attr "z10prop" "z10_super_c_E1")])
8187
8188 ; lcr, lcgr
8189 (define_insn "*neg<mode>2"
8190 [(set (match_operand:GPR 0 "register_operand" "=d")
8191 (neg:GPR (match_operand:GPR 1 "register_operand" "d")))
8192 (clobber (reg:CC CC_REGNUM))]
8193 ""
8194 "lc<g>r\t%0,%1"
8195 [(set_attr "op_type" "RR<E>")
8196 (set_attr "z10prop" "z10_super_c_E1")])
8197
8198 (define_insn "*negdi2_31"
8199 [(set (match_operand:DI 0 "register_operand" "=d")
8200 (neg:DI (match_operand:DI 1 "register_operand" "d")))
8201 (clobber (reg:CC CC_REGNUM))]
8202 "!TARGET_ZARCH"
8203 "#")
8204
8205 ; Split a DImode NEG on 31bit into 2 SImode NEGs
8206
8207 ; Doing the twos complement separately on the SImode parts does an
8208 ; unwanted +1 on the high part which needs to be subtracted afterwards
8209 ; ... unless the +1 on the low part created an overflow.
8210
8211 (define_split
8212 [(set (match_operand:DI 0 "register_operand" "")
8213 (neg:DI (match_operand:DI 1 "register_operand" "")))
8214 (clobber (reg:CC CC_REGNUM))]
8215 "!TARGET_ZARCH
8216 && (REGNO (operands[0]) == REGNO (operands[1])
8217 || s390_split_ok_p (operands[0], operands[1], DImode, 0))
8218 && reload_completed"
8219 [(parallel
8220 [(set (match_dup 2) (neg:SI (match_dup 3)))
8221 (clobber (reg:CC CC_REGNUM))])
8222 (parallel
8223 [(set (reg:CCAP CC_REGNUM)
8224 (compare:CCAP (neg:SI (match_dup 5)) (const_int 0)))
8225 (set (match_dup 4) (neg:SI (match_dup 5)))])
8226 (set (pc)
8227 (if_then_else (ne (reg:CCAP CC_REGNUM) (const_int 0))
8228 (pc)
8229 (label_ref (match_dup 6))))
8230 (parallel
8231 [(set (match_dup 2) (plus:SI (match_dup 2) (const_int -1)))
8232 (clobber (reg:CC CC_REGNUM))])
8233 (match_dup 6)]
8234 "operands[2] = operand_subword (operands[0], 0, 0, DImode);
8235 operands[3] = operand_subword (operands[1], 0, 0, DImode);
8236 operands[4] = operand_subword (operands[0], 1, 0, DImode);
8237 operands[5] = operand_subword (operands[1], 1, 0, DImode);
8238 operands[6] = gen_label_rtx ();")
8239
8240 ; Like above but first make a copy of the low part of the src operand
8241 ; since it might overlap with the high part of the destination.
8242
8243 (define_split
8244 [(set (match_operand:DI 0 "register_operand" "")
8245 (neg:DI (match_operand:DI 1 "register_operand" "")))
8246 (clobber (reg:CC CC_REGNUM))]
8247 "!TARGET_ZARCH
8248 && s390_split_ok_p (operands[0], operands[1], DImode, 1)
8249 && reload_completed"
8250 [; Make a backup of op5 first
8251 (set (match_dup 4) (match_dup 5))
8252 ; Setting op2 here might clobber op5
8253 (parallel
8254 [(set (match_dup 2) (neg:SI (match_dup 3)))
8255 (clobber (reg:CC CC_REGNUM))])
8256 (parallel
8257 [(set (reg:CCAP CC_REGNUM)
8258 (compare:CCAP (neg:SI (match_dup 4)) (const_int 0)))
8259 (set (match_dup 4) (neg:SI (match_dup 4)))])
8260 (set (pc)
8261 (if_then_else (ne (reg:CCAP CC_REGNUM) (const_int 0))
8262 (pc)
8263 (label_ref (match_dup 6))))
8264 (parallel
8265 [(set (match_dup 2) (plus:SI (match_dup 2) (const_int -1)))
8266 (clobber (reg:CC CC_REGNUM))])
8267 (match_dup 6)]
8268 "operands[2] = operand_subword (operands[0], 0, 0, DImode);
8269 operands[3] = operand_subword (operands[1], 0, 0, DImode);
8270 operands[4] = operand_subword (operands[0], 1, 0, DImode);
8271 operands[5] = operand_subword (operands[1], 1, 0, DImode);
8272 operands[6] = gen_label_rtx ();")
8273
8274 ;
8275 ; neg(df|sf)2 instruction pattern(s).
8276 ;
8277
8278 (define_expand "neg<mode>2"
8279 [(parallel
8280 [(set (match_operand:BFP 0 "register_operand" "=f")
8281 (neg:BFP (match_operand:BFP 1 "register_operand" "f")))
8282 (clobber (reg:CC CC_REGNUM))])]
8283 "TARGET_HARD_FLOAT"
8284 "")
8285
8286 ; lcxbr, lcdbr, lcebr
8287 (define_insn "*neg<mode>2_cc"
8288 [(set (reg CC_REGNUM)
8289 (compare (neg:BFP (match_operand:BFP 1 "register_operand" "f"))
8290 (match_operand:BFP 2 "const0_operand" "")))
8291 (set (match_operand:BFP 0 "register_operand" "=f")
8292 (neg:BFP (match_dup 1)))]
8293 "s390_match_ccmode (insn, CCSmode) && TARGET_HARD_FLOAT"
8294 "lc<xde>br\t%0,%1"
8295 [(set_attr "op_type" "RRE")
8296 (set_attr "type" "fsimp<mode>")])
8297
8298 ; lcxbr, lcdbr, lcebr
8299 (define_insn "*neg<mode>2_cconly"
8300 [(set (reg CC_REGNUM)
8301 (compare (neg:BFP (match_operand:BFP 1 "register_operand" "f"))
8302 (match_operand:BFP 2 "const0_operand" "")))
8303 (clobber (match_scratch:BFP 0 "=f"))]
8304 "s390_match_ccmode (insn, CCSmode) && TARGET_HARD_FLOAT"
8305 "lc<xde>br\t%0,%1"
8306 [(set_attr "op_type" "RRE")
8307 (set_attr "type" "fsimp<mode>")])
8308
8309 ; lcdfr
8310 (define_insn "*neg<mode>2_nocc"
8311 [(set (match_operand:FP 0 "register_operand" "=f")
8312 (neg:FP (match_operand:FP 1 "register_operand" "<fT0>")))]
8313 "TARGET_DFP"
8314 "lcdfr\t%0,%1"
8315 [(set_attr "op_type" "RRE")
8316 (set_attr "type" "fsimp<mode>")])
8317
8318 ; lcxbr, lcdbr, lcebr
8319 ; FIXME: wflcdb does not clobber cc
8320 (define_insn "*neg<mode>2"
8321 [(set (match_operand:BFP 0 "register_operand" "=f,v")
8322 (neg:BFP (match_operand:BFP 1 "register_operand" "f,v")))
8323 (clobber (reg:CC CC_REGNUM))]
8324 "TARGET_HARD_FLOAT"
8325 "@
8326 lc<xde>br\t%0,%1
8327 wflcdb\t%0,%1"
8328 [(set_attr "op_type" "RRE,VRR")
8329 (set_attr "cpu_facility" "*,vec")
8330 (set_attr "type" "fsimp<mode>,*")
8331 (set_attr "enabled" "*,<DFDI>")])
8332
8333
8334 ;;
8335 ;;- Absolute value instructions.
8336 ;;
8337
8338 ;
8339 ; abs(di|si)2 instruction pattern(s).
8340 ;
8341
8342 (define_insn "*absdi2_sign_cc"
8343 [(set (reg CC_REGNUM)
8344 (compare (abs:DI (ashiftrt:DI (ashift:DI (subreg:DI
8345 (match_operand:SI 1 "register_operand" "d") 0)
8346 (const_int 32)) (const_int 32)))
8347 (const_int 0)))
8348 (set (match_operand:DI 0 "register_operand" "=d")
8349 (abs:DI (sign_extend:DI (match_dup 1))))]
8350 "TARGET_ZARCH && s390_match_ccmode (insn, CCAmode)"
8351 "lpgfr\t%0,%1"
8352 [(set_attr "op_type" "RRE")
8353 (set_attr "z10prop" "z10_c")])
8354
8355 (define_insn "*absdi2_sign"
8356 [(set (match_operand:DI 0 "register_operand" "=d")
8357 (abs:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "d"))))
8358 (clobber (reg:CC CC_REGNUM))]
8359 "TARGET_ZARCH"
8360 "lpgfr\t%0,%1"
8361 [(set_attr "op_type" "RRE")
8362 (set_attr "z10prop" "z10_c")])
8363
8364 ; lpr, lpgr
8365 (define_insn "*abs<mode>2_cc"
8366 [(set (reg CC_REGNUM)
8367 (compare (abs:GPR (match_operand:DI 1 "register_operand" "d"))
8368 (const_int 0)))
8369 (set (match_operand:GPR 0 "register_operand" "=d")
8370 (abs:GPR (match_dup 1)))]
8371 "s390_match_ccmode (insn, CCAmode)"
8372 "lp<g>r\t%0,%1"
8373 [(set_attr "op_type" "RR<E>")
8374 (set_attr "z10prop" "z10_c")])
8375
8376 ; lpr, lpgr
8377 (define_insn "*abs<mode>2_cconly"
8378 [(set (reg CC_REGNUM)
8379 (compare (abs:GPR (match_operand:GPR 1 "register_operand" "d"))
8380 (const_int 0)))
8381 (clobber (match_scratch:GPR 0 "=d"))]
8382 "s390_match_ccmode (insn, CCAmode)"
8383 "lp<g>r\t%0,%1"
8384 [(set_attr "op_type" "RR<E>")
8385 (set_attr "z10prop" "z10_c")])
8386
8387 ; lpr, lpgr
8388 (define_insn "abs<mode>2"
8389 [(set (match_operand:GPR 0 "register_operand" "=d")
8390 (abs:GPR (match_operand:GPR 1 "register_operand" "d")))
8391 (clobber (reg:CC CC_REGNUM))]
8392 ""
8393 "lp<g>r\t%0,%1"
8394 [(set_attr "op_type" "RR<E>")
8395 (set_attr "z10prop" "z10_c")])
8396
8397 ;
8398 ; abs(df|sf)2 instruction pattern(s).
8399 ;
8400
8401 (define_expand "abs<mode>2"
8402 [(parallel
8403 [(set (match_operand:BFP 0 "register_operand" "=f")
8404 (abs:BFP (match_operand:BFP 1 "register_operand" "f")))
8405 (clobber (reg:CC CC_REGNUM))])]
8406 "TARGET_HARD_FLOAT"
8407 "")
8408
8409 ; lpxbr, lpdbr, lpebr
8410 (define_insn "*abs<mode>2_cc"
8411 [(set (reg CC_REGNUM)
8412 (compare (abs:BFP (match_operand:BFP 1 "register_operand" "f"))
8413 (match_operand:BFP 2 "const0_operand" "")))
8414 (set (match_operand:BFP 0 "register_operand" "=f")
8415 (abs:BFP (match_dup 1)))]
8416 "s390_match_ccmode (insn, CCSmode) && TARGET_HARD_FLOAT"
8417 "lp<xde>br\t%0,%1"
8418 [(set_attr "op_type" "RRE")
8419 (set_attr "type" "fsimp<mode>")])
8420
8421 ; lpxbr, lpdbr, lpebr
8422 (define_insn "*abs<mode>2_cconly"
8423 [(set (reg CC_REGNUM)
8424 (compare (abs:BFP (match_operand:BFP 1 "register_operand" "f"))
8425 (match_operand:BFP 2 "const0_operand" "")))
8426 (clobber (match_scratch:BFP 0 "=f"))]
8427 "s390_match_ccmode (insn, CCSmode) && TARGET_HARD_FLOAT"
8428 "lp<xde>br\t%0,%1"
8429 [(set_attr "op_type" "RRE")
8430 (set_attr "type" "fsimp<mode>")])
8431
8432 ; lpdfr
8433 (define_insn "*abs<mode>2_nocc"
8434 [(set (match_operand:FP 0 "register_operand" "=f")
8435 (abs:FP (match_operand:FP 1 "register_operand" "<fT0>")))]
8436 "TARGET_DFP"
8437 "lpdfr\t%0,%1"
8438 [(set_attr "op_type" "RRE")
8439 (set_attr "type" "fsimp<mode>")])
8440
8441 ; lpxbr, lpdbr, lpebr
8442 ; FIXME: wflpdb does not clobber cc
8443 (define_insn "*abs<mode>2"
8444 [(set (match_operand:BFP 0 "register_operand" "=f,v")
8445 (abs:BFP (match_operand:BFP 1 "register_operand" "f,v")))
8446 (clobber (reg:CC CC_REGNUM))]
8447 "TARGET_HARD_FLOAT"
8448 "@
8449 lp<xde>br\t%0,%1
8450 wflpdb\t%0,%1"
8451 [(set_attr "op_type" "RRE,VRR")
8452 (set_attr "cpu_facility" "*,vec")
8453 (set_attr "type" "fsimp<mode>,*")
8454 (set_attr "enabled" "*,<DFDI>")])
8455
8456
8457 ;;
8458 ;;- Negated absolute value instructions
8459 ;;
8460
8461 ;
8462 ; Integer
8463 ;
8464
8465 (define_insn "*negabsdi2_sign_cc"
8466 [(set (reg CC_REGNUM)
8467 (compare (neg:DI (abs:DI (ashiftrt:DI (ashift:DI (subreg:DI
8468 (match_operand:SI 1 "register_operand" "d") 0)
8469 (const_int 32)) (const_int 32))))
8470 (const_int 0)))
8471 (set (match_operand:DI 0 "register_operand" "=d")
8472 (neg:DI (abs:DI (sign_extend:DI (match_dup 1)))))]
8473 "TARGET_ZARCH && s390_match_ccmode (insn, CCAmode)"
8474 "lngfr\t%0,%1"
8475 [(set_attr "op_type" "RRE")
8476 (set_attr "z10prop" "z10_c")])
8477
8478 (define_insn "*negabsdi2_sign"
8479 [(set (match_operand:DI 0 "register_operand" "=d")
8480 (neg:DI (abs:DI (sign_extend:DI
8481 (match_operand:SI 1 "register_operand" "d")))))
8482 (clobber (reg:CC CC_REGNUM))]
8483 "TARGET_ZARCH"
8484 "lngfr\t%0,%1"
8485 [(set_attr "op_type" "RRE")
8486 (set_attr "z10prop" "z10_c")])
8487
8488 ; lnr, lngr
8489 (define_insn "*negabs<mode>2_cc"
8490 [(set (reg CC_REGNUM)
8491 (compare (neg:GPR (abs:GPR (match_operand:GPR 1 "register_operand" "d")))
8492 (const_int 0)))
8493 (set (match_operand:GPR 0 "register_operand" "=d")
8494 (neg:GPR (abs:GPR (match_dup 1))))]
8495 "s390_match_ccmode (insn, CCAmode)"
8496 "ln<g>r\t%0,%1"
8497 [(set_attr "op_type" "RR<E>")
8498 (set_attr "z10prop" "z10_c")])
8499
8500 ; lnr, lngr
8501 (define_insn "*negabs<mode>2_cconly"
8502 [(set (reg CC_REGNUM)
8503 (compare (neg:GPR (abs:GPR (match_operand:GPR 1 "register_operand" "d")))
8504 (const_int 0)))
8505 (clobber (match_scratch:GPR 0 "=d"))]
8506 "s390_match_ccmode (insn, CCAmode)"
8507 "ln<g>r\t%0,%1"
8508 [(set_attr "op_type" "RR<E>")
8509 (set_attr "z10prop" "z10_c")])
8510
8511 ; lnr, lngr
8512 (define_insn "*negabs<mode>2"
8513 [(set (match_operand:GPR 0 "register_operand" "=d")
8514 (neg:GPR (abs:GPR (match_operand:GPR 1 "register_operand" "d"))))
8515 (clobber (reg:CC CC_REGNUM))]
8516 ""
8517 "ln<g>r\t%0,%1"
8518 [(set_attr "op_type" "RR<E>")
8519 (set_attr "z10prop" "z10_c")])
8520
8521 ;
8522 ; Floating point
8523 ;
8524
8525 ; lnxbr, lndbr, lnebr
8526 (define_insn "*negabs<mode>2_cc"
8527 [(set (reg CC_REGNUM)
8528 (compare (neg:BFP (abs:BFP (match_operand:BFP 1 "register_operand" "f")))
8529 (match_operand:BFP 2 "const0_operand" "")))
8530 (set (match_operand:BFP 0 "register_operand" "=f")
8531 (neg:BFP (abs:BFP (match_dup 1))))]
8532 "s390_match_ccmode (insn, CCSmode) && TARGET_HARD_FLOAT"
8533 "ln<xde>br\t%0,%1"
8534 [(set_attr "op_type" "RRE")
8535 (set_attr "type" "fsimp<mode>")])
8536
8537 ; lnxbr, lndbr, lnebr
8538 (define_insn "*negabs<mode>2_cconly"
8539 [(set (reg CC_REGNUM)
8540 (compare (neg:BFP (abs:BFP (match_operand:BFP 1 "register_operand" "f")))
8541 (match_operand:BFP 2 "const0_operand" "")))
8542 (clobber (match_scratch:BFP 0 "=f"))]
8543 "s390_match_ccmode (insn, CCSmode) && TARGET_HARD_FLOAT"
8544 "ln<xde>br\t%0,%1"
8545 [(set_attr "op_type" "RRE")
8546 (set_attr "type" "fsimp<mode>")])
8547
8548 ; lndfr
8549 (define_insn "*negabs<mode>2_nocc"
8550 [(set (match_operand:FP 0 "register_operand" "=f")
8551 (neg:FP (abs:FP (match_operand:BFP 1 "register_operand" "<fT0>"))))]
8552 "TARGET_DFP"
8553 "lndfr\t%0,%1"
8554 [(set_attr "op_type" "RRE")
8555 (set_attr "type" "fsimp<mode>")])
8556
8557 ; lnxbr, lndbr, lnebr
8558 ; FIXME: wflndb does not clobber cc
8559 (define_insn "*negabs<mode>2"
8560 [(set (match_operand:BFP 0 "register_operand" "=f,v")
8561 (neg:BFP (abs:BFP (match_operand:BFP 1 "register_operand" "f,v"))))
8562 (clobber (reg:CC CC_REGNUM))]
8563 "TARGET_HARD_FLOAT"
8564 "@
8565 ln<xde>br\t%0,%1
8566 wflndb\t%0,%1"
8567 [(set_attr "op_type" "RRE,VRR")
8568 (set_attr "cpu_facility" "*,vec")
8569 (set_attr "type" "fsimp<mode>,*")
8570 (set_attr "enabled" "*,<DFDI>")])
8571
8572 ;;
8573 ;;- Square root instructions.
8574 ;;
8575
8576 ;
8577 ; sqrt(df|sf)2 instruction pattern(s).
8578 ;
8579
8580 ; sqxbr, sqdbr, sqebr, sqdb, sqeb
8581 (define_insn "sqrt<mode>2"
8582 [(set (match_operand:BFP 0 "register_operand" "=f,f,v")
8583 (sqrt:BFP (match_operand:BFP 1 "general_operand" "f,R,v")))]
8584 "TARGET_HARD_FLOAT"
8585 "@
8586 sq<xde>br\t%0,%1
8587 sq<xde>b\t%0,%1
8588 wfsqdb\t%v0,%v1"
8589 [(set_attr "op_type" "RRE,RXE,VRR")
8590 (set_attr "type" "fsqrt<mode>")
8591 (set_attr "cpu_facility" "*,*,vec")
8592 (set_attr "enabled" "*,<DSF>,<DFDI>")])
8593
8594
8595 ;;
8596 ;;- One complement instructions.
8597 ;;
8598
8599 ;
8600 ; one_cmpl(di|si|hi|qi)2 instruction pattern(s).
8601 ;
8602
8603 (define_expand "one_cmpl<mode>2"
8604 [(parallel
8605 [(set (match_operand:INT 0 "register_operand" "")
8606 (xor:INT (match_operand:INT 1 "register_operand" "")
8607 (const_int -1)))
8608 (clobber (reg:CC CC_REGNUM))])]
8609 ""
8610 "")
8611
8612
8613 ;;
8614 ;; Find leftmost bit instructions.
8615 ;;
8616
8617 (define_expand "clzdi2"
8618 [(set (match_operand:DI 0 "register_operand" "=d")
8619 (clz:DI (match_operand:DI 1 "register_operand" "d")))]
8620 "TARGET_EXTIMM && TARGET_ZARCH"
8621 {
8622 rtx_insn *insn;
8623 rtx clz_equal;
8624 rtx wide_reg = gen_reg_rtx (TImode);
8625 rtx msb = gen_rtx_CONST_INT (DImode, (unsigned HOST_WIDE_INT) 1 << 63);
8626
8627 clz_equal = gen_rtx_CLZ (DImode, operands[1]);
8628
8629 emit_insn (gen_clztidi2 (wide_reg, operands[1], msb));
8630
8631 insn = emit_move_insn (operands[0], gen_highpart (DImode, wide_reg));
8632 set_unique_reg_note (insn, REG_EQUAL, clz_equal);
8633
8634 DONE;
8635 })
8636
8637 (define_insn "clztidi2"
8638 [(set (match_operand:TI 0 "register_operand" "=d")
8639 (ior:TI
8640 (ashift:TI
8641 (zero_extend:TI
8642 (xor:DI (match_operand:DI 1 "register_operand" "d")
8643 (lshiftrt (match_operand:DI 2 "const_int_operand" "")
8644 (subreg:SI (clz:DI (match_dup 1)) 4))))
8645
8646 (const_int 64))
8647 (zero_extend:TI (clz:DI (match_dup 1)))))
8648 (clobber (reg:CC CC_REGNUM))]
8649 "(unsigned HOST_WIDE_INT) INTVAL (operands[2])
8650 == (unsigned HOST_WIDE_INT) 1 << 63
8651 && TARGET_EXTIMM && TARGET_ZARCH"
8652 "flogr\t%0,%1"
8653 [(set_attr "op_type" "RRE")])
8654
8655
8656 ;;
8657 ;;- Rotate instructions.
8658 ;;
8659
8660 ;
8661 ; rotl(di|si)3 instruction pattern(s).
8662 ;
8663
8664 (define_expand "rotl<mode>3"
8665 [(set (match_operand:GPR 0 "register_operand" "")
8666 (rotate:GPR (match_operand:GPR 1 "register_operand" "")
8667 (match_operand:SI 2 "nonmemory_operand" "")))]
8668 "TARGET_CPU_ZARCH"
8669 "")
8670
8671 ; rll, rllg
8672 (define_insn "*rotl<mode>3<addr_style_op><masked_op>"
8673 [(set (match_operand:GPR 0 "register_operand" "=d")
8674 (rotate:GPR (match_operand:GPR 1 "register_operand" "d")
8675 (match_operand:SI 2 "nonmemory_operand" "an")))]
8676 "TARGET_CPU_ZARCH"
8677 "rll<g>\t%0,%1,<addr_style_op_ops>"
8678 [(set_attr "op_type" "RSE")
8679 (set_attr "atype" "reg")
8680 (set_attr "z10prop" "z10_super_E1")])
8681
8682
8683 ;;
8684 ;;- Shift instructions.
8685 ;;
8686
8687 ;
8688 ; (ashl|lshr)(di|si)3 instruction pattern(s).
8689 ; Left shifts and logical right shifts
8690
8691 (define_expand "<shift><mode>3"
8692 [(set (match_operand:DSI 0 "register_operand" "")
8693 (SHIFT:DSI (match_operand:DSI 1 "register_operand" "")
8694 (match_operand:SI 2 "nonmemory_operand" "")))]
8695 ""
8696 "")
8697
8698 ; ESA 64 bit register pair shift with reg or imm shift count
8699 ; sldl, srdl
8700 (define_insn "*<shift>di3_31<addr_style_op><masked_op>"
8701 [(set (match_operand:DI 0 "register_operand" "=d")
8702 (SHIFT:DI (match_operand:DI 1 "register_operand" "0")
8703 (match_operand:SI 2 "nonmemory_operand" "an")))]
8704 "!TARGET_ZARCH"
8705 "s<lr>dl\t%0,<addr_style_op_ops>"
8706 [(set_attr "op_type" "RS")
8707 (set_attr "atype" "reg")
8708 (set_attr "z196prop" "z196_cracked")])
8709
8710
8711 ; 64 bit register shift with reg or imm shift count
8712 ; sll, srl, sllg, srlg, sllk, srlk
8713 (define_insn "*<shift><mode>3<addr_style_op><masked_op>"
8714 [(set (match_operand:GPR 0 "register_operand" "=d, d")
8715 (SHIFT:GPR (match_operand:GPR 1 "register_operand" "<d0>, d")
8716 (match_operand:SI 2 "nonmemory_operand" "an,an")))]
8717 ""
8718 "@
8719 s<lr>l<g>\t%0,<1><addr_style_op_ops>
8720 s<lr>l<gk>\t%0,%1,<addr_style_op_ops>"
8721 [(set_attr "op_type" "RS<E>,RSY")
8722 (set_attr "atype" "reg,reg")
8723 (set_attr "cpu_facility" "*,z196")
8724 (set_attr "z10prop" "z10_super_E1,*")])
8725
8726 ;
8727 ; ashr(di|si)3 instruction pattern(s).
8728 ; Arithmetic right shifts
8729
8730 (define_expand "ashr<mode>3"
8731 [(parallel
8732 [(set (match_operand:DSI 0 "register_operand" "")
8733 (ashiftrt:DSI (match_operand:DSI 1 "register_operand" "")
8734 (match_operand:SI 2 "nonmemory_operand" "")))
8735 (clobber (reg:CC CC_REGNUM))])]
8736 ""
8737 "")
8738
8739 ; FIXME: The number of alternatives is doubled here to match the fix
8740 ; number of 2 in the subst pattern for the (clobber (match_scratch...
8741 ; The right fix should be to support match_scratch in the output
8742 ; pattern of a define_subst.
8743 (define_insn "*ashrdi3_31<addr_style_op_cc><masked_op_cc><setcc><cconly>"
8744 [(set (match_operand:DI 0 "register_operand" "=d, d")
8745 (ashiftrt:DI (match_operand:DI 1 "register_operand" "0, 0")
8746 (match_operand:SI 2 "nonmemory_operand" "an,an")))
8747 (clobber (reg:CC CC_REGNUM))]
8748 "!TARGET_ZARCH"
8749 "@
8750 srda\t%0,<addr_style_op_cc_ops>
8751 srda\t%0,<addr_style_op_cc_ops>"
8752 [(set_attr "op_type" "RS")
8753 (set_attr "atype" "reg")])
8754
8755
8756 ; sra, srag
8757 (define_insn "*ashr<mode>3<addr_style_op_cc><masked_op_cc><setcc><cconly>"
8758 [(set (match_operand:GPR 0 "register_operand" "=d, d")
8759 (ashiftrt:GPR (match_operand:GPR 1 "register_operand" "<d0>, d")
8760 (match_operand:SI 2 "nonmemory_operand" "an,an")))
8761 (clobber (reg:CC CC_REGNUM))]
8762 ""
8763 "@
8764 sra<g>\t%0,<1><addr_style_op_cc_ops>
8765 sra<gk>\t%0,%1,<addr_style_op_cc_ops>"
8766 [(set_attr "op_type" "RS<E>,RSY")
8767 (set_attr "atype" "reg")
8768 (set_attr "cpu_facility" "*,z196")
8769 (set_attr "z10prop" "z10_super_E1,*")])
8770
8771
8772 ;;
8773 ;; Branch instruction patterns.
8774 ;;
8775
8776 (define_expand "cbranch<mode>4"
8777 [(set (pc)
8778 (if_then_else (match_operator 0 "comparison_operator"
8779 [(match_operand:GPR 1 "register_operand" "")
8780 (match_operand:GPR 2 "general_operand" "")])
8781 (label_ref (match_operand 3 "" ""))
8782 (pc)))]
8783 ""
8784 "s390_emit_jump (operands[3],
8785 s390_emit_compare (GET_CODE (operands[0]), operands[1], operands[2]));
8786 DONE;")
8787
8788 (define_expand "cbranch<mode>4"
8789 [(set (pc)
8790 (if_then_else (match_operator 0 "comparison_operator"
8791 [(match_operand:FP 1 "register_operand" "")
8792 (match_operand:FP 2 "general_operand" "")])
8793 (label_ref (match_operand 3 "" ""))
8794 (pc)))]
8795 "TARGET_HARD_FLOAT"
8796 "s390_emit_jump (operands[3],
8797 s390_emit_compare (GET_CODE (operands[0]), operands[1], operands[2]));
8798 DONE;")
8799
8800 (define_expand "cbranchcc4"
8801 [(set (pc)
8802 (if_then_else (match_operator 0 "s390_comparison"
8803 [(match_operand 1 "cc_reg_operand" "")
8804 (match_operand 2 "const_int_operand" "")])
8805 (label_ref (match_operand 3 "" ""))
8806 (pc)))]
8807 ""
8808 "")
8809
8810
8811 ;;
8812 ;;- Conditional jump instructions.
8813 ;;
8814
8815 (define_insn "*cjump_64"
8816 [(set (pc)
8817 (if_then_else
8818 (match_operator 1 "s390_comparison" [(reg CC_REGNUM)
8819 (match_operand 2 "const_int_operand" "")])
8820 (label_ref (match_operand 0 "" ""))
8821 (pc)))]
8822 "TARGET_CPU_ZARCH"
8823 {
8824 if (get_attr_length (insn) == 4)
8825 return "j%C1\t%l0";
8826 else
8827 return "jg%C1\t%l0";
8828 }
8829 [(set_attr "op_type" "RI")
8830 (set_attr "type" "branch")
8831 (set (attr "length")
8832 (if_then_else (lt (abs (minus (pc) (match_dup 0))) (const_int 60000))
8833 (const_int 4) (const_int 6)))])
8834
8835 (define_insn "*cjump_31"
8836 [(set (pc)
8837 (if_then_else
8838 (match_operator 1 "s390_comparison" [(reg CC_REGNUM)
8839 (match_operand 2 "const_int_operand" "")])
8840 (label_ref (match_operand 0 "" ""))
8841 (pc)))]
8842 "!TARGET_CPU_ZARCH"
8843 {
8844 gcc_assert (get_attr_length (insn) == 4);
8845 return "j%C1\t%l0";
8846 }
8847 [(set_attr "op_type" "RI")
8848 (set_attr "type" "branch")
8849 (set (attr "length")
8850 (if_then_else (not (match_test "flag_pic"))
8851 (if_then_else (lt (abs (minus (pc) (match_dup 0))) (const_int 60000))
8852 (const_int 4) (const_int 6))
8853 (if_then_else (lt (abs (minus (pc) (match_dup 0))) (const_int 60000))
8854 (const_int 4) (const_int 8))))])
8855
8856 (define_insn "*cjump_long"
8857 [(set (pc)
8858 (if_then_else
8859 (match_operator 1 "s390_comparison" [(reg CC_REGNUM) (const_int 0)])
8860 (match_operand 0 "address_operand" "ZQZR")
8861 (pc)))]
8862 ""
8863 {
8864 if (get_attr_op_type (insn) == OP_TYPE_RR)
8865 return "b%C1r\t%0";
8866 else
8867 return "b%C1\t%a0";
8868 }
8869 [(set (attr "op_type")
8870 (if_then_else (match_operand 0 "register_operand" "")
8871 (const_string "RR") (const_string "RX")))
8872 (set_attr "type" "branch")
8873 (set_attr "atype" "agen")])
8874
8875 ;; A conditional return instruction.
8876 (define_insn "*c<code>"
8877 [(set (pc)
8878 (if_then_else
8879 (match_operator 0 "s390_comparison" [(reg CC_REGNUM) (const_int 0)])
8880 (ANY_RETURN)
8881 (pc)))]
8882 "s390_can_use_<code>_insn ()"
8883 "b%C0r\t%%r14"
8884 [(set_attr "op_type" "RR")
8885 (set_attr "type" "jsr")
8886 (set_attr "atype" "agen")])
8887
8888 ;;
8889 ;;- Negated conditional jump instructions.
8890 ;;
8891
8892 (define_insn "*icjump_64"
8893 [(set (pc)
8894 (if_then_else
8895 (match_operator 1 "s390_comparison" [(reg CC_REGNUM) (const_int 0)])
8896 (pc)
8897 (label_ref (match_operand 0 "" ""))))]
8898 "TARGET_CPU_ZARCH"
8899 {
8900 if (get_attr_length (insn) == 4)
8901 return "j%D1\t%l0";
8902 else
8903 return "jg%D1\t%l0";
8904 }
8905 [(set_attr "op_type" "RI")
8906 (set_attr "type" "branch")
8907 (set (attr "length")
8908 (if_then_else (lt (abs (minus (pc) (match_dup 0))) (const_int 60000))
8909 (const_int 4) (const_int 6)))])
8910
8911 (define_insn "*icjump_31"
8912 [(set (pc)
8913 (if_then_else
8914 (match_operator 1 "s390_comparison" [(reg CC_REGNUM) (const_int 0)])
8915 (pc)
8916 (label_ref (match_operand 0 "" ""))))]
8917 "!TARGET_CPU_ZARCH"
8918 {
8919 gcc_assert (get_attr_length (insn) == 4);
8920 return "j%D1\t%l0";
8921 }
8922 [(set_attr "op_type" "RI")
8923 (set_attr "type" "branch")
8924 (set (attr "length")
8925 (if_then_else (not (match_test "flag_pic"))
8926 (if_then_else (lt (abs (minus (pc) (match_dup 0))) (const_int 60000))
8927 (const_int 4) (const_int 6))
8928 (if_then_else (lt (abs (minus (pc) (match_dup 0))) (const_int 60000))
8929 (const_int 4) (const_int 8))))])
8930
8931 (define_insn "*icjump_long"
8932 [(set (pc)
8933 (if_then_else
8934 (match_operator 1 "s390_comparison" [(reg CC_REGNUM) (const_int 0)])
8935 (pc)
8936 (match_operand 0 "address_operand" "ZQZR")))]
8937 ""
8938 {
8939 if (get_attr_op_type (insn) == OP_TYPE_RR)
8940 return "b%D1r\t%0";
8941 else
8942 return "b%D1\t%a0";
8943 }
8944 [(set (attr "op_type")
8945 (if_then_else (match_operand 0 "register_operand" "")
8946 (const_string "RR") (const_string "RX")))
8947 (set_attr "type" "branch")
8948 (set_attr "atype" "agen")])
8949
8950 ;;
8951 ;;- Trap instructions.
8952 ;;
8953
8954 (define_insn "trap"
8955 [(trap_if (const_int 1) (const_int 0))]
8956 ""
8957 "j\t.+2"
8958 [(set_attr "op_type" "RI")
8959 (set_attr "type" "branch")])
8960
8961 (define_expand "ctrap<mode>4"
8962 [(trap_if (match_operator 0 "comparison_operator"
8963 [(match_operand:GPR 1 "register_operand" "")
8964 (match_operand:GPR 2 "general_operand" "")])
8965 (match_operand 3 "const0_operand" ""))]
8966 ""
8967 {
8968 rtx cond = s390_emit_compare (GET_CODE (operands[0]),
8969 operands[1], operands[2]);
8970 emit_insn (gen_condtrap (cond, XEXP (cond, 0)));
8971 DONE;
8972 })
8973
8974 (define_expand "ctrap<mode>4"
8975 [(trap_if (match_operator 0 "comparison_operator"
8976 [(match_operand:FP 1 "register_operand" "")
8977 (match_operand:FP 2 "general_operand" "")])
8978 (match_operand 3 "const0_operand" ""))]
8979 ""
8980 {
8981 rtx cond = s390_emit_compare (GET_CODE (operands[0]),
8982 operands[1], operands[2]);
8983 emit_insn (gen_condtrap (cond, XEXP (cond, 0)));
8984 DONE;
8985 })
8986
8987 (define_insn "condtrap"
8988 [(trap_if (match_operator 0 "s390_comparison"
8989 [(match_operand 1 "cc_reg_operand" "c")
8990 (const_int 0)])
8991 (const_int 0))]
8992 ""
8993 "j%C0\t.+2";
8994 [(set_attr "op_type" "RI")
8995 (set_attr "type" "branch")])
8996
8997 ; crt, cgrt, cit, cgit
8998 (define_insn "*cmp_and_trap_signed_int<mode>"
8999 [(trap_if (match_operator 0 "s390_signed_integer_comparison"
9000 [(match_operand:GPR 1 "register_operand" "d,d")
9001 (match_operand:GPR 2 "nonmemory_operand" "d,K")])
9002 (const_int 0))]
9003 "TARGET_Z10"
9004 "@
9005 c<g>rt%C0\t%1,%2
9006 c<g>it%C0\t%1,%h2"
9007 [(set_attr "op_type" "RRF,RIE")
9008 (set_attr "type" "branch")
9009 (set_attr "z10prop" "z10_super_c,z10_super")])
9010
9011 ; clrt, clgrt, clfit, clgit, clt, clgt
9012 (define_insn "*cmp_and_trap_unsigned_int<mode>"
9013 [(trap_if (match_operator 0 "s390_unsigned_integer_comparison"
9014 [(match_operand:GPR 1 "register_operand" "d,d,d")
9015 (match_operand:GPR 2 "general_operand" "d,D,T")])
9016 (const_int 0))]
9017 "TARGET_Z10"
9018 "@
9019 cl<g>rt%C0\t%1,%2
9020 cl<gf>it%C0\t%1,%x2
9021 cl<g>t%C0\t%1,%2"
9022 [(set_attr "op_type" "RRF,RIE,RSY")
9023 (set_attr "type" "branch")
9024 (set_attr "z10prop" "z10_super_c,z10_super,*")
9025 (set_attr "cpu_facility" "z10,z10,zEC12")])
9026
9027 ; lat, lgat
9028 (define_insn "*load_and_trap<mode>"
9029 [(trap_if (eq (match_operand:GPR 0 "memory_operand" "T")
9030 (const_int 0))
9031 (const_int 0))
9032 (set (match_operand:GPR 1 "register_operand" "=d")
9033 (match_dup 0))]
9034 "TARGET_ZEC12"
9035 "l<g>at\t%1,%0"
9036 [(set_attr "op_type" "RXY")])
9037
9038
9039 ;;
9040 ;;- Loop instructions.
9041 ;;
9042 ;; This is all complicated by the fact that since this is a jump insn
9043 ;; we must handle our own output reloads.
9044
9045 ;; branch on index
9046
9047 ; This splitter will be matched by combine and has to add the 2 moves
9048 ; necessary to load the compare and the increment values into a
9049 ; register pair as needed by brxle.
9050
9051 (define_insn_and_split "*brx_stage1_<GPR:mode>"
9052 [(set (pc)
9053 (if_then_else
9054 (match_operator 6 "s390_brx_operator"
9055 [(plus:GPR (match_operand:GPR 1 "register_operand" "")
9056 (match_operand:GPR 2 "general_operand" ""))
9057 (match_operand:GPR 3 "register_operand" "")])
9058 (label_ref (match_operand 0 "" ""))
9059 (pc)))
9060 (set (match_operand:GPR 4 "nonimmediate_operand" "")
9061 (plus:GPR (match_dup 1) (match_dup 2)))
9062 (clobber (match_scratch:GPR 5 ""))]
9063 "TARGET_CPU_ZARCH"
9064 "#"
9065 "!reload_completed && !reload_in_progress"
9066 [(set (match_dup 7) (match_dup 2)) ; the increment
9067 (set (match_dup 8) (match_dup 3)) ; the comparison value
9068 (parallel [(set (pc)
9069 (if_then_else
9070 (match_op_dup 6
9071 [(plus:GPR (match_dup 1) (match_dup 7))
9072 (match_dup 8)])
9073 (label_ref (match_dup 0))
9074 (pc)))
9075 (set (match_dup 4)
9076 (plus:GPR (match_dup 1) (match_dup 7)))
9077 (clobber (match_dup 5))
9078 (clobber (reg:CC CC_REGNUM))])]
9079 {
9080 rtx dreg = gen_reg_rtx (word_mode == DImode ? TImode : DImode);
9081 operands[7] = gen_lowpart (<GPR:MODE>mode,
9082 gen_highpart (word_mode, dreg));
9083 operands[8] = gen_lowpart (<GPR:MODE>mode,
9084 gen_lowpart (word_mode, dreg));
9085 })
9086
9087 ; brxlg, brxhg
9088
9089 (define_insn_and_split "*brxg_64bit"
9090 [(set (pc)
9091 (if_then_else
9092 (match_operator 5 "s390_brx_operator"
9093 [(plus:DI (match_operand:DI 1 "register_operand" "d,d,d")
9094 (subreg:DI (match_operand:TI 2 "register_operand" "d,d,d") 0))
9095 (subreg:DI (match_dup 2) 8)])
9096 (label_ref (match_operand 0 "" ""))
9097 (pc)))
9098 (set (match_operand:DI 3 "nonimmediate_operand" "=1,?X,?X")
9099 (plus:DI (match_dup 1)
9100 (subreg:DI (match_dup 2) 0)))
9101 (clobber (match_scratch:DI 4 "=X,&1,&?d"))
9102 (clobber (reg:CC CC_REGNUM))]
9103 "TARGET_ZARCH"
9104 {
9105 if (which_alternative != 0)
9106 return "#";
9107 else if (get_attr_length (insn) == 6)
9108 return "brx%E5g\t%1,%2,%l0";
9109 else
9110 return "agr\t%1,%2\;cgr\t%1,%M2\;jg%C5\t%l0";
9111 }
9112 "&& reload_completed
9113 && (!REG_P (operands[3])
9114 || !rtx_equal_p (operands[1], operands[3]))"
9115 [(set (match_dup 4) (match_dup 1))
9116 (parallel [(set (match_dup 4) (plus:DI (match_dup 4) (subreg:DI (match_dup 2) 0)))
9117 (clobber (reg:CC CC_REGNUM))])
9118 (set (reg:CCS CC_REGNUM) (compare:CCS (match_dup 4) (subreg:DI (match_dup 2) 8)))
9119 (set (match_dup 3) (match_dup 4))
9120 (set (pc) (if_then_else (match_op_dup 5 [(reg:CCS CC_REGNUM) (const_int 0)])
9121 (label_ref (match_dup 0))
9122 (pc)))]
9123 ""
9124 [(set_attr "op_type" "RIE")
9125 (set_attr "type" "branch")
9126 (set (attr "length")
9127 (if_then_else (lt (abs (minus (pc) (match_dup 0))) (const_int 60000))
9128 (const_int 6) (const_int 16)))])
9129
9130 ; brxle, brxh
9131
9132 (define_insn_and_split "*brx_64bit"
9133 [(set (pc)
9134 (if_then_else
9135 (match_operator 5 "s390_brx_operator"
9136 [(plus:SI (match_operand:SI 1 "register_operand" "d,d,d")
9137 (subreg:SI (match_operand:TI 2 "register_operand" "d,d,d") 4))
9138 (subreg:SI (match_dup 2) 12)])
9139 (label_ref (match_operand 0 "" ""))
9140 (pc)))
9141 (set (match_operand:SI 3 "nonimmediate_operand" "=1,?X,?X")
9142 (plus:SI (match_dup 1)
9143 (subreg:SI (match_dup 2) 4)))
9144 (clobber (match_scratch:SI 4 "=X,&1,&?d"))
9145 (clobber (reg:CC CC_REGNUM))]
9146 "TARGET_ZARCH"
9147 {
9148 if (which_alternative != 0)
9149 return "#";
9150 else if (get_attr_length (insn) == 6)
9151 return "brx%C5\t%1,%2,%l0";
9152 else
9153 return "ar\t%1,%2\;cr\t%1,%M2\;jg%C5\t%l0";
9154 }
9155 "&& reload_completed
9156 && (!REG_P (operands[3])
9157 || !rtx_equal_p (operands[1], operands[3]))"
9158 [(set (match_dup 4) (match_dup 1))
9159 (parallel [(set (match_dup 4) (plus:SI (match_dup 4) (subreg:SI (match_dup 2) 4)))
9160 (clobber (reg:CC CC_REGNUM))])
9161 (set (reg:CCS CC_REGNUM) (compare:CCS (match_dup 4) (subreg:SI (match_dup 2) 12)))
9162 (set (match_dup 3) (match_dup 4))
9163 (set (pc) (if_then_else (match_op_dup 5 [(reg:CCS CC_REGNUM) (const_int 0)])
9164 (label_ref (match_dup 0))
9165 (pc)))]
9166 ""
9167 [(set_attr "op_type" "RSI")
9168 (set_attr "type" "branch")
9169 (set (attr "length")
9170 (if_then_else (lt (abs (minus (pc) (match_dup 0))) (const_int 60000))
9171 (const_int 6) (const_int 14)))])
9172
9173 ; brxle, brxh
9174
9175 (define_insn_and_split "*brx_31bit"
9176 [(set (pc)
9177 (if_then_else
9178 (match_operator 5 "s390_brx_operator"
9179 [(plus:SI (match_operand:SI 1 "register_operand" "d,d,d")
9180 (subreg:SI (match_operand:DI 2 "register_operand" "d,d,d") 0))
9181 (subreg:SI (match_dup 2) 4)])
9182 (label_ref (match_operand 0 "" ""))
9183 (pc)))
9184 (set (match_operand:SI 3 "nonimmediate_operand" "=1,?X,?X")
9185 (plus:SI (match_dup 1)
9186 (subreg:SI (match_dup 2) 0)))
9187 (clobber (match_scratch:SI 4 "=X,&1,&?d"))
9188 (clobber (reg:CC CC_REGNUM))]
9189 "!TARGET_ZARCH && TARGET_CPU_ZARCH"
9190 {
9191 if (which_alternative != 0)
9192 return "#";
9193 else if (get_attr_length (insn) == 6)
9194 return "brx%C5\t%1,%2,%l0";
9195 else
9196 return "ar\t%1,%2\;cr\t%1,%M2\;jg%C5\t%l0";
9197 }
9198 "&& reload_completed
9199 && (!REG_P (operands[3])
9200 || !rtx_equal_p (operands[1], operands[3]))"
9201 [(set (match_dup 4) (match_dup 1))
9202 (parallel [(set (match_dup 4) (plus:SI (match_dup 4) (subreg:SI (match_dup 2) 0)))
9203 (clobber (reg:CC CC_REGNUM))])
9204 (set (reg:CCS CC_REGNUM) (compare:CCS (match_dup 4) (subreg:SI (match_dup 2) 4)))
9205 (set (match_dup 3) (match_dup 4))
9206 (set (pc) (if_then_else (match_op_dup 5 [(reg:CCS CC_REGNUM) (const_int 0)])
9207 (label_ref (match_dup 0))
9208 (pc)))]
9209 ""
9210 [(set_attr "op_type" "RSI")
9211 (set_attr "type" "branch")
9212 (set (attr "length")
9213 (if_then_else (lt (abs (minus (pc) (match_dup 0))) (const_int 60000))
9214 (const_int 6) (const_int 14)))])
9215
9216
9217 ;; branch on count
9218
9219 (define_expand "doloop_end"
9220 [(use (match_operand 0 "" "")) ; loop pseudo
9221 (use (match_operand 1 "" ""))] ; label
9222 ""
9223 {
9224 if (GET_MODE (operands[0]) == SImode && !TARGET_CPU_ZARCH)
9225 emit_jump_insn (gen_doloop_si31 (operands[1], operands[0], operands[0]));
9226 else if (GET_MODE (operands[0]) == SImode && TARGET_CPU_ZARCH)
9227 emit_jump_insn (gen_doloop_si64 (operands[1], operands[0], operands[0]));
9228 else if (GET_MODE (operands[0]) == DImode && TARGET_ZARCH)
9229 emit_jump_insn (gen_doloop_di (operands[1], operands[0], operands[0]));
9230 else
9231 FAIL;
9232
9233 DONE;
9234 })
9235
9236 (define_insn_and_split "doloop_si64"
9237 [(set (pc)
9238 (if_then_else
9239 (ne (match_operand:SI 1 "register_operand" "d,d,d")
9240 (const_int 1))
9241 (label_ref (match_operand 0 "" ""))
9242 (pc)))
9243 (set (match_operand:SI 2 "nonimmediate_operand" "=1,?X,?X")
9244 (plus:SI (match_dup 1) (const_int -1)))
9245 (clobber (match_scratch:SI 3 "=X,&1,&?d"))
9246 (clobber (reg:CC CC_REGNUM))]
9247 "TARGET_CPU_ZARCH"
9248 {
9249 if (which_alternative != 0)
9250 return "#";
9251 else if (get_attr_length (insn) == 4)
9252 return "brct\t%1,%l0";
9253 else
9254 return "ahi\t%1,-1\;jgne\t%l0";
9255 }
9256 "&& reload_completed
9257 && (! REG_P (operands[2])
9258 || ! rtx_equal_p (operands[1], operands[2]))"
9259 [(set (match_dup 3) (match_dup 1))
9260 (parallel [(set (reg:CCAN CC_REGNUM)
9261 (compare:CCAN (plus:SI (match_dup 3) (const_int -1))
9262 (const_int 0)))
9263 (set (match_dup 3) (plus:SI (match_dup 3) (const_int -1)))])
9264 (set (match_dup 2) (match_dup 3))
9265 (set (pc) (if_then_else (ne (reg:CCAN CC_REGNUM) (const_int 0))
9266 (label_ref (match_dup 0))
9267 (pc)))]
9268 ""
9269 [(set_attr "op_type" "RI")
9270 ; Strictly speaking, the z10 properties are valid for brct only, however, it does not
9271 ; hurt us in the (rare) case of ahi.
9272 (set_attr "z10prop" "z10_super_E1")
9273 (set_attr "type" "branch")
9274 (set (attr "length")
9275 (if_then_else (lt (abs (minus (pc) (match_dup 0))) (const_int 60000))
9276 (const_int 4) (const_int 10)))])
9277
9278 (define_insn_and_split "doloop_si31"
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 gcc_unreachable ();
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 (not (match_test "flag_pic"))
9318 (if_then_else (lt (abs (minus (pc) (match_dup 0))) (const_int 60000))
9319 (const_int 4) (const_int 6))
9320 (if_then_else (lt (abs (minus (pc) (match_dup 0))) (const_int 60000))
9321 (const_int 4) (const_int 8))))])
9322
9323 (define_insn "*doloop_si_long"
9324 [(set (pc)
9325 (if_then_else
9326 (ne (match_operand:SI 1 "register_operand" "d")
9327 (const_int 1))
9328 (match_operand 0 "address_operand" "ZR")
9329 (pc)))
9330 (set (match_operand:SI 2 "register_operand" "=1")
9331 (plus:SI (match_dup 1) (const_int -1)))
9332 (clobber (match_scratch:SI 3 "=X"))
9333 (clobber (reg:CC CC_REGNUM))]
9334 "!TARGET_CPU_ZARCH"
9335 {
9336 if (get_attr_op_type (insn) == OP_TYPE_RR)
9337 return "bctr\t%1,%0";
9338 else
9339 return "bct\t%1,%a0";
9340 }
9341 [(set (attr "op_type")
9342 (if_then_else (match_operand 0 "register_operand" "")
9343 (const_string "RR") (const_string "RX")))
9344 (set_attr "type" "branch")
9345 (set_attr "atype" "agen")
9346 (set_attr "z10prop" "z10_c")
9347 (set_attr "z196prop" "z196_cracked")])
9348
9349 (define_insn_and_split "doloop_di"
9350 [(set (pc)
9351 (if_then_else
9352 (ne (match_operand:DI 1 "register_operand" "d,d,d")
9353 (const_int 1))
9354 (label_ref (match_operand 0 "" ""))
9355 (pc)))
9356 (set (match_operand:DI 2 "nonimmediate_operand" "=1,?X,?X")
9357 (plus:DI (match_dup 1) (const_int -1)))
9358 (clobber (match_scratch:DI 3 "=X,&1,&?d"))
9359 (clobber (reg:CC CC_REGNUM))]
9360 "TARGET_ZARCH"
9361 {
9362 if (which_alternative != 0)
9363 return "#";
9364 else if (get_attr_length (insn) == 4)
9365 return "brctg\t%1,%l0";
9366 else
9367 return "aghi\t%1,-1\;jgne\t%l0";
9368 }
9369 "&& reload_completed
9370 && (! REG_P (operands[2])
9371 || ! rtx_equal_p (operands[1], operands[2]))"
9372 [(set (match_dup 3) (match_dup 1))
9373 (parallel [(set (reg:CCAN CC_REGNUM)
9374 (compare:CCAN (plus:DI (match_dup 3) (const_int -1))
9375 (const_int 0)))
9376 (set (match_dup 3) (plus:DI (match_dup 3) (const_int -1)))])
9377 (set (match_dup 2) (match_dup 3))
9378 (set (pc) (if_then_else (ne (reg:CCAN CC_REGNUM) (const_int 0))
9379 (label_ref (match_dup 0))
9380 (pc)))]
9381 ""
9382 [(set_attr "op_type" "RI")
9383 ; Strictly speaking, the z10 properties are valid for brct only, however, it does not
9384 ; hurt us in the (rare) case of ahi.
9385 (set_attr "z10prop" "z10_super_E1")
9386 (set_attr "type" "branch")
9387 (set (attr "length")
9388 (if_then_else (lt (abs (minus (pc) (match_dup 0))) (const_int 60000))
9389 (const_int 4) (const_int 10)))])
9390
9391 ;;
9392 ;;- Unconditional jump instructions.
9393 ;;
9394
9395 ;
9396 ; jump instruction pattern(s).
9397 ;
9398
9399 (define_expand "jump"
9400 [(match_operand 0 "" "")]
9401 ""
9402 "s390_emit_jump (operands[0], NULL_RTX); DONE;")
9403
9404 (define_insn "*jump64"
9405 [(set (pc) (label_ref (match_operand 0 "" "")))]
9406 "TARGET_CPU_ZARCH"
9407 {
9408 if (get_attr_length (insn) == 4)
9409 return "j\t%l0";
9410 else
9411 return "jg\t%l0";
9412 }
9413 [(set_attr "op_type" "RI")
9414 (set_attr "type" "branch")
9415 (set (attr "length")
9416 (if_then_else (lt (abs (minus (pc) (match_dup 0))) (const_int 60000))
9417 (const_int 4) (const_int 6)))])
9418
9419 (define_insn "*jump31"
9420 [(set (pc) (label_ref (match_operand 0 "" "")))]
9421 "!TARGET_CPU_ZARCH"
9422 {
9423 gcc_assert (get_attr_length (insn) == 4);
9424 return "j\t%l0";
9425 }
9426 [(set_attr "op_type" "RI")
9427 (set_attr "type" "branch")
9428 (set (attr "length")
9429 (if_then_else (not (match_test "flag_pic"))
9430 (if_then_else (lt (abs (minus (pc) (match_dup 0))) (const_int 60000))
9431 (const_int 4) (const_int 6))
9432 (if_then_else (lt (abs (minus (pc) (match_dup 0))) (const_int 60000))
9433 (const_int 4) (const_int 8))))])
9434
9435 ;
9436 ; indirect-jump instruction pattern(s).
9437 ;
9438
9439 (define_insn "indirect_jump"
9440 [(set (pc) (match_operand 0 "address_operand" "ZR"))]
9441 ""
9442 {
9443 if (get_attr_op_type (insn) == OP_TYPE_RR)
9444 return "br\t%0";
9445 else
9446 return "b\t%a0";
9447 }
9448 [(set (attr "op_type")
9449 (if_then_else (match_operand 0 "register_operand" "")
9450 (const_string "RR") (const_string "RX")))
9451 (set_attr "type" "branch")
9452 (set_attr "atype" "agen")])
9453
9454 ;
9455 ; casesi instruction pattern(s).
9456 ;
9457
9458 (define_insn "casesi_jump"
9459 [(set (pc) (match_operand 0 "address_operand" "ZR"))
9460 (use (label_ref (match_operand 1 "" "")))]
9461 ""
9462 {
9463 if (get_attr_op_type (insn) == OP_TYPE_RR)
9464 return "br\t%0";
9465 else
9466 return "b\t%a0";
9467 }
9468 [(set (attr "op_type")
9469 (if_then_else (match_operand 0 "register_operand" "")
9470 (const_string "RR") (const_string "RX")))
9471 (set_attr "type" "branch")
9472 (set_attr "atype" "agen")])
9473
9474 (define_expand "casesi"
9475 [(match_operand:SI 0 "general_operand" "")
9476 (match_operand:SI 1 "general_operand" "")
9477 (match_operand:SI 2 "general_operand" "")
9478 (label_ref (match_operand 3 "" ""))
9479 (label_ref (match_operand 4 "" ""))]
9480 ""
9481 {
9482 rtx index = gen_reg_rtx (SImode);
9483 rtx base = gen_reg_rtx (Pmode);
9484 rtx target = gen_reg_rtx (Pmode);
9485
9486 emit_move_insn (index, operands[0]);
9487 emit_insn (gen_subsi3 (index, index, operands[1]));
9488 emit_cmp_and_jump_insns (index, operands[2], GTU, NULL_RTX, SImode, 1,
9489 operands[4]);
9490
9491 if (Pmode != SImode)
9492 index = convert_to_mode (Pmode, index, 1);
9493 if (GET_CODE (index) != REG)
9494 index = copy_to_mode_reg (Pmode, index);
9495
9496 if (TARGET_64BIT)
9497 emit_insn (gen_ashldi3 (index, index, GEN_INT (3)));
9498 else
9499 emit_insn (gen_ashlsi3 (index, index, const2_rtx));
9500
9501 emit_move_insn (base, gen_rtx_LABEL_REF (Pmode, operands[3]));
9502
9503 index = gen_const_mem (Pmode, gen_rtx_PLUS (Pmode, base, index));
9504 emit_move_insn (target, index);
9505
9506 if (flag_pic)
9507 target = gen_rtx_PLUS (Pmode, base, target);
9508 emit_jump_insn (gen_casesi_jump (target, operands[3]));
9509
9510 DONE;
9511 })
9512
9513
9514 ;;
9515 ;;- Jump to subroutine.
9516 ;;
9517 ;;
9518
9519 ;
9520 ; untyped call instruction pattern(s).
9521 ;
9522
9523 ;; Call subroutine returning any type.
9524 (define_expand "untyped_call"
9525 [(parallel [(call (match_operand 0 "" "")
9526 (const_int 0))
9527 (match_operand 1 "" "")
9528 (match_operand 2 "" "")])]
9529 ""
9530 {
9531 int i;
9532
9533 emit_call_insn (gen_call (operands[0], const0_rtx, const0_rtx));
9534
9535 for (i = 0; i < XVECLEN (operands[2], 0); i++)
9536 {
9537 rtx set = XVECEXP (operands[2], 0, i);
9538 emit_move_insn (SET_DEST (set), SET_SRC (set));
9539 }
9540
9541 /* The optimizer does not know that the call sets the function value
9542 registers we stored in the result block. We avoid problems by
9543 claiming that all hard registers are used and clobbered at this
9544 point. */
9545 emit_insn (gen_blockage ());
9546
9547 DONE;
9548 })
9549
9550 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
9551 ;; all of memory. This blocks insns from being moved across this point.
9552
9553 (define_insn "blockage"
9554 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
9555 ""
9556 ""
9557 [(set_attr "type" "none")
9558 (set_attr "length" "0")])
9559
9560 ;
9561 ; sibcall patterns
9562 ;
9563
9564 (define_expand "sibcall"
9565 [(call (match_operand 0 "" "")
9566 (match_operand 1 "" ""))]
9567 ""
9568 {
9569 s390_emit_call (XEXP (operands[0], 0), NULL_RTX, NULL_RTX, NULL_RTX);
9570 DONE;
9571 })
9572
9573 (define_insn "*sibcall_br"
9574 [(call (mem:QI (reg SIBCALL_REGNUM))
9575 (match_operand 0 "const_int_operand" "n"))]
9576 "SIBLING_CALL_P (insn)
9577 && GET_MODE (XEXP (XEXP (PATTERN (insn), 0), 0)) == Pmode"
9578 "br\t%%r1"
9579 [(set_attr "op_type" "RR")
9580 (set_attr "type" "branch")
9581 (set_attr "atype" "agen")])
9582
9583 (define_insn "*sibcall_brc"
9584 [(call (mem:QI (match_operand 0 "bras_sym_operand" "X"))
9585 (match_operand 1 "const_int_operand" "n"))]
9586 "SIBLING_CALL_P (insn) && TARGET_SMALL_EXEC"
9587 "j\t%0"
9588 [(set_attr "op_type" "RI")
9589 (set_attr "type" "branch")])
9590
9591 (define_insn "*sibcall_brcl"
9592 [(call (mem:QI (match_operand 0 "bras_sym_operand" "X"))
9593 (match_operand 1 "const_int_operand" "n"))]
9594 "SIBLING_CALL_P (insn) && TARGET_CPU_ZARCH"
9595 "jg\t%0"
9596 [(set_attr "op_type" "RIL")
9597 (set_attr "type" "branch")])
9598
9599 ;
9600 ; sibcall_value patterns
9601 ;
9602
9603 (define_expand "sibcall_value"
9604 [(set (match_operand 0 "" "")
9605 (call (match_operand 1 "" "")
9606 (match_operand 2 "" "")))]
9607 ""
9608 {
9609 s390_emit_call (XEXP (operands[1], 0), NULL_RTX, operands[0], NULL_RTX);
9610 DONE;
9611 })
9612
9613 (define_insn "*sibcall_value_br"
9614 [(set (match_operand 0 "" "")
9615 (call (mem:QI (reg SIBCALL_REGNUM))
9616 (match_operand 1 "const_int_operand" "n")))]
9617 "SIBLING_CALL_P (insn)
9618 && GET_MODE (XEXP (XEXP (XEXP (PATTERN (insn), 1), 0), 0)) == Pmode"
9619 "br\t%%r1"
9620 [(set_attr "op_type" "RR")
9621 (set_attr "type" "branch")
9622 (set_attr "atype" "agen")])
9623
9624 (define_insn "*sibcall_value_brc"
9625 [(set (match_operand 0 "" "")
9626 (call (mem:QI (match_operand 1 "bras_sym_operand" "X"))
9627 (match_operand 2 "const_int_operand" "n")))]
9628 "SIBLING_CALL_P (insn) && TARGET_SMALL_EXEC"
9629 "j\t%1"
9630 [(set_attr "op_type" "RI")
9631 (set_attr "type" "branch")])
9632
9633 (define_insn "*sibcall_value_brcl"
9634 [(set (match_operand 0 "" "")
9635 (call (mem:QI (match_operand 1 "bras_sym_operand" "X"))
9636 (match_operand 2 "const_int_operand" "n")))]
9637 "SIBLING_CALL_P (insn) && TARGET_CPU_ZARCH"
9638 "jg\t%1"
9639 [(set_attr "op_type" "RIL")
9640 (set_attr "type" "branch")])
9641
9642
9643 ;
9644 ; call instruction pattern(s).
9645 ;
9646
9647 (define_expand "call"
9648 [(call (match_operand 0 "" "")
9649 (match_operand 1 "" ""))
9650 (use (match_operand 2 "" ""))]
9651 ""
9652 {
9653 s390_emit_call (XEXP (operands[0], 0), NULL_RTX, NULL_RTX,
9654 gen_rtx_REG (Pmode, RETURN_REGNUM));
9655 DONE;
9656 })
9657
9658 (define_insn "*bras"
9659 [(call (mem:QI (match_operand 0 "bras_sym_operand" "X"))
9660 (match_operand 1 "const_int_operand" "n"))
9661 (clobber (match_operand 2 "register_operand" "=r"))]
9662 "!SIBLING_CALL_P (insn)
9663 && TARGET_SMALL_EXEC
9664 && GET_MODE (operands[2]) == Pmode"
9665 "bras\t%2,%0"
9666 [(set_attr "op_type" "RI")
9667 (set_attr "type" "jsr")
9668 (set_attr "z196prop" "z196_cracked")])
9669
9670 (define_insn "*brasl"
9671 [(call (mem:QI (match_operand 0 "bras_sym_operand" "X"))
9672 (match_operand 1 "const_int_operand" "n"))
9673 (clobber (match_operand 2 "register_operand" "=r"))]
9674 "!SIBLING_CALL_P (insn)
9675 && TARGET_CPU_ZARCH
9676 && GET_MODE (operands[2]) == Pmode"
9677 "brasl\t%2,%0"
9678 [(set_attr "op_type" "RIL")
9679 (set_attr "type" "jsr")
9680 (set_attr "z196prop" "z196_cracked")])
9681
9682 (define_insn "*basr"
9683 [(call (mem:QI (match_operand 0 "address_operand" "ZR"))
9684 (match_operand 1 "const_int_operand" "n"))
9685 (clobber (match_operand 2 "register_operand" "=r"))]
9686 "!SIBLING_CALL_P (insn) && GET_MODE (operands[2]) == Pmode"
9687 {
9688 if (get_attr_op_type (insn) == OP_TYPE_RR)
9689 return "basr\t%2,%0";
9690 else
9691 return "bas\t%2,%a0";
9692 }
9693 [(set (attr "op_type")
9694 (if_then_else (match_operand 0 "register_operand" "")
9695 (const_string "RR") (const_string "RX")))
9696 (set_attr "type" "jsr")
9697 (set_attr "atype" "agen")
9698 (set_attr "z196prop" "z196_cracked")])
9699
9700 ;
9701 ; call_value instruction pattern(s).
9702 ;
9703
9704 (define_expand "call_value"
9705 [(set (match_operand 0 "" "")
9706 (call (match_operand 1 "" "")
9707 (match_operand 2 "" "")))
9708 (use (match_operand 3 "" ""))]
9709 ""
9710 {
9711 s390_emit_call (XEXP (operands[1], 0), NULL_RTX, operands[0],
9712 gen_rtx_REG (Pmode, RETURN_REGNUM));
9713 DONE;
9714 })
9715
9716 (define_insn "*bras_r"
9717 [(set (match_operand 0 "" "")
9718 (call (mem:QI (match_operand 1 "bras_sym_operand" "X"))
9719 (match_operand:SI 2 "const_int_operand" "n")))
9720 (clobber (match_operand 3 "register_operand" "=r"))]
9721 "!SIBLING_CALL_P (insn)
9722 && TARGET_SMALL_EXEC
9723 && GET_MODE (operands[3]) == Pmode"
9724 "bras\t%3,%1"
9725 [(set_attr "op_type" "RI")
9726 (set_attr "type" "jsr")
9727 (set_attr "z196prop" "z196_cracked")])
9728
9729 (define_insn "*brasl_r"
9730 [(set (match_operand 0 "" "")
9731 (call (mem:QI (match_operand 1 "bras_sym_operand" "X"))
9732 (match_operand 2 "const_int_operand" "n")))
9733 (clobber (match_operand 3 "register_operand" "=r"))]
9734 "!SIBLING_CALL_P (insn)
9735 && TARGET_CPU_ZARCH
9736 && GET_MODE (operands[3]) == Pmode"
9737 "brasl\t%3,%1"
9738 [(set_attr "op_type" "RIL")
9739 (set_attr "type" "jsr")
9740 (set_attr "z196prop" "z196_cracked")])
9741
9742 (define_insn "*basr_r"
9743 [(set (match_operand 0 "" "")
9744 (call (mem:QI (match_operand 1 "address_operand" "ZR"))
9745 (match_operand 2 "const_int_operand" "n")))
9746 (clobber (match_operand 3 "register_operand" "=r"))]
9747 "!SIBLING_CALL_P (insn) && GET_MODE (operands[3]) == Pmode"
9748 {
9749 if (get_attr_op_type (insn) == OP_TYPE_RR)
9750 return "basr\t%3,%1";
9751 else
9752 return "bas\t%3,%a1";
9753 }
9754 [(set (attr "op_type")
9755 (if_then_else (match_operand 1 "register_operand" "")
9756 (const_string "RR") (const_string "RX")))
9757 (set_attr "type" "jsr")
9758 (set_attr "atype" "agen")
9759 (set_attr "z196prop" "z196_cracked")])
9760
9761 ;;
9762 ;;- Thread-local storage support.
9763 ;;
9764
9765 (define_expand "get_thread_pointer<mode>"
9766 [(set (match_operand:P 0 "nonimmediate_operand" "") (reg:P TP_REGNUM))]
9767 ""
9768 "")
9769
9770 (define_expand "set_thread_pointer<mode>"
9771 [(set (reg:P TP_REGNUM) (match_operand:P 0 "nonimmediate_operand" ""))
9772 (set (reg:P TP_REGNUM) (unspec_volatile:P [(reg:P TP_REGNUM)] UNSPECV_SET_TP))]
9773 ""
9774 "")
9775
9776 (define_insn "*set_tp"
9777 [(set (reg TP_REGNUM) (unspec_volatile [(reg TP_REGNUM)] UNSPECV_SET_TP))]
9778 ""
9779 ""
9780 [(set_attr "type" "none")
9781 (set_attr "length" "0")])
9782
9783 (define_insn "*tls_load_64"
9784 [(set (match_operand:DI 0 "register_operand" "=d")
9785 (unspec:DI [(match_operand:DI 1 "memory_operand" "T")
9786 (match_operand:DI 2 "" "")]
9787 UNSPEC_TLS_LOAD))]
9788 "TARGET_64BIT"
9789 "lg\t%0,%1%J2"
9790 [(set_attr "op_type" "RXE")
9791 (set_attr "z10prop" "z10_fwd_A3")])
9792
9793 (define_insn "*tls_load_31"
9794 [(set (match_operand:SI 0 "register_operand" "=d,d")
9795 (unspec:SI [(match_operand:SI 1 "memory_operand" "R,T")
9796 (match_operand:SI 2 "" "")]
9797 UNSPEC_TLS_LOAD))]
9798 "!TARGET_64BIT"
9799 "@
9800 l\t%0,%1%J2
9801 ly\t%0,%1%J2"
9802 [(set_attr "op_type" "RX,RXY")
9803 (set_attr "type" "load")
9804 (set_attr "cpu_facility" "*,longdisp")
9805 (set_attr "z10prop" "z10_fwd_A3,z10_fwd_A3")])
9806
9807 (define_insn "*bras_tls"
9808 [(set (match_operand 0 "" "")
9809 (call (mem:QI (match_operand 1 "bras_sym_operand" "X"))
9810 (match_operand 2 "const_int_operand" "n")))
9811 (clobber (match_operand 3 "register_operand" "=r"))
9812 (use (match_operand 4 "" ""))]
9813 "!SIBLING_CALL_P (insn)
9814 && TARGET_SMALL_EXEC
9815 && GET_MODE (operands[3]) == Pmode"
9816 "bras\t%3,%1%J4"
9817 [(set_attr "op_type" "RI")
9818 (set_attr "type" "jsr")
9819 (set_attr "z196prop" "z196_cracked")])
9820
9821 (define_insn "*brasl_tls"
9822 [(set (match_operand 0 "" "")
9823 (call (mem:QI (match_operand 1 "bras_sym_operand" "X"))
9824 (match_operand 2 "const_int_operand" "n")))
9825 (clobber (match_operand 3 "register_operand" "=r"))
9826 (use (match_operand 4 "" ""))]
9827 "!SIBLING_CALL_P (insn)
9828 && TARGET_CPU_ZARCH
9829 && GET_MODE (operands[3]) == Pmode"
9830 "brasl\t%3,%1%J4"
9831 [(set_attr "op_type" "RIL")
9832 (set_attr "type" "jsr")
9833 (set_attr "z196prop" "z196_cracked")])
9834
9835 (define_insn "*basr_tls"
9836 [(set (match_operand 0 "" "")
9837 (call (mem:QI (match_operand 1 "address_operand" "ZR"))
9838 (match_operand 2 "const_int_operand" "n")))
9839 (clobber (match_operand 3 "register_operand" "=r"))
9840 (use (match_operand 4 "" ""))]
9841 "!SIBLING_CALL_P (insn) && GET_MODE (operands[3]) == Pmode"
9842 {
9843 if (get_attr_op_type (insn) == OP_TYPE_RR)
9844 return "basr\t%3,%1%J4";
9845 else
9846 return "bas\t%3,%a1%J4";
9847 }
9848 [(set (attr "op_type")
9849 (if_then_else (match_operand 1 "register_operand" "")
9850 (const_string "RR") (const_string "RX")))
9851 (set_attr "type" "jsr")
9852 (set_attr "atype" "agen")
9853 (set_attr "z196prop" "z196_cracked")])
9854
9855 ;;
9856 ;;- Atomic operations
9857 ;;
9858
9859 ;
9860 ; memory barrier patterns.
9861 ;
9862
9863 (define_expand "mem_signal_fence"
9864 [(match_operand:SI 0 "const_int_operand")] ;; model
9865 ""
9866 {
9867 /* The s390 memory model is strong enough not to require any
9868 barrier in order to synchronize a thread with itself. */
9869 DONE;
9870 })
9871
9872 (define_expand "mem_thread_fence"
9873 [(match_operand:SI 0 "const_int_operand")] ;; model
9874 ""
9875 {
9876 /* Unless this is a SEQ_CST fence, the s390 memory model is strong
9877 enough not to require barriers of any kind. */
9878 if (is_mm_seq_cst (memmodel_from_int (INTVAL (operands[0]))))
9879 {
9880 rtx mem = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
9881 MEM_VOLATILE_P (mem) = 1;
9882 emit_insn (gen_mem_thread_fence_1 (mem));
9883 }
9884 DONE;
9885 })
9886
9887 ; Although bcr is superscalar on Z10, this variant will never
9888 ; become part of an execution group.
9889 ; With z196 we can make use of the fast-BCR-serialization facility.
9890 ; This allows for a slightly faster sync which is sufficient for our
9891 ; purposes.
9892 (define_insn "mem_thread_fence_1"
9893 [(set (match_operand:BLK 0 "" "")
9894 (unspec:BLK [(match_dup 0)] UNSPEC_MB))]
9895 ""
9896 {
9897 if (TARGET_Z196)
9898 return "bcr\t14,0";
9899 else
9900 return "bcr\t15,0";
9901 }
9902 [(set_attr "op_type" "RR")
9903 (set_attr "mnemonic" "bcr_flush")
9904 (set_attr "z196prop" "z196_alone")])
9905
9906 ;
9907 ; atomic load/store operations
9908 ;
9909
9910 ; Atomic loads need not examine the memory model at all.
9911 (define_expand "atomic_load<mode>"
9912 [(match_operand:DINT 0 "register_operand") ;; output
9913 (match_operand:DINT 1 "memory_operand") ;; memory
9914 (match_operand:SI 2 "const_int_operand")] ;; model
9915 ""
9916 {
9917 if (MEM_ALIGN (operands[1]) < GET_MODE_BITSIZE (GET_MODE (operands[1])))
9918 FAIL;
9919
9920 if (<MODE>mode == TImode)
9921 emit_insn (gen_atomic_loadti_1 (operands[0], operands[1]));
9922 else if (<MODE>mode == DImode && !TARGET_ZARCH)
9923 emit_insn (gen_atomic_loaddi_1 (operands[0], operands[1]));
9924 else
9925 emit_move_insn (operands[0], operands[1]);
9926 DONE;
9927 })
9928
9929 ; Different from movdi_31 in that we want no splitters.
9930 (define_insn "atomic_loaddi_1"
9931 [(set (match_operand:DI 0 "register_operand" "=d,d,!*f,!*f")
9932 (unspec:DI [(match_operand:DI 1 "memory_operand" "Q,S,R,T")]
9933 UNSPEC_MOVA))]
9934 "!TARGET_ZARCH"
9935 "@
9936 lm\t%0,%M0,%S1
9937 lmy\t%0,%M0,%S1
9938 ld\t%0,%1
9939 ldy\t%0,%1"
9940 [(set_attr "op_type" "RS,RSY,RS,RSY")
9941 (set_attr "cpu_facility" "*,longdisp,*,longdisp")
9942 (set_attr "type" "lm,lm,floaddf,floaddf")])
9943
9944 (define_insn "atomic_loadti_1"
9945 [(set (match_operand:TI 0 "register_operand" "=r")
9946 (unspec:TI [(match_operand:TI 1 "memory_operand" "T")]
9947 UNSPEC_MOVA))]
9948 "TARGET_ZARCH"
9949 "lpq\t%0,%1"
9950 [(set_attr "op_type" "RXY")
9951 (set_attr "type" "other")])
9952
9953 ; Atomic stores must(?) enforce sequential consistency.
9954 (define_expand "atomic_store<mode>"
9955 [(match_operand:DINT 0 "memory_operand") ;; memory
9956 (match_operand:DINT 1 "register_operand") ;; input
9957 (match_operand:SI 2 "const_int_operand")] ;; model
9958 ""
9959 {
9960 enum memmodel model = memmodel_from_int (INTVAL (operands[2]));
9961
9962 if (MEM_ALIGN (operands[0]) < GET_MODE_BITSIZE (GET_MODE (operands[0])))
9963 FAIL;
9964
9965 if (<MODE>mode == TImode)
9966 emit_insn (gen_atomic_storeti_1 (operands[0], operands[1]));
9967 else if (<MODE>mode == DImode && !TARGET_ZARCH)
9968 emit_insn (gen_atomic_storedi_1 (operands[0], operands[1]));
9969 else
9970 emit_move_insn (operands[0], operands[1]);
9971 if (is_mm_seq_cst (model))
9972 emit_insn (gen_mem_thread_fence (operands[2]));
9973 DONE;
9974 })
9975
9976 ; Different from movdi_31 in that we want no splitters.
9977 (define_insn "atomic_storedi_1"
9978 [(set (match_operand:DI 0 "memory_operand" "=Q,S,R,T")
9979 (unspec:DI [(match_operand:DI 1 "register_operand" "d,d,!*f,!*f")]
9980 UNSPEC_MOVA))]
9981 "!TARGET_ZARCH"
9982 "@
9983 stm\t%1,%N1,%S0
9984 stmy\t%1,%N1,%S0
9985 std %1,%0
9986 stdy %1,%0"
9987 [(set_attr "op_type" "RS,RSY,RS,RSY")
9988 (set_attr "cpu_facility" "*,longdisp,*,longdisp")
9989 (set_attr "type" "stm,stm,fstoredf,fstoredf")])
9990
9991 (define_insn "atomic_storeti_1"
9992 [(set (match_operand:TI 0 "memory_operand" "=T")
9993 (unspec:TI [(match_operand:TI 1 "register_operand" "r")]
9994 UNSPEC_MOVA))]
9995 "TARGET_ZARCH"
9996 "stpq\t%1,%0"
9997 [(set_attr "op_type" "RXY")
9998 (set_attr "type" "other")])
9999
10000 ;
10001 ; compare and swap patterns.
10002 ;
10003
10004 (define_expand "atomic_compare_and_swap<mode>"
10005 [(match_operand:SI 0 "register_operand") ;; bool success output
10006 (match_operand:DGPR 1 "nonimmediate_operand");; oldval output
10007 (match_operand:DGPR 2 "memory_operand") ;; memory
10008 (match_operand:DGPR 3 "register_operand") ;; expected intput
10009 (match_operand:DGPR 4 "register_operand") ;; newval intput
10010 (match_operand:SI 5 "const_int_operand") ;; is_weak
10011 (match_operand:SI 6 "const_int_operand") ;; success model
10012 (match_operand:SI 7 "const_int_operand")] ;; failure model
10013 ""
10014 {
10015 rtx cc, cmp, output = operands[1];
10016
10017 if (!register_operand (output, <MODE>mode))
10018 output = gen_reg_rtx (<MODE>mode);
10019
10020 if (MEM_ALIGN (operands[2]) < GET_MODE_BITSIZE (GET_MODE (operands[2])))
10021 FAIL;
10022
10023 emit_insn (gen_atomic_compare_and_swap<mode>_internal
10024 (output, operands[2], operands[3], operands[4]));
10025
10026 /* We deliberately accept non-register operands in the predicate
10027 to ensure the write back to the output operand happens *before*
10028 the store-flags code below. This makes it easier for combine
10029 to merge the store-flags code with a potential test-and-branch
10030 pattern following (immediately!) afterwards. */
10031 if (output != operands[1])
10032 emit_move_insn (operands[1], output);
10033
10034 cc = gen_rtx_REG (CCZ1mode, CC_REGNUM);
10035 cmp = gen_rtx_EQ (SImode, cc, const0_rtx);
10036 emit_insn (gen_cstorecc4 (operands[0], cmp, cc, const0_rtx));
10037 DONE;
10038 })
10039
10040 (define_expand "atomic_compare_and_swap<mode>"
10041 [(match_operand:SI 0 "register_operand") ;; bool success output
10042 (match_operand:HQI 1 "nonimmediate_operand") ;; oldval output
10043 (match_operand:HQI 2 "memory_operand") ;; memory
10044 (match_operand:HQI 3 "general_operand") ;; expected intput
10045 (match_operand:HQI 4 "general_operand") ;; newval intput
10046 (match_operand:SI 5 "const_int_operand") ;; is_weak
10047 (match_operand:SI 6 "const_int_operand") ;; success model
10048 (match_operand:SI 7 "const_int_operand")] ;; failure model
10049 ""
10050 {
10051 s390_expand_cs_hqi (<MODE>mode, operands[0], operands[1], operands[2],
10052 operands[3], operands[4], INTVAL (operands[5]));
10053 DONE;
10054 })
10055
10056 (define_expand "atomic_compare_and_swap<mode>_internal"
10057 [(parallel
10058 [(set (match_operand:DGPR 0 "register_operand")
10059 (match_operand:DGPR 1 "memory_operand"))
10060 (set (match_dup 1)
10061 (unspec_volatile:DGPR
10062 [(match_dup 1)
10063 (match_operand:DGPR 2 "register_operand")
10064 (match_operand:DGPR 3 "register_operand")]
10065 UNSPECV_CAS))
10066 (set (reg:CCZ1 CC_REGNUM)
10067 (compare:CCZ1 (match_dup 1) (match_dup 2)))])]
10068 "")
10069
10070 ; cdsg, csg
10071 (define_insn "*atomic_compare_and_swap<mode>_1"
10072 [(set (match_operand:TDI 0 "register_operand" "=r")
10073 (match_operand:TDI 1 "memory_operand" "+S"))
10074 (set (match_dup 1)
10075 (unspec_volatile:TDI
10076 [(match_dup 1)
10077 (match_operand:TDI 2 "register_operand" "0")
10078 (match_operand:TDI 3 "register_operand" "r")]
10079 UNSPECV_CAS))
10080 (set (reg:CCZ1 CC_REGNUM)
10081 (compare:CCZ1 (match_dup 1) (match_dup 2)))]
10082 "TARGET_ZARCH"
10083 "c<td>sg\t%0,%3,%S1"
10084 [(set_attr "op_type" "RSY")
10085 (set_attr "type" "sem")])
10086
10087 ; cds, cdsy
10088 (define_insn "*atomic_compare_and_swapdi_2"
10089 [(set (match_operand:DI 0 "register_operand" "=r,r")
10090 (match_operand:DI 1 "memory_operand" "+Q,S"))
10091 (set (match_dup 1)
10092 (unspec_volatile:DI
10093 [(match_dup 1)
10094 (match_operand:DI 2 "register_operand" "0,0")
10095 (match_operand:DI 3 "register_operand" "r,r")]
10096 UNSPECV_CAS))
10097 (set (reg:CCZ1 CC_REGNUM)
10098 (compare:CCZ1 (match_dup 1) (match_dup 2)))]
10099 "!TARGET_ZARCH"
10100 "@
10101 cds\t%0,%3,%S1
10102 cdsy\t%0,%3,%S1"
10103 [(set_attr "op_type" "RS,RSY")
10104 (set_attr "cpu_facility" "*,longdisp")
10105 (set_attr "type" "sem")])
10106
10107 ; cs, csy
10108 (define_insn "*atomic_compare_and_swapsi_3"
10109 [(set (match_operand:SI 0 "register_operand" "=r,r")
10110 (match_operand:SI 1 "memory_operand" "+Q,S"))
10111 (set (match_dup 1)
10112 (unspec_volatile:SI
10113 [(match_dup 1)
10114 (match_operand:SI 2 "register_operand" "0,0")
10115 (match_operand:SI 3 "register_operand" "r,r")]
10116 UNSPECV_CAS))
10117 (set (reg:CCZ1 CC_REGNUM)
10118 (compare:CCZ1 (match_dup 1) (match_dup 2)))]
10119 ""
10120 "@
10121 cs\t%0,%3,%S1
10122 csy\t%0,%3,%S1"
10123 [(set_attr "op_type" "RS,RSY")
10124 (set_attr "cpu_facility" "*,longdisp")
10125 (set_attr "type" "sem")])
10126
10127 ;
10128 ; Other atomic instruction patterns.
10129 ;
10130
10131 ; z196 load and add, xor, or and and instructions
10132
10133 (define_expand "atomic_fetch_<atomic><mode>"
10134 [(match_operand:GPR 0 "register_operand") ;; val out
10135 (ATOMIC_Z196:GPR
10136 (match_operand:GPR 1 "memory_operand") ;; memory
10137 (match_operand:GPR 2 "register_operand")) ;; val in
10138 (match_operand:SI 3 "const_int_operand")] ;; model
10139 "TARGET_Z196"
10140 {
10141 if (MEM_ALIGN (operands[1]) < GET_MODE_BITSIZE (GET_MODE (operands[1])))
10142 FAIL;
10143
10144 emit_insn (gen_atomic_fetch_<atomic><mode>_iaf
10145 (operands[0], operands[1], operands[2]));
10146 DONE;
10147 })
10148
10149 ; lan, lang, lao, laog, lax, laxg, laa, laag
10150 (define_insn "atomic_fetch_<atomic><mode>_iaf"
10151 [(set (match_operand:GPR 0 "register_operand" "=d")
10152 (match_operand:GPR 1 "memory_operand" "+S"))
10153 (set (match_dup 1)
10154 (unspec_volatile:GPR
10155 [(ATOMIC_Z196:GPR (match_dup 1)
10156 (match_operand:GPR 2 "general_operand" "d"))]
10157 UNSPECV_ATOMIC_OP))
10158 (clobber (reg:CC CC_REGNUM))]
10159 "TARGET_Z196"
10160 "la<noxa><g>\t%0,%2,%1"
10161 [(set_attr "op_type" "RSY")
10162 (set_attr "type" "sem")])
10163
10164 ;; For SImode and larger, the optabs.c code will do just fine in
10165 ;; expanding a compare-and-swap loop. For QI/HImode, we can do
10166 ;; better by expanding our own loop.
10167
10168 (define_expand "atomic_<atomic><mode>"
10169 [(ATOMIC:HQI
10170 (match_operand:HQI 0 "memory_operand") ;; memory
10171 (match_operand:HQI 1 "general_operand")) ;; val in
10172 (match_operand:SI 2 "const_int_operand")] ;; model
10173 ""
10174 {
10175 s390_expand_atomic (<MODE>mode, <CODE>, NULL_RTX, operands[0],
10176 operands[1], false);
10177 DONE;
10178 })
10179
10180 (define_expand "atomic_fetch_<atomic><mode>"
10181 [(match_operand:HQI 0 "register_operand") ;; val out
10182 (ATOMIC:HQI
10183 (match_operand:HQI 1 "memory_operand") ;; memory
10184 (match_operand:HQI 2 "general_operand")) ;; val in
10185 (match_operand:SI 3 "const_int_operand")] ;; model
10186 ""
10187 {
10188 s390_expand_atomic (<MODE>mode, <CODE>, operands[0], operands[1],
10189 operands[2], false);
10190 DONE;
10191 })
10192
10193 (define_expand "atomic_<atomic>_fetch<mode>"
10194 [(match_operand:HQI 0 "register_operand") ;; val out
10195 (ATOMIC:HQI
10196 (match_operand:HQI 1 "memory_operand") ;; memory
10197 (match_operand:HQI 2 "general_operand")) ;; val in
10198 (match_operand:SI 3 "const_int_operand")] ;; model
10199 ""
10200 {
10201 s390_expand_atomic (<MODE>mode, <CODE>, operands[0], operands[1],
10202 operands[2], true);
10203 DONE;
10204 })
10205
10206 (define_expand "atomic_exchange<mode>"
10207 [(match_operand:HQI 0 "register_operand") ;; val out
10208 (match_operand:HQI 1 "memory_operand") ;; memory
10209 (match_operand:HQI 2 "general_operand") ;; val in
10210 (match_operand:SI 3 "const_int_operand")] ;; model
10211 ""
10212 {
10213 s390_expand_atomic (<MODE>mode, SET, operands[0], operands[1],
10214 operands[2], false);
10215 DONE;
10216 })
10217
10218 ;;
10219 ;;- Miscellaneous instructions.
10220 ;;
10221
10222 ;
10223 ; allocate stack instruction pattern(s).
10224 ;
10225
10226 (define_expand "allocate_stack"
10227 [(match_operand 0 "general_operand" "")
10228 (match_operand 1 "general_operand" "")]
10229 "TARGET_BACKCHAIN"
10230 {
10231 rtx temp = gen_reg_rtx (Pmode);
10232
10233 emit_move_insn (temp, s390_back_chain_rtx ());
10234 anti_adjust_stack (operands[1]);
10235 emit_move_insn (s390_back_chain_rtx (), temp);
10236
10237 emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
10238 DONE;
10239 })
10240
10241
10242 ;
10243 ; setjmp instruction pattern.
10244 ;
10245
10246 (define_expand "builtin_setjmp_receiver"
10247 [(match_operand 0 "" "")]
10248 "flag_pic"
10249 {
10250 emit_insn (s390_load_got ());
10251 emit_use (pic_offset_table_rtx);
10252 DONE;
10253 })
10254
10255 ;; These patterns say how to save and restore the stack pointer. We need not
10256 ;; save the stack pointer at function level since we are careful to
10257 ;; preserve the backchain. At block level, we have to restore the backchain
10258 ;; when we restore the stack pointer.
10259 ;;
10260 ;; For nonlocal gotos, we must save both the stack pointer and its
10261 ;; backchain and restore both. Note that in the nonlocal case, the
10262 ;; save area is a memory location.
10263
10264 (define_expand "save_stack_function"
10265 [(match_operand 0 "general_operand" "")
10266 (match_operand 1 "general_operand" "")]
10267 ""
10268 "DONE;")
10269
10270 (define_expand "restore_stack_function"
10271 [(match_operand 0 "general_operand" "")
10272 (match_operand 1 "general_operand" "")]
10273 ""
10274 "DONE;")
10275
10276 (define_expand "restore_stack_block"
10277 [(match_operand 0 "register_operand" "")
10278 (match_operand 1 "register_operand" "")]
10279 "TARGET_BACKCHAIN"
10280 {
10281 rtx temp = gen_reg_rtx (Pmode);
10282
10283 emit_move_insn (temp, s390_back_chain_rtx ());
10284 emit_move_insn (operands[0], operands[1]);
10285 emit_move_insn (s390_back_chain_rtx (), temp);
10286
10287 DONE;
10288 })
10289
10290 (define_expand "save_stack_nonlocal"
10291 [(match_operand 0 "memory_operand" "")
10292 (match_operand 1 "register_operand" "")]
10293 ""
10294 {
10295 rtx base = gen_rtx_REG (Pmode, BASE_REGNUM);
10296
10297 /* Copy the backchain to the first word, sp to the second and the
10298 literal pool base to the third. */
10299
10300 rtx save_bc = adjust_address (operands[0], Pmode, 0);
10301 rtx save_sp = adjust_address (operands[0], Pmode, GET_MODE_SIZE (Pmode));
10302 rtx save_bp = adjust_address (operands[0], Pmode, 2 * GET_MODE_SIZE (Pmode));
10303
10304 if (TARGET_BACKCHAIN)
10305 emit_move_insn (save_bc, force_reg (Pmode, s390_back_chain_rtx ()));
10306
10307 emit_move_insn (save_sp, operands[1]);
10308 emit_move_insn (save_bp, base);
10309
10310 DONE;
10311 })
10312
10313 (define_expand "restore_stack_nonlocal"
10314 [(match_operand 0 "register_operand" "")
10315 (match_operand 1 "memory_operand" "")]
10316 ""
10317 {
10318 rtx base = gen_rtx_REG (Pmode, BASE_REGNUM);
10319 rtx temp = NULL_RTX;
10320
10321 /* Restore the backchain from the first word, sp from the second and the
10322 literal pool base from the third. */
10323
10324 rtx save_bc = adjust_address (operands[1], Pmode, 0);
10325 rtx save_sp = adjust_address (operands[1], Pmode, GET_MODE_SIZE (Pmode));
10326 rtx save_bp = adjust_address (operands[1], Pmode, 2 * GET_MODE_SIZE (Pmode));
10327
10328 if (TARGET_BACKCHAIN)
10329 temp = force_reg (Pmode, save_bc);
10330
10331 emit_move_insn (base, save_bp);
10332 emit_move_insn (operands[0], save_sp);
10333
10334 if (temp)
10335 emit_move_insn (s390_back_chain_rtx (), temp);
10336
10337 emit_use (base);
10338 DONE;
10339 })
10340
10341 (define_expand "exception_receiver"
10342 [(const_int 0)]
10343 ""
10344 {
10345 s390_set_has_landing_pad_p (true);
10346 DONE;
10347 })
10348
10349 ;
10350 ; nop instruction pattern(s).
10351 ;
10352
10353 (define_insn "nop"
10354 [(const_int 0)]
10355 ""
10356 "lr\t0,0"
10357 [(set_attr "op_type" "RR")
10358 (set_attr "z10prop" "z10_fr_E1")])
10359
10360 (define_insn "nop1"
10361 [(const_int 1)]
10362 ""
10363 "lr\t1,1"
10364 [(set_attr "op_type" "RR")])
10365
10366 ;;- Undeletable nops (used for hotpatching)
10367
10368 (define_insn "nop_2_byte"
10369 [(unspec_volatile [(const_int 0)] UNSPECV_NOP_2_BYTE)]
10370 ""
10371 "nopr\t%%r7"
10372 [(set_attr "op_type" "RR")])
10373
10374 (define_insn "nop_4_byte"
10375 [(unspec_volatile [(const_int 0)] UNSPECV_NOP_4_BYTE)]
10376 ""
10377 "nop\t0"
10378 [(set_attr "op_type" "RX")])
10379
10380 (define_insn "nop_6_byte"
10381 [(unspec_volatile [(const_int 0)] UNSPECV_NOP_6_BYTE)]
10382 "TARGET_CPU_ZARCH"
10383 "brcl\t0, 0"
10384 [(set_attr "op_type" "RIL")])
10385
10386
10387 ;
10388 ; Special literal pool access instruction pattern(s).
10389 ;
10390
10391 (define_insn "*pool_entry"
10392 [(unspec_volatile [(match_operand 0 "consttable_operand" "X")]
10393 UNSPECV_POOL_ENTRY)]
10394 ""
10395 {
10396 machine_mode mode = GET_MODE (PATTERN (insn));
10397 unsigned int align = GET_MODE_BITSIZE (mode);
10398 s390_output_pool_entry (operands[0], mode, align);
10399 return "";
10400 }
10401 [(set (attr "length")
10402 (symbol_ref "GET_MODE_SIZE (GET_MODE (PATTERN (insn)))"))])
10403
10404 (define_insn "pool_align"
10405 [(unspec_volatile [(match_operand 0 "const_int_operand" "n")]
10406 UNSPECV_POOL_ALIGN)]
10407 ""
10408 ".align\t%0"
10409 [(set (attr "length") (symbol_ref "INTVAL (operands[0])"))])
10410
10411 (define_insn "pool_section_start"
10412 [(unspec_volatile [(const_int 1)] UNSPECV_POOL_SECTION)]
10413 ""
10414 {
10415 switch_to_section (targetm.asm_out.function_rodata_section
10416 (current_function_decl));
10417 return "";
10418 }
10419 [(set_attr "length" "0")])
10420
10421 (define_insn "pool_section_end"
10422 [(unspec_volatile [(const_int 0)] UNSPECV_POOL_SECTION)]
10423 ""
10424 {
10425 switch_to_section (current_function_section ());
10426 return "";
10427 }
10428 [(set_attr "length" "0")])
10429
10430 (define_insn "main_base_31_small"
10431 [(set (match_operand 0 "register_operand" "=a")
10432 (unspec [(label_ref (match_operand 1 "" ""))] UNSPEC_MAIN_BASE))]
10433 "!TARGET_CPU_ZARCH && GET_MODE (operands[0]) == Pmode"
10434 "basr\t%0,0"
10435 [(set_attr "op_type" "RR")
10436 (set_attr "type" "la")
10437 (set_attr "z196prop" "z196_cracked")])
10438
10439 (define_insn "main_base_31_large"
10440 [(set (match_operand 0 "register_operand" "=a")
10441 (unspec [(label_ref (match_operand 1 "" ""))] UNSPEC_MAIN_BASE))
10442 (set (pc) (label_ref (match_operand 2 "" "")))]
10443 "!TARGET_CPU_ZARCH && GET_MODE (operands[0]) == Pmode"
10444 "bras\t%0,%2"
10445 [(set_attr "op_type" "RI")
10446 (set_attr "z196prop" "z196_cracked")])
10447
10448 (define_insn "main_base_64"
10449 [(set (match_operand 0 "register_operand" "=a")
10450 (unspec [(label_ref (match_operand 1 "" ""))] UNSPEC_MAIN_BASE))]
10451 "TARGET_CPU_ZARCH && GET_MODE (operands[0]) == Pmode"
10452 "larl\t%0,%1"
10453 [(set_attr "op_type" "RIL")
10454 (set_attr "type" "larl")
10455 (set_attr "z10prop" "z10_fwd_A1")])
10456
10457 (define_insn "main_pool"
10458 [(set (match_operand 0 "register_operand" "=a")
10459 (unspec_volatile [(const_int 0)] UNSPECV_MAIN_POOL))]
10460 "GET_MODE (operands[0]) == Pmode"
10461 {
10462 gcc_unreachable ();
10463 }
10464 [(set (attr "type")
10465 (if_then_else (match_test "TARGET_CPU_ZARCH")
10466 (const_string "larl") (const_string "la")))])
10467
10468 (define_insn "reload_base_31"
10469 [(set (match_operand 0 "register_operand" "=a")
10470 (unspec [(label_ref (match_operand 1 "" ""))] UNSPEC_RELOAD_BASE))]
10471 "!TARGET_CPU_ZARCH && GET_MODE (operands[0]) == Pmode"
10472 "basr\t%0,0\;la\t%0,%1-.(%0)"
10473 [(set_attr "length" "6")
10474 (set_attr "type" "la")
10475 (set_attr "z196prop" "z196_cracked")])
10476
10477 (define_insn "reload_base_64"
10478 [(set (match_operand 0 "register_operand" "=a")
10479 (unspec [(label_ref (match_operand 1 "" ""))] UNSPEC_RELOAD_BASE))]
10480 "TARGET_CPU_ZARCH && GET_MODE (operands[0]) == Pmode"
10481 "larl\t%0,%1"
10482 [(set_attr "op_type" "RIL")
10483 (set_attr "type" "larl")
10484 (set_attr "z10prop" "z10_fwd_A1")])
10485
10486 (define_insn "pool"
10487 [(unspec_volatile [(match_operand 0 "const_int_operand" "n")] UNSPECV_POOL)]
10488 ""
10489 {
10490 gcc_unreachable ();
10491 }
10492 [(set (attr "length") (symbol_ref "INTVAL (operands[0])"))])
10493
10494 ;;
10495 ;; Insns related to generating the function prologue and epilogue.
10496 ;;
10497
10498
10499 (define_expand "prologue"
10500 [(use (const_int 0))]
10501 ""
10502 "s390_emit_prologue (); DONE;")
10503
10504 (define_expand "epilogue"
10505 [(use (const_int 1))]
10506 ""
10507 "s390_emit_epilogue (false); DONE;")
10508
10509 (define_expand "sibcall_epilogue"
10510 [(use (const_int 0))]
10511 ""
10512 "s390_emit_epilogue (true); DONE;")
10513
10514 ;; A direct return instruction, without using an epilogue.
10515 (define_insn "<code>"
10516 [(ANY_RETURN)]
10517 "s390_can_use_<code>_insn ()"
10518 "br\t%%r14"
10519 [(set_attr "op_type" "RR")
10520 (set_attr "type" "jsr")
10521 (set_attr "atype" "agen")])
10522
10523 (define_insn "*return"
10524 [(return)
10525 (use (match_operand 0 "register_operand" "a"))]
10526 "GET_MODE (operands[0]) == Pmode"
10527 "br\t%0"
10528 [(set_attr "op_type" "RR")
10529 (set_attr "type" "jsr")
10530 (set_attr "atype" "agen")])
10531
10532
10533 ;; Instruction definition to extend a 31-bit pointer into a 64-bit
10534 ;; pointer. This is used for compatibility.
10535
10536 (define_expand "ptr_extend"
10537 [(set (match_operand:DI 0 "register_operand" "=r")
10538 (match_operand:SI 1 "register_operand" "r"))]
10539 "TARGET_64BIT"
10540 {
10541 emit_insn (gen_anddi3 (operands[0],
10542 gen_lowpart (DImode, operands[1]),
10543 GEN_INT (0x7fffffff)));
10544 DONE;
10545 })
10546
10547 ;; Instruction definition to expand eh_return macro to support
10548 ;; swapping in special linkage return addresses.
10549
10550 (define_expand "eh_return"
10551 [(use (match_operand 0 "register_operand" ""))]
10552 "TARGET_TPF"
10553 {
10554 s390_emit_tpf_eh_return (operands[0]);
10555 DONE;
10556 })
10557
10558 ;
10559 ; Stack Protector Patterns
10560 ;
10561
10562 (define_expand "stack_protect_set"
10563 [(set (match_operand 0 "memory_operand" "")
10564 (match_operand 1 "memory_operand" ""))]
10565 ""
10566 {
10567 #ifdef TARGET_THREAD_SSP_OFFSET
10568 operands[1]
10569 = gen_rtx_MEM (Pmode, gen_rtx_PLUS (Pmode, s390_get_thread_pointer (),
10570 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
10571 #endif
10572 if (TARGET_64BIT)
10573 emit_insn (gen_stack_protect_setdi (operands[0], operands[1]));
10574 else
10575 emit_insn (gen_stack_protect_setsi (operands[0], operands[1]));
10576
10577 DONE;
10578 })
10579
10580 (define_insn "stack_protect_set<mode>"
10581 [(set (match_operand:DSI 0 "memory_operand" "=Q")
10582 (unspec:DSI [(match_operand:DSI 1 "memory_operand" "Q")] UNSPEC_SP_SET))]
10583 ""
10584 "mvc\t%O0(%G0,%R0),%S1"
10585 [(set_attr "op_type" "SS")])
10586
10587 (define_expand "stack_protect_test"
10588 [(set (reg:CC CC_REGNUM)
10589 (compare (match_operand 0 "memory_operand" "")
10590 (match_operand 1 "memory_operand" "")))
10591 (match_operand 2 "" "")]
10592 ""
10593 {
10594 rtx cc_reg, test;
10595 #ifdef TARGET_THREAD_SSP_OFFSET
10596 operands[1]
10597 = gen_rtx_MEM (Pmode, gen_rtx_PLUS (Pmode, s390_get_thread_pointer (),
10598 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
10599 #endif
10600 if (TARGET_64BIT)
10601 emit_insn (gen_stack_protect_testdi (operands[0], operands[1]));
10602 else
10603 emit_insn (gen_stack_protect_testsi (operands[0], operands[1]));
10604
10605 cc_reg = gen_rtx_REG (CCZmode, CC_REGNUM);
10606 test = gen_rtx_EQ (VOIDmode, cc_reg, const0_rtx);
10607 emit_jump_insn (gen_cbranchcc4 (test, cc_reg, const0_rtx, operands[2]));
10608 DONE;
10609 })
10610
10611 (define_insn "stack_protect_test<mode>"
10612 [(set (reg:CCZ CC_REGNUM)
10613 (unspec:CCZ [(match_operand:DSI 0 "memory_operand" "Q")
10614 (match_operand:DSI 1 "memory_operand" "Q")] UNSPEC_SP_TEST))]
10615 ""
10616 "clc\t%O0(%G0,%R0),%S1"
10617 [(set_attr "op_type" "SS")])
10618
10619 ; This is used in s390_emit_prologue in order to prevent insns
10620 ; adjusting the stack pointer to be moved over insns writing stack
10621 ; slots using a copy of the stack pointer in a different register.
10622 (define_insn "stack_tie"
10623 [(set (match_operand:BLK 0 "memory_operand" "+m")
10624 (unspec:BLK [(match_dup 0)] UNSPEC_TIE))]
10625 ""
10626 ""
10627 [(set_attr "length" "0")])
10628
10629
10630 (define_insn "stack_restore_from_fpr"
10631 [(set (reg:DI STACK_REGNUM)
10632 (match_operand:DI 0 "register_operand" "f"))
10633 (clobber (mem:BLK (scratch)))]
10634 "TARGET_Z10"
10635 "lgdr\t%%r15,%0"
10636 [(set_attr "op_type" "RRE")])
10637
10638 ;
10639 ; Data prefetch patterns
10640 ;
10641
10642 (define_insn "prefetch"
10643 [(prefetch (match_operand 0 "address_operand" "ZT,X")
10644 (match_operand:SI 1 "const_int_operand" " n,n")
10645 (match_operand:SI 2 "const_int_operand" " n,n"))]
10646 "TARGET_Z10"
10647 {
10648 switch (which_alternative)
10649 {
10650 case 0:
10651 return INTVAL (operands[1]) == 1 ? "pfd\t2,%a0" : "pfd\t1,%a0";
10652 case 1:
10653 if (larl_operand (operands[0], Pmode))
10654 return INTVAL (operands[1]) == 1 ? "pfdrl\t2,%a0" : "pfdrl\t1,%a0";
10655 /* fallthrough */
10656 default:
10657
10658 /* This might be reached for symbolic operands with an odd
10659 addend. We simply omit the prefetch for such rare cases. */
10660
10661 return "";
10662 }
10663 }
10664 [(set_attr "type" "load,larl")
10665 (set_attr "op_type" "RXY,RIL")
10666 (set_attr "z10prop" "z10_super")
10667 (set_attr "z196prop" "z196_alone")])
10668
10669
10670 ;
10671 ; Byte swap instructions
10672 ;
10673
10674 ; FIXME: There is also mvcin but we cannot use it since src and target
10675 ; may overlap.
10676 (define_insn "bswap<mode>2"
10677 [(set (match_operand:GPR 0 "nonimmediate_operand" "=d,d,T")
10678 (bswap:GPR (match_operand:GPR 1 "nonimmediate_operand" " d,T,d")))]
10679 "TARGET_CPU_ZARCH"
10680 "@
10681 lrv<g>r\t%0,%1
10682 lrv<g>\t%0,%1
10683 strv<g>\t%1,%0"
10684 [(set_attr "type" "*,load,store")
10685 (set_attr "op_type" "RRE,RXY,RXY")
10686 (set_attr "z10prop" "z10_super")])
10687
10688 (define_insn "bswaphi2"
10689 [(set (match_operand:HI 0 "nonimmediate_operand" "=d,d,T")
10690 (bswap:HI (match_operand:HI 1 "nonimmediate_operand" " d,T,d")))]
10691 "TARGET_CPU_ZARCH"
10692 "@
10693 #
10694 lrvh\t%0,%1
10695 strvh\t%1,%0"
10696 [(set_attr "type" "*,load,store")
10697 (set_attr "op_type" "RRE,RXY,RXY")
10698 (set_attr "z10prop" "z10_super")])
10699
10700 (define_split
10701 [(set (match_operand:HI 0 "register_operand" "")
10702 (bswap:HI (match_operand:HI 1 "register_operand" "")))]
10703 "TARGET_CPU_ZARCH"
10704 [(set (match_dup 2) (bswap:SI (match_dup 3)))
10705 (set (match_dup 2) (lshiftrt:SI (match_dup 2) (const_int 16)))]
10706 {
10707 operands[2] = simplify_gen_subreg (SImode, operands[0], HImode, 0);
10708 operands[3] = simplify_gen_subreg (SImode, operands[1], HImode, 0);
10709 })
10710
10711
10712 ;
10713 ; Population count instruction
10714 ;
10715
10716 ; The S/390 popcount instruction counts the bits of op1 in 8 byte
10717 ; portions and stores the result in the corresponding bytes in op0.
10718 (define_insn "*popcount<mode>"
10719 [(set (match_operand:INT 0 "register_operand" "=d")
10720 (unspec:INT [(match_operand:INT 1 "register_operand" "d")] UNSPEC_POPCNT))
10721 (clobber (reg:CC CC_REGNUM))]
10722 "TARGET_Z196"
10723 "popcnt\t%0,%1"
10724 [(set_attr "op_type" "RRE")])
10725
10726 (define_expand "popcountdi2"
10727 [; popcnt op0, op1
10728 (parallel [(set (match_operand:DI 0 "register_operand" "")
10729 (unspec:DI [(match_operand:DI 1 "register_operand")]
10730 UNSPEC_POPCNT))
10731 (clobber (reg:CC CC_REGNUM))])
10732 ; sllg op2, op0, 32
10733 (set (match_dup 2) (ashift:DI (match_dup 0) (const_int 32)))
10734 ; agr op0, op2
10735 (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 2)))
10736 (clobber (reg:CC CC_REGNUM))])
10737 ; sllg op2, op0, 16
10738 (set (match_dup 2)
10739 (ashift:DI (match_dup 0) (const_int 16)))
10740 ; agr op0, op2
10741 (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 2)))
10742 (clobber (reg:CC CC_REGNUM))])
10743 ; sllg op2, op0, 8
10744 (set (match_dup 2) (ashift:DI (match_dup 0) (const_int 8)))
10745 ; agr op0, op2
10746 (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 2)))
10747 (clobber (reg:CC CC_REGNUM))])
10748 ; srlg op0, op0, 56
10749 (set (match_dup 0) (lshiftrt:DI (match_dup 0) (const_int 56)))]
10750 "TARGET_Z196 && TARGET_64BIT"
10751 "operands[2] = gen_reg_rtx (DImode);")
10752
10753 (define_expand "popcountsi2"
10754 [; popcnt op0, op1
10755 (parallel [(set (match_operand:SI 0 "register_operand" "")
10756 (unspec:SI [(match_operand:SI 1 "register_operand")]
10757 UNSPEC_POPCNT))
10758 (clobber (reg:CC CC_REGNUM))])
10759 ; sllk op2, op0, 16
10760 (set (match_dup 2)
10761 (ashift:SI (match_dup 0) (const_int 16)))
10762 ; ar op0, op2
10763 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
10764 (clobber (reg:CC CC_REGNUM))])
10765 ; sllk op2, op0, 8
10766 (set (match_dup 2) (ashift:SI (match_dup 0) (const_int 8)))
10767 ; ar op0, op2
10768 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
10769 (clobber (reg:CC CC_REGNUM))])
10770 ; srl op0, op0, 24
10771 (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 24)))]
10772 "TARGET_Z196"
10773 "operands[2] = gen_reg_rtx (SImode);")
10774
10775 (define_expand "popcounthi2"
10776 [; popcnt op0, op1
10777 (parallel [(set (match_operand:HI 0 "register_operand" "")
10778 (unspec:HI [(match_operand:HI 1 "register_operand")]
10779 UNSPEC_POPCNT))
10780 (clobber (reg:CC CC_REGNUM))])
10781 ; sllk op2, op0, 8
10782 (set (match_dup 2)
10783 (ashift:SI (match_dup 0) (const_int 8)))
10784 ; ar op0, op2
10785 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
10786 (clobber (reg:CC CC_REGNUM))])
10787 ; srl op0, op0, 8
10788 (set (match_dup 0) (lshiftrt:HI (match_dup 0) (const_int 8)))]
10789 "TARGET_Z196"
10790 "operands[2] = gen_reg_rtx (SImode);")
10791
10792 (define_expand "popcountqi2"
10793 [; popcnt op0, op1
10794 (parallel [(set (match_operand:QI 0 "register_operand" "")
10795 (unspec:QI [(match_operand:QI 1 "register_operand")]
10796 UNSPEC_POPCNT))
10797 (clobber (reg:CC CC_REGNUM))])]
10798 "TARGET_Z196"
10799 "")
10800
10801 ;;
10802 ;;- Copy sign instructions
10803 ;;
10804
10805 (define_insn "copysign<mode>3"
10806 [(set (match_operand:FP 0 "register_operand" "=f")
10807 (unspec:FP [(match_operand:FP 1 "register_operand" "<fT0>")
10808 (match_operand:FP 2 "register_operand" "f")]
10809 UNSPEC_COPYSIGN))]
10810 "TARGET_Z196"
10811 "cpsdr\t%0,%2,%1"
10812 [(set_attr "op_type" "RRF")
10813 (set_attr "type" "fsimp<mode>")])
10814
10815
10816 ;;
10817 ;;- Transactional execution instructions
10818 ;;
10819
10820 ; This splitter helps combine to make use of CC directly when
10821 ; comparing the integer result of a tbegin builtin with a constant.
10822 ; The unspec is already removed by canonicalize_comparison. So this
10823 ; splitters only job is to turn the PARALLEL into separate insns
10824 ; again. Unfortunately this only works with the very first cc/int
10825 ; compare since combine is not able to deal with data flow across
10826 ; basic block boundaries.
10827
10828 ; It needs to be an insn pattern as well since combine does not apply
10829 ; the splitter directly. Combine would only use it if it actually
10830 ; would reduce the number of instructions.
10831 (define_insn_and_split "*ccraw_to_int"
10832 [(set (pc)
10833 (if_then_else
10834 (match_operator 0 "s390_eqne_operator"
10835 [(reg:CCRAW CC_REGNUM)
10836 (match_operand 1 "const_int_operand" "")])
10837 (label_ref (match_operand 2 "" ""))
10838 (pc)))
10839 (set (match_operand:SI 3 "register_operand" "=d")
10840 (unspec:SI [(reg:CCRAW CC_REGNUM)] UNSPEC_CC_TO_INT))]
10841 ""
10842 "#"
10843 ""
10844 [(set (match_dup 3)
10845 (unspec:SI [(reg:CCRAW CC_REGNUM)] UNSPEC_CC_TO_INT))
10846 (set (pc)
10847 (if_then_else (match_op_dup 0 [(reg:CCRAW CC_REGNUM) (match_dup 1)])
10848 (label_ref (match_dup 2))
10849 (pc)))]
10850 "")
10851
10852 ; Non-constrained transaction begin
10853
10854 (define_expand "tbegin"
10855 [(match_operand:SI 0 "register_operand" "")
10856 (match_operand:BLK 1 "memory_operand" "")]
10857 "TARGET_HTM"
10858 {
10859 s390_expand_tbegin (operands[0], operands[1], NULL_RTX, true);
10860 DONE;
10861 })
10862
10863 (define_expand "tbegin_nofloat"
10864 [(match_operand:SI 0 "register_operand" "")
10865 (match_operand:BLK 1 "memory_operand" "")]
10866 "TARGET_HTM"
10867 {
10868 s390_expand_tbegin (operands[0], operands[1], NULL_RTX, false);
10869 DONE;
10870 })
10871
10872 (define_expand "tbegin_retry"
10873 [(match_operand:SI 0 "register_operand" "")
10874 (match_operand:BLK 1 "memory_operand" "")
10875 (match_operand:SI 2 "general_operand" "")]
10876 "TARGET_HTM"
10877 {
10878 s390_expand_tbegin (operands[0], operands[1], operands[2], true);
10879 DONE;
10880 })
10881
10882 (define_expand "tbegin_retry_nofloat"
10883 [(match_operand:SI 0 "register_operand" "")
10884 (match_operand:BLK 1 "memory_operand" "")
10885 (match_operand:SI 2 "general_operand" "")]
10886 "TARGET_HTM"
10887 {
10888 s390_expand_tbegin (operands[0], operands[1], operands[2], false);
10889 DONE;
10890 })
10891
10892 ; Clobber VRs since they don't get restored
10893 (define_insn "tbegin_1_z13"
10894 [(set (reg:CCRAW CC_REGNUM)
10895 (unspec_volatile:CCRAW [(match_operand 0 "const_int_operand" "D")]
10896 UNSPECV_TBEGIN))
10897 (set (match_operand:BLK 1 "memory_operand" "=Q")
10898 (unspec_volatile:BLK [(match_dup 0)] UNSPECV_TBEGIN_TDB))
10899 (clobber (reg:TI 16)) (clobber (reg:TI 38))
10900 (clobber (reg:TI 17)) (clobber (reg:TI 39))
10901 (clobber (reg:TI 18)) (clobber (reg:TI 40))
10902 (clobber (reg:TI 19)) (clobber (reg:TI 41))
10903 (clobber (reg:TI 20)) (clobber (reg:TI 42))
10904 (clobber (reg:TI 21)) (clobber (reg:TI 43))
10905 (clobber (reg:TI 22)) (clobber (reg:TI 44))
10906 (clobber (reg:TI 23)) (clobber (reg:TI 45))
10907 (clobber (reg:TI 24)) (clobber (reg:TI 46))
10908 (clobber (reg:TI 25)) (clobber (reg:TI 47))
10909 (clobber (reg:TI 26)) (clobber (reg:TI 48))
10910 (clobber (reg:TI 27)) (clobber (reg:TI 49))
10911 (clobber (reg:TI 28)) (clobber (reg:TI 50))
10912 (clobber (reg:TI 29)) (clobber (reg:TI 51))
10913 (clobber (reg:TI 30)) (clobber (reg:TI 52))
10914 (clobber (reg:TI 31)) (clobber (reg:TI 53))]
10915 ; CONST_OK_FOR_CONSTRAINT_P does not work with D constraint since D is
10916 ; not supposed to be used for immediates (see genpreds.c).
10917 "TARGET_VX && INTVAL (operands[0]) >= 0 && INTVAL (operands[0]) <= 0xffff"
10918 "tbegin\t%1,%x0"
10919 [(set_attr "op_type" "SIL")])
10920
10921 (define_insn "tbegin_1"
10922 [(set (reg:CCRAW CC_REGNUM)
10923 (unspec_volatile:CCRAW [(match_operand 0 "const_int_operand" "D")]
10924 UNSPECV_TBEGIN))
10925 (set (match_operand:BLK 1 "memory_operand" "=Q")
10926 (unspec_volatile:BLK [(match_dup 0)] UNSPECV_TBEGIN_TDB))
10927 (clobber (reg:DF 16))
10928 (clobber (reg:DF 17))
10929 (clobber (reg:DF 18))
10930 (clobber (reg:DF 19))
10931 (clobber (reg:DF 20))
10932 (clobber (reg:DF 21))
10933 (clobber (reg:DF 22))
10934 (clobber (reg:DF 23))
10935 (clobber (reg:DF 24))
10936 (clobber (reg:DF 25))
10937 (clobber (reg:DF 26))
10938 (clobber (reg:DF 27))
10939 (clobber (reg:DF 28))
10940 (clobber (reg:DF 29))
10941 (clobber (reg:DF 30))
10942 (clobber (reg:DF 31))]
10943 ; CONST_OK_FOR_CONSTRAINT_P does not work with D constraint since D is
10944 ; not supposed to be used for immediates (see genpreds.c).
10945 "TARGET_HTM && INTVAL (operands[0]) >= 0 && INTVAL (operands[0]) <= 0xffff"
10946 "tbegin\t%1,%x0"
10947 [(set_attr "op_type" "SIL")])
10948
10949 ; Same as above but without the FPR clobbers
10950 (define_insn "tbegin_nofloat_1"
10951 [(set (reg:CCRAW CC_REGNUM)
10952 (unspec_volatile:CCRAW [(match_operand 0 "const_int_operand" "D")]
10953 UNSPECV_TBEGIN))
10954 (set (match_operand:BLK 1 "memory_operand" "=Q")
10955 (unspec_volatile:BLK [(match_dup 0)] UNSPECV_TBEGIN_TDB))]
10956 "TARGET_HTM && INTVAL (operands[0]) >= 0 && INTVAL (operands[0]) <= 0xffff"
10957 "tbegin\t%1,%x0"
10958 [(set_attr "op_type" "SIL")])
10959
10960
10961 ; Constrained transaction begin
10962
10963 (define_expand "tbeginc"
10964 [(set (reg:CCRAW CC_REGNUM)
10965 (unspec_volatile:CCRAW [(const_int TBEGINC_MASK)]
10966 UNSPECV_TBEGINC))]
10967 "TARGET_HTM"
10968 "")
10969
10970 (define_insn "*tbeginc_1"
10971 [(set (reg:CCRAW CC_REGNUM)
10972 (unspec_volatile:CCRAW [(match_operand 0 "const_int_operand" " D")]
10973 UNSPECV_TBEGINC))]
10974 "TARGET_HTM && INTVAL (operands[0]) >= 0 && INTVAL (operands[0]) <= 0xffff"
10975 "tbeginc\t0,%x0"
10976 [(set_attr "op_type" "SIL")])
10977
10978 ; Transaction end
10979
10980 (define_expand "tend"
10981 [(set (reg:CCRAW CC_REGNUM)
10982 (unspec_volatile:CCRAW [(const_int 0)] UNSPECV_TEND))
10983 (set (match_operand:SI 0 "register_operand" "")
10984 (unspec:SI [(reg:CCRAW CC_REGNUM)] UNSPEC_CC_TO_INT))]
10985 "TARGET_HTM"
10986 "")
10987
10988 (define_insn "*tend_1"
10989 [(set (reg:CCRAW CC_REGNUM)
10990 (unspec_volatile:CCRAW [(const_int 0)] UNSPECV_TEND))]
10991 "TARGET_HTM"
10992 "tend"
10993 [(set_attr "op_type" "S")])
10994
10995 ; Transaction abort
10996
10997 (define_expand "tabort"
10998 [(unspec_volatile [(match_operand:SI 0 "nonmemory_operand" "")]
10999 UNSPECV_TABORT)]
11000 "TARGET_HTM && operands != NULL"
11001 {
11002 if (CONST_INT_P (operands[0])
11003 && INTVAL (operands[0]) >= 0 && INTVAL (operands[0]) <= 255)
11004 {
11005 error ("Invalid transaction abort code: " HOST_WIDE_INT_PRINT_DEC
11006 ". Values in range 0 through 255 are reserved.",
11007 INTVAL (operands[0]));
11008 FAIL;
11009 }
11010 })
11011
11012 (define_insn "*tabort_1"
11013 [(unspec_volatile [(match_operand:SI 0 "nonmemory_operand" "aJ")]
11014 UNSPECV_TABORT)]
11015 "TARGET_HTM && operands != NULL"
11016 "tabort\t%Y0"
11017 [(set_attr "op_type" "S")])
11018
11019 (define_insn "*tabort_1_plus"
11020 [(unspec_volatile [(plus:SI (match_operand:SI 0 "register_operand" "a")
11021 (match_operand:SI 1 "const_int_operand" "J"))]
11022 UNSPECV_TABORT)]
11023 "TARGET_HTM && operands != NULL
11024 && CONST_OK_FOR_CONSTRAINT_P (INTVAL (operands[1]), 'J', \"J\")"
11025 "tabort\t%1(%0)"
11026 [(set_attr "op_type" "S")])
11027
11028 ; Transaction extract nesting depth
11029
11030 (define_insn "etnd"
11031 [(set (match_operand:SI 0 "register_operand" "=d")
11032 (unspec_volatile:SI [(const_int 0)] UNSPECV_ETND))]
11033 "TARGET_HTM"
11034 "etnd\t%0"
11035 [(set_attr "op_type" "RRE")])
11036
11037 ; Non-transactional store
11038
11039 (define_insn "ntstg"
11040 [(set (match_operand:DI 0 "memory_operand" "=T")
11041 (unspec_volatile:DI [(match_operand:DI 1 "register_operand" "d")]
11042 UNSPECV_NTSTG))]
11043 "TARGET_HTM"
11044 "ntstg\t%1,%0"
11045 [(set_attr "op_type" "RXY")])
11046
11047 ; Transaction perform processor assist
11048
11049 (define_expand "tx_assist"
11050 [(unspec_volatile [(match_operand:SI 0 "register_operand" "")
11051 (reg:SI GPR0_REGNUM)
11052 (const_int 1)]
11053 UNSPECV_PPA)]
11054 "TARGET_HTM"
11055 "")
11056
11057 (define_insn "*ppa"
11058 [(unspec_volatile [(match_operand:SI 0 "register_operand" "d")
11059 (match_operand:SI 1 "register_operand" "d")
11060 (match_operand 2 "const_int_operand" "I")]
11061 UNSPECV_PPA)]
11062 "TARGET_HTM && INTVAL (operands[2]) < 16"
11063 "ppa\t%0,%1,%2"
11064 [(set_attr "op_type" "RRF")])
11065
11066
11067 ; Set and get floating point control register
11068
11069 (define_insn "sfpc"
11070 [(unspec_volatile [(match_operand:SI 0 "register_operand" "d")]
11071 UNSPECV_SFPC)]
11072 "TARGET_HARD_FLOAT"
11073 "sfpc\t%0")
11074
11075 (define_insn "efpc"
11076 [(set (match_operand:SI 0 "register_operand" "=d")
11077 (unspec_volatile:SI [(const_int 0)] UNSPECV_EFPC))]
11078 "TARGET_HARD_FLOAT"
11079 "efpc\t%0")
11080
11081
11082 ; Load count to block boundary
11083
11084 (define_insn "lcbb"
11085 [(set (match_operand:SI 0 "register_operand" "=d")
11086 (unspec:SI [(match_operand 1 "address_operand" "ZR")
11087 (match_operand:SI 2 "immediate_operand" "C")] UNSPEC_LCBB))
11088 (clobber (reg:CC CC_REGNUM))]
11089 "TARGET_Z13"
11090 "lcbb\t%0,%a1,%b2"
11091 [(set_attr "op_type" "VRX")])
11092
11093 ; Handle -fsplit-stack.
11094
11095 (define_expand "split_stack_prologue"
11096 [(const_int 0)]
11097 ""
11098 {
11099 s390_expand_split_stack_prologue ();
11100 DONE;
11101 })
11102
11103 ;; If there are operand 0 bytes available on the stack, jump to
11104 ;; operand 1.
11105
11106 (define_expand "split_stack_space_check"
11107 [(set (pc) (if_then_else
11108 (ltu (minus (reg 15)
11109 (match_operand 0 "register_operand"))
11110 (unspec [(const_int 0)] UNSPEC_STACK_CHECK))
11111 (label_ref (match_operand 1))
11112 (pc)))]
11113 ""
11114 {
11115 /* Offset from thread pointer to __private_ss. */
11116 int psso = TARGET_64BIT ? 0x38 : 0x20;
11117 rtx tp = s390_get_thread_pointer ();
11118 rtx guard = gen_rtx_MEM (Pmode, plus_constant (Pmode, tp, psso));
11119 rtx reg = gen_reg_rtx (Pmode);
11120 rtx cc;
11121 if (TARGET_64BIT)
11122 emit_insn (gen_subdi3 (reg, stack_pointer_rtx, operands[0]));
11123 else
11124 emit_insn (gen_subsi3 (reg, stack_pointer_rtx, operands[0]));
11125 cc = s390_emit_compare (GT, reg, guard);
11126 s390_emit_jump (operands[1], cc);
11127
11128 DONE;
11129 })
11130
11131 ;; __morestack parameter block for split stack prologue. Parameters are:
11132 ;; parameter block label, label to be called by __morestack, frame size,
11133 ;; stack parameter size.
11134
11135 (define_insn "split_stack_data"
11136 [(unspec_volatile [(match_operand 0 "" "X")
11137 (match_operand 1 "" "X")
11138 (match_operand 2 "const_int_operand" "X")
11139 (match_operand 3 "const_int_operand" "X")]
11140 UNSPECV_SPLIT_STACK_DATA)]
11141 "TARGET_CPU_ZARCH"
11142 {
11143 switch_to_section (targetm.asm_out.function_rodata_section
11144 (current_function_decl));
11145
11146 if (TARGET_64BIT)
11147 output_asm_insn (".align\t8", operands);
11148 else
11149 output_asm_insn (".align\t4", operands);
11150 (*targetm.asm_out.internal_label) (asm_out_file, "L",
11151 CODE_LABEL_NUMBER (operands[0]));
11152 if (TARGET_64BIT)
11153 {
11154 output_asm_insn (".quad\t%2", operands);
11155 output_asm_insn (".quad\t%3", operands);
11156 output_asm_insn (".quad\t%1-%0", operands);
11157 }
11158 else
11159 {
11160 output_asm_insn (".long\t%2", operands);
11161 output_asm_insn (".long\t%3", operands);
11162 output_asm_insn (".long\t%1-%0", operands);
11163 }
11164
11165 switch_to_section (current_function_section ());
11166 return "";
11167 }
11168 [(set_attr "length" "0")])
11169
11170
11171 ;; A jg with minimal fuss for use in split stack prologue.
11172
11173 (define_expand "split_stack_call"
11174 [(match_operand 0 "bras_sym_operand" "X")
11175 (match_operand 1 "" "")]
11176 "TARGET_CPU_ZARCH"
11177 {
11178 if (TARGET_64BIT)
11179 emit_jump_insn (gen_split_stack_call_di (operands[0], operands[1]));
11180 else
11181 emit_jump_insn (gen_split_stack_call_si (operands[0], operands[1]));
11182 DONE;
11183 })
11184
11185 (define_insn "split_stack_call_<mode>"
11186 [(set (pc) (label_ref (match_operand 1 "" "")))
11187 (set (reg:P 1) (unspec_volatile [(match_operand 0 "bras_sym_operand" "X")
11188 (reg:P 1)]
11189 UNSPECV_SPLIT_STACK_CALL))]
11190 "TARGET_CPU_ZARCH"
11191 "jg\t%0"
11192 [(set_attr "op_type" "RIL")
11193 (set_attr "type" "branch")])
11194
11195 ;; Also a conditional one.
11196
11197 (define_expand "split_stack_cond_call"
11198 [(match_operand 0 "bras_sym_operand" "X")
11199 (match_operand 1 "" "")
11200 (match_operand 2 "" "")]
11201 "TARGET_CPU_ZARCH"
11202 {
11203 if (TARGET_64BIT)
11204 emit_jump_insn (gen_split_stack_cond_call_di (operands[0], operands[1], operands[2]));
11205 else
11206 emit_jump_insn (gen_split_stack_cond_call_si (operands[0], operands[1], operands[2]));
11207 DONE;
11208 })
11209
11210 (define_insn "split_stack_cond_call_<mode>"
11211 [(set (pc)
11212 (if_then_else
11213 (match_operand 1 "" "")
11214 (label_ref (match_operand 2 "" ""))
11215 (pc)))
11216 (set (reg:P 1) (unspec_volatile [(match_operand 0 "bras_sym_operand" "X")
11217 (reg:P 1)]
11218 UNSPECV_SPLIT_STACK_CALL))]
11219 "TARGET_CPU_ZARCH"
11220 "jg%C1\t%0"
11221 [(set_attr "op_type" "RIL")
11222 (set_attr "type" "branch")])
11223
11224 (define_insn "osc_break"
11225 [(unspec_volatile [(const_int 0)] UNSPECV_OSC_BREAK)]
11226 ""
11227 "bcr\t7,%%r0"
11228 [(set_attr "op_type" "RR")])