[PATCH] S/390: Improve risbg usage
[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 "operands[1] = s390_emit_compare (GET_CODE (operands[1]),
6112 XEXP (operands[1], 0), XEXP (operands[1], 1));")
6113
6114 ; locr, loc, stoc, locgr, locg, stocg
6115 (define_insn_and_split "*mov<mode>cc"
6116 [(set (match_operand:GPR 0 "nonimmediate_operand" "=d,d, d, d,QS,QS,&d")
6117 (if_then_else:GPR
6118 (match_operator 1 "s390_comparison"
6119 [(match_operand 2 "cc_reg_operand" " c,c, c, c, c, c, c")
6120 (match_operand 5 "const_int_operand" "")])
6121 (match_operand:GPR 3 "nonimmediate_operand" " d,0,QS, 0, d, 0,QS")
6122 (match_operand:GPR 4 "nonimmediate_operand" " 0,d, 0,QS, 0, d,QS")))]
6123 "TARGET_Z196"
6124 "@
6125 loc<g>r%C1\t%0,%3
6126 loc<g>r%D1\t%0,%4
6127 loc<g>%C1\t%0,%3
6128 loc<g>%D1\t%0,%4
6129 stoc<g>%C1\t%3,%0
6130 stoc<g>%D1\t%4,%0
6131 #"
6132 "&& reload_completed
6133 && MEM_P (operands[3]) && MEM_P (operands[4])"
6134 [(set (match_dup 0)
6135 (if_then_else:GPR
6136 (match_op_dup 1 [(match_dup 2) (const_int 0)])
6137 (match_dup 3)
6138 (match_dup 0)))
6139 (set (match_dup 0)
6140 (if_then_else:GPR
6141 (match_op_dup 1 [(match_dup 2) (const_int 0)])
6142 (match_dup 0)
6143 (match_dup 4)))]
6144 ""
6145 [(set_attr "op_type" "RRF,RRF,RSY,RSY,RSY,RSY,*")])
6146
6147 ;;
6148 ;;- Multiply instructions.
6149 ;;
6150
6151 ;
6152 ; muldi3 instruction pattern(s).
6153 ;
6154
6155 (define_insn "*muldi3_sign"
6156 [(set (match_operand:DI 0 "register_operand" "=d,d")
6157 (mult:DI (sign_extend:DI (match_operand:SI 2 "general_operand" "d,RT"))
6158 (match_operand:DI 1 "register_operand" "0,0")))]
6159 "TARGET_ZARCH"
6160 "@
6161 msgfr\t%0,%2
6162 msgf\t%0,%2"
6163 [(set_attr "op_type" "RRE,RXY")
6164 (set_attr "type" "imuldi")])
6165
6166 (define_insn "muldi3"
6167 [(set (match_operand:DI 0 "register_operand" "=d,d,d,d")
6168 (mult:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,0")
6169 (match_operand:DI 2 "general_operand" "d,K,RT,Os")))]
6170 "TARGET_ZARCH"
6171 "@
6172 msgr\t%0,%2
6173 mghi\t%0,%h2
6174 msg\t%0,%2
6175 msgfi\t%0,%2"
6176 [(set_attr "op_type" "RRE,RI,RXY,RIL")
6177 (set_attr "type" "imuldi")
6178 (set_attr "cpu_facility" "*,*,*,z10")])
6179
6180 ;
6181 ; mulsi3 instruction pattern(s).
6182 ;
6183
6184 (define_insn "*mulsi3_sign"
6185 [(set (match_operand:SI 0 "register_operand" "=d,d")
6186 (mult:SI (sign_extend:SI (match_operand:HI 2 "memory_operand" "R,T"))
6187 (match_operand:SI 1 "register_operand" "0,0")))]
6188 ""
6189 "@
6190 mh\t%0,%2
6191 mhy\t%0,%2"
6192 [(set_attr "op_type" "RX,RXY")
6193 (set_attr "type" "imulhi")
6194 (set_attr "cpu_facility" "*,z10")])
6195
6196 (define_insn "mulsi3"
6197 [(set (match_operand:SI 0 "register_operand" "=d,d,d,d,d")
6198 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,0,0,0")
6199 (match_operand:SI 2 "general_operand" "d,K,R,T,Os")))]
6200 ""
6201 "@
6202 msr\t%0,%2
6203 mhi\t%0,%h2
6204 ms\t%0,%2
6205 msy\t%0,%2
6206 msfi\t%0,%2"
6207 [(set_attr "op_type" "RRE,RI,RX,RXY,RIL")
6208 (set_attr "type" "imulsi,imulhi,imulsi,imulsi,imulsi")
6209 (set_attr "cpu_facility" "*,*,*,*,z10")])
6210
6211 ;
6212 ; mulsidi3 instruction pattern(s).
6213 ;
6214
6215 (define_insn "mulsidi3"
6216 [(set (match_operand:DI 0 "register_operand" "=d,d,d")
6217 (mult:DI (sign_extend:DI
6218 (match_operand:SI 1 "register_operand" "%0,0,0"))
6219 (sign_extend:DI
6220 (match_operand:SI 2 "nonimmediate_operand" "d,R,T"))))]
6221 "!TARGET_ZARCH"
6222 "@
6223 mr\t%0,%2
6224 m\t%0,%2
6225 mfy\t%0,%2"
6226 [(set_attr "op_type" "RR,RX,RXY")
6227 (set_attr "type" "imulsi")
6228 (set_attr "cpu_facility" "*,*,z10")])
6229
6230 ;
6231 ; umul instruction pattern(s).
6232 ;
6233
6234 ; mlr, ml, mlgr, mlg
6235 (define_insn "umul<dwh><mode>3"
6236 [(set (match_operand:DW 0 "register_operand" "=d, d")
6237 (mult:DW (zero_extend:DW
6238 (match_operand:<DWH> 1 "register_operand" "%0, 0"))
6239 (zero_extend:DW
6240 (match_operand:<DWH> 2 "nonimmediate_operand" " d,RT"))))]
6241 "TARGET_CPU_ZARCH"
6242 "@
6243 ml<tg>r\t%0,%2
6244 ml<tg>\t%0,%2"
6245 [(set_attr "op_type" "RRE,RXY")
6246 (set_attr "type" "imul<dwh>")])
6247
6248 ;
6249 ; mul(tf|df|sf|td|dd)3 instruction pattern(s).
6250 ;
6251
6252 ; mxbr, mdbr, meebr, mxb, mxb, meeb, mdtr, mxtr
6253 (define_insn "mul<mode>3"
6254 [(set (match_operand:FP 0 "register_operand" "=f, f,<vf>")
6255 (mult:FP (match_operand:FP 1 "nonimmediate_operand" "%<f0>, 0,<v0>")
6256 (match_operand:FP 2 "general_operand" "f,<Rf>,<vf>")))]
6257 "TARGET_HARD_FLOAT"
6258 "@
6259 m<xdee><bt>r\t%0,<op1>%2
6260 m<xdee>b\t%0,%2
6261 wfmdb\t%v0,%v1,%v2"
6262 [(set_attr "op_type" "<RRer>,RXE,VRR")
6263 (set_attr "type" "fmul<mode>")
6264 (set_attr "cpu_facility" "*,*,vec")])
6265
6266 ; madbr, maebr, maxb, madb, maeb
6267 (define_insn "fma<mode>4"
6268 [(set (match_operand:DSF 0 "register_operand" "=f,f,<vf>")
6269 (fma:DSF (match_operand:DSF 1 "nonimmediate_operand" "%f,f,<vf>")
6270 (match_operand:DSF 2 "nonimmediate_operand" "f,R,<vf>")
6271 (match_operand:DSF 3 "register_operand" "0,0,<v0>")))]
6272 "TARGET_HARD_FLOAT"
6273 "@
6274 ma<xde>br\t%0,%1,%2
6275 ma<xde>b\t%0,%1,%2
6276 wfmadb\t%v0,%v1,%v2,%v3"
6277 [(set_attr "op_type" "RRE,RXE,VRR")
6278 (set_attr "type" "fmadd<mode>")
6279 (set_attr "cpu_facility" "*,*,vec")])
6280
6281 ; msxbr, msdbr, msebr, msxb, msdb, mseb
6282 (define_insn "fms<mode>4"
6283 [(set (match_operand:DSF 0 "register_operand" "=f,f,<vf>")
6284 (fma:DSF (match_operand:DSF 1 "nonimmediate_operand" "%f,f,<vf>")
6285 (match_operand:DSF 2 "nonimmediate_operand" "f,R,<vf>")
6286 (neg:DSF (match_operand:DSF 3 "register_operand" "0,0,<v0>"))))]
6287 "TARGET_HARD_FLOAT"
6288 "@
6289 ms<xde>br\t%0,%1,%2
6290 ms<xde>b\t%0,%1,%2
6291 wfmsdb\t%v0,%v1,%v2,%v3"
6292 [(set_attr "op_type" "RRE,RXE,VRR")
6293 (set_attr "type" "fmadd<mode>")
6294 (set_attr "cpu_facility" "*,*,vec")])
6295
6296 ;;
6297 ;;- Divide and modulo instructions.
6298 ;;
6299
6300 ;
6301 ; divmoddi4 instruction pattern(s).
6302 ;
6303
6304 (define_expand "divmoddi4"
6305 [(parallel [(set (match_operand:DI 0 "general_operand" "")
6306 (div:DI (match_operand:DI 1 "register_operand" "")
6307 (match_operand:DI 2 "general_operand" "")))
6308 (set (match_operand:DI 3 "general_operand" "")
6309 (mod:DI (match_dup 1) (match_dup 2)))])
6310 (clobber (match_dup 4))]
6311 "TARGET_ZARCH"
6312 {
6313 rtx insn, div_equal, mod_equal;
6314
6315 div_equal = gen_rtx_DIV (DImode, operands[1], operands[2]);
6316 mod_equal = gen_rtx_MOD (DImode, operands[1], operands[2]);
6317
6318 operands[4] = gen_reg_rtx(TImode);
6319 emit_insn (gen_divmodtidi3 (operands[4], operands[1], operands[2]));
6320
6321 insn = emit_move_insn (operands[0], gen_lowpart (DImode, operands[4]));
6322 set_unique_reg_note (insn, REG_EQUAL, div_equal);
6323
6324 insn = emit_move_insn (operands[3], gen_highpart (DImode, operands[4]));
6325 set_unique_reg_note (insn, REG_EQUAL, mod_equal);
6326
6327 DONE;
6328 })
6329
6330 (define_insn "divmodtidi3"
6331 [(set (match_operand:TI 0 "register_operand" "=d,d")
6332 (ior:TI
6333 (ashift:TI
6334 (zero_extend:TI
6335 (mod:DI (match_operand:DI 1 "register_operand" "0,0")
6336 (match_operand:DI 2 "general_operand" "d,RT")))
6337 (const_int 64))
6338 (zero_extend:TI (div:DI (match_dup 1) (match_dup 2)))))]
6339 "TARGET_ZARCH"
6340 "@
6341 dsgr\t%0,%2
6342 dsg\t%0,%2"
6343 [(set_attr "op_type" "RRE,RXY")
6344 (set_attr "type" "idiv")])
6345
6346 (define_insn "divmodtisi3"
6347 [(set (match_operand:TI 0 "register_operand" "=d,d")
6348 (ior:TI
6349 (ashift:TI
6350 (zero_extend:TI
6351 (mod:DI (match_operand:DI 1 "register_operand" "0,0")
6352 (sign_extend:DI
6353 (match_operand:SI 2 "nonimmediate_operand" "d,RT"))))
6354 (const_int 64))
6355 (zero_extend:TI
6356 (div:DI (match_dup 1) (sign_extend:DI (match_dup 2))))))]
6357 "TARGET_ZARCH"
6358 "@
6359 dsgfr\t%0,%2
6360 dsgf\t%0,%2"
6361 [(set_attr "op_type" "RRE,RXY")
6362 (set_attr "type" "idiv")])
6363
6364 ;
6365 ; udivmoddi4 instruction pattern(s).
6366 ;
6367
6368 (define_expand "udivmoddi4"
6369 [(parallel [(set (match_operand:DI 0 "general_operand" "")
6370 (udiv:DI (match_operand:DI 1 "general_operand" "")
6371 (match_operand:DI 2 "nonimmediate_operand" "")))
6372 (set (match_operand:DI 3 "general_operand" "")
6373 (umod:DI (match_dup 1) (match_dup 2)))])
6374 (clobber (match_dup 4))]
6375 "TARGET_ZARCH"
6376 {
6377 rtx insn, div_equal, mod_equal, equal;
6378
6379 div_equal = gen_rtx_UDIV (DImode, operands[1], operands[2]);
6380 mod_equal = gen_rtx_UMOD (DImode, operands[1], operands[2]);
6381 equal = gen_rtx_IOR (TImode,
6382 gen_rtx_ASHIFT (TImode,
6383 gen_rtx_ZERO_EXTEND (TImode, mod_equal),
6384 GEN_INT (64)),
6385 gen_rtx_ZERO_EXTEND (TImode, div_equal));
6386
6387 operands[4] = gen_reg_rtx(TImode);
6388 emit_clobber (operands[4]);
6389 emit_move_insn (gen_lowpart (DImode, operands[4]), operands[1]);
6390 emit_move_insn (gen_highpart (DImode, operands[4]), const0_rtx);
6391
6392 insn = emit_insn (gen_udivmodtidi3 (operands[4], operands[4], operands[2]));
6393 set_unique_reg_note (insn, REG_EQUAL, equal);
6394
6395 insn = emit_move_insn (operands[0], gen_lowpart (DImode, operands[4]));
6396 set_unique_reg_note (insn, REG_EQUAL, div_equal);
6397
6398 insn = emit_move_insn (operands[3], gen_highpart (DImode, operands[4]));
6399 set_unique_reg_note (insn, REG_EQUAL, mod_equal);
6400
6401 DONE;
6402 })
6403
6404 (define_insn "udivmodtidi3"
6405 [(set (match_operand:TI 0 "register_operand" "=d,d")
6406 (ior:TI
6407 (ashift:TI
6408 (zero_extend:TI
6409 (truncate:DI
6410 (umod:TI (match_operand:TI 1 "register_operand" "0,0")
6411 (zero_extend:TI
6412 (match_operand:DI 2 "nonimmediate_operand" "d,RT")))))
6413 (const_int 64))
6414 (zero_extend:TI
6415 (truncate:DI
6416 (udiv:TI (match_dup 1) (zero_extend:TI (match_dup 2)))))))]
6417 "TARGET_ZARCH"
6418 "@
6419 dlgr\t%0,%2
6420 dlg\t%0,%2"
6421 [(set_attr "op_type" "RRE,RXY")
6422 (set_attr "type" "idiv")])
6423
6424 ;
6425 ; divmodsi4 instruction pattern(s).
6426 ;
6427
6428 (define_expand "divmodsi4"
6429 [(parallel [(set (match_operand:SI 0 "general_operand" "")
6430 (div:SI (match_operand:SI 1 "general_operand" "")
6431 (match_operand:SI 2 "nonimmediate_operand" "")))
6432 (set (match_operand:SI 3 "general_operand" "")
6433 (mod:SI (match_dup 1) (match_dup 2)))])
6434 (clobber (match_dup 4))]
6435 "!TARGET_ZARCH"
6436 {
6437 rtx insn, div_equal, mod_equal, equal;
6438
6439 div_equal = gen_rtx_DIV (SImode, operands[1], operands[2]);
6440 mod_equal = gen_rtx_MOD (SImode, operands[1], operands[2]);
6441 equal = gen_rtx_IOR (DImode,
6442 gen_rtx_ASHIFT (DImode,
6443 gen_rtx_ZERO_EXTEND (DImode, mod_equal),
6444 GEN_INT (32)),
6445 gen_rtx_ZERO_EXTEND (DImode, div_equal));
6446
6447 operands[4] = gen_reg_rtx(DImode);
6448 emit_insn (gen_extendsidi2 (operands[4], operands[1]));
6449
6450 insn = emit_insn (gen_divmoddisi3 (operands[4], operands[4], operands[2]));
6451 set_unique_reg_note (insn, REG_EQUAL, equal);
6452
6453 insn = emit_move_insn (operands[0], gen_lowpart (SImode, operands[4]));
6454 set_unique_reg_note (insn, REG_EQUAL, div_equal);
6455
6456 insn = emit_move_insn (operands[3], gen_highpart (SImode, operands[4]));
6457 set_unique_reg_note (insn, REG_EQUAL, mod_equal);
6458
6459 DONE;
6460 })
6461
6462 (define_insn "divmoddisi3"
6463 [(set (match_operand:DI 0 "register_operand" "=d,d")
6464 (ior:DI
6465 (ashift:DI
6466 (zero_extend:DI
6467 (truncate:SI
6468 (mod:DI (match_operand:DI 1 "register_operand" "0,0")
6469 (sign_extend:DI
6470 (match_operand:SI 2 "nonimmediate_operand" "d,R")))))
6471 (const_int 32))
6472 (zero_extend:DI
6473 (truncate:SI
6474 (div:DI (match_dup 1) (sign_extend:DI (match_dup 2)))))))]
6475 "!TARGET_ZARCH"
6476 "@
6477 dr\t%0,%2
6478 d\t%0,%2"
6479 [(set_attr "op_type" "RR,RX")
6480 (set_attr "type" "idiv")])
6481
6482 ;
6483 ; udivsi3 and umodsi3 instruction pattern(s).
6484 ;
6485
6486 (define_expand "udivmodsi4"
6487 [(parallel [(set (match_operand:SI 0 "general_operand" "")
6488 (udiv:SI (match_operand:SI 1 "general_operand" "")
6489 (match_operand:SI 2 "nonimmediate_operand" "")))
6490 (set (match_operand:SI 3 "general_operand" "")
6491 (umod:SI (match_dup 1) (match_dup 2)))])
6492 (clobber (match_dup 4))]
6493 "!TARGET_ZARCH && TARGET_CPU_ZARCH"
6494 {
6495 rtx insn, div_equal, mod_equal, equal;
6496
6497 div_equal = gen_rtx_UDIV (SImode, operands[1], operands[2]);
6498 mod_equal = gen_rtx_UMOD (SImode, operands[1], operands[2]);
6499 equal = gen_rtx_IOR (DImode,
6500 gen_rtx_ASHIFT (DImode,
6501 gen_rtx_ZERO_EXTEND (DImode, mod_equal),
6502 GEN_INT (32)),
6503 gen_rtx_ZERO_EXTEND (DImode, div_equal));
6504
6505 operands[4] = gen_reg_rtx(DImode);
6506 emit_clobber (operands[4]);
6507 emit_move_insn (gen_lowpart (SImode, operands[4]), operands[1]);
6508 emit_move_insn (gen_highpart (SImode, operands[4]), const0_rtx);
6509
6510 insn = emit_insn (gen_udivmoddisi3 (operands[4], operands[4], operands[2]));
6511 set_unique_reg_note (insn, REG_EQUAL, equal);
6512
6513 insn = emit_move_insn (operands[0], gen_lowpart (SImode, operands[4]));
6514 set_unique_reg_note (insn, REG_EQUAL, div_equal);
6515
6516 insn = emit_move_insn (operands[3], gen_highpart (SImode, operands[4]));
6517 set_unique_reg_note (insn, REG_EQUAL, mod_equal);
6518
6519 DONE;
6520 })
6521
6522 (define_insn "udivmoddisi3"
6523 [(set (match_operand:DI 0 "register_operand" "=d,d")
6524 (ior:DI
6525 (ashift:DI
6526 (zero_extend:DI
6527 (truncate:SI
6528 (umod:DI (match_operand:DI 1 "register_operand" "0,0")
6529 (zero_extend:DI
6530 (match_operand:SI 2 "nonimmediate_operand" "d,RT")))))
6531 (const_int 32))
6532 (zero_extend:DI
6533 (truncate:SI
6534 (udiv:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))))]
6535 "!TARGET_ZARCH && TARGET_CPU_ZARCH"
6536 "@
6537 dlr\t%0,%2
6538 dl\t%0,%2"
6539 [(set_attr "op_type" "RRE,RXY")
6540 (set_attr "type" "idiv")])
6541
6542 (define_expand "udivsi3"
6543 [(set (match_operand:SI 0 "register_operand" "=d")
6544 (udiv:SI (match_operand:SI 1 "general_operand" "")
6545 (match_operand:SI 2 "general_operand" "")))
6546 (clobber (match_dup 3))]
6547 "!TARGET_ZARCH && !TARGET_CPU_ZARCH"
6548 {
6549 rtx insn, udiv_equal, umod_equal, equal;
6550
6551 udiv_equal = gen_rtx_UDIV (SImode, operands[1], operands[2]);
6552 umod_equal = gen_rtx_UMOD (SImode, operands[1], operands[2]);
6553 equal = gen_rtx_IOR (DImode,
6554 gen_rtx_ASHIFT (DImode,
6555 gen_rtx_ZERO_EXTEND (DImode, umod_equal),
6556 GEN_INT (32)),
6557 gen_rtx_ZERO_EXTEND (DImode, udiv_equal));
6558
6559 operands[3] = gen_reg_rtx (DImode);
6560
6561 if (CONSTANT_P (operands[2]))
6562 {
6563 if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0)
6564 {
6565 rtx_code_label *label1 = gen_label_rtx ();
6566
6567 operands[1] = make_safe_from (operands[1], operands[0]);
6568 emit_move_insn (operands[0], const0_rtx);
6569 emit_cmp_and_jump_insns (operands[1], operands[2], LT, NULL_RTX,
6570 SImode, 1, label1);
6571 emit_move_insn (operands[0], const1_rtx);
6572 emit_label (label1);
6573 }
6574 else
6575 {
6576 operands[2] = force_reg (SImode, operands[2]);
6577 operands[2] = make_safe_from (operands[2], operands[0]);
6578
6579 emit_insn (gen_zero_extendsidi2 (operands[3], operands[1]));
6580 insn = emit_insn (gen_divmoddisi3 (operands[3], operands[3],
6581 operands[2]));
6582 set_unique_reg_note (insn, REG_EQUAL, equal);
6583
6584 insn = emit_move_insn (operands[0],
6585 gen_lowpart (SImode, operands[3]));
6586 set_unique_reg_note (insn, REG_EQUAL, udiv_equal);
6587 }
6588 }
6589 else
6590 {
6591 rtx_code_label *label1 = gen_label_rtx ();
6592 rtx_code_label *label2 = gen_label_rtx ();
6593 rtx_code_label *label3 = gen_label_rtx ();
6594
6595 operands[1] = force_reg (SImode, operands[1]);
6596 operands[1] = make_safe_from (operands[1], operands[0]);
6597 operands[2] = force_reg (SImode, operands[2]);
6598 operands[2] = make_safe_from (operands[2], operands[0]);
6599
6600 emit_move_insn (operands[0], const0_rtx);
6601 emit_cmp_and_jump_insns (operands[2], operands[1], GT, NULL_RTX,
6602 SImode, 1, label3);
6603 emit_cmp_and_jump_insns (operands[2], const0_rtx, LT, NULL_RTX,
6604 SImode, 0, label2);
6605 emit_cmp_and_jump_insns (operands[2], const1_rtx, EQ, NULL_RTX,
6606 SImode, 0, label1);
6607 emit_insn (gen_zero_extendsidi2 (operands[3], operands[1]));
6608 insn = emit_insn (gen_divmoddisi3 (operands[3], operands[3],
6609 operands[2]));
6610 set_unique_reg_note (insn, REG_EQUAL, equal);
6611
6612 insn = emit_move_insn (operands[0],
6613 gen_lowpart (SImode, operands[3]));
6614 set_unique_reg_note (insn, REG_EQUAL, udiv_equal);
6615
6616 emit_jump (label3);
6617 emit_label (label1);
6618 emit_move_insn (operands[0], operands[1]);
6619 emit_jump (label3);
6620 emit_label (label2);
6621 emit_move_insn (operands[0], const1_rtx);
6622 emit_label (label3);
6623 }
6624 emit_move_insn (operands[0], operands[0]);
6625 DONE;
6626 })
6627
6628 (define_expand "umodsi3"
6629 [(set (match_operand:SI 0 "register_operand" "=d")
6630 (umod:SI (match_operand:SI 1 "nonimmediate_operand" "")
6631 (match_operand:SI 2 "nonimmediate_operand" "")))
6632 (clobber (match_dup 3))]
6633 "!TARGET_ZARCH && !TARGET_CPU_ZARCH"
6634 {
6635 rtx insn, udiv_equal, umod_equal, equal;
6636
6637 udiv_equal = gen_rtx_UDIV (SImode, operands[1], operands[2]);
6638 umod_equal = gen_rtx_UMOD (SImode, operands[1], operands[2]);
6639 equal = gen_rtx_IOR (DImode,
6640 gen_rtx_ASHIFT (DImode,
6641 gen_rtx_ZERO_EXTEND (DImode, umod_equal),
6642 GEN_INT (32)),
6643 gen_rtx_ZERO_EXTEND (DImode, udiv_equal));
6644
6645 operands[3] = gen_reg_rtx (DImode);
6646
6647 if (CONSTANT_P (operands[2]))
6648 {
6649 if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) <= 0)
6650 {
6651 rtx_code_label *label1 = gen_label_rtx ();
6652
6653 operands[1] = make_safe_from (operands[1], operands[0]);
6654 emit_move_insn (operands[0], operands[1]);
6655 emit_cmp_and_jump_insns (operands[0], operands[2], LT, NULL_RTX,
6656 SImode, 1, label1);
6657 emit_insn (gen_abssi2 (operands[0], operands[2]));
6658 emit_insn (gen_addsi3 (operands[0], operands[0], operands[1]));
6659 emit_label (label1);
6660 }
6661 else
6662 {
6663 operands[2] = force_reg (SImode, operands[2]);
6664 operands[2] = make_safe_from (operands[2], operands[0]);
6665
6666 emit_insn (gen_zero_extendsidi2 (operands[3], operands[1]));
6667 insn = emit_insn (gen_divmoddisi3 (operands[3], operands[3],
6668 operands[2]));
6669 set_unique_reg_note (insn, REG_EQUAL, equal);
6670
6671 insn = emit_move_insn (operands[0],
6672 gen_highpart (SImode, operands[3]));
6673 set_unique_reg_note (insn, REG_EQUAL, umod_equal);
6674 }
6675 }
6676 else
6677 {
6678 rtx_code_label *label1 = gen_label_rtx ();
6679 rtx_code_label *label2 = gen_label_rtx ();
6680 rtx_code_label *label3 = gen_label_rtx ();
6681
6682 operands[1] = force_reg (SImode, operands[1]);
6683 operands[1] = make_safe_from (operands[1], operands[0]);
6684 operands[2] = force_reg (SImode, operands[2]);
6685 operands[2] = make_safe_from (operands[2], operands[0]);
6686
6687 emit_move_insn(operands[0], operands[1]);
6688 emit_cmp_and_jump_insns (operands[2], operands[1], GT, NULL_RTX,
6689 SImode, 1, label3);
6690 emit_cmp_and_jump_insns (operands[2], const0_rtx, LT, NULL_RTX,
6691 SImode, 0, label2);
6692 emit_cmp_and_jump_insns (operands[2], const1_rtx, EQ, NULL_RTX,
6693 SImode, 0, label1);
6694 emit_insn (gen_zero_extendsidi2 (operands[3], operands[1]));
6695 insn = emit_insn (gen_divmoddisi3 (operands[3], operands[3],
6696 operands[2]));
6697 set_unique_reg_note (insn, REG_EQUAL, equal);
6698
6699 insn = emit_move_insn (operands[0],
6700 gen_highpart (SImode, operands[3]));
6701 set_unique_reg_note (insn, REG_EQUAL, umod_equal);
6702
6703 emit_jump (label3);
6704 emit_label (label1);
6705 emit_move_insn (operands[0], const0_rtx);
6706 emit_jump (label3);
6707 emit_label (label2);
6708 emit_insn (gen_subsi3 (operands[0], operands[0], operands[2]));
6709 emit_label (label3);
6710 }
6711 DONE;
6712 })
6713
6714 ;
6715 ; div(df|sf)3 instruction pattern(s).
6716 ;
6717
6718 ; dxbr, ddbr, debr, dxb, ddb, deb, ddtr, dxtr
6719 (define_insn "div<mode>3"
6720 [(set (match_operand:FP 0 "register_operand" "=f, f,<vf>")
6721 (div:FP (match_operand:FP 1 "register_operand" "<f0>, 0,<v0>")
6722 (match_operand:FP 2 "general_operand" "f,<Rf>,<vf>")))]
6723 "TARGET_HARD_FLOAT"
6724 "@
6725 d<xde><bt>r\t%0,<op1>%2
6726 d<xde>b\t%0,%2
6727 wfddb\t%v0,%v1,%v2"
6728 [(set_attr "op_type" "<RRer>,RXE,VRR")
6729 (set_attr "type" "fdiv<mode>")
6730 (set_attr "cpu_facility" "*,*,vec")])
6731
6732
6733 ;;
6734 ;;- And instructions.
6735 ;;
6736
6737 (define_expand "and<mode>3"
6738 [(set (match_operand:INT 0 "nonimmediate_operand" "")
6739 (and:INT (match_operand:INT 1 "nonimmediate_operand" "")
6740 (match_operand:INT 2 "general_operand" "")))
6741 (clobber (reg:CC CC_REGNUM))]
6742 ""
6743 "s390_expand_logical_operator (AND, <MODE>mode, operands); DONE;")
6744
6745 ;
6746 ; anddi3 instruction pattern(s).
6747 ;
6748
6749 (define_insn "*anddi3_cc"
6750 [(set (reg CC_REGNUM)
6751 (compare
6752 (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,d, 0, d")
6753 (match_operand:DI 2 "general_operand" " d,d,RT,NxxDq"))
6754 (const_int 0)))
6755 (set (match_operand:DI 0 "register_operand" "=d,d, d, d")
6756 (and:DI (match_dup 1) (match_dup 2)))]
6757 "TARGET_ZARCH && s390_match_ccmode(insn, CCTmode)"
6758 "@
6759 ngr\t%0,%2
6760 ngrk\t%0,%1,%2
6761 ng\t%0,%2
6762 risbg\t%0,%1,%s2,128+%e2,0"
6763 [(set_attr "op_type" "RRE,RRF,RXY,RIE")
6764 (set_attr "cpu_facility" "*,z196,*,z10")
6765 (set_attr "z10prop" "z10_super_E1,*,z10_super_E1,z10_super_E1")])
6766
6767 (define_insn "*anddi3_cconly"
6768 [(set (reg CC_REGNUM)
6769 (compare
6770 (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,d, 0, d")
6771 (match_operand:DI 2 "general_operand" " d,d,RT,NxxDq"))
6772 (const_int 0)))
6773 (clobber (match_scratch:DI 0 "=d,d, d, d"))]
6774 "TARGET_ZARCH
6775 && s390_match_ccmode(insn, CCTmode)
6776 /* Do not steal TM patterns. */
6777 && s390_single_part (operands[2], DImode, HImode, 0) < 0"
6778 "@
6779 ngr\t%0,%2
6780 ngrk\t%0,%1,%2
6781 ng\t%0,%2
6782 risbg\t%0,%1,%s2,128+%e2,0"
6783 [(set_attr "op_type" "RRE,RRF,RXY,RIE")
6784 (set_attr "cpu_facility" "*,z196,*,z10")
6785 (set_attr "z10prop" "z10_super_E1,*,z10_super_E1,z10_super_E1")])
6786
6787 (define_insn "*anddi3"
6788 [(set (match_operand:DI 0 "nonimmediate_operand"
6789 "=d,d, d, d, d, d, d, d,d,d, d, d, AQ,Q")
6790 (and:DI
6791 (match_operand:DI 1 "nonimmediate_operand"
6792 "%d,o, 0, 0, 0, 0, 0, 0,0,d, 0, d, 0,0")
6793 (match_operand:DI 2 "general_operand"
6794 "M, M,N0HDF,N1HDF,N2HDF,N3HDF,N0SDF,N1SDF,d,d,RT,NxxDq,NxQDF,Q")))
6795 (clobber (reg:CC CC_REGNUM))]
6796 "TARGET_ZARCH && s390_logical_operator_ok_p (operands)"
6797 "@
6798 #
6799 #
6800 nihh\t%0,%j2
6801 nihl\t%0,%j2
6802 nilh\t%0,%j2
6803 nill\t%0,%j2
6804 nihf\t%0,%m2
6805 nilf\t%0,%m2
6806 ngr\t%0,%2
6807 ngrk\t%0,%1,%2
6808 ng\t%0,%2
6809 risbg\t%0,%1,%s2,128+%e2,0
6810 #
6811 #"
6812 [(set_attr "op_type" "RRE,RXE,RI,RI,RI,RI,RIL,RIL,RRE,RRF,RXY,RIE,SI,SS")
6813 (set_attr "cpu_facility" "*,*,*,*,*,*,extimm,extimm,*,z196,*,z10,*,*")
6814 (set_attr "z10prop" "*,
6815 *,
6816 z10_super_E1,
6817 z10_super_E1,
6818 z10_super_E1,
6819 z10_super_E1,
6820 z10_super_E1,
6821 z10_super_E1,
6822 z10_super_E1,
6823 *,
6824 z10_super_E1,
6825 z10_super_E1,
6826 *,
6827 *")])
6828
6829 (define_split
6830 [(set (match_operand:DI 0 "s_operand" "")
6831 (and:DI (match_dup 0) (match_operand:DI 1 "immediate_operand" "")))
6832 (clobber (reg:CC CC_REGNUM))]
6833 "reload_completed"
6834 [(parallel
6835 [(set (match_dup 0) (and:QI (match_dup 0) (match_dup 1)))
6836 (clobber (reg:CC CC_REGNUM))])]
6837 "s390_narrow_logical_operator (AND, &operands[0], &operands[1]);")
6838
6839 ;; These two are what combine generates for (ashift (zero_extract)).
6840 (define_insn "*extzv_<mode>_srl"
6841 [(set (match_operand:GPR 0 "register_operand" "=d")
6842 (and:GPR (lshiftrt:GPR
6843 (match_operand:GPR 1 "register_operand" "d")
6844 (match_operand:GPR 2 "nonzero_shift_count_operand" ""))
6845 (match_operand:GPR 3 "contiguous_bitmask_operand" "")))
6846 (clobber (reg:CC CC_REGNUM))]
6847 "TARGET_Z10
6848 /* Note that even for the SImode pattern, the rotate is always DImode. */
6849 && s390_extzv_shift_ok (<bitsize>, -INTVAL (operands[2]),
6850 INTVAL (operands[3]))"
6851 "risbg\t%0,%1,%<bfstart>3,128+%<bfend>3,64-%2"
6852 [(set_attr "op_type" "RIE")
6853 (set_attr "z10prop" "z10_super_E1")])
6854
6855 (define_insn "*extzv_<mode>_sll"
6856 [(set (match_operand:GPR 0 "register_operand" "=d")
6857 (and:GPR (ashift:GPR
6858 (match_operand:GPR 1 "register_operand" "d")
6859 (match_operand:GPR 2 "nonzero_shift_count_operand" ""))
6860 (match_operand:GPR 3 "contiguous_bitmask_operand" "")))
6861 (clobber (reg:CC CC_REGNUM))]
6862 "TARGET_Z10
6863 && s390_extzv_shift_ok (<bitsize>, INTVAL (operands[2]),
6864 INTVAL (operands[3]))"
6865 "risbg\t%0,%1,%<bfstart>3,128+%<bfend>3,%2"
6866 [(set_attr "op_type" "RIE")
6867 (set_attr "z10prop" "z10_super_E1")])
6868
6869
6870 ;
6871 ; andsi3 instruction pattern(s).
6872 ;
6873
6874 (define_insn "*andsi3_cc"
6875 [(set (reg CC_REGNUM)
6876 (compare
6877 (and:SI
6878 (match_operand:SI 1 "nonimmediate_operand" "%0,0,d,0,0, d")
6879 (match_operand:SI 2 "general_operand" "Os,d,d,R,T,NxxSq"))
6880 (const_int 0)))
6881 (set (match_operand:SI 0 "register_operand" "=d,d,d,d,d, d")
6882 (and:SI (match_dup 1) (match_dup 2)))]
6883 "s390_match_ccmode(insn, CCTmode)"
6884 "@
6885 nilf\t%0,%o2
6886 nr\t%0,%2
6887 nrk\t%0,%1,%2
6888 n\t%0,%2
6889 ny\t%0,%2
6890 risbg\t%0,%1,%t2,128+%f2,0"
6891 [(set_attr "op_type" "RIL,RR,RRF,RX,RXY,RIE")
6892 (set_attr "cpu_facility" "*,*,z196,*,*,z10")
6893 (set_attr "z10prop" "z10_super_E1,z10_super_E1,*,
6894 z10_super_E1,z10_super_E1,z10_super_E1")])
6895
6896 (define_insn "*andsi3_cconly"
6897 [(set (reg CC_REGNUM)
6898 (compare
6899 (and:SI
6900 (match_operand:SI 1 "nonimmediate_operand" "%0,0,d,0,0, d")
6901 (match_operand:SI 2 "general_operand" "Os,d,d,R,T,NxxSq"))
6902 (const_int 0)))
6903 (clobber (match_scratch:SI 0 "=d,d,d,d,d, d"))]
6904 "s390_match_ccmode(insn, CCTmode)
6905 /* Do not steal TM patterns. */
6906 && s390_single_part (operands[2], SImode, HImode, 0) < 0"
6907 "@
6908 nilf\t%0,%o2
6909 nr\t%0,%2
6910 nrk\t%0,%1,%2
6911 n\t%0,%2
6912 ny\t%0,%2
6913 risbg\t%0,%1,%t2,128+%f2,0"
6914 [(set_attr "op_type" "RIL,RR,RRF,RX,RXY,RIE")
6915 (set_attr "cpu_facility" "*,*,z196,*,*,z10")
6916 (set_attr "z10prop" "z10_super_E1,z10_super_E1,*,
6917 z10_super_E1,z10_super_E1,z10_super_E1")])
6918
6919 (define_insn "*andsi3_zarch"
6920 [(set (match_operand:SI 0 "nonimmediate_operand"
6921 "=d,d, d, d, d,d,d,d,d, d, AQ,Q")
6922 (and:SI (match_operand:SI 1 "nonimmediate_operand"
6923 "%d,o, 0, 0, 0,0,d,0,0, d, 0,0")
6924 (match_operand:SI 2 "general_operand"
6925 " M,M,N0HSF,N1HSF,Os,d,d,R,T,NxxSq,NxQSF,Q")))
6926 (clobber (reg:CC CC_REGNUM))]
6927 "TARGET_ZARCH && s390_logical_operator_ok_p (operands)"
6928 "@
6929 #
6930 #
6931 nilh\t%0,%j2
6932 nill\t%0,%j2
6933 nilf\t%0,%o2
6934 nr\t%0,%2
6935 nrk\t%0,%1,%2
6936 n\t%0,%2
6937 ny\t%0,%2
6938 risbg\t%0,%1,%t2,128+%f2,0
6939 #
6940 #"
6941 [(set_attr "op_type" "RRE,RXE,RI,RI,RIL,RR,RRF,RX,RXY,RIE,SI,SS")
6942 (set_attr "cpu_facility" "*,*,*,*,*,*,z196,*,*,z10,*,*")
6943 (set_attr "z10prop" "*,
6944 *,
6945 z10_super_E1,
6946 z10_super_E1,
6947 z10_super_E1,
6948 z10_super_E1,
6949 *,
6950 z10_super_E1,
6951 z10_super_E1,
6952 z10_super_E1,
6953 *,
6954 *")])
6955
6956 (define_insn "*andsi3_esa"
6957 [(set (match_operand:SI 0 "nonimmediate_operand" "=d,d, AQ,Q")
6958 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0, 0,0")
6959 (match_operand:SI 2 "general_operand" " d,R,NxQSF,Q")))
6960 (clobber (reg:CC CC_REGNUM))]
6961 "!TARGET_ZARCH && s390_logical_operator_ok_p (operands)"
6962 "@
6963 nr\t%0,%2
6964 n\t%0,%2
6965 #
6966 #"
6967 [(set_attr "op_type" "RR,RX,SI,SS")
6968 (set_attr "z10prop" "z10_super_E1,z10_super_E1,*,*")])
6969
6970
6971 (define_split
6972 [(set (match_operand:SI 0 "s_operand" "")
6973 (and:SI (match_dup 0) (match_operand:SI 1 "immediate_operand" "")))
6974 (clobber (reg:CC CC_REGNUM))]
6975 "reload_completed"
6976 [(parallel
6977 [(set (match_dup 0) (and:QI (match_dup 0) (match_dup 1)))
6978 (clobber (reg:CC CC_REGNUM))])]
6979 "s390_narrow_logical_operator (AND, &operands[0], &operands[1]);")
6980
6981 ;
6982 ; andhi3 instruction pattern(s).
6983 ;
6984
6985 (define_insn "*andhi3_zarch"
6986 [(set (match_operand:HI 0 "nonimmediate_operand" "=d,d,d, AQ,Q")
6987 (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,d,0, 0,0")
6988 (match_operand:HI 2 "general_operand" " d,d,n,NxQHF,Q")))
6989 (clobber (reg:CC CC_REGNUM))]
6990 "TARGET_ZARCH && s390_logical_operator_ok_p (operands)"
6991 "@
6992 nr\t%0,%2
6993 nrk\t%0,%1,%2
6994 nill\t%0,%x2
6995 #
6996 #"
6997 [(set_attr "op_type" "RR,RRF,RI,SI,SS")
6998 (set_attr "cpu_facility" "*,z196,*,*,*")
6999 (set_attr "z10prop" "z10_super_E1,*,z10_super_E1,*,*")
7000 ])
7001
7002 (define_insn "*andhi3_esa"
7003 [(set (match_operand:HI 0 "nonimmediate_operand" "=d,AQ,Q")
7004 (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,0")
7005 (match_operand:HI 2 "general_operand" "d,NxQHF,Q")))
7006 (clobber (reg:CC CC_REGNUM))]
7007 "!TARGET_ZARCH && s390_logical_operator_ok_p (operands)"
7008 "@
7009 nr\t%0,%2
7010 #
7011 #"
7012 [(set_attr "op_type" "RR,SI,SS")
7013 (set_attr "z10prop" "z10_super_E1,*,*")
7014 ])
7015
7016 (define_split
7017 [(set (match_operand:HI 0 "s_operand" "")
7018 (and:HI (match_dup 0) (match_operand:HI 1 "immediate_operand" "")))
7019 (clobber (reg:CC CC_REGNUM))]
7020 "reload_completed"
7021 [(parallel
7022 [(set (match_dup 0) (and:QI (match_dup 0) (match_dup 1)))
7023 (clobber (reg:CC CC_REGNUM))])]
7024 "s390_narrow_logical_operator (AND, &operands[0], &operands[1]);")
7025
7026 ;
7027 ; andqi3 instruction pattern(s).
7028 ;
7029
7030 (define_insn "*andqi3_zarch"
7031 [(set (match_operand:QI 0 "nonimmediate_operand" "=d,d,d,Q,S,Q")
7032 (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,d,0,0,0,0")
7033 (match_operand:QI 2 "general_operand" " d,d,n,n,n,Q")))
7034 (clobber (reg:CC CC_REGNUM))]
7035 "TARGET_ZARCH && s390_logical_operator_ok_p (operands)"
7036 "@
7037 nr\t%0,%2
7038 nrk\t%0,%1,%2
7039 nill\t%0,%b2
7040 ni\t%S0,%b2
7041 niy\t%S0,%b2
7042 #"
7043 [(set_attr "op_type" "RR,RRF,RI,SI,SIY,SS")
7044 (set_attr "cpu_facility" "*,z196,*,*,*,*")
7045 (set_attr "z10prop" "z10_super_E1,*,z10_super_E1,z10_super,z10_super,*")])
7046
7047 (define_insn "*andqi3_esa"
7048 [(set (match_operand:QI 0 "nonimmediate_operand" "=d,Q,Q")
7049 (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
7050 (match_operand:QI 2 "general_operand" "d,n,Q")))
7051 (clobber (reg:CC CC_REGNUM))]
7052 "!TARGET_ZARCH && s390_logical_operator_ok_p (operands)"
7053 "@
7054 nr\t%0,%2
7055 ni\t%S0,%b2
7056 #"
7057 [(set_attr "op_type" "RR,SI,SS")
7058 (set_attr "z10prop" "z10_super_E1,z10_super,*")])
7059
7060 ;
7061 ; Block and (NC) patterns.
7062 ;
7063
7064 (define_insn "*nc"
7065 [(set (match_operand:BLK 0 "memory_operand" "=Q")
7066 (and:BLK (match_dup 0)
7067 (match_operand:BLK 1 "memory_operand" "Q")))
7068 (use (match_operand 2 "const_int_operand" "n"))
7069 (clobber (reg:CC CC_REGNUM))]
7070 "INTVAL (operands[2]) >= 1 && INTVAL (operands[2]) <= 256"
7071 "nc\t%O0(%2,%R0),%S1"
7072 [(set_attr "op_type" "SS")
7073 (set_attr "z196prop" "z196_cracked")])
7074
7075 (define_split
7076 [(set (match_operand 0 "memory_operand" "")
7077 (and (match_dup 0)
7078 (match_operand 1 "memory_operand" "")))
7079 (clobber (reg:CC CC_REGNUM))]
7080 "reload_completed
7081 && GET_MODE (operands[0]) == GET_MODE (operands[1])
7082 && GET_MODE_SIZE (GET_MODE (operands[0])) > 0"
7083 [(parallel
7084 [(set (match_dup 0) (and:BLK (match_dup 0) (match_dup 1)))
7085 (use (match_dup 2))
7086 (clobber (reg:CC CC_REGNUM))])]
7087 {
7088 operands[2] = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[0])));
7089 operands[0] = adjust_address (operands[0], BLKmode, 0);
7090 operands[1] = adjust_address (operands[1], BLKmode, 0);
7091 })
7092
7093 (define_peephole2
7094 [(parallel
7095 [(set (match_operand:BLK 0 "memory_operand" "")
7096 (and:BLK (match_dup 0)
7097 (match_operand:BLK 1 "memory_operand" "")))
7098 (use (match_operand 2 "const_int_operand" ""))
7099 (clobber (reg:CC CC_REGNUM))])
7100 (parallel
7101 [(set (match_operand:BLK 3 "memory_operand" "")
7102 (and:BLK (match_dup 3)
7103 (match_operand:BLK 4 "memory_operand" "")))
7104 (use (match_operand 5 "const_int_operand" ""))
7105 (clobber (reg:CC CC_REGNUM))])]
7106 "s390_offset_p (operands[0], operands[3], operands[2])
7107 && s390_offset_p (operands[1], operands[4], operands[2])
7108 && !s390_overlap_p (operands[0], operands[1],
7109 INTVAL (operands[2]) + INTVAL (operands[5]))
7110 && INTVAL (operands[2]) + INTVAL (operands[5]) <= 256"
7111 [(parallel
7112 [(set (match_dup 6) (and:BLK (match_dup 6) (match_dup 7)))
7113 (use (match_dup 8))
7114 (clobber (reg:CC CC_REGNUM))])]
7115 "operands[6] = gen_rtx_MEM (BLKmode, XEXP (operands[0], 0));
7116 operands[7] = gen_rtx_MEM (BLKmode, XEXP (operands[1], 0));
7117 operands[8] = GEN_INT (INTVAL (operands[2]) + INTVAL (operands[5]));")
7118
7119
7120 ;;
7121 ;;- Bit set (inclusive or) instructions.
7122 ;;
7123
7124 (define_expand "ior<mode>3"
7125 [(set (match_operand:INT 0 "nonimmediate_operand" "")
7126 (ior:INT (match_operand:INT 1 "nonimmediate_operand" "")
7127 (match_operand:INT 2 "general_operand" "")))
7128 (clobber (reg:CC CC_REGNUM))]
7129 ""
7130 "s390_expand_logical_operator (IOR, <MODE>mode, operands); DONE;")
7131
7132 ;
7133 ; iordi3 instruction pattern(s).
7134 ;
7135
7136 (define_insn "*iordi3_cc"
7137 [(set (reg CC_REGNUM)
7138 (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,d, 0")
7139 (match_operand:DI 2 "general_operand" " d,d,RT"))
7140 (const_int 0)))
7141 (set (match_operand:DI 0 "register_operand" "=d,d, d")
7142 (ior:DI (match_dup 1) (match_dup 2)))]
7143 "s390_match_ccmode(insn, CCTmode) && TARGET_ZARCH"
7144 "@
7145 ogr\t%0,%2
7146 ogrk\t%0,%1,%2
7147 og\t%0,%2"
7148 [(set_attr "op_type" "RRE,RRF,RXY")
7149 (set_attr "cpu_facility" "*,z196,*")
7150 (set_attr "z10prop" "z10_super_E1,*,z10_super_E1")])
7151
7152 (define_insn "*iordi3_cconly"
7153 [(set (reg CC_REGNUM)
7154 (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,d,0")
7155 (match_operand:DI 2 "general_operand" " d,d,RT"))
7156 (const_int 0)))
7157 (clobber (match_scratch:DI 0 "=d,d,d"))]
7158 "s390_match_ccmode(insn, CCTmode) && TARGET_ZARCH"
7159 "@
7160 ogr\t%0,%2
7161 ogrk\t%0,%1,%2
7162 og\t%0,%2"
7163 [(set_attr "op_type" "RRE,RRF,RXY")
7164 (set_attr "cpu_facility" "*,z196,*")
7165 (set_attr "z10prop" "z10_super_E1,*,z10_super_E1")])
7166
7167 (define_insn "*iordi3"
7168 [(set (match_operand:DI 0 "nonimmediate_operand"
7169 "=d, d, d, d, d, d,d,d, d, AQ,Q")
7170 (ior:DI (match_operand:DI 1 "nonimmediate_operand"
7171 " %0, 0, 0, 0, 0, 0,0,d, 0, 0,0")
7172 (match_operand:DI 2 "general_operand"
7173 "N0HD0,N1HD0,N2HD0,N3HD0,N0SD0,N1SD0,d,d,RT,NxQD0,Q")))
7174 (clobber (reg:CC CC_REGNUM))]
7175 "TARGET_ZARCH && s390_logical_operator_ok_p (operands)"
7176 "@
7177 oihh\t%0,%i2
7178 oihl\t%0,%i2
7179 oilh\t%0,%i2
7180 oill\t%0,%i2
7181 oihf\t%0,%k2
7182 oilf\t%0,%k2
7183 ogr\t%0,%2
7184 ogrk\t%0,%1,%2
7185 og\t%0,%2
7186 #
7187 #"
7188 [(set_attr "op_type" "RI,RI,RI,RI,RIL,RIL,RRE,RRF,RXY,SI,SS")
7189 (set_attr "cpu_facility" "*,*,*,*,extimm,extimm,*,z196,*,*,*")
7190 (set_attr "z10prop" "z10_super_E1,
7191 z10_super_E1,
7192 z10_super_E1,
7193 z10_super_E1,
7194 z10_super_E1,
7195 z10_super_E1,
7196 z10_super_E1,
7197 *,
7198 z10_super_E1,
7199 *,
7200 *")])
7201
7202 (define_split
7203 [(set (match_operand:DI 0 "s_operand" "")
7204 (ior:DI (match_dup 0) (match_operand:DI 1 "immediate_operand" "")))
7205 (clobber (reg:CC CC_REGNUM))]
7206 "reload_completed"
7207 [(parallel
7208 [(set (match_dup 0) (ior:QI (match_dup 0) (match_dup 1)))
7209 (clobber (reg:CC CC_REGNUM))])]
7210 "s390_narrow_logical_operator (IOR, &operands[0], &operands[1]);")
7211
7212 ;
7213 ; iorsi3 instruction pattern(s).
7214 ;
7215
7216 (define_insn "*iorsi3_cc"
7217 [(set (reg CC_REGNUM)
7218 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,d,0,0")
7219 (match_operand:SI 2 "general_operand" "Os,d,d,R,T"))
7220 (const_int 0)))
7221 (set (match_operand:SI 0 "register_operand" "=d,d,d,d,d")
7222 (ior:SI (match_dup 1) (match_dup 2)))]
7223 "s390_match_ccmode(insn, CCTmode)"
7224 "@
7225 oilf\t%0,%o2
7226 or\t%0,%2
7227 ork\t%0,%1,%2
7228 o\t%0,%2
7229 oy\t%0,%2"
7230 [(set_attr "op_type" "RIL,RR,RRF,RX,RXY")
7231 (set_attr "cpu_facility" "*,*,z196,*,*")
7232 (set_attr "z10prop" "z10_super_E1,z10_super_E1,*,z10_super_E1,z10_super_E1")])
7233
7234 (define_insn "*iorsi3_cconly"
7235 [(set (reg CC_REGNUM)
7236 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,d,0,0")
7237 (match_operand:SI 2 "general_operand" "Os,d,d,R,T"))
7238 (const_int 0)))
7239 (clobber (match_scratch:SI 0 "=d,d,d,d,d"))]
7240 "s390_match_ccmode(insn, CCTmode)"
7241 "@
7242 oilf\t%0,%o2
7243 or\t%0,%2
7244 ork\t%0,%1,%2
7245 o\t%0,%2
7246 oy\t%0,%2"
7247 [(set_attr "op_type" "RIL,RR,RRF,RX,RXY")
7248 (set_attr "cpu_facility" "*,*,z196,*,*")
7249 (set_attr "z10prop" "z10_super_E1,z10_super_E1,*,z10_super_E1,z10_super_E1")])
7250
7251 (define_insn "*iorsi3_zarch"
7252 [(set (match_operand:SI 0 "nonimmediate_operand" "=d, d, d,d,d,d,d, AQ,Q")
7253 (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0, 0, 0,0,d,0,0, 0,0")
7254 (match_operand:SI 2 "general_operand" "N0HS0,N1HS0,Os,d,d,R,T,NxQS0,Q")))
7255 (clobber (reg:CC CC_REGNUM))]
7256 "TARGET_ZARCH && s390_logical_operator_ok_p (operands)"
7257 "@
7258 oilh\t%0,%i2
7259 oill\t%0,%i2
7260 oilf\t%0,%o2
7261 or\t%0,%2
7262 ork\t%0,%1,%2
7263 o\t%0,%2
7264 oy\t%0,%2
7265 #
7266 #"
7267 [(set_attr "op_type" "RI,RI,RIL,RR,RRF,RX,RXY,SI,SS")
7268 (set_attr "cpu_facility" "*,*,*,*,z196,*,*,*,*")
7269 (set_attr "z10prop" "z10_super_E1,
7270 z10_super_E1,
7271 z10_super_E1,
7272 z10_super_E1,
7273 *,
7274 z10_super_E1,
7275 z10_super_E1,
7276 *,
7277 *")])
7278
7279 (define_insn "*iorsi3_esa"
7280 [(set (match_operand:SI 0 "nonimmediate_operand" "=d,d,AQ,Q")
7281 (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,0,0")
7282 (match_operand:SI 2 "general_operand" "d,R,NxQS0,Q")))
7283 (clobber (reg:CC CC_REGNUM))]
7284 "!TARGET_ZARCH && s390_logical_operator_ok_p (operands)"
7285 "@
7286 or\t%0,%2
7287 o\t%0,%2
7288 #
7289 #"
7290 [(set_attr "op_type" "RR,RX,SI,SS")
7291 (set_attr "z10prop" "z10_super_E1,z10_super_E1,*,*")])
7292
7293 (define_split
7294 [(set (match_operand:SI 0 "s_operand" "")
7295 (ior:SI (match_dup 0) (match_operand:SI 1 "immediate_operand" "")))
7296 (clobber (reg:CC CC_REGNUM))]
7297 "reload_completed"
7298 [(parallel
7299 [(set (match_dup 0) (ior:QI (match_dup 0) (match_dup 1)))
7300 (clobber (reg:CC CC_REGNUM))])]
7301 "s390_narrow_logical_operator (IOR, &operands[0], &operands[1]);")
7302
7303 ;
7304 ; iorhi3 instruction pattern(s).
7305 ;
7306
7307 (define_insn "*iorhi3_zarch"
7308 [(set (match_operand:HI 0 "nonimmediate_operand" "=d,d,d, AQ,Q")
7309 (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,d,0, 0,0")
7310 (match_operand:HI 2 "general_operand" " d,d,n,NxQH0,Q")))
7311 (clobber (reg:CC CC_REGNUM))]
7312 "TARGET_ZARCH && s390_logical_operator_ok_p (operands)"
7313 "@
7314 or\t%0,%2
7315 ork\t%0,%1,%2
7316 oill\t%0,%x2
7317 #
7318 #"
7319 [(set_attr "op_type" "RR,RRF,RI,SI,SS")
7320 (set_attr "cpu_facility" "*,z196,*,*,*")
7321 (set_attr "z10prop" "z10_super_E1,*,z10_super_E1,*,*")])
7322
7323 (define_insn "*iorhi3_esa"
7324 [(set (match_operand:HI 0 "nonimmediate_operand" "=d,AQ,Q")
7325 (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,0")
7326 (match_operand:HI 2 "general_operand" "d,NxQH0,Q")))
7327 (clobber (reg:CC CC_REGNUM))]
7328 "!TARGET_ZARCH && s390_logical_operator_ok_p (operands)"
7329 "@
7330 or\t%0,%2
7331 #
7332 #"
7333 [(set_attr "op_type" "RR,SI,SS")
7334 (set_attr "z10prop" "z10_super_E1,*,*")])
7335
7336 (define_split
7337 [(set (match_operand:HI 0 "s_operand" "")
7338 (ior:HI (match_dup 0) (match_operand:HI 1 "immediate_operand" "")))
7339 (clobber (reg:CC CC_REGNUM))]
7340 "reload_completed"
7341 [(parallel
7342 [(set (match_dup 0) (ior:QI (match_dup 0) (match_dup 1)))
7343 (clobber (reg:CC CC_REGNUM))])]
7344 "s390_narrow_logical_operator (IOR, &operands[0], &operands[1]);")
7345
7346 ;
7347 ; iorqi3 instruction pattern(s).
7348 ;
7349
7350 (define_insn "*iorqi3_zarch"
7351 [(set (match_operand:QI 0 "nonimmediate_operand" "=d,d,d,Q,S,Q")
7352 (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,d,0,0,0,0")
7353 (match_operand:QI 2 "general_operand" " d,d,n,n,n,Q")))
7354 (clobber (reg:CC CC_REGNUM))]
7355 "TARGET_ZARCH && s390_logical_operator_ok_p (operands)"
7356 "@
7357 or\t%0,%2
7358 ork\t%0,%1,%2
7359 oill\t%0,%b2
7360 oi\t%S0,%b2
7361 oiy\t%S0,%b2
7362 #"
7363 [(set_attr "op_type" "RR,RRF,RI,SI,SIY,SS")
7364 (set_attr "cpu_facility" "*,z196,*,*,*,*")
7365 (set_attr "z10prop" "z10_super_E1,*,z10_super_E1,
7366 z10_super,z10_super,*")])
7367
7368 (define_insn "*iorqi3_esa"
7369 [(set (match_operand:QI 0 "nonimmediate_operand" "=d,Q,Q")
7370 (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
7371 (match_operand:QI 2 "general_operand" "d,n,Q")))
7372 (clobber (reg:CC CC_REGNUM))]
7373 "!TARGET_ZARCH && s390_logical_operator_ok_p (operands)"
7374 "@
7375 or\t%0,%2
7376 oi\t%S0,%b2
7377 #"
7378 [(set_attr "op_type" "RR,SI,SS")
7379 (set_attr "z10prop" "z10_super_E1,z10_super,*")])
7380
7381 ;
7382 ; Block inclusive or (OC) patterns.
7383 ;
7384
7385 (define_insn "*oc"
7386 [(set (match_operand:BLK 0 "memory_operand" "=Q")
7387 (ior:BLK (match_dup 0)
7388 (match_operand:BLK 1 "memory_operand" "Q")))
7389 (use (match_operand 2 "const_int_operand" "n"))
7390 (clobber (reg:CC CC_REGNUM))]
7391 "INTVAL (operands[2]) >= 1 && INTVAL (operands[2]) <= 256"
7392 "oc\t%O0(%2,%R0),%S1"
7393 [(set_attr "op_type" "SS")
7394 (set_attr "z196prop" "z196_cracked")])
7395
7396 (define_split
7397 [(set (match_operand 0 "memory_operand" "")
7398 (ior (match_dup 0)
7399 (match_operand 1 "memory_operand" "")))
7400 (clobber (reg:CC CC_REGNUM))]
7401 "reload_completed
7402 && GET_MODE (operands[0]) == GET_MODE (operands[1])
7403 && GET_MODE_SIZE (GET_MODE (operands[0])) > 0"
7404 [(parallel
7405 [(set (match_dup 0) (ior:BLK (match_dup 0) (match_dup 1)))
7406 (use (match_dup 2))
7407 (clobber (reg:CC CC_REGNUM))])]
7408 {
7409 operands[2] = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[0])));
7410 operands[0] = adjust_address (operands[0], BLKmode, 0);
7411 operands[1] = adjust_address (operands[1], BLKmode, 0);
7412 })
7413
7414 (define_peephole2
7415 [(parallel
7416 [(set (match_operand:BLK 0 "memory_operand" "")
7417 (ior:BLK (match_dup 0)
7418 (match_operand:BLK 1 "memory_operand" "")))
7419 (use (match_operand 2 "const_int_operand" ""))
7420 (clobber (reg:CC CC_REGNUM))])
7421 (parallel
7422 [(set (match_operand:BLK 3 "memory_operand" "")
7423 (ior:BLK (match_dup 3)
7424 (match_operand:BLK 4 "memory_operand" "")))
7425 (use (match_operand 5 "const_int_operand" ""))
7426 (clobber (reg:CC CC_REGNUM))])]
7427 "s390_offset_p (operands[0], operands[3], operands[2])
7428 && s390_offset_p (operands[1], operands[4], operands[2])
7429 && !s390_overlap_p (operands[0], operands[1],
7430 INTVAL (operands[2]) + INTVAL (operands[5]))
7431 && INTVAL (operands[2]) + INTVAL (operands[5]) <= 256"
7432 [(parallel
7433 [(set (match_dup 6) (ior:BLK (match_dup 6) (match_dup 7)))
7434 (use (match_dup 8))
7435 (clobber (reg:CC CC_REGNUM))])]
7436 "operands[6] = gen_rtx_MEM (BLKmode, XEXP (operands[0], 0));
7437 operands[7] = gen_rtx_MEM (BLKmode, XEXP (operands[1], 0));
7438 operands[8] = GEN_INT (INTVAL (operands[2]) + INTVAL (operands[5]));")
7439
7440
7441 ;;
7442 ;;- Xor instructions.
7443 ;;
7444
7445 (define_expand "xor<mode>3"
7446 [(set (match_operand:INT 0 "nonimmediate_operand" "")
7447 (xor:INT (match_operand:INT 1 "nonimmediate_operand" "")
7448 (match_operand:INT 2 "general_operand" "")))
7449 (clobber (reg:CC CC_REGNUM))]
7450 ""
7451 "s390_expand_logical_operator (XOR, <MODE>mode, operands); DONE;")
7452
7453 ; Combine replaces (xor (x) (const_int -1)) with (not (x)) when doing
7454 ; simplifications. So its better to have something matching.
7455 (define_split
7456 [(set (match_operand:INT 0 "nonimmediate_operand" "")
7457 (not:INT (match_operand:INT 1 "nonimmediate_operand" "")))]
7458 ""
7459 [(parallel
7460 [(set (match_dup 0) (xor:INT (match_dup 1) (match_dup 2)))
7461 (clobber (reg:CC CC_REGNUM))])]
7462 {
7463 operands[2] = constm1_rtx;
7464 if (!s390_logical_operator_ok_p (operands))
7465 FAIL;
7466 })
7467
7468 ;
7469 ; xordi3 instruction pattern(s).
7470 ;
7471
7472 (define_insn "*xordi3_cc"
7473 [(set (reg CC_REGNUM)
7474 (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,d, 0")
7475 (match_operand:DI 2 "general_operand" " d,d,RT"))
7476 (const_int 0)))
7477 (set (match_operand:DI 0 "register_operand" "=d,d, d")
7478 (xor:DI (match_dup 1) (match_dup 2)))]
7479 "s390_match_ccmode(insn, CCTmode) && TARGET_ZARCH"
7480 "@
7481 xgr\t%0,%2
7482 xgrk\t%0,%1,%2
7483 xg\t%0,%2"
7484 [(set_attr "op_type" "RRE,RRF,RXY")
7485 (set_attr "cpu_facility" "*,z196,*")
7486 (set_attr "z10prop" "z10_super_E1,*,z10_super_E1")])
7487
7488 (define_insn "*xordi3_cconly"
7489 [(set (reg CC_REGNUM)
7490 (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,d, 0")
7491 (match_operand:DI 2 "general_operand" " d,d,RT"))
7492 (const_int 0)))
7493 (clobber (match_scratch:DI 0 "=d,d, d"))]
7494 "s390_match_ccmode(insn, CCTmode) && TARGET_ZARCH"
7495 "@
7496 xgr\t%0,%2
7497 xgrk\t%0,%1,%2
7498 xg\t%0,%2"
7499 [(set_attr "op_type" "RRE,RRF,RXY")
7500 (set_attr "cpu_facility" "*,z196,*")
7501 (set_attr "z10prop" "z10_super_E1,*,z10_super_E1")])
7502
7503 (define_insn "*xordi3"
7504 [(set (match_operand:DI 0 "nonimmediate_operand" "=d, d,d,d, d, AQ,Q")
7505 (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0, 0,0,d, 0, 0,0")
7506 (match_operand:DI 2 "general_operand" "N0SD0,N1SD0,d,d,RT,NxQD0,Q")))
7507 (clobber (reg:CC CC_REGNUM))]
7508 "TARGET_ZARCH && s390_logical_operator_ok_p (operands)"
7509 "@
7510 xihf\t%0,%k2
7511 xilf\t%0,%k2
7512 xgr\t%0,%2
7513 xgrk\t%0,%1,%2
7514 xg\t%0,%2
7515 #
7516 #"
7517 [(set_attr "op_type" "RIL,RIL,RRE,RRF,RXY,SI,SS")
7518 (set_attr "cpu_facility" "extimm,extimm,*,z196,*,*,*")
7519 (set_attr "z10prop" "z10_super_E1,z10_super_E1,z10_super_E1,
7520 *,z10_super_E1,*,*")])
7521
7522 (define_split
7523 [(set (match_operand:DI 0 "s_operand" "")
7524 (xor:DI (match_dup 0) (match_operand:DI 1 "immediate_operand" "")))
7525 (clobber (reg:CC CC_REGNUM))]
7526 "reload_completed"
7527 [(parallel
7528 [(set (match_dup 0) (xor:QI (match_dup 0) (match_dup 1)))
7529 (clobber (reg:CC CC_REGNUM))])]
7530 "s390_narrow_logical_operator (XOR, &operands[0], &operands[1]);")
7531
7532 ;
7533 ; xorsi3 instruction pattern(s).
7534 ;
7535
7536 (define_insn "*xorsi3_cc"
7537 [(set (reg CC_REGNUM)
7538 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,d,0,0")
7539 (match_operand:SI 2 "general_operand" "Os,d,d,R,T"))
7540 (const_int 0)))
7541 (set (match_operand:SI 0 "register_operand" "=d,d,d,d,d")
7542 (xor:SI (match_dup 1) (match_dup 2)))]
7543 "s390_match_ccmode(insn, CCTmode)"
7544 "@
7545 xilf\t%0,%o2
7546 xr\t%0,%2
7547 xrk\t%0,%1,%2
7548 x\t%0,%2
7549 xy\t%0,%2"
7550 [(set_attr "op_type" "RIL,RR,RRF,RX,RXY")
7551 (set_attr "cpu_facility" "*,*,z196,*,*")
7552 (set_attr "z10prop" "z10_super_E1,z10_super_E1,*,
7553 z10_super_E1,z10_super_E1")])
7554
7555 (define_insn "*xorsi3_cconly"
7556 [(set (reg CC_REGNUM)
7557 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,d,0,0")
7558 (match_operand:SI 2 "general_operand" "Os,d,d,R,T"))
7559 (const_int 0)))
7560 (clobber (match_scratch:SI 0 "=d,d,d,d,d"))]
7561 "s390_match_ccmode(insn, CCTmode)"
7562 "@
7563 xilf\t%0,%o2
7564 xr\t%0,%2
7565 xrk\t%0,%1,%2
7566 x\t%0,%2
7567 xy\t%0,%2"
7568 [(set_attr "op_type" "RIL,RR,RRF,RX,RXY")
7569 (set_attr "cpu_facility" "*,*,z196,*,*")
7570 (set_attr "z10prop" "z10_super_E1,z10_super_E1,*,
7571 z10_super_E1,z10_super_E1")])
7572
7573 (define_insn "*xorsi3"
7574 [(set (match_operand:SI 0 "nonimmediate_operand" "=d,d,d,d,d, AQ,Q")
7575 (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,d,0,0, 0,0")
7576 (match_operand:SI 2 "general_operand" "Os,d,d,R,T,NxQS0,Q")))
7577 (clobber (reg:CC CC_REGNUM))]
7578 "s390_logical_operator_ok_p (operands)"
7579 "@
7580 xilf\t%0,%o2
7581 xr\t%0,%2
7582 xrk\t%0,%1,%2
7583 x\t%0,%2
7584 xy\t%0,%2
7585 #
7586 #"
7587 [(set_attr "op_type" "RIL,RR,RRF,RX,RXY,SI,SS")
7588 (set_attr "cpu_facility" "*,*,z196,*,*,*,*")
7589 (set_attr "z10prop" "z10_super_E1,z10_super_E1,*,
7590 z10_super_E1,z10_super_E1,*,*")])
7591
7592 (define_split
7593 [(set (match_operand:SI 0 "s_operand" "")
7594 (xor:SI (match_dup 0) (match_operand:SI 1 "immediate_operand" "")))
7595 (clobber (reg:CC CC_REGNUM))]
7596 "reload_completed"
7597 [(parallel
7598 [(set (match_dup 0) (xor:QI (match_dup 0) (match_dup 1)))
7599 (clobber (reg:CC CC_REGNUM))])]
7600 "s390_narrow_logical_operator (XOR, &operands[0], &operands[1]);")
7601
7602 ;
7603 ; xorhi3 instruction pattern(s).
7604 ;
7605
7606 (define_insn "*xorhi3"
7607 [(set (match_operand:HI 0 "nonimmediate_operand" "=d,d,d, AQ,Q")
7608 (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,d, 0,0")
7609 (match_operand:HI 2 "general_operand" "Os,d,d,NxQH0,Q")))
7610 (clobber (reg:CC CC_REGNUM))]
7611 "s390_logical_operator_ok_p (operands)"
7612 "@
7613 xilf\t%0,%x2
7614 xr\t%0,%2
7615 xrk\t%0,%1,%2
7616 #
7617 #"
7618 [(set_attr "op_type" "RIL,RR,RRF,SI,SS")
7619 (set_attr "cpu_facility" "*,*,z196,*,*")
7620 (set_attr "z10prop" "z10_super_E1,z10_super_E1,*,*,*")])
7621
7622 (define_split
7623 [(set (match_operand:HI 0 "s_operand" "")
7624 (xor:HI (match_dup 0) (match_operand:HI 1 "immediate_operand" "")))
7625 (clobber (reg:CC CC_REGNUM))]
7626 "reload_completed"
7627 [(parallel
7628 [(set (match_dup 0) (xor:QI (match_dup 0) (match_dup 1)))
7629 (clobber (reg:CC CC_REGNUM))])]
7630 "s390_narrow_logical_operator (XOR, &operands[0], &operands[1]);")
7631
7632 ;
7633 ; xorqi3 instruction pattern(s).
7634 ;
7635
7636 (define_insn "*xorqi3"
7637 [(set (match_operand:QI 0 "nonimmediate_operand" "=d,d,d,Q,S,Q")
7638 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,d,0,0,0")
7639 (match_operand:QI 2 "general_operand" "Os,d,d,n,n,Q")))
7640 (clobber (reg:CC CC_REGNUM))]
7641 "s390_logical_operator_ok_p (operands)"
7642 "@
7643 xilf\t%0,%b2
7644 xr\t%0,%2
7645 xrk\t%0,%1,%2
7646 xi\t%S0,%b2
7647 xiy\t%S0,%b2
7648 #"
7649 [(set_attr "op_type" "RIL,RR,RRF,SI,SIY,SS")
7650 (set_attr "cpu_facility" "*,*,z196,*,*,*")
7651 (set_attr "z10prop" "z10_super_E1,z10_super_E1,*,z10_super,z10_super,*")])
7652
7653
7654 ;
7655 ; Block exclusive or (XC) patterns.
7656 ;
7657
7658 (define_insn "*xc"
7659 [(set (match_operand:BLK 0 "memory_operand" "=Q")
7660 (xor:BLK (match_dup 0)
7661 (match_operand:BLK 1 "memory_operand" "Q")))
7662 (use (match_operand 2 "const_int_operand" "n"))
7663 (clobber (reg:CC CC_REGNUM))]
7664 "INTVAL (operands[2]) >= 1 && INTVAL (operands[2]) <= 256"
7665 "xc\t%O0(%2,%R0),%S1"
7666 [(set_attr "op_type" "SS")])
7667
7668 (define_split
7669 [(set (match_operand 0 "memory_operand" "")
7670 (xor (match_dup 0)
7671 (match_operand 1 "memory_operand" "")))
7672 (clobber (reg:CC CC_REGNUM))]
7673 "reload_completed
7674 && GET_MODE (operands[0]) == GET_MODE (operands[1])
7675 && GET_MODE_SIZE (GET_MODE (operands[0])) > 0"
7676 [(parallel
7677 [(set (match_dup 0) (xor:BLK (match_dup 0) (match_dup 1)))
7678 (use (match_dup 2))
7679 (clobber (reg:CC CC_REGNUM))])]
7680 {
7681 operands[2] = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[0])));
7682 operands[0] = adjust_address (operands[0], BLKmode, 0);
7683 operands[1] = adjust_address (operands[1], BLKmode, 0);
7684 })
7685
7686 (define_peephole2
7687 [(parallel
7688 [(set (match_operand:BLK 0 "memory_operand" "")
7689 (xor:BLK (match_dup 0)
7690 (match_operand:BLK 1 "memory_operand" "")))
7691 (use (match_operand 2 "const_int_operand" ""))
7692 (clobber (reg:CC CC_REGNUM))])
7693 (parallel
7694 [(set (match_operand:BLK 3 "memory_operand" "")
7695 (xor:BLK (match_dup 3)
7696 (match_operand:BLK 4 "memory_operand" "")))
7697 (use (match_operand 5 "const_int_operand" ""))
7698 (clobber (reg:CC CC_REGNUM))])]
7699 "s390_offset_p (operands[0], operands[3], operands[2])
7700 && s390_offset_p (operands[1], operands[4], operands[2])
7701 && !s390_overlap_p (operands[0], operands[1],
7702 INTVAL (operands[2]) + INTVAL (operands[5]))
7703 && INTVAL (operands[2]) + INTVAL (operands[5]) <= 256"
7704 [(parallel
7705 [(set (match_dup 6) (xor:BLK (match_dup 6) (match_dup 7)))
7706 (use (match_dup 8))
7707 (clobber (reg:CC CC_REGNUM))])]
7708 "operands[6] = gen_rtx_MEM (BLKmode, XEXP (operands[0], 0));
7709 operands[7] = gen_rtx_MEM (BLKmode, XEXP (operands[1], 0));
7710 operands[8] = GEN_INT (INTVAL (operands[2]) + INTVAL (operands[5]));")
7711
7712 ;
7713 ; Block xor (XC) patterns with src == dest.
7714 ;
7715
7716 (define_insn "*xc_zero"
7717 [(set (match_operand:BLK 0 "memory_operand" "=Q")
7718 (const_int 0))
7719 (use (match_operand 1 "const_int_operand" "n"))
7720 (clobber (reg:CC CC_REGNUM))]
7721 "INTVAL (operands[1]) >= 1 && INTVAL (operands[1]) <= 256"
7722 "xc\t%O0(%1,%R0),%S0"
7723 [(set_attr "op_type" "SS")
7724 (set_attr "z196prop" "z196_cracked")])
7725
7726 (define_peephole2
7727 [(parallel
7728 [(set (match_operand:BLK 0 "memory_operand" "")
7729 (const_int 0))
7730 (use (match_operand 1 "const_int_operand" ""))
7731 (clobber (reg:CC CC_REGNUM))])
7732 (parallel
7733 [(set (match_operand:BLK 2 "memory_operand" "")
7734 (const_int 0))
7735 (use (match_operand 3 "const_int_operand" ""))
7736 (clobber (reg:CC CC_REGNUM))])]
7737 "s390_offset_p (operands[0], operands[2], operands[1])
7738 && INTVAL (operands[1]) + INTVAL (operands[3]) <= 256"
7739 [(parallel
7740 [(set (match_dup 4) (const_int 0))
7741 (use (match_dup 5))
7742 (clobber (reg:CC CC_REGNUM))])]
7743 "operands[4] = gen_rtx_MEM (BLKmode, XEXP (operands[0], 0));
7744 operands[5] = GEN_INT (INTVAL (operands[1]) + INTVAL (operands[3]));")
7745
7746
7747 ;;
7748 ;;- Negate instructions.
7749 ;;
7750
7751 ;
7752 ; neg(di|si)2 instruction pattern(s).
7753 ;
7754
7755 (define_expand "neg<mode>2"
7756 [(parallel
7757 [(set (match_operand:DSI 0 "register_operand" "=d")
7758 (neg:DSI (match_operand:DSI 1 "register_operand" "d")))
7759 (clobber (reg:CC CC_REGNUM))])]
7760 ""
7761 "")
7762
7763 (define_insn "*negdi2_sign_cc"
7764 [(set (reg CC_REGNUM)
7765 (compare (neg:DI (ashiftrt:DI (ashift:DI (subreg:DI
7766 (match_operand:SI 1 "register_operand" "d") 0)
7767 (const_int 32)) (const_int 32)))
7768 (const_int 0)))
7769 (set (match_operand:DI 0 "register_operand" "=d")
7770 (neg:DI (sign_extend:DI (match_dup 1))))]
7771 "TARGET_ZARCH && s390_match_ccmode (insn, CCAmode)"
7772 "lcgfr\t%0,%1"
7773 [(set_attr "op_type" "RRE")
7774 (set_attr "z10prop" "z10_c")])
7775
7776 (define_insn "*negdi2_sign"
7777 [(set (match_operand:DI 0 "register_operand" "=d")
7778 (neg:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "d"))))
7779 (clobber (reg:CC CC_REGNUM))]
7780 "TARGET_ZARCH"
7781 "lcgfr\t%0,%1"
7782 [(set_attr "op_type" "RRE")
7783 (set_attr "z10prop" "z10_c")])
7784
7785 ; lcr, lcgr
7786 (define_insn "*neg<mode>2_cc"
7787 [(set (reg CC_REGNUM)
7788 (compare (neg:GPR (match_operand:GPR 1 "register_operand" "d"))
7789 (const_int 0)))
7790 (set (match_operand:GPR 0 "register_operand" "=d")
7791 (neg:GPR (match_dup 1)))]
7792 "s390_match_ccmode (insn, CCAmode)"
7793 "lc<g>r\t%0,%1"
7794 [(set_attr "op_type" "RR<E>")
7795 (set_attr "z10prop" "z10_super_c_E1")])
7796
7797 ; lcr, lcgr
7798 (define_insn "*neg<mode>2_cconly"
7799 [(set (reg CC_REGNUM)
7800 (compare (neg:GPR (match_operand:GPR 1 "register_operand" "d"))
7801 (const_int 0)))
7802 (clobber (match_scratch:GPR 0 "=d"))]
7803 "s390_match_ccmode (insn, CCAmode)"
7804 "lc<g>r\t%0,%1"
7805 [(set_attr "op_type" "RR<E>")
7806 (set_attr "z10prop" "z10_super_c_E1")])
7807
7808 ; lcr, lcgr
7809 (define_insn "*neg<mode>2"
7810 [(set (match_operand:GPR 0 "register_operand" "=d")
7811 (neg:GPR (match_operand:GPR 1 "register_operand" "d")))
7812 (clobber (reg:CC CC_REGNUM))]
7813 ""
7814 "lc<g>r\t%0,%1"
7815 [(set_attr "op_type" "RR<E>")
7816 (set_attr "z10prop" "z10_super_c_E1")])
7817
7818 (define_insn "*negdi2_31"
7819 [(set (match_operand:DI 0 "register_operand" "=d")
7820 (neg:DI (match_operand:DI 1 "register_operand" "d")))
7821 (clobber (reg:CC CC_REGNUM))]
7822 "!TARGET_ZARCH"
7823 "#")
7824
7825 ; Split a DImode NEG on 31bit into 2 SImode NEGs
7826
7827 ; Doing the twos complement separately on the SImode parts does an
7828 ; unwanted +1 on the high part which needs to be subtracted afterwards
7829 ; ... unless the +1 on the low part created an overflow.
7830
7831 (define_split
7832 [(set (match_operand:DI 0 "register_operand" "")
7833 (neg:DI (match_operand:DI 1 "register_operand" "")))
7834 (clobber (reg:CC CC_REGNUM))]
7835 "!TARGET_ZARCH
7836 && (REGNO (operands[0]) == REGNO (operands[1])
7837 || s390_split_ok_p (operands[0], operands[1], DImode, 0))
7838 && reload_completed"
7839 [(parallel
7840 [(set (match_dup 2) (neg:SI (match_dup 3)))
7841 (clobber (reg:CC CC_REGNUM))])
7842 (parallel
7843 [(set (reg:CCAP CC_REGNUM)
7844 (compare:CCAP (neg:SI (match_dup 5)) (const_int 0)))
7845 (set (match_dup 4) (neg:SI (match_dup 5)))])
7846 (set (pc)
7847 (if_then_else (ne (reg:CCAP CC_REGNUM) (const_int 0))
7848 (pc)
7849 (label_ref (match_dup 6))))
7850 (parallel
7851 [(set (match_dup 2) (plus:SI (match_dup 2) (const_int -1)))
7852 (clobber (reg:CC CC_REGNUM))])
7853 (match_dup 6)]
7854 "operands[2] = operand_subword (operands[0], 0, 0, DImode);
7855 operands[3] = operand_subword (operands[1], 0, 0, DImode);
7856 operands[4] = operand_subword (operands[0], 1, 0, DImode);
7857 operands[5] = operand_subword (operands[1], 1, 0, DImode);
7858 operands[6] = gen_label_rtx ();")
7859
7860 ; Like above but first make a copy of the low part of the src operand
7861 ; since it might overlap with the high part of the destination.
7862
7863 (define_split
7864 [(set (match_operand:DI 0 "register_operand" "")
7865 (neg:DI (match_operand:DI 1 "register_operand" "")))
7866 (clobber (reg:CC CC_REGNUM))]
7867 "!TARGET_ZARCH
7868 && s390_split_ok_p (operands[0], operands[1], DImode, 1)
7869 && reload_completed"
7870 [; Make a backup of op5 first
7871 (set (match_dup 4) (match_dup 5))
7872 ; Setting op2 here might clobber op5
7873 (parallel
7874 [(set (match_dup 2) (neg:SI (match_dup 3)))
7875 (clobber (reg:CC CC_REGNUM))])
7876 (parallel
7877 [(set (reg:CCAP CC_REGNUM)
7878 (compare:CCAP (neg:SI (match_dup 4)) (const_int 0)))
7879 (set (match_dup 4) (neg:SI (match_dup 4)))])
7880 (set (pc)
7881 (if_then_else (ne (reg:CCAP CC_REGNUM) (const_int 0))
7882 (pc)
7883 (label_ref (match_dup 6))))
7884 (parallel
7885 [(set (match_dup 2) (plus:SI (match_dup 2) (const_int -1)))
7886 (clobber (reg:CC CC_REGNUM))])
7887 (match_dup 6)]
7888 "operands[2] = operand_subword (operands[0], 0, 0, DImode);
7889 operands[3] = operand_subword (operands[1], 0, 0, DImode);
7890 operands[4] = operand_subword (operands[0], 1, 0, DImode);
7891 operands[5] = operand_subword (operands[1], 1, 0, DImode);
7892 operands[6] = gen_label_rtx ();")
7893
7894 ;
7895 ; neg(df|sf)2 instruction pattern(s).
7896 ;
7897
7898 (define_expand "neg<mode>2"
7899 [(parallel
7900 [(set (match_operand:BFP 0 "register_operand" "=f")
7901 (neg:BFP (match_operand:BFP 1 "register_operand" "f")))
7902 (clobber (reg:CC CC_REGNUM))])]
7903 "TARGET_HARD_FLOAT"
7904 "")
7905
7906 ; lcxbr, lcdbr, lcebr
7907 (define_insn "*neg<mode>2_cc"
7908 [(set (reg CC_REGNUM)
7909 (compare (neg:BFP (match_operand:BFP 1 "register_operand" "f"))
7910 (match_operand:BFP 2 "const0_operand" "")))
7911 (set (match_operand:BFP 0 "register_operand" "=f")
7912 (neg:BFP (match_dup 1)))]
7913 "s390_match_ccmode (insn, CCSmode) && TARGET_HARD_FLOAT"
7914 "lc<xde>br\t%0,%1"
7915 [(set_attr "op_type" "RRE")
7916 (set_attr "type" "fsimp<mode>")])
7917
7918 ; lcxbr, lcdbr, lcebr
7919 (define_insn "*neg<mode>2_cconly"
7920 [(set (reg CC_REGNUM)
7921 (compare (neg:BFP (match_operand:BFP 1 "register_operand" "f"))
7922 (match_operand:BFP 2 "const0_operand" "")))
7923 (clobber (match_scratch:BFP 0 "=f"))]
7924 "s390_match_ccmode (insn, CCSmode) && TARGET_HARD_FLOAT"
7925 "lc<xde>br\t%0,%1"
7926 [(set_attr "op_type" "RRE")
7927 (set_attr "type" "fsimp<mode>")])
7928
7929 ; lcdfr
7930 (define_insn "*neg<mode>2_nocc"
7931 [(set (match_operand:FP 0 "register_operand" "=f")
7932 (neg:FP (match_operand:FP 1 "register_operand" "<fT0>")))]
7933 "TARGET_DFP"
7934 "lcdfr\t%0,%1"
7935 [(set_attr "op_type" "RRE")
7936 (set_attr "type" "fsimp<mode>")])
7937
7938 ; lcxbr, lcdbr, lcebr
7939 ; FIXME: wflcdb does not clobber cc
7940 (define_insn "*neg<mode>2"
7941 [(set (match_operand:BFP 0 "register_operand" "=f,<vf>")
7942 (neg:BFP (match_operand:BFP 1 "register_operand" "f,<vf>")))
7943 (clobber (reg:CC CC_REGNUM))]
7944 "TARGET_HARD_FLOAT"
7945 "@
7946 lc<xde>br\t%0,%1
7947 wflcdb\t%0,%1"
7948 [(set_attr "op_type" "RRE,VRR")
7949 (set_attr "cpu_facility" "*,vec")
7950 (set_attr "type" "fsimp<mode>,*")])
7951
7952
7953 ;;
7954 ;;- Absolute value instructions.
7955 ;;
7956
7957 ;
7958 ; abs(di|si)2 instruction pattern(s).
7959 ;
7960
7961 (define_insn "*absdi2_sign_cc"
7962 [(set (reg CC_REGNUM)
7963 (compare (abs:DI (ashiftrt:DI (ashift:DI (subreg:DI
7964 (match_operand:SI 1 "register_operand" "d") 0)
7965 (const_int 32)) (const_int 32)))
7966 (const_int 0)))
7967 (set (match_operand:DI 0 "register_operand" "=d")
7968 (abs:DI (sign_extend:DI (match_dup 1))))]
7969 "TARGET_ZARCH && s390_match_ccmode (insn, CCAmode)"
7970 "lpgfr\t%0,%1"
7971 [(set_attr "op_type" "RRE")
7972 (set_attr "z10prop" "z10_c")])
7973
7974 (define_insn "*absdi2_sign"
7975 [(set (match_operand:DI 0 "register_operand" "=d")
7976 (abs:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "d"))))
7977 (clobber (reg:CC CC_REGNUM))]
7978 "TARGET_ZARCH"
7979 "lpgfr\t%0,%1"
7980 [(set_attr "op_type" "RRE")
7981 (set_attr "z10prop" "z10_c")])
7982
7983 ; lpr, lpgr
7984 (define_insn "*abs<mode>2_cc"
7985 [(set (reg CC_REGNUM)
7986 (compare (abs:GPR (match_operand:DI 1 "register_operand" "d"))
7987 (const_int 0)))
7988 (set (match_operand:GPR 0 "register_operand" "=d")
7989 (abs:GPR (match_dup 1)))]
7990 "s390_match_ccmode (insn, CCAmode)"
7991 "lp<g>r\t%0,%1"
7992 [(set_attr "op_type" "RR<E>")
7993 (set_attr "z10prop" "z10_c")])
7994
7995 ; lpr, lpgr
7996 (define_insn "*abs<mode>2_cconly"
7997 [(set (reg CC_REGNUM)
7998 (compare (abs:GPR (match_operand:GPR 1 "register_operand" "d"))
7999 (const_int 0)))
8000 (clobber (match_scratch:GPR 0 "=d"))]
8001 "s390_match_ccmode (insn, CCAmode)"
8002 "lp<g>r\t%0,%1"
8003 [(set_attr "op_type" "RR<E>")
8004 (set_attr "z10prop" "z10_c")])
8005
8006 ; lpr, lpgr
8007 (define_insn "abs<mode>2"
8008 [(set (match_operand:GPR 0 "register_operand" "=d")
8009 (abs:GPR (match_operand:GPR 1 "register_operand" "d")))
8010 (clobber (reg:CC CC_REGNUM))]
8011 ""
8012 "lp<g>r\t%0,%1"
8013 [(set_attr "op_type" "RR<E>")
8014 (set_attr "z10prop" "z10_c")])
8015
8016 ;
8017 ; abs(df|sf)2 instruction pattern(s).
8018 ;
8019
8020 (define_expand "abs<mode>2"
8021 [(parallel
8022 [(set (match_operand:BFP 0 "register_operand" "=f")
8023 (abs:BFP (match_operand:BFP 1 "register_operand" "f")))
8024 (clobber (reg:CC CC_REGNUM))])]
8025 "TARGET_HARD_FLOAT"
8026 "")
8027
8028 ; lpxbr, lpdbr, lpebr
8029 (define_insn "*abs<mode>2_cc"
8030 [(set (reg CC_REGNUM)
8031 (compare (abs:BFP (match_operand:BFP 1 "register_operand" "f"))
8032 (match_operand:BFP 2 "const0_operand" "")))
8033 (set (match_operand:BFP 0 "register_operand" "=f")
8034 (abs:BFP (match_dup 1)))]
8035 "s390_match_ccmode (insn, CCSmode) && TARGET_HARD_FLOAT"
8036 "lp<xde>br\t%0,%1"
8037 [(set_attr "op_type" "RRE")
8038 (set_attr "type" "fsimp<mode>")])
8039
8040 ; lpxbr, lpdbr, lpebr
8041 (define_insn "*abs<mode>2_cconly"
8042 [(set (reg CC_REGNUM)
8043 (compare (abs:BFP (match_operand:BFP 1 "register_operand" "f"))
8044 (match_operand:BFP 2 "const0_operand" "")))
8045 (clobber (match_scratch:BFP 0 "=f"))]
8046 "s390_match_ccmode (insn, CCSmode) && TARGET_HARD_FLOAT"
8047 "lp<xde>br\t%0,%1"
8048 [(set_attr "op_type" "RRE")
8049 (set_attr "type" "fsimp<mode>")])
8050
8051 ; lpdfr
8052 (define_insn "*abs<mode>2_nocc"
8053 [(set (match_operand:FP 0 "register_operand" "=f")
8054 (abs:FP (match_operand:FP 1 "register_operand" "<fT0>")))]
8055 "TARGET_DFP"
8056 "lpdfr\t%0,%1"
8057 [(set_attr "op_type" "RRE")
8058 (set_attr "type" "fsimp<mode>")])
8059
8060 ; lpxbr, lpdbr, lpebr
8061 ; FIXME: wflpdb does not clobber cc
8062 (define_insn "*abs<mode>2"
8063 [(set (match_operand:BFP 0 "register_operand" "=f,<vf>")
8064 (abs:BFP (match_operand:BFP 1 "register_operand" "f,<vf>")))
8065 (clobber (reg:CC CC_REGNUM))]
8066 "TARGET_HARD_FLOAT"
8067 "@
8068 lp<xde>br\t%0,%1
8069 wflpdb\t%0,%1"
8070 [(set_attr "op_type" "RRE,VRR")
8071 (set_attr "cpu_facility" "*,vec")
8072 (set_attr "type" "fsimp<mode>,*")])
8073
8074
8075 ;;
8076 ;;- Negated absolute value instructions
8077 ;;
8078
8079 ;
8080 ; Integer
8081 ;
8082
8083 (define_insn "*negabsdi2_sign_cc"
8084 [(set (reg CC_REGNUM)
8085 (compare (neg:DI (abs:DI (ashiftrt:DI (ashift:DI (subreg:DI
8086 (match_operand:SI 1 "register_operand" "d") 0)
8087 (const_int 32)) (const_int 32))))
8088 (const_int 0)))
8089 (set (match_operand:DI 0 "register_operand" "=d")
8090 (neg:DI (abs:DI (sign_extend:DI (match_dup 1)))))]
8091 "TARGET_ZARCH && s390_match_ccmode (insn, CCAmode)"
8092 "lngfr\t%0,%1"
8093 [(set_attr "op_type" "RRE")
8094 (set_attr "z10prop" "z10_c")])
8095
8096 (define_insn "*negabsdi2_sign"
8097 [(set (match_operand:DI 0 "register_operand" "=d")
8098 (neg:DI (abs:DI (sign_extend:DI
8099 (match_operand:SI 1 "register_operand" "d")))))
8100 (clobber (reg:CC CC_REGNUM))]
8101 "TARGET_ZARCH"
8102 "lngfr\t%0,%1"
8103 [(set_attr "op_type" "RRE")
8104 (set_attr "z10prop" "z10_c")])
8105
8106 ; lnr, lngr
8107 (define_insn "*negabs<mode>2_cc"
8108 [(set (reg CC_REGNUM)
8109 (compare (neg:GPR (abs:GPR (match_operand:GPR 1 "register_operand" "d")))
8110 (const_int 0)))
8111 (set (match_operand:GPR 0 "register_operand" "=d")
8112 (neg:GPR (abs:GPR (match_dup 1))))]
8113 "s390_match_ccmode (insn, CCAmode)"
8114 "ln<g>r\t%0,%1"
8115 [(set_attr "op_type" "RR<E>")
8116 (set_attr "z10prop" "z10_c")])
8117
8118 ; lnr, lngr
8119 (define_insn "*negabs<mode>2_cconly"
8120 [(set (reg CC_REGNUM)
8121 (compare (neg:GPR (abs:GPR (match_operand:GPR 1 "register_operand" "d")))
8122 (const_int 0)))
8123 (clobber (match_scratch:GPR 0 "=d"))]
8124 "s390_match_ccmode (insn, CCAmode)"
8125 "ln<g>r\t%0,%1"
8126 [(set_attr "op_type" "RR<E>")
8127 (set_attr "z10prop" "z10_c")])
8128
8129 ; lnr, lngr
8130 (define_insn "*negabs<mode>2"
8131 [(set (match_operand:GPR 0 "register_operand" "=d")
8132 (neg:GPR (abs:GPR (match_operand:GPR 1 "register_operand" "d"))))
8133 (clobber (reg:CC CC_REGNUM))]
8134 ""
8135 "ln<g>r\t%0,%1"
8136 [(set_attr "op_type" "RR<E>")
8137 (set_attr "z10prop" "z10_c")])
8138
8139 ;
8140 ; Floating point
8141 ;
8142
8143 ; lnxbr, lndbr, lnebr
8144 (define_insn "*negabs<mode>2_cc"
8145 [(set (reg CC_REGNUM)
8146 (compare (neg:BFP (abs:BFP (match_operand:BFP 1 "register_operand" "f")))
8147 (match_operand:BFP 2 "const0_operand" "")))
8148 (set (match_operand:BFP 0 "register_operand" "=f")
8149 (neg:BFP (abs:BFP (match_dup 1))))]
8150 "s390_match_ccmode (insn, CCSmode) && TARGET_HARD_FLOAT"
8151 "ln<xde>br\t%0,%1"
8152 [(set_attr "op_type" "RRE")
8153 (set_attr "type" "fsimp<mode>")])
8154
8155 ; lnxbr, lndbr, lnebr
8156 (define_insn "*negabs<mode>2_cconly"
8157 [(set (reg CC_REGNUM)
8158 (compare (neg:BFP (abs:BFP (match_operand:BFP 1 "register_operand" "f")))
8159 (match_operand:BFP 2 "const0_operand" "")))
8160 (clobber (match_scratch:BFP 0 "=f"))]
8161 "s390_match_ccmode (insn, CCSmode) && TARGET_HARD_FLOAT"
8162 "ln<xde>br\t%0,%1"
8163 [(set_attr "op_type" "RRE")
8164 (set_attr "type" "fsimp<mode>")])
8165
8166 ; lndfr
8167 (define_insn "*negabs<mode>2_nocc"
8168 [(set (match_operand:FP 0 "register_operand" "=f")
8169 (neg:FP (abs:FP (match_operand:BFP 1 "register_operand" "<fT0>"))))]
8170 "TARGET_DFP"
8171 "lndfr\t%0,%1"
8172 [(set_attr "op_type" "RRE")
8173 (set_attr "type" "fsimp<mode>")])
8174
8175 ; lnxbr, lndbr, lnebr
8176 ; FIXME: wflndb does not clobber cc
8177 (define_insn "*negabs<mode>2"
8178 [(set (match_operand:BFP 0 "register_operand" "=f,<vf>")
8179 (neg:BFP (abs:BFP (match_operand:BFP 1 "register_operand" "f,<vf>"))))
8180 (clobber (reg:CC CC_REGNUM))]
8181 "TARGET_HARD_FLOAT"
8182 "@
8183 ln<xde>br\t%0,%1
8184 wflndb\t%0,%1"
8185 [(set_attr "op_type" "RRE,VRR")
8186 (set_attr "cpu_facility" "*,vec")
8187 (set_attr "type" "fsimp<mode>,*")])
8188
8189 ;;
8190 ;;- Square root instructions.
8191 ;;
8192
8193 ;
8194 ; sqrt(df|sf)2 instruction pattern(s).
8195 ;
8196
8197 ; sqxbr, sqdbr, sqebr, sqdb, sqeb
8198 (define_insn "sqrt<mode>2"
8199 [(set (match_operand:BFP 0 "register_operand" "=f, f,<vf>")
8200 (sqrt:BFP (match_operand:BFP 1 "general_operand" "f,<Rf>,<vf>")))]
8201 "TARGET_HARD_FLOAT"
8202 "@
8203 sq<xde>br\t%0,%1
8204 sq<xde>b\t%0,%1
8205 wfsqdb\t%v0,%v1"
8206 [(set_attr "op_type" "RRE,RXE,VRR")
8207 (set_attr "type" "fsqrt<mode>")
8208 (set_attr "cpu_facility" "*,*,vec")])
8209
8210
8211 ;;
8212 ;;- One complement instructions.
8213 ;;
8214
8215 ;
8216 ; one_cmpl(di|si|hi|qi)2 instruction pattern(s).
8217 ;
8218
8219 (define_expand "one_cmpl<mode>2"
8220 [(parallel
8221 [(set (match_operand:INT 0 "register_operand" "")
8222 (xor:INT (match_operand:INT 1 "register_operand" "")
8223 (const_int -1)))
8224 (clobber (reg:CC CC_REGNUM))])]
8225 ""
8226 "")
8227
8228
8229 ;;
8230 ;; Find leftmost bit instructions.
8231 ;;
8232
8233 (define_expand "clzdi2"
8234 [(set (match_operand:DI 0 "register_operand" "=d")
8235 (clz:DI (match_operand:DI 1 "register_operand" "d")))]
8236 "TARGET_EXTIMM && TARGET_ZARCH"
8237 {
8238 rtx insn, clz_equal;
8239 rtx wide_reg = gen_reg_rtx (TImode);
8240 rtx msb = gen_rtx_CONST_INT (DImode, (unsigned HOST_WIDE_INT) 1 << 63);
8241
8242 clz_equal = gen_rtx_CLZ (DImode, operands[1]);
8243
8244 emit_insn (gen_clztidi2 (wide_reg, operands[1], msb));
8245
8246 insn = emit_move_insn (operands[0], gen_highpart (DImode, wide_reg));
8247 set_unique_reg_note (insn, REG_EQUAL, clz_equal);
8248
8249 DONE;
8250 })
8251
8252 (define_insn "clztidi2"
8253 [(set (match_operand:TI 0 "register_operand" "=d")
8254 (ior:TI
8255 (ashift:TI
8256 (zero_extend:TI
8257 (xor:DI (match_operand:DI 1 "register_operand" "d")
8258 (lshiftrt (match_operand:DI 2 "const_int_operand" "")
8259 (subreg:SI (clz:DI (match_dup 1)) 4))))
8260
8261 (const_int 64))
8262 (zero_extend:TI (clz:DI (match_dup 1)))))
8263 (clobber (reg:CC CC_REGNUM))]
8264 "(unsigned HOST_WIDE_INT) INTVAL (operands[2])
8265 == (unsigned HOST_WIDE_INT) 1 << 63
8266 && TARGET_EXTIMM && TARGET_ZARCH"
8267 "flogr\t%0,%1"
8268 [(set_attr "op_type" "RRE")])
8269
8270
8271 ;;
8272 ;;- Rotate instructions.
8273 ;;
8274
8275 ;
8276 ; rotl(di|si)3 instruction pattern(s).
8277 ;
8278
8279 ; rll, rllg
8280 (define_insn "rotl<mode>3"
8281 [(set (match_operand:GPR 0 "register_operand" "=d")
8282 (rotate:GPR (match_operand:GPR 1 "register_operand" "d")
8283 (match_operand:SI 2 "shift_count_or_setmem_operand" "Y")))]
8284 "TARGET_CPU_ZARCH"
8285 "rll<g>\t%0,%1,%Y2"
8286 [(set_attr "op_type" "RSE")
8287 (set_attr "atype" "reg")
8288 (set_attr "z10prop" "z10_super_E1")])
8289
8290 ; rll, rllg
8291 (define_insn "*rotl<mode>3_and"
8292 [(set (match_operand:GPR 0 "register_operand" "=d")
8293 (rotate:GPR (match_operand:GPR 1 "register_operand" "d")
8294 (and:SI (match_operand:SI 2 "shift_count_or_setmem_operand" "Y")
8295 (match_operand:SI 3 "const_int_operand" "n"))))]
8296 "TARGET_CPU_ZARCH && (INTVAL (operands[3]) & 63) == 63"
8297 "rll<g>\t%0,%1,%Y2"
8298 [(set_attr "op_type" "RSE")
8299 (set_attr "atype" "reg")
8300 (set_attr "z10prop" "z10_super_E1")])
8301
8302
8303 ;;
8304 ;;- Shift instructions.
8305 ;;
8306
8307 ;
8308 ; (ashl|lshr)(di|si)3 instruction pattern(s).
8309 ; Left shifts and logical right shifts
8310
8311 (define_expand "<shift><mode>3"
8312 [(set (match_operand:DSI 0 "register_operand" "")
8313 (SHIFT:DSI (match_operand:DSI 1 "register_operand" "")
8314 (match_operand:SI 2 "shift_count_or_setmem_operand" "")))]
8315 ""
8316 "")
8317
8318 ; sldl, srdl
8319 (define_insn "*<shift>di3_31"
8320 [(set (match_operand:DI 0 "register_operand" "=d")
8321 (SHIFT:DI (match_operand:DI 1 "register_operand" "0")
8322 (match_operand:SI 2 "shift_count_or_setmem_operand" "Y")))]
8323 "!TARGET_ZARCH"
8324 "s<lr>dl\t%0,%Y2"
8325 [(set_attr "op_type" "RS")
8326 (set_attr "atype" "reg")
8327 (set_attr "z196prop" "z196_cracked")])
8328
8329 ; sll, srl, sllg, srlg, sllk, srlk
8330 (define_insn "*<shift><mode>3"
8331 [(set (match_operand:GPR 0 "register_operand" "=d,d")
8332 (SHIFT:GPR (match_operand:GPR 1 "register_operand" "<d0>,d")
8333 (match_operand:SI 2 "shift_count_or_setmem_operand" "Y,Y")))]
8334 ""
8335 "@
8336 s<lr>l<g>\t%0,<1>%Y2
8337 s<lr>l<gk>\t%0,%1,%Y2"
8338 [(set_attr "op_type" "RS<E>,RSY")
8339 (set_attr "atype" "reg,reg")
8340 (set_attr "cpu_facility" "*,z196")
8341 (set_attr "z10prop" "z10_super_E1,*")])
8342
8343 ; sldl, srdl
8344 (define_insn "*<shift>di3_31_and"
8345 [(set (match_operand:DI 0 "register_operand" "=d")
8346 (SHIFT:DI (match_operand:DI 1 "register_operand" "0")
8347 (and:SI (match_operand:SI 2 "shift_count_or_setmem_operand" "Y")
8348 (match_operand:SI 3 "const_int_operand" "n"))))]
8349 "!TARGET_ZARCH && (INTVAL (operands[3]) & 63) == 63"
8350 "s<lr>dl\t%0,%Y2"
8351 [(set_attr "op_type" "RS")
8352 (set_attr "atype" "reg")])
8353
8354 ; sll, srl, sllg, srlg, sllk, srlk
8355 (define_insn "*<shift><mode>3_and"
8356 [(set (match_operand:GPR 0 "register_operand" "=d,d")
8357 (SHIFT:GPR (match_operand:GPR 1 "register_operand" "<d0>,d")
8358 (and:SI (match_operand:SI 2 "shift_count_or_setmem_operand" "Y,Y")
8359 (match_operand:SI 3 "const_int_operand" "n,n"))))]
8360 "(INTVAL (operands[3]) & 63) == 63"
8361 "@
8362 s<lr>l<g>\t%0,<1>%Y2
8363 s<lr>l<gk>\t%0,%1,%Y2"
8364 [(set_attr "op_type" "RS<E>,RSY")
8365 (set_attr "atype" "reg,reg")
8366 (set_attr "cpu_facility" "*,z196")
8367 (set_attr "z10prop" "z10_super_E1,*")])
8368
8369 ;
8370 ; ashr(di|si)3 instruction pattern(s).
8371 ; Arithmetic right shifts
8372
8373 (define_expand "ashr<mode>3"
8374 [(parallel
8375 [(set (match_operand:DSI 0 "register_operand" "")
8376 (ashiftrt:DSI (match_operand:DSI 1 "register_operand" "")
8377 (match_operand:SI 2 "shift_count_or_setmem_operand" "")))
8378 (clobber (reg:CC CC_REGNUM))])]
8379 ""
8380 "")
8381
8382 (define_insn "*ashrdi3_cc_31"
8383 [(set (reg CC_REGNUM)
8384 (compare (ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
8385 (match_operand:SI 2 "shift_count_or_setmem_operand" "Y"))
8386 (const_int 0)))
8387 (set (match_operand:DI 0 "register_operand" "=d")
8388 (ashiftrt:DI (match_dup 1) (match_dup 2)))]
8389 "!TARGET_ZARCH && s390_match_ccmode(insn, CCSmode)"
8390 "srda\t%0,%Y2"
8391 [(set_attr "op_type" "RS")
8392 (set_attr "atype" "reg")])
8393
8394 (define_insn "*ashrdi3_cconly_31"
8395 [(set (reg CC_REGNUM)
8396 (compare (ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
8397 (match_operand:SI 2 "shift_count_or_setmem_operand" "Y"))
8398 (const_int 0)))
8399 (clobber (match_scratch:DI 0 "=d"))]
8400 "!TARGET_ZARCH && s390_match_ccmode(insn, CCSmode)"
8401 "srda\t%0,%Y2"
8402 [(set_attr "op_type" "RS")
8403 (set_attr "atype" "reg")])
8404
8405 (define_insn "*ashrdi3_31"
8406 [(set (match_operand:DI 0 "register_operand" "=d")
8407 (ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
8408 (match_operand:SI 2 "shift_count_or_setmem_operand" "Y")))
8409 (clobber (reg:CC CC_REGNUM))]
8410 "!TARGET_ZARCH"
8411 "srda\t%0,%Y2"
8412 [(set_attr "op_type" "RS")
8413 (set_attr "atype" "reg")])
8414
8415 ; sra, srag, srak
8416 (define_insn "*ashr<mode>3_cc"
8417 [(set (reg CC_REGNUM)
8418 (compare (ashiftrt:GPR (match_operand:GPR 1 "register_operand" "<d0>,d")
8419 (match_operand:SI 2 "shift_count_or_setmem_operand" "Y,Y"))
8420 (const_int 0)))
8421 (set (match_operand:GPR 0 "register_operand" "=d,d")
8422 (ashiftrt:GPR (match_dup 1) (match_dup 2)))]
8423 "s390_match_ccmode(insn, CCSmode)"
8424 "@
8425 sra<g>\t%0,<1>%Y2
8426 sra<gk>\t%0,%1,%Y2"
8427 [(set_attr "op_type" "RS<E>,RSY")
8428 (set_attr "atype" "reg,reg")
8429 (set_attr "cpu_facility" "*,z196")
8430 (set_attr "z10prop" "z10_super_E1,*")])
8431
8432 ; sra, srag, srak
8433 (define_insn "*ashr<mode>3_cconly"
8434 [(set (reg CC_REGNUM)
8435 (compare (ashiftrt:GPR (match_operand:GPR 1 "register_operand" "<d0>,d")
8436 (match_operand:SI 2 "shift_count_or_setmem_operand" "Y,Y"))
8437 (const_int 0)))
8438 (clobber (match_scratch:GPR 0 "=d,d"))]
8439 "s390_match_ccmode(insn, CCSmode)"
8440 "@
8441 sra<g>\t%0,<1>%Y2
8442 sra<gk>\t%0,%1,%Y2"
8443 [(set_attr "op_type" "RS<E>,RSY")
8444 (set_attr "atype" "reg,reg")
8445 (set_attr "cpu_facility" "*,z196")
8446 (set_attr "z10prop" "z10_super_E1,*")])
8447
8448 ; sra, srag
8449 (define_insn "*ashr<mode>3"
8450 [(set (match_operand:GPR 0 "register_operand" "=d,d")
8451 (ashiftrt:GPR (match_operand:GPR 1 "register_operand" "<d0>,d")
8452 (match_operand:SI 2 "shift_count_or_setmem_operand" "Y,Y")))
8453 (clobber (reg:CC CC_REGNUM))]
8454 ""
8455 "@
8456 sra<g>\t%0,<1>%Y2
8457 sra<gk>\t%0,%1,%Y2"
8458 [(set_attr "op_type" "RS<E>,RSY")
8459 (set_attr "atype" "reg,reg")
8460 (set_attr "cpu_facility" "*,z196")
8461 (set_attr "z10prop" "z10_super_E1,*")])
8462
8463
8464 ; shift pattern with implicit ANDs
8465
8466 (define_insn "*ashrdi3_cc_31_and"
8467 [(set (reg CC_REGNUM)
8468 (compare (ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
8469 (and:SI (match_operand:SI 2 "shift_count_or_setmem_operand" "Y")
8470 (match_operand:SI 3 "const_int_operand" "n")))
8471 (const_int 0)))
8472 (set (match_operand:DI 0 "register_operand" "=d")
8473 (ashiftrt:DI (match_dup 1) (and:SI (match_dup 2) (match_dup 3))))]
8474 "!TARGET_ZARCH && s390_match_ccmode(insn, CCSmode)
8475 && (INTVAL (operands[3]) & 63) == 63"
8476 "srda\t%0,%Y2"
8477 [(set_attr "op_type" "RS")
8478 (set_attr "atype" "reg")])
8479
8480 (define_insn "*ashrdi3_cconly_31_and"
8481 [(set (reg CC_REGNUM)
8482 (compare (ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
8483 (and:SI (match_operand:SI 2 "shift_count_or_setmem_operand" "Y")
8484 (match_operand:SI 3 "const_int_operand" "n")))
8485 (const_int 0)))
8486 (clobber (match_scratch:DI 0 "=d"))]
8487 "!TARGET_ZARCH && s390_match_ccmode(insn, CCSmode)
8488 && (INTVAL (operands[3]) & 63) == 63"
8489 "srda\t%0,%Y2"
8490 [(set_attr "op_type" "RS")
8491 (set_attr "atype" "reg")])
8492
8493 (define_insn "*ashrdi3_31_and"
8494 [(set (match_operand:DI 0 "register_operand" "=d")
8495 (ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
8496 (and:SI (match_operand:SI 2 "shift_count_or_setmem_operand" "Y")
8497 (match_operand:SI 3 "const_int_operand" "n"))))
8498 (clobber (reg:CC CC_REGNUM))]
8499 "!TARGET_ZARCH && (INTVAL (operands[3]) & 63) == 63"
8500 "srda\t%0,%Y2"
8501 [(set_attr "op_type" "RS")
8502 (set_attr "atype" "reg")])
8503
8504 ; sra, srag, srak
8505 (define_insn "*ashr<mode>3_cc_and"
8506 [(set (reg CC_REGNUM)
8507 (compare (ashiftrt:GPR (match_operand:GPR 1 "register_operand" "<d0>,d")
8508 (and:SI (match_operand:SI 2 "shift_count_or_setmem_operand" "Y,Y")
8509 (match_operand:SI 3 "const_int_operand" "n,n")))
8510 (const_int 0)))
8511 (set (match_operand:GPR 0 "register_operand" "=d,d")
8512 (ashiftrt:GPR (match_dup 1) (and:SI (match_dup 2) (match_dup 3))))]
8513 "s390_match_ccmode(insn, CCSmode) && (INTVAL (operands[3]) & 63) == 63"
8514 "@
8515 sra<g>\t%0,<1>%Y2
8516 sra<gk>\t%0,%1,%Y2"
8517 [(set_attr "op_type" "RS<E>,RSY")
8518 (set_attr "atype" "reg,reg")
8519 (set_attr "cpu_facility" "*,z196")
8520 (set_attr "z10prop" "z10_super_E1,*")])
8521
8522 ; sra, srag, srak
8523 (define_insn "*ashr<mode>3_cconly_and"
8524 [(set (reg CC_REGNUM)
8525 (compare (ashiftrt:GPR (match_operand:GPR 1 "register_operand" "<d0>,d")
8526 (and:SI (match_operand:SI 2 "shift_count_or_setmem_operand" "Y,Y")
8527 (match_operand:SI 3 "const_int_operand" "n,n")))
8528 (const_int 0)))
8529 (clobber (match_scratch:GPR 0 "=d,d"))]
8530 "s390_match_ccmode(insn, CCSmode) && (INTVAL (operands[3]) & 63) == 63"
8531 "@
8532 sra<g>\t%0,<1>%Y2
8533 sra<gk>\t%0,%1,%Y2"
8534 [(set_attr "op_type" "RS<E>,RSY")
8535 (set_attr "atype" "reg,reg")
8536 (set_attr "cpu_facility" "*,z196")
8537 (set_attr "z10prop" "z10_super_E1,*")])
8538
8539 ; sra, srag, srak
8540 (define_insn "*ashr<mode>3_and"
8541 [(set (match_operand:GPR 0 "register_operand" "=d,d")
8542 (ashiftrt:GPR (match_operand:GPR 1 "register_operand" "<d0>,d")
8543 (and:SI (match_operand:SI 2 "shift_count_or_setmem_operand" "Y,Y")
8544 (match_operand:SI 3 "const_int_operand" "n,n"))))
8545 (clobber (reg:CC CC_REGNUM))]
8546 "(INTVAL (operands[3]) & 63) == 63"
8547 "@
8548 sra<g>\t%0,<1>%Y2
8549 sra<gk>\t%0,%1,%Y2"
8550 [(set_attr "op_type" "RS<E>,RSY")
8551 (set_attr "atype" "reg,reg")
8552 (set_attr "cpu_facility" "*,z196")
8553 (set_attr "z10prop" "z10_super_E1,*")])
8554
8555
8556 ;;
8557 ;; Branch instruction patterns.
8558 ;;
8559
8560 (define_expand "cbranch<mode>4"
8561 [(set (pc)
8562 (if_then_else (match_operator 0 "comparison_operator"
8563 [(match_operand:GPR 1 "register_operand" "")
8564 (match_operand:GPR 2 "general_operand" "")])
8565 (label_ref (match_operand 3 "" ""))
8566 (pc)))]
8567 ""
8568 "s390_emit_jump (operands[3],
8569 s390_emit_compare (GET_CODE (operands[0]), operands[1], operands[2]));
8570 DONE;")
8571
8572 (define_expand "cbranch<mode>4"
8573 [(set (pc)
8574 (if_then_else (match_operator 0 "comparison_operator"
8575 [(match_operand:FP 1 "register_operand" "")
8576 (match_operand:FP 2 "general_operand" "")])
8577 (label_ref (match_operand 3 "" ""))
8578 (pc)))]
8579 "TARGET_HARD_FLOAT"
8580 "s390_emit_jump (operands[3],
8581 s390_emit_compare (GET_CODE (operands[0]), operands[1], operands[2]));
8582 DONE;")
8583
8584 (define_expand "cbranchcc4"
8585 [(set (pc)
8586 (if_then_else (match_operator 0 "s390_comparison"
8587 [(match_operand 1 "cc_reg_operand" "")
8588 (match_operand 2 "const_int_operand" "")])
8589 (label_ref (match_operand 3 "" ""))
8590 (pc)))]
8591 ""
8592 "")
8593
8594
8595 ;;
8596 ;;- Conditional jump instructions.
8597 ;;
8598
8599 (define_insn "*cjump_64"
8600 [(set (pc)
8601 (if_then_else
8602 (match_operator 1 "s390_comparison" [(reg CC_REGNUM)
8603 (match_operand 2 "const_int_operand" "")])
8604 (label_ref (match_operand 0 "" ""))
8605 (pc)))]
8606 "TARGET_CPU_ZARCH"
8607 {
8608 if (get_attr_length (insn) == 4)
8609 return "j%C1\t%l0";
8610 else
8611 return "jg%C1\t%l0";
8612 }
8613 [(set_attr "op_type" "RI")
8614 (set_attr "type" "branch")
8615 (set (attr "length")
8616 (if_then_else (lt (abs (minus (pc) (match_dup 0))) (const_int 60000))
8617 (const_int 4) (const_int 6)))])
8618
8619 (define_insn "*cjump_31"
8620 [(set (pc)
8621 (if_then_else
8622 (match_operator 1 "s390_comparison" [(reg CC_REGNUM)
8623 (match_operand 2 "const_int_operand" "")])
8624 (label_ref (match_operand 0 "" ""))
8625 (pc)))]
8626 "!TARGET_CPU_ZARCH"
8627 {
8628 gcc_assert (get_attr_length (insn) == 4);
8629 return "j%C1\t%l0";
8630 }
8631 [(set_attr "op_type" "RI")
8632 (set_attr "type" "branch")
8633 (set (attr "length")
8634 (if_then_else (not (match_test "flag_pic"))
8635 (if_then_else (lt (abs (minus (pc) (match_dup 0))) (const_int 60000))
8636 (const_int 4) (const_int 6))
8637 (if_then_else (lt (abs (minus (pc) (match_dup 0))) (const_int 60000))
8638 (const_int 4) (const_int 8))))])
8639
8640 (define_insn "*cjump_long"
8641 [(set (pc)
8642 (if_then_else
8643 (match_operator 1 "s390_comparison" [(reg CC_REGNUM) (const_int 0)])
8644 (match_operand 0 "address_operand" "ZQZR")
8645 (pc)))]
8646 ""
8647 {
8648 if (get_attr_op_type (insn) == OP_TYPE_RR)
8649 return "b%C1r\t%0";
8650 else
8651 return "b%C1\t%a0";
8652 }
8653 [(set (attr "op_type")
8654 (if_then_else (match_operand 0 "register_operand" "")
8655 (const_string "RR") (const_string "RX")))
8656 (set_attr "type" "branch")
8657 (set_attr "atype" "agen")])
8658
8659 ;; A conditional return instruction.
8660 (define_insn "*c<code>"
8661 [(set (pc)
8662 (if_then_else
8663 (match_operator 0 "s390_comparison" [(reg CC_REGNUM) (const_int 0)])
8664 (ANY_RETURN)
8665 (pc)))]
8666 "s390_can_use_<code>_insn ()"
8667 "b%C0r\t%%r14"
8668 [(set_attr "op_type" "RR")
8669 (set_attr "type" "jsr")
8670 (set_attr "atype" "agen")])
8671
8672 ;;
8673 ;;- Negated conditional jump instructions.
8674 ;;
8675
8676 (define_insn "*icjump_64"
8677 [(set (pc)
8678 (if_then_else
8679 (match_operator 1 "s390_comparison" [(reg CC_REGNUM) (const_int 0)])
8680 (pc)
8681 (label_ref (match_operand 0 "" ""))))]
8682 "TARGET_CPU_ZARCH"
8683 {
8684 if (get_attr_length (insn) == 4)
8685 return "j%D1\t%l0";
8686 else
8687 return "jg%D1\t%l0";
8688 }
8689 [(set_attr "op_type" "RI")
8690 (set_attr "type" "branch")
8691 (set (attr "length")
8692 (if_then_else (lt (abs (minus (pc) (match_dup 0))) (const_int 60000))
8693 (const_int 4) (const_int 6)))])
8694
8695 (define_insn "*icjump_31"
8696 [(set (pc)
8697 (if_then_else
8698 (match_operator 1 "s390_comparison" [(reg CC_REGNUM) (const_int 0)])
8699 (pc)
8700 (label_ref (match_operand 0 "" ""))))]
8701 "!TARGET_CPU_ZARCH"
8702 {
8703 gcc_assert (get_attr_length (insn) == 4);
8704 return "j%D1\t%l0";
8705 }
8706 [(set_attr "op_type" "RI")
8707 (set_attr "type" "branch")
8708 (set (attr "length")
8709 (if_then_else (not (match_test "flag_pic"))
8710 (if_then_else (lt (abs (minus (pc) (match_dup 0))) (const_int 60000))
8711 (const_int 4) (const_int 6))
8712 (if_then_else (lt (abs (minus (pc) (match_dup 0))) (const_int 60000))
8713 (const_int 4) (const_int 8))))])
8714
8715 (define_insn "*icjump_long"
8716 [(set (pc)
8717 (if_then_else
8718 (match_operator 1 "s390_comparison" [(reg CC_REGNUM) (const_int 0)])
8719 (pc)
8720 (match_operand 0 "address_operand" "ZQZR")))]
8721 ""
8722 {
8723 if (get_attr_op_type (insn) == OP_TYPE_RR)
8724 return "b%D1r\t%0";
8725 else
8726 return "b%D1\t%a0";
8727 }
8728 [(set (attr "op_type")
8729 (if_then_else (match_operand 0 "register_operand" "")
8730 (const_string "RR") (const_string "RX")))
8731 (set_attr "type" "branch")
8732 (set_attr "atype" "agen")])
8733
8734 ;;
8735 ;;- Trap instructions.
8736 ;;
8737
8738 (define_insn "trap"
8739 [(trap_if (const_int 1) (const_int 0))]
8740 ""
8741 "j\t.+2"
8742 [(set_attr "op_type" "RI")
8743 (set_attr "type" "branch")])
8744
8745 (define_expand "ctrap<mode>4"
8746 [(trap_if (match_operator 0 "comparison_operator"
8747 [(match_operand:GPR 1 "register_operand" "")
8748 (match_operand:GPR 2 "general_operand" "")])
8749 (match_operand 3 "const0_operand" ""))]
8750 ""
8751 {
8752 rtx cond = s390_emit_compare (GET_CODE (operands[0]),
8753 operands[1], operands[2]);
8754 emit_insn (gen_condtrap (cond, XEXP (cond, 0)));
8755 DONE;
8756 })
8757
8758 (define_expand "ctrap<mode>4"
8759 [(trap_if (match_operator 0 "comparison_operator"
8760 [(match_operand:FP 1 "register_operand" "")
8761 (match_operand:FP 2 "general_operand" "")])
8762 (match_operand 3 "const0_operand" ""))]
8763 ""
8764 {
8765 rtx cond = s390_emit_compare (GET_CODE (operands[0]),
8766 operands[1], operands[2]);
8767 emit_insn (gen_condtrap (cond, XEXP (cond, 0)));
8768 DONE;
8769 })
8770
8771 (define_insn "condtrap"
8772 [(trap_if (match_operator 0 "s390_comparison"
8773 [(match_operand 1 "cc_reg_operand" "c")
8774 (const_int 0)])
8775 (const_int 0))]
8776 ""
8777 "j%C0\t.+2";
8778 [(set_attr "op_type" "RI")
8779 (set_attr "type" "branch")])
8780
8781 ; crt, cgrt, cit, cgit
8782 (define_insn "*cmp_and_trap_signed_int<mode>"
8783 [(trap_if (match_operator 0 "s390_signed_integer_comparison"
8784 [(match_operand:GPR 1 "register_operand" "d,d")
8785 (match_operand:GPR 2 "nonmemory_operand" "d,K")])
8786 (const_int 0))]
8787 "TARGET_Z10"
8788 "@
8789 c<g>rt%C0\t%1,%2
8790 c<g>it%C0\t%1,%h2"
8791 [(set_attr "op_type" "RRF,RIE")
8792 (set_attr "type" "branch")
8793 (set_attr "z10prop" "z10_super_c,z10_super")])
8794
8795 ; clrt, clgrt, clfit, clgit, clt, clgt
8796 (define_insn "*cmp_and_trap_unsigned_int<mode>"
8797 [(trap_if (match_operator 0 "s390_unsigned_integer_comparison"
8798 [(match_operand:GPR 1 "register_operand" "d,d, d")
8799 (match_operand:GPR 2 "general_operand" "d,D,RT")])
8800 (const_int 0))]
8801 "TARGET_Z10"
8802 "@
8803 cl<g>rt%C0\t%1,%2
8804 cl<gf>it%C0\t%1,%x2
8805 cl<g>t%C0\t%1,%2"
8806 [(set_attr "op_type" "RRF,RIE,RSY")
8807 (set_attr "type" "branch")
8808 (set_attr "z10prop" "z10_super_c,z10_super,*")
8809 (set_attr "cpu_facility" "z10,z10,zEC12")])
8810
8811 ; lat, lgat
8812 (define_insn "*load_and_trap<mode>"
8813 [(trap_if (eq (match_operand:GPR 0 "memory_operand" "RT")
8814 (const_int 0))
8815 (const_int 0))
8816 (set (match_operand:GPR 1 "register_operand" "=d")
8817 (match_dup 0))]
8818 "TARGET_ZEC12"
8819 "l<g>at\t%1,%0"
8820 [(set_attr "op_type" "RXY")])
8821
8822
8823 ;;
8824 ;;- Loop instructions.
8825 ;;
8826 ;; This is all complicated by the fact that since this is a jump insn
8827 ;; we must handle our own output reloads.
8828
8829 ;; branch on index
8830
8831 ; This splitter will be matched by combine and has to add the 2 moves
8832 ; necessary to load the compare and the increment values into a
8833 ; register pair as needed by brxle.
8834
8835 (define_insn_and_split "*brx_stage1_<GPR:mode>"
8836 [(set (pc)
8837 (if_then_else
8838 (match_operator 6 "s390_brx_operator"
8839 [(plus:GPR (match_operand:GPR 1 "register_operand" "")
8840 (match_operand:GPR 2 "general_operand" ""))
8841 (match_operand:GPR 3 "register_operand" "")])
8842 (label_ref (match_operand 0 "" ""))
8843 (pc)))
8844 (set (match_operand:GPR 4 "nonimmediate_operand" "")
8845 (plus:GPR (match_dup 1) (match_dup 2)))
8846 (clobber (match_scratch:GPR 5 ""))]
8847 "TARGET_CPU_ZARCH"
8848 "#"
8849 "!reload_completed && !reload_in_progress"
8850 [(set (match_dup 7) (match_dup 2)) ; the increment
8851 (set (match_dup 8) (match_dup 3)) ; the comparison value
8852 (parallel [(set (pc)
8853 (if_then_else
8854 (match_op_dup 6
8855 [(plus:GPR (match_dup 1) (match_dup 7))
8856 (match_dup 8)])
8857 (label_ref (match_dup 0))
8858 (pc)))
8859 (set (match_dup 4)
8860 (plus:GPR (match_dup 1) (match_dup 7)))
8861 (clobber (match_dup 5))
8862 (clobber (reg:CC CC_REGNUM))])]
8863 {
8864 rtx dreg = gen_reg_rtx (word_mode == DImode ? TImode : DImode);
8865 operands[7] = gen_lowpart (<GPR:MODE>mode,
8866 gen_highpart (word_mode, dreg));
8867 operands[8] = gen_lowpart (<GPR:MODE>mode,
8868 gen_lowpart (word_mode, dreg));
8869 })
8870
8871 ; brxlg, brxhg
8872
8873 (define_insn_and_split "*brxg_64bit"
8874 [(set (pc)
8875 (if_then_else
8876 (match_operator 5 "s390_brx_operator"
8877 [(plus:DI (match_operand:DI 1 "register_operand" "d,d,d")
8878 (subreg:DI (match_operand:TI 2 "register_operand" "d,d,d") 0))
8879 (subreg:DI (match_dup 2) 8)])
8880 (label_ref (match_operand 0 "" ""))
8881 (pc)))
8882 (set (match_operand:DI 3 "nonimmediate_operand" "=1,?X,?X")
8883 (plus:DI (match_dup 1)
8884 (subreg:DI (match_dup 2) 0)))
8885 (clobber (match_scratch:DI 4 "=X,&1,&?d"))
8886 (clobber (reg:CC CC_REGNUM))]
8887 "TARGET_ZARCH"
8888 {
8889 if (which_alternative != 0)
8890 return "#";
8891 else if (get_attr_length (insn) == 6)
8892 return "brx%E5g\t%1,%2,%l0";
8893 else
8894 return "agr\t%1,%2\;cgr\t%1,%M2\;jg%C5\t%l0";
8895 }
8896 "&& reload_completed
8897 && (!REG_P (operands[3])
8898 || !rtx_equal_p (operands[1], operands[3]))"
8899 [(set (match_dup 4) (match_dup 1))
8900 (parallel [(set (match_dup 4) (plus:DI (match_dup 4) (subreg:DI (match_dup 2) 0)))
8901 (clobber (reg:CC CC_REGNUM))])
8902 (set (reg:CCS CC_REGNUM) (compare:CCS (match_dup 4) (subreg:DI (match_dup 2) 8)))
8903 (set (match_dup 3) (match_dup 4))
8904 (set (pc) (if_then_else (match_op_dup 5 [(reg:CCS CC_REGNUM) (const_int 0)])
8905 (label_ref (match_dup 0))
8906 (pc)))]
8907 ""
8908 [(set_attr "op_type" "RIE")
8909 (set_attr "type" "branch")
8910 (set (attr "length")
8911 (if_then_else (lt (abs (minus (pc) (match_dup 0))) (const_int 60000))
8912 (const_int 6) (const_int 16)))])
8913
8914 ; brxle, brxh
8915
8916 (define_insn_and_split "*brx_64bit"
8917 [(set (pc)
8918 (if_then_else
8919 (match_operator 5 "s390_brx_operator"
8920 [(plus:SI (match_operand:SI 1 "register_operand" "d,d,d")
8921 (subreg:SI (match_operand:TI 2 "register_operand" "d,d,d") 4))
8922 (subreg:SI (match_dup 2) 12)])
8923 (label_ref (match_operand 0 "" ""))
8924 (pc)))
8925 (set (match_operand:SI 3 "nonimmediate_operand" "=1,?X,?X")
8926 (plus:SI (match_dup 1)
8927 (subreg:SI (match_dup 2) 4)))
8928 (clobber (match_scratch:SI 4 "=X,&1,&?d"))
8929 (clobber (reg:CC CC_REGNUM))]
8930 "TARGET_ZARCH"
8931 {
8932 if (which_alternative != 0)
8933 return "#";
8934 else if (get_attr_length (insn) == 6)
8935 return "brx%C5\t%1,%2,%l0";
8936 else
8937 return "ar\t%1,%2\;cr\t%1,%M2\;jg%C5\t%l0";
8938 }
8939 "&& reload_completed
8940 && (!REG_P (operands[3])
8941 || !rtx_equal_p (operands[1], operands[3]))"
8942 [(set (match_dup 4) (match_dup 1))
8943 (parallel [(set (match_dup 4) (plus:SI (match_dup 4) (subreg:SI (match_dup 2) 4)))
8944 (clobber (reg:CC CC_REGNUM))])
8945 (set (reg:CCS CC_REGNUM) (compare:CCS (match_dup 4) (subreg:SI (match_dup 2) 12)))
8946 (set (match_dup 3) (match_dup 4))
8947 (set (pc) (if_then_else (match_op_dup 5 [(reg:CCS CC_REGNUM) (const_int 0)])
8948 (label_ref (match_dup 0))
8949 (pc)))]
8950 ""
8951 [(set_attr "op_type" "RSI")
8952 (set_attr "type" "branch")
8953 (set (attr "length")
8954 (if_then_else (lt (abs (minus (pc) (match_dup 0))) (const_int 60000))
8955 (const_int 6) (const_int 14)))])
8956
8957 ; brxle, brxh
8958
8959 (define_insn_and_split "*brx_31bit"
8960 [(set (pc)
8961 (if_then_else
8962 (match_operator 5 "s390_brx_operator"
8963 [(plus:SI (match_operand:SI 1 "register_operand" "d,d,d")
8964 (subreg:SI (match_operand:DI 2 "register_operand" "d,d,d") 0))
8965 (subreg:SI (match_dup 2) 4)])
8966 (label_ref (match_operand 0 "" ""))
8967 (pc)))
8968 (set (match_operand:SI 3 "nonimmediate_operand" "=1,?X,?X")
8969 (plus:SI (match_dup 1)
8970 (subreg:SI (match_dup 2) 0)))
8971 (clobber (match_scratch:SI 4 "=X,&1,&?d"))
8972 (clobber (reg:CC CC_REGNUM))]
8973 "!TARGET_ZARCH && TARGET_CPU_ZARCH"
8974 {
8975 if (which_alternative != 0)
8976 return "#";
8977 else if (get_attr_length (insn) == 6)
8978 return "brx%C5\t%1,%2,%l0";
8979 else
8980 return "ar\t%1,%2\;cr\t%1,%M2\;jg%C5\t%l0";
8981 }
8982 "&& reload_completed
8983 && (!REG_P (operands[3])
8984 || !rtx_equal_p (operands[1], operands[3]))"
8985 [(set (match_dup 4) (match_dup 1))
8986 (parallel [(set (match_dup 4) (plus:SI (match_dup 4) (subreg:SI (match_dup 2) 0)))
8987 (clobber (reg:CC CC_REGNUM))])
8988 (set (reg:CCS CC_REGNUM) (compare:CCS (match_dup 4) (subreg:SI (match_dup 2) 4)))
8989 (set (match_dup 3) (match_dup 4))
8990 (set (pc) (if_then_else (match_op_dup 5 [(reg:CCS CC_REGNUM) (const_int 0)])
8991 (label_ref (match_dup 0))
8992 (pc)))]
8993 ""
8994 [(set_attr "op_type" "RSI")
8995 (set_attr "type" "branch")
8996 (set (attr "length")
8997 (if_then_else (lt (abs (minus (pc) (match_dup 0))) (const_int 60000))
8998 (const_int 6) (const_int 14)))])
8999
9000
9001 ;; branch on count
9002
9003 (define_expand "doloop_end"
9004 [(use (match_operand 0 "" "")) ; loop pseudo
9005 (use (match_operand 1 "" ""))] ; label
9006 ""
9007 {
9008 if (GET_MODE (operands[0]) == SImode && !TARGET_CPU_ZARCH)
9009 emit_jump_insn (gen_doloop_si31 (operands[1], operands[0], operands[0]));
9010 else if (GET_MODE (operands[0]) == SImode && TARGET_CPU_ZARCH)
9011 emit_jump_insn (gen_doloop_si64 (operands[1], operands[0], operands[0]));
9012 else if (GET_MODE (operands[0]) == DImode && TARGET_ZARCH)
9013 emit_jump_insn (gen_doloop_di (operands[1], operands[0], operands[0]));
9014 else
9015 FAIL;
9016
9017 DONE;
9018 })
9019
9020 (define_insn_and_split "doloop_si64"
9021 [(set (pc)
9022 (if_then_else
9023 (ne (match_operand:SI 1 "register_operand" "d,d,d")
9024 (const_int 1))
9025 (label_ref (match_operand 0 "" ""))
9026 (pc)))
9027 (set (match_operand:SI 2 "nonimmediate_operand" "=1,?X,?X")
9028 (plus:SI (match_dup 1) (const_int -1)))
9029 (clobber (match_scratch:SI 3 "=X,&1,&?d"))
9030 (clobber (reg:CC CC_REGNUM))]
9031 "TARGET_CPU_ZARCH"
9032 {
9033 if (which_alternative != 0)
9034 return "#";
9035 else if (get_attr_length (insn) == 4)
9036 return "brct\t%1,%l0";
9037 else
9038 return "ahi\t%1,-1\;jgne\t%l0";
9039 }
9040 "&& reload_completed
9041 && (! REG_P (operands[2])
9042 || ! rtx_equal_p (operands[1], operands[2]))"
9043 [(set (match_dup 3) (match_dup 1))
9044 (parallel [(set (reg:CCAN CC_REGNUM)
9045 (compare:CCAN (plus:SI (match_dup 3) (const_int -1))
9046 (const_int 0)))
9047 (set (match_dup 3) (plus:SI (match_dup 3) (const_int -1)))])
9048 (set (match_dup 2) (match_dup 3))
9049 (set (pc) (if_then_else (ne (reg:CCAN CC_REGNUM) (const_int 0))
9050 (label_ref (match_dup 0))
9051 (pc)))]
9052 ""
9053 [(set_attr "op_type" "RI")
9054 ; Strictly speaking, the z10 properties are valid for brct only, however, it does not
9055 ; hurt us in the (rare) case of ahi.
9056 (set_attr "z10prop" "z10_super_E1")
9057 (set_attr "type" "branch")
9058 (set (attr "length")
9059 (if_then_else (lt (abs (minus (pc) (match_dup 0))) (const_int 60000))
9060 (const_int 4) (const_int 10)))])
9061
9062 (define_insn_and_split "doloop_si31"
9063 [(set (pc)
9064 (if_then_else
9065 (ne (match_operand:SI 1 "register_operand" "d,d,d")
9066 (const_int 1))
9067 (label_ref (match_operand 0 "" ""))
9068 (pc)))
9069 (set (match_operand:SI 2 "nonimmediate_operand" "=1,?X,?X")
9070 (plus:SI (match_dup 1) (const_int -1)))
9071 (clobber (match_scratch:SI 3 "=X,&1,&?d"))
9072 (clobber (reg:CC CC_REGNUM))]
9073 "!TARGET_CPU_ZARCH"
9074 {
9075 if (which_alternative != 0)
9076 return "#";
9077 else if (get_attr_length (insn) == 4)
9078 return "brct\t%1,%l0";
9079 else
9080 gcc_unreachable ();
9081 }
9082 "&& reload_completed
9083 && (! REG_P (operands[2])
9084 || ! rtx_equal_p (operands[1], operands[2]))"
9085 [(set (match_dup 3) (match_dup 1))
9086 (parallel [(set (reg:CCAN CC_REGNUM)
9087 (compare:CCAN (plus:SI (match_dup 3) (const_int -1))
9088 (const_int 0)))
9089 (set (match_dup 3) (plus:SI (match_dup 3) (const_int -1)))])
9090 (set (match_dup 2) (match_dup 3))
9091 (set (pc) (if_then_else (ne (reg:CCAN CC_REGNUM) (const_int 0))
9092 (label_ref (match_dup 0))
9093 (pc)))]
9094 ""
9095 [(set_attr "op_type" "RI")
9096 ; Strictly speaking, the z10 properties are valid for brct only, however, it does not
9097 ; hurt us in the (rare) case of ahi.
9098 (set_attr "z10prop" "z10_super_E1")
9099 (set_attr "type" "branch")
9100 (set (attr "length")
9101 (if_then_else (not (match_test "flag_pic"))
9102 (if_then_else (lt (abs (minus (pc) (match_dup 0))) (const_int 60000))
9103 (const_int 4) (const_int 6))
9104 (if_then_else (lt (abs (minus (pc) (match_dup 0))) (const_int 60000))
9105 (const_int 4) (const_int 8))))])
9106
9107 (define_insn "*doloop_si_long"
9108 [(set (pc)
9109 (if_then_else
9110 (ne (match_operand:SI 1 "register_operand" "d")
9111 (const_int 1))
9112 (match_operand 0 "address_operand" "ZQZR")
9113 (pc)))
9114 (set (match_operand:SI 2 "register_operand" "=1")
9115 (plus:SI (match_dup 1) (const_int -1)))
9116 (clobber (match_scratch:SI 3 "=X"))
9117 (clobber (reg:CC CC_REGNUM))]
9118 "!TARGET_CPU_ZARCH"
9119 {
9120 if (get_attr_op_type (insn) == OP_TYPE_RR)
9121 return "bctr\t%1,%0";
9122 else
9123 return "bct\t%1,%a0";
9124 }
9125 [(set (attr "op_type")
9126 (if_then_else (match_operand 0 "register_operand" "")
9127 (const_string "RR") (const_string "RX")))
9128 (set_attr "type" "branch")
9129 (set_attr "atype" "agen")
9130 (set_attr "z10prop" "z10_c")
9131 (set_attr "z196prop" "z196_cracked")])
9132
9133 (define_insn_and_split "doloop_di"
9134 [(set (pc)
9135 (if_then_else
9136 (ne (match_operand:DI 1 "register_operand" "d,d,d")
9137 (const_int 1))
9138 (label_ref (match_operand 0 "" ""))
9139 (pc)))
9140 (set (match_operand:DI 2 "nonimmediate_operand" "=1,?X,?X")
9141 (plus:DI (match_dup 1) (const_int -1)))
9142 (clobber (match_scratch:DI 3 "=X,&1,&?d"))
9143 (clobber (reg:CC CC_REGNUM))]
9144 "TARGET_ZARCH"
9145 {
9146 if (which_alternative != 0)
9147 return "#";
9148 else if (get_attr_length (insn) == 4)
9149 return "brctg\t%1,%l0";
9150 else
9151 return "aghi\t%1,-1\;jgne\t%l0";
9152 }
9153 "&& reload_completed
9154 && (! REG_P (operands[2])
9155 || ! rtx_equal_p (operands[1], operands[2]))"
9156 [(set (match_dup 3) (match_dup 1))
9157 (parallel [(set (reg:CCAN CC_REGNUM)
9158 (compare:CCAN (plus:DI (match_dup 3) (const_int -1))
9159 (const_int 0)))
9160 (set (match_dup 3) (plus:DI (match_dup 3) (const_int -1)))])
9161 (set (match_dup 2) (match_dup 3))
9162 (set (pc) (if_then_else (ne (reg:CCAN CC_REGNUM) (const_int 0))
9163 (label_ref (match_dup 0))
9164 (pc)))]
9165 ""
9166 [(set_attr "op_type" "RI")
9167 ; Strictly speaking, the z10 properties are valid for brct only, however, it does not
9168 ; hurt us in the (rare) case of ahi.
9169 (set_attr "z10prop" "z10_super_E1")
9170 (set_attr "type" "branch")
9171 (set (attr "length")
9172 (if_then_else (lt (abs (minus (pc) (match_dup 0))) (const_int 60000))
9173 (const_int 4) (const_int 10)))])
9174
9175 ;;
9176 ;;- Unconditional jump instructions.
9177 ;;
9178
9179 ;
9180 ; jump instruction pattern(s).
9181 ;
9182
9183 (define_expand "jump"
9184 [(match_operand 0 "" "")]
9185 ""
9186 "s390_emit_jump (operands[0], NULL_RTX); DONE;")
9187
9188 (define_insn "*jump64"
9189 [(set (pc) (label_ref (match_operand 0 "" "")))]
9190 "TARGET_CPU_ZARCH"
9191 {
9192 if (get_attr_length (insn) == 4)
9193 return "j\t%l0";
9194 else
9195 return "jg\t%l0";
9196 }
9197 [(set_attr "op_type" "RI")
9198 (set_attr "type" "branch")
9199 (set (attr "length")
9200 (if_then_else (lt (abs (minus (pc) (match_dup 0))) (const_int 60000))
9201 (const_int 4) (const_int 6)))])
9202
9203 (define_insn "*jump31"
9204 [(set (pc) (label_ref (match_operand 0 "" "")))]
9205 "!TARGET_CPU_ZARCH"
9206 {
9207 gcc_assert (get_attr_length (insn) == 4);
9208 return "j\t%l0";
9209 }
9210 [(set_attr "op_type" "RI")
9211 (set_attr "type" "branch")
9212 (set (attr "length")
9213 (if_then_else (not (match_test "flag_pic"))
9214 (if_then_else (lt (abs (minus (pc) (match_dup 0))) (const_int 60000))
9215 (const_int 4) (const_int 6))
9216 (if_then_else (lt (abs (minus (pc) (match_dup 0))) (const_int 60000))
9217 (const_int 4) (const_int 8))))])
9218
9219 ;
9220 ; indirect-jump instruction pattern(s).
9221 ;
9222
9223 (define_insn "indirect_jump"
9224 [(set (pc) (match_operand 0 "address_operand" "ZQZR"))]
9225 ""
9226 {
9227 if (get_attr_op_type (insn) == OP_TYPE_RR)
9228 return "br\t%0";
9229 else
9230 return "b\t%a0";
9231 }
9232 [(set (attr "op_type")
9233 (if_then_else (match_operand 0 "register_operand" "")
9234 (const_string "RR") (const_string "RX")))
9235 (set_attr "type" "branch")
9236 (set_attr "atype" "agen")])
9237
9238 ;
9239 ; casesi instruction pattern(s).
9240 ;
9241
9242 (define_insn "casesi_jump"
9243 [(set (pc) (match_operand 0 "address_operand" "ZQZR"))
9244 (use (label_ref (match_operand 1 "" "")))]
9245 ""
9246 {
9247 if (get_attr_op_type (insn) == OP_TYPE_RR)
9248 return "br\t%0";
9249 else
9250 return "b\t%a0";
9251 }
9252 [(set (attr "op_type")
9253 (if_then_else (match_operand 0 "register_operand" "")
9254 (const_string "RR") (const_string "RX")))
9255 (set_attr "type" "branch")
9256 (set_attr "atype" "agen")])
9257
9258 (define_expand "casesi"
9259 [(match_operand:SI 0 "general_operand" "")
9260 (match_operand:SI 1 "general_operand" "")
9261 (match_operand:SI 2 "general_operand" "")
9262 (label_ref (match_operand 3 "" ""))
9263 (label_ref (match_operand 4 "" ""))]
9264 ""
9265 {
9266 rtx index = gen_reg_rtx (SImode);
9267 rtx base = gen_reg_rtx (Pmode);
9268 rtx target = gen_reg_rtx (Pmode);
9269
9270 emit_move_insn (index, operands[0]);
9271 emit_insn (gen_subsi3 (index, index, operands[1]));
9272 emit_cmp_and_jump_insns (index, operands[2], GTU, NULL_RTX, SImode, 1,
9273 operands[4]);
9274
9275 if (Pmode != SImode)
9276 index = convert_to_mode (Pmode, index, 1);
9277 if (GET_CODE (index) != REG)
9278 index = copy_to_mode_reg (Pmode, index);
9279
9280 if (TARGET_64BIT)
9281 emit_insn (gen_ashldi3 (index, index, GEN_INT (3)));
9282 else
9283 emit_insn (gen_ashlsi3 (index, index, const2_rtx));
9284
9285 emit_move_insn (base, gen_rtx_LABEL_REF (Pmode, operands[3]));
9286
9287 index = gen_const_mem (Pmode, gen_rtx_PLUS (Pmode, base, index));
9288 emit_move_insn (target, index);
9289
9290 if (flag_pic)
9291 target = gen_rtx_PLUS (Pmode, base, target);
9292 emit_jump_insn (gen_casesi_jump (target, operands[3]));
9293
9294 DONE;
9295 })
9296
9297
9298 ;;
9299 ;;- Jump to subroutine.
9300 ;;
9301 ;;
9302
9303 ;
9304 ; untyped call instruction pattern(s).
9305 ;
9306
9307 ;; Call subroutine returning any type.
9308 (define_expand "untyped_call"
9309 [(parallel [(call (match_operand 0 "" "")
9310 (const_int 0))
9311 (match_operand 1 "" "")
9312 (match_operand 2 "" "")])]
9313 ""
9314 {
9315 int i;
9316
9317 emit_call_insn (gen_call (operands[0], const0_rtx, const0_rtx));
9318
9319 for (i = 0; i < XVECLEN (operands[2], 0); i++)
9320 {
9321 rtx set = XVECEXP (operands[2], 0, i);
9322 emit_move_insn (SET_DEST (set), SET_SRC (set));
9323 }
9324
9325 /* The optimizer does not know that the call sets the function value
9326 registers we stored in the result block. We avoid problems by
9327 claiming that all hard registers are used and clobbered at this
9328 point. */
9329 emit_insn (gen_blockage ());
9330
9331 DONE;
9332 })
9333
9334 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
9335 ;; all of memory. This blocks insns from being moved across this point.
9336
9337 (define_insn "blockage"
9338 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
9339 ""
9340 ""
9341 [(set_attr "type" "none")
9342 (set_attr "length" "0")])
9343
9344 ;
9345 ; sibcall patterns
9346 ;
9347
9348 (define_expand "sibcall"
9349 [(call (match_operand 0 "" "")
9350 (match_operand 1 "" ""))]
9351 ""
9352 {
9353 s390_emit_call (XEXP (operands[0], 0), NULL_RTX, NULL_RTX, NULL_RTX);
9354 DONE;
9355 })
9356
9357 (define_insn "*sibcall_br"
9358 [(call (mem:QI (reg SIBCALL_REGNUM))
9359 (match_operand 0 "const_int_operand" "n"))]
9360 "SIBLING_CALL_P (insn)
9361 && GET_MODE (XEXP (XEXP (PATTERN (insn), 0), 0)) == Pmode"
9362 "br\t%%r1"
9363 [(set_attr "op_type" "RR")
9364 (set_attr "type" "branch")
9365 (set_attr "atype" "agen")])
9366
9367 (define_insn "*sibcall_brc"
9368 [(call (mem:QI (match_operand 0 "bras_sym_operand" "X"))
9369 (match_operand 1 "const_int_operand" "n"))]
9370 "SIBLING_CALL_P (insn) && TARGET_SMALL_EXEC"
9371 "j\t%0"
9372 [(set_attr "op_type" "RI")
9373 (set_attr "type" "branch")])
9374
9375 (define_insn "*sibcall_brcl"
9376 [(call (mem:QI (match_operand 0 "bras_sym_operand" "X"))
9377 (match_operand 1 "const_int_operand" "n"))]
9378 "SIBLING_CALL_P (insn) && TARGET_CPU_ZARCH"
9379 "jg\t%0"
9380 [(set_attr "op_type" "RIL")
9381 (set_attr "type" "branch")])
9382
9383 ;
9384 ; sibcall_value patterns
9385 ;
9386
9387 (define_expand "sibcall_value"
9388 [(set (match_operand 0 "" "")
9389 (call (match_operand 1 "" "")
9390 (match_operand 2 "" "")))]
9391 ""
9392 {
9393 s390_emit_call (XEXP (operands[1], 0), NULL_RTX, operands[0], NULL_RTX);
9394 DONE;
9395 })
9396
9397 (define_insn "*sibcall_value_br"
9398 [(set (match_operand 0 "" "")
9399 (call (mem:QI (reg SIBCALL_REGNUM))
9400 (match_operand 1 "const_int_operand" "n")))]
9401 "SIBLING_CALL_P (insn)
9402 && GET_MODE (XEXP (XEXP (XEXP (PATTERN (insn), 1), 0), 0)) == Pmode"
9403 "br\t%%r1"
9404 [(set_attr "op_type" "RR")
9405 (set_attr "type" "branch")
9406 (set_attr "atype" "agen")])
9407
9408 (define_insn "*sibcall_value_brc"
9409 [(set (match_operand 0 "" "")
9410 (call (mem:QI (match_operand 1 "bras_sym_operand" "X"))
9411 (match_operand 2 "const_int_operand" "n")))]
9412 "SIBLING_CALL_P (insn) && TARGET_SMALL_EXEC"
9413 "j\t%1"
9414 [(set_attr "op_type" "RI")
9415 (set_attr "type" "branch")])
9416
9417 (define_insn "*sibcall_value_brcl"
9418 [(set (match_operand 0 "" "")
9419 (call (mem:QI (match_operand 1 "bras_sym_operand" "X"))
9420 (match_operand 2 "const_int_operand" "n")))]
9421 "SIBLING_CALL_P (insn) && TARGET_CPU_ZARCH"
9422 "jg\t%1"
9423 [(set_attr "op_type" "RIL")
9424 (set_attr "type" "branch")])
9425
9426
9427 ;
9428 ; call instruction pattern(s).
9429 ;
9430
9431 (define_expand "call"
9432 [(call (match_operand 0 "" "")
9433 (match_operand 1 "" ""))
9434 (use (match_operand 2 "" ""))]
9435 ""
9436 {
9437 s390_emit_call (XEXP (operands[0], 0), NULL_RTX, NULL_RTX,
9438 gen_rtx_REG (Pmode, RETURN_REGNUM));
9439 DONE;
9440 })
9441
9442 (define_insn "*bras"
9443 [(call (mem:QI (match_operand 0 "bras_sym_operand" "X"))
9444 (match_operand 1 "const_int_operand" "n"))
9445 (clobber (match_operand 2 "register_operand" "=r"))]
9446 "!SIBLING_CALL_P (insn)
9447 && TARGET_SMALL_EXEC
9448 && GET_MODE (operands[2]) == Pmode"
9449 "bras\t%2,%0"
9450 [(set_attr "op_type" "RI")
9451 (set_attr "type" "jsr")
9452 (set_attr "z196prop" "z196_cracked")])
9453
9454 (define_insn "*brasl"
9455 [(call (mem:QI (match_operand 0 "bras_sym_operand" "X"))
9456 (match_operand 1 "const_int_operand" "n"))
9457 (clobber (match_operand 2 "register_operand" "=r"))]
9458 "!SIBLING_CALL_P (insn)
9459 && TARGET_CPU_ZARCH
9460 && GET_MODE (operands[2]) == Pmode"
9461 "brasl\t%2,%0"
9462 [(set_attr "op_type" "RIL")
9463 (set_attr "type" "jsr")
9464 (set_attr "z196prop" "z196_cracked")])
9465
9466 (define_insn "*basr"
9467 [(call (mem:QI (match_operand 0 "address_operand" "ZQZR"))
9468 (match_operand 1 "const_int_operand" "n"))
9469 (clobber (match_operand 2 "register_operand" "=r"))]
9470 "!SIBLING_CALL_P (insn) && GET_MODE (operands[2]) == Pmode"
9471 {
9472 if (get_attr_op_type (insn) == OP_TYPE_RR)
9473 return "basr\t%2,%0";
9474 else
9475 return "bas\t%2,%a0";
9476 }
9477 [(set (attr "op_type")
9478 (if_then_else (match_operand 0 "register_operand" "")
9479 (const_string "RR") (const_string "RX")))
9480 (set_attr "type" "jsr")
9481 (set_attr "atype" "agen")
9482 (set_attr "z196prop" "z196_cracked")])
9483
9484 ;
9485 ; call_value instruction pattern(s).
9486 ;
9487
9488 (define_expand "call_value"
9489 [(set (match_operand 0 "" "")
9490 (call (match_operand 1 "" "")
9491 (match_operand 2 "" "")))
9492 (use (match_operand 3 "" ""))]
9493 ""
9494 {
9495 s390_emit_call (XEXP (operands[1], 0), NULL_RTX, operands[0],
9496 gen_rtx_REG (Pmode, RETURN_REGNUM));
9497 DONE;
9498 })
9499
9500 (define_insn "*bras_r"
9501 [(set (match_operand 0 "" "")
9502 (call (mem:QI (match_operand 1 "bras_sym_operand" "X"))
9503 (match_operand:SI 2 "const_int_operand" "n")))
9504 (clobber (match_operand 3 "register_operand" "=r"))]
9505 "!SIBLING_CALL_P (insn)
9506 && TARGET_SMALL_EXEC
9507 && GET_MODE (operands[3]) == Pmode"
9508 "bras\t%3,%1"
9509 [(set_attr "op_type" "RI")
9510 (set_attr "type" "jsr")
9511 (set_attr "z196prop" "z196_cracked")])
9512
9513 (define_insn "*brasl_r"
9514 [(set (match_operand 0 "" "")
9515 (call (mem:QI (match_operand 1 "bras_sym_operand" "X"))
9516 (match_operand 2 "const_int_operand" "n")))
9517 (clobber (match_operand 3 "register_operand" "=r"))]
9518 "!SIBLING_CALL_P (insn)
9519 && TARGET_CPU_ZARCH
9520 && GET_MODE (operands[3]) == Pmode"
9521 "brasl\t%3,%1"
9522 [(set_attr "op_type" "RIL")
9523 (set_attr "type" "jsr")
9524 (set_attr "z196prop" "z196_cracked")])
9525
9526 (define_insn "*basr_r"
9527 [(set (match_operand 0 "" "")
9528 (call (mem:QI (match_operand 1 "address_operand" "ZQZR"))
9529 (match_operand 2 "const_int_operand" "n")))
9530 (clobber (match_operand 3 "register_operand" "=r"))]
9531 "!SIBLING_CALL_P (insn) && GET_MODE (operands[3]) == Pmode"
9532 {
9533 if (get_attr_op_type (insn) == OP_TYPE_RR)
9534 return "basr\t%3,%1";
9535 else
9536 return "bas\t%3,%a1";
9537 }
9538 [(set (attr "op_type")
9539 (if_then_else (match_operand 1 "register_operand" "")
9540 (const_string "RR") (const_string "RX")))
9541 (set_attr "type" "jsr")
9542 (set_attr "atype" "agen")
9543 (set_attr "z196prop" "z196_cracked")])
9544
9545 ;;
9546 ;;- Thread-local storage support.
9547 ;;
9548
9549 (define_expand "get_thread_pointer<mode>"
9550 [(set (match_operand:P 0 "nonimmediate_operand" "") (reg:P TP_REGNUM))]
9551 ""
9552 "")
9553
9554 (define_expand "set_thread_pointer<mode>"
9555 [(set (reg:P TP_REGNUM) (match_operand:P 0 "nonimmediate_operand" ""))
9556 (set (reg:P TP_REGNUM) (unspec_volatile:P [(reg:P TP_REGNUM)] UNSPECV_SET_TP))]
9557 ""
9558 "")
9559
9560 (define_insn "*set_tp"
9561 [(set (reg TP_REGNUM) (unspec_volatile [(reg TP_REGNUM)] UNSPECV_SET_TP))]
9562 ""
9563 ""
9564 [(set_attr "type" "none")
9565 (set_attr "length" "0")])
9566
9567 (define_insn "*tls_load_64"
9568 [(set (match_operand:DI 0 "register_operand" "=d")
9569 (unspec:DI [(match_operand:DI 1 "memory_operand" "RT")
9570 (match_operand:DI 2 "" "")]
9571 UNSPEC_TLS_LOAD))]
9572 "TARGET_64BIT"
9573 "lg\t%0,%1%J2"
9574 [(set_attr "op_type" "RXE")
9575 (set_attr "z10prop" "z10_fwd_A3")])
9576
9577 (define_insn "*tls_load_31"
9578 [(set (match_operand:SI 0 "register_operand" "=d,d")
9579 (unspec:SI [(match_operand:SI 1 "memory_operand" "R,T")
9580 (match_operand:SI 2 "" "")]
9581 UNSPEC_TLS_LOAD))]
9582 "!TARGET_64BIT"
9583 "@
9584 l\t%0,%1%J2
9585 ly\t%0,%1%J2"
9586 [(set_attr "op_type" "RX,RXY")
9587 (set_attr "type" "load")
9588 (set_attr "z10prop" "z10_fwd_A3,z10_fwd_A3")])
9589
9590 (define_insn "*bras_tls"
9591 [(set (match_operand 0 "" "")
9592 (call (mem:QI (match_operand 1 "bras_sym_operand" "X"))
9593 (match_operand 2 "const_int_operand" "n")))
9594 (clobber (match_operand 3 "register_operand" "=r"))
9595 (use (match_operand 4 "" ""))]
9596 "!SIBLING_CALL_P (insn)
9597 && TARGET_SMALL_EXEC
9598 && GET_MODE (operands[3]) == Pmode"
9599 "bras\t%3,%1%J4"
9600 [(set_attr "op_type" "RI")
9601 (set_attr "type" "jsr")
9602 (set_attr "z196prop" "z196_cracked")])
9603
9604 (define_insn "*brasl_tls"
9605 [(set (match_operand 0 "" "")
9606 (call (mem:QI (match_operand 1 "bras_sym_operand" "X"))
9607 (match_operand 2 "const_int_operand" "n")))
9608 (clobber (match_operand 3 "register_operand" "=r"))
9609 (use (match_operand 4 "" ""))]
9610 "!SIBLING_CALL_P (insn)
9611 && TARGET_CPU_ZARCH
9612 && GET_MODE (operands[3]) == Pmode"
9613 "brasl\t%3,%1%J4"
9614 [(set_attr "op_type" "RIL")
9615 (set_attr "type" "jsr")
9616 (set_attr "z196prop" "z196_cracked")])
9617
9618 (define_insn "*basr_tls"
9619 [(set (match_operand 0 "" "")
9620 (call (mem:QI (match_operand 1 "address_operand" "ZQZR"))
9621 (match_operand 2 "const_int_operand" "n")))
9622 (clobber (match_operand 3 "register_operand" "=r"))
9623 (use (match_operand 4 "" ""))]
9624 "!SIBLING_CALL_P (insn) && GET_MODE (operands[3]) == Pmode"
9625 {
9626 if (get_attr_op_type (insn) == OP_TYPE_RR)
9627 return "basr\t%3,%1%J4";
9628 else
9629 return "bas\t%3,%a1%J4";
9630 }
9631 [(set (attr "op_type")
9632 (if_then_else (match_operand 1 "register_operand" "")
9633 (const_string "RR") (const_string "RX")))
9634 (set_attr "type" "jsr")
9635 (set_attr "atype" "agen")
9636 (set_attr "z196prop" "z196_cracked")])
9637
9638 ;;
9639 ;;- Atomic operations
9640 ;;
9641
9642 ;
9643 ; memory barrier patterns.
9644 ;
9645
9646 (define_expand "mem_signal_fence"
9647 [(match_operand:SI 0 "const_int_operand")] ;; model
9648 ""
9649 {
9650 /* The s390 memory model is strong enough not to require any
9651 barrier in order to synchronize a thread with itself. */
9652 DONE;
9653 })
9654
9655 (define_expand "mem_thread_fence"
9656 [(match_operand:SI 0 "const_int_operand")] ;; model
9657 ""
9658 {
9659 /* Unless this is a SEQ_CST fence, the s390 memory model is strong
9660 enough not to require barriers of any kind. */
9661 if (is_mm_seq_cst (memmodel_from_int (INTVAL (operands[0]))))
9662 {
9663 rtx mem = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
9664 MEM_VOLATILE_P (mem) = 1;
9665 emit_insn (gen_mem_thread_fence_1 (mem));
9666 }
9667 DONE;
9668 })
9669
9670 ; Although bcr is superscalar on Z10, this variant will never
9671 ; become part of an execution group.
9672 ; With z196 we can make use of the fast-BCR-serialization facility.
9673 ; This allows for a slightly faster sync which is sufficient for our
9674 ; purposes.
9675 (define_insn "mem_thread_fence_1"
9676 [(set (match_operand:BLK 0 "" "")
9677 (unspec:BLK [(match_dup 0)] UNSPEC_MB))]
9678 ""
9679 {
9680 if (TARGET_Z196)
9681 return "bcr\t14,0";
9682 else
9683 return "bcr\t15,0";
9684 }
9685 [(set_attr "op_type" "RR")
9686 (set_attr "mnemonic" "bcr_flush")
9687 (set_attr "z196prop" "z196_alone")])
9688
9689 ;
9690 ; atomic load/store operations
9691 ;
9692
9693 ; Atomic loads need not examine the memory model at all.
9694 (define_expand "atomic_load<mode>"
9695 [(match_operand:DINT 0 "register_operand") ;; output
9696 (match_operand:DINT 1 "memory_operand") ;; memory
9697 (match_operand:SI 2 "const_int_operand")] ;; model
9698 ""
9699 {
9700 if (MEM_ALIGN (operands[1]) < GET_MODE_BITSIZE (GET_MODE (operands[1])))
9701 FAIL;
9702
9703 if (<MODE>mode == TImode)
9704 emit_insn (gen_atomic_loadti_1 (operands[0], operands[1]));
9705 else if (<MODE>mode == DImode && !TARGET_ZARCH)
9706 emit_insn (gen_atomic_loaddi_1 (operands[0], operands[1]));
9707 else
9708 emit_move_insn (operands[0], operands[1]);
9709 DONE;
9710 })
9711
9712 ; Different from movdi_31 in that we want no splitters.
9713 (define_insn "atomic_loaddi_1"
9714 [(set (match_operand:DI 0 "register_operand" "=d,d,!*f,!*f")
9715 (unspec:DI [(match_operand:DI 1 "memory_operand" "Q,S,R,T")]
9716 UNSPEC_MOVA))]
9717 "!TARGET_ZARCH"
9718 "@
9719 lm\t%0,%M0,%S1
9720 lmy\t%0,%M0,%S1
9721 ld\t%0,%1
9722 ldy\t%0,%1"
9723 [(set_attr "op_type" "RS,RSY,RS,RSY")
9724 (set_attr "type" "lm,lm,floaddf,floaddf")])
9725
9726 (define_insn "atomic_loadti_1"
9727 [(set (match_operand:TI 0 "register_operand" "=r")
9728 (unspec:TI [(match_operand:TI 1 "memory_operand" "RT")]
9729 UNSPEC_MOVA))]
9730 "TARGET_ZARCH"
9731 "lpq\t%0,%1"
9732 [(set_attr "op_type" "RXY")
9733 (set_attr "type" "other")])
9734
9735 ; Atomic stores must(?) enforce sequential consistency.
9736 (define_expand "atomic_store<mode>"
9737 [(match_operand:DINT 0 "memory_operand") ;; memory
9738 (match_operand:DINT 1 "register_operand") ;; input
9739 (match_operand:SI 2 "const_int_operand")] ;; model
9740 ""
9741 {
9742 enum memmodel model = memmodel_from_int (INTVAL (operands[2]));
9743
9744 if (MEM_ALIGN (operands[0]) < GET_MODE_BITSIZE (GET_MODE (operands[0])))
9745 FAIL;
9746
9747 if (<MODE>mode == TImode)
9748 emit_insn (gen_atomic_storeti_1 (operands[0], operands[1]));
9749 else if (<MODE>mode == DImode && !TARGET_ZARCH)
9750 emit_insn (gen_atomic_storedi_1 (operands[0], operands[1]));
9751 else
9752 emit_move_insn (operands[0], operands[1]);
9753 if (is_mm_seq_cst (model))
9754 emit_insn (gen_mem_thread_fence (operands[2]));
9755 DONE;
9756 })
9757
9758 ; Different from movdi_31 in that we want no splitters.
9759 (define_insn "atomic_storedi_1"
9760 [(set (match_operand:DI 0 "memory_operand" "=Q,S,R,T")
9761 (unspec:DI [(match_operand:DI 1 "register_operand" "d,d,!*f,!*f")]
9762 UNSPEC_MOVA))]
9763 "!TARGET_ZARCH"
9764 "@
9765 stm\t%1,%N1,%S0
9766 stmy\t%1,%N1,%S0
9767 std %1,%0
9768 stdy %1,%0"
9769 [(set_attr "op_type" "RS,RSY,RS,RSY")
9770 (set_attr "type" "stm,stm,fstoredf,fstoredf")])
9771
9772 (define_insn "atomic_storeti_1"
9773 [(set (match_operand:TI 0 "memory_operand" "=RT")
9774 (unspec:TI [(match_operand:TI 1 "register_operand" "r")]
9775 UNSPEC_MOVA))]
9776 "TARGET_ZARCH"
9777 "stpq\t%1,%0"
9778 [(set_attr "op_type" "RXY")
9779 (set_attr "type" "other")])
9780
9781 ;
9782 ; compare and swap patterns.
9783 ;
9784
9785 (define_expand "atomic_compare_and_swap<mode>"
9786 [(match_operand:SI 0 "register_operand") ;; bool success output
9787 (match_operand:DGPR 1 "nonimmediate_operand");; oldval output
9788 (match_operand:DGPR 2 "memory_operand") ;; memory
9789 (match_operand:DGPR 3 "register_operand") ;; expected intput
9790 (match_operand:DGPR 4 "register_operand") ;; newval intput
9791 (match_operand:SI 5 "const_int_operand") ;; is_weak
9792 (match_operand:SI 6 "const_int_operand") ;; success model
9793 (match_operand:SI 7 "const_int_operand")] ;; failure model
9794 ""
9795 {
9796 rtx cc, cmp, output = operands[1];
9797
9798 if (!register_operand (output, <MODE>mode))
9799 output = gen_reg_rtx (<MODE>mode);
9800
9801 if (MEM_ALIGN (operands[2]) < GET_MODE_BITSIZE (GET_MODE (operands[2])))
9802 FAIL;
9803
9804 emit_insn (gen_atomic_compare_and_swap<mode>_internal
9805 (output, operands[2], operands[3], operands[4]));
9806
9807 /* We deliberately accept non-register operands in the predicate
9808 to ensure the write back to the output operand happens *before*
9809 the store-flags code below. This makes it easier for combine
9810 to merge the store-flags code with a potential test-and-branch
9811 pattern following (immediately!) afterwards. */
9812 if (output != operands[1])
9813 emit_move_insn (operands[1], output);
9814
9815 cc = gen_rtx_REG (CCZ1mode, CC_REGNUM);
9816 cmp = gen_rtx_EQ (SImode, cc, const0_rtx);
9817 emit_insn (gen_cstorecc4 (operands[0], cmp, cc, const0_rtx));
9818 DONE;
9819 })
9820
9821 (define_expand "atomic_compare_and_swap<mode>"
9822 [(match_operand:SI 0 "register_operand") ;; bool success output
9823 (match_operand:HQI 1 "nonimmediate_operand") ;; oldval output
9824 (match_operand:HQI 2 "memory_operand") ;; memory
9825 (match_operand:HQI 3 "general_operand") ;; expected intput
9826 (match_operand:HQI 4 "general_operand") ;; newval intput
9827 (match_operand:SI 5 "const_int_operand") ;; is_weak
9828 (match_operand:SI 6 "const_int_operand") ;; success model
9829 (match_operand:SI 7 "const_int_operand")] ;; failure model
9830 ""
9831 {
9832 s390_expand_cs_hqi (<MODE>mode, operands[0], operands[1], operands[2],
9833 operands[3], operands[4], INTVAL (operands[5]));
9834 DONE;
9835 })
9836
9837 (define_expand "atomic_compare_and_swap<mode>_internal"
9838 [(parallel
9839 [(set (match_operand:DGPR 0 "register_operand")
9840 (match_operand:DGPR 1 "memory_operand"))
9841 (set (match_dup 1)
9842 (unspec_volatile:DGPR
9843 [(match_dup 1)
9844 (match_operand:DGPR 2 "register_operand")
9845 (match_operand:DGPR 3 "register_operand")]
9846 UNSPECV_CAS))
9847 (set (reg:CCZ1 CC_REGNUM)
9848 (compare:CCZ1 (match_dup 1) (match_dup 2)))])]
9849 "")
9850
9851 ; cdsg, csg
9852 (define_insn "*atomic_compare_and_swap<mode>_1"
9853 [(set (match_operand:TDI 0 "register_operand" "=r")
9854 (match_operand:TDI 1 "memory_operand" "+QS"))
9855 (set (match_dup 1)
9856 (unspec_volatile:TDI
9857 [(match_dup 1)
9858 (match_operand:TDI 2 "register_operand" "0")
9859 (match_operand:TDI 3 "register_operand" "r")]
9860 UNSPECV_CAS))
9861 (set (reg:CCZ1 CC_REGNUM)
9862 (compare:CCZ1 (match_dup 1) (match_dup 2)))]
9863 "TARGET_ZARCH"
9864 "c<td>sg\t%0,%3,%S1"
9865 [(set_attr "op_type" "RSY")
9866 (set_attr "type" "sem")])
9867
9868 ; cds, cdsy
9869 (define_insn "*atomic_compare_and_swapdi_2"
9870 [(set (match_operand:DI 0 "register_operand" "=r,r")
9871 (match_operand:DI 1 "memory_operand" "+Q,S"))
9872 (set (match_dup 1)
9873 (unspec_volatile:DI
9874 [(match_dup 1)
9875 (match_operand:DI 2 "register_operand" "0,0")
9876 (match_operand:DI 3 "register_operand" "r,r")]
9877 UNSPECV_CAS))
9878 (set (reg:CCZ1 CC_REGNUM)
9879 (compare:CCZ1 (match_dup 1) (match_dup 2)))]
9880 "!TARGET_ZARCH"
9881 "@
9882 cds\t%0,%3,%S1
9883 cdsy\t%0,%3,%S1"
9884 [(set_attr "op_type" "RS,RSY")
9885 (set_attr "type" "sem")])
9886
9887 ; cs, csy
9888 (define_insn "*atomic_compare_and_swapsi_3"
9889 [(set (match_operand:SI 0 "register_operand" "=r,r")
9890 (match_operand:SI 1 "memory_operand" "+Q,S"))
9891 (set (match_dup 1)
9892 (unspec_volatile:SI
9893 [(match_dup 1)
9894 (match_operand:SI 2 "register_operand" "0,0")
9895 (match_operand:SI 3 "register_operand" "r,r")]
9896 UNSPECV_CAS))
9897 (set (reg:CCZ1 CC_REGNUM)
9898 (compare:CCZ1 (match_dup 1) (match_dup 2)))]
9899 ""
9900 "@
9901 cs\t%0,%3,%S1
9902 csy\t%0,%3,%S1"
9903 [(set_attr "op_type" "RS,RSY")
9904 (set_attr "type" "sem")])
9905
9906 ;
9907 ; Other atomic instruction patterns.
9908 ;
9909
9910 ; z196 load and add, xor, or and and instructions
9911
9912 (define_expand "atomic_fetch_<atomic><mode>"
9913 [(match_operand:GPR 0 "register_operand") ;; val out
9914 (ATOMIC_Z196:GPR
9915 (match_operand:GPR 1 "memory_operand") ;; memory
9916 (match_operand:GPR 2 "register_operand")) ;; val in
9917 (match_operand:SI 3 "const_int_operand")] ;; model
9918 "TARGET_Z196"
9919 {
9920 if (MEM_ALIGN (operands[1]) < GET_MODE_BITSIZE (GET_MODE (operands[1])))
9921 FAIL;
9922
9923 emit_insn (gen_atomic_fetch_<atomic><mode>_iaf
9924 (operands[0], operands[1], operands[2]));
9925 DONE;
9926 })
9927
9928 ; lan, lang, lao, laog, lax, laxg, laa, laag
9929 (define_insn "atomic_fetch_<atomic><mode>_iaf"
9930 [(set (match_operand:GPR 0 "register_operand" "=d")
9931 (match_operand:GPR 1 "memory_operand" "+QS"))
9932 (set (match_dup 1)
9933 (unspec_volatile:GPR
9934 [(ATOMIC_Z196:GPR (match_dup 1)
9935 (match_operand:GPR 2 "general_operand" "d"))]
9936 UNSPECV_ATOMIC_OP))
9937 (clobber (reg:CC CC_REGNUM))]
9938 "TARGET_Z196"
9939 "la<noxa><g>\t%0,%2,%1"
9940 [(set_attr "op_type" "RSY")
9941 (set_attr "type" "sem")])
9942
9943 ;; For SImode and larger, the optabs.c code will do just fine in
9944 ;; expanding a compare-and-swap loop. For QI/HImode, we can do
9945 ;; better by expanding our own loop.
9946
9947 (define_expand "atomic_<atomic><mode>"
9948 [(ATOMIC:HQI
9949 (match_operand:HQI 0 "memory_operand") ;; memory
9950 (match_operand:HQI 1 "general_operand")) ;; val in
9951 (match_operand:SI 2 "const_int_operand")] ;; model
9952 ""
9953 {
9954 s390_expand_atomic (<MODE>mode, <CODE>, NULL_RTX, operands[0],
9955 operands[1], false);
9956 DONE;
9957 })
9958
9959 (define_expand "atomic_fetch_<atomic><mode>"
9960 [(match_operand:HQI 0 "register_operand") ;; val out
9961 (ATOMIC:HQI
9962 (match_operand:HQI 1 "memory_operand") ;; memory
9963 (match_operand:HQI 2 "general_operand")) ;; val in
9964 (match_operand:SI 3 "const_int_operand")] ;; model
9965 ""
9966 {
9967 s390_expand_atomic (<MODE>mode, <CODE>, operands[0], operands[1],
9968 operands[2], false);
9969 DONE;
9970 })
9971
9972 (define_expand "atomic_<atomic>_fetch<mode>"
9973 [(match_operand:HQI 0 "register_operand") ;; val out
9974 (ATOMIC:HQI
9975 (match_operand:HQI 1 "memory_operand") ;; memory
9976 (match_operand:HQI 2 "general_operand")) ;; val in
9977 (match_operand:SI 3 "const_int_operand")] ;; model
9978 ""
9979 {
9980 s390_expand_atomic (<MODE>mode, <CODE>, operands[0], operands[1],
9981 operands[2], true);
9982 DONE;
9983 })
9984
9985 (define_expand "atomic_exchange<mode>"
9986 [(match_operand:HQI 0 "register_operand") ;; val out
9987 (match_operand:HQI 1 "memory_operand") ;; memory
9988 (match_operand:HQI 2 "general_operand") ;; val in
9989 (match_operand:SI 3 "const_int_operand")] ;; model
9990 ""
9991 {
9992 s390_expand_atomic (<MODE>mode, SET, operands[0], operands[1],
9993 operands[2], false);
9994 DONE;
9995 })
9996
9997 ;;
9998 ;;- Miscellaneous instructions.
9999 ;;
10000
10001 ;
10002 ; allocate stack instruction pattern(s).
10003 ;
10004
10005 (define_expand "allocate_stack"
10006 [(match_operand 0 "general_operand" "")
10007 (match_operand 1 "general_operand" "")]
10008 "TARGET_BACKCHAIN"
10009 {
10010 rtx temp = gen_reg_rtx (Pmode);
10011
10012 emit_move_insn (temp, s390_back_chain_rtx ());
10013 anti_adjust_stack (operands[1]);
10014 emit_move_insn (s390_back_chain_rtx (), temp);
10015
10016 emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
10017 DONE;
10018 })
10019
10020
10021 ;
10022 ; setjmp instruction pattern.
10023 ;
10024
10025 (define_expand "builtin_setjmp_receiver"
10026 [(match_operand 0 "" "")]
10027 "flag_pic"
10028 {
10029 emit_insn (s390_load_got ());
10030 emit_use (pic_offset_table_rtx);
10031 DONE;
10032 })
10033
10034 ;; These patterns say how to save and restore the stack pointer. We need not
10035 ;; save the stack pointer at function level since we are careful to
10036 ;; preserve the backchain. At block level, we have to restore the backchain
10037 ;; when we restore the stack pointer.
10038 ;;
10039 ;; For nonlocal gotos, we must save both the stack pointer and its
10040 ;; backchain and restore both. Note that in the nonlocal case, the
10041 ;; save area is a memory location.
10042
10043 (define_expand "save_stack_function"
10044 [(match_operand 0 "general_operand" "")
10045 (match_operand 1 "general_operand" "")]
10046 ""
10047 "DONE;")
10048
10049 (define_expand "restore_stack_function"
10050 [(match_operand 0 "general_operand" "")
10051 (match_operand 1 "general_operand" "")]
10052 ""
10053 "DONE;")
10054
10055 (define_expand "restore_stack_block"
10056 [(match_operand 0 "register_operand" "")
10057 (match_operand 1 "register_operand" "")]
10058 "TARGET_BACKCHAIN"
10059 {
10060 rtx temp = gen_reg_rtx (Pmode);
10061
10062 emit_move_insn (temp, s390_back_chain_rtx ());
10063 emit_move_insn (operands[0], operands[1]);
10064 emit_move_insn (s390_back_chain_rtx (), temp);
10065
10066 DONE;
10067 })
10068
10069 (define_expand "save_stack_nonlocal"
10070 [(match_operand 0 "memory_operand" "")
10071 (match_operand 1 "register_operand" "")]
10072 ""
10073 {
10074 rtx base = gen_rtx_REG (Pmode, BASE_REGNUM);
10075
10076 /* Copy the backchain to the first word, sp to the second and the
10077 literal pool base to the third. */
10078
10079 rtx save_bc = adjust_address (operands[0], Pmode, 0);
10080 rtx save_sp = adjust_address (operands[0], Pmode, GET_MODE_SIZE (Pmode));
10081 rtx save_bp = adjust_address (operands[0], Pmode, 2 * GET_MODE_SIZE (Pmode));
10082
10083 if (TARGET_BACKCHAIN)
10084 emit_move_insn (save_bc, force_reg (Pmode, s390_back_chain_rtx ()));
10085
10086 emit_move_insn (save_sp, operands[1]);
10087 emit_move_insn (save_bp, base);
10088
10089 DONE;
10090 })
10091
10092 (define_expand "restore_stack_nonlocal"
10093 [(match_operand 0 "register_operand" "")
10094 (match_operand 1 "memory_operand" "")]
10095 ""
10096 {
10097 rtx base = gen_rtx_REG (Pmode, BASE_REGNUM);
10098 rtx temp = NULL_RTX;
10099
10100 /* Restore the backchain from the first word, sp from the second and the
10101 literal pool base from the third. */
10102
10103 rtx save_bc = adjust_address (operands[1], Pmode, 0);
10104 rtx save_sp = adjust_address (operands[1], Pmode, GET_MODE_SIZE (Pmode));
10105 rtx save_bp = adjust_address (operands[1], Pmode, 2 * GET_MODE_SIZE (Pmode));
10106
10107 if (TARGET_BACKCHAIN)
10108 temp = force_reg (Pmode, save_bc);
10109
10110 emit_move_insn (base, save_bp);
10111 emit_move_insn (operands[0], save_sp);
10112
10113 if (temp)
10114 emit_move_insn (s390_back_chain_rtx (), temp);
10115
10116 emit_use (base);
10117 DONE;
10118 })
10119
10120 (define_expand "exception_receiver"
10121 [(const_int 0)]
10122 ""
10123 {
10124 s390_set_has_landing_pad_p (true);
10125 DONE;
10126 })
10127
10128 ;
10129 ; nop instruction pattern(s).
10130 ;
10131
10132 (define_insn "nop"
10133 [(const_int 0)]
10134 ""
10135 "lr\t0,0"
10136 [(set_attr "op_type" "RR")
10137 (set_attr "z10prop" "z10_fr_E1")])
10138
10139 (define_insn "nop1"
10140 [(const_int 1)]
10141 ""
10142 "lr\t1,1"
10143 [(set_attr "op_type" "RR")])
10144
10145 ;;- Undeletable nops (used for hotpatching)
10146
10147 (define_insn "nop_2_byte"
10148 [(unspec_volatile [(const_int 0)] UNSPECV_NOP_2_BYTE)]
10149 ""
10150 "nopr\t%%r7"
10151 [(set_attr "op_type" "RR")])
10152
10153 (define_insn "nop_4_byte"
10154 [(unspec_volatile [(const_int 0)] UNSPECV_NOP_4_BYTE)]
10155 ""
10156 "nop\t0"
10157 [(set_attr "op_type" "RX")])
10158
10159 (define_insn "nop_6_byte"
10160 [(unspec_volatile [(const_int 0)] UNSPECV_NOP_6_BYTE)]
10161 "TARGET_CPU_ZARCH"
10162 "brcl\t0, 0"
10163 [(set_attr "op_type" "RIL")])
10164
10165
10166 ;
10167 ; Special literal pool access instruction pattern(s).
10168 ;
10169
10170 (define_insn "*pool_entry"
10171 [(unspec_volatile [(match_operand 0 "consttable_operand" "X")]
10172 UNSPECV_POOL_ENTRY)]
10173 ""
10174 {
10175 machine_mode mode = GET_MODE (PATTERN (insn));
10176 unsigned int align = GET_MODE_BITSIZE (mode);
10177 s390_output_pool_entry (operands[0], mode, align);
10178 return "";
10179 }
10180 [(set (attr "length")
10181 (symbol_ref "GET_MODE_SIZE (GET_MODE (PATTERN (insn)))"))])
10182
10183 (define_insn "pool_align"
10184 [(unspec_volatile [(match_operand 0 "const_int_operand" "n")]
10185 UNSPECV_POOL_ALIGN)]
10186 ""
10187 ".align\t%0"
10188 [(set (attr "length") (symbol_ref "INTVAL (operands[0])"))])
10189
10190 (define_insn "pool_section_start"
10191 [(unspec_volatile [(const_int 1)] UNSPECV_POOL_SECTION)]
10192 ""
10193 ".section\t.rodata"
10194 [(set_attr "length" "0")])
10195
10196 (define_insn "pool_section_end"
10197 [(unspec_volatile [(const_int 0)] UNSPECV_POOL_SECTION)]
10198 ""
10199 ".previous"
10200 [(set_attr "length" "0")])
10201
10202 (define_insn "main_base_31_small"
10203 [(set (match_operand 0 "register_operand" "=a")
10204 (unspec [(label_ref (match_operand 1 "" ""))] UNSPEC_MAIN_BASE))]
10205 "!TARGET_CPU_ZARCH && GET_MODE (operands[0]) == Pmode"
10206 "basr\t%0,0"
10207 [(set_attr "op_type" "RR")
10208 (set_attr "type" "la")
10209 (set_attr "z196prop" "z196_cracked")])
10210
10211 (define_insn "main_base_31_large"
10212 [(set (match_operand 0 "register_operand" "=a")
10213 (unspec [(label_ref (match_operand 1 "" ""))] UNSPEC_MAIN_BASE))
10214 (set (pc) (label_ref (match_operand 2 "" "")))]
10215 "!TARGET_CPU_ZARCH && GET_MODE (operands[0]) == Pmode"
10216 "bras\t%0,%2"
10217 [(set_attr "op_type" "RI")
10218 (set_attr "z196prop" "z196_cracked")])
10219
10220 (define_insn "main_base_64"
10221 [(set (match_operand 0 "register_operand" "=a")
10222 (unspec [(label_ref (match_operand 1 "" ""))] UNSPEC_MAIN_BASE))]
10223 "TARGET_CPU_ZARCH && GET_MODE (operands[0]) == Pmode"
10224 "larl\t%0,%1"
10225 [(set_attr "op_type" "RIL")
10226 (set_attr "type" "larl")
10227 (set_attr "z10prop" "z10_fwd_A1")])
10228
10229 (define_insn "main_pool"
10230 [(set (match_operand 0 "register_operand" "=a")
10231 (unspec_volatile [(const_int 0)] UNSPECV_MAIN_POOL))]
10232 "GET_MODE (operands[0]) == Pmode"
10233 {
10234 gcc_unreachable ();
10235 }
10236 [(set (attr "type")
10237 (if_then_else (match_test "TARGET_CPU_ZARCH")
10238 (const_string "larl") (const_string "la")))])
10239
10240 (define_insn "reload_base_31"
10241 [(set (match_operand 0 "register_operand" "=a")
10242 (unspec [(label_ref (match_operand 1 "" ""))] UNSPEC_RELOAD_BASE))]
10243 "!TARGET_CPU_ZARCH && GET_MODE (operands[0]) == Pmode"
10244 "basr\t%0,0\;la\t%0,%1-.(%0)"
10245 [(set_attr "length" "6")
10246 (set_attr "type" "la")
10247 (set_attr "z196prop" "z196_cracked")])
10248
10249 (define_insn "reload_base_64"
10250 [(set (match_operand 0 "register_operand" "=a")
10251 (unspec [(label_ref (match_operand 1 "" ""))] UNSPEC_RELOAD_BASE))]
10252 "TARGET_CPU_ZARCH && GET_MODE (operands[0]) == Pmode"
10253 "larl\t%0,%1"
10254 [(set_attr "op_type" "RIL")
10255 (set_attr "type" "larl")
10256 (set_attr "z10prop" "z10_fwd_A1")])
10257
10258 (define_insn "pool"
10259 [(unspec_volatile [(match_operand 0 "const_int_operand" "n")] UNSPECV_POOL)]
10260 ""
10261 {
10262 gcc_unreachable ();
10263 }
10264 [(set (attr "length") (symbol_ref "INTVAL (operands[0])"))])
10265
10266 ;;
10267 ;; Insns related to generating the function prologue and epilogue.
10268 ;;
10269
10270
10271 (define_expand "prologue"
10272 [(use (const_int 0))]
10273 ""
10274 "s390_emit_prologue (); DONE;")
10275
10276 (define_expand "epilogue"
10277 [(use (const_int 1))]
10278 ""
10279 "s390_emit_epilogue (false); DONE;")
10280
10281 (define_expand "sibcall_epilogue"
10282 [(use (const_int 0))]
10283 ""
10284 "s390_emit_epilogue (true); DONE;")
10285
10286 ;; A direct return instruction, without using an epilogue.
10287 (define_insn "<code>"
10288 [(ANY_RETURN)]
10289 "s390_can_use_<code>_insn ()"
10290 "br\t%%r14"
10291 [(set_attr "op_type" "RR")
10292 (set_attr "type" "jsr")
10293 (set_attr "atype" "agen")])
10294
10295 (define_insn "*return"
10296 [(return)
10297 (use (match_operand 0 "register_operand" "a"))]
10298 "GET_MODE (operands[0]) == Pmode"
10299 "br\t%0"
10300 [(set_attr "op_type" "RR")
10301 (set_attr "type" "jsr")
10302 (set_attr "atype" "agen")])
10303
10304
10305 ;; Instruction definition to extend a 31-bit pointer into a 64-bit
10306 ;; pointer. This is used for compatibility.
10307
10308 (define_expand "ptr_extend"
10309 [(set (match_operand:DI 0 "register_operand" "=r")
10310 (match_operand:SI 1 "register_operand" "r"))]
10311 "TARGET_64BIT"
10312 {
10313 emit_insn (gen_anddi3 (operands[0],
10314 gen_lowpart (DImode, operands[1]),
10315 GEN_INT (0x7fffffff)));
10316 DONE;
10317 })
10318
10319 ;; Instruction definition to expand eh_return macro to support
10320 ;; swapping in special linkage return addresses.
10321
10322 (define_expand "eh_return"
10323 [(use (match_operand 0 "register_operand" ""))]
10324 "TARGET_TPF"
10325 {
10326 s390_emit_tpf_eh_return (operands[0]);
10327 DONE;
10328 })
10329
10330 ;
10331 ; Stack Protector Patterns
10332 ;
10333
10334 (define_expand "stack_protect_set"
10335 [(set (match_operand 0 "memory_operand" "")
10336 (match_operand 1 "memory_operand" ""))]
10337 ""
10338 {
10339 #ifdef TARGET_THREAD_SSP_OFFSET
10340 operands[1]
10341 = gen_rtx_MEM (Pmode, gen_rtx_PLUS (Pmode, s390_get_thread_pointer (),
10342 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
10343 #endif
10344 if (TARGET_64BIT)
10345 emit_insn (gen_stack_protect_setdi (operands[0], operands[1]));
10346 else
10347 emit_insn (gen_stack_protect_setsi (operands[0], operands[1]));
10348
10349 DONE;
10350 })
10351
10352 (define_insn "stack_protect_set<mode>"
10353 [(set (match_operand:DSI 0 "memory_operand" "=Q")
10354 (unspec:DSI [(match_operand:DSI 1 "memory_operand" "Q")] UNSPEC_SP_SET))]
10355 ""
10356 "mvc\t%O0(%G0,%R0),%S1"
10357 [(set_attr "op_type" "SS")])
10358
10359 (define_expand "stack_protect_test"
10360 [(set (reg:CC CC_REGNUM)
10361 (compare (match_operand 0 "memory_operand" "")
10362 (match_operand 1 "memory_operand" "")))
10363 (match_operand 2 "" "")]
10364 ""
10365 {
10366 rtx cc_reg, test;
10367 #ifdef TARGET_THREAD_SSP_OFFSET
10368 operands[1]
10369 = gen_rtx_MEM (Pmode, gen_rtx_PLUS (Pmode, s390_get_thread_pointer (),
10370 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
10371 #endif
10372 if (TARGET_64BIT)
10373 emit_insn (gen_stack_protect_testdi (operands[0], operands[1]));
10374 else
10375 emit_insn (gen_stack_protect_testsi (operands[0], operands[1]));
10376
10377 cc_reg = gen_rtx_REG (CCZmode, CC_REGNUM);
10378 test = gen_rtx_EQ (VOIDmode, cc_reg, const0_rtx);
10379 emit_jump_insn (gen_cbranchcc4 (test, cc_reg, const0_rtx, operands[2]));
10380 DONE;
10381 })
10382
10383 (define_insn "stack_protect_test<mode>"
10384 [(set (reg:CCZ CC_REGNUM)
10385 (unspec:CCZ [(match_operand:DSI 0 "memory_operand" "Q")
10386 (match_operand:DSI 1 "memory_operand" "Q")] UNSPEC_SP_TEST))]
10387 ""
10388 "clc\t%O0(%G0,%R0),%S1"
10389 [(set_attr "op_type" "SS")])
10390
10391 ; This is used in s390_emit_prologue in order to prevent insns
10392 ; adjusting the stack pointer to be moved over insns writing stack
10393 ; slots using a copy of the stack pointer in a different register.
10394 (define_insn "stack_tie"
10395 [(set (match_operand:BLK 0 "memory_operand" "+m")
10396 (unspec:BLK [(match_dup 0)] UNSPEC_TIE))]
10397 ""
10398 ""
10399 [(set_attr "length" "0")])
10400
10401
10402 ;
10403 ; Data prefetch patterns
10404 ;
10405
10406 (define_insn "prefetch"
10407 [(prefetch (match_operand 0 "address_operand" "ZQZRZSZT,X")
10408 (match_operand:SI 1 "const_int_operand" " n,n")
10409 (match_operand:SI 2 "const_int_operand" " n,n"))]
10410 "TARGET_Z10"
10411 {
10412 switch (which_alternative)
10413 {
10414 case 0:
10415 return INTVAL (operands[1]) == 1 ? "pfd\t2,%a0" : "pfd\t1,%a0";
10416 case 1:
10417 if (larl_operand (operands[0], Pmode))
10418 return INTVAL (operands[1]) == 1 ? "pfdrl\t2,%a0" : "pfdrl\t1,%a0";
10419 default:
10420
10421 /* This might be reached for symbolic operands with an odd
10422 addend. We simply omit the prefetch for such rare cases. */
10423
10424 return "";
10425 }
10426 }
10427 [(set_attr "type" "load,larl")
10428 (set_attr "op_type" "RXY,RIL")
10429 (set_attr "z10prop" "z10_super")
10430 (set_attr "z196prop" "z196_alone")])
10431
10432
10433 ;
10434 ; Byte swap instructions
10435 ;
10436
10437 (define_insn "bswap<mode>2"
10438 [(set (match_operand:GPR 0 "register_operand" "=d, d")
10439 (bswap:GPR (match_operand:GPR 1 "nonimmediate_operand" " d,RT")))]
10440 "TARGET_CPU_ZARCH"
10441 "@
10442 lrv<g>r\t%0,%1
10443 lrv<g>\t%0,%1"
10444 [(set_attr "type" "*,load")
10445 (set_attr "op_type" "RRE,RXY")
10446 (set_attr "z10prop" "z10_super")])
10447
10448
10449 ;
10450 ; Population count instruction
10451 ;
10452
10453 ; The S/390 popcount instruction counts the bits of op1 in 8 byte
10454 ; portions and stores the result in the corresponding bytes in op0.
10455 (define_insn "*popcount<mode>"
10456 [(set (match_operand:INT 0 "register_operand" "=d")
10457 (unspec:INT [(match_operand:INT 1 "register_operand" "d")] UNSPEC_POPCNT))
10458 (clobber (reg:CC CC_REGNUM))]
10459 "TARGET_Z196"
10460 "popcnt\t%0,%1"
10461 [(set_attr "op_type" "RRE")])
10462
10463 (define_expand "popcountdi2"
10464 [; popcnt op0, op1
10465 (parallel [(set (match_operand:DI 0 "register_operand" "")
10466 (unspec:DI [(match_operand:DI 1 "register_operand")]
10467 UNSPEC_POPCNT))
10468 (clobber (reg:CC CC_REGNUM))])
10469 ; sllg op2, op0, 32
10470 (set (match_dup 2) (ashift:DI (match_dup 0) (const_int 32)))
10471 ; agr op0, op2
10472 (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 2)))
10473 (clobber (reg:CC CC_REGNUM))])
10474 ; sllg op2, op0, 16
10475 (set (match_dup 2)
10476 (ashift:DI (match_dup 0) (const_int 16)))
10477 ; agr op0, op2
10478 (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 2)))
10479 (clobber (reg:CC CC_REGNUM))])
10480 ; sllg op2, op0, 8
10481 (set (match_dup 2) (ashift:DI (match_dup 0) (const_int 8)))
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 ; srlg op0, op0, 56
10486 (set (match_dup 0) (lshiftrt:DI (match_dup 0) (const_int 56)))]
10487 "TARGET_Z196 && TARGET_64BIT"
10488 "operands[2] = gen_reg_rtx (DImode);")
10489
10490 (define_expand "popcountsi2"
10491 [; popcnt op0, op1
10492 (parallel [(set (match_operand:SI 0 "register_operand" "")
10493 (unspec:SI [(match_operand:SI 1 "register_operand")]
10494 UNSPEC_POPCNT))
10495 (clobber (reg:CC CC_REGNUM))])
10496 ; sllk op2, op0, 16
10497 (set (match_dup 2)
10498 (ashift:SI (match_dup 0) (const_int 16)))
10499 ; ar op0, op2
10500 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
10501 (clobber (reg:CC CC_REGNUM))])
10502 ; sllk op2, op0, 8
10503 (set (match_dup 2) (ashift:SI (match_dup 0) (const_int 8)))
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 ; srl op0, op0, 24
10508 (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 24)))]
10509 "TARGET_Z196"
10510 "operands[2] = gen_reg_rtx (SImode);")
10511
10512 (define_expand "popcounthi2"
10513 [; popcnt op0, op1
10514 (parallel [(set (match_operand:HI 0 "register_operand" "")
10515 (unspec:HI [(match_operand:HI 1 "register_operand")]
10516 UNSPEC_POPCNT))
10517 (clobber (reg:CC CC_REGNUM))])
10518 ; sllk op2, op0, 8
10519 (set (match_dup 2)
10520 (ashift:SI (match_dup 0) (const_int 8)))
10521 ; ar op0, op2
10522 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
10523 (clobber (reg:CC CC_REGNUM))])
10524 ; srl op0, op0, 8
10525 (set (match_dup 0) (lshiftrt:HI (match_dup 0) (const_int 8)))]
10526 "TARGET_Z196"
10527 "operands[2] = gen_reg_rtx (SImode);")
10528
10529 (define_expand "popcountqi2"
10530 [; popcnt op0, op1
10531 (parallel [(set (match_operand:QI 0 "register_operand" "")
10532 (unspec:QI [(match_operand:QI 1 "register_operand")]
10533 UNSPEC_POPCNT))
10534 (clobber (reg:CC CC_REGNUM))])]
10535 "TARGET_Z196"
10536 "")
10537
10538 ;;
10539 ;;- Copy sign instructions
10540 ;;
10541
10542 (define_insn "copysign<mode>3"
10543 [(set (match_operand:FP 0 "register_operand" "=f")
10544 (unspec:FP [(match_operand:FP 1 "register_operand" "<fT0>")
10545 (match_operand:FP 2 "register_operand" "f")]
10546 UNSPEC_COPYSIGN))]
10547 "TARGET_Z196"
10548 "cpsdr\t%0,%2,%1"
10549 [(set_attr "op_type" "RRF")
10550 (set_attr "type" "fsimp<mode>")])
10551
10552
10553 ;;
10554 ;;- Transactional execution instructions
10555 ;;
10556
10557 ; This splitter helps combine to make use of CC directly when
10558 ; comparing the integer result of a tbegin builtin with a constant.
10559 ; The unspec is already removed by canonicalize_comparison. So this
10560 ; splitters only job is to turn the PARALLEL into separate insns
10561 ; again. Unfortunately this only works with the very first cc/int
10562 ; compare since combine is not able to deal with data flow across
10563 ; basic block boundaries.
10564
10565 ; It needs to be an insn pattern as well since combine does not apply
10566 ; the splitter directly. Combine would only use it if it actually
10567 ; would reduce the number of instructions.
10568 (define_insn_and_split "*ccraw_to_int"
10569 [(set (pc)
10570 (if_then_else
10571 (match_operator 0 "s390_eqne_operator"
10572 [(reg:CCRAW CC_REGNUM)
10573 (match_operand 1 "const_int_operand" "")])
10574 (label_ref (match_operand 2 "" ""))
10575 (pc)))
10576 (set (match_operand:SI 3 "register_operand" "=d")
10577 (unspec:SI [(reg:CCRAW CC_REGNUM)] UNSPEC_CC_TO_INT))]
10578 ""
10579 "#"
10580 ""
10581 [(set (match_dup 3)
10582 (unspec:SI [(reg:CCRAW CC_REGNUM)] UNSPEC_CC_TO_INT))
10583 (set (pc)
10584 (if_then_else (match_op_dup 0 [(reg:CCRAW CC_REGNUM) (match_dup 1)])
10585 (label_ref (match_dup 2))
10586 (pc)))]
10587 "")
10588
10589 ; Non-constrained transaction begin
10590
10591 (define_expand "tbegin"
10592 [(match_operand:SI 0 "register_operand" "")
10593 (match_operand:BLK 1 "memory_operand" "")]
10594 "TARGET_HTM"
10595 {
10596 s390_expand_tbegin (operands[0], operands[1], NULL_RTX, true);
10597 DONE;
10598 })
10599
10600 (define_expand "tbegin_nofloat"
10601 [(match_operand:SI 0 "register_operand" "")
10602 (match_operand:BLK 1 "memory_operand" "")]
10603 "TARGET_HTM"
10604 {
10605 s390_expand_tbegin (operands[0], operands[1], NULL_RTX, false);
10606 DONE;
10607 })
10608
10609 (define_expand "tbegin_retry"
10610 [(match_operand:SI 0 "register_operand" "")
10611 (match_operand:BLK 1 "memory_operand" "")
10612 (match_operand:SI 2 "general_operand" "")]
10613 "TARGET_HTM"
10614 {
10615 s390_expand_tbegin (operands[0], operands[1], operands[2], true);
10616 DONE;
10617 })
10618
10619 (define_expand "tbegin_retry_nofloat"
10620 [(match_operand:SI 0 "register_operand" "")
10621 (match_operand:BLK 1 "memory_operand" "")
10622 (match_operand:SI 2 "general_operand" "")]
10623 "TARGET_HTM"
10624 {
10625 s390_expand_tbegin (operands[0], operands[1], operands[2], false);
10626 DONE;
10627 })
10628
10629 (define_insn "tbegin_1"
10630 [(set (reg:CCRAW CC_REGNUM)
10631 (unspec_volatile:CCRAW [(match_operand 0 "const_int_operand" "D")]
10632 UNSPECV_TBEGIN))
10633 (set (match_operand:BLK 1 "memory_operand" "=Q")
10634 (unspec_volatile:BLK [(match_dup 0)] UNSPECV_TBEGIN_TDB))
10635 (clobber (reg:DF 16))
10636 (clobber (reg:DF 17))
10637 (clobber (reg:DF 18))
10638 (clobber (reg:DF 19))
10639 (clobber (reg:DF 20))
10640 (clobber (reg:DF 21))
10641 (clobber (reg:DF 22))
10642 (clobber (reg:DF 23))
10643 (clobber (reg:DF 24))
10644 (clobber (reg:DF 25))
10645 (clobber (reg:DF 26))
10646 (clobber (reg:DF 27))
10647 (clobber (reg:DF 28))
10648 (clobber (reg:DF 29))
10649 (clobber (reg:DF 30))
10650 (clobber (reg:DF 31))]
10651 ; CONST_OK_FOR_CONSTRAINT_P does not work with D constraint since D is
10652 ; not supposed to be used for immediates (see genpreds.c).
10653 "TARGET_HTM && INTVAL (operands[0]) >= 0 && INTVAL (operands[0]) <= 0xffff"
10654 "tbegin\t%1,%x0"
10655 [(set_attr "op_type" "SIL")])
10656
10657 ; Same as above but without the FPR clobbers
10658 (define_insn "tbegin_nofloat_1"
10659 [(set (reg:CCRAW CC_REGNUM)
10660 (unspec_volatile:CCRAW [(match_operand 0 "const_int_operand" "D")]
10661 UNSPECV_TBEGIN))
10662 (set (match_operand:BLK 1 "memory_operand" "=Q")
10663 (unspec_volatile:BLK [(match_dup 0)] UNSPECV_TBEGIN_TDB))]
10664 "TARGET_HTM && INTVAL (operands[0]) >= 0 && INTVAL (operands[0]) <= 0xffff"
10665 "tbegin\t%1,%x0"
10666 [(set_attr "op_type" "SIL")])
10667
10668
10669 ; Constrained transaction begin
10670
10671 (define_expand "tbeginc"
10672 [(set (reg:CCRAW CC_REGNUM)
10673 (unspec_volatile:CCRAW [(const_int TBEGINC_MASK)]
10674 UNSPECV_TBEGINC))]
10675 "TARGET_HTM"
10676 "")
10677
10678 (define_insn "*tbeginc_1"
10679 [(set (reg:CCRAW CC_REGNUM)
10680 (unspec_volatile:CCRAW [(match_operand 0 "const_int_operand" " D")]
10681 UNSPECV_TBEGINC))]
10682 "TARGET_HTM && INTVAL (operands[0]) >= 0 && INTVAL (operands[0]) <= 0xffff"
10683 "tbeginc\t0,%x0"
10684 [(set_attr "op_type" "SIL")])
10685
10686 ; Transaction end
10687
10688 (define_expand "tend"
10689 [(set (reg:CCRAW CC_REGNUM)
10690 (unspec_volatile:CCRAW [(const_int 0)] UNSPECV_TEND))
10691 (set (match_operand:SI 0 "register_operand" "")
10692 (unspec:SI [(reg:CCRAW CC_REGNUM)] UNSPEC_CC_TO_INT))]
10693 "TARGET_HTM"
10694 "")
10695
10696 (define_insn "*tend_1"
10697 [(set (reg:CCRAW CC_REGNUM)
10698 (unspec_volatile:CCRAW [(const_int 0)] UNSPECV_TEND))]
10699 "TARGET_HTM"
10700 "tend"
10701 [(set_attr "op_type" "S")])
10702
10703 ; Transaction abort
10704
10705 (define_expand "tabort"
10706 [(unspec_volatile [(match_operand:SI 0 "shift_count_or_setmem_operand" "")]
10707 UNSPECV_TABORT)]
10708 "TARGET_HTM && operands != NULL"
10709 {
10710 if (CONST_INT_P (operands[0])
10711 && INTVAL (operands[0]) >= 0 && INTVAL (operands[0]) <= 255)
10712 {
10713 error ("Invalid transaction abort code: " HOST_WIDE_INT_PRINT_DEC
10714 ". Values in range 0 through 255 are reserved.",
10715 INTVAL (operands[0]));
10716 FAIL;
10717 }
10718 })
10719
10720 (define_insn "*tabort_1"
10721 [(unspec_volatile [(match_operand:SI 0 "shift_count_or_setmem_operand" "Y")]
10722 UNSPECV_TABORT)]
10723 "TARGET_HTM && operands != NULL"
10724 "tabort\t%Y0"
10725 [(set_attr "op_type" "S")])
10726
10727 ; Transaction extract nesting depth
10728
10729 (define_insn "etnd"
10730 [(set (match_operand:SI 0 "register_operand" "=d")
10731 (unspec_volatile:SI [(const_int 0)] UNSPECV_ETND))]
10732 "TARGET_HTM"
10733 "etnd\t%0"
10734 [(set_attr "op_type" "RRE")])
10735
10736 ; Non-transactional store
10737
10738 (define_insn "ntstg"
10739 [(set (match_operand:DI 0 "memory_operand" "=RT")
10740 (unspec_volatile:DI [(match_operand:DI 1 "register_operand" "d")]
10741 UNSPECV_NTSTG))]
10742 "TARGET_HTM"
10743 "ntstg\t%1,%0"
10744 [(set_attr "op_type" "RXY")])
10745
10746 ; Transaction perform processor assist
10747
10748 (define_expand "tx_assist"
10749 [(unspec_volatile [(match_operand:SI 0 "register_operand" "")
10750 (reg:SI GPR0_REGNUM)
10751 (const_int 1)]
10752 UNSPECV_PPA)]
10753 "TARGET_HTM"
10754 "")
10755
10756 (define_insn "*ppa"
10757 [(unspec_volatile [(match_operand:SI 0 "register_operand" "d")
10758 (match_operand:SI 1 "register_operand" "d")
10759 (match_operand 2 "const_int_operand" "I")]
10760 UNSPECV_PPA)]
10761 "TARGET_HTM && INTVAL (operands[2]) < 16"
10762 "ppa\t%0,%1,%2"
10763 [(set_attr "op_type" "RRF")])
10764
10765
10766 ; Set and get floating point control register
10767
10768 (define_insn "sfpc"
10769 [(unspec_volatile [(match_operand:SI 0 "register_operand" "d")]
10770 UNSPECV_SFPC)]
10771 "TARGET_HARD_FLOAT"
10772 "sfpc\t%0")
10773
10774 (define_insn "efpc"
10775 [(set (match_operand:SI 0 "register_operand" "=d")
10776 (unspec_volatile:SI [(const_int 0)] UNSPECV_EFPC))]
10777 "TARGET_HARD_FLOAT"
10778 "efpc\t%0")
10779
10780
10781 ; Load count to block boundary
10782
10783 (define_insn "lcbb"
10784 [(set (match_operand:SI 0 "register_operand" "=d")
10785 (unspec:SI [(match_operand:SI 1 "address_operand" "ZQZR")
10786 (match_operand:SI 2 "immediate_operand" "C")] UNSPEC_LCBB))
10787 (clobber (reg:CC CC_REGNUM))]
10788 "TARGET_Z13"
10789 "lcbb\t%0,%1,%b2"
10790 [(set_attr "op_type" "VRX")])