S/390: Fix r6 vararg handling.
[gcc.git] / gcc / config / s390 / s390.md
1 ;;- Machine description for GNU compiler -- S/390 / zSeries version.
2 ;; Copyright (C) 1999-2016 Free Software Foundation, Inc.
3 ;; Contributed by Hartmut Penner (hpenner@de.ibm.com) and
4 ;; Ulrich Weigand (uweigand@de.ibm.com) and
5 ;; Andreas Krebbel (Andreas.Krebbel@de.ibm.com)
6
7 ;; This file is part of GCC.
8
9 ;; GCC is free software; you can redistribute it and/or modify it under
10 ;; the terms of the GNU General Public License as published by the Free
11 ;; Software Foundation; either version 3, or (at your option) any later
12 ;; version.
13
14 ;; GCC is distributed in the hope that it will be useful, but WITHOUT ANY
15 ;; WARRANTY; without even the implied warranty of MERCHANTABILITY or
16 ;; FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
17 ;; for more details.
18
19 ;; You should have received a copy of the GNU General Public License
20 ;; along with GCC; see the file COPYING3. If not see
21 ;; <http://www.gnu.org/licenses/>.
22
23 ;;
24 ;; See constraints.md for a description of constraints specific to s390.
25 ;;
26
27 ;; Special formats used for outputting 390 instructions.
28 ;;
29 ;; %C: print opcode suffix for branch condition.
30 ;; %D: print opcode suffix for inverse branch condition.
31 ;; %J: print tls_load/tls_gdcall/tls_ldcall suffix
32 ;; %G: print the size of the operand in bytes.
33 ;; %O: print only the displacement of a memory reference.
34 ;; %R: print only the base register of a memory reference.
35 ;; %S: print S-type memory reference (base+displacement).
36 ;; %N: print the second word of a DImode operand.
37 ;; %M: print the second word of a TImode operand.
38 ;; %Y: print shift count operand.
39 ;;
40 ;; %b: print integer X as if it's an unsigned byte.
41 ;; %c: print integer X as if it's an signed byte.
42 ;; %x: print integer X as if it's an unsigned halfword.
43 ;; %h: print integer X as if it's a signed halfword.
44 ;; %i: print the first nonzero HImode part of X.
45 ;; %j: print the first HImode part unequal to -1 of X.
46 ;; %k: print the first nonzero SImode part of X.
47 ;; %m: print the first SImode part unequal to -1 of X.
48 ;; %o: print integer X as if it's an unsigned 32bit word.
49 ;;
50 ;; We have a special constraint for pattern matching.
51 ;;
52 ;; s_operand -- Matches a valid S operand in a RS, SI or SS type instruction.
53 ;;
54
55 ;;
56 ;; UNSPEC usage
57 ;;
58
59 (define_c_enum "unspec" [
60 ; Miscellaneous
61 UNSPEC_ROUND
62 UNSPEC_ICM
63 UNSPEC_TIE
64
65 ; Convert CC into a str comparison result and copy it into an
66 ; integer register
67 ; cc0->0, cc1->1, cc2->-1, (cc3->-1)
68 UNSPEC_STRCMPCC_TO_INT
69
70 ; Copy CC as is into the lower 2 bits of an integer register
71 UNSPEC_CC_TO_INT
72
73 ; The right hand side of an setmem
74 UNSPEC_REPLICATE_BYTE
75
76 ; GOT/PLT and lt-relative accesses
77 UNSPEC_LTREL_OFFSET
78 UNSPEC_LTREL_BASE
79 UNSPEC_POOL_OFFSET
80 UNSPEC_GOTENT
81 UNSPEC_GOT
82 UNSPEC_GOTOFF
83 UNSPEC_PLT
84 UNSPEC_PLTOFF
85
86 ; Literal pool
87 UNSPEC_RELOAD_BASE
88 UNSPEC_MAIN_BASE
89 UNSPEC_LTREF
90 UNSPEC_INSN
91 UNSPEC_EXECUTE
92
93 ; Atomic Support
94 UNSPEC_MB
95 UNSPEC_MOVA
96
97 ; TLS relocation specifiers
98 UNSPEC_TLSGD
99 UNSPEC_TLSLDM
100 UNSPEC_NTPOFF
101 UNSPEC_DTPOFF
102 UNSPEC_GOTNTPOFF
103 UNSPEC_INDNTPOFF
104
105 ; TLS support
106 UNSPEC_TLSLDM_NTPOFF
107 UNSPEC_TLS_LOAD
108
109 ; String Functions
110 UNSPEC_SRST
111 UNSPEC_MVST
112
113 ; Stack Smashing Protector
114 UNSPEC_SP_SET
115 UNSPEC_SP_TEST
116
117 ; Test Data Class (TDC)
118 UNSPEC_TDC_INSN
119
120 ; Population Count
121 UNSPEC_POPCNT
122 UNSPEC_COPYSIGN
123
124 ; Load FP Integer
125 UNSPEC_FPINT_FLOOR
126 UNSPEC_FPINT_BTRUNC
127 UNSPEC_FPINT_ROUND
128 UNSPEC_FPINT_CEIL
129 UNSPEC_FPINT_NEARBYINT
130 UNSPEC_FPINT_RINT
131
132 UNSPEC_LCBB
133
134 ; Vector
135 UNSPEC_VEC_SMULT_HI
136 UNSPEC_VEC_UMULT_HI
137 UNSPEC_VEC_SMULT_LO
138 UNSPEC_VEC_SMULT_EVEN
139 UNSPEC_VEC_UMULT_EVEN
140 UNSPEC_VEC_SMULT_ODD
141 UNSPEC_VEC_UMULT_ODD
142
143 UNSPEC_VEC_VMAL
144 UNSPEC_VEC_VMAH
145 UNSPEC_VEC_VMALH
146 UNSPEC_VEC_VMAE
147 UNSPEC_VEC_VMALE
148 UNSPEC_VEC_VMAO
149 UNSPEC_VEC_VMALO
150
151 UNSPEC_VEC_GATHER
152 UNSPEC_VEC_EXTRACT
153 UNSPEC_VEC_INSERT_AND_ZERO
154 UNSPEC_VEC_LOAD_BNDRY
155 UNSPEC_VEC_LOAD_LEN
156 UNSPEC_VEC_MERGEH
157 UNSPEC_VEC_MERGEL
158 UNSPEC_VEC_PACK
159 UNSPEC_VEC_PACK_SATURATE
160 UNSPEC_VEC_PACK_SATURATE_CC
161 UNSPEC_VEC_PACK_SATURATE_GENCC
162 UNSPEC_VEC_PACK_UNSIGNED_SATURATE
163 UNSPEC_VEC_PACK_UNSIGNED_SATURATE_CC
164 UNSPEC_VEC_PACK_UNSIGNED_SATURATE_GENCC
165 UNSPEC_VEC_PERM
166 UNSPEC_VEC_PERMI
167 UNSPEC_VEC_EXTEND
168 UNSPEC_VEC_STORE_LEN
169 UNSPEC_VEC_UNPACKH
170 UNSPEC_VEC_UNPACKH_L
171 UNSPEC_VEC_UNPACKL
172 UNSPEC_VEC_UNPACKL_L
173 UNSPEC_VEC_ADDC
174 UNSPEC_VEC_ADDC_U128
175 UNSPEC_VEC_ADDE_U128
176 UNSPEC_VEC_ADDEC_U128
177 UNSPEC_VEC_AVG
178 UNSPEC_VEC_AVGU
179 UNSPEC_VEC_CHECKSUM
180 UNSPEC_VEC_GFMSUM
181 UNSPEC_VEC_GFMSUM_128
182 UNSPEC_VEC_GFMSUM_ACCUM
183 UNSPEC_VEC_GFMSUM_ACCUM_128
184 UNSPEC_VEC_SET
185
186 UNSPEC_VEC_VSUMG
187 UNSPEC_VEC_VSUMQ
188 UNSPEC_VEC_VSUM
189 UNSPEC_VEC_RL_MASK
190 UNSPEC_VEC_SLL
191 UNSPEC_VEC_SLB
192 UNSPEC_VEC_SLDB
193 UNSPEC_VEC_SRAL
194 UNSPEC_VEC_SRAB
195 UNSPEC_VEC_SRL
196 UNSPEC_VEC_SRLB
197
198 UNSPEC_VEC_SUB_U128
199 UNSPEC_VEC_SUBC
200 UNSPEC_VEC_SUBC_U128
201 UNSPEC_VEC_SUBE_U128
202 UNSPEC_VEC_SUBEC_U128
203
204 UNSPEC_VEC_TEST_MASK
205
206 UNSPEC_VEC_VFAE
207 UNSPEC_VEC_VFAECC
208
209 UNSPEC_VEC_VFEE
210 UNSPEC_VEC_VFEECC
211 UNSPEC_VEC_VFENE
212 UNSPEC_VEC_VFENECC
213
214 UNSPEC_VEC_VISTR
215 UNSPEC_VEC_VISTRCC
216
217 UNSPEC_VEC_VSTRC
218 UNSPEC_VEC_VSTRCCC
219
220 UNSPEC_VEC_VCDGB
221 UNSPEC_VEC_VCDLGB
222
223 UNSPEC_VEC_VCGDB
224 UNSPEC_VEC_VCLGDB
225
226 UNSPEC_VEC_VFIDB
227
228 UNSPEC_VEC_VLDEB
229 UNSPEC_VEC_VLEDB
230
231 UNSPEC_VEC_VFTCIDB
232 UNSPEC_VEC_VFTCIDBCC
233 ])
234
235 ;;
236 ;; UNSPEC_VOLATILE usage
237 ;;
238
239 (define_c_enum "unspecv" [
240 ; Blockage
241 UNSPECV_BLOCKAGE
242
243 ; TPF Support
244 UNSPECV_TPF_PROLOGUE
245 UNSPECV_TPF_EPILOGUE
246
247 ; Literal pool
248 UNSPECV_POOL
249 UNSPECV_POOL_SECTION
250 UNSPECV_POOL_ALIGN
251 UNSPECV_POOL_ENTRY
252 UNSPECV_MAIN_POOL
253
254 ; TLS support
255 UNSPECV_SET_TP
256
257 ; Atomic Support
258 UNSPECV_CAS
259 UNSPECV_ATOMIC_OP
260
261 ; Hotpatching (unremovable NOPs)
262 UNSPECV_NOP_2_BYTE
263 UNSPECV_NOP_4_BYTE
264 UNSPECV_NOP_6_BYTE
265
266 ; Transactional Execution support
267 UNSPECV_TBEGIN
268 UNSPECV_TBEGIN_TDB
269 UNSPECV_TBEGINC
270 UNSPECV_TEND
271 UNSPECV_TABORT
272 UNSPECV_ETND
273 UNSPECV_NTSTG
274 UNSPECV_PPA
275
276 ; Set and get floating point control register
277 UNSPECV_SFPC
278 UNSPECV_EFPC
279 ])
280
281 ;;
282 ;; Registers
283 ;;
284
285 ; Registers with special meaning
286
287 (define_constants
288 [
289 ; Sibling call register.
290 (SIBCALL_REGNUM 1)
291 ; Literal pool base register.
292 (BASE_REGNUM 13)
293 ; Return address register.
294 (RETURN_REGNUM 14)
295 ; Condition code register.
296 (CC_REGNUM 33)
297 ; Thread local storage pointer register.
298 (TP_REGNUM 36)
299 ])
300
301 ; Hardware register names
302
303 (define_constants
304 [
305 ; General purpose registers
306 (GPR0_REGNUM 0)
307 (GPR1_REGNUM 1)
308 (GPR2_REGNUM 2)
309 (GPR6_REGNUM 6)
310 ; Floating point registers.
311 (FPR0_REGNUM 16)
312 (FPR1_REGNUM 20)
313 (FPR2_REGNUM 17)
314 (FPR3_REGNUM 21)
315 (FPR4_REGNUM 18)
316 (FPR5_REGNUM 22)
317 (FPR6_REGNUM 19)
318 (FPR7_REGNUM 23)
319 (FPR8_REGNUM 24)
320 (FPR9_REGNUM 28)
321 (FPR10_REGNUM 25)
322 (FPR11_REGNUM 29)
323 (FPR12_REGNUM 26)
324 (FPR13_REGNUM 30)
325 (FPR14_REGNUM 27)
326 (FPR15_REGNUM 31)
327 (VR0_REGNUM 16)
328 (VR16_REGNUM 38)
329 (VR23_REGNUM 45)
330 (VR24_REGNUM 46)
331 (VR31_REGNUM 53)
332 ])
333
334 ;;
335 ;; PFPO GPR0 argument format
336 ;;
337
338 (define_constants
339 [
340 ; PFPO operation type
341 (PFPO_CONVERT 0x1000000)
342 ; PFPO operand types
343 (PFPO_OP_TYPE_SF 0x5)
344 (PFPO_OP_TYPE_DF 0x6)
345 (PFPO_OP_TYPE_TF 0x7)
346 (PFPO_OP_TYPE_SD 0x8)
347 (PFPO_OP_TYPE_DD 0x9)
348 (PFPO_OP_TYPE_TD 0xa)
349 ; Bitposition of operand types
350 (PFPO_OP0_TYPE_SHIFT 16)
351 (PFPO_OP1_TYPE_SHIFT 8)
352 ])
353
354 ; Immediate operands for tbegin and tbeginc
355 (define_constants [(TBEGIN_MASK 65292)]) ; 0xff0c
356 (define_constants [(TBEGINC_MASK 65288)]) ; 0xff08
357
358 ;; Instruction operand type as used in the Principles of Operation.
359 ;; Used to determine defaults for length and other attribute values.
360
361 (define_attr "op_type"
362 "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"
363 (const_string "NN"))
364
365 ;; Instruction type attribute used for scheduling.
366
367 (define_attr "type" "none,integer,load,lr,la,larl,lm,stm,
368 cs,vs,store,sem,idiv,
369 imulhi,imulsi,imuldi,
370 branch,jsr,fsimptf,fsimpdf,fsimpsf,fhex,
371 floadtf,floaddf,floadsf,fstoredf,fstoresf,
372 fmultf,fmuldf,fmulsf,fdivtf,fdivdf,fdivsf,
373 ftoi,fsqrttf,fsqrtdf,fsqrtsf,
374 fmadddf,fmaddsf,
375 ftrunctf,ftruncdf, ftruncsd, ftruncdd,
376 itoftf, itofdf, itofsf, itofdd, itoftd,
377 fdivdd, fdivtd, floaddd, floadsd, fmuldd, fmultd,
378 fsimpdd, fsimpsd, fsimptd, fstoredd, fstoresd,
379 ftoidfp, other"
380 (cond [(eq_attr "op_type" "NN") (const_string "other")
381 (eq_attr "op_type" "SS") (const_string "cs")]
382 (const_string "integer")))
383
384 ;; Another attribute used for scheduling purposes:
385 ;; agen: Instruction uses the address generation unit
386 ;; reg: Instruction does not use the agen unit
387
388 (define_attr "atype" "agen,reg"
389 (if_then_else (eq_attr "op_type" "E,RR,RI,RRE,RSI,RIL,RIE,RRF,RRR")
390 (const_string "reg")
391 (const_string "agen")))
392
393 ;; Properties concerning Z10 execution grouping and value forwarding.
394 ;; z10_super: instruction is superscalar.
395 ;; z10_super_c: instruction is superscalar and meets the condition of z10_c.
396 ;; z10_fwd: The instruction reads the value of an operand and stores it into a
397 ;; target register. It can forward this value to a second instruction that reads
398 ;; the same register if that second instruction is issued in the same group.
399 ;; z10_rec: The instruction is in the T pipeline and reads a register. If the
400 ;; instruction in the S pipe writes to the register, then the T instruction
401 ;; can immediately read the new value.
402 ;; z10_fr: union of Z10_fwd and z10_rec.
403 ;; z10_c: second operand of instruction is a register and read with complemented bits.
404 ;;
405 ;; An additional suffix A1, A3, or E1 indicates the respective AGI bypass.
406
407
408 (define_attr "z10prop" "none,
409 z10_super, z10_super_E1, z10_super_A1, z10_super_c, z10_super_c_E1,
410 z10_fwd, z10_fwd_A1, z10_fwd_A3, z10_fwd_E1,
411 z10_rec,
412 z10_fr, z10_fr_A3, z10_fr_E1,
413 z10_c"
414 (const_string "none"))
415
416 ;; Properties concerning Z196 decoding
417 ;; z196_alone: must group alone
418 ;; z196_end: ends a group
419 ;; z196_cracked: instruction is cracked or expanded
420 (define_attr "z196prop" "none,
421 z196_alone, z196_ends,
422 z196_cracked"
423 (const_string "none"))
424
425 (define_attr "mnemonic" "bcr_flush,unknown" (const_string "unknown"))
426
427 ;; Length in bytes.
428
429 (define_attr "length" ""
430 (cond [(eq_attr "op_type" "E,RR") (const_int 2)
431 (eq_attr "op_type" "RX,RI,RRE,RS,RSI,S,SI,RRF,RRR") (const_int 4)]
432 (const_int 6)))
433
434
435 ;; Processor type. This attribute must exactly match the processor_type
436 ;; enumeration in s390.h. The current machine description does not
437 ;; distinguish between g5 and g6, but there are differences between the two
438 ;; CPUs could in theory be modeled.
439
440 (define_attr "cpu" "g5,g6,z900,z990,z9_109,z9_ec,z10,z196,zEC12,z13"
441 (const (symbol_ref "s390_tune_attr")))
442
443 (define_attr "cpu_facility"
444 "standard,ieee,zarch,cpu_zarch,longdisp,extimm,dfp,z10,z196,zEC12,vec"
445 (const_string "standard"))
446
447 (define_attr "enabled" ""
448 (cond [(eq_attr "cpu_facility" "standard")
449 (const_int 1)
450
451 (and (eq_attr "cpu_facility" "ieee")
452 (match_test "TARGET_CPU_IEEE_FLOAT"))
453 (const_int 1)
454
455 (and (eq_attr "cpu_facility" "zarch")
456 (match_test "TARGET_ZARCH"))
457 (const_int 1)
458
459 (and (eq_attr "cpu_facility" "longdisp")
460 (match_test "TARGET_LONG_DISPLACEMENT"))
461 (const_int 1)
462
463 (and (eq_attr "cpu_facility" "extimm")
464 (match_test "TARGET_EXTIMM"))
465 (const_int 1)
466
467 (and (eq_attr "cpu_facility" "dfp")
468 (match_test "TARGET_DFP"))
469 (const_int 1)
470
471 (and (eq_attr "cpu_facility" "cpu_zarch")
472 (match_test "TARGET_CPU_ZARCH"))
473 (const_int 1)
474
475 (and (eq_attr "cpu_facility" "z10")
476 (match_test "TARGET_Z10"))
477 (const_int 1)
478
479 (and (eq_attr "cpu_facility" "z196")
480 (match_test "TARGET_Z196"))
481 (const_int 1)
482
483 (and (eq_attr "cpu_facility" "zEC12")
484 (match_test "TARGET_ZEC12"))
485 (const_int 1)
486
487 (and (eq_attr "cpu_facility" "vec")
488 (match_test "TARGET_VX"))
489 (const_int 1)]
490 (const_int 0)))
491
492 ;; Pipeline description for z900. For lack of anything better,
493 ;; this description is also used for the g5 and g6.
494 (include "2064.md")
495
496 ;; Pipeline description for z990, z9-109 and z9-ec.
497 (include "2084.md")
498
499 ;; Pipeline description for z10
500 (include "2097.md")
501
502 ;; Pipeline description for z196
503 (include "2817.md")
504
505 ;; Pipeline description for zEC12
506 (include "2827.md")
507
508 ;; Predicates
509 (include "predicates.md")
510
511 ;; Constraint definitions
512 (include "constraints.md")
513
514 ;; Other includes
515 (include "tpf.md")
516
517 ;; Iterators
518
519 (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])
520
521 ;; These mode iterators allow floating point patterns to be generated from the
522 ;; same template.
523 (define_mode_iterator FP_ALL [TF DF SF (TD "TARGET_HARD_DFP") (DD "TARGET_HARD_DFP")
524 (SD "TARGET_HARD_DFP")])
525 (define_mode_iterator FP [TF DF SF (TD "TARGET_HARD_DFP") (DD "TARGET_HARD_DFP")])
526 (define_mode_iterator BFP [TF DF SF])
527 (define_mode_iterator DFP [TD DD])
528 (define_mode_iterator DFP_ALL [TD DD SD])
529 (define_mode_iterator DSF [DF SF])
530 (define_mode_iterator SD_SF [SF SD])
531 (define_mode_iterator DD_DF [DF DD])
532 (define_mode_iterator TD_TF [TF TD])
533
534 ;; These mode iterators allow 31-bit and 64-bit GPR patterns to be generated
535 ;; from the same template.
536 (define_mode_iterator GPR [(DI "TARGET_ZARCH") SI])
537 (define_mode_iterator DGPR [(TI "TARGET_ZARCH") DI SI])
538 (define_mode_iterator DSI [DI SI])
539 (define_mode_iterator TDI [TI DI])
540
541 ;; These mode iterators allow :P to be used for patterns that operate on
542 ;; pointer-sized quantities. Exactly one of the two alternatives will match.
543 (define_mode_iterator P [(DI "TARGET_64BIT") (SI "!TARGET_64BIT")])
544
545 ;; These macros refer to the actual word_mode of the configuration.
546 ;; This is equal to Pmode except on 31-bit machines in zarch mode.
547 (define_mode_iterator DW [(TI "TARGET_ZARCH") (DI "!TARGET_ZARCH")])
548 (define_mode_iterator W [(DI "TARGET_ZARCH") (SI "!TARGET_ZARCH")])
549
550 ;; Used by the umul pattern to express modes having half the size.
551 (define_mode_attr DWH [(TI "DI") (DI "SI")])
552 (define_mode_attr dwh [(TI "di") (DI "si")])
553
554 ;; This mode iterator allows the QI and HI patterns to be defined from
555 ;; the same template.
556 (define_mode_iterator HQI [HI QI])
557
558 ;; This mode iterator allows the integer patterns to be defined from the
559 ;; same template.
560 (define_mode_iterator INT [(DI "TARGET_ZARCH") SI HI QI])
561 (define_mode_iterator DINT [(TI "TARGET_ZARCH") DI SI HI QI])
562
563 ;; This iterator allows some 'ashift' and 'lshiftrt' pattern to be defined from
564 ;; the same template.
565 (define_code_iterator SHIFT [ashift lshiftrt])
566
567 ;; This iterator allows r[ox]sbg to be defined with the same template
568 (define_code_iterator IXOR [ior xor])
569
570 ;; This iterator is used to expand the patterns for the nearest
571 ;; integer functions.
572 (define_int_iterator FPINT [UNSPEC_FPINT_FLOOR UNSPEC_FPINT_BTRUNC
573 UNSPEC_FPINT_ROUND UNSPEC_FPINT_CEIL
574 UNSPEC_FPINT_NEARBYINT])
575 (define_int_attr fpint_name [(UNSPEC_FPINT_FLOOR "floor")
576 (UNSPEC_FPINT_BTRUNC "btrunc")
577 (UNSPEC_FPINT_ROUND "round")
578 (UNSPEC_FPINT_CEIL "ceil")
579 (UNSPEC_FPINT_NEARBYINT "nearbyint")])
580 (define_int_attr fpint_roundingmode [(UNSPEC_FPINT_FLOOR "7")
581 (UNSPEC_FPINT_BTRUNC "5")
582 (UNSPEC_FPINT_ROUND "1")
583 (UNSPEC_FPINT_CEIL "6")
584 (UNSPEC_FPINT_NEARBYINT "0")])
585
586 ;; This iterator and attribute allow to combine most atomic operations.
587 (define_code_iterator ATOMIC [and ior xor plus minus mult])
588 (define_code_iterator ATOMIC_Z196 [and ior xor plus])
589 (define_code_attr atomic [(and "and") (ior "or") (xor "xor")
590 (plus "add") (minus "sub") (mult "nand")])
591 (define_code_attr noxa [(and "n") (ior "o") (xor "x") (plus "a")])
592
593 ;; In FP templates, a string like "lt<de>br" will expand to "ltxbr" in
594 ;; TF/TDmode, "ltdbr" in DF/DDmode, and "ltebr" in SF/SDmode.
595 (define_mode_attr xde [(TF "x") (DF "d") (SF "e") (TD "x") (DD "d") (SD "e")])
596
597 ;; In FP templates, a <dee> in "m<dee><bt>r" will expand to "mx<bt>r" in
598 ;; TF/TDmode, "md<bt>r" in DF/DDmode, "mee<bt>r" in SFmode and "me<bt>r in
599 ;; SDmode.
600 (define_mode_attr xdee [(TF "x") (DF "d") (SF "ee") (TD "x") (DD "d") (SD "e")])
601
602 ;; In FP templates, "<RRe>" will expand to "RRE" in TFmode and "RR" otherwise.
603 ;; Likewise for "<RXe>".
604 (define_mode_attr RRe [(TF "RRE") (DF "RR") (SF "RR")])
605 (define_mode_attr RXe [(TF "RXE") (DF "RX") (SF "RX")])
606
607 ;; The decimal floating point variants of add, sub, div and mul support 3
608 ;; fp register operands. The following attributes allow to merge the bfp and
609 ;; dfp variants in a single insn definition.
610
611 ;; This attribute is used to set op_type accordingly.
612 (define_mode_attr RRer [(TF "RRE") (DF "RRE") (SF "RRE") (TD "RRR")
613 (DD "RRR") (SD "RRR")])
614
615 ;; This attribute is used in the operand constraint list in order to have the
616 ;; first and the second operand match for bfp modes.
617 (define_mode_attr f0 [(TF "0") (DF "0") (SF "0") (TD "f") (DD "f") (DD "f")])
618
619 ;; This attribute is used to merge the scalar vector instructions into
620 ;; the FP patterns. For non-supported modes (all but DF) it expands
621 ;; to constraints which are supposed to be matched by an earlier
622 ;; variant.
623 (define_mode_attr v0 [(TF "0") (DF "v") (SF "0") (TD "0") (DD "0") (DD "0") (TI "0") (DI "v") (SI "0")])
624 (define_mode_attr vf [(TF "f") (DF "v") (SF "f") (TD "f") (DD "f") (DD "f") (TI "f") (DI "v") (SI "f")])
625 (define_mode_attr vd [(TF "d") (DF "v") (SF "d") (TD "d") (DD "d") (DD "d") (TI "d") (DI "v") (SI "d")])
626
627 ;; This attribute is used in the operand list of the instruction to have an
628 ;; additional operand for the dfp instructions.
629 (define_mode_attr op1 [(TF "") (DF "") (SF "")
630 (TD "%1,") (DD "%1,") (SD "%1,")])
631
632
633 ;; This attribute is used in the operand constraint list
634 ;; for instructions dealing with the sign bit of 32 or 64bit fp values.
635 ;; TFmode values are represented by a fp register pair. Since the
636 ;; sign bit instructions only handle single source and target fp registers
637 ;; these instructions can only be used for TFmode values if the source and
638 ;; target operand uses the same fp register.
639 (define_mode_attr fT0 [(TF "0") (DF "f") (SF "f")])
640
641 ;; In FP templates, "<Rf>" will expand to "f" in TFmode and "R" otherwise.
642 ;; This is used to disable the memory alternative in TFmode patterns.
643 (define_mode_attr Rf [(TF "f") (DF "R") (SF "R") (TD "f") (DD "f") (SD "f")])
644
645 ;; This attribute adds b for bfp instructions and t for dfp instructions and is used
646 ;; within instruction mnemonics.
647 (define_mode_attr bt [(TF "b") (DF "b") (SF "b") (TD "t") (DD "t") (SD "t")])
648
649 ;; This attribute is used within instruction mnemonics. It evaluates to d for dfp
650 ;; modes and to an empty string for bfp modes.
651 (define_mode_attr _d [(TF "") (DF "") (SF "") (TD "d") (DD "d") (SD "d")])
652
653 ;; In GPR and P templates, a constraint like "<d0>" will expand to "d" in DImode
654 ;; and "0" in SImode. This allows to combine instructions of which the 31bit
655 ;; version only operates on one register.
656 (define_mode_attr d0 [(DI "d") (SI "0")])
657
658 ;; In combination with d0 this allows to combine instructions of which the 31bit
659 ;; version only operates on one register. The DImode version needs an additional
660 ;; register for the assembler output.
661 (define_mode_attr 1 [(DI "%1,") (SI "")])
662
663 ;; In SHIFT templates, a string like "s<lr>dl" will expand to "sldl" in
664 ;; 'ashift' and "srdl" in 'lshiftrt'.
665 (define_code_attr lr [(ashift "l") (lshiftrt "r")])
666
667 ;; In SHIFT templates, this attribute holds the correct standard name for the
668 ;; pattern itself and the corresponding function calls.
669 (define_code_attr shift [(ashift "ashl") (lshiftrt "lshr")])
670
671 ;; This attribute handles differences in the instruction 'type' and will result
672 ;; in "RRE" for DImode and "RR" for SImode.
673 (define_mode_attr E [(DI "E") (SI "")])
674
675 ;; This attribute handles differences in the instruction 'type' and makes RX<Y>
676 ;; to result in "RXY" for DImode and "RX" for SImode.
677 (define_mode_attr Y [(DI "Y") (SI "")])
678
679 ;; This attribute handles differences in the instruction 'type' and will result
680 ;; in "RSE" for TImode and "RS" for DImode.
681 (define_mode_attr TE [(TI "E") (DI "")])
682
683 ;; In GPR templates, a string like "lc<g>r" will expand to "lcgr" in DImode
684 ;; and "lcr" in SImode.
685 (define_mode_attr g [(DI "g") (SI "")])
686
687 ;; In GPR templates, a string like "sl<y>" will expand to "slg" in DImode
688 ;; and "sly" in SImode. This is useful because on 64bit the ..g instructions
689 ;; were enhanced with long displacements whereas 31bit instructions got a ..y
690 ;; variant for long displacements.
691 (define_mode_attr y [(DI "g") (SI "y")])
692
693 ;; In DW templates, a string like "cds<g>" will expand to "cdsg" in TImode
694 ;; and "cds" in DImode.
695 (define_mode_attr tg [(TI "g") (DI "")])
696
697 ;; In TDI templates, a string like "c<d>sg".
698 (define_mode_attr td [(TI "d") (DI "")])
699
700 ;; In GPR templates, a string like "c<gf>dbr" will expand to "cgdbr" in DImode
701 ;; and "cfdbr" in SImode.
702 (define_mode_attr gf [(DI "g") (SI "f")])
703
704 ;; In GPR templates, a string like sll<gk> will expand to sllg for DI
705 ;; and sllk for SI. This way it is possible to merge the new z196 SI
706 ;; 3 operands shift instructions into the existing patterns.
707 (define_mode_attr gk [(DI "g") (SI "k")])
708
709 ;; ICM mask required to load MODE value into the lowest subreg
710 ;; of a SImode register.
711 (define_mode_attr icm_lo [(HI "3") (QI "1")])
712
713 ;; In HQI templates, a string like "llg<hc>" will expand to "llgh" in
714 ;; HImode and "llgc" in QImode.
715 (define_mode_attr hc [(HI "h") (QI "c")])
716
717 ;; In P templates, the mode <DBL> will expand to "TI" in DImode and "DI"
718 ;; in SImode.
719 (define_mode_attr DBL [(DI "TI") (SI "DI")])
720
721 ;; This attribute expands to DF for TFmode and to DD for TDmode . It is
722 ;; used for Txmode splitters splitting a Txmode copy into 2 Dxmode copies.
723 (define_mode_attr HALF_TMODE [(TF "DF") (TD "DD")])
724
725 ;; Maximum unsigned integer that fits in MODE.
726 (define_mode_attr max_uint [(HI "65535") (QI "255")])
727
728 ;; Start and end field computations for RISBG et al.
729 (define_mode_attr bfstart [(DI "s") (SI "t")])
730 (define_mode_attr bfend [(DI "e") (SI "f")])
731
732 ;; In place of GET_MODE_BITSIZE (<MODE>mode)
733 (define_mode_attr bitsize [(DI "64") (SI "32") (HI "16") (QI "8")])
734
735 ;; In place of GET_MODE_SIZE (<MODE>mode)
736 (define_mode_attr modesize [(DI "8") (SI "4")])
737
738 ;; Allow return and simple_return to be defined from a single template.
739 (define_code_iterator ANY_RETURN [return simple_return])
740
741
742
743 ; Condition code modes generated by vector fp comparisons. These will
744 ; be used also in single element mode.
745 (define_mode_iterator VFCMP [CCVEQ CCVFH CCVFHE])
746 ; Used with VFCMP to expand part of the mnemonic
747 ; For fp we have a mismatch: eq in the insn name - e in asm
748 (define_mode_attr asm_fcmp [(CCVEQ "e") (CCVFH "h") (CCVFHE "he")])
749 (define_mode_attr insn_cmp [(CCVEQ "eq") (CCVH "h") (CCVHU "hl") (CCVFH "h") (CCVFHE "he")])
750
751
752 (include "vector.md")
753
754 ;;
755 ;;- Compare instructions.
756 ;;
757
758 ; Test-under-Mask instructions
759
760 (define_insn "*tmqi_mem"
761 [(set (reg CC_REGNUM)
762 (compare (and:QI (match_operand:QI 0 "memory_operand" "Q,S")
763 (match_operand:QI 1 "immediate_operand" "n,n"))
764 (match_operand:QI 2 "immediate_operand" "n,n")))]
765 "s390_match_ccmode (insn, s390_tm_ccmode (operands[1], operands[2], false))"
766 "@
767 tm\t%S0,%b1
768 tmy\t%S0,%b1"
769 [(set_attr "op_type" "SI,SIY")
770 (set_attr "z10prop" "z10_super,z10_super")])
771
772 (define_insn "*tmdi_reg"
773 [(set (reg CC_REGNUM)
774 (compare (and:DI (match_operand:DI 0 "nonimmediate_operand" "d,d,d,d")
775 (match_operand:DI 1 "immediate_operand"
776 "N0HD0,N1HD0,N2HD0,N3HD0"))
777 (match_operand:DI 2 "immediate_operand" "n,n,n,n")))]
778 "TARGET_ZARCH
779 && s390_match_ccmode (insn, s390_tm_ccmode (operands[1], operands[2], true))
780 && s390_single_part (operands[1], DImode, HImode, 0) >= 0"
781 "@
782 tmhh\t%0,%i1
783 tmhl\t%0,%i1
784 tmlh\t%0,%i1
785 tmll\t%0,%i1"
786 [(set_attr "op_type" "RI")
787 (set_attr "z10prop" "z10_super,z10_super,z10_super,z10_super")])
788
789 (define_insn "*tmsi_reg"
790 [(set (reg CC_REGNUM)
791 (compare (and:SI (match_operand:SI 0 "nonimmediate_operand" "d,d")
792 (match_operand:SI 1 "immediate_operand" "N0HS0,N1HS0"))
793 (match_operand:SI 2 "immediate_operand" "n,n")))]
794 "s390_match_ccmode (insn, s390_tm_ccmode (operands[1], operands[2], true))
795 && s390_single_part (operands[1], SImode, HImode, 0) >= 0"
796 "@
797 tmh\t%0,%i1
798 tml\t%0,%i1"
799 [(set_attr "op_type" "RI")
800 (set_attr "z10prop" "z10_super,z10_super")])
801
802 (define_insn "*tm<mode>_full"
803 [(set (reg CC_REGNUM)
804 (compare (match_operand:HQI 0 "register_operand" "d")
805 (match_operand:HQI 1 "immediate_operand" "n")))]
806 "s390_match_ccmode (insn, s390_tm_ccmode (constm1_rtx, operands[1], true))"
807 "tml\t%0,<max_uint>"
808 [(set_attr "op_type" "RI")
809 (set_attr "z10prop" "z10_super")])
810
811
812 ;
813 ; Load-and-Test instructions
814 ;
815
816 ; tst(di|si) instruction pattern(s).
817
818 (define_insn "*tstdi_sign"
819 [(set (reg CC_REGNUM)
820 (compare
821 (ashiftrt:DI
822 (ashift:DI
823 (subreg:DI (match_operand:SI 0 "nonimmediate_operand" "d,RT") 0)
824 (const_int 32)) (const_int 32))
825 (match_operand:DI 1 "const0_operand" "")))
826 (set (match_operand:DI 2 "register_operand" "=d,d")
827 (sign_extend:DI (match_dup 0)))]
828 "s390_match_ccmode(insn, CCSmode) && TARGET_ZARCH"
829 "ltgfr\t%2,%0
830 ltgf\t%2,%0"
831 [(set_attr "op_type" "RRE,RXY")
832 (set_attr "cpu_facility" "*,z10")
833 (set_attr "z10prop" "z10_super_E1,z10_super_E1") ])
834
835 ; ltr, lt, ltgr, ltg
836 (define_insn "*tst<mode>_extimm"
837 [(set (reg CC_REGNUM)
838 (compare (match_operand:GPR 0 "nonimmediate_operand" "d,RT")
839 (match_operand:GPR 1 "const0_operand" "")))
840 (set (match_operand:GPR 2 "register_operand" "=d,d")
841 (match_dup 0))]
842 "s390_match_ccmode(insn, CCSmode) && TARGET_EXTIMM"
843 "@
844 lt<g>r\t%2,%0
845 lt<g>\t%2,%0"
846 [(set_attr "op_type" "RR<E>,RXY")
847 (set_attr "z10prop" "z10_fr_E1,z10_fwd_A3") ])
848
849 ; ltr, lt, ltgr, ltg
850 (define_insn "*tst<mode>_cconly_extimm"
851 [(set (reg CC_REGNUM)
852 (compare (match_operand:GPR 0 "nonimmediate_operand" "d,RT")
853 (match_operand:GPR 1 "const0_operand" "")))
854 (clobber (match_scratch:GPR 2 "=X,d"))]
855 "s390_match_ccmode(insn, CCSmode) && TARGET_EXTIMM"
856 "@
857 lt<g>r\t%0,%0
858 lt<g>\t%2,%0"
859 [(set_attr "op_type" "RR<E>,RXY")
860 (set_attr "z10prop" "z10_fr_E1,z10_fwd_A3")])
861
862 (define_insn "*tstdi"
863 [(set (reg CC_REGNUM)
864 (compare (match_operand:DI 0 "register_operand" "d")
865 (match_operand:DI 1 "const0_operand" "")))
866 (set (match_operand:DI 2 "register_operand" "=d")
867 (match_dup 0))]
868 "s390_match_ccmode(insn, CCSmode) && TARGET_ZARCH && !TARGET_EXTIMM"
869 "ltgr\t%2,%0"
870 [(set_attr "op_type" "RRE")
871 (set_attr "z10prop" "z10_fr_E1")])
872
873 (define_insn "*tstsi"
874 [(set (reg CC_REGNUM)
875 (compare (match_operand:SI 0 "nonimmediate_operand" "d,Q,S")
876 (match_operand:SI 1 "const0_operand" "")))
877 (set (match_operand:SI 2 "register_operand" "=d,d,d")
878 (match_dup 0))]
879 "s390_match_ccmode(insn, CCSmode) && !TARGET_EXTIMM"
880 "@
881 ltr\t%2,%0
882 icm\t%2,15,%S0
883 icmy\t%2,15,%S0"
884 [(set_attr "op_type" "RR,RS,RSY")
885 (set_attr "z10prop" "z10_fr_E1,z10_super_E1,z10_super_E1")])
886
887 (define_insn "*tstsi_cconly"
888 [(set (reg CC_REGNUM)
889 (compare (match_operand:SI 0 "nonimmediate_operand" "d,Q,S")
890 (match_operand:SI 1 "const0_operand" "")))
891 (clobber (match_scratch:SI 2 "=X,d,d"))]
892 "s390_match_ccmode(insn, CCSmode)"
893 "@
894 ltr\t%0,%0
895 icm\t%2,15,%S0
896 icmy\t%2,15,%S0"
897 [(set_attr "op_type" "RR,RS,RSY")
898 (set_attr "z10prop" "z10_fr_E1,z10_super_E1,z10_super_E1")])
899
900 (define_insn "*tstdi_cconly_31"
901 [(set (reg CC_REGNUM)
902 (compare (match_operand:DI 0 "register_operand" "d")
903 (match_operand:DI 1 "const0_operand" "")))]
904 "s390_match_ccmode(insn, CCSmode) && !TARGET_ZARCH"
905 "srda\t%0,0"
906 [(set_attr "op_type" "RS")
907 (set_attr "atype" "reg")])
908
909 ; ltr, ltgr
910 (define_insn "*tst<mode>_cconly2"
911 [(set (reg CC_REGNUM)
912 (compare (match_operand:GPR 0 "register_operand" "d")
913 (match_operand:GPR 1 "const0_operand" "")))]
914 "s390_match_ccmode(insn, CCSmode)"
915 "lt<g>r\t%0,%0"
916 [(set_attr "op_type" "RR<E>")
917 (set_attr "z10prop" "z10_fr_E1")])
918
919 ; tst(hi|qi) instruction pattern(s).
920
921 (define_insn "*tst<mode>CCT"
922 [(set (reg CC_REGNUM)
923 (compare (match_operand:HQI 0 "nonimmediate_operand" "?Q,?S,d")
924 (match_operand:HQI 1 "const0_operand" "")))
925 (set (match_operand:HQI 2 "register_operand" "=d,d,0")
926 (match_dup 0))]
927 "s390_match_ccmode(insn, CCTmode)"
928 "@
929 icm\t%2,<icm_lo>,%S0
930 icmy\t%2,<icm_lo>,%S0
931 tml\t%0,<max_uint>"
932 [(set_attr "op_type" "RS,RSY,RI")
933 (set_attr "z10prop" "z10_super_E1,z10_super_E1,z10_super")])
934
935 (define_insn "*tsthiCCT_cconly"
936 [(set (reg CC_REGNUM)
937 (compare (match_operand:HI 0 "nonimmediate_operand" "Q,S,d")
938 (match_operand:HI 1 "const0_operand" "")))
939 (clobber (match_scratch:HI 2 "=d,d,X"))]
940 "s390_match_ccmode(insn, CCTmode)"
941 "@
942 icm\t%2,3,%S0
943 icmy\t%2,3,%S0
944 tml\t%0,65535"
945 [(set_attr "op_type" "RS,RSY,RI")
946 (set_attr "z10prop" "z10_super_E1,z10_super_E1,z10_super")])
947
948 (define_insn "*tstqiCCT_cconly"
949 [(set (reg CC_REGNUM)
950 (compare (match_operand:QI 0 "nonimmediate_operand" "?Q,?S,d")
951 (match_operand:QI 1 "const0_operand" "")))]
952 "s390_match_ccmode(insn, CCTmode)"
953 "@
954 cli\t%S0,0
955 cliy\t%S0,0
956 tml\t%0,255"
957 [(set_attr "op_type" "SI,SIY,RI")
958 (set_attr "z10prop" "z10_super,z10_super,z10_super")])
959
960 (define_insn "*tst<mode>"
961 [(set (reg CC_REGNUM)
962 (compare (match_operand:HQI 0 "s_operand" "Q,S")
963 (match_operand:HQI 1 "const0_operand" "")))
964 (set (match_operand:HQI 2 "register_operand" "=d,d")
965 (match_dup 0))]
966 "s390_match_ccmode(insn, CCSmode)"
967 "@
968 icm\t%2,<icm_lo>,%S0
969 icmy\t%2,<icm_lo>,%S0"
970 [(set_attr "op_type" "RS,RSY")
971 (set_attr "z10prop" "z10_super_E1,z10_super_E1")])
972
973 (define_insn "*tst<mode>_cconly"
974 [(set (reg CC_REGNUM)
975 (compare (match_operand:HQI 0 "s_operand" "Q,S")
976 (match_operand:HQI 1 "const0_operand" "")))
977 (clobber (match_scratch:HQI 2 "=d,d"))]
978 "s390_match_ccmode(insn, CCSmode)"
979 "@
980 icm\t%2,<icm_lo>,%S0
981 icmy\t%2,<icm_lo>,%S0"
982 [(set_attr "op_type" "RS,RSY")
983 (set_attr "z10prop" "z10_super_E1,z10_super_E1")])
984
985
986 ; Compare (equality) instructions
987
988 (define_insn "*cmpdi_cct"
989 [(set (reg CC_REGNUM)
990 (compare (match_operand:DI 0 "nonimmediate_operand" "%d,d,d,d,Q")
991 (match_operand:DI 1 "general_operand" "d,K,Os,RT,BQ")))]
992 "s390_match_ccmode (insn, CCTmode) && TARGET_ZARCH"
993 "@
994 cgr\t%0,%1
995 cghi\t%0,%h1
996 cgfi\t%0,%1
997 cg\t%0,%1
998 #"
999 [(set_attr "op_type" "RRE,RI,RIL,RXY,SS")
1000 (set_attr "z10prop" "z10_super_c,z10_super,z10_super,z10_super,*")])
1001
1002 (define_insn "*cmpsi_cct"
1003 [(set (reg CC_REGNUM)
1004 (compare (match_operand:SI 0 "nonimmediate_operand" "%d,d,d,d,d,Q")
1005 (match_operand:SI 1 "general_operand" "d,K,Os,R,T,BQ")))]
1006 "s390_match_ccmode (insn, CCTmode)"
1007 "@
1008 cr\t%0,%1
1009 chi\t%0,%h1
1010 cfi\t%0,%1
1011 c\t%0,%1
1012 cy\t%0,%1
1013 #"
1014 [(set_attr "op_type" "RR,RI,RIL,RX,RXY,SS")
1015 (set_attr "z10prop" "z10_super_c,z10_super,z10_super,z10_super,z10_super,*")])
1016
1017 ; Compare (signed) instructions
1018
1019 (define_insn "*cmpdi_ccs_sign"
1020 [(set (reg CC_REGNUM)
1021 (compare (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand"
1022 "d,RT,b"))
1023 (match_operand:DI 0 "register_operand" "d, d,d")))]
1024 "s390_match_ccmode(insn, CCSRmode) && TARGET_ZARCH"
1025 "@
1026 cgfr\t%0,%1
1027 cgf\t%0,%1
1028 cgfrl\t%0,%1"
1029 [(set_attr "op_type" "RRE,RXY,RIL")
1030 (set_attr "z10prop" "z10_c,*,*")
1031 (set_attr "type" "*,*,larl")])
1032
1033
1034
1035 (define_insn "*cmpsi_ccs_sign"
1036 [(set (reg CC_REGNUM)
1037 (compare (sign_extend:SI (match_operand:HI 1 "memory_operand" "R,T,b"))
1038 (match_operand:SI 0 "register_operand" "d,d,d")))]
1039 "s390_match_ccmode(insn, CCSRmode)"
1040 "@
1041 ch\t%0,%1
1042 chy\t%0,%1
1043 chrl\t%0,%1"
1044 [(set_attr "op_type" "RX,RXY,RIL")
1045 (set_attr "cpu_facility" "*,*,z10")
1046 (set_attr "type" "*,*,larl")
1047 (set_attr "z196prop" "z196_cracked,z196_cracked,z196_cracked")])
1048
1049 (define_insn "*cmphi_ccs_z10"
1050 [(set (reg CC_REGNUM)
1051 (compare (match_operand:HI 0 "s_operand" "Q")
1052 (match_operand:HI 1 "immediate_operand" "K")))]
1053 "s390_match_ccmode(insn, CCSmode) && TARGET_Z10"
1054 "chhsi\t%0,%1"
1055 [(set_attr "op_type" "SIL")
1056 (set_attr "z196prop" "z196_cracked")])
1057
1058 (define_insn "*cmpdi_ccs_signhi_rl"
1059 [(set (reg CC_REGNUM)
1060 (compare (sign_extend:DI (match_operand:HI 1 "memory_operand" "RT,b"))
1061 (match_operand:GPR 0 "register_operand" "d,d")))]
1062 "s390_match_ccmode(insn, CCSRmode) && TARGET_Z10"
1063 "@
1064 cgh\t%0,%1
1065 cghrl\t%0,%1"
1066 [(set_attr "op_type" "RXY,RIL")
1067 (set_attr "type" "*,larl")])
1068
1069 ; cr, chi, cfi, c, cy, cgr, cghi, cgfi, cg, chsi, cghsi, crl, cgrl
1070 (define_insn "*cmp<mode>_ccs"
1071 [(set (reg CC_REGNUM)
1072 (compare (match_operand:GPR 0 "nonimmediate_operand"
1073 "d,d,Q, d,d,d,d")
1074 (match_operand:GPR 1 "general_operand"
1075 "d,K,K,Os,R,T,b")))]
1076 "s390_match_ccmode(insn, CCSmode)"
1077 "@
1078 c<g>r\t%0,%1
1079 c<g>hi\t%0,%h1
1080 c<g>hsi\t%0,%h1
1081 c<g>fi\t%0,%1
1082 c<g>\t%0,%1
1083 c<y>\t%0,%1
1084 c<g>rl\t%0,%1"
1085 [(set_attr "op_type" "RR<E>,RI,SIL,RIL,RX<Y>,RXY,RIL")
1086 (set_attr "cpu_facility" "*,*,z10,extimm,*,*,z10")
1087 (set_attr "type" "*,*,*,*,*,*,larl")
1088 (set_attr "z10prop" "z10_super_c,z10_super,z10_super,z10_super,z10_super,z10_super,z10_super")])
1089
1090
1091 ; Compare (unsigned) instructions
1092
1093 (define_insn "*cmpsi_ccu_zerohi_rlsi"
1094 [(set (reg CC_REGNUM)
1095 (compare (zero_extend:SI (mem:HI (match_operand:SI 1
1096 "larl_operand" "X")))
1097 (match_operand:SI 0 "register_operand" "d")))]
1098 "s390_match_ccmode(insn, CCURmode) && TARGET_Z10"
1099 "clhrl\t%0,%1"
1100 [(set_attr "op_type" "RIL")
1101 (set_attr "type" "larl")
1102 (set_attr "z10prop" "z10_super")])
1103
1104 ; clhrl, clghrl
1105 (define_insn "*cmp<GPR:mode>_ccu_zerohi_rldi"
1106 [(set (reg CC_REGNUM)
1107 (compare (zero_extend:GPR (mem:HI (match_operand:DI 1
1108 "larl_operand" "X")))
1109 (match_operand:GPR 0 "register_operand" "d")))]
1110 "s390_match_ccmode(insn, CCURmode) && TARGET_Z10"
1111 "cl<g>hrl\t%0,%1"
1112 [(set_attr "op_type" "RIL")
1113 (set_attr "type" "larl")
1114 (set_attr "z10prop" "z10_super")])
1115
1116 (define_insn "*cmpdi_ccu_zero"
1117 [(set (reg CC_REGNUM)
1118 (compare (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand"
1119 "d,RT,b"))
1120 (match_operand:DI 0 "register_operand" "d, d,d")))]
1121 "s390_match_ccmode (insn, CCURmode) && TARGET_ZARCH"
1122 "@
1123 clgfr\t%0,%1
1124 clgf\t%0,%1
1125 clgfrl\t%0,%1"
1126 [(set_attr "op_type" "RRE,RXY,RIL")
1127 (set_attr "cpu_facility" "*,*,z10")
1128 (set_attr "type" "*,*,larl")
1129 (set_attr "z10prop" "z10_super_c,z10_super_E1,z10_super")])
1130
1131 (define_insn "*cmpdi_ccu"
1132 [(set (reg CC_REGNUM)
1133 (compare (match_operand:DI 0 "nonimmediate_operand"
1134 "d, d,d,Q, d, Q,BQ")
1135 (match_operand:DI 1 "general_operand"
1136 "d,Op,b,D,RT,BQ,Q")))]
1137 "s390_match_ccmode (insn, CCUmode) && TARGET_ZARCH"
1138 "@
1139 clgr\t%0,%1
1140 clgfi\t%0,%1
1141 clgrl\t%0,%1
1142 clghsi\t%0,%x1
1143 clg\t%0,%1
1144 #
1145 #"
1146 [(set_attr "op_type" "RRE,RIL,RIL,SIL,RXY,SS,SS")
1147 (set_attr "cpu_facility" "*,extimm,z10,z10,*,*,*")
1148 (set_attr "type" "*,*,larl,*,*,*,*")
1149 (set_attr "z10prop" "z10_super_c,z10_super,z10_super,z10_super,z10_super,*,*")])
1150
1151 (define_insn "*cmpsi_ccu"
1152 [(set (reg CC_REGNUM)
1153 (compare (match_operand:SI 0 "nonimmediate_operand" "d, d,d,Q,d,d, Q,BQ")
1154 (match_operand:SI 1 "general_operand" "d,Os,b,D,R,T,BQ, Q")))]
1155 "s390_match_ccmode (insn, CCUmode)"
1156 "@
1157 clr\t%0,%1
1158 clfi\t%0,%o1
1159 clrl\t%0,%1
1160 clfhsi\t%0,%x1
1161 cl\t%0,%1
1162 cly\t%0,%1
1163 #
1164 #"
1165 [(set_attr "op_type" "RR,RIL,RIL,SIL,RX,RXY,SS,SS")
1166 (set_attr "cpu_facility" "*,extimm,z10,z10,*,*,*,*")
1167 (set_attr "type" "*,*,larl,*,*,*,*,*")
1168 (set_attr "z10prop" "z10_super_c,z10_super,z10_super,z10_super,z10_super,z10_super,*,*")])
1169
1170 (define_insn "*cmphi_ccu"
1171 [(set (reg CC_REGNUM)
1172 (compare (match_operand:HI 0 "nonimmediate_operand" "d,d,Q,Q,BQ")
1173 (match_operand:HI 1 "general_operand" "Q,S,D,BQ,Q")))]
1174 "s390_match_ccmode (insn, CCUmode)
1175 && !register_operand (operands[1], HImode)"
1176 "@
1177 clm\t%0,3,%S1
1178 clmy\t%0,3,%S1
1179 clhhsi\t%0,%1
1180 #
1181 #"
1182 [(set_attr "op_type" "RS,RSY,SIL,SS,SS")
1183 (set_attr "cpu_facility" "*,*,z10,*,*")
1184 (set_attr "z10prop" "*,*,z10_super,*,*")])
1185
1186 (define_insn "*cmpqi_ccu"
1187 [(set (reg CC_REGNUM)
1188 (compare (match_operand:QI 0 "nonimmediate_operand" "d,d,Q,S,Q,BQ")
1189 (match_operand:QI 1 "general_operand" "Q,S,n,n,BQ,Q")))]
1190 "s390_match_ccmode (insn, CCUmode)
1191 && !register_operand (operands[1], QImode)"
1192 "@
1193 clm\t%0,1,%S1
1194 clmy\t%0,1,%S1
1195 cli\t%S0,%b1
1196 cliy\t%S0,%b1
1197 #
1198 #"
1199 [(set_attr "op_type" "RS,RSY,SI,SIY,SS,SS")
1200 (set_attr "z10prop" "*,*,z10_super,z10_super,*,*")])
1201
1202
1203 ; Block compare (CLC) instruction patterns.
1204
1205 (define_insn "*clc"
1206 [(set (reg CC_REGNUM)
1207 (compare (match_operand:BLK 0 "memory_operand" "Q")
1208 (match_operand:BLK 1 "memory_operand" "Q")))
1209 (use (match_operand 2 "const_int_operand" "n"))]
1210 "s390_match_ccmode (insn, CCUmode)
1211 && INTVAL (operands[2]) >= 1 && INTVAL (operands[2]) <= 256"
1212 "clc\t%O0(%2,%R0),%S1"
1213 [(set_attr "op_type" "SS")])
1214
1215 (define_split
1216 [(set (reg CC_REGNUM)
1217 (compare (match_operand 0 "memory_operand" "")
1218 (match_operand 1 "memory_operand" "")))]
1219 "reload_completed
1220 && s390_match_ccmode (insn, CCUmode)
1221 && GET_MODE (operands[0]) == GET_MODE (operands[1])
1222 && GET_MODE_SIZE (GET_MODE (operands[0])) > 0"
1223 [(parallel
1224 [(set (match_dup 0) (match_dup 1))
1225 (use (match_dup 2))])]
1226 {
1227 operands[2] = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[0])));
1228 operands[0] = adjust_address (operands[0], BLKmode, 0);
1229 operands[1] = adjust_address (operands[1], BLKmode, 0);
1230
1231 operands[1] = gen_rtx_COMPARE (GET_MODE (SET_DEST (PATTERN (curr_insn))),
1232 operands[0], operands[1]);
1233 operands[0] = SET_DEST (PATTERN (curr_insn));
1234 })
1235
1236
1237 ; (TF|DF|SF|TD|DD|SD) instructions
1238
1239 ; ltxbr, ltdbr, ltebr, ltxtr, ltdtr
1240 (define_insn "*cmp<mode>_ccs_0"
1241 [(set (reg CC_REGNUM)
1242 (compare (match_operand:FP 0 "register_operand" "f")
1243 (match_operand:FP 1 "const0_operand" "")))]
1244 "s390_match_ccmode(insn, CCSmode) && TARGET_HARD_FLOAT"
1245 "lt<xde><bt>r\t%0,%0"
1246 [(set_attr "op_type" "RRE")
1247 (set_attr "type" "fsimp<mode>")])
1248
1249 ; cxtr, cxbr, cdtr, cdbr, cebr, cdb, ceb
1250 (define_insn "*cmp<mode>_ccs"
1251 [(set (reg CC_REGNUM)
1252 (compare (match_operand:FP 0 "register_operand" "f,f")
1253 (match_operand:FP 1 "general_operand" "f,<Rf>")))]
1254 "s390_match_ccmode(insn, CCSmode) && TARGET_HARD_FLOAT"
1255 "@
1256 c<xde><bt>r\t%0,%1
1257 c<xde>b\t%0,%1"
1258 [(set_attr "op_type" "RRE,RXE")
1259 (set_attr "type" "fsimp<mode>")])
1260
1261 ; wfcedbs, wfchdbs, wfchedbs
1262 (define_insn "*vec_cmp<insn_cmp>df_cconly"
1263 [(set (reg:VFCMP CC_REGNUM)
1264 (compare:VFCMP (match_operand:DF 0 "register_operand" "v")
1265 (match_operand:DF 1 "register_operand" "v")))
1266 (clobber (match_scratch:V2DI 2 "=v"))]
1267 "TARGET_Z13 && TARGET_HARD_FLOAT"
1268 "wfc<asm_fcmp>dbs\t%v2,%v0,%v1"
1269 [(set_attr "op_type" "VRR")])
1270
1271 ; Compare and Branch instructions
1272
1273 ; cij, cgij, crj, cgrj, cfi, cgfi, cr, cgr
1274 ; The following instructions do a complementary access of their second
1275 ; operand (z01 only): crj_c, cgrjc, cr, cgr
1276 (define_insn "*cmp_and_br_signed_<mode>"
1277 [(set (pc)
1278 (if_then_else (match_operator 0 "s390_signed_integer_comparison"
1279 [(match_operand:GPR 1 "register_operand" "d,d")
1280 (match_operand:GPR 2 "nonmemory_operand" "d,C")])
1281 (label_ref (match_operand 3 "" ""))
1282 (pc)))
1283 (clobber (reg:CC CC_REGNUM))]
1284 "TARGET_Z10 && !TARGET_AVOID_CMP_AND_BRANCH"
1285 {
1286 if (get_attr_length (insn) == 6)
1287 return which_alternative ?
1288 "c<g>ij%C0\t%1,%c2,%l3" : "c<g>rj%C0\t%1,%2,%l3";
1289 else
1290 return which_alternative ?
1291 "c<g>fi\t%1,%c2\;jg%C0\t%l3" : "c<g>r\t%1,%2\;jg%C0\t%l3";
1292 }
1293 [(set_attr "op_type" "RIE")
1294 (set_attr "type" "branch")
1295 (set_attr "z10prop" "z10_super_c,z10_super")
1296 (set (attr "length")
1297 (if_then_else (lt (abs (minus (pc) (match_dup 3))) (const_int 60000))
1298 (const_int 6) (const_int 12)))]) ; 8 byte for cr/jg
1299 ; 10 byte for cgr/jg
1300
1301 ; clij, clgij, clrj, clgrj, clfi, clgfi, clr, clgr
1302 ; The following instructions do a complementary access of their second
1303 ; operand (z10 only): clrj, clgrj, clr, clgr
1304 (define_insn "*cmp_and_br_unsigned_<mode>"
1305 [(set (pc)
1306 (if_then_else (match_operator 0 "s390_unsigned_integer_comparison"
1307 [(match_operand:GPR 1 "register_operand" "d,d")
1308 (match_operand:GPR 2 "nonmemory_operand" "d,I")])
1309 (label_ref (match_operand 3 "" ""))
1310 (pc)))
1311 (clobber (reg:CC CC_REGNUM))]
1312 "TARGET_Z10 && !TARGET_AVOID_CMP_AND_BRANCH"
1313 {
1314 if (get_attr_length (insn) == 6)
1315 return which_alternative ?
1316 "cl<g>ij%C0\t%1,%b2,%l3" : "cl<g>rj%C0\t%1,%2,%l3";
1317 else
1318 return which_alternative ?
1319 "cl<g>fi\t%1,%b2\;jg%C0\t%l3" : "cl<g>r\t%1,%2\;jg%C0\t%l3";
1320 }
1321 [(set_attr "op_type" "RIE")
1322 (set_attr "type" "branch")
1323 (set_attr "z10prop" "z10_super_c,z10_super")
1324 (set (attr "length")
1325 (if_then_else (lt (abs (minus (pc) (match_dup 3))) (const_int 60000))
1326 (const_int 6) (const_int 12)))]) ; 8 byte for clr/jg
1327 ; 10 byte for clgr/jg
1328
1329 ; And now the same two patterns as above but with a negated CC mask.
1330
1331 ; cij, cgij, crj, cgrj, cfi, cgfi, cr, cgr
1332 ; The following instructions do a complementary access of their second
1333 ; operand (z01 only): crj_c, cgrjc, cr, cgr
1334 (define_insn "*icmp_and_br_signed_<mode>"
1335 [(set (pc)
1336 (if_then_else (match_operator 0 "s390_signed_integer_comparison"
1337 [(match_operand:GPR 1 "register_operand" "d,d")
1338 (match_operand:GPR 2 "nonmemory_operand" "d,C")])
1339 (pc)
1340 (label_ref (match_operand 3 "" ""))))
1341 (clobber (reg:CC CC_REGNUM))]
1342 "TARGET_Z10 && !TARGET_AVOID_CMP_AND_BRANCH"
1343 {
1344 if (get_attr_length (insn) == 6)
1345 return which_alternative ?
1346 "c<g>ij%D0\t%1,%c2,%l3" : "c<g>rj%D0\t%1,%2,%l3";
1347 else
1348 return which_alternative ?
1349 "c<g>fi\t%1,%c2\;jg%D0\t%l3" : "c<g>r\t%1,%2\;jg%D0\t%l3";
1350 }
1351 [(set_attr "op_type" "RIE")
1352 (set_attr "type" "branch")
1353 (set_attr "z10prop" "z10_super_c,z10_super")
1354 (set (attr "length")
1355 (if_then_else (lt (abs (minus (pc) (match_dup 3))) (const_int 60000))
1356 (const_int 6) (const_int 12)))]) ; 8 byte for cr/jg
1357 ; 10 byte for cgr/jg
1358
1359 ; clij, clgij, clrj, clgrj, clfi, clgfi, clr, clgr
1360 ; The following instructions do a complementary access of their second
1361 ; operand (z10 only): clrj, clgrj, clr, clgr
1362 (define_insn "*icmp_and_br_unsigned_<mode>"
1363 [(set (pc)
1364 (if_then_else (match_operator 0 "s390_unsigned_integer_comparison"
1365 [(match_operand:GPR 1 "register_operand" "d,d")
1366 (match_operand:GPR 2 "nonmemory_operand" "d,I")])
1367 (pc)
1368 (label_ref (match_operand 3 "" ""))))
1369 (clobber (reg:CC CC_REGNUM))]
1370 "TARGET_Z10 && !TARGET_AVOID_CMP_AND_BRANCH"
1371 {
1372 if (get_attr_length (insn) == 6)
1373 return which_alternative ?
1374 "cl<g>ij%D0\t%1,%b2,%l3" : "cl<g>rj%D0\t%1,%2,%l3";
1375 else
1376 return which_alternative ?
1377 "cl<g>fi\t%1,%b2\;jg%D0\t%l3" : "cl<g>r\t%1,%2\;jg%D0\t%l3";
1378 }
1379 [(set_attr "op_type" "RIE")
1380 (set_attr "type" "branch")
1381 (set_attr "z10prop" "z10_super_c,z10_super")
1382 (set (attr "length")
1383 (if_then_else (lt (abs (minus (pc) (match_dup 3))) (const_int 60000))
1384 (const_int 6) (const_int 12)))]) ; 8 byte for clr/jg
1385 ; 10 byte for clgr/jg
1386
1387 ;;
1388 ;;- Move instructions.
1389 ;;
1390
1391 ;
1392 ; movti instruction pattern(s).
1393 ;
1394
1395 ; FIXME: More constants are possible by enabling jxx, jyy constraints
1396 ; for TImode (use double-int for the calculations)
1397 (define_insn "movti"
1398 [(set (match_operand:TI 0 "nonimmediate_operand" "=d,QS,v, v, v,v,d, v,QR, d,o")
1399 (match_operand:TI 1 "general_operand" "QS, d,v,j00,jm1,d,v,QR, v,dPRT,d"))]
1400 "TARGET_ZARCH"
1401 "@
1402 lmg\t%0,%N0,%S1
1403 stmg\t%1,%N1,%S0
1404 vlr\t%v0,%v1
1405 vzero\t%v0
1406 vone\t%v0
1407 vlvgp\t%v0,%1,%N1
1408 #
1409 vl\t%v0,%1
1410 vst\t%v1,%0
1411 #
1412 #"
1413 [(set_attr "op_type" "RSY,RSY,VRR,VRI,VRI,VRR,*,VRX,VRX,*,*")
1414 (set_attr "type" "lm,stm,*,*,*,*,*,*,*,*,*")
1415 (set_attr "cpu_facility" "*,*,vec,vec,vec,vec,vec,vec,vec,*,*")])
1416
1417 (define_split
1418 [(set (match_operand:TI 0 "nonimmediate_operand" "")
1419 (match_operand:TI 1 "general_operand" ""))]
1420 "TARGET_ZARCH && reload_completed
1421 && s390_split_ok_p (operands[0], operands[1], TImode, 0)"
1422 [(set (match_dup 2) (match_dup 4))
1423 (set (match_dup 3) (match_dup 5))]
1424 {
1425 operands[2] = operand_subword (operands[0], 0, 0, TImode);
1426 operands[3] = operand_subword (operands[0], 1, 0, TImode);
1427 operands[4] = operand_subword (operands[1], 0, 0, TImode);
1428 operands[5] = operand_subword (operands[1], 1, 0, TImode);
1429 })
1430
1431 (define_split
1432 [(set (match_operand:TI 0 "nonimmediate_operand" "")
1433 (match_operand:TI 1 "general_operand" ""))]
1434 "TARGET_ZARCH && reload_completed
1435 && s390_split_ok_p (operands[0], operands[1], TImode, 1)"
1436 [(set (match_dup 2) (match_dup 4))
1437 (set (match_dup 3) (match_dup 5))]
1438 {
1439 operands[2] = operand_subword (operands[0], 1, 0, TImode);
1440 operands[3] = operand_subword (operands[0], 0, 0, TImode);
1441 operands[4] = operand_subword (operands[1], 1, 0, TImode);
1442 operands[5] = operand_subword (operands[1], 0, 0, TImode);
1443 })
1444
1445 ; Use part of the TImode target reg to perform the address
1446 ; calculation. If the TImode value is supposed to be copied into a VR
1447 ; this splitter is not necessary.
1448 (define_split
1449 [(set (match_operand:TI 0 "register_operand" "")
1450 (match_operand:TI 1 "memory_operand" ""))]
1451 "TARGET_ZARCH && reload_completed
1452 && !VECTOR_REG_P (operands[0])
1453 && !s_operand (operands[1], VOIDmode)"
1454 [(set (match_dup 0) (match_dup 1))]
1455 {
1456 rtx addr = operand_subword (operands[0], 1, 0, TImode);
1457 addr = gen_lowpart (Pmode, addr);
1458 s390_load_address (addr, XEXP (operands[1], 0));
1459 operands[1] = replace_equiv_address (operands[1], addr);
1460 })
1461
1462
1463 ; Split a VR -> GPR TImode move into 2 vector load GR from VR element.
1464 ; For the higher order bits we do simply a DImode move while the
1465 ; second part is done via vec extract. Both will end up as vlgvg.
1466 (define_split
1467 [(set (match_operand:TI 0 "register_operand" "")
1468 (match_operand:TI 1 "register_operand" ""))]
1469 "TARGET_VX && reload_completed
1470 && GENERAL_REG_P (operands[0])
1471 && VECTOR_REG_P (operands[1])"
1472 [(set (match_dup 2) (match_dup 4))
1473 (set (match_dup 3) (unspec:DI [(match_dup 5) (const_int 1)]
1474 UNSPEC_VEC_EXTRACT))]
1475 {
1476 operands[2] = operand_subword (operands[0], 0, 0, TImode);
1477 operands[3] = operand_subword (operands[0], 1, 0, TImode);
1478 operands[4] = gen_rtx_REG (DImode, REGNO (operands[1]));
1479 operands[5] = gen_rtx_REG (V2DImode, REGNO (operands[1]));
1480 })
1481
1482 ;
1483 ; Patterns used for secondary reloads
1484 ;
1485
1486 ; z10 provides move instructions accepting larl memory operands.
1487 ; Unfortunately there is no such variant for QI, TI and FP mode moves.
1488 ; These patterns are also used for unaligned SI and DI accesses.
1489
1490 (define_expand "reload<ALL:mode><P:mode>_tomem_z10"
1491 [(parallel [(match_operand:ALL 0 "memory_operand" "")
1492 (match_operand:ALL 1 "register_operand" "=d")
1493 (match_operand:P 2 "register_operand" "=&a")])]
1494 "TARGET_Z10"
1495 {
1496 s390_reload_symref_address (operands[1], operands[0], operands[2], 1);
1497 DONE;
1498 })
1499
1500 (define_expand "reload<ALL:mode><P:mode>_toreg_z10"
1501 [(parallel [(match_operand:ALL 0 "register_operand" "=d")
1502 (match_operand:ALL 1 "memory_operand" "")
1503 (match_operand:P 2 "register_operand" "=a")])]
1504 "TARGET_Z10"
1505 {
1506 s390_reload_symref_address (operands[0], operands[1], operands[2], 0);
1507 DONE;
1508 })
1509
1510 (define_expand "reload<P:mode>_larl_odd_addend_z10"
1511 [(parallel [(match_operand:P 0 "register_operand" "=d")
1512 (match_operand:P 1 "larl_operand" "")
1513 (match_operand:P 2 "register_operand" "=a")])]
1514 "TARGET_Z10"
1515 {
1516 s390_reload_larl_operand (operands[0], operands[1], operands[2]);
1517 DONE;
1518 })
1519
1520 ; Handles loading a PLUS (load address) expression
1521
1522 (define_expand "reload<mode>_plus"
1523 [(parallel [(match_operand:P 0 "register_operand" "=a")
1524 (match_operand:P 1 "s390_plus_operand" "")
1525 (match_operand:P 2 "register_operand" "=&a")])]
1526 ""
1527 {
1528 s390_expand_plus_operand (operands[0], operands[1], operands[2]);
1529 DONE;
1530 })
1531
1532 ; Not all the indirect memory access instructions support the full
1533 ; format (long disp + index + base). So whenever a move from/to such
1534 ; an address is required and the instruction cannot deal with it we do
1535 ; a load address into a scratch register first and use this as the new
1536 ; base register.
1537 ; This in particular is used for:
1538 ; - non-offsetable memory accesses for multiword moves
1539 ; - full vector reg moves with long displacements
1540
1541 (define_expand "reload<mode>_la_in"
1542 [(parallel [(match_operand 0 "register_operand" "")
1543 (match_operand 1 "" "")
1544 (match_operand:P 2 "register_operand" "=&a")])]
1545 ""
1546 {
1547 gcc_assert (MEM_P (operands[1]));
1548 s390_load_address (operands[2], find_replacement (&XEXP (operands[1], 0)));
1549 operands[1] = replace_equiv_address (operands[1], operands[2]);
1550 emit_move_insn (operands[0], operands[1]);
1551 DONE;
1552 })
1553
1554 (define_expand "reload<mode>_la_out"
1555 [(parallel [(match_operand 0 "" "")
1556 (match_operand 1 "register_operand" "")
1557 (match_operand:P 2 "register_operand" "=&a")])]
1558 ""
1559 {
1560 gcc_assert (MEM_P (operands[0]));
1561 s390_load_address (operands[2], find_replacement (&XEXP (operands[0], 0)));
1562 operands[0] = replace_equiv_address (operands[0], operands[2]);
1563 emit_move_insn (operands[0], operands[1]);
1564 DONE;
1565 })
1566
1567 (define_expand "reload<mode>_PIC_addr"
1568 [(parallel [(match_operand 0 "register_operand" "=d")
1569 (match_operand 1 "larl_operand" "")
1570 (match_operand:P 2 "register_operand" "=a")])]
1571 ""
1572 {
1573 rtx new_rtx = legitimize_pic_address (operands[1], operands[2]);
1574 emit_move_insn (operands[0], new_rtx);
1575 })
1576
1577 ;
1578 ; movdi instruction pattern(s).
1579 ;
1580
1581 (define_expand "movdi"
1582 [(set (match_operand:DI 0 "general_operand" "")
1583 (match_operand:DI 1 "general_operand" ""))]
1584 ""
1585 {
1586 /* Handle symbolic constants. */
1587 if (TARGET_64BIT
1588 && (SYMBOLIC_CONST (operands[1])
1589 || (GET_CODE (operands[1]) == PLUS
1590 && XEXP (operands[1], 0) == pic_offset_table_rtx
1591 && SYMBOLIC_CONST (XEXP (operands[1], 1)))))
1592 emit_symbolic_move (operands);
1593 })
1594
1595 (define_insn "*movdi_larl"
1596 [(set (match_operand:DI 0 "register_operand" "=d")
1597 (match_operand:DI 1 "larl_operand" "X"))]
1598 "TARGET_64BIT
1599 && !FP_REG_P (operands[0])"
1600 "larl\t%0,%1"
1601 [(set_attr "op_type" "RIL")
1602 (set_attr "type" "larl")
1603 (set_attr "z10prop" "z10_super_A1")])
1604
1605 (define_insn "*movdi_64"
1606 [(set (match_operand:DI 0 "nonimmediate_operand"
1607 "=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")
1608 (match_operand:DI 1 "general_operand"
1609 " 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"))]
1610 "TARGET_ZARCH"
1611 "@
1612 lghi\t%0,%h1
1613 llihh\t%0,%i1
1614 llihl\t%0,%i1
1615 llilh\t%0,%i1
1616 llill\t%0,%i1
1617 lgfi\t%0,%1
1618 llihf\t%0,%k1
1619 llilf\t%0,%k1
1620 ldgr\t%0,%1
1621 lgdr\t%0,%1
1622 lay\t%0,%a1
1623 lgrl\t%0,%1
1624 lgr\t%0,%1
1625 lg\t%0,%1
1626 stg\t%1,%0
1627 ldr\t%0,%1
1628 ld\t%0,%1
1629 ldy\t%0,%1
1630 std\t%1,%0
1631 stdy\t%1,%0
1632 stgrl\t%1,%0
1633 mvghi\t%0,%1
1634 #
1635 #
1636 stam\t%1,%N1,%S0
1637 lam\t%0,%N0,%S1
1638 vleig\t%v0,%h1,0
1639 vlr\t%v0,%v1
1640 vlvgg\t%v0,%1,0
1641 vlgvg\t%0,%v1,0
1642 vleg\t%v0,%1,0
1643 vsteg\t%v1,%0,0"
1644 [(set_attr "op_type" "RI,RI,RI,RI,RI,RIL,RIL,RIL,RRE,RRE,RXY,RIL,RRE,RXY,
1645 RXY,RR,RX,RXY,RX,RXY,RIL,SIL,*,*,RS,RS,VRI,VRR,VRS,VRS,VRX,VRX")
1646 (set_attr "type" "*,*,*,*,*,*,*,*,floaddf,floaddf,la,larl,lr,load,store,
1647 floaddf,floaddf,floaddf,fstoredf,fstoredf,larl,*,*,*,*,
1648 *,*,*,*,*,*,*")
1649 (set_attr "cpu_facility" "*,*,*,*,*,extimm,extimm,extimm,dfp,dfp,longdisp,
1650 z10,*,*,*,*,*,longdisp,*,longdisp,
1651 z10,z10,*,*,*,*,vec,vec,vec,vec,vec,vec")
1652 (set_attr "z10prop" "z10_fwd_A1,
1653 z10_fwd_E1,
1654 z10_fwd_E1,
1655 z10_fwd_E1,
1656 z10_fwd_E1,
1657 z10_fwd_A1,
1658 z10_fwd_E1,
1659 z10_fwd_E1,
1660 *,
1661 *,
1662 z10_fwd_A1,
1663 z10_fwd_A3,
1664 z10_fr_E1,
1665 z10_fwd_A3,
1666 z10_rec,
1667 *,
1668 *,
1669 *,
1670 *,
1671 *,
1672 z10_rec,
1673 z10_super,
1674 *,
1675 *,
1676 *,
1677 *,*,*,*,*,*,*")
1678 ])
1679
1680 (define_split
1681 [(set (match_operand:DI 0 "register_operand" "")
1682 (match_operand:DI 1 "register_operand" ""))]
1683 "TARGET_ZARCH && ACCESS_REG_P (operands[1])"
1684 [(set (match_dup 2) (match_dup 3))
1685 (set (match_dup 0) (ashift:DI (match_dup 0) (const_int 32)))
1686 (set (strict_low_part (match_dup 2)) (match_dup 4))]
1687 "operands[2] = gen_lowpart (SImode, operands[0]);
1688 s390_split_access_reg (operands[1], &operands[4], &operands[3]);")
1689
1690 (define_split
1691 [(set (match_operand:DI 0 "register_operand" "")
1692 (match_operand:DI 1 "register_operand" ""))]
1693 "TARGET_ZARCH && ACCESS_REG_P (operands[0])
1694 && dead_or_set_p (insn, operands[1])"
1695 [(set (match_dup 3) (match_dup 2))
1696 (set (match_dup 1) (lshiftrt:DI (match_dup 1) (const_int 32)))
1697 (set (match_dup 4) (match_dup 2))]
1698 "operands[2] = gen_lowpart (SImode, operands[1]);
1699 s390_split_access_reg (operands[0], &operands[3], &operands[4]);")
1700
1701 (define_split
1702 [(set (match_operand:DI 0 "register_operand" "")
1703 (match_operand:DI 1 "register_operand" ""))]
1704 "TARGET_ZARCH && ACCESS_REG_P (operands[0])
1705 && !dead_or_set_p (insn, operands[1])"
1706 [(set (match_dup 3) (match_dup 2))
1707 (set (match_dup 1) (rotate:DI (match_dup 1) (const_int 32)))
1708 (set (match_dup 4) (match_dup 2))
1709 (set (match_dup 1) (rotate:DI (match_dup 1) (const_int 32)))]
1710 "operands[2] = gen_lowpart (SImode, operands[1]);
1711 s390_split_access_reg (operands[0], &operands[3], &operands[4]);")
1712
1713 (define_insn "*movdi_31"
1714 [(set (match_operand:DI 0 "nonimmediate_operand"
1715 "=d,d,Q,S,d ,o,!*f,!*f,!*f,!R,!T,d")
1716 (match_operand:DI 1 "general_operand"
1717 " Q,S,d,d,dPRT,d, *f, R, T,*f,*f,b"))]
1718 "!TARGET_ZARCH"
1719 "@
1720 lm\t%0,%N0,%S1
1721 lmy\t%0,%N0,%S1
1722 stm\t%1,%N1,%S0
1723 stmy\t%1,%N1,%S0
1724 #
1725 #
1726 ldr\t%0,%1
1727 ld\t%0,%1
1728 ldy\t%0,%1
1729 std\t%1,%0
1730 stdy\t%1,%0
1731 #"
1732 [(set_attr "op_type" "RS,RSY,RS,RSY,*,*,RR,RX,RXY,RX,RXY,*")
1733 (set_attr "type" "lm,lm,stm,stm,*,*,floaddf,floaddf,floaddf,fstoredf,fstoredf,*")
1734 (set_attr "cpu_facility" "*,*,*,*,*,*,*,*,*,*,*,z10")])
1735
1736 ; For a load from a symbol ref we can use one of the target registers
1737 ; together with larl to load the address.
1738 (define_split
1739 [(set (match_operand:DI 0 "register_operand" "")
1740 (match_operand:DI 1 "memory_operand" ""))]
1741 "!TARGET_ZARCH && reload_completed && TARGET_Z10
1742 && larl_operand (XEXP (operands[1], 0), SImode)"
1743 [(set (match_dup 2) (match_dup 3))
1744 (set (match_dup 0) (match_dup 1))]
1745 {
1746 operands[2] = operand_subword (operands[0], 1, 0, DImode);
1747 operands[3] = XEXP (operands[1], 0);
1748 operands[1] = replace_equiv_address (operands[1], operands[2]);
1749 })
1750
1751 (define_split
1752 [(set (match_operand:DI 0 "nonimmediate_operand" "")
1753 (match_operand:DI 1 "general_operand" ""))]
1754 "!TARGET_ZARCH && reload_completed
1755 && s390_split_ok_p (operands[0], operands[1], DImode, 0)"
1756 [(set (match_dup 2) (match_dup 4))
1757 (set (match_dup 3) (match_dup 5))]
1758 {
1759 operands[2] = operand_subword (operands[0], 0, 0, DImode);
1760 operands[3] = operand_subword (operands[0], 1, 0, DImode);
1761 operands[4] = operand_subword (operands[1], 0, 0, DImode);
1762 operands[5] = operand_subword (operands[1], 1, 0, DImode);
1763 })
1764
1765 (define_split
1766 [(set (match_operand:DI 0 "nonimmediate_operand" "")
1767 (match_operand:DI 1 "general_operand" ""))]
1768 "!TARGET_ZARCH && reload_completed
1769 && s390_split_ok_p (operands[0], operands[1], DImode, 1)"
1770 [(set (match_dup 2) (match_dup 4))
1771 (set (match_dup 3) (match_dup 5))]
1772 {
1773 operands[2] = operand_subword (operands[0], 1, 0, DImode);
1774 operands[3] = operand_subword (operands[0], 0, 0, DImode);
1775 operands[4] = operand_subword (operands[1], 1, 0, DImode);
1776 operands[5] = operand_subword (operands[1], 0, 0, DImode);
1777 })
1778
1779 (define_split
1780 [(set (match_operand:DI 0 "register_operand" "")
1781 (match_operand:DI 1 "memory_operand" ""))]
1782 "!TARGET_ZARCH && reload_completed
1783 && !FP_REG_P (operands[0])
1784 && !s_operand (operands[1], VOIDmode)"
1785 [(set (match_dup 0) (match_dup 1))]
1786 {
1787 rtx addr = operand_subword (operands[0], 1, 0, DImode);
1788 s390_load_address (addr, XEXP (operands[1], 0));
1789 operands[1] = replace_equiv_address (operands[1], addr);
1790 })
1791
1792 (define_peephole2
1793 [(set (match_operand:DI 0 "register_operand" "")
1794 (mem:DI (match_operand 1 "address_operand" "")))]
1795 "TARGET_ZARCH
1796 && !FP_REG_P (operands[0])
1797 && GET_CODE (operands[1]) == SYMBOL_REF
1798 && CONSTANT_POOL_ADDRESS_P (operands[1])
1799 && get_pool_mode (operands[1]) == DImode
1800 && legitimate_reload_constant_p (get_pool_constant (operands[1]))"
1801 [(set (match_dup 0) (match_dup 2))]
1802 "operands[2] = get_pool_constant (operands[1]);")
1803
1804 (define_insn "*la_64"
1805 [(set (match_operand:DI 0 "register_operand" "=d,d")
1806 (match_operand:QI 1 "address_operand" "ZQZR,ZSZT"))]
1807 "TARGET_64BIT"
1808 "@
1809 la\t%0,%a1
1810 lay\t%0,%a1"
1811 [(set_attr "op_type" "RX,RXY")
1812 (set_attr "type" "la")
1813 (set_attr "z10prop" "z10_fwd_A1,z10_fwd_A1")])
1814
1815 (define_peephole2
1816 [(parallel
1817 [(set (match_operand:DI 0 "register_operand" "")
1818 (match_operand:QI 1 "address_operand" ""))
1819 (clobber (reg:CC CC_REGNUM))])]
1820 "TARGET_64BIT
1821 && preferred_la_operand_p (operands[1], const0_rtx)"
1822 [(set (match_dup 0) (match_dup 1))]
1823 "")
1824
1825 (define_peephole2
1826 [(set (match_operand:DI 0 "register_operand" "")
1827 (match_operand:DI 1 "register_operand" ""))
1828 (parallel
1829 [(set (match_dup 0)
1830 (plus:DI (match_dup 0)
1831 (match_operand:DI 2 "nonmemory_operand" "")))
1832 (clobber (reg:CC CC_REGNUM))])]
1833 "TARGET_64BIT
1834 && !reg_overlap_mentioned_p (operands[0], operands[2])
1835 && preferred_la_operand_p (operands[1], operands[2])"
1836 [(set (match_dup 0) (plus:DI (match_dup 1) (match_dup 2)))]
1837 "")
1838
1839 ;
1840 ; movsi instruction pattern(s).
1841 ;
1842
1843 (define_expand "movsi"
1844 [(set (match_operand:SI 0 "general_operand" "")
1845 (match_operand:SI 1 "general_operand" ""))]
1846 ""
1847 {
1848 /* Handle symbolic constants. */
1849 if (!TARGET_64BIT
1850 && (SYMBOLIC_CONST (operands[1])
1851 || (GET_CODE (operands[1]) == PLUS
1852 && XEXP (operands[1], 0) == pic_offset_table_rtx
1853 && SYMBOLIC_CONST (XEXP(operands[1], 1)))))
1854 emit_symbolic_move (operands);
1855 })
1856
1857 (define_insn "*movsi_larl"
1858 [(set (match_operand:SI 0 "register_operand" "=d")
1859 (match_operand:SI 1 "larl_operand" "X"))]
1860 "!TARGET_64BIT && TARGET_CPU_ZARCH
1861 && !FP_REG_P (operands[0])"
1862 "larl\t%0,%1"
1863 [(set_attr "op_type" "RIL")
1864 (set_attr "type" "larl")
1865 (set_attr "z10prop" "z10_fwd_A1")])
1866
1867 (define_insn "*movsi_zarch"
1868 [(set (match_operand:SI 0 "nonimmediate_operand"
1869 "=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")
1870 (match_operand:SI 1 "general_operand"
1871 " 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"))]
1872 "TARGET_ZARCH"
1873 "@
1874 lhi\t%0,%h1
1875 llilh\t%0,%i1
1876 llill\t%0,%i1
1877 iilf\t%0,%o1
1878 lay\t%0,%a1
1879 lrl\t%0,%1
1880 lr\t%0,%1
1881 l\t%0,%1
1882 ly\t%0,%1
1883 st\t%1,%0
1884 sty\t%1,%0
1885 lder\t%0,%1
1886 ler\t%0,%1
1887 lde\t%0,%1
1888 le\t%0,%1
1889 ley\t%0,%1
1890 ste\t%1,%0
1891 stey\t%1,%0
1892 ear\t%0,%1
1893 sar\t%0,%1
1894 stam\t%1,%1,%S0
1895 strl\t%1,%0
1896 mvhi\t%0,%1
1897 lam\t%0,%0,%S1
1898 vleif\t%v0,%h1,0
1899 vlr\t%v0,%v1
1900 vlvgf\t%v0,%1,0
1901 vlgvf\t%0,%v1,0
1902 vlef\t%v0,%1,0
1903 vstef\t%v1,%0,0"
1904 [(set_attr "op_type" "RI,RI,RI,RIL,RXY,RIL,RR,RX,RXY,RX,RXY,
1905 RRE,RR,RXE,RX,RXY,RX,RXY,RRE,RRE,RS,RIL,SIL,RS,VRI,VRR,VRS,VRS,VRX,VRX")
1906 (set_attr "type" "*,
1907 *,
1908 *,
1909 *,
1910 la,
1911 larl,
1912 lr,
1913 load,
1914 load,
1915 store,
1916 store,
1917 floadsf,
1918 floadsf,
1919 floadsf,
1920 floadsf,
1921 floadsf,
1922 fstoresf,
1923 fstoresf,
1924 *,
1925 *,
1926 *,
1927 larl,
1928 *,
1929 *,*,*,*,*,*,*")
1930 (set_attr "cpu_facility" "*,*,*,extimm,longdisp,z10,*,*,longdisp,*,longdisp,
1931 vec,*,vec,*,longdisp,*,longdisp,*,*,*,z10,z10,*,vec,vec,vec,vec,vec,vec")
1932 (set_attr "z10prop" "z10_fwd_A1,
1933 z10_fwd_E1,
1934 z10_fwd_E1,
1935 z10_fwd_A1,
1936 z10_fwd_A1,
1937 z10_fwd_A3,
1938 z10_fr_E1,
1939 z10_fwd_A3,
1940 z10_fwd_A3,
1941 z10_rec,
1942 z10_rec,
1943 *,
1944 *,
1945 *,
1946 *,
1947 *,
1948 *,
1949 *,
1950 z10_super_E1,
1951 z10_super,
1952 *,
1953 z10_rec,
1954 z10_super,
1955 *,*,*,*,*,*,*")])
1956
1957 (define_insn "*movsi_esa"
1958 [(set (match_operand:SI 0 "nonimmediate_operand" "=d,d,d,R,!*f,!*f,!*f,!*f,!R,d,t,Q,t")
1959 (match_operand:SI 1 "general_operand" "K,d,R,d, *f, *f, R, R,*f,t,d,t,Q"))]
1960 "!TARGET_ZARCH"
1961 "@
1962 lhi\t%0,%h1
1963 lr\t%0,%1
1964 l\t%0,%1
1965 st\t%1,%0
1966 lder\t%0,%1
1967 ler\t%0,%1
1968 lde\t%0,%1
1969 le\t%0,%1
1970 ste\t%1,%0
1971 ear\t%0,%1
1972 sar\t%0,%1
1973 stam\t%1,%1,%S0
1974 lam\t%0,%0,%S1"
1975 [(set_attr "op_type" "RI,RR,RX,RX,RRE,RR,RXE,RX,RX,RRE,RRE,RS,RS")
1976 (set_attr "type" "*,lr,load,store,floadsf,floadsf,floadsf,floadsf,fstoresf,*,*,*,*")
1977 (set_attr "z10prop" "z10_fwd_A1,z10_fr_E1,z10_fwd_A3,z10_rec,*,*,*,*,*,z10_super_E1,
1978 z10_super,*,*")
1979 (set_attr "cpu_facility" "*,*,*,*,vec,*,vec,*,*,*,*,*,*")
1980 ])
1981
1982 (define_peephole2
1983 [(set (match_operand:SI 0 "register_operand" "")
1984 (mem:SI (match_operand 1 "address_operand" "")))]
1985 "!FP_REG_P (operands[0])
1986 && GET_CODE (operands[1]) == SYMBOL_REF
1987 && CONSTANT_POOL_ADDRESS_P (operands[1])
1988 && get_pool_mode (operands[1]) == SImode
1989 && legitimate_reload_constant_p (get_pool_constant (operands[1]))"
1990 [(set (match_dup 0) (match_dup 2))]
1991 "operands[2] = get_pool_constant (operands[1]);")
1992
1993 (define_insn "*la_31"
1994 [(set (match_operand:SI 0 "register_operand" "=d,d")
1995 (match_operand:QI 1 "address_operand" "ZQZR,ZSZT"))]
1996 "!TARGET_64BIT && legitimate_la_operand_p (operands[1])"
1997 "@
1998 la\t%0,%a1
1999 lay\t%0,%a1"
2000 [(set_attr "op_type" "RX,RXY")
2001 (set_attr "type" "la")
2002 (set_attr "z10prop" "z10_fwd_A1,z10_fwd_A1")])
2003
2004 (define_peephole2
2005 [(parallel
2006 [(set (match_operand:SI 0 "register_operand" "")
2007 (match_operand:QI 1 "address_operand" ""))
2008 (clobber (reg:CC CC_REGNUM))])]
2009 "!TARGET_64BIT
2010 && preferred_la_operand_p (operands[1], const0_rtx)"
2011 [(set (match_dup 0) (match_dup 1))]
2012 "")
2013
2014 (define_peephole2
2015 [(set (match_operand:SI 0 "register_operand" "")
2016 (match_operand:SI 1 "register_operand" ""))
2017 (parallel
2018 [(set (match_dup 0)
2019 (plus:SI (match_dup 0)
2020 (match_operand:SI 2 "nonmemory_operand" "")))
2021 (clobber (reg:CC CC_REGNUM))])]
2022 "!TARGET_64BIT
2023 && !reg_overlap_mentioned_p (operands[0], operands[2])
2024 && preferred_la_operand_p (operands[1], operands[2])"
2025 [(set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))]
2026 "")
2027
2028 (define_insn "*la_31_and"
2029 [(set (match_operand:SI 0 "register_operand" "=d,d")
2030 (and:SI (match_operand:QI 1 "address_operand" "ZQZR,ZSZT")
2031 (const_int 2147483647)))]
2032 "!TARGET_64BIT"
2033 "@
2034 la\t%0,%a1
2035 lay\t%0,%a1"
2036 [(set_attr "op_type" "RX,RXY")
2037 (set_attr "type" "la")
2038 (set_attr "z10prop" "z10_fwd_A1,z10_fwd_A1")])
2039
2040 (define_insn_and_split "*la_31_and_cc"
2041 [(set (match_operand:SI 0 "register_operand" "=d")
2042 (and:SI (match_operand:QI 1 "address_operand" "p")
2043 (const_int 2147483647)))
2044 (clobber (reg:CC CC_REGNUM))]
2045 "!TARGET_64BIT"
2046 "#"
2047 "&& reload_completed"
2048 [(set (match_dup 0)
2049 (and:SI (match_dup 1) (const_int 2147483647)))]
2050 ""
2051 [(set_attr "op_type" "RX")
2052 (set_attr "type" "la")])
2053
2054 (define_insn "force_la_31"
2055 [(set (match_operand:SI 0 "register_operand" "=d,d")
2056 (match_operand:QI 1 "address_operand" "ZQZR,ZSZT"))
2057 (use (const_int 0))]
2058 "!TARGET_64BIT"
2059 "@
2060 la\t%0,%a1
2061 lay\t%0,%a1"
2062 [(set_attr "op_type" "RX")
2063 (set_attr "type" "la")
2064 (set_attr "z10prop" "z10_fwd_A1,z10_fwd_A1")])
2065
2066 ;
2067 ; movhi instruction pattern(s).
2068 ;
2069
2070 (define_expand "movhi"
2071 [(set (match_operand:HI 0 "nonimmediate_operand" "")
2072 (match_operand:HI 1 "general_operand" ""))]
2073 ""
2074 {
2075 /* Make it explicit that loading a register from memory
2076 always sign-extends (at least) to SImode. */
2077 if (optimize && can_create_pseudo_p ()
2078 && register_operand (operands[0], VOIDmode)
2079 && GET_CODE (operands[1]) == MEM)
2080 {
2081 rtx tmp = gen_reg_rtx (SImode);
2082 rtx ext = gen_rtx_SIGN_EXTEND (SImode, operands[1]);
2083 emit_insn (gen_rtx_SET (tmp, ext));
2084 operands[1] = gen_lowpart (HImode, tmp);
2085 }
2086 })
2087
2088 (define_insn "*movhi"
2089 [(set (match_operand:HI 0 "nonimmediate_operand" "=d,d,d,d,d,R,T,b,Q,v,v,v,d, v,QR")
2090 (match_operand:HI 1 "general_operand" " d,n,R,T,b,d,d,d,K,K,v,d,v,QR, v"))]
2091 ""
2092 "@
2093 lr\t%0,%1
2094 lhi\t%0,%h1
2095 lh\t%0,%1
2096 lhy\t%0,%1
2097 lhrl\t%0,%1
2098 sth\t%1,%0
2099 sthy\t%1,%0
2100 sthrl\t%1,%0
2101 mvhhi\t%0,%1
2102 vleih\t%v0,%h1,0
2103 vlr\t%v0,%v1
2104 vlvgh\t%v0,%1,0
2105 vlgvh\t%0,%v1,0
2106 vleh\t%v0,%1,0
2107 vsteh\t%v1,%0,0"
2108 [(set_attr "op_type" "RR,RI,RX,RXY,RIL,RX,RXY,RIL,SIL,VRI,VRR,VRS,VRS,VRX,VRX")
2109 (set_attr "type" "lr,*,*,*,larl,store,store,store,*,*,*,*,*,*,*")
2110 (set_attr "cpu_facility" "*,*,*,*,z10,*,*,z10,z10,vec,vec,vec,vec,vec,vec")
2111 (set_attr "z10prop" "z10_fr_E1,
2112 z10_fwd_A1,
2113 z10_super_E1,
2114 z10_super_E1,
2115 z10_super_E1,
2116 z10_rec,
2117 z10_rec,
2118 z10_rec,
2119 z10_super,*,*,*,*,*,*")])
2120
2121 (define_peephole2
2122 [(set (match_operand:HI 0 "register_operand" "")
2123 (mem:HI (match_operand 1 "address_operand" "")))]
2124 "GET_CODE (operands[1]) == SYMBOL_REF
2125 && CONSTANT_POOL_ADDRESS_P (operands[1])
2126 && get_pool_mode (operands[1]) == HImode
2127 && GET_CODE (get_pool_constant (operands[1])) == CONST_INT"
2128 [(set (match_dup 0) (match_dup 2))]
2129 "operands[2] = get_pool_constant (operands[1]);")
2130
2131 ;
2132 ; movqi instruction pattern(s).
2133 ;
2134
2135 (define_expand "movqi"
2136 [(set (match_operand:QI 0 "nonimmediate_operand" "")
2137 (match_operand:QI 1 "general_operand" ""))]
2138 ""
2139 {
2140 /* On z/Architecture, zero-extending from memory to register
2141 is just as fast as a QImode load. */
2142 if (TARGET_ZARCH && optimize && can_create_pseudo_p ()
2143 && register_operand (operands[0], VOIDmode)
2144 && GET_CODE (operands[1]) == MEM)
2145 {
2146 rtx tmp = gen_reg_rtx (DImode);
2147 rtx ext = gen_rtx_ZERO_EXTEND (DImode, operands[1]);
2148 emit_insn (gen_rtx_SET (tmp, ext));
2149 operands[1] = gen_lowpart (QImode, tmp);
2150 }
2151 })
2152
2153 (define_insn "*movqi"
2154 [(set (match_operand:QI 0 "nonimmediate_operand" "=d,d,d,d,R,T,Q,S,?Q,v,v,v,d, v,QR")
2155 (match_operand:QI 1 "general_operand" " d,n,R,T,d,d,n,n,?Q,K,v,d,v,QR, v"))]
2156 ""
2157 "@
2158 lr\t%0,%1
2159 lhi\t%0,%b1
2160 ic\t%0,%1
2161 icy\t%0,%1
2162 stc\t%1,%0
2163 stcy\t%1,%0
2164 mvi\t%S0,%b1
2165 mviy\t%S0,%b1
2166 #
2167 vleib\t%v0,%b1,0
2168 vlr\t%v0,%v1
2169 vlvgb\t%v0,%1,0
2170 vlgvb\t%0,%v1,0
2171 vleb\t%v0,%1,0
2172 vsteb\t%v1,%0,0"
2173 [(set_attr "op_type" "RR,RI,RX,RXY,RX,RXY,SI,SIY,SS,VRI,VRR,VRS,VRS,VRX,VRX")
2174 (set_attr "type" "lr,*,*,*,store,store,store,store,*,*,*,*,*,*,*")
2175 (set_attr "cpu_facility" "*,*,*,*,*,*,*,*,*,vec,vec,vec,vec,vec,vec")
2176 (set_attr "z10prop" "z10_fr_E1,
2177 z10_fwd_A1,
2178 z10_super_E1,
2179 z10_super_E1,
2180 z10_rec,
2181 z10_rec,
2182 z10_super,
2183 z10_super,
2184 *,*,*,*,*,*,*")])
2185
2186 (define_peephole2
2187 [(set (match_operand:QI 0 "nonimmediate_operand" "")
2188 (mem:QI (match_operand 1 "address_operand" "")))]
2189 "GET_CODE (operands[1]) == SYMBOL_REF
2190 && CONSTANT_POOL_ADDRESS_P (operands[1])
2191 && get_pool_mode (operands[1]) == QImode
2192 && GET_CODE (get_pool_constant (operands[1])) == CONST_INT"
2193 [(set (match_dup 0) (match_dup 2))]
2194 "operands[2] = get_pool_constant (operands[1]);")
2195
2196 ;
2197 ; movstrictqi instruction pattern(s).
2198 ;
2199
2200 (define_insn "*movstrictqi"
2201 [(set (strict_low_part (match_operand:QI 0 "register_operand" "+d,d"))
2202 (match_operand:QI 1 "memory_operand" "R,T"))]
2203 ""
2204 "@
2205 ic\t%0,%1
2206 icy\t%0,%1"
2207 [(set_attr "op_type" "RX,RXY")
2208 (set_attr "z10prop" "z10_super_E1,z10_super_E1")])
2209
2210 ;
2211 ; movstricthi instruction pattern(s).
2212 ;
2213
2214 (define_insn "*movstricthi"
2215 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+d,d"))
2216 (match_operand:HI 1 "memory_operand" "Q,S"))
2217 (clobber (reg:CC CC_REGNUM))]
2218 ""
2219 "@
2220 icm\t%0,3,%S1
2221 icmy\t%0,3,%S1"
2222 [(set_attr "op_type" "RS,RSY")
2223 (set_attr "z10prop" "z10_super_E1,z10_super_E1")])
2224
2225 ;
2226 ; movstrictsi instruction pattern(s).
2227 ;
2228
2229 (define_insn "movstrictsi"
2230 [(set (strict_low_part (match_operand:SI 0 "register_operand" "+d,d,d,d"))
2231 (match_operand:SI 1 "general_operand" "d,R,T,t"))]
2232 "TARGET_ZARCH"
2233 "@
2234 lr\t%0,%1
2235 l\t%0,%1
2236 ly\t%0,%1
2237 ear\t%0,%1"
2238 [(set_attr "op_type" "RR,RX,RXY,RRE")
2239 (set_attr "type" "lr,load,load,*")
2240 (set_attr "z10prop" "z10_fr_E1,z10_fwd_A3,z10_fwd_A3,z10_super_E1")])
2241
2242 ;
2243 ; mov(tf|td) instruction pattern(s).
2244 ;
2245
2246 (define_expand "mov<mode>"
2247 [(set (match_operand:TD_TF 0 "nonimmediate_operand" "")
2248 (match_operand:TD_TF 1 "general_operand" ""))]
2249 ""
2250 "")
2251
2252 (define_insn "*mov<mode>_64"
2253 [(set (match_operand:TD_TF 0 "nonimmediate_operand" "=f,f,f,o, d,QS, d,o")
2254 (match_operand:TD_TF 1 "general_operand" " G,f,o,f,QS, d,dRT,d"))]
2255 "TARGET_ZARCH"
2256 "@
2257 lzxr\t%0
2258 lxr\t%0,%1
2259 #
2260 #
2261 lmg\t%0,%N0,%S1
2262 stmg\t%1,%N1,%S0
2263 #
2264 #"
2265 [(set_attr "op_type" "RRE,RRE,*,*,RSY,RSY,*,*")
2266 (set_attr "type" "fsimptf,fsimptf,*,*,lm,stm,*,*")
2267 (set_attr "cpu_facility" "z196,*,*,*,*,*,*,*")])
2268
2269 (define_insn "*mov<mode>_31"
2270 [(set (match_operand:TD_TF 0 "nonimmediate_operand" "=f,f,f,o")
2271 (match_operand:TD_TF 1 "general_operand" " G,f,o,f"))]
2272 "!TARGET_ZARCH"
2273 "@
2274 lzxr\t%0
2275 lxr\t%0,%1
2276 #
2277 #"
2278 [(set_attr "op_type" "RRE,RRE,*,*")
2279 (set_attr "type" "fsimptf,fsimptf,*,*")
2280 (set_attr "cpu_facility" "z196,*,*,*")])
2281
2282 ; TFmode in GPRs splitters
2283
2284 (define_split
2285 [(set (match_operand:TD_TF 0 "nonimmediate_operand" "")
2286 (match_operand:TD_TF 1 "general_operand" ""))]
2287 "TARGET_ZARCH && reload_completed
2288 && s390_split_ok_p (operands[0], operands[1], <MODE>mode, 0)"
2289 [(set (match_dup 2) (match_dup 4))
2290 (set (match_dup 3) (match_dup 5))]
2291 {
2292 operands[2] = operand_subword (operands[0], 0, 0, <MODE>mode);
2293 operands[3] = operand_subword (operands[0], 1, 0, <MODE>mode);
2294 operands[4] = operand_subword (operands[1], 0, 0, <MODE>mode);
2295 operands[5] = operand_subword (operands[1], 1, 0, <MODE>mode);
2296 })
2297
2298 (define_split
2299 [(set (match_operand:TD_TF 0 "nonimmediate_operand" "")
2300 (match_operand:TD_TF 1 "general_operand" ""))]
2301 "TARGET_ZARCH && reload_completed
2302 && s390_split_ok_p (operands[0], operands[1], <MODE>mode, 1)"
2303 [(set (match_dup 2) (match_dup 4))
2304 (set (match_dup 3) (match_dup 5))]
2305 {
2306 operands[2] = operand_subword (operands[0], 1, 0, <MODE>mode);
2307 operands[3] = operand_subword (operands[0], 0, 0, <MODE>mode);
2308 operands[4] = operand_subword (operands[1], 1, 0, <MODE>mode);
2309 operands[5] = operand_subword (operands[1], 0, 0, <MODE>mode);
2310 })
2311
2312 (define_split
2313 [(set (match_operand:TD_TF 0 "register_operand" "")
2314 (match_operand:TD_TF 1 "memory_operand" ""))]
2315 "TARGET_ZARCH && reload_completed
2316 && GENERAL_REG_P (operands[0])
2317 && !s_operand (operands[1], VOIDmode)"
2318 [(set (match_dup 0) (match_dup 1))]
2319 {
2320 rtx addr = operand_subword (operands[0], 1, 0, <MODE>mode);
2321 addr = gen_lowpart (Pmode, addr);
2322 s390_load_address (addr, XEXP (operands[1], 0));
2323 operands[1] = replace_equiv_address (operands[1], addr);
2324 })
2325
2326 ; TFmode in BFPs splitters
2327
2328 (define_split
2329 [(set (match_operand:TD_TF 0 "register_operand" "")
2330 (match_operand:TD_TF 1 "memory_operand" ""))]
2331 "reload_completed && offsettable_memref_p (operands[1])
2332 && FP_REG_P (operands[0])"
2333 [(set (match_dup 2) (match_dup 4))
2334 (set (match_dup 3) (match_dup 5))]
2335 {
2336 operands[2] = simplify_gen_subreg (<HALF_TMODE>mode, operands[0],
2337 <MODE>mode, 0);
2338 operands[3] = simplify_gen_subreg (<HALF_TMODE>mode, operands[0],
2339 <MODE>mode, 8);
2340 operands[4] = adjust_address_nv (operands[1], <HALF_TMODE>mode, 0);
2341 operands[5] = adjust_address_nv (operands[1], <HALF_TMODE>mode, 8);
2342 })
2343
2344 (define_split
2345 [(set (match_operand:TD_TF 0 "memory_operand" "")
2346 (match_operand:TD_TF 1 "register_operand" ""))]
2347 "reload_completed && offsettable_memref_p (operands[0])
2348 && FP_REG_P (operands[1])"
2349 [(set (match_dup 2) (match_dup 4))
2350 (set (match_dup 3) (match_dup 5))]
2351 {
2352 operands[2] = adjust_address_nv (operands[0], <HALF_TMODE>mode, 0);
2353 operands[3] = adjust_address_nv (operands[0], <HALF_TMODE>mode, 8);
2354 operands[4] = simplify_gen_subreg (<HALF_TMODE>mode, operands[1],
2355 <MODE>mode, 0);
2356 operands[5] = simplify_gen_subreg (<HALF_TMODE>mode, operands[1],
2357 <MODE>mode, 8);
2358 })
2359
2360 ;
2361 ; mov(df|dd) instruction pattern(s).
2362 ;
2363
2364 (define_expand "mov<mode>"
2365 [(set (match_operand:DD_DF 0 "nonimmediate_operand" "")
2366 (match_operand:DD_DF 1 "general_operand" ""))]
2367 ""
2368 "")
2369
2370 (define_insn "*mov<mode>_64dfp"
2371 [(set (match_operand:DD_DF 0 "nonimmediate_operand"
2372 "=f,f,f,d,f,f,R,T,d,d,d, d,b,RT,v,v,d,v,QR")
2373 (match_operand:DD_DF 1 "general_operand"
2374 " G,f,d,f,R,T,f,f,G,d,b,RT,d, d,v,d,v,QR,v"))]
2375 "TARGET_DFP"
2376 "@
2377 lzdr\t%0
2378 ldr\t%0,%1
2379 ldgr\t%0,%1
2380 lgdr\t%0,%1
2381 ld\t%0,%1
2382 ldy\t%0,%1
2383 std\t%1,%0
2384 stdy\t%1,%0
2385 lghi\t%0,0
2386 lgr\t%0,%1
2387 lgrl\t%0,%1
2388 lg\t%0,%1
2389 stgrl\t%1,%0
2390 stg\t%1,%0
2391 vlr\t%v0,%v1
2392 vlvgg\t%v0,%1,0
2393 vlgvg\t%0,%v1,0
2394 vleg\t%0,%1,0
2395 vsteg\t%1,%0,0"
2396 [(set_attr "op_type" "RRE,RR,RRE,RRE,RX,RXY,RX,RXY,RI,RRE,RIL,RXY,RIL,RXY,VRR,VRS,VRS,VRX,VRX")
2397 (set_attr "type" "fsimpdf,floaddf,floaddf,floaddf,floaddf,floaddf,
2398 fstoredf,fstoredf,*,lr,load,load,store,store,*,*,*,load,store")
2399 (set_attr "z10prop" "*,*,*,*,*,*,*,*,z10_fwd_A1,z10_fr_E1,z10_fwd_A3,z10_fwd_A3,z10_rec,z10_rec,*,*,*,*,*")
2400 (set_attr "cpu_facility" "z196,*,*,*,*,*,*,*,*,*,z10,*,z10,*,vec,vec,vec,vec,vec")])
2401
2402 (define_insn "*mov<mode>_64"
2403 [(set (match_operand:DD_DF 0 "nonimmediate_operand" "=f,f,f,f,R,T,d,d,d, d,b,RT,v,v,QR")
2404 (match_operand:DD_DF 1 "general_operand" " G,f,R,T,f,f,G,d,b,RT,d, d,v,QR,v"))]
2405 "TARGET_ZARCH"
2406 "@
2407 lzdr\t%0
2408 ldr\t%0,%1
2409 ld\t%0,%1
2410 ldy\t%0,%1
2411 std\t%1,%0
2412 stdy\t%1,%0
2413 lghi\t%0,0
2414 lgr\t%0,%1
2415 lgrl\t%0,%1
2416 lg\t%0,%1
2417 stgrl\t%1,%0
2418 stg\t%1,%0
2419 vlr\t%v0,%v1
2420 vleg\t%v0,%1,0
2421 vsteg\t%v1,%0,0"
2422 [(set_attr "op_type" "RRE,RR,RX,RXY,RX,RXY,RI,RRE,RIL,RXY,RIL,RXY,VRR,VRX,VRX")
2423 (set_attr "type" "fsimpdf,fload<mode>,fload<mode>,fload<mode>,
2424 fstore<mode>,fstore<mode>,*,lr,load,load,store,store,*,load,store")
2425 (set_attr "z10prop" "*,*,*,*,*,*,z10_fwd_A1,z10_fr_E1,z10_fwd_A3,z10_fwd_A3,z10_rec,z10_rec,*,*,*")
2426 (set_attr "cpu_facility" "z196,*,*,*,*,*,*,*,z10,*,z10,*,vec,vec,vec")])
2427
2428 (define_insn "*mov<mode>_31"
2429 [(set (match_operand:DD_DF 0 "nonimmediate_operand"
2430 "=f,f,f,f,R,T,d,d,Q,S, d,o")
2431 (match_operand:DD_DF 1 "general_operand"
2432 " G,f,R,T,f,f,Q,S,d,d,dPRT,d"))]
2433 "!TARGET_ZARCH"
2434 "@
2435 lzdr\t%0
2436 ldr\t%0,%1
2437 ld\t%0,%1
2438 ldy\t%0,%1
2439 std\t%1,%0
2440 stdy\t%1,%0
2441 lm\t%0,%N0,%S1
2442 lmy\t%0,%N0,%S1
2443 stm\t%1,%N1,%S0
2444 stmy\t%1,%N1,%S0
2445 #
2446 #"
2447 [(set_attr "op_type" "RRE,RR,RX,RXY,RX,RXY,RS,RSY,RS,RSY,*,*")
2448 (set_attr "type" "fsimpdf,fload<mode>,fload<mode>,fload<mode>,
2449 fstore<mode>,fstore<mode>,lm,lm,stm,stm,*,*")
2450 (set_attr "cpu_facility" "z196,*,*,*,*,*,*,*,*,*,*,*")])
2451
2452 (define_split
2453 [(set (match_operand:DD_DF 0 "nonimmediate_operand" "")
2454 (match_operand:DD_DF 1 "general_operand" ""))]
2455 "!TARGET_ZARCH && reload_completed
2456 && s390_split_ok_p (operands[0], operands[1], <MODE>mode, 0)"
2457 [(set (match_dup 2) (match_dup 4))
2458 (set (match_dup 3) (match_dup 5))]
2459 {
2460 operands[2] = operand_subword (operands[0], 0, 0, <MODE>mode);
2461 operands[3] = operand_subword (operands[0], 1, 0, <MODE>mode);
2462 operands[4] = operand_subword (operands[1], 0, 0, <MODE>mode);
2463 operands[5] = operand_subword (operands[1], 1, 0, <MODE>mode);
2464 })
2465
2466 (define_split
2467 [(set (match_operand:DD_DF 0 "nonimmediate_operand" "")
2468 (match_operand:DD_DF 1 "general_operand" ""))]
2469 "!TARGET_ZARCH && reload_completed
2470 && s390_split_ok_p (operands[0], operands[1], <MODE>mode, 1)"
2471 [(set (match_dup 2) (match_dup 4))
2472 (set (match_dup 3) (match_dup 5))]
2473 {
2474 operands[2] = operand_subword (operands[0], 1, 0, <MODE>mode);
2475 operands[3] = operand_subword (operands[0], 0, 0, <MODE>mode);
2476 operands[4] = operand_subword (operands[1], 1, 0, <MODE>mode);
2477 operands[5] = operand_subword (operands[1], 0, 0, <MODE>mode);
2478 })
2479
2480 (define_split
2481 [(set (match_operand:DD_DF 0 "register_operand" "")
2482 (match_operand:DD_DF 1 "memory_operand" ""))]
2483 "!TARGET_ZARCH && reload_completed
2484 && !FP_REG_P (operands[0])
2485 && !s_operand (operands[1], VOIDmode)"
2486 [(set (match_dup 0) (match_dup 1))]
2487 {
2488 rtx addr = operand_subword (operands[0], 1, 0, <MODE>mode);
2489 s390_load_address (addr, XEXP (operands[1], 0));
2490 operands[1] = replace_equiv_address (operands[1], addr);
2491 })
2492
2493 ;
2494 ; mov(sf|sd) instruction pattern(s).
2495 ;
2496
2497 (define_insn "mov<mode>"
2498 [(set (match_operand:SD_SF 0 "nonimmediate_operand"
2499 "=f,f,f,f,f,f,R,T,d,d,d,d,d,b,R,T,v,v,v,d,v,QR")
2500 (match_operand:SD_SF 1 "general_operand"
2501 " G,f,f,R,R,T,f,f,G,d,b,R,T,d,d,d,v,G,d,v,QR,v"))]
2502 ""
2503 "@
2504 lzer\t%0
2505 lder\t%0,%1
2506 ler\t%0,%1
2507 lde\t%0,%1
2508 le\t%0,%1
2509 ley\t%0,%1
2510 ste\t%1,%0
2511 stey\t%1,%0
2512 lhi\t%0,0
2513 lr\t%0,%1
2514 lrl\t%0,%1
2515 l\t%0,%1
2516 ly\t%0,%1
2517 strl\t%1,%0
2518 st\t%1,%0
2519 sty\t%1,%0
2520 vlr\t%v0,%v1
2521 vleif\t%v0,0
2522 vlvgf\t%v0,%1,0
2523 vlgvf\t%0,%v1,0
2524 vleg\t%0,%1,0
2525 vsteg\t%1,%0,0"
2526 [(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")
2527 (set_attr "type" "fsimpsf,fsimpsf,fload<mode>,fload<mode>,fload<mode>,fload<mode>,
2528 fstore<mode>,fstore<mode>,*,lr,load,load,load,store,store,store,*,*,*,*,load,store")
2529 (set_attr "z10prop" "*,*,*,*,*,*,*,*,z10_fwd_A1,z10_fr_E1,z10_fr_E1,z10_fwd_A3,z10_fwd_A3,z10_rec,z10_rec,z10_rec,*,*,*,*,*,*")
2530 (set_attr "cpu_facility" "z196,vec,*,vec,*,*,*,*,*,*,z10,*,*,z10,*,*,vec,vec,vec,vec,vec,vec")])
2531
2532 ;
2533 ; movcc instruction pattern
2534 ;
2535
2536 (define_insn "movcc"
2537 [(set (match_operand:CC 0 "nonimmediate_operand" "=d,c,d,d,d,R,T")
2538 (match_operand:CC 1 "nonimmediate_operand" " d,d,c,R,T,d,d"))]
2539 ""
2540 "@
2541 lr\t%0,%1
2542 tmh\t%1,12288
2543 ipm\t%0
2544 l\t%0,%1
2545 ly\t%0,%1
2546 st\t%1,%0
2547 sty\t%1,%0"
2548 [(set_attr "op_type" "RR,RI,RRE,RX,RXY,RX,RXY")
2549 (set_attr "type" "lr,*,*,load,load,store,store")
2550 (set_attr "z10prop" "z10_fr_E1,z10_super,*,z10_fwd_A3,z10_fwd_A3,z10_rec,z10_rec")
2551 (set_attr "z196prop" "*,*,z196_ends,*,*,*,*")])
2552
2553 ;
2554 ; Block move (MVC) patterns.
2555 ;
2556
2557 (define_insn "*mvc"
2558 [(set (match_operand:BLK 0 "memory_operand" "=Q")
2559 (match_operand:BLK 1 "memory_operand" "Q"))
2560 (use (match_operand 2 "const_int_operand" "n"))]
2561 "INTVAL (operands[2]) >= 1 && INTVAL (operands[2]) <= 256"
2562 "mvc\t%O0(%2,%R0),%S1"
2563 [(set_attr "op_type" "SS")])
2564
2565 ; This splitter converts a QI to QI mode copy into a BLK mode copy in
2566 ; order to have it implemented with mvc.
2567
2568 (define_split
2569 [(set (match_operand:QI 0 "memory_operand" "")
2570 (match_operand:QI 1 "memory_operand" ""))]
2571 "reload_completed"
2572 [(parallel
2573 [(set (match_dup 0) (match_dup 1))
2574 (use (const_int 1))])]
2575 {
2576 operands[0] = adjust_address (operands[0], BLKmode, 0);
2577 operands[1] = adjust_address (operands[1], BLKmode, 0);
2578 })
2579
2580
2581 (define_peephole2
2582 [(parallel
2583 [(set (match_operand:BLK 0 "memory_operand" "")
2584 (match_operand:BLK 1 "memory_operand" ""))
2585 (use (match_operand 2 "const_int_operand" ""))])
2586 (parallel
2587 [(set (match_operand:BLK 3 "memory_operand" "")
2588 (match_operand:BLK 4 "memory_operand" ""))
2589 (use (match_operand 5 "const_int_operand" ""))])]
2590 "s390_offset_p (operands[0], operands[3], operands[2])
2591 && s390_offset_p (operands[1], operands[4], operands[2])
2592 && !s390_overlap_p (operands[0], operands[1],
2593 INTVAL (operands[2]) + INTVAL (operands[5]))
2594 && INTVAL (operands[2]) + INTVAL (operands[5]) <= 256"
2595 [(parallel
2596 [(set (match_dup 6) (match_dup 7))
2597 (use (match_dup 8))])]
2598 "operands[6] = gen_rtx_MEM (BLKmode, XEXP (operands[0], 0));
2599 operands[7] = gen_rtx_MEM (BLKmode, XEXP (operands[1], 0));
2600 operands[8] = GEN_INT (INTVAL (operands[2]) + INTVAL (operands[5]));")
2601
2602
2603 ;
2604 ; load_multiple pattern(s).
2605 ;
2606 ; ??? Due to reload problems with replacing registers inside match_parallel
2607 ; we currently support load_multiple/store_multiple only after reload.
2608 ;
2609
2610 (define_expand "load_multiple"
2611 [(match_par_dup 3 [(set (match_operand 0 "" "")
2612 (match_operand 1 "" ""))
2613 (use (match_operand 2 "" ""))])]
2614 "reload_completed"
2615 {
2616 machine_mode mode;
2617 int regno;
2618 int count;
2619 rtx from;
2620 int i, off;
2621
2622 /* Support only loading a constant number of fixed-point registers from
2623 memory and only bother with this if more than two */
2624 if (GET_CODE (operands[2]) != CONST_INT
2625 || INTVAL (operands[2]) < 2
2626 || INTVAL (operands[2]) > 16
2627 || GET_CODE (operands[1]) != MEM
2628 || GET_CODE (operands[0]) != REG
2629 || REGNO (operands[0]) >= 16)
2630 FAIL;
2631
2632 count = INTVAL (operands[2]);
2633 regno = REGNO (operands[0]);
2634 mode = GET_MODE (operands[0]);
2635 if (mode != SImode && (!TARGET_ZARCH || mode != DImode))
2636 FAIL;
2637
2638 operands[3] = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (count));
2639 if (!can_create_pseudo_p ())
2640 {
2641 if (GET_CODE (XEXP (operands[1], 0)) == REG)
2642 {
2643 from = XEXP (operands[1], 0);
2644 off = 0;
2645 }
2646 else if (GET_CODE (XEXP (operands[1], 0)) == PLUS
2647 && GET_CODE (XEXP (XEXP (operands[1], 0), 0)) == REG
2648 && GET_CODE (XEXP (XEXP (operands[1], 0), 1)) == CONST_INT)
2649 {
2650 from = XEXP (XEXP (operands[1], 0), 0);
2651 off = INTVAL (XEXP (XEXP (operands[1], 0), 1));
2652 }
2653 else
2654 FAIL;
2655 }
2656 else
2657 {
2658 from = force_reg (Pmode, XEXP (operands[1], 0));
2659 off = 0;
2660 }
2661
2662 for (i = 0; i < count; i++)
2663 XVECEXP (operands[3], 0, i)
2664 = gen_rtx_SET (gen_rtx_REG (mode, regno + i),
2665 change_address (operands[1], mode,
2666 plus_constant (Pmode, from,
2667 off + i * GET_MODE_SIZE (mode))));
2668 })
2669
2670 (define_insn "*load_multiple_di"
2671 [(match_parallel 0 "load_multiple_operation"
2672 [(set (match_operand:DI 1 "register_operand" "=r")
2673 (match_operand:DI 2 "s_operand" "QS"))])]
2674 "reload_completed && TARGET_ZARCH"
2675 {
2676 int words = XVECLEN (operands[0], 0);
2677 operands[0] = gen_rtx_REG (DImode, REGNO (operands[1]) + words - 1);
2678 return "lmg\t%1,%0,%S2";
2679 }
2680 [(set_attr "op_type" "RSY")
2681 (set_attr "type" "lm")])
2682
2683 (define_insn "*load_multiple_si"
2684 [(match_parallel 0 "load_multiple_operation"
2685 [(set (match_operand:SI 1 "register_operand" "=r,r")
2686 (match_operand:SI 2 "s_operand" "Q,S"))])]
2687 "reload_completed"
2688 {
2689 int words = XVECLEN (operands[0], 0);
2690 operands[0] = gen_rtx_REG (SImode, REGNO (operands[1]) + words - 1);
2691 return which_alternative == 0 ? "lm\t%1,%0,%S2" : "lmy\t%1,%0,%S2";
2692 }
2693 [(set_attr "op_type" "RS,RSY")
2694 (set_attr "type" "lm")])
2695
2696 ;
2697 ; store multiple pattern(s).
2698 ;
2699
2700 (define_expand "store_multiple"
2701 [(match_par_dup 3 [(set (match_operand 0 "" "")
2702 (match_operand 1 "" ""))
2703 (use (match_operand 2 "" ""))])]
2704 "reload_completed"
2705 {
2706 machine_mode mode;
2707 int regno;
2708 int count;
2709 rtx to;
2710 int i, off;
2711
2712 /* Support only storing a constant number of fixed-point registers to
2713 memory and only bother with this if more than two. */
2714 if (GET_CODE (operands[2]) != CONST_INT
2715 || INTVAL (operands[2]) < 2
2716 || INTVAL (operands[2]) > 16
2717 || GET_CODE (operands[0]) != MEM
2718 || GET_CODE (operands[1]) != REG
2719 || REGNO (operands[1]) >= 16)
2720 FAIL;
2721
2722 count = INTVAL (operands[2]);
2723 regno = REGNO (operands[1]);
2724 mode = GET_MODE (operands[1]);
2725 if (mode != SImode && (!TARGET_ZARCH || mode != DImode))
2726 FAIL;
2727
2728 operands[3] = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (count));
2729
2730 if (!can_create_pseudo_p ())
2731 {
2732 if (GET_CODE (XEXP (operands[0], 0)) == REG)
2733 {
2734 to = XEXP (operands[0], 0);
2735 off = 0;
2736 }
2737 else if (GET_CODE (XEXP (operands[0], 0)) == PLUS
2738 && GET_CODE (XEXP (XEXP (operands[0], 0), 0)) == REG
2739 && GET_CODE (XEXP (XEXP (operands[0], 0), 1)) == CONST_INT)
2740 {
2741 to = XEXP (XEXP (operands[0], 0), 0);
2742 off = INTVAL (XEXP (XEXP (operands[0], 0), 1));
2743 }
2744 else
2745 FAIL;
2746 }
2747 else
2748 {
2749 to = force_reg (Pmode, XEXP (operands[0], 0));
2750 off = 0;
2751 }
2752
2753 for (i = 0; i < count; i++)
2754 XVECEXP (operands[3], 0, i)
2755 = gen_rtx_SET (change_address (operands[0], mode,
2756 plus_constant (Pmode, to,
2757 off + i * GET_MODE_SIZE (mode))),
2758 gen_rtx_REG (mode, regno + i));
2759 })
2760
2761 (define_insn "*store_multiple_di"
2762 [(match_parallel 0 "store_multiple_operation"
2763 [(set (match_operand:DI 1 "s_operand" "=QS")
2764 (match_operand:DI 2 "register_operand" "r"))])]
2765 "reload_completed && TARGET_ZARCH"
2766 {
2767 int words = XVECLEN (operands[0], 0);
2768 operands[0] = gen_rtx_REG (DImode, REGNO (operands[2]) + words - 1);
2769 return "stmg\t%2,%0,%S1";
2770 }
2771 [(set_attr "op_type" "RSY")
2772 (set_attr "type" "stm")])
2773
2774
2775 (define_insn "*store_multiple_si"
2776 [(match_parallel 0 "store_multiple_operation"
2777 [(set (match_operand:SI 1 "s_operand" "=Q,S")
2778 (match_operand:SI 2 "register_operand" "r,r"))])]
2779 "reload_completed"
2780 {
2781 int words = XVECLEN (operands[0], 0);
2782 operands[0] = gen_rtx_REG (SImode, REGNO (operands[2]) + words - 1);
2783 return which_alternative == 0 ? "stm\t%2,%0,%S1" : "stmy\t%2,%0,%S1";
2784 }
2785 [(set_attr "op_type" "RS,RSY")
2786 (set_attr "type" "stm")])
2787
2788 ;;
2789 ;; String instructions.
2790 ;;
2791
2792 (define_insn "*execute_rl"
2793 [(match_parallel 0 "execute_operation"
2794 [(unspec [(match_operand 1 "register_operand" "a")
2795 (match_operand 2 "" "")
2796 (match_operand:SI 3 "larl_operand" "X")] UNSPEC_EXECUTE)])]
2797 "TARGET_Z10 && GET_MODE_CLASS (GET_MODE (operands[1])) == MODE_INT
2798 && GET_MODE_SIZE (GET_MODE (operands[1])) <= UNITS_PER_WORD"
2799 "exrl\t%1,%3"
2800 [(set_attr "op_type" "RIL")
2801 (set_attr "type" "cs")])
2802
2803 (define_insn "*execute"
2804 [(match_parallel 0 "execute_operation"
2805 [(unspec [(match_operand 1 "register_operand" "a")
2806 (match_operand:BLK 2 "memory_operand" "R")
2807 (match_operand 3 "" "")] UNSPEC_EXECUTE)])]
2808 "GET_MODE_CLASS (GET_MODE (operands[1])) == MODE_INT
2809 && GET_MODE_SIZE (GET_MODE (operands[1])) <= UNITS_PER_WORD"
2810 "ex\t%1,%2"
2811 [(set_attr "op_type" "RX")
2812 (set_attr "type" "cs")])
2813
2814
2815 ;
2816 ; strlenM instruction pattern(s).
2817 ;
2818
2819 (define_expand "strlen<mode>"
2820 [(match_operand:P 0 "register_operand" "") ; result
2821 (match_operand:BLK 1 "memory_operand" "") ; input string
2822 (match_operand:SI 2 "immediate_operand" "") ; search character
2823 (match_operand:SI 3 "immediate_operand" "")] ; known alignment
2824 ""
2825 {
2826 if (!TARGET_VX || operands[2] != const0_rtx)
2827 emit_insn (gen_strlen_srst<mode> (operands[0], operands[1],
2828 operands[2], operands[3]));
2829 else
2830 s390_expand_vec_strlen (operands[0], operands[1], operands[3]);
2831
2832 DONE;
2833 })
2834
2835 (define_expand "strlen_srst<mode>"
2836 [(set (reg:SI 0) (match_operand:SI 2 "immediate_operand" ""))
2837 (parallel
2838 [(set (match_dup 4)
2839 (unspec:P [(const_int 0)
2840 (match_operand:BLK 1 "memory_operand" "")
2841 (reg:SI 0)
2842 (match_operand 3 "immediate_operand" "")] UNSPEC_SRST))
2843 (clobber (scratch:P))
2844 (clobber (reg:CC CC_REGNUM))])
2845 (parallel
2846 [(set (match_operand:P 0 "register_operand" "")
2847 (minus:P (match_dup 4) (match_dup 5)))
2848 (clobber (reg:CC CC_REGNUM))])]
2849 ""
2850 {
2851 operands[4] = gen_reg_rtx (Pmode);
2852 operands[5] = gen_reg_rtx (Pmode);
2853 emit_move_insn (operands[5], force_operand (XEXP (operands[1], 0), NULL_RTX));
2854 operands[1] = replace_equiv_address (operands[1], operands[5]);
2855 })
2856
2857 (define_insn "*strlen<mode>"
2858 [(set (match_operand:P 0 "register_operand" "=a")
2859 (unspec:P [(match_operand:P 2 "general_operand" "0")
2860 (mem:BLK (match_operand:P 3 "register_operand" "1"))
2861 (reg:SI 0)
2862 (match_operand 4 "immediate_operand" "")] UNSPEC_SRST))
2863 (clobber (match_scratch:P 1 "=a"))
2864 (clobber (reg:CC CC_REGNUM))]
2865 ""
2866 "srst\t%0,%1\;jo\t.-4"
2867 [(set_attr "length" "8")
2868 (set_attr "type" "vs")])
2869
2870 ;
2871 ; cmpstrM instruction pattern(s).
2872 ;
2873
2874 (define_expand "cmpstrsi"
2875 [(set (reg:SI 0) (const_int 0))
2876 (parallel
2877 [(clobber (match_operand 3 "" ""))
2878 (clobber (match_dup 4))
2879 (set (reg:CCU CC_REGNUM)
2880 (compare:CCU (match_operand:BLK 1 "memory_operand" "")
2881 (match_operand:BLK 2 "memory_operand" "")))
2882 (use (reg:SI 0))])
2883 (parallel
2884 [(set (match_operand:SI 0 "register_operand" "=d")
2885 (unspec:SI [(reg:CCU CC_REGNUM)] UNSPEC_STRCMPCC_TO_INT))
2886 (clobber (reg:CC CC_REGNUM))])]
2887 ""
2888 {
2889 /* As the result of CMPINT is inverted compared to what we need,
2890 we have to swap the operands. */
2891 rtx op1 = operands[2];
2892 rtx op2 = operands[1];
2893 rtx addr1 = gen_reg_rtx (Pmode);
2894 rtx addr2 = gen_reg_rtx (Pmode);
2895
2896 emit_move_insn (addr1, force_operand (XEXP (op1, 0), NULL_RTX));
2897 emit_move_insn (addr2, force_operand (XEXP (op2, 0), NULL_RTX));
2898 operands[1] = replace_equiv_address_nv (op1, addr1);
2899 operands[2] = replace_equiv_address_nv (op2, addr2);
2900 operands[3] = addr1;
2901 operands[4] = addr2;
2902 })
2903
2904 (define_insn "*cmpstr<mode>"
2905 [(clobber (match_operand:P 0 "register_operand" "=d"))
2906 (clobber (match_operand:P 1 "register_operand" "=d"))
2907 (set (reg:CCU CC_REGNUM)
2908 (compare:CCU (mem:BLK (match_operand:P 2 "register_operand" "0"))
2909 (mem:BLK (match_operand:P 3 "register_operand" "1"))))
2910 (use (reg:SI 0))]
2911 ""
2912 "clst\t%0,%1\;jo\t.-4"
2913 [(set_attr "length" "8")
2914 (set_attr "type" "vs")])
2915
2916 ;
2917 ; movstr instruction pattern.
2918 ;
2919
2920 (define_expand "movstr"
2921 [(match_operand 0 "register_operand" "")
2922 (match_operand 1 "memory_operand" "")
2923 (match_operand 2 "memory_operand" "")]
2924 ""
2925 {
2926 if (TARGET_64BIT)
2927 emit_insn (gen_movstrdi (operands[0], operands[1], operands[2]));
2928 else
2929 emit_insn (gen_movstrsi (operands[0], operands[1], operands[2]));
2930 DONE;
2931 })
2932
2933 (define_expand "movstr<P:mode>"
2934 [(set (reg:SI 0) (const_int 0))
2935 (parallel
2936 [(clobber (match_dup 3))
2937 (set (match_operand:BLK 1 "memory_operand" "")
2938 (match_operand:BLK 2 "memory_operand" ""))
2939 (set (match_operand:P 0 "register_operand" "")
2940 (unspec:P [(match_dup 1)
2941 (match_dup 2)
2942 (reg:SI 0)] UNSPEC_MVST))
2943 (clobber (reg:CC CC_REGNUM))])]
2944 ""
2945 {
2946 rtx addr1 = gen_reg_rtx (Pmode);
2947 rtx addr2 = gen_reg_rtx (Pmode);
2948
2949 emit_move_insn (addr1, force_operand (XEXP (operands[1], 0), NULL_RTX));
2950 emit_move_insn (addr2, force_operand (XEXP (operands[2], 0), NULL_RTX));
2951 operands[1] = replace_equiv_address_nv (operands[1], addr1);
2952 operands[2] = replace_equiv_address_nv (operands[2], addr2);
2953 operands[3] = addr2;
2954 })
2955
2956 (define_insn "*movstr"
2957 [(clobber (match_operand:P 2 "register_operand" "=d"))
2958 (set (mem:BLK (match_operand:P 1 "register_operand" "0"))
2959 (mem:BLK (match_operand:P 3 "register_operand" "2")))
2960 (set (match_operand:P 0 "register_operand" "=d")
2961 (unspec:P [(mem:BLK (match_dup 1))
2962 (mem:BLK (match_dup 3))
2963 (reg:SI 0)] UNSPEC_MVST))
2964 (clobber (reg:CC CC_REGNUM))]
2965 ""
2966 "mvst\t%1,%2\;jo\t.-4"
2967 [(set_attr "length" "8")
2968 (set_attr "type" "vs")])
2969
2970
2971 ;
2972 ; movmemM instruction pattern(s).
2973 ;
2974
2975 (define_expand "movmem<mode>"
2976 [(set (match_operand:BLK 0 "memory_operand" "") ; destination
2977 (match_operand:BLK 1 "memory_operand" "")) ; source
2978 (use (match_operand:GPR 2 "general_operand" "")) ; count
2979 (match_operand 3 "" "")]
2980 ""
2981 {
2982 if (s390_expand_movmem (operands[0], operands[1], operands[2]))
2983 DONE;
2984 else
2985 FAIL;
2986 })
2987
2988 ; Move a block that is up to 256 bytes in length.
2989 ; The block length is taken as (operands[2] % 256) + 1.
2990
2991 (define_expand "movmem_short"
2992 [(parallel
2993 [(set (match_operand:BLK 0 "memory_operand" "")
2994 (match_operand:BLK 1 "memory_operand" ""))
2995 (use (match_operand 2 "nonmemory_operand" ""))
2996 (use (const:BLK (unspec:BLK [(const_int 0)] UNSPEC_INSN)))
2997 (clobber (match_dup 3))])]
2998 ""
2999 "operands[3] = gen_rtx_SCRATCH (Pmode);")
3000
3001 (define_insn "*movmem_short"
3002 [(set (match_operand:BLK 0 "memory_operand" "=Q,Q,Q,Q")
3003 (match_operand:BLK 1 "memory_operand" "Q,Q,Q,Q"))
3004 (use (match_operand 2 "nonmemory_operand" "n,a,a,a"))
3005 (use (match_operand 3 "immediate_operand" "X,R,X,X"))
3006 (clobber (match_scratch:P 4 "=X,X,X,&a"))]
3007 "(GET_MODE (operands[2]) == Pmode || GET_MODE (operands[2]) == VOIDmode)"
3008 "#"
3009 [(set_attr "type" "cs")
3010 (set_attr "cpu_facility" "*,*,z10,cpu_zarch")])
3011
3012 (define_split
3013 [(set (match_operand:BLK 0 "memory_operand" "")
3014 (match_operand:BLK 1 "memory_operand" ""))
3015 (use (match_operand 2 "const_int_operand" ""))
3016 (use (match_operand 3 "immediate_operand" ""))
3017 (clobber (scratch))]
3018 "reload_completed"
3019 [(parallel
3020 [(set (match_dup 0) (match_dup 1))
3021 (use (match_dup 2))])]
3022 "operands[2] = GEN_INT ((INTVAL (operands[2]) & 0xff) + 1);")
3023
3024 (define_split
3025 [(set (match_operand:BLK 0 "memory_operand" "")
3026 (match_operand:BLK 1 "memory_operand" ""))
3027 (use (match_operand 2 "register_operand" ""))
3028 (use (match_operand 3 "memory_operand" ""))
3029 (clobber (scratch))]
3030 "reload_completed"
3031 [(parallel
3032 [(unspec [(match_dup 2) (match_dup 3)
3033 (const_int 0)] UNSPEC_EXECUTE)
3034 (set (match_dup 0) (match_dup 1))
3035 (use (const_int 1))])]
3036 "")
3037
3038 (define_split
3039 [(set (match_operand:BLK 0 "memory_operand" "")
3040 (match_operand:BLK 1 "memory_operand" ""))
3041 (use (match_operand 2 "register_operand" ""))
3042 (use (const:BLK (unspec:BLK [(const_int 0)] UNSPEC_INSN)))
3043 (clobber (scratch))]
3044 "TARGET_Z10 && reload_completed"
3045 [(parallel
3046 [(unspec [(match_dup 2) (const_int 0)
3047 (label_ref (match_dup 3))] UNSPEC_EXECUTE)
3048 (set (match_dup 0) (match_dup 1))
3049 (use (const_int 1))])]
3050 "operands[3] = gen_label_rtx ();")
3051
3052 (define_split
3053 [(set (match_operand:BLK 0 "memory_operand" "")
3054 (match_operand:BLK 1 "memory_operand" ""))
3055 (use (match_operand 2 "register_operand" ""))
3056 (use (const:BLK (unspec:BLK [(const_int 0)] UNSPEC_INSN)))
3057 (clobber (match_operand 3 "register_operand" ""))]
3058 "reload_completed && TARGET_CPU_ZARCH"
3059 [(set (match_dup 3) (label_ref (match_dup 4)))
3060 (parallel
3061 [(unspec [(match_dup 2) (mem:BLK (match_dup 3))
3062 (label_ref (match_dup 4))] UNSPEC_EXECUTE)
3063 (set (match_dup 0) (match_dup 1))
3064 (use (const_int 1))])]
3065 "operands[4] = gen_label_rtx ();")
3066
3067 ; Move a block of arbitrary length.
3068
3069 (define_expand "movmem_long"
3070 [(parallel
3071 [(clobber (match_dup 2))
3072 (clobber (match_dup 3))
3073 (set (match_operand:BLK 0 "memory_operand" "")
3074 (match_operand:BLK 1 "memory_operand" ""))
3075 (use (match_operand 2 "general_operand" ""))
3076 (use (match_dup 3))
3077 (clobber (reg:CC CC_REGNUM))])]
3078 ""
3079 {
3080 machine_mode sreg_mode = TARGET_ZARCH ? DImode : SImode;
3081 machine_mode dreg_mode = TARGET_ZARCH ? TImode : DImode;
3082 rtx reg0 = gen_reg_rtx (dreg_mode);
3083 rtx reg1 = gen_reg_rtx (dreg_mode);
3084 rtx addr0 = gen_lowpart (Pmode, gen_highpart (sreg_mode, reg0));
3085 rtx addr1 = gen_lowpart (Pmode, gen_highpart (sreg_mode, reg1));
3086 rtx len0 = gen_lowpart (Pmode, reg0);
3087 rtx len1 = gen_lowpart (Pmode, reg1);
3088
3089 emit_clobber (reg0);
3090 emit_move_insn (addr0, force_operand (XEXP (operands[0], 0), NULL_RTX));
3091 emit_move_insn (len0, operands[2]);
3092
3093 emit_clobber (reg1);
3094 emit_move_insn (addr1, force_operand (XEXP (operands[1], 0), NULL_RTX));
3095 emit_move_insn (len1, operands[2]);
3096
3097 operands[0] = replace_equiv_address_nv (operands[0], addr0);
3098 operands[1] = replace_equiv_address_nv (operands[1], addr1);
3099 operands[2] = reg0;
3100 operands[3] = reg1;
3101 })
3102
3103 (define_insn "*movmem_long"
3104 [(clobber (match_operand:<DBL> 0 "register_operand" "=d"))
3105 (clobber (match_operand:<DBL> 1 "register_operand" "=d"))
3106 (set (mem:BLK (subreg:P (match_operand:<DBL> 2 "register_operand" "0") 0))
3107 (mem:BLK (subreg:P (match_operand:<DBL> 3 "register_operand" "1") 0)))
3108 (use (match_dup 2))
3109 (use (match_dup 3))
3110 (clobber (reg:CC CC_REGNUM))]
3111 "TARGET_64BIT || !TARGET_ZARCH"
3112 "mvcle\t%0,%1,0\;jo\t.-4"
3113 [(set_attr "length" "8")
3114 (set_attr "type" "vs")])
3115
3116 (define_insn "*movmem_long_31z"
3117 [(clobber (match_operand:TI 0 "register_operand" "=d"))
3118 (clobber (match_operand:TI 1 "register_operand" "=d"))
3119 (set (mem:BLK (subreg:SI (match_operand:TI 2 "register_operand" "0") 4))
3120 (mem:BLK (subreg:SI (match_operand:TI 3 "register_operand" "1") 4)))
3121 (use (match_dup 2))
3122 (use (match_dup 3))
3123 (clobber (reg:CC CC_REGNUM))]
3124 "!TARGET_64BIT && TARGET_ZARCH"
3125 "mvcle\t%0,%1,0\;jo\t.-4"
3126 [(set_attr "length" "8")
3127 (set_attr "type" "vs")])
3128
3129
3130 ;
3131 ; Test data class.
3132 ;
3133
3134 (define_expand "signbit<mode>2"
3135 [(set (reg:CCZ CC_REGNUM)
3136 (unspec:CCZ [(match_operand:FP_ALL 1 "register_operand" "f")
3137 (match_dup 2)]
3138 UNSPEC_TDC_INSN))
3139 (set (match_operand:SI 0 "register_operand" "=d")
3140 (unspec:SI [(reg:CCZ CC_REGNUM)] UNSPEC_CC_TO_INT))]
3141 "TARGET_HARD_FLOAT"
3142 {
3143 operands[2] = GEN_INT (S390_TDC_SIGNBIT_SET);
3144 })
3145
3146 (define_expand "isinf<mode>2"
3147 [(set (reg:CCZ CC_REGNUM)
3148 (unspec:CCZ [(match_operand:FP_ALL 1 "register_operand" "f")
3149 (match_dup 2)]
3150 UNSPEC_TDC_INSN))
3151 (set (match_operand:SI 0 "register_operand" "=d")
3152 (unspec:SI [(reg:CCZ CC_REGNUM)] UNSPEC_CC_TO_INT))]
3153 "TARGET_HARD_FLOAT"
3154 {
3155 operands[2] = GEN_INT (S390_TDC_INFINITY);
3156 })
3157
3158 ; This extracts CC into a GPR properly shifted. The actual IPM
3159 ; instruction will be issued by reload. The constraint of operand 1
3160 ; forces reload to use a GPR. So reload will issue a movcc insn for
3161 ; copying CC into a GPR first.
3162 (define_insn_and_split "*cc_to_int"
3163 [(set (match_operand:SI 0 "nonimmediate_operand" "=d")
3164 (unspec:SI [(match_operand 1 "register_operand" "0")]
3165 UNSPEC_CC_TO_INT))]
3166 "operands != NULL"
3167 "#"
3168 "reload_completed"
3169 [(set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 28)))])
3170
3171 ; This insn is used to generate all variants of the Test Data Class
3172 ; instruction, namely tcxb, tcdb, and tceb. The insn's first operand
3173 ; is the register to be tested and the second one is the bit mask
3174 ; specifying the required test(s).
3175 ;
3176 ; tcxb, tcdb, tceb, tdcxt, tdcdt, tdcet
3177 (define_insn "*TDC_insn_<mode>"
3178 [(set (reg:CCZ CC_REGNUM)
3179 (unspec:CCZ [(match_operand:FP_ALL 0 "register_operand" "f")
3180 (match_operand:SI 1 "const_int_operand")] UNSPEC_TDC_INSN))]
3181 "TARGET_HARD_FLOAT"
3182 "t<_d>c<xde><bt>\t%0,%1"
3183 [(set_attr "op_type" "RXE")
3184 (set_attr "type" "fsimp<mode>")])
3185
3186
3187
3188 ;
3189 ; setmemM instruction pattern(s).
3190 ;
3191
3192 (define_expand "setmem<mode>"
3193 [(set (match_operand:BLK 0 "memory_operand" "")
3194 (match_operand:QI 2 "general_operand" ""))
3195 (use (match_operand:GPR 1 "general_operand" ""))
3196 (match_operand 3 "" "")]
3197 ""
3198 "s390_expand_setmem (operands[0], operands[1], operands[2]); DONE;")
3199
3200 ; Clear a block that is up to 256 bytes in length.
3201 ; The block length is taken as (operands[1] % 256) + 1.
3202
3203 (define_expand "clrmem_short"
3204 [(parallel
3205 [(set (match_operand:BLK 0 "memory_operand" "")
3206 (const_int 0))
3207 (use (match_operand 1 "nonmemory_operand" ""))
3208 (use (const:BLK (unspec:BLK [(const_int 0)] UNSPEC_INSN)))
3209 (clobber (match_dup 2))
3210 (clobber (reg:CC CC_REGNUM))])]
3211 ""
3212 "operands[2] = gen_rtx_SCRATCH (Pmode);")
3213
3214 (define_insn "*clrmem_short"
3215 [(set (match_operand:BLK 0 "memory_operand" "=Q,Q,Q,Q")
3216 (const_int 0))
3217 (use (match_operand 1 "nonmemory_operand" "n,a,a,a"))
3218 (use (match_operand 2 "immediate_operand" "X,R,X,X"))
3219 (clobber (match_scratch:P 3 "=X,X,X,&a"))
3220 (clobber (reg:CC CC_REGNUM))]
3221 "(GET_MODE (operands[1]) == Pmode || GET_MODE (operands[1]) == VOIDmode)"
3222 "#"
3223 [(set_attr "type" "cs")
3224 (set_attr "cpu_facility" "*,*,z10,cpu_zarch")])
3225
3226 (define_split
3227 [(set (match_operand:BLK 0 "memory_operand" "")
3228 (const_int 0))
3229 (use (match_operand 1 "const_int_operand" ""))
3230 (use (match_operand 2 "immediate_operand" ""))
3231 (clobber (scratch))
3232 (clobber (reg:CC CC_REGNUM))]
3233 "reload_completed"
3234 [(parallel
3235 [(set (match_dup 0) (const_int 0))
3236 (use (match_dup 1))
3237 (clobber (reg:CC CC_REGNUM))])]
3238 "operands[1] = GEN_INT ((INTVAL (operands[1]) & 0xff) + 1);")
3239
3240 (define_split
3241 [(set (match_operand:BLK 0 "memory_operand" "")
3242 (const_int 0))
3243 (use (match_operand 1 "register_operand" ""))
3244 (use (match_operand 2 "memory_operand" ""))
3245 (clobber (scratch))
3246 (clobber (reg:CC CC_REGNUM))]
3247 "reload_completed"
3248 [(parallel
3249 [(unspec [(match_dup 1) (match_dup 2)
3250 (const_int 0)] UNSPEC_EXECUTE)
3251 (set (match_dup 0) (const_int 0))
3252 (use (const_int 1))
3253 (clobber (reg:CC CC_REGNUM))])]
3254 "")
3255
3256 (define_split
3257 [(set (match_operand:BLK 0 "memory_operand" "")
3258 (const_int 0))
3259 (use (match_operand 1 "register_operand" ""))
3260 (use (const:BLK (unspec:BLK [(const_int 0)] UNSPEC_INSN)))
3261 (clobber (scratch))
3262 (clobber (reg:CC CC_REGNUM))]
3263 "TARGET_Z10 && reload_completed"
3264 [(parallel
3265 [(unspec [(match_dup 1) (const_int 0)
3266 (label_ref (match_dup 3))] UNSPEC_EXECUTE)
3267 (set (match_dup 0) (const_int 0))
3268 (use (const_int 1))
3269 (clobber (reg:CC CC_REGNUM))])]
3270 "operands[3] = gen_label_rtx ();")
3271
3272 (define_split
3273 [(set (match_operand:BLK 0 "memory_operand" "")
3274 (const_int 0))
3275 (use (match_operand 1 "register_operand" ""))
3276 (use (const:BLK (unspec:BLK [(const_int 0)] UNSPEC_INSN)))
3277 (clobber (match_operand 2 "register_operand" ""))
3278 (clobber (reg:CC CC_REGNUM))]
3279 "reload_completed && TARGET_CPU_ZARCH"
3280 [(set (match_dup 2) (label_ref (match_dup 3)))
3281 (parallel
3282 [(unspec [(match_dup 1) (mem:BLK (match_dup 2))
3283 (label_ref (match_dup 3))] UNSPEC_EXECUTE)
3284 (set (match_dup 0) (const_int 0))
3285 (use (const_int 1))
3286 (clobber (reg:CC CC_REGNUM))])]
3287 "operands[3] = gen_label_rtx ();")
3288
3289 ; Initialize a block of arbitrary length with (operands[2] % 256).
3290
3291 (define_expand "setmem_long_<P:mode>"
3292 [(parallel
3293 [(clobber (match_dup 1))
3294 (set (match_operand:BLK 0 "memory_operand" "")
3295 (unspec:BLK [(match_operand:P 2 "shift_count_or_setmem_operand" "")
3296 (match_dup 4)] UNSPEC_REPLICATE_BYTE))
3297 (use (match_dup 3))
3298 (clobber (reg:CC CC_REGNUM))])]
3299 ""
3300 {
3301 machine_mode sreg_mode = TARGET_ZARCH ? DImode : SImode;
3302 machine_mode dreg_mode = TARGET_ZARCH ? TImode : DImode;
3303 rtx reg0 = gen_reg_rtx (dreg_mode);
3304 rtx reg1 = gen_reg_rtx (dreg_mode);
3305 rtx addr0 = gen_lowpart (Pmode, gen_highpart (sreg_mode, reg0));
3306 rtx len0 = gen_lowpart (Pmode, reg0);
3307
3308 emit_clobber (reg0);
3309 emit_move_insn (addr0, force_operand (XEXP (operands[0], 0), NULL_RTX));
3310 emit_move_insn (len0, operands[1]);
3311
3312 emit_move_insn (reg1, const0_rtx);
3313
3314 operands[0] = replace_equiv_address_nv (operands[0], addr0);
3315 operands[1] = reg0;
3316 operands[3] = reg1;
3317 operands[4] = gen_lowpart (Pmode, operands[1]);
3318 })
3319
3320 ; Patterns for 31 bit + Esa and 64 bit + Zarch.
3321
3322 (define_insn "*setmem_long"
3323 [(clobber (match_operand:<DBL> 0 "register_operand" "=d"))
3324 (set (mem:BLK (subreg:P (match_operand:<DBL> 3 "register_operand" "0") 0))
3325 (unspec:BLK [(match_operand:P 2 "shift_count_or_setmem_operand" "Y")
3326 (subreg:P (match_dup 3) <modesize>)]
3327 UNSPEC_REPLICATE_BYTE))
3328 (use (match_operand:<DBL> 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 (define_insn "*setmem_long_and"
3336 [(clobber (match_operand:<DBL> 0 "register_operand" "=d"))
3337 (set (mem:BLK (subreg:P (match_operand:<DBL> 3 "register_operand" "0") 0))
3338 (unspec:BLK [(and:P
3339 (match_operand:P 2 "shift_count_or_setmem_operand" "Y")
3340 (match_operand:P 4 "const_int_operand" "n"))
3341 (subreg:P (match_dup 3) <modesize>)]
3342 UNSPEC_REPLICATE_BYTE))
3343 (use (match_operand:<DBL> 1 "register_operand" "d"))
3344 (clobber (reg:CC CC_REGNUM))]
3345 "(TARGET_64BIT || !TARGET_ZARCH) &&
3346 (INTVAL (operands[4]) & 255) == 255"
3347 "mvcle\t%0,%1,%Y2\;jo\t.-4"
3348 [(set_attr "length" "8")
3349 (set_attr "type" "vs")])
3350
3351 ; Variants for 31 bit + Zarch, necessary because of the odd in-register offsets
3352 ; of the SImode subregs.
3353
3354 (define_insn "*setmem_long_31z"
3355 [(clobber (match_operand:TI 0 "register_operand" "=d"))
3356 (set (mem:BLK (subreg:SI (match_operand:TI 3 "register_operand" "0") 4))
3357 (unspec:BLK [(match_operand:SI 2 "shift_count_or_setmem_operand" "Y")
3358 (subreg:SI (match_dup 3) 12)] UNSPEC_REPLICATE_BYTE))
3359 (use (match_operand:TI 1 "register_operand" "d"))
3360 (clobber (reg:CC CC_REGNUM))]
3361 "!TARGET_64BIT && TARGET_ZARCH"
3362 "mvcle\t%0,%1,%Y2\;jo\t.-4"
3363 [(set_attr "length" "8")
3364 (set_attr "type" "vs")])
3365
3366 (define_insn "*setmem_long_and_31z"
3367 [(clobber (match_operand:TI 0 "register_operand" "=d"))
3368 (set (mem:BLK (subreg:SI (match_operand:TI 3 "register_operand" "0") 4))
3369 (unspec:BLK [(and:SI
3370 (match_operand:SI 2 "shift_count_or_setmem_operand" "Y")
3371 (match_operand:SI 4 "const_int_operand" "n"))
3372 (subreg:SI (match_dup 3) 12)] UNSPEC_REPLICATE_BYTE))
3373 (use (match_operand:TI 1 "register_operand" "d"))
3374 (clobber (reg:CC CC_REGNUM))]
3375 "(!TARGET_64BIT && TARGET_ZARCH) &&
3376 (INTVAL (operands[4]) & 255) == 255"
3377 "mvcle\t%0,%1,%Y2\;jo\t.-4"
3378 [(set_attr "length" "8")
3379 (set_attr "type" "vs")])
3380
3381 ;
3382 ; cmpmemM instruction pattern(s).
3383 ;
3384
3385 (define_expand "cmpmemsi"
3386 [(set (match_operand:SI 0 "register_operand" "")
3387 (compare:SI (match_operand:BLK 1 "memory_operand" "")
3388 (match_operand:BLK 2 "memory_operand" "") ) )
3389 (use (match_operand:SI 3 "general_operand" ""))
3390 (use (match_operand:SI 4 "" ""))]
3391 ""
3392 {
3393 if (s390_expand_cmpmem (operands[0], operands[1],
3394 operands[2], operands[3]))
3395 DONE;
3396 else
3397 FAIL;
3398 })
3399
3400 ; Compare a block that is up to 256 bytes in length.
3401 ; The block length is taken as (operands[2] % 256) + 1.
3402
3403 (define_expand "cmpmem_short"
3404 [(parallel
3405 [(set (reg:CCU CC_REGNUM)
3406 (compare:CCU (match_operand:BLK 0 "memory_operand" "")
3407 (match_operand:BLK 1 "memory_operand" "")))
3408 (use (match_operand 2 "nonmemory_operand" ""))
3409 (use (const:BLK (unspec:BLK [(const_int 0)] UNSPEC_INSN)))
3410 (clobber (match_dup 3))])]
3411 ""
3412 "operands[3] = gen_rtx_SCRATCH (Pmode);")
3413
3414 (define_insn "*cmpmem_short"
3415 [(set (reg:CCU CC_REGNUM)
3416 (compare:CCU (match_operand:BLK 0 "memory_operand" "Q,Q,Q,Q")
3417 (match_operand:BLK 1 "memory_operand" "Q,Q,Q,Q")))
3418 (use (match_operand 2 "nonmemory_operand" "n,a,a,a"))
3419 (use (match_operand 3 "immediate_operand" "X,R,X,X"))
3420 (clobber (match_scratch:P 4 "=X,X,X,&a"))]
3421 "(GET_MODE (operands[2]) == Pmode || GET_MODE (operands[2]) == VOIDmode)"
3422 "#"
3423 [(set_attr "type" "cs")
3424 (set_attr "cpu_facility" "*,*,z10,cpu_zarch")])
3425
3426 (define_split
3427 [(set (reg:CCU CC_REGNUM)
3428 (compare:CCU (match_operand:BLK 0 "memory_operand" "")
3429 (match_operand:BLK 1 "memory_operand" "")))
3430 (use (match_operand 2 "const_int_operand" ""))
3431 (use (match_operand 3 "immediate_operand" ""))
3432 (clobber (scratch))]
3433 "reload_completed"
3434 [(parallel
3435 [(set (reg:CCU CC_REGNUM) (compare:CCU (match_dup 0) (match_dup 1)))
3436 (use (match_dup 2))])]
3437 "operands[2] = GEN_INT ((INTVAL (operands[2]) & 0xff) + 1);")
3438
3439 (define_split
3440 [(set (reg:CCU CC_REGNUM)
3441 (compare:CCU (match_operand:BLK 0 "memory_operand" "")
3442 (match_operand:BLK 1 "memory_operand" "")))
3443 (use (match_operand 2 "register_operand" ""))
3444 (use (match_operand 3 "memory_operand" ""))
3445 (clobber (scratch))]
3446 "reload_completed"
3447 [(parallel
3448 [(unspec [(match_dup 2) (match_dup 3)
3449 (const_int 0)] UNSPEC_EXECUTE)
3450 (set (reg:CCU CC_REGNUM) (compare:CCU (match_dup 0) (match_dup 1)))
3451 (use (const_int 1))])]
3452 "")
3453
3454 (define_split
3455 [(set (reg:CCU CC_REGNUM)
3456 (compare:CCU (match_operand:BLK 0 "memory_operand" "")
3457 (match_operand:BLK 1 "memory_operand" "")))
3458 (use (match_operand 2 "register_operand" ""))
3459 (use (const:BLK (unspec:BLK [(const_int 0)] UNSPEC_INSN)))
3460 (clobber (scratch))]
3461 "TARGET_Z10 && reload_completed"
3462 [(parallel
3463 [(unspec [(match_dup 2) (const_int 0)
3464 (label_ref (match_dup 4))] UNSPEC_EXECUTE)
3465 (set (reg:CCU CC_REGNUM) (compare:CCU (match_dup 0) (match_dup 1)))
3466 (use (const_int 1))])]
3467 "operands[4] = gen_label_rtx ();")
3468
3469 (define_split
3470 [(set (reg:CCU CC_REGNUM)
3471 (compare:CCU (match_operand:BLK 0 "memory_operand" "")
3472 (match_operand:BLK 1 "memory_operand" "")))
3473 (use (match_operand 2 "register_operand" ""))
3474 (use (const:BLK (unspec:BLK [(const_int 0)] UNSPEC_INSN)))
3475 (clobber (match_operand 3 "register_operand" ""))]
3476 "reload_completed && TARGET_CPU_ZARCH"
3477 [(set (match_dup 3) (label_ref (match_dup 4)))
3478 (parallel
3479 [(unspec [(match_dup 2) (mem:BLK (match_dup 3))
3480 (label_ref (match_dup 4))] UNSPEC_EXECUTE)
3481 (set (reg:CCU CC_REGNUM) (compare:CCU (match_dup 0) (match_dup 1)))
3482 (use (const_int 1))])]
3483 "operands[4] = gen_label_rtx ();")
3484
3485 ; Compare a block of arbitrary length.
3486
3487 (define_expand "cmpmem_long"
3488 [(parallel
3489 [(clobber (match_dup 2))
3490 (clobber (match_dup 3))
3491 (set (reg:CCU CC_REGNUM)
3492 (compare:CCU (match_operand:BLK 0 "memory_operand" "")
3493 (match_operand:BLK 1 "memory_operand" "")))
3494 (use (match_operand 2 "general_operand" ""))
3495 (use (match_dup 3))])]
3496 ""
3497 {
3498 machine_mode sreg_mode = TARGET_ZARCH ? DImode : SImode;
3499 machine_mode dreg_mode = TARGET_ZARCH ? TImode : DImode;
3500 rtx reg0 = gen_reg_rtx (dreg_mode);
3501 rtx reg1 = gen_reg_rtx (dreg_mode);
3502 rtx addr0 = gen_lowpart (Pmode, gen_highpart (sreg_mode, reg0));
3503 rtx addr1 = gen_lowpart (Pmode, gen_highpart (sreg_mode, reg1));
3504 rtx len0 = gen_lowpart (Pmode, reg0);
3505 rtx len1 = gen_lowpart (Pmode, reg1);
3506
3507 emit_clobber (reg0);
3508 emit_move_insn (addr0, force_operand (XEXP (operands[0], 0), NULL_RTX));
3509 emit_move_insn (len0, operands[2]);
3510
3511 emit_clobber (reg1);
3512 emit_move_insn (addr1, force_operand (XEXP (operands[1], 0), NULL_RTX));
3513 emit_move_insn (len1, operands[2]);
3514
3515 operands[0] = replace_equiv_address_nv (operands[0], addr0);
3516 operands[1] = replace_equiv_address_nv (operands[1], addr1);
3517 operands[2] = reg0;
3518 operands[3] = reg1;
3519 })
3520
3521 (define_insn "*cmpmem_long"
3522 [(clobber (match_operand:<DBL> 0 "register_operand" "=d"))
3523 (clobber (match_operand:<DBL> 1 "register_operand" "=d"))
3524 (set (reg:CCU CC_REGNUM)
3525 (compare:CCU (mem:BLK (subreg:P (match_operand:<DBL> 2 "register_operand" "0") 0))
3526 (mem:BLK (subreg:P (match_operand:<DBL> 3 "register_operand" "1") 0))))
3527 (use (match_dup 2))
3528 (use (match_dup 3))]
3529 "TARGET_64BIT || !TARGET_ZARCH"
3530 "clcle\t%0,%1,0\;jo\t.-4"
3531 [(set_attr "length" "8")
3532 (set_attr "type" "vs")])
3533
3534 (define_insn "*cmpmem_long_31z"
3535 [(clobber (match_operand:TI 0 "register_operand" "=d"))
3536 (clobber (match_operand:TI 1 "register_operand" "=d"))
3537 (set (reg:CCU CC_REGNUM)
3538 (compare:CCU (mem:BLK (subreg:SI (match_operand:TI 2 "register_operand" "0") 4))
3539 (mem:BLK (subreg:SI (match_operand:TI 3 "register_operand" "1") 4))))
3540 (use (match_dup 2))
3541 (use (match_dup 3))]
3542 "!TARGET_64BIT && TARGET_ZARCH"
3543 "clcle\t%0,%1,0\;jo\t.-4"
3544 [(set_attr "op_type" "NN")
3545 (set_attr "type" "vs")
3546 (set_attr "length" "8")])
3547
3548 ; Convert CCUmode condition code to integer.
3549 ; Result is zero if EQ, positive if LTU, negative if GTU.
3550
3551 (define_insn_and_split "cmpint"
3552 [(set (match_operand:SI 0 "register_operand" "=d")
3553 (unspec:SI [(match_operand:CCU 1 "register_operand" "0")]
3554 UNSPEC_STRCMPCC_TO_INT))
3555 (clobber (reg:CC CC_REGNUM))]
3556 ""
3557 "#"
3558 "reload_completed"
3559 [(set (match_dup 0) (ashift:SI (match_dup 0) (const_int 2)))
3560 (parallel
3561 [(set (match_dup 0) (ashiftrt:SI (match_dup 0) (const_int 30)))
3562 (clobber (reg:CC CC_REGNUM))])])
3563
3564 (define_insn_and_split "*cmpint_cc"
3565 [(set (reg CC_REGNUM)
3566 (compare (unspec:SI [(match_operand:CCU 1 "register_operand" "0")]
3567 UNSPEC_STRCMPCC_TO_INT)
3568 (const_int 0)))
3569 (set (match_operand:SI 0 "register_operand" "=d")
3570 (unspec:SI [(match_dup 1)] UNSPEC_STRCMPCC_TO_INT))]
3571 "s390_match_ccmode (insn, CCSmode)"
3572 "#"
3573 "&& reload_completed"
3574 [(set (match_dup 0) (ashift:SI (match_dup 0) (const_int 2)))
3575 (parallel
3576 [(set (match_dup 2) (match_dup 3))
3577 (set (match_dup 0) (ashiftrt:SI (match_dup 0) (const_int 30)))])]
3578 {
3579 rtx result = gen_rtx_ASHIFTRT (SImode, operands[0], GEN_INT (30));
3580 operands[2] = SET_DEST (XVECEXP (PATTERN (curr_insn), 0, 0));
3581 operands[3] = gen_rtx_COMPARE (GET_MODE (operands[2]), result, const0_rtx);
3582 })
3583
3584 (define_insn_and_split "*cmpint_sign"
3585 [(set (match_operand:DI 0 "register_operand" "=d")
3586 (sign_extend:DI (unspec:SI [(match_operand:CCU 1 "register_operand" "0")]
3587 UNSPEC_STRCMPCC_TO_INT)))
3588 (clobber (reg:CC CC_REGNUM))]
3589 "TARGET_ZARCH"
3590 "#"
3591 "&& reload_completed"
3592 [(set (match_dup 0) (ashift:DI (match_dup 0) (const_int 34)))
3593 (parallel
3594 [(set (match_dup 0) (ashiftrt:DI (match_dup 0) (const_int 62)))
3595 (clobber (reg:CC CC_REGNUM))])])
3596
3597 (define_insn_and_split "*cmpint_sign_cc"
3598 [(set (reg CC_REGNUM)
3599 (compare (ashiftrt:DI (ashift:DI (subreg:DI
3600 (unspec:SI [(match_operand:CCU 1 "register_operand" "0")]
3601 UNSPEC_STRCMPCC_TO_INT) 0)
3602 (const_int 32)) (const_int 32))
3603 (const_int 0)))
3604 (set (match_operand:DI 0 "register_operand" "=d")
3605 (sign_extend:DI (unspec:SI [(match_dup 1)] UNSPEC_STRCMPCC_TO_INT)))]
3606 "s390_match_ccmode (insn, CCSmode) && TARGET_ZARCH"
3607 "#"
3608 "&& reload_completed"
3609 [(set (match_dup 0) (ashift:DI (match_dup 0) (const_int 34)))
3610 (parallel
3611 [(set (match_dup 2) (match_dup 3))
3612 (set (match_dup 0) (ashiftrt:DI (match_dup 0) (const_int 62)))])]
3613 {
3614 rtx result = gen_rtx_ASHIFTRT (DImode, operands[0], GEN_INT (62));
3615 operands[2] = SET_DEST (XVECEXP (PATTERN (curr_insn), 0, 0));
3616 operands[3] = gen_rtx_COMPARE (GET_MODE (operands[2]), result, const0_rtx);
3617 })
3618
3619
3620 ;;
3621 ;;- Conversion instructions.
3622 ;;
3623
3624 (define_insn "*sethighpartsi"
3625 [(set (match_operand:SI 0 "register_operand" "=d,d")
3626 (unspec:SI [(match_operand:BLK 1 "s_operand" "Q,S")
3627 (match_operand 2 "const_int_operand" "n,n")] UNSPEC_ICM))
3628 (clobber (reg:CC CC_REGNUM))]
3629 ""
3630 "@
3631 icm\t%0,%2,%S1
3632 icmy\t%0,%2,%S1"
3633 [(set_attr "op_type" "RS,RSY")
3634 (set_attr "z10prop" "z10_super_E1,z10_super_E1")])
3635
3636 (define_insn "*sethighpartdi_64"
3637 [(set (match_operand:DI 0 "register_operand" "=d")
3638 (unspec:DI [(match_operand:BLK 1 "s_operand" "QS")
3639 (match_operand 2 "const_int_operand" "n")] UNSPEC_ICM))
3640 (clobber (reg:CC CC_REGNUM))]
3641 "TARGET_ZARCH"
3642 "icmh\t%0,%2,%S1"
3643 [(set_attr "op_type" "RSY")
3644 (set_attr "z10prop" "z10_super")])
3645
3646 (define_insn "*sethighpartdi_31"
3647 [(set (match_operand:DI 0 "register_operand" "=d,d")
3648 (unspec:DI [(match_operand:BLK 1 "s_operand" "Q,S")
3649 (match_operand 2 "const_int_operand" "n,n")] UNSPEC_ICM))
3650 (clobber (reg:CC CC_REGNUM))]
3651 "!TARGET_ZARCH"
3652 "@
3653 icm\t%0,%2,%S1
3654 icmy\t%0,%2,%S1"
3655 [(set_attr "op_type" "RS,RSY")
3656 (set_attr "z10prop" "z10_super_E1,z10_super_E1")])
3657
3658 ;
3659 ; extv instruction patterns
3660 ;
3661
3662 ; FIXME: This expander needs to be converted from DI to GPR as well
3663 ; after resolving some issues with it.
3664
3665 (define_expand "extzv"
3666 [(parallel
3667 [(set (match_operand:DI 0 "register_operand" "=d")
3668 (zero_extract:DI
3669 (match_operand:DI 1 "register_operand" "d")
3670 (match_operand 2 "const_int_operand" "") ; size
3671 (match_operand 3 "const_int_operand" ""))) ; start
3672 (clobber (reg:CC CC_REGNUM))])]
3673 "TARGET_Z10"
3674 {
3675 /* Starting with zEC12 there is risbgn not clobbering CC. */
3676 if (TARGET_ZEC12)
3677 {
3678 emit_move_insn (operands[0],
3679 gen_rtx_ZERO_EXTRACT (DImode,
3680 operands[1],
3681 operands[2],
3682 operands[3]));
3683 DONE;
3684 }
3685 })
3686
3687 (define_insn "*extzv<mode>_zEC12"
3688 [(set (match_operand:GPR 0 "register_operand" "=d")
3689 (zero_extract:GPR
3690 (match_operand:GPR 1 "register_operand" "d")
3691 (match_operand 2 "const_int_operand" "") ; size
3692 (match_operand 3 "const_int_operand" "")))] ; start]
3693 "TARGET_ZEC12"
3694 "risbgn\t%0,%1,64-%2,128+63,<bitsize>+%3+%2" ; dst, src, start, end, shift
3695 [(set_attr "op_type" "RIE")])
3696
3697 (define_insn "*extzv<mode>_z10"
3698 [(set (match_operand:GPR 0 "register_operand" "=d")
3699 (zero_extract:GPR
3700 (match_operand:GPR 1 "register_operand" "d")
3701 (match_operand 2 "const_int_operand" "") ; size
3702 (match_operand 3 "const_int_operand" ""))) ; start
3703 (clobber (reg:CC CC_REGNUM))]
3704 "TARGET_Z10"
3705 "risbg\t%0,%1,64-%2,128+63,<bitsize>+%3+%2" ; dst, src, start, end, shift
3706 [(set_attr "op_type" "RIE")
3707 (set_attr "z10prop" "z10_super_E1")])
3708
3709 (define_insn_and_split "*pre_z10_extzv<mode>"
3710 [(set (match_operand:GPR 0 "register_operand" "=d")
3711 (zero_extract:GPR (match_operand:QI 1 "s_operand" "QS")
3712 (match_operand 2 "nonzero_shift_count_operand" "")
3713 (const_int 0)))
3714 (clobber (reg:CC CC_REGNUM))]
3715 "!TARGET_Z10"
3716 "#"
3717 "&& reload_completed"
3718 [(parallel
3719 [(set (match_dup 0) (unspec:GPR [(match_dup 1) (match_dup 3)] UNSPEC_ICM))
3720 (clobber (reg:CC CC_REGNUM))])
3721 (set (match_dup 0) (lshiftrt:GPR (match_dup 0) (match_dup 2)))]
3722 {
3723 int bitsize = INTVAL (operands[2]);
3724 int size = (bitsize - 1) / BITS_PER_UNIT + 1; /* round up */
3725 int mask = ((1ul << size) - 1) << (GET_MODE_SIZE (SImode) - size);
3726
3727 operands[1] = adjust_address (operands[1], BLKmode, 0);
3728 set_mem_size (operands[1], size);
3729 operands[2] = GEN_INT (<GPR:bitsize> - bitsize);
3730 operands[3] = GEN_INT (mask);
3731 })
3732
3733 (define_insn_and_split "*pre_z10_extv<mode>"
3734 [(set (match_operand:GPR 0 "register_operand" "=d")
3735 (sign_extract:GPR (match_operand:QI 1 "s_operand" "QS")
3736 (match_operand 2 "nonzero_shift_count_operand" "")
3737 (const_int 0)))
3738 (clobber (reg:CC CC_REGNUM))]
3739 ""
3740 "#"
3741 "&& reload_completed"
3742 [(parallel
3743 [(set (match_dup 0) (unspec:GPR [(match_dup 1) (match_dup 3)] UNSPEC_ICM))
3744 (clobber (reg:CC CC_REGNUM))])
3745 (parallel
3746 [(set (match_dup 0) (ashiftrt:GPR (match_dup 0) (match_dup 2)))
3747 (clobber (reg:CC CC_REGNUM))])]
3748 {
3749 int bitsize = INTVAL (operands[2]);
3750 int size = (bitsize - 1) / BITS_PER_UNIT + 1; /* round up */
3751 int mask = ((1ul << size) - 1) << (GET_MODE_SIZE (SImode) - size);
3752
3753 operands[1] = adjust_address (operands[1], BLKmode, 0);
3754 set_mem_size (operands[1], size);
3755 operands[2] = GEN_INT (<GPR:bitsize> - bitsize);
3756 operands[3] = GEN_INT (mask);
3757 })
3758
3759 ;
3760 ; insv instruction patterns
3761 ;
3762
3763 (define_expand "insv"
3764 [(set (zero_extract (match_operand 0 "nonimmediate_operand" "")
3765 (match_operand 1 "const_int_operand" "")
3766 (match_operand 2 "const_int_operand" ""))
3767 (match_operand 3 "general_operand" ""))]
3768 ""
3769 {
3770 if (s390_expand_insv (operands[0], operands[1], operands[2], operands[3]))
3771 DONE;
3772 FAIL;
3773 })
3774
3775
3776 ; The normal RTL expansion will never generate a zero_extract where
3777 ; the location operand isn't word mode. However, we do this in the
3778 ; back-end when generating atomic operations. See s390_two_part_insv.
3779 (define_insn "*insv<mode>_zEC12"
3780 [(set (zero_extract:GPR (match_operand:GPR 0 "nonimmediate_operand" "+d")
3781 (match_operand 1 "const_int_operand" "I") ; size
3782 (match_operand 2 "const_int_operand" "I")) ; pos
3783 (match_operand:GPR 3 "nonimmediate_operand" "d"))]
3784 "TARGET_ZEC12
3785 && (INTVAL (operands[1]) + INTVAL (operands[2])) <= <bitsize>"
3786 "risbgn\t%0,%3,64-<bitsize>+%2,64-<bitsize>+%2+%1-1,<bitsize>-%2-%1"
3787 [(set_attr "op_type" "RIE")])
3788
3789 (define_insn "*insv<mode>_z10"
3790 [(set (zero_extract:GPR (match_operand:GPR 0 "nonimmediate_operand" "+d")
3791 (match_operand 1 "const_int_operand" "I") ; size
3792 (match_operand 2 "const_int_operand" "I")) ; pos
3793 (match_operand:GPR 3 "nonimmediate_operand" "d"))
3794 (clobber (reg:CC CC_REGNUM))]
3795 "TARGET_Z10
3796 && (INTVAL (operands[1]) + INTVAL (operands[2])) <= <bitsize>"
3797 "risbg\t%0,%3,64-<bitsize>+%2,64-<bitsize>+%2+%1-1,<bitsize>-%2-%1"
3798 [(set_attr "op_type" "RIE")
3799 (set_attr "z10prop" "z10_super_E1")])
3800
3801 ; and op1 with a mask being 1 for the selected bits and 0 for the rest
3802 ; and op3=op0 with a mask being 0 for the selected bits and 1 for the rest
3803 (define_insn "*insv<mode>_zEC12_noshift"
3804 [(set (match_operand:GPR 0 "nonimmediate_operand" "=d")
3805 (ior:GPR (and:GPR (match_operand:GPR 1 "nonimmediate_operand" "d")
3806 (match_operand:GPR 2 "contiguous_bitmask_operand" ""))
3807 (and:GPR (match_operand:GPR 3 "nonimmediate_operand" "0")
3808 (match_operand:GPR 4 "const_int_operand" ""))))]
3809 "TARGET_ZEC12 && INTVAL (operands[2]) == ~INTVAL (operands[4])"
3810 "risbgn\t%0,%1,%<bfstart>2,%<bfend>2,0"
3811 [(set_attr "op_type" "RIE")])
3812
3813 (define_insn "*insv<mode>_z10_noshift"
3814 [(set (match_operand:GPR 0 "nonimmediate_operand" "=d")
3815 (ior:GPR (and:GPR (match_operand:GPR 1 "nonimmediate_operand" "d")
3816 (match_operand:GPR 2 "contiguous_bitmask_operand" ""))
3817 (and:GPR (match_operand:GPR 3 "nonimmediate_operand" "0")
3818 (match_operand:GPR 4 "const_int_operand" ""))))
3819 (clobber (reg:CC CC_REGNUM))]
3820 "TARGET_Z10 && INTVAL (operands[2]) == ~INTVAL (operands[4])"
3821 "risbg\t%0,%1,%<bfstart>2,%<bfend>2,0"
3822 [(set_attr "op_type" "RIE")
3823 (set_attr "z10prop" "z10_super_E1")])
3824
3825 ; Implement appending Y on the left of S bits of X
3826 ; x = (y << s) | (x & ((1 << s) - 1))
3827 (define_insn "*insv<mode>_zEC12_appendbitsleft"
3828 [(set (match_operand:GPR 0 "nonimmediate_operand" "=d")
3829 (ior:GPR (and:GPR (match_operand:GPR 1 "nonimmediate_operand" "0")
3830 (match_operand:GPR 2 "immediate_operand" ""))
3831 (ashift:GPR (match_operand:GPR 3 "nonimmediate_operand" "d")
3832 (match_operand:GPR 4 "nonzero_shift_count_operand" ""))))]
3833 "TARGET_ZEC12 && UINTVAL (operands[2]) == (1UL << UINTVAL (operands[4])) - 1"
3834 "risbgn\t%0,%3,64-<bitsize>,64-%4-1,%4"
3835 [(set_attr "op_type" "RIE")
3836 (set_attr "z10prop" "z10_super_E1")])
3837
3838 (define_insn "*insv<mode>_z10_appendbitsleft"
3839 [(set (match_operand:GPR 0 "nonimmediate_operand" "=d")
3840 (ior:GPR (and:GPR (match_operand:GPR 1 "nonimmediate_operand" "0")
3841 (match_operand:GPR 2 "immediate_operand" ""))
3842 (ashift:GPR (match_operand:GPR 3 "nonimmediate_operand" "d")
3843 (match_operand:GPR 4 "nonzero_shift_count_operand" ""))))
3844 (clobber (reg:CC CC_REGNUM))]
3845 "TARGET_Z10 && !TARGET_ZEC12 && UINTVAL (operands[2]) == (1UL << UINTVAL (operands[4])) - 1"
3846 "risbg\t%0,%3,64-<bitsize>,64-%4-1,%4"
3847 [(set_attr "op_type" "RIE")
3848 (set_attr "z10prop" "z10_super_E1")])
3849
3850 ; z = (x << c) | (y >> d) with (x << c) and (y >> d) not overlapping after shifting
3851 ; -> z = y >> d; z = (x << c) | (z & ((1 << c) - 1))
3852 ; -> z = y >> d; z = risbg;
3853
3854 (define_split
3855 [(set (match_operand:GPR 0 "nonimmediate_operand" "")
3856 (ior:GPR (lshiftrt:GPR (match_operand:GPR 1 "nonimmediate_operand" "")
3857 (match_operand:GPR 2 "nonzero_shift_count_operand" ""))
3858 (ashift:GPR (match_operand:GPR 3 "nonimmediate_operand" "")
3859 (match_operand:GPR 4 "nonzero_shift_count_operand" ""))))]
3860 "TARGET_ZEC12 && UINTVAL (operands[2]) + UINTVAL (operands[4]) >= <bitsize>"
3861 [(set (match_dup 0)
3862 (lshiftrt:GPR (match_dup 1) (match_dup 2)))
3863 (set (match_dup 0)
3864 (ior:GPR (and:GPR (match_dup 0) (match_dup 5))
3865 (ashift:GPR (match_dup 3) (match_dup 4))))]
3866 {
3867 operands[5] = GEN_INT ((1UL << UINTVAL (operands[4])) - 1);
3868 })
3869
3870 (define_split
3871 [(parallel
3872 [(set (match_operand:GPR 0 "nonimmediate_operand" "")
3873 (ior:GPR (lshiftrt:GPR (match_operand:GPR 1 "nonimmediate_operand" "")
3874 (match_operand:GPR 2 "nonzero_shift_count_operand" ""))
3875 (ashift:GPR (match_operand:GPR 3 "nonimmediate_operand" "")
3876 (match_operand:GPR 4 "nonzero_shift_count_operand" ""))))
3877 (clobber (reg:CC CC_REGNUM))])]
3878 "TARGET_Z10 && !TARGET_ZEC12 && UINTVAL (operands[2]) + UINTVAL (operands[4]) >= <bitsize>"
3879 [(set (match_dup 0)
3880 (lshiftrt:GPR (match_dup 1) (match_dup 2)))
3881 (parallel
3882 [(set (match_dup 0)
3883 (ior:GPR (and:GPR (match_dup 0) (match_dup 5))
3884 (ashift:GPR (match_dup 3) (match_dup 4))))
3885 (clobber (reg:CC CC_REGNUM))])]
3886 {
3887 operands[5] = GEN_INT ((1UL << UINTVAL (operands[4])) - 1);
3888 })
3889
3890 (define_insn "*r<noxa>sbg_<mode>_noshift"
3891 [(set (match_operand:GPR 0 "nonimmediate_operand" "=d")
3892 (IXOR:GPR
3893 (and:GPR (match_operand:GPR 1 "nonimmediate_operand" "d")
3894 (match_operand:GPR 2 "contiguous_bitmask_operand" ""))
3895 (match_operand:GPR 3 "nonimmediate_operand" "0")))
3896 (clobber (reg:CC CC_REGNUM))]
3897 "TARGET_Z10"
3898 "r<noxa>sbg\t%0,%1,%<bfstart>2,%<bfend>2,0"
3899 [(set_attr "op_type" "RIE")])
3900
3901 (define_insn "*r<noxa>sbg_di_rotl"
3902 [(set (match_operand:DI 0 "nonimmediate_operand" "=d")
3903 (IXOR:DI
3904 (and:DI
3905 (rotate:DI
3906 (match_operand:DI 1 "nonimmediate_operand" "d")
3907 (match_operand:DI 3 "const_int_operand" ""))
3908 (match_operand:DI 2 "contiguous_bitmask_operand" ""))
3909 (match_operand:DI 4 "nonimmediate_operand" "0")))
3910 (clobber (reg:CC CC_REGNUM))]
3911 "TARGET_Z10"
3912 "r<noxa>sbg\t%0,%1,%<bfstart>2,%<bfend>2,%b3"
3913 [(set_attr "op_type" "RIE")])
3914
3915 (define_insn "*r<noxa>sbg_<mode>_srl"
3916 [(set (match_operand:GPR 0 "nonimmediate_operand" "=d")
3917 (IXOR:GPR
3918 (and:GPR
3919 (lshiftrt:GPR
3920 (match_operand:GPR 1 "nonimmediate_operand" "d")
3921 (match_operand:GPR 3 "nonzero_shift_count_operand" ""))
3922 (match_operand:GPR 2 "contiguous_bitmask_operand" ""))
3923 (match_operand:GPR 4 "nonimmediate_operand" "0")))
3924 (clobber (reg:CC CC_REGNUM))]
3925 "TARGET_Z10
3926 && s390_extzv_shift_ok (<bitsize>, 64 - INTVAL (operands[3]),
3927 INTVAL (operands[2]))"
3928 "r<noxa>sbg\t%0,%1,%<bfstart>2,%<bfend>2,64-%3"
3929 [(set_attr "op_type" "RIE")])
3930
3931 (define_insn "*r<noxa>sbg_<mode>_sll"
3932 [(set (match_operand:GPR 0 "nonimmediate_operand" "=d")
3933 (IXOR:GPR
3934 (and:GPR
3935 (ashift:GPR
3936 (match_operand:GPR 1 "nonimmediate_operand" "d")
3937 (match_operand:GPR 3 "nonzero_shift_count_operand" ""))
3938 (match_operand:GPR 2 "contiguous_bitmask_operand" ""))
3939 (match_operand:GPR 4 "nonimmediate_operand" "0")))
3940 (clobber (reg:CC CC_REGNUM))]
3941 "TARGET_Z10
3942 && s390_extzv_shift_ok (<bitsize>, INTVAL (operands[3]),
3943 INTVAL (operands[2]))"
3944 "r<noxa>sbg\t%0,%1,%<bfstart>2,%<bfend>2,%3"
3945 [(set_attr "op_type" "RIE")])
3946
3947 ;; These two are generated by combine for s.bf &= val.
3948 ;; ??? For bitfields smaller than 32-bits, we wind up with SImode
3949 ;; shifts and ands, which results in some truly awful patterns
3950 ;; including subregs of operations. Rather unnecessisarily, IMO.
3951 ;; Instead of
3952 ;;
3953 ;; (set (zero_extract:DI (reg/v:DI 50 [ s ])
3954 ;; (const_int 24 [0x18])
3955 ;; (const_int 0 [0]))
3956 ;; (subreg:DI (and:SI (subreg:SI (lshiftrt:DI (reg/v:DI 50 [ s ])
3957 ;; (const_int 40 [0x28])) 4)
3958 ;; (reg:SI 4 %r4 [ y+4 ])) 0))
3959 ;;
3960 ;; we should instead generate
3961 ;;
3962 ;; (set (zero_extract:DI (reg/v:DI 50 [ s ])
3963 ;; (const_int 24 [0x18])
3964 ;; (const_int 0 [0]))
3965 ;; (and:DI (lshiftrt:DI (reg/v:DI 50 [ s ])
3966 ;; (const_int 40 [0x28]))
3967 ;; (subreg:DI (reg:SI 4 %r4 [ y+4 ]) 0)))
3968 ;;
3969 ;; by noticing that we can push down the outer paradoxical subreg
3970 ;; into the operation.
3971
3972 (define_insn "*insv_rnsbg_noshift"
3973 [(set (zero_extract:DI
3974 (match_operand:DI 0 "nonimmediate_operand" "+d")
3975 (match_operand 1 "const_int_operand" "")
3976 (match_operand 2 "const_int_operand" ""))
3977 (and:DI
3978 (match_dup 0)
3979 (match_operand:DI 3 "nonimmediate_operand" "d")))
3980 (clobber (reg:CC CC_REGNUM))]
3981 "TARGET_Z10
3982 && INTVAL (operands[1]) + INTVAL (operands[2]) == 64"
3983 "rnsbg\t%0,%3,%2,63,0"
3984 [(set_attr "op_type" "RIE")])
3985
3986 (define_insn "*insv_rnsbg_srl"
3987 [(set (zero_extract:DI
3988 (match_operand:DI 0 "nonimmediate_operand" "+d")
3989 (match_operand 1 "const_int_operand" "")
3990 (match_operand 2 "const_int_operand" ""))
3991 (and:DI
3992 (lshiftrt:DI
3993 (match_dup 0)
3994 (match_operand 3 "const_int_operand" ""))
3995 (match_operand:DI 4 "nonimmediate_operand" "d")))
3996 (clobber (reg:CC CC_REGNUM))]
3997 "TARGET_Z10
3998 && INTVAL (operands[3]) == 64 - INTVAL (operands[1]) - INTVAL (operands[2])"
3999 "rnsbg\t%0,%4,%2,%2+%1-1,%3"
4000 [(set_attr "op_type" "RIE")])
4001
4002 (define_insn "*insv<mode>_mem_reg"
4003 [(set (zero_extract:W (match_operand:QI 0 "memory_operand" "+Q,S")
4004 (match_operand 1 "const_int_operand" "n,n")
4005 (const_int 0))
4006 (match_operand:W 2 "register_operand" "d,d"))]
4007 "INTVAL (operands[1]) > 0
4008 && INTVAL (operands[1]) <= GET_MODE_BITSIZE (SImode)
4009 && INTVAL (operands[1]) % BITS_PER_UNIT == 0"
4010 {
4011 int size = INTVAL (operands[1]) / BITS_PER_UNIT;
4012
4013 operands[1] = GEN_INT ((1ul << size) - 1);
4014 return (which_alternative == 0) ? "stcm\t%2,%1,%S0"
4015 : "stcmy\t%2,%1,%S0";
4016 }
4017 [(set_attr "op_type" "RS,RSY")
4018 (set_attr "z10prop" "z10_super,z10_super")])
4019
4020 (define_insn "*insvdi_mem_reghigh"
4021 [(set (zero_extract:DI (match_operand:QI 0 "memory_operand" "+QS")
4022 (match_operand 1 "const_int_operand" "n")
4023 (const_int 0))
4024 (lshiftrt:DI (match_operand:DI 2 "register_operand" "d")
4025 (const_int 32)))]
4026 "TARGET_ZARCH
4027 && INTVAL (operands[1]) > 0
4028 && INTVAL (operands[1]) <= GET_MODE_BITSIZE (SImode)
4029 && INTVAL (operands[1]) % BITS_PER_UNIT == 0"
4030 {
4031 int size = INTVAL (operands[1]) / BITS_PER_UNIT;
4032
4033 operands[1] = GEN_INT ((1ul << size) - 1);
4034 return "stcmh\t%2,%1,%S0";
4035 }
4036 [(set_attr "op_type" "RSY")
4037 (set_attr "z10prop" "z10_super")])
4038
4039 (define_insn "*insvdi_reg_imm"
4040 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+d")
4041 (const_int 16)
4042 (match_operand 1 "const_int_operand" "n"))
4043 (match_operand:DI 2 "const_int_operand" "n"))]
4044 "TARGET_ZARCH
4045 && INTVAL (operands[1]) >= 0
4046 && INTVAL (operands[1]) < BITS_PER_WORD
4047 && INTVAL (operands[1]) % 16 == 0"
4048 {
4049 switch (BITS_PER_WORD - INTVAL (operands[1]))
4050 {
4051 case 64: return "iihh\t%0,%x2"; break;
4052 case 48: return "iihl\t%0,%x2"; break;
4053 case 32: return "iilh\t%0,%x2"; break;
4054 case 16: return "iill\t%0,%x2"; break;
4055 default: gcc_unreachable();
4056 }
4057 }
4058 [(set_attr "op_type" "RI")
4059 (set_attr "z10prop" "z10_super_E1")])
4060
4061 ; Update the left-most 32 bit of a DI.
4062 (define_insn "*insv_h_di_reg_extimm"
4063 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+d")
4064 (const_int 32)
4065 (const_int 0))
4066 (match_operand:DI 1 "const_int_operand" "n"))]
4067 "TARGET_EXTIMM"
4068 "iihf\t%0,%o1"
4069 [(set_attr "op_type" "RIL")
4070 (set_attr "z10prop" "z10_fwd_E1")])
4071
4072 ; Update the right-most 32 bit of a DI.
4073 (define_insn "*insv_l_di_reg_extimm"
4074 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+d")
4075 (const_int 32)
4076 (const_int 32))
4077 (match_operand:DI 1 "const_int_operand" "n"))]
4078 "TARGET_EXTIMM"
4079 "iilf\t%0,%o1"
4080 [(set_attr "op_type" "RIL")
4081 (set_attr "z10prop" "z10_fwd_A1")])
4082
4083 ;
4084 ; extendsidi2 instruction pattern(s).
4085 ;
4086
4087 (define_expand "extendsidi2"
4088 [(set (match_operand:DI 0 "register_operand" "")
4089 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "")))]
4090 ""
4091 {
4092 if (!TARGET_ZARCH)
4093 {
4094 emit_clobber (operands[0]);
4095 emit_move_insn (gen_highpart (SImode, operands[0]), operands[1]);
4096 emit_move_insn (gen_lowpart (SImode, operands[0]), const0_rtx);
4097 emit_insn (gen_ashrdi3 (operands[0], operands[0], GEN_INT (32)));
4098 DONE;
4099 }
4100 })
4101
4102 (define_insn "*extendsidi2"
4103 [(set (match_operand:DI 0 "register_operand" "=d,d,d")
4104 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "d,RT,b")))]
4105 "TARGET_ZARCH"
4106 "@
4107 lgfr\t%0,%1
4108 lgf\t%0,%1
4109 lgfrl\t%0,%1"
4110 [(set_attr "op_type" "RRE,RXY,RIL")
4111 (set_attr "type" "*,*,larl")
4112 (set_attr "cpu_facility" "*,*,z10")
4113 (set_attr "z10prop" "z10_super_E1,z10_super_E1,z10_super_E1")])
4114
4115 ;
4116 ; extend(hi|qi)(si|di)2 instruction pattern(s).
4117 ;
4118
4119 (define_expand "extend<HQI:mode><DSI:mode>2"
4120 [(set (match_operand:DSI 0 "register_operand" "")
4121 (sign_extend:DSI (match_operand:HQI 1 "nonimmediate_operand" "")))]
4122 ""
4123 {
4124 if (<DSI:MODE>mode == DImode && !TARGET_ZARCH)
4125 {
4126 rtx tmp = gen_reg_rtx (SImode);
4127 emit_insn (gen_extend<HQI:mode>si2 (tmp, operands[1]));
4128 emit_insn (gen_extendsidi2 (operands[0], tmp));
4129 DONE;
4130 }
4131 else if (!TARGET_EXTIMM)
4132 {
4133 rtx bitcount = GEN_INT (<DSI:bitsize> - <HQI:bitsize>);
4134
4135 operands[1] = gen_lowpart (<DSI:MODE>mode, operands[1]);
4136 emit_insn (gen_ashl<DSI:mode>3 (operands[0], operands[1], bitcount));
4137 emit_insn (gen_ashr<DSI:mode>3 (operands[0], operands[0], bitcount));
4138 DONE;
4139 }
4140 })
4141
4142 ;
4143 ; extendhidi2 instruction pattern(s).
4144 ;
4145
4146 (define_insn "*extendhidi2_extimm"
4147 [(set (match_operand:DI 0 "register_operand" "=d,d,d")
4148 (sign_extend:DI (match_operand:HI 1 "general_operand" "d,RT,b")))]
4149 "TARGET_ZARCH && TARGET_EXTIMM"
4150 "@
4151 lghr\t%0,%1
4152 lgh\t%0,%1
4153 lghrl\t%0,%1"
4154 [(set_attr "op_type" "RRE,RXY,RIL")
4155 (set_attr "type" "*,*,larl")
4156 (set_attr "cpu_facility" "extimm,extimm,z10")
4157 (set_attr "z10prop" "z10_super_E1,z10_super_E1,z10_super_E1")])
4158
4159 (define_insn "*extendhidi2"
4160 [(set (match_operand:DI 0 "register_operand" "=d")
4161 (sign_extend:DI (match_operand:HI 1 "memory_operand" "RT")))]
4162 "TARGET_ZARCH"
4163 "lgh\t%0,%1"
4164 [(set_attr "op_type" "RXY")
4165 (set_attr "z10prop" "z10_super_E1")])
4166
4167 ;
4168 ; extendhisi2 instruction pattern(s).
4169 ;
4170
4171 (define_insn "*extendhisi2_extimm"
4172 [(set (match_operand:SI 0 "register_operand" "=d,d,d,d")
4173 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" " d,R,T,b")))]
4174 "TARGET_EXTIMM"
4175 "@
4176 lhr\t%0,%1
4177 lh\t%0,%1
4178 lhy\t%0,%1
4179 lhrl\t%0,%1"
4180 [(set_attr "op_type" "RRE,RX,RXY,RIL")
4181 (set_attr "type" "*,*,*,larl")
4182 (set_attr "cpu_facility" "extimm,extimm,extimm,z10")
4183 (set_attr "z10prop" "z10_super_E1,z10_super_E1,z10_super_E1,z10_super_E1")])
4184
4185 (define_insn "*extendhisi2"
4186 [(set (match_operand:SI 0 "register_operand" "=d,d")
4187 (sign_extend:SI (match_operand:HI 1 "memory_operand" "R,T")))]
4188 "!TARGET_EXTIMM"
4189 "@
4190 lh\t%0,%1
4191 lhy\t%0,%1"
4192 [(set_attr "op_type" "RX,RXY")
4193 (set_attr "z10prop" "z10_super_E1,z10_super_E1")])
4194
4195 ;
4196 ; extendqi(si|di)2 instruction pattern(s).
4197 ;
4198
4199 ; lbr, lgbr, lb, lgb
4200 (define_insn "*extendqi<mode>2_extimm"
4201 [(set (match_operand:GPR 0 "register_operand" "=d,d")
4202 (sign_extend:GPR (match_operand:QI 1 "nonimmediate_operand" "d,RT")))]
4203 "TARGET_EXTIMM"
4204 "@
4205 l<g>br\t%0,%1
4206 l<g>b\t%0,%1"
4207 [(set_attr "op_type" "RRE,RXY")
4208 (set_attr "z10prop" "z10_super_E1,z10_super_E1")])
4209
4210 ; lb, lgb
4211 (define_insn "*extendqi<mode>2"
4212 [(set (match_operand:GPR 0 "register_operand" "=d")
4213 (sign_extend:GPR (match_operand:QI 1 "memory_operand" "RT")))]
4214 "!TARGET_EXTIMM && TARGET_LONG_DISPLACEMENT"
4215 "l<g>b\t%0,%1"
4216 [(set_attr "op_type" "RXY")
4217 (set_attr "z10prop" "z10_super_E1")])
4218
4219 (define_insn_and_split "*extendqi<mode>2_short_displ"
4220 [(set (match_operand:GPR 0 "register_operand" "=d")
4221 (sign_extend:GPR (match_operand:QI 1 "s_operand" "Q")))
4222 (clobber (reg:CC CC_REGNUM))]
4223 "!TARGET_EXTIMM && !TARGET_LONG_DISPLACEMENT"
4224 "#"
4225 "&& reload_completed"
4226 [(parallel
4227 [(set (match_dup 0) (unspec:GPR [(match_dup 1) (const_int 8)] UNSPEC_ICM))
4228 (clobber (reg:CC CC_REGNUM))])
4229 (parallel
4230 [(set (match_dup 0) (ashiftrt:GPR (match_dup 0) (match_dup 2)))
4231 (clobber (reg:CC CC_REGNUM))])]
4232 {
4233 operands[1] = adjust_address (operands[1], BLKmode, 0);
4234 set_mem_size (operands[1], GET_MODE_SIZE (QImode));
4235 operands[2] = GEN_INT (<GPR:bitsize> - BITS_PER_UNIT);
4236 })
4237
4238 ;
4239 ; zero_extendsidi2 instruction pattern(s).
4240 ;
4241
4242 (define_expand "zero_extendsidi2"
4243 [(set (match_operand:DI 0 "register_operand" "")
4244 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "")))]
4245 ""
4246 {
4247 if (!TARGET_ZARCH)
4248 {
4249 emit_clobber (operands[0]);
4250 emit_move_insn (gen_lowpart (SImode, operands[0]), operands[1]);
4251 emit_move_insn (gen_highpart (SImode, operands[0]), const0_rtx);
4252 DONE;
4253 }
4254 })
4255
4256 (define_insn "*zero_extendsidi2"
4257 [(set (match_operand:DI 0 "register_operand" "=d,d,d")
4258 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "d,RT,b")))]
4259 "TARGET_ZARCH"
4260 "@
4261 llgfr\t%0,%1
4262 llgf\t%0,%1
4263 llgfrl\t%0,%1"
4264 [(set_attr "op_type" "RRE,RXY,RIL")
4265 (set_attr "type" "*,*,larl")
4266 (set_attr "cpu_facility" "*,*,z10")
4267 (set_attr "z10prop" "z10_fwd_E1,z10_fwd_A3,z10_fwd_A3")])
4268
4269 ;
4270 ; LLGT-type instructions (zero-extend from 31 bit to 64 bit).
4271 ;
4272
4273 (define_insn "*llgt_sidi"
4274 [(set (match_operand:DI 0 "register_operand" "=d")
4275 (and:DI (subreg:DI (match_operand:SI 1 "memory_operand" "RT") 0)
4276 (const_int 2147483647)))]
4277 "TARGET_ZARCH"
4278 "llgt\t%0,%1"
4279 [(set_attr "op_type" "RXE")
4280 (set_attr "z10prop" "z10_super_E1")])
4281
4282 (define_insn_and_split "*llgt_sidi_split"
4283 [(set (match_operand:DI 0 "register_operand" "=d")
4284 (and:DI (subreg:DI (match_operand:SI 1 "memory_operand" "RT") 0)
4285 (const_int 2147483647)))
4286 (clobber (reg:CC CC_REGNUM))]
4287 "TARGET_ZARCH"
4288 "#"
4289 "&& reload_completed"
4290 [(set (match_dup 0)
4291 (and:DI (subreg:DI (match_dup 1) 0)
4292 (const_int 2147483647)))]
4293 "")
4294
4295 (define_insn "*llgt_sisi"
4296 [(set (match_operand:SI 0 "register_operand" "=d,d")
4297 (and:SI (match_operand:SI 1 "nonimmediate_operand" "d,RT")
4298 (const_int 2147483647)))]
4299 "TARGET_ZARCH"
4300 "@
4301 llgtr\t%0,%1
4302 llgt\t%0,%1"
4303 [(set_attr "op_type" "RRE,RXE")
4304 (set_attr "z10prop" "z10_super_E1,z10_super_E1")])
4305
4306 (define_insn "*llgt_didi"
4307 [(set (match_operand:DI 0 "register_operand" "=d,d")
4308 (and:DI (match_operand:DI 1 "nonimmediate_operand" "d,o")
4309 (const_int 2147483647)))]
4310 "TARGET_ZARCH"
4311 "@
4312 llgtr\t%0,%1
4313 llgt\t%0,%N1"
4314 [(set_attr "op_type" "RRE,RXE")
4315 (set_attr "z10prop" "z10_super_E1,z10_super_E1")])
4316
4317 (define_split
4318 [(set (match_operand:DSI 0 "register_operand" "")
4319 (and:DSI (match_operand:DSI 1 "nonimmediate_operand" "")
4320 (const_int 2147483647)))
4321 (clobber (reg:CC CC_REGNUM))]
4322 "TARGET_ZARCH && reload_completed"
4323 [(set (match_dup 0)
4324 (and:DSI (match_dup 1)
4325 (const_int 2147483647)))]
4326 "")
4327
4328 ;
4329 ; zero_extend(hi|qi)(si|di)2 instruction pattern(s).
4330 ;
4331
4332 (define_expand "zero_extend<mode>di2"
4333 [(set (match_operand:DI 0 "register_operand" "")
4334 (zero_extend:DI (match_operand:HQI 1 "nonimmediate_operand" "")))]
4335 ""
4336 {
4337 if (!TARGET_ZARCH)
4338 {
4339 rtx tmp = gen_reg_rtx (SImode);
4340 emit_insn (gen_zero_extend<mode>si2 (tmp, operands[1]));
4341 emit_insn (gen_zero_extendsidi2 (operands[0], tmp));
4342 DONE;
4343 }
4344 else if (!TARGET_EXTIMM)
4345 {
4346 rtx bitcount = GEN_INT (64 - <HQI:bitsize>);
4347 operands[1] = gen_lowpart (DImode, operands[1]);
4348 emit_insn (gen_ashldi3 (operands[0], operands[1], bitcount));
4349 emit_insn (gen_lshrdi3 (operands[0], operands[0], bitcount));
4350 DONE;
4351 }
4352 })
4353
4354 (define_expand "zero_extend<mode>si2"
4355 [(set (match_operand:SI 0 "register_operand" "")
4356 (zero_extend:SI (match_operand:HQI 1 "nonimmediate_operand" "")))]
4357 ""
4358 {
4359 if (!TARGET_EXTIMM)
4360 {
4361 operands[1] = gen_lowpart (SImode, operands[1]);
4362 emit_insn (gen_andsi3 (operands[0], operands[1],
4363 GEN_INT ((1 << <HQI:bitsize>) - 1)));
4364 DONE;
4365 }
4366 })
4367
4368 ; llhrl, llghrl
4369 (define_insn "*zero_extendhi<mode>2_z10"
4370 [(set (match_operand:GPR 0 "register_operand" "=d,d,d")
4371 (zero_extend:GPR (match_operand:HI 1 "nonimmediate_operand" "d,RT,b")))]
4372 "TARGET_Z10"
4373 "@
4374 ll<g>hr\t%0,%1
4375 ll<g>h\t%0,%1
4376 ll<g>hrl\t%0,%1"
4377 [(set_attr "op_type" "RXY,RRE,RIL")
4378 (set_attr "type" "*,*,larl")
4379 (set_attr "cpu_facility" "*,*,z10")
4380 (set_attr "z10prop" "z10_super_E1,z10_fwd_A3,z10_fwd_A3")])
4381
4382 ; llhr, llcr, llghr, llgcr, llh, llc, llgh, llgc
4383 (define_insn "*zero_extend<HQI:mode><GPR:mode>2_extimm"
4384 [(set (match_operand:GPR 0 "register_operand" "=d,d")
4385 (zero_extend:GPR (match_operand:HQI 1 "nonimmediate_operand" "d,RT")))]
4386 "TARGET_EXTIMM"
4387 "@
4388 ll<g><hc>r\t%0,%1
4389 ll<g><hc>\t%0,%1"
4390 [(set_attr "op_type" "RRE,RXY")
4391 (set_attr "z10prop" "z10_super_E1,z10_fwd_A3")])
4392
4393 ; llgh, llgc
4394 (define_insn "*zero_extend<HQI:mode><GPR:mode>2"
4395 [(set (match_operand:GPR 0 "register_operand" "=d")
4396 (zero_extend:GPR (match_operand:HQI 1 "memory_operand" "RT")))]
4397 "TARGET_ZARCH && !TARGET_EXTIMM"
4398 "llg<hc>\t%0,%1"
4399 [(set_attr "op_type" "RXY")
4400 (set_attr "z10prop" "z10_fwd_A3")])
4401
4402 (define_insn_and_split "*zero_extendhisi2_31"
4403 [(set (match_operand:SI 0 "register_operand" "=&d")
4404 (zero_extend:SI (match_operand:HI 1 "s_operand" "QS")))
4405 (clobber (reg:CC CC_REGNUM))]
4406 "!TARGET_ZARCH"
4407 "#"
4408 "&& reload_completed"
4409 [(set (match_dup 0) (const_int 0))
4410 (parallel
4411 [(set (strict_low_part (match_dup 2)) (match_dup 1))
4412 (clobber (reg:CC CC_REGNUM))])]
4413 "operands[2] = gen_lowpart (HImode, operands[0]);")
4414
4415 (define_insn_and_split "*zero_extendqisi2_31"
4416 [(set (match_operand:SI 0 "register_operand" "=&d")
4417 (zero_extend:SI (match_operand:QI 1 "memory_operand" "RT")))]
4418 "!TARGET_ZARCH"
4419 "#"
4420 "&& reload_completed"
4421 [(set (match_dup 0) (const_int 0))
4422 (set (strict_low_part (match_dup 2)) (match_dup 1))]
4423 "operands[2] = gen_lowpart (QImode, operands[0]);")
4424
4425 ;
4426 ; zero_extendqihi2 instruction pattern(s).
4427 ;
4428
4429 (define_expand "zero_extendqihi2"
4430 [(set (match_operand:HI 0 "register_operand" "")
4431 (zero_extend:HI (match_operand:QI 1 "register_operand" "")))]
4432 "TARGET_ZARCH && !TARGET_EXTIMM"
4433 {
4434 operands[1] = gen_lowpart (HImode, operands[1]);
4435 emit_insn (gen_andhi3 (operands[0], operands[1], GEN_INT (0xff)));
4436 DONE;
4437 })
4438
4439 (define_insn "*zero_extendqihi2_64"
4440 [(set (match_operand:HI 0 "register_operand" "=d")
4441 (zero_extend:HI (match_operand:QI 1 "memory_operand" "RT")))]
4442 "TARGET_ZARCH && !TARGET_EXTIMM"
4443 "llgc\t%0,%1"
4444 [(set_attr "op_type" "RXY")
4445 (set_attr "z10prop" "z10_fwd_A3")])
4446
4447 (define_insn_and_split "*zero_extendqihi2_31"
4448 [(set (match_operand:HI 0 "register_operand" "=&d")
4449 (zero_extend:HI (match_operand:QI 1 "memory_operand" "RT")))]
4450 "!TARGET_ZARCH"
4451 "#"
4452 "&& reload_completed"
4453 [(set (match_dup 0) (const_int 0))
4454 (set (strict_low_part (match_dup 2)) (match_dup 1))]
4455 "operands[2] = gen_lowpart (QImode, operands[0]);")
4456
4457 ;
4458 ; fixuns_trunc(dd|td)di2 instruction pattern(s).
4459 ;
4460
4461 (define_expand "fixuns_truncdddi2"
4462 [(parallel
4463 [(set (match_operand:DI 0 "register_operand" "")
4464 (unsigned_fix:DI (match_operand:DD 1 "register_operand" "")))
4465 (unspec:DI [(const_int 5)] UNSPEC_ROUND)
4466 (clobber (reg:CC CC_REGNUM))])]
4467
4468 "TARGET_HARD_DFP"
4469 {
4470 if (!TARGET_Z196)
4471 {
4472 rtx_code_label *label1 = gen_label_rtx ();
4473 rtx_code_label *label2 = gen_label_rtx ();
4474 rtx temp = gen_reg_rtx (TDmode);
4475 REAL_VALUE_TYPE cmp, sub;
4476
4477 decimal_real_from_string (&cmp, "9223372036854775808.0"); /* 2^63 */
4478 decimal_real_from_string (&sub, "18446744073709551616.0"); /* 2^64 */
4479
4480 /* 2^63 can't be represented as 64bit DFP number with full precision. The
4481 solution is doing the check and the subtraction in TD mode and using a
4482 TD -> DI convert afterwards. */
4483 emit_insn (gen_extendddtd2 (temp, operands[1]));
4484 temp = force_reg (TDmode, temp);
4485 emit_cmp_and_jump_insns (temp,
4486 const_double_from_real_value (cmp, TDmode),
4487 LT, NULL_RTX, VOIDmode, 0, label1);
4488 emit_insn (gen_subtd3 (temp, temp,
4489 const_double_from_real_value (sub, TDmode)));
4490 emit_insn (gen_fix_trunctddi2_dfp (operands[0], temp, GEN_INT (11)));
4491 emit_jump (label2);
4492
4493 emit_label (label1);
4494 emit_insn (gen_fix_truncdddi2_dfp (operands[0], operands[1], GEN_INT (9)));
4495 emit_label (label2);
4496 DONE;
4497 }
4498 })
4499
4500 (define_expand "fixuns_trunctddi2"
4501 [(parallel
4502 [(set (match_operand:DI 0 "register_operand" "")
4503 (unsigned_fix:DI (match_operand:TD 1 "register_operand" "")))
4504 (unspec:DI [(const_int 5)] UNSPEC_ROUND)
4505 (clobber (reg:CC CC_REGNUM))])]
4506
4507 "TARGET_HARD_DFP"
4508 {
4509 if (!TARGET_Z196)
4510 {
4511 rtx_code_label *label1 = gen_label_rtx ();
4512 rtx_code_label *label2 = gen_label_rtx ();
4513 rtx temp = gen_reg_rtx (TDmode);
4514 REAL_VALUE_TYPE cmp, sub;
4515
4516 operands[1] = force_reg (TDmode, operands[1]);
4517 decimal_real_from_string (&cmp, "9223372036854775808.0"); /* 2^63 */
4518 decimal_real_from_string (&sub, "18446744073709551616.0"); /* 2^64 */
4519
4520 emit_cmp_and_jump_insns (operands[1],
4521 const_double_from_real_value (cmp, TDmode),
4522 LT, NULL_RTX, VOIDmode, 0, label1);
4523 emit_insn (gen_subtd3 (temp, operands[1],
4524 const_double_from_real_value (sub, TDmode)));
4525 emit_insn (gen_fix_trunctddi2_dfp (operands[0], temp, GEN_INT (11)));
4526 emit_jump (label2);
4527
4528 emit_label (label1);
4529 emit_insn (gen_fix_trunctddi2_dfp (operands[0], operands[1], GEN_INT (9)));
4530 emit_label (label2);
4531 DONE;
4532 }
4533 })
4534
4535 ;
4536 ; fixuns_trunc(sf|df|tf)(si|di)2 and fix_trunc(sf|df|tf)(si|di)2
4537 ; instruction pattern(s).
4538 ;
4539
4540 (define_expand "fixuns_trunc<BFP:mode><GPR:mode>2"
4541 [(parallel
4542 [(set (match_operand:GPR 0 "register_operand" "")
4543 (unsigned_fix:GPR (match_operand:BFP 1 "register_operand" "")))
4544 (unspec:GPR [(const_int 5)] UNSPEC_ROUND)
4545 (clobber (reg:CC CC_REGNUM))])]
4546 "TARGET_HARD_FLOAT"
4547 {
4548 if (!TARGET_Z196)
4549 {
4550 rtx_code_label *label1 = gen_label_rtx ();
4551 rtx_code_label *label2 = gen_label_rtx ();
4552 rtx temp = gen_reg_rtx (<BFP:MODE>mode);
4553 REAL_VALUE_TYPE cmp, sub;
4554
4555 operands[1] = force_reg (<BFP:MODE>mode, operands[1]);
4556 real_2expN (&cmp, <GPR:bitsize> - 1, <BFP:MODE>mode);
4557 real_2expN (&sub, <GPR:bitsize>, <BFP:MODE>mode);
4558
4559 emit_cmp_and_jump_insns (operands[1],
4560 const_double_from_real_value (cmp, <BFP:MODE>mode),
4561 LT, NULL_RTX, VOIDmode, 0, label1);
4562 emit_insn (gen_sub<BFP:mode>3 (temp, operands[1],
4563 const_double_from_real_value (sub, <BFP:MODE>mode)));
4564 emit_insn (gen_fix_trunc<BFP:mode><GPR:mode>2_bfp (operands[0], temp,
4565 GEN_INT (7)));
4566 emit_jump (label2);
4567
4568 emit_label (label1);
4569 emit_insn (gen_fix_trunc<BFP:mode><GPR:mode>2_bfp (operands[0],
4570 operands[1], GEN_INT (5)));
4571 emit_label (label2);
4572 DONE;
4573 }
4574 })
4575
4576 ; fixuns_trunc(td|dd)si2 expander
4577 (define_expand "fixuns_trunc<mode>si2"
4578 [(parallel
4579 [(set (match_operand:SI 0 "register_operand" "")
4580 (unsigned_fix:SI (match_operand:DFP 1 "register_operand" "")))
4581 (unspec:SI [(const_int 5)] UNSPEC_ROUND)
4582 (clobber (reg:CC CC_REGNUM))])]
4583 "TARGET_Z196 && TARGET_HARD_DFP"
4584 "")
4585
4586 ; fixuns_trunc(tf|df|sf|td|dd)(di|si)2 instruction patterns.
4587
4588 (define_insn "*fixuns_truncdfdi2_z13"
4589 [(set (match_operand:DI 0 "register_operand" "=d,v")
4590 (unsigned_fix:DI (match_operand:DF 1 "register_operand" "f,v")))
4591 (unspec:DI [(match_operand:DI 2 "immediate_operand" "K,K")] UNSPEC_ROUND)
4592 (clobber (reg:CC CC_REGNUM))]
4593 "TARGET_Z13 && TARGET_HARD_FLOAT"
4594 "@
4595 clgdbr\t%0,%h2,%1,0
4596 wclgdb\t%v0,%v1,0,%h2"
4597 [(set_attr "op_type" "RRF,VRR")
4598 (set_attr "type" "ftoi")])
4599
4600 ; clfebr, clfdbr, clfxbr, clgebr, clgdbr, clgxbr
4601 ; clfdtr, clfxtr, clgdtr, clgxtr
4602 (define_insn "*fixuns_trunc<FP:mode><GPR:mode>2_z196"
4603 [(set (match_operand:GPR 0 "register_operand" "=d")
4604 (unsigned_fix:GPR (match_operand:FP 1 "register_operand" "f")))
4605 (unspec:GPR [(match_operand:GPR 2 "immediate_operand" "K")] UNSPEC_ROUND)
4606 (clobber (reg:CC CC_REGNUM))]
4607 "TARGET_Z196 && TARGET_HARD_FLOAT
4608 && (!TARGET_Z13 || <GPR:MODE>mode != DImode || <FP:MODE>mode != DFmode)"
4609 "cl<GPR:gf><FP:xde><FP:bt>r\t%0,%h2,%1,0"
4610 [(set_attr "op_type" "RRF")
4611 (set_attr "type" "ftoi")])
4612
4613 (define_expand "fix_trunc<DSF:mode><GPR:mode>2"
4614 [(set (match_operand:GPR 0 "register_operand" "")
4615 (fix:GPR (match_operand:DSF 1 "register_operand" "")))]
4616 "TARGET_HARD_FLOAT"
4617 {
4618 emit_insn (gen_fix_trunc<DSF:mode><GPR:mode>2_bfp (operands[0], operands[1],
4619 GEN_INT (5)));
4620 DONE;
4621 })
4622
4623 (define_insn "*fix_truncdfdi2_bfp_z13"
4624 [(set (match_operand:DI 0 "register_operand" "=d,v")
4625 (fix:DI (match_operand:DF 1 "register_operand" "f,v")))
4626 (unspec:DI [(match_operand:DI 2 "immediate_operand" "K,K")] UNSPEC_ROUND)
4627 (clobber (reg:CC CC_REGNUM))]
4628 "TARGET_Z13 && TARGET_HARD_FLOAT"
4629 "@
4630 cgdbr\t%0,%h2,%1
4631 wcgdb\t%v0,%v1,0,%h2"
4632 [(set_attr "op_type" "RRE,VRR")
4633 (set_attr "type" "ftoi")])
4634
4635 ; cgxbr, cgdbr, cgebr, cfxbr, cfdbr, cfebr
4636 (define_insn "*fix_trunc<BFP:mode><GPR:mode>2_bfp"
4637 [(set (match_operand:GPR 0 "register_operand" "=d")
4638 (fix:GPR (match_operand:BFP 1 "register_operand" "f")))
4639 (unspec:GPR [(match_operand:GPR 2 "immediate_operand" "K")] UNSPEC_ROUND)
4640 (clobber (reg:CC CC_REGNUM))]
4641 "TARGET_HARD_FLOAT
4642 && (!TARGET_VX || <GPR:MODE>mode != DImode || <BFP:MODE>mode != DFmode)"
4643 "c<GPR:gf><BFP:xde>br\t%0,%h2,%1"
4644 [(set_attr "op_type" "RRE")
4645 (set_attr "type" "ftoi")])
4646
4647 (define_expand "fix_trunc<BFP:mode><GPR:mode>2_bfp"
4648 [(parallel
4649 [(set (match_operand:GPR 0 "register_operand" "=d")
4650 (fix:GPR (match_operand:BFP 1 "register_operand" "f")))
4651 (unspec:GPR [(match_operand:GPR 2 "immediate_operand" "K")] UNSPEC_ROUND)
4652 (clobber (reg:CC CC_REGNUM))])]
4653 "TARGET_HARD_FLOAT")
4654 ;
4655 ; fix_trunc(td|dd)di2 instruction pattern(s).
4656 ;
4657
4658 (define_expand "fix_trunc<mode>di2"
4659 [(set (match_operand:DI 0 "register_operand" "")
4660 (fix:DI (match_operand:DFP 1 "nonimmediate_operand" "")))]
4661 "TARGET_ZARCH && TARGET_HARD_DFP"
4662 {
4663 operands[1] = force_reg (<MODE>mode, operands[1]);
4664 emit_insn (gen_fix_trunc<mode>di2_dfp (operands[0], operands[1],
4665 GEN_INT (9)));
4666 DONE;
4667 })
4668
4669 ; cgxtr, cgdtr
4670 (define_insn "fix_trunc<DFP:mode>di2_dfp"
4671 [(set (match_operand:DI 0 "register_operand" "=d")
4672 (fix:DI (match_operand:DFP 1 "register_operand" "f")))
4673 (unspec:DI [(match_operand:DI 2 "immediate_operand" "K")] UNSPEC_ROUND)
4674 (clobber (reg:CC CC_REGNUM))]
4675 "TARGET_ZARCH && TARGET_HARD_DFP"
4676 "cg<DFP:xde>tr\t%0,%h2,%1"
4677 [(set_attr "op_type" "RRF")
4678 (set_attr "type" "ftoidfp")])
4679
4680
4681 ;
4682 ; fix_trunctf(si|di)2 instruction pattern(s).
4683 ;
4684
4685 (define_expand "fix_trunctf<mode>2"
4686 [(parallel [(set (match_operand:GPR 0 "register_operand" "")
4687 (fix:GPR (match_operand:TF 1 "register_operand" "")))
4688 (unspec:GPR [(const_int 5)] UNSPEC_ROUND)
4689 (clobber (reg:CC CC_REGNUM))])]
4690 "TARGET_HARD_FLOAT"
4691 "")
4692
4693
4694 ;
4695 ; float(si|di)(tf|df|sf|td|dd)2 instruction pattern(s).
4696 ;
4697
4698 ; cxgbr, cdgbr, cegbr, cxgtr, cdgtr
4699 (define_insn "floatdi<mode>2"
4700 [(set (match_operand:FP 0 "register_operand" "=f,<vf>")
4701 (float:FP (match_operand:DI 1 "register_operand" "d,<vd>")))]
4702 "TARGET_ZARCH && TARGET_HARD_FLOAT"
4703 "@
4704 c<xde>g<bt>r\t%0,%1
4705 wcdgb\t%v0,%v1,0,0"
4706 [(set_attr "op_type" "RRE,VRR")
4707 (set_attr "type" "itof<mode>" )
4708 (set_attr "cpu_facility" "*,vec")])
4709
4710 ; cxfbr, cdfbr, cefbr
4711 (define_insn "floatsi<mode>2"
4712 [(set (match_operand:BFP 0 "register_operand" "=f")
4713 (float:BFP (match_operand:SI 1 "register_operand" "d")))]
4714 "TARGET_HARD_FLOAT"
4715 "c<xde>fbr\t%0,%1"
4716 [(set_attr "op_type" "RRE")
4717 (set_attr "type" "itof<mode>" )])
4718
4719 ; cxftr, cdftr
4720 (define_insn "floatsi<mode>2"
4721 [(set (match_operand:DFP 0 "register_operand" "=f")
4722 (float:DFP (match_operand:SI 1 "register_operand" "d")))]
4723 "TARGET_Z196 && TARGET_HARD_FLOAT"
4724 "c<xde>ftr\t%0,0,%1,0"
4725 [(set_attr "op_type" "RRE")
4726 (set_attr "type" "itof<mode>" )])
4727
4728 ;
4729 ; floatuns(si|di)(tf|df|sf|td|dd)2 instruction pattern(s).
4730 ;
4731
4732 (define_insn "*floatunsdidf2_z13"
4733 [(set (match_operand:DF 0 "register_operand" "=f,v")
4734 (unsigned_float:DF (match_operand:DI 1 "register_operand" "d,v")))]
4735 "TARGET_Z13 && TARGET_HARD_FLOAT"
4736 "@
4737 cdlgbr\t%0,0,%1,0
4738 wcdlgb\t%v0,%v1,0,0"
4739 [(set_attr "op_type" "RRE,VRR")
4740 (set_attr "type" "itofdf")])
4741
4742 ; cxlgbr, cdlgbr, celgbr, cxlgtr, cdlgtr
4743 ; cxlfbr, cdlfbr, celfbr, cxlftr, cdlftr
4744 (define_insn "*floatuns<GPR:mode><FP:mode>2"
4745 [(set (match_operand:FP 0 "register_operand" "=f")
4746 (unsigned_float:FP (match_operand:GPR 1 "register_operand" "d")))]
4747 "TARGET_Z196 && TARGET_HARD_FLOAT
4748 && (!TARGET_VX || <FP:MODE>mode != DFmode || <GPR:MODE>mode != DImode)"
4749 "c<FP:xde>l<GPR:gf><FP:bt>r\t%0,0,%1,0"
4750 [(set_attr "op_type" "RRE")
4751 (set_attr "type" "itof<FP:mode>")])
4752
4753 (define_expand "floatuns<GPR:mode><FP:mode>2"
4754 [(set (match_operand:FP 0 "register_operand" "")
4755 (unsigned_float:FP (match_operand:GPR 1 "register_operand" "")))]
4756 "TARGET_Z196 && TARGET_HARD_FLOAT")
4757
4758 ;
4759 ; truncdfsf2 instruction pattern(s).
4760 ;
4761
4762 (define_insn "truncdfsf2"
4763 [(set (match_operand:SF 0 "register_operand" "=f,v")
4764 (float_truncate:SF (match_operand:DF 1 "register_operand" "f,v")))]
4765 "TARGET_HARD_FLOAT"
4766 "@
4767 ledbr\t%0,%1
4768 wledb\t%v0,%v1,0,0" ; IEEE inexact exception not suppressed
4769 ; According to BFP rounding mode
4770 [(set_attr "op_type" "RRE,VRR")
4771 (set_attr "type" "ftruncdf")
4772 (set_attr "cpu_facility" "*,vec")])
4773
4774 ;
4775 ; trunctf(df|sf)2 instruction pattern(s).
4776 ;
4777
4778 ; ldxbr, lexbr
4779 (define_insn "trunctf<mode>2"
4780 [(set (match_operand:DSF 0 "register_operand" "=f")
4781 (float_truncate:DSF (match_operand:TF 1 "register_operand" "f")))
4782 (clobber (match_scratch:TF 2 "=f"))]
4783 "TARGET_HARD_FLOAT"
4784 "l<xde>xbr\t%2,%1\;l<xde>r\t%0,%2"
4785 [(set_attr "length" "6")
4786 (set_attr "type" "ftrunctf")])
4787
4788 ;
4789 ; trunctddd2 and truncddsd2 instruction pattern(s).
4790 ;
4791
4792 (define_insn "trunctddd2"
4793 [(set (match_operand:DD 0 "register_operand" "=f")
4794 (float_truncate:DD (match_operand:TD 1 "register_operand" "f")))
4795 (clobber (match_scratch:TD 2 "=f"))]
4796 "TARGET_HARD_DFP"
4797 "ldxtr\t%2,0,%1,0\;ldr\t%0,%2"
4798 [(set_attr "length" "6")
4799 (set_attr "type" "ftruncdd")])
4800
4801 (define_insn "truncddsd2"
4802 [(set (match_operand:SD 0 "register_operand" "=f")
4803 (float_truncate:SD (match_operand:DD 1 "register_operand" "f")))]
4804 "TARGET_HARD_DFP"
4805 "ledtr\t%0,0,%1,0"
4806 [(set_attr "op_type" "RRF")
4807 (set_attr "type" "ftruncsd")])
4808
4809 (define_expand "trunctdsd2"
4810 [(parallel
4811 [(set (match_dup 3)
4812 (float_truncate:DD (match_operand:TD 1 "register_operand" "")))
4813 (clobber (match_scratch:TD 2 ""))])
4814 (set (match_operand:SD 0 "register_operand" "")
4815 (float_truncate:SD (match_dup 3)))]
4816 "TARGET_HARD_DFP"
4817 {
4818 operands[3] = gen_reg_rtx (DDmode);
4819 })
4820
4821 ;
4822 ; extend(sf|df)(df|tf)2 instruction pattern(s).
4823 ;
4824
4825 (define_insn "*extendsfdf2_z13"
4826 [(set (match_operand:DF 0 "register_operand" "=f,f,v")
4827 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "f,R,v")))]
4828 "TARGET_Z13 && TARGET_HARD_FLOAT"
4829 "@
4830 ldebr\t%0,%1
4831 ldeb\t%0,%1
4832 wldeb\t%v0,%v1"
4833 [(set_attr "op_type" "RRE,RXE,VRR")
4834 (set_attr "type" "fsimpdf, floaddf,fsimpdf")])
4835
4836 ; ldebr, ldeb, lxdbr, lxdb, lxebr, lxeb
4837 (define_insn "*extend<DSF:mode><BFP:mode>2"
4838 [(set (match_operand:BFP 0 "register_operand" "=f,f")
4839 (float_extend:BFP (match_operand:DSF 1 "nonimmediate_operand" "f,R")))]
4840 "TARGET_HARD_FLOAT
4841 && GET_MODE_SIZE (<BFP:MODE>mode) > GET_MODE_SIZE (<DSF:MODE>mode)
4842 && (!TARGET_VX || <BFP:MODE>mode != DFmode || <DSF:MODE>mode != SFmode)"
4843 "@
4844 l<BFP:xde><DSF:xde>br\t%0,%1
4845 l<BFP:xde><DSF:xde>b\t%0,%1"
4846 [(set_attr "op_type" "RRE,RXE")
4847 (set_attr "type" "fsimp<BFP:mode>, fload<BFP:mode>")])
4848
4849 (define_expand "extend<DSF:mode><BFP:mode>2"
4850 [(set (match_operand:BFP 0 "register_operand" "")
4851 (float_extend:BFP (match_operand:DSF 1 "nonimmediate_operand" "")))]
4852 "TARGET_HARD_FLOAT
4853 && GET_MODE_SIZE (<BFP:MODE>mode) > GET_MODE_SIZE (<DSF:MODE>mode)")
4854
4855 ;
4856 ; extendddtd2 and extendsddd2 instruction pattern(s).
4857 ;
4858
4859 (define_insn "extendddtd2"
4860 [(set (match_operand:TD 0 "register_operand" "=f")
4861 (float_extend:TD (match_operand:DD 1 "register_operand" "f")))]
4862 "TARGET_HARD_DFP"
4863 "lxdtr\t%0,%1,0"
4864 [(set_attr "op_type" "RRF")
4865 (set_attr "type" "fsimptf")])
4866
4867 (define_insn "extendsddd2"
4868 [(set (match_operand:DD 0 "register_operand" "=f")
4869 (float_extend:DD (match_operand:SD 1 "register_operand" "f")))]
4870 "TARGET_HARD_DFP"
4871 "ldetr\t%0,%1,0"
4872 [(set_attr "op_type" "RRF")
4873 (set_attr "type" "fsimptf")])
4874
4875 (define_expand "extendsdtd2"
4876 [(set (match_dup 2)
4877 (float_extend:DD (match_operand:SD 1 "register_operand" "")))
4878 (set (match_operand:TD 0 "register_operand" "")
4879 (float_extend:TD (match_dup 2)))]
4880 "TARGET_HARD_DFP"
4881 {
4882 operands[2] = gen_reg_rtx (DDmode);
4883 })
4884
4885 ; Binary Floating Point - load fp integer
4886
4887 ; Expanders for: floor, btrunc, round, ceil, and nearbyint
4888 ; For all of them the inexact exceptions are suppressed.
4889
4890 ; fiebra, fidbra, fixbra
4891 (define_insn "<FPINT:fpint_name><BFP:mode>2"
4892 [(set (match_operand:BFP 0 "register_operand" "=f")
4893 (unspec:BFP [(match_operand:BFP 1 "register_operand" "f")]
4894 FPINT))]
4895 "TARGET_Z196"
4896 "fi<BFP:xde>bra\t%0,<FPINT:fpint_roundingmode>,%1,4"
4897 [(set_attr "op_type" "RRF")
4898 (set_attr "type" "fsimp<BFP:mode>")])
4899
4900 ; rint is supposed to raise an inexact exception so we can use the
4901 ; older instructions.
4902
4903 ; fiebr, fidbr, fixbr
4904 (define_insn "rint<BFP:mode>2"
4905 [(set (match_operand:BFP 0 "register_operand" "=f")
4906 (unspec:BFP [(match_operand:BFP 1 "register_operand" "f")]
4907 UNSPEC_FPINT_RINT))]
4908 ""
4909 "fi<BFP:xde>br\t%0,0,%1"
4910 [(set_attr "op_type" "RRF")
4911 (set_attr "type" "fsimp<BFP:mode>")])
4912
4913
4914 ; Decimal Floating Point - load fp integer
4915
4916 ; fidtr, fixtr
4917 (define_insn "<FPINT:fpint_name><DFP:mode>2"
4918 [(set (match_operand:DFP 0 "register_operand" "=f")
4919 (unspec:DFP [(match_operand:DFP 1 "register_operand" "f")]
4920 FPINT))]
4921 "TARGET_HARD_DFP"
4922 "fi<DFP:xde>tr\t%0,<FPINT:fpint_roundingmode>,%1,4"
4923 [(set_attr "op_type" "RRF")
4924 (set_attr "type" "fsimp<DFP:mode>")])
4925
4926 ; fidtr, fixtr
4927 (define_insn "rint<DFP:mode>2"
4928 [(set (match_operand:DFP 0 "register_operand" "=f")
4929 (unspec:DFP [(match_operand:DFP 1 "register_operand" "f")]
4930 UNSPEC_FPINT_RINT))]
4931 "TARGET_HARD_DFP"
4932 "fi<DFP:xde>tr\t%0,0,%1,0"
4933 [(set_attr "op_type" "RRF")
4934 (set_attr "type" "fsimp<DFP:mode>")])
4935
4936 ;
4937 ; Binary <-> Decimal floating point trunc patterns
4938 ;
4939
4940 (define_insn "*trunc<BFP:mode><DFP_ALL:mode>2"
4941 [(set (reg:DFP_ALL FPR0_REGNUM)
4942 (float_truncate:DFP_ALL (reg:BFP FPR4_REGNUM)))
4943 (use (reg:SI GPR0_REGNUM))
4944 (clobber (reg:CC CC_REGNUM))
4945 (clobber (reg:SI GPR1_REGNUM))]
4946 "TARGET_HARD_DFP"
4947 "pfpo")
4948
4949 (define_insn "*trunc<DFP_ALL:mode><BFP:mode>2"
4950 [(set (reg:BFP FPR0_REGNUM)
4951 (float_truncate:BFP (reg:DFP_ALL FPR4_REGNUM)))
4952 (use (reg:SI GPR0_REGNUM))
4953 (clobber (reg:CC CC_REGNUM))
4954 (clobber (reg:SI GPR1_REGNUM))]
4955 "TARGET_HARD_DFP"
4956 "pfpo")
4957
4958 (define_expand "trunc<BFP:mode><DFP_ALL:mode>2"
4959 [(set (reg:BFP FPR4_REGNUM) (match_operand:BFP 1 "nonimmediate_operand" ""))
4960 (set (reg:SI GPR0_REGNUM) (match_dup 2))
4961 (parallel
4962 [(set (reg:DFP_ALL FPR0_REGNUM)
4963 (float_truncate:DFP_ALL (reg:BFP FPR4_REGNUM)))
4964 (use (reg:SI GPR0_REGNUM))
4965 (clobber (reg:CC CC_REGNUM))
4966 (clobber (reg:SI GPR1_REGNUM))])
4967 (set (match_operand:DFP_ALL 0 "nonimmediate_operand" "")
4968 (reg:DFP_ALL FPR0_REGNUM))]
4969 "TARGET_HARD_DFP
4970 && GET_MODE_SIZE (<BFP:MODE>mode) > GET_MODE_SIZE (<DFP_ALL:MODE>mode)"
4971 {
4972 HOST_WIDE_INT flags;
4973
4974 flags = (PFPO_CONVERT |
4975 PFPO_OP_TYPE_<DFP_ALL:MODE> << PFPO_OP0_TYPE_SHIFT |
4976 PFPO_OP_TYPE_<BFP:MODE> << PFPO_OP1_TYPE_SHIFT);
4977
4978 operands[2] = GEN_INT (flags);
4979 })
4980
4981 (define_expand "trunc<DFP_ALL:mode><BFP:mode>2"
4982 [(set (reg:DFP_ALL FPR4_REGNUM)
4983 (match_operand:DFP_ALL 1 "nonimmediate_operand" ""))
4984 (set (reg:SI GPR0_REGNUM) (match_dup 2))
4985 (parallel
4986 [(set (reg:BFP FPR0_REGNUM) (float_truncate:BFP (reg:DFP_ALL FPR4_REGNUM)))
4987 (use (reg:SI GPR0_REGNUM))
4988 (clobber (reg:CC CC_REGNUM))
4989 (clobber (reg:SI GPR1_REGNUM))])
4990 (set (match_operand:BFP 0 "nonimmediate_operand" "") (reg:BFP FPR0_REGNUM))]
4991 "TARGET_HARD_DFP
4992 && GET_MODE_SIZE (<DFP_ALL:MODE>mode) >= GET_MODE_SIZE (<BFP:MODE>mode)"
4993 {
4994 HOST_WIDE_INT flags;
4995
4996 flags = (PFPO_CONVERT |
4997 PFPO_OP_TYPE_<BFP:MODE> << PFPO_OP0_TYPE_SHIFT |
4998 PFPO_OP_TYPE_<DFP_ALL:MODE> << PFPO_OP1_TYPE_SHIFT);
4999
5000 operands[2] = GEN_INT (flags);
5001 })
5002
5003 ;
5004 ; Binary <-> Decimal floating point extend patterns
5005 ;
5006
5007 (define_insn "*extend<BFP:mode><DFP_ALL:mode>2"
5008 [(set (reg:DFP_ALL FPR0_REGNUM) (float_extend:DFP_ALL (reg:BFP FPR4_REGNUM)))
5009 (use (reg:SI GPR0_REGNUM))
5010 (clobber (reg:CC CC_REGNUM))
5011 (clobber (reg:SI GPR1_REGNUM))]
5012 "TARGET_HARD_DFP"
5013 "pfpo")
5014
5015 (define_insn "*extend<DFP_ALL:mode><BFP:mode>2"
5016 [(set (reg:BFP FPR0_REGNUM) (float_extend:BFP (reg:DFP_ALL FPR4_REGNUM)))
5017 (use (reg:SI GPR0_REGNUM))
5018 (clobber (reg:CC CC_REGNUM))
5019 (clobber (reg:SI GPR1_REGNUM))]
5020 "TARGET_HARD_DFP"
5021 "pfpo")
5022
5023 (define_expand "extend<BFP:mode><DFP_ALL:mode>2"
5024 [(set (reg:BFP FPR4_REGNUM) (match_operand:BFP 1 "nonimmediate_operand" ""))
5025 (set (reg:SI GPR0_REGNUM) (match_dup 2))
5026 (parallel
5027 [(set (reg:DFP_ALL FPR0_REGNUM)
5028 (float_extend:DFP_ALL (reg:BFP FPR4_REGNUM)))
5029 (use (reg:SI GPR0_REGNUM))
5030 (clobber (reg:CC CC_REGNUM))
5031 (clobber (reg:SI GPR1_REGNUM))])
5032 (set (match_operand:DFP_ALL 0 "nonimmediate_operand" "")
5033 (reg:DFP_ALL FPR0_REGNUM))]
5034 "TARGET_HARD_DFP
5035 && GET_MODE_SIZE (<BFP:MODE>mode) <= GET_MODE_SIZE (<DFP_ALL:MODE>mode)"
5036 {
5037 HOST_WIDE_INT flags;
5038
5039 flags = (PFPO_CONVERT |
5040 PFPO_OP_TYPE_<DFP_ALL:MODE> << PFPO_OP0_TYPE_SHIFT |
5041 PFPO_OP_TYPE_<BFP:MODE> << PFPO_OP1_TYPE_SHIFT);
5042
5043 operands[2] = GEN_INT (flags);
5044 })
5045
5046 (define_expand "extend<DFP_ALL:mode><BFP:mode>2"
5047 [(set (reg:DFP_ALL FPR4_REGNUM)
5048 (match_operand:DFP_ALL 1 "nonimmediate_operand" ""))
5049 (set (reg:SI GPR0_REGNUM) (match_dup 2))
5050 (parallel
5051 [(set (reg:BFP FPR0_REGNUM) (float_extend:BFP (reg:DFP_ALL FPR4_REGNUM)))
5052 (use (reg:SI GPR0_REGNUM))
5053 (clobber (reg:CC CC_REGNUM))
5054 (clobber (reg:SI GPR1_REGNUM))])
5055 (set (match_operand:BFP 0 "nonimmediate_operand" "") (reg:BFP FPR0_REGNUM))]
5056 "TARGET_HARD_DFP
5057 && GET_MODE_SIZE (<DFP_ALL:MODE>mode) < GET_MODE_SIZE (<BFP:MODE>mode)"
5058 {
5059 HOST_WIDE_INT flags;
5060
5061 flags = (PFPO_CONVERT |
5062 PFPO_OP_TYPE_<BFP:MODE> << PFPO_OP0_TYPE_SHIFT |
5063 PFPO_OP_TYPE_<DFP_ALL:MODE> << PFPO_OP1_TYPE_SHIFT);
5064
5065 operands[2] = GEN_INT (flags);
5066 })
5067
5068
5069 ;;
5070 ;; ARITHMETIC OPERATIONS
5071 ;;
5072 ; arithmetic operations set the ConditionCode,
5073 ; because of unpredictable Bits in Register for Halfword and Byte
5074 ; the ConditionCode can be set wrong in operations for Halfword and Byte
5075
5076 ;;
5077 ;;- Add instructions.
5078 ;;
5079
5080 ;
5081 ; addti3 instruction pattern(s).
5082 ;
5083
5084 (define_expand "addti3"
5085 [(parallel
5086 [(set (match_operand:TI 0 "register_operand" "")
5087 (plus:TI (match_operand:TI 1 "nonimmediate_operand" "")
5088 (match_operand:TI 2 "general_operand" "") ) )
5089 (clobber (reg:CC CC_REGNUM))])]
5090 "TARGET_ZARCH"
5091 {
5092 /* For z13 we have vaq which doesn't set CC. */
5093 if (TARGET_VX)
5094 {
5095 emit_insn (gen_rtx_SET (operands[0],
5096 gen_rtx_PLUS (TImode,
5097 copy_to_mode_reg (TImode, operands[1]),
5098 copy_to_mode_reg (TImode, operands[2]))));
5099 DONE;
5100 }
5101 })
5102
5103 (define_insn_and_split "*addti3"
5104 [(set (match_operand:TI 0 "register_operand" "=&d")
5105 (plus:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
5106 (match_operand:TI 2 "general_operand" "do") ) )
5107 (clobber (reg:CC CC_REGNUM))]
5108 "TARGET_ZARCH"
5109 "#"
5110 "&& reload_completed"
5111 [(parallel
5112 [(set (reg:CCL1 CC_REGNUM)
5113 (compare:CCL1 (plus:DI (match_dup 7) (match_dup 8))
5114 (match_dup 7)))
5115 (set (match_dup 6) (plus:DI (match_dup 7) (match_dup 8)))])
5116 (parallel
5117 [(set (match_dup 3) (plus:DI
5118 (plus:DI (ltu:DI (reg:CCL1 CC_REGNUM) (const_int 0))
5119 (match_dup 4)) (match_dup 5)))
5120 (clobber (reg:CC CC_REGNUM))])]
5121 "operands[3] = operand_subword (operands[0], 0, 0, TImode);
5122 operands[4] = operand_subword (operands[1], 0, 0, TImode);
5123 operands[5] = operand_subword (operands[2], 0, 0, TImode);
5124 operands[6] = operand_subword (operands[0], 1, 0, TImode);
5125 operands[7] = operand_subword (operands[1], 1, 0, TImode);
5126 operands[8] = operand_subword (operands[2], 1, 0, TImode);"
5127 [(set_attr "op_type" "*")
5128 (set_attr "cpu_facility" "*")])
5129
5130 ;
5131 ; adddi3 instruction pattern(s).
5132 ;
5133
5134 (define_expand "adddi3"
5135 [(parallel
5136 [(set (match_operand:DI 0 "nonimmediate_operand" "")
5137 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
5138 (match_operand:DI 2 "general_operand" "")))
5139 (clobber (reg:CC CC_REGNUM))])]
5140 ""
5141 "")
5142
5143 (define_insn "*adddi3_sign"
5144 [(set (match_operand:DI 0 "register_operand" "=d,d")
5145 (plus:DI (sign_extend:DI (match_operand:SI 2 "general_operand" "d,RT"))
5146 (match_operand:DI 1 "register_operand" "0,0")))
5147 (clobber (reg:CC CC_REGNUM))]
5148 "TARGET_ZARCH"
5149 "@
5150 agfr\t%0,%2
5151 agf\t%0,%2"
5152 [(set_attr "op_type" "RRE,RXY")
5153 (set_attr "z196prop" "z196_cracked,z196_cracked")])
5154
5155 (define_insn "*adddi3_zero_cc"
5156 [(set (reg CC_REGNUM)
5157 (compare (plus:DI (zero_extend:DI (match_operand:SI 2 "general_operand" "d,RT"))
5158 (match_operand:DI 1 "register_operand" "0,0"))
5159 (const_int 0)))
5160 (set (match_operand:DI 0 "register_operand" "=d,d")
5161 (plus:DI (zero_extend:DI (match_dup 2)) (match_dup 1)))]
5162 "s390_match_ccmode (insn, CCLmode) && TARGET_ZARCH"
5163 "@
5164 algfr\t%0,%2
5165 algf\t%0,%2"
5166 [(set_attr "op_type" "RRE,RXY")
5167 (set_attr "z10prop" "z10_super_E1,z10_super_E1")])
5168
5169 (define_insn "*adddi3_zero_cconly"
5170 [(set (reg CC_REGNUM)
5171 (compare (plus:DI (zero_extend:DI (match_operand:SI 2 "general_operand" "d,RT"))
5172 (match_operand:DI 1 "register_operand" "0,0"))
5173 (const_int 0)))
5174 (clobber (match_scratch:DI 0 "=d,d"))]
5175 "s390_match_ccmode (insn, CCLmode) && TARGET_ZARCH"
5176 "@
5177 algfr\t%0,%2
5178 algf\t%0,%2"
5179 [(set_attr "op_type" "RRE,RXY")
5180 (set_attr "z10prop" "z10_super_E1,z10_super_E1")])
5181
5182 (define_insn "*adddi3_zero"
5183 [(set (match_operand:DI 0 "register_operand" "=d,d")
5184 (plus:DI (zero_extend:DI (match_operand:SI 2 "general_operand" "d,RT"))
5185 (match_operand:DI 1 "register_operand" "0,0")))
5186 (clobber (reg:CC CC_REGNUM))]
5187 "TARGET_ZARCH"
5188 "@
5189 algfr\t%0,%2
5190 algf\t%0,%2"
5191 [(set_attr "op_type" "RRE,RXY")
5192 (set_attr "z10prop" "z10_super_E1,z10_super_E1")])
5193
5194 (define_insn_and_split "*adddi3_31z"
5195 [(set (match_operand:DI 0 "nonimmediate_operand" "=&d")
5196 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
5197 (match_operand:DI 2 "general_operand" "do") ) )
5198 (clobber (reg:CC CC_REGNUM))]
5199 "!TARGET_ZARCH && TARGET_CPU_ZARCH"
5200 "#"
5201 "&& reload_completed"
5202 [(parallel
5203 [(set (reg:CCL1 CC_REGNUM)
5204 (compare:CCL1 (plus:SI (match_dup 7) (match_dup 8))
5205 (match_dup 7)))
5206 (set (match_dup 6) (plus:SI (match_dup 7) (match_dup 8)))])
5207 (parallel
5208 [(set (match_dup 3) (plus:SI
5209 (plus:SI (ltu:SI (reg:CCL1 CC_REGNUM) (const_int 0))
5210 (match_dup 4)) (match_dup 5)))
5211 (clobber (reg:CC CC_REGNUM))])]
5212 "operands[3] = operand_subword (operands[0], 0, 0, DImode);
5213 operands[4] = operand_subword (operands[1], 0, 0, DImode);
5214 operands[5] = operand_subword (operands[2], 0, 0, DImode);
5215 operands[6] = operand_subword (operands[0], 1, 0, DImode);
5216 operands[7] = operand_subword (operands[1], 1, 0, DImode);
5217 operands[8] = operand_subword (operands[2], 1, 0, DImode);")
5218
5219 (define_insn_and_split "*adddi3_31"
5220 [(set (match_operand:DI 0 "nonimmediate_operand" "=&d")
5221 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
5222 (match_operand:DI 2 "general_operand" "do") ) )
5223 (clobber (reg:CC CC_REGNUM))]
5224 "!TARGET_CPU_ZARCH"
5225 "#"
5226 "&& reload_completed"
5227 [(parallel
5228 [(set (match_dup 3) (plus:SI (match_dup 4) (match_dup 5)))
5229 (clobber (reg:CC CC_REGNUM))])
5230 (parallel
5231 [(set (reg:CCL1 CC_REGNUM)
5232 (compare:CCL1 (plus:SI (match_dup 7) (match_dup 8))
5233 (match_dup 7)))
5234 (set (match_dup 6) (plus:SI (match_dup 7) (match_dup 8)))])
5235 (set (pc)
5236 (if_then_else (ltu (reg:CCL1 CC_REGNUM) (const_int 0))
5237 (pc)
5238 (label_ref (match_dup 9))))
5239 (parallel
5240 [(set (match_dup 3) (plus:SI (match_dup 3) (const_int 1)))
5241 (clobber (reg:CC CC_REGNUM))])
5242 (match_dup 9)]
5243 "operands[3] = operand_subword (operands[0], 0, 0, DImode);
5244 operands[4] = operand_subword (operands[1], 0, 0, DImode);
5245 operands[5] = operand_subword (operands[2], 0, 0, DImode);
5246 operands[6] = operand_subword (operands[0], 1, 0, DImode);
5247 operands[7] = operand_subword (operands[1], 1, 0, DImode);
5248 operands[8] = operand_subword (operands[2], 1, 0, DImode);
5249 operands[9] = gen_label_rtx ();")
5250
5251 ;
5252 ; addsi3 instruction pattern(s).
5253 ;
5254
5255 (define_expand "addsi3"
5256 [(parallel
5257 [(set (match_operand:SI 0 "nonimmediate_operand" "")
5258 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "")
5259 (match_operand:SI 2 "general_operand" "")))
5260 (clobber (reg:CC CC_REGNUM))])]
5261 ""
5262 "")
5263
5264 (define_insn "*addsi3_sign"
5265 [(set (match_operand:SI 0 "register_operand" "=d,d")
5266 (plus:SI (sign_extend:SI (match_operand:HI 2 "memory_operand" "R,T"))
5267 (match_operand:SI 1 "register_operand" "0,0")))
5268 (clobber (reg:CC CC_REGNUM))]
5269 ""
5270 "@
5271 ah\t%0,%2
5272 ahy\t%0,%2"
5273 [(set_attr "op_type" "RX,RXY")
5274 (set_attr "z196prop" "z196_cracked,z196_cracked")])
5275
5276 ;
5277 ; add(di|si)3 instruction pattern(s).
5278 ;
5279
5280 ; ark, agrk, ar, ahi, ahik, aghik, alfi, slfi, a, ay, agr, aghi, algfi, slgfi, ag, asi, agsi
5281 (define_insn "*add<mode>3"
5282 [(set (match_operand:GPR 0 "nonimmediate_operand" "=d,d,d,d, d, d,d,d,QS")
5283 (plus:GPR (match_operand:GPR 1 "nonimmediate_operand" "%0,d,0,d, 0, 0,0,0, 0")
5284 (match_operand:GPR 2 "general_operand" " d,d,K,K,Op,On,R,T, C") ) )
5285 (clobber (reg:CC CC_REGNUM))]
5286 ""
5287 "@
5288 a<g>r\t%0,%2
5289 a<g>rk\t%0,%1,%2
5290 a<g>hi\t%0,%h2
5291 a<g>hik\t%0,%1,%h2
5292 al<g>fi\t%0,%2
5293 sl<g>fi\t%0,%n2
5294 a<g>\t%0,%2
5295 a<y>\t%0,%2
5296 a<g>si\t%0,%c2"
5297 [(set_attr "op_type" "RR<E>,RRF,RI,RIE,RIL,RIL,RX<Y>,RXY,SIY")
5298 (set_attr "cpu_facility" "*,z196,*,z196,extimm,extimm,*,*,z10")
5299 (set_attr "z10prop" "z10_super_E1,*,z10_super_E1,*,z10_super_E1,z10_super_E1,
5300 z10_super_E1,z10_super_E1,z10_super_E1")])
5301
5302 ; alr, alfi, slfi, al, aly, alrk, alhsik, algr, algfi, slgfi, alg, alsi, algsi, algrk, alghsik
5303 (define_insn "*add<mode>3_carry1_cc"
5304 [(set (reg CC_REGNUM)
5305 (compare (plus:GPR (match_operand:GPR 1 "nonimmediate_operand" "%0,d, 0, 0,d,0,0,0")
5306 (match_operand:GPR 2 "general_operand" " d,d,Op,On,K,R,T,C"))
5307 (match_dup 1)))
5308 (set (match_operand:GPR 0 "nonimmediate_operand" "=d,d, d, d,d,d,d,d")
5309 (plus:GPR (match_dup 1) (match_dup 2)))]
5310 "s390_match_ccmode (insn, CCL1mode)"
5311 "@
5312 al<g>r\t%0,%2
5313 al<g>rk\t%0,%1,%2
5314 al<g>fi\t%0,%2
5315 sl<g>fi\t%0,%n2
5316 al<g>hsik\t%0,%1,%h2
5317 al<g>\t%0,%2
5318 al<y>\t%0,%2
5319 al<g>si\t%0,%c2"
5320 [(set_attr "op_type" "RR<E>,RRF,RIL,RIL,RIE,RX<Y>,RXY,SIY")
5321 (set_attr "cpu_facility" "*,z196,extimm,extimm,z196,*,*,z10")
5322 (set_attr "z10prop" "z10_super_E1,*,z10_super_E1,z10_super_E1,*,
5323 z10_super_E1,z10_super_E1,z10_super_E1")])
5324
5325 ; alr, al, aly, algr, alg, alrk, algrk
5326 (define_insn "*add<mode>3_carry1_cconly"
5327 [(set (reg CC_REGNUM)
5328 (compare (plus:GPR (match_operand:GPR 1 "nonimmediate_operand" "%0,d,0,0")
5329 (match_operand:GPR 2 "general_operand" "d,d,R,T"))
5330 (match_dup 1)))
5331 (clobber (match_scratch:GPR 0 "=d,d,d,d"))]
5332 "s390_match_ccmode (insn, CCL1mode)"
5333 "@
5334 al<g>r\t%0,%2
5335 al<g>rk\t%0,%1,%2
5336 al<g>\t%0,%2
5337 al<y>\t%0,%2"
5338 [(set_attr "op_type" "RR<E>,RRF,RX<Y>,RXY")
5339 (set_attr "cpu_facility" "*,z196,*,*")
5340 (set_attr "z10prop" "z10_super_E1,*,z10_super_E1,z10_super_E1")])
5341
5342 ; alr, alfi, slfi, al, aly, algr, algfi, slgfi, alg, alsi, algsi, alrk, algrk, alhsik, alghsik
5343 (define_insn "*add<mode>3_carry2_cc"
5344 [(set (reg CC_REGNUM)
5345 (compare (plus:GPR (match_operand:GPR 1 "nonimmediate_operand" "%0,d, 0, 0,d,0,0, 0")
5346 (match_operand:GPR 2 "general_operand" " d,d,Op,On,K,R,T, C"))
5347 (match_dup 2)))
5348 (set (match_operand:GPR 0 "nonimmediate_operand" "=d,d, d, d,d,d,d,RS")
5349 (plus:GPR (match_dup 1) (match_dup 2)))]
5350 "s390_match_ccmode (insn, CCL1mode)"
5351 "@
5352 al<g>r\t%0,%2
5353 al<g>rk\t%0,%1,%2
5354 al<g>fi\t%0,%2
5355 sl<g>fi\t%0,%n2
5356 al<g>hsik\t%0,%1,%h2
5357 al<g>\t%0,%2
5358 al<y>\t%0,%2
5359 al<g>si\t%0,%c2"
5360 [(set_attr "op_type" "RR<E>,RRF,RIL,RIL,RIE,RX<Y>,RXY,SIY")
5361 (set_attr "cpu_facility" "*,z196,extimm,extimm,z196,*,*,z10")
5362 (set_attr "z10prop" "z10_super_E1,*,z10_super_E1,z10_super_E1,*,
5363 z10_super_E1,z10_super_E1,z10_super_E1")])
5364
5365 ; alr, al, aly, algr, alg, alrk, algrk
5366 (define_insn "*add<mode>3_carry2_cconly"
5367 [(set (reg CC_REGNUM)
5368 (compare (plus:GPR (match_operand:GPR 1 "nonimmediate_operand" "%0,d,0,0")
5369 (match_operand:GPR 2 "general_operand" "d,d,R,T"))
5370 (match_dup 2)))
5371 (clobber (match_scratch:GPR 0 "=d,d,d,d"))]
5372 "s390_match_ccmode (insn, CCL1mode)"
5373 "@
5374 al<g>r\t%0,%2
5375 al<g>rk\t%0,%1,%2
5376 al<g>\t%0,%2
5377 al<y>\t%0,%2"
5378 [(set_attr "op_type" "RR<E>,RRF,RX<Y>,RXY")
5379 (set_attr "cpu_facility" "*,z196,*,*")
5380 (set_attr "z10prop" "z10_super_E1,*,z10_super_E1,z10_super_E1")])
5381
5382 ; alr, alfi, slfi, al, aly, algr, algfi, slgfi, alg, alsi, algsi, alrk, algrk, alhsik, alghsik
5383 (define_insn "*add<mode>3_cc"
5384 [(set (reg CC_REGNUM)
5385 (compare (plus:GPR (match_operand:GPR 1 "nonimmediate_operand" "%0,d, 0, 0,d,0,0, 0")
5386 (match_operand:GPR 2 "general_operand" " d,d,Op,On,K,R,T, C"))
5387 (const_int 0)))
5388 (set (match_operand:GPR 0 "nonimmediate_operand" "=d,d, d, d,d,d,d,RS")
5389 (plus:GPR (match_dup 1) (match_dup 2)))]
5390 "s390_match_ccmode (insn, CCLmode)"
5391 "@
5392 al<g>r\t%0,%2
5393 al<g>rk\t%0,%1,%2
5394 al<g>fi\t%0,%2
5395 sl<g>fi\t%0,%n2
5396 al<g>hsik\t%0,%1,%h2
5397 al<g>\t%0,%2
5398 al<y>\t%0,%2
5399 al<g>si\t%0,%c2"
5400 [(set_attr "op_type" "RR<E>,RRF,RIL,RIL,RIE,RX<Y>,RXY,SIY")
5401 (set_attr "cpu_facility" "*,z196,extimm,extimm,z196,*,*,z10")
5402 (set_attr "z10prop" "z10_super_E1,*,z10_super_E1,z10_super_E1,
5403 *,z10_super_E1,z10_super_E1,z10_super_E1")])
5404
5405 ; alr, al, aly, algr, alg, alrk, algrk
5406 (define_insn "*add<mode>3_cconly"
5407 [(set (reg CC_REGNUM)
5408 (compare (plus:GPR (match_operand:GPR 1 "nonimmediate_operand" "%0,d,0,0")
5409 (match_operand:GPR 2 "general_operand" "d,d,R,T"))
5410 (const_int 0)))
5411 (clobber (match_scratch:GPR 0 "=d,d,d,d"))]
5412 "s390_match_ccmode (insn, CCLmode)"
5413 "@
5414 al<g>r\t%0,%2
5415 al<g>rk\t%0,%1,%2
5416 al<g>\t%0,%2
5417 al<y>\t%0,%2"
5418 [(set_attr "op_type" "RR<E>,RRF,RX<Y>,RXY")
5419 (set_attr "cpu_facility" "*,z196,*,*")
5420 (set_attr "z10prop" "z10_super_E1,*,z10_super_E1,z10_super_E1")])
5421
5422 ; alr, al, aly, algr, alg, alrk, algrk
5423 (define_insn "*add<mode>3_cconly2"
5424 [(set (reg CC_REGNUM)
5425 (compare (match_operand:GPR 1 "nonimmediate_operand" "%0,d,0,0")
5426 (neg:GPR (match_operand:GPR 2 "general_operand" "d,d,R,T"))))
5427 (clobber (match_scratch:GPR 0 "=d,d,d,d"))]
5428 "s390_match_ccmode(insn, CCLmode)"
5429 "@
5430 al<g>r\t%0,%2
5431 al<g>rk\t%0,%1,%2
5432 al<g>\t%0,%2
5433 al<y>\t%0,%2"
5434 [(set_attr "op_type" "RR<E>,RRF,RX<Y>,RXY")
5435 (set_attr "cpu_facility" "*,z196,*,*")
5436 (set_attr "z10prop" "z10_super_E1,*,z10_super_E1,z10_super_E1")])
5437
5438 ; ahi, afi, aghi, agfi, asi, agsi
5439 (define_insn "*add<mode>3_imm_cc"
5440 [(set (reg CC_REGNUM)
5441 (compare (plus:GPR (match_operand:GPR 1 "nonimmediate_operand" " 0, d,0, 0")
5442 (match_operand:GPR 2 "const_int_operand" " K, K,Os, C"))
5443 (const_int 0)))
5444 (set (match_operand:GPR 0 "nonimmediate_operand" "=d, d,d,QS")
5445 (plus:GPR (match_dup 1) (match_dup 2)))]
5446 "s390_match_ccmode (insn, CCAmode)
5447 && (CONST_OK_FOR_CONSTRAINT_P (INTVAL (operands[2]), 'K', \"K\")
5448 || (CONST_OK_FOR_CONSTRAINT_P (INTVAL (operands[2]), 'O', \"Os\")
5449 /* Avoid INT32_MIN on 32 bit. */
5450 && (!TARGET_ZARCH || INTVAL (operands[2]) != -0x7fffffff - 1)))"
5451 "@
5452 a<g>hi\t%0,%h2
5453 a<g>hik\t%0,%1,%h2
5454 a<g>fi\t%0,%2
5455 a<g>si\t%0,%c2"
5456 [(set_attr "op_type" "RI,RIE,RIL,SIY")
5457 (set_attr "cpu_facility" "*,z196,extimm,z10")
5458 (set_attr "z10prop" "z10_super_E1,*,z10_super_E1,z10_super_E1")])
5459
5460 ;
5461 ; add(tf|df|sf|td|dd)3 instruction pattern(s).
5462 ;
5463
5464 ; axbr, adbr, aebr, axb, adb, aeb, adtr, axtr
5465 ; FIXME: wfadb does not clobber cc
5466 (define_insn "add<mode>3"
5467 [(set (match_operand:FP 0 "register_operand" "=f, f,<vf>")
5468 (plus:FP (match_operand:FP 1 "nonimmediate_operand" "%<f0>, 0,<v0>")
5469 (match_operand:FP 2 "general_operand" "f,<Rf>,<vf>")))
5470 (clobber (reg:CC CC_REGNUM))]
5471 "TARGET_HARD_FLOAT"
5472 "@
5473 a<xde><bt>r\t%0,<op1>%2
5474 a<xde>b\t%0,%2
5475 wfadb\t%v0,%v1,%v2"
5476 [(set_attr "op_type" "<RRer>,RXE,VRR")
5477 (set_attr "type" "fsimp<mode>")
5478 (set_attr "cpu_facility" "*,*,vec")])
5479
5480 ; axbr, adbr, aebr, axb, adb, aeb, adtr, axtr
5481 (define_insn "*add<mode>3_cc"
5482 [(set (reg CC_REGNUM)
5483 (compare (plus:FP (match_operand:FP 1 "nonimmediate_operand" "%<f0>,0")
5484 (match_operand:FP 2 "general_operand" " f,<Rf>"))
5485 (match_operand:FP 3 "const0_operand" "")))
5486 (set (match_operand:FP 0 "register_operand" "=f,f")
5487 (plus:FP (match_dup 1) (match_dup 2)))]
5488 "s390_match_ccmode (insn, CCSmode) && TARGET_HARD_FLOAT"
5489 "@
5490 a<xde><bt>r\t%0,<op1>%2
5491 a<xde>b\t%0,%2"
5492 [(set_attr "op_type" "<RRer>,RXE")
5493 (set_attr "type" "fsimp<mode>")])
5494
5495 ; axbr, adbr, aebr, axb, adb, aeb, adtr, axtr
5496 (define_insn "*add<mode>3_cconly"
5497 [(set (reg CC_REGNUM)
5498 (compare (plus:FP (match_operand:FP 1 "nonimmediate_operand" "%<f0>,0")
5499 (match_operand:FP 2 "general_operand" " f,<Rf>"))
5500 (match_operand:FP 3 "const0_operand" "")))
5501 (clobber (match_scratch:FP 0 "=f,f"))]
5502 "s390_match_ccmode (insn, CCSmode) && TARGET_HARD_FLOAT"
5503 "@
5504 a<xde><bt>r\t%0,<op1>%2
5505 a<xde>b\t%0,%2"
5506 [(set_attr "op_type" "<RRer>,RXE")
5507 (set_attr "type" "fsimp<mode>")])
5508
5509 ;
5510 ; Pointer add instruction patterns
5511 ;
5512
5513 ; This will match "*la_64"
5514 (define_expand "addptrdi3"
5515 [(set (match_operand:DI 0 "register_operand" "")
5516 (plus:DI (match_operand:DI 1 "register_operand" "")
5517 (match_operand:DI 2 "nonmemory_operand" "")))]
5518 "TARGET_64BIT"
5519 {
5520 if (GET_CODE (operands[2]) == CONST_INT)
5521 {
5522 HOST_WIDE_INT c = INTVAL (operands[2]);
5523
5524 if (!CONST_OK_FOR_CONSTRAINT_P (c, 'K', "K")
5525 && !CONST_OK_FOR_CONSTRAINT_P (c, 'O', "Os"))
5526 {
5527 operands[2] = force_const_mem (DImode, operands[2]);
5528 operands[2] = force_reg (DImode, operands[2]);
5529 }
5530 else if (!DISP_IN_RANGE (INTVAL (operands[2])))
5531 operands[2] = force_reg (DImode, operands[2]);
5532 }
5533 })
5534
5535 ; For 31 bit we have to prevent the generated pattern from matching
5536 ; normal ADDs since la only does a 31 bit add. This is supposed to
5537 ; match "force_la_31".
5538 (define_expand "addptrsi3"
5539 [(parallel
5540 [(set (match_operand:SI 0 "register_operand" "")
5541 (plus:SI (match_operand:SI 1 "register_operand" "")
5542 (match_operand:SI 2 "nonmemory_operand" "")))
5543 (use (const_int 0))])]
5544 "!TARGET_64BIT"
5545 {
5546 if (GET_CODE (operands[2]) == CONST_INT)
5547 {
5548 HOST_WIDE_INT c = INTVAL (operands[2]);
5549
5550 if (!CONST_OK_FOR_CONSTRAINT_P (c, 'K', "K")
5551 && !CONST_OK_FOR_CONSTRAINT_P (c, 'O', "Os"))
5552 {
5553 operands[2] = force_const_mem (SImode, operands[2]);
5554 operands[2] = force_reg (SImode, operands[2]);
5555 }
5556 else if (!DISP_IN_RANGE (INTVAL (operands[2])))
5557 operands[2] = force_reg (SImode, operands[2]);
5558 }
5559 })
5560
5561 ;;
5562 ;;- Subtract instructions.
5563 ;;
5564
5565 ;
5566 ; subti3 instruction pattern(s).
5567 ;
5568
5569 (define_expand "subti3"
5570 [(parallel
5571 [(set (match_operand:TI 0 "register_operand" "")
5572 (minus:TI (match_operand:TI 1 "register_operand" "")
5573 (match_operand:TI 2 "general_operand" "") ) )
5574 (clobber (reg:CC CC_REGNUM))])]
5575 "TARGET_ZARCH"
5576 {
5577 /* For z13 we have vaq which doesn't set CC. */
5578 if (TARGET_VX)
5579 {
5580 emit_insn (gen_rtx_SET (operands[0],
5581 gen_rtx_MINUS (TImode,
5582 operands[1],
5583 copy_to_mode_reg (TImode, operands[2]))));
5584 DONE;
5585 }
5586 })
5587
5588 (define_insn_and_split "*subti3"
5589 [(set (match_operand:TI 0 "register_operand" "=&d")
5590 (minus:TI (match_operand:TI 1 "register_operand" "0")
5591 (match_operand:TI 2 "general_operand" "do") ) )
5592 (clobber (reg:CC CC_REGNUM))]
5593 "TARGET_ZARCH"
5594 "#"
5595 "&& reload_completed"
5596 [(parallel
5597 [(set (reg:CCL2 CC_REGNUM)
5598 (compare:CCL2 (minus:DI (match_dup 7) (match_dup 8))
5599 (match_dup 7)))
5600 (set (match_dup 6) (minus:DI (match_dup 7) (match_dup 8)))])
5601 (parallel
5602 [(set (match_dup 3) (minus:DI (minus:DI (match_dup 4) (match_dup 5))
5603 (gtu:DI (reg:CCL2 CC_REGNUM) (const_int 0))))
5604 (clobber (reg:CC CC_REGNUM))])]
5605 "operands[3] = operand_subword (operands[0], 0, 0, TImode);
5606 operands[4] = operand_subword (operands[1], 0, 0, TImode);
5607 operands[5] = operand_subword (operands[2], 0, 0, TImode);
5608 operands[6] = operand_subword (operands[0], 1, 0, TImode);
5609 operands[7] = operand_subword (operands[1], 1, 0, TImode);
5610 operands[8] = operand_subword (operands[2], 1, 0, TImode);"
5611 [(set_attr "op_type" "*")
5612 (set_attr "cpu_facility" "*")])
5613
5614 ;
5615 ; subdi3 instruction pattern(s).
5616 ;
5617
5618 (define_expand "subdi3"
5619 [(parallel
5620 [(set (match_operand:DI 0 "register_operand" "")
5621 (minus:DI (match_operand:DI 1 "register_operand" "")
5622 (match_operand:DI 2 "general_operand" "")))
5623 (clobber (reg:CC CC_REGNUM))])]
5624 ""
5625 "")
5626
5627 (define_insn "*subdi3_sign"
5628 [(set (match_operand:DI 0 "register_operand" "=d,d")
5629 (minus:DI (match_operand:DI 1 "register_operand" "0,0")
5630 (sign_extend:DI (match_operand:SI 2 "general_operand" "d,RT"))))
5631 (clobber (reg:CC CC_REGNUM))]
5632 "TARGET_ZARCH"
5633 "@
5634 sgfr\t%0,%2
5635 sgf\t%0,%2"
5636 [(set_attr "op_type" "RRE,RXY")
5637 (set_attr "z10prop" "z10_c,*")
5638 (set_attr "z196prop" "z196_cracked")])
5639
5640 (define_insn "*subdi3_zero_cc"
5641 [(set (reg CC_REGNUM)
5642 (compare (minus:DI (match_operand:DI 1 "register_operand" "0,0")
5643 (zero_extend:DI (match_operand:SI 2 "general_operand" "d,RT")))
5644 (const_int 0)))
5645 (set (match_operand:DI 0 "register_operand" "=d,d")
5646 (minus:DI (match_dup 1) (zero_extend:DI (match_dup 2))))]
5647 "s390_match_ccmode (insn, CCLmode) && TARGET_ZARCH"
5648 "@
5649 slgfr\t%0,%2
5650 slgf\t%0,%2"
5651 [(set_attr "op_type" "RRE,RXY")
5652 (set_attr "z10prop" "z10_super_c_E1,z10_super_E1")])
5653
5654 (define_insn "*subdi3_zero_cconly"
5655 [(set (reg CC_REGNUM)
5656 (compare (minus:DI (match_operand:DI 1 "register_operand" "0,0")
5657 (zero_extend:DI (match_operand:SI 2 "general_operand" "d,RT")))
5658 (const_int 0)))
5659 (clobber (match_scratch:DI 0 "=d,d"))]
5660 "s390_match_ccmode (insn, CCLmode) && TARGET_ZARCH"
5661 "@
5662 slgfr\t%0,%2
5663 slgf\t%0,%2"
5664 [(set_attr "op_type" "RRE,RXY")
5665 (set_attr "z10prop" "z10_super_c_E1,z10_super_E1")])
5666
5667 (define_insn "*subdi3_zero"
5668 [(set (match_operand:DI 0 "register_operand" "=d,d")
5669 (minus:DI (match_operand:DI 1 "register_operand" "0,0")
5670 (zero_extend:DI (match_operand:SI 2 "general_operand" "d,RT"))))
5671 (clobber (reg:CC CC_REGNUM))]
5672 "TARGET_ZARCH"
5673 "@
5674 slgfr\t%0,%2
5675 slgf\t%0,%2"
5676 [(set_attr "op_type" "RRE,RXY")
5677 (set_attr "z10prop" "z10_super_c_E1,z10_super_E1")])
5678
5679 (define_insn_and_split "*subdi3_31z"
5680 [(set (match_operand:DI 0 "register_operand" "=&d")
5681 (minus:DI (match_operand:DI 1 "register_operand" "0")
5682 (match_operand:DI 2 "general_operand" "do") ) )
5683 (clobber (reg:CC CC_REGNUM))]
5684 "!TARGET_ZARCH && TARGET_CPU_ZARCH"
5685 "#"
5686 "&& reload_completed"
5687 [(parallel
5688 [(set (reg:CCL2 CC_REGNUM)
5689 (compare:CCL2 (minus:SI (match_dup 7) (match_dup 8))
5690 (match_dup 7)))
5691 (set (match_dup 6) (minus:SI (match_dup 7) (match_dup 8)))])
5692 (parallel
5693 [(set (match_dup 3) (minus:SI (minus:SI (match_dup 4) (match_dup 5))
5694 (gtu:SI (reg:CCL2 CC_REGNUM) (const_int 0))))
5695 (clobber (reg:CC CC_REGNUM))])]
5696 "operands[3] = operand_subword (operands[0], 0, 0, DImode);
5697 operands[4] = operand_subword (operands[1], 0, 0, DImode);
5698 operands[5] = operand_subword (operands[2], 0, 0, DImode);
5699 operands[6] = operand_subword (operands[0], 1, 0, DImode);
5700 operands[7] = operand_subword (operands[1], 1, 0, DImode);
5701 operands[8] = operand_subword (operands[2], 1, 0, DImode);")
5702
5703 (define_insn_and_split "*subdi3_31"
5704 [(set (match_operand:DI 0 "register_operand" "=&d")
5705 (minus:DI (match_operand:DI 1 "register_operand" "0")
5706 (match_operand:DI 2 "general_operand" "do") ) )
5707 (clobber (reg:CC CC_REGNUM))]
5708 "!TARGET_CPU_ZARCH"
5709 "#"
5710 "&& reload_completed"
5711 [(parallel
5712 [(set (match_dup 3) (minus:SI (match_dup 4) (match_dup 5)))
5713 (clobber (reg:CC CC_REGNUM))])
5714 (parallel
5715 [(set (reg:CCL2 CC_REGNUM)
5716 (compare:CCL2 (minus:SI (match_dup 7) (match_dup 8))
5717 (match_dup 7)))
5718 (set (match_dup 6) (minus:SI (match_dup 7) (match_dup 8)))])
5719 (set (pc)
5720 (if_then_else (gtu (reg:CCL2 CC_REGNUM) (const_int 0))
5721 (pc)
5722 (label_ref (match_dup 9))))
5723 (parallel
5724 [(set (match_dup 3) (plus:SI (match_dup 3) (const_int -1)))
5725 (clobber (reg:CC CC_REGNUM))])
5726 (match_dup 9)]
5727 "operands[3] = operand_subword (operands[0], 0, 0, DImode);
5728 operands[4] = operand_subword (operands[1], 0, 0, DImode);
5729 operands[5] = operand_subword (operands[2], 0, 0, DImode);
5730 operands[6] = operand_subword (operands[0], 1, 0, DImode);
5731 operands[7] = operand_subword (operands[1], 1, 0, DImode);
5732 operands[8] = operand_subword (operands[2], 1, 0, DImode);
5733 operands[9] = gen_label_rtx ();")
5734
5735 ;
5736 ; subsi3 instruction pattern(s).
5737 ;
5738
5739 (define_expand "subsi3"
5740 [(parallel
5741 [(set (match_operand:SI 0 "register_operand" "")
5742 (minus:SI (match_operand:SI 1 "register_operand" "")
5743 (match_operand:SI 2 "general_operand" "")))
5744 (clobber (reg:CC CC_REGNUM))])]
5745 ""
5746 "")
5747
5748 (define_insn "*subsi3_sign"
5749 [(set (match_operand:SI 0 "register_operand" "=d,d")
5750 (minus:SI (match_operand:SI 1 "register_operand" "0,0")
5751 (sign_extend:SI (match_operand:HI 2 "memory_operand" "R,T"))))
5752 (clobber (reg:CC CC_REGNUM))]
5753 ""
5754 "@
5755 sh\t%0,%2
5756 shy\t%0,%2"
5757 [(set_attr "op_type" "RX,RXY")
5758 (set_attr "z196prop" "z196_cracked,z196_cracked")])
5759
5760 ;
5761 ; sub(di|si)3 instruction pattern(s).
5762 ;
5763
5764 ; sr, s, sy, sgr, sg, srk, sgrk
5765 (define_insn "*sub<mode>3"
5766 [(set (match_operand:GPR 0 "register_operand" "=d,d,d,d")
5767 (minus:GPR (match_operand:GPR 1 "register_operand" "0,d,0,0")
5768 (match_operand:GPR 2 "general_operand" "d,d,R,T") ) )
5769 (clobber (reg:CC CC_REGNUM))]
5770 ""
5771 "@
5772 s<g>r\t%0,%2
5773 s<g>rk\t%0,%1,%2
5774 s<g>\t%0,%2
5775 s<y>\t%0,%2"
5776 [(set_attr "op_type" "RR<E>,RRF,RX<Y>,RXY")
5777 (set_attr "cpu_facility" "*,z196,*,*")
5778 (set_attr "z10prop" "z10_super_c_E1,*,z10_super_E1,z10_super_E1")])
5779
5780 ; slr, sl, sly, slgr, slg, slrk, slgrk
5781 (define_insn "*sub<mode>3_borrow_cc"
5782 [(set (reg CC_REGNUM)
5783 (compare (minus:GPR (match_operand:GPR 1 "register_operand" "0,d,0,0")
5784 (match_operand:GPR 2 "general_operand" "d,d,R,T"))
5785 (match_dup 1)))
5786 (set (match_operand:GPR 0 "register_operand" "=d,d,d,d")
5787 (minus:GPR (match_dup 1) (match_dup 2)))]
5788 "s390_match_ccmode (insn, CCL2mode)"
5789 "@
5790 sl<g>r\t%0,%2
5791 sl<g>rk\t%0,%1,%2
5792 sl<g>\t%0,%2
5793 sl<y>\t%0,%2"
5794 [(set_attr "op_type" "RR<E>,RRF,RX<Y>,RXY")
5795 (set_attr "cpu_facility" "*,z196,*,*")
5796 (set_attr "z10prop" "z10_super_c_E1,*,z10_super_E1,z10_super_E1")])
5797
5798 ; slr, sl, sly, slgr, slg, slrk, slgrk
5799 (define_insn "*sub<mode>3_borrow_cconly"
5800 [(set (reg CC_REGNUM)
5801 (compare (minus:GPR (match_operand:GPR 1 "register_operand" "0,d,0,0")
5802 (match_operand:GPR 2 "general_operand" "d,d,R,T"))
5803 (match_dup 1)))
5804 (clobber (match_scratch:GPR 0 "=d,d,d,d"))]
5805 "s390_match_ccmode (insn, CCL2mode)"
5806 "@
5807 sl<g>r\t%0,%2
5808 sl<g>rk\t%0,%1,%2
5809 sl<g>\t%0,%2
5810 sl<y>\t%0,%2"
5811 [(set_attr "op_type" "RR<E>,RRF,RX<Y>,RXY")
5812 (set_attr "cpu_facility" "*,z196,*,*")
5813 (set_attr "z10prop" "z10_super_c_E1,*,z10_super_E1,z10_super_E1")])
5814
5815 ; slr, sl, sly, slgr, slg, slrk, slgrk
5816 (define_insn "*sub<mode>3_cc"
5817 [(set (reg CC_REGNUM)
5818 (compare (minus:GPR (match_operand:GPR 1 "register_operand" "0,d,0,0")
5819 (match_operand:GPR 2 "general_operand" "d,d,R,T"))
5820 (const_int 0)))
5821 (set (match_operand:GPR 0 "register_operand" "=d,d,d,d")
5822 (minus:GPR (match_dup 1) (match_dup 2)))]
5823 "s390_match_ccmode (insn, CCLmode)"
5824 "@
5825 sl<g>r\t%0,%2
5826 sl<g>rk\t%0,%1,%2
5827 sl<g>\t%0,%2
5828 sl<y>\t%0,%2"
5829 [(set_attr "op_type" "RR<E>,RRF,RX<Y>,RXY")
5830 (set_attr "cpu_facility" "*,z196,*,*")
5831 (set_attr "z10prop" "z10_super_c_E1,*,z10_super_E1,z10_super_E1")])
5832
5833 ; slr, sl, sly, slgr, slg, slrk, slgrk
5834 (define_insn "*sub<mode>3_cc2"
5835 [(set (reg CC_REGNUM)
5836 (compare (match_operand:GPR 1 "register_operand" "0,d,0,0")
5837 (match_operand:GPR 2 "general_operand" "d,d,R,T")))
5838 (set (match_operand:GPR 0 "register_operand" "=d,d,d,d")
5839 (minus:GPR (match_dup 1) (match_dup 2)))]
5840 "s390_match_ccmode (insn, CCL3mode)"
5841 "@
5842 sl<g>r\t%0,%2
5843 sl<g>rk\t%0,%1,%2
5844 sl<g>\t%0,%2
5845 sl<y>\t%0,%2"
5846 [(set_attr "op_type" "RR<E>,RRF,RX<Y>,RXY")
5847 (set_attr "cpu_facility" "*,z196,*,*")
5848 (set_attr "z10prop" "z10_super_c_E1,*,z10_super_E1,z10_super_E1")])
5849
5850 ; slr, sl, sly, slgr, slg, slrk, slgrk
5851 (define_insn "*sub<mode>3_cconly"
5852 [(set (reg CC_REGNUM)
5853 (compare (minus:GPR (match_operand:GPR 1 "register_operand" "0,d,0,0")
5854 (match_operand:GPR 2 "general_operand" "d,d,R,T"))
5855 (const_int 0)))
5856 (clobber (match_scratch:GPR 0 "=d,d,d,d"))]
5857 "s390_match_ccmode (insn, CCLmode)"
5858 "@
5859 sl<g>r\t%0,%2
5860 sl<g>rk\t%0,%1,%2
5861 sl<g>\t%0,%2
5862 sl<y>\t%0,%2"
5863 [(set_attr "op_type" "RR<E>,RRF,RX<Y>,RXY")
5864 (set_attr "cpu_facility" "*,z196,*,*")
5865 (set_attr "z10prop" "z10_super_c_E1,*,z10_super_E1,z10_super_E1")])
5866
5867
5868 ; slr, sl, sly, slgr, slg, slrk, slgrk
5869 (define_insn "*sub<mode>3_cconly2"
5870 [(set (reg CC_REGNUM)
5871 (compare (match_operand:GPR 1 "register_operand" "0,d,0,0")
5872 (match_operand:GPR 2 "general_operand" "d,d,R,T")))
5873 (clobber (match_scratch:GPR 0 "=d,d,d,d"))]
5874 "s390_match_ccmode (insn, CCL3mode)"
5875 "@
5876 sl<g>r\t%0,%2
5877 sl<g>rk\t%0,%1,%2
5878 sl<g>\t%0,%2
5879 sl<y>\t%0,%2"
5880 [(set_attr "op_type" "RR<E>,RRF,RX<Y>,RXY")
5881 (set_attr "cpu_facility" "*,z196,*,*")
5882 (set_attr "z10prop" "z10_super_c_E1,*,z10_super_E1,z10_super_E1")])
5883
5884
5885 ;
5886 ; sub(tf|df|sf|td|dd)3 instruction pattern(s).
5887 ;
5888
5889 ; sxbr, sdbr, sebr, sdb, seb, sxtr, sdtr
5890 (define_insn "sub<mode>3"
5891 [(set (match_operand:FP 0 "register_operand" "=f, f,<vf>")
5892 (minus:FP (match_operand:FP 1 "register_operand" "<f0>, 0,<v0>")
5893 (match_operand:FP 2 "general_operand" "f,<Rf>,<vf>")))
5894 (clobber (reg:CC CC_REGNUM))]
5895 "TARGET_HARD_FLOAT"
5896 "@
5897 s<xde><bt>r\t%0,<op1>%2
5898 s<xde>b\t%0,%2
5899 wfsdb\t%v0,%v1,%v2"
5900 [(set_attr "op_type" "<RRer>,RXE,VRR")
5901 (set_attr "type" "fsimp<mode>")
5902 (set_attr "cpu_facility" "*,*,vec")])
5903
5904 ; sxbr, sdbr, sebr, sdb, seb, sxtr, sdtr
5905 (define_insn "*sub<mode>3_cc"
5906 [(set (reg CC_REGNUM)
5907 (compare (minus:FP (match_operand:FP 1 "nonimmediate_operand" "<f0>,0")
5908 (match_operand:FP 2 "general_operand" "f,<Rf>"))
5909 (match_operand:FP 3 "const0_operand" "")))
5910 (set (match_operand:FP 0 "register_operand" "=f,f")
5911 (minus:FP (match_dup 1) (match_dup 2)))]
5912 "s390_match_ccmode (insn, CCSmode) && TARGET_HARD_FLOAT"
5913 "@
5914 s<xde><bt>r\t%0,<op1>%2
5915 s<xde>b\t%0,%2"
5916 [(set_attr "op_type" "<RRer>,RXE")
5917 (set_attr "type" "fsimp<mode>")])
5918
5919 ; sxbr, sdbr, sebr, sdb, seb, sxtr, sdtr
5920 (define_insn "*sub<mode>3_cconly"
5921 [(set (reg CC_REGNUM)
5922 (compare (minus:FP (match_operand:FP 1 "nonimmediate_operand" "<f0>,0")
5923 (match_operand:FP 2 "general_operand" "f,<Rf>"))
5924 (match_operand:FP 3 "const0_operand" "")))
5925 (clobber (match_scratch:FP 0 "=f,f"))]
5926 "s390_match_ccmode (insn, CCSmode) && TARGET_HARD_FLOAT"
5927 "@
5928 s<xde><bt>r\t%0,<op1>%2
5929 s<xde>b\t%0,%2"
5930 [(set_attr "op_type" "<RRer>,RXE")
5931 (set_attr "type" "fsimp<mode>")])
5932
5933
5934 ;;
5935 ;;- Conditional add/subtract instructions.
5936 ;;
5937
5938 ;
5939 ; add(di|si)cc instruction pattern(s).
5940 ;
5941
5942 ; the following 4 patterns are used when the result of an add with
5943 ; carry is checked for an overflow condition
5944
5945 ; op1 + op2 + c < op1
5946
5947 ; alcr, alc, alcgr, alcg
5948 (define_insn "*add<mode>3_alc_carry1_cc"
5949 [(set (reg CC_REGNUM)
5950 (compare
5951 (plus:GPR (plus:GPR (match_operand:GPR 3 "s390_alc_comparison" "")
5952 (match_operand:GPR 1 "nonimmediate_operand" "%0,0"))
5953 (match_operand:GPR 2 "general_operand" "d,RT"))
5954 (match_dup 1)))
5955 (set (match_operand:GPR 0 "register_operand" "=d,d")
5956 (plus:GPR (plus:GPR (match_dup 3) (match_dup 1)) (match_dup 2)))]
5957 "s390_match_ccmode (insn, CCL1mode) && TARGET_CPU_ZARCH"
5958 "@
5959 alc<g>r\t%0,%2
5960 alc<g>\t%0,%2"
5961 [(set_attr "op_type" "RRE,RXY")
5962 (set_attr "z196prop" "z196_alone,z196_alone")])
5963
5964 ; alcr, alc, alcgr, alcg
5965 (define_insn "*add<mode>3_alc_carry1_cconly"
5966 [(set (reg CC_REGNUM)
5967 (compare
5968 (plus:GPR (plus:GPR (match_operand:GPR 3 "s390_alc_comparison" "")
5969 (match_operand:GPR 1 "nonimmediate_operand" "%0,0"))
5970 (match_operand:GPR 2 "general_operand" "d,RT"))
5971 (match_dup 1)))
5972 (clobber (match_scratch:GPR 0 "=d,d"))]
5973 "s390_match_ccmode (insn, CCL1mode) && TARGET_CPU_ZARCH"
5974 "@
5975 alc<g>r\t%0,%2
5976 alc<g>\t%0,%2"
5977 [(set_attr "op_type" "RRE,RXY")
5978 (set_attr "z196prop" "z196_alone,z196_alone")])
5979
5980 ; op1 + op2 + c < op2
5981
5982 ; alcr, alc, alcgr, alcg
5983 (define_insn "*add<mode>3_alc_carry2_cc"
5984 [(set (reg CC_REGNUM)
5985 (compare
5986 (plus:GPR (plus:GPR (match_operand:GPR 3 "s390_alc_comparison" "")
5987 (match_operand:GPR 1 "nonimmediate_operand" "%0,0"))
5988 (match_operand:GPR 2 "general_operand" "d,RT"))
5989 (match_dup 2)))
5990 (set (match_operand:GPR 0 "register_operand" "=d,d")
5991 (plus:GPR (plus:GPR (match_dup 3) (match_dup 1)) (match_dup 2)))]
5992 "s390_match_ccmode (insn, CCL1mode) && TARGET_CPU_ZARCH"
5993 "@
5994 alc<g>r\t%0,%2
5995 alc<g>\t%0,%2"
5996 [(set_attr "op_type" "RRE,RXY")])
5997
5998 ; alcr, alc, alcgr, alcg
5999 (define_insn "*add<mode>3_alc_carry2_cconly"
6000 [(set (reg CC_REGNUM)
6001 (compare
6002 (plus:GPR (plus:GPR (match_operand:GPR 3 "s390_alc_comparison" "")
6003 (match_operand:GPR 1 "nonimmediate_operand" "%0,0"))
6004 (match_operand:GPR 2 "general_operand" "d,RT"))
6005 (match_dup 2)))
6006 (clobber (match_scratch:GPR 0 "=d,d"))]
6007 "s390_match_ccmode (insn, CCL1mode) && TARGET_CPU_ZARCH"
6008 "@
6009 alc<g>r\t%0,%2
6010 alc<g>\t%0,%2"
6011 [(set_attr "op_type" "RRE,RXY")])
6012
6013 ; alcr, alc, alcgr, alcg
6014 (define_insn "*add<mode>3_alc_cc"
6015 [(set (reg CC_REGNUM)
6016 (compare
6017 (plus:GPR (plus:GPR (match_operand:GPR 3 "s390_alc_comparison" "")
6018 (match_operand:GPR 1 "nonimmediate_operand" "%0,0"))
6019 (match_operand:GPR 2 "general_operand" "d,RT"))
6020 (const_int 0)))
6021 (set (match_operand:GPR 0 "register_operand" "=d,d")
6022 (plus:GPR (plus:GPR (match_dup 3) (match_dup 1)) (match_dup 2)))]
6023 "s390_match_ccmode (insn, CCLmode) && TARGET_CPU_ZARCH"
6024 "@
6025 alc<g>r\t%0,%2
6026 alc<g>\t%0,%2"
6027 [(set_attr "op_type" "RRE,RXY")])
6028
6029 ; alcr, alc, alcgr, alcg
6030 (define_insn "*add<mode>3_alc"
6031 [(set (match_operand:GPR 0 "register_operand" "=d,d")
6032 (plus:GPR (plus:GPR (match_operand:GPR 3 "s390_alc_comparison" "")
6033 (match_operand:GPR 1 "nonimmediate_operand" "%0,0"))
6034 (match_operand:GPR 2 "general_operand" "d,RT")))
6035 (clobber (reg:CC CC_REGNUM))]
6036 "TARGET_CPU_ZARCH"
6037 "@
6038 alc<g>r\t%0,%2
6039 alc<g>\t%0,%2"
6040 [(set_attr "op_type" "RRE,RXY")])
6041
6042 ; slbr, slb, slbgr, slbg
6043 (define_insn "*sub<mode>3_slb_cc"
6044 [(set (reg CC_REGNUM)
6045 (compare
6046 (minus:GPR (minus:GPR (match_operand:GPR 1 "nonimmediate_operand" "0,0")
6047 (match_operand:GPR 2 "general_operand" "d,RT"))
6048 (match_operand:GPR 3 "s390_slb_comparison" ""))
6049 (const_int 0)))
6050 (set (match_operand:GPR 0 "register_operand" "=d,d")
6051 (minus:GPR (minus:GPR (match_dup 1) (match_dup 2)) (match_dup 3)))]
6052 "s390_match_ccmode (insn, CCLmode) && TARGET_CPU_ZARCH"
6053 "@
6054 slb<g>r\t%0,%2
6055 slb<g>\t%0,%2"
6056 [(set_attr "op_type" "RRE,RXY")
6057 (set_attr "z10prop" "z10_c,*")])
6058
6059 ; slbr, slb, slbgr, slbg
6060 (define_insn "*sub<mode>3_slb"
6061 [(set (match_operand:GPR 0 "register_operand" "=d,d")
6062 (minus:GPR (minus:GPR (match_operand:GPR 1 "nonimmediate_operand" "0,0")
6063 (match_operand:GPR 2 "general_operand" "d,RT"))
6064 (match_operand:GPR 3 "s390_slb_comparison" "")))
6065 (clobber (reg:CC CC_REGNUM))]
6066 "TARGET_CPU_ZARCH"
6067 "@
6068 slb<g>r\t%0,%2
6069 slb<g>\t%0,%2"
6070 [(set_attr "op_type" "RRE,RXY")
6071 (set_attr "z10prop" "z10_c,*")])
6072
6073 (define_expand "add<mode>cc"
6074 [(match_operand:GPR 0 "register_operand" "")
6075 (match_operand 1 "comparison_operator" "")
6076 (match_operand:GPR 2 "register_operand" "")
6077 (match_operand:GPR 3 "const_int_operand" "")]
6078 "TARGET_CPU_ZARCH"
6079 "if (!s390_expand_addcc (GET_CODE (operands[1]),
6080 XEXP (operands[1], 0), XEXP (operands[1], 1),
6081 operands[0], operands[2],
6082 operands[3])) FAIL; DONE;")
6083
6084 ;
6085 ; scond instruction pattern(s).
6086 ;
6087
6088 (define_insn_and_split "*scond<mode>"
6089 [(set (match_operand:GPR 0 "register_operand" "=&d")
6090 (match_operand:GPR 1 "s390_alc_comparison" ""))
6091 (clobber (reg:CC CC_REGNUM))]
6092 "TARGET_CPU_ZARCH"
6093 "#"
6094 "&& reload_completed"
6095 [(set (match_dup 0) (const_int 0))
6096 (parallel
6097 [(set (match_dup 0) (plus:GPR (plus:GPR (match_dup 1) (match_dup 0))
6098 (match_dup 0)))
6099 (clobber (reg:CC CC_REGNUM))])]
6100 "")
6101
6102 (define_insn_and_split "*scond<mode>_neg"
6103 [(set (match_operand:GPR 0 "register_operand" "=&d")
6104 (match_operand:GPR 1 "s390_slb_comparison" ""))
6105 (clobber (reg:CC CC_REGNUM))]
6106 "TARGET_CPU_ZARCH"
6107 "#"
6108 "&& reload_completed"
6109 [(set (match_dup 0) (const_int 0))
6110 (parallel
6111 [(set (match_dup 0) (minus:GPR (minus:GPR (match_dup 0) (match_dup 0))
6112 (match_dup 1)))
6113 (clobber (reg:CC CC_REGNUM))])
6114 (parallel
6115 [(set (match_dup 0) (neg:GPR (match_dup 0)))
6116 (clobber (reg:CC CC_REGNUM))])]
6117 "")
6118
6119
6120 (define_expand "cstore<mode>4"
6121 [(set (match_operand:SI 0 "register_operand" "")
6122 (match_operator:SI 1 "s390_scond_operator"
6123 [(match_operand:GPR 2 "register_operand" "")
6124 (match_operand:GPR 3 "general_operand" "")]))]
6125 "TARGET_CPU_ZARCH"
6126 "if (!s390_expand_addcc (GET_CODE (operands[1]), operands[2], operands[3],
6127 operands[0], const0_rtx, const1_rtx)) FAIL; DONE;")
6128
6129 (define_expand "cstorecc4"
6130 [(parallel
6131 [(set (match_operand:SI 0 "register_operand" "")
6132 (match_operator:SI 1 "s390_eqne_operator"
6133 [(match_operand:CCZ1 2 "register_operand")
6134 (match_operand 3 "const0_operand")]))
6135 (clobber (reg:CC CC_REGNUM))])]
6136 ""
6137 "emit_insn (gen_sne (operands[0], operands[2]));
6138 if (GET_CODE (operands[1]) == EQ)
6139 emit_insn (gen_xorsi3 (operands[0], operands[0], const1_rtx));
6140 DONE;")
6141
6142 (define_insn_and_split "sne"
6143 [(set (match_operand:SI 0 "register_operand" "=d")
6144 (ne:SI (match_operand:CCZ1 1 "register_operand" "0")
6145 (const_int 0)))
6146 (clobber (reg:CC CC_REGNUM))]
6147 ""
6148 "#"
6149 "reload_completed"
6150 [(parallel
6151 [(set (match_dup 0) (ashiftrt:SI (match_dup 0) (const_int 28)))
6152 (clobber (reg:CC CC_REGNUM))])])
6153
6154
6155 ;;
6156 ;; - Conditional move instructions (introduced with z196)
6157 ;;
6158
6159 (define_expand "mov<mode>cc"
6160 [(set (match_operand:GPR 0 "nonimmediate_operand" "")
6161 (if_then_else:GPR (match_operand 1 "comparison_operator" "")
6162 (match_operand:GPR 2 "nonimmediate_operand" "")
6163 (match_operand:GPR 3 "nonimmediate_operand" "")))]
6164 "TARGET_Z196"
6165 {
6166 /* Emit the comparison insn in case we do not already have a comparison result. */
6167 if (!s390_comparison (operands[1], VOIDmode))
6168 operands[1] = s390_emit_compare (GET_CODE (operands[1]),
6169 XEXP (operands[1], 0),
6170 XEXP (operands[1], 1));
6171 })
6172
6173 ; locr, loc, stoc, locgr, locg, stocg
6174 (define_insn_and_split "*mov<mode>cc"
6175 [(set (match_operand:GPR 0 "nonimmediate_operand" "=d,d, d, d,QS,QS,&d")
6176 (if_then_else:GPR
6177 (match_operator 1 "s390_comparison"
6178 [(match_operand 2 "cc_reg_operand" " c,c, c, c, c, c, c")
6179 (match_operand 5 "const_int_operand" "")])
6180 (match_operand:GPR 3 "nonimmediate_operand" " d,0,QS, 0, d, 0,QS")
6181 (match_operand:GPR 4 "nonimmediate_operand" " 0,d, 0,QS, 0, d,QS")))]
6182 "TARGET_Z196"
6183 "@
6184 loc<g>r%C1\t%0,%3
6185 loc<g>r%D1\t%0,%4
6186 loc<g>%C1\t%0,%3
6187 loc<g>%D1\t%0,%4
6188 stoc<g>%C1\t%3,%0
6189 stoc<g>%D1\t%4,%0
6190 #"
6191 "&& reload_completed
6192 && MEM_P (operands[3]) && MEM_P (operands[4])"
6193 [(set (match_dup 0)
6194 (if_then_else:GPR
6195 (match_op_dup 1 [(match_dup 2) (const_int 0)])
6196 (match_dup 3)
6197 (match_dup 0)))
6198 (set (match_dup 0)
6199 (if_then_else:GPR
6200 (match_op_dup 1 [(match_dup 2) (const_int 0)])
6201 (match_dup 0)
6202 (match_dup 4)))]
6203 ""
6204 [(set_attr "op_type" "RRF,RRF,RSY,RSY,RSY,RSY,*")])
6205
6206 ;;
6207 ;;- Multiply instructions.
6208 ;;
6209
6210 ;
6211 ; muldi3 instruction pattern(s).
6212 ;
6213
6214 (define_insn "*muldi3_sign"
6215 [(set (match_operand:DI 0 "register_operand" "=d,d")
6216 (mult:DI (sign_extend:DI (match_operand:SI 2 "general_operand" "d,RT"))
6217 (match_operand:DI 1 "register_operand" "0,0")))]
6218 "TARGET_ZARCH"
6219 "@
6220 msgfr\t%0,%2
6221 msgf\t%0,%2"
6222 [(set_attr "op_type" "RRE,RXY")
6223 (set_attr "type" "imuldi")])
6224
6225 (define_insn "muldi3"
6226 [(set (match_operand:DI 0 "register_operand" "=d,d,d,d")
6227 (mult:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,0")
6228 (match_operand:DI 2 "general_operand" "d,K,RT,Os")))]
6229 "TARGET_ZARCH"
6230 "@
6231 msgr\t%0,%2
6232 mghi\t%0,%h2
6233 msg\t%0,%2
6234 msgfi\t%0,%2"
6235 [(set_attr "op_type" "RRE,RI,RXY,RIL")
6236 (set_attr "type" "imuldi")
6237 (set_attr "cpu_facility" "*,*,*,z10")])
6238
6239 ;
6240 ; mulsi3 instruction pattern(s).
6241 ;
6242
6243 (define_insn "*mulsi3_sign"
6244 [(set (match_operand:SI 0 "register_operand" "=d,d")
6245 (mult:SI (sign_extend:SI (match_operand:HI 2 "memory_operand" "R,T"))
6246 (match_operand:SI 1 "register_operand" "0,0")))]
6247 ""
6248 "@
6249 mh\t%0,%2
6250 mhy\t%0,%2"
6251 [(set_attr "op_type" "RX,RXY")
6252 (set_attr "type" "imulhi")
6253 (set_attr "cpu_facility" "*,z10")])
6254
6255 (define_insn "mulsi3"
6256 [(set (match_operand:SI 0 "register_operand" "=d,d,d,d,d")
6257 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,0,0,0")
6258 (match_operand:SI 2 "general_operand" "d,K,R,T,Os")))]
6259 ""
6260 "@
6261 msr\t%0,%2
6262 mhi\t%0,%h2
6263 ms\t%0,%2
6264 msy\t%0,%2
6265 msfi\t%0,%2"
6266 [(set_attr "op_type" "RRE,RI,RX,RXY,RIL")
6267 (set_attr "type" "imulsi,imulhi,imulsi,imulsi,imulsi")
6268 (set_attr "cpu_facility" "*,*,*,*,z10")])
6269
6270 ;
6271 ; mulsidi3 instruction pattern(s).
6272 ;
6273
6274 (define_insn "mulsidi3"
6275 [(set (match_operand:DI 0 "register_operand" "=d,d,d")
6276 (mult:DI (sign_extend:DI
6277 (match_operand:SI 1 "register_operand" "%0,0,0"))
6278 (sign_extend:DI
6279 (match_operand:SI 2 "nonimmediate_operand" "d,R,T"))))]
6280 "!TARGET_ZARCH"
6281 "@
6282 mr\t%0,%2
6283 m\t%0,%2
6284 mfy\t%0,%2"
6285 [(set_attr "op_type" "RR,RX,RXY")
6286 (set_attr "type" "imulsi")
6287 (set_attr "cpu_facility" "*,*,z10")])
6288
6289 ;
6290 ; umul instruction pattern(s).
6291 ;
6292
6293 ; mlr, ml, mlgr, mlg
6294 (define_insn "umul<dwh><mode>3"
6295 [(set (match_operand:DW 0 "register_operand" "=d, d")
6296 (mult:DW (zero_extend:DW
6297 (match_operand:<DWH> 1 "register_operand" "%0, 0"))
6298 (zero_extend:DW
6299 (match_operand:<DWH> 2 "nonimmediate_operand" " d,RT"))))]
6300 "TARGET_CPU_ZARCH"
6301 "@
6302 ml<tg>r\t%0,%2
6303 ml<tg>\t%0,%2"
6304 [(set_attr "op_type" "RRE,RXY")
6305 (set_attr "type" "imul<dwh>")])
6306
6307 ;
6308 ; mul(tf|df|sf|td|dd)3 instruction pattern(s).
6309 ;
6310
6311 ; mxbr, mdbr, meebr, mxb, mxb, meeb, mdtr, mxtr
6312 (define_insn "mul<mode>3"
6313 [(set (match_operand:FP 0 "register_operand" "=f, f,<vf>")
6314 (mult:FP (match_operand:FP 1 "nonimmediate_operand" "%<f0>, 0,<v0>")
6315 (match_operand:FP 2 "general_operand" "f,<Rf>,<vf>")))]
6316 "TARGET_HARD_FLOAT"
6317 "@
6318 m<xdee><bt>r\t%0,<op1>%2
6319 m<xdee>b\t%0,%2
6320 wfmdb\t%v0,%v1,%v2"
6321 [(set_attr "op_type" "<RRer>,RXE,VRR")
6322 (set_attr "type" "fmul<mode>")
6323 (set_attr "cpu_facility" "*,*,vec")])
6324
6325 ; madbr, maebr, maxb, madb, maeb
6326 (define_insn "fma<mode>4"
6327 [(set (match_operand:DSF 0 "register_operand" "=f,f,<vf>")
6328 (fma:DSF (match_operand:DSF 1 "nonimmediate_operand" "%f,f,<vf>")
6329 (match_operand:DSF 2 "nonimmediate_operand" "f,R,<vf>")
6330 (match_operand:DSF 3 "register_operand" "0,0,<v0>")))]
6331 "TARGET_HARD_FLOAT"
6332 "@
6333 ma<xde>br\t%0,%1,%2
6334 ma<xde>b\t%0,%1,%2
6335 wfmadb\t%v0,%v1,%v2,%v3"
6336 [(set_attr "op_type" "RRE,RXE,VRR")
6337 (set_attr "type" "fmadd<mode>")
6338 (set_attr "cpu_facility" "*,*,vec")])
6339
6340 ; msxbr, msdbr, msebr, msxb, msdb, mseb
6341 (define_insn "fms<mode>4"
6342 [(set (match_operand:DSF 0 "register_operand" "=f,f,<vf>")
6343 (fma:DSF (match_operand:DSF 1 "nonimmediate_operand" "%f,f,<vf>")
6344 (match_operand:DSF 2 "nonimmediate_operand" "f,R,<vf>")
6345 (neg:DSF (match_operand:DSF 3 "register_operand" "0,0,<v0>"))))]
6346 "TARGET_HARD_FLOAT"
6347 "@
6348 ms<xde>br\t%0,%1,%2
6349 ms<xde>b\t%0,%1,%2
6350 wfmsdb\t%v0,%v1,%v2,%v3"
6351 [(set_attr "op_type" "RRE,RXE,VRR")
6352 (set_attr "type" "fmadd<mode>")
6353 (set_attr "cpu_facility" "*,*,vec")])
6354
6355 ;;
6356 ;;- Divide and modulo instructions.
6357 ;;
6358
6359 ;
6360 ; divmoddi4 instruction pattern(s).
6361 ;
6362
6363 (define_expand "divmoddi4"
6364 [(parallel [(set (match_operand:DI 0 "general_operand" "")
6365 (div:DI (match_operand:DI 1 "register_operand" "")
6366 (match_operand:DI 2 "general_operand" "")))
6367 (set (match_operand:DI 3 "general_operand" "")
6368 (mod:DI (match_dup 1) (match_dup 2)))])
6369 (clobber (match_dup 4))]
6370 "TARGET_ZARCH"
6371 {
6372 rtx insn, div_equal, mod_equal;
6373
6374 div_equal = gen_rtx_DIV (DImode, operands[1], operands[2]);
6375 mod_equal = gen_rtx_MOD (DImode, operands[1], operands[2]);
6376
6377 operands[4] = gen_reg_rtx(TImode);
6378 emit_insn (gen_divmodtidi3 (operands[4], operands[1], operands[2]));
6379
6380 insn = emit_move_insn (operands[0], gen_lowpart (DImode, operands[4]));
6381 set_unique_reg_note (insn, REG_EQUAL, div_equal);
6382
6383 insn = emit_move_insn (operands[3], gen_highpart (DImode, operands[4]));
6384 set_unique_reg_note (insn, REG_EQUAL, mod_equal);
6385
6386 DONE;
6387 })
6388
6389 (define_insn "divmodtidi3"
6390 [(set (match_operand:TI 0 "register_operand" "=d,d")
6391 (ior:TI
6392 (ashift:TI
6393 (zero_extend:TI
6394 (mod:DI (match_operand:DI 1 "register_operand" "0,0")
6395 (match_operand:DI 2 "general_operand" "d,RT")))
6396 (const_int 64))
6397 (zero_extend:TI (div:DI (match_dup 1) (match_dup 2)))))]
6398 "TARGET_ZARCH"
6399 "@
6400 dsgr\t%0,%2
6401 dsg\t%0,%2"
6402 [(set_attr "op_type" "RRE,RXY")
6403 (set_attr "type" "idiv")])
6404
6405 (define_insn "divmodtisi3"
6406 [(set (match_operand:TI 0 "register_operand" "=d,d")
6407 (ior:TI
6408 (ashift:TI
6409 (zero_extend:TI
6410 (mod:DI (match_operand:DI 1 "register_operand" "0,0")
6411 (sign_extend:DI
6412 (match_operand:SI 2 "nonimmediate_operand" "d,RT"))))
6413 (const_int 64))
6414 (zero_extend:TI
6415 (div:DI (match_dup 1) (sign_extend:DI (match_dup 2))))))]
6416 "TARGET_ZARCH"
6417 "@
6418 dsgfr\t%0,%2
6419 dsgf\t%0,%2"
6420 [(set_attr "op_type" "RRE,RXY")
6421 (set_attr "type" "idiv")])
6422
6423 ;
6424 ; udivmoddi4 instruction pattern(s).
6425 ;
6426
6427 (define_expand "udivmoddi4"
6428 [(parallel [(set (match_operand:DI 0 "general_operand" "")
6429 (udiv:DI (match_operand:DI 1 "general_operand" "")
6430 (match_operand:DI 2 "nonimmediate_operand" "")))
6431 (set (match_operand:DI 3 "general_operand" "")
6432 (umod:DI (match_dup 1) (match_dup 2)))])
6433 (clobber (match_dup 4))]
6434 "TARGET_ZARCH"
6435 {
6436 rtx insn, div_equal, mod_equal, equal;
6437
6438 div_equal = gen_rtx_UDIV (DImode, operands[1], operands[2]);
6439 mod_equal = gen_rtx_UMOD (DImode, operands[1], operands[2]);
6440 equal = gen_rtx_IOR (TImode,
6441 gen_rtx_ASHIFT (TImode,
6442 gen_rtx_ZERO_EXTEND (TImode, mod_equal),
6443 GEN_INT (64)),
6444 gen_rtx_ZERO_EXTEND (TImode, div_equal));
6445
6446 operands[4] = gen_reg_rtx(TImode);
6447 emit_clobber (operands[4]);
6448 emit_move_insn (gen_lowpart (DImode, operands[4]), operands[1]);
6449 emit_move_insn (gen_highpart (DImode, operands[4]), const0_rtx);
6450
6451 insn = emit_insn (gen_udivmodtidi3 (operands[4], operands[4], operands[2]));
6452 set_unique_reg_note (insn, REG_EQUAL, equal);
6453
6454 insn = emit_move_insn (operands[0], gen_lowpart (DImode, operands[4]));
6455 set_unique_reg_note (insn, REG_EQUAL, div_equal);
6456
6457 insn = emit_move_insn (operands[3], gen_highpart (DImode, operands[4]));
6458 set_unique_reg_note (insn, REG_EQUAL, mod_equal);
6459
6460 DONE;
6461 })
6462
6463 (define_insn "udivmodtidi3"
6464 [(set (match_operand:TI 0 "register_operand" "=d,d")
6465 (ior:TI
6466 (ashift:TI
6467 (zero_extend:TI
6468 (truncate:DI
6469 (umod:TI (match_operand:TI 1 "register_operand" "0,0")
6470 (zero_extend:TI
6471 (match_operand:DI 2 "nonimmediate_operand" "d,RT")))))
6472 (const_int 64))
6473 (zero_extend:TI
6474 (truncate:DI
6475 (udiv:TI (match_dup 1) (zero_extend:TI (match_dup 2)))))))]
6476 "TARGET_ZARCH"
6477 "@
6478 dlgr\t%0,%2
6479 dlg\t%0,%2"
6480 [(set_attr "op_type" "RRE,RXY")
6481 (set_attr "type" "idiv")])
6482
6483 ;
6484 ; divmodsi4 instruction pattern(s).
6485 ;
6486
6487 (define_expand "divmodsi4"
6488 [(parallel [(set (match_operand:SI 0 "general_operand" "")
6489 (div:SI (match_operand:SI 1 "general_operand" "")
6490 (match_operand:SI 2 "nonimmediate_operand" "")))
6491 (set (match_operand:SI 3 "general_operand" "")
6492 (mod:SI (match_dup 1) (match_dup 2)))])
6493 (clobber (match_dup 4))]
6494 "!TARGET_ZARCH"
6495 {
6496 rtx insn, div_equal, mod_equal, equal;
6497
6498 div_equal = gen_rtx_DIV (SImode, operands[1], operands[2]);
6499 mod_equal = gen_rtx_MOD (SImode, operands[1], operands[2]);
6500 equal = gen_rtx_IOR (DImode,
6501 gen_rtx_ASHIFT (DImode,
6502 gen_rtx_ZERO_EXTEND (DImode, mod_equal),
6503 GEN_INT (32)),
6504 gen_rtx_ZERO_EXTEND (DImode, div_equal));
6505
6506 operands[4] = gen_reg_rtx(DImode);
6507 emit_insn (gen_extendsidi2 (operands[4], operands[1]));
6508
6509 insn = emit_insn (gen_divmoddisi3 (operands[4], operands[4], operands[2]));
6510 set_unique_reg_note (insn, REG_EQUAL, equal);
6511
6512 insn = emit_move_insn (operands[0], gen_lowpart (SImode, operands[4]));
6513 set_unique_reg_note (insn, REG_EQUAL, div_equal);
6514
6515 insn = emit_move_insn (operands[3], gen_highpart (SImode, operands[4]));
6516 set_unique_reg_note (insn, REG_EQUAL, mod_equal);
6517
6518 DONE;
6519 })
6520
6521 (define_insn "divmoddisi3"
6522 [(set (match_operand:DI 0 "register_operand" "=d,d")
6523 (ior:DI
6524 (ashift:DI
6525 (zero_extend:DI
6526 (truncate:SI
6527 (mod:DI (match_operand:DI 1 "register_operand" "0,0")
6528 (sign_extend:DI
6529 (match_operand:SI 2 "nonimmediate_operand" "d,R")))))
6530 (const_int 32))
6531 (zero_extend:DI
6532 (truncate:SI
6533 (div:DI (match_dup 1) (sign_extend:DI (match_dup 2)))))))]
6534 "!TARGET_ZARCH"
6535 "@
6536 dr\t%0,%2
6537 d\t%0,%2"
6538 [(set_attr "op_type" "RR,RX")
6539 (set_attr "type" "idiv")])
6540
6541 ;
6542 ; udivsi3 and umodsi3 instruction pattern(s).
6543 ;
6544
6545 (define_expand "udivmodsi4"
6546 [(parallel [(set (match_operand:SI 0 "general_operand" "")
6547 (udiv:SI (match_operand:SI 1 "general_operand" "")
6548 (match_operand:SI 2 "nonimmediate_operand" "")))
6549 (set (match_operand:SI 3 "general_operand" "")
6550 (umod:SI (match_dup 1) (match_dup 2)))])
6551 (clobber (match_dup 4))]
6552 "!TARGET_ZARCH && TARGET_CPU_ZARCH"
6553 {
6554 rtx insn, div_equal, mod_equal, equal;
6555
6556 div_equal = gen_rtx_UDIV (SImode, operands[1], operands[2]);
6557 mod_equal = gen_rtx_UMOD (SImode, operands[1], operands[2]);
6558 equal = gen_rtx_IOR (DImode,
6559 gen_rtx_ASHIFT (DImode,
6560 gen_rtx_ZERO_EXTEND (DImode, mod_equal),
6561 GEN_INT (32)),
6562 gen_rtx_ZERO_EXTEND (DImode, div_equal));
6563
6564 operands[4] = gen_reg_rtx(DImode);
6565 emit_clobber (operands[4]);
6566 emit_move_insn (gen_lowpart (SImode, operands[4]), operands[1]);
6567 emit_move_insn (gen_highpart (SImode, operands[4]), const0_rtx);
6568
6569 insn = emit_insn (gen_udivmoddisi3 (operands[4], operands[4], operands[2]));
6570 set_unique_reg_note (insn, REG_EQUAL, equal);
6571
6572 insn = emit_move_insn (operands[0], gen_lowpart (SImode, operands[4]));
6573 set_unique_reg_note (insn, REG_EQUAL, div_equal);
6574
6575 insn = emit_move_insn (operands[3], gen_highpart (SImode, operands[4]));
6576 set_unique_reg_note (insn, REG_EQUAL, mod_equal);
6577
6578 DONE;
6579 })
6580
6581 (define_insn "udivmoddisi3"
6582 [(set (match_operand:DI 0 "register_operand" "=d,d")
6583 (ior:DI
6584 (ashift:DI
6585 (zero_extend:DI
6586 (truncate:SI
6587 (umod:DI (match_operand:DI 1 "register_operand" "0,0")
6588 (zero_extend:DI
6589 (match_operand:SI 2 "nonimmediate_operand" "d,RT")))))
6590 (const_int 32))
6591 (zero_extend:DI
6592 (truncate:SI
6593 (udiv:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))))]
6594 "!TARGET_ZARCH && TARGET_CPU_ZARCH"
6595 "@
6596 dlr\t%0,%2
6597 dl\t%0,%2"
6598 [(set_attr "op_type" "RRE,RXY")
6599 (set_attr "type" "idiv")])
6600
6601 (define_expand "udivsi3"
6602 [(set (match_operand:SI 0 "register_operand" "=d")
6603 (udiv:SI (match_operand:SI 1 "general_operand" "")
6604 (match_operand:SI 2 "general_operand" "")))
6605 (clobber (match_dup 3))]
6606 "!TARGET_ZARCH && !TARGET_CPU_ZARCH"
6607 {
6608 rtx insn, udiv_equal, umod_equal, equal;
6609
6610 udiv_equal = gen_rtx_UDIV (SImode, operands[1], operands[2]);
6611 umod_equal = gen_rtx_UMOD (SImode, operands[1], operands[2]);
6612 equal = gen_rtx_IOR (DImode,
6613 gen_rtx_ASHIFT (DImode,
6614 gen_rtx_ZERO_EXTEND (DImode, umod_equal),
6615 GEN_INT (32)),
6616 gen_rtx_ZERO_EXTEND (DImode, udiv_equal));
6617
6618 operands[3] = gen_reg_rtx (DImode);
6619
6620 if (CONSTANT_P (operands[2]))
6621 {
6622 if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0)
6623 {
6624 rtx_code_label *label1 = gen_label_rtx ();
6625
6626 operands[1] = make_safe_from (operands[1], operands[0]);
6627 emit_move_insn (operands[0], const0_rtx);
6628 emit_cmp_and_jump_insns (operands[1], operands[2], LT, NULL_RTX,
6629 SImode, 1, label1);
6630 emit_move_insn (operands[0], const1_rtx);
6631 emit_label (label1);
6632 }
6633 else
6634 {
6635 operands[2] = force_reg (SImode, operands[2]);
6636 operands[2] = make_safe_from (operands[2], operands[0]);
6637
6638 emit_insn (gen_zero_extendsidi2 (operands[3], operands[1]));
6639 insn = emit_insn (gen_divmoddisi3 (operands[3], operands[3],
6640 operands[2]));
6641 set_unique_reg_note (insn, REG_EQUAL, equal);
6642
6643 insn = emit_move_insn (operands[0],
6644 gen_lowpart (SImode, operands[3]));
6645 set_unique_reg_note (insn, REG_EQUAL, udiv_equal);
6646 }
6647 }
6648 else
6649 {
6650 rtx_code_label *label1 = gen_label_rtx ();
6651 rtx_code_label *label2 = gen_label_rtx ();
6652 rtx_code_label *label3 = gen_label_rtx ();
6653
6654 operands[1] = force_reg (SImode, operands[1]);
6655 operands[1] = make_safe_from (operands[1], operands[0]);
6656 operands[2] = force_reg (SImode, operands[2]);
6657 operands[2] = make_safe_from (operands[2], operands[0]);
6658
6659 emit_move_insn (operands[0], const0_rtx);
6660 emit_cmp_and_jump_insns (operands[2], operands[1], GT, NULL_RTX,
6661 SImode, 1, label3);
6662 emit_cmp_and_jump_insns (operands[2], const0_rtx, LT, NULL_RTX,
6663 SImode, 0, label2);
6664 emit_cmp_and_jump_insns (operands[2], const1_rtx, EQ, NULL_RTX,
6665 SImode, 0, label1);
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_lowpart (SImode, operands[3]));
6673 set_unique_reg_note (insn, REG_EQUAL, udiv_equal);
6674
6675 emit_jump (label3);
6676 emit_label (label1);
6677 emit_move_insn (operands[0], operands[1]);
6678 emit_jump (label3);
6679 emit_label (label2);
6680 emit_move_insn (operands[0], const1_rtx);
6681 emit_label (label3);
6682 }
6683 emit_move_insn (operands[0], operands[0]);
6684 DONE;
6685 })
6686
6687 (define_expand "umodsi3"
6688 [(set (match_operand:SI 0 "register_operand" "=d")
6689 (umod:SI (match_operand:SI 1 "nonimmediate_operand" "")
6690 (match_operand:SI 2 "nonimmediate_operand" "")))
6691 (clobber (match_dup 3))]
6692 "!TARGET_ZARCH && !TARGET_CPU_ZARCH"
6693 {
6694 rtx insn, udiv_equal, umod_equal, equal;
6695
6696 udiv_equal = gen_rtx_UDIV (SImode, operands[1], operands[2]);
6697 umod_equal = gen_rtx_UMOD (SImode, operands[1], operands[2]);
6698 equal = gen_rtx_IOR (DImode,
6699 gen_rtx_ASHIFT (DImode,
6700 gen_rtx_ZERO_EXTEND (DImode, umod_equal),
6701 GEN_INT (32)),
6702 gen_rtx_ZERO_EXTEND (DImode, udiv_equal));
6703
6704 operands[3] = gen_reg_rtx (DImode);
6705
6706 if (CONSTANT_P (operands[2]))
6707 {
6708 if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) <= 0)
6709 {
6710 rtx_code_label *label1 = gen_label_rtx ();
6711
6712 operands[1] = make_safe_from (operands[1], operands[0]);
6713 emit_move_insn (operands[0], operands[1]);
6714 emit_cmp_and_jump_insns (operands[0], operands[2], LT, NULL_RTX,
6715 SImode, 1, label1);
6716 emit_insn (gen_abssi2 (operands[0], operands[2]));
6717 emit_insn (gen_addsi3 (operands[0], operands[0], operands[1]));
6718 emit_label (label1);
6719 }
6720 else
6721 {
6722 operands[2] = force_reg (SImode, operands[2]);
6723 operands[2] = make_safe_from (operands[2], operands[0]);
6724
6725 emit_insn (gen_zero_extendsidi2 (operands[3], operands[1]));
6726 insn = emit_insn (gen_divmoddisi3 (operands[3], operands[3],
6727 operands[2]));
6728 set_unique_reg_note (insn, REG_EQUAL, equal);
6729
6730 insn = emit_move_insn (operands[0],
6731 gen_highpart (SImode, operands[3]));
6732 set_unique_reg_note (insn, REG_EQUAL, umod_equal);
6733 }
6734 }
6735 else
6736 {
6737 rtx_code_label *label1 = gen_label_rtx ();
6738 rtx_code_label *label2 = gen_label_rtx ();
6739 rtx_code_label *label3 = gen_label_rtx ();
6740
6741 operands[1] = force_reg (SImode, operands[1]);
6742 operands[1] = make_safe_from (operands[1], operands[0]);
6743 operands[2] = force_reg (SImode, operands[2]);
6744 operands[2] = make_safe_from (operands[2], operands[0]);
6745
6746 emit_move_insn(operands[0], operands[1]);
6747 emit_cmp_and_jump_insns (operands[2], operands[1], GT, NULL_RTX,
6748 SImode, 1, label3);
6749 emit_cmp_and_jump_insns (operands[2], const0_rtx, LT, NULL_RTX,
6750 SImode, 0, label2);
6751 emit_cmp_and_jump_insns (operands[2], const1_rtx, EQ, NULL_RTX,
6752 SImode, 0, label1);
6753 emit_insn (gen_zero_extendsidi2 (operands[3], operands[1]));
6754 insn = emit_insn (gen_divmoddisi3 (operands[3], operands[3],
6755 operands[2]));
6756 set_unique_reg_note (insn, REG_EQUAL, equal);
6757
6758 insn = emit_move_insn (operands[0],
6759 gen_highpart (SImode, operands[3]));
6760 set_unique_reg_note (insn, REG_EQUAL, umod_equal);
6761
6762 emit_jump (label3);
6763 emit_label (label1);
6764 emit_move_insn (operands[0], const0_rtx);
6765 emit_jump (label3);
6766 emit_label (label2);
6767 emit_insn (gen_subsi3 (operands[0], operands[0], operands[2]));
6768 emit_label (label3);
6769 }
6770 DONE;
6771 })
6772
6773 ;
6774 ; div(df|sf)3 instruction pattern(s).
6775 ;
6776
6777 ; dxbr, ddbr, debr, dxb, ddb, deb, ddtr, dxtr
6778 (define_insn "div<mode>3"
6779 [(set (match_operand:FP 0 "register_operand" "=f, f,<vf>")
6780 (div:FP (match_operand:FP 1 "register_operand" "<f0>, 0,<v0>")
6781 (match_operand:FP 2 "general_operand" "f,<Rf>,<vf>")))]
6782 "TARGET_HARD_FLOAT"
6783 "@
6784 d<xde><bt>r\t%0,<op1>%2
6785 d<xde>b\t%0,%2
6786 wfddb\t%v0,%v1,%v2"
6787 [(set_attr "op_type" "<RRer>,RXE,VRR")
6788 (set_attr "type" "fdiv<mode>")
6789 (set_attr "cpu_facility" "*,*,vec")])
6790
6791
6792 ;;
6793 ;;- And instructions.
6794 ;;
6795
6796 (define_expand "and<mode>3"
6797 [(set (match_operand:INT 0 "nonimmediate_operand" "")
6798 (and:INT (match_operand:INT 1 "nonimmediate_operand" "")
6799 (match_operand:INT 2 "general_operand" "")))
6800 (clobber (reg:CC CC_REGNUM))]
6801 ""
6802 "s390_expand_logical_operator (AND, <MODE>mode, operands); DONE;")
6803
6804 ;
6805 ; anddi3 instruction pattern(s).
6806 ;
6807
6808 (define_insn "*anddi3_cc"
6809 [(set (reg CC_REGNUM)
6810 (compare
6811 (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,d, 0, d")
6812 (match_operand:DI 2 "general_operand" " d,d,RT,NxxDq"))
6813 (const_int 0)))
6814 (set (match_operand:DI 0 "register_operand" "=d,d, d, d")
6815 (and:DI (match_dup 1) (match_dup 2)))]
6816 "TARGET_ZARCH && s390_match_ccmode(insn, CCTmode)"
6817 "@
6818 ngr\t%0,%2
6819 ngrk\t%0,%1,%2
6820 ng\t%0,%2
6821 risbg\t%0,%1,%s2,128+%e2,0"
6822 [(set_attr "op_type" "RRE,RRF,RXY,RIE")
6823 (set_attr "cpu_facility" "*,z196,*,z10")
6824 (set_attr "z10prop" "z10_super_E1,*,z10_super_E1,z10_super_E1")])
6825
6826 (define_insn "*anddi3_cconly"
6827 [(set (reg CC_REGNUM)
6828 (compare
6829 (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,d, 0, d")
6830 (match_operand:DI 2 "general_operand" " d,d,RT,NxxDq"))
6831 (const_int 0)))
6832 (clobber (match_scratch:DI 0 "=d,d, d, d"))]
6833 "TARGET_ZARCH
6834 && s390_match_ccmode(insn, CCTmode)
6835 /* Do not steal TM patterns. */
6836 && s390_single_part (operands[2], DImode, HImode, 0) < 0"
6837 "@
6838 ngr\t%0,%2
6839 ngrk\t%0,%1,%2
6840 ng\t%0,%2
6841 risbg\t%0,%1,%s2,128+%e2,0"
6842 [(set_attr "op_type" "RRE,RRF,RXY,RIE")
6843 (set_attr "cpu_facility" "*,z196,*,z10")
6844 (set_attr "z10prop" "z10_super_E1,*,z10_super_E1,z10_super_E1")])
6845
6846 (define_insn "*anddi3"
6847 [(set (match_operand:DI 0 "nonimmediate_operand"
6848 "=d,d, d, d, d, d, d, d,d,d, d, d, AQ,Q")
6849 (and:DI
6850 (match_operand:DI 1 "nonimmediate_operand"
6851 "%d,o, 0, 0, 0, 0, 0, 0,0,d, 0, d, 0,0")
6852 (match_operand:DI 2 "general_operand"
6853 "M, M,N0HDF,N1HDF,N2HDF,N3HDF,N0SDF,N1SDF,d,d,RT,NxxDq,NxQDF,Q")))
6854 (clobber (reg:CC CC_REGNUM))]
6855 "TARGET_ZARCH && s390_logical_operator_ok_p (operands)"
6856 "@
6857 #
6858 #
6859 nihh\t%0,%j2
6860 nihl\t%0,%j2
6861 nilh\t%0,%j2
6862 nill\t%0,%j2
6863 nihf\t%0,%m2
6864 nilf\t%0,%m2
6865 ngr\t%0,%2
6866 ngrk\t%0,%1,%2
6867 ng\t%0,%2
6868 risbg\t%0,%1,%s2,128+%e2,0
6869 #
6870 #"
6871 [(set_attr "op_type" "RRE,RXE,RI,RI,RI,RI,RIL,RIL,RRE,RRF,RXY,RIE,SI,SS")
6872 (set_attr "cpu_facility" "*,*,*,*,*,*,extimm,extimm,*,z196,*,z10,*,*")
6873 (set_attr "z10prop" "*,
6874 *,
6875 z10_super_E1,
6876 z10_super_E1,
6877 z10_super_E1,
6878 z10_super_E1,
6879 z10_super_E1,
6880 z10_super_E1,
6881 z10_super_E1,
6882 *,
6883 z10_super_E1,
6884 z10_super_E1,
6885 *,
6886 *")])
6887
6888 (define_split
6889 [(set (match_operand:DI 0 "s_operand" "")
6890 (and:DI (match_dup 0) (match_operand:DI 1 "immediate_operand" "")))
6891 (clobber (reg:CC CC_REGNUM))]
6892 "reload_completed"
6893 [(parallel
6894 [(set (match_dup 0) (and:QI (match_dup 0) (match_dup 1)))
6895 (clobber (reg:CC CC_REGNUM))])]
6896 "s390_narrow_logical_operator (AND, &operands[0], &operands[1]);")
6897
6898 ;; These two are what combine generates for (ashift (zero_extract)).
6899 (define_insn "*extzv_<mode>_srl"
6900 [(set (match_operand:GPR 0 "register_operand" "=d")
6901 (and:GPR (lshiftrt:GPR
6902 (match_operand:GPR 1 "register_operand" "d")
6903 (match_operand:GPR 2 "nonzero_shift_count_operand" ""))
6904 (match_operand:GPR 3 "contiguous_bitmask_operand" "")))
6905 (clobber (reg:CC CC_REGNUM))]
6906 "TARGET_Z10
6907 /* Note that even for the SImode pattern, the rotate is always DImode. */
6908 && s390_extzv_shift_ok (<bitsize>, -INTVAL (operands[2]),
6909 INTVAL (operands[3]))"
6910 "risbg\t%0,%1,%<bfstart>3,128+%<bfend>3,64-%2"
6911 [(set_attr "op_type" "RIE")
6912 (set_attr "z10prop" "z10_super_E1")])
6913
6914 (define_insn "*extzv_<mode>_sll"
6915 [(set (match_operand:GPR 0 "register_operand" "=d")
6916 (and:GPR (ashift:GPR
6917 (match_operand:GPR 1 "register_operand" "d")
6918 (match_operand:GPR 2 "nonzero_shift_count_operand" ""))
6919 (match_operand:GPR 3 "contiguous_bitmask_operand" "")))
6920 (clobber (reg:CC CC_REGNUM))]
6921 "TARGET_Z10
6922 && s390_extzv_shift_ok (<bitsize>, INTVAL (operands[2]),
6923 INTVAL (operands[3]))"
6924 "risbg\t%0,%1,%<bfstart>3,128+%<bfend>3,%2"
6925 [(set_attr "op_type" "RIE")
6926 (set_attr "z10prop" "z10_super_E1")])
6927
6928
6929 ;
6930 ; andsi3 instruction pattern(s).
6931 ;
6932
6933 (define_insn "*andsi3_cc"
6934 [(set (reg CC_REGNUM)
6935 (compare
6936 (and:SI
6937 (match_operand:SI 1 "nonimmediate_operand" "%0,0,d,0,0, d")
6938 (match_operand:SI 2 "general_operand" "Os,d,d,R,T,NxxSq"))
6939 (const_int 0)))
6940 (set (match_operand:SI 0 "register_operand" "=d,d,d,d,d, d")
6941 (and:SI (match_dup 1) (match_dup 2)))]
6942 "s390_match_ccmode(insn, CCTmode)"
6943 "@
6944 nilf\t%0,%o2
6945 nr\t%0,%2
6946 nrk\t%0,%1,%2
6947 n\t%0,%2
6948 ny\t%0,%2
6949 risbg\t%0,%1,%t2,128+%f2,0"
6950 [(set_attr "op_type" "RIL,RR,RRF,RX,RXY,RIE")
6951 (set_attr "cpu_facility" "*,*,z196,*,*,z10")
6952 (set_attr "z10prop" "z10_super_E1,z10_super_E1,*,
6953 z10_super_E1,z10_super_E1,z10_super_E1")])
6954
6955 (define_insn "*andsi3_cconly"
6956 [(set (reg CC_REGNUM)
6957 (compare
6958 (and:SI
6959 (match_operand:SI 1 "nonimmediate_operand" "%0,0,d,0,0, d")
6960 (match_operand:SI 2 "general_operand" "Os,d,d,R,T,NxxSq"))
6961 (const_int 0)))
6962 (clobber (match_scratch:SI 0 "=d,d,d,d,d, d"))]
6963 "s390_match_ccmode(insn, CCTmode)
6964 /* Do not steal TM patterns. */
6965 && s390_single_part (operands[2], SImode, HImode, 0) < 0"
6966 "@
6967 nilf\t%0,%o2
6968 nr\t%0,%2
6969 nrk\t%0,%1,%2
6970 n\t%0,%2
6971 ny\t%0,%2
6972 risbg\t%0,%1,%t2,128+%f2,0"
6973 [(set_attr "op_type" "RIL,RR,RRF,RX,RXY,RIE")
6974 (set_attr "cpu_facility" "*,*,z196,*,*,z10")
6975 (set_attr "z10prop" "z10_super_E1,z10_super_E1,*,
6976 z10_super_E1,z10_super_E1,z10_super_E1")])
6977
6978 (define_insn "*andsi3_zarch"
6979 [(set (match_operand:SI 0 "nonimmediate_operand"
6980 "=d,d, d, d, d,d,d,d,d, d, AQ,Q")
6981 (and:SI (match_operand:SI 1 "nonimmediate_operand"
6982 "%d,o, 0, 0, 0,0,d,0,0, d, 0,0")
6983 (match_operand:SI 2 "general_operand"
6984 " M,M,N0HSF,N1HSF,Os,d,d,R,T,NxxSq,NxQSF,Q")))
6985 (clobber (reg:CC CC_REGNUM))]
6986 "TARGET_ZARCH && s390_logical_operator_ok_p (operands)"
6987 "@
6988 #
6989 #
6990 nilh\t%0,%j2
6991 nill\t%0,%j2
6992 nilf\t%0,%o2
6993 nr\t%0,%2
6994 nrk\t%0,%1,%2
6995 n\t%0,%2
6996 ny\t%0,%2
6997 risbg\t%0,%1,%t2,128+%f2,0
6998 #
6999 #"
7000 [(set_attr "op_type" "RRE,RXE,RI,RI,RIL,RR,RRF,RX,RXY,RIE,SI,SS")
7001 (set_attr "cpu_facility" "*,*,*,*,*,*,z196,*,*,z10,*,*")
7002 (set_attr "z10prop" "*,
7003 *,
7004 z10_super_E1,
7005 z10_super_E1,
7006 z10_super_E1,
7007 z10_super_E1,
7008 *,
7009 z10_super_E1,
7010 z10_super_E1,
7011 z10_super_E1,
7012 *,
7013 *")])
7014
7015 (define_insn "*andsi3_esa"
7016 [(set (match_operand:SI 0 "nonimmediate_operand" "=d,d, AQ,Q")
7017 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0, 0,0")
7018 (match_operand:SI 2 "general_operand" " d,R,NxQSF,Q")))
7019 (clobber (reg:CC CC_REGNUM))]
7020 "!TARGET_ZARCH && s390_logical_operator_ok_p (operands)"
7021 "@
7022 nr\t%0,%2
7023 n\t%0,%2
7024 #
7025 #"
7026 [(set_attr "op_type" "RR,RX,SI,SS")
7027 (set_attr "z10prop" "z10_super_E1,z10_super_E1,*,*")])
7028
7029
7030 (define_split
7031 [(set (match_operand:SI 0 "s_operand" "")
7032 (and:SI (match_dup 0) (match_operand:SI 1 "immediate_operand" "")))
7033 (clobber (reg:CC CC_REGNUM))]
7034 "reload_completed"
7035 [(parallel
7036 [(set (match_dup 0) (and:QI (match_dup 0) (match_dup 1)))
7037 (clobber (reg:CC CC_REGNUM))])]
7038 "s390_narrow_logical_operator (AND, &operands[0], &operands[1]);")
7039
7040 ;
7041 ; andhi3 instruction pattern(s).
7042 ;
7043
7044 (define_insn "*andhi3_zarch"
7045 [(set (match_operand:HI 0 "nonimmediate_operand" "=d,d,d, AQ,Q")
7046 (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,d,0, 0,0")
7047 (match_operand:HI 2 "general_operand" " d,d,n,NxQHF,Q")))
7048 (clobber (reg:CC CC_REGNUM))]
7049 "TARGET_ZARCH && s390_logical_operator_ok_p (operands)"
7050 "@
7051 nr\t%0,%2
7052 nrk\t%0,%1,%2
7053 nill\t%0,%x2
7054 #
7055 #"
7056 [(set_attr "op_type" "RR,RRF,RI,SI,SS")
7057 (set_attr "cpu_facility" "*,z196,*,*,*")
7058 (set_attr "z10prop" "z10_super_E1,*,z10_super_E1,*,*")
7059 ])
7060
7061 (define_insn "*andhi3_esa"
7062 [(set (match_operand:HI 0 "nonimmediate_operand" "=d,AQ,Q")
7063 (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,0")
7064 (match_operand:HI 2 "general_operand" "d,NxQHF,Q")))
7065 (clobber (reg:CC CC_REGNUM))]
7066 "!TARGET_ZARCH && s390_logical_operator_ok_p (operands)"
7067 "@
7068 nr\t%0,%2
7069 #
7070 #"
7071 [(set_attr "op_type" "RR,SI,SS")
7072 (set_attr "z10prop" "z10_super_E1,*,*")
7073 ])
7074
7075 (define_split
7076 [(set (match_operand:HI 0 "s_operand" "")
7077 (and:HI (match_dup 0) (match_operand:HI 1 "immediate_operand" "")))
7078 (clobber (reg:CC CC_REGNUM))]
7079 "reload_completed"
7080 [(parallel
7081 [(set (match_dup 0) (and:QI (match_dup 0) (match_dup 1)))
7082 (clobber (reg:CC CC_REGNUM))])]
7083 "s390_narrow_logical_operator (AND, &operands[0], &operands[1]);")
7084
7085 ;
7086 ; andqi3 instruction pattern(s).
7087 ;
7088
7089 (define_insn "*andqi3_zarch"
7090 [(set (match_operand:QI 0 "nonimmediate_operand" "=d,d,d,Q,S,Q")
7091 (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,d,0,0,0,0")
7092 (match_operand:QI 2 "general_operand" " d,d,n,n,n,Q")))
7093 (clobber (reg:CC CC_REGNUM))]
7094 "TARGET_ZARCH && s390_logical_operator_ok_p (operands)"
7095 "@
7096 nr\t%0,%2
7097 nrk\t%0,%1,%2
7098 nill\t%0,%b2
7099 ni\t%S0,%b2
7100 niy\t%S0,%b2
7101 #"
7102 [(set_attr "op_type" "RR,RRF,RI,SI,SIY,SS")
7103 (set_attr "cpu_facility" "*,z196,*,*,*,*")
7104 (set_attr "z10prop" "z10_super_E1,*,z10_super_E1,z10_super,z10_super,*")])
7105
7106 (define_insn "*andqi3_esa"
7107 [(set (match_operand:QI 0 "nonimmediate_operand" "=d,Q,Q")
7108 (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
7109 (match_operand:QI 2 "general_operand" "d,n,Q")))
7110 (clobber (reg:CC CC_REGNUM))]
7111 "!TARGET_ZARCH && s390_logical_operator_ok_p (operands)"
7112 "@
7113 nr\t%0,%2
7114 ni\t%S0,%b2
7115 #"
7116 [(set_attr "op_type" "RR,SI,SS")
7117 (set_attr "z10prop" "z10_super_E1,z10_super,*")])
7118
7119 ;
7120 ; Block and (NC) patterns.
7121 ;
7122
7123 (define_insn "*nc"
7124 [(set (match_operand:BLK 0 "memory_operand" "=Q")
7125 (and:BLK (match_dup 0)
7126 (match_operand:BLK 1 "memory_operand" "Q")))
7127 (use (match_operand 2 "const_int_operand" "n"))
7128 (clobber (reg:CC CC_REGNUM))]
7129 "INTVAL (operands[2]) >= 1 && INTVAL (operands[2]) <= 256"
7130 "nc\t%O0(%2,%R0),%S1"
7131 [(set_attr "op_type" "SS")
7132 (set_attr "z196prop" "z196_cracked")])
7133
7134 (define_split
7135 [(set (match_operand 0 "memory_operand" "")
7136 (and (match_dup 0)
7137 (match_operand 1 "memory_operand" "")))
7138 (clobber (reg:CC CC_REGNUM))]
7139 "reload_completed
7140 && GET_MODE (operands[0]) == GET_MODE (operands[1])
7141 && GET_MODE_SIZE (GET_MODE (operands[0])) > 0"
7142 [(parallel
7143 [(set (match_dup 0) (and:BLK (match_dup 0) (match_dup 1)))
7144 (use (match_dup 2))
7145 (clobber (reg:CC CC_REGNUM))])]
7146 {
7147 operands[2] = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[0])));
7148 operands[0] = adjust_address (operands[0], BLKmode, 0);
7149 operands[1] = adjust_address (operands[1], BLKmode, 0);
7150 })
7151
7152 (define_peephole2
7153 [(parallel
7154 [(set (match_operand:BLK 0 "memory_operand" "")
7155 (and:BLK (match_dup 0)
7156 (match_operand:BLK 1 "memory_operand" "")))
7157 (use (match_operand 2 "const_int_operand" ""))
7158 (clobber (reg:CC CC_REGNUM))])
7159 (parallel
7160 [(set (match_operand:BLK 3 "memory_operand" "")
7161 (and:BLK (match_dup 3)
7162 (match_operand:BLK 4 "memory_operand" "")))
7163 (use (match_operand 5 "const_int_operand" ""))
7164 (clobber (reg:CC CC_REGNUM))])]
7165 "s390_offset_p (operands[0], operands[3], operands[2])
7166 && s390_offset_p (operands[1], operands[4], operands[2])
7167 && !s390_overlap_p (operands[0], operands[1],
7168 INTVAL (operands[2]) + INTVAL (operands[5]))
7169 && INTVAL (operands[2]) + INTVAL (operands[5]) <= 256"
7170 [(parallel
7171 [(set (match_dup 6) (and:BLK (match_dup 6) (match_dup 7)))
7172 (use (match_dup 8))
7173 (clobber (reg:CC CC_REGNUM))])]
7174 "operands[6] = gen_rtx_MEM (BLKmode, XEXP (operands[0], 0));
7175 operands[7] = gen_rtx_MEM (BLKmode, XEXP (operands[1], 0));
7176 operands[8] = GEN_INT (INTVAL (operands[2]) + INTVAL (operands[5]));")
7177
7178
7179 ;;
7180 ;;- Bit set (inclusive or) instructions.
7181 ;;
7182
7183 (define_expand "ior<mode>3"
7184 [(set (match_operand:INT 0 "nonimmediate_operand" "")
7185 (ior:INT (match_operand:INT 1 "nonimmediate_operand" "")
7186 (match_operand:INT 2 "general_operand" "")))
7187 (clobber (reg:CC CC_REGNUM))]
7188 ""
7189 "s390_expand_logical_operator (IOR, <MODE>mode, operands); DONE;")
7190
7191 ;
7192 ; iordi3 instruction pattern(s).
7193 ;
7194
7195 (define_insn "*iordi3_cc"
7196 [(set (reg CC_REGNUM)
7197 (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,d, 0")
7198 (match_operand:DI 2 "general_operand" " d,d,RT"))
7199 (const_int 0)))
7200 (set (match_operand:DI 0 "register_operand" "=d,d, d")
7201 (ior:DI (match_dup 1) (match_dup 2)))]
7202 "s390_match_ccmode(insn, CCTmode) && TARGET_ZARCH"
7203 "@
7204 ogr\t%0,%2
7205 ogrk\t%0,%1,%2
7206 og\t%0,%2"
7207 [(set_attr "op_type" "RRE,RRF,RXY")
7208 (set_attr "cpu_facility" "*,z196,*")
7209 (set_attr "z10prop" "z10_super_E1,*,z10_super_E1")])
7210
7211 (define_insn "*iordi3_cconly"
7212 [(set (reg CC_REGNUM)
7213 (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,d,0")
7214 (match_operand:DI 2 "general_operand" " d,d,RT"))
7215 (const_int 0)))
7216 (clobber (match_scratch:DI 0 "=d,d,d"))]
7217 "s390_match_ccmode(insn, CCTmode) && TARGET_ZARCH"
7218 "@
7219 ogr\t%0,%2
7220 ogrk\t%0,%1,%2
7221 og\t%0,%2"
7222 [(set_attr "op_type" "RRE,RRF,RXY")
7223 (set_attr "cpu_facility" "*,z196,*")
7224 (set_attr "z10prop" "z10_super_E1,*,z10_super_E1")])
7225
7226 (define_insn "*iordi3"
7227 [(set (match_operand:DI 0 "nonimmediate_operand"
7228 "=d, d, d, d, d, d,d,d, d, AQ,Q")
7229 (ior:DI (match_operand:DI 1 "nonimmediate_operand"
7230 " %0, 0, 0, 0, 0, 0,0,d, 0, 0,0")
7231 (match_operand:DI 2 "general_operand"
7232 "N0HD0,N1HD0,N2HD0,N3HD0,N0SD0,N1SD0,d,d,RT,NxQD0,Q")))
7233 (clobber (reg:CC CC_REGNUM))]
7234 "TARGET_ZARCH && s390_logical_operator_ok_p (operands)"
7235 "@
7236 oihh\t%0,%i2
7237 oihl\t%0,%i2
7238 oilh\t%0,%i2
7239 oill\t%0,%i2
7240 oihf\t%0,%k2
7241 oilf\t%0,%k2
7242 ogr\t%0,%2
7243 ogrk\t%0,%1,%2
7244 og\t%0,%2
7245 #
7246 #"
7247 [(set_attr "op_type" "RI,RI,RI,RI,RIL,RIL,RRE,RRF,RXY,SI,SS")
7248 (set_attr "cpu_facility" "*,*,*,*,extimm,extimm,*,z196,*,*,*")
7249 (set_attr "z10prop" "z10_super_E1,
7250 z10_super_E1,
7251 z10_super_E1,
7252 z10_super_E1,
7253 z10_super_E1,
7254 z10_super_E1,
7255 z10_super_E1,
7256 *,
7257 z10_super_E1,
7258 *,
7259 *")])
7260
7261 (define_split
7262 [(set (match_operand:DI 0 "s_operand" "")
7263 (ior:DI (match_dup 0) (match_operand:DI 1 "immediate_operand" "")))
7264 (clobber (reg:CC CC_REGNUM))]
7265 "reload_completed"
7266 [(parallel
7267 [(set (match_dup 0) (ior:QI (match_dup 0) (match_dup 1)))
7268 (clobber (reg:CC CC_REGNUM))])]
7269 "s390_narrow_logical_operator (IOR, &operands[0], &operands[1]);")
7270
7271 ;
7272 ; iorsi3 instruction pattern(s).
7273 ;
7274
7275 (define_insn "*iorsi3_cc"
7276 [(set (reg CC_REGNUM)
7277 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,d,0,0")
7278 (match_operand:SI 2 "general_operand" "Os,d,d,R,T"))
7279 (const_int 0)))
7280 (set (match_operand:SI 0 "register_operand" "=d,d,d,d,d")
7281 (ior:SI (match_dup 1) (match_dup 2)))]
7282 "s390_match_ccmode(insn, CCTmode)"
7283 "@
7284 oilf\t%0,%o2
7285 or\t%0,%2
7286 ork\t%0,%1,%2
7287 o\t%0,%2
7288 oy\t%0,%2"
7289 [(set_attr "op_type" "RIL,RR,RRF,RX,RXY")
7290 (set_attr "cpu_facility" "*,*,z196,*,*")
7291 (set_attr "z10prop" "z10_super_E1,z10_super_E1,*,z10_super_E1,z10_super_E1")])
7292
7293 (define_insn "*iorsi3_cconly"
7294 [(set (reg CC_REGNUM)
7295 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,d,0,0")
7296 (match_operand:SI 2 "general_operand" "Os,d,d,R,T"))
7297 (const_int 0)))
7298 (clobber (match_scratch:SI 0 "=d,d,d,d,d"))]
7299 "s390_match_ccmode(insn, CCTmode)"
7300 "@
7301 oilf\t%0,%o2
7302 or\t%0,%2
7303 ork\t%0,%1,%2
7304 o\t%0,%2
7305 oy\t%0,%2"
7306 [(set_attr "op_type" "RIL,RR,RRF,RX,RXY")
7307 (set_attr "cpu_facility" "*,*,z196,*,*")
7308 (set_attr "z10prop" "z10_super_E1,z10_super_E1,*,z10_super_E1,z10_super_E1")])
7309
7310 (define_insn "*iorsi3_zarch"
7311 [(set (match_operand:SI 0 "nonimmediate_operand" "=d, d, d,d,d,d,d, AQ,Q")
7312 (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0, 0, 0,0,d,0,0, 0,0")
7313 (match_operand:SI 2 "general_operand" "N0HS0,N1HS0,Os,d,d,R,T,NxQS0,Q")))
7314 (clobber (reg:CC CC_REGNUM))]
7315 "TARGET_ZARCH && s390_logical_operator_ok_p (operands)"
7316 "@
7317 oilh\t%0,%i2
7318 oill\t%0,%i2
7319 oilf\t%0,%o2
7320 or\t%0,%2
7321 ork\t%0,%1,%2
7322 o\t%0,%2
7323 oy\t%0,%2
7324 #
7325 #"
7326 [(set_attr "op_type" "RI,RI,RIL,RR,RRF,RX,RXY,SI,SS")
7327 (set_attr "cpu_facility" "*,*,*,*,z196,*,*,*,*")
7328 (set_attr "z10prop" "z10_super_E1,
7329 z10_super_E1,
7330 z10_super_E1,
7331 z10_super_E1,
7332 *,
7333 z10_super_E1,
7334 z10_super_E1,
7335 *,
7336 *")])
7337
7338 (define_insn "*iorsi3_esa"
7339 [(set (match_operand:SI 0 "nonimmediate_operand" "=d,d,AQ,Q")
7340 (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,0,0")
7341 (match_operand:SI 2 "general_operand" "d,R,NxQS0,Q")))
7342 (clobber (reg:CC CC_REGNUM))]
7343 "!TARGET_ZARCH && s390_logical_operator_ok_p (operands)"
7344 "@
7345 or\t%0,%2
7346 o\t%0,%2
7347 #
7348 #"
7349 [(set_attr "op_type" "RR,RX,SI,SS")
7350 (set_attr "z10prop" "z10_super_E1,z10_super_E1,*,*")])
7351
7352 (define_split
7353 [(set (match_operand:SI 0 "s_operand" "")
7354 (ior:SI (match_dup 0) (match_operand:SI 1 "immediate_operand" "")))
7355 (clobber (reg:CC CC_REGNUM))]
7356 "reload_completed"
7357 [(parallel
7358 [(set (match_dup 0) (ior:QI (match_dup 0) (match_dup 1)))
7359 (clobber (reg:CC CC_REGNUM))])]
7360 "s390_narrow_logical_operator (IOR, &operands[0], &operands[1]);")
7361
7362 ;
7363 ; iorhi3 instruction pattern(s).
7364 ;
7365
7366 (define_insn "*iorhi3_zarch"
7367 [(set (match_operand:HI 0 "nonimmediate_operand" "=d,d,d, AQ,Q")
7368 (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,d,0, 0,0")
7369 (match_operand:HI 2 "general_operand" " d,d,n,NxQH0,Q")))
7370 (clobber (reg:CC CC_REGNUM))]
7371 "TARGET_ZARCH && s390_logical_operator_ok_p (operands)"
7372 "@
7373 or\t%0,%2
7374 ork\t%0,%1,%2
7375 oill\t%0,%x2
7376 #
7377 #"
7378 [(set_attr "op_type" "RR,RRF,RI,SI,SS")
7379 (set_attr "cpu_facility" "*,z196,*,*,*")
7380 (set_attr "z10prop" "z10_super_E1,*,z10_super_E1,*,*")])
7381
7382 (define_insn "*iorhi3_esa"
7383 [(set (match_operand:HI 0 "nonimmediate_operand" "=d,AQ,Q")
7384 (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,0")
7385 (match_operand:HI 2 "general_operand" "d,NxQH0,Q")))
7386 (clobber (reg:CC CC_REGNUM))]
7387 "!TARGET_ZARCH && s390_logical_operator_ok_p (operands)"
7388 "@
7389 or\t%0,%2
7390 #
7391 #"
7392 [(set_attr "op_type" "RR,SI,SS")
7393 (set_attr "z10prop" "z10_super_E1,*,*")])
7394
7395 (define_split
7396 [(set (match_operand:HI 0 "s_operand" "")
7397 (ior:HI (match_dup 0) (match_operand:HI 1 "immediate_operand" "")))
7398 (clobber (reg:CC CC_REGNUM))]
7399 "reload_completed"
7400 [(parallel
7401 [(set (match_dup 0) (ior:QI (match_dup 0) (match_dup 1)))
7402 (clobber (reg:CC CC_REGNUM))])]
7403 "s390_narrow_logical_operator (IOR, &operands[0], &operands[1]);")
7404
7405 ;
7406 ; iorqi3 instruction pattern(s).
7407 ;
7408
7409 (define_insn "*iorqi3_zarch"
7410 [(set (match_operand:QI 0 "nonimmediate_operand" "=d,d,d,Q,S,Q")
7411 (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,d,0,0,0,0")
7412 (match_operand:QI 2 "general_operand" " d,d,n,n,n,Q")))
7413 (clobber (reg:CC CC_REGNUM))]
7414 "TARGET_ZARCH && s390_logical_operator_ok_p (operands)"
7415 "@
7416 or\t%0,%2
7417 ork\t%0,%1,%2
7418 oill\t%0,%b2
7419 oi\t%S0,%b2
7420 oiy\t%S0,%b2
7421 #"
7422 [(set_attr "op_type" "RR,RRF,RI,SI,SIY,SS")
7423 (set_attr "cpu_facility" "*,z196,*,*,*,*")
7424 (set_attr "z10prop" "z10_super_E1,*,z10_super_E1,
7425 z10_super,z10_super,*")])
7426
7427 (define_insn "*iorqi3_esa"
7428 [(set (match_operand:QI 0 "nonimmediate_operand" "=d,Q,Q")
7429 (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
7430 (match_operand:QI 2 "general_operand" "d,n,Q")))
7431 (clobber (reg:CC CC_REGNUM))]
7432 "!TARGET_ZARCH && s390_logical_operator_ok_p (operands)"
7433 "@
7434 or\t%0,%2
7435 oi\t%S0,%b2
7436 #"
7437 [(set_attr "op_type" "RR,SI,SS")
7438 (set_attr "z10prop" "z10_super_E1,z10_super,*")])
7439
7440 ;
7441 ; Block inclusive or (OC) patterns.
7442 ;
7443
7444 (define_insn "*oc"
7445 [(set (match_operand:BLK 0 "memory_operand" "=Q")
7446 (ior:BLK (match_dup 0)
7447 (match_operand:BLK 1 "memory_operand" "Q")))
7448 (use (match_operand 2 "const_int_operand" "n"))
7449 (clobber (reg:CC CC_REGNUM))]
7450 "INTVAL (operands[2]) >= 1 && INTVAL (operands[2]) <= 256"
7451 "oc\t%O0(%2,%R0),%S1"
7452 [(set_attr "op_type" "SS")
7453 (set_attr "z196prop" "z196_cracked")])
7454
7455 (define_split
7456 [(set (match_operand 0 "memory_operand" "")
7457 (ior (match_dup 0)
7458 (match_operand 1 "memory_operand" "")))
7459 (clobber (reg:CC CC_REGNUM))]
7460 "reload_completed
7461 && GET_MODE (operands[0]) == GET_MODE (operands[1])
7462 && GET_MODE_SIZE (GET_MODE (operands[0])) > 0"
7463 [(parallel
7464 [(set (match_dup 0) (ior:BLK (match_dup 0) (match_dup 1)))
7465 (use (match_dup 2))
7466 (clobber (reg:CC CC_REGNUM))])]
7467 {
7468 operands[2] = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[0])));
7469 operands[0] = adjust_address (operands[0], BLKmode, 0);
7470 operands[1] = adjust_address (operands[1], BLKmode, 0);
7471 })
7472
7473 (define_peephole2
7474 [(parallel
7475 [(set (match_operand:BLK 0 "memory_operand" "")
7476 (ior:BLK (match_dup 0)
7477 (match_operand:BLK 1 "memory_operand" "")))
7478 (use (match_operand 2 "const_int_operand" ""))
7479 (clobber (reg:CC CC_REGNUM))])
7480 (parallel
7481 [(set (match_operand:BLK 3 "memory_operand" "")
7482 (ior:BLK (match_dup 3)
7483 (match_operand:BLK 4 "memory_operand" "")))
7484 (use (match_operand 5 "const_int_operand" ""))
7485 (clobber (reg:CC CC_REGNUM))])]
7486 "s390_offset_p (operands[0], operands[3], operands[2])
7487 && s390_offset_p (operands[1], operands[4], operands[2])
7488 && !s390_overlap_p (operands[0], operands[1],
7489 INTVAL (operands[2]) + INTVAL (operands[5]))
7490 && INTVAL (operands[2]) + INTVAL (operands[5]) <= 256"
7491 [(parallel
7492 [(set (match_dup 6) (ior:BLK (match_dup 6) (match_dup 7)))
7493 (use (match_dup 8))
7494 (clobber (reg:CC CC_REGNUM))])]
7495 "operands[6] = gen_rtx_MEM (BLKmode, XEXP (operands[0], 0));
7496 operands[7] = gen_rtx_MEM (BLKmode, XEXP (operands[1], 0));
7497 operands[8] = GEN_INT (INTVAL (operands[2]) + INTVAL (operands[5]));")
7498
7499
7500 ;;
7501 ;;- Xor instructions.
7502 ;;
7503
7504 (define_expand "xor<mode>3"
7505 [(set (match_operand:INT 0 "nonimmediate_operand" "")
7506 (xor:INT (match_operand:INT 1 "nonimmediate_operand" "")
7507 (match_operand:INT 2 "general_operand" "")))
7508 (clobber (reg:CC CC_REGNUM))]
7509 ""
7510 "s390_expand_logical_operator (XOR, <MODE>mode, operands); DONE;")
7511
7512 ; Combine replaces (xor (x) (const_int -1)) with (not (x)) when doing
7513 ; simplifications. So its better to have something matching.
7514 (define_split
7515 [(set (match_operand:INT 0 "nonimmediate_operand" "")
7516 (not:INT (match_operand:INT 1 "nonimmediate_operand" "")))]
7517 ""
7518 [(parallel
7519 [(set (match_dup 0) (xor:INT (match_dup 1) (match_dup 2)))
7520 (clobber (reg:CC CC_REGNUM))])]
7521 {
7522 operands[2] = constm1_rtx;
7523 if (!s390_logical_operator_ok_p (operands))
7524 FAIL;
7525 })
7526
7527 ;
7528 ; xordi3 instruction pattern(s).
7529 ;
7530
7531 (define_insn "*xordi3_cc"
7532 [(set (reg CC_REGNUM)
7533 (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,d, 0")
7534 (match_operand:DI 2 "general_operand" " d,d,RT"))
7535 (const_int 0)))
7536 (set (match_operand:DI 0 "register_operand" "=d,d, d")
7537 (xor:DI (match_dup 1) (match_dup 2)))]
7538 "s390_match_ccmode(insn, CCTmode) && TARGET_ZARCH"
7539 "@
7540 xgr\t%0,%2
7541 xgrk\t%0,%1,%2
7542 xg\t%0,%2"
7543 [(set_attr "op_type" "RRE,RRF,RXY")
7544 (set_attr "cpu_facility" "*,z196,*")
7545 (set_attr "z10prop" "z10_super_E1,*,z10_super_E1")])
7546
7547 (define_insn "*xordi3_cconly"
7548 [(set (reg CC_REGNUM)
7549 (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,d, 0")
7550 (match_operand:DI 2 "general_operand" " d,d,RT"))
7551 (const_int 0)))
7552 (clobber (match_scratch:DI 0 "=d,d, d"))]
7553 "s390_match_ccmode(insn, CCTmode) && TARGET_ZARCH"
7554 "@
7555 xgr\t%0,%2
7556 xgrk\t%0,%1,%2
7557 xg\t%0,%2"
7558 [(set_attr "op_type" "RRE,RRF,RXY")
7559 (set_attr "cpu_facility" "*,z196,*")
7560 (set_attr "z10prop" "z10_super_E1,*,z10_super_E1")])
7561
7562 (define_insn "*xordi3"
7563 [(set (match_operand:DI 0 "nonimmediate_operand" "=d, d,d,d, d, AQ,Q")
7564 (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0, 0,0,d, 0, 0,0")
7565 (match_operand:DI 2 "general_operand" "N0SD0,N1SD0,d,d,RT,NxQD0,Q")))
7566 (clobber (reg:CC CC_REGNUM))]
7567 "TARGET_ZARCH && s390_logical_operator_ok_p (operands)"
7568 "@
7569 xihf\t%0,%k2
7570 xilf\t%0,%k2
7571 xgr\t%0,%2
7572 xgrk\t%0,%1,%2
7573 xg\t%0,%2
7574 #
7575 #"
7576 [(set_attr "op_type" "RIL,RIL,RRE,RRF,RXY,SI,SS")
7577 (set_attr "cpu_facility" "extimm,extimm,*,z196,*,*,*")
7578 (set_attr "z10prop" "z10_super_E1,z10_super_E1,z10_super_E1,
7579 *,z10_super_E1,*,*")])
7580
7581 (define_split
7582 [(set (match_operand:DI 0 "s_operand" "")
7583 (xor:DI (match_dup 0) (match_operand:DI 1 "immediate_operand" "")))
7584 (clobber (reg:CC CC_REGNUM))]
7585 "reload_completed"
7586 [(parallel
7587 [(set (match_dup 0) (xor:QI (match_dup 0) (match_dup 1)))
7588 (clobber (reg:CC CC_REGNUM))])]
7589 "s390_narrow_logical_operator (XOR, &operands[0], &operands[1]);")
7590
7591 ;
7592 ; xorsi3 instruction pattern(s).
7593 ;
7594
7595 (define_insn "*xorsi3_cc"
7596 [(set (reg CC_REGNUM)
7597 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,d,0,0")
7598 (match_operand:SI 2 "general_operand" "Os,d,d,R,T"))
7599 (const_int 0)))
7600 (set (match_operand:SI 0 "register_operand" "=d,d,d,d,d")
7601 (xor:SI (match_dup 1) (match_dup 2)))]
7602 "s390_match_ccmode(insn, CCTmode)"
7603 "@
7604 xilf\t%0,%o2
7605 xr\t%0,%2
7606 xrk\t%0,%1,%2
7607 x\t%0,%2
7608 xy\t%0,%2"
7609 [(set_attr "op_type" "RIL,RR,RRF,RX,RXY")
7610 (set_attr "cpu_facility" "*,*,z196,*,*")
7611 (set_attr "z10prop" "z10_super_E1,z10_super_E1,*,
7612 z10_super_E1,z10_super_E1")])
7613
7614 (define_insn "*xorsi3_cconly"
7615 [(set (reg CC_REGNUM)
7616 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,d,0,0")
7617 (match_operand:SI 2 "general_operand" "Os,d,d,R,T"))
7618 (const_int 0)))
7619 (clobber (match_scratch:SI 0 "=d,d,d,d,d"))]
7620 "s390_match_ccmode(insn, CCTmode)"
7621 "@
7622 xilf\t%0,%o2
7623 xr\t%0,%2
7624 xrk\t%0,%1,%2
7625 x\t%0,%2
7626 xy\t%0,%2"
7627 [(set_attr "op_type" "RIL,RR,RRF,RX,RXY")
7628 (set_attr "cpu_facility" "*,*,z196,*,*")
7629 (set_attr "z10prop" "z10_super_E1,z10_super_E1,*,
7630 z10_super_E1,z10_super_E1")])
7631
7632 (define_insn "*xorsi3"
7633 [(set (match_operand:SI 0 "nonimmediate_operand" "=d,d,d,d,d, AQ,Q")
7634 (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,d,0,0, 0,0")
7635 (match_operand:SI 2 "general_operand" "Os,d,d,R,T,NxQS0,Q")))
7636 (clobber (reg:CC CC_REGNUM))]
7637 "s390_logical_operator_ok_p (operands)"
7638 "@
7639 xilf\t%0,%o2
7640 xr\t%0,%2
7641 xrk\t%0,%1,%2
7642 x\t%0,%2
7643 xy\t%0,%2
7644 #
7645 #"
7646 [(set_attr "op_type" "RIL,RR,RRF,RX,RXY,SI,SS")
7647 (set_attr "cpu_facility" "*,*,z196,*,*,*,*")
7648 (set_attr "z10prop" "z10_super_E1,z10_super_E1,*,
7649 z10_super_E1,z10_super_E1,*,*")])
7650
7651 (define_split
7652 [(set (match_operand:SI 0 "s_operand" "")
7653 (xor:SI (match_dup 0) (match_operand:SI 1 "immediate_operand" "")))
7654 (clobber (reg:CC CC_REGNUM))]
7655 "reload_completed"
7656 [(parallel
7657 [(set (match_dup 0) (xor:QI (match_dup 0) (match_dup 1)))
7658 (clobber (reg:CC CC_REGNUM))])]
7659 "s390_narrow_logical_operator (XOR, &operands[0], &operands[1]);")
7660
7661 ;
7662 ; xorhi3 instruction pattern(s).
7663 ;
7664
7665 (define_insn "*xorhi3"
7666 [(set (match_operand:HI 0 "nonimmediate_operand" "=d,d,d, AQ,Q")
7667 (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,d, 0,0")
7668 (match_operand:HI 2 "general_operand" "Os,d,d,NxQH0,Q")))
7669 (clobber (reg:CC CC_REGNUM))]
7670 "s390_logical_operator_ok_p (operands)"
7671 "@
7672 xilf\t%0,%x2
7673 xr\t%0,%2
7674 xrk\t%0,%1,%2
7675 #
7676 #"
7677 [(set_attr "op_type" "RIL,RR,RRF,SI,SS")
7678 (set_attr "cpu_facility" "*,*,z196,*,*")
7679 (set_attr "z10prop" "z10_super_E1,z10_super_E1,*,*,*")])
7680
7681 (define_split
7682 [(set (match_operand:HI 0 "s_operand" "")
7683 (xor:HI (match_dup 0) (match_operand:HI 1 "immediate_operand" "")))
7684 (clobber (reg:CC CC_REGNUM))]
7685 "reload_completed"
7686 [(parallel
7687 [(set (match_dup 0) (xor:QI (match_dup 0) (match_dup 1)))
7688 (clobber (reg:CC CC_REGNUM))])]
7689 "s390_narrow_logical_operator (XOR, &operands[0], &operands[1]);")
7690
7691 ;
7692 ; xorqi3 instruction pattern(s).
7693 ;
7694
7695 (define_insn "*xorqi3"
7696 [(set (match_operand:QI 0 "nonimmediate_operand" "=d,d,d,Q,S,Q")
7697 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,d,0,0,0")
7698 (match_operand:QI 2 "general_operand" "Os,d,d,n,n,Q")))
7699 (clobber (reg:CC CC_REGNUM))]
7700 "s390_logical_operator_ok_p (operands)"
7701 "@
7702 xilf\t%0,%b2
7703 xr\t%0,%2
7704 xrk\t%0,%1,%2
7705 xi\t%S0,%b2
7706 xiy\t%S0,%b2
7707 #"
7708 [(set_attr "op_type" "RIL,RR,RRF,SI,SIY,SS")
7709 (set_attr "cpu_facility" "*,*,z196,*,*,*")
7710 (set_attr "z10prop" "z10_super_E1,z10_super_E1,*,z10_super,z10_super,*")])
7711
7712
7713 ;
7714 ; Block exclusive or (XC) patterns.
7715 ;
7716
7717 (define_insn "*xc"
7718 [(set (match_operand:BLK 0 "memory_operand" "=Q")
7719 (xor:BLK (match_dup 0)
7720 (match_operand:BLK 1 "memory_operand" "Q")))
7721 (use (match_operand 2 "const_int_operand" "n"))
7722 (clobber (reg:CC CC_REGNUM))]
7723 "INTVAL (operands[2]) >= 1 && INTVAL (operands[2]) <= 256"
7724 "xc\t%O0(%2,%R0),%S1"
7725 [(set_attr "op_type" "SS")])
7726
7727 (define_split
7728 [(set (match_operand 0 "memory_operand" "")
7729 (xor (match_dup 0)
7730 (match_operand 1 "memory_operand" "")))
7731 (clobber (reg:CC CC_REGNUM))]
7732 "reload_completed
7733 && GET_MODE (operands[0]) == GET_MODE (operands[1])
7734 && GET_MODE_SIZE (GET_MODE (operands[0])) > 0"
7735 [(parallel
7736 [(set (match_dup 0) (xor:BLK (match_dup 0) (match_dup 1)))
7737 (use (match_dup 2))
7738 (clobber (reg:CC CC_REGNUM))])]
7739 {
7740 operands[2] = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[0])));
7741 operands[0] = adjust_address (operands[0], BLKmode, 0);
7742 operands[1] = adjust_address (operands[1], BLKmode, 0);
7743 })
7744
7745 (define_peephole2
7746 [(parallel
7747 [(set (match_operand:BLK 0 "memory_operand" "")
7748 (xor:BLK (match_dup 0)
7749 (match_operand:BLK 1 "memory_operand" "")))
7750 (use (match_operand 2 "const_int_operand" ""))
7751 (clobber (reg:CC CC_REGNUM))])
7752 (parallel
7753 [(set (match_operand:BLK 3 "memory_operand" "")
7754 (xor:BLK (match_dup 3)
7755 (match_operand:BLK 4 "memory_operand" "")))
7756 (use (match_operand 5 "const_int_operand" ""))
7757 (clobber (reg:CC CC_REGNUM))])]
7758 "s390_offset_p (operands[0], operands[3], operands[2])
7759 && s390_offset_p (operands[1], operands[4], operands[2])
7760 && !s390_overlap_p (operands[0], operands[1],
7761 INTVAL (operands[2]) + INTVAL (operands[5]))
7762 && INTVAL (operands[2]) + INTVAL (operands[5]) <= 256"
7763 [(parallel
7764 [(set (match_dup 6) (xor:BLK (match_dup 6) (match_dup 7)))
7765 (use (match_dup 8))
7766 (clobber (reg:CC CC_REGNUM))])]
7767 "operands[6] = gen_rtx_MEM (BLKmode, XEXP (operands[0], 0));
7768 operands[7] = gen_rtx_MEM (BLKmode, XEXP (operands[1], 0));
7769 operands[8] = GEN_INT (INTVAL (operands[2]) + INTVAL (operands[5]));")
7770
7771 ;
7772 ; Block xor (XC) patterns with src == dest.
7773 ;
7774
7775 (define_insn "*xc_zero"
7776 [(set (match_operand:BLK 0 "memory_operand" "=Q")
7777 (const_int 0))
7778 (use (match_operand 1 "const_int_operand" "n"))
7779 (clobber (reg:CC CC_REGNUM))]
7780 "INTVAL (operands[1]) >= 1 && INTVAL (operands[1]) <= 256"
7781 "xc\t%O0(%1,%R0),%S0"
7782 [(set_attr "op_type" "SS")
7783 (set_attr "z196prop" "z196_cracked")])
7784
7785 (define_peephole2
7786 [(parallel
7787 [(set (match_operand:BLK 0 "memory_operand" "")
7788 (const_int 0))
7789 (use (match_operand 1 "const_int_operand" ""))
7790 (clobber (reg:CC CC_REGNUM))])
7791 (parallel
7792 [(set (match_operand:BLK 2 "memory_operand" "")
7793 (const_int 0))
7794 (use (match_operand 3 "const_int_operand" ""))
7795 (clobber (reg:CC CC_REGNUM))])]
7796 "s390_offset_p (operands[0], operands[2], operands[1])
7797 && INTVAL (operands[1]) + INTVAL (operands[3]) <= 256"
7798 [(parallel
7799 [(set (match_dup 4) (const_int 0))
7800 (use (match_dup 5))
7801 (clobber (reg:CC CC_REGNUM))])]
7802 "operands[4] = gen_rtx_MEM (BLKmode, XEXP (operands[0], 0));
7803 operands[5] = GEN_INT (INTVAL (operands[1]) + INTVAL (operands[3]));")
7804
7805
7806 ;;
7807 ;;- Negate instructions.
7808 ;;
7809
7810 ;
7811 ; neg(di|si)2 instruction pattern(s).
7812 ;
7813
7814 (define_expand "neg<mode>2"
7815 [(parallel
7816 [(set (match_operand:DSI 0 "register_operand" "=d")
7817 (neg:DSI (match_operand:DSI 1 "register_operand" "d")))
7818 (clobber (reg:CC CC_REGNUM))])]
7819 ""
7820 "")
7821
7822 (define_insn "*negdi2_sign_cc"
7823 [(set (reg CC_REGNUM)
7824 (compare (neg:DI (ashiftrt:DI (ashift:DI (subreg:DI
7825 (match_operand:SI 1 "register_operand" "d") 0)
7826 (const_int 32)) (const_int 32)))
7827 (const_int 0)))
7828 (set (match_operand:DI 0 "register_operand" "=d")
7829 (neg:DI (sign_extend:DI (match_dup 1))))]
7830 "TARGET_ZARCH && s390_match_ccmode (insn, CCAmode)"
7831 "lcgfr\t%0,%1"
7832 [(set_attr "op_type" "RRE")
7833 (set_attr "z10prop" "z10_c")])
7834
7835 (define_insn "*negdi2_sign"
7836 [(set (match_operand:DI 0 "register_operand" "=d")
7837 (neg:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "d"))))
7838 (clobber (reg:CC CC_REGNUM))]
7839 "TARGET_ZARCH"
7840 "lcgfr\t%0,%1"
7841 [(set_attr "op_type" "RRE")
7842 (set_attr "z10prop" "z10_c")])
7843
7844 ; lcr, lcgr
7845 (define_insn "*neg<mode>2_cc"
7846 [(set (reg CC_REGNUM)
7847 (compare (neg:GPR (match_operand:GPR 1 "register_operand" "d"))
7848 (const_int 0)))
7849 (set (match_operand:GPR 0 "register_operand" "=d")
7850 (neg:GPR (match_dup 1)))]
7851 "s390_match_ccmode (insn, CCAmode)"
7852 "lc<g>r\t%0,%1"
7853 [(set_attr "op_type" "RR<E>")
7854 (set_attr "z10prop" "z10_super_c_E1")])
7855
7856 ; lcr, lcgr
7857 (define_insn "*neg<mode>2_cconly"
7858 [(set (reg CC_REGNUM)
7859 (compare (neg:GPR (match_operand:GPR 1 "register_operand" "d"))
7860 (const_int 0)))
7861 (clobber (match_scratch:GPR 0 "=d"))]
7862 "s390_match_ccmode (insn, CCAmode)"
7863 "lc<g>r\t%0,%1"
7864 [(set_attr "op_type" "RR<E>")
7865 (set_attr "z10prop" "z10_super_c_E1")])
7866
7867 ; lcr, lcgr
7868 (define_insn "*neg<mode>2"
7869 [(set (match_operand:GPR 0 "register_operand" "=d")
7870 (neg:GPR (match_operand:GPR 1 "register_operand" "d")))
7871 (clobber (reg:CC CC_REGNUM))]
7872 ""
7873 "lc<g>r\t%0,%1"
7874 [(set_attr "op_type" "RR<E>")
7875 (set_attr "z10prop" "z10_super_c_E1")])
7876
7877 (define_insn "*negdi2_31"
7878 [(set (match_operand:DI 0 "register_operand" "=d")
7879 (neg:DI (match_operand:DI 1 "register_operand" "d")))
7880 (clobber (reg:CC CC_REGNUM))]
7881 "!TARGET_ZARCH"
7882 "#")
7883
7884 ; Split a DImode NEG on 31bit into 2 SImode NEGs
7885
7886 ; Doing the twos complement separately on the SImode parts does an
7887 ; unwanted +1 on the high part which needs to be subtracted afterwards
7888 ; ... unless the +1 on the low part created an overflow.
7889
7890 (define_split
7891 [(set (match_operand:DI 0 "register_operand" "")
7892 (neg:DI (match_operand:DI 1 "register_operand" "")))
7893 (clobber (reg:CC CC_REGNUM))]
7894 "!TARGET_ZARCH
7895 && (REGNO (operands[0]) == REGNO (operands[1])
7896 || s390_split_ok_p (operands[0], operands[1], DImode, 0))
7897 && reload_completed"
7898 [(parallel
7899 [(set (match_dup 2) (neg:SI (match_dup 3)))
7900 (clobber (reg:CC CC_REGNUM))])
7901 (parallel
7902 [(set (reg:CCAP CC_REGNUM)
7903 (compare:CCAP (neg:SI (match_dup 5)) (const_int 0)))
7904 (set (match_dup 4) (neg:SI (match_dup 5)))])
7905 (set (pc)
7906 (if_then_else (ne (reg:CCAP CC_REGNUM) (const_int 0))
7907 (pc)
7908 (label_ref (match_dup 6))))
7909 (parallel
7910 [(set (match_dup 2) (plus:SI (match_dup 2) (const_int -1)))
7911 (clobber (reg:CC CC_REGNUM))])
7912 (match_dup 6)]
7913 "operands[2] = operand_subword (operands[0], 0, 0, DImode);
7914 operands[3] = operand_subword (operands[1], 0, 0, DImode);
7915 operands[4] = operand_subword (operands[0], 1, 0, DImode);
7916 operands[5] = operand_subword (operands[1], 1, 0, DImode);
7917 operands[6] = gen_label_rtx ();")
7918
7919 ; Like above but first make a copy of the low part of the src operand
7920 ; since it might overlap with the high part of the destination.
7921
7922 (define_split
7923 [(set (match_operand:DI 0 "register_operand" "")
7924 (neg:DI (match_operand:DI 1 "register_operand" "")))
7925 (clobber (reg:CC CC_REGNUM))]
7926 "!TARGET_ZARCH
7927 && s390_split_ok_p (operands[0], operands[1], DImode, 1)
7928 && reload_completed"
7929 [; Make a backup of op5 first
7930 (set (match_dup 4) (match_dup 5))
7931 ; Setting op2 here might clobber op5
7932 (parallel
7933 [(set (match_dup 2) (neg:SI (match_dup 3)))
7934 (clobber (reg:CC CC_REGNUM))])
7935 (parallel
7936 [(set (reg:CCAP CC_REGNUM)
7937 (compare:CCAP (neg:SI (match_dup 4)) (const_int 0)))
7938 (set (match_dup 4) (neg:SI (match_dup 4)))])
7939 (set (pc)
7940 (if_then_else (ne (reg:CCAP CC_REGNUM) (const_int 0))
7941 (pc)
7942 (label_ref (match_dup 6))))
7943 (parallel
7944 [(set (match_dup 2) (plus:SI (match_dup 2) (const_int -1)))
7945 (clobber (reg:CC CC_REGNUM))])
7946 (match_dup 6)]
7947 "operands[2] = operand_subword (operands[0], 0, 0, DImode);
7948 operands[3] = operand_subword (operands[1], 0, 0, DImode);
7949 operands[4] = operand_subword (operands[0], 1, 0, DImode);
7950 operands[5] = operand_subword (operands[1], 1, 0, DImode);
7951 operands[6] = gen_label_rtx ();")
7952
7953 ;
7954 ; neg(df|sf)2 instruction pattern(s).
7955 ;
7956
7957 (define_expand "neg<mode>2"
7958 [(parallel
7959 [(set (match_operand:BFP 0 "register_operand" "=f")
7960 (neg:BFP (match_operand:BFP 1 "register_operand" "f")))
7961 (clobber (reg:CC CC_REGNUM))])]
7962 "TARGET_HARD_FLOAT"
7963 "")
7964
7965 ; lcxbr, lcdbr, lcebr
7966 (define_insn "*neg<mode>2_cc"
7967 [(set (reg CC_REGNUM)
7968 (compare (neg:BFP (match_operand:BFP 1 "register_operand" "f"))
7969 (match_operand:BFP 2 "const0_operand" "")))
7970 (set (match_operand:BFP 0 "register_operand" "=f")
7971 (neg:BFP (match_dup 1)))]
7972 "s390_match_ccmode (insn, CCSmode) && TARGET_HARD_FLOAT"
7973 "lc<xde>br\t%0,%1"
7974 [(set_attr "op_type" "RRE")
7975 (set_attr "type" "fsimp<mode>")])
7976
7977 ; lcxbr, lcdbr, lcebr
7978 (define_insn "*neg<mode>2_cconly"
7979 [(set (reg CC_REGNUM)
7980 (compare (neg:BFP (match_operand:BFP 1 "register_operand" "f"))
7981 (match_operand:BFP 2 "const0_operand" "")))
7982 (clobber (match_scratch:BFP 0 "=f"))]
7983 "s390_match_ccmode (insn, CCSmode) && TARGET_HARD_FLOAT"
7984 "lc<xde>br\t%0,%1"
7985 [(set_attr "op_type" "RRE")
7986 (set_attr "type" "fsimp<mode>")])
7987
7988 ; lcdfr
7989 (define_insn "*neg<mode>2_nocc"
7990 [(set (match_operand:FP 0 "register_operand" "=f")
7991 (neg:FP (match_operand:FP 1 "register_operand" "<fT0>")))]
7992 "TARGET_DFP"
7993 "lcdfr\t%0,%1"
7994 [(set_attr "op_type" "RRE")
7995 (set_attr "type" "fsimp<mode>")])
7996
7997 ; lcxbr, lcdbr, lcebr
7998 ; FIXME: wflcdb does not clobber cc
7999 (define_insn "*neg<mode>2"
8000 [(set (match_operand:BFP 0 "register_operand" "=f,<vf>")
8001 (neg:BFP (match_operand:BFP 1 "register_operand" "f,<vf>")))
8002 (clobber (reg:CC CC_REGNUM))]
8003 "TARGET_HARD_FLOAT"
8004 "@
8005 lc<xde>br\t%0,%1
8006 wflcdb\t%0,%1"
8007 [(set_attr "op_type" "RRE,VRR")
8008 (set_attr "cpu_facility" "*,vec")
8009 (set_attr "type" "fsimp<mode>,*")])
8010
8011
8012 ;;
8013 ;;- Absolute value instructions.
8014 ;;
8015
8016 ;
8017 ; abs(di|si)2 instruction pattern(s).
8018 ;
8019
8020 (define_insn "*absdi2_sign_cc"
8021 [(set (reg CC_REGNUM)
8022 (compare (abs:DI (ashiftrt:DI (ashift:DI (subreg:DI
8023 (match_operand:SI 1 "register_operand" "d") 0)
8024 (const_int 32)) (const_int 32)))
8025 (const_int 0)))
8026 (set (match_operand:DI 0 "register_operand" "=d")
8027 (abs:DI (sign_extend:DI (match_dup 1))))]
8028 "TARGET_ZARCH && s390_match_ccmode (insn, CCAmode)"
8029 "lpgfr\t%0,%1"
8030 [(set_attr "op_type" "RRE")
8031 (set_attr "z10prop" "z10_c")])
8032
8033 (define_insn "*absdi2_sign"
8034 [(set (match_operand:DI 0 "register_operand" "=d")
8035 (abs:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "d"))))
8036 (clobber (reg:CC CC_REGNUM))]
8037 "TARGET_ZARCH"
8038 "lpgfr\t%0,%1"
8039 [(set_attr "op_type" "RRE")
8040 (set_attr "z10prop" "z10_c")])
8041
8042 ; lpr, lpgr
8043 (define_insn "*abs<mode>2_cc"
8044 [(set (reg CC_REGNUM)
8045 (compare (abs:GPR (match_operand:DI 1 "register_operand" "d"))
8046 (const_int 0)))
8047 (set (match_operand:GPR 0 "register_operand" "=d")
8048 (abs:GPR (match_dup 1)))]
8049 "s390_match_ccmode (insn, CCAmode)"
8050 "lp<g>r\t%0,%1"
8051 [(set_attr "op_type" "RR<E>")
8052 (set_attr "z10prop" "z10_c")])
8053
8054 ; lpr, lpgr
8055 (define_insn "*abs<mode>2_cconly"
8056 [(set (reg CC_REGNUM)
8057 (compare (abs:GPR (match_operand:GPR 1 "register_operand" "d"))
8058 (const_int 0)))
8059 (clobber (match_scratch:GPR 0 "=d"))]
8060 "s390_match_ccmode (insn, CCAmode)"
8061 "lp<g>r\t%0,%1"
8062 [(set_attr "op_type" "RR<E>")
8063 (set_attr "z10prop" "z10_c")])
8064
8065 ; lpr, lpgr
8066 (define_insn "abs<mode>2"
8067 [(set (match_operand:GPR 0 "register_operand" "=d")
8068 (abs:GPR (match_operand:GPR 1 "register_operand" "d")))
8069 (clobber (reg:CC CC_REGNUM))]
8070 ""
8071 "lp<g>r\t%0,%1"
8072 [(set_attr "op_type" "RR<E>")
8073 (set_attr "z10prop" "z10_c")])
8074
8075 ;
8076 ; abs(df|sf)2 instruction pattern(s).
8077 ;
8078
8079 (define_expand "abs<mode>2"
8080 [(parallel
8081 [(set (match_operand:BFP 0 "register_operand" "=f")
8082 (abs:BFP (match_operand:BFP 1 "register_operand" "f")))
8083 (clobber (reg:CC CC_REGNUM))])]
8084 "TARGET_HARD_FLOAT"
8085 "")
8086
8087 ; lpxbr, lpdbr, lpebr
8088 (define_insn "*abs<mode>2_cc"
8089 [(set (reg CC_REGNUM)
8090 (compare (abs:BFP (match_operand:BFP 1 "register_operand" "f"))
8091 (match_operand:BFP 2 "const0_operand" "")))
8092 (set (match_operand:BFP 0 "register_operand" "=f")
8093 (abs:BFP (match_dup 1)))]
8094 "s390_match_ccmode (insn, CCSmode) && TARGET_HARD_FLOAT"
8095 "lp<xde>br\t%0,%1"
8096 [(set_attr "op_type" "RRE")
8097 (set_attr "type" "fsimp<mode>")])
8098
8099 ; lpxbr, lpdbr, lpebr
8100 (define_insn "*abs<mode>2_cconly"
8101 [(set (reg CC_REGNUM)
8102 (compare (abs:BFP (match_operand:BFP 1 "register_operand" "f"))
8103 (match_operand:BFP 2 "const0_operand" "")))
8104 (clobber (match_scratch:BFP 0 "=f"))]
8105 "s390_match_ccmode (insn, CCSmode) && TARGET_HARD_FLOAT"
8106 "lp<xde>br\t%0,%1"
8107 [(set_attr "op_type" "RRE")
8108 (set_attr "type" "fsimp<mode>")])
8109
8110 ; lpdfr
8111 (define_insn "*abs<mode>2_nocc"
8112 [(set (match_operand:FP 0 "register_operand" "=f")
8113 (abs:FP (match_operand:FP 1 "register_operand" "<fT0>")))]
8114 "TARGET_DFP"
8115 "lpdfr\t%0,%1"
8116 [(set_attr "op_type" "RRE")
8117 (set_attr "type" "fsimp<mode>")])
8118
8119 ; lpxbr, lpdbr, lpebr
8120 ; FIXME: wflpdb does not clobber cc
8121 (define_insn "*abs<mode>2"
8122 [(set (match_operand:BFP 0 "register_operand" "=f,<vf>")
8123 (abs:BFP (match_operand:BFP 1 "register_operand" "f,<vf>")))
8124 (clobber (reg:CC CC_REGNUM))]
8125 "TARGET_HARD_FLOAT"
8126 "@
8127 lp<xde>br\t%0,%1
8128 wflpdb\t%0,%1"
8129 [(set_attr "op_type" "RRE,VRR")
8130 (set_attr "cpu_facility" "*,vec")
8131 (set_attr "type" "fsimp<mode>,*")])
8132
8133
8134 ;;
8135 ;;- Negated absolute value instructions
8136 ;;
8137
8138 ;
8139 ; Integer
8140 ;
8141
8142 (define_insn "*negabsdi2_sign_cc"
8143 [(set (reg CC_REGNUM)
8144 (compare (neg:DI (abs:DI (ashiftrt:DI (ashift:DI (subreg:DI
8145 (match_operand:SI 1 "register_operand" "d") 0)
8146 (const_int 32)) (const_int 32))))
8147 (const_int 0)))
8148 (set (match_operand:DI 0 "register_operand" "=d")
8149 (neg:DI (abs:DI (sign_extend:DI (match_dup 1)))))]
8150 "TARGET_ZARCH && s390_match_ccmode (insn, CCAmode)"
8151 "lngfr\t%0,%1"
8152 [(set_attr "op_type" "RRE")
8153 (set_attr "z10prop" "z10_c")])
8154
8155 (define_insn "*negabsdi2_sign"
8156 [(set (match_operand:DI 0 "register_operand" "=d")
8157 (neg:DI (abs:DI (sign_extend:DI
8158 (match_operand:SI 1 "register_operand" "d")))))
8159 (clobber (reg:CC CC_REGNUM))]
8160 "TARGET_ZARCH"
8161 "lngfr\t%0,%1"
8162 [(set_attr "op_type" "RRE")
8163 (set_attr "z10prop" "z10_c")])
8164
8165 ; lnr, lngr
8166 (define_insn "*negabs<mode>2_cc"
8167 [(set (reg CC_REGNUM)
8168 (compare (neg:GPR (abs:GPR (match_operand:GPR 1 "register_operand" "d")))
8169 (const_int 0)))
8170 (set (match_operand:GPR 0 "register_operand" "=d")
8171 (neg:GPR (abs:GPR (match_dup 1))))]
8172 "s390_match_ccmode (insn, CCAmode)"
8173 "ln<g>r\t%0,%1"
8174 [(set_attr "op_type" "RR<E>")
8175 (set_attr "z10prop" "z10_c")])
8176
8177 ; lnr, lngr
8178 (define_insn "*negabs<mode>2_cconly"
8179 [(set (reg CC_REGNUM)
8180 (compare (neg:GPR (abs:GPR (match_operand:GPR 1 "register_operand" "d")))
8181 (const_int 0)))
8182 (clobber (match_scratch:GPR 0 "=d"))]
8183 "s390_match_ccmode (insn, CCAmode)"
8184 "ln<g>r\t%0,%1"
8185 [(set_attr "op_type" "RR<E>")
8186 (set_attr "z10prop" "z10_c")])
8187
8188 ; lnr, lngr
8189 (define_insn "*negabs<mode>2"
8190 [(set (match_operand:GPR 0 "register_operand" "=d")
8191 (neg:GPR (abs:GPR (match_operand:GPR 1 "register_operand" "d"))))
8192 (clobber (reg:CC CC_REGNUM))]
8193 ""
8194 "ln<g>r\t%0,%1"
8195 [(set_attr "op_type" "RR<E>")
8196 (set_attr "z10prop" "z10_c")])
8197
8198 ;
8199 ; Floating point
8200 ;
8201
8202 ; lnxbr, lndbr, lnebr
8203 (define_insn "*negabs<mode>2_cc"
8204 [(set (reg CC_REGNUM)
8205 (compare (neg:BFP (abs:BFP (match_operand:BFP 1 "register_operand" "f")))
8206 (match_operand:BFP 2 "const0_operand" "")))
8207 (set (match_operand:BFP 0 "register_operand" "=f")
8208 (neg:BFP (abs:BFP (match_dup 1))))]
8209 "s390_match_ccmode (insn, CCSmode) && TARGET_HARD_FLOAT"
8210 "ln<xde>br\t%0,%1"
8211 [(set_attr "op_type" "RRE")
8212 (set_attr "type" "fsimp<mode>")])
8213
8214 ; lnxbr, lndbr, lnebr
8215 (define_insn "*negabs<mode>2_cconly"
8216 [(set (reg CC_REGNUM)
8217 (compare (neg:BFP (abs:BFP (match_operand:BFP 1 "register_operand" "f")))
8218 (match_operand:BFP 2 "const0_operand" "")))
8219 (clobber (match_scratch:BFP 0 "=f"))]
8220 "s390_match_ccmode (insn, CCSmode) && TARGET_HARD_FLOAT"
8221 "ln<xde>br\t%0,%1"
8222 [(set_attr "op_type" "RRE")
8223 (set_attr "type" "fsimp<mode>")])
8224
8225 ; lndfr
8226 (define_insn "*negabs<mode>2_nocc"
8227 [(set (match_operand:FP 0 "register_operand" "=f")
8228 (neg:FP (abs:FP (match_operand:BFP 1 "register_operand" "<fT0>"))))]
8229 "TARGET_DFP"
8230 "lndfr\t%0,%1"
8231 [(set_attr "op_type" "RRE")
8232 (set_attr "type" "fsimp<mode>")])
8233
8234 ; lnxbr, lndbr, lnebr
8235 ; FIXME: wflndb does not clobber cc
8236 (define_insn "*negabs<mode>2"
8237 [(set (match_operand:BFP 0 "register_operand" "=f,<vf>")
8238 (neg:BFP (abs:BFP (match_operand:BFP 1 "register_operand" "f,<vf>"))))
8239 (clobber (reg:CC CC_REGNUM))]
8240 "TARGET_HARD_FLOAT"
8241 "@
8242 ln<xde>br\t%0,%1
8243 wflndb\t%0,%1"
8244 [(set_attr "op_type" "RRE,VRR")
8245 (set_attr "cpu_facility" "*,vec")
8246 (set_attr "type" "fsimp<mode>,*")])
8247
8248 ;;
8249 ;;- Square root instructions.
8250 ;;
8251
8252 ;
8253 ; sqrt(df|sf)2 instruction pattern(s).
8254 ;
8255
8256 ; sqxbr, sqdbr, sqebr, sqdb, sqeb
8257 (define_insn "sqrt<mode>2"
8258 [(set (match_operand:BFP 0 "register_operand" "=f, f,<vf>")
8259 (sqrt:BFP (match_operand:BFP 1 "general_operand" "f,<Rf>,<vf>")))]
8260 "TARGET_HARD_FLOAT"
8261 "@
8262 sq<xde>br\t%0,%1
8263 sq<xde>b\t%0,%1
8264 wfsqdb\t%v0,%v1"
8265 [(set_attr "op_type" "RRE,RXE,VRR")
8266 (set_attr "type" "fsqrt<mode>")
8267 (set_attr "cpu_facility" "*,*,vec")])
8268
8269
8270 ;;
8271 ;;- One complement instructions.
8272 ;;
8273
8274 ;
8275 ; one_cmpl(di|si|hi|qi)2 instruction pattern(s).
8276 ;
8277
8278 (define_expand "one_cmpl<mode>2"
8279 [(parallel
8280 [(set (match_operand:INT 0 "register_operand" "")
8281 (xor:INT (match_operand:INT 1 "register_operand" "")
8282 (const_int -1)))
8283 (clobber (reg:CC CC_REGNUM))])]
8284 ""
8285 "")
8286
8287
8288 ;;
8289 ;; Find leftmost bit instructions.
8290 ;;
8291
8292 (define_expand "clzdi2"
8293 [(set (match_operand:DI 0 "register_operand" "=d")
8294 (clz:DI (match_operand:DI 1 "register_operand" "d")))]
8295 "TARGET_EXTIMM && TARGET_ZARCH"
8296 {
8297 rtx insn, clz_equal;
8298 rtx wide_reg = gen_reg_rtx (TImode);
8299 rtx msb = gen_rtx_CONST_INT (DImode, (unsigned HOST_WIDE_INT) 1 << 63);
8300
8301 clz_equal = gen_rtx_CLZ (DImode, operands[1]);
8302
8303 emit_insn (gen_clztidi2 (wide_reg, operands[1], msb));
8304
8305 insn = emit_move_insn (operands[0], gen_highpart (DImode, wide_reg));
8306 set_unique_reg_note (insn, REG_EQUAL, clz_equal);
8307
8308 DONE;
8309 })
8310
8311 (define_insn "clztidi2"
8312 [(set (match_operand:TI 0 "register_operand" "=d")
8313 (ior:TI
8314 (ashift:TI
8315 (zero_extend:TI
8316 (xor:DI (match_operand:DI 1 "register_operand" "d")
8317 (lshiftrt (match_operand:DI 2 "const_int_operand" "")
8318 (subreg:SI (clz:DI (match_dup 1)) 4))))
8319
8320 (const_int 64))
8321 (zero_extend:TI (clz:DI (match_dup 1)))))
8322 (clobber (reg:CC CC_REGNUM))]
8323 "(unsigned HOST_WIDE_INT) INTVAL (operands[2])
8324 == (unsigned HOST_WIDE_INT) 1 << 63
8325 && TARGET_EXTIMM && TARGET_ZARCH"
8326 "flogr\t%0,%1"
8327 [(set_attr "op_type" "RRE")])
8328
8329
8330 ;;
8331 ;;- Rotate instructions.
8332 ;;
8333
8334 ;
8335 ; rotl(di|si)3 instruction pattern(s).
8336 ;
8337
8338 ; rll, rllg
8339 (define_insn "rotl<mode>3"
8340 [(set (match_operand:GPR 0 "register_operand" "=d")
8341 (rotate:GPR (match_operand:GPR 1 "register_operand" "d")
8342 (match_operand:SI 2 "shift_count_or_setmem_operand" "Y")))]
8343 "TARGET_CPU_ZARCH"
8344 "rll<g>\t%0,%1,%Y2"
8345 [(set_attr "op_type" "RSE")
8346 (set_attr "atype" "reg")
8347 (set_attr "z10prop" "z10_super_E1")])
8348
8349 ; rll, rllg
8350 (define_insn "*rotl<mode>3_and"
8351 [(set (match_operand:GPR 0 "register_operand" "=d")
8352 (rotate:GPR (match_operand:GPR 1 "register_operand" "d")
8353 (and:SI (match_operand:SI 2 "shift_count_or_setmem_operand" "Y")
8354 (match_operand:SI 3 "const_int_operand" "n"))))]
8355 "TARGET_CPU_ZARCH && (INTVAL (operands[3]) & 63) == 63"
8356 "rll<g>\t%0,%1,%Y2"
8357 [(set_attr "op_type" "RSE")
8358 (set_attr "atype" "reg")
8359 (set_attr "z10prop" "z10_super_E1")])
8360
8361
8362 ;;
8363 ;;- Shift instructions.
8364 ;;
8365
8366 ;
8367 ; (ashl|lshr)(di|si)3 instruction pattern(s).
8368 ; Left shifts and logical right shifts
8369
8370 (define_expand "<shift><mode>3"
8371 [(set (match_operand:DSI 0 "register_operand" "")
8372 (SHIFT:DSI (match_operand:DSI 1 "register_operand" "")
8373 (match_operand:SI 2 "shift_count_or_setmem_operand" "")))]
8374 ""
8375 "")
8376
8377 ; sldl, srdl
8378 (define_insn "*<shift>di3_31"
8379 [(set (match_operand:DI 0 "register_operand" "=d")
8380 (SHIFT:DI (match_operand:DI 1 "register_operand" "0")
8381 (match_operand:SI 2 "shift_count_or_setmem_operand" "Y")))]
8382 "!TARGET_ZARCH"
8383 "s<lr>dl\t%0,%Y2"
8384 [(set_attr "op_type" "RS")
8385 (set_attr "atype" "reg")
8386 (set_attr "z196prop" "z196_cracked")])
8387
8388 ; sll, srl, sllg, srlg, sllk, srlk
8389 (define_insn "*<shift><mode>3"
8390 [(set (match_operand:GPR 0 "register_operand" "=d,d")
8391 (SHIFT:GPR (match_operand:GPR 1 "register_operand" "<d0>,d")
8392 (match_operand:SI 2 "shift_count_or_setmem_operand" "Y,Y")))]
8393 ""
8394 "@
8395 s<lr>l<g>\t%0,<1>%Y2
8396 s<lr>l<gk>\t%0,%1,%Y2"
8397 [(set_attr "op_type" "RS<E>,RSY")
8398 (set_attr "atype" "reg,reg")
8399 (set_attr "cpu_facility" "*,z196")
8400 (set_attr "z10prop" "z10_super_E1,*")])
8401
8402 ; sldl, srdl
8403 (define_insn "*<shift>di3_31_and"
8404 [(set (match_operand:DI 0 "register_operand" "=d")
8405 (SHIFT:DI (match_operand:DI 1 "register_operand" "0")
8406 (and:SI (match_operand:SI 2 "shift_count_or_setmem_operand" "Y")
8407 (match_operand:SI 3 "const_int_operand" "n"))))]
8408 "!TARGET_ZARCH && (INTVAL (operands[3]) & 63) == 63"
8409 "s<lr>dl\t%0,%Y2"
8410 [(set_attr "op_type" "RS")
8411 (set_attr "atype" "reg")])
8412
8413 ; sll, srl, sllg, srlg, sllk, srlk
8414 (define_insn "*<shift><mode>3_and"
8415 [(set (match_operand:GPR 0 "register_operand" "=d,d")
8416 (SHIFT:GPR (match_operand:GPR 1 "register_operand" "<d0>,d")
8417 (and:SI (match_operand:SI 2 "shift_count_or_setmem_operand" "Y,Y")
8418 (match_operand:SI 3 "const_int_operand" "n,n"))))]
8419 "(INTVAL (operands[3]) & 63) == 63"
8420 "@
8421 s<lr>l<g>\t%0,<1>%Y2
8422 s<lr>l<gk>\t%0,%1,%Y2"
8423 [(set_attr "op_type" "RS<E>,RSY")
8424 (set_attr "atype" "reg,reg")
8425 (set_attr "cpu_facility" "*,z196")
8426 (set_attr "z10prop" "z10_super_E1,*")])
8427
8428 ;
8429 ; ashr(di|si)3 instruction pattern(s).
8430 ; Arithmetic right shifts
8431
8432 (define_expand "ashr<mode>3"
8433 [(parallel
8434 [(set (match_operand:DSI 0 "register_operand" "")
8435 (ashiftrt:DSI (match_operand:DSI 1 "register_operand" "")
8436 (match_operand:SI 2 "shift_count_or_setmem_operand" "")))
8437 (clobber (reg:CC CC_REGNUM))])]
8438 ""
8439 "")
8440
8441 (define_insn "*ashrdi3_cc_31"
8442 [(set (reg CC_REGNUM)
8443 (compare (ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
8444 (match_operand:SI 2 "shift_count_or_setmem_operand" "Y"))
8445 (const_int 0)))
8446 (set (match_operand:DI 0 "register_operand" "=d")
8447 (ashiftrt:DI (match_dup 1) (match_dup 2)))]
8448 "!TARGET_ZARCH && s390_match_ccmode(insn, CCSmode)"
8449 "srda\t%0,%Y2"
8450 [(set_attr "op_type" "RS")
8451 (set_attr "atype" "reg")])
8452
8453 (define_insn "*ashrdi3_cconly_31"
8454 [(set (reg CC_REGNUM)
8455 (compare (ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
8456 (match_operand:SI 2 "shift_count_or_setmem_operand" "Y"))
8457 (const_int 0)))
8458 (clobber (match_scratch:DI 0 "=d"))]
8459 "!TARGET_ZARCH && s390_match_ccmode(insn, CCSmode)"
8460 "srda\t%0,%Y2"
8461 [(set_attr "op_type" "RS")
8462 (set_attr "atype" "reg")])
8463
8464 (define_insn "*ashrdi3_31"
8465 [(set (match_operand:DI 0 "register_operand" "=d")
8466 (ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
8467 (match_operand:SI 2 "shift_count_or_setmem_operand" "Y")))
8468 (clobber (reg:CC CC_REGNUM))]
8469 "!TARGET_ZARCH"
8470 "srda\t%0,%Y2"
8471 [(set_attr "op_type" "RS")
8472 (set_attr "atype" "reg")])
8473
8474 ; sra, srag, srak
8475 (define_insn "*ashr<mode>3_cc"
8476 [(set (reg CC_REGNUM)
8477 (compare (ashiftrt:GPR (match_operand:GPR 1 "register_operand" "<d0>,d")
8478 (match_operand:SI 2 "shift_count_or_setmem_operand" "Y,Y"))
8479 (const_int 0)))
8480 (set (match_operand:GPR 0 "register_operand" "=d,d")
8481 (ashiftrt:GPR (match_dup 1) (match_dup 2)))]
8482 "s390_match_ccmode(insn, CCSmode)"
8483 "@
8484 sra<g>\t%0,<1>%Y2
8485 sra<gk>\t%0,%1,%Y2"
8486 [(set_attr "op_type" "RS<E>,RSY")
8487 (set_attr "atype" "reg,reg")
8488 (set_attr "cpu_facility" "*,z196")
8489 (set_attr "z10prop" "z10_super_E1,*")])
8490
8491 ; sra, srag, srak
8492 (define_insn "*ashr<mode>3_cconly"
8493 [(set (reg CC_REGNUM)
8494 (compare (ashiftrt:GPR (match_operand:GPR 1 "register_operand" "<d0>,d")
8495 (match_operand:SI 2 "shift_count_or_setmem_operand" "Y,Y"))
8496 (const_int 0)))
8497 (clobber (match_scratch:GPR 0 "=d,d"))]
8498 "s390_match_ccmode(insn, CCSmode)"
8499 "@
8500 sra<g>\t%0,<1>%Y2
8501 sra<gk>\t%0,%1,%Y2"
8502 [(set_attr "op_type" "RS<E>,RSY")
8503 (set_attr "atype" "reg,reg")
8504 (set_attr "cpu_facility" "*,z196")
8505 (set_attr "z10prop" "z10_super_E1,*")])
8506
8507 ; sra, srag
8508 (define_insn "*ashr<mode>3"
8509 [(set (match_operand:GPR 0 "register_operand" "=d,d")
8510 (ashiftrt:GPR (match_operand:GPR 1 "register_operand" "<d0>,d")
8511 (match_operand:SI 2 "shift_count_or_setmem_operand" "Y,Y")))
8512 (clobber (reg:CC CC_REGNUM))]
8513 ""
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
8523 ; shift pattern with implicit ANDs
8524
8525 (define_insn "*ashrdi3_cc_31_and"
8526 [(set (reg CC_REGNUM)
8527 (compare (ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
8528 (and:SI (match_operand:SI 2 "shift_count_or_setmem_operand" "Y")
8529 (match_operand:SI 3 "const_int_operand" "n")))
8530 (const_int 0)))
8531 (set (match_operand:DI 0 "register_operand" "=d")
8532 (ashiftrt:DI (match_dup 1) (and:SI (match_dup 2) (match_dup 3))))]
8533 "!TARGET_ZARCH && s390_match_ccmode(insn, CCSmode)
8534 && (INTVAL (operands[3]) & 63) == 63"
8535 "srda\t%0,%Y2"
8536 [(set_attr "op_type" "RS")
8537 (set_attr "atype" "reg")])
8538
8539 (define_insn "*ashrdi3_cconly_31_and"
8540 [(set (reg CC_REGNUM)
8541 (compare (ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
8542 (and:SI (match_operand:SI 2 "shift_count_or_setmem_operand" "Y")
8543 (match_operand:SI 3 "const_int_operand" "n")))
8544 (const_int 0)))
8545 (clobber (match_scratch:DI 0 "=d"))]
8546 "!TARGET_ZARCH && s390_match_ccmode(insn, CCSmode)
8547 && (INTVAL (operands[3]) & 63) == 63"
8548 "srda\t%0,%Y2"
8549 [(set_attr "op_type" "RS")
8550 (set_attr "atype" "reg")])
8551
8552 (define_insn "*ashrdi3_31_and"
8553 [(set (match_operand:DI 0 "register_operand" "=d")
8554 (ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
8555 (and:SI (match_operand:SI 2 "shift_count_or_setmem_operand" "Y")
8556 (match_operand:SI 3 "const_int_operand" "n"))))
8557 (clobber (reg:CC CC_REGNUM))]
8558 "!TARGET_ZARCH && (INTVAL (operands[3]) & 63) == 63"
8559 "srda\t%0,%Y2"
8560 [(set_attr "op_type" "RS")
8561 (set_attr "atype" "reg")])
8562
8563 ; sra, srag, srak
8564 (define_insn "*ashr<mode>3_cc_and"
8565 [(set (reg CC_REGNUM)
8566 (compare (ashiftrt:GPR (match_operand:GPR 1 "register_operand" "<d0>,d")
8567 (and:SI (match_operand:SI 2 "shift_count_or_setmem_operand" "Y,Y")
8568 (match_operand:SI 3 "const_int_operand" "n,n")))
8569 (const_int 0)))
8570 (set (match_operand:GPR 0 "register_operand" "=d,d")
8571 (ashiftrt:GPR (match_dup 1) (and:SI (match_dup 2) (match_dup 3))))]
8572 "s390_match_ccmode(insn, CCSmode) && (INTVAL (operands[3]) & 63) == 63"
8573 "@
8574 sra<g>\t%0,<1>%Y2
8575 sra<gk>\t%0,%1,%Y2"
8576 [(set_attr "op_type" "RS<E>,RSY")
8577 (set_attr "atype" "reg,reg")
8578 (set_attr "cpu_facility" "*,z196")
8579 (set_attr "z10prop" "z10_super_E1,*")])
8580
8581 ; sra, srag, srak
8582 (define_insn "*ashr<mode>3_cconly_and"
8583 [(set (reg CC_REGNUM)
8584 (compare (ashiftrt:GPR (match_operand:GPR 1 "register_operand" "<d0>,d")
8585 (and:SI (match_operand:SI 2 "shift_count_or_setmem_operand" "Y,Y")
8586 (match_operand:SI 3 "const_int_operand" "n,n")))
8587 (const_int 0)))
8588 (clobber (match_scratch:GPR 0 "=d,d"))]
8589 "s390_match_ccmode(insn, CCSmode) && (INTVAL (operands[3]) & 63) == 63"
8590 "@
8591 sra<g>\t%0,<1>%Y2
8592 sra<gk>\t%0,%1,%Y2"
8593 [(set_attr "op_type" "RS<E>,RSY")
8594 (set_attr "atype" "reg,reg")
8595 (set_attr "cpu_facility" "*,z196")
8596 (set_attr "z10prop" "z10_super_E1,*")])
8597
8598 ; sra, srag, srak
8599 (define_insn "*ashr<mode>3_and"
8600 [(set (match_operand:GPR 0 "register_operand" "=d,d")
8601 (ashiftrt:GPR (match_operand:GPR 1 "register_operand" "<d0>,d")
8602 (and:SI (match_operand:SI 2 "shift_count_or_setmem_operand" "Y,Y")
8603 (match_operand:SI 3 "const_int_operand" "n,n"))))
8604 (clobber (reg:CC CC_REGNUM))]
8605 "(INTVAL (operands[3]) & 63) == 63"
8606 "@
8607 sra<g>\t%0,<1>%Y2
8608 sra<gk>\t%0,%1,%Y2"
8609 [(set_attr "op_type" "RS<E>,RSY")
8610 (set_attr "atype" "reg,reg")
8611 (set_attr "cpu_facility" "*,z196")
8612 (set_attr "z10prop" "z10_super_E1,*")])
8613
8614
8615 ;;
8616 ;; Branch instruction patterns.
8617 ;;
8618
8619 (define_expand "cbranch<mode>4"
8620 [(set (pc)
8621 (if_then_else (match_operator 0 "comparison_operator"
8622 [(match_operand:GPR 1 "register_operand" "")
8623 (match_operand:GPR 2 "general_operand" "")])
8624 (label_ref (match_operand 3 "" ""))
8625 (pc)))]
8626 ""
8627 "s390_emit_jump (operands[3],
8628 s390_emit_compare (GET_CODE (operands[0]), operands[1], operands[2]));
8629 DONE;")
8630
8631 (define_expand "cbranch<mode>4"
8632 [(set (pc)
8633 (if_then_else (match_operator 0 "comparison_operator"
8634 [(match_operand:FP 1 "register_operand" "")
8635 (match_operand:FP 2 "general_operand" "")])
8636 (label_ref (match_operand 3 "" ""))
8637 (pc)))]
8638 "TARGET_HARD_FLOAT"
8639 "s390_emit_jump (operands[3],
8640 s390_emit_compare (GET_CODE (operands[0]), operands[1], operands[2]));
8641 DONE;")
8642
8643 (define_expand "cbranchcc4"
8644 [(set (pc)
8645 (if_then_else (match_operator 0 "s390_comparison"
8646 [(match_operand 1 "cc_reg_operand" "")
8647 (match_operand 2 "const_int_operand" "")])
8648 (label_ref (match_operand 3 "" ""))
8649 (pc)))]
8650 ""
8651 "")
8652
8653
8654 ;;
8655 ;;- Conditional jump instructions.
8656 ;;
8657
8658 (define_insn "*cjump_64"
8659 [(set (pc)
8660 (if_then_else
8661 (match_operator 1 "s390_comparison" [(reg CC_REGNUM)
8662 (match_operand 2 "const_int_operand" "")])
8663 (label_ref (match_operand 0 "" ""))
8664 (pc)))]
8665 "TARGET_CPU_ZARCH"
8666 {
8667 if (get_attr_length (insn) == 4)
8668 return "j%C1\t%l0";
8669 else
8670 return "jg%C1\t%l0";
8671 }
8672 [(set_attr "op_type" "RI")
8673 (set_attr "type" "branch")
8674 (set (attr "length")
8675 (if_then_else (lt (abs (minus (pc) (match_dup 0))) (const_int 60000))
8676 (const_int 4) (const_int 6)))])
8677
8678 (define_insn "*cjump_31"
8679 [(set (pc)
8680 (if_then_else
8681 (match_operator 1 "s390_comparison" [(reg CC_REGNUM)
8682 (match_operand 2 "const_int_operand" "")])
8683 (label_ref (match_operand 0 "" ""))
8684 (pc)))]
8685 "!TARGET_CPU_ZARCH"
8686 {
8687 gcc_assert (get_attr_length (insn) == 4);
8688 return "j%C1\t%l0";
8689 }
8690 [(set_attr "op_type" "RI")
8691 (set_attr "type" "branch")
8692 (set (attr "length")
8693 (if_then_else (not (match_test "flag_pic"))
8694 (if_then_else (lt (abs (minus (pc) (match_dup 0))) (const_int 60000))
8695 (const_int 4) (const_int 6))
8696 (if_then_else (lt (abs (minus (pc) (match_dup 0))) (const_int 60000))
8697 (const_int 4) (const_int 8))))])
8698
8699 (define_insn "*cjump_long"
8700 [(set (pc)
8701 (if_then_else
8702 (match_operator 1 "s390_comparison" [(reg CC_REGNUM) (const_int 0)])
8703 (match_operand 0 "address_operand" "ZQZR")
8704 (pc)))]
8705 ""
8706 {
8707 if (get_attr_op_type (insn) == OP_TYPE_RR)
8708 return "b%C1r\t%0";
8709 else
8710 return "b%C1\t%a0";
8711 }
8712 [(set (attr "op_type")
8713 (if_then_else (match_operand 0 "register_operand" "")
8714 (const_string "RR") (const_string "RX")))
8715 (set_attr "type" "branch")
8716 (set_attr "atype" "agen")])
8717
8718 ;; A conditional return instruction.
8719 (define_insn "*c<code>"
8720 [(set (pc)
8721 (if_then_else
8722 (match_operator 0 "s390_comparison" [(reg CC_REGNUM) (const_int 0)])
8723 (ANY_RETURN)
8724 (pc)))]
8725 "s390_can_use_<code>_insn ()"
8726 "b%C0r\t%%r14"
8727 [(set_attr "op_type" "RR")
8728 (set_attr "type" "jsr")
8729 (set_attr "atype" "agen")])
8730
8731 ;;
8732 ;;- Negated conditional jump instructions.
8733 ;;
8734
8735 (define_insn "*icjump_64"
8736 [(set (pc)
8737 (if_then_else
8738 (match_operator 1 "s390_comparison" [(reg CC_REGNUM) (const_int 0)])
8739 (pc)
8740 (label_ref (match_operand 0 "" ""))))]
8741 "TARGET_CPU_ZARCH"
8742 {
8743 if (get_attr_length (insn) == 4)
8744 return "j%D1\t%l0";
8745 else
8746 return "jg%D1\t%l0";
8747 }
8748 [(set_attr "op_type" "RI")
8749 (set_attr "type" "branch")
8750 (set (attr "length")
8751 (if_then_else (lt (abs (minus (pc) (match_dup 0))) (const_int 60000))
8752 (const_int 4) (const_int 6)))])
8753
8754 (define_insn "*icjump_31"
8755 [(set (pc)
8756 (if_then_else
8757 (match_operator 1 "s390_comparison" [(reg CC_REGNUM) (const_int 0)])
8758 (pc)
8759 (label_ref (match_operand 0 "" ""))))]
8760 "!TARGET_CPU_ZARCH"
8761 {
8762 gcc_assert (get_attr_length (insn) == 4);
8763 return "j%D1\t%l0";
8764 }
8765 [(set_attr "op_type" "RI")
8766 (set_attr "type" "branch")
8767 (set (attr "length")
8768 (if_then_else (not (match_test "flag_pic"))
8769 (if_then_else (lt (abs (minus (pc) (match_dup 0))) (const_int 60000))
8770 (const_int 4) (const_int 6))
8771 (if_then_else (lt (abs (minus (pc) (match_dup 0))) (const_int 60000))
8772 (const_int 4) (const_int 8))))])
8773
8774 (define_insn "*icjump_long"
8775 [(set (pc)
8776 (if_then_else
8777 (match_operator 1 "s390_comparison" [(reg CC_REGNUM) (const_int 0)])
8778 (pc)
8779 (match_operand 0 "address_operand" "ZQZR")))]
8780 ""
8781 {
8782 if (get_attr_op_type (insn) == OP_TYPE_RR)
8783 return "b%D1r\t%0";
8784 else
8785 return "b%D1\t%a0";
8786 }
8787 [(set (attr "op_type")
8788 (if_then_else (match_operand 0 "register_operand" "")
8789 (const_string "RR") (const_string "RX")))
8790 (set_attr "type" "branch")
8791 (set_attr "atype" "agen")])
8792
8793 ;;
8794 ;;- Trap instructions.
8795 ;;
8796
8797 (define_insn "trap"
8798 [(trap_if (const_int 1) (const_int 0))]
8799 ""
8800 "j\t.+2"
8801 [(set_attr "op_type" "RI")
8802 (set_attr "type" "branch")])
8803
8804 (define_expand "ctrap<mode>4"
8805 [(trap_if (match_operator 0 "comparison_operator"
8806 [(match_operand:GPR 1 "register_operand" "")
8807 (match_operand:GPR 2 "general_operand" "")])
8808 (match_operand 3 "const0_operand" ""))]
8809 ""
8810 {
8811 rtx cond = s390_emit_compare (GET_CODE (operands[0]),
8812 operands[1], operands[2]);
8813 emit_insn (gen_condtrap (cond, XEXP (cond, 0)));
8814 DONE;
8815 })
8816
8817 (define_expand "ctrap<mode>4"
8818 [(trap_if (match_operator 0 "comparison_operator"
8819 [(match_operand:FP 1 "register_operand" "")
8820 (match_operand:FP 2 "general_operand" "")])
8821 (match_operand 3 "const0_operand" ""))]
8822 ""
8823 {
8824 rtx cond = s390_emit_compare (GET_CODE (operands[0]),
8825 operands[1], operands[2]);
8826 emit_insn (gen_condtrap (cond, XEXP (cond, 0)));
8827 DONE;
8828 })
8829
8830 (define_insn "condtrap"
8831 [(trap_if (match_operator 0 "s390_comparison"
8832 [(match_operand 1 "cc_reg_operand" "c")
8833 (const_int 0)])
8834 (const_int 0))]
8835 ""
8836 "j%C0\t.+2";
8837 [(set_attr "op_type" "RI")
8838 (set_attr "type" "branch")])
8839
8840 ; crt, cgrt, cit, cgit
8841 (define_insn "*cmp_and_trap_signed_int<mode>"
8842 [(trap_if (match_operator 0 "s390_signed_integer_comparison"
8843 [(match_operand:GPR 1 "register_operand" "d,d")
8844 (match_operand:GPR 2 "nonmemory_operand" "d,K")])
8845 (const_int 0))]
8846 "TARGET_Z10"
8847 "@
8848 c<g>rt%C0\t%1,%2
8849 c<g>it%C0\t%1,%h2"
8850 [(set_attr "op_type" "RRF,RIE")
8851 (set_attr "type" "branch")
8852 (set_attr "z10prop" "z10_super_c,z10_super")])
8853
8854 ; clrt, clgrt, clfit, clgit, clt, clgt
8855 (define_insn "*cmp_and_trap_unsigned_int<mode>"
8856 [(trap_if (match_operator 0 "s390_unsigned_integer_comparison"
8857 [(match_operand:GPR 1 "register_operand" "d,d, d")
8858 (match_operand:GPR 2 "general_operand" "d,D,RT")])
8859 (const_int 0))]
8860 "TARGET_Z10"
8861 "@
8862 cl<g>rt%C0\t%1,%2
8863 cl<gf>it%C0\t%1,%x2
8864 cl<g>t%C0\t%1,%2"
8865 [(set_attr "op_type" "RRF,RIE,RSY")
8866 (set_attr "type" "branch")
8867 (set_attr "z10prop" "z10_super_c,z10_super,*")
8868 (set_attr "cpu_facility" "z10,z10,zEC12")])
8869
8870 ; lat, lgat
8871 (define_insn "*load_and_trap<mode>"
8872 [(trap_if (eq (match_operand:GPR 0 "memory_operand" "RT")
8873 (const_int 0))
8874 (const_int 0))
8875 (set (match_operand:GPR 1 "register_operand" "=d")
8876 (match_dup 0))]
8877 "TARGET_ZEC12"
8878 "l<g>at\t%1,%0"
8879 [(set_attr "op_type" "RXY")])
8880
8881
8882 ;;
8883 ;;- Loop instructions.
8884 ;;
8885 ;; This is all complicated by the fact that since this is a jump insn
8886 ;; we must handle our own output reloads.
8887
8888 ;; branch on index
8889
8890 ; This splitter will be matched by combine and has to add the 2 moves
8891 ; necessary to load the compare and the increment values into a
8892 ; register pair as needed by brxle.
8893
8894 (define_insn_and_split "*brx_stage1_<GPR:mode>"
8895 [(set (pc)
8896 (if_then_else
8897 (match_operator 6 "s390_brx_operator"
8898 [(plus:GPR (match_operand:GPR 1 "register_operand" "")
8899 (match_operand:GPR 2 "general_operand" ""))
8900 (match_operand:GPR 3 "register_operand" "")])
8901 (label_ref (match_operand 0 "" ""))
8902 (pc)))
8903 (set (match_operand:GPR 4 "nonimmediate_operand" "")
8904 (plus:GPR (match_dup 1) (match_dup 2)))
8905 (clobber (match_scratch:GPR 5 ""))]
8906 "TARGET_CPU_ZARCH"
8907 "#"
8908 "!reload_completed && !reload_in_progress"
8909 [(set (match_dup 7) (match_dup 2)) ; the increment
8910 (set (match_dup 8) (match_dup 3)) ; the comparison value
8911 (parallel [(set (pc)
8912 (if_then_else
8913 (match_op_dup 6
8914 [(plus:GPR (match_dup 1) (match_dup 7))
8915 (match_dup 8)])
8916 (label_ref (match_dup 0))
8917 (pc)))
8918 (set (match_dup 4)
8919 (plus:GPR (match_dup 1) (match_dup 7)))
8920 (clobber (match_dup 5))
8921 (clobber (reg:CC CC_REGNUM))])]
8922 {
8923 rtx dreg = gen_reg_rtx (word_mode == DImode ? TImode : DImode);
8924 operands[7] = gen_lowpart (<GPR:MODE>mode,
8925 gen_highpart (word_mode, dreg));
8926 operands[8] = gen_lowpart (<GPR:MODE>mode,
8927 gen_lowpart (word_mode, dreg));
8928 })
8929
8930 ; brxlg, brxhg
8931
8932 (define_insn_and_split "*brxg_64bit"
8933 [(set (pc)
8934 (if_then_else
8935 (match_operator 5 "s390_brx_operator"
8936 [(plus:DI (match_operand:DI 1 "register_operand" "d,d,d")
8937 (subreg:DI (match_operand:TI 2 "register_operand" "d,d,d") 0))
8938 (subreg:DI (match_dup 2) 8)])
8939 (label_ref (match_operand 0 "" ""))
8940 (pc)))
8941 (set (match_operand:DI 3 "nonimmediate_operand" "=1,?X,?X")
8942 (plus:DI (match_dup 1)
8943 (subreg:DI (match_dup 2) 0)))
8944 (clobber (match_scratch:DI 4 "=X,&1,&?d"))
8945 (clobber (reg:CC CC_REGNUM))]
8946 "TARGET_ZARCH"
8947 {
8948 if (which_alternative != 0)
8949 return "#";
8950 else if (get_attr_length (insn) == 6)
8951 return "brx%E5g\t%1,%2,%l0";
8952 else
8953 return "agr\t%1,%2\;cgr\t%1,%M2\;jg%C5\t%l0";
8954 }
8955 "&& reload_completed
8956 && (!REG_P (operands[3])
8957 || !rtx_equal_p (operands[1], operands[3]))"
8958 [(set (match_dup 4) (match_dup 1))
8959 (parallel [(set (match_dup 4) (plus:DI (match_dup 4) (subreg:DI (match_dup 2) 0)))
8960 (clobber (reg:CC CC_REGNUM))])
8961 (set (reg:CCS CC_REGNUM) (compare:CCS (match_dup 4) (subreg:DI (match_dup 2) 8)))
8962 (set (match_dup 3) (match_dup 4))
8963 (set (pc) (if_then_else (match_op_dup 5 [(reg:CCS CC_REGNUM) (const_int 0)])
8964 (label_ref (match_dup 0))
8965 (pc)))]
8966 ""
8967 [(set_attr "op_type" "RIE")
8968 (set_attr "type" "branch")
8969 (set (attr "length")
8970 (if_then_else (lt (abs (minus (pc) (match_dup 0))) (const_int 60000))
8971 (const_int 6) (const_int 16)))])
8972
8973 ; brxle, brxh
8974
8975 (define_insn_and_split "*brx_64bit"
8976 [(set (pc)
8977 (if_then_else
8978 (match_operator 5 "s390_brx_operator"
8979 [(plus:SI (match_operand:SI 1 "register_operand" "d,d,d")
8980 (subreg:SI (match_operand:TI 2 "register_operand" "d,d,d") 4))
8981 (subreg:SI (match_dup 2) 12)])
8982 (label_ref (match_operand 0 "" ""))
8983 (pc)))
8984 (set (match_operand:SI 3 "nonimmediate_operand" "=1,?X,?X")
8985 (plus:SI (match_dup 1)
8986 (subreg:SI (match_dup 2) 4)))
8987 (clobber (match_scratch:SI 4 "=X,&1,&?d"))
8988 (clobber (reg:CC CC_REGNUM))]
8989 "TARGET_ZARCH"
8990 {
8991 if (which_alternative != 0)
8992 return "#";
8993 else if (get_attr_length (insn) == 6)
8994 return "brx%C5\t%1,%2,%l0";
8995 else
8996 return "ar\t%1,%2\;cr\t%1,%M2\;jg%C5\t%l0";
8997 }
8998 "&& reload_completed
8999 && (!REG_P (operands[3])
9000 || !rtx_equal_p (operands[1], operands[3]))"
9001 [(set (match_dup 4) (match_dup 1))
9002 (parallel [(set (match_dup 4) (plus:SI (match_dup 4) (subreg:SI (match_dup 2) 4)))
9003 (clobber (reg:CC CC_REGNUM))])
9004 (set (reg:CCS CC_REGNUM) (compare:CCS (match_dup 4) (subreg:SI (match_dup 2) 12)))
9005 (set (match_dup 3) (match_dup 4))
9006 (set (pc) (if_then_else (match_op_dup 5 [(reg:CCS CC_REGNUM) (const_int 0)])
9007 (label_ref (match_dup 0))
9008 (pc)))]
9009 ""
9010 [(set_attr "op_type" "RSI")
9011 (set_attr "type" "branch")
9012 (set (attr "length")
9013 (if_then_else (lt (abs (minus (pc) (match_dup 0))) (const_int 60000))
9014 (const_int 6) (const_int 14)))])
9015
9016 ; brxle, brxh
9017
9018 (define_insn_and_split "*brx_31bit"
9019 [(set (pc)
9020 (if_then_else
9021 (match_operator 5 "s390_brx_operator"
9022 [(plus:SI (match_operand:SI 1 "register_operand" "d,d,d")
9023 (subreg:SI (match_operand:DI 2 "register_operand" "d,d,d") 0))
9024 (subreg:SI (match_dup 2) 4)])
9025 (label_ref (match_operand 0 "" ""))
9026 (pc)))
9027 (set (match_operand:SI 3 "nonimmediate_operand" "=1,?X,?X")
9028 (plus:SI (match_dup 1)
9029 (subreg:SI (match_dup 2) 0)))
9030 (clobber (match_scratch:SI 4 "=X,&1,&?d"))
9031 (clobber (reg:CC CC_REGNUM))]
9032 "!TARGET_ZARCH && TARGET_CPU_ZARCH"
9033 {
9034 if (which_alternative != 0)
9035 return "#";
9036 else if (get_attr_length (insn) == 6)
9037 return "brx%C5\t%1,%2,%l0";
9038 else
9039 return "ar\t%1,%2\;cr\t%1,%M2\;jg%C5\t%l0";
9040 }
9041 "&& reload_completed
9042 && (!REG_P (operands[3])
9043 || !rtx_equal_p (operands[1], operands[3]))"
9044 [(set (match_dup 4) (match_dup 1))
9045 (parallel [(set (match_dup 4) (plus:SI (match_dup 4) (subreg:SI (match_dup 2) 0)))
9046 (clobber (reg:CC CC_REGNUM))])
9047 (set (reg:CCS CC_REGNUM) (compare:CCS (match_dup 4) (subreg:SI (match_dup 2) 4)))
9048 (set (match_dup 3) (match_dup 4))
9049 (set (pc) (if_then_else (match_op_dup 5 [(reg:CCS CC_REGNUM) (const_int 0)])
9050 (label_ref (match_dup 0))
9051 (pc)))]
9052 ""
9053 [(set_attr "op_type" "RSI")
9054 (set_attr "type" "branch")
9055 (set (attr "length")
9056 (if_then_else (lt (abs (minus (pc) (match_dup 0))) (const_int 60000))
9057 (const_int 6) (const_int 14)))])
9058
9059
9060 ;; branch on count
9061
9062 (define_expand "doloop_end"
9063 [(use (match_operand 0 "" "")) ; loop pseudo
9064 (use (match_operand 1 "" ""))] ; label
9065 ""
9066 {
9067 if (GET_MODE (operands[0]) == SImode && !TARGET_CPU_ZARCH)
9068 emit_jump_insn (gen_doloop_si31 (operands[1], operands[0], operands[0]));
9069 else if (GET_MODE (operands[0]) == SImode && TARGET_CPU_ZARCH)
9070 emit_jump_insn (gen_doloop_si64 (operands[1], operands[0], operands[0]));
9071 else if (GET_MODE (operands[0]) == DImode && TARGET_ZARCH)
9072 emit_jump_insn (gen_doloop_di (operands[1], operands[0], operands[0]));
9073 else
9074 FAIL;
9075
9076 DONE;
9077 })
9078
9079 (define_insn_and_split "doloop_si64"
9080 [(set (pc)
9081 (if_then_else
9082 (ne (match_operand:SI 1 "register_operand" "d,d,d")
9083 (const_int 1))
9084 (label_ref (match_operand 0 "" ""))
9085 (pc)))
9086 (set (match_operand:SI 2 "nonimmediate_operand" "=1,?X,?X")
9087 (plus:SI (match_dup 1) (const_int -1)))
9088 (clobber (match_scratch:SI 3 "=X,&1,&?d"))
9089 (clobber (reg:CC CC_REGNUM))]
9090 "TARGET_CPU_ZARCH"
9091 {
9092 if (which_alternative != 0)
9093 return "#";
9094 else if (get_attr_length (insn) == 4)
9095 return "brct\t%1,%l0";
9096 else
9097 return "ahi\t%1,-1\;jgne\t%l0";
9098 }
9099 "&& reload_completed
9100 && (! REG_P (operands[2])
9101 || ! rtx_equal_p (operands[1], operands[2]))"
9102 [(set (match_dup 3) (match_dup 1))
9103 (parallel [(set (reg:CCAN CC_REGNUM)
9104 (compare:CCAN (plus:SI (match_dup 3) (const_int -1))
9105 (const_int 0)))
9106 (set (match_dup 3) (plus:SI (match_dup 3) (const_int -1)))])
9107 (set (match_dup 2) (match_dup 3))
9108 (set (pc) (if_then_else (ne (reg:CCAN CC_REGNUM) (const_int 0))
9109 (label_ref (match_dup 0))
9110 (pc)))]
9111 ""
9112 [(set_attr "op_type" "RI")
9113 ; Strictly speaking, the z10 properties are valid for brct only, however, it does not
9114 ; hurt us in the (rare) case of ahi.
9115 (set_attr "z10prop" "z10_super_E1")
9116 (set_attr "type" "branch")
9117 (set (attr "length")
9118 (if_then_else (lt (abs (minus (pc) (match_dup 0))) (const_int 60000))
9119 (const_int 4) (const_int 10)))])
9120
9121 (define_insn_and_split "doloop_si31"
9122 [(set (pc)
9123 (if_then_else
9124 (ne (match_operand:SI 1 "register_operand" "d,d,d")
9125 (const_int 1))
9126 (label_ref (match_operand 0 "" ""))
9127 (pc)))
9128 (set (match_operand:SI 2 "nonimmediate_operand" "=1,?X,?X")
9129 (plus:SI (match_dup 1) (const_int -1)))
9130 (clobber (match_scratch:SI 3 "=X,&1,&?d"))
9131 (clobber (reg:CC CC_REGNUM))]
9132 "!TARGET_CPU_ZARCH"
9133 {
9134 if (which_alternative != 0)
9135 return "#";
9136 else if (get_attr_length (insn) == 4)
9137 return "brct\t%1,%l0";
9138 else
9139 gcc_unreachable ();
9140 }
9141 "&& reload_completed
9142 && (! REG_P (operands[2])
9143 || ! rtx_equal_p (operands[1], operands[2]))"
9144 [(set (match_dup 3) (match_dup 1))
9145 (parallel [(set (reg:CCAN CC_REGNUM)
9146 (compare:CCAN (plus:SI (match_dup 3) (const_int -1))
9147 (const_int 0)))
9148 (set (match_dup 3) (plus:SI (match_dup 3) (const_int -1)))])
9149 (set (match_dup 2) (match_dup 3))
9150 (set (pc) (if_then_else (ne (reg:CCAN CC_REGNUM) (const_int 0))
9151 (label_ref (match_dup 0))
9152 (pc)))]
9153 ""
9154 [(set_attr "op_type" "RI")
9155 ; Strictly speaking, the z10 properties are valid for brct only, however, it does not
9156 ; hurt us in the (rare) case of ahi.
9157 (set_attr "z10prop" "z10_super_E1")
9158 (set_attr "type" "branch")
9159 (set (attr "length")
9160 (if_then_else (not (match_test "flag_pic"))
9161 (if_then_else (lt (abs (minus (pc) (match_dup 0))) (const_int 60000))
9162 (const_int 4) (const_int 6))
9163 (if_then_else (lt (abs (minus (pc) (match_dup 0))) (const_int 60000))
9164 (const_int 4) (const_int 8))))])
9165
9166 (define_insn "*doloop_si_long"
9167 [(set (pc)
9168 (if_then_else
9169 (ne (match_operand:SI 1 "register_operand" "d")
9170 (const_int 1))
9171 (match_operand 0 "address_operand" "ZQZR")
9172 (pc)))
9173 (set (match_operand:SI 2 "register_operand" "=1")
9174 (plus:SI (match_dup 1) (const_int -1)))
9175 (clobber (match_scratch:SI 3 "=X"))
9176 (clobber (reg:CC CC_REGNUM))]
9177 "!TARGET_CPU_ZARCH"
9178 {
9179 if (get_attr_op_type (insn) == OP_TYPE_RR)
9180 return "bctr\t%1,%0";
9181 else
9182 return "bct\t%1,%a0";
9183 }
9184 [(set (attr "op_type")
9185 (if_then_else (match_operand 0 "register_operand" "")
9186 (const_string "RR") (const_string "RX")))
9187 (set_attr "type" "branch")
9188 (set_attr "atype" "agen")
9189 (set_attr "z10prop" "z10_c")
9190 (set_attr "z196prop" "z196_cracked")])
9191
9192 (define_insn_and_split "doloop_di"
9193 [(set (pc)
9194 (if_then_else
9195 (ne (match_operand:DI 1 "register_operand" "d,d,d")
9196 (const_int 1))
9197 (label_ref (match_operand 0 "" ""))
9198 (pc)))
9199 (set (match_operand:DI 2 "nonimmediate_operand" "=1,?X,?X")
9200 (plus:DI (match_dup 1) (const_int -1)))
9201 (clobber (match_scratch:DI 3 "=X,&1,&?d"))
9202 (clobber (reg:CC CC_REGNUM))]
9203 "TARGET_ZARCH"
9204 {
9205 if (which_alternative != 0)
9206 return "#";
9207 else if (get_attr_length (insn) == 4)
9208 return "brctg\t%1,%l0";
9209 else
9210 return "aghi\t%1,-1\;jgne\t%l0";
9211 }
9212 "&& reload_completed
9213 && (! REG_P (operands[2])
9214 || ! rtx_equal_p (operands[1], operands[2]))"
9215 [(set (match_dup 3) (match_dup 1))
9216 (parallel [(set (reg:CCAN CC_REGNUM)
9217 (compare:CCAN (plus:DI (match_dup 3) (const_int -1))
9218 (const_int 0)))
9219 (set (match_dup 3) (plus:DI (match_dup 3) (const_int -1)))])
9220 (set (match_dup 2) (match_dup 3))
9221 (set (pc) (if_then_else (ne (reg:CCAN CC_REGNUM) (const_int 0))
9222 (label_ref (match_dup 0))
9223 (pc)))]
9224 ""
9225 [(set_attr "op_type" "RI")
9226 ; Strictly speaking, the z10 properties are valid for brct only, however, it does not
9227 ; hurt us in the (rare) case of ahi.
9228 (set_attr "z10prop" "z10_super_E1")
9229 (set_attr "type" "branch")
9230 (set (attr "length")
9231 (if_then_else (lt (abs (minus (pc) (match_dup 0))) (const_int 60000))
9232 (const_int 4) (const_int 10)))])
9233
9234 ;;
9235 ;;- Unconditional jump instructions.
9236 ;;
9237
9238 ;
9239 ; jump instruction pattern(s).
9240 ;
9241
9242 (define_expand "jump"
9243 [(match_operand 0 "" "")]
9244 ""
9245 "s390_emit_jump (operands[0], NULL_RTX); DONE;")
9246
9247 (define_insn "*jump64"
9248 [(set (pc) (label_ref (match_operand 0 "" "")))]
9249 "TARGET_CPU_ZARCH"
9250 {
9251 if (get_attr_length (insn) == 4)
9252 return "j\t%l0";
9253 else
9254 return "jg\t%l0";
9255 }
9256 [(set_attr "op_type" "RI")
9257 (set_attr "type" "branch")
9258 (set (attr "length")
9259 (if_then_else (lt (abs (minus (pc) (match_dup 0))) (const_int 60000))
9260 (const_int 4) (const_int 6)))])
9261
9262 (define_insn "*jump31"
9263 [(set (pc) (label_ref (match_operand 0 "" "")))]
9264 "!TARGET_CPU_ZARCH"
9265 {
9266 gcc_assert (get_attr_length (insn) == 4);
9267 return "j\t%l0";
9268 }
9269 [(set_attr "op_type" "RI")
9270 (set_attr "type" "branch")
9271 (set (attr "length")
9272 (if_then_else (not (match_test "flag_pic"))
9273 (if_then_else (lt (abs (minus (pc) (match_dup 0))) (const_int 60000))
9274 (const_int 4) (const_int 6))
9275 (if_then_else (lt (abs (minus (pc) (match_dup 0))) (const_int 60000))
9276 (const_int 4) (const_int 8))))])
9277
9278 ;
9279 ; indirect-jump instruction pattern(s).
9280 ;
9281
9282 (define_insn "indirect_jump"
9283 [(set (pc) (match_operand 0 "address_operand" "ZQZR"))]
9284 ""
9285 {
9286 if (get_attr_op_type (insn) == OP_TYPE_RR)
9287 return "br\t%0";
9288 else
9289 return "b\t%a0";
9290 }
9291 [(set (attr "op_type")
9292 (if_then_else (match_operand 0 "register_operand" "")
9293 (const_string "RR") (const_string "RX")))
9294 (set_attr "type" "branch")
9295 (set_attr "atype" "agen")])
9296
9297 ;
9298 ; casesi instruction pattern(s).
9299 ;
9300
9301 (define_insn "casesi_jump"
9302 [(set (pc) (match_operand 0 "address_operand" "ZQZR"))
9303 (use (label_ref (match_operand 1 "" "")))]
9304 ""
9305 {
9306 if (get_attr_op_type (insn) == OP_TYPE_RR)
9307 return "br\t%0";
9308 else
9309 return "b\t%a0";
9310 }
9311 [(set (attr "op_type")
9312 (if_then_else (match_operand 0 "register_operand" "")
9313 (const_string "RR") (const_string "RX")))
9314 (set_attr "type" "branch")
9315 (set_attr "atype" "agen")])
9316
9317 (define_expand "casesi"
9318 [(match_operand:SI 0 "general_operand" "")
9319 (match_operand:SI 1 "general_operand" "")
9320 (match_operand:SI 2 "general_operand" "")
9321 (label_ref (match_operand 3 "" ""))
9322 (label_ref (match_operand 4 "" ""))]
9323 ""
9324 {
9325 rtx index = gen_reg_rtx (SImode);
9326 rtx base = gen_reg_rtx (Pmode);
9327 rtx target = gen_reg_rtx (Pmode);
9328
9329 emit_move_insn (index, operands[0]);
9330 emit_insn (gen_subsi3 (index, index, operands[1]));
9331 emit_cmp_and_jump_insns (index, operands[2], GTU, NULL_RTX, SImode, 1,
9332 operands[4]);
9333
9334 if (Pmode != SImode)
9335 index = convert_to_mode (Pmode, index, 1);
9336 if (GET_CODE (index) != REG)
9337 index = copy_to_mode_reg (Pmode, index);
9338
9339 if (TARGET_64BIT)
9340 emit_insn (gen_ashldi3 (index, index, GEN_INT (3)));
9341 else
9342 emit_insn (gen_ashlsi3 (index, index, const2_rtx));
9343
9344 emit_move_insn (base, gen_rtx_LABEL_REF (Pmode, operands[3]));
9345
9346 index = gen_const_mem (Pmode, gen_rtx_PLUS (Pmode, base, index));
9347 emit_move_insn (target, index);
9348
9349 if (flag_pic)
9350 target = gen_rtx_PLUS (Pmode, base, target);
9351 emit_jump_insn (gen_casesi_jump (target, operands[3]));
9352
9353 DONE;
9354 })
9355
9356
9357 ;;
9358 ;;- Jump to subroutine.
9359 ;;
9360 ;;
9361
9362 ;
9363 ; untyped call instruction pattern(s).
9364 ;
9365
9366 ;; Call subroutine returning any type.
9367 (define_expand "untyped_call"
9368 [(parallel [(call (match_operand 0 "" "")
9369 (const_int 0))
9370 (match_operand 1 "" "")
9371 (match_operand 2 "" "")])]
9372 ""
9373 {
9374 int i;
9375
9376 emit_call_insn (gen_call (operands[0], const0_rtx, const0_rtx));
9377
9378 for (i = 0; i < XVECLEN (operands[2], 0); i++)
9379 {
9380 rtx set = XVECEXP (operands[2], 0, i);
9381 emit_move_insn (SET_DEST (set), SET_SRC (set));
9382 }
9383
9384 /* The optimizer does not know that the call sets the function value
9385 registers we stored in the result block. We avoid problems by
9386 claiming that all hard registers are used and clobbered at this
9387 point. */
9388 emit_insn (gen_blockage ());
9389
9390 DONE;
9391 })
9392
9393 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
9394 ;; all of memory. This blocks insns from being moved across this point.
9395
9396 (define_insn "blockage"
9397 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
9398 ""
9399 ""
9400 [(set_attr "type" "none")
9401 (set_attr "length" "0")])
9402
9403 ;
9404 ; sibcall patterns
9405 ;
9406
9407 (define_expand "sibcall"
9408 [(call (match_operand 0 "" "")
9409 (match_operand 1 "" ""))]
9410 ""
9411 {
9412 s390_emit_call (XEXP (operands[0], 0), NULL_RTX, NULL_RTX, NULL_RTX);
9413 DONE;
9414 })
9415
9416 (define_insn "*sibcall_br"
9417 [(call (mem:QI (reg SIBCALL_REGNUM))
9418 (match_operand 0 "const_int_operand" "n"))]
9419 "SIBLING_CALL_P (insn)
9420 && GET_MODE (XEXP (XEXP (PATTERN (insn), 0), 0)) == Pmode"
9421 "br\t%%r1"
9422 [(set_attr "op_type" "RR")
9423 (set_attr "type" "branch")
9424 (set_attr "atype" "agen")])
9425
9426 (define_insn "*sibcall_brc"
9427 [(call (mem:QI (match_operand 0 "bras_sym_operand" "X"))
9428 (match_operand 1 "const_int_operand" "n"))]
9429 "SIBLING_CALL_P (insn) && TARGET_SMALL_EXEC"
9430 "j\t%0"
9431 [(set_attr "op_type" "RI")
9432 (set_attr "type" "branch")])
9433
9434 (define_insn "*sibcall_brcl"
9435 [(call (mem:QI (match_operand 0 "bras_sym_operand" "X"))
9436 (match_operand 1 "const_int_operand" "n"))]
9437 "SIBLING_CALL_P (insn) && TARGET_CPU_ZARCH"
9438 "jg\t%0"
9439 [(set_attr "op_type" "RIL")
9440 (set_attr "type" "branch")])
9441
9442 ;
9443 ; sibcall_value patterns
9444 ;
9445
9446 (define_expand "sibcall_value"
9447 [(set (match_operand 0 "" "")
9448 (call (match_operand 1 "" "")
9449 (match_operand 2 "" "")))]
9450 ""
9451 {
9452 s390_emit_call (XEXP (operands[1], 0), NULL_RTX, operands[0], NULL_RTX);
9453 DONE;
9454 })
9455
9456 (define_insn "*sibcall_value_br"
9457 [(set (match_operand 0 "" "")
9458 (call (mem:QI (reg SIBCALL_REGNUM))
9459 (match_operand 1 "const_int_operand" "n")))]
9460 "SIBLING_CALL_P (insn)
9461 && GET_MODE (XEXP (XEXP (XEXP (PATTERN (insn), 1), 0), 0)) == Pmode"
9462 "br\t%%r1"
9463 [(set_attr "op_type" "RR")
9464 (set_attr "type" "branch")
9465 (set_attr "atype" "agen")])
9466
9467 (define_insn "*sibcall_value_brc"
9468 [(set (match_operand 0 "" "")
9469 (call (mem:QI (match_operand 1 "bras_sym_operand" "X"))
9470 (match_operand 2 "const_int_operand" "n")))]
9471 "SIBLING_CALL_P (insn) && TARGET_SMALL_EXEC"
9472 "j\t%1"
9473 [(set_attr "op_type" "RI")
9474 (set_attr "type" "branch")])
9475
9476 (define_insn "*sibcall_value_brcl"
9477 [(set (match_operand 0 "" "")
9478 (call (mem:QI (match_operand 1 "bras_sym_operand" "X"))
9479 (match_operand 2 "const_int_operand" "n")))]
9480 "SIBLING_CALL_P (insn) && TARGET_CPU_ZARCH"
9481 "jg\t%1"
9482 [(set_attr "op_type" "RIL")
9483 (set_attr "type" "branch")])
9484
9485
9486 ;
9487 ; call instruction pattern(s).
9488 ;
9489
9490 (define_expand "call"
9491 [(call (match_operand 0 "" "")
9492 (match_operand 1 "" ""))
9493 (use (match_operand 2 "" ""))]
9494 ""
9495 {
9496 s390_emit_call (XEXP (operands[0], 0), NULL_RTX, NULL_RTX,
9497 gen_rtx_REG (Pmode, RETURN_REGNUM));
9498 DONE;
9499 })
9500
9501 (define_insn "*bras"
9502 [(call (mem:QI (match_operand 0 "bras_sym_operand" "X"))
9503 (match_operand 1 "const_int_operand" "n"))
9504 (clobber (match_operand 2 "register_operand" "=r"))]
9505 "!SIBLING_CALL_P (insn)
9506 && TARGET_SMALL_EXEC
9507 && GET_MODE (operands[2]) == Pmode"
9508 "bras\t%2,%0"
9509 [(set_attr "op_type" "RI")
9510 (set_attr "type" "jsr")
9511 (set_attr "z196prop" "z196_cracked")])
9512
9513 (define_insn "*brasl"
9514 [(call (mem:QI (match_operand 0 "bras_sym_operand" "X"))
9515 (match_operand 1 "const_int_operand" "n"))
9516 (clobber (match_operand 2 "register_operand" "=r"))]
9517 "!SIBLING_CALL_P (insn)
9518 && TARGET_CPU_ZARCH
9519 && GET_MODE (operands[2]) == Pmode"
9520 "brasl\t%2,%0"
9521 [(set_attr "op_type" "RIL")
9522 (set_attr "type" "jsr")
9523 (set_attr "z196prop" "z196_cracked")])
9524
9525 (define_insn "*basr"
9526 [(call (mem:QI (match_operand 0 "address_operand" "ZQZR"))
9527 (match_operand 1 "const_int_operand" "n"))
9528 (clobber (match_operand 2 "register_operand" "=r"))]
9529 "!SIBLING_CALL_P (insn) && GET_MODE (operands[2]) == Pmode"
9530 {
9531 if (get_attr_op_type (insn) == OP_TYPE_RR)
9532 return "basr\t%2,%0";
9533 else
9534 return "bas\t%2,%a0";
9535 }
9536 [(set (attr "op_type")
9537 (if_then_else (match_operand 0 "register_operand" "")
9538 (const_string "RR") (const_string "RX")))
9539 (set_attr "type" "jsr")
9540 (set_attr "atype" "agen")
9541 (set_attr "z196prop" "z196_cracked")])
9542
9543 ;
9544 ; call_value instruction pattern(s).
9545 ;
9546
9547 (define_expand "call_value"
9548 [(set (match_operand 0 "" "")
9549 (call (match_operand 1 "" "")
9550 (match_operand 2 "" "")))
9551 (use (match_operand 3 "" ""))]
9552 ""
9553 {
9554 s390_emit_call (XEXP (operands[1], 0), NULL_RTX, operands[0],
9555 gen_rtx_REG (Pmode, RETURN_REGNUM));
9556 DONE;
9557 })
9558
9559 (define_insn "*bras_r"
9560 [(set (match_operand 0 "" "")
9561 (call (mem:QI (match_operand 1 "bras_sym_operand" "X"))
9562 (match_operand:SI 2 "const_int_operand" "n")))
9563 (clobber (match_operand 3 "register_operand" "=r"))]
9564 "!SIBLING_CALL_P (insn)
9565 && TARGET_SMALL_EXEC
9566 && GET_MODE (operands[3]) == Pmode"
9567 "bras\t%3,%1"
9568 [(set_attr "op_type" "RI")
9569 (set_attr "type" "jsr")
9570 (set_attr "z196prop" "z196_cracked")])
9571
9572 (define_insn "*brasl_r"
9573 [(set (match_operand 0 "" "")
9574 (call (mem:QI (match_operand 1 "bras_sym_operand" "X"))
9575 (match_operand 2 "const_int_operand" "n")))
9576 (clobber (match_operand 3 "register_operand" "=r"))]
9577 "!SIBLING_CALL_P (insn)
9578 && TARGET_CPU_ZARCH
9579 && GET_MODE (operands[3]) == Pmode"
9580 "brasl\t%3,%1"
9581 [(set_attr "op_type" "RIL")
9582 (set_attr "type" "jsr")
9583 (set_attr "z196prop" "z196_cracked")])
9584
9585 (define_insn "*basr_r"
9586 [(set (match_operand 0 "" "")
9587 (call (mem:QI (match_operand 1 "address_operand" "ZQZR"))
9588 (match_operand 2 "const_int_operand" "n")))
9589 (clobber (match_operand 3 "register_operand" "=r"))]
9590 "!SIBLING_CALL_P (insn) && GET_MODE (operands[3]) == Pmode"
9591 {
9592 if (get_attr_op_type (insn) == OP_TYPE_RR)
9593 return "basr\t%3,%1";
9594 else
9595 return "bas\t%3,%a1";
9596 }
9597 [(set (attr "op_type")
9598 (if_then_else (match_operand 1 "register_operand" "")
9599 (const_string "RR") (const_string "RX")))
9600 (set_attr "type" "jsr")
9601 (set_attr "atype" "agen")
9602 (set_attr "z196prop" "z196_cracked")])
9603
9604 ;;
9605 ;;- Thread-local storage support.
9606 ;;
9607
9608 (define_expand "get_thread_pointer<mode>"
9609 [(set (match_operand:P 0 "nonimmediate_operand" "") (reg:P TP_REGNUM))]
9610 ""
9611 "")
9612
9613 (define_expand "set_thread_pointer<mode>"
9614 [(set (reg:P TP_REGNUM) (match_operand:P 0 "nonimmediate_operand" ""))
9615 (set (reg:P TP_REGNUM) (unspec_volatile:P [(reg:P TP_REGNUM)] UNSPECV_SET_TP))]
9616 ""
9617 "")
9618
9619 (define_insn "*set_tp"
9620 [(set (reg TP_REGNUM) (unspec_volatile [(reg TP_REGNUM)] UNSPECV_SET_TP))]
9621 ""
9622 ""
9623 [(set_attr "type" "none")
9624 (set_attr "length" "0")])
9625
9626 (define_insn "*tls_load_64"
9627 [(set (match_operand:DI 0 "register_operand" "=d")
9628 (unspec:DI [(match_operand:DI 1 "memory_operand" "RT")
9629 (match_operand:DI 2 "" "")]
9630 UNSPEC_TLS_LOAD))]
9631 "TARGET_64BIT"
9632 "lg\t%0,%1%J2"
9633 [(set_attr "op_type" "RXE")
9634 (set_attr "z10prop" "z10_fwd_A3")])
9635
9636 (define_insn "*tls_load_31"
9637 [(set (match_operand:SI 0 "register_operand" "=d,d")
9638 (unspec:SI [(match_operand:SI 1 "memory_operand" "R,T")
9639 (match_operand:SI 2 "" "")]
9640 UNSPEC_TLS_LOAD))]
9641 "!TARGET_64BIT"
9642 "@
9643 l\t%0,%1%J2
9644 ly\t%0,%1%J2"
9645 [(set_attr "op_type" "RX,RXY")
9646 (set_attr "type" "load")
9647 (set_attr "z10prop" "z10_fwd_A3,z10_fwd_A3")])
9648
9649 (define_insn "*bras_tls"
9650 [(set (match_operand 0 "" "")
9651 (call (mem:QI (match_operand 1 "bras_sym_operand" "X"))
9652 (match_operand 2 "const_int_operand" "n")))
9653 (clobber (match_operand 3 "register_operand" "=r"))
9654 (use (match_operand 4 "" ""))]
9655 "!SIBLING_CALL_P (insn)
9656 && TARGET_SMALL_EXEC
9657 && GET_MODE (operands[3]) == Pmode"
9658 "bras\t%3,%1%J4"
9659 [(set_attr "op_type" "RI")
9660 (set_attr "type" "jsr")
9661 (set_attr "z196prop" "z196_cracked")])
9662
9663 (define_insn "*brasl_tls"
9664 [(set (match_operand 0 "" "")
9665 (call (mem:QI (match_operand 1 "bras_sym_operand" "X"))
9666 (match_operand 2 "const_int_operand" "n")))
9667 (clobber (match_operand 3 "register_operand" "=r"))
9668 (use (match_operand 4 "" ""))]
9669 "!SIBLING_CALL_P (insn)
9670 && TARGET_CPU_ZARCH
9671 && GET_MODE (operands[3]) == Pmode"
9672 "brasl\t%3,%1%J4"
9673 [(set_attr "op_type" "RIL")
9674 (set_attr "type" "jsr")
9675 (set_attr "z196prop" "z196_cracked")])
9676
9677 (define_insn "*basr_tls"
9678 [(set (match_operand 0 "" "")
9679 (call (mem:QI (match_operand 1 "address_operand" "ZQZR"))
9680 (match_operand 2 "const_int_operand" "n")))
9681 (clobber (match_operand 3 "register_operand" "=r"))
9682 (use (match_operand 4 "" ""))]
9683 "!SIBLING_CALL_P (insn) && GET_MODE (operands[3]) == Pmode"
9684 {
9685 if (get_attr_op_type (insn) == OP_TYPE_RR)
9686 return "basr\t%3,%1%J4";
9687 else
9688 return "bas\t%3,%a1%J4";
9689 }
9690 [(set (attr "op_type")
9691 (if_then_else (match_operand 1 "register_operand" "")
9692 (const_string "RR") (const_string "RX")))
9693 (set_attr "type" "jsr")
9694 (set_attr "atype" "agen")
9695 (set_attr "z196prop" "z196_cracked")])
9696
9697 ;;
9698 ;;- Atomic operations
9699 ;;
9700
9701 ;
9702 ; memory barrier patterns.
9703 ;
9704
9705 (define_expand "mem_signal_fence"
9706 [(match_operand:SI 0 "const_int_operand")] ;; model
9707 ""
9708 {
9709 /* The s390 memory model is strong enough not to require any
9710 barrier in order to synchronize a thread with itself. */
9711 DONE;
9712 })
9713
9714 (define_expand "mem_thread_fence"
9715 [(match_operand:SI 0 "const_int_operand")] ;; model
9716 ""
9717 {
9718 /* Unless this is a SEQ_CST fence, the s390 memory model is strong
9719 enough not to require barriers of any kind. */
9720 if (is_mm_seq_cst (memmodel_from_int (INTVAL (operands[0]))))
9721 {
9722 rtx mem = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
9723 MEM_VOLATILE_P (mem) = 1;
9724 emit_insn (gen_mem_thread_fence_1 (mem));
9725 }
9726 DONE;
9727 })
9728
9729 ; Although bcr is superscalar on Z10, this variant will never
9730 ; become part of an execution group.
9731 ; With z196 we can make use of the fast-BCR-serialization facility.
9732 ; This allows for a slightly faster sync which is sufficient for our
9733 ; purposes.
9734 (define_insn "mem_thread_fence_1"
9735 [(set (match_operand:BLK 0 "" "")
9736 (unspec:BLK [(match_dup 0)] UNSPEC_MB))]
9737 ""
9738 {
9739 if (TARGET_Z196)
9740 return "bcr\t14,0";
9741 else
9742 return "bcr\t15,0";
9743 }
9744 [(set_attr "op_type" "RR")
9745 (set_attr "mnemonic" "bcr_flush")
9746 (set_attr "z196prop" "z196_alone")])
9747
9748 ;
9749 ; atomic load/store operations
9750 ;
9751
9752 ; Atomic loads need not examine the memory model at all.
9753 (define_expand "atomic_load<mode>"
9754 [(match_operand:DINT 0 "register_operand") ;; output
9755 (match_operand:DINT 1 "memory_operand") ;; memory
9756 (match_operand:SI 2 "const_int_operand")] ;; model
9757 ""
9758 {
9759 if (MEM_ALIGN (operands[1]) < GET_MODE_BITSIZE (GET_MODE (operands[1])))
9760 FAIL;
9761
9762 if (<MODE>mode == TImode)
9763 emit_insn (gen_atomic_loadti_1 (operands[0], operands[1]));
9764 else if (<MODE>mode == DImode && !TARGET_ZARCH)
9765 emit_insn (gen_atomic_loaddi_1 (operands[0], operands[1]));
9766 else
9767 emit_move_insn (operands[0], operands[1]);
9768 DONE;
9769 })
9770
9771 ; Different from movdi_31 in that we want no splitters.
9772 (define_insn "atomic_loaddi_1"
9773 [(set (match_operand:DI 0 "register_operand" "=d,d,!*f,!*f")
9774 (unspec:DI [(match_operand:DI 1 "memory_operand" "Q,S,R,T")]
9775 UNSPEC_MOVA))]
9776 "!TARGET_ZARCH"
9777 "@
9778 lm\t%0,%M0,%S1
9779 lmy\t%0,%M0,%S1
9780 ld\t%0,%1
9781 ldy\t%0,%1"
9782 [(set_attr "op_type" "RS,RSY,RS,RSY")
9783 (set_attr "type" "lm,lm,floaddf,floaddf")])
9784
9785 (define_insn "atomic_loadti_1"
9786 [(set (match_operand:TI 0 "register_operand" "=r")
9787 (unspec:TI [(match_operand:TI 1 "memory_operand" "RT")]
9788 UNSPEC_MOVA))]
9789 "TARGET_ZARCH"
9790 "lpq\t%0,%1"
9791 [(set_attr "op_type" "RXY")
9792 (set_attr "type" "other")])
9793
9794 ; Atomic stores must(?) enforce sequential consistency.
9795 (define_expand "atomic_store<mode>"
9796 [(match_operand:DINT 0 "memory_operand") ;; memory
9797 (match_operand:DINT 1 "register_operand") ;; input
9798 (match_operand:SI 2 "const_int_operand")] ;; model
9799 ""
9800 {
9801 enum memmodel model = memmodel_from_int (INTVAL (operands[2]));
9802
9803 if (MEM_ALIGN (operands[0]) < GET_MODE_BITSIZE (GET_MODE (operands[0])))
9804 FAIL;
9805
9806 if (<MODE>mode == TImode)
9807 emit_insn (gen_atomic_storeti_1 (operands[0], operands[1]));
9808 else if (<MODE>mode == DImode && !TARGET_ZARCH)
9809 emit_insn (gen_atomic_storedi_1 (operands[0], operands[1]));
9810 else
9811 emit_move_insn (operands[0], operands[1]);
9812 if (is_mm_seq_cst (model))
9813 emit_insn (gen_mem_thread_fence (operands[2]));
9814 DONE;
9815 })
9816
9817 ; Different from movdi_31 in that we want no splitters.
9818 (define_insn "atomic_storedi_1"
9819 [(set (match_operand:DI 0 "memory_operand" "=Q,S,R,T")
9820 (unspec:DI [(match_operand:DI 1 "register_operand" "d,d,!*f,!*f")]
9821 UNSPEC_MOVA))]
9822 "!TARGET_ZARCH"
9823 "@
9824 stm\t%1,%N1,%S0
9825 stmy\t%1,%N1,%S0
9826 std %1,%0
9827 stdy %1,%0"
9828 [(set_attr "op_type" "RS,RSY,RS,RSY")
9829 (set_attr "type" "stm,stm,fstoredf,fstoredf")])
9830
9831 (define_insn "atomic_storeti_1"
9832 [(set (match_operand:TI 0 "memory_operand" "=RT")
9833 (unspec:TI [(match_operand:TI 1 "register_operand" "r")]
9834 UNSPEC_MOVA))]
9835 "TARGET_ZARCH"
9836 "stpq\t%1,%0"
9837 [(set_attr "op_type" "RXY")
9838 (set_attr "type" "other")])
9839
9840 ;
9841 ; compare and swap patterns.
9842 ;
9843
9844 (define_expand "atomic_compare_and_swap<mode>"
9845 [(match_operand:SI 0 "register_operand") ;; bool success output
9846 (match_operand:DGPR 1 "nonimmediate_operand");; oldval output
9847 (match_operand:DGPR 2 "memory_operand") ;; memory
9848 (match_operand:DGPR 3 "register_operand") ;; expected intput
9849 (match_operand:DGPR 4 "register_operand") ;; newval intput
9850 (match_operand:SI 5 "const_int_operand") ;; is_weak
9851 (match_operand:SI 6 "const_int_operand") ;; success model
9852 (match_operand:SI 7 "const_int_operand")] ;; failure model
9853 ""
9854 {
9855 rtx cc, cmp, output = operands[1];
9856
9857 if (!register_operand (output, <MODE>mode))
9858 output = gen_reg_rtx (<MODE>mode);
9859
9860 if (MEM_ALIGN (operands[2]) < GET_MODE_BITSIZE (GET_MODE (operands[2])))
9861 FAIL;
9862
9863 emit_insn (gen_atomic_compare_and_swap<mode>_internal
9864 (output, operands[2], operands[3], operands[4]));
9865
9866 /* We deliberately accept non-register operands in the predicate
9867 to ensure the write back to the output operand happens *before*
9868 the store-flags code below. This makes it easier for combine
9869 to merge the store-flags code with a potential test-and-branch
9870 pattern following (immediately!) afterwards. */
9871 if (output != operands[1])
9872 emit_move_insn (operands[1], output);
9873
9874 cc = gen_rtx_REG (CCZ1mode, CC_REGNUM);
9875 cmp = gen_rtx_EQ (SImode, cc, const0_rtx);
9876 emit_insn (gen_cstorecc4 (operands[0], cmp, cc, const0_rtx));
9877 DONE;
9878 })
9879
9880 (define_expand "atomic_compare_and_swap<mode>"
9881 [(match_operand:SI 0 "register_operand") ;; bool success output
9882 (match_operand:HQI 1 "nonimmediate_operand") ;; oldval output
9883 (match_operand:HQI 2 "memory_operand") ;; memory
9884 (match_operand:HQI 3 "general_operand") ;; expected intput
9885 (match_operand:HQI 4 "general_operand") ;; newval intput
9886 (match_operand:SI 5 "const_int_operand") ;; is_weak
9887 (match_operand:SI 6 "const_int_operand") ;; success model
9888 (match_operand:SI 7 "const_int_operand")] ;; failure model
9889 ""
9890 {
9891 s390_expand_cs_hqi (<MODE>mode, operands[0], operands[1], operands[2],
9892 operands[3], operands[4], INTVAL (operands[5]));
9893 DONE;
9894 })
9895
9896 (define_expand "atomic_compare_and_swap<mode>_internal"
9897 [(parallel
9898 [(set (match_operand:DGPR 0 "register_operand")
9899 (match_operand:DGPR 1 "memory_operand"))
9900 (set (match_dup 1)
9901 (unspec_volatile:DGPR
9902 [(match_dup 1)
9903 (match_operand:DGPR 2 "register_operand")
9904 (match_operand:DGPR 3 "register_operand")]
9905 UNSPECV_CAS))
9906 (set (reg:CCZ1 CC_REGNUM)
9907 (compare:CCZ1 (match_dup 1) (match_dup 2)))])]
9908 "")
9909
9910 ; cdsg, csg
9911 (define_insn "*atomic_compare_and_swap<mode>_1"
9912 [(set (match_operand:TDI 0 "register_operand" "=r")
9913 (match_operand:TDI 1 "memory_operand" "+QS"))
9914 (set (match_dup 1)
9915 (unspec_volatile:TDI
9916 [(match_dup 1)
9917 (match_operand:TDI 2 "register_operand" "0")
9918 (match_operand:TDI 3 "register_operand" "r")]
9919 UNSPECV_CAS))
9920 (set (reg:CCZ1 CC_REGNUM)
9921 (compare:CCZ1 (match_dup 1) (match_dup 2)))]
9922 "TARGET_ZARCH"
9923 "c<td>sg\t%0,%3,%S1"
9924 [(set_attr "op_type" "RSY")
9925 (set_attr "type" "sem")])
9926
9927 ; cds, cdsy
9928 (define_insn "*atomic_compare_and_swapdi_2"
9929 [(set (match_operand:DI 0 "register_operand" "=r,r")
9930 (match_operand:DI 1 "memory_operand" "+Q,S"))
9931 (set (match_dup 1)
9932 (unspec_volatile:DI
9933 [(match_dup 1)
9934 (match_operand:DI 2 "register_operand" "0,0")
9935 (match_operand:DI 3 "register_operand" "r,r")]
9936 UNSPECV_CAS))
9937 (set (reg:CCZ1 CC_REGNUM)
9938 (compare:CCZ1 (match_dup 1) (match_dup 2)))]
9939 "!TARGET_ZARCH"
9940 "@
9941 cds\t%0,%3,%S1
9942 cdsy\t%0,%3,%S1"
9943 [(set_attr "op_type" "RS,RSY")
9944 (set_attr "type" "sem")])
9945
9946 ; cs, csy
9947 (define_insn "*atomic_compare_and_swapsi_3"
9948 [(set (match_operand:SI 0 "register_operand" "=r,r")
9949 (match_operand:SI 1 "memory_operand" "+Q,S"))
9950 (set (match_dup 1)
9951 (unspec_volatile:SI
9952 [(match_dup 1)
9953 (match_operand:SI 2 "register_operand" "0,0")
9954 (match_operand:SI 3 "register_operand" "r,r")]
9955 UNSPECV_CAS))
9956 (set (reg:CCZ1 CC_REGNUM)
9957 (compare:CCZ1 (match_dup 1) (match_dup 2)))]
9958 ""
9959 "@
9960 cs\t%0,%3,%S1
9961 csy\t%0,%3,%S1"
9962 [(set_attr "op_type" "RS,RSY")
9963 (set_attr "type" "sem")])
9964
9965 ;
9966 ; Other atomic instruction patterns.
9967 ;
9968
9969 ; z196 load and add, xor, or and and instructions
9970
9971 (define_expand "atomic_fetch_<atomic><mode>"
9972 [(match_operand:GPR 0 "register_operand") ;; val out
9973 (ATOMIC_Z196:GPR
9974 (match_operand:GPR 1 "memory_operand") ;; memory
9975 (match_operand:GPR 2 "register_operand")) ;; val in
9976 (match_operand:SI 3 "const_int_operand")] ;; model
9977 "TARGET_Z196"
9978 {
9979 if (MEM_ALIGN (operands[1]) < GET_MODE_BITSIZE (GET_MODE (operands[1])))
9980 FAIL;
9981
9982 emit_insn (gen_atomic_fetch_<atomic><mode>_iaf
9983 (operands[0], operands[1], operands[2]));
9984 DONE;
9985 })
9986
9987 ; lan, lang, lao, laog, lax, laxg, laa, laag
9988 (define_insn "atomic_fetch_<atomic><mode>_iaf"
9989 [(set (match_operand:GPR 0 "register_operand" "=d")
9990 (match_operand:GPR 1 "memory_operand" "+QS"))
9991 (set (match_dup 1)
9992 (unspec_volatile:GPR
9993 [(ATOMIC_Z196:GPR (match_dup 1)
9994 (match_operand:GPR 2 "general_operand" "d"))]
9995 UNSPECV_ATOMIC_OP))
9996 (clobber (reg:CC CC_REGNUM))]
9997 "TARGET_Z196"
9998 "la<noxa><g>\t%0,%2,%1"
9999 [(set_attr "op_type" "RSY")
10000 (set_attr "type" "sem")])
10001
10002 ;; For SImode and larger, the optabs.c code will do just fine in
10003 ;; expanding a compare-and-swap loop. For QI/HImode, we can do
10004 ;; better by expanding our own loop.
10005
10006 (define_expand "atomic_<atomic><mode>"
10007 [(ATOMIC:HQI
10008 (match_operand:HQI 0 "memory_operand") ;; memory
10009 (match_operand:HQI 1 "general_operand")) ;; val in
10010 (match_operand:SI 2 "const_int_operand")] ;; model
10011 ""
10012 {
10013 s390_expand_atomic (<MODE>mode, <CODE>, NULL_RTX, operands[0],
10014 operands[1], false);
10015 DONE;
10016 })
10017
10018 (define_expand "atomic_fetch_<atomic><mode>"
10019 [(match_operand:HQI 0 "register_operand") ;; val out
10020 (ATOMIC:HQI
10021 (match_operand:HQI 1 "memory_operand") ;; memory
10022 (match_operand:HQI 2 "general_operand")) ;; val in
10023 (match_operand:SI 3 "const_int_operand")] ;; model
10024 ""
10025 {
10026 s390_expand_atomic (<MODE>mode, <CODE>, operands[0], operands[1],
10027 operands[2], false);
10028 DONE;
10029 })
10030
10031 (define_expand "atomic_<atomic>_fetch<mode>"
10032 [(match_operand:HQI 0 "register_operand") ;; val out
10033 (ATOMIC:HQI
10034 (match_operand:HQI 1 "memory_operand") ;; memory
10035 (match_operand:HQI 2 "general_operand")) ;; val in
10036 (match_operand:SI 3 "const_int_operand")] ;; model
10037 ""
10038 {
10039 s390_expand_atomic (<MODE>mode, <CODE>, operands[0], operands[1],
10040 operands[2], true);
10041 DONE;
10042 })
10043
10044 (define_expand "atomic_exchange<mode>"
10045 [(match_operand:HQI 0 "register_operand") ;; val out
10046 (match_operand:HQI 1 "memory_operand") ;; memory
10047 (match_operand:HQI 2 "general_operand") ;; val in
10048 (match_operand:SI 3 "const_int_operand")] ;; model
10049 ""
10050 {
10051 s390_expand_atomic (<MODE>mode, SET, operands[0], operands[1],
10052 operands[2], false);
10053 DONE;
10054 })
10055
10056 ;;
10057 ;;- Miscellaneous instructions.
10058 ;;
10059
10060 ;
10061 ; allocate stack instruction pattern(s).
10062 ;
10063
10064 (define_expand "allocate_stack"
10065 [(match_operand 0 "general_operand" "")
10066 (match_operand 1 "general_operand" "")]
10067 "TARGET_BACKCHAIN"
10068 {
10069 rtx temp = gen_reg_rtx (Pmode);
10070
10071 emit_move_insn (temp, s390_back_chain_rtx ());
10072 anti_adjust_stack (operands[1]);
10073 emit_move_insn (s390_back_chain_rtx (), temp);
10074
10075 emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
10076 DONE;
10077 })
10078
10079
10080 ;
10081 ; setjmp instruction pattern.
10082 ;
10083
10084 (define_expand "builtin_setjmp_receiver"
10085 [(match_operand 0 "" "")]
10086 "flag_pic"
10087 {
10088 emit_insn (s390_load_got ());
10089 emit_use (pic_offset_table_rtx);
10090 DONE;
10091 })
10092
10093 ;; These patterns say how to save and restore the stack pointer. We need not
10094 ;; save the stack pointer at function level since we are careful to
10095 ;; preserve the backchain. At block level, we have to restore the backchain
10096 ;; when we restore the stack pointer.
10097 ;;
10098 ;; For nonlocal gotos, we must save both the stack pointer and its
10099 ;; backchain and restore both. Note that in the nonlocal case, the
10100 ;; save area is a memory location.
10101
10102 (define_expand "save_stack_function"
10103 [(match_operand 0 "general_operand" "")
10104 (match_operand 1 "general_operand" "")]
10105 ""
10106 "DONE;")
10107
10108 (define_expand "restore_stack_function"
10109 [(match_operand 0 "general_operand" "")
10110 (match_operand 1 "general_operand" "")]
10111 ""
10112 "DONE;")
10113
10114 (define_expand "restore_stack_block"
10115 [(match_operand 0 "register_operand" "")
10116 (match_operand 1 "register_operand" "")]
10117 "TARGET_BACKCHAIN"
10118 {
10119 rtx temp = gen_reg_rtx (Pmode);
10120
10121 emit_move_insn (temp, s390_back_chain_rtx ());
10122 emit_move_insn (operands[0], operands[1]);
10123 emit_move_insn (s390_back_chain_rtx (), temp);
10124
10125 DONE;
10126 })
10127
10128 (define_expand "save_stack_nonlocal"
10129 [(match_operand 0 "memory_operand" "")
10130 (match_operand 1 "register_operand" "")]
10131 ""
10132 {
10133 rtx base = gen_rtx_REG (Pmode, BASE_REGNUM);
10134
10135 /* Copy the backchain to the first word, sp to the second and the
10136 literal pool base to the third. */
10137
10138 rtx save_bc = adjust_address (operands[0], Pmode, 0);
10139 rtx save_sp = adjust_address (operands[0], Pmode, GET_MODE_SIZE (Pmode));
10140 rtx save_bp = adjust_address (operands[0], Pmode, 2 * GET_MODE_SIZE (Pmode));
10141
10142 if (TARGET_BACKCHAIN)
10143 emit_move_insn (save_bc, force_reg (Pmode, s390_back_chain_rtx ()));
10144
10145 emit_move_insn (save_sp, operands[1]);
10146 emit_move_insn (save_bp, base);
10147
10148 DONE;
10149 })
10150
10151 (define_expand "restore_stack_nonlocal"
10152 [(match_operand 0 "register_operand" "")
10153 (match_operand 1 "memory_operand" "")]
10154 ""
10155 {
10156 rtx base = gen_rtx_REG (Pmode, BASE_REGNUM);
10157 rtx temp = NULL_RTX;
10158
10159 /* Restore the backchain from the first word, sp from the second and the
10160 literal pool base from the third. */
10161
10162 rtx save_bc = adjust_address (operands[1], Pmode, 0);
10163 rtx save_sp = adjust_address (operands[1], Pmode, GET_MODE_SIZE (Pmode));
10164 rtx save_bp = adjust_address (operands[1], Pmode, 2 * GET_MODE_SIZE (Pmode));
10165
10166 if (TARGET_BACKCHAIN)
10167 temp = force_reg (Pmode, save_bc);
10168
10169 emit_move_insn (base, save_bp);
10170 emit_move_insn (operands[0], save_sp);
10171
10172 if (temp)
10173 emit_move_insn (s390_back_chain_rtx (), temp);
10174
10175 emit_use (base);
10176 DONE;
10177 })
10178
10179 (define_expand "exception_receiver"
10180 [(const_int 0)]
10181 ""
10182 {
10183 s390_set_has_landing_pad_p (true);
10184 DONE;
10185 })
10186
10187 ;
10188 ; nop instruction pattern(s).
10189 ;
10190
10191 (define_insn "nop"
10192 [(const_int 0)]
10193 ""
10194 "lr\t0,0"
10195 [(set_attr "op_type" "RR")
10196 (set_attr "z10prop" "z10_fr_E1")])
10197
10198 (define_insn "nop1"
10199 [(const_int 1)]
10200 ""
10201 "lr\t1,1"
10202 [(set_attr "op_type" "RR")])
10203
10204 ;;- Undeletable nops (used for hotpatching)
10205
10206 (define_insn "nop_2_byte"
10207 [(unspec_volatile [(const_int 0)] UNSPECV_NOP_2_BYTE)]
10208 ""
10209 "nopr\t%%r7"
10210 [(set_attr "op_type" "RR")])
10211
10212 (define_insn "nop_4_byte"
10213 [(unspec_volatile [(const_int 0)] UNSPECV_NOP_4_BYTE)]
10214 ""
10215 "nop\t0"
10216 [(set_attr "op_type" "RX")])
10217
10218 (define_insn "nop_6_byte"
10219 [(unspec_volatile [(const_int 0)] UNSPECV_NOP_6_BYTE)]
10220 "TARGET_CPU_ZARCH"
10221 "brcl\t0, 0"
10222 [(set_attr "op_type" "RIL")])
10223
10224
10225 ;
10226 ; Special literal pool access instruction pattern(s).
10227 ;
10228
10229 (define_insn "*pool_entry"
10230 [(unspec_volatile [(match_operand 0 "consttable_operand" "X")]
10231 UNSPECV_POOL_ENTRY)]
10232 ""
10233 {
10234 machine_mode mode = GET_MODE (PATTERN (insn));
10235 unsigned int align = GET_MODE_BITSIZE (mode);
10236 s390_output_pool_entry (operands[0], mode, align);
10237 return "";
10238 }
10239 [(set (attr "length")
10240 (symbol_ref "GET_MODE_SIZE (GET_MODE (PATTERN (insn)))"))])
10241
10242 (define_insn "pool_align"
10243 [(unspec_volatile [(match_operand 0 "const_int_operand" "n")]
10244 UNSPECV_POOL_ALIGN)]
10245 ""
10246 ".align\t%0"
10247 [(set (attr "length") (symbol_ref "INTVAL (operands[0])"))])
10248
10249 (define_insn "pool_section_start"
10250 [(unspec_volatile [(const_int 1)] UNSPECV_POOL_SECTION)]
10251 ""
10252 {
10253 switch_to_section (targetm.asm_out.function_rodata_section
10254 (current_function_decl));
10255 return "";
10256 }
10257 [(set_attr "length" "0")])
10258
10259 (define_insn "pool_section_end"
10260 [(unspec_volatile [(const_int 0)] UNSPECV_POOL_SECTION)]
10261 ""
10262 {
10263 switch_to_section (current_function_section ());
10264 return "";
10265 }
10266 [(set_attr "length" "0")])
10267
10268 (define_insn "main_base_31_small"
10269 [(set (match_operand 0 "register_operand" "=a")
10270 (unspec [(label_ref (match_operand 1 "" ""))] UNSPEC_MAIN_BASE))]
10271 "!TARGET_CPU_ZARCH && GET_MODE (operands[0]) == Pmode"
10272 "basr\t%0,0"
10273 [(set_attr "op_type" "RR")
10274 (set_attr "type" "la")
10275 (set_attr "z196prop" "z196_cracked")])
10276
10277 (define_insn "main_base_31_large"
10278 [(set (match_operand 0 "register_operand" "=a")
10279 (unspec [(label_ref (match_operand 1 "" ""))] UNSPEC_MAIN_BASE))
10280 (set (pc) (label_ref (match_operand 2 "" "")))]
10281 "!TARGET_CPU_ZARCH && GET_MODE (operands[0]) == Pmode"
10282 "bras\t%0,%2"
10283 [(set_attr "op_type" "RI")
10284 (set_attr "z196prop" "z196_cracked")])
10285
10286 (define_insn "main_base_64"
10287 [(set (match_operand 0 "register_operand" "=a")
10288 (unspec [(label_ref (match_operand 1 "" ""))] UNSPEC_MAIN_BASE))]
10289 "TARGET_CPU_ZARCH && GET_MODE (operands[0]) == Pmode"
10290 "larl\t%0,%1"
10291 [(set_attr "op_type" "RIL")
10292 (set_attr "type" "larl")
10293 (set_attr "z10prop" "z10_fwd_A1")])
10294
10295 (define_insn "main_pool"
10296 [(set (match_operand 0 "register_operand" "=a")
10297 (unspec_volatile [(const_int 0)] UNSPECV_MAIN_POOL))]
10298 "GET_MODE (operands[0]) == Pmode"
10299 {
10300 gcc_unreachable ();
10301 }
10302 [(set (attr "type")
10303 (if_then_else (match_test "TARGET_CPU_ZARCH")
10304 (const_string "larl") (const_string "la")))])
10305
10306 (define_insn "reload_base_31"
10307 [(set (match_operand 0 "register_operand" "=a")
10308 (unspec [(label_ref (match_operand 1 "" ""))] UNSPEC_RELOAD_BASE))]
10309 "!TARGET_CPU_ZARCH && GET_MODE (operands[0]) == Pmode"
10310 "basr\t%0,0\;la\t%0,%1-.(%0)"
10311 [(set_attr "length" "6")
10312 (set_attr "type" "la")
10313 (set_attr "z196prop" "z196_cracked")])
10314
10315 (define_insn "reload_base_64"
10316 [(set (match_operand 0 "register_operand" "=a")
10317 (unspec [(label_ref (match_operand 1 "" ""))] UNSPEC_RELOAD_BASE))]
10318 "TARGET_CPU_ZARCH && GET_MODE (operands[0]) == Pmode"
10319 "larl\t%0,%1"
10320 [(set_attr "op_type" "RIL")
10321 (set_attr "type" "larl")
10322 (set_attr "z10prop" "z10_fwd_A1")])
10323
10324 (define_insn "pool"
10325 [(unspec_volatile [(match_operand 0 "const_int_operand" "n")] UNSPECV_POOL)]
10326 ""
10327 {
10328 gcc_unreachable ();
10329 }
10330 [(set (attr "length") (symbol_ref "INTVAL (operands[0])"))])
10331
10332 ;;
10333 ;; Insns related to generating the function prologue and epilogue.
10334 ;;
10335
10336
10337 (define_expand "prologue"
10338 [(use (const_int 0))]
10339 ""
10340 "s390_emit_prologue (); DONE;")
10341
10342 (define_expand "epilogue"
10343 [(use (const_int 1))]
10344 ""
10345 "s390_emit_epilogue (false); DONE;")
10346
10347 (define_expand "sibcall_epilogue"
10348 [(use (const_int 0))]
10349 ""
10350 "s390_emit_epilogue (true); DONE;")
10351
10352 ;; A direct return instruction, without using an epilogue.
10353 (define_insn "<code>"
10354 [(ANY_RETURN)]
10355 "s390_can_use_<code>_insn ()"
10356 "br\t%%r14"
10357 [(set_attr "op_type" "RR")
10358 (set_attr "type" "jsr")
10359 (set_attr "atype" "agen")])
10360
10361 (define_insn "*return"
10362 [(return)
10363 (use (match_operand 0 "register_operand" "a"))]
10364 "GET_MODE (operands[0]) == Pmode"
10365 "br\t%0"
10366 [(set_attr "op_type" "RR")
10367 (set_attr "type" "jsr")
10368 (set_attr "atype" "agen")])
10369
10370
10371 ;; Instruction definition to extend a 31-bit pointer into a 64-bit
10372 ;; pointer. This is used for compatibility.
10373
10374 (define_expand "ptr_extend"
10375 [(set (match_operand:DI 0 "register_operand" "=r")
10376 (match_operand:SI 1 "register_operand" "r"))]
10377 "TARGET_64BIT"
10378 {
10379 emit_insn (gen_anddi3 (operands[0],
10380 gen_lowpart (DImode, operands[1]),
10381 GEN_INT (0x7fffffff)));
10382 DONE;
10383 })
10384
10385 ;; Instruction definition to expand eh_return macro to support
10386 ;; swapping in special linkage return addresses.
10387
10388 (define_expand "eh_return"
10389 [(use (match_operand 0 "register_operand" ""))]
10390 "TARGET_TPF"
10391 {
10392 s390_emit_tpf_eh_return (operands[0]);
10393 DONE;
10394 })
10395
10396 ;
10397 ; Stack Protector Patterns
10398 ;
10399
10400 (define_expand "stack_protect_set"
10401 [(set (match_operand 0 "memory_operand" "")
10402 (match_operand 1 "memory_operand" ""))]
10403 ""
10404 {
10405 #ifdef TARGET_THREAD_SSP_OFFSET
10406 operands[1]
10407 = gen_rtx_MEM (Pmode, gen_rtx_PLUS (Pmode, s390_get_thread_pointer (),
10408 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
10409 #endif
10410 if (TARGET_64BIT)
10411 emit_insn (gen_stack_protect_setdi (operands[0], operands[1]));
10412 else
10413 emit_insn (gen_stack_protect_setsi (operands[0], operands[1]));
10414
10415 DONE;
10416 })
10417
10418 (define_insn "stack_protect_set<mode>"
10419 [(set (match_operand:DSI 0 "memory_operand" "=Q")
10420 (unspec:DSI [(match_operand:DSI 1 "memory_operand" "Q")] UNSPEC_SP_SET))]
10421 ""
10422 "mvc\t%O0(%G0,%R0),%S1"
10423 [(set_attr "op_type" "SS")])
10424
10425 (define_expand "stack_protect_test"
10426 [(set (reg:CC CC_REGNUM)
10427 (compare (match_operand 0 "memory_operand" "")
10428 (match_operand 1 "memory_operand" "")))
10429 (match_operand 2 "" "")]
10430 ""
10431 {
10432 rtx cc_reg, test;
10433 #ifdef TARGET_THREAD_SSP_OFFSET
10434 operands[1]
10435 = gen_rtx_MEM (Pmode, gen_rtx_PLUS (Pmode, s390_get_thread_pointer (),
10436 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
10437 #endif
10438 if (TARGET_64BIT)
10439 emit_insn (gen_stack_protect_testdi (operands[0], operands[1]));
10440 else
10441 emit_insn (gen_stack_protect_testsi (operands[0], operands[1]));
10442
10443 cc_reg = gen_rtx_REG (CCZmode, CC_REGNUM);
10444 test = gen_rtx_EQ (VOIDmode, cc_reg, const0_rtx);
10445 emit_jump_insn (gen_cbranchcc4 (test, cc_reg, const0_rtx, operands[2]));
10446 DONE;
10447 })
10448
10449 (define_insn "stack_protect_test<mode>"
10450 [(set (reg:CCZ CC_REGNUM)
10451 (unspec:CCZ [(match_operand:DSI 0 "memory_operand" "Q")
10452 (match_operand:DSI 1 "memory_operand" "Q")] UNSPEC_SP_TEST))]
10453 ""
10454 "clc\t%O0(%G0,%R0),%S1"
10455 [(set_attr "op_type" "SS")])
10456
10457 ; This is used in s390_emit_prologue in order to prevent insns
10458 ; adjusting the stack pointer to be moved over insns writing stack
10459 ; slots using a copy of the stack pointer in a different register.
10460 (define_insn "stack_tie"
10461 [(set (match_operand:BLK 0 "memory_operand" "+m")
10462 (unspec:BLK [(match_dup 0)] UNSPEC_TIE))]
10463 ""
10464 ""
10465 [(set_attr "length" "0")])
10466
10467
10468 ;
10469 ; Data prefetch patterns
10470 ;
10471
10472 (define_insn "prefetch"
10473 [(prefetch (match_operand 0 "address_operand" "ZQZRZSZT,X")
10474 (match_operand:SI 1 "const_int_operand" " n,n")
10475 (match_operand:SI 2 "const_int_operand" " n,n"))]
10476 "TARGET_Z10"
10477 {
10478 switch (which_alternative)
10479 {
10480 case 0:
10481 return INTVAL (operands[1]) == 1 ? "pfd\t2,%a0" : "pfd\t1,%a0";
10482 case 1:
10483 if (larl_operand (operands[0], Pmode))
10484 return INTVAL (operands[1]) == 1 ? "pfdrl\t2,%a0" : "pfdrl\t1,%a0";
10485 default:
10486
10487 /* This might be reached for symbolic operands with an odd
10488 addend. We simply omit the prefetch for such rare cases. */
10489
10490 return "";
10491 }
10492 }
10493 [(set_attr "type" "load,larl")
10494 (set_attr "op_type" "RXY,RIL")
10495 (set_attr "z10prop" "z10_super")
10496 (set_attr "z196prop" "z196_alone")])
10497
10498
10499 ;
10500 ; Byte swap instructions
10501 ;
10502
10503 ; FIXME: There is also mvcin but we cannot use it since src and target
10504 ; may overlap.
10505 (define_insn "bswap<mode>2"
10506 [(set (match_operand:GPR 0 "nonimmediate_operand" "=d, d,RT")
10507 (bswap:GPR (match_operand:GPR 1 "nonimmediate_operand" " d,RT, d")))]
10508 "TARGET_CPU_ZARCH"
10509 "@
10510 lrv<g>r\t%0,%1
10511 lrv<g>\t%0,%1
10512 strv<g>\t%1,%0"
10513 [(set_attr "type" "*,load,store")
10514 (set_attr "op_type" "RRE,RXY,RXY")
10515 (set_attr "z10prop" "z10_super")])
10516
10517 (define_insn "bswaphi2"
10518 [(set (match_operand:HI 0 "nonimmediate_operand" "=d, d,RT")
10519 (bswap:HI (match_operand:HI 1 "nonimmediate_operand" " d,RT, d")))]
10520 "TARGET_CPU_ZARCH"
10521 "@
10522 #
10523 lrvh\t%0,%1
10524 strvh\t%1,%0"
10525 [(set_attr "type" "*,load,store")
10526 (set_attr "op_type" "RRE,RXY,RXY")
10527 (set_attr "z10prop" "z10_super")])
10528
10529 (define_split
10530 [(set (match_operand:HI 0 "register_operand" "")
10531 (bswap:HI (match_operand:HI 1 "register_operand" "")))]
10532 "TARGET_CPU_ZARCH"
10533 [(set (match_dup 2) (bswap:SI (match_dup 3)))
10534 (set (match_dup 2) (lshiftrt:SI (match_dup 2) (const_int 16)))]
10535 {
10536 operands[2] = simplify_gen_subreg (SImode, operands[0], HImode, 0);
10537 operands[3] = simplify_gen_subreg (SImode, operands[1], HImode, 0);
10538 })
10539
10540
10541 ;
10542 ; Population count instruction
10543 ;
10544
10545 ; The S/390 popcount instruction counts the bits of op1 in 8 byte
10546 ; portions and stores the result in the corresponding bytes in op0.
10547 (define_insn "*popcount<mode>"
10548 [(set (match_operand:INT 0 "register_operand" "=d")
10549 (unspec:INT [(match_operand:INT 1 "register_operand" "d")] UNSPEC_POPCNT))
10550 (clobber (reg:CC CC_REGNUM))]
10551 "TARGET_Z196"
10552 "popcnt\t%0,%1"
10553 [(set_attr "op_type" "RRE")])
10554
10555 (define_expand "popcountdi2"
10556 [; popcnt op0, op1
10557 (parallel [(set (match_operand:DI 0 "register_operand" "")
10558 (unspec:DI [(match_operand:DI 1 "register_operand")]
10559 UNSPEC_POPCNT))
10560 (clobber (reg:CC CC_REGNUM))])
10561 ; sllg op2, op0, 32
10562 (set (match_dup 2) (ashift:DI (match_dup 0) (const_int 32)))
10563 ; agr op0, op2
10564 (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 2)))
10565 (clobber (reg:CC CC_REGNUM))])
10566 ; sllg op2, op0, 16
10567 (set (match_dup 2)
10568 (ashift:DI (match_dup 0) (const_int 16)))
10569 ; agr op0, op2
10570 (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 2)))
10571 (clobber (reg:CC CC_REGNUM))])
10572 ; sllg op2, op0, 8
10573 (set (match_dup 2) (ashift:DI (match_dup 0) (const_int 8)))
10574 ; agr op0, op2
10575 (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 2)))
10576 (clobber (reg:CC CC_REGNUM))])
10577 ; srlg op0, op0, 56
10578 (set (match_dup 0) (lshiftrt:DI (match_dup 0) (const_int 56)))]
10579 "TARGET_Z196 && TARGET_64BIT"
10580 "operands[2] = gen_reg_rtx (DImode);")
10581
10582 (define_expand "popcountsi2"
10583 [; popcnt op0, op1
10584 (parallel [(set (match_operand:SI 0 "register_operand" "")
10585 (unspec:SI [(match_operand:SI 1 "register_operand")]
10586 UNSPEC_POPCNT))
10587 (clobber (reg:CC CC_REGNUM))])
10588 ; sllk op2, op0, 16
10589 (set (match_dup 2)
10590 (ashift:SI (match_dup 0) (const_int 16)))
10591 ; ar op0, op2
10592 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
10593 (clobber (reg:CC CC_REGNUM))])
10594 ; sllk op2, op0, 8
10595 (set (match_dup 2) (ashift:SI (match_dup 0) (const_int 8)))
10596 ; ar op0, op2
10597 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
10598 (clobber (reg:CC CC_REGNUM))])
10599 ; srl op0, op0, 24
10600 (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 24)))]
10601 "TARGET_Z196"
10602 "operands[2] = gen_reg_rtx (SImode);")
10603
10604 (define_expand "popcounthi2"
10605 [; popcnt op0, op1
10606 (parallel [(set (match_operand:HI 0 "register_operand" "")
10607 (unspec:HI [(match_operand:HI 1 "register_operand")]
10608 UNSPEC_POPCNT))
10609 (clobber (reg:CC CC_REGNUM))])
10610 ; sllk op2, op0, 8
10611 (set (match_dup 2)
10612 (ashift:SI (match_dup 0) (const_int 8)))
10613 ; ar op0, op2
10614 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
10615 (clobber (reg:CC CC_REGNUM))])
10616 ; srl op0, op0, 8
10617 (set (match_dup 0) (lshiftrt:HI (match_dup 0) (const_int 8)))]
10618 "TARGET_Z196"
10619 "operands[2] = gen_reg_rtx (SImode);")
10620
10621 (define_expand "popcountqi2"
10622 [; popcnt op0, op1
10623 (parallel [(set (match_operand:QI 0 "register_operand" "")
10624 (unspec:QI [(match_operand:QI 1 "register_operand")]
10625 UNSPEC_POPCNT))
10626 (clobber (reg:CC CC_REGNUM))])]
10627 "TARGET_Z196"
10628 "")
10629
10630 ;;
10631 ;;- Copy sign instructions
10632 ;;
10633
10634 (define_insn "copysign<mode>3"
10635 [(set (match_operand:FP 0 "register_operand" "=f")
10636 (unspec:FP [(match_operand:FP 1 "register_operand" "<fT0>")
10637 (match_operand:FP 2 "register_operand" "f")]
10638 UNSPEC_COPYSIGN))]
10639 "TARGET_Z196"
10640 "cpsdr\t%0,%2,%1"
10641 [(set_attr "op_type" "RRF")
10642 (set_attr "type" "fsimp<mode>")])
10643
10644
10645 ;;
10646 ;;- Transactional execution instructions
10647 ;;
10648
10649 ; This splitter helps combine to make use of CC directly when
10650 ; comparing the integer result of a tbegin builtin with a constant.
10651 ; The unspec is already removed by canonicalize_comparison. So this
10652 ; splitters only job is to turn the PARALLEL into separate insns
10653 ; again. Unfortunately this only works with the very first cc/int
10654 ; compare since combine is not able to deal with data flow across
10655 ; basic block boundaries.
10656
10657 ; It needs to be an insn pattern as well since combine does not apply
10658 ; the splitter directly. Combine would only use it if it actually
10659 ; would reduce the number of instructions.
10660 (define_insn_and_split "*ccraw_to_int"
10661 [(set (pc)
10662 (if_then_else
10663 (match_operator 0 "s390_eqne_operator"
10664 [(reg:CCRAW CC_REGNUM)
10665 (match_operand 1 "const_int_operand" "")])
10666 (label_ref (match_operand 2 "" ""))
10667 (pc)))
10668 (set (match_operand:SI 3 "register_operand" "=d")
10669 (unspec:SI [(reg:CCRAW CC_REGNUM)] UNSPEC_CC_TO_INT))]
10670 ""
10671 "#"
10672 ""
10673 [(set (match_dup 3)
10674 (unspec:SI [(reg:CCRAW CC_REGNUM)] UNSPEC_CC_TO_INT))
10675 (set (pc)
10676 (if_then_else (match_op_dup 0 [(reg:CCRAW CC_REGNUM) (match_dup 1)])
10677 (label_ref (match_dup 2))
10678 (pc)))]
10679 "")
10680
10681 ; Non-constrained transaction begin
10682
10683 (define_expand "tbegin"
10684 [(match_operand:SI 0 "register_operand" "")
10685 (match_operand:BLK 1 "memory_operand" "")]
10686 "TARGET_HTM"
10687 {
10688 s390_expand_tbegin (operands[0], operands[1], NULL_RTX, true);
10689 DONE;
10690 })
10691
10692 (define_expand "tbegin_nofloat"
10693 [(match_operand:SI 0 "register_operand" "")
10694 (match_operand:BLK 1 "memory_operand" "")]
10695 "TARGET_HTM"
10696 {
10697 s390_expand_tbegin (operands[0], operands[1], NULL_RTX, false);
10698 DONE;
10699 })
10700
10701 (define_expand "tbegin_retry"
10702 [(match_operand:SI 0 "register_operand" "")
10703 (match_operand:BLK 1 "memory_operand" "")
10704 (match_operand:SI 2 "general_operand" "")]
10705 "TARGET_HTM"
10706 {
10707 s390_expand_tbegin (operands[0], operands[1], operands[2], true);
10708 DONE;
10709 })
10710
10711 (define_expand "tbegin_retry_nofloat"
10712 [(match_operand:SI 0 "register_operand" "")
10713 (match_operand:BLK 1 "memory_operand" "")
10714 (match_operand:SI 2 "general_operand" "")]
10715 "TARGET_HTM"
10716 {
10717 s390_expand_tbegin (operands[0], operands[1], operands[2], false);
10718 DONE;
10719 })
10720
10721 ; Clobber VRs since they don't get restored
10722 (define_insn "tbegin_1_z13"
10723 [(set (reg:CCRAW CC_REGNUM)
10724 (unspec_volatile:CCRAW [(match_operand 0 "const_int_operand" "D")]
10725 UNSPECV_TBEGIN))
10726 (set (match_operand:BLK 1 "memory_operand" "=Q")
10727 (unspec_volatile:BLK [(match_dup 0)] UNSPECV_TBEGIN_TDB))
10728 (clobber (reg:TI 16)) (clobber (reg:TI 38))
10729 (clobber (reg:TI 17)) (clobber (reg:TI 39))
10730 (clobber (reg:TI 18)) (clobber (reg:TI 40))
10731 (clobber (reg:TI 19)) (clobber (reg:TI 41))
10732 (clobber (reg:TI 20)) (clobber (reg:TI 42))
10733 (clobber (reg:TI 21)) (clobber (reg:TI 43))
10734 (clobber (reg:TI 22)) (clobber (reg:TI 44))
10735 (clobber (reg:TI 23)) (clobber (reg:TI 45))
10736 (clobber (reg:TI 24)) (clobber (reg:TI 46))
10737 (clobber (reg:TI 25)) (clobber (reg:TI 47))
10738 (clobber (reg:TI 26)) (clobber (reg:TI 48))
10739 (clobber (reg:TI 27)) (clobber (reg:TI 49))
10740 (clobber (reg:TI 28)) (clobber (reg:TI 50))
10741 (clobber (reg:TI 29)) (clobber (reg:TI 51))
10742 (clobber (reg:TI 30)) (clobber (reg:TI 52))
10743 (clobber (reg:TI 31)) (clobber (reg:TI 53))]
10744 ; CONST_OK_FOR_CONSTRAINT_P does not work with D constraint since D is
10745 ; not supposed to be used for immediates (see genpreds.c).
10746 "TARGET_VX && INTVAL (operands[0]) >= 0 && INTVAL (operands[0]) <= 0xffff"
10747 "tbegin\t%1,%x0"
10748 [(set_attr "op_type" "SIL")])
10749
10750 (define_insn "tbegin_1"
10751 [(set (reg:CCRAW CC_REGNUM)
10752 (unspec_volatile:CCRAW [(match_operand 0 "const_int_operand" "D")]
10753 UNSPECV_TBEGIN))
10754 (set (match_operand:BLK 1 "memory_operand" "=Q")
10755 (unspec_volatile:BLK [(match_dup 0)] UNSPECV_TBEGIN_TDB))
10756 (clobber (reg:DF 16))
10757 (clobber (reg:DF 17))
10758 (clobber (reg:DF 18))
10759 (clobber (reg:DF 19))
10760 (clobber (reg:DF 20))
10761 (clobber (reg:DF 21))
10762 (clobber (reg:DF 22))
10763 (clobber (reg:DF 23))
10764 (clobber (reg:DF 24))
10765 (clobber (reg:DF 25))
10766 (clobber (reg:DF 26))
10767 (clobber (reg:DF 27))
10768 (clobber (reg:DF 28))
10769 (clobber (reg:DF 29))
10770 (clobber (reg:DF 30))
10771 (clobber (reg:DF 31))]
10772 ; CONST_OK_FOR_CONSTRAINT_P does not work with D constraint since D is
10773 ; not supposed to be used for immediates (see genpreds.c).
10774 "TARGET_HTM && INTVAL (operands[0]) >= 0 && INTVAL (operands[0]) <= 0xffff"
10775 "tbegin\t%1,%x0"
10776 [(set_attr "op_type" "SIL")])
10777
10778 ; Same as above but without the FPR clobbers
10779 (define_insn "tbegin_nofloat_1"
10780 [(set (reg:CCRAW CC_REGNUM)
10781 (unspec_volatile:CCRAW [(match_operand 0 "const_int_operand" "D")]
10782 UNSPECV_TBEGIN))
10783 (set (match_operand:BLK 1 "memory_operand" "=Q")
10784 (unspec_volatile:BLK [(match_dup 0)] UNSPECV_TBEGIN_TDB))]
10785 "TARGET_HTM && INTVAL (operands[0]) >= 0 && INTVAL (operands[0]) <= 0xffff"
10786 "tbegin\t%1,%x0"
10787 [(set_attr "op_type" "SIL")])
10788
10789
10790 ; Constrained transaction begin
10791
10792 (define_expand "tbeginc"
10793 [(set (reg:CCRAW CC_REGNUM)
10794 (unspec_volatile:CCRAW [(const_int TBEGINC_MASK)]
10795 UNSPECV_TBEGINC))]
10796 "TARGET_HTM"
10797 "")
10798
10799 (define_insn "*tbeginc_1"
10800 [(set (reg:CCRAW CC_REGNUM)
10801 (unspec_volatile:CCRAW [(match_operand 0 "const_int_operand" " D")]
10802 UNSPECV_TBEGINC))]
10803 "TARGET_HTM && INTVAL (operands[0]) >= 0 && INTVAL (operands[0]) <= 0xffff"
10804 "tbeginc\t0,%x0"
10805 [(set_attr "op_type" "SIL")])
10806
10807 ; Transaction end
10808
10809 (define_expand "tend"
10810 [(set (reg:CCRAW CC_REGNUM)
10811 (unspec_volatile:CCRAW [(const_int 0)] UNSPECV_TEND))
10812 (set (match_operand:SI 0 "register_operand" "")
10813 (unspec:SI [(reg:CCRAW CC_REGNUM)] UNSPEC_CC_TO_INT))]
10814 "TARGET_HTM"
10815 "")
10816
10817 (define_insn "*tend_1"
10818 [(set (reg:CCRAW CC_REGNUM)
10819 (unspec_volatile:CCRAW [(const_int 0)] UNSPECV_TEND))]
10820 "TARGET_HTM"
10821 "tend"
10822 [(set_attr "op_type" "S")])
10823
10824 ; Transaction abort
10825
10826 (define_expand "tabort"
10827 [(unspec_volatile [(match_operand:SI 0 "shift_count_or_setmem_operand" "")]
10828 UNSPECV_TABORT)]
10829 "TARGET_HTM && operands != NULL"
10830 {
10831 if (CONST_INT_P (operands[0])
10832 && INTVAL (operands[0]) >= 0 && INTVAL (operands[0]) <= 255)
10833 {
10834 error ("Invalid transaction abort code: " HOST_WIDE_INT_PRINT_DEC
10835 ". Values in range 0 through 255 are reserved.",
10836 INTVAL (operands[0]));
10837 FAIL;
10838 }
10839 })
10840
10841 (define_insn "*tabort_1"
10842 [(unspec_volatile [(match_operand:SI 0 "shift_count_or_setmem_operand" "Y")]
10843 UNSPECV_TABORT)]
10844 "TARGET_HTM && operands != NULL"
10845 "tabort\t%Y0"
10846 [(set_attr "op_type" "S")])
10847
10848 ; Transaction extract nesting depth
10849
10850 (define_insn "etnd"
10851 [(set (match_operand:SI 0 "register_operand" "=d")
10852 (unspec_volatile:SI [(const_int 0)] UNSPECV_ETND))]
10853 "TARGET_HTM"
10854 "etnd\t%0"
10855 [(set_attr "op_type" "RRE")])
10856
10857 ; Non-transactional store
10858
10859 (define_insn "ntstg"
10860 [(set (match_operand:DI 0 "memory_operand" "=RT")
10861 (unspec_volatile:DI [(match_operand:DI 1 "register_operand" "d")]
10862 UNSPECV_NTSTG))]
10863 "TARGET_HTM"
10864 "ntstg\t%1,%0"
10865 [(set_attr "op_type" "RXY")])
10866
10867 ; Transaction perform processor assist
10868
10869 (define_expand "tx_assist"
10870 [(unspec_volatile [(match_operand:SI 0 "register_operand" "")
10871 (reg:SI GPR0_REGNUM)
10872 (const_int 1)]
10873 UNSPECV_PPA)]
10874 "TARGET_HTM"
10875 "")
10876
10877 (define_insn "*ppa"
10878 [(unspec_volatile [(match_operand:SI 0 "register_operand" "d")
10879 (match_operand:SI 1 "register_operand" "d")
10880 (match_operand 2 "const_int_operand" "I")]
10881 UNSPECV_PPA)]
10882 "TARGET_HTM && INTVAL (operands[2]) < 16"
10883 "ppa\t%0,%1,%2"
10884 [(set_attr "op_type" "RRF")])
10885
10886
10887 ; Set and get floating point control register
10888
10889 (define_insn "sfpc"
10890 [(unspec_volatile [(match_operand:SI 0 "register_operand" "d")]
10891 UNSPECV_SFPC)]
10892 "TARGET_HARD_FLOAT"
10893 "sfpc\t%0")
10894
10895 (define_insn "efpc"
10896 [(set (match_operand:SI 0 "register_operand" "=d")
10897 (unspec_volatile:SI [(const_int 0)] UNSPECV_EFPC))]
10898 "TARGET_HARD_FLOAT"
10899 "efpc\t%0")
10900
10901
10902 ; Load count to block boundary
10903
10904 (define_insn "lcbb"
10905 [(set (match_operand:SI 0 "register_operand" "=d")
10906 (unspec:SI [(match_operand:SI 1 "address_operand" "ZQZR")
10907 (match_operand:SI 2 "immediate_operand" "C")] UNSPEC_LCBB))
10908 (clobber (reg:CC CC_REGNUM))]
10909 "TARGET_Z13"
10910 "lcbb\t%0,%1,%b2"
10911 [(set_attr "op_type" "VRX")])