S/390: PR68015 Fix ICE in s390_emit_compare
[gcc.git] / gcc / config / s390 / s390.md
1 ;;- Machine description for GNU compiler -- S/390 / zSeries version.
2 ;; Copyright (C) 1999-2015 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 ; GOT/PLT and lt-relative accesses
74 UNSPEC_LTREL_OFFSET
75 UNSPEC_LTREL_BASE
76 UNSPEC_POOL_OFFSET
77 UNSPEC_GOTENT
78 UNSPEC_GOT
79 UNSPEC_GOTOFF
80 UNSPEC_PLT
81 UNSPEC_PLTOFF
82
83 ; Literal pool
84 UNSPEC_RELOAD_BASE
85 UNSPEC_MAIN_BASE
86 UNSPEC_LTREF
87 UNSPEC_INSN
88 UNSPEC_EXECUTE
89
90 ; Atomic Support
91 UNSPEC_MB
92 UNSPEC_MOVA
93
94 ; TLS relocation specifiers
95 UNSPEC_TLSGD
96 UNSPEC_TLSLDM
97 UNSPEC_NTPOFF
98 UNSPEC_DTPOFF
99 UNSPEC_GOTNTPOFF
100 UNSPEC_INDNTPOFF
101
102 ; TLS support
103 UNSPEC_TLSLDM_NTPOFF
104 UNSPEC_TLS_LOAD
105
106 ; String Functions
107 UNSPEC_SRST
108 UNSPEC_MVST
109
110 ; Stack Smashing Protector
111 UNSPEC_SP_SET
112 UNSPEC_SP_TEST
113
114 ; Test Data Class (TDC)
115 UNSPEC_TDC_INSN
116
117 ; Population Count
118 UNSPEC_POPCNT
119 UNSPEC_COPYSIGN
120
121 ; Load FP Integer
122 UNSPEC_FPINT_FLOOR
123 UNSPEC_FPINT_BTRUNC
124 UNSPEC_FPINT_ROUND
125 UNSPEC_FPINT_CEIL
126 UNSPEC_FPINT_NEARBYINT
127 UNSPEC_FPINT_RINT
128
129 UNSPEC_LCBB
130
131 ; Vector
132 UNSPEC_VEC_SMULT_HI
133 UNSPEC_VEC_UMULT_HI
134 UNSPEC_VEC_SMULT_LO
135 UNSPEC_VEC_SMULT_EVEN
136 UNSPEC_VEC_UMULT_EVEN
137 UNSPEC_VEC_SMULT_ODD
138 UNSPEC_VEC_UMULT_ODD
139
140 UNSPEC_VEC_VMAL
141 UNSPEC_VEC_VMAH
142 UNSPEC_VEC_VMALH
143 UNSPEC_VEC_VMAE
144 UNSPEC_VEC_VMALE
145 UNSPEC_VEC_VMAO
146 UNSPEC_VEC_VMALO
147
148 UNSPEC_VEC_GATHER
149 UNSPEC_VEC_EXTRACT
150 UNSPEC_VEC_INSERT_AND_ZERO
151 UNSPEC_VEC_LOAD_BNDRY
152 UNSPEC_VEC_LOAD_LEN
153 UNSPEC_VEC_MERGEH
154 UNSPEC_VEC_MERGEL
155 UNSPEC_VEC_PACK
156 UNSPEC_VEC_PACK_SATURATE
157 UNSPEC_VEC_PACK_SATURATE_CC
158 UNSPEC_VEC_PACK_SATURATE_GENCC
159 UNSPEC_VEC_PACK_UNSIGNED_SATURATE
160 UNSPEC_VEC_PACK_UNSIGNED_SATURATE_CC
161 UNSPEC_VEC_PACK_UNSIGNED_SATURATE_GENCC
162 UNSPEC_VEC_PERM
163 UNSPEC_VEC_PERMI
164 UNSPEC_VEC_EXTEND
165 UNSPEC_VEC_STORE_LEN
166 UNSPEC_VEC_UNPACKH
167 UNSPEC_VEC_UNPACKH_L
168 UNSPEC_VEC_UNPACKL
169 UNSPEC_VEC_UNPACKL_L
170 UNSPEC_VEC_ADDC
171 UNSPEC_VEC_ADDC_U128
172 UNSPEC_VEC_ADDE_U128
173 UNSPEC_VEC_ADDEC_U128
174 UNSPEC_VEC_AVG
175 UNSPEC_VEC_AVGU
176 UNSPEC_VEC_CHECKSUM
177 UNSPEC_VEC_GFMSUM
178 UNSPEC_VEC_GFMSUM_128
179 UNSPEC_VEC_GFMSUM_ACCUM
180 UNSPEC_VEC_GFMSUM_ACCUM_128
181 UNSPEC_VEC_SET
182
183 UNSPEC_VEC_VSUMG
184 UNSPEC_VEC_VSUMQ
185 UNSPEC_VEC_VSUM
186 UNSPEC_VEC_RL_MASK
187 UNSPEC_VEC_SLL
188 UNSPEC_VEC_SLB
189 UNSPEC_VEC_SLDB
190 UNSPEC_VEC_SRAL
191 UNSPEC_VEC_SRAB
192 UNSPEC_VEC_SRL
193 UNSPEC_VEC_SRLB
194
195 UNSPEC_VEC_SUB_U128
196 UNSPEC_VEC_SUBC
197 UNSPEC_VEC_SUBC_U128
198 UNSPEC_VEC_SUBE_U128
199 UNSPEC_VEC_SUBEC_U128
200
201 UNSPEC_VEC_TEST_MASK
202
203 UNSPEC_VEC_VFAE
204 UNSPEC_VEC_VFAECC
205
206 UNSPEC_VEC_VFEE
207 UNSPEC_VEC_VFEECC
208 UNSPEC_VEC_VFENE
209 UNSPEC_VEC_VFENECC
210
211 UNSPEC_VEC_VISTR
212 UNSPEC_VEC_VISTRCC
213
214 UNSPEC_VEC_VSTRC
215 UNSPEC_VEC_VSTRCCC
216
217 UNSPEC_VEC_VCDGB
218 UNSPEC_VEC_VCDLGB
219
220 UNSPEC_VEC_VCGDB
221 UNSPEC_VEC_VCLGDB
222
223 UNSPEC_VEC_VFIDB
224
225 UNSPEC_VEC_VLDEB
226 UNSPEC_VEC_VLEDB
227
228 UNSPEC_VEC_VFTCIDB
229 UNSPEC_VEC_VFTCIDBCC
230 ])
231
232 ;;
233 ;; UNSPEC_VOLATILE usage
234 ;;
235
236 (define_c_enum "unspecv" [
237 ; Blockage
238 UNSPECV_BLOCKAGE
239
240 ; TPF Support
241 UNSPECV_TPF_PROLOGUE
242 UNSPECV_TPF_EPILOGUE
243
244 ; Literal pool
245 UNSPECV_POOL
246 UNSPECV_POOL_SECTION
247 UNSPECV_POOL_ALIGN
248 UNSPECV_POOL_ENTRY
249 UNSPECV_MAIN_POOL
250
251 ; TLS support
252 UNSPECV_SET_TP
253
254 ; Atomic Support
255 UNSPECV_CAS
256 UNSPECV_ATOMIC_OP
257
258 ; Hotpatching (unremovable NOPs)
259 UNSPECV_NOP_2_BYTE
260 UNSPECV_NOP_4_BYTE
261 UNSPECV_NOP_6_BYTE
262
263 ; Transactional Execution support
264 UNSPECV_TBEGIN
265 UNSPECV_TBEGIN_TDB
266 UNSPECV_TBEGINC
267 UNSPECV_TEND
268 UNSPECV_TABORT
269 UNSPECV_ETND
270 UNSPECV_NTSTG
271 UNSPECV_PPA
272
273 ; Set and get floating point control register
274 UNSPECV_SFPC
275 UNSPECV_EFPC
276 ])
277
278 ;;
279 ;; Registers
280 ;;
281
282 ; Registers with special meaning
283
284 (define_constants
285 [
286 ; Sibling call register.
287 (SIBCALL_REGNUM 1)
288 ; Literal pool base register.
289 (BASE_REGNUM 13)
290 ; Return address register.
291 (RETURN_REGNUM 14)
292 ; Condition code register.
293 (CC_REGNUM 33)
294 ; Thread local storage pointer register.
295 (TP_REGNUM 36)
296 ])
297
298 ; Hardware register names
299
300 (define_constants
301 [
302 ; General purpose registers
303 (GPR0_REGNUM 0)
304 ; Floating point registers.
305 (FPR0_REGNUM 16)
306 (FPR1_REGNUM 20)
307 (FPR2_REGNUM 17)
308 (FPR3_REGNUM 21)
309 (FPR4_REGNUM 18)
310 (FPR5_REGNUM 22)
311 (FPR6_REGNUM 19)
312 (FPR7_REGNUM 23)
313 (FPR8_REGNUM 24)
314 (FPR9_REGNUM 28)
315 (FPR10_REGNUM 25)
316 (FPR11_REGNUM 29)
317 (FPR12_REGNUM 26)
318 (FPR13_REGNUM 30)
319 (FPR14_REGNUM 27)
320 (FPR15_REGNUM 31)
321 (VR0_REGNUM 16)
322 (VR16_REGNUM 38)
323 (VR23_REGNUM 45)
324 (VR24_REGNUM 46)
325 (VR31_REGNUM 53)
326 ])
327
328 ;;
329 ;; PFPO GPR0 argument format
330 ;;
331
332 (define_constants
333 [
334 ; PFPO operation type
335 (PFPO_CONVERT 0x1000000)
336 ; PFPO operand types
337 (PFPO_OP_TYPE_SF 0x5)
338 (PFPO_OP_TYPE_DF 0x6)
339 (PFPO_OP_TYPE_TF 0x7)
340 (PFPO_OP_TYPE_SD 0x8)
341 (PFPO_OP_TYPE_DD 0x9)
342 (PFPO_OP_TYPE_TD 0xa)
343 ; Bitposition of operand types
344 (PFPO_OP0_TYPE_SHIFT 16)
345 (PFPO_OP1_TYPE_SHIFT 8)
346 ])
347
348 ; Immediate operands for tbegin and tbeginc
349 (define_constants [(TBEGIN_MASK 65292)]) ; 0xff0c
350 (define_constants [(TBEGINC_MASK 65288)]) ; 0xff08
351
352 ;; Instruction operand type as used in the Principles of Operation.
353 ;; Used to determine defaults for length and other attribute values.
354
355 (define_attr "op_type"
356 "NN,E,RR,RRE,RX,RS,RSI,RI,SI,S,SS,SSE,RXE,RSE,RIL,RIE,RXY,RSY,SIY,RRF,RRR,SIL,RRS,RIS,VRI,VRR,VRS,VRV,VRX"
357 (const_string "NN"))
358
359 ;; Instruction type attribute used for scheduling.
360
361 (define_attr "type" "none,integer,load,lr,la,larl,lm,stm,
362 cs,vs,store,sem,idiv,
363 imulhi,imulsi,imuldi,
364 branch,jsr,fsimptf,fsimpdf,fsimpsf,fhex,
365 floadtf,floaddf,floadsf,fstoredf,fstoresf,
366 fmultf,fmuldf,fmulsf,fdivtf,fdivdf,fdivsf,
367 ftoi,fsqrttf,fsqrtdf,fsqrtsf,
368 fmadddf,fmaddsf,
369 ftrunctf,ftruncdf, ftruncsd, ftruncdd,
370 itoftf, itofdf, itofsf, itofdd, itoftd,
371 fdivdd, fdivtd, floaddd, floadsd, fmuldd, fmultd,
372 fsimpdd, fsimpsd, fsimptd, fstoredd, fstoresd,
373 ftoidfp, other"
374 (cond [(eq_attr "op_type" "NN") (const_string "other")
375 (eq_attr "op_type" "SS") (const_string "cs")]
376 (const_string "integer")))
377
378 ;; Another attribute used for scheduling purposes:
379 ;; agen: Instruction uses the address generation unit
380 ;; reg: Instruction does not use the agen unit
381
382 (define_attr "atype" "agen,reg"
383 (if_then_else (eq_attr "op_type" "E,RR,RI,RRE,RSI,RIL,RIE,RRF,RRR")
384 (const_string "reg")
385 (const_string "agen")))
386
387 ;; Properties concerning Z10 execution grouping and value forwarding.
388 ;; z10_super: instruction is superscalar.
389 ;; z10_super_c: instruction is superscalar and meets the condition of z10_c.
390 ;; z10_fwd: The instruction reads the value of an operand and stores it into a
391 ;; target register. It can forward this value to a second instruction that reads
392 ;; the same register if that second instruction is issued in the same group.
393 ;; z10_rec: The instruction is in the T pipeline and reads a register. If the
394 ;; instruction in the S pipe writes to the register, then the T instruction
395 ;; can immediately read the new value.
396 ;; z10_fr: union of Z10_fwd and z10_rec.
397 ;; z10_c: second operand of instruction is a register and read with complemented bits.
398 ;;
399 ;; An additional suffix A1, A3, or E1 indicates the respective AGI bypass.
400
401
402 (define_attr "z10prop" "none,
403 z10_super, z10_super_E1, z10_super_A1, z10_super_c, z10_super_c_E1,
404 z10_fwd, z10_fwd_A1, z10_fwd_A3, z10_fwd_E1,
405 z10_rec,
406 z10_fr, z10_fr_A3, z10_fr_E1,
407 z10_c"
408 (const_string "none"))
409
410 ;; Properties concerning Z196 decoding
411 ;; z196_alone: must group alone
412 ;; z196_end: ends a group
413 ;; z196_cracked: instruction is cracked or expanded
414 (define_attr "z196prop" "none,
415 z196_alone, z196_ends,
416 z196_cracked"
417 (const_string "none"))
418
419 (define_attr "mnemonic" "bcr_flush,unknown" (const_string "unknown"))
420
421 ;; Length in bytes.
422
423 (define_attr "length" ""
424 (cond [(eq_attr "op_type" "E,RR") (const_int 2)
425 (eq_attr "op_type" "RX,RI,RRE,RS,RSI,S,SI,RRF,RRR") (const_int 4)]
426 (const_int 6)))
427
428
429 ;; Processor type. This attribute must exactly match the processor_type
430 ;; enumeration in s390.h. The current machine description does not
431 ;; distinguish between g5 and g6, but there are differences between the two
432 ;; CPUs could in theory be modeled.
433
434 (define_attr "cpu" "g5,g6,z900,z990,z9_109,z9_ec,z10,z196,zEC12,z13"
435 (const (symbol_ref "s390_tune_attr")))
436
437 (define_attr "cpu_facility"
438 "standard,ieee,zarch,cpu_zarch,longdisp,extimm,dfp,z10,z196,zEC12,vec"
439 (const_string "standard"))
440
441 (define_attr "enabled" ""
442 (cond [(eq_attr "cpu_facility" "standard")
443 (const_int 1)
444
445 (and (eq_attr "cpu_facility" "ieee")
446 (match_test "TARGET_CPU_IEEE_FLOAT"))
447 (const_int 1)
448
449 (and (eq_attr "cpu_facility" "zarch")
450 (match_test "TARGET_ZARCH"))
451 (const_int 1)
452
453 (and (eq_attr "cpu_facility" "longdisp")
454 (match_test "TARGET_LONG_DISPLACEMENT"))
455 (const_int 1)
456
457 (and (eq_attr "cpu_facility" "extimm")
458 (match_test "TARGET_EXTIMM"))
459 (const_int 1)
460
461 (and (eq_attr "cpu_facility" "dfp")
462 (match_test "TARGET_DFP"))
463 (const_int 1)
464
465 (and (eq_attr "cpu_facility" "cpu_zarch")
466 (match_test "TARGET_CPU_ZARCH"))
467 (const_int 1)
468
469 (and (eq_attr "cpu_facility" "z10")
470 (match_test "TARGET_Z10"))
471 (const_int 1)
472
473 (and (eq_attr "cpu_facility" "z196")
474 (match_test "TARGET_Z196"))
475 (const_int 1)
476
477 (and (eq_attr "cpu_facility" "zEC12")
478 (match_test "TARGET_ZEC12"))
479 (const_int 1)
480
481 (and (eq_attr "cpu_facility" "vec")
482 (match_test "TARGET_VX"))
483 (const_int 1)]
484 (const_int 0)))
485
486 ;; Pipeline description for z900. For lack of anything better,
487 ;; this description is also used for the g5 and g6.
488 (include "2064.md")
489
490 ;; Pipeline description for z990, z9-109 and z9-ec.
491 (include "2084.md")
492
493 ;; Pipeline description for z10
494 (include "2097.md")
495
496 ;; Pipeline description for z196
497 (include "2817.md")
498
499 ;; Pipeline description for zEC12
500 (include "2827.md")
501
502 ;; Predicates
503 (include "predicates.md")
504
505 ;; Constraint definitions
506 (include "constraints.md")
507
508 ;; Other includes
509 (include "tpf.md")
510
511 ;; Iterators
512
513 (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])
514
515 ;; These mode iterators allow floating point patterns to be generated from the
516 ;; same template.
517 (define_mode_iterator FP_ALL [TF DF SF (TD "TARGET_HARD_DFP") (DD "TARGET_HARD_DFP")
518 (SD "TARGET_HARD_DFP")])
519 (define_mode_iterator FP [TF DF SF (TD "TARGET_HARD_DFP") (DD "TARGET_HARD_DFP")])
520 (define_mode_iterator BFP [TF DF SF])
521 (define_mode_iterator DFP [TD DD])
522 (define_mode_iterator DFP_ALL [TD DD SD])
523 (define_mode_iterator DSF [DF SF])
524 (define_mode_iterator SD_SF [SF SD])
525 (define_mode_iterator DD_DF [DF DD])
526 (define_mode_iterator TD_TF [TF TD])
527
528 ;; These mode iterators allow 31-bit and 64-bit GPR patterns to be generated
529 ;; from the same template.
530 (define_mode_iterator GPR [(DI "TARGET_ZARCH") SI])
531 (define_mode_iterator DGPR [(TI "TARGET_ZARCH") DI SI])
532 (define_mode_iterator DSI [DI SI])
533 (define_mode_iterator TDI [TI DI])
534
535 ;; These mode iterators allow :P to be used for patterns that operate on
536 ;; pointer-sized quantities. Exactly one of the two alternatives will match.
537 (define_mode_iterator P [(DI "TARGET_64BIT") (SI "!TARGET_64BIT")])
538
539 ;; These macros refer to the actual word_mode of the configuration.
540 ;; This is equal to Pmode except on 31-bit machines in zarch mode.
541 (define_mode_iterator DW [(TI "TARGET_ZARCH") (DI "!TARGET_ZARCH")])
542 (define_mode_iterator W [(DI "TARGET_ZARCH") (SI "!TARGET_ZARCH")])
543
544 ;; Used by the umul pattern to express modes having half the size.
545 (define_mode_attr DWH [(TI "DI") (DI "SI")])
546 (define_mode_attr dwh [(TI "di") (DI "si")])
547
548 ;; This mode iterator allows the QI and HI patterns to be defined from
549 ;; the same template.
550 (define_mode_iterator HQI [HI QI])
551
552 ;; This mode iterator allows the integer patterns to be defined from the
553 ;; same template.
554 (define_mode_iterator INT [(DI "TARGET_ZARCH") SI HI QI])
555 (define_mode_iterator DINT [(TI "TARGET_ZARCH") DI SI HI QI])
556
557 ;; This iterator allows some 'ashift' and 'lshiftrt' pattern to be defined from
558 ;; the same template.
559 (define_code_iterator SHIFT [ashift lshiftrt])
560
561 ;; This iterator allows r[ox]sbg to be defined with the same template
562 (define_code_iterator IXOR [ior xor])
563
564 ;; This iterator is used to expand the patterns for the nearest
565 ;; integer functions.
566 (define_int_iterator FPINT [UNSPEC_FPINT_FLOOR UNSPEC_FPINT_BTRUNC
567 UNSPEC_FPINT_ROUND UNSPEC_FPINT_CEIL
568 UNSPEC_FPINT_NEARBYINT])
569 (define_int_attr fpint_name [(UNSPEC_FPINT_FLOOR "floor")
570 (UNSPEC_FPINT_BTRUNC "btrunc")
571 (UNSPEC_FPINT_ROUND "round")
572 (UNSPEC_FPINT_CEIL "ceil")
573 (UNSPEC_FPINT_NEARBYINT "nearbyint")])
574 (define_int_attr fpint_roundingmode [(UNSPEC_FPINT_FLOOR "7")
575 (UNSPEC_FPINT_BTRUNC "5")
576 (UNSPEC_FPINT_ROUND "1")
577 (UNSPEC_FPINT_CEIL "6")
578 (UNSPEC_FPINT_NEARBYINT "0")])
579
580 ;; This iterator and attribute allow to combine most atomic operations.
581 (define_code_iterator ATOMIC [and ior xor plus minus mult])
582 (define_code_iterator ATOMIC_Z196 [and ior xor plus])
583 (define_code_attr atomic [(and "and") (ior "or") (xor "xor")
584 (plus "add") (minus "sub") (mult "nand")])
585 (define_code_attr noxa [(and "n") (ior "o") (xor "x") (plus "a")])
586
587 ;; In FP templates, a string like "lt<de>br" will expand to "ltxbr" in
588 ;; TF/TDmode, "ltdbr" in DF/DDmode, and "ltebr" in SF/SDmode.
589 (define_mode_attr xde [(TF "x") (DF "d") (SF "e") (TD "x") (DD "d") (SD "e")])
590
591 ;; In FP templates, a <dee> in "m<dee><bt>r" will expand to "mx<bt>r" in
592 ;; TF/TDmode, "md<bt>r" in DF/DDmode, "mee<bt>r" in SFmode and "me<bt>r in
593 ;; SDmode.
594 (define_mode_attr xdee [(TF "x") (DF "d") (SF "ee") (TD "x") (DD "d") (SD "e")])
595
596 ;; In FP templates, "<RRe>" will expand to "RRE" in TFmode and "RR" otherwise.
597 ;; Likewise for "<RXe>".
598 (define_mode_attr RRe [(TF "RRE") (DF "RR") (SF "RR")])
599 (define_mode_attr RXe [(TF "RXE") (DF "RX") (SF "RX")])
600
601 ;; The decimal floating point variants of add, sub, div and mul support 3
602 ;; fp register operands. The following attributes allow to merge the bfp and
603 ;; dfp variants in a single insn definition.
604
605 ;; This attribute is used to set op_type accordingly.
606 (define_mode_attr RRer [(TF "RRE") (DF "RRE") (SF "RRE") (TD "RRR")
607 (DD "RRR") (SD "RRR")])
608
609 ;; This attribute is used in the operand constraint list in order to have the
610 ;; first and the second operand match for bfp modes.
611 (define_mode_attr f0 [(TF "0") (DF "0") (SF "0") (TD "f") (DD "f") (DD "f")])
612
613 ;; This attribute is used to merge the scalar vector instructions into
614 ;; the FP patterns. For non-supported modes (all but DF) it expands
615 ;; to constraints which are supposed to be matched by an earlier
616 ;; variant.
617 (define_mode_attr v0 [(TF "0") (DF "v") (SF "0") (TD "0") (DD "0") (DD "0") (TI "0") (DI "v") (SI "0")])
618 (define_mode_attr vf [(TF "f") (DF "v") (SF "f") (TD "f") (DD "f") (DD "f") (TI "f") (DI "v") (SI "f")])
619 (define_mode_attr vd [(TF "d") (DF "v") (SF "d") (TD "d") (DD "d") (DD "d") (TI "d") (DI "v") (SI "d")])
620
621 ;; This attribute is used in the operand list of the instruction to have an
622 ;; additional operand for the dfp instructions.
623 (define_mode_attr op1 [(TF "") (DF "") (SF "")
624 (TD "%1,") (DD "%1,") (SD "%1,")])
625
626
627 ;; This attribute is used in the operand constraint list
628 ;; for instructions dealing with the sign bit of 32 or 64bit fp values.
629 ;; TFmode values are represented by a fp register pair. Since the
630 ;; sign bit instructions only handle single source and target fp registers
631 ;; these instructions can only be used for TFmode values if the source and
632 ;; target operand uses the same fp register.
633 (define_mode_attr fT0 [(TF "0") (DF "f") (SF "f")])
634
635 ;; In FP templates, "<Rf>" will expand to "f" in TFmode and "R" otherwise.
636 ;; This is used to disable the memory alternative in TFmode patterns.
637 (define_mode_attr Rf [(TF "f") (DF "R") (SF "R") (TD "f") (DD "f") (SD "f")])
638
639 ;; This attribute adds b for bfp instructions and t for dfp instructions and is used
640 ;; within instruction mnemonics.
641 (define_mode_attr bt [(TF "b") (DF "b") (SF "b") (TD "t") (DD "t") (SD "t")])
642
643 ;; This attribute is used within instruction mnemonics. It evaluates to d for dfp
644 ;; modes and to an empty string for bfp modes.
645 (define_mode_attr _d [(TF "") (DF "") (SF "") (TD "d") (DD "d") (SD "d")])
646
647 ;; In GPR and P templates, a constraint like "<d0>" will expand to "d" in DImode
648 ;; and "0" in SImode. This allows to combine instructions of which the 31bit
649 ;; version only operates on one register.
650 (define_mode_attr d0 [(DI "d") (SI "0")])
651
652 ;; In combination with d0 this allows to combine instructions of which the 31bit
653 ;; version only operates on one register. The DImode version needs an additional
654 ;; register for the assembler output.
655 (define_mode_attr 1 [(DI "%1,") (SI "")])
656
657 ;; In SHIFT templates, a string like "s<lr>dl" will expand to "sldl" in
658 ;; 'ashift' and "srdl" in 'lshiftrt'.
659 (define_code_attr lr [(ashift "l") (lshiftrt "r")])
660
661 ;; In SHIFT templates, this attribute holds the correct standard name for the
662 ;; pattern itself and the corresponding function calls.
663 (define_code_attr shift [(ashift "ashl") (lshiftrt "lshr")])
664
665 ;; This attribute handles differences in the instruction 'type' and will result
666 ;; in "RRE" for DImode and "RR" for SImode.
667 (define_mode_attr E [(DI "E") (SI "")])
668
669 ;; This attribute handles differences in the instruction 'type' and makes RX<Y>
670 ;; to result in "RXY" for DImode and "RX" for SImode.
671 (define_mode_attr Y [(DI "Y") (SI "")])
672
673 ;; This attribute handles differences in the instruction 'type' and will result
674 ;; in "RSE" for TImode and "RS" for DImode.
675 (define_mode_attr TE [(TI "E") (DI "")])
676
677 ;; In GPR templates, a string like "lc<g>r" will expand to "lcgr" in DImode
678 ;; and "lcr" in SImode.
679 (define_mode_attr g [(DI "g") (SI "")])
680
681 ;; In GPR templates, a string like "sl<y>" will expand to "slg" in DImode
682 ;; and "sly" in SImode. This is useful because on 64bit the ..g instructions
683 ;; were enhanced with long displacements whereas 31bit instructions got a ..y
684 ;; variant for long displacements.
685 (define_mode_attr y [(DI "g") (SI "y")])
686
687 ;; In DW templates, a string like "cds<g>" will expand to "cdsg" in TImode
688 ;; and "cds" in DImode.
689 (define_mode_attr tg [(TI "g") (DI "")])
690
691 ;; In TDI templates, a string like "c<d>sg".
692 (define_mode_attr td [(TI "d") (DI "")])
693
694 ;; In GPR templates, a string like "c<gf>dbr" will expand to "cgdbr" in DImode
695 ;; and "cfdbr" in SImode.
696 (define_mode_attr gf [(DI "g") (SI "f")])
697
698 ;; In GPR templates, a string like sll<gk> will expand to sllg for DI
699 ;; and sllk for SI. This way it is possible to merge the new z196 SI
700 ;; 3 operands shift instructions into the existing patterns.
701 (define_mode_attr gk [(DI "g") (SI "k")])
702
703 ;; ICM mask required to load MODE value into the lowest subreg
704 ;; of a SImode register.
705 (define_mode_attr icm_lo [(HI "3") (QI "1")])
706
707 ;; In HQI templates, a string like "llg<hc>" will expand to "llgh" in
708 ;; HImode and "llgc" in QImode.
709 (define_mode_attr hc [(HI "h") (QI "c")])
710
711 ;; In P templates, the mode <DBL> will expand to "TI" in DImode and "DI"
712 ;; in SImode.
713 (define_mode_attr DBL [(DI "TI") (SI "DI")])
714
715 ;; This attribute expands to DF for TFmode and to DD for TDmode . It is
716 ;; used for Txmode splitters splitting a Txmode copy into 2 Dxmode copies.
717 (define_mode_attr HALF_TMODE [(TF "DF") (TD "DD")])
718
719 ;; Maximum unsigned integer that fits in MODE.
720 (define_mode_attr max_uint [(HI "65535") (QI "255")])
721
722 ;; Start and end field computations for RISBG et al.
723 (define_mode_attr bfstart [(DI "s") (SI "t")])
724 (define_mode_attr bfend [(DI "e") (SI "f")])
725
726 ;; In place of GET_MODE_BITSIZE (<MODE>mode)
727 (define_mode_attr bitsize [(DI "64") (SI "32") (HI "16") (QI "8")])
728
729 ;; Allow return and simple_return to be defined from a single template.
730 (define_code_iterator ANY_RETURN [return simple_return])
731
732
733
734 ; Condition code modes generated by vector fp comparisons. These will
735 ; be used also in single element mode.
736 (define_mode_iterator VFCMP [CCVEQ CCVFH CCVFHE])
737 ; Used with VFCMP to expand part of the mnemonic
738 ; For fp we have a mismatch: eq in the insn name - e in asm
739 (define_mode_attr asm_fcmp [(CCVEQ "e") (CCVFH "h") (CCVFHE "he")])
740 (define_mode_attr insn_cmp [(CCVEQ "eq") (CCVH "h") (CCVHU "hl") (CCVFH "h") (CCVFHE "he")])
741
742
743 (include "vector.md")
744
745 ;;
746 ;;- Compare instructions.
747 ;;
748
749 ; Test-under-Mask instructions
750
751 (define_insn "*tmqi_mem"
752 [(set (reg CC_REGNUM)
753 (compare (and:QI (match_operand:QI 0 "memory_operand" "Q,S")
754 (match_operand:QI 1 "immediate_operand" "n,n"))
755 (match_operand:QI 2 "immediate_operand" "n,n")))]
756 "s390_match_ccmode (insn, s390_tm_ccmode (operands[1], operands[2], false))"
757 "@
758 tm\t%S0,%b1
759 tmy\t%S0,%b1"
760 [(set_attr "op_type" "SI,SIY")
761 (set_attr "z10prop" "z10_super,z10_super")])
762
763 (define_insn "*tmdi_reg"
764 [(set (reg CC_REGNUM)
765 (compare (and:DI (match_operand:DI 0 "nonimmediate_operand" "d,d,d,d")
766 (match_operand:DI 1 "immediate_operand"
767 "N0HD0,N1HD0,N2HD0,N3HD0"))
768 (match_operand:DI 2 "immediate_operand" "n,n,n,n")))]
769 "TARGET_ZARCH
770 && s390_match_ccmode (insn, s390_tm_ccmode (operands[1], operands[2], true))
771 && s390_single_part (operands[1], DImode, HImode, 0) >= 0"
772 "@
773 tmhh\t%0,%i1
774 tmhl\t%0,%i1
775 tmlh\t%0,%i1
776 tmll\t%0,%i1"
777 [(set_attr "op_type" "RI")
778 (set_attr "z10prop" "z10_super,z10_super,z10_super,z10_super")])
779
780 (define_insn "*tmsi_reg"
781 [(set (reg CC_REGNUM)
782 (compare (and:SI (match_operand:SI 0 "nonimmediate_operand" "d,d")
783 (match_operand:SI 1 "immediate_operand" "N0HS0,N1HS0"))
784 (match_operand:SI 2 "immediate_operand" "n,n")))]
785 "s390_match_ccmode (insn, s390_tm_ccmode (operands[1], operands[2], true))
786 && s390_single_part (operands[1], SImode, HImode, 0) >= 0"
787 "@
788 tmh\t%0,%i1
789 tml\t%0,%i1"
790 [(set_attr "op_type" "RI")
791 (set_attr "z10prop" "z10_super,z10_super")])
792
793 (define_insn "*tm<mode>_full"
794 [(set (reg CC_REGNUM)
795 (compare (match_operand:HQI 0 "register_operand" "d")
796 (match_operand:HQI 1 "immediate_operand" "n")))]
797 "s390_match_ccmode (insn, s390_tm_ccmode (constm1_rtx, operands[1], true))"
798 "tml\t%0,<max_uint>"
799 [(set_attr "op_type" "RI")
800 (set_attr "z10prop" "z10_super")])
801
802
803 ;
804 ; Load-and-Test instructions
805 ;
806
807 ; tst(di|si) instruction pattern(s).
808
809 (define_insn "*tstdi_sign"
810 [(set (reg CC_REGNUM)
811 (compare
812 (ashiftrt:DI
813 (ashift:DI
814 (subreg:DI (match_operand:SI 0 "nonimmediate_operand" "d,RT") 0)
815 (const_int 32)) (const_int 32))
816 (match_operand:DI 1 "const0_operand" "")))
817 (set (match_operand:DI 2 "register_operand" "=d,d")
818 (sign_extend:DI (match_dup 0)))]
819 "s390_match_ccmode(insn, CCSmode) && TARGET_ZARCH"
820 "ltgfr\t%2,%0
821 ltgf\t%2,%0"
822 [(set_attr "op_type" "RRE,RXY")
823 (set_attr "cpu_facility" "*,z10")
824 (set_attr "z10prop" "z10_super_E1,z10_super_E1") ])
825
826 ; ltr, lt, ltgr, ltg
827 (define_insn "*tst<mode>_extimm"
828 [(set (reg CC_REGNUM)
829 (compare (match_operand:GPR 0 "nonimmediate_operand" "d,RT")
830 (match_operand:GPR 1 "const0_operand" "")))
831 (set (match_operand:GPR 2 "register_operand" "=d,d")
832 (match_dup 0))]
833 "s390_match_ccmode(insn, CCSmode) && TARGET_EXTIMM"
834 "@
835 lt<g>r\t%2,%0
836 lt<g>\t%2,%0"
837 [(set_attr "op_type" "RR<E>,RXY")
838 (set_attr "z10prop" "z10_fr_E1,z10_fwd_A3") ])
839
840 ; ltr, lt, ltgr, ltg
841 (define_insn "*tst<mode>_cconly_extimm"
842 [(set (reg CC_REGNUM)
843 (compare (match_operand:GPR 0 "nonimmediate_operand" "d,RT")
844 (match_operand:GPR 1 "const0_operand" "")))
845 (clobber (match_scratch:GPR 2 "=X,d"))]
846 "s390_match_ccmode(insn, CCSmode) && TARGET_EXTIMM"
847 "@
848 lt<g>r\t%0,%0
849 lt<g>\t%2,%0"
850 [(set_attr "op_type" "RR<E>,RXY")
851 (set_attr "z10prop" "z10_fr_E1,z10_fwd_A3")])
852
853 (define_insn "*tstdi"
854 [(set (reg CC_REGNUM)
855 (compare (match_operand:DI 0 "register_operand" "d")
856 (match_operand:DI 1 "const0_operand" "")))
857 (set (match_operand:DI 2 "register_operand" "=d")
858 (match_dup 0))]
859 "s390_match_ccmode(insn, CCSmode) && TARGET_ZARCH && !TARGET_EXTIMM"
860 "ltgr\t%2,%0"
861 [(set_attr "op_type" "RRE")
862 (set_attr "z10prop" "z10_fr_E1")])
863
864 (define_insn "*tstsi"
865 [(set (reg CC_REGNUM)
866 (compare (match_operand:SI 0 "nonimmediate_operand" "d,Q,S")
867 (match_operand:SI 1 "const0_operand" "")))
868 (set (match_operand:SI 2 "register_operand" "=d,d,d")
869 (match_dup 0))]
870 "s390_match_ccmode(insn, CCSmode) && !TARGET_EXTIMM"
871 "@
872 ltr\t%2,%0
873 icm\t%2,15,%S0
874 icmy\t%2,15,%S0"
875 [(set_attr "op_type" "RR,RS,RSY")
876 (set_attr "z10prop" "z10_fr_E1,z10_super_E1,z10_super_E1")])
877
878 (define_insn "*tstsi_cconly"
879 [(set (reg CC_REGNUM)
880 (compare (match_operand:SI 0 "nonimmediate_operand" "d,Q,S")
881 (match_operand:SI 1 "const0_operand" "")))
882 (clobber (match_scratch:SI 2 "=X,d,d"))]
883 "s390_match_ccmode(insn, CCSmode)"
884 "@
885 ltr\t%0,%0
886 icm\t%2,15,%S0
887 icmy\t%2,15,%S0"
888 [(set_attr "op_type" "RR,RS,RSY")
889 (set_attr "z10prop" "z10_fr_E1,z10_super_E1,z10_super_E1")])
890
891 (define_insn "*tstdi_cconly_31"
892 [(set (reg CC_REGNUM)
893 (compare (match_operand:DI 0 "register_operand" "d")
894 (match_operand:DI 1 "const0_operand" "")))]
895 "s390_match_ccmode(insn, CCSmode) && !TARGET_ZARCH"
896 "srda\t%0,0"
897 [(set_attr "op_type" "RS")
898 (set_attr "atype" "reg")])
899
900 ; ltr, ltgr
901 (define_insn "*tst<mode>_cconly2"
902 [(set (reg CC_REGNUM)
903 (compare (match_operand:GPR 0 "register_operand" "d")
904 (match_operand:GPR 1 "const0_operand" "")))]
905 "s390_match_ccmode(insn, CCSmode)"
906 "lt<g>r\t%0,%0"
907 [(set_attr "op_type" "RR<E>")
908 (set_attr "z10prop" "z10_fr_E1")])
909
910 ; tst(hi|qi) instruction pattern(s).
911
912 (define_insn "*tst<mode>CCT"
913 [(set (reg CC_REGNUM)
914 (compare (match_operand:HQI 0 "nonimmediate_operand" "?Q,?S,d")
915 (match_operand:HQI 1 "const0_operand" "")))
916 (set (match_operand:HQI 2 "register_operand" "=d,d,0")
917 (match_dup 0))]
918 "s390_match_ccmode(insn, CCTmode)"
919 "@
920 icm\t%2,<icm_lo>,%S0
921 icmy\t%2,<icm_lo>,%S0
922 tml\t%0,<max_uint>"
923 [(set_attr "op_type" "RS,RSY,RI")
924 (set_attr "z10prop" "z10_super_E1,z10_super_E1,z10_super")])
925
926 (define_insn "*tsthiCCT_cconly"
927 [(set (reg CC_REGNUM)
928 (compare (match_operand:HI 0 "nonimmediate_operand" "Q,S,d")
929 (match_operand:HI 1 "const0_operand" "")))
930 (clobber (match_scratch:HI 2 "=d,d,X"))]
931 "s390_match_ccmode(insn, CCTmode)"
932 "@
933 icm\t%2,3,%S0
934 icmy\t%2,3,%S0
935 tml\t%0,65535"
936 [(set_attr "op_type" "RS,RSY,RI")
937 (set_attr "z10prop" "z10_super_E1,z10_super_E1,z10_super")])
938
939 (define_insn "*tstqiCCT_cconly"
940 [(set (reg CC_REGNUM)
941 (compare (match_operand:QI 0 "nonimmediate_operand" "?Q,?S,d")
942 (match_operand:QI 1 "const0_operand" "")))]
943 "s390_match_ccmode(insn, CCTmode)"
944 "@
945 cli\t%S0,0
946 cliy\t%S0,0
947 tml\t%0,255"
948 [(set_attr "op_type" "SI,SIY,RI")
949 (set_attr "z10prop" "z10_super,z10_super,z10_super")])
950
951 (define_insn "*tst<mode>"
952 [(set (reg CC_REGNUM)
953 (compare (match_operand:HQI 0 "s_operand" "Q,S")
954 (match_operand:HQI 1 "const0_operand" "")))
955 (set (match_operand:HQI 2 "register_operand" "=d,d")
956 (match_dup 0))]
957 "s390_match_ccmode(insn, CCSmode)"
958 "@
959 icm\t%2,<icm_lo>,%S0
960 icmy\t%2,<icm_lo>,%S0"
961 [(set_attr "op_type" "RS,RSY")
962 (set_attr "z10prop" "z10_super_E1,z10_super_E1")])
963
964 (define_insn "*tst<mode>_cconly"
965 [(set (reg CC_REGNUM)
966 (compare (match_operand:HQI 0 "s_operand" "Q,S")
967 (match_operand:HQI 1 "const0_operand" "")))
968 (clobber (match_scratch:HQI 2 "=d,d"))]
969 "s390_match_ccmode(insn, CCSmode)"
970 "@
971 icm\t%2,<icm_lo>,%S0
972 icmy\t%2,<icm_lo>,%S0"
973 [(set_attr "op_type" "RS,RSY")
974 (set_attr "z10prop" "z10_super_E1,z10_super_E1")])
975
976
977 ; Compare (equality) instructions
978
979 (define_insn "*cmpdi_cct"
980 [(set (reg CC_REGNUM)
981 (compare (match_operand:DI 0 "nonimmediate_operand" "%d,d,d,d,Q")
982 (match_operand:DI 1 "general_operand" "d,K,Os,RT,BQ")))]
983 "s390_match_ccmode (insn, CCTmode) && TARGET_ZARCH"
984 "@
985 cgr\t%0,%1
986 cghi\t%0,%h1
987 cgfi\t%0,%1
988 cg\t%0,%1
989 #"
990 [(set_attr "op_type" "RRE,RI,RIL,RXY,SS")
991 (set_attr "z10prop" "z10_super_c,z10_super,z10_super,z10_super,*")])
992
993 (define_insn "*cmpsi_cct"
994 [(set (reg CC_REGNUM)
995 (compare (match_operand:SI 0 "nonimmediate_operand" "%d,d,d,d,d,Q")
996 (match_operand:SI 1 "general_operand" "d,K,Os,R,T,BQ")))]
997 "s390_match_ccmode (insn, CCTmode)"
998 "@
999 cr\t%0,%1
1000 chi\t%0,%h1
1001 cfi\t%0,%1
1002 c\t%0,%1
1003 cy\t%0,%1
1004 #"
1005 [(set_attr "op_type" "RR,RI,RIL,RX,RXY,SS")
1006 (set_attr "z10prop" "z10_super_c,z10_super,z10_super,z10_super,z10_super,*")])
1007
1008 ; Compare (signed) instructions
1009
1010 (define_insn "*cmpdi_ccs_sign"
1011 [(set (reg CC_REGNUM)
1012 (compare (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand"
1013 "d,RT,b"))
1014 (match_operand:DI 0 "register_operand" "d, d,d")))]
1015 "s390_match_ccmode(insn, CCSRmode) && TARGET_ZARCH"
1016 "@
1017 cgfr\t%0,%1
1018 cgf\t%0,%1
1019 cgfrl\t%0,%1"
1020 [(set_attr "op_type" "RRE,RXY,RIL")
1021 (set_attr "z10prop" "z10_c,*,*")
1022 (set_attr "type" "*,*,larl")])
1023
1024
1025
1026 (define_insn "*cmpsi_ccs_sign"
1027 [(set (reg CC_REGNUM)
1028 (compare (sign_extend:SI (match_operand:HI 1 "memory_operand" "R,T,b"))
1029 (match_operand:SI 0 "register_operand" "d,d,d")))]
1030 "s390_match_ccmode(insn, CCSRmode)"
1031 "@
1032 ch\t%0,%1
1033 chy\t%0,%1
1034 chrl\t%0,%1"
1035 [(set_attr "op_type" "RX,RXY,RIL")
1036 (set_attr "cpu_facility" "*,*,z10")
1037 (set_attr "type" "*,*,larl")
1038 (set_attr "z196prop" "z196_cracked,z196_cracked,z196_cracked")])
1039
1040 (define_insn "*cmphi_ccs_z10"
1041 [(set (reg CC_REGNUM)
1042 (compare (match_operand:HI 0 "s_operand" "Q")
1043 (match_operand:HI 1 "immediate_operand" "K")))]
1044 "s390_match_ccmode(insn, CCSmode) && TARGET_Z10"
1045 "chhsi\t%0,%1"
1046 [(set_attr "op_type" "SIL")
1047 (set_attr "z196prop" "z196_cracked")])
1048
1049 (define_insn "*cmpdi_ccs_signhi_rl"
1050 [(set (reg CC_REGNUM)
1051 (compare (sign_extend:DI (match_operand:HI 1 "memory_operand" "RT,b"))
1052 (match_operand:GPR 0 "register_operand" "d,d")))]
1053 "s390_match_ccmode(insn, CCSRmode) && TARGET_Z10"
1054 "@
1055 cgh\t%0,%1
1056 cghrl\t%0,%1"
1057 [(set_attr "op_type" "RXY,RIL")
1058 (set_attr "type" "*,larl")])
1059
1060 ; cr, chi, cfi, c, cy, cgr, cghi, cgfi, cg, chsi, cghsi, crl, cgrl
1061 (define_insn "*cmp<mode>_ccs"
1062 [(set (reg CC_REGNUM)
1063 (compare (match_operand:GPR 0 "nonimmediate_operand"
1064 "d,d,Q, d,d,d,d")
1065 (match_operand:GPR 1 "general_operand"
1066 "d,K,K,Os,R,T,b")))]
1067 "s390_match_ccmode(insn, CCSmode)"
1068 "@
1069 c<g>r\t%0,%1
1070 c<g>hi\t%0,%h1
1071 c<g>hsi\t%0,%h1
1072 c<g>fi\t%0,%1
1073 c<g>\t%0,%1
1074 c<y>\t%0,%1
1075 c<g>rl\t%0,%1"
1076 [(set_attr "op_type" "RR<E>,RI,SIL,RIL,RX<Y>,RXY,RIL")
1077 (set_attr "cpu_facility" "*,*,z10,extimm,*,*,z10")
1078 (set_attr "type" "*,*,*,*,*,*,larl")
1079 (set_attr "z10prop" "z10_super_c,z10_super,z10_super,z10_super,z10_super,z10_super,z10_super")])
1080
1081
1082 ; Compare (unsigned) instructions
1083
1084 (define_insn "*cmpsi_ccu_zerohi_rlsi"
1085 [(set (reg CC_REGNUM)
1086 (compare (zero_extend:SI (mem:HI (match_operand:SI 1
1087 "larl_operand" "X")))
1088 (match_operand:SI 0 "register_operand" "d")))]
1089 "s390_match_ccmode(insn, CCURmode) && TARGET_Z10"
1090 "clhrl\t%0,%1"
1091 [(set_attr "op_type" "RIL")
1092 (set_attr "type" "larl")
1093 (set_attr "z10prop" "z10_super")])
1094
1095 ; clhrl, clghrl
1096 (define_insn "*cmp<GPR:mode>_ccu_zerohi_rldi"
1097 [(set (reg CC_REGNUM)
1098 (compare (zero_extend:GPR (mem:HI (match_operand:DI 1
1099 "larl_operand" "X")))
1100 (match_operand:GPR 0 "register_operand" "d")))]
1101 "s390_match_ccmode(insn, CCURmode) && TARGET_Z10"
1102 "cl<g>hrl\t%0,%1"
1103 [(set_attr "op_type" "RIL")
1104 (set_attr "type" "larl")
1105 (set_attr "z10prop" "z10_super")])
1106
1107 (define_insn "*cmpdi_ccu_zero"
1108 [(set (reg CC_REGNUM)
1109 (compare (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand"
1110 "d,RT,b"))
1111 (match_operand:DI 0 "register_operand" "d, d,d")))]
1112 "s390_match_ccmode (insn, CCURmode) && TARGET_ZARCH"
1113 "@
1114 clgfr\t%0,%1
1115 clgf\t%0,%1
1116 clgfrl\t%0,%1"
1117 [(set_attr "op_type" "RRE,RXY,RIL")
1118 (set_attr "cpu_facility" "*,*,z10")
1119 (set_attr "type" "*,*,larl")
1120 (set_attr "z10prop" "z10_super_c,z10_super_E1,z10_super")])
1121
1122 (define_insn "*cmpdi_ccu"
1123 [(set (reg CC_REGNUM)
1124 (compare (match_operand:DI 0 "nonimmediate_operand"
1125 "d, d,d,Q, d, Q,BQ")
1126 (match_operand:DI 1 "general_operand"
1127 "d,Op,b,D,RT,BQ,Q")))]
1128 "s390_match_ccmode (insn, CCUmode) && TARGET_ZARCH"
1129 "@
1130 clgr\t%0,%1
1131 clgfi\t%0,%1
1132 clgrl\t%0,%1
1133 clghsi\t%0,%x1
1134 clg\t%0,%1
1135 #
1136 #"
1137 [(set_attr "op_type" "RRE,RIL,RIL,SIL,RXY,SS,SS")
1138 (set_attr "cpu_facility" "*,extimm,z10,z10,*,*,*")
1139 (set_attr "type" "*,*,larl,*,*,*,*")
1140 (set_attr "z10prop" "z10_super_c,z10_super,z10_super,z10_super,z10_super,*,*")])
1141
1142 (define_insn "*cmpsi_ccu"
1143 [(set (reg CC_REGNUM)
1144 (compare (match_operand:SI 0 "nonimmediate_operand" "d, d,d,Q,d,d, Q,BQ")
1145 (match_operand:SI 1 "general_operand" "d,Os,b,D,R,T,BQ, Q")))]
1146 "s390_match_ccmode (insn, CCUmode)"
1147 "@
1148 clr\t%0,%1
1149 clfi\t%0,%o1
1150 clrl\t%0,%1
1151 clfhsi\t%0,%x1
1152 cl\t%0,%1
1153 cly\t%0,%1
1154 #
1155 #"
1156 [(set_attr "op_type" "RR,RIL,RIL,SIL,RX,RXY,SS,SS")
1157 (set_attr "cpu_facility" "*,extimm,z10,z10,*,*,*,*")
1158 (set_attr "type" "*,*,larl,*,*,*,*,*")
1159 (set_attr "z10prop" "z10_super_c,z10_super,z10_super,z10_super,z10_super,z10_super,*,*")])
1160
1161 (define_insn "*cmphi_ccu"
1162 [(set (reg CC_REGNUM)
1163 (compare (match_operand:HI 0 "nonimmediate_operand" "d,d,Q,Q,BQ")
1164 (match_operand:HI 1 "general_operand" "Q,S,D,BQ,Q")))]
1165 "s390_match_ccmode (insn, CCUmode)
1166 && !register_operand (operands[1], HImode)"
1167 "@
1168 clm\t%0,3,%S1
1169 clmy\t%0,3,%S1
1170 clhhsi\t%0,%1
1171 #
1172 #"
1173 [(set_attr "op_type" "RS,RSY,SIL,SS,SS")
1174 (set_attr "cpu_facility" "*,*,z10,*,*")
1175 (set_attr "z10prop" "*,*,z10_super,*,*")])
1176
1177 (define_insn "*cmpqi_ccu"
1178 [(set (reg CC_REGNUM)
1179 (compare (match_operand:QI 0 "nonimmediate_operand" "d,d,Q,S,Q,BQ")
1180 (match_operand:QI 1 "general_operand" "Q,S,n,n,BQ,Q")))]
1181 "s390_match_ccmode (insn, CCUmode)
1182 && !register_operand (operands[1], QImode)"
1183 "@
1184 clm\t%0,1,%S1
1185 clmy\t%0,1,%S1
1186 cli\t%S0,%b1
1187 cliy\t%S0,%b1
1188 #
1189 #"
1190 [(set_attr "op_type" "RS,RSY,SI,SIY,SS,SS")
1191 (set_attr "z10prop" "*,*,z10_super,z10_super,*,*")])
1192
1193
1194 ; Block compare (CLC) instruction patterns.
1195
1196 (define_insn "*clc"
1197 [(set (reg CC_REGNUM)
1198 (compare (match_operand:BLK 0 "memory_operand" "Q")
1199 (match_operand:BLK 1 "memory_operand" "Q")))
1200 (use (match_operand 2 "const_int_operand" "n"))]
1201 "s390_match_ccmode (insn, CCUmode)
1202 && INTVAL (operands[2]) >= 1 && INTVAL (operands[2]) <= 256"
1203 "clc\t%O0(%2,%R0),%S1"
1204 [(set_attr "op_type" "SS")])
1205
1206 (define_split
1207 [(set (reg CC_REGNUM)
1208 (compare (match_operand 0 "memory_operand" "")
1209 (match_operand 1 "memory_operand" "")))]
1210 "reload_completed
1211 && s390_match_ccmode (insn, CCUmode)
1212 && GET_MODE (operands[0]) == GET_MODE (operands[1])
1213 && GET_MODE_SIZE (GET_MODE (operands[0])) > 0"
1214 [(parallel
1215 [(set (match_dup 0) (match_dup 1))
1216 (use (match_dup 2))])]
1217 {
1218 operands[2] = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[0])));
1219 operands[0] = adjust_address (operands[0], BLKmode, 0);
1220 operands[1] = adjust_address (operands[1], BLKmode, 0);
1221
1222 operands[1] = gen_rtx_COMPARE (GET_MODE (SET_DEST (PATTERN (curr_insn))),
1223 operands[0], operands[1]);
1224 operands[0] = SET_DEST (PATTERN (curr_insn));
1225 })
1226
1227
1228 ; (TF|DF|SF|TD|DD|SD) instructions
1229
1230 ; ltxbr, ltdbr, ltebr, ltxtr, ltdtr
1231 (define_insn "*cmp<mode>_ccs_0"
1232 [(set (reg CC_REGNUM)
1233 (compare (match_operand:FP 0 "register_operand" "f")
1234 (match_operand:FP 1 "const0_operand" "")))]
1235 "s390_match_ccmode(insn, CCSmode) && TARGET_HARD_FLOAT"
1236 "lt<xde><bt>r\t%0,%0"
1237 [(set_attr "op_type" "RRE")
1238 (set_attr "type" "fsimp<mode>")])
1239
1240 ; cxtr, cxbr, cdtr, cdbr, cebr, cdb, ceb
1241 (define_insn "*cmp<mode>_ccs"
1242 [(set (reg CC_REGNUM)
1243 (compare (match_operand:FP 0 "register_operand" "f,f")
1244 (match_operand:FP 1 "general_operand" "f,<Rf>")))]
1245 "s390_match_ccmode(insn, CCSmode) && TARGET_HARD_FLOAT"
1246 "@
1247 c<xde><bt>r\t%0,%1
1248 c<xde>b\t%0,%1"
1249 [(set_attr "op_type" "RRE,RXE")
1250 (set_attr "type" "fsimp<mode>")])
1251
1252 ; wfcedbs, wfchdbs, wfchedbs
1253 (define_insn "*vec_cmp<insn_cmp>df_cconly"
1254 [(set (reg:VFCMP CC_REGNUM)
1255 (compare:VFCMP (match_operand:DF 0 "register_operand" "v")
1256 (match_operand:DF 1 "register_operand" "v")))
1257 (clobber (match_scratch:V2DI 2 "=v"))]
1258 "TARGET_Z13 && TARGET_HARD_FLOAT"
1259 "wfc<asm_fcmp>dbs\t%v2,%v0,%v1"
1260 [(set_attr "op_type" "VRR")])
1261
1262 ; Compare and Branch instructions
1263
1264 ; cij, cgij, crj, cgrj, cfi, cgfi, cr, cgr
1265 ; The following instructions do a complementary access of their second
1266 ; operand (z01 only): crj_c, cgrjc, cr, cgr
1267 (define_insn "*cmp_and_br_signed_<mode>"
1268 [(set (pc)
1269 (if_then_else (match_operator 0 "s390_signed_integer_comparison"
1270 [(match_operand:GPR 1 "register_operand" "d,d")
1271 (match_operand:GPR 2 "nonmemory_operand" "d,C")])
1272 (label_ref (match_operand 3 "" ""))
1273 (pc)))
1274 (clobber (reg:CC CC_REGNUM))]
1275 "TARGET_Z10 && !TARGET_AVOID_CMP_AND_BRANCH"
1276 {
1277 if (get_attr_length (insn) == 6)
1278 return which_alternative ?
1279 "c<g>ij%C0\t%1,%c2,%l3" : "c<g>rj%C0\t%1,%2,%l3";
1280 else
1281 return which_alternative ?
1282 "c<g>fi\t%1,%c2\;jg%C0\t%l3" : "c<g>r\t%1,%2\;jg%C0\t%l3";
1283 }
1284 [(set_attr "op_type" "RIE")
1285 (set_attr "type" "branch")
1286 (set_attr "z10prop" "z10_super_c,z10_super")
1287 (set (attr "length")
1288 (if_then_else (lt (abs (minus (pc) (match_dup 3))) (const_int 60000))
1289 (const_int 6) (const_int 12)))]) ; 8 byte for cr/jg
1290 ; 10 byte for cgr/jg
1291
1292 ; clij, clgij, clrj, clgrj, clfi, clgfi, clr, clgr
1293 ; The following instructions do a complementary access of their second
1294 ; operand (z10 only): clrj, clgrj, clr, clgr
1295 (define_insn "*cmp_and_br_unsigned_<mode>"
1296 [(set (pc)
1297 (if_then_else (match_operator 0 "s390_unsigned_integer_comparison"
1298 [(match_operand:GPR 1 "register_operand" "d,d")
1299 (match_operand:GPR 2 "nonmemory_operand" "d,I")])
1300 (label_ref (match_operand 3 "" ""))
1301 (pc)))
1302 (clobber (reg:CC CC_REGNUM))]
1303 "TARGET_Z10 && !TARGET_AVOID_CMP_AND_BRANCH"
1304 {
1305 if (get_attr_length (insn) == 6)
1306 return which_alternative ?
1307 "cl<g>ij%C0\t%1,%b2,%l3" : "cl<g>rj%C0\t%1,%2,%l3";
1308 else
1309 return which_alternative ?
1310 "cl<g>fi\t%1,%b2\;jg%C0\t%l3" : "cl<g>r\t%1,%2\;jg%C0\t%l3";
1311 }
1312 [(set_attr "op_type" "RIE")
1313 (set_attr "type" "branch")
1314 (set_attr "z10prop" "z10_super_c,z10_super")
1315 (set (attr "length")
1316 (if_then_else (lt (abs (minus (pc) (match_dup 3))) (const_int 60000))
1317 (const_int 6) (const_int 12)))]) ; 8 byte for clr/jg
1318 ; 10 byte for clgr/jg
1319
1320 ; And now the same two patterns as above but with a negated CC mask.
1321
1322 ; cij, cgij, crj, cgrj, cfi, cgfi, cr, cgr
1323 ; The following instructions do a complementary access of their second
1324 ; operand (z01 only): crj_c, cgrjc, cr, cgr
1325 (define_insn "*icmp_and_br_signed_<mode>"
1326 [(set (pc)
1327 (if_then_else (match_operator 0 "s390_signed_integer_comparison"
1328 [(match_operand:GPR 1 "register_operand" "d,d")
1329 (match_operand:GPR 2 "nonmemory_operand" "d,C")])
1330 (pc)
1331 (label_ref (match_operand 3 "" ""))))
1332 (clobber (reg:CC CC_REGNUM))]
1333 "TARGET_Z10 && !TARGET_AVOID_CMP_AND_BRANCH"
1334 {
1335 if (get_attr_length (insn) == 6)
1336 return which_alternative ?
1337 "c<g>ij%D0\t%1,%c2,%l3" : "c<g>rj%D0\t%1,%2,%l3";
1338 else
1339 return which_alternative ?
1340 "c<g>fi\t%1,%c2\;jg%D0\t%l3" : "c<g>r\t%1,%2\;jg%D0\t%l3";
1341 }
1342 [(set_attr "op_type" "RIE")
1343 (set_attr "type" "branch")
1344 (set_attr "z10prop" "z10_super_c,z10_super")
1345 (set (attr "length")
1346 (if_then_else (lt (abs (minus (pc) (match_dup 3))) (const_int 60000))
1347 (const_int 6) (const_int 12)))]) ; 8 byte for cr/jg
1348 ; 10 byte for cgr/jg
1349
1350 ; clij, clgij, clrj, clgrj, clfi, clgfi, clr, clgr
1351 ; The following instructions do a complementary access of their second
1352 ; operand (z10 only): clrj, clgrj, clr, clgr
1353 (define_insn "*icmp_and_br_unsigned_<mode>"
1354 [(set (pc)
1355 (if_then_else (match_operator 0 "s390_unsigned_integer_comparison"
1356 [(match_operand:GPR 1 "register_operand" "d,d")
1357 (match_operand:GPR 2 "nonmemory_operand" "d,I")])
1358 (pc)
1359 (label_ref (match_operand 3 "" ""))))
1360 (clobber (reg:CC CC_REGNUM))]
1361 "TARGET_Z10 && !TARGET_AVOID_CMP_AND_BRANCH"
1362 {
1363 if (get_attr_length (insn) == 6)
1364 return which_alternative ?
1365 "cl<g>ij%D0\t%1,%b2,%l3" : "cl<g>rj%D0\t%1,%2,%l3";
1366 else
1367 return which_alternative ?
1368 "cl<g>fi\t%1,%b2\;jg%D0\t%l3" : "cl<g>r\t%1,%2\;jg%D0\t%l3";
1369 }
1370 [(set_attr "op_type" "RIE")
1371 (set_attr "type" "branch")
1372 (set_attr "z10prop" "z10_super_c,z10_super")
1373 (set (attr "length")
1374 (if_then_else (lt (abs (minus (pc) (match_dup 3))) (const_int 60000))
1375 (const_int 6) (const_int 12)))]) ; 8 byte for clr/jg
1376 ; 10 byte for clgr/jg
1377
1378 ;;
1379 ;;- Move instructions.
1380 ;;
1381
1382 ;
1383 ; movti instruction pattern(s).
1384 ;
1385
1386 ; FIXME: More constants are possible by enabling jxx, jyy constraints
1387 ; for TImode (use double-int for the calculations)
1388 (define_insn "movti"
1389 [(set (match_operand:TI 0 "nonimmediate_operand" "=d,QS,v, v, v,v,d, v,QR, d,o")
1390 (match_operand:TI 1 "general_operand" "QS, d,v,j00,jm1,d,v,QR, v,dPRT,d"))]
1391 "TARGET_ZARCH"
1392 "@
1393 lmg\t%0,%N0,%S1
1394 stmg\t%1,%N1,%S0
1395 vlr\t%v0,%v1
1396 vzero\t%v0
1397 vone\t%v0
1398 vlvgp\t%v0,%1,%N1
1399 #
1400 vl\t%v0,%1
1401 vst\t%v1,%0
1402 #
1403 #"
1404 [(set_attr "op_type" "RSY,RSY,VRR,VRI,VRI,VRR,*,VRX,VRX,*,*")
1405 (set_attr "type" "lm,stm,*,*,*,*,*,*,*,*,*")
1406 (set_attr "cpu_facility" "*,*,vec,vec,vec,vec,vec,vec,vec,*,*")])
1407
1408 (define_split
1409 [(set (match_operand:TI 0 "nonimmediate_operand" "")
1410 (match_operand:TI 1 "general_operand" ""))]
1411 "TARGET_ZARCH && reload_completed
1412 && s390_split_ok_p (operands[0], operands[1], TImode, 0)"
1413 [(set (match_dup 2) (match_dup 4))
1414 (set (match_dup 3) (match_dup 5))]
1415 {
1416 operands[2] = operand_subword (operands[0], 0, 0, TImode);
1417 operands[3] = operand_subword (operands[0], 1, 0, TImode);
1418 operands[4] = operand_subword (operands[1], 0, 0, TImode);
1419 operands[5] = operand_subword (operands[1], 1, 0, TImode);
1420 })
1421
1422 (define_split
1423 [(set (match_operand:TI 0 "nonimmediate_operand" "")
1424 (match_operand:TI 1 "general_operand" ""))]
1425 "TARGET_ZARCH && reload_completed
1426 && s390_split_ok_p (operands[0], operands[1], TImode, 1)"
1427 [(set (match_dup 2) (match_dup 4))
1428 (set (match_dup 3) (match_dup 5))]
1429 {
1430 operands[2] = operand_subword (operands[0], 1, 0, TImode);
1431 operands[3] = operand_subword (operands[0], 0, 0, TImode);
1432 operands[4] = operand_subword (operands[1], 1, 0, TImode);
1433 operands[5] = operand_subword (operands[1], 0, 0, TImode);
1434 })
1435
1436 ; Use part of the TImode target reg to perform the address
1437 ; calculation. If the TImode value is supposed to be copied into a VR
1438 ; this splitter is not necessary.
1439 (define_split
1440 [(set (match_operand:TI 0 "register_operand" "")
1441 (match_operand:TI 1 "memory_operand" ""))]
1442 "TARGET_ZARCH && reload_completed
1443 && !VECTOR_REG_P (operands[0])
1444 && !s_operand (operands[1], VOIDmode)"
1445 [(set (match_dup 0) (match_dup 1))]
1446 {
1447 rtx addr = operand_subword (operands[0], 1, 0, TImode);
1448 addr = gen_lowpart (Pmode, addr);
1449 s390_load_address (addr, XEXP (operands[1], 0));
1450 operands[1] = replace_equiv_address (operands[1], addr);
1451 })
1452
1453
1454 ; Split a VR -> GPR TImode move into 2 vector load GR from VR element.
1455 ; For the higher order bits we do simply a DImode move while the
1456 ; second part is done via vec extract. Both will end up as vlgvg.
1457 (define_split
1458 [(set (match_operand:TI 0 "register_operand" "")
1459 (match_operand:TI 1 "register_operand" ""))]
1460 "TARGET_VX && reload_completed
1461 && GENERAL_REG_P (operands[0])
1462 && VECTOR_REG_P (operands[1])"
1463 [(set (match_dup 2) (match_dup 4))
1464 (set (match_dup 3) (unspec:DI [(match_dup 5) (const_int 1)]
1465 UNSPEC_VEC_EXTRACT))]
1466 {
1467 operands[2] = operand_subword (operands[0], 0, 0, TImode);
1468 operands[3] = operand_subword (operands[0], 1, 0, TImode);
1469 operands[4] = gen_rtx_REG (DImode, REGNO (operands[1]));
1470 operands[5] = gen_rtx_REG (V2DImode, REGNO (operands[1]));
1471 })
1472
1473 ;
1474 ; Patterns used for secondary reloads
1475 ;
1476
1477 ; z10 provides move instructions accepting larl memory operands.
1478 ; Unfortunately there is no such variant for QI, TI and FP mode moves.
1479 ; These patterns are also used for unaligned SI and DI accesses.
1480
1481 (define_expand "reload<ALL:mode><P:mode>_tomem_z10"
1482 [(parallel [(match_operand:ALL 0 "memory_operand" "")
1483 (match_operand:ALL 1 "register_operand" "=d")
1484 (match_operand:P 2 "register_operand" "=&a")])]
1485 "TARGET_Z10"
1486 {
1487 s390_reload_symref_address (operands[1], operands[0], operands[2], 1);
1488 DONE;
1489 })
1490
1491 (define_expand "reload<ALL:mode><P:mode>_toreg_z10"
1492 [(parallel [(match_operand:ALL 0 "register_operand" "=d")
1493 (match_operand:ALL 1 "memory_operand" "")
1494 (match_operand:P 2 "register_operand" "=a")])]
1495 "TARGET_Z10"
1496 {
1497 s390_reload_symref_address (operands[0], operands[1], operands[2], 0);
1498 DONE;
1499 })
1500
1501 (define_expand "reload<P:mode>_larl_odd_addend_z10"
1502 [(parallel [(match_operand:P 0 "register_operand" "=d")
1503 (match_operand:P 1 "larl_operand" "")
1504 (match_operand:P 2 "register_operand" "=a")])]
1505 "TARGET_Z10"
1506 {
1507 s390_reload_larl_operand (operands[0], operands[1], operands[2]);
1508 DONE;
1509 })
1510
1511 ; Handles loading a PLUS (load address) expression
1512
1513 (define_expand "reload<mode>_plus"
1514 [(parallel [(match_operand:P 0 "register_operand" "=a")
1515 (match_operand:P 1 "s390_plus_operand" "")
1516 (match_operand:P 2 "register_operand" "=&a")])]
1517 ""
1518 {
1519 s390_expand_plus_operand (operands[0], operands[1], operands[2]);
1520 DONE;
1521 })
1522
1523 ; Not all the indirect memory access instructions support the full
1524 ; format (long disp + index + base). So whenever a move from/to such
1525 ; an address is required and the instruction cannot deal with it we do
1526 ; a load address into a scratch register first and use this as the new
1527 ; base register.
1528 ; This in particular is used for:
1529 ; - non-offsetable memory accesses for multiword moves
1530 ; - full vector reg moves with long displacements
1531
1532 (define_expand "reload<mode>_la_in"
1533 [(parallel [(match_operand 0 "register_operand" "")
1534 (match_operand 1 "" "")
1535 (match_operand:P 2 "register_operand" "=&a")])]
1536 ""
1537 {
1538 gcc_assert (MEM_P (operands[1]));
1539 s390_load_address (operands[2], find_replacement (&XEXP (operands[1], 0)));
1540 operands[1] = replace_equiv_address (operands[1], operands[2]);
1541 emit_move_insn (operands[0], operands[1]);
1542 DONE;
1543 })
1544
1545 (define_expand "reload<mode>_la_out"
1546 [(parallel [(match_operand 0 "" "")
1547 (match_operand 1 "register_operand" "")
1548 (match_operand:P 2 "register_operand" "=&a")])]
1549 ""
1550 {
1551 gcc_assert (MEM_P (operands[0]));
1552 s390_load_address (operands[2], find_replacement (&XEXP (operands[0], 0)));
1553 operands[0] = replace_equiv_address (operands[0], operands[2]);
1554 emit_move_insn (operands[0], operands[1]);
1555 DONE;
1556 })
1557
1558 (define_expand "reload<mode>_PIC_addr"
1559 [(parallel [(match_operand 0 "register_operand" "=d")
1560 (match_operand 1 "larl_operand" "")
1561 (match_operand:P 2 "register_operand" "=a")])]
1562 ""
1563 {
1564 rtx new_rtx = legitimize_pic_address (operands[1], operands[2]);
1565 emit_move_insn (operands[0], new_rtx);
1566 })
1567
1568 ;
1569 ; movdi instruction pattern(s).
1570 ;
1571
1572 (define_expand "movdi"
1573 [(set (match_operand:DI 0 "general_operand" "")
1574 (match_operand:DI 1 "general_operand" ""))]
1575 ""
1576 {
1577 /* Handle symbolic constants. */
1578 if (TARGET_64BIT
1579 && (SYMBOLIC_CONST (operands[1])
1580 || (GET_CODE (operands[1]) == PLUS
1581 && XEXP (operands[1], 0) == pic_offset_table_rtx
1582 && SYMBOLIC_CONST (XEXP (operands[1], 1)))))
1583 emit_symbolic_move (operands);
1584 })
1585
1586 (define_insn "*movdi_larl"
1587 [(set (match_operand:DI 0 "register_operand" "=d")
1588 (match_operand:DI 1 "larl_operand" "X"))]
1589 "TARGET_64BIT
1590 && !FP_REG_P (operands[0])"
1591 "larl\t%0,%1"
1592 [(set_attr "op_type" "RIL")
1593 (set_attr "type" "larl")
1594 (set_attr "z10prop" "z10_super_A1")])
1595
1596 (define_insn "*movdi_64"
1597 [(set (match_operand:DI 0 "nonimmediate_operand"
1598 "=d, d, d, d, d, d, d, d,f,d,d,d,d, d,RT,!*f,!*f,!*f,!R,!T,b,Q,d,t,Q,t,v,v,v,d, v,QR")
1599 (match_operand:DI 1 "general_operand"
1600 " K,N0HD0,N1HD0,N2HD0,N3HD0,Os,N0SD0,N1SD0,d,f,L,b,d,RT, d, *f, R, T,*f,*f,d,K,t,d,t,Q,K,v,d,v,QR, v"))]
1601 "TARGET_ZARCH"
1602 "@
1603 lghi\t%0,%h1
1604 llihh\t%0,%i1
1605 llihl\t%0,%i1
1606 llilh\t%0,%i1
1607 llill\t%0,%i1
1608 lgfi\t%0,%1
1609 llihf\t%0,%k1
1610 llilf\t%0,%k1
1611 ldgr\t%0,%1
1612 lgdr\t%0,%1
1613 lay\t%0,%a1
1614 lgrl\t%0,%1
1615 lgr\t%0,%1
1616 lg\t%0,%1
1617 stg\t%1,%0
1618 ldr\t%0,%1
1619 ld\t%0,%1
1620 ldy\t%0,%1
1621 std\t%1,%0
1622 stdy\t%1,%0
1623 stgrl\t%1,%0
1624 mvghi\t%0,%1
1625 #
1626 #
1627 stam\t%1,%N1,%S0
1628 lam\t%0,%N0,%S1
1629 vleig\t%v0,%h1,0
1630 vlr\t%v0,%v1
1631 vlvgg\t%v0,%1,0
1632 vlgvg\t%0,%v1,0
1633 vleg\t%v0,%1,0
1634 vsteg\t%v1,%0,0"
1635 [(set_attr "op_type" "RI,RI,RI,RI,RI,RIL,RIL,RIL,RRE,RRE,RXY,RIL,RRE,RXY,
1636 RXY,RR,RX,RXY,RX,RXY,RIL,SIL,*,*,RS,RS,VRI,VRR,VRS,VRS,VRX,VRX")
1637 (set_attr "type" "*,*,*,*,*,*,*,*,floaddf,floaddf,la,larl,lr,load,store,
1638 floaddf,floaddf,floaddf,fstoredf,fstoredf,larl,*,*,*,*,
1639 *,*,*,*,*,*,*")
1640 (set_attr "cpu_facility" "*,*,*,*,*,extimm,extimm,extimm,dfp,dfp,longdisp,
1641 z10,*,*,*,*,*,longdisp,*,longdisp,
1642 z10,z10,*,*,*,*,vec,vec,vec,vec,vec,vec")
1643 (set_attr "z10prop" "z10_fwd_A1,
1644 z10_fwd_E1,
1645 z10_fwd_E1,
1646 z10_fwd_E1,
1647 z10_fwd_E1,
1648 z10_fwd_A1,
1649 z10_fwd_E1,
1650 z10_fwd_E1,
1651 *,
1652 *,
1653 z10_fwd_A1,
1654 z10_fwd_A3,
1655 z10_fr_E1,
1656 z10_fwd_A3,
1657 z10_rec,
1658 *,
1659 *,
1660 *,
1661 *,
1662 *,
1663 z10_rec,
1664 z10_super,
1665 *,
1666 *,
1667 *,
1668 *,*,*,*,*,*,*")
1669 ])
1670
1671 (define_split
1672 [(set (match_operand:DI 0 "register_operand" "")
1673 (match_operand:DI 1 "register_operand" ""))]
1674 "TARGET_ZARCH && ACCESS_REG_P (operands[1])"
1675 [(set (match_dup 2) (match_dup 3))
1676 (set (match_dup 0) (ashift:DI (match_dup 0) (const_int 32)))
1677 (set (strict_low_part (match_dup 2)) (match_dup 4))]
1678 "operands[2] = gen_lowpart (SImode, operands[0]);
1679 s390_split_access_reg (operands[1], &operands[4], &operands[3]);")
1680
1681 (define_split
1682 [(set (match_operand:DI 0 "register_operand" "")
1683 (match_operand:DI 1 "register_operand" ""))]
1684 "TARGET_ZARCH && ACCESS_REG_P (operands[0])
1685 && dead_or_set_p (insn, operands[1])"
1686 [(set (match_dup 3) (match_dup 2))
1687 (set (match_dup 1) (lshiftrt:DI (match_dup 1) (const_int 32)))
1688 (set (match_dup 4) (match_dup 2))]
1689 "operands[2] = gen_lowpart (SImode, operands[1]);
1690 s390_split_access_reg (operands[0], &operands[3], &operands[4]);")
1691
1692 (define_split
1693 [(set (match_operand:DI 0 "register_operand" "")
1694 (match_operand:DI 1 "register_operand" ""))]
1695 "TARGET_ZARCH && ACCESS_REG_P (operands[0])
1696 && !dead_or_set_p (insn, operands[1])"
1697 [(set (match_dup 3) (match_dup 2))
1698 (set (match_dup 1) (rotate:DI (match_dup 1) (const_int 32)))
1699 (set (match_dup 4) (match_dup 2))
1700 (set (match_dup 1) (rotate:DI (match_dup 1) (const_int 32)))]
1701 "operands[2] = gen_lowpart (SImode, operands[1]);
1702 s390_split_access_reg (operands[0], &operands[3], &operands[4]);")
1703
1704 (define_insn "*movdi_31"
1705 [(set (match_operand:DI 0 "nonimmediate_operand"
1706 "=d,d,Q,S,d ,o,!*f,!*f,!*f,!R,!T,d")
1707 (match_operand:DI 1 "general_operand"
1708 " Q,S,d,d,dPRT,d, *f, R, T,*f,*f,b"))]
1709 "!TARGET_ZARCH"
1710 "@
1711 lm\t%0,%N0,%S1
1712 lmy\t%0,%N0,%S1
1713 stm\t%1,%N1,%S0
1714 stmy\t%1,%N1,%S0
1715 #
1716 #
1717 ldr\t%0,%1
1718 ld\t%0,%1
1719 ldy\t%0,%1
1720 std\t%1,%0
1721 stdy\t%1,%0
1722 #"
1723 [(set_attr "op_type" "RS,RSY,RS,RSY,*,*,RR,RX,RXY,RX,RXY,*")
1724 (set_attr "type" "lm,lm,stm,stm,*,*,floaddf,floaddf,floaddf,fstoredf,fstoredf,*")
1725 (set_attr "cpu_facility" "*,*,*,*,*,*,*,*,*,*,*,z10")])
1726
1727 ; For a load from a symbol ref we can use one of the target registers
1728 ; together with larl to load the address.
1729 (define_split
1730 [(set (match_operand:DI 0 "register_operand" "")
1731 (match_operand:DI 1 "memory_operand" ""))]
1732 "!TARGET_ZARCH && reload_completed && TARGET_Z10
1733 && larl_operand (XEXP (operands[1], 0), SImode)"
1734 [(set (match_dup 2) (match_dup 3))
1735 (set (match_dup 0) (match_dup 1))]
1736 {
1737 operands[2] = operand_subword (operands[0], 1, 0, DImode);
1738 operands[3] = XEXP (operands[1], 0);
1739 operands[1] = replace_equiv_address (operands[1], operands[2]);
1740 })
1741
1742 (define_split
1743 [(set (match_operand:DI 0 "nonimmediate_operand" "")
1744 (match_operand:DI 1 "general_operand" ""))]
1745 "!TARGET_ZARCH && reload_completed
1746 && s390_split_ok_p (operands[0], operands[1], DImode, 0)"
1747 [(set (match_dup 2) (match_dup 4))
1748 (set (match_dup 3) (match_dup 5))]
1749 {
1750 operands[2] = operand_subword (operands[0], 0, 0, DImode);
1751 operands[3] = operand_subword (operands[0], 1, 0, DImode);
1752 operands[4] = operand_subword (operands[1], 0, 0, DImode);
1753 operands[5] = operand_subword (operands[1], 1, 0, DImode);
1754 })
1755
1756 (define_split
1757 [(set (match_operand:DI 0 "nonimmediate_operand" "")
1758 (match_operand:DI 1 "general_operand" ""))]
1759 "!TARGET_ZARCH && reload_completed
1760 && s390_split_ok_p (operands[0], operands[1], DImode, 1)"
1761 [(set (match_dup 2) (match_dup 4))
1762 (set (match_dup 3) (match_dup 5))]
1763 {
1764 operands[2] = operand_subword (operands[0], 1, 0, DImode);
1765 operands[3] = operand_subword (operands[0], 0, 0, DImode);
1766 operands[4] = operand_subword (operands[1], 1, 0, DImode);
1767 operands[5] = operand_subword (operands[1], 0, 0, DImode);
1768 })
1769
1770 (define_split
1771 [(set (match_operand:DI 0 "register_operand" "")
1772 (match_operand:DI 1 "memory_operand" ""))]
1773 "!TARGET_ZARCH && reload_completed
1774 && !FP_REG_P (operands[0])
1775 && !s_operand (operands[1], VOIDmode)"
1776 [(set (match_dup 0) (match_dup 1))]
1777 {
1778 rtx addr = operand_subword (operands[0], 1, 0, DImode);
1779 s390_load_address (addr, XEXP (operands[1], 0));
1780 operands[1] = replace_equiv_address (operands[1], addr);
1781 })
1782
1783 (define_peephole2
1784 [(set (match_operand:DI 0 "register_operand" "")
1785 (mem:DI (match_operand 1 "address_operand" "")))]
1786 "TARGET_ZARCH
1787 && !FP_REG_P (operands[0])
1788 && GET_CODE (operands[1]) == SYMBOL_REF
1789 && CONSTANT_POOL_ADDRESS_P (operands[1])
1790 && get_pool_mode (operands[1]) == DImode
1791 && legitimate_reload_constant_p (get_pool_constant (operands[1]))"
1792 [(set (match_dup 0) (match_dup 2))]
1793 "operands[2] = get_pool_constant (operands[1]);")
1794
1795 (define_insn "*la_64"
1796 [(set (match_operand:DI 0 "register_operand" "=d,d")
1797 (match_operand:QI 1 "address_operand" "ZQZR,ZSZT"))]
1798 "TARGET_64BIT"
1799 "@
1800 la\t%0,%a1
1801 lay\t%0,%a1"
1802 [(set_attr "op_type" "RX,RXY")
1803 (set_attr "type" "la")
1804 (set_attr "z10prop" "z10_fwd_A1,z10_fwd_A1")])
1805
1806 (define_peephole2
1807 [(parallel
1808 [(set (match_operand:DI 0 "register_operand" "")
1809 (match_operand:QI 1 "address_operand" ""))
1810 (clobber (reg:CC CC_REGNUM))])]
1811 "TARGET_64BIT
1812 && preferred_la_operand_p (operands[1], const0_rtx)"
1813 [(set (match_dup 0) (match_dup 1))]
1814 "")
1815
1816 (define_peephole2
1817 [(set (match_operand:DI 0 "register_operand" "")
1818 (match_operand:DI 1 "register_operand" ""))
1819 (parallel
1820 [(set (match_dup 0)
1821 (plus:DI (match_dup 0)
1822 (match_operand:DI 2 "nonmemory_operand" "")))
1823 (clobber (reg:CC CC_REGNUM))])]
1824 "TARGET_64BIT
1825 && !reg_overlap_mentioned_p (operands[0], operands[2])
1826 && preferred_la_operand_p (operands[1], operands[2])"
1827 [(set (match_dup 0) (plus:DI (match_dup 1) (match_dup 2)))]
1828 "")
1829
1830 ;
1831 ; movsi instruction pattern(s).
1832 ;
1833
1834 (define_expand "movsi"
1835 [(set (match_operand:SI 0 "general_operand" "")
1836 (match_operand:SI 1 "general_operand" ""))]
1837 ""
1838 {
1839 /* Handle symbolic constants. */
1840 if (!TARGET_64BIT
1841 && (SYMBOLIC_CONST (operands[1])
1842 || (GET_CODE (operands[1]) == PLUS
1843 && XEXP (operands[1], 0) == pic_offset_table_rtx
1844 && SYMBOLIC_CONST (XEXP(operands[1], 1)))))
1845 emit_symbolic_move (operands);
1846 })
1847
1848 (define_insn "*movsi_larl"
1849 [(set (match_operand:SI 0 "register_operand" "=d")
1850 (match_operand:SI 1 "larl_operand" "X"))]
1851 "!TARGET_64BIT && TARGET_CPU_ZARCH
1852 && !FP_REG_P (operands[0])"
1853 "larl\t%0,%1"
1854 [(set_attr "op_type" "RIL")
1855 (set_attr "type" "larl")
1856 (set_attr "z10prop" "z10_fwd_A1")])
1857
1858 (define_insn "*movsi_zarch"
1859 [(set (match_operand:SI 0 "nonimmediate_operand"
1860 "=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,QR")
1861 (match_operand:SI 1 "general_operand"
1862 " 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,QR, v"))]
1863 "TARGET_ZARCH"
1864 "@
1865 lhi\t%0,%h1
1866 llilh\t%0,%i1
1867 llill\t%0,%i1
1868 iilf\t%0,%o1
1869 lay\t%0,%a1
1870 lrl\t%0,%1
1871 lr\t%0,%1
1872 l\t%0,%1
1873 ly\t%0,%1
1874 st\t%1,%0
1875 sty\t%1,%0
1876 lder\t%0,%1
1877 ler\t%0,%1
1878 lde\t%0,%1
1879 le\t%0,%1
1880 ley\t%0,%1
1881 ste\t%1,%0
1882 stey\t%1,%0
1883 ear\t%0,%1
1884 sar\t%0,%1
1885 stam\t%1,%1,%S0
1886 strl\t%1,%0
1887 mvhi\t%0,%1
1888 lam\t%0,%0,%S1
1889 vleif\t%v0,%h1,0
1890 vlr\t%v0,%v1
1891 vlvgf\t%v0,%1,0
1892 vlgvf\t%0,%v1,0
1893 vlef\t%v0,%1,0
1894 vstef\t%v1,%0,0"
1895 [(set_attr "op_type" "RI,RI,RI,RIL,RXY,RIL,RR,RX,RXY,RX,RXY,
1896 RRE,RR,RXE,RX,RXY,RX,RXY,RRE,RRE,RS,RIL,SIL,RS,VRI,VRR,VRS,VRS,VRX,VRX")
1897 (set_attr "type" "*,
1898 *,
1899 *,
1900 *,
1901 la,
1902 larl,
1903 lr,
1904 load,
1905 load,
1906 store,
1907 store,
1908 floadsf,
1909 floadsf,
1910 floadsf,
1911 floadsf,
1912 floadsf,
1913 fstoresf,
1914 fstoresf,
1915 *,
1916 *,
1917 *,
1918 larl,
1919 *,
1920 *,*,*,*,*,*,*")
1921 (set_attr "cpu_facility" "*,*,*,extimm,longdisp,z10,*,*,longdisp,*,longdisp,
1922 vec,*,vec,*,longdisp,*,longdisp,*,*,*,z10,z10,*,vec,vec,vec,vec,vec,vec")
1923 (set_attr "z10prop" "z10_fwd_A1,
1924 z10_fwd_E1,
1925 z10_fwd_E1,
1926 z10_fwd_A1,
1927 z10_fwd_A1,
1928 z10_fwd_A3,
1929 z10_fr_E1,
1930 z10_fwd_A3,
1931 z10_fwd_A3,
1932 z10_rec,
1933 z10_rec,
1934 *,
1935 *,
1936 *,
1937 *,
1938 *,
1939 *,
1940 *,
1941 z10_super_E1,
1942 z10_super,
1943 *,
1944 z10_rec,
1945 z10_super,
1946 *,*,*,*,*,*,*")])
1947
1948 (define_insn "*movsi_esa"
1949 [(set (match_operand:SI 0 "nonimmediate_operand" "=d,d,d,R,!*f,!*f,!*f,!*f,!R,d,t,Q,t")
1950 (match_operand:SI 1 "general_operand" "K,d,R,d, *f, *f, R, R,*f,t,d,t,Q"))]
1951 "!TARGET_ZARCH"
1952 "@
1953 lhi\t%0,%h1
1954 lr\t%0,%1
1955 l\t%0,%1
1956 st\t%1,%0
1957 lder\t%0,%1
1958 ler\t%0,%1
1959 lde\t%0,%1
1960 le\t%0,%1
1961 ste\t%1,%0
1962 ear\t%0,%1
1963 sar\t%0,%1
1964 stam\t%1,%1,%S0
1965 lam\t%0,%0,%S1"
1966 [(set_attr "op_type" "RI,RR,RX,RX,RRE,RR,RXE,RX,RX,RRE,RRE,RS,RS")
1967 (set_attr "type" "*,lr,load,store,floadsf,floadsf,floadsf,floadsf,fstoresf,*,*,*,*")
1968 (set_attr "z10prop" "z10_fwd_A1,z10_fr_E1,z10_fwd_A3,z10_rec,*,*,*,*,*,z10_super_E1,
1969 z10_super,*,*")
1970 (set_attr "cpu_facility" "*,*,*,*,vec,*,vec,*,*,*,*,*,*")
1971 ])
1972
1973 (define_peephole2
1974 [(set (match_operand:SI 0 "register_operand" "")
1975 (mem:SI (match_operand 1 "address_operand" "")))]
1976 "!FP_REG_P (operands[0])
1977 && GET_CODE (operands[1]) == SYMBOL_REF
1978 && CONSTANT_POOL_ADDRESS_P (operands[1])
1979 && get_pool_mode (operands[1]) == SImode
1980 && legitimate_reload_constant_p (get_pool_constant (operands[1]))"
1981 [(set (match_dup 0) (match_dup 2))]
1982 "operands[2] = get_pool_constant (operands[1]);")
1983
1984 (define_insn "*la_31"
1985 [(set (match_operand:SI 0 "register_operand" "=d,d")
1986 (match_operand:QI 1 "address_operand" "ZQZR,ZSZT"))]
1987 "!TARGET_64BIT && legitimate_la_operand_p (operands[1])"
1988 "@
1989 la\t%0,%a1
1990 lay\t%0,%a1"
1991 [(set_attr "op_type" "RX,RXY")
1992 (set_attr "type" "la")
1993 (set_attr "z10prop" "z10_fwd_A1,z10_fwd_A1")])
1994
1995 (define_peephole2
1996 [(parallel
1997 [(set (match_operand:SI 0 "register_operand" "")
1998 (match_operand:QI 1 "address_operand" ""))
1999 (clobber (reg:CC CC_REGNUM))])]
2000 "!TARGET_64BIT
2001 && preferred_la_operand_p (operands[1], const0_rtx)"
2002 [(set (match_dup 0) (match_dup 1))]
2003 "")
2004
2005 (define_peephole2
2006 [(set (match_operand:SI 0 "register_operand" "")
2007 (match_operand:SI 1 "register_operand" ""))
2008 (parallel
2009 [(set (match_dup 0)
2010 (plus:SI (match_dup 0)
2011 (match_operand:SI 2 "nonmemory_operand" "")))
2012 (clobber (reg:CC CC_REGNUM))])]
2013 "!TARGET_64BIT
2014 && !reg_overlap_mentioned_p (operands[0], operands[2])
2015 && preferred_la_operand_p (operands[1], operands[2])"
2016 [(set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))]
2017 "")
2018
2019 (define_insn "*la_31_and"
2020 [(set (match_operand:SI 0 "register_operand" "=d,d")
2021 (and:SI (match_operand:QI 1 "address_operand" "ZQZR,ZSZT")
2022 (const_int 2147483647)))]
2023 "!TARGET_64BIT"
2024 "@
2025 la\t%0,%a1
2026 lay\t%0,%a1"
2027 [(set_attr "op_type" "RX,RXY")
2028 (set_attr "type" "la")
2029 (set_attr "z10prop" "z10_fwd_A1,z10_fwd_A1")])
2030
2031 (define_insn_and_split "*la_31_and_cc"
2032 [(set (match_operand:SI 0 "register_operand" "=d")
2033 (and:SI (match_operand:QI 1 "address_operand" "p")
2034 (const_int 2147483647)))
2035 (clobber (reg:CC CC_REGNUM))]
2036 "!TARGET_64BIT"
2037 "#"
2038 "&& reload_completed"
2039 [(set (match_dup 0)
2040 (and:SI (match_dup 1) (const_int 2147483647)))]
2041 ""
2042 [(set_attr "op_type" "RX")
2043 (set_attr "type" "la")])
2044
2045 (define_insn "force_la_31"
2046 [(set (match_operand:SI 0 "register_operand" "=d,d")
2047 (match_operand:QI 1 "address_operand" "ZQZR,ZSZT"))
2048 (use (const_int 0))]
2049 "!TARGET_64BIT"
2050 "@
2051 la\t%0,%a1
2052 lay\t%0,%a1"
2053 [(set_attr "op_type" "RX")
2054 (set_attr "type" "la")
2055 (set_attr "z10prop" "z10_fwd_A1,z10_fwd_A1")])
2056
2057 ;
2058 ; movhi instruction pattern(s).
2059 ;
2060
2061 (define_expand "movhi"
2062 [(set (match_operand:HI 0 "nonimmediate_operand" "")
2063 (match_operand:HI 1 "general_operand" ""))]
2064 ""
2065 {
2066 /* Make it explicit that loading a register from memory
2067 always sign-extends (at least) to SImode. */
2068 if (optimize && can_create_pseudo_p ()
2069 && register_operand (operands[0], VOIDmode)
2070 && GET_CODE (operands[1]) == MEM)
2071 {
2072 rtx tmp = gen_reg_rtx (SImode);
2073 rtx ext = gen_rtx_SIGN_EXTEND (SImode, operands[1]);
2074 emit_insn (gen_rtx_SET (tmp, ext));
2075 operands[1] = gen_lowpart (HImode, tmp);
2076 }
2077 })
2078
2079 (define_insn "*movhi"
2080 [(set (match_operand:HI 0 "nonimmediate_operand" "=d,d,d,d,d,R,T,b,Q,v,v,v,d, v,QR")
2081 (match_operand:HI 1 "general_operand" " d,n,R,T,b,d,d,d,K,K,v,d,v,QR, v"))]
2082 ""
2083 "@
2084 lr\t%0,%1
2085 lhi\t%0,%h1
2086 lh\t%0,%1
2087 lhy\t%0,%1
2088 lhrl\t%0,%1
2089 sth\t%1,%0
2090 sthy\t%1,%0
2091 sthrl\t%1,%0
2092 mvhhi\t%0,%1
2093 vleih\t%v0,%h1,0
2094 vlr\t%v0,%v1
2095 vlvgh\t%v0,%1,0
2096 vlgvh\t%0,%v1,0
2097 vleh\t%v0,%1,0
2098 vsteh\t%v1,%0,0"
2099 [(set_attr "op_type" "RR,RI,RX,RXY,RIL,RX,RXY,RIL,SIL,VRI,VRR,VRS,VRS,VRX,VRX")
2100 (set_attr "type" "lr,*,*,*,larl,store,store,store,*,*,*,*,*,*,*")
2101 (set_attr "cpu_facility" "*,*,*,*,z10,*,*,z10,z10,vec,vec,vec,vec,vec,vec")
2102 (set_attr "z10prop" "z10_fr_E1,
2103 z10_fwd_A1,
2104 z10_super_E1,
2105 z10_super_E1,
2106 z10_super_E1,
2107 z10_rec,
2108 z10_rec,
2109 z10_rec,
2110 z10_super,*,*,*,*,*,*")])
2111
2112 (define_peephole2
2113 [(set (match_operand:HI 0 "register_operand" "")
2114 (mem:HI (match_operand 1 "address_operand" "")))]
2115 "GET_CODE (operands[1]) == SYMBOL_REF
2116 && CONSTANT_POOL_ADDRESS_P (operands[1])
2117 && get_pool_mode (operands[1]) == HImode
2118 && GET_CODE (get_pool_constant (operands[1])) == CONST_INT"
2119 [(set (match_dup 0) (match_dup 2))]
2120 "operands[2] = get_pool_constant (operands[1]);")
2121
2122 ;
2123 ; movqi instruction pattern(s).
2124 ;
2125
2126 (define_expand "movqi"
2127 [(set (match_operand:QI 0 "nonimmediate_operand" "")
2128 (match_operand:QI 1 "general_operand" ""))]
2129 ""
2130 {
2131 /* On z/Architecture, zero-extending from memory to register
2132 is just as fast as a QImode load. */
2133 if (TARGET_ZARCH && optimize && can_create_pseudo_p ()
2134 && register_operand (operands[0], VOIDmode)
2135 && GET_CODE (operands[1]) == MEM)
2136 {
2137 rtx tmp = gen_reg_rtx (DImode);
2138 rtx ext = gen_rtx_ZERO_EXTEND (DImode, operands[1]);
2139 emit_insn (gen_rtx_SET (tmp, ext));
2140 operands[1] = gen_lowpart (QImode, tmp);
2141 }
2142 })
2143
2144 (define_insn "*movqi"
2145 [(set (match_operand:QI 0 "nonimmediate_operand" "=d,d,d,d,R,T,Q,S,?Q,v,v,v,d, v,QR")
2146 (match_operand:QI 1 "general_operand" " d,n,R,T,d,d,n,n,?Q,K,v,d,v,QR, v"))]
2147 ""
2148 "@
2149 lr\t%0,%1
2150 lhi\t%0,%b1
2151 ic\t%0,%1
2152 icy\t%0,%1
2153 stc\t%1,%0
2154 stcy\t%1,%0
2155 mvi\t%S0,%b1
2156 mviy\t%S0,%b1
2157 #
2158 vleib\t%v0,%b1,0
2159 vlr\t%v0,%v1
2160 vlvgb\t%v0,%1,0
2161 vlgvb\t%0,%v1,0
2162 vleb\t%v0,%1,0
2163 vsteb\t%v1,%0,0"
2164 [(set_attr "op_type" "RR,RI,RX,RXY,RX,RXY,SI,SIY,SS,VRI,VRR,VRS,VRS,VRX,VRX")
2165 (set_attr "type" "lr,*,*,*,store,store,store,store,*,*,*,*,*,*,*")
2166 (set_attr "cpu_facility" "*,*,*,*,*,*,*,*,*,vec,vec,vec,vec,vec,vec")
2167 (set_attr "z10prop" "z10_fr_E1,
2168 z10_fwd_A1,
2169 z10_super_E1,
2170 z10_super_E1,
2171 z10_rec,
2172 z10_rec,
2173 z10_super,
2174 z10_super,
2175 *,*,*,*,*,*,*")])
2176
2177 (define_peephole2
2178 [(set (match_operand:QI 0 "nonimmediate_operand" "")
2179 (mem:QI (match_operand 1 "address_operand" "")))]
2180 "GET_CODE (operands[1]) == SYMBOL_REF
2181 && CONSTANT_POOL_ADDRESS_P (operands[1])
2182 && get_pool_mode (operands[1]) == QImode
2183 && GET_CODE (get_pool_constant (operands[1])) == CONST_INT"
2184 [(set (match_dup 0) (match_dup 2))]
2185 "operands[2] = get_pool_constant (operands[1]);")
2186
2187 ;
2188 ; movstrictqi instruction pattern(s).
2189 ;
2190
2191 (define_insn "*movstrictqi"
2192 [(set (strict_low_part (match_operand:QI 0 "register_operand" "+d,d"))
2193 (match_operand:QI 1 "memory_operand" "R,T"))]
2194 ""
2195 "@
2196 ic\t%0,%1
2197 icy\t%0,%1"
2198 [(set_attr "op_type" "RX,RXY")
2199 (set_attr "z10prop" "z10_super_E1,z10_super_E1")])
2200
2201 ;
2202 ; movstricthi instruction pattern(s).
2203 ;
2204
2205 (define_insn "*movstricthi"
2206 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+d,d"))
2207 (match_operand:HI 1 "memory_operand" "Q,S"))
2208 (clobber (reg:CC CC_REGNUM))]
2209 ""
2210 "@
2211 icm\t%0,3,%S1
2212 icmy\t%0,3,%S1"
2213 [(set_attr "op_type" "RS,RSY")
2214 (set_attr "z10prop" "z10_super_E1,z10_super_E1")])
2215
2216 ;
2217 ; movstrictsi instruction pattern(s).
2218 ;
2219
2220 (define_insn "movstrictsi"
2221 [(set (strict_low_part (match_operand:SI 0 "register_operand" "+d,d,d,d"))
2222 (match_operand:SI 1 "general_operand" "d,R,T,t"))]
2223 "TARGET_ZARCH"
2224 "@
2225 lr\t%0,%1
2226 l\t%0,%1
2227 ly\t%0,%1
2228 ear\t%0,%1"
2229 [(set_attr "op_type" "RR,RX,RXY,RRE")
2230 (set_attr "type" "lr,load,load,*")
2231 (set_attr "z10prop" "z10_fr_E1,z10_fwd_A3,z10_fwd_A3,z10_super_E1")])
2232
2233 ;
2234 ; mov(tf|td) instruction pattern(s).
2235 ;
2236
2237 (define_expand "mov<mode>"
2238 [(set (match_operand:TD_TF 0 "nonimmediate_operand" "")
2239 (match_operand:TD_TF 1 "general_operand" ""))]
2240 ""
2241 "")
2242
2243 (define_insn "*mov<mode>_64"
2244 [(set (match_operand:TD_TF 0 "nonimmediate_operand" "=f,f,f,o, d,QS, d,o")
2245 (match_operand:TD_TF 1 "general_operand" " G,f,o,f,QS, d,dRT,d"))]
2246 "TARGET_ZARCH"
2247 "@
2248 lzxr\t%0
2249 lxr\t%0,%1
2250 #
2251 #
2252 lmg\t%0,%N0,%S1
2253 stmg\t%1,%N1,%S0
2254 #
2255 #"
2256 [(set_attr "op_type" "RRE,RRE,*,*,RSY,RSY,*,*")
2257 (set_attr "type" "fsimptf,fsimptf,*,*,lm,stm,*,*")
2258 (set_attr "cpu_facility" "z196,*,*,*,*,*,*,*")])
2259
2260 (define_insn "*mov<mode>_31"
2261 [(set (match_operand:TD_TF 0 "nonimmediate_operand" "=f,f,f,o")
2262 (match_operand:TD_TF 1 "general_operand" " G,f,o,f"))]
2263 "!TARGET_ZARCH"
2264 "@
2265 lzxr\t%0
2266 lxr\t%0,%1
2267 #
2268 #"
2269 [(set_attr "op_type" "RRE,RRE,*,*")
2270 (set_attr "type" "fsimptf,fsimptf,*,*")
2271 (set_attr "cpu_facility" "z196,*,*,*")])
2272
2273 ; TFmode in GPRs splitters
2274
2275 (define_split
2276 [(set (match_operand:TD_TF 0 "nonimmediate_operand" "")
2277 (match_operand:TD_TF 1 "general_operand" ""))]
2278 "TARGET_ZARCH && reload_completed
2279 && s390_split_ok_p (operands[0], operands[1], <MODE>mode, 0)"
2280 [(set (match_dup 2) (match_dup 4))
2281 (set (match_dup 3) (match_dup 5))]
2282 {
2283 operands[2] = operand_subword (operands[0], 0, 0, <MODE>mode);
2284 operands[3] = operand_subword (operands[0], 1, 0, <MODE>mode);
2285 operands[4] = operand_subword (operands[1], 0, 0, <MODE>mode);
2286 operands[5] = operand_subword (operands[1], 1, 0, <MODE>mode);
2287 })
2288
2289 (define_split
2290 [(set (match_operand:TD_TF 0 "nonimmediate_operand" "")
2291 (match_operand:TD_TF 1 "general_operand" ""))]
2292 "TARGET_ZARCH && reload_completed
2293 && s390_split_ok_p (operands[0], operands[1], <MODE>mode, 1)"
2294 [(set (match_dup 2) (match_dup 4))
2295 (set (match_dup 3) (match_dup 5))]
2296 {
2297 operands[2] = operand_subword (operands[0], 1, 0, <MODE>mode);
2298 operands[3] = operand_subword (operands[0], 0, 0, <MODE>mode);
2299 operands[4] = operand_subword (operands[1], 1, 0, <MODE>mode);
2300 operands[5] = operand_subword (operands[1], 0, 0, <MODE>mode);
2301 })
2302
2303 (define_split
2304 [(set (match_operand:TD_TF 0 "register_operand" "")
2305 (match_operand:TD_TF 1 "memory_operand" ""))]
2306 "TARGET_ZARCH && reload_completed
2307 && GENERAL_REG_P (operands[0])
2308 && !s_operand (operands[1], VOIDmode)"
2309 [(set (match_dup 0) (match_dup 1))]
2310 {
2311 rtx addr = operand_subword (operands[0], 1, 0, <MODE>mode);
2312 addr = gen_lowpart (Pmode, addr);
2313 s390_load_address (addr, XEXP (operands[1], 0));
2314 operands[1] = replace_equiv_address (operands[1], addr);
2315 })
2316
2317 ; TFmode in BFPs splitters
2318
2319 (define_split
2320 [(set (match_operand:TD_TF 0 "register_operand" "")
2321 (match_operand:TD_TF 1 "memory_operand" ""))]
2322 "reload_completed && offsettable_memref_p (operands[1])
2323 && FP_REG_P (operands[0])"
2324 [(set (match_dup 2) (match_dup 4))
2325 (set (match_dup 3) (match_dup 5))]
2326 {
2327 operands[2] = simplify_gen_subreg (<HALF_TMODE>mode, operands[0],
2328 <MODE>mode, 0);
2329 operands[3] = simplify_gen_subreg (<HALF_TMODE>mode, operands[0],
2330 <MODE>mode, 8);
2331 operands[4] = adjust_address_nv (operands[1], <HALF_TMODE>mode, 0);
2332 operands[5] = adjust_address_nv (operands[1], <HALF_TMODE>mode, 8);
2333 })
2334
2335 (define_split
2336 [(set (match_operand:TD_TF 0 "memory_operand" "")
2337 (match_operand:TD_TF 1 "register_operand" ""))]
2338 "reload_completed && offsettable_memref_p (operands[0])
2339 && FP_REG_P (operands[1])"
2340 [(set (match_dup 2) (match_dup 4))
2341 (set (match_dup 3) (match_dup 5))]
2342 {
2343 operands[2] = adjust_address_nv (operands[0], <HALF_TMODE>mode, 0);
2344 operands[3] = adjust_address_nv (operands[0], <HALF_TMODE>mode, 8);
2345 operands[4] = simplify_gen_subreg (<HALF_TMODE>mode, operands[1],
2346 <MODE>mode, 0);
2347 operands[5] = simplify_gen_subreg (<HALF_TMODE>mode, operands[1],
2348 <MODE>mode, 8);
2349 })
2350
2351 ;
2352 ; mov(df|dd) instruction pattern(s).
2353 ;
2354
2355 (define_expand "mov<mode>"
2356 [(set (match_operand:DD_DF 0 "nonimmediate_operand" "")
2357 (match_operand:DD_DF 1 "general_operand" ""))]
2358 ""
2359 "")
2360
2361 (define_insn "*mov<mode>_64dfp"
2362 [(set (match_operand:DD_DF 0 "nonimmediate_operand"
2363 "=f,f,f,d,f,f,R,T,d,d,d, d,b,RT,v,v,d,v,QR")
2364 (match_operand:DD_DF 1 "general_operand"
2365 " G,f,d,f,R,T,f,f,G,d,b,RT,d, d,v,d,v,QR,v"))]
2366 "TARGET_DFP"
2367 "@
2368 lzdr\t%0
2369 ldr\t%0,%1
2370 ldgr\t%0,%1
2371 lgdr\t%0,%1
2372 ld\t%0,%1
2373 ldy\t%0,%1
2374 std\t%1,%0
2375 stdy\t%1,%0
2376 lghi\t%0,0
2377 lgr\t%0,%1
2378 lgrl\t%0,%1
2379 lg\t%0,%1
2380 stgrl\t%1,%0
2381 stg\t%1,%0
2382 vlr\t%v0,%v1
2383 vlvgg\t%v0,%1,0
2384 vlgvg\t%0,%v1,0
2385 vleg\t%0,%1,0
2386 vsteg\t%1,%0,0"
2387 [(set_attr "op_type" "RRE,RR,RRE,RRE,RX,RXY,RX,RXY,RI,RRE,RIL,RXY,RIL,RXY,VRR,VRS,VRS,VRX,VRX")
2388 (set_attr "type" "fsimpdf,floaddf,floaddf,floaddf,floaddf,floaddf,
2389 fstoredf,fstoredf,*,lr,load,load,store,store,*,*,*,load,store")
2390 (set_attr "z10prop" "*,*,*,*,*,*,*,*,z10_fwd_A1,z10_fr_E1,z10_fwd_A3,z10_fwd_A3,z10_rec,z10_rec,*,*,*,*,*")
2391 (set_attr "cpu_facility" "z196,*,*,*,*,*,*,*,*,*,z10,*,z10,*,vec,vec,vec,vec,vec")])
2392
2393 (define_insn "*mov<mode>_64"
2394 [(set (match_operand:DD_DF 0 "nonimmediate_operand" "=f,f,f,f,R,T,d,d,d, d,b,RT,v,v,QR")
2395 (match_operand:DD_DF 1 "general_operand" " G,f,R,T,f,f,G,d,b,RT,d, d,v,QR,v"))]
2396 "TARGET_ZARCH"
2397 "@
2398 lzdr\t%0
2399 ldr\t%0,%1
2400 ld\t%0,%1
2401 ldy\t%0,%1
2402 std\t%1,%0
2403 stdy\t%1,%0
2404 lghi\t%0,0
2405 lgr\t%0,%1
2406 lgrl\t%0,%1
2407 lg\t%0,%1
2408 stgrl\t%1,%0
2409 stg\t%1,%0
2410 vlr\t%v0,%v1
2411 vleg\t%v0,%1,0
2412 vsteg\t%v1,%0,0"
2413 [(set_attr "op_type" "RRE,RR,RX,RXY,RX,RXY,RI,RRE,RIL,RXY,RIL,RXY,VRR,VRX,VRX")
2414 (set_attr "type" "fsimpdf,fload<mode>,fload<mode>,fload<mode>,
2415 fstore<mode>,fstore<mode>,*,lr,load,load,store,store,*,load,store")
2416 (set_attr "z10prop" "*,*,*,*,*,*,z10_fwd_A1,z10_fr_E1,z10_fwd_A3,z10_fwd_A3,z10_rec,z10_rec,*,*,*")
2417 (set_attr "cpu_facility" "z196,*,*,*,*,*,*,*,z10,*,z10,*,vec,vec,vec")])
2418
2419 (define_insn "*mov<mode>_31"
2420 [(set (match_operand:DD_DF 0 "nonimmediate_operand"
2421 "=f,f,f,f,R,T,d,d,Q,S, d,o")
2422 (match_operand:DD_DF 1 "general_operand"
2423 " G,f,R,T,f,f,Q,S,d,d,dPRT,d"))]
2424 "!TARGET_ZARCH"
2425 "@
2426 lzdr\t%0
2427 ldr\t%0,%1
2428 ld\t%0,%1
2429 ldy\t%0,%1
2430 std\t%1,%0
2431 stdy\t%1,%0
2432 lm\t%0,%N0,%S1
2433 lmy\t%0,%N0,%S1
2434 stm\t%1,%N1,%S0
2435 stmy\t%1,%N1,%S0
2436 #
2437 #"
2438 [(set_attr "op_type" "RRE,RR,RX,RXY,RX,RXY,RS,RSY,RS,RSY,*,*")
2439 (set_attr "type" "fsimpdf,fload<mode>,fload<mode>,fload<mode>,
2440 fstore<mode>,fstore<mode>,lm,lm,stm,stm,*,*")
2441 (set_attr "cpu_facility" "z196,*,*,*,*,*,*,*,*,*,*,*")])
2442
2443 (define_split
2444 [(set (match_operand:DD_DF 0 "nonimmediate_operand" "")
2445 (match_operand:DD_DF 1 "general_operand" ""))]
2446 "!TARGET_ZARCH && reload_completed
2447 && s390_split_ok_p (operands[0], operands[1], <MODE>mode, 0)"
2448 [(set (match_dup 2) (match_dup 4))
2449 (set (match_dup 3) (match_dup 5))]
2450 {
2451 operands[2] = operand_subword (operands[0], 0, 0, <MODE>mode);
2452 operands[3] = operand_subword (operands[0], 1, 0, <MODE>mode);
2453 operands[4] = operand_subword (operands[1], 0, 0, <MODE>mode);
2454 operands[5] = operand_subword (operands[1], 1, 0, <MODE>mode);
2455 })
2456
2457 (define_split
2458 [(set (match_operand:DD_DF 0 "nonimmediate_operand" "")
2459 (match_operand:DD_DF 1 "general_operand" ""))]
2460 "!TARGET_ZARCH && reload_completed
2461 && s390_split_ok_p (operands[0], operands[1], <MODE>mode, 1)"
2462 [(set (match_dup 2) (match_dup 4))
2463 (set (match_dup 3) (match_dup 5))]
2464 {
2465 operands[2] = operand_subword (operands[0], 1, 0, <MODE>mode);
2466 operands[3] = operand_subword (operands[0], 0, 0, <MODE>mode);
2467 operands[4] = operand_subword (operands[1], 1, 0, <MODE>mode);
2468 operands[5] = operand_subword (operands[1], 0, 0, <MODE>mode);
2469 })
2470
2471 (define_split
2472 [(set (match_operand:DD_DF 0 "register_operand" "")
2473 (match_operand:DD_DF 1 "memory_operand" ""))]
2474 "!TARGET_ZARCH && reload_completed
2475 && !FP_REG_P (operands[0])
2476 && !s_operand (operands[1], VOIDmode)"
2477 [(set (match_dup 0) (match_dup 1))]
2478 {
2479 rtx addr = operand_subword (operands[0], 1, 0, <MODE>mode);
2480 s390_load_address (addr, XEXP (operands[1], 0));
2481 operands[1] = replace_equiv_address (operands[1], addr);
2482 })
2483
2484 ;
2485 ; mov(sf|sd) instruction pattern(s).
2486 ;
2487
2488 (define_insn "mov<mode>"
2489 [(set (match_operand:SD_SF 0 "nonimmediate_operand"
2490 "=f,f,f,f,f,f,R,T,d,d,d,d,d,b,R,T,v,v,v,d,v,QR")
2491 (match_operand:SD_SF 1 "general_operand"
2492 " G,f,f,R,R,T,f,f,G,d,b,R,T,d,d,d,v,G,d,v,QR,v"))]
2493 ""
2494 "@
2495 lzer\t%0
2496 lder\t%0,%1
2497 ler\t%0,%1
2498 lde\t%0,%1
2499 le\t%0,%1
2500 ley\t%0,%1
2501 ste\t%1,%0
2502 stey\t%1,%0
2503 lhi\t%0,0
2504 lr\t%0,%1
2505 lrl\t%0,%1
2506 l\t%0,%1
2507 ly\t%0,%1
2508 strl\t%1,%0
2509 st\t%1,%0
2510 sty\t%1,%0
2511 vlr\t%v0,%v1
2512 vleif\t%v0,0
2513 vlvgf\t%v0,%1,0
2514 vlgvf\t%0,%v1,0
2515 vleg\t%0,%1,0
2516 vsteg\t%1,%0,0"
2517 [(set_attr "op_type" "RRE,RRE,RR,RXE,RX,RXY,RX,RXY,RI,RR,RIL,RX,RXY,RIL,RX,RXY,VRR,VRI,VRS,VRS,VRX,VRX")
2518 (set_attr "type" "fsimpsf,fsimpsf,fload<mode>,fload<mode>,fload<mode>,fload<mode>,
2519 fstore<mode>,fstore<mode>,*,lr,load,load,load,store,store,store,*,*,*,*,load,store")
2520 (set_attr "z10prop" "*,*,*,*,*,*,*,*,z10_fwd_A1,z10_fr_E1,z10_fr_E1,z10_fwd_A3,z10_fwd_A3,z10_rec,z10_rec,z10_rec,*,*,*,*,*,*")
2521 (set_attr "cpu_facility" "z196,vec,*,vec,*,*,*,*,*,*,z10,*,*,z10,*,*,vec,vec,vec,vec,vec,vec")])
2522
2523 ;
2524 ; movcc instruction pattern
2525 ;
2526
2527 (define_insn "movcc"
2528 [(set (match_operand:CC 0 "nonimmediate_operand" "=d,c,d,d,d,R,T")
2529 (match_operand:CC 1 "nonimmediate_operand" " d,d,c,R,T,d,d"))]
2530 ""
2531 "@
2532 lr\t%0,%1
2533 tmh\t%1,12288
2534 ipm\t%0
2535 l\t%0,%1
2536 ly\t%0,%1
2537 st\t%1,%0
2538 sty\t%1,%0"
2539 [(set_attr "op_type" "RR,RI,RRE,RX,RXY,RX,RXY")
2540 (set_attr "type" "lr,*,*,load,load,store,store")
2541 (set_attr "z10prop" "z10_fr_E1,z10_super,*,z10_fwd_A3,z10_fwd_A3,z10_rec,z10_rec")
2542 (set_attr "z196prop" "*,*,z196_ends,*,*,*,*")])
2543
2544 ;
2545 ; Block move (MVC) patterns.
2546 ;
2547
2548 (define_insn "*mvc"
2549 [(set (match_operand:BLK 0 "memory_operand" "=Q")
2550 (match_operand:BLK 1 "memory_operand" "Q"))
2551 (use (match_operand 2 "const_int_operand" "n"))]
2552 "INTVAL (operands[2]) >= 1 && INTVAL (operands[2]) <= 256"
2553 "mvc\t%O0(%2,%R0),%S1"
2554 [(set_attr "op_type" "SS")])
2555
2556 ; This splitter converts a QI to QI mode copy into a BLK mode copy in
2557 ; order to have it implemented with mvc.
2558
2559 (define_split
2560 [(set (match_operand:QI 0 "memory_operand" "")
2561 (match_operand:QI 1 "memory_operand" ""))]
2562 "reload_completed"
2563 [(parallel
2564 [(set (match_dup 0) (match_dup 1))
2565 (use (const_int 1))])]
2566 {
2567 operands[0] = adjust_address (operands[0], BLKmode, 0);
2568 operands[1] = adjust_address (operands[1], BLKmode, 0);
2569 })
2570
2571
2572 (define_peephole2
2573 [(parallel
2574 [(set (match_operand:BLK 0 "memory_operand" "")
2575 (match_operand:BLK 1 "memory_operand" ""))
2576 (use (match_operand 2 "const_int_operand" ""))])
2577 (parallel
2578 [(set (match_operand:BLK 3 "memory_operand" "")
2579 (match_operand:BLK 4 "memory_operand" ""))
2580 (use (match_operand 5 "const_int_operand" ""))])]
2581 "s390_offset_p (operands[0], operands[3], operands[2])
2582 && s390_offset_p (operands[1], operands[4], operands[2])
2583 && !s390_overlap_p (operands[0], operands[1],
2584 INTVAL (operands[2]) + INTVAL (operands[5]))
2585 && INTVAL (operands[2]) + INTVAL (operands[5]) <= 256"
2586 [(parallel
2587 [(set (match_dup 6) (match_dup 7))
2588 (use (match_dup 8))])]
2589 "operands[6] = gen_rtx_MEM (BLKmode, XEXP (operands[0], 0));
2590 operands[7] = gen_rtx_MEM (BLKmode, XEXP (operands[1], 0));
2591 operands[8] = GEN_INT (INTVAL (operands[2]) + INTVAL (operands[5]));")
2592
2593
2594 ;
2595 ; load_multiple pattern(s).
2596 ;
2597 ; ??? Due to reload problems with replacing registers inside match_parallel
2598 ; we currently support load_multiple/store_multiple only after reload.
2599 ;
2600
2601 (define_expand "load_multiple"
2602 [(match_par_dup 3 [(set (match_operand 0 "" "")
2603 (match_operand 1 "" ""))
2604 (use (match_operand 2 "" ""))])]
2605 "reload_completed"
2606 {
2607 machine_mode mode;
2608 int regno;
2609 int count;
2610 rtx from;
2611 int i, off;
2612
2613 /* Support only loading a constant number of fixed-point registers from
2614 memory and only bother with this if more than two */
2615 if (GET_CODE (operands[2]) != CONST_INT
2616 || INTVAL (operands[2]) < 2
2617 || INTVAL (operands[2]) > 16
2618 || GET_CODE (operands[1]) != MEM
2619 || GET_CODE (operands[0]) != REG
2620 || REGNO (operands[0]) >= 16)
2621 FAIL;
2622
2623 count = INTVAL (operands[2]);
2624 regno = REGNO (operands[0]);
2625 mode = GET_MODE (operands[0]);
2626 if (mode != SImode && (!TARGET_ZARCH || mode != DImode))
2627 FAIL;
2628
2629 operands[3] = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (count));
2630 if (!can_create_pseudo_p ())
2631 {
2632 if (GET_CODE (XEXP (operands[1], 0)) == REG)
2633 {
2634 from = XEXP (operands[1], 0);
2635 off = 0;
2636 }
2637 else if (GET_CODE (XEXP (operands[1], 0)) == PLUS
2638 && GET_CODE (XEXP (XEXP (operands[1], 0), 0)) == REG
2639 && GET_CODE (XEXP (XEXP (operands[1], 0), 1)) == CONST_INT)
2640 {
2641 from = XEXP (XEXP (operands[1], 0), 0);
2642 off = INTVAL (XEXP (XEXP (operands[1], 0), 1));
2643 }
2644 else
2645 FAIL;
2646 }
2647 else
2648 {
2649 from = force_reg (Pmode, XEXP (operands[1], 0));
2650 off = 0;
2651 }
2652
2653 for (i = 0; i < count; i++)
2654 XVECEXP (operands[3], 0, i)
2655 = gen_rtx_SET (gen_rtx_REG (mode, regno + i),
2656 change_address (operands[1], mode,
2657 plus_constant (Pmode, from,
2658 off + i * GET_MODE_SIZE (mode))));
2659 })
2660
2661 (define_insn "*load_multiple_di"
2662 [(match_parallel 0 "load_multiple_operation"
2663 [(set (match_operand:DI 1 "register_operand" "=r")
2664 (match_operand:DI 2 "s_operand" "QS"))])]
2665 "reload_completed && TARGET_ZARCH"
2666 {
2667 int words = XVECLEN (operands[0], 0);
2668 operands[0] = gen_rtx_REG (DImode, REGNO (operands[1]) + words - 1);
2669 return "lmg\t%1,%0,%S2";
2670 }
2671 [(set_attr "op_type" "RSY")
2672 (set_attr "type" "lm")])
2673
2674 (define_insn "*load_multiple_si"
2675 [(match_parallel 0 "load_multiple_operation"
2676 [(set (match_operand:SI 1 "register_operand" "=r,r")
2677 (match_operand:SI 2 "s_operand" "Q,S"))])]
2678 "reload_completed"
2679 {
2680 int words = XVECLEN (operands[0], 0);
2681 operands[0] = gen_rtx_REG (SImode, REGNO (operands[1]) + words - 1);
2682 return which_alternative == 0 ? "lm\t%1,%0,%S2" : "lmy\t%1,%0,%S2";
2683 }
2684 [(set_attr "op_type" "RS,RSY")
2685 (set_attr "type" "lm")])
2686
2687 ;
2688 ; store multiple pattern(s).
2689 ;
2690
2691 (define_expand "store_multiple"
2692 [(match_par_dup 3 [(set (match_operand 0 "" "")
2693 (match_operand 1 "" ""))
2694 (use (match_operand 2 "" ""))])]
2695 "reload_completed"
2696 {
2697 machine_mode mode;
2698 int regno;
2699 int count;
2700 rtx to;
2701 int i, off;
2702
2703 /* Support only storing a constant number of fixed-point registers to
2704 memory and only bother with this if more than two. */
2705 if (GET_CODE (operands[2]) != CONST_INT
2706 || INTVAL (operands[2]) < 2
2707 || INTVAL (operands[2]) > 16
2708 || GET_CODE (operands[0]) != MEM
2709 || GET_CODE (operands[1]) != REG
2710 || REGNO (operands[1]) >= 16)
2711 FAIL;
2712
2713 count = INTVAL (operands[2]);
2714 regno = REGNO (operands[1]);
2715 mode = GET_MODE (operands[1]);
2716 if (mode != SImode && (!TARGET_ZARCH || mode != DImode))
2717 FAIL;
2718
2719 operands[3] = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (count));
2720
2721 if (!can_create_pseudo_p ())
2722 {
2723 if (GET_CODE (XEXP (operands[0], 0)) == REG)
2724 {
2725 to = XEXP (operands[0], 0);
2726 off = 0;
2727 }
2728 else if (GET_CODE (XEXP (operands[0], 0)) == PLUS
2729 && GET_CODE (XEXP (XEXP (operands[0], 0), 0)) == REG
2730 && GET_CODE (XEXP (XEXP (operands[0], 0), 1)) == CONST_INT)
2731 {
2732 to = XEXP (XEXP (operands[0], 0), 0);
2733 off = INTVAL (XEXP (XEXP (operands[0], 0), 1));
2734 }
2735 else
2736 FAIL;
2737 }
2738 else
2739 {
2740 to = force_reg (Pmode, XEXP (operands[0], 0));
2741 off = 0;
2742 }
2743
2744 for (i = 0; i < count; i++)
2745 XVECEXP (operands[3], 0, i)
2746 = gen_rtx_SET (change_address (operands[0], mode,
2747 plus_constant (Pmode, to,
2748 off + i * GET_MODE_SIZE (mode))),
2749 gen_rtx_REG (mode, regno + i));
2750 })
2751
2752 (define_insn "*store_multiple_di"
2753 [(match_parallel 0 "store_multiple_operation"
2754 [(set (match_operand:DI 1 "s_operand" "=QS")
2755 (match_operand:DI 2 "register_operand" "r"))])]
2756 "reload_completed && TARGET_ZARCH"
2757 {
2758 int words = XVECLEN (operands[0], 0);
2759 operands[0] = gen_rtx_REG (DImode, REGNO (operands[2]) + words - 1);
2760 return "stmg\t%2,%0,%S1";
2761 }
2762 [(set_attr "op_type" "RSY")
2763 (set_attr "type" "stm")])
2764
2765
2766 (define_insn "*store_multiple_si"
2767 [(match_parallel 0 "store_multiple_operation"
2768 [(set (match_operand:SI 1 "s_operand" "=Q,S")
2769 (match_operand:SI 2 "register_operand" "r,r"))])]
2770 "reload_completed"
2771 {
2772 int words = XVECLEN (operands[0], 0);
2773 operands[0] = gen_rtx_REG (SImode, REGNO (operands[2]) + words - 1);
2774 return which_alternative == 0 ? "stm\t%2,%0,%S1" : "stmy\t%2,%0,%S1";
2775 }
2776 [(set_attr "op_type" "RS,RSY")
2777 (set_attr "type" "stm")])
2778
2779 ;;
2780 ;; String instructions.
2781 ;;
2782
2783 (define_insn "*execute_rl"
2784 [(match_parallel 0 "execute_operation"
2785 [(unspec [(match_operand 1 "register_operand" "a")
2786 (match_operand 2 "" "")
2787 (match_operand:SI 3 "larl_operand" "X")] UNSPEC_EXECUTE)])]
2788 "TARGET_Z10 && GET_MODE_CLASS (GET_MODE (operands[1])) == MODE_INT
2789 && GET_MODE_SIZE (GET_MODE (operands[1])) <= UNITS_PER_WORD"
2790 "exrl\t%1,%3"
2791 [(set_attr "op_type" "RIL")
2792 (set_attr "type" "cs")])
2793
2794 (define_insn "*execute"
2795 [(match_parallel 0 "execute_operation"
2796 [(unspec [(match_operand 1 "register_operand" "a")
2797 (match_operand:BLK 2 "memory_operand" "R")
2798 (match_operand 3 "" "")] UNSPEC_EXECUTE)])]
2799 "GET_MODE_CLASS (GET_MODE (operands[1])) == MODE_INT
2800 && GET_MODE_SIZE (GET_MODE (operands[1])) <= UNITS_PER_WORD"
2801 "ex\t%1,%2"
2802 [(set_attr "op_type" "RX")
2803 (set_attr "type" "cs")])
2804
2805
2806 ;
2807 ; strlenM instruction pattern(s).
2808 ;
2809
2810 (define_expand "strlen<mode>"
2811 [(match_operand:P 0 "register_operand" "") ; result
2812 (match_operand:BLK 1 "memory_operand" "") ; input string
2813 (match_operand:SI 2 "immediate_operand" "") ; search character
2814 (match_operand:SI 3 "immediate_operand" "")] ; known alignment
2815 ""
2816 {
2817 if (!TARGET_VX || operands[2] != const0_rtx)
2818 emit_insn (gen_strlen_srst<mode> (operands[0], operands[1],
2819 operands[2], operands[3]));
2820 else
2821 s390_expand_vec_strlen (operands[0], operands[1], operands[3]);
2822
2823 DONE;
2824 })
2825
2826 (define_expand "strlen_srst<mode>"
2827 [(set (reg:SI 0) (match_operand:SI 2 "immediate_operand" ""))
2828 (parallel
2829 [(set (match_dup 4)
2830 (unspec:P [(const_int 0)
2831 (match_operand:BLK 1 "memory_operand" "")
2832 (reg:SI 0)
2833 (match_operand 3 "immediate_operand" "")] UNSPEC_SRST))
2834 (clobber (scratch:P))
2835 (clobber (reg:CC CC_REGNUM))])
2836 (parallel
2837 [(set (match_operand:P 0 "register_operand" "")
2838 (minus:P (match_dup 4) (match_dup 5)))
2839 (clobber (reg:CC CC_REGNUM))])]
2840 ""
2841 {
2842 operands[4] = gen_reg_rtx (Pmode);
2843 operands[5] = gen_reg_rtx (Pmode);
2844 emit_move_insn (operands[5], force_operand (XEXP (operands[1], 0), NULL_RTX));
2845 operands[1] = replace_equiv_address (operands[1], operands[5]);
2846 })
2847
2848 (define_insn "*strlen<mode>"
2849 [(set (match_operand:P 0 "register_operand" "=a")
2850 (unspec:P [(match_operand:P 2 "general_operand" "0")
2851 (mem:BLK (match_operand:P 3 "register_operand" "1"))
2852 (reg:SI 0)
2853 (match_operand 4 "immediate_operand" "")] UNSPEC_SRST))
2854 (clobber (match_scratch:P 1 "=a"))
2855 (clobber (reg:CC CC_REGNUM))]
2856 ""
2857 "srst\t%0,%1\;jo\t.-4"
2858 [(set_attr "length" "8")
2859 (set_attr "type" "vs")])
2860
2861 ;
2862 ; cmpstrM instruction pattern(s).
2863 ;
2864
2865 (define_expand "cmpstrsi"
2866 [(set (reg:SI 0) (const_int 0))
2867 (parallel
2868 [(clobber (match_operand 3 "" ""))
2869 (clobber (match_dup 4))
2870 (set (reg:CCU CC_REGNUM)
2871 (compare:CCU (match_operand:BLK 1 "memory_operand" "")
2872 (match_operand:BLK 2 "memory_operand" "")))
2873 (use (reg:SI 0))])
2874 (parallel
2875 [(set (match_operand:SI 0 "register_operand" "=d")
2876 (unspec:SI [(reg:CCU CC_REGNUM)] UNSPEC_STRCMPCC_TO_INT))
2877 (clobber (reg:CC CC_REGNUM))])]
2878 ""
2879 {
2880 /* As the result of CMPINT is inverted compared to what we need,
2881 we have to swap the operands. */
2882 rtx op1 = operands[2];
2883 rtx op2 = operands[1];
2884 rtx addr1 = gen_reg_rtx (Pmode);
2885 rtx addr2 = gen_reg_rtx (Pmode);
2886
2887 emit_move_insn (addr1, force_operand (XEXP (op1, 0), NULL_RTX));
2888 emit_move_insn (addr2, force_operand (XEXP (op2, 0), NULL_RTX));
2889 operands[1] = replace_equiv_address_nv (op1, addr1);
2890 operands[2] = replace_equiv_address_nv (op2, addr2);
2891 operands[3] = addr1;
2892 operands[4] = addr2;
2893 })
2894
2895 (define_insn "*cmpstr<mode>"
2896 [(clobber (match_operand:P 0 "register_operand" "=d"))
2897 (clobber (match_operand:P 1 "register_operand" "=d"))
2898 (set (reg:CCU CC_REGNUM)
2899 (compare:CCU (mem:BLK (match_operand:P 2 "register_operand" "0"))
2900 (mem:BLK (match_operand:P 3 "register_operand" "1"))))
2901 (use (reg:SI 0))]
2902 ""
2903 "clst\t%0,%1\;jo\t.-4"
2904 [(set_attr "length" "8")
2905 (set_attr "type" "vs")])
2906
2907 ;
2908 ; movstr instruction pattern.
2909 ;
2910
2911 (define_expand "movstr"
2912 [(set (reg:SI 0) (const_int 0))
2913 (parallel
2914 [(clobber (match_dup 3))
2915 (set (match_operand:BLK 1 "memory_operand" "")
2916 (match_operand:BLK 2 "memory_operand" ""))
2917 (set (match_operand 0 "register_operand" "")
2918 (unspec [(match_dup 1)
2919 (match_dup 2)
2920 (reg:SI 0)] UNSPEC_MVST))
2921 (clobber (reg:CC CC_REGNUM))])]
2922 ""
2923 {
2924 rtx addr1 = gen_reg_rtx (Pmode);
2925 rtx addr2 = gen_reg_rtx (Pmode);
2926
2927 emit_move_insn (addr1, force_operand (XEXP (operands[1], 0), NULL_RTX));
2928 emit_move_insn (addr2, force_operand (XEXP (operands[2], 0), NULL_RTX));
2929 operands[1] = replace_equiv_address_nv (operands[1], addr1);
2930 operands[2] = replace_equiv_address_nv (operands[2], addr2);
2931 operands[3] = addr2;
2932 })
2933
2934 (define_insn "*movstr"
2935 [(clobber (match_operand:P 2 "register_operand" "=d"))
2936 (set (mem:BLK (match_operand:P 1 "register_operand" "0"))
2937 (mem:BLK (match_operand:P 3 "register_operand" "2")))
2938 (set (match_operand:P 0 "register_operand" "=d")
2939 (unspec [(mem:BLK (match_dup 1))
2940 (mem:BLK (match_dup 3))
2941 (reg:SI 0)] UNSPEC_MVST))
2942 (clobber (reg:CC CC_REGNUM))]
2943 ""
2944 "mvst\t%1,%2\;jo\t.-4"
2945 [(set_attr "length" "8")
2946 (set_attr "type" "vs")])
2947
2948
2949 ;
2950 ; movmemM instruction pattern(s).
2951 ;
2952
2953 (define_expand "movmem<mode>"
2954 [(set (match_operand:BLK 0 "memory_operand" "") ; destination
2955 (match_operand:BLK 1 "memory_operand" "")) ; source
2956 (use (match_operand:GPR 2 "general_operand" "")) ; count
2957 (match_operand 3 "" "")]
2958 ""
2959 {
2960 if (s390_expand_movmem (operands[0], operands[1], operands[2]))
2961 DONE;
2962 else
2963 FAIL;
2964 })
2965
2966 ; Move a block that is up to 256 bytes in length.
2967 ; The block length is taken as (operands[2] % 256) + 1.
2968
2969 (define_expand "movmem_short"
2970 [(parallel
2971 [(set (match_operand:BLK 0 "memory_operand" "")
2972 (match_operand:BLK 1 "memory_operand" ""))
2973 (use (match_operand 2 "nonmemory_operand" ""))
2974 (use (const:BLK (unspec:BLK [(const_int 0)] UNSPEC_INSN)))
2975 (clobber (match_dup 3))])]
2976 ""
2977 "operands[3] = gen_rtx_SCRATCH (Pmode);")
2978
2979 (define_insn "*movmem_short"
2980 [(set (match_operand:BLK 0 "memory_operand" "=Q,Q,Q,Q")
2981 (match_operand:BLK 1 "memory_operand" "Q,Q,Q,Q"))
2982 (use (match_operand 2 "nonmemory_operand" "n,a,a,a"))
2983 (use (match_operand 3 "immediate_operand" "X,R,X,X"))
2984 (clobber (match_scratch:P 4 "=X,X,X,&a"))]
2985 "(GET_MODE (operands[2]) == Pmode || GET_MODE (operands[2]) == VOIDmode)"
2986 "#"
2987 [(set_attr "type" "cs")
2988 (set_attr "cpu_facility" "*,*,z10,cpu_zarch")])
2989
2990 (define_split
2991 [(set (match_operand:BLK 0 "memory_operand" "")
2992 (match_operand:BLK 1 "memory_operand" ""))
2993 (use (match_operand 2 "const_int_operand" ""))
2994 (use (match_operand 3 "immediate_operand" ""))
2995 (clobber (scratch))]
2996 "reload_completed"
2997 [(parallel
2998 [(set (match_dup 0) (match_dup 1))
2999 (use (match_dup 2))])]
3000 "operands[2] = GEN_INT ((INTVAL (operands[2]) & 0xff) + 1);")
3001
3002 (define_split
3003 [(set (match_operand:BLK 0 "memory_operand" "")
3004 (match_operand:BLK 1 "memory_operand" ""))
3005 (use (match_operand 2 "register_operand" ""))
3006 (use (match_operand 3 "memory_operand" ""))
3007 (clobber (scratch))]
3008 "reload_completed"
3009 [(parallel
3010 [(unspec [(match_dup 2) (match_dup 3)
3011 (const_int 0)] UNSPEC_EXECUTE)
3012 (set (match_dup 0) (match_dup 1))
3013 (use (const_int 1))])]
3014 "")
3015
3016 (define_split
3017 [(set (match_operand:BLK 0 "memory_operand" "")
3018 (match_operand:BLK 1 "memory_operand" ""))
3019 (use (match_operand 2 "register_operand" ""))
3020 (use (const:BLK (unspec:BLK [(const_int 0)] UNSPEC_INSN)))
3021 (clobber (scratch))]
3022 "TARGET_Z10 && reload_completed"
3023 [(parallel
3024 [(unspec [(match_dup 2) (const_int 0)
3025 (label_ref (match_dup 3))] UNSPEC_EXECUTE)
3026 (set (match_dup 0) (match_dup 1))
3027 (use (const_int 1))])]
3028 "operands[3] = gen_label_rtx ();")
3029
3030 (define_split
3031 [(set (match_operand:BLK 0 "memory_operand" "")
3032 (match_operand:BLK 1 "memory_operand" ""))
3033 (use (match_operand 2 "register_operand" ""))
3034 (use (const:BLK (unspec:BLK [(const_int 0)] UNSPEC_INSN)))
3035 (clobber (match_operand 3 "register_operand" ""))]
3036 "reload_completed && TARGET_CPU_ZARCH"
3037 [(set (match_dup 3) (label_ref (match_dup 4)))
3038 (parallel
3039 [(unspec [(match_dup 2) (mem:BLK (match_dup 3))
3040 (label_ref (match_dup 4))] UNSPEC_EXECUTE)
3041 (set (match_dup 0) (match_dup 1))
3042 (use (const_int 1))])]
3043 "operands[4] = gen_label_rtx ();")
3044
3045 ; Move a block of arbitrary length.
3046
3047 (define_expand "movmem_long"
3048 [(parallel
3049 [(clobber (match_dup 2))
3050 (clobber (match_dup 3))
3051 (set (match_operand:BLK 0 "memory_operand" "")
3052 (match_operand:BLK 1 "memory_operand" ""))
3053 (use (match_operand 2 "general_operand" ""))
3054 (use (match_dup 3))
3055 (clobber (reg:CC CC_REGNUM))])]
3056 ""
3057 {
3058 machine_mode sreg_mode = TARGET_ZARCH ? DImode : SImode;
3059 machine_mode dreg_mode = TARGET_ZARCH ? TImode : DImode;
3060 rtx reg0 = gen_reg_rtx (dreg_mode);
3061 rtx reg1 = gen_reg_rtx (dreg_mode);
3062 rtx addr0 = gen_lowpart (Pmode, gen_highpart (sreg_mode, reg0));
3063 rtx addr1 = gen_lowpart (Pmode, gen_highpart (sreg_mode, reg1));
3064 rtx len0 = gen_lowpart (Pmode, reg0);
3065 rtx len1 = gen_lowpart (Pmode, reg1);
3066
3067 emit_clobber (reg0);
3068 emit_move_insn (addr0, force_operand (XEXP (operands[0], 0), NULL_RTX));
3069 emit_move_insn (len0, operands[2]);
3070
3071 emit_clobber (reg1);
3072 emit_move_insn (addr1, force_operand (XEXP (operands[1], 0), NULL_RTX));
3073 emit_move_insn (len1, operands[2]);
3074
3075 operands[0] = replace_equiv_address_nv (operands[0], addr0);
3076 operands[1] = replace_equiv_address_nv (operands[1], addr1);
3077 operands[2] = reg0;
3078 operands[3] = reg1;
3079 })
3080
3081 (define_insn "*movmem_long"
3082 [(clobber (match_operand:<DBL> 0 "register_operand" "=d"))
3083 (clobber (match_operand:<DBL> 1 "register_operand" "=d"))
3084 (set (mem:BLK (subreg:P (match_operand:<DBL> 2 "register_operand" "0") 0))
3085 (mem:BLK (subreg:P (match_operand:<DBL> 3 "register_operand" "1") 0)))
3086 (use (match_dup 2))
3087 (use (match_dup 3))
3088 (clobber (reg:CC CC_REGNUM))]
3089 "TARGET_64BIT || !TARGET_ZARCH"
3090 "mvcle\t%0,%1,0\;jo\t.-4"
3091 [(set_attr "length" "8")
3092 (set_attr "type" "vs")])
3093
3094 (define_insn "*movmem_long_31z"
3095 [(clobber (match_operand:TI 0 "register_operand" "=d"))
3096 (clobber (match_operand:TI 1 "register_operand" "=d"))
3097 (set (mem:BLK (subreg:SI (match_operand:TI 2 "register_operand" "0") 4))
3098 (mem:BLK (subreg:SI (match_operand:TI 3 "register_operand" "1") 4)))
3099 (use (match_dup 2))
3100 (use (match_dup 3))
3101 (clobber (reg:CC CC_REGNUM))]
3102 "!TARGET_64BIT && TARGET_ZARCH"
3103 "mvcle\t%0,%1,0\;jo\t.-4"
3104 [(set_attr "length" "8")
3105 (set_attr "type" "vs")])
3106
3107
3108 ;
3109 ; Test data class.
3110 ;
3111
3112 (define_expand "signbit<mode>2"
3113 [(set (reg:CCZ CC_REGNUM)
3114 (unspec:CCZ [(match_operand:FP_ALL 1 "register_operand" "f")
3115 (match_dup 2)]
3116 UNSPEC_TDC_INSN))
3117 (set (match_operand:SI 0 "register_operand" "=d")
3118 (unspec:SI [(reg:CCZ CC_REGNUM)] UNSPEC_CC_TO_INT))]
3119 "TARGET_HARD_FLOAT"
3120 {
3121 operands[2] = GEN_INT (S390_TDC_SIGNBIT_SET);
3122 })
3123
3124 (define_expand "isinf<mode>2"
3125 [(set (reg:CCZ CC_REGNUM)
3126 (unspec:CCZ [(match_operand:FP_ALL 1 "register_operand" "f")
3127 (match_dup 2)]
3128 UNSPEC_TDC_INSN))
3129 (set (match_operand:SI 0 "register_operand" "=d")
3130 (unspec:SI [(reg:CCZ CC_REGNUM)] UNSPEC_CC_TO_INT))]
3131 "TARGET_HARD_FLOAT"
3132 {
3133 operands[2] = GEN_INT (S390_TDC_INFINITY);
3134 })
3135
3136 ; This extracts CC into a GPR properly shifted. The actual IPM
3137 ; instruction will be issued by reload. The constraint of operand 1
3138 ; forces reload to use a GPR. So reload will issue a movcc insn for
3139 ; copying CC into a GPR first.
3140 (define_insn_and_split "*cc_to_int"
3141 [(set (match_operand:SI 0 "nonimmediate_operand" "=d")
3142 (unspec:SI [(match_operand 1 "register_operand" "0")]
3143 UNSPEC_CC_TO_INT))]
3144 "operands != NULL"
3145 "#"
3146 "reload_completed"
3147 [(set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 28)))])
3148
3149 ; This insn is used to generate all variants of the Test Data Class
3150 ; instruction, namely tcxb, tcdb, and tceb. The insn's first operand
3151 ; is the register to be tested and the second one is the bit mask
3152 ; specifying the required test(s).
3153 ;
3154 ; tcxb, tcdb, tceb, tdcxt, tdcdt, tdcet
3155 (define_insn "*TDC_insn_<mode>"
3156 [(set (reg:CCZ CC_REGNUM)
3157 (unspec:CCZ [(match_operand:FP_ALL 0 "register_operand" "f")
3158 (match_operand:SI 1 "const_int_operand")] UNSPEC_TDC_INSN))]
3159 "TARGET_HARD_FLOAT"
3160 "t<_d>c<xde><bt>\t%0,%1"
3161 [(set_attr "op_type" "RXE")
3162 (set_attr "type" "fsimp<mode>")])
3163
3164
3165
3166 ;
3167 ; setmemM instruction pattern(s).
3168 ;
3169
3170 (define_expand "setmem<mode>"
3171 [(set (match_operand:BLK 0 "memory_operand" "")
3172 (match_operand:QI 2 "general_operand" ""))
3173 (use (match_operand:GPR 1 "general_operand" ""))
3174 (match_operand 3 "" "")]
3175 ""
3176 "s390_expand_setmem (operands[0], operands[1], operands[2]); DONE;")
3177
3178 ; Clear a block that is up to 256 bytes in length.
3179 ; The block length is taken as (operands[1] % 256) + 1.
3180
3181 (define_expand "clrmem_short"
3182 [(parallel
3183 [(set (match_operand:BLK 0 "memory_operand" "")
3184 (const_int 0))
3185 (use (match_operand 1 "nonmemory_operand" ""))
3186 (use (const:BLK (unspec:BLK [(const_int 0)] UNSPEC_INSN)))
3187 (clobber (match_dup 2))
3188 (clobber (reg:CC CC_REGNUM))])]
3189 ""
3190 "operands[2] = gen_rtx_SCRATCH (Pmode);")
3191
3192 (define_insn "*clrmem_short"
3193 [(set (match_operand:BLK 0 "memory_operand" "=Q,Q,Q,Q")
3194 (const_int 0))
3195 (use (match_operand 1 "nonmemory_operand" "n,a,a,a"))
3196 (use (match_operand 2 "immediate_operand" "X,R,X,X"))
3197 (clobber (match_scratch:P 3 "=X,X,X,&a"))
3198 (clobber (reg:CC CC_REGNUM))]
3199 "(GET_MODE (operands[1]) == Pmode || GET_MODE (operands[1]) == VOIDmode)"
3200 "#"
3201 [(set_attr "type" "cs")
3202 (set_attr "cpu_facility" "*,*,z10,cpu_zarch")])
3203
3204 (define_split
3205 [(set (match_operand:BLK 0 "memory_operand" "")
3206 (const_int 0))
3207 (use (match_operand 1 "const_int_operand" ""))
3208 (use (match_operand 2 "immediate_operand" ""))
3209 (clobber (scratch))
3210 (clobber (reg:CC CC_REGNUM))]
3211 "reload_completed"
3212 [(parallel
3213 [(set (match_dup 0) (const_int 0))
3214 (use (match_dup 1))
3215 (clobber (reg:CC CC_REGNUM))])]
3216 "operands[1] = GEN_INT ((INTVAL (operands[1]) & 0xff) + 1);")
3217
3218 (define_split
3219 [(set (match_operand:BLK 0 "memory_operand" "")
3220 (const_int 0))
3221 (use (match_operand 1 "register_operand" ""))
3222 (use (match_operand 2 "memory_operand" ""))
3223 (clobber (scratch))
3224 (clobber (reg:CC CC_REGNUM))]
3225 "reload_completed"
3226 [(parallel
3227 [(unspec [(match_dup 1) (match_dup 2)
3228 (const_int 0)] UNSPEC_EXECUTE)
3229 (set (match_dup 0) (const_int 0))
3230 (use (const_int 1))
3231 (clobber (reg:CC CC_REGNUM))])]
3232 "")
3233
3234 (define_split
3235 [(set (match_operand:BLK 0 "memory_operand" "")
3236 (const_int 0))
3237 (use (match_operand 1 "register_operand" ""))
3238 (use (const:BLK (unspec:BLK [(const_int 0)] UNSPEC_INSN)))
3239 (clobber (scratch))
3240 (clobber (reg:CC CC_REGNUM))]
3241 "TARGET_Z10 && reload_completed"
3242 [(parallel
3243 [(unspec [(match_dup 1) (const_int 0)
3244 (label_ref (match_dup 3))] UNSPEC_EXECUTE)
3245 (set (match_dup 0) (const_int 0))
3246 (use (const_int 1))
3247 (clobber (reg:CC CC_REGNUM))])]
3248 "operands[3] = gen_label_rtx ();")
3249
3250 (define_split
3251 [(set (match_operand:BLK 0 "memory_operand" "")
3252 (const_int 0))
3253 (use (match_operand 1 "register_operand" ""))
3254 (use (const:BLK (unspec:BLK [(const_int 0)] UNSPEC_INSN)))
3255 (clobber (match_operand 2 "register_operand" ""))
3256 (clobber (reg:CC CC_REGNUM))]
3257 "reload_completed && TARGET_CPU_ZARCH"
3258 [(set (match_dup 2) (label_ref (match_dup 3)))
3259 (parallel
3260 [(unspec [(match_dup 1) (mem:BLK (match_dup 2))
3261 (label_ref (match_dup 3))] UNSPEC_EXECUTE)
3262 (set (match_dup 0) (const_int 0))
3263 (use (const_int 1))
3264 (clobber (reg:CC CC_REGNUM))])]
3265 "operands[3] = gen_label_rtx ();")
3266
3267 ; Initialize a block of arbitrary length with (operands[2] % 256).
3268
3269 (define_expand "setmem_long"
3270 [(parallel
3271 [(clobber (match_dup 1))
3272 (set (match_operand:BLK 0 "memory_operand" "")
3273 (match_operand 2 "shift_count_or_setmem_operand" ""))
3274 (use (match_operand 1 "general_operand" ""))
3275 (use (match_dup 3))
3276 (clobber (reg:CC CC_REGNUM))])]
3277 ""
3278 {
3279 machine_mode sreg_mode = TARGET_ZARCH ? DImode : SImode;
3280 machine_mode dreg_mode = TARGET_ZARCH ? TImode : DImode;
3281 rtx reg0 = gen_reg_rtx (dreg_mode);
3282 rtx reg1 = gen_reg_rtx (dreg_mode);
3283 rtx addr0 = gen_lowpart (Pmode, gen_highpart (sreg_mode, reg0));
3284 rtx len0 = gen_lowpart (Pmode, reg0);
3285
3286 emit_clobber (reg0);
3287 emit_move_insn (addr0, force_operand (XEXP (operands[0], 0), NULL_RTX));
3288 emit_move_insn (len0, operands[1]);
3289
3290 emit_move_insn (reg1, const0_rtx);
3291
3292 operands[0] = replace_equiv_address_nv (operands[0], addr0);
3293 operands[1] = reg0;
3294 operands[3] = reg1;
3295 })
3296
3297 (define_insn "*setmem_long"
3298 [(clobber (match_operand:<DBL> 0 "register_operand" "=d"))
3299 (set (mem:BLK (subreg:P (match_operand:<DBL> 3 "register_operand" "0") 0))
3300 (match_operand 2 "shift_count_or_setmem_operand" "Y"))
3301 (use (match_dup 3))
3302 (use (match_operand:<DBL> 1 "register_operand" "d"))
3303 (clobber (reg:CC CC_REGNUM))]
3304 "TARGET_64BIT || !TARGET_ZARCH"
3305 "mvcle\t%0,%1,%Y2\;jo\t.-4"
3306 [(set_attr "length" "8")
3307 (set_attr "type" "vs")])
3308
3309 (define_insn "*setmem_long_and"
3310 [(clobber (match_operand:<DBL> 0 "register_operand" "=d"))
3311 (set (mem:BLK (subreg:P (match_operand:<DBL> 3 "register_operand" "0") 0))
3312 (and (match_operand 2 "shift_count_or_setmem_operand" "Y")
3313 (match_operand 4 "const_int_operand" "n")))
3314 (use (match_dup 3))
3315 (use (match_operand:<DBL> 1 "register_operand" "d"))
3316 (clobber (reg:CC CC_REGNUM))]
3317 "(TARGET_64BIT || !TARGET_ZARCH) &&
3318 (INTVAL (operands[4]) & 255) == 255"
3319 "mvcle\t%0,%1,%Y2\;jo\t.-4"
3320 [(set_attr "length" "8")
3321 (set_attr "type" "vs")])
3322
3323 (define_insn "*setmem_long_31z"
3324 [(clobber (match_operand:TI 0 "register_operand" "=d"))
3325 (set (mem:BLK (subreg:SI (match_operand:TI 3 "register_operand" "0") 4))
3326 (match_operand 2 "shift_count_or_setmem_operand" "Y"))
3327 (use (match_dup 3))
3328 (use (match_operand:TI 1 "register_operand" "d"))
3329 (clobber (reg:CC CC_REGNUM))]
3330 "!TARGET_64BIT && TARGET_ZARCH"
3331 "mvcle\t%0,%1,%Y2\;jo\t.-4"
3332 [(set_attr "length" "8")
3333 (set_attr "type" "vs")])
3334
3335 ;
3336 ; cmpmemM instruction pattern(s).
3337 ;
3338
3339 (define_expand "cmpmemsi"
3340 [(set (match_operand:SI 0 "register_operand" "")
3341 (compare:SI (match_operand:BLK 1 "memory_operand" "")
3342 (match_operand:BLK 2 "memory_operand" "") ) )
3343 (use (match_operand:SI 3 "general_operand" ""))
3344 (use (match_operand:SI 4 "" ""))]
3345 ""
3346 {
3347 if (s390_expand_cmpmem (operands[0], operands[1],
3348 operands[2], operands[3]))
3349 DONE;
3350 else
3351 FAIL;
3352 })
3353
3354 ; Compare a block that is up to 256 bytes in length.
3355 ; The block length is taken as (operands[2] % 256) + 1.
3356
3357 (define_expand "cmpmem_short"
3358 [(parallel
3359 [(set (reg:CCU CC_REGNUM)
3360 (compare:CCU (match_operand:BLK 0 "memory_operand" "")
3361 (match_operand:BLK 1 "memory_operand" "")))
3362 (use (match_operand 2 "nonmemory_operand" ""))
3363 (use (const:BLK (unspec:BLK [(const_int 0)] UNSPEC_INSN)))
3364 (clobber (match_dup 3))])]
3365 ""
3366 "operands[3] = gen_rtx_SCRATCH (Pmode);")
3367
3368 (define_insn "*cmpmem_short"
3369 [(set (reg:CCU CC_REGNUM)
3370 (compare:CCU (match_operand:BLK 0 "memory_operand" "Q,Q,Q,Q")
3371 (match_operand:BLK 1 "memory_operand" "Q,Q,Q,Q")))
3372 (use (match_operand 2 "nonmemory_operand" "n,a,a,a"))
3373 (use (match_operand 3 "immediate_operand" "X,R,X,X"))
3374 (clobber (match_scratch:P 4 "=X,X,X,&a"))]
3375 "(GET_MODE (operands[2]) == Pmode || GET_MODE (operands[2]) == VOIDmode)"
3376 "#"
3377 [(set_attr "type" "cs")
3378 (set_attr "cpu_facility" "*,*,z10,cpu_zarch")])
3379
3380 (define_split
3381 [(set (reg:CCU CC_REGNUM)
3382 (compare:CCU (match_operand:BLK 0 "memory_operand" "")
3383 (match_operand:BLK 1 "memory_operand" "")))
3384 (use (match_operand 2 "const_int_operand" ""))
3385 (use (match_operand 3 "immediate_operand" ""))
3386 (clobber (scratch))]
3387 "reload_completed"
3388 [(parallel
3389 [(set (reg:CCU CC_REGNUM) (compare:CCU (match_dup 0) (match_dup 1)))
3390 (use (match_dup 2))])]
3391 "operands[2] = GEN_INT ((INTVAL (operands[2]) & 0xff) + 1);")
3392
3393 (define_split
3394 [(set (reg:CCU CC_REGNUM)
3395 (compare:CCU (match_operand:BLK 0 "memory_operand" "")
3396 (match_operand:BLK 1 "memory_operand" "")))
3397 (use (match_operand 2 "register_operand" ""))
3398 (use (match_operand 3 "memory_operand" ""))
3399 (clobber (scratch))]
3400 "reload_completed"
3401 [(parallel
3402 [(unspec [(match_dup 2) (match_dup 3)
3403 (const_int 0)] UNSPEC_EXECUTE)
3404 (set (reg:CCU CC_REGNUM) (compare:CCU (match_dup 0) (match_dup 1)))
3405 (use (const_int 1))])]
3406 "")
3407
3408 (define_split
3409 [(set (reg:CCU CC_REGNUM)
3410 (compare:CCU (match_operand:BLK 0 "memory_operand" "")
3411 (match_operand:BLK 1 "memory_operand" "")))
3412 (use (match_operand 2 "register_operand" ""))
3413 (use (const:BLK (unspec:BLK [(const_int 0)] UNSPEC_INSN)))
3414 (clobber (scratch))]
3415 "TARGET_Z10 && reload_completed"
3416 [(parallel
3417 [(unspec [(match_dup 2) (const_int 0)
3418 (label_ref (match_dup 4))] UNSPEC_EXECUTE)
3419 (set (reg:CCU CC_REGNUM) (compare:CCU (match_dup 0) (match_dup 1)))
3420 (use (const_int 1))])]
3421 "operands[4] = gen_label_rtx ();")
3422
3423 (define_split
3424 [(set (reg:CCU CC_REGNUM)
3425 (compare:CCU (match_operand:BLK 0 "memory_operand" "")
3426 (match_operand:BLK 1 "memory_operand" "")))
3427 (use (match_operand 2 "register_operand" ""))
3428 (use (const:BLK (unspec:BLK [(const_int 0)] UNSPEC_INSN)))
3429 (clobber (match_operand 3 "register_operand" ""))]
3430 "reload_completed && TARGET_CPU_ZARCH"
3431 [(set (match_dup 3) (label_ref (match_dup 4)))
3432 (parallel
3433 [(unspec [(match_dup 2) (mem:BLK (match_dup 3))
3434 (label_ref (match_dup 4))] UNSPEC_EXECUTE)
3435 (set (reg:CCU CC_REGNUM) (compare:CCU (match_dup 0) (match_dup 1)))
3436 (use (const_int 1))])]
3437 "operands[4] = gen_label_rtx ();")
3438
3439 ; Compare a block of arbitrary length.
3440
3441 (define_expand "cmpmem_long"
3442 [(parallel
3443 [(clobber (match_dup 2))
3444 (clobber (match_dup 3))
3445 (set (reg:CCU CC_REGNUM)
3446 (compare:CCU (match_operand:BLK 0 "memory_operand" "")
3447 (match_operand:BLK 1 "memory_operand" "")))
3448 (use (match_operand 2 "general_operand" ""))
3449 (use (match_dup 3))])]
3450 ""
3451 {
3452 machine_mode sreg_mode = TARGET_ZARCH ? DImode : SImode;
3453 machine_mode dreg_mode = TARGET_ZARCH ? TImode : DImode;
3454 rtx reg0 = gen_reg_rtx (dreg_mode);
3455 rtx reg1 = gen_reg_rtx (dreg_mode);
3456 rtx addr0 = gen_lowpart (Pmode, gen_highpart (sreg_mode, reg0));
3457 rtx addr1 = gen_lowpart (Pmode, gen_highpart (sreg_mode, reg1));
3458 rtx len0 = gen_lowpart (Pmode, reg0);
3459 rtx len1 = gen_lowpart (Pmode, reg1);
3460
3461 emit_clobber (reg0);
3462 emit_move_insn (addr0, force_operand (XEXP (operands[0], 0), NULL_RTX));
3463 emit_move_insn (len0, operands[2]);
3464
3465 emit_clobber (reg1);
3466 emit_move_insn (addr1, force_operand (XEXP (operands[1], 0), NULL_RTX));
3467 emit_move_insn (len1, operands[2]);
3468
3469 operands[0] = replace_equiv_address_nv (operands[0], addr0);
3470 operands[1] = replace_equiv_address_nv (operands[1], addr1);
3471 operands[2] = reg0;
3472 operands[3] = reg1;
3473 })
3474
3475 (define_insn "*cmpmem_long"
3476 [(clobber (match_operand:<DBL> 0 "register_operand" "=d"))
3477 (clobber (match_operand:<DBL> 1 "register_operand" "=d"))
3478 (set (reg:CCU CC_REGNUM)
3479 (compare:CCU (mem:BLK (subreg:P (match_operand:<DBL> 2 "register_operand" "0") 0))
3480 (mem:BLK (subreg:P (match_operand:<DBL> 3 "register_operand" "1") 0))))
3481 (use (match_dup 2))
3482 (use (match_dup 3))]
3483 "TARGET_64BIT || !TARGET_ZARCH"
3484 "clcle\t%0,%1,0\;jo\t.-4"
3485 [(set_attr "length" "8")
3486 (set_attr "type" "vs")])
3487
3488 (define_insn "*cmpmem_long_31z"
3489 [(clobber (match_operand:TI 0 "register_operand" "=d"))
3490 (clobber (match_operand:TI 1 "register_operand" "=d"))
3491 (set (reg:CCU CC_REGNUM)
3492 (compare:CCU (mem:BLK (subreg:SI (match_operand:TI 2 "register_operand" "0") 4))
3493 (mem:BLK (subreg:SI (match_operand:TI 3 "register_operand" "1") 4))))
3494 (use (match_dup 2))
3495 (use (match_dup 3))]
3496 "!TARGET_64BIT && TARGET_ZARCH"
3497 "clcle\t%0,%1,0\;jo\t.-4"
3498 [(set_attr "op_type" "NN")
3499 (set_attr "type" "vs")
3500 (set_attr "length" "8")])
3501
3502 ; Convert CCUmode condition code to integer.
3503 ; Result is zero if EQ, positive if LTU, negative if GTU.
3504
3505 (define_insn_and_split "cmpint"
3506 [(set (match_operand:SI 0 "register_operand" "=d")
3507 (unspec:SI [(match_operand:CCU 1 "register_operand" "0")]
3508 UNSPEC_STRCMPCC_TO_INT))
3509 (clobber (reg:CC CC_REGNUM))]
3510 ""
3511 "#"
3512 "reload_completed"
3513 [(set (match_dup 0) (ashift:SI (match_dup 0) (const_int 2)))
3514 (parallel
3515 [(set (match_dup 0) (ashiftrt:SI (match_dup 0) (const_int 30)))
3516 (clobber (reg:CC CC_REGNUM))])])
3517
3518 (define_insn_and_split "*cmpint_cc"
3519 [(set (reg CC_REGNUM)
3520 (compare (unspec:SI [(match_operand:CCU 1 "register_operand" "0")]
3521 UNSPEC_STRCMPCC_TO_INT)
3522 (const_int 0)))
3523 (set (match_operand:SI 0 "register_operand" "=d")
3524 (unspec:SI [(match_dup 1)] UNSPEC_STRCMPCC_TO_INT))]
3525 "s390_match_ccmode (insn, CCSmode)"
3526 "#"
3527 "&& reload_completed"
3528 [(set (match_dup 0) (ashift:SI (match_dup 0) (const_int 2)))
3529 (parallel
3530 [(set (match_dup 2) (match_dup 3))
3531 (set (match_dup 0) (ashiftrt:SI (match_dup 0) (const_int 30)))])]
3532 {
3533 rtx result = gen_rtx_ASHIFTRT (SImode, operands[0], GEN_INT (30));
3534 operands[2] = SET_DEST (XVECEXP (PATTERN (curr_insn), 0, 0));
3535 operands[3] = gen_rtx_COMPARE (GET_MODE (operands[2]), result, const0_rtx);
3536 })
3537
3538 (define_insn_and_split "*cmpint_sign"
3539 [(set (match_operand:DI 0 "register_operand" "=d")
3540 (sign_extend:DI (unspec:SI [(match_operand:CCU 1 "register_operand" "0")]
3541 UNSPEC_STRCMPCC_TO_INT)))
3542 (clobber (reg:CC CC_REGNUM))]
3543 "TARGET_ZARCH"
3544 "#"
3545 "&& reload_completed"
3546 [(set (match_dup 0) (ashift:DI (match_dup 0) (const_int 34)))
3547 (parallel
3548 [(set (match_dup 0) (ashiftrt:DI (match_dup 0) (const_int 62)))
3549 (clobber (reg:CC CC_REGNUM))])])
3550
3551 (define_insn_and_split "*cmpint_sign_cc"
3552 [(set (reg CC_REGNUM)
3553 (compare (ashiftrt:DI (ashift:DI (subreg:DI
3554 (unspec:SI [(match_operand:CCU 1 "register_operand" "0")]
3555 UNSPEC_STRCMPCC_TO_INT) 0)
3556 (const_int 32)) (const_int 32))
3557 (const_int 0)))
3558 (set (match_operand:DI 0 "register_operand" "=d")
3559 (sign_extend:DI (unspec:SI [(match_dup 1)] UNSPEC_STRCMPCC_TO_INT)))]
3560 "s390_match_ccmode (insn, CCSmode) && TARGET_ZARCH"
3561 "#"
3562 "&& reload_completed"
3563 [(set (match_dup 0) (ashift:DI (match_dup 0) (const_int 34)))
3564 (parallel
3565 [(set (match_dup 2) (match_dup 3))
3566 (set (match_dup 0) (ashiftrt:DI (match_dup 0) (const_int 62)))])]
3567 {
3568 rtx result = gen_rtx_ASHIFTRT (DImode, operands[0], GEN_INT (62));
3569 operands[2] = SET_DEST (XVECEXP (PATTERN (curr_insn), 0, 0));
3570 operands[3] = gen_rtx_COMPARE (GET_MODE (operands[2]), result, const0_rtx);
3571 })
3572
3573
3574 ;;
3575 ;;- Conversion instructions.
3576 ;;
3577
3578 (define_insn "*sethighpartsi"
3579 [(set (match_operand:SI 0 "register_operand" "=d,d")
3580 (unspec:SI [(match_operand:BLK 1 "s_operand" "Q,S")
3581 (match_operand 2 "const_int_operand" "n,n")] UNSPEC_ICM))
3582 (clobber (reg:CC CC_REGNUM))]
3583 ""
3584 "@
3585 icm\t%0,%2,%S1
3586 icmy\t%0,%2,%S1"
3587 [(set_attr "op_type" "RS,RSY")
3588 (set_attr "z10prop" "z10_super_E1,z10_super_E1")])
3589
3590 (define_insn "*sethighpartdi_64"
3591 [(set (match_operand:DI 0 "register_operand" "=d")
3592 (unspec:DI [(match_operand:BLK 1 "s_operand" "QS")
3593 (match_operand 2 "const_int_operand" "n")] UNSPEC_ICM))
3594 (clobber (reg:CC CC_REGNUM))]
3595 "TARGET_ZARCH"
3596 "icmh\t%0,%2,%S1"
3597 [(set_attr "op_type" "RSY")
3598 (set_attr "z10prop" "z10_super")])
3599
3600 (define_insn "*sethighpartdi_31"
3601 [(set (match_operand:DI 0 "register_operand" "=d,d")
3602 (unspec:DI [(match_operand:BLK 1 "s_operand" "Q,S")
3603 (match_operand 2 "const_int_operand" "n,n")] UNSPEC_ICM))
3604 (clobber (reg:CC CC_REGNUM))]
3605 "!TARGET_ZARCH"
3606 "@
3607 icm\t%0,%2,%S1
3608 icmy\t%0,%2,%S1"
3609 [(set_attr "op_type" "RS,RSY")
3610 (set_attr "z10prop" "z10_super_E1,z10_super_E1")])
3611
3612 ;
3613 ; extv instruction patterns
3614 ;
3615
3616 ; FIXME: This expander needs to be converted from DI to GPR as well
3617 ; after resolving some issues with it.
3618
3619 (define_expand "extzv"
3620 [(parallel
3621 [(set (match_operand:DI 0 "register_operand" "=d")
3622 (zero_extract:DI
3623 (match_operand:DI 1 "register_operand" "d")
3624 (match_operand 2 "const_int_operand" "") ; size
3625 (match_operand 3 "const_int_operand" ""))) ; start
3626 (clobber (reg:CC CC_REGNUM))])]
3627 "TARGET_Z10"
3628 {
3629 /* Starting with zEC12 there is risbgn not clobbering CC. */
3630 if (TARGET_ZEC12)
3631 {
3632 emit_move_insn (operands[0],
3633 gen_rtx_ZERO_EXTRACT (DImode,
3634 operands[1],
3635 operands[2],
3636 operands[3]));
3637 DONE;
3638 }
3639 })
3640
3641 (define_insn "*extzv<mode>_zEC12"
3642 [(set (match_operand:GPR 0 "register_operand" "=d")
3643 (zero_extract:GPR
3644 (match_operand:GPR 1 "register_operand" "d")
3645 (match_operand 2 "const_int_operand" "") ; size
3646 (match_operand 3 "const_int_operand" "")))] ; start]
3647 "TARGET_ZEC12"
3648 "risbgn\t%0,%1,64-%2,128+63,<bitsize>+%3+%2" ; dst, src, start, end, shift
3649 [(set_attr "op_type" "RIE")])
3650
3651 (define_insn "*extzv<mode>_z10"
3652 [(set (match_operand:GPR 0 "register_operand" "=d")
3653 (zero_extract:GPR
3654 (match_operand:GPR 1 "register_operand" "d")
3655 (match_operand 2 "const_int_operand" "") ; size
3656 (match_operand 3 "const_int_operand" ""))) ; start
3657 (clobber (reg:CC CC_REGNUM))]
3658 "TARGET_Z10"
3659 "risbg\t%0,%1,64-%2,128+63,<bitsize>+%3+%2" ; dst, src, start, end, shift
3660 [(set_attr "op_type" "RIE")
3661 (set_attr "z10prop" "z10_super_E1")])
3662
3663 (define_insn_and_split "*pre_z10_extzv<mode>"
3664 [(set (match_operand:GPR 0 "register_operand" "=d")
3665 (zero_extract:GPR (match_operand:QI 1 "s_operand" "QS")
3666 (match_operand 2 "nonzero_shift_count_operand" "")
3667 (const_int 0)))
3668 (clobber (reg:CC CC_REGNUM))]
3669 "!TARGET_Z10"
3670 "#"
3671 "&& reload_completed"
3672 [(parallel
3673 [(set (match_dup 0) (unspec:GPR [(match_dup 1) (match_dup 3)] UNSPEC_ICM))
3674 (clobber (reg:CC CC_REGNUM))])
3675 (set (match_dup 0) (lshiftrt:GPR (match_dup 0) (match_dup 2)))]
3676 {
3677 int bitsize = INTVAL (operands[2]);
3678 int size = (bitsize - 1) / BITS_PER_UNIT + 1; /* round up */
3679 int mask = ((1ul << size) - 1) << (GET_MODE_SIZE (SImode) - size);
3680
3681 operands[1] = adjust_address (operands[1], BLKmode, 0);
3682 set_mem_size (operands[1], size);
3683 operands[2] = GEN_INT (<GPR:bitsize> - bitsize);
3684 operands[3] = GEN_INT (mask);
3685 })
3686
3687 (define_insn_and_split "*pre_z10_extv<mode>"
3688 [(set (match_operand:GPR 0 "register_operand" "=d")
3689 (sign_extract:GPR (match_operand:QI 1 "s_operand" "QS")
3690 (match_operand 2 "nonzero_shift_count_operand" "")
3691 (const_int 0)))
3692 (clobber (reg:CC CC_REGNUM))]
3693 ""
3694 "#"
3695 "&& reload_completed"
3696 [(parallel
3697 [(set (match_dup 0) (unspec:GPR [(match_dup 1) (match_dup 3)] UNSPEC_ICM))
3698 (clobber (reg:CC CC_REGNUM))])
3699 (parallel
3700 [(set (match_dup 0) (ashiftrt:GPR (match_dup 0) (match_dup 2)))
3701 (clobber (reg:CC CC_REGNUM))])]
3702 {
3703 int bitsize = INTVAL (operands[2]);
3704 int size = (bitsize - 1) / BITS_PER_UNIT + 1; /* round up */
3705 int mask = ((1ul << size) - 1) << (GET_MODE_SIZE (SImode) - size);
3706
3707 operands[1] = adjust_address (operands[1], BLKmode, 0);
3708 set_mem_size (operands[1], size);
3709 operands[2] = GEN_INT (<GPR:bitsize> - bitsize);
3710 operands[3] = GEN_INT (mask);
3711 })
3712
3713 ;
3714 ; insv instruction patterns
3715 ;
3716
3717 (define_expand "insv"
3718 [(set (zero_extract (match_operand 0 "nonimmediate_operand" "")
3719 (match_operand 1 "const_int_operand" "")
3720 (match_operand 2 "const_int_operand" ""))
3721 (match_operand 3 "general_operand" ""))]
3722 ""
3723 {
3724 if (s390_expand_insv (operands[0], operands[1], operands[2], operands[3]))
3725 DONE;
3726 FAIL;
3727 })
3728
3729
3730 ; The normal RTL expansion will never generate a zero_extract where
3731 ; the location operand isn't word mode. However, we do this in the
3732 ; back-end when generating atomic operations. See s390_two_part_insv.
3733 (define_insn "*insv<mode>_zEC12"
3734 [(set (zero_extract:GPR (match_operand:GPR 0 "nonimmediate_operand" "+d")
3735 (match_operand 1 "const_int_operand" "I") ; size
3736 (match_operand 2 "const_int_operand" "I")) ; pos
3737 (match_operand:GPR 3 "nonimmediate_operand" "d"))]
3738 "TARGET_ZEC12
3739 && (INTVAL (operands[1]) + INTVAL (operands[2])) <= <bitsize>"
3740 "risbgn\t%0,%3,64-<bitsize>+%2,64-<bitsize>+%2+%1-1,<bitsize>-%2-%1"
3741 [(set_attr "op_type" "RIE")])
3742
3743 (define_insn "*insv<mode>_z10"
3744 [(set (zero_extract:GPR (match_operand:GPR 0 "nonimmediate_operand" "+d")
3745 (match_operand 1 "const_int_operand" "I") ; size
3746 (match_operand 2 "const_int_operand" "I")) ; pos
3747 (match_operand:GPR 3 "nonimmediate_operand" "d"))
3748 (clobber (reg:CC CC_REGNUM))]
3749 "TARGET_Z10
3750 && (INTVAL (operands[1]) + INTVAL (operands[2])) <= <bitsize>"
3751 "risbg\t%0,%3,64-<bitsize>+%2,64-<bitsize>+%2+%1-1,<bitsize>-%2-%1"
3752 [(set_attr "op_type" "RIE")
3753 (set_attr "z10prop" "z10_super_E1")])
3754
3755 ; and op1 with a mask being 1 for the selected bits and 0 for the rest
3756 ; and op3=op0 with a mask being 0 for the selected bits and 1 for the rest
3757 (define_insn "*insv<mode>_zEC12_noshift"
3758 [(set (match_operand:GPR 0 "nonimmediate_operand" "=d")
3759 (ior:GPR (and:GPR (match_operand:GPR 1 "nonimmediate_operand" "d")
3760 (match_operand:GPR 2 "contiguous_bitmask_operand" ""))
3761 (and:GPR (match_operand:GPR 3 "nonimmediate_operand" "0")
3762 (match_operand:GPR 4 "const_int_operand" ""))))]
3763 "TARGET_ZEC12 && INTVAL (operands[2]) == ~INTVAL (operands[4])"
3764 "risbgn\t%0,%1,%<bfstart>2,%<bfend>2,0"
3765 [(set_attr "op_type" "RIE")])
3766
3767 (define_insn "*insv<mode>_z10_noshift"
3768 [(set (match_operand:GPR 0 "nonimmediate_operand" "=d")
3769 (ior:GPR (and:GPR (match_operand:GPR 1 "nonimmediate_operand" "d")
3770 (match_operand:GPR 2 "contiguous_bitmask_operand" ""))
3771 (and:GPR (match_operand:GPR 3 "nonimmediate_operand" "0")
3772 (match_operand:GPR 4 "const_int_operand" ""))))
3773 (clobber (reg:CC CC_REGNUM))]
3774 "TARGET_Z10 && INTVAL (operands[2]) == ~INTVAL (operands[4])"
3775 "risbg\t%0,%1,%<bfstart>2,%<bfend>2,0"
3776 [(set_attr "op_type" "RIE")
3777 (set_attr "z10prop" "z10_super_E1")])
3778
3779 ; Implement appending Y on the left of S bits of X
3780 ; x = (y << s) | (x & ((1 << s) - 1))
3781 (define_insn "*insv<mode>_zEC12_appendbitsleft"
3782 [(set (match_operand:GPR 0 "nonimmediate_operand" "=d")
3783 (ior:GPR (and:GPR (match_operand:GPR 1 "nonimmediate_operand" "0")
3784 (match_operand:GPR 2 "immediate_operand" ""))
3785 (ashift:GPR (match_operand:GPR 3 "nonimmediate_operand" "d")
3786 (match_operand:GPR 4 "nonzero_shift_count_operand" ""))))]
3787 "TARGET_ZEC12 && UINTVAL (operands[2]) == (1UL << UINTVAL (operands[4])) - 1"
3788 "risbgn\t%0,%3,64-<bitsize>,64-%4-1,%4"
3789 [(set_attr "op_type" "RIE")
3790 (set_attr "z10prop" "z10_super_E1")])
3791
3792 (define_insn "*insv<mode>_z10_appendbitsleft"
3793 [(set (match_operand:GPR 0 "nonimmediate_operand" "=d")
3794 (ior:GPR (and:GPR (match_operand:GPR 1 "nonimmediate_operand" "0")
3795 (match_operand:GPR 2 "immediate_operand" ""))
3796 (ashift:GPR (match_operand:GPR 3 "nonimmediate_operand" "d")
3797 (match_operand:GPR 4 "nonzero_shift_count_operand" ""))))
3798 (clobber (reg:CC CC_REGNUM))]
3799 "TARGET_Z10 && !TARGET_ZEC12 && UINTVAL (operands[2]) == (1UL << UINTVAL (operands[4])) - 1"
3800 "risbg\t%0,%3,64-<bitsize>,64-%4-1,%4"
3801 [(set_attr "op_type" "RIE")
3802 (set_attr "z10prop" "z10_super_E1")])
3803
3804 ; z = (x << c) | (y >> d) with (x << c) and (y >> d) not overlapping after shifting
3805 ; -> z = y >> d; z = (x << c) | (z & ((1 << c) - 1))
3806 ; -> z = y >> d; z = risbg;
3807
3808 (define_split
3809 [(set (match_operand:GPR 0 "nonimmediate_operand" "")
3810 (ior:GPR (lshiftrt:GPR (match_operand:GPR 1 "nonimmediate_operand" "")
3811 (match_operand:GPR 2 "nonzero_shift_count_operand" ""))
3812 (ashift:GPR (match_operand:GPR 3 "nonimmediate_operand" "")
3813 (match_operand:GPR 4 "nonzero_shift_count_operand" ""))))]
3814 "TARGET_ZEC12 && UINTVAL (operands[2]) + UINTVAL (operands[4]) >= <bitsize>"
3815 [(set (match_dup 0)
3816 (lshiftrt:GPR (match_dup 1) (match_dup 2)))
3817 (set (match_dup 0)
3818 (ior:GPR (and:GPR (match_dup 0) (match_dup 5))
3819 (ashift:GPR (match_dup 3) (match_dup 4))))]
3820 {
3821 operands[5] = GEN_INT ((1UL << UINTVAL (operands[4])) - 1);
3822 })
3823
3824 (define_split
3825 [(parallel
3826 [(set (match_operand:GPR 0 "nonimmediate_operand" "")
3827 (ior:GPR (lshiftrt:GPR (match_operand:GPR 1 "nonimmediate_operand" "")
3828 (match_operand:GPR 2 "nonzero_shift_count_operand" ""))
3829 (ashift:GPR (match_operand:GPR 3 "nonimmediate_operand" "")
3830 (match_operand:GPR 4 "nonzero_shift_count_operand" ""))))
3831 (clobber (reg:CC CC_REGNUM))])]
3832 "TARGET_Z10 && !TARGET_ZEC12 && UINTVAL (operands[2]) + UINTVAL (operands[4]) >= <bitsize>"
3833 [(set (match_dup 0)
3834 (lshiftrt:GPR (match_dup 1) (match_dup 2)))
3835 (parallel
3836 [(set (match_dup 0)
3837 (ior:GPR (and:GPR (match_dup 0) (match_dup 5))
3838 (ashift:GPR (match_dup 3) (match_dup 4))))
3839 (clobber (reg:CC CC_REGNUM))])]
3840 {
3841 operands[5] = GEN_INT ((1UL << UINTVAL (operands[4])) - 1);
3842 })
3843
3844 (define_insn "*r<noxa>sbg_<mode>_noshift"
3845 [(set (match_operand:GPR 0 "nonimmediate_operand" "=d")
3846 (IXOR:GPR
3847 (and:GPR (match_operand:GPR 1 "nonimmediate_operand" "d")
3848 (match_operand:GPR 2 "contiguous_bitmask_operand" ""))
3849 (match_operand:GPR 3 "nonimmediate_operand" "0")))
3850 (clobber (reg:CC CC_REGNUM))]
3851 "TARGET_Z10"
3852 "r<noxa>sbg\t%0,%1,%<bfstart>2,%<bfend>2,0"
3853 [(set_attr "op_type" "RIE")])
3854
3855 (define_insn "*r<noxa>sbg_di_rotl"
3856 [(set (match_operand:DI 0 "nonimmediate_operand" "=d")
3857 (IXOR:DI
3858 (and:DI
3859 (rotate:DI
3860 (match_operand:DI 1 "nonimmediate_operand" "d")
3861 (match_operand:DI 3 "const_int_operand" ""))
3862 (match_operand:DI 2 "contiguous_bitmask_operand" ""))
3863 (match_operand:DI 4 "nonimmediate_operand" "0")))
3864 (clobber (reg:CC CC_REGNUM))]
3865 "TARGET_Z10"
3866 "r<noxa>sbg\t%0,%1,%<bfstart>2,%<bfend>2,%b3"
3867 [(set_attr "op_type" "RIE")])
3868
3869 (define_insn "*r<noxa>sbg_<mode>_srl"
3870 [(set (match_operand:GPR 0 "nonimmediate_operand" "=d")
3871 (IXOR:GPR
3872 (and:GPR
3873 (lshiftrt:GPR
3874 (match_operand:GPR 1 "nonimmediate_operand" "d")
3875 (match_operand:GPR 3 "nonzero_shift_count_operand" ""))
3876 (match_operand:GPR 2 "contiguous_bitmask_operand" ""))
3877 (match_operand:GPR 4 "nonimmediate_operand" "0")))
3878 (clobber (reg:CC CC_REGNUM))]
3879 "TARGET_Z10
3880 && s390_extzv_shift_ok (<bitsize>, 64 - INTVAL (operands[3]),
3881 INTVAL (operands[2]))"
3882 "r<noxa>sbg\t%0,%1,%<bfstart>2,%<bfend>2,64-%3"
3883 [(set_attr "op_type" "RIE")])
3884
3885 (define_insn "*r<noxa>sbg_<mode>_sll"
3886 [(set (match_operand:GPR 0 "nonimmediate_operand" "=d")
3887 (IXOR:GPR
3888 (and:GPR
3889 (ashift:GPR
3890 (match_operand:GPR 1 "nonimmediate_operand" "d")
3891 (match_operand:GPR 3 "nonzero_shift_count_operand" ""))
3892 (match_operand:GPR 2 "contiguous_bitmask_operand" ""))
3893 (match_operand:GPR 4 "nonimmediate_operand" "0")))
3894 (clobber (reg:CC CC_REGNUM))]
3895 "TARGET_Z10
3896 && s390_extzv_shift_ok (<bitsize>, INTVAL (operands[3]),
3897 INTVAL (operands[2]))"
3898 "r<noxa>sbg\t%0,%1,%<bfstart>2,%<bfend>2,%3"
3899 [(set_attr "op_type" "RIE")])
3900
3901 ;; These two are generated by combine for s.bf &= val.
3902 ;; ??? For bitfields smaller than 32-bits, we wind up with SImode
3903 ;; shifts and ands, which results in some truly awful patterns
3904 ;; including subregs of operations. Rather unnecessisarily, IMO.
3905 ;; Instead of
3906 ;;
3907 ;; (set (zero_extract:DI (reg/v:DI 50 [ s ])
3908 ;; (const_int 24 [0x18])
3909 ;; (const_int 0 [0]))
3910 ;; (subreg:DI (and:SI (subreg:SI (lshiftrt:DI (reg/v:DI 50 [ s ])
3911 ;; (const_int 40 [0x28])) 4)
3912 ;; (reg:SI 4 %r4 [ y+4 ])) 0))
3913 ;;
3914 ;; we should instead generate
3915 ;;
3916 ;; (set (zero_extract:DI (reg/v:DI 50 [ s ])
3917 ;; (const_int 24 [0x18])
3918 ;; (const_int 0 [0]))
3919 ;; (and:DI (lshiftrt:DI (reg/v:DI 50 [ s ])
3920 ;; (const_int 40 [0x28]))
3921 ;; (subreg:DI (reg:SI 4 %r4 [ y+4 ]) 0)))
3922 ;;
3923 ;; by noticing that we can push down the outer paradoxical subreg
3924 ;; into the operation.
3925
3926 (define_insn "*insv_rnsbg_noshift"
3927 [(set (zero_extract:DI
3928 (match_operand:DI 0 "nonimmediate_operand" "+d")
3929 (match_operand 1 "const_int_operand" "")
3930 (match_operand 2 "const_int_operand" ""))
3931 (and:DI
3932 (match_dup 0)
3933 (match_operand:DI 3 "nonimmediate_operand" "d")))
3934 (clobber (reg:CC CC_REGNUM))]
3935 "TARGET_Z10
3936 && INTVAL (operands[1]) + INTVAL (operands[2]) == 64"
3937 "rnsbg\t%0,%3,%2,63,0"
3938 [(set_attr "op_type" "RIE")])
3939
3940 (define_insn "*insv_rnsbg_srl"
3941 [(set (zero_extract:DI
3942 (match_operand:DI 0 "nonimmediate_operand" "+d")
3943 (match_operand 1 "const_int_operand" "")
3944 (match_operand 2 "const_int_operand" ""))
3945 (and:DI
3946 (lshiftrt:DI
3947 (match_dup 0)
3948 (match_operand 3 "const_int_operand" ""))
3949 (match_operand:DI 4 "nonimmediate_operand" "d")))
3950 (clobber (reg:CC CC_REGNUM))]
3951 "TARGET_Z10
3952 && INTVAL (operands[3]) == 64 - INTVAL (operands[1]) - INTVAL (operands[2])"
3953 "rnsbg\t%0,%4,%2,%2+%1-1,%3"
3954 [(set_attr "op_type" "RIE")])
3955
3956 (define_insn "*insv<mode>_mem_reg"
3957 [(set (zero_extract:W (match_operand:QI 0 "memory_operand" "+Q,S")
3958 (match_operand 1 "const_int_operand" "n,n")
3959 (const_int 0))
3960 (match_operand:W 2 "register_operand" "d,d"))]
3961 "INTVAL (operands[1]) > 0
3962 && INTVAL (operands[1]) <= GET_MODE_BITSIZE (SImode)
3963 && INTVAL (operands[1]) % BITS_PER_UNIT == 0"
3964 {
3965 int size = INTVAL (operands[1]) / BITS_PER_UNIT;
3966
3967 operands[1] = GEN_INT ((1ul << size) - 1);
3968 return (which_alternative == 0) ? "stcm\t%2,%1,%S0"
3969 : "stcmy\t%2,%1,%S0";
3970 }
3971 [(set_attr "op_type" "RS,RSY")
3972 (set_attr "z10prop" "z10_super,z10_super")])
3973
3974 (define_insn "*insvdi_mem_reghigh"
3975 [(set (zero_extract:DI (match_operand:QI 0 "memory_operand" "+QS")
3976 (match_operand 1 "const_int_operand" "n")
3977 (const_int 0))
3978 (lshiftrt:DI (match_operand:DI 2 "register_operand" "d")
3979 (const_int 32)))]
3980 "TARGET_ZARCH
3981 && INTVAL (operands[1]) > 0
3982 && INTVAL (operands[1]) <= GET_MODE_BITSIZE (SImode)
3983 && INTVAL (operands[1]) % BITS_PER_UNIT == 0"
3984 {
3985 int size = INTVAL (operands[1]) / BITS_PER_UNIT;
3986
3987 operands[1] = GEN_INT ((1ul << size) - 1);
3988 return "stcmh\t%2,%1,%S0";
3989 }
3990 [(set_attr "op_type" "RSY")
3991 (set_attr "z10prop" "z10_super")])
3992
3993 (define_insn "*insvdi_reg_imm"
3994 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+d")
3995 (const_int 16)
3996 (match_operand 1 "const_int_operand" "n"))
3997 (match_operand:DI 2 "const_int_operand" "n"))]
3998 "TARGET_ZARCH
3999 && INTVAL (operands[1]) >= 0
4000 && INTVAL (operands[1]) < BITS_PER_WORD
4001 && INTVAL (operands[1]) % 16 == 0"
4002 {
4003 switch (BITS_PER_WORD - INTVAL (operands[1]))
4004 {
4005 case 64: return "iihh\t%0,%x2"; break;
4006 case 48: return "iihl\t%0,%x2"; break;
4007 case 32: return "iilh\t%0,%x2"; break;
4008 case 16: return "iill\t%0,%x2"; break;
4009 default: gcc_unreachable();
4010 }
4011 }
4012 [(set_attr "op_type" "RI")
4013 (set_attr "z10prop" "z10_super_E1")])
4014
4015 ; Update the left-most 32 bit of a DI.
4016 (define_insn "*insv_h_di_reg_extimm"
4017 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+d")
4018 (const_int 32)
4019 (const_int 0))
4020 (match_operand:DI 1 "const_int_operand" "n"))]
4021 "TARGET_EXTIMM"
4022 "iihf\t%0,%o1"
4023 [(set_attr "op_type" "RIL")
4024 (set_attr "z10prop" "z10_fwd_E1")])
4025
4026 ; Update the right-most 32 bit of a DI.
4027 (define_insn "*insv_l_di_reg_extimm"
4028 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+d")
4029 (const_int 32)
4030 (const_int 32))
4031 (match_operand:DI 1 "const_int_operand" "n"))]
4032 "TARGET_EXTIMM"
4033 "iilf\t%0,%o1"
4034 [(set_attr "op_type" "RIL")
4035 (set_attr "z10prop" "z10_fwd_A1")])
4036
4037 ;
4038 ; extendsidi2 instruction pattern(s).
4039 ;
4040
4041 (define_expand "extendsidi2"
4042 [(set (match_operand:DI 0 "register_operand" "")
4043 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "")))]
4044 ""
4045 {
4046 if (!TARGET_ZARCH)
4047 {
4048 emit_clobber (operands[0]);
4049 emit_move_insn (gen_highpart (SImode, operands[0]), operands[1]);
4050 emit_move_insn (gen_lowpart (SImode, operands[0]), const0_rtx);
4051 emit_insn (gen_ashrdi3 (operands[0], operands[0], GEN_INT (32)));
4052 DONE;
4053 }
4054 })
4055
4056 (define_insn "*extendsidi2"
4057 [(set (match_operand:DI 0 "register_operand" "=d,d,d")
4058 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "d,RT,b")))]
4059 "TARGET_ZARCH"
4060 "@
4061 lgfr\t%0,%1
4062 lgf\t%0,%1
4063 lgfrl\t%0,%1"
4064 [(set_attr "op_type" "RRE,RXY,RIL")
4065 (set_attr "type" "*,*,larl")
4066 (set_attr "cpu_facility" "*,*,z10")
4067 (set_attr "z10prop" "z10_super_E1,z10_super_E1,z10_super_E1")])
4068
4069 ;
4070 ; extend(hi|qi)(si|di)2 instruction pattern(s).
4071 ;
4072
4073 (define_expand "extend<HQI:mode><DSI:mode>2"
4074 [(set (match_operand:DSI 0 "register_operand" "")
4075 (sign_extend:DSI (match_operand:HQI 1 "nonimmediate_operand" "")))]
4076 ""
4077 {
4078 if (<DSI:MODE>mode == DImode && !TARGET_ZARCH)
4079 {
4080 rtx tmp = gen_reg_rtx (SImode);
4081 emit_insn (gen_extend<HQI:mode>si2 (tmp, operands[1]));
4082 emit_insn (gen_extendsidi2 (operands[0], tmp));
4083 DONE;
4084 }
4085 else if (!TARGET_EXTIMM)
4086 {
4087 rtx bitcount = GEN_INT (<DSI:bitsize> - <HQI:bitsize>);
4088
4089 operands[1] = gen_lowpart (<DSI:MODE>mode, operands[1]);
4090 emit_insn (gen_ashl<DSI:mode>3 (operands[0], operands[1], bitcount));
4091 emit_insn (gen_ashr<DSI:mode>3 (operands[0], operands[0], bitcount));
4092 DONE;
4093 }
4094 })
4095
4096 ;
4097 ; extendhidi2 instruction pattern(s).
4098 ;
4099
4100 (define_insn "*extendhidi2_extimm"
4101 [(set (match_operand:DI 0 "register_operand" "=d,d,d")
4102 (sign_extend:DI (match_operand:HI 1 "general_operand" "d,RT,b")))]
4103 "TARGET_ZARCH && TARGET_EXTIMM"
4104 "@
4105 lghr\t%0,%1
4106 lgh\t%0,%1
4107 lghrl\t%0,%1"
4108 [(set_attr "op_type" "RRE,RXY,RIL")
4109 (set_attr "type" "*,*,larl")
4110 (set_attr "cpu_facility" "extimm,extimm,z10")
4111 (set_attr "z10prop" "z10_super_E1,z10_super_E1,z10_super_E1")])
4112
4113 (define_insn "*extendhidi2"
4114 [(set (match_operand:DI 0 "register_operand" "=d")
4115 (sign_extend:DI (match_operand:HI 1 "memory_operand" "RT")))]
4116 "TARGET_ZARCH"
4117 "lgh\t%0,%1"
4118 [(set_attr "op_type" "RXY")
4119 (set_attr "z10prop" "z10_super_E1")])
4120
4121 ;
4122 ; extendhisi2 instruction pattern(s).
4123 ;
4124
4125 (define_insn "*extendhisi2_extimm"
4126 [(set (match_operand:SI 0 "register_operand" "=d,d,d,d")
4127 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" " d,R,T,b")))]
4128 "TARGET_EXTIMM"
4129 "@
4130 lhr\t%0,%1
4131 lh\t%0,%1
4132 lhy\t%0,%1
4133 lhrl\t%0,%1"
4134 [(set_attr "op_type" "RRE,RX,RXY,RIL")
4135 (set_attr "type" "*,*,*,larl")
4136 (set_attr "cpu_facility" "extimm,extimm,extimm,z10")
4137 (set_attr "z10prop" "z10_super_E1,z10_super_E1,z10_super_E1,z10_super_E1")])
4138
4139 (define_insn "*extendhisi2"
4140 [(set (match_operand:SI 0 "register_operand" "=d,d")
4141 (sign_extend:SI (match_operand:HI 1 "memory_operand" "R,T")))]
4142 "!TARGET_EXTIMM"
4143 "@
4144 lh\t%0,%1
4145 lhy\t%0,%1"
4146 [(set_attr "op_type" "RX,RXY")
4147 (set_attr "z10prop" "z10_super_E1,z10_super_E1")])
4148
4149 ;
4150 ; extendqi(si|di)2 instruction pattern(s).
4151 ;
4152
4153 ; lbr, lgbr, lb, lgb
4154 (define_insn "*extendqi<mode>2_extimm"
4155 [(set (match_operand:GPR 0 "register_operand" "=d,d")
4156 (sign_extend:GPR (match_operand:QI 1 "nonimmediate_operand" "d,RT")))]
4157 "TARGET_EXTIMM"
4158 "@
4159 l<g>br\t%0,%1
4160 l<g>b\t%0,%1"
4161 [(set_attr "op_type" "RRE,RXY")
4162 (set_attr "z10prop" "z10_super_E1,z10_super_E1")])
4163
4164 ; lb, lgb
4165 (define_insn "*extendqi<mode>2"
4166 [(set (match_operand:GPR 0 "register_operand" "=d")
4167 (sign_extend:GPR (match_operand:QI 1 "memory_operand" "RT")))]
4168 "!TARGET_EXTIMM && TARGET_LONG_DISPLACEMENT"
4169 "l<g>b\t%0,%1"
4170 [(set_attr "op_type" "RXY")
4171 (set_attr "z10prop" "z10_super_E1")])
4172
4173 (define_insn_and_split "*extendqi<mode>2_short_displ"
4174 [(set (match_operand:GPR 0 "register_operand" "=d")
4175 (sign_extend:GPR (match_operand:QI 1 "s_operand" "Q")))
4176 (clobber (reg:CC CC_REGNUM))]
4177 "!TARGET_EXTIMM && !TARGET_LONG_DISPLACEMENT"
4178 "#"
4179 "&& reload_completed"
4180 [(parallel
4181 [(set (match_dup 0) (unspec:GPR [(match_dup 1) (const_int 8)] UNSPEC_ICM))
4182 (clobber (reg:CC CC_REGNUM))])
4183 (parallel
4184 [(set (match_dup 0) (ashiftrt:GPR (match_dup 0) (match_dup 2)))
4185 (clobber (reg:CC CC_REGNUM))])]
4186 {
4187 operands[1] = adjust_address (operands[1], BLKmode, 0);
4188 set_mem_size (operands[1], GET_MODE_SIZE (QImode));
4189 operands[2] = GEN_INT (<GPR:bitsize> - BITS_PER_UNIT);
4190 })
4191
4192 ;
4193 ; zero_extendsidi2 instruction pattern(s).
4194 ;
4195
4196 (define_expand "zero_extendsidi2"
4197 [(set (match_operand:DI 0 "register_operand" "")
4198 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "")))]
4199 ""
4200 {
4201 if (!TARGET_ZARCH)
4202 {
4203 emit_clobber (operands[0]);
4204 emit_move_insn (gen_lowpart (SImode, operands[0]), operands[1]);
4205 emit_move_insn (gen_highpart (SImode, operands[0]), const0_rtx);
4206 DONE;
4207 }
4208 })
4209
4210 (define_insn "*zero_extendsidi2"
4211 [(set (match_operand:DI 0 "register_operand" "=d,d,d")
4212 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "d,RT,b")))]
4213 "TARGET_ZARCH"
4214 "@
4215 llgfr\t%0,%1
4216 llgf\t%0,%1
4217 llgfrl\t%0,%1"
4218 [(set_attr "op_type" "RRE,RXY,RIL")
4219 (set_attr "type" "*,*,larl")
4220 (set_attr "cpu_facility" "*,*,z10")
4221 (set_attr "z10prop" "z10_fwd_E1,z10_fwd_A3,z10_fwd_A3")])
4222
4223 ;
4224 ; LLGT-type instructions (zero-extend from 31 bit to 64 bit).
4225 ;
4226
4227 (define_insn "*llgt_sidi"
4228 [(set (match_operand:DI 0 "register_operand" "=d")
4229 (and:DI (subreg:DI (match_operand:SI 1 "memory_operand" "RT") 0)
4230 (const_int 2147483647)))]
4231 "TARGET_ZARCH"
4232 "llgt\t%0,%1"
4233 [(set_attr "op_type" "RXE")
4234 (set_attr "z10prop" "z10_super_E1")])
4235
4236 (define_insn_and_split "*llgt_sidi_split"
4237 [(set (match_operand:DI 0 "register_operand" "=d")
4238 (and:DI (subreg:DI (match_operand:SI 1 "memory_operand" "RT") 0)
4239 (const_int 2147483647)))
4240 (clobber (reg:CC CC_REGNUM))]
4241 "TARGET_ZARCH"
4242 "#"
4243 "&& reload_completed"
4244 [(set (match_dup 0)
4245 (and:DI (subreg:DI (match_dup 1) 0)
4246 (const_int 2147483647)))]
4247 "")
4248
4249 (define_insn "*llgt_sisi"
4250 [(set (match_operand:SI 0 "register_operand" "=d,d")
4251 (and:SI (match_operand:SI 1 "nonimmediate_operand" "d,RT")
4252 (const_int 2147483647)))]
4253 "TARGET_ZARCH"
4254 "@
4255 llgtr\t%0,%1
4256 llgt\t%0,%1"
4257 [(set_attr "op_type" "RRE,RXE")
4258 (set_attr "z10prop" "z10_super_E1,z10_super_E1")])
4259
4260 (define_insn "*llgt_didi"
4261 [(set (match_operand:DI 0 "register_operand" "=d,d")
4262 (and:DI (match_operand:DI 1 "nonimmediate_operand" "d,o")
4263 (const_int 2147483647)))]
4264 "TARGET_ZARCH"
4265 "@
4266 llgtr\t%0,%1
4267 llgt\t%0,%N1"
4268 [(set_attr "op_type" "RRE,RXE")
4269 (set_attr "z10prop" "z10_super_E1,z10_super_E1")])
4270
4271 (define_split
4272 [(set (match_operand:DSI 0 "register_operand" "")
4273 (and:DSI (match_operand:DSI 1 "nonimmediate_operand" "")
4274 (const_int 2147483647)))
4275 (clobber (reg:CC CC_REGNUM))]
4276 "TARGET_ZARCH && reload_completed"
4277 [(set (match_dup 0)
4278 (and:DSI (match_dup 1)
4279 (const_int 2147483647)))]
4280 "")
4281
4282 ;
4283 ; zero_extend(hi|qi)(si|di)2 instruction pattern(s).
4284 ;
4285
4286 (define_expand "zero_extend<mode>di2"
4287 [(set (match_operand:DI 0 "register_operand" "")
4288 (zero_extend:DI (match_operand:HQI 1 "nonimmediate_operand" "")))]
4289 ""
4290 {
4291 if (!TARGET_ZARCH)
4292 {
4293 rtx tmp = gen_reg_rtx (SImode);
4294 emit_insn (gen_zero_extend<mode>si2 (tmp, operands[1]));
4295 emit_insn (gen_zero_extendsidi2 (operands[0], tmp));
4296 DONE;
4297 }
4298 else if (!TARGET_EXTIMM)
4299 {
4300 rtx bitcount = GEN_INT (64 - <HQI:bitsize>);
4301 operands[1] = gen_lowpart (DImode, operands[1]);
4302 emit_insn (gen_ashldi3 (operands[0], operands[1], bitcount));
4303 emit_insn (gen_lshrdi3 (operands[0], operands[0], bitcount));
4304 DONE;
4305 }
4306 })
4307
4308 (define_expand "zero_extend<mode>si2"
4309 [(set (match_operand:SI 0 "register_operand" "")
4310 (zero_extend:SI (match_operand:HQI 1 "nonimmediate_operand" "")))]
4311 ""
4312 {
4313 if (!TARGET_EXTIMM)
4314 {
4315 operands[1] = gen_lowpart (SImode, operands[1]);
4316 emit_insn (gen_andsi3 (operands[0], operands[1],
4317 GEN_INT ((1 << <HQI:bitsize>) - 1)));
4318 DONE;
4319 }
4320 })
4321
4322 ; llhrl, llghrl
4323 (define_insn "*zero_extendhi<mode>2_z10"
4324 [(set (match_operand:GPR 0 "register_operand" "=d,d,d")
4325 (zero_extend:GPR (match_operand:HI 1 "nonimmediate_operand" "d,RT,b")))]
4326 "TARGET_Z10"
4327 "@
4328 ll<g>hr\t%0,%1
4329 ll<g>h\t%0,%1
4330 ll<g>hrl\t%0,%1"
4331 [(set_attr "op_type" "RXY,RRE,RIL")
4332 (set_attr "type" "*,*,larl")
4333 (set_attr "cpu_facility" "*,*,z10")
4334 (set_attr "z10prop" "z10_super_E1,z10_fwd_A3,z10_fwd_A3")])
4335
4336 ; llhr, llcr, llghr, llgcr, llh, llc, llgh, llgc
4337 (define_insn "*zero_extend<HQI:mode><GPR:mode>2_extimm"
4338 [(set (match_operand:GPR 0 "register_operand" "=d,d")
4339 (zero_extend:GPR (match_operand:HQI 1 "nonimmediate_operand" "d,RT")))]
4340 "TARGET_EXTIMM"
4341 "@
4342 ll<g><hc>r\t%0,%1
4343 ll<g><hc>\t%0,%1"
4344 [(set_attr "op_type" "RRE,RXY")
4345 (set_attr "z10prop" "z10_super_E1,z10_fwd_A3")])
4346
4347 ; llgh, llgc
4348 (define_insn "*zero_extend<HQI:mode><GPR:mode>2"
4349 [(set (match_operand:GPR 0 "register_operand" "=d")
4350 (zero_extend:GPR (match_operand:HQI 1 "memory_operand" "RT")))]
4351 "TARGET_ZARCH && !TARGET_EXTIMM"
4352 "llg<hc>\t%0,%1"
4353 [(set_attr "op_type" "RXY")
4354 (set_attr "z10prop" "z10_fwd_A3")])
4355
4356 (define_insn_and_split "*zero_extendhisi2_31"
4357 [(set (match_operand:SI 0 "register_operand" "=&d")
4358 (zero_extend:SI (match_operand:HI 1 "s_operand" "QS")))
4359 (clobber (reg:CC CC_REGNUM))]
4360 "!TARGET_ZARCH"
4361 "#"
4362 "&& reload_completed"
4363 [(set (match_dup 0) (const_int 0))
4364 (parallel
4365 [(set (strict_low_part (match_dup 2)) (match_dup 1))
4366 (clobber (reg:CC CC_REGNUM))])]
4367 "operands[2] = gen_lowpart (HImode, operands[0]);")
4368
4369 (define_insn_and_split "*zero_extendqisi2_31"
4370 [(set (match_operand:SI 0 "register_operand" "=&d")
4371 (zero_extend:SI (match_operand:QI 1 "memory_operand" "RT")))]
4372 "!TARGET_ZARCH"
4373 "#"
4374 "&& reload_completed"
4375 [(set (match_dup 0) (const_int 0))
4376 (set (strict_low_part (match_dup 2)) (match_dup 1))]
4377 "operands[2] = gen_lowpart (QImode, operands[0]);")
4378
4379 ;
4380 ; zero_extendqihi2 instruction pattern(s).
4381 ;
4382
4383 (define_expand "zero_extendqihi2"
4384 [(set (match_operand:HI 0 "register_operand" "")
4385 (zero_extend:HI (match_operand:QI 1 "register_operand" "")))]
4386 "TARGET_ZARCH && !TARGET_EXTIMM"
4387 {
4388 operands[1] = gen_lowpart (HImode, operands[1]);
4389 emit_insn (gen_andhi3 (operands[0], operands[1], GEN_INT (0xff)));
4390 DONE;
4391 })
4392
4393 (define_insn "*zero_extendqihi2_64"
4394 [(set (match_operand:HI 0 "register_operand" "=d")
4395 (zero_extend:HI (match_operand:QI 1 "memory_operand" "RT")))]
4396 "TARGET_ZARCH && !TARGET_EXTIMM"
4397 "llgc\t%0,%1"
4398 [(set_attr "op_type" "RXY")
4399 (set_attr "z10prop" "z10_fwd_A3")])
4400
4401 (define_insn_and_split "*zero_extendqihi2_31"
4402 [(set (match_operand:HI 0 "register_operand" "=&d")
4403 (zero_extend:HI (match_operand:QI 1 "memory_operand" "RT")))]
4404 "!TARGET_ZARCH"
4405 "#"
4406 "&& reload_completed"
4407 [(set (match_dup 0) (const_int 0))
4408 (set (strict_low_part (match_dup 2)) (match_dup 1))]
4409 "operands[2] = gen_lowpart (QImode, operands[0]);")
4410
4411 ;
4412 ; fixuns_trunc(dd|td)di2 instruction pattern(s).
4413 ;
4414
4415 (define_expand "fixuns_truncdddi2"
4416 [(parallel
4417 [(set (match_operand:DI 0 "register_operand" "")
4418 (unsigned_fix:DI (match_operand:DD 1 "register_operand" "")))
4419 (unspec:DI [(const_int 5)] UNSPEC_ROUND)
4420 (clobber (reg:CC CC_REGNUM))])]
4421
4422 "TARGET_HARD_DFP"
4423 {
4424 if (!TARGET_Z196)
4425 {
4426 rtx_code_label *label1 = gen_label_rtx ();
4427 rtx_code_label *label2 = gen_label_rtx ();
4428 rtx temp = gen_reg_rtx (TDmode);
4429 REAL_VALUE_TYPE cmp, sub;
4430
4431 decimal_real_from_string (&cmp, "9223372036854775808.0"); /* 2^63 */
4432 decimal_real_from_string (&sub, "18446744073709551616.0"); /* 2^64 */
4433
4434 /* 2^63 can't be represented as 64bit DFP number with full precision. The
4435 solution is doing the check and the subtraction in TD mode and using a
4436 TD -> DI convert afterwards. */
4437 emit_insn (gen_extendddtd2 (temp, operands[1]));
4438 temp = force_reg (TDmode, temp);
4439 emit_cmp_and_jump_insns (temp,
4440 const_double_from_real_value (cmp, TDmode),
4441 LT, NULL_RTX, VOIDmode, 0, label1);
4442 emit_insn (gen_subtd3 (temp, temp,
4443 const_double_from_real_value (sub, TDmode)));
4444 emit_insn (gen_fix_trunctddi2_dfp (operands[0], temp, GEN_INT (11)));
4445 emit_jump (label2);
4446
4447 emit_label (label1);
4448 emit_insn (gen_fix_truncdddi2_dfp (operands[0], operands[1], GEN_INT (9)));
4449 emit_label (label2);
4450 DONE;
4451 }
4452 })
4453
4454 (define_expand "fixuns_trunctddi2"
4455 [(parallel
4456 [(set (match_operand:DI 0 "register_operand" "")
4457 (unsigned_fix:DI (match_operand:TD 1 "register_operand" "")))
4458 (unspec:DI [(const_int 5)] UNSPEC_ROUND)
4459 (clobber (reg:CC CC_REGNUM))])]
4460
4461 "TARGET_HARD_DFP"
4462 {
4463 if (!TARGET_Z196)
4464 {
4465 rtx_code_label *label1 = gen_label_rtx ();
4466 rtx_code_label *label2 = gen_label_rtx ();
4467 rtx temp = gen_reg_rtx (TDmode);
4468 REAL_VALUE_TYPE cmp, sub;
4469
4470 operands[1] = force_reg (TDmode, operands[1]);
4471 decimal_real_from_string (&cmp, "9223372036854775808.0"); /* 2^63 */
4472 decimal_real_from_string (&sub, "18446744073709551616.0"); /* 2^64 */
4473
4474 emit_cmp_and_jump_insns (operands[1],
4475 const_double_from_real_value (cmp, TDmode),
4476 LT, NULL_RTX, VOIDmode, 0, label1);
4477 emit_insn (gen_subtd3 (temp, operands[1],
4478 const_double_from_real_value (sub, TDmode)));
4479 emit_insn (gen_fix_trunctddi2_dfp (operands[0], temp, GEN_INT (11)));
4480 emit_jump (label2);
4481
4482 emit_label (label1);
4483 emit_insn (gen_fix_trunctddi2_dfp (operands[0], operands[1], GEN_INT (9)));
4484 emit_label (label2);
4485 DONE;
4486 }
4487 })
4488
4489 ;
4490 ; fixuns_trunc(sf|df|tf)(si|di)2 and fix_trunc(sf|df|tf)(si|di)2
4491 ; instruction pattern(s).
4492 ;
4493
4494 (define_expand "fixuns_trunc<BFP:mode><GPR:mode>2"
4495 [(parallel
4496 [(set (match_operand:GPR 0 "register_operand" "")
4497 (unsigned_fix:GPR (match_operand:BFP 1 "register_operand" "")))
4498 (unspec:GPR [(const_int 5)] UNSPEC_ROUND)
4499 (clobber (reg:CC CC_REGNUM))])]
4500 "TARGET_HARD_FLOAT"
4501 {
4502 if (!TARGET_Z196)
4503 {
4504 rtx_code_label *label1 = gen_label_rtx ();
4505 rtx_code_label *label2 = gen_label_rtx ();
4506 rtx temp = gen_reg_rtx (<BFP:MODE>mode);
4507 REAL_VALUE_TYPE cmp, sub;
4508
4509 operands[1] = force_reg (<BFP:MODE>mode, operands[1]);
4510 real_2expN (&cmp, <GPR:bitsize> - 1, <BFP:MODE>mode);
4511 real_2expN (&sub, <GPR:bitsize>, <BFP:MODE>mode);
4512
4513 emit_cmp_and_jump_insns (operands[1],
4514 const_double_from_real_value (cmp, <BFP:MODE>mode),
4515 LT, NULL_RTX, VOIDmode, 0, label1);
4516 emit_insn (gen_sub<BFP:mode>3 (temp, operands[1],
4517 const_double_from_real_value (sub, <BFP:MODE>mode)));
4518 emit_insn (gen_fix_trunc<BFP:mode><GPR:mode>2_bfp (operands[0], temp,
4519 GEN_INT (7)));
4520 emit_jump (label2);
4521
4522 emit_label (label1);
4523 emit_insn (gen_fix_trunc<BFP:mode><GPR:mode>2_bfp (operands[0],
4524 operands[1], GEN_INT (5)));
4525 emit_label (label2);
4526 DONE;
4527 }
4528 })
4529
4530 ; fixuns_trunc(td|dd)si2 expander
4531 (define_expand "fixuns_trunc<mode>si2"
4532 [(parallel
4533 [(set (match_operand:SI 0 "register_operand" "")
4534 (unsigned_fix:SI (match_operand:DFP 1 "register_operand" "")))
4535 (unspec:SI [(const_int 5)] UNSPEC_ROUND)
4536 (clobber (reg:CC CC_REGNUM))])]
4537 "TARGET_Z196 && TARGET_HARD_DFP"
4538 "")
4539
4540 ; fixuns_trunc(tf|df|sf|td|dd)(di|si)2 instruction patterns.
4541
4542 (define_insn "*fixuns_truncdfdi2_z13"
4543 [(set (match_operand:DI 0 "register_operand" "=d,v")
4544 (unsigned_fix:DI (match_operand:DF 1 "register_operand" "f,v")))
4545 (unspec:DI [(match_operand:DI 2 "immediate_operand" "K,K")] UNSPEC_ROUND)
4546 (clobber (reg:CC CC_REGNUM))]
4547 "TARGET_Z13 && TARGET_HARD_FLOAT"
4548 "@
4549 clgdbr\t%0,%h2,%1,0
4550 wclgdb\t%v0,%v1,0,%h2"
4551 [(set_attr "op_type" "RRF,VRR")
4552 (set_attr "type" "ftoi")])
4553
4554 ; clfebr, clfdbr, clfxbr, clgebr, clgdbr, clgxbr
4555 ; clfdtr, clfxtr, clgdtr, clgxtr
4556 (define_insn "*fixuns_trunc<FP:mode><GPR:mode>2_z196"
4557 [(set (match_operand:GPR 0 "register_operand" "=d")
4558 (unsigned_fix:GPR (match_operand:FP 1 "register_operand" "f")))
4559 (unspec:GPR [(match_operand:GPR 2 "immediate_operand" "K")] UNSPEC_ROUND)
4560 (clobber (reg:CC CC_REGNUM))]
4561 "TARGET_Z196 && TARGET_HARD_FLOAT
4562 && (!TARGET_Z13 || <GPR:MODE>mode != DImode || <FP:MODE>mode != DFmode)"
4563 "cl<GPR:gf><FP:xde><FP:bt>r\t%0,%h2,%1,0"
4564 [(set_attr "op_type" "RRF")
4565 (set_attr "type" "ftoi")])
4566
4567 (define_expand "fix_trunc<DSF:mode><GPR:mode>2"
4568 [(set (match_operand:GPR 0 "register_operand" "")
4569 (fix:GPR (match_operand:DSF 1 "register_operand" "")))]
4570 "TARGET_HARD_FLOAT"
4571 {
4572 emit_insn (gen_fix_trunc<DSF:mode><GPR:mode>2_bfp (operands[0], operands[1],
4573 GEN_INT (5)));
4574 DONE;
4575 })
4576
4577 (define_insn "*fix_truncdfdi2_bfp_z13"
4578 [(set (match_operand:DI 0 "register_operand" "=d,v")
4579 (fix:DI (match_operand:DF 1 "register_operand" "f,v")))
4580 (unspec:DI [(match_operand:DI 2 "immediate_operand" "K,K")] UNSPEC_ROUND)
4581 (clobber (reg:CC CC_REGNUM))]
4582 "TARGET_Z13 && TARGET_HARD_FLOAT"
4583 "@
4584 cgdbr\t%0,%h2,%1
4585 wcgdb\t%v0,%v1,0,%h2"
4586 [(set_attr "op_type" "RRE,VRR")
4587 (set_attr "type" "ftoi")])
4588
4589 ; cgxbr, cgdbr, cgebr, cfxbr, cfdbr, cfebr
4590 (define_insn "*fix_trunc<BFP:mode><GPR:mode>2_bfp"
4591 [(set (match_operand:GPR 0 "register_operand" "=d")
4592 (fix:GPR (match_operand:BFP 1 "register_operand" "f")))
4593 (unspec:GPR [(match_operand:GPR 2 "immediate_operand" "K")] UNSPEC_ROUND)
4594 (clobber (reg:CC CC_REGNUM))]
4595 "TARGET_HARD_FLOAT
4596 && (!TARGET_VX || <GPR:MODE>mode != DImode || <BFP:MODE>mode != DFmode)"
4597 "c<GPR:gf><BFP:xde>br\t%0,%h2,%1"
4598 [(set_attr "op_type" "RRE")
4599 (set_attr "type" "ftoi")])
4600
4601 (define_expand "fix_trunc<BFP:mode><GPR:mode>2_bfp"
4602 [(parallel
4603 [(set (match_operand:GPR 0 "register_operand" "=d")
4604 (fix:GPR (match_operand:BFP 1 "register_operand" "f")))
4605 (unspec:GPR [(match_operand:GPR 2 "immediate_operand" "K")] UNSPEC_ROUND)
4606 (clobber (reg:CC CC_REGNUM))])]
4607 "TARGET_HARD_FLOAT")
4608 ;
4609 ; fix_trunc(td|dd)di2 instruction pattern(s).
4610 ;
4611
4612 (define_expand "fix_trunc<mode>di2"
4613 [(set (match_operand:DI 0 "register_operand" "")
4614 (fix:DI (match_operand:DFP 1 "nonimmediate_operand" "")))]
4615 "TARGET_ZARCH && TARGET_HARD_DFP"
4616 {
4617 operands[1] = force_reg (<MODE>mode, operands[1]);
4618 emit_insn (gen_fix_trunc<mode>di2_dfp (operands[0], operands[1],
4619 GEN_INT (9)));
4620 DONE;
4621 })
4622
4623 ; cgxtr, cgdtr
4624 (define_insn "fix_trunc<DFP:mode>di2_dfp"
4625 [(set (match_operand:DI 0 "register_operand" "=d")
4626 (fix:DI (match_operand:DFP 1 "register_operand" "f")))
4627 (unspec:DI [(match_operand:DI 2 "immediate_operand" "K")] UNSPEC_ROUND)
4628 (clobber (reg:CC CC_REGNUM))]
4629 "TARGET_ZARCH && TARGET_HARD_DFP"
4630 "cg<DFP:xde>tr\t%0,%h2,%1"
4631 [(set_attr "op_type" "RRF")
4632 (set_attr "type" "ftoidfp")])
4633
4634
4635 ;
4636 ; fix_trunctf(si|di)2 instruction pattern(s).
4637 ;
4638
4639 (define_expand "fix_trunctf<mode>2"
4640 [(parallel [(set (match_operand:GPR 0 "register_operand" "")
4641 (fix:GPR (match_operand:TF 1 "register_operand" "")))
4642 (unspec:GPR [(const_int 5)] UNSPEC_ROUND)
4643 (clobber (reg:CC CC_REGNUM))])]
4644 "TARGET_HARD_FLOAT"
4645 "")
4646
4647
4648 ;
4649 ; float(si|di)(tf|df|sf|td|dd)2 instruction pattern(s).
4650 ;
4651
4652 ; cxgbr, cdgbr, cegbr, cxgtr, cdgtr
4653 (define_insn "floatdi<mode>2"
4654 [(set (match_operand:FP 0 "register_operand" "=f,<vf>")
4655 (float:FP (match_operand:DI 1 "register_operand" "d,<vd>")))]
4656 "TARGET_ZARCH && TARGET_HARD_FLOAT"
4657 "@
4658 c<xde>g<bt>r\t%0,%1
4659 wcdgb\t%v0,%v1,0,0"
4660 [(set_attr "op_type" "RRE,VRR")
4661 (set_attr "type" "itof<mode>" )
4662 (set_attr "cpu_facility" "*,vec")])
4663
4664 ; cxfbr, cdfbr, cefbr
4665 (define_insn "floatsi<mode>2"
4666 [(set (match_operand:BFP 0 "register_operand" "=f")
4667 (float:BFP (match_operand:SI 1 "register_operand" "d")))]
4668 "TARGET_HARD_FLOAT"
4669 "c<xde>fbr\t%0,%1"
4670 [(set_attr "op_type" "RRE")
4671 (set_attr "type" "itof<mode>" )])
4672
4673 ; cxftr, cdftr
4674 (define_insn "floatsi<mode>2"
4675 [(set (match_operand:DFP 0 "register_operand" "=f")
4676 (float:DFP (match_operand:SI 1 "register_operand" "d")))]
4677 "TARGET_Z196 && TARGET_HARD_FLOAT"
4678 "c<xde>ftr\t%0,0,%1,0"
4679 [(set_attr "op_type" "RRE")
4680 (set_attr "type" "itof<mode>" )])
4681
4682 ;
4683 ; floatuns(si|di)(tf|df|sf|td|dd)2 instruction pattern(s).
4684 ;
4685
4686 (define_insn "*floatunsdidf2_z13"
4687 [(set (match_operand:DF 0 "register_operand" "=f,v")
4688 (unsigned_float:DF (match_operand:DI 1 "register_operand" "d,v")))]
4689 "TARGET_Z13 && TARGET_HARD_FLOAT"
4690 "@
4691 cdlgbr\t%0,0,%1,0
4692 wcdlgb\t%v0,%v1,0,0"
4693 [(set_attr "op_type" "RRE,VRR")
4694 (set_attr "type" "itofdf")])
4695
4696 ; cxlgbr, cdlgbr, celgbr, cxlgtr, cdlgtr
4697 ; cxlfbr, cdlfbr, celfbr, cxlftr, cdlftr
4698 (define_insn "*floatuns<GPR:mode><FP:mode>2"
4699 [(set (match_operand:FP 0 "register_operand" "=f")
4700 (unsigned_float:FP (match_operand:GPR 1 "register_operand" "d")))]
4701 "TARGET_Z196 && TARGET_HARD_FLOAT
4702 && (!TARGET_VX || <FP:MODE>mode != DFmode || <GPR:MODE>mode != DImode)"
4703 "c<FP:xde>l<GPR:gf><FP:bt>r\t%0,0,%1,0"
4704 [(set_attr "op_type" "RRE")
4705 (set_attr "type" "itof<FP:mode>")])
4706
4707 (define_expand "floatuns<GPR:mode><FP:mode>2"
4708 [(set (match_operand:FP 0 "register_operand" "")
4709 (unsigned_float:FP (match_operand:GPR 1 "register_operand" "")))]
4710 "TARGET_Z196 && TARGET_HARD_FLOAT")
4711
4712 ;
4713 ; truncdfsf2 instruction pattern(s).
4714 ;
4715
4716 (define_insn "truncdfsf2"
4717 [(set (match_operand:SF 0 "register_operand" "=f,v")
4718 (float_truncate:SF (match_operand:DF 1 "register_operand" "f,v")))]
4719 "TARGET_HARD_FLOAT"
4720 "@
4721 ledbr\t%0,%1
4722 wledb\t%v0,%v1,0,0" ; IEEE inexact exception not suppressed
4723 ; According to BFP rounding mode
4724 [(set_attr "op_type" "RRE,VRR")
4725 (set_attr "type" "ftruncdf")
4726 (set_attr "cpu_facility" "*,vec")])
4727
4728 ;
4729 ; trunctf(df|sf)2 instruction pattern(s).
4730 ;
4731
4732 ; ldxbr, lexbr
4733 (define_insn "trunctf<mode>2"
4734 [(set (match_operand:DSF 0 "register_operand" "=f")
4735 (float_truncate:DSF (match_operand:TF 1 "register_operand" "f")))
4736 (clobber (match_scratch:TF 2 "=f"))]
4737 "TARGET_HARD_FLOAT"
4738 "l<xde>xbr\t%2,%1\;l<xde>r\t%0,%2"
4739 [(set_attr "length" "6")
4740 (set_attr "type" "ftrunctf")])
4741
4742 ;
4743 ; trunctddd2 and truncddsd2 instruction pattern(s).
4744 ;
4745
4746 (define_insn "trunctddd2"
4747 [(set (match_operand:DD 0 "register_operand" "=f")
4748 (float_truncate:DD (match_operand:TD 1 "register_operand" "f")))
4749 (clobber (match_scratch:TD 2 "=f"))]
4750 "TARGET_HARD_DFP"
4751 "ldxtr\t%2,0,%1,0\;ldr\t%0,%2"
4752 [(set_attr "length" "6")
4753 (set_attr "type" "ftruncdd")])
4754
4755 (define_insn "truncddsd2"
4756 [(set (match_operand:SD 0 "register_operand" "=f")
4757 (float_truncate:SD (match_operand:DD 1 "register_operand" "f")))]
4758 "TARGET_HARD_DFP"
4759 "ledtr\t%0,0,%1,0"
4760 [(set_attr "op_type" "RRF")
4761 (set_attr "type" "ftruncsd")])
4762
4763 (define_expand "trunctdsd2"
4764 [(parallel
4765 [(set (match_dup 3)
4766 (float_truncate:DD (match_operand:TD 1 "register_operand" "")))
4767 (clobber (match_scratch:TD 2 ""))])
4768 (set (match_operand:SD 0 "register_operand" "")
4769 (float_truncate:SD (match_dup 3)))]
4770 "TARGET_HARD_DFP"
4771 {
4772 operands[3] = gen_reg_rtx (DDmode);
4773 })
4774
4775 ;
4776 ; extend(sf|df)(df|tf)2 instruction pattern(s).
4777 ;
4778
4779 (define_insn "*extendsfdf2_z13"
4780 [(set (match_operand:DF 0 "register_operand" "=f,f,v")
4781 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "f,R,v")))]
4782 "TARGET_Z13 && TARGET_HARD_FLOAT"
4783 "@
4784 ldebr\t%0,%1
4785 ldeb\t%0,%1
4786 wldeb\t%v0,%v1"
4787 [(set_attr "op_type" "RRE,RXE,VRR")
4788 (set_attr "type" "fsimpdf, floaddf,fsimpdf")])
4789
4790 ; ldebr, ldeb, lxdbr, lxdb, lxebr, lxeb
4791 (define_insn "*extend<DSF:mode><BFP:mode>2"
4792 [(set (match_operand:BFP 0 "register_operand" "=f,f")
4793 (float_extend:BFP (match_operand:DSF 1 "nonimmediate_operand" "f,R")))]
4794 "TARGET_HARD_FLOAT
4795 && GET_MODE_SIZE (<BFP:MODE>mode) > GET_MODE_SIZE (<DSF:MODE>mode)
4796 && (!TARGET_VX || <BFP:MODE>mode != DFmode || <DSF:MODE>mode != SFmode)"
4797 "@
4798 l<BFP:xde><DSF:xde>br\t%0,%1
4799 l<BFP:xde><DSF:xde>b\t%0,%1"
4800 [(set_attr "op_type" "RRE,RXE")
4801 (set_attr "type" "fsimp<BFP:mode>, fload<BFP:mode>")])
4802
4803 (define_expand "extend<DSF:mode><BFP:mode>2"
4804 [(set (match_operand:BFP 0 "register_operand" "")
4805 (float_extend:BFP (match_operand:DSF 1 "nonimmediate_operand" "")))]
4806 "TARGET_HARD_FLOAT
4807 && GET_MODE_SIZE (<BFP:MODE>mode) > GET_MODE_SIZE (<DSF:MODE>mode)")
4808
4809 ;
4810 ; extendddtd2 and extendsddd2 instruction pattern(s).
4811 ;
4812
4813 (define_insn "extendddtd2"
4814 [(set (match_operand:TD 0 "register_operand" "=f")
4815 (float_extend:TD (match_operand:DD 1 "register_operand" "f")))]
4816 "TARGET_HARD_DFP"
4817 "lxdtr\t%0,%1,0"
4818 [(set_attr "op_type" "RRF")
4819 (set_attr "type" "fsimptf")])
4820
4821 (define_insn "extendsddd2"
4822 [(set (match_operand:DD 0 "register_operand" "=f")
4823 (float_extend:DD (match_operand:SD 1 "register_operand" "f")))]
4824 "TARGET_HARD_DFP"
4825 "ldetr\t%0,%1,0"
4826 [(set_attr "op_type" "RRF")
4827 (set_attr "type" "fsimptf")])
4828
4829 (define_expand "extendsdtd2"
4830 [(set (match_dup 2)
4831 (float_extend:DD (match_operand:SD 1 "register_operand" "")))
4832 (set (match_operand:TD 0 "register_operand" "")
4833 (float_extend:TD (match_dup 2)))]
4834 "TARGET_HARD_DFP"
4835 {
4836 operands[2] = gen_reg_rtx (DDmode);
4837 })
4838
4839 ; Binary Floating Point - load fp integer
4840
4841 ; Expanders for: floor, btrunc, round, ceil, and nearbyint
4842 ; For all of them the inexact exceptions are suppressed.
4843
4844 ; fiebra, fidbra, fixbra
4845 (define_insn "<FPINT:fpint_name><BFP:mode>2"
4846 [(set (match_operand:BFP 0 "register_operand" "=f")
4847 (unspec:BFP [(match_operand:BFP 1 "register_operand" "f")]
4848 FPINT))]
4849 "TARGET_Z196"
4850 "fi<BFP:xde>bra\t%0,<FPINT:fpint_roundingmode>,%1,4"
4851 [(set_attr "op_type" "RRF")
4852 (set_attr "type" "fsimp<BFP:mode>")])
4853
4854 ; rint is supposed to raise an inexact exception so we can use the
4855 ; older instructions.
4856
4857 ; fiebr, fidbr, fixbr
4858 (define_insn "rint<BFP:mode>2"
4859 [(set (match_operand:BFP 0 "register_operand" "=f")
4860 (unspec:BFP [(match_operand:BFP 1 "register_operand" "f")]
4861 UNSPEC_FPINT_RINT))]
4862 ""
4863 "fi<BFP:xde>br\t%0,0,%1"
4864 [(set_attr "op_type" "RRF")
4865 (set_attr "type" "fsimp<BFP:mode>")])
4866
4867
4868 ; Decimal Floating Point - load fp integer
4869
4870 ; fidtr, fixtr
4871 (define_insn "<FPINT:fpint_name><DFP:mode>2"
4872 [(set (match_operand:DFP 0 "register_operand" "=f")
4873 (unspec:DFP [(match_operand:DFP 1 "register_operand" "f")]
4874 FPINT))]
4875 "TARGET_HARD_DFP"
4876 "fi<DFP:xde>tr\t%0,<FPINT:fpint_roundingmode>,%1,4"
4877 [(set_attr "op_type" "RRF")
4878 (set_attr "type" "fsimp<DFP:mode>")])
4879
4880 ; fidtr, fixtr
4881 (define_insn "rint<DFP:mode>2"
4882 [(set (match_operand:DFP 0 "register_operand" "=f")
4883 (unspec:DFP [(match_operand:DFP 1 "register_operand" "f")]
4884 UNSPEC_FPINT_RINT))]
4885 "TARGET_HARD_DFP"
4886 "fi<DFP:xde>tr\t%0,0,%1,0"
4887 [(set_attr "op_type" "RRF")
4888 (set_attr "type" "fsimp<DFP:mode>")])
4889
4890 ;
4891 ; Binary <-> Decimal floating point trunc patterns
4892 ;
4893
4894 (define_insn "*trunc<BFP:mode><DFP_ALL:mode>2"
4895 [(set (reg:DFP_ALL FPR0_REGNUM)
4896 (float_truncate:DFP_ALL (reg:BFP FPR4_REGNUM)))
4897 (use (reg:SI GPR0_REGNUM))
4898 (clobber (reg:CC CC_REGNUM))]
4899 "TARGET_HARD_DFP"
4900 "pfpo")
4901
4902 (define_insn "*trunc<DFP_ALL:mode><BFP:mode>2"
4903 [(set (reg:BFP FPR0_REGNUM)
4904 (float_truncate:BFP (reg:DFP_ALL FPR4_REGNUM)))
4905 (use (reg:SI GPR0_REGNUM))
4906 (clobber (reg:CC CC_REGNUM))]
4907 "TARGET_HARD_DFP"
4908 "pfpo")
4909
4910 (define_expand "trunc<BFP:mode><DFP_ALL:mode>2"
4911 [(set (reg:BFP FPR4_REGNUM) (match_operand:BFP 1 "nonimmediate_operand" ""))
4912 (set (reg:SI GPR0_REGNUM) (match_dup 2))
4913 (parallel
4914 [(set (reg:DFP_ALL FPR0_REGNUM)
4915 (float_truncate:DFP_ALL (reg:BFP FPR4_REGNUM)))
4916 (use (reg:SI GPR0_REGNUM))
4917 (clobber (reg:CC CC_REGNUM))])
4918 (set (match_operand:DFP_ALL 0 "nonimmediate_operand" "")
4919 (reg:DFP_ALL FPR0_REGNUM))]
4920 "TARGET_HARD_DFP
4921 && GET_MODE_SIZE (<BFP:MODE>mode) > GET_MODE_SIZE (<DFP_ALL:MODE>mode)"
4922 {
4923 HOST_WIDE_INT flags;
4924
4925 flags = (PFPO_CONVERT |
4926 PFPO_OP_TYPE_<DFP_ALL:MODE> << PFPO_OP0_TYPE_SHIFT |
4927 PFPO_OP_TYPE_<BFP:MODE> << PFPO_OP1_TYPE_SHIFT);
4928
4929 operands[2] = GEN_INT (flags);
4930 })
4931
4932 (define_expand "trunc<DFP_ALL:mode><BFP:mode>2"
4933 [(set (reg:DFP_ALL FPR4_REGNUM)
4934 (match_operand:DFP_ALL 1 "nonimmediate_operand" ""))
4935 (set (reg:SI GPR0_REGNUM) (match_dup 2))
4936 (parallel
4937 [(set (reg:BFP FPR0_REGNUM) (float_truncate:BFP (reg:DFP_ALL FPR4_REGNUM)))
4938 (use (reg:SI GPR0_REGNUM))
4939 (clobber (reg:CC CC_REGNUM))])
4940 (set (match_operand:BFP 0 "nonimmediate_operand" "") (reg:BFP FPR0_REGNUM))]
4941 "TARGET_HARD_DFP
4942 && GET_MODE_SIZE (<DFP_ALL:MODE>mode) >= GET_MODE_SIZE (<BFP:MODE>mode)"
4943 {
4944 HOST_WIDE_INT flags;
4945
4946 flags = (PFPO_CONVERT |
4947 PFPO_OP_TYPE_<BFP:MODE> << PFPO_OP0_TYPE_SHIFT |
4948 PFPO_OP_TYPE_<DFP_ALL:MODE> << PFPO_OP1_TYPE_SHIFT);
4949
4950 operands[2] = GEN_INT (flags);
4951 })
4952
4953 ;
4954 ; Binary <-> Decimal floating point extend patterns
4955 ;
4956
4957 (define_insn "*extend<BFP:mode><DFP_ALL:mode>2"
4958 [(set (reg:DFP_ALL FPR0_REGNUM) (float_extend:DFP_ALL (reg:BFP FPR4_REGNUM)))
4959 (use (reg:SI GPR0_REGNUM))
4960 (clobber (reg:CC CC_REGNUM))]
4961 "TARGET_HARD_DFP"
4962 "pfpo")
4963
4964 (define_insn "*extend<DFP_ALL:mode><BFP:mode>2"
4965 [(set (reg:BFP FPR0_REGNUM) (float_extend:BFP (reg:DFP_ALL FPR4_REGNUM)))
4966 (use (reg:SI GPR0_REGNUM))
4967 (clobber (reg:CC CC_REGNUM))]
4968 "TARGET_HARD_DFP"
4969 "pfpo")
4970
4971 (define_expand "extend<BFP:mode><DFP_ALL:mode>2"
4972 [(set (reg:BFP FPR4_REGNUM) (match_operand:BFP 1 "nonimmediate_operand" ""))
4973 (set (reg:SI GPR0_REGNUM) (match_dup 2))
4974 (parallel
4975 [(set (reg:DFP_ALL FPR0_REGNUM)
4976 (float_extend:DFP_ALL (reg:BFP FPR4_REGNUM)))
4977 (use (reg:SI GPR0_REGNUM))
4978 (clobber (reg:CC CC_REGNUM))])
4979 (set (match_operand:DFP_ALL 0 "nonimmediate_operand" "")
4980 (reg:DFP_ALL FPR0_REGNUM))]
4981 "TARGET_HARD_DFP
4982 && GET_MODE_SIZE (<BFP:MODE>mode) <= GET_MODE_SIZE (<DFP_ALL:MODE>mode)"
4983 {
4984 HOST_WIDE_INT flags;
4985
4986 flags = (PFPO_CONVERT |
4987 PFPO_OP_TYPE_<DFP_ALL:MODE> << PFPO_OP0_TYPE_SHIFT |
4988 PFPO_OP_TYPE_<BFP:MODE> << PFPO_OP1_TYPE_SHIFT);
4989
4990 operands[2] = GEN_INT (flags);
4991 })
4992
4993 (define_expand "extend<DFP_ALL:mode><BFP:mode>2"
4994 [(set (reg:DFP_ALL FPR4_REGNUM)
4995 (match_operand:DFP_ALL 1 "nonimmediate_operand" ""))
4996 (set (reg:SI GPR0_REGNUM) (match_dup 2))
4997 (parallel
4998 [(set (reg:BFP FPR0_REGNUM) (float_extend:BFP (reg:DFP_ALL FPR4_REGNUM)))
4999 (use (reg:SI GPR0_REGNUM))
5000 (clobber (reg:CC CC_REGNUM))])
5001 (set (match_operand:BFP 0 "nonimmediate_operand" "") (reg:BFP FPR0_REGNUM))]
5002 "TARGET_HARD_DFP
5003 && GET_MODE_SIZE (<DFP_ALL:MODE>mode) < GET_MODE_SIZE (<BFP:MODE>mode)"
5004 {
5005 HOST_WIDE_INT flags;
5006
5007 flags = (PFPO_CONVERT |
5008 PFPO_OP_TYPE_<BFP:MODE> << PFPO_OP0_TYPE_SHIFT |
5009 PFPO_OP_TYPE_<DFP_ALL:MODE> << PFPO_OP1_TYPE_SHIFT);
5010
5011 operands[2] = GEN_INT (flags);
5012 })
5013
5014
5015 ;;
5016 ;; ARITHMETIC OPERATIONS
5017 ;;
5018 ; arithmetic operations set the ConditionCode,
5019 ; because of unpredictable Bits in Register for Halfword and Byte
5020 ; the ConditionCode can be set wrong in operations for Halfword and Byte
5021
5022 ;;
5023 ;;- Add instructions.
5024 ;;
5025
5026 ;
5027 ; addti3 instruction pattern(s).
5028 ;
5029
5030 (define_expand "addti3"
5031 [(parallel
5032 [(set (match_operand:TI 0 "register_operand" "")
5033 (plus:TI (match_operand:TI 1 "nonimmediate_operand" "")
5034 (match_operand:TI 2 "general_operand" "") ) )
5035 (clobber (reg:CC CC_REGNUM))])]
5036 "TARGET_ZARCH"
5037 {
5038 /* For z13 we have vaq which doesn't set CC. */
5039 if (TARGET_VX)
5040 {
5041 emit_insn (gen_rtx_SET (operands[0],
5042 gen_rtx_PLUS (TImode,
5043 copy_to_mode_reg (TImode, operands[1]),
5044 copy_to_mode_reg (TImode, operands[2]))));
5045 DONE;
5046 }
5047 })
5048
5049 (define_insn_and_split "*addti3"
5050 [(set (match_operand:TI 0 "register_operand" "=&d")
5051 (plus:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
5052 (match_operand:TI 2 "general_operand" "do") ) )
5053 (clobber (reg:CC CC_REGNUM))]
5054 "TARGET_ZARCH"
5055 "#"
5056 "&& reload_completed"
5057 [(parallel
5058 [(set (reg:CCL1 CC_REGNUM)
5059 (compare:CCL1 (plus:DI (match_dup 7) (match_dup 8))
5060 (match_dup 7)))
5061 (set (match_dup 6) (plus:DI (match_dup 7) (match_dup 8)))])
5062 (parallel
5063 [(set (match_dup 3) (plus:DI
5064 (plus:DI (ltu:DI (reg:CCL1 CC_REGNUM) (const_int 0))
5065 (match_dup 4)) (match_dup 5)))
5066 (clobber (reg:CC CC_REGNUM))])]
5067 "operands[3] = operand_subword (operands[0], 0, 0, TImode);
5068 operands[4] = operand_subword (operands[1], 0, 0, TImode);
5069 operands[5] = operand_subword (operands[2], 0, 0, TImode);
5070 operands[6] = operand_subword (operands[0], 1, 0, TImode);
5071 operands[7] = operand_subword (operands[1], 1, 0, TImode);
5072 operands[8] = operand_subword (operands[2], 1, 0, TImode);"
5073 [(set_attr "op_type" "*")
5074 (set_attr "cpu_facility" "*")])
5075
5076 ;
5077 ; adddi3 instruction pattern(s).
5078 ;
5079
5080 (define_expand "adddi3"
5081 [(parallel
5082 [(set (match_operand:DI 0 "nonimmediate_operand" "")
5083 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
5084 (match_operand:DI 2 "general_operand" "")))
5085 (clobber (reg:CC CC_REGNUM))])]
5086 ""
5087 "")
5088
5089 (define_insn "*adddi3_sign"
5090 [(set (match_operand:DI 0 "register_operand" "=d,d")
5091 (plus:DI (sign_extend:DI (match_operand:SI 2 "general_operand" "d,RT"))
5092 (match_operand:DI 1 "register_operand" "0,0")))
5093 (clobber (reg:CC CC_REGNUM))]
5094 "TARGET_ZARCH"
5095 "@
5096 agfr\t%0,%2
5097 agf\t%0,%2"
5098 [(set_attr "op_type" "RRE,RXY")
5099 (set_attr "z196prop" "z196_cracked,z196_cracked")])
5100
5101 (define_insn "*adddi3_zero_cc"
5102 [(set (reg CC_REGNUM)
5103 (compare (plus:DI (zero_extend:DI (match_operand:SI 2 "general_operand" "d,RT"))
5104 (match_operand:DI 1 "register_operand" "0,0"))
5105 (const_int 0)))
5106 (set (match_operand:DI 0 "register_operand" "=d,d")
5107 (plus:DI (zero_extend:DI (match_dup 2)) (match_dup 1)))]
5108 "s390_match_ccmode (insn, CCLmode) && TARGET_ZARCH"
5109 "@
5110 algfr\t%0,%2
5111 algf\t%0,%2"
5112 [(set_attr "op_type" "RRE,RXY")
5113 (set_attr "z10prop" "z10_super_E1,z10_super_E1")])
5114
5115 (define_insn "*adddi3_zero_cconly"
5116 [(set (reg CC_REGNUM)
5117 (compare (plus:DI (zero_extend:DI (match_operand:SI 2 "general_operand" "d,RT"))
5118 (match_operand:DI 1 "register_operand" "0,0"))
5119 (const_int 0)))
5120 (clobber (match_scratch:DI 0 "=d,d"))]
5121 "s390_match_ccmode (insn, CCLmode) && TARGET_ZARCH"
5122 "@
5123 algfr\t%0,%2
5124 algf\t%0,%2"
5125 [(set_attr "op_type" "RRE,RXY")
5126 (set_attr "z10prop" "z10_super_E1,z10_super_E1")])
5127
5128 (define_insn "*adddi3_zero"
5129 [(set (match_operand:DI 0 "register_operand" "=d,d")
5130 (plus:DI (zero_extend:DI (match_operand:SI 2 "general_operand" "d,RT"))
5131 (match_operand:DI 1 "register_operand" "0,0")))
5132 (clobber (reg:CC CC_REGNUM))]
5133 "TARGET_ZARCH"
5134 "@
5135 algfr\t%0,%2
5136 algf\t%0,%2"
5137 [(set_attr "op_type" "RRE,RXY")
5138 (set_attr "z10prop" "z10_super_E1,z10_super_E1")])
5139
5140 (define_insn_and_split "*adddi3_31z"
5141 [(set (match_operand:DI 0 "nonimmediate_operand" "=&d")
5142 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
5143 (match_operand:DI 2 "general_operand" "do") ) )
5144 (clobber (reg:CC CC_REGNUM))]
5145 "!TARGET_ZARCH && TARGET_CPU_ZARCH"
5146 "#"
5147 "&& reload_completed"
5148 [(parallel
5149 [(set (reg:CCL1 CC_REGNUM)
5150 (compare:CCL1 (plus:SI (match_dup 7) (match_dup 8))
5151 (match_dup 7)))
5152 (set (match_dup 6) (plus:SI (match_dup 7) (match_dup 8)))])
5153 (parallel
5154 [(set (match_dup 3) (plus:SI
5155 (plus:SI (ltu:SI (reg:CCL1 CC_REGNUM) (const_int 0))
5156 (match_dup 4)) (match_dup 5)))
5157 (clobber (reg:CC CC_REGNUM))])]
5158 "operands[3] = operand_subword (operands[0], 0, 0, DImode);
5159 operands[4] = operand_subword (operands[1], 0, 0, DImode);
5160 operands[5] = operand_subword (operands[2], 0, 0, DImode);
5161 operands[6] = operand_subword (operands[0], 1, 0, DImode);
5162 operands[7] = operand_subword (operands[1], 1, 0, DImode);
5163 operands[8] = operand_subword (operands[2], 1, 0, DImode);")
5164
5165 (define_insn_and_split "*adddi3_31"
5166 [(set (match_operand:DI 0 "nonimmediate_operand" "=&d")
5167 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
5168 (match_operand:DI 2 "general_operand" "do") ) )
5169 (clobber (reg:CC CC_REGNUM))]
5170 "!TARGET_CPU_ZARCH"
5171 "#"
5172 "&& reload_completed"
5173 [(parallel
5174 [(set (match_dup 3) (plus:SI (match_dup 4) (match_dup 5)))
5175 (clobber (reg:CC CC_REGNUM))])
5176 (parallel
5177 [(set (reg:CCL1 CC_REGNUM)
5178 (compare:CCL1 (plus:SI (match_dup 7) (match_dup 8))
5179 (match_dup 7)))
5180 (set (match_dup 6) (plus:SI (match_dup 7) (match_dup 8)))])
5181 (set (pc)
5182 (if_then_else (ltu (reg:CCL1 CC_REGNUM) (const_int 0))
5183 (pc)
5184 (label_ref (match_dup 9))))
5185 (parallel
5186 [(set (match_dup 3) (plus:SI (match_dup 3) (const_int 1)))
5187 (clobber (reg:CC CC_REGNUM))])
5188 (match_dup 9)]
5189 "operands[3] = operand_subword (operands[0], 0, 0, DImode);
5190 operands[4] = operand_subword (operands[1], 0, 0, DImode);
5191 operands[5] = operand_subword (operands[2], 0, 0, DImode);
5192 operands[6] = operand_subword (operands[0], 1, 0, DImode);
5193 operands[7] = operand_subword (operands[1], 1, 0, DImode);
5194 operands[8] = operand_subword (operands[2], 1, 0, DImode);
5195 operands[9] = gen_label_rtx ();")
5196
5197 ;
5198 ; addsi3 instruction pattern(s).
5199 ;
5200
5201 (define_expand "addsi3"
5202 [(parallel
5203 [(set (match_operand:SI 0 "nonimmediate_operand" "")
5204 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "")
5205 (match_operand:SI 2 "general_operand" "")))
5206 (clobber (reg:CC CC_REGNUM))])]
5207 ""
5208 "")
5209
5210 (define_insn "*addsi3_sign"
5211 [(set (match_operand:SI 0 "register_operand" "=d,d")
5212 (plus:SI (sign_extend:SI (match_operand:HI 2 "memory_operand" "R,T"))
5213 (match_operand:SI 1 "register_operand" "0,0")))
5214 (clobber (reg:CC CC_REGNUM))]
5215 ""
5216 "@
5217 ah\t%0,%2
5218 ahy\t%0,%2"
5219 [(set_attr "op_type" "RX,RXY")
5220 (set_attr "z196prop" "z196_cracked,z196_cracked")])
5221
5222 ;
5223 ; add(di|si)3 instruction pattern(s).
5224 ;
5225
5226 ; ark, agrk, ar, ahi, ahik, aghik, alfi, slfi, a, ay, agr, aghi, algfi, slgfi, ag, asi, agsi
5227 (define_insn "*add<mode>3"
5228 [(set (match_operand:GPR 0 "nonimmediate_operand" "=d,d,d,d, d, d,d,d,QS")
5229 (plus:GPR (match_operand:GPR 1 "nonimmediate_operand" "%0,d,0,d, 0, 0,0,0, 0")
5230 (match_operand:GPR 2 "general_operand" " d,d,K,K,Op,On,R,T, C") ) )
5231 (clobber (reg:CC CC_REGNUM))]
5232 ""
5233 "@
5234 a<g>r\t%0,%2
5235 a<g>rk\t%0,%1,%2
5236 a<g>hi\t%0,%h2
5237 a<g>hik\t%0,%1,%h2
5238 al<g>fi\t%0,%2
5239 sl<g>fi\t%0,%n2
5240 a<g>\t%0,%2
5241 a<y>\t%0,%2
5242 a<g>si\t%0,%c2"
5243 [(set_attr "op_type" "RR<E>,RRF,RI,RIE,RIL,RIL,RX<Y>,RXY,SIY")
5244 (set_attr "cpu_facility" "*,z196,*,z196,extimm,extimm,*,*,z10")
5245 (set_attr "z10prop" "z10_super_E1,*,z10_super_E1,*,z10_super_E1,z10_super_E1,
5246 z10_super_E1,z10_super_E1,z10_super_E1")])
5247
5248 ; alr, alfi, slfi, al, aly, alrk, alhsik, algr, algfi, slgfi, alg, alsi, algsi, algrk, alghsik
5249 (define_insn "*add<mode>3_carry1_cc"
5250 [(set (reg CC_REGNUM)
5251 (compare (plus:GPR (match_operand:GPR 1 "nonimmediate_operand" "%0,d, 0, 0,d,0,0,0")
5252 (match_operand:GPR 2 "general_operand" " d,d,Op,On,K,R,T,C"))
5253 (match_dup 1)))
5254 (set (match_operand:GPR 0 "nonimmediate_operand" "=d,d, d, d,d,d,d,d")
5255 (plus:GPR (match_dup 1) (match_dup 2)))]
5256 "s390_match_ccmode (insn, CCL1mode)"
5257 "@
5258 al<g>r\t%0,%2
5259 al<g>rk\t%0,%1,%2
5260 al<g>fi\t%0,%2
5261 sl<g>fi\t%0,%n2
5262 al<g>hsik\t%0,%1,%h2
5263 al<g>\t%0,%2
5264 al<y>\t%0,%2
5265 al<g>si\t%0,%c2"
5266 [(set_attr "op_type" "RR<E>,RRF,RIL,RIL,RIE,RX<Y>,RXY,SIY")
5267 (set_attr "cpu_facility" "*,z196,extimm,extimm,z196,*,*,z10")
5268 (set_attr "z10prop" "z10_super_E1,*,z10_super_E1,z10_super_E1,*,
5269 z10_super_E1,z10_super_E1,z10_super_E1")])
5270
5271 ; alr, al, aly, algr, alg, alrk, algrk
5272 (define_insn "*add<mode>3_carry1_cconly"
5273 [(set (reg CC_REGNUM)
5274 (compare (plus:GPR (match_operand:GPR 1 "nonimmediate_operand" "%0,d,0,0")
5275 (match_operand:GPR 2 "general_operand" "d,d,R,T"))
5276 (match_dup 1)))
5277 (clobber (match_scratch:GPR 0 "=d,d,d,d"))]
5278 "s390_match_ccmode (insn, CCL1mode)"
5279 "@
5280 al<g>r\t%0,%2
5281 al<g>rk\t%0,%1,%2
5282 al<g>\t%0,%2
5283 al<y>\t%0,%2"
5284 [(set_attr "op_type" "RR<E>,RRF,RX<Y>,RXY")
5285 (set_attr "cpu_facility" "*,z196,*,*")
5286 (set_attr "z10prop" "z10_super_E1,*,z10_super_E1,z10_super_E1")])
5287
5288 ; alr, alfi, slfi, al, aly, algr, algfi, slgfi, alg, alsi, algsi, alrk, algrk, alhsik, alghsik
5289 (define_insn "*add<mode>3_carry2_cc"
5290 [(set (reg CC_REGNUM)
5291 (compare (plus:GPR (match_operand:GPR 1 "nonimmediate_operand" "%0,d, 0, 0,d,0,0, 0")
5292 (match_operand:GPR 2 "general_operand" " d,d,Op,On,K,R,T, C"))
5293 (match_dup 2)))
5294 (set (match_operand:GPR 0 "nonimmediate_operand" "=d,d, d, d,d,d,d,RS")
5295 (plus:GPR (match_dup 1) (match_dup 2)))]
5296 "s390_match_ccmode (insn, CCL1mode)"
5297 "@
5298 al<g>r\t%0,%2
5299 al<g>rk\t%0,%1,%2
5300 al<g>fi\t%0,%2
5301 sl<g>fi\t%0,%n2
5302 al<g>hsik\t%0,%1,%h2
5303 al<g>\t%0,%2
5304 al<y>\t%0,%2
5305 al<g>si\t%0,%c2"
5306 [(set_attr "op_type" "RR<E>,RRF,RIL,RIL,RIE,RX<Y>,RXY,SIY")
5307 (set_attr "cpu_facility" "*,z196,extimm,extimm,z196,*,*,z10")
5308 (set_attr "z10prop" "z10_super_E1,*,z10_super_E1,z10_super_E1,*,
5309 z10_super_E1,z10_super_E1,z10_super_E1")])
5310
5311 ; alr, al, aly, algr, alg, alrk, algrk
5312 (define_insn "*add<mode>3_carry2_cconly"
5313 [(set (reg CC_REGNUM)
5314 (compare (plus:GPR (match_operand:GPR 1 "nonimmediate_operand" "%0,d,0,0")
5315 (match_operand:GPR 2 "general_operand" "d,d,R,T"))
5316 (match_dup 2)))
5317 (clobber (match_scratch:GPR 0 "=d,d,d,d"))]
5318 "s390_match_ccmode (insn, CCL1mode)"
5319 "@
5320 al<g>r\t%0,%2
5321 al<g>rk\t%0,%1,%2
5322 al<g>\t%0,%2
5323 al<y>\t%0,%2"
5324 [(set_attr "op_type" "RR<E>,RRF,RX<Y>,RXY")
5325 (set_attr "cpu_facility" "*,z196,*,*")
5326 (set_attr "z10prop" "z10_super_E1,*,z10_super_E1,z10_super_E1")])
5327
5328 ; alr, alfi, slfi, al, aly, algr, algfi, slgfi, alg, alsi, algsi, alrk, algrk, alhsik, alghsik
5329 (define_insn "*add<mode>3_cc"
5330 [(set (reg CC_REGNUM)
5331 (compare (plus:GPR (match_operand:GPR 1 "nonimmediate_operand" "%0,d, 0, 0,d,0,0, 0")
5332 (match_operand:GPR 2 "general_operand" " d,d,Op,On,K,R,T, C"))
5333 (const_int 0)))
5334 (set (match_operand:GPR 0 "nonimmediate_operand" "=d,d, d, d,d,d,d,RS")
5335 (plus:GPR (match_dup 1) (match_dup 2)))]
5336 "s390_match_ccmode (insn, CCLmode)"
5337 "@
5338 al<g>r\t%0,%2
5339 al<g>rk\t%0,%1,%2
5340 al<g>fi\t%0,%2
5341 sl<g>fi\t%0,%n2
5342 al<g>hsik\t%0,%1,%h2
5343 al<g>\t%0,%2
5344 al<y>\t%0,%2
5345 al<g>si\t%0,%c2"
5346 [(set_attr "op_type" "RR<E>,RRF,RIL,RIL,RIE,RX<Y>,RXY,SIY")
5347 (set_attr "cpu_facility" "*,z196,extimm,extimm,z196,*,*,z10")
5348 (set_attr "z10prop" "z10_super_E1,*,z10_super_E1,z10_super_E1,
5349 *,z10_super_E1,z10_super_E1,z10_super_E1")])
5350
5351 ; alr, al, aly, algr, alg, alrk, algrk
5352 (define_insn "*add<mode>3_cconly"
5353 [(set (reg CC_REGNUM)
5354 (compare (plus:GPR (match_operand:GPR 1 "nonimmediate_operand" "%0,d,0,0")
5355 (match_operand:GPR 2 "general_operand" "d,d,R,T"))
5356 (const_int 0)))
5357 (clobber (match_scratch:GPR 0 "=d,d,d,d"))]
5358 "s390_match_ccmode (insn, CCLmode)"
5359 "@
5360 al<g>r\t%0,%2
5361 al<g>rk\t%0,%1,%2
5362 al<g>\t%0,%2
5363 al<y>\t%0,%2"
5364 [(set_attr "op_type" "RR<E>,RRF,RX<Y>,RXY")
5365 (set_attr "cpu_facility" "*,z196,*,*")
5366 (set_attr "z10prop" "z10_super_E1,*,z10_super_E1,z10_super_E1")])
5367
5368 ; alr, al, aly, algr, alg, alrk, algrk
5369 (define_insn "*add<mode>3_cconly2"
5370 [(set (reg CC_REGNUM)
5371 (compare (match_operand:GPR 1 "nonimmediate_operand" "%0,d,0,0")
5372 (neg:GPR (match_operand:GPR 2 "general_operand" "d,d,R,T"))))
5373 (clobber (match_scratch:GPR 0 "=d,d,d,d"))]
5374 "s390_match_ccmode(insn, CCLmode)"
5375 "@
5376 al<g>r\t%0,%2
5377 al<g>rk\t%0,%1,%2
5378 al<g>\t%0,%2
5379 al<y>\t%0,%2"
5380 [(set_attr "op_type" "RR<E>,RRF,RX<Y>,RXY")
5381 (set_attr "cpu_facility" "*,z196,*,*")
5382 (set_attr "z10prop" "z10_super_E1,*,z10_super_E1,z10_super_E1")])
5383
5384 ; ahi, afi, aghi, agfi, asi, agsi
5385 (define_insn "*add<mode>3_imm_cc"
5386 [(set (reg CC_REGNUM)
5387 (compare (plus:GPR (match_operand:GPR 1 "nonimmediate_operand" " 0, d,0, 0")
5388 (match_operand:GPR 2 "const_int_operand" " K, K,Os, C"))
5389 (const_int 0)))
5390 (set (match_operand:GPR 0 "nonimmediate_operand" "=d, d,d,QS")
5391 (plus:GPR (match_dup 1) (match_dup 2)))]
5392 "s390_match_ccmode (insn, CCAmode)
5393 && (CONST_OK_FOR_CONSTRAINT_P (INTVAL (operands[2]), 'K', \"K\")
5394 || (CONST_OK_FOR_CONSTRAINT_P (INTVAL (operands[2]), 'O', \"Os\")
5395 /* Avoid INT32_MIN on 32 bit. */
5396 && (!TARGET_ZARCH || INTVAL (operands[2]) != -0x7fffffff - 1)))"
5397 "@
5398 a<g>hi\t%0,%h2
5399 a<g>hik\t%0,%1,%h2
5400 a<g>fi\t%0,%2
5401 a<g>si\t%0,%c2"
5402 [(set_attr "op_type" "RI,RIE,RIL,SIY")
5403 (set_attr "cpu_facility" "*,z196,extimm,z10")
5404 (set_attr "z10prop" "z10_super_E1,*,z10_super_E1,z10_super_E1")])
5405
5406 ;
5407 ; add(tf|df|sf|td|dd)3 instruction pattern(s).
5408 ;
5409
5410 ; axbr, adbr, aebr, axb, adb, aeb, adtr, axtr
5411 ; FIXME: wfadb does not clobber cc
5412 (define_insn "add<mode>3"
5413 [(set (match_operand:FP 0 "register_operand" "=f, f,<vf>")
5414 (plus:FP (match_operand:FP 1 "nonimmediate_operand" "%<f0>, 0,<v0>")
5415 (match_operand:FP 2 "general_operand" "f,<Rf>,<vf>")))
5416 (clobber (reg:CC CC_REGNUM))]
5417 "TARGET_HARD_FLOAT"
5418 "@
5419 a<xde><bt>r\t%0,<op1>%2
5420 a<xde>b\t%0,%2
5421 wfadb\t%v0,%v1,%v2"
5422 [(set_attr "op_type" "<RRer>,RXE,VRR")
5423 (set_attr "type" "fsimp<mode>")
5424 (set_attr "cpu_facility" "*,*,vec")])
5425
5426 ; axbr, adbr, aebr, axb, adb, aeb, adtr, axtr
5427 (define_insn "*add<mode>3_cc"
5428 [(set (reg CC_REGNUM)
5429 (compare (plus:FP (match_operand:FP 1 "nonimmediate_operand" "%<f0>,0")
5430 (match_operand:FP 2 "general_operand" " f,<Rf>"))
5431 (match_operand:FP 3 "const0_operand" "")))
5432 (set (match_operand:FP 0 "register_operand" "=f,f")
5433 (plus:FP (match_dup 1) (match_dup 2)))]
5434 "s390_match_ccmode (insn, CCSmode) && TARGET_HARD_FLOAT"
5435 "@
5436 a<xde><bt>r\t%0,<op1>%2
5437 a<xde>b\t%0,%2"
5438 [(set_attr "op_type" "<RRer>,RXE")
5439 (set_attr "type" "fsimp<mode>")])
5440
5441 ; axbr, adbr, aebr, axb, adb, aeb, adtr, axtr
5442 (define_insn "*add<mode>3_cconly"
5443 [(set (reg CC_REGNUM)
5444 (compare (plus:FP (match_operand:FP 1 "nonimmediate_operand" "%<f0>,0")
5445 (match_operand:FP 2 "general_operand" " f,<Rf>"))
5446 (match_operand:FP 3 "const0_operand" "")))
5447 (clobber (match_scratch:FP 0 "=f,f"))]
5448 "s390_match_ccmode (insn, CCSmode) && TARGET_HARD_FLOAT"
5449 "@
5450 a<xde><bt>r\t%0,<op1>%2
5451 a<xde>b\t%0,%2"
5452 [(set_attr "op_type" "<RRer>,RXE")
5453 (set_attr "type" "fsimp<mode>")])
5454
5455 ;
5456 ; Pointer add instruction patterns
5457 ;
5458
5459 ; This will match "*la_64"
5460 (define_expand "addptrdi3"
5461 [(set (match_operand:DI 0 "register_operand" "")
5462 (plus:DI (match_operand:DI 1 "register_operand" "")
5463 (match_operand:DI 2 "nonmemory_operand" "")))]
5464 "TARGET_64BIT"
5465 {
5466 if (GET_CODE (operands[2]) == CONST_INT)
5467 {
5468 HOST_WIDE_INT c = INTVAL (operands[2]);
5469
5470 if (!CONST_OK_FOR_CONSTRAINT_P (c, 'K', "K")
5471 && !CONST_OK_FOR_CONSTRAINT_P (c, 'O', "Os"))
5472 {
5473 operands[2] = force_const_mem (DImode, operands[2]);
5474 operands[2] = force_reg (DImode, operands[2]);
5475 }
5476 else if (!DISP_IN_RANGE (INTVAL (operands[2])))
5477 operands[2] = force_reg (DImode, operands[2]);
5478 }
5479 })
5480
5481 ; For 31 bit we have to prevent the generated pattern from matching
5482 ; normal ADDs since la only does a 31 bit add. This is supposed to
5483 ; match "force_la_31".
5484 (define_expand "addptrsi3"
5485 [(parallel
5486 [(set (match_operand:SI 0 "register_operand" "")
5487 (plus:SI (match_operand:SI 1 "register_operand" "")
5488 (match_operand:SI 2 "nonmemory_operand" "")))
5489 (use (const_int 0))])]
5490 "!TARGET_64BIT"
5491 {
5492 if (GET_CODE (operands[2]) == CONST_INT)
5493 {
5494 HOST_WIDE_INT c = INTVAL (operands[2]);
5495
5496 if (!CONST_OK_FOR_CONSTRAINT_P (c, 'K', "K")
5497 && !CONST_OK_FOR_CONSTRAINT_P (c, 'O', "Os"))
5498 {
5499 operands[2] = force_const_mem (SImode, operands[2]);
5500 operands[2] = force_reg (SImode, operands[2]);
5501 }
5502 else if (!DISP_IN_RANGE (INTVAL (operands[2])))
5503 operands[2] = force_reg (SImode, operands[2]);
5504 }
5505 })
5506
5507 ;;
5508 ;;- Subtract instructions.
5509 ;;
5510
5511 ;
5512 ; subti3 instruction pattern(s).
5513 ;
5514
5515 (define_expand "subti3"
5516 [(parallel
5517 [(set (match_operand:TI 0 "register_operand" "")
5518 (minus:TI (match_operand:TI 1 "register_operand" "")
5519 (match_operand:TI 2 "general_operand" "") ) )
5520 (clobber (reg:CC CC_REGNUM))])]
5521 "TARGET_ZARCH"
5522 {
5523 /* For z13 we have vaq which doesn't set CC. */
5524 if (TARGET_VX)
5525 {
5526 emit_insn (gen_rtx_SET (operands[0],
5527 gen_rtx_MINUS (TImode,
5528 operands[1],
5529 copy_to_mode_reg (TImode, operands[2]))));
5530 DONE;
5531 }
5532 })
5533
5534 (define_insn_and_split "*subti3"
5535 [(set (match_operand:TI 0 "register_operand" "=&d")
5536 (minus:TI (match_operand:TI 1 "register_operand" "0")
5537 (match_operand:TI 2 "general_operand" "do") ) )
5538 (clobber (reg:CC CC_REGNUM))]
5539 "TARGET_ZARCH"
5540 "#"
5541 "&& reload_completed"
5542 [(parallel
5543 [(set (reg:CCL2 CC_REGNUM)
5544 (compare:CCL2 (minus:DI (match_dup 7) (match_dup 8))
5545 (match_dup 7)))
5546 (set (match_dup 6) (minus:DI (match_dup 7) (match_dup 8)))])
5547 (parallel
5548 [(set (match_dup 3) (minus:DI (minus:DI (match_dup 4) (match_dup 5))
5549 (gtu:DI (reg:CCL2 CC_REGNUM) (const_int 0))))
5550 (clobber (reg:CC CC_REGNUM))])]
5551 "operands[3] = operand_subword (operands[0], 0, 0, TImode);
5552 operands[4] = operand_subword (operands[1], 0, 0, TImode);
5553 operands[5] = operand_subword (operands[2], 0, 0, TImode);
5554 operands[6] = operand_subword (operands[0], 1, 0, TImode);
5555 operands[7] = operand_subword (operands[1], 1, 0, TImode);
5556 operands[8] = operand_subword (operands[2], 1, 0, TImode);"
5557 [(set_attr "op_type" "*")
5558 (set_attr "cpu_facility" "*")])
5559
5560 ;
5561 ; subdi3 instruction pattern(s).
5562 ;
5563
5564 (define_expand "subdi3"
5565 [(parallel
5566 [(set (match_operand:DI 0 "register_operand" "")
5567 (minus:DI (match_operand:DI 1 "register_operand" "")
5568 (match_operand:DI 2 "general_operand" "")))
5569 (clobber (reg:CC CC_REGNUM))])]
5570 ""
5571 "")
5572
5573 (define_insn "*subdi3_sign"
5574 [(set (match_operand:DI 0 "register_operand" "=d,d")
5575 (minus:DI (match_operand:DI 1 "register_operand" "0,0")
5576 (sign_extend:DI (match_operand:SI 2 "general_operand" "d,RT"))))
5577 (clobber (reg:CC CC_REGNUM))]
5578 "TARGET_ZARCH"
5579 "@
5580 sgfr\t%0,%2
5581 sgf\t%0,%2"
5582 [(set_attr "op_type" "RRE,RXY")
5583 (set_attr "z10prop" "z10_c,*")
5584 (set_attr "z196prop" "z196_cracked")])
5585
5586 (define_insn "*subdi3_zero_cc"
5587 [(set (reg CC_REGNUM)
5588 (compare (minus:DI (match_operand:DI 1 "register_operand" "0,0")
5589 (zero_extend:DI (match_operand:SI 2 "general_operand" "d,RT")))
5590 (const_int 0)))
5591 (set (match_operand:DI 0 "register_operand" "=d,d")
5592 (minus:DI (match_dup 1) (zero_extend:DI (match_dup 2))))]
5593 "s390_match_ccmode (insn, CCLmode) && TARGET_ZARCH"
5594 "@
5595 slgfr\t%0,%2
5596 slgf\t%0,%2"
5597 [(set_attr "op_type" "RRE,RXY")
5598 (set_attr "z10prop" "z10_super_c_E1,z10_super_E1")])
5599
5600 (define_insn "*subdi3_zero_cconly"
5601 [(set (reg CC_REGNUM)
5602 (compare (minus:DI (match_operand:DI 1 "register_operand" "0,0")
5603 (zero_extend:DI (match_operand:SI 2 "general_operand" "d,RT")))
5604 (const_int 0)))
5605 (clobber (match_scratch:DI 0 "=d,d"))]
5606 "s390_match_ccmode (insn, CCLmode) && TARGET_ZARCH"
5607 "@
5608 slgfr\t%0,%2
5609 slgf\t%0,%2"
5610 [(set_attr "op_type" "RRE,RXY")
5611 (set_attr "z10prop" "z10_super_c_E1,z10_super_E1")])
5612
5613 (define_insn "*subdi3_zero"
5614 [(set (match_operand:DI 0 "register_operand" "=d,d")
5615 (minus:DI (match_operand:DI 1 "register_operand" "0,0")
5616 (zero_extend:DI (match_operand:SI 2 "general_operand" "d,RT"))))
5617 (clobber (reg:CC CC_REGNUM))]
5618 "TARGET_ZARCH"
5619 "@
5620 slgfr\t%0,%2
5621 slgf\t%0,%2"
5622 [(set_attr "op_type" "RRE,RXY")
5623 (set_attr "z10prop" "z10_super_c_E1,z10_super_E1")])
5624
5625 (define_insn_and_split "*subdi3_31z"
5626 [(set (match_operand:DI 0 "register_operand" "=&d")
5627 (minus:DI (match_operand:DI 1 "register_operand" "0")
5628 (match_operand:DI 2 "general_operand" "do") ) )
5629 (clobber (reg:CC CC_REGNUM))]
5630 "!TARGET_ZARCH && TARGET_CPU_ZARCH"
5631 "#"
5632 "&& reload_completed"
5633 [(parallel
5634 [(set (reg:CCL2 CC_REGNUM)
5635 (compare:CCL2 (minus:SI (match_dup 7) (match_dup 8))
5636 (match_dup 7)))
5637 (set (match_dup 6) (minus:SI (match_dup 7) (match_dup 8)))])
5638 (parallel
5639 [(set (match_dup 3) (minus:SI (minus:SI (match_dup 4) (match_dup 5))
5640 (gtu:SI (reg:CCL2 CC_REGNUM) (const_int 0))))
5641 (clobber (reg:CC CC_REGNUM))])]
5642 "operands[3] = operand_subword (operands[0], 0, 0, DImode);
5643 operands[4] = operand_subword (operands[1], 0, 0, DImode);
5644 operands[5] = operand_subword (operands[2], 0, 0, DImode);
5645 operands[6] = operand_subword (operands[0], 1, 0, DImode);
5646 operands[7] = operand_subword (operands[1], 1, 0, DImode);
5647 operands[8] = operand_subword (operands[2], 1, 0, DImode);")
5648
5649 (define_insn_and_split "*subdi3_31"
5650 [(set (match_operand:DI 0 "register_operand" "=&d")
5651 (minus:DI (match_operand:DI 1 "register_operand" "0")
5652 (match_operand:DI 2 "general_operand" "do") ) )
5653 (clobber (reg:CC CC_REGNUM))]
5654 "!TARGET_CPU_ZARCH"
5655 "#"
5656 "&& reload_completed"
5657 [(parallel
5658 [(set (match_dup 3) (minus:SI (match_dup 4) (match_dup 5)))
5659 (clobber (reg:CC CC_REGNUM))])
5660 (parallel
5661 [(set (reg:CCL2 CC_REGNUM)
5662 (compare:CCL2 (minus:SI (match_dup 7) (match_dup 8))
5663 (match_dup 7)))
5664 (set (match_dup 6) (minus:SI (match_dup 7) (match_dup 8)))])
5665 (set (pc)
5666 (if_then_else (gtu (reg:CCL2 CC_REGNUM) (const_int 0))
5667 (pc)
5668 (label_ref (match_dup 9))))
5669 (parallel
5670 [(set (match_dup 3) (plus:SI (match_dup 3) (const_int -1)))
5671 (clobber (reg:CC CC_REGNUM))])
5672 (match_dup 9)]
5673 "operands[3] = operand_subword (operands[0], 0, 0, DImode);
5674 operands[4] = operand_subword (operands[1], 0, 0, DImode);
5675 operands[5] = operand_subword (operands[2], 0, 0, DImode);
5676 operands[6] = operand_subword (operands[0], 1, 0, DImode);
5677 operands[7] = operand_subword (operands[1], 1, 0, DImode);
5678 operands[8] = operand_subword (operands[2], 1, 0, DImode);
5679 operands[9] = gen_label_rtx ();")
5680
5681 ;
5682 ; subsi3 instruction pattern(s).
5683 ;
5684
5685 (define_expand "subsi3"
5686 [(parallel
5687 [(set (match_operand:SI 0 "register_operand" "")
5688 (minus:SI (match_operand:SI 1 "register_operand" "")
5689 (match_operand:SI 2 "general_operand" "")))
5690 (clobber (reg:CC CC_REGNUM))])]
5691 ""
5692 "")
5693
5694 (define_insn "*subsi3_sign"
5695 [(set (match_operand:SI 0 "register_operand" "=d,d")
5696 (minus:SI (match_operand:SI 1 "register_operand" "0,0")
5697 (sign_extend:SI (match_operand:HI 2 "memory_operand" "R,T"))))
5698 (clobber (reg:CC CC_REGNUM))]
5699 ""
5700 "@
5701 sh\t%0,%2
5702 shy\t%0,%2"
5703 [(set_attr "op_type" "RX,RXY")
5704 (set_attr "z196prop" "z196_cracked,z196_cracked")])
5705
5706 ;
5707 ; sub(di|si)3 instruction pattern(s).
5708 ;
5709
5710 ; sr, s, sy, sgr, sg, srk, sgrk
5711 (define_insn "*sub<mode>3"
5712 [(set (match_operand:GPR 0 "register_operand" "=d,d,d,d")
5713 (minus:GPR (match_operand:GPR 1 "register_operand" "0,d,0,0")
5714 (match_operand:GPR 2 "general_operand" "d,d,R,T") ) )
5715 (clobber (reg:CC CC_REGNUM))]
5716 ""
5717 "@
5718 s<g>r\t%0,%2
5719 s<g>rk\t%0,%1,%2
5720 s<g>\t%0,%2
5721 s<y>\t%0,%2"
5722 [(set_attr "op_type" "RR<E>,RRF,RX<Y>,RXY")
5723 (set_attr "cpu_facility" "*,z196,*,*")
5724 (set_attr "z10prop" "z10_super_c_E1,*,z10_super_E1,z10_super_E1")])
5725
5726 ; slr, sl, sly, slgr, slg, slrk, slgrk
5727 (define_insn "*sub<mode>3_borrow_cc"
5728 [(set (reg CC_REGNUM)
5729 (compare (minus:GPR (match_operand:GPR 1 "register_operand" "0,d,0,0")
5730 (match_operand:GPR 2 "general_operand" "d,d,R,T"))
5731 (match_dup 1)))
5732 (set (match_operand:GPR 0 "register_operand" "=d,d,d,d")
5733 (minus:GPR (match_dup 1) (match_dup 2)))]
5734 "s390_match_ccmode (insn, CCL2mode)"
5735 "@
5736 sl<g>r\t%0,%2
5737 sl<g>rk\t%0,%1,%2
5738 sl<g>\t%0,%2
5739 sl<y>\t%0,%2"
5740 [(set_attr "op_type" "RR<E>,RRF,RX<Y>,RXY")
5741 (set_attr "cpu_facility" "*,z196,*,*")
5742 (set_attr "z10prop" "z10_super_c_E1,*,z10_super_E1,z10_super_E1")])
5743
5744 ; slr, sl, sly, slgr, slg, slrk, slgrk
5745 (define_insn "*sub<mode>3_borrow_cconly"
5746 [(set (reg CC_REGNUM)
5747 (compare (minus:GPR (match_operand:GPR 1 "register_operand" "0,d,0,0")
5748 (match_operand:GPR 2 "general_operand" "d,d,R,T"))
5749 (match_dup 1)))
5750 (clobber (match_scratch:GPR 0 "=d,d,d,d"))]
5751 "s390_match_ccmode (insn, CCL2mode)"
5752 "@
5753 sl<g>r\t%0,%2
5754 sl<g>rk\t%0,%1,%2
5755 sl<g>\t%0,%2
5756 sl<y>\t%0,%2"
5757 [(set_attr "op_type" "RR<E>,RRF,RX<Y>,RXY")
5758 (set_attr "cpu_facility" "*,z196,*,*")
5759 (set_attr "z10prop" "z10_super_c_E1,*,z10_super_E1,z10_super_E1")])
5760
5761 ; slr, sl, sly, slgr, slg, slrk, slgrk
5762 (define_insn "*sub<mode>3_cc"
5763 [(set (reg CC_REGNUM)
5764 (compare (minus:GPR (match_operand:GPR 1 "register_operand" "0,d,0,0")
5765 (match_operand:GPR 2 "general_operand" "d,d,R,T"))
5766 (const_int 0)))
5767 (set (match_operand:GPR 0 "register_operand" "=d,d,d,d")
5768 (minus:GPR (match_dup 1) (match_dup 2)))]
5769 "s390_match_ccmode (insn, CCLmode)"
5770 "@
5771 sl<g>r\t%0,%2
5772 sl<g>rk\t%0,%1,%2
5773 sl<g>\t%0,%2
5774 sl<y>\t%0,%2"
5775 [(set_attr "op_type" "RR<E>,RRF,RX<Y>,RXY")
5776 (set_attr "cpu_facility" "*,z196,*,*")
5777 (set_attr "z10prop" "z10_super_c_E1,*,z10_super_E1,z10_super_E1")])
5778
5779 ; slr, sl, sly, slgr, slg, slrk, slgrk
5780 (define_insn "*sub<mode>3_cc2"
5781 [(set (reg CC_REGNUM)
5782 (compare (match_operand:GPR 1 "register_operand" "0,d,0,0")
5783 (match_operand:GPR 2 "general_operand" "d,d,R,T")))
5784 (set (match_operand:GPR 0 "register_operand" "=d,d,d,d")
5785 (minus:GPR (match_dup 1) (match_dup 2)))]
5786 "s390_match_ccmode (insn, CCL3mode)"
5787 "@
5788 sl<g>r\t%0,%2
5789 sl<g>rk\t%0,%1,%2
5790 sl<g>\t%0,%2
5791 sl<y>\t%0,%2"
5792 [(set_attr "op_type" "RR<E>,RRF,RX<Y>,RXY")
5793 (set_attr "cpu_facility" "*,z196,*,*")
5794 (set_attr "z10prop" "z10_super_c_E1,*,z10_super_E1,z10_super_E1")])
5795
5796 ; slr, sl, sly, slgr, slg, slrk, slgrk
5797 (define_insn "*sub<mode>3_cconly"
5798 [(set (reg CC_REGNUM)
5799 (compare (minus:GPR (match_operand:GPR 1 "register_operand" "0,d,0,0")
5800 (match_operand:GPR 2 "general_operand" "d,d,R,T"))
5801 (const_int 0)))
5802 (clobber (match_scratch:GPR 0 "=d,d,d,d"))]
5803 "s390_match_ccmode (insn, CCLmode)"
5804 "@
5805 sl<g>r\t%0,%2
5806 sl<g>rk\t%0,%1,%2
5807 sl<g>\t%0,%2
5808 sl<y>\t%0,%2"
5809 [(set_attr "op_type" "RR<E>,RRF,RX<Y>,RXY")
5810 (set_attr "cpu_facility" "*,z196,*,*")
5811 (set_attr "z10prop" "z10_super_c_E1,*,z10_super_E1,z10_super_E1")])
5812
5813
5814 ; slr, sl, sly, slgr, slg, slrk, slgrk
5815 (define_insn "*sub<mode>3_cconly2"
5816 [(set (reg CC_REGNUM)
5817 (compare (match_operand:GPR 1 "register_operand" "0,d,0,0")
5818 (match_operand:GPR 2 "general_operand" "d,d,R,T")))
5819 (clobber (match_scratch:GPR 0 "=d,d,d,d"))]
5820 "s390_match_ccmode (insn, CCL3mode)"
5821 "@
5822 sl<g>r\t%0,%2
5823 sl<g>rk\t%0,%1,%2
5824 sl<g>\t%0,%2
5825 sl<y>\t%0,%2"
5826 [(set_attr "op_type" "RR<E>,RRF,RX<Y>,RXY")
5827 (set_attr "cpu_facility" "*,z196,*,*")
5828 (set_attr "z10prop" "z10_super_c_E1,*,z10_super_E1,z10_super_E1")])
5829
5830
5831 ;
5832 ; sub(tf|df|sf|td|dd)3 instruction pattern(s).
5833 ;
5834
5835 ; sxbr, sdbr, sebr, sdb, seb, sxtr, sdtr
5836 (define_insn "sub<mode>3"
5837 [(set (match_operand:FP 0 "register_operand" "=f, f,<vf>")
5838 (minus:FP (match_operand:FP 1 "register_operand" "<f0>, 0,<v0>")
5839 (match_operand:FP 2 "general_operand" "f,<Rf>,<vf>")))
5840 (clobber (reg:CC CC_REGNUM))]
5841 "TARGET_HARD_FLOAT"
5842 "@
5843 s<xde><bt>r\t%0,<op1>%2
5844 s<xde>b\t%0,%2
5845 wfsdb\t%v0,%v1,%v2"
5846 [(set_attr "op_type" "<RRer>,RXE,VRR")
5847 (set_attr "type" "fsimp<mode>")
5848 (set_attr "cpu_facility" "*,*,vec")])
5849
5850 ; sxbr, sdbr, sebr, sdb, seb, sxtr, sdtr
5851 (define_insn "*sub<mode>3_cc"
5852 [(set (reg CC_REGNUM)
5853 (compare (minus:FP (match_operand:FP 1 "nonimmediate_operand" "<f0>,0")
5854 (match_operand:FP 2 "general_operand" "f,<Rf>"))
5855 (match_operand:FP 3 "const0_operand" "")))
5856 (set (match_operand:FP 0 "register_operand" "=f,f")
5857 (minus:FP (match_dup 1) (match_dup 2)))]
5858 "s390_match_ccmode (insn, CCSmode) && TARGET_HARD_FLOAT"
5859 "@
5860 s<xde><bt>r\t%0,<op1>%2
5861 s<xde>b\t%0,%2"
5862 [(set_attr "op_type" "<RRer>,RXE")
5863 (set_attr "type" "fsimp<mode>")])
5864
5865 ; sxbr, sdbr, sebr, sdb, seb, sxtr, sdtr
5866 (define_insn "*sub<mode>3_cconly"
5867 [(set (reg CC_REGNUM)
5868 (compare (minus:FP (match_operand:FP 1 "nonimmediate_operand" "<f0>,0")
5869 (match_operand:FP 2 "general_operand" "f,<Rf>"))
5870 (match_operand:FP 3 "const0_operand" "")))
5871 (clobber (match_scratch:FP 0 "=f,f"))]
5872 "s390_match_ccmode (insn, CCSmode) && TARGET_HARD_FLOAT"
5873 "@
5874 s<xde><bt>r\t%0,<op1>%2
5875 s<xde>b\t%0,%2"
5876 [(set_attr "op_type" "<RRer>,RXE")
5877 (set_attr "type" "fsimp<mode>")])
5878
5879
5880 ;;
5881 ;;- Conditional add/subtract instructions.
5882 ;;
5883
5884 ;
5885 ; add(di|si)cc instruction pattern(s).
5886 ;
5887
5888 ; the following 4 patterns are used when the result of an add with
5889 ; carry is checked for an overflow condition
5890
5891 ; op1 + op2 + c < op1
5892
5893 ; alcr, alc, alcgr, alcg
5894 (define_insn "*add<mode>3_alc_carry1_cc"
5895 [(set (reg CC_REGNUM)
5896 (compare
5897 (plus:GPR (plus:GPR (match_operand:GPR 3 "s390_alc_comparison" "")
5898 (match_operand:GPR 1 "nonimmediate_operand" "%0,0"))
5899 (match_operand:GPR 2 "general_operand" "d,RT"))
5900 (match_dup 1)))
5901 (set (match_operand:GPR 0 "register_operand" "=d,d")
5902 (plus:GPR (plus:GPR (match_dup 3) (match_dup 1)) (match_dup 2)))]
5903 "s390_match_ccmode (insn, CCL1mode) && TARGET_CPU_ZARCH"
5904 "@
5905 alc<g>r\t%0,%2
5906 alc<g>\t%0,%2"
5907 [(set_attr "op_type" "RRE,RXY")
5908 (set_attr "z196prop" "z196_alone,z196_alone")])
5909
5910 ; alcr, alc, alcgr, alcg
5911 (define_insn "*add<mode>3_alc_carry1_cconly"
5912 [(set (reg CC_REGNUM)
5913 (compare
5914 (plus:GPR (plus:GPR (match_operand:GPR 3 "s390_alc_comparison" "")
5915 (match_operand:GPR 1 "nonimmediate_operand" "%0,0"))
5916 (match_operand:GPR 2 "general_operand" "d,RT"))
5917 (match_dup 1)))
5918 (clobber (match_scratch:GPR 0 "=d,d"))]
5919 "s390_match_ccmode (insn, CCL1mode) && TARGET_CPU_ZARCH"
5920 "@
5921 alc<g>r\t%0,%2
5922 alc<g>\t%0,%2"
5923 [(set_attr "op_type" "RRE,RXY")
5924 (set_attr "z196prop" "z196_alone,z196_alone")])
5925
5926 ; op1 + op2 + c < op2
5927
5928 ; alcr, alc, alcgr, alcg
5929 (define_insn "*add<mode>3_alc_carry2_cc"
5930 [(set (reg CC_REGNUM)
5931 (compare
5932 (plus:GPR (plus:GPR (match_operand:GPR 3 "s390_alc_comparison" "")
5933 (match_operand:GPR 1 "nonimmediate_operand" "%0,0"))
5934 (match_operand:GPR 2 "general_operand" "d,RT"))
5935 (match_dup 2)))
5936 (set (match_operand:GPR 0 "register_operand" "=d,d")
5937 (plus:GPR (plus:GPR (match_dup 3) (match_dup 1)) (match_dup 2)))]
5938 "s390_match_ccmode (insn, CCL1mode) && TARGET_CPU_ZARCH"
5939 "@
5940 alc<g>r\t%0,%2
5941 alc<g>\t%0,%2"
5942 [(set_attr "op_type" "RRE,RXY")])
5943
5944 ; alcr, alc, alcgr, alcg
5945 (define_insn "*add<mode>3_alc_carry2_cconly"
5946 [(set (reg CC_REGNUM)
5947 (compare
5948 (plus:GPR (plus:GPR (match_operand:GPR 3 "s390_alc_comparison" "")
5949 (match_operand:GPR 1 "nonimmediate_operand" "%0,0"))
5950 (match_operand:GPR 2 "general_operand" "d,RT"))
5951 (match_dup 2)))
5952 (clobber (match_scratch:GPR 0 "=d,d"))]
5953 "s390_match_ccmode (insn, CCL1mode) && TARGET_CPU_ZARCH"
5954 "@
5955 alc<g>r\t%0,%2
5956 alc<g>\t%0,%2"
5957 [(set_attr "op_type" "RRE,RXY")])
5958
5959 ; alcr, alc, alcgr, alcg
5960 (define_insn "*add<mode>3_alc_cc"
5961 [(set (reg CC_REGNUM)
5962 (compare
5963 (plus:GPR (plus:GPR (match_operand:GPR 3 "s390_alc_comparison" "")
5964 (match_operand:GPR 1 "nonimmediate_operand" "%0,0"))
5965 (match_operand:GPR 2 "general_operand" "d,RT"))
5966 (const_int 0)))
5967 (set (match_operand:GPR 0 "register_operand" "=d,d")
5968 (plus:GPR (plus:GPR (match_dup 3) (match_dup 1)) (match_dup 2)))]
5969 "s390_match_ccmode (insn, CCLmode) && TARGET_CPU_ZARCH"
5970 "@
5971 alc<g>r\t%0,%2
5972 alc<g>\t%0,%2"
5973 [(set_attr "op_type" "RRE,RXY")])
5974
5975 ; alcr, alc, alcgr, alcg
5976 (define_insn "*add<mode>3_alc"
5977 [(set (match_operand:GPR 0 "register_operand" "=d,d")
5978 (plus:GPR (plus:GPR (match_operand:GPR 3 "s390_alc_comparison" "")
5979 (match_operand:GPR 1 "nonimmediate_operand" "%0,0"))
5980 (match_operand:GPR 2 "general_operand" "d,RT")))
5981 (clobber (reg:CC CC_REGNUM))]
5982 "TARGET_CPU_ZARCH"
5983 "@
5984 alc<g>r\t%0,%2
5985 alc<g>\t%0,%2"
5986 [(set_attr "op_type" "RRE,RXY")])
5987
5988 ; slbr, slb, slbgr, slbg
5989 (define_insn "*sub<mode>3_slb_cc"
5990 [(set (reg CC_REGNUM)
5991 (compare
5992 (minus:GPR (minus:GPR (match_operand:GPR 1 "nonimmediate_operand" "0,0")
5993 (match_operand:GPR 2 "general_operand" "d,RT"))
5994 (match_operand:GPR 3 "s390_slb_comparison" ""))
5995 (const_int 0)))
5996 (set (match_operand:GPR 0 "register_operand" "=d,d")
5997 (minus:GPR (minus:GPR (match_dup 1) (match_dup 2)) (match_dup 3)))]
5998 "s390_match_ccmode (insn, CCLmode) && TARGET_CPU_ZARCH"
5999 "@
6000 slb<g>r\t%0,%2
6001 slb<g>\t%0,%2"
6002 [(set_attr "op_type" "RRE,RXY")
6003 (set_attr "z10prop" "z10_c,*")])
6004
6005 ; slbr, slb, slbgr, slbg
6006 (define_insn "*sub<mode>3_slb"
6007 [(set (match_operand:GPR 0 "register_operand" "=d,d")
6008 (minus:GPR (minus:GPR (match_operand:GPR 1 "nonimmediate_operand" "0,0")
6009 (match_operand:GPR 2 "general_operand" "d,RT"))
6010 (match_operand:GPR 3 "s390_slb_comparison" "")))
6011 (clobber (reg:CC CC_REGNUM))]
6012 "TARGET_CPU_ZARCH"
6013 "@
6014 slb<g>r\t%0,%2
6015 slb<g>\t%0,%2"
6016 [(set_attr "op_type" "RRE,RXY")
6017 (set_attr "z10prop" "z10_c,*")])
6018
6019 (define_expand "add<mode>cc"
6020 [(match_operand:GPR 0 "register_operand" "")
6021 (match_operand 1 "comparison_operator" "")
6022 (match_operand:GPR 2 "register_operand" "")
6023 (match_operand:GPR 3 "const_int_operand" "")]
6024 "TARGET_CPU_ZARCH"
6025 "if (!s390_expand_addcc (GET_CODE (operands[1]),
6026 XEXP (operands[1], 0), XEXP (operands[1], 1),
6027 operands[0], operands[2],
6028 operands[3])) FAIL; DONE;")
6029
6030 ;
6031 ; scond instruction pattern(s).
6032 ;
6033
6034 (define_insn_and_split "*scond<mode>"
6035 [(set (match_operand:GPR 0 "register_operand" "=&d")
6036 (match_operand:GPR 1 "s390_alc_comparison" ""))
6037 (clobber (reg:CC CC_REGNUM))]
6038 "TARGET_CPU_ZARCH"
6039 "#"
6040 "&& reload_completed"
6041 [(set (match_dup 0) (const_int 0))
6042 (parallel
6043 [(set (match_dup 0) (plus:GPR (plus:GPR (match_dup 1) (match_dup 0))
6044 (match_dup 0)))
6045 (clobber (reg:CC CC_REGNUM))])]
6046 "")
6047
6048 (define_insn_and_split "*scond<mode>_neg"
6049 [(set (match_operand:GPR 0 "register_operand" "=&d")
6050 (match_operand:GPR 1 "s390_slb_comparison" ""))
6051 (clobber (reg:CC CC_REGNUM))]
6052 "TARGET_CPU_ZARCH"
6053 "#"
6054 "&& reload_completed"
6055 [(set (match_dup 0) (const_int 0))
6056 (parallel
6057 [(set (match_dup 0) (minus:GPR (minus:GPR (match_dup 0) (match_dup 0))
6058 (match_dup 1)))
6059 (clobber (reg:CC CC_REGNUM))])
6060 (parallel
6061 [(set (match_dup 0) (neg:GPR (match_dup 0)))
6062 (clobber (reg:CC CC_REGNUM))])]
6063 "")
6064
6065
6066 (define_expand "cstore<mode>4"
6067 [(set (match_operand:SI 0 "register_operand" "")
6068 (match_operator:SI 1 "s390_scond_operator"
6069 [(match_operand:GPR 2 "register_operand" "")
6070 (match_operand:GPR 3 "general_operand" "")]))]
6071 "TARGET_CPU_ZARCH"
6072 "if (!s390_expand_addcc (GET_CODE (operands[1]), operands[2], operands[3],
6073 operands[0], const0_rtx, const1_rtx)) FAIL; DONE;")
6074
6075 (define_expand "cstorecc4"
6076 [(parallel
6077 [(set (match_operand:SI 0 "register_operand" "")
6078 (match_operator:SI 1 "s390_eqne_operator"
6079 [(match_operand:CCZ1 2 "register_operand")
6080 (match_operand 3 "const0_operand")]))
6081 (clobber (reg:CC CC_REGNUM))])]
6082 ""
6083 "emit_insn (gen_sne (operands[0], operands[2]));
6084 if (GET_CODE (operands[1]) == EQ)
6085 emit_insn (gen_xorsi3 (operands[0], operands[0], const1_rtx));
6086 DONE;")
6087
6088 (define_insn_and_split "sne"
6089 [(set (match_operand:SI 0 "register_operand" "=d")
6090 (ne:SI (match_operand:CCZ1 1 "register_operand" "0")
6091 (const_int 0)))
6092 (clobber (reg:CC CC_REGNUM))]
6093 ""
6094 "#"
6095 "reload_completed"
6096 [(parallel
6097 [(set (match_dup 0) (ashiftrt:SI (match_dup 0) (const_int 28)))
6098 (clobber (reg:CC CC_REGNUM))])])
6099
6100
6101 ;;
6102 ;; - Conditional move instructions (introduced with z196)
6103 ;;
6104
6105 (define_expand "mov<mode>cc"
6106 [(set (match_operand:GPR 0 "nonimmediate_operand" "")
6107 (if_then_else:GPR (match_operand 1 "comparison_operator" "")
6108 (match_operand:GPR 2 "nonimmediate_operand" "")
6109 (match_operand:GPR 3 "nonimmediate_operand" "")))]
6110 "TARGET_Z196"
6111 {
6112 /* Emit the comparison insn in case we do not already have a comparison result. */
6113 if (!s390_comparison (operands[1], VOIDmode))
6114 operands[1] = s390_emit_compare (GET_CODE (operands[1]),
6115 XEXP (operands[1], 0),
6116 XEXP (operands[1], 1));
6117 })
6118
6119 ; locr, loc, stoc, locgr, locg, stocg
6120 (define_insn_and_split "*mov<mode>cc"
6121 [(set (match_operand:GPR 0 "nonimmediate_operand" "=d,d, d, d,QS,QS,&d")
6122 (if_then_else:GPR
6123 (match_operator 1 "s390_comparison"
6124 [(match_operand 2 "cc_reg_operand" " c,c, c, c, c, c, c")
6125 (match_operand 5 "const_int_operand" "")])
6126 (match_operand:GPR 3 "nonimmediate_operand" " d,0,QS, 0, d, 0,QS")
6127 (match_operand:GPR 4 "nonimmediate_operand" " 0,d, 0,QS, 0, d,QS")))]
6128 "TARGET_Z196"
6129 "@
6130 loc<g>r%C1\t%0,%3
6131 loc<g>r%D1\t%0,%4
6132 loc<g>%C1\t%0,%3
6133 loc<g>%D1\t%0,%4
6134 stoc<g>%C1\t%3,%0
6135 stoc<g>%D1\t%4,%0
6136 #"
6137 "&& reload_completed
6138 && MEM_P (operands[3]) && MEM_P (operands[4])"
6139 [(set (match_dup 0)
6140 (if_then_else:GPR
6141 (match_op_dup 1 [(match_dup 2) (const_int 0)])
6142 (match_dup 3)
6143 (match_dup 0)))
6144 (set (match_dup 0)
6145 (if_then_else:GPR
6146 (match_op_dup 1 [(match_dup 2) (const_int 0)])
6147 (match_dup 0)
6148 (match_dup 4)))]
6149 ""
6150 [(set_attr "op_type" "RRF,RRF,RSY,RSY,RSY,RSY,*")])
6151
6152 ;;
6153 ;;- Multiply instructions.
6154 ;;
6155
6156 ;
6157 ; muldi3 instruction pattern(s).
6158 ;
6159
6160 (define_insn "*muldi3_sign"
6161 [(set (match_operand:DI 0 "register_operand" "=d,d")
6162 (mult:DI (sign_extend:DI (match_operand:SI 2 "general_operand" "d,RT"))
6163 (match_operand:DI 1 "register_operand" "0,0")))]
6164 "TARGET_ZARCH"
6165 "@
6166 msgfr\t%0,%2
6167 msgf\t%0,%2"
6168 [(set_attr "op_type" "RRE,RXY")
6169 (set_attr "type" "imuldi")])
6170
6171 (define_insn "muldi3"
6172 [(set (match_operand:DI 0 "register_operand" "=d,d,d,d")
6173 (mult:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,0")
6174 (match_operand:DI 2 "general_operand" "d,K,RT,Os")))]
6175 "TARGET_ZARCH"
6176 "@
6177 msgr\t%0,%2
6178 mghi\t%0,%h2
6179 msg\t%0,%2
6180 msgfi\t%0,%2"
6181 [(set_attr "op_type" "RRE,RI,RXY,RIL")
6182 (set_attr "type" "imuldi")
6183 (set_attr "cpu_facility" "*,*,*,z10")])
6184
6185 ;
6186 ; mulsi3 instruction pattern(s).
6187 ;
6188
6189 (define_insn "*mulsi3_sign"
6190 [(set (match_operand:SI 0 "register_operand" "=d,d")
6191 (mult:SI (sign_extend:SI (match_operand:HI 2 "memory_operand" "R,T"))
6192 (match_operand:SI 1 "register_operand" "0,0")))]
6193 ""
6194 "@
6195 mh\t%0,%2
6196 mhy\t%0,%2"
6197 [(set_attr "op_type" "RX,RXY")
6198 (set_attr "type" "imulhi")
6199 (set_attr "cpu_facility" "*,z10")])
6200
6201 (define_insn "mulsi3"
6202 [(set (match_operand:SI 0 "register_operand" "=d,d,d,d,d")
6203 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,0,0,0")
6204 (match_operand:SI 2 "general_operand" "d,K,R,T,Os")))]
6205 ""
6206 "@
6207 msr\t%0,%2
6208 mhi\t%0,%h2
6209 ms\t%0,%2
6210 msy\t%0,%2
6211 msfi\t%0,%2"
6212 [(set_attr "op_type" "RRE,RI,RX,RXY,RIL")
6213 (set_attr "type" "imulsi,imulhi,imulsi,imulsi,imulsi")
6214 (set_attr "cpu_facility" "*,*,*,*,z10")])
6215
6216 ;
6217 ; mulsidi3 instruction pattern(s).
6218 ;
6219
6220 (define_insn "mulsidi3"
6221 [(set (match_operand:DI 0 "register_operand" "=d,d,d")
6222 (mult:DI (sign_extend:DI
6223 (match_operand:SI 1 "register_operand" "%0,0,0"))
6224 (sign_extend:DI
6225 (match_operand:SI 2 "nonimmediate_operand" "d,R,T"))))]
6226 "!TARGET_ZARCH"
6227 "@
6228 mr\t%0,%2
6229 m\t%0,%2
6230 mfy\t%0,%2"
6231 [(set_attr "op_type" "RR,RX,RXY")
6232 (set_attr "type" "imulsi")
6233 (set_attr "cpu_facility" "*,*,z10")])
6234
6235 ;
6236 ; umul instruction pattern(s).
6237 ;
6238
6239 ; mlr, ml, mlgr, mlg
6240 (define_insn "umul<dwh><mode>3"
6241 [(set (match_operand:DW 0 "register_operand" "=d, d")
6242 (mult:DW (zero_extend:DW
6243 (match_operand:<DWH> 1 "register_operand" "%0, 0"))
6244 (zero_extend:DW
6245 (match_operand:<DWH> 2 "nonimmediate_operand" " d,RT"))))]
6246 "TARGET_CPU_ZARCH"
6247 "@
6248 ml<tg>r\t%0,%2
6249 ml<tg>\t%0,%2"
6250 [(set_attr "op_type" "RRE,RXY")
6251 (set_attr "type" "imul<dwh>")])
6252
6253 ;
6254 ; mul(tf|df|sf|td|dd)3 instruction pattern(s).
6255 ;
6256
6257 ; mxbr, mdbr, meebr, mxb, mxb, meeb, mdtr, mxtr
6258 (define_insn "mul<mode>3"
6259 [(set (match_operand:FP 0 "register_operand" "=f, f,<vf>")
6260 (mult:FP (match_operand:FP 1 "nonimmediate_operand" "%<f0>, 0,<v0>")
6261 (match_operand:FP 2 "general_operand" "f,<Rf>,<vf>")))]
6262 "TARGET_HARD_FLOAT"
6263 "@
6264 m<xdee><bt>r\t%0,<op1>%2
6265 m<xdee>b\t%0,%2
6266 wfmdb\t%v0,%v1,%v2"
6267 [(set_attr "op_type" "<RRer>,RXE,VRR")
6268 (set_attr "type" "fmul<mode>")
6269 (set_attr "cpu_facility" "*,*,vec")])
6270
6271 ; madbr, maebr, maxb, madb, maeb
6272 (define_insn "fma<mode>4"
6273 [(set (match_operand:DSF 0 "register_operand" "=f,f,<vf>")
6274 (fma:DSF (match_operand:DSF 1 "nonimmediate_operand" "%f,f,<vf>")
6275 (match_operand:DSF 2 "nonimmediate_operand" "f,R,<vf>")
6276 (match_operand:DSF 3 "register_operand" "0,0,<v0>")))]
6277 "TARGET_HARD_FLOAT"
6278 "@
6279 ma<xde>br\t%0,%1,%2
6280 ma<xde>b\t%0,%1,%2
6281 wfmadb\t%v0,%v1,%v2,%v3"
6282 [(set_attr "op_type" "RRE,RXE,VRR")
6283 (set_attr "type" "fmadd<mode>")
6284 (set_attr "cpu_facility" "*,*,vec")])
6285
6286 ; msxbr, msdbr, msebr, msxb, msdb, mseb
6287 (define_insn "fms<mode>4"
6288 [(set (match_operand:DSF 0 "register_operand" "=f,f,<vf>")
6289 (fma:DSF (match_operand:DSF 1 "nonimmediate_operand" "%f,f,<vf>")
6290 (match_operand:DSF 2 "nonimmediate_operand" "f,R,<vf>")
6291 (neg:DSF (match_operand:DSF 3 "register_operand" "0,0,<v0>"))))]
6292 "TARGET_HARD_FLOAT"
6293 "@
6294 ms<xde>br\t%0,%1,%2
6295 ms<xde>b\t%0,%1,%2
6296 wfmsdb\t%v0,%v1,%v2,%v3"
6297 [(set_attr "op_type" "RRE,RXE,VRR")
6298 (set_attr "type" "fmadd<mode>")
6299 (set_attr "cpu_facility" "*,*,vec")])
6300
6301 ;;
6302 ;;- Divide and modulo instructions.
6303 ;;
6304
6305 ;
6306 ; divmoddi4 instruction pattern(s).
6307 ;
6308
6309 (define_expand "divmoddi4"
6310 [(parallel [(set (match_operand:DI 0 "general_operand" "")
6311 (div:DI (match_operand:DI 1 "register_operand" "")
6312 (match_operand:DI 2 "general_operand" "")))
6313 (set (match_operand:DI 3 "general_operand" "")
6314 (mod:DI (match_dup 1) (match_dup 2)))])
6315 (clobber (match_dup 4))]
6316 "TARGET_ZARCH"
6317 {
6318 rtx insn, div_equal, mod_equal;
6319
6320 div_equal = gen_rtx_DIV (DImode, operands[1], operands[2]);
6321 mod_equal = gen_rtx_MOD (DImode, operands[1], operands[2]);
6322
6323 operands[4] = gen_reg_rtx(TImode);
6324 emit_insn (gen_divmodtidi3 (operands[4], operands[1], operands[2]));
6325
6326 insn = emit_move_insn (operands[0], gen_lowpart (DImode, operands[4]));
6327 set_unique_reg_note (insn, REG_EQUAL, div_equal);
6328
6329 insn = emit_move_insn (operands[3], gen_highpart (DImode, operands[4]));
6330 set_unique_reg_note (insn, REG_EQUAL, mod_equal);
6331
6332 DONE;
6333 })
6334
6335 (define_insn "divmodtidi3"
6336 [(set (match_operand:TI 0 "register_operand" "=d,d")
6337 (ior:TI
6338 (ashift:TI
6339 (zero_extend:TI
6340 (mod:DI (match_operand:DI 1 "register_operand" "0,0")
6341 (match_operand:DI 2 "general_operand" "d,RT")))
6342 (const_int 64))
6343 (zero_extend:TI (div:DI (match_dup 1) (match_dup 2)))))]
6344 "TARGET_ZARCH"
6345 "@
6346 dsgr\t%0,%2
6347 dsg\t%0,%2"
6348 [(set_attr "op_type" "RRE,RXY")
6349 (set_attr "type" "idiv")])
6350
6351 (define_insn "divmodtisi3"
6352 [(set (match_operand:TI 0 "register_operand" "=d,d")
6353 (ior:TI
6354 (ashift:TI
6355 (zero_extend:TI
6356 (mod:DI (match_operand:DI 1 "register_operand" "0,0")
6357 (sign_extend:DI
6358 (match_operand:SI 2 "nonimmediate_operand" "d,RT"))))
6359 (const_int 64))
6360 (zero_extend:TI
6361 (div:DI (match_dup 1) (sign_extend:DI (match_dup 2))))))]
6362 "TARGET_ZARCH"
6363 "@
6364 dsgfr\t%0,%2
6365 dsgf\t%0,%2"
6366 [(set_attr "op_type" "RRE,RXY")
6367 (set_attr "type" "idiv")])
6368
6369 ;
6370 ; udivmoddi4 instruction pattern(s).
6371 ;
6372
6373 (define_expand "udivmoddi4"
6374 [(parallel [(set (match_operand:DI 0 "general_operand" "")
6375 (udiv:DI (match_operand:DI 1 "general_operand" "")
6376 (match_operand:DI 2 "nonimmediate_operand" "")))
6377 (set (match_operand:DI 3 "general_operand" "")
6378 (umod:DI (match_dup 1) (match_dup 2)))])
6379 (clobber (match_dup 4))]
6380 "TARGET_ZARCH"
6381 {
6382 rtx insn, div_equal, mod_equal, equal;
6383
6384 div_equal = gen_rtx_UDIV (DImode, operands[1], operands[2]);
6385 mod_equal = gen_rtx_UMOD (DImode, operands[1], operands[2]);
6386 equal = gen_rtx_IOR (TImode,
6387 gen_rtx_ASHIFT (TImode,
6388 gen_rtx_ZERO_EXTEND (TImode, mod_equal),
6389 GEN_INT (64)),
6390 gen_rtx_ZERO_EXTEND (TImode, div_equal));
6391
6392 operands[4] = gen_reg_rtx(TImode);
6393 emit_clobber (operands[4]);
6394 emit_move_insn (gen_lowpart (DImode, operands[4]), operands[1]);
6395 emit_move_insn (gen_highpart (DImode, operands[4]), const0_rtx);
6396
6397 insn = emit_insn (gen_udivmodtidi3 (operands[4], operands[4], operands[2]));
6398 set_unique_reg_note (insn, REG_EQUAL, equal);
6399
6400 insn = emit_move_insn (operands[0], gen_lowpart (DImode, operands[4]));
6401 set_unique_reg_note (insn, REG_EQUAL, div_equal);
6402
6403 insn = emit_move_insn (operands[3], gen_highpart (DImode, operands[4]));
6404 set_unique_reg_note (insn, REG_EQUAL, mod_equal);
6405
6406 DONE;
6407 })
6408
6409 (define_insn "udivmodtidi3"
6410 [(set (match_operand:TI 0 "register_operand" "=d,d")
6411 (ior:TI
6412 (ashift:TI
6413 (zero_extend:TI
6414 (truncate:DI
6415 (umod:TI (match_operand:TI 1 "register_operand" "0,0")
6416 (zero_extend:TI
6417 (match_operand:DI 2 "nonimmediate_operand" "d,RT")))))
6418 (const_int 64))
6419 (zero_extend:TI
6420 (truncate:DI
6421 (udiv:TI (match_dup 1) (zero_extend:TI (match_dup 2)))))))]
6422 "TARGET_ZARCH"
6423 "@
6424 dlgr\t%0,%2
6425 dlg\t%0,%2"
6426 [(set_attr "op_type" "RRE,RXY")
6427 (set_attr "type" "idiv")])
6428
6429 ;
6430 ; divmodsi4 instruction pattern(s).
6431 ;
6432
6433 (define_expand "divmodsi4"
6434 [(parallel [(set (match_operand:SI 0 "general_operand" "")
6435 (div:SI (match_operand:SI 1 "general_operand" "")
6436 (match_operand:SI 2 "nonimmediate_operand" "")))
6437 (set (match_operand:SI 3 "general_operand" "")
6438 (mod:SI (match_dup 1) (match_dup 2)))])
6439 (clobber (match_dup 4))]
6440 "!TARGET_ZARCH"
6441 {
6442 rtx insn, div_equal, mod_equal, equal;
6443
6444 div_equal = gen_rtx_DIV (SImode, operands[1], operands[2]);
6445 mod_equal = gen_rtx_MOD (SImode, operands[1], operands[2]);
6446 equal = gen_rtx_IOR (DImode,
6447 gen_rtx_ASHIFT (DImode,
6448 gen_rtx_ZERO_EXTEND (DImode, mod_equal),
6449 GEN_INT (32)),
6450 gen_rtx_ZERO_EXTEND (DImode, div_equal));
6451
6452 operands[4] = gen_reg_rtx(DImode);
6453 emit_insn (gen_extendsidi2 (operands[4], operands[1]));
6454
6455 insn = emit_insn (gen_divmoddisi3 (operands[4], operands[4], operands[2]));
6456 set_unique_reg_note (insn, REG_EQUAL, equal);
6457
6458 insn = emit_move_insn (operands[0], gen_lowpart (SImode, operands[4]));
6459 set_unique_reg_note (insn, REG_EQUAL, div_equal);
6460
6461 insn = emit_move_insn (operands[3], gen_highpart (SImode, operands[4]));
6462 set_unique_reg_note (insn, REG_EQUAL, mod_equal);
6463
6464 DONE;
6465 })
6466
6467 (define_insn "divmoddisi3"
6468 [(set (match_operand:DI 0 "register_operand" "=d,d")
6469 (ior:DI
6470 (ashift:DI
6471 (zero_extend:DI
6472 (truncate:SI
6473 (mod:DI (match_operand:DI 1 "register_operand" "0,0")
6474 (sign_extend:DI
6475 (match_operand:SI 2 "nonimmediate_operand" "d,R")))))
6476 (const_int 32))
6477 (zero_extend:DI
6478 (truncate:SI
6479 (div:DI (match_dup 1) (sign_extend:DI (match_dup 2)))))))]
6480 "!TARGET_ZARCH"
6481 "@
6482 dr\t%0,%2
6483 d\t%0,%2"
6484 [(set_attr "op_type" "RR,RX")
6485 (set_attr "type" "idiv")])
6486
6487 ;
6488 ; udivsi3 and umodsi3 instruction pattern(s).
6489 ;
6490
6491 (define_expand "udivmodsi4"
6492 [(parallel [(set (match_operand:SI 0 "general_operand" "")
6493 (udiv:SI (match_operand:SI 1 "general_operand" "")
6494 (match_operand:SI 2 "nonimmediate_operand" "")))
6495 (set (match_operand:SI 3 "general_operand" "")
6496 (umod:SI (match_dup 1) (match_dup 2)))])
6497 (clobber (match_dup 4))]
6498 "!TARGET_ZARCH && TARGET_CPU_ZARCH"
6499 {
6500 rtx insn, div_equal, mod_equal, equal;
6501
6502 div_equal = gen_rtx_UDIV (SImode, operands[1], operands[2]);
6503 mod_equal = gen_rtx_UMOD (SImode, operands[1], operands[2]);
6504 equal = gen_rtx_IOR (DImode,
6505 gen_rtx_ASHIFT (DImode,
6506 gen_rtx_ZERO_EXTEND (DImode, mod_equal),
6507 GEN_INT (32)),
6508 gen_rtx_ZERO_EXTEND (DImode, div_equal));
6509
6510 operands[4] = gen_reg_rtx(DImode);
6511 emit_clobber (operands[4]);
6512 emit_move_insn (gen_lowpart (SImode, operands[4]), operands[1]);
6513 emit_move_insn (gen_highpart (SImode, operands[4]), const0_rtx);
6514
6515 insn = emit_insn (gen_udivmoddisi3 (operands[4], operands[4], operands[2]));
6516 set_unique_reg_note (insn, REG_EQUAL, equal);
6517
6518 insn = emit_move_insn (operands[0], gen_lowpart (SImode, operands[4]));
6519 set_unique_reg_note (insn, REG_EQUAL, div_equal);
6520
6521 insn = emit_move_insn (operands[3], gen_highpart (SImode, operands[4]));
6522 set_unique_reg_note (insn, REG_EQUAL, mod_equal);
6523
6524 DONE;
6525 })
6526
6527 (define_insn "udivmoddisi3"
6528 [(set (match_operand:DI 0 "register_operand" "=d,d")
6529 (ior:DI
6530 (ashift:DI
6531 (zero_extend:DI
6532 (truncate:SI
6533 (umod:DI (match_operand:DI 1 "register_operand" "0,0")
6534 (zero_extend:DI
6535 (match_operand:SI 2 "nonimmediate_operand" "d,RT")))))
6536 (const_int 32))
6537 (zero_extend:DI
6538 (truncate:SI
6539 (udiv:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))))]
6540 "!TARGET_ZARCH && TARGET_CPU_ZARCH"
6541 "@
6542 dlr\t%0,%2
6543 dl\t%0,%2"
6544 [(set_attr "op_type" "RRE,RXY")
6545 (set_attr "type" "idiv")])
6546
6547 (define_expand "udivsi3"
6548 [(set (match_operand:SI 0 "register_operand" "=d")
6549 (udiv:SI (match_operand:SI 1 "general_operand" "")
6550 (match_operand:SI 2 "general_operand" "")))
6551 (clobber (match_dup 3))]
6552 "!TARGET_ZARCH && !TARGET_CPU_ZARCH"
6553 {
6554 rtx insn, udiv_equal, umod_equal, equal;
6555
6556 udiv_equal = gen_rtx_UDIV (SImode, operands[1], operands[2]);
6557 umod_equal = gen_rtx_UMOD (SImode, operands[1], operands[2]);
6558 equal = gen_rtx_IOR (DImode,
6559 gen_rtx_ASHIFT (DImode,
6560 gen_rtx_ZERO_EXTEND (DImode, umod_equal),
6561 GEN_INT (32)),
6562 gen_rtx_ZERO_EXTEND (DImode, udiv_equal));
6563
6564 operands[3] = gen_reg_rtx (DImode);
6565
6566 if (CONSTANT_P (operands[2]))
6567 {
6568 if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0)
6569 {
6570 rtx_code_label *label1 = gen_label_rtx ();
6571
6572 operands[1] = make_safe_from (operands[1], operands[0]);
6573 emit_move_insn (operands[0], const0_rtx);
6574 emit_cmp_and_jump_insns (operands[1], operands[2], LT, NULL_RTX,
6575 SImode, 1, label1);
6576 emit_move_insn (operands[0], const1_rtx);
6577 emit_label (label1);
6578 }
6579 else
6580 {
6581 operands[2] = force_reg (SImode, operands[2]);
6582 operands[2] = make_safe_from (operands[2], operands[0]);
6583
6584 emit_insn (gen_zero_extendsidi2 (operands[3], operands[1]));
6585 insn = emit_insn (gen_divmoddisi3 (operands[3], operands[3],
6586 operands[2]));
6587 set_unique_reg_note (insn, REG_EQUAL, equal);
6588
6589 insn = emit_move_insn (operands[0],
6590 gen_lowpart (SImode, operands[3]));
6591 set_unique_reg_note (insn, REG_EQUAL, udiv_equal);
6592 }
6593 }
6594 else
6595 {
6596 rtx_code_label *label1 = gen_label_rtx ();
6597 rtx_code_label *label2 = gen_label_rtx ();
6598 rtx_code_label *label3 = gen_label_rtx ();
6599
6600 operands[1] = force_reg (SImode, operands[1]);
6601 operands[1] = make_safe_from (operands[1], operands[0]);
6602 operands[2] = force_reg (SImode, operands[2]);
6603 operands[2] = make_safe_from (operands[2], operands[0]);
6604
6605 emit_move_insn (operands[0], const0_rtx);
6606 emit_cmp_and_jump_insns (operands[2], operands[1], GT, NULL_RTX,
6607 SImode, 1, label3);
6608 emit_cmp_and_jump_insns (operands[2], const0_rtx, LT, NULL_RTX,
6609 SImode, 0, label2);
6610 emit_cmp_and_jump_insns (operands[2], const1_rtx, EQ, NULL_RTX,
6611 SImode, 0, label1);
6612 emit_insn (gen_zero_extendsidi2 (operands[3], operands[1]));
6613 insn = emit_insn (gen_divmoddisi3 (operands[3], operands[3],
6614 operands[2]));
6615 set_unique_reg_note (insn, REG_EQUAL, equal);
6616
6617 insn = emit_move_insn (operands[0],
6618 gen_lowpart (SImode, operands[3]));
6619 set_unique_reg_note (insn, REG_EQUAL, udiv_equal);
6620
6621 emit_jump (label3);
6622 emit_label (label1);
6623 emit_move_insn (operands[0], operands[1]);
6624 emit_jump (label3);
6625 emit_label (label2);
6626 emit_move_insn (operands[0], const1_rtx);
6627 emit_label (label3);
6628 }
6629 emit_move_insn (operands[0], operands[0]);
6630 DONE;
6631 })
6632
6633 (define_expand "umodsi3"
6634 [(set (match_operand:SI 0 "register_operand" "=d")
6635 (umod:SI (match_operand:SI 1 "nonimmediate_operand" "")
6636 (match_operand:SI 2 "nonimmediate_operand" "")))
6637 (clobber (match_dup 3))]
6638 "!TARGET_ZARCH && !TARGET_CPU_ZARCH"
6639 {
6640 rtx insn, udiv_equal, umod_equal, equal;
6641
6642 udiv_equal = gen_rtx_UDIV (SImode, operands[1], operands[2]);
6643 umod_equal = gen_rtx_UMOD (SImode, operands[1], operands[2]);
6644 equal = gen_rtx_IOR (DImode,
6645 gen_rtx_ASHIFT (DImode,
6646 gen_rtx_ZERO_EXTEND (DImode, umod_equal),
6647 GEN_INT (32)),
6648 gen_rtx_ZERO_EXTEND (DImode, udiv_equal));
6649
6650 operands[3] = gen_reg_rtx (DImode);
6651
6652 if (CONSTANT_P (operands[2]))
6653 {
6654 if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) <= 0)
6655 {
6656 rtx_code_label *label1 = gen_label_rtx ();
6657
6658 operands[1] = make_safe_from (operands[1], operands[0]);
6659 emit_move_insn (operands[0], operands[1]);
6660 emit_cmp_and_jump_insns (operands[0], operands[2], LT, NULL_RTX,
6661 SImode, 1, label1);
6662 emit_insn (gen_abssi2 (operands[0], operands[2]));
6663 emit_insn (gen_addsi3 (operands[0], operands[0], operands[1]));
6664 emit_label (label1);
6665 }
6666 else
6667 {
6668 operands[2] = force_reg (SImode, operands[2]);
6669 operands[2] = make_safe_from (operands[2], operands[0]);
6670
6671 emit_insn (gen_zero_extendsidi2 (operands[3], operands[1]));
6672 insn = emit_insn (gen_divmoddisi3 (operands[3], operands[3],
6673 operands[2]));
6674 set_unique_reg_note (insn, REG_EQUAL, equal);
6675
6676 insn = emit_move_insn (operands[0],
6677 gen_highpart (SImode, operands[3]));
6678 set_unique_reg_note (insn, REG_EQUAL, umod_equal);
6679 }
6680 }
6681 else
6682 {
6683 rtx_code_label *label1 = gen_label_rtx ();
6684 rtx_code_label *label2 = gen_label_rtx ();
6685 rtx_code_label *label3 = gen_label_rtx ();
6686
6687 operands[1] = force_reg (SImode, operands[1]);
6688 operands[1] = make_safe_from (operands[1], operands[0]);
6689 operands[2] = force_reg (SImode, operands[2]);
6690 operands[2] = make_safe_from (operands[2], operands[0]);
6691
6692 emit_move_insn(operands[0], operands[1]);
6693 emit_cmp_and_jump_insns (operands[2], operands[1], GT, NULL_RTX,
6694 SImode, 1, label3);
6695 emit_cmp_and_jump_insns (operands[2], const0_rtx, LT, NULL_RTX,
6696 SImode, 0, label2);
6697 emit_cmp_and_jump_insns (operands[2], const1_rtx, EQ, NULL_RTX,
6698 SImode, 0, label1);
6699 emit_insn (gen_zero_extendsidi2 (operands[3], operands[1]));
6700 insn = emit_insn (gen_divmoddisi3 (operands[3], operands[3],
6701 operands[2]));
6702 set_unique_reg_note (insn, REG_EQUAL, equal);
6703
6704 insn = emit_move_insn (operands[0],
6705 gen_highpart (SImode, operands[3]));
6706 set_unique_reg_note (insn, REG_EQUAL, umod_equal);
6707
6708 emit_jump (label3);
6709 emit_label (label1);
6710 emit_move_insn (operands[0], const0_rtx);
6711 emit_jump (label3);
6712 emit_label (label2);
6713 emit_insn (gen_subsi3 (operands[0], operands[0], operands[2]));
6714 emit_label (label3);
6715 }
6716 DONE;
6717 })
6718
6719 ;
6720 ; div(df|sf)3 instruction pattern(s).
6721 ;
6722
6723 ; dxbr, ddbr, debr, dxb, ddb, deb, ddtr, dxtr
6724 (define_insn "div<mode>3"
6725 [(set (match_operand:FP 0 "register_operand" "=f, f,<vf>")
6726 (div:FP (match_operand:FP 1 "register_operand" "<f0>, 0,<v0>")
6727 (match_operand:FP 2 "general_operand" "f,<Rf>,<vf>")))]
6728 "TARGET_HARD_FLOAT"
6729 "@
6730 d<xde><bt>r\t%0,<op1>%2
6731 d<xde>b\t%0,%2
6732 wfddb\t%v0,%v1,%v2"
6733 [(set_attr "op_type" "<RRer>,RXE,VRR")
6734 (set_attr "type" "fdiv<mode>")
6735 (set_attr "cpu_facility" "*,*,vec")])
6736
6737
6738 ;;
6739 ;;- And instructions.
6740 ;;
6741
6742 (define_expand "and<mode>3"
6743 [(set (match_operand:INT 0 "nonimmediate_operand" "")
6744 (and:INT (match_operand:INT 1 "nonimmediate_operand" "")
6745 (match_operand:INT 2 "general_operand" "")))
6746 (clobber (reg:CC CC_REGNUM))]
6747 ""
6748 "s390_expand_logical_operator (AND, <MODE>mode, operands); DONE;")
6749
6750 ;
6751 ; anddi3 instruction pattern(s).
6752 ;
6753
6754 (define_insn "*anddi3_cc"
6755 [(set (reg CC_REGNUM)
6756 (compare
6757 (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,d, 0, d")
6758 (match_operand:DI 2 "general_operand" " d,d,RT,NxxDq"))
6759 (const_int 0)))
6760 (set (match_operand:DI 0 "register_operand" "=d,d, d, d")
6761 (and:DI (match_dup 1) (match_dup 2)))]
6762 "TARGET_ZARCH && s390_match_ccmode(insn, CCTmode)"
6763 "@
6764 ngr\t%0,%2
6765 ngrk\t%0,%1,%2
6766 ng\t%0,%2
6767 risbg\t%0,%1,%s2,128+%e2,0"
6768 [(set_attr "op_type" "RRE,RRF,RXY,RIE")
6769 (set_attr "cpu_facility" "*,z196,*,z10")
6770 (set_attr "z10prop" "z10_super_E1,*,z10_super_E1,z10_super_E1")])
6771
6772 (define_insn "*anddi3_cconly"
6773 [(set (reg CC_REGNUM)
6774 (compare
6775 (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,d, 0, d")
6776 (match_operand:DI 2 "general_operand" " d,d,RT,NxxDq"))
6777 (const_int 0)))
6778 (clobber (match_scratch:DI 0 "=d,d, d, d"))]
6779 "TARGET_ZARCH
6780 && s390_match_ccmode(insn, CCTmode)
6781 /* Do not steal TM patterns. */
6782 && s390_single_part (operands[2], DImode, HImode, 0) < 0"
6783 "@
6784 ngr\t%0,%2
6785 ngrk\t%0,%1,%2
6786 ng\t%0,%2
6787 risbg\t%0,%1,%s2,128+%e2,0"
6788 [(set_attr "op_type" "RRE,RRF,RXY,RIE")
6789 (set_attr "cpu_facility" "*,z196,*,z10")
6790 (set_attr "z10prop" "z10_super_E1,*,z10_super_E1,z10_super_E1")])
6791
6792 (define_insn "*anddi3"
6793 [(set (match_operand:DI 0 "nonimmediate_operand"
6794 "=d,d, d, d, d, d, d, d,d,d, d, d, AQ,Q")
6795 (and:DI
6796 (match_operand:DI 1 "nonimmediate_operand"
6797 "%d,o, 0, 0, 0, 0, 0, 0,0,d, 0, d, 0,0")
6798 (match_operand:DI 2 "general_operand"
6799 "M, M,N0HDF,N1HDF,N2HDF,N3HDF,N0SDF,N1SDF,d,d,RT,NxxDq,NxQDF,Q")))
6800 (clobber (reg:CC CC_REGNUM))]
6801 "TARGET_ZARCH && s390_logical_operator_ok_p (operands)"
6802 "@
6803 #
6804 #
6805 nihh\t%0,%j2
6806 nihl\t%0,%j2
6807 nilh\t%0,%j2
6808 nill\t%0,%j2
6809 nihf\t%0,%m2
6810 nilf\t%0,%m2
6811 ngr\t%0,%2
6812 ngrk\t%0,%1,%2
6813 ng\t%0,%2
6814 risbg\t%0,%1,%s2,128+%e2,0
6815 #
6816 #"
6817 [(set_attr "op_type" "RRE,RXE,RI,RI,RI,RI,RIL,RIL,RRE,RRF,RXY,RIE,SI,SS")
6818 (set_attr "cpu_facility" "*,*,*,*,*,*,extimm,extimm,*,z196,*,z10,*,*")
6819 (set_attr "z10prop" "*,
6820 *,
6821 z10_super_E1,
6822 z10_super_E1,
6823 z10_super_E1,
6824 z10_super_E1,
6825 z10_super_E1,
6826 z10_super_E1,
6827 z10_super_E1,
6828 *,
6829 z10_super_E1,
6830 z10_super_E1,
6831 *,
6832 *")])
6833
6834 (define_split
6835 [(set (match_operand:DI 0 "s_operand" "")
6836 (and:DI (match_dup 0) (match_operand:DI 1 "immediate_operand" "")))
6837 (clobber (reg:CC CC_REGNUM))]
6838 "reload_completed"
6839 [(parallel
6840 [(set (match_dup 0) (and:QI (match_dup 0) (match_dup 1)))
6841 (clobber (reg:CC CC_REGNUM))])]
6842 "s390_narrow_logical_operator (AND, &operands[0], &operands[1]);")
6843
6844 ;; These two are what combine generates for (ashift (zero_extract)).
6845 (define_insn "*extzv_<mode>_srl"
6846 [(set (match_operand:GPR 0 "register_operand" "=d")
6847 (and:GPR (lshiftrt:GPR
6848 (match_operand:GPR 1 "register_operand" "d")
6849 (match_operand:GPR 2 "nonzero_shift_count_operand" ""))
6850 (match_operand:GPR 3 "contiguous_bitmask_operand" "")))
6851 (clobber (reg:CC CC_REGNUM))]
6852 "TARGET_Z10
6853 /* Note that even for the SImode pattern, the rotate is always DImode. */
6854 && s390_extzv_shift_ok (<bitsize>, -INTVAL (operands[2]),
6855 INTVAL (operands[3]))"
6856 "risbg\t%0,%1,%<bfstart>3,128+%<bfend>3,64-%2"
6857 [(set_attr "op_type" "RIE")
6858 (set_attr "z10prop" "z10_super_E1")])
6859
6860 (define_insn "*extzv_<mode>_sll"
6861 [(set (match_operand:GPR 0 "register_operand" "=d")
6862 (and:GPR (ashift:GPR
6863 (match_operand:GPR 1 "register_operand" "d")
6864 (match_operand:GPR 2 "nonzero_shift_count_operand" ""))
6865 (match_operand:GPR 3 "contiguous_bitmask_operand" "")))
6866 (clobber (reg:CC CC_REGNUM))]
6867 "TARGET_Z10
6868 && s390_extzv_shift_ok (<bitsize>, INTVAL (operands[2]),
6869 INTVAL (operands[3]))"
6870 "risbg\t%0,%1,%<bfstart>3,128+%<bfend>3,%2"
6871 [(set_attr "op_type" "RIE")
6872 (set_attr "z10prop" "z10_super_E1")])
6873
6874
6875 ;
6876 ; andsi3 instruction pattern(s).
6877 ;
6878
6879 (define_insn "*andsi3_cc"
6880 [(set (reg CC_REGNUM)
6881 (compare
6882 (and:SI
6883 (match_operand:SI 1 "nonimmediate_operand" "%0,0,d,0,0, d")
6884 (match_operand:SI 2 "general_operand" "Os,d,d,R,T,NxxSq"))
6885 (const_int 0)))
6886 (set (match_operand:SI 0 "register_operand" "=d,d,d,d,d, d")
6887 (and:SI (match_dup 1) (match_dup 2)))]
6888 "s390_match_ccmode(insn, CCTmode)"
6889 "@
6890 nilf\t%0,%o2
6891 nr\t%0,%2
6892 nrk\t%0,%1,%2
6893 n\t%0,%2
6894 ny\t%0,%2
6895 risbg\t%0,%1,%t2,128+%f2,0"
6896 [(set_attr "op_type" "RIL,RR,RRF,RX,RXY,RIE")
6897 (set_attr "cpu_facility" "*,*,z196,*,*,z10")
6898 (set_attr "z10prop" "z10_super_E1,z10_super_E1,*,
6899 z10_super_E1,z10_super_E1,z10_super_E1")])
6900
6901 (define_insn "*andsi3_cconly"
6902 [(set (reg CC_REGNUM)
6903 (compare
6904 (and:SI
6905 (match_operand:SI 1 "nonimmediate_operand" "%0,0,d,0,0, d")
6906 (match_operand:SI 2 "general_operand" "Os,d,d,R,T,NxxSq"))
6907 (const_int 0)))
6908 (clobber (match_scratch:SI 0 "=d,d,d,d,d, d"))]
6909 "s390_match_ccmode(insn, CCTmode)
6910 /* Do not steal TM patterns. */
6911 && s390_single_part (operands[2], SImode, HImode, 0) < 0"
6912 "@
6913 nilf\t%0,%o2
6914 nr\t%0,%2
6915 nrk\t%0,%1,%2
6916 n\t%0,%2
6917 ny\t%0,%2
6918 risbg\t%0,%1,%t2,128+%f2,0"
6919 [(set_attr "op_type" "RIL,RR,RRF,RX,RXY,RIE")
6920 (set_attr "cpu_facility" "*,*,z196,*,*,z10")
6921 (set_attr "z10prop" "z10_super_E1,z10_super_E1,*,
6922 z10_super_E1,z10_super_E1,z10_super_E1")])
6923
6924 (define_insn "*andsi3_zarch"
6925 [(set (match_operand:SI 0 "nonimmediate_operand"
6926 "=d,d, d, d, d,d,d,d,d, d, AQ,Q")
6927 (and:SI (match_operand:SI 1 "nonimmediate_operand"
6928 "%d,o, 0, 0, 0,0,d,0,0, d, 0,0")
6929 (match_operand:SI 2 "general_operand"
6930 " M,M,N0HSF,N1HSF,Os,d,d,R,T,NxxSq,NxQSF,Q")))
6931 (clobber (reg:CC CC_REGNUM))]
6932 "TARGET_ZARCH && s390_logical_operator_ok_p (operands)"
6933 "@
6934 #
6935 #
6936 nilh\t%0,%j2
6937 nill\t%0,%j2
6938 nilf\t%0,%o2
6939 nr\t%0,%2
6940 nrk\t%0,%1,%2
6941 n\t%0,%2
6942 ny\t%0,%2
6943 risbg\t%0,%1,%t2,128+%f2,0
6944 #
6945 #"
6946 [(set_attr "op_type" "RRE,RXE,RI,RI,RIL,RR,RRF,RX,RXY,RIE,SI,SS")
6947 (set_attr "cpu_facility" "*,*,*,*,*,*,z196,*,*,z10,*,*")
6948 (set_attr "z10prop" "*,
6949 *,
6950 z10_super_E1,
6951 z10_super_E1,
6952 z10_super_E1,
6953 z10_super_E1,
6954 *,
6955 z10_super_E1,
6956 z10_super_E1,
6957 z10_super_E1,
6958 *,
6959 *")])
6960
6961 (define_insn "*andsi3_esa"
6962 [(set (match_operand:SI 0 "nonimmediate_operand" "=d,d, AQ,Q")
6963 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0, 0,0")
6964 (match_operand:SI 2 "general_operand" " d,R,NxQSF,Q")))
6965 (clobber (reg:CC CC_REGNUM))]
6966 "!TARGET_ZARCH && s390_logical_operator_ok_p (operands)"
6967 "@
6968 nr\t%0,%2
6969 n\t%0,%2
6970 #
6971 #"
6972 [(set_attr "op_type" "RR,RX,SI,SS")
6973 (set_attr "z10prop" "z10_super_E1,z10_super_E1,*,*")])
6974
6975
6976 (define_split
6977 [(set (match_operand:SI 0 "s_operand" "")
6978 (and:SI (match_dup 0) (match_operand:SI 1 "immediate_operand" "")))
6979 (clobber (reg:CC CC_REGNUM))]
6980 "reload_completed"
6981 [(parallel
6982 [(set (match_dup 0) (and:QI (match_dup 0) (match_dup 1)))
6983 (clobber (reg:CC CC_REGNUM))])]
6984 "s390_narrow_logical_operator (AND, &operands[0], &operands[1]);")
6985
6986 ;
6987 ; andhi3 instruction pattern(s).
6988 ;
6989
6990 (define_insn "*andhi3_zarch"
6991 [(set (match_operand:HI 0 "nonimmediate_operand" "=d,d,d, AQ,Q")
6992 (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,d,0, 0,0")
6993 (match_operand:HI 2 "general_operand" " d,d,n,NxQHF,Q")))
6994 (clobber (reg:CC CC_REGNUM))]
6995 "TARGET_ZARCH && s390_logical_operator_ok_p (operands)"
6996 "@
6997 nr\t%0,%2
6998 nrk\t%0,%1,%2
6999 nill\t%0,%x2
7000 #
7001 #"
7002 [(set_attr "op_type" "RR,RRF,RI,SI,SS")
7003 (set_attr "cpu_facility" "*,z196,*,*,*")
7004 (set_attr "z10prop" "z10_super_E1,*,z10_super_E1,*,*")
7005 ])
7006
7007 (define_insn "*andhi3_esa"
7008 [(set (match_operand:HI 0 "nonimmediate_operand" "=d,AQ,Q")
7009 (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,0")
7010 (match_operand:HI 2 "general_operand" "d,NxQHF,Q")))
7011 (clobber (reg:CC CC_REGNUM))]
7012 "!TARGET_ZARCH && s390_logical_operator_ok_p (operands)"
7013 "@
7014 nr\t%0,%2
7015 #
7016 #"
7017 [(set_attr "op_type" "RR,SI,SS")
7018 (set_attr "z10prop" "z10_super_E1,*,*")
7019 ])
7020
7021 (define_split
7022 [(set (match_operand:HI 0 "s_operand" "")
7023 (and:HI (match_dup 0) (match_operand:HI 1 "immediate_operand" "")))
7024 (clobber (reg:CC CC_REGNUM))]
7025 "reload_completed"
7026 [(parallel
7027 [(set (match_dup 0) (and:QI (match_dup 0) (match_dup 1)))
7028 (clobber (reg:CC CC_REGNUM))])]
7029 "s390_narrow_logical_operator (AND, &operands[0], &operands[1]);")
7030
7031 ;
7032 ; andqi3 instruction pattern(s).
7033 ;
7034
7035 (define_insn "*andqi3_zarch"
7036 [(set (match_operand:QI 0 "nonimmediate_operand" "=d,d,d,Q,S,Q")
7037 (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,d,0,0,0,0")
7038 (match_operand:QI 2 "general_operand" " d,d,n,n,n,Q")))
7039 (clobber (reg:CC CC_REGNUM))]
7040 "TARGET_ZARCH && s390_logical_operator_ok_p (operands)"
7041 "@
7042 nr\t%0,%2
7043 nrk\t%0,%1,%2
7044 nill\t%0,%b2
7045 ni\t%S0,%b2
7046 niy\t%S0,%b2
7047 #"
7048 [(set_attr "op_type" "RR,RRF,RI,SI,SIY,SS")
7049 (set_attr "cpu_facility" "*,z196,*,*,*,*")
7050 (set_attr "z10prop" "z10_super_E1,*,z10_super_E1,z10_super,z10_super,*")])
7051
7052 (define_insn "*andqi3_esa"
7053 [(set (match_operand:QI 0 "nonimmediate_operand" "=d,Q,Q")
7054 (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
7055 (match_operand:QI 2 "general_operand" "d,n,Q")))
7056 (clobber (reg:CC CC_REGNUM))]
7057 "!TARGET_ZARCH && s390_logical_operator_ok_p (operands)"
7058 "@
7059 nr\t%0,%2
7060 ni\t%S0,%b2
7061 #"
7062 [(set_attr "op_type" "RR,SI,SS")
7063 (set_attr "z10prop" "z10_super_E1,z10_super,*")])
7064
7065 ;
7066 ; Block and (NC) patterns.
7067 ;
7068
7069 (define_insn "*nc"
7070 [(set (match_operand:BLK 0 "memory_operand" "=Q")
7071 (and:BLK (match_dup 0)
7072 (match_operand:BLK 1 "memory_operand" "Q")))
7073 (use (match_operand 2 "const_int_operand" "n"))
7074 (clobber (reg:CC CC_REGNUM))]
7075 "INTVAL (operands[2]) >= 1 && INTVAL (operands[2]) <= 256"
7076 "nc\t%O0(%2,%R0),%S1"
7077 [(set_attr "op_type" "SS")
7078 (set_attr "z196prop" "z196_cracked")])
7079
7080 (define_split
7081 [(set (match_operand 0 "memory_operand" "")
7082 (and (match_dup 0)
7083 (match_operand 1 "memory_operand" "")))
7084 (clobber (reg:CC CC_REGNUM))]
7085 "reload_completed
7086 && GET_MODE (operands[0]) == GET_MODE (operands[1])
7087 && GET_MODE_SIZE (GET_MODE (operands[0])) > 0"
7088 [(parallel
7089 [(set (match_dup 0) (and:BLK (match_dup 0) (match_dup 1)))
7090 (use (match_dup 2))
7091 (clobber (reg:CC CC_REGNUM))])]
7092 {
7093 operands[2] = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[0])));
7094 operands[0] = adjust_address (operands[0], BLKmode, 0);
7095 operands[1] = adjust_address (operands[1], BLKmode, 0);
7096 })
7097
7098 (define_peephole2
7099 [(parallel
7100 [(set (match_operand:BLK 0 "memory_operand" "")
7101 (and:BLK (match_dup 0)
7102 (match_operand:BLK 1 "memory_operand" "")))
7103 (use (match_operand 2 "const_int_operand" ""))
7104 (clobber (reg:CC CC_REGNUM))])
7105 (parallel
7106 [(set (match_operand:BLK 3 "memory_operand" "")
7107 (and:BLK (match_dup 3)
7108 (match_operand:BLK 4 "memory_operand" "")))
7109 (use (match_operand 5 "const_int_operand" ""))
7110 (clobber (reg:CC CC_REGNUM))])]
7111 "s390_offset_p (operands[0], operands[3], operands[2])
7112 && s390_offset_p (operands[1], operands[4], operands[2])
7113 && !s390_overlap_p (operands[0], operands[1],
7114 INTVAL (operands[2]) + INTVAL (operands[5]))
7115 && INTVAL (operands[2]) + INTVAL (operands[5]) <= 256"
7116 [(parallel
7117 [(set (match_dup 6) (and:BLK (match_dup 6) (match_dup 7)))
7118 (use (match_dup 8))
7119 (clobber (reg:CC CC_REGNUM))])]
7120 "operands[6] = gen_rtx_MEM (BLKmode, XEXP (operands[0], 0));
7121 operands[7] = gen_rtx_MEM (BLKmode, XEXP (operands[1], 0));
7122 operands[8] = GEN_INT (INTVAL (operands[2]) + INTVAL (operands[5]));")
7123
7124
7125 ;;
7126 ;;- Bit set (inclusive or) instructions.
7127 ;;
7128
7129 (define_expand "ior<mode>3"
7130 [(set (match_operand:INT 0 "nonimmediate_operand" "")
7131 (ior: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 (IOR, <MODE>mode, operands); DONE;")
7136
7137 ;
7138 ; iordi3 instruction pattern(s).
7139 ;
7140
7141 (define_insn "*iordi3_cc"
7142 [(set (reg CC_REGNUM)
7143 (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,d, 0")
7144 (match_operand:DI 2 "general_operand" " d,d,RT"))
7145 (const_int 0)))
7146 (set (match_operand:DI 0 "register_operand" "=d,d, d")
7147 (ior:DI (match_dup 1) (match_dup 2)))]
7148 "s390_match_ccmode(insn, CCTmode) && TARGET_ZARCH"
7149 "@
7150 ogr\t%0,%2
7151 ogrk\t%0,%1,%2
7152 og\t%0,%2"
7153 [(set_attr "op_type" "RRE,RRF,RXY")
7154 (set_attr "cpu_facility" "*,z196,*")
7155 (set_attr "z10prop" "z10_super_E1,*,z10_super_E1")])
7156
7157 (define_insn "*iordi3_cconly"
7158 [(set (reg CC_REGNUM)
7159 (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,d,0")
7160 (match_operand:DI 2 "general_operand" " d,d,RT"))
7161 (const_int 0)))
7162 (clobber (match_scratch:DI 0 "=d,d,d"))]
7163 "s390_match_ccmode(insn, CCTmode) && TARGET_ZARCH"
7164 "@
7165 ogr\t%0,%2
7166 ogrk\t%0,%1,%2
7167 og\t%0,%2"
7168 [(set_attr "op_type" "RRE,RRF,RXY")
7169 (set_attr "cpu_facility" "*,z196,*")
7170 (set_attr "z10prop" "z10_super_E1,*,z10_super_E1")])
7171
7172 (define_insn "*iordi3"
7173 [(set (match_operand:DI 0 "nonimmediate_operand"
7174 "=d, d, d, d, d, d,d,d, d, AQ,Q")
7175 (ior:DI (match_operand:DI 1 "nonimmediate_operand"
7176 " %0, 0, 0, 0, 0, 0,0,d, 0, 0,0")
7177 (match_operand:DI 2 "general_operand"
7178 "N0HD0,N1HD0,N2HD0,N3HD0,N0SD0,N1SD0,d,d,RT,NxQD0,Q")))
7179 (clobber (reg:CC CC_REGNUM))]
7180 "TARGET_ZARCH && s390_logical_operator_ok_p (operands)"
7181 "@
7182 oihh\t%0,%i2
7183 oihl\t%0,%i2
7184 oilh\t%0,%i2
7185 oill\t%0,%i2
7186 oihf\t%0,%k2
7187 oilf\t%0,%k2
7188 ogr\t%0,%2
7189 ogrk\t%0,%1,%2
7190 og\t%0,%2
7191 #
7192 #"
7193 [(set_attr "op_type" "RI,RI,RI,RI,RIL,RIL,RRE,RRF,RXY,SI,SS")
7194 (set_attr "cpu_facility" "*,*,*,*,extimm,extimm,*,z196,*,*,*")
7195 (set_attr "z10prop" "z10_super_E1,
7196 z10_super_E1,
7197 z10_super_E1,
7198 z10_super_E1,
7199 z10_super_E1,
7200 z10_super_E1,
7201 z10_super_E1,
7202 *,
7203 z10_super_E1,
7204 *,
7205 *")])
7206
7207 (define_split
7208 [(set (match_operand:DI 0 "s_operand" "")
7209 (ior:DI (match_dup 0) (match_operand:DI 1 "immediate_operand" "")))
7210 (clobber (reg:CC CC_REGNUM))]
7211 "reload_completed"
7212 [(parallel
7213 [(set (match_dup 0) (ior:QI (match_dup 0) (match_dup 1)))
7214 (clobber (reg:CC CC_REGNUM))])]
7215 "s390_narrow_logical_operator (IOR, &operands[0], &operands[1]);")
7216
7217 ;
7218 ; iorsi3 instruction pattern(s).
7219 ;
7220
7221 (define_insn "*iorsi3_cc"
7222 [(set (reg CC_REGNUM)
7223 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,d,0,0")
7224 (match_operand:SI 2 "general_operand" "Os,d,d,R,T"))
7225 (const_int 0)))
7226 (set (match_operand:SI 0 "register_operand" "=d,d,d,d,d")
7227 (ior:SI (match_dup 1) (match_dup 2)))]
7228 "s390_match_ccmode(insn, CCTmode)"
7229 "@
7230 oilf\t%0,%o2
7231 or\t%0,%2
7232 ork\t%0,%1,%2
7233 o\t%0,%2
7234 oy\t%0,%2"
7235 [(set_attr "op_type" "RIL,RR,RRF,RX,RXY")
7236 (set_attr "cpu_facility" "*,*,z196,*,*")
7237 (set_attr "z10prop" "z10_super_E1,z10_super_E1,*,z10_super_E1,z10_super_E1")])
7238
7239 (define_insn "*iorsi3_cconly"
7240 [(set (reg CC_REGNUM)
7241 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,d,0,0")
7242 (match_operand:SI 2 "general_operand" "Os,d,d,R,T"))
7243 (const_int 0)))
7244 (clobber (match_scratch:SI 0 "=d,d,d,d,d"))]
7245 "s390_match_ccmode(insn, CCTmode)"
7246 "@
7247 oilf\t%0,%o2
7248 or\t%0,%2
7249 ork\t%0,%1,%2
7250 o\t%0,%2
7251 oy\t%0,%2"
7252 [(set_attr "op_type" "RIL,RR,RRF,RX,RXY")
7253 (set_attr "cpu_facility" "*,*,z196,*,*")
7254 (set_attr "z10prop" "z10_super_E1,z10_super_E1,*,z10_super_E1,z10_super_E1")])
7255
7256 (define_insn "*iorsi3_zarch"
7257 [(set (match_operand:SI 0 "nonimmediate_operand" "=d, d, d,d,d,d,d, AQ,Q")
7258 (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0, 0, 0,0,d,0,0, 0,0")
7259 (match_operand:SI 2 "general_operand" "N0HS0,N1HS0,Os,d,d,R,T,NxQS0,Q")))
7260 (clobber (reg:CC CC_REGNUM))]
7261 "TARGET_ZARCH && s390_logical_operator_ok_p (operands)"
7262 "@
7263 oilh\t%0,%i2
7264 oill\t%0,%i2
7265 oilf\t%0,%o2
7266 or\t%0,%2
7267 ork\t%0,%1,%2
7268 o\t%0,%2
7269 oy\t%0,%2
7270 #
7271 #"
7272 [(set_attr "op_type" "RI,RI,RIL,RR,RRF,RX,RXY,SI,SS")
7273 (set_attr "cpu_facility" "*,*,*,*,z196,*,*,*,*")
7274 (set_attr "z10prop" "z10_super_E1,
7275 z10_super_E1,
7276 z10_super_E1,
7277 z10_super_E1,
7278 *,
7279 z10_super_E1,
7280 z10_super_E1,
7281 *,
7282 *")])
7283
7284 (define_insn "*iorsi3_esa"
7285 [(set (match_operand:SI 0 "nonimmediate_operand" "=d,d,AQ,Q")
7286 (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,0,0")
7287 (match_operand:SI 2 "general_operand" "d,R,NxQS0,Q")))
7288 (clobber (reg:CC CC_REGNUM))]
7289 "!TARGET_ZARCH && s390_logical_operator_ok_p (operands)"
7290 "@
7291 or\t%0,%2
7292 o\t%0,%2
7293 #
7294 #"
7295 [(set_attr "op_type" "RR,RX,SI,SS")
7296 (set_attr "z10prop" "z10_super_E1,z10_super_E1,*,*")])
7297
7298 (define_split
7299 [(set (match_operand:SI 0 "s_operand" "")
7300 (ior:SI (match_dup 0) (match_operand:SI 1 "immediate_operand" "")))
7301 (clobber (reg:CC CC_REGNUM))]
7302 "reload_completed"
7303 [(parallel
7304 [(set (match_dup 0) (ior:QI (match_dup 0) (match_dup 1)))
7305 (clobber (reg:CC CC_REGNUM))])]
7306 "s390_narrow_logical_operator (IOR, &operands[0], &operands[1]);")
7307
7308 ;
7309 ; iorhi3 instruction pattern(s).
7310 ;
7311
7312 (define_insn "*iorhi3_zarch"
7313 [(set (match_operand:HI 0 "nonimmediate_operand" "=d,d,d, AQ,Q")
7314 (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,d,0, 0,0")
7315 (match_operand:HI 2 "general_operand" " d,d,n,NxQH0,Q")))
7316 (clobber (reg:CC CC_REGNUM))]
7317 "TARGET_ZARCH && s390_logical_operator_ok_p (operands)"
7318 "@
7319 or\t%0,%2
7320 ork\t%0,%1,%2
7321 oill\t%0,%x2
7322 #
7323 #"
7324 [(set_attr "op_type" "RR,RRF,RI,SI,SS")
7325 (set_attr "cpu_facility" "*,z196,*,*,*")
7326 (set_attr "z10prop" "z10_super_E1,*,z10_super_E1,*,*")])
7327
7328 (define_insn "*iorhi3_esa"
7329 [(set (match_operand:HI 0 "nonimmediate_operand" "=d,AQ,Q")
7330 (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,0")
7331 (match_operand:HI 2 "general_operand" "d,NxQH0,Q")))
7332 (clobber (reg:CC CC_REGNUM))]
7333 "!TARGET_ZARCH && s390_logical_operator_ok_p (operands)"
7334 "@
7335 or\t%0,%2
7336 #
7337 #"
7338 [(set_attr "op_type" "RR,SI,SS")
7339 (set_attr "z10prop" "z10_super_E1,*,*")])
7340
7341 (define_split
7342 [(set (match_operand:HI 0 "s_operand" "")
7343 (ior:HI (match_dup 0) (match_operand:HI 1 "immediate_operand" "")))
7344 (clobber (reg:CC CC_REGNUM))]
7345 "reload_completed"
7346 [(parallel
7347 [(set (match_dup 0) (ior:QI (match_dup 0) (match_dup 1)))
7348 (clobber (reg:CC CC_REGNUM))])]
7349 "s390_narrow_logical_operator (IOR, &operands[0], &operands[1]);")
7350
7351 ;
7352 ; iorqi3 instruction pattern(s).
7353 ;
7354
7355 (define_insn "*iorqi3_zarch"
7356 [(set (match_operand:QI 0 "nonimmediate_operand" "=d,d,d,Q,S,Q")
7357 (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,d,0,0,0,0")
7358 (match_operand:QI 2 "general_operand" " d,d,n,n,n,Q")))
7359 (clobber (reg:CC CC_REGNUM))]
7360 "TARGET_ZARCH && s390_logical_operator_ok_p (operands)"
7361 "@
7362 or\t%0,%2
7363 ork\t%0,%1,%2
7364 oill\t%0,%b2
7365 oi\t%S0,%b2
7366 oiy\t%S0,%b2
7367 #"
7368 [(set_attr "op_type" "RR,RRF,RI,SI,SIY,SS")
7369 (set_attr "cpu_facility" "*,z196,*,*,*,*")
7370 (set_attr "z10prop" "z10_super_E1,*,z10_super_E1,
7371 z10_super,z10_super,*")])
7372
7373 (define_insn "*iorqi3_esa"
7374 [(set (match_operand:QI 0 "nonimmediate_operand" "=d,Q,Q")
7375 (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
7376 (match_operand:QI 2 "general_operand" "d,n,Q")))
7377 (clobber (reg:CC CC_REGNUM))]
7378 "!TARGET_ZARCH && s390_logical_operator_ok_p (operands)"
7379 "@
7380 or\t%0,%2
7381 oi\t%S0,%b2
7382 #"
7383 [(set_attr "op_type" "RR,SI,SS")
7384 (set_attr "z10prop" "z10_super_E1,z10_super,*")])
7385
7386 ;
7387 ; Block inclusive or (OC) patterns.
7388 ;
7389
7390 (define_insn "*oc"
7391 [(set (match_operand:BLK 0 "memory_operand" "=Q")
7392 (ior:BLK (match_dup 0)
7393 (match_operand:BLK 1 "memory_operand" "Q")))
7394 (use (match_operand 2 "const_int_operand" "n"))
7395 (clobber (reg:CC CC_REGNUM))]
7396 "INTVAL (operands[2]) >= 1 && INTVAL (operands[2]) <= 256"
7397 "oc\t%O0(%2,%R0),%S1"
7398 [(set_attr "op_type" "SS")
7399 (set_attr "z196prop" "z196_cracked")])
7400
7401 (define_split
7402 [(set (match_operand 0 "memory_operand" "")
7403 (ior (match_dup 0)
7404 (match_operand 1 "memory_operand" "")))
7405 (clobber (reg:CC CC_REGNUM))]
7406 "reload_completed
7407 && GET_MODE (operands[0]) == GET_MODE (operands[1])
7408 && GET_MODE_SIZE (GET_MODE (operands[0])) > 0"
7409 [(parallel
7410 [(set (match_dup 0) (ior:BLK (match_dup 0) (match_dup 1)))
7411 (use (match_dup 2))
7412 (clobber (reg:CC CC_REGNUM))])]
7413 {
7414 operands[2] = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[0])));
7415 operands[0] = adjust_address (operands[0], BLKmode, 0);
7416 operands[1] = adjust_address (operands[1], BLKmode, 0);
7417 })
7418
7419 (define_peephole2
7420 [(parallel
7421 [(set (match_operand:BLK 0 "memory_operand" "")
7422 (ior:BLK (match_dup 0)
7423 (match_operand:BLK 1 "memory_operand" "")))
7424 (use (match_operand 2 "const_int_operand" ""))
7425 (clobber (reg:CC CC_REGNUM))])
7426 (parallel
7427 [(set (match_operand:BLK 3 "memory_operand" "")
7428 (ior:BLK (match_dup 3)
7429 (match_operand:BLK 4 "memory_operand" "")))
7430 (use (match_operand 5 "const_int_operand" ""))
7431 (clobber (reg:CC CC_REGNUM))])]
7432 "s390_offset_p (operands[0], operands[3], operands[2])
7433 && s390_offset_p (operands[1], operands[4], operands[2])
7434 && !s390_overlap_p (operands[0], operands[1],
7435 INTVAL (operands[2]) + INTVAL (operands[5]))
7436 && INTVAL (operands[2]) + INTVAL (operands[5]) <= 256"
7437 [(parallel
7438 [(set (match_dup 6) (ior:BLK (match_dup 6) (match_dup 7)))
7439 (use (match_dup 8))
7440 (clobber (reg:CC CC_REGNUM))])]
7441 "operands[6] = gen_rtx_MEM (BLKmode, XEXP (operands[0], 0));
7442 operands[7] = gen_rtx_MEM (BLKmode, XEXP (operands[1], 0));
7443 operands[8] = GEN_INT (INTVAL (operands[2]) + INTVAL (operands[5]));")
7444
7445
7446 ;;
7447 ;;- Xor instructions.
7448 ;;
7449
7450 (define_expand "xor<mode>3"
7451 [(set (match_operand:INT 0 "nonimmediate_operand" "")
7452 (xor:INT (match_operand:INT 1 "nonimmediate_operand" "")
7453 (match_operand:INT 2 "general_operand" "")))
7454 (clobber (reg:CC CC_REGNUM))]
7455 ""
7456 "s390_expand_logical_operator (XOR, <MODE>mode, operands); DONE;")
7457
7458 ; Combine replaces (xor (x) (const_int -1)) with (not (x)) when doing
7459 ; simplifications. So its better to have something matching.
7460 (define_split
7461 [(set (match_operand:INT 0 "nonimmediate_operand" "")
7462 (not:INT (match_operand:INT 1 "nonimmediate_operand" "")))]
7463 ""
7464 [(parallel
7465 [(set (match_dup 0) (xor:INT (match_dup 1) (match_dup 2)))
7466 (clobber (reg:CC CC_REGNUM))])]
7467 {
7468 operands[2] = constm1_rtx;
7469 if (!s390_logical_operator_ok_p (operands))
7470 FAIL;
7471 })
7472
7473 ;
7474 ; xordi3 instruction pattern(s).
7475 ;
7476
7477 (define_insn "*xordi3_cc"
7478 [(set (reg CC_REGNUM)
7479 (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,d, 0")
7480 (match_operand:DI 2 "general_operand" " d,d,RT"))
7481 (const_int 0)))
7482 (set (match_operand:DI 0 "register_operand" "=d,d, d")
7483 (xor:DI (match_dup 1) (match_dup 2)))]
7484 "s390_match_ccmode(insn, CCTmode) && TARGET_ZARCH"
7485 "@
7486 xgr\t%0,%2
7487 xgrk\t%0,%1,%2
7488 xg\t%0,%2"
7489 [(set_attr "op_type" "RRE,RRF,RXY")
7490 (set_attr "cpu_facility" "*,z196,*")
7491 (set_attr "z10prop" "z10_super_E1,*,z10_super_E1")])
7492
7493 (define_insn "*xordi3_cconly"
7494 [(set (reg CC_REGNUM)
7495 (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,d, 0")
7496 (match_operand:DI 2 "general_operand" " d,d,RT"))
7497 (const_int 0)))
7498 (clobber (match_scratch:DI 0 "=d,d, d"))]
7499 "s390_match_ccmode(insn, CCTmode) && TARGET_ZARCH"
7500 "@
7501 xgr\t%0,%2
7502 xgrk\t%0,%1,%2
7503 xg\t%0,%2"
7504 [(set_attr "op_type" "RRE,RRF,RXY")
7505 (set_attr "cpu_facility" "*,z196,*")
7506 (set_attr "z10prop" "z10_super_E1,*,z10_super_E1")])
7507
7508 (define_insn "*xordi3"
7509 [(set (match_operand:DI 0 "nonimmediate_operand" "=d, d,d,d, d, AQ,Q")
7510 (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0, 0,0,d, 0, 0,0")
7511 (match_operand:DI 2 "general_operand" "N0SD0,N1SD0,d,d,RT,NxQD0,Q")))
7512 (clobber (reg:CC CC_REGNUM))]
7513 "TARGET_ZARCH && s390_logical_operator_ok_p (operands)"
7514 "@
7515 xihf\t%0,%k2
7516 xilf\t%0,%k2
7517 xgr\t%0,%2
7518 xgrk\t%0,%1,%2
7519 xg\t%0,%2
7520 #
7521 #"
7522 [(set_attr "op_type" "RIL,RIL,RRE,RRF,RXY,SI,SS")
7523 (set_attr "cpu_facility" "extimm,extimm,*,z196,*,*,*")
7524 (set_attr "z10prop" "z10_super_E1,z10_super_E1,z10_super_E1,
7525 *,z10_super_E1,*,*")])
7526
7527 (define_split
7528 [(set (match_operand:DI 0 "s_operand" "")
7529 (xor:DI (match_dup 0) (match_operand:DI 1 "immediate_operand" "")))
7530 (clobber (reg:CC CC_REGNUM))]
7531 "reload_completed"
7532 [(parallel
7533 [(set (match_dup 0) (xor:QI (match_dup 0) (match_dup 1)))
7534 (clobber (reg:CC CC_REGNUM))])]
7535 "s390_narrow_logical_operator (XOR, &operands[0], &operands[1]);")
7536
7537 ;
7538 ; xorsi3 instruction pattern(s).
7539 ;
7540
7541 (define_insn "*xorsi3_cc"
7542 [(set (reg CC_REGNUM)
7543 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,d,0,0")
7544 (match_operand:SI 2 "general_operand" "Os,d,d,R,T"))
7545 (const_int 0)))
7546 (set (match_operand:SI 0 "register_operand" "=d,d,d,d,d")
7547 (xor:SI (match_dup 1) (match_dup 2)))]
7548 "s390_match_ccmode(insn, CCTmode)"
7549 "@
7550 xilf\t%0,%o2
7551 xr\t%0,%2
7552 xrk\t%0,%1,%2
7553 x\t%0,%2
7554 xy\t%0,%2"
7555 [(set_attr "op_type" "RIL,RR,RRF,RX,RXY")
7556 (set_attr "cpu_facility" "*,*,z196,*,*")
7557 (set_attr "z10prop" "z10_super_E1,z10_super_E1,*,
7558 z10_super_E1,z10_super_E1")])
7559
7560 (define_insn "*xorsi3_cconly"
7561 [(set (reg CC_REGNUM)
7562 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,d,0,0")
7563 (match_operand:SI 2 "general_operand" "Os,d,d,R,T"))
7564 (const_int 0)))
7565 (clobber (match_scratch:SI 0 "=d,d,d,d,d"))]
7566 "s390_match_ccmode(insn, CCTmode)"
7567 "@
7568 xilf\t%0,%o2
7569 xr\t%0,%2
7570 xrk\t%0,%1,%2
7571 x\t%0,%2
7572 xy\t%0,%2"
7573 [(set_attr "op_type" "RIL,RR,RRF,RX,RXY")
7574 (set_attr "cpu_facility" "*,*,z196,*,*")
7575 (set_attr "z10prop" "z10_super_E1,z10_super_E1,*,
7576 z10_super_E1,z10_super_E1")])
7577
7578 (define_insn "*xorsi3"
7579 [(set (match_operand:SI 0 "nonimmediate_operand" "=d,d,d,d,d, AQ,Q")
7580 (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,d,0,0, 0,0")
7581 (match_operand:SI 2 "general_operand" "Os,d,d,R,T,NxQS0,Q")))
7582 (clobber (reg:CC CC_REGNUM))]
7583 "s390_logical_operator_ok_p (operands)"
7584 "@
7585 xilf\t%0,%o2
7586 xr\t%0,%2
7587 xrk\t%0,%1,%2
7588 x\t%0,%2
7589 xy\t%0,%2
7590 #
7591 #"
7592 [(set_attr "op_type" "RIL,RR,RRF,RX,RXY,SI,SS")
7593 (set_attr "cpu_facility" "*,*,z196,*,*,*,*")
7594 (set_attr "z10prop" "z10_super_E1,z10_super_E1,*,
7595 z10_super_E1,z10_super_E1,*,*")])
7596
7597 (define_split
7598 [(set (match_operand:SI 0 "s_operand" "")
7599 (xor:SI (match_dup 0) (match_operand:SI 1 "immediate_operand" "")))
7600 (clobber (reg:CC CC_REGNUM))]
7601 "reload_completed"
7602 [(parallel
7603 [(set (match_dup 0) (xor:QI (match_dup 0) (match_dup 1)))
7604 (clobber (reg:CC CC_REGNUM))])]
7605 "s390_narrow_logical_operator (XOR, &operands[0], &operands[1]);")
7606
7607 ;
7608 ; xorhi3 instruction pattern(s).
7609 ;
7610
7611 (define_insn "*xorhi3"
7612 [(set (match_operand:HI 0 "nonimmediate_operand" "=d,d,d, AQ,Q")
7613 (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,d, 0,0")
7614 (match_operand:HI 2 "general_operand" "Os,d,d,NxQH0,Q")))
7615 (clobber (reg:CC CC_REGNUM))]
7616 "s390_logical_operator_ok_p (operands)"
7617 "@
7618 xilf\t%0,%x2
7619 xr\t%0,%2
7620 xrk\t%0,%1,%2
7621 #
7622 #"
7623 [(set_attr "op_type" "RIL,RR,RRF,SI,SS")
7624 (set_attr "cpu_facility" "*,*,z196,*,*")
7625 (set_attr "z10prop" "z10_super_E1,z10_super_E1,*,*,*")])
7626
7627 (define_split
7628 [(set (match_operand:HI 0 "s_operand" "")
7629 (xor:HI (match_dup 0) (match_operand:HI 1 "immediate_operand" "")))
7630 (clobber (reg:CC CC_REGNUM))]
7631 "reload_completed"
7632 [(parallel
7633 [(set (match_dup 0) (xor:QI (match_dup 0) (match_dup 1)))
7634 (clobber (reg:CC CC_REGNUM))])]
7635 "s390_narrow_logical_operator (XOR, &operands[0], &operands[1]);")
7636
7637 ;
7638 ; xorqi3 instruction pattern(s).
7639 ;
7640
7641 (define_insn "*xorqi3"
7642 [(set (match_operand:QI 0 "nonimmediate_operand" "=d,d,d,Q,S,Q")
7643 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,d,0,0,0")
7644 (match_operand:QI 2 "general_operand" "Os,d,d,n,n,Q")))
7645 (clobber (reg:CC CC_REGNUM))]
7646 "s390_logical_operator_ok_p (operands)"
7647 "@
7648 xilf\t%0,%b2
7649 xr\t%0,%2
7650 xrk\t%0,%1,%2
7651 xi\t%S0,%b2
7652 xiy\t%S0,%b2
7653 #"
7654 [(set_attr "op_type" "RIL,RR,RRF,SI,SIY,SS")
7655 (set_attr "cpu_facility" "*,*,z196,*,*,*")
7656 (set_attr "z10prop" "z10_super_E1,z10_super_E1,*,z10_super,z10_super,*")])
7657
7658
7659 ;
7660 ; Block exclusive or (XC) patterns.
7661 ;
7662
7663 (define_insn "*xc"
7664 [(set (match_operand:BLK 0 "memory_operand" "=Q")
7665 (xor:BLK (match_dup 0)
7666 (match_operand:BLK 1 "memory_operand" "Q")))
7667 (use (match_operand 2 "const_int_operand" "n"))
7668 (clobber (reg:CC CC_REGNUM))]
7669 "INTVAL (operands[2]) >= 1 && INTVAL (operands[2]) <= 256"
7670 "xc\t%O0(%2,%R0),%S1"
7671 [(set_attr "op_type" "SS")])
7672
7673 (define_split
7674 [(set (match_operand 0 "memory_operand" "")
7675 (xor (match_dup 0)
7676 (match_operand 1 "memory_operand" "")))
7677 (clobber (reg:CC CC_REGNUM))]
7678 "reload_completed
7679 && GET_MODE (operands[0]) == GET_MODE (operands[1])
7680 && GET_MODE_SIZE (GET_MODE (operands[0])) > 0"
7681 [(parallel
7682 [(set (match_dup 0) (xor:BLK (match_dup 0) (match_dup 1)))
7683 (use (match_dup 2))
7684 (clobber (reg:CC CC_REGNUM))])]
7685 {
7686 operands[2] = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[0])));
7687 operands[0] = adjust_address (operands[0], BLKmode, 0);
7688 operands[1] = adjust_address (operands[1], BLKmode, 0);
7689 })
7690
7691 (define_peephole2
7692 [(parallel
7693 [(set (match_operand:BLK 0 "memory_operand" "")
7694 (xor:BLK (match_dup 0)
7695 (match_operand:BLK 1 "memory_operand" "")))
7696 (use (match_operand 2 "const_int_operand" ""))
7697 (clobber (reg:CC CC_REGNUM))])
7698 (parallel
7699 [(set (match_operand:BLK 3 "memory_operand" "")
7700 (xor:BLK (match_dup 3)
7701 (match_operand:BLK 4 "memory_operand" "")))
7702 (use (match_operand 5 "const_int_operand" ""))
7703 (clobber (reg:CC CC_REGNUM))])]
7704 "s390_offset_p (operands[0], operands[3], operands[2])
7705 && s390_offset_p (operands[1], operands[4], operands[2])
7706 && !s390_overlap_p (operands[0], operands[1],
7707 INTVAL (operands[2]) + INTVAL (operands[5]))
7708 && INTVAL (operands[2]) + INTVAL (operands[5]) <= 256"
7709 [(parallel
7710 [(set (match_dup 6) (xor:BLK (match_dup 6) (match_dup 7)))
7711 (use (match_dup 8))
7712 (clobber (reg:CC CC_REGNUM))])]
7713 "operands[6] = gen_rtx_MEM (BLKmode, XEXP (operands[0], 0));
7714 operands[7] = gen_rtx_MEM (BLKmode, XEXP (operands[1], 0));
7715 operands[8] = GEN_INT (INTVAL (operands[2]) + INTVAL (operands[5]));")
7716
7717 ;
7718 ; Block xor (XC) patterns with src == dest.
7719 ;
7720
7721 (define_insn "*xc_zero"
7722 [(set (match_operand:BLK 0 "memory_operand" "=Q")
7723 (const_int 0))
7724 (use (match_operand 1 "const_int_operand" "n"))
7725 (clobber (reg:CC CC_REGNUM))]
7726 "INTVAL (operands[1]) >= 1 && INTVAL (operands[1]) <= 256"
7727 "xc\t%O0(%1,%R0),%S0"
7728 [(set_attr "op_type" "SS")
7729 (set_attr "z196prop" "z196_cracked")])
7730
7731 (define_peephole2
7732 [(parallel
7733 [(set (match_operand:BLK 0 "memory_operand" "")
7734 (const_int 0))
7735 (use (match_operand 1 "const_int_operand" ""))
7736 (clobber (reg:CC CC_REGNUM))])
7737 (parallel
7738 [(set (match_operand:BLK 2 "memory_operand" "")
7739 (const_int 0))
7740 (use (match_operand 3 "const_int_operand" ""))
7741 (clobber (reg:CC CC_REGNUM))])]
7742 "s390_offset_p (operands[0], operands[2], operands[1])
7743 && INTVAL (operands[1]) + INTVAL (operands[3]) <= 256"
7744 [(parallel
7745 [(set (match_dup 4) (const_int 0))
7746 (use (match_dup 5))
7747 (clobber (reg:CC CC_REGNUM))])]
7748 "operands[4] = gen_rtx_MEM (BLKmode, XEXP (operands[0], 0));
7749 operands[5] = GEN_INT (INTVAL (operands[1]) + INTVAL (operands[3]));")
7750
7751
7752 ;;
7753 ;;- Negate instructions.
7754 ;;
7755
7756 ;
7757 ; neg(di|si)2 instruction pattern(s).
7758 ;
7759
7760 (define_expand "neg<mode>2"
7761 [(parallel
7762 [(set (match_operand:DSI 0 "register_operand" "=d")
7763 (neg:DSI (match_operand:DSI 1 "register_operand" "d")))
7764 (clobber (reg:CC CC_REGNUM))])]
7765 ""
7766 "")
7767
7768 (define_insn "*negdi2_sign_cc"
7769 [(set (reg CC_REGNUM)
7770 (compare (neg:DI (ashiftrt:DI (ashift:DI (subreg:DI
7771 (match_operand:SI 1 "register_operand" "d") 0)
7772 (const_int 32)) (const_int 32)))
7773 (const_int 0)))
7774 (set (match_operand:DI 0 "register_operand" "=d")
7775 (neg:DI (sign_extend:DI (match_dup 1))))]
7776 "TARGET_ZARCH && s390_match_ccmode (insn, CCAmode)"
7777 "lcgfr\t%0,%1"
7778 [(set_attr "op_type" "RRE")
7779 (set_attr "z10prop" "z10_c")])
7780
7781 (define_insn "*negdi2_sign"
7782 [(set (match_operand:DI 0 "register_operand" "=d")
7783 (neg:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "d"))))
7784 (clobber (reg:CC CC_REGNUM))]
7785 "TARGET_ZARCH"
7786 "lcgfr\t%0,%1"
7787 [(set_attr "op_type" "RRE")
7788 (set_attr "z10prop" "z10_c")])
7789
7790 ; lcr, lcgr
7791 (define_insn "*neg<mode>2_cc"
7792 [(set (reg CC_REGNUM)
7793 (compare (neg:GPR (match_operand:GPR 1 "register_operand" "d"))
7794 (const_int 0)))
7795 (set (match_operand:GPR 0 "register_operand" "=d")
7796 (neg:GPR (match_dup 1)))]
7797 "s390_match_ccmode (insn, CCAmode)"
7798 "lc<g>r\t%0,%1"
7799 [(set_attr "op_type" "RR<E>")
7800 (set_attr "z10prop" "z10_super_c_E1")])
7801
7802 ; lcr, lcgr
7803 (define_insn "*neg<mode>2_cconly"
7804 [(set (reg CC_REGNUM)
7805 (compare (neg:GPR (match_operand:GPR 1 "register_operand" "d"))
7806 (const_int 0)))
7807 (clobber (match_scratch:GPR 0 "=d"))]
7808 "s390_match_ccmode (insn, CCAmode)"
7809 "lc<g>r\t%0,%1"
7810 [(set_attr "op_type" "RR<E>")
7811 (set_attr "z10prop" "z10_super_c_E1")])
7812
7813 ; lcr, lcgr
7814 (define_insn "*neg<mode>2"
7815 [(set (match_operand:GPR 0 "register_operand" "=d")
7816 (neg:GPR (match_operand:GPR 1 "register_operand" "d")))
7817 (clobber (reg:CC CC_REGNUM))]
7818 ""
7819 "lc<g>r\t%0,%1"
7820 [(set_attr "op_type" "RR<E>")
7821 (set_attr "z10prop" "z10_super_c_E1")])
7822
7823 (define_insn "*negdi2_31"
7824 [(set (match_operand:DI 0 "register_operand" "=d")
7825 (neg:DI (match_operand:DI 1 "register_operand" "d")))
7826 (clobber (reg:CC CC_REGNUM))]
7827 "!TARGET_ZARCH"
7828 "#")
7829
7830 ; Split a DImode NEG on 31bit into 2 SImode NEGs
7831
7832 ; Doing the twos complement separately on the SImode parts does an
7833 ; unwanted +1 on the high part which needs to be subtracted afterwards
7834 ; ... unless the +1 on the low part created an overflow.
7835
7836 (define_split
7837 [(set (match_operand:DI 0 "register_operand" "")
7838 (neg:DI (match_operand:DI 1 "register_operand" "")))
7839 (clobber (reg:CC CC_REGNUM))]
7840 "!TARGET_ZARCH
7841 && (REGNO (operands[0]) == REGNO (operands[1])
7842 || s390_split_ok_p (operands[0], operands[1], DImode, 0))
7843 && reload_completed"
7844 [(parallel
7845 [(set (match_dup 2) (neg:SI (match_dup 3)))
7846 (clobber (reg:CC CC_REGNUM))])
7847 (parallel
7848 [(set (reg:CCAP CC_REGNUM)
7849 (compare:CCAP (neg:SI (match_dup 5)) (const_int 0)))
7850 (set (match_dup 4) (neg:SI (match_dup 5)))])
7851 (set (pc)
7852 (if_then_else (ne (reg:CCAP CC_REGNUM) (const_int 0))
7853 (pc)
7854 (label_ref (match_dup 6))))
7855 (parallel
7856 [(set (match_dup 2) (plus:SI (match_dup 2) (const_int -1)))
7857 (clobber (reg:CC CC_REGNUM))])
7858 (match_dup 6)]
7859 "operands[2] = operand_subword (operands[0], 0, 0, DImode);
7860 operands[3] = operand_subword (operands[1], 0, 0, DImode);
7861 operands[4] = operand_subword (operands[0], 1, 0, DImode);
7862 operands[5] = operand_subword (operands[1], 1, 0, DImode);
7863 operands[6] = gen_label_rtx ();")
7864
7865 ; Like above but first make a copy of the low part of the src operand
7866 ; since it might overlap with the high part of the destination.
7867
7868 (define_split
7869 [(set (match_operand:DI 0 "register_operand" "")
7870 (neg:DI (match_operand:DI 1 "register_operand" "")))
7871 (clobber (reg:CC CC_REGNUM))]
7872 "!TARGET_ZARCH
7873 && s390_split_ok_p (operands[0], operands[1], DImode, 1)
7874 && reload_completed"
7875 [; Make a backup of op5 first
7876 (set (match_dup 4) (match_dup 5))
7877 ; Setting op2 here might clobber op5
7878 (parallel
7879 [(set (match_dup 2) (neg:SI (match_dup 3)))
7880 (clobber (reg:CC CC_REGNUM))])
7881 (parallel
7882 [(set (reg:CCAP CC_REGNUM)
7883 (compare:CCAP (neg:SI (match_dup 4)) (const_int 0)))
7884 (set (match_dup 4) (neg:SI (match_dup 4)))])
7885 (set (pc)
7886 (if_then_else (ne (reg:CCAP CC_REGNUM) (const_int 0))
7887 (pc)
7888 (label_ref (match_dup 6))))
7889 (parallel
7890 [(set (match_dup 2) (plus:SI (match_dup 2) (const_int -1)))
7891 (clobber (reg:CC CC_REGNUM))])
7892 (match_dup 6)]
7893 "operands[2] = operand_subword (operands[0], 0, 0, DImode);
7894 operands[3] = operand_subword (operands[1], 0, 0, DImode);
7895 operands[4] = operand_subword (operands[0], 1, 0, DImode);
7896 operands[5] = operand_subword (operands[1], 1, 0, DImode);
7897 operands[6] = gen_label_rtx ();")
7898
7899 ;
7900 ; neg(df|sf)2 instruction pattern(s).
7901 ;
7902
7903 (define_expand "neg<mode>2"
7904 [(parallel
7905 [(set (match_operand:BFP 0 "register_operand" "=f")
7906 (neg:BFP (match_operand:BFP 1 "register_operand" "f")))
7907 (clobber (reg:CC CC_REGNUM))])]
7908 "TARGET_HARD_FLOAT"
7909 "")
7910
7911 ; lcxbr, lcdbr, lcebr
7912 (define_insn "*neg<mode>2_cc"
7913 [(set (reg CC_REGNUM)
7914 (compare (neg:BFP (match_operand:BFP 1 "register_operand" "f"))
7915 (match_operand:BFP 2 "const0_operand" "")))
7916 (set (match_operand:BFP 0 "register_operand" "=f")
7917 (neg:BFP (match_dup 1)))]
7918 "s390_match_ccmode (insn, CCSmode) && TARGET_HARD_FLOAT"
7919 "lc<xde>br\t%0,%1"
7920 [(set_attr "op_type" "RRE")
7921 (set_attr "type" "fsimp<mode>")])
7922
7923 ; lcxbr, lcdbr, lcebr
7924 (define_insn "*neg<mode>2_cconly"
7925 [(set (reg CC_REGNUM)
7926 (compare (neg:BFP (match_operand:BFP 1 "register_operand" "f"))
7927 (match_operand:BFP 2 "const0_operand" "")))
7928 (clobber (match_scratch:BFP 0 "=f"))]
7929 "s390_match_ccmode (insn, CCSmode) && TARGET_HARD_FLOAT"
7930 "lc<xde>br\t%0,%1"
7931 [(set_attr "op_type" "RRE")
7932 (set_attr "type" "fsimp<mode>")])
7933
7934 ; lcdfr
7935 (define_insn "*neg<mode>2_nocc"
7936 [(set (match_operand:FP 0 "register_operand" "=f")
7937 (neg:FP (match_operand:FP 1 "register_operand" "<fT0>")))]
7938 "TARGET_DFP"
7939 "lcdfr\t%0,%1"
7940 [(set_attr "op_type" "RRE")
7941 (set_attr "type" "fsimp<mode>")])
7942
7943 ; lcxbr, lcdbr, lcebr
7944 ; FIXME: wflcdb does not clobber cc
7945 (define_insn "*neg<mode>2"
7946 [(set (match_operand:BFP 0 "register_operand" "=f,<vf>")
7947 (neg:BFP (match_operand:BFP 1 "register_operand" "f,<vf>")))
7948 (clobber (reg:CC CC_REGNUM))]
7949 "TARGET_HARD_FLOAT"
7950 "@
7951 lc<xde>br\t%0,%1
7952 wflcdb\t%0,%1"
7953 [(set_attr "op_type" "RRE,VRR")
7954 (set_attr "cpu_facility" "*,vec")
7955 (set_attr "type" "fsimp<mode>,*")])
7956
7957
7958 ;;
7959 ;;- Absolute value instructions.
7960 ;;
7961
7962 ;
7963 ; abs(di|si)2 instruction pattern(s).
7964 ;
7965
7966 (define_insn "*absdi2_sign_cc"
7967 [(set (reg CC_REGNUM)
7968 (compare (abs:DI (ashiftrt:DI (ashift:DI (subreg:DI
7969 (match_operand:SI 1 "register_operand" "d") 0)
7970 (const_int 32)) (const_int 32)))
7971 (const_int 0)))
7972 (set (match_operand:DI 0 "register_operand" "=d")
7973 (abs:DI (sign_extend:DI (match_dup 1))))]
7974 "TARGET_ZARCH && s390_match_ccmode (insn, CCAmode)"
7975 "lpgfr\t%0,%1"
7976 [(set_attr "op_type" "RRE")
7977 (set_attr "z10prop" "z10_c")])
7978
7979 (define_insn "*absdi2_sign"
7980 [(set (match_operand:DI 0 "register_operand" "=d")
7981 (abs:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "d"))))
7982 (clobber (reg:CC CC_REGNUM))]
7983 "TARGET_ZARCH"
7984 "lpgfr\t%0,%1"
7985 [(set_attr "op_type" "RRE")
7986 (set_attr "z10prop" "z10_c")])
7987
7988 ; lpr, lpgr
7989 (define_insn "*abs<mode>2_cc"
7990 [(set (reg CC_REGNUM)
7991 (compare (abs:GPR (match_operand:DI 1 "register_operand" "d"))
7992 (const_int 0)))
7993 (set (match_operand:GPR 0 "register_operand" "=d")
7994 (abs:GPR (match_dup 1)))]
7995 "s390_match_ccmode (insn, CCAmode)"
7996 "lp<g>r\t%0,%1"
7997 [(set_attr "op_type" "RR<E>")
7998 (set_attr "z10prop" "z10_c")])
7999
8000 ; lpr, lpgr
8001 (define_insn "*abs<mode>2_cconly"
8002 [(set (reg CC_REGNUM)
8003 (compare (abs:GPR (match_operand:GPR 1 "register_operand" "d"))
8004 (const_int 0)))
8005 (clobber (match_scratch:GPR 0 "=d"))]
8006 "s390_match_ccmode (insn, CCAmode)"
8007 "lp<g>r\t%0,%1"
8008 [(set_attr "op_type" "RR<E>")
8009 (set_attr "z10prop" "z10_c")])
8010
8011 ; lpr, lpgr
8012 (define_insn "abs<mode>2"
8013 [(set (match_operand:GPR 0 "register_operand" "=d")
8014 (abs:GPR (match_operand:GPR 1 "register_operand" "d")))
8015 (clobber (reg:CC CC_REGNUM))]
8016 ""
8017 "lp<g>r\t%0,%1"
8018 [(set_attr "op_type" "RR<E>")
8019 (set_attr "z10prop" "z10_c")])
8020
8021 ;
8022 ; abs(df|sf)2 instruction pattern(s).
8023 ;
8024
8025 (define_expand "abs<mode>2"
8026 [(parallel
8027 [(set (match_operand:BFP 0 "register_operand" "=f")
8028 (abs:BFP (match_operand:BFP 1 "register_operand" "f")))
8029 (clobber (reg:CC CC_REGNUM))])]
8030 "TARGET_HARD_FLOAT"
8031 "")
8032
8033 ; lpxbr, lpdbr, lpebr
8034 (define_insn "*abs<mode>2_cc"
8035 [(set (reg CC_REGNUM)
8036 (compare (abs:BFP (match_operand:BFP 1 "register_operand" "f"))
8037 (match_operand:BFP 2 "const0_operand" "")))
8038 (set (match_operand:BFP 0 "register_operand" "=f")
8039 (abs:BFP (match_dup 1)))]
8040 "s390_match_ccmode (insn, CCSmode) && TARGET_HARD_FLOAT"
8041 "lp<xde>br\t%0,%1"
8042 [(set_attr "op_type" "RRE")
8043 (set_attr "type" "fsimp<mode>")])
8044
8045 ; lpxbr, lpdbr, lpebr
8046 (define_insn "*abs<mode>2_cconly"
8047 [(set (reg CC_REGNUM)
8048 (compare (abs:BFP (match_operand:BFP 1 "register_operand" "f"))
8049 (match_operand:BFP 2 "const0_operand" "")))
8050 (clobber (match_scratch:BFP 0 "=f"))]
8051 "s390_match_ccmode (insn, CCSmode) && TARGET_HARD_FLOAT"
8052 "lp<xde>br\t%0,%1"
8053 [(set_attr "op_type" "RRE")
8054 (set_attr "type" "fsimp<mode>")])
8055
8056 ; lpdfr
8057 (define_insn "*abs<mode>2_nocc"
8058 [(set (match_operand:FP 0 "register_operand" "=f")
8059 (abs:FP (match_operand:FP 1 "register_operand" "<fT0>")))]
8060 "TARGET_DFP"
8061 "lpdfr\t%0,%1"
8062 [(set_attr "op_type" "RRE")
8063 (set_attr "type" "fsimp<mode>")])
8064
8065 ; lpxbr, lpdbr, lpebr
8066 ; FIXME: wflpdb does not clobber cc
8067 (define_insn "*abs<mode>2"
8068 [(set (match_operand:BFP 0 "register_operand" "=f,<vf>")
8069 (abs:BFP (match_operand:BFP 1 "register_operand" "f,<vf>")))
8070 (clobber (reg:CC CC_REGNUM))]
8071 "TARGET_HARD_FLOAT"
8072 "@
8073 lp<xde>br\t%0,%1
8074 wflpdb\t%0,%1"
8075 [(set_attr "op_type" "RRE,VRR")
8076 (set_attr "cpu_facility" "*,vec")
8077 (set_attr "type" "fsimp<mode>,*")])
8078
8079
8080 ;;
8081 ;;- Negated absolute value instructions
8082 ;;
8083
8084 ;
8085 ; Integer
8086 ;
8087
8088 (define_insn "*negabsdi2_sign_cc"
8089 [(set (reg CC_REGNUM)
8090 (compare (neg:DI (abs:DI (ashiftrt:DI (ashift:DI (subreg:DI
8091 (match_operand:SI 1 "register_operand" "d") 0)
8092 (const_int 32)) (const_int 32))))
8093 (const_int 0)))
8094 (set (match_operand:DI 0 "register_operand" "=d")
8095 (neg:DI (abs:DI (sign_extend:DI (match_dup 1)))))]
8096 "TARGET_ZARCH && s390_match_ccmode (insn, CCAmode)"
8097 "lngfr\t%0,%1"
8098 [(set_attr "op_type" "RRE")
8099 (set_attr "z10prop" "z10_c")])
8100
8101 (define_insn "*negabsdi2_sign"
8102 [(set (match_operand:DI 0 "register_operand" "=d")
8103 (neg:DI (abs:DI (sign_extend:DI
8104 (match_operand:SI 1 "register_operand" "d")))))
8105 (clobber (reg:CC CC_REGNUM))]
8106 "TARGET_ZARCH"
8107 "lngfr\t%0,%1"
8108 [(set_attr "op_type" "RRE")
8109 (set_attr "z10prop" "z10_c")])
8110
8111 ; lnr, lngr
8112 (define_insn "*negabs<mode>2_cc"
8113 [(set (reg CC_REGNUM)
8114 (compare (neg:GPR (abs:GPR (match_operand:GPR 1 "register_operand" "d")))
8115 (const_int 0)))
8116 (set (match_operand:GPR 0 "register_operand" "=d")
8117 (neg:GPR (abs:GPR (match_dup 1))))]
8118 "s390_match_ccmode (insn, CCAmode)"
8119 "ln<g>r\t%0,%1"
8120 [(set_attr "op_type" "RR<E>")
8121 (set_attr "z10prop" "z10_c")])
8122
8123 ; lnr, lngr
8124 (define_insn "*negabs<mode>2_cconly"
8125 [(set (reg CC_REGNUM)
8126 (compare (neg:GPR (abs:GPR (match_operand:GPR 1 "register_operand" "d")))
8127 (const_int 0)))
8128 (clobber (match_scratch:GPR 0 "=d"))]
8129 "s390_match_ccmode (insn, CCAmode)"
8130 "ln<g>r\t%0,%1"
8131 [(set_attr "op_type" "RR<E>")
8132 (set_attr "z10prop" "z10_c")])
8133
8134 ; lnr, lngr
8135 (define_insn "*negabs<mode>2"
8136 [(set (match_operand:GPR 0 "register_operand" "=d")
8137 (neg:GPR (abs:GPR (match_operand:GPR 1 "register_operand" "d"))))
8138 (clobber (reg:CC CC_REGNUM))]
8139 ""
8140 "ln<g>r\t%0,%1"
8141 [(set_attr "op_type" "RR<E>")
8142 (set_attr "z10prop" "z10_c")])
8143
8144 ;
8145 ; Floating point
8146 ;
8147
8148 ; lnxbr, lndbr, lnebr
8149 (define_insn "*negabs<mode>2_cc"
8150 [(set (reg CC_REGNUM)
8151 (compare (neg:BFP (abs:BFP (match_operand:BFP 1 "register_operand" "f")))
8152 (match_operand:BFP 2 "const0_operand" "")))
8153 (set (match_operand:BFP 0 "register_operand" "=f")
8154 (neg:BFP (abs:BFP (match_dup 1))))]
8155 "s390_match_ccmode (insn, CCSmode) && TARGET_HARD_FLOAT"
8156 "ln<xde>br\t%0,%1"
8157 [(set_attr "op_type" "RRE")
8158 (set_attr "type" "fsimp<mode>")])
8159
8160 ; lnxbr, lndbr, lnebr
8161 (define_insn "*negabs<mode>2_cconly"
8162 [(set (reg CC_REGNUM)
8163 (compare (neg:BFP (abs:BFP (match_operand:BFP 1 "register_operand" "f")))
8164 (match_operand:BFP 2 "const0_operand" "")))
8165 (clobber (match_scratch:BFP 0 "=f"))]
8166 "s390_match_ccmode (insn, CCSmode) && TARGET_HARD_FLOAT"
8167 "ln<xde>br\t%0,%1"
8168 [(set_attr "op_type" "RRE")
8169 (set_attr "type" "fsimp<mode>")])
8170
8171 ; lndfr
8172 (define_insn "*negabs<mode>2_nocc"
8173 [(set (match_operand:FP 0 "register_operand" "=f")
8174 (neg:FP (abs:FP (match_operand:BFP 1 "register_operand" "<fT0>"))))]
8175 "TARGET_DFP"
8176 "lndfr\t%0,%1"
8177 [(set_attr "op_type" "RRE")
8178 (set_attr "type" "fsimp<mode>")])
8179
8180 ; lnxbr, lndbr, lnebr
8181 ; FIXME: wflndb does not clobber cc
8182 (define_insn "*negabs<mode>2"
8183 [(set (match_operand:BFP 0 "register_operand" "=f,<vf>")
8184 (neg:BFP (abs:BFP (match_operand:BFP 1 "register_operand" "f,<vf>"))))
8185 (clobber (reg:CC CC_REGNUM))]
8186 "TARGET_HARD_FLOAT"
8187 "@
8188 ln<xde>br\t%0,%1
8189 wflndb\t%0,%1"
8190 [(set_attr "op_type" "RRE,VRR")
8191 (set_attr "cpu_facility" "*,vec")
8192 (set_attr "type" "fsimp<mode>,*")])
8193
8194 ;;
8195 ;;- Square root instructions.
8196 ;;
8197
8198 ;
8199 ; sqrt(df|sf)2 instruction pattern(s).
8200 ;
8201
8202 ; sqxbr, sqdbr, sqebr, sqdb, sqeb
8203 (define_insn "sqrt<mode>2"
8204 [(set (match_operand:BFP 0 "register_operand" "=f, f,<vf>")
8205 (sqrt:BFP (match_operand:BFP 1 "general_operand" "f,<Rf>,<vf>")))]
8206 "TARGET_HARD_FLOAT"
8207 "@
8208 sq<xde>br\t%0,%1
8209 sq<xde>b\t%0,%1
8210 wfsqdb\t%v0,%v1"
8211 [(set_attr "op_type" "RRE,RXE,VRR")
8212 (set_attr "type" "fsqrt<mode>")
8213 (set_attr "cpu_facility" "*,*,vec")])
8214
8215
8216 ;;
8217 ;;- One complement instructions.
8218 ;;
8219
8220 ;
8221 ; one_cmpl(di|si|hi|qi)2 instruction pattern(s).
8222 ;
8223
8224 (define_expand "one_cmpl<mode>2"
8225 [(parallel
8226 [(set (match_operand:INT 0 "register_operand" "")
8227 (xor:INT (match_operand:INT 1 "register_operand" "")
8228 (const_int -1)))
8229 (clobber (reg:CC CC_REGNUM))])]
8230 ""
8231 "")
8232
8233
8234 ;;
8235 ;; Find leftmost bit instructions.
8236 ;;
8237
8238 (define_expand "clzdi2"
8239 [(set (match_operand:DI 0 "register_operand" "=d")
8240 (clz:DI (match_operand:DI 1 "register_operand" "d")))]
8241 "TARGET_EXTIMM && TARGET_ZARCH"
8242 {
8243 rtx insn, clz_equal;
8244 rtx wide_reg = gen_reg_rtx (TImode);
8245 rtx msb = gen_rtx_CONST_INT (DImode, (unsigned HOST_WIDE_INT) 1 << 63);
8246
8247 clz_equal = gen_rtx_CLZ (DImode, operands[1]);
8248
8249 emit_insn (gen_clztidi2 (wide_reg, operands[1], msb));
8250
8251 insn = emit_move_insn (operands[0], gen_highpart (DImode, wide_reg));
8252 set_unique_reg_note (insn, REG_EQUAL, clz_equal);
8253
8254 DONE;
8255 })
8256
8257 (define_insn "clztidi2"
8258 [(set (match_operand:TI 0 "register_operand" "=d")
8259 (ior:TI
8260 (ashift:TI
8261 (zero_extend:TI
8262 (xor:DI (match_operand:DI 1 "register_operand" "d")
8263 (lshiftrt (match_operand:DI 2 "const_int_operand" "")
8264 (subreg:SI (clz:DI (match_dup 1)) 4))))
8265
8266 (const_int 64))
8267 (zero_extend:TI (clz:DI (match_dup 1)))))
8268 (clobber (reg:CC CC_REGNUM))]
8269 "(unsigned HOST_WIDE_INT) INTVAL (operands[2])
8270 == (unsigned HOST_WIDE_INT) 1 << 63
8271 && TARGET_EXTIMM && TARGET_ZARCH"
8272 "flogr\t%0,%1"
8273 [(set_attr "op_type" "RRE")])
8274
8275
8276 ;;
8277 ;;- Rotate instructions.
8278 ;;
8279
8280 ;
8281 ; rotl(di|si)3 instruction pattern(s).
8282 ;
8283
8284 ; rll, rllg
8285 (define_insn "rotl<mode>3"
8286 [(set (match_operand:GPR 0 "register_operand" "=d")
8287 (rotate:GPR (match_operand:GPR 1 "register_operand" "d")
8288 (match_operand:SI 2 "shift_count_or_setmem_operand" "Y")))]
8289 "TARGET_CPU_ZARCH"
8290 "rll<g>\t%0,%1,%Y2"
8291 [(set_attr "op_type" "RSE")
8292 (set_attr "atype" "reg")
8293 (set_attr "z10prop" "z10_super_E1")])
8294
8295 ; rll, rllg
8296 (define_insn "*rotl<mode>3_and"
8297 [(set (match_operand:GPR 0 "register_operand" "=d")
8298 (rotate:GPR (match_operand:GPR 1 "register_operand" "d")
8299 (and:SI (match_operand:SI 2 "shift_count_or_setmem_operand" "Y")
8300 (match_operand:SI 3 "const_int_operand" "n"))))]
8301 "TARGET_CPU_ZARCH && (INTVAL (operands[3]) & 63) == 63"
8302 "rll<g>\t%0,%1,%Y2"
8303 [(set_attr "op_type" "RSE")
8304 (set_attr "atype" "reg")
8305 (set_attr "z10prop" "z10_super_E1")])
8306
8307
8308 ;;
8309 ;;- Shift instructions.
8310 ;;
8311
8312 ;
8313 ; (ashl|lshr)(di|si)3 instruction pattern(s).
8314 ; Left shifts and logical right shifts
8315
8316 (define_expand "<shift><mode>3"
8317 [(set (match_operand:DSI 0 "register_operand" "")
8318 (SHIFT:DSI (match_operand:DSI 1 "register_operand" "")
8319 (match_operand:SI 2 "shift_count_or_setmem_operand" "")))]
8320 ""
8321 "")
8322
8323 ; sldl, srdl
8324 (define_insn "*<shift>di3_31"
8325 [(set (match_operand:DI 0 "register_operand" "=d")
8326 (SHIFT:DI (match_operand:DI 1 "register_operand" "0")
8327 (match_operand:SI 2 "shift_count_or_setmem_operand" "Y")))]
8328 "!TARGET_ZARCH"
8329 "s<lr>dl\t%0,%Y2"
8330 [(set_attr "op_type" "RS")
8331 (set_attr "atype" "reg")
8332 (set_attr "z196prop" "z196_cracked")])
8333
8334 ; sll, srl, sllg, srlg, sllk, srlk
8335 (define_insn "*<shift><mode>3"
8336 [(set (match_operand:GPR 0 "register_operand" "=d,d")
8337 (SHIFT:GPR (match_operand:GPR 1 "register_operand" "<d0>,d")
8338 (match_operand:SI 2 "shift_count_or_setmem_operand" "Y,Y")))]
8339 ""
8340 "@
8341 s<lr>l<g>\t%0,<1>%Y2
8342 s<lr>l<gk>\t%0,%1,%Y2"
8343 [(set_attr "op_type" "RS<E>,RSY")
8344 (set_attr "atype" "reg,reg")
8345 (set_attr "cpu_facility" "*,z196")
8346 (set_attr "z10prop" "z10_super_E1,*")])
8347
8348 ; sldl, srdl
8349 (define_insn "*<shift>di3_31_and"
8350 [(set (match_operand:DI 0 "register_operand" "=d")
8351 (SHIFT:DI (match_operand:DI 1 "register_operand" "0")
8352 (and:SI (match_operand:SI 2 "shift_count_or_setmem_operand" "Y")
8353 (match_operand:SI 3 "const_int_operand" "n"))))]
8354 "!TARGET_ZARCH && (INTVAL (operands[3]) & 63) == 63"
8355 "s<lr>dl\t%0,%Y2"
8356 [(set_attr "op_type" "RS")
8357 (set_attr "atype" "reg")])
8358
8359 ; sll, srl, sllg, srlg, sllk, srlk
8360 (define_insn "*<shift><mode>3_and"
8361 [(set (match_operand:GPR 0 "register_operand" "=d,d")
8362 (SHIFT:GPR (match_operand:GPR 1 "register_operand" "<d0>,d")
8363 (and:SI (match_operand:SI 2 "shift_count_or_setmem_operand" "Y,Y")
8364 (match_operand:SI 3 "const_int_operand" "n,n"))))]
8365 "(INTVAL (operands[3]) & 63) == 63"
8366 "@
8367 s<lr>l<g>\t%0,<1>%Y2
8368 s<lr>l<gk>\t%0,%1,%Y2"
8369 [(set_attr "op_type" "RS<E>,RSY")
8370 (set_attr "atype" "reg,reg")
8371 (set_attr "cpu_facility" "*,z196")
8372 (set_attr "z10prop" "z10_super_E1,*")])
8373
8374 ;
8375 ; ashr(di|si)3 instruction pattern(s).
8376 ; Arithmetic right shifts
8377
8378 (define_expand "ashr<mode>3"
8379 [(parallel
8380 [(set (match_operand:DSI 0 "register_operand" "")
8381 (ashiftrt:DSI (match_operand:DSI 1 "register_operand" "")
8382 (match_operand:SI 2 "shift_count_or_setmem_operand" "")))
8383 (clobber (reg:CC CC_REGNUM))])]
8384 ""
8385 "")
8386
8387 (define_insn "*ashrdi3_cc_31"
8388 [(set (reg CC_REGNUM)
8389 (compare (ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
8390 (match_operand:SI 2 "shift_count_or_setmem_operand" "Y"))
8391 (const_int 0)))
8392 (set (match_operand:DI 0 "register_operand" "=d")
8393 (ashiftrt:DI (match_dup 1) (match_dup 2)))]
8394 "!TARGET_ZARCH && s390_match_ccmode(insn, CCSmode)"
8395 "srda\t%0,%Y2"
8396 [(set_attr "op_type" "RS")
8397 (set_attr "atype" "reg")])
8398
8399 (define_insn "*ashrdi3_cconly_31"
8400 [(set (reg CC_REGNUM)
8401 (compare (ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
8402 (match_operand:SI 2 "shift_count_or_setmem_operand" "Y"))
8403 (const_int 0)))
8404 (clobber (match_scratch:DI 0 "=d"))]
8405 "!TARGET_ZARCH && s390_match_ccmode(insn, CCSmode)"
8406 "srda\t%0,%Y2"
8407 [(set_attr "op_type" "RS")
8408 (set_attr "atype" "reg")])
8409
8410 (define_insn "*ashrdi3_31"
8411 [(set (match_operand:DI 0 "register_operand" "=d")
8412 (ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
8413 (match_operand:SI 2 "shift_count_or_setmem_operand" "Y")))
8414 (clobber (reg:CC CC_REGNUM))]
8415 "!TARGET_ZARCH"
8416 "srda\t%0,%Y2"
8417 [(set_attr "op_type" "RS")
8418 (set_attr "atype" "reg")])
8419
8420 ; sra, srag, srak
8421 (define_insn "*ashr<mode>3_cc"
8422 [(set (reg CC_REGNUM)
8423 (compare (ashiftrt:GPR (match_operand:GPR 1 "register_operand" "<d0>,d")
8424 (match_operand:SI 2 "shift_count_or_setmem_operand" "Y,Y"))
8425 (const_int 0)))
8426 (set (match_operand:GPR 0 "register_operand" "=d,d")
8427 (ashiftrt:GPR (match_dup 1) (match_dup 2)))]
8428 "s390_match_ccmode(insn, CCSmode)"
8429 "@
8430 sra<g>\t%0,<1>%Y2
8431 sra<gk>\t%0,%1,%Y2"
8432 [(set_attr "op_type" "RS<E>,RSY")
8433 (set_attr "atype" "reg,reg")
8434 (set_attr "cpu_facility" "*,z196")
8435 (set_attr "z10prop" "z10_super_E1,*")])
8436
8437 ; sra, srag, srak
8438 (define_insn "*ashr<mode>3_cconly"
8439 [(set (reg CC_REGNUM)
8440 (compare (ashiftrt:GPR (match_operand:GPR 1 "register_operand" "<d0>,d")
8441 (match_operand:SI 2 "shift_count_or_setmem_operand" "Y,Y"))
8442 (const_int 0)))
8443 (clobber (match_scratch:GPR 0 "=d,d"))]
8444 "s390_match_ccmode(insn, CCSmode)"
8445 "@
8446 sra<g>\t%0,<1>%Y2
8447 sra<gk>\t%0,%1,%Y2"
8448 [(set_attr "op_type" "RS<E>,RSY")
8449 (set_attr "atype" "reg,reg")
8450 (set_attr "cpu_facility" "*,z196")
8451 (set_attr "z10prop" "z10_super_E1,*")])
8452
8453 ; sra, srag
8454 (define_insn "*ashr<mode>3"
8455 [(set (match_operand:GPR 0 "register_operand" "=d,d")
8456 (ashiftrt:GPR (match_operand:GPR 1 "register_operand" "<d0>,d")
8457 (match_operand:SI 2 "shift_count_or_setmem_operand" "Y,Y")))
8458 (clobber (reg:CC CC_REGNUM))]
8459 ""
8460 "@
8461 sra<g>\t%0,<1>%Y2
8462 sra<gk>\t%0,%1,%Y2"
8463 [(set_attr "op_type" "RS<E>,RSY")
8464 (set_attr "atype" "reg,reg")
8465 (set_attr "cpu_facility" "*,z196")
8466 (set_attr "z10prop" "z10_super_E1,*")])
8467
8468
8469 ; shift pattern with implicit ANDs
8470
8471 (define_insn "*ashrdi3_cc_31_and"
8472 [(set (reg CC_REGNUM)
8473 (compare (ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
8474 (and:SI (match_operand:SI 2 "shift_count_or_setmem_operand" "Y")
8475 (match_operand:SI 3 "const_int_operand" "n")))
8476 (const_int 0)))
8477 (set (match_operand:DI 0 "register_operand" "=d")
8478 (ashiftrt:DI (match_dup 1) (and:SI (match_dup 2) (match_dup 3))))]
8479 "!TARGET_ZARCH && s390_match_ccmode(insn, CCSmode)
8480 && (INTVAL (operands[3]) & 63) == 63"
8481 "srda\t%0,%Y2"
8482 [(set_attr "op_type" "RS")
8483 (set_attr "atype" "reg")])
8484
8485 (define_insn "*ashrdi3_cconly_31_and"
8486 [(set (reg CC_REGNUM)
8487 (compare (ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
8488 (and:SI (match_operand:SI 2 "shift_count_or_setmem_operand" "Y")
8489 (match_operand:SI 3 "const_int_operand" "n")))
8490 (const_int 0)))
8491 (clobber (match_scratch:DI 0 "=d"))]
8492 "!TARGET_ZARCH && s390_match_ccmode(insn, CCSmode)
8493 && (INTVAL (operands[3]) & 63) == 63"
8494 "srda\t%0,%Y2"
8495 [(set_attr "op_type" "RS")
8496 (set_attr "atype" "reg")])
8497
8498 (define_insn "*ashrdi3_31_and"
8499 [(set (match_operand:DI 0 "register_operand" "=d")
8500 (ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
8501 (and:SI (match_operand:SI 2 "shift_count_or_setmem_operand" "Y")
8502 (match_operand:SI 3 "const_int_operand" "n"))))
8503 (clobber (reg:CC CC_REGNUM))]
8504 "!TARGET_ZARCH && (INTVAL (operands[3]) & 63) == 63"
8505 "srda\t%0,%Y2"
8506 [(set_attr "op_type" "RS")
8507 (set_attr "atype" "reg")])
8508
8509 ; sra, srag, srak
8510 (define_insn "*ashr<mode>3_cc_and"
8511 [(set (reg CC_REGNUM)
8512 (compare (ashiftrt:GPR (match_operand:GPR 1 "register_operand" "<d0>,d")
8513 (and:SI (match_operand:SI 2 "shift_count_or_setmem_operand" "Y,Y")
8514 (match_operand:SI 3 "const_int_operand" "n,n")))
8515 (const_int 0)))
8516 (set (match_operand:GPR 0 "register_operand" "=d,d")
8517 (ashiftrt:GPR (match_dup 1) (and:SI (match_dup 2) (match_dup 3))))]
8518 "s390_match_ccmode(insn, CCSmode) && (INTVAL (operands[3]) & 63) == 63"
8519 "@
8520 sra<g>\t%0,<1>%Y2
8521 sra<gk>\t%0,%1,%Y2"
8522 [(set_attr "op_type" "RS<E>,RSY")
8523 (set_attr "atype" "reg,reg")
8524 (set_attr "cpu_facility" "*,z196")
8525 (set_attr "z10prop" "z10_super_E1,*")])
8526
8527 ; sra, srag, srak
8528 (define_insn "*ashr<mode>3_cconly_and"
8529 [(set (reg CC_REGNUM)
8530 (compare (ashiftrt:GPR (match_operand:GPR 1 "register_operand" "<d0>,d")
8531 (and:SI (match_operand:SI 2 "shift_count_or_setmem_operand" "Y,Y")
8532 (match_operand:SI 3 "const_int_operand" "n,n")))
8533 (const_int 0)))
8534 (clobber (match_scratch:GPR 0 "=d,d"))]
8535 "s390_match_ccmode(insn, CCSmode) && (INTVAL (operands[3]) & 63) == 63"
8536 "@
8537 sra<g>\t%0,<1>%Y2
8538 sra<gk>\t%0,%1,%Y2"
8539 [(set_attr "op_type" "RS<E>,RSY")
8540 (set_attr "atype" "reg,reg")
8541 (set_attr "cpu_facility" "*,z196")
8542 (set_attr "z10prop" "z10_super_E1,*")])
8543
8544 ; sra, srag, srak
8545 (define_insn "*ashr<mode>3_and"
8546 [(set (match_operand:GPR 0 "register_operand" "=d,d")
8547 (ashiftrt:GPR (match_operand:GPR 1 "register_operand" "<d0>,d")
8548 (and:SI (match_operand:SI 2 "shift_count_or_setmem_operand" "Y,Y")
8549 (match_operand:SI 3 "const_int_operand" "n,n"))))
8550 (clobber (reg:CC CC_REGNUM))]
8551 "(INTVAL (operands[3]) & 63) == 63"
8552 "@
8553 sra<g>\t%0,<1>%Y2
8554 sra<gk>\t%0,%1,%Y2"
8555 [(set_attr "op_type" "RS<E>,RSY")
8556 (set_attr "atype" "reg,reg")
8557 (set_attr "cpu_facility" "*,z196")
8558 (set_attr "z10prop" "z10_super_E1,*")])
8559
8560
8561 ;;
8562 ;; Branch instruction patterns.
8563 ;;
8564
8565 (define_expand "cbranch<mode>4"
8566 [(set (pc)
8567 (if_then_else (match_operator 0 "comparison_operator"
8568 [(match_operand:GPR 1 "register_operand" "")
8569 (match_operand:GPR 2 "general_operand" "")])
8570 (label_ref (match_operand 3 "" ""))
8571 (pc)))]
8572 ""
8573 "s390_emit_jump (operands[3],
8574 s390_emit_compare (GET_CODE (operands[0]), operands[1], operands[2]));
8575 DONE;")
8576
8577 (define_expand "cbranch<mode>4"
8578 [(set (pc)
8579 (if_then_else (match_operator 0 "comparison_operator"
8580 [(match_operand:FP 1 "register_operand" "")
8581 (match_operand:FP 2 "general_operand" "")])
8582 (label_ref (match_operand 3 "" ""))
8583 (pc)))]
8584 "TARGET_HARD_FLOAT"
8585 "s390_emit_jump (operands[3],
8586 s390_emit_compare (GET_CODE (operands[0]), operands[1], operands[2]));
8587 DONE;")
8588
8589 (define_expand "cbranchcc4"
8590 [(set (pc)
8591 (if_then_else (match_operator 0 "s390_comparison"
8592 [(match_operand 1 "cc_reg_operand" "")
8593 (match_operand 2 "const_int_operand" "")])
8594 (label_ref (match_operand 3 "" ""))
8595 (pc)))]
8596 ""
8597 "")
8598
8599
8600 ;;
8601 ;;- Conditional jump instructions.
8602 ;;
8603
8604 (define_insn "*cjump_64"
8605 [(set (pc)
8606 (if_then_else
8607 (match_operator 1 "s390_comparison" [(reg CC_REGNUM)
8608 (match_operand 2 "const_int_operand" "")])
8609 (label_ref (match_operand 0 "" ""))
8610 (pc)))]
8611 "TARGET_CPU_ZARCH"
8612 {
8613 if (get_attr_length (insn) == 4)
8614 return "j%C1\t%l0";
8615 else
8616 return "jg%C1\t%l0";
8617 }
8618 [(set_attr "op_type" "RI")
8619 (set_attr "type" "branch")
8620 (set (attr "length")
8621 (if_then_else (lt (abs (minus (pc) (match_dup 0))) (const_int 60000))
8622 (const_int 4) (const_int 6)))])
8623
8624 (define_insn "*cjump_31"
8625 [(set (pc)
8626 (if_then_else
8627 (match_operator 1 "s390_comparison" [(reg CC_REGNUM)
8628 (match_operand 2 "const_int_operand" "")])
8629 (label_ref (match_operand 0 "" ""))
8630 (pc)))]
8631 "!TARGET_CPU_ZARCH"
8632 {
8633 gcc_assert (get_attr_length (insn) == 4);
8634 return "j%C1\t%l0";
8635 }
8636 [(set_attr "op_type" "RI")
8637 (set_attr "type" "branch")
8638 (set (attr "length")
8639 (if_then_else (not (match_test "flag_pic"))
8640 (if_then_else (lt (abs (minus (pc) (match_dup 0))) (const_int 60000))
8641 (const_int 4) (const_int 6))
8642 (if_then_else (lt (abs (minus (pc) (match_dup 0))) (const_int 60000))
8643 (const_int 4) (const_int 8))))])
8644
8645 (define_insn "*cjump_long"
8646 [(set (pc)
8647 (if_then_else
8648 (match_operator 1 "s390_comparison" [(reg CC_REGNUM) (const_int 0)])
8649 (match_operand 0 "address_operand" "ZQZR")
8650 (pc)))]
8651 ""
8652 {
8653 if (get_attr_op_type (insn) == OP_TYPE_RR)
8654 return "b%C1r\t%0";
8655 else
8656 return "b%C1\t%a0";
8657 }
8658 [(set (attr "op_type")
8659 (if_then_else (match_operand 0 "register_operand" "")
8660 (const_string "RR") (const_string "RX")))
8661 (set_attr "type" "branch")
8662 (set_attr "atype" "agen")])
8663
8664 ;; A conditional return instruction.
8665 (define_insn "*c<code>"
8666 [(set (pc)
8667 (if_then_else
8668 (match_operator 0 "s390_comparison" [(reg CC_REGNUM) (const_int 0)])
8669 (ANY_RETURN)
8670 (pc)))]
8671 "s390_can_use_<code>_insn ()"
8672 "b%C0r\t%%r14"
8673 [(set_attr "op_type" "RR")
8674 (set_attr "type" "jsr")
8675 (set_attr "atype" "agen")])
8676
8677 ;;
8678 ;;- Negated conditional jump instructions.
8679 ;;
8680
8681 (define_insn "*icjump_64"
8682 [(set (pc)
8683 (if_then_else
8684 (match_operator 1 "s390_comparison" [(reg CC_REGNUM) (const_int 0)])
8685 (pc)
8686 (label_ref (match_operand 0 "" ""))))]
8687 "TARGET_CPU_ZARCH"
8688 {
8689 if (get_attr_length (insn) == 4)
8690 return "j%D1\t%l0";
8691 else
8692 return "jg%D1\t%l0";
8693 }
8694 [(set_attr "op_type" "RI")
8695 (set_attr "type" "branch")
8696 (set (attr "length")
8697 (if_then_else (lt (abs (minus (pc) (match_dup 0))) (const_int 60000))
8698 (const_int 4) (const_int 6)))])
8699
8700 (define_insn "*icjump_31"
8701 [(set (pc)
8702 (if_then_else
8703 (match_operator 1 "s390_comparison" [(reg CC_REGNUM) (const_int 0)])
8704 (pc)
8705 (label_ref (match_operand 0 "" ""))))]
8706 "!TARGET_CPU_ZARCH"
8707 {
8708 gcc_assert (get_attr_length (insn) == 4);
8709 return "j%D1\t%l0";
8710 }
8711 [(set_attr "op_type" "RI")
8712 (set_attr "type" "branch")
8713 (set (attr "length")
8714 (if_then_else (not (match_test "flag_pic"))
8715 (if_then_else (lt (abs (minus (pc) (match_dup 0))) (const_int 60000))
8716 (const_int 4) (const_int 6))
8717 (if_then_else (lt (abs (minus (pc) (match_dup 0))) (const_int 60000))
8718 (const_int 4) (const_int 8))))])
8719
8720 (define_insn "*icjump_long"
8721 [(set (pc)
8722 (if_then_else
8723 (match_operator 1 "s390_comparison" [(reg CC_REGNUM) (const_int 0)])
8724 (pc)
8725 (match_operand 0 "address_operand" "ZQZR")))]
8726 ""
8727 {
8728 if (get_attr_op_type (insn) == OP_TYPE_RR)
8729 return "b%D1r\t%0";
8730 else
8731 return "b%D1\t%a0";
8732 }
8733 [(set (attr "op_type")
8734 (if_then_else (match_operand 0 "register_operand" "")
8735 (const_string "RR") (const_string "RX")))
8736 (set_attr "type" "branch")
8737 (set_attr "atype" "agen")])
8738
8739 ;;
8740 ;;- Trap instructions.
8741 ;;
8742
8743 (define_insn "trap"
8744 [(trap_if (const_int 1) (const_int 0))]
8745 ""
8746 "j\t.+2"
8747 [(set_attr "op_type" "RI")
8748 (set_attr "type" "branch")])
8749
8750 (define_expand "ctrap<mode>4"
8751 [(trap_if (match_operator 0 "comparison_operator"
8752 [(match_operand:GPR 1 "register_operand" "")
8753 (match_operand:GPR 2 "general_operand" "")])
8754 (match_operand 3 "const0_operand" ""))]
8755 ""
8756 {
8757 rtx cond = s390_emit_compare (GET_CODE (operands[0]),
8758 operands[1], operands[2]);
8759 emit_insn (gen_condtrap (cond, XEXP (cond, 0)));
8760 DONE;
8761 })
8762
8763 (define_expand "ctrap<mode>4"
8764 [(trap_if (match_operator 0 "comparison_operator"
8765 [(match_operand:FP 1 "register_operand" "")
8766 (match_operand:FP 2 "general_operand" "")])
8767 (match_operand 3 "const0_operand" ""))]
8768 ""
8769 {
8770 rtx cond = s390_emit_compare (GET_CODE (operands[0]),
8771 operands[1], operands[2]);
8772 emit_insn (gen_condtrap (cond, XEXP (cond, 0)));
8773 DONE;
8774 })
8775
8776 (define_insn "condtrap"
8777 [(trap_if (match_operator 0 "s390_comparison"
8778 [(match_operand 1 "cc_reg_operand" "c")
8779 (const_int 0)])
8780 (const_int 0))]
8781 ""
8782 "j%C0\t.+2";
8783 [(set_attr "op_type" "RI")
8784 (set_attr "type" "branch")])
8785
8786 ; crt, cgrt, cit, cgit
8787 (define_insn "*cmp_and_trap_signed_int<mode>"
8788 [(trap_if (match_operator 0 "s390_signed_integer_comparison"
8789 [(match_operand:GPR 1 "register_operand" "d,d")
8790 (match_operand:GPR 2 "nonmemory_operand" "d,K")])
8791 (const_int 0))]
8792 "TARGET_Z10"
8793 "@
8794 c<g>rt%C0\t%1,%2
8795 c<g>it%C0\t%1,%h2"
8796 [(set_attr "op_type" "RRF,RIE")
8797 (set_attr "type" "branch")
8798 (set_attr "z10prop" "z10_super_c,z10_super")])
8799
8800 ; clrt, clgrt, clfit, clgit, clt, clgt
8801 (define_insn "*cmp_and_trap_unsigned_int<mode>"
8802 [(trap_if (match_operator 0 "s390_unsigned_integer_comparison"
8803 [(match_operand:GPR 1 "register_operand" "d,d, d")
8804 (match_operand:GPR 2 "general_operand" "d,D,RT")])
8805 (const_int 0))]
8806 "TARGET_Z10"
8807 "@
8808 cl<g>rt%C0\t%1,%2
8809 cl<gf>it%C0\t%1,%x2
8810 cl<g>t%C0\t%1,%2"
8811 [(set_attr "op_type" "RRF,RIE,RSY")
8812 (set_attr "type" "branch")
8813 (set_attr "z10prop" "z10_super_c,z10_super,*")
8814 (set_attr "cpu_facility" "z10,z10,zEC12")])
8815
8816 ; lat, lgat
8817 (define_insn "*load_and_trap<mode>"
8818 [(trap_if (eq (match_operand:GPR 0 "memory_operand" "RT")
8819 (const_int 0))
8820 (const_int 0))
8821 (set (match_operand:GPR 1 "register_operand" "=d")
8822 (match_dup 0))]
8823 "TARGET_ZEC12"
8824 "l<g>at\t%1,%0"
8825 [(set_attr "op_type" "RXY")])
8826
8827
8828 ;;
8829 ;;- Loop instructions.
8830 ;;
8831 ;; This is all complicated by the fact that since this is a jump insn
8832 ;; we must handle our own output reloads.
8833
8834 ;; branch on index
8835
8836 ; This splitter will be matched by combine and has to add the 2 moves
8837 ; necessary to load the compare and the increment values into a
8838 ; register pair as needed by brxle.
8839
8840 (define_insn_and_split "*brx_stage1_<GPR:mode>"
8841 [(set (pc)
8842 (if_then_else
8843 (match_operator 6 "s390_brx_operator"
8844 [(plus:GPR (match_operand:GPR 1 "register_operand" "")
8845 (match_operand:GPR 2 "general_operand" ""))
8846 (match_operand:GPR 3 "register_operand" "")])
8847 (label_ref (match_operand 0 "" ""))
8848 (pc)))
8849 (set (match_operand:GPR 4 "nonimmediate_operand" "")
8850 (plus:GPR (match_dup 1) (match_dup 2)))
8851 (clobber (match_scratch:GPR 5 ""))]
8852 "TARGET_CPU_ZARCH"
8853 "#"
8854 "!reload_completed && !reload_in_progress"
8855 [(set (match_dup 7) (match_dup 2)) ; the increment
8856 (set (match_dup 8) (match_dup 3)) ; the comparison value
8857 (parallel [(set (pc)
8858 (if_then_else
8859 (match_op_dup 6
8860 [(plus:GPR (match_dup 1) (match_dup 7))
8861 (match_dup 8)])
8862 (label_ref (match_dup 0))
8863 (pc)))
8864 (set (match_dup 4)
8865 (plus:GPR (match_dup 1) (match_dup 7)))
8866 (clobber (match_dup 5))
8867 (clobber (reg:CC CC_REGNUM))])]
8868 {
8869 rtx dreg = gen_reg_rtx (word_mode == DImode ? TImode : DImode);
8870 operands[7] = gen_lowpart (<GPR:MODE>mode,
8871 gen_highpart (word_mode, dreg));
8872 operands[8] = gen_lowpart (<GPR:MODE>mode,
8873 gen_lowpart (word_mode, dreg));
8874 })
8875
8876 ; brxlg, brxhg
8877
8878 (define_insn_and_split "*brxg_64bit"
8879 [(set (pc)
8880 (if_then_else
8881 (match_operator 5 "s390_brx_operator"
8882 [(plus:DI (match_operand:DI 1 "register_operand" "d,d,d")
8883 (subreg:DI (match_operand:TI 2 "register_operand" "d,d,d") 0))
8884 (subreg:DI (match_dup 2) 8)])
8885 (label_ref (match_operand 0 "" ""))
8886 (pc)))
8887 (set (match_operand:DI 3 "nonimmediate_operand" "=1,?X,?X")
8888 (plus:DI (match_dup 1)
8889 (subreg:DI (match_dup 2) 0)))
8890 (clobber (match_scratch:DI 4 "=X,&1,&?d"))
8891 (clobber (reg:CC CC_REGNUM))]
8892 "TARGET_ZARCH"
8893 {
8894 if (which_alternative != 0)
8895 return "#";
8896 else if (get_attr_length (insn) == 6)
8897 return "brx%E5g\t%1,%2,%l0";
8898 else
8899 return "agr\t%1,%2\;cgr\t%1,%M2\;jg%C5\t%l0";
8900 }
8901 "&& reload_completed
8902 && (!REG_P (operands[3])
8903 || !rtx_equal_p (operands[1], operands[3]))"
8904 [(set (match_dup 4) (match_dup 1))
8905 (parallel [(set (match_dup 4) (plus:DI (match_dup 4) (subreg:DI (match_dup 2) 0)))
8906 (clobber (reg:CC CC_REGNUM))])
8907 (set (reg:CCS CC_REGNUM) (compare:CCS (match_dup 4) (subreg:DI (match_dup 2) 8)))
8908 (set (match_dup 3) (match_dup 4))
8909 (set (pc) (if_then_else (match_op_dup 5 [(reg:CCS CC_REGNUM) (const_int 0)])
8910 (label_ref (match_dup 0))
8911 (pc)))]
8912 ""
8913 [(set_attr "op_type" "RIE")
8914 (set_attr "type" "branch")
8915 (set (attr "length")
8916 (if_then_else (lt (abs (minus (pc) (match_dup 0))) (const_int 60000))
8917 (const_int 6) (const_int 16)))])
8918
8919 ; brxle, brxh
8920
8921 (define_insn_and_split "*brx_64bit"
8922 [(set (pc)
8923 (if_then_else
8924 (match_operator 5 "s390_brx_operator"
8925 [(plus:SI (match_operand:SI 1 "register_operand" "d,d,d")
8926 (subreg:SI (match_operand:TI 2 "register_operand" "d,d,d") 4))
8927 (subreg:SI (match_dup 2) 12)])
8928 (label_ref (match_operand 0 "" ""))
8929 (pc)))
8930 (set (match_operand:SI 3 "nonimmediate_operand" "=1,?X,?X")
8931 (plus:SI (match_dup 1)
8932 (subreg:SI (match_dup 2) 4)))
8933 (clobber (match_scratch:SI 4 "=X,&1,&?d"))
8934 (clobber (reg:CC CC_REGNUM))]
8935 "TARGET_ZARCH"
8936 {
8937 if (which_alternative != 0)
8938 return "#";
8939 else if (get_attr_length (insn) == 6)
8940 return "brx%C5\t%1,%2,%l0";
8941 else
8942 return "ar\t%1,%2\;cr\t%1,%M2\;jg%C5\t%l0";
8943 }
8944 "&& reload_completed
8945 && (!REG_P (operands[3])
8946 || !rtx_equal_p (operands[1], operands[3]))"
8947 [(set (match_dup 4) (match_dup 1))
8948 (parallel [(set (match_dup 4) (plus:SI (match_dup 4) (subreg:SI (match_dup 2) 4)))
8949 (clobber (reg:CC CC_REGNUM))])
8950 (set (reg:CCS CC_REGNUM) (compare:CCS (match_dup 4) (subreg:SI (match_dup 2) 12)))
8951 (set (match_dup 3) (match_dup 4))
8952 (set (pc) (if_then_else (match_op_dup 5 [(reg:CCS CC_REGNUM) (const_int 0)])
8953 (label_ref (match_dup 0))
8954 (pc)))]
8955 ""
8956 [(set_attr "op_type" "RSI")
8957 (set_attr "type" "branch")
8958 (set (attr "length")
8959 (if_then_else (lt (abs (minus (pc) (match_dup 0))) (const_int 60000))
8960 (const_int 6) (const_int 14)))])
8961
8962 ; brxle, brxh
8963
8964 (define_insn_and_split "*brx_31bit"
8965 [(set (pc)
8966 (if_then_else
8967 (match_operator 5 "s390_brx_operator"
8968 [(plus:SI (match_operand:SI 1 "register_operand" "d,d,d")
8969 (subreg:SI (match_operand:DI 2 "register_operand" "d,d,d") 0))
8970 (subreg:SI (match_dup 2) 4)])
8971 (label_ref (match_operand 0 "" ""))
8972 (pc)))
8973 (set (match_operand:SI 3 "nonimmediate_operand" "=1,?X,?X")
8974 (plus:SI (match_dup 1)
8975 (subreg:SI (match_dup 2) 0)))
8976 (clobber (match_scratch:SI 4 "=X,&1,&?d"))
8977 (clobber (reg:CC CC_REGNUM))]
8978 "!TARGET_ZARCH && TARGET_CPU_ZARCH"
8979 {
8980 if (which_alternative != 0)
8981 return "#";
8982 else if (get_attr_length (insn) == 6)
8983 return "brx%C5\t%1,%2,%l0";
8984 else
8985 return "ar\t%1,%2\;cr\t%1,%M2\;jg%C5\t%l0";
8986 }
8987 "&& reload_completed
8988 && (!REG_P (operands[3])
8989 || !rtx_equal_p (operands[1], operands[3]))"
8990 [(set (match_dup 4) (match_dup 1))
8991 (parallel [(set (match_dup 4) (plus:SI (match_dup 4) (subreg:SI (match_dup 2) 0)))
8992 (clobber (reg:CC CC_REGNUM))])
8993 (set (reg:CCS CC_REGNUM) (compare:CCS (match_dup 4) (subreg:SI (match_dup 2) 4)))
8994 (set (match_dup 3) (match_dup 4))
8995 (set (pc) (if_then_else (match_op_dup 5 [(reg:CCS CC_REGNUM) (const_int 0)])
8996 (label_ref (match_dup 0))
8997 (pc)))]
8998 ""
8999 [(set_attr "op_type" "RSI")
9000 (set_attr "type" "branch")
9001 (set (attr "length")
9002 (if_then_else (lt (abs (minus (pc) (match_dup 0))) (const_int 60000))
9003 (const_int 6) (const_int 14)))])
9004
9005
9006 ;; branch on count
9007
9008 (define_expand "doloop_end"
9009 [(use (match_operand 0 "" "")) ; loop pseudo
9010 (use (match_operand 1 "" ""))] ; label
9011 ""
9012 {
9013 if (GET_MODE (operands[0]) == SImode && !TARGET_CPU_ZARCH)
9014 emit_jump_insn (gen_doloop_si31 (operands[1], operands[0], operands[0]));
9015 else if (GET_MODE (operands[0]) == SImode && TARGET_CPU_ZARCH)
9016 emit_jump_insn (gen_doloop_si64 (operands[1], operands[0], operands[0]));
9017 else if (GET_MODE (operands[0]) == DImode && TARGET_ZARCH)
9018 emit_jump_insn (gen_doloop_di (operands[1], operands[0], operands[0]));
9019 else
9020 FAIL;
9021
9022 DONE;
9023 })
9024
9025 (define_insn_and_split "doloop_si64"
9026 [(set (pc)
9027 (if_then_else
9028 (ne (match_operand:SI 1 "register_operand" "d,d,d")
9029 (const_int 1))
9030 (label_ref (match_operand 0 "" ""))
9031 (pc)))
9032 (set (match_operand:SI 2 "nonimmediate_operand" "=1,?X,?X")
9033 (plus:SI (match_dup 1) (const_int -1)))
9034 (clobber (match_scratch:SI 3 "=X,&1,&?d"))
9035 (clobber (reg:CC CC_REGNUM))]
9036 "TARGET_CPU_ZARCH"
9037 {
9038 if (which_alternative != 0)
9039 return "#";
9040 else if (get_attr_length (insn) == 4)
9041 return "brct\t%1,%l0";
9042 else
9043 return "ahi\t%1,-1\;jgne\t%l0";
9044 }
9045 "&& reload_completed
9046 && (! REG_P (operands[2])
9047 || ! rtx_equal_p (operands[1], operands[2]))"
9048 [(set (match_dup 3) (match_dup 1))
9049 (parallel [(set (reg:CCAN CC_REGNUM)
9050 (compare:CCAN (plus:SI (match_dup 3) (const_int -1))
9051 (const_int 0)))
9052 (set (match_dup 3) (plus:SI (match_dup 3) (const_int -1)))])
9053 (set (match_dup 2) (match_dup 3))
9054 (set (pc) (if_then_else (ne (reg:CCAN CC_REGNUM) (const_int 0))
9055 (label_ref (match_dup 0))
9056 (pc)))]
9057 ""
9058 [(set_attr "op_type" "RI")
9059 ; Strictly speaking, the z10 properties are valid for brct only, however, it does not
9060 ; hurt us in the (rare) case of ahi.
9061 (set_attr "z10prop" "z10_super_E1")
9062 (set_attr "type" "branch")
9063 (set (attr "length")
9064 (if_then_else (lt (abs (minus (pc) (match_dup 0))) (const_int 60000))
9065 (const_int 4) (const_int 10)))])
9066
9067 (define_insn_and_split "doloop_si31"
9068 [(set (pc)
9069 (if_then_else
9070 (ne (match_operand:SI 1 "register_operand" "d,d,d")
9071 (const_int 1))
9072 (label_ref (match_operand 0 "" ""))
9073 (pc)))
9074 (set (match_operand:SI 2 "nonimmediate_operand" "=1,?X,?X")
9075 (plus:SI (match_dup 1) (const_int -1)))
9076 (clobber (match_scratch:SI 3 "=X,&1,&?d"))
9077 (clobber (reg:CC CC_REGNUM))]
9078 "!TARGET_CPU_ZARCH"
9079 {
9080 if (which_alternative != 0)
9081 return "#";
9082 else if (get_attr_length (insn) == 4)
9083 return "brct\t%1,%l0";
9084 else
9085 gcc_unreachable ();
9086 }
9087 "&& reload_completed
9088 && (! REG_P (operands[2])
9089 || ! rtx_equal_p (operands[1], operands[2]))"
9090 [(set (match_dup 3) (match_dup 1))
9091 (parallel [(set (reg:CCAN CC_REGNUM)
9092 (compare:CCAN (plus:SI (match_dup 3) (const_int -1))
9093 (const_int 0)))
9094 (set (match_dup 3) (plus:SI (match_dup 3) (const_int -1)))])
9095 (set (match_dup 2) (match_dup 3))
9096 (set (pc) (if_then_else (ne (reg:CCAN CC_REGNUM) (const_int 0))
9097 (label_ref (match_dup 0))
9098 (pc)))]
9099 ""
9100 [(set_attr "op_type" "RI")
9101 ; Strictly speaking, the z10 properties are valid for brct only, however, it does not
9102 ; hurt us in the (rare) case of ahi.
9103 (set_attr "z10prop" "z10_super_E1")
9104 (set_attr "type" "branch")
9105 (set (attr "length")
9106 (if_then_else (not (match_test "flag_pic"))
9107 (if_then_else (lt (abs (minus (pc) (match_dup 0))) (const_int 60000))
9108 (const_int 4) (const_int 6))
9109 (if_then_else (lt (abs (minus (pc) (match_dup 0))) (const_int 60000))
9110 (const_int 4) (const_int 8))))])
9111
9112 (define_insn "*doloop_si_long"
9113 [(set (pc)
9114 (if_then_else
9115 (ne (match_operand:SI 1 "register_operand" "d")
9116 (const_int 1))
9117 (match_operand 0 "address_operand" "ZQZR")
9118 (pc)))
9119 (set (match_operand:SI 2 "register_operand" "=1")
9120 (plus:SI (match_dup 1) (const_int -1)))
9121 (clobber (match_scratch:SI 3 "=X"))
9122 (clobber (reg:CC CC_REGNUM))]
9123 "!TARGET_CPU_ZARCH"
9124 {
9125 if (get_attr_op_type (insn) == OP_TYPE_RR)
9126 return "bctr\t%1,%0";
9127 else
9128 return "bct\t%1,%a0";
9129 }
9130 [(set (attr "op_type")
9131 (if_then_else (match_operand 0 "register_operand" "")
9132 (const_string "RR") (const_string "RX")))
9133 (set_attr "type" "branch")
9134 (set_attr "atype" "agen")
9135 (set_attr "z10prop" "z10_c")
9136 (set_attr "z196prop" "z196_cracked")])
9137
9138 (define_insn_and_split "doloop_di"
9139 [(set (pc)
9140 (if_then_else
9141 (ne (match_operand:DI 1 "register_operand" "d,d,d")
9142 (const_int 1))
9143 (label_ref (match_operand 0 "" ""))
9144 (pc)))
9145 (set (match_operand:DI 2 "nonimmediate_operand" "=1,?X,?X")
9146 (plus:DI (match_dup 1) (const_int -1)))
9147 (clobber (match_scratch:DI 3 "=X,&1,&?d"))
9148 (clobber (reg:CC CC_REGNUM))]
9149 "TARGET_ZARCH"
9150 {
9151 if (which_alternative != 0)
9152 return "#";
9153 else if (get_attr_length (insn) == 4)
9154 return "brctg\t%1,%l0";
9155 else
9156 return "aghi\t%1,-1\;jgne\t%l0";
9157 }
9158 "&& reload_completed
9159 && (! REG_P (operands[2])
9160 || ! rtx_equal_p (operands[1], operands[2]))"
9161 [(set (match_dup 3) (match_dup 1))
9162 (parallel [(set (reg:CCAN CC_REGNUM)
9163 (compare:CCAN (plus:DI (match_dup 3) (const_int -1))
9164 (const_int 0)))
9165 (set (match_dup 3) (plus:DI (match_dup 3) (const_int -1)))])
9166 (set (match_dup 2) (match_dup 3))
9167 (set (pc) (if_then_else (ne (reg:CCAN CC_REGNUM) (const_int 0))
9168 (label_ref (match_dup 0))
9169 (pc)))]
9170 ""
9171 [(set_attr "op_type" "RI")
9172 ; Strictly speaking, the z10 properties are valid for brct only, however, it does not
9173 ; hurt us in the (rare) case of ahi.
9174 (set_attr "z10prop" "z10_super_E1")
9175 (set_attr "type" "branch")
9176 (set (attr "length")
9177 (if_then_else (lt (abs (minus (pc) (match_dup 0))) (const_int 60000))
9178 (const_int 4) (const_int 10)))])
9179
9180 ;;
9181 ;;- Unconditional jump instructions.
9182 ;;
9183
9184 ;
9185 ; jump instruction pattern(s).
9186 ;
9187
9188 (define_expand "jump"
9189 [(match_operand 0 "" "")]
9190 ""
9191 "s390_emit_jump (operands[0], NULL_RTX); DONE;")
9192
9193 (define_insn "*jump64"
9194 [(set (pc) (label_ref (match_operand 0 "" "")))]
9195 "TARGET_CPU_ZARCH"
9196 {
9197 if (get_attr_length (insn) == 4)
9198 return "j\t%l0";
9199 else
9200 return "jg\t%l0";
9201 }
9202 [(set_attr "op_type" "RI")
9203 (set_attr "type" "branch")
9204 (set (attr "length")
9205 (if_then_else (lt (abs (minus (pc) (match_dup 0))) (const_int 60000))
9206 (const_int 4) (const_int 6)))])
9207
9208 (define_insn "*jump31"
9209 [(set (pc) (label_ref (match_operand 0 "" "")))]
9210 "!TARGET_CPU_ZARCH"
9211 {
9212 gcc_assert (get_attr_length (insn) == 4);
9213 return "j\t%l0";
9214 }
9215 [(set_attr "op_type" "RI")
9216 (set_attr "type" "branch")
9217 (set (attr "length")
9218 (if_then_else (not (match_test "flag_pic"))
9219 (if_then_else (lt (abs (minus (pc) (match_dup 0))) (const_int 60000))
9220 (const_int 4) (const_int 6))
9221 (if_then_else (lt (abs (minus (pc) (match_dup 0))) (const_int 60000))
9222 (const_int 4) (const_int 8))))])
9223
9224 ;
9225 ; indirect-jump instruction pattern(s).
9226 ;
9227
9228 (define_insn "indirect_jump"
9229 [(set (pc) (match_operand 0 "address_operand" "ZQZR"))]
9230 ""
9231 {
9232 if (get_attr_op_type (insn) == OP_TYPE_RR)
9233 return "br\t%0";
9234 else
9235 return "b\t%a0";
9236 }
9237 [(set (attr "op_type")
9238 (if_then_else (match_operand 0 "register_operand" "")
9239 (const_string "RR") (const_string "RX")))
9240 (set_attr "type" "branch")
9241 (set_attr "atype" "agen")])
9242
9243 ;
9244 ; casesi instruction pattern(s).
9245 ;
9246
9247 (define_insn "casesi_jump"
9248 [(set (pc) (match_operand 0 "address_operand" "ZQZR"))
9249 (use (label_ref (match_operand 1 "" "")))]
9250 ""
9251 {
9252 if (get_attr_op_type (insn) == OP_TYPE_RR)
9253 return "br\t%0";
9254 else
9255 return "b\t%a0";
9256 }
9257 [(set (attr "op_type")
9258 (if_then_else (match_operand 0 "register_operand" "")
9259 (const_string "RR") (const_string "RX")))
9260 (set_attr "type" "branch")
9261 (set_attr "atype" "agen")])
9262
9263 (define_expand "casesi"
9264 [(match_operand:SI 0 "general_operand" "")
9265 (match_operand:SI 1 "general_operand" "")
9266 (match_operand:SI 2 "general_operand" "")
9267 (label_ref (match_operand 3 "" ""))
9268 (label_ref (match_operand 4 "" ""))]
9269 ""
9270 {
9271 rtx index = gen_reg_rtx (SImode);
9272 rtx base = gen_reg_rtx (Pmode);
9273 rtx target = gen_reg_rtx (Pmode);
9274
9275 emit_move_insn (index, operands[0]);
9276 emit_insn (gen_subsi3 (index, index, operands[1]));
9277 emit_cmp_and_jump_insns (index, operands[2], GTU, NULL_RTX, SImode, 1,
9278 operands[4]);
9279
9280 if (Pmode != SImode)
9281 index = convert_to_mode (Pmode, index, 1);
9282 if (GET_CODE (index) != REG)
9283 index = copy_to_mode_reg (Pmode, index);
9284
9285 if (TARGET_64BIT)
9286 emit_insn (gen_ashldi3 (index, index, GEN_INT (3)));
9287 else
9288 emit_insn (gen_ashlsi3 (index, index, const2_rtx));
9289
9290 emit_move_insn (base, gen_rtx_LABEL_REF (Pmode, operands[3]));
9291
9292 index = gen_const_mem (Pmode, gen_rtx_PLUS (Pmode, base, index));
9293 emit_move_insn (target, index);
9294
9295 if (flag_pic)
9296 target = gen_rtx_PLUS (Pmode, base, target);
9297 emit_jump_insn (gen_casesi_jump (target, operands[3]));
9298
9299 DONE;
9300 })
9301
9302
9303 ;;
9304 ;;- Jump to subroutine.
9305 ;;
9306 ;;
9307
9308 ;
9309 ; untyped call instruction pattern(s).
9310 ;
9311
9312 ;; Call subroutine returning any type.
9313 (define_expand "untyped_call"
9314 [(parallel [(call (match_operand 0 "" "")
9315 (const_int 0))
9316 (match_operand 1 "" "")
9317 (match_operand 2 "" "")])]
9318 ""
9319 {
9320 int i;
9321
9322 emit_call_insn (gen_call (operands[0], const0_rtx, const0_rtx));
9323
9324 for (i = 0; i < XVECLEN (operands[2], 0); i++)
9325 {
9326 rtx set = XVECEXP (operands[2], 0, i);
9327 emit_move_insn (SET_DEST (set), SET_SRC (set));
9328 }
9329
9330 /* The optimizer does not know that the call sets the function value
9331 registers we stored in the result block. We avoid problems by
9332 claiming that all hard registers are used and clobbered at this
9333 point. */
9334 emit_insn (gen_blockage ());
9335
9336 DONE;
9337 })
9338
9339 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
9340 ;; all of memory. This blocks insns from being moved across this point.
9341
9342 (define_insn "blockage"
9343 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
9344 ""
9345 ""
9346 [(set_attr "type" "none")
9347 (set_attr "length" "0")])
9348
9349 ;
9350 ; sibcall patterns
9351 ;
9352
9353 (define_expand "sibcall"
9354 [(call (match_operand 0 "" "")
9355 (match_operand 1 "" ""))]
9356 ""
9357 {
9358 s390_emit_call (XEXP (operands[0], 0), NULL_RTX, NULL_RTX, NULL_RTX);
9359 DONE;
9360 })
9361
9362 (define_insn "*sibcall_br"
9363 [(call (mem:QI (reg SIBCALL_REGNUM))
9364 (match_operand 0 "const_int_operand" "n"))]
9365 "SIBLING_CALL_P (insn)
9366 && GET_MODE (XEXP (XEXP (PATTERN (insn), 0), 0)) == Pmode"
9367 "br\t%%r1"
9368 [(set_attr "op_type" "RR")
9369 (set_attr "type" "branch")
9370 (set_attr "atype" "agen")])
9371
9372 (define_insn "*sibcall_brc"
9373 [(call (mem:QI (match_operand 0 "bras_sym_operand" "X"))
9374 (match_operand 1 "const_int_operand" "n"))]
9375 "SIBLING_CALL_P (insn) && TARGET_SMALL_EXEC"
9376 "j\t%0"
9377 [(set_attr "op_type" "RI")
9378 (set_attr "type" "branch")])
9379
9380 (define_insn "*sibcall_brcl"
9381 [(call (mem:QI (match_operand 0 "bras_sym_operand" "X"))
9382 (match_operand 1 "const_int_operand" "n"))]
9383 "SIBLING_CALL_P (insn) && TARGET_CPU_ZARCH"
9384 "jg\t%0"
9385 [(set_attr "op_type" "RIL")
9386 (set_attr "type" "branch")])
9387
9388 ;
9389 ; sibcall_value patterns
9390 ;
9391
9392 (define_expand "sibcall_value"
9393 [(set (match_operand 0 "" "")
9394 (call (match_operand 1 "" "")
9395 (match_operand 2 "" "")))]
9396 ""
9397 {
9398 s390_emit_call (XEXP (operands[1], 0), NULL_RTX, operands[0], NULL_RTX);
9399 DONE;
9400 })
9401
9402 (define_insn "*sibcall_value_br"
9403 [(set (match_operand 0 "" "")
9404 (call (mem:QI (reg SIBCALL_REGNUM))
9405 (match_operand 1 "const_int_operand" "n")))]
9406 "SIBLING_CALL_P (insn)
9407 && GET_MODE (XEXP (XEXP (XEXP (PATTERN (insn), 1), 0), 0)) == Pmode"
9408 "br\t%%r1"
9409 [(set_attr "op_type" "RR")
9410 (set_attr "type" "branch")
9411 (set_attr "atype" "agen")])
9412
9413 (define_insn "*sibcall_value_brc"
9414 [(set (match_operand 0 "" "")
9415 (call (mem:QI (match_operand 1 "bras_sym_operand" "X"))
9416 (match_operand 2 "const_int_operand" "n")))]
9417 "SIBLING_CALL_P (insn) && TARGET_SMALL_EXEC"
9418 "j\t%1"
9419 [(set_attr "op_type" "RI")
9420 (set_attr "type" "branch")])
9421
9422 (define_insn "*sibcall_value_brcl"
9423 [(set (match_operand 0 "" "")
9424 (call (mem:QI (match_operand 1 "bras_sym_operand" "X"))
9425 (match_operand 2 "const_int_operand" "n")))]
9426 "SIBLING_CALL_P (insn) && TARGET_CPU_ZARCH"
9427 "jg\t%1"
9428 [(set_attr "op_type" "RIL")
9429 (set_attr "type" "branch")])
9430
9431
9432 ;
9433 ; call instruction pattern(s).
9434 ;
9435
9436 (define_expand "call"
9437 [(call (match_operand 0 "" "")
9438 (match_operand 1 "" ""))
9439 (use (match_operand 2 "" ""))]
9440 ""
9441 {
9442 s390_emit_call (XEXP (operands[0], 0), NULL_RTX, NULL_RTX,
9443 gen_rtx_REG (Pmode, RETURN_REGNUM));
9444 DONE;
9445 })
9446
9447 (define_insn "*bras"
9448 [(call (mem:QI (match_operand 0 "bras_sym_operand" "X"))
9449 (match_operand 1 "const_int_operand" "n"))
9450 (clobber (match_operand 2 "register_operand" "=r"))]
9451 "!SIBLING_CALL_P (insn)
9452 && TARGET_SMALL_EXEC
9453 && GET_MODE (operands[2]) == Pmode"
9454 "bras\t%2,%0"
9455 [(set_attr "op_type" "RI")
9456 (set_attr "type" "jsr")
9457 (set_attr "z196prop" "z196_cracked")])
9458
9459 (define_insn "*brasl"
9460 [(call (mem:QI (match_operand 0 "bras_sym_operand" "X"))
9461 (match_operand 1 "const_int_operand" "n"))
9462 (clobber (match_operand 2 "register_operand" "=r"))]
9463 "!SIBLING_CALL_P (insn)
9464 && TARGET_CPU_ZARCH
9465 && GET_MODE (operands[2]) == Pmode"
9466 "brasl\t%2,%0"
9467 [(set_attr "op_type" "RIL")
9468 (set_attr "type" "jsr")
9469 (set_attr "z196prop" "z196_cracked")])
9470
9471 (define_insn "*basr"
9472 [(call (mem:QI (match_operand 0 "address_operand" "ZQZR"))
9473 (match_operand 1 "const_int_operand" "n"))
9474 (clobber (match_operand 2 "register_operand" "=r"))]
9475 "!SIBLING_CALL_P (insn) && GET_MODE (operands[2]) == Pmode"
9476 {
9477 if (get_attr_op_type (insn) == OP_TYPE_RR)
9478 return "basr\t%2,%0";
9479 else
9480 return "bas\t%2,%a0";
9481 }
9482 [(set (attr "op_type")
9483 (if_then_else (match_operand 0 "register_operand" "")
9484 (const_string "RR") (const_string "RX")))
9485 (set_attr "type" "jsr")
9486 (set_attr "atype" "agen")
9487 (set_attr "z196prop" "z196_cracked")])
9488
9489 ;
9490 ; call_value instruction pattern(s).
9491 ;
9492
9493 (define_expand "call_value"
9494 [(set (match_operand 0 "" "")
9495 (call (match_operand 1 "" "")
9496 (match_operand 2 "" "")))
9497 (use (match_operand 3 "" ""))]
9498 ""
9499 {
9500 s390_emit_call (XEXP (operands[1], 0), NULL_RTX, operands[0],
9501 gen_rtx_REG (Pmode, RETURN_REGNUM));
9502 DONE;
9503 })
9504
9505 (define_insn "*bras_r"
9506 [(set (match_operand 0 "" "")
9507 (call (mem:QI (match_operand 1 "bras_sym_operand" "X"))
9508 (match_operand:SI 2 "const_int_operand" "n")))
9509 (clobber (match_operand 3 "register_operand" "=r"))]
9510 "!SIBLING_CALL_P (insn)
9511 && TARGET_SMALL_EXEC
9512 && GET_MODE (operands[3]) == Pmode"
9513 "bras\t%3,%1"
9514 [(set_attr "op_type" "RI")
9515 (set_attr "type" "jsr")
9516 (set_attr "z196prop" "z196_cracked")])
9517
9518 (define_insn "*brasl_r"
9519 [(set (match_operand 0 "" "")
9520 (call (mem:QI (match_operand 1 "bras_sym_operand" "X"))
9521 (match_operand 2 "const_int_operand" "n")))
9522 (clobber (match_operand 3 "register_operand" "=r"))]
9523 "!SIBLING_CALL_P (insn)
9524 && TARGET_CPU_ZARCH
9525 && GET_MODE (operands[3]) == Pmode"
9526 "brasl\t%3,%1"
9527 [(set_attr "op_type" "RIL")
9528 (set_attr "type" "jsr")
9529 (set_attr "z196prop" "z196_cracked")])
9530
9531 (define_insn "*basr_r"
9532 [(set (match_operand 0 "" "")
9533 (call (mem:QI (match_operand 1 "address_operand" "ZQZR"))
9534 (match_operand 2 "const_int_operand" "n")))
9535 (clobber (match_operand 3 "register_operand" "=r"))]
9536 "!SIBLING_CALL_P (insn) && GET_MODE (operands[3]) == Pmode"
9537 {
9538 if (get_attr_op_type (insn) == OP_TYPE_RR)
9539 return "basr\t%3,%1";
9540 else
9541 return "bas\t%3,%a1";
9542 }
9543 [(set (attr "op_type")
9544 (if_then_else (match_operand 1 "register_operand" "")
9545 (const_string "RR") (const_string "RX")))
9546 (set_attr "type" "jsr")
9547 (set_attr "atype" "agen")
9548 (set_attr "z196prop" "z196_cracked")])
9549
9550 ;;
9551 ;;- Thread-local storage support.
9552 ;;
9553
9554 (define_expand "get_thread_pointer<mode>"
9555 [(set (match_operand:P 0 "nonimmediate_operand" "") (reg:P TP_REGNUM))]
9556 ""
9557 "")
9558
9559 (define_expand "set_thread_pointer<mode>"
9560 [(set (reg:P TP_REGNUM) (match_operand:P 0 "nonimmediate_operand" ""))
9561 (set (reg:P TP_REGNUM) (unspec_volatile:P [(reg:P TP_REGNUM)] UNSPECV_SET_TP))]
9562 ""
9563 "")
9564
9565 (define_insn "*set_tp"
9566 [(set (reg TP_REGNUM) (unspec_volatile [(reg TP_REGNUM)] UNSPECV_SET_TP))]
9567 ""
9568 ""
9569 [(set_attr "type" "none")
9570 (set_attr "length" "0")])
9571
9572 (define_insn "*tls_load_64"
9573 [(set (match_operand:DI 0 "register_operand" "=d")
9574 (unspec:DI [(match_operand:DI 1 "memory_operand" "RT")
9575 (match_operand:DI 2 "" "")]
9576 UNSPEC_TLS_LOAD))]
9577 "TARGET_64BIT"
9578 "lg\t%0,%1%J2"
9579 [(set_attr "op_type" "RXE")
9580 (set_attr "z10prop" "z10_fwd_A3")])
9581
9582 (define_insn "*tls_load_31"
9583 [(set (match_operand:SI 0 "register_operand" "=d,d")
9584 (unspec:SI [(match_operand:SI 1 "memory_operand" "R,T")
9585 (match_operand:SI 2 "" "")]
9586 UNSPEC_TLS_LOAD))]
9587 "!TARGET_64BIT"
9588 "@
9589 l\t%0,%1%J2
9590 ly\t%0,%1%J2"
9591 [(set_attr "op_type" "RX,RXY")
9592 (set_attr "type" "load")
9593 (set_attr "z10prop" "z10_fwd_A3,z10_fwd_A3")])
9594
9595 (define_insn "*bras_tls"
9596 [(set (match_operand 0 "" "")
9597 (call (mem:QI (match_operand 1 "bras_sym_operand" "X"))
9598 (match_operand 2 "const_int_operand" "n")))
9599 (clobber (match_operand 3 "register_operand" "=r"))
9600 (use (match_operand 4 "" ""))]
9601 "!SIBLING_CALL_P (insn)
9602 && TARGET_SMALL_EXEC
9603 && GET_MODE (operands[3]) == Pmode"
9604 "bras\t%3,%1%J4"
9605 [(set_attr "op_type" "RI")
9606 (set_attr "type" "jsr")
9607 (set_attr "z196prop" "z196_cracked")])
9608
9609 (define_insn "*brasl_tls"
9610 [(set (match_operand 0 "" "")
9611 (call (mem:QI (match_operand 1 "bras_sym_operand" "X"))
9612 (match_operand 2 "const_int_operand" "n")))
9613 (clobber (match_operand 3 "register_operand" "=r"))
9614 (use (match_operand 4 "" ""))]
9615 "!SIBLING_CALL_P (insn)
9616 && TARGET_CPU_ZARCH
9617 && GET_MODE (operands[3]) == Pmode"
9618 "brasl\t%3,%1%J4"
9619 [(set_attr "op_type" "RIL")
9620 (set_attr "type" "jsr")
9621 (set_attr "z196prop" "z196_cracked")])
9622
9623 (define_insn "*basr_tls"
9624 [(set (match_operand 0 "" "")
9625 (call (mem:QI (match_operand 1 "address_operand" "ZQZR"))
9626 (match_operand 2 "const_int_operand" "n")))
9627 (clobber (match_operand 3 "register_operand" "=r"))
9628 (use (match_operand 4 "" ""))]
9629 "!SIBLING_CALL_P (insn) && GET_MODE (operands[3]) == Pmode"
9630 {
9631 if (get_attr_op_type (insn) == OP_TYPE_RR)
9632 return "basr\t%3,%1%J4";
9633 else
9634 return "bas\t%3,%a1%J4";
9635 }
9636 [(set (attr "op_type")
9637 (if_then_else (match_operand 1 "register_operand" "")
9638 (const_string "RR") (const_string "RX")))
9639 (set_attr "type" "jsr")
9640 (set_attr "atype" "agen")
9641 (set_attr "z196prop" "z196_cracked")])
9642
9643 ;;
9644 ;;- Atomic operations
9645 ;;
9646
9647 ;
9648 ; memory barrier patterns.
9649 ;
9650
9651 (define_expand "mem_signal_fence"
9652 [(match_operand:SI 0 "const_int_operand")] ;; model
9653 ""
9654 {
9655 /* The s390 memory model is strong enough not to require any
9656 barrier in order to synchronize a thread with itself. */
9657 DONE;
9658 })
9659
9660 (define_expand "mem_thread_fence"
9661 [(match_operand:SI 0 "const_int_operand")] ;; model
9662 ""
9663 {
9664 /* Unless this is a SEQ_CST fence, the s390 memory model is strong
9665 enough not to require barriers of any kind. */
9666 if (is_mm_seq_cst (memmodel_from_int (INTVAL (operands[0]))))
9667 {
9668 rtx mem = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
9669 MEM_VOLATILE_P (mem) = 1;
9670 emit_insn (gen_mem_thread_fence_1 (mem));
9671 }
9672 DONE;
9673 })
9674
9675 ; Although bcr is superscalar on Z10, this variant will never
9676 ; become part of an execution group.
9677 ; With z196 we can make use of the fast-BCR-serialization facility.
9678 ; This allows for a slightly faster sync which is sufficient for our
9679 ; purposes.
9680 (define_insn "mem_thread_fence_1"
9681 [(set (match_operand:BLK 0 "" "")
9682 (unspec:BLK [(match_dup 0)] UNSPEC_MB))]
9683 ""
9684 {
9685 if (TARGET_Z196)
9686 return "bcr\t14,0";
9687 else
9688 return "bcr\t15,0";
9689 }
9690 [(set_attr "op_type" "RR")
9691 (set_attr "mnemonic" "bcr_flush")
9692 (set_attr "z196prop" "z196_alone")])
9693
9694 ;
9695 ; atomic load/store operations
9696 ;
9697
9698 ; Atomic loads need not examine the memory model at all.
9699 (define_expand "atomic_load<mode>"
9700 [(match_operand:DINT 0 "register_operand") ;; output
9701 (match_operand:DINT 1 "memory_operand") ;; memory
9702 (match_operand:SI 2 "const_int_operand")] ;; model
9703 ""
9704 {
9705 if (MEM_ALIGN (operands[1]) < GET_MODE_BITSIZE (GET_MODE (operands[1])))
9706 FAIL;
9707
9708 if (<MODE>mode == TImode)
9709 emit_insn (gen_atomic_loadti_1 (operands[0], operands[1]));
9710 else if (<MODE>mode == DImode && !TARGET_ZARCH)
9711 emit_insn (gen_atomic_loaddi_1 (operands[0], operands[1]));
9712 else
9713 emit_move_insn (operands[0], operands[1]);
9714 DONE;
9715 })
9716
9717 ; Different from movdi_31 in that we want no splitters.
9718 (define_insn "atomic_loaddi_1"
9719 [(set (match_operand:DI 0 "register_operand" "=d,d,!*f,!*f")
9720 (unspec:DI [(match_operand:DI 1 "memory_operand" "Q,S,R,T")]
9721 UNSPEC_MOVA))]
9722 "!TARGET_ZARCH"
9723 "@
9724 lm\t%0,%M0,%S1
9725 lmy\t%0,%M0,%S1
9726 ld\t%0,%1
9727 ldy\t%0,%1"
9728 [(set_attr "op_type" "RS,RSY,RS,RSY")
9729 (set_attr "type" "lm,lm,floaddf,floaddf")])
9730
9731 (define_insn "atomic_loadti_1"
9732 [(set (match_operand:TI 0 "register_operand" "=r")
9733 (unspec:TI [(match_operand:TI 1 "memory_operand" "RT")]
9734 UNSPEC_MOVA))]
9735 "TARGET_ZARCH"
9736 "lpq\t%0,%1"
9737 [(set_attr "op_type" "RXY")
9738 (set_attr "type" "other")])
9739
9740 ; Atomic stores must(?) enforce sequential consistency.
9741 (define_expand "atomic_store<mode>"
9742 [(match_operand:DINT 0 "memory_operand") ;; memory
9743 (match_operand:DINT 1 "register_operand") ;; input
9744 (match_operand:SI 2 "const_int_operand")] ;; model
9745 ""
9746 {
9747 enum memmodel model = memmodel_from_int (INTVAL (operands[2]));
9748
9749 if (MEM_ALIGN (operands[0]) < GET_MODE_BITSIZE (GET_MODE (operands[0])))
9750 FAIL;
9751
9752 if (<MODE>mode == TImode)
9753 emit_insn (gen_atomic_storeti_1 (operands[0], operands[1]));
9754 else if (<MODE>mode == DImode && !TARGET_ZARCH)
9755 emit_insn (gen_atomic_storedi_1 (operands[0], operands[1]));
9756 else
9757 emit_move_insn (operands[0], operands[1]);
9758 if (is_mm_seq_cst (model))
9759 emit_insn (gen_mem_thread_fence (operands[2]));
9760 DONE;
9761 })
9762
9763 ; Different from movdi_31 in that we want no splitters.
9764 (define_insn "atomic_storedi_1"
9765 [(set (match_operand:DI 0 "memory_operand" "=Q,S,R,T")
9766 (unspec:DI [(match_operand:DI 1 "register_operand" "d,d,!*f,!*f")]
9767 UNSPEC_MOVA))]
9768 "!TARGET_ZARCH"
9769 "@
9770 stm\t%1,%N1,%S0
9771 stmy\t%1,%N1,%S0
9772 std %1,%0
9773 stdy %1,%0"
9774 [(set_attr "op_type" "RS,RSY,RS,RSY")
9775 (set_attr "type" "stm,stm,fstoredf,fstoredf")])
9776
9777 (define_insn "atomic_storeti_1"
9778 [(set (match_operand:TI 0 "memory_operand" "=RT")
9779 (unspec:TI [(match_operand:TI 1 "register_operand" "r")]
9780 UNSPEC_MOVA))]
9781 "TARGET_ZARCH"
9782 "stpq\t%1,%0"
9783 [(set_attr "op_type" "RXY")
9784 (set_attr "type" "other")])
9785
9786 ;
9787 ; compare and swap patterns.
9788 ;
9789
9790 (define_expand "atomic_compare_and_swap<mode>"
9791 [(match_operand:SI 0 "register_operand") ;; bool success output
9792 (match_operand:DGPR 1 "nonimmediate_operand");; oldval output
9793 (match_operand:DGPR 2 "memory_operand") ;; memory
9794 (match_operand:DGPR 3 "register_operand") ;; expected intput
9795 (match_operand:DGPR 4 "register_operand") ;; newval intput
9796 (match_operand:SI 5 "const_int_operand") ;; is_weak
9797 (match_operand:SI 6 "const_int_operand") ;; success model
9798 (match_operand:SI 7 "const_int_operand")] ;; failure model
9799 ""
9800 {
9801 rtx cc, cmp, output = operands[1];
9802
9803 if (!register_operand (output, <MODE>mode))
9804 output = gen_reg_rtx (<MODE>mode);
9805
9806 if (MEM_ALIGN (operands[2]) < GET_MODE_BITSIZE (GET_MODE (operands[2])))
9807 FAIL;
9808
9809 emit_insn (gen_atomic_compare_and_swap<mode>_internal
9810 (output, operands[2], operands[3], operands[4]));
9811
9812 /* We deliberately accept non-register operands in the predicate
9813 to ensure the write back to the output operand happens *before*
9814 the store-flags code below. This makes it easier for combine
9815 to merge the store-flags code with a potential test-and-branch
9816 pattern following (immediately!) afterwards. */
9817 if (output != operands[1])
9818 emit_move_insn (operands[1], output);
9819
9820 cc = gen_rtx_REG (CCZ1mode, CC_REGNUM);
9821 cmp = gen_rtx_EQ (SImode, cc, const0_rtx);
9822 emit_insn (gen_cstorecc4 (operands[0], cmp, cc, const0_rtx));
9823 DONE;
9824 })
9825
9826 (define_expand "atomic_compare_and_swap<mode>"
9827 [(match_operand:SI 0 "register_operand") ;; bool success output
9828 (match_operand:HQI 1 "nonimmediate_operand") ;; oldval output
9829 (match_operand:HQI 2 "memory_operand") ;; memory
9830 (match_operand:HQI 3 "general_operand") ;; expected intput
9831 (match_operand:HQI 4 "general_operand") ;; newval intput
9832 (match_operand:SI 5 "const_int_operand") ;; is_weak
9833 (match_operand:SI 6 "const_int_operand") ;; success model
9834 (match_operand:SI 7 "const_int_operand")] ;; failure model
9835 ""
9836 {
9837 s390_expand_cs_hqi (<MODE>mode, operands[0], operands[1], operands[2],
9838 operands[3], operands[4], INTVAL (operands[5]));
9839 DONE;
9840 })
9841
9842 (define_expand "atomic_compare_and_swap<mode>_internal"
9843 [(parallel
9844 [(set (match_operand:DGPR 0 "register_operand")
9845 (match_operand:DGPR 1 "memory_operand"))
9846 (set (match_dup 1)
9847 (unspec_volatile:DGPR
9848 [(match_dup 1)
9849 (match_operand:DGPR 2 "register_operand")
9850 (match_operand:DGPR 3 "register_operand")]
9851 UNSPECV_CAS))
9852 (set (reg:CCZ1 CC_REGNUM)
9853 (compare:CCZ1 (match_dup 1) (match_dup 2)))])]
9854 "")
9855
9856 ; cdsg, csg
9857 (define_insn "*atomic_compare_and_swap<mode>_1"
9858 [(set (match_operand:TDI 0 "register_operand" "=r")
9859 (match_operand:TDI 1 "memory_operand" "+QS"))
9860 (set (match_dup 1)
9861 (unspec_volatile:TDI
9862 [(match_dup 1)
9863 (match_operand:TDI 2 "register_operand" "0")
9864 (match_operand:TDI 3 "register_operand" "r")]
9865 UNSPECV_CAS))
9866 (set (reg:CCZ1 CC_REGNUM)
9867 (compare:CCZ1 (match_dup 1) (match_dup 2)))]
9868 "TARGET_ZARCH"
9869 "c<td>sg\t%0,%3,%S1"
9870 [(set_attr "op_type" "RSY")
9871 (set_attr "type" "sem")])
9872
9873 ; cds, cdsy
9874 (define_insn "*atomic_compare_and_swapdi_2"
9875 [(set (match_operand:DI 0 "register_operand" "=r,r")
9876 (match_operand:DI 1 "memory_operand" "+Q,S"))
9877 (set (match_dup 1)
9878 (unspec_volatile:DI
9879 [(match_dup 1)
9880 (match_operand:DI 2 "register_operand" "0,0")
9881 (match_operand:DI 3 "register_operand" "r,r")]
9882 UNSPECV_CAS))
9883 (set (reg:CCZ1 CC_REGNUM)
9884 (compare:CCZ1 (match_dup 1) (match_dup 2)))]
9885 "!TARGET_ZARCH"
9886 "@
9887 cds\t%0,%3,%S1
9888 cdsy\t%0,%3,%S1"
9889 [(set_attr "op_type" "RS,RSY")
9890 (set_attr "type" "sem")])
9891
9892 ; cs, csy
9893 (define_insn "*atomic_compare_and_swapsi_3"
9894 [(set (match_operand:SI 0 "register_operand" "=r,r")
9895 (match_operand:SI 1 "memory_operand" "+Q,S"))
9896 (set (match_dup 1)
9897 (unspec_volatile:SI
9898 [(match_dup 1)
9899 (match_operand:SI 2 "register_operand" "0,0")
9900 (match_operand:SI 3 "register_operand" "r,r")]
9901 UNSPECV_CAS))
9902 (set (reg:CCZ1 CC_REGNUM)
9903 (compare:CCZ1 (match_dup 1) (match_dup 2)))]
9904 ""
9905 "@
9906 cs\t%0,%3,%S1
9907 csy\t%0,%3,%S1"
9908 [(set_attr "op_type" "RS,RSY")
9909 (set_attr "type" "sem")])
9910
9911 ;
9912 ; Other atomic instruction patterns.
9913 ;
9914
9915 ; z196 load and add, xor, or and and instructions
9916
9917 (define_expand "atomic_fetch_<atomic><mode>"
9918 [(match_operand:GPR 0 "register_operand") ;; val out
9919 (ATOMIC_Z196:GPR
9920 (match_operand:GPR 1 "memory_operand") ;; memory
9921 (match_operand:GPR 2 "register_operand")) ;; val in
9922 (match_operand:SI 3 "const_int_operand")] ;; model
9923 "TARGET_Z196"
9924 {
9925 if (MEM_ALIGN (operands[1]) < GET_MODE_BITSIZE (GET_MODE (operands[1])))
9926 FAIL;
9927
9928 emit_insn (gen_atomic_fetch_<atomic><mode>_iaf
9929 (operands[0], operands[1], operands[2]));
9930 DONE;
9931 })
9932
9933 ; lan, lang, lao, laog, lax, laxg, laa, laag
9934 (define_insn "atomic_fetch_<atomic><mode>_iaf"
9935 [(set (match_operand:GPR 0 "register_operand" "=d")
9936 (match_operand:GPR 1 "memory_operand" "+QS"))
9937 (set (match_dup 1)
9938 (unspec_volatile:GPR
9939 [(ATOMIC_Z196:GPR (match_dup 1)
9940 (match_operand:GPR 2 "general_operand" "d"))]
9941 UNSPECV_ATOMIC_OP))
9942 (clobber (reg:CC CC_REGNUM))]
9943 "TARGET_Z196"
9944 "la<noxa><g>\t%0,%2,%1"
9945 [(set_attr "op_type" "RSY")
9946 (set_attr "type" "sem")])
9947
9948 ;; For SImode and larger, the optabs.c code will do just fine in
9949 ;; expanding a compare-and-swap loop. For QI/HImode, we can do
9950 ;; better by expanding our own loop.
9951
9952 (define_expand "atomic_<atomic><mode>"
9953 [(ATOMIC:HQI
9954 (match_operand:HQI 0 "memory_operand") ;; memory
9955 (match_operand:HQI 1 "general_operand")) ;; val in
9956 (match_operand:SI 2 "const_int_operand")] ;; model
9957 ""
9958 {
9959 s390_expand_atomic (<MODE>mode, <CODE>, NULL_RTX, operands[0],
9960 operands[1], false);
9961 DONE;
9962 })
9963
9964 (define_expand "atomic_fetch_<atomic><mode>"
9965 [(match_operand:HQI 0 "register_operand") ;; val out
9966 (ATOMIC:HQI
9967 (match_operand:HQI 1 "memory_operand") ;; memory
9968 (match_operand:HQI 2 "general_operand")) ;; val in
9969 (match_operand:SI 3 "const_int_operand")] ;; model
9970 ""
9971 {
9972 s390_expand_atomic (<MODE>mode, <CODE>, operands[0], operands[1],
9973 operands[2], false);
9974 DONE;
9975 })
9976
9977 (define_expand "atomic_<atomic>_fetch<mode>"
9978 [(match_operand:HQI 0 "register_operand") ;; val out
9979 (ATOMIC:HQI
9980 (match_operand:HQI 1 "memory_operand") ;; memory
9981 (match_operand:HQI 2 "general_operand")) ;; val in
9982 (match_operand:SI 3 "const_int_operand")] ;; model
9983 ""
9984 {
9985 s390_expand_atomic (<MODE>mode, <CODE>, operands[0], operands[1],
9986 operands[2], true);
9987 DONE;
9988 })
9989
9990 (define_expand "atomic_exchange<mode>"
9991 [(match_operand:HQI 0 "register_operand") ;; val out
9992 (match_operand:HQI 1 "memory_operand") ;; memory
9993 (match_operand:HQI 2 "general_operand") ;; val in
9994 (match_operand:SI 3 "const_int_operand")] ;; model
9995 ""
9996 {
9997 s390_expand_atomic (<MODE>mode, SET, operands[0], operands[1],
9998 operands[2], false);
9999 DONE;
10000 })
10001
10002 ;;
10003 ;;- Miscellaneous instructions.
10004 ;;
10005
10006 ;
10007 ; allocate stack instruction pattern(s).
10008 ;
10009
10010 (define_expand "allocate_stack"
10011 [(match_operand 0 "general_operand" "")
10012 (match_operand 1 "general_operand" "")]
10013 "TARGET_BACKCHAIN"
10014 {
10015 rtx temp = gen_reg_rtx (Pmode);
10016
10017 emit_move_insn (temp, s390_back_chain_rtx ());
10018 anti_adjust_stack (operands[1]);
10019 emit_move_insn (s390_back_chain_rtx (), temp);
10020
10021 emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
10022 DONE;
10023 })
10024
10025
10026 ;
10027 ; setjmp instruction pattern.
10028 ;
10029
10030 (define_expand "builtin_setjmp_receiver"
10031 [(match_operand 0 "" "")]
10032 "flag_pic"
10033 {
10034 emit_insn (s390_load_got ());
10035 emit_use (pic_offset_table_rtx);
10036 DONE;
10037 })
10038
10039 ;; These patterns say how to save and restore the stack pointer. We need not
10040 ;; save the stack pointer at function level since we are careful to
10041 ;; preserve the backchain. At block level, we have to restore the backchain
10042 ;; when we restore the stack pointer.
10043 ;;
10044 ;; For nonlocal gotos, we must save both the stack pointer and its
10045 ;; backchain and restore both. Note that in the nonlocal case, the
10046 ;; save area is a memory location.
10047
10048 (define_expand "save_stack_function"
10049 [(match_operand 0 "general_operand" "")
10050 (match_operand 1 "general_operand" "")]
10051 ""
10052 "DONE;")
10053
10054 (define_expand "restore_stack_function"
10055 [(match_operand 0 "general_operand" "")
10056 (match_operand 1 "general_operand" "")]
10057 ""
10058 "DONE;")
10059
10060 (define_expand "restore_stack_block"
10061 [(match_operand 0 "register_operand" "")
10062 (match_operand 1 "register_operand" "")]
10063 "TARGET_BACKCHAIN"
10064 {
10065 rtx temp = gen_reg_rtx (Pmode);
10066
10067 emit_move_insn (temp, s390_back_chain_rtx ());
10068 emit_move_insn (operands[0], operands[1]);
10069 emit_move_insn (s390_back_chain_rtx (), temp);
10070
10071 DONE;
10072 })
10073
10074 (define_expand "save_stack_nonlocal"
10075 [(match_operand 0 "memory_operand" "")
10076 (match_operand 1 "register_operand" "")]
10077 ""
10078 {
10079 rtx base = gen_rtx_REG (Pmode, BASE_REGNUM);
10080
10081 /* Copy the backchain to the first word, sp to the second and the
10082 literal pool base to the third. */
10083
10084 rtx save_bc = adjust_address (operands[0], Pmode, 0);
10085 rtx save_sp = adjust_address (operands[0], Pmode, GET_MODE_SIZE (Pmode));
10086 rtx save_bp = adjust_address (operands[0], Pmode, 2 * GET_MODE_SIZE (Pmode));
10087
10088 if (TARGET_BACKCHAIN)
10089 emit_move_insn (save_bc, force_reg (Pmode, s390_back_chain_rtx ()));
10090
10091 emit_move_insn (save_sp, operands[1]);
10092 emit_move_insn (save_bp, base);
10093
10094 DONE;
10095 })
10096
10097 (define_expand "restore_stack_nonlocal"
10098 [(match_operand 0 "register_operand" "")
10099 (match_operand 1 "memory_operand" "")]
10100 ""
10101 {
10102 rtx base = gen_rtx_REG (Pmode, BASE_REGNUM);
10103 rtx temp = NULL_RTX;
10104
10105 /* Restore the backchain from the first word, sp from the second and the
10106 literal pool base from the third. */
10107
10108 rtx save_bc = adjust_address (operands[1], Pmode, 0);
10109 rtx save_sp = adjust_address (operands[1], Pmode, GET_MODE_SIZE (Pmode));
10110 rtx save_bp = adjust_address (operands[1], Pmode, 2 * GET_MODE_SIZE (Pmode));
10111
10112 if (TARGET_BACKCHAIN)
10113 temp = force_reg (Pmode, save_bc);
10114
10115 emit_move_insn (base, save_bp);
10116 emit_move_insn (operands[0], save_sp);
10117
10118 if (temp)
10119 emit_move_insn (s390_back_chain_rtx (), temp);
10120
10121 emit_use (base);
10122 DONE;
10123 })
10124
10125 (define_expand "exception_receiver"
10126 [(const_int 0)]
10127 ""
10128 {
10129 s390_set_has_landing_pad_p (true);
10130 DONE;
10131 })
10132
10133 ;
10134 ; nop instruction pattern(s).
10135 ;
10136
10137 (define_insn "nop"
10138 [(const_int 0)]
10139 ""
10140 "lr\t0,0"
10141 [(set_attr "op_type" "RR")
10142 (set_attr "z10prop" "z10_fr_E1")])
10143
10144 (define_insn "nop1"
10145 [(const_int 1)]
10146 ""
10147 "lr\t1,1"
10148 [(set_attr "op_type" "RR")])
10149
10150 ;;- Undeletable nops (used for hotpatching)
10151
10152 (define_insn "nop_2_byte"
10153 [(unspec_volatile [(const_int 0)] UNSPECV_NOP_2_BYTE)]
10154 ""
10155 "nopr\t%%r7"
10156 [(set_attr "op_type" "RR")])
10157
10158 (define_insn "nop_4_byte"
10159 [(unspec_volatile [(const_int 0)] UNSPECV_NOP_4_BYTE)]
10160 ""
10161 "nop\t0"
10162 [(set_attr "op_type" "RX")])
10163
10164 (define_insn "nop_6_byte"
10165 [(unspec_volatile [(const_int 0)] UNSPECV_NOP_6_BYTE)]
10166 "TARGET_CPU_ZARCH"
10167 "brcl\t0, 0"
10168 [(set_attr "op_type" "RIL")])
10169
10170
10171 ;
10172 ; Special literal pool access instruction pattern(s).
10173 ;
10174
10175 (define_insn "*pool_entry"
10176 [(unspec_volatile [(match_operand 0 "consttable_operand" "X")]
10177 UNSPECV_POOL_ENTRY)]
10178 ""
10179 {
10180 machine_mode mode = GET_MODE (PATTERN (insn));
10181 unsigned int align = GET_MODE_BITSIZE (mode);
10182 s390_output_pool_entry (operands[0], mode, align);
10183 return "";
10184 }
10185 [(set (attr "length")
10186 (symbol_ref "GET_MODE_SIZE (GET_MODE (PATTERN (insn)))"))])
10187
10188 (define_insn "pool_align"
10189 [(unspec_volatile [(match_operand 0 "const_int_operand" "n")]
10190 UNSPECV_POOL_ALIGN)]
10191 ""
10192 ".align\t%0"
10193 [(set (attr "length") (symbol_ref "INTVAL (operands[0])"))])
10194
10195 (define_insn "pool_section_start"
10196 [(unspec_volatile [(const_int 1)] UNSPECV_POOL_SECTION)]
10197 ""
10198 ".section\t.rodata"
10199 [(set_attr "length" "0")])
10200
10201 (define_insn "pool_section_end"
10202 [(unspec_volatile [(const_int 0)] UNSPECV_POOL_SECTION)]
10203 ""
10204 ".previous"
10205 [(set_attr "length" "0")])
10206
10207 (define_insn "main_base_31_small"
10208 [(set (match_operand 0 "register_operand" "=a")
10209 (unspec [(label_ref (match_operand 1 "" ""))] UNSPEC_MAIN_BASE))]
10210 "!TARGET_CPU_ZARCH && GET_MODE (operands[0]) == Pmode"
10211 "basr\t%0,0"
10212 [(set_attr "op_type" "RR")
10213 (set_attr "type" "la")
10214 (set_attr "z196prop" "z196_cracked")])
10215
10216 (define_insn "main_base_31_large"
10217 [(set (match_operand 0 "register_operand" "=a")
10218 (unspec [(label_ref (match_operand 1 "" ""))] UNSPEC_MAIN_BASE))
10219 (set (pc) (label_ref (match_operand 2 "" "")))]
10220 "!TARGET_CPU_ZARCH && GET_MODE (operands[0]) == Pmode"
10221 "bras\t%0,%2"
10222 [(set_attr "op_type" "RI")
10223 (set_attr "z196prop" "z196_cracked")])
10224
10225 (define_insn "main_base_64"
10226 [(set (match_operand 0 "register_operand" "=a")
10227 (unspec [(label_ref (match_operand 1 "" ""))] UNSPEC_MAIN_BASE))]
10228 "TARGET_CPU_ZARCH && GET_MODE (operands[0]) == Pmode"
10229 "larl\t%0,%1"
10230 [(set_attr "op_type" "RIL")
10231 (set_attr "type" "larl")
10232 (set_attr "z10prop" "z10_fwd_A1")])
10233
10234 (define_insn "main_pool"
10235 [(set (match_operand 0 "register_operand" "=a")
10236 (unspec_volatile [(const_int 0)] UNSPECV_MAIN_POOL))]
10237 "GET_MODE (operands[0]) == Pmode"
10238 {
10239 gcc_unreachable ();
10240 }
10241 [(set (attr "type")
10242 (if_then_else (match_test "TARGET_CPU_ZARCH")
10243 (const_string "larl") (const_string "la")))])
10244
10245 (define_insn "reload_base_31"
10246 [(set (match_operand 0 "register_operand" "=a")
10247 (unspec [(label_ref (match_operand 1 "" ""))] UNSPEC_RELOAD_BASE))]
10248 "!TARGET_CPU_ZARCH && GET_MODE (operands[0]) == Pmode"
10249 "basr\t%0,0\;la\t%0,%1-.(%0)"
10250 [(set_attr "length" "6")
10251 (set_attr "type" "la")
10252 (set_attr "z196prop" "z196_cracked")])
10253
10254 (define_insn "reload_base_64"
10255 [(set (match_operand 0 "register_operand" "=a")
10256 (unspec [(label_ref (match_operand 1 "" ""))] UNSPEC_RELOAD_BASE))]
10257 "TARGET_CPU_ZARCH && GET_MODE (operands[0]) == Pmode"
10258 "larl\t%0,%1"
10259 [(set_attr "op_type" "RIL")
10260 (set_attr "type" "larl")
10261 (set_attr "z10prop" "z10_fwd_A1")])
10262
10263 (define_insn "pool"
10264 [(unspec_volatile [(match_operand 0 "const_int_operand" "n")] UNSPECV_POOL)]
10265 ""
10266 {
10267 gcc_unreachable ();
10268 }
10269 [(set (attr "length") (symbol_ref "INTVAL (operands[0])"))])
10270
10271 ;;
10272 ;; Insns related to generating the function prologue and epilogue.
10273 ;;
10274
10275
10276 (define_expand "prologue"
10277 [(use (const_int 0))]
10278 ""
10279 "s390_emit_prologue (); DONE;")
10280
10281 (define_expand "epilogue"
10282 [(use (const_int 1))]
10283 ""
10284 "s390_emit_epilogue (false); DONE;")
10285
10286 (define_expand "sibcall_epilogue"
10287 [(use (const_int 0))]
10288 ""
10289 "s390_emit_epilogue (true); DONE;")
10290
10291 ;; A direct return instruction, without using an epilogue.
10292 (define_insn "<code>"
10293 [(ANY_RETURN)]
10294 "s390_can_use_<code>_insn ()"
10295 "br\t%%r14"
10296 [(set_attr "op_type" "RR")
10297 (set_attr "type" "jsr")
10298 (set_attr "atype" "agen")])
10299
10300 (define_insn "*return"
10301 [(return)
10302 (use (match_operand 0 "register_operand" "a"))]
10303 "GET_MODE (operands[0]) == Pmode"
10304 "br\t%0"
10305 [(set_attr "op_type" "RR")
10306 (set_attr "type" "jsr")
10307 (set_attr "atype" "agen")])
10308
10309
10310 ;; Instruction definition to extend a 31-bit pointer into a 64-bit
10311 ;; pointer. This is used for compatibility.
10312
10313 (define_expand "ptr_extend"
10314 [(set (match_operand:DI 0 "register_operand" "=r")
10315 (match_operand:SI 1 "register_operand" "r"))]
10316 "TARGET_64BIT"
10317 {
10318 emit_insn (gen_anddi3 (operands[0],
10319 gen_lowpart (DImode, operands[1]),
10320 GEN_INT (0x7fffffff)));
10321 DONE;
10322 })
10323
10324 ;; Instruction definition to expand eh_return macro to support
10325 ;; swapping in special linkage return addresses.
10326
10327 (define_expand "eh_return"
10328 [(use (match_operand 0 "register_operand" ""))]
10329 "TARGET_TPF"
10330 {
10331 s390_emit_tpf_eh_return (operands[0]);
10332 DONE;
10333 })
10334
10335 ;
10336 ; Stack Protector Patterns
10337 ;
10338
10339 (define_expand "stack_protect_set"
10340 [(set (match_operand 0 "memory_operand" "")
10341 (match_operand 1 "memory_operand" ""))]
10342 ""
10343 {
10344 #ifdef TARGET_THREAD_SSP_OFFSET
10345 operands[1]
10346 = gen_rtx_MEM (Pmode, gen_rtx_PLUS (Pmode, s390_get_thread_pointer (),
10347 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
10348 #endif
10349 if (TARGET_64BIT)
10350 emit_insn (gen_stack_protect_setdi (operands[0], operands[1]));
10351 else
10352 emit_insn (gen_stack_protect_setsi (operands[0], operands[1]));
10353
10354 DONE;
10355 })
10356
10357 (define_insn "stack_protect_set<mode>"
10358 [(set (match_operand:DSI 0 "memory_operand" "=Q")
10359 (unspec:DSI [(match_operand:DSI 1 "memory_operand" "Q")] UNSPEC_SP_SET))]
10360 ""
10361 "mvc\t%O0(%G0,%R0),%S1"
10362 [(set_attr "op_type" "SS")])
10363
10364 (define_expand "stack_protect_test"
10365 [(set (reg:CC CC_REGNUM)
10366 (compare (match_operand 0 "memory_operand" "")
10367 (match_operand 1 "memory_operand" "")))
10368 (match_operand 2 "" "")]
10369 ""
10370 {
10371 rtx cc_reg, test;
10372 #ifdef TARGET_THREAD_SSP_OFFSET
10373 operands[1]
10374 = gen_rtx_MEM (Pmode, gen_rtx_PLUS (Pmode, s390_get_thread_pointer (),
10375 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
10376 #endif
10377 if (TARGET_64BIT)
10378 emit_insn (gen_stack_protect_testdi (operands[0], operands[1]));
10379 else
10380 emit_insn (gen_stack_protect_testsi (operands[0], operands[1]));
10381
10382 cc_reg = gen_rtx_REG (CCZmode, CC_REGNUM);
10383 test = gen_rtx_EQ (VOIDmode, cc_reg, const0_rtx);
10384 emit_jump_insn (gen_cbranchcc4 (test, cc_reg, const0_rtx, operands[2]));
10385 DONE;
10386 })
10387
10388 (define_insn "stack_protect_test<mode>"
10389 [(set (reg:CCZ CC_REGNUM)
10390 (unspec:CCZ [(match_operand:DSI 0 "memory_operand" "Q")
10391 (match_operand:DSI 1 "memory_operand" "Q")] UNSPEC_SP_TEST))]
10392 ""
10393 "clc\t%O0(%G0,%R0),%S1"
10394 [(set_attr "op_type" "SS")])
10395
10396 ; This is used in s390_emit_prologue in order to prevent insns
10397 ; adjusting the stack pointer to be moved over insns writing stack
10398 ; slots using a copy of the stack pointer in a different register.
10399 (define_insn "stack_tie"
10400 [(set (match_operand:BLK 0 "memory_operand" "+m")
10401 (unspec:BLK [(match_dup 0)] UNSPEC_TIE))]
10402 ""
10403 ""
10404 [(set_attr "length" "0")])
10405
10406
10407 ;
10408 ; Data prefetch patterns
10409 ;
10410
10411 (define_insn "prefetch"
10412 [(prefetch (match_operand 0 "address_operand" "ZQZRZSZT,X")
10413 (match_operand:SI 1 "const_int_operand" " n,n")
10414 (match_operand:SI 2 "const_int_operand" " n,n"))]
10415 "TARGET_Z10"
10416 {
10417 switch (which_alternative)
10418 {
10419 case 0:
10420 return INTVAL (operands[1]) == 1 ? "pfd\t2,%a0" : "pfd\t1,%a0";
10421 case 1:
10422 if (larl_operand (operands[0], Pmode))
10423 return INTVAL (operands[1]) == 1 ? "pfdrl\t2,%a0" : "pfdrl\t1,%a0";
10424 default:
10425
10426 /* This might be reached for symbolic operands with an odd
10427 addend. We simply omit the prefetch for such rare cases. */
10428
10429 return "";
10430 }
10431 }
10432 [(set_attr "type" "load,larl")
10433 (set_attr "op_type" "RXY,RIL")
10434 (set_attr "z10prop" "z10_super")
10435 (set_attr "z196prop" "z196_alone")])
10436
10437
10438 ;
10439 ; Byte swap instructions
10440 ;
10441
10442 (define_insn "bswap<mode>2"
10443 [(set (match_operand:GPR 0 "register_operand" "=d, d")
10444 (bswap:GPR (match_operand:GPR 1 "nonimmediate_operand" " d,RT")))]
10445 "TARGET_CPU_ZARCH"
10446 "@
10447 lrv<g>r\t%0,%1
10448 lrv<g>\t%0,%1"
10449 [(set_attr "type" "*,load")
10450 (set_attr "op_type" "RRE,RXY")
10451 (set_attr "z10prop" "z10_super")])
10452
10453
10454 ;
10455 ; Population count instruction
10456 ;
10457
10458 ; The S/390 popcount instruction counts the bits of op1 in 8 byte
10459 ; portions and stores the result in the corresponding bytes in op0.
10460 (define_insn "*popcount<mode>"
10461 [(set (match_operand:INT 0 "register_operand" "=d")
10462 (unspec:INT [(match_operand:INT 1 "register_operand" "d")] UNSPEC_POPCNT))
10463 (clobber (reg:CC CC_REGNUM))]
10464 "TARGET_Z196"
10465 "popcnt\t%0,%1"
10466 [(set_attr "op_type" "RRE")])
10467
10468 (define_expand "popcountdi2"
10469 [; popcnt op0, op1
10470 (parallel [(set (match_operand:DI 0 "register_operand" "")
10471 (unspec:DI [(match_operand:DI 1 "register_operand")]
10472 UNSPEC_POPCNT))
10473 (clobber (reg:CC CC_REGNUM))])
10474 ; sllg op2, op0, 32
10475 (set (match_dup 2) (ashift:DI (match_dup 0) (const_int 32)))
10476 ; agr op0, op2
10477 (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 2)))
10478 (clobber (reg:CC CC_REGNUM))])
10479 ; sllg op2, op0, 16
10480 (set (match_dup 2)
10481 (ashift:DI (match_dup 0) (const_int 16)))
10482 ; agr op0, op2
10483 (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 2)))
10484 (clobber (reg:CC CC_REGNUM))])
10485 ; sllg op2, op0, 8
10486 (set (match_dup 2) (ashift:DI (match_dup 0) (const_int 8)))
10487 ; agr op0, op2
10488 (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 2)))
10489 (clobber (reg:CC CC_REGNUM))])
10490 ; srlg op0, op0, 56
10491 (set (match_dup 0) (lshiftrt:DI (match_dup 0) (const_int 56)))]
10492 "TARGET_Z196 && TARGET_64BIT"
10493 "operands[2] = gen_reg_rtx (DImode);")
10494
10495 (define_expand "popcountsi2"
10496 [; popcnt op0, op1
10497 (parallel [(set (match_operand:SI 0 "register_operand" "")
10498 (unspec:SI [(match_operand:SI 1 "register_operand")]
10499 UNSPEC_POPCNT))
10500 (clobber (reg:CC CC_REGNUM))])
10501 ; sllk op2, op0, 16
10502 (set (match_dup 2)
10503 (ashift:SI (match_dup 0) (const_int 16)))
10504 ; ar op0, op2
10505 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
10506 (clobber (reg:CC CC_REGNUM))])
10507 ; sllk op2, op0, 8
10508 (set (match_dup 2) (ashift:SI (match_dup 0) (const_int 8)))
10509 ; ar op0, op2
10510 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
10511 (clobber (reg:CC CC_REGNUM))])
10512 ; srl op0, op0, 24
10513 (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 24)))]
10514 "TARGET_Z196"
10515 "operands[2] = gen_reg_rtx (SImode);")
10516
10517 (define_expand "popcounthi2"
10518 [; popcnt op0, op1
10519 (parallel [(set (match_operand:HI 0 "register_operand" "")
10520 (unspec:HI [(match_operand:HI 1 "register_operand")]
10521 UNSPEC_POPCNT))
10522 (clobber (reg:CC CC_REGNUM))])
10523 ; sllk op2, op0, 8
10524 (set (match_dup 2)
10525 (ashift:SI (match_dup 0) (const_int 8)))
10526 ; ar op0, op2
10527 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
10528 (clobber (reg:CC CC_REGNUM))])
10529 ; srl op0, op0, 8
10530 (set (match_dup 0) (lshiftrt:HI (match_dup 0) (const_int 8)))]
10531 "TARGET_Z196"
10532 "operands[2] = gen_reg_rtx (SImode);")
10533
10534 (define_expand "popcountqi2"
10535 [; popcnt op0, op1
10536 (parallel [(set (match_operand:QI 0 "register_operand" "")
10537 (unspec:QI [(match_operand:QI 1 "register_operand")]
10538 UNSPEC_POPCNT))
10539 (clobber (reg:CC CC_REGNUM))])]
10540 "TARGET_Z196"
10541 "")
10542
10543 ;;
10544 ;;- Copy sign instructions
10545 ;;
10546
10547 (define_insn "copysign<mode>3"
10548 [(set (match_operand:FP 0 "register_operand" "=f")
10549 (unspec:FP [(match_operand:FP 1 "register_operand" "<fT0>")
10550 (match_operand:FP 2 "register_operand" "f")]
10551 UNSPEC_COPYSIGN))]
10552 "TARGET_Z196"
10553 "cpsdr\t%0,%2,%1"
10554 [(set_attr "op_type" "RRF")
10555 (set_attr "type" "fsimp<mode>")])
10556
10557
10558 ;;
10559 ;;- Transactional execution instructions
10560 ;;
10561
10562 ; This splitter helps combine to make use of CC directly when
10563 ; comparing the integer result of a tbegin builtin with a constant.
10564 ; The unspec is already removed by canonicalize_comparison. So this
10565 ; splitters only job is to turn the PARALLEL into separate insns
10566 ; again. Unfortunately this only works with the very first cc/int
10567 ; compare since combine is not able to deal with data flow across
10568 ; basic block boundaries.
10569
10570 ; It needs to be an insn pattern as well since combine does not apply
10571 ; the splitter directly. Combine would only use it if it actually
10572 ; would reduce the number of instructions.
10573 (define_insn_and_split "*ccraw_to_int"
10574 [(set (pc)
10575 (if_then_else
10576 (match_operator 0 "s390_eqne_operator"
10577 [(reg:CCRAW CC_REGNUM)
10578 (match_operand 1 "const_int_operand" "")])
10579 (label_ref (match_operand 2 "" ""))
10580 (pc)))
10581 (set (match_operand:SI 3 "register_operand" "=d")
10582 (unspec:SI [(reg:CCRAW CC_REGNUM)] UNSPEC_CC_TO_INT))]
10583 ""
10584 "#"
10585 ""
10586 [(set (match_dup 3)
10587 (unspec:SI [(reg:CCRAW CC_REGNUM)] UNSPEC_CC_TO_INT))
10588 (set (pc)
10589 (if_then_else (match_op_dup 0 [(reg:CCRAW CC_REGNUM) (match_dup 1)])
10590 (label_ref (match_dup 2))
10591 (pc)))]
10592 "")
10593
10594 ; Non-constrained transaction begin
10595
10596 (define_expand "tbegin"
10597 [(match_operand:SI 0 "register_operand" "")
10598 (match_operand:BLK 1 "memory_operand" "")]
10599 "TARGET_HTM"
10600 {
10601 s390_expand_tbegin (operands[0], operands[1], NULL_RTX, true);
10602 DONE;
10603 })
10604
10605 (define_expand "tbegin_nofloat"
10606 [(match_operand:SI 0 "register_operand" "")
10607 (match_operand:BLK 1 "memory_operand" "")]
10608 "TARGET_HTM"
10609 {
10610 s390_expand_tbegin (operands[0], operands[1], NULL_RTX, false);
10611 DONE;
10612 })
10613
10614 (define_expand "tbegin_retry"
10615 [(match_operand:SI 0 "register_operand" "")
10616 (match_operand:BLK 1 "memory_operand" "")
10617 (match_operand:SI 2 "general_operand" "")]
10618 "TARGET_HTM"
10619 {
10620 s390_expand_tbegin (operands[0], operands[1], operands[2], true);
10621 DONE;
10622 })
10623
10624 (define_expand "tbegin_retry_nofloat"
10625 [(match_operand:SI 0 "register_operand" "")
10626 (match_operand:BLK 1 "memory_operand" "")
10627 (match_operand:SI 2 "general_operand" "")]
10628 "TARGET_HTM"
10629 {
10630 s390_expand_tbegin (operands[0], operands[1], operands[2], false);
10631 DONE;
10632 })
10633
10634 ; Clobber VRs since they don't get restored
10635 (define_insn "tbegin_1_z13"
10636 [(set (reg:CCRAW CC_REGNUM)
10637 (unspec_volatile:CCRAW [(match_operand 0 "const_int_operand" "D")]
10638 UNSPECV_TBEGIN))
10639 (set (match_operand:BLK 1 "memory_operand" "=Q")
10640 (unspec_volatile:BLK [(match_dup 0)] UNSPECV_TBEGIN_TDB))
10641 (clobber (reg:TI 16)) (clobber (reg:TI 38))
10642 (clobber (reg:TI 17)) (clobber (reg:TI 39))
10643 (clobber (reg:TI 18)) (clobber (reg:TI 40))
10644 (clobber (reg:TI 19)) (clobber (reg:TI 41))
10645 (clobber (reg:TI 20)) (clobber (reg:TI 42))
10646 (clobber (reg:TI 21)) (clobber (reg:TI 43))
10647 (clobber (reg:TI 22)) (clobber (reg:TI 44))
10648 (clobber (reg:TI 23)) (clobber (reg:TI 45))
10649 (clobber (reg:TI 24)) (clobber (reg:TI 46))
10650 (clobber (reg:TI 25)) (clobber (reg:TI 47))
10651 (clobber (reg:TI 26)) (clobber (reg:TI 48))
10652 (clobber (reg:TI 27)) (clobber (reg:TI 49))
10653 (clobber (reg:TI 28)) (clobber (reg:TI 50))
10654 (clobber (reg:TI 29)) (clobber (reg:TI 51))
10655 (clobber (reg:TI 30)) (clobber (reg:TI 52))
10656 (clobber (reg:TI 31)) (clobber (reg:TI 53))]
10657 ; CONST_OK_FOR_CONSTRAINT_P does not work with D constraint since D is
10658 ; not supposed to be used for immediates (see genpreds.c).
10659 "TARGET_VX && INTVAL (operands[0]) >= 0 && INTVAL (operands[0]) <= 0xffff"
10660 "tbegin\t%1,%x0"
10661 [(set_attr "op_type" "SIL")])
10662
10663 (define_insn "tbegin_1"
10664 [(set (reg:CCRAW CC_REGNUM)
10665 (unspec_volatile:CCRAW [(match_operand 0 "const_int_operand" "D")]
10666 UNSPECV_TBEGIN))
10667 (set (match_operand:BLK 1 "memory_operand" "=Q")
10668 (unspec_volatile:BLK [(match_dup 0)] UNSPECV_TBEGIN_TDB))
10669 (clobber (reg:DF 16))
10670 (clobber (reg:DF 17))
10671 (clobber (reg:DF 18))
10672 (clobber (reg:DF 19))
10673 (clobber (reg:DF 20))
10674 (clobber (reg:DF 21))
10675 (clobber (reg:DF 22))
10676 (clobber (reg:DF 23))
10677 (clobber (reg:DF 24))
10678 (clobber (reg:DF 25))
10679 (clobber (reg:DF 26))
10680 (clobber (reg:DF 27))
10681 (clobber (reg:DF 28))
10682 (clobber (reg:DF 29))
10683 (clobber (reg:DF 30))
10684 (clobber (reg:DF 31))]
10685 ; CONST_OK_FOR_CONSTRAINT_P does not work with D constraint since D is
10686 ; not supposed to be used for immediates (see genpreds.c).
10687 "TARGET_HTM && INTVAL (operands[0]) >= 0 && INTVAL (operands[0]) <= 0xffff"
10688 "tbegin\t%1,%x0"
10689 [(set_attr "op_type" "SIL")])
10690
10691 ; Same as above but without the FPR clobbers
10692 (define_insn "tbegin_nofloat_1"
10693 [(set (reg:CCRAW CC_REGNUM)
10694 (unspec_volatile:CCRAW [(match_operand 0 "const_int_operand" "D")]
10695 UNSPECV_TBEGIN))
10696 (set (match_operand:BLK 1 "memory_operand" "=Q")
10697 (unspec_volatile:BLK [(match_dup 0)] UNSPECV_TBEGIN_TDB))]
10698 "TARGET_HTM && INTVAL (operands[0]) >= 0 && INTVAL (operands[0]) <= 0xffff"
10699 "tbegin\t%1,%x0"
10700 [(set_attr "op_type" "SIL")])
10701
10702
10703 ; Constrained transaction begin
10704
10705 (define_expand "tbeginc"
10706 [(set (reg:CCRAW CC_REGNUM)
10707 (unspec_volatile:CCRAW [(const_int TBEGINC_MASK)]
10708 UNSPECV_TBEGINC))]
10709 "TARGET_HTM"
10710 "")
10711
10712 (define_insn "*tbeginc_1"
10713 [(set (reg:CCRAW CC_REGNUM)
10714 (unspec_volatile:CCRAW [(match_operand 0 "const_int_operand" " D")]
10715 UNSPECV_TBEGINC))]
10716 "TARGET_HTM && INTVAL (operands[0]) >= 0 && INTVAL (operands[0]) <= 0xffff"
10717 "tbeginc\t0,%x0"
10718 [(set_attr "op_type" "SIL")])
10719
10720 ; Transaction end
10721
10722 (define_expand "tend"
10723 [(set (reg:CCRAW CC_REGNUM)
10724 (unspec_volatile:CCRAW [(const_int 0)] UNSPECV_TEND))
10725 (set (match_operand:SI 0 "register_operand" "")
10726 (unspec:SI [(reg:CCRAW CC_REGNUM)] UNSPEC_CC_TO_INT))]
10727 "TARGET_HTM"
10728 "")
10729
10730 (define_insn "*tend_1"
10731 [(set (reg:CCRAW CC_REGNUM)
10732 (unspec_volatile:CCRAW [(const_int 0)] UNSPECV_TEND))]
10733 "TARGET_HTM"
10734 "tend"
10735 [(set_attr "op_type" "S")])
10736
10737 ; Transaction abort
10738
10739 (define_expand "tabort"
10740 [(unspec_volatile [(match_operand:SI 0 "shift_count_or_setmem_operand" "")]
10741 UNSPECV_TABORT)]
10742 "TARGET_HTM && operands != NULL"
10743 {
10744 if (CONST_INT_P (operands[0])
10745 && INTVAL (operands[0]) >= 0 && INTVAL (operands[0]) <= 255)
10746 {
10747 error ("Invalid transaction abort code: " HOST_WIDE_INT_PRINT_DEC
10748 ". Values in range 0 through 255 are reserved.",
10749 INTVAL (operands[0]));
10750 FAIL;
10751 }
10752 })
10753
10754 (define_insn "*tabort_1"
10755 [(unspec_volatile [(match_operand:SI 0 "shift_count_or_setmem_operand" "Y")]
10756 UNSPECV_TABORT)]
10757 "TARGET_HTM && operands != NULL"
10758 "tabort\t%Y0"
10759 [(set_attr "op_type" "S")])
10760
10761 ; Transaction extract nesting depth
10762
10763 (define_insn "etnd"
10764 [(set (match_operand:SI 0 "register_operand" "=d")
10765 (unspec_volatile:SI [(const_int 0)] UNSPECV_ETND))]
10766 "TARGET_HTM"
10767 "etnd\t%0"
10768 [(set_attr "op_type" "RRE")])
10769
10770 ; Non-transactional store
10771
10772 (define_insn "ntstg"
10773 [(set (match_operand:DI 0 "memory_operand" "=RT")
10774 (unspec_volatile:DI [(match_operand:DI 1 "register_operand" "d")]
10775 UNSPECV_NTSTG))]
10776 "TARGET_HTM"
10777 "ntstg\t%1,%0"
10778 [(set_attr "op_type" "RXY")])
10779
10780 ; Transaction perform processor assist
10781
10782 (define_expand "tx_assist"
10783 [(unspec_volatile [(match_operand:SI 0 "register_operand" "")
10784 (reg:SI GPR0_REGNUM)
10785 (const_int 1)]
10786 UNSPECV_PPA)]
10787 "TARGET_HTM"
10788 "")
10789
10790 (define_insn "*ppa"
10791 [(unspec_volatile [(match_operand:SI 0 "register_operand" "d")
10792 (match_operand:SI 1 "register_operand" "d")
10793 (match_operand 2 "const_int_operand" "I")]
10794 UNSPECV_PPA)]
10795 "TARGET_HTM && INTVAL (operands[2]) < 16"
10796 "ppa\t%0,%1,%2"
10797 [(set_attr "op_type" "RRF")])
10798
10799
10800 ; Set and get floating point control register
10801
10802 (define_insn "sfpc"
10803 [(unspec_volatile [(match_operand:SI 0 "register_operand" "d")]
10804 UNSPECV_SFPC)]
10805 "TARGET_HARD_FLOAT"
10806 "sfpc\t%0")
10807
10808 (define_insn "efpc"
10809 [(set (match_operand:SI 0 "register_operand" "=d")
10810 (unspec_volatile:SI [(const_int 0)] UNSPECV_EFPC))]
10811 "TARGET_HARD_FLOAT"
10812 "efpc\t%0")
10813
10814
10815 ; Load count to block boundary
10816
10817 (define_insn "lcbb"
10818 [(set (match_operand:SI 0 "register_operand" "=d")
10819 (unspec:SI [(match_operand:SI 1 "address_operand" "ZQZR")
10820 (match_operand:SI 2 "immediate_operand" "C")] UNSPEC_LCBB))
10821 (clobber (reg:CC CC_REGNUM))]
10822 "TARGET_Z13"
10823 "lcbb\t%0,%1,%b2"
10824 [(set_attr "op_type" "VRX")])