S/390 Add vector scalar instruction support.
[gcc.git] / gcc / config / s390 / s390.md
1 ;;- Machine description for GNU compiler -- S/390 / zSeries version.
2 ;; Copyright (C) 1999-2015 Free Software Foundation, Inc.
3 ;; Contributed by Hartmut Penner (hpenner@de.ibm.com) and
4 ;; Ulrich Weigand (uweigand@de.ibm.com) and
5 ;; Andreas Krebbel (Andreas.Krebbel@de.ibm.com)
6
7 ;; This file is part of GCC.
8
9 ;; GCC is free software; you can redistribute it and/or modify it under
10 ;; the terms of the GNU General Public License as published by the Free
11 ;; Software Foundation; either version 3, or (at your option) any later
12 ;; version.
13
14 ;; GCC is distributed in the hope that it will be useful, but WITHOUT ANY
15 ;; WARRANTY; without even the implied warranty of MERCHANTABILITY or
16 ;; FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
17 ;; for more details.
18
19 ;; You should have received a copy of the GNU General Public License
20 ;; along with GCC; see the file COPYING3. If not see
21 ;; <http://www.gnu.org/licenses/>.
22
23 ;;
24 ;; See constraints.md for a description of constraints specific to s390.
25 ;;
26
27 ;; Special formats used for outputting 390 instructions.
28 ;;
29 ;; %C: print opcode suffix for branch condition.
30 ;; %D: print opcode suffix for inverse branch condition.
31 ;; %J: print tls_load/tls_gdcall/tls_ldcall suffix
32 ;; %G: print the size of the operand in bytes.
33 ;; %O: print only the displacement of a memory reference.
34 ;; %R: print only the base register of a memory reference.
35 ;; %S: print S-type memory reference (base+displacement).
36 ;; %N: print the second word of a DImode operand.
37 ;; %M: print the second word of a TImode operand.
38 ;; %Y: print shift count operand.
39 ;;
40 ;; %b: print integer X as if it's an unsigned byte.
41 ;; %c: print integer X as if it's an signed byte.
42 ;; %x: print integer X as if it's an unsigned halfword.
43 ;; %h: print integer X as if it's a signed halfword.
44 ;; %i: print the first nonzero HImode part of X.
45 ;; %j: print the first HImode part unequal to -1 of X.
46 ;; %k: print the first nonzero SImode part of X.
47 ;; %m: print the first SImode part unequal to -1 of X.
48 ;; %o: print integer X as if it's an unsigned 32bit word.
49 ;;
50 ;; We have a special constraint for pattern matching.
51 ;;
52 ;; s_operand -- Matches a valid S operand in a RS, SI or SS type instruction.
53 ;;
54
55 ;;
56 ;; UNSPEC usage
57 ;;
58
59 (define_c_enum "unspec" [
60 ; Miscellaneous
61 UNSPEC_ROUND
62 UNSPEC_ICM
63 UNSPEC_TIE
64
65 ; Convert CC into a str comparison result and copy it into an
66 ; integer register
67 ; cc0->0, cc1->1, cc2->-1, (cc3->-1)
68 UNSPEC_STRCMPCC_TO_INT
69
70 ; Copy CC as is into the lower 2 bits of an integer register
71 UNSPEC_CC_TO_INT
72
73 ; GOT/PLT and lt-relative accesses
74 UNSPEC_LTREL_OFFSET
75 UNSPEC_LTREL_BASE
76 UNSPEC_POOL_OFFSET
77 UNSPEC_GOTENT
78 UNSPEC_GOT
79 UNSPEC_GOTOFF
80 UNSPEC_PLT
81 UNSPEC_PLTOFF
82
83 ; Literal pool
84 UNSPEC_RELOAD_BASE
85 UNSPEC_MAIN_BASE
86 UNSPEC_LTREF
87 UNSPEC_INSN
88 UNSPEC_EXECUTE
89
90 ; Atomic Support
91 UNSPEC_MB
92 UNSPEC_MOVA
93
94 ; TLS relocation specifiers
95 UNSPEC_TLSGD
96 UNSPEC_TLSLDM
97 UNSPEC_NTPOFF
98 UNSPEC_DTPOFF
99 UNSPEC_GOTNTPOFF
100 UNSPEC_INDNTPOFF
101
102 ; TLS support
103 UNSPEC_TLSLDM_NTPOFF
104 UNSPEC_TLS_LOAD
105
106 ; String Functions
107 UNSPEC_SRST
108 UNSPEC_MVST
109
110 ; Stack Smashing Protector
111 UNSPEC_SP_SET
112 UNSPEC_SP_TEST
113
114 ; Test Data Class (TDC)
115 UNSPEC_TDC_INSN
116
117 ; Population Count
118 UNSPEC_POPCNT
119 UNSPEC_COPYSIGN
120
121 ; Load FP Integer
122 UNSPEC_FPINT_FLOOR
123 UNSPEC_FPINT_BTRUNC
124 UNSPEC_FPINT_ROUND
125 UNSPEC_FPINT_CEIL
126 UNSPEC_FPINT_NEARBYINT
127 UNSPEC_FPINT_RINT
128
129 ; Vector
130 UNSPEC_VEC_EXTRACT
131 UNSPEC_VEC_SET
132 UNSPEC_VEC_PERM
133 UNSPEC_VEC_SRLB
134 UNSPEC_VEC_GENBYTEMASK
135 UNSPEC_VEC_VSUM
136 UNSPEC_VEC_VSUMG
137 UNSPEC_VEC_SMULT_EVEN
138 UNSPEC_VEC_UMULT_EVEN
139 UNSPEC_VEC_SMULT_ODD
140 UNSPEC_VEC_UMULT_ODD
141 UNSPEC_VEC_LOAD_LEN
142 UNSPEC_VEC_VFENE
143 UNSPEC_VEC_VFENECC
144 ])
145
146 ;;
147 ;; UNSPEC_VOLATILE usage
148 ;;
149
150 (define_c_enum "unspecv" [
151 ; Blockage
152 UNSPECV_BLOCKAGE
153
154 ; TPF Support
155 UNSPECV_TPF_PROLOGUE
156 UNSPECV_TPF_EPILOGUE
157
158 ; Literal pool
159 UNSPECV_POOL
160 UNSPECV_POOL_SECTION
161 UNSPECV_POOL_ALIGN
162 UNSPECV_POOL_ENTRY
163 UNSPECV_MAIN_POOL
164
165 ; TLS support
166 UNSPECV_SET_TP
167
168 ; Atomic Support
169 UNSPECV_CAS
170 UNSPECV_ATOMIC_OP
171
172 ; Hotpatching (unremovable NOPs)
173 UNSPECV_NOP_2_BYTE
174 UNSPECV_NOP_4_BYTE
175 UNSPECV_NOP_6_BYTE
176
177 ; Transactional Execution support
178 UNSPECV_TBEGIN
179 UNSPECV_TBEGIN_TDB
180 UNSPECV_TBEGINC
181 UNSPECV_TEND
182 UNSPECV_TABORT
183 UNSPECV_ETND
184 UNSPECV_NTSTG
185 UNSPECV_PPA
186
187 ; Set and get floating point control register
188 UNSPECV_SFPC
189 UNSPECV_EFPC
190 ])
191
192 ;;
193 ;; Registers
194 ;;
195
196 ; Registers with special meaning
197
198 (define_constants
199 [
200 ; Sibling call register.
201 (SIBCALL_REGNUM 1)
202 ; Literal pool base register.
203 (BASE_REGNUM 13)
204 ; Return address register.
205 (RETURN_REGNUM 14)
206 ; Condition code register.
207 (CC_REGNUM 33)
208 ; Thread local storage pointer register.
209 (TP_REGNUM 36)
210 ])
211
212 ; Hardware register names
213
214 (define_constants
215 [
216 ; General purpose registers
217 (GPR0_REGNUM 0)
218 ; Floating point registers.
219 (FPR0_REGNUM 16)
220 (FPR1_REGNUM 20)
221 (FPR2_REGNUM 17)
222 (FPR3_REGNUM 21)
223 (FPR4_REGNUM 18)
224 (FPR5_REGNUM 22)
225 (FPR6_REGNUM 19)
226 (FPR7_REGNUM 23)
227 (FPR8_REGNUM 24)
228 (FPR9_REGNUM 28)
229 (FPR10_REGNUM 25)
230 (FPR11_REGNUM 29)
231 (FPR12_REGNUM 26)
232 (FPR13_REGNUM 30)
233 (FPR14_REGNUM 27)
234 (FPR15_REGNUM 31)
235 (VR0_REGNUM 16)
236 (VR16_REGNUM 38)
237 (VR23_REGNUM 45)
238 (VR24_REGNUM 46)
239 (VR31_REGNUM 53)
240 ])
241
242 ;;
243 ;; PFPO GPR0 argument format
244 ;;
245
246 (define_constants
247 [
248 ; PFPO operation type
249 (PFPO_CONVERT 0x1000000)
250 ; PFPO operand types
251 (PFPO_OP_TYPE_SF 0x5)
252 (PFPO_OP_TYPE_DF 0x6)
253 (PFPO_OP_TYPE_TF 0x7)
254 (PFPO_OP_TYPE_SD 0x8)
255 (PFPO_OP_TYPE_DD 0x9)
256 (PFPO_OP_TYPE_TD 0xa)
257 ; Bitposition of operand types
258 (PFPO_OP0_TYPE_SHIFT 16)
259 (PFPO_OP1_TYPE_SHIFT 8)
260 ])
261
262 ; Immediate operands for tbegin and tbeginc
263 (define_constants [(TBEGIN_MASK 65292)]) ; 0xff0c
264 (define_constants [(TBEGINC_MASK 65288)]) ; 0xff08
265
266 ;; Instruction operand type as used in the Principles of Operation.
267 ;; Used to determine defaults for length and other attribute values.
268
269 (define_attr "op_type"
270 "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"
271 (const_string "NN"))
272
273 ;; Instruction type attribute used for scheduling.
274
275 (define_attr "type" "none,integer,load,lr,la,larl,lm,stm,
276 cs,vs,store,sem,idiv,
277 imulhi,imulsi,imuldi,
278 branch,jsr,fsimptf,fsimpdf,fsimpsf,fhex,
279 floadtf,floaddf,floadsf,fstoredf,fstoresf,
280 fmultf,fmuldf,fmulsf,fdivtf,fdivdf,fdivsf,
281 ftoi,fsqrttf,fsqrtdf,fsqrtsf,
282 fmadddf,fmaddsf,
283 ftrunctf,ftruncdf, ftruncsd, ftruncdd,
284 itoftf, itofdf, itofsf, itofdd, itoftd,
285 fdivdd, fdivtd, floaddd, floadsd, fmuldd, fmultd,
286 fsimpdd, fsimpsd, fsimptd, fstoredd, fstoresd,
287 ftoidfp, other"
288 (cond [(eq_attr "op_type" "NN") (const_string "other")
289 (eq_attr "op_type" "SS") (const_string "cs")]
290 (const_string "integer")))
291
292 ;; Another attribute used for scheduling purposes:
293 ;; agen: Instruction uses the address generation unit
294 ;; reg: Instruction does not use the agen unit
295
296 (define_attr "atype" "agen,reg"
297 (if_then_else (eq_attr "op_type" "E,RR,RI,RRE,RSI,RIL,RIE,RRF,RRR")
298 (const_string "reg")
299 (const_string "agen")))
300
301 ;; Properties concerning Z10 execution grouping and value forwarding.
302 ;; z10_super: instruction is superscalar.
303 ;; z10_super_c: instruction is superscalar and meets the condition of z10_c.
304 ;; z10_fwd: The instruction reads the value of an operand and stores it into a
305 ;; target register. It can forward this value to a second instruction that reads
306 ;; the same register if that second instruction is issued in the same group.
307 ;; z10_rec: The instruction is in the T pipeline and reads a register. If the
308 ;; instruction in the S pipe writes to the register, then the T instruction
309 ;; can immediately read the new value.
310 ;; z10_fr: union of Z10_fwd and z10_rec.
311 ;; z10_c: second operand of instruction is a register and read with complemented bits.
312 ;;
313 ;; An additional suffix A1, A3, or E1 indicates the respective AGI bypass.
314
315
316 (define_attr "z10prop" "none,
317 z10_super, z10_super_E1, z10_super_A1, z10_super_c, z10_super_c_E1,
318 z10_fwd, z10_fwd_A1, z10_fwd_A3, z10_fwd_E1,
319 z10_rec,
320 z10_fr, z10_fr_A3, z10_fr_E1,
321 z10_c"
322 (const_string "none"))
323
324 ;; Properties concerning Z196 decoding
325 ;; z196_alone: must group alone
326 ;; z196_end: ends a group
327 ;; z196_cracked: instruction is cracked or expanded
328 (define_attr "z196prop" "none,
329 z196_alone, z196_ends,
330 z196_cracked"
331 (const_string "none"))
332
333 (define_attr "mnemonic" "bcr_flush,unknown" (const_string "unknown"))
334
335 ;; Length in bytes.
336
337 (define_attr "length" ""
338 (cond [(eq_attr "op_type" "E,RR") (const_int 2)
339 (eq_attr "op_type" "RX,RI,RRE,RS,RSI,S,SI,RRF,RRR") (const_int 4)]
340 (const_int 6)))
341
342
343 ;; Processor type. This attribute must exactly match the processor_type
344 ;; enumeration in s390.h. The current machine description does not
345 ;; distinguish between g5 and g6, but there are differences between the two
346 ;; CPUs could in theory be modeled.
347
348 (define_attr "cpu" "g5,g6,z900,z990,z9_109,z9_ec,z10,z196,zEC12,z13"
349 (const (symbol_ref "s390_tune_attr")))
350
351 (define_attr "cpu_facility"
352 "standard,ieee,zarch,cpu_zarch,longdisp,extimm,dfp,z10,z196,zEC12,vec"
353 (const_string "standard"))
354
355 (define_attr "enabled" ""
356 (cond [(eq_attr "cpu_facility" "standard")
357 (const_int 1)
358
359 (and (eq_attr "cpu_facility" "ieee")
360 (match_test "TARGET_CPU_IEEE_FLOAT"))
361 (const_int 1)
362
363 (and (eq_attr "cpu_facility" "zarch")
364 (match_test "TARGET_ZARCH"))
365 (const_int 1)
366
367 (and (eq_attr "cpu_facility" "longdisp")
368 (match_test "TARGET_LONG_DISPLACEMENT"))
369 (const_int 1)
370
371 (and (eq_attr "cpu_facility" "extimm")
372 (match_test "TARGET_EXTIMM"))
373 (const_int 1)
374
375 (and (eq_attr "cpu_facility" "dfp")
376 (match_test "TARGET_DFP"))
377 (const_int 1)
378
379 (and (eq_attr "cpu_facility" "cpu_zarch")
380 (match_test "TARGET_CPU_ZARCH"))
381 (const_int 1)
382
383 (and (eq_attr "cpu_facility" "z10")
384 (match_test "TARGET_Z10"))
385 (const_int 1)
386
387 (and (eq_attr "cpu_facility" "z196")
388 (match_test "TARGET_Z196"))
389 (const_int 1)
390
391 (and (eq_attr "cpu_facility" "zEC12")
392 (match_test "TARGET_ZEC12"))
393 (const_int 1)
394
395 (and (eq_attr "cpu_facility" "vec")
396 (match_test "TARGET_VX"))
397 (const_int 1)]
398 (const_int 0)))
399
400 ;; Pipeline description for z900. For lack of anything better,
401 ;; this description is also used for the g5 and g6.
402 (include "2064.md")
403
404 ;; Pipeline description for z990, z9-109 and z9-ec.
405 (include "2084.md")
406
407 ;; Pipeline description for z10
408 (include "2097.md")
409
410 ;; Pipeline description for z196
411 (include "2817.md")
412
413 ;; Pipeline description for zEC12
414 (include "2827.md")
415
416 ;; Predicates
417 (include "predicates.md")
418
419 ;; Constraint definitions
420 (include "constraints.md")
421
422 ;; Other includes
423 (include "tpf.md")
424
425 ;; Iterators
426
427 (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])
428
429 ;; These mode iterators allow floating point patterns to be generated from the
430 ;; same template.
431 (define_mode_iterator FP_ALL [TF DF SF (TD "TARGET_HARD_DFP") (DD "TARGET_HARD_DFP")
432 (SD "TARGET_HARD_DFP")])
433 (define_mode_iterator FP [TF DF SF (TD "TARGET_HARD_DFP") (DD "TARGET_HARD_DFP")])
434 (define_mode_iterator BFP [TF DF SF])
435 (define_mode_iterator DFP [TD DD])
436 (define_mode_iterator DFP_ALL [TD DD SD])
437 (define_mode_iterator DSF [DF SF])
438 (define_mode_iterator SD_SF [SF SD])
439 (define_mode_iterator DD_DF [DF DD])
440 (define_mode_iterator TD_TF [TF TD])
441
442 ;; These mode iterators allow 31-bit and 64-bit GPR patterns to be generated
443 ;; from the same template.
444 (define_mode_iterator GPR [(DI "TARGET_ZARCH") SI])
445 (define_mode_iterator DGPR [(TI "TARGET_ZARCH") DI SI])
446 (define_mode_iterator DSI [DI SI])
447 (define_mode_iterator TDI [TI DI])
448
449 ;; These mode iterators allow :P to be used for patterns that operate on
450 ;; pointer-sized quantities. Exactly one of the two alternatives will match.
451 (define_mode_iterator P [(DI "TARGET_64BIT") (SI "!TARGET_64BIT")])
452
453 ;; These macros refer to the actual word_mode of the configuration.
454 ;; This is equal to Pmode except on 31-bit machines in zarch mode.
455 (define_mode_iterator DW [(TI "TARGET_ZARCH") (DI "!TARGET_ZARCH")])
456 (define_mode_iterator W [(DI "TARGET_ZARCH") (SI "!TARGET_ZARCH")])
457
458 ;; Used by the umul pattern to express modes having half the size.
459 (define_mode_attr DWH [(TI "DI") (DI "SI")])
460 (define_mode_attr dwh [(TI "di") (DI "si")])
461
462 ;; This mode iterator allows the QI and HI patterns to be defined from
463 ;; the same template.
464 (define_mode_iterator HQI [HI QI])
465
466 ;; This mode iterator allows the integer patterns to be defined from the
467 ;; same template.
468 (define_mode_iterator INT [(DI "TARGET_ZARCH") SI HI QI])
469 (define_mode_iterator DINT [(TI "TARGET_ZARCH") DI SI HI QI])
470
471 ;; This iterator allows some 'ashift' and 'lshiftrt' pattern to be defined from
472 ;; the same template.
473 (define_code_iterator SHIFT [ashift lshiftrt])
474
475 ;; This iterator allows r[ox]sbg to be defined with the same template
476 (define_code_iterator IXOR [ior xor])
477
478 ;; This iterator is used to expand the patterns for the nearest
479 ;; integer functions.
480 (define_int_iterator FPINT [UNSPEC_FPINT_FLOOR UNSPEC_FPINT_BTRUNC
481 UNSPEC_FPINT_ROUND UNSPEC_FPINT_CEIL
482 UNSPEC_FPINT_NEARBYINT])
483 (define_int_attr fpint_name [(UNSPEC_FPINT_FLOOR "floor")
484 (UNSPEC_FPINT_BTRUNC "btrunc")
485 (UNSPEC_FPINT_ROUND "round")
486 (UNSPEC_FPINT_CEIL "ceil")
487 (UNSPEC_FPINT_NEARBYINT "nearbyint")])
488 (define_int_attr fpint_roundingmode [(UNSPEC_FPINT_FLOOR "7")
489 (UNSPEC_FPINT_BTRUNC "5")
490 (UNSPEC_FPINT_ROUND "1")
491 (UNSPEC_FPINT_CEIL "6")
492 (UNSPEC_FPINT_NEARBYINT "0")])
493
494 ;; This iterator and attribute allow to combine most atomic operations.
495 (define_code_iterator ATOMIC [and ior xor plus minus mult])
496 (define_code_iterator ATOMIC_Z196 [and ior xor plus])
497 (define_code_attr atomic [(and "and") (ior "or") (xor "xor")
498 (plus "add") (minus "sub") (mult "nand")])
499 (define_code_attr noxa [(and "n") (ior "o") (xor "x") (plus "a")])
500
501 ;; In FP templates, a string like "lt<de>br" will expand to "ltxbr" in
502 ;; TF/TDmode, "ltdbr" in DF/DDmode, and "ltebr" in SF/SDmode.
503 (define_mode_attr xde [(TF "x") (DF "d") (SF "e") (TD "x") (DD "d") (SD "e")])
504
505 ;; In FP templates, a <dee> in "m<dee><bt>r" will expand to "mx<bt>r" in
506 ;; TF/TDmode, "md<bt>r" in DF/DDmode, "mee<bt>r" in SFmode and "me<bt>r in
507 ;; SDmode.
508 (define_mode_attr xdee [(TF "x") (DF "d") (SF "ee") (TD "x") (DD "d") (SD "e")])
509
510 ;; In FP templates, "<RRe>" will expand to "RRE" in TFmode and "RR" otherwise.
511 ;; Likewise for "<RXe>".
512 (define_mode_attr RRe [(TF "RRE") (DF "RR") (SF "RR")])
513 (define_mode_attr RXe [(TF "RXE") (DF "RX") (SF "RX")])
514
515 ;; The decimal floating point variants of add, sub, div and mul support 3
516 ;; fp register operands. The following attributes allow to merge the bfp and
517 ;; dfp variants in a single insn definition.
518
519 ;; This attribute is used to set op_type accordingly.
520 (define_mode_attr RRer [(TF "RRE") (DF "RRE") (SF "RRE") (TD "RRR")
521 (DD "RRR") (SD "RRR")])
522
523 ;; This attribute is used in the operand constraint list in order to have the
524 ;; first and the second operand match for bfp modes.
525 (define_mode_attr f0 [(TF "0") (DF "0") (SF "0") (TD "f") (DD "f") (DD "f")])
526
527 ;; This attribute is used to merge the scalar vector instructions into
528 ;; the FP patterns. For non-supported modes (all but DF) it expands
529 ;; to constraints which are supposed to be matched by an earlier
530 ;; variant.
531 (define_mode_attr v0 [(TF "0") (DF "v") (SF "0") (TD "0") (DD "0") (DD "0") (TI "0") (DI "v") (SI "0")])
532 (define_mode_attr vf [(TF "f") (DF "v") (SF "f") (TD "f") (DD "f") (DD "f") (TI "f") (DI "v") (SI "f")])
533 (define_mode_attr vd [(TF "d") (DF "v") (SF "d") (TD "d") (DD "d") (DD "d") (TI "d") (DI "v") (SI "d")])
534
535 ;; This attribute is used in the operand list of the instruction to have an
536 ;; additional operand for the dfp instructions.
537 (define_mode_attr op1 [(TF "") (DF "") (SF "")
538 (TD "%1,") (DD "%1,") (SD "%1,")])
539
540
541 ;; This attribute is used in the operand constraint list
542 ;; for instructions dealing with the sign bit of 32 or 64bit fp values.
543 ;; TFmode values are represented by a fp register pair. Since the
544 ;; sign bit instructions only handle single source and target fp registers
545 ;; these instructions can only be used for TFmode values if the source and
546 ;; target operand uses the same fp register.
547 (define_mode_attr fT0 [(TF "0") (DF "f") (SF "f")])
548
549 ;; In FP templates, "<Rf>" will expand to "f" in TFmode and "R" otherwise.
550 ;; This is used to disable the memory alternative in TFmode patterns.
551 (define_mode_attr Rf [(TF "f") (DF "R") (SF "R") (TD "f") (DD "f") (SD "f")])
552
553 ;; This attribute adds b for bfp instructions and t for dfp instructions and is used
554 ;; within instruction mnemonics.
555 (define_mode_attr bt [(TF "b") (DF "b") (SF "b") (TD "t") (DD "t") (SD "t")])
556
557 ;; This attribute is used within instruction mnemonics. It evaluates to d for dfp
558 ;; modes and to an empty string for bfp modes.
559 (define_mode_attr _d [(TF "") (DF "") (SF "") (TD "d") (DD "d") (SD "d")])
560
561 ;; In GPR and P templates, a constraint like "<d0>" will expand to "d" in DImode
562 ;; and "0" in SImode. This allows to combine instructions of which the 31bit
563 ;; version only operates on one register.
564 (define_mode_attr d0 [(DI "d") (SI "0")])
565
566 ;; In combination with d0 this allows to combine instructions of which the 31bit
567 ;; version only operates on one register. The DImode version needs an additional
568 ;; register for the assembler output.
569 (define_mode_attr 1 [(DI "%1,") (SI "")])
570
571 ;; In SHIFT templates, a string like "s<lr>dl" will expand to "sldl" in
572 ;; 'ashift' and "srdl" in 'lshiftrt'.
573 (define_code_attr lr [(ashift "l") (lshiftrt "r")])
574
575 ;; In SHIFT templates, this attribute holds the correct standard name for the
576 ;; pattern itself and the corresponding function calls.
577 (define_code_attr shift [(ashift "ashl") (lshiftrt "lshr")])
578
579 ;; This attribute handles differences in the instruction 'type' and will result
580 ;; in "RRE" for DImode and "RR" for SImode.
581 (define_mode_attr E [(DI "E") (SI "")])
582
583 ;; This attribute handles differences in the instruction 'type' and makes RX<Y>
584 ;; to result in "RXY" for DImode and "RX" for SImode.
585 (define_mode_attr Y [(DI "Y") (SI "")])
586
587 ;; This attribute handles differences in the instruction 'type' and will result
588 ;; in "RSE" for TImode and "RS" for DImode.
589 (define_mode_attr TE [(TI "E") (DI "")])
590
591 ;; In GPR templates, a string like "lc<g>r" will expand to "lcgr" in DImode
592 ;; and "lcr" in SImode.
593 (define_mode_attr g [(DI "g") (SI "")])
594
595 ;; In GPR templates, a string like "sl<y>" will expand to "slg" in DImode
596 ;; and "sly" in SImode. This is useful because on 64bit the ..g instructions
597 ;; were enhanced with long displacements whereas 31bit instructions got a ..y
598 ;; variant for long displacements.
599 (define_mode_attr y [(DI "g") (SI "y")])
600
601 ;; In DW templates, a string like "cds<g>" will expand to "cdsg" in TImode
602 ;; and "cds" in DImode.
603 (define_mode_attr tg [(TI "g") (DI "")])
604
605 ;; In TDI templates, a string like "c<d>sg".
606 (define_mode_attr td [(TI "d") (DI "")])
607
608 ;; In GPR templates, a string like "c<gf>dbr" will expand to "cgdbr" in DImode
609 ;; and "cfdbr" in SImode.
610 (define_mode_attr gf [(DI "g") (SI "f")])
611
612 ;; In GPR templates, a string like sll<gk> will expand to sllg for DI
613 ;; and sllk for SI. This way it is possible to merge the new z196 SI
614 ;; 3 operands shift instructions into the existing patterns.
615 (define_mode_attr gk [(DI "g") (SI "k")])
616
617 ;; ICM mask required to load MODE value into the lowest subreg
618 ;; of a SImode register.
619 (define_mode_attr icm_lo [(HI "3") (QI "1")])
620
621 ;; In HQI templates, a string like "llg<hc>" will expand to "llgh" in
622 ;; HImode and "llgc" in QImode.
623 (define_mode_attr hc [(HI "h") (QI "c")])
624
625 ;; In P templates, the mode <DBL> will expand to "TI" in DImode and "DI"
626 ;; in SImode.
627 (define_mode_attr DBL [(DI "TI") (SI "DI")])
628
629 ;; This attribute expands to DF for TFmode and to DD for TDmode . It is
630 ;; used for Txmode splitters splitting a Txmode copy into 2 Dxmode copies.
631 (define_mode_attr HALF_TMODE [(TF "DF") (TD "DD")])
632
633 ;; Maximum unsigned integer that fits in MODE.
634 (define_mode_attr max_uint [(HI "65535") (QI "255")])
635
636 ;; Start and end field computations for RISBG et al.
637 (define_mode_attr bfstart [(DI "s") (SI "t")])
638 (define_mode_attr bfend [(DI "e") (SI "f")])
639
640 ;; In place of GET_MODE_BITSIZE (<MODE>mode)
641 (define_mode_attr bitsize [(DI "64") (SI "32") (HI "16") (QI "8")])
642
643 ;; Allow return and simple_return to be defined from a single template.
644 (define_code_iterator ANY_RETURN [return simple_return])
645
646
647
648 ; Condition code modes generated by vector fp comparisons. These will
649 ; be used also in single element mode.
650 (define_mode_iterator VFCMP [CCVEQ CCVFH CCVFHE])
651 ; Used with VFCMP to expand part of the mnemonic
652 ; For fp we have a mismatch: eq in the insn name - e in asm
653 (define_mode_attr asm_fcmp [(CCVEQ "e") (CCVFH "h") (CCVFHE "he")])
654 (define_mode_attr insn_cmp [(CCVEQ "eq") (CCVFH "h") (CCVFHE "he")])
655
656
657 (include "vector.md")
658
659 ;;
660 ;;- Compare instructions.
661 ;;
662
663 ; Test-under-Mask instructions
664
665 (define_insn "*tmqi_mem"
666 [(set (reg CC_REGNUM)
667 (compare (and:QI (match_operand:QI 0 "memory_operand" "Q,S")
668 (match_operand:QI 1 "immediate_operand" "n,n"))
669 (match_operand:QI 2 "immediate_operand" "n,n")))]
670 "s390_match_ccmode (insn, s390_tm_ccmode (operands[1], operands[2], false))"
671 "@
672 tm\t%S0,%b1
673 tmy\t%S0,%b1"
674 [(set_attr "op_type" "SI,SIY")
675 (set_attr "z10prop" "z10_super,z10_super")])
676
677 (define_insn "*tmdi_reg"
678 [(set (reg CC_REGNUM)
679 (compare (and:DI (match_operand:DI 0 "nonimmediate_operand" "d,d,d,d")
680 (match_operand:DI 1 "immediate_operand"
681 "N0HD0,N1HD0,N2HD0,N3HD0"))
682 (match_operand:DI 2 "immediate_operand" "n,n,n,n")))]
683 "TARGET_ZARCH
684 && s390_match_ccmode (insn, s390_tm_ccmode (operands[1], operands[2], true))
685 && s390_single_part (operands[1], DImode, HImode, 0) >= 0"
686 "@
687 tmhh\t%0,%i1
688 tmhl\t%0,%i1
689 tmlh\t%0,%i1
690 tmll\t%0,%i1"
691 [(set_attr "op_type" "RI")
692 (set_attr "z10prop" "z10_super,z10_super,z10_super,z10_super")])
693
694 (define_insn "*tmsi_reg"
695 [(set (reg CC_REGNUM)
696 (compare (and:SI (match_operand:SI 0 "nonimmediate_operand" "d,d")
697 (match_operand:SI 1 "immediate_operand" "N0HS0,N1HS0"))
698 (match_operand:SI 2 "immediate_operand" "n,n")))]
699 "s390_match_ccmode (insn, s390_tm_ccmode (operands[1], operands[2], true))
700 && s390_single_part (operands[1], SImode, HImode, 0) >= 0"
701 "@
702 tmh\t%0,%i1
703 tml\t%0,%i1"
704 [(set_attr "op_type" "RI")
705 (set_attr "z10prop" "z10_super,z10_super")])
706
707 (define_insn "*tm<mode>_full"
708 [(set (reg CC_REGNUM)
709 (compare (match_operand:HQI 0 "register_operand" "d")
710 (match_operand:HQI 1 "immediate_operand" "n")))]
711 "s390_match_ccmode (insn, s390_tm_ccmode (constm1_rtx, operands[1], true))"
712 "tml\t%0,<max_uint>"
713 [(set_attr "op_type" "RI")
714 (set_attr "z10prop" "z10_super")])
715
716
717 ;
718 ; Load-and-Test instructions
719 ;
720
721 ; tst(di|si) instruction pattern(s).
722
723 (define_insn "*tstdi_sign"
724 [(set (reg CC_REGNUM)
725 (compare
726 (ashiftrt:DI
727 (ashift:DI
728 (subreg:DI (match_operand:SI 0 "nonimmediate_operand" "d,RT") 0)
729 (const_int 32)) (const_int 32))
730 (match_operand:DI 1 "const0_operand" "")))
731 (set (match_operand:DI 2 "register_operand" "=d,d")
732 (sign_extend:DI (match_dup 0)))]
733 "s390_match_ccmode(insn, CCSmode) && TARGET_ZARCH"
734 "ltgfr\t%2,%0
735 ltgf\t%2,%0"
736 [(set_attr "op_type" "RRE,RXY")
737 (set_attr "cpu_facility" "*,z10")
738 (set_attr "z10prop" "z10_super_E1,z10_super_E1") ])
739
740 ; ltr, lt, ltgr, ltg
741 (define_insn "*tst<mode>_extimm"
742 [(set (reg CC_REGNUM)
743 (compare (match_operand:GPR 0 "nonimmediate_operand" "d,RT")
744 (match_operand:GPR 1 "const0_operand" "")))
745 (set (match_operand:GPR 2 "register_operand" "=d,d")
746 (match_dup 0))]
747 "s390_match_ccmode(insn, CCSmode) && TARGET_EXTIMM"
748 "@
749 lt<g>r\t%2,%0
750 lt<g>\t%2,%0"
751 [(set_attr "op_type" "RR<E>,RXY")
752 (set_attr "z10prop" "z10_fr_E1,z10_fwd_A3") ])
753
754 ; ltr, lt, ltgr, ltg
755 (define_insn "*tst<mode>_cconly_extimm"
756 [(set (reg CC_REGNUM)
757 (compare (match_operand:GPR 0 "nonimmediate_operand" "d,RT")
758 (match_operand:GPR 1 "const0_operand" "")))
759 (clobber (match_scratch:GPR 2 "=X,d"))]
760 "s390_match_ccmode(insn, CCSmode) && TARGET_EXTIMM"
761 "@
762 lt<g>r\t%0,%0
763 lt<g>\t%2,%0"
764 [(set_attr "op_type" "RR<E>,RXY")
765 (set_attr "z10prop" "z10_fr_E1,z10_fwd_A3")])
766
767 (define_insn "*tstdi"
768 [(set (reg CC_REGNUM)
769 (compare (match_operand:DI 0 "register_operand" "d")
770 (match_operand:DI 1 "const0_operand" "")))
771 (set (match_operand:DI 2 "register_operand" "=d")
772 (match_dup 0))]
773 "s390_match_ccmode(insn, CCSmode) && TARGET_ZARCH && !TARGET_EXTIMM"
774 "ltgr\t%2,%0"
775 [(set_attr "op_type" "RRE")
776 (set_attr "z10prop" "z10_fr_E1")])
777
778 (define_insn "*tstsi"
779 [(set (reg CC_REGNUM)
780 (compare (match_operand:SI 0 "nonimmediate_operand" "d,Q,S")
781 (match_operand:SI 1 "const0_operand" "")))
782 (set (match_operand:SI 2 "register_operand" "=d,d,d")
783 (match_dup 0))]
784 "s390_match_ccmode(insn, CCSmode) && !TARGET_EXTIMM"
785 "@
786 ltr\t%2,%0
787 icm\t%2,15,%S0
788 icmy\t%2,15,%S0"
789 [(set_attr "op_type" "RR,RS,RSY")
790 (set_attr "z10prop" "z10_fr_E1,z10_super_E1,z10_super_E1")])
791
792 (define_insn "*tstsi_cconly"
793 [(set (reg CC_REGNUM)
794 (compare (match_operand:SI 0 "nonimmediate_operand" "d,Q,S")
795 (match_operand:SI 1 "const0_operand" "")))
796 (clobber (match_scratch:SI 2 "=X,d,d"))]
797 "s390_match_ccmode(insn, CCSmode)"
798 "@
799 ltr\t%0,%0
800 icm\t%2,15,%S0
801 icmy\t%2,15,%S0"
802 [(set_attr "op_type" "RR,RS,RSY")
803 (set_attr "z10prop" "z10_fr_E1,z10_super_E1,z10_super_E1")])
804
805 (define_insn "*tstdi_cconly_31"
806 [(set (reg CC_REGNUM)
807 (compare (match_operand:DI 0 "register_operand" "d")
808 (match_operand:DI 1 "const0_operand" "")))]
809 "s390_match_ccmode(insn, CCSmode) && !TARGET_ZARCH"
810 "srda\t%0,0"
811 [(set_attr "op_type" "RS")
812 (set_attr "atype" "reg")])
813
814 ; ltr, ltgr
815 (define_insn "*tst<mode>_cconly2"
816 [(set (reg CC_REGNUM)
817 (compare (match_operand:GPR 0 "register_operand" "d")
818 (match_operand:GPR 1 "const0_operand" "")))]
819 "s390_match_ccmode(insn, CCSmode)"
820 "lt<g>r\t%0,%0"
821 [(set_attr "op_type" "RR<E>")
822 (set_attr "z10prop" "z10_fr_E1")])
823
824 ; tst(hi|qi) instruction pattern(s).
825
826 (define_insn "*tst<mode>CCT"
827 [(set (reg CC_REGNUM)
828 (compare (match_operand:HQI 0 "nonimmediate_operand" "?Q,?S,d")
829 (match_operand:HQI 1 "const0_operand" "")))
830 (set (match_operand:HQI 2 "register_operand" "=d,d,0")
831 (match_dup 0))]
832 "s390_match_ccmode(insn, CCTmode)"
833 "@
834 icm\t%2,<icm_lo>,%S0
835 icmy\t%2,<icm_lo>,%S0
836 tml\t%0,<max_uint>"
837 [(set_attr "op_type" "RS,RSY,RI")
838 (set_attr "z10prop" "z10_super_E1,z10_super_E1,z10_super")])
839
840 (define_insn "*tsthiCCT_cconly"
841 [(set (reg CC_REGNUM)
842 (compare (match_operand:HI 0 "nonimmediate_operand" "Q,S,d")
843 (match_operand:HI 1 "const0_operand" "")))
844 (clobber (match_scratch:HI 2 "=d,d,X"))]
845 "s390_match_ccmode(insn, CCTmode)"
846 "@
847 icm\t%2,3,%S0
848 icmy\t%2,3,%S0
849 tml\t%0,65535"
850 [(set_attr "op_type" "RS,RSY,RI")
851 (set_attr "z10prop" "z10_super_E1,z10_super_E1,z10_super")])
852
853 (define_insn "*tstqiCCT_cconly"
854 [(set (reg CC_REGNUM)
855 (compare (match_operand:QI 0 "nonimmediate_operand" "?Q,?S,d")
856 (match_operand:QI 1 "const0_operand" "")))]
857 "s390_match_ccmode(insn, CCTmode)"
858 "@
859 cli\t%S0,0
860 cliy\t%S0,0
861 tml\t%0,255"
862 [(set_attr "op_type" "SI,SIY,RI")
863 (set_attr "z10prop" "z10_super,z10_super,z10_super")])
864
865 (define_insn "*tst<mode>"
866 [(set (reg CC_REGNUM)
867 (compare (match_operand:HQI 0 "s_operand" "Q,S")
868 (match_operand:HQI 1 "const0_operand" "")))
869 (set (match_operand:HQI 2 "register_operand" "=d,d")
870 (match_dup 0))]
871 "s390_match_ccmode(insn, CCSmode)"
872 "@
873 icm\t%2,<icm_lo>,%S0
874 icmy\t%2,<icm_lo>,%S0"
875 [(set_attr "op_type" "RS,RSY")
876 (set_attr "z10prop" "z10_super_E1,z10_super_E1")])
877
878 (define_insn "*tst<mode>_cconly"
879 [(set (reg CC_REGNUM)
880 (compare (match_operand:HQI 0 "s_operand" "Q,S")
881 (match_operand:HQI 1 "const0_operand" "")))
882 (clobber (match_scratch:HQI 2 "=d,d"))]
883 "s390_match_ccmode(insn, CCSmode)"
884 "@
885 icm\t%2,<icm_lo>,%S0
886 icmy\t%2,<icm_lo>,%S0"
887 [(set_attr "op_type" "RS,RSY")
888 (set_attr "z10prop" "z10_super_E1,z10_super_E1")])
889
890
891 ; Compare (equality) instructions
892
893 (define_insn "*cmpdi_cct"
894 [(set (reg CC_REGNUM)
895 (compare (match_operand:DI 0 "nonimmediate_operand" "%d,d,d,d,Q")
896 (match_operand:DI 1 "general_operand" "d,K,Os,RT,BQ")))]
897 "s390_match_ccmode (insn, CCTmode) && TARGET_ZARCH"
898 "@
899 cgr\t%0,%1
900 cghi\t%0,%h1
901 cgfi\t%0,%1
902 cg\t%0,%1
903 #"
904 [(set_attr "op_type" "RRE,RI,RIL,RXY,SS")
905 (set_attr "z10prop" "z10_super_c,z10_super,z10_super,z10_super,*")])
906
907 (define_insn "*cmpsi_cct"
908 [(set (reg CC_REGNUM)
909 (compare (match_operand:SI 0 "nonimmediate_operand" "%d,d,d,d,d,Q")
910 (match_operand:SI 1 "general_operand" "d,K,Os,R,T,BQ")))]
911 "s390_match_ccmode (insn, CCTmode)"
912 "@
913 cr\t%0,%1
914 chi\t%0,%h1
915 cfi\t%0,%1
916 c\t%0,%1
917 cy\t%0,%1
918 #"
919 [(set_attr "op_type" "RR,RI,RIL,RX,RXY,SS")
920 (set_attr "z10prop" "z10_super_c,z10_super,z10_super,z10_super,z10_super,*")])
921
922 ; Compare (signed) instructions
923
924 (define_insn "*cmpdi_ccs_sign"
925 [(set (reg CC_REGNUM)
926 (compare (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand"
927 "d,RT,b"))
928 (match_operand:DI 0 "register_operand" "d, d,d")))]
929 "s390_match_ccmode(insn, CCSRmode) && TARGET_ZARCH"
930 "@
931 cgfr\t%0,%1
932 cgf\t%0,%1
933 cgfrl\t%0,%1"
934 [(set_attr "op_type" "RRE,RXY,RIL")
935 (set_attr "z10prop" "z10_c,*,*")
936 (set_attr "type" "*,*,larl")])
937
938
939
940 (define_insn "*cmpsi_ccs_sign"
941 [(set (reg CC_REGNUM)
942 (compare (sign_extend:SI (match_operand:HI 1 "memory_operand" "R,T,b"))
943 (match_operand:SI 0 "register_operand" "d,d,d")))]
944 "s390_match_ccmode(insn, CCSRmode)"
945 "@
946 ch\t%0,%1
947 chy\t%0,%1
948 chrl\t%0,%1"
949 [(set_attr "op_type" "RX,RXY,RIL")
950 (set_attr "cpu_facility" "*,*,z10")
951 (set_attr "type" "*,*,larl")
952 (set_attr "z196prop" "z196_cracked,z196_cracked,z196_cracked")])
953
954 (define_insn "*cmphi_ccs_z10"
955 [(set (reg CC_REGNUM)
956 (compare (match_operand:HI 0 "s_operand" "Q")
957 (match_operand:HI 1 "immediate_operand" "K")))]
958 "s390_match_ccmode(insn, CCSmode) && TARGET_Z10"
959 "chhsi\t%0,%1"
960 [(set_attr "op_type" "SIL")
961 (set_attr "z196prop" "z196_cracked")])
962
963 (define_insn "*cmpdi_ccs_signhi_rl"
964 [(set (reg CC_REGNUM)
965 (compare (sign_extend:DI (match_operand:HI 1 "memory_operand" "RT,b"))
966 (match_operand:GPR 0 "register_operand" "d,d")))]
967 "s390_match_ccmode(insn, CCSRmode) && TARGET_Z10"
968 "@
969 cgh\t%0,%1
970 cghrl\t%0,%1"
971 [(set_attr "op_type" "RXY,RIL")
972 (set_attr "type" "*,larl")])
973
974 ; cr, chi, cfi, c, cy, cgr, cghi, cgfi, cg, chsi, cghsi, crl, cgrl
975 (define_insn "*cmp<mode>_ccs"
976 [(set (reg CC_REGNUM)
977 (compare (match_operand:GPR 0 "nonimmediate_operand"
978 "d,d,Q, d,d,d,d")
979 (match_operand:GPR 1 "general_operand"
980 "d,K,K,Os,R,T,b")))]
981 "s390_match_ccmode(insn, CCSmode)"
982 "@
983 c<g>r\t%0,%1
984 c<g>hi\t%0,%h1
985 c<g>hsi\t%0,%h1
986 c<g>fi\t%0,%1
987 c<g>\t%0,%1
988 c<y>\t%0,%1
989 c<g>rl\t%0,%1"
990 [(set_attr "op_type" "RR<E>,RI,SIL,RIL,RX<Y>,RXY,RIL")
991 (set_attr "cpu_facility" "*,*,z10,extimm,*,*,z10")
992 (set_attr "type" "*,*,*,*,*,*,larl")
993 (set_attr "z10prop" "z10_super_c,z10_super,z10_super,z10_super,z10_super,z10_super,z10_super")])
994
995
996 ; Compare (unsigned) instructions
997
998 (define_insn "*cmpsi_ccu_zerohi_rlsi"
999 [(set (reg CC_REGNUM)
1000 (compare (zero_extend:SI (mem:HI (match_operand:SI 1
1001 "larl_operand" "X")))
1002 (match_operand:SI 0 "register_operand" "d")))]
1003 "s390_match_ccmode(insn, CCURmode) && TARGET_Z10"
1004 "clhrl\t%0,%1"
1005 [(set_attr "op_type" "RIL")
1006 (set_attr "type" "larl")
1007 (set_attr "z10prop" "z10_super")])
1008
1009 ; clhrl, clghrl
1010 (define_insn "*cmp<GPR:mode>_ccu_zerohi_rldi"
1011 [(set (reg CC_REGNUM)
1012 (compare (zero_extend:GPR (mem:HI (match_operand:DI 1
1013 "larl_operand" "X")))
1014 (match_operand:GPR 0 "register_operand" "d")))]
1015 "s390_match_ccmode(insn, CCURmode) && TARGET_Z10"
1016 "cl<g>hrl\t%0,%1"
1017 [(set_attr "op_type" "RIL")
1018 (set_attr "type" "larl")
1019 (set_attr "z10prop" "z10_super")])
1020
1021 (define_insn "*cmpdi_ccu_zero"
1022 [(set (reg CC_REGNUM)
1023 (compare (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand"
1024 "d,RT,b"))
1025 (match_operand:DI 0 "register_operand" "d, d,d")))]
1026 "s390_match_ccmode (insn, CCURmode) && TARGET_ZARCH"
1027 "@
1028 clgfr\t%0,%1
1029 clgf\t%0,%1
1030 clgfrl\t%0,%1"
1031 [(set_attr "op_type" "RRE,RXY,RIL")
1032 (set_attr "cpu_facility" "*,*,z10")
1033 (set_attr "type" "*,*,larl")
1034 (set_attr "z10prop" "z10_super_c,z10_super_E1,z10_super")])
1035
1036 (define_insn "*cmpdi_ccu"
1037 [(set (reg CC_REGNUM)
1038 (compare (match_operand:DI 0 "nonimmediate_operand"
1039 "d, d,d,Q, d, Q,BQ")
1040 (match_operand:DI 1 "general_operand"
1041 "d,Op,b,D,RT,BQ,Q")))]
1042 "s390_match_ccmode (insn, CCUmode) && TARGET_ZARCH"
1043 "@
1044 clgr\t%0,%1
1045 clgfi\t%0,%1
1046 clgrl\t%0,%1
1047 clghsi\t%0,%x1
1048 clg\t%0,%1
1049 #
1050 #"
1051 [(set_attr "op_type" "RRE,RIL,RIL,SIL,RXY,SS,SS")
1052 (set_attr "cpu_facility" "*,extimm,z10,z10,*,*,*")
1053 (set_attr "type" "*,*,larl,*,*,*,*")
1054 (set_attr "z10prop" "z10_super_c,z10_super,z10_super,z10_super,z10_super,*,*")])
1055
1056 (define_insn "*cmpsi_ccu"
1057 [(set (reg CC_REGNUM)
1058 (compare (match_operand:SI 0 "nonimmediate_operand" "d, d,d,Q,d,d, Q,BQ")
1059 (match_operand:SI 1 "general_operand" "d,Os,b,D,R,T,BQ, Q")))]
1060 "s390_match_ccmode (insn, CCUmode)"
1061 "@
1062 clr\t%0,%1
1063 clfi\t%0,%o1
1064 clrl\t%0,%1
1065 clfhsi\t%0,%x1
1066 cl\t%0,%1
1067 cly\t%0,%1
1068 #
1069 #"
1070 [(set_attr "op_type" "RR,RIL,RIL,SIL,RX,RXY,SS,SS")
1071 (set_attr "cpu_facility" "*,extimm,z10,z10,*,*,*,*")
1072 (set_attr "type" "*,*,larl,*,*,*,*,*")
1073 (set_attr "z10prop" "z10_super_c,z10_super,z10_super,z10_super,z10_super,z10_super,*,*")])
1074
1075 (define_insn "*cmphi_ccu"
1076 [(set (reg CC_REGNUM)
1077 (compare (match_operand:HI 0 "nonimmediate_operand" "d,d,Q,Q,BQ")
1078 (match_operand:HI 1 "general_operand" "Q,S,D,BQ,Q")))]
1079 "s390_match_ccmode (insn, CCUmode)
1080 && !register_operand (operands[1], HImode)"
1081 "@
1082 clm\t%0,3,%S1
1083 clmy\t%0,3,%S1
1084 clhhsi\t%0,%1
1085 #
1086 #"
1087 [(set_attr "op_type" "RS,RSY,SIL,SS,SS")
1088 (set_attr "cpu_facility" "*,*,z10,*,*")
1089 (set_attr "z10prop" "*,*,z10_super,*,*")])
1090
1091 (define_insn "*cmpqi_ccu"
1092 [(set (reg CC_REGNUM)
1093 (compare (match_operand:QI 0 "nonimmediate_operand" "d,d,Q,S,Q,BQ")
1094 (match_operand:QI 1 "general_operand" "Q,S,n,n,BQ,Q")))]
1095 "s390_match_ccmode (insn, CCUmode)
1096 && !register_operand (operands[1], QImode)"
1097 "@
1098 clm\t%0,1,%S1
1099 clmy\t%0,1,%S1
1100 cli\t%S0,%b1
1101 cliy\t%S0,%b1
1102 #
1103 #"
1104 [(set_attr "op_type" "RS,RSY,SI,SIY,SS,SS")
1105 (set_attr "z10prop" "*,*,z10_super,z10_super,*,*")])
1106
1107
1108 ; Block compare (CLC) instruction patterns.
1109
1110 (define_insn "*clc"
1111 [(set (reg CC_REGNUM)
1112 (compare (match_operand:BLK 0 "memory_operand" "Q")
1113 (match_operand:BLK 1 "memory_operand" "Q")))
1114 (use (match_operand 2 "const_int_operand" "n"))]
1115 "s390_match_ccmode (insn, CCUmode)
1116 && INTVAL (operands[2]) >= 1 && INTVAL (operands[2]) <= 256"
1117 "clc\t%O0(%2,%R0),%S1"
1118 [(set_attr "op_type" "SS")])
1119
1120 (define_split
1121 [(set (reg CC_REGNUM)
1122 (compare (match_operand 0 "memory_operand" "")
1123 (match_operand 1 "memory_operand" "")))]
1124 "reload_completed
1125 && s390_match_ccmode (insn, CCUmode)
1126 && GET_MODE (operands[0]) == GET_MODE (operands[1])
1127 && GET_MODE_SIZE (GET_MODE (operands[0])) > 0"
1128 [(parallel
1129 [(set (match_dup 0) (match_dup 1))
1130 (use (match_dup 2))])]
1131 {
1132 operands[2] = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[0])));
1133 operands[0] = adjust_address (operands[0], BLKmode, 0);
1134 operands[1] = adjust_address (operands[1], BLKmode, 0);
1135
1136 operands[1] = gen_rtx_COMPARE (GET_MODE (SET_DEST (PATTERN (curr_insn))),
1137 operands[0], operands[1]);
1138 operands[0] = SET_DEST (PATTERN (curr_insn));
1139 })
1140
1141
1142 ; (TF|DF|SF|TD|DD|SD) instructions
1143
1144 ; ltxbr, ltdbr, ltebr, ltxtr, ltdtr
1145 (define_insn "*cmp<mode>_ccs_0"
1146 [(set (reg CC_REGNUM)
1147 (compare (match_operand:FP 0 "register_operand" "f")
1148 (match_operand:FP 1 "const0_operand" "")))]
1149 "s390_match_ccmode(insn, CCSmode) && TARGET_HARD_FLOAT"
1150 "lt<xde><bt>r\t%0,%0"
1151 [(set_attr "op_type" "RRE")
1152 (set_attr "type" "fsimp<mode>")])
1153
1154 ; cxtr, cxbr, cdtr, cdbr, cebr, cdb, ceb
1155 (define_insn "*cmp<mode>_ccs"
1156 [(set (reg CC_REGNUM)
1157 (compare (match_operand:FP 0 "register_operand" "f,f")
1158 (match_operand:FP 1 "general_operand" "f,<Rf>")))]
1159 "s390_match_ccmode(insn, CCSmode) && TARGET_HARD_FLOAT"
1160 "@
1161 c<xde><bt>r\t%0,%1
1162 c<xde>b\t%0,%1"
1163 [(set_attr "op_type" "RRE,RXE")
1164 (set_attr "type" "fsimp<mode>")])
1165
1166 ; wfcedbs, wfchdbs, wfchedbs
1167 (define_insn "*vec_cmp<insn_cmp>df_cconly"
1168 [(set (reg:VFCMP CC_REGNUM)
1169 (compare:VFCMP (match_operand:DF 0 "register_operand" "v")
1170 (match_operand:DF 1 "register_operand" "v")))
1171 (clobber (match_scratch:V2DI 2 "=v"))]
1172 "TARGET_Z13 && TARGET_HARD_FLOAT"
1173 "wfc<asm_fcmp>dbs\t%v2,%v0,%v1"
1174 [(set_attr "op_type" "VRR")])
1175
1176 ; Compare and Branch instructions
1177
1178 ; cij, cgij, crj, cgrj, cfi, cgfi, cr, cgr
1179 ; The following instructions do a complementary access of their second
1180 ; operand (z01 only): crj_c, cgrjc, cr, cgr
1181 (define_insn "*cmp_and_br_signed_<mode>"
1182 [(set (pc)
1183 (if_then_else (match_operator 0 "s390_signed_integer_comparison"
1184 [(match_operand:GPR 1 "register_operand" "d,d")
1185 (match_operand:GPR 2 "nonmemory_operand" "d,C")])
1186 (label_ref (match_operand 3 "" ""))
1187 (pc)))
1188 (clobber (reg:CC CC_REGNUM))]
1189 "TARGET_Z10 && !TARGET_AVOID_CMP_AND_BRANCH"
1190 {
1191 if (get_attr_length (insn) == 6)
1192 return which_alternative ?
1193 "c<g>ij%C0\t%1,%c2,%l3" : "c<g>rj%C0\t%1,%2,%l3";
1194 else
1195 return which_alternative ?
1196 "c<g>fi\t%1,%c2\;jg%C0\t%l3" : "c<g>r\t%1,%2\;jg%C0\t%l3";
1197 }
1198 [(set_attr "op_type" "RIE")
1199 (set_attr "type" "branch")
1200 (set_attr "z10prop" "z10_super_c,z10_super")
1201 (set (attr "length")
1202 (if_then_else (lt (abs (minus (pc) (match_dup 3))) (const_int 60000))
1203 (const_int 6) (const_int 12)))]) ; 8 byte for cr/jg
1204 ; 10 byte for cgr/jg
1205
1206 ; clij, clgij, clrj, clgrj, clfi, clgfi, clr, clgr
1207 ; The following instructions do a complementary access of their second
1208 ; operand (z10 only): clrj, clgrj, clr, clgr
1209 (define_insn "*cmp_and_br_unsigned_<mode>"
1210 [(set (pc)
1211 (if_then_else (match_operator 0 "s390_unsigned_integer_comparison"
1212 [(match_operand:GPR 1 "register_operand" "d,d")
1213 (match_operand:GPR 2 "nonmemory_operand" "d,I")])
1214 (label_ref (match_operand 3 "" ""))
1215 (pc)))
1216 (clobber (reg:CC CC_REGNUM))]
1217 "TARGET_Z10 && !TARGET_AVOID_CMP_AND_BRANCH"
1218 {
1219 if (get_attr_length (insn) == 6)
1220 return which_alternative ?
1221 "cl<g>ij%C0\t%1,%b2,%l3" : "cl<g>rj%C0\t%1,%2,%l3";
1222 else
1223 return which_alternative ?
1224 "cl<g>fi\t%1,%b2\;jg%C0\t%l3" : "cl<g>r\t%1,%2\;jg%C0\t%l3";
1225 }
1226 [(set_attr "op_type" "RIE")
1227 (set_attr "type" "branch")
1228 (set_attr "z10prop" "z10_super_c,z10_super")
1229 (set (attr "length")
1230 (if_then_else (lt (abs (minus (pc) (match_dup 3))) (const_int 60000))
1231 (const_int 6) (const_int 12)))]) ; 8 byte for clr/jg
1232 ; 10 byte for clgr/jg
1233
1234 ; And now the same two patterns as above but with a negated CC mask.
1235
1236 ; cij, cgij, crj, cgrj, cfi, cgfi, cr, cgr
1237 ; The following instructions do a complementary access of their second
1238 ; operand (z01 only): crj_c, cgrjc, cr, cgr
1239 (define_insn "*icmp_and_br_signed_<mode>"
1240 [(set (pc)
1241 (if_then_else (match_operator 0 "s390_signed_integer_comparison"
1242 [(match_operand:GPR 1 "register_operand" "d,d")
1243 (match_operand:GPR 2 "nonmemory_operand" "d,C")])
1244 (pc)
1245 (label_ref (match_operand 3 "" ""))))
1246 (clobber (reg:CC CC_REGNUM))]
1247 "TARGET_Z10 && !TARGET_AVOID_CMP_AND_BRANCH"
1248 {
1249 if (get_attr_length (insn) == 6)
1250 return which_alternative ?
1251 "c<g>ij%D0\t%1,%c2,%l3" : "c<g>rj%D0\t%1,%2,%l3";
1252 else
1253 return which_alternative ?
1254 "c<g>fi\t%1,%c2\;jg%D0\t%l3" : "c<g>r\t%1,%2\;jg%D0\t%l3";
1255 }
1256 [(set_attr "op_type" "RIE")
1257 (set_attr "type" "branch")
1258 (set_attr "z10prop" "z10_super_c,z10_super")
1259 (set (attr "length")
1260 (if_then_else (lt (abs (minus (pc) (match_dup 3))) (const_int 60000))
1261 (const_int 6) (const_int 12)))]) ; 8 byte for cr/jg
1262 ; 10 byte for cgr/jg
1263
1264 ; clij, clgij, clrj, clgrj, clfi, clgfi, clr, clgr
1265 ; The following instructions do a complementary access of their second
1266 ; operand (z10 only): clrj, clgrj, clr, clgr
1267 (define_insn "*icmp_and_br_unsigned_<mode>"
1268 [(set (pc)
1269 (if_then_else (match_operator 0 "s390_unsigned_integer_comparison"
1270 [(match_operand:GPR 1 "register_operand" "d,d")
1271 (match_operand:GPR 2 "nonmemory_operand" "d,I")])
1272 (pc)
1273 (label_ref (match_operand 3 "" ""))))
1274 (clobber (reg:CC CC_REGNUM))]
1275 "TARGET_Z10 && !TARGET_AVOID_CMP_AND_BRANCH"
1276 {
1277 if (get_attr_length (insn) == 6)
1278 return which_alternative ?
1279 "cl<g>ij%D0\t%1,%b2,%l3" : "cl<g>rj%D0\t%1,%2,%l3";
1280 else
1281 return which_alternative ?
1282 "cl<g>fi\t%1,%b2\;jg%D0\t%l3" : "cl<g>r\t%1,%2\;jg%D0\t%l3";
1283 }
1284 [(set_attr "op_type" "RIE")
1285 (set_attr "type" "branch")
1286 (set_attr "z10prop" "z10_super_c,z10_super")
1287 (set (attr "length")
1288 (if_then_else (lt (abs (minus (pc) (match_dup 3))) (const_int 60000))
1289 (const_int 6) (const_int 12)))]) ; 8 byte for clr/jg
1290 ; 10 byte for clgr/jg
1291
1292 ;;
1293 ;;- Move instructions.
1294 ;;
1295
1296 ;
1297 ; movti instruction pattern(s).
1298 ;
1299
1300 ; FIXME: More constants are possible by enabling jxx, jyy constraints
1301 ; for TImode (use double-int for the calculations)
1302 (define_insn "movti"
1303 [(set (match_operand:TI 0 "nonimmediate_operand" "=d,QS,v, v, v,v,d, v,QR, d,o")
1304 (match_operand:TI 1 "general_operand" "QS, d,v,j00,jm1,d,v,QR, v,dPRT,d"))]
1305 "TARGET_ZARCH"
1306 "@
1307 lmg\t%0,%N0,%S1
1308 stmg\t%1,%N1,%S0
1309 vlr\t%v0,%v1
1310 vzero\t%v0
1311 vone\t%v0
1312 vlvgp\t%v0,%1,%N1
1313 #
1314 vl\t%v0,%1
1315 vst\t%v1,%0
1316 #
1317 #"
1318 [(set_attr "op_type" "RSY,RSY,VRR,VRI,VRI,VRR,*,VRX,VRX,*,*")
1319 (set_attr "type" "lm,stm,*,*,*,*,*,*,*,*,*")
1320 (set_attr "cpu_facility" "*,*,vec,vec,vec,vec,vec,vec,vec,*,*")])
1321
1322 (define_split
1323 [(set (match_operand:TI 0 "nonimmediate_operand" "")
1324 (match_operand:TI 1 "general_operand" ""))]
1325 "TARGET_ZARCH && reload_completed
1326 && s390_split_ok_p (operands[0], operands[1], TImode, 0)"
1327 [(set (match_dup 2) (match_dup 4))
1328 (set (match_dup 3) (match_dup 5))]
1329 {
1330 operands[2] = operand_subword (operands[0], 0, 0, TImode);
1331 operands[3] = operand_subword (operands[0], 1, 0, TImode);
1332 operands[4] = operand_subword (operands[1], 0, 0, TImode);
1333 operands[5] = operand_subword (operands[1], 1, 0, TImode);
1334 })
1335
1336 (define_split
1337 [(set (match_operand:TI 0 "nonimmediate_operand" "")
1338 (match_operand:TI 1 "general_operand" ""))]
1339 "TARGET_ZARCH && reload_completed
1340 && s390_split_ok_p (operands[0], operands[1], TImode, 1)"
1341 [(set (match_dup 2) (match_dup 4))
1342 (set (match_dup 3) (match_dup 5))]
1343 {
1344 operands[2] = operand_subword (operands[0], 1, 0, TImode);
1345 operands[3] = operand_subword (operands[0], 0, 0, TImode);
1346 operands[4] = operand_subword (operands[1], 1, 0, TImode);
1347 operands[5] = operand_subword (operands[1], 0, 0, TImode);
1348 })
1349
1350 ; Use part of the TImode target reg to perform the address
1351 ; calculation. If the TImode value is supposed to be copied into a VR
1352 ; this splitter is not necessary.
1353 (define_split
1354 [(set (match_operand:TI 0 "register_operand" "")
1355 (match_operand:TI 1 "memory_operand" ""))]
1356 "TARGET_ZARCH && reload_completed
1357 && !VECTOR_REG_P (operands[0])
1358 && !s_operand (operands[1], VOIDmode)"
1359 [(set (match_dup 0) (match_dup 1))]
1360 {
1361 rtx addr = operand_subword (operands[0], 1, 0, TImode);
1362 addr = gen_lowpart (Pmode, addr);
1363 s390_load_address (addr, XEXP (operands[1], 0));
1364 operands[1] = replace_equiv_address (operands[1], addr);
1365 })
1366
1367
1368 ; Split a VR -> GPR TImode move into 2 vector load GR from VR element.
1369 ; For the higher order bits we do simply a DImode move while the
1370 ; second part is done via vec extract. Both will end up as vlgvg.
1371 (define_split
1372 [(set (match_operand:TI 0 "register_operand" "")
1373 (match_operand:TI 1 "register_operand" ""))]
1374 "TARGET_VX && reload_completed
1375 && GENERAL_REG_P (operands[0])
1376 && VECTOR_REG_P (operands[1])"
1377 [(set (match_dup 2) (match_dup 4))
1378 (set (match_dup 3) (unspec:DI [(match_dup 5) (const_int 1)]
1379 UNSPEC_VEC_EXTRACT))]
1380 {
1381 operands[2] = operand_subword (operands[0], 0, 0, TImode);
1382 operands[3] = operand_subword (operands[0], 1, 0, TImode);
1383 operands[4] = gen_rtx_REG (DImode, REGNO (operands[1]));
1384 operands[5] = gen_rtx_REG (V2DImode, REGNO (operands[1]));
1385 })
1386
1387 ;
1388 ; Patterns used for secondary reloads
1389 ;
1390
1391 ; z10 provides move instructions accepting larl memory operands.
1392 ; Unfortunately there is no such variant for QI, TI and FP mode moves.
1393 ; These patterns are also used for unaligned SI and DI accesses.
1394
1395 (define_expand "reload<ALL:mode><P:mode>_tomem_z10"
1396 [(parallel [(match_operand:ALL 0 "memory_operand" "")
1397 (match_operand:ALL 1 "register_operand" "=d")
1398 (match_operand:P 2 "register_operand" "=&a")])]
1399 "TARGET_Z10"
1400 {
1401 s390_reload_symref_address (operands[1], operands[0], operands[2], 1);
1402 DONE;
1403 })
1404
1405 (define_expand "reload<ALL:mode><P:mode>_toreg_z10"
1406 [(parallel [(match_operand:ALL 0 "register_operand" "=d")
1407 (match_operand:ALL 1 "memory_operand" "")
1408 (match_operand:P 2 "register_operand" "=a")])]
1409 "TARGET_Z10"
1410 {
1411 s390_reload_symref_address (operands[0], operands[1], operands[2], 0);
1412 DONE;
1413 })
1414
1415 (define_expand "reload<P:mode>_larl_odd_addend_z10"
1416 [(parallel [(match_operand:P 0 "register_operand" "=d")
1417 (match_operand:P 1 "larl_operand" "")
1418 (match_operand:P 2 "register_operand" "=a")])]
1419 "TARGET_Z10"
1420 {
1421 s390_reload_larl_operand (operands[0], operands[1], operands[2]);
1422 DONE;
1423 })
1424
1425 ; Handles loading a PLUS (load address) expression
1426
1427 (define_expand "reload<mode>_plus"
1428 [(parallel [(match_operand:P 0 "register_operand" "=a")
1429 (match_operand:P 1 "s390_plus_operand" "")
1430 (match_operand:P 2 "register_operand" "=&a")])]
1431 ""
1432 {
1433 s390_expand_plus_operand (operands[0], operands[1], operands[2]);
1434 DONE;
1435 })
1436
1437 ; Not all the indirect memory access instructions support the full
1438 ; format (long disp + index + base). So whenever a move from/to such
1439 ; an address is required and the instruction cannot deal with it we do
1440 ; a load address into a scratch register first and use this as the new
1441 ; base register.
1442 ; This in particular is used for:
1443 ; - non-offsetable memory accesses for multiword moves
1444 ; - full vector reg moves with long displacements
1445
1446 (define_expand "reload<mode>_la_in"
1447 [(parallel [(match_operand 0 "register_operand" "")
1448 (match_operand 1 "" "")
1449 (match_operand:P 2 "register_operand" "=&a")])]
1450 ""
1451 {
1452 gcc_assert (MEM_P (operands[1]));
1453 s390_load_address (operands[2], find_replacement (&XEXP (operands[1], 0)));
1454 operands[1] = replace_equiv_address (operands[1], operands[2]);
1455 emit_move_insn (operands[0], operands[1]);
1456 DONE;
1457 })
1458
1459 (define_expand "reload<mode>_la_out"
1460 [(parallel [(match_operand 0 "" "")
1461 (match_operand 1 "register_operand" "")
1462 (match_operand:P 2 "register_operand" "=&a")])]
1463 ""
1464 {
1465 gcc_assert (MEM_P (operands[0]));
1466 s390_load_address (operands[2], find_replacement (&XEXP (operands[0], 0)));
1467 operands[0] = replace_equiv_address (operands[0], operands[2]);
1468 emit_move_insn (operands[0], operands[1]);
1469 DONE;
1470 })
1471
1472 (define_expand "reload<mode>_PIC_addr"
1473 [(parallel [(match_operand 0 "register_operand" "=d")
1474 (match_operand 1 "larl_operand" "")
1475 (match_operand:P 2 "register_operand" "=a")])]
1476 ""
1477 {
1478 rtx new_rtx = legitimize_pic_address (operands[1], operands[2]);
1479 emit_move_insn (operands[0], new_rtx);
1480 })
1481
1482 ;
1483 ; movdi instruction pattern(s).
1484 ;
1485
1486 (define_expand "movdi"
1487 [(set (match_operand:DI 0 "general_operand" "")
1488 (match_operand:DI 1 "general_operand" ""))]
1489 ""
1490 {
1491 /* Handle symbolic constants. */
1492 if (TARGET_64BIT
1493 && (SYMBOLIC_CONST (operands[1])
1494 || (GET_CODE (operands[1]) == PLUS
1495 && XEXP (operands[1], 0) == pic_offset_table_rtx
1496 && SYMBOLIC_CONST (XEXP (operands[1], 1)))))
1497 emit_symbolic_move (operands);
1498 })
1499
1500 (define_insn "*movdi_larl"
1501 [(set (match_operand:DI 0 "register_operand" "=d")
1502 (match_operand:DI 1 "larl_operand" "X"))]
1503 "TARGET_64BIT
1504 && !FP_REG_P (operands[0])"
1505 "larl\t%0,%1"
1506 [(set_attr "op_type" "RIL")
1507 (set_attr "type" "larl")
1508 (set_attr "z10prop" "z10_super_A1")])
1509
1510 (define_insn "*movdi_64"
1511 [(set (match_operand:DI 0 "nonimmediate_operand"
1512 "=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")
1513 (match_operand:DI 1 "general_operand"
1514 " 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"))]
1515 "TARGET_ZARCH"
1516 "@
1517 lghi\t%0,%h1
1518 llihh\t%0,%i1
1519 llihl\t%0,%i1
1520 llilh\t%0,%i1
1521 llill\t%0,%i1
1522 lgfi\t%0,%1
1523 llihf\t%0,%k1
1524 llilf\t%0,%k1
1525 ldgr\t%0,%1
1526 lgdr\t%0,%1
1527 lay\t%0,%a1
1528 lgrl\t%0,%1
1529 lgr\t%0,%1
1530 lg\t%0,%1
1531 stg\t%1,%0
1532 ldr\t%0,%1
1533 ld\t%0,%1
1534 ldy\t%0,%1
1535 std\t%1,%0
1536 stdy\t%1,%0
1537 stgrl\t%1,%0
1538 mvghi\t%0,%1
1539 #
1540 #
1541 stam\t%1,%N1,%S0
1542 lam\t%0,%N0,%S1
1543 vleig\t%v0,%h1,0
1544 vlr\t%v0,%v1
1545 vlvgg\t%v0,%1,0
1546 vlgvg\t%0,%v1,0
1547 vleg\t%v0,%1,0
1548 vsteg\t%v1,%0,0"
1549 [(set_attr "op_type" "RI,RI,RI,RI,RI,RIL,RIL,RIL,RRE,RRE,RXY,RIL,RRE,RXY,
1550 RXY,RR,RX,RXY,RX,RXY,RIL,SIL,*,*,RS,RS,VRI,VRR,VRS,VRS,VRX,VRX")
1551 (set_attr "type" "*,*,*,*,*,*,*,*,floaddf,floaddf,la,larl,lr,load,store,
1552 floaddf,floaddf,floaddf,fstoredf,fstoredf,larl,*,*,*,*,
1553 *,*,*,*,*,*,*")
1554 (set_attr "cpu_facility" "*,*,*,*,*,extimm,extimm,extimm,dfp,dfp,longdisp,
1555 z10,*,*,*,*,*,longdisp,*,longdisp,
1556 z10,z10,*,*,*,*,vec,vec,vec,vec,vec,vec")
1557 (set_attr "z10prop" "z10_fwd_A1,
1558 z10_fwd_E1,
1559 z10_fwd_E1,
1560 z10_fwd_E1,
1561 z10_fwd_E1,
1562 z10_fwd_A1,
1563 z10_fwd_E1,
1564 z10_fwd_E1,
1565 *,
1566 *,
1567 z10_fwd_A1,
1568 z10_fwd_A3,
1569 z10_fr_E1,
1570 z10_fwd_A3,
1571 z10_rec,
1572 *,
1573 *,
1574 *,
1575 *,
1576 *,
1577 z10_rec,
1578 z10_super,
1579 *,
1580 *,
1581 *,
1582 *,*,*,*,*,*,*")
1583 ])
1584
1585 (define_split
1586 [(set (match_operand:DI 0 "register_operand" "")
1587 (match_operand:DI 1 "register_operand" ""))]
1588 "TARGET_ZARCH && ACCESS_REG_P (operands[1])"
1589 [(set (match_dup 2) (match_dup 3))
1590 (set (match_dup 0) (ashift:DI (match_dup 0) (const_int 32)))
1591 (set (strict_low_part (match_dup 2)) (match_dup 4))]
1592 "operands[2] = gen_lowpart (SImode, operands[0]);
1593 s390_split_access_reg (operands[1], &operands[4], &operands[3]);")
1594
1595 (define_split
1596 [(set (match_operand:DI 0 "register_operand" "")
1597 (match_operand:DI 1 "register_operand" ""))]
1598 "TARGET_ZARCH && ACCESS_REG_P (operands[0])
1599 && dead_or_set_p (insn, operands[1])"
1600 [(set (match_dup 3) (match_dup 2))
1601 (set (match_dup 1) (lshiftrt:DI (match_dup 1) (const_int 32)))
1602 (set (match_dup 4) (match_dup 2))]
1603 "operands[2] = gen_lowpart (SImode, operands[1]);
1604 s390_split_access_reg (operands[0], &operands[3], &operands[4]);")
1605
1606 (define_split
1607 [(set (match_operand:DI 0 "register_operand" "")
1608 (match_operand:DI 1 "register_operand" ""))]
1609 "TARGET_ZARCH && ACCESS_REG_P (operands[0])
1610 && !dead_or_set_p (insn, operands[1])"
1611 [(set (match_dup 3) (match_dup 2))
1612 (set (match_dup 1) (rotate:DI (match_dup 1) (const_int 32)))
1613 (set (match_dup 4) (match_dup 2))
1614 (set (match_dup 1) (rotate:DI (match_dup 1) (const_int 32)))]
1615 "operands[2] = gen_lowpart (SImode, operands[1]);
1616 s390_split_access_reg (operands[0], &operands[3], &operands[4]);")
1617
1618 (define_insn "*movdi_31"
1619 [(set (match_operand:DI 0 "nonimmediate_operand"
1620 "=d,d,Q,S,d ,o,!*f,!*f,!*f,!R,!T,d")
1621 (match_operand:DI 1 "general_operand"
1622 " Q,S,d,d,dPRT,d, *f, R, T,*f,*f,b"))]
1623 "!TARGET_ZARCH"
1624 "@
1625 lm\t%0,%N0,%S1
1626 lmy\t%0,%N0,%S1
1627 stm\t%1,%N1,%S0
1628 stmy\t%1,%N1,%S0
1629 #
1630 #
1631 ldr\t%0,%1
1632 ld\t%0,%1
1633 ldy\t%0,%1
1634 std\t%1,%0
1635 stdy\t%1,%0
1636 #"
1637 [(set_attr "op_type" "RS,RSY,RS,RSY,*,*,RR,RX,RXY,RX,RXY,*")
1638 (set_attr "type" "lm,lm,stm,stm,*,*,floaddf,floaddf,floaddf,fstoredf,fstoredf,*")
1639 (set_attr "cpu_facility" "*,*,*,*,*,*,*,*,*,*,*,z10")])
1640
1641 ; For a load from a symbol ref we can use one of the target registers
1642 ; together with larl to load the address.
1643 (define_split
1644 [(set (match_operand:DI 0 "register_operand" "")
1645 (match_operand:DI 1 "memory_operand" ""))]
1646 "!TARGET_ZARCH && reload_completed && TARGET_Z10
1647 && larl_operand (XEXP (operands[1], 0), SImode)"
1648 [(set (match_dup 2) (match_dup 3))
1649 (set (match_dup 0) (match_dup 1))]
1650 {
1651 operands[2] = operand_subword (operands[0], 1, 0, DImode);
1652 operands[3] = XEXP (operands[1], 0);
1653 operands[1] = replace_equiv_address (operands[1], operands[2]);
1654 })
1655
1656 (define_split
1657 [(set (match_operand:DI 0 "nonimmediate_operand" "")
1658 (match_operand:DI 1 "general_operand" ""))]
1659 "!TARGET_ZARCH && reload_completed
1660 && s390_split_ok_p (operands[0], operands[1], DImode, 0)"
1661 [(set (match_dup 2) (match_dup 4))
1662 (set (match_dup 3) (match_dup 5))]
1663 {
1664 operands[2] = operand_subword (operands[0], 0, 0, DImode);
1665 operands[3] = operand_subword (operands[0], 1, 0, DImode);
1666 operands[4] = operand_subword (operands[1], 0, 0, DImode);
1667 operands[5] = operand_subword (operands[1], 1, 0, DImode);
1668 })
1669
1670 (define_split
1671 [(set (match_operand:DI 0 "nonimmediate_operand" "")
1672 (match_operand:DI 1 "general_operand" ""))]
1673 "!TARGET_ZARCH && reload_completed
1674 && s390_split_ok_p (operands[0], operands[1], DImode, 1)"
1675 [(set (match_dup 2) (match_dup 4))
1676 (set (match_dup 3) (match_dup 5))]
1677 {
1678 operands[2] = operand_subword (operands[0], 1, 0, DImode);
1679 operands[3] = operand_subword (operands[0], 0, 0, DImode);
1680 operands[4] = operand_subword (operands[1], 1, 0, DImode);
1681 operands[5] = operand_subword (operands[1], 0, 0, DImode);
1682 })
1683
1684 (define_split
1685 [(set (match_operand:DI 0 "register_operand" "")
1686 (match_operand:DI 1 "memory_operand" ""))]
1687 "!TARGET_ZARCH && reload_completed
1688 && !FP_REG_P (operands[0])
1689 && !s_operand (operands[1], VOIDmode)"
1690 [(set (match_dup 0) (match_dup 1))]
1691 {
1692 rtx addr = operand_subword (operands[0], 1, 0, DImode);
1693 s390_load_address (addr, XEXP (operands[1], 0));
1694 operands[1] = replace_equiv_address (operands[1], addr);
1695 })
1696
1697 (define_peephole2
1698 [(set (match_operand:DI 0 "register_operand" "")
1699 (mem:DI (match_operand 1 "address_operand" "")))]
1700 "TARGET_ZARCH
1701 && !FP_REG_P (operands[0])
1702 && GET_CODE (operands[1]) == SYMBOL_REF
1703 && CONSTANT_POOL_ADDRESS_P (operands[1])
1704 && get_pool_mode (operands[1]) == DImode
1705 && legitimate_reload_constant_p (get_pool_constant (operands[1]))"
1706 [(set (match_dup 0) (match_dup 2))]
1707 "operands[2] = get_pool_constant (operands[1]);")
1708
1709 (define_insn "*la_64"
1710 [(set (match_operand:DI 0 "register_operand" "=d,d")
1711 (match_operand:QI 1 "address_operand" "ZQZR,ZSZT"))]
1712 "TARGET_64BIT"
1713 "@
1714 la\t%0,%a1
1715 lay\t%0,%a1"
1716 [(set_attr "op_type" "RX,RXY")
1717 (set_attr "type" "la")
1718 (set_attr "z10prop" "z10_fwd_A1,z10_fwd_A1")])
1719
1720 (define_peephole2
1721 [(parallel
1722 [(set (match_operand:DI 0 "register_operand" "")
1723 (match_operand:QI 1 "address_operand" ""))
1724 (clobber (reg:CC CC_REGNUM))])]
1725 "TARGET_64BIT
1726 && preferred_la_operand_p (operands[1], const0_rtx)"
1727 [(set (match_dup 0) (match_dup 1))]
1728 "")
1729
1730 (define_peephole2
1731 [(set (match_operand:DI 0 "register_operand" "")
1732 (match_operand:DI 1 "register_operand" ""))
1733 (parallel
1734 [(set (match_dup 0)
1735 (plus:DI (match_dup 0)
1736 (match_operand:DI 2 "nonmemory_operand" "")))
1737 (clobber (reg:CC CC_REGNUM))])]
1738 "TARGET_64BIT
1739 && !reg_overlap_mentioned_p (operands[0], operands[2])
1740 && preferred_la_operand_p (operands[1], operands[2])"
1741 [(set (match_dup 0) (plus:DI (match_dup 1) (match_dup 2)))]
1742 "")
1743
1744 ;
1745 ; movsi instruction pattern(s).
1746 ;
1747
1748 (define_expand "movsi"
1749 [(set (match_operand:SI 0 "general_operand" "")
1750 (match_operand:SI 1 "general_operand" ""))]
1751 ""
1752 {
1753 /* Handle symbolic constants. */
1754 if (!TARGET_64BIT
1755 && (SYMBOLIC_CONST (operands[1])
1756 || (GET_CODE (operands[1]) == PLUS
1757 && XEXP (operands[1], 0) == pic_offset_table_rtx
1758 && SYMBOLIC_CONST (XEXP(operands[1], 1)))))
1759 emit_symbolic_move (operands);
1760 })
1761
1762 (define_insn "*movsi_larl"
1763 [(set (match_operand:SI 0 "register_operand" "=d")
1764 (match_operand:SI 1 "larl_operand" "X"))]
1765 "!TARGET_64BIT && TARGET_CPU_ZARCH
1766 && !FP_REG_P (operands[0])"
1767 "larl\t%0,%1"
1768 [(set_attr "op_type" "RIL")
1769 (set_attr "type" "larl")
1770 (set_attr "z10prop" "z10_fwd_A1")])
1771
1772 (define_insn "*movsi_zarch"
1773 [(set (match_operand:SI 0 "nonimmediate_operand"
1774 "=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")
1775 (match_operand:SI 1 "general_operand"
1776 " 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"))]
1777 "TARGET_ZARCH"
1778 "@
1779 lhi\t%0,%h1
1780 llilh\t%0,%i1
1781 llill\t%0,%i1
1782 iilf\t%0,%o1
1783 lay\t%0,%a1
1784 lrl\t%0,%1
1785 lr\t%0,%1
1786 l\t%0,%1
1787 ly\t%0,%1
1788 st\t%1,%0
1789 sty\t%1,%0
1790 lder\t%0,%1
1791 ler\t%0,%1
1792 lde\t%0,%1
1793 le\t%0,%1
1794 ley\t%0,%1
1795 ste\t%1,%0
1796 stey\t%1,%0
1797 ear\t%0,%1
1798 sar\t%0,%1
1799 stam\t%1,%1,%S0
1800 strl\t%1,%0
1801 mvhi\t%0,%1
1802 lam\t%0,%0,%S1
1803 vleif\t%v0,%h1,0
1804 vlr\t%v0,%v1
1805 vlvgf\t%v0,%1,0
1806 vlgvf\t%0,%v1,0
1807 vlef\t%v0,%1,0
1808 vstef\t%v1,%0,0"
1809 [(set_attr "op_type" "RI,RI,RI,RIL,RXY,RIL,RR,RX,RXY,RX,RXY,
1810 RRE,RR,RXE,RX,RXY,RX,RXY,RRE,RRE,RS,RIL,SIL,RS,VRI,VRR,VRS,VRS,VRX,VRX")
1811 (set_attr "type" "*,
1812 *,
1813 *,
1814 *,
1815 la,
1816 larl,
1817 lr,
1818 load,
1819 load,
1820 store,
1821 store,
1822 floadsf,
1823 floadsf,
1824 floadsf,
1825 floadsf,
1826 floadsf,
1827 fstoresf,
1828 fstoresf,
1829 *,
1830 *,
1831 *,
1832 larl,
1833 *,
1834 *,*,*,*,*,*,*")
1835 (set_attr "cpu_facility" "*,*,*,extimm,longdisp,z10,*,*,longdisp,*,longdisp,
1836 vec,*,vec,*,longdisp,*,longdisp,*,*,*,z10,z10,*,vec,vec,vec,vec,vec,vec")
1837 (set_attr "z10prop" "z10_fwd_A1,
1838 z10_fwd_E1,
1839 z10_fwd_E1,
1840 z10_fwd_A1,
1841 z10_fwd_A1,
1842 z10_fwd_A3,
1843 z10_fr_E1,
1844 z10_fwd_A3,
1845 z10_fwd_A3,
1846 z10_rec,
1847 z10_rec,
1848 *,
1849 *,
1850 *,
1851 *,
1852 *,
1853 *,
1854 *,
1855 z10_super_E1,
1856 z10_super,
1857 *,
1858 z10_rec,
1859 z10_super,
1860 *,*,*,*,*,*,*")])
1861
1862 (define_insn "*movsi_esa"
1863 [(set (match_operand:SI 0 "nonimmediate_operand" "=d,d,d,R,!*f,!*f,!*f,!*f,!R,d,t,Q,t")
1864 (match_operand:SI 1 "general_operand" "K,d,R,d, *f, *f, R, R,*f,t,d,t,Q"))]
1865 "!TARGET_ZARCH"
1866 "@
1867 lhi\t%0,%h1
1868 lr\t%0,%1
1869 l\t%0,%1
1870 st\t%1,%0
1871 lder\t%0,%1
1872 ler\t%0,%1
1873 lde\t%0,%1
1874 le\t%0,%1
1875 ste\t%1,%0
1876 ear\t%0,%1
1877 sar\t%0,%1
1878 stam\t%1,%1,%S0
1879 lam\t%0,%0,%S1"
1880 [(set_attr "op_type" "RI,RR,RX,RX,RRE,RR,RXE,RX,RX,RRE,RRE,RS,RS")
1881 (set_attr "type" "*,lr,load,store,floadsf,floadsf,floadsf,floadsf,fstoresf,*,*,*,*")
1882 (set_attr "z10prop" "z10_fwd_A1,z10_fr_E1,z10_fwd_A3,z10_rec,*,*,*,*,*,z10_super_E1,
1883 z10_super,*,*")
1884 (set_attr "cpu_facility" "*,*,*,*,vec,*,vec,*,*,*,*,*,*")
1885 ])
1886
1887 (define_peephole2
1888 [(set (match_operand:SI 0 "register_operand" "")
1889 (mem:SI (match_operand 1 "address_operand" "")))]
1890 "!FP_REG_P (operands[0])
1891 && GET_CODE (operands[1]) == SYMBOL_REF
1892 && CONSTANT_POOL_ADDRESS_P (operands[1])
1893 && get_pool_mode (operands[1]) == SImode
1894 && legitimate_reload_constant_p (get_pool_constant (operands[1]))"
1895 [(set (match_dup 0) (match_dup 2))]
1896 "operands[2] = get_pool_constant (operands[1]);")
1897
1898 (define_insn "*la_31"
1899 [(set (match_operand:SI 0 "register_operand" "=d,d")
1900 (match_operand:QI 1 "address_operand" "ZQZR,ZSZT"))]
1901 "!TARGET_64BIT && legitimate_la_operand_p (operands[1])"
1902 "@
1903 la\t%0,%a1
1904 lay\t%0,%a1"
1905 [(set_attr "op_type" "RX,RXY")
1906 (set_attr "type" "la")
1907 (set_attr "z10prop" "z10_fwd_A1,z10_fwd_A1")])
1908
1909 (define_peephole2
1910 [(parallel
1911 [(set (match_operand:SI 0 "register_operand" "")
1912 (match_operand:QI 1 "address_operand" ""))
1913 (clobber (reg:CC CC_REGNUM))])]
1914 "!TARGET_64BIT
1915 && preferred_la_operand_p (operands[1], const0_rtx)"
1916 [(set (match_dup 0) (match_dup 1))]
1917 "")
1918
1919 (define_peephole2
1920 [(set (match_operand:SI 0 "register_operand" "")
1921 (match_operand:SI 1 "register_operand" ""))
1922 (parallel
1923 [(set (match_dup 0)
1924 (plus:SI (match_dup 0)
1925 (match_operand:SI 2 "nonmemory_operand" "")))
1926 (clobber (reg:CC CC_REGNUM))])]
1927 "!TARGET_64BIT
1928 && !reg_overlap_mentioned_p (operands[0], operands[2])
1929 && preferred_la_operand_p (operands[1], operands[2])"
1930 [(set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))]
1931 "")
1932
1933 (define_insn "*la_31_and"
1934 [(set (match_operand:SI 0 "register_operand" "=d,d")
1935 (and:SI (match_operand:QI 1 "address_operand" "ZQZR,ZSZT")
1936 (const_int 2147483647)))]
1937 "!TARGET_64BIT"
1938 "@
1939 la\t%0,%a1
1940 lay\t%0,%a1"
1941 [(set_attr "op_type" "RX,RXY")
1942 (set_attr "type" "la")
1943 (set_attr "z10prop" "z10_fwd_A1,z10_fwd_A1")])
1944
1945 (define_insn_and_split "*la_31_and_cc"
1946 [(set (match_operand:SI 0 "register_operand" "=d")
1947 (and:SI (match_operand:QI 1 "address_operand" "p")
1948 (const_int 2147483647)))
1949 (clobber (reg:CC CC_REGNUM))]
1950 "!TARGET_64BIT"
1951 "#"
1952 "&& reload_completed"
1953 [(set (match_dup 0)
1954 (and:SI (match_dup 1) (const_int 2147483647)))]
1955 ""
1956 [(set_attr "op_type" "RX")
1957 (set_attr "type" "la")])
1958
1959 (define_insn "force_la_31"
1960 [(set (match_operand:SI 0 "register_operand" "=d,d")
1961 (match_operand:QI 1 "address_operand" "ZQZR,ZSZT"))
1962 (use (const_int 0))]
1963 "!TARGET_64BIT"
1964 "@
1965 la\t%0,%a1
1966 lay\t%0,%a1"
1967 [(set_attr "op_type" "RX")
1968 (set_attr "type" "la")
1969 (set_attr "z10prop" "z10_fwd_A1,z10_fwd_A1")])
1970
1971 ;
1972 ; movhi instruction pattern(s).
1973 ;
1974
1975 (define_expand "movhi"
1976 [(set (match_operand:HI 0 "nonimmediate_operand" "")
1977 (match_operand:HI 1 "general_operand" ""))]
1978 ""
1979 {
1980 /* Make it explicit that loading a register from memory
1981 always sign-extends (at least) to SImode. */
1982 if (optimize && can_create_pseudo_p ()
1983 && register_operand (operands[0], VOIDmode)
1984 && GET_CODE (operands[1]) == MEM)
1985 {
1986 rtx tmp = gen_reg_rtx (SImode);
1987 rtx ext = gen_rtx_SIGN_EXTEND (SImode, operands[1]);
1988 emit_insn (gen_rtx_SET (tmp, ext));
1989 operands[1] = gen_lowpart (HImode, tmp);
1990 }
1991 })
1992
1993 (define_insn "*movhi"
1994 [(set (match_operand:HI 0 "nonimmediate_operand" "=d,d,d,d,d,R,T,b,Q,v,v,v,d, v,QR")
1995 (match_operand:HI 1 "general_operand" " d,n,R,T,b,d,d,d,K,K,v,d,v,QR, v"))]
1996 ""
1997 "@
1998 lr\t%0,%1
1999 lhi\t%0,%h1
2000 lh\t%0,%1
2001 lhy\t%0,%1
2002 lhrl\t%0,%1
2003 sth\t%1,%0
2004 sthy\t%1,%0
2005 sthrl\t%1,%0
2006 mvhhi\t%0,%1
2007 vleih\t%v0,%h1,0
2008 vlr\t%v0,%v1
2009 vlvgh\t%v0,%1,0
2010 vlgvh\t%0,%v1,0
2011 vleh\t%v0,%1,0
2012 vsteh\t%v1,%0,0"
2013 [(set_attr "op_type" "RR,RI,RX,RXY,RIL,RX,RXY,RIL,SIL,VRI,VRR,VRS,VRS,VRX,VRX")
2014 (set_attr "type" "lr,*,*,*,larl,store,store,store,*,*,*,*,*,*,*")
2015 (set_attr "cpu_facility" "*,*,*,*,z10,*,*,z10,z10,vec,vec,vec,vec,vec,vec")
2016 (set_attr "z10prop" "z10_fr_E1,
2017 z10_fwd_A1,
2018 z10_super_E1,
2019 z10_super_E1,
2020 z10_super_E1,
2021 z10_rec,
2022 z10_rec,
2023 z10_rec,
2024 z10_super,*,*,*,*,*,*")])
2025
2026 (define_peephole2
2027 [(set (match_operand:HI 0 "register_operand" "")
2028 (mem:HI (match_operand 1 "address_operand" "")))]
2029 "GET_CODE (operands[1]) == SYMBOL_REF
2030 && CONSTANT_POOL_ADDRESS_P (operands[1])
2031 && get_pool_mode (operands[1]) == HImode
2032 && GET_CODE (get_pool_constant (operands[1])) == CONST_INT"
2033 [(set (match_dup 0) (match_dup 2))]
2034 "operands[2] = get_pool_constant (operands[1]);")
2035
2036 ;
2037 ; movqi instruction pattern(s).
2038 ;
2039
2040 (define_expand "movqi"
2041 [(set (match_operand:QI 0 "nonimmediate_operand" "")
2042 (match_operand:QI 1 "general_operand" ""))]
2043 ""
2044 {
2045 /* On z/Architecture, zero-extending from memory to register
2046 is just as fast as a QImode load. */
2047 if (TARGET_ZARCH && optimize && can_create_pseudo_p ()
2048 && register_operand (operands[0], VOIDmode)
2049 && GET_CODE (operands[1]) == MEM)
2050 {
2051 rtx tmp = gen_reg_rtx (DImode);
2052 rtx ext = gen_rtx_ZERO_EXTEND (DImode, operands[1]);
2053 emit_insn (gen_rtx_SET (tmp, ext));
2054 operands[1] = gen_lowpart (QImode, tmp);
2055 }
2056 })
2057
2058 (define_insn "*movqi"
2059 [(set (match_operand:QI 0 "nonimmediate_operand" "=d,d,d,d,R,T,Q,S,?Q,v,v,v,d, v,QR")
2060 (match_operand:QI 1 "general_operand" " d,n,R,T,d,d,n,n,?Q,K,v,d,v,QR, v"))]
2061 ""
2062 "@
2063 lr\t%0,%1
2064 lhi\t%0,%b1
2065 ic\t%0,%1
2066 icy\t%0,%1
2067 stc\t%1,%0
2068 stcy\t%1,%0
2069 mvi\t%S0,%b1
2070 mviy\t%S0,%b1
2071 #
2072 vleib\t%v0,%b1,0
2073 vlr\t%v0,%v1
2074 vlvgb\t%v0,%1,0
2075 vlgvb\t%0,%v1,0
2076 vleb\t%v0,%1,0
2077 vsteb\t%v1,%0,0"
2078 [(set_attr "op_type" "RR,RI,RX,RXY,RX,RXY,SI,SIY,SS,VRI,VRR,VRS,VRS,VRX,VRX")
2079 (set_attr "type" "lr,*,*,*,store,store,store,store,*,*,*,*,*,*,*")
2080 (set_attr "cpu_facility" "*,*,*,*,*,*,*,*,*,vec,vec,vec,vec,vec,vec")
2081 (set_attr "z10prop" "z10_fr_E1,
2082 z10_fwd_A1,
2083 z10_super_E1,
2084 z10_super_E1,
2085 z10_rec,
2086 z10_rec,
2087 z10_super,
2088 z10_super,
2089 *,*,*,*,*,*,*")])
2090
2091 (define_peephole2
2092 [(set (match_operand:QI 0 "nonimmediate_operand" "")
2093 (mem:QI (match_operand 1 "address_operand" "")))]
2094 "GET_CODE (operands[1]) == SYMBOL_REF
2095 && CONSTANT_POOL_ADDRESS_P (operands[1])
2096 && get_pool_mode (operands[1]) == QImode
2097 && GET_CODE (get_pool_constant (operands[1])) == CONST_INT"
2098 [(set (match_dup 0) (match_dup 2))]
2099 "operands[2] = get_pool_constant (operands[1]);")
2100
2101 ;
2102 ; movstrictqi instruction pattern(s).
2103 ;
2104
2105 (define_insn "*movstrictqi"
2106 [(set (strict_low_part (match_operand:QI 0 "register_operand" "+d,d"))
2107 (match_operand:QI 1 "memory_operand" "R,T"))]
2108 ""
2109 "@
2110 ic\t%0,%1
2111 icy\t%0,%1"
2112 [(set_attr "op_type" "RX,RXY")
2113 (set_attr "z10prop" "z10_super_E1,z10_super_E1")])
2114
2115 ;
2116 ; movstricthi instruction pattern(s).
2117 ;
2118
2119 (define_insn "*movstricthi"
2120 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+d,d"))
2121 (match_operand:HI 1 "memory_operand" "Q,S"))
2122 (clobber (reg:CC CC_REGNUM))]
2123 ""
2124 "@
2125 icm\t%0,3,%S1
2126 icmy\t%0,3,%S1"
2127 [(set_attr "op_type" "RS,RSY")
2128 (set_attr "z10prop" "z10_super_E1,z10_super_E1")])
2129
2130 ;
2131 ; movstrictsi instruction pattern(s).
2132 ;
2133
2134 (define_insn "movstrictsi"
2135 [(set (strict_low_part (match_operand:SI 0 "register_operand" "+d,d,d,d"))
2136 (match_operand:SI 1 "general_operand" "d,R,T,t"))]
2137 "TARGET_ZARCH"
2138 "@
2139 lr\t%0,%1
2140 l\t%0,%1
2141 ly\t%0,%1
2142 ear\t%0,%1"
2143 [(set_attr "op_type" "RR,RX,RXY,RRE")
2144 (set_attr "type" "lr,load,load,*")
2145 (set_attr "z10prop" "z10_fr_E1,z10_fwd_A3,z10_fwd_A3,z10_super_E1")])
2146
2147 ;
2148 ; mov(tf|td) instruction pattern(s).
2149 ;
2150
2151 (define_expand "mov<mode>"
2152 [(set (match_operand:TD_TF 0 "nonimmediate_operand" "")
2153 (match_operand:TD_TF 1 "general_operand" ""))]
2154 ""
2155 "")
2156
2157 (define_insn "*mov<mode>_64"
2158 [(set (match_operand:TD_TF 0 "nonimmediate_operand" "=f,f,f,o, d,QS, d,o")
2159 (match_operand:TD_TF 1 "general_operand" " G,f,o,f,QS, d,dRT,d"))]
2160 "TARGET_ZARCH"
2161 "@
2162 lzxr\t%0
2163 lxr\t%0,%1
2164 #
2165 #
2166 lmg\t%0,%N0,%S1
2167 stmg\t%1,%N1,%S0
2168 #
2169 #"
2170 [(set_attr "op_type" "RRE,RRE,*,*,RSY,RSY,*,*")
2171 (set_attr "type" "fsimptf,fsimptf,*,*,lm,stm,*,*")
2172 (set_attr "cpu_facility" "z196,*,*,*,*,*,*,*")])
2173
2174 (define_insn "*mov<mode>_31"
2175 [(set (match_operand:TD_TF 0 "nonimmediate_operand" "=f,f,f,o")
2176 (match_operand:TD_TF 1 "general_operand" " G,f,o,f"))]
2177 "!TARGET_ZARCH"
2178 "@
2179 lzxr\t%0
2180 lxr\t%0,%1
2181 #
2182 #"
2183 [(set_attr "op_type" "RRE,RRE,*,*")
2184 (set_attr "type" "fsimptf,fsimptf,*,*")
2185 (set_attr "cpu_facility" "z196,*,*,*")])
2186
2187 ; TFmode in GPRs splitters
2188
2189 (define_split
2190 [(set (match_operand:TD_TF 0 "nonimmediate_operand" "")
2191 (match_operand:TD_TF 1 "general_operand" ""))]
2192 "TARGET_ZARCH && reload_completed
2193 && s390_split_ok_p (operands[0], operands[1], <MODE>mode, 0)"
2194 [(set (match_dup 2) (match_dup 4))
2195 (set (match_dup 3) (match_dup 5))]
2196 {
2197 operands[2] = operand_subword (operands[0], 0, 0, <MODE>mode);
2198 operands[3] = operand_subword (operands[0], 1, 0, <MODE>mode);
2199 operands[4] = operand_subword (operands[1], 0, 0, <MODE>mode);
2200 operands[5] = operand_subword (operands[1], 1, 0, <MODE>mode);
2201 })
2202
2203 (define_split
2204 [(set (match_operand:TD_TF 0 "nonimmediate_operand" "")
2205 (match_operand:TD_TF 1 "general_operand" ""))]
2206 "TARGET_ZARCH && reload_completed
2207 && s390_split_ok_p (operands[0], operands[1], <MODE>mode, 1)"
2208 [(set (match_dup 2) (match_dup 4))
2209 (set (match_dup 3) (match_dup 5))]
2210 {
2211 operands[2] = operand_subword (operands[0], 1, 0, <MODE>mode);
2212 operands[3] = operand_subword (operands[0], 0, 0, <MODE>mode);
2213 operands[4] = operand_subword (operands[1], 1, 0, <MODE>mode);
2214 operands[5] = operand_subword (operands[1], 0, 0, <MODE>mode);
2215 })
2216
2217 (define_split
2218 [(set (match_operand:TD_TF 0 "register_operand" "")
2219 (match_operand:TD_TF 1 "memory_operand" ""))]
2220 "TARGET_ZARCH && reload_completed
2221 && GENERAL_REG_P (operands[0])
2222 && !s_operand (operands[1], VOIDmode)"
2223 [(set (match_dup 0) (match_dup 1))]
2224 {
2225 rtx addr = operand_subword (operands[0], 1, 0, <MODE>mode);
2226 addr = gen_lowpart (Pmode, addr);
2227 s390_load_address (addr, XEXP (operands[1], 0));
2228 operands[1] = replace_equiv_address (operands[1], addr);
2229 })
2230
2231 ; TFmode in BFPs splitters
2232
2233 (define_split
2234 [(set (match_operand:TD_TF 0 "register_operand" "")
2235 (match_operand:TD_TF 1 "memory_operand" ""))]
2236 "reload_completed && offsettable_memref_p (operands[1])
2237 && FP_REG_P (operands[0])"
2238 [(set (match_dup 2) (match_dup 4))
2239 (set (match_dup 3) (match_dup 5))]
2240 {
2241 operands[2] = simplify_gen_subreg (<HALF_TMODE>mode, operands[0],
2242 <MODE>mode, 0);
2243 operands[3] = simplify_gen_subreg (<HALF_TMODE>mode, operands[0],
2244 <MODE>mode, 8);
2245 operands[4] = adjust_address_nv (operands[1], <HALF_TMODE>mode, 0);
2246 operands[5] = adjust_address_nv (operands[1], <HALF_TMODE>mode, 8);
2247 })
2248
2249 (define_split
2250 [(set (match_operand:TD_TF 0 "memory_operand" "")
2251 (match_operand:TD_TF 1 "register_operand" ""))]
2252 "reload_completed && offsettable_memref_p (operands[0])
2253 && FP_REG_P (operands[1])"
2254 [(set (match_dup 2) (match_dup 4))
2255 (set (match_dup 3) (match_dup 5))]
2256 {
2257 operands[2] = adjust_address_nv (operands[0], <HALF_TMODE>mode, 0);
2258 operands[3] = adjust_address_nv (operands[0], <HALF_TMODE>mode, 8);
2259 operands[4] = simplify_gen_subreg (<HALF_TMODE>mode, operands[1],
2260 <MODE>mode, 0);
2261 operands[5] = simplify_gen_subreg (<HALF_TMODE>mode, operands[1],
2262 <MODE>mode, 8);
2263 })
2264
2265 ;
2266 ; mov(df|dd) instruction pattern(s).
2267 ;
2268
2269 (define_expand "mov<mode>"
2270 [(set (match_operand:DD_DF 0 "nonimmediate_operand" "")
2271 (match_operand:DD_DF 1 "general_operand" ""))]
2272 ""
2273 "")
2274
2275 (define_insn "*mov<mode>_64dfp"
2276 [(set (match_operand:DD_DF 0 "nonimmediate_operand"
2277 "=f,f,f,d,f,f,R,T,d,d,d, d,b,RT,v,v,d,v,QR")
2278 (match_operand:DD_DF 1 "general_operand"
2279 " G,f,d,f,R,T,f,f,G,d,b,RT,d, d,v,d,v,QR,v"))]
2280 "TARGET_DFP"
2281 "@
2282 lzdr\t%0
2283 ldr\t%0,%1
2284 ldgr\t%0,%1
2285 lgdr\t%0,%1
2286 ld\t%0,%1
2287 ldy\t%0,%1
2288 std\t%1,%0
2289 stdy\t%1,%0
2290 lghi\t%0,0
2291 lgr\t%0,%1
2292 lgrl\t%0,%1
2293 lg\t%0,%1
2294 stgrl\t%1,%0
2295 stg\t%1,%0
2296 vlr\t%v0,%v1
2297 vlvgg\t%v0,%1,0
2298 vlgvg\t%0,%v1,0
2299 vleg\t%0,%1,0
2300 vsteg\t%1,%0,0"
2301 [(set_attr "op_type" "RRE,RR,RRE,RRE,RX,RXY,RX,RXY,RI,RRE,RIL,RXY,RIL,RXY,VRR,VRS,VRS,VRX,VRX")
2302 (set_attr "type" "fsimpdf,floaddf,floaddf,floaddf,floaddf,floaddf,
2303 fstoredf,fstoredf,*,lr,load,load,store,store,*,*,*,load,store")
2304 (set_attr "z10prop" "*,*,*,*,*,*,*,*,z10_fwd_A1,z10_fr_E1,z10_fwd_A3,z10_fwd_A3,z10_rec,z10_rec,*,*,*,*,*")
2305 (set_attr "cpu_facility" "z196,*,*,*,*,*,*,*,*,*,z10,*,z10,*,vec,vec,vec,vec,vec")])
2306
2307 (define_insn "*mov<mode>_64"
2308 [(set (match_operand:DD_DF 0 "nonimmediate_operand" "=f,f,f,f,R,T,d,d,d, d,b,RT,v,v,QR")
2309 (match_operand:DD_DF 1 "general_operand" " G,f,R,T,f,f,G,d,b,RT,d, d,v,QR,v"))]
2310 "TARGET_ZARCH"
2311 "@
2312 lzdr\t%0
2313 ldr\t%0,%1
2314 ld\t%0,%1
2315 ldy\t%0,%1
2316 std\t%1,%0
2317 stdy\t%1,%0
2318 lghi\t%0,0
2319 lgr\t%0,%1
2320 lgrl\t%0,%1
2321 lg\t%0,%1
2322 stgrl\t%1,%0
2323 stg\t%1,%0
2324 vlr\t%v0,%v1
2325 vleg\t%v0,%1,0
2326 vsteg\t%v1,%0,0"
2327 [(set_attr "op_type" "RRE,RR,RX,RXY,RX,RXY,RI,RRE,RIL,RXY,RIL,RXY,VRR,VRX,VRX")
2328 (set_attr "type" "fsimpdf,fload<mode>,fload<mode>,fload<mode>,
2329 fstore<mode>,fstore<mode>,*,lr,load,load,store,store,*,load,store")
2330 (set_attr "z10prop" "*,*,*,*,*,*,z10_fwd_A1,z10_fr_E1,z10_fwd_A3,z10_fwd_A3,z10_rec,z10_rec,*,*,*")
2331 (set_attr "cpu_facility" "z196,*,*,*,*,*,*,*,z10,*,z10,*,vec,vec,vec")])
2332
2333 (define_insn "*mov<mode>_31"
2334 [(set (match_operand:DD_DF 0 "nonimmediate_operand"
2335 "=f,f,f,f,R,T,d,d,Q,S, d,o")
2336 (match_operand:DD_DF 1 "general_operand"
2337 " G,f,R,T,f,f,Q,S,d,d,dPRT,d"))]
2338 "!TARGET_ZARCH"
2339 "@
2340 lzdr\t%0
2341 ldr\t%0,%1
2342 ld\t%0,%1
2343 ldy\t%0,%1
2344 std\t%1,%0
2345 stdy\t%1,%0
2346 lm\t%0,%N0,%S1
2347 lmy\t%0,%N0,%S1
2348 stm\t%1,%N1,%S0
2349 stmy\t%1,%N1,%S0
2350 #
2351 #"
2352 [(set_attr "op_type" "RRE,RR,RX,RXY,RX,RXY,RS,RSY,RS,RSY,*,*")
2353 (set_attr "type" "fsimpdf,fload<mode>,fload<mode>,fload<mode>,
2354 fstore<mode>,fstore<mode>,lm,lm,stm,stm,*,*")
2355 (set_attr "cpu_facility" "z196,*,*,*,*,*,*,*,*,*,*,*")])
2356
2357 (define_split
2358 [(set (match_operand:DD_DF 0 "nonimmediate_operand" "")
2359 (match_operand:DD_DF 1 "general_operand" ""))]
2360 "!TARGET_ZARCH && reload_completed
2361 && s390_split_ok_p (operands[0], operands[1], <MODE>mode, 0)"
2362 [(set (match_dup 2) (match_dup 4))
2363 (set (match_dup 3) (match_dup 5))]
2364 {
2365 operands[2] = operand_subword (operands[0], 0, 0, <MODE>mode);
2366 operands[3] = operand_subword (operands[0], 1, 0, <MODE>mode);
2367 operands[4] = operand_subword (operands[1], 0, 0, <MODE>mode);
2368 operands[5] = operand_subword (operands[1], 1, 0, <MODE>mode);
2369 })
2370
2371 (define_split
2372 [(set (match_operand:DD_DF 0 "nonimmediate_operand" "")
2373 (match_operand:DD_DF 1 "general_operand" ""))]
2374 "!TARGET_ZARCH && reload_completed
2375 && s390_split_ok_p (operands[0], operands[1], <MODE>mode, 1)"
2376 [(set (match_dup 2) (match_dup 4))
2377 (set (match_dup 3) (match_dup 5))]
2378 {
2379 operands[2] = operand_subword (operands[0], 1, 0, <MODE>mode);
2380 operands[3] = operand_subword (operands[0], 0, 0, <MODE>mode);
2381 operands[4] = operand_subword (operands[1], 1, 0, <MODE>mode);
2382 operands[5] = operand_subword (operands[1], 0, 0, <MODE>mode);
2383 })
2384
2385 (define_split
2386 [(set (match_operand:DD_DF 0 "register_operand" "")
2387 (match_operand:DD_DF 1 "memory_operand" ""))]
2388 "!TARGET_ZARCH && reload_completed
2389 && !FP_REG_P (operands[0])
2390 && !s_operand (operands[1], VOIDmode)"
2391 [(set (match_dup 0) (match_dup 1))]
2392 {
2393 rtx addr = operand_subword (operands[0], 1, 0, <MODE>mode);
2394 s390_load_address (addr, XEXP (operands[1], 0));
2395 operands[1] = replace_equiv_address (operands[1], addr);
2396 })
2397
2398 ;
2399 ; mov(sf|sd) instruction pattern(s).
2400 ;
2401
2402 (define_insn "mov<mode>"
2403 [(set (match_operand:SD_SF 0 "nonimmediate_operand"
2404 "=f,f,f,f,f,f,R,T,d,d,d,d,d,b,R,T,v,v,v,d,v,QR")
2405 (match_operand:SD_SF 1 "general_operand"
2406 " G,f,f,R,R,T,f,f,G,d,b,R,T,d,d,d,v,G,d,v,QR,v"))]
2407 ""
2408 "@
2409 lzer\t%0
2410 lder\t%0,%1
2411 ler\t%0,%1
2412 lde\t%0,%1
2413 le\t%0,%1
2414 ley\t%0,%1
2415 ste\t%1,%0
2416 stey\t%1,%0
2417 lhi\t%0,0
2418 lr\t%0,%1
2419 lrl\t%0,%1
2420 l\t%0,%1
2421 ly\t%0,%1
2422 strl\t%1,%0
2423 st\t%1,%0
2424 sty\t%1,%0
2425 vlr\t%v0,%v1
2426 vleif\t%v0,0
2427 vlvgf\t%v0,%1,0
2428 vlgvf\t%0,%v1,0
2429 vleg\t%0,%1,0
2430 vsteg\t%1,%0,0"
2431 [(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")
2432 (set_attr "type" "fsimpsf,fsimpsf,fload<mode>,fload<mode>,fload<mode>,fload<mode>,
2433 fstore<mode>,fstore<mode>,*,lr,load,load,load,store,store,store,*,*,*,*,load,store")
2434 (set_attr "z10prop" "*,*,*,*,*,*,*,*,z10_fwd_A1,z10_fr_E1,z10_fr_E1,z10_fwd_A3,z10_fwd_A3,z10_rec,z10_rec,z10_rec,*,*,*,*,*,*")
2435 (set_attr "cpu_facility" "z196,vec,*,vec,*,*,*,*,*,*,z10,*,*,z10,*,*,vec,vec,vec,vec,vec,vec")])
2436
2437 ;
2438 ; movcc instruction pattern
2439 ;
2440
2441 (define_insn "movcc"
2442 [(set (match_operand:CC 0 "nonimmediate_operand" "=d,c,d,d,d,R,T")
2443 (match_operand:CC 1 "nonimmediate_operand" " d,d,c,R,T,d,d"))]
2444 ""
2445 "@
2446 lr\t%0,%1
2447 tmh\t%1,12288
2448 ipm\t%0
2449 l\t%0,%1
2450 ly\t%0,%1
2451 st\t%1,%0
2452 sty\t%1,%0"
2453 [(set_attr "op_type" "RR,RI,RRE,RX,RXY,RX,RXY")
2454 (set_attr "type" "lr,*,*,load,load,store,store")
2455 (set_attr "z10prop" "z10_fr_E1,z10_super,*,z10_fwd_A3,z10_fwd_A3,z10_rec,z10_rec")
2456 (set_attr "z196prop" "*,*,z196_ends,*,*,*,*")])
2457
2458 ;
2459 ; Block move (MVC) patterns.
2460 ;
2461
2462 (define_insn "*mvc"
2463 [(set (match_operand:BLK 0 "memory_operand" "=Q")
2464 (match_operand:BLK 1 "memory_operand" "Q"))
2465 (use (match_operand 2 "const_int_operand" "n"))]
2466 "INTVAL (operands[2]) >= 1 && INTVAL (operands[2]) <= 256"
2467 "mvc\t%O0(%2,%R0),%S1"
2468 [(set_attr "op_type" "SS")])
2469
2470 ; This splitter converts a QI to QI mode copy into a BLK mode copy in
2471 ; order to have it implemented with mvc.
2472
2473 (define_split
2474 [(set (match_operand:QI 0 "memory_operand" "")
2475 (match_operand:QI 1 "memory_operand" ""))]
2476 "reload_completed"
2477 [(parallel
2478 [(set (match_dup 0) (match_dup 1))
2479 (use (const_int 1))])]
2480 {
2481 operands[0] = adjust_address (operands[0], BLKmode, 0);
2482 operands[1] = adjust_address (operands[1], BLKmode, 0);
2483 })
2484
2485
2486 (define_peephole2
2487 [(parallel
2488 [(set (match_operand:BLK 0 "memory_operand" "")
2489 (match_operand:BLK 1 "memory_operand" ""))
2490 (use (match_operand 2 "const_int_operand" ""))])
2491 (parallel
2492 [(set (match_operand:BLK 3 "memory_operand" "")
2493 (match_operand:BLK 4 "memory_operand" ""))
2494 (use (match_operand 5 "const_int_operand" ""))])]
2495 "s390_offset_p (operands[0], operands[3], operands[2])
2496 && s390_offset_p (operands[1], operands[4], operands[2])
2497 && !s390_overlap_p (operands[0], operands[1],
2498 INTVAL (operands[2]) + INTVAL (operands[5]))
2499 && INTVAL (operands[2]) + INTVAL (operands[5]) <= 256"
2500 [(parallel
2501 [(set (match_dup 6) (match_dup 7))
2502 (use (match_dup 8))])]
2503 "operands[6] = gen_rtx_MEM (BLKmode, XEXP (operands[0], 0));
2504 operands[7] = gen_rtx_MEM (BLKmode, XEXP (operands[1], 0));
2505 operands[8] = GEN_INT (INTVAL (operands[2]) + INTVAL (operands[5]));")
2506
2507
2508 ;
2509 ; load_multiple pattern(s).
2510 ;
2511 ; ??? Due to reload problems with replacing registers inside match_parallel
2512 ; we currently support load_multiple/store_multiple only after reload.
2513 ;
2514
2515 (define_expand "load_multiple"
2516 [(match_par_dup 3 [(set (match_operand 0 "" "")
2517 (match_operand 1 "" ""))
2518 (use (match_operand 2 "" ""))])]
2519 "reload_completed"
2520 {
2521 machine_mode mode;
2522 int regno;
2523 int count;
2524 rtx from;
2525 int i, off;
2526
2527 /* Support only loading a constant number of fixed-point registers from
2528 memory and only bother with this if more than two */
2529 if (GET_CODE (operands[2]) != CONST_INT
2530 || INTVAL (operands[2]) < 2
2531 || INTVAL (operands[2]) > 16
2532 || GET_CODE (operands[1]) != MEM
2533 || GET_CODE (operands[0]) != REG
2534 || REGNO (operands[0]) >= 16)
2535 FAIL;
2536
2537 count = INTVAL (operands[2]);
2538 regno = REGNO (operands[0]);
2539 mode = GET_MODE (operands[0]);
2540 if (mode != SImode && (!TARGET_ZARCH || mode != DImode))
2541 FAIL;
2542
2543 operands[3] = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (count));
2544 if (!can_create_pseudo_p ())
2545 {
2546 if (GET_CODE (XEXP (operands[1], 0)) == REG)
2547 {
2548 from = XEXP (operands[1], 0);
2549 off = 0;
2550 }
2551 else if (GET_CODE (XEXP (operands[1], 0)) == PLUS
2552 && GET_CODE (XEXP (XEXP (operands[1], 0), 0)) == REG
2553 && GET_CODE (XEXP (XEXP (operands[1], 0), 1)) == CONST_INT)
2554 {
2555 from = XEXP (XEXP (operands[1], 0), 0);
2556 off = INTVAL (XEXP (XEXP (operands[1], 0), 1));
2557 }
2558 else
2559 FAIL;
2560 }
2561 else
2562 {
2563 from = force_reg (Pmode, XEXP (operands[1], 0));
2564 off = 0;
2565 }
2566
2567 for (i = 0; i < count; i++)
2568 XVECEXP (operands[3], 0, i)
2569 = gen_rtx_SET (gen_rtx_REG (mode, regno + i),
2570 change_address (operands[1], mode,
2571 plus_constant (Pmode, from,
2572 off + i * GET_MODE_SIZE (mode))));
2573 })
2574
2575 (define_insn "*load_multiple_di"
2576 [(match_parallel 0 "load_multiple_operation"
2577 [(set (match_operand:DI 1 "register_operand" "=r")
2578 (match_operand:DI 2 "s_operand" "QS"))])]
2579 "reload_completed && TARGET_ZARCH"
2580 {
2581 int words = XVECLEN (operands[0], 0);
2582 operands[0] = gen_rtx_REG (DImode, REGNO (operands[1]) + words - 1);
2583 return "lmg\t%1,%0,%S2";
2584 }
2585 [(set_attr "op_type" "RSY")
2586 (set_attr "type" "lm")])
2587
2588 (define_insn "*load_multiple_si"
2589 [(match_parallel 0 "load_multiple_operation"
2590 [(set (match_operand:SI 1 "register_operand" "=r,r")
2591 (match_operand:SI 2 "s_operand" "Q,S"))])]
2592 "reload_completed"
2593 {
2594 int words = XVECLEN (operands[0], 0);
2595 operands[0] = gen_rtx_REG (SImode, REGNO (operands[1]) + words - 1);
2596 return which_alternative == 0 ? "lm\t%1,%0,%S2" : "lmy\t%1,%0,%S2";
2597 }
2598 [(set_attr "op_type" "RS,RSY")
2599 (set_attr "type" "lm")])
2600
2601 ;
2602 ; store multiple pattern(s).
2603 ;
2604
2605 (define_expand "store_multiple"
2606 [(match_par_dup 3 [(set (match_operand 0 "" "")
2607 (match_operand 1 "" ""))
2608 (use (match_operand 2 "" ""))])]
2609 "reload_completed"
2610 {
2611 machine_mode mode;
2612 int regno;
2613 int count;
2614 rtx to;
2615 int i, off;
2616
2617 /* Support only storing a constant number of fixed-point registers to
2618 memory and only bother with this if more than two. */
2619 if (GET_CODE (operands[2]) != CONST_INT
2620 || INTVAL (operands[2]) < 2
2621 || INTVAL (operands[2]) > 16
2622 || GET_CODE (operands[0]) != MEM
2623 || GET_CODE (operands[1]) != REG
2624 || REGNO (operands[1]) >= 16)
2625 FAIL;
2626
2627 count = INTVAL (operands[2]);
2628 regno = REGNO (operands[1]);
2629 mode = GET_MODE (operands[1]);
2630 if (mode != SImode && (!TARGET_ZARCH || mode != DImode))
2631 FAIL;
2632
2633 operands[3] = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (count));
2634
2635 if (!can_create_pseudo_p ())
2636 {
2637 if (GET_CODE (XEXP (operands[0], 0)) == REG)
2638 {
2639 to = XEXP (operands[0], 0);
2640 off = 0;
2641 }
2642 else if (GET_CODE (XEXP (operands[0], 0)) == PLUS
2643 && GET_CODE (XEXP (XEXP (operands[0], 0), 0)) == REG
2644 && GET_CODE (XEXP (XEXP (operands[0], 0), 1)) == CONST_INT)
2645 {
2646 to = XEXP (XEXP (operands[0], 0), 0);
2647 off = INTVAL (XEXP (XEXP (operands[0], 0), 1));
2648 }
2649 else
2650 FAIL;
2651 }
2652 else
2653 {
2654 to = force_reg (Pmode, XEXP (operands[0], 0));
2655 off = 0;
2656 }
2657
2658 for (i = 0; i < count; i++)
2659 XVECEXP (operands[3], 0, i)
2660 = gen_rtx_SET (change_address (operands[0], mode,
2661 plus_constant (Pmode, to,
2662 off + i * GET_MODE_SIZE (mode))),
2663 gen_rtx_REG (mode, regno + i));
2664 })
2665
2666 (define_insn "*store_multiple_di"
2667 [(match_parallel 0 "store_multiple_operation"
2668 [(set (match_operand:DI 1 "s_operand" "=QS")
2669 (match_operand:DI 2 "register_operand" "r"))])]
2670 "reload_completed && TARGET_ZARCH"
2671 {
2672 int words = XVECLEN (operands[0], 0);
2673 operands[0] = gen_rtx_REG (DImode, REGNO (operands[2]) + words - 1);
2674 return "stmg\t%2,%0,%S1";
2675 }
2676 [(set_attr "op_type" "RSY")
2677 (set_attr "type" "stm")])
2678
2679
2680 (define_insn "*store_multiple_si"
2681 [(match_parallel 0 "store_multiple_operation"
2682 [(set (match_operand:SI 1 "s_operand" "=Q,S")
2683 (match_operand:SI 2 "register_operand" "r,r"))])]
2684 "reload_completed"
2685 {
2686 int words = XVECLEN (operands[0], 0);
2687 operands[0] = gen_rtx_REG (SImode, REGNO (operands[2]) + words - 1);
2688 return which_alternative == 0 ? "stm\t%2,%0,%S1" : "stmy\t%2,%0,%S1";
2689 }
2690 [(set_attr "op_type" "RS,RSY")
2691 (set_attr "type" "stm")])
2692
2693 ;;
2694 ;; String instructions.
2695 ;;
2696
2697 (define_insn "*execute_rl"
2698 [(match_parallel 0 "execute_operation"
2699 [(unspec [(match_operand 1 "register_operand" "a")
2700 (match_operand 2 "" "")
2701 (match_operand:SI 3 "larl_operand" "X")] UNSPEC_EXECUTE)])]
2702 "TARGET_Z10 && GET_MODE_CLASS (GET_MODE (operands[1])) == MODE_INT
2703 && GET_MODE_SIZE (GET_MODE (operands[1])) <= UNITS_PER_WORD"
2704 "exrl\t%1,%3"
2705 [(set_attr "op_type" "RIL")
2706 (set_attr "type" "cs")])
2707
2708 (define_insn "*execute"
2709 [(match_parallel 0 "execute_operation"
2710 [(unspec [(match_operand 1 "register_operand" "a")
2711 (match_operand:BLK 2 "memory_operand" "R")
2712 (match_operand 3 "" "")] UNSPEC_EXECUTE)])]
2713 "GET_MODE_CLASS (GET_MODE (operands[1])) == MODE_INT
2714 && GET_MODE_SIZE (GET_MODE (operands[1])) <= UNITS_PER_WORD"
2715 "ex\t%1,%2"
2716 [(set_attr "op_type" "RX")
2717 (set_attr "type" "cs")])
2718
2719
2720 ;
2721 ; strlenM instruction pattern(s).
2722 ;
2723
2724 (define_expand "strlen<mode>"
2725 [(match_operand:P 0 "register_operand" "") ; result
2726 (match_operand:BLK 1 "memory_operand" "") ; input string
2727 (match_operand:SI 2 "immediate_operand" "") ; search character
2728 (match_operand:SI 3 "immediate_operand" "")] ; known alignment
2729 ""
2730 {
2731 if (!TARGET_VX || operands[2] != const0_rtx)
2732 emit_insn (gen_strlen_srst<mode> (operands[0], operands[1],
2733 operands[2], operands[3]));
2734 else
2735 s390_expand_vec_strlen (operands[0], operands[1], operands[3]);
2736
2737 DONE;
2738 })
2739
2740 (define_expand "strlen_srst<mode>"
2741 [(set (reg:SI 0) (match_operand:SI 2 "immediate_operand" ""))
2742 (parallel
2743 [(set (match_dup 4)
2744 (unspec:P [(const_int 0)
2745 (match_operand:BLK 1 "memory_operand" "")
2746 (reg:SI 0)
2747 (match_operand 3 "immediate_operand" "")] UNSPEC_SRST))
2748 (clobber (scratch:P))
2749 (clobber (reg:CC CC_REGNUM))])
2750 (parallel
2751 [(set (match_operand:P 0 "register_operand" "")
2752 (minus:P (match_dup 4) (match_dup 5)))
2753 (clobber (reg:CC CC_REGNUM))])]
2754 ""
2755 {
2756 operands[4] = gen_reg_rtx (Pmode);
2757 operands[5] = gen_reg_rtx (Pmode);
2758 emit_move_insn (operands[5], force_operand (XEXP (operands[1], 0), NULL_RTX));
2759 operands[1] = replace_equiv_address (operands[1], operands[5]);
2760 })
2761
2762 (define_insn "*strlen<mode>"
2763 [(set (match_operand:P 0 "register_operand" "=a")
2764 (unspec:P [(match_operand:P 2 "general_operand" "0")
2765 (mem:BLK (match_operand:P 3 "register_operand" "1"))
2766 (reg:SI 0)
2767 (match_operand 4 "immediate_operand" "")] UNSPEC_SRST))
2768 (clobber (match_scratch:P 1 "=a"))
2769 (clobber (reg:CC CC_REGNUM))]
2770 ""
2771 "srst\t%0,%1\;jo\t.-4"
2772 [(set_attr "length" "8")
2773 (set_attr "type" "vs")])
2774
2775 ;
2776 ; cmpstrM instruction pattern(s).
2777 ;
2778
2779 (define_expand "cmpstrsi"
2780 [(set (reg:SI 0) (const_int 0))
2781 (parallel
2782 [(clobber (match_operand 3 "" ""))
2783 (clobber (match_dup 4))
2784 (set (reg:CCU CC_REGNUM)
2785 (compare:CCU (match_operand:BLK 1 "memory_operand" "")
2786 (match_operand:BLK 2 "memory_operand" "")))
2787 (use (reg:SI 0))])
2788 (parallel
2789 [(set (match_operand:SI 0 "register_operand" "=d")
2790 (unspec:SI [(reg:CCU CC_REGNUM)] UNSPEC_STRCMPCC_TO_INT))
2791 (clobber (reg:CC CC_REGNUM))])]
2792 ""
2793 {
2794 /* As the result of CMPINT is inverted compared to what we need,
2795 we have to swap the operands. */
2796 rtx op1 = operands[2];
2797 rtx op2 = operands[1];
2798 rtx addr1 = gen_reg_rtx (Pmode);
2799 rtx addr2 = gen_reg_rtx (Pmode);
2800
2801 emit_move_insn (addr1, force_operand (XEXP (op1, 0), NULL_RTX));
2802 emit_move_insn (addr2, force_operand (XEXP (op2, 0), NULL_RTX));
2803 operands[1] = replace_equiv_address_nv (op1, addr1);
2804 operands[2] = replace_equiv_address_nv (op2, addr2);
2805 operands[3] = addr1;
2806 operands[4] = addr2;
2807 })
2808
2809 (define_insn "*cmpstr<mode>"
2810 [(clobber (match_operand:P 0 "register_operand" "=d"))
2811 (clobber (match_operand:P 1 "register_operand" "=d"))
2812 (set (reg:CCU CC_REGNUM)
2813 (compare:CCU (mem:BLK (match_operand:P 2 "register_operand" "0"))
2814 (mem:BLK (match_operand:P 3 "register_operand" "1"))))
2815 (use (reg:SI 0))]
2816 ""
2817 "clst\t%0,%1\;jo\t.-4"
2818 [(set_attr "length" "8")
2819 (set_attr "type" "vs")])
2820
2821 ;
2822 ; movstr instruction pattern.
2823 ;
2824
2825 (define_expand "movstr"
2826 [(set (reg:SI 0) (const_int 0))
2827 (parallel
2828 [(clobber (match_dup 3))
2829 (set (match_operand:BLK 1 "memory_operand" "")
2830 (match_operand:BLK 2 "memory_operand" ""))
2831 (set (match_operand 0 "register_operand" "")
2832 (unspec [(match_dup 1)
2833 (match_dup 2)
2834 (reg:SI 0)] UNSPEC_MVST))
2835 (clobber (reg:CC CC_REGNUM))])]
2836 ""
2837 {
2838 rtx addr1 = gen_reg_rtx (Pmode);
2839 rtx addr2 = gen_reg_rtx (Pmode);
2840
2841 emit_move_insn (addr1, force_operand (XEXP (operands[1], 0), NULL_RTX));
2842 emit_move_insn (addr2, force_operand (XEXP (operands[2], 0), NULL_RTX));
2843 operands[1] = replace_equiv_address_nv (operands[1], addr1);
2844 operands[2] = replace_equiv_address_nv (operands[2], addr2);
2845 operands[3] = addr2;
2846 })
2847
2848 (define_insn "*movstr"
2849 [(clobber (match_operand:P 2 "register_operand" "=d"))
2850 (set (mem:BLK (match_operand:P 1 "register_operand" "0"))
2851 (mem:BLK (match_operand:P 3 "register_operand" "2")))
2852 (set (match_operand:P 0 "register_operand" "=d")
2853 (unspec [(mem:BLK (match_dup 1))
2854 (mem:BLK (match_dup 3))
2855 (reg:SI 0)] UNSPEC_MVST))
2856 (clobber (reg:CC CC_REGNUM))]
2857 ""
2858 "mvst\t%1,%2\;jo\t.-4"
2859 [(set_attr "length" "8")
2860 (set_attr "type" "vs")])
2861
2862
2863 ;
2864 ; movmemM instruction pattern(s).
2865 ;
2866
2867 (define_expand "movmem<mode>"
2868 [(set (match_operand:BLK 0 "memory_operand" "") ; destination
2869 (match_operand:BLK 1 "memory_operand" "")) ; source
2870 (use (match_operand:GPR 2 "general_operand" "")) ; count
2871 (match_operand 3 "" "")]
2872 ""
2873 {
2874 if (s390_expand_movmem (operands[0], operands[1], operands[2]))
2875 DONE;
2876 else
2877 FAIL;
2878 })
2879
2880 ; Move a block that is up to 256 bytes in length.
2881 ; The block length is taken as (operands[2] % 256) + 1.
2882
2883 (define_expand "movmem_short"
2884 [(parallel
2885 [(set (match_operand:BLK 0 "memory_operand" "")
2886 (match_operand:BLK 1 "memory_operand" ""))
2887 (use (match_operand 2 "nonmemory_operand" ""))
2888 (use (const:BLK (unspec:BLK [(const_int 0)] UNSPEC_INSN)))
2889 (clobber (match_dup 3))])]
2890 ""
2891 "operands[3] = gen_rtx_SCRATCH (Pmode);")
2892
2893 (define_insn "*movmem_short"
2894 [(set (match_operand:BLK 0 "memory_operand" "=Q,Q,Q,Q")
2895 (match_operand:BLK 1 "memory_operand" "Q,Q,Q,Q"))
2896 (use (match_operand 2 "nonmemory_operand" "n,a,a,a"))
2897 (use (match_operand 3 "immediate_operand" "X,R,X,X"))
2898 (clobber (match_scratch:P 4 "=X,X,X,&a"))]
2899 "(GET_MODE (operands[2]) == Pmode || GET_MODE (operands[2]) == VOIDmode)"
2900 "#"
2901 [(set_attr "type" "cs")
2902 (set_attr "cpu_facility" "*,*,z10,cpu_zarch")])
2903
2904 (define_split
2905 [(set (match_operand:BLK 0 "memory_operand" "")
2906 (match_operand:BLK 1 "memory_operand" ""))
2907 (use (match_operand 2 "const_int_operand" ""))
2908 (use (match_operand 3 "immediate_operand" ""))
2909 (clobber (scratch))]
2910 "reload_completed"
2911 [(parallel
2912 [(set (match_dup 0) (match_dup 1))
2913 (use (match_dup 2))])]
2914 "operands[2] = GEN_INT ((INTVAL (operands[2]) & 0xff) + 1);")
2915
2916 (define_split
2917 [(set (match_operand:BLK 0 "memory_operand" "")
2918 (match_operand:BLK 1 "memory_operand" ""))
2919 (use (match_operand 2 "register_operand" ""))
2920 (use (match_operand 3 "memory_operand" ""))
2921 (clobber (scratch))]
2922 "reload_completed"
2923 [(parallel
2924 [(unspec [(match_dup 2) (match_dup 3)
2925 (const_int 0)] UNSPEC_EXECUTE)
2926 (set (match_dup 0) (match_dup 1))
2927 (use (const_int 1))])]
2928 "")
2929
2930 (define_split
2931 [(set (match_operand:BLK 0 "memory_operand" "")
2932 (match_operand:BLK 1 "memory_operand" ""))
2933 (use (match_operand 2 "register_operand" ""))
2934 (use (const:BLK (unspec:BLK [(const_int 0)] UNSPEC_INSN)))
2935 (clobber (scratch))]
2936 "TARGET_Z10 && reload_completed"
2937 [(parallel
2938 [(unspec [(match_dup 2) (const_int 0)
2939 (label_ref (match_dup 3))] UNSPEC_EXECUTE)
2940 (set (match_dup 0) (match_dup 1))
2941 (use (const_int 1))])]
2942 "operands[3] = gen_label_rtx ();")
2943
2944 (define_split
2945 [(set (match_operand:BLK 0 "memory_operand" "")
2946 (match_operand:BLK 1 "memory_operand" ""))
2947 (use (match_operand 2 "register_operand" ""))
2948 (use (const:BLK (unspec:BLK [(const_int 0)] UNSPEC_INSN)))
2949 (clobber (match_operand 3 "register_operand" ""))]
2950 "reload_completed && TARGET_CPU_ZARCH"
2951 [(set (match_dup 3) (label_ref (match_dup 4)))
2952 (parallel
2953 [(unspec [(match_dup 2) (mem:BLK (match_dup 3))
2954 (label_ref (match_dup 4))] UNSPEC_EXECUTE)
2955 (set (match_dup 0) (match_dup 1))
2956 (use (const_int 1))])]
2957 "operands[4] = gen_label_rtx ();")
2958
2959 ; Move a block of arbitrary length.
2960
2961 (define_expand "movmem_long"
2962 [(parallel
2963 [(clobber (match_dup 2))
2964 (clobber (match_dup 3))
2965 (set (match_operand:BLK 0 "memory_operand" "")
2966 (match_operand:BLK 1 "memory_operand" ""))
2967 (use (match_operand 2 "general_operand" ""))
2968 (use (match_dup 3))
2969 (clobber (reg:CC CC_REGNUM))])]
2970 ""
2971 {
2972 machine_mode sreg_mode = TARGET_ZARCH ? DImode : SImode;
2973 machine_mode dreg_mode = TARGET_ZARCH ? TImode : DImode;
2974 rtx reg0 = gen_reg_rtx (dreg_mode);
2975 rtx reg1 = gen_reg_rtx (dreg_mode);
2976 rtx addr0 = gen_lowpart (Pmode, gen_highpart (sreg_mode, reg0));
2977 rtx addr1 = gen_lowpart (Pmode, gen_highpart (sreg_mode, reg1));
2978 rtx len0 = gen_lowpart (Pmode, reg0);
2979 rtx len1 = gen_lowpart (Pmode, reg1);
2980
2981 emit_clobber (reg0);
2982 emit_move_insn (addr0, force_operand (XEXP (operands[0], 0), NULL_RTX));
2983 emit_move_insn (len0, operands[2]);
2984
2985 emit_clobber (reg1);
2986 emit_move_insn (addr1, force_operand (XEXP (operands[1], 0), NULL_RTX));
2987 emit_move_insn (len1, operands[2]);
2988
2989 operands[0] = replace_equiv_address_nv (operands[0], addr0);
2990 operands[1] = replace_equiv_address_nv (operands[1], addr1);
2991 operands[2] = reg0;
2992 operands[3] = reg1;
2993 })
2994
2995 (define_insn "*movmem_long"
2996 [(clobber (match_operand:<DBL> 0 "register_operand" "=d"))
2997 (clobber (match_operand:<DBL> 1 "register_operand" "=d"))
2998 (set (mem:BLK (subreg:P (match_operand:<DBL> 2 "register_operand" "0") 0))
2999 (mem:BLK (subreg:P (match_operand:<DBL> 3 "register_operand" "1") 0)))
3000 (use (match_dup 2))
3001 (use (match_dup 3))
3002 (clobber (reg:CC CC_REGNUM))]
3003 "TARGET_64BIT || !TARGET_ZARCH"
3004 "mvcle\t%0,%1,0\;jo\t.-4"
3005 [(set_attr "length" "8")
3006 (set_attr "type" "vs")])
3007
3008 (define_insn "*movmem_long_31z"
3009 [(clobber (match_operand:TI 0 "register_operand" "=d"))
3010 (clobber (match_operand:TI 1 "register_operand" "=d"))
3011 (set (mem:BLK (subreg:SI (match_operand:TI 2 "register_operand" "0") 4))
3012 (mem:BLK (subreg:SI (match_operand:TI 3 "register_operand" "1") 4)))
3013 (use (match_dup 2))
3014 (use (match_dup 3))
3015 (clobber (reg:CC CC_REGNUM))]
3016 "!TARGET_64BIT && TARGET_ZARCH"
3017 "mvcle\t%0,%1,0\;jo\t.-4"
3018 [(set_attr "length" "8")
3019 (set_attr "type" "vs")])
3020
3021
3022 ;
3023 ; Test data class.
3024 ;
3025
3026 (define_expand "signbit<mode>2"
3027 [(set (reg:CCZ CC_REGNUM)
3028 (unspec:CCZ [(match_operand:FP_ALL 1 "register_operand" "f")
3029 (match_dup 2)]
3030 UNSPEC_TDC_INSN))
3031 (set (match_operand:SI 0 "register_operand" "=d")
3032 (unspec:SI [(reg:CCZ CC_REGNUM)] UNSPEC_CC_TO_INT))]
3033 "TARGET_HARD_FLOAT"
3034 {
3035 operands[2] = GEN_INT (S390_TDC_SIGNBIT_SET);
3036 })
3037
3038 (define_expand "isinf<mode>2"
3039 [(set (reg:CCZ CC_REGNUM)
3040 (unspec:CCZ [(match_operand:FP_ALL 1 "register_operand" "f")
3041 (match_dup 2)]
3042 UNSPEC_TDC_INSN))
3043 (set (match_operand:SI 0 "register_operand" "=d")
3044 (unspec:SI [(reg:CCZ CC_REGNUM)] UNSPEC_CC_TO_INT))]
3045 "TARGET_HARD_FLOAT"
3046 {
3047 operands[2] = GEN_INT (S390_TDC_INFINITY);
3048 })
3049
3050 ; This extracts CC into a GPR properly shifted. The actual IPM
3051 ; instruction will be issued by reload. The constraint of operand 1
3052 ; forces reload to use a GPR. So reload will issue a movcc insn for
3053 ; copying CC into a GPR first.
3054 (define_insn_and_split "*cc_to_int"
3055 [(set (match_operand:SI 0 "nonimmediate_operand" "=d")
3056 (unspec:SI [(match_operand 1 "register_operand" "0")]
3057 UNSPEC_CC_TO_INT))]
3058 "operands != NULL"
3059 "#"
3060 "reload_completed"
3061 [(set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 28)))])
3062
3063 ; This insn is used to generate all variants of the Test Data Class
3064 ; instruction, namely tcxb, tcdb, and tceb. The insn's first operand
3065 ; is the register to be tested and the second one is the bit mask
3066 ; specifying the required test(s).
3067 ;
3068 ; tcxb, tcdb, tceb, tdcxt, tdcdt, tdcet
3069 (define_insn "*TDC_insn_<mode>"
3070 [(set (reg:CCZ CC_REGNUM)
3071 (unspec:CCZ [(match_operand:FP_ALL 0 "register_operand" "f")
3072 (match_operand:SI 1 "const_int_operand")] UNSPEC_TDC_INSN))]
3073 "TARGET_HARD_FLOAT"
3074 "t<_d>c<xde><bt>\t%0,%1"
3075 [(set_attr "op_type" "RXE")
3076 (set_attr "type" "fsimp<mode>")])
3077
3078
3079
3080 ;
3081 ; setmemM instruction pattern(s).
3082 ;
3083
3084 (define_expand "setmem<mode>"
3085 [(set (match_operand:BLK 0 "memory_operand" "")
3086 (match_operand:QI 2 "general_operand" ""))
3087 (use (match_operand:GPR 1 "general_operand" ""))
3088 (match_operand 3 "" "")]
3089 ""
3090 "s390_expand_setmem (operands[0], operands[1], operands[2]); DONE;")
3091
3092 ; Clear a block that is up to 256 bytes in length.
3093 ; The block length is taken as (operands[1] % 256) + 1.
3094
3095 (define_expand "clrmem_short"
3096 [(parallel
3097 [(set (match_operand:BLK 0 "memory_operand" "")
3098 (const_int 0))
3099 (use (match_operand 1 "nonmemory_operand" ""))
3100 (use (const:BLK (unspec:BLK [(const_int 0)] UNSPEC_INSN)))
3101 (clobber (match_dup 2))
3102 (clobber (reg:CC CC_REGNUM))])]
3103 ""
3104 "operands[2] = gen_rtx_SCRATCH (Pmode);")
3105
3106 (define_insn "*clrmem_short"
3107 [(set (match_operand:BLK 0 "memory_operand" "=Q,Q,Q,Q")
3108 (const_int 0))
3109 (use (match_operand 1 "nonmemory_operand" "n,a,a,a"))
3110 (use (match_operand 2 "immediate_operand" "X,R,X,X"))
3111 (clobber (match_scratch:P 3 "=X,X,X,&a"))
3112 (clobber (reg:CC CC_REGNUM))]
3113 "(GET_MODE (operands[1]) == Pmode || GET_MODE (operands[1]) == VOIDmode)"
3114 "#"
3115 [(set_attr "type" "cs")
3116 (set_attr "cpu_facility" "*,*,z10,cpu_zarch")])
3117
3118 (define_split
3119 [(set (match_operand:BLK 0 "memory_operand" "")
3120 (const_int 0))
3121 (use (match_operand 1 "const_int_operand" ""))
3122 (use (match_operand 2 "immediate_operand" ""))
3123 (clobber (scratch))
3124 (clobber (reg:CC CC_REGNUM))]
3125 "reload_completed"
3126 [(parallel
3127 [(set (match_dup 0) (const_int 0))
3128 (use (match_dup 1))
3129 (clobber (reg:CC CC_REGNUM))])]
3130 "operands[1] = GEN_INT ((INTVAL (operands[1]) & 0xff) + 1);")
3131
3132 (define_split
3133 [(set (match_operand:BLK 0 "memory_operand" "")
3134 (const_int 0))
3135 (use (match_operand 1 "register_operand" ""))
3136 (use (match_operand 2 "memory_operand" ""))
3137 (clobber (scratch))
3138 (clobber (reg:CC CC_REGNUM))]
3139 "reload_completed"
3140 [(parallel
3141 [(unspec [(match_dup 1) (match_dup 2)
3142 (const_int 0)] UNSPEC_EXECUTE)
3143 (set (match_dup 0) (const_int 0))
3144 (use (const_int 1))
3145 (clobber (reg:CC CC_REGNUM))])]
3146 "")
3147
3148 (define_split
3149 [(set (match_operand:BLK 0 "memory_operand" "")
3150 (const_int 0))
3151 (use (match_operand 1 "register_operand" ""))
3152 (use (const:BLK (unspec:BLK [(const_int 0)] UNSPEC_INSN)))
3153 (clobber (scratch))
3154 (clobber (reg:CC CC_REGNUM))]
3155 "TARGET_Z10 && reload_completed"
3156 [(parallel
3157 [(unspec [(match_dup 1) (const_int 0)
3158 (label_ref (match_dup 3))] UNSPEC_EXECUTE)
3159 (set (match_dup 0) (const_int 0))
3160 (use (const_int 1))
3161 (clobber (reg:CC CC_REGNUM))])]
3162 "operands[3] = gen_label_rtx ();")
3163
3164 (define_split
3165 [(set (match_operand:BLK 0 "memory_operand" "")
3166 (const_int 0))
3167 (use (match_operand 1 "register_operand" ""))
3168 (use (const:BLK (unspec:BLK [(const_int 0)] UNSPEC_INSN)))
3169 (clobber (match_operand 2 "register_operand" ""))
3170 (clobber (reg:CC CC_REGNUM))]
3171 "reload_completed && TARGET_CPU_ZARCH"
3172 [(set (match_dup 2) (label_ref (match_dup 3)))
3173 (parallel
3174 [(unspec [(match_dup 1) (mem:BLK (match_dup 2))
3175 (label_ref (match_dup 3))] UNSPEC_EXECUTE)
3176 (set (match_dup 0) (const_int 0))
3177 (use (const_int 1))
3178 (clobber (reg:CC CC_REGNUM))])]
3179 "operands[3] = gen_label_rtx ();")
3180
3181 ; Initialize a block of arbitrary length with (operands[2] % 256).
3182
3183 (define_expand "setmem_long"
3184 [(parallel
3185 [(clobber (match_dup 1))
3186 (set (match_operand:BLK 0 "memory_operand" "")
3187 (match_operand 2 "shift_count_or_setmem_operand" ""))
3188 (use (match_operand 1 "general_operand" ""))
3189 (use (match_dup 3))
3190 (clobber (reg:CC CC_REGNUM))])]
3191 ""
3192 {
3193 machine_mode sreg_mode = TARGET_ZARCH ? DImode : SImode;
3194 machine_mode dreg_mode = TARGET_ZARCH ? TImode : DImode;
3195 rtx reg0 = gen_reg_rtx (dreg_mode);
3196 rtx reg1 = gen_reg_rtx (dreg_mode);
3197 rtx addr0 = gen_lowpart (Pmode, gen_highpart (sreg_mode, reg0));
3198 rtx len0 = gen_lowpart (Pmode, reg0);
3199
3200 emit_clobber (reg0);
3201 emit_move_insn (addr0, force_operand (XEXP (operands[0], 0), NULL_RTX));
3202 emit_move_insn (len0, operands[1]);
3203
3204 emit_move_insn (reg1, const0_rtx);
3205
3206 operands[0] = replace_equiv_address_nv (operands[0], addr0);
3207 operands[1] = reg0;
3208 operands[3] = reg1;
3209 })
3210
3211 (define_insn "*setmem_long"
3212 [(clobber (match_operand:<DBL> 0 "register_operand" "=d"))
3213 (set (mem:BLK (subreg:P (match_operand:<DBL> 3 "register_operand" "0") 0))
3214 (match_operand 2 "shift_count_or_setmem_operand" "Y"))
3215 (use (match_dup 3))
3216 (use (match_operand:<DBL> 1 "register_operand" "d"))
3217 (clobber (reg:CC CC_REGNUM))]
3218 "TARGET_64BIT || !TARGET_ZARCH"
3219 "mvcle\t%0,%1,%Y2\;jo\t.-4"
3220 [(set_attr "length" "8")
3221 (set_attr "type" "vs")])
3222
3223 (define_insn "*setmem_long_and"
3224 [(clobber (match_operand:<DBL> 0 "register_operand" "=d"))
3225 (set (mem:BLK (subreg:P (match_operand:<DBL> 3 "register_operand" "0") 0))
3226 (and (match_operand 2 "shift_count_or_setmem_operand" "Y")
3227 (match_operand 4 "const_int_operand" "n")))
3228 (use (match_dup 3))
3229 (use (match_operand:<DBL> 1 "register_operand" "d"))
3230 (clobber (reg:CC CC_REGNUM))]
3231 "(TARGET_64BIT || !TARGET_ZARCH) &&
3232 (INTVAL (operands[4]) & 255) == 255"
3233 "mvcle\t%0,%1,%Y2\;jo\t.-4"
3234 [(set_attr "length" "8")
3235 (set_attr "type" "vs")])
3236
3237 (define_insn "*setmem_long_31z"
3238 [(clobber (match_operand:TI 0 "register_operand" "=d"))
3239 (set (mem:BLK (subreg:SI (match_operand:TI 3 "register_operand" "0") 4))
3240 (match_operand 2 "shift_count_or_setmem_operand" "Y"))
3241 (use (match_dup 3))
3242 (use (match_operand:TI 1 "register_operand" "d"))
3243 (clobber (reg:CC CC_REGNUM))]
3244 "!TARGET_64BIT && TARGET_ZARCH"
3245 "mvcle\t%0,%1,%Y2\;jo\t.-4"
3246 [(set_attr "length" "8")
3247 (set_attr "type" "vs")])
3248
3249 ;
3250 ; cmpmemM instruction pattern(s).
3251 ;
3252
3253 (define_expand "cmpmemsi"
3254 [(set (match_operand:SI 0 "register_operand" "")
3255 (compare:SI (match_operand:BLK 1 "memory_operand" "")
3256 (match_operand:BLK 2 "memory_operand" "") ) )
3257 (use (match_operand:SI 3 "general_operand" ""))
3258 (use (match_operand:SI 4 "" ""))]
3259 ""
3260 {
3261 if (s390_expand_cmpmem (operands[0], operands[1],
3262 operands[2], operands[3]))
3263 DONE;
3264 else
3265 FAIL;
3266 })
3267
3268 ; Compare a block that is up to 256 bytes in length.
3269 ; The block length is taken as (operands[2] % 256) + 1.
3270
3271 (define_expand "cmpmem_short"
3272 [(parallel
3273 [(set (reg:CCU CC_REGNUM)
3274 (compare:CCU (match_operand:BLK 0 "memory_operand" "")
3275 (match_operand:BLK 1 "memory_operand" "")))
3276 (use (match_operand 2 "nonmemory_operand" ""))
3277 (use (const:BLK (unspec:BLK [(const_int 0)] UNSPEC_INSN)))
3278 (clobber (match_dup 3))])]
3279 ""
3280 "operands[3] = gen_rtx_SCRATCH (Pmode);")
3281
3282 (define_insn "*cmpmem_short"
3283 [(set (reg:CCU CC_REGNUM)
3284 (compare:CCU (match_operand:BLK 0 "memory_operand" "Q,Q,Q,Q")
3285 (match_operand:BLK 1 "memory_operand" "Q,Q,Q,Q")))
3286 (use (match_operand 2 "nonmemory_operand" "n,a,a,a"))
3287 (use (match_operand 3 "immediate_operand" "X,R,X,X"))
3288 (clobber (match_scratch:P 4 "=X,X,X,&a"))]
3289 "(GET_MODE (operands[2]) == Pmode || GET_MODE (operands[2]) == VOIDmode)"
3290 "#"
3291 [(set_attr "type" "cs")
3292 (set_attr "cpu_facility" "*,*,z10,cpu_zarch")])
3293
3294 (define_split
3295 [(set (reg:CCU CC_REGNUM)
3296 (compare:CCU (match_operand:BLK 0 "memory_operand" "")
3297 (match_operand:BLK 1 "memory_operand" "")))
3298 (use (match_operand 2 "const_int_operand" ""))
3299 (use (match_operand 3 "immediate_operand" ""))
3300 (clobber (scratch))]
3301 "reload_completed"
3302 [(parallel
3303 [(set (reg:CCU CC_REGNUM) (compare:CCU (match_dup 0) (match_dup 1)))
3304 (use (match_dup 2))])]
3305 "operands[2] = GEN_INT ((INTVAL (operands[2]) & 0xff) + 1);")
3306
3307 (define_split
3308 [(set (reg:CCU CC_REGNUM)
3309 (compare:CCU (match_operand:BLK 0 "memory_operand" "")
3310 (match_operand:BLK 1 "memory_operand" "")))
3311 (use (match_operand 2 "register_operand" ""))
3312 (use (match_operand 3 "memory_operand" ""))
3313 (clobber (scratch))]
3314 "reload_completed"
3315 [(parallel
3316 [(unspec [(match_dup 2) (match_dup 3)
3317 (const_int 0)] UNSPEC_EXECUTE)
3318 (set (reg:CCU CC_REGNUM) (compare:CCU (match_dup 0) (match_dup 1)))
3319 (use (const_int 1))])]
3320 "")
3321
3322 (define_split
3323 [(set (reg:CCU CC_REGNUM)
3324 (compare:CCU (match_operand:BLK 0 "memory_operand" "")
3325 (match_operand:BLK 1 "memory_operand" "")))
3326 (use (match_operand 2 "register_operand" ""))
3327 (use (const:BLK (unspec:BLK [(const_int 0)] UNSPEC_INSN)))
3328 (clobber (scratch))]
3329 "TARGET_Z10 && reload_completed"
3330 [(parallel
3331 [(unspec [(match_dup 2) (const_int 0)
3332 (label_ref (match_dup 4))] UNSPEC_EXECUTE)
3333 (set (reg:CCU CC_REGNUM) (compare:CCU (match_dup 0) (match_dup 1)))
3334 (use (const_int 1))])]
3335 "operands[4] = gen_label_rtx ();")
3336
3337 (define_split
3338 [(set (reg:CCU CC_REGNUM)
3339 (compare:CCU (match_operand:BLK 0 "memory_operand" "")
3340 (match_operand:BLK 1 "memory_operand" "")))
3341 (use (match_operand 2 "register_operand" ""))
3342 (use (const:BLK (unspec:BLK [(const_int 0)] UNSPEC_INSN)))
3343 (clobber (match_operand 3 "register_operand" ""))]
3344 "reload_completed && TARGET_CPU_ZARCH"
3345 [(set (match_dup 3) (label_ref (match_dup 4)))
3346 (parallel
3347 [(unspec [(match_dup 2) (mem:BLK (match_dup 3))
3348 (label_ref (match_dup 4))] UNSPEC_EXECUTE)
3349 (set (reg:CCU CC_REGNUM) (compare:CCU (match_dup 0) (match_dup 1)))
3350 (use (const_int 1))])]
3351 "operands[4] = gen_label_rtx ();")
3352
3353 ; Compare a block of arbitrary length.
3354
3355 (define_expand "cmpmem_long"
3356 [(parallel
3357 [(clobber (match_dup 2))
3358 (clobber (match_dup 3))
3359 (set (reg:CCU CC_REGNUM)
3360 (compare:CCU (match_operand:BLK 0 "memory_operand" "")
3361 (match_operand:BLK 1 "memory_operand" "")))
3362 (use (match_operand 2 "general_operand" ""))
3363 (use (match_dup 3))])]
3364 ""
3365 {
3366 machine_mode sreg_mode = TARGET_ZARCH ? DImode : SImode;
3367 machine_mode dreg_mode = TARGET_ZARCH ? TImode : DImode;
3368 rtx reg0 = gen_reg_rtx (dreg_mode);
3369 rtx reg1 = gen_reg_rtx (dreg_mode);
3370 rtx addr0 = gen_lowpart (Pmode, gen_highpart (sreg_mode, reg0));
3371 rtx addr1 = gen_lowpart (Pmode, gen_highpart (sreg_mode, reg1));
3372 rtx len0 = gen_lowpart (Pmode, reg0);
3373 rtx len1 = gen_lowpart (Pmode, reg1);
3374
3375 emit_clobber (reg0);
3376 emit_move_insn (addr0, force_operand (XEXP (operands[0], 0), NULL_RTX));
3377 emit_move_insn (len0, operands[2]);
3378
3379 emit_clobber (reg1);
3380 emit_move_insn (addr1, force_operand (XEXP (operands[1], 0), NULL_RTX));
3381 emit_move_insn (len1, operands[2]);
3382
3383 operands[0] = replace_equiv_address_nv (operands[0], addr0);
3384 operands[1] = replace_equiv_address_nv (operands[1], addr1);
3385 operands[2] = reg0;
3386 operands[3] = reg1;
3387 })
3388
3389 (define_insn "*cmpmem_long"
3390 [(clobber (match_operand:<DBL> 0 "register_operand" "=d"))
3391 (clobber (match_operand:<DBL> 1 "register_operand" "=d"))
3392 (set (reg:CCU CC_REGNUM)
3393 (compare:CCU (mem:BLK (subreg:P (match_operand:<DBL> 2 "register_operand" "0") 0))
3394 (mem:BLK (subreg:P (match_operand:<DBL> 3 "register_operand" "1") 0))))
3395 (use (match_dup 2))
3396 (use (match_dup 3))]
3397 "TARGET_64BIT || !TARGET_ZARCH"
3398 "clcle\t%0,%1,0\;jo\t.-4"
3399 [(set_attr "length" "8")
3400 (set_attr "type" "vs")])
3401
3402 (define_insn "*cmpmem_long_31z"
3403 [(clobber (match_operand:TI 0 "register_operand" "=d"))
3404 (clobber (match_operand:TI 1 "register_operand" "=d"))
3405 (set (reg:CCU CC_REGNUM)
3406 (compare:CCU (mem:BLK (subreg:SI (match_operand:TI 2 "register_operand" "0") 4))
3407 (mem:BLK (subreg:SI (match_operand:TI 3 "register_operand" "1") 4))))
3408 (use (match_dup 2))
3409 (use (match_dup 3))]
3410 "!TARGET_64BIT && TARGET_ZARCH"
3411 "clcle\t%0,%1,0\;jo\t.-4"
3412 [(set_attr "op_type" "NN")
3413 (set_attr "type" "vs")
3414 (set_attr "length" "8")])
3415
3416 ; Convert CCUmode condition code to integer.
3417 ; Result is zero if EQ, positive if LTU, negative if GTU.
3418
3419 (define_insn_and_split "cmpint"
3420 [(set (match_operand:SI 0 "register_operand" "=d")
3421 (unspec:SI [(match_operand:CCU 1 "register_operand" "0")]
3422 UNSPEC_STRCMPCC_TO_INT))
3423 (clobber (reg:CC CC_REGNUM))]
3424 ""
3425 "#"
3426 "reload_completed"
3427 [(set (match_dup 0) (ashift:SI (match_dup 0) (const_int 2)))
3428 (parallel
3429 [(set (match_dup 0) (ashiftrt:SI (match_dup 0) (const_int 30)))
3430 (clobber (reg:CC CC_REGNUM))])])
3431
3432 (define_insn_and_split "*cmpint_cc"
3433 [(set (reg CC_REGNUM)
3434 (compare (unspec:SI [(match_operand:CCU 1 "register_operand" "0")]
3435 UNSPEC_STRCMPCC_TO_INT)
3436 (const_int 0)))
3437 (set (match_operand:SI 0 "register_operand" "=d")
3438 (unspec:SI [(match_dup 1)] UNSPEC_STRCMPCC_TO_INT))]
3439 "s390_match_ccmode (insn, CCSmode)"
3440 "#"
3441 "&& reload_completed"
3442 [(set (match_dup 0) (ashift:SI (match_dup 0) (const_int 2)))
3443 (parallel
3444 [(set (match_dup 2) (match_dup 3))
3445 (set (match_dup 0) (ashiftrt:SI (match_dup 0) (const_int 30)))])]
3446 {
3447 rtx result = gen_rtx_ASHIFTRT (SImode, operands[0], GEN_INT (30));
3448 operands[2] = SET_DEST (XVECEXP (PATTERN (curr_insn), 0, 0));
3449 operands[3] = gen_rtx_COMPARE (GET_MODE (operands[2]), result, const0_rtx);
3450 })
3451
3452 (define_insn_and_split "*cmpint_sign"
3453 [(set (match_operand:DI 0 "register_operand" "=d")
3454 (sign_extend:DI (unspec:SI [(match_operand:CCU 1 "register_operand" "0")]
3455 UNSPEC_STRCMPCC_TO_INT)))
3456 (clobber (reg:CC CC_REGNUM))]
3457 "TARGET_ZARCH"
3458 "#"
3459 "&& reload_completed"
3460 [(set (match_dup 0) (ashift:DI (match_dup 0) (const_int 34)))
3461 (parallel
3462 [(set (match_dup 0) (ashiftrt:DI (match_dup 0) (const_int 62)))
3463 (clobber (reg:CC CC_REGNUM))])])
3464
3465 (define_insn_and_split "*cmpint_sign_cc"
3466 [(set (reg CC_REGNUM)
3467 (compare (ashiftrt:DI (ashift:DI (subreg:DI
3468 (unspec:SI [(match_operand:CCU 1 "register_operand" "0")]
3469 UNSPEC_STRCMPCC_TO_INT) 0)
3470 (const_int 32)) (const_int 32))
3471 (const_int 0)))
3472 (set (match_operand:DI 0 "register_operand" "=d")
3473 (sign_extend:DI (unspec:SI [(match_dup 1)] UNSPEC_STRCMPCC_TO_INT)))]
3474 "s390_match_ccmode (insn, CCSmode) && TARGET_ZARCH"
3475 "#"
3476 "&& reload_completed"
3477 [(set (match_dup 0) (ashift:DI (match_dup 0) (const_int 34)))
3478 (parallel
3479 [(set (match_dup 2) (match_dup 3))
3480 (set (match_dup 0) (ashiftrt:DI (match_dup 0) (const_int 62)))])]
3481 {
3482 rtx result = gen_rtx_ASHIFTRT (DImode, operands[0], GEN_INT (62));
3483 operands[2] = SET_DEST (XVECEXP (PATTERN (curr_insn), 0, 0));
3484 operands[3] = gen_rtx_COMPARE (GET_MODE (operands[2]), result, const0_rtx);
3485 })
3486
3487
3488 ;;
3489 ;;- Conversion instructions.
3490 ;;
3491
3492 (define_insn "*sethighpartsi"
3493 [(set (match_operand:SI 0 "register_operand" "=d,d")
3494 (unspec:SI [(match_operand:BLK 1 "s_operand" "Q,S")
3495 (match_operand 2 "const_int_operand" "n,n")] UNSPEC_ICM))
3496 (clobber (reg:CC CC_REGNUM))]
3497 ""
3498 "@
3499 icm\t%0,%2,%S1
3500 icmy\t%0,%2,%S1"
3501 [(set_attr "op_type" "RS,RSY")
3502 (set_attr "z10prop" "z10_super_E1,z10_super_E1")])
3503
3504 (define_insn "*sethighpartdi_64"
3505 [(set (match_operand:DI 0 "register_operand" "=d")
3506 (unspec:DI [(match_operand:BLK 1 "s_operand" "QS")
3507 (match_operand 2 "const_int_operand" "n")] UNSPEC_ICM))
3508 (clobber (reg:CC CC_REGNUM))]
3509 "TARGET_ZARCH"
3510 "icmh\t%0,%2,%S1"
3511 [(set_attr "op_type" "RSY")
3512 (set_attr "z10prop" "z10_super")])
3513
3514 (define_insn "*sethighpartdi_31"
3515 [(set (match_operand:DI 0 "register_operand" "=d,d")
3516 (unspec:DI [(match_operand:BLK 1 "s_operand" "Q,S")
3517 (match_operand 2 "const_int_operand" "n,n")] UNSPEC_ICM))
3518 (clobber (reg:CC CC_REGNUM))]
3519 "!TARGET_ZARCH"
3520 "@
3521 icm\t%0,%2,%S1
3522 icmy\t%0,%2,%S1"
3523 [(set_attr "op_type" "RS,RSY")
3524 (set_attr "z10prop" "z10_super_E1,z10_super_E1")])
3525
3526 ;
3527 ; extv instruction patterns
3528 ;
3529
3530 ; FIXME: This expander needs to be converted from DI to GPR as well
3531 ; after resolving some issues with it.
3532
3533 (define_expand "extzv"
3534 [(parallel
3535 [(set (match_operand:DI 0 "register_operand" "=d")
3536 (zero_extract:DI
3537 (match_operand:DI 1 "register_operand" "d")
3538 (match_operand 2 "const_int_operand" "") ; size
3539 (match_operand 3 "const_int_operand" ""))) ; start
3540 (clobber (reg:CC CC_REGNUM))])]
3541 "TARGET_Z10"
3542 {
3543 /* Starting with zEC12 there is risbgn not clobbering CC. */
3544 if (TARGET_ZEC12)
3545 {
3546 emit_move_insn (operands[0],
3547 gen_rtx_ZERO_EXTRACT (DImode,
3548 operands[1],
3549 operands[2],
3550 operands[3]));
3551 DONE;
3552 }
3553 })
3554
3555 (define_insn "*extzv<mode>_zEC12"
3556 [(set (match_operand:GPR 0 "register_operand" "=d")
3557 (zero_extract:GPR
3558 (match_operand:GPR 1 "register_operand" "d")
3559 (match_operand 2 "const_int_operand" "") ; size
3560 (match_operand 3 "const_int_operand" "")))] ; start]
3561 "TARGET_ZEC12"
3562 "risbgn\t%0,%1,64-%2,128+63,<bitsize>+%3+%2" ; dst, src, start, end, shift
3563 [(set_attr "op_type" "RIE")])
3564
3565 (define_insn "*extzv<mode>_z10"
3566 [(set (match_operand:GPR 0 "register_operand" "=d")
3567 (zero_extract:GPR
3568 (match_operand:GPR 1 "register_operand" "d")
3569 (match_operand 2 "const_int_operand" "") ; size
3570 (match_operand 3 "const_int_operand" ""))) ; start
3571 (clobber (reg:CC CC_REGNUM))]
3572 "TARGET_Z10"
3573 "risbg\t%0,%1,64-%2,128+63,<bitsize>+%3+%2" ; dst, src, start, end, shift
3574 [(set_attr "op_type" "RIE")
3575 (set_attr "z10prop" "z10_super_E1")])
3576
3577 (define_insn_and_split "*pre_z10_extzv<mode>"
3578 [(set (match_operand:GPR 0 "register_operand" "=d")
3579 (zero_extract:GPR (match_operand:QI 1 "s_operand" "QS")
3580 (match_operand 2 "nonzero_shift_count_operand" "")
3581 (const_int 0)))
3582 (clobber (reg:CC CC_REGNUM))]
3583 "!TARGET_Z10"
3584 "#"
3585 "&& reload_completed"
3586 [(parallel
3587 [(set (match_dup 0) (unspec:GPR [(match_dup 1) (match_dup 3)] UNSPEC_ICM))
3588 (clobber (reg:CC CC_REGNUM))])
3589 (set (match_dup 0) (lshiftrt:GPR (match_dup 0) (match_dup 2)))]
3590 {
3591 int bitsize = INTVAL (operands[2]);
3592 int size = (bitsize - 1) / BITS_PER_UNIT + 1; /* round up */
3593 int mask = ((1ul << size) - 1) << (GET_MODE_SIZE (SImode) - size);
3594
3595 operands[1] = adjust_address (operands[1], BLKmode, 0);
3596 set_mem_size (operands[1], size);
3597 operands[2] = GEN_INT (<GPR:bitsize> - bitsize);
3598 operands[3] = GEN_INT (mask);
3599 })
3600
3601 (define_insn_and_split "*pre_z10_extv<mode>"
3602 [(set (match_operand:GPR 0 "register_operand" "=d")
3603 (sign_extract:GPR (match_operand:QI 1 "s_operand" "QS")
3604 (match_operand 2 "nonzero_shift_count_operand" "")
3605 (const_int 0)))
3606 (clobber (reg:CC CC_REGNUM))]
3607 ""
3608 "#"
3609 "&& reload_completed"
3610 [(parallel
3611 [(set (match_dup 0) (unspec:GPR [(match_dup 1) (match_dup 3)] UNSPEC_ICM))
3612 (clobber (reg:CC CC_REGNUM))])
3613 (parallel
3614 [(set (match_dup 0) (ashiftrt:GPR (match_dup 0) (match_dup 2)))
3615 (clobber (reg:CC CC_REGNUM))])]
3616 {
3617 int bitsize = INTVAL (operands[2]);
3618 int size = (bitsize - 1) / BITS_PER_UNIT + 1; /* round up */
3619 int mask = ((1ul << size) - 1) << (GET_MODE_SIZE (SImode) - size);
3620
3621 operands[1] = adjust_address (operands[1], BLKmode, 0);
3622 set_mem_size (operands[1], size);
3623 operands[2] = GEN_INT (<GPR:bitsize> - bitsize);
3624 operands[3] = GEN_INT (mask);
3625 })
3626
3627 ;
3628 ; insv instruction patterns
3629 ;
3630
3631 (define_expand "insv"
3632 [(set (zero_extract (match_operand 0 "nonimmediate_operand" "")
3633 (match_operand 1 "const_int_operand" "")
3634 (match_operand 2 "const_int_operand" ""))
3635 (match_operand 3 "general_operand" ""))]
3636 ""
3637 {
3638 if (s390_expand_insv (operands[0], operands[1], operands[2], operands[3]))
3639 DONE;
3640 FAIL;
3641 })
3642
3643
3644 ; The normal RTL expansion will never generate a zero_extract where
3645 ; the location operand isn't word mode. However, we do this in the
3646 ; back-end when generating atomic operations. See s390_two_part_insv.
3647 (define_insn "*insv<mode>_zEC12"
3648 [(set (zero_extract:GPR (match_operand:GPR 0 "nonimmediate_operand" "+d")
3649 (match_operand 1 "const_int_operand" "I") ; size
3650 (match_operand 2 "const_int_operand" "I")) ; pos
3651 (match_operand:GPR 3 "nonimmediate_operand" "d"))]
3652 "TARGET_ZEC12
3653 && (INTVAL (operands[1]) + INTVAL (operands[2])) <= <bitsize>"
3654 "risbgn\t%0,%3,64-<bitsize>+%2,64-<bitsize>+%2+%1-1,<bitsize>-%2-%1"
3655 [(set_attr "op_type" "RIE")])
3656
3657 (define_insn "*insv<mode>_z10"
3658 [(set (zero_extract:GPR (match_operand:GPR 0 "nonimmediate_operand" "+d")
3659 (match_operand 1 "const_int_operand" "I") ; size
3660 (match_operand 2 "const_int_operand" "I")) ; pos
3661 (match_operand:GPR 3 "nonimmediate_operand" "d"))
3662 (clobber (reg:CC CC_REGNUM))]
3663 "TARGET_Z10
3664 && (INTVAL (operands[1]) + INTVAL (operands[2])) <= <bitsize>"
3665 "risbg\t%0,%3,64-<bitsize>+%2,64-<bitsize>+%2+%1-1,<bitsize>-%2-%1"
3666 [(set_attr "op_type" "RIE")
3667 (set_attr "z10prop" "z10_super_E1")])
3668
3669 ; and op1 with a mask being 1 for the selected bits and 0 for the rest
3670 ; and op3=op0 with a mask being 0 for the selected bits and 1 for the rest
3671 (define_insn "*insv<mode>_zEC12_noshift"
3672 [(set (match_operand:GPR 0 "nonimmediate_operand" "=d")
3673 (ior:GPR (and:GPR (match_operand:GPR 1 "nonimmediate_operand" "d")
3674 (match_operand:GPR 2 "contiguous_bitmask_operand" ""))
3675 (and:GPR (match_operand:GPR 3 "nonimmediate_operand" "0")
3676 (match_operand:GPR 4 "const_int_operand" ""))))]
3677 "TARGET_ZEC12 && INTVAL (operands[2]) == ~INTVAL (operands[4])"
3678 "risbgn\t%0,%1,%<bfstart>2,%<bfend>2,0"
3679 [(set_attr "op_type" "RIE")])
3680
3681 (define_insn "*insv<mode>_z10_noshift"
3682 [(set (match_operand:GPR 0 "nonimmediate_operand" "=d")
3683 (ior:GPR (and:GPR (match_operand:GPR 1 "nonimmediate_operand" "d")
3684 (match_operand:GPR 2 "contiguous_bitmask_operand" ""))
3685 (and:GPR (match_operand:GPR 3 "nonimmediate_operand" "0")
3686 (match_operand:GPR 4 "const_int_operand" ""))))
3687 (clobber (reg:CC CC_REGNUM))]
3688 "TARGET_Z10 && INTVAL (operands[2]) == ~INTVAL (operands[4])"
3689 "risbg\t%0,%1,%<bfstart>2,%<bfend>2,0"
3690 [(set_attr "op_type" "RIE")
3691 (set_attr "z10prop" "z10_super_E1")])
3692
3693 (define_insn "*r<noxa>sbg_<mode>_noshift"
3694 [(set (match_operand:GPR 0 "nonimmediate_operand" "=d")
3695 (IXOR:GPR
3696 (and:GPR (match_operand:GPR 1 "nonimmediate_operand" "d")
3697 (match_operand:GPR 2 "contiguous_bitmask_operand" ""))
3698 (match_operand:GPR 3 "nonimmediate_operand" "0")))
3699 (clobber (reg:CC CC_REGNUM))]
3700 "TARGET_Z10"
3701 "r<noxa>sbg\t%0,%1,%<bfstart>2,%<bfend>2,0"
3702 [(set_attr "op_type" "RIE")])
3703
3704 (define_insn "*r<noxa>sbg_di_rotl"
3705 [(set (match_operand:DI 0 "nonimmediate_operand" "=d")
3706 (IXOR:DI
3707 (and:DI
3708 (rotate:DI
3709 (match_operand:DI 1 "nonimmediate_operand" "d")
3710 (match_operand:DI 3 "const_int_operand" ""))
3711 (match_operand:DI 2 "contiguous_bitmask_operand" ""))
3712 (match_operand:DI 4 "nonimmediate_operand" "0")))
3713 (clobber (reg:CC CC_REGNUM))]
3714 "TARGET_Z10"
3715 "r<noxa>sbg\t%0,%1,%<bfstart>2,%<bfend>2,%b3"
3716 [(set_attr "op_type" "RIE")])
3717
3718 (define_insn "*r<noxa>sbg_<mode>_srl"
3719 [(set (match_operand:GPR 0 "nonimmediate_operand" "=d")
3720 (IXOR:GPR
3721 (and:GPR
3722 (lshiftrt:GPR
3723 (match_operand:GPR 1 "nonimmediate_operand" "d")
3724 (match_operand:GPR 3 "nonzero_shift_count_operand" ""))
3725 (match_operand:GPR 2 "contiguous_bitmask_operand" ""))
3726 (match_operand:GPR 4 "nonimmediate_operand" "0")))
3727 (clobber (reg:CC CC_REGNUM))]
3728 "TARGET_Z10
3729 && s390_extzv_shift_ok (<bitsize>, 64 - INTVAL (operands[3]),
3730 INTVAL (operands[2]))"
3731 "r<noxa>sbg\t%0,%1,%<bfstart>2,%<bfend>2,64-%3"
3732 [(set_attr "op_type" "RIE")])
3733
3734 (define_insn "*r<noxa>sbg_<mode>_sll"
3735 [(set (match_operand:GPR 0 "nonimmediate_operand" "=d")
3736 (IXOR:GPR
3737 (and:GPR
3738 (ashift:GPR
3739 (match_operand:GPR 1 "nonimmediate_operand" "d")
3740 (match_operand:GPR 3 "nonzero_shift_count_operand" ""))
3741 (match_operand:GPR 2 "contiguous_bitmask_operand" ""))
3742 (match_operand:GPR 4 "nonimmediate_operand" "0")))
3743 (clobber (reg:CC CC_REGNUM))]
3744 "TARGET_Z10
3745 && s390_extzv_shift_ok (<bitsize>, INTVAL (operands[3]),
3746 INTVAL (operands[2]))"
3747 "r<noxa>sbg\t%0,%1,%<bfstart>2,%<bfend>2,%3"
3748 [(set_attr "op_type" "RIE")])
3749
3750 ;; These two are generated by combine for s.bf &= val.
3751 ;; ??? For bitfields smaller than 32-bits, we wind up with SImode
3752 ;; shifts and ands, which results in some truly awful patterns
3753 ;; including subregs of operations. Rather unnecessisarily, IMO.
3754 ;; Instead of
3755 ;;
3756 ;; (set (zero_extract:DI (reg/v:DI 50 [ s ])
3757 ;; (const_int 24 [0x18])
3758 ;; (const_int 0 [0]))
3759 ;; (subreg:DI (and:SI (subreg:SI (lshiftrt:DI (reg/v:DI 50 [ s ])
3760 ;; (const_int 40 [0x28])) 4)
3761 ;; (reg:SI 4 %r4 [ y+4 ])) 0))
3762 ;;
3763 ;; we should instead generate
3764 ;;
3765 ;; (set (zero_extract:DI (reg/v:DI 50 [ s ])
3766 ;; (const_int 24 [0x18])
3767 ;; (const_int 0 [0]))
3768 ;; (and:DI (lshiftrt:DI (reg/v:DI 50 [ s ])
3769 ;; (const_int 40 [0x28]))
3770 ;; (subreg:DI (reg:SI 4 %r4 [ y+4 ]) 0)))
3771 ;;
3772 ;; by noticing that we can push down the outer paradoxical subreg
3773 ;; into the operation.
3774
3775 (define_insn "*insv_rnsbg_noshift"
3776 [(set (zero_extract:DI
3777 (match_operand:DI 0 "nonimmediate_operand" "+d")
3778 (match_operand 1 "const_int_operand" "")
3779 (match_operand 2 "const_int_operand" ""))
3780 (and:DI
3781 (match_dup 0)
3782 (match_operand:DI 3 "nonimmediate_operand" "d")))
3783 (clobber (reg:CC CC_REGNUM))]
3784 "TARGET_Z10
3785 && INTVAL (operands[1]) + INTVAL (operands[2]) == 64"
3786 "rnsbg\t%0,%3,%2,63,0"
3787 [(set_attr "op_type" "RIE")])
3788
3789 (define_insn "*insv_rnsbg_srl"
3790 [(set (zero_extract:DI
3791 (match_operand:DI 0 "nonimmediate_operand" "+d")
3792 (match_operand 1 "const_int_operand" "")
3793 (match_operand 2 "const_int_operand" ""))
3794 (and:DI
3795 (lshiftrt:DI
3796 (match_dup 0)
3797 (match_operand 3 "const_int_operand" ""))
3798 (match_operand:DI 4 "nonimmediate_operand" "d")))
3799 (clobber (reg:CC CC_REGNUM))]
3800 "TARGET_Z10
3801 && INTVAL (operands[3]) == 64 - INTVAL (operands[1]) - INTVAL (operands[2])"
3802 "rnsbg\t%0,%4,%2,%2+%1-1,%3"
3803 [(set_attr "op_type" "RIE")])
3804
3805 (define_insn "*insv<mode>_mem_reg"
3806 [(set (zero_extract:W (match_operand:QI 0 "memory_operand" "+Q,S")
3807 (match_operand 1 "const_int_operand" "n,n")
3808 (const_int 0))
3809 (match_operand:W 2 "register_operand" "d,d"))]
3810 "INTVAL (operands[1]) > 0
3811 && INTVAL (operands[1]) <= GET_MODE_BITSIZE (SImode)
3812 && INTVAL (operands[1]) % BITS_PER_UNIT == 0"
3813 {
3814 int size = INTVAL (operands[1]) / BITS_PER_UNIT;
3815
3816 operands[1] = GEN_INT ((1ul << size) - 1);
3817 return (which_alternative == 0) ? "stcm\t%2,%1,%S0"
3818 : "stcmy\t%2,%1,%S0";
3819 }
3820 [(set_attr "op_type" "RS,RSY")
3821 (set_attr "z10prop" "z10_super,z10_super")])
3822
3823 (define_insn "*insvdi_mem_reghigh"
3824 [(set (zero_extract:DI (match_operand:QI 0 "memory_operand" "+QS")
3825 (match_operand 1 "const_int_operand" "n")
3826 (const_int 0))
3827 (lshiftrt:DI (match_operand:DI 2 "register_operand" "d")
3828 (const_int 32)))]
3829 "TARGET_ZARCH
3830 && INTVAL (operands[1]) > 0
3831 && INTVAL (operands[1]) <= GET_MODE_BITSIZE (SImode)
3832 && INTVAL (operands[1]) % BITS_PER_UNIT == 0"
3833 {
3834 int size = INTVAL (operands[1]) / BITS_PER_UNIT;
3835
3836 operands[1] = GEN_INT ((1ul << size) - 1);
3837 return "stcmh\t%2,%1,%S0";
3838 }
3839 [(set_attr "op_type" "RSY")
3840 (set_attr "z10prop" "z10_super")])
3841
3842 (define_insn "*insvdi_reg_imm"
3843 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+d")
3844 (const_int 16)
3845 (match_operand 1 "const_int_operand" "n"))
3846 (match_operand:DI 2 "const_int_operand" "n"))]
3847 "TARGET_ZARCH
3848 && INTVAL (operands[1]) >= 0
3849 && INTVAL (operands[1]) < BITS_PER_WORD
3850 && INTVAL (operands[1]) % 16 == 0"
3851 {
3852 switch (BITS_PER_WORD - INTVAL (operands[1]))
3853 {
3854 case 64: return "iihh\t%0,%x2"; break;
3855 case 48: return "iihl\t%0,%x2"; break;
3856 case 32: return "iilh\t%0,%x2"; break;
3857 case 16: return "iill\t%0,%x2"; break;
3858 default: gcc_unreachable();
3859 }
3860 }
3861 [(set_attr "op_type" "RI")
3862 (set_attr "z10prop" "z10_super_E1")])
3863
3864 ; Update the left-most 32 bit of a DI.
3865 (define_insn "*insv_h_di_reg_extimm"
3866 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+d")
3867 (const_int 32)
3868 (const_int 0))
3869 (match_operand:DI 1 "const_int_operand" "n"))]
3870 "TARGET_EXTIMM"
3871 "iihf\t%0,%o1"
3872 [(set_attr "op_type" "RIL")
3873 (set_attr "z10prop" "z10_fwd_E1")])
3874
3875 ; Update the right-most 32 bit of a DI.
3876 (define_insn "*insv_l_di_reg_extimm"
3877 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+d")
3878 (const_int 32)
3879 (const_int 32))
3880 (match_operand:DI 1 "const_int_operand" "n"))]
3881 "TARGET_EXTIMM"
3882 "iilf\t%0,%o1"
3883 [(set_attr "op_type" "RIL")
3884 (set_attr "z10prop" "z10_fwd_A1")])
3885
3886 ;
3887 ; extendsidi2 instruction pattern(s).
3888 ;
3889
3890 (define_expand "extendsidi2"
3891 [(set (match_operand:DI 0 "register_operand" "")
3892 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "")))]
3893 ""
3894 {
3895 if (!TARGET_ZARCH)
3896 {
3897 emit_clobber (operands[0]);
3898 emit_move_insn (gen_highpart (SImode, operands[0]), operands[1]);
3899 emit_move_insn (gen_lowpart (SImode, operands[0]), const0_rtx);
3900 emit_insn (gen_ashrdi3 (operands[0], operands[0], GEN_INT (32)));
3901 DONE;
3902 }
3903 })
3904
3905 (define_insn "*extendsidi2"
3906 [(set (match_operand:DI 0 "register_operand" "=d,d,d")
3907 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "d,RT,b")))]
3908 "TARGET_ZARCH"
3909 "@
3910 lgfr\t%0,%1
3911 lgf\t%0,%1
3912 lgfrl\t%0,%1"
3913 [(set_attr "op_type" "RRE,RXY,RIL")
3914 (set_attr "type" "*,*,larl")
3915 (set_attr "cpu_facility" "*,*,z10")
3916 (set_attr "z10prop" "z10_super_E1,z10_super_E1,z10_super_E1")])
3917
3918 ;
3919 ; extend(hi|qi)(si|di)2 instruction pattern(s).
3920 ;
3921
3922 (define_expand "extend<HQI:mode><DSI:mode>2"
3923 [(set (match_operand:DSI 0 "register_operand" "")
3924 (sign_extend:DSI (match_operand:HQI 1 "nonimmediate_operand" "")))]
3925 ""
3926 {
3927 if (<DSI:MODE>mode == DImode && !TARGET_ZARCH)
3928 {
3929 rtx tmp = gen_reg_rtx (SImode);
3930 emit_insn (gen_extend<HQI:mode>si2 (tmp, operands[1]));
3931 emit_insn (gen_extendsidi2 (operands[0], tmp));
3932 DONE;
3933 }
3934 else if (!TARGET_EXTIMM)
3935 {
3936 rtx bitcount = GEN_INT (<DSI:bitsize> - <HQI:bitsize>);
3937
3938 operands[1] = gen_lowpart (<DSI:MODE>mode, operands[1]);
3939 emit_insn (gen_ashl<DSI:mode>3 (operands[0], operands[1], bitcount));
3940 emit_insn (gen_ashr<DSI:mode>3 (operands[0], operands[0], bitcount));
3941 DONE;
3942 }
3943 })
3944
3945 ;
3946 ; extendhidi2 instruction pattern(s).
3947 ;
3948
3949 (define_insn "*extendhidi2_extimm"
3950 [(set (match_operand:DI 0 "register_operand" "=d,d,d")
3951 (sign_extend:DI (match_operand:HI 1 "general_operand" "d,RT,b")))]
3952 "TARGET_ZARCH && TARGET_EXTIMM"
3953 "@
3954 lghr\t%0,%1
3955 lgh\t%0,%1
3956 lghrl\t%0,%1"
3957 [(set_attr "op_type" "RRE,RXY,RIL")
3958 (set_attr "type" "*,*,larl")
3959 (set_attr "cpu_facility" "extimm,extimm,z10")
3960 (set_attr "z10prop" "z10_super_E1,z10_super_E1,z10_super_E1")])
3961
3962 (define_insn "*extendhidi2"
3963 [(set (match_operand:DI 0 "register_operand" "=d")
3964 (sign_extend:DI (match_operand:HI 1 "memory_operand" "RT")))]
3965 "TARGET_ZARCH"
3966 "lgh\t%0,%1"
3967 [(set_attr "op_type" "RXY")
3968 (set_attr "z10prop" "z10_super_E1")])
3969
3970 ;
3971 ; extendhisi2 instruction pattern(s).
3972 ;
3973
3974 (define_insn "*extendhisi2_extimm"
3975 [(set (match_operand:SI 0 "register_operand" "=d,d,d,d")
3976 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" " d,R,T,b")))]
3977 "TARGET_EXTIMM"
3978 "@
3979 lhr\t%0,%1
3980 lh\t%0,%1
3981 lhy\t%0,%1
3982 lhrl\t%0,%1"
3983 [(set_attr "op_type" "RRE,RX,RXY,RIL")
3984 (set_attr "type" "*,*,*,larl")
3985 (set_attr "cpu_facility" "extimm,extimm,extimm,z10")
3986 (set_attr "z10prop" "z10_super_E1,z10_super_E1,z10_super_E1,z10_super_E1")])
3987
3988 (define_insn "*extendhisi2"
3989 [(set (match_operand:SI 0 "register_operand" "=d,d")
3990 (sign_extend:SI (match_operand:HI 1 "memory_operand" "R,T")))]
3991 "!TARGET_EXTIMM"
3992 "@
3993 lh\t%0,%1
3994 lhy\t%0,%1"
3995 [(set_attr "op_type" "RX,RXY")
3996 (set_attr "z10prop" "z10_super_E1,z10_super_E1")])
3997
3998 ;
3999 ; extendqi(si|di)2 instruction pattern(s).
4000 ;
4001
4002 ; lbr, lgbr, lb, lgb
4003 (define_insn "*extendqi<mode>2_extimm"
4004 [(set (match_operand:GPR 0 "register_operand" "=d,d")
4005 (sign_extend:GPR (match_operand:QI 1 "nonimmediate_operand" "d,RT")))]
4006 "TARGET_EXTIMM"
4007 "@
4008 l<g>br\t%0,%1
4009 l<g>b\t%0,%1"
4010 [(set_attr "op_type" "RRE,RXY")
4011 (set_attr "z10prop" "z10_super_E1,z10_super_E1")])
4012
4013 ; lb, lgb
4014 (define_insn "*extendqi<mode>2"
4015 [(set (match_operand:GPR 0 "register_operand" "=d")
4016 (sign_extend:GPR (match_operand:QI 1 "memory_operand" "RT")))]
4017 "!TARGET_EXTIMM && TARGET_LONG_DISPLACEMENT"
4018 "l<g>b\t%0,%1"
4019 [(set_attr "op_type" "RXY")
4020 (set_attr "z10prop" "z10_super_E1")])
4021
4022 (define_insn_and_split "*extendqi<mode>2_short_displ"
4023 [(set (match_operand:GPR 0 "register_operand" "=d")
4024 (sign_extend:GPR (match_operand:QI 1 "s_operand" "Q")))
4025 (clobber (reg:CC CC_REGNUM))]
4026 "!TARGET_EXTIMM && !TARGET_LONG_DISPLACEMENT"
4027 "#"
4028 "&& reload_completed"
4029 [(parallel
4030 [(set (match_dup 0) (unspec:GPR [(match_dup 1) (const_int 8)] UNSPEC_ICM))
4031 (clobber (reg:CC CC_REGNUM))])
4032 (parallel
4033 [(set (match_dup 0) (ashiftrt:GPR (match_dup 0) (match_dup 2)))
4034 (clobber (reg:CC CC_REGNUM))])]
4035 {
4036 operands[1] = adjust_address (operands[1], BLKmode, 0);
4037 set_mem_size (operands[1], GET_MODE_SIZE (QImode));
4038 operands[2] = GEN_INT (<GPR:bitsize> - BITS_PER_UNIT);
4039 })
4040
4041 ;
4042 ; zero_extendsidi2 instruction pattern(s).
4043 ;
4044
4045 (define_expand "zero_extendsidi2"
4046 [(set (match_operand:DI 0 "register_operand" "")
4047 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "")))]
4048 ""
4049 {
4050 if (!TARGET_ZARCH)
4051 {
4052 emit_clobber (operands[0]);
4053 emit_move_insn (gen_lowpart (SImode, operands[0]), operands[1]);
4054 emit_move_insn (gen_highpart (SImode, operands[0]), const0_rtx);
4055 DONE;
4056 }
4057 })
4058
4059 (define_insn "*zero_extendsidi2"
4060 [(set (match_operand:DI 0 "register_operand" "=d,d,d")
4061 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "d,RT,b")))]
4062 "TARGET_ZARCH"
4063 "@
4064 llgfr\t%0,%1
4065 llgf\t%0,%1
4066 llgfrl\t%0,%1"
4067 [(set_attr "op_type" "RRE,RXY,RIL")
4068 (set_attr "type" "*,*,larl")
4069 (set_attr "cpu_facility" "*,*,z10")
4070 (set_attr "z10prop" "z10_fwd_E1,z10_fwd_A3,z10_fwd_A3")])
4071
4072 ;
4073 ; LLGT-type instructions (zero-extend from 31 bit to 64 bit).
4074 ;
4075
4076 (define_insn "*llgt_sidi"
4077 [(set (match_operand:DI 0 "register_operand" "=d")
4078 (and:DI (subreg:DI (match_operand:SI 1 "memory_operand" "RT") 0)
4079 (const_int 2147483647)))]
4080 "TARGET_ZARCH"
4081 "llgt\t%0,%1"
4082 [(set_attr "op_type" "RXE")
4083 (set_attr "z10prop" "z10_super_E1")])
4084
4085 (define_insn_and_split "*llgt_sidi_split"
4086 [(set (match_operand:DI 0 "register_operand" "=d")
4087 (and:DI (subreg:DI (match_operand:SI 1 "memory_operand" "RT") 0)
4088 (const_int 2147483647)))
4089 (clobber (reg:CC CC_REGNUM))]
4090 "TARGET_ZARCH"
4091 "#"
4092 "&& reload_completed"
4093 [(set (match_dup 0)
4094 (and:DI (subreg:DI (match_dup 1) 0)
4095 (const_int 2147483647)))]
4096 "")
4097
4098 (define_insn "*llgt_sisi"
4099 [(set (match_operand:SI 0 "register_operand" "=d,d")
4100 (and:SI (match_operand:SI 1 "nonimmediate_operand" "d,RT")
4101 (const_int 2147483647)))]
4102 "TARGET_ZARCH"
4103 "@
4104 llgtr\t%0,%1
4105 llgt\t%0,%1"
4106 [(set_attr "op_type" "RRE,RXE")
4107 (set_attr "z10prop" "z10_super_E1,z10_super_E1")])
4108
4109 (define_insn "*llgt_didi"
4110 [(set (match_operand:DI 0 "register_operand" "=d,d")
4111 (and:DI (match_operand:DI 1 "nonimmediate_operand" "d,o")
4112 (const_int 2147483647)))]
4113 "TARGET_ZARCH"
4114 "@
4115 llgtr\t%0,%1
4116 llgt\t%0,%N1"
4117 [(set_attr "op_type" "RRE,RXE")
4118 (set_attr "z10prop" "z10_super_E1,z10_super_E1")])
4119
4120 (define_split
4121 [(set (match_operand:DSI 0 "register_operand" "")
4122 (and:DSI (match_operand:DSI 1 "nonimmediate_operand" "")
4123 (const_int 2147483647)))
4124 (clobber (reg:CC CC_REGNUM))]
4125 "TARGET_ZARCH && reload_completed"
4126 [(set (match_dup 0)
4127 (and:DSI (match_dup 1)
4128 (const_int 2147483647)))]
4129 "")
4130
4131 ;
4132 ; zero_extend(hi|qi)(si|di)2 instruction pattern(s).
4133 ;
4134
4135 (define_expand "zero_extend<mode>di2"
4136 [(set (match_operand:DI 0 "register_operand" "")
4137 (zero_extend:DI (match_operand:HQI 1 "nonimmediate_operand" "")))]
4138 ""
4139 {
4140 if (!TARGET_ZARCH)
4141 {
4142 rtx tmp = gen_reg_rtx (SImode);
4143 emit_insn (gen_zero_extend<mode>si2 (tmp, operands[1]));
4144 emit_insn (gen_zero_extendsidi2 (operands[0], tmp));
4145 DONE;
4146 }
4147 else if (!TARGET_EXTIMM)
4148 {
4149 rtx bitcount = GEN_INT (64 - <HQI:bitsize>);
4150 operands[1] = gen_lowpart (DImode, operands[1]);
4151 emit_insn (gen_ashldi3 (operands[0], operands[1], bitcount));
4152 emit_insn (gen_lshrdi3 (operands[0], operands[0], bitcount));
4153 DONE;
4154 }
4155 })
4156
4157 (define_expand "zero_extend<mode>si2"
4158 [(set (match_operand:SI 0 "register_operand" "")
4159 (zero_extend:SI (match_operand:HQI 1 "nonimmediate_operand" "")))]
4160 ""
4161 {
4162 if (!TARGET_EXTIMM)
4163 {
4164 operands[1] = gen_lowpart (SImode, operands[1]);
4165 emit_insn (gen_andsi3 (operands[0], operands[1],
4166 GEN_INT ((1 << <HQI:bitsize>) - 1)));
4167 DONE;
4168 }
4169 })
4170
4171 ; llhrl, llghrl
4172 (define_insn "*zero_extendhi<mode>2_z10"
4173 [(set (match_operand:GPR 0 "register_operand" "=d,d,d")
4174 (zero_extend:GPR (match_operand:HI 1 "nonimmediate_operand" "d,RT,b")))]
4175 "TARGET_Z10"
4176 "@
4177 ll<g>hr\t%0,%1
4178 ll<g>h\t%0,%1
4179 ll<g>hrl\t%0,%1"
4180 [(set_attr "op_type" "RXY,RRE,RIL")
4181 (set_attr "type" "*,*,larl")
4182 (set_attr "cpu_facility" "*,*,z10")
4183 (set_attr "z10prop" "z10_super_E1,z10_fwd_A3,z10_fwd_A3")])
4184
4185 ; llhr, llcr, llghr, llgcr, llh, llc, llgh, llgc
4186 (define_insn "*zero_extend<HQI:mode><GPR:mode>2_extimm"
4187 [(set (match_operand:GPR 0 "register_operand" "=d,d")
4188 (zero_extend:GPR (match_operand:HQI 1 "nonimmediate_operand" "d,RT")))]
4189 "TARGET_EXTIMM"
4190 "@
4191 ll<g><hc>r\t%0,%1
4192 ll<g><hc>\t%0,%1"
4193 [(set_attr "op_type" "RRE,RXY")
4194 (set_attr "z10prop" "z10_super_E1,z10_fwd_A3")])
4195
4196 ; llgh, llgc
4197 (define_insn "*zero_extend<HQI:mode><GPR:mode>2"
4198 [(set (match_operand:GPR 0 "register_operand" "=d")
4199 (zero_extend:GPR (match_operand:HQI 1 "memory_operand" "RT")))]
4200 "TARGET_ZARCH && !TARGET_EXTIMM"
4201 "llg<hc>\t%0,%1"
4202 [(set_attr "op_type" "RXY")
4203 (set_attr "z10prop" "z10_fwd_A3")])
4204
4205 (define_insn_and_split "*zero_extendhisi2_31"
4206 [(set (match_operand:SI 0 "register_operand" "=&d")
4207 (zero_extend:SI (match_operand:HI 1 "s_operand" "QS")))
4208 (clobber (reg:CC CC_REGNUM))]
4209 "!TARGET_ZARCH"
4210 "#"
4211 "&& reload_completed"
4212 [(set (match_dup 0) (const_int 0))
4213 (parallel
4214 [(set (strict_low_part (match_dup 2)) (match_dup 1))
4215 (clobber (reg:CC CC_REGNUM))])]
4216 "operands[2] = gen_lowpart (HImode, operands[0]);")
4217
4218 (define_insn_and_split "*zero_extendqisi2_31"
4219 [(set (match_operand:SI 0 "register_operand" "=&d")
4220 (zero_extend:SI (match_operand:QI 1 "memory_operand" "RT")))]
4221 "!TARGET_ZARCH"
4222 "#"
4223 "&& reload_completed"
4224 [(set (match_dup 0) (const_int 0))
4225 (set (strict_low_part (match_dup 2)) (match_dup 1))]
4226 "operands[2] = gen_lowpart (QImode, operands[0]);")
4227
4228 ;
4229 ; zero_extendqihi2 instruction pattern(s).
4230 ;
4231
4232 (define_expand "zero_extendqihi2"
4233 [(set (match_operand:HI 0 "register_operand" "")
4234 (zero_extend:HI (match_operand:QI 1 "register_operand" "")))]
4235 "TARGET_ZARCH && !TARGET_EXTIMM"
4236 {
4237 operands[1] = gen_lowpart (HImode, operands[1]);
4238 emit_insn (gen_andhi3 (operands[0], operands[1], GEN_INT (0xff)));
4239 DONE;
4240 })
4241
4242 (define_insn "*zero_extendqihi2_64"
4243 [(set (match_operand:HI 0 "register_operand" "=d")
4244 (zero_extend:HI (match_operand:QI 1 "memory_operand" "RT")))]
4245 "TARGET_ZARCH && !TARGET_EXTIMM"
4246 "llgc\t%0,%1"
4247 [(set_attr "op_type" "RXY")
4248 (set_attr "z10prop" "z10_fwd_A3")])
4249
4250 (define_insn_and_split "*zero_extendqihi2_31"
4251 [(set (match_operand:HI 0 "register_operand" "=&d")
4252 (zero_extend:HI (match_operand:QI 1 "memory_operand" "RT")))]
4253 "!TARGET_ZARCH"
4254 "#"
4255 "&& reload_completed"
4256 [(set (match_dup 0) (const_int 0))
4257 (set (strict_low_part (match_dup 2)) (match_dup 1))]
4258 "operands[2] = gen_lowpart (QImode, operands[0]);")
4259
4260 ;
4261 ; fixuns_trunc(dd|td)di2 instruction pattern(s).
4262 ;
4263
4264 (define_expand "fixuns_truncdddi2"
4265 [(parallel
4266 [(set (match_operand:DI 0 "register_operand" "")
4267 (unsigned_fix:DI (match_operand:DD 1 "register_operand" "")))
4268 (unspec:DI [(const_int 5)] UNSPEC_ROUND)
4269 (clobber (reg:CC CC_REGNUM))])]
4270
4271 "TARGET_HARD_DFP"
4272 {
4273 if (!TARGET_Z196)
4274 {
4275 rtx_code_label *label1 = gen_label_rtx ();
4276 rtx_code_label *label2 = gen_label_rtx ();
4277 rtx temp = gen_reg_rtx (TDmode);
4278 REAL_VALUE_TYPE cmp, sub;
4279
4280 decimal_real_from_string (&cmp, "9223372036854775808.0"); /* 2^63 */
4281 decimal_real_from_string (&sub, "18446744073709551616.0"); /* 2^64 */
4282
4283 /* 2^63 can't be represented as 64bit DFP number with full precision. The
4284 solution is doing the check and the subtraction in TD mode and using a
4285 TD -> DI convert afterwards. */
4286 emit_insn (gen_extendddtd2 (temp, operands[1]));
4287 temp = force_reg (TDmode, temp);
4288 emit_cmp_and_jump_insns (temp,
4289 CONST_DOUBLE_FROM_REAL_VALUE (cmp, TDmode),
4290 LT, NULL_RTX, VOIDmode, 0, label1);
4291 emit_insn (gen_subtd3 (temp, temp,
4292 CONST_DOUBLE_FROM_REAL_VALUE (sub, TDmode)));
4293 emit_insn (gen_fix_trunctddi2_dfp (operands[0], temp, GEN_INT (11)));
4294 emit_jump (label2);
4295
4296 emit_label (label1);
4297 emit_insn (gen_fix_truncdddi2_dfp (operands[0], operands[1], GEN_INT (9)));
4298 emit_label (label2);
4299 DONE;
4300 }
4301 })
4302
4303 (define_expand "fixuns_trunctddi2"
4304 [(parallel
4305 [(set (match_operand:DI 0 "register_operand" "")
4306 (unsigned_fix:DI (match_operand:TD 1 "register_operand" "")))
4307 (unspec:DI [(const_int 5)] UNSPEC_ROUND)
4308 (clobber (reg:CC CC_REGNUM))])]
4309
4310 "TARGET_HARD_DFP"
4311 {
4312 if (!TARGET_Z196)
4313 {
4314 rtx_code_label *label1 = gen_label_rtx ();
4315 rtx_code_label *label2 = gen_label_rtx ();
4316 rtx temp = gen_reg_rtx (TDmode);
4317 REAL_VALUE_TYPE cmp, sub;
4318
4319 operands[1] = force_reg (TDmode, operands[1]);
4320 decimal_real_from_string (&cmp, "9223372036854775808.0"); /* 2^63 */
4321 decimal_real_from_string (&sub, "18446744073709551616.0"); /* 2^64 */
4322
4323 emit_cmp_and_jump_insns (operands[1],
4324 CONST_DOUBLE_FROM_REAL_VALUE (cmp, TDmode),
4325 LT, NULL_RTX, VOIDmode, 0, label1);
4326 emit_insn (gen_subtd3 (temp, operands[1],
4327 CONST_DOUBLE_FROM_REAL_VALUE (sub, TDmode)));
4328 emit_insn (gen_fix_trunctddi2_dfp (operands[0], temp, GEN_INT (11)));
4329 emit_jump (label2);
4330
4331 emit_label (label1);
4332 emit_insn (gen_fix_trunctddi2_dfp (operands[0], operands[1], GEN_INT (9)));
4333 emit_label (label2);
4334 DONE;
4335 }
4336 })
4337
4338 ;
4339 ; fixuns_trunc(sf|df|tf)(si|di)2 and fix_trunc(sf|df|tf)(si|di)2
4340 ; instruction pattern(s).
4341 ;
4342
4343 (define_expand "fixuns_trunc<BFP:mode><GPR:mode>2"
4344 [(parallel
4345 [(set (match_operand:GPR 0 "register_operand" "")
4346 (unsigned_fix:GPR (match_operand:BFP 1 "register_operand" "")))
4347 (unspec:GPR [(const_int 5)] UNSPEC_ROUND)
4348 (clobber (reg:CC CC_REGNUM))])]
4349 "TARGET_HARD_FLOAT"
4350 {
4351 if (!TARGET_Z196)
4352 {
4353 rtx_code_label *label1 = gen_label_rtx ();
4354 rtx_code_label *label2 = gen_label_rtx ();
4355 rtx temp = gen_reg_rtx (<BFP:MODE>mode);
4356 REAL_VALUE_TYPE cmp, sub;
4357
4358 operands[1] = force_reg (<BFP:MODE>mode, operands[1]);
4359 real_2expN (&cmp, <GPR:bitsize> - 1, <BFP:MODE>mode);
4360 real_2expN (&sub, <GPR:bitsize>, <BFP:MODE>mode);
4361
4362 emit_cmp_and_jump_insns (operands[1],
4363 CONST_DOUBLE_FROM_REAL_VALUE (cmp, <BFP:MODE>mode),
4364 LT, NULL_RTX, VOIDmode, 0, label1);
4365 emit_insn (gen_sub<BFP:mode>3 (temp, operands[1],
4366 CONST_DOUBLE_FROM_REAL_VALUE (sub, <BFP:MODE>mode)));
4367 emit_insn (gen_fix_trunc<BFP:mode><GPR:mode>2_bfp (operands[0], temp,
4368 GEN_INT (7)));
4369 emit_jump (label2);
4370
4371 emit_label (label1);
4372 emit_insn (gen_fix_trunc<BFP:mode><GPR:mode>2_bfp (operands[0],
4373 operands[1], GEN_INT (5)));
4374 emit_label (label2);
4375 DONE;
4376 }
4377 })
4378
4379 ; fixuns_trunc(td|dd)si2 expander
4380 (define_expand "fixuns_trunc<mode>si2"
4381 [(parallel
4382 [(set (match_operand:SI 0 "register_operand" "")
4383 (unsigned_fix:SI (match_operand:DFP 1 "register_operand" "")))
4384 (unspec:SI [(const_int 5)] UNSPEC_ROUND)
4385 (clobber (reg:CC CC_REGNUM))])]
4386 "TARGET_Z196 && TARGET_HARD_DFP"
4387 "")
4388
4389 ; fixuns_trunc(tf|df|sf|td|dd)(di|si)2 instruction patterns.
4390
4391 (define_insn "*fixuns_truncdfdi2_z13"
4392 [(set (match_operand:DI 0 "register_operand" "=d,v")
4393 (unsigned_fix:DI (match_operand:DF 1 "register_operand" "f,v")))
4394 (unspec:DI [(match_operand:DI 2 "immediate_operand" "K,K")] UNSPEC_ROUND)
4395 (clobber (reg:CC CC_REGNUM))]
4396 "TARGET_Z13 && TARGET_HARD_FLOAT"
4397 "@
4398 clgdbr\t%0,%h2,%1,0
4399 wclgdb\t%v0,%v1,0,%h2"
4400 [(set_attr "op_type" "RRF,VRR")
4401 (set_attr "type" "ftoi")])
4402
4403 ; clfebr, clfdbr, clfxbr, clgebr, clgdbr, clgxbr
4404 ; clfdtr, clfxtr, clgdtr, clgxtr
4405 (define_insn "*fixuns_trunc<FP:mode><GPR:mode>2_z196"
4406 [(set (match_operand:GPR 0 "register_operand" "=d")
4407 (unsigned_fix:GPR (match_operand:FP 1 "register_operand" "f")))
4408 (unspec:GPR [(match_operand:GPR 2 "immediate_operand" "K")] UNSPEC_ROUND)
4409 (clobber (reg:CC CC_REGNUM))]
4410 "TARGET_Z196 && TARGET_HARD_FLOAT
4411 && (!TARGET_Z13 || <GPR:MODE>mode != DImode || <FP:MODE>mode != DFmode)"
4412 "cl<GPR:gf><FP:xde><FP:bt>r\t%0,%h2,%1,0"
4413 [(set_attr "op_type" "RRF")
4414 (set_attr "type" "ftoi")])
4415
4416 (define_expand "fix_trunc<DSF:mode><GPR:mode>2"
4417 [(set (match_operand:GPR 0 "register_operand" "")
4418 (fix:GPR (match_operand:DSF 1 "register_operand" "")))]
4419 "TARGET_HARD_FLOAT"
4420 {
4421 emit_insn (gen_fix_trunc<DSF:mode><GPR:mode>2_bfp (operands[0], operands[1],
4422 GEN_INT (5)));
4423 DONE;
4424 })
4425
4426 (define_insn "*fix_truncdfdi2_bfp_z13"
4427 [(set (match_operand:DI 0 "register_operand" "=d,v")
4428 (fix:DI (match_operand:DF 1 "register_operand" "f,v")))
4429 (unspec:DI [(match_operand:DI 2 "immediate_operand" "K,K")] UNSPEC_ROUND)
4430 (clobber (reg:CC CC_REGNUM))]
4431 "TARGET_Z13 && TARGET_HARD_FLOAT"
4432 "@
4433 cgdbr\t%0,%h2,%1
4434 wcgdb\t%v0,%v1,0,%h2"
4435 [(set_attr "op_type" "RRE,VRR")
4436 (set_attr "type" "ftoi")])
4437
4438 ; cgxbr, cgdbr, cgebr, cfxbr, cfdbr, cfebr
4439 (define_insn "*fix_trunc<BFP:mode><GPR:mode>2_bfp"
4440 [(set (match_operand:GPR 0 "register_operand" "=d")
4441 (fix:GPR (match_operand:BFP 1 "register_operand" "f")))
4442 (unspec:GPR [(match_operand:GPR 2 "immediate_operand" "K")] UNSPEC_ROUND)
4443 (clobber (reg:CC CC_REGNUM))]
4444 "TARGET_HARD_FLOAT
4445 && (!TARGET_VX || <GPR:MODE>mode != DImode || <BFP:MODE>mode != DFmode)"
4446 "c<GPR:gf><BFP:xde>br\t%0,%h2,%1"
4447 [(set_attr "op_type" "RRE")
4448 (set_attr "type" "ftoi")])
4449
4450 (define_expand "fix_trunc<BFP:mode><GPR:mode>2_bfp"
4451 [(parallel
4452 [(set (match_operand:GPR 0 "register_operand" "=d")
4453 (fix:GPR (match_operand:BFP 1 "register_operand" "f")))
4454 (unspec:GPR [(match_operand:GPR 2 "immediate_operand" "K")] UNSPEC_ROUND)
4455 (clobber (reg:CC CC_REGNUM))])]
4456 "TARGET_HARD_FLOAT")
4457 ;
4458 ; fix_trunc(td|dd)di2 instruction pattern(s).
4459 ;
4460
4461 (define_expand "fix_trunc<mode>di2"
4462 [(set (match_operand:DI 0 "register_operand" "")
4463 (fix:DI (match_operand:DFP 1 "nonimmediate_operand" "")))]
4464 "TARGET_ZARCH && TARGET_HARD_DFP"
4465 {
4466 operands[1] = force_reg (<MODE>mode, operands[1]);
4467 emit_insn (gen_fix_trunc<mode>di2_dfp (operands[0], operands[1],
4468 GEN_INT (9)));
4469 DONE;
4470 })
4471
4472 ; cgxtr, cgdtr
4473 (define_insn "fix_trunc<DFP:mode>di2_dfp"
4474 [(set (match_operand:DI 0 "register_operand" "=d")
4475 (fix:DI (match_operand:DFP 1 "register_operand" "f")))
4476 (unspec:DI [(match_operand:DI 2 "immediate_operand" "K")] UNSPEC_ROUND)
4477 (clobber (reg:CC CC_REGNUM))]
4478 "TARGET_ZARCH && TARGET_HARD_DFP"
4479 "cg<DFP:xde>tr\t%0,%h2,%1"
4480 [(set_attr "op_type" "RRF")
4481 (set_attr "type" "ftoidfp")])
4482
4483
4484 ;
4485 ; fix_trunctf(si|di)2 instruction pattern(s).
4486 ;
4487
4488 (define_expand "fix_trunctf<mode>2"
4489 [(parallel [(set (match_operand:GPR 0 "register_operand" "")
4490 (fix:GPR (match_operand:TF 1 "register_operand" "")))
4491 (unspec:GPR [(const_int 5)] UNSPEC_ROUND)
4492 (clobber (reg:CC CC_REGNUM))])]
4493 "TARGET_HARD_FLOAT"
4494 "")
4495
4496
4497 ;
4498 ; float(si|di)(tf|df|sf|td|dd)2 instruction pattern(s).
4499 ;
4500
4501 ; cxgbr, cdgbr, cegbr, cxgtr, cdgtr
4502 (define_insn "floatdi<mode>2"
4503 [(set (match_operand:FP 0 "register_operand" "=f,<vf>")
4504 (float:FP (match_operand:DI 1 "register_operand" "d,<vd>")))]
4505 "TARGET_ZARCH && TARGET_HARD_FLOAT"
4506 "@
4507 c<xde>g<bt>r\t%0,%1
4508 wcdgb\t%v0,%v1,0,0"
4509 [(set_attr "op_type" "RRE,VRR")
4510 (set_attr "type" "itof<mode>" )
4511 (set_attr "cpu_facility" "*,vec")])
4512
4513 ; cxfbr, cdfbr, cefbr
4514 (define_insn "floatsi<mode>2"
4515 [(set (match_operand:BFP 0 "register_operand" "=f")
4516 (float:BFP (match_operand:SI 1 "register_operand" "d")))]
4517 "TARGET_HARD_FLOAT"
4518 "c<xde>fbr\t%0,%1"
4519 [(set_attr "op_type" "RRE")
4520 (set_attr "type" "itof<mode>" )])
4521
4522 ; cxftr, cdftr
4523 (define_insn "floatsi<mode>2"
4524 [(set (match_operand:DFP 0 "register_operand" "=f")
4525 (float:DFP (match_operand:SI 1 "register_operand" "d")))]
4526 "TARGET_Z196 && TARGET_HARD_FLOAT"
4527 "c<xde>ftr\t%0,0,%1,0"
4528 [(set_attr "op_type" "RRE")
4529 (set_attr "type" "itof<mode>" )])
4530
4531 ;
4532 ; floatuns(si|di)(tf|df|sf|td|dd)2 instruction pattern(s).
4533 ;
4534
4535 (define_insn "*floatunsdidf2_z13"
4536 [(set (match_operand:DF 0 "register_operand" "=f,v")
4537 (unsigned_float:DF (match_operand:DI 1 "register_operand" "d,v")))]
4538 "TARGET_Z13 && TARGET_HARD_FLOAT"
4539 "@
4540 cdlgbr\t%0,0,%1,0
4541 wcdlgb\t%v0,%v1,0,0"
4542 [(set_attr "op_type" "RRE,VRR")
4543 (set_attr "type" "itofdf")])
4544
4545 ; cxlgbr, cdlgbr, celgbr, cxlgtr, cdlgtr
4546 ; cxlfbr, cdlfbr, celfbr, cxlftr, cdlftr
4547 (define_insn "*floatuns<GPR:mode><FP:mode>2"
4548 [(set (match_operand:FP 0 "register_operand" "=f")
4549 (unsigned_float:FP (match_operand:GPR 1 "register_operand" "d")))]
4550 "TARGET_Z196 && TARGET_HARD_FLOAT
4551 && (!TARGET_VX || <FP:MODE>mode != DFmode || <GPR:MODE>mode != DImode)"
4552 "c<FP:xde>l<GPR:gf><FP:bt>r\t%0,0,%1,0"
4553 [(set_attr "op_type" "RRE")
4554 (set_attr "type" "itof<FP:mode>")])
4555
4556 (define_expand "floatuns<GPR:mode><FP:mode>2"
4557 [(set (match_operand:FP 0 "register_operand" "")
4558 (unsigned_float:FP (match_operand:GPR 1 "register_operand" "")))]
4559 "TARGET_Z196 && TARGET_HARD_FLOAT")
4560
4561 ;
4562 ; truncdfsf2 instruction pattern(s).
4563 ;
4564
4565 (define_insn "truncdfsf2"
4566 [(set (match_operand:SF 0 "register_operand" "=f,v")
4567 (float_truncate:SF (match_operand:DF 1 "register_operand" "f,v")))]
4568 "TARGET_HARD_FLOAT"
4569 "@
4570 ledbr\t%0,%1
4571 wledb\t%v0,%v1,0,0" ; IEEE inexact exception not suppressed
4572 ; According to BFP rounding mode
4573 [(set_attr "op_type" "RRE,VRR")
4574 (set_attr "type" "ftruncdf")
4575 (set_attr "cpu_facility" "*,vec")])
4576
4577 ;
4578 ; trunctf(df|sf)2 instruction pattern(s).
4579 ;
4580
4581 ; ldxbr, lexbr
4582 (define_insn "trunctf<mode>2"
4583 [(set (match_operand:DSF 0 "register_operand" "=f")
4584 (float_truncate:DSF (match_operand:TF 1 "register_operand" "f")))
4585 (clobber (match_scratch:TF 2 "=f"))]
4586 "TARGET_HARD_FLOAT"
4587 "l<xde>xbr\t%2,%1\;l<xde>r\t%0,%2"
4588 [(set_attr "length" "6")
4589 (set_attr "type" "ftrunctf")])
4590
4591 ;
4592 ; trunctddd2 and truncddsd2 instruction pattern(s).
4593 ;
4594
4595 (define_insn "trunctddd2"
4596 [(set (match_operand:DD 0 "register_operand" "=f")
4597 (float_truncate:DD (match_operand:TD 1 "register_operand" "f")))
4598 (clobber (match_scratch:TD 2 "=f"))]
4599 "TARGET_HARD_DFP"
4600 "ldxtr\t%2,0,%1,0\;ldr\t%0,%2"
4601 [(set_attr "length" "6")
4602 (set_attr "type" "ftruncdd")])
4603
4604 (define_insn "truncddsd2"
4605 [(set (match_operand:SD 0 "register_operand" "=f")
4606 (float_truncate:SD (match_operand:DD 1 "register_operand" "f")))]
4607 "TARGET_HARD_DFP"
4608 "ledtr\t%0,0,%1,0"
4609 [(set_attr "op_type" "RRF")
4610 (set_attr "type" "ftruncsd")])
4611
4612 (define_expand "trunctdsd2"
4613 [(parallel
4614 [(set (match_dup 3)
4615 (float_truncate:DD (match_operand:TD 1 "register_operand" "")))
4616 (clobber (match_scratch:TD 2 ""))])
4617 (set (match_operand:SD 0 "register_operand" "")
4618 (float_truncate:SD (match_dup 3)))]
4619 "TARGET_HARD_DFP"
4620 {
4621 operands[3] = gen_reg_rtx (DDmode);
4622 })
4623
4624 ;
4625 ; extend(sf|df)(df|tf)2 instruction pattern(s).
4626 ;
4627
4628 (define_insn "*extendsfdf2_z13"
4629 [(set (match_operand:DF 0 "register_operand" "=f,f,v")
4630 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "f,R,v")))]
4631 "TARGET_Z13 && TARGET_HARD_FLOAT"
4632 "@
4633 ldebr\t%0,%1
4634 ldeb\t%0,%1
4635 wldeb\t%v0,%v1"
4636 [(set_attr "op_type" "RRE,RXE,VRR")
4637 (set_attr "type" "fsimpdf, floaddf,fsimpdf")])
4638
4639 ; ldebr, ldeb, lxdbr, lxdb, lxebr, lxeb
4640 (define_insn "*extend<DSF:mode><BFP:mode>2"
4641 [(set (match_operand:BFP 0 "register_operand" "=f,f")
4642 (float_extend:BFP (match_operand:DSF 1 "nonimmediate_operand" "f,R")))]
4643 "TARGET_HARD_FLOAT
4644 && GET_MODE_SIZE (<BFP:MODE>mode) > GET_MODE_SIZE (<DSF:MODE>mode)
4645 && (!TARGET_VX || <BFP:MODE>mode != DFmode || <DSF:MODE>mode != SFmode)"
4646 "@
4647 l<BFP:xde><DSF:xde>br\t%0,%1
4648 l<BFP:xde><DSF:xde>b\t%0,%1"
4649 [(set_attr "op_type" "RRE,RXE")
4650 (set_attr "type" "fsimp<BFP:mode>, fload<BFP:mode>")])
4651
4652 (define_expand "extend<DSF:mode><BFP:mode>2"
4653 [(set (match_operand:BFP 0 "register_operand" "")
4654 (float_extend:BFP (match_operand:DSF 1 "nonimmediate_operand" "")))]
4655 "TARGET_HARD_FLOAT
4656 && GET_MODE_SIZE (<BFP:MODE>mode) > GET_MODE_SIZE (<DSF:MODE>mode)")
4657
4658 ;
4659 ; extendddtd2 and extendsddd2 instruction pattern(s).
4660 ;
4661
4662 (define_insn "extendddtd2"
4663 [(set (match_operand:TD 0 "register_operand" "=f")
4664 (float_extend:TD (match_operand:DD 1 "register_operand" "f")))]
4665 "TARGET_HARD_DFP"
4666 "lxdtr\t%0,%1,0"
4667 [(set_attr "op_type" "RRF")
4668 (set_attr "type" "fsimptf")])
4669
4670 (define_insn "extendsddd2"
4671 [(set (match_operand:DD 0 "register_operand" "=f")
4672 (float_extend:DD (match_operand:SD 1 "register_operand" "f")))]
4673 "TARGET_HARD_DFP"
4674 "ldetr\t%0,%1,0"
4675 [(set_attr "op_type" "RRF")
4676 (set_attr "type" "fsimptf")])
4677
4678 (define_expand "extendsdtd2"
4679 [(set (match_dup 2)
4680 (float_extend:DD (match_operand:SD 1 "register_operand" "")))
4681 (set (match_operand:TD 0 "register_operand" "")
4682 (float_extend:TD (match_dup 2)))]
4683 "TARGET_HARD_DFP"
4684 {
4685 operands[2] = gen_reg_rtx (DDmode);
4686 })
4687
4688 ; Binary Floating Point - load fp integer
4689
4690 ; Expanders for: floor, btrunc, round, ceil, and nearbyint
4691 ; For all of them the inexact exceptions are suppressed.
4692
4693 ; fiebra, fidbra, fixbra
4694 (define_insn "<FPINT:fpint_name><BFP:mode>2"
4695 [(set (match_operand:BFP 0 "register_operand" "=f")
4696 (unspec:BFP [(match_operand:BFP 1 "register_operand" "f")]
4697 FPINT))]
4698 "TARGET_Z196"
4699 "fi<BFP:xde>bra\t%0,<FPINT:fpint_roundingmode>,%1,4"
4700 [(set_attr "op_type" "RRF")
4701 (set_attr "type" "fsimp<BFP:mode>")])
4702
4703 ; rint is supposed to raise an inexact exception so we can use the
4704 ; older instructions.
4705
4706 ; fiebr, fidbr, fixbr
4707 (define_insn "rint<BFP:mode>2"
4708 [(set (match_operand:BFP 0 "register_operand" "=f")
4709 (unspec:BFP [(match_operand:BFP 1 "register_operand" "f")]
4710 UNSPEC_FPINT_RINT))]
4711 ""
4712 "fi<BFP:xde>br\t%0,0,%1"
4713 [(set_attr "op_type" "RRF")
4714 (set_attr "type" "fsimp<BFP:mode>")])
4715
4716
4717 ; Decimal Floating Point - load fp integer
4718
4719 ; fidtr, fixtr
4720 (define_insn "<FPINT:fpint_name><DFP:mode>2"
4721 [(set (match_operand:DFP 0 "register_operand" "=f")
4722 (unspec:DFP [(match_operand:DFP 1 "register_operand" "f")]
4723 FPINT))]
4724 "TARGET_HARD_DFP"
4725 "fi<DFP:xde>tr\t%0,<FPINT:fpint_roundingmode>,%1,4"
4726 [(set_attr "op_type" "RRF")
4727 (set_attr "type" "fsimp<DFP:mode>")])
4728
4729 ; fidtr, fixtr
4730 (define_insn "rint<DFP:mode>2"
4731 [(set (match_operand:DFP 0 "register_operand" "=f")
4732 (unspec:DFP [(match_operand:DFP 1 "register_operand" "f")]
4733 UNSPEC_FPINT_RINT))]
4734 "TARGET_HARD_DFP"
4735 "fi<DFP:xde>tr\t%0,0,%1,0"
4736 [(set_attr "op_type" "RRF")
4737 (set_attr "type" "fsimp<DFP:mode>")])
4738
4739 ;
4740 ; Binary <-> Decimal floating point trunc patterns
4741 ;
4742
4743 (define_insn "*trunc<BFP:mode><DFP_ALL:mode>2"
4744 [(set (reg:DFP_ALL FPR0_REGNUM)
4745 (float_truncate:DFP_ALL (reg:BFP FPR4_REGNUM)))
4746 (use (reg:SI GPR0_REGNUM))
4747 (clobber (reg:CC CC_REGNUM))]
4748 "TARGET_HARD_DFP"
4749 "pfpo")
4750
4751 (define_insn "*trunc<DFP_ALL:mode><BFP:mode>2"
4752 [(set (reg:BFP FPR0_REGNUM)
4753 (float_truncate:BFP (reg:DFP_ALL FPR4_REGNUM)))
4754 (use (reg:SI GPR0_REGNUM))
4755 (clobber (reg:CC CC_REGNUM))]
4756 "TARGET_HARD_DFP"
4757 "pfpo")
4758
4759 (define_expand "trunc<BFP:mode><DFP_ALL:mode>2"
4760 [(set (reg:BFP FPR4_REGNUM) (match_operand:BFP 1 "nonimmediate_operand" ""))
4761 (set (reg:SI GPR0_REGNUM) (match_dup 2))
4762 (parallel
4763 [(set (reg:DFP_ALL FPR0_REGNUM)
4764 (float_truncate:DFP_ALL (reg:BFP FPR4_REGNUM)))
4765 (use (reg:SI GPR0_REGNUM))
4766 (clobber (reg:CC CC_REGNUM))])
4767 (set (match_operand:DFP_ALL 0 "nonimmediate_operand" "")
4768 (reg:DFP_ALL FPR0_REGNUM))]
4769 "TARGET_HARD_DFP
4770 && GET_MODE_SIZE (<BFP:MODE>mode) > GET_MODE_SIZE (<DFP_ALL:MODE>mode)"
4771 {
4772 HOST_WIDE_INT flags;
4773
4774 flags = (PFPO_CONVERT |
4775 PFPO_OP_TYPE_<DFP_ALL:MODE> << PFPO_OP0_TYPE_SHIFT |
4776 PFPO_OP_TYPE_<BFP:MODE> << PFPO_OP1_TYPE_SHIFT);
4777
4778 operands[2] = GEN_INT (flags);
4779 })
4780
4781 (define_expand "trunc<DFP_ALL:mode><BFP:mode>2"
4782 [(set (reg:DFP_ALL FPR4_REGNUM)
4783 (match_operand:DFP_ALL 1 "nonimmediate_operand" ""))
4784 (set (reg:SI GPR0_REGNUM) (match_dup 2))
4785 (parallel
4786 [(set (reg:BFP FPR0_REGNUM) (float_truncate:BFP (reg:DFP_ALL FPR4_REGNUM)))
4787 (use (reg:SI GPR0_REGNUM))
4788 (clobber (reg:CC CC_REGNUM))])
4789 (set (match_operand:BFP 0 "nonimmediate_operand" "") (reg:BFP FPR0_REGNUM))]
4790 "TARGET_HARD_DFP
4791 && GET_MODE_SIZE (<DFP_ALL:MODE>mode) >= GET_MODE_SIZE (<BFP:MODE>mode)"
4792 {
4793 HOST_WIDE_INT flags;
4794
4795 flags = (PFPO_CONVERT |
4796 PFPO_OP_TYPE_<BFP:MODE> << PFPO_OP0_TYPE_SHIFT |
4797 PFPO_OP_TYPE_<DFP_ALL:MODE> << PFPO_OP1_TYPE_SHIFT);
4798
4799 operands[2] = GEN_INT (flags);
4800 })
4801
4802 ;
4803 ; Binary <-> Decimal floating point extend patterns
4804 ;
4805
4806 (define_insn "*extend<BFP:mode><DFP_ALL:mode>2"
4807 [(set (reg:DFP_ALL FPR0_REGNUM) (float_extend:DFP_ALL (reg:BFP FPR4_REGNUM)))
4808 (use (reg:SI GPR0_REGNUM))
4809 (clobber (reg:CC CC_REGNUM))]
4810 "TARGET_HARD_DFP"
4811 "pfpo")
4812
4813 (define_insn "*extend<DFP_ALL:mode><BFP:mode>2"
4814 [(set (reg:BFP FPR0_REGNUM) (float_extend:BFP (reg:DFP_ALL FPR4_REGNUM)))
4815 (use (reg:SI GPR0_REGNUM))
4816 (clobber (reg:CC CC_REGNUM))]
4817 "TARGET_HARD_DFP"
4818 "pfpo")
4819
4820 (define_expand "extend<BFP:mode><DFP_ALL:mode>2"
4821 [(set (reg:BFP FPR4_REGNUM) (match_operand:BFP 1 "nonimmediate_operand" ""))
4822 (set (reg:SI GPR0_REGNUM) (match_dup 2))
4823 (parallel
4824 [(set (reg:DFP_ALL FPR0_REGNUM)
4825 (float_extend:DFP_ALL (reg:BFP FPR4_REGNUM)))
4826 (use (reg:SI GPR0_REGNUM))
4827 (clobber (reg:CC CC_REGNUM))])
4828 (set (match_operand:DFP_ALL 0 "nonimmediate_operand" "")
4829 (reg:DFP_ALL FPR0_REGNUM))]
4830 "TARGET_HARD_DFP
4831 && GET_MODE_SIZE (<BFP:MODE>mode) <= GET_MODE_SIZE (<DFP_ALL:MODE>mode)"
4832 {
4833 HOST_WIDE_INT flags;
4834
4835 flags = (PFPO_CONVERT |
4836 PFPO_OP_TYPE_<DFP_ALL:MODE> << PFPO_OP0_TYPE_SHIFT |
4837 PFPO_OP_TYPE_<BFP:MODE> << PFPO_OP1_TYPE_SHIFT);
4838
4839 operands[2] = GEN_INT (flags);
4840 })
4841
4842 (define_expand "extend<DFP_ALL:mode><BFP:mode>2"
4843 [(set (reg:DFP_ALL FPR4_REGNUM)
4844 (match_operand:DFP_ALL 1 "nonimmediate_operand" ""))
4845 (set (reg:SI GPR0_REGNUM) (match_dup 2))
4846 (parallel
4847 [(set (reg:BFP FPR0_REGNUM) (float_extend:BFP (reg:DFP_ALL FPR4_REGNUM)))
4848 (use (reg:SI GPR0_REGNUM))
4849 (clobber (reg:CC CC_REGNUM))])
4850 (set (match_operand:BFP 0 "nonimmediate_operand" "") (reg:BFP FPR0_REGNUM))]
4851 "TARGET_HARD_DFP
4852 && GET_MODE_SIZE (<DFP_ALL:MODE>mode) < GET_MODE_SIZE (<BFP:MODE>mode)"
4853 {
4854 HOST_WIDE_INT flags;
4855
4856 flags = (PFPO_CONVERT |
4857 PFPO_OP_TYPE_<BFP:MODE> << PFPO_OP0_TYPE_SHIFT |
4858 PFPO_OP_TYPE_<DFP_ALL:MODE> << PFPO_OP1_TYPE_SHIFT);
4859
4860 operands[2] = GEN_INT (flags);
4861 })
4862
4863
4864 ;;
4865 ;; ARITHMETIC OPERATIONS
4866 ;;
4867 ; arithmetic operations set the ConditionCode,
4868 ; because of unpredictable Bits in Register for Halfword and Byte
4869 ; the ConditionCode can be set wrong in operations for Halfword and Byte
4870
4871 ;;
4872 ;;- Add instructions.
4873 ;;
4874
4875 ;
4876 ; addti3 instruction pattern(s).
4877 ;
4878
4879 (define_expand "addti3"
4880 [(parallel
4881 [(set (match_operand:TI 0 "register_operand" "")
4882 (plus:TI (match_operand:TI 1 "nonimmediate_operand" "")
4883 (match_operand:TI 2 "general_operand" "") ) )
4884 (clobber (reg:CC CC_REGNUM))])]
4885 "TARGET_ZARCH"
4886 {
4887 /* For z13 we have vaq which doesn't set CC. */
4888 if (TARGET_VX)
4889 {
4890 emit_insn (gen_rtx_SET (operands[0],
4891 gen_rtx_PLUS (TImode,
4892 copy_to_mode_reg (TImode, operands[1]),
4893 copy_to_mode_reg (TImode, operands[2]))));
4894 DONE;
4895 }
4896 })
4897
4898 (define_insn_and_split "*addti3"
4899 [(set (match_operand:TI 0 "register_operand" "=&d")
4900 (plus:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
4901 (match_operand:TI 2 "general_operand" "do") ) )
4902 (clobber (reg:CC CC_REGNUM))]
4903 "TARGET_ZARCH"
4904 "#"
4905 "&& reload_completed"
4906 [(parallel
4907 [(set (reg:CCL1 CC_REGNUM)
4908 (compare:CCL1 (plus:DI (match_dup 7) (match_dup 8))
4909 (match_dup 7)))
4910 (set (match_dup 6) (plus:DI (match_dup 7) (match_dup 8)))])
4911 (parallel
4912 [(set (match_dup 3) (plus:DI
4913 (plus:DI (ltu:DI (reg:CCL1 CC_REGNUM) (const_int 0))
4914 (match_dup 4)) (match_dup 5)))
4915 (clobber (reg:CC CC_REGNUM))])]
4916 "operands[3] = operand_subword (operands[0], 0, 0, TImode);
4917 operands[4] = operand_subword (operands[1], 0, 0, TImode);
4918 operands[5] = operand_subword (operands[2], 0, 0, TImode);
4919 operands[6] = operand_subword (operands[0], 1, 0, TImode);
4920 operands[7] = operand_subword (operands[1], 1, 0, TImode);
4921 operands[8] = operand_subword (operands[2], 1, 0, TImode);"
4922 [(set_attr "op_type" "*")
4923 (set_attr "cpu_facility" "*")])
4924
4925 ;
4926 ; adddi3 instruction pattern(s).
4927 ;
4928
4929 (define_expand "adddi3"
4930 [(parallel
4931 [(set (match_operand:DI 0 "nonimmediate_operand" "")
4932 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
4933 (match_operand:DI 2 "general_operand" "")))
4934 (clobber (reg:CC CC_REGNUM))])]
4935 ""
4936 "")
4937
4938 (define_insn "*adddi3_sign"
4939 [(set (match_operand:DI 0 "register_operand" "=d,d")
4940 (plus:DI (sign_extend:DI (match_operand:SI 2 "general_operand" "d,RT"))
4941 (match_operand:DI 1 "register_operand" "0,0")))
4942 (clobber (reg:CC CC_REGNUM))]
4943 "TARGET_ZARCH"
4944 "@
4945 agfr\t%0,%2
4946 agf\t%0,%2"
4947 [(set_attr "op_type" "RRE,RXY")
4948 (set_attr "z196prop" "z196_cracked,z196_cracked")])
4949
4950 (define_insn "*adddi3_zero_cc"
4951 [(set (reg CC_REGNUM)
4952 (compare (plus:DI (zero_extend:DI (match_operand:SI 2 "general_operand" "d,RT"))
4953 (match_operand:DI 1 "register_operand" "0,0"))
4954 (const_int 0)))
4955 (set (match_operand:DI 0 "register_operand" "=d,d")
4956 (plus:DI (zero_extend:DI (match_dup 2)) (match_dup 1)))]
4957 "s390_match_ccmode (insn, CCLmode) && TARGET_ZARCH"
4958 "@
4959 algfr\t%0,%2
4960 algf\t%0,%2"
4961 [(set_attr "op_type" "RRE,RXY")
4962 (set_attr "z10prop" "z10_super_E1,z10_super_E1")])
4963
4964 (define_insn "*adddi3_zero_cconly"
4965 [(set (reg CC_REGNUM)
4966 (compare (plus:DI (zero_extend:DI (match_operand:SI 2 "general_operand" "d,RT"))
4967 (match_operand:DI 1 "register_operand" "0,0"))
4968 (const_int 0)))
4969 (clobber (match_scratch:DI 0 "=d,d"))]
4970 "s390_match_ccmode (insn, CCLmode) && TARGET_ZARCH"
4971 "@
4972 algfr\t%0,%2
4973 algf\t%0,%2"
4974 [(set_attr "op_type" "RRE,RXY")
4975 (set_attr "z10prop" "z10_super_E1,z10_super_E1")])
4976
4977 (define_insn "*adddi3_zero"
4978 [(set (match_operand:DI 0 "register_operand" "=d,d")
4979 (plus:DI (zero_extend:DI (match_operand:SI 2 "general_operand" "d,RT"))
4980 (match_operand:DI 1 "register_operand" "0,0")))
4981 (clobber (reg:CC CC_REGNUM))]
4982 "TARGET_ZARCH"
4983 "@
4984 algfr\t%0,%2
4985 algf\t%0,%2"
4986 [(set_attr "op_type" "RRE,RXY")
4987 (set_attr "z10prop" "z10_super_E1,z10_super_E1")])
4988
4989 (define_insn_and_split "*adddi3_31z"
4990 [(set (match_operand:DI 0 "nonimmediate_operand" "=&d")
4991 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
4992 (match_operand:DI 2 "general_operand" "do") ) )
4993 (clobber (reg:CC CC_REGNUM))]
4994 "!TARGET_ZARCH && TARGET_CPU_ZARCH"
4995 "#"
4996 "&& reload_completed"
4997 [(parallel
4998 [(set (reg:CCL1 CC_REGNUM)
4999 (compare:CCL1 (plus:SI (match_dup 7) (match_dup 8))
5000 (match_dup 7)))
5001 (set (match_dup 6) (plus:SI (match_dup 7) (match_dup 8)))])
5002 (parallel
5003 [(set (match_dup 3) (plus:SI
5004 (plus:SI (ltu:SI (reg:CCL1 CC_REGNUM) (const_int 0))
5005 (match_dup 4)) (match_dup 5)))
5006 (clobber (reg:CC CC_REGNUM))])]
5007 "operands[3] = operand_subword (operands[0], 0, 0, DImode);
5008 operands[4] = operand_subword (operands[1], 0, 0, DImode);
5009 operands[5] = operand_subword (operands[2], 0, 0, DImode);
5010 operands[6] = operand_subword (operands[0], 1, 0, DImode);
5011 operands[7] = operand_subword (operands[1], 1, 0, DImode);
5012 operands[8] = operand_subword (operands[2], 1, 0, DImode);")
5013
5014 (define_insn_and_split "*adddi3_31"
5015 [(set (match_operand:DI 0 "nonimmediate_operand" "=&d")
5016 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
5017 (match_operand:DI 2 "general_operand" "do") ) )
5018 (clobber (reg:CC CC_REGNUM))]
5019 "!TARGET_CPU_ZARCH"
5020 "#"
5021 "&& reload_completed"
5022 [(parallel
5023 [(set (match_dup 3) (plus:SI (match_dup 4) (match_dup 5)))
5024 (clobber (reg:CC CC_REGNUM))])
5025 (parallel
5026 [(set (reg:CCL1 CC_REGNUM)
5027 (compare:CCL1 (plus:SI (match_dup 7) (match_dup 8))
5028 (match_dup 7)))
5029 (set (match_dup 6) (plus:SI (match_dup 7) (match_dup 8)))])
5030 (set (pc)
5031 (if_then_else (ltu (reg:CCL1 CC_REGNUM) (const_int 0))
5032 (pc)
5033 (label_ref (match_dup 9))))
5034 (parallel
5035 [(set (match_dup 3) (plus:SI (match_dup 3) (const_int 1)))
5036 (clobber (reg:CC CC_REGNUM))])
5037 (match_dup 9)]
5038 "operands[3] = operand_subword (operands[0], 0, 0, DImode);
5039 operands[4] = operand_subword (operands[1], 0, 0, DImode);
5040 operands[5] = operand_subword (operands[2], 0, 0, DImode);
5041 operands[6] = operand_subword (operands[0], 1, 0, DImode);
5042 operands[7] = operand_subword (operands[1], 1, 0, DImode);
5043 operands[8] = operand_subword (operands[2], 1, 0, DImode);
5044 operands[9] = gen_label_rtx ();")
5045
5046 ;
5047 ; addsi3 instruction pattern(s).
5048 ;
5049
5050 (define_expand "addsi3"
5051 [(parallel
5052 [(set (match_operand:SI 0 "nonimmediate_operand" "")
5053 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "")
5054 (match_operand:SI 2 "general_operand" "")))
5055 (clobber (reg:CC CC_REGNUM))])]
5056 ""
5057 "")
5058
5059 (define_insn "*addsi3_sign"
5060 [(set (match_operand:SI 0 "register_operand" "=d,d")
5061 (plus:SI (sign_extend:SI (match_operand:HI 2 "memory_operand" "R,T"))
5062 (match_operand:SI 1 "register_operand" "0,0")))
5063 (clobber (reg:CC CC_REGNUM))]
5064 ""
5065 "@
5066 ah\t%0,%2
5067 ahy\t%0,%2"
5068 [(set_attr "op_type" "RX,RXY")
5069 (set_attr "z196prop" "z196_cracked,z196_cracked")])
5070
5071 ;
5072 ; add(di|si)3 instruction pattern(s).
5073 ;
5074
5075 ; ark, agrk, ar, ahi, ahik, aghik, alfi, slfi, a, ay, agr, aghi, algfi, slgfi, ag, asi, agsi
5076 (define_insn "*add<mode>3"
5077 [(set (match_operand:GPR 0 "nonimmediate_operand" "=d,d,d,d, d, d,d,d,QS")
5078 (plus:GPR (match_operand:GPR 1 "nonimmediate_operand" "%0,d,0,d, 0, 0,0,0, 0")
5079 (match_operand:GPR 2 "general_operand" " d,d,K,K,Op,On,R,T, C") ) )
5080 (clobber (reg:CC CC_REGNUM))]
5081 ""
5082 "@
5083 a<g>r\t%0,%2
5084 a<g>rk\t%0,%1,%2
5085 a<g>hi\t%0,%h2
5086 a<g>hik\t%0,%1,%h2
5087 al<g>fi\t%0,%2
5088 sl<g>fi\t%0,%n2
5089 a<g>\t%0,%2
5090 a<y>\t%0,%2
5091 a<g>si\t%0,%c2"
5092 [(set_attr "op_type" "RR<E>,RRF,RI,RIE,RIL,RIL,RX<Y>,RXY,SIY")
5093 (set_attr "cpu_facility" "*,z196,*,z196,extimm,extimm,*,*,z10")
5094 (set_attr "z10prop" "z10_super_E1,*,z10_super_E1,*,z10_super_E1,z10_super_E1,
5095 z10_super_E1,z10_super_E1,z10_super_E1")])
5096
5097 ; alr, alfi, slfi, al, aly, alrk, alhsik, algr, algfi, slgfi, alg, alsi, algsi, algrk, alghsik
5098 (define_insn "*add<mode>3_carry1_cc"
5099 [(set (reg CC_REGNUM)
5100 (compare (plus:GPR (match_operand:GPR 1 "nonimmediate_operand" "%0,d, 0, 0,d,0,0,0")
5101 (match_operand:GPR 2 "general_operand" " d,d,Op,On,K,R,T,C"))
5102 (match_dup 1)))
5103 (set (match_operand:GPR 0 "nonimmediate_operand" "=d,d, d, d,d,d,d,d")
5104 (plus:GPR (match_dup 1) (match_dup 2)))]
5105 "s390_match_ccmode (insn, CCL1mode)"
5106 "@
5107 al<g>r\t%0,%2
5108 al<g>rk\t%0,%1,%2
5109 al<g>fi\t%0,%2
5110 sl<g>fi\t%0,%n2
5111 al<g>hsik\t%0,%1,%h2
5112 al<g>\t%0,%2
5113 al<y>\t%0,%2
5114 al<g>si\t%0,%c2"
5115 [(set_attr "op_type" "RR<E>,RRF,RIL,RIL,RIE,RX<Y>,RXY,SIY")
5116 (set_attr "cpu_facility" "*,z196,extimm,extimm,z196,*,*,z10")
5117 (set_attr "z10prop" "z10_super_E1,*,z10_super_E1,z10_super_E1,*,
5118 z10_super_E1,z10_super_E1,z10_super_E1")])
5119
5120 ; alr, al, aly, algr, alg, alrk, algrk
5121 (define_insn "*add<mode>3_carry1_cconly"
5122 [(set (reg CC_REGNUM)
5123 (compare (plus:GPR (match_operand:GPR 1 "nonimmediate_operand" "%0,d,0,0")
5124 (match_operand:GPR 2 "general_operand" "d,d,R,T"))
5125 (match_dup 1)))
5126 (clobber (match_scratch:GPR 0 "=d,d,d,d"))]
5127 "s390_match_ccmode (insn, CCL1mode)"
5128 "@
5129 al<g>r\t%0,%2
5130 al<g>rk\t%0,%1,%2
5131 al<g>\t%0,%2
5132 al<y>\t%0,%2"
5133 [(set_attr "op_type" "RR<E>,RRF,RX<Y>,RXY")
5134 (set_attr "cpu_facility" "*,z196,*,*")
5135 (set_attr "z10prop" "z10_super_E1,*,z10_super_E1,z10_super_E1")])
5136
5137 ; alr, alfi, slfi, al, aly, algr, algfi, slgfi, alg, alsi, algsi, alrk, algrk, alhsik, alghsik
5138 (define_insn "*add<mode>3_carry2_cc"
5139 [(set (reg CC_REGNUM)
5140 (compare (plus:GPR (match_operand:GPR 1 "nonimmediate_operand" "%0,d, 0, 0,d,0,0, 0")
5141 (match_operand:GPR 2 "general_operand" " d,d,Op,On,K,R,T, C"))
5142 (match_dup 2)))
5143 (set (match_operand:GPR 0 "nonimmediate_operand" "=d,d, d, d,d,d,d,RS")
5144 (plus:GPR (match_dup 1) (match_dup 2)))]
5145 "s390_match_ccmode (insn, CCL1mode)"
5146 "@
5147 al<g>r\t%0,%2
5148 al<g>rk\t%0,%1,%2
5149 al<g>fi\t%0,%2
5150 sl<g>fi\t%0,%n2
5151 al<g>hsik\t%0,%1,%h2
5152 al<g>\t%0,%2
5153 al<y>\t%0,%2
5154 al<g>si\t%0,%c2"
5155 [(set_attr "op_type" "RR<E>,RRF,RIL,RIL,RIE,RX<Y>,RXY,SIY")
5156 (set_attr "cpu_facility" "*,z196,extimm,extimm,z196,*,*,z10")
5157 (set_attr "z10prop" "z10_super_E1,*,z10_super_E1,z10_super_E1,*,
5158 z10_super_E1,z10_super_E1,z10_super_E1")])
5159
5160 ; alr, al, aly, algr, alg, alrk, algrk
5161 (define_insn "*add<mode>3_carry2_cconly"
5162 [(set (reg CC_REGNUM)
5163 (compare (plus:GPR (match_operand:GPR 1 "nonimmediate_operand" "%0,d,0,0")
5164 (match_operand:GPR 2 "general_operand" "d,d,R,T"))
5165 (match_dup 2)))
5166 (clobber (match_scratch:GPR 0 "=d,d,d,d"))]
5167 "s390_match_ccmode (insn, CCL1mode)"
5168 "@
5169 al<g>r\t%0,%2
5170 al<g>rk\t%0,%1,%2
5171 al<g>\t%0,%2
5172 al<y>\t%0,%2"
5173 [(set_attr "op_type" "RR<E>,RRF,RX<Y>,RXY")
5174 (set_attr "cpu_facility" "*,z196,*,*")
5175 (set_attr "z10prop" "z10_super_E1,*,z10_super_E1,z10_super_E1")])
5176
5177 ; alr, alfi, slfi, al, aly, algr, algfi, slgfi, alg, alsi, algsi, alrk, algrk, alhsik, alghsik
5178 (define_insn "*add<mode>3_cc"
5179 [(set (reg CC_REGNUM)
5180 (compare (plus:GPR (match_operand:GPR 1 "nonimmediate_operand" "%0,d, 0, 0,d,0,0, 0")
5181 (match_operand:GPR 2 "general_operand" " d,d,Op,On,K,R,T, C"))
5182 (const_int 0)))
5183 (set (match_operand:GPR 0 "nonimmediate_operand" "=d,d, d, d,d,d,d,RS")
5184 (plus:GPR (match_dup 1) (match_dup 2)))]
5185 "s390_match_ccmode (insn, CCLmode)"
5186 "@
5187 al<g>r\t%0,%2
5188 al<g>rk\t%0,%1,%2
5189 al<g>fi\t%0,%2
5190 sl<g>fi\t%0,%n2
5191 al<g>hsik\t%0,%1,%h2
5192 al<g>\t%0,%2
5193 al<y>\t%0,%2
5194 al<g>si\t%0,%c2"
5195 [(set_attr "op_type" "RR<E>,RRF,RIL,RIL,RIE,RX<Y>,RXY,SIY")
5196 (set_attr "cpu_facility" "*,z196,extimm,extimm,z196,*,*,z10")
5197 (set_attr "z10prop" "z10_super_E1,*,z10_super_E1,z10_super_E1,
5198 *,z10_super_E1,z10_super_E1,z10_super_E1")])
5199
5200 ; alr, al, aly, algr, alg, alrk, algrk
5201 (define_insn "*add<mode>3_cconly"
5202 [(set (reg CC_REGNUM)
5203 (compare (plus:GPR (match_operand:GPR 1 "nonimmediate_operand" "%0,d,0,0")
5204 (match_operand:GPR 2 "general_operand" "d,d,R,T"))
5205 (const_int 0)))
5206 (clobber (match_scratch:GPR 0 "=d,d,d,d"))]
5207 "s390_match_ccmode (insn, CCLmode)"
5208 "@
5209 al<g>r\t%0,%2
5210 al<g>rk\t%0,%1,%2
5211 al<g>\t%0,%2
5212 al<y>\t%0,%2"
5213 [(set_attr "op_type" "RR<E>,RRF,RX<Y>,RXY")
5214 (set_attr "cpu_facility" "*,z196,*,*")
5215 (set_attr "z10prop" "z10_super_E1,*,z10_super_E1,z10_super_E1")])
5216
5217 ; alr, al, aly, algr, alg, alrk, algrk
5218 (define_insn "*add<mode>3_cconly2"
5219 [(set (reg CC_REGNUM)
5220 (compare (match_operand:GPR 1 "nonimmediate_operand" "%0,d,0,0")
5221 (neg:GPR (match_operand:GPR 2 "general_operand" "d,d,R,T"))))
5222 (clobber (match_scratch:GPR 0 "=d,d,d,d"))]
5223 "s390_match_ccmode(insn, CCLmode)"
5224 "@
5225 al<g>r\t%0,%2
5226 al<g>rk\t%0,%1,%2
5227 al<g>\t%0,%2
5228 al<y>\t%0,%2"
5229 [(set_attr "op_type" "RR<E>,RRF,RX<Y>,RXY")
5230 (set_attr "cpu_facility" "*,z196,*,*")
5231 (set_attr "z10prop" "z10_super_E1,*,z10_super_E1,z10_super_E1")])
5232
5233 ; ahi, afi, aghi, agfi, asi, agsi
5234 (define_insn "*add<mode>3_imm_cc"
5235 [(set (reg CC_REGNUM)
5236 (compare (plus:GPR (match_operand:GPR 1 "nonimmediate_operand" " 0, d,0, 0")
5237 (match_operand:GPR 2 "const_int_operand" " K, K,Os, C"))
5238 (const_int 0)))
5239 (set (match_operand:GPR 0 "nonimmediate_operand" "=d, d,d,QS")
5240 (plus:GPR (match_dup 1) (match_dup 2)))]
5241 "s390_match_ccmode (insn, CCAmode)
5242 && (CONST_OK_FOR_CONSTRAINT_P (INTVAL (operands[2]), 'K', \"K\")
5243 || (CONST_OK_FOR_CONSTRAINT_P (INTVAL (operands[2]), 'O', \"Os\")
5244 /* Avoid INT32_MIN on 32 bit. */
5245 && (!TARGET_ZARCH || INTVAL (operands[2]) != -0x7fffffff - 1)))"
5246 "@
5247 a<g>hi\t%0,%h2
5248 a<g>hik\t%0,%1,%h2
5249 a<g>fi\t%0,%2
5250 a<g>si\t%0,%c2"
5251 [(set_attr "op_type" "RI,RIE,RIL,SIY")
5252 (set_attr "cpu_facility" "*,z196,extimm,z10")
5253 (set_attr "z10prop" "z10_super_E1,*,z10_super_E1,z10_super_E1")])
5254
5255 ;
5256 ; add(tf|df|sf|td|dd)3 instruction pattern(s).
5257 ;
5258
5259 ; axbr, adbr, aebr, axb, adb, aeb, adtr, axtr
5260 ; FIXME: wfadb does not clobber cc
5261 (define_insn "add<mode>3"
5262 [(set (match_operand:FP 0 "register_operand" "=f, f,<vf>")
5263 (plus:FP (match_operand:FP 1 "nonimmediate_operand" "%<f0>, 0,<v0>")
5264 (match_operand:FP 2 "general_operand" "f,<Rf>,<vf>")))
5265 (clobber (reg:CC CC_REGNUM))]
5266 "TARGET_HARD_FLOAT"
5267 "@
5268 a<xde><bt>r\t%0,<op1>%2
5269 a<xde>b\t%0,%2
5270 wfadb\t%v0,%v1,%v2"
5271 [(set_attr "op_type" "<RRer>,RXE,VRR")
5272 (set_attr "type" "fsimp<mode>")
5273 (set_attr "cpu_facility" "*,*,vec")])
5274
5275 ; axbr, adbr, aebr, axb, adb, aeb, adtr, axtr
5276 (define_insn "*add<mode>3_cc"
5277 [(set (reg CC_REGNUM)
5278 (compare (plus:FP (match_operand:FP 1 "nonimmediate_operand" "%<f0>,0")
5279 (match_operand:FP 2 "general_operand" " f,<Rf>"))
5280 (match_operand:FP 3 "const0_operand" "")))
5281 (set (match_operand:FP 0 "register_operand" "=f,f")
5282 (plus:FP (match_dup 1) (match_dup 2)))]
5283 "s390_match_ccmode (insn, CCSmode) && TARGET_HARD_FLOAT"
5284 "@
5285 a<xde><bt>r\t%0,<op1>%2
5286 a<xde>b\t%0,%2"
5287 [(set_attr "op_type" "<RRer>,RXE")
5288 (set_attr "type" "fsimp<mode>")])
5289
5290 ; axbr, adbr, aebr, axb, adb, aeb, adtr, axtr
5291 (define_insn "*add<mode>3_cconly"
5292 [(set (reg CC_REGNUM)
5293 (compare (plus:FP (match_operand:FP 1 "nonimmediate_operand" "%<f0>,0")
5294 (match_operand:FP 2 "general_operand" " f,<Rf>"))
5295 (match_operand:FP 3 "const0_operand" "")))
5296 (clobber (match_scratch:FP 0 "=f,f"))]
5297 "s390_match_ccmode (insn, CCSmode) && TARGET_HARD_FLOAT"
5298 "@
5299 a<xde><bt>r\t%0,<op1>%2
5300 a<xde>b\t%0,%2"
5301 [(set_attr "op_type" "<RRer>,RXE")
5302 (set_attr "type" "fsimp<mode>")])
5303
5304 ;
5305 ; Pointer add instruction patterns
5306 ;
5307
5308 ; This will match "*la_64"
5309 (define_expand "addptrdi3"
5310 [(set (match_operand:DI 0 "register_operand" "")
5311 (plus:DI (match_operand:DI 1 "register_operand" "")
5312 (match_operand:DI 2 "nonmemory_operand" "")))]
5313 "TARGET_64BIT"
5314 {
5315 if (GET_CODE (operands[2]) == CONST_INT)
5316 {
5317 HOST_WIDE_INT c = INTVAL (operands[2]);
5318
5319 if (!CONST_OK_FOR_CONSTRAINT_P (c, 'K', "K")
5320 && !CONST_OK_FOR_CONSTRAINT_P (c, 'O', "Os"))
5321 {
5322 operands[2] = force_const_mem (DImode, operands[2]);
5323 operands[2] = force_reg (DImode, operands[2]);
5324 }
5325 else if (!DISP_IN_RANGE (INTVAL (operands[2])))
5326 operands[2] = force_reg (DImode, operands[2]);
5327 }
5328 })
5329
5330 ; For 31 bit we have to prevent the generated pattern from matching
5331 ; normal ADDs since la only does a 31 bit add. This is supposed to
5332 ; match "force_la_31".
5333 (define_expand "addptrsi3"
5334 [(parallel
5335 [(set (match_operand:SI 0 "register_operand" "")
5336 (plus:SI (match_operand:SI 1 "register_operand" "")
5337 (match_operand:SI 2 "nonmemory_operand" "")))
5338 (use (const_int 0))])]
5339 "!TARGET_64BIT"
5340 {
5341 if (GET_CODE (operands[2]) == CONST_INT)
5342 {
5343 HOST_WIDE_INT c = INTVAL (operands[2]);
5344
5345 if (!CONST_OK_FOR_CONSTRAINT_P (c, 'K', "K")
5346 && !CONST_OK_FOR_CONSTRAINT_P (c, 'O', "Os"))
5347 {
5348 operands[2] = force_const_mem (SImode, operands[2]);
5349 operands[2] = force_reg (SImode, operands[2]);
5350 }
5351 else if (!DISP_IN_RANGE (INTVAL (operands[2])))
5352 operands[2] = force_reg (SImode, operands[2]);
5353 }
5354 })
5355
5356 ;;
5357 ;;- Subtract instructions.
5358 ;;
5359
5360 ;
5361 ; subti3 instruction pattern(s).
5362 ;
5363
5364 (define_expand "subti3"
5365 [(parallel
5366 [(set (match_operand:TI 0 "register_operand" "")
5367 (minus:TI (match_operand:TI 1 "register_operand" "")
5368 (match_operand:TI 2 "general_operand" "") ) )
5369 (clobber (reg:CC CC_REGNUM))])]
5370 "TARGET_ZARCH"
5371 {
5372 /* For z13 we have vaq which doesn't set CC. */
5373 if (TARGET_VX)
5374 {
5375 emit_insn (gen_rtx_SET (operands[0],
5376 gen_rtx_MINUS (TImode,
5377 operands[1],
5378 copy_to_mode_reg (TImode, operands[2]))));
5379 DONE;
5380 }
5381 })
5382
5383 (define_insn_and_split "*subti3"
5384 [(set (match_operand:TI 0 "register_operand" "=&d")
5385 (minus:TI (match_operand:TI 1 "register_operand" "0")
5386 (match_operand:TI 2 "general_operand" "do") ) )
5387 (clobber (reg:CC CC_REGNUM))]
5388 "TARGET_ZARCH"
5389 "#"
5390 "&& reload_completed"
5391 [(parallel
5392 [(set (reg:CCL2 CC_REGNUM)
5393 (compare:CCL2 (minus:DI (match_dup 7) (match_dup 8))
5394 (match_dup 7)))
5395 (set (match_dup 6) (minus:DI (match_dup 7) (match_dup 8)))])
5396 (parallel
5397 [(set (match_dup 3) (minus:DI (minus:DI (match_dup 4) (match_dup 5))
5398 (gtu:DI (reg:CCL2 CC_REGNUM) (const_int 0))))
5399 (clobber (reg:CC CC_REGNUM))])]
5400 "operands[3] = operand_subword (operands[0], 0, 0, TImode);
5401 operands[4] = operand_subword (operands[1], 0, 0, TImode);
5402 operands[5] = operand_subword (operands[2], 0, 0, TImode);
5403 operands[6] = operand_subword (operands[0], 1, 0, TImode);
5404 operands[7] = operand_subword (operands[1], 1, 0, TImode);
5405 operands[8] = operand_subword (operands[2], 1, 0, TImode);"
5406 [(set_attr "op_type" "*")
5407 (set_attr "cpu_facility" "*")])
5408
5409 ;
5410 ; subdi3 instruction pattern(s).
5411 ;
5412
5413 (define_expand "subdi3"
5414 [(parallel
5415 [(set (match_operand:DI 0 "register_operand" "")
5416 (minus:DI (match_operand:DI 1 "register_operand" "")
5417 (match_operand:DI 2 "general_operand" "")))
5418 (clobber (reg:CC CC_REGNUM))])]
5419 ""
5420 "")
5421
5422 (define_insn "*subdi3_sign"
5423 [(set (match_operand:DI 0 "register_operand" "=d,d")
5424 (minus:DI (match_operand:DI 1 "register_operand" "0,0")
5425 (sign_extend:DI (match_operand:SI 2 "general_operand" "d,RT"))))
5426 (clobber (reg:CC CC_REGNUM))]
5427 "TARGET_ZARCH"
5428 "@
5429 sgfr\t%0,%2
5430 sgf\t%0,%2"
5431 [(set_attr "op_type" "RRE,RXY")
5432 (set_attr "z10prop" "z10_c,*")
5433 (set_attr "z196prop" "z196_cracked")])
5434
5435 (define_insn "*subdi3_zero_cc"
5436 [(set (reg CC_REGNUM)
5437 (compare (minus:DI (match_operand:DI 1 "register_operand" "0,0")
5438 (zero_extend:DI (match_operand:SI 2 "general_operand" "d,RT")))
5439 (const_int 0)))
5440 (set (match_operand:DI 0 "register_operand" "=d,d")
5441 (minus:DI (match_dup 1) (zero_extend:DI (match_dup 2))))]
5442 "s390_match_ccmode (insn, CCLmode) && TARGET_ZARCH"
5443 "@
5444 slgfr\t%0,%2
5445 slgf\t%0,%2"
5446 [(set_attr "op_type" "RRE,RXY")
5447 (set_attr "z10prop" "z10_super_c_E1,z10_super_E1")])
5448
5449 (define_insn "*subdi3_zero_cconly"
5450 [(set (reg CC_REGNUM)
5451 (compare (minus:DI (match_operand:DI 1 "register_operand" "0,0")
5452 (zero_extend:DI (match_operand:SI 2 "general_operand" "d,RT")))
5453 (const_int 0)))
5454 (clobber (match_scratch:DI 0 "=d,d"))]
5455 "s390_match_ccmode (insn, CCLmode) && TARGET_ZARCH"
5456 "@
5457 slgfr\t%0,%2
5458 slgf\t%0,%2"
5459 [(set_attr "op_type" "RRE,RXY")
5460 (set_attr "z10prop" "z10_super_c_E1,z10_super_E1")])
5461
5462 (define_insn "*subdi3_zero"
5463 [(set (match_operand:DI 0 "register_operand" "=d,d")
5464 (minus:DI (match_operand:DI 1 "register_operand" "0,0")
5465 (zero_extend:DI (match_operand:SI 2 "general_operand" "d,RT"))))
5466 (clobber (reg:CC CC_REGNUM))]
5467 "TARGET_ZARCH"
5468 "@
5469 slgfr\t%0,%2
5470 slgf\t%0,%2"
5471 [(set_attr "op_type" "RRE,RXY")
5472 (set_attr "z10prop" "z10_super_c_E1,z10_super_E1")])
5473
5474 (define_insn_and_split "*subdi3_31z"
5475 [(set (match_operand:DI 0 "register_operand" "=&d")
5476 (minus:DI (match_operand:DI 1 "register_operand" "0")
5477 (match_operand:DI 2 "general_operand" "do") ) )
5478 (clobber (reg:CC CC_REGNUM))]
5479 "!TARGET_ZARCH && TARGET_CPU_ZARCH"
5480 "#"
5481 "&& reload_completed"
5482 [(parallel
5483 [(set (reg:CCL2 CC_REGNUM)
5484 (compare:CCL2 (minus:SI (match_dup 7) (match_dup 8))
5485 (match_dup 7)))
5486 (set (match_dup 6) (minus:SI (match_dup 7) (match_dup 8)))])
5487 (parallel
5488 [(set (match_dup 3) (minus:SI (minus:SI (match_dup 4) (match_dup 5))
5489 (gtu:SI (reg:CCL2 CC_REGNUM) (const_int 0))))
5490 (clobber (reg:CC CC_REGNUM))])]
5491 "operands[3] = operand_subword (operands[0], 0, 0, DImode);
5492 operands[4] = operand_subword (operands[1], 0, 0, DImode);
5493 operands[5] = operand_subword (operands[2], 0, 0, DImode);
5494 operands[6] = operand_subword (operands[0], 1, 0, DImode);
5495 operands[7] = operand_subword (operands[1], 1, 0, DImode);
5496 operands[8] = operand_subword (operands[2], 1, 0, DImode);")
5497
5498 (define_insn_and_split "*subdi3_31"
5499 [(set (match_operand:DI 0 "register_operand" "=&d")
5500 (minus:DI (match_operand:DI 1 "register_operand" "0")
5501 (match_operand:DI 2 "general_operand" "do") ) )
5502 (clobber (reg:CC CC_REGNUM))]
5503 "!TARGET_CPU_ZARCH"
5504 "#"
5505 "&& reload_completed"
5506 [(parallel
5507 [(set (match_dup 3) (minus:SI (match_dup 4) (match_dup 5)))
5508 (clobber (reg:CC CC_REGNUM))])
5509 (parallel
5510 [(set (reg:CCL2 CC_REGNUM)
5511 (compare:CCL2 (minus:SI (match_dup 7) (match_dup 8))
5512 (match_dup 7)))
5513 (set (match_dup 6) (minus:SI (match_dup 7) (match_dup 8)))])
5514 (set (pc)
5515 (if_then_else (gtu (reg:CCL2 CC_REGNUM) (const_int 0))
5516 (pc)
5517 (label_ref (match_dup 9))))
5518 (parallel
5519 [(set (match_dup 3) (plus:SI (match_dup 3) (const_int -1)))
5520 (clobber (reg:CC CC_REGNUM))])
5521 (match_dup 9)]
5522 "operands[3] = operand_subword (operands[0], 0, 0, DImode);
5523 operands[4] = operand_subword (operands[1], 0, 0, DImode);
5524 operands[5] = operand_subword (operands[2], 0, 0, DImode);
5525 operands[6] = operand_subword (operands[0], 1, 0, DImode);
5526 operands[7] = operand_subword (operands[1], 1, 0, DImode);
5527 operands[8] = operand_subword (operands[2], 1, 0, DImode);
5528 operands[9] = gen_label_rtx ();")
5529
5530 ;
5531 ; subsi3 instruction pattern(s).
5532 ;
5533
5534 (define_expand "subsi3"
5535 [(parallel
5536 [(set (match_operand:SI 0 "register_operand" "")
5537 (minus:SI (match_operand:SI 1 "register_operand" "")
5538 (match_operand:SI 2 "general_operand" "")))
5539 (clobber (reg:CC CC_REGNUM))])]
5540 ""
5541 "")
5542
5543 (define_insn "*subsi3_sign"
5544 [(set (match_operand:SI 0 "register_operand" "=d,d")
5545 (minus:SI (match_operand:SI 1 "register_operand" "0,0")
5546 (sign_extend:SI (match_operand:HI 2 "memory_operand" "R,T"))))
5547 (clobber (reg:CC CC_REGNUM))]
5548 ""
5549 "@
5550 sh\t%0,%2
5551 shy\t%0,%2"
5552 [(set_attr "op_type" "RX,RXY")
5553 (set_attr "z196prop" "z196_cracked,z196_cracked")])
5554
5555 ;
5556 ; sub(di|si)3 instruction pattern(s).
5557 ;
5558
5559 ; sr, s, sy, sgr, sg, srk, sgrk
5560 (define_insn "*sub<mode>3"
5561 [(set (match_operand:GPR 0 "register_operand" "=d,d,d,d")
5562 (minus:GPR (match_operand:GPR 1 "register_operand" "0,d,0,0")
5563 (match_operand:GPR 2 "general_operand" "d,d,R,T") ) )
5564 (clobber (reg:CC CC_REGNUM))]
5565 ""
5566 "@
5567 s<g>r\t%0,%2
5568 s<g>rk\t%0,%1,%2
5569 s<g>\t%0,%2
5570 s<y>\t%0,%2"
5571 [(set_attr "op_type" "RR<E>,RRF,RX<Y>,RXY")
5572 (set_attr "cpu_facility" "*,z196,*,*")
5573 (set_attr "z10prop" "z10_super_c_E1,*,z10_super_E1,z10_super_E1")])
5574
5575 ; slr, sl, sly, slgr, slg, slrk, slgrk
5576 (define_insn "*sub<mode>3_borrow_cc"
5577 [(set (reg CC_REGNUM)
5578 (compare (minus:GPR (match_operand:GPR 1 "register_operand" "0,d,0,0")
5579 (match_operand:GPR 2 "general_operand" "d,d,R,T"))
5580 (match_dup 1)))
5581 (set (match_operand:GPR 0 "register_operand" "=d,d,d,d")
5582 (minus:GPR (match_dup 1) (match_dup 2)))]
5583 "s390_match_ccmode (insn, CCL2mode)"
5584 "@
5585 sl<g>r\t%0,%2
5586 sl<g>rk\t%0,%1,%2
5587 sl<g>\t%0,%2
5588 sl<y>\t%0,%2"
5589 [(set_attr "op_type" "RR<E>,RRF,RX<Y>,RXY")
5590 (set_attr "cpu_facility" "*,z196,*,*")
5591 (set_attr "z10prop" "z10_super_c_E1,*,z10_super_E1,z10_super_E1")])
5592
5593 ; slr, sl, sly, slgr, slg, slrk, slgrk
5594 (define_insn "*sub<mode>3_borrow_cconly"
5595 [(set (reg CC_REGNUM)
5596 (compare (minus:GPR (match_operand:GPR 1 "register_operand" "0,d,0,0")
5597 (match_operand:GPR 2 "general_operand" "d,d,R,T"))
5598 (match_dup 1)))
5599 (clobber (match_scratch:GPR 0 "=d,d,d,d"))]
5600 "s390_match_ccmode (insn, CCL2mode)"
5601 "@
5602 sl<g>r\t%0,%2
5603 sl<g>rk\t%0,%1,%2
5604 sl<g>\t%0,%2
5605 sl<y>\t%0,%2"
5606 [(set_attr "op_type" "RR<E>,RRF,RX<Y>,RXY")
5607 (set_attr "cpu_facility" "*,z196,*,*")
5608 (set_attr "z10prop" "z10_super_c_E1,*,z10_super_E1,z10_super_E1")])
5609
5610 ; slr, sl, sly, slgr, slg, slrk, slgrk
5611 (define_insn "*sub<mode>3_cc"
5612 [(set (reg CC_REGNUM)
5613 (compare (minus:GPR (match_operand:GPR 1 "register_operand" "0,d,0,0")
5614 (match_operand:GPR 2 "general_operand" "d,d,R,T"))
5615 (const_int 0)))
5616 (set (match_operand:GPR 0 "register_operand" "=d,d,d,d")
5617 (minus:GPR (match_dup 1) (match_dup 2)))]
5618 "s390_match_ccmode (insn, CCLmode)"
5619 "@
5620 sl<g>r\t%0,%2
5621 sl<g>rk\t%0,%1,%2
5622 sl<g>\t%0,%2
5623 sl<y>\t%0,%2"
5624 [(set_attr "op_type" "RR<E>,RRF,RX<Y>,RXY")
5625 (set_attr "cpu_facility" "*,z196,*,*")
5626 (set_attr "z10prop" "z10_super_c_E1,*,z10_super_E1,z10_super_E1")])
5627
5628 ; slr, sl, sly, slgr, slg, slrk, slgrk
5629 (define_insn "*sub<mode>3_cc2"
5630 [(set (reg CC_REGNUM)
5631 (compare (match_operand:GPR 1 "register_operand" "0,d,0,0")
5632 (match_operand:GPR 2 "general_operand" "d,d,R,T")))
5633 (set (match_operand:GPR 0 "register_operand" "=d,d,d,d")
5634 (minus:GPR (match_dup 1) (match_dup 2)))]
5635 "s390_match_ccmode (insn, CCL3mode)"
5636 "@
5637 sl<g>r\t%0,%2
5638 sl<g>rk\t%0,%1,%2
5639 sl<g>\t%0,%2
5640 sl<y>\t%0,%2"
5641 [(set_attr "op_type" "RR<E>,RRF,RX<Y>,RXY")
5642 (set_attr "cpu_facility" "*,z196,*,*")
5643 (set_attr "z10prop" "z10_super_c_E1,*,z10_super_E1,z10_super_E1")])
5644
5645 ; slr, sl, sly, slgr, slg, slrk, slgrk
5646 (define_insn "*sub<mode>3_cconly"
5647 [(set (reg CC_REGNUM)
5648 (compare (minus:GPR (match_operand:GPR 1 "register_operand" "0,d,0,0")
5649 (match_operand:GPR 2 "general_operand" "d,d,R,T"))
5650 (const_int 0)))
5651 (clobber (match_scratch:GPR 0 "=d,d,d,d"))]
5652 "s390_match_ccmode (insn, CCLmode)"
5653 "@
5654 sl<g>r\t%0,%2
5655 sl<g>rk\t%0,%1,%2
5656 sl<g>\t%0,%2
5657 sl<y>\t%0,%2"
5658 [(set_attr "op_type" "RR<E>,RRF,RX<Y>,RXY")
5659 (set_attr "cpu_facility" "*,z196,*,*")
5660 (set_attr "z10prop" "z10_super_c_E1,*,z10_super_E1,z10_super_E1")])
5661
5662
5663 ; slr, sl, sly, slgr, slg, slrk, slgrk
5664 (define_insn "*sub<mode>3_cconly2"
5665 [(set (reg CC_REGNUM)
5666 (compare (match_operand:GPR 1 "register_operand" "0,d,0,0")
5667 (match_operand:GPR 2 "general_operand" "d,d,R,T")))
5668 (clobber (match_scratch:GPR 0 "=d,d,d,d"))]
5669 "s390_match_ccmode (insn, CCL3mode)"
5670 "@
5671 sl<g>r\t%0,%2
5672 sl<g>rk\t%0,%1,%2
5673 sl<g>\t%0,%2
5674 sl<y>\t%0,%2"
5675 [(set_attr "op_type" "RR<E>,RRF,RX<Y>,RXY")
5676 (set_attr "cpu_facility" "*,z196,*,*")
5677 (set_attr "z10prop" "z10_super_c_E1,*,z10_super_E1,z10_super_E1")])
5678
5679
5680 ;
5681 ; sub(tf|df|sf|td|dd)3 instruction pattern(s).
5682 ;
5683
5684 ; sxbr, sdbr, sebr, sdb, seb, sxtr, sdtr
5685 (define_insn "sub<mode>3"
5686 [(set (match_operand:FP 0 "register_operand" "=f, f,<vf>")
5687 (minus:FP (match_operand:FP 1 "register_operand" "<f0>, 0,<v0>")
5688 (match_operand:FP 2 "general_operand" "f,<Rf>,<vf>")))
5689 (clobber (reg:CC CC_REGNUM))]
5690 "TARGET_HARD_FLOAT"
5691 "@
5692 s<xde><bt>r\t%0,<op1>%2
5693 s<xde>b\t%0,%2
5694 wfsdb\t%v0,%v1,%v2"
5695 [(set_attr "op_type" "<RRer>,RXE,VRR")
5696 (set_attr "type" "fsimp<mode>")
5697 (set_attr "cpu_facility" "*,*,vec")])
5698
5699 ; sxbr, sdbr, sebr, sdb, seb, sxtr, sdtr
5700 (define_insn "*sub<mode>3_cc"
5701 [(set (reg CC_REGNUM)
5702 (compare (minus:FP (match_operand:FP 1 "nonimmediate_operand" "<f0>,0")
5703 (match_operand:FP 2 "general_operand" "f,<Rf>"))
5704 (match_operand:FP 3 "const0_operand" "")))
5705 (set (match_operand:FP 0 "register_operand" "=f,f")
5706 (minus:FP (match_dup 1) (match_dup 2)))]
5707 "s390_match_ccmode (insn, CCSmode) && TARGET_HARD_FLOAT"
5708 "@
5709 s<xde><bt>r\t%0,<op1>%2
5710 s<xde>b\t%0,%2"
5711 [(set_attr "op_type" "<RRer>,RXE")
5712 (set_attr "type" "fsimp<mode>")])
5713
5714 ; sxbr, sdbr, sebr, sdb, seb, sxtr, sdtr
5715 (define_insn "*sub<mode>3_cconly"
5716 [(set (reg CC_REGNUM)
5717 (compare (minus:FP (match_operand:FP 1 "nonimmediate_operand" "<f0>,0")
5718 (match_operand:FP 2 "general_operand" "f,<Rf>"))
5719 (match_operand:FP 3 "const0_operand" "")))
5720 (clobber (match_scratch:FP 0 "=f,f"))]
5721 "s390_match_ccmode (insn, CCSmode) && TARGET_HARD_FLOAT"
5722 "@
5723 s<xde><bt>r\t%0,<op1>%2
5724 s<xde>b\t%0,%2"
5725 [(set_attr "op_type" "<RRer>,RXE")
5726 (set_attr "type" "fsimp<mode>")])
5727
5728
5729 ;;
5730 ;;- Conditional add/subtract instructions.
5731 ;;
5732
5733 ;
5734 ; add(di|si)cc instruction pattern(s).
5735 ;
5736
5737 ; the following 4 patterns are used when the result of an add with
5738 ; carry is checked for an overflow condition
5739
5740 ; op1 + op2 + c < op1
5741
5742 ; alcr, alc, alcgr, alcg
5743 (define_insn "*add<mode>3_alc_carry1_cc"
5744 [(set (reg CC_REGNUM)
5745 (compare
5746 (plus:GPR (plus:GPR (match_operand:GPR 3 "s390_alc_comparison" "")
5747 (match_operand:GPR 1 "nonimmediate_operand" "%0,0"))
5748 (match_operand:GPR 2 "general_operand" "d,RT"))
5749 (match_dup 1)))
5750 (set (match_operand:GPR 0 "register_operand" "=d,d")
5751 (plus:GPR (plus:GPR (match_dup 3) (match_dup 1)) (match_dup 2)))]
5752 "s390_match_ccmode (insn, CCL1mode) && TARGET_CPU_ZARCH"
5753 "@
5754 alc<g>r\t%0,%2
5755 alc<g>\t%0,%2"
5756 [(set_attr "op_type" "RRE,RXY")
5757 (set_attr "z196prop" "z196_alone,z196_alone")])
5758
5759 ; alcr, alc, alcgr, alcg
5760 (define_insn "*add<mode>3_alc_carry1_cconly"
5761 [(set (reg CC_REGNUM)
5762 (compare
5763 (plus:GPR (plus:GPR (match_operand:GPR 3 "s390_alc_comparison" "")
5764 (match_operand:GPR 1 "nonimmediate_operand" "%0,0"))
5765 (match_operand:GPR 2 "general_operand" "d,RT"))
5766 (match_dup 1)))
5767 (clobber (match_scratch:GPR 0 "=d,d"))]
5768 "s390_match_ccmode (insn, CCL1mode) && TARGET_CPU_ZARCH"
5769 "@
5770 alc<g>r\t%0,%2
5771 alc<g>\t%0,%2"
5772 [(set_attr "op_type" "RRE,RXY")
5773 (set_attr "z196prop" "z196_alone,z196_alone")])
5774
5775 ; op1 + op2 + c < op2
5776
5777 ; alcr, alc, alcgr, alcg
5778 (define_insn "*add<mode>3_alc_carry2_cc"
5779 [(set (reg CC_REGNUM)
5780 (compare
5781 (plus:GPR (plus:GPR (match_operand:GPR 3 "s390_alc_comparison" "")
5782 (match_operand:GPR 1 "nonimmediate_operand" "%0,0"))
5783 (match_operand:GPR 2 "general_operand" "d,RT"))
5784 (match_dup 2)))
5785 (set (match_operand:GPR 0 "register_operand" "=d,d")
5786 (plus:GPR (plus:GPR (match_dup 3) (match_dup 1)) (match_dup 2)))]
5787 "s390_match_ccmode (insn, CCL1mode) && TARGET_CPU_ZARCH"
5788 "@
5789 alc<g>r\t%0,%2
5790 alc<g>\t%0,%2"
5791 [(set_attr "op_type" "RRE,RXY")])
5792
5793 ; alcr, alc, alcgr, alcg
5794 (define_insn "*add<mode>3_alc_carry2_cconly"
5795 [(set (reg CC_REGNUM)
5796 (compare
5797 (plus:GPR (plus:GPR (match_operand:GPR 3 "s390_alc_comparison" "")
5798 (match_operand:GPR 1 "nonimmediate_operand" "%0,0"))
5799 (match_operand:GPR 2 "general_operand" "d,RT"))
5800 (match_dup 2)))
5801 (clobber (match_scratch:GPR 0 "=d,d"))]
5802 "s390_match_ccmode (insn, CCL1mode) && TARGET_CPU_ZARCH"
5803 "@
5804 alc<g>r\t%0,%2
5805 alc<g>\t%0,%2"
5806 [(set_attr "op_type" "RRE,RXY")])
5807
5808 ; alcr, alc, alcgr, alcg
5809 (define_insn "*add<mode>3_alc_cc"
5810 [(set (reg CC_REGNUM)
5811 (compare
5812 (plus:GPR (plus:GPR (match_operand:GPR 3 "s390_alc_comparison" "")
5813 (match_operand:GPR 1 "nonimmediate_operand" "%0,0"))
5814 (match_operand:GPR 2 "general_operand" "d,RT"))
5815 (const_int 0)))
5816 (set (match_operand:GPR 0 "register_operand" "=d,d")
5817 (plus:GPR (plus:GPR (match_dup 3) (match_dup 1)) (match_dup 2)))]
5818 "s390_match_ccmode (insn, CCLmode) && TARGET_CPU_ZARCH"
5819 "@
5820 alc<g>r\t%0,%2
5821 alc<g>\t%0,%2"
5822 [(set_attr "op_type" "RRE,RXY")])
5823
5824 ; alcr, alc, alcgr, alcg
5825 (define_insn "*add<mode>3_alc"
5826 [(set (match_operand:GPR 0 "register_operand" "=d,d")
5827 (plus:GPR (plus:GPR (match_operand:GPR 3 "s390_alc_comparison" "")
5828 (match_operand:GPR 1 "nonimmediate_operand" "%0,0"))
5829 (match_operand:GPR 2 "general_operand" "d,RT")))
5830 (clobber (reg:CC CC_REGNUM))]
5831 "TARGET_CPU_ZARCH"
5832 "@
5833 alc<g>r\t%0,%2
5834 alc<g>\t%0,%2"
5835 [(set_attr "op_type" "RRE,RXY")])
5836
5837 ; slbr, slb, slbgr, slbg
5838 (define_insn "*sub<mode>3_slb_cc"
5839 [(set (reg CC_REGNUM)
5840 (compare
5841 (minus:GPR (minus:GPR (match_operand:GPR 1 "nonimmediate_operand" "0,0")
5842 (match_operand:GPR 2 "general_operand" "d,RT"))
5843 (match_operand:GPR 3 "s390_slb_comparison" ""))
5844 (const_int 0)))
5845 (set (match_operand:GPR 0 "register_operand" "=d,d")
5846 (minus:GPR (minus:GPR (match_dup 1) (match_dup 2)) (match_dup 3)))]
5847 "s390_match_ccmode (insn, CCLmode) && TARGET_CPU_ZARCH"
5848 "@
5849 slb<g>r\t%0,%2
5850 slb<g>\t%0,%2"
5851 [(set_attr "op_type" "RRE,RXY")
5852 (set_attr "z10prop" "z10_c,*")])
5853
5854 ; slbr, slb, slbgr, slbg
5855 (define_insn "*sub<mode>3_slb"
5856 [(set (match_operand:GPR 0 "register_operand" "=d,d")
5857 (minus:GPR (minus:GPR (match_operand:GPR 1 "nonimmediate_operand" "0,0")
5858 (match_operand:GPR 2 "general_operand" "d,RT"))
5859 (match_operand:GPR 3 "s390_slb_comparison" "")))
5860 (clobber (reg:CC CC_REGNUM))]
5861 "TARGET_CPU_ZARCH"
5862 "@
5863 slb<g>r\t%0,%2
5864 slb<g>\t%0,%2"
5865 [(set_attr "op_type" "RRE,RXY")
5866 (set_attr "z10prop" "z10_c,*")])
5867
5868 (define_expand "add<mode>cc"
5869 [(match_operand:GPR 0 "register_operand" "")
5870 (match_operand 1 "comparison_operator" "")
5871 (match_operand:GPR 2 "register_operand" "")
5872 (match_operand:GPR 3 "const_int_operand" "")]
5873 "TARGET_CPU_ZARCH"
5874 "if (!s390_expand_addcc (GET_CODE (operands[1]),
5875 XEXP (operands[1], 0), XEXP (operands[1], 1),
5876 operands[0], operands[2],
5877 operands[3])) FAIL; DONE;")
5878
5879 ;
5880 ; scond instruction pattern(s).
5881 ;
5882
5883 (define_insn_and_split "*scond<mode>"
5884 [(set (match_operand:GPR 0 "register_operand" "=&d")
5885 (match_operand:GPR 1 "s390_alc_comparison" ""))
5886 (clobber (reg:CC CC_REGNUM))]
5887 "TARGET_CPU_ZARCH"
5888 "#"
5889 "&& reload_completed"
5890 [(set (match_dup 0) (const_int 0))
5891 (parallel
5892 [(set (match_dup 0) (plus:GPR (plus:GPR (match_dup 1) (match_dup 0))
5893 (match_dup 0)))
5894 (clobber (reg:CC CC_REGNUM))])]
5895 "")
5896
5897 (define_insn_and_split "*scond<mode>_neg"
5898 [(set (match_operand:GPR 0 "register_operand" "=&d")
5899 (match_operand:GPR 1 "s390_slb_comparison" ""))
5900 (clobber (reg:CC CC_REGNUM))]
5901 "TARGET_CPU_ZARCH"
5902 "#"
5903 "&& reload_completed"
5904 [(set (match_dup 0) (const_int 0))
5905 (parallel
5906 [(set (match_dup 0) (minus:GPR (minus:GPR (match_dup 0) (match_dup 0))
5907 (match_dup 1)))
5908 (clobber (reg:CC CC_REGNUM))])
5909 (parallel
5910 [(set (match_dup 0) (neg:GPR (match_dup 0)))
5911 (clobber (reg:CC CC_REGNUM))])]
5912 "")
5913
5914
5915 (define_expand "cstore<mode>4"
5916 [(set (match_operand:SI 0 "register_operand" "")
5917 (match_operator:SI 1 "s390_scond_operator"
5918 [(match_operand:GPR 2 "register_operand" "")
5919 (match_operand:GPR 3 "general_operand" "")]))]
5920 "TARGET_CPU_ZARCH"
5921 "if (!s390_expand_addcc (GET_CODE (operands[1]), operands[2], operands[3],
5922 operands[0], const0_rtx, const1_rtx)) FAIL; DONE;")
5923
5924 (define_expand "cstorecc4"
5925 [(parallel
5926 [(set (match_operand:SI 0 "register_operand" "")
5927 (match_operator:SI 1 "s390_eqne_operator"
5928 [(match_operand:CCZ1 2 "register_operand")
5929 (match_operand 3 "const0_operand")]))
5930 (clobber (reg:CC CC_REGNUM))])]
5931 ""
5932 "emit_insn (gen_sne (operands[0], operands[2]));
5933 if (GET_CODE (operands[1]) == EQ)
5934 emit_insn (gen_xorsi3 (operands[0], operands[0], const1_rtx));
5935 DONE;")
5936
5937 (define_insn_and_split "sne"
5938 [(set (match_operand:SI 0 "register_operand" "=d")
5939 (ne:SI (match_operand:CCZ1 1 "register_operand" "0")
5940 (const_int 0)))
5941 (clobber (reg:CC CC_REGNUM))]
5942 ""
5943 "#"
5944 "reload_completed"
5945 [(parallel
5946 [(set (match_dup 0) (ashiftrt:SI (match_dup 0) (const_int 28)))
5947 (clobber (reg:CC CC_REGNUM))])])
5948
5949
5950 ;;
5951 ;; - Conditional move instructions (introduced with z196)
5952 ;;
5953
5954 (define_expand "mov<mode>cc"
5955 [(set (match_operand:GPR 0 "nonimmediate_operand" "")
5956 (if_then_else:GPR (match_operand 1 "comparison_operator" "")
5957 (match_operand:GPR 2 "nonimmediate_operand" "")
5958 (match_operand:GPR 3 "nonimmediate_operand" "")))]
5959 "TARGET_Z196"
5960 "operands[1] = s390_emit_compare (GET_CODE (operands[1]),
5961 XEXP (operands[1], 0), XEXP (operands[1], 1));")
5962
5963 ; locr, loc, stoc, locgr, locg, stocg
5964 (define_insn_and_split "*mov<mode>cc"
5965 [(set (match_operand:GPR 0 "nonimmediate_operand" "=d,d, d, d,QS,QS,&d")
5966 (if_then_else:GPR
5967 (match_operator 1 "s390_comparison"
5968 [(match_operand 2 "cc_reg_operand" " c,c, c, c, c, c, c")
5969 (match_operand 5 "const_int_operand" "")])
5970 (match_operand:GPR 3 "nonimmediate_operand" " d,0,QS, 0, d, 0,QS")
5971 (match_operand:GPR 4 "nonimmediate_operand" " 0,d, 0,QS, 0, d,QS")))]
5972 "TARGET_Z196"
5973 "@
5974 loc<g>r%C1\t%0,%3
5975 loc<g>r%D1\t%0,%4
5976 loc<g>%C1\t%0,%3
5977 loc<g>%D1\t%0,%4
5978 stoc<g>%C1\t%3,%0
5979 stoc<g>%D1\t%4,%0
5980 #"
5981 "&& reload_completed
5982 && MEM_P (operands[3]) && MEM_P (operands[4])"
5983 [(set (match_dup 0)
5984 (if_then_else:GPR
5985 (match_op_dup 1 [(match_dup 2) (const_int 0)])
5986 (match_dup 3)
5987 (match_dup 0)))
5988 (set (match_dup 0)
5989 (if_then_else:GPR
5990 (match_op_dup 1 [(match_dup 2) (const_int 0)])
5991 (match_dup 0)
5992 (match_dup 4)))]
5993 ""
5994 [(set_attr "op_type" "RRF,RRF,RSY,RSY,RSY,RSY,*")])
5995
5996 ;;
5997 ;;- Multiply instructions.
5998 ;;
5999
6000 ;
6001 ; muldi3 instruction pattern(s).
6002 ;
6003
6004 (define_insn "*muldi3_sign"
6005 [(set (match_operand:DI 0 "register_operand" "=d,d")
6006 (mult:DI (sign_extend:DI (match_operand:SI 2 "general_operand" "d,RT"))
6007 (match_operand:DI 1 "register_operand" "0,0")))]
6008 "TARGET_ZARCH"
6009 "@
6010 msgfr\t%0,%2
6011 msgf\t%0,%2"
6012 [(set_attr "op_type" "RRE,RXY")
6013 (set_attr "type" "imuldi")])
6014
6015 (define_insn "muldi3"
6016 [(set (match_operand:DI 0 "register_operand" "=d,d,d,d")
6017 (mult:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,0")
6018 (match_operand:DI 2 "general_operand" "d,K,RT,Os")))]
6019 "TARGET_ZARCH"
6020 "@
6021 msgr\t%0,%2
6022 mghi\t%0,%h2
6023 msg\t%0,%2
6024 msgfi\t%0,%2"
6025 [(set_attr "op_type" "RRE,RI,RXY,RIL")
6026 (set_attr "type" "imuldi")
6027 (set_attr "cpu_facility" "*,*,*,z10")])
6028
6029 ;
6030 ; mulsi3 instruction pattern(s).
6031 ;
6032
6033 (define_insn "*mulsi3_sign"
6034 [(set (match_operand:SI 0 "register_operand" "=d,d")
6035 (mult:SI (sign_extend:SI (match_operand:HI 2 "memory_operand" "R,T"))
6036 (match_operand:SI 1 "register_operand" "0,0")))]
6037 ""
6038 "@
6039 mh\t%0,%2
6040 mhy\t%0,%2"
6041 [(set_attr "op_type" "RX,RXY")
6042 (set_attr "type" "imulhi")
6043 (set_attr "cpu_facility" "*,z10")])
6044
6045 (define_insn "mulsi3"
6046 [(set (match_operand:SI 0 "register_operand" "=d,d,d,d,d")
6047 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,0,0,0")
6048 (match_operand:SI 2 "general_operand" "d,K,R,T,Os")))]
6049 ""
6050 "@
6051 msr\t%0,%2
6052 mhi\t%0,%h2
6053 ms\t%0,%2
6054 msy\t%0,%2
6055 msfi\t%0,%2"
6056 [(set_attr "op_type" "RRE,RI,RX,RXY,RIL")
6057 (set_attr "type" "imulsi,imulhi,imulsi,imulsi,imulsi")
6058 (set_attr "cpu_facility" "*,*,*,*,z10")])
6059
6060 ;
6061 ; mulsidi3 instruction pattern(s).
6062 ;
6063
6064 (define_insn "mulsidi3"
6065 [(set (match_operand:DI 0 "register_operand" "=d,d,d")
6066 (mult:DI (sign_extend:DI
6067 (match_operand:SI 1 "register_operand" "%0,0,0"))
6068 (sign_extend:DI
6069 (match_operand:SI 2 "nonimmediate_operand" "d,R,T"))))]
6070 "!TARGET_ZARCH"
6071 "@
6072 mr\t%0,%2
6073 m\t%0,%2
6074 mfy\t%0,%2"
6075 [(set_attr "op_type" "RR,RX,RXY")
6076 (set_attr "type" "imulsi")
6077 (set_attr "cpu_facility" "*,*,z10")])
6078
6079 ;
6080 ; umul instruction pattern(s).
6081 ;
6082
6083 ; mlr, ml, mlgr, mlg
6084 (define_insn "umul<dwh><mode>3"
6085 [(set (match_operand:DW 0 "register_operand" "=d, d")
6086 (mult:DW (zero_extend:DW
6087 (match_operand:<DWH> 1 "register_operand" "%0, 0"))
6088 (zero_extend:DW
6089 (match_operand:<DWH> 2 "nonimmediate_operand" " d,RT"))))]
6090 "TARGET_CPU_ZARCH"
6091 "@
6092 ml<tg>r\t%0,%2
6093 ml<tg>\t%0,%2"
6094 [(set_attr "op_type" "RRE,RXY")
6095 (set_attr "type" "imul<dwh>")])
6096
6097 ;
6098 ; mul(tf|df|sf|td|dd)3 instruction pattern(s).
6099 ;
6100
6101 ; mxbr, mdbr, meebr, mxb, mxb, meeb, mdtr, mxtr
6102 (define_insn "mul<mode>3"
6103 [(set (match_operand:FP 0 "register_operand" "=f, f,<vf>")
6104 (mult:FP (match_operand:FP 1 "nonimmediate_operand" "%<f0>, 0,<v0>")
6105 (match_operand:FP 2 "general_operand" "f,<Rf>,<vf>")))]
6106 "TARGET_HARD_FLOAT"
6107 "@
6108 m<xdee><bt>r\t%0,<op1>%2
6109 m<xdee>b\t%0,%2
6110 wfmdb\t%v0,%v1,%v2"
6111 [(set_attr "op_type" "<RRer>,RXE,VRR")
6112 (set_attr "type" "fmul<mode>")
6113 (set_attr "cpu_facility" "*,*,vec")])
6114
6115 ; madbr, maebr, maxb, madb, maeb
6116 (define_insn "fma<mode>4"
6117 [(set (match_operand:DSF 0 "register_operand" "=f,f,<vf>")
6118 (fma:DSF (match_operand:DSF 1 "nonimmediate_operand" "%f,f,<vf>")
6119 (match_operand:DSF 2 "nonimmediate_operand" "f,R,<vf>")
6120 (match_operand:DSF 3 "register_operand" "0,0,<v0>")))]
6121 "TARGET_HARD_FLOAT"
6122 "@
6123 ma<xde>br\t%0,%1,%2
6124 ma<xde>b\t%0,%1,%2
6125 wfmadb\t%v0,%v1,%v2,%v3"
6126 [(set_attr "op_type" "RRE,RXE,VRR")
6127 (set_attr "type" "fmadd<mode>")
6128 (set_attr "cpu_facility" "*,*,vec")])
6129
6130 ; msxbr, msdbr, msebr, msxb, msdb, mseb
6131 (define_insn "fms<mode>4"
6132 [(set (match_operand:DSF 0 "register_operand" "=f,f,<vf>")
6133 (fma:DSF (match_operand:DSF 1 "nonimmediate_operand" "%f,f,<vf>")
6134 (match_operand:DSF 2 "nonimmediate_operand" "f,R,<vf>")
6135 (neg:DSF (match_operand:DSF 3 "register_operand" "0,0,<v0>"))))]
6136 "TARGET_HARD_FLOAT"
6137 "@
6138 ms<xde>br\t%0,%1,%2
6139 ms<xde>b\t%0,%1,%2
6140 wfmsdb\t%v0,%v1,%v2,%v3"
6141 [(set_attr "op_type" "RRE,RXE,VRR")
6142 (set_attr "type" "fmadd<mode>")
6143 (set_attr "cpu_facility" "*,*,vec")])
6144
6145 ;;
6146 ;;- Divide and modulo instructions.
6147 ;;
6148
6149 ;
6150 ; divmoddi4 instruction pattern(s).
6151 ;
6152
6153 (define_expand "divmoddi4"
6154 [(parallel [(set (match_operand:DI 0 "general_operand" "")
6155 (div:DI (match_operand:DI 1 "register_operand" "")
6156 (match_operand:DI 2 "general_operand" "")))
6157 (set (match_operand:DI 3 "general_operand" "")
6158 (mod:DI (match_dup 1) (match_dup 2)))])
6159 (clobber (match_dup 4))]
6160 "TARGET_ZARCH"
6161 {
6162 rtx insn, div_equal, mod_equal;
6163
6164 div_equal = gen_rtx_DIV (DImode, operands[1], operands[2]);
6165 mod_equal = gen_rtx_MOD (DImode, operands[1], operands[2]);
6166
6167 operands[4] = gen_reg_rtx(TImode);
6168 emit_insn (gen_divmodtidi3 (operands[4], operands[1], operands[2]));
6169
6170 insn = emit_move_insn (operands[0], gen_lowpart (DImode, operands[4]));
6171 set_unique_reg_note (insn, REG_EQUAL, div_equal);
6172
6173 insn = emit_move_insn (operands[3], gen_highpart (DImode, operands[4]));
6174 set_unique_reg_note (insn, REG_EQUAL, mod_equal);
6175
6176 DONE;
6177 })
6178
6179 (define_insn "divmodtidi3"
6180 [(set (match_operand:TI 0 "register_operand" "=d,d")
6181 (ior:TI
6182 (ashift:TI
6183 (zero_extend:TI
6184 (mod:DI (match_operand:DI 1 "register_operand" "0,0")
6185 (match_operand:DI 2 "general_operand" "d,RT")))
6186 (const_int 64))
6187 (zero_extend:TI (div:DI (match_dup 1) (match_dup 2)))))]
6188 "TARGET_ZARCH"
6189 "@
6190 dsgr\t%0,%2
6191 dsg\t%0,%2"
6192 [(set_attr "op_type" "RRE,RXY")
6193 (set_attr "type" "idiv")])
6194
6195 (define_insn "divmodtisi3"
6196 [(set (match_operand:TI 0 "register_operand" "=d,d")
6197 (ior:TI
6198 (ashift:TI
6199 (zero_extend:TI
6200 (mod:DI (match_operand:DI 1 "register_operand" "0,0")
6201 (sign_extend:DI
6202 (match_operand:SI 2 "nonimmediate_operand" "d,RT"))))
6203 (const_int 64))
6204 (zero_extend:TI
6205 (div:DI (match_dup 1) (sign_extend:DI (match_dup 2))))))]
6206 "TARGET_ZARCH"
6207 "@
6208 dsgfr\t%0,%2
6209 dsgf\t%0,%2"
6210 [(set_attr "op_type" "RRE,RXY")
6211 (set_attr "type" "idiv")])
6212
6213 ;
6214 ; udivmoddi4 instruction pattern(s).
6215 ;
6216
6217 (define_expand "udivmoddi4"
6218 [(parallel [(set (match_operand:DI 0 "general_operand" "")
6219 (udiv:DI (match_operand:DI 1 "general_operand" "")
6220 (match_operand:DI 2 "nonimmediate_operand" "")))
6221 (set (match_operand:DI 3 "general_operand" "")
6222 (umod:DI (match_dup 1) (match_dup 2)))])
6223 (clobber (match_dup 4))]
6224 "TARGET_ZARCH"
6225 {
6226 rtx insn, div_equal, mod_equal, equal;
6227
6228 div_equal = gen_rtx_UDIV (DImode, operands[1], operands[2]);
6229 mod_equal = gen_rtx_UMOD (DImode, operands[1], operands[2]);
6230 equal = gen_rtx_IOR (TImode,
6231 gen_rtx_ASHIFT (TImode,
6232 gen_rtx_ZERO_EXTEND (TImode, mod_equal),
6233 GEN_INT (64)),
6234 gen_rtx_ZERO_EXTEND (TImode, div_equal));
6235
6236 operands[4] = gen_reg_rtx(TImode);
6237 emit_clobber (operands[4]);
6238 emit_move_insn (gen_lowpart (DImode, operands[4]), operands[1]);
6239 emit_move_insn (gen_highpart (DImode, operands[4]), const0_rtx);
6240
6241 insn = emit_insn (gen_udivmodtidi3 (operands[4], operands[4], operands[2]));
6242 set_unique_reg_note (insn, REG_EQUAL, equal);
6243
6244 insn = emit_move_insn (operands[0], gen_lowpart (DImode, operands[4]));
6245 set_unique_reg_note (insn, REG_EQUAL, div_equal);
6246
6247 insn = emit_move_insn (operands[3], gen_highpart (DImode, operands[4]));
6248 set_unique_reg_note (insn, REG_EQUAL, mod_equal);
6249
6250 DONE;
6251 })
6252
6253 (define_insn "udivmodtidi3"
6254 [(set (match_operand:TI 0 "register_operand" "=d,d")
6255 (ior:TI
6256 (ashift:TI
6257 (zero_extend:TI
6258 (truncate:DI
6259 (umod:TI (match_operand:TI 1 "register_operand" "0,0")
6260 (zero_extend:TI
6261 (match_operand:DI 2 "nonimmediate_operand" "d,RT")))))
6262 (const_int 64))
6263 (zero_extend:TI
6264 (truncate:DI
6265 (udiv:TI (match_dup 1) (zero_extend:TI (match_dup 2)))))))]
6266 "TARGET_ZARCH"
6267 "@
6268 dlgr\t%0,%2
6269 dlg\t%0,%2"
6270 [(set_attr "op_type" "RRE,RXY")
6271 (set_attr "type" "idiv")])
6272
6273 ;
6274 ; divmodsi4 instruction pattern(s).
6275 ;
6276
6277 (define_expand "divmodsi4"
6278 [(parallel [(set (match_operand:SI 0 "general_operand" "")
6279 (div:SI (match_operand:SI 1 "general_operand" "")
6280 (match_operand:SI 2 "nonimmediate_operand" "")))
6281 (set (match_operand:SI 3 "general_operand" "")
6282 (mod:SI (match_dup 1) (match_dup 2)))])
6283 (clobber (match_dup 4))]
6284 "!TARGET_ZARCH"
6285 {
6286 rtx insn, div_equal, mod_equal, equal;
6287
6288 div_equal = gen_rtx_DIV (SImode, operands[1], operands[2]);
6289 mod_equal = gen_rtx_MOD (SImode, operands[1], operands[2]);
6290 equal = gen_rtx_IOR (DImode,
6291 gen_rtx_ASHIFT (DImode,
6292 gen_rtx_ZERO_EXTEND (DImode, mod_equal),
6293 GEN_INT (32)),
6294 gen_rtx_ZERO_EXTEND (DImode, div_equal));
6295
6296 operands[4] = gen_reg_rtx(DImode);
6297 emit_insn (gen_extendsidi2 (operands[4], operands[1]));
6298
6299 insn = emit_insn (gen_divmoddisi3 (operands[4], operands[4], operands[2]));
6300 set_unique_reg_note (insn, REG_EQUAL, equal);
6301
6302 insn = emit_move_insn (operands[0], gen_lowpart (SImode, operands[4]));
6303 set_unique_reg_note (insn, REG_EQUAL, div_equal);
6304
6305 insn = emit_move_insn (operands[3], gen_highpart (SImode, operands[4]));
6306 set_unique_reg_note (insn, REG_EQUAL, mod_equal);
6307
6308 DONE;
6309 })
6310
6311 (define_insn "divmoddisi3"
6312 [(set (match_operand:DI 0 "register_operand" "=d,d")
6313 (ior:DI
6314 (ashift:DI
6315 (zero_extend:DI
6316 (truncate:SI
6317 (mod:DI (match_operand:DI 1 "register_operand" "0,0")
6318 (sign_extend:DI
6319 (match_operand:SI 2 "nonimmediate_operand" "d,R")))))
6320 (const_int 32))
6321 (zero_extend:DI
6322 (truncate:SI
6323 (div:DI (match_dup 1) (sign_extend:DI (match_dup 2)))))))]
6324 "!TARGET_ZARCH"
6325 "@
6326 dr\t%0,%2
6327 d\t%0,%2"
6328 [(set_attr "op_type" "RR,RX")
6329 (set_attr "type" "idiv")])
6330
6331 ;
6332 ; udivsi3 and umodsi3 instruction pattern(s).
6333 ;
6334
6335 (define_expand "udivmodsi4"
6336 [(parallel [(set (match_operand:SI 0 "general_operand" "")
6337 (udiv:SI (match_operand:SI 1 "general_operand" "")
6338 (match_operand:SI 2 "nonimmediate_operand" "")))
6339 (set (match_operand:SI 3 "general_operand" "")
6340 (umod:SI (match_dup 1) (match_dup 2)))])
6341 (clobber (match_dup 4))]
6342 "!TARGET_ZARCH && TARGET_CPU_ZARCH"
6343 {
6344 rtx insn, div_equal, mod_equal, equal;
6345
6346 div_equal = gen_rtx_UDIV (SImode, operands[1], operands[2]);
6347 mod_equal = gen_rtx_UMOD (SImode, operands[1], operands[2]);
6348 equal = gen_rtx_IOR (DImode,
6349 gen_rtx_ASHIFT (DImode,
6350 gen_rtx_ZERO_EXTEND (DImode, mod_equal),
6351 GEN_INT (32)),
6352 gen_rtx_ZERO_EXTEND (DImode, div_equal));
6353
6354 operands[4] = gen_reg_rtx(DImode);
6355 emit_clobber (operands[4]);
6356 emit_move_insn (gen_lowpart (SImode, operands[4]), operands[1]);
6357 emit_move_insn (gen_highpart (SImode, operands[4]), const0_rtx);
6358
6359 insn = emit_insn (gen_udivmoddisi3 (operands[4], operands[4], operands[2]));
6360 set_unique_reg_note (insn, REG_EQUAL, equal);
6361
6362 insn = emit_move_insn (operands[0], gen_lowpart (SImode, operands[4]));
6363 set_unique_reg_note (insn, REG_EQUAL, div_equal);
6364
6365 insn = emit_move_insn (operands[3], gen_highpart (SImode, operands[4]));
6366 set_unique_reg_note (insn, REG_EQUAL, mod_equal);
6367
6368 DONE;
6369 })
6370
6371 (define_insn "udivmoddisi3"
6372 [(set (match_operand:DI 0 "register_operand" "=d,d")
6373 (ior:DI
6374 (ashift:DI
6375 (zero_extend:DI
6376 (truncate:SI
6377 (umod:DI (match_operand:DI 1 "register_operand" "0,0")
6378 (zero_extend:DI
6379 (match_operand:SI 2 "nonimmediate_operand" "d,RT")))))
6380 (const_int 32))
6381 (zero_extend:DI
6382 (truncate:SI
6383 (udiv:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))))]
6384 "!TARGET_ZARCH && TARGET_CPU_ZARCH"
6385 "@
6386 dlr\t%0,%2
6387 dl\t%0,%2"
6388 [(set_attr "op_type" "RRE,RXY")
6389 (set_attr "type" "idiv")])
6390
6391 (define_expand "udivsi3"
6392 [(set (match_operand:SI 0 "register_operand" "=d")
6393 (udiv:SI (match_operand:SI 1 "general_operand" "")
6394 (match_operand:SI 2 "general_operand" "")))
6395 (clobber (match_dup 3))]
6396 "!TARGET_ZARCH && !TARGET_CPU_ZARCH"
6397 {
6398 rtx insn, udiv_equal, umod_equal, equal;
6399
6400 udiv_equal = gen_rtx_UDIV (SImode, operands[1], operands[2]);
6401 umod_equal = gen_rtx_UMOD (SImode, operands[1], operands[2]);
6402 equal = gen_rtx_IOR (DImode,
6403 gen_rtx_ASHIFT (DImode,
6404 gen_rtx_ZERO_EXTEND (DImode, umod_equal),
6405 GEN_INT (32)),
6406 gen_rtx_ZERO_EXTEND (DImode, udiv_equal));
6407
6408 operands[3] = gen_reg_rtx (DImode);
6409
6410 if (CONSTANT_P (operands[2]))
6411 {
6412 if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0)
6413 {
6414 rtx_code_label *label1 = gen_label_rtx ();
6415
6416 operands[1] = make_safe_from (operands[1], operands[0]);
6417 emit_move_insn (operands[0], const0_rtx);
6418 emit_cmp_and_jump_insns (operands[1], operands[2], LT, NULL_RTX,
6419 SImode, 1, label1);
6420 emit_move_insn (operands[0], const1_rtx);
6421 emit_label (label1);
6422 }
6423 else
6424 {
6425 operands[2] = force_reg (SImode, operands[2]);
6426 operands[2] = make_safe_from (operands[2], operands[0]);
6427
6428 emit_insn (gen_zero_extendsidi2 (operands[3], operands[1]));
6429 insn = emit_insn (gen_divmoddisi3 (operands[3], operands[3],
6430 operands[2]));
6431 set_unique_reg_note (insn, REG_EQUAL, equal);
6432
6433 insn = emit_move_insn (operands[0],
6434 gen_lowpart (SImode, operands[3]));
6435 set_unique_reg_note (insn, REG_EQUAL, udiv_equal);
6436 }
6437 }
6438 else
6439 {
6440 rtx_code_label *label1 = gen_label_rtx ();
6441 rtx_code_label *label2 = gen_label_rtx ();
6442 rtx_code_label *label3 = gen_label_rtx ();
6443
6444 operands[1] = force_reg (SImode, operands[1]);
6445 operands[1] = make_safe_from (operands[1], operands[0]);
6446 operands[2] = force_reg (SImode, operands[2]);
6447 operands[2] = make_safe_from (operands[2], operands[0]);
6448
6449 emit_move_insn (operands[0], const0_rtx);
6450 emit_cmp_and_jump_insns (operands[2], operands[1], GT, NULL_RTX,
6451 SImode, 1, label3);
6452 emit_cmp_and_jump_insns (operands[2], const0_rtx, LT, NULL_RTX,
6453 SImode, 0, label2);
6454 emit_cmp_and_jump_insns (operands[2], const1_rtx, EQ, NULL_RTX,
6455 SImode, 0, label1);
6456 emit_insn (gen_zero_extendsidi2 (operands[3], operands[1]));
6457 insn = emit_insn (gen_divmoddisi3 (operands[3], operands[3],
6458 operands[2]));
6459 set_unique_reg_note (insn, REG_EQUAL, equal);
6460
6461 insn = emit_move_insn (operands[0],
6462 gen_lowpart (SImode, operands[3]));
6463 set_unique_reg_note (insn, REG_EQUAL, udiv_equal);
6464
6465 emit_jump (label3);
6466 emit_label (label1);
6467 emit_move_insn (operands[0], operands[1]);
6468 emit_jump (label3);
6469 emit_label (label2);
6470 emit_move_insn (operands[0], const1_rtx);
6471 emit_label (label3);
6472 }
6473 emit_move_insn (operands[0], operands[0]);
6474 DONE;
6475 })
6476
6477 (define_expand "umodsi3"
6478 [(set (match_operand:SI 0 "register_operand" "=d")
6479 (umod:SI (match_operand:SI 1 "nonimmediate_operand" "")
6480 (match_operand:SI 2 "nonimmediate_operand" "")))
6481 (clobber (match_dup 3))]
6482 "!TARGET_ZARCH && !TARGET_CPU_ZARCH"
6483 {
6484 rtx insn, udiv_equal, umod_equal, equal;
6485
6486 udiv_equal = gen_rtx_UDIV (SImode, operands[1], operands[2]);
6487 umod_equal = gen_rtx_UMOD (SImode, operands[1], operands[2]);
6488 equal = gen_rtx_IOR (DImode,
6489 gen_rtx_ASHIFT (DImode,
6490 gen_rtx_ZERO_EXTEND (DImode, umod_equal),
6491 GEN_INT (32)),
6492 gen_rtx_ZERO_EXTEND (DImode, udiv_equal));
6493
6494 operands[3] = gen_reg_rtx (DImode);
6495
6496 if (CONSTANT_P (operands[2]))
6497 {
6498 if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) <= 0)
6499 {
6500 rtx_code_label *label1 = gen_label_rtx ();
6501
6502 operands[1] = make_safe_from (operands[1], operands[0]);
6503 emit_move_insn (operands[0], operands[1]);
6504 emit_cmp_and_jump_insns (operands[0], operands[2], LT, NULL_RTX,
6505 SImode, 1, label1);
6506 emit_insn (gen_abssi2 (operands[0], operands[2]));
6507 emit_insn (gen_addsi3 (operands[0], operands[0], operands[1]));
6508 emit_label (label1);
6509 }
6510 else
6511 {
6512 operands[2] = force_reg (SImode, operands[2]);
6513 operands[2] = make_safe_from (operands[2], operands[0]);
6514
6515 emit_insn (gen_zero_extendsidi2 (operands[3], operands[1]));
6516 insn = emit_insn (gen_divmoddisi3 (operands[3], operands[3],
6517 operands[2]));
6518 set_unique_reg_note (insn, REG_EQUAL, equal);
6519
6520 insn = emit_move_insn (operands[0],
6521 gen_highpart (SImode, operands[3]));
6522 set_unique_reg_note (insn, REG_EQUAL, umod_equal);
6523 }
6524 }
6525 else
6526 {
6527 rtx_code_label *label1 = gen_label_rtx ();
6528 rtx_code_label *label2 = gen_label_rtx ();
6529 rtx_code_label *label3 = gen_label_rtx ();
6530
6531 operands[1] = force_reg (SImode, operands[1]);
6532 operands[1] = make_safe_from (operands[1], operands[0]);
6533 operands[2] = force_reg (SImode, operands[2]);
6534 operands[2] = make_safe_from (operands[2], operands[0]);
6535
6536 emit_move_insn(operands[0], operands[1]);
6537 emit_cmp_and_jump_insns (operands[2], operands[1], GT, NULL_RTX,
6538 SImode, 1, label3);
6539 emit_cmp_and_jump_insns (operands[2], const0_rtx, LT, NULL_RTX,
6540 SImode, 0, label2);
6541 emit_cmp_and_jump_insns (operands[2], const1_rtx, EQ, NULL_RTX,
6542 SImode, 0, label1);
6543 emit_insn (gen_zero_extendsidi2 (operands[3], operands[1]));
6544 insn = emit_insn (gen_divmoddisi3 (operands[3], operands[3],
6545 operands[2]));
6546 set_unique_reg_note (insn, REG_EQUAL, equal);
6547
6548 insn = emit_move_insn (operands[0],
6549 gen_highpart (SImode, operands[3]));
6550 set_unique_reg_note (insn, REG_EQUAL, umod_equal);
6551
6552 emit_jump (label3);
6553 emit_label (label1);
6554 emit_move_insn (operands[0], const0_rtx);
6555 emit_jump (label3);
6556 emit_label (label2);
6557 emit_insn (gen_subsi3 (operands[0], operands[0], operands[2]));
6558 emit_label (label3);
6559 }
6560 DONE;
6561 })
6562
6563 ;
6564 ; div(df|sf)3 instruction pattern(s).
6565 ;
6566
6567 ; dxbr, ddbr, debr, dxb, ddb, deb, ddtr, dxtr
6568 (define_insn "div<mode>3"
6569 [(set (match_operand:FP 0 "register_operand" "=f, f,<vf>")
6570 (div:FP (match_operand:FP 1 "register_operand" "<f0>, 0,<v0>")
6571 (match_operand:FP 2 "general_operand" "f,<Rf>,<vf>")))]
6572 "TARGET_HARD_FLOAT"
6573 "@
6574 d<xde><bt>r\t%0,<op1>%2
6575 d<xde>b\t%0,%2
6576 wfddb\t%v0,%v1,%v2"
6577 [(set_attr "op_type" "<RRer>,RXE,VRR")
6578 (set_attr "type" "fdiv<mode>")
6579 (set_attr "cpu_facility" "*,*,vec")])
6580
6581
6582 ;;
6583 ;;- And instructions.
6584 ;;
6585
6586 (define_expand "and<mode>3"
6587 [(set (match_operand:INT 0 "nonimmediate_operand" "")
6588 (and:INT (match_operand:INT 1 "nonimmediate_operand" "")
6589 (match_operand:INT 2 "general_operand" "")))
6590 (clobber (reg:CC CC_REGNUM))]
6591 ""
6592 "s390_expand_logical_operator (AND, <MODE>mode, operands); DONE;")
6593
6594 ;
6595 ; anddi3 instruction pattern(s).
6596 ;
6597
6598 (define_insn "*anddi3_cc"
6599 [(set (reg CC_REGNUM)
6600 (compare
6601 (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,d, 0, d")
6602 (match_operand:DI 2 "general_operand" " d,d,RT,NxxDq"))
6603 (const_int 0)))
6604 (set (match_operand:DI 0 "register_operand" "=d,d, d, d")
6605 (and:DI (match_dup 1) (match_dup 2)))]
6606 "TARGET_ZARCH && s390_match_ccmode(insn, CCTmode)"
6607 "@
6608 ngr\t%0,%2
6609 ngrk\t%0,%1,%2
6610 ng\t%0,%2
6611 risbg\t%0,%1,%s2,128+%e2,0"
6612 [(set_attr "op_type" "RRE,RRF,RXY,RIE")
6613 (set_attr "cpu_facility" "*,z196,*,z10")
6614 (set_attr "z10prop" "z10_super_E1,*,z10_super_E1,z10_super_E1")])
6615
6616 (define_insn "*anddi3_cconly"
6617 [(set (reg CC_REGNUM)
6618 (compare
6619 (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,d, 0, d")
6620 (match_operand:DI 2 "general_operand" " d,d,RT,NxxDq"))
6621 (const_int 0)))
6622 (clobber (match_scratch:DI 0 "=d,d, d, d"))]
6623 "TARGET_ZARCH
6624 && s390_match_ccmode(insn, CCTmode)
6625 /* Do not steal TM patterns. */
6626 && s390_single_part (operands[2], DImode, HImode, 0) < 0"
6627 "@
6628 ngr\t%0,%2
6629 ngrk\t%0,%1,%2
6630 ng\t%0,%2
6631 risbg\t%0,%1,%s2,128+%e2,0"
6632 [(set_attr "op_type" "RRE,RRF,RXY,RIE")
6633 (set_attr "cpu_facility" "*,z196,*,z10")
6634 (set_attr "z10prop" "z10_super_E1,*,z10_super_E1,z10_super_E1")])
6635
6636 (define_insn "*anddi3"
6637 [(set (match_operand:DI 0 "nonimmediate_operand"
6638 "=d,d, d, d, d, d, d, d,d,d, d, d, AQ,Q")
6639 (and:DI
6640 (match_operand:DI 1 "nonimmediate_operand"
6641 "%d,o, 0, 0, 0, 0, 0, 0,0,d, 0, d, 0,0")
6642 (match_operand:DI 2 "general_operand"
6643 "M, M,N0HDF,N1HDF,N2HDF,N3HDF,N0SDF,N1SDF,d,d,RT,NxxDq,NxQDF,Q")))
6644 (clobber (reg:CC CC_REGNUM))]
6645 "TARGET_ZARCH && s390_logical_operator_ok_p (operands)"
6646 "@
6647 #
6648 #
6649 nihh\t%0,%j2
6650 nihl\t%0,%j2
6651 nilh\t%0,%j2
6652 nill\t%0,%j2
6653 nihf\t%0,%m2
6654 nilf\t%0,%m2
6655 ngr\t%0,%2
6656 ngrk\t%0,%1,%2
6657 ng\t%0,%2
6658 risbg\t%0,%1,%s2,128+%e2,0
6659 #
6660 #"
6661 [(set_attr "op_type" "RRE,RXE,RI,RI,RI,RI,RIL,RIL,RRE,RRF,RXY,RIE,SI,SS")
6662 (set_attr "cpu_facility" "*,*,*,*,*,*,extimm,extimm,*,z196,*,z10,*,*")
6663 (set_attr "z10prop" "*,
6664 *,
6665 z10_super_E1,
6666 z10_super_E1,
6667 z10_super_E1,
6668 z10_super_E1,
6669 z10_super_E1,
6670 z10_super_E1,
6671 z10_super_E1,
6672 *,
6673 z10_super_E1,
6674 z10_super_E1,
6675 *,
6676 *")])
6677
6678 (define_split
6679 [(set (match_operand:DI 0 "s_operand" "")
6680 (and:DI (match_dup 0) (match_operand:DI 1 "immediate_operand" "")))
6681 (clobber (reg:CC CC_REGNUM))]
6682 "reload_completed"
6683 [(parallel
6684 [(set (match_dup 0) (and:QI (match_dup 0) (match_dup 1)))
6685 (clobber (reg:CC CC_REGNUM))])]
6686 "s390_narrow_logical_operator (AND, &operands[0], &operands[1]);")
6687
6688 ;; These two are what combine generates for (ashift (zero_extract)).
6689 (define_insn "*extzv_<mode>_srl"
6690 [(set (match_operand:GPR 0 "register_operand" "=d")
6691 (and:GPR (lshiftrt:GPR
6692 (match_operand:GPR 1 "register_operand" "d")
6693 (match_operand:GPR 2 "nonzero_shift_count_operand" ""))
6694 (match_operand:GPR 3 "contiguous_bitmask_operand" "")))
6695 (clobber (reg:CC CC_REGNUM))]
6696 "TARGET_Z10
6697 /* Note that even for the SImode pattern, the rotate is always DImode. */
6698 && s390_extzv_shift_ok (<bitsize>, -INTVAL (operands[2]),
6699 INTVAL (operands[3]))"
6700 "risbg\t%0,%1,%<bfstart>3,128+%<bfend>3,64-%2"
6701 [(set_attr "op_type" "RIE")
6702 (set_attr "z10prop" "z10_super_E1")])
6703
6704 (define_insn "*extzv_<mode>_sll"
6705 [(set (match_operand:GPR 0 "register_operand" "=d")
6706 (and:GPR (ashift:GPR
6707 (match_operand:GPR 1 "register_operand" "d")
6708 (match_operand:GPR 2 "nonzero_shift_count_operand" ""))
6709 (match_operand:GPR 3 "contiguous_bitmask_operand" "")))
6710 (clobber (reg:CC CC_REGNUM))]
6711 "TARGET_Z10
6712 && s390_extzv_shift_ok (<bitsize>, INTVAL (operands[2]),
6713 INTVAL (operands[3]))"
6714 "risbg\t%0,%1,%<bfstart>3,128+%<bfend>3,%2"
6715 [(set_attr "op_type" "RIE")
6716 (set_attr "z10prop" "z10_super_E1")])
6717
6718
6719 ;
6720 ; andsi3 instruction pattern(s).
6721 ;
6722
6723 (define_insn "*andsi3_cc"
6724 [(set (reg CC_REGNUM)
6725 (compare
6726 (and:SI
6727 (match_operand:SI 1 "nonimmediate_operand" "%0,0,d,0,0, d")
6728 (match_operand:SI 2 "general_operand" "Os,d,d,R,T,NxxSq"))
6729 (const_int 0)))
6730 (set (match_operand:SI 0 "register_operand" "=d,d,d,d,d, d")
6731 (and:SI (match_dup 1) (match_dup 2)))]
6732 "s390_match_ccmode(insn, CCTmode)"
6733 "@
6734 nilf\t%0,%o2
6735 nr\t%0,%2
6736 nrk\t%0,%1,%2
6737 n\t%0,%2
6738 ny\t%0,%2
6739 risbg\t%0,%1,%t2,128+%f2,0"
6740 [(set_attr "op_type" "RIL,RR,RRF,RX,RXY,RIE")
6741 (set_attr "cpu_facility" "*,*,z196,*,*,z10")
6742 (set_attr "z10prop" "z10_super_E1,z10_super_E1,*,
6743 z10_super_E1,z10_super_E1,z10_super_E1")])
6744
6745 (define_insn "*andsi3_cconly"
6746 [(set (reg CC_REGNUM)
6747 (compare
6748 (and:SI
6749 (match_operand:SI 1 "nonimmediate_operand" "%0,0,d,0,0, d")
6750 (match_operand:SI 2 "general_operand" "Os,d,d,R,T,NxxSq"))
6751 (const_int 0)))
6752 (clobber (match_scratch:SI 0 "=d,d,d,d,d, d"))]
6753 "s390_match_ccmode(insn, CCTmode)
6754 /* Do not steal TM patterns. */
6755 && s390_single_part (operands[2], SImode, HImode, 0) < 0"
6756 "@
6757 nilf\t%0,%o2
6758 nr\t%0,%2
6759 nrk\t%0,%1,%2
6760 n\t%0,%2
6761 ny\t%0,%2
6762 risbg\t%0,%1,%t2,128+%f2,0"
6763 [(set_attr "op_type" "RIL,RR,RRF,RX,RXY,RIE")
6764 (set_attr "cpu_facility" "*,*,z196,*,*,z10")
6765 (set_attr "z10prop" "z10_super_E1,z10_super_E1,*,
6766 z10_super_E1,z10_super_E1,z10_super_E1")])
6767
6768 (define_insn "*andsi3_zarch"
6769 [(set (match_operand:SI 0 "nonimmediate_operand"
6770 "=d,d, d, d, d,d,d,d,d, d, AQ,Q")
6771 (and:SI (match_operand:SI 1 "nonimmediate_operand"
6772 "%d,o, 0, 0, 0,0,d,0,0, d, 0,0")
6773 (match_operand:SI 2 "general_operand"
6774 " M,M,N0HSF,N1HSF,Os,d,d,R,T,NxxSq,NxQSF,Q")))
6775 (clobber (reg:CC CC_REGNUM))]
6776 "TARGET_ZARCH && s390_logical_operator_ok_p (operands)"
6777 "@
6778 #
6779 #
6780 nilh\t%0,%j2
6781 nill\t%0,%j2
6782 nilf\t%0,%o2
6783 nr\t%0,%2
6784 nrk\t%0,%1,%2
6785 n\t%0,%2
6786 ny\t%0,%2
6787 risbg\t%0,%1,%t2,128+%f2,0
6788 #
6789 #"
6790 [(set_attr "op_type" "RRE,RXE,RI,RI,RIL,RR,RRF,RX,RXY,RIE,SI,SS")
6791 (set_attr "cpu_facility" "*,*,*,*,*,*,z196,*,*,z10,*,*")
6792 (set_attr "z10prop" "*,
6793 *,
6794 z10_super_E1,
6795 z10_super_E1,
6796 z10_super_E1,
6797 z10_super_E1,
6798 *,
6799 z10_super_E1,
6800 z10_super_E1,
6801 z10_super_E1,
6802 *,
6803 *")])
6804
6805 (define_insn "*andsi3_esa"
6806 [(set (match_operand:SI 0 "nonimmediate_operand" "=d,d, AQ,Q")
6807 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0, 0,0")
6808 (match_operand:SI 2 "general_operand" " d,R,NxQSF,Q")))
6809 (clobber (reg:CC CC_REGNUM))]
6810 "!TARGET_ZARCH && s390_logical_operator_ok_p (operands)"
6811 "@
6812 nr\t%0,%2
6813 n\t%0,%2
6814 #
6815 #"
6816 [(set_attr "op_type" "RR,RX,SI,SS")
6817 (set_attr "z10prop" "z10_super_E1,z10_super_E1,*,*")])
6818
6819
6820 (define_split
6821 [(set (match_operand:SI 0 "s_operand" "")
6822 (and:SI (match_dup 0) (match_operand:SI 1 "immediate_operand" "")))
6823 (clobber (reg:CC CC_REGNUM))]
6824 "reload_completed"
6825 [(parallel
6826 [(set (match_dup 0) (and:QI (match_dup 0) (match_dup 1)))
6827 (clobber (reg:CC CC_REGNUM))])]
6828 "s390_narrow_logical_operator (AND, &operands[0], &operands[1]);")
6829
6830 ;
6831 ; andhi3 instruction pattern(s).
6832 ;
6833
6834 (define_insn "*andhi3_zarch"
6835 [(set (match_operand:HI 0 "nonimmediate_operand" "=d,d,d, AQ,Q")
6836 (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,d,0, 0,0")
6837 (match_operand:HI 2 "general_operand" " d,d,n,NxQHF,Q")))
6838 (clobber (reg:CC CC_REGNUM))]
6839 "TARGET_ZARCH && s390_logical_operator_ok_p (operands)"
6840 "@
6841 nr\t%0,%2
6842 nrk\t%0,%1,%2
6843 nill\t%0,%x2
6844 #
6845 #"
6846 [(set_attr "op_type" "RR,RRF,RI,SI,SS")
6847 (set_attr "cpu_facility" "*,z196,*,*,*")
6848 (set_attr "z10prop" "z10_super_E1,*,z10_super_E1,*,*")
6849 ])
6850
6851 (define_insn "*andhi3_esa"
6852 [(set (match_operand:HI 0 "nonimmediate_operand" "=d,AQ,Q")
6853 (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,0")
6854 (match_operand:HI 2 "general_operand" "d,NxQHF,Q")))
6855 (clobber (reg:CC CC_REGNUM))]
6856 "!TARGET_ZARCH && s390_logical_operator_ok_p (operands)"
6857 "@
6858 nr\t%0,%2
6859 #
6860 #"
6861 [(set_attr "op_type" "RR,SI,SS")
6862 (set_attr "z10prop" "z10_super_E1,*,*")
6863 ])
6864
6865 (define_split
6866 [(set (match_operand:HI 0 "s_operand" "")
6867 (and:HI (match_dup 0) (match_operand:HI 1 "immediate_operand" "")))
6868 (clobber (reg:CC CC_REGNUM))]
6869 "reload_completed"
6870 [(parallel
6871 [(set (match_dup 0) (and:QI (match_dup 0) (match_dup 1)))
6872 (clobber (reg:CC CC_REGNUM))])]
6873 "s390_narrow_logical_operator (AND, &operands[0], &operands[1]);")
6874
6875 ;
6876 ; andqi3 instruction pattern(s).
6877 ;
6878
6879 (define_insn "*andqi3_zarch"
6880 [(set (match_operand:QI 0 "nonimmediate_operand" "=d,d,d,Q,S,Q")
6881 (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,d,0,0,0,0")
6882 (match_operand:QI 2 "general_operand" " d,d,n,n,n,Q")))
6883 (clobber (reg:CC CC_REGNUM))]
6884 "TARGET_ZARCH && s390_logical_operator_ok_p (operands)"
6885 "@
6886 nr\t%0,%2
6887 nrk\t%0,%1,%2
6888 nill\t%0,%b2
6889 ni\t%S0,%b2
6890 niy\t%S0,%b2
6891 #"
6892 [(set_attr "op_type" "RR,RRF,RI,SI,SIY,SS")
6893 (set_attr "cpu_facility" "*,z196,*,*,*,*")
6894 (set_attr "z10prop" "z10_super_E1,*,z10_super_E1,z10_super,z10_super,*")])
6895
6896 (define_insn "*andqi3_esa"
6897 [(set (match_operand:QI 0 "nonimmediate_operand" "=d,Q,Q")
6898 (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
6899 (match_operand:QI 2 "general_operand" "d,n,Q")))
6900 (clobber (reg:CC CC_REGNUM))]
6901 "!TARGET_ZARCH && s390_logical_operator_ok_p (operands)"
6902 "@
6903 nr\t%0,%2
6904 ni\t%S0,%b2
6905 #"
6906 [(set_attr "op_type" "RR,SI,SS")
6907 (set_attr "z10prop" "z10_super_E1,z10_super,*")])
6908
6909 ;
6910 ; Block and (NC) patterns.
6911 ;
6912
6913 (define_insn "*nc"
6914 [(set (match_operand:BLK 0 "memory_operand" "=Q")
6915 (and:BLK (match_dup 0)
6916 (match_operand:BLK 1 "memory_operand" "Q")))
6917 (use (match_operand 2 "const_int_operand" "n"))
6918 (clobber (reg:CC CC_REGNUM))]
6919 "INTVAL (operands[2]) >= 1 && INTVAL (operands[2]) <= 256"
6920 "nc\t%O0(%2,%R0),%S1"
6921 [(set_attr "op_type" "SS")
6922 (set_attr "z196prop" "z196_cracked")])
6923
6924 (define_split
6925 [(set (match_operand 0 "memory_operand" "")
6926 (and (match_dup 0)
6927 (match_operand 1 "memory_operand" "")))
6928 (clobber (reg:CC CC_REGNUM))]
6929 "reload_completed
6930 && GET_MODE (operands[0]) == GET_MODE (operands[1])
6931 && GET_MODE_SIZE (GET_MODE (operands[0])) > 0"
6932 [(parallel
6933 [(set (match_dup 0) (and:BLK (match_dup 0) (match_dup 1)))
6934 (use (match_dup 2))
6935 (clobber (reg:CC CC_REGNUM))])]
6936 {
6937 operands[2] = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[0])));
6938 operands[0] = adjust_address (operands[0], BLKmode, 0);
6939 operands[1] = adjust_address (operands[1], BLKmode, 0);
6940 })
6941
6942 (define_peephole2
6943 [(parallel
6944 [(set (match_operand:BLK 0 "memory_operand" "")
6945 (and:BLK (match_dup 0)
6946 (match_operand:BLK 1 "memory_operand" "")))
6947 (use (match_operand 2 "const_int_operand" ""))
6948 (clobber (reg:CC CC_REGNUM))])
6949 (parallel
6950 [(set (match_operand:BLK 3 "memory_operand" "")
6951 (and:BLK (match_dup 3)
6952 (match_operand:BLK 4 "memory_operand" "")))
6953 (use (match_operand 5 "const_int_operand" ""))
6954 (clobber (reg:CC CC_REGNUM))])]
6955 "s390_offset_p (operands[0], operands[3], operands[2])
6956 && s390_offset_p (operands[1], operands[4], operands[2])
6957 && !s390_overlap_p (operands[0], operands[1],
6958 INTVAL (operands[2]) + INTVAL (operands[5]))
6959 && INTVAL (operands[2]) + INTVAL (operands[5]) <= 256"
6960 [(parallel
6961 [(set (match_dup 6) (and:BLK (match_dup 6) (match_dup 7)))
6962 (use (match_dup 8))
6963 (clobber (reg:CC CC_REGNUM))])]
6964 "operands[6] = gen_rtx_MEM (BLKmode, XEXP (operands[0], 0));
6965 operands[7] = gen_rtx_MEM (BLKmode, XEXP (operands[1], 0));
6966 operands[8] = GEN_INT (INTVAL (operands[2]) + INTVAL (operands[5]));")
6967
6968
6969 ;;
6970 ;;- Bit set (inclusive or) instructions.
6971 ;;
6972
6973 (define_expand "ior<mode>3"
6974 [(set (match_operand:INT 0 "nonimmediate_operand" "")
6975 (ior:INT (match_operand:INT 1 "nonimmediate_operand" "")
6976 (match_operand:INT 2 "general_operand" "")))
6977 (clobber (reg:CC CC_REGNUM))]
6978 ""
6979 "s390_expand_logical_operator (IOR, <MODE>mode, operands); DONE;")
6980
6981 ;
6982 ; iordi3 instruction pattern(s).
6983 ;
6984
6985 (define_insn "*iordi3_cc"
6986 [(set (reg CC_REGNUM)
6987 (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,d, 0")
6988 (match_operand:DI 2 "general_operand" " d,d,RT"))
6989 (const_int 0)))
6990 (set (match_operand:DI 0 "register_operand" "=d,d, d")
6991 (ior:DI (match_dup 1) (match_dup 2)))]
6992 "s390_match_ccmode(insn, CCTmode) && TARGET_ZARCH"
6993 "@
6994 ogr\t%0,%2
6995 ogrk\t%0,%1,%2
6996 og\t%0,%2"
6997 [(set_attr "op_type" "RRE,RRF,RXY")
6998 (set_attr "cpu_facility" "*,z196,*")
6999 (set_attr "z10prop" "z10_super_E1,*,z10_super_E1")])
7000
7001 (define_insn "*iordi3_cconly"
7002 [(set (reg CC_REGNUM)
7003 (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,d,0")
7004 (match_operand:DI 2 "general_operand" " d,d,RT"))
7005 (const_int 0)))
7006 (clobber (match_scratch:DI 0 "=d,d,d"))]
7007 "s390_match_ccmode(insn, CCTmode) && TARGET_ZARCH"
7008 "@
7009 ogr\t%0,%2
7010 ogrk\t%0,%1,%2
7011 og\t%0,%2"
7012 [(set_attr "op_type" "RRE,RRF,RXY")
7013 (set_attr "cpu_facility" "*,z196,*")
7014 (set_attr "z10prop" "z10_super_E1,*,z10_super_E1")])
7015
7016 (define_insn "*iordi3"
7017 [(set (match_operand:DI 0 "nonimmediate_operand"
7018 "=d, d, d, d, d, d,d,d, d, AQ,Q")
7019 (ior:DI (match_operand:DI 1 "nonimmediate_operand"
7020 " %0, 0, 0, 0, 0, 0,0,d, 0, 0,0")
7021 (match_operand:DI 2 "general_operand"
7022 "N0HD0,N1HD0,N2HD0,N3HD0,N0SD0,N1SD0,d,d,RT,NxQD0,Q")))
7023 (clobber (reg:CC CC_REGNUM))]
7024 "TARGET_ZARCH && s390_logical_operator_ok_p (operands)"
7025 "@
7026 oihh\t%0,%i2
7027 oihl\t%0,%i2
7028 oilh\t%0,%i2
7029 oill\t%0,%i2
7030 oihf\t%0,%k2
7031 oilf\t%0,%k2
7032 ogr\t%0,%2
7033 ogrk\t%0,%1,%2
7034 og\t%0,%2
7035 #
7036 #"
7037 [(set_attr "op_type" "RI,RI,RI,RI,RIL,RIL,RRE,RRF,RXY,SI,SS")
7038 (set_attr "cpu_facility" "*,*,*,*,extimm,extimm,*,z196,*,*,*")
7039 (set_attr "z10prop" "z10_super_E1,
7040 z10_super_E1,
7041 z10_super_E1,
7042 z10_super_E1,
7043 z10_super_E1,
7044 z10_super_E1,
7045 z10_super_E1,
7046 *,
7047 z10_super_E1,
7048 *,
7049 *")])
7050
7051 (define_split
7052 [(set (match_operand:DI 0 "s_operand" "")
7053 (ior:DI (match_dup 0) (match_operand:DI 1 "immediate_operand" "")))
7054 (clobber (reg:CC CC_REGNUM))]
7055 "reload_completed"
7056 [(parallel
7057 [(set (match_dup 0) (ior:QI (match_dup 0) (match_dup 1)))
7058 (clobber (reg:CC CC_REGNUM))])]
7059 "s390_narrow_logical_operator (IOR, &operands[0], &operands[1]);")
7060
7061 ;
7062 ; iorsi3 instruction pattern(s).
7063 ;
7064
7065 (define_insn "*iorsi3_cc"
7066 [(set (reg CC_REGNUM)
7067 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,d,0,0")
7068 (match_operand:SI 2 "general_operand" "Os,d,d,R,T"))
7069 (const_int 0)))
7070 (set (match_operand:SI 0 "register_operand" "=d,d,d,d,d")
7071 (ior:SI (match_dup 1) (match_dup 2)))]
7072 "s390_match_ccmode(insn, CCTmode)"
7073 "@
7074 oilf\t%0,%o2
7075 or\t%0,%2
7076 ork\t%0,%1,%2
7077 o\t%0,%2
7078 oy\t%0,%2"
7079 [(set_attr "op_type" "RIL,RR,RRF,RX,RXY")
7080 (set_attr "cpu_facility" "*,*,z196,*,*")
7081 (set_attr "z10prop" "z10_super_E1,z10_super_E1,*,z10_super_E1,z10_super_E1")])
7082
7083 (define_insn "*iorsi3_cconly"
7084 [(set (reg CC_REGNUM)
7085 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,d,0,0")
7086 (match_operand:SI 2 "general_operand" "Os,d,d,R,T"))
7087 (const_int 0)))
7088 (clobber (match_scratch:SI 0 "=d,d,d,d,d"))]
7089 "s390_match_ccmode(insn, CCTmode)"
7090 "@
7091 oilf\t%0,%o2
7092 or\t%0,%2
7093 ork\t%0,%1,%2
7094 o\t%0,%2
7095 oy\t%0,%2"
7096 [(set_attr "op_type" "RIL,RR,RRF,RX,RXY")
7097 (set_attr "cpu_facility" "*,*,z196,*,*")
7098 (set_attr "z10prop" "z10_super_E1,z10_super_E1,*,z10_super_E1,z10_super_E1")])
7099
7100 (define_insn "*iorsi3_zarch"
7101 [(set (match_operand:SI 0 "nonimmediate_operand" "=d, d, d,d,d,d,d, AQ,Q")
7102 (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0, 0, 0,0,d,0,0, 0,0")
7103 (match_operand:SI 2 "general_operand" "N0HS0,N1HS0,Os,d,d,R,T,NxQS0,Q")))
7104 (clobber (reg:CC CC_REGNUM))]
7105 "TARGET_ZARCH && s390_logical_operator_ok_p (operands)"
7106 "@
7107 oilh\t%0,%i2
7108 oill\t%0,%i2
7109 oilf\t%0,%o2
7110 or\t%0,%2
7111 ork\t%0,%1,%2
7112 o\t%0,%2
7113 oy\t%0,%2
7114 #
7115 #"
7116 [(set_attr "op_type" "RI,RI,RIL,RR,RRF,RX,RXY,SI,SS")
7117 (set_attr "cpu_facility" "*,*,*,*,z196,*,*,*,*")
7118 (set_attr "z10prop" "z10_super_E1,
7119 z10_super_E1,
7120 z10_super_E1,
7121 z10_super_E1,
7122 *,
7123 z10_super_E1,
7124 z10_super_E1,
7125 *,
7126 *")])
7127
7128 (define_insn "*iorsi3_esa"
7129 [(set (match_operand:SI 0 "nonimmediate_operand" "=d,d,AQ,Q")
7130 (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,0,0")
7131 (match_operand:SI 2 "general_operand" "d,R,NxQS0,Q")))
7132 (clobber (reg:CC CC_REGNUM))]
7133 "!TARGET_ZARCH && s390_logical_operator_ok_p (operands)"
7134 "@
7135 or\t%0,%2
7136 o\t%0,%2
7137 #
7138 #"
7139 [(set_attr "op_type" "RR,RX,SI,SS")
7140 (set_attr "z10prop" "z10_super_E1,z10_super_E1,*,*")])
7141
7142 (define_split
7143 [(set (match_operand:SI 0 "s_operand" "")
7144 (ior:SI (match_dup 0) (match_operand:SI 1 "immediate_operand" "")))
7145 (clobber (reg:CC CC_REGNUM))]
7146 "reload_completed"
7147 [(parallel
7148 [(set (match_dup 0) (ior:QI (match_dup 0) (match_dup 1)))
7149 (clobber (reg:CC CC_REGNUM))])]
7150 "s390_narrow_logical_operator (IOR, &operands[0], &operands[1]);")
7151
7152 ;
7153 ; iorhi3 instruction pattern(s).
7154 ;
7155
7156 (define_insn "*iorhi3_zarch"
7157 [(set (match_operand:HI 0 "nonimmediate_operand" "=d,d,d, AQ,Q")
7158 (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,d,0, 0,0")
7159 (match_operand:HI 2 "general_operand" " d,d,n,NxQH0,Q")))
7160 (clobber (reg:CC CC_REGNUM))]
7161 "TARGET_ZARCH && s390_logical_operator_ok_p (operands)"
7162 "@
7163 or\t%0,%2
7164 ork\t%0,%1,%2
7165 oill\t%0,%x2
7166 #
7167 #"
7168 [(set_attr "op_type" "RR,RRF,RI,SI,SS")
7169 (set_attr "cpu_facility" "*,z196,*,*,*")
7170 (set_attr "z10prop" "z10_super_E1,*,z10_super_E1,*,*")])
7171
7172 (define_insn "*iorhi3_esa"
7173 [(set (match_operand:HI 0 "nonimmediate_operand" "=d,AQ,Q")
7174 (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,0")
7175 (match_operand:HI 2 "general_operand" "d,NxQH0,Q")))
7176 (clobber (reg:CC CC_REGNUM))]
7177 "!TARGET_ZARCH && s390_logical_operator_ok_p (operands)"
7178 "@
7179 or\t%0,%2
7180 #
7181 #"
7182 [(set_attr "op_type" "RR,SI,SS")
7183 (set_attr "z10prop" "z10_super_E1,*,*")])
7184
7185 (define_split
7186 [(set (match_operand:HI 0 "s_operand" "")
7187 (ior:HI (match_dup 0) (match_operand:HI 1 "immediate_operand" "")))
7188 (clobber (reg:CC CC_REGNUM))]
7189 "reload_completed"
7190 [(parallel
7191 [(set (match_dup 0) (ior:QI (match_dup 0) (match_dup 1)))
7192 (clobber (reg:CC CC_REGNUM))])]
7193 "s390_narrow_logical_operator (IOR, &operands[0], &operands[1]);")
7194
7195 ;
7196 ; iorqi3 instruction pattern(s).
7197 ;
7198
7199 (define_insn "*iorqi3_zarch"
7200 [(set (match_operand:QI 0 "nonimmediate_operand" "=d,d,d,Q,S,Q")
7201 (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,d,0,0,0,0")
7202 (match_operand:QI 2 "general_operand" " d,d,n,n,n,Q")))
7203 (clobber (reg:CC CC_REGNUM))]
7204 "TARGET_ZARCH && s390_logical_operator_ok_p (operands)"
7205 "@
7206 or\t%0,%2
7207 ork\t%0,%1,%2
7208 oill\t%0,%b2
7209 oi\t%S0,%b2
7210 oiy\t%S0,%b2
7211 #"
7212 [(set_attr "op_type" "RR,RRF,RI,SI,SIY,SS")
7213 (set_attr "cpu_facility" "*,z196,*,*,*,*")
7214 (set_attr "z10prop" "z10_super_E1,*,z10_super_E1,
7215 z10_super,z10_super,*")])
7216
7217 (define_insn "*iorqi3_esa"
7218 [(set (match_operand:QI 0 "nonimmediate_operand" "=d,Q,Q")
7219 (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
7220 (match_operand:QI 2 "general_operand" "d,n,Q")))
7221 (clobber (reg:CC CC_REGNUM))]
7222 "!TARGET_ZARCH && s390_logical_operator_ok_p (operands)"
7223 "@
7224 or\t%0,%2
7225 oi\t%S0,%b2
7226 #"
7227 [(set_attr "op_type" "RR,SI,SS")
7228 (set_attr "z10prop" "z10_super_E1,z10_super,*")])
7229
7230 ;
7231 ; Block inclusive or (OC) patterns.
7232 ;
7233
7234 (define_insn "*oc"
7235 [(set (match_operand:BLK 0 "memory_operand" "=Q")
7236 (ior:BLK (match_dup 0)
7237 (match_operand:BLK 1 "memory_operand" "Q")))
7238 (use (match_operand 2 "const_int_operand" "n"))
7239 (clobber (reg:CC CC_REGNUM))]
7240 "INTVAL (operands[2]) >= 1 && INTVAL (operands[2]) <= 256"
7241 "oc\t%O0(%2,%R0),%S1"
7242 [(set_attr "op_type" "SS")
7243 (set_attr "z196prop" "z196_cracked")])
7244
7245 (define_split
7246 [(set (match_operand 0 "memory_operand" "")
7247 (ior (match_dup 0)
7248 (match_operand 1 "memory_operand" "")))
7249 (clobber (reg:CC CC_REGNUM))]
7250 "reload_completed
7251 && GET_MODE (operands[0]) == GET_MODE (operands[1])
7252 && GET_MODE_SIZE (GET_MODE (operands[0])) > 0"
7253 [(parallel
7254 [(set (match_dup 0) (ior:BLK (match_dup 0) (match_dup 1)))
7255 (use (match_dup 2))
7256 (clobber (reg:CC CC_REGNUM))])]
7257 {
7258 operands[2] = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[0])));
7259 operands[0] = adjust_address (operands[0], BLKmode, 0);
7260 operands[1] = adjust_address (operands[1], BLKmode, 0);
7261 })
7262
7263 (define_peephole2
7264 [(parallel
7265 [(set (match_operand:BLK 0 "memory_operand" "")
7266 (ior:BLK (match_dup 0)
7267 (match_operand:BLK 1 "memory_operand" "")))
7268 (use (match_operand 2 "const_int_operand" ""))
7269 (clobber (reg:CC CC_REGNUM))])
7270 (parallel
7271 [(set (match_operand:BLK 3 "memory_operand" "")
7272 (ior:BLK (match_dup 3)
7273 (match_operand:BLK 4 "memory_operand" "")))
7274 (use (match_operand 5 "const_int_operand" ""))
7275 (clobber (reg:CC CC_REGNUM))])]
7276 "s390_offset_p (operands[0], operands[3], operands[2])
7277 && s390_offset_p (operands[1], operands[4], operands[2])
7278 && !s390_overlap_p (operands[0], operands[1],
7279 INTVAL (operands[2]) + INTVAL (operands[5]))
7280 && INTVAL (operands[2]) + INTVAL (operands[5]) <= 256"
7281 [(parallel
7282 [(set (match_dup 6) (ior:BLK (match_dup 6) (match_dup 7)))
7283 (use (match_dup 8))
7284 (clobber (reg:CC CC_REGNUM))])]
7285 "operands[6] = gen_rtx_MEM (BLKmode, XEXP (operands[0], 0));
7286 operands[7] = gen_rtx_MEM (BLKmode, XEXP (operands[1], 0));
7287 operands[8] = GEN_INT (INTVAL (operands[2]) + INTVAL (operands[5]));")
7288
7289
7290 ;;
7291 ;;- Xor instructions.
7292 ;;
7293
7294 (define_expand "xor<mode>3"
7295 [(set (match_operand:INT 0 "nonimmediate_operand" "")
7296 (xor:INT (match_operand:INT 1 "nonimmediate_operand" "")
7297 (match_operand:INT 2 "general_operand" "")))
7298 (clobber (reg:CC CC_REGNUM))]
7299 ""
7300 "s390_expand_logical_operator (XOR, <MODE>mode, operands); DONE;")
7301
7302 ; Combine replaces (xor (x) (const_int -1)) with (not (x)) when doing
7303 ; simplifications. So its better to have something matching.
7304 (define_split
7305 [(set (match_operand:INT 0 "nonimmediate_operand" "")
7306 (not:INT (match_operand:INT 1 "nonimmediate_operand" "")))]
7307 ""
7308 [(parallel
7309 [(set (match_dup 0) (xor:INT (match_dup 1) (match_dup 2)))
7310 (clobber (reg:CC CC_REGNUM))])]
7311 {
7312 operands[2] = constm1_rtx;
7313 if (!s390_logical_operator_ok_p (operands))
7314 FAIL;
7315 })
7316
7317 ;
7318 ; xordi3 instruction pattern(s).
7319 ;
7320
7321 (define_insn "*xordi3_cc"
7322 [(set (reg CC_REGNUM)
7323 (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,d, 0")
7324 (match_operand:DI 2 "general_operand" " d,d,RT"))
7325 (const_int 0)))
7326 (set (match_operand:DI 0 "register_operand" "=d,d, d")
7327 (xor:DI (match_dup 1) (match_dup 2)))]
7328 "s390_match_ccmode(insn, CCTmode) && TARGET_ZARCH"
7329 "@
7330 xgr\t%0,%2
7331 xgrk\t%0,%1,%2
7332 xg\t%0,%2"
7333 [(set_attr "op_type" "RRE,RRF,RXY")
7334 (set_attr "cpu_facility" "*,z196,*")
7335 (set_attr "z10prop" "z10_super_E1,*,z10_super_E1")])
7336
7337 (define_insn "*xordi3_cconly"
7338 [(set (reg CC_REGNUM)
7339 (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,d, 0")
7340 (match_operand:DI 2 "general_operand" " d,d,RT"))
7341 (const_int 0)))
7342 (clobber (match_scratch:DI 0 "=d,d, d"))]
7343 "s390_match_ccmode(insn, CCTmode) && TARGET_ZARCH"
7344 "@
7345 xgr\t%0,%2
7346 xgrk\t%0,%1,%2
7347 xg\t%0,%2"
7348 [(set_attr "op_type" "RRE,RRF,RXY")
7349 (set_attr "cpu_facility" "*,z196,*")
7350 (set_attr "z10prop" "z10_super_E1,*,z10_super_E1")])
7351
7352 (define_insn "*xordi3"
7353 [(set (match_operand:DI 0 "nonimmediate_operand" "=d, d,d,d, d, AQ,Q")
7354 (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0, 0,0,d, 0, 0,0")
7355 (match_operand:DI 2 "general_operand" "N0SD0,N1SD0,d,d,RT,NxQD0,Q")))
7356 (clobber (reg:CC CC_REGNUM))]
7357 "TARGET_ZARCH && s390_logical_operator_ok_p (operands)"
7358 "@
7359 xihf\t%0,%k2
7360 xilf\t%0,%k2
7361 xgr\t%0,%2
7362 xgrk\t%0,%1,%2
7363 xg\t%0,%2
7364 #
7365 #"
7366 [(set_attr "op_type" "RIL,RIL,RRE,RRF,RXY,SI,SS")
7367 (set_attr "cpu_facility" "extimm,extimm,*,z196,*,*,*")
7368 (set_attr "z10prop" "z10_super_E1,z10_super_E1,z10_super_E1,
7369 *,z10_super_E1,*,*")])
7370
7371 (define_split
7372 [(set (match_operand:DI 0 "s_operand" "")
7373 (xor:DI (match_dup 0) (match_operand:DI 1 "immediate_operand" "")))
7374 (clobber (reg:CC CC_REGNUM))]
7375 "reload_completed"
7376 [(parallel
7377 [(set (match_dup 0) (xor:QI (match_dup 0) (match_dup 1)))
7378 (clobber (reg:CC CC_REGNUM))])]
7379 "s390_narrow_logical_operator (XOR, &operands[0], &operands[1]);")
7380
7381 ;
7382 ; xorsi3 instruction pattern(s).
7383 ;
7384
7385 (define_insn "*xorsi3_cc"
7386 [(set (reg CC_REGNUM)
7387 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,d,0,0")
7388 (match_operand:SI 2 "general_operand" "Os,d,d,R,T"))
7389 (const_int 0)))
7390 (set (match_operand:SI 0 "register_operand" "=d,d,d,d,d")
7391 (xor:SI (match_dup 1) (match_dup 2)))]
7392 "s390_match_ccmode(insn, CCTmode)"
7393 "@
7394 xilf\t%0,%o2
7395 xr\t%0,%2
7396 xrk\t%0,%1,%2
7397 x\t%0,%2
7398 xy\t%0,%2"
7399 [(set_attr "op_type" "RIL,RR,RRF,RX,RXY")
7400 (set_attr "cpu_facility" "*,*,z196,*,*")
7401 (set_attr "z10prop" "z10_super_E1,z10_super_E1,*,
7402 z10_super_E1,z10_super_E1")])
7403
7404 (define_insn "*xorsi3_cconly"
7405 [(set (reg CC_REGNUM)
7406 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,d,0,0")
7407 (match_operand:SI 2 "general_operand" "Os,d,d,R,T"))
7408 (const_int 0)))
7409 (clobber (match_scratch:SI 0 "=d,d,d,d,d"))]
7410 "s390_match_ccmode(insn, CCTmode)"
7411 "@
7412 xilf\t%0,%o2
7413 xr\t%0,%2
7414 xrk\t%0,%1,%2
7415 x\t%0,%2
7416 xy\t%0,%2"
7417 [(set_attr "op_type" "RIL,RR,RRF,RX,RXY")
7418 (set_attr "cpu_facility" "*,*,z196,*,*")
7419 (set_attr "z10prop" "z10_super_E1,z10_super_E1,*,
7420 z10_super_E1,z10_super_E1")])
7421
7422 (define_insn "*xorsi3"
7423 [(set (match_operand:SI 0 "nonimmediate_operand" "=d,d,d,d,d, AQ,Q")
7424 (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,d,0,0, 0,0")
7425 (match_operand:SI 2 "general_operand" "Os,d,d,R,T,NxQS0,Q")))
7426 (clobber (reg:CC CC_REGNUM))]
7427 "s390_logical_operator_ok_p (operands)"
7428 "@
7429 xilf\t%0,%o2
7430 xr\t%0,%2
7431 xrk\t%0,%1,%2
7432 x\t%0,%2
7433 xy\t%0,%2
7434 #
7435 #"
7436 [(set_attr "op_type" "RIL,RR,RRF,RX,RXY,SI,SS")
7437 (set_attr "cpu_facility" "*,*,z196,*,*,*,*")
7438 (set_attr "z10prop" "z10_super_E1,z10_super_E1,*,
7439 z10_super_E1,z10_super_E1,*,*")])
7440
7441 (define_split
7442 [(set (match_operand:SI 0 "s_operand" "")
7443 (xor:SI (match_dup 0) (match_operand:SI 1 "immediate_operand" "")))
7444 (clobber (reg:CC CC_REGNUM))]
7445 "reload_completed"
7446 [(parallel
7447 [(set (match_dup 0) (xor:QI (match_dup 0) (match_dup 1)))
7448 (clobber (reg:CC CC_REGNUM))])]
7449 "s390_narrow_logical_operator (XOR, &operands[0], &operands[1]);")
7450
7451 ;
7452 ; xorhi3 instruction pattern(s).
7453 ;
7454
7455 (define_insn "*xorhi3"
7456 [(set (match_operand:HI 0 "nonimmediate_operand" "=d,d,d, AQ,Q")
7457 (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,d, 0,0")
7458 (match_operand:HI 2 "general_operand" "Os,d,d,NxQH0,Q")))
7459 (clobber (reg:CC CC_REGNUM))]
7460 "s390_logical_operator_ok_p (operands)"
7461 "@
7462 xilf\t%0,%x2
7463 xr\t%0,%2
7464 xrk\t%0,%1,%2
7465 #
7466 #"
7467 [(set_attr "op_type" "RIL,RR,RRF,SI,SS")
7468 (set_attr "cpu_facility" "*,*,z196,*,*")
7469 (set_attr "z10prop" "z10_super_E1,z10_super_E1,*,*,*")])
7470
7471 (define_split
7472 [(set (match_operand:HI 0 "s_operand" "")
7473 (xor:HI (match_dup 0) (match_operand:HI 1 "immediate_operand" "")))
7474 (clobber (reg:CC CC_REGNUM))]
7475 "reload_completed"
7476 [(parallel
7477 [(set (match_dup 0) (xor:QI (match_dup 0) (match_dup 1)))
7478 (clobber (reg:CC CC_REGNUM))])]
7479 "s390_narrow_logical_operator (XOR, &operands[0], &operands[1]);")
7480
7481 ;
7482 ; xorqi3 instruction pattern(s).
7483 ;
7484
7485 (define_insn "*xorqi3"
7486 [(set (match_operand:QI 0 "nonimmediate_operand" "=d,d,d,Q,S,Q")
7487 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,d,0,0,0")
7488 (match_operand:QI 2 "general_operand" "Os,d,d,n,n,Q")))
7489 (clobber (reg:CC CC_REGNUM))]
7490 "s390_logical_operator_ok_p (operands)"
7491 "@
7492 xilf\t%0,%b2
7493 xr\t%0,%2
7494 xrk\t%0,%1,%2
7495 xi\t%S0,%b2
7496 xiy\t%S0,%b2
7497 #"
7498 [(set_attr "op_type" "RIL,RR,RRF,SI,SIY,SS")
7499 (set_attr "cpu_facility" "*,*,z196,*,*,*")
7500 (set_attr "z10prop" "z10_super_E1,z10_super_E1,*,z10_super,z10_super,*")])
7501
7502
7503 ;
7504 ; Block exclusive or (XC) patterns.
7505 ;
7506
7507 (define_insn "*xc"
7508 [(set (match_operand:BLK 0 "memory_operand" "=Q")
7509 (xor:BLK (match_dup 0)
7510 (match_operand:BLK 1 "memory_operand" "Q")))
7511 (use (match_operand 2 "const_int_operand" "n"))
7512 (clobber (reg:CC CC_REGNUM))]
7513 "INTVAL (operands[2]) >= 1 && INTVAL (operands[2]) <= 256"
7514 "xc\t%O0(%2,%R0),%S1"
7515 [(set_attr "op_type" "SS")])
7516
7517 (define_split
7518 [(set (match_operand 0 "memory_operand" "")
7519 (xor (match_dup 0)
7520 (match_operand 1 "memory_operand" "")))
7521 (clobber (reg:CC CC_REGNUM))]
7522 "reload_completed
7523 && GET_MODE (operands[0]) == GET_MODE (operands[1])
7524 && GET_MODE_SIZE (GET_MODE (operands[0])) > 0"
7525 [(parallel
7526 [(set (match_dup 0) (xor:BLK (match_dup 0) (match_dup 1)))
7527 (use (match_dup 2))
7528 (clobber (reg:CC CC_REGNUM))])]
7529 {
7530 operands[2] = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[0])));
7531 operands[0] = adjust_address (operands[0], BLKmode, 0);
7532 operands[1] = adjust_address (operands[1], BLKmode, 0);
7533 })
7534
7535 (define_peephole2
7536 [(parallel
7537 [(set (match_operand:BLK 0 "memory_operand" "")
7538 (xor:BLK (match_dup 0)
7539 (match_operand:BLK 1 "memory_operand" "")))
7540 (use (match_operand 2 "const_int_operand" ""))
7541 (clobber (reg:CC CC_REGNUM))])
7542 (parallel
7543 [(set (match_operand:BLK 3 "memory_operand" "")
7544 (xor:BLK (match_dup 3)
7545 (match_operand:BLK 4 "memory_operand" "")))
7546 (use (match_operand 5 "const_int_operand" ""))
7547 (clobber (reg:CC CC_REGNUM))])]
7548 "s390_offset_p (operands[0], operands[3], operands[2])
7549 && s390_offset_p (operands[1], operands[4], operands[2])
7550 && !s390_overlap_p (operands[0], operands[1],
7551 INTVAL (operands[2]) + INTVAL (operands[5]))
7552 && INTVAL (operands[2]) + INTVAL (operands[5]) <= 256"
7553 [(parallel
7554 [(set (match_dup 6) (xor:BLK (match_dup 6) (match_dup 7)))
7555 (use (match_dup 8))
7556 (clobber (reg:CC CC_REGNUM))])]
7557 "operands[6] = gen_rtx_MEM (BLKmode, XEXP (operands[0], 0));
7558 operands[7] = gen_rtx_MEM (BLKmode, XEXP (operands[1], 0));
7559 operands[8] = GEN_INT (INTVAL (operands[2]) + INTVAL (operands[5]));")
7560
7561 ;
7562 ; Block xor (XC) patterns with src == dest.
7563 ;
7564
7565 (define_insn "*xc_zero"
7566 [(set (match_operand:BLK 0 "memory_operand" "=Q")
7567 (const_int 0))
7568 (use (match_operand 1 "const_int_operand" "n"))
7569 (clobber (reg:CC CC_REGNUM))]
7570 "INTVAL (operands[1]) >= 1 && INTVAL (operands[1]) <= 256"
7571 "xc\t%O0(%1,%R0),%S0"
7572 [(set_attr "op_type" "SS")
7573 (set_attr "z196prop" "z196_cracked")])
7574
7575 (define_peephole2
7576 [(parallel
7577 [(set (match_operand:BLK 0 "memory_operand" "")
7578 (const_int 0))
7579 (use (match_operand 1 "const_int_operand" ""))
7580 (clobber (reg:CC CC_REGNUM))])
7581 (parallel
7582 [(set (match_operand:BLK 2 "memory_operand" "")
7583 (const_int 0))
7584 (use (match_operand 3 "const_int_operand" ""))
7585 (clobber (reg:CC CC_REGNUM))])]
7586 "s390_offset_p (operands[0], operands[2], operands[1])
7587 && INTVAL (operands[1]) + INTVAL (operands[3]) <= 256"
7588 [(parallel
7589 [(set (match_dup 4) (const_int 0))
7590 (use (match_dup 5))
7591 (clobber (reg:CC CC_REGNUM))])]
7592 "operands[4] = gen_rtx_MEM (BLKmode, XEXP (operands[0], 0));
7593 operands[5] = GEN_INT (INTVAL (operands[1]) + INTVAL (operands[3]));")
7594
7595
7596 ;;
7597 ;;- Negate instructions.
7598 ;;
7599
7600 ;
7601 ; neg(di|si)2 instruction pattern(s).
7602 ;
7603
7604 (define_expand "neg<mode>2"
7605 [(parallel
7606 [(set (match_operand:DSI 0 "register_operand" "=d")
7607 (neg:DSI (match_operand:DSI 1 "register_operand" "d")))
7608 (clobber (reg:CC CC_REGNUM))])]
7609 ""
7610 "")
7611
7612 (define_insn "*negdi2_sign_cc"
7613 [(set (reg CC_REGNUM)
7614 (compare (neg:DI (ashiftrt:DI (ashift:DI (subreg:DI
7615 (match_operand:SI 1 "register_operand" "d") 0)
7616 (const_int 32)) (const_int 32)))
7617 (const_int 0)))
7618 (set (match_operand:DI 0 "register_operand" "=d")
7619 (neg:DI (sign_extend:DI (match_dup 1))))]
7620 "TARGET_ZARCH && s390_match_ccmode (insn, CCAmode)"
7621 "lcgfr\t%0,%1"
7622 [(set_attr "op_type" "RRE")
7623 (set_attr "z10prop" "z10_c")])
7624
7625 (define_insn "*negdi2_sign"
7626 [(set (match_operand:DI 0 "register_operand" "=d")
7627 (neg:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "d"))))
7628 (clobber (reg:CC CC_REGNUM))]
7629 "TARGET_ZARCH"
7630 "lcgfr\t%0,%1"
7631 [(set_attr "op_type" "RRE")
7632 (set_attr "z10prop" "z10_c")])
7633
7634 ; lcr, lcgr
7635 (define_insn "*neg<mode>2_cc"
7636 [(set (reg CC_REGNUM)
7637 (compare (neg:GPR (match_operand:GPR 1 "register_operand" "d"))
7638 (const_int 0)))
7639 (set (match_operand:GPR 0 "register_operand" "=d")
7640 (neg:GPR (match_dup 1)))]
7641 "s390_match_ccmode (insn, CCAmode)"
7642 "lc<g>r\t%0,%1"
7643 [(set_attr "op_type" "RR<E>")
7644 (set_attr "z10prop" "z10_super_c_E1")])
7645
7646 ; lcr, lcgr
7647 (define_insn "*neg<mode>2_cconly"
7648 [(set (reg CC_REGNUM)
7649 (compare (neg:GPR (match_operand:GPR 1 "register_operand" "d"))
7650 (const_int 0)))
7651 (clobber (match_scratch:GPR 0 "=d"))]
7652 "s390_match_ccmode (insn, CCAmode)"
7653 "lc<g>r\t%0,%1"
7654 [(set_attr "op_type" "RR<E>")
7655 (set_attr "z10prop" "z10_super_c_E1")])
7656
7657 ; lcr, lcgr
7658 (define_insn "*neg<mode>2"
7659 [(set (match_operand:GPR 0 "register_operand" "=d")
7660 (neg:GPR (match_operand:GPR 1 "register_operand" "d")))
7661 (clobber (reg:CC CC_REGNUM))]
7662 ""
7663 "lc<g>r\t%0,%1"
7664 [(set_attr "op_type" "RR<E>")
7665 (set_attr "z10prop" "z10_super_c_E1")])
7666
7667 (define_insn "*negdi2_31"
7668 [(set (match_operand:DI 0 "register_operand" "=d")
7669 (neg:DI (match_operand:DI 1 "register_operand" "d")))
7670 (clobber (reg:CC CC_REGNUM))]
7671 "!TARGET_ZARCH"
7672 "#")
7673
7674 ; Split a DImode NEG on 31bit into 2 SImode NEGs
7675
7676 ; Doing the twos complement separately on the SImode parts does an
7677 ; unwanted +1 on the high part which needs to be subtracted afterwards
7678 ; ... unless the +1 on the low part created an overflow.
7679
7680 (define_split
7681 [(set (match_operand:DI 0 "register_operand" "")
7682 (neg:DI (match_operand:DI 1 "register_operand" "")))
7683 (clobber (reg:CC CC_REGNUM))]
7684 "!TARGET_ZARCH
7685 && (REGNO (operands[0]) == REGNO (operands[1])
7686 || s390_split_ok_p (operands[0], operands[1], DImode, 0))
7687 && reload_completed"
7688 [(parallel
7689 [(set (match_dup 2) (neg:SI (match_dup 3)))
7690 (clobber (reg:CC CC_REGNUM))])
7691 (parallel
7692 [(set (reg:CCAP CC_REGNUM)
7693 (compare:CCAP (neg:SI (match_dup 5)) (const_int 0)))
7694 (set (match_dup 4) (neg:SI (match_dup 5)))])
7695 (set (pc)
7696 (if_then_else (ne (reg:CCAP CC_REGNUM) (const_int 0))
7697 (pc)
7698 (label_ref (match_dup 6))))
7699 (parallel
7700 [(set (match_dup 2) (plus:SI (match_dup 2) (const_int -1)))
7701 (clobber (reg:CC CC_REGNUM))])
7702 (match_dup 6)]
7703 "operands[2] = operand_subword (operands[0], 0, 0, DImode);
7704 operands[3] = operand_subword (operands[1], 0, 0, DImode);
7705 operands[4] = operand_subword (operands[0], 1, 0, DImode);
7706 operands[5] = operand_subword (operands[1], 1, 0, DImode);
7707 operands[6] = gen_label_rtx ();")
7708
7709 ; Like above but first make a copy of the low part of the src operand
7710 ; since it might overlap with the high part of the destination.
7711
7712 (define_split
7713 [(set (match_operand:DI 0 "register_operand" "")
7714 (neg:DI (match_operand:DI 1 "register_operand" "")))
7715 (clobber (reg:CC CC_REGNUM))]
7716 "!TARGET_ZARCH
7717 && s390_split_ok_p (operands[0], operands[1], DImode, 1)
7718 && reload_completed"
7719 [; Make a backup of op5 first
7720 (set (match_dup 4) (match_dup 5))
7721 ; Setting op2 here might clobber op5
7722 (parallel
7723 [(set (match_dup 2) (neg:SI (match_dup 3)))
7724 (clobber (reg:CC CC_REGNUM))])
7725 (parallel
7726 [(set (reg:CCAP CC_REGNUM)
7727 (compare:CCAP (neg:SI (match_dup 4)) (const_int 0)))
7728 (set (match_dup 4) (neg:SI (match_dup 4)))])
7729 (set (pc)
7730 (if_then_else (ne (reg:CCAP CC_REGNUM) (const_int 0))
7731 (pc)
7732 (label_ref (match_dup 6))))
7733 (parallel
7734 [(set (match_dup 2) (plus:SI (match_dup 2) (const_int -1)))
7735 (clobber (reg:CC CC_REGNUM))])
7736 (match_dup 6)]
7737 "operands[2] = operand_subword (operands[0], 0, 0, DImode);
7738 operands[3] = operand_subword (operands[1], 0, 0, DImode);
7739 operands[4] = operand_subword (operands[0], 1, 0, DImode);
7740 operands[5] = operand_subword (operands[1], 1, 0, DImode);
7741 operands[6] = gen_label_rtx ();")
7742
7743 ;
7744 ; neg(df|sf)2 instruction pattern(s).
7745 ;
7746
7747 (define_expand "neg<mode>2"
7748 [(parallel
7749 [(set (match_operand:BFP 0 "register_operand" "=f")
7750 (neg:BFP (match_operand:BFP 1 "register_operand" "f")))
7751 (clobber (reg:CC CC_REGNUM))])]
7752 "TARGET_HARD_FLOAT"
7753 "")
7754
7755 ; lcxbr, lcdbr, lcebr
7756 (define_insn "*neg<mode>2_cc"
7757 [(set (reg CC_REGNUM)
7758 (compare (neg:BFP (match_operand:BFP 1 "register_operand" "f"))
7759 (match_operand:BFP 2 "const0_operand" "")))
7760 (set (match_operand:BFP 0 "register_operand" "=f")
7761 (neg:BFP (match_dup 1)))]
7762 "s390_match_ccmode (insn, CCSmode) && TARGET_HARD_FLOAT"
7763 "lc<xde>br\t%0,%1"
7764 [(set_attr "op_type" "RRE")
7765 (set_attr "type" "fsimp<mode>")])
7766
7767 ; lcxbr, lcdbr, lcebr
7768 (define_insn "*neg<mode>2_cconly"
7769 [(set (reg CC_REGNUM)
7770 (compare (neg:BFP (match_operand:BFP 1 "register_operand" "f"))
7771 (match_operand:BFP 2 "const0_operand" "")))
7772 (clobber (match_scratch:BFP 0 "=f"))]
7773 "s390_match_ccmode (insn, CCSmode) && TARGET_HARD_FLOAT"
7774 "lc<xde>br\t%0,%1"
7775 [(set_attr "op_type" "RRE")
7776 (set_attr "type" "fsimp<mode>")])
7777
7778 ; lcdfr
7779 (define_insn "*neg<mode>2_nocc"
7780 [(set (match_operand:FP 0 "register_operand" "=f")
7781 (neg:FP (match_operand:FP 1 "register_operand" "<fT0>")))]
7782 "TARGET_DFP"
7783 "lcdfr\t%0,%1"
7784 [(set_attr "op_type" "RRE")
7785 (set_attr "type" "fsimp<mode>")])
7786
7787 ; lcxbr, lcdbr, lcebr
7788 ; FIXME: wflcdb does not clobber cc
7789 (define_insn "*neg<mode>2"
7790 [(set (match_operand:BFP 0 "register_operand" "=f,<vf>")
7791 (neg:BFP (match_operand:BFP 1 "register_operand" "f,<vf>")))
7792 (clobber (reg:CC CC_REGNUM))]
7793 "TARGET_HARD_FLOAT"
7794 "@
7795 lc<xde>br\t%0,%1
7796 wflcdb\t%0,%1"
7797 [(set_attr "op_type" "RRE,VRR")
7798 (set_attr "cpu_facility" "*,vec")
7799 (set_attr "type" "fsimp<mode>,*")])
7800
7801
7802 ;;
7803 ;;- Absolute value instructions.
7804 ;;
7805
7806 ;
7807 ; abs(di|si)2 instruction pattern(s).
7808 ;
7809
7810 (define_insn "*absdi2_sign_cc"
7811 [(set (reg CC_REGNUM)
7812 (compare (abs:DI (ashiftrt:DI (ashift:DI (subreg:DI
7813 (match_operand:SI 1 "register_operand" "d") 0)
7814 (const_int 32)) (const_int 32)))
7815 (const_int 0)))
7816 (set (match_operand:DI 0 "register_operand" "=d")
7817 (abs:DI (sign_extend:DI (match_dup 1))))]
7818 "TARGET_ZARCH && s390_match_ccmode (insn, CCAmode)"
7819 "lpgfr\t%0,%1"
7820 [(set_attr "op_type" "RRE")
7821 (set_attr "z10prop" "z10_c")])
7822
7823 (define_insn "*absdi2_sign"
7824 [(set (match_operand:DI 0 "register_operand" "=d")
7825 (abs:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "d"))))
7826 (clobber (reg:CC CC_REGNUM))]
7827 "TARGET_ZARCH"
7828 "lpgfr\t%0,%1"
7829 [(set_attr "op_type" "RRE")
7830 (set_attr "z10prop" "z10_c")])
7831
7832 ; lpr, lpgr
7833 (define_insn "*abs<mode>2_cc"
7834 [(set (reg CC_REGNUM)
7835 (compare (abs:GPR (match_operand:DI 1 "register_operand" "d"))
7836 (const_int 0)))
7837 (set (match_operand:GPR 0 "register_operand" "=d")
7838 (abs:GPR (match_dup 1)))]
7839 "s390_match_ccmode (insn, CCAmode)"
7840 "lp<g>r\t%0,%1"
7841 [(set_attr "op_type" "RR<E>")
7842 (set_attr "z10prop" "z10_c")])
7843
7844 ; lpr, lpgr
7845 (define_insn "*abs<mode>2_cconly"
7846 [(set (reg CC_REGNUM)
7847 (compare (abs:GPR (match_operand:GPR 1 "register_operand" "d"))
7848 (const_int 0)))
7849 (clobber (match_scratch:GPR 0 "=d"))]
7850 "s390_match_ccmode (insn, CCAmode)"
7851 "lp<g>r\t%0,%1"
7852 [(set_attr "op_type" "RR<E>")
7853 (set_attr "z10prop" "z10_c")])
7854
7855 ; lpr, lpgr
7856 (define_insn "abs<mode>2"
7857 [(set (match_operand:GPR 0 "register_operand" "=d")
7858 (abs:GPR (match_operand:GPR 1 "register_operand" "d")))
7859 (clobber (reg:CC CC_REGNUM))]
7860 ""
7861 "lp<g>r\t%0,%1"
7862 [(set_attr "op_type" "RR<E>")
7863 (set_attr "z10prop" "z10_c")])
7864
7865 ;
7866 ; abs(df|sf)2 instruction pattern(s).
7867 ;
7868
7869 (define_expand "abs<mode>2"
7870 [(parallel
7871 [(set (match_operand:BFP 0 "register_operand" "=f")
7872 (abs:BFP (match_operand:BFP 1 "register_operand" "f")))
7873 (clobber (reg:CC CC_REGNUM))])]
7874 "TARGET_HARD_FLOAT"
7875 "")
7876
7877 ; lpxbr, lpdbr, lpebr
7878 (define_insn "*abs<mode>2_cc"
7879 [(set (reg CC_REGNUM)
7880 (compare (abs:BFP (match_operand:BFP 1 "register_operand" "f"))
7881 (match_operand:BFP 2 "const0_operand" "")))
7882 (set (match_operand:BFP 0 "register_operand" "=f")
7883 (abs:BFP (match_dup 1)))]
7884 "s390_match_ccmode (insn, CCSmode) && TARGET_HARD_FLOAT"
7885 "lp<xde>br\t%0,%1"
7886 [(set_attr "op_type" "RRE")
7887 (set_attr "type" "fsimp<mode>")])
7888
7889 ; lpxbr, lpdbr, lpebr
7890 (define_insn "*abs<mode>2_cconly"
7891 [(set (reg CC_REGNUM)
7892 (compare (abs:BFP (match_operand:BFP 1 "register_operand" "f"))
7893 (match_operand:BFP 2 "const0_operand" "")))
7894 (clobber (match_scratch:BFP 0 "=f"))]
7895 "s390_match_ccmode (insn, CCSmode) && TARGET_HARD_FLOAT"
7896 "lp<xde>br\t%0,%1"
7897 [(set_attr "op_type" "RRE")
7898 (set_attr "type" "fsimp<mode>")])
7899
7900 ; lpdfr
7901 (define_insn "*abs<mode>2_nocc"
7902 [(set (match_operand:FP 0 "register_operand" "=f")
7903 (abs:FP (match_operand:FP 1 "register_operand" "<fT0>")))]
7904 "TARGET_DFP"
7905 "lpdfr\t%0,%1"
7906 [(set_attr "op_type" "RRE")
7907 (set_attr "type" "fsimp<mode>")])
7908
7909 ; lpxbr, lpdbr, lpebr
7910 ; FIXME: wflpdb does not clobber cc
7911 (define_insn "*abs<mode>2"
7912 [(set (match_operand:BFP 0 "register_operand" "=f,<vf>")
7913 (abs:BFP (match_operand:BFP 1 "register_operand" "f,<vf>")))
7914 (clobber (reg:CC CC_REGNUM))]
7915 "TARGET_HARD_FLOAT"
7916 "@
7917 lp<xde>br\t%0,%1
7918 wflpdb\t%0,%1"
7919 [(set_attr "op_type" "RRE,VRR")
7920 (set_attr "cpu_facility" "*,vec")
7921 (set_attr "type" "fsimp<mode>,*")])
7922
7923
7924 ;;
7925 ;;- Negated absolute value instructions
7926 ;;
7927
7928 ;
7929 ; Integer
7930 ;
7931
7932 (define_insn "*negabsdi2_sign_cc"
7933 [(set (reg CC_REGNUM)
7934 (compare (neg:DI (abs:DI (ashiftrt:DI (ashift:DI (subreg:DI
7935 (match_operand:SI 1 "register_operand" "d") 0)
7936 (const_int 32)) (const_int 32))))
7937 (const_int 0)))
7938 (set (match_operand:DI 0 "register_operand" "=d")
7939 (neg:DI (abs:DI (sign_extend:DI (match_dup 1)))))]
7940 "TARGET_ZARCH && s390_match_ccmode (insn, CCAmode)"
7941 "lngfr\t%0,%1"
7942 [(set_attr "op_type" "RRE")
7943 (set_attr "z10prop" "z10_c")])
7944
7945 (define_insn "*negabsdi2_sign"
7946 [(set (match_operand:DI 0 "register_operand" "=d")
7947 (neg:DI (abs:DI (sign_extend:DI
7948 (match_operand:SI 1 "register_operand" "d")))))
7949 (clobber (reg:CC CC_REGNUM))]
7950 "TARGET_ZARCH"
7951 "lngfr\t%0,%1"
7952 [(set_attr "op_type" "RRE")
7953 (set_attr "z10prop" "z10_c")])
7954
7955 ; lnr, lngr
7956 (define_insn "*negabs<mode>2_cc"
7957 [(set (reg CC_REGNUM)
7958 (compare (neg:GPR (abs:GPR (match_operand:GPR 1 "register_operand" "d")))
7959 (const_int 0)))
7960 (set (match_operand:GPR 0 "register_operand" "=d")
7961 (neg:GPR (abs:GPR (match_dup 1))))]
7962 "s390_match_ccmode (insn, CCAmode)"
7963 "ln<g>r\t%0,%1"
7964 [(set_attr "op_type" "RR<E>")
7965 (set_attr "z10prop" "z10_c")])
7966
7967 ; lnr, lngr
7968 (define_insn "*negabs<mode>2_cconly"
7969 [(set (reg CC_REGNUM)
7970 (compare (neg:GPR (abs:GPR (match_operand:GPR 1 "register_operand" "d")))
7971 (const_int 0)))
7972 (clobber (match_scratch:GPR 0 "=d"))]
7973 "s390_match_ccmode (insn, CCAmode)"
7974 "ln<g>r\t%0,%1"
7975 [(set_attr "op_type" "RR<E>")
7976 (set_attr "z10prop" "z10_c")])
7977
7978 ; lnr, lngr
7979 (define_insn "*negabs<mode>2"
7980 [(set (match_operand:GPR 0 "register_operand" "=d")
7981 (neg:GPR (abs:GPR (match_operand:GPR 1 "register_operand" "d"))))
7982 (clobber (reg:CC CC_REGNUM))]
7983 ""
7984 "ln<g>r\t%0,%1"
7985 [(set_attr "op_type" "RR<E>")
7986 (set_attr "z10prop" "z10_c")])
7987
7988 ;
7989 ; Floating point
7990 ;
7991
7992 ; lnxbr, lndbr, lnebr
7993 (define_insn "*negabs<mode>2_cc"
7994 [(set (reg CC_REGNUM)
7995 (compare (neg:BFP (abs:BFP (match_operand:BFP 1 "register_operand" "f")))
7996 (match_operand:BFP 2 "const0_operand" "")))
7997 (set (match_operand:BFP 0 "register_operand" "=f")
7998 (neg:BFP (abs:BFP (match_dup 1))))]
7999 "s390_match_ccmode (insn, CCSmode) && TARGET_HARD_FLOAT"
8000 "ln<xde>br\t%0,%1"
8001 [(set_attr "op_type" "RRE")
8002 (set_attr "type" "fsimp<mode>")])
8003
8004 ; lnxbr, lndbr, lnebr
8005 (define_insn "*negabs<mode>2_cconly"
8006 [(set (reg CC_REGNUM)
8007 (compare (neg:BFP (abs:BFP (match_operand:BFP 1 "register_operand" "f")))
8008 (match_operand:BFP 2 "const0_operand" "")))
8009 (clobber (match_scratch:BFP 0 "=f"))]
8010 "s390_match_ccmode (insn, CCSmode) && TARGET_HARD_FLOAT"
8011 "ln<xde>br\t%0,%1"
8012 [(set_attr "op_type" "RRE")
8013 (set_attr "type" "fsimp<mode>")])
8014
8015 ; lndfr
8016 (define_insn "*negabs<mode>2_nocc"
8017 [(set (match_operand:FP 0 "register_operand" "=f")
8018 (neg:FP (abs:FP (match_operand:BFP 1 "register_operand" "<fT0>"))))]
8019 "TARGET_DFP"
8020 "lndfr\t%0,%1"
8021 [(set_attr "op_type" "RRE")
8022 (set_attr "type" "fsimp<mode>")])
8023
8024 ; lnxbr, lndbr, lnebr
8025 ; FIXME: wflndb does not clobber cc
8026 (define_insn "*negabs<mode>2"
8027 [(set (match_operand:BFP 0 "register_operand" "=f,<vf>")
8028 (neg:BFP (abs:BFP (match_operand:BFP 1 "register_operand" "f,<vf>"))))
8029 (clobber (reg:CC CC_REGNUM))]
8030 "TARGET_HARD_FLOAT"
8031 "@
8032 ln<xde>br\t%0,%1
8033 wflndb\t%0,%1"
8034 [(set_attr "op_type" "RRE,VRR")
8035 (set_attr "cpu_facility" "*,vec")
8036 (set_attr "type" "fsimp<mode>,*")])
8037
8038 ;;
8039 ;;- Square root instructions.
8040 ;;
8041
8042 ;
8043 ; sqrt(df|sf)2 instruction pattern(s).
8044 ;
8045
8046 ; sqxbr, sqdbr, sqebr, sqdb, sqeb
8047 (define_insn "sqrt<mode>2"
8048 [(set (match_operand:BFP 0 "register_operand" "=f, f,<vf>")
8049 (sqrt:BFP (match_operand:BFP 1 "general_operand" "f,<Rf>,<vf>")))]
8050 "TARGET_HARD_FLOAT"
8051 "@
8052 sq<xde>br\t%0,%1
8053 sq<xde>b\t%0,%1
8054 wfsqdb\t%v0,%v1"
8055 [(set_attr "op_type" "RRE,RXE,VRR")
8056 (set_attr "type" "fsqrt<mode>")
8057 (set_attr "cpu_facility" "*,*,vec")])
8058
8059
8060 ;;
8061 ;;- One complement instructions.
8062 ;;
8063
8064 ;
8065 ; one_cmpl(di|si|hi|qi)2 instruction pattern(s).
8066 ;
8067
8068 (define_expand "one_cmpl<mode>2"
8069 [(parallel
8070 [(set (match_operand:INT 0 "register_operand" "")
8071 (xor:INT (match_operand:INT 1 "register_operand" "")
8072 (const_int -1)))
8073 (clobber (reg:CC CC_REGNUM))])]
8074 ""
8075 "")
8076
8077
8078 ;;
8079 ;; Find leftmost bit instructions.
8080 ;;
8081
8082 (define_expand "clzdi2"
8083 [(set (match_operand:DI 0 "register_operand" "=d")
8084 (clz:DI (match_operand:DI 1 "register_operand" "d")))]
8085 "TARGET_EXTIMM && TARGET_ZARCH"
8086 {
8087 rtx insn, clz_equal;
8088 rtx wide_reg = gen_reg_rtx (TImode);
8089 rtx msb = gen_rtx_CONST_INT (DImode, (unsigned HOST_WIDE_INT) 1 << 63);
8090
8091 clz_equal = gen_rtx_CLZ (DImode, operands[1]);
8092
8093 emit_insn (gen_clztidi2 (wide_reg, operands[1], msb));
8094
8095 insn = emit_move_insn (operands[0], gen_highpart (DImode, wide_reg));
8096 set_unique_reg_note (insn, REG_EQUAL, clz_equal);
8097
8098 DONE;
8099 })
8100
8101 (define_insn "clztidi2"
8102 [(set (match_operand:TI 0 "register_operand" "=d")
8103 (ior:TI
8104 (ashift:TI
8105 (zero_extend:TI
8106 (xor:DI (match_operand:DI 1 "register_operand" "d")
8107 (lshiftrt (match_operand:DI 2 "const_int_operand" "")
8108 (subreg:SI (clz:DI (match_dup 1)) 4))))
8109
8110 (const_int 64))
8111 (zero_extend:TI (clz:DI (match_dup 1)))))
8112 (clobber (reg:CC CC_REGNUM))]
8113 "(unsigned HOST_WIDE_INT) INTVAL (operands[2])
8114 == (unsigned HOST_WIDE_INT) 1 << 63
8115 && TARGET_EXTIMM && TARGET_ZARCH"
8116 "flogr\t%0,%1"
8117 [(set_attr "op_type" "RRE")])
8118
8119
8120 ;;
8121 ;;- Rotate instructions.
8122 ;;
8123
8124 ;
8125 ; rotl(di|si)3 instruction pattern(s).
8126 ;
8127
8128 ; rll, rllg
8129 (define_insn "rotl<mode>3"
8130 [(set (match_operand:GPR 0 "register_operand" "=d")
8131 (rotate:GPR (match_operand:GPR 1 "register_operand" "d")
8132 (match_operand:SI 2 "shift_count_or_setmem_operand" "Y")))]
8133 "TARGET_CPU_ZARCH"
8134 "rll<g>\t%0,%1,%Y2"
8135 [(set_attr "op_type" "RSE")
8136 (set_attr "atype" "reg")
8137 (set_attr "z10prop" "z10_super_E1")])
8138
8139 ; rll, rllg
8140 (define_insn "*rotl<mode>3_and"
8141 [(set (match_operand:GPR 0 "register_operand" "=d")
8142 (rotate:GPR (match_operand:GPR 1 "register_operand" "d")
8143 (and:SI (match_operand:SI 2 "shift_count_or_setmem_operand" "Y")
8144 (match_operand:SI 3 "const_int_operand" "n"))))]
8145 "TARGET_CPU_ZARCH && (INTVAL (operands[3]) & 63) == 63"
8146 "rll<g>\t%0,%1,%Y2"
8147 [(set_attr "op_type" "RSE")
8148 (set_attr "atype" "reg")
8149 (set_attr "z10prop" "z10_super_E1")])
8150
8151
8152 ;;
8153 ;;- Shift instructions.
8154 ;;
8155
8156 ;
8157 ; (ashl|lshr)(di|si)3 instruction pattern(s).
8158 ; Left shifts and logical right shifts
8159
8160 (define_expand "<shift><mode>3"
8161 [(set (match_operand:DSI 0 "register_operand" "")
8162 (SHIFT:DSI (match_operand:DSI 1 "register_operand" "")
8163 (match_operand:SI 2 "shift_count_or_setmem_operand" "")))]
8164 ""
8165 "")
8166
8167 ; sldl, srdl
8168 (define_insn "*<shift>di3_31"
8169 [(set (match_operand:DI 0 "register_operand" "=d")
8170 (SHIFT:DI (match_operand:DI 1 "register_operand" "0")
8171 (match_operand:SI 2 "shift_count_or_setmem_operand" "Y")))]
8172 "!TARGET_ZARCH"
8173 "s<lr>dl\t%0,%Y2"
8174 [(set_attr "op_type" "RS")
8175 (set_attr "atype" "reg")
8176 (set_attr "z196prop" "z196_cracked")])
8177
8178 ; sll, srl, sllg, srlg, sllk, srlk
8179 (define_insn "*<shift><mode>3"
8180 [(set (match_operand:GPR 0 "register_operand" "=d,d")
8181 (SHIFT:GPR (match_operand:GPR 1 "register_operand" "<d0>,d")
8182 (match_operand:SI 2 "shift_count_or_setmem_operand" "Y,Y")))]
8183 ""
8184 "@
8185 s<lr>l<g>\t%0,<1>%Y2
8186 s<lr>l<gk>\t%0,%1,%Y2"
8187 [(set_attr "op_type" "RS<E>,RSY")
8188 (set_attr "atype" "reg,reg")
8189 (set_attr "cpu_facility" "*,z196")
8190 (set_attr "z10prop" "z10_super_E1,*")])
8191
8192 ; sldl, srdl
8193 (define_insn "*<shift>di3_31_and"
8194 [(set (match_operand:DI 0 "register_operand" "=d")
8195 (SHIFT:DI (match_operand:DI 1 "register_operand" "0")
8196 (and:SI (match_operand:SI 2 "shift_count_or_setmem_operand" "Y")
8197 (match_operand:SI 3 "const_int_operand" "n"))))]
8198 "!TARGET_ZARCH && (INTVAL (operands[3]) & 63) == 63"
8199 "s<lr>dl\t%0,%Y2"
8200 [(set_attr "op_type" "RS")
8201 (set_attr "atype" "reg")])
8202
8203 ; sll, srl, sllg, srlg, sllk, srlk
8204 (define_insn "*<shift><mode>3_and"
8205 [(set (match_operand:GPR 0 "register_operand" "=d,d")
8206 (SHIFT:GPR (match_operand:GPR 1 "register_operand" "<d0>,d")
8207 (and:SI (match_operand:SI 2 "shift_count_or_setmem_operand" "Y,Y")
8208 (match_operand:SI 3 "const_int_operand" "n,n"))))]
8209 "(INTVAL (operands[3]) & 63) == 63"
8210 "@
8211 s<lr>l<g>\t%0,<1>%Y2
8212 s<lr>l<gk>\t%0,%1,%Y2"
8213 [(set_attr "op_type" "RS<E>,RSY")
8214 (set_attr "atype" "reg,reg")
8215 (set_attr "cpu_facility" "*,z196")
8216 (set_attr "z10prop" "z10_super_E1,*")])
8217
8218 ;
8219 ; ashr(di|si)3 instruction pattern(s).
8220 ; Arithmetic right shifts
8221
8222 (define_expand "ashr<mode>3"
8223 [(parallel
8224 [(set (match_operand:DSI 0 "register_operand" "")
8225 (ashiftrt:DSI (match_operand:DSI 1 "register_operand" "")
8226 (match_operand:SI 2 "shift_count_or_setmem_operand" "")))
8227 (clobber (reg:CC CC_REGNUM))])]
8228 ""
8229 "")
8230
8231 (define_insn "*ashrdi3_cc_31"
8232 [(set (reg CC_REGNUM)
8233 (compare (ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
8234 (match_operand:SI 2 "shift_count_or_setmem_operand" "Y"))
8235 (const_int 0)))
8236 (set (match_operand:DI 0 "register_operand" "=d")
8237 (ashiftrt:DI (match_dup 1) (match_dup 2)))]
8238 "!TARGET_ZARCH && s390_match_ccmode(insn, CCSmode)"
8239 "srda\t%0,%Y2"
8240 [(set_attr "op_type" "RS")
8241 (set_attr "atype" "reg")])
8242
8243 (define_insn "*ashrdi3_cconly_31"
8244 [(set (reg CC_REGNUM)
8245 (compare (ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
8246 (match_operand:SI 2 "shift_count_or_setmem_operand" "Y"))
8247 (const_int 0)))
8248 (clobber (match_scratch:DI 0 "=d"))]
8249 "!TARGET_ZARCH && s390_match_ccmode(insn, CCSmode)"
8250 "srda\t%0,%Y2"
8251 [(set_attr "op_type" "RS")
8252 (set_attr "atype" "reg")])
8253
8254 (define_insn "*ashrdi3_31"
8255 [(set (match_operand:DI 0 "register_operand" "=d")
8256 (ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
8257 (match_operand:SI 2 "shift_count_or_setmem_operand" "Y")))
8258 (clobber (reg:CC CC_REGNUM))]
8259 "!TARGET_ZARCH"
8260 "srda\t%0,%Y2"
8261 [(set_attr "op_type" "RS")
8262 (set_attr "atype" "reg")])
8263
8264 ; sra, srag, srak
8265 (define_insn "*ashr<mode>3_cc"
8266 [(set (reg CC_REGNUM)
8267 (compare (ashiftrt:GPR (match_operand:GPR 1 "register_operand" "<d0>,d")
8268 (match_operand:SI 2 "shift_count_or_setmem_operand" "Y,Y"))
8269 (const_int 0)))
8270 (set (match_operand:GPR 0 "register_operand" "=d,d")
8271 (ashiftrt:GPR (match_dup 1) (match_dup 2)))]
8272 "s390_match_ccmode(insn, CCSmode)"
8273 "@
8274 sra<g>\t%0,<1>%Y2
8275 sra<gk>\t%0,%1,%Y2"
8276 [(set_attr "op_type" "RS<E>,RSY")
8277 (set_attr "atype" "reg,reg")
8278 (set_attr "cpu_facility" "*,z196")
8279 (set_attr "z10prop" "z10_super_E1,*")])
8280
8281 ; sra, srag, srak
8282 (define_insn "*ashr<mode>3_cconly"
8283 [(set (reg CC_REGNUM)
8284 (compare (ashiftrt:GPR (match_operand:GPR 1 "register_operand" "<d0>,d")
8285 (match_operand:SI 2 "shift_count_or_setmem_operand" "Y,Y"))
8286 (const_int 0)))
8287 (clobber (match_scratch:GPR 0 "=d,d"))]
8288 "s390_match_ccmode(insn, CCSmode)"
8289 "@
8290 sra<g>\t%0,<1>%Y2
8291 sra<gk>\t%0,%1,%Y2"
8292 [(set_attr "op_type" "RS<E>,RSY")
8293 (set_attr "atype" "reg,reg")
8294 (set_attr "cpu_facility" "*,z196")
8295 (set_attr "z10prop" "z10_super_E1,*")])
8296
8297 ; sra, srag
8298 (define_insn "*ashr<mode>3"
8299 [(set (match_operand:GPR 0 "register_operand" "=d,d")
8300 (ashiftrt:GPR (match_operand:GPR 1 "register_operand" "<d0>,d")
8301 (match_operand:SI 2 "shift_count_or_setmem_operand" "Y,Y")))
8302 (clobber (reg:CC CC_REGNUM))]
8303 ""
8304 "@
8305 sra<g>\t%0,<1>%Y2
8306 sra<gk>\t%0,%1,%Y2"
8307 [(set_attr "op_type" "RS<E>,RSY")
8308 (set_attr "atype" "reg,reg")
8309 (set_attr "cpu_facility" "*,z196")
8310 (set_attr "z10prop" "z10_super_E1,*")])
8311
8312
8313 ; shift pattern with implicit ANDs
8314
8315 (define_insn "*ashrdi3_cc_31_and"
8316 [(set (reg CC_REGNUM)
8317 (compare (ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
8318 (and:SI (match_operand:SI 2 "shift_count_or_setmem_operand" "Y")
8319 (match_operand:SI 3 "const_int_operand" "n")))
8320 (const_int 0)))
8321 (set (match_operand:DI 0 "register_operand" "=d")
8322 (ashiftrt:DI (match_dup 1) (and:SI (match_dup 2) (match_dup 3))))]
8323 "!TARGET_ZARCH && s390_match_ccmode(insn, CCSmode)
8324 && (INTVAL (operands[3]) & 63) == 63"
8325 "srda\t%0,%Y2"
8326 [(set_attr "op_type" "RS")
8327 (set_attr "atype" "reg")])
8328
8329 (define_insn "*ashrdi3_cconly_31_and"
8330 [(set (reg CC_REGNUM)
8331 (compare (ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
8332 (and:SI (match_operand:SI 2 "shift_count_or_setmem_operand" "Y")
8333 (match_operand:SI 3 "const_int_operand" "n")))
8334 (const_int 0)))
8335 (clobber (match_scratch:DI 0 "=d"))]
8336 "!TARGET_ZARCH && s390_match_ccmode(insn, CCSmode)
8337 && (INTVAL (operands[3]) & 63) == 63"
8338 "srda\t%0,%Y2"
8339 [(set_attr "op_type" "RS")
8340 (set_attr "atype" "reg")])
8341
8342 (define_insn "*ashrdi3_31_and"
8343 [(set (match_operand:DI 0 "register_operand" "=d")
8344 (ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
8345 (and:SI (match_operand:SI 2 "shift_count_or_setmem_operand" "Y")
8346 (match_operand:SI 3 "const_int_operand" "n"))))
8347 (clobber (reg:CC CC_REGNUM))]
8348 "!TARGET_ZARCH && (INTVAL (operands[3]) & 63) == 63"
8349 "srda\t%0,%Y2"
8350 [(set_attr "op_type" "RS")
8351 (set_attr "atype" "reg")])
8352
8353 ; sra, srag, srak
8354 (define_insn "*ashr<mode>3_cc_and"
8355 [(set (reg CC_REGNUM)
8356 (compare (ashiftrt:GPR (match_operand:GPR 1 "register_operand" "<d0>,d")
8357 (and:SI (match_operand:SI 2 "shift_count_or_setmem_operand" "Y,Y")
8358 (match_operand:SI 3 "const_int_operand" "n,n")))
8359 (const_int 0)))
8360 (set (match_operand:GPR 0 "register_operand" "=d,d")
8361 (ashiftrt:GPR (match_dup 1) (and:SI (match_dup 2) (match_dup 3))))]
8362 "s390_match_ccmode(insn, CCSmode) && (INTVAL (operands[3]) & 63) == 63"
8363 "@
8364 sra<g>\t%0,<1>%Y2
8365 sra<gk>\t%0,%1,%Y2"
8366 [(set_attr "op_type" "RS<E>,RSY")
8367 (set_attr "atype" "reg,reg")
8368 (set_attr "cpu_facility" "*,z196")
8369 (set_attr "z10prop" "z10_super_E1,*")])
8370
8371 ; sra, srag, srak
8372 (define_insn "*ashr<mode>3_cconly_and"
8373 [(set (reg CC_REGNUM)
8374 (compare (ashiftrt:GPR (match_operand:GPR 1 "register_operand" "<d0>,d")
8375 (and:SI (match_operand:SI 2 "shift_count_or_setmem_operand" "Y,Y")
8376 (match_operand:SI 3 "const_int_operand" "n,n")))
8377 (const_int 0)))
8378 (clobber (match_scratch:GPR 0 "=d,d"))]
8379 "s390_match_ccmode(insn, CCSmode) && (INTVAL (operands[3]) & 63) == 63"
8380 "@
8381 sra<g>\t%0,<1>%Y2
8382 sra<gk>\t%0,%1,%Y2"
8383 [(set_attr "op_type" "RS<E>,RSY")
8384 (set_attr "atype" "reg,reg")
8385 (set_attr "cpu_facility" "*,z196")
8386 (set_attr "z10prop" "z10_super_E1,*")])
8387
8388 ; sra, srag, srak
8389 (define_insn "*ashr<mode>3_and"
8390 [(set (match_operand:GPR 0 "register_operand" "=d,d")
8391 (ashiftrt:GPR (match_operand:GPR 1 "register_operand" "<d0>,d")
8392 (and:SI (match_operand:SI 2 "shift_count_or_setmem_operand" "Y,Y")
8393 (match_operand:SI 3 "const_int_operand" "n,n"))))
8394 (clobber (reg:CC CC_REGNUM))]
8395 "(INTVAL (operands[3]) & 63) == 63"
8396 "@
8397 sra<g>\t%0,<1>%Y2
8398 sra<gk>\t%0,%1,%Y2"
8399 [(set_attr "op_type" "RS<E>,RSY")
8400 (set_attr "atype" "reg,reg")
8401 (set_attr "cpu_facility" "*,z196")
8402 (set_attr "z10prop" "z10_super_E1,*")])
8403
8404
8405 ;;
8406 ;; Branch instruction patterns.
8407 ;;
8408
8409 (define_expand "cbranch<mode>4"
8410 [(set (pc)
8411 (if_then_else (match_operator 0 "comparison_operator"
8412 [(match_operand:GPR 1 "register_operand" "")
8413 (match_operand:GPR 2 "general_operand" "")])
8414 (label_ref (match_operand 3 "" ""))
8415 (pc)))]
8416 ""
8417 "s390_emit_jump (operands[3],
8418 s390_emit_compare (GET_CODE (operands[0]), operands[1], operands[2]));
8419 DONE;")
8420
8421 (define_expand "cbranch<mode>4"
8422 [(set (pc)
8423 (if_then_else (match_operator 0 "comparison_operator"
8424 [(match_operand:FP 1 "register_operand" "")
8425 (match_operand:FP 2 "general_operand" "")])
8426 (label_ref (match_operand 3 "" ""))
8427 (pc)))]
8428 "TARGET_HARD_FLOAT"
8429 "s390_emit_jump (operands[3],
8430 s390_emit_compare (GET_CODE (operands[0]), operands[1], operands[2]));
8431 DONE;")
8432
8433 (define_expand "cbranchcc4"
8434 [(set (pc)
8435 (if_then_else (match_operator 0 "s390_comparison"
8436 [(match_operand 1 "cc_reg_operand" "")
8437 (match_operand 2 "const_int_operand" "")])
8438 (label_ref (match_operand 3 "" ""))
8439 (pc)))]
8440 ""
8441 "")
8442
8443
8444 ;;
8445 ;;- Conditional jump instructions.
8446 ;;
8447
8448 (define_insn "*cjump_64"
8449 [(set (pc)
8450 (if_then_else
8451 (match_operator 1 "s390_comparison" [(reg CC_REGNUM)
8452 (match_operand 2 "const_int_operand" "")])
8453 (label_ref (match_operand 0 "" ""))
8454 (pc)))]
8455 "TARGET_CPU_ZARCH"
8456 {
8457 if (get_attr_length (insn) == 4)
8458 return "j%C1\t%l0";
8459 else
8460 return "jg%C1\t%l0";
8461 }
8462 [(set_attr "op_type" "RI")
8463 (set_attr "type" "branch")
8464 (set (attr "length")
8465 (if_then_else (lt (abs (minus (pc) (match_dup 0))) (const_int 60000))
8466 (const_int 4) (const_int 6)))])
8467
8468 (define_insn "*cjump_31"
8469 [(set (pc)
8470 (if_then_else
8471 (match_operator 1 "s390_comparison" [(reg CC_REGNUM)
8472 (match_operand 2 "const_int_operand" "")])
8473 (label_ref (match_operand 0 "" ""))
8474 (pc)))]
8475 "!TARGET_CPU_ZARCH"
8476 {
8477 gcc_assert (get_attr_length (insn) == 4);
8478 return "j%C1\t%l0";
8479 }
8480 [(set_attr "op_type" "RI")
8481 (set_attr "type" "branch")
8482 (set (attr "length")
8483 (if_then_else (not (match_test "flag_pic"))
8484 (if_then_else (lt (abs (minus (pc) (match_dup 0))) (const_int 60000))
8485 (const_int 4) (const_int 6))
8486 (if_then_else (lt (abs (minus (pc) (match_dup 0))) (const_int 60000))
8487 (const_int 4) (const_int 8))))])
8488
8489 (define_insn "*cjump_long"
8490 [(set (pc)
8491 (if_then_else
8492 (match_operator 1 "s390_comparison" [(reg CC_REGNUM) (const_int 0)])
8493 (match_operand 0 "address_operand" "ZQZR")
8494 (pc)))]
8495 ""
8496 {
8497 if (get_attr_op_type (insn) == OP_TYPE_RR)
8498 return "b%C1r\t%0";
8499 else
8500 return "b%C1\t%a0";
8501 }
8502 [(set (attr "op_type")
8503 (if_then_else (match_operand 0 "register_operand" "")
8504 (const_string "RR") (const_string "RX")))
8505 (set_attr "type" "branch")
8506 (set_attr "atype" "agen")])
8507
8508 ;; A conditional return instruction.
8509 (define_insn "*c<code>"
8510 [(set (pc)
8511 (if_then_else
8512 (match_operator 0 "s390_comparison" [(reg CC_REGNUM) (const_int 0)])
8513 (ANY_RETURN)
8514 (pc)))]
8515 "s390_can_use_<code>_insn ()"
8516 "b%C0r\t%%r14"
8517 [(set_attr "op_type" "RR")
8518 (set_attr "type" "jsr")
8519 (set_attr "atype" "agen")])
8520
8521 ;;
8522 ;;- Negated conditional jump instructions.
8523 ;;
8524
8525 (define_insn "*icjump_64"
8526 [(set (pc)
8527 (if_then_else
8528 (match_operator 1 "s390_comparison" [(reg CC_REGNUM) (const_int 0)])
8529 (pc)
8530 (label_ref (match_operand 0 "" ""))))]
8531 "TARGET_CPU_ZARCH"
8532 {
8533 if (get_attr_length (insn) == 4)
8534 return "j%D1\t%l0";
8535 else
8536 return "jg%D1\t%l0";
8537 }
8538 [(set_attr "op_type" "RI")
8539 (set_attr "type" "branch")
8540 (set (attr "length")
8541 (if_then_else (lt (abs (minus (pc) (match_dup 0))) (const_int 60000))
8542 (const_int 4) (const_int 6)))])
8543
8544 (define_insn "*icjump_31"
8545 [(set (pc)
8546 (if_then_else
8547 (match_operator 1 "s390_comparison" [(reg CC_REGNUM) (const_int 0)])
8548 (pc)
8549 (label_ref (match_operand 0 "" ""))))]
8550 "!TARGET_CPU_ZARCH"
8551 {
8552 gcc_assert (get_attr_length (insn) == 4);
8553 return "j%D1\t%l0";
8554 }
8555 [(set_attr "op_type" "RI")
8556 (set_attr "type" "branch")
8557 (set (attr "length")
8558 (if_then_else (not (match_test "flag_pic"))
8559 (if_then_else (lt (abs (minus (pc) (match_dup 0))) (const_int 60000))
8560 (const_int 4) (const_int 6))
8561 (if_then_else (lt (abs (minus (pc) (match_dup 0))) (const_int 60000))
8562 (const_int 4) (const_int 8))))])
8563
8564 (define_insn "*icjump_long"
8565 [(set (pc)
8566 (if_then_else
8567 (match_operator 1 "s390_comparison" [(reg CC_REGNUM) (const_int 0)])
8568 (pc)
8569 (match_operand 0 "address_operand" "ZQZR")))]
8570 ""
8571 {
8572 if (get_attr_op_type (insn) == OP_TYPE_RR)
8573 return "b%D1r\t%0";
8574 else
8575 return "b%D1\t%a0";
8576 }
8577 [(set (attr "op_type")
8578 (if_then_else (match_operand 0 "register_operand" "")
8579 (const_string "RR") (const_string "RX")))
8580 (set_attr "type" "branch")
8581 (set_attr "atype" "agen")])
8582
8583 ;;
8584 ;;- Trap instructions.
8585 ;;
8586
8587 (define_insn "trap"
8588 [(trap_if (const_int 1) (const_int 0))]
8589 ""
8590 "j\t.+2"
8591 [(set_attr "op_type" "RI")
8592 (set_attr "type" "branch")])
8593
8594 (define_expand "ctrap<mode>4"
8595 [(trap_if (match_operator 0 "comparison_operator"
8596 [(match_operand:GPR 1 "register_operand" "")
8597 (match_operand:GPR 2 "general_operand" "")])
8598 (match_operand 3 "const0_operand" ""))]
8599 ""
8600 {
8601 rtx cond = s390_emit_compare (GET_CODE (operands[0]),
8602 operands[1], operands[2]);
8603 emit_insn (gen_condtrap (cond, XEXP (cond, 0)));
8604 DONE;
8605 })
8606
8607 (define_expand "ctrap<mode>4"
8608 [(trap_if (match_operator 0 "comparison_operator"
8609 [(match_operand:FP 1 "register_operand" "")
8610 (match_operand:FP 2 "general_operand" "")])
8611 (match_operand 3 "const0_operand" ""))]
8612 ""
8613 {
8614 rtx cond = s390_emit_compare (GET_CODE (operands[0]),
8615 operands[1], operands[2]);
8616 emit_insn (gen_condtrap (cond, XEXP (cond, 0)));
8617 DONE;
8618 })
8619
8620 (define_insn "condtrap"
8621 [(trap_if (match_operator 0 "s390_comparison"
8622 [(match_operand 1 "cc_reg_operand" "c")
8623 (const_int 0)])
8624 (const_int 0))]
8625 ""
8626 "j%C0\t.+2";
8627 [(set_attr "op_type" "RI")
8628 (set_attr "type" "branch")])
8629
8630 ; crt, cgrt, cit, cgit
8631 (define_insn "*cmp_and_trap_signed_int<mode>"
8632 [(trap_if (match_operator 0 "s390_signed_integer_comparison"
8633 [(match_operand:GPR 1 "register_operand" "d,d")
8634 (match_operand:GPR 2 "nonmemory_operand" "d,K")])
8635 (const_int 0))]
8636 "TARGET_Z10"
8637 "@
8638 c<g>rt%C0\t%1,%2
8639 c<g>it%C0\t%1,%h2"
8640 [(set_attr "op_type" "RRF,RIE")
8641 (set_attr "type" "branch")
8642 (set_attr "z10prop" "z10_super_c,z10_super")])
8643
8644 ; clrt, clgrt, clfit, clgit, clt, clgt
8645 (define_insn "*cmp_and_trap_unsigned_int<mode>"
8646 [(trap_if (match_operator 0 "s390_unsigned_integer_comparison"
8647 [(match_operand:GPR 1 "register_operand" "d,d, d")
8648 (match_operand:GPR 2 "general_operand" "d,D,RT")])
8649 (const_int 0))]
8650 "TARGET_Z10"
8651 "@
8652 cl<g>rt%C0\t%1,%2
8653 cl<gf>it%C0\t%1,%x2
8654 cl<g>t%C0\t%1,%2"
8655 [(set_attr "op_type" "RRF,RIE,RSY")
8656 (set_attr "type" "branch")
8657 (set_attr "z10prop" "z10_super_c,z10_super,*")
8658 (set_attr "cpu_facility" "z10,z10,zEC12")])
8659
8660 ; lat, lgat
8661 (define_insn "*load_and_trap<mode>"
8662 [(trap_if (eq (match_operand:GPR 0 "memory_operand" "RT")
8663 (const_int 0))
8664 (const_int 0))
8665 (set (match_operand:GPR 1 "register_operand" "=d")
8666 (match_dup 0))]
8667 "TARGET_ZEC12"
8668 "l<g>at\t%1,%0"
8669 [(set_attr "op_type" "RXY")])
8670
8671
8672 ;;
8673 ;;- Loop instructions.
8674 ;;
8675 ;; This is all complicated by the fact that since this is a jump insn
8676 ;; we must handle our own output reloads.
8677
8678 ;; branch on index
8679
8680 ; This splitter will be matched by combine and has to add the 2 moves
8681 ; necessary to load the compare and the increment values into a
8682 ; register pair as needed by brxle.
8683
8684 (define_insn_and_split "*brx_stage1_<GPR:mode>"
8685 [(set (pc)
8686 (if_then_else
8687 (match_operator 6 "s390_brx_operator"
8688 [(plus:GPR (match_operand:GPR 1 "register_operand" "")
8689 (match_operand:GPR 2 "general_operand" ""))
8690 (match_operand:GPR 3 "register_operand" "")])
8691 (label_ref (match_operand 0 "" ""))
8692 (pc)))
8693 (set (match_operand:GPR 4 "nonimmediate_operand" "")
8694 (plus:GPR (match_dup 1) (match_dup 2)))
8695 (clobber (match_scratch:GPR 5 ""))]
8696 "TARGET_CPU_ZARCH"
8697 "#"
8698 "!reload_completed && !reload_in_progress"
8699 [(set (match_dup 7) (match_dup 2)) ; the increment
8700 (set (match_dup 8) (match_dup 3)) ; the comparison value
8701 (parallel [(set (pc)
8702 (if_then_else
8703 (match_op_dup 6
8704 [(plus:GPR (match_dup 1) (match_dup 7))
8705 (match_dup 8)])
8706 (label_ref (match_dup 0))
8707 (pc)))
8708 (set (match_dup 4)
8709 (plus:GPR (match_dup 1) (match_dup 7)))
8710 (clobber (match_dup 5))
8711 (clobber (reg:CC CC_REGNUM))])]
8712 {
8713 rtx dreg = gen_reg_rtx (word_mode == DImode ? TImode : DImode);
8714 operands[7] = gen_lowpart (<GPR:MODE>mode,
8715 gen_highpart (word_mode, dreg));
8716 operands[8] = gen_lowpart (<GPR:MODE>mode,
8717 gen_lowpart (word_mode, dreg));
8718 })
8719
8720 ; brxlg, brxhg
8721
8722 (define_insn_and_split "*brxg_64bit"
8723 [(set (pc)
8724 (if_then_else
8725 (match_operator 5 "s390_brx_operator"
8726 [(plus:DI (match_operand:DI 1 "register_operand" "d,d,d")
8727 (subreg:DI (match_operand:TI 2 "register_operand" "d,d,d") 0))
8728 (subreg:DI (match_dup 2) 8)])
8729 (label_ref (match_operand 0 "" ""))
8730 (pc)))
8731 (set (match_operand:DI 3 "nonimmediate_operand" "=1,?X,?X")
8732 (plus:DI (match_dup 1)
8733 (subreg:DI (match_dup 2) 0)))
8734 (clobber (match_scratch:DI 4 "=X,&1,&?d"))
8735 (clobber (reg:CC CC_REGNUM))]
8736 "TARGET_ZARCH"
8737 {
8738 if (which_alternative != 0)
8739 return "#";
8740 else if (get_attr_length (insn) == 6)
8741 return "brx%E5g\t%1,%2,%l0";
8742 else
8743 return "agr\t%1,%2\;cgr\t%1,%M2\;jg%C5\t%l0";
8744 }
8745 "&& reload_completed
8746 && (!REG_P (operands[3])
8747 || !rtx_equal_p (operands[1], operands[3]))"
8748 [(set (match_dup 4) (match_dup 1))
8749 (parallel [(set (match_dup 4) (plus:DI (match_dup 4) (subreg:DI (match_dup 2) 0)))
8750 (clobber (reg:CC CC_REGNUM))])
8751 (set (reg:CCS CC_REGNUM) (compare:CCS (match_dup 4) (subreg:DI (match_dup 2) 8)))
8752 (set (match_dup 3) (match_dup 4))
8753 (set (pc) (if_then_else (match_op_dup 5 [(reg:CCS CC_REGNUM) (const_int 0)])
8754 (label_ref (match_dup 0))
8755 (pc)))]
8756 ""
8757 [(set_attr "op_type" "RIE")
8758 (set_attr "type" "branch")
8759 (set (attr "length")
8760 (if_then_else (lt (abs (minus (pc) (match_dup 0))) (const_int 60000))
8761 (const_int 6) (const_int 16)))])
8762
8763 ; brxle, brxh
8764
8765 (define_insn_and_split "*brx_64bit"
8766 [(set (pc)
8767 (if_then_else
8768 (match_operator 5 "s390_brx_operator"
8769 [(plus:SI (match_operand:SI 1 "register_operand" "d,d,d")
8770 (subreg:SI (match_operand:TI 2 "register_operand" "d,d,d") 4))
8771 (subreg:SI (match_dup 2) 12)])
8772 (label_ref (match_operand 0 "" ""))
8773 (pc)))
8774 (set (match_operand:SI 3 "nonimmediate_operand" "=1,?X,?X")
8775 (plus:SI (match_dup 1)
8776 (subreg:SI (match_dup 2) 4)))
8777 (clobber (match_scratch:SI 4 "=X,&1,&?d"))
8778 (clobber (reg:CC CC_REGNUM))]
8779 "TARGET_ZARCH"
8780 {
8781 if (which_alternative != 0)
8782 return "#";
8783 else if (get_attr_length (insn) == 6)
8784 return "brx%C5\t%1,%2,%l0";
8785 else
8786 return "ar\t%1,%2\;cr\t%1,%M2\;jg%C5\t%l0";
8787 }
8788 "&& reload_completed
8789 && (!REG_P (operands[3])
8790 || !rtx_equal_p (operands[1], operands[3]))"
8791 [(set (match_dup 4) (match_dup 1))
8792 (parallel [(set (match_dup 4) (plus:SI (match_dup 4) (subreg:SI (match_dup 2) 4)))
8793 (clobber (reg:CC CC_REGNUM))])
8794 (set (reg:CCS CC_REGNUM) (compare:CCS (match_dup 4) (subreg:SI (match_dup 2) 12)))
8795 (set (match_dup 3) (match_dup 4))
8796 (set (pc) (if_then_else (match_op_dup 5 [(reg:CCS CC_REGNUM) (const_int 0)])
8797 (label_ref (match_dup 0))
8798 (pc)))]
8799 ""
8800 [(set_attr "op_type" "RSI")
8801 (set_attr "type" "branch")
8802 (set (attr "length")
8803 (if_then_else (lt (abs (minus (pc) (match_dup 0))) (const_int 60000))
8804 (const_int 6) (const_int 14)))])
8805
8806 ; brxle, brxh
8807
8808 (define_insn_and_split "*brx_31bit"
8809 [(set (pc)
8810 (if_then_else
8811 (match_operator 5 "s390_brx_operator"
8812 [(plus:SI (match_operand:SI 1 "register_operand" "d,d,d")
8813 (subreg:SI (match_operand:DI 2 "register_operand" "d,d,d") 0))
8814 (subreg:SI (match_dup 2) 4)])
8815 (label_ref (match_operand 0 "" ""))
8816 (pc)))
8817 (set (match_operand:SI 3 "nonimmediate_operand" "=1,?X,?X")
8818 (plus:SI (match_dup 1)
8819 (subreg:SI (match_dup 2) 0)))
8820 (clobber (match_scratch:SI 4 "=X,&1,&?d"))
8821 (clobber (reg:CC CC_REGNUM))]
8822 "!TARGET_ZARCH && TARGET_CPU_ZARCH"
8823 {
8824 if (which_alternative != 0)
8825 return "#";
8826 else if (get_attr_length (insn) == 6)
8827 return "brx%C5\t%1,%2,%l0";
8828 else
8829 return "ar\t%1,%2\;cr\t%1,%M2\;jg%C5\t%l0";
8830 }
8831 "&& reload_completed
8832 && (!REG_P (operands[3])
8833 || !rtx_equal_p (operands[1], operands[3]))"
8834 [(set (match_dup 4) (match_dup 1))
8835 (parallel [(set (match_dup 4) (plus:SI (match_dup 4) (subreg:SI (match_dup 2) 0)))
8836 (clobber (reg:CC CC_REGNUM))])
8837 (set (reg:CCS CC_REGNUM) (compare:CCS (match_dup 4) (subreg:SI (match_dup 2) 4)))
8838 (set (match_dup 3) (match_dup 4))
8839 (set (pc) (if_then_else (match_op_dup 5 [(reg:CCS CC_REGNUM) (const_int 0)])
8840 (label_ref (match_dup 0))
8841 (pc)))]
8842 ""
8843 [(set_attr "op_type" "RSI")
8844 (set_attr "type" "branch")
8845 (set (attr "length")
8846 (if_then_else (lt (abs (minus (pc) (match_dup 0))) (const_int 60000))
8847 (const_int 6) (const_int 14)))])
8848
8849
8850 ;; branch on count
8851
8852 (define_expand "doloop_end"
8853 [(use (match_operand 0 "" "")) ; loop pseudo
8854 (use (match_operand 1 "" ""))] ; label
8855 ""
8856 {
8857 if (GET_MODE (operands[0]) == SImode && !TARGET_CPU_ZARCH)
8858 emit_jump_insn (gen_doloop_si31 (operands[1], operands[0], operands[0]));
8859 else if (GET_MODE (operands[0]) == SImode && TARGET_CPU_ZARCH)
8860 emit_jump_insn (gen_doloop_si64 (operands[1], operands[0], operands[0]));
8861 else if (GET_MODE (operands[0]) == DImode && TARGET_ZARCH)
8862 emit_jump_insn (gen_doloop_di (operands[1], operands[0], operands[0]));
8863 else
8864 FAIL;
8865
8866 DONE;
8867 })
8868
8869 (define_insn_and_split "doloop_si64"
8870 [(set (pc)
8871 (if_then_else
8872 (ne (match_operand:SI 1 "register_operand" "d,d,d")
8873 (const_int 1))
8874 (label_ref (match_operand 0 "" ""))
8875 (pc)))
8876 (set (match_operand:SI 2 "nonimmediate_operand" "=1,?X,?X")
8877 (plus:SI (match_dup 1) (const_int -1)))
8878 (clobber (match_scratch:SI 3 "=X,&1,&?d"))
8879 (clobber (reg:CC CC_REGNUM))]
8880 "TARGET_CPU_ZARCH"
8881 {
8882 if (which_alternative != 0)
8883 return "#";
8884 else if (get_attr_length (insn) == 4)
8885 return "brct\t%1,%l0";
8886 else
8887 return "ahi\t%1,-1\;jgne\t%l0";
8888 }
8889 "&& reload_completed
8890 && (! REG_P (operands[2])
8891 || ! rtx_equal_p (operands[1], operands[2]))"
8892 [(set (match_dup 3) (match_dup 1))
8893 (parallel [(set (reg:CCAN CC_REGNUM)
8894 (compare:CCAN (plus:SI (match_dup 3) (const_int -1))
8895 (const_int 0)))
8896 (set (match_dup 3) (plus:SI (match_dup 3) (const_int -1)))])
8897 (set (match_dup 2) (match_dup 3))
8898 (set (pc) (if_then_else (ne (reg:CCAN CC_REGNUM) (const_int 0))
8899 (label_ref (match_dup 0))
8900 (pc)))]
8901 ""
8902 [(set_attr "op_type" "RI")
8903 ; Strictly speaking, the z10 properties are valid for brct only, however, it does not
8904 ; hurt us in the (rare) case of ahi.
8905 (set_attr "z10prop" "z10_super_E1")
8906 (set_attr "type" "branch")
8907 (set (attr "length")
8908 (if_then_else (lt (abs (minus (pc) (match_dup 0))) (const_int 60000))
8909 (const_int 4) (const_int 10)))])
8910
8911 (define_insn_and_split "doloop_si31"
8912 [(set (pc)
8913 (if_then_else
8914 (ne (match_operand:SI 1 "register_operand" "d,d,d")
8915 (const_int 1))
8916 (label_ref (match_operand 0 "" ""))
8917 (pc)))
8918 (set (match_operand:SI 2 "nonimmediate_operand" "=1,?X,?X")
8919 (plus:SI (match_dup 1) (const_int -1)))
8920 (clobber (match_scratch:SI 3 "=X,&1,&?d"))
8921 (clobber (reg:CC CC_REGNUM))]
8922 "!TARGET_CPU_ZARCH"
8923 {
8924 if (which_alternative != 0)
8925 return "#";
8926 else if (get_attr_length (insn) == 4)
8927 return "brct\t%1,%l0";
8928 else
8929 gcc_unreachable ();
8930 }
8931 "&& reload_completed
8932 && (! REG_P (operands[2])
8933 || ! rtx_equal_p (operands[1], operands[2]))"
8934 [(set (match_dup 3) (match_dup 1))
8935 (parallel [(set (reg:CCAN CC_REGNUM)
8936 (compare:CCAN (plus:SI (match_dup 3) (const_int -1))
8937 (const_int 0)))
8938 (set (match_dup 3) (plus:SI (match_dup 3) (const_int -1)))])
8939 (set (match_dup 2) (match_dup 3))
8940 (set (pc) (if_then_else (ne (reg:CCAN CC_REGNUM) (const_int 0))
8941 (label_ref (match_dup 0))
8942 (pc)))]
8943 ""
8944 [(set_attr "op_type" "RI")
8945 ; Strictly speaking, the z10 properties are valid for brct only, however, it does not
8946 ; hurt us in the (rare) case of ahi.
8947 (set_attr "z10prop" "z10_super_E1")
8948 (set_attr "type" "branch")
8949 (set (attr "length")
8950 (if_then_else (not (match_test "flag_pic"))
8951 (if_then_else (lt (abs (minus (pc) (match_dup 0))) (const_int 60000))
8952 (const_int 4) (const_int 6))
8953 (if_then_else (lt (abs (minus (pc) (match_dup 0))) (const_int 60000))
8954 (const_int 4) (const_int 8))))])
8955
8956 (define_insn "*doloop_si_long"
8957 [(set (pc)
8958 (if_then_else
8959 (ne (match_operand:SI 1 "register_operand" "d")
8960 (const_int 1))
8961 (match_operand 0 "address_operand" "ZQZR")
8962 (pc)))
8963 (set (match_operand:SI 2 "register_operand" "=1")
8964 (plus:SI (match_dup 1) (const_int -1)))
8965 (clobber (match_scratch:SI 3 "=X"))
8966 (clobber (reg:CC CC_REGNUM))]
8967 "!TARGET_CPU_ZARCH"
8968 {
8969 if (get_attr_op_type (insn) == OP_TYPE_RR)
8970 return "bctr\t%1,%0";
8971 else
8972 return "bct\t%1,%a0";
8973 }
8974 [(set (attr "op_type")
8975 (if_then_else (match_operand 0 "register_operand" "")
8976 (const_string "RR") (const_string "RX")))
8977 (set_attr "type" "branch")
8978 (set_attr "atype" "agen")
8979 (set_attr "z10prop" "z10_c")
8980 (set_attr "z196prop" "z196_cracked")])
8981
8982 (define_insn_and_split "doloop_di"
8983 [(set (pc)
8984 (if_then_else
8985 (ne (match_operand:DI 1 "register_operand" "d,d,d")
8986 (const_int 1))
8987 (label_ref (match_operand 0 "" ""))
8988 (pc)))
8989 (set (match_operand:DI 2 "nonimmediate_operand" "=1,?X,?X")
8990 (plus:DI (match_dup 1) (const_int -1)))
8991 (clobber (match_scratch:DI 3 "=X,&1,&?d"))
8992 (clobber (reg:CC CC_REGNUM))]
8993 "TARGET_ZARCH"
8994 {
8995 if (which_alternative != 0)
8996 return "#";
8997 else if (get_attr_length (insn) == 4)
8998 return "brctg\t%1,%l0";
8999 else
9000 return "aghi\t%1,-1\;jgne\t%l0";
9001 }
9002 "&& reload_completed
9003 && (! REG_P (operands[2])
9004 || ! rtx_equal_p (operands[1], operands[2]))"
9005 [(set (match_dup 3) (match_dup 1))
9006 (parallel [(set (reg:CCAN CC_REGNUM)
9007 (compare:CCAN (plus:DI (match_dup 3) (const_int -1))
9008 (const_int 0)))
9009 (set (match_dup 3) (plus:DI (match_dup 3) (const_int -1)))])
9010 (set (match_dup 2) (match_dup 3))
9011 (set (pc) (if_then_else (ne (reg:CCAN CC_REGNUM) (const_int 0))
9012 (label_ref (match_dup 0))
9013 (pc)))]
9014 ""
9015 [(set_attr "op_type" "RI")
9016 ; Strictly speaking, the z10 properties are valid for brct only, however, it does not
9017 ; hurt us in the (rare) case of ahi.
9018 (set_attr "z10prop" "z10_super_E1")
9019 (set_attr "type" "branch")
9020 (set (attr "length")
9021 (if_then_else (lt (abs (minus (pc) (match_dup 0))) (const_int 60000))
9022 (const_int 4) (const_int 10)))])
9023
9024 ;;
9025 ;;- Unconditional jump instructions.
9026 ;;
9027
9028 ;
9029 ; jump instruction pattern(s).
9030 ;
9031
9032 (define_expand "jump"
9033 [(match_operand 0 "" "")]
9034 ""
9035 "s390_emit_jump (operands[0], NULL_RTX); DONE;")
9036
9037 (define_insn "*jump64"
9038 [(set (pc) (label_ref (match_operand 0 "" "")))]
9039 "TARGET_CPU_ZARCH"
9040 {
9041 if (get_attr_length (insn) == 4)
9042 return "j\t%l0";
9043 else
9044 return "jg\t%l0";
9045 }
9046 [(set_attr "op_type" "RI")
9047 (set_attr "type" "branch")
9048 (set (attr "length")
9049 (if_then_else (lt (abs (minus (pc) (match_dup 0))) (const_int 60000))
9050 (const_int 4) (const_int 6)))])
9051
9052 (define_insn "*jump31"
9053 [(set (pc) (label_ref (match_operand 0 "" "")))]
9054 "!TARGET_CPU_ZARCH"
9055 {
9056 gcc_assert (get_attr_length (insn) == 4);
9057 return "j\t%l0";
9058 }
9059 [(set_attr "op_type" "RI")
9060 (set_attr "type" "branch")
9061 (set (attr "length")
9062 (if_then_else (not (match_test "flag_pic"))
9063 (if_then_else (lt (abs (minus (pc) (match_dup 0))) (const_int 60000))
9064 (const_int 4) (const_int 6))
9065 (if_then_else (lt (abs (minus (pc) (match_dup 0))) (const_int 60000))
9066 (const_int 4) (const_int 8))))])
9067
9068 ;
9069 ; indirect-jump instruction pattern(s).
9070 ;
9071
9072 (define_insn "indirect_jump"
9073 [(set (pc) (match_operand 0 "address_operand" "ZQZR"))]
9074 ""
9075 {
9076 if (get_attr_op_type (insn) == OP_TYPE_RR)
9077 return "br\t%0";
9078 else
9079 return "b\t%a0";
9080 }
9081 [(set (attr "op_type")
9082 (if_then_else (match_operand 0 "register_operand" "")
9083 (const_string "RR") (const_string "RX")))
9084 (set_attr "type" "branch")
9085 (set_attr "atype" "agen")])
9086
9087 ;
9088 ; casesi instruction pattern(s).
9089 ;
9090
9091 (define_insn "casesi_jump"
9092 [(set (pc) (match_operand 0 "address_operand" "ZQZR"))
9093 (use (label_ref (match_operand 1 "" "")))]
9094 ""
9095 {
9096 if (get_attr_op_type (insn) == OP_TYPE_RR)
9097 return "br\t%0";
9098 else
9099 return "b\t%a0";
9100 }
9101 [(set (attr "op_type")
9102 (if_then_else (match_operand 0 "register_operand" "")
9103 (const_string "RR") (const_string "RX")))
9104 (set_attr "type" "branch")
9105 (set_attr "atype" "agen")])
9106
9107 (define_expand "casesi"
9108 [(match_operand:SI 0 "general_operand" "")
9109 (match_operand:SI 1 "general_operand" "")
9110 (match_operand:SI 2 "general_operand" "")
9111 (label_ref (match_operand 3 "" ""))
9112 (label_ref (match_operand 4 "" ""))]
9113 ""
9114 {
9115 rtx index = gen_reg_rtx (SImode);
9116 rtx base = gen_reg_rtx (Pmode);
9117 rtx target = gen_reg_rtx (Pmode);
9118
9119 emit_move_insn (index, operands[0]);
9120 emit_insn (gen_subsi3 (index, index, operands[1]));
9121 emit_cmp_and_jump_insns (index, operands[2], GTU, NULL_RTX, SImode, 1,
9122 operands[4]);
9123
9124 if (Pmode != SImode)
9125 index = convert_to_mode (Pmode, index, 1);
9126 if (GET_CODE (index) != REG)
9127 index = copy_to_mode_reg (Pmode, index);
9128
9129 if (TARGET_64BIT)
9130 emit_insn (gen_ashldi3 (index, index, GEN_INT (3)));
9131 else
9132 emit_insn (gen_ashlsi3 (index, index, const2_rtx));
9133
9134 emit_move_insn (base, gen_rtx_LABEL_REF (Pmode, operands[3]));
9135
9136 index = gen_const_mem (Pmode, gen_rtx_PLUS (Pmode, base, index));
9137 emit_move_insn (target, index);
9138
9139 if (flag_pic)
9140 target = gen_rtx_PLUS (Pmode, base, target);
9141 emit_jump_insn (gen_casesi_jump (target, operands[3]));
9142
9143 DONE;
9144 })
9145
9146
9147 ;;
9148 ;;- Jump to subroutine.
9149 ;;
9150 ;;
9151
9152 ;
9153 ; untyped call instruction pattern(s).
9154 ;
9155
9156 ;; Call subroutine returning any type.
9157 (define_expand "untyped_call"
9158 [(parallel [(call (match_operand 0 "" "")
9159 (const_int 0))
9160 (match_operand 1 "" "")
9161 (match_operand 2 "" "")])]
9162 ""
9163 {
9164 int i;
9165
9166 emit_call_insn (gen_call (operands[0], const0_rtx, const0_rtx));
9167
9168 for (i = 0; i < XVECLEN (operands[2], 0); i++)
9169 {
9170 rtx set = XVECEXP (operands[2], 0, i);
9171 emit_move_insn (SET_DEST (set), SET_SRC (set));
9172 }
9173
9174 /* The optimizer does not know that the call sets the function value
9175 registers we stored in the result block. We avoid problems by
9176 claiming that all hard registers are used and clobbered at this
9177 point. */
9178 emit_insn (gen_blockage ());
9179
9180 DONE;
9181 })
9182
9183 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
9184 ;; all of memory. This blocks insns from being moved across this point.
9185
9186 (define_insn "blockage"
9187 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
9188 ""
9189 ""
9190 [(set_attr "type" "none")
9191 (set_attr "length" "0")])
9192
9193 ;
9194 ; sibcall patterns
9195 ;
9196
9197 (define_expand "sibcall"
9198 [(call (match_operand 0 "" "")
9199 (match_operand 1 "" ""))]
9200 ""
9201 {
9202 s390_emit_call (XEXP (operands[0], 0), NULL_RTX, NULL_RTX, NULL_RTX);
9203 DONE;
9204 })
9205
9206 (define_insn "*sibcall_br"
9207 [(call (mem:QI (reg SIBCALL_REGNUM))
9208 (match_operand 0 "const_int_operand" "n"))]
9209 "SIBLING_CALL_P (insn)
9210 && GET_MODE (XEXP (XEXP (PATTERN (insn), 0), 0)) == Pmode"
9211 "br\t%%r1"
9212 [(set_attr "op_type" "RR")
9213 (set_attr "type" "branch")
9214 (set_attr "atype" "agen")])
9215
9216 (define_insn "*sibcall_brc"
9217 [(call (mem:QI (match_operand 0 "bras_sym_operand" "X"))
9218 (match_operand 1 "const_int_operand" "n"))]
9219 "SIBLING_CALL_P (insn) && TARGET_SMALL_EXEC"
9220 "j\t%0"
9221 [(set_attr "op_type" "RI")
9222 (set_attr "type" "branch")])
9223
9224 (define_insn "*sibcall_brcl"
9225 [(call (mem:QI (match_operand 0 "bras_sym_operand" "X"))
9226 (match_operand 1 "const_int_operand" "n"))]
9227 "SIBLING_CALL_P (insn) && TARGET_CPU_ZARCH"
9228 "jg\t%0"
9229 [(set_attr "op_type" "RIL")
9230 (set_attr "type" "branch")])
9231
9232 ;
9233 ; sibcall_value patterns
9234 ;
9235
9236 (define_expand "sibcall_value"
9237 [(set (match_operand 0 "" "")
9238 (call (match_operand 1 "" "")
9239 (match_operand 2 "" "")))]
9240 ""
9241 {
9242 s390_emit_call (XEXP (operands[1], 0), NULL_RTX, operands[0], NULL_RTX);
9243 DONE;
9244 })
9245
9246 (define_insn "*sibcall_value_br"
9247 [(set (match_operand 0 "" "")
9248 (call (mem:QI (reg SIBCALL_REGNUM))
9249 (match_operand 1 "const_int_operand" "n")))]
9250 "SIBLING_CALL_P (insn)
9251 && GET_MODE (XEXP (XEXP (XEXP (PATTERN (insn), 1), 0), 0)) == Pmode"
9252 "br\t%%r1"
9253 [(set_attr "op_type" "RR")
9254 (set_attr "type" "branch")
9255 (set_attr "atype" "agen")])
9256
9257 (define_insn "*sibcall_value_brc"
9258 [(set (match_operand 0 "" "")
9259 (call (mem:QI (match_operand 1 "bras_sym_operand" "X"))
9260 (match_operand 2 "const_int_operand" "n")))]
9261 "SIBLING_CALL_P (insn) && TARGET_SMALL_EXEC"
9262 "j\t%1"
9263 [(set_attr "op_type" "RI")
9264 (set_attr "type" "branch")])
9265
9266 (define_insn "*sibcall_value_brcl"
9267 [(set (match_operand 0 "" "")
9268 (call (mem:QI (match_operand 1 "bras_sym_operand" "X"))
9269 (match_operand 2 "const_int_operand" "n")))]
9270 "SIBLING_CALL_P (insn) && TARGET_CPU_ZARCH"
9271 "jg\t%1"
9272 [(set_attr "op_type" "RIL")
9273 (set_attr "type" "branch")])
9274
9275
9276 ;
9277 ; call instruction pattern(s).
9278 ;
9279
9280 (define_expand "call"
9281 [(call (match_operand 0 "" "")
9282 (match_operand 1 "" ""))
9283 (use (match_operand 2 "" ""))]
9284 ""
9285 {
9286 s390_emit_call (XEXP (operands[0], 0), NULL_RTX, NULL_RTX,
9287 gen_rtx_REG (Pmode, RETURN_REGNUM));
9288 DONE;
9289 })
9290
9291 (define_insn "*bras"
9292 [(call (mem:QI (match_operand 0 "bras_sym_operand" "X"))
9293 (match_operand 1 "const_int_operand" "n"))
9294 (clobber (match_operand 2 "register_operand" "=r"))]
9295 "!SIBLING_CALL_P (insn)
9296 && TARGET_SMALL_EXEC
9297 && GET_MODE (operands[2]) == Pmode"
9298 "bras\t%2,%0"
9299 [(set_attr "op_type" "RI")
9300 (set_attr "type" "jsr")
9301 (set_attr "z196prop" "z196_cracked")])
9302
9303 (define_insn "*brasl"
9304 [(call (mem:QI (match_operand 0 "bras_sym_operand" "X"))
9305 (match_operand 1 "const_int_operand" "n"))
9306 (clobber (match_operand 2 "register_operand" "=r"))]
9307 "!SIBLING_CALL_P (insn)
9308 && TARGET_CPU_ZARCH
9309 && GET_MODE (operands[2]) == Pmode"
9310 "brasl\t%2,%0"
9311 [(set_attr "op_type" "RIL")
9312 (set_attr "type" "jsr")
9313 (set_attr "z196prop" "z196_cracked")])
9314
9315 (define_insn "*basr"
9316 [(call (mem:QI (match_operand 0 "address_operand" "ZQZR"))
9317 (match_operand 1 "const_int_operand" "n"))
9318 (clobber (match_operand 2 "register_operand" "=r"))]
9319 "!SIBLING_CALL_P (insn) && GET_MODE (operands[2]) == Pmode"
9320 {
9321 if (get_attr_op_type (insn) == OP_TYPE_RR)
9322 return "basr\t%2,%0";
9323 else
9324 return "bas\t%2,%a0";
9325 }
9326 [(set (attr "op_type")
9327 (if_then_else (match_operand 0 "register_operand" "")
9328 (const_string "RR") (const_string "RX")))
9329 (set_attr "type" "jsr")
9330 (set_attr "atype" "agen")
9331 (set_attr "z196prop" "z196_cracked")])
9332
9333 ;
9334 ; call_value instruction pattern(s).
9335 ;
9336
9337 (define_expand "call_value"
9338 [(set (match_operand 0 "" "")
9339 (call (match_operand 1 "" "")
9340 (match_operand 2 "" "")))
9341 (use (match_operand 3 "" ""))]
9342 ""
9343 {
9344 s390_emit_call (XEXP (operands[1], 0), NULL_RTX, operands[0],
9345 gen_rtx_REG (Pmode, RETURN_REGNUM));
9346 DONE;
9347 })
9348
9349 (define_insn "*bras_r"
9350 [(set (match_operand 0 "" "")
9351 (call (mem:QI (match_operand 1 "bras_sym_operand" "X"))
9352 (match_operand:SI 2 "const_int_operand" "n")))
9353 (clobber (match_operand 3 "register_operand" "=r"))]
9354 "!SIBLING_CALL_P (insn)
9355 && TARGET_SMALL_EXEC
9356 && GET_MODE (operands[3]) == Pmode"
9357 "bras\t%3,%1"
9358 [(set_attr "op_type" "RI")
9359 (set_attr "type" "jsr")
9360 (set_attr "z196prop" "z196_cracked")])
9361
9362 (define_insn "*brasl_r"
9363 [(set (match_operand 0 "" "")
9364 (call (mem:QI (match_operand 1 "bras_sym_operand" "X"))
9365 (match_operand 2 "const_int_operand" "n")))
9366 (clobber (match_operand 3 "register_operand" "=r"))]
9367 "!SIBLING_CALL_P (insn)
9368 && TARGET_CPU_ZARCH
9369 && GET_MODE (operands[3]) == Pmode"
9370 "brasl\t%3,%1"
9371 [(set_attr "op_type" "RIL")
9372 (set_attr "type" "jsr")
9373 (set_attr "z196prop" "z196_cracked")])
9374
9375 (define_insn "*basr_r"
9376 [(set (match_operand 0 "" "")
9377 (call (mem:QI (match_operand 1 "address_operand" "ZQZR"))
9378 (match_operand 2 "const_int_operand" "n")))
9379 (clobber (match_operand 3 "register_operand" "=r"))]
9380 "!SIBLING_CALL_P (insn) && GET_MODE (operands[3]) == Pmode"
9381 {
9382 if (get_attr_op_type (insn) == OP_TYPE_RR)
9383 return "basr\t%3,%1";
9384 else
9385 return "bas\t%3,%a1";
9386 }
9387 [(set (attr "op_type")
9388 (if_then_else (match_operand 1 "register_operand" "")
9389 (const_string "RR") (const_string "RX")))
9390 (set_attr "type" "jsr")
9391 (set_attr "atype" "agen")
9392 (set_attr "z196prop" "z196_cracked")])
9393
9394 ;;
9395 ;;- Thread-local storage support.
9396 ;;
9397
9398 (define_expand "get_thread_pointer<mode>"
9399 [(set (match_operand:P 0 "nonimmediate_operand" "") (reg:P TP_REGNUM))]
9400 ""
9401 "")
9402
9403 (define_expand "set_thread_pointer<mode>"
9404 [(set (reg:P TP_REGNUM) (match_operand:P 0 "nonimmediate_operand" ""))
9405 (set (reg:P TP_REGNUM) (unspec_volatile:P [(reg:P TP_REGNUM)] UNSPECV_SET_TP))]
9406 ""
9407 "")
9408
9409 (define_insn "*set_tp"
9410 [(set (reg TP_REGNUM) (unspec_volatile [(reg TP_REGNUM)] UNSPECV_SET_TP))]
9411 ""
9412 ""
9413 [(set_attr "type" "none")
9414 (set_attr "length" "0")])
9415
9416 (define_insn "*tls_load_64"
9417 [(set (match_operand:DI 0 "register_operand" "=d")
9418 (unspec:DI [(match_operand:DI 1 "memory_operand" "RT")
9419 (match_operand:DI 2 "" "")]
9420 UNSPEC_TLS_LOAD))]
9421 "TARGET_64BIT"
9422 "lg\t%0,%1%J2"
9423 [(set_attr "op_type" "RXE")
9424 (set_attr "z10prop" "z10_fwd_A3")])
9425
9426 (define_insn "*tls_load_31"
9427 [(set (match_operand:SI 0 "register_operand" "=d,d")
9428 (unspec:SI [(match_operand:SI 1 "memory_operand" "R,T")
9429 (match_operand:SI 2 "" "")]
9430 UNSPEC_TLS_LOAD))]
9431 "!TARGET_64BIT"
9432 "@
9433 l\t%0,%1%J2
9434 ly\t%0,%1%J2"
9435 [(set_attr "op_type" "RX,RXY")
9436 (set_attr "type" "load")
9437 (set_attr "z10prop" "z10_fwd_A3,z10_fwd_A3")])
9438
9439 (define_insn "*bras_tls"
9440 [(set (match_operand 0 "" "")
9441 (call (mem:QI (match_operand 1 "bras_sym_operand" "X"))
9442 (match_operand 2 "const_int_operand" "n")))
9443 (clobber (match_operand 3 "register_operand" "=r"))
9444 (use (match_operand 4 "" ""))]
9445 "!SIBLING_CALL_P (insn)
9446 && TARGET_SMALL_EXEC
9447 && GET_MODE (operands[3]) == Pmode"
9448 "bras\t%3,%1%J4"
9449 [(set_attr "op_type" "RI")
9450 (set_attr "type" "jsr")
9451 (set_attr "z196prop" "z196_cracked")])
9452
9453 (define_insn "*brasl_tls"
9454 [(set (match_operand 0 "" "")
9455 (call (mem:QI (match_operand 1 "bras_sym_operand" "X"))
9456 (match_operand 2 "const_int_operand" "n")))
9457 (clobber (match_operand 3 "register_operand" "=r"))
9458 (use (match_operand 4 "" ""))]
9459 "!SIBLING_CALL_P (insn)
9460 && TARGET_CPU_ZARCH
9461 && GET_MODE (operands[3]) == Pmode"
9462 "brasl\t%3,%1%J4"
9463 [(set_attr "op_type" "RIL")
9464 (set_attr "type" "jsr")
9465 (set_attr "z196prop" "z196_cracked")])
9466
9467 (define_insn "*basr_tls"
9468 [(set (match_operand 0 "" "")
9469 (call (mem:QI (match_operand 1 "address_operand" "ZQZR"))
9470 (match_operand 2 "const_int_operand" "n")))
9471 (clobber (match_operand 3 "register_operand" "=r"))
9472 (use (match_operand 4 "" ""))]
9473 "!SIBLING_CALL_P (insn) && GET_MODE (operands[3]) == Pmode"
9474 {
9475 if (get_attr_op_type (insn) == OP_TYPE_RR)
9476 return "basr\t%3,%1%J4";
9477 else
9478 return "bas\t%3,%a1%J4";
9479 }
9480 [(set (attr "op_type")
9481 (if_then_else (match_operand 1 "register_operand" "")
9482 (const_string "RR") (const_string "RX")))
9483 (set_attr "type" "jsr")
9484 (set_attr "atype" "agen")
9485 (set_attr "z196prop" "z196_cracked")])
9486
9487 ;;
9488 ;;- Atomic operations
9489 ;;
9490
9491 ;
9492 ; memory barrier patterns.
9493 ;
9494
9495 (define_expand "mem_signal_fence"
9496 [(match_operand:SI 0 "const_int_operand")] ;; model
9497 ""
9498 {
9499 /* The s390 memory model is strong enough not to require any
9500 barrier in order to synchronize a thread with itself. */
9501 DONE;
9502 })
9503
9504 (define_expand "mem_thread_fence"
9505 [(match_operand:SI 0 "const_int_operand")] ;; model
9506 ""
9507 {
9508 /* Unless this is a SEQ_CST fence, the s390 memory model is strong
9509 enough not to require barriers of any kind. */
9510 if (is_mm_seq_cst (memmodel_from_int (INTVAL (operands[0]))))
9511 {
9512 rtx mem = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
9513 MEM_VOLATILE_P (mem) = 1;
9514 emit_insn (gen_mem_thread_fence_1 (mem));
9515 }
9516 DONE;
9517 })
9518
9519 ; Although bcr is superscalar on Z10, this variant will never
9520 ; become part of an execution group.
9521 ; With z196 we can make use of the fast-BCR-serialization facility.
9522 ; This allows for a slightly faster sync which is sufficient for our
9523 ; purposes.
9524 (define_insn "mem_thread_fence_1"
9525 [(set (match_operand:BLK 0 "" "")
9526 (unspec:BLK [(match_dup 0)] UNSPEC_MB))]
9527 ""
9528 {
9529 if (TARGET_Z196)
9530 return "bcr\t14,0";
9531 else
9532 return "bcr\t15,0";
9533 }
9534 [(set_attr "op_type" "RR")
9535 (set_attr "mnemonic" "bcr_flush")
9536 (set_attr "z196prop" "z196_alone")])
9537
9538 ;
9539 ; atomic load/store operations
9540 ;
9541
9542 ; Atomic loads need not examine the memory model at all.
9543 (define_expand "atomic_load<mode>"
9544 [(match_operand:DINT 0 "register_operand") ;; output
9545 (match_operand:DINT 1 "memory_operand") ;; memory
9546 (match_operand:SI 2 "const_int_operand")] ;; model
9547 ""
9548 {
9549 if (MEM_ALIGN (operands[1]) < GET_MODE_BITSIZE (GET_MODE (operands[1])))
9550 FAIL;
9551
9552 if (<MODE>mode == TImode)
9553 emit_insn (gen_atomic_loadti_1 (operands[0], operands[1]));
9554 else if (<MODE>mode == DImode && !TARGET_ZARCH)
9555 emit_insn (gen_atomic_loaddi_1 (operands[0], operands[1]));
9556 else
9557 emit_move_insn (operands[0], operands[1]);
9558 DONE;
9559 })
9560
9561 ; Different from movdi_31 in that we want no splitters.
9562 (define_insn "atomic_loaddi_1"
9563 [(set (match_operand:DI 0 "register_operand" "=d,d,!*f,!*f")
9564 (unspec:DI [(match_operand:DI 1 "memory_operand" "Q,S,R,T")]
9565 UNSPEC_MOVA))]
9566 "!TARGET_ZARCH"
9567 "@
9568 lm\t%0,%M0,%S1
9569 lmy\t%0,%M0,%S1
9570 ld\t%0,%1
9571 ldy\t%0,%1"
9572 [(set_attr "op_type" "RS,RSY,RS,RSY")
9573 (set_attr "type" "lm,lm,floaddf,floaddf")])
9574
9575 (define_insn "atomic_loadti_1"
9576 [(set (match_operand:TI 0 "register_operand" "=r")
9577 (unspec:TI [(match_operand:TI 1 "memory_operand" "RT")]
9578 UNSPEC_MOVA))]
9579 "TARGET_ZARCH"
9580 "lpq\t%0,%1"
9581 [(set_attr "op_type" "RXY")
9582 (set_attr "type" "other")])
9583
9584 ; Atomic stores must(?) enforce sequential consistency.
9585 (define_expand "atomic_store<mode>"
9586 [(match_operand:DINT 0 "memory_operand") ;; memory
9587 (match_operand:DINT 1 "register_operand") ;; input
9588 (match_operand:SI 2 "const_int_operand")] ;; model
9589 ""
9590 {
9591 enum memmodel model = memmodel_from_int (INTVAL (operands[2]));
9592
9593 if (MEM_ALIGN (operands[0]) < GET_MODE_BITSIZE (GET_MODE (operands[0])))
9594 FAIL;
9595
9596 if (<MODE>mode == TImode)
9597 emit_insn (gen_atomic_storeti_1 (operands[0], operands[1]));
9598 else if (<MODE>mode == DImode && !TARGET_ZARCH)
9599 emit_insn (gen_atomic_storedi_1 (operands[0], operands[1]));
9600 else
9601 emit_move_insn (operands[0], operands[1]);
9602 if (is_mm_seq_cst (model))
9603 emit_insn (gen_mem_thread_fence (operands[2]));
9604 DONE;
9605 })
9606
9607 ; Different from movdi_31 in that we want no splitters.
9608 (define_insn "atomic_storedi_1"
9609 [(set (match_operand:DI 0 "memory_operand" "=Q,S,R,T")
9610 (unspec:DI [(match_operand:DI 1 "register_operand" "d,d,!*f,!*f")]
9611 UNSPEC_MOVA))]
9612 "!TARGET_ZARCH"
9613 "@
9614 stm\t%1,%N1,%S0
9615 stmy\t%1,%N1,%S0
9616 std %1,%0
9617 stdy %1,%0"
9618 [(set_attr "op_type" "RS,RSY,RS,RSY")
9619 (set_attr "type" "stm,stm,fstoredf,fstoredf")])
9620
9621 (define_insn "atomic_storeti_1"
9622 [(set (match_operand:TI 0 "memory_operand" "=RT")
9623 (unspec:TI [(match_operand:TI 1 "register_operand" "r")]
9624 UNSPEC_MOVA))]
9625 "TARGET_ZARCH"
9626 "stpq\t%1,%0"
9627 [(set_attr "op_type" "RXY")
9628 (set_attr "type" "other")])
9629
9630 ;
9631 ; compare and swap patterns.
9632 ;
9633
9634 (define_expand "atomic_compare_and_swap<mode>"
9635 [(match_operand:SI 0 "register_operand") ;; bool success output
9636 (match_operand:DGPR 1 "nonimmediate_operand");; oldval output
9637 (match_operand:DGPR 2 "memory_operand") ;; memory
9638 (match_operand:DGPR 3 "register_operand") ;; expected intput
9639 (match_operand:DGPR 4 "register_operand") ;; newval intput
9640 (match_operand:SI 5 "const_int_operand") ;; is_weak
9641 (match_operand:SI 6 "const_int_operand") ;; success model
9642 (match_operand:SI 7 "const_int_operand")] ;; failure model
9643 ""
9644 {
9645 rtx cc, cmp, output = operands[1];
9646
9647 if (!register_operand (output, <MODE>mode))
9648 output = gen_reg_rtx (<MODE>mode);
9649
9650 if (MEM_ALIGN (operands[2]) < GET_MODE_BITSIZE (GET_MODE (operands[2])))
9651 FAIL;
9652
9653 emit_insn (gen_atomic_compare_and_swap<mode>_internal
9654 (output, operands[2], operands[3], operands[4]));
9655
9656 /* We deliberately accept non-register operands in the predicate
9657 to ensure the write back to the output operand happens *before*
9658 the store-flags code below. This makes it easier for combine
9659 to merge the store-flags code with a potential test-and-branch
9660 pattern following (immediately!) afterwards. */
9661 if (output != operands[1])
9662 emit_move_insn (operands[1], output);
9663
9664 cc = gen_rtx_REG (CCZ1mode, CC_REGNUM);
9665 cmp = gen_rtx_EQ (SImode, cc, const0_rtx);
9666 emit_insn (gen_cstorecc4 (operands[0], cmp, cc, const0_rtx));
9667 DONE;
9668 })
9669
9670 (define_expand "atomic_compare_and_swap<mode>"
9671 [(match_operand:SI 0 "register_operand") ;; bool success output
9672 (match_operand:HQI 1 "nonimmediate_operand") ;; oldval output
9673 (match_operand:HQI 2 "memory_operand") ;; memory
9674 (match_operand:HQI 3 "general_operand") ;; expected intput
9675 (match_operand:HQI 4 "general_operand") ;; newval intput
9676 (match_operand:SI 5 "const_int_operand") ;; is_weak
9677 (match_operand:SI 6 "const_int_operand") ;; success model
9678 (match_operand:SI 7 "const_int_operand")] ;; failure model
9679 ""
9680 {
9681 s390_expand_cs_hqi (<MODE>mode, operands[0], operands[1], operands[2],
9682 operands[3], operands[4], INTVAL (operands[5]));
9683 DONE;
9684 })
9685
9686 (define_expand "atomic_compare_and_swap<mode>_internal"
9687 [(parallel
9688 [(set (match_operand:DGPR 0 "register_operand")
9689 (match_operand:DGPR 1 "memory_operand"))
9690 (set (match_dup 1)
9691 (unspec_volatile:DGPR
9692 [(match_dup 1)
9693 (match_operand:DGPR 2 "register_operand")
9694 (match_operand:DGPR 3 "register_operand")]
9695 UNSPECV_CAS))
9696 (set (reg:CCZ1 CC_REGNUM)
9697 (compare:CCZ1 (match_dup 1) (match_dup 2)))])]
9698 "")
9699
9700 ; cdsg, csg
9701 (define_insn "*atomic_compare_and_swap<mode>_1"
9702 [(set (match_operand:TDI 0 "register_operand" "=r")
9703 (match_operand:TDI 1 "memory_operand" "+QS"))
9704 (set (match_dup 1)
9705 (unspec_volatile:TDI
9706 [(match_dup 1)
9707 (match_operand:TDI 2 "register_operand" "0")
9708 (match_operand:TDI 3 "register_operand" "r")]
9709 UNSPECV_CAS))
9710 (set (reg:CCZ1 CC_REGNUM)
9711 (compare:CCZ1 (match_dup 1) (match_dup 2)))]
9712 "TARGET_ZARCH"
9713 "c<td>sg\t%0,%3,%S1"
9714 [(set_attr "op_type" "RSY")
9715 (set_attr "type" "sem")])
9716
9717 ; cds, cdsy
9718 (define_insn "*atomic_compare_and_swapdi_2"
9719 [(set (match_operand:DI 0 "register_operand" "=r,r")
9720 (match_operand:DI 1 "memory_operand" "+Q,S"))
9721 (set (match_dup 1)
9722 (unspec_volatile:DI
9723 [(match_dup 1)
9724 (match_operand:DI 2 "register_operand" "0,0")
9725 (match_operand:DI 3 "register_operand" "r,r")]
9726 UNSPECV_CAS))
9727 (set (reg:CCZ1 CC_REGNUM)
9728 (compare:CCZ1 (match_dup 1) (match_dup 2)))]
9729 "!TARGET_ZARCH"
9730 "@
9731 cds\t%0,%3,%S1
9732 cdsy\t%0,%3,%S1"
9733 [(set_attr "op_type" "RS,RSY")
9734 (set_attr "type" "sem")])
9735
9736 ; cs, csy
9737 (define_insn "*atomic_compare_and_swapsi_3"
9738 [(set (match_operand:SI 0 "register_operand" "=r,r")
9739 (match_operand:SI 1 "memory_operand" "+Q,S"))
9740 (set (match_dup 1)
9741 (unspec_volatile:SI
9742 [(match_dup 1)
9743 (match_operand:SI 2 "register_operand" "0,0")
9744 (match_operand:SI 3 "register_operand" "r,r")]
9745 UNSPECV_CAS))
9746 (set (reg:CCZ1 CC_REGNUM)
9747 (compare:CCZ1 (match_dup 1) (match_dup 2)))]
9748 ""
9749 "@
9750 cs\t%0,%3,%S1
9751 csy\t%0,%3,%S1"
9752 [(set_attr "op_type" "RS,RSY")
9753 (set_attr "type" "sem")])
9754
9755 ;
9756 ; Other atomic instruction patterns.
9757 ;
9758
9759 ; z196 load and add, xor, or and and instructions
9760
9761 (define_expand "atomic_fetch_<atomic><mode>"
9762 [(match_operand:GPR 0 "register_operand") ;; val out
9763 (ATOMIC_Z196:GPR
9764 (match_operand:GPR 1 "memory_operand") ;; memory
9765 (match_operand:GPR 2 "register_operand")) ;; val in
9766 (match_operand:SI 3 "const_int_operand")] ;; model
9767 "TARGET_Z196"
9768 {
9769 if (MEM_ALIGN (operands[1]) < GET_MODE_BITSIZE (GET_MODE (operands[1])))
9770 FAIL;
9771
9772 emit_insn (gen_atomic_fetch_<atomic><mode>_iaf
9773 (operands[0], operands[1], operands[2]));
9774 DONE;
9775 })
9776
9777 ; lan, lang, lao, laog, lax, laxg, laa, laag
9778 (define_insn "atomic_fetch_<atomic><mode>_iaf"
9779 [(set (match_operand:GPR 0 "register_operand" "=d")
9780 (match_operand:GPR 1 "memory_operand" "+QS"))
9781 (set (match_dup 1)
9782 (unspec_volatile:GPR
9783 [(ATOMIC_Z196:GPR (match_dup 1)
9784 (match_operand:GPR 2 "general_operand" "d"))]
9785 UNSPECV_ATOMIC_OP))
9786 (clobber (reg:CC CC_REGNUM))]
9787 "TARGET_Z196"
9788 "la<noxa><g>\t%0,%2,%1"
9789 [(set_attr "op_type" "RSY")
9790 (set_attr "type" "sem")])
9791
9792 ;; For SImode and larger, the optabs.c code will do just fine in
9793 ;; expanding a compare-and-swap loop. For QI/HImode, we can do
9794 ;; better by expanding our own loop.
9795
9796 (define_expand "atomic_<atomic><mode>"
9797 [(ATOMIC:HQI
9798 (match_operand:HQI 0 "memory_operand") ;; memory
9799 (match_operand:HQI 1 "general_operand")) ;; val in
9800 (match_operand:SI 2 "const_int_operand")] ;; model
9801 ""
9802 {
9803 s390_expand_atomic (<MODE>mode, <CODE>, NULL_RTX, operands[0],
9804 operands[1], false);
9805 DONE;
9806 })
9807
9808 (define_expand "atomic_fetch_<atomic><mode>"
9809 [(match_operand:HQI 0 "register_operand") ;; val out
9810 (ATOMIC:HQI
9811 (match_operand:HQI 1 "memory_operand") ;; memory
9812 (match_operand:HQI 2 "general_operand")) ;; val in
9813 (match_operand:SI 3 "const_int_operand")] ;; model
9814 ""
9815 {
9816 s390_expand_atomic (<MODE>mode, <CODE>, operands[0], operands[1],
9817 operands[2], false);
9818 DONE;
9819 })
9820
9821 (define_expand "atomic_<atomic>_fetch<mode>"
9822 [(match_operand:HQI 0 "register_operand") ;; val out
9823 (ATOMIC:HQI
9824 (match_operand:HQI 1 "memory_operand") ;; memory
9825 (match_operand:HQI 2 "general_operand")) ;; val in
9826 (match_operand:SI 3 "const_int_operand")] ;; model
9827 ""
9828 {
9829 s390_expand_atomic (<MODE>mode, <CODE>, operands[0], operands[1],
9830 operands[2], true);
9831 DONE;
9832 })
9833
9834 (define_expand "atomic_exchange<mode>"
9835 [(match_operand:HQI 0 "register_operand") ;; val out
9836 (match_operand:HQI 1 "memory_operand") ;; memory
9837 (match_operand:HQI 2 "general_operand") ;; val in
9838 (match_operand:SI 3 "const_int_operand")] ;; model
9839 ""
9840 {
9841 s390_expand_atomic (<MODE>mode, SET, operands[0], operands[1],
9842 operands[2], false);
9843 DONE;
9844 })
9845
9846 ;;
9847 ;;- Miscellaneous instructions.
9848 ;;
9849
9850 ;
9851 ; allocate stack instruction pattern(s).
9852 ;
9853
9854 (define_expand "allocate_stack"
9855 [(match_operand 0 "general_operand" "")
9856 (match_operand 1 "general_operand" "")]
9857 "TARGET_BACKCHAIN"
9858 {
9859 rtx temp = gen_reg_rtx (Pmode);
9860
9861 emit_move_insn (temp, s390_back_chain_rtx ());
9862 anti_adjust_stack (operands[1]);
9863 emit_move_insn (s390_back_chain_rtx (), temp);
9864
9865 emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
9866 DONE;
9867 })
9868
9869
9870 ;
9871 ; setjmp instruction pattern.
9872 ;
9873
9874 (define_expand "builtin_setjmp_receiver"
9875 [(match_operand 0 "" "")]
9876 "flag_pic"
9877 {
9878 emit_insn (s390_load_got ());
9879 emit_use (pic_offset_table_rtx);
9880 DONE;
9881 })
9882
9883 ;; These patterns say how to save and restore the stack pointer. We need not
9884 ;; save the stack pointer at function level since we are careful to
9885 ;; preserve the backchain. At block level, we have to restore the backchain
9886 ;; when we restore the stack pointer.
9887 ;;
9888 ;; For nonlocal gotos, we must save both the stack pointer and its
9889 ;; backchain and restore both. Note that in the nonlocal case, the
9890 ;; save area is a memory location.
9891
9892 (define_expand "save_stack_function"
9893 [(match_operand 0 "general_operand" "")
9894 (match_operand 1 "general_operand" "")]
9895 ""
9896 "DONE;")
9897
9898 (define_expand "restore_stack_function"
9899 [(match_operand 0 "general_operand" "")
9900 (match_operand 1 "general_operand" "")]
9901 ""
9902 "DONE;")
9903
9904 (define_expand "restore_stack_block"
9905 [(match_operand 0 "register_operand" "")
9906 (match_operand 1 "register_operand" "")]
9907 "TARGET_BACKCHAIN"
9908 {
9909 rtx temp = gen_reg_rtx (Pmode);
9910
9911 emit_move_insn (temp, s390_back_chain_rtx ());
9912 emit_move_insn (operands[0], operands[1]);
9913 emit_move_insn (s390_back_chain_rtx (), temp);
9914
9915 DONE;
9916 })
9917
9918 (define_expand "save_stack_nonlocal"
9919 [(match_operand 0 "memory_operand" "")
9920 (match_operand 1 "register_operand" "")]
9921 ""
9922 {
9923 rtx base = gen_rtx_REG (Pmode, BASE_REGNUM);
9924
9925 /* Copy the backchain to the first word, sp to the second and the
9926 literal pool base to the third. */
9927
9928 rtx save_bc = adjust_address (operands[0], Pmode, 0);
9929 rtx save_sp = adjust_address (operands[0], Pmode, GET_MODE_SIZE (Pmode));
9930 rtx save_bp = adjust_address (operands[0], Pmode, 2 * GET_MODE_SIZE (Pmode));
9931
9932 if (TARGET_BACKCHAIN)
9933 emit_move_insn (save_bc, force_reg (Pmode, s390_back_chain_rtx ()));
9934
9935 emit_move_insn (save_sp, operands[1]);
9936 emit_move_insn (save_bp, base);
9937
9938 DONE;
9939 })
9940
9941 (define_expand "restore_stack_nonlocal"
9942 [(match_operand 0 "register_operand" "")
9943 (match_operand 1 "memory_operand" "")]
9944 ""
9945 {
9946 rtx base = gen_rtx_REG (Pmode, BASE_REGNUM);
9947 rtx temp = NULL_RTX;
9948
9949 /* Restore the backchain from the first word, sp from the second and the
9950 literal pool base from the third. */
9951
9952 rtx save_bc = adjust_address (operands[1], Pmode, 0);
9953 rtx save_sp = adjust_address (operands[1], Pmode, GET_MODE_SIZE (Pmode));
9954 rtx save_bp = adjust_address (operands[1], Pmode, 2 * GET_MODE_SIZE (Pmode));
9955
9956 if (TARGET_BACKCHAIN)
9957 temp = force_reg (Pmode, save_bc);
9958
9959 emit_move_insn (base, save_bp);
9960 emit_move_insn (operands[0], save_sp);
9961
9962 if (temp)
9963 emit_move_insn (s390_back_chain_rtx (), temp);
9964
9965 emit_use (base);
9966 DONE;
9967 })
9968
9969 (define_expand "exception_receiver"
9970 [(const_int 0)]
9971 ""
9972 {
9973 s390_set_has_landing_pad_p (true);
9974 DONE;
9975 })
9976
9977 ;
9978 ; nop instruction pattern(s).
9979 ;
9980
9981 (define_insn "nop"
9982 [(const_int 0)]
9983 ""
9984 "lr\t0,0"
9985 [(set_attr "op_type" "RR")
9986 (set_attr "z10prop" "z10_fr_E1")])
9987
9988 (define_insn "nop1"
9989 [(const_int 1)]
9990 ""
9991 "lr\t1,1"
9992 [(set_attr "op_type" "RR")])
9993
9994 ;;- Undeletable nops (used for hotpatching)
9995
9996 (define_insn "nop_2_byte"
9997 [(unspec_volatile [(const_int 0)] UNSPECV_NOP_2_BYTE)]
9998 ""
9999 "nopr\t%%r7"
10000 [(set_attr "op_type" "RR")])
10001
10002 (define_insn "nop_4_byte"
10003 [(unspec_volatile [(const_int 0)] UNSPECV_NOP_4_BYTE)]
10004 ""
10005 "nop\t0"
10006 [(set_attr "op_type" "RX")])
10007
10008 (define_insn "nop_6_byte"
10009 [(unspec_volatile [(const_int 0)] UNSPECV_NOP_6_BYTE)]
10010 "TARGET_CPU_ZARCH"
10011 "brcl\t0, 0"
10012 [(set_attr "op_type" "RIL")])
10013
10014
10015 ;
10016 ; Special literal pool access instruction pattern(s).
10017 ;
10018
10019 (define_insn "*pool_entry"
10020 [(unspec_volatile [(match_operand 0 "consttable_operand" "X")]
10021 UNSPECV_POOL_ENTRY)]
10022 ""
10023 {
10024 machine_mode mode = GET_MODE (PATTERN (insn));
10025 unsigned int align = GET_MODE_BITSIZE (mode);
10026 s390_output_pool_entry (operands[0], mode, align);
10027 return "";
10028 }
10029 [(set (attr "length")
10030 (symbol_ref "GET_MODE_SIZE (GET_MODE (PATTERN (insn)))"))])
10031
10032 (define_insn "pool_align"
10033 [(unspec_volatile [(match_operand 0 "const_int_operand" "n")]
10034 UNSPECV_POOL_ALIGN)]
10035 ""
10036 ".align\t%0"
10037 [(set (attr "length") (symbol_ref "INTVAL (operands[0])"))])
10038
10039 (define_insn "pool_section_start"
10040 [(unspec_volatile [(const_int 1)] UNSPECV_POOL_SECTION)]
10041 ""
10042 ".section\t.rodata"
10043 [(set_attr "length" "0")])
10044
10045 (define_insn "pool_section_end"
10046 [(unspec_volatile [(const_int 0)] UNSPECV_POOL_SECTION)]
10047 ""
10048 ".previous"
10049 [(set_attr "length" "0")])
10050
10051 (define_insn "main_base_31_small"
10052 [(set (match_operand 0 "register_operand" "=a")
10053 (unspec [(label_ref (match_operand 1 "" ""))] UNSPEC_MAIN_BASE))]
10054 "!TARGET_CPU_ZARCH && GET_MODE (operands[0]) == Pmode"
10055 "basr\t%0,0"
10056 [(set_attr "op_type" "RR")
10057 (set_attr "type" "la")
10058 (set_attr "z196prop" "z196_cracked")])
10059
10060 (define_insn "main_base_31_large"
10061 [(set (match_operand 0 "register_operand" "=a")
10062 (unspec [(label_ref (match_operand 1 "" ""))] UNSPEC_MAIN_BASE))
10063 (set (pc) (label_ref (match_operand 2 "" "")))]
10064 "!TARGET_CPU_ZARCH && GET_MODE (operands[0]) == Pmode"
10065 "bras\t%0,%2"
10066 [(set_attr "op_type" "RI")
10067 (set_attr "z196prop" "z196_cracked")])
10068
10069 (define_insn "main_base_64"
10070 [(set (match_operand 0 "register_operand" "=a")
10071 (unspec [(label_ref (match_operand 1 "" ""))] UNSPEC_MAIN_BASE))]
10072 "TARGET_CPU_ZARCH && GET_MODE (operands[0]) == Pmode"
10073 "larl\t%0,%1"
10074 [(set_attr "op_type" "RIL")
10075 (set_attr "type" "larl")
10076 (set_attr "z10prop" "z10_fwd_A1")])
10077
10078 (define_insn "main_pool"
10079 [(set (match_operand 0 "register_operand" "=a")
10080 (unspec_volatile [(const_int 0)] UNSPECV_MAIN_POOL))]
10081 "GET_MODE (operands[0]) == Pmode"
10082 {
10083 gcc_unreachable ();
10084 }
10085 [(set (attr "type")
10086 (if_then_else (match_test "TARGET_CPU_ZARCH")
10087 (const_string "larl") (const_string "la")))])
10088
10089 (define_insn "reload_base_31"
10090 [(set (match_operand 0 "register_operand" "=a")
10091 (unspec [(label_ref (match_operand 1 "" ""))] UNSPEC_RELOAD_BASE))]
10092 "!TARGET_CPU_ZARCH && GET_MODE (operands[0]) == Pmode"
10093 "basr\t%0,0\;la\t%0,%1-.(%0)"
10094 [(set_attr "length" "6")
10095 (set_attr "type" "la")
10096 (set_attr "z196prop" "z196_cracked")])
10097
10098 (define_insn "reload_base_64"
10099 [(set (match_operand 0 "register_operand" "=a")
10100 (unspec [(label_ref (match_operand 1 "" ""))] UNSPEC_RELOAD_BASE))]
10101 "TARGET_CPU_ZARCH && GET_MODE (operands[0]) == Pmode"
10102 "larl\t%0,%1"
10103 [(set_attr "op_type" "RIL")
10104 (set_attr "type" "larl")
10105 (set_attr "z10prop" "z10_fwd_A1")])
10106
10107 (define_insn "pool"
10108 [(unspec_volatile [(match_operand 0 "const_int_operand" "n")] UNSPECV_POOL)]
10109 ""
10110 {
10111 gcc_unreachable ();
10112 }
10113 [(set (attr "length") (symbol_ref "INTVAL (operands[0])"))])
10114
10115 ;;
10116 ;; Insns related to generating the function prologue and epilogue.
10117 ;;
10118
10119
10120 (define_expand "prologue"
10121 [(use (const_int 0))]
10122 ""
10123 "s390_emit_prologue (); DONE;")
10124
10125 (define_expand "epilogue"
10126 [(use (const_int 1))]
10127 ""
10128 "s390_emit_epilogue (false); DONE;")
10129
10130 (define_expand "sibcall_epilogue"
10131 [(use (const_int 0))]
10132 ""
10133 "s390_emit_epilogue (true); DONE;")
10134
10135 ;; A direct return instruction, without using an epilogue.
10136 (define_insn "<code>"
10137 [(ANY_RETURN)]
10138 "s390_can_use_<code>_insn ()"
10139 "br\t%%r14"
10140 [(set_attr "op_type" "RR")
10141 (set_attr "type" "jsr")
10142 (set_attr "atype" "agen")])
10143
10144 (define_insn "*return"
10145 [(return)
10146 (use (match_operand 0 "register_operand" "a"))]
10147 "GET_MODE (operands[0]) == Pmode"
10148 "br\t%0"
10149 [(set_attr "op_type" "RR")
10150 (set_attr "type" "jsr")
10151 (set_attr "atype" "agen")])
10152
10153
10154 ;; Instruction definition to extend a 31-bit pointer into a 64-bit
10155 ;; pointer. This is used for compatibility.
10156
10157 (define_expand "ptr_extend"
10158 [(set (match_operand:DI 0 "register_operand" "=r")
10159 (match_operand:SI 1 "register_operand" "r"))]
10160 "TARGET_64BIT"
10161 {
10162 emit_insn (gen_anddi3 (operands[0],
10163 gen_lowpart (DImode, operands[1]),
10164 GEN_INT (0x7fffffff)));
10165 DONE;
10166 })
10167
10168 ;; Instruction definition to expand eh_return macro to support
10169 ;; swapping in special linkage return addresses.
10170
10171 (define_expand "eh_return"
10172 [(use (match_operand 0 "register_operand" ""))]
10173 "TARGET_TPF"
10174 {
10175 s390_emit_tpf_eh_return (operands[0]);
10176 DONE;
10177 })
10178
10179 ;
10180 ; Stack Protector Patterns
10181 ;
10182
10183 (define_expand "stack_protect_set"
10184 [(set (match_operand 0 "memory_operand" "")
10185 (match_operand 1 "memory_operand" ""))]
10186 ""
10187 {
10188 #ifdef TARGET_THREAD_SSP_OFFSET
10189 operands[1]
10190 = gen_rtx_MEM (Pmode, gen_rtx_PLUS (Pmode, s390_get_thread_pointer (),
10191 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
10192 #endif
10193 if (TARGET_64BIT)
10194 emit_insn (gen_stack_protect_setdi (operands[0], operands[1]));
10195 else
10196 emit_insn (gen_stack_protect_setsi (operands[0], operands[1]));
10197
10198 DONE;
10199 })
10200
10201 (define_insn "stack_protect_set<mode>"
10202 [(set (match_operand:DSI 0 "memory_operand" "=Q")
10203 (unspec:DSI [(match_operand:DSI 1 "memory_operand" "Q")] UNSPEC_SP_SET))]
10204 ""
10205 "mvc\t%O0(%G0,%R0),%S1"
10206 [(set_attr "op_type" "SS")])
10207
10208 (define_expand "stack_protect_test"
10209 [(set (reg:CC CC_REGNUM)
10210 (compare (match_operand 0 "memory_operand" "")
10211 (match_operand 1 "memory_operand" "")))
10212 (match_operand 2 "" "")]
10213 ""
10214 {
10215 rtx cc_reg, test;
10216 #ifdef TARGET_THREAD_SSP_OFFSET
10217 operands[1]
10218 = gen_rtx_MEM (Pmode, gen_rtx_PLUS (Pmode, s390_get_thread_pointer (),
10219 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
10220 #endif
10221 if (TARGET_64BIT)
10222 emit_insn (gen_stack_protect_testdi (operands[0], operands[1]));
10223 else
10224 emit_insn (gen_stack_protect_testsi (operands[0], operands[1]));
10225
10226 cc_reg = gen_rtx_REG (CCZmode, CC_REGNUM);
10227 test = gen_rtx_EQ (VOIDmode, cc_reg, const0_rtx);
10228 emit_jump_insn (gen_cbranchcc4 (test, cc_reg, const0_rtx, operands[2]));
10229 DONE;
10230 })
10231
10232 (define_insn "stack_protect_test<mode>"
10233 [(set (reg:CCZ CC_REGNUM)
10234 (unspec:CCZ [(match_operand:DSI 0 "memory_operand" "Q")
10235 (match_operand:DSI 1 "memory_operand" "Q")] UNSPEC_SP_TEST))]
10236 ""
10237 "clc\t%O0(%G0,%R0),%S1"
10238 [(set_attr "op_type" "SS")])
10239
10240 ; This is used in s390_emit_prologue in order to prevent insns
10241 ; adjusting the stack pointer to be moved over insns writing stack
10242 ; slots using a copy of the stack pointer in a different register.
10243 (define_insn "stack_tie"
10244 [(set (match_operand:BLK 0 "memory_operand" "+m")
10245 (unspec:BLK [(match_dup 0)] UNSPEC_TIE))]
10246 ""
10247 ""
10248 [(set_attr "length" "0")])
10249
10250
10251 ;
10252 ; Data prefetch patterns
10253 ;
10254
10255 (define_insn "prefetch"
10256 [(prefetch (match_operand 0 "address_operand" "ZQZRZSZT,X")
10257 (match_operand:SI 1 "const_int_operand" " n,n")
10258 (match_operand:SI 2 "const_int_operand" " n,n"))]
10259 "TARGET_Z10"
10260 {
10261 switch (which_alternative)
10262 {
10263 case 0:
10264 return INTVAL (operands[1]) == 1 ? "pfd\t2,%a0" : "pfd\t1,%a0";
10265 case 1:
10266 if (larl_operand (operands[0], Pmode))
10267 return INTVAL (operands[1]) == 1 ? "pfdrl\t2,%a0" : "pfdrl\t1,%a0";
10268 default:
10269
10270 /* This might be reached for symbolic operands with an odd
10271 addend. We simply omit the prefetch for such rare cases. */
10272
10273 return "";
10274 }
10275 }
10276 [(set_attr "type" "load,larl")
10277 (set_attr "op_type" "RXY,RIL")
10278 (set_attr "z10prop" "z10_super")
10279 (set_attr "z196prop" "z196_alone")])
10280
10281
10282 ;
10283 ; Byte swap instructions
10284 ;
10285
10286 (define_insn "bswap<mode>2"
10287 [(set (match_operand:GPR 0 "register_operand" "=d, d")
10288 (bswap:GPR (match_operand:GPR 1 "nonimmediate_operand" " d,RT")))]
10289 "TARGET_CPU_ZARCH"
10290 "@
10291 lrv<g>r\t%0,%1
10292 lrv<g>\t%0,%1"
10293 [(set_attr "type" "*,load")
10294 (set_attr "op_type" "RRE,RXY")
10295 (set_attr "z10prop" "z10_super")])
10296
10297
10298 ;
10299 ; Population count instruction
10300 ;
10301
10302 ; The S/390 popcount instruction counts the bits of op1 in 8 byte
10303 ; portions and stores the result in the corresponding bytes in op0.
10304 (define_insn "*popcount<mode>"
10305 [(set (match_operand:INT 0 "register_operand" "=d")
10306 (unspec:INT [(match_operand:INT 1 "register_operand" "d")] UNSPEC_POPCNT))
10307 (clobber (reg:CC CC_REGNUM))]
10308 "TARGET_Z196"
10309 "popcnt\t%0,%1"
10310 [(set_attr "op_type" "RRE")])
10311
10312 (define_expand "popcountdi2"
10313 [; popcnt op0, op1
10314 (parallel [(set (match_operand:DI 0 "register_operand" "")
10315 (unspec:DI [(match_operand:DI 1 "register_operand")]
10316 UNSPEC_POPCNT))
10317 (clobber (reg:CC CC_REGNUM))])
10318 ; sllg op2, op0, 32
10319 (set (match_dup 2) (ashift:DI (match_dup 0) (const_int 32)))
10320 ; agr op0, op2
10321 (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 2)))
10322 (clobber (reg:CC CC_REGNUM))])
10323 ; sllg op2, op0, 16
10324 (set (match_dup 2)
10325 (ashift:DI (match_dup 0) (const_int 16)))
10326 ; agr op0, op2
10327 (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 2)))
10328 (clobber (reg:CC CC_REGNUM))])
10329 ; sllg op2, op0, 8
10330 (set (match_dup 2) (ashift:DI (match_dup 0) (const_int 8)))
10331 ; agr op0, op2
10332 (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 2)))
10333 (clobber (reg:CC CC_REGNUM))])
10334 ; srlg op0, op0, 56
10335 (set (match_dup 0) (lshiftrt:DI (match_dup 0) (const_int 56)))]
10336 "TARGET_Z196 && TARGET_64BIT"
10337 "operands[2] = gen_reg_rtx (DImode);")
10338
10339 (define_expand "popcountsi2"
10340 [; popcnt op0, op1
10341 (parallel [(set (match_operand:SI 0 "register_operand" "")
10342 (unspec:SI [(match_operand:SI 1 "register_operand")]
10343 UNSPEC_POPCNT))
10344 (clobber (reg:CC CC_REGNUM))])
10345 ; sllk op2, op0, 16
10346 (set (match_dup 2)
10347 (ashift:SI (match_dup 0) (const_int 16)))
10348 ; ar op0, op2
10349 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
10350 (clobber (reg:CC CC_REGNUM))])
10351 ; sllk op2, op0, 8
10352 (set (match_dup 2) (ashift:SI (match_dup 0) (const_int 8)))
10353 ; ar op0, op2
10354 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
10355 (clobber (reg:CC CC_REGNUM))])
10356 ; srl op0, op0, 24
10357 (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 24)))]
10358 "TARGET_Z196"
10359 "operands[2] = gen_reg_rtx (SImode);")
10360
10361 (define_expand "popcounthi2"
10362 [; popcnt op0, op1
10363 (parallel [(set (match_operand:HI 0 "register_operand" "")
10364 (unspec:HI [(match_operand:HI 1 "register_operand")]
10365 UNSPEC_POPCNT))
10366 (clobber (reg:CC CC_REGNUM))])
10367 ; sllk op2, op0, 8
10368 (set (match_dup 2)
10369 (ashift:SI (match_dup 0) (const_int 8)))
10370 ; ar op0, op2
10371 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
10372 (clobber (reg:CC CC_REGNUM))])
10373 ; srl op0, op0, 8
10374 (set (match_dup 0) (lshiftrt:HI (match_dup 0) (const_int 8)))]
10375 "TARGET_Z196"
10376 "operands[2] = gen_reg_rtx (SImode);")
10377
10378 (define_expand "popcountqi2"
10379 [; popcnt op0, op1
10380 (parallel [(set (match_operand:QI 0 "register_operand" "")
10381 (unspec:QI [(match_operand:QI 1 "register_operand")]
10382 UNSPEC_POPCNT))
10383 (clobber (reg:CC CC_REGNUM))])]
10384 "TARGET_Z196"
10385 "")
10386
10387 ;;
10388 ;;- Copy sign instructions
10389 ;;
10390
10391 (define_insn "copysign<mode>3"
10392 [(set (match_operand:FP 0 "register_operand" "=f")
10393 (unspec:FP [(match_operand:FP 1 "register_operand" "<fT0>")
10394 (match_operand:FP 2 "register_operand" "f")]
10395 UNSPEC_COPYSIGN))]
10396 "TARGET_Z196"
10397 "cpsdr\t%0,%2,%1"
10398 [(set_attr "op_type" "RRF")
10399 (set_attr "type" "fsimp<mode>")])
10400
10401
10402 ;;
10403 ;;- Transactional execution instructions
10404 ;;
10405
10406 ; This splitter helps combine to make use of CC directly when
10407 ; comparing the integer result of a tbegin builtin with a constant.
10408 ; The unspec is already removed by canonicalize_comparison. So this
10409 ; splitters only job is to turn the PARALLEL into separate insns
10410 ; again. Unfortunately this only works with the very first cc/int
10411 ; compare since combine is not able to deal with data flow across
10412 ; basic block boundaries.
10413
10414 ; It needs to be an insn pattern as well since combine does not apply
10415 ; the splitter directly. Combine would only use it if it actually
10416 ; would reduce the number of instructions.
10417 (define_insn_and_split "*ccraw_to_int"
10418 [(set (pc)
10419 (if_then_else
10420 (match_operator 0 "s390_eqne_operator"
10421 [(reg:CCRAW CC_REGNUM)
10422 (match_operand 1 "const_int_operand" "")])
10423 (label_ref (match_operand 2 "" ""))
10424 (pc)))
10425 (set (match_operand:SI 3 "register_operand" "=d")
10426 (unspec:SI [(reg:CCRAW CC_REGNUM)] UNSPEC_CC_TO_INT))]
10427 ""
10428 "#"
10429 ""
10430 [(set (match_dup 3)
10431 (unspec:SI [(reg:CCRAW CC_REGNUM)] UNSPEC_CC_TO_INT))
10432 (set (pc)
10433 (if_then_else (match_op_dup 0 [(reg:CCRAW CC_REGNUM) (match_dup 1)])
10434 (label_ref (match_dup 2))
10435 (pc)))]
10436 "")
10437
10438 ; Non-constrained transaction begin
10439
10440 (define_expand "tbegin"
10441 [(match_operand:SI 0 "register_operand" "")
10442 (match_operand:BLK 1 "memory_operand" "")]
10443 "TARGET_HTM"
10444 {
10445 s390_expand_tbegin (operands[0], operands[1], NULL_RTX, true);
10446 DONE;
10447 })
10448
10449 (define_expand "tbegin_nofloat"
10450 [(match_operand:SI 0 "register_operand" "")
10451 (match_operand:BLK 1 "memory_operand" "")]
10452 "TARGET_HTM"
10453 {
10454 s390_expand_tbegin (operands[0], operands[1], NULL_RTX, false);
10455 DONE;
10456 })
10457
10458 (define_expand "tbegin_retry"
10459 [(match_operand:SI 0 "register_operand" "")
10460 (match_operand:BLK 1 "memory_operand" "")
10461 (match_operand:SI 2 "general_operand" "")]
10462 "TARGET_HTM"
10463 {
10464 s390_expand_tbegin (operands[0], operands[1], operands[2], true);
10465 DONE;
10466 })
10467
10468 (define_expand "tbegin_retry_nofloat"
10469 [(match_operand:SI 0 "register_operand" "")
10470 (match_operand:BLK 1 "memory_operand" "")
10471 (match_operand:SI 2 "general_operand" "")]
10472 "TARGET_HTM"
10473 {
10474 s390_expand_tbegin (operands[0], operands[1], operands[2], false);
10475 DONE;
10476 })
10477
10478 (define_insn "tbegin_1"
10479 [(set (reg:CCRAW CC_REGNUM)
10480 (unspec_volatile:CCRAW [(match_operand 0 "const_int_operand" "D")]
10481 UNSPECV_TBEGIN))
10482 (set (match_operand:BLK 1 "memory_operand" "=Q")
10483 (unspec_volatile:BLK [(match_dup 0)] UNSPECV_TBEGIN_TDB))
10484 (clobber (reg:DF 16))
10485 (clobber (reg:DF 17))
10486 (clobber (reg:DF 18))
10487 (clobber (reg:DF 19))
10488 (clobber (reg:DF 20))
10489 (clobber (reg:DF 21))
10490 (clobber (reg:DF 22))
10491 (clobber (reg:DF 23))
10492 (clobber (reg:DF 24))
10493 (clobber (reg:DF 25))
10494 (clobber (reg:DF 26))
10495 (clobber (reg:DF 27))
10496 (clobber (reg:DF 28))
10497 (clobber (reg:DF 29))
10498 (clobber (reg:DF 30))
10499 (clobber (reg:DF 31))]
10500 ; CONST_OK_FOR_CONSTRAINT_P does not work with D constraint since D is
10501 ; not supposed to be used for immediates (see genpreds.c).
10502 "TARGET_HTM && INTVAL (operands[0]) >= 0 && INTVAL (operands[0]) <= 0xffff"
10503 "tbegin\t%1,%x0"
10504 [(set_attr "op_type" "SIL")])
10505
10506 ; Same as above but without the FPR clobbers
10507 (define_insn "tbegin_nofloat_1"
10508 [(set (reg:CCRAW CC_REGNUM)
10509 (unspec_volatile:CCRAW [(match_operand 0 "const_int_operand" "D")]
10510 UNSPECV_TBEGIN))
10511 (set (match_operand:BLK 1 "memory_operand" "=Q")
10512 (unspec_volatile:BLK [(match_dup 0)] UNSPECV_TBEGIN_TDB))]
10513 "TARGET_HTM && INTVAL (operands[0]) >= 0 && INTVAL (operands[0]) <= 0xffff"
10514 "tbegin\t%1,%x0"
10515 [(set_attr "op_type" "SIL")])
10516
10517
10518 ; Constrained transaction begin
10519
10520 (define_expand "tbeginc"
10521 [(set (reg:CCRAW CC_REGNUM)
10522 (unspec_volatile:CCRAW [(const_int TBEGINC_MASK)]
10523 UNSPECV_TBEGINC))]
10524 "TARGET_HTM"
10525 "")
10526
10527 (define_insn "*tbeginc_1"
10528 [(set (reg:CCRAW CC_REGNUM)
10529 (unspec_volatile:CCRAW [(match_operand 0 "const_int_operand" " D")]
10530 UNSPECV_TBEGINC))]
10531 "TARGET_HTM && INTVAL (operands[0]) >= 0 && INTVAL (operands[0]) <= 0xffff"
10532 "tbeginc\t0,%x0"
10533 [(set_attr "op_type" "SIL")])
10534
10535 ; Transaction end
10536
10537 (define_expand "tend"
10538 [(set (reg:CCRAW CC_REGNUM)
10539 (unspec_volatile:CCRAW [(const_int 0)] UNSPECV_TEND))
10540 (set (match_operand:SI 0 "register_operand" "")
10541 (unspec:SI [(reg:CCRAW CC_REGNUM)] UNSPEC_CC_TO_INT))]
10542 "TARGET_HTM"
10543 "")
10544
10545 (define_insn "*tend_1"
10546 [(set (reg:CCRAW CC_REGNUM)
10547 (unspec_volatile:CCRAW [(const_int 0)] UNSPECV_TEND))]
10548 "TARGET_HTM"
10549 "tend"
10550 [(set_attr "op_type" "S")])
10551
10552 ; Transaction abort
10553
10554 (define_expand "tabort"
10555 [(unspec_volatile [(match_operand:SI 0 "shift_count_or_setmem_operand" "")]
10556 UNSPECV_TABORT)]
10557 "TARGET_HTM && operands != NULL"
10558 {
10559 if (CONST_INT_P (operands[0])
10560 && INTVAL (operands[0]) >= 0 && INTVAL (operands[0]) <= 255)
10561 {
10562 error ("Invalid transaction abort code: " HOST_WIDE_INT_PRINT_DEC
10563 ". Values in range 0 through 255 are reserved.",
10564 INTVAL (operands[0]));
10565 FAIL;
10566 }
10567 })
10568
10569 (define_insn "*tabort_1"
10570 [(unspec_volatile [(match_operand:SI 0 "shift_count_or_setmem_operand" "Y")]
10571 UNSPECV_TABORT)]
10572 "TARGET_HTM && operands != NULL"
10573 "tabort\t%Y0"
10574 [(set_attr "op_type" "S")])
10575
10576 ; Transaction extract nesting depth
10577
10578 (define_insn "etnd"
10579 [(set (match_operand:SI 0 "register_operand" "=d")
10580 (unspec_volatile:SI [(const_int 0)] UNSPECV_ETND))]
10581 "TARGET_HTM"
10582 "etnd\t%0"
10583 [(set_attr "op_type" "RRE")])
10584
10585 ; Non-transactional store
10586
10587 (define_insn "ntstg"
10588 [(set (match_operand:DI 0 "memory_operand" "=RT")
10589 (unspec_volatile:DI [(match_operand:DI 1 "register_operand" "d")]
10590 UNSPECV_NTSTG))]
10591 "TARGET_HTM"
10592 "ntstg\t%1,%0"
10593 [(set_attr "op_type" "RXY")])
10594
10595 ; Transaction perform processor assist
10596
10597 (define_expand "tx_assist"
10598 [(unspec_volatile [(match_operand:SI 0 "register_operand" "")
10599 (reg:SI GPR0_REGNUM)
10600 (const_int 1)]
10601 UNSPECV_PPA)]
10602 "TARGET_HTM"
10603 "")
10604
10605 (define_insn "*ppa"
10606 [(unspec_volatile [(match_operand:SI 0 "register_operand" "d")
10607 (match_operand:SI 1 "register_operand" "d")
10608 (match_operand 2 "const_int_operand" "I")]
10609 UNSPECV_PPA)]
10610 "TARGET_HTM && INTVAL (operands[2]) < 16"
10611 "ppa\t%0,%1,%2"
10612 [(set_attr "op_type" "RRF")])
10613
10614
10615 ; Set and get floating point control register
10616
10617 (define_insn "s390_sfpc"
10618 [(unspec_volatile [(match_operand:SI 0 "register_operand" "d")]
10619 UNSPECV_SFPC)]
10620 "TARGET_HARD_FLOAT"
10621 "sfpc\t%0")
10622
10623 (define_insn "s390_efpc"
10624 [(set (match_operand:SI 0 "register_operand" "=d")
10625 (unspec_volatile:SI [(const_int 0)] UNSPECV_EFPC))]
10626 "TARGET_HARD_FLOAT"
10627 "efpc\t%0")