S/390: movdf improvements
[gcc.git] / gcc / config / s390 / s390.md
1 ;;- Machine description for GNU compiler -- S/390 / zSeries version.
2 ;; Copyright (C) 1999-2017 Free Software Foundation, Inc.
3 ;; Contributed by Hartmut Penner (hpenner@de.ibm.com) and
4 ;; Ulrich Weigand (uweigand@de.ibm.com) and
5 ;; Andreas Krebbel (Andreas.Krebbel@de.ibm.com)
6
7 ;; This file is part of GCC.
8
9 ;; GCC is free software; you can redistribute it and/or modify it under
10 ;; the terms of the GNU General Public License as published by the Free
11 ;; Software Foundation; either version 3, or (at your option) any later
12 ;; version.
13
14 ;; GCC is distributed in the hope that it will be useful, but WITHOUT ANY
15 ;; WARRANTY; without even the implied warranty of MERCHANTABILITY or
16 ;; FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
17 ;; for more details.
18
19 ;; You should have received a copy of the GNU General Public License
20 ;; along with GCC; see the file COPYING3. If not see
21 ;; <http://www.gnu.org/licenses/>.
22
23 ;;
24 ;; See constraints.md for a description of constraints specific to s390.
25 ;;
26
27 ;; Special formats used for outputting 390 instructions.
28 ;;
29 ;; %C: print opcode suffix for branch condition.
30 ;; %D: print opcode suffix for inverse branch condition.
31 ;; %J: print tls_load/tls_gdcall/tls_ldcall suffix
32 ;; %G: print the size of the operand in bytes.
33 ;; %O: print only the displacement of a memory reference.
34 ;; %R: print only the base register of a memory reference.
35 ;; %S: print S-type memory reference (base+displacement).
36 ;; %N: print the second word of a DImode operand.
37 ;; %M: print the second word of a TImode operand.
38 ;; %Y: print shift count operand.
39 ;;
40 ;; %b: print integer X as if it's an unsigned byte.
41 ;; %c: print integer X as if it's an signed byte.
42 ;; %x: print integer X as if it's an unsigned halfword.
43 ;; %h: print integer X as if it's a signed halfword.
44 ;; %i: print the first nonzero HImode part of X.
45 ;; %j: print the first HImode part unequal to -1 of X.
46 ;; %k: print the first nonzero SImode part of X.
47 ;; %m: print the first SImode part unequal to -1 of X.
48 ;; %o: print integer X as if it's an unsigned 32bit word.
49 ;;
50 ;; We have a special constraint for pattern matching.
51 ;;
52 ;; s_operand -- Matches a valid S operand in a RS, SI or SS type instruction.
53 ;;
54
55 ;;
56 ;; UNSPEC usage
57 ;;
58
59 (define_c_enum "unspec" [
60 ; Miscellaneous
61 UNSPEC_ROUND
62 UNSPEC_ICM
63 UNSPEC_TIE
64
65 ; Convert CC into a str comparison result and copy it into an
66 ; integer register
67 ; cc0->0, cc1->1, cc2->-1, (cc3->-1)
68 UNSPEC_STRCMPCC_TO_INT
69
70 ; Copy CC as is into the lower 2 bits of an integer register
71 UNSPEC_CC_TO_INT
72
73 ; The right hand side of an setmem
74 UNSPEC_REPLICATE_BYTE
75
76 ; GOT/PLT and lt-relative accesses
77 UNSPEC_LTREL_OFFSET
78 UNSPEC_LTREL_BASE
79 UNSPEC_POOL_OFFSET
80 UNSPEC_GOTENT
81 UNSPEC_GOT
82 UNSPEC_GOTOFF
83 UNSPEC_PLT
84 UNSPEC_PLTOFF
85
86 ; Literal pool
87 UNSPEC_RELOAD_BASE
88 UNSPEC_MAIN_BASE
89 UNSPEC_LTREF
90 UNSPEC_INSN
91 UNSPEC_EXECUTE
92
93 ; Atomic Support
94 UNSPEC_MB
95 UNSPEC_MOVA
96
97 ; TLS relocation specifiers
98 UNSPEC_TLSGD
99 UNSPEC_TLSLDM
100 UNSPEC_NTPOFF
101 UNSPEC_DTPOFF
102 UNSPEC_GOTNTPOFF
103 UNSPEC_INDNTPOFF
104
105 ; TLS support
106 UNSPEC_TLSLDM_NTPOFF
107 UNSPEC_TLS_LOAD
108
109 ; String Functions
110 UNSPEC_SRST
111 UNSPEC_MVST
112
113 ; Stack Smashing Protector
114 UNSPEC_SP_SET
115 UNSPEC_SP_TEST
116
117 ; Split stack support
118 UNSPEC_STACK_CHECK
119
120 ; Test Data Class (TDC)
121 UNSPEC_TDC_INSN
122
123 ; Population Count
124 UNSPEC_POPCNT
125 UNSPEC_COPYSIGN
126
127 ; Load FP Integer
128 UNSPEC_FPINT_FLOOR
129 UNSPEC_FPINT_BTRUNC
130 UNSPEC_FPINT_ROUND
131 UNSPEC_FPINT_CEIL
132 UNSPEC_FPINT_NEARBYINT
133 UNSPEC_FPINT_RINT
134
135 UNSPEC_LCBB
136
137 ; Vector
138 UNSPEC_VEC_SMULT_HI
139 UNSPEC_VEC_UMULT_HI
140 UNSPEC_VEC_SMULT_LO
141 UNSPEC_VEC_SMULT_EVEN
142 UNSPEC_VEC_UMULT_EVEN
143 UNSPEC_VEC_SMULT_ODD
144 UNSPEC_VEC_UMULT_ODD
145
146 UNSPEC_VEC_VMAL
147 UNSPEC_VEC_VMAH
148 UNSPEC_VEC_VMALH
149 UNSPEC_VEC_VMAE
150 UNSPEC_VEC_VMALE
151 UNSPEC_VEC_VMAO
152 UNSPEC_VEC_VMALO
153
154 UNSPEC_VEC_GATHER
155 UNSPEC_VEC_EXTRACT
156 UNSPEC_VEC_INSERT_AND_ZERO
157 UNSPEC_VEC_LOAD_BNDRY
158 UNSPEC_VEC_LOAD_LEN
159 UNSPEC_VEC_MERGEH
160 UNSPEC_VEC_MERGEL
161 UNSPEC_VEC_PACK
162 UNSPEC_VEC_PACK_SATURATE
163 UNSPEC_VEC_PACK_SATURATE_CC
164 UNSPEC_VEC_PACK_SATURATE_GENCC
165 UNSPEC_VEC_PACK_UNSIGNED_SATURATE
166 UNSPEC_VEC_PACK_UNSIGNED_SATURATE_CC
167 UNSPEC_VEC_PACK_UNSIGNED_SATURATE_GENCC
168 UNSPEC_VEC_PERM
169 UNSPEC_VEC_PERMI
170 UNSPEC_VEC_EXTEND
171 UNSPEC_VEC_STORE_LEN
172 UNSPEC_VEC_UNPACKH
173 UNSPEC_VEC_UNPACKH_L
174 UNSPEC_VEC_UNPACKL
175 UNSPEC_VEC_UNPACKL_L
176 UNSPEC_VEC_ADDC
177 UNSPEC_VEC_ADDE_U128
178 UNSPEC_VEC_ADDEC_U128
179 UNSPEC_VEC_AVG
180 UNSPEC_VEC_AVGU
181 UNSPEC_VEC_CHECKSUM
182 UNSPEC_VEC_GFMSUM
183 UNSPEC_VEC_GFMSUM_128
184 UNSPEC_VEC_GFMSUM_ACCUM
185 UNSPEC_VEC_GFMSUM_ACCUM_128
186 UNSPEC_VEC_SET
187
188 UNSPEC_VEC_VSUMG
189 UNSPEC_VEC_VSUMQ
190 UNSPEC_VEC_VSUM
191 UNSPEC_VEC_RL_MASK
192 UNSPEC_VEC_SLL
193 UNSPEC_VEC_SLB
194 UNSPEC_VEC_SLDB
195 UNSPEC_VEC_SRAL
196 UNSPEC_VEC_SRAB
197 UNSPEC_VEC_SRL
198 UNSPEC_VEC_SRLB
199
200 UNSPEC_VEC_SUBC
201 UNSPEC_VEC_SUBE_U128
202 UNSPEC_VEC_SUBEC_U128
203
204 UNSPEC_VEC_TEST_MASK
205
206 UNSPEC_VEC_VFAE
207 UNSPEC_VEC_VFAECC
208
209 UNSPEC_VEC_VFEE
210 UNSPEC_VEC_VFEECC
211 UNSPEC_VEC_VFENE
212 UNSPEC_VEC_VFENECC
213
214 UNSPEC_VEC_VISTR
215 UNSPEC_VEC_VISTRCC
216
217 UNSPEC_VEC_VSTRC
218 UNSPEC_VEC_VSTRCCC
219
220 UNSPEC_VEC_VCDGB
221 UNSPEC_VEC_VCDLGB
222
223 UNSPEC_VEC_VCGDB
224 UNSPEC_VEC_VCLGDB
225
226 UNSPEC_VEC_VFIDB
227
228 UNSPEC_VEC_VLDEB
229 UNSPEC_VEC_VLEDB
230
231 UNSPEC_VEC_VFTCIDB
232 UNSPEC_VEC_VFTCIDBCC
233 ])
234
235 ;;
236 ;; UNSPEC_VOLATILE usage
237 ;;
238
239 (define_c_enum "unspecv" [
240 ; Blockage
241 UNSPECV_BLOCKAGE
242
243 ; TPF Support
244 UNSPECV_TPF_PROLOGUE
245 UNSPECV_TPF_EPILOGUE
246
247 ; Literal pool
248 UNSPECV_POOL
249 UNSPECV_POOL_SECTION
250 UNSPECV_POOL_ALIGN
251 UNSPECV_POOL_ENTRY
252 UNSPECV_MAIN_POOL
253
254 ; TLS support
255 UNSPECV_SET_TP
256
257 ; Atomic Support
258 UNSPECV_CAS
259 UNSPECV_ATOMIC_OP
260
261 ; Hotpatching (unremovable NOPs)
262 UNSPECV_NOP_2_BYTE
263 UNSPECV_NOP_4_BYTE
264 UNSPECV_NOP_6_BYTE
265
266 ; Transactional Execution support
267 UNSPECV_TBEGIN
268 UNSPECV_TBEGIN_TDB
269 UNSPECV_TBEGINC
270 UNSPECV_TEND
271 UNSPECV_TABORT
272 UNSPECV_ETND
273 UNSPECV_NTSTG
274 UNSPECV_PPA
275
276 ; Set and get floating point control register
277 UNSPECV_SFPC
278 UNSPECV_EFPC
279
280 ; Split stack support
281 UNSPECV_SPLIT_STACK_CALL
282 UNSPECV_SPLIT_STACK_DATA
283
284 UNSPECV_OSC_BREAK
285 ])
286
287 ;;
288 ;; Registers
289 ;;
290
291 ; Registers with special meaning
292
293 (define_constants
294 [
295 ; Sibling call register.
296 (SIBCALL_REGNUM 1)
297 ; Literal pool base register.
298 (BASE_REGNUM 13)
299 ; Return address register.
300 (RETURN_REGNUM 14)
301 ; Stack pointer register.
302 (STACK_REGNUM 15)
303 ; Condition code register.
304 (CC_REGNUM 33)
305 ; Thread local storage pointer register.
306 (TP_REGNUM 36)
307 ])
308
309 ; Hardware register names
310
311 (define_constants
312 [
313 ; General purpose registers
314 (GPR0_REGNUM 0)
315 (GPR1_REGNUM 1)
316 (GPR2_REGNUM 2)
317 (GPR6_REGNUM 6)
318 ; Floating point registers.
319 (FPR0_REGNUM 16)
320 (FPR1_REGNUM 20)
321 (FPR2_REGNUM 17)
322 (FPR3_REGNUM 21)
323 (FPR4_REGNUM 18)
324 (FPR5_REGNUM 22)
325 (FPR6_REGNUM 19)
326 (FPR7_REGNUM 23)
327 (FPR8_REGNUM 24)
328 (FPR9_REGNUM 28)
329 (FPR10_REGNUM 25)
330 (FPR11_REGNUM 29)
331 (FPR12_REGNUM 26)
332 (FPR13_REGNUM 30)
333 (FPR14_REGNUM 27)
334 (FPR15_REGNUM 31)
335 (VR0_REGNUM 16)
336 (VR16_REGNUM 38)
337 (VR23_REGNUM 45)
338 (VR24_REGNUM 46)
339 (VR31_REGNUM 53)
340 ])
341
342 ; Rounding modes for binary floating point numbers
343 (define_constants
344 [(BFP_RND_CURRENT 0)
345 (BFP_RND_NEAREST_TIE_AWAY_FROM_0 1)
346 (BFP_RND_PREP_FOR_SHORT_PREC 3)
347 (BFP_RND_NEAREST_TIE_TO_EVEN 4)
348 (BFP_RND_TOWARD_0 5)
349 (BFP_RND_TOWARD_INF 6)
350 (BFP_RND_TOWARD_MINF 7)])
351
352 ; Rounding modes for decimal floating point numbers
353 ; 1-7 were introduced with the floating point extension facility
354 ; available with z196
355 ; With these rounding modes (1-7) a quantum exception might occur
356 ; which is suppressed for the other modes.
357 (define_constants
358 [(DFP_RND_CURRENT 0)
359 (DFP_RND_NEAREST_TIE_AWAY_FROM_0_QUANTEXC 1)
360 (DFP_RND_CURRENT_QUANTEXC 2)
361 (DFP_RND_PREP_FOR_SHORT_PREC_QUANTEXC 3)
362 (DFP_RND_NEAREST_TIE_TO_EVEN_QUANTEXC 4)
363 (DFP_RND_TOWARD_0_QUANTEXC 5)
364 (DFP_RND_TOWARD_INF_QUANTEXC 6)
365 (DFP_RND_TOWARD_MINF_QUANTEXC 7)
366 (DFP_RND_NEAREST_TIE_TO_EVEN 8)
367 (DFP_RND_TOWARD_0 9)
368 (DFP_RND_TOWARD_INF 10)
369 (DFP_RND_TOWARD_MINF 11)
370 (DFP_RND_NEAREST_TIE_AWAY_FROM_0 12)
371 (DFP_RND_NEAREST_TIE_TO_0 13)
372 (DFP_RND_AWAY_FROM_0 14)
373 (DFP_RND_PREP_FOR_SHORT_PREC 15)])
374
375 ;;
376 ;; PFPO GPR0 argument format
377 ;;
378
379 (define_constants
380 [
381 ; PFPO operation type
382 (PFPO_CONVERT 0x1000000)
383 ; PFPO operand types
384 (PFPO_OP_TYPE_SF 0x5)
385 (PFPO_OP_TYPE_DF 0x6)
386 (PFPO_OP_TYPE_TF 0x7)
387 (PFPO_OP_TYPE_SD 0x8)
388 (PFPO_OP_TYPE_DD 0x9)
389 (PFPO_OP_TYPE_TD 0xa)
390 ; Bitposition of operand types
391 (PFPO_OP0_TYPE_SHIFT 16)
392 (PFPO_OP1_TYPE_SHIFT 8)
393 ])
394
395 ; Immediate operands for tbegin and tbeginc
396 (define_constants [(TBEGIN_MASK 65292)]) ; 0xff0c
397 (define_constants [(TBEGINC_MASK 65288)]) ; 0xff08
398
399 ;; Instruction operand type as used in the Principles of Operation.
400 ;; Used to determine defaults for length and other attribute values.
401
402 (define_attr "op_type"
403 "NN,E,RR,RRE,RX,RS,RSI,RI,SI,S,SS,SSE,RXE,RSE,RIL,RIE,RXY,RSY,SIY,RRF,SIL,RRS,RIS,VRI,VRR,VRS,VRV,VRX"
404 (const_string "NN"))
405
406 ;; Instruction type attribute used for scheduling.
407
408 (define_attr "type" "none,integer,load,lr,la,larl,lm,stm,
409 cs,vs,store,sem,idiv,
410 imulhi,imulsi,imuldi,
411 branch,jsr,fsimptf,fsimpdf,fsimpsf,fhex,
412 floadtf,floaddf,floadsf,fstoredf,fstoresf,
413 fmultf,fmuldf,fmulsf,fdivtf,fdivdf,fdivsf,
414 ftoi,fsqrttf,fsqrtdf,fsqrtsf,
415 fmadddf,fmaddsf,
416 ftrunctf,ftruncdf, ftruncsd, ftruncdd,
417 itoftf, itofdf, itofsf, itofdd, itoftd,
418 fdivdd, fdivtd, floaddd, floadsd, fmuldd, fmultd,
419 fsimpdd, fsimpsd, fsimptd, fstoredd, fstoresd,
420 ftoidfp, other"
421 (cond [(eq_attr "op_type" "NN") (const_string "other")
422 (eq_attr "op_type" "SS") (const_string "cs")]
423 (const_string "integer")))
424
425 ;; Another attribute used for scheduling purposes:
426 ;; agen: Instruction uses the address generation unit
427 ;; reg: Instruction does not use the agen unit
428
429 (define_attr "atype" "agen,reg"
430 (if_then_else (eq_attr "op_type" "E,RR,RI,RRE,RSI,RIL,RIE,RRF")
431 (const_string "reg")
432 (const_string "agen")))
433
434 ;; Properties concerning Z10 execution grouping and value forwarding.
435 ;; z10_super: instruction is superscalar.
436 ;; z10_super_c: instruction is superscalar and meets the condition of z10_c.
437 ;; z10_fwd: The instruction reads the value of an operand and stores it into a
438 ;; target register. It can forward this value to a second instruction that reads
439 ;; the same register if that second instruction is issued in the same group.
440 ;; z10_rec: The instruction is in the T pipeline and reads a register. If the
441 ;; instruction in the S pipe writes to the register, then the T instruction
442 ;; can immediately read the new value.
443 ;; z10_fr: union of Z10_fwd and z10_rec.
444 ;; z10_c: second operand of instruction is a register and read with complemented bits.
445 ;;
446 ;; An additional suffix A1, A3, or E1 indicates the respective AGI bypass.
447
448
449 (define_attr "z10prop" "none,
450 z10_super, z10_super_E1, z10_super_A1, z10_super_c, z10_super_c_E1,
451 z10_fwd, z10_fwd_A1, z10_fwd_A3, z10_fwd_E1,
452 z10_rec,
453 z10_fr, z10_fr_A3, z10_fr_E1,
454 z10_c"
455 (const_string "none"))
456
457 ;; Properties concerning Z196 decoding
458 ;; z196_alone: must group alone
459 ;; z196_end: ends a group
460 ;; z196_cracked: instruction is cracked or expanded
461 (define_attr "z196prop" "none,
462 z196_alone, z196_ends,
463 z196_cracked"
464 (const_string "none"))
465
466 (define_attr "mnemonic" "bcr_flush,unknown" (const_string "unknown"))
467
468 ;; Length in bytes.
469
470 (define_attr "length" ""
471 (cond [(eq_attr "op_type" "E,RR") (const_int 2)
472 (eq_attr "op_type" "RX,RI,RRE,RS,RSI,S,SI,RRF") (const_int 4)]
473 (const_int 6)))
474
475
476 ;; Processor type. This attribute must exactly match the processor_type
477 ;; enumeration in s390.h. The current machine description does not
478 ;; distinguish between g5 and g6, but there are differences between the two
479 ;; CPUs could in theory be modeled.
480
481 (define_attr "cpu" "g5,g6,z900,z990,z9_109,z9_ec,z10,z196,zEC12,z13"
482 (const (symbol_ref "s390_tune_attr")))
483
484 (define_attr "cpu_facility"
485 "standard,ieee,zarch,cpu_zarch,longdisp,extimm,dfp,z10,z196,zEC12,vx,z13"
486 (const_string "standard"))
487
488 (define_attr "enabled" ""
489 (cond [(eq_attr "cpu_facility" "standard")
490 (const_int 1)
491
492 (and (eq_attr "cpu_facility" "ieee")
493 (match_test "TARGET_CPU_IEEE_FLOAT"))
494 (const_int 1)
495
496 (and (eq_attr "cpu_facility" "zarch")
497 (match_test "TARGET_ZARCH"))
498 (const_int 1)
499
500 (and (eq_attr "cpu_facility" "longdisp")
501 (match_test "TARGET_LONG_DISPLACEMENT"))
502 (const_int 1)
503
504 (and (eq_attr "cpu_facility" "extimm")
505 (match_test "TARGET_EXTIMM"))
506 (const_int 1)
507
508 (and (eq_attr "cpu_facility" "dfp")
509 (match_test "TARGET_DFP"))
510 (const_int 1)
511
512 (and (eq_attr "cpu_facility" "cpu_zarch")
513 (match_test "TARGET_CPU_ZARCH"))
514 (const_int 1)
515
516 (and (eq_attr "cpu_facility" "z10")
517 (match_test "TARGET_Z10"))
518 (const_int 1)
519
520 (and (eq_attr "cpu_facility" "z196")
521 (match_test "TARGET_Z196"))
522 (const_int 1)
523
524 (and (eq_attr "cpu_facility" "zEC12")
525 (match_test "TARGET_ZEC12"))
526 (const_int 1)
527
528 (and (eq_attr "cpu_facility" "vx")
529 (match_test "TARGET_VX"))
530 (const_int 1)
531
532 (and (eq_attr "cpu_facility" "z13")
533 (match_test "TARGET_Z13"))
534 (const_int 1)
535 ]
536 (const_int 0)))
537
538 ;; Pipeline description for z900. For lack of anything better,
539 ;; this description is also used for the g5 and g6.
540 (include "2064.md")
541
542 ;; Pipeline description for z990, z9-109 and z9-ec.
543 (include "2084.md")
544
545 ;; Pipeline description for z10
546 (include "2097.md")
547
548 ;; Pipeline description for z196
549 (include "2817.md")
550
551 ;; Pipeline description for zEC12
552 (include "2827.md")
553
554 ;; Pipeline description for z13
555 (include "2964.md")
556
557 ;; Predicates
558 (include "predicates.md")
559
560 ;; Constraint definitions
561 (include "constraints.md")
562
563 ;; Other includes
564 (include "tpf.md")
565
566 ;; Iterators
567
568 (define_mode_iterator ALL [TI DI SI HI QI TF DF SF TD DD SD V1QI V2QI V4QI V8QI V16QI V1HI V2HI V4HI V8HI V1SI V2SI V4SI V1DI V2DI V1SF V2SF V4SF V1TI V1DF V2DF V1TF])
569
570 ;; These mode iterators allow floating point patterns to be generated from the
571 ;; same template.
572 (define_mode_iterator FP_ALL [TF DF SF (TD "TARGET_HARD_DFP") (DD "TARGET_HARD_DFP")
573 (SD "TARGET_HARD_DFP")])
574 (define_mode_iterator FP [TF DF SF (TD "TARGET_HARD_DFP") (DD "TARGET_HARD_DFP")])
575 (define_mode_iterator BFP [TF DF SF])
576 (define_mode_iterator DFP [TD DD])
577 (define_mode_iterator DFP_ALL [TD DD SD])
578 (define_mode_iterator DSF [DF SF])
579 (define_mode_iterator SD_SF [SF SD])
580 (define_mode_iterator DD_DF [DF DD])
581 (define_mode_iterator TD_TF [TF TD])
582
583 ;; These mode iterators allow 31-bit and 64-bit GPR patterns to be generated
584 ;; from the same template.
585 (define_mode_iterator GPR [(DI "TARGET_ZARCH") SI])
586 (define_mode_iterator DGPR [(TI "TARGET_ZARCH") DI SI])
587 (define_mode_iterator DSI [DI SI])
588 (define_mode_iterator TDI [TI DI])
589
590 ;; These mode iterators allow :P to be used for patterns that operate on
591 ;; pointer-sized quantities. Exactly one of the two alternatives will match.
592 (define_mode_iterator P [(DI "TARGET_64BIT") (SI "!TARGET_64BIT")])
593
594 ;; These macros refer to the actual word_mode of the configuration.
595 ;; This is equal to Pmode except on 31-bit machines in zarch mode.
596 (define_mode_iterator DW [(TI "TARGET_ZARCH") (DI "!TARGET_ZARCH")])
597 (define_mode_iterator W [(DI "TARGET_ZARCH") (SI "!TARGET_ZARCH")])
598
599 ;; Used by the umul pattern to express modes having half the size.
600 (define_mode_attr DWH [(TI "DI") (DI "SI")])
601 (define_mode_attr dwh [(TI "di") (DI "si")])
602
603 ;; This mode iterator allows the QI and HI patterns to be defined from
604 ;; the same template.
605 (define_mode_iterator HQI [HI QI])
606
607 ;; This mode iterator allows the integer patterns to be defined from the
608 ;; same template.
609 (define_mode_iterator INT [(DI "TARGET_ZARCH") SI HI QI])
610 (define_mode_iterator DINT [(TI "TARGET_ZARCH") DI SI HI QI])
611 (define_mode_iterator SINT [SI HI QI])
612
613 ;; This iterator allows some 'ashift' and 'lshiftrt' pattern to be defined from
614 ;; the same template.
615 (define_code_iterator SHIFT [ashift lshiftrt])
616
617 ;; This iterator allows r[ox]sbg to be defined with the same template
618 (define_code_iterator IXOR [ior xor])
619
620 ;; This iterator is used to expand the patterns for the nearest
621 ;; integer functions.
622 (define_int_iterator FPINT [UNSPEC_FPINT_FLOOR UNSPEC_FPINT_BTRUNC
623 UNSPEC_FPINT_ROUND UNSPEC_FPINT_CEIL
624 UNSPEC_FPINT_NEARBYINT])
625 (define_int_attr fpint_name [(UNSPEC_FPINT_FLOOR "floor")
626 (UNSPEC_FPINT_BTRUNC "btrunc")
627 (UNSPEC_FPINT_ROUND "round")
628 (UNSPEC_FPINT_CEIL "ceil")
629 (UNSPEC_FPINT_NEARBYINT "nearbyint")])
630 (define_int_attr fpint_roundingmode [(UNSPEC_FPINT_FLOOR "7")
631 (UNSPEC_FPINT_BTRUNC "5")
632 (UNSPEC_FPINT_ROUND "1")
633 (UNSPEC_FPINT_CEIL "6")
634 (UNSPEC_FPINT_NEARBYINT "0")])
635
636 ;; This iterator and attribute allow to combine most atomic operations.
637 (define_code_iterator ATOMIC [and ior xor plus minus mult])
638 (define_code_iterator ATOMIC_Z196 [and ior xor plus])
639 (define_code_attr atomic [(and "and") (ior "or") (xor "xor")
640 (plus "add") (minus "sub") (mult "nand")])
641 (define_code_attr noxa [(and "n") (ior "o") (xor "x") (plus "a")])
642
643 ;; In FP templates, a string like "lt<de>br" will expand to "ltxbr" in
644 ;; TF/TDmode, "ltdbr" in DF/DDmode, and "ltebr" in SF/SDmode.
645 (define_mode_attr xde [(TF "x") (DF "d") (SF "e") (TD "x") (DD "d") (SD "e")])
646
647 ;; In FP templates, a <dee> in "m<dee><bt>r" will expand to "mx<bt>r" in
648 ;; TF/TDmode, "md<bt>r" in DF/DDmode, "mee<bt>r" in SFmode and "me<bt>r in
649 ;; SDmode.
650 (define_mode_attr xdee [(TF "x") (DF "d") (SF "ee") (TD "x") (DD "d") (SD "e")])
651
652 ;; In FP templates, "<RRe>" will expand to "RRE" in TFmode and "RR" otherwise.
653 ;; Likewise for "<RXe>".
654 (define_mode_attr RRe [(TF "RRE") (DF "RR") (SF "RR")])
655 (define_mode_attr RXe [(TF "RXE") (DF "RX") (SF "RX")])
656
657 ;; The decimal floating point variants of add, sub, div and mul support 3
658 ;; fp register operands. The following attributes allow to merge the bfp and
659 ;; dfp variants in a single insn definition.
660
661 ;; These mode attributes are supposed to be used in the `enabled' insn
662 ;; attribute to disable certain alternatives for certain modes.
663 (define_mode_attr nBFP [(TF "0") (DF "0") (SF "0") (TD "*") (DD "*") (DD "*")])
664 (define_mode_attr nDFP [(TF "*") (DF "*") (SF "*") (TD "0") (DD "0") (DD "0")])
665 (define_mode_attr DSF [(TF "0") (DF "*") (SF "*") (TD "0") (DD "0") (SD "0")])
666 (define_mode_attr DFDI [(TF "0") (DF "*") (SF "0")
667 (TD "0") (DD "0") (DD "0")
668 (TI "0") (DI "*") (SI "0")])
669
670 ;; This attribute is used in the operand constraint list
671 ;; for instructions dealing with the sign bit of 32 or 64bit fp values.
672 ;; TFmode values are represented by a fp register pair. Since the
673 ;; sign bit instructions only handle single source and target fp registers
674 ;; these instructions can only be used for TFmode values if the source and
675 ;; target operand uses the same fp register.
676 (define_mode_attr fT0 [(TF "0") (DF "f") (SF "f")])
677
678 ;; This attribute adds b for bfp instructions and t for dfp instructions and is used
679 ;; within instruction mnemonics.
680 (define_mode_attr bt [(TF "b") (DF "b") (SF "b") (TD "t") (DD "t") (SD "t")])
681
682 ;; This attribute is used within instruction mnemonics. It evaluates to d for dfp
683 ;; modes and to an empty string for bfp modes.
684 (define_mode_attr _d [(TF "") (DF "") (SF "") (TD "d") (DD "d") (SD "d")])
685
686 ;; In GPR and P templates, a constraint like "<d0>" will expand to "d" in DImode
687 ;; and "0" in SImode. This allows to combine instructions of which the 31bit
688 ;; version only operates on one register.
689 (define_mode_attr d0 [(DI "d") (SI "0")])
690
691 ;; In combination with d0 this allows to combine instructions of which the 31bit
692 ;; version only operates on one register. The DImode version needs an additional
693 ;; register for the assembler output.
694 (define_mode_attr 1 [(DI "%1,") (SI "")])
695
696 ;; In SHIFT templates, a string like "s<lr>dl" will expand to "sldl" in
697 ;; 'ashift' and "srdl" in 'lshiftrt'.
698 (define_code_attr lr [(ashift "l") (lshiftrt "r")])
699
700 ;; In SHIFT templates, this attribute holds the correct standard name for the
701 ;; pattern itself and the corresponding function calls.
702 (define_code_attr shift [(ashift "ashl") (lshiftrt "lshr")])
703
704 ;; This attribute handles differences in the instruction 'type' and will result
705 ;; in "RRE" for DImode and "RR" for SImode.
706 (define_mode_attr E [(DI "E") (SI "")])
707
708 ;; This attribute handles differences in the instruction 'type' and makes RX<Y>
709 ;; to result in "RXY" for DImode and "RX" for SImode.
710 (define_mode_attr Y [(DI "Y") (SI "")])
711
712 ;; This attribute handles differences in the instruction 'type' and will result
713 ;; in "RSE" for TImode and "RS" for DImode.
714 (define_mode_attr TE [(TI "E") (DI "")])
715
716 ;; In GPR templates, a string like "lc<g>r" will expand to "lcgr" in DImode
717 ;; and "lcr" in SImode.
718 (define_mode_attr g [(DI "g") (SI "")])
719
720 ;; In GPR templates, a string like "sl<y>" will expand to "slg" in DImode
721 ;; and "sly" in SImode. This is useful because on 64bit the ..g instructions
722 ;; were enhanced with long displacements whereas 31bit instructions got a ..y
723 ;; variant for long displacements.
724 (define_mode_attr y [(DI "g") (SI "y")])
725
726 ;; In DW templates, a string like "cds<g>" will expand to "cdsg" in TImode
727 ;; and "cds" in DImode.
728 (define_mode_attr tg [(TI "g") (DI "")])
729
730 ;; In TDI templates, a string like "c<d>sg".
731 (define_mode_attr td [(TI "d") (DI "")])
732
733 ;; In GPR templates, a string like "c<gf>dbr" will expand to "cgdbr" in DImode
734 ;; and "cfdbr" in SImode.
735 (define_mode_attr gf [(DI "g") (SI "f")])
736
737 ;; In GPR templates, a string like sll<gk> will expand to sllg for DI
738 ;; and sllk for SI. This way it is possible to merge the new z196 SI
739 ;; 3 operands shift instructions into the existing patterns.
740 (define_mode_attr gk [(DI "g") (SI "k")])
741
742 ;; ICM mask required to load MODE value into the lowest subreg
743 ;; of a SImode register.
744 (define_mode_attr icm_lo [(HI "3") (QI "1")])
745
746 ;; In HQI templates, a string like "llg<hc>" will expand to "llgh" in
747 ;; HImode and "llgc" in QImode.
748 (define_mode_attr hc [(HI "h") (QI "c")])
749
750 ;; In P templates, the mode <DBL> will expand to "TI" in DImode and "DI"
751 ;; in SImode.
752 (define_mode_attr DBL [(DI "TI") (SI "DI")])
753
754 ;; This attribute expands to DF for TFmode and to DD for TDmode . It is
755 ;; used for Txmode splitters splitting a Txmode copy into 2 Dxmode copies.
756 (define_mode_attr HALF_TMODE [(TF "DF") (TD "DD")])
757
758 ;; Maximum unsigned integer that fits in MODE.
759 (define_mode_attr max_uint [(HI "65535") (QI "255")])
760
761 ;; Start and end field computations for RISBG et al.
762 (define_mode_attr bfstart [(DI "s") (SI "t")])
763 (define_mode_attr bfend [(DI "e") (SI "f")])
764
765 ;; In place of GET_MODE_BITSIZE (<MODE>mode)
766 (define_mode_attr bitsize [(DI "64") (SI "32") (HI "16") (QI "8")])
767 ;; 64 - bitsize
768 (define_mode_attr bitoff [(DI "0") (SI "32") (HI "48") (QI "56")])
769 (define_mode_attr bitoff_plus [(DI "") (SI "32+") (HI "48+") (QI "56+")])
770
771 ;; In place of GET_MODE_SIZE (<MODE>mode)
772 (define_mode_attr modesize [(DI "8") (SI "4")])
773
774 ;; Allow return and simple_return to be defined from a single template.
775 (define_code_iterator ANY_RETURN [return simple_return])
776
777
778
779 ; Condition code modes generated by vector fp comparisons. These will
780 ; be used also in single element mode.
781 (define_mode_iterator VFCMP [CCVEQ CCVFH CCVFHE])
782 ; Used with VFCMP to expand part of the mnemonic
783 ; For fp we have a mismatch: eq in the insn name - e in asm
784 (define_mode_attr asm_fcmp [(CCVEQ "e") (CCVFH "h") (CCVFHE "he")])
785 (define_mode_attr insn_cmp [(CCVEQ "eq") (CCVIH "h") (CCVIHU "hl") (CCVFH "h") (CCVFHE "he")])
786
787 ;; Subst pattern definitions
788 (include "subst.md")
789
790 (include "vector.md")
791
792 ;;
793 ;;- Compare instructions.
794 ;;
795
796 ; Test-under-Mask instructions
797
798 (define_insn "*tmqi_mem"
799 [(set (reg CC_REGNUM)
800 (compare (and:QI (match_operand:QI 0 "memory_operand" "Q,S")
801 (match_operand:QI 1 "immediate_operand" "n,n"))
802 (match_operand:QI 2 "immediate_operand" "n,n")))]
803 "s390_match_ccmode (insn, s390_tm_ccmode (operands[1], operands[2], false))"
804 "@
805 tm\t%S0,%b1
806 tmy\t%S0,%b1"
807 [(set_attr "op_type" "SI,SIY")
808 (set_attr "cpu_facility" "*,longdisp")
809 (set_attr "z10prop" "z10_super,z10_super")])
810
811 (define_insn "*tmdi_reg"
812 [(set (reg CC_REGNUM)
813 (compare (and:DI (match_operand:DI 0 "nonimmediate_operand" "d,d,d,d")
814 (match_operand:DI 1 "immediate_operand"
815 "N0HD0,N1HD0,N2HD0,N3HD0"))
816 (match_operand:DI 2 "immediate_operand" "n,n,n,n")))]
817 "TARGET_ZARCH
818 && s390_match_ccmode (insn, s390_tm_ccmode (operands[1], operands[2], true))
819 && s390_single_part (operands[1], DImode, HImode, 0) >= 0"
820 "@
821 tmhh\t%0,%i1
822 tmhl\t%0,%i1
823 tmlh\t%0,%i1
824 tmll\t%0,%i1"
825 [(set_attr "op_type" "RI")
826 (set_attr "z10prop" "z10_super,z10_super,z10_super,z10_super")])
827
828 (define_insn "*tmsi_reg"
829 [(set (reg CC_REGNUM)
830 (compare (and:SI (match_operand:SI 0 "nonimmediate_operand" "d,d")
831 (match_operand:SI 1 "immediate_operand" "N0HS0,N1HS0"))
832 (match_operand:SI 2 "immediate_operand" "n,n")))]
833 "s390_match_ccmode (insn, s390_tm_ccmode (operands[1], operands[2], true))
834 && s390_single_part (operands[1], SImode, HImode, 0) >= 0"
835 "@
836 tmh\t%0,%i1
837 tml\t%0,%i1"
838 [(set_attr "op_type" "RI")
839 (set_attr "z10prop" "z10_super,z10_super")])
840
841 (define_insn "*tm<mode>_full"
842 [(set (reg CC_REGNUM)
843 (compare (match_operand:HQI 0 "register_operand" "d")
844 (match_operand:HQI 1 "immediate_operand" "n")))]
845 "s390_match_ccmode (insn, s390_tm_ccmode (constm1_rtx, operands[1], true))"
846 "tml\t%0,<max_uint>"
847 [(set_attr "op_type" "RI")
848 (set_attr "z10prop" "z10_super")])
849
850
851 ;
852 ; Load-and-Test instructions
853 ;
854
855 ; tst(di|si) instruction pattern(s).
856
857 (define_insn "*tstdi_sign"
858 [(set (reg CC_REGNUM)
859 (compare
860 (ashiftrt:DI
861 (ashift:DI
862 (subreg:DI (match_operand:SI 0 "nonimmediate_operand" "d,T") 0)
863 (const_int 32)) (const_int 32))
864 (match_operand:DI 1 "const0_operand" "")))
865 (set (match_operand:DI 2 "register_operand" "=d,d")
866 (sign_extend:DI (match_dup 0)))]
867 "s390_match_ccmode(insn, CCSmode) && TARGET_ZARCH"
868 "ltgfr\t%2,%0
869 ltgf\t%2,%0"
870 [(set_attr "op_type" "RRE,RXY")
871 (set_attr "cpu_facility" "*,z10")
872 (set_attr "z10prop" "z10_super_E1,z10_super_E1") ])
873
874 ; ltr, lt, ltgr, ltg
875 (define_insn "*tst<mode>_extimm"
876 [(set (reg CC_REGNUM)
877 (compare (match_operand:GPR 0 "nonimmediate_operand" "d,T")
878 (match_operand:GPR 1 "const0_operand" "")))
879 (set (match_operand:GPR 2 "register_operand" "=d,d")
880 (match_dup 0))]
881 "s390_match_ccmode(insn, CCSmode) && TARGET_EXTIMM"
882 "@
883 lt<g>r\t%2,%0
884 lt<g>\t%2,%0"
885 [(set_attr "op_type" "RR<E>,RXY")
886 (set_attr "z10prop" "z10_fr_E1,z10_fwd_A3") ])
887
888 ; ltr, lt, ltgr, ltg
889 (define_insn "*tst<mode>_cconly_extimm"
890 [(set (reg CC_REGNUM)
891 (compare (match_operand:GPR 0 "nonimmediate_operand" "d,T")
892 (match_operand:GPR 1 "const0_operand" "")))
893 (clobber (match_scratch:GPR 2 "=X,d"))]
894 "s390_match_ccmode(insn, CCSmode) && TARGET_EXTIMM"
895 "@
896 lt<g>r\t%0,%0
897 lt<g>\t%2,%0"
898 [(set_attr "op_type" "RR<E>,RXY")
899 (set_attr "z10prop" "z10_fr_E1,z10_fwd_A3")])
900
901 (define_insn "*tstdi"
902 [(set (reg CC_REGNUM)
903 (compare (match_operand:DI 0 "register_operand" "d")
904 (match_operand:DI 1 "const0_operand" "")))
905 (set (match_operand:DI 2 "register_operand" "=d")
906 (match_dup 0))]
907 "s390_match_ccmode(insn, CCSmode) && TARGET_ZARCH && !TARGET_EXTIMM"
908 "ltgr\t%2,%0"
909 [(set_attr "op_type" "RRE")
910 (set_attr "z10prop" "z10_fr_E1")])
911
912 (define_insn "*tstsi"
913 [(set (reg CC_REGNUM)
914 (compare (match_operand:SI 0 "nonimmediate_operand" "d,Q,S")
915 (match_operand:SI 1 "const0_operand" "")))
916 (set (match_operand:SI 2 "register_operand" "=d,d,d")
917 (match_dup 0))]
918 "s390_match_ccmode(insn, CCSmode) && !TARGET_EXTIMM"
919 "@
920 ltr\t%2,%0
921 icm\t%2,15,%S0
922 icmy\t%2,15,%S0"
923 [(set_attr "op_type" "RR,RS,RSY")
924 (set_attr "cpu_facility" "*,*,longdisp")
925 (set_attr "z10prop" "z10_fr_E1,z10_super_E1,z10_super_E1")])
926
927 (define_insn "*tstsi_cconly"
928 [(set (reg CC_REGNUM)
929 (compare (match_operand:SI 0 "nonimmediate_operand" "d,Q,S")
930 (match_operand:SI 1 "const0_operand" "")))
931 (clobber (match_scratch:SI 2 "=X,d,d"))]
932 "s390_match_ccmode(insn, CCSmode)"
933 "@
934 ltr\t%0,%0
935 icm\t%2,15,%S0
936 icmy\t%2,15,%S0"
937 [(set_attr "op_type" "RR,RS,RSY")
938 (set_attr "cpu_facility" "*,*,longdisp")
939 (set_attr "z10prop" "z10_fr_E1,z10_super_E1,z10_super_E1")])
940
941 (define_insn "*tstdi_cconly_31"
942 [(set (reg CC_REGNUM)
943 (compare (match_operand:DI 0 "register_operand" "d")
944 (match_operand:DI 1 "const0_operand" "")))]
945 "s390_match_ccmode(insn, CCSmode) && !TARGET_ZARCH"
946 "srda\t%0,0"
947 [(set_attr "op_type" "RS")
948 (set_attr "atype" "reg")])
949
950 ; ltr, ltgr
951 (define_insn "*tst<mode>_cconly2"
952 [(set (reg CC_REGNUM)
953 (compare (match_operand:GPR 0 "register_operand" "d")
954 (match_operand:GPR 1 "const0_operand" "")))]
955 "s390_match_ccmode(insn, CCSmode)"
956 "lt<g>r\t%0,%0"
957 [(set_attr "op_type" "RR<E>")
958 (set_attr "z10prop" "z10_fr_E1")])
959
960 ; tst(hi|qi) instruction pattern(s).
961
962 (define_insn "*tst<mode>CCT"
963 [(set (reg CC_REGNUM)
964 (compare (match_operand:HQI 0 "nonimmediate_operand" "?Q,?S,d")
965 (match_operand:HQI 1 "const0_operand" "")))
966 (set (match_operand:HQI 2 "register_operand" "=d,d,0")
967 (match_dup 0))]
968 "s390_match_ccmode(insn, CCTmode)"
969 "@
970 icm\t%2,<icm_lo>,%S0
971 icmy\t%2,<icm_lo>,%S0
972 tml\t%0,<max_uint>"
973 [(set_attr "op_type" "RS,RSY,RI")
974 (set_attr "cpu_facility" "*,longdisp,*")
975 (set_attr "z10prop" "z10_super_E1,z10_super_E1,z10_super")])
976
977 (define_insn "*tsthiCCT_cconly"
978 [(set (reg CC_REGNUM)
979 (compare (match_operand:HI 0 "nonimmediate_operand" "Q,S,d")
980 (match_operand:HI 1 "const0_operand" "")))
981 (clobber (match_scratch:HI 2 "=d,d,X"))]
982 "s390_match_ccmode(insn, CCTmode)"
983 "@
984 icm\t%2,3,%S0
985 icmy\t%2,3,%S0
986 tml\t%0,65535"
987 [(set_attr "op_type" "RS,RSY,RI")
988 (set_attr "cpu_facility" "*,longdisp,*")
989 (set_attr "z10prop" "z10_super_E1,z10_super_E1,z10_super")])
990
991 (define_insn "*tstqiCCT_cconly"
992 [(set (reg CC_REGNUM)
993 (compare (match_operand:QI 0 "nonimmediate_operand" "?Q,?S,d")
994 (match_operand:QI 1 "const0_operand" "")))]
995 "s390_match_ccmode(insn, CCTmode)"
996 "@
997 cli\t%S0,0
998 cliy\t%S0,0
999 tml\t%0,255"
1000 [(set_attr "op_type" "SI,SIY,RI")
1001 (set_attr "cpu_facility" "*,longdisp,*")
1002 (set_attr "z10prop" "z10_super,z10_super,z10_super")])
1003
1004 (define_insn "*tst<mode>"
1005 [(set (reg CC_REGNUM)
1006 (compare (match_operand:HQI 0 "s_operand" "Q,S")
1007 (match_operand:HQI 1 "const0_operand" "")))
1008 (set (match_operand:HQI 2 "register_operand" "=d,d")
1009 (match_dup 0))]
1010 "s390_match_ccmode(insn, CCSmode)"
1011 "@
1012 icm\t%2,<icm_lo>,%S0
1013 icmy\t%2,<icm_lo>,%S0"
1014 [(set_attr "op_type" "RS,RSY")
1015 (set_attr "cpu_facility" "*,longdisp")
1016 (set_attr "z10prop" "z10_super_E1,z10_super_E1")])
1017
1018 (define_insn "*tst<mode>_cconly"
1019 [(set (reg CC_REGNUM)
1020 (compare (match_operand:HQI 0 "s_operand" "Q,S")
1021 (match_operand:HQI 1 "const0_operand" "")))
1022 (clobber (match_scratch:HQI 2 "=d,d"))]
1023 "s390_match_ccmode(insn, CCSmode)"
1024 "@
1025 icm\t%2,<icm_lo>,%S0
1026 icmy\t%2,<icm_lo>,%S0"
1027 [(set_attr "op_type" "RS,RSY")
1028 (set_attr "cpu_facility" "*,longdisp")
1029 (set_attr "z10prop" "z10_super_E1,z10_super_E1")])
1030
1031
1032 ; Compare (equality) instructions
1033
1034 (define_insn "*cmpdi_cct"
1035 [(set (reg CC_REGNUM)
1036 (compare (match_operand:DI 0 "nonimmediate_operand" "%d,d,d,d,Q")
1037 (match_operand:DI 1 "general_operand" "d,K,Os,T,BQ")))]
1038 "s390_match_ccmode (insn, CCTmode) && TARGET_ZARCH"
1039 "@
1040 cgr\t%0,%1
1041 cghi\t%0,%h1
1042 cgfi\t%0,%1
1043 cg\t%0,%1
1044 #"
1045 [(set_attr "op_type" "RRE,RI,RIL,RXY,SS")
1046 (set_attr "z10prop" "z10_super_c,z10_super,z10_super,z10_super,*")])
1047
1048 (define_insn "*cmpsi_cct"
1049 [(set (reg CC_REGNUM)
1050 (compare (match_operand:SI 0 "nonimmediate_operand" "%d,d,d,d,d,Q")
1051 (match_operand:SI 1 "general_operand" "d,K,Os,R,T,BQ")))]
1052 "s390_match_ccmode (insn, CCTmode)"
1053 "@
1054 cr\t%0,%1
1055 chi\t%0,%h1
1056 cfi\t%0,%1
1057 c\t%0,%1
1058 cy\t%0,%1
1059 #"
1060 [(set_attr "op_type" "RR,RI,RIL,RX,RXY,SS")
1061 (set_attr "cpu_facility" "*,*,*,*,longdisp,*")
1062 (set_attr "z10prop" "z10_super_c,z10_super,z10_super,z10_super,z10_super,*")])
1063
1064 ; Compare (signed) instructions
1065
1066 (define_insn "*cmpdi_ccs_sign"
1067 [(set (reg CC_REGNUM)
1068 (compare (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand"
1069 "d,T,b"))
1070 (match_operand:DI 0 "register_operand" "d, d,d")))]
1071 "s390_match_ccmode(insn, CCSRmode) && TARGET_ZARCH"
1072 "@
1073 cgfr\t%0,%1
1074 cgf\t%0,%1
1075 cgfrl\t%0,%1"
1076 [(set_attr "op_type" "RRE,RXY,RIL")
1077 (set_attr "z10prop" "z10_c,*,*")
1078 (set_attr "type" "*,*,larl")])
1079
1080
1081
1082 (define_insn "*cmpsi_ccs_sign"
1083 [(set (reg CC_REGNUM)
1084 (compare (sign_extend:SI (match_operand:HI 1 "memory_operand" "R,T,b"))
1085 (match_operand:SI 0 "register_operand" "d,d,d")))]
1086 "s390_match_ccmode(insn, CCSRmode)"
1087 "@
1088 ch\t%0,%1
1089 chy\t%0,%1
1090 chrl\t%0,%1"
1091 [(set_attr "op_type" "RX,RXY,RIL")
1092 (set_attr "cpu_facility" "*,longdisp,z10")
1093 (set_attr "type" "*,*,larl")
1094 (set_attr "z196prop" "z196_cracked,z196_cracked,z196_cracked")])
1095
1096 (define_insn "*cmphi_ccs_z10"
1097 [(set (reg CC_REGNUM)
1098 (compare (match_operand:HI 0 "s_operand" "Q")
1099 (match_operand:HI 1 "immediate_operand" "K")))]
1100 "s390_match_ccmode(insn, CCSmode) && TARGET_Z10"
1101 "chhsi\t%0,%1"
1102 [(set_attr "op_type" "SIL")
1103 (set_attr "z196prop" "z196_cracked")])
1104
1105 (define_insn "*cmpdi_ccs_signhi_rl"
1106 [(set (reg CC_REGNUM)
1107 (compare (sign_extend:DI (match_operand:HI 1 "memory_operand" "T,b"))
1108 (match_operand:GPR 0 "register_operand" "d,d")))]
1109 "s390_match_ccmode(insn, CCSRmode) && TARGET_Z10"
1110 "@
1111 cgh\t%0,%1
1112 cghrl\t%0,%1"
1113 [(set_attr "op_type" "RXY,RIL")
1114 (set_attr "type" "*,larl")])
1115
1116 ; cr, chi, cfi, c, cy, cgr, cghi, cgfi, cg, chsi, cghsi, crl, cgrl
1117 (define_insn "*cmp<mode>_ccs"
1118 [(set (reg CC_REGNUM)
1119 (compare (match_operand:GPR 0 "nonimmediate_operand"
1120 "d,d,Q, d,d,d,d")
1121 (match_operand:GPR 1 "general_operand"
1122 "d,K,K,Os,R,T,b")))]
1123 "s390_match_ccmode(insn, CCSmode)"
1124 "@
1125 c<g>r\t%0,%1
1126 c<g>hi\t%0,%h1
1127 c<g>hsi\t%0,%h1
1128 c<g>fi\t%0,%1
1129 c<g>\t%0,%1
1130 c<y>\t%0,%1
1131 c<g>rl\t%0,%1"
1132 [(set_attr "op_type" "RR<E>,RI,SIL,RIL,RX<Y>,RXY,RIL")
1133 (set_attr "cpu_facility" "*,*,z10,extimm,*,longdisp,z10")
1134 (set_attr "type" "*,*,*,*,*,*,larl")
1135 (set_attr "z10prop" "z10_super_c,z10_super,z10_super,z10_super,z10_super,z10_super,z10_super")])
1136
1137
1138 ; Compare (unsigned) instructions
1139
1140 (define_insn "*cmpsi_ccu_zerohi_rlsi"
1141 [(set (reg CC_REGNUM)
1142 (compare (zero_extend:SI (mem:HI (match_operand:SI 1
1143 "larl_operand" "X")))
1144 (match_operand:SI 0 "register_operand" "d")))]
1145 "s390_match_ccmode(insn, CCURmode) && TARGET_Z10"
1146 "clhrl\t%0,%1"
1147 [(set_attr "op_type" "RIL")
1148 (set_attr "type" "larl")
1149 (set_attr "z10prop" "z10_super")])
1150
1151 ; clhrl, clghrl
1152 (define_insn "*cmp<GPR:mode>_ccu_zerohi_rldi"
1153 [(set (reg CC_REGNUM)
1154 (compare (zero_extend:GPR (mem:HI (match_operand:DI 1
1155 "larl_operand" "X")))
1156 (match_operand:GPR 0 "register_operand" "d")))]
1157 "s390_match_ccmode(insn, CCURmode) && TARGET_Z10"
1158 "cl<g>hrl\t%0,%1"
1159 [(set_attr "op_type" "RIL")
1160 (set_attr "type" "larl")
1161 (set_attr "z10prop" "z10_super")])
1162
1163 (define_insn "*cmpdi_ccu_zero"
1164 [(set (reg CC_REGNUM)
1165 (compare (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand"
1166 "d,T,b"))
1167 (match_operand:DI 0 "register_operand" "d,d,d")))]
1168 "s390_match_ccmode (insn, CCURmode) && TARGET_ZARCH"
1169 "@
1170 clgfr\t%0,%1
1171 clgf\t%0,%1
1172 clgfrl\t%0,%1"
1173 [(set_attr "op_type" "RRE,RXY,RIL")
1174 (set_attr "cpu_facility" "*,*,z10")
1175 (set_attr "type" "*,*,larl")
1176 (set_attr "z10prop" "z10_super_c,z10_super_E1,z10_super")])
1177
1178 (define_insn "*cmpdi_ccu"
1179 [(set (reg CC_REGNUM)
1180 (compare (match_operand:DI 0 "nonimmediate_operand"
1181 "d, d,d,Q,d, Q,BQ")
1182 (match_operand:DI 1 "general_operand"
1183 "d,Op,b,D,T,BQ,Q")))]
1184 "s390_match_ccmode (insn, CCUmode) && TARGET_ZARCH"
1185 "@
1186 clgr\t%0,%1
1187 clgfi\t%0,%1
1188 clgrl\t%0,%1
1189 clghsi\t%0,%x1
1190 clg\t%0,%1
1191 #
1192 #"
1193 [(set_attr "op_type" "RRE,RIL,RIL,SIL,RXY,SS,SS")
1194 (set_attr "cpu_facility" "*,extimm,z10,z10,*,*,*")
1195 (set_attr "type" "*,*,larl,*,*,*,*")
1196 (set_attr "z10prop" "z10_super_c,z10_super,z10_super,z10_super,z10_super,*,*")])
1197
1198 (define_insn "*cmpsi_ccu"
1199 [(set (reg CC_REGNUM)
1200 (compare (match_operand:SI 0 "nonimmediate_operand" "d, d,d,Q,d,d, Q,BQ")
1201 (match_operand:SI 1 "general_operand" "d,Os,b,D,R,T,BQ, Q")))]
1202 "s390_match_ccmode (insn, CCUmode)"
1203 "@
1204 clr\t%0,%1
1205 clfi\t%0,%o1
1206 clrl\t%0,%1
1207 clfhsi\t%0,%x1
1208 cl\t%0,%1
1209 cly\t%0,%1
1210 #
1211 #"
1212 [(set_attr "op_type" "RR,RIL,RIL,SIL,RX,RXY,SS,SS")
1213 (set_attr "cpu_facility" "*,extimm,z10,z10,*,longdisp,*,*")
1214 (set_attr "type" "*,*,larl,*,*,*,*,*")
1215 (set_attr "z10prop" "z10_super_c,z10_super,z10_super,z10_super,z10_super,z10_super,*,*")])
1216
1217 (define_insn "*cmphi_ccu"
1218 [(set (reg CC_REGNUM)
1219 (compare (match_operand:HI 0 "nonimmediate_operand" "d,d,Q,Q,BQ")
1220 (match_operand:HI 1 "general_operand" "Q,S,D,BQ,Q")))]
1221 "s390_match_ccmode (insn, CCUmode)
1222 && !register_operand (operands[1], HImode)"
1223 "@
1224 clm\t%0,3,%S1
1225 clmy\t%0,3,%S1
1226 clhhsi\t%0,%1
1227 #
1228 #"
1229 [(set_attr "op_type" "RS,RSY,SIL,SS,SS")
1230 (set_attr "cpu_facility" "*,longdisp,z10,*,*")
1231 (set_attr "z10prop" "*,*,z10_super,*,*")])
1232
1233 (define_insn "*cmpqi_ccu"
1234 [(set (reg CC_REGNUM)
1235 (compare (match_operand:QI 0 "nonimmediate_operand" "d,d,Q,S,Q,BQ")
1236 (match_operand:QI 1 "general_operand" "Q,S,n,n,BQ,Q")))]
1237 "s390_match_ccmode (insn, CCUmode)
1238 && !register_operand (operands[1], QImode)"
1239 "@
1240 clm\t%0,1,%S1
1241 clmy\t%0,1,%S1
1242 cli\t%S0,%b1
1243 cliy\t%S0,%b1
1244 #
1245 #"
1246 [(set_attr "op_type" "RS,RSY,SI,SIY,SS,SS")
1247 (set_attr "cpu_facility" "*,longdisp,*,longdisp,*,*")
1248 (set_attr "z10prop" "*,*,z10_super,z10_super,*,*")])
1249
1250
1251 ; Block compare (CLC) instruction patterns.
1252
1253 (define_insn "*clc"
1254 [(set (reg CC_REGNUM)
1255 (compare (match_operand:BLK 0 "memory_operand" "Q")
1256 (match_operand:BLK 1 "memory_operand" "Q")))
1257 (use (match_operand 2 "const_int_operand" "n"))]
1258 "s390_match_ccmode (insn, CCUmode)
1259 && INTVAL (operands[2]) >= 1 && INTVAL (operands[2]) <= 256"
1260 "clc\t%O0(%2,%R0),%S1"
1261 [(set_attr "op_type" "SS")])
1262
1263 (define_split
1264 [(set (reg CC_REGNUM)
1265 (compare (match_operand 0 "memory_operand" "")
1266 (match_operand 1 "memory_operand" "")))]
1267 "reload_completed
1268 && s390_match_ccmode (insn, CCUmode)
1269 && GET_MODE (operands[0]) == GET_MODE (operands[1])
1270 && GET_MODE_SIZE (GET_MODE (operands[0])) > 0"
1271 [(parallel
1272 [(set (match_dup 0) (match_dup 1))
1273 (use (match_dup 2))])]
1274 {
1275 operands[2] = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[0])));
1276 operands[0] = adjust_address (operands[0], BLKmode, 0);
1277 operands[1] = adjust_address (operands[1], BLKmode, 0);
1278
1279 operands[1] = gen_rtx_COMPARE (GET_MODE (SET_DEST (PATTERN (curr_insn))),
1280 operands[0], operands[1]);
1281 operands[0] = SET_DEST (PATTERN (curr_insn));
1282 })
1283
1284
1285 ; (TF|DF|SF|TD|DD|SD) instructions
1286
1287
1288 ; load and test instructions turn SNaN into QNaN what is not
1289 ; acceptable if the target will be used afterwards. On the other hand
1290 ; they are quite convenient for implementing comparisons with 0.0. So
1291 ; try to enable them via splitter if the value isn't needed anymore.
1292
1293 ; ltxbr, ltdbr, ltebr, ltxtr, ltdtr
1294 (define_insn "*cmp<mode>_ccs_0"
1295 [(set (reg CC_REGNUM)
1296 (compare (match_operand:FP 0 "register_operand" "f")
1297 (match_operand:FP 1 "const0_operand" "")))
1298 (clobber (match_operand:FP 2 "register_operand" "=0"))]
1299 "s390_match_ccmode(insn, CCSmode) && TARGET_HARD_FLOAT"
1300 "lt<xde><bt>r\t%0,%0"
1301 [(set_attr "op_type" "RRE")
1302 (set_attr "type" "fsimp<mode>")])
1303
1304 (define_split
1305 [(set (match_operand 0 "cc_reg_operand")
1306 (compare (match_operand:FP 1 "register_operand")
1307 (match_operand:FP 2 "const0_operand")))]
1308 "TARGET_HARD_FLOAT && REG_P (operands[1]) && dead_or_set_p (insn, operands[1])"
1309 [(parallel
1310 [(set (match_dup 0) (match_dup 3))
1311 (clobber (match_dup 1))])]
1312 {
1313 /* s390_match_ccmode requires the compare to have the same CC mode
1314 as the CC destination register. */
1315 operands[3] = gen_rtx_COMPARE (GET_MODE (operands[0]),
1316 operands[1], operands[2]);
1317 })
1318
1319
1320 ; cxtr, cxbr, cdtr, cdbr, cebr, cdb, ceb
1321 (define_insn "*cmp<mode>_ccs"
1322 [(set (reg CC_REGNUM)
1323 (compare (match_operand:FP 0 "register_operand" "f,f")
1324 (match_operand:FP 1 "general_operand" "f,R")))]
1325 "s390_match_ccmode(insn, CCSmode) && TARGET_HARD_FLOAT"
1326 "@
1327 c<xde><bt>r\t%0,%1
1328 c<xde>b\t%0,%1"
1329 [(set_attr "op_type" "RRE,RXE")
1330 (set_attr "type" "fsimp<mode>")
1331 (set_attr "enabled" "*,<DSF>")])
1332
1333 ; wfcedbs, wfchdbs, wfchedbs
1334 (define_insn "*vec_cmp<insn_cmp>df_cconly"
1335 [(set (reg:VFCMP CC_REGNUM)
1336 (compare:VFCMP (match_operand:DF 0 "register_operand" "v")
1337 (match_operand:DF 1 "register_operand" "v")))
1338 (clobber (match_scratch:V2DI 2 "=v"))]
1339 "TARGET_VX && TARGET_HARD_FLOAT"
1340 "wfc<asm_fcmp>dbs\t%v2,%v0,%v1"
1341 [(set_attr "op_type" "VRR")])
1342
1343 ; Compare and Branch instructions
1344
1345 ; cij, cgij, crj, cgrj, cfi, cgfi, cr, cgr
1346 ; The following instructions do a complementary access of their second
1347 ; operand (z01 only): crj_c, cgrjc, cr, cgr
1348 (define_insn "*cmp_and_br_signed_<mode>"
1349 [(set (pc)
1350 (if_then_else (match_operator 0 "s390_signed_integer_comparison"
1351 [(match_operand:GPR 1 "register_operand" "d,d")
1352 (match_operand:GPR 2 "nonmemory_operand" "d,C")])
1353 (label_ref (match_operand 3 "" ""))
1354 (pc)))
1355 (clobber (reg:CC CC_REGNUM))]
1356 "TARGET_Z10 && !TARGET_AVOID_CMP_AND_BRANCH"
1357 {
1358 if (get_attr_length (insn) == 6)
1359 return which_alternative ?
1360 "c<g>ij%C0\t%1,%c2,%l3" : "c<g>rj%C0\t%1,%2,%l3";
1361 else
1362 return which_alternative ?
1363 "c<g>fi\t%1,%c2\;jg%C0\t%l3" : "c<g>r\t%1,%2\;jg%C0\t%l3";
1364 }
1365 [(set_attr "op_type" "RIE")
1366 (set_attr "type" "branch")
1367 (set_attr "z10prop" "z10_super_c,z10_super")
1368 (set (attr "length")
1369 (if_then_else (lt (abs (minus (pc) (match_dup 3))) (const_int 60000))
1370 (const_int 6) (const_int 12)))]) ; 8 byte for cr/jg
1371 ; 10 byte for cgr/jg
1372
1373 ; clij, clgij, clrj, clgrj, clfi, clgfi, clr, clgr
1374 ; The following instructions do a complementary access of their second
1375 ; operand (z10 only): clrj, clgrj, clr, clgr
1376 (define_insn "*cmp_and_br_unsigned_<mode>"
1377 [(set (pc)
1378 (if_then_else (match_operator 0 "s390_unsigned_integer_comparison"
1379 [(match_operand:GPR 1 "register_operand" "d,d")
1380 (match_operand:GPR 2 "nonmemory_operand" "d,I")])
1381 (label_ref (match_operand 3 "" ""))
1382 (pc)))
1383 (clobber (reg:CC CC_REGNUM))]
1384 "TARGET_Z10 && !TARGET_AVOID_CMP_AND_BRANCH"
1385 {
1386 if (get_attr_length (insn) == 6)
1387 return which_alternative ?
1388 "cl<g>ij%C0\t%1,%b2,%l3" : "cl<g>rj%C0\t%1,%2,%l3";
1389 else
1390 return which_alternative ?
1391 "cl<g>fi\t%1,%b2\;jg%C0\t%l3" : "cl<g>r\t%1,%2\;jg%C0\t%l3";
1392 }
1393 [(set_attr "op_type" "RIE")
1394 (set_attr "type" "branch")
1395 (set_attr "z10prop" "z10_super_c,z10_super")
1396 (set (attr "length")
1397 (if_then_else (lt (abs (minus (pc) (match_dup 3))) (const_int 60000))
1398 (const_int 6) (const_int 12)))]) ; 8 byte for clr/jg
1399 ; 10 byte for clgr/jg
1400
1401 ; And now the same two patterns as above but with a negated CC mask.
1402
1403 ; cij, cgij, crj, cgrj, cfi, cgfi, cr, cgr
1404 ; The following instructions do a complementary access of their second
1405 ; operand (z01 only): crj_c, cgrjc, cr, cgr
1406 (define_insn "*icmp_and_br_signed_<mode>"
1407 [(set (pc)
1408 (if_then_else (match_operator 0 "s390_signed_integer_comparison"
1409 [(match_operand:GPR 1 "register_operand" "d,d")
1410 (match_operand:GPR 2 "nonmemory_operand" "d,C")])
1411 (pc)
1412 (label_ref (match_operand 3 "" ""))))
1413 (clobber (reg:CC CC_REGNUM))]
1414 "TARGET_Z10 && !TARGET_AVOID_CMP_AND_BRANCH"
1415 {
1416 if (get_attr_length (insn) == 6)
1417 return which_alternative ?
1418 "c<g>ij%D0\t%1,%c2,%l3" : "c<g>rj%D0\t%1,%2,%l3";
1419 else
1420 return which_alternative ?
1421 "c<g>fi\t%1,%c2\;jg%D0\t%l3" : "c<g>r\t%1,%2\;jg%D0\t%l3";
1422 }
1423 [(set_attr "op_type" "RIE")
1424 (set_attr "type" "branch")
1425 (set_attr "z10prop" "z10_super_c,z10_super")
1426 (set (attr "length")
1427 (if_then_else (lt (abs (minus (pc) (match_dup 3))) (const_int 60000))
1428 (const_int 6) (const_int 12)))]) ; 8 byte for cr/jg
1429 ; 10 byte for cgr/jg
1430
1431 ; clij, clgij, clrj, clgrj, clfi, clgfi, clr, clgr
1432 ; The following instructions do a complementary access of their second
1433 ; operand (z10 only): clrj, clgrj, clr, clgr
1434 (define_insn "*icmp_and_br_unsigned_<mode>"
1435 [(set (pc)
1436 (if_then_else (match_operator 0 "s390_unsigned_integer_comparison"
1437 [(match_operand:GPR 1 "register_operand" "d,d")
1438 (match_operand:GPR 2 "nonmemory_operand" "d,I")])
1439 (pc)
1440 (label_ref (match_operand 3 "" ""))))
1441 (clobber (reg:CC CC_REGNUM))]
1442 "TARGET_Z10 && !TARGET_AVOID_CMP_AND_BRANCH"
1443 {
1444 if (get_attr_length (insn) == 6)
1445 return which_alternative ?
1446 "cl<g>ij%D0\t%1,%b2,%l3" : "cl<g>rj%D0\t%1,%2,%l3";
1447 else
1448 return which_alternative ?
1449 "cl<g>fi\t%1,%b2\;jg%D0\t%l3" : "cl<g>r\t%1,%2\;jg%D0\t%l3";
1450 }
1451 [(set_attr "op_type" "RIE")
1452 (set_attr "type" "branch")
1453 (set_attr "z10prop" "z10_super_c,z10_super")
1454 (set (attr "length")
1455 (if_then_else (lt (abs (minus (pc) (match_dup 3))) (const_int 60000))
1456 (const_int 6) (const_int 12)))]) ; 8 byte for clr/jg
1457 ; 10 byte for clgr/jg
1458
1459 ;;
1460 ;;- Move instructions.
1461 ;;
1462
1463 ;
1464 ; movti instruction pattern(s).
1465 ;
1466
1467 ; FIXME: More constants are possible by enabling jxx, jyy constraints
1468 ; for TImode (use double-int for the calculations)
1469 (define_insn "movti"
1470 [(set (match_operand:TI 0 "nonimmediate_operand" "=d,S,v, v, v,v,d,v,R, d,o")
1471 (match_operand:TI 1 "general_operand" " S,d,v,j00,jm1,d,v,R,v,dPT,d"))]
1472 "TARGET_ZARCH"
1473 "@
1474 lmg\t%0,%N0,%S1
1475 stmg\t%1,%N1,%S0
1476 vlr\t%v0,%v1
1477 vzero\t%v0
1478 vone\t%v0
1479 vlvgp\t%v0,%1,%N1
1480 #
1481 vl\t%v0,%1
1482 vst\t%v1,%0
1483 #
1484 #"
1485 [(set_attr "op_type" "RSY,RSY,VRR,VRI,VRI,VRR,*,VRX,VRX,*,*")
1486 (set_attr "type" "lm,stm,*,*,*,*,*,*,*,*,*")
1487 (set_attr "cpu_facility" "*,*,vx,vx,vx,vx,vx,vx,vx,*,*")])
1488
1489 (define_split
1490 [(set (match_operand:TI 0 "nonimmediate_operand" "")
1491 (match_operand:TI 1 "general_operand" ""))]
1492 "TARGET_ZARCH && reload_completed
1493 && !s_operand (operands[0], TImode)
1494 && !s_operand (operands[1], TImode)
1495 && s390_split_ok_p (operands[0], operands[1], TImode, 0)"
1496 [(set (match_dup 2) (match_dup 4))
1497 (set (match_dup 3) (match_dup 5))]
1498 {
1499 operands[2] = operand_subword (operands[0], 0, 0, TImode);
1500 operands[3] = operand_subword (operands[0], 1, 0, TImode);
1501 operands[4] = operand_subword (operands[1], 0, 0, TImode);
1502 operands[5] = operand_subword (operands[1], 1, 0, TImode);
1503 })
1504
1505 (define_split
1506 [(set (match_operand:TI 0 "nonimmediate_operand" "")
1507 (match_operand:TI 1 "general_operand" ""))]
1508 "TARGET_ZARCH && reload_completed
1509 && !s_operand (operands[0], TImode)
1510 && !s_operand (operands[1], TImode)
1511 && s390_split_ok_p (operands[0], operands[1], TImode, 1)"
1512 [(set (match_dup 2) (match_dup 4))
1513 (set (match_dup 3) (match_dup 5))]
1514 {
1515 operands[2] = operand_subword (operands[0], 1, 0, TImode);
1516 operands[3] = operand_subword (operands[0], 0, 0, TImode);
1517 operands[4] = operand_subword (operands[1], 1, 0, TImode);
1518 operands[5] = operand_subword (operands[1], 0, 0, TImode);
1519 })
1520
1521 ; Use part of the TImode target reg to perform the address
1522 ; calculation. If the TImode value is supposed to be copied into a VR
1523 ; this splitter is not necessary.
1524 (define_split
1525 [(set (match_operand:TI 0 "register_operand" "")
1526 (match_operand:TI 1 "memory_operand" ""))]
1527 "TARGET_ZARCH && reload_completed
1528 && !VECTOR_REG_P (operands[0])
1529 && !s_operand (operands[1], VOIDmode)"
1530 [(set (match_dup 0) (match_dup 1))]
1531 {
1532 rtx addr = operand_subword (operands[0], 1, 0, TImode);
1533 addr = gen_lowpart (Pmode, addr);
1534 s390_load_address (addr, XEXP (operands[1], 0));
1535 operands[1] = replace_equiv_address (operands[1], addr);
1536 })
1537
1538
1539 ; Split a VR -> GPR TImode move into 2 vector load GR from VR element.
1540 ; For the higher order bits we do simply a DImode move while the
1541 ; second part is done via vec extract. Both will end up as vlgvg.
1542 (define_split
1543 [(set (match_operand:TI 0 "register_operand" "")
1544 (match_operand:TI 1 "register_operand" ""))]
1545 "TARGET_VX && reload_completed
1546 && GENERAL_REG_P (operands[0])
1547 && VECTOR_REG_P (operands[1])"
1548 [(set (match_dup 2) (match_dup 4))
1549 (set (match_dup 3) (unspec:DI [(match_dup 5) (const_int 1)]
1550 UNSPEC_VEC_EXTRACT))]
1551 {
1552 operands[2] = operand_subword (operands[0], 0, 0, TImode);
1553 operands[3] = operand_subword (operands[0], 1, 0, TImode);
1554 operands[4] = gen_rtx_REG (DImode, REGNO (operands[1]));
1555 operands[5] = gen_rtx_REG (V2DImode, REGNO (operands[1]));
1556 })
1557
1558 ;
1559 ; Patterns used for secondary reloads
1560 ;
1561
1562 ; z10 provides move instructions accepting larl memory operands.
1563 ; Unfortunately there is no such variant for QI, TI and FP mode moves.
1564 ; These patterns are also used for unaligned SI and DI accesses.
1565
1566 (define_expand "reload<ALL:mode><P:mode>_tomem_z10"
1567 [(parallel [(match_operand:ALL 0 "memory_operand" "")
1568 (match_operand:ALL 1 "register_operand" "=d")
1569 (match_operand:P 2 "register_operand" "=&a")])]
1570 "TARGET_Z10"
1571 {
1572 s390_reload_symref_address (operands[1], operands[0], operands[2], 1);
1573 DONE;
1574 })
1575
1576 (define_expand "reload<ALL:mode><P:mode>_toreg_z10"
1577 [(parallel [(match_operand:ALL 0 "register_operand" "=d")
1578 (match_operand:ALL 1 "memory_operand" "")
1579 (match_operand:P 2 "register_operand" "=a")])]
1580 "TARGET_Z10"
1581 {
1582 s390_reload_symref_address (operands[0], operands[1], operands[2], 0);
1583 DONE;
1584 })
1585
1586 (define_expand "reload<P:mode>_larl_odd_addend_z10"
1587 [(parallel [(match_operand:P 0 "register_operand" "=d")
1588 (match_operand:P 1 "larl_operand" "")
1589 (match_operand:P 2 "register_operand" "=a")])]
1590 "TARGET_Z10"
1591 {
1592 s390_reload_larl_operand (operands[0], operands[1], operands[2]);
1593 DONE;
1594 })
1595
1596 ; Handles loading a PLUS (load address) expression
1597
1598 (define_expand "reload<mode>_plus"
1599 [(parallel [(match_operand:P 0 "register_operand" "=a")
1600 (match_operand:P 1 "s390_plus_operand" "")
1601 (match_operand:P 2 "register_operand" "=&a")])]
1602 ""
1603 {
1604 s390_expand_plus_operand (operands[0], operands[1], operands[2]);
1605 DONE;
1606 })
1607
1608 ; Not all the indirect memory access instructions support the full
1609 ; format (long disp + index + base). So whenever a move from/to such
1610 ; an address is required and the instruction cannot deal with it we do
1611 ; a load address into a scratch register first and use this as the new
1612 ; base register.
1613 ; This in particular is used for:
1614 ; - non-offsetable memory accesses for multiword moves
1615 ; - full vector reg moves with long displacements
1616
1617 (define_expand "reload<mode>_la_in"
1618 [(parallel [(match_operand 0 "register_operand" "")
1619 (match_operand 1 "" "")
1620 (match_operand:P 2 "register_operand" "=&a")])]
1621 ""
1622 {
1623 gcc_assert (MEM_P (operands[1]));
1624 s390_load_address (operands[2], find_replacement (&XEXP (operands[1], 0)));
1625 operands[1] = replace_equiv_address (operands[1], operands[2]);
1626 emit_move_insn (operands[0], operands[1]);
1627 DONE;
1628 })
1629
1630 (define_expand "reload<mode>_la_out"
1631 [(parallel [(match_operand 0 "" "")
1632 (match_operand 1 "register_operand" "")
1633 (match_operand:P 2 "register_operand" "=&a")])]
1634 ""
1635 {
1636 gcc_assert (MEM_P (operands[0]));
1637 s390_load_address (operands[2], find_replacement (&XEXP (operands[0], 0)));
1638 operands[0] = replace_equiv_address (operands[0], operands[2]);
1639 emit_move_insn (operands[0], operands[1]);
1640 DONE;
1641 })
1642
1643 (define_expand "reload<mode>_PIC_addr"
1644 [(parallel [(match_operand 0 "register_operand" "=d")
1645 (match_operand 1 "larl_operand" "")
1646 (match_operand:P 2 "register_operand" "=a")])]
1647 ""
1648 {
1649 rtx new_rtx = legitimize_pic_address (operands[1], operands[2]);
1650 emit_move_insn (operands[0], new_rtx);
1651 })
1652
1653 ;
1654 ; movdi instruction pattern(s).
1655 ;
1656
1657 (define_expand "movdi"
1658 [(set (match_operand:DI 0 "general_operand" "")
1659 (match_operand:DI 1 "general_operand" ""))]
1660 ""
1661 {
1662 /* Handle symbolic constants. */
1663 if (TARGET_64BIT
1664 && (SYMBOLIC_CONST (operands[1])
1665 || (GET_CODE (operands[1]) == PLUS
1666 && XEXP (operands[1], 0) == pic_offset_table_rtx
1667 && SYMBOLIC_CONST (XEXP (operands[1], 1)))))
1668 emit_symbolic_move (operands);
1669 })
1670
1671 (define_insn "*movdi_larl"
1672 [(set (match_operand:DI 0 "register_operand" "=d")
1673 (match_operand:DI 1 "larl_operand" "X"))]
1674 "TARGET_64BIT
1675 && !FP_REG_P (operands[0])"
1676 "larl\t%0,%1"
1677 [(set_attr "op_type" "RIL")
1678 (set_attr "type" "larl")
1679 (set_attr "z10prop" "z10_super_A1")])
1680
1681 (define_insn "*movdi_64"
1682 [(set (match_operand:DI 0 "nonimmediate_operand"
1683 "=d, d, d, d, d, d, d, d,f,d,d,d,d,d,T,!*f,!*f,!*f,!R,!T,b,Q,d,t,Q,t,v,v,v,d,v,R")
1684 (match_operand:DI 1 "general_operand"
1685 " K,N0HD0,N1HD0,N2HD0,N3HD0,Os,N0SD0,N1SD0,d,f,L,b,d,T,d, *f, R, T,*f,*f,d,K,t,d,t,Q,K,v,d,v,R,v"))]
1686 "TARGET_ZARCH"
1687 "@
1688 lghi\t%0,%h1
1689 llihh\t%0,%i1
1690 llihl\t%0,%i1
1691 llilh\t%0,%i1
1692 llill\t%0,%i1
1693 lgfi\t%0,%1
1694 llihf\t%0,%k1
1695 llilf\t%0,%k1
1696 ldgr\t%0,%1
1697 lgdr\t%0,%1
1698 lay\t%0,%a1
1699 lgrl\t%0,%1
1700 lgr\t%0,%1
1701 lg\t%0,%1
1702 stg\t%1,%0
1703 ldr\t%0,%1
1704 ld\t%0,%1
1705 ldy\t%0,%1
1706 std\t%1,%0
1707 stdy\t%1,%0
1708 stgrl\t%1,%0
1709 mvghi\t%0,%1
1710 #
1711 #
1712 stam\t%1,%N1,%S0
1713 lam\t%0,%N0,%S1
1714 vleig\t%v0,%h1,0
1715 vlr\t%v0,%v1
1716 vlvgg\t%v0,%1,0
1717 vlgvg\t%0,%v1,0
1718 vleg\t%v0,%1,0
1719 vsteg\t%v1,%0,0"
1720 [(set_attr "op_type" "RI,RI,RI,RI,RI,RIL,RIL,RIL,RRE,RRE,RXY,RIL,RRE,RXY,
1721 RXY,RR,RX,RXY,RX,RXY,RIL,SIL,*,*,RS,RS,VRI,VRR,VRS,VRS,VRX,VRX")
1722 (set_attr "type" "*,*,*,*,*,*,*,*,floaddf,floaddf,la,larl,lr,load,store,
1723 floaddf,floaddf,floaddf,fstoredf,fstoredf,larl,*,*,*,*,
1724 *,*,*,*,*,*,*")
1725 (set_attr "cpu_facility" "*,*,*,*,*,extimm,extimm,extimm,dfp,dfp,longdisp,
1726 z10,*,*,*,*,*,longdisp,*,longdisp,
1727 z10,z10,*,*,*,*,vx,vx,vx,vx,vx,vx")
1728 (set_attr "z10prop" "z10_fwd_A1,
1729 z10_fwd_E1,
1730 z10_fwd_E1,
1731 z10_fwd_E1,
1732 z10_fwd_E1,
1733 z10_fwd_A1,
1734 z10_fwd_E1,
1735 z10_fwd_E1,
1736 *,
1737 *,
1738 z10_fwd_A1,
1739 z10_fwd_A3,
1740 z10_fr_E1,
1741 z10_fwd_A3,
1742 z10_rec,
1743 *,
1744 *,
1745 *,
1746 *,
1747 *,
1748 z10_rec,
1749 z10_super,
1750 *,
1751 *,
1752 *,
1753 *,*,*,*,*,*,*")
1754 ])
1755
1756 (define_split
1757 [(set (match_operand:DI 0 "register_operand" "")
1758 (match_operand:DI 1 "register_operand" ""))]
1759 "TARGET_ZARCH && ACCESS_REG_P (operands[1])"
1760 [(set (match_dup 2) (match_dup 3))
1761 (set (match_dup 0) (ashift:DI (match_dup 0) (const_int 32)))
1762 (set (strict_low_part (match_dup 2)) (match_dup 4))]
1763 "operands[2] = gen_lowpart (SImode, operands[0]);
1764 s390_split_access_reg (operands[1], &operands[4], &operands[3]);")
1765
1766 (define_split
1767 [(set (match_operand:DI 0 "register_operand" "")
1768 (match_operand:DI 1 "register_operand" ""))]
1769 "TARGET_ZARCH && ACCESS_REG_P (operands[0])
1770 && dead_or_set_p (insn, operands[1])"
1771 [(set (match_dup 3) (match_dup 2))
1772 (set (match_dup 1) (lshiftrt:DI (match_dup 1) (const_int 32)))
1773 (set (match_dup 4) (match_dup 2))]
1774 "operands[2] = gen_lowpart (SImode, operands[1]);
1775 s390_split_access_reg (operands[0], &operands[3], &operands[4]);")
1776
1777 (define_split
1778 [(set (match_operand:DI 0 "register_operand" "")
1779 (match_operand:DI 1 "register_operand" ""))]
1780 "TARGET_ZARCH && ACCESS_REG_P (operands[0])
1781 && !dead_or_set_p (insn, operands[1])"
1782 [(set (match_dup 3) (match_dup 2))
1783 (set (match_dup 1) (rotate:DI (match_dup 1) (const_int 32)))
1784 (set (match_dup 4) (match_dup 2))
1785 (set (match_dup 1) (rotate:DI (match_dup 1) (const_int 32)))]
1786 "operands[2] = gen_lowpart (SImode, operands[1]);
1787 s390_split_access_reg (operands[0], &operands[3], &operands[4]);")
1788
1789 (define_insn "*movdi_31"
1790 [(set (match_operand:DI 0 "nonimmediate_operand"
1791 "=d,d,Q,S,d ,o,!*f,!*f,!*f,!R,!T,d")
1792 (match_operand:DI 1 "general_operand"
1793 " Q,S,d,d,dPT,d, *f, R, T,*f,*f,b"))]
1794 "!TARGET_ZARCH"
1795 "@
1796 lm\t%0,%N0,%S1
1797 lmy\t%0,%N0,%S1
1798 stm\t%1,%N1,%S0
1799 stmy\t%1,%N1,%S0
1800 #
1801 #
1802 ldr\t%0,%1
1803 ld\t%0,%1
1804 ldy\t%0,%1
1805 std\t%1,%0
1806 stdy\t%1,%0
1807 #"
1808 [(set_attr "op_type" "RS,RSY,RS,RSY,*,*,RR,RX,RXY,RX,RXY,*")
1809 (set_attr "type" "lm,lm,stm,stm,*,*,floaddf,floaddf,floaddf,fstoredf,fstoredf,*")
1810 (set_attr "cpu_facility" "*,longdisp,*,longdisp,*,*,*,*,longdisp,*,longdisp,z10")])
1811
1812 ; For a load from a symbol ref we can use one of the target registers
1813 ; together with larl to load the address.
1814 (define_split
1815 [(set (match_operand:DI 0 "register_operand" "")
1816 (match_operand:DI 1 "memory_operand" ""))]
1817 "!TARGET_ZARCH && reload_completed && TARGET_Z10
1818 && larl_operand (XEXP (operands[1], 0), SImode)"
1819 [(set (match_dup 2) (match_dup 3))
1820 (set (match_dup 0) (match_dup 1))]
1821 {
1822 operands[2] = operand_subword (operands[0], 1, 0, DImode);
1823 operands[3] = XEXP (operands[1], 0);
1824 operands[1] = replace_equiv_address (operands[1], operands[2]);
1825 })
1826
1827 (define_split
1828 [(set (match_operand:DI 0 "nonimmediate_operand" "")
1829 (match_operand:DI 1 "general_operand" ""))]
1830 "!TARGET_ZARCH && reload_completed
1831 && !s_operand (operands[0], DImode)
1832 && !s_operand (operands[1], DImode)
1833 && s390_split_ok_p (operands[0], operands[1], DImode, 0)"
1834 [(set (match_dup 2) (match_dup 4))
1835 (set (match_dup 3) (match_dup 5))]
1836 {
1837 operands[2] = operand_subword (operands[0], 0, 0, DImode);
1838 operands[3] = operand_subword (operands[0], 1, 0, DImode);
1839 operands[4] = operand_subword (operands[1], 0, 0, DImode);
1840 operands[5] = operand_subword (operands[1], 1, 0, DImode);
1841 })
1842
1843 (define_split
1844 [(set (match_operand:DI 0 "nonimmediate_operand" "")
1845 (match_operand:DI 1 "general_operand" ""))]
1846 "!TARGET_ZARCH && reload_completed
1847 && !s_operand (operands[0], DImode)
1848 && !s_operand (operands[1], DImode)
1849 && s390_split_ok_p (operands[0], operands[1], DImode, 1)"
1850 [(set (match_dup 2) (match_dup 4))
1851 (set (match_dup 3) (match_dup 5))]
1852 {
1853 operands[2] = operand_subword (operands[0], 1, 0, DImode);
1854 operands[3] = operand_subword (operands[0], 0, 0, DImode);
1855 operands[4] = operand_subword (operands[1], 1, 0, DImode);
1856 operands[5] = operand_subword (operands[1], 0, 0, DImode);
1857 })
1858
1859 (define_split
1860 [(set (match_operand:DI 0 "register_operand" "")
1861 (match_operand:DI 1 "memory_operand" ""))]
1862 "!TARGET_ZARCH && reload_completed
1863 && !FP_REG_P (operands[0])
1864 && !s_operand (operands[1], VOIDmode)"
1865 [(set (match_dup 0) (match_dup 1))]
1866 {
1867 rtx addr = operand_subword (operands[0], 1, 0, DImode);
1868 s390_load_address (addr, XEXP (operands[1], 0));
1869 operands[1] = replace_equiv_address (operands[1], addr);
1870 })
1871
1872 (define_peephole2
1873 [(set (match_operand:DI 0 "register_operand" "")
1874 (mem:DI (match_operand 1 "address_operand" "")))]
1875 "TARGET_ZARCH
1876 && !FP_REG_P (operands[0])
1877 && GET_CODE (operands[1]) == SYMBOL_REF
1878 && CONSTANT_POOL_ADDRESS_P (operands[1])
1879 && get_pool_mode (operands[1]) == DImode
1880 && legitimate_reload_constant_p (get_pool_constant (operands[1]))"
1881 [(set (match_dup 0) (match_dup 2))]
1882 "operands[2] = get_pool_constant (operands[1]);")
1883
1884 (define_insn "*la_64"
1885 [(set (match_operand:DI 0 "register_operand" "=d,d")
1886 (match_operand:QI 1 "address_operand" "ZR,ZT"))]
1887 "TARGET_64BIT"
1888 "@
1889 la\t%0,%a1
1890 lay\t%0,%a1"
1891 [(set_attr "op_type" "RX,RXY")
1892 (set_attr "type" "la")
1893 (set_attr "cpu_facility" "*,longdisp")
1894 (set_attr "z10prop" "z10_fwd_A1,z10_fwd_A1")])
1895
1896 (define_peephole2
1897 [(parallel
1898 [(set (match_operand:DI 0 "register_operand" "")
1899 (match_operand:QI 1 "address_operand" ""))
1900 (clobber (reg:CC CC_REGNUM))])]
1901 "TARGET_64BIT
1902 && preferred_la_operand_p (operands[1], const0_rtx)"
1903 [(set (match_dup 0) (match_dup 1))]
1904 "")
1905
1906 (define_peephole2
1907 [(set (match_operand:DI 0 "register_operand" "")
1908 (match_operand:DI 1 "register_operand" ""))
1909 (parallel
1910 [(set (match_dup 0)
1911 (plus:DI (match_dup 0)
1912 (match_operand:DI 2 "nonmemory_operand" "")))
1913 (clobber (reg:CC CC_REGNUM))])]
1914 "TARGET_64BIT
1915 && !reg_overlap_mentioned_p (operands[0], operands[2])
1916 && preferred_la_operand_p (operands[1], operands[2])"
1917 [(set (match_dup 0) (plus:DI (match_dup 1) (match_dup 2)))]
1918 "")
1919
1920 ;
1921 ; movsi instruction pattern(s).
1922 ;
1923
1924 (define_expand "movsi"
1925 [(set (match_operand:SI 0 "general_operand" "")
1926 (match_operand:SI 1 "general_operand" ""))]
1927 ""
1928 {
1929 /* Handle symbolic constants. */
1930 if (!TARGET_64BIT
1931 && (SYMBOLIC_CONST (operands[1])
1932 || (GET_CODE (operands[1]) == PLUS
1933 && XEXP (operands[1], 0) == pic_offset_table_rtx
1934 && SYMBOLIC_CONST (XEXP(operands[1], 1)))))
1935 emit_symbolic_move (operands);
1936 })
1937
1938 (define_insn "*movsi_larl"
1939 [(set (match_operand:SI 0 "register_operand" "=d")
1940 (match_operand:SI 1 "larl_operand" "X"))]
1941 "!TARGET_64BIT && TARGET_CPU_ZARCH
1942 && !FP_REG_P (operands[0])"
1943 "larl\t%0,%1"
1944 [(set_attr "op_type" "RIL")
1945 (set_attr "type" "larl")
1946 (set_attr "z10prop" "z10_fwd_A1")])
1947
1948 (define_insn "*movsi_zarch"
1949 [(set (match_operand:SI 0 "nonimmediate_operand"
1950 "=d, d, d, d,d,d,d,d,d,R,T,!*f,!*f,!*f,!*f,!*f,!R,!T,d,t,Q,b,Q,t,v,v,v,d,v,R")
1951 (match_operand:SI 1 "general_operand"
1952 " K,N0HS0,N1HS0,Os,L,b,d,R,T,d,d, *f, *f, R, R, T,*f,*f,t,d,t,d,K,Q,K,v,d,v,R,v"))]
1953 "TARGET_ZARCH"
1954 "@
1955 lhi\t%0,%h1
1956 llilh\t%0,%i1
1957 llill\t%0,%i1
1958 iilf\t%0,%o1
1959 lay\t%0,%a1
1960 lrl\t%0,%1
1961 lr\t%0,%1
1962 l\t%0,%1
1963 ly\t%0,%1
1964 st\t%1,%0
1965 sty\t%1,%0
1966 ldr\t%0,%1
1967 ler\t%0,%1
1968 lde\t%0,%1
1969 le\t%0,%1
1970 ley\t%0,%1
1971 ste\t%1,%0
1972 stey\t%1,%0
1973 ear\t%0,%1
1974 sar\t%0,%1
1975 stam\t%1,%1,%S0
1976 strl\t%1,%0
1977 mvhi\t%0,%1
1978 lam\t%0,%0,%S1
1979 vleif\t%v0,%h1,0
1980 vlr\t%v0,%v1
1981 vlvgf\t%v0,%1,0
1982 vlgvf\t%0,%v1,0
1983 vlef\t%v0,%1,0
1984 vstef\t%v1,%0,0"
1985 [(set_attr "op_type" "RI,RI,RI,RIL,RXY,RIL,RR,RX,RXY,RX,RXY,
1986 RR,RR,RXE,RX,RXY,RX,RXY,RRE,RRE,RS,RIL,SIL,RS,VRI,VRR,VRS,VRS,VRX,VRX")
1987 (set_attr "type" "*,
1988 *,
1989 *,
1990 *,
1991 la,
1992 larl,
1993 lr,
1994 load,
1995 load,
1996 store,
1997 store,
1998 floadsf,
1999 floadsf,
2000 floadsf,
2001 floadsf,
2002 floadsf,
2003 fstoresf,
2004 fstoresf,
2005 *,
2006 *,
2007 *,
2008 larl,
2009 *,
2010 *,*,*,*,*,*,*")
2011 (set_attr "cpu_facility" "*,*,*,extimm,longdisp,z10,*,*,longdisp,*,longdisp,
2012 vx,*,vx,*,longdisp,*,longdisp,*,*,*,z10,z10,*,vx,vx,vx,vx,vx,vx")
2013 (set_attr "z10prop" "z10_fwd_A1,
2014 z10_fwd_E1,
2015 z10_fwd_E1,
2016 z10_fwd_A1,
2017 z10_fwd_A1,
2018 z10_fwd_A3,
2019 z10_fr_E1,
2020 z10_fwd_A3,
2021 z10_fwd_A3,
2022 z10_rec,
2023 z10_rec,
2024 *,
2025 *,
2026 *,
2027 *,
2028 *,
2029 *,
2030 *,
2031 z10_super_E1,
2032 z10_super,
2033 *,
2034 z10_rec,
2035 z10_super,
2036 *,*,*,*,*,*,*")])
2037
2038 (define_insn "*movsi_esa"
2039 [(set (match_operand:SI 0 "nonimmediate_operand" "=d,d,d,R,!*f,!*f,!*f,!*f,!R,d,t,Q,t")
2040 (match_operand:SI 1 "general_operand" "K,d,R,d, *f, *f, R, R,*f,t,d,t,Q"))]
2041 "!TARGET_ZARCH"
2042 "@
2043 lhi\t%0,%h1
2044 lr\t%0,%1
2045 l\t%0,%1
2046 st\t%1,%0
2047 ldr\t%0,%1
2048 ler\t%0,%1
2049 lde\t%0,%1
2050 le\t%0,%1
2051 ste\t%1,%0
2052 ear\t%0,%1
2053 sar\t%0,%1
2054 stam\t%1,%1,%S0
2055 lam\t%0,%0,%S1"
2056 [(set_attr "op_type" "RI,RR,RX,RX,RR,RR,RXE,RX,RX,RRE,RRE,RS,RS")
2057 (set_attr "type" "*,lr,load,store,floadsf,floadsf,floadsf,floadsf,fstoresf,*,*,*,*")
2058 (set_attr "z10prop" "z10_fwd_A1,z10_fr_E1,z10_fwd_A3,z10_rec,*,*,*,*,*,z10_super_E1,
2059 z10_super,*,*")
2060 (set_attr "cpu_facility" "*,*,*,*,vx,*,vx,*,*,*,*,*,*")
2061 ])
2062
2063 (define_peephole2
2064 [(set (match_operand:SI 0 "register_operand" "")
2065 (mem:SI (match_operand 1 "address_operand" "")))]
2066 "!FP_REG_P (operands[0])
2067 && GET_CODE (operands[1]) == SYMBOL_REF
2068 && CONSTANT_POOL_ADDRESS_P (operands[1])
2069 && get_pool_mode (operands[1]) == SImode
2070 && legitimate_reload_constant_p (get_pool_constant (operands[1]))"
2071 [(set (match_dup 0) (match_dup 2))]
2072 "operands[2] = get_pool_constant (operands[1]);")
2073
2074 (define_insn "*la_31"
2075 [(set (match_operand:SI 0 "register_operand" "=d,d")
2076 (match_operand:QI 1 "address_operand" "ZR,ZT"))]
2077 "!TARGET_64BIT && legitimate_la_operand_p (operands[1])"
2078 "@
2079 la\t%0,%a1
2080 lay\t%0,%a1"
2081 [(set_attr "op_type" "RX,RXY")
2082 (set_attr "type" "la")
2083 (set_attr "cpu_facility" "*,longdisp")
2084 (set_attr "z10prop" "z10_fwd_A1,z10_fwd_A1")])
2085
2086 (define_peephole2
2087 [(parallel
2088 [(set (match_operand:SI 0 "register_operand" "")
2089 (match_operand:QI 1 "address_operand" ""))
2090 (clobber (reg:CC CC_REGNUM))])]
2091 "!TARGET_64BIT
2092 && preferred_la_operand_p (operands[1], const0_rtx)"
2093 [(set (match_dup 0) (match_dup 1))]
2094 "")
2095
2096 (define_peephole2
2097 [(set (match_operand:SI 0 "register_operand" "")
2098 (match_operand:SI 1 "register_operand" ""))
2099 (parallel
2100 [(set (match_dup 0)
2101 (plus:SI (match_dup 0)
2102 (match_operand:SI 2 "nonmemory_operand" "")))
2103 (clobber (reg:CC CC_REGNUM))])]
2104 "!TARGET_64BIT
2105 && !reg_overlap_mentioned_p (operands[0], operands[2])
2106 && preferred_la_operand_p (operands[1], operands[2])"
2107 [(set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))]
2108 "")
2109
2110 (define_insn "*la_31_and"
2111 [(set (match_operand:SI 0 "register_operand" "=d,d")
2112 (and:SI (match_operand:QI 1 "address_operand" "ZR,ZT")
2113 (const_int 2147483647)))]
2114 "!TARGET_64BIT"
2115 "@
2116 la\t%0,%a1
2117 lay\t%0,%a1"
2118 [(set_attr "op_type" "RX,RXY")
2119 (set_attr "type" "la")
2120 (set_attr "cpu_facility" "*,longdisp")
2121 (set_attr "z10prop" "z10_fwd_A1,z10_fwd_A1")])
2122
2123 (define_insn_and_split "*la_31_and_cc"
2124 [(set (match_operand:SI 0 "register_operand" "=d")
2125 (and:SI (match_operand:QI 1 "address_operand" "p")
2126 (const_int 2147483647)))
2127 (clobber (reg:CC CC_REGNUM))]
2128 "!TARGET_64BIT"
2129 "#"
2130 "&& reload_completed"
2131 [(set (match_dup 0)
2132 (and:SI (match_dup 1) (const_int 2147483647)))]
2133 ""
2134 [(set_attr "op_type" "RX")
2135 (set_attr "type" "la")])
2136
2137 (define_insn "force_la_31"
2138 [(set (match_operand:SI 0 "register_operand" "=d,d")
2139 (match_operand:QI 1 "address_operand" "ZR,ZT"))
2140 (use (const_int 0))]
2141 "!TARGET_64BIT"
2142 "@
2143 la\t%0,%a1
2144 lay\t%0,%a1"
2145 [(set_attr "op_type" "RX")
2146 (set_attr "type" "la")
2147 (set_attr "cpu_facility" "*,longdisp")
2148 (set_attr "z10prop" "z10_fwd_A1,z10_fwd_A1")])
2149
2150 ;
2151 ; movhi instruction pattern(s).
2152 ;
2153
2154 (define_expand "movhi"
2155 [(set (match_operand:HI 0 "nonimmediate_operand" "")
2156 (match_operand:HI 1 "general_operand" ""))]
2157 ""
2158 {
2159 /* Make it explicit that loading a register from memory
2160 always sign-extends (at least) to SImode. */
2161 if (optimize && can_create_pseudo_p ()
2162 && register_operand (operands[0], VOIDmode)
2163 && GET_CODE (operands[1]) == MEM)
2164 {
2165 rtx tmp = gen_reg_rtx (SImode);
2166 rtx ext = gen_rtx_SIGN_EXTEND (SImode, operands[1]);
2167 emit_insn (gen_rtx_SET (tmp, ext));
2168 operands[1] = gen_lowpart (HImode, tmp);
2169 }
2170 })
2171
2172 (define_insn "*movhi"
2173 [(set (match_operand:HI 0 "nonimmediate_operand" "=d,d,d,d,d,R,T,b,Q,v,v,v,d,v,R")
2174 (match_operand:HI 1 "general_operand" " d,n,R,T,b,d,d,d,K,K,v,d,v,R,v"))]
2175 ""
2176 "@
2177 lr\t%0,%1
2178 lhi\t%0,%h1
2179 lh\t%0,%1
2180 lhy\t%0,%1
2181 lhrl\t%0,%1
2182 sth\t%1,%0
2183 sthy\t%1,%0
2184 sthrl\t%1,%0
2185 mvhhi\t%0,%1
2186 vleih\t%v0,%h1,0
2187 vlr\t%v0,%v1
2188 vlvgh\t%v0,%1,0
2189 vlgvh\t%0,%v1,0
2190 vleh\t%v0,%1,0
2191 vsteh\t%v1,%0,0"
2192 [(set_attr "op_type" "RR,RI,RX,RXY,RIL,RX,RXY,RIL,SIL,VRI,VRR,VRS,VRS,VRX,VRX")
2193 (set_attr "type" "lr,*,*,*,larl,store,store,store,*,*,*,*,*,*,*")
2194 (set_attr "cpu_facility" "*,*,*,longdisp,z10,*,longdisp,z10,z10,vx,vx,vx,vx,vx,vx")
2195 (set_attr "z10prop" "z10_fr_E1,
2196 z10_fwd_A1,
2197 z10_super_E1,
2198 z10_super_E1,
2199 z10_super_E1,
2200 z10_rec,
2201 z10_rec,
2202 z10_rec,
2203 z10_super,*,*,*,*,*,*")])
2204
2205 (define_peephole2
2206 [(set (match_operand:HI 0 "register_operand" "")
2207 (mem:HI (match_operand 1 "address_operand" "")))]
2208 "GET_CODE (operands[1]) == SYMBOL_REF
2209 && CONSTANT_POOL_ADDRESS_P (operands[1])
2210 && get_pool_mode (operands[1]) == HImode
2211 && GET_CODE (get_pool_constant (operands[1])) == CONST_INT"
2212 [(set (match_dup 0) (match_dup 2))]
2213 "operands[2] = get_pool_constant (operands[1]);")
2214
2215 ;
2216 ; movqi instruction pattern(s).
2217 ;
2218
2219 (define_expand "movqi"
2220 [(set (match_operand:QI 0 "nonimmediate_operand" "")
2221 (match_operand:QI 1 "general_operand" ""))]
2222 ""
2223 {
2224 /* On z/Architecture, zero-extending from memory to register
2225 is just as fast as a QImode load. */
2226 if (TARGET_ZARCH && optimize && can_create_pseudo_p ()
2227 && register_operand (operands[0], VOIDmode)
2228 && GET_CODE (operands[1]) == MEM)
2229 {
2230 rtx tmp = gen_reg_rtx (DImode);
2231 rtx ext = gen_rtx_ZERO_EXTEND (DImode, operands[1]);
2232 emit_insn (gen_rtx_SET (tmp, ext));
2233 operands[1] = gen_lowpart (QImode, tmp);
2234 }
2235 })
2236
2237 (define_insn "*movqi"
2238 [(set (match_operand:QI 0 "nonimmediate_operand" "=d,d,d,d,R,T,Q,S,?Q,v,v,v,d,v,R")
2239 (match_operand:QI 1 "general_operand" " d,n,R,T,d,d,n,n,?Q,K,v,d,v,R,v"))]
2240 ""
2241 "@
2242 lr\t%0,%1
2243 lhi\t%0,%b1
2244 ic\t%0,%1
2245 icy\t%0,%1
2246 stc\t%1,%0
2247 stcy\t%1,%0
2248 mvi\t%S0,%b1
2249 mviy\t%S0,%b1
2250 #
2251 vleib\t%v0,%b1,0
2252 vlr\t%v0,%v1
2253 vlvgb\t%v0,%1,0
2254 vlgvb\t%0,%v1,0
2255 vleb\t%v0,%1,0
2256 vsteb\t%v1,%0,0"
2257 [(set_attr "op_type" "RR,RI,RX,RXY,RX,RXY,SI,SIY,SS,VRI,VRR,VRS,VRS,VRX,VRX")
2258 (set_attr "type" "lr,*,*,*,store,store,store,store,*,*,*,*,*,*,*")
2259 (set_attr "cpu_facility" "*,*,*,longdisp,*,longdisp,*,longdisp,*,vx,vx,vx,vx,vx,vx")
2260 (set_attr "z10prop" "z10_fr_E1,
2261 z10_fwd_A1,
2262 z10_super_E1,
2263 z10_super_E1,
2264 z10_rec,
2265 z10_rec,
2266 z10_super,
2267 z10_super,
2268 *,*,*,*,*,*,*")])
2269
2270 (define_peephole2
2271 [(set (match_operand:QI 0 "nonimmediate_operand" "")
2272 (mem:QI (match_operand 1 "address_operand" "")))]
2273 "GET_CODE (operands[1]) == SYMBOL_REF
2274 && CONSTANT_POOL_ADDRESS_P (operands[1])
2275 && get_pool_mode (operands[1]) == QImode
2276 && GET_CODE (get_pool_constant (operands[1])) == CONST_INT"
2277 [(set (match_dup 0) (match_dup 2))]
2278 "operands[2] = get_pool_constant (operands[1]);")
2279
2280 ;
2281 ; movstrictqi instruction pattern(s).
2282 ;
2283
2284 (define_insn "*movstrictqi"
2285 [(set (strict_low_part (match_operand:QI 0 "register_operand" "+d,d"))
2286 (match_operand:QI 1 "memory_operand" "R,T"))]
2287 ""
2288 "@
2289 ic\t%0,%1
2290 icy\t%0,%1"
2291 [(set_attr "op_type" "RX,RXY")
2292 (set_attr "cpu_facility" "*,longdisp")
2293 (set_attr "z10prop" "z10_super_E1,z10_super_E1")])
2294
2295 ;
2296 ; movstricthi instruction pattern(s).
2297 ;
2298
2299 (define_insn "*movstricthi"
2300 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+d,d"))
2301 (match_operand:HI 1 "memory_operand" "Q,S"))
2302 (clobber (reg:CC CC_REGNUM))]
2303 ""
2304 "@
2305 icm\t%0,3,%S1
2306 icmy\t%0,3,%S1"
2307 [(set_attr "op_type" "RS,RSY")
2308 (set_attr "cpu_facility" "*,longdisp")
2309 (set_attr "z10prop" "z10_super_E1,z10_super_E1")])
2310
2311 ;
2312 ; movstrictsi instruction pattern(s).
2313 ;
2314
2315 (define_insn "movstrictsi"
2316 [(set (strict_low_part (match_operand:SI 0 "register_operand" "+d,d,d,d"))
2317 (match_operand:SI 1 "general_operand" "d,R,T,t"))]
2318 "TARGET_ZARCH"
2319 "@
2320 lr\t%0,%1
2321 l\t%0,%1
2322 ly\t%0,%1
2323 ear\t%0,%1"
2324 [(set_attr "op_type" "RR,RX,RXY,RRE")
2325 (set_attr "type" "lr,load,load,*")
2326 (set_attr "cpu_facility" "*,*,longdisp,*")
2327 (set_attr "z10prop" "z10_fr_E1,z10_fwd_A3,z10_fwd_A3,z10_super_E1")])
2328
2329 ;
2330 ; mov(tf|td) instruction pattern(s).
2331 ;
2332
2333 (define_expand "mov<mode>"
2334 [(set (match_operand:TD_TF 0 "nonimmediate_operand" "")
2335 (match_operand:TD_TF 1 "general_operand" ""))]
2336 ""
2337 "")
2338
2339 (define_insn "*mov<mode>_64"
2340 [(set (match_operand:TD_TF 0 "nonimmediate_operand" "=f,f,f,o,d,S, d,o")
2341 (match_operand:TD_TF 1 "general_operand" " G,f,o,f,S,d,dT,d"))]
2342 "TARGET_ZARCH"
2343 "@
2344 lzxr\t%0
2345 lxr\t%0,%1
2346 #
2347 #
2348 lmg\t%0,%N0,%S1
2349 stmg\t%1,%N1,%S0
2350 #
2351 #"
2352 [(set_attr "op_type" "RRE,RRE,*,*,RSY,RSY,*,*")
2353 (set_attr "type" "fsimptf,fsimptf,*,*,lm,stm,*,*")
2354 (set_attr "cpu_facility" "z196,*,*,*,*,*,*,*")])
2355
2356 (define_insn "*mov<mode>_31"
2357 [(set (match_operand:TD_TF 0 "nonimmediate_operand" "=f,f,f,o")
2358 (match_operand:TD_TF 1 "general_operand" " G,f,o,f"))]
2359 "!TARGET_ZARCH"
2360 "@
2361 lzxr\t%0
2362 lxr\t%0,%1
2363 #
2364 #"
2365 [(set_attr "op_type" "RRE,RRE,*,*")
2366 (set_attr "type" "fsimptf,fsimptf,*,*")
2367 (set_attr "cpu_facility" "z196,*,*,*")])
2368
2369 ; TFmode in GPRs splitters
2370
2371 (define_split
2372 [(set (match_operand:TD_TF 0 "nonimmediate_operand" "")
2373 (match_operand:TD_TF 1 "general_operand" ""))]
2374 "TARGET_ZARCH && reload_completed
2375 && !s_operand (operands[0], <MODE>mode)
2376 && !s_operand (operands[1], <MODE>mode)
2377 && s390_split_ok_p (operands[0], operands[1], <MODE>mode, 0)"
2378 [(set (match_dup 2) (match_dup 4))
2379 (set (match_dup 3) (match_dup 5))]
2380 {
2381 operands[2] = operand_subword (operands[0], 0, 0, <MODE>mode);
2382 operands[3] = operand_subword (operands[0], 1, 0, <MODE>mode);
2383 operands[4] = operand_subword (operands[1], 0, 0, <MODE>mode);
2384 operands[5] = operand_subword (operands[1], 1, 0, <MODE>mode);
2385 })
2386
2387 (define_split
2388 [(set (match_operand:TD_TF 0 "nonimmediate_operand" "")
2389 (match_operand:TD_TF 1 "general_operand" ""))]
2390 "TARGET_ZARCH && reload_completed
2391 && !s_operand (operands[0], <MODE>mode)
2392 && !s_operand (operands[1], <MODE>mode)
2393 && s390_split_ok_p (operands[0], operands[1], <MODE>mode, 1)"
2394 [(set (match_dup 2) (match_dup 4))
2395 (set (match_dup 3) (match_dup 5))]
2396 {
2397 operands[2] = operand_subword (operands[0], 1, 0, <MODE>mode);
2398 operands[3] = operand_subword (operands[0], 0, 0, <MODE>mode);
2399 operands[4] = operand_subword (operands[1], 1, 0, <MODE>mode);
2400 operands[5] = operand_subword (operands[1], 0, 0, <MODE>mode);
2401 })
2402
2403 (define_split
2404 [(set (match_operand:TD_TF 0 "register_operand" "")
2405 (match_operand:TD_TF 1 "memory_operand" ""))]
2406 "TARGET_ZARCH && reload_completed
2407 && GENERAL_REG_P (operands[0])
2408 && !s_operand (operands[1], VOIDmode)"
2409 [(set (match_dup 0) (match_dup 1))]
2410 {
2411 rtx addr = operand_subword (operands[0], 1, 0, <MODE>mode);
2412 addr = gen_lowpart (Pmode, addr);
2413 s390_load_address (addr, XEXP (operands[1], 0));
2414 operands[1] = replace_equiv_address (operands[1], addr);
2415 })
2416
2417 ; TFmode in BFPs splitters
2418
2419 (define_split
2420 [(set (match_operand:TD_TF 0 "register_operand" "")
2421 (match_operand:TD_TF 1 "memory_operand" ""))]
2422 "reload_completed && offsettable_memref_p (operands[1])
2423 && FP_REG_P (operands[0])"
2424 [(set (match_dup 2) (match_dup 4))
2425 (set (match_dup 3) (match_dup 5))]
2426 {
2427 operands[2] = simplify_gen_subreg (<HALF_TMODE>mode, operands[0],
2428 <MODE>mode, 0);
2429 operands[3] = simplify_gen_subreg (<HALF_TMODE>mode, operands[0],
2430 <MODE>mode, 8);
2431 operands[4] = adjust_address_nv (operands[1], <HALF_TMODE>mode, 0);
2432 operands[5] = adjust_address_nv (operands[1], <HALF_TMODE>mode, 8);
2433 })
2434
2435 (define_split
2436 [(set (match_operand:TD_TF 0 "memory_operand" "")
2437 (match_operand:TD_TF 1 "register_operand" ""))]
2438 "reload_completed && offsettable_memref_p (operands[0])
2439 && FP_REG_P (operands[1])"
2440 [(set (match_dup 2) (match_dup 4))
2441 (set (match_dup 3) (match_dup 5))]
2442 {
2443 operands[2] = adjust_address_nv (operands[0], <HALF_TMODE>mode, 0);
2444 operands[3] = adjust_address_nv (operands[0], <HALF_TMODE>mode, 8);
2445 operands[4] = simplify_gen_subreg (<HALF_TMODE>mode, operands[1],
2446 <MODE>mode, 0);
2447 operands[5] = simplify_gen_subreg (<HALF_TMODE>mode, operands[1],
2448 <MODE>mode, 8);
2449 })
2450
2451 ;
2452 ; mov(df|dd) instruction pattern(s).
2453 ;
2454
2455 (define_expand "mov<mode>"
2456 [(set (match_operand:DD_DF 0 "nonimmediate_operand" "")
2457 (match_operand:DD_DF 1 "general_operand" ""))]
2458 ""
2459 "")
2460
2461 (define_insn "*mov<mode>_64dfp"
2462 [(set (match_operand:DD_DF 0 "nonimmediate_operand"
2463 "=f,f,f,d,f,f,R,T,d,d,d,d,b,T,v,v,v,d,v,R")
2464 (match_operand:DD_DF 1 "general_operand"
2465 " G,f,d,f,R,T,f,f,G,d,b,T,d,d,v,G,d,v,R,v"))]
2466 "TARGET_DFP"
2467 "@
2468 lzdr\t%0
2469 ldr\t%0,%1
2470 ldgr\t%0,%1
2471 lgdr\t%0,%1
2472 ld\t%0,%1
2473 ldy\t%0,%1
2474 std\t%1,%0
2475 stdy\t%1,%0
2476 lghi\t%0,0
2477 lgr\t%0,%1
2478 lgrl\t%0,%1
2479 lg\t%0,%1
2480 stgrl\t%1,%0
2481 stg\t%1,%0
2482 vlr\t%v0,%v1
2483 vleig\t%v0,0,0
2484 vlvgg\t%v0,%1,0
2485 vlgvg\t%0,%v1,0
2486 vleg\t%0,%1,0
2487 vsteg\t%1,%0,0"
2488 [(set_attr "op_type" "RRE,RR,RRE,RRE,RX,RXY,RX,RXY,RI,RRE,RIL,RXY,RIL,RXY,VRR,VRI,VRS,VRS,VRX,VRX")
2489 (set_attr "type" "fsimpdf,floaddf,floaddf,floaddf,floaddf,floaddf,
2490 fstoredf,fstoredf,*,lr,load,load,store,store,*,*,*,*,load,store")
2491 (set_attr "z10prop" "*,*,*,*,*,*,*,*,z10_fwd_A1,z10_fr_E1,z10_fwd_A3,z10_fwd_A3,z10_rec,z10_rec,*,*,*,*,*,*")
2492 (set_attr "cpu_facility" "z196,*,*,*,*,longdisp,*,longdisp,*,*,z10,*,z10,*,vx,vx,vx,vx,vx,vx")])
2493
2494 (define_insn "*mov<mode>_64"
2495 [(set (match_operand:DD_DF 0 "nonimmediate_operand" "=f,f,f,f,R,T,d,d,d,d,b,T")
2496 (match_operand:DD_DF 1 "general_operand" " G,f,R,T,f,f,G,d,b,T,d,d"))]
2497 "TARGET_ZARCH"
2498 "@
2499 lzdr\t%0
2500 ldr\t%0,%1
2501 ld\t%0,%1
2502 ldy\t%0,%1
2503 std\t%1,%0
2504 stdy\t%1,%0
2505 lghi\t%0,0
2506 lgr\t%0,%1
2507 lgrl\t%0,%1
2508 lg\t%0,%1
2509 stgrl\t%1,%0
2510 stg\t%1,%0"
2511 [(set_attr "op_type" "RRE,RR,RX,RXY,RX,RXY,RI,RRE,RIL,RXY,RIL,RXY")
2512 (set_attr "type" "fsimpdf,fload<mode>,fload<mode>,fload<mode>,
2513 fstore<mode>,fstore<mode>,*,lr,load,load,store,store")
2514 (set_attr "z10prop" "*,*,*,*,*,*,z10_fwd_A1,z10_fr_E1,z10_fwd_A3,z10_fwd_A3,z10_rec,z10_rec")
2515 (set_attr "cpu_facility" "z196,*,*,longdisp,*,longdisp,*,*,z10,*,z10,*")])
2516
2517 (define_insn "*mov<mode>_31"
2518 [(set (match_operand:DD_DF 0 "nonimmediate_operand"
2519 "=f,f,f,f,R,T,d,d,Q,S, d,o")
2520 (match_operand:DD_DF 1 "general_operand"
2521 " G,f,R,T,f,f,Q,S,d,d,dPT,d"))]
2522 "!TARGET_ZARCH"
2523 "@
2524 lzdr\t%0
2525 ldr\t%0,%1
2526 ld\t%0,%1
2527 ldy\t%0,%1
2528 std\t%1,%0
2529 stdy\t%1,%0
2530 lm\t%0,%N0,%S1
2531 lmy\t%0,%N0,%S1
2532 stm\t%1,%N1,%S0
2533 stmy\t%1,%N1,%S0
2534 #
2535 #"
2536 [(set_attr "op_type" "RRE,RR,RX,RXY,RX,RXY,RS,RSY,RS,RSY,*,*")
2537 (set_attr "type" "fsimpdf,fload<mode>,fload<mode>,fload<mode>,
2538 fstore<mode>,fstore<mode>,lm,lm,stm,stm,*,*")
2539 (set_attr "cpu_facility" "z196,*,*,longdisp,*,longdisp,*,longdisp,*,longdisp,*,*")])
2540
2541 (define_split
2542 [(set (match_operand:DD_DF 0 "nonimmediate_operand" "")
2543 (match_operand:DD_DF 1 "general_operand" ""))]
2544 "!TARGET_ZARCH && reload_completed
2545 && !s_operand (operands[0], <MODE>mode)
2546 && !s_operand (operands[1], <MODE>mode)
2547 && s390_split_ok_p (operands[0], operands[1], <MODE>mode, 0)"
2548 [(set (match_dup 2) (match_dup 4))
2549 (set (match_dup 3) (match_dup 5))]
2550 {
2551 operands[2] = operand_subword (operands[0], 0, 0, <MODE>mode);
2552 operands[3] = operand_subword (operands[0], 1, 0, <MODE>mode);
2553 operands[4] = operand_subword (operands[1], 0, 0, <MODE>mode);
2554 operands[5] = operand_subword (operands[1], 1, 0, <MODE>mode);
2555 })
2556
2557 (define_split
2558 [(set (match_operand:DD_DF 0 "nonimmediate_operand" "")
2559 (match_operand:DD_DF 1 "general_operand" ""))]
2560 "!TARGET_ZARCH && reload_completed
2561 && !s_operand (operands[0], <MODE>mode)
2562 && !s_operand (operands[1], <MODE>mode)
2563 && s390_split_ok_p (operands[0], operands[1], <MODE>mode, 1)"
2564 [(set (match_dup 2) (match_dup 4))
2565 (set (match_dup 3) (match_dup 5))]
2566 {
2567 operands[2] = operand_subword (operands[0], 1, 0, <MODE>mode);
2568 operands[3] = operand_subword (operands[0], 0, 0, <MODE>mode);
2569 operands[4] = operand_subword (operands[1], 1, 0, <MODE>mode);
2570 operands[5] = operand_subword (operands[1], 0, 0, <MODE>mode);
2571 })
2572
2573 (define_split
2574 [(set (match_operand:DD_DF 0 "register_operand" "")
2575 (match_operand:DD_DF 1 "memory_operand" ""))]
2576 "!TARGET_ZARCH && reload_completed
2577 && !FP_REG_P (operands[0])
2578 && !s_operand (operands[1], VOIDmode)"
2579 [(set (match_dup 0) (match_dup 1))]
2580 {
2581 rtx addr = operand_subword (operands[0], 1, 0, <MODE>mode);
2582 s390_load_address (addr, XEXP (operands[1], 0));
2583 operands[1] = replace_equiv_address (operands[1], addr);
2584 })
2585
2586 ;
2587 ; mov(sf|sd) instruction pattern(s).
2588 ;
2589
2590 (define_insn "mov<mode>"
2591 [(set (match_operand:SD_SF 0 "nonimmediate_operand"
2592 "=f,f,f,f,f,f,R,T,d,d,d,d,d,b,R,T,v,v,v,d,v,R")
2593 (match_operand:SD_SF 1 "general_operand"
2594 " G,f,f,R,R,T,f,f,G,d,b,R,T,d,d,d,v,G,d,v,R,v"))]
2595 ""
2596 "@
2597 lzer\t%0
2598 ldr\t%0,%1
2599 ler\t%0,%1
2600 lde\t%0,%1
2601 le\t%0,%1
2602 ley\t%0,%1
2603 ste\t%1,%0
2604 stey\t%1,%0
2605 lhi\t%0,0
2606 lr\t%0,%1
2607 lrl\t%0,%1
2608 l\t%0,%1
2609 ly\t%0,%1
2610 strl\t%1,%0
2611 st\t%1,%0
2612 sty\t%1,%0
2613 vlr\t%v0,%v1
2614 vleif\t%v0,0,0
2615 vlvgf\t%v0,%1,0
2616 vlgvf\t%0,%v1,0
2617 vlef\t%0,%1,0
2618 vstef\t%1,%0,0"
2619 [(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")
2620 (set_attr "type" "fsimpsf,fsimpsf,fload<mode>,fload<mode>,fload<mode>,fload<mode>,
2621 fstore<mode>,fstore<mode>,*,lr,load,load,load,store,store,store,*,*,*,*,load,store")
2622 (set_attr "z10prop" "*,*,*,*,*,*,*,*,z10_fwd_A1,z10_fr_E1,z10_fr_E1,z10_fwd_A3,z10_fwd_A3,z10_rec,z10_rec,z10_rec,*,*,*,*,*,*")
2623 (set_attr "cpu_facility" "z196,vx,*,vx,*,longdisp,*,longdisp,*,*,z10,*,longdisp,z10,*,longdisp,vx,vx,vx,vx,vx,vx")])
2624
2625 ;
2626 ; movcc instruction pattern
2627 ;
2628
2629 (define_insn "movcc"
2630 [(set (match_operand:CC 0 "nonimmediate_operand" "=d,c,d,d,d,R,T")
2631 (match_operand:CC 1 "nonimmediate_operand" " d,d,c,R,T,d,d"))]
2632 ""
2633 "@
2634 lr\t%0,%1
2635 tmh\t%1,12288
2636 ipm\t%0
2637 l\t%0,%1
2638 ly\t%0,%1
2639 st\t%1,%0
2640 sty\t%1,%0"
2641 [(set_attr "op_type" "RR,RI,RRE,RX,RXY,RX,RXY")
2642 (set_attr "type" "lr,*,*,load,load,store,store")
2643 (set_attr "cpu_facility" "*,*,*,*,longdisp,*,longdisp")
2644 (set_attr "z10prop" "z10_fr_E1,z10_super,*,z10_fwd_A3,z10_fwd_A3,z10_rec,z10_rec")
2645 (set_attr "z196prop" "*,*,z196_ends,*,*,*,*")])
2646
2647 ;
2648 ; Block move (MVC) patterns.
2649 ;
2650
2651 (define_insn "*mvc"
2652 [(set (match_operand:BLK 0 "memory_operand" "=Q")
2653 (match_operand:BLK 1 "memory_operand" "Q"))
2654 (use (match_operand 2 "const_int_operand" "n"))]
2655 "INTVAL (operands[2]) >= 1 && INTVAL (operands[2]) <= 256"
2656 "mvc\t%O0(%2,%R0),%S1"
2657 [(set_attr "op_type" "SS")])
2658
2659 ; This splitter converts a QI to QI mode copy into a BLK mode copy in
2660 ; order to have it implemented with mvc.
2661
2662 (define_split
2663 [(set (match_operand:QI 0 "memory_operand" "")
2664 (match_operand:QI 1 "memory_operand" ""))]
2665 "reload_completed"
2666 [(parallel
2667 [(set (match_dup 0) (match_dup 1))
2668 (use (const_int 1))])]
2669 {
2670 operands[0] = adjust_address (operands[0], BLKmode, 0);
2671 operands[1] = adjust_address (operands[1], BLKmode, 0);
2672 })
2673
2674
2675 (define_peephole2
2676 [(parallel
2677 [(set (match_operand:BLK 0 "memory_operand" "")
2678 (match_operand:BLK 1 "memory_operand" ""))
2679 (use (match_operand 2 "const_int_operand" ""))])
2680 (parallel
2681 [(set (match_operand:BLK 3 "memory_operand" "")
2682 (match_operand:BLK 4 "memory_operand" ""))
2683 (use (match_operand 5 "const_int_operand" ""))])]
2684 "s390_offset_p (operands[0], operands[3], operands[2])
2685 && s390_offset_p (operands[1], operands[4], operands[2])
2686 && !s390_overlap_p (operands[0], operands[1],
2687 INTVAL (operands[2]) + INTVAL (operands[5]))
2688 && INTVAL (operands[2]) + INTVAL (operands[5]) <= 256"
2689 [(parallel
2690 [(set (match_dup 6) (match_dup 7))
2691 (use (match_dup 8))])]
2692 "operands[6] = gen_rtx_MEM (BLKmode, XEXP (operands[0], 0));
2693 operands[7] = gen_rtx_MEM (BLKmode, XEXP (operands[1], 0));
2694 operands[8] = GEN_INT (INTVAL (operands[2]) + INTVAL (operands[5]));")
2695
2696
2697 ;
2698 ; load_multiple pattern(s).
2699 ;
2700 ; ??? Due to reload problems with replacing registers inside match_parallel
2701 ; we currently support load_multiple/store_multiple only after reload.
2702 ;
2703
2704 (define_expand "load_multiple"
2705 [(match_par_dup 3 [(set (match_operand 0 "" "")
2706 (match_operand 1 "" ""))
2707 (use (match_operand 2 "" ""))])]
2708 "reload_completed"
2709 {
2710 machine_mode mode;
2711 int regno;
2712 int count;
2713 rtx from;
2714 int i, off;
2715
2716 /* Support only loading a constant number of fixed-point registers from
2717 memory and only bother with this if more than two */
2718 if (GET_CODE (operands[2]) != CONST_INT
2719 || INTVAL (operands[2]) < 2
2720 || INTVAL (operands[2]) > 16
2721 || GET_CODE (operands[1]) != MEM
2722 || GET_CODE (operands[0]) != REG
2723 || REGNO (operands[0]) >= 16)
2724 FAIL;
2725
2726 count = INTVAL (operands[2]);
2727 regno = REGNO (operands[0]);
2728 mode = GET_MODE (operands[0]);
2729 if (mode != SImode && (!TARGET_ZARCH || mode != DImode))
2730 FAIL;
2731
2732 operands[3] = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (count));
2733 if (!can_create_pseudo_p ())
2734 {
2735 if (GET_CODE (XEXP (operands[1], 0)) == REG)
2736 {
2737 from = XEXP (operands[1], 0);
2738 off = 0;
2739 }
2740 else if (GET_CODE (XEXP (operands[1], 0)) == PLUS
2741 && GET_CODE (XEXP (XEXP (operands[1], 0), 0)) == REG
2742 && GET_CODE (XEXP (XEXP (operands[1], 0), 1)) == CONST_INT)
2743 {
2744 from = XEXP (XEXP (operands[1], 0), 0);
2745 off = INTVAL (XEXP (XEXP (operands[1], 0), 1));
2746 }
2747 else
2748 FAIL;
2749 }
2750 else
2751 {
2752 from = force_reg (Pmode, XEXP (operands[1], 0));
2753 off = 0;
2754 }
2755
2756 for (i = 0; i < count; i++)
2757 XVECEXP (operands[3], 0, i)
2758 = gen_rtx_SET (gen_rtx_REG (mode, regno + i),
2759 change_address (operands[1], mode,
2760 plus_constant (Pmode, from,
2761 off + i * GET_MODE_SIZE (mode))));
2762 })
2763
2764 (define_insn "*load_multiple_di"
2765 [(match_parallel 0 "load_multiple_operation"
2766 [(set (match_operand:DI 1 "register_operand" "=r")
2767 (match_operand:DI 2 "s_operand" "S"))])]
2768 "reload_completed && TARGET_ZARCH"
2769 {
2770 int words = XVECLEN (operands[0], 0);
2771 operands[0] = gen_rtx_REG (DImode, REGNO (operands[1]) + words - 1);
2772 return "lmg\t%1,%0,%S2";
2773 }
2774 [(set_attr "op_type" "RSY")
2775 (set_attr "type" "lm")])
2776
2777 (define_insn "*load_multiple_si"
2778 [(match_parallel 0 "load_multiple_operation"
2779 [(set (match_operand:SI 1 "register_operand" "=r,r")
2780 (match_operand:SI 2 "s_operand" "Q,S"))])]
2781 "reload_completed"
2782 {
2783 int words = XVECLEN (operands[0], 0);
2784 operands[0] = gen_rtx_REG (SImode, REGNO (operands[1]) + words - 1);
2785 return which_alternative == 0 ? "lm\t%1,%0,%S2" : "lmy\t%1,%0,%S2";
2786 }
2787 [(set_attr "op_type" "RS,RSY")
2788 (set_attr "cpu_facility" "*,longdisp")
2789 (set_attr "type" "lm")])
2790
2791 ;
2792 ; store multiple pattern(s).
2793 ;
2794
2795 (define_expand "store_multiple"
2796 [(match_par_dup 3 [(set (match_operand 0 "" "")
2797 (match_operand 1 "" ""))
2798 (use (match_operand 2 "" ""))])]
2799 "reload_completed"
2800 {
2801 machine_mode mode;
2802 int regno;
2803 int count;
2804 rtx to;
2805 int i, off;
2806
2807 /* Support only storing a constant number of fixed-point registers to
2808 memory and only bother with this if more than two. */
2809 if (GET_CODE (operands[2]) != CONST_INT
2810 || INTVAL (operands[2]) < 2
2811 || INTVAL (operands[2]) > 16
2812 || GET_CODE (operands[0]) != MEM
2813 || GET_CODE (operands[1]) != REG
2814 || REGNO (operands[1]) >= 16)
2815 FAIL;
2816
2817 count = INTVAL (operands[2]);
2818 regno = REGNO (operands[1]);
2819 mode = GET_MODE (operands[1]);
2820 if (mode != SImode && (!TARGET_ZARCH || mode != DImode))
2821 FAIL;
2822
2823 operands[3] = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (count));
2824
2825 if (!can_create_pseudo_p ())
2826 {
2827 if (GET_CODE (XEXP (operands[0], 0)) == REG)
2828 {
2829 to = XEXP (operands[0], 0);
2830 off = 0;
2831 }
2832 else if (GET_CODE (XEXP (operands[0], 0)) == PLUS
2833 && GET_CODE (XEXP (XEXP (operands[0], 0), 0)) == REG
2834 && GET_CODE (XEXP (XEXP (operands[0], 0), 1)) == CONST_INT)
2835 {
2836 to = XEXP (XEXP (operands[0], 0), 0);
2837 off = INTVAL (XEXP (XEXP (operands[0], 0), 1));
2838 }
2839 else
2840 FAIL;
2841 }
2842 else
2843 {
2844 to = force_reg (Pmode, XEXP (operands[0], 0));
2845 off = 0;
2846 }
2847
2848 for (i = 0; i < count; i++)
2849 XVECEXP (operands[3], 0, i)
2850 = gen_rtx_SET (change_address (operands[0], mode,
2851 plus_constant (Pmode, to,
2852 off + i * GET_MODE_SIZE (mode))),
2853 gen_rtx_REG (mode, regno + i));
2854 })
2855
2856 (define_insn "*store_multiple_di"
2857 [(match_parallel 0 "store_multiple_operation"
2858 [(set (match_operand:DI 1 "s_operand" "=S")
2859 (match_operand:DI 2 "register_operand" "r"))])]
2860 "reload_completed && TARGET_ZARCH"
2861 {
2862 int words = XVECLEN (operands[0], 0);
2863 operands[0] = gen_rtx_REG (DImode, REGNO (operands[2]) + words - 1);
2864 return "stmg\t%2,%0,%S1";
2865 }
2866 [(set_attr "op_type" "RSY")
2867 (set_attr "type" "stm")])
2868
2869
2870 (define_insn "*store_multiple_si"
2871 [(match_parallel 0 "store_multiple_operation"
2872 [(set (match_operand:SI 1 "s_operand" "=Q,S")
2873 (match_operand:SI 2 "register_operand" "r,r"))])]
2874 "reload_completed"
2875 {
2876 int words = XVECLEN (operands[0], 0);
2877 operands[0] = gen_rtx_REG (SImode, REGNO (operands[2]) + words - 1);
2878 return which_alternative == 0 ? "stm\t%2,%0,%S1" : "stmy\t%2,%0,%S1";
2879 }
2880 [(set_attr "op_type" "RS,RSY")
2881 (set_attr "cpu_facility" "*,longdisp")
2882 (set_attr "type" "stm")])
2883
2884 ;;
2885 ;; String instructions.
2886 ;;
2887
2888 (define_insn "*execute_rl"
2889 [(match_parallel 0 "execute_operation"
2890 [(unspec [(match_operand 1 "register_operand" "a")
2891 (match_operand 2 "" "")
2892 (match_operand:SI 3 "larl_operand" "X")] UNSPEC_EXECUTE)])]
2893 "TARGET_Z10 && GET_MODE_CLASS (GET_MODE (operands[1])) == MODE_INT
2894 && GET_MODE_SIZE (GET_MODE (operands[1])) <= UNITS_PER_WORD"
2895 "exrl\t%1,%3"
2896 [(set_attr "op_type" "RIL")
2897 (set_attr "type" "cs")])
2898
2899 (define_insn "*execute"
2900 [(match_parallel 0 "execute_operation"
2901 [(unspec [(match_operand 1 "register_operand" "a")
2902 (match_operand:BLK 2 "memory_operand" "R")
2903 (match_operand 3 "" "")] UNSPEC_EXECUTE)])]
2904 "GET_MODE_CLASS (GET_MODE (operands[1])) == MODE_INT
2905 && GET_MODE_SIZE (GET_MODE (operands[1])) <= UNITS_PER_WORD"
2906 "ex\t%1,%2"
2907 [(set_attr "op_type" "RX")
2908 (set_attr "type" "cs")])
2909
2910
2911 ;
2912 ; strlenM instruction pattern(s).
2913 ;
2914
2915 (define_expand "strlen<mode>"
2916 [(match_operand:P 0 "register_operand" "") ; result
2917 (match_operand:BLK 1 "memory_operand" "") ; input string
2918 (match_operand:SI 2 "immediate_operand" "") ; search character
2919 (match_operand:SI 3 "immediate_operand" "")] ; known alignment
2920 ""
2921 {
2922 if (!TARGET_VX || operands[2] != const0_rtx)
2923 emit_insn (gen_strlen_srst<mode> (operands[0], operands[1],
2924 operands[2], operands[3]));
2925 else
2926 s390_expand_vec_strlen (operands[0], operands[1], operands[3]);
2927
2928 DONE;
2929 })
2930
2931 (define_expand "strlen_srst<mode>"
2932 [(set (reg:SI 0) (match_operand:SI 2 "immediate_operand" ""))
2933 (parallel
2934 [(set (match_dup 4)
2935 (unspec:P [(const_int 0)
2936 (match_operand:BLK 1 "memory_operand" "")
2937 (reg:SI 0)
2938 (match_operand 3 "immediate_operand" "")] UNSPEC_SRST))
2939 (clobber (scratch:P))
2940 (clobber (reg:CC CC_REGNUM))])
2941 (parallel
2942 [(set (match_operand:P 0 "register_operand" "")
2943 (minus:P (match_dup 4) (match_dup 5)))
2944 (clobber (reg:CC CC_REGNUM))])]
2945 ""
2946 {
2947 operands[4] = gen_reg_rtx (Pmode);
2948 operands[5] = gen_reg_rtx (Pmode);
2949 emit_move_insn (operands[5], force_operand (XEXP (operands[1], 0), NULL_RTX));
2950 operands[1] = replace_equiv_address (operands[1], operands[5]);
2951 })
2952
2953 (define_insn "*strlen<mode>"
2954 [(set (match_operand:P 0 "register_operand" "=a")
2955 (unspec:P [(match_operand:P 2 "general_operand" "0")
2956 (mem:BLK (match_operand:P 3 "register_operand" "1"))
2957 (reg:SI 0)
2958 (match_operand 4 "immediate_operand" "")] UNSPEC_SRST))
2959 (clobber (match_scratch:P 1 "=a"))
2960 (clobber (reg:CC CC_REGNUM))]
2961 ""
2962 "srst\t%0,%1\;jo\t.-4"
2963 [(set_attr "length" "8")
2964 (set_attr "type" "vs")])
2965
2966 ;
2967 ; cmpstrM instruction pattern(s).
2968 ;
2969
2970 (define_expand "cmpstrsi"
2971 [(set (reg:SI 0) (const_int 0))
2972 (parallel
2973 [(clobber (match_operand 3 "" ""))
2974 (clobber (match_dup 4))
2975 (set (reg:CCU CC_REGNUM)
2976 (compare:CCU (match_operand:BLK 1 "memory_operand" "")
2977 (match_operand:BLK 2 "memory_operand" "")))
2978 (use (reg:SI 0))])
2979 (parallel
2980 [(set (match_operand:SI 0 "register_operand" "=d")
2981 (unspec:SI [(reg:CCU CC_REGNUM)] UNSPEC_STRCMPCC_TO_INT))
2982 (clobber (reg:CC CC_REGNUM))])]
2983 ""
2984 {
2985 /* As the result of CMPINT is inverted compared to what we need,
2986 we have to swap the operands. */
2987 rtx op1 = operands[2];
2988 rtx op2 = operands[1];
2989 rtx addr1 = gen_reg_rtx (Pmode);
2990 rtx addr2 = gen_reg_rtx (Pmode);
2991
2992 emit_move_insn (addr1, force_operand (XEXP (op1, 0), NULL_RTX));
2993 emit_move_insn (addr2, force_operand (XEXP (op2, 0), NULL_RTX));
2994 operands[1] = replace_equiv_address_nv (op1, addr1);
2995 operands[2] = replace_equiv_address_nv (op2, addr2);
2996 operands[3] = addr1;
2997 operands[4] = addr2;
2998 })
2999
3000 (define_insn "*cmpstr<mode>"
3001 [(clobber (match_operand:P 0 "register_operand" "=d"))
3002 (clobber (match_operand:P 1 "register_operand" "=d"))
3003 (set (reg:CCU CC_REGNUM)
3004 (compare:CCU (mem:BLK (match_operand:P 2 "register_operand" "0"))
3005 (mem:BLK (match_operand:P 3 "register_operand" "1"))))
3006 (use (reg:SI 0))]
3007 ""
3008 "clst\t%0,%1\;jo\t.-4"
3009 [(set_attr "length" "8")
3010 (set_attr "type" "vs")])
3011
3012 ;
3013 ; movstr instruction pattern.
3014 ;
3015
3016 (define_expand "movstr"
3017 [(match_operand 0 "register_operand" "")
3018 (match_operand 1 "memory_operand" "")
3019 (match_operand 2 "memory_operand" "")]
3020 ""
3021 {
3022 if (TARGET_64BIT)
3023 emit_insn (gen_movstrdi (operands[0], operands[1], operands[2]));
3024 else
3025 emit_insn (gen_movstrsi (operands[0], operands[1], operands[2]));
3026 DONE;
3027 })
3028
3029 (define_expand "movstr<P:mode>"
3030 [(set (reg:SI 0) (const_int 0))
3031 (parallel
3032 [(clobber (match_dup 3))
3033 (set (match_operand:BLK 1 "memory_operand" "")
3034 (match_operand:BLK 2 "memory_operand" ""))
3035 (set (match_operand:P 0 "register_operand" "")
3036 (unspec:P [(match_dup 1)
3037 (match_dup 2)
3038 (reg:SI 0)] UNSPEC_MVST))
3039 (clobber (reg:CC CC_REGNUM))])]
3040 ""
3041 {
3042 rtx addr1, addr2;
3043
3044 if (TARGET_VX && optimize_function_for_speed_p (cfun))
3045 {
3046 s390_expand_vec_movstr (operands[0], operands[1], operands[2]);
3047 DONE;
3048 }
3049
3050 addr1 = gen_reg_rtx (Pmode);
3051 addr2 = gen_reg_rtx (Pmode);
3052
3053 emit_move_insn (addr1, force_operand (XEXP (operands[1], 0), NULL_RTX));
3054 emit_move_insn (addr2, force_operand (XEXP (operands[2], 0), NULL_RTX));
3055 operands[1] = replace_equiv_address_nv (operands[1], addr1);
3056 operands[2] = replace_equiv_address_nv (operands[2], addr2);
3057 operands[3] = addr2;
3058 })
3059
3060 (define_insn "*movstr"
3061 [(clobber (match_operand:P 2 "register_operand" "=d"))
3062 (set (mem:BLK (match_operand:P 1 "register_operand" "0"))
3063 (mem:BLK (match_operand:P 3 "register_operand" "2")))
3064 (set (match_operand:P 0 "register_operand" "=d")
3065 (unspec:P [(mem:BLK (match_dup 1))
3066 (mem:BLK (match_dup 3))
3067 (reg:SI 0)] UNSPEC_MVST))
3068 (clobber (reg:CC CC_REGNUM))]
3069 ""
3070 "mvst\t%1,%2\;jo\t.-4"
3071 [(set_attr "length" "8")
3072 (set_attr "type" "vs")])
3073
3074
3075 ;
3076 ; movmemM instruction pattern(s).
3077 ;
3078
3079 (define_expand "movmem<mode>"
3080 [(set (match_operand:BLK 0 "memory_operand" "") ; destination
3081 (match_operand:BLK 1 "memory_operand" "")) ; source
3082 (use (match_operand:GPR 2 "general_operand" "")) ; count
3083 (match_operand 3 "" "")]
3084 ""
3085 {
3086 if (s390_expand_movmem (operands[0], operands[1], operands[2]))
3087 DONE;
3088 else
3089 FAIL;
3090 })
3091
3092 ; Move a block that is up to 256 bytes in length.
3093 ; The block length is taken as (operands[2] % 256) + 1.
3094
3095 (define_expand "movmem_short"
3096 [(parallel
3097 [(set (match_operand:BLK 0 "memory_operand" "")
3098 (match_operand:BLK 1 "memory_operand" ""))
3099 (use (match_operand 2 "nonmemory_operand" ""))
3100 (use (const:BLK (unspec:BLK [(const_int 0)] UNSPEC_INSN)))
3101 (clobber (match_dup 3))])]
3102 ""
3103 "operands[3] = gen_rtx_SCRATCH (Pmode);")
3104
3105 (define_insn "*movmem_short"
3106 [(set (match_operand:BLK 0 "memory_operand" "=Q,Q,Q,Q")
3107 (match_operand:BLK 1 "memory_operand" "Q,Q,Q,Q"))
3108 (use (match_operand 2 "nonmemory_operand" "n,a,a,a"))
3109 (use (match_operand 3 "immediate_operand" "X,R,X,X"))
3110 (clobber (match_scratch:P 4 "=X,X,X,&a"))]
3111 "(GET_MODE (operands[2]) == Pmode || GET_MODE (operands[2]) == VOIDmode)"
3112 "#"
3113 [(set_attr "type" "cs")
3114 (set_attr "cpu_facility" "*,*,z10,cpu_zarch")])
3115
3116 (define_split
3117 [(set (match_operand:BLK 0 "memory_operand" "")
3118 (match_operand:BLK 1 "memory_operand" ""))
3119 (use (match_operand 2 "const_int_operand" ""))
3120 (use (match_operand 3 "immediate_operand" ""))
3121 (clobber (scratch))]
3122 "reload_completed"
3123 [(parallel
3124 [(set (match_dup 0) (match_dup 1))
3125 (use (match_dup 2))])]
3126 "operands[2] = GEN_INT ((INTVAL (operands[2]) & 0xff) + 1);")
3127
3128 (define_split
3129 [(set (match_operand:BLK 0 "memory_operand" "")
3130 (match_operand:BLK 1 "memory_operand" ""))
3131 (use (match_operand 2 "register_operand" ""))
3132 (use (match_operand 3 "memory_operand" ""))
3133 (clobber (scratch))]
3134 "reload_completed"
3135 [(parallel
3136 [(unspec [(match_dup 2) (match_dup 3)
3137 (const_int 0)] UNSPEC_EXECUTE)
3138 (set (match_dup 0) (match_dup 1))
3139 (use (const_int 1))])]
3140 "")
3141
3142 (define_split
3143 [(set (match_operand:BLK 0 "memory_operand" "")
3144 (match_operand:BLK 1 "memory_operand" ""))
3145 (use (match_operand 2 "register_operand" ""))
3146 (use (const:BLK (unspec:BLK [(const_int 0)] UNSPEC_INSN)))
3147 (clobber (scratch))]
3148 "TARGET_Z10 && reload_completed"
3149 [(parallel
3150 [(unspec [(match_dup 2) (const_int 0)
3151 (label_ref (match_dup 3))] UNSPEC_EXECUTE)
3152 (set (match_dup 0) (match_dup 1))
3153 (use (const_int 1))])]
3154 "operands[3] = gen_label_rtx ();")
3155
3156 (define_split
3157 [(set (match_operand:BLK 0 "memory_operand" "")
3158 (match_operand:BLK 1 "memory_operand" ""))
3159 (use (match_operand 2 "register_operand" ""))
3160 (use (const:BLK (unspec:BLK [(const_int 0)] UNSPEC_INSN)))
3161 (clobber (match_operand 3 "register_operand" ""))]
3162 "reload_completed && TARGET_CPU_ZARCH"
3163 [(set (match_dup 3) (label_ref (match_dup 4)))
3164 (parallel
3165 [(unspec [(match_dup 2) (mem:BLK (match_dup 3))
3166 (label_ref (match_dup 4))] UNSPEC_EXECUTE)
3167 (set (match_dup 0) (match_dup 1))
3168 (use (const_int 1))])]
3169 "operands[4] = gen_label_rtx ();")
3170
3171 ; Move a block of arbitrary length.
3172
3173 (define_expand "movmem_long"
3174 [(parallel
3175 [(clobber (match_dup 2))
3176 (clobber (match_dup 3))
3177 (set (match_operand:BLK 0 "memory_operand" "")
3178 (match_operand:BLK 1 "memory_operand" ""))
3179 (use (match_operand 2 "general_operand" ""))
3180 (use (match_dup 3))
3181 (clobber (reg:CC CC_REGNUM))])]
3182 ""
3183 {
3184 machine_mode sreg_mode = TARGET_ZARCH ? DImode : SImode;
3185 machine_mode dreg_mode = TARGET_ZARCH ? TImode : DImode;
3186 rtx reg0 = gen_reg_rtx (dreg_mode);
3187 rtx reg1 = gen_reg_rtx (dreg_mode);
3188 rtx addr0 = gen_lowpart (Pmode, gen_highpart (sreg_mode, reg0));
3189 rtx addr1 = gen_lowpart (Pmode, gen_highpart (sreg_mode, reg1));
3190 rtx len0 = gen_lowpart (Pmode, reg0);
3191 rtx len1 = gen_lowpart (Pmode, reg1);
3192
3193 emit_clobber (reg0);
3194 emit_move_insn (addr0, force_operand (XEXP (operands[0], 0), NULL_RTX));
3195 emit_move_insn (len0, operands[2]);
3196
3197 emit_clobber (reg1);
3198 emit_move_insn (addr1, force_operand (XEXP (operands[1], 0), NULL_RTX));
3199 emit_move_insn (len1, operands[2]);
3200
3201 operands[0] = replace_equiv_address_nv (operands[0], addr0);
3202 operands[1] = replace_equiv_address_nv (operands[1], addr1);
3203 operands[2] = reg0;
3204 operands[3] = reg1;
3205 })
3206
3207 (define_insn "*movmem_long"
3208 [(clobber (match_operand:<DBL> 0 "register_operand" "=d"))
3209 (clobber (match_operand:<DBL> 1 "register_operand" "=d"))
3210 (set (mem:BLK (subreg:P (match_operand:<DBL> 2 "register_operand" "0") 0))
3211 (mem:BLK (subreg:P (match_operand:<DBL> 3 "register_operand" "1") 0)))
3212 (use (match_dup 2))
3213 (use (match_dup 3))
3214 (clobber (reg:CC CC_REGNUM))]
3215 "TARGET_64BIT || !TARGET_ZARCH"
3216 "mvcle\t%0,%1,0\;jo\t.-4"
3217 [(set_attr "length" "8")
3218 (set_attr "type" "vs")])
3219
3220 (define_insn "*movmem_long_31z"
3221 [(clobber (match_operand:TI 0 "register_operand" "=d"))
3222 (clobber (match_operand:TI 1 "register_operand" "=d"))
3223 (set (mem:BLK (subreg:SI (match_operand:TI 2 "register_operand" "0") 4))
3224 (mem:BLK (subreg:SI (match_operand:TI 3 "register_operand" "1") 4)))
3225 (use (match_dup 2))
3226 (use (match_dup 3))
3227 (clobber (reg:CC CC_REGNUM))]
3228 "!TARGET_64BIT && TARGET_ZARCH"
3229 "mvcle\t%0,%1,0\;jo\t.-4"
3230 [(set_attr "length" "8")
3231 (set_attr "type" "vs")])
3232
3233
3234 ;
3235 ; Test data class.
3236 ;
3237
3238 (define_expand "signbit<mode>2"
3239 [(set (reg:CCZ CC_REGNUM)
3240 (unspec:CCZ [(match_operand:FP_ALL 1 "register_operand" "f")
3241 (match_dup 2)]
3242 UNSPEC_TDC_INSN))
3243 (set (match_operand:SI 0 "register_operand" "=d")
3244 (unspec:SI [(reg:CCZ CC_REGNUM)] UNSPEC_CC_TO_INT))]
3245 "TARGET_HARD_FLOAT"
3246 {
3247 operands[2] = GEN_INT (S390_TDC_SIGNBIT_SET);
3248 })
3249
3250 (define_expand "isinf<mode>2"
3251 [(set (reg:CCZ CC_REGNUM)
3252 (unspec:CCZ [(match_operand:FP_ALL 1 "register_operand" "f")
3253 (match_dup 2)]
3254 UNSPEC_TDC_INSN))
3255 (set (match_operand:SI 0 "register_operand" "=d")
3256 (unspec:SI [(reg:CCZ CC_REGNUM)] UNSPEC_CC_TO_INT))]
3257 "TARGET_HARD_FLOAT"
3258 {
3259 operands[2] = GEN_INT (S390_TDC_INFINITY);
3260 })
3261
3262 ; This extracts CC into a GPR properly shifted. The actual IPM
3263 ; instruction will be issued by reload. The constraint of operand 1
3264 ; forces reload to use a GPR. So reload will issue a movcc insn for
3265 ; copying CC into a GPR first.
3266 (define_insn_and_split "*cc_to_int"
3267 [(set (match_operand:SI 0 "nonimmediate_operand" "=d")
3268 (unspec:SI [(match_operand 1 "register_operand" "0")]
3269 UNSPEC_CC_TO_INT))]
3270 "operands != NULL"
3271 "#"
3272 "reload_completed"
3273 [(set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 28)))])
3274
3275 ; This insn is used to generate all variants of the Test Data Class
3276 ; instruction, namely tcxb, tcdb, and tceb. The insn's first operand
3277 ; is the register to be tested and the second one is the bit mask
3278 ; specifying the required test(s).
3279 ;
3280 ; tcxb, tcdb, tceb, tdcxt, tdcdt, tdcet
3281 (define_insn "*TDC_insn_<mode>"
3282 [(set (reg:CCZ CC_REGNUM)
3283 (unspec:CCZ [(match_operand:FP_ALL 0 "register_operand" "f")
3284 (match_operand:SI 1 "const_int_operand")] UNSPEC_TDC_INSN))]
3285 "TARGET_HARD_FLOAT"
3286 "t<_d>c<xde><bt>\t%0,%1"
3287 [(set_attr "op_type" "RXE")
3288 (set_attr "type" "fsimp<mode>")])
3289
3290
3291
3292 ;
3293 ; setmemM instruction pattern(s).
3294 ;
3295
3296 (define_expand "setmem<mode>"
3297 [(set (match_operand:BLK 0 "memory_operand" "")
3298 (match_operand:QI 2 "general_operand" ""))
3299 (use (match_operand:GPR 1 "general_operand" ""))
3300 (match_operand 3 "" "")]
3301 ""
3302 "s390_expand_setmem (operands[0], operands[1], operands[2]); DONE;")
3303
3304 ; Clear a block that is up to 256 bytes in length.
3305 ; The block length is taken as (operands[1] % 256) + 1.
3306
3307 (define_expand "clrmem_short"
3308 [(parallel
3309 [(set (match_operand:BLK 0 "memory_operand" "")
3310 (const_int 0))
3311 (use (match_operand 1 "nonmemory_operand" ""))
3312 (use (const:BLK (unspec:BLK [(const_int 0)] UNSPEC_INSN)))
3313 (clobber (match_dup 2))
3314 (clobber (reg:CC CC_REGNUM))])]
3315 ""
3316 "operands[2] = gen_rtx_SCRATCH (Pmode);")
3317
3318 (define_insn "*clrmem_short"
3319 [(set (match_operand:BLK 0 "memory_operand" "=Q,Q,Q,Q")
3320 (const_int 0))
3321 (use (match_operand 1 "nonmemory_operand" "n,a,a,a"))
3322 (use (match_operand 2 "immediate_operand" "X,R,X,X"))
3323 (clobber (match_scratch:P 3 "=X,X,X,&a"))
3324 (clobber (reg:CC CC_REGNUM))]
3325 "(GET_MODE (operands[1]) == Pmode || GET_MODE (operands[1]) == VOIDmode)"
3326 "#"
3327 [(set_attr "type" "cs")
3328 (set_attr "cpu_facility" "*,*,z10,cpu_zarch")])
3329
3330 (define_split
3331 [(set (match_operand:BLK 0 "memory_operand" "")
3332 (const_int 0))
3333 (use (match_operand 1 "const_int_operand" ""))
3334 (use (match_operand 2 "immediate_operand" ""))
3335 (clobber (scratch))
3336 (clobber (reg:CC CC_REGNUM))]
3337 "reload_completed"
3338 [(parallel
3339 [(set (match_dup 0) (const_int 0))
3340 (use (match_dup 1))
3341 (clobber (reg:CC CC_REGNUM))])]
3342 "operands[1] = GEN_INT ((INTVAL (operands[1]) & 0xff) + 1);")
3343
3344 (define_split
3345 [(set (match_operand:BLK 0 "memory_operand" "")
3346 (const_int 0))
3347 (use (match_operand 1 "register_operand" ""))
3348 (use (match_operand 2 "memory_operand" ""))
3349 (clobber (scratch))
3350 (clobber (reg:CC CC_REGNUM))]
3351 "reload_completed"
3352 [(parallel
3353 [(unspec [(match_dup 1) (match_dup 2)
3354 (const_int 0)] UNSPEC_EXECUTE)
3355 (set (match_dup 0) (const_int 0))
3356 (use (const_int 1))
3357 (clobber (reg:CC CC_REGNUM))])]
3358 "")
3359
3360 (define_split
3361 [(set (match_operand:BLK 0 "memory_operand" "")
3362 (const_int 0))
3363 (use (match_operand 1 "register_operand" ""))
3364 (use (const:BLK (unspec:BLK [(const_int 0)] UNSPEC_INSN)))
3365 (clobber (scratch))
3366 (clobber (reg:CC CC_REGNUM))]
3367 "TARGET_Z10 && reload_completed"
3368 [(parallel
3369 [(unspec [(match_dup 1) (const_int 0)
3370 (label_ref (match_dup 3))] UNSPEC_EXECUTE)
3371 (set (match_dup 0) (const_int 0))
3372 (use (const_int 1))
3373 (clobber (reg:CC CC_REGNUM))])]
3374 "operands[3] = gen_label_rtx ();")
3375
3376 (define_split
3377 [(set (match_operand:BLK 0 "memory_operand" "")
3378 (const_int 0))
3379 (use (match_operand 1 "register_operand" ""))
3380 (use (const:BLK (unspec:BLK [(const_int 0)] UNSPEC_INSN)))
3381 (clobber (match_operand 2 "register_operand" ""))
3382 (clobber (reg:CC CC_REGNUM))]
3383 "reload_completed && TARGET_CPU_ZARCH"
3384 [(set (match_dup 2) (label_ref (match_dup 3)))
3385 (parallel
3386 [(unspec [(match_dup 1) (mem:BLK (match_dup 2))
3387 (label_ref (match_dup 3))] UNSPEC_EXECUTE)
3388 (set (match_dup 0) (const_int 0))
3389 (use (const_int 1))
3390 (clobber (reg:CC CC_REGNUM))])]
3391 "operands[3] = gen_label_rtx ();")
3392
3393 ; Initialize a block of arbitrary length with (operands[2] % 256).
3394
3395 (define_expand "setmem_long_<P:mode>"
3396 [(parallel
3397 [(clobber (match_dup 1))
3398 (set (match_operand:BLK 0 "memory_operand" "")
3399 (unspec:BLK [(match_operand:P 2 "setmem_operand" "")
3400 (match_dup 4)] UNSPEC_REPLICATE_BYTE))
3401 (use (match_dup 3))
3402 (clobber (reg:CC CC_REGNUM))])]
3403 ""
3404 {
3405 machine_mode sreg_mode = TARGET_ZARCH ? DImode : SImode;
3406 machine_mode dreg_mode = TARGET_ZARCH ? TImode : DImode;
3407 rtx reg0 = gen_reg_rtx (dreg_mode);
3408 rtx reg1 = gen_reg_rtx (dreg_mode);
3409 rtx addr0 = gen_lowpart (Pmode, gen_highpart (sreg_mode, reg0));
3410 rtx len0 = gen_lowpart (Pmode, reg0);
3411
3412 emit_clobber (reg0);
3413 emit_move_insn (addr0, force_operand (XEXP (operands[0], 0), NULL_RTX));
3414 emit_move_insn (len0, operands[1]);
3415
3416 emit_move_insn (reg1, const0_rtx);
3417
3418 operands[0] = replace_equiv_address_nv (operands[0], addr0);
3419 operands[1] = reg0;
3420 operands[3] = reg1;
3421 operands[4] = gen_lowpart (Pmode, operands[1]);
3422 })
3423
3424 ; Patterns for 31 bit + Esa and 64 bit + Zarch.
3425
3426 (define_insn "*setmem_long"
3427 [(clobber (match_operand:<DBL> 0 "register_operand" "=d"))
3428 (set (mem:BLK (subreg:P (match_operand:<DBL> 3 "register_operand" "0") 0))
3429 (unspec:BLK [(match_operand:P 2 "setmem_operand" "Y")
3430 (subreg:P (match_dup 3) <modesize>)]
3431 UNSPEC_REPLICATE_BYTE))
3432 (use (match_operand:<DBL> 1 "register_operand" "d"))
3433 (clobber (reg:CC CC_REGNUM))]
3434 "TARGET_64BIT || !TARGET_ZARCH"
3435 "mvcle\t%0,%1,%Y2\;jo\t.-4"
3436 [(set_attr "length" "8")
3437 (set_attr "type" "vs")])
3438
3439 (define_insn "*setmem_long_and"
3440 [(clobber (match_operand:<DBL> 0 "register_operand" "=d"))
3441 (set (mem:BLK (subreg:P (match_operand:<DBL> 3 "register_operand" "0") 0))
3442 (unspec:BLK [(zero_extend:P (match_operand:QI 2 "setmem_operand" "Y"))
3443 (subreg:P (match_dup 3) <modesize>)]
3444 UNSPEC_REPLICATE_BYTE))
3445 (use (match_operand:<DBL> 1 "register_operand" "d"))
3446 (clobber (reg:CC CC_REGNUM))]
3447 "(TARGET_64BIT || !TARGET_ZARCH)"
3448 "mvcle\t%0,%1,%Y2\;jo\t.-4"
3449 [(set_attr "length" "8")
3450 (set_attr "type" "vs")])
3451
3452 ; Variants for 31 bit + Zarch, necessary because of the odd in-register offsets
3453 ; of the SImode subregs.
3454
3455 (define_insn "*setmem_long_31z"
3456 [(clobber (match_operand:TI 0 "register_operand" "=d"))
3457 (set (mem:BLK (subreg:SI (match_operand:TI 3 "register_operand" "0") 4))
3458 (unspec:BLK [(match_operand:SI 2 "setmem_operand" "Y")
3459 (subreg:SI (match_dup 3) 12)] UNSPEC_REPLICATE_BYTE))
3460 (use (match_operand:TI 1 "register_operand" "d"))
3461 (clobber (reg:CC CC_REGNUM))]
3462 "!TARGET_64BIT && TARGET_ZARCH"
3463 "mvcle\t%0,%1,%Y2\;jo\t.-4"
3464 [(set_attr "length" "8")
3465 (set_attr "type" "vs")])
3466
3467 (define_insn "*setmem_long_and_31z"
3468 [(clobber (match_operand:TI 0 "register_operand" "=d"))
3469 (set (mem:BLK (subreg:SI (match_operand:TI 3 "register_operand" "0") 4))
3470 (unspec:BLK [(zero_extend:SI (match_operand:QI 2 "setmem_operand" "Y"))
3471 (subreg:SI (match_dup 3) 12)] UNSPEC_REPLICATE_BYTE))
3472 (use (match_operand:TI 1 "register_operand" "d"))
3473 (clobber (reg:CC CC_REGNUM))]
3474 "(!TARGET_64BIT && TARGET_ZARCH)"
3475 "mvcle\t%0,%1,%Y2\;jo\t.-4"
3476 [(set_attr "length" "8")
3477 (set_attr "type" "vs")])
3478
3479 ;
3480 ; cmpmemM instruction pattern(s).
3481 ;
3482
3483 (define_expand "cmpmemsi"
3484 [(set (match_operand:SI 0 "register_operand" "")
3485 (compare:SI (match_operand:BLK 1 "memory_operand" "")
3486 (match_operand:BLK 2 "memory_operand" "") ) )
3487 (use (match_operand:SI 3 "general_operand" ""))
3488 (use (match_operand:SI 4 "" ""))]
3489 ""
3490 {
3491 if (s390_expand_cmpmem (operands[0], operands[1],
3492 operands[2], operands[3]))
3493 DONE;
3494 else
3495 FAIL;
3496 })
3497
3498 ; Compare a block that is up to 256 bytes in length.
3499 ; The block length is taken as (operands[2] % 256) + 1.
3500
3501 (define_expand "cmpmem_short"
3502 [(parallel
3503 [(set (reg:CCU CC_REGNUM)
3504 (compare:CCU (match_operand:BLK 0 "memory_operand" "")
3505 (match_operand:BLK 1 "memory_operand" "")))
3506 (use (match_operand 2 "nonmemory_operand" ""))
3507 (use (const:BLK (unspec:BLK [(const_int 0)] UNSPEC_INSN)))
3508 (clobber (match_dup 3))])]
3509 ""
3510 "operands[3] = gen_rtx_SCRATCH (Pmode);")
3511
3512 (define_insn "*cmpmem_short"
3513 [(set (reg:CCU CC_REGNUM)
3514 (compare:CCU (match_operand:BLK 0 "memory_operand" "Q,Q,Q,Q")
3515 (match_operand:BLK 1 "memory_operand" "Q,Q,Q,Q")))
3516 (use (match_operand 2 "nonmemory_operand" "n,a,a,a"))
3517 (use (match_operand 3 "immediate_operand" "X,R,X,X"))
3518 (clobber (match_scratch:P 4 "=X,X,X,&a"))]
3519 "(GET_MODE (operands[2]) == Pmode || GET_MODE (operands[2]) == VOIDmode)"
3520 "#"
3521 [(set_attr "type" "cs")
3522 (set_attr "cpu_facility" "*,*,z10,cpu_zarch")])
3523
3524 (define_split
3525 [(set (reg:CCU CC_REGNUM)
3526 (compare:CCU (match_operand:BLK 0 "memory_operand" "")
3527 (match_operand:BLK 1 "memory_operand" "")))
3528 (use (match_operand 2 "const_int_operand" ""))
3529 (use (match_operand 3 "immediate_operand" ""))
3530 (clobber (scratch))]
3531 "reload_completed"
3532 [(parallel
3533 [(set (reg:CCU CC_REGNUM) (compare:CCU (match_dup 0) (match_dup 1)))
3534 (use (match_dup 2))])]
3535 "operands[2] = GEN_INT ((INTVAL (operands[2]) & 0xff) + 1);")
3536
3537 (define_split
3538 [(set (reg:CCU CC_REGNUM)
3539 (compare:CCU (match_operand:BLK 0 "memory_operand" "")
3540 (match_operand:BLK 1 "memory_operand" "")))
3541 (use (match_operand 2 "register_operand" ""))
3542 (use (match_operand 3 "memory_operand" ""))
3543 (clobber (scratch))]
3544 "reload_completed"
3545 [(parallel
3546 [(unspec [(match_dup 2) (match_dup 3)
3547 (const_int 0)] UNSPEC_EXECUTE)
3548 (set (reg:CCU CC_REGNUM) (compare:CCU (match_dup 0) (match_dup 1)))
3549 (use (const_int 1))])]
3550 "")
3551
3552 (define_split
3553 [(set (reg:CCU CC_REGNUM)
3554 (compare:CCU (match_operand:BLK 0 "memory_operand" "")
3555 (match_operand:BLK 1 "memory_operand" "")))
3556 (use (match_operand 2 "register_operand" ""))
3557 (use (const:BLK (unspec:BLK [(const_int 0)] UNSPEC_INSN)))
3558 (clobber (scratch))]
3559 "TARGET_Z10 && reload_completed"
3560 [(parallel
3561 [(unspec [(match_dup 2) (const_int 0)
3562 (label_ref (match_dup 4))] UNSPEC_EXECUTE)
3563 (set (reg:CCU CC_REGNUM) (compare:CCU (match_dup 0) (match_dup 1)))
3564 (use (const_int 1))])]
3565 "operands[4] = gen_label_rtx ();")
3566
3567 (define_split
3568 [(set (reg:CCU CC_REGNUM)
3569 (compare:CCU (match_operand:BLK 0 "memory_operand" "")
3570 (match_operand:BLK 1 "memory_operand" "")))
3571 (use (match_operand 2 "register_operand" ""))
3572 (use (const:BLK (unspec:BLK [(const_int 0)] UNSPEC_INSN)))
3573 (clobber (match_operand 3 "register_operand" ""))]
3574 "reload_completed && TARGET_CPU_ZARCH"
3575 [(set (match_dup 3) (label_ref (match_dup 4)))
3576 (parallel
3577 [(unspec [(match_dup 2) (mem:BLK (match_dup 3))
3578 (label_ref (match_dup 4))] UNSPEC_EXECUTE)
3579 (set (reg:CCU CC_REGNUM) (compare:CCU (match_dup 0) (match_dup 1)))
3580 (use (const_int 1))])]
3581 "operands[4] = gen_label_rtx ();")
3582
3583 ; Compare a block of arbitrary length.
3584
3585 (define_expand "cmpmem_long"
3586 [(parallel
3587 [(clobber (match_dup 2))
3588 (clobber (match_dup 3))
3589 (set (reg:CCU CC_REGNUM)
3590 (compare:CCU (match_operand:BLK 0 "memory_operand" "")
3591 (match_operand:BLK 1 "memory_operand" "")))
3592 (use (match_operand 2 "general_operand" ""))
3593 (use (match_dup 3))])]
3594 ""
3595 {
3596 machine_mode sreg_mode = TARGET_ZARCH ? DImode : SImode;
3597 machine_mode dreg_mode = TARGET_ZARCH ? TImode : DImode;
3598 rtx reg0 = gen_reg_rtx (dreg_mode);
3599 rtx reg1 = gen_reg_rtx (dreg_mode);
3600 rtx addr0 = gen_lowpart (Pmode, gen_highpart (sreg_mode, reg0));
3601 rtx addr1 = gen_lowpart (Pmode, gen_highpart (sreg_mode, reg1));
3602 rtx len0 = gen_lowpart (Pmode, reg0);
3603 rtx len1 = gen_lowpart (Pmode, reg1);
3604
3605 emit_clobber (reg0);
3606 emit_move_insn (addr0, force_operand (XEXP (operands[0], 0), NULL_RTX));
3607 emit_move_insn (len0, operands[2]);
3608
3609 emit_clobber (reg1);
3610 emit_move_insn (addr1, force_operand (XEXP (operands[1], 0), NULL_RTX));
3611 emit_move_insn (len1, operands[2]);
3612
3613 operands[0] = replace_equiv_address_nv (operands[0], addr0);
3614 operands[1] = replace_equiv_address_nv (operands[1], addr1);
3615 operands[2] = reg0;
3616 operands[3] = reg1;
3617 })
3618
3619 (define_insn "*cmpmem_long"
3620 [(clobber (match_operand:<DBL> 0 "register_operand" "=d"))
3621 (clobber (match_operand:<DBL> 1 "register_operand" "=d"))
3622 (set (reg:CCU CC_REGNUM)
3623 (compare:CCU (mem:BLK (subreg:P (match_operand:<DBL> 2 "register_operand" "0") 0))
3624 (mem:BLK (subreg:P (match_operand:<DBL> 3 "register_operand" "1") 0))))
3625 (use (match_dup 2))
3626 (use (match_dup 3))]
3627 "TARGET_64BIT || !TARGET_ZARCH"
3628 "clcle\t%0,%1,0\;jo\t.-4"
3629 [(set_attr "length" "8")
3630 (set_attr "type" "vs")])
3631
3632 (define_insn "*cmpmem_long_31z"
3633 [(clobber (match_operand:TI 0 "register_operand" "=d"))
3634 (clobber (match_operand:TI 1 "register_operand" "=d"))
3635 (set (reg:CCU CC_REGNUM)
3636 (compare:CCU (mem:BLK (subreg:SI (match_operand:TI 2 "register_operand" "0") 4))
3637 (mem:BLK (subreg:SI (match_operand:TI 3 "register_operand" "1") 4))))
3638 (use (match_dup 2))
3639 (use (match_dup 3))]
3640 "!TARGET_64BIT && TARGET_ZARCH"
3641 "clcle\t%0,%1,0\;jo\t.-4"
3642 [(set_attr "op_type" "NN")
3643 (set_attr "type" "vs")
3644 (set_attr "length" "8")])
3645
3646 ; Convert CCUmode condition code to integer.
3647 ; Result is zero if EQ, positive if LTU, negative if GTU.
3648
3649 (define_insn_and_split "cmpint"
3650 [(set (match_operand:SI 0 "register_operand" "=d")
3651 (unspec:SI [(match_operand:CCU 1 "register_operand" "0")]
3652 UNSPEC_STRCMPCC_TO_INT))
3653 (clobber (reg:CC CC_REGNUM))]
3654 ""
3655 "#"
3656 "reload_completed"
3657 [(set (match_dup 0) (ashift:SI (match_dup 0) (const_int 2)))
3658 (parallel
3659 [(set (match_dup 0) (ashiftrt:SI (match_dup 0) (const_int 30)))
3660 (clobber (reg:CC CC_REGNUM))])])
3661
3662 (define_insn_and_split "*cmpint_cc"
3663 [(set (reg CC_REGNUM)
3664 (compare (unspec:SI [(match_operand:CCU 1 "register_operand" "0")]
3665 UNSPEC_STRCMPCC_TO_INT)
3666 (const_int 0)))
3667 (set (match_operand:SI 0 "register_operand" "=d")
3668 (unspec:SI [(match_dup 1)] UNSPEC_STRCMPCC_TO_INT))]
3669 "s390_match_ccmode (insn, CCSmode)"
3670 "#"
3671 "&& reload_completed"
3672 [(set (match_dup 0) (ashift:SI (match_dup 0) (const_int 2)))
3673 (parallel
3674 [(set (match_dup 2) (match_dup 3))
3675 (set (match_dup 0) (ashiftrt:SI (match_dup 0) (const_int 30)))])]
3676 {
3677 rtx result = gen_rtx_ASHIFTRT (SImode, operands[0], GEN_INT (30));
3678 operands[2] = SET_DEST (XVECEXP (PATTERN (curr_insn), 0, 0));
3679 operands[3] = gen_rtx_COMPARE (GET_MODE (operands[2]), result, const0_rtx);
3680 })
3681
3682 (define_insn_and_split "*cmpint_sign"
3683 [(set (match_operand:DI 0 "register_operand" "=d")
3684 (sign_extend:DI (unspec:SI [(match_operand:CCU 1 "register_operand" "0")]
3685 UNSPEC_STRCMPCC_TO_INT)))
3686 (clobber (reg:CC CC_REGNUM))]
3687 "TARGET_ZARCH"
3688 "#"
3689 "&& reload_completed"
3690 [(set (match_dup 0) (ashift:DI (match_dup 0) (const_int 34)))
3691 (parallel
3692 [(set (match_dup 0) (ashiftrt:DI (match_dup 0) (const_int 62)))
3693 (clobber (reg:CC CC_REGNUM))])])
3694
3695 (define_insn_and_split "*cmpint_sign_cc"
3696 [(set (reg CC_REGNUM)
3697 (compare (ashiftrt:DI (ashift:DI (subreg:DI
3698 (unspec:SI [(match_operand:CCU 1 "register_operand" "0")]
3699 UNSPEC_STRCMPCC_TO_INT) 0)
3700 (const_int 32)) (const_int 32))
3701 (const_int 0)))
3702 (set (match_operand:DI 0 "register_operand" "=d")
3703 (sign_extend:DI (unspec:SI [(match_dup 1)] UNSPEC_STRCMPCC_TO_INT)))]
3704 "s390_match_ccmode (insn, CCSmode) && TARGET_ZARCH"
3705 "#"
3706 "&& reload_completed"
3707 [(set (match_dup 0) (ashift:DI (match_dup 0) (const_int 34)))
3708 (parallel
3709 [(set (match_dup 2) (match_dup 3))
3710 (set (match_dup 0) (ashiftrt:DI (match_dup 0) (const_int 62)))])]
3711 {
3712 rtx result = gen_rtx_ASHIFTRT (DImode, operands[0], GEN_INT (62));
3713 operands[2] = SET_DEST (XVECEXP (PATTERN (curr_insn), 0, 0));
3714 operands[3] = gen_rtx_COMPARE (GET_MODE (operands[2]), result, const0_rtx);
3715 })
3716
3717
3718 ;;
3719 ;;- Conversion instructions.
3720 ;;
3721
3722 (define_insn "*sethighpartsi"
3723 [(set (match_operand:SI 0 "register_operand" "=d,d")
3724 (unspec:SI [(match_operand:BLK 1 "s_operand" "Q,S")
3725 (match_operand 2 "const_int_operand" "n,n")] UNSPEC_ICM))
3726 (clobber (reg:CC CC_REGNUM))]
3727 ""
3728 "@
3729 icm\t%0,%2,%S1
3730 icmy\t%0,%2,%S1"
3731 [(set_attr "op_type" "RS,RSY")
3732 (set_attr "cpu_facility" "*,longdisp")
3733 (set_attr "z10prop" "z10_super_E1,z10_super_E1")])
3734
3735 (define_insn "*sethighpartdi_64"
3736 [(set (match_operand:DI 0 "register_operand" "=d")
3737 (unspec:DI [(match_operand:BLK 1 "s_operand" "S")
3738 (match_operand 2 "const_int_operand" "n")] UNSPEC_ICM))
3739 (clobber (reg:CC CC_REGNUM))]
3740 "TARGET_ZARCH"
3741 "icmh\t%0,%2,%S1"
3742 [(set_attr "op_type" "RSY")
3743 (set_attr "z10prop" "z10_super")])
3744
3745 (define_insn "*sethighpartdi_31"
3746 [(set (match_operand:DI 0 "register_operand" "=d,d")
3747 (unspec:DI [(match_operand:BLK 1 "s_operand" "Q,S")
3748 (match_operand 2 "const_int_operand" "n,n")] UNSPEC_ICM))
3749 (clobber (reg:CC CC_REGNUM))]
3750 "!TARGET_ZARCH"
3751 "@
3752 icm\t%0,%2,%S1
3753 icmy\t%0,%2,%S1"
3754 [(set_attr "op_type" "RS,RSY")
3755 (set_attr "cpu_facility" "*,longdisp")
3756 (set_attr "z10prop" "z10_super_E1,z10_super_E1")])
3757
3758 ;
3759 ; extv instruction patterns
3760 ;
3761
3762 ; FIXME: This expander needs to be converted from DI to GPR as well
3763 ; after resolving some issues with it.
3764
3765 (define_expand "extzv"
3766 [(parallel
3767 [(set (match_operand:DI 0 "register_operand" "=d")
3768 (zero_extract:DI
3769 (match_operand:DI 1 "register_operand" "d")
3770 (match_operand 2 "const_int_operand" "") ; size
3771 (match_operand 3 "const_int_operand" ""))) ; start
3772 (clobber (reg:CC CC_REGNUM))])]
3773 "TARGET_Z10"
3774 {
3775 if (! EXTRACT_ARGS_IN_RANGE (INTVAL (operands[2]), INTVAL (operands[3]), 64))
3776 FAIL;
3777 /* Starting with zEC12 there is risbgn not clobbering CC. */
3778 if (TARGET_ZEC12)
3779 {
3780 emit_move_insn (operands[0],
3781 gen_rtx_ZERO_EXTRACT (DImode,
3782 operands[1],
3783 operands[2],
3784 operands[3]));
3785 DONE;
3786 }
3787 })
3788
3789 (define_insn "*extzv<mode><clobbercc_or_nocc>"
3790 [(set (match_operand:GPR 0 "register_operand" "=d")
3791 (zero_extract:GPR
3792 (match_operand:GPR 1 "register_operand" "d")
3793 (match_operand 2 "const_int_operand" "") ; size
3794 (match_operand 3 "const_int_operand" ""))) ; start
3795 ]
3796 "<z10_or_zEC12_cond>
3797 && EXTRACT_ARGS_IN_RANGE (INTVAL (operands[2]), INTVAL (operands[3]),
3798 GET_MODE_BITSIZE (<MODE>mode))"
3799 "<risbg_n>\t%0,%1,64-%2,128+63,<bitoff_plus>%3+%2" ; dst, src, start, end, shift
3800 [(set_attr "op_type" "RIE")
3801 (set_attr "z10prop" "z10_super_E1")])
3802
3803 ; 64 bit: (a & -16) | ((b >> 8) & 15)
3804 (define_insn "*extzvdi<clobbercc_or_nocc>_lshiftrt"
3805 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+d")
3806 (match_operand 1 "const_int_operand" "") ; size
3807 (match_operand 2 "const_int_operand" "")) ; start
3808 (lshiftrt:DI (match_operand:DI 3 "register_operand" "d")
3809 (match_operand:DI 4 "nonzero_shift_count_operand" "")))]
3810 "<z10_or_zEC12_cond>
3811 && EXTRACT_ARGS_IN_RANGE (INTVAL (operands[1]), INTVAL (operands[2]), 64)
3812 && 64 - UINTVAL (operands[4]) >= UINTVAL (operands[1])"
3813 "<risbg_n>\t%0,%3,%2,%2+%1-1,128-%2-%1-%4"
3814 [(set_attr "op_type" "RIE")
3815 (set_attr "z10prop" "z10_super_E1")])
3816
3817 ; 32 bit: (a & -16) | ((b >> 8) & 15)
3818 (define_insn "*<risbg_n>_ior_and_sr_ze"
3819 [(set (match_operand:SI 0 "register_operand" "=d")
3820 (ior:SI (and:SI
3821 (match_operand:SI 1 "register_operand" "0")
3822 (match_operand:SI 2 "const_int_operand" ""))
3823 (subreg:SI
3824 (zero_extract:DI
3825 (match_operand:DI 3 "register_operand" "d")
3826 (match_operand 4 "const_int_operand" "") ; size
3827 (match_operand 5 "const_int_operand" "")) ; start
3828 4)))]
3829 "<z10_or_zEC12_cond>
3830 && EXTRACT_ARGS_IN_RANGE (INTVAL (operands[4]), INTVAL (operands[5]), 64)
3831 && UINTVAL (operands[2]) == (~(0ULL) << UINTVAL (operands[4]))"
3832 "<risbg_n>\t%0,%3,64-%4,63,%4+%5"
3833 [(set_attr "op_type" "RIE")
3834 (set_attr "z10prop" "z10_super_E1")])
3835
3836 ; ((int)foo >> 10) & 1;
3837 (define_insn "*extract1bitdi<clobbercc_or_nocc>"
3838 [(set (match_operand:DI 0 "register_operand" "=d")
3839 (ne:DI (zero_extract:DI
3840 (match_operand:DI 1 "register_operand" "d")
3841 (const_int 1) ; size
3842 (match_operand 2 "const_int_operand" "")) ; start
3843 (const_int 0)))]
3844 "<z10_or_zEC12_cond>
3845 && EXTRACT_ARGS_IN_RANGE (1, INTVAL (operands[2]), 64)"
3846 "<risbg_n>\t%0,%1,64-1,128+63,%2+1" ; dst, src, start, end, shift
3847 [(set_attr "op_type" "RIE")
3848 (set_attr "z10prop" "z10_super_E1")])
3849
3850 (define_insn "*<risbg_n>_and_subregdi_rotr"
3851 [(set (match_operand:DI 0 "register_operand" "=d")
3852 (and:DI (subreg:DI
3853 (rotate:SINT (match_operand:SINT 1 "register_operand" "d")
3854 (match_operand:SINT 2 "const_int_operand" "")) 0)
3855 (match_operand:DI 3 "contiguous_bitmask_operand" "")))]
3856 "<z10_or_zEC12_cond>
3857 && UINTVAL (operands[3]) < (1ULL << (UINTVAL (operands[2]) & 0x3f))"
3858 "<risbg_n>\t%0,%1,%s3,128+%e3,<bitoff_plus>%2" ; dst, src, start, end, shift
3859 [(set_attr "op_type" "RIE")
3860 (set_attr "z10prop" "z10_super_E1")])
3861
3862 (define_insn "*<risbg_n>_and_subregdi_rotl"
3863 [(set (match_operand:DI 0 "register_operand" "=d")
3864 (and:DI (subreg:DI
3865 (rotate:SINT (match_operand:SINT 1 "register_operand" "d")
3866 (match_operand:SINT 2 "const_int_operand" "")) 0)
3867 (match_operand:DI 3 "contiguous_bitmask_operand" "")))]
3868 "<z10_or_zEC12_cond>
3869 && !(UINTVAL (operands[3]) & ((1ULL << (UINTVAL (operands[2]) & 0x3f)) - 1))"
3870 "<risbg_n>\t%0,%1,%s3,128+%e3,%2" ; dst, src, start, end, shift
3871 [(set_attr "op_type" "RIE")
3872 (set_attr "z10prop" "z10_super_E1")])
3873
3874 (define_insn "*<risbg_n>_di_and_rot"
3875 [(set (match_operand:DI 0 "register_operand" "=d")
3876 (and:DI (rotate:DI (match_operand:DI 1 "register_operand" "d")
3877 (match_operand:DI 2 "const_int_operand" ""))
3878 (match_operand:DI 3 "contiguous_bitmask_operand" "")))]
3879 "<z10_or_zEC12_cond>"
3880 "<risbg_n>\t%0,%1,%s3,128+%e3,%2" ; dst, src, start, end, shift
3881 [(set_attr "op_type" "RIE")
3882 (set_attr "z10prop" "z10_super_E1")])
3883
3884 (define_insn_and_split "*pre_z10_extzv<mode>"
3885 [(set (match_operand:GPR 0 "register_operand" "=d")
3886 (zero_extract:GPR (match_operand:QI 1 "s_operand" "S")
3887 (match_operand 2 "nonzero_shift_count_operand" "")
3888 (const_int 0)))
3889 (clobber (reg:CC CC_REGNUM))]
3890 "!TARGET_Z10"
3891 "#"
3892 "&& reload_completed"
3893 [(parallel
3894 [(set (match_dup 0) (unspec:GPR [(match_dup 1) (match_dup 3)] UNSPEC_ICM))
3895 (clobber (reg:CC CC_REGNUM))])
3896 (set (match_dup 0) (lshiftrt:GPR (match_dup 0) (match_dup 2)))]
3897 {
3898 int bitsize = INTVAL (operands[2]);
3899 int size = (bitsize - 1) / BITS_PER_UNIT + 1; /* round up */
3900 int mask = ((1ul << size) - 1) << (GET_MODE_SIZE (SImode) - size);
3901
3902 operands[1] = adjust_address (operands[1], BLKmode, 0);
3903 set_mem_size (operands[1], size);
3904 operands[2] = GEN_INT (<GPR:bitsize> - bitsize);
3905 operands[3] = GEN_INT (mask);
3906 })
3907
3908 (define_insn_and_split "*pre_z10_extv<mode>"
3909 [(set (match_operand:GPR 0 "register_operand" "=d")
3910 (sign_extract:GPR (match_operand:QI 1 "s_operand" "S")
3911 (match_operand 2 "nonzero_shift_count_operand" "")
3912 (const_int 0)))
3913 (clobber (reg:CC CC_REGNUM))]
3914 ""
3915 "#"
3916 "&& reload_completed"
3917 [(parallel
3918 [(set (match_dup 0) (unspec:GPR [(match_dup 1) (match_dup 3)] UNSPEC_ICM))
3919 (clobber (reg:CC CC_REGNUM))])
3920 (parallel
3921 [(set (match_dup 0) (ashiftrt:GPR (match_dup 0) (match_dup 2)))
3922 (clobber (reg:CC CC_REGNUM))])]
3923 {
3924 int bitsize = INTVAL (operands[2]);
3925 int size = (bitsize - 1) / BITS_PER_UNIT + 1; /* round up */
3926 int mask = ((1ul << size) - 1) << (GET_MODE_SIZE (SImode) - size);
3927
3928 operands[1] = adjust_address (operands[1], BLKmode, 0);
3929 set_mem_size (operands[1], size);
3930 operands[2] = GEN_INT (<GPR:bitsize> - bitsize);
3931 operands[3] = GEN_INT (mask);
3932 })
3933
3934 ;
3935 ; insv instruction patterns
3936 ;
3937
3938 (define_expand "insv"
3939 [(set (zero_extract (match_operand 0 "nonimmediate_operand" "")
3940 (match_operand 1 "const_int_operand" "")
3941 (match_operand 2 "const_int_operand" ""))
3942 (match_operand 3 "general_operand" ""))]
3943 ""
3944 {
3945 if (s390_expand_insv (operands[0], operands[1], operands[2], operands[3]))
3946 DONE;
3947 FAIL;
3948 })
3949
3950
3951 ; The normal RTL expansion will never generate a zero_extract where
3952 ; the location operand isn't word mode. However, we do this in the
3953 ; back-end when generating atomic operations. See s390_two_part_insv.
3954 (define_insn "*insv<mode><clobbercc_or_nocc>"
3955 [(set (zero_extract:GPR (match_operand:GPR 0 "nonimmediate_operand" "+d")
3956 (match_operand 1 "const_int_operand" "I") ; size
3957 (match_operand 2 "const_int_operand" "I")) ; pos
3958 (match_operand:GPR 3 "nonimmediate_operand" "d"))]
3959 "<z10_or_zEC12_cond>
3960 && EXTRACT_ARGS_IN_RANGE (INTVAL (operands[1]), INTVAL (operands[2]),
3961 GET_MODE_BITSIZE (<MODE>mode))
3962 && (INTVAL (operands[1]) + INTVAL (operands[2])) <= <bitsize>"
3963 "<risbg_n>\t%0,%3,<bitoff_plus>%2,<bitoff_plus>%2+%1-1,<bitsize>-%2-%1"
3964 [(set_attr "op_type" "RIE")
3965 (set_attr "z10prop" "z10_super_E1")])
3966
3967 ; and op1 with a mask being 1 for the selected bits and 0 for the rest
3968 ; and op3=op0 with a mask being 0 for the selected bits and 1 for the rest
3969 (define_insn "*insv<mode><clobbercc_or_nocc>_noshift"
3970 [(set (match_operand:GPR 0 "nonimmediate_operand" "=d,d")
3971 (ior:GPR (and:GPR (match_operand:GPR 1 "nonimmediate_operand" "d,0")
3972 (match_operand:GPR 2 "contiguous_bitmask_operand" ""))
3973 (and:GPR (match_operand:GPR 3 "nonimmediate_operand" "0,d")
3974 (match_operand:GPR 4 "const_int_operand" ""))))]
3975 "<z10_or_zEC12_cond> && INTVAL (operands[2]) == ~INTVAL (operands[4])"
3976 "@
3977 <risbg_n>\t%0,%1,%<bfstart>2,%<bfend>2,0
3978 <risbg_n>\t%0,%3,%<bfstart>4,%<bfend>4,0"
3979 [(set_attr "op_type" "RIE")
3980 (set_attr "z10prop" "z10_super_E1")])
3981
3982 (define_insn "*insv_z10_noshift_cc"
3983 [(set (reg CC_REGNUM)
3984 (compare
3985 (ior:DI
3986 (and:DI (match_operand:DI 1 "nonimmediate_operand" "d,0")
3987 (match_operand:DI 2 "contiguous_bitmask_operand" ""))
3988 (and:DI (match_operand:DI 3 "nonimmediate_operand" "0,d")
3989 (match_operand:DI 4 "const_int_operand" "")))
3990 (const_int 0)))
3991 (set (match_operand:DI 0 "nonimmediate_operand" "=d,d")
3992 (ior:DI (and:DI (match_dup 1) (match_dup 2))
3993 (and:DI (match_dup 3) (match_dup 4))))]
3994 "TARGET_Z10 && s390_match_ccmode (insn, CCSmode)
3995 && INTVAL (operands[2]) == ~INTVAL (operands[4])"
3996 "@
3997 risbg\t%0,%1,%s2,%e2,0
3998 risbg\t%0,%3,%s4,%e4,0"
3999 [(set_attr "op_type" "RIE")
4000 (set_attr "z10prop" "z10_super_E1")])
4001
4002 (define_insn "*insv_z10_noshift_cconly"
4003 [(set
4004 (reg CC_REGNUM)
4005 (compare
4006 (ior:DI
4007 (and:DI (match_operand:DI 1 "nonimmediate_operand" "d,0")
4008 (match_operand:DI 2 "contiguous_bitmask_operand" ""))
4009 (and:DI (match_operand:DI 3 "nonimmediate_operand" "0,d")
4010 (match_operand:DI 4 "const_int_operand" "")))
4011 (const_int 0)))
4012 (clobber (match_scratch:DI 0 "=d,d"))]
4013 "TARGET_Z10 && s390_match_ccmode (insn, CCSmode)
4014 && INTVAL (operands[2]) == ~INTVAL (operands[4])"
4015 "@
4016 risbg\t%0,%1,%s2,%e2,0
4017 risbg\t%0,%3,%s4,%e4,0"
4018 [(set_attr "op_type" "RIE")
4019 (set_attr "z10prop" "z10_super_E1")])
4020
4021 ; Implement appending Y on the left of S bits of X
4022 ; x = (y << s) | (x & ((1 << s) - 1))
4023 (define_insn "*insv<mode><clobbercc_or_nocc>_appendbitsleft"
4024 [(set (match_operand:GPR 0 "nonimmediate_operand" "=d")
4025 (ior:GPR (and:GPR (match_operand:GPR 1 "nonimmediate_operand" "0")
4026 (match_operand:GPR 2 "immediate_operand" ""))
4027 (ashift:GPR (match_operand:GPR 3 "nonimmediate_operand" "d")
4028 (match_operand:GPR 4 "nonzero_shift_count_operand" ""))))]
4029 "<z10_or_zEC12_cond>
4030 && UINTVAL (operands[2]) == (1UL << UINTVAL (operands[4])) - 1"
4031 "<risbg_n>\t%0,%3,<bitoff>,64-%4-1,%4"
4032 [(set_attr "op_type" "RIE")
4033 (set_attr "z10prop" "z10_super_E1")])
4034
4035 ; a = ((i32)a & -16777216) | (((ui32)b) >> 8)
4036 (define_insn "*<risbg_n>_<mode>_ior_and_lshiftrt"
4037 [(set (match_operand:GPR 0 "register_operand" "=d")
4038 (ior:GPR (and:GPR
4039 (match_operand:GPR 1 "register_operand" "0")
4040 (match_operand:GPR 2 "const_int_operand" ""))
4041 (lshiftrt:GPR
4042 (match_operand:GPR 3 "register_operand" "d")
4043 (match_operand:GPR 4 "nonzero_shift_count_operand" ""))))]
4044 "<z10_or_zEC12_cond> && UINTVAL (operands[2])
4045 == (~(0ULL) << (GET_MODE_BITSIZE (<MODE>mode) - UINTVAL (operands[4])))"
4046 "<risbg_n>\t%0,%3,<bitoff_plus>%4,63,64-%4"
4047 [(set_attr "op_type" "RIE")
4048 (set_attr "z10prop" "z10_super_E1")])
4049
4050 ; (ui32)(((ui64)x) >> 48) | ((i32)y & -65536);
4051 (define_insn "*<risbg_n>_sidi_ior_and_lshiftrt"
4052 [(set (match_operand:SI 0 "register_operand" "=d")
4053 (ior:SI (and:SI
4054 (match_operand:SI 1 "register_operand" "0")
4055 (match_operand:SI 2 "const_int_operand" ""))
4056 (subreg:SI
4057 (lshiftrt:DI
4058 (match_operand:DI 3 "register_operand" "d")
4059 (match_operand:DI 4 "nonzero_shift_count_operand" "")) 4)))]
4060 "<z10_or_zEC12_cond>
4061 && UINTVAL (operands[2]) == ~(~(0ULL) >> UINTVAL (operands[4]))"
4062 "<risbg_n>\t%0,%3,%4,63,64-%4"
4063 [(set_attr "op_type" "RIE")
4064 (set_attr "z10prop" "z10_super_E1")])
4065
4066 ; (ui32)(((ui64)x) >> 12) & -4
4067 (define_insn "*trunc_sidi_and_subreg_lshrt<clobbercc_or_nocc>"
4068 [(set (match_operand:SI 0 "register_operand" "=d")
4069 (and:SI
4070 (subreg:SI (lshiftrt:DI
4071 (match_operand:DI 1 "register_operand" "d")
4072 (match_operand:DI 2 "nonzero_shift_count_operand" "")) 4)
4073 (match_operand:SI 3 "contiguous_bitmask_nowrap_operand" "")))]
4074 "<z10_or_zEC12_cond>"
4075 "<risbg_n>\t%0,%1,%t3,128+%f3,64-%2"
4076 [(set_attr "op_type" "RIE")
4077 (set_attr "z10prop" "z10_super_E1")])
4078
4079 ; z = (x << c) | (y >> d) with (x << c) and (y >> d) not overlapping after shifting
4080 ; -> z = y >> d; z = (x << c) | (z & ((1 << c) - 1))
4081 ; -> z = y >> d; z = risbg;
4082
4083 (define_split
4084 [(set (match_operand:GPR 0 "nonimmediate_operand" "")
4085 (ior:GPR (lshiftrt:GPR (match_operand:GPR 1 "nonimmediate_operand" "")
4086 (match_operand:GPR 2 "nonzero_shift_count_operand" ""))
4087 (ashift:GPR (match_operand:GPR 3 "nonimmediate_operand" "")
4088 (match_operand:GPR 4 "nonzero_shift_count_operand" ""))))]
4089 "TARGET_ZEC12 && UINTVAL (operands[2]) + UINTVAL (operands[4]) >= <bitsize>"
4090 [(set (match_dup 6)
4091 (lshiftrt:GPR (match_dup 1) (match_dup 2)))
4092 (set (match_dup 0)
4093 (ior:GPR (and:GPR (match_dup 6) (match_dup 5))
4094 (ashift:GPR (match_dup 3) (match_dup 4))))]
4095 {
4096 operands[5] = GEN_INT ((1UL << UINTVAL (operands[4])) - 1);
4097 if (reg_overlap_mentioned_p (operands[0], operands[3]))
4098 {
4099 if (!can_create_pseudo_p ())
4100 FAIL;
4101 operands[6] = gen_reg_rtx (<MODE>mode);
4102 }
4103 else
4104 operands[6] = operands[0];
4105 })
4106
4107 (define_split
4108 [(parallel
4109 [(set (match_operand:GPR 0 "nonimmediate_operand" "")
4110 (ior:GPR (lshiftrt:GPR (match_operand:GPR 1 "nonimmediate_operand" "")
4111 (match_operand:GPR 2 "nonzero_shift_count_operand" ""))
4112 (ashift:GPR (match_operand:GPR 3 "nonimmediate_operand" "")
4113 (match_operand:GPR 4 "nonzero_shift_count_operand" ""))))
4114 (clobber (reg:CC CC_REGNUM))])]
4115 "TARGET_Z10 && !TARGET_ZEC12 && UINTVAL (operands[2]) + UINTVAL (operands[4]) >= <bitsize>"
4116 [(set (match_dup 6)
4117 (lshiftrt:GPR (match_dup 1) (match_dup 2)))
4118 (parallel
4119 [(set (match_dup 0)
4120 (ior:GPR (and:GPR (match_dup 6) (match_dup 5))
4121 (ashift:GPR (match_dup 3) (match_dup 4))))
4122 (clobber (reg:CC CC_REGNUM))])]
4123 {
4124 operands[5] = GEN_INT ((1UL << UINTVAL (operands[4])) - 1);
4125 if (reg_overlap_mentioned_p (operands[0], operands[3]))
4126 {
4127 if (!can_create_pseudo_p ())
4128 FAIL;
4129 operands[6] = gen_reg_rtx (<MODE>mode);
4130 }
4131 else
4132 operands[6] = operands[0];
4133 })
4134
4135 ; rosbg, rxsbg
4136 (define_insn "*r<noxa>sbg_<mode>_noshift"
4137 [(set (match_operand:GPR 0 "nonimmediate_operand" "=d")
4138 (IXOR:GPR
4139 (and:GPR (match_operand:GPR 1 "nonimmediate_operand" "d")
4140 (match_operand:GPR 2 "contiguous_bitmask_operand" ""))
4141 (match_operand:GPR 3 "nonimmediate_operand" "0")))
4142 (clobber (reg:CC CC_REGNUM))]
4143 "TARGET_Z10"
4144 "r<noxa>sbg\t%0,%1,%<bfstart>2,%<bfend>2,0"
4145 [(set_attr "op_type" "RIE")])
4146
4147 ; rosbg, rxsbg
4148 (define_insn "*r<noxa>sbg_di_rotl"
4149 [(set (match_operand:DI 0 "nonimmediate_operand" "=d")
4150 (IXOR:DI
4151 (and:DI
4152 (rotate:DI
4153 (match_operand:DI 1 "nonimmediate_operand" "d")
4154 (match_operand:DI 3 "const_int_operand" ""))
4155 (match_operand:DI 2 "contiguous_bitmask_operand" ""))
4156 (match_operand:DI 4 "nonimmediate_operand" "0")))
4157 (clobber (reg:CC CC_REGNUM))]
4158 "TARGET_Z10"
4159 "r<noxa>sbg\t%0,%1,%<bfstart>2,%<bfend>2,%b3"
4160 [(set_attr "op_type" "RIE")])
4161
4162 ; rosbg, rxsbg
4163 (define_insn "*r<noxa>sbg_<mode>_srl_bitmask"
4164 [(set (match_operand:GPR 0 "nonimmediate_operand" "=d")
4165 (IXOR:GPR
4166 (and:GPR
4167 (lshiftrt:GPR
4168 (match_operand:GPR 1 "nonimmediate_operand" "d")
4169 (match_operand:GPR 3 "nonzero_shift_count_operand" ""))
4170 (match_operand:GPR 2 "contiguous_bitmask_nowrap_operand" ""))
4171 (match_operand:GPR 4 "nonimmediate_operand" "0")))
4172 (clobber (reg:CC CC_REGNUM))]
4173 "TARGET_Z10
4174 && s390_extzv_shift_ok (<bitsize>, 64 - INTVAL (operands[3]),
4175 INTVAL (operands[2]))"
4176 "r<noxa>sbg\t%0,%1,%<bfstart>2,%<bfend>2,64-%3"
4177 [(set_attr "op_type" "RIE")])
4178
4179 ; rosbg, rxsbg
4180 (define_insn "*r<noxa>sbg_<mode>_sll_bitmask"
4181 [(set (match_operand:GPR 0 "nonimmediate_operand" "=d")
4182 (IXOR:GPR
4183 (and:GPR
4184 (ashift:GPR
4185 (match_operand:GPR 1 "nonimmediate_operand" "d")
4186 (match_operand:GPR 3 "nonzero_shift_count_operand" ""))
4187 (match_operand:GPR 2 "contiguous_bitmask_nowrap_operand" ""))
4188 (match_operand:GPR 4 "nonimmediate_operand" "0")))
4189 (clobber (reg:CC CC_REGNUM))]
4190 "TARGET_Z10
4191 && s390_extzv_shift_ok (<bitsize>, INTVAL (operands[3]),
4192 INTVAL (operands[2]))"
4193 "r<noxa>sbg\t%0,%1,%<bfstart>2,%<bfend>2,%3"
4194 [(set_attr "op_type" "RIE")])
4195
4196 ;; unsigned {int,long} a, b
4197 ;; a = a | (b << const_int)
4198 ;; a = a ^ (b << const_int)
4199 ; rosbg, rxsbg
4200 (define_insn "*r<noxa>sbg_<mode>_sll"
4201 [(set (match_operand:GPR 0 "nonimmediate_operand" "=d")
4202 (IXOR:GPR
4203 (ashift:GPR
4204 (match_operand:GPR 1 "nonimmediate_operand" "d")
4205 (match_operand:GPR 2 "nonzero_shift_count_operand" ""))
4206 (match_operand:GPR 3 "nonimmediate_operand" "0")))
4207 (clobber (reg:CC CC_REGNUM))]
4208 "TARGET_Z10"
4209 "r<noxa>sbg\t%0,%1,<bitoff>,63-%2,%2"
4210 [(set_attr "op_type" "RIE")])
4211
4212 ;; unsigned {int,long} a, b
4213 ;; a = a | (b >> const_int)
4214 ;; a = a ^ (b >> const_int)
4215 ; rosbg, rxsbg
4216 (define_insn "*r<noxa>sbg_<mode>_srl"
4217 [(set (match_operand:GPR 0 "nonimmediate_operand" "=d")
4218 (IXOR:GPR
4219 (lshiftrt:GPR
4220 (match_operand:GPR 1 "nonimmediate_operand" "d")
4221 (match_operand:GPR 2 "nonzero_shift_count_operand" ""))
4222 (match_operand:GPR 3 "nonimmediate_operand" "0")))
4223 (clobber (reg:CC CC_REGNUM))]
4224 "TARGET_Z10"
4225 "r<noxa>sbg\t%0,%1,<bitoff_plus>%2,63,64-%2"
4226 [(set_attr "op_type" "RIE")])
4227
4228 ;; These two are generated by combine for s.bf &= val.
4229 ;; ??? For bitfields smaller than 32-bits, we wind up with SImode
4230 ;; shifts and ands, which results in some truly awful patterns
4231 ;; including subregs of operations. Rather unnecessisarily, IMO.
4232 ;; Instead of
4233 ;;
4234 ;; (set (zero_extract:DI (reg/v:DI 50 [ s ])
4235 ;; (const_int 24 [0x18])
4236 ;; (const_int 0 [0]))
4237 ;; (subreg:DI (and:SI (subreg:SI (lshiftrt:DI (reg/v:DI 50 [ s ])
4238 ;; (const_int 40 [0x28])) 4)
4239 ;; (reg:SI 4 %r4 [ y+4 ])) 0))
4240 ;;
4241 ;; we should instead generate
4242 ;;
4243 ;; (set (zero_extract:DI (reg/v:DI 50 [ s ])
4244 ;; (const_int 24 [0x18])
4245 ;; (const_int 0 [0]))
4246 ;; (and:DI (lshiftrt:DI (reg/v:DI 50 [ s ])
4247 ;; (const_int 40 [0x28]))
4248 ;; (subreg:DI (reg:SI 4 %r4 [ y+4 ]) 0)))
4249 ;;
4250 ;; by noticing that we can push down the outer paradoxical subreg
4251 ;; into the operation.
4252
4253 (define_insn "*insv_rnsbg_noshift"
4254 [(set (zero_extract:DI
4255 (match_operand:DI 0 "nonimmediate_operand" "+d")
4256 (match_operand 1 "const_int_operand" "")
4257 (match_operand 2 "const_int_operand" ""))
4258 (and:DI
4259 (match_dup 0)
4260 (match_operand:DI 3 "nonimmediate_operand" "d")))
4261 (clobber (reg:CC CC_REGNUM))]
4262 "TARGET_Z10
4263 && EXTRACT_ARGS_IN_RANGE (INTVAL (operands[1]), INTVAL (operands[2]), 64)
4264 && INTVAL (operands[1]) + INTVAL (operands[2]) == 64"
4265 "rnsbg\t%0,%3,%2,63,0"
4266 [(set_attr "op_type" "RIE")])
4267
4268 (define_insn "*insv_rnsbg_srl"
4269 [(set (zero_extract:DI
4270 (match_operand:DI 0 "nonimmediate_operand" "+d")
4271 (match_operand 1 "const_int_operand" "")
4272 (match_operand 2 "const_int_operand" ""))
4273 (and:DI
4274 (lshiftrt:DI
4275 (match_dup 0)
4276 (match_operand 3 "const_int_operand" ""))
4277 (match_operand:DI 4 "nonimmediate_operand" "d")))
4278 (clobber (reg:CC CC_REGNUM))]
4279 "TARGET_Z10
4280 && EXTRACT_ARGS_IN_RANGE (INTVAL (operands[1]), INTVAL (operands[2]), 64)
4281 && INTVAL (operands[3]) == 64 - INTVAL (operands[1]) - INTVAL (operands[2])"
4282 "rnsbg\t%0,%4,%2,%2+%1-1,%3"
4283 [(set_attr "op_type" "RIE")])
4284
4285 (define_insn "*insv<mode>_mem_reg"
4286 [(set (zero_extract:W (match_operand:QI 0 "memory_operand" "+Q,S")
4287 (match_operand 1 "const_int_operand" "n,n")
4288 (const_int 0))
4289 (match_operand:W 2 "register_operand" "d,d"))]
4290 "EXTRACT_ARGS_IN_RANGE (INTVAL (operands[1]), 0, 64)
4291 && INTVAL (operands[1]) > 0
4292 && INTVAL (operands[1]) <= GET_MODE_BITSIZE (SImode)
4293 && INTVAL (operands[1]) % BITS_PER_UNIT == 0"
4294 {
4295 int size = INTVAL (operands[1]) / BITS_PER_UNIT;
4296
4297 operands[1] = GEN_INT ((1ul << size) - 1);
4298 return (which_alternative == 0) ? "stcm\t%2,%1,%S0"
4299 : "stcmy\t%2,%1,%S0";
4300 }
4301 [(set_attr "op_type" "RS,RSY")
4302 (set_attr "cpu_facility" "*,longdisp")
4303 (set_attr "z10prop" "z10_super,z10_super")])
4304
4305 (define_insn "*insvdi_mem_reghigh"
4306 [(set (zero_extract:DI (match_operand:QI 0 "memory_operand" "+S")
4307 (match_operand 1 "const_int_operand" "n")
4308 (const_int 0))
4309 (lshiftrt:DI (match_operand:DI 2 "register_operand" "d")
4310 (const_int 32)))]
4311 "TARGET_ZARCH
4312 && EXTRACT_ARGS_IN_RANGE (INTVAL (operands[1]), 0, 64)
4313 && INTVAL (operands[1]) > 0
4314 && INTVAL (operands[1]) <= GET_MODE_BITSIZE (SImode)
4315 && INTVAL (operands[1]) % BITS_PER_UNIT == 0"
4316 {
4317 int size = INTVAL (operands[1]) / BITS_PER_UNIT;
4318
4319 operands[1] = GEN_INT ((1ul << size) - 1);
4320 return "stcmh\t%2,%1,%S0";
4321 }
4322 [(set_attr "op_type" "RSY")
4323 (set_attr "z10prop" "z10_super")])
4324
4325 (define_insn "*insvdi_reg_imm"
4326 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+d")
4327 (const_int 16)
4328 (match_operand 1 "const_int_operand" "n"))
4329 (match_operand:DI 2 "const_int_operand" "n"))]
4330 "TARGET_ZARCH
4331 && EXTRACT_ARGS_IN_RANGE (16, INTVAL (operands[1]), 64)
4332 && INTVAL (operands[1]) >= 0
4333 && INTVAL (operands[1]) < BITS_PER_WORD
4334 && INTVAL (operands[1]) % 16 == 0"
4335 {
4336 switch (BITS_PER_WORD - INTVAL (operands[1]))
4337 {
4338 case 64: return "iihh\t%0,%x2"; break;
4339 case 48: return "iihl\t%0,%x2"; break;
4340 case 32: return "iilh\t%0,%x2"; break;
4341 case 16: return "iill\t%0,%x2"; break;
4342 default: gcc_unreachable();
4343 }
4344 }
4345 [(set_attr "op_type" "RI")
4346 (set_attr "z10prop" "z10_super_E1")])
4347
4348 ; Update the left-most 32 bit of a DI.
4349 (define_insn "*insv_h_di_reg_extimm"
4350 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+d")
4351 (const_int 32)
4352 (const_int 0))
4353 (match_operand:DI 1 "const_int_operand" "n"))]
4354 "TARGET_EXTIMM"
4355 "iihf\t%0,%o1"
4356 [(set_attr "op_type" "RIL")
4357 (set_attr "z10prop" "z10_fwd_E1")])
4358
4359 ; Update the right-most 32 bit of a DI.
4360 (define_insn "*insv_l_di_reg_extimm"
4361 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+d")
4362 (const_int 32)
4363 (const_int 32))
4364 (match_operand:DI 1 "const_int_operand" "n"))]
4365 "TARGET_EXTIMM"
4366 "iilf\t%0,%o1"
4367 [(set_attr "op_type" "RIL")
4368 (set_attr "z10prop" "z10_fwd_A1")])
4369
4370 ;
4371 ; extendsidi2 instruction pattern(s).
4372 ;
4373
4374 (define_expand "extendsidi2"
4375 [(set (match_operand:DI 0 "register_operand" "")
4376 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "")))]
4377 ""
4378 {
4379 if (!TARGET_ZARCH)
4380 {
4381 emit_clobber (operands[0]);
4382 emit_move_insn (gen_highpart (SImode, operands[0]), operands[1]);
4383 emit_move_insn (gen_lowpart (SImode, operands[0]), const0_rtx);
4384 emit_insn (gen_ashrdi3 (operands[0], operands[0], GEN_INT (32)));
4385 DONE;
4386 }
4387 })
4388
4389 (define_insn "*extendsidi2"
4390 [(set (match_operand:DI 0 "register_operand" "=d,d,d")
4391 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "d,T,b")))]
4392 "TARGET_ZARCH"
4393 "@
4394 lgfr\t%0,%1
4395 lgf\t%0,%1
4396 lgfrl\t%0,%1"
4397 [(set_attr "op_type" "RRE,RXY,RIL")
4398 (set_attr "type" "*,*,larl")
4399 (set_attr "cpu_facility" "*,*,z10")
4400 (set_attr "z10prop" "z10_super_E1,z10_super_E1,z10_super_E1")])
4401
4402 ;
4403 ; extend(hi|qi)(si|di)2 instruction pattern(s).
4404 ;
4405
4406 (define_expand "extend<HQI:mode><DSI:mode>2"
4407 [(set (match_operand:DSI 0 "register_operand" "")
4408 (sign_extend:DSI (match_operand:HQI 1 "nonimmediate_operand" "")))]
4409 ""
4410 {
4411 if (<DSI:MODE>mode == DImode && !TARGET_ZARCH)
4412 {
4413 rtx tmp = gen_reg_rtx (SImode);
4414 emit_insn (gen_extend<HQI:mode>si2 (tmp, operands[1]));
4415 emit_insn (gen_extendsidi2 (operands[0], tmp));
4416 DONE;
4417 }
4418 else if (!TARGET_EXTIMM)
4419 {
4420 rtx bitcount = GEN_INT (<DSI:bitsize> - <HQI:bitsize>);
4421
4422 operands[1] = gen_lowpart (<DSI:MODE>mode, operands[1]);
4423 emit_insn (gen_ashl<DSI:mode>3 (operands[0], operands[1], bitcount));
4424 emit_insn (gen_ashr<DSI:mode>3 (operands[0], operands[0], bitcount));
4425 DONE;
4426 }
4427 })
4428
4429 ;
4430 ; extendhidi2 instruction pattern(s).
4431 ;
4432
4433 (define_insn "*extendhidi2_extimm"
4434 [(set (match_operand:DI 0 "register_operand" "=d,d,d")
4435 (sign_extend:DI (match_operand:HI 1 "general_operand" "d,T,b")))]
4436 "TARGET_ZARCH && TARGET_EXTIMM"
4437 "@
4438 lghr\t%0,%1
4439 lgh\t%0,%1
4440 lghrl\t%0,%1"
4441 [(set_attr "op_type" "RRE,RXY,RIL")
4442 (set_attr "type" "*,*,larl")
4443 (set_attr "cpu_facility" "extimm,extimm,z10")
4444 (set_attr "z10prop" "z10_super_E1,z10_super_E1,z10_super_E1")])
4445
4446 (define_insn "*extendhidi2"
4447 [(set (match_operand:DI 0 "register_operand" "=d")
4448 (sign_extend:DI (match_operand:HI 1 "memory_operand" "T")))]
4449 "TARGET_ZARCH"
4450 "lgh\t%0,%1"
4451 [(set_attr "op_type" "RXY")
4452 (set_attr "z10prop" "z10_super_E1")])
4453
4454 ;
4455 ; extendhisi2 instruction pattern(s).
4456 ;
4457
4458 (define_insn "*extendhisi2_extimm"
4459 [(set (match_operand:SI 0 "register_operand" "=d,d,d,d")
4460 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" " d,R,T,b")))]
4461 "TARGET_EXTIMM"
4462 "@
4463 lhr\t%0,%1
4464 lh\t%0,%1
4465 lhy\t%0,%1
4466 lhrl\t%0,%1"
4467 [(set_attr "op_type" "RRE,RX,RXY,RIL")
4468 (set_attr "type" "*,*,*,larl")
4469 (set_attr "cpu_facility" "extimm,extimm,extimm,z10")
4470 (set_attr "z10prop" "z10_super_E1,z10_super_E1,z10_super_E1,z10_super_E1")])
4471
4472 (define_insn "*extendhisi2"
4473 [(set (match_operand:SI 0 "register_operand" "=d,d")
4474 (sign_extend:SI (match_operand:HI 1 "memory_operand" "R,T")))]
4475 "!TARGET_EXTIMM"
4476 "@
4477 lh\t%0,%1
4478 lhy\t%0,%1"
4479 [(set_attr "op_type" "RX,RXY")
4480 (set_attr "cpu_facility" "*,longdisp")
4481 (set_attr "z10prop" "z10_super_E1,z10_super_E1")])
4482
4483 ;
4484 ; extendqi(si|di)2 instruction pattern(s).
4485 ;
4486
4487 ; lbr, lgbr, lb, lgb
4488 (define_insn "*extendqi<mode>2_extimm"
4489 [(set (match_operand:GPR 0 "register_operand" "=d,d")
4490 (sign_extend:GPR (match_operand:QI 1 "nonimmediate_operand" "d,T")))]
4491 "TARGET_EXTIMM"
4492 "@
4493 l<g>br\t%0,%1
4494 l<g>b\t%0,%1"
4495 [(set_attr "op_type" "RRE,RXY")
4496 (set_attr "z10prop" "z10_super_E1,z10_super_E1")])
4497
4498 ; lb, lgb
4499 (define_insn "*extendqi<mode>2"
4500 [(set (match_operand:GPR 0 "register_operand" "=d")
4501 (sign_extend:GPR (match_operand:QI 1 "memory_operand" "T")))]
4502 "!TARGET_EXTIMM && TARGET_LONG_DISPLACEMENT"
4503 "l<g>b\t%0,%1"
4504 [(set_attr "op_type" "RXY")
4505 (set_attr "z10prop" "z10_super_E1")])
4506
4507 (define_insn_and_split "*extendqi<mode>2_short_displ"
4508 [(set (match_operand:GPR 0 "register_operand" "=d")
4509 (sign_extend:GPR (match_operand:QI 1 "s_operand" "Q")))
4510 (clobber (reg:CC CC_REGNUM))]
4511 "!TARGET_EXTIMM && !TARGET_LONG_DISPLACEMENT"
4512 "#"
4513 "&& reload_completed"
4514 [(parallel
4515 [(set (match_dup 0) (unspec:GPR [(match_dup 1) (const_int 8)] UNSPEC_ICM))
4516 (clobber (reg:CC CC_REGNUM))])
4517 (parallel
4518 [(set (match_dup 0) (ashiftrt:GPR (match_dup 0) (match_dup 2)))
4519 (clobber (reg:CC CC_REGNUM))])]
4520 {
4521 operands[1] = adjust_address (operands[1], BLKmode, 0);
4522 set_mem_size (operands[1], GET_MODE_SIZE (QImode));
4523 operands[2] = GEN_INT (<GPR:bitsize> - BITS_PER_UNIT);
4524 })
4525
4526 ;
4527 ; zero_extendsidi2 instruction pattern(s).
4528 ;
4529
4530 (define_expand "zero_extendsidi2"
4531 [(set (match_operand:DI 0 "register_operand" "")
4532 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "")))]
4533 ""
4534 {
4535 if (!TARGET_ZARCH)
4536 {
4537 emit_clobber (operands[0]);
4538 emit_move_insn (gen_lowpart (SImode, operands[0]), operands[1]);
4539 emit_move_insn (gen_highpart (SImode, operands[0]), const0_rtx);
4540 DONE;
4541 }
4542 })
4543
4544 (define_insn "*zero_extendsidi2"
4545 [(set (match_operand:DI 0 "register_operand" "=d,d,d")
4546 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "d,T,b")))]
4547 "TARGET_ZARCH"
4548 "@
4549 llgfr\t%0,%1
4550 llgf\t%0,%1
4551 llgfrl\t%0,%1"
4552 [(set_attr "op_type" "RRE,RXY,RIL")
4553 (set_attr "type" "*,*,larl")
4554 (set_attr "cpu_facility" "*,*,z10")
4555 (set_attr "z10prop" "z10_fwd_E1,z10_fwd_A3,z10_fwd_A3")])
4556
4557 ;
4558 ; LLGT-type instructions (zero-extend from 31 bit to 64 bit).
4559 ;
4560
4561 (define_insn "*llgt_sidi"
4562 [(set (match_operand:DI 0 "register_operand" "=d")
4563 (and:DI (subreg:DI (match_operand:SI 1 "memory_operand" "T") 0)
4564 (const_int 2147483647)))]
4565 "TARGET_ZARCH"
4566 "llgt\t%0,%1"
4567 [(set_attr "op_type" "RXE")
4568 (set_attr "z10prop" "z10_super_E1")])
4569
4570 (define_insn_and_split "*llgt_sidi_split"
4571 [(set (match_operand:DI 0 "register_operand" "=d")
4572 (and:DI (subreg:DI (match_operand:SI 1 "memory_operand" "T") 0)
4573 (const_int 2147483647)))
4574 (clobber (reg:CC CC_REGNUM))]
4575 "TARGET_ZARCH"
4576 "#"
4577 "&& reload_completed"
4578 [(set (match_dup 0)
4579 (and:DI (subreg:DI (match_dup 1) 0)
4580 (const_int 2147483647)))]
4581 "")
4582
4583 (define_insn "*llgt_sisi"
4584 [(set (match_operand:SI 0 "register_operand" "=d,d")
4585 (and:SI (match_operand:SI 1 "nonimmediate_operand" "d,T")
4586 (const_int 2147483647)))]
4587 "TARGET_ZARCH"
4588 "@
4589 llgtr\t%0,%1
4590 llgt\t%0,%1"
4591 [(set_attr "op_type" "RRE,RXE")
4592 (set_attr "z10prop" "z10_super_E1,z10_super_E1")])
4593
4594 (define_insn "*llgt_didi"
4595 [(set (match_operand:DI 0 "register_operand" "=d,d")
4596 (and:DI (match_operand:DI 1 "nonimmediate_operand" "d,o")
4597 (const_int 2147483647)))]
4598 "TARGET_ZARCH"
4599 "@
4600 llgtr\t%0,%1
4601 llgt\t%0,%N1"
4602 [(set_attr "op_type" "RRE,RXE")
4603 (set_attr "z10prop" "z10_super_E1,z10_super_E1")])
4604
4605 (define_split
4606 [(set (match_operand:DSI 0 "register_operand" "")
4607 (and:DSI (match_operand:DSI 1 "nonimmediate_operand" "")
4608 (const_int 2147483647)))
4609 (clobber (reg:CC CC_REGNUM))]
4610 "TARGET_ZARCH && reload_completed"
4611 [(set (match_dup 0)
4612 (and:DSI (match_dup 1)
4613 (const_int 2147483647)))]
4614 "")
4615
4616 ;
4617 ; zero_extend(hi|qi)(si|di)2 instruction pattern(s).
4618 ;
4619
4620 (define_expand "zero_extend<mode>di2"
4621 [(set (match_operand:DI 0 "register_operand" "")
4622 (zero_extend:DI (match_operand:HQI 1 "nonimmediate_operand" "")))]
4623 ""
4624 {
4625 if (!TARGET_ZARCH)
4626 {
4627 rtx tmp = gen_reg_rtx (SImode);
4628 emit_insn (gen_zero_extend<mode>si2 (tmp, operands[1]));
4629 emit_insn (gen_zero_extendsidi2 (operands[0], tmp));
4630 DONE;
4631 }
4632 else if (!TARGET_EXTIMM)
4633 {
4634 rtx bitcount = GEN_INT (64 - <HQI:bitsize>);
4635 operands[1] = gen_lowpart (DImode, operands[1]);
4636 emit_insn (gen_ashldi3 (operands[0], operands[1], bitcount));
4637 emit_insn (gen_lshrdi3 (operands[0], operands[0], bitcount));
4638 DONE;
4639 }
4640 })
4641
4642 (define_expand "zero_extend<mode>si2"
4643 [(set (match_operand:SI 0 "register_operand" "")
4644 (zero_extend:SI (match_operand:HQI 1 "nonimmediate_operand" "")))]
4645 ""
4646 {
4647 if (!TARGET_EXTIMM)
4648 {
4649 operands[1] = gen_lowpart (SImode, operands[1]);
4650 emit_insn (gen_andsi3 (operands[0], operands[1],
4651 GEN_INT ((1 << <HQI:bitsize>) - 1)));
4652 DONE;
4653 }
4654 })
4655
4656 ; llhrl, llghrl
4657 (define_insn "*zero_extendhi<mode>2_z10"
4658 [(set (match_operand:GPR 0 "register_operand" "=d,d,d")
4659 (zero_extend:GPR (match_operand:HI 1 "nonimmediate_operand" "d,T,b")))]
4660 "TARGET_Z10"
4661 "@
4662 ll<g>hr\t%0,%1
4663 ll<g>h\t%0,%1
4664 ll<g>hrl\t%0,%1"
4665 [(set_attr "op_type" "RXY,RRE,RIL")
4666 (set_attr "type" "*,*,larl")
4667 (set_attr "cpu_facility" "*,*,z10")
4668 (set_attr "z10prop" "z10_super_E1,z10_fwd_A3,z10_fwd_A3")])
4669
4670 ; llhr, llcr, llghr, llgcr, llh, llc, llgh, llgc
4671 (define_insn "*zero_extend<HQI:mode><GPR:mode>2_extimm"
4672 [(set (match_operand:GPR 0 "register_operand" "=d,d")
4673 (zero_extend:GPR (match_operand:HQI 1 "nonimmediate_operand" "d,T")))]
4674 "TARGET_EXTIMM"
4675 "@
4676 ll<g><hc>r\t%0,%1
4677 ll<g><hc>\t%0,%1"
4678 [(set_attr "op_type" "RRE,RXY")
4679 (set_attr "z10prop" "z10_super_E1,z10_fwd_A3")])
4680
4681 ; llgh, llgc
4682 (define_insn "*zero_extend<HQI:mode><GPR:mode>2"
4683 [(set (match_operand:GPR 0 "register_operand" "=d")
4684 (zero_extend:GPR (match_operand:HQI 1 "memory_operand" "T")))]
4685 "TARGET_ZARCH && !TARGET_EXTIMM"
4686 "llg<hc>\t%0,%1"
4687 [(set_attr "op_type" "RXY")
4688 (set_attr "z10prop" "z10_fwd_A3")])
4689
4690 (define_insn_and_split "*zero_extendhisi2_31"
4691 [(set (match_operand:SI 0 "register_operand" "=&d")
4692 (zero_extend:SI (match_operand:HI 1 "s_operand" "S")))
4693 (clobber (reg:CC CC_REGNUM))]
4694 "!TARGET_ZARCH"
4695 "#"
4696 "&& reload_completed"
4697 [(set (match_dup 0) (const_int 0))
4698 (parallel
4699 [(set (strict_low_part (match_dup 2)) (match_dup 1))
4700 (clobber (reg:CC CC_REGNUM))])]
4701 "operands[2] = gen_lowpart (HImode, operands[0]);")
4702
4703 (define_insn_and_split "*zero_extendqisi2_31"
4704 [(set (match_operand:SI 0 "register_operand" "=&d")
4705 (zero_extend:SI (match_operand:QI 1 "memory_operand" "T")))]
4706 "!TARGET_ZARCH"
4707 "#"
4708 "&& reload_completed"
4709 [(set (match_dup 0) (const_int 0))
4710 (set (strict_low_part (match_dup 2)) (match_dup 1))]
4711 "operands[2] = gen_lowpart (QImode, operands[0]);")
4712
4713 ;
4714 ; zero_extendqihi2 instruction pattern(s).
4715 ;
4716
4717 (define_expand "zero_extendqihi2"
4718 [(set (match_operand:HI 0 "register_operand" "")
4719 (zero_extend:HI (match_operand:QI 1 "register_operand" "")))]
4720 "TARGET_ZARCH && !TARGET_EXTIMM"
4721 {
4722 operands[1] = gen_lowpart (HImode, operands[1]);
4723 emit_insn (gen_andhi3 (operands[0], operands[1], GEN_INT (0xff)));
4724 DONE;
4725 })
4726
4727 (define_insn "*zero_extendqihi2_64"
4728 [(set (match_operand:HI 0 "register_operand" "=d")
4729 (zero_extend:HI (match_operand:QI 1 "memory_operand" "T")))]
4730 "TARGET_ZARCH && !TARGET_EXTIMM"
4731 "llgc\t%0,%1"
4732 [(set_attr "op_type" "RXY")
4733 (set_attr "z10prop" "z10_fwd_A3")])
4734
4735 (define_insn_and_split "*zero_extendqihi2_31"
4736 [(set (match_operand:HI 0 "register_operand" "=&d")
4737 (zero_extend:HI (match_operand:QI 1 "memory_operand" "T")))]
4738 "!TARGET_ZARCH"
4739 "#"
4740 "&& reload_completed"
4741 [(set (match_dup 0) (const_int 0))
4742 (set (strict_low_part (match_dup 2)) (match_dup 1))]
4743 "operands[2] = gen_lowpart (QImode, operands[0]);")
4744
4745 ;
4746 ; fixuns_trunc(dd|td)di2 instruction pattern(s).
4747 ;
4748
4749 (define_expand "fixuns_truncdddi2"
4750 [(parallel
4751 [(set (match_operand:DI 0 "register_operand" "")
4752 (unsigned_fix:DI (match_operand:DD 1 "register_operand" "")))
4753 (unspec:DI [(const_int DFP_RND_TOWARD_0)] UNSPEC_ROUND)
4754 (clobber (reg:CC CC_REGNUM))])]
4755
4756 "TARGET_HARD_DFP"
4757 {
4758 if (!TARGET_Z196)
4759 {
4760 rtx_code_label *label1 = gen_label_rtx ();
4761 rtx_code_label *label2 = gen_label_rtx ();
4762 rtx temp = gen_reg_rtx (TDmode);
4763 REAL_VALUE_TYPE cmp, sub;
4764
4765 decimal_real_from_string (&cmp, "9223372036854775808.0"); /* 2^63 */
4766 decimal_real_from_string (&sub, "18446744073709551616.0"); /* 2^64 */
4767
4768 /* 2^63 can't be represented as 64bit DFP number with full precision. The
4769 solution is doing the check and the subtraction in TD mode and using a
4770 TD -> DI convert afterwards. */
4771 emit_insn (gen_extendddtd2 (temp, operands[1]));
4772 temp = force_reg (TDmode, temp);
4773 emit_cmp_and_jump_insns (temp,
4774 const_double_from_real_value (cmp, TDmode),
4775 LT, NULL_RTX, VOIDmode, 0, label1);
4776 emit_insn (gen_subtd3 (temp, temp,
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_truncdddi2_dfp (operands[0], operands[1],
4784 GEN_INT (DFP_RND_TOWARD_0)));
4785 emit_label (label2);
4786 DONE;
4787 }
4788 })
4789
4790 (define_expand "fixuns_trunctddi2"
4791 [(parallel
4792 [(set (match_operand:DI 0 "register_operand" "")
4793 (unsigned_fix:DI (match_operand:TD 1 "register_operand" "")))
4794 (unspec:DI [(const_int DFP_RND_TOWARD_0)] UNSPEC_ROUND)
4795 (clobber (reg:CC CC_REGNUM))])]
4796
4797 "TARGET_HARD_DFP"
4798 {
4799 if (!TARGET_Z196)
4800 {
4801 rtx_code_label *label1 = gen_label_rtx ();
4802 rtx_code_label *label2 = gen_label_rtx ();
4803 rtx temp = gen_reg_rtx (TDmode);
4804 REAL_VALUE_TYPE cmp, sub;
4805
4806 operands[1] = force_reg (TDmode, operands[1]);
4807 decimal_real_from_string (&cmp, "9223372036854775808.0"); /* 2^63 */
4808 decimal_real_from_string (&sub, "18446744073709551616.0"); /* 2^64 */
4809
4810 emit_cmp_and_jump_insns (operands[1],
4811 const_double_from_real_value (cmp, TDmode),
4812 LT, NULL_RTX, VOIDmode, 0, label1);
4813 emit_insn (gen_subtd3 (temp, operands[1],
4814 const_double_from_real_value (sub, TDmode)));
4815 emit_insn (gen_fix_trunctddi2_dfp (operands[0], temp,
4816 GEN_INT (DFP_RND_TOWARD_MINF)));
4817 emit_jump (label2);
4818
4819 emit_label (label1);
4820 emit_insn (gen_fix_trunctddi2_dfp (operands[0], operands[1],
4821 GEN_INT (DFP_RND_TOWARD_0)));
4822 emit_label (label2);
4823 DONE;
4824 }
4825 })
4826
4827 ;
4828 ; fixuns_trunc(sf|df|tf)(si|di)2 and fix_trunc(sf|df|tf)(si|di)2
4829 ; instruction pattern(s).
4830 ;
4831
4832 (define_expand "fixuns_trunc<BFP:mode><GPR:mode>2"
4833 [(parallel
4834 [(set (match_operand:GPR 0 "register_operand" "")
4835 (unsigned_fix:GPR (match_operand:BFP 1 "register_operand" "")))
4836 (unspec:GPR [(const_int BFP_RND_TOWARD_0)] UNSPEC_ROUND)
4837 (clobber (reg:CC CC_REGNUM))])]
4838 "TARGET_HARD_FLOAT"
4839 {
4840 if (!TARGET_Z196)
4841 {
4842 rtx_code_label *label1 = gen_label_rtx ();
4843 rtx_code_label *label2 = gen_label_rtx ();
4844 rtx temp = gen_reg_rtx (<BFP:MODE>mode);
4845 REAL_VALUE_TYPE cmp, sub;
4846
4847 operands[1] = force_reg (<BFP:MODE>mode, operands[1]);
4848 real_2expN (&cmp, <GPR:bitsize> - 1, <BFP:MODE>mode);
4849 real_2expN (&sub, <GPR:bitsize>, <BFP:MODE>mode);
4850
4851 emit_cmp_and_jump_insns (operands[1],
4852 const_double_from_real_value (cmp, <BFP:MODE>mode),
4853 LT, NULL_RTX, VOIDmode, 0, label1);
4854 emit_insn (gen_sub<BFP:mode>3 (temp, operands[1],
4855 const_double_from_real_value (sub, <BFP:MODE>mode)));
4856 emit_insn (gen_fix_trunc<BFP:mode><GPR:mode>2_bfp (operands[0], temp,
4857 GEN_INT (BFP_RND_TOWARD_MINF)));
4858 emit_jump (label2);
4859
4860 emit_label (label1);
4861 emit_insn (gen_fix_trunc<BFP:mode><GPR:mode>2_bfp (operands[0],
4862 operands[1], GEN_INT (BFP_RND_TOWARD_0)));
4863 emit_label (label2);
4864 DONE;
4865 }
4866 })
4867
4868 ; fixuns_trunc(td|dd)si2 expander
4869 (define_expand "fixuns_trunc<mode>si2"
4870 [(parallel
4871 [(set (match_operand:SI 0 "register_operand" "")
4872 (unsigned_fix:SI (match_operand:DFP 1 "register_operand" "")))
4873 (unspec:SI [(const_int DFP_RND_TOWARD_0)] UNSPEC_ROUND)
4874 (clobber (reg:CC CC_REGNUM))])]
4875 "TARGET_Z196 && TARGET_HARD_DFP"
4876 "")
4877
4878 ; fixuns_trunc(tf|df|sf|td|dd)(di|si)2 instruction patterns.
4879
4880 (define_insn "*fixuns_truncdfdi2_z13"
4881 [(set (match_operand:DI 0 "register_operand" "=d,v")
4882 (unsigned_fix:DI (match_operand:DF 1 "register_operand" "f,v")))
4883 (unspec:DI [(match_operand:DI 2 "immediate_operand" "K,K")] UNSPEC_ROUND)
4884 (clobber (reg:CC CC_REGNUM))]
4885 "TARGET_VX && TARGET_HARD_FLOAT"
4886 "@
4887 clgdbr\t%0,%h2,%1,0
4888 wclgdb\t%v0,%v1,0,%h2"
4889 [(set_attr "op_type" "RRF,VRR")
4890 (set_attr "type" "ftoi")])
4891
4892 ; clfebr, clfdbr, clfxbr, clgebr, clgdbr, clgxbr
4893 ; clfdtr, clfxtr, clgdtr, clgxtr
4894 (define_insn "*fixuns_trunc<FP:mode><GPR:mode>2_z196"
4895 [(set (match_operand:GPR 0 "register_operand" "=d")
4896 (unsigned_fix:GPR (match_operand:FP 1 "register_operand" "f")))
4897 (unspec:GPR [(match_operand:GPR 2 "immediate_operand" "K")] UNSPEC_ROUND)
4898 (clobber (reg:CC CC_REGNUM))]
4899 "TARGET_Z196 && TARGET_HARD_FLOAT
4900 && (!TARGET_VX || <GPR:MODE>mode != DImode || <FP:MODE>mode != DFmode)"
4901 "cl<GPR:gf><FP:xde><FP:bt>r\t%0,%h2,%1,0"
4902 [(set_attr "op_type" "RRF")
4903 (set_attr "type" "ftoi")])
4904
4905 (define_expand "fix_trunc<DSF:mode><GPR:mode>2"
4906 [(set (match_operand:GPR 0 "register_operand" "")
4907 (fix:GPR (match_operand:DSF 1 "register_operand" "")))]
4908 "TARGET_HARD_FLOAT"
4909 {
4910 emit_insn (gen_fix_trunc<DSF:mode><GPR:mode>2_bfp (operands[0], operands[1],
4911 GEN_INT (BFP_RND_TOWARD_0)));
4912 DONE;
4913 })
4914
4915 (define_insn "*fix_truncdfdi2_bfp_z13"
4916 [(set (match_operand:DI 0 "register_operand" "=d,v")
4917 (fix:DI (match_operand:DF 1 "register_operand" "f,v")))
4918 (unspec:DI [(match_operand:DI 2 "immediate_operand" "K,K")] UNSPEC_ROUND)
4919 (clobber (reg:CC CC_REGNUM))]
4920 "TARGET_VX && TARGET_HARD_FLOAT"
4921 "@
4922 cgdbr\t%0,%h2,%1
4923 wcgdb\t%v0,%v1,0,%h2"
4924 [(set_attr "op_type" "RRE,VRR")
4925 (set_attr "type" "ftoi")])
4926
4927 ; cgxbr, cgdbr, cgebr, cfxbr, cfdbr, cfebr
4928 (define_insn "*fix_trunc<BFP:mode><GPR:mode>2_bfp"
4929 [(set (match_operand:GPR 0 "register_operand" "=d")
4930 (fix:GPR (match_operand:BFP 1 "register_operand" "f")))
4931 (unspec:GPR [(match_operand:GPR 2 "immediate_operand" "K")] UNSPEC_ROUND)
4932 (clobber (reg:CC CC_REGNUM))]
4933 "TARGET_HARD_FLOAT
4934 && (!TARGET_VX || <GPR:MODE>mode != DImode || <BFP:MODE>mode != DFmode)"
4935 "c<GPR:gf><BFP:xde>br\t%0,%h2,%1"
4936 [(set_attr "op_type" "RRE")
4937 (set_attr "type" "ftoi")])
4938
4939 (define_expand "fix_trunc<BFP:mode><GPR:mode>2_bfp"
4940 [(parallel
4941 [(set (match_operand:GPR 0 "register_operand" "=d")
4942 (fix:GPR (match_operand:BFP 1 "register_operand" "f")))
4943 (unspec:GPR [(match_operand:GPR 2 "immediate_operand" "K")] UNSPEC_ROUND)
4944 (clobber (reg:CC CC_REGNUM))])]
4945 "TARGET_HARD_FLOAT")
4946 ;
4947 ; fix_trunc(td|dd)di2 instruction pattern(s).
4948 ;
4949
4950 (define_expand "fix_trunc<mode>di2"
4951 [(set (match_operand:DI 0 "register_operand" "")
4952 (fix:DI (match_operand:DFP 1 "nonimmediate_operand" "")))]
4953 "TARGET_ZARCH && TARGET_HARD_DFP"
4954 {
4955 operands[1] = force_reg (<MODE>mode, operands[1]);
4956 emit_insn (gen_fix_trunc<mode>di2_dfp (operands[0], operands[1],
4957 GEN_INT (DFP_RND_TOWARD_0)));
4958 DONE;
4959 })
4960
4961 ; cgxtr, cgdtr
4962 (define_insn "fix_trunc<DFP:mode>di2_dfp"
4963 [(set (match_operand:DI 0 "register_operand" "=d")
4964 (fix:DI (match_operand:DFP 1 "register_operand" "f")))
4965 (unspec:DI [(match_operand:DI 2 "immediate_operand" "K")] UNSPEC_ROUND)
4966 (clobber (reg:CC CC_REGNUM))]
4967 "TARGET_ZARCH && TARGET_HARD_DFP"
4968 "cg<DFP:xde>tr\t%0,%h2,%1"
4969 [(set_attr "op_type" "RRF")
4970 (set_attr "type" "ftoidfp")])
4971
4972
4973 ;
4974 ; fix_trunctf(si|di)2 instruction pattern(s).
4975 ;
4976
4977 (define_expand "fix_trunctf<mode>2"
4978 [(parallel [(set (match_operand:GPR 0 "register_operand" "")
4979 (fix:GPR (match_operand:TF 1 "register_operand" "")))
4980 (unspec:GPR [(const_int BFP_RND_TOWARD_0)] UNSPEC_ROUND)
4981 (clobber (reg:CC CC_REGNUM))])]
4982 "TARGET_HARD_FLOAT"
4983 "")
4984
4985
4986 ;
4987 ; float(si|di)(tf|df|sf|td|dd)2 instruction pattern(s).
4988 ;
4989
4990 ; cxgbr, cdgbr, cegbr, cxgtr, cdgtr
4991 (define_insn "floatdi<mode>2"
4992 [(set (match_operand:FP 0 "register_operand" "=f,v")
4993 (float:FP (match_operand:DI 1 "register_operand" "d,v")))]
4994 "TARGET_ZARCH && TARGET_HARD_FLOAT"
4995 "@
4996 c<xde>g<bt>r\t%0,%1
4997 wcdgb\t%v0,%v1,0,0"
4998 [(set_attr "op_type" "RRE,VRR")
4999 (set_attr "type" "itof<mode>" )
5000 (set_attr "cpu_facility" "*,vx")
5001 (set_attr "enabled" "*,<DFDI>")])
5002
5003 ; cxfbr, cdfbr, cefbr
5004 (define_insn "floatsi<mode>2"
5005 [(set (match_operand:BFP 0 "register_operand" "=f")
5006 (float:BFP (match_operand:SI 1 "register_operand" "d")))]
5007 "TARGET_HARD_FLOAT"
5008 "c<xde>fbr\t%0,%1"
5009 [(set_attr "op_type" "RRE")
5010 (set_attr "type" "itof<mode>" )])
5011
5012 ; cxftr, cdftr
5013 (define_insn "floatsi<mode>2"
5014 [(set (match_operand:DFP 0 "register_operand" "=f")
5015 (float:DFP (match_operand:SI 1 "register_operand" "d")))]
5016 "TARGET_Z196 && TARGET_HARD_FLOAT"
5017 "c<xde>ftr\t%0,0,%1,0"
5018 [(set_attr "op_type" "RRE")
5019 (set_attr "type" "itof<mode>" )])
5020
5021 ;
5022 ; floatuns(si|di)(tf|df|sf|td|dd)2 instruction pattern(s).
5023 ;
5024
5025 (define_insn "*floatunsdidf2_z13"
5026 [(set (match_operand:DF 0 "register_operand" "=f,v")
5027 (unsigned_float:DF (match_operand:DI 1 "register_operand" "d,v")))]
5028 "TARGET_VX && TARGET_HARD_FLOAT"
5029 "@
5030 cdlgbr\t%0,0,%1,0
5031 wcdlgb\t%v0,%v1,0,0"
5032 [(set_attr "op_type" "RRE,VRR")
5033 (set_attr "type" "itofdf")])
5034
5035 ; cxlgbr, cdlgbr, celgbr, cxlgtr, cdlgtr
5036 ; cxlfbr, cdlfbr, celfbr, cxlftr, cdlftr
5037 (define_insn "*floatuns<GPR:mode><FP:mode>2"
5038 [(set (match_operand:FP 0 "register_operand" "=f")
5039 (unsigned_float:FP (match_operand:GPR 1 "register_operand" "d")))]
5040 "TARGET_Z196 && TARGET_HARD_FLOAT
5041 && (!TARGET_VX || <FP:MODE>mode != DFmode || <GPR:MODE>mode != DImode)"
5042 "c<FP:xde>l<GPR:gf><FP:bt>r\t%0,0,%1,0"
5043 [(set_attr "op_type" "RRE")
5044 (set_attr "type" "itof<FP:mode>")])
5045
5046 (define_expand "floatuns<GPR:mode><FP:mode>2"
5047 [(set (match_operand:FP 0 "register_operand" "")
5048 (unsigned_float:FP (match_operand:GPR 1 "register_operand" "")))]
5049 "TARGET_Z196 && TARGET_HARD_FLOAT")
5050
5051 ;
5052 ; truncdfsf2 instruction pattern(s).
5053 ;
5054
5055 (define_insn "truncdfsf2"
5056 [(set (match_operand:SF 0 "register_operand" "=f,v")
5057 (float_truncate:SF (match_operand:DF 1 "register_operand" "f,v")))]
5058 "TARGET_HARD_FLOAT"
5059 "@
5060 ledbr\t%0,%1
5061 wledb\t%v0,%v1,0,0" ; IEEE inexact exception not suppressed
5062 ; According to BFP rounding mode
5063 [(set_attr "op_type" "RRE,VRR")
5064 (set_attr "type" "ftruncdf")
5065 (set_attr "cpu_facility" "*,vx")])
5066
5067 ;
5068 ; trunctf(df|sf)2 instruction pattern(s).
5069 ;
5070
5071 ; ldxbr, lexbr
5072 (define_insn "trunctf<mode>2"
5073 [(set (match_operand:DSF 0 "register_operand" "=f")
5074 (float_truncate:DSF (match_operand:TF 1 "register_operand" "f")))
5075 (clobber (match_scratch:TF 2 "=f"))]
5076 "TARGET_HARD_FLOAT"
5077 "l<xde>xbr\t%2,%1\;l<xde>r\t%0,%2"
5078 [(set_attr "length" "6")
5079 (set_attr "type" "ftrunctf")])
5080
5081 ;
5082 ; trunctddd2 and truncddsd2 instruction pattern(s).
5083 ;
5084
5085
5086 (define_expand "trunctddd2"
5087 [(parallel
5088 [(set (match_operand:DD 0 "register_operand" "")
5089 (float_truncate:DD (match_operand:TD 1 "register_operand" "")))
5090 (unspec:DI [(const_int DFP_RND_CURRENT)] UNSPEC_ROUND)
5091 (clobber (scratch:TD))])]
5092 "TARGET_HARD_DFP")
5093
5094 (define_insn "*trunctddd2"
5095 [(set (match_operand:DD 0 "register_operand" "=f")
5096 (float_truncate:DD (match_operand:TD 1 "register_operand" "f")))
5097 (unspec:DI [(match_operand:DI 2 "const_mask_operand" "I")] UNSPEC_ROUND)
5098 (clobber (match_scratch:TD 3 "=f"))]
5099 "TARGET_HARD_DFP"
5100 "ldxtr\t%3,%2,%1,0\;ldr\t%0,%3"
5101 [(set_attr "length" "6")
5102 (set_attr "type" "ftruncdd")])
5103
5104 (define_insn "truncddsd2"
5105 [(set (match_operand:SD 0 "register_operand" "=f")
5106 (float_truncate:SD (match_operand:DD 1 "register_operand" "f")))]
5107 "TARGET_HARD_DFP"
5108 "ledtr\t%0,0,%1,0"
5109 [(set_attr "op_type" "RRF")
5110 (set_attr "type" "ftruncsd")])
5111
5112 (define_expand "trunctdsd2"
5113 [(parallel
5114 [(set (match_dup 2)
5115 (float_truncate:DD (match_operand:TD 1 "register_operand" "")))
5116 (unspec:DI [(const_int DFP_RND_PREP_FOR_SHORT_PREC)] UNSPEC_ROUND)
5117 (clobber (match_scratch:TD 3 ""))])
5118 (set (match_operand:SD 0 "register_operand" "")
5119 (float_truncate:SD (match_dup 2)))]
5120 "TARGET_HARD_DFP"
5121 {
5122 operands[2] = gen_reg_rtx (DDmode);
5123 })
5124
5125 ;
5126 ; extend(sf|df)(df|tf)2 instruction pattern(s).
5127 ;
5128
5129 (define_insn "*extendsfdf2_z13"
5130 [(set (match_operand:DF 0 "register_operand" "=f,f,v")
5131 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "f,R,v")))]
5132 "TARGET_VX && TARGET_HARD_FLOAT"
5133 "@
5134 ldebr\t%0,%1
5135 ldeb\t%0,%1
5136 wldeb\t%v0,%v1"
5137 [(set_attr "op_type" "RRE,RXE,VRR")
5138 (set_attr "type" "fsimpdf, floaddf,fsimpdf")])
5139
5140 ; ldebr, ldeb, lxdbr, lxdb, lxebr, lxeb
5141 (define_insn "*extend<DSF:mode><BFP:mode>2"
5142 [(set (match_operand:BFP 0 "register_operand" "=f,f")
5143 (float_extend:BFP (match_operand:DSF 1 "nonimmediate_operand" "f,R")))]
5144 "TARGET_HARD_FLOAT
5145 && GET_MODE_SIZE (<BFP:MODE>mode) > GET_MODE_SIZE (<DSF:MODE>mode)
5146 && (!TARGET_VX || <BFP:MODE>mode != DFmode || <DSF:MODE>mode != SFmode)"
5147 "@
5148 l<BFP:xde><DSF:xde>br\t%0,%1
5149 l<BFP:xde><DSF:xde>b\t%0,%1"
5150 [(set_attr "op_type" "RRE,RXE")
5151 (set_attr "type" "fsimp<BFP:mode>, fload<BFP:mode>")])
5152
5153 (define_expand "extend<DSF:mode><BFP:mode>2"
5154 [(set (match_operand:BFP 0 "register_operand" "")
5155 (float_extend:BFP (match_operand:DSF 1 "nonimmediate_operand" "")))]
5156 "TARGET_HARD_FLOAT
5157 && GET_MODE_SIZE (<BFP:MODE>mode) > GET_MODE_SIZE (<DSF:MODE>mode)")
5158
5159 ;
5160 ; extendddtd2 and extendsddd2 instruction pattern(s).
5161 ;
5162
5163 (define_insn "extendddtd2"
5164 [(set (match_operand:TD 0 "register_operand" "=f")
5165 (float_extend:TD (match_operand:DD 1 "register_operand" "f")))]
5166 "TARGET_HARD_DFP"
5167 "lxdtr\t%0,%1,0"
5168 [(set_attr "op_type" "RRF")
5169 (set_attr "type" "fsimptf")])
5170
5171 (define_insn "extendsddd2"
5172 [(set (match_operand:DD 0 "register_operand" "=f")
5173 (float_extend:DD (match_operand:SD 1 "register_operand" "f")))]
5174 "TARGET_HARD_DFP"
5175 "ldetr\t%0,%1,0"
5176 [(set_attr "op_type" "RRF")
5177 (set_attr "type" "fsimptf")])
5178
5179 (define_expand "extendsdtd2"
5180 [(set (match_dup 2)
5181 (float_extend:DD (match_operand:SD 1 "register_operand" "")))
5182 (set (match_operand:TD 0 "register_operand" "")
5183 (float_extend:TD (match_dup 2)))]
5184 "TARGET_HARD_DFP"
5185 {
5186 operands[2] = gen_reg_rtx (DDmode);
5187 })
5188
5189 ; Binary Floating Point - load fp integer
5190
5191 ; Expanders for: floor, btrunc, round, ceil, and nearbyint
5192 ; For all of them the inexact exceptions are suppressed.
5193
5194 ; fiebra, fidbra, fixbra
5195 (define_insn "<FPINT:fpint_name><BFP:mode>2"
5196 [(set (match_operand:BFP 0 "register_operand" "=f")
5197 (unspec:BFP [(match_operand:BFP 1 "register_operand" "f")]
5198 FPINT))]
5199 "TARGET_Z196"
5200 "fi<BFP:xde>bra\t%0,<FPINT:fpint_roundingmode>,%1,4"
5201 [(set_attr "op_type" "RRF")
5202 (set_attr "type" "fsimp<BFP:mode>")])
5203
5204 ; rint is supposed to raise an inexact exception so we can use the
5205 ; older instructions.
5206
5207 ; fiebr, fidbr, fixbr
5208 (define_insn "rint<BFP:mode>2"
5209 [(set (match_operand:BFP 0 "register_operand" "=f")
5210 (unspec:BFP [(match_operand:BFP 1 "register_operand" "f")]
5211 UNSPEC_FPINT_RINT))]
5212 ""
5213 "fi<BFP:xde>br\t%0,0,%1"
5214 [(set_attr "op_type" "RRF")
5215 (set_attr "type" "fsimp<BFP:mode>")])
5216
5217
5218 ; Decimal Floating Point - load fp integer
5219
5220 ; fidtr, fixtr
5221 (define_insn "<FPINT:fpint_name><DFP:mode>2"
5222 [(set (match_operand:DFP 0 "register_operand" "=f")
5223 (unspec:DFP [(match_operand:DFP 1 "register_operand" "f")]
5224 FPINT))]
5225 "TARGET_HARD_DFP"
5226 "fi<DFP:xde>tr\t%0,<FPINT:fpint_roundingmode>,%1,4"
5227 [(set_attr "op_type" "RRF")
5228 (set_attr "type" "fsimp<DFP:mode>")])
5229
5230 ; fidtr, fixtr
5231 (define_insn "rint<DFP:mode>2"
5232 [(set (match_operand:DFP 0 "register_operand" "=f")
5233 (unspec:DFP [(match_operand:DFP 1 "register_operand" "f")]
5234 UNSPEC_FPINT_RINT))]
5235 "TARGET_HARD_DFP"
5236 "fi<DFP:xde>tr\t%0,0,%1,0"
5237 [(set_attr "op_type" "RRF")
5238 (set_attr "type" "fsimp<DFP:mode>")])
5239
5240 ;
5241 ; Binary <-> Decimal floating point trunc patterns
5242 ;
5243
5244 (define_insn "*trunc<BFP:mode><DFP_ALL:mode>2"
5245 [(set (reg:DFP_ALL FPR0_REGNUM)
5246 (float_truncate:DFP_ALL (reg:BFP FPR4_REGNUM)))
5247 (use (reg:SI GPR0_REGNUM))
5248 (clobber (reg:CC CC_REGNUM))
5249 (clobber (reg:SI GPR1_REGNUM))]
5250 "TARGET_HARD_DFP"
5251 "pfpo")
5252
5253 (define_insn "*trunc<DFP_ALL:mode><BFP:mode>2"
5254 [(set (reg:BFP FPR0_REGNUM)
5255 (float_truncate:BFP (reg:DFP_ALL FPR4_REGNUM)))
5256 (use (reg:SI GPR0_REGNUM))
5257 (clobber (reg:CC CC_REGNUM))
5258 (clobber (reg:SI GPR1_REGNUM))]
5259 "TARGET_HARD_DFP"
5260 "pfpo")
5261
5262 (define_expand "trunc<BFP:mode><DFP_ALL:mode>2"
5263 [(set (reg:BFP FPR4_REGNUM) (match_operand:BFP 1 "nonimmediate_operand" ""))
5264 (set (reg:SI GPR0_REGNUM) (match_dup 2))
5265 (parallel
5266 [(set (reg:DFP_ALL FPR0_REGNUM)
5267 (float_truncate:DFP_ALL (reg:BFP FPR4_REGNUM)))
5268 (use (reg:SI GPR0_REGNUM))
5269 (clobber (reg:CC CC_REGNUM))
5270 (clobber (reg:SI GPR1_REGNUM))])
5271 (set (match_operand:DFP_ALL 0 "nonimmediate_operand" "")
5272 (reg:DFP_ALL FPR0_REGNUM))]
5273 "TARGET_HARD_DFP
5274 && GET_MODE_SIZE (<BFP:MODE>mode) > GET_MODE_SIZE (<DFP_ALL:MODE>mode)"
5275 {
5276 HOST_WIDE_INT flags;
5277
5278 flags = (PFPO_CONVERT |
5279 PFPO_OP_TYPE_<DFP_ALL:MODE> << PFPO_OP0_TYPE_SHIFT |
5280 PFPO_OP_TYPE_<BFP:MODE> << PFPO_OP1_TYPE_SHIFT);
5281
5282 operands[2] = GEN_INT (flags);
5283 })
5284
5285 (define_expand "trunc<DFP_ALL:mode><BFP:mode>2"
5286 [(set (reg:DFP_ALL FPR4_REGNUM)
5287 (match_operand:DFP_ALL 1 "nonimmediate_operand" ""))
5288 (set (reg:SI GPR0_REGNUM) (match_dup 2))
5289 (parallel
5290 [(set (reg:BFP FPR0_REGNUM) (float_truncate:BFP (reg:DFP_ALL FPR4_REGNUM)))
5291 (use (reg:SI GPR0_REGNUM))
5292 (clobber (reg:CC CC_REGNUM))
5293 (clobber (reg:SI GPR1_REGNUM))])
5294 (set (match_operand:BFP 0 "nonimmediate_operand" "") (reg:BFP FPR0_REGNUM))]
5295 "TARGET_HARD_DFP
5296 && GET_MODE_SIZE (<DFP_ALL:MODE>mode) >= GET_MODE_SIZE (<BFP:MODE>mode)"
5297 {
5298 HOST_WIDE_INT flags;
5299
5300 flags = (PFPO_CONVERT |
5301 PFPO_OP_TYPE_<BFP:MODE> << PFPO_OP0_TYPE_SHIFT |
5302 PFPO_OP_TYPE_<DFP_ALL:MODE> << PFPO_OP1_TYPE_SHIFT);
5303
5304 operands[2] = GEN_INT (flags);
5305 })
5306
5307 ;
5308 ; Binary <-> Decimal floating point extend patterns
5309 ;
5310
5311 (define_insn "*extend<BFP:mode><DFP_ALL:mode>2"
5312 [(set (reg:DFP_ALL FPR0_REGNUM) (float_extend:DFP_ALL (reg:BFP FPR4_REGNUM)))
5313 (use (reg:SI GPR0_REGNUM))
5314 (clobber (reg:CC CC_REGNUM))
5315 (clobber (reg:SI GPR1_REGNUM))]
5316 "TARGET_HARD_DFP"
5317 "pfpo")
5318
5319 (define_insn "*extend<DFP_ALL:mode><BFP:mode>2"
5320 [(set (reg:BFP FPR0_REGNUM) (float_extend:BFP (reg:DFP_ALL FPR4_REGNUM)))
5321 (use (reg:SI GPR0_REGNUM))
5322 (clobber (reg:CC CC_REGNUM))
5323 (clobber (reg:SI GPR1_REGNUM))]
5324 "TARGET_HARD_DFP"
5325 "pfpo")
5326
5327 (define_expand "extend<BFP:mode><DFP_ALL:mode>2"
5328 [(set (reg:BFP FPR4_REGNUM) (match_operand:BFP 1 "nonimmediate_operand" ""))
5329 (set (reg:SI GPR0_REGNUM) (match_dup 2))
5330 (parallel
5331 [(set (reg:DFP_ALL FPR0_REGNUM)
5332 (float_extend:DFP_ALL (reg:BFP FPR4_REGNUM)))
5333 (use (reg:SI GPR0_REGNUM))
5334 (clobber (reg:CC CC_REGNUM))
5335 (clobber (reg:SI GPR1_REGNUM))])
5336 (set (match_operand:DFP_ALL 0 "nonimmediate_operand" "")
5337 (reg:DFP_ALL FPR0_REGNUM))]
5338 "TARGET_HARD_DFP
5339 && GET_MODE_SIZE (<BFP:MODE>mode) <= GET_MODE_SIZE (<DFP_ALL:MODE>mode)"
5340 {
5341 HOST_WIDE_INT flags;
5342
5343 flags = (PFPO_CONVERT |
5344 PFPO_OP_TYPE_<DFP_ALL:MODE> << PFPO_OP0_TYPE_SHIFT |
5345 PFPO_OP_TYPE_<BFP:MODE> << PFPO_OP1_TYPE_SHIFT);
5346
5347 operands[2] = GEN_INT (flags);
5348 })
5349
5350 (define_expand "extend<DFP_ALL:mode><BFP:mode>2"
5351 [(set (reg:DFP_ALL FPR4_REGNUM)
5352 (match_operand:DFP_ALL 1 "nonimmediate_operand" ""))
5353 (set (reg:SI GPR0_REGNUM) (match_dup 2))
5354 (parallel
5355 [(set (reg:BFP FPR0_REGNUM) (float_extend:BFP (reg:DFP_ALL FPR4_REGNUM)))
5356 (use (reg:SI GPR0_REGNUM))
5357 (clobber (reg:CC CC_REGNUM))
5358 (clobber (reg:SI GPR1_REGNUM))])
5359 (set (match_operand:BFP 0 "nonimmediate_operand" "") (reg:BFP FPR0_REGNUM))]
5360 "TARGET_HARD_DFP
5361 && GET_MODE_SIZE (<DFP_ALL:MODE>mode) < GET_MODE_SIZE (<BFP:MODE>mode)"
5362 {
5363 HOST_WIDE_INT flags;
5364
5365 flags = (PFPO_CONVERT |
5366 PFPO_OP_TYPE_<BFP:MODE> << PFPO_OP0_TYPE_SHIFT |
5367 PFPO_OP_TYPE_<DFP_ALL:MODE> << PFPO_OP1_TYPE_SHIFT);
5368
5369 operands[2] = GEN_INT (flags);
5370 })
5371
5372
5373 ;;
5374 ;; ARITHMETIC OPERATIONS
5375 ;;
5376 ; arithmetic operations set the ConditionCode,
5377 ; because of unpredictable Bits in Register for Halfword and Byte
5378 ; the ConditionCode can be set wrong in operations for Halfword and Byte
5379
5380 ;;
5381 ;;- Add instructions.
5382 ;;
5383
5384 ;
5385 ; addti3 instruction pattern(s).
5386 ;
5387
5388 (define_expand "addti3"
5389 [(parallel
5390 [(set (match_operand:TI 0 "register_operand" "")
5391 (plus:TI (match_operand:TI 1 "nonimmediate_operand" "")
5392 (match_operand:TI 2 "general_operand" "") ) )
5393 (clobber (reg:CC CC_REGNUM))])]
5394 "TARGET_ZARCH"
5395 {
5396 /* For z13 we have vaq which doesn't set CC. */
5397 if (TARGET_VX)
5398 {
5399 emit_insn (gen_rtx_SET (operands[0],
5400 gen_rtx_PLUS (TImode,
5401 copy_to_mode_reg (TImode, operands[1]),
5402 copy_to_mode_reg (TImode, operands[2]))));
5403 DONE;
5404 }
5405 })
5406
5407 (define_insn_and_split "*addti3"
5408 [(set (match_operand:TI 0 "register_operand" "=&d")
5409 (plus:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
5410 (match_operand:TI 2 "general_operand" "do") ) )
5411 (clobber (reg:CC CC_REGNUM))]
5412 "TARGET_ZARCH"
5413 "#"
5414 "&& reload_completed"
5415 [(parallel
5416 [(set (reg:CCL1 CC_REGNUM)
5417 (compare:CCL1 (plus:DI (match_dup 7) (match_dup 8))
5418 (match_dup 7)))
5419 (set (match_dup 6) (plus:DI (match_dup 7) (match_dup 8)))])
5420 (parallel
5421 [(set (match_dup 3) (plus:DI
5422 (plus:DI (ltu:DI (reg:CCL1 CC_REGNUM) (const_int 0))
5423 (match_dup 4)) (match_dup 5)))
5424 (clobber (reg:CC CC_REGNUM))])]
5425 "operands[3] = operand_subword (operands[0], 0, 0, TImode);
5426 operands[4] = operand_subword (operands[1], 0, 0, TImode);
5427 operands[5] = operand_subword (operands[2], 0, 0, TImode);
5428 operands[6] = operand_subword (operands[0], 1, 0, TImode);
5429 operands[7] = operand_subword (operands[1], 1, 0, TImode);
5430 operands[8] = operand_subword (operands[2], 1, 0, TImode);"
5431 [(set_attr "op_type" "*")
5432 (set_attr "cpu_facility" "*")])
5433
5434 ;
5435 ; adddi3 instruction pattern(s).
5436 ;
5437
5438 (define_expand "adddi3"
5439 [(parallel
5440 [(set (match_operand:DI 0 "nonimmediate_operand" "")
5441 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
5442 (match_operand:DI 2 "general_operand" "")))
5443 (clobber (reg:CC CC_REGNUM))])]
5444 ""
5445 "")
5446
5447 (define_insn "*adddi3_sign"
5448 [(set (match_operand:DI 0 "register_operand" "=d,d")
5449 (plus:DI (sign_extend:DI (match_operand:SI 2 "general_operand" "d,T"))
5450 (match_operand:DI 1 "register_operand" "0,0")))
5451 (clobber (reg:CC CC_REGNUM))]
5452 "TARGET_ZARCH"
5453 "@
5454 agfr\t%0,%2
5455 agf\t%0,%2"
5456 [(set_attr "op_type" "RRE,RXY")
5457 (set_attr "z196prop" "z196_cracked,z196_cracked")])
5458
5459 (define_insn "*adddi3_zero_cc"
5460 [(set (reg CC_REGNUM)
5461 (compare (plus:DI (zero_extend:DI (match_operand:SI 2 "general_operand" "d,T"))
5462 (match_operand:DI 1 "register_operand" "0,0"))
5463 (const_int 0)))
5464 (set (match_operand:DI 0 "register_operand" "=d,d")
5465 (plus:DI (zero_extend:DI (match_dup 2)) (match_dup 1)))]
5466 "s390_match_ccmode (insn, CCLmode) && TARGET_ZARCH"
5467 "@
5468 algfr\t%0,%2
5469 algf\t%0,%2"
5470 [(set_attr "op_type" "RRE,RXY")
5471 (set_attr "z10prop" "z10_super_E1,z10_super_E1")])
5472
5473 (define_insn "*adddi3_zero_cconly"
5474 [(set (reg CC_REGNUM)
5475 (compare (plus:DI (zero_extend:DI (match_operand:SI 2 "general_operand" "d,T"))
5476 (match_operand:DI 1 "register_operand" "0,0"))
5477 (const_int 0)))
5478 (clobber (match_scratch:DI 0 "=d,d"))]
5479 "s390_match_ccmode (insn, CCLmode) && TARGET_ZARCH"
5480 "@
5481 algfr\t%0,%2
5482 algf\t%0,%2"
5483 [(set_attr "op_type" "RRE,RXY")
5484 (set_attr "z10prop" "z10_super_E1,z10_super_E1")])
5485
5486 (define_insn "*adddi3_zero"
5487 [(set (match_operand:DI 0 "register_operand" "=d,d")
5488 (plus:DI (zero_extend:DI (match_operand:SI 2 "general_operand" "d,T"))
5489 (match_operand:DI 1 "register_operand" "0,0")))
5490 (clobber (reg:CC CC_REGNUM))]
5491 "TARGET_ZARCH"
5492 "@
5493 algfr\t%0,%2
5494 algf\t%0,%2"
5495 [(set_attr "op_type" "RRE,RXY")
5496 (set_attr "z10prop" "z10_super_E1,z10_super_E1")])
5497
5498 (define_insn_and_split "*adddi3_31z"
5499 [(set (match_operand:DI 0 "nonimmediate_operand" "=&d")
5500 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
5501 (match_operand:DI 2 "general_operand" "do") ) )
5502 (clobber (reg:CC CC_REGNUM))]
5503 "!TARGET_ZARCH && TARGET_CPU_ZARCH"
5504 "#"
5505 "&& reload_completed"
5506 [(parallel
5507 [(set (reg:CCL1 CC_REGNUM)
5508 (compare:CCL1 (plus:SI (match_dup 7) (match_dup 8))
5509 (match_dup 7)))
5510 (set (match_dup 6) (plus:SI (match_dup 7) (match_dup 8)))])
5511 (parallel
5512 [(set (match_dup 3) (plus:SI
5513 (plus:SI (ltu:SI (reg:CCL1 CC_REGNUM) (const_int 0))
5514 (match_dup 4)) (match_dup 5)))
5515 (clobber (reg:CC CC_REGNUM))])]
5516 "operands[3] = operand_subword (operands[0], 0, 0, DImode);
5517 operands[4] = operand_subword (operands[1], 0, 0, DImode);
5518 operands[5] = operand_subword (operands[2], 0, 0, DImode);
5519 operands[6] = operand_subword (operands[0], 1, 0, DImode);
5520 operands[7] = operand_subword (operands[1], 1, 0, DImode);
5521 operands[8] = operand_subword (operands[2], 1, 0, DImode);")
5522
5523 (define_insn_and_split "*adddi3_31"
5524 [(set (match_operand:DI 0 "nonimmediate_operand" "=&d")
5525 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
5526 (match_operand:DI 2 "general_operand" "do") ) )
5527 (clobber (reg:CC CC_REGNUM))]
5528 "!TARGET_CPU_ZARCH"
5529 "#"
5530 "&& reload_completed"
5531 [(parallel
5532 [(set (match_dup 3) (plus:SI (match_dup 4) (match_dup 5)))
5533 (clobber (reg:CC CC_REGNUM))])
5534 (parallel
5535 [(set (reg:CCL1 CC_REGNUM)
5536 (compare:CCL1 (plus:SI (match_dup 7) (match_dup 8))
5537 (match_dup 7)))
5538 (set (match_dup 6) (plus:SI (match_dup 7) (match_dup 8)))])
5539 (set (pc)
5540 (if_then_else (ltu (reg:CCL1 CC_REGNUM) (const_int 0))
5541 (pc)
5542 (label_ref (match_dup 9))))
5543 (parallel
5544 [(set (match_dup 3) (plus:SI (match_dup 3) (const_int 1)))
5545 (clobber (reg:CC CC_REGNUM))])
5546 (match_dup 9)]
5547 "operands[3] = operand_subword (operands[0], 0, 0, DImode);
5548 operands[4] = operand_subword (operands[1], 0, 0, DImode);
5549 operands[5] = operand_subword (operands[2], 0, 0, DImode);
5550 operands[6] = operand_subword (operands[0], 1, 0, DImode);
5551 operands[7] = operand_subword (operands[1], 1, 0, DImode);
5552 operands[8] = operand_subword (operands[2], 1, 0, DImode);
5553 operands[9] = gen_label_rtx ();")
5554
5555 ;
5556 ; addsi3 instruction pattern(s).
5557 ;
5558
5559 (define_expand "addsi3"
5560 [(parallel
5561 [(set (match_operand:SI 0 "nonimmediate_operand" "")
5562 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "")
5563 (match_operand:SI 2 "general_operand" "")))
5564 (clobber (reg:CC CC_REGNUM))])]
5565 ""
5566 "")
5567
5568 (define_insn "*addsi3_sign"
5569 [(set (match_operand:SI 0 "register_operand" "=d,d")
5570 (plus:SI (sign_extend:SI (match_operand:HI 2 "memory_operand" "R,T"))
5571 (match_operand:SI 1 "register_operand" "0,0")))
5572 (clobber (reg:CC CC_REGNUM))]
5573 ""
5574 "@
5575 ah\t%0,%2
5576 ahy\t%0,%2"
5577 [(set_attr "op_type" "RX,RXY")
5578 (set_attr "cpu_facility" "*,longdisp")
5579 (set_attr "z196prop" "z196_cracked,z196_cracked")])
5580
5581 ;
5582 ; add(di|si)3 instruction pattern(s).
5583 ;
5584
5585 ; ark, agrk, ar, ahi, ahik, aghik, alfi, slfi, a, ay, agr, aghi, algfi, slgfi, ag, asi, agsi
5586 (define_insn "*add<mode>3"
5587 [(set (match_operand:GPR 0 "nonimmediate_operand" "=d,d,d,d, d, d,d,d,S")
5588 (plus:GPR (match_operand:GPR 1 "nonimmediate_operand" "%0,d,0,d, 0, 0,0,0,0")
5589 (match_operand:GPR 2 "general_operand" " d,d,K,K,Op,On,R,T,C") ) )
5590 (clobber (reg:CC CC_REGNUM))]
5591 ""
5592 "@
5593 a<g>r\t%0,%2
5594 a<g>rk\t%0,%1,%2
5595 a<g>hi\t%0,%h2
5596 a<g>hik\t%0,%1,%h2
5597 al<g>fi\t%0,%2
5598 sl<g>fi\t%0,%n2
5599 a<g>\t%0,%2
5600 a<y>\t%0,%2
5601 a<g>si\t%0,%c2"
5602 [(set_attr "op_type" "RR<E>,RRF,RI,RIE,RIL,RIL,RX<Y>,RXY,SIY")
5603 (set_attr "cpu_facility" "*,z196,*,z196,extimm,extimm,*,longdisp,z10")
5604 (set_attr "z10prop" "z10_super_E1,*,z10_super_E1,*,z10_super_E1,z10_super_E1,
5605 z10_super_E1,z10_super_E1,z10_super_E1")])
5606
5607 ; alr, alfi, slfi, al, aly, alrk, alhsik, algr, algfi, slgfi, alg, alsi, algsi, algrk, alghsik
5608 (define_insn "*add<mode>3_carry1_cc"
5609 [(set (reg CC_REGNUM)
5610 (compare (plus:GPR (match_operand:GPR 1 "nonimmediate_operand" "%0,d, 0, 0,d,0,0,0")
5611 (match_operand:GPR 2 "general_operand" " d,d,Op,On,K,R,T,C"))
5612 (match_dup 1)))
5613 (set (match_operand:GPR 0 "nonimmediate_operand" "=d,d, d, d,d,d,d,d")
5614 (plus:GPR (match_dup 1) (match_dup 2)))]
5615 "s390_match_ccmode (insn, CCL1mode)"
5616 "@
5617 al<g>r\t%0,%2
5618 al<g>rk\t%0,%1,%2
5619 al<g>fi\t%0,%2
5620 sl<g>fi\t%0,%n2
5621 al<g>hsik\t%0,%1,%h2
5622 al<g>\t%0,%2
5623 al<y>\t%0,%2
5624 al<g>si\t%0,%c2"
5625 [(set_attr "op_type" "RR<E>,RRF,RIL,RIL,RIE,RX<Y>,RXY,SIY")
5626 (set_attr "cpu_facility" "*,z196,extimm,extimm,z196,*,longdisp,z10")
5627 (set_attr "z10prop" "z10_super_E1,*,z10_super_E1,z10_super_E1,*,
5628 z10_super_E1,z10_super_E1,z10_super_E1")])
5629
5630 ; alr, al, aly, algr, alg, alrk, algrk
5631 (define_insn "*add<mode>3_carry1_cconly"
5632 [(set (reg CC_REGNUM)
5633 (compare (plus:GPR (match_operand:GPR 1 "nonimmediate_operand" "%0,d,0,0")
5634 (match_operand:GPR 2 "general_operand" "d,d,R,T"))
5635 (match_dup 1)))
5636 (clobber (match_scratch:GPR 0 "=d,d,d,d"))]
5637 "s390_match_ccmode (insn, CCL1mode)"
5638 "@
5639 al<g>r\t%0,%2
5640 al<g>rk\t%0,%1,%2
5641 al<g>\t%0,%2
5642 al<y>\t%0,%2"
5643 [(set_attr "op_type" "RR<E>,RRF,RX<Y>,RXY")
5644 (set_attr "cpu_facility" "*,z196,*,longdisp")
5645 (set_attr "z10prop" "z10_super_E1,*,z10_super_E1,z10_super_E1")])
5646
5647 ; alr, alfi, slfi, al, aly, algr, algfi, slgfi, alg, alsi, algsi, alrk, algrk, alhsik, alghsik
5648 (define_insn "*add<mode>3_carry2_cc"
5649 [(set (reg CC_REGNUM)
5650 (compare (plus:GPR (match_operand:GPR 1 "nonimmediate_operand" "%0,d, 0, 0,d,0,0,0")
5651 (match_operand:GPR 2 "general_operand" " d,d,Op,On,K,R,T,C"))
5652 (match_dup 2)))
5653 (set (match_operand:GPR 0 "nonimmediate_operand" "=d,d, d, d,d,d,d,S")
5654 (plus:GPR (match_dup 1) (match_dup 2)))]
5655 "s390_match_ccmode (insn, CCL1mode)"
5656 "@
5657 al<g>r\t%0,%2
5658 al<g>rk\t%0,%1,%2
5659 al<g>fi\t%0,%2
5660 sl<g>fi\t%0,%n2
5661 al<g>hsik\t%0,%1,%h2
5662 al<g>\t%0,%2
5663 al<y>\t%0,%2
5664 al<g>si\t%0,%c2"
5665 [(set_attr "op_type" "RR<E>,RRF,RIL,RIL,RIE,RX<Y>,RXY,SIY")
5666 (set_attr "cpu_facility" "*,z196,extimm,extimm,z196,*,longdisp,z10")
5667 (set_attr "z10prop" "z10_super_E1,*,z10_super_E1,z10_super_E1,*,
5668 z10_super_E1,z10_super_E1,z10_super_E1")])
5669
5670 ; alr, al, aly, algr, alg, alrk, algrk
5671 (define_insn "*add<mode>3_carry2_cconly"
5672 [(set (reg CC_REGNUM)
5673 (compare (plus:GPR (match_operand:GPR 1 "nonimmediate_operand" "%0,d,0,0")
5674 (match_operand:GPR 2 "general_operand" "d,d,R,T"))
5675 (match_dup 2)))
5676 (clobber (match_scratch:GPR 0 "=d,d,d,d"))]
5677 "s390_match_ccmode (insn, CCL1mode)"
5678 "@
5679 al<g>r\t%0,%2
5680 al<g>rk\t%0,%1,%2
5681 al<g>\t%0,%2
5682 al<y>\t%0,%2"
5683 [(set_attr "op_type" "RR<E>,RRF,RX<Y>,RXY")
5684 (set_attr "cpu_facility" "*,z196,*,longdisp")
5685 (set_attr "z10prop" "z10_super_E1,*,z10_super_E1,z10_super_E1")])
5686
5687 ; alr, alfi, slfi, al, aly, algr, algfi, slgfi, alg, alsi, algsi, alrk, algrk, alhsik, alghsik
5688 (define_insn "*add<mode>3_cc"
5689 [(set (reg CC_REGNUM)
5690 (compare (plus:GPR (match_operand:GPR 1 "nonimmediate_operand" "%0,d, 0, 0,d,0,0,0")
5691 (match_operand:GPR 2 "general_operand" " d,d,Op,On,K,R,T,C"))
5692 (const_int 0)))
5693 (set (match_operand:GPR 0 "nonimmediate_operand" "=d,d, d, d,d,d,d,S")
5694 (plus:GPR (match_dup 1) (match_dup 2)))]
5695 "s390_match_ccmode (insn, CCLmode)"
5696 "@
5697 al<g>r\t%0,%2
5698 al<g>rk\t%0,%1,%2
5699 al<g>fi\t%0,%2
5700 sl<g>fi\t%0,%n2
5701 al<g>hsik\t%0,%1,%h2
5702 al<g>\t%0,%2
5703 al<y>\t%0,%2
5704 al<g>si\t%0,%c2"
5705 [(set_attr "op_type" "RR<E>,RRF,RIL,RIL,RIE,RX<Y>,RXY,SIY")
5706 (set_attr "cpu_facility" "*,z196,extimm,extimm,z196,*,longdisp,z10")
5707 (set_attr "z10prop" "z10_super_E1,*,z10_super_E1,z10_super_E1,
5708 *,z10_super_E1,z10_super_E1,z10_super_E1")])
5709
5710 ; alr, al, aly, algr, alg, alrk, algrk
5711 (define_insn "*add<mode>3_cconly"
5712 [(set (reg CC_REGNUM)
5713 (compare (plus:GPR (match_operand:GPR 1 "nonimmediate_operand" "%0,d,0,0")
5714 (match_operand:GPR 2 "general_operand" "d,d,R,T"))
5715 (const_int 0)))
5716 (clobber (match_scratch:GPR 0 "=d,d,d,d"))]
5717 "s390_match_ccmode (insn, CCLmode)"
5718 "@
5719 al<g>r\t%0,%2
5720 al<g>rk\t%0,%1,%2
5721 al<g>\t%0,%2
5722 al<y>\t%0,%2"
5723 [(set_attr "op_type" "RR<E>,RRF,RX<Y>,RXY")
5724 (set_attr "cpu_facility" "*,z196,*,longdisp")
5725 (set_attr "z10prop" "z10_super_E1,*,z10_super_E1,z10_super_E1")])
5726
5727 ; alr, al, aly, algr, alg, alrk, algrk
5728 (define_insn "*add<mode>3_cconly2"
5729 [(set (reg CC_REGNUM)
5730 (compare (match_operand:GPR 1 "nonimmediate_operand" "%0,d,0,0")
5731 (neg:GPR (match_operand:GPR 2 "general_operand" "d,d,R,T"))))
5732 (clobber (match_scratch:GPR 0 "=d,d,d,d"))]
5733 "s390_match_ccmode(insn, CCLmode)"
5734 "@
5735 al<g>r\t%0,%2
5736 al<g>rk\t%0,%1,%2
5737 al<g>\t%0,%2
5738 al<y>\t%0,%2"
5739 [(set_attr "op_type" "RR<E>,RRF,RX<Y>,RXY")
5740 (set_attr "cpu_facility" "*,z196,*,longdisp")
5741 (set_attr "z10prop" "z10_super_E1,*,z10_super_E1,z10_super_E1")])
5742
5743 ; ahi, afi, aghi, agfi, asi, agsi
5744 (define_insn "*add<mode>3_imm_cc"
5745 [(set (reg CC_REGNUM)
5746 (compare (plus:GPR (match_operand:GPR 1 "nonimmediate_operand" " 0, d,0, 0")
5747 (match_operand:GPR 2 "const_int_operand" " K, K,Os,C"))
5748 (const_int 0)))
5749 (set (match_operand:GPR 0 "nonimmediate_operand" "=d, d,d, S")
5750 (plus:GPR (match_dup 1) (match_dup 2)))]
5751 "s390_match_ccmode (insn, CCAmode)
5752 && (CONST_OK_FOR_CONSTRAINT_P (INTVAL (operands[2]), 'K', \"K\")
5753 || (CONST_OK_FOR_CONSTRAINT_P (INTVAL (operands[2]), 'O', \"Os\")
5754 /* Avoid INT32_MIN on 32 bit. */
5755 && (!TARGET_ZARCH || INTVAL (operands[2]) != -0x7fffffff - 1)))"
5756 "@
5757 a<g>hi\t%0,%h2
5758 a<g>hik\t%0,%1,%h2
5759 a<g>fi\t%0,%2
5760 a<g>si\t%0,%c2"
5761 [(set_attr "op_type" "RI,RIE,RIL,SIY")
5762 (set_attr "cpu_facility" "*,z196,extimm,z10")
5763 (set_attr "z10prop" "z10_super_E1,*,z10_super_E1,z10_super_E1")])
5764
5765 ;
5766 ; add(tf|df|sf|td|dd)3 instruction pattern(s).
5767 ;
5768
5769 ; axbr, adbr, aebr, axb, adb, aeb, adtr, axtr
5770 ; FIXME: wfadb does not clobber cc
5771 (define_insn "add<mode>3"
5772 [(set (match_operand:FP 0 "register_operand" "=f,f,f,v")
5773 (plus:FP (match_operand:FP 1 "nonimmediate_operand" "%f,0,0,v")
5774 (match_operand:FP 2 "general_operand" "f,f,R,v")))
5775 (clobber (reg:CC CC_REGNUM))]
5776 "TARGET_HARD_FLOAT"
5777 "@
5778 a<xde>tr\t%0,%1,%2
5779 a<xde>br\t%0,%2
5780 a<xde>b\t%0,%2
5781 wfadb\t%v0,%v1,%v2"
5782 [(set_attr "op_type" "RRF,RRE,RXE,VRR")
5783 (set_attr "type" "fsimp<mode>")
5784 (set_attr "cpu_facility" "*,*,*,vx")
5785 (set_attr "enabled" "<nBFP>,<nDFP>,<DSF>,<DFDI>")])
5786
5787 ; axbr, adbr, aebr, axb, adb, aeb, adtr, axtr
5788 (define_insn "*add<mode>3_cc"
5789 [(set (reg CC_REGNUM)
5790 (compare (plus:FP (match_operand:FP 1 "nonimmediate_operand" "%f,0,0")
5791 (match_operand:FP 2 "general_operand" "f,f,R"))
5792 (match_operand:FP 3 "const0_operand" "")))
5793 (set (match_operand:FP 0 "register_operand" "=f,f,f")
5794 (plus:FP (match_dup 1) (match_dup 2)))]
5795 "s390_match_ccmode (insn, CCSmode) && TARGET_HARD_FLOAT"
5796 "@
5797 a<xde>tr\t%0,%1,%2
5798 a<xde>br\t%0,%2
5799 a<xde>b\t%0,%2"
5800 [(set_attr "op_type" "RRF,RRE,RXE")
5801 (set_attr "type" "fsimp<mode>")
5802 (set_attr "enabled" "<nBFP>,<nDFP>,<DSF>")])
5803
5804 ; axbr, adbr, aebr, axb, adb, aeb, adtr, axtr
5805 (define_insn "*add<mode>3_cconly"
5806 [(set (reg CC_REGNUM)
5807 (compare (plus:FP (match_operand:FP 1 "nonimmediate_operand" "%f,0,0")
5808 (match_operand:FP 2 "general_operand" "f,f,R"))
5809 (match_operand:FP 3 "const0_operand" "")))
5810 (clobber (match_scratch:FP 0 "=f,f,f"))]
5811 "s390_match_ccmode (insn, CCSmode) && TARGET_HARD_FLOAT"
5812 "@
5813 a<xde>tr\t%0,%1,%2
5814 a<xde>br\t%0,%2
5815 a<xde>b\t%0,%2"
5816 [(set_attr "op_type" "RRF,RRE,RXE")
5817 (set_attr "type" "fsimp<mode>")
5818 (set_attr "enabled" "<nBFP>,<nDFP>,<DSF>")])
5819
5820 ;
5821 ; Pointer add instruction patterns
5822 ;
5823
5824 ; This will match "*la_64"
5825 (define_expand "addptrdi3"
5826 [(set (match_operand:DI 0 "register_operand" "")
5827 (plus:DI (match_operand:DI 1 "register_operand" "")
5828 (match_operand:DI 2 "nonmemory_operand" "")))]
5829 "TARGET_64BIT"
5830 {
5831 if (GET_CODE (operands[2]) == CONST_INT)
5832 {
5833 HOST_WIDE_INT c = INTVAL (operands[2]);
5834
5835 if (!CONST_OK_FOR_CONSTRAINT_P (c, 'K', "K")
5836 && !CONST_OK_FOR_CONSTRAINT_P (c, 'O', "Os"))
5837 {
5838 operands[2] = force_const_mem (DImode, operands[2]);
5839 operands[2] = force_reg (DImode, operands[2]);
5840 }
5841 else if (!DISP_IN_RANGE (INTVAL (operands[2])))
5842 operands[2] = force_reg (DImode, operands[2]);
5843 }
5844 })
5845
5846 ; For 31 bit we have to prevent the generated pattern from matching
5847 ; normal ADDs since la only does a 31 bit add. This is supposed to
5848 ; match "force_la_31".
5849 (define_expand "addptrsi3"
5850 [(parallel
5851 [(set (match_operand:SI 0 "register_operand" "")
5852 (plus:SI (match_operand:SI 1 "register_operand" "")
5853 (match_operand:SI 2 "nonmemory_operand" "")))
5854 (use (const_int 0))])]
5855 "!TARGET_64BIT"
5856 {
5857 if (GET_CODE (operands[2]) == CONST_INT)
5858 {
5859 HOST_WIDE_INT c = INTVAL (operands[2]);
5860
5861 if (!CONST_OK_FOR_CONSTRAINT_P (c, 'K', "K")
5862 && !CONST_OK_FOR_CONSTRAINT_P (c, 'O', "Os"))
5863 {
5864 operands[2] = force_const_mem (SImode, operands[2]);
5865 operands[2] = force_reg (SImode, operands[2]);
5866 }
5867 else if (!DISP_IN_RANGE (INTVAL (operands[2])))
5868 operands[2] = force_reg (SImode, operands[2]);
5869 }
5870 })
5871
5872 ;;
5873 ;;- Subtract instructions.
5874 ;;
5875
5876 ;
5877 ; subti3 instruction pattern(s).
5878 ;
5879
5880 (define_expand "subti3"
5881 [(parallel
5882 [(set (match_operand:TI 0 "register_operand" "")
5883 (minus:TI (match_operand:TI 1 "register_operand" "")
5884 (match_operand:TI 2 "general_operand" "") ) )
5885 (clobber (reg:CC CC_REGNUM))])]
5886 "TARGET_ZARCH"
5887 {
5888 /* For z13 we have vsq which doesn't set CC. */
5889 if (TARGET_VX)
5890 {
5891 emit_insn (gen_rtx_SET (operands[0],
5892 gen_rtx_MINUS (TImode,
5893 operands[1],
5894 copy_to_mode_reg (TImode, operands[2]))));
5895 DONE;
5896 }
5897 })
5898
5899 (define_insn_and_split "*subti3"
5900 [(set (match_operand:TI 0 "register_operand" "=&d")
5901 (minus:TI (match_operand:TI 1 "register_operand" "0")
5902 (match_operand:TI 2 "general_operand" "do") ) )
5903 (clobber (reg:CC CC_REGNUM))]
5904 "TARGET_ZARCH"
5905 "#"
5906 "&& reload_completed"
5907 [(parallel
5908 [(set (reg:CCL2 CC_REGNUM)
5909 (compare:CCL2 (minus:DI (match_dup 7) (match_dup 8))
5910 (match_dup 7)))
5911 (set (match_dup 6) (minus:DI (match_dup 7) (match_dup 8)))])
5912 (parallel
5913 [(set (match_dup 3) (minus:DI (minus:DI (match_dup 4) (match_dup 5))
5914 (gtu:DI (reg:CCL2 CC_REGNUM) (const_int 0))))
5915 (clobber (reg:CC CC_REGNUM))])]
5916 "operands[3] = operand_subword (operands[0], 0, 0, TImode);
5917 operands[4] = operand_subword (operands[1], 0, 0, TImode);
5918 operands[5] = operand_subword (operands[2], 0, 0, TImode);
5919 operands[6] = operand_subword (operands[0], 1, 0, TImode);
5920 operands[7] = operand_subword (operands[1], 1, 0, TImode);
5921 operands[8] = operand_subword (operands[2], 1, 0, TImode);"
5922 [(set_attr "op_type" "*")
5923 (set_attr "cpu_facility" "*")])
5924
5925 ;
5926 ; subdi3 instruction pattern(s).
5927 ;
5928
5929 (define_expand "subdi3"
5930 [(parallel
5931 [(set (match_operand:DI 0 "register_operand" "")
5932 (minus:DI (match_operand:DI 1 "register_operand" "")
5933 (match_operand:DI 2 "general_operand" "")))
5934 (clobber (reg:CC CC_REGNUM))])]
5935 ""
5936 "")
5937
5938 (define_insn "*subdi3_sign"
5939 [(set (match_operand:DI 0 "register_operand" "=d,d")
5940 (minus:DI (match_operand:DI 1 "register_operand" "0,0")
5941 (sign_extend:DI (match_operand:SI 2 "general_operand" "d,T"))))
5942 (clobber (reg:CC CC_REGNUM))]
5943 "TARGET_ZARCH"
5944 "@
5945 sgfr\t%0,%2
5946 sgf\t%0,%2"
5947 [(set_attr "op_type" "RRE,RXY")
5948 (set_attr "z10prop" "z10_c,*")
5949 (set_attr "z196prop" "z196_cracked")])
5950
5951 (define_insn "*subdi3_zero_cc"
5952 [(set (reg CC_REGNUM)
5953 (compare (minus:DI (match_operand:DI 1 "register_operand" "0,0")
5954 (zero_extend:DI (match_operand:SI 2 "general_operand" "d,T")))
5955 (const_int 0)))
5956 (set (match_operand:DI 0 "register_operand" "=d,d")
5957 (minus:DI (match_dup 1) (zero_extend:DI (match_dup 2))))]
5958 "s390_match_ccmode (insn, CCLmode) && TARGET_ZARCH"
5959 "@
5960 slgfr\t%0,%2
5961 slgf\t%0,%2"
5962 [(set_attr "op_type" "RRE,RXY")
5963 (set_attr "z10prop" "z10_super_c_E1,z10_super_E1")])
5964
5965 (define_insn "*subdi3_zero_cconly"
5966 [(set (reg CC_REGNUM)
5967 (compare (minus:DI (match_operand:DI 1 "register_operand" "0,0")
5968 (zero_extend:DI (match_operand:SI 2 "general_operand" "d,T")))
5969 (const_int 0)))
5970 (clobber (match_scratch:DI 0 "=d,d"))]
5971 "s390_match_ccmode (insn, CCLmode) && TARGET_ZARCH"
5972 "@
5973 slgfr\t%0,%2
5974 slgf\t%0,%2"
5975 [(set_attr "op_type" "RRE,RXY")
5976 (set_attr "z10prop" "z10_super_c_E1,z10_super_E1")])
5977
5978 (define_insn "*subdi3_zero"
5979 [(set (match_operand:DI 0 "register_operand" "=d,d")
5980 (minus:DI (match_operand:DI 1 "register_operand" "0,0")
5981 (zero_extend:DI (match_operand:SI 2 "general_operand" "d,T"))))
5982 (clobber (reg:CC CC_REGNUM))]
5983 "TARGET_ZARCH"
5984 "@
5985 slgfr\t%0,%2
5986 slgf\t%0,%2"
5987 [(set_attr "op_type" "RRE,RXY")
5988 (set_attr "z10prop" "z10_super_c_E1,z10_super_E1")])
5989
5990 (define_insn_and_split "*subdi3_31z"
5991 [(set (match_operand:DI 0 "register_operand" "=&d")
5992 (minus:DI (match_operand:DI 1 "register_operand" "0")
5993 (match_operand:DI 2 "general_operand" "do") ) )
5994 (clobber (reg:CC CC_REGNUM))]
5995 "!TARGET_ZARCH && TARGET_CPU_ZARCH"
5996 "#"
5997 "&& reload_completed"
5998 [(parallel
5999 [(set (reg:CCL2 CC_REGNUM)
6000 (compare:CCL2 (minus:SI (match_dup 7) (match_dup 8))
6001 (match_dup 7)))
6002 (set (match_dup 6) (minus:SI (match_dup 7) (match_dup 8)))])
6003 (parallel
6004 [(set (match_dup 3) (minus:SI (minus:SI (match_dup 4) (match_dup 5))
6005 (gtu:SI (reg:CCL2 CC_REGNUM) (const_int 0))))
6006 (clobber (reg:CC CC_REGNUM))])]
6007 "operands[3] = operand_subword (operands[0], 0, 0, DImode);
6008 operands[4] = operand_subword (operands[1], 0, 0, DImode);
6009 operands[5] = operand_subword (operands[2], 0, 0, DImode);
6010 operands[6] = operand_subword (operands[0], 1, 0, DImode);
6011 operands[7] = operand_subword (operands[1], 1, 0, DImode);
6012 operands[8] = operand_subword (operands[2], 1, 0, DImode);")
6013
6014 (define_insn_and_split "*subdi3_31"
6015 [(set (match_operand:DI 0 "register_operand" "=&d")
6016 (minus:DI (match_operand:DI 1 "register_operand" "0")
6017 (match_operand:DI 2 "general_operand" "do") ) )
6018 (clobber (reg:CC CC_REGNUM))]
6019 "!TARGET_CPU_ZARCH"
6020 "#"
6021 "&& reload_completed"
6022 [(parallel
6023 [(set (match_dup 3) (minus:SI (match_dup 4) (match_dup 5)))
6024 (clobber (reg:CC CC_REGNUM))])
6025 (parallel
6026 [(set (reg:CCL2 CC_REGNUM)
6027 (compare:CCL2 (minus:SI (match_dup 7) (match_dup 8))
6028 (match_dup 7)))
6029 (set (match_dup 6) (minus:SI (match_dup 7) (match_dup 8)))])
6030 (set (pc)
6031 (if_then_else (gtu (reg:CCL2 CC_REGNUM) (const_int 0))
6032 (pc)
6033 (label_ref (match_dup 9))))
6034 (parallel
6035 [(set (match_dup 3) (plus:SI (match_dup 3) (const_int -1)))
6036 (clobber (reg:CC CC_REGNUM))])
6037 (match_dup 9)]
6038 "operands[3] = operand_subword (operands[0], 0, 0, DImode);
6039 operands[4] = operand_subword (operands[1], 0, 0, DImode);
6040 operands[5] = operand_subword (operands[2], 0, 0, DImode);
6041 operands[6] = operand_subword (operands[0], 1, 0, DImode);
6042 operands[7] = operand_subword (operands[1], 1, 0, DImode);
6043 operands[8] = operand_subword (operands[2], 1, 0, DImode);
6044 operands[9] = gen_label_rtx ();")
6045
6046 ;
6047 ; subsi3 instruction pattern(s).
6048 ;
6049
6050 (define_expand "subsi3"
6051 [(parallel
6052 [(set (match_operand:SI 0 "register_operand" "")
6053 (minus:SI (match_operand:SI 1 "register_operand" "")
6054 (match_operand:SI 2 "general_operand" "")))
6055 (clobber (reg:CC CC_REGNUM))])]
6056 ""
6057 "")
6058
6059 (define_insn "*subsi3_sign"
6060 [(set (match_operand:SI 0 "register_operand" "=d,d")
6061 (minus:SI (match_operand:SI 1 "register_operand" "0,0")
6062 (sign_extend:SI (match_operand:HI 2 "memory_operand" "R,T"))))
6063 (clobber (reg:CC CC_REGNUM))]
6064 ""
6065 "@
6066 sh\t%0,%2
6067 shy\t%0,%2"
6068 [(set_attr "op_type" "RX,RXY")
6069 (set_attr "cpu_facility" "*,longdisp")
6070 (set_attr "z196prop" "z196_cracked,z196_cracked")])
6071
6072 ;
6073 ; sub(di|si)3 instruction pattern(s).
6074 ;
6075
6076 ; sr, s, sy, sgr, sg, srk, sgrk
6077 (define_insn "*sub<mode>3"
6078 [(set (match_operand:GPR 0 "register_operand" "=d,d,d,d")
6079 (minus:GPR (match_operand:GPR 1 "register_operand" "0,d,0,0")
6080 (match_operand:GPR 2 "general_operand" "d,d,R,T") ) )
6081 (clobber (reg:CC CC_REGNUM))]
6082 ""
6083 "@
6084 s<g>r\t%0,%2
6085 s<g>rk\t%0,%1,%2
6086 s<g>\t%0,%2
6087 s<y>\t%0,%2"
6088 [(set_attr "op_type" "RR<E>,RRF,RX<Y>,RXY")
6089 (set_attr "cpu_facility" "*,z196,*,longdisp")
6090 (set_attr "z10prop" "z10_super_c_E1,*,z10_super_E1,z10_super_E1")])
6091
6092 ; slr, sl, sly, slgr, slg, slrk, slgrk
6093 (define_insn "*sub<mode>3_borrow_cc"
6094 [(set (reg CC_REGNUM)
6095 (compare (minus:GPR (match_operand:GPR 1 "register_operand" "0,d,0,0")
6096 (match_operand:GPR 2 "general_operand" "d,d,R,T"))
6097 (match_dup 1)))
6098 (set (match_operand:GPR 0 "register_operand" "=d,d,d,d")
6099 (minus:GPR (match_dup 1) (match_dup 2)))]
6100 "s390_match_ccmode (insn, CCL2mode)"
6101 "@
6102 sl<g>r\t%0,%2
6103 sl<g>rk\t%0,%1,%2
6104 sl<g>\t%0,%2
6105 sl<y>\t%0,%2"
6106 [(set_attr "op_type" "RR<E>,RRF,RX<Y>,RXY")
6107 (set_attr "cpu_facility" "*,z196,*,longdisp")
6108 (set_attr "z10prop" "z10_super_c_E1,*,z10_super_E1,z10_super_E1")])
6109
6110 ; slr, sl, sly, slgr, slg, slrk, slgrk
6111 (define_insn "*sub<mode>3_borrow_cconly"
6112 [(set (reg CC_REGNUM)
6113 (compare (minus:GPR (match_operand:GPR 1 "register_operand" "0,d,0,0")
6114 (match_operand:GPR 2 "general_operand" "d,d,R,T"))
6115 (match_dup 1)))
6116 (clobber (match_scratch:GPR 0 "=d,d,d,d"))]
6117 "s390_match_ccmode (insn, CCL2mode)"
6118 "@
6119 sl<g>r\t%0,%2
6120 sl<g>rk\t%0,%1,%2
6121 sl<g>\t%0,%2
6122 sl<y>\t%0,%2"
6123 [(set_attr "op_type" "RR<E>,RRF,RX<Y>,RXY")
6124 (set_attr "cpu_facility" "*,z196,*,longdisp")
6125 (set_attr "z10prop" "z10_super_c_E1,*,z10_super_E1,z10_super_E1")])
6126
6127 ; slr, sl, sly, slgr, slg, slrk, slgrk
6128 (define_insn "*sub<mode>3_cc"
6129 [(set (reg CC_REGNUM)
6130 (compare (minus:GPR (match_operand:GPR 1 "register_operand" "0,d,0,0")
6131 (match_operand:GPR 2 "general_operand" "d,d,R,T"))
6132 (const_int 0)))
6133 (set (match_operand:GPR 0 "register_operand" "=d,d,d,d")
6134 (minus:GPR (match_dup 1) (match_dup 2)))]
6135 "s390_match_ccmode (insn, CCLmode)"
6136 "@
6137 sl<g>r\t%0,%2
6138 sl<g>rk\t%0,%1,%2
6139 sl<g>\t%0,%2
6140 sl<y>\t%0,%2"
6141 [(set_attr "op_type" "RR<E>,RRF,RX<Y>,RXY")
6142 (set_attr "cpu_facility" "*,z196,*,longdisp")
6143 (set_attr "z10prop" "z10_super_c_E1,*,z10_super_E1,z10_super_E1")])
6144
6145 ; slr, sl, sly, slgr, slg, slrk, slgrk
6146 (define_insn "*sub<mode>3_cc2"
6147 [(set (reg CC_REGNUM)
6148 (compare (match_operand:GPR 1 "register_operand" "0,d,0,0")
6149 (match_operand:GPR 2 "general_operand" "d,d,R,T")))
6150 (set (match_operand:GPR 0 "register_operand" "=d,d,d,d")
6151 (minus:GPR (match_dup 1) (match_dup 2)))]
6152 "s390_match_ccmode (insn, CCL3mode)"
6153 "@
6154 sl<g>r\t%0,%2
6155 sl<g>rk\t%0,%1,%2
6156 sl<g>\t%0,%2
6157 sl<y>\t%0,%2"
6158 [(set_attr "op_type" "RR<E>,RRF,RX<Y>,RXY")
6159 (set_attr "cpu_facility" "*,z196,*,longdisp")
6160 (set_attr "z10prop" "z10_super_c_E1,*,z10_super_E1,z10_super_E1")])
6161
6162 ; slr, sl, sly, slgr, slg, slrk, slgrk
6163 (define_insn "*sub<mode>3_cconly"
6164 [(set (reg CC_REGNUM)
6165 (compare (minus:GPR (match_operand:GPR 1 "register_operand" "0,d,0,0")
6166 (match_operand:GPR 2 "general_operand" "d,d,R,T"))
6167 (const_int 0)))
6168 (clobber (match_scratch:GPR 0 "=d,d,d,d"))]
6169 "s390_match_ccmode (insn, CCLmode)"
6170 "@
6171 sl<g>r\t%0,%2
6172 sl<g>rk\t%0,%1,%2
6173 sl<g>\t%0,%2
6174 sl<y>\t%0,%2"
6175 [(set_attr "op_type" "RR<E>,RRF,RX<Y>,RXY")
6176 (set_attr "cpu_facility" "*,z196,*,longdisp")
6177 (set_attr "z10prop" "z10_super_c_E1,*,z10_super_E1,z10_super_E1")])
6178
6179
6180 ; slr, sl, sly, slgr, slg, slrk, slgrk
6181 (define_insn "*sub<mode>3_cconly2"
6182 [(set (reg CC_REGNUM)
6183 (compare (match_operand:GPR 1 "register_operand" "0,d,0,0")
6184 (match_operand:GPR 2 "general_operand" "d,d,R,T")))
6185 (clobber (match_scratch:GPR 0 "=d,d,d,d"))]
6186 "s390_match_ccmode (insn, CCL3mode)"
6187 "@
6188 sl<g>r\t%0,%2
6189 sl<g>rk\t%0,%1,%2
6190 sl<g>\t%0,%2
6191 sl<y>\t%0,%2"
6192 [(set_attr "op_type" "RR<E>,RRF,RX<Y>,RXY")
6193 (set_attr "cpu_facility" "*,z196,*,longdisp")
6194 (set_attr "z10prop" "z10_super_c_E1,*,z10_super_E1,z10_super_E1")])
6195
6196
6197 ;
6198 ; sub(tf|df|sf|td|dd)3 instruction pattern(s).
6199 ;
6200
6201 ; sxbr, sdbr, sebr, sdb, seb, sxtr, sdtr
6202 (define_insn "sub<mode>3"
6203 [(set (match_operand:FP 0 "register_operand" "=f,f,f,v")
6204 (minus:FP (match_operand:FP 1 "register_operand" "f,0,0,v")
6205 (match_operand:FP 2 "general_operand" "f,f,R,v")))
6206 (clobber (reg:CC CC_REGNUM))]
6207 "TARGET_HARD_FLOAT"
6208 "@
6209 s<xde>tr\t%0,%1,%2
6210 s<xde>br\t%0,%2
6211 s<xde>b\t%0,%2
6212 wfsdb\t%v0,%v1,%v2"
6213 [(set_attr "op_type" "RRF,RRE,RXE,VRR")
6214 (set_attr "type" "fsimp<mode>")
6215 (set_attr "cpu_facility" "*,*,*,vx")
6216 (set_attr "enabled" "<nBFP>,<nDFP>,<DSF>,<DFDI>")])
6217
6218 ; sxbr, sdbr, sebr, sdb, seb, sxtr, sdtr
6219 (define_insn "*sub<mode>3_cc"
6220 [(set (reg CC_REGNUM)
6221 (compare (minus:FP (match_operand:FP 1 "nonimmediate_operand" "f,0,0")
6222 (match_operand:FP 2 "general_operand" "f,f,R"))
6223 (match_operand:FP 3 "const0_operand" "")))
6224 (set (match_operand:FP 0 "register_operand" "=f,f,f")
6225 (minus:FP (match_dup 1) (match_dup 2)))]
6226 "s390_match_ccmode (insn, CCSmode) && TARGET_HARD_FLOAT"
6227 "@
6228 s<xde>tr\t%0,%1,%2
6229 s<xde>br\t%0,%2
6230 s<xde>b\t%0,%2"
6231 [(set_attr "op_type" "RRF,RRE,RXE")
6232 (set_attr "type" "fsimp<mode>")
6233 (set_attr "enabled" "<nBFP>,<nDFP>,<DSF>")])
6234
6235 ; sxbr, sdbr, sebr, sdb, seb, sxtr, sdtr
6236 (define_insn "*sub<mode>3_cconly"
6237 [(set (reg CC_REGNUM)
6238 (compare (minus:FP (match_operand:FP 1 "nonimmediate_operand" "f,0,0")
6239 (match_operand:FP 2 "general_operand" "f,f,R"))
6240 (match_operand:FP 3 "const0_operand" "")))
6241 (clobber (match_scratch:FP 0 "=f,f,f"))]
6242 "s390_match_ccmode (insn, CCSmode) && TARGET_HARD_FLOAT"
6243 "@
6244 s<xde>tr\t%0,%1,%2
6245 s<xde>br\t%0,%2
6246 s<xde>b\t%0,%2"
6247 [(set_attr "op_type" "RRF,RRE,RXE")
6248 (set_attr "type" "fsimp<mode>")
6249 (set_attr "enabled" "<nBFP>,<nDFP>,<DSF>")])
6250
6251
6252 ;;
6253 ;;- Conditional add/subtract instructions.
6254 ;;
6255
6256 ;
6257 ; add(di|si)cc instruction pattern(s).
6258 ;
6259
6260 ; the following 4 patterns are used when the result of an add with
6261 ; carry is checked for an overflow condition
6262
6263 ; op1 + op2 + c < op1
6264
6265 ; alcr, alc, alcgr, alcg
6266 (define_insn "*add<mode>3_alc_carry1_cc"
6267 [(set (reg CC_REGNUM)
6268 (compare
6269 (plus:GPR (plus:GPR (match_operand:GPR 3 "s390_alc_comparison" "")
6270 (match_operand:GPR 1 "nonimmediate_operand" "%0,0"))
6271 (match_operand:GPR 2 "general_operand" "d,T"))
6272 (match_dup 1)))
6273 (set (match_operand:GPR 0 "register_operand" "=d,d")
6274 (plus:GPR (plus:GPR (match_dup 3) (match_dup 1)) (match_dup 2)))]
6275 "s390_match_ccmode (insn, CCL1mode) && TARGET_CPU_ZARCH"
6276 "@
6277 alc<g>r\t%0,%2
6278 alc<g>\t%0,%2"
6279 [(set_attr "op_type" "RRE,RXY")
6280 (set_attr "z196prop" "z196_alone,z196_alone")])
6281
6282 ; alcr, alc, alcgr, alcg
6283 (define_insn "*add<mode>3_alc_carry1_cconly"
6284 [(set (reg CC_REGNUM)
6285 (compare
6286 (plus:GPR (plus:GPR (match_operand:GPR 3 "s390_alc_comparison" "")
6287 (match_operand:GPR 1 "nonimmediate_operand" "%0,0"))
6288 (match_operand:GPR 2 "general_operand" "d,T"))
6289 (match_dup 1)))
6290 (clobber (match_scratch:GPR 0 "=d,d"))]
6291 "s390_match_ccmode (insn, CCL1mode) && TARGET_CPU_ZARCH"
6292 "@
6293 alc<g>r\t%0,%2
6294 alc<g>\t%0,%2"
6295 [(set_attr "op_type" "RRE,RXY")
6296 (set_attr "z196prop" "z196_alone,z196_alone")])
6297
6298 ; op1 + op2 + c < op2
6299
6300 ; alcr, alc, alcgr, alcg
6301 (define_insn "*add<mode>3_alc_carry2_cc"
6302 [(set (reg CC_REGNUM)
6303 (compare
6304 (plus:GPR (plus:GPR (match_operand:GPR 3 "s390_alc_comparison" "")
6305 (match_operand:GPR 1 "nonimmediate_operand" "%0,0"))
6306 (match_operand:GPR 2 "general_operand" "d,T"))
6307 (match_dup 2)))
6308 (set (match_operand:GPR 0 "register_operand" "=d,d")
6309 (plus:GPR (plus:GPR (match_dup 3) (match_dup 1)) (match_dup 2)))]
6310 "s390_match_ccmode (insn, CCL1mode) && TARGET_CPU_ZARCH"
6311 "@
6312 alc<g>r\t%0,%2
6313 alc<g>\t%0,%2"
6314 [(set_attr "op_type" "RRE,RXY")])
6315
6316 ; alcr, alc, alcgr, alcg
6317 (define_insn "*add<mode>3_alc_carry2_cconly"
6318 [(set (reg CC_REGNUM)
6319 (compare
6320 (plus:GPR (plus:GPR (match_operand:GPR 3 "s390_alc_comparison" "")
6321 (match_operand:GPR 1 "nonimmediate_operand" "%0,0"))
6322 (match_operand:GPR 2 "general_operand" "d,T"))
6323 (match_dup 2)))
6324 (clobber (match_scratch:GPR 0 "=d,d"))]
6325 "s390_match_ccmode (insn, CCL1mode) && TARGET_CPU_ZARCH"
6326 "@
6327 alc<g>r\t%0,%2
6328 alc<g>\t%0,%2"
6329 [(set_attr "op_type" "RRE,RXY")])
6330
6331 ; alcr, alc, alcgr, alcg
6332 (define_insn "*add<mode>3_alc_cc"
6333 [(set (reg CC_REGNUM)
6334 (compare
6335 (plus:GPR (plus:GPR (match_operand:GPR 3 "s390_alc_comparison" "")
6336 (match_operand:GPR 1 "nonimmediate_operand" "%0,0"))
6337 (match_operand:GPR 2 "general_operand" "d,T"))
6338 (const_int 0)))
6339 (set (match_operand:GPR 0 "register_operand" "=d,d")
6340 (plus:GPR (plus:GPR (match_dup 3) (match_dup 1)) (match_dup 2)))]
6341 "s390_match_ccmode (insn, CCLmode) && TARGET_CPU_ZARCH"
6342 "@
6343 alc<g>r\t%0,%2
6344 alc<g>\t%0,%2"
6345 [(set_attr "op_type" "RRE,RXY")])
6346
6347 ; alcr, alc, alcgr, alcg
6348 (define_insn "*add<mode>3_alc"
6349 [(set (match_operand:GPR 0 "register_operand" "=d,d")
6350 (plus:GPR (plus:GPR (match_operand:GPR 3 "s390_alc_comparison" "")
6351 (match_operand:GPR 1 "nonimmediate_operand" "%0,0"))
6352 (match_operand:GPR 2 "general_operand" "d,T")))
6353 (clobber (reg:CC CC_REGNUM))]
6354 "TARGET_CPU_ZARCH"
6355 "@
6356 alc<g>r\t%0,%2
6357 alc<g>\t%0,%2"
6358 [(set_attr "op_type" "RRE,RXY")])
6359
6360 ; slbr, slb, slbgr, slbg
6361 (define_insn "*sub<mode>3_slb_cc"
6362 [(set (reg CC_REGNUM)
6363 (compare
6364 (minus:GPR (minus:GPR (match_operand:GPR 1 "nonimmediate_operand" "0,0")
6365 (match_operand:GPR 2 "general_operand" "d,T"))
6366 (match_operand:GPR 3 "s390_slb_comparison" ""))
6367 (const_int 0)))
6368 (set (match_operand:GPR 0 "register_operand" "=d,d")
6369 (minus:GPR (minus:GPR (match_dup 1) (match_dup 2)) (match_dup 3)))]
6370 "s390_match_ccmode (insn, CCLmode) && TARGET_CPU_ZARCH"
6371 "@
6372 slb<g>r\t%0,%2
6373 slb<g>\t%0,%2"
6374 [(set_attr "op_type" "RRE,RXY")
6375 (set_attr "z10prop" "z10_c,*")])
6376
6377 ; slbr, slb, slbgr, slbg
6378 (define_insn "*sub<mode>3_slb"
6379 [(set (match_operand:GPR 0 "register_operand" "=d,d")
6380 (minus:GPR (minus:GPR (match_operand:GPR 1 "nonimmediate_operand" "0,0")
6381 (match_operand:GPR 2 "general_operand" "d,T"))
6382 (match_operand:GPR 3 "s390_slb_comparison" "")))
6383 (clobber (reg:CC CC_REGNUM))]
6384 "TARGET_CPU_ZARCH"
6385 "@
6386 slb<g>r\t%0,%2
6387 slb<g>\t%0,%2"
6388 [(set_attr "op_type" "RRE,RXY")
6389 (set_attr "z10prop" "z10_c,*")])
6390
6391 (define_expand "add<mode>cc"
6392 [(match_operand:GPR 0 "register_operand" "")
6393 (match_operand 1 "comparison_operator" "")
6394 (match_operand:GPR 2 "register_operand" "")
6395 (match_operand:GPR 3 "const_int_operand" "")]
6396 "TARGET_CPU_ZARCH"
6397 "if (!s390_expand_addcc (GET_CODE (operands[1]),
6398 XEXP (operands[1], 0), XEXP (operands[1], 1),
6399 operands[0], operands[2],
6400 operands[3])) FAIL; DONE;")
6401
6402 ;
6403 ; scond instruction pattern(s).
6404 ;
6405
6406 (define_insn_and_split "*scond<mode>"
6407 [(set (match_operand:GPR 0 "register_operand" "=&d")
6408 (match_operand:GPR 1 "s390_alc_comparison" ""))
6409 (clobber (reg:CC CC_REGNUM))]
6410 "TARGET_CPU_ZARCH"
6411 "#"
6412 "&& reload_completed"
6413 [(set (match_dup 0) (const_int 0))
6414 (parallel
6415 [(set (match_dup 0) (plus:GPR (plus:GPR (match_dup 1) (match_dup 0))
6416 (match_dup 0)))
6417 (clobber (reg:CC CC_REGNUM))])]
6418 "")
6419
6420 (define_insn_and_split "*scond<mode>_neg"
6421 [(set (match_operand:GPR 0 "register_operand" "=&d")
6422 (match_operand:GPR 1 "s390_slb_comparison" ""))
6423 (clobber (reg:CC CC_REGNUM))]
6424 "TARGET_CPU_ZARCH"
6425 "#"
6426 "&& reload_completed"
6427 [(set (match_dup 0) (const_int 0))
6428 (parallel
6429 [(set (match_dup 0) (minus:GPR (minus:GPR (match_dup 0) (match_dup 0))
6430 (match_dup 1)))
6431 (clobber (reg:CC CC_REGNUM))])
6432 (parallel
6433 [(set (match_dup 0) (neg:GPR (match_dup 0)))
6434 (clobber (reg:CC CC_REGNUM))])]
6435 "")
6436
6437
6438 (define_expand "cstore<mode>4"
6439 [(set (match_operand:SI 0 "register_operand" "")
6440 (match_operator:SI 1 "s390_scond_operator"
6441 [(match_operand:GPR 2 "register_operand" "")
6442 (match_operand:GPR 3 "general_operand" "")]))]
6443 "TARGET_CPU_ZARCH"
6444 "if (!s390_expand_addcc (GET_CODE (operands[1]), operands[2], operands[3],
6445 operands[0], const0_rtx, const1_rtx)) FAIL; DONE;")
6446
6447 (define_expand "cstorecc4"
6448 [(parallel
6449 [(set (match_operand:SI 0 "register_operand" "")
6450 (match_operator:SI 1 "s390_eqne_operator"
6451 [(match_operand:CCZ1 2 "register_operand")
6452 (match_operand 3 "const0_operand")]))
6453 (clobber (reg:CC CC_REGNUM))])]
6454 ""
6455 "emit_insn (gen_sne (operands[0], operands[2]));
6456 if (GET_CODE (operands[1]) == EQ)
6457 emit_insn (gen_xorsi3 (operands[0], operands[0], const1_rtx));
6458 DONE;")
6459
6460 (define_insn_and_split "sne"
6461 [(set (match_operand:SI 0 "register_operand" "=d")
6462 (ne:SI (match_operand:CCZ1 1 "register_operand" "0")
6463 (const_int 0)))
6464 (clobber (reg:CC CC_REGNUM))]
6465 ""
6466 "#"
6467 "reload_completed"
6468 [(parallel
6469 [(set (match_dup 0) (ashiftrt:SI (match_dup 0) (const_int 28)))
6470 (clobber (reg:CC CC_REGNUM))])])
6471
6472
6473 ;;
6474 ;; - Conditional move instructions (introduced with z196)
6475 ;;
6476
6477 (define_expand "mov<mode>cc"
6478 [(set (match_operand:GPR 0 "nonimmediate_operand" "")
6479 (if_then_else:GPR (match_operand 1 "comparison_operator" "")
6480 (match_operand:GPR 2 "nonimmediate_operand" "")
6481 (match_operand:GPR 3 "nonimmediate_operand" "")))]
6482 "TARGET_Z196"
6483 {
6484 /* Emit the comparison insn in case we do not already have a comparison result. */
6485 if (!s390_comparison (operands[1], VOIDmode))
6486 operands[1] = s390_emit_compare (GET_CODE (operands[1]),
6487 XEXP (operands[1], 0),
6488 XEXP (operands[1], 1));
6489 })
6490
6491 ; locr, loc, stoc, locgr, locg, stocg, lochi, locghi
6492 (define_insn_and_split "*mov<mode>cc"
6493 [(set (match_operand:GPR 0 "nonimmediate_operand" "=d,d,d,d,d,d,S,S,&d")
6494 (if_then_else:GPR
6495 (match_operator 1 "s390_comparison"
6496 [(match_operand 2 "cc_reg_operand" " c,c,c,c,c,c,c,c,c")
6497 (match_operand 5 "const_int_operand" "")])
6498 (match_operand:GPR 3 "loc_operand" " d,0,S,0,K,0,d,0,S")
6499 (match_operand:GPR 4 "loc_operand" " 0,d,0,S,0,K,0,d,S")))]
6500 "TARGET_Z196"
6501 "@
6502 loc<g>r%C1\t%0,%3
6503 loc<g>r%D1\t%0,%4
6504 loc<g>%C1\t%0,%3
6505 loc<g>%D1\t%0,%4
6506 loc<g>hi%C1\t%0,%h3
6507 loc<g>hi%D1\t%0,%h4
6508 stoc<g>%C1\t%3,%0
6509 stoc<g>%D1\t%4,%0
6510 #"
6511 "&& reload_completed
6512 && MEM_P (operands[3]) && MEM_P (operands[4])"
6513 [(set (match_dup 0)
6514 (if_then_else:GPR
6515 (match_op_dup 1 [(match_dup 2) (const_int 0)])
6516 (match_dup 3)
6517 (match_dup 0)))
6518 (set (match_dup 0)
6519 (if_then_else:GPR
6520 (match_op_dup 1 [(match_dup 2) (const_int 0)])
6521 (match_dup 0)
6522 (match_dup 4)))]
6523 ""
6524 [(set_attr "op_type" "RRF,RRF,RSY,RSY,RIE,RIE,RSY,RSY,*")
6525 (set_attr "cpu_facility" "*,*,*,*,z13,z13,*,*,*")])
6526
6527 ;;
6528 ;;- Multiply instructions.
6529 ;;
6530
6531 ;
6532 ; muldi3 instruction pattern(s).
6533 ;
6534
6535 (define_insn "*muldi3_sign"
6536 [(set (match_operand:DI 0 "register_operand" "=d,d")
6537 (mult:DI (sign_extend:DI (match_operand:SI 2 "general_operand" "d,T"))
6538 (match_operand:DI 1 "register_operand" "0,0")))]
6539 "TARGET_ZARCH"
6540 "@
6541 msgfr\t%0,%2
6542 msgf\t%0,%2"
6543 [(set_attr "op_type" "RRE,RXY")
6544 (set_attr "type" "imuldi")])
6545
6546 (define_insn "muldi3"
6547 [(set (match_operand:DI 0 "register_operand" "=d,d,d,d")
6548 (mult:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,0")
6549 (match_operand:DI 2 "general_operand" "d,K,T,Os")))]
6550 "TARGET_ZARCH"
6551 "@
6552 msgr\t%0,%2
6553 mghi\t%0,%h2
6554 msg\t%0,%2
6555 msgfi\t%0,%2"
6556 [(set_attr "op_type" "RRE,RI,RXY,RIL")
6557 (set_attr "type" "imuldi")
6558 (set_attr "cpu_facility" "*,*,*,z10")])
6559
6560 ;
6561 ; mulsi3 instruction pattern(s).
6562 ;
6563
6564 (define_insn "*mulsi3_sign"
6565 [(set (match_operand:SI 0 "register_operand" "=d,d")
6566 (mult:SI (sign_extend:SI (match_operand:HI 2 "memory_operand" "R,T"))
6567 (match_operand:SI 1 "register_operand" "0,0")))]
6568 ""
6569 "@
6570 mh\t%0,%2
6571 mhy\t%0,%2"
6572 [(set_attr "op_type" "RX,RXY")
6573 (set_attr "type" "imulhi")
6574 (set_attr "cpu_facility" "*,z10")])
6575
6576 (define_insn "mulsi3"
6577 [(set (match_operand:SI 0 "register_operand" "=d,d,d,d,d")
6578 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,0,0,0")
6579 (match_operand:SI 2 "general_operand" "d,K,R,T,Os")))]
6580 ""
6581 "@
6582 msr\t%0,%2
6583 mhi\t%0,%h2
6584 ms\t%0,%2
6585 msy\t%0,%2
6586 msfi\t%0,%2"
6587 [(set_attr "op_type" "RRE,RI,RX,RXY,RIL")
6588 (set_attr "type" "imulsi,imulhi,imulsi,imulsi,imulsi")
6589 (set_attr "cpu_facility" "*,*,*,longdisp,z10")])
6590
6591 ;
6592 ; mulsidi3 instruction pattern(s).
6593 ;
6594
6595 (define_insn "mulsidi3"
6596 [(set (match_operand:DI 0 "register_operand" "=d,d,d")
6597 (mult:DI (sign_extend:DI
6598 (match_operand:SI 1 "register_operand" "%0,0,0"))
6599 (sign_extend:DI
6600 (match_operand:SI 2 "nonimmediate_operand" "d,R,T"))))]
6601 "!TARGET_ZARCH"
6602 "@
6603 mr\t%0,%2
6604 m\t%0,%2
6605 mfy\t%0,%2"
6606 [(set_attr "op_type" "RR,RX,RXY")
6607 (set_attr "type" "imulsi")
6608 (set_attr "cpu_facility" "*,*,z10")])
6609
6610 ;
6611 ; umul instruction pattern(s).
6612 ;
6613
6614 ; mlr, ml, mlgr, mlg
6615 (define_insn "umul<dwh><mode>3"
6616 [(set (match_operand:DW 0 "register_operand" "=d,d")
6617 (mult:DW (zero_extend:DW
6618 (match_operand:<DWH> 1 "register_operand" "%0,0"))
6619 (zero_extend:DW
6620 (match_operand:<DWH> 2 "nonimmediate_operand" " d,T"))))]
6621 "TARGET_CPU_ZARCH"
6622 "@
6623 ml<tg>r\t%0,%2
6624 ml<tg>\t%0,%2"
6625 [(set_attr "op_type" "RRE,RXY")
6626 (set_attr "type" "imul<dwh>")])
6627
6628 ;
6629 ; mul(tf|df|sf|td|dd)3 instruction pattern(s).
6630 ;
6631
6632 ; mxbr, mdbr, meebr, mxb, mxb, meeb, mdtr, mxtr
6633 (define_insn "mul<mode>3"
6634 [(set (match_operand:FP 0 "register_operand" "=f,f,f,v")
6635 (mult:FP (match_operand:FP 1 "nonimmediate_operand" "%f,0,0,v")
6636 (match_operand:FP 2 "general_operand" "f,f,R,v")))]
6637 "TARGET_HARD_FLOAT"
6638 "@
6639 m<xdee>tr\t%0,%1,%2
6640 m<xdee>br\t%0,%2
6641 m<xdee>b\t%0,%2
6642 wfmdb\t%v0,%v1,%v2"
6643 [(set_attr "op_type" "RRF,RRE,RXE,VRR")
6644 (set_attr "type" "fmul<mode>")
6645 (set_attr "cpu_facility" "*,*,*,vx")
6646 (set_attr "enabled" "<nBFP>,<nDFP>,<DSF>,<DFDI>")])
6647
6648 ; madbr, maebr, maxb, madb, maeb
6649 (define_insn "fma<mode>4"
6650 [(set (match_operand:DSF 0 "register_operand" "=f,f,v")
6651 (fma:DSF (match_operand:DSF 1 "nonimmediate_operand" "%f,f,v")
6652 (match_operand:DSF 2 "nonimmediate_operand" "f,R,v")
6653 (match_operand:DSF 3 "register_operand" "0,0,v")))]
6654 "TARGET_HARD_FLOAT"
6655 "@
6656 ma<xde>br\t%0,%1,%2
6657 ma<xde>b\t%0,%1,%2
6658 wfmadb\t%v0,%v1,%v2,%v3"
6659 [(set_attr "op_type" "RRE,RXE,VRR")
6660 (set_attr "type" "fmadd<mode>")
6661 (set_attr "cpu_facility" "*,*,vx")
6662 (set_attr "enabled" "*,*,<DFDI>")])
6663
6664 ; msxbr, msdbr, msebr, msxb, msdb, mseb
6665 (define_insn "fms<mode>4"
6666 [(set (match_operand:DSF 0 "register_operand" "=f,f,v")
6667 (fma:DSF (match_operand:DSF 1 "nonimmediate_operand" "%f,f,v")
6668 (match_operand:DSF 2 "nonimmediate_operand" "f,R,v")
6669 (neg:DSF (match_operand:DSF 3 "register_operand" "0,0,v"))))]
6670 "TARGET_HARD_FLOAT"
6671 "@
6672 ms<xde>br\t%0,%1,%2
6673 ms<xde>b\t%0,%1,%2
6674 wfmsdb\t%v0,%v1,%v2,%v3"
6675 [(set_attr "op_type" "RRE,RXE,VRR")
6676 (set_attr "type" "fmadd<mode>")
6677 (set_attr "cpu_facility" "*,*,vx")
6678 (set_attr "enabled" "*,*,<DFDI>")])
6679
6680 ;;
6681 ;;- Divide and modulo instructions.
6682 ;;
6683
6684 ;
6685 ; divmoddi4 instruction pattern(s).
6686 ;
6687
6688 (define_expand "divmoddi4"
6689 [(parallel [(set (match_operand:DI 0 "general_operand" "")
6690 (div:DI (match_operand:DI 1 "register_operand" "")
6691 (match_operand:DI 2 "general_operand" "")))
6692 (set (match_operand:DI 3 "general_operand" "")
6693 (mod:DI (match_dup 1) (match_dup 2)))])
6694 (clobber (match_dup 4))]
6695 "TARGET_ZARCH"
6696 {
6697 rtx div_equal, mod_equal;
6698 rtx_insn *insn;
6699
6700 div_equal = gen_rtx_DIV (DImode, operands[1], operands[2]);
6701 mod_equal = gen_rtx_MOD (DImode, operands[1], operands[2]);
6702
6703 operands[4] = gen_reg_rtx(TImode);
6704 emit_insn (gen_divmodtidi3 (operands[4], operands[1], operands[2]));
6705
6706 insn = emit_move_insn (operands[0], gen_lowpart (DImode, operands[4]));
6707 set_unique_reg_note (insn, REG_EQUAL, div_equal);
6708
6709 insn = emit_move_insn (operands[3], gen_highpart (DImode, operands[4]));
6710 set_unique_reg_note (insn, REG_EQUAL, mod_equal);
6711
6712 DONE;
6713 })
6714
6715 (define_insn "divmodtidi3"
6716 [(set (match_operand:TI 0 "register_operand" "=d,d")
6717 (ior:TI
6718 (ashift:TI
6719 (zero_extend:TI
6720 (mod:DI (match_operand:DI 1 "register_operand" "0,0")
6721 (match_operand:DI 2 "general_operand" "d,T")))
6722 (const_int 64))
6723 (zero_extend:TI (div:DI (match_dup 1) (match_dup 2)))))]
6724 "TARGET_ZARCH"
6725 "@
6726 dsgr\t%0,%2
6727 dsg\t%0,%2"
6728 [(set_attr "op_type" "RRE,RXY")
6729 (set_attr "type" "idiv")])
6730
6731 (define_insn "divmodtisi3"
6732 [(set (match_operand:TI 0 "register_operand" "=d,d")
6733 (ior:TI
6734 (ashift:TI
6735 (zero_extend:TI
6736 (mod:DI (match_operand:DI 1 "register_operand" "0,0")
6737 (sign_extend:DI
6738 (match_operand:SI 2 "nonimmediate_operand" "d,T"))))
6739 (const_int 64))
6740 (zero_extend:TI
6741 (div:DI (match_dup 1) (sign_extend:DI (match_dup 2))))))]
6742 "TARGET_ZARCH"
6743 "@
6744 dsgfr\t%0,%2
6745 dsgf\t%0,%2"
6746 [(set_attr "op_type" "RRE,RXY")
6747 (set_attr "type" "idiv")])
6748
6749 ;
6750 ; udivmoddi4 instruction pattern(s).
6751 ;
6752
6753 (define_expand "udivmoddi4"
6754 [(parallel [(set (match_operand:DI 0 "general_operand" "")
6755 (udiv:DI (match_operand:DI 1 "general_operand" "")
6756 (match_operand:DI 2 "nonimmediate_operand" "")))
6757 (set (match_operand:DI 3 "general_operand" "")
6758 (umod:DI (match_dup 1) (match_dup 2)))])
6759 (clobber (match_dup 4))]
6760 "TARGET_ZARCH"
6761 {
6762 rtx div_equal, mod_equal, equal;
6763 rtx_insn *insn;
6764
6765 div_equal = gen_rtx_UDIV (DImode, operands[1], operands[2]);
6766 mod_equal = gen_rtx_UMOD (DImode, operands[1], operands[2]);
6767 equal = gen_rtx_IOR (TImode,
6768 gen_rtx_ASHIFT (TImode,
6769 gen_rtx_ZERO_EXTEND (TImode, mod_equal),
6770 GEN_INT (64)),
6771 gen_rtx_ZERO_EXTEND (TImode, div_equal));
6772
6773 operands[4] = gen_reg_rtx(TImode);
6774 emit_clobber (operands[4]);
6775 emit_move_insn (gen_lowpart (DImode, operands[4]), operands[1]);
6776 emit_move_insn (gen_highpart (DImode, operands[4]), const0_rtx);
6777
6778 insn = emit_insn (gen_udivmodtidi3 (operands[4], operands[4], operands[2]));
6779 set_unique_reg_note (insn, REG_EQUAL, equal);
6780
6781 insn = emit_move_insn (operands[0], gen_lowpart (DImode, operands[4]));
6782 set_unique_reg_note (insn, REG_EQUAL, div_equal);
6783
6784 insn = emit_move_insn (operands[3], gen_highpart (DImode, operands[4]));
6785 set_unique_reg_note (insn, REG_EQUAL, mod_equal);
6786
6787 DONE;
6788 })
6789
6790 (define_insn "udivmodtidi3"
6791 [(set (match_operand:TI 0 "register_operand" "=d,d")
6792 (ior:TI
6793 (ashift:TI
6794 (zero_extend:TI
6795 (truncate:DI
6796 (umod:TI (match_operand:TI 1 "register_operand" "0,0")
6797 (zero_extend:TI
6798 (match_operand:DI 2 "nonimmediate_operand" "d,T")))))
6799 (const_int 64))
6800 (zero_extend:TI
6801 (truncate:DI
6802 (udiv:TI (match_dup 1) (zero_extend:TI (match_dup 2)))))))]
6803 "TARGET_ZARCH"
6804 "@
6805 dlgr\t%0,%2
6806 dlg\t%0,%2"
6807 [(set_attr "op_type" "RRE,RXY")
6808 (set_attr "type" "idiv")])
6809
6810 ;
6811 ; divmodsi4 instruction pattern(s).
6812 ;
6813
6814 (define_expand "divmodsi4"
6815 [(parallel [(set (match_operand:SI 0 "general_operand" "")
6816 (div:SI (match_operand:SI 1 "general_operand" "")
6817 (match_operand:SI 2 "nonimmediate_operand" "")))
6818 (set (match_operand:SI 3 "general_operand" "")
6819 (mod:SI (match_dup 1) (match_dup 2)))])
6820 (clobber (match_dup 4))]
6821 "!TARGET_ZARCH"
6822 {
6823 rtx div_equal, mod_equal, equal;
6824 rtx_insn *insn;
6825
6826 div_equal = gen_rtx_DIV (SImode, operands[1], operands[2]);
6827 mod_equal = gen_rtx_MOD (SImode, operands[1], operands[2]);
6828 equal = gen_rtx_IOR (DImode,
6829 gen_rtx_ASHIFT (DImode,
6830 gen_rtx_ZERO_EXTEND (DImode, mod_equal),
6831 GEN_INT (32)),
6832 gen_rtx_ZERO_EXTEND (DImode, div_equal));
6833
6834 operands[4] = gen_reg_rtx(DImode);
6835 emit_insn (gen_extendsidi2 (operands[4], operands[1]));
6836
6837 insn = emit_insn (gen_divmoddisi3 (operands[4], operands[4], operands[2]));
6838 set_unique_reg_note (insn, REG_EQUAL, equal);
6839
6840 insn = emit_move_insn (operands[0], gen_lowpart (SImode, operands[4]));
6841 set_unique_reg_note (insn, REG_EQUAL, div_equal);
6842
6843 insn = emit_move_insn (operands[3], gen_highpart (SImode, operands[4]));
6844 set_unique_reg_note (insn, REG_EQUAL, mod_equal);
6845
6846 DONE;
6847 })
6848
6849 (define_insn "divmoddisi3"
6850 [(set (match_operand:DI 0 "register_operand" "=d,d")
6851 (ior:DI
6852 (ashift:DI
6853 (zero_extend:DI
6854 (truncate:SI
6855 (mod:DI (match_operand:DI 1 "register_operand" "0,0")
6856 (sign_extend:DI
6857 (match_operand:SI 2 "nonimmediate_operand" "d,R")))))
6858 (const_int 32))
6859 (zero_extend:DI
6860 (truncate:SI
6861 (div:DI (match_dup 1) (sign_extend:DI (match_dup 2)))))))]
6862 "!TARGET_ZARCH"
6863 "@
6864 dr\t%0,%2
6865 d\t%0,%2"
6866 [(set_attr "op_type" "RR,RX")
6867 (set_attr "type" "idiv")])
6868
6869 ;
6870 ; udivsi3 and umodsi3 instruction pattern(s).
6871 ;
6872
6873 (define_expand "udivmodsi4"
6874 [(parallel [(set (match_operand:SI 0 "general_operand" "")
6875 (udiv:SI (match_operand:SI 1 "general_operand" "")
6876 (match_operand:SI 2 "nonimmediate_operand" "")))
6877 (set (match_operand:SI 3 "general_operand" "")
6878 (umod:SI (match_dup 1) (match_dup 2)))])
6879 (clobber (match_dup 4))]
6880 "!TARGET_ZARCH && TARGET_CPU_ZARCH"
6881 {
6882 rtx div_equal, mod_equal, equal;
6883 rtx_insn *insn;
6884
6885 div_equal = gen_rtx_UDIV (SImode, operands[1], operands[2]);
6886 mod_equal = gen_rtx_UMOD (SImode, operands[1], operands[2]);
6887 equal = gen_rtx_IOR (DImode,
6888 gen_rtx_ASHIFT (DImode,
6889 gen_rtx_ZERO_EXTEND (DImode, mod_equal),
6890 GEN_INT (32)),
6891 gen_rtx_ZERO_EXTEND (DImode, div_equal));
6892
6893 operands[4] = gen_reg_rtx(DImode);
6894 emit_clobber (operands[4]);
6895 emit_move_insn (gen_lowpart (SImode, operands[4]), operands[1]);
6896 emit_move_insn (gen_highpart (SImode, operands[4]), const0_rtx);
6897
6898 insn = emit_insn (gen_udivmoddisi3 (operands[4], operands[4], operands[2]));
6899 set_unique_reg_note (insn, REG_EQUAL, equal);
6900
6901 insn = emit_move_insn (operands[0], gen_lowpart (SImode, operands[4]));
6902 set_unique_reg_note (insn, REG_EQUAL, div_equal);
6903
6904 insn = emit_move_insn (operands[3], gen_highpart (SImode, operands[4]));
6905 set_unique_reg_note (insn, REG_EQUAL, mod_equal);
6906
6907 DONE;
6908 })
6909
6910 (define_insn "udivmoddisi3"
6911 [(set (match_operand:DI 0 "register_operand" "=d,d")
6912 (ior:DI
6913 (ashift:DI
6914 (zero_extend:DI
6915 (truncate:SI
6916 (umod:DI (match_operand:DI 1 "register_operand" "0,0")
6917 (zero_extend:DI
6918 (match_operand:SI 2 "nonimmediate_operand" "d,T")))))
6919 (const_int 32))
6920 (zero_extend:DI
6921 (truncate:SI
6922 (udiv:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))))]
6923 "!TARGET_ZARCH && TARGET_CPU_ZARCH"
6924 "@
6925 dlr\t%0,%2
6926 dl\t%0,%2"
6927 [(set_attr "op_type" "RRE,RXY")
6928 (set_attr "type" "idiv")])
6929
6930 (define_expand "udivsi3"
6931 [(set (match_operand:SI 0 "register_operand" "=d")
6932 (udiv:SI (match_operand:SI 1 "general_operand" "")
6933 (match_operand:SI 2 "general_operand" "")))
6934 (clobber (match_dup 3))]
6935 "!TARGET_ZARCH && !TARGET_CPU_ZARCH"
6936 {
6937 rtx udiv_equal, umod_equal, equal;
6938 rtx_insn *insn;
6939
6940 udiv_equal = gen_rtx_UDIV (SImode, operands[1], operands[2]);
6941 umod_equal = gen_rtx_UMOD (SImode, operands[1], operands[2]);
6942 equal = gen_rtx_IOR (DImode,
6943 gen_rtx_ASHIFT (DImode,
6944 gen_rtx_ZERO_EXTEND (DImode, umod_equal),
6945 GEN_INT (32)),
6946 gen_rtx_ZERO_EXTEND (DImode, udiv_equal));
6947
6948 operands[3] = gen_reg_rtx (DImode);
6949
6950 if (CONSTANT_P (operands[2]))
6951 {
6952 if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0)
6953 {
6954 rtx_code_label *label1 = gen_label_rtx ();
6955
6956 operands[1] = make_safe_from (operands[1], operands[0]);
6957 emit_move_insn (operands[0], const0_rtx);
6958 emit_cmp_and_jump_insns (operands[1], operands[2], LT, NULL_RTX,
6959 SImode, 1, label1);
6960 emit_move_insn (operands[0], const1_rtx);
6961 emit_label (label1);
6962 }
6963 else
6964 {
6965 operands[2] = force_reg (SImode, operands[2]);
6966 operands[2] = make_safe_from (operands[2], operands[0]);
6967
6968 emit_insn (gen_zero_extendsidi2 (operands[3], operands[1]));
6969 insn = emit_insn (gen_divmoddisi3 (operands[3], operands[3],
6970 operands[2]));
6971 set_unique_reg_note (insn, REG_EQUAL, equal);
6972
6973 insn = emit_move_insn (operands[0],
6974 gen_lowpart (SImode, operands[3]));
6975 set_unique_reg_note (insn, REG_EQUAL, udiv_equal);
6976 }
6977 }
6978 else
6979 {
6980 rtx_code_label *label1 = gen_label_rtx ();
6981 rtx_code_label *label2 = gen_label_rtx ();
6982 rtx_code_label *label3 = gen_label_rtx ();
6983
6984 operands[1] = force_reg (SImode, operands[1]);
6985 operands[1] = make_safe_from (operands[1], operands[0]);
6986 operands[2] = force_reg (SImode, operands[2]);
6987 operands[2] = make_safe_from (operands[2], operands[0]);
6988
6989 emit_move_insn (operands[0], const0_rtx);
6990 emit_cmp_and_jump_insns (operands[2], operands[1], GT, NULL_RTX,
6991 SImode, 1, label3);
6992 emit_cmp_and_jump_insns (operands[2], const0_rtx, LT, NULL_RTX,
6993 SImode, 0, label2);
6994 emit_cmp_and_jump_insns (operands[2], const1_rtx, EQ, NULL_RTX,
6995 SImode, 0, label1);
6996 emit_insn (gen_zero_extendsidi2 (operands[3], operands[1]));
6997 insn = emit_insn (gen_divmoddisi3 (operands[3], operands[3],
6998 operands[2]));
6999 set_unique_reg_note (insn, REG_EQUAL, equal);
7000
7001 insn = emit_move_insn (operands[0],
7002 gen_lowpart (SImode, operands[3]));
7003 set_unique_reg_note (insn, REG_EQUAL, udiv_equal);
7004
7005 emit_jump (label3);
7006 emit_label (label1);
7007 emit_move_insn (operands[0], operands[1]);
7008 emit_jump (label3);
7009 emit_label (label2);
7010 emit_move_insn (operands[0], const1_rtx);
7011 emit_label (label3);
7012 }
7013 emit_move_insn (operands[0], operands[0]);
7014 DONE;
7015 })
7016
7017 (define_expand "umodsi3"
7018 [(set (match_operand:SI 0 "register_operand" "=d")
7019 (umod:SI (match_operand:SI 1 "nonimmediate_operand" "")
7020 (match_operand:SI 2 "nonimmediate_operand" "")))
7021 (clobber (match_dup 3))]
7022 "!TARGET_ZARCH && !TARGET_CPU_ZARCH"
7023 {
7024 rtx udiv_equal, umod_equal, equal;
7025 rtx_insn *insn;
7026
7027 udiv_equal = gen_rtx_UDIV (SImode, operands[1], operands[2]);
7028 umod_equal = gen_rtx_UMOD (SImode, operands[1], operands[2]);
7029 equal = gen_rtx_IOR (DImode,
7030 gen_rtx_ASHIFT (DImode,
7031 gen_rtx_ZERO_EXTEND (DImode, umod_equal),
7032 GEN_INT (32)),
7033 gen_rtx_ZERO_EXTEND (DImode, udiv_equal));
7034
7035 operands[3] = gen_reg_rtx (DImode);
7036
7037 if (CONSTANT_P (operands[2]))
7038 {
7039 if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) <= 0)
7040 {
7041 rtx_code_label *label1 = gen_label_rtx ();
7042
7043 operands[1] = make_safe_from (operands[1], operands[0]);
7044 emit_move_insn (operands[0], operands[1]);
7045 emit_cmp_and_jump_insns (operands[0], operands[2], LT, NULL_RTX,
7046 SImode, 1, label1);
7047 emit_insn (gen_abssi2 (operands[0], operands[2]));
7048 emit_insn (gen_addsi3 (operands[0], operands[0], operands[1]));
7049 emit_label (label1);
7050 }
7051 else
7052 {
7053 operands[2] = force_reg (SImode, operands[2]);
7054 operands[2] = make_safe_from (operands[2], operands[0]);
7055
7056 emit_insn (gen_zero_extendsidi2 (operands[3], operands[1]));
7057 insn = emit_insn (gen_divmoddisi3 (operands[3], operands[3],
7058 operands[2]));
7059 set_unique_reg_note (insn, REG_EQUAL, equal);
7060
7061 insn = emit_move_insn (operands[0],
7062 gen_highpart (SImode, operands[3]));
7063 set_unique_reg_note (insn, REG_EQUAL, umod_equal);
7064 }
7065 }
7066 else
7067 {
7068 rtx_code_label *label1 = gen_label_rtx ();
7069 rtx_code_label *label2 = gen_label_rtx ();
7070 rtx_code_label *label3 = gen_label_rtx ();
7071
7072 operands[1] = force_reg (SImode, operands[1]);
7073 operands[1] = make_safe_from (operands[1], operands[0]);
7074 operands[2] = force_reg (SImode, operands[2]);
7075 operands[2] = make_safe_from (operands[2], operands[0]);
7076
7077 emit_move_insn(operands[0], operands[1]);
7078 emit_cmp_and_jump_insns (operands[2], operands[1], GT, NULL_RTX,
7079 SImode, 1, label3);
7080 emit_cmp_and_jump_insns (operands[2], const0_rtx, LT, NULL_RTX,
7081 SImode, 0, label2);
7082 emit_cmp_and_jump_insns (operands[2], const1_rtx, EQ, NULL_RTX,
7083 SImode, 0, label1);
7084 emit_insn (gen_zero_extendsidi2 (operands[3], operands[1]));
7085 insn = emit_insn (gen_divmoddisi3 (operands[3], operands[3],
7086 operands[2]));
7087 set_unique_reg_note (insn, REG_EQUAL, equal);
7088
7089 insn = emit_move_insn (operands[0],
7090 gen_highpart (SImode, operands[3]));
7091 set_unique_reg_note (insn, REG_EQUAL, umod_equal);
7092
7093 emit_jump (label3);
7094 emit_label (label1);
7095 emit_move_insn (operands[0], const0_rtx);
7096 emit_jump (label3);
7097 emit_label (label2);
7098 emit_insn (gen_subsi3 (operands[0], operands[0], operands[2]));
7099 emit_label (label3);
7100 }
7101 DONE;
7102 })
7103
7104 ;
7105 ; div(df|sf)3 instruction pattern(s).
7106 ;
7107
7108 ; dxbr, ddbr, debr, dxb, ddb, deb, ddtr, dxtr
7109 (define_insn "div<mode>3"
7110 [(set (match_operand:FP 0 "register_operand" "=f,f,f,v")
7111 (div:FP (match_operand:FP 1 "register_operand" "f,0,0,v")
7112 (match_operand:FP 2 "general_operand" "f,f,R,v")))]
7113 "TARGET_HARD_FLOAT"
7114 "@
7115 d<xde>tr\t%0,%1,%2
7116 d<xde>br\t%0,%2
7117 d<xde>b\t%0,%2
7118 wfddb\t%v0,%v1,%v2"
7119 [(set_attr "op_type" "RRF,RRE,RXE,VRR")
7120 (set_attr "type" "fdiv<mode>")
7121 (set_attr "cpu_facility" "*,*,*,vx")
7122 (set_attr "enabled" "<nBFP>,<nDFP>,<DSF>,<DFDI>")])
7123
7124
7125 ;;
7126 ;;- And instructions.
7127 ;;
7128
7129 (define_expand "and<mode>3"
7130 [(set (match_operand:INT 0 "nonimmediate_operand" "")
7131 (and:INT (match_operand:INT 1 "nonimmediate_operand" "")
7132 (match_operand:INT 2 "general_operand" "")))
7133 (clobber (reg:CC CC_REGNUM))]
7134 ""
7135 "s390_expand_logical_operator (AND, <MODE>mode, operands); DONE;")
7136
7137 ;
7138 ; anddi3 instruction pattern(s).
7139 ;
7140
7141 (define_insn "*anddi3_cc"
7142 [(set (reg CC_REGNUM)
7143 (compare
7144 (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,d,0, d")
7145 (match_operand:DI 2 "general_operand" " d,d,T,NxxDw"))
7146 (const_int 0)))
7147 (set (match_operand:DI 0 "register_operand" "=d,d,d, d")
7148 (and:DI (match_dup 1) (match_dup 2)))]
7149 "TARGET_ZARCH && s390_match_ccmode(insn, CCTmode)"
7150 "@
7151 ngr\t%0,%2
7152 ngrk\t%0,%1,%2
7153 ng\t%0,%2
7154 risbg\t%0,%1,%s2,128+%e2,0"
7155 [(set_attr "op_type" "RRE,RRF,RXY,RIE")
7156 (set_attr "cpu_facility" "*,z196,*,z10")
7157 (set_attr "z10prop" "z10_super_E1,*,z10_super_E1,z10_super_E1")])
7158
7159 (define_insn "*anddi3_cconly"
7160 [(set (reg CC_REGNUM)
7161 (compare
7162 (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,d,0, d")
7163 (match_operand:DI 2 "general_operand" " d,d,T,NxxDw"))
7164 (const_int 0)))
7165 (clobber (match_scratch:DI 0 "=d,d,d, d"))]
7166 "TARGET_ZARCH
7167 && s390_match_ccmode(insn, CCTmode)
7168 /* Do not steal TM patterns. */
7169 && s390_single_part (operands[2], DImode, HImode, 0) < 0"
7170 "@
7171 ngr\t%0,%2
7172 ngrk\t%0,%1,%2
7173 ng\t%0,%2
7174 risbg\t%0,%1,%s2,128+%e2,0"
7175 [(set_attr "op_type" "RRE,RRF,RXY,RIE")
7176 (set_attr "cpu_facility" "*,z196,*,z10")
7177 (set_attr "z10prop" "z10_super_E1,*,z10_super_E1,z10_super_E1")])
7178
7179 (define_insn "*anddi3"
7180 [(set (match_operand:DI 0 "nonimmediate_operand"
7181 "=d,d, d, d, d, d, d, d,d,d,d, d, AQ,Q")
7182 (and:DI
7183 (match_operand:DI 1 "nonimmediate_operand"
7184 "%d,o, 0, 0, 0, 0, 0, 0,0,d,0, d, 0,0")
7185 (match_operand:DI 2 "general_operand"
7186 "M, M,N0HDF,N1HDF,N2HDF,N3HDF,N0SDF,N1SDF,d,d,T,NxxDw,NxQDF,Q")))
7187 (clobber (reg:CC CC_REGNUM))]
7188 "TARGET_ZARCH && s390_logical_operator_ok_p (operands)"
7189 "@
7190 #
7191 #
7192 nihh\t%0,%j2
7193 nihl\t%0,%j2
7194 nilh\t%0,%j2
7195 nill\t%0,%j2
7196 nihf\t%0,%m2
7197 nilf\t%0,%m2
7198 ngr\t%0,%2
7199 ngrk\t%0,%1,%2
7200 ng\t%0,%2
7201 risbg\t%0,%1,%s2,128+%e2,0
7202 #
7203 #"
7204 [(set_attr "op_type" "RRE,RXE,RI,RI,RI,RI,RIL,RIL,RRE,RRF,RXY,RIE,SI,SS")
7205 (set_attr "cpu_facility" "*,*,*,*,*,*,extimm,extimm,*,z196,*,z10,*,*")
7206 (set_attr "z10prop" "*,
7207 *,
7208 z10_super_E1,
7209 z10_super_E1,
7210 z10_super_E1,
7211 z10_super_E1,
7212 z10_super_E1,
7213 z10_super_E1,
7214 z10_super_E1,
7215 *,
7216 z10_super_E1,
7217 z10_super_E1,
7218 *,
7219 *")])
7220
7221 (define_split
7222 [(set (match_operand:DI 0 "s_operand" "")
7223 (and:DI (match_dup 0) (match_operand:DI 1 "immediate_operand" "")))
7224 (clobber (reg:CC CC_REGNUM))]
7225 "reload_completed"
7226 [(parallel
7227 [(set (match_dup 0) (and:QI (match_dup 0) (match_dup 1)))
7228 (clobber (reg:CC CC_REGNUM))])]
7229 "s390_narrow_logical_operator (AND, &operands[0], &operands[1]);")
7230
7231 ;; These two are what combine generates for (ashift (zero_extract)).
7232 (define_insn "*extzv_<mode>_srl<clobbercc_or_nocc>"
7233 [(set (match_operand:GPR 0 "register_operand" "=d")
7234 (and:GPR (lshiftrt:GPR
7235 (match_operand:GPR 1 "register_operand" "d")
7236 (match_operand:GPR 2 "nonzero_shift_count_operand" ""))
7237 (match_operand:GPR 3 "contiguous_bitmask_nowrap_operand" "")))]
7238 "<z10_or_zEC12_cond>
7239 /* Note that even for the SImode pattern, the rotate is always DImode. */
7240 && s390_extzv_shift_ok (<bitsize>, -INTVAL (operands[2]),
7241 INTVAL (operands[3]))"
7242 "<risbg_n>\t%0,%1,%<bfstart>3,128+%<bfend>3,64-%2"
7243 [(set_attr "op_type" "RIE")
7244 (set_attr "z10prop" "z10_super_E1")])
7245
7246 (define_insn "*extzv_<mode>_sll<clobbercc_or_nocc>"
7247 [(set (match_operand:GPR 0 "register_operand" "=d")
7248 (and:GPR (ashift:GPR
7249 (match_operand:GPR 1 "register_operand" "d")
7250 (match_operand:GPR 2 "nonzero_shift_count_operand" ""))
7251 (match_operand:GPR 3 "contiguous_bitmask_nowrap_operand" "")))]
7252 "<z10_or_zEC12_cond>
7253 && s390_extzv_shift_ok (<bitsize>, INTVAL (operands[2]),
7254 INTVAL (operands[3]))"
7255 "<risbg_n>\t%0,%1,%<bfstart>3,128+%<bfend>3,%2"
7256 [(set_attr "op_type" "RIE")
7257 (set_attr "z10prop" "z10_super_E1")])
7258
7259
7260 ;
7261 ; andsi3 instruction pattern(s).
7262 ;
7263
7264 (define_insn "*andsi3_cc"
7265 [(set (reg CC_REGNUM)
7266 (compare
7267 (and:SI
7268 (match_operand:SI 1 "nonimmediate_operand" "%0,0,d,0,0, d")
7269 (match_operand:SI 2 "general_operand" "Os,d,d,R,T,NxxSq"))
7270 (const_int 0)))
7271 (set (match_operand:SI 0 "register_operand" "=d,d,d,d,d, d")
7272 (and:SI (match_dup 1) (match_dup 2)))]
7273 "s390_match_ccmode(insn, CCTmode)"
7274 "@
7275 nilf\t%0,%o2
7276 nr\t%0,%2
7277 nrk\t%0,%1,%2
7278 n\t%0,%2
7279 ny\t%0,%2
7280 risbg\t%0,%1,%t2,128+%f2,0"
7281 [(set_attr "op_type" "RIL,RR,RRF,RX,RXY,RIE")
7282 (set_attr "cpu_facility" "*,*,z196,*,longdisp,z10")
7283 (set_attr "z10prop" "z10_super_E1,z10_super_E1,*,
7284 z10_super_E1,z10_super_E1,z10_super_E1")])
7285
7286 (define_insn "*andsi3_cconly"
7287 [(set (reg CC_REGNUM)
7288 (compare
7289 (and:SI
7290 (match_operand:SI 1 "nonimmediate_operand" "%0,0,d,0,0, d")
7291 (match_operand:SI 2 "general_operand" "Os,d,d,R,T,NxxSq"))
7292 (const_int 0)))
7293 (clobber (match_scratch:SI 0 "=d,d,d,d,d, d"))]
7294 "s390_match_ccmode(insn, CCTmode)
7295 /* Do not steal TM patterns. */
7296 && s390_single_part (operands[2], SImode, HImode, 0) < 0"
7297 "@
7298 nilf\t%0,%o2
7299 nr\t%0,%2
7300 nrk\t%0,%1,%2
7301 n\t%0,%2
7302 ny\t%0,%2
7303 risbg\t%0,%1,%t2,128+%f2,0"
7304 [(set_attr "op_type" "RIL,RR,RRF,RX,RXY,RIE")
7305 (set_attr "cpu_facility" "*,*,z196,*,longdisp,z10")
7306 (set_attr "z10prop" "z10_super_E1,z10_super_E1,*,
7307 z10_super_E1,z10_super_E1,z10_super_E1")])
7308
7309 (define_insn "*andsi3_zarch"
7310 [(set (match_operand:SI 0 "nonimmediate_operand"
7311 "=d,d, d, d, d,d,d,d,d, d, AQ,Q")
7312 (and:SI (match_operand:SI 1 "nonimmediate_operand"
7313 "%d,o, 0, 0, 0,0,d,0,0, d, 0,0")
7314 (match_operand:SI 2 "general_operand"
7315 " M,M,N0HSF,N1HSF,Os,d,d,R,T,NxxSw,NxQSF,Q")))
7316 (clobber (reg:CC CC_REGNUM))]
7317 "TARGET_ZARCH && s390_logical_operator_ok_p (operands)"
7318 "@
7319 #
7320 #
7321 nilh\t%0,%j2
7322 nill\t%0,%j2
7323 nilf\t%0,%o2
7324 nr\t%0,%2
7325 nrk\t%0,%1,%2
7326 n\t%0,%2
7327 ny\t%0,%2
7328 risbg\t%0,%1,%t2,128+%f2,0
7329 #
7330 #"
7331 [(set_attr "op_type" "RRE,RXE,RI,RI,RIL,RR,RRF,RX,RXY,RIE,SI,SS")
7332 (set_attr "cpu_facility" "*,*,*,*,*,*,z196,*,longdisp,z10,*,*")
7333 (set_attr "z10prop" "*,
7334 *,
7335 z10_super_E1,
7336 z10_super_E1,
7337 z10_super_E1,
7338 z10_super_E1,
7339 *,
7340 z10_super_E1,
7341 z10_super_E1,
7342 z10_super_E1,
7343 *,
7344 *")])
7345
7346 (define_insn "*andsi3_esa"
7347 [(set (match_operand:SI 0 "nonimmediate_operand" "=d,d, AQ,Q")
7348 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0, 0,0")
7349 (match_operand:SI 2 "general_operand" " d,R,NxQSF,Q")))
7350 (clobber (reg:CC CC_REGNUM))]
7351 "!TARGET_ZARCH && s390_logical_operator_ok_p (operands)"
7352 "@
7353 nr\t%0,%2
7354 n\t%0,%2
7355 #
7356 #"
7357 [(set_attr "op_type" "RR,RX,SI,SS")
7358 (set_attr "z10prop" "z10_super_E1,z10_super_E1,*,*")])
7359
7360
7361 (define_split
7362 [(set (match_operand:SI 0 "s_operand" "")
7363 (and:SI (match_dup 0) (match_operand:SI 1 "immediate_operand" "")))
7364 (clobber (reg:CC CC_REGNUM))]
7365 "reload_completed"
7366 [(parallel
7367 [(set (match_dup 0) (and:QI (match_dup 0) (match_dup 1)))
7368 (clobber (reg:CC CC_REGNUM))])]
7369 "s390_narrow_logical_operator (AND, &operands[0], &operands[1]);")
7370
7371 ;
7372 ; andhi3 instruction pattern(s).
7373 ;
7374
7375 (define_insn "*andhi3_zarch"
7376 [(set (match_operand:HI 0 "nonimmediate_operand" "=d,d,d, AQ,Q")
7377 (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,d,0, 0,0")
7378 (match_operand:HI 2 "general_operand" " d,d,n,NxQHF,Q")))
7379 (clobber (reg:CC CC_REGNUM))]
7380 "TARGET_ZARCH && s390_logical_operator_ok_p (operands)"
7381 "@
7382 nr\t%0,%2
7383 nrk\t%0,%1,%2
7384 nill\t%0,%x2
7385 #
7386 #"
7387 [(set_attr "op_type" "RR,RRF,RI,SI,SS")
7388 (set_attr "cpu_facility" "*,z196,*,*,*")
7389 (set_attr "z10prop" "z10_super_E1,*,z10_super_E1,*,*")
7390 ])
7391
7392 (define_insn "*andhi3_esa"
7393 [(set (match_operand:HI 0 "nonimmediate_operand" "=d,AQ,Q")
7394 (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,0")
7395 (match_operand:HI 2 "general_operand" "d,NxQHF,Q")))
7396 (clobber (reg:CC CC_REGNUM))]
7397 "!TARGET_ZARCH && s390_logical_operator_ok_p (operands)"
7398 "@
7399 nr\t%0,%2
7400 #
7401 #"
7402 [(set_attr "op_type" "RR,SI,SS")
7403 (set_attr "z10prop" "z10_super_E1,*,*")
7404 ])
7405
7406 (define_split
7407 [(set (match_operand:HI 0 "s_operand" "")
7408 (and:HI (match_dup 0) (match_operand:HI 1 "immediate_operand" "")))
7409 (clobber (reg:CC CC_REGNUM))]
7410 "reload_completed"
7411 [(parallel
7412 [(set (match_dup 0) (and:QI (match_dup 0) (match_dup 1)))
7413 (clobber (reg:CC CC_REGNUM))])]
7414 "s390_narrow_logical_operator (AND, &operands[0], &operands[1]);")
7415
7416 ;
7417 ; andqi3 instruction pattern(s).
7418 ;
7419
7420 (define_insn "*andqi3_zarch"
7421 [(set (match_operand:QI 0 "nonimmediate_operand" "=d,d,d,Q,S,Q")
7422 (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,d,0,0,0,0")
7423 (match_operand:QI 2 "general_operand" " d,d,n,n,n,Q")))
7424 (clobber (reg:CC CC_REGNUM))]
7425 "TARGET_ZARCH && s390_logical_operator_ok_p (operands)"
7426 "@
7427 nr\t%0,%2
7428 nrk\t%0,%1,%2
7429 nill\t%0,%b2
7430 ni\t%S0,%b2
7431 niy\t%S0,%b2
7432 #"
7433 [(set_attr "op_type" "RR,RRF,RI,SI,SIY,SS")
7434 (set_attr "cpu_facility" "*,z196,*,*,longdisp,*")
7435 (set_attr "z10prop" "z10_super_E1,*,z10_super_E1,z10_super,z10_super,*")])
7436
7437 (define_insn "*andqi3_esa"
7438 [(set (match_operand:QI 0 "nonimmediate_operand" "=d,Q,Q")
7439 (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
7440 (match_operand:QI 2 "general_operand" "d,n,Q")))
7441 (clobber (reg:CC CC_REGNUM))]
7442 "!TARGET_ZARCH && s390_logical_operator_ok_p (operands)"
7443 "@
7444 nr\t%0,%2
7445 ni\t%S0,%b2
7446 #"
7447 [(set_attr "op_type" "RR,SI,SS")
7448 (set_attr "z10prop" "z10_super_E1,z10_super,*")])
7449
7450 ;
7451 ; And with complement
7452 ;
7453 ; c = ~b & a = (b & a) ^ a
7454
7455 (define_insn_and_split "*andc_split_<mode>"
7456 [(set (match_operand:GPR 0 "nonimmediate_operand" "")
7457 (and:GPR (not:GPR (match_operand:GPR 1 "nonimmediate_operand" ""))
7458 (match_operand:GPR 2 "general_operand" "")))
7459 (clobber (reg:CC CC_REGNUM))]
7460 "! reload_completed
7461 && (GET_CODE (operands[0]) != MEM
7462 /* Ensure that s390_logical_operator_ok_p will succeed even
7463 on the split xor if (b & a) is stored into a pseudo. */
7464 || rtx_equal_p (operands[0], operands[2]))"
7465 "#"
7466 "&& 1"
7467 [
7468 (parallel
7469 [(set (match_dup 3) (and:GPR (match_dup 1) (match_dup 2)))
7470 (clobber (reg:CC CC_REGNUM))])
7471 (parallel
7472 [(set (match_dup 0) (xor:GPR (match_dup 3) (match_dup 2)))
7473 (clobber (reg:CC CC_REGNUM))])]
7474 {
7475 if (reg_overlap_mentioned_p (operands[0], operands[2]))
7476 operands[3] = gen_reg_rtx (<MODE>mode);
7477 else
7478 operands[3] = operands[0];
7479 })
7480
7481 ;
7482 ; Block and (NC) patterns.
7483 ;
7484
7485 (define_insn "*nc"
7486 [(set (match_operand:BLK 0 "memory_operand" "=Q")
7487 (and:BLK (match_dup 0)
7488 (match_operand:BLK 1 "memory_operand" "Q")))
7489 (use (match_operand 2 "const_int_operand" "n"))
7490 (clobber (reg:CC CC_REGNUM))]
7491 "INTVAL (operands[2]) >= 1 && INTVAL (operands[2]) <= 256"
7492 "nc\t%O0(%2,%R0),%S1"
7493 [(set_attr "op_type" "SS")
7494 (set_attr "z196prop" "z196_cracked")])
7495
7496 (define_split
7497 [(set (match_operand 0 "memory_operand" "")
7498 (and (match_dup 0)
7499 (match_operand 1 "memory_operand" "")))
7500 (clobber (reg:CC CC_REGNUM))]
7501 "reload_completed
7502 && GET_MODE (operands[0]) == GET_MODE (operands[1])
7503 && GET_MODE_SIZE (GET_MODE (operands[0])) > 0"
7504 [(parallel
7505 [(set (match_dup 0) (and:BLK (match_dup 0) (match_dup 1)))
7506 (use (match_dup 2))
7507 (clobber (reg:CC CC_REGNUM))])]
7508 {
7509 operands[2] = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[0])));
7510 operands[0] = adjust_address (operands[0], BLKmode, 0);
7511 operands[1] = adjust_address (operands[1], BLKmode, 0);
7512 })
7513
7514 (define_peephole2
7515 [(parallel
7516 [(set (match_operand:BLK 0 "memory_operand" "")
7517 (and:BLK (match_dup 0)
7518 (match_operand:BLK 1 "memory_operand" "")))
7519 (use (match_operand 2 "const_int_operand" ""))
7520 (clobber (reg:CC CC_REGNUM))])
7521 (parallel
7522 [(set (match_operand:BLK 3 "memory_operand" "")
7523 (and:BLK (match_dup 3)
7524 (match_operand:BLK 4 "memory_operand" "")))
7525 (use (match_operand 5 "const_int_operand" ""))
7526 (clobber (reg:CC CC_REGNUM))])]
7527 "s390_offset_p (operands[0], operands[3], operands[2])
7528 && s390_offset_p (operands[1], operands[4], operands[2])
7529 && !s390_overlap_p (operands[0], operands[1],
7530 INTVAL (operands[2]) + INTVAL (operands[5]))
7531 && INTVAL (operands[2]) + INTVAL (operands[5]) <= 256"
7532 [(parallel
7533 [(set (match_dup 6) (and:BLK (match_dup 6) (match_dup 7)))
7534 (use (match_dup 8))
7535 (clobber (reg:CC CC_REGNUM))])]
7536 "operands[6] = gen_rtx_MEM (BLKmode, XEXP (operands[0], 0));
7537 operands[7] = gen_rtx_MEM (BLKmode, XEXP (operands[1], 0));
7538 operands[8] = GEN_INT (INTVAL (operands[2]) + INTVAL (operands[5]));")
7539
7540
7541 ;;
7542 ;;- Bit set (inclusive or) instructions.
7543 ;;
7544
7545 (define_expand "ior<mode>3"
7546 [(set (match_operand:INT 0 "nonimmediate_operand" "")
7547 (ior:INT (match_operand:INT 1 "nonimmediate_operand" "")
7548 (match_operand:INT 2 "general_operand" "")))
7549 (clobber (reg:CC CC_REGNUM))]
7550 ""
7551 "s390_expand_logical_operator (IOR, <MODE>mode, operands); DONE;")
7552
7553 ;
7554 ; iordi3 instruction pattern(s).
7555 ;
7556
7557 (define_insn "*iordi3_cc"
7558 [(set (reg CC_REGNUM)
7559 (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,d,0")
7560 (match_operand:DI 2 "general_operand" " d,d,T"))
7561 (const_int 0)))
7562 (set (match_operand:DI 0 "register_operand" "=d,d,d")
7563 (ior:DI (match_dup 1) (match_dup 2)))]
7564 "s390_match_ccmode(insn, CCTmode) && TARGET_ZARCH"
7565 "@
7566 ogr\t%0,%2
7567 ogrk\t%0,%1,%2
7568 og\t%0,%2"
7569 [(set_attr "op_type" "RRE,RRF,RXY")
7570 (set_attr "cpu_facility" "*,z196,*")
7571 (set_attr "z10prop" "z10_super_E1,*,z10_super_E1")])
7572
7573 (define_insn "*iordi3_cconly"
7574 [(set (reg CC_REGNUM)
7575 (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,d,0")
7576 (match_operand:DI 2 "general_operand" " d,d,T"))
7577 (const_int 0)))
7578 (clobber (match_scratch:DI 0 "=d,d,d"))]
7579 "s390_match_ccmode(insn, CCTmode) && TARGET_ZARCH"
7580 "@
7581 ogr\t%0,%2
7582 ogrk\t%0,%1,%2
7583 og\t%0,%2"
7584 [(set_attr "op_type" "RRE,RRF,RXY")
7585 (set_attr "cpu_facility" "*,z196,*")
7586 (set_attr "z10prop" "z10_super_E1,*,z10_super_E1")])
7587
7588 (define_insn "*iordi3"
7589 [(set (match_operand:DI 0 "nonimmediate_operand"
7590 "=d, d, d, d, d, d,d,d,d, AQ,Q")
7591 (ior:DI (match_operand:DI 1 "nonimmediate_operand"
7592 " %0, 0, 0, 0, 0, 0,0,d,0, 0,0")
7593 (match_operand:DI 2 "general_operand"
7594 "N0HD0,N1HD0,N2HD0,N3HD0,N0SD0,N1SD0,d,d,T,NxQD0,Q")))
7595 (clobber (reg:CC CC_REGNUM))]
7596 "TARGET_ZARCH && s390_logical_operator_ok_p (operands)"
7597 "@
7598 oihh\t%0,%i2
7599 oihl\t%0,%i2
7600 oilh\t%0,%i2
7601 oill\t%0,%i2
7602 oihf\t%0,%k2
7603 oilf\t%0,%k2
7604 ogr\t%0,%2
7605 ogrk\t%0,%1,%2
7606 og\t%0,%2
7607 #
7608 #"
7609 [(set_attr "op_type" "RI,RI,RI,RI,RIL,RIL,RRE,RRF,RXY,SI,SS")
7610 (set_attr "cpu_facility" "*,*,*,*,extimm,extimm,*,z196,*,*,*")
7611 (set_attr "z10prop" "z10_super_E1,
7612 z10_super_E1,
7613 z10_super_E1,
7614 z10_super_E1,
7615 z10_super_E1,
7616 z10_super_E1,
7617 z10_super_E1,
7618 *,
7619 z10_super_E1,
7620 *,
7621 *")])
7622
7623 (define_split
7624 [(set (match_operand:DI 0 "s_operand" "")
7625 (ior:DI (match_dup 0) (match_operand:DI 1 "immediate_operand" "")))
7626 (clobber (reg:CC CC_REGNUM))]
7627 "reload_completed"
7628 [(parallel
7629 [(set (match_dup 0) (ior:QI (match_dup 0) (match_dup 1)))
7630 (clobber (reg:CC CC_REGNUM))])]
7631 "s390_narrow_logical_operator (IOR, &operands[0], &operands[1]);")
7632
7633 ;
7634 ; iorsi3 instruction pattern(s).
7635 ;
7636
7637 (define_insn "*iorsi3_cc"
7638 [(set (reg CC_REGNUM)
7639 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,d,0,0")
7640 (match_operand:SI 2 "general_operand" "Os,d,d,R,T"))
7641 (const_int 0)))
7642 (set (match_operand:SI 0 "register_operand" "=d,d,d,d,d")
7643 (ior:SI (match_dup 1) (match_dup 2)))]
7644 "s390_match_ccmode(insn, CCTmode)"
7645 "@
7646 oilf\t%0,%o2
7647 or\t%0,%2
7648 ork\t%0,%1,%2
7649 o\t%0,%2
7650 oy\t%0,%2"
7651 [(set_attr "op_type" "RIL,RR,RRF,RX,RXY")
7652 (set_attr "cpu_facility" "*,*,z196,*,longdisp")
7653 (set_attr "z10prop" "z10_super_E1,z10_super_E1,*,z10_super_E1,z10_super_E1")])
7654
7655 (define_insn "*iorsi3_cconly"
7656 [(set (reg CC_REGNUM)
7657 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,d,0,0")
7658 (match_operand:SI 2 "general_operand" "Os,d,d,R,T"))
7659 (const_int 0)))
7660 (clobber (match_scratch:SI 0 "=d,d,d,d,d"))]
7661 "s390_match_ccmode(insn, CCTmode)"
7662 "@
7663 oilf\t%0,%o2
7664 or\t%0,%2
7665 ork\t%0,%1,%2
7666 o\t%0,%2
7667 oy\t%0,%2"
7668 [(set_attr "op_type" "RIL,RR,RRF,RX,RXY")
7669 (set_attr "cpu_facility" "*,*,z196,*,longdisp")
7670 (set_attr "z10prop" "z10_super_E1,z10_super_E1,*,z10_super_E1,z10_super_E1")])
7671
7672 (define_insn "*iorsi3_zarch"
7673 [(set (match_operand:SI 0 "nonimmediate_operand" "=d, d, d,d,d,d,d, AQ,Q")
7674 (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0, 0, 0,0,d,0,0, 0,0")
7675 (match_operand:SI 2 "general_operand" "N0HS0,N1HS0,Os,d,d,R,T,NxQS0,Q")))
7676 (clobber (reg:CC CC_REGNUM))]
7677 "TARGET_ZARCH && s390_logical_operator_ok_p (operands)"
7678 "@
7679 oilh\t%0,%i2
7680 oill\t%0,%i2
7681 oilf\t%0,%o2
7682 or\t%0,%2
7683 ork\t%0,%1,%2
7684 o\t%0,%2
7685 oy\t%0,%2
7686 #
7687 #"
7688 [(set_attr "op_type" "RI,RI,RIL,RR,RRF,RX,RXY,SI,SS")
7689 (set_attr "cpu_facility" "*,*,*,*,z196,*,longdisp,*,*")
7690 (set_attr "z10prop" "z10_super_E1,
7691 z10_super_E1,
7692 z10_super_E1,
7693 z10_super_E1,
7694 *,
7695 z10_super_E1,
7696 z10_super_E1,
7697 *,
7698 *")])
7699
7700 (define_insn "*iorsi3_esa"
7701 [(set (match_operand:SI 0 "nonimmediate_operand" "=d,d,AQ,Q")
7702 (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,0,0")
7703 (match_operand:SI 2 "general_operand" "d,R,NxQS0,Q")))
7704 (clobber (reg:CC CC_REGNUM))]
7705 "!TARGET_ZARCH && s390_logical_operator_ok_p (operands)"
7706 "@
7707 or\t%0,%2
7708 o\t%0,%2
7709 #
7710 #"
7711 [(set_attr "op_type" "RR,RX,SI,SS")
7712 (set_attr "z10prop" "z10_super_E1,z10_super_E1,*,*")])
7713
7714 (define_split
7715 [(set (match_operand:SI 0 "s_operand" "")
7716 (ior:SI (match_dup 0) (match_operand:SI 1 "immediate_operand" "")))
7717 (clobber (reg:CC CC_REGNUM))]
7718 "reload_completed"
7719 [(parallel
7720 [(set (match_dup 0) (ior:QI (match_dup 0) (match_dup 1)))
7721 (clobber (reg:CC CC_REGNUM))])]
7722 "s390_narrow_logical_operator (IOR, &operands[0], &operands[1]);")
7723
7724 ;
7725 ; iorhi3 instruction pattern(s).
7726 ;
7727
7728 (define_insn "*iorhi3_zarch"
7729 [(set (match_operand:HI 0 "nonimmediate_operand" "=d,d,d, AQ,Q")
7730 (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,d,0, 0,0")
7731 (match_operand:HI 2 "general_operand" " d,d,n,NxQH0,Q")))
7732 (clobber (reg:CC CC_REGNUM))]
7733 "TARGET_ZARCH && s390_logical_operator_ok_p (operands)"
7734 "@
7735 or\t%0,%2
7736 ork\t%0,%1,%2
7737 oill\t%0,%x2
7738 #
7739 #"
7740 [(set_attr "op_type" "RR,RRF,RI,SI,SS")
7741 (set_attr "cpu_facility" "*,z196,*,*,*")
7742 (set_attr "z10prop" "z10_super_E1,*,z10_super_E1,*,*")])
7743
7744 (define_insn "*iorhi3_esa"
7745 [(set (match_operand:HI 0 "nonimmediate_operand" "=d,AQ,Q")
7746 (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,0")
7747 (match_operand:HI 2 "general_operand" "d,NxQH0,Q")))
7748 (clobber (reg:CC CC_REGNUM))]
7749 "!TARGET_ZARCH && s390_logical_operator_ok_p (operands)"
7750 "@
7751 or\t%0,%2
7752 #
7753 #"
7754 [(set_attr "op_type" "RR,SI,SS")
7755 (set_attr "z10prop" "z10_super_E1,*,*")])
7756
7757 (define_split
7758 [(set (match_operand:HI 0 "s_operand" "")
7759 (ior:HI (match_dup 0) (match_operand:HI 1 "immediate_operand" "")))
7760 (clobber (reg:CC CC_REGNUM))]
7761 "reload_completed"
7762 [(parallel
7763 [(set (match_dup 0) (ior:QI (match_dup 0) (match_dup 1)))
7764 (clobber (reg:CC CC_REGNUM))])]
7765 "s390_narrow_logical_operator (IOR, &operands[0], &operands[1]);")
7766
7767 ;
7768 ; iorqi3 instruction pattern(s).
7769 ;
7770
7771 (define_insn "*iorqi3_zarch"
7772 [(set (match_operand:QI 0 "nonimmediate_operand" "=d,d,d,Q,S,Q")
7773 (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,d,0,0,0,0")
7774 (match_operand:QI 2 "general_operand" " d,d,n,n,n,Q")))
7775 (clobber (reg:CC CC_REGNUM))]
7776 "TARGET_ZARCH && s390_logical_operator_ok_p (operands)"
7777 "@
7778 or\t%0,%2
7779 ork\t%0,%1,%2
7780 oill\t%0,%b2
7781 oi\t%S0,%b2
7782 oiy\t%S0,%b2
7783 #"
7784 [(set_attr "op_type" "RR,RRF,RI,SI,SIY,SS")
7785 (set_attr "cpu_facility" "*,z196,*,*,longdisp,*")
7786 (set_attr "z10prop" "z10_super_E1,*,z10_super_E1,
7787 z10_super,z10_super,*")])
7788
7789 (define_insn "*iorqi3_esa"
7790 [(set (match_operand:QI 0 "nonimmediate_operand" "=d,Q,Q")
7791 (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
7792 (match_operand:QI 2 "general_operand" "d,n,Q")))
7793 (clobber (reg:CC CC_REGNUM))]
7794 "!TARGET_ZARCH && s390_logical_operator_ok_p (operands)"
7795 "@
7796 or\t%0,%2
7797 oi\t%S0,%b2
7798 #"
7799 [(set_attr "op_type" "RR,SI,SS")
7800 (set_attr "z10prop" "z10_super_E1,z10_super,*")])
7801
7802 ;
7803 ; Block inclusive or (OC) patterns.
7804 ;
7805
7806 (define_insn "*oc"
7807 [(set (match_operand:BLK 0 "memory_operand" "=Q")
7808 (ior:BLK (match_dup 0)
7809 (match_operand:BLK 1 "memory_operand" "Q")))
7810 (use (match_operand 2 "const_int_operand" "n"))
7811 (clobber (reg:CC CC_REGNUM))]
7812 "INTVAL (operands[2]) >= 1 && INTVAL (operands[2]) <= 256"
7813 "oc\t%O0(%2,%R0),%S1"
7814 [(set_attr "op_type" "SS")
7815 (set_attr "z196prop" "z196_cracked")])
7816
7817 (define_split
7818 [(set (match_operand 0 "memory_operand" "")
7819 (ior (match_dup 0)
7820 (match_operand 1 "memory_operand" "")))
7821 (clobber (reg:CC CC_REGNUM))]
7822 "reload_completed
7823 && GET_MODE (operands[0]) == GET_MODE (operands[1])
7824 && GET_MODE_SIZE (GET_MODE (operands[0])) > 0"
7825 [(parallel
7826 [(set (match_dup 0) (ior:BLK (match_dup 0) (match_dup 1)))
7827 (use (match_dup 2))
7828 (clobber (reg:CC CC_REGNUM))])]
7829 {
7830 operands[2] = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[0])));
7831 operands[0] = adjust_address (operands[0], BLKmode, 0);
7832 operands[1] = adjust_address (operands[1], BLKmode, 0);
7833 })
7834
7835 (define_peephole2
7836 [(parallel
7837 [(set (match_operand:BLK 0 "memory_operand" "")
7838 (ior:BLK (match_dup 0)
7839 (match_operand:BLK 1 "memory_operand" "")))
7840 (use (match_operand 2 "const_int_operand" ""))
7841 (clobber (reg:CC CC_REGNUM))])
7842 (parallel
7843 [(set (match_operand:BLK 3 "memory_operand" "")
7844 (ior:BLK (match_dup 3)
7845 (match_operand:BLK 4 "memory_operand" "")))
7846 (use (match_operand 5 "const_int_operand" ""))
7847 (clobber (reg:CC CC_REGNUM))])]
7848 "s390_offset_p (operands[0], operands[3], operands[2])
7849 && s390_offset_p (operands[1], operands[4], operands[2])
7850 && !s390_overlap_p (operands[0], operands[1],
7851 INTVAL (operands[2]) + INTVAL (operands[5]))
7852 && INTVAL (operands[2]) + INTVAL (operands[5]) <= 256"
7853 [(parallel
7854 [(set (match_dup 6) (ior:BLK (match_dup 6) (match_dup 7)))
7855 (use (match_dup 8))
7856 (clobber (reg:CC CC_REGNUM))])]
7857 "operands[6] = gen_rtx_MEM (BLKmode, XEXP (operands[0], 0));
7858 operands[7] = gen_rtx_MEM (BLKmode, XEXP (operands[1], 0));
7859 operands[8] = GEN_INT (INTVAL (operands[2]) + INTVAL (operands[5]));")
7860
7861
7862 ;;
7863 ;;- Xor instructions.
7864 ;;
7865
7866 (define_expand "xor<mode>3"
7867 [(set (match_operand:INT 0 "nonimmediate_operand" "")
7868 (xor:INT (match_operand:INT 1 "nonimmediate_operand" "")
7869 (match_operand:INT 2 "general_operand" "")))
7870 (clobber (reg:CC CC_REGNUM))]
7871 ""
7872 "s390_expand_logical_operator (XOR, <MODE>mode, operands); DONE;")
7873
7874 ; Combine replaces (xor (x) (const_int -1)) with (not (x)) when doing
7875 ; simplifications. So its better to have something matching.
7876 (define_split
7877 [(set (match_operand:INT 0 "nonimmediate_operand" "")
7878 (not:INT (match_operand:INT 1 "nonimmediate_operand" "")))]
7879 ""
7880 [(parallel
7881 [(set (match_dup 0) (xor:INT (match_dup 1) (match_dup 2)))
7882 (clobber (reg:CC CC_REGNUM))])]
7883 {
7884 operands[2] = constm1_rtx;
7885 if (!s390_logical_operator_ok_p (operands))
7886 FAIL;
7887 })
7888
7889 ;
7890 ; xordi3 instruction pattern(s).
7891 ;
7892
7893 (define_insn "*xordi3_cc"
7894 [(set (reg CC_REGNUM)
7895 (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,d,0")
7896 (match_operand:DI 2 "general_operand" " d,d,T"))
7897 (const_int 0)))
7898 (set (match_operand:DI 0 "register_operand" "=d,d,d")
7899 (xor:DI (match_dup 1) (match_dup 2)))]
7900 "s390_match_ccmode(insn, CCTmode) && TARGET_ZARCH"
7901 "@
7902 xgr\t%0,%2
7903 xgrk\t%0,%1,%2
7904 xg\t%0,%2"
7905 [(set_attr "op_type" "RRE,RRF,RXY")
7906 (set_attr "cpu_facility" "*,z196,*")
7907 (set_attr "z10prop" "z10_super_E1,*,z10_super_E1")])
7908
7909 (define_insn "*xordi3_cconly"
7910 [(set (reg CC_REGNUM)
7911 (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,d,0")
7912 (match_operand:DI 2 "general_operand" " d,d,T"))
7913 (const_int 0)))
7914 (clobber (match_scratch:DI 0 "=d,d,d"))]
7915 "s390_match_ccmode(insn, CCTmode) && TARGET_ZARCH"
7916 "@
7917 xgr\t%0,%2
7918 xgrk\t%0,%1,%2
7919 xg\t%0,%2"
7920 [(set_attr "op_type" "RRE,RRF,RXY")
7921 (set_attr "cpu_facility" "*,z196,*")
7922 (set_attr "z10prop" "z10_super_E1,*,z10_super_E1")])
7923
7924 (define_insn "*xordi3"
7925 [(set (match_operand:DI 0 "nonimmediate_operand" "=d, d,d,d,d, AQ,Q")
7926 (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0, 0,0,d,0, 0,0")
7927 (match_operand:DI 2 "general_operand" "N0SD0,N1SD0,d,d,T,NxQD0,Q")))
7928 (clobber (reg:CC CC_REGNUM))]
7929 "TARGET_ZARCH && s390_logical_operator_ok_p (operands)"
7930 "@
7931 xihf\t%0,%k2
7932 xilf\t%0,%k2
7933 xgr\t%0,%2
7934 xgrk\t%0,%1,%2
7935 xg\t%0,%2
7936 #
7937 #"
7938 [(set_attr "op_type" "RIL,RIL,RRE,RRF,RXY,SI,SS")
7939 (set_attr "cpu_facility" "extimm,extimm,*,z196,*,*,*")
7940 (set_attr "z10prop" "z10_super_E1,z10_super_E1,z10_super_E1,
7941 *,z10_super_E1,*,*")])
7942
7943 (define_split
7944 [(set (match_operand:DI 0 "s_operand" "")
7945 (xor:DI (match_dup 0) (match_operand:DI 1 "immediate_operand" "")))
7946 (clobber (reg:CC CC_REGNUM))]
7947 "reload_completed"
7948 [(parallel
7949 [(set (match_dup 0) (xor:QI (match_dup 0) (match_dup 1)))
7950 (clobber (reg:CC CC_REGNUM))])]
7951 "s390_narrow_logical_operator (XOR, &operands[0], &operands[1]);")
7952
7953 ;
7954 ; xorsi3 instruction pattern(s).
7955 ;
7956
7957 (define_insn "*xorsi3_cc"
7958 [(set (reg CC_REGNUM)
7959 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,d,0,0")
7960 (match_operand:SI 2 "general_operand" "Os,d,d,R,T"))
7961 (const_int 0)))
7962 (set (match_operand:SI 0 "register_operand" "=d,d,d,d,d")
7963 (xor:SI (match_dup 1) (match_dup 2)))]
7964 "s390_match_ccmode(insn, CCTmode)"
7965 "@
7966 xilf\t%0,%o2
7967 xr\t%0,%2
7968 xrk\t%0,%1,%2
7969 x\t%0,%2
7970 xy\t%0,%2"
7971 [(set_attr "op_type" "RIL,RR,RRF,RX,RXY")
7972 (set_attr "cpu_facility" "*,*,z196,*,longdisp")
7973 (set_attr "z10prop" "z10_super_E1,z10_super_E1,*,
7974 z10_super_E1,z10_super_E1")])
7975
7976 (define_insn "*xorsi3_cconly"
7977 [(set (reg CC_REGNUM)
7978 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,d,0,0")
7979 (match_operand:SI 2 "general_operand" "Os,d,d,R,T"))
7980 (const_int 0)))
7981 (clobber (match_scratch:SI 0 "=d,d,d,d,d"))]
7982 "s390_match_ccmode(insn, CCTmode)"
7983 "@
7984 xilf\t%0,%o2
7985 xr\t%0,%2
7986 xrk\t%0,%1,%2
7987 x\t%0,%2
7988 xy\t%0,%2"
7989 [(set_attr "op_type" "RIL,RR,RRF,RX,RXY")
7990 (set_attr "cpu_facility" "*,*,z196,*,longdisp")
7991 (set_attr "z10prop" "z10_super_E1,z10_super_E1,*,
7992 z10_super_E1,z10_super_E1")])
7993
7994 (define_insn "*xorsi3"
7995 [(set (match_operand:SI 0 "nonimmediate_operand" "=d,d,d,d,d, AQ,Q")
7996 (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,d,0,0, 0,0")
7997 (match_operand:SI 2 "general_operand" "Os,d,d,R,T,NxQS0,Q")))
7998 (clobber (reg:CC CC_REGNUM))]
7999 "s390_logical_operator_ok_p (operands)"
8000 "@
8001 xilf\t%0,%o2
8002 xr\t%0,%2
8003 xrk\t%0,%1,%2
8004 x\t%0,%2
8005 xy\t%0,%2
8006 #
8007 #"
8008 [(set_attr "op_type" "RIL,RR,RRF,RX,RXY,SI,SS")
8009 (set_attr "cpu_facility" "*,*,z196,*,longdisp,*,*")
8010 (set_attr "z10prop" "z10_super_E1,z10_super_E1,*,
8011 z10_super_E1,z10_super_E1,*,*")])
8012
8013 (define_split
8014 [(set (match_operand:SI 0 "s_operand" "")
8015 (xor:SI (match_dup 0) (match_operand:SI 1 "immediate_operand" "")))
8016 (clobber (reg:CC CC_REGNUM))]
8017 "reload_completed"
8018 [(parallel
8019 [(set (match_dup 0) (xor:QI (match_dup 0) (match_dup 1)))
8020 (clobber (reg:CC CC_REGNUM))])]
8021 "s390_narrow_logical_operator (XOR, &operands[0], &operands[1]);")
8022
8023 ;
8024 ; xorhi3 instruction pattern(s).
8025 ;
8026
8027 (define_insn "*xorhi3"
8028 [(set (match_operand:HI 0 "nonimmediate_operand" "=d,d,d, AQ,Q")
8029 (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,d, 0,0")
8030 (match_operand:HI 2 "general_operand" "Os,d,d,NxQH0,Q")))
8031 (clobber (reg:CC CC_REGNUM))]
8032 "s390_logical_operator_ok_p (operands)"
8033 "@
8034 xilf\t%0,%x2
8035 xr\t%0,%2
8036 xrk\t%0,%1,%2
8037 #
8038 #"
8039 [(set_attr "op_type" "RIL,RR,RRF,SI,SS")
8040 (set_attr "cpu_facility" "*,*,z196,*,*")
8041 (set_attr "z10prop" "z10_super_E1,z10_super_E1,*,*,*")])
8042
8043 (define_split
8044 [(set (match_operand:HI 0 "s_operand" "")
8045 (xor:HI (match_dup 0) (match_operand:HI 1 "immediate_operand" "")))
8046 (clobber (reg:CC CC_REGNUM))]
8047 "reload_completed"
8048 [(parallel
8049 [(set (match_dup 0) (xor:QI (match_dup 0) (match_dup 1)))
8050 (clobber (reg:CC CC_REGNUM))])]
8051 "s390_narrow_logical_operator (XOR, &operands[0], &operands[1]);")
8052
8053 ;
8054 ; xorqi3 instruction pattern(s).
8055 ;
8056
8057 (define_insn "*xorqi3"
8058 [(set (match_operand:QI 0 "nonimmediate_operand" "=d,d,d,Q,S,Q")
8059 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,d,0,0,0")
8060 (match_operand:QI 2 "general_operand" "Os,d,d,n,n,Q")))
8061 (clobber (reg:CC CC_REGNUM))]
8062 "s390_logical_operator_ok_p (operands)"
8063 "@
8064 xilf\t%0,%b2
8065 xr\t%0,%2
8066 xrk\t%0,%1,%2
8067 xi\t%S0,%b2
8068 xiy\t%S0,%b2
8069 #"
8070 [(set_attr "op_type" "RIL,RR,RRF,SI,SIY,SS")
8071 (set_attr "cpu_facility" "*,*,z196,*,longdisp,*")
8072 (set_attr "z10prop" "z10_super_E1,z10_super_E1,*,z10_super,z10_super,*")])
8073
8074
8075 ;
8076 ; Block exclusive or (XC) patterns.
8077 ;
8078
8079 (define_insn "*xc"
8080 [(set (match_operand:BLK 0 "memory_operand" "=Q")
8081 (xor:BLK (match_dup 0)
8082 (match_operand:BLK 1 "memory_operand" "Q")))
8083 (use (match_operand 2 "const_int_operand" "n"))
8084 (clobber (reg:CC CC_REGNUM))]
8085 "INTVAL (operands[2]) >= 1 && INTVAL (operands[2]) <= 256"
8086 "xc\t%O0(%2,%R0),%S1"
8087 [(set_attr "op_type" "SS")])
8088
8089 (define_split
8090 [(set (match_operand 0 "memory_operand" "")
8091 (xor (match_dup 0)
8092 (match_operand 1 "memory_operand" "")))
8093 (clobber (reg:CC CC_REGNUM))]
8094 "reload_completed
8095 && GET_MODE (operands[0]) == GET_MODE (operands[1])
8096 && GET_MODE_SIZE (GET_MODE (operands[0])) > 0"
8097 [(parallel
8098 [(set (match_dup 0) (xor:BLK (match_dup 0) (match_dup 1)))
8099 (use (match_dup 2))
8100 (clobber (reg:CC CC_REGNUM))])]
8101 {
8102 operands[2] = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[0])));
8103 operands[0] = adjust_address (operands[0], BLKmode, 0);
8104 operands[1] = adjust_address (operands[1], BLKmode, 0);
8105 })
8106
8107 (define_peephole2
8108 [(parallel
8109 [(set (match_operand:BLK 0 "memory_operand" "")
8110 (xor:BLK (match_dup 0)
8111 (match_operand:BLK 1 "memory_operand" "")))
8112 (use (match_operand 2 "const_int_operand" ""))
8113 (clobber (reg:CC CC_REGNUM))])
8114 (parallel
8115 [(set (match_operand:BLK 3 "memory_operand" "")
8116 (xor:BLK (match_dup 3)
8117 (match_operand:BLK 4 "memory_operand" "")))
8118 (use (match_operand 5 "const_int_operand" ""))
8119 (clobber (reg:CC CC_REGNUM))])]
8120 "s390_offset_p (operands[0], operands[3], operands[2])
8121 && s390_offset_p (operands[1], operands[4], operands[2])
8122 && !s390_overlap_p (operands[0], operands[1],
8123 INTVAL (operands[2]) + INTVAL (operands[5]))
8124 && INTVAL (operands[2]) + INTVAL (operands[5]) <= 256"
8125 [(parallel
8126 [(set (match_dup 6) (xor:BLK (match_dup 6) (match_dup 7)))
8127 (use (match_dup 8))
8128 (clobber (reg:CC CC_REGNUM))])]
8129 "operands[6] = gen_rtx_MEM (BLKmode, XEXP (operands[0], 0));
8130 operands[7] = gen_rtx_MEM (BLKmode, XEXP (operands[1], 0));
8131 operands[8] = GEN_INT (INTVAL (operands[2]) + INTVAL (operands[5]));")
8132
8133 ;
8134 ; Block xor (XC) patterns with src == dest.
8135 ;
8136
8137 (define_insn "*xc_zero"
8138 [(set (match_operand:BLK 0 "memory_operand" "=Q")
8139 (const_int 0))
8140 (use (match_operand 1 "const_int_operand" "n"))
8141 (clobber (reg:CC CC_REGNUM))]
8142 "INTVAL (operands[1]) >= 1 && INTVAL (operands[1]) <= 256"
8143 "xc\t%O0(%1,%R0),%S0"
8144 [(set_attr "op_type" "SS")
8145 (set_attr "z196prop" "z196_cracked")])
8146
8147 (define_peephole2
8148 [(parallel
8149 [(set (match_operand:BLK 0 "memory_operand" "")
8150 (const_int 0))
8151 (use (match_operand 1 "const_int_operand" ""))
8152 (clobber (reg:CC CC_REGNUM))])
8153 (parallel
8154 [(set (match_operand:BLK 2 "memory_operand" "")
8155 (const_int 0))
8156 (use (match_operand 3 "const_int_operand" ""))
8157 (clobber (reg:CC CC_REGNUM))])]
8158 "s390_offset_p (operands[0], operands[2], operands[1])
8159 && INTVAL (operands[1]) + INTVAL (operands[3]) <= 256"
8160 [(parallel
8161 [(set (match_dup 4) (const_int 0))
8162 (use (match_dup 5))
8163 (clobber (reg:CC CC_REGNUM))])]
8164 "operands[4] = gen_rtx_MEM (BLKmode, XEXP (operands[0], 0));
8165 operands[5] = GEN_INT (INTVAL (operands[1]) + INTVAL (operands[3]));")
8166
8167
8168 ;;
8169 ;;- Negate instructions.
8170 ;;
8171
8172 ;
8173 ; neg(di|si)2 instruction pattern(s).
8174 ;
8175
8176 (define_expand "neg<mode>2"
8177 [(parallel
8178 [(set (match_operand:DSI 0 "register_operand" "=d")
8179 (neg:DSI (match_operand:DSI 1 "register_operand" "d")))
8180 (clobber (reg:CC CC_REGNUM))])]
8181 ""
8182 "")
8183
8184 (define_insn "*negdi2_sign_cc"
8185 [(set (reg CC_REGNUM)
8186 (compare (neg:DI (ashiftrt:DI (ashift:DI (subreg:DI
8187 (match_operand:SI 1 "register_operand" "d") 0)
8188 (const_int 32)) (const_int 32)))
8189 (const_int 0)))
8190 (set (match_operand:DI 0 "register_operand" "=d")
8191 (neg:DI (sign_extend:DI (match_dup 1))))]
8192 "TARGET_ZARCH && s390_match_ccmode (insn, CCAmode)"
8193 "lcgfr\t%0,%1"
8194 [(set_attr "op_type" "RRE")
8195 (set_attr "z10prop" "z10_c")])
8196
8197 (define_insn "*negdi2_sign"
8198 [(set (match_operand:DI 0 "register_operand" "=d")
8199 (neg:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "d"))))
8200 (clobber (reg:CC CC_REGNUM))]
8201 "TARGET_ZARCH"
8202 "lcgfr\t%0,%1"
8203 [(set_attr "op_type" "RRE")
8204 (set_attr "z10prop" "z10_c")])
8205
8206 ; lcr, lcgr
8207 (define_insn "*neg<mode>2_cc"
8208 [(set (reg CC_REGNUM)
8209 (compare (neg:GPR (match_operand:GPR 1 "register_operand" "d"))
8210 (const_int 0)))
8211 (set (match_operand:GPR 0 "register_operand" "=d")
8212 (neg:GPR (match_dup 1)))]
8213 "s390_match_ccmode (insn, CCAmode)"
8214 "lc<g>r\t%0,%1"
8215 [(set_attr "op_type" "RR<E>")
8216 (set_attr "z10prop" "z10_super_c_E1")])
8217
8218 ; lcr, lcgr
8219 (define_insn "*neg<mode>2_cconly"
8220 [(set (reg CC_REGNUM)
8221 (compare (neg:GPR (match_operand:GPR 1 "register_operand" "d"))
8222 (const_int 0)))
8223 (clobber (match_scratch:GPR 0 "=d"))]
8224 "s390_match_ccmode (insn, CCAmode)"
8225 "lc<g>r\t%0,%1"
8226 [(set_attr "op_type" "RR<E>")
8227 (set_attr "z10prop" "z10_super_c_E1")])
8228
8229 ; lcr, lcgr
8230 (define_insn "*neg<mode>2"
8231 [(set (match_operand:GPR 0 "register_operand" "=d")
8232 (neg:GPR (match_operand:GPR 1 "register_operand" "d")))
8233 (clobber (reg:CC CC_REGNUM))]
8234 ""
8235 "lc<g>r\t%0,%1"
8236 [(set_attr "op_type" "RR<E>")
8237 (set_attr "z10prop" "z10_super_c_E1")])
8238
8239 (define_insn "*negdi2_31"
8240 [(set (match_operand:DI 0 "register_operand" "=d")
8241 (neg:DI (match_operand:DI 1 "register_operand" "d")))
8242 (clobber (reg:CC CC_REGNUM))]
8243 "!TARGET_ZARCH"
8244 "#")
8245
8246 ; Split a DImode NEG on 31bit into 2 SImode NEGs
8247
8248 ; Doing the twos complement separately on the SImode parts does an
8249 ; unwanted +1 on the high part which needs to be subtracted afterwards
8250 ; ... unless the +1 on the low part created an overflow.
8251
8252 (define_split
8253 [(set (match_operand:DI 0 "register_operand" "")
8254 (neg:DI (match_operand:DI 1 "register_operand" "")))
8255 (clobber (reg:CC CC_REGNUM))]
8256 "!TARGET_ZARCH
8257 && (REGNO (operands[0]) == REGNO (operands[1])
8258 || s390_split_ok_p (operands[0], operands[1], DImode, 0))
8259 && reload_completed"
8260 [(parallel
8261 [(set (match_dup 2) (neg:SI (match_dup 3)))
8262 (clobber (reg:CC CC_REGNUM))])
8263 (parallel
8264 [(set (reg:CCAP CC_REGNUM)
8265 (compare:CCAP (neg:SI (match_dup 5)) (const_int 0)))
8266 (set (match_dup 4) (neg:SI (match_dup 5)))])
8267 (set (pc)
8268 (if_then_else (ne (reg:CCAP CC_REGNUM) (const_int 0))
8269 (pc)
8270 (label_ref (match_dup 6))))
8271 (parallel
8272 [(set (match_dup 2) (plus:SI (match_dup 2) (const_int -1)))
8273 (clobber (reg:CC CC_REGNUM))])
8274 (match_dup 6)]
8275 "operands[2] = operand_subword (operands[0], 0, 0, DImode);
8276 operands[3] = operand_subword (operands[1], 0, 0, DImode);
8277 operands[4] = operand_subword (operands[0], 1, 0, DImode);
8278 operands[5] = operand_subword (operands[1], 1, 0, DImode);
8279 operands[6] = gen_label_rtx ();")
8280
8281 ; Like above but first make a copy of the low part of the src operand
8282 ; since it might overlap with the high part of the destination.
8283
8284 (define_split
8285 [(set (match_operand:DI 0 "register_operand" "")
8286 (neg:DI (match_operand:DI 1 "register_operand" "")))
8287 (clobber (reg:CC CC_REGNUM))]
8288 "!TARGET_ZARCH
8289 && s390_split_ok_p (operands[0], operands[1], DImode, 1)
8290 && reload_completed"
8291 [; Make a backup of op5 first
8292 (set (match_dup 4) (match_dup 5))
8293 ; Setting op2 here might clobber op5
8294 (parallel
8295 [(set (match_dup 2) (neg:SI (match_dup 3)))
8296 (clobber (reg:CC CC_REGNUM))])
8297 (parallel
8298 [(set (reg:CCAP CC_REGNUM)
8299 (compare:CCAP (neg:SI (match_dup 4)) (const_int 0)))
8300 (set (match_dup 4) (neg:SI (match_dup 4)))])
8301 (set (pc)
8302 (if_then_else (ne (reg:CCAP CC_REGNUM) (const_int 0))
8303 (pc)
8304 (label_ref (match_dup 6))))
8305 (parallel
8306 [(set (match_dup 2) (plus:SI (match_dup 2) (const_int -1)))
8307 (clobber (reg:CC CC_REGNUM))])
8308 (match_dup 6)]
8309 "operands[2] = operand_subword (operands[0], 0, 0, DImode);
8310 operands[3] = operand_subword (operands[1], 0, 0, DImode);
8311 operands[4] = operand_subword (operands[0], 1, 0, DImode);
8312 operands[5] = operand_subword (operands[1], 1, 0, DImode);
8313 operands[6] = gen_label_rtx ();")
8314
8315 ;
8316 ; neg(df|sf)2 instruction pattern(s).
8317 ;
8318
8319 (define_expand "neg<mode>2"
8320 [(parallel
8321 [(set (match_operand:BFP 0 "register_operand" "=f")
8322 (neg:BFP (match_operand:BFP 1 "register_operand" "f")))
8323 (clobber (reg:CC CC_REGNUM))])]
8324 "TARGET_HARD_FLOAT"
8325 "")
8326
8327 ; lcxbr, lcdbr, lcebr
8328 (define_insn "*neg<mode>2_cc"
8329 [(set (reg CC_REGNUM)
8330 (compare (neg:BFP (match_operand:BFP 1 "register_operand" "f"))
8331 (match_operand:BFP 2 "const0_operand" "")))
8332 (set (match_operand:BFP 0 "register_operand" "=f")
8333 (neg:BFP (match_dup 1)))]
8334 "s390_match_ccmode (insn, CCSmode) && TARGET_HARD_FLOAT"
8335 "lc<xde>br\t%0,%1"
8336 [(set_attr "op_type" "RRE")
8337 (set_attr "type" "fsimp<mode>")])
8338
8339 ; lcxbr, lcdbr, lcebr
8340 (define_insn "*neg<mode>2_cconly"
8341 [(set (reg CC_REGNUM)
8342 (compare (neg:BFP (match_operand:BFP 1 "register_operand" "f"))
8343 (match_operand:BFP 2 "const0_operand" "")))
8344 (clobber (match_scratch:BFP 0 "=f"))]
8345 "s390_match_ccmode (insn, CCSmode) && TARGET_HARD_FLOAT"
8346 "lc<xde>br\t%0,%1"
8347 [(set_attr "op_type" "RRE")
8348 (set_attr "type" "fsimp<mode>")])
8349
8350 ; lcdfr
8351 (define_insn "*neg<mode>2_nocc"
8352 [(set (match_operand:FP 0 "register_operand" "=f")
8353 (neg:FP (match_operand:FP 1 "register_operand" "<fT0>")))]
8354 "TARGET_DFP"
8355 "lcdfr\t%0,%1"
8356 [(set_attr "op_type" "RRE")
8357 (set_attr "type" "fsimp<mode>")])
8358
8359 ; lcxbr, lcdbr, lcebr
8360 ; FIXME: wflcdb does not clobber cc
8361 (define_insn "*neg<mode>2"
8362 [(set (match_operand:BFP 0 "register_operand" "=f,v")
8363 (neg:BFP (match_operand:BFP 1 "register_operand" "f,v")))
8364 (clobber (reg:CC CC_REGNUM))]
8365 "TARGET_HARD_FLOAT"
8366 "@
8367 lc<xde>br\t%0,%1
8368 wflcdb\t%0,%1"
8369 [(set_attr "op_type" "RRE,VRR")
8370 (set_attr "cpu_facility" "*,vx")
8371 (set_attr "type" "fsimp<mode>,*")
8372 (set_attr "enabled" "*,<DFDI>")])
8373
8374
8375 ;;
8376 ;;- Absolute value instructions.
8377 ;;
8378
8379 ;
8380 ; abs(di|si)2 instruction pattern(s).
8381 ;
8382
8383 (define_insn "*absdi2_sign_cc"
8384 [(set (reg CC_REGNUM)
8385 (compare (abs:DI (ashiftrt:DI (ashift:DI (subreg:DI
8386 (match_operand:SI 1 "register_operand" "d") 0)
8387 (const_int 32)) (const_int 32)))
8388 (const_int 0)))
8389 (set (match_operand:DI 0 "register_operand" "=d")
8390 (abs:DI (sign_extend:DI (match_dup 1))))]
8391 "TARGET_ZARCH && s390_match_ccmode (insn, CCAmode)"
8392 "lpgfr\t%0,%1"
8393 [(set_attr "op_type" "RRE")
8394 (set_attr "z10prop" "z10_c")])
8395
8396 (define_insn "*absdi2_sign"
8397 [(set (match_operand:DI 0 "register_operand" "=d")
8398 (abs:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "d"))))
8399 (clobber (reg:CC CC_REGNUM))]
8400 "TARGET_ZARCH"
8401 "lpgfr\t%0,%1"
8402 [(set_attr "op_type" "RRE")
8403 (set_attr "z10prop" "z10_c")])
8404
8405 ; lpr, lpgr
8406 (define_insn "*abs<mode>2_cc"
8407 [(set (reg CC_REGNUM)
8408 (compare (abs:GPR (match_operand:DI 1 "register_operand" "d"))
8409 (const_int 0)))
8410 (set (match_operand:GPR 0 "register_operand" "=d")
8411 (abs:GPR (match_dup 1)))]
8412 "s390_match_ccmode (insn, CCAmode)"
8413 "lp<g>r\t%0,%1"
8414 [(set_attr "op_type" "RR<E>")
8415 (set_attr "z10prop" "z10_c")])
8416
8417 ; lpr, lpgr
8418 (define_insn "*abs<mode>2_cconly"
8419 [(set (reg CC_REGNUM)
8420 (compare (abs:GPR (match_operand:GPR 1 "register_operand" "d"))
8421 (const_int 0)))
8422 (clobber (match_scratch:GPR 0 "=d"))]
8423 "s390_match_ccmode (insn, CCAmode)"
8424 "lp<g>r\t%0,%1"
8425 [(set_attr "op_type" "RR<E>")
8426 (set_attr "z10prop" "z10_c")])
8427
8428 ; lpr, lpgr
8429 (define_insn "abs<mode>2"
8430 [(set (match_operand:GPR 0 "register_operand" "=d")
8431 (abs:GPR (match_operand:GPR 1 "register_operand" "d")))
8432 (clobber (reg:CC CC_REGNUM))]
8433 ""
8434 "lp<g>r\t%0,%1"
8435 [(set_attr "op_type" "RR<E>")
8436 (set_attr "z10prop" "z10_c")])
8437
8438 ;
8439 ; abs(df|sf)2 instruction pattern(s).
8440 ;
8441
8442 (define_expand "abs<mode>2"
8443 [(parallel
8444 [(set (match_operand:BFP 0 "register_operand" "=f")
8445 (abs:BFP (match_operand:BFP 1 "register_operand" "f")))
8446 (clobber (reg:CC CC_REGNUM))])]
8447 "TARGET_HARD_FLOAT"
8448 "")
8449
8450 ; lpxbr, lpdbr, lpebr
8451 (define_insn "*abs<mode>2_cc"
8452 [(set (reg CC_REGNUM)
8453 (compare (abs:BFP (match_operand:BFP 1 "register_operand" "f"))
8454 (match_operand:BFP 2 "const0_operand" "")))
8455 (set (match_operand:BFP 0 "register_operand" "=f")
8456 (abs:BFP (match_dup 1)))]
8457 "s390_match_ccmode (insn, CCSmode) && TARGET_HARD_FLOAT"
8458 "lp<xde>br\t%0,%1"
8459 [(set_attr "op_type" "RRE")
8460 (set_attr "type" "fsimp<mode>")])
8461
8462 ; lpxbr, lpdbr, lpebr
8463 (define_insn "*abs<mode>2_cconly"
8464 [(set (reg CC_REGNUM)
8465 (compare (abs:BFP (match_operand:BFP 1 "register_operand" "f"))
8466 (match_operand:BFP 2 "const0_operand" "")))
8467 (clobber (match_scratch:BFP 0 "=f"))]
8468 "s390_match_ccmode (insn, CCSmode) && TARGET_HARD_FLOAT"
8469 "lp<xde>br\t%0,%1"
8470 [(set_attr "op_type" "RRE")
8471 (set_attr "type" "fsimp<mode>")])
8472
8473 ; lpdfr
8474 (define_insn "*abs<mode>2_nocc"
8475 [(set (match_operand:FP 0 "register_operand" "=f")
8476 (abs:FP (match_operand:FP 1 "register_operand" "<fT0>")))]
8477 "TARGET_DFP"
8478 "lpdfr\t%0,%1"
8479 [(set_attr "op_type" "RRE")
8480 (set_attr "type" "fsimp<mode>")])
8481
8482 ; lpxbr, lpdbr, lpebr
8483 ; FIXME: wflpdb does not clobber cc
8484 (define_insn "*abs<mode>2"
8485 [(set (match_operand:BFP 0 "register_operand" "=f,v")
8486 (abs:BFP (match_operand:BFP 1 "register_operand" "f,v")))
8487 (clobber (reg:CC CC_REGNUM))]
8488 "TARGET_HARD_FLOAT"
8489 "@
8490 lp<xde>br\t%0,%1
8491 wflpdb\t%0,%1"
8492 [(set_attr "op_type" "RRE,VRR")
8493 (set_attr "cpu_facility" "*,vx")
8494 (set_attr "type" "fsimp<mode>,*")
8495 (set_attr "enabled" "*,<DFDI>")])
8496
8497
8498 ;;
8499 ;;- Negated absolute value instructions
8500 ;;
8501
8502 ;
8503 ; Integer
8504 ;
8505
8506 (define_insn "*negabsdi2_sign_cc"
8507 [(set (reg CC_REGNUM)
8508 (compare (neg:DI (abs:DI (ashiftrt:DI (ashift:DI (subreg:DI
8509 (match_operand:SI 1 "register_operand" "d") 0)
8510 (const_int 32)) (const_int 32))))
8511 (const_int 0)))
8512 (set (match_operand:DI 0 "register_operand" "=d")
8513 (neg:DI (abs:DI (sign_extend:DI (match_dup 1)))))]
8514 "TARGET_ZARCH && s390_match_ccmode (insn, CCAmode)"
8515 "lngfr\t%0,%1"
8516 [(set_attr "op_type" "RRE")
8517 (set_attr "z10prop" "z10_c")])
8518
8519 (define_insn "*negabsdi2_sign"
8520 [(set (match_operand:DI 0 "register_operand" "=d")
8521 (neg:DI (abs:DI (sign_extend:DI
8522 (match_operand:SI 1 "register_operand" "d")))))
8523 (clobber (reg:CC CC_REGNUM))]
8524 "TARGET_ZARCH"
8525 "lngfr\t%0,%1"
8526 [(set_attr "op_type" "RRE")
8527 (set_attr "z10prop" "z10_c")])
8528
8529 ; lnr, lngr
8530 (define_insn "*negabs<mode>2_cc"
8531 [(set (reg CC_REGNUM)
8532 (compare (neg:GPR (abs:GPR (match_operand:GPR 1 "register_operand" "d")))
8533 (const_int 0)))
8534 (set (match_operand:GPR 0 "register_operand" "=d")
8535 (neg:GPR (abs:GPR (match_dup 1))))]
8536 "s390_match_ccmode (insn, CCAmode)"
8537 "ln<g>r\t%0,%1"
8538 [(set_attr "op_type" "RR<E>")
8539 (set_attr "z10prop" "z10_c")])
8540
8541 ; lnr, lngr
8542 (define_insn "*negabs<mode>2_cconly"
8543 [(set (reg CC_REGNUM)
8544 (compare (neg:GPR (abs:GPR (match_operand:GPR 1 "register_operand" "d")))
8545 (const_int 0)))
8546 (clobber (match_scratch:GPR 0 "=d"))]
8547 "s390_match_ccmode (insn, CCAmode)"
8548 "ln<g>r\t%0,%1"
8549 [(set_attr "op_type" "RR<E>")
8550 (set_attr "z10prop" "z10_c")])
8551
8552 ; lnr, lngr
8553 (define_insn "*negabs<mode>2"
8554 [(set (match_operand:GPR 0 "register_operand" "=d")
8555 (neg:GPR (abs:GPR (match_operand:GPR 1 "register_operand" "d"))))
8556 (clobber (reg:CC CC_REGNUM))]
8557 ""
8558 "ln<g>r\t%0,%1"
8559 [(set_attr "op_type" "RR<E>")
8560 (set_attr "z10prop" "z10_c")])
8561
8562 ;
8563 ; Floating point
8564 ;
8565
8566 ; lnxbr, lndbr, lnebr
8567 (define_insn "*negabs<mode>2_cc"
8568 [(set (reg CC_REGNUM)
8569 (compare (neg:BFP (abs:BFP (match_operand:BFP 1 "register_operand" "f")))
8570 (match_operand:BFP 2 "const0_operand" "")))
8571 (set (match_operand:BFP 0 "register_operand" "=f")
8572 (neg:BFP (abs:BFP (match_dup 1))))]
8573 "s390_match_ccmode (insn, CCSmode) && TARGET_HARD_FLOAT"
8574 "ln<xde>br\t%0,%1"
8575 [(set_attr "op_type" "RRE")
8576 (set_attr "type" "fsimp<mode>")])
8577
8578 ; lnxbr, lndbr, lnebr
8579 (define_insn "*negabs<mode>2_cconly"
8580 [(set (reg CC_REGNUM)
8581 (compare (neg:BFP (abs:BFP (match_operand:BFP 1 "register_operand" "f")))
8582 (match_operand:BFP 2 "const0_operand" "")))
8583 (clobber (match_scratch:BFP 0 "=f"))]
8584 "s390_match_ccmode (insn, CCSmode) && TARGET_HARD_FLOAT"
8585 "ln<xde>br\t%0,%1"
8586 [(set_attr "op_type" "RRE")
8587 (set_attr "type" "fsimp<mode>")])
8588
8589 ; lndfr
8590 (define_insn "*negabs<mode>2_nocc"
8591 [(set (match_operand:FP 0 "register_operand" "=f")
8592 (neg:FP (abs:FP (match_operand:BFP 1 "register_operand" "<fT0>"))))]
8593 "TARGET_DFP"
8594 "lndfr\t%0,%1"
8595 [(set_attr "op_type" "RRE")
8596 (set_attr "type" "fsimp<mode>")])
8597
8598 ; lnxbr, lndbr, lnebr
8599 ; FIXME: wflndb does not clobber cc
8600 (define_insn "*negabs<mode>2"
8601 [(set (match_operand:BFP 0 "register_operand" "=f,v")
8602 (neg:BFP (abs:BFP (match_operand:BFP 1 "register_operand" "f,v"))))
8603 (clobber (reg:CC CC_REGNUM))]
8604 "TARGET_HARD_FLOAT"
8605 "@
8606 ln<xde>br\t%0,%1
8607 wflndb\t%0,%1"
8608 [(set_attr "op_type" "RRE,VRR")
8609 (set_attr "cpu_facility" "*,vx")
8610 (set_attr "type" "fsimp<mode>,*")
8611 (set_attr "enabled" "*,<DFDI>")])
8612
8613 ;;
8614 ;;- Square root instructions.
8615 ;;
8616
8617 ;
8618 ; sqrt(df|sf)2 instruction pattern(s).
8619 ;
8620
8621 ; sqxbr, sqdbr, sqebr, sqdb, sqeb
8622 (define_insn "sqrt<mode>2"
8623 [(set (match_operand:BFP 0 "register_operand" "=f,f,v")
8624 (sqrt:BFP (match_operand:BFP 1 "general_operand" "f,R,v")))]
8625 "TARGET_HARD_FLOAT"
8626 "@
8627 sq<xde>br\t%0,%1
8628 sq<xde>b\t%0,%1
8629 wfsqdb\t%v0,%v1"
8630 [(set_attr "op_type" "RRE,RXE,VRR")
8631 (set_attr "type" "fsqrt<mode>")
8632 (set_attr "cpu_facility" "*,*,vx")
8633 (set_attr "enabled" "*,<DSF>,<DFDI>")])
8634
8635
8636 ;;
8637 ;;- One complement instructions.
8638 ;;
8639
8640 ;
8641 ; one_cmpl(di|si|hi|qi)2 instruction pattern(s).
8642 ;
8643
8644 (define_expand "one_cmpl<mode>2"
8645 [(parallel
8646 [(set (match_operand:INT 0 "register_operand" "")
8647 (xor:INT (match_operand:INT 1 "register_operand" "")
8648 (const_int -1)))
8649 (clobber (reg:CC CC_REGNUM))])]
8650 ""
8651 "")
8652
8653
8654 ;;
8655 ;; Find leftmost bit instructions.
8656 ;;
8657
8658 (define_expand "clzdi2"
8659 [(set (match_operand:DI 0 "register_operand" "=d")
8660 (clz:DI (match_operand:DI 1 "register_operand" "d")))]
8661 "TARGET_EXTIMM && TARGET_ZARCH"
8662 {
8663 rtx_insn *insn;
8664 rtx clz_equal;
8665 rtx wide_reg = gen_reg_rtx (TImode);
8666 rtx msb = gen_rtx_CONST_INT (DImode, HOST_WIDE_INT_1U << 63);
8667
8668 clz_equal = gen_rtx_CLZ (DImode, operands[1]);
8669
8670 emit_insn (gen_clztidi2 (wide_reg, operands[1], msb));
8671
8672 insn = emit_move_insn (operands[0], gen_highpart (DImode, wide_reg));
8673 set_unique_reg_note (insn, REG_EQUAL, clz_equal);
8674
8675 DONE;
8676 })
8677
8678 (define_insn "clztidi2"
8679 [(set (match_operand:TI 0 "register_operand" "=d")
8680 (ior:TI
8681 (ashift:TI
8682 (zero_extend:TI
8683 (xor:DI (match_operand:DI 1 "register_operand" "d")
8684 (lshiftrt (match_operand:DI 2 "const_int_operand" "")
8685 (subreg:SI (clz:DI (match_dup 1)) 4))))
8686
8687 (const_int 64))
8688 (zero_extend:TI (clz:DI (match_dup 1)))))
8689 (clobber (reg:CC CC_REGNUM))]
8690 "UINTVAL (operands[2]) == HOST_WIDE_INT_1U << 63
8691 && TARGET_EXTIMM && TARGET_ZARCH"
8692 "flogr\t%0,%1"
8693 [(set_attr "op_type" "RRE")])
8694
8695
8696 ;;
8697 ;;- Rotate instructions.
8698 ;;
8699
8700 ;
8701 ; rotl(di|si)3 instruction pattern(s).
8702 ;
8703
8704 (define_expand "rotl<mode>3"
8705 [(set (match_operand:GPR 0 "register_operand" "")
8706 (rotate:GPR (match_operand:GPR 1 "register_operand" "")
8707 (match_operand:SI 2 "nonmemory_operand" "")))]
8708 "TARGET_CPU_ZARCH"
8709 "")
8710
8711 ; rll, rllg
8712 (define_insn "*rotl<mode>3<addr_style_op><masked_op>"
8713 [(set (match_operand:GPR 0 "register_operand" "=d")
8714 (rotate:GPR (match_operand:GPR 1 "register_operand" "d")
8715 (match_operand:SI 2 "nonmemory_operand" "an")))]
8716 "TARGET_CPU_ZARCH"
8717 "rll<g>\t%0,%1,<addr_style_op_ops>"
8718 [(set_attr "op_type" "RSE")
8719 (set_attr "atype" "reg")
8720 (set_attr "z10prop" "z10_super_E1")])
8721
8722
8723 ;;
8724 ;;- Shift instructions.
8725 ;;
8726
8727 ;
8728 ; (ashl|lshr)(di|si)3 instruction pattern(s).
8729 ; Left shifts and logical right shifts
8730
8731 (define_expand "<shift><mode>3"
8732 [(set (match_operand:DSI 0 "register_operand" "")
8733 (SHIFT:DSI (match_operand:DSI 1 "register_operand" "")
8734 (match_operand:SI 2 "nonmemory_operand" "")))]
8735 ""
8736 "")
8737
8738 ; ESA 64 bit register pair shift with reg or imm shift count
8739 ; sldl, srdl
8740 (define_insn "*<shift>di3_31<addr_style_op><masked_op>"
8741 [(set (match_operand:DI 0 "register_operand" "=d")
8742 (SHIFT:DI (match_operand:DI 1 "register_operand" "0")
8743 (match_operand:SI 2 "nonmemory_operand" "an")))]
8744 "!TARGET_ZARCH"
8745 "s<lr>dl\t%0,<addr_style_op_ops>"
8746 [(set_attr "op_type" "RS")
8747 (set_attr "atype" "reg")
8748 (set_attr "z196prop" "z196_cracked")])
8749
8750
8751 ; 64 bit register shift with reg or imm shift count
8752 ; sll, srl, sllg, srlg, sllk, srlk
8753 (define_insn "*<shift><mode>3<addr_style_op><masked_op>"
8754 [(set (match_operand:GPR 0 "register_operand" "=d, d")
8755 (SHIFT:GPR (match_operand:GPR 1 "register_operand" "<d0>, d")
8756 (match_operand:SI 2 "nonmemory_operand" "an,an")))]
8757 ""
8758 "@
8759 s<lr>l<g>\t%0,<1><addr_style_op_ops>
8760 s<lr>l<gk>\t%0,%1,<addr_style_op_ops>"
8761 [(set_attr "op_type" "RS<E>,RSY")
8762 (set_attr "atype" "reg,reg")
8763 (set_attr "cpu_facility" "*,z196")
8764 (set_attr "z10prop" "z10_super_E1,*")])
8765
8766 ;
8767 ; ashr(di|si)3 instruction pattern(s).
8768 ; Arithmetic right shifts
8769
8770 (define_expand "ashr<mode>3"
8771 [(parallel
8772 [(set (match_operand:DSI 0 "register_operand" "")
8773 (ashiftrt:DSI (match_operand:DSI 1 "register_operand" "")
8774 (match_operand:SI 2 "nonmemory_operand" "")))
8775 (clobber (reg:CC CC_REGNUM))])]
8776 ""
8777 "")
8778
8779 ; FIXME: The number of alternatives is doubled here to match the fix
8780 ; number of 2 in the subst pattern for the (clobber (match_scratch...
8781 ; The right fix should be to support match_scratch in the output
8782 ; pattern of a define_subst.
8783 (define_insn "*ashrdi3_31<addr_style_op_cc><masked_op_cc><setcc><cconly>"
8784 [(set (match_operand:DI 0 "register_operand" "=d, d")
8785 (ashiftrt:DI (match_operand:DI 1 "register_operand" "0, 0")
8786 (match_operand:SI 2 "nonmemory_operand" "an,an")))
8787 (clobber (reg:CC CC_REGNUM))]
8788 "!TARGET_ZARCH"
8789 "@
8790 srda\t%0,<addr_style_op_cc_ops>
8791 srda\t%0,<addr_style_op_cc_ops>"
8792 [(set_attr "op_type" "RS")
8793 (set_attr "atype" "reg")])
8794
8795
8796 ; sra, srag
8797 (define_insn "*ashr<mode>3<addr_style_op_cc><masked_op_cc><setcc><cconly>"
8798 [(set (match_operand:GPR 0 "register_operand" "=d, d")
8799 (ashiftrt:GPR (match_operand:GPR 1 "register_operand" "<d0>, d")
8800 (match_operand:SI 2 "nonmemory_operand" "an,an")))
8801 (clobber (reg:CC CC_REGNUM))]
8802 ""
8803 "@
8804 sra<g>\t%0,<1><addr_style_op_cc_ops>
8805 sra<gk>\t%0,%1,<addr_style_op_cc_ops>"
8806 [(set_attr "op_type" "RS<E>,RSY")
8807 (set_attr "atype" "reg")
8808 (set_attr "cpu_facility" "*,z196")
8809 (set_attr "z10prop" "z10_super_E1,*")])
8810
8811
8812 ;;
8813 ;; Branch instruction patterns.
8814 ;;
8815
8816 (define_expand "cbranch<mode>4"
8817 [(set (pc)
8818 (if_then_else (match_operator 0 "comparison_operator"
8819 [(match_operand:GPR 1 "register_operand" "")
8820 (match_operand:GPR 2 "general_operand" "")])
8821 (label_ref (match_operand 3 "" ""))
8822 (pc)))]
8823 ""
8824 "s390_emit_jump (operands[3],
8825 s390_emit_compare (GET_CODE (operands[0]), operands[1], operands[2]));
8826 DONE;")
8827
8828 (define_expand "cbranch<mode>4"
8829 [(set (pc)
8830 (if_then_else (match_operator 0 "comparison_operator"
8831 [(match_operand:FP 1 "register_operand" "")
8832 (match_operand:FP 2 "general_operand" "")])
8833 (label_ref (match_operand 3 "" ""))
8834 (pc)))]
8835 "TARGET_HARD_FLOAT"
8836 "s390_emit_jump (operands[3],
8837 s390_emit_compare (GET_CODE (operands[0]), operands[1], operands[2]));
8838 DONE;")
8839
8840 (define_expand "cbranchcc4"
8841 [(set (pc)
8842 (if_then_else (match_operator 0 "s390_comparison"
8843 [(match_operand 1 "cc_reg_operand" "")
8844 (match_operand 2 "const_int_operand" "")])
8845 (label_ref (match_operand 3 "" ""))
8846 (pc)))]
8847 ""
8848 "")
8849
8850
8851 ;;
8852 ;;- Conditional jump instructions.
8853 ;;
8854
8855 (define_insn "*cjump_64"
8856 [(set (pc)
8857 (if_then_else
8858 (match_operator 1 "s390_comparison" [(reg CC_REGNUM)
8859 (match_operand 2 "const_int_operand" "")])
8860 (label_ref (match_operand 0 "" ""))
8861 (pc)))]
8862 "TARGET_CPU_ZARCH"
8863 {
8864 if (get_attr_length (insn) == 4)
8865 return "j%C1\t%l0";
8866 else
8867 return "jg%C1\t%l0";
8868 }
8869 [(set_attr "op_type" "RI")
8870 (set_attr "type" "branch")
8871 (set (attr "length")
8872 (if_then_else (lt (abs (minus (pc) (match_dup 0))) (const_int 60000))
8873 (const_int 4) (const_int 6)))])
8874
8875 (define_insn "*cjump_31"
8876 [(set (pc)
8877 (if_then_else
8878 (match_operator 1 "s390_comparison" [(reg CC_REGNUM)
8879 (match_operand 2 "const_int_operand" "")])
8880 (label_ref (match_operand 0 "" ""))
8881 (pc)))]
8882 "!TARGET_CPU_ZARCH"
8883 {
8884 gcc_assert (get_attr_length (insn) == 4);
8885 return "j%C1\t%l0";
8886 }
8887 [(set_attr "op_type" "RI")
8888 (set_attr "type" "branch")
8889 (set (attr "length")
8890 (if_then_else (not (match_test "flag_pic"))
8891 (if_then_else (lt (abs (minus (pc) (match_dup 0))) (const_int 60000))
8892 (const_int 4) (const_int 6))
8893 (if_then_else (lt (abs (minus (pc) (match_dup 0))) (const_int 60000))
8894 (const_int 4) (const_int 8))))])
8895
8896 (define_insn "*cjump_long"
8897 [(set (pc)
8898 (if_then_else
8899 (match_operator 1 "s390_comparison" [(reg CC_REGNUM) (const_int 0)])
8900 (match_operand 0 "address_operand" "ZQZR")
8901 (pc)))]
8902 ""
8903 {
8904 if (get_attr_op_type (insn) == OP_TYPE_RR)
8905 return "b%C1r\t%0";
8906 else
8907 return "b%C1\t%a0";
8908 }
8909 [(set (attr "op_type")
8910 (if_then_else (match_operand 0 "register_operand" "")
8911 (const_string "RR") (const_string "RX")))
8912 (set_attr "type" "branch")
8913 (set_attr "atype" "agen")])
8914
8915 ;; A conditional return instruction.
8916 (define_insn "*c<code>"
8917 [(set (pc)
8918 (if_then_else
8919 (match_operator 0 "s390_comparison" [(reg CC_REGNUM) (const_int 0)])
8920 (ANY_RETURN)
8921 (pc)))]
8922 "s390_can_use_<code>_insn ()"
8923 "b%C0r\t%%r14"
8924 [(set_attr "op_type" "RR")
8925 (set_attr "type" "jsr")
8926 (set_attr "atype" "agen")])
8927
8928 ;;
8929 ;;- Negated conditional jump instructions.
8930 ;;
8931
8932 (define_insn "*icjump_64"
8933 [(set (pc)
8934 (if_then_else
8935 (match_operator 1 "s390_comparison" [(reg CC_REGNUM) (const_int 0)])
8936 (pc)
8937 (label_ref (match_operand 0 "" ""))))]
8938 "TARGET_CPU_ZARCH"
8939 {
8940 if (get_attr_length (insn) == 4)
8941 return "j%D1\t%l0";
8942 else
8943 return "jg%D1\t%l0";
8944 }
8945 [(set_attr "op_type" "RI")
8946 (set_attr "type" "branch")
8947 (set (attr "length")
8948 (if_then_else (lt (abs (minus (pc) (match_dup 0))) (const_int 60000))
8949 (const_int 4) (const_int 6)))])
8950
8951 (define_insn "*icjump_31"
8952 [(set (pc)
8953 (if_then_else
8954 (match_operator 1 "s390_comparison" [(reg CC_REGNUM) (const_int 0)])
8955 (pc)
8956 (label_ref (match_operand 0 "" ""))))]
8957 "!TARGET_CPU_ZARCH"
8958 {
8959 gcc_assert (get_attr_length (insn) == 4);
8960 return "j%D1\t%l0";
8961 }
8962 [(set_attr "op_type" "RI")
8963 (set_attr "type" "branch")
8964 (set (attr "length")
8965 (if_then_else (not (match_test "flag_pic"))
8966 (if_then_else (lt (abs (minus (pc) (match_dup 0))) (const_int 60000))
8967 (const_int 4) (const_int 6))
8968 (if_then_else (lt (abs (minus (pc) (match_dup 0))) (const_int 60000))
8969 (const_int 4) (const_int 8))))])
8970
8971 (define_insn "*icjump_long"
8972 [(set (pc)
8973 (if_then_else
8974 (match_operator 1 "s390_comparison" [(reg CC_REGNUM) (const_int 0)])
8975 (pc)
8976 (match_operand 0 "address_operand" "ZQZR")))]
8977 ""
8978 {
8979 if (get_attr_op_type (insn) == OP_TYPE_RR)
8980 return "b%D1r\t%0";
8981 else
8982 return "b%D1\t%a0";
8983 }
8984 [(set (attr "op_type")
8985 (if_then_else (match_operand 0 "register_operand" "")
8986 (const_string "RR") (const_string "RX")))
8987 (set_attr "type" "branch")
8988 (set_attr "atype" "agen")])
8989
8990 ;;
8991 ;;- Trap instructions.
8992 ;;
8993
8994 (define_insn "trap"
8995 [(trap_if (const_int 1) (const_int 0))]
8996 ""
8997 "j\t.+2"
8998 [(set_attr "op_type" "RI")
8999 (set_attr "type" "branch")])
9000
9001 (define_expand "ctrap<mode>4"
9002 [(trap_if (match_operator 0 "comparison_operator"
9003 [(match_operand:GPR 1 "register_operand" "")
9004 (match_operand:GPR 2 "general_operand" "")])
9005 (match_operand 3 "const0_operand" ""))]
9006 ""
9007 {
9008 rtx cond = s390_emit_compare (GET_CODE (operands[0]),
9009 operands[1], operands[2]);
9010 emit_insn (gen_condtrap (cond, XEXP (cond, 0)));
9011 DONE;
9012 })
9013
9014 (define_expand "ctrap<mode>4"
9015 [(trap_if (match_operator 0 "comparison_operator"
9016 [(match_operand:FP 1 "register_operand" "")
9017 (match_operand:FP 2 "general_operand" "")])
9018 (match_operand 3 "const0_operand" ""))]
9019 ""
9020 {
9021 rtx cond = s390_emit_compare (GET_CODE (operands[0]),
9022 operands[1], operands[2]);
9023 emit_insn (gen_condtrap (cond, XEXP (cond, 0)));
9024 DONE;
9025 })
9026
9027 (define_insn "condtrap"
9028 [(trap_if (match_operator 0 "s390_comparison"
9029 [(match_operand 1 "cc_reg_operand" "c")
9030 (const_int 0)])
9031 (const_int 0))]
9032 ""
9033 "j%C0\t.+2";
9034 [(set_attr "op_type" "RI")
9035 (set_attr "type" "branch")])
9036
9037 ; crt, cgrt, cit, cgit
9038 (define_insn "*cmp_and_trap_signed_int<mode>"
9039 [(trap_if (match_operator 0 "s390_signed_integer_comparison"
9040 [(match_operand:GPR 1 "register_operand" "d,d")
9041 (match_operand:GPR 2 "nonmemory_operand" "d,K")])
9042 (const_int 0))]
9043 "TARGET_Z10"
9044 "@
9045 c<g>rt%C0\t%1,%2
9046 c<g>it%C0\t%1,%h2"
9047 [(set_attr "op_type" "RRF,RIE")
9048 (set_attr "type" "branch")
9049 (set_attr "z10prop" "z10_super_c,z10_super")])
9050
9051 ; clrt, clgrt, clfit, clgit, clt, clgt
9052 (define_insn "*cmp_and_trap_unsigned_int<mode>"
9053 [(trap_if (match_operator 0 "s390_unsigned_integer_comparison"
9054 [(match_operand:GPR 1 "register_operand" "d,d,d")
9055 (match_operand:GPR 2 "general_operand" "d,D,T")])
9056 (const_int 0))]
9057 "TARGET_Z10"
9058 "@
9059 cl<g>rt%C0\t%1,%2
9060 cl<gf>it%C0\t%1,%x2
9061 cl<g>t%C0\t%1,%2"
9062 [(set_attr "op_type" "RRF,RIE,RSY")
9063 (set_attr "type" "branch")
9064 (set_attr "z10prop" "z10_super_c,z10_super,*")
9065 (set_attr "cpu_facility" "z10,z10,zEC12")])
9066
9067 ; lat, lgat
9068 (define_insn "*load_and_trap<mode>"
9069 [(trap_if (eq (match_operand:GPR 0 "memory_operand" "T")
9070 (const_int 0))
9071 (const_int 0))
9072 (set (match_operand:GPR 1 "register_operand" "=d")
9073 (match_dup 0))]
9074 "TARGET_ZEC12"
9075 "l<g>at\t%1,%0"
9076 [(set_attr "op_type" "RXY")])
9077
9078
9079 ;;
9080 ;;- Loop instructions.
9081 ;;
9082 ;; This is all complicated by the fact that since this is a jump insn
9083 ;; we must handle our own output reloads.
9084
9085 ;; branch on index
9086
9087 ; This splitter will be matched by combine and has to add the 2 moves
9088 ; necessary to load the compare and the increment values into a
9089 ; register pair as needed by brxle.
9090
9091 (define_insn_and_split "*brx_stage1_<GPR:mode>"
9092 [(set (pc)
9093 (if_then_else
9094 (match_operator 6 "s390_brx_operator"
9095 [(plus:GPR (match_operand:GPR 1 "register_operand" "")
9096 (match_operand:GPR 2 "general_operand" ""))
9097 (match_operand:GPR 3 "register_operand" "")])
9098 (label_ref (match_operand 0 "" ""))
9099 (pc)))
9100 (set (match_operand:GPR 4 "nonimmediate_operand" "")
9101 (plus:GPR (match_dup 1) (match_dup 2)))
9102 (clobber (match_scratch:GPR 5 ""))]
9103 "TARGET_CPU_ZARCH"
9104 "#"
9105 "!reload_completed && !reload_in_progress"
9106 [(set (match_dup 7) (match_dup 2)) ; the increment
9107 (set (match_dup 8) (match_dup 3)) ; the comparison value
9108 (parallel [(set (pc)
9109 (if_then_else
9110 (match_op_dup 6
9111 [(plus:GPR (match_dup 1) (match_dup 7))
9112 (match_dup 8)])
9113 (label_ref (match_dup 0))
9114 (pc)))
9115 (set (match_dup 4)
9116 (plus:GPR (match_dup 1) (match_dup 7)))
9117 (clobber (match_dup 5))
9118 (clobber (reg:CC CC_REGNUM))])]
9119 {
9120 rtx dreg = gen_reg_rtx (word_mode == DImode ? TImode : DImode);
9121 operands[7] = gen_lowpart (<GPR:MODE>mode,
9122 gen_highpart (word_mode, dreg));
9123 operands[8] = gen_lowpart (<GPR:MODE>mode,
9124 gen_lowpart (word_mode, dreg));
9125 })
9126
9127 ; brxlg, brxhg
9128
9129 (define_insn_and_split "*brxg_64bit"
9130 [(set (pc)
9131 (if_then_else
9132 (match_operator 5 "s390_brx_operator"
9133 [(plus:DI (match_operand:DI 1 "register_operand" "d,d,d")
9134 (subreg:DI (match_operand:TI 2 "register_operand" "d,d,d") 0))
9135 (subreg:DI (match_dup 2) 8)])
9136 (label_ref (match_operand 0 "" ""))
9137 (pc)))
9138 (set (match_operand:DI 3 "nonimmediate_operand" "=1,?X,?X")
9139 (plus:DI (match_dup 1)
9140 (subreg:DI (match_dup 2) 0)))
9141 (clobber (match_scratch:DI 4 "=X,&1,&?d"))
9142 (clobber (reg:CC CC_REGNUM))]
9143 "TARGET_ZARCH"
9144 {
9145 if (which_alternative != 0)
9146 return "#";
9147 else if (get_attr_length (insn) == 6)
9148 return "brx%E5g\t%1,%2,%l0";
9149 else
9150 return "agr\t%1,%2\;cgr\t%1,%M2\;jg%C5\t%l0";
9151 }
9152 "&& reload_completed
9153 && (!REG_P (operands[3])
9154 || !rtx_equal_p (operands[1], operands[3]))"
9155 [(set (match_dup 4) (match_dup 1))
9156 (parallel [(set (match_dup 4) (plus:DI (match_dup 4) (subreg:DI (match_dup 2) 0)))
9157 (clobber (reg:CC CC_REGNUM))])
9158 (set (reg:CCS CC_REGNUM) (compare:CCS (match_dup 4) (subreg:DI (match_dup 2) 8)))
9159 (set (match_dup 3) (match_dup 4))
9160 (set (pc) (if_then_else (match_op_dup 5 [(reg:CCS CC_REGNUM) (const_int 0)])
9161 (label_ref (match_dup 0))
9162 (pc)))]
9163 ""
9164 [(set_attr "op_type" "RIE")
9165 (set_attr "type" "branch")
9166 (set (attr "length")
9167 (if_then_else (lt (abs (minus (pc) (match_dup 0))) (const_int 60000))
9168 (const_int 6) (const_int 16)))])
9169
9170 ; brxle, brxh
9171
9172 (define_insn_and_split "*brx_64bit"
9173 [(set (pc)
9174 (if_then_else
9175 (match_operator 5 "s390_brx_operator"
9176 [(plus:SI (match_operand:SI 1 "register_operand" "d,d,d")
9177 (subreg:SI (match_operand:TI 2 "register_operand" "d,d,d") 4))
9178 (subreg:SI (match_dup 2) 12)])
9179 (label_ref (match_operand 0 "" ""))
9180 (pc)))
9181 (set (match_operand:SI 3 "nonimmediate_operand" "=1,?X,?X")
9182 (plus:SI (match_dup 1)
9183 (subreg:SI (match_dup 2) 4)))
9184 (clobber (match_scratch:SI 4 "=X,&1,&?d"))
9185 (clobber (reg:CC CC_REGNUM))]
9186 "TARGET_ZARCH"
9187 {
9188 if (which_alternative != 0)
9189 return "#";
9190 else if (get_attr_length (insn) == 6)
9191 return "brx%C5\t%1,%2,%l0";
9192 else
9193 return "ar\t%1,%2\;cr\t%1,%M2\;jg%C5\t%l0";
9194 }
9195 "&& reload_completed
9196 && (!REG_P (operands[3])
9197 || !rtx_equal_p (operands[1], operands[3]))"
9198 [(set (match_dup 4) (match_dup 1))
9199 (parallel [(set (match_dup 4) (plus:SI (match_dup 4) (subreg:SI (match_dup 2) 4)))
9200 (clobber (reg:CC CC_REGNUM))])
9201 (set (reg:CCS CC_REGNUM) (compare:CCS (match_dup 4) (subreg:SI (match_dup 2) 12)))
9202 (set (match_dup 3) (match_dup 4))
9203 (set (pc) (if_then_else (match_op_dup 5 [(reg:CCS CC_REGNUM) (const_int 0)])
9204 (label_ref (match_dup 0))
9205 (pc)))]
9206 ""
9207 [(set_attr "op_type" "RSI")
9208 (set_attr "type" "branch")
9209 (set (attr "length")
9210 (if_then_else (lt (abs (minus (pc) (match_dup 0))) (const_int 60000))
9211 (const_int 6) (const_int 14)))])
9212
9213 ; brxle, brxh
9214
9215 (define_insn_and_split "*brx_31bit"
9216 [(set (pc)
9217 (if_then_else
9218 (match_operator 5 "s390_brx_operator"
9219 [(plus:SI (match_operand:SI 1 "register_operand" "d,d,d")
9220 (subreg:SI (match_operand:DI 2 "register_operand" "d,d,d") 0))
9221 (subreg:SI (match_dup 2) 4)])
9222 (label_ref (match_operand 0 "" ""))
9223 (pc)))
9224 (set (match_operand:SI 3 "nonimmediate_operand" "=1,?X,?X")
9225 (plus:SI (match_dup 1)
9226 (subreg:SI (match_dup 2) 0)))
9227 (clobber (match_scratch:SI 4 "=X,&1,&?d"))
9228 (clobber (reg:CC CC_REGNUM))]
9229 "!TARGET_ZARCH && TARGET_CPU_ZARCH"
9230 {
9231 if (which_alternative != 0)
9232 return "#";
9233 else if (get_attr_length (insn) == 6)
9234 return "brx%C5\t%1,%2,%l0";
9235 else
9236 return "ar\t%1,%2\;cr\t%1,%M2\;jg%C5\t%l0";
9237 }
9238 "&& reload_completed
9239 && (!REG_P (operands[3])
9240 || !rtx_equal_p (operands[1], operands[3]))"
9241 [(set (match_dup 4) (match_dup 1))
9242 (parallel [(set (match_dup 4) (plus:SI (match_dup 4) (subreg:SI (match_dup 2) 0)))
9243 (clobber (reg:CC CC_REGNUM))])
9244 (set (reg:CCS CC_REGNUM) (compare:CCS (match_dup 4) (subreg:SI (match_dup 2) 4)))
9245 (set (match_dup 3) (match_dup 4))
9246 (set (pc) (if_then_else (match_op_dup 5 [(reg:CCS CC_REGNUM) (const_int 0)])
9247 (label_ref (match_dup 0))
9248 (pc)))]
9249 ""
9250 [(set_attr "op_type" "RSI")
9251 (set_attr "type" "branch")
9252 (set (attr "length")
9253 (if_then_else (lt (abs (minus (pc) (match_dup 0))) (const_int 60000))
9254 (const_int 6) (const_int 14)))])
9255
9256
9257 ;; branch on count
9258
9259 (define_expand "doloop_end"
9260 [(use (match_operand 0 "" "")) ; loop pseudo
9261 (use (match_operand 1 "" ""))] ; label
9262 ""
9263 {
9264 if (GET_MODE (operands[0]) == SImode && !TARGET_CPU_ZARCH)
9265 emit_jump_insn (gen_doloop_si31 (operands[1], operands[0], operands[0]));
9266 else if (GET_MODE (operands[0]) == SImode && TARGET_CPU_ZARCH)
9267 emit_jump_insn (gen_doloop_si64 (operands[1], operands[0], operands[0]));
9268 else if (GET_MODE (operands[0]) == DImode && TARGET_ZARCH)
9269 emit_jump_insn (gen_doloop_di (operands[1], operands[0], operands[0]));
9270 else
9271 FAIL;
9272
9273 DONE;
9274 })
9275
9276 (define_insn_and_split "doloop_si64"
9277 [(set (pc)
9278 (if_then_else
9279 (ne (match_operand:SI 1 "register_operand" "d,d,d")
9280 (const_int 1))
9281 (label_ref (match_operand 0 "" ""))
9282 (pc)))
9283 (set (match_operand:SI 2 "nonimmediate_operand" "=1,?X,?X")
9284 (plus:SI (match_dup 1) (const_int -1)))
9285 (clobber (match_scratch:SI 3 "=X,&1,&?d"))
9286 (clobber (reg:CC CC_REGNUM))]
9287 "TARGET_CPU_ZARCH"
9288 {
9289 if (which_alternative != 0)
9290 return "#";
9291 else if (get_attr_length (insn) == 4)
9292 return "brct\t%1,%l0";
9293 else
9294 return "ahi\t%1,-1\;jgne\t%l0";
9295 }
9296 "&& reload_completed
9297 && (! REG_P (operands[2])
9298 || ! rtx_equal_p (operands[1], operands[2]))"
9299 [(set (match_dup 3) (match_dup 1))
9300 (parallel [(set (reg:CCAN CC_REGNUM)
9301 (compare:CCAN (plus:SI (match_dup 3) (const_int -1))
9302 (const_int 0)))
9303 (set (match_dup 3) (plus:SI (match_dup 3) (const_int -1)))])
9304 (set (match_dup 2) (match_dup 3))
9305 (set (pc) (if_then_else (ne (reg:CCAN CC_REGNUM) (const_int 0))
9306 (label_ref (match_dup 0))
9307 (pc)))]
9308 ""
9309 [(set_attr "op_type" "RI")
9310 ; Strictly speaking, the z10 properties are valid for brct only, however, it does not
9311 ; hurt us in the (rare) case of ahi.
9312 (set_attr "z10prop" "z10_super_E1")
9313 (set_attr "type" "branch")
9314 (set (attr "length")
9315 (if_then_else (lt (abs (minus (pc) (match_dup 0))) (const_int 60000))
9316 (const_int 4) (const_int 10)))])
9317
9318 (define_insn_and_split "doloop_si31"
9319 [(set (pc)
9320 (if_then_else
9321 (ne (match_operand:SI 1 "register_operand" "d,d,d")
9322 (const_int 1))
9323 (label_ref (match_operand 0 "" ""))
9324 (pc)))
9325 (set (match_operand:SI 2 "nonimmediate_operand" "=1,?X,?X")
9326 (plus:SI (match_dup 1) (const_int -1)))
9327 (clobber (match_scratch:SI 3 "=X,&1,&?d"))
9328 (clobber (reg:CC CC_REGNUM))]
9329 "!TARGET_CPU_ZARCH"
9330 {
9331 if (which_alternative != 0)
9332 return "#";
9333 else if (get_attr_length (insn) == 4)
9334 return "brct\t%1,%l0";
9335 else
9336 gcc_unreachable ();
9337 }
9338 "&& reload_completed
9339 && (! REG_P (operands[2])
9340 || ! rtx_equal_p (operands[1], operands[2]))"
9341 [(set (match_dup 3) (match_dup 1))
9342 (parallel [(set (reg:CCAN CC_REGNUM)
9343 (compare:CCAN (plus:SI (match_dup 3) (const_int -1))
9344 (const_int 0)))
9345 (set (match_dup 3) (plus:SI (match_dup 3) (const_int -1)))])
9346 (set (match_dup 2) (match_dup 3))
9347 (set (pc) (if_then_else (ne (reg:CCAN CC_REGNUM) (const_int 0))
9348 (label_ref (match_dup 0))
9349 (pc)))]
9350 ""
9351 [(set_attr "op_type" "RI")
9352 ; Strictly speaking, the z10 properties are valid for brct only, however, it does not
9353 ; hurt us in the (rare) case of ahi.
9354 (set_attr "z10prop" "z10_super_E1")
9355 (set_attr "type" "branch")
9356 (set (attr "length")
9357 (if_then_else (not (match_test "flag_pic"))
9358 (if_then_else (lt (abs (minus (pc) (match_dup 0))) (const_int 60000))
9359 (const_int 4) (const_int 6))
9360 (if_then_else (lt (abs (minus (pc) (match_dup 0))) (const_int 60000))
9361 (const_int 4) (const_int 8))))])
9362
9363 (define_insn "*doloop_si_long"
9364 [(set (pc)
9365 (if_then_else
9366 (ne (match_operand:SI 1 "register_operand" "d")
9367 (const_int 1))
9368 (match_operand 0 "address_operand" "ZR")
9369 (pc)))
9370 (set (match_operand:SI 2 "register_operand" "=1")
9371 (plus:SI (match_dup 1) (const_int -1)))
9372 (clobber (match_scratch:SI 3 "=X"))
9373 (clobber (reg:CC CC_REGNUM))]
9374 "!TARGET_CPU_ZARCH"
9375 {
9376 if (get_attr_op_type (insn) == OP_TYPE_RR)
9377 return "bctr\t%1,%0";
9378 else
9379 return "bct\t%1,%a0";
9380 }
9381 [(set (attr "op_type")
9382 (if_then_else (match_operand 0 "register_operand" "")
9383 (const_string "RR") (const_string "RX")))
9384 (set_attr "type" "branch")
9385 (set_attr "atype" "agen")
9386 (set_attr "z10prop" "z10_c")
9387 (set_attr "z196prop" "z196_cracked")])
9388
9389 (define_insn_and_split "doloop_di"
9390 [(set (pc)
9391 (if_then_else
9392 (ne (match_operand:DI 1 "register_operand" "d,d,d")
9393 (const_int 1))
9394 (label_ref (match_operand 0 "" ""))
9395 (pc)))
9396 (set (match_operand:DI 2 "nonimmediate_operand" "=1,?X,?X")
9397 (plus:DI (match_dup 1) (const_int -1)))
9398 (clobber (match_scratch:DI 3 "=X,&1,&?d"))
9399 (clobber (reg:CC CC_REGNUM))]
9400 "TARGET_ZARCH"
9401 {
9402 if (which_alternative != 0)
9403 return "#";
9404 else if (get_attr_length (insn) == 4)
9405 return "brctg\t%1,%l0";
9406 else
9407 return "aghi\t%1,-1\;jgne\t%l0";
9408 }
9409 "&& reload_completed
9410 && (! REG_P (operands[2])
9411 || ! rtx_equal_p (operands[1], operands[2]))"
9412 [(set (match_dup 3) (match_dup 1))
9413 (parallel [(set (reg:CCAN CC_REGNUM)
9414 (compare:CCAN (plus:DI (match_dup 3) (const_int -1))
9415 (const_int 0)))
9416 (set (match_dup 3) (plus:DI (match_dup 3) (const_int -1)))])
9417 (set (match_dup 2) (match_dup 3))
9418 (set (pc) (if_then_else (ne (reg:CCAN CC_REGNUM) (const_int 0))
9419 (label_ref (match_dup 0))
9420 (pc)))]
9421 ""
9422 [(set_attr "op_type" "RI")
9423 ; Strictly speaking, the z10 properties are valid for brct only, however, it does not
9424 ; hurt us in the (rare) case of ahi.
9425 (set_attr "z10prop" "z10_super_E1")
9426 (set_attr "type" "branch")
9427 (set (attr "length")
9428 (if_then_else (lt (abs (minus (pc) (match_dup 0))) (const_int 60000))
9429 (const_int 4) (const_int 10)))])
9430
9431 ;;
9432 ;;- Unconditional jump instructions.
9433 ;;
9434
9435 ;
9436 ; jump instruction pattern(s).
9437 ;
9438
9439 (define_expand "jump"
9440 [(match_operand 0 "" "")]
9441 ""
9442 "s390_emit_jump (operands[0], NULL_RTX); DONE;")
9443
9444 (define_insn "*jump64"
9445 [(set (pc) (label_ref (match_operand 0 "" "")))]
9446 "TARGET_CPU_ZARCH"
9447 {
9448 if (get_attr_length (insn) == 4)
9449 return "j\t%l0";
9450 else
9451 return "jg\t%l0";
9452 }
9453 [(set_attr "op_type" "RI")
9454 (set_attr "type" "branch")
9455 (set (attr "length")
9456 (if_then_else (lt (abs (minus (pc) (match_dup 0))) (const_int 60000))
9457 (const_int 4) (const_int 6)))])
9458
9459 (define_insn "*jump31"
9460 [(set (pc) (label_ref (match_operand 0 "" "")))]
9461 "!TARGET_CPU_ZARCH"
9462 {
9463 gcc_assert (get_attr_length (insn) == 4);
9464 return "j\t%l0";
9465 }
9466 [(set_attr "op_type" "RI")
9467 (set_attr "type" "branch")
9468 (set (attr "length")
9469 (if_then_else (not (match_test "flag_pic"))
9470 (if_then_else (lt (abs (minus (pc) (match_dup 0))) (const_int 60000))
9471 (const_int 4) (const_int 6))
9472 (if_then_else (lt (abs (minus (pc) (match_dup 0))) (const_int 60000))
9473 (const_int 4) (const_int 8))))])
9474
9475 ;
9476 ; indirect-jump instruction pattern(s).
9477 ;
9478
9479 (define_insn "indirect_jump"
9480 [(set (pc) (match_operand 0 "address_operand" "ZR"))]
9481 ""
9482 {
9483 if (get_attr_op_type (insn) == OP_TYPE_RR)
9484 return "br\t%0";
9485 else
9486 return "b\t%a0";
9487 }
9488 [(set (attr "op_type")
9489 (if_then_else (match_operand 0 "register_operand" "")
9490 (const_string "RR") (const_string "RX")))
9491 (set_attr "type" "branch")
9492 (set_attr "atype" "agen")])
9493
9494 ;
9495 ; casesi instruction pattern(s).
9496 ;
9497
9498 (define_insn "casesi_jump"
9499 [(set (pc) (match_operand 0 "address_operand" "ZR"))
9500 (use (label_ref (match_operand 1 "" "")))]
9501 ""
9502 {
9503 if (get_attr_op_type (insn) == OP_TYPE_RR)
9504 return "br\t%0";
9505 else
9506 return "b\t%a0";
9507 }
9508 [(set (attr "op_type")
9509 (if_then_else (match_operand 0 "register_operand" "")
9510 (const_string "RR") (const_string "RX")))
9511 (set_attr "type" "branch")
9512 (set_attr "atype" "agen")])
9513
9514 (define_expand "casesi"
9515 [(match_operand:SI 0 "general_operand" "")
9516 (match_operand:SI 1 "general_operand" "")
9517 (match_operand:SI 2 "general_operand" "")
9518 (label_ref (match_operand 3 "" ""))
9519 (label_ref (match_operand 4 "" ""))]
9520 ""
9521 {
9522 rtx index = gen_reg_rtx (SImode);
9523 rtx base = gen_reg_rtx (Pmode);
9524 rtx target = gen_reg_rtx (Pmode);
9525
9526 emit_move_insn (index, operands[0]);
9527 emit_insn (gen_subsi3 (index, index, operands[1]));
9528 emit_cmp_and_jump_insns (index, operands[2], GTU, NULL_RTX, SImode, 1,
9529 operands[4]);
9530
9531 if (Pmode != SImode)
9532 index = convert_to_mode (Pmode, index, 1);
9533 if (GET_CODE (index) != REG)
9534 index = copy_to_mode_reg (Pmode, index);
9535
9536 if (TARGET_64BIT)
9537 emit_insn (gen_ashldi3 (index, index, GEN_INT (3)));
9538 else
9539 emit_insn (gen_ashlsi3 (index, index, const2_rtx));
9540
9541 emit_move_insn (base, gen_rtx_LABEL_REF (Pmode, operands[3]));
9542
9543 index = gen_const_mem (Pmode, gen_rtx_PLUS (Pmode, base, index));
9544 emit_move_insn (target, index);
9545
9546 if (flag_pic)
9547 target = gen_rtx_PLUS (Pmode, base, target);
9548 emit_jump_insn (gen_casesi_jump (target, operands[3]));
9549
9550 DONE;
9551 })
9552
9553
9554 ;;
9555 ;;- Jump to subroutine.
9556 ;;
9557 ;;
9558
9559 ;
9560 ; untyped call instruction pattern(s).
9561 ;
9562
9563 ;; Call subroutine returning any type.
9564 (define_expand "untyped_call"
9565 [(parallel [(call (match_operand 0 "" "")
9566 (const_int 0))
9567 (match_operand 1 "" "")
9568 (match_operand 2 "" "")])]
9569 ""
9570 {
9571 int i;
9572
9573 emit_call_insn (gen_call (operands[0], const0_rtx, const0_rtx));
9574
9575 for (i = 0; i < XVECLEN (operands[2], 0); i++)
9576 {
9577 rtx set = XVECEXP (operands[2], 0, i);
9578 emit_move_insn (SET_DEST (set), SET_SRC (set));
9579 }
9580
9581 /* The optimizer does not know that the call sets the function value
9582 registers we stored in the result block. We avoid problems by
9583 claiming that all hard registers are used and clobbered at this
9584 point. */
9585 emit_insn (gen_blockage ());
9586
9587 DONE;
9588 })
9589
9590 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
9591 ;; all of memory. This blocks insns from being moved across this point.
9592
9593 (define_insn "blockage"
9594 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
9595 ""
9596 ""
9597 [(set_attr "type" "none")
9598 (set_attr "length" "0")])
9599
9600 ;
9601 ; sibcall patterns
9602 ;
9603
9604 (define_expand "sibcall"
9605 [(call (match_operand 0 "" "")
9606 (match_operand 1 "" ""))]
9607 ""
9608 {
9609 s390_emit_call (XEXP (operands[0], 0), NULL_RTX, NULL_RTX, NULL_RTX);
9610 DONE;
9611 })
9612
9613 (define_insn "*sibcall_br"
9614 [(call (mem:QI (reg SIBCALL_REGNUM))
9615 (match_operand 0 "const_int_operand" "n"))]
9616 "SIBLING_CALL_P (insn)
9617 && GET_MODE (XEXP (XEXP (PATTERN (insn), 0), 0)) == Pmode"
9618 "br\t%%r1"
9619 [(set_attr "op_type" "RR")
9620 (set_attr "type" "branch")
9621 (set_attr "atype" "agen")])
9622
9623 (define_insn "*sibcall_brc"
9624 [(call (mem:QI (match_operand 0 "bras_sym_operand" "X"))
9625 (match_operand 1 "const_int_operand" "n"))]
9626 "SIBLING_CALL_P (insn) && TARGET_SMALL_EXEC"
9627 "j\t%0"
9628 [(set_attr "op_type" "RI")
9629 (set_attr "type" "branch")])
9630
9631 (define_insn "*sibcall_brcl"
9632 [(call (mem:QI (match_operand 0 "bras_sym_operand" "X"))
9633 (match_operand 1 "const_int_operand" "n"))]
9634 "SIBLING_CALL_P (insn) && TARGET_CPU_ZARCH"
9635 "jg\t%0"
9636 [(set_attr "op_type" "RIL")
9637 (set_attr "type" "branch")])
9638
9639 ;
9640 ; sibcall_value patterns
9641 ;
9642
9643 (define_expand "sibcall_value"
9644 [(set (match_operand 0 "" "")
9645 (call (match_operand 1 "" "")
9646 (match_operand 2 "" "")))]
9647 ""
9648 {
9649 s390_emit_call (XEXP (operands[1], 0), NULL_RTX, operands[0], NULL_RTX);
9650 DONE;
9651 })
9652
9653 (define_insn "*sibcall_value_br"
9654 [(set (match_operand 0 "" "")
9655 (call (mem:QI (reg SIBCALL_REGNUM))
9656 (match_operand 1 "const_int_operand" "n")))]
9657 "SIBLING_CALL_P (insn)
9658 && GET_MODE (XEXP (XEXP (XEXP (PATTERN (insn), 1), 0), 0)) == Pmode"
9659 "br\t%%r1"
9660 [(set_attr "op_type" "RR")
9661 (set_attr "type" "branch")
9662 (set_attr "atype" "agen")])
9663
9664 (define_insn "*sibcall_value_brc"
9665 [(set (match_operand 0 "" "")
9666 (call (mem:QI (match_operand 1 "bras_sym_operand" "X"))
9667 (match_operand 2 "const_int_operand" "n")))]
9668 "SIBLING_CALL_P (insn) && TARGET_SMALL_EXEC"
9669 "j\t%1"
9670 [(set_attr "op_type" "RI")
9671 (set_attr "type" "branch")])
9672
9673 (define_insn "*sibcall_value_brcl"
9674 [(set (match_operand 0 "" "")
9675 (call (mem:QI (match_operand 1 "bras_sym_operand" "X"))
9676 (match_operand 2 "const_int_operand" "n")))]
9677 "SIBLING_CALL_P (insn) && TARGET_CPU_ZARCH"
9678 "jg\t%1"
9679 [(set_attr "op_type" "RIL")
9680 (set_attr "type" "branch")])
9681
9682
9683 ;
9684 ; call instruction pattern(s).
9685 ;
9686
9687 (define_expand "call"
9688 [(call (match_operand 0 "" "")
9689 (match_operand 1 "" ""))
9690 (use (match_operand 2 "" ""))]
9691 ""
9692 {
9693 s390_emit_call (XEXP (operands[0], 0), NULL_RTX, NULL_RTX,
9694 gen_rtx_REG (Pmode, RETURN_REGNUM));
9695 DONE;
9696 })
9697
9698 (define_insn "*bras"
9699 [(call (mem:QI (match_operand 0 "bras_sym_operand" "X"))
9700 (match_operand 1 "const_int_operand" "n"))
9701 (clobber (match_operand 2 "register_operand" "=r"))]
9702 "!SIBLING_CALL_P (insn)
9703 && TARGET_SMALL_EXEC
9704 && GET_MODE (operands[2]) == Pmode"
9705 "bras\t%2,%0"
9706 [(set_attr "op_type" "RI")
9707 (set_attr "type" "jsr")
9708 (set_attr "z196prop" "z196_cracked")])
9709
9710 (define_insn "*brasl"
9711 [(call (mem:QI (match_operand 0 "bras_sym_operand" "X"))
9712 (match_operand 1 "const_int_operand" "n"))
9713 (clobber (match_operand 2 "register_operand" "=r"))]
9714 "!SIBLING_CALL_P (insn)
9715 && TARGET_CPU_ZARCH
9716 && GET_MODE (operands[2]) == Pmode"
9717 "brasl\t%2,%0"
9718 [(set_attr "op_type" "RIL")
9719 (set_attr "type" "jsr")
9720 (set_attr "z196prop" "z196_cracked")])
9721
9722 (define_insn "*basr"
9723 [(call (mem:QI (match_operand 0 "address_operand" "ZR"))
9724 (match_operand 1 "const_int_operand" "n"))
9725 (clobber (match_operand 2 "register_operand" "=r"))]
9726 "!SIBLING_CALL_P (insn) && GET_MODE (operands[2]) == Pmode"
9727 {
9728 if (get_attr_op_type (insn) == OP_TYPE_RR)
9729 return "basr\t%2,%0";
9730 else
9731 return "bas\t%2,%a0";
9732 }
9733 [(set (attr "op_type")
9734 (if_then_else (match_operand 0 "register_operand" "")
9735 (const_string "RR") (const_string "RX")))
9736 (set_attr "type" "jsr")
9737 (set_attr "atype" "agen")
9738 (set_attr "z196prop" "z196_cracked")])
9739
9740 ;
9741 ; call_value instruction pattern(s).
9742 ;
9743
9744 (define_expand "call_value"
9745 [(set (match_operand 0 "" "")
9746 (call (match_operand 1 "" "")
9747 (match_operand 2 "" "")))
9748 (use (match_operand 3 "" ""))]
9749 ""
9750 {
9751 s390_emit_call (XEXP (operands[1], 0), NULL_RTX, operands[0],
9752 gen_rtx_REG (Pmode, RETURN_REGNUM));
9753 DONE;
9754 })
9755
9756 (define_insn "*bras_r"
9757 [(set (match_operand 0 "" "")
9758 (call (mem:QI (match_operand 1 "bras_sym_operand" "X"))
9759 (match_operand:SI 2 "const_int_operand" "n")))
9760 (clobber (match_operand 3 "register_operand" "=r"))]
9761 "!SIBLING_CALL_P (insn)
9762 && TARGET_SMALL_EXEC
9763 && GET_MODE (operands[3]) == Pmode"
9764 "bras\t%3,%1"
9765 [(set_attr "op_type" "RI")
9766 (set_attr "type" "jsr")
9767 (set_attr "z196prop" "z196_cracked")])
9768
9769 (define_insn "*brasl_r"
9770 [(set (match_operand 0 "" "")
9771 (call (mem:QI (match_operand 1 "bras_sym_operand" "X"))
9772 (match_operand 2 "const_int_operand" "n")))
9773 (clobber (match_operand 3 "register_operand" "=r"))]
9774 "!SIBLING_CALL_P (insn)
9775 && TARGET_CPU_ZARCH
9776 && GET_MODE (operands[3]) == Pmode"
9777 "brasl\t%3,%1"
9778 [(set_attr "op_type" "RIL")
9779 (set_attr "type" "jsr")
9780 (set_attr "z196prop" "z196_cracked")])
9781
9782 (define_insn "*basr_r"
9783 [(set (match_operand 0 "" "")
9784 (call (mem:QI (match_operand 1 "address_operand" "ZR"))
9785 (match_operand 2 "const_int_operand" "n")))
9786 (clobber (match_operand 3 "register_operand" "=r"))]
9787 "!SIBLING_CALL_P (insn) && GET_MODE (operands[3]) == Pmode"
9788 {
9789 if (get_attr_op_type (insn) == OP_TYPE_RR)
9790 return "basr\t%3,%1";
9791 else
9792 return "bas\t%3,%a1";
9793 }
9794 [(set (attr "op_type")
9795 (if_then_else (match_operand 1 "register_operand" "")
9796 (const_string "RR") (const_string "RX")))
9797 (set_attr "type" "jsr")
9798 (set_attr "atype" "agen")
9799 (set_attr "z196prop" "z196_cracked")])
9800
9801 ;;
9802 ;;- Thread-local storage support.
9803 ;;
9804
9805 (define_expand "get_thread_pointer<mode>"
9806 [(set (match_operand:P 0 "nonimmediate_operand" "") (reg:P TP_REGNUM))]
9807 ""
9808 "")
9809
9810 (define_expand "set_thread_pointer<mode>"
9811 [(set (reg:P TP_REGNUM) (match_operand:P 0 "nonimmediate_operand" ""))
9812 (set (reg:P TP_REGNUM) (unspec_volatile:P [(reg:P TP_REGNUM)] UNSPECV_SET_TP))]
9813 ""
9814 "")
9815
9816 (define_insn "*set_tp"
9817 [(set (reg TP_REGNUM) (unspec_volatile [(reg TP_REGNUM)] UNSPECV_SET_TP))]
9818 ""
9819 ""
9820 [(set_attr "type" "none")
9821 (set_attr "length" "0")])
9822
9823 (define_insn "*tls_load_64"
9824 [(set (match_operand:DI 0 "register_operand" "=d")
9825 (unspec:DI [(match_operand:DI 1 "memory_operand" "T")
9826 (match_operand:DI 2 "" "")]
9827 UNSPEC_TLS_LOAD))]
9828 "TARGET_64BIT"
9829 "lg\t%0,%1%J2"
9830 [(set_attr "op_type" "RXE")
9831 (set_attr "z10prop" "z10_fwd_A3")])
9832
9833 (define_insn "*tls_load_31"
9834 [(set (match_operand:SI 0 "register_operand" "=d,d")
9835 (unspec:SI [(match_operand:SI 1 "memory_operand" "R,T")
9836 (match_operand:SI 2 "" "")]
9837 UNSPEC_TLS_LOAD))]
9838 "!TARGET_64BIT"
9839 "@
9840 l\t%0,%1%J2
9841 ly\t%0,%1%J2"
9842 [(set_attr "op_type" "RX,RXY")
9843 (set_attr "type" "load")
9844 (set_attr "cpu_facility" "*,longdisp")
9845 (set_attr "z10prop" "z10_fwd_A3,z10_fwd_A3")])
9846
9847 (define_insn "*bras_tls"
9848 [(set (match_operand 0 "" "")
9849 (call (mem:QI (match_operand 1 "bras_sym_operand" "X"))
9850 (match_operand 2 "const_int_operand" "n")))
9851 (clobber (match_operand 3 "register_operand" "=r"))
9852 (use (match_operand 4 "" ""))]
9853 "!SIBLING_CALL_P (insn)
9854 && TARGET_SMALL_EXEC
9855 && GET_MODE (operands[3]) == Pmode"
9856 "bras\t%3,%1%J4"
9857 [(set_attr "op_type" "RI")
9858 (set_attr "type" "jsr")
9859 (set_attr "z196prop" "z196_cracked")])
9860
9861 (define_insn "*brasl_tls"
9862 [(set (match_operand 0 "" "")
9863 (call (mem:QI (match_operand 1 "bras_sym_operand" "X"))
9864 (match_operand 2 "const_int_operand" "n")))
9865 (clobber (match_operand 3 "register_operand" "=r"))
9866 (use (match_operand 4 "" ""))]
9867 "!SIBLING_CALL_P (insn)
9868 && TARGET_CPU_ZARCH
9869 && GET_MODE (operands[3]) == Pmode"
9870 "brasl\t%3,%1%J4"
9871 [(set_attr "op_type" "RIL")
9872 (set_attr "type" "jsr")
9873 (set_attr "z196prop" "z196_cracked")])
9874
9875 (define_insn "*basr_tls"
9876 [(set (match_operand 0 "" "")
9877 (call (mem:QI (match_operand 1 "address_operand" "ZR"))
9878 (match_operand 2 "const_int_operand" "n")))
9879 (clobber (match_operand 3 "register_operand" "=r"))
9880 (use (match_operand 4 "" ""))]
9881 "!SIBLING_CALL_P (insn) && GET_MODE (operands[3]) == Pmode"
9882 {
9883 if (get_attr_op_type (insn) == OP_TYPE_RR)
9884 return "basr\t%3,%1%J4";
9885 else
9886 return "bas\t%3,%a1%J4";
9887 }
9888 [(set (attr "op_type")
9889 (if_then_else (match_operand 1 "register_operand" "")
9890 (const_string "RR") (const_string "RX")))
9891 (set_attr "type" "jsr")
9892 (set_attr "atype" "agen")
9893 (set_attr "z196prop" "z196_cracked")])
9894
9895 ;;
9896 ;;- Atomic operations
9897 ;;
9898
9899 ;
9900 ; memory barrier patterns.
9901 ;
9902
9903 (define_expand "mem_signal_fence"
9904 [(match_operand:SI 0 "const_int_operand")] ;; model
9905 ""
9906 {
9907 /* The s390 memory model is strong enough not to require any
9908 barrier in order to synchronize a thread with itself. */
9909 DONE;
9910 })
9911
9912 (define_expand "mem_thread_fence"
9913 [(match_operand:SI 0 "const_int_operand")] ;; model
9914 ""
9915 {
9916 /* Unless this is a SEQ_CST fence, the s390 memory model is strong
9917 enough not to require barriers of any kind. */
9918 if (is_mm_seq_cst (memmodel_from_int (INTVAL (operands[0]))))
9919 {
9920 rtx mem = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
9921 MEM_VOLATILE_P (mem) = 1;
9922 emit_insn (gen_mem_thread_fence_1 (mem));
9923 }
9924 DONE;
9925 })
9926
9927 ; Although bcr is superscalar on Z10, this variant will never
9928 ; become part of an execution group.
9929 ; With z196 we can make use of the fast-BCR-serialization facility.
9930 ; This allows for a slightly faster sync which is sufficient for our
9931 ; purposes.
9932 (define_insn "mem_thread_fence_1"
9933 [(set (match_operand:BLK 0 "" "")
9934 (unspec:BLK [(match_dup 0)] UNSPEC_MB))]
9935 ""
9936 {
9937 if (TARGET_Z196)
9938 return "bcr\t14,0";
9939 else
9940 return "bcr\t15,0";
9941 }
9942 [(set_attr "op_type" "RR")
9943 (set_attr "mnemonic" "bcr_flush")
9944 (set_attr "z196prop" "z196_alone")])
9945
9946 ;
9947 ; atomic load/store operations
9948 ;
9949
9950 ; Atomic loads need not examine the memory model at all.
9951 (define_expand "atomic_load<mode>"
9952 [(match_operand:DINT 0 "register_operand") ;; output
9953 (match_operand:DINT 1 "memory_operand") ;; memory
9954 (match_operand:SI 2 "const_int_operand")] ;; model
9955 ""
9956 {
9957 if (MEM_ALIGN (operands[1]) < GET_MODE_BITSIZE (GET_MODE (operands[1])))
9958 FAIL;
9959
9960 if (<MODE>mode == TImode)
9961 emit_insn (gen_atomic_loadti_1 (operands[0], operands[1]));
9962 else if (<MODE>mode == DImode && !TARGET_ZARCH)
9963 emit_insn (gen_atomic_loaddi_1 (operands[0], operands[1]));
9964 else
9965 emit_move_insn (operands[0], operands[1]);
9966 DONE;
9967 })
9968
9969 ; Different from movdi_31 in that we want no splitters.
9970 (define_insn "atomic_loaddi_1"
9971 [(set (match_operand:DI 0 "register_operand" "=d,d,!*f,!*f")
9972 (unspec:DI [(match_operand:DI 1 "memory_operand" "Q,S,R,T")]
9973 UNSPEC_MOVA))]
9974 "!TARGET_ZARCH"
9975 "@
9976 lm\t%0,%M0,%S1
9977 lmy\t%0,%M0,%S1
9978 ld\t%0,%1
9979 ldy\t%0,%1"
9980 [(set_attr "op_type" "RS,RSY,RS,RSY")
9981 (set_attr "cpu_facility" "*,longdisp,*,longdisp")
9982 (set_attr "type" "lm,lm,floaddf,floaddf")])
9983
9984 (define_insn "atomic_loadti_1"
9985 [(set (match_operand:TI 0 "register_operand" "=r")
9986 (unspec:TI [(match_operand:TI 1 "memory_operand" "T")]
9987 UNSPEC_MOVA))]
9988 "TARGET_ZARCH"
9989 "lpq\t%0,%1"
9990 [(set_attr "op_type" "RXY")
9991 (set_attr "type" "other")])
9992
9993 ; Atomic stores must(?) enforce sequential consistency.
9994 (define_expand "atomic_store<mode>"
9995 [(match_operand:DINT 0 "memory_operand") ;; memory
9996 (match_operand:DINT 1 "register_operand") ;; input
9997 (match_operand:SI 2 "const_int_operand")] ;; model
9998 ""
9999 {
10000 enum memmodel model = memmodel_from_int (INTVAL (operands[2]));
10001
10002 if (MEM_ALIGN (operands[0]) < GET_MODE_BITSIZE (GET_MODE (operands[0])))
10003 FAIL;
10004
10005 if (<MODE>mode == TImode)
10006 emit_insn (gen_atomic_storeti_1 (operands[0], operands[1]));
10007 else if (<MODE>mode == DImode && !TARGET_ZARCH)
10008 emit_insn (gen_atomic_storedi_1 (operands[0], operands[1]));
10009 else
10010 emit_move_insn (operands[0], operands[1]);
10011 if (is_mm_seq_cst (model))
10012 emit_insn (gen_mem_thread_fence (operands[2]));
10013 DONE;
10014 })
10015
10016 ; Different from movdi_31 in that we want no splitters.
10017 (define_insn "atomic_storedi_1"
10018 [(set (match_operand:DI 0 "memory_operand" "=Q,S,R,T")
10019 (unspec:DI [(match_operand:DI 1 "register_operand" "d,d,!*f,!*f")]
10020 UNSPEC_MOVA))]
10021 "!TARGET_ZARCH"
10022 "@
10023 stm\t%1,%N1,%S0
10024 stmy\t%1,%N1,%S0
10025 std %1,%0
10026 stdy %1,%0"
10027 [(set_attr "op_type" "RS,RSY,RS,RSY")
10028 (set_attr "cpu_facility" "*,longdisp,*,longdisp")
10029 (set_attr "type" "stm,stm,fstoredf,fstoredf")])
10030
10031 (define_insn "atomic_storeti_1"
10032 [(set (match_operand:TI 0 "memory_operand" "=T")
10033 (unspec:TI [(match_operand:TI 1 "register_operand" "r")]
10034 UNSPEC_MOVA))]
10035 "TARGET_ZARCH"
10036 "stpq\t%1,%0"
10037 [(set_attr "op_type" "RXY")
10038 (set_attr "type" "other")])
10039
10040 ;
10041 ; compare and swap patterns.
10042 ;
10043
10044 (define_expand "atomic_compare_and_swap<mode>"
10045 [(match_operand:SI 0 "register_operand") ;; bool success output
10046 (match_operand:DGPR 1 "nonimmediate_operand");; oldval output
10047 (match_operand:DGPR 2 "memory_operand") ;; memory
10048 (match_operand:DGPR 3 "register_operand") ;; expected intput
10049 (match_operand:DGPR 4 "register_operand") ;; newval intput
10050 (match_operand:SI 5 "const_int_operand") ;; is_weak
10051 (match_operand:SI 6 "const_int_operand") ;; success model
10052 (match_operand:SI 7 "const_int_operand")] ;; failure model
10053 ""
10054 {
10055 rtx cc, cmp, output = operands[1];
10056
10057 if (!register_operand (output, <MODE>mode))
10058 output = gen_reg_rtx (<MODE>mode);
10059
10060 if (MEM_ALIGN (operands[2]) < GET_MODE_BITSIZE (GET_MODE (operands[2])))
10061 FAIL;
10062
10063 emit_insn (gen_atomic_compare_and_swap<mode>_internal
10064 (output, operands[2], operands[3], operands[4]));
10065
10066 /* We deliberately accept non-register operands in the predicate
10067 to ensure the write back to the output operand happens *before*
10068 the store-flags code below. This makes it easier for combine
10069 to merge the store-flags code with a potential test-and-branch
10070 pattern following (immediately!) afterwards. */
10071 if (output != operands[1])
10072 emit_move_insn (operands[1], output);
10073
10074 cc = gen_rtx_REG (CCZ1mode, CC_REGNUM);
10075 cmp = gen_rtx_EQ (SImode, cc, const0_rtx);
10076 emit_insn (gen_cstorecc4 (operands[0], cmp, cc, const0_rtx));
10077 DONE;
10078 })
10079
10080 (define_expand "atomic_compare_and_swap<mode>"
10081 [(match_operand:SI 0 "register_operand") ;; bool success output
10082 (match_operand:HQI 1 "nonimmediate_operand") ;; oldval output
10083 (match_operand:HQI 2 "memory_operand") ;; memory
10084 (match_operand:HQI 3 "general_operand") ;; expected intput
10085 (match_operand:HQI 4 "general_operand") ;; newval intput
10086 (match_operand:SI 5 "const_int_operand") ;; is_weak
10087 (match_operand:SI 6 "const_int_operand") ;; success model
10088 (match_operand:SI 7 "const_int_operand")] ;; failure model
10089 ""
10090 {
10091 s390_expand_cs_hqi (<MODE>mode, operands[0], operands[1], operands[2],
10092 operands[3], operands[4], INTVAL (operands[5]));
10093 DONE;
10094 })
10095
10096 (define_expand "atomic_compare_and_swap<mode>_internal"
10097 [(parallel
10098 [(set (match_operand:DGPR 0 "register_operand")
10099 (match_operand:DGPR 1 "memory_operand"))
10100 (set (match_dup 1)
10101 (unspec_volatile:DGPR
10102 [(match_dup 1)
10103 (match_operand:DGPR 2 "register_operand")
10104 (match_operand:DGPR 3 "register_operand")]
10105 UNSPECV_CAS))
10106 (set (reg:CCZ1 CC_REGNUM)
10107 (compare:CCZ1 (match_dup 1) (match_dup 2)))])]
10108 "")
10109
10110 ; cdsg, csg
10111 (define_insn "*atomic_compare_and_swap<mode>_1"
10112 [(set (match_operand:TDI 0 "register_operand" "=r")
10113 (match_operand:TDI 1 "memory_operand" "+S"))
10114 (set (match_dup 1)
10115 (unspec_volatile:TDI
10116 [(match_dup 1)
10117 (match_operand:TDI 2 "register_operand" "0")
10118 (match_operand:TDI 3 "register_operand" "r")]
10119 UNSPECV_CAS))
10120 (set (reg:CCZ1 CC_REGNUM)
10121 (compare:CCZ1 (match_dup 1) (match_dup 2)))]
10122 "TARGET_ZARCH"
10123 "c<td>sg\t%0,%3,%S1"
10124 [(set_attr "op_type" "RSY")
10125 (set_attr "type" "sem")])
10126
10127 ; cds, cdsy
10128 (define_insn "*atomic_compare_and_swapdi_2"
10129 [(set (match_operand:DI 0 "register_operand" "=r,r")
10130 (match_operand:DI 1 "memory_operand" "+Q,S"))
10131 (set (match_dup 1)
10132 (unspec_volatile:DI
10133 [(match_dup 1)
10134 (match_operand:DI 2 "register_operand" "0,0")
10135 (match_operand:DI 3 "register_operand" "r,r")]
10136 UNSPECV_CAS))
10137 (set (reg:CCZ1 CC_REGNUM)
10138 (compare:CCZ1 (match_dup 1) (match_dup 2)))]
10139 "!TARGET_ZARCH"
10140 "@
10141 cds\t%0,%3,%S1
10142 cdsy\t%0,%3,%S1"
10143 [(set_attr "op_type" "RS,RSY")
10144 (set_attr "cpu_facility" "*,longdisp")
10145 (set_attr "type" "sem")])
10146
10147 ; cs, csy
10148 (define_insn "*atomic_compare_and_swapsi_3"
10149 [(set (match_operand:SI 0 "register_operand" "=r,r")
10150 (match_operand:SI 1 "memory_operand" "+Q,S"))
10151 (set (match_dup 1)
10152 (unspec_volatile:SI
10153 [(match_dup 1)
10154 (match_operand:SI 2 "register_operand" "0,0")
10155 (match_operand:SI 3 "register_operand" "r,r")]
10156 UNSPECV_CAS))
10157 (set (reg:CCZ1 CC_REGNUM)
10158 (compare:CCZ1 (match_dup 1) (match_dup 2)))]
10159 ""
10160 "@
10161 cs\t%0,%3,%S1
10162 csy\t%0,%3,%S1"
10163 [(set_attr "op_type" "RS,RSY")
10164 (set_attr "cpu_facility" "*,longdisp")
10165 (set_attr "type" "sem")])
10166
10167 ;
10168 ; Other atomic instruction patterns.
10169 ;
10170
10171 ; z196 load and add, xor, or and and instructions
10172
10173 (define_expand "atomic_fetch_<atomic><mode>"
10174 [(match_operand:GPR 0 "register_operand") ;; val out
10175 (ATOMIC_Z196:GPR
10176 (match_operand:GPR 1 "memory_operand") ;; memory
10177 (match_operand:GPR 2 "register_operand")) ;; val in
10178 (match_operand:SI 3 "const_int_operand")] ;; model
10179 "TARGET_Z196"
10180 {
10181 if (MEM_ALIGN (operands[1]) < GET_MODE_BITSIZE (GET_MODE (operands[1])))
10182 FAIL;
10183
10184 emit_insn (gen_atomic_fetch_<atomic><mode>_iaf
10185 (operands[0], operands[1], operands[2]));
10186 DONE;
10187 })
10188
10189 ; lan, lang, lao, laog, lax, laxg, laa, laag
10190 (define_insn "atomic_fetch_<atomic><mode>_iaf"
10191 [(set (match_operand:GPR 0 "register_operand" "=d")
10192 (match_operand:GPR 1 "memory_operand" "+S"))
10193 (set (match_dup 1)
10194 (unspec_volatile:GPR
10195 [(ATOMIC_Z196:GPR (match_dup 1)
10196 (match_operand:GPR 2 "general_operand" "d"))]
10197 UNSPECV_ATOMIC_OP))
10198 (clobber (reg:CC CC_REGNUM))]
10199 "TARGET_Z196"
10200 "la<noxa><g>\t%0,%2,%1"
10201 [(set_attr "op_type" "RSY")
10202 (set_attr "type" "sem")])
10203
10204 ;; For SImode and larger, the optabs.c code will do just fine in
10205 ;; expanding a compare-and-swap loop. For QI/HImode, we can do
10206 ;; better by expanding our own loop.
10207
10208 (define_expand "atomic_<atomic><mode>"
10209 [(ATOMIC:HQI
10210 (match_operand:HQI 0 "memory_operand") ;; memory
10211 (match_operand:HQI 1 "general_operand")) ;; val in
10212 (match_operand:SI 2 "const_int_operand")] ;; model
10213 ""
10214 {
10215 s390_expand_atomic (<MODE>mode, <CODE>, NULL_RTX, operands[0],
10216 operands[1], false);
10217 DONE;
10218 })
10219
10220 (define_expand "atomic_fetch_<atomic><mode>"
10221 [(match_operand:HQI 0 "register_operand") ;; val out
10222 (ATOMIC:HQI
10223 (match_operand:HQI 1 "memory_operand") ;; memory
10224 (match_operand:HQI 2 "general_operand")) ;; val in
10225 (match_operand:SI 3 "const_int_operand")] ;; model
10226 ""
10227 {
10228 s390_expand_atomic (<MODE>mode, <CODE>, operands[0], operands[1],
10229 operands[2], false);
10230 DONE;
10231 })
10232
10233 (define_expand "atomic_<atomic>_fetch<mode>"
10234 [(match_operand:HQI 0 "register_operand") ;; val out
10235 (ATOMIC:HQI
10236 (match_operand:HQI 1 "memory_operand") ;; memory
10237 (match_operand:HQI 2 "general_operand")) ;; val in
10238 (match_operand:SI 3 "const_int_operand")] ;; model
10239 ""
10240 {
10241 s390_expand_atomic (<MODE>mode, <CODE>, operands[0], operands[1],
10242 operands[2], true);
10243 DONE;
10244 })
10245
10246 (define_expand "atomic_exchange<mode>"
10247 [(match_operand:HQI 0 "register_operand") ;; val out
10248 (match_operand:HQI 1 "memory_operand") ;; memory
10249 (match_operand:HQI 2 "general_operand") ;; val in
10250 (match_operand:SI 3 "const_int_operand")] ;; model
10251 ""
10252 {
10253 s390_expand_atomic (<MODE>mode, SET, operands[0], operands[1],
10254 operands[2], false);
10255 DONE;
10256 })
10257
10258 ;;
10259 ;;- Miscellaneous instructions.
10260 ;;
10261
10262 ;
10263 ; allocate stack instruction pattern(s).
10264 ;
10265
10266 (define_expand "allocate_stack"
10267 [(match_operand 0 "general_operand" "")
10268 (match_operand 1 "general_operand" "")]
10269 "TARGET_BACKCHAIN"
10270 {
10271 rtx temp = gen_reg_rtx (Pmode);
10272
10273 emit_move_insn (temp, s390_back_chain_rtx ());
10274 anti_adjust_stack (operands[1]);
10275 emit_move_insn (s390_back_chain_rtx (), temp);
10276
10277 emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
10278 DONE;
10279 })
10280
10281
10282 ;
10283 ; setjmp instruction pattern.
10284 ;
10285
10286 (define_expand "builtin_setjmp_receiver"
10287 [(match_operand 0 "" "")]
10288 "flag_pic"
10289 {
10290 emit_insn (s390_load_got ());
10291 emit_use (pic_offset_table_rtx);
10292 DONE;
10293 })
10294
10295 ;; These patterns say how to save and restore the stack pointer. We need not
10296 ;; save the stack pointer at function level since we are careful to
10297 ;; preserve the backchain. At block level, we have to restore the backchain
10298 ;; when we restore the stack pointer.
10299 ;;
10300 ;; For nonlocal gotos, we must save both the stack pointer and its
10301 ;; backchain and restore both. Note that in the nonlocal case, the
10302 ;; save area is a memory location.
10303
10304 (define_expand "save_stack_function"
10305 [(match_operand 0 "general_operand" "")
10306 (match_operand 1 "general_operand" "")]
10307 ""
10308 "DONE;")
10309
10310 (define_expand "restore_stack_function"
10311 [(match_operand 0 "general_operand" "")
10312 (match_operand 1 "general_operand" "")]
10313 ""
10314 "DONE;")
10315
10316 (define_expand "restore_stack_block"
10317 [(match_operand 0 "register_operand" "")
10318 (match_operand 1 "register_operand" "")]
10319 "TARGET_BACKCHAIN"
10320 {
10321 rtx temp = gen_reg_rtx (Pmode);
10322
10323 emit_move_insn (temp, s390_back_chain_rtx ());
10324 emit_move_insn (operands[0], operands[1]);
10325 emit_move_insn (s390_back_chain_rtx (), temp);
10326
10327 DONE;
10328 })
10329
10330 (define_expand "save_stack_nonlocal"
10331 [(match_operand 0 "memory_operand" "")
10332 (match_operand 1 "register_operand" "")]
10333 ""
10334 {
10335 rtx base = gen_rtx_REG (Pmode, BASE_REGNUM);
10336
10337 /* Copy the backchain to the first word, sp to the second and the
10338 literal pool base to the third. */
10339
10340 rtx save_bc = adjust_address (operands[0], Pmode, 0);
10341 rtx save_sp = adjust_address (operands[0], Pmode, GET_MODE_SIZE (Pmode));
10342 rtx save_bp = adjust_address (operands[0], Pmode, 2 * GET_MODE_SIZE (Pmode));
10343
10344 if (TARGET_BACKCHAIN)
10345 emit_move_insn (save_bc, force_reg (Pmode, s390_back_chain_rtx ()));
10346
10347 emit_move_insn (save_sp, operands[1]);
10348 emit_move_insn (save_bp, base);
10349
10350 DONE;
10351 })
10352
10353 (define_expand "restore_stack_nonlocal"
10354 [(match_operand 0 "register_operand" "")
10355 (match_operand 1 "memory_operand" "")]
10356 ""
10357 {
10358 rtx base = gen_rtx_REG (Pmode, BASE_REGNUM);
10359 rtx temp = NULL_RTX;
10360
10361 /* Restore the backchain from the first word, sp from the second and the
10362 literal pool base from the third. */
10363
10364 rtx save_bc = adjust_address (operands[1], Pmode, 0);
10365 rtx save_sp = adjust_address (operands[1], Pmode, GET_MODE_SIZE (Pmode));
10366 rtx save_bp = adjust_address (operands[1], Pmode, 2 * GET_MODE_SIZE (Pmode));
10367
10368 if (TARGET_BACKCHAIN)
10369 temp = force_reg (Pmode, save_bc);
10370
10371 emit_move_insn (base, save_bp);
10372 emit_move_insn (operands[0], save_sp);
10373
10374 if (temp)
10375 emit_move_insn (s390_back_chain_rtx (), temp);
10376
10377 emit_use (base);
10378 DONE;
10379 })
10380
10381 (define_expand "exception_receiver"
10382 [(const_int 0)]
10383 ""
10384 {
10385 s390_set_has_landing_pad_p (true);
10386 DONE;
10387 })
10388
10389 ;
10390 ; nop instruction pattern(s).
10391 ;
10392
10393 (define_insn "nop"
10394 [(const_int 0)]
10395 ""
10396 "lr\t0,0"
10397 [(set_attr "op_type" "RR")
10398 (set_attr "z10prop" "z10_fr_E1")])
10399
10400 (define_insn "nop1"
10401 [(const_int 1)]
10402 ""
10403 "lr\t1,1"
10404 [(set_attr "op_type" "RR")])
10405
10406 ;;- Undeletable nops (used for hotpatching)
10407
10408 (define_insn "nop_2_byte"
10409 [(unspec_volatile [(const_int 0)] UNSPECV_NOP_2_BYTE)]
10410 ""
10411 "nopr\t%%r0"
10412 [(set_attr "op_type" "RR")])
10413
10414 (define_insn "nop_4_byte"
10415 [(unspec_volatile [(const_int 0)] UNSPECV_NOP_4_BYTE)]
10416 ""
10417 "nop\t0"
10418 [(set_attr "op_type" "RX")])
10419
10420 (define_insn "nop_6_byte"
10421 [(unspec_volatile [(const_int 0)] UNSPECV_NOP_6_BYTE)]
10422 "TARGET_CPU_ZARCH"
10423 "brcl\t0, 0"
10424 [(set_attr "op_type" "RIL")])
10425
10426
10427 ;
10428 ; Special literal pool access instruction pattern(s).
10429 ;
10430
10431 (define_insn "*pool_entry"
10432 [(unspec_volatile [(match_operand 0 "consttable_operand" "X")]
10433 UNSPECV_POOL_ENTRY)]
10434 ""
10435 {
10436 machine_mode mode = GET_MODE (PATTERN (insn));
10437 unsigned int align = GET_MODE_BITSIZE (mode);
10438 s390_output_pool_entry (operands[0], mode, align);
10439 return "";
10440 }
10441 [(set (attr "length")
10442 (symbol_ref "GET_MODE_SIZE (GET_MODE (PATTERN (insn)))"))])
10443
10444 (define_insn "pool_align"
10445 [(unspec_volatile [(match_operand 0 "const_int_operand" "n")]
10446 UNSPECV_POOL_ALIGN)]
10447 ""
10448 ".align\t%0"
10449 [(set (attr "length") (symbol_ref "INTVAL (operands[0])"))])
10450
10451 (define_insn "pool_section_start"
10452 [(unspec_volatile [(const_int 1)] UNSPECV_POOL_SECTION)]
10453 ""
10454 {
10455 switch_to_section (targetm.asm_out.function_rodata_section
10456 (current_function_decl));
10457 return "";
10458 }
10459 [(set_attr "length" "0")])
10460
10461 (define_insn "pool_section_end"
10462 [(unspec_volatile [(const_int 0)] UNSPECV_POOL_SECTION)]
10463 ""
10464 {
10465 switch_to_section (current_function_section ());
10466 return "";
10467 }
10468 [(set_attr "length" "0")])
10469
10470 (define_insn "main_base_31_small"
10471 [(set (match_operand 0 "register_operand" "=a")
10472 (unspec [(label_ref (match_operand 1 "" ""))] UNSPEC_MAIN_BASE))]
10473 "!TARGET_CPU_ZARCH && GET_MODE (operands[0]) == Pmode"
10474 "basr\t%0,0"
10475 [(set_attr "op_type" "RR")
10476 (set_attr "type" "la")
10477 (set_attr "z196prop" "z196_cracked")])
10478
10479 (define_insn "main_base_31_large"
10480 [(set (match_operand 0 "register_operand" "=a")
10481 (unspec [(label_ref (match_operand 1 "" ""))] UNSPEC_MAIN_BASE))
10482 (set (pc) (label_ref (match_operand 2 "" "")))]
10483 "!TARGET_CPU_ZARCH && GET_MODE (operands[0]) == Pmode"
10484 "bras\t%0,%2"
10485 [(set_attr "op_type" "RI")
10486 (set_attr "z196prop" "z196_cracked")])
10487
10488 (define_insn "main_base_64"
10489 [(set (match_operand 0 "register_operand" "=a")
10490 (unspec [(label_ref (match_operand 1 "" ""))] UNSPEC_MAIN_BASE))]
10491 "TARGET_CPU_ZARCH && GET_MODE (operands[0]) == Pmode"
10492 "larl\t%0,%1"
10493 [(set_attr "op_type" "RIL")
10494 (set_attr "type" "larl")
10495 (set_attr "z10prop" "z10_fwd_A1")])
10496
10497 (define_insn "main_pool"
10498 [(set (match_operand 0 "register_operand" "=a")
10499 (unspec_volatile [(const_int 0)] UNSPECV_MAIN_POOL))]
10500 "GET_MODE (operands[0]) == Pmode"
10501 {
10502 gcc_unreachable ();
10503 }
10504 [(set (attr "type")
10505 (if_then_else (match_test "TARGET_CPU_ZARCH")
10506 (const_string "larl") (const_string "la")))])
10507
10508 (define_insn "reload_base_31"
10509 [(set (match_operand 0 "register_operand" "=a")
10510 (unspec [(label_ref (match_operand 1 "" ""))] UNSPEC_RELOAD_BASE))]
10511 "!TARGET_CPU_ZARCH && GET_MODE (operands[0]) == Pmode"
10512 "basr\t%0,0\;la\t%0,%1-.(%0)"
10513 [(set_attr "length" "6")
10514 (set_attr "type" "la")
10515 (set_attr "z196prop" "z196_cracked")])
10516
10517 (define_insn "reload_base_64"
10518 [(set (match_operand 0 "register_operand" "=a")
10519 (unspec [(label_ref (match_operand 1 "" ""))] UNSPEC_RELOAD_BASE))]
10520 "TARGET_CPU_ZARCH && GET_MODE (operands[0]) == Pmode"
10521 "larl\t%0,%1"
10522 [(set_attr "op_type" "RIL")
10523 (set_attr "type" "larl")
10524 (set_attr "z10prop" "z10_fwd_A1")])
10525
10526 (define_insn "pool"
10527 [(unspec_volatile [(match_operand 0 "const_int_operand" "n")] UNSPECV_POOL)]
10528 ""
10529 {
10530 gcc_unreachable ();
10531 }
10532 [(set (attr "length") (symbol_ref "INTVAL (operands[0])"))])
10533
10534 ;;
10535 ;; Insns related to generating the function prologue and epilogue.
10536 ;;
10537
10538
10539 (define_expand "prologue"
10540 [(use (const_int 0))]
10541 ""
10542 "s390_emit_prologue (); DONE;")
10543
10544 (define_expand "epilogue"
10545 [(use (const_int 1))]
10546 ""
10547 "s390_emit_epilogue (false); DONE;")
10548
10549 (define_expand "sibcall_epilogue"
10550 [(use (const_int 0))]
10551 ""
10552 "s390_emit_epilogue (true); DONE;")
10553
10554 ;; A direct return instruction, without using an epilogue.
10555 (define_insn "<code>"
10556 [(ANY_RETURN)]
10557 "s390_can_use_<code>_insn ()"
10558 "br\t%%r14"
10559 [(set_attr "op_type" "RR")
10560 (set_attr "type" "jsr")
10561 (set_attr "atype" "agen")])
10562
10563 (define_insn "*return"
10564 [(return)
10565 (use (match_operand 0 "register_operand" "a"))]
10566 "GET_MODE (operands[0]) == Pmode"
10567 "br\t%0"
10568 [(set_attr "op_type" "RR")
10569 (set_attr "type" "jsr")
10570 (set_attr "atype" "agen")])
10571
10572
10573 ;; Instruction definition to extend a 31-bit pointer into a 64-bit
10574 ;; pointer. This is used for compatibility.
10575
10576 (define_expand "ptr_extend"
10577 [(set (match_operand:DI 0 "register_operand" "=r")
10578 (match_operand:SI 1 "register_operand" "r"))]
10579 "TARGET_64BIT"
10580 {
10581 emit_insn (gen_anddi3 (operands[0],
10582 gen_lowpart (DImode, operands[1]),
10583 GEN_INT (0x7fffffff)));
10584 DONE;
10585 })
10586
10587 ;; Instruction definition to expand eh_return macro to support
10588 ;; swapping in special linkage return addresses.
10589
10590 (define_expand "eh_return"
10591 [(use (match_operand 0 "register_operand" ""))]
10592 "TARGET_TPF"
10593 {
10594 s390_emit_tpf_eh_return (operands[0]);
10595 DONE;
10596 })
10597
10598 ;
10599 ; Stack Protector Patterns
10600 ;
10601
10602 (define_expand "stack_protect_set"
10603 [(set (match_operand 0 "memory_operand" "")
10604 (match_operand 1 "memory_operand" ""))]
10605 ""
10606 {
10607 #ifdef TARGET_THREAD_SSP_OFFSET
10608 operands[1]
10609 = gen_rtx_MEM (Pmode, gen_rtx_PLUS (Pmode, s390_get_thread_pointer (),
10610 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
10611 #endif
10612 if (TARGET_64BIT)
10613 emit_insn (gen_stack_protect_setdi (operands[0], operands[1]));
10614 else
10615 emit_insn (gen_stack_protect_setsi (operands[0], operands[1]));
10616
10617 DONE;
10618 })
10619
10620 (define_insn "stack_protect_set<mode>"
10621 [(set (match_operand:DSI 0 "memory_operand" "=Q")
10622 (unspec:DSI [(match_operand:DSI 1 "memory_operand" "Q")] UNSPEC_SP_SET))]
10623 ""
10624 "mvc\t%O0(%G0,%R0),%S1"
10625 [(set_attr "op_type" "SS")])
10626
10627 (define_expand "stack_protect_test"
10628 [(set (reg:CC CC_REGNUM)
10629 (compare (match_operand 0 "memory_operand" "")
10630 (match_operand 1 "memory_operand" "")))
10631 (match_operand 2 "" "")]
10632 ""
10633 {
10634 rtx cc_reg, test;
10635 #ifdef TARGET_THREAD_SSP_OFFSET
10636 operands[1]
10637 = gen_rtx_MEM (Pmode, gen_rtx_PLUS (Pmode, s390_get_thread_pointer (),
10638 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
10639 #endif
10640 if (TARGET_64BIT)
10641 emit_insn (gen_stack_protect_testdi (operands[0], operands[1]));
10642 else
10643 emit_insn (gen_stack_protect_testsi (operands[0], operands[1]));
10644
10645 cc_reg = gen_rtx_REG (CCZmode, CC_REGNUM);
10646 test = gen_rtx_EQ (VOIDmode, cc_reg, const0_rtx);
10647 emit_jump_insn (gen_cbranchcc4 (test, cc_reg, const0_rtx, operands[2]));
10648 DONE;
10649 })
10650
10651 (define_insn "stack_protect_test<mode>"
10652 [(set (reg:CCZ CC_REGNUM)
10653 (unspec:CCZ [(match_operand:DSI 0 "memory_operand" "Q")
10654 (match_operand:DSI 1 "memory_operand" "Q")] UNSPEC_SP_TEST))]
10655 ""
10656 "clc\t%O0(%G0,%R0),%S1"
10657 [(set_attr "op_type" "SS")])
10658
10659 ; This is used in s390_emit_prologue in order to prevent insns
10660 ; adjusting the stack pointer to be moved over insns writing stack
10661 ; slots using a copy of the stack pointer in a different register.
10662 (define_insn "stack_tie"
10663 [(set (match_operand:BLK 0 "memory_operand" "+m")
10664 (unspec:BLK [(match_dup 0)] UNSPEC_TIE))]
10665 ""
10666 ""
10667 [(set_attr "length" "0")])
10668
10669
10670 (define_insn "stack_restore_from_fpr"
10671 [(set (reg:DI STACK_REGNUM)
10672 (match_operand:DI 0 "register_operand" "f"))
10673 (clobber (mem:BLK (scratch)))]
10674 "TARGET_Z10"
10675 "lgdr\t%%r15,%0"
10676 [(set_attr "op_type" "RRE")])
10677
10678 ;
10679 ; Data prefetch patterns
10680 ;
10681
10682 (define_insn "prefetch"
10683 [(prefetch (match_operand 0 "address_operand" "ZT,X")
10684 (match_operand:SI 1 "const_int_operand" " n,n")
10685 (match_operand:SI 2 "const_int_operand" " n,n"))]
10686 "TARGET_Z10"
10687 {
10688 switch (which_alternative)
10689 {
10690 case 0:
10691 return INTVAL (operands[1]) == 1 ? "pfd\t2,%a0" : "pfd\t1,%a0";
10692 case 1:
10693 if (larl_operand (operands[0], Pmode))
10694 return INTVAL (operands[1]) == 1 ? "pfdrl\t2,%a0" : "pfdrl\t1,%a0";
10695 /* fallthrough */
10696 default:
10697
10698 /* This might be reached for symbolic operands with an odd
10699 addend. We simply omit the prefetch for such rare cases. */
10700
10701 return "";
10702 }
10703 }
10704 [(set_attr "type" "load,larl")
10705 (set_attr "op_type" "RXY,RIL")
10706 (set_attr "z10prop" "z10_super")
10707 (set_attr "z196prop" "z196_alone")])
10708
10709
10710 ;
10711 ; Byte swap instructions
10712 ;
10713
10714 ; FIXME: There is also mvcin but we cannot use it since src and target
10715 ; may overlap.
10716 ; lrvr, lrv, strv, lrvgr, lrvg, strvg
10717 (define_insn "bswap<mode>2"
10718 [(set (match_operand:GPR 0 "nonimmediate_operand" "=d,d,T")
10719 (bswap:GPR (match_operand:GPR 1 "nonimmediate_operand" " d,T,d")))]
10720 "TARGET_CPU_ZARCH"
10721 "@
10722 lrv<g>r\t%0,%1
10723 lrv<g>\t%0,%1
10724 strv<g>\t%1,%0"
10725 [(set_attr "type" "*,load,store")
10726 (set_attr "op_type" "RRE,RXY,RXY")
10727 (set_attr "z10prop" "z10_super")])
10728
10729 (define_insn "bswaphi2"
10730 [(set (match_operand:HI 0 "nonimmediate_operand" "=d,d,T")
10731 (bswap:HI (match_operand:HI 1 "nonimmediate_operand" " d,T,d")))]
10732 "TARGET_CPU_ZARCH"
10733 "@
10734 #
10735 lrvh\t%0,%1
10736 strvh\t%1,%0"
10737 [(set_attr "type" "*,load,store")
10738 (set_attr "op_type" "RRE,RXY,RXY")
10739 (set_attr "z10prop" "z10_super")])
10740
10741 (define_split
10742 [(set (match_operand:HI 0 "register_operand" "")
10743 (bswap:HI (match_operand:HI 1 "register_operand" "")))]
10744 "TARGET_CPU_ZARCH"
10745 [(set (match_dup 2) (bswap:SI (match_dup 3)))
10746 (set (match_dup 2) (lshiftrt:SI (match_dup 2) (const_int 16)))]
10747 {
10748 operands[2] = simplify_gen_subreg (SImode, operands[0], HImode, 0);
10749 operands[3] = simplify_gen_subreg (SImode, operands[1], HImode, 0);
10750 })
10751
10752
10753 ;
10754 ; Population count instruction
10755 ;
10756
10757 ; The S/390 popcount instruction counts the bits of op1 in 8 byte
10758 ; portions and stores the result in the corresponding bytes in op0.
10759 (define_insn "*popcount<mode>"
10760 [(set (match_operand:INT 0 "register_operand" "=d")
10761 (unspec:INT [(match_operand:INT 1 "register_operand" "d")] UNSPEC_POPCNT))
10762 (clobber (reg:CC CC_REGNUM))]
10763 "TARGET_Z196"
10764 "popcnt\t%0,%1"
10765 [(set_attr "op_type" "RRE")])
10766
10767 (define_expand "popcountdi2"
10768 [; popcnt op0, op1
10769 (parallel [(set (match_operand:DI 0 "register_operand" "")
10770 (unspec:DI [(match_operand:DI 1 "register_operand")]
10771 UNSPEC_POPCNT))
10772 (clobber (reg:CC CC_REGNUM))])
10773 ; sllg op2, op0, 32
10774 (set (match_dup 2) (ashift:DI (match_dup 0) (const_int 32)))
10775 ; agr op0, op2
10776 (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 2)))
10777 (clobber (reg:CC CC_REGNUM))])
10778 ; sllg op2, op0, 16
10779 (set (match_dup 2)
10780 (ashift:DI (match_dup 0) (const_int 16)))
10781 ; agr op0, op2
10782 (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 2)))
10783 (clobber (reg:CC CC_REGNUM))])
10784 ; sllg op2, op0, 8
10785 (set (match_dup 2) (ashift:DI (match_dup 0) (const_int 8)))
10786 ; agr op0, op2
10787 (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 2)))
10788 (clobber (reg:CC CC_REGNUM))])
10789 ; srlg op0, op0, 56
10790 (set (match_dup 0) (lshiftrt:DI (match_dup 0) (const_int 56)))]
10791 "TARGET_Z196 && TARGET_64BIT"
10792 "operands[2] = gen_reg_rtx (DImode);")
10793
10794 (define_expand "popcountsi2"
10795 [; popcnt op0, op1
10796 (parallel [(set (match_operand:SI 0 "register_operand" "")
10797 (unspec:SI [(match_operand:SI 1 "register_operand")]
10798 UNSPEC_POPCNT))
10799 (clobber (reg:CC CC_REGNUM))])
10800 ; sllk op2, op0, 16
10801 (set (match_dup 2)
10802 (ashift:SI (match_dup 0) (const_int 16)))
10803 ; ar op0, op2
10804 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
10805 (clobber (reg:CC CC_REGNUM))])
10806 ; sllk op2, op0, 8
10807 (set (match_dup 2) (ashift:SI (match_dup 0) (const_int 8)))
10808 ; ar op0, op2
10809 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
10810 (clobber (reg:CC CC_REGNUM))])
10811 ; srl op0, op0, 24
10812 (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 24)))]
10813 "TARGET_Z196"
10814 "operands[2] = gen_reg_rtx (SImode);")
10815
10816 (define_expand "popcounthi2"
10817 [; popcnt op0, op1
10818 (parallel [(set (match_operand:HI 0 "register_operand" "")
10819 (unspec:HI [(match_operand:HI 1 "register_operand")]
10820 UNSPEC_POPCNT))
10821 (clobber (reg:CC CC_REGNUM))])
10822 ; sllk op2, op0, 8
10823 (set (match_dup 2)
10824 (ashift:SI (match_dup 0) (const_int 8)))
10825 ; ar op0, op2
10826 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
10827 (clobber (reg:CC CC_REGNUM))])
10828 ; srl op0, op0, 8
10829 (set (match_dup 0) (lshiftrt:HI (match_dup 0) (const_int 8)))]
10830 "TARGET_Z196"
10831 "operands[2] = gen_reg_rtx (SImode);")
10832
10833 (define_expand "popcountqi2"
10834 [; popcnt op0, op1
10835 (parallel [(set (match_operand:QI 0 "register_operand" "")
10836 (unspec:QI [(match_operand:QI 1 "register_operand")]
10837 UNSPEC_POPCNT))
10838 (clobber (reg:CC CC_REGNUM))])]
10839 "TARGET_Z196"
10840 "")
10841
10842 ;;
10843 ;;- Copy sign instructions
10844 ;;
10845
10846 (define_insn "copysign<mode>3"
10847 [(set (match_operand:FP 0 "register_operand" "=f")
10848 (unspec:FP [(match_operand:FP 1 "register_operand" "<fT0>")
10849 (match_operand:FP 2 "register_operand" "f")]
10850 UNSPEC_COPYSIGN))]
10851 "TARGET_Z196"
10852 "cpsdr\t%0,%2,%1"
10853 [(set_attr "op_type" "RRF")
10854 (set_attr "type" "fsimp<mode>")])
10855
10856
10857 ;;
10858 ;;- Transactional execution instructions
10859 ;;
10860
10861 ; This splitter helps combine to make use of CC directly when
10862 ; comparing the integer result of a tbegin builtin with a constant.
10863 ; The unspec is already removed by canonicalize_comparison. So this
10864 ; splitters only job is to turn the PARALLEL into separate insns
10865 ; again. Unfortunately this only works with the very first cc/int
10866 ; compare since combine is not able to deal with data flow across
10867 ; basic block boundaries.
10868
10869 ; It needs to be an insn pattern as well since combine does not apply
10870 ; the splitter directly. Combine would only use it if it actually
10871 ; would reduce the number of instructions.
10872 (define_insn_and_split "*ccraw_to_int"
10873 [(set (pc)
10874 (if_then_else
10875 (match_operator 0 "s390_eqne_operator"
10876 [(reg:CCRAW CC_REGNUM)
10877 (match_operand 1 "const_int_operand" "")])
10878 (label_ref (match_operand 2 "" ""))
10879 (pc)))
10880 (set (match_operand:SI 3 "register_operand" "=d")
10881 (unspec:SI [(reg:CCRAW CC_REGNUM)] UNSPEC_CC_TO_INT))]
10882 ""
10883 "#"
10884 ""
10885 [(set (match_dup 3)
10886 (unspec:SI [(reg:CCRAW CC_REGNUM)] UNSPEC_CC_TO_INT))
10887 (set (pc)
10888 (if_then_else (match_op_dup 0 [(reg:CCRAW CC_REGNUM) (match_dup 1)])
10889 (label_ref (match_dup 2))
10890 (pc)))]
10891 "")
10892
10893 ; Non-constrained transaction begin
10894
10895 (define_expand "tbegin"
10896 [(match_operand:SI 0 "register_operand" "")
10897 (match_operand:BLK 1 "memory_operand" "")]
10898 "TARGET_HTM"
10899 {
10900 s390_expand_tbegin (operands[0], operands[1], NULL_RTX, true);
10901 DONE;
10902 })
10903
10904 (define_expand "tbegin_nofloat"
10905 [(match_operand:SI 0 "register_operand" "")
10906 (match_operand:BLK 1 "memory_operand" "")]
10907 "TARGET_HTM"
10908 {
10909 s390_expand_tbegin (operands[0], operands[1], NULL_RTX, false);
10910 DONE;
10911 })
10912
10913 (define_expand "tbegin_retry"
10914 [(match_operand:SI 0 "register_operand" "")
10915 (match_operand:BLK 1 "memory_operand" "")
10916 (match_operand:SI 2 "general_operand" "")]
10917 "TARGET_HTM"
10918 {
10919 s390_expand_tbegin (operands[0], operands[1], operands[2], true);
10920 DONE;
10921 })
10922
10923 (define_expand "tbegin_retry_nofloat"
10924 [(match_operand:SI 0 "register_operand" "")
10925 (match_operand:BLK 1 "memory_operand" "")
10926 (match_operand:SI 2 "general_operand" "")]
10927 "TARGET_HTM"
10928 {
10929 s390_expand_tbegin (operands[0], operands[1], operands[2], false);
10930 DONE;
10931 })
10932
10933 ; Clobber VRs since they don't get restored
10934 (define_insn "tbegin_1_z13"
10935 [(set (reg:CCRAW CC_REGNUM)
10936 (unspec_volatile:CCRAW [(match_operand 0 "const_int_operand" "D")]
10937 UNSPECV_TBEGIN))
10938 (set (match_operand:BLK 1 "memory_operand" "=Q")
10939 (unspec_volatile:BLK [(match_dup 0)] UNSPECV_TBEGIN_TDB))
10940 (clobber (reg:TI 16)) (clobber (reg:TI 38))
10941 (clobber (reg:TI 17)) (clobber (reg:TI 39))
10942 (clobber (reg:TI 18)) (clobber (reg:TI 40))
10943 (clobber (reg:TI 19)) (clobber (reg:TI 41))
10944 (clobber (reg:TI 20)) (clobber (reg:TI 42))
10945 (clobber (reg:TI 21)) (clobber (reg:TI 43))
10946 (clobber (reg:TI 22)) (clobber (reg:TI 44))
10947 (clobber (reg:TI 23)) (clobber (reg:TI 45))
10948 (clobber (reg:TI 24)) (clobber (reg:TI 46))
10949 (clobber (reg:TI 25)) (clobber (reg:TI 47))
10950 (clobber (reg:TI 26)) (clobber (reg:TI 48))
10951 (clobber (reg:TI 27)) (clobber (reg:TI 49))
10952 (clobber (reg:TI 28)) (clobber (reg:TI 50))
10953 (clobber (reg:TI 29)) (clobber (reg:TI 51))
10954 (clobber (reg:TI 30)) (clobber (reg:TI 52))
10955 (clobber (reg:TI 31)) (clobber (reg:TI 53))]
10956 ; CONST_OK_FOR_CONSTRAINT_P does not work with D constraint since D is
10957 ; not supposed to be used for immediates (see genpreds.c).
10958 "TARGET_VX && INTVAL (operands[0]) >= 0 && INTVAL (operands[0]) <= 0xffff"
10959 "tbegin\t%1,%x0"
10960 [(set_attr "op_type" "SIL")])
10961
10962 (define_insn "tbegin_1"
10963 [(set (reg:CCRAW CC_REGNUM)
10964 (unspec_volatile:CCRAW [(match_operand 0 "const_int_operand" "D")]
10965 UNSPECV_TBEGIN))
10966 (set (match_operand:BLK 1 "memory_operand" "=Q")
10967 (unspec_volatile:BLK [(match_dup 0)] UNSPECV_TBEGIN_TDB))
10968 (clobber (reg:DF 16))
10969 (clobber (reg:DF 17))
10970 (clobber (reg:DF 18))
10971 (clobber (reg:DF 19))
10972 (clobber (reg:DF 20))
10973 (clobber (reg:DF 21))
10974 (clobber (reg:DF 22))
10975 (clobber (reg:DF 23))
10976 (clobber (reg:DF 24))
10977 (clobber (reg:DF 25))
10978 (clobber (reg:DF 26))
10979 (clobber (reg:DF 27))
10980 (clobber (reg:DF 28))
10981 (clobber (reg:DF 29))
10982 (clobber (reg:DF 30))
10983 (clobber (reg:DF 31))]
10984 ; CONST_OK_FOR_CONSTRAINT_P does not work with D constraint since D is
10985 ; not supposed to be used for immediates (see genpreds.c).
10986 "TARGET_HTM && INTVAL (operands[0]) >= 0 && INTVAL (operands[0]) <= 0xffff"
10987 "tbegin\t%1,%x0"
10988 [(set_attr "op_type" "SIL")])
10989
10990 ; Same as above but without the FPR clobbers
10991 (define_insn "tbegin_nofloat_1"
10992 [(set (reg:CCRAW CC_REGNUM)
10993 (unspec_volatile:CCRAW [(match_operand 0 "const_int_operand" "D")]
10994 UNSPECV_TBEGIN))
10995 (set (match_operand:BLK 1 "memory_operand" "=Q")
10996 (unspec_volatile:BLK [(match_dup 0)] UNSPECV_TBEGIN_TDB))]
10997 "TARGET_HTM && INTVAL (operands[0]) >= 0 && INTVAL (operands[0]) <= 0xffff"
10998 "tbegin\t%1,%x0"
10999 [(set_attr "op_type" "SIL")])
11000
11001
11002 ; Constrained transaction begin
11003
11004 (define_expand "tbeginc"
11005 [(set (reg:CCRAW CC_REGNUM)
11006 (unspec_volatile:CCRAW [(const_int TBEGINC_MASK)]
11007 UNSPECV_TBEGINC))]
11008 "TARGET_HTM"
11009 "")
11010
11011 (define_insn "*tbeginc_1"
11012 [(set (reg:CCRAW CC_REGNUM)
11013 (unspec_volatile:CCRAW [(match_operand 0 "const_int_operand" " D")]
11014 UNSPECV_TBEGINC))]
11015 "TARGET_HTM && INTVAL (operands[0]) >= 0 && INTVAL (operands[0]) <= 0xffff"
11016 "tbeginc\t0,%x0"
11017 [(set_attr "op_type" "SIL")])
11018
11019 ; Transaction end
11020
11021 (define_expand "tend"
11022 [(set (reg:CCRAW CC_REGNUM)
11023 (unspec_volatile:CCRAW [(const_int 0)] UNSPECV_TEND))
11024 (set (match_operand:SI 0 "register_operand" "")
11025 (unspec:SI [(reg:CCRAW CC_REGNUM)] UNSPEC_CC_TO_INT))]
11026 "TARGET_HTM"
11027 "")
11028
11029 (define_insn "*tend_1"
11030 [(set (reg:CCRAW CC_REGNUM)
11031 (unspec_volatile:CCRAW [(const_int 0)] UNSPECV_TEND))]
11032 "TARGET_HTM"
11033 "tend"
11034 [(set_attr "op_type" "S")])
11035
11036 ; Transaction abort
11037
11038 (define_expand "tabort"
11039 [(unspec_volatile [(match_operand:SI 0 "nonmemory_operand" "")]
11040 UNSPECV_TABORT)]
11041 "TARGET_HTM && operands != NULL"
11042 {
11043 if (CONST_INT_P (operands[0])
11044 && INTVAL (operands[0]) >= 0 && INTVAL (operands[0]) <= 255)
11045 {
11046 error ("invalid transaction abort code: " HOST_WIDE_INT_PRINT_DEC
11047 ". Values in range 0 through 255 are reserved.",
11048 INTVAL (operands[0]));
11049 FAIL;
11050 }
11051 })
11052
11053 (define_insn "*tabort_1"
11054 [(unspec_volatile [(match_operand:SI 0 "nonmemory_operand" "aJ")]
11055 UNSPECV_TABORT)]
11056 "TARGET_HTM && operands != NULL"
11057 "tabort\t%Y0"
11058 [(set_attr "op_type" "S")])
11059
11060 (define_insn "*tabort_1_plus"
11061 [(unspec_volatile [(plus:SI (match_operand:SI 0 "register_operand" "a")
11062 (match_operand:SI 1 "const_int_operand" "J"))]
11063 UNSPECV_TABORT)]
11064 "TARGET_HTM && operands != NULL
11065 && CONST_OK_FOR_CONSTRAINT_P (INTVAL (operands[1]), 'J', \"J\")"
11066 "tabort\t%1(%0)"
11067 [(set_attr "op_type" "S")])
11068
11069 ; Transaction extract nesting depth
11070
11071 (define_insn "etnd"
11072 [(set (match_operand:SI 0 "register_operand" "=d")
11073 (unspec_volatile:SI [(const_int 0)] UNSPECV_ETND))]
11074 "TARGET_HTM"
11075 "etnd\t%0"
11076 [(set_attr "op_type" "RRE")])
11077
11078 ; Non-transactional store
11079
11080 (define_insn "ntstg"
11081 [(set (match_operand:DI 0 "memory_operand" "=T")
11082 (unspec_volatile:DI [(match_operand:DI 1 "register_operand" "d")]
11083 UNSPECV_NTSTG))]
11084 "TARGET_HTM"
11085 "ntstg\t%1,%0"
11086 [(set_attr "op_type" "RXY")])
11087
11088 ; Transaction perform processor assist
11089
11090 (define_expand "tx_assist"
11091 [(unspec_volatile [(match_operand:SI 0 "register_operand" "")
11092 (reg:SI GPR0_REGNUM)
11093 (const_int 1)]
11094 UNSPECV_PPA)]
11095 "TARGET_HTM"
11096 "")
11097
11098 (define_insn "*ppa"
11099 [(unspec_volatile [(match_operand:SI 0 "register_operand" "d")
11100 (match_operand:SI 1 "register_operand" "d")
11101 (match_operand 2 "const_int_operand" "I")]
11102 UNSPECV_PPA)]
11103 "TARGET_HTM && INTVAL (operands[2]) < 16"
11104 "ppa\t%0,%1,%2"
11105 [(set_attr "op_type" "RRF")])
11106
11107
11108 ; Set and get floating point control register
11109
11110 (define_insn "sfpc"
11111 [(unspec_volatile [(match_operand:SI 0 "register_operand" "d")]
11112 UNSPECV_SFPC)]
11113 "TARGET_HARD_FLOAT"
11114 "sfpc\t%0")
11115
11116 (define_insn "efpc"
11117 [(set (match_operand:SI 0 "register_operand" "=d")
11118 (unspec_volatile:SI [(const_int 0)] UNSPECV_EFPC))]
11119 "TARGET_HARD_FLOAT"
11120 "efpc\t%0")
11121
11122
11123 ; Load count to block boundary
11124
11125 (define_insn "lcbb"
11126 [(set (match_operand:SI 0 "register_operand" "=d")
11127 (unspec:SI [(match_operand 1 "address_operand" "ZR")
11128 (match_operand:SI 2 "immediate_operand" "C")] UNSPEC_LCBB))
11129 (clobber (reg:CC CC_REGNUM))]
11130 "TARGET_Z13"
11131 "lcbb\t%0,%a1,%b2"
11132 [(set_attr "op_type" "VRX")])
11133
11134 ; Handle -fsplit-stack.
11135
11136 (define_expand "split_stack_prologue"
11137 [(const_int 0)]
11138 ""
11139 {
11140 s390_expand_split_stack_prologue ();
11141 DONE;
11142 })
11143
11144 ;; If there are operand 0 bytes available on the stack, jump to
11145 ;; operand 1.
11146
11147 (define_expand "split_stack_space_check"
11148 [(set (pc) (if_then_else
11149 (ltu (minus (reg 15)
11150 (match_operand 0 "register_operand"))
11151 (unspec [(const_int 0)] UNSPEC_STACK_CHECK))
11152 (label_ref (match_operand 1))
11153 (pc)))]
11154 ""
11155 {
11156 /* Offset from thread pointer to __private_ss. */
11157 int psso = TARGET_64BIT ? 0x38 : 0x20;
11158 rtx tp = s390_get_thread_pointer ();
11159 rtx guard = gen_rtx_MEM (Pmode, plus_constant (Pmode, tp, psso));
11160 rtx reg = gen_reg_rtx (Pmode);
11161 rtx cc;
11162 if (TARGET_64BIT)
11163 emit_insn (gen_subdi3 (reg, stack_pointer_rtx, operands[0]));
11164 else
11165 emit_insn (gen_subsi3 (reg, stack_pointer_rtx, operands[0]));
11166 cc = s390_emit_compare (GT, reg, guard);
11167 s390_emit_jump (operands[1], cc);
11168
11169 DONE;
11170 })
11171
11172 ;; __morestack parameter block for split stack prologue. Parameters are:
11173 ;; parameter block label, label to be called by __morestack, frame size,
11174 ;; stack parameter size.
11175
11176 (define_insn "split_stack_data"
11177 [(unspec_volatile [(match_operand 0 "" "X")
11178 (match_operand 1 "" "X")
11179 (match_operand 2 "const_int_operand" "X")
11180 (match_operand 3 "const_int_operand" "X")]
11181 UNSPECV_SPLIT_STACK_DATA)]
11182 "TARGET_CPU_ZARCH"
11183 {
11184 switch_to_section (targetm.asm_out.function_rodata_section
11185 (current_function_decl));
11186
11187 if (TARGET_64BIT)
11188 output_asm_insn (".align\t8", operands);
11189 else
11190 output_asm_insn (".align\t4", operands);
11191 (*targetm.asm_out.internal_label) (asm_out_file, "L",
11192 CODE_LABEL_NUMBER (operands[0]));
11193 if (TARGET_64BIT)
11194 {
11195 output_asm_insn (".quad\t%2", operands);
11196 output_asm_insn (".quad\t%3", operands);
11197 output_asm_insn (".quad\t%1-%0", operands);
11198 }
11199 else
11200 {
11201 output_asm_insn (".long\t%2", operands);
11202 output_asm_insn (".long\t%3", operands);
11203 output_asm_insn (".long\t%1-%0", operands);
11204 }
11205
11206 switch_to_section (current_function_section ());
11207 return "";
11208 }
11209 [(set_attr "length" "0")])
11210
11211
11212 ;; A jg with minimal fuss for use in split stack prologue.
11213
11214 (define_expand "split_stack_call"
11215 [(match_operand 0 "bras_sym_operand" "X")
11216 (match_operand 1 "" "")]
11217 "TARGET_CPU_ZARCH"
11218 {
11219 if (TARGET_64BIT)
11220 emit_jump_insn (gen_split_stack_call_di (operands[0], operands[1]));
11221 else
11222 emit_jump_insn (gen_split_stack_call_si (operands[0], operands[1]));
11223 DONE;
11224 })
11225
11226 (define_insn "split_stack_call_<mode>"
11227 [(set (pc) (label_ref (match_operand 1 "" "")))
11228 (set (reg:P 1) (unspec_volatile [(match_operand 0 "bras_sym_operand" "X")
11229 (reg:P 1)]
11230 UNSPECV_SPLIT_STACK_CALL))]
11231 "TARGET_CPU_ZARCH"
11232 "jg\t%0"
11233 [(set_attr "op_type" "RIL")
11234 (set_attr "type" "branch")])
11235
11236 ;; Also a conditional one.
11237
11238 (define_expand "split_stack_cond_call"
11239 [(match_operand 0 "bras_sym_operand" "X")
11240 (match_operand 1 "" "")
11241 (match_operand 2 "" "")]
11242 "TARGET_CPU_ZARCH"
11243 {
11244 if (TARGET_64BIT)
11245 emit_jump_insn (gen_split_stack_cond_call_di (operands[0], operands[1], operands[2]));
11246 else
11247 emit_jump_insn (gen_split_stack_cond_call_si (operands[0], operands[1], operands[2]));
11248 DONE;
11249 })
11250
11251 (define_insn "split_stack_cond_call_<mode>"
11252 [(set (pc)
11253 (if_then_else
11254 (match_operand 1 "" "")
11255 (label_ref (match_operand 2 "" ""))
11256 (pc)))
11257 (set (reg:P 1) (unspec_volatile [(match_operand 0 "bras_sym_operand" "X")
11258 (reg:P 1)]
11259 UNSPECV_SPLIT_STACK_CALL))]
11260 "TARGET_CPU_ZARCH"
11261 "jg%C1\t%0"
11262 [(set_attr "op_type" "RIL")
11263 (set_attr "type" "branch")])
11264
11265 (define_insn "osc_break"
11266 [(unspec_volatile [(const_int 0)] UNSPECV_OSC_BREAK)]
11267 ""
11268 "bcr\t7,%%r0"
11269 [(set_attr "op_type" "RR")])