optabs.h: Added declaration for signbit_optab.
[gcc.git] / gcc / config / s390 / s390.md
1 ;;- Machine description for GNU compiler -- S/390 / zSeries version.
2 ;; Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006
3 ;; Free Software Foundation, Inc.
4 ;; Contributed by Hartmut Penner (hpenner@de.ibm.com) and
5 ;; Ulrich Weigand (uweigand@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 2, 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 COPYING. If not, write to the Free
21 ;; Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
22 ;; 02110-1301, USA.
23
24 ;;
25 ;; See constraints.md for a description of constraints specific to s390.
26 ;;
27
28 ;; Special formats used for outputting 390 instructions.
29 ;;
30 ;; %C: print opcode suffix for branch condition.
31 ;; %D: print opcode suffix for inverse branch condition.
32 ;; %J: print tls_load/tls_gdcall/tls_ldcall suffix
33 ;; %G: print the size of the operand in bytes.
34 ;; %O: print only the displacement of a memory reference.
35 ;; %R: print only the base register of a memory reference.
36 ;; %S: print S-type memory reference (base+displacement).
37 ;; %N: print the second word of a DImode operand.
38 ;; %M: print the second word of a TImode operand.
39 ;; %Y: print shift count operand.
40 ;;
41 ;; %b: print integer X as if it's an unsigned 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_constants
60 [; Miscellaneous
61 (UNSPEC_ROUND 1)
62 (UNSPEC_CCU_TO_INT 2)
63 (UNSPEC_CCZ_TO_INT 3)
64 (UNSPEC_ICM 10)
65
66 ; GOT/PLT and lt-relative accesses
67 (UNSPEC_LTREL_OFFSET 100)
68 (UNSPEC_LTREL_BASE 101)
69 (UNSPEC_GOTENT 110)
70 (UNSPEC_GOT 111)
71 (UNSPEC_GOTOFF 112)
72 (UNSPEC_PLT 113)
73 (UNSPEC_PLTOFF 114)
74
75 ; Literal pool
76 (UNSPEC_RELOAD_BASE 210)
77 (UNSPEC_MAIN_BASE 211)
78 (UNSPEC_LTREF 212)
79 (UNSPEC_INSN 213)
80 (UNSPEC_EXECUTE 214)
81
82 ; TLS relocation specifiers
83 (UNSPEC_TLSGD 500)
84 (UNSPEC_TLSLDM 501)
85 (UNSPEC_NTPOFF 502)
86 (UNSPEC_DTPOFF 503)
87 (UNSPEC_GOTNTPOFF 504)
88 (UNSPEC_INDNTPOFF 505)
89
90 ; TLS support
91 (UNSPEC_TLSLDM_NTPOFF 511)
92 (UNSPEC_TLS_LOAD 512)
93
94 ; String Functions
95 (UNSPEC_SRST 600)
96 (UNSPEC_MVST 601)
97
98 ; Stack Smashing Protector
99 (UNSPEC_SP_SET 700)
100 (UNSPEC_SP_TEST 701)
101
102 ; Copy sign instructions
103 (UNSPEC_COPYSIGN 800)
104
105 ; Test Data Class (TDC)
106 (UNSPEC_TDC_INSN 900)
107 ])
108
109 ;;
110 ;; UNSPEC_VOLATILE usage
111 ;;
112
113 (define_constants
114 [; Blockage
115 (UNSPECV_BLOCKAGE 0)
116
117 ; TPF Support
118 (UNSPECV_TPF_PROLOGUE 20)
119 (UNSPECV_TPF_EPILOGUE 21)
120
121 ; Literal pool
122 (UNSPECV_POOL 200)
123 (UNSPECV_POOL_SECTION 201)
124 (UNSPECV_POOL_ALIGN 202)
125 (UNSPECV_POOL_ENTRY 203)
126 (UNSPECV_MAIN_POOL 300)
127
128 ; TLS support
129 (UNSPECV_SET_TP 500)
130
131 ; Atomic Support
132 (UNSPECV_MB 700)
133 (UNSPECV_CAS 701)
134 ])
135
136 ;;
137 ;; Registers
138 ;;
139
140 ; Registers with special meaning
141
142 (define_constants
143 [
144 ; Sibling call register.
145 (SIBCALL_REGNUM 1)
146 ; Literal pool base register.
147 (BASE_REGNUM 13)
148 ; Return address register.
149 (RETURN_REGNUM 14)
150 ; Condition code register.
151 (CC_REGNUM 33)
152 ; Thread local storage pointer register.
153 (TP_REGNUM 36)
154 ])
155
156 ; Hardware register names
157
158 (define_constants
159 [
160 ; General purpose registers
161 (GPR0_REGNUM 0)
162 ; Floating point registers.
163 (FPR0_REGNUM 16)
164 (FPR2_REGNUM 18)
165 ])
166
167 ;;
168 ;; PFPO GPR0 argument format
169 ;;
170
171 (define_constants
172 [
173 ; PFPO operation type
174 (PFPO_CONVERT 0x1000000)
175 ; PFPO operand types
176 (PFPO_OP_TYPE_SF 0x5)
177 (PFPO_OP_TYPE_DF 0x6)
178 (PFPO_OP_TYPE_TF 0x7)
179 (PFPO_OP_TYPE_SD 0x8)
180 (PFPO_OP_TYPE_DD 0x9)
181 (PFPO_OP_TYPE_TD 0xa)
182 ; Bitposition of operand types
183 (PFPO_OP0_TYPE_SHIFT 16)
184 (PFPO_OP1_TYPE_SHIFT 8)
185 ])
186
187
188 ;; Instruction operand type as used in the Principles of Operation.
189 ;; Used to determine defaults for length and other attribute values.
190
191 (define_attr "op_type"
192 "NN,E,RR,RRE,RX,RS,RSI,RI,SI,S,SS,SSE,RXE,RSE,RIL,RIE,RXY,RSY,SIY,RRF,RRR"
193 (const_string "NN"))
194
195 ;; Instruction type attribute used for scheduling.
196
197 (define_attr "type" "none,integer,load,lr,la,larl,lm,stm,
198 cs,vs,store,sem,idiv,
199 imulhi,imulsi,imuldi,
200 branch,jsr,fsimptf,fsimpdf,fsimpsf,
201 floadtf,floaddf,floadsf,fstoredf,fstoresf,
202 fmultf,fmuldf,fmulsf,fdivtf,fdivdf,fdivsf,
203 ftoi,itof,fsqrttf,fsqrtdf,fsqrtsf,
204 ftrunctf,ftruncdf,other"
205 (cond [(eq_attr "op_type" "NN") (const_string "other")
206 (eq_attr "op_type" "SS") (const_string "cs")]
207 (const_string "integer")))
208
209 ;; Another attribute used for scheduling purposes:
210 ;; agen: Instruction uses the address generation unit
211 ;; reg: Instruction does not use the agen unit
212
213 (define_attr "atype" "agen,reg"
214 (if_then_else (eq_attr "op_type" "E,RR,RI,RRE")
215 (const_string "reg")
216 (const_string "agen")))
217
218 ;; Length in bytes.
219
220 (define_attr "length" ""
221 (cond [(eq_attr "op_type" "E,RR") (const_int 2)
222 (eq_attr "op_type" "RX,RI,RRE,RS,RSI,S,SI") (const_int 4)]
223 (const_int 6)))
224
225
226 ;; Processor type. This attribute must exactly match the processor_type
227 ;; enumeration in s390.h. The current machine description does not
228 ;; distinguish between g5 and g6, but there are differences between the two
229 ;; CPUs could in theory be modeled.
230
231 (define_attr "cpu" "g5,g6,z900,z990,z9_109"
232 (const (symbol_ref "s390_tune")))
233
234 ;; Pipeline description for z900. For lack of anything better,
235 ;; this description is also used for the g5 and g6.
236 (include "2064.md")
237
238 ;; Pipeline description for z990, z9-109 and z9-ec.
239 (include "2084.md")
240
241 ;; Predicates
242 (include "predicates.md")
243
244 ;; Constraint definitions
245 (include "constraints.md")
246
247 ;; Other includes
248 (include "tpf.md")
249
250 ;; Macros
251
252 ;; This mode macro allows floating point patterns to be generated from the
253 ;; same template.
254 (define_mode_macro FP [TF DF SF (TD "TARGET_HARD_DFP") (DD "TARGET_HARD_DFP")])
255 (define_mode_macro BFP [TF DF SF])
256 (define_mode_macro DFP [TD DD])
257 (define_mode_macro DFP_ALL [TD DD SD])
258 (define_mode_macro DSF [DF SF])
259 (define_mode_macro SD_SF [SF SD])
260 (define_mode_macro DD_DF [DF DD])
261 (define_mode_macro TD_TF [TF TD])
262
263 ;; These mode macros allow 31-bit and 64-bit TDSI patterns to be generated
264 ;; from the same template.
265 (define_mode_macro TDSI [(TI "TARGET_64BIT") DI SI])
266
267 ;; These mode macros allow 31-bit and 64-bit GPR patterns to be generated
268 ;; from the same template.
269 (define_mode_macro GPR [(DI "TARGET_64BIT") SI])
270 (define_mode_macro DSI [DI SI])
271
272 ;; This mode macro allows :P to be used for patterns that operate on
273 ;; pointer-sized quantities. Exactly one of the two alternatives will match.
274 (define_mode_macro DP [(TI "TARGET_64BIT") (DI "!TARGET_64BIT")])
275 (define_mode_macro P [(DI "TARGET_64BIT") (SI "!TARGET_64BIT")])
276
277 ;; This mode macro allows the QI and HI patterns to be defined from
278 ;; the same template.
279 (define_mode_macro HQI [HI QI])
280
281 ;; This mode macro allows the integer patterns to be defined from the
282 ;; same template.
283 (define_mode_macro INT [(DI "TARGET_64BIT") SI HI QI])
284
285 ;; This macro allows to unify all 'bCOND' expander patterns.
286 (define_code_macro COMPARE [eq ne gt gtu lt ltu ge geu le leu unordered
287 ordered uneq unlt ungt unle unge ltgt])
288
289 ;; This macro allows to unify all 'sCOND' patterns.
290 (define_code_macro SCOND [ltu gtu leu geu])
291
292 ;; This macro allows some 'ashift' and 'lshiftrt' pattern to be defined from
293 ;; the same template.
294 (define_code_macro SHIFT [ashift lshiftrt])
295
296 ;; These macros allow to combine most atomic operations.
297 (define_code_macro ATOMIC [and ior xor plus minus mult])
298 (define_code_attr atomic [(and "and") (ior "ior") (xor "xor")
299 (plus "add") (minus "sub") (mult "nand")])
300
301 ;; In FP templates, a string like "lt<de>br" will expand to "ltxbr" in
302 ;; TF/TDmode, "ltdbr" in DF/DDmode, and "ltebr" in SF/SDmode.
303 (define_mode_attr xde [(TF "x") (DF "d") (SF "e") (TD "x") (DD "d") (SD "e")])
304
305 ;; In FP templates, a <dee> in "m<dee><bt>r" will expand to "mx<bt>r" in
306 ;; TF/TDmode, "md<bt>r" in DF/DDmode, "mee<bt>r" in SFmode and "me<bt>r in
307 ;; SDmode.
308 (define_mode_attr xdee [(TF "x") (DF "d") (SF "ee") (TD "x") (DD "d") (SD "e")])
309
310 ;; In FP templates, "<RRe>" will expand to "RRE" in TFmode and "RR" otherwise.
311 ;; Likewise for "<RXe>".
312 (define_mode_attr RRe [(TF "RRE") (DF "RR") (SF "RR")])
313 (define_mode_attr RXe [(TF "RXE") (DF "RX") (SF "RX")])
314
315 ;; The decimal floating point variants of add, sub, div and mul support 3
316 ;; fp register operands. The following macros allow to merge the bfp and
317 ;; dfp variants in a single insn definition.
318
319 ;; This macro is used to set op_type accordingly.
320 (define_mode_attr RRer [(TF "RRE") (DF "RRE") (SF "RRE") (TD "RRR")
321 (DD "RRR") (SD "RRR")])
322
323 ;; This macro is used in the operand constraint list in order to have the
324 ;; first and the second operand match for bfp modes.
325 (define_mode_attr f0 [(TF "0") (DF "0") (SF "0") (TD "f") (DD "f") (DD "f")])
326
327 ;; This macro is used in the operand list of the instruction to have an
328 ;; additional operand for the dfp instructions.
329 (define_mode_attr op1 [(TF "") (DF "") (SF "")
330 (TD "%1,") (DD "%1,") (SD "%1,")])
331
332
333 ;; This attribute is used in the operand constraint list
334 ;; for instructions dealing with the sign bit of 32 or 64bit fp values.
335 ;; TFmode values are represented by a fp register pair. Since the
336 ;; sign bit instructions only handle single source and target fp registers
337 ;; these instructions can only be used for TFmode values if the source and
338 ;; target operand uses the same fp register.
339 (define_mode_attr fT0 [(TF "0") (DF "f") (SF "f")])
340
341 ;; In FP templates, "<Rf>" will expand to "f" in TFmode and "R" otherwise.
342 ;; This is used to disable the memory alternative in TFmode patterns.
343 (define_mode_attr Rf [(TF "f") (DF "R") (SF "R") (TD "f") (DD "f") (SD "f")])
344
345 ;; This macro adds b for bfp instructions and t for dfp instructions and is used
346 ;; within instruction mnemonics.
347 (define_mode_attr bt [(TF "b") (DF "b") (SF "b") (TD "t") (DD "t") (SD "t")])
348
349 ;; Although it is imprecise for z9-ec we handle all dfp instructions like
350 ;; bfp regarding the pipeline description.
351 (define_mode_attr bfp [(TF "tf") (DF "df") (SF "sf")
352 (TD "tf") (DD "df") (SD "sf")])
353
354
355 ;; In GPR and P templates, a constraint like "<d0>" will expand to "d" in DImode
356 ;; and "0" in SImode. This allows to combine instructions of which the 31bit
357 ;; version only operates on one register.
358 (define_mode_attr d0 [(DI "d") (SI "0")])
359
360 ;; In combination with d0 this allows to combine instructions of which the 31bit
361 ;; version only operates on one register. The DImode version needs an additional
362 ;; register for the assembler output.
363 (define_mode_attr 1 [(DI "%1,") (SI "")])
364
365 ;; In SHIFT templates, a string like "s<lr>dl" will expand to "sldl" in
366 ;; 'ashift' and "srdl" in 'lshiftrt'.
367 (define_code_attr lr [(ashift "l") (lshiftrt "r")])
368
369 ;; In SHIFT templates, this attribute holds the correct standard name for the
370 ;; pattern itself and the corresponding function calls.
371 (define_code_attr shift [(ashift "ashl") (lshiftrt "lshr")])
372
373 ;; This attribute handles differences in the instruction 'type' and will result
374 ;; in "RRE" for DImode and "RR" for SImode.
375 (define_mode_attr E [(DI "E") (SI "")])
376
377 ;; This attribute handles differences in the instruction 'type' and makes RX<Y>
378 ;; to result in "RXY" for DImode and "RX" for SImode.
379 (define_mode_attr Y [(DI "Y") (SI "")])
380
381 ;; This attribute handles differences in the instruction 'type' and will result
382 ;; in "RSE" for TImode and "RS" for DImode.
383 (define_mode_attr TE [(TI "E") (DI "")])
384
385 ;; In GPR templates, a string like "lc<g>r" will expand to "lcgr" in DImode
386 ;; and "lcr" in SImode.
387 (define_mode_attr g [(DI "g") (SI "")])
388
389 ;; In GPR templates, a string like "sl<y>" will expand to "slg" in DImode
390 ;; and "sly" in SImode. This is useful because on 64bit the ..g instructions
391 ;; were enhanced with long displacements whereas 31bit instructions got a ..y
392 ;; variant for long displacements.
393 (define_mode_attr y [(DI "g") (SI "y")])
394
395 ;; In DP templates, a string like "cds<g>" will expand to "cdsg" in TImode
396 ;; and "cds" in DImode.
397 (define_mode_attr tg [(TI "g") (DI "")])
398
399 ;; In GPR templates, a string like "c<gf>dbr" will expand to "cgdbr" in DImode
400 ;; and "cfdbr" in SImode.
401 (define_mode_attr gf [(DI "g") (SI "f")])
402
403 ;; ICM mask required to load MODE value into the lowest subreg
404 ;; of a SImode register.
405 (define_mode_attr icm_lo [(HI "3") (QI "1")])
406
407 ;; In HQI templates, a string like "llg<hc>" will expand to "llgh" in
408 ;; HImode and "llgc" in QImode.
409 (define_mode_attr hc [(HI "h") (QI "c")])
410
411 ;; In P templates, the mode <DBL> will expand to "TI" in DImode and "DI"
412 ;; in SImode.
413 (define_mode_attr DBL [(DI "TI") (SI "DI")])
414
415 ;; This attribute expands to DF for TFmode and to DD for TDmode . It is
416 ;; used for Txmode splitters splitting a Txmode copy into 2 Dxmode copies.
417 (define_mode_attr HALF_TMODE [(TF "DF") (TD "DD")])
418
419 ;; Maximum unsigned integer that fits in MODE.
420 (define_mode_attr max_uint [(HI "65535") (QI "255")])
421
422
423 ;;
424 ;;- Compare instructions.
425 ;;
426
427 (define_expand "cmp<mode>"
428 [(set (reg:CC CC_REGNUM)
429 (compare:CC (match_operand:GPR 0 "register_operand" "")
430 (match_operand:GPR 1 "general_operand" "")))]
431 ""
432 {
433 s390_compare_op0 = operands[0];
434 s390_compare_op1 = operands[1];
435 DONE;
436 })
437
438 (define_expand "cmp<mode>"
439 [(set (reg:CC CC_REGNUM)
440 (compare:CC (match_operand:FP 0 "register_operand" "")
441 (match_operand:FP 1 "general_operand" "")))]
442 "TARGET_HARD_FLOAT"
443 {
444 s390_compare_op0 = operands[0];
445 s390_compare_op1 = operands[1];
446 DONE;
447 })
448
449
450 ; Test-under-Mask instructions
451
452 (define_insn "*tmqi_mem"
453 [(set (reg CC_REGNUM)
454 (compare (and:QI (match_operand:QI 0 "memory_operand" "Q,S")
455 (match_operand:QI 1 "immediate_operand" "n,n"))
456 (match_operand:QI 2 "immediate_operand" "n,n")))]
457 "s390_match_ccmode (insn, s390_tm_ccmode (operands[1], operands[2], false))"
458 "@
459 tm\t%S0,%b1
460 tmy\t%S0,%b1"
461 [(set_attr "op_type" "SI,SIY")])
462
463 (define_insn "*tmdi_reg"
464 [(set (reg CC_REGNUM)
465 (compare (and:DI (match_operand:DI 0 "nonimmediate_operand" "d,d,d,d")
466 (match_operand:DI 1 "immediate_operand"
467 "N0HD0,N1HD0,N2HD0,N3HD0"))
468 (match_operand:DI 2 "immediate_operand" "n,n,n,n")))]
469 "TARGET_64BIT
470 && s390_match_ccmode (insn, s390_tm_ccmode (operands[1], operands[2], true))
471 && s390_single_part (operands[1], DImode, HImode, 0) >= 0"
472 "@
473 tmhh\t%0,%i1
474 tmhl\t%0,%i1
475 tmlh\t%0,%i1
476 tmll\t%0,%i1"
477 [(set_attr "op_type" "RI")])
478
479 (define_insn "*tmsi_reg"
480 [(set (reg CC_REGNUM)
481 (compare (and:SI (match_operand:SI 0 "nonimmediate_operand" "d,d")
482 (match_operand:SI 1 "immediate_operand" "N0HS0,N1HS0"))
483 (match_operand:SI 2 "immediate_operand" "n,n")))]
484 "s390_match_ccmode (insn, s390_tm_ccmode (operands[1], operands[2], true))
485 && s390_single_part (operands[1], SImode, HImode, 0) >= 0"
486 "@
487 tmh\t%0,%i1
488 tml\t%0,%i1"
489 [(set_attr "op_type" "RI")])
490
491 (define_insn "*tm<mode>_full"
492 [(set (reg CC_REGNUM)
493 (compare (match_operand:HQI 0 "register_operand" "d")
494 (match_operand:HQI 1 "immediate_operand" "n")))]
495 "s390_match_ccmode (insn, s390_tm_ccmode (constm1_rtx, operands[1], true))"
496 "tml\t%0,<max_uint>"
497 [(set_attr "op_type" "RI")])
498
499
500 ;
501 ; Load-and-Test instructions
502 ;
503
504 ; tst(di|si) instruction pattern(s).
505
506 (define_insn "*tstdi_sign"
507 [(set (reg CC_REGNUM)
508 (compare (ashiftrt:DI (ashift:DI (subreg:DI (match_operand:SI 0 "register_operand" "d") 0)
509 (const_int 32)) (const_int 32))
510 (match_operand:DI 1 "const0_operand" "")))
511 (set (match_operand:DI 2 "register_operand" "=d")
512 (sign_extend:DI (match_dup 0)))]
513 "s390_match_ccmode(insn, CCSmode) && TARGET_64BIT"
514 "ltgfr\t%2,%0"
515 [(set_attr "op_type" "RRE")])
516
517 ; ltr, lt, ltgr, ltg
518 (define_insn "*tst<mode>_extimm"
519 [(set (reg CC_REGNUM)
520 (compare (match_operand:GPR 0 "nonimmediate_operand" "d,m")
521 (match_operand:GPR 1 "const0_operand" "")))
522 (set (match_operand:GPR 2 "register_operand" "=d,d")
523 (match_dup 0))]
524 "s390_match_ccmode(insn, CCSmode) && TARGET_EXTIMM"
525 "@
526 lt<g>r\t%2,%0
527 lt<g>\t%2,%0"
528 [(set_attr "op_type" "RR<E>,RXY")])
529
530 ; ltr, lt, ltgr, ltg
531 (define_insn "*tst<mode>_cconly_extimm"
532 [(set (reg CC_REGNUM)
533 (compare (match_operand:GPR 0 "nonimmediate_operand" "d,m")
534 (match_operand:GPR 1 "const0_operand" "")))
535 (clobber (match_scratch:GPR 2 "=X,d"))]
536 "s390_match_ccmode(insn, CCSmode) && TARGET_EXTIMM"
537 "@
538 lt<g>r\t%0,%0
539 lt<g>\t%2,%0"
540 [(set_attr "op_type" "RR<E>,RXY")])
541
542 (define_insn "*tstdi"
543 [(set (reg CC_REGNUM)
544 (compare (match_operand:DI 0 "register_operand" "d")
545 (match_operand:DI 1 "const0_operand" "")))
546 (set (match_operand:DI 2 "register_operand" "=d")
547 (match_dup 0))]
548 "s390_match_ccmode(insn, CCSmode) && TARGET_64BIT && !TARGET_EXTIMM"
549 "ltgr\t%2,%0"
550 [(set_attr "op_type" "RRE")])
551
552 (define_insn "*tstsi"
553 [(set (reg CC_REGNUM)
554 (compare (match_operand:SI 0 "nonimmediate_operand" "d,Q,S")
555 (match_operand:SI 1 "const0_operand" "")))
556 (set (match_operand:SI 2 "register_operand" "=d,d,d")
557 (match_dup 0))]
558 "s390_match_ccmode(insn, CCSmode) && !TARGET_EXTIMM"
559 "@
560 ltr\t%2,%0
561 icm\t%2,15,%S0
562 icmy\t%2,15,%S0"
563 [(set_attr "op_type" "RR,RS,RSY")])
564
565 (define_insn "*tstsi_cconly"
566 [(set (reg CC_REGNUM)
567 (compare (match_operand:SI 0 "nonimmediate_operand" "d,Q,S")
568 (match_operand:SI 1 "const0_operand" "")))
569 (clobber (match_scratch:SI 2 "=X,d,d"))]
570 "s390_match_ccmode(insn, CCSmode)"
571 "@
572 ltr\t%0,%0
573 icm\t%2,15,%S0
574 icmy\t%2,15,%S0"
575 [(set_attr "op_type" "RR,RS,RSY")])
576
577 (define_insn "*tstdi_cconly_31"
578 [(set (reg CC_REGNUM)
579 (compare (match_operand:DI 0 "register_operand" "d")
580 (match_operand:DI 1 "const0_operand" "")))]
581 "s390_match_ccmode(insn, CCSmode) && !TARGET_64BIT"
582 "srda\t%0,0"
583 [(set_attr "op_type" "RS")
584 (set_attr "atype" "reg")])
585
586 ; ltr, ltgr
587 (define_insn "*tst<mode>_cconly2"
588 [(set (reg CC_REGNUM)
589 (compare (match_operand:GPR 0 "register_operand" "d")
590 (match_operand:GPR 1 "const0_operand" "")))]
591 "s390_match_ccmode(insn, CCSmode)"
592 "lt<g>r\t%0,%0"
593 [(set_attr "op_type" "RR<E>")])
594
595 ; tst(hi|qi) instruction pattern(s).
596
597 (define_insn "*tst<mode>CCT"
598 [(set (reg CC_REGNUM)
599 (compare (match_operand:HQI 0 "nonimmediate_operand" "?Q,?S,d")
600 (match_operand:HQI 1 "const0_operand" "")))
601 (set (match_operand:HQI 2 "register_operand" "=d,d,0")
602 (match_dup 0))]
603 "s390_match_ccmode(insn, CCTmode)"
604 "@
605 icm\t%2,<icm_lo>,%S0
606 icmy\t%2,<icm_lo>,%S0
607 tml\t%0,<max_uint>"
608 [(set_attr "op_type" "RS,RSY,RI")])
609
610 (define_insn "*tsthiCCT_cconly"
611 [(set (reg CC_REGNUM)
612 (compare (match_operand:HI 0 "nonimmediate_operand" "Q,S,d")
613 (match_operand:HI 1 "const0_operand" "")))
614 (clobber (match_scratch:HI 2 "=d,d,X"))]
615 "s390_match_ccmode(insn, CCTmode)"
616 "@
617 icm\t%2,3,%S0
618 icmy\t%2,3,%S0
619 tml\t%0,65535"
620 [(set_attr "op_type" "RS,RSY,RI")])
621
622 (define_insn "*tstqiCCT_cconly"
623 [(set (reg CC_REGNUM)
624 (compare (match_operand:QI 0 "nonimmediate_operand" "?Q,?S,d")
625 (match_operand:QI 1 "const0_operand" "")))]
626 "s390_match_ccmode(insn, CCTmode)"
627 "@
628 cli\t%S0,0
629 cliy\t%S0,0
630 tml\t%0,255"
631 [(set_attr "op_type" "SI,SIY,RI")])
632
633 (define_insn "*tst<mode>"
634 [(set (reg CC_REGNUM)
635 (compare (match_operand:HQI 0 "s_operand" "Q,S")
636 (match_operand:HQI 1 "const0_operand" "")))
637 (set (match_operand:HQI 2 "register_operand" "=d,d")
638 (match_dup 0))]
639 "s390_match_ccmode(insn, CCSmode)"
640 "@
641 icm\t%2,<icm_lo>,%S0
642 icmy\t%2,<icm_lo>,%S0"
643 [(set_attr "op_type" "RS,RSY")])
644
645 (define_insn "*tst<mode>_cconly"
646 [(set (reg CC_REGNUM)
647 (compare (match_operand:HQI 0 "s_operand" "Q,S")
648 (match_operand:HQI 1 "const0_operand" "")))
649 (clobber (match_scratch:HQI 2 "=d,d"))]
650 "s390_match_ccmode(insn, CCSmode)"
651 "@
652 icm\t%2,<icm_lo>,%S0
653 icmy\t%2,<icm_lo>,%S0"
654 [(set_attr "op_type" "RS,RSY")])
655
656
657 ; Compare (equality) instructions
658
659 (define_insn "*cmpdi_cct"
660 [(set (reg CC_REGNUM)
661 (compare (match_operand:DI 0 "nonimmediate_operand" "%d,d,d,d,Q")
662 (match_operand:DI 1 "general_operand" "d,K,Os,m,BQ")))]
663 "s390_match_ccmode (insn, CCTmode) && TARGET_64BIT"
664 "@
665 cgr\t%0,%1
666 cghi\t%0,%h1
667 cgfi\t%0,%1
668 cg\t%0,%1
669 #"
670 [(set_attr "op_type" "RRE,RI,RIL,RXY,SS")])
671
672 (define_insn "*cmpsi_cct"
673 [(set (reg CC_REGNUM)
674 (compare (match_operand:SI 0 "nonimmediate_operand" "%d,d,d,d,d,Q")
675 (match_operand:SI 1 "general_operand" "d,K,Os,R,T,BQ")))]
676 "s390_match_ccmode (insn, CCTmode)"
677 "@
678 cr\t%0,%1
679 chi\t%0,%h1
680 cfi\t%0,%1
681 c\t%0,%1
682 cy\t%0,%1
683 #"
684 [(set_attr "op_type" "RR,RI,RIL,RX,RXY,SS")])
685
686
687 ; Compare (signed) instructions
688
689 (define_insn "*cmpdi_ccs_sign"
690 [(set (reg CC_REGNUM)
691 (compare (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "d,m"))
692 (match_operand:DI 0 "register_operand" "d,d")))]
693 "s390_match_ccmode(insn, CCSRmode) && TARGET_64BIT"
694 "@
695 cgfr\t%0,%1
696 cgf\t%0,%1"
697 [(set_attr "op_type" "RRE,RXY")])
698
699 (define_insn "*cmpsi_ccs_sign"
700 [(set (reg CC_REGNUM)
701 (compare (sign_extend:SI (match_operand:HI 1 "memory_operand" "R,T"))
702 (match_operand:SI 0 "register_operand" "d,d")))]
703 "s390_match_ccmode(insn, CCSRmode)"
704 "@
705 ch\t%0,%1
706 chy\t%0,%1"
707 [(set_attr "op_type" "RX,RXY")])
708
709 ; cr, chi, cfi, c, cy, cgr, cghi, cgfi, cg
710 (define_insn "*cmp<mode>_ccs"
711 [(set (reg CC_REGNUM)
712 (compare (match_operand:GPR 0 "register_operand" "d,d,d,d,d")
713 (match_operand:GPR 1 "general_operand" "d,K,Os,R,T")))]
714 "s390_match_ccmode(insn, CCSmode)"
715 "@
716 c<g>r\t%0,%1
717 c<g>hi\t%0,%h1
718 c<g>fi\t%0,%1
719 c<g>\t%0,%1
720 c<y>\t%0,%1"
721 [(set_attr "op_type" "RR<E>,RI,RIL,RX<Y>,RXY")])
722
723
724 ; Compare (unsigned) instructions
725
726 (define_insn "*cmpdi_ccu_zero"
727 [(set (reg CC_REGNUM)
728 (compare (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "d,m"))
729 (match_operand:DI 0 "register_operand" "d,d")))]
730 "s390_match_ccmode (insn, CCURmode) && TARGET_64BIT"
731 "@
732 clgfr\t%0,%1
733 clgf\t%0,%1"
734 [(set_attr "op_type" "RRE,RXY")])
735
736 (define_insn "*cmpdi_ccu"
737 [(set (reg CC_REGNUM)
738 (compare (match_operand:DI 0 "nonimmediate_operand" "d,d,d,Q,BQ")
739 (match_operand:DI 1 "general_operand" "d,Op,m,BQ,Q")))]
740 "s390_match_ccmode (insn, CCUmode) && TARGET_64BIT"
741 "@
742 clgr\t%0,%1
743 clgfi\t%0,%1
744 clg\t%0,%1
745 #
746 #"
747 [(set_attr "op_type" "RRE,RIL,RXY,SS,SS")])
748
749 (define_insn "*cmpsi_ccu"
750 [(set (reg CC_REGNUM)
751 (compare (match_operand:SI 0 "nonimmediate_operand" "d,d,d,d,Q,BQ")
752 (match_operand:SI 1 "general_operand" "d,Os,R,T,BQ,Q")))]
753 "s390_match_ccmode (insn, CCUmode)"
754 "@
755 clr\t%0,%1
756 clfi\t%0,%o1
757 cl\t%0,%1
758 cly\t%0,%1
759 #
760 #"
761 [(set_attr "op_type" "RR,RIL,RX,RXY,SS,SS")])
762
763 (define_insn "*cmphi_ccu"
764 [(set (reg CC_REGNUM)
765 (compare (match_operand:HI 0 "nonimmediate_operand" "d,d,Q,BQ")
766 (match_operand:HI 1 "general_operand" "Q,S,BQ,Q")))]
767 "s390_match_ccmode (insn, CCUmode)
768 && !register_operand (operands[1], HImode)"
769 "@
770 clm\t%0,3,%S1
771 clmy\t%0,3,%S1
772 #
773 #"
774 [(set_attr "op_type" "RS,RSY,SS,SS")])
775
776 (define_insn "*cmpqi_ccu"
777 [(set (reg CC_REGNUM)
778 (compare (match_operand:QI 0 "nonimmediate_operand" "d,d,Q,S,Q,BQ")
779 (match_operand:QI 1 "general_operand" "Q,S,n,n,BQ,Q")))]
780 "s390_match_ccmode (insn, CCUmode)
781 && !register_operand (operands[1], QImode)"
782 "@
783 clm\t%0,1,%S1
784 clmy\t%0,1,%S1
785 cli\t%S0,%b1
786 cliy\t%S0,%b1
787 #
788 #"
789 [(set_attr "op_type" "RS,RSY,SI,SIY,SS,SS")])
790
791
792 ; Block compare (CLC) instruction patterns.
793
794 (define_insn "*clc"
795 [(set (reg CC_REGNUM)
796 (compare (match_operand:BLK 0 "memory_operand" "Q")
797 (match_operand:BLK 1 "memory_operand" "Q")))
798 (use (match_operand 2 "const_int_operand" "n"))]
799 "s390_match_ccmode (insn, CCUmode)
800 && INTVAL (operands[2]) >= 1 && INTVAL (operands[2]) <= 256"
801 "clc\t%O0(%2,%R0),%S1"
802 [(set_attr "op_type" "SS")])
803
804 (define_split
805 [(set (reg CC_REGNUM)
806 (compare (match_operand 0 "memory_operand" "")
807 (match_operand 1 "memory_operand" "")))]
808 "reload_completed
809 && s390_match_ccmode (insn, CCUmode)
810 && GET_MODE (operands[0]) == GET_MODE (operands[1])
811 && GET_MODE_SIZE (GET_MODE (operands[0])) > 0"
812 [(parallel
813 [(set (match_dup 0) (match_dup 1))
814 (use (match_dup 2))])]
815 {
816 operands[2] = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[0])));
817 operands[0] = adjust_address (operands[0], BLKmode, 0);
818 operands[1] = adjust_address (operands[1], BLKmode, 0);
819
820 operands[1] = gen_rtx_COMPARE (GET_MODE (SET_DEST (PATTERN (curr_insn))),
821 operands[0], operands[1]);
822 operands[0] = SET_DEST (PATTERN (curr_insn));
823 })
824
825
826 ; (TF|DF|SF|TD|DD|SD) instructions
827
828 ; ltxbr, ltdbr, ltebr, ltxtr, ltdtr
829 (define_insn "*cmp<mode>_ccs_0"
830 [(set (reg CC_REGNUM)
831 (compare (match_operand:FP 0 "register_operand" "f")
832 (match_operand:FP 1 "const0_operand" "")))]
833 "s390_match_ccmode(insn, CCSmode) && TARGET_HARD_FLOAT"
834 "lt<xde><bt>r\t%0,%0"
835 [(set_attr "op_type" "RRE")
836 (set_attr "type" "fsimp<bfp>")])
837
838 ; cxtr, cxbr, cdbr, cebr, cxb, cdb, ceb, cxbtr, cdbtr
839 (define_insn "*cmp<mode>_ccs"
840 [(set (reg CC_REGNUM)
841 (compare (match_operand:FP 0 "register_operand" "f,f")
842 (match_operand:FP 1 "general_operand" "f,<Rf>")))]
843 "s390_match_ccmode(insn, CCSmode) && TARGET_HARD_FLOAT"
844 "@
845 c<xde><bt>r\t%0,%1
846 c<xde>b\t%0,%1"
847 [(set_attr "op_type" "RRE,RXE")
848 (set_attr "type" "fsimp<bfp>")])
849
850 ;;
851 ;;- Move instructions.
852 ;;
853
854 ;
855 ; movti instruction pattern(s).
856 ;
857
858 (define_insn "movti"
859 [(set (match_operand:TI 0 "nonimmediate_operand" "=d,QS,d,o,Q")
860 (match_operand:TI 1 "general_operand" "QS,d,dPm,d,Q"))]
861 "TARGET_64BIT"
862 "@
863 lmg\t%0,%N0,%S1
864 stmg\t%1,%N1,%S0
865 #
866 #
867 #"
868 [(set_attr "op_type" "RSY,RSY,*,*,SS")
869 (set_attr "type" "lm,stm,*,*,*")])
870
871 (define_split
872 [(set (match_operand:TI 0 "nonimmediate_operand" "")
873 (match_operand:TI 1 "general_operand" ""))]
874 "TARGET_64BIT && reload_completed
875 && s390_split_ok_p (operands[0], operands[1], TImode, 0)"
876 [(set (match_dup 2) (match_dup 4))
877 (set (match_dup 3) (match_dup 5))]
878 {
879 operands[2] = operand_subword (operands[0], 0, 0, TImode);
880 operands[3] = operand_subword (operands[0], 1, 0, TImode);
881 operands[4] = operand_subword (operands[1], 0, 0, TImode);
882 operands[5] = operand_subword (operands[1], 1, 0, TImode);
883 })
884
885 (define_split
886 [(set (match_operand:TI 0 "nonimmediate_operand" "")
887 (match_operand:TI 1 "general_operand" ""))]
888 "TARGET_64BIT && reload_completed
889 && s390_split_ok_p (operands[0], operands[1], TImode, 1)"
890 [(set (match_dup 2) (match_dup 4))
891 (set (match_dup 3) (match_dup 5))]
892 {
893 operands[2] = operand_subword (operands[0], 1, 0, TImode);
894 operands[3] = operand_subword (operands[0], 0, 0, TImode);
895 operands[4] = operand_subword (operands[1], 1, 0, TImode);
896 operands[5] = operand_subword (operands[1], 0, 0, TImode);
897 })
898
899 (define_split
900 [(set (match_operand:TI 0 "register_operand" "")
901 (match_operand:TI 1 "memory_operand" ""))]
902 "TARGET_64BIT && reload_completed
903 && !s_operand (operands[1], VOIDmode)"
904 [(set (match_dup 0) (match_dup 1))]
905 {
906 rtx addr = operand_subword (operands[0], 1, 0, TImode);
907 s390_load_address (addr, XEXP (operands[1], 0));
908 operands[1] = replace_equiv_address (operands[1], addr);
909 })
910
911
912 ;
913 ; Patterns used for secondary reloads
914 ;
915
916 ; Handles loading a PLUS (load address) expression
917
918 (define_expand "reload<mode>_plus"
919 [(parallel [(match_operand:P 0 "register_operand" "=a")
920 (match_operand:P 1 "s390_plus_operand" "")
921 (match_operand:P 2 "register_operand" "=&a")])]
922 ""
923 {
924 s390_expand_plus_operand (operands[0], operands[1], operands[2]);
925 DONE;
926 })
927
928 ; Handles assessing a non-offsetable memory address
929
930 (define_expand "reload<mode>_nonoffmem_in"
931 [(parallel [(match_operand 0 "register_operand" "")
932 (match_operand 1 "" "")
933 (match_operand:P 2 "register_operand" "=&a")])]
934 ""
935 {
936 gcc_assert (MEM_P (operands[1]));
937 s390_load_address (operands[2], find_replacement (&XEXP (operands[1], 0)));
938 operands[1] = replace_equiv_address (operands[1], operands[2]);
939 emit_move_insn (operands[0], operands[1]);
940 DONE;
941 })
942
943 (define_expand "reload<mode>_nonoffmem_out"
944 [(parallel [(match_operand 0 "" "")
945 (match_operand 1 "register_operand" "")
946 (match_operand:P 2 "register_operand" "=&a")])]
947 ""
948 {
949 gcc_assert (MEM_P (operands[0]));
950 s390_load_address (operands[2], find_replacement (&XEXP (operands[0], 0)));
951 operands[0] = replace_equiv_address (operands[0], operands[2]);
952 emit_move_insn (operands[0], operands[1]);
953 DONE;
954 })
955
956 ;
957 ; movdi instruction pattern(s).
958 ;
959
960 (define_expand "movdi"
961 [(set (match_operand:DI 0 "general_operand" "")
962 (match_operand:DI 1 "general_operand" ""))]
963 ""
964 {
965 /* Handle symbolic constants. */
966 if (TARGET_64BIT
967 && (SYMBOLIC_CONST (operands[1])
968 || (GET_CODE (operands[1]) == PLUS
969 && XEXP (operands[1], 0) == pic_offset_table_rtx
970 && SYMBOLIC_CONST (XEXP (operands[1], 1)))))
971 emit_symbolic_move (operands);
972 })
973
974 (define_insn "*movdi_larl"
975 [(set (match_operand:DI 0 "register_operand" "=d")
976 (match_operand:DI 1 "larl_operand" "X"))]
977 "TARGET_64BIT
978 && !FP_REG_P (operands[0])"
979 "larl\t%0,%1"
980 [(set_attr "op_type" "RIL")
981 (set_attr "type" "larl")])
982
983 (define_insn "*movdi_64dfp"
984 [(set (match_operand:DI 0 "nonimmediate_operand"
985 "=d,d,d,d,d,d,d,d,f,d,d,d,d,
986 m,!*f,!*f,!*f,!R,!T,d,t,Q,t,?Q")
987 (match_operand:DI 1 "general_operand"
988 "K,N0HD0,N1HD0,N2HD0,N3HD0,Os,N0SD0,N1SD0,d,f,L,d,m,
989 d,*f,R,T,*f,*f,t,d,t,Q,?Q"))]
990 "TARGET_64BIT && TARGET_DFP"
991 "@
992 lghi\t%0,%h1
993 llihh\t%0,%i1
994 llihl\t%0,%i1
995 llilh\t%0,%i1
996 llill\t%0,%i1
997 lgfi\t%0,%1
998 llihf\t%0,%k1
999 llilf\t%0,%k1
1000 ldgr\t%0,%1
1001 lgdr\t%0,%1
1002 lay\t%0,%a1
1003 lgr\t%0,%1
1004 lg\t%0,%1
1005 stg\t%1,%0
1006 ldr\t%0,%1
1007 ld\t%0,%1
1008 ldy\t%0,%1
1009 std\t%1,%0
1010 stdy\t%1,%0
1011 #
1012 #
1013 stam\t%1,%N1,%S0
1014 lam\t%0,%N0,%S1
1015 #"
1016 [(set_attr "op_type" "RI,RI,RI,RI,RI,RIL,RIL,RIL,RRE,RRE,RXY,RRE,RXY,RXY,
1017 RR,RX,RXY,RX,RXY,*,*,RS,RS,SS")
1018 (set_attr "type" "*,*,*,*,*,*,*,*,floaddf,floaddf,la,lr,load,store,
1019 floaddf,floaddf,floaddf,fstoredf,fstoredf,*,*,*,*,*")])
1020
1021 (define_insn "*movdi_64extimm"
1022 [(set (match_operand:DI 0 "nonimmediate_operand"
1023 "=d,d,d,d,d,d,d,d,d,d,d,m,!*f,!*f,!*f,!R,!T,d,t,Q,t,?Q")
1024 (match_operand:DI 1 "general_operand"
1025 "K,N0HD0,N1HD0,N2HD0,N3HD0,Os,N0SD0,N1SD0,L,d,m,d,*f,R,T,*f,*f,t,d,t,Q,?Q"))]
1026 "TARGET_64BIT && TARGET_EXTIMM"
1027 "@
1028 lghi\t%0,%h1
1029 llihh\t%0,%i1
1030 llihl\t%0,%i1
1031 llilh\t%0,%i1
1032 llill\t%0,%i1
1033 lgfi\t%0,%1
1034 llihf\t%0,%k1
1035 llilf\t%0,%k1
1036 lay\t%0,%a1
1037 lgr\t%0,%1
1038 lg\t%0,%1
1039 stg\t%1,%0
1040 ldr\t%0,%1
1041 ld\t%0,%1
1042 ldy\t%0,%1
1043 std\t%1,%0
1044 stdy\t%1,%0
1045 #
1046 #
1047 stam\t%1,%N1,%S0
1048 lam\t%0,%N0,%S1
1049 #"
1050 [(set_attr "op_type" "RI,RI,RI,RI,RI,RIL,RIL,RIL,RXY,RRE,RXY,RXY,
1051 RR,RX,RXY,RX,RXY,*,*,RS,RS,SS")
1052 (set_attr "type" "*,*,*,*,*,*,*,*,la,lr,load,store,
1053 floaddf,floaddf,floaddf,fstoredf,fstoredf,*,*,*,*,*")])
1054
1055 (define_insn "*movdi_64"
1056 [(set (match_operand:DI 0 "nonimmediate_operand"
1057 "=d,d,d,d,d,d,d,d,m,!*f,!*f,!*f,!R,!T,d,t,Q,t,?Q")
1058 (match_operand:DI 1 "general_operand"
1059 "K,N0HD0,N1HD0,N2HD0,N3HD0,L,d,m,d,*f,R,T,*f,*f,t,d,t,Q,?Q"))]
1060 "TARGET_64BIT && !TARGET_EXTIMM"
1061 "@
1062 lghi\t%0,%h1
1063 llihh\t%0,%i1
1064 llihl\t%0,%i1
1065 llilh\t%0,%i1
1066 llill\t%0,%i1
1067 lay\t%0,%a1
1068 lgr\t%0,%1
1069 lg\t%0,%1
1070 stg\t%1,%0
1071 ldr\t%0,%1
1072 ld\t%0,%1
1073 ldy\t%0,%1
1074 std\t%1,%0
1075 stdy\t%1,%0
1076 #
1077 #
1078 stam\t%1,%N1,%S0
1079 lam\t%0,%N0,%S1
1080 #"
1081 [(set_attr "op_type" "RI,RI,RI,RI,RI,RXY,RRE,RXY,RXY,
1082 RR,RX,RXY,RX,RXY,*,*,RS,RS,SS")
1083 (set_attr "type" "*,*,*,*,*,la,lr,load,store,
1084 floaddf,floaddf,floaddf,fstoredf,fstoredf,*,*,*,*,*")])
1085
1086 (define_split
1087 [(set (match_operand:DI 0 "register_operand" "")
1088 (match_operand:DI 1 "register_operand" ""))]
1089 "TARGET_64BIT && ACCESS_REG_P (operands[1])"
1090 [(set (match_dup 2) (match_dup 3))
1091 (set (match_dup 0) (ashift:DI (match_dup 0) (const_int 32)))
1092 (set (strict_low_part (match_dup 2)) (match_dup 4))]
1093 "operands[2] = gen_lowpart (SImode, operands[0]);
1094 s390_split_access_reg (operands[1], &operands[4], &operands[3]);")
1095
1096 (define_split
1097 [(set (match_operand:DI 0 "register_operand" "")
1098 (match_operand:DI 1 "register_operand" ""))]
1099 "TARGET_64BIT && ACCESS_REG_P (operands[0])
1100 && dead_or_set_p (insn, operands[1])"
1101 [(set (match_dup 3) (match_dup 2))
1102 (set (match_dup 1) (lshiftrt:DI (match_dup 1) (const_int 32)))
1103 (set (match_dup 4) (match_dup 2))]
1104 "operands[2] = gen_lowpart (SImode, operands[1]);
1105 s390_split_access_reg (operands[0], &operands[3], &operands[4]);")
1106
1107 (define_split
1108 [(set (match_operand:DI 0 "register_operand" "")
1109 (match_operand:DI 1 "register_operand" ""))]
1110 "TARGET_64BIT && ACCESS_REG_P (operands[0])
1111 && !dead_or_set_p (insn, operands[1])"
1112 [(set (match_dup 3) (match_dup 2))
1113 (set (match_dup 1) (rotate:DI (match_dup 1) (const_int 32)))
1114 (set (match_dup 4) (match_dup 2))
1115 (set (match_dup 1) (rotate:DI (match_dup 1) (const_int 32)))]
1116 "operands[2] = gen_lowpart (SImode, operands[1]);
1117 s390_split_access_reg (operands[0], &operands[3], &operands[4]);")
1118
1119 (define_insn "*movdi_31"
1120 [(set (match_operand:DI 0 "nonimmediate_operand" "=d,d,Q,S,d,o,!*f,!*f,!*f,!R,!T,Q")
1121 (match_operand:DI 1 "general_operand" "Q,S,d,d,dPm,d,*f,R,T,*f,*f,Q"))]
1122 "!TARGET_64BIT"
1123 "@
1124 lm\t%0,%N0,%S1
1125 lmy\t%0,%N0,%S1
1126 stm\t%1,%N1,%S0
1127 stmy\t%1,%N1,%S0
1128 #
1129 #
1130 ldr\t%0,%1
1131 ld\t%0,%1
1132 ldy\t%0,%1
1133 std\t%1,%0
1134 stdy\t%1,%0
1135 #"
1136 [(set_attr "op_type" "RS,RSY,RS,RSY,*,*,RR,RX,RXY,RX,RXY,SS")
1137 (set_attr "type" "lm,lm,stm,stm,*,*,floaddf,floaddf,floaddf,fstoredf,fstoredf,*")])
1138
1139 (define_split
1140 [(set (match_operand:DI 0 "nonimmediate_operand" "")
1141 (match_operand:DI 1 "general_operand" ""))]
1142 "!TARGET_64BIT && reload_completed
1143 && s390_split_ok_p (operands[0], operands[1], DImode, 0)"
1144 [(set (match_dup 2) (match_dup 4))
1145 (set (match_dup 3) (match_dup 5))]
1146 {
1147 operands[2] = operand_subword (operands[0], 0, 0, DImode);
1148 operands[3] = operand_subword (operands[0], 1, 0, DImode);
1149 operands[4] = operand_subword (operands[1], 0, 0, DImode);
1150 operands[5] = operand_subword (operands[1], 1, 0, DImode);
1151 })
1152
1153 (define_split
1154 [(set (match_operand:DI 0 "nonimmediate_operand" "")
1155 (match_operand:DI 1 "general_operand" ""))]
1156 "!TARGET_64BIT && reload_completed
1157 && s390_split_ok_p (operands[0], operands[1], DImode, 1)"
1158 [(set (match_dup 2) (match_dup 4))
1159 (set (match_dup 3) (match_dup 5))]
1160 {
1161 operands[2] = operand_subword (operands[0], 1, 0, DImode);
1162 operands[3] = operand_subword (operands[0], 0, 0, DImode);
1163 operands[4] = operand_subword (operands[1], 1, 0, DImode);
1164 operands[5] = operand_subword (operands[1], 0, 0, DImode);
1165 })
1166
1167 (define_split
1168 [(set (match_operand:DI 0 "register_operand" "")
1169 (match_operand:DI 1 "memory_operand" ""))]
1170 "!TARGET_64BIT && reload_completed
1171 && !FP_REG_P (operands[0])
1172 && !s_operand (operands[1], VOIDmode)"
1173 [(set (match_dup 0) (match_dup 1))]
1174 {
1175 rtx addr = operand_subword (operands[0], 1, 0, DImode);
1176 s390_load_address (addr, XEXP (operands[1], 0));
1177 operands[1] = replace_equiv_address (operands[1], addr);
1178 })
1179
1180 (define_peephole2
1181 [(set (match_operand:DI 0 "register_operand" "")
1182 (mem:DI (match_operand 1 "address_operand" "")))]
1183 "TARGET_64BIT
1184 && !FP_REG_P (operands[0])
1185 && GET_CODE (operands[1]) == SYMBOL_REF
1186 && CONSTANT_POOL_ADDRESS_P (operands[1])
1187 && get_pool_mode (operands[1]) == DImode
1188 && legitimate_reload_constant_p (get_pool_constant (operands[1]))"
1189 [(set (match_dup 0) (match_dup 2))]
1190 "operands[2] = get_pool_constant (operands[1]);")
1191
1192 (define_insn "*la_64"
1193 [(set (match_operand:DI 0 "register_operand" "=d,d")
1194 (match_operand:QI 1 "address_operand" "U,W"))]
1195 "TARGET_64BIT"
1196 "@
1197 la\t%0,%a1
1198 lay\t%0,%a1"
1199 [(set_attr "op_type" "RX,RXY")
1200 (set_attr "type" "la")])
1201
1202 (define_peephole2
1203 [(parallel
1204 [(set (match_operand:DI 0 "register_operand" "")
1205 (match_operand:QI 1 "address_operand" ""))
1206 (clobber (reg:CC CC_REGNUM))])]
1207 "TARGET_64BIT
1208 && preferred_la_operand_p (operands[1], const0_rtx)"
1209 [(set (match_dup 0) (match_dup 1))]
1210 "")
1211
1212 (define_peephole2
1213 [(set (match_operand:DI 0 "register_operand" "")
1214 (match_operand:DI 1 "register_operand" ""))
1215 (parallel
1216 [(set (match_dup 0)
1217 (plus:DI (match_dup 0)
1218 (match_operand:DI 2 "nonmemory_operand" "")))
1219 (clobber (reg:CC CC_REGNUM))])]
1220 "TARGET_64BIT
1221 && !reg_overlap_mentioned_p (operands[0], operands[2])
1222 && preferred_la_operand_p (operands[1], operands[2])"
1223 [(set (match_dup 0) (plus:DI (match_dup 1) (match_dup 2)))]
1224 "")
1225
1226 ;
1227 ; movsi instruction pattern(s).
1228 ;
1229
1230 (define_expand "movsi"
1231 [(set (match_operand:SI 0 "general_operand" "")
1232 (match_operand:SI 1 "general_operand" ""))]
1233 ""
1234 {
1235 /* Handle symbolic constants. */
1236 if (!TARGET_64BIT
1237 && (SYMBOLIC_CONST (operands[1])
1238 || (GET_CODE (operands[1]) == PLUS
1239 && XEXP (operands[1], 0) == pic_offset_table_rtx
1240 && SYMBOLIC_CONST (XEXP(operands[1], 1)))))
1241 emit_symbolic_move (operands);
1242 })
1243
1244 (define_insn "*movsi_larl"
1245 [(set (match_operand:SI 0 "register_operand" "=d")
1246 (match_operand:SI 1 "larl_operand" "X"))]
1247 "!TARGET_64BIT && TARGET_CPU_ZARCH
1248 && !FP_REG_P (operands[0])"
1249 "larl\t%0,%1"
1250 [(set_attr "op_type" "RIL")
1251 (set_attr "type" "larl")])
1252
1253 (define_insn "*movsi_zarch"
1254 [(set (match_operand:SI 0 "nonimmediate_operand"
1255 "=d,d,d,d,d,d,d,d,R,T,!*f,!*f,!*f,!R,!T,d,t,Q,t,?Q")
1256 (match_operand:SI 1 "general_operand"
1257 "K,N0HS0,N1HS0,Os,L,d,R,T,d,d,*f,R,T,*f,*f,t,d,t,Q,?Q"))]
1258 "TARGET_ZARCH"
1259 "@
1260 lhi\t%0,%h1
1261 llilh\t%0,%i1
1262 llill\t%0,%i1
1263 iilf\t%0,%o1
1264 lay\t%0,%a1
1265 lr\t%0,%1
1266 l\t%0,%1
1267 ly\t%0,%1
1268 st\t%1,%0
1269 sty\t%1,%0
1270 ler\t%0,%1
1271 le\t%0,%1
1272 ley\t%0,%1
1273 ste\t%1,%0
1274 stey\t%1,%0
1275 ear\t%0,%1
1276 sar\t%0,%1
1277 stam\t%1,%1,%S0
1278 lam\t%0,%0,%S1
1279 #"
1280 [(set_attr "op_type" "RI,RI,RI,RIL,RXY,RR,RX,RXY,RX,RXY,
1281 RR,RX,RXY,RX,RXY,RRE,RRE,RS,RS,SS")
1282 (set_attr "type" "*,*,*,*,la,lr,load,load,store,store,
1283 floadsf,floadsf,floadsf,fstoresf,fstoresf,*,*,*,*,*")])
1284
1285 (define_insn "*movsi_esa"
1286 [(set (match_operand:SI 0 "nonimmediate_operand" "=d,d,d,R,!*f,!*f,!R,d,t,Q,t,?Q")
1287 (match_operand:SI 1 "general_operand" "K,d,R,d,*f,R,*f,t,d,t,Q,?Q"))]
1288 "!TARGET_ZARCH"
1289 "@
1290 lhi\t%0,%h1
1291 lr\t%0,%1
1292 l\t%0,%1
1293 st\t%1,%0
1294 ler\t%0,%1
1295 le\t%0,%1
1296 ste\t%1,%0
1297 ear\t%0,%1
1298 sar\t%0,%1
1299 stam\t%1,%1,%S0
1300 lam\t%0,%0,%S1
1301 #"
1302 [(set_attr "op_type" "RI,RR,RX,RX,RR,RX,RX,RRE,RRE,RS,RS,SS")
1303 (set_attr "type" "*,lr,load,store,floadsf,floadsf,fstoresf,*,*,*,*,*")])
1304
1305 (define_peephole2
1306 [(set (match_operand:SI 0 "register_operand" "")
1307 (mem:SI (match_operand 1 "address_operand" "")))]
1308 "!FP_REG_P (operands[0])
1309 && GET_CODE (operands[1]) == SYMBOL_REF
1310 && CONSTANT_POOL_ADDRESS_P (operands[1])
1311 && get_pool_mode (operands[1]) == SImode
1312 && legitimate_reload_constant_p (get_pool_constant (operands[1]))"
1313 [(set (match_dup 0) (match_dup 2))]
1314 "operands[2] = get_pool_constant (operands[1]);")
1315
1316 (define_insn "*la_31"
1317 [(set (match_operand:SI 0 "register_operand" "=d,d")
1318 (match_operand:QI 1 "address_operand" "U,W"))]
1319 "!TARGET_64BIT && legitimate_la_operand_p (operands[1])"
1320 "@
1321 la\t%0,%a1
1322 lay\t%0,%a1"
1323 [(set_attr "op_type" "RX,RXY")
1324 (set_attr "type" "la")])
1325
1326 (define_peephole2
1327 [(parallel
1328 [(set (match_operand:SI 0 "register_operand" "")
1329 (match_operand:QI 1 "address_operand" ""))
1330 (clobber (reg:CC CC_REGNUM))])]
1331 "!TARGET_64BIT
1332 && preferred_la_operand_p (operands[1], const0_rtx)"
1333 [(set (match_dup 0) (match_dup 1))]
1334 "")
1335
1336 (define_peephole2
1337 [(set (match_operand:SI 0 "register_operand" "")
1338 (match_operand:SI 1 "register_operand" ""))
1339 (parallel
1340 [(set (match_dup 0)
1341 (plus:SI (match_dup 0)
1342 (match_operand:SI 2 "nonmemory_operand" "")))
1343 (clobber (reg:CC CC_REGNUM))])]
1344 "!TARGET_64BIT
1345 && !reg_overlap_mentioned_p (operands[0], operands[2])
1346 && preferred_la_operand_p (operands[1], operands[2])"
1347 [(set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))]
1348 "")
1349
1350 (define_insn "*la_31_and"
1351 [(set (match_operand:SI 0 "register_operand" "=d,d")
1352 (and:SI (match_operand:QI 1 "address_operand" "U,W")
1353 (const_int 2147483647)))]
1354 "!TARGET_64BIT"
1355 "@
1356 la\t%0,%a1
1357 lay\t%0,%a1"
1358 [(set_attr "op_type" "RX,RXY")
1359 (set_attr "type" "la")])
1360
1361 (define_insn_and_split "*la_31_and_cc"
1362 [(set (match_operand:SI 0 "register_operand" "=d")
1363 (and:SI (match_operand:QI 1 "address_operand" "p")
1364 (const_int 2147483647)))
1365 (clobber (reg:CC CC_REGNUM))]
1366 "!TARGET_64BIT"
1367 "#"
1368 "&& reload_completed"
1369 [(set (match_dup 0)
1370 (and:SI (match_dup 1) (const_int 2147483647)))]
1371 ""
1372 [(set_attr "op_type" "RX")
1373 (set_attr "type" "la")])
1374
1375 (define_insn "force_la_31"
1376 [(set (match_operand:SI 0 "register_operand" "=d,d")
1377 (match_operand:QI 1 "address_operand" "U,W"))
1378 (use (const_int 0))]
1379 "!TARGET_64BIT"
1380 "@
1381 la\t%0,%a1
1382 lay\t%0,%a1"
1383 [(set_attr "op_type" "RX")
1384 (set_attr "type" "la")])
1385
1386 ;
1387 ; movhi instruction pattern(s).
1388 ;
1389
1390 (define_expand "movhi"
1391 [(set (match_operand:HI 0 "nonimmediate_operand" "")
1392 (match_operand:HI 1 "general_operand" ""))]
1393 ""
1394 {
1395 /* Make it explicit that loading a register from memory
1396 always sign-extends (at least) to SImode. */
1397 if (optimize && !no_new_pseudos
1398 && register_operand (operands[0], VOIDmode)
1399 && GET_CODE (operands[1]) == MEM)
1400 {
1401 rtx tmp = gen_reg_rtx (SImode);
1402 rtx ext = gen_rtx_SIGN_EXTEND (SImode, operands[1]);
1403 emit_insn (gen_rtx_SET (VOIDmode, tmp, ext));
1404 operands[1] = gen_lowpart (HImode, tmp);
1405 }
1406 })
1407
1408 (define_insn "*movhi"
1409 [(set (match_operand:HI 0 "nonimmediate_operand" "=d,d,d,d,R,T,?Q")
1410 (match_operand:HI 1 "general_operand" "d,n,R,T,d,d,?Q"))]
1411 ""
1412 "@
1413 lr\t%0,%1
1414 lhi\t%0,%h1
1415 lh\t%0,%1
1416 lhy\t%0,%1
1417 sth\t%1,%0
1418 sthy\t%1,%0
1419 #"
1420 [(set_attr "op_type" "RR,RI,RX,RXY,RX,RXY,SS")
1421 (set_attr "type" "lr,*,*,*,store,store,*")])
1422
1423 (define_peephole2
1424 [(set (match_operand:HI 0 "register_operand" "")
1425 (mem:HI (match_operand 1 "address_operand" "")))]
1426 "GET_CODE (operands[1]) == SYMBOL_REF
1427 && CONSTANT_POOL_ADDRESS_P (operands[1])
1428 && get_pool_mode (operands[1]) == HImode
1429 && GET_CODE (get_pool_constant (operands[1])) == CONST_INT"
1430 [(set (match_dup 0) (match_dup 2))]
1431 "operands[2] = get_pool_constant (operands[1]);")
1432
1433 ;
1434 ; movqi instruction pattern(s).
1435 ;
1436
1437 (define_expand "movqi"
1438 [(set (match_operand:QI 0 "nonimmediate_operand" "")
1439 (match_operand:QI 1 "general_operand" ""))]
1440 ""
1441 {
1442 /* On z/Architecture, zero-extending from memory to register
1443 is just as fast as a QImode load. */
1444 if (TARGET_ZARCH && optimize && !no_new_pseudos
1445 && register_operand (operands[0], VOIDmode)
1446 && GET_CODE (operands[1]) == MEM)
1447 {
1448 rtx tmp = gen_reg_rtx (word_mode);
1449 rtx ext = gen_rtx_ZERO_EXTEND (word_mode, operands[1]);
1450 emit_insn (gen_rtx_SET (VOIDmode, tmp, ext));
1451 operands[1] = gen_lowpart (QImode, tmp);
1452 }
1453 })
1454
1455 (define_insn "*movqi"
1456 [(set (match_operand:QI 0 "nonimmediate_operand" "=d,d,d,d,R,T,Q,S,?Q")
1457 (match_operand:QI 1 "general_operand" "d,n,R,T,d,d,n,n,?Q"))]
1458 ""
1459 "@
1460 lr\t%0,%1
1461 lhi\t%0,%b1
1462 ic\t%0,%1
1463 icy\t%0,%1
1464 stc\t%1,%0
1465 stcy\t%1,%0
1466 mvi\t%S0,%b1
1467 mviy\t%S0,%b1
1468 #"
1469 [(set_attr "op_type" "RR,RI,RX,RXY,RX,RXY,SI,SIY,SS")
1470 (set_attr "type" "lr,*,*,*,store,store,store,store,*")])
1471
1472 (define_peephole2
1473 [(set (match_operand:QI 0 "nonimmediate_operand" "")
1474 (mem:QI (match_operand 1 "address_operand" "")))]
1475 "GET_CODE (operands[1]) == SYMBOL_REF
1476 && CONSTANT_POOL_ADDRESS_P (operands[1])
1477 && get_pool_mode (operands[1]) == QImode
1478 && GET_CODE (get_pool_constant (operands[1])) == CONST_INT"
1479 [(set (match_dup 0) (match_dup 2))]
1480 "operands[2] = get_pool_constant (operands[1]);")
1481
1482 ;
1483 ; movstrictqi instruction pattern(s).
1484 ;
1485
1486 (define_insn "*movstrictqi"
1487 [(set (strict_low_part (match_operand:QI 0 "register_operand" "+d,d"))
1488 (match_operand:QI 1 "memory_operand" "R,T"))]
1489 ""
1490 "@
1491 ic\t%0,%1
1492 icy\t%0,%1"
1493 [(set_attr "op_type" "RX,RXY")])
1494
1495 ;
1496 ; movstricthi instruction pattern(s).
1497 ;
1498
1499 (define_insn "*movstricthi"
1500 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+d,d"))
1501 (match_operand:HI 1 "memory_operand" "Q,S"))
1502 (clobber (reg:CC CC_REGNUM))]
1503 ""
1504 "@
1505 icm\t%0,3,%S1
1506 icmy\t%0,3,%S1"
1507 [(set_attr "op_type" "RS,RSY")])
1508
1509 ;
1510 ; movstrictsi instruction pattern(s).
1511 ;
1512
1513 (define_insn "movstrictsi"
1514 [(set (strict_low_part (match_operand:SI 0 "register_operand" "+d,d,d,d"))
1515 (match_operand:SI 1 "general_operand" "d,R,T,t"))]
1516 "TARGET_64BIT"
1517 "@
1518 lr\t%0,%1
1519 l\t%0,%1
1520 ly\t%0,%1
1521 ear\t%0,%1"
1522 [(set_attr "op_type" "RR,RX,RXY,RRE")
1523 (set_attr "type" "lr,load,load,*")])
1524
1525 ;
1526 ; mov(tf|td) instruction pattern(s).
1527 ;
1528
1529 (define_expand "mov<mode>"
1530 [(set (match_operand:TD_TF 0 "nonimmediate_operand" "")
1531 (match_operand:TD_TF 1 "general_operand" ""))]
1532 ""
1533 "")
1534
1535 (define_insn "*mov<mode>_64"
1536 [(set (match_operand:TD_TF 0 "nonimmediate_operand" "=f,f,f,o, d,QS, d,o,Q")
1537 (match_operand:TD_TF 1 "general_operand" " G,f,o,f,QS, d,dm,d,Q"))]
1538 "TARGET_64BIT"
1539 "@
1540 lzxr\t%0
1541 lxr\t%0,%1
1542 #
1543 #
1544 lmg\t%0,%N0,%S1
1545 stmg\t%1,%N1,%S0
1546 #
1547 #
1548 #"
1549 [(set_attr "op_type" "RRE,RRE,*,*,RSY,RSY,*,*,*")
1550 (set_attr "type" "fsimptf,fsimptf,*,*,lm,stm,*,*,*")])
1551
1552 (define_insn "*mov<mode>_31"
1553 [(set (match_operand:TD_TF 0 "nonimmediate_operand" "=f,f,f,o,Q")
1554 (match_operand:TD_TF 1 "general_operand" " G,f,o,f,Q"))]
1555 "!TARGET_64BIT"
1556 "@
1557 lzxr\t%0
1558 lxr\t%0,%1
1559 #
1560 #
1561 #"
1562 [(set_attr "op_type" "RRE,RRE,*,*,*")
1563 (set_attr "type" "fsimptf,fsimptf,*,*,*")])
1564
1565 ; TFmode in GPRs splitters
1566
1567 (define_split
1568 [(set (match_operand:TD_TF 0 "nonimmediate_operand" "")
1569 (match_operand:TD_TF 1 "general_operand" ""))]
1570 "TARGET_64BIT && reload_completed
1571 && s390_split_ok_p (operands[0], operands[1], <MODE>mode, 0)"
1572 [(set (match_dup 2) (match_dup 4))
1573 (set (match_dup 3) (match_dup 5))]
1574 {
1575 operands[2] = operand_subword (operands[0], 0, 0, <MODE>mode);
1576 operands[3] = operand_subword (operands[0], 1, 0, <MODE>mode);
1577 operands[4] = operand_subword (operands[1], 0, 0, <MODE>mode);
1578 operands[5] = operand_subword (operands[1], 1, 0, <MODE>mode);
1579 })
1580
1581 (define_split
1582 [(set (match_operand:TD_TF 0 "nonimmediate_operand" "")
1583 (match_operand:TD_TF 1 "general_operand" ""))]
1584 "TARGET_64BIT && reload_completed
1585 && s390_split_ok_p (operands[0], operands[1], <MODE>mode, 1)"
1586 [(set (match_dup 2) (match_dup 4))
1587 (set (match_dup 3) (match_dup 5))]
1588 {
1589 operands[2] = operand_subword (operands[0], 1, 0, <MODE>mode);
1590 operands[3] = operand_subword (operands[0], 0, 0, <MODE>mode);
1591 operands[4] = operand_subword (operands[1], 1, 0, <MODE>mode);
1592 operands[5] = operand_subword (operands[1], 0, 0, <MODE>mode);
1593 })
1594
1595 (define_split
1596 [(set (match_operand:TD_TF 0 "register_operand" "")
1597 (match_operand:TD_TF 1 "memory_operand" ""))]
1598 "TARGET_64BIT && reload_completed
1599 && !FP_REG_P (operands[0])
1600 && !s_operand (operands[1], VOIDmode)"
1601 [(set (match_dup 0) (match_dup 1))]
1602 {
1603 rtx addr = operand_subword (operands[0], 1, 0, <MODE>mode);
1604 s390_load_address (addr, XEXP (operands[1], 0));
1605 operands[1] = replace_equiv_address (operands[1], addr);
1606 })
1607
1608 ; TFmode in BFPs splitters
1609
1610 (define_split
1611 [(set (match_operand:TD_TF 0 "register_operand" "")
1612 (match_operand:TD_TF 1 "memory_operand" ""))]
1613 "reload_completed && offsettable_memref_p (operands[1])
1614 && FP_REG_P (operands[0])"
1615 [(set (match_dup 2) (match_dup 4))
1616 (set (match_dup 3) (match_dup 5))]
1617 {
1618 operands[2] = simplify_gen_subreg (<HALF_TMODE>mode, operands[0],
1619 <MODE>mode, 0);
1620 operands[3] = simplify_gen_subreg (<HALF_TMODE>mode, operands[0],
1621 <MODE>mode, 8);
1622 operands[4] = adjust_address_nv (operands[1], <HALF_TMODE>mode, 0);
1623 operands[5] = adjust_address_nv (operands[1], <HALF_TMODE>mode, 8);
1624 })
1625
1626 (define_split
1627 [(set (match_operand:TD_TF 0 "memory_operand" "")
1628 (match_operand:TD_TF 1 "register_operand" ""))]
1629 "reload_completed && offsettable_memref_p (operands[0])
1630 && FP_REG_P (operands[1])"
1631 [(set (match_dup 2) (match_dup 4))
1632 (set (match_dup 3) (match_dup 5))]
1633 {
1634 operands[2] = adjust_address_nv (operands[0], <HALF_TMODE>mode, 0);
1635 operands[3] = adjust_address_nv (operands[0], <HALF_TMODE>mode, 8);
1636 operands[4] = simplify_gen_subreg (<HALF_TMODE>mode, operands[1],
1637 <MODE>mode, 0);
1638 operands[5] = simplify_gen_subreg (<HALF_TMODE>mode, operands[1],
1639 <MODE>mode, 8);
1640 })
1641
1642 ;
1643 ; mov(df|dd) instruction pattern(s).
1644 ;
1645
1646 (define_expand "mov<mode>"
1647 [(set (match_operand:DD_DF 0 "nonimmediate_operand" "")
1648 (match_operand:DD_DF 1 "general_operand" ""))]
1649 ""
1650 "")
1651
1652 (define_insn "*mov<mode>_64dfp"
1653 [(set (match_operand:DD_DF 0 "nonimmediate_operand"
1654 "=f,f,f,d,f,f,R,T,d,d,m,?Q")
1655 (match_operand:DD_DF 1 "general_operand"
1656 "G,f,d,f,R,T,f,f,d,m,d,?Q"))]
1657 "TARGET_64BIT && TARGET_DFP"
1658 "@
1659 lzdr\t%0
1660 ldr\t%0,%1
1661 ldgr\t%0,%1
1662 lgdr\t%0,%1
1663 ld\t%0,%1
1664 ldy\t%0,%1
1665 std\t%1,%0
1666 stdy\t%1,%0
1667 lgr\t%0,%1
1668 lg\t%0,%1
1669 stg\t%1,%0
1670 #"
1671 [(set_attr "op_type" "RRE,RR,RRE,RRE,RX,RXY,RX,RXY,RRE,RXY,RXY,SS")
1672 (set_attr "type" "fsimpdf,floaddf,floaddf,floaddf,floaddf,floaddf,
1673 fstoredf,fstoredf,lr,load,store,*")])
1674
1675 (define_insn "*mov<mode>_64"
1676 [(set (match_operand:DD_DF 0 "nonimmediate_operand" "=f,f,f,f,R,T,d,d,m,?Q")
1677 (match_operand:DD_DF 1 "general_operand" "G,f,R,T,f,f,d,m,d,?Q"))]
1678 "TARGET_64BIT"
1679 "@
1680 lzdr\t%0
1681 ldr\t%0,%1
1682 ld\t%0,%1
1683 ldy\t%0,%1
1684 std\t%1,%0
1685 stdy\t%1,%0
1686 lgr\t%0,%1
1687 lg\t%0,%1
1688 stg\t%1,%0
1689 #"
1690 [(set_attr "op_type" "RRE,RR,RX,RXY,RX,RXY,RRE,RXY,RXY,SS")
1691 (set_attr "type" "fsimp<bfp>,fload<bfp>,fload<bfp>,fload<bfp>,
1692 fstore<bfp>,fstore<bfp>,lr,load,store,*")])
1693
1694 (define_insn "*mov<mode>_31"
1695 [(set (match_operand:DD_DF 0 "nonimmediate_operand"
1696 "=f,f,f,f,R,T,d,d,Q,S, d,o,Q")
1697 (match_operand:DD_DF 1 "general_operand"
1698 " G,f,R,T,f,f,Q,S,d,d,dPm,d,Q"))]
1699 "!TARGET_64BIT"
1700 "@
1701 lzdr\t%0
1702 ldr\t%0,%1
1703 ld\t%0,%1
1704 ldy\t%0,%1
1705 std\t%1,%0
1706 stdy\t%1,%0
1707 lm\t%0,%N0,%S1
1708 lmy\t%0,%N0,%S1
1709 stm\t%1,%N1,%S0
1710 stmy\t%1,%N1,%S0
1711 #
1712 #
1713 #"
1714 [(set_attr "op_type" "RRE,RR,RX,RXY,RX,RXY,RS,RSY,RS,RSY,*,*,SS")
1715 (set_attr "type" "fsimp<bfp>,fload<bfp>,fload<bfp>,fload<bfp>,
1716 fstore<bfp>,fstore<bfp>,lm,lm,stm,stm,*,*,*")])
1717
1718 (define_split
1719 [(set (match_operand:DD_DF 0 "nonimmediate_operand" "")
1720 (match_operand:DD_DF 1 "general_operand" ""))]
1721 "!TARGET_64BIT && reload_completed
1722 && s390_split_ok_p (operands[0], operands[1], <MODE>mode, 0)"
1723 [(set (match_dup 2) (match_dup 4))
1724 (set (match_dup 3) (match_dup 5))]
1725 {
1726 operands[2] = operand_subword (operands[0], 0, 0, <MODE>mode);
1727 operands[3] = operand_subword (operands[0], 1, 0, <MODE>mode);
1728 operands[4] = operand_subword (operands[1], 0, 0, <MODE>mode);
1729 operands[5] = operand_subword (operands[1], 1, 0, <MODE>mode);
1730 })
1731
1732 (define_split
1733 [(set (match_operand:DD_DF 0 "nonimmediate_operand" "")
1734 (match_operand:DD_DF 1 "general_operand" ""))]
1735 "!TARGET_64BIT && reload_completed
1736 && s390_split_ok_p (operands[0], operands[1], <MODE>mode, 1)"
1737 [(set (match_dup 2) (match_dup 4))
1738 (set (match_dup 3) (match_dup 5))]
1739 {
1740 operands[2] = operand_subword (operands[0], 1, 0, <MODE>mode);
1741 operands[3] = operand_subword (operands[0], 0, 0, <MODE>mode);
1742 operands[4] = operand_subword (operands[1], 1, 0, <MODE>mode);
1743 operands[5] = operand_subword (operands[1], 0, 0, <MODE>mode);
1744 })
1745
1746 (define_split
1747 [(set (match_operand:DD_DF 0 "register_operand" "")
1748 (match_operand:DD_DF 1 "memory_operand" ""))]
1749 "!TARGET_64BIT && reload_completed
1750 && !FP_REG_P (operands[0])
1751 && !s_operand (operands[1], VOIDmode)"
1752 [(set (match_dup 0) (match_dup 1))]
1753 {
1754 rtx addr = operand_subword (operands[0], 1, 0, <MODE>mode);
1755 s390_load_address (addr, XEXP (operands[1], 0));
1756 operands[1] = replace_equiv_address (operands[1], addr);
1757 })
1758
1759 ;
1760 ; mov(sf|sd) instruction pattern(s).
1761 ;
1762
1763 (define_insn "mov<mode>"
1764 [(set (match_operand:SD_SF 0 "nonimmediate_operand"
1765 "=f,f,f,f,R,T,d,d,d,R,T,?Q")
1766 (match_operand:SD_SF 1 "general_operand"
1767 " G,f,R,T,f,f,d,R,T,d,d,?Q"))]
1768 ""
1769 "@
1770 lzer\t%0
1771 ler\t%0,%1
1772 le\t%0,%1
1773 ley\t%0,%1
1774 ste\t%1,%0
1775 stey\t%1,%0
1776 lr\t%0,%1
1777 l\t%0,%1
1778 ly\t%0,%1
1779 st\t%1,%0
1780 sty\t%1,%0
1781 #"
1782 [(set_attr "op_type" "RRE,RR,RX,RXY,RX,RXY,RR,RX,RXY,RX,RXY,SS")
1783 (set_attr "type" "fsimp<bfp>,fload<bfp>,fload<bfp>,fload<bfp>,
1784 fstore<bfp>,fstore<bfp>,lr,load,load,store,store,*")])
1785
1786 ;
1787 ; movcc instruction pattern
1788 ;
1789
1790 (define_insn "movcc"
1791 [(set (match_operand:CC 0 "nonimmediate_operand" "=d,c,d,d,d,R,T")
1792 (match_operand:CC 1 "nonimmediate_operand" "d,d,c,R,T,d,d"))]
1793 ""
1794 "@
1795 lr\t%0,%1
1796 tmh\t%1,12288
1797 ipm\t%0
1798 st\t%0,%1
1799 sty\t%0,%1
1800 l\t%1,%0
1801 ly\t%1,%0"
1802 [(set_attr "op_type" "RR,RI,RRE,RX,RXY,RX,RXY")
1803 (set_attr "type" "lr,*,*,store,store,load,load")])
1804
1805 ;
1806 ; Block move (MVC) patterns.
1807 ;
1808
1809 (define_insn "*mvc"
1810 [(set (match_operand:BLK 0 "memory_operand" "=Q")
1811 (match_operand:BLK 1 "memory_operand" "Q"))
1812 (use (match_operand 2 "const_int_operand" "n"))]
1813 "INTVAL (operands[2]) >= 1 && INTVAL (operands[2]) <= 256"
1814 "mvc\t%O0(%2,%R0),%S1"
1815 [(set_attr "op_type" "SS")])
1816
1817 (define_split
1818 [(set (match_operand 0 "memory_operand" "")
1819 (match_operand 1 "memory_operand" ""))]
1820 "reload_completed
1821 && GET_MODE (operands[0]) == GET_MODE (operands[1])
1822 && GET_MODE_SIZE (GET_MODE (operands[0])) > 0"
1823 [(parallel
1824 [(set (match_dup 0) (match_dup 1))
1825 (use (match_dup 2))])]
1826 {
1827 operands[2] = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[0])));
1828 operands[0] = adjust_address (operands[0], BLKmode, 0);
1829 operands[1] = adjust_address (operands[1], BLKmode, 0);
1830 })
1831
1832 (define_peephole2
1833 [(parallel
1834 [(set (match_operand:BLK 0 "memory_operand" "")
1835 (match_operand:BLK 1 "memory_operand" ""))
1836 (use (match_operand 2 "const_int_operand" ""))])
1837 (parallel
1838 [(set (match_operand:BLK 3 "memory_operand" "")
1839 (match_operand:BLK 4 "memory_operand" ""))
1840 (use (match_operand 5 "const_int_operand" ""))])]
1841 "s390_offset_p (operands[0], operands[3], operands[2])
1842 && s390_offset_p (operands[1], operands[4], operands[2])
1843 && !s390_overlap_p (operands[0], operands[1],
1844 INTVAL (operands[2]) + INTVAL (operands[5]))
1845 && INTVAL (operands[2]) + INTVAL (operands[5]) <= 256"
1846 [(parallel
1847 [(set (match_dup 6) (match_dup 7))
1848 (use (match_dup 8))])]
1849 "operands[6] = gen_rtx_MEM (BLKmode, XEXP (operands[0], 0));
1850 operands[7] = gen_rtx_MEM (BLKmode, XEXP (operands[1], 0));
1851 operands[8] = GEN_INT (INTVAL (operands[2]) + INTVAL (operands[5]));")
1852
1853
1854 ;
1855 ; load_multiple pattern(s).
1856 ;
1857 ; ??? Due to reload problems with replacing registers inside match_parallel
1858 ; we currently support load_multiple/store_multiple only after reload.
1859 ;
1860
1861 (define_expand "load_multiple"
1862 [(match_par_dup 3 [(set (match_operand 0 "" "")
1863 (match_operand 1 "" ""))
1864 (use (match_operand 2 "" ""))])]
1865 "reload_completed"
1866 {
1867 enum machine_mode mode;
1868 int regno;
1869 int count;
1870 rtx from;
1871 int i, off;
1872
1873 /* Support only loading a constant number of fixed-point registers from
1874 memory and only bother with this if more than two */
1875 if (GET_CODE (operands[2]) != CONST_INT
1876 || INTVAL (operands[2]) < 2
1877 || INTVAL (operands[2]) > 16
1878 || GET_CODE (operands[1]) != MEM
1879 || GET_CODE (operands[0]) != REG
1880 || REGNO (operands[0]) >= 16)
1881 FAIL;
1882
1883 count = INTVAL (operands[2]);
1884 regno = REGNO (operands[0]);
1885 mode = GET_MODE (operands[0]);
1886 if (mode != SImode && mode != word_mode)
1887 FAIL;
1888
1889 operands[3] = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (count));
1890 if (no_new_pseudos)
1891 {
1892 if (GET_CODE (XEXP (operands[1], 0)) == REG)
1893 {
1894 from = XEXP (operands[1], 0);
1895 off = 0;
1896 }
1897 else if (GET_CODE (XEXP (operands[1], 0)) == PLUS
1898 && GET_CODE (XEXP (XEXP (operands[1], 0), 0)) == REG
1899 && GET_CODE (XEXP (XEXP (operands[1], 0), 1)) == CONST_INT)
1900 {
1901 from = XEXP (XEXP (operands[1], 0), 0);
1902 off = INTVAL (XEXP (XEXP (operands[1], 0), 1));
1903 }
1904 else
1905 FAIL;
1906 }
1907 else
1908 {
1909 from = force_reg (Pmode, XEXP (operands[1], 0));
1910 off = 0;
1911 }
1912
1913 for (i = 0; i < count; i++)
1914 XVECEXP (operands[3], 0, i)
1915 = gen_rtx_SET (VOIDmode, gen_rtx_REG (mode, regno + i),
1916 change_address (operands[1], mode,
1917 plus_constant (from, off + i * GET_MODE_SIZE (mode))));
1918 })
1919
1920 (define_insn "*load_multiple_di"
1921 [(match_parallel 0 "load_multiple_operation"
1922 [(set (match_operand:DI 1 "register_operand" "=r")
1923 (match_operand:DI 2 "s_operand" "QS"))])]
1924 "reload_completed && word_mode == DImode"
1925 {
1926 int words = XVECLEN (operands[0], 0);
1927 operands[0] = gen_rtx_REG (DImode, REGNO (operands[1]) + words - 1);
1928 return "lmg\t%1,%0,%S2";
1929 }
1930 [(set_attr "op_type" "RSY")
1931 (set_attr "type" "lm")])
1932
1933 (define_insn "*load_multiple_si"
1934 [(match_parallel 0 "load_multiple_operation"
1935 [(set (match_operand:SI 1 "register_operand" "=r,r")
1936 (match_operand:SI 2 "s_operand" "Q,S"))])]
1937 "reload_completed"
1938 {
1939 int words = XVECLEN (operands[0], 0);
1940 operands[0] = gen_rtx_REG (SImode, REGNO (operands[1]) + words - 1);
1941 return which_alternative == 0 ? "lm\t%1,%0,%S2" : "lmy\t%1,%0,%S2";
1942 }
1943 [(set_attr "op_type" "RS,RSY")
1944 (set_attr "type" "lm")])
1945
1946 ;
1947 ; store multiple pattern(s).
1948 ;
1949
1950 (define_expand "store_multiple"
1951 [(match_par_dup 3 [(set (match_operand 0 "" "")
1952 (match_operand 1 "" ""))
1953 (use (match_operand 2 "" ""))])]
1954 "reload_completed"
1955 {
1956 enum machine_mode mode;
1957 int regno;
1958 int count;
1959 rtx to;
1960 int i, off;
1961
1962 /* Support only storing a constant number of fixed-point registers to
1963 memory and only bother with this if more than two. */
1964 if (GET_CODE (operands[2]) != CONST_INT
1965 || INTVAL (operands[2]) < 2
1966 || INTVAL (operands[2]) > 16
1967 || GET_CODE (operands[0]) != MEM
1968 || GET_CODE (operands[1]) != REG
1969 || REGNO (operands[1]) >= 16)
1970 FAIL;
1971
1972 count = INTVAL (operands[2]);
1973 regno = REGNO (operands[1]);
1974 mode = GET_MODE (operands[1]);
1975 if (mode != SImode && mode != word_mode)
1976 FAIL;
1977
1978 operands[3] = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (count));
1979
1980 if (no_new_pseudos)
1981 {
1982 if (GET_CODE (XEXP (operands[0], 0)) == REG)
1983 {
1984 to = XEXP (operands[0], 0);
1985 off = 0;
1986 }
1987 else if (GET_CODE (XEXP (operands[0], 0)) == PLUS
1988 && GET_CODE (XEXP (XEXP (operands[0], 0), 0)) == REG
1989 && GET_CODE (XEXP (XEXP (operands[0], 0), 1)) == CONST_INT)
1990 {
1991 to = XEXP (XEXP (operands[0], 0), 0);
1992 off = INTVAL (XEXP (XEXP (operands[0], 0), 1));
1993 }
1994 else
1995 FAIL;
1996 }
1997 else
1998 {
1999 to = force_reg (Pmode, XEXP (operands[0], 0));
2000 off = 0;
2001 }
2002
2003 for (i = 0; i < count; i++)
2004 XVECEXP (operands[3], 0, i)
2005 = gen_rtx_SET (VOIDmode,
2006 change_address (operands[0], mode,
2007 plus_constant (to, off + i * GET_MODE_SIZE (mode))),
2008 gen_rtx_REG (mode, regno + i));
2009 })
2010
2011 (define_insn "*store_multiple_di"
2012 [(match_parallel 0 "store_multiple_operation"
2013 [(set (match_operand:DI 1 "s_operand" "=QS")
2014 (match_operand:DI 2 "register_operand" "r"))])]
2015 "reload_completed && word_mode == DImode"
2016 {
2017 int words = XVECLEN (operands[0], 0);
2018 operands[0] = gen_rtx_REG (DImode, REGNO (operands[2]) + words - 1);
2019 return "stmg\t%2,%0,%S1";
2020 }
2021 [(set_attr "op_type" "RSY")
2022 (set_attr "type" "stm")])
2023
2024
2025 (define_insn "*store_multiple_si"
2026 [(match_parallel 0 "store_multiple_operation"
2027 [(set (match_operand:SI 1 "s_operand" "=Q,S")
2028 (match_operand:SI 2 "register_operand" "r,r"))])]
2029 "reload_completed"
2030 {
2031 int words = XVECLEN (operands[0], 0);
2032 operands[0] = gen_rtx_REG (SImode, REGNO (operands[2]) + words - 1);
2033 return which_alternative == 0 ? "stm\t%2,%0,%S1" : "stmy\t%2,%0,%S1";
2034 }
2035 [(set_attr "op_type" "RS,RSY")
2036 (set_attr "type" "stm")])
2037
2038 ;;
2039 ;; String instructions.
2040 ;;
2041
2042 (define_insn "*execute"
2043 [(match_parallel 0 ""
2044 [(unspec [(match_operand 1 "register_operand" "a")
2045 (match_operand:BLK 2 "memory_operand" "R")
2046 (match_operand 3 "" "")] UNSPEC_EXECUTE)])]
2047 "GET_MODE_CLASS (GET_MODE (operands[1])) == MODE_INT
2048 && GET_MODE_SIZE (GET_MODE (operands[1])) <= UNITS_PER_WORD"
2049 "ex\t%1,%2"
2050 [(set_attr "op_type" "RX")
2051 (set_attr "type" "cs")])
2052
2053
2054 ;
2055 ; strlenM instruction pattern(s).
2056 ;
2057
2058 (define_expand "strlen<mode>"
2059 [(set (reg:SI 0) (match_operand:SI 2 "immediate_operand" ""))
2060 (parallel
2061 [(set (match_dup 4)
2062 (unspec:P [(const_int 0)
2063 (match_operand:BLK 1 "memory_operand" "")
2064 (reg:SI 0)
2065 (match_operand 3 "immediate_operand" "")] UNSPEC_SRST))
2066 (clobber (scratch:P))
2067 (clobber (reg:CC CC_REGNUM))])
2068 (parallel
2069 [(set (match_operand:P 0 "register_operand" "")
2070 (minus:P (match_dup 4) (match_dup 5)))
2071 (clobber (reg:CC CC_REGNUM))])]
2072 ""
2073 {
2074 operands[4] = gen_reg_rtx (Pmode);
2075 operands[5] = gen_reg_rtx (Pmode);
2076 emit_move_insn (operands[5], force_operand (XEXP (operands[1], 0), NULL_RTX));
2077 operands[1] = replace_equiv_address (operands[1], operands[5]);
2078 })
2079
2080 (define_insn "*strlen<mode>"
2081 [(set (match_operand:P 0 "register_operand" "=a")
2082 (unspec:P [(match_operand:P 2 "general_operand" "0")
2083 (mem:BLK (match_operand:P 3 "register_operand" "1"))
2084 (reg:SI 0)
2085 (match_operand 4 "immediate_operand" "")] UNSPEC_SRST))
2086 (clobber (match_scratch:P 1 "=a"))
2087 (clobber (reg:CC CC_REGNUM))]
2088 ""
2089 "srst\t%0,%1\;jo\t.-4"
2090 [(set_attr "length" "8")
2091 (set_attr "type" "vs")])
2092
2093 ;
2094 ; cmpstrM instruction pattern(s).
2095 ;
2096
2097 (define_expand "cmpstrsi"
2098 [(set (reg:SI 0) (const_int 0))
2099 (parallel
2100 [(clobber (match_operand 3 "" ""))
2101 (clobber (match_dup 4))
2102 (set (reg:CCU CC_REGNUM)
2103 (compare:CCU (match_operand:BLK 1 "memory_operand" "")
2104 (match_operand:BLK 2 "memory_operand" "")))
2105 (use (reg:SI 0))])
2106 (parallel
2107 [(set (match_operand:SI 0 "register_operand" "=d")
2108 (unspec:SI [(reg:CCU CC_REGNUM)] UNSPEC_CCU_TO_INT))
2109 (clobber (reg:CC CC_REGNUM))])]
2110 ""
2111 {
2112 /* As the result of CMPINT is inverted compared to what we need,
2113 we have to swap the operands. */
2114 rtx op1 = operands[2];
2115 rtx op2 = operands[1];
2116 rtx addr1 = gen_reg_rtx (Pmode);
2117 rtx addr2 = gen_reg_rtx (Pmode);
2118
2119 emit_move_insn (addr1, force_operand (XEXP (op1, 0), NULL_RTX));
2120 emit_move_insn (addr2, force_operand (XEXP (op2, 0), NULL_RTX));
2121 operands[1] = replace_equiv_address_nv (op1, addr1);
2122 operands[2] = replace_equiv_address_nv (op2, addr2);
2123 operands[3] = addr1;
2124 operands[4] = addr2;
2125 })
2126
2127 (define_insn "*cmpstr<mode>"
2128 [(clobber (match_operand:P 0 "register_operand" "=d"))
2129 (clobber (match_operand:P 1 "register_operand" "=d"))
2130 (set (reg:CCU CC_REGNUM)
2131 (compare:CCU (mem:BLK (match_operand:P 2 "register_operand" "0"))
2132 (mem:BLK (match_operand:P 3 "register_operand" "1"))))
2133 (use (reg:SI 0))]
2134 ""
2135 "clst\t%0,%1\;jo\t.-4"
2136 [(set_attr "length" "8")
2137 (set_attr "type" "vs")])
2138
2139 ;
2140 ; movstr instruction pattern.
2141 ;
2142
2143 (define_expand "movstr"
2144 [(set (reg:SI 0) (const_int 0))
2145 (parallel
2146 [(clobber (match_dup 3))
2147 (set (match_operand:BLK 1 "memory_operand" "")
2148 (match_operand:BLK 2 "memory_operand" ""))
2149 (set (match_operand 0 "register_operand" "")
2150 (unspec [(match_dup 1)
2151 (match_dup 2)
2152 (reg:SI 0)] UNSPEC_MVST))
2153 (clobber (reg:CC CC_REGNUM))])]
2154 ""
2155 {
2156 rtx addr1 = gen_reg_rtx (Pmode);
2157 rtx addr2 = gen_reg_rtx (Pmode);
2158
2159 emit_move_insn (addr1, force_operand (XEXP (operands[1], 0), NULL_RTX));
2160 emit_move_insn (addr2, force_operand (XEXP (operands[2], 0), NULL_RTX));
2161 operands[1] = replace_equiv_address_nv (operands[1], addr1);
2162 operands[2] = replace_equiv_address_nv (operands[2], addr2);
2163 operands[3] = addr2;
2164 })
2165
2166 (define_insn "*movstr"
2167 [(clobber (match_operand:P 2 "register_operand" "=d"))
2168 (set (mem:BLK (match_operand:P 1 "register_operand" "0"))
2169 (mem:BLK (match_operand:P 3 "register_operand" "2")))
2170 (set (match_operand:P 0 "register_operand" "=d")
2171 (unspec [(mem:BLK (match_dup 1))
2172 (mem:BLK (match_dup 3))
2173 (reg:SI 0)] UNSPEC_MVST))
2174 (clobber (reg:CC CC_REGNUM))]
2175 ""
2176 "mvst\t%1,%2\;jo\t.-4"
2177 [(set_attr "length" "8")
2178 (set_attr "type" "vs")])
2179
2180
2181 ;
2182 ; movmemM instruction pattern(s).
2183 ;
2184
2185 (define_expand "movmem<mode>"
2186 [(set (match_operand:BLK 0 "memory_operand" "")
2187 (match_operand:BLK 1 "memory_operand" ""))
2188 (use (match_operand:GPR 2 "general_operand" ""))
2189 (match_operand 3 "" "")]
2190 ""
2191 "s390_expand_movmem (operands[0], operands[1], operands[2]); DONE;")
2192
2193 ; Move a block that is up to 256 bytes in length.
2194 ; The block length is taken as (operands[2] % 256) + 1.
2195
2196 (define_expand "movmem_short"
2197 [(parallel
2198 [(set (match_operand:BLK 0 "memory_operand" "")
2199 (match_operand:BLK 1 "memory_operand" ""))
2200 (use (match_operand 2 "nonmemory_operand" ""))
2201 (use (const:BLK (unspec:BLK [(const_int 0)] UNSPEC_INSN)))
2202 (clobber (match_dup 3))])]
2203 ""
2204 "operands[3] = gen_rtx_SCRATCH (Pmode);")
2205
2206 (define_insn "*movmem_short"
2207 [(set (match_operand:BLK 0 "memory_operand" "=Q,Q,Q")
2208 (match_operand:BLK 1 "memory_operand" "Q,Q,Q"))
2209 (use (match_operand 2 "nonmemory_operand" "n,a,a"))
2210 (use (match_operand 3 "immediate_operand" "X,R,X"))
2211 (clobber (match_scratch 4 "=X,X,&a"))]
2212 "(GET_MODE (operands[2]) == Pmode || GET_MODE (operands[2]) == VOIDmode)
2213 && GET_MODE (operands[4]) == Pmode"
2214 "#"
2215 [(set_attr "type" "cs")])
2216
2217 (define_split
2218 [(set (match_operand:BLK 0 "memory_operand" "")
2219 (match_operand:BLK 1 "memory_operand" ""))
2220 (use (match_operand 2 "const_int_operand" ""))
2221 (use (match_operand 3 "immediate_operand" ""))
2222 (clobber (scratch))]
2223 "reload_completed"
2224 [(parallel
2225 [(set (match_dup 0) (match_dup 1))
2226 (use (match_dup 2))])]
2227 "operands[2] = GEN_INT ((INTVAL (operands[2]) & 0xff) + 1);")
2228
2229 (define_split
2230 [(set (match_operand:BLK 0 "memory_operand" "")
2231 (match_operand:BLK 1 "memory_operand" ""))
2232 (use (match_operand 2 "register_operand" ""))
2233 (use (match_operand 3 "memory_operand" ""))
2234 (clobber (scratch))]
2235 "reload_completed"
2236 [(parallel
2237 [(unspec [(match_dup 2) (match_dup 3)
2238 (const_int 0)] UNSPEC_EXECUTE)
2239 (set (match_dup 0) (match_dup 1))
2240 (use (const_int 1))])]
2241 "")
2242
2243 (define_split
2244 [(set (match_operand:BLK 0 "memory_operand" "")
2245 (match_operand:BLK 1 "memory_operand" ""))
2246 (use (match_operand 2 "register_operand" ""))
2247 (use (const:BLK (unspec:BLK [(const_int 0)] UNSPEC_INSN)))
2248 (clobber (match_operand 3 "register_operand" ""))]
2249 "reload_completed && TARGET_CPU_ZARCH"
2250 [(set (match_dup 3) (label_ref (match_dup 4)))
2251 (parallel
2252 [(unspec [(match_dup 2) (mem:BLK (match_dup 3))
2253 (label_ref (match_dup 4))] UNSPEC_EXECUTE)
2254 (set (match_dup 0) (match_dup 1))
2255 (use (const_int 1))])]
2256 "operands[4] = gen_label_rtx ();")
2257
2258 ; Move a block of arbitrary length.
2259
2260 (define_expand "movmem_long"
2261 [(parallel
2262 [(clobber (match_dup 2))
2263 (clobber (match_dup 3))
2264 (set (match_operand:BLK 0 "memory_operand" "")
2265 (match_operand:BLK 1 "memory_operand" ""))
2266 (use (match_operand 2 "general_operand" ""))
2267 (use (match_dup 3))
2268 (clobber (reg:CC CC_REGNUM))])]
2269 ""
2270 {
2271 enum machine_mode dword_mode = word_mode == DImode ? TImode : DImode;
2272 rtx reg0 = gen_reg_rtx (dword_mode);
2273 rtx reg1 = gen_reg_rtx (dword_mode);
2274 rtx addr0 = gen_lowpart (Pmode, gen_highpart (word_mode, reg0));
2275 rtx addr1 = gen_lowpart (Pmode, gen_highpart (word_mode, reg1));
2276 rtx len0 = gen_lowpart (Pmode, reg0);
2277 rtx len1 = gen_lowpart (Pmode, reg1);
2278
2279 emit_insn (gen_rtx_CLOBBER (VOIDmode, reg0));
2280 emit_move_insn (addr0, force_operand (XEXP (operands[0], 0), NULL_RTX));
2281 emit_move_insn (len0, operands[2]);
2282
2283 emit_insn (gen_rtx_CLOBBER (VOIDmode, reg1));
2284 emit_move_insn (addr1, force_operand (XEXP (operands[1], 0), NULL_RTX));
2285 emit_move_insn (len1, operands[2]);
2286
2287 operands[0] = replace_equiv_address_nv (operands[0], addr0);
2288 operands[1] = replace_equiv_address_nv (operands[1], addr1);
2289 operands[2] = reg0;
2290 operands[3] = reg1;
2291 })
2292
2293 (define_insn "*movmem_long"
2294 [(clobber (match_operand:<DBL> 0 "register_operand" "=d"))
2295 (clobber (match_operand:<DBL> 1 "register_operand" "=d"))
2296 (set (mem:BLK (subreg:P (match_operand:<DBL> 2 "register_operand" "0") 0))
2297 (mem:BLK (subreg:P (match_operand:<DBL> 3 "register_operand" "1") 0)))
2298 (use (match_dup 2))
2299 (use (match_dup 3))
2300 (clobber (reg:CC CC_REGNUM))]
2301 ""
2302 "mvcle\t%0,%1,0\;jo\t.-4"
2303 [(set_attr "length" "8")
2304 (set_attr "type" "vs")])
2305
2306
2307 ;
2308 ; Test data class.
2309 ;
2310
2311 (define_expand "signbit<mode>2"
2312 [(set (reg:CCZ CC_REGNUM)
2313 (unspec:CCZ [(match_operand:BFP 1 "register_operand" "f")
2314 (match_dup 2)]
2315 UNSPEC_TDC_INSN))
2316 (set (match_operand:SI 0 "register_operand" "=d")
2317 (unspec:SI [(reg:CCZ CC_REGNUM)] UNSPEC_CCZ_TO_INT))]
2318 "TARGET_HARD_FLOAT"
2319 {
2320 operands[2] = GEN_INT (S390_TDC_SIGNBIT_SET);
2321 })
2322
2323 (define_expand "isinf<mode>2"
2324 [(set (reg:CCZ CC_REGNUM)
2325 (unspec:CCZ [(match_operand:BFP 1 "register_operand" "f")
2326 (match_dup 2)]
2327 UNSPEC_TDC_INSN))
2328 (set (match_operand:SI 0 "register_operand" "=d")
2329 (unspec:SI [(reg:CCZ CC_REGNUM)] UNSPEC_CCZ_TO_INT))]
2330 "TARGET_HARD_FLOAT"
2331 {
2332 operands[2] = GEN_INT (S390_TDC_INFINITY);
2333 })
2334
2335 ; This insn is used to generate all variants of the Test Data Class
2336 ; instruction, namely tcxb, tcdb, and tceb. The insn's first operand
2337 ; is the register to be tested and the second one is the bit mask
2338 ; specifying the required test(s).
2339 ;
2340 (define_insn "*TDC_insn_<mode>"
2341 [(set (reg:CCZ CC_REGNUM)
2342 (unspec:CCZ [(match_operand:BFP 0 "register_operand" "f")
2343 (match_operand:SI 1 "const_int_operand")] UNSPEC_TDC_INSN))]
2344 "TARGET_HARD_FLOAT"
2345 "tc<xde>b\t%0,%1"
2346 [(set_attr "op_type" "RXE")
2347 (set_attr "type" "fsimp<mode>")])
2348
2349 (define_insn_and_split "*ccz_to_int"
2350 [(set (match_operand:SI 0 "register_operand" "=d")
2351 (unspec:SI [(match_operand:CCZ 1 "register_operand" "0")]
2352 UNSPEC_CCZ_TO_INT))]
2353 ""
2354 "#"
2355 "reload_completed"
2356 [(set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 28)))])
2357
2358
2359 ;
2360 ; setmemM instruction pattern(s).
2361 ;
2362
2363 (define_expand "setmem<mode>"
2364 [(set (match_operand:BLK 0 "memory_operand" "")
2365 (match_operand:QI 2 "general_operand" ""))
2366 (use (match_operand:GPR 1 "general_operand" ""))
2367 (match_operand 3 "" "")]
2368 ""
2369 "s390_expand_setmem (operands[0], operands[1], operands[2]); DONE;")
2370
2371 ; Clear a block that is up to 256 bytes in length.
2372 ; The block length is taken as (operands[1] % 256) + 1.
2373
2374 (define_expand "clrmem_short"
2375 [(parallel
2376 [(set (match_operand:BLK 0 "memory_operand" "")
2377 (const_int 0))
2378 (use (match_operand 1 "nonmemory_operand" ""))
2379 (use (const:BLK (unspec:BLK [(const_int 0)] UNSPEC_INSN)))
2380 (clobber (match_dup 2))
2381 (clobber (reg:CC CC_REGNUM))])]
2382 ""
2383 "operands[2] = gen_rtx_SCRATCH (Pmode);")
2384
2385 (define_insn "*clrmem_short"
2386 [(set (match_operand:BLK 0 "memory_operand" "=Q,Q,Q")
2387 (const_int 0))
2388 (use (match_operand 1 "nonmemory_operand" "n,a,a"))
2389 (use (match_operand 2 "immediate_operand" "X,R,X"))
2390 (clobber (match_scratch 3 "=X,X,&a"))
2391 (clobber (reg:CC CC_REGNUM))]
2392 "(GET_MODE (operands[1]) == Pmode || GET_MODE (operands[1]) == VOIDmode)
2393 && GET_MODE (operands[3]) == Pmode"
2394 "#"
2395 [(set_attr "type" "cs")])
2396
2397 (define_split
2398 [(set (match_operand:BLK 0 "memory_operand" "")
2399 (const_int 0))
2400 (use (match_operand 1 "const_int_operand" ""))
2401 (use (match_operand 2 "immediate_operand" ""))
2402 (clobber (scratch))
2403 (clobber (reg:CC CC_REGNUM))]
2404 "reload_completed"
2405 [(parallel
2406 [(set (match_dup 0) (const_int 0))
2407 (use (match_dup 1))
2408 (clobber (reg:CC CC_REGNUM))])]
2409 "operands[1] = GEN_INT ((INTVAL (operands[1]) & 0xff) + 1);")
2410
2411 (define_split
2412 [(set (match_operand:BLK 0 "memory_operand" "")
2413 (const_int 0))
2414 (use (match_operand 1 "register_operand" ""))
2415 (use (match_operand 2 "memory_operand" ""))
2416 (clobber (scratch))
2417 (clobber (reg:CC CC_REGNUM))]
2418 "reload_completed"
2419 [(parallel
2420 [(unspec [(match_dup 1) (match_dup 2)
2421 (const_int 0)] UNSPEC_EXECUTE)
2422 (set (match_dup 0) (const_int 0))
2423 (use (const_int 1))
2424 (clobber (reg:CC CC_REGNUM))])]
2425 "")
2426
2427 (define_split
2428 [(set (match_operand:BLK 0 "memory_operand" "")
2429 (const_int 0))
2430 (use (match_operand 1 "register_operand" ""))
2431 (use (const:BLK (unspec:BLK [(const_int 0)] UNSPEC_INSN)))
2432 (clobber (match_operand 2 "register_operand" ""))
2433 (clobber (reg:CC CC_REGNUM))]
2434 "reload_completed && TARGET_CPU_ZARCH"
2435 [(set (match_dup 2) (label_ref (match_dup 3)))
2436 (parallel
2437 [(unspec [(match_dup 1) (mem:BLK (match_dup 2))
2438 (label_ref (match_dup 3))] UNSPEC_EXECUTE)
2439 (set (match_dup 0) (const_int 0))
2440 (use (const_int 1))
2441 (clobber (reg:CC CC_REGNUM))])]
2442 "operands[3] = gen_label_rtx ();")
2443
2444 ; Initialize a block of arbitrary length with (operands[2] % 256).
2445
2446 (define_expand "setmem_long"
2447 [(parallel
2448 [(clobber (match_dup 1))
2449 (set (match_operand:BLK 0 "memory_operand" "")
2450 (match_operand 2 "shift_count_or_setmem_operand" ""))
2451 (use (match_operand 1 "general_operand" ""))
2452 (use (match_dup 3))
2453 (clobber (reg:CC CC_REGNUM))])]
2454 ""
2455 {
2456 enum machine_mode dword_mode = word_mode == DImode ? TImode : DImode;
2457 rtx reg0 = gen_reg_rtx (dword_mode);
2458 rtx reg1 = gen_reg_rtx (dword_mode);
2459 rtx addr0 = gen_lowpart (Pmode, gen_highpart (word_mode, reg0));
2460 rtx len0 = gen_lowpart (Pmode, reg0);
2461
2462 emit_insn (gen_rtx_CLOBBER (VOIDmode, reg0));
2463 emit_move_insn (addr0, force_operand (XEXP (operands[0], 0), NULL_RTX));
2464 emit_move_insn (len0, operands[1]);
2465
2466 emit_move_insn (reg1, const0_rtx);
2467
2468 operands[0] = replace_equiv_address_nv (operands[0], addr0);
2469 operands[1] = reg0;
2470 operands[3] = reg1;
2471 })
2472
2473 (define_insn "*setmem_long"
2474 [(clobber (match_operand:<DBL> 0 "register_operand" "=d"))
2475 (set (mem:BLK (subreg:P (match_operand:<DBL> 3 "register_operand" "0") 0))
2476 (match_operand 2 "shift_count_or_setmem_operand" "Y"))
2477 (use (match_dup 3))
2478 (use (match_operand:<DBL> 1 "register_operand" "d"))
2479 (clobber (reg:CC CC_REGNUM))]
2480 ""
2481 "mvcle\t%0,%1,%Y2\;jo\t.-4"
2482 [(set_attr "length" "8")
2483 (set_attr "type" "vs")])
2484
2485 (define_insn "*setmem_long_and"
2486 [(clobber (match_operand:<DBL> 0 "register_operand" "=d"))
2487 (set (mem:BLK (subreg:P (match_operand:<DBL> 3 "register_operand" "0") 0))
2488 (and (match_operand 2 "shift_count_or_setmem_operand" "Y")
2489 (match_operand 4 "const_int_operand" "n")))
2490 (use (match_dup 3))
2491 (use (match_operand:<DBL> 1 "register_operand" "d"))
2492 (clobber (reg:CC CC_REGNUM))]
2493 "(INTVAL (operands[4]) & 255) == 255"
2494 "mvcle\t%0,%1,%Y2\;jo\t.-4"
2495 [(set_attr "length" "8")
2496 (set_attr "type" "vs")])
2497 ;
2498 ; cmpmemM instruction pattern(s).
2499 ;
2500
2501 (define_expand "cmpmemsi"
2502 [(set (match_operand:SI 0 "register_operand" "")
2503 (compare:SI (match_operand:BLK 1 "memory_operand" "")
2504 (match_operand:BLK 2 "memory_operand" "") ) )
2505 (use (match_operand:SI 3 "general_operand" ""))
2506 (use (match_operand:SI 4 "" ""))]
2507 ""
2508 "s390_expand_cmpmem (operands[0], operands[1],
2509 operands[2], operands[3]); DONE;")
2510
2511 ; Compare a block that is up to 256 bytes in length.
2512 ; The block length is taken as (operands[2] % 256) + 1.
2513
2514 (define_expand "cmpmem_short"
2515 [(parallel
2516 [(set (reg:CCU CC_REGNUM)
2517 (compare:CCU (match_operand:BLK 0 "memory_operand" "")
2518 (match_operand:BLK 1 "memory_operand" "")))
2519 (use (match_operand 2 "nonmemory_operand" ""))
2520 (use (const:BLK (unspec:BLK [(const_int 0)] UNSPEC_INSN)))
2521 (clobber (match_dup 3))])]
2522 ""
2523 "operands[3] = gen_rtx_SCRATCH (Pmode);")
2524
2525 (define_insn "*cmpmem_short"
2526 [(set (reg:CCU CC_REGNUM)
2527 (compare:CCU (match_operand:BLK 0 "memory_operand" "Q,Q,Q")
2528 (match_operand:BLK 1 "memory_operand" "Q,Q,Q")))
2529 (use (match_operand 2 "nonmemory_operand" "n,a,a"))
2530 (use (match_operand 3 "immediate_operand" "X,R,X"))
2531 (clobber (match_scratch 4 "=X,X,&a"))]
2532 "(GET_MODE (operands[2]) == Pmode || GET_MODE (operands[2]) == VOIDmode)
2533 && GET_MODE (operands[4]) == Pmode"
2534 "#"
2535 [(set_attr "type" "cs")])
2536
2537 (define_split
2538 [(set (reg:CCU CC_REGNUM)
2539 (compare:CCU (match_operand:BLK 0 "memory_operand" "")
2540 (match_operand:BLK 1 "memory_operand" "")))
2541 (use (match_operand 2 "const_int_operand" ""))
2542 (use (match_operand 3 "immediate_operand" ""))
2543 (clobber (scratch))]
2544 "reload_completed"
2545 [(parallel
2546 [(set (reg:CCU CC_REGNUM) (compare:CCU (match_dup 0) (match_dup 1)))
2547 (use (match_dup 2))])]
2548 "operands[2] = GEN_INT ((INTVAL (operands[2]) & 0xff) + 1);")
2549
2550 (define_split
2551 [(set (reg:CCU CC_REGNUM)
2552 (compare:CCU (match_operand:BLK 0 "memory_operand" "")
2553 (match_operand:BLK 1 "memory_operand" "")))
2554 (use (match_operand 2 "register_operand" ""))
2555 (use (match_operand 3 "memory_operand" ""))
2556 (clobber (scratch))]
2557 "reload_completed"
2558 [(parallel
2559 [(unspec [(match_dup 2) (match_dup 3)
2560 (const_int 0)] UNSPEC_EXECUTE)
2561 (set (reg:CCU CC_REGNUM) (compare:CCU (match_dup 0) (match_dup 1)))
2562 (use (const_int 1))])]
2563 "")
2564
2565 (define_split
2566 [(set (reg:CCU CC_REGNUM)
2567 (compare:CCU (match_operand:BLK 0 "memory_operand" "")
2568 (match_operand:BLK 1 "memory_operand" "")))
2569 (use (match_operand 2 "register_operand" ""))
2570 (use (const:BLK (unspec:BLK [(const_int 0)] UNSPEC_INSN)))
2571 (clobber (match_operand 3 "register_operand" ""))]
2572 "reload_completed && TARGET_CPU_ZARCH"
2573 [(set (match_dup 3) (label_ref (match_dup 4)))
2574 (parallel
2575 [(unspec [(match_dup 2) (mem:BLK (match_dup 3))
2576 (label_ref (match_dup 4))] UNSPEC_EXECUTE)
2577 (set (reg:CCU CC_REGNUM) (compare:CCU (match_dup 0) (match_dup 1)))
2578 (use (const_int 1))])]
2579 "operands[4] = gen_label_rtx ();")
2580
2581 ; Compare a block of arbitrary length.
2582
2583 (define_expand "cmpmem_long"
2584 [(parallel
2585 [(clobber (match_dup 2))
2586 (clobber (match_dup 3))
2587 (set (reg:CCU CC_REGNUM)
2588 (compare:CCU (match_operand:BLK 0 "memory_operand" "")
2589 (match_operand:BLK 1 "memory_operand" "")))
2590 (use (match_operand 2 "general_operand" ""))
2591 (use (match_dup 3))])]
2592 ""
2593 {
2594 enum machine_mode dword_mode = word_mode == DImode ? TImode : DImode;
2595 rtx reg0 = gen_reg_rtx (dword_mode);
2596 rtx reg1 = gen_reg_rtx (dword_mode);
2597 rtx addr0 = gen_lowpart (Pmode, gen_highpart (word_mode, reg0));
2598 rtx addr1 = gen_lowpart (Pmode, gen_highpart (word_mode, reg1));
2599 rtx len0 = gen_lowpart (Pmode, reg0);
2600 rtx len1 = gen_lowpart (Pmode, reg1);
2601
2602 emit_insn (gen_rtx_CLOBBER (VOIDmode, reg0));
2603 emit_move_insn (addr0, force_operand (XEXP (operands[0], 0), NULL_RTX));
2604 emit_move_insn (len0, operands[2]);
2605
2606 emit_insn (gen_rtx_CLOBBER (VOIDmode, reg1));
2607 emit_move_insn (addr1, force_operand (XEXP (operands[1], 0), NULL_RTX));
2608 emit_move_insn (len1, operands[2]);
2609
2610 operands[0] = replace_equiv_address_nv (operands[0], addr0);
2611 operands[1] = replace_equiv_address_nv (operands[1], addr1);
2612 operands[2] = reg0;
2613 operands[3] = reg1;
2614 })
2615
2616 (define_insn "*cmpmem_long"
2617 [(clobber (match_operand:<DBL> 0 "register_operand" "=d"))
2618 (clobber (match_operand:<DBL> 1 "register_operand" "=d"))
2619 (set (reg:CCU CC_REGNUM)
2620 (compare:CCU (mem:BLK (subreg:P (match_operand:<DBL> 2 "register_operand" "0") 0))
2621 (mem:BLK (subreg:P (match_operand:<DBL> 3 "register_operand" "1") 0))))
2622 (use (match_dup 2))
2623 (use (match_dup 3))]
2624 ""
2625 "clcle\t%0,%1,0\;jo\t.-4"
2626 [(set_attr "length" "8")
2627 (set_attr "type" "vs")])
2628
2629 ; Convert CCUmode condition code to integer.
2630 ; Result is zero if EQ, positive if LTU, negative if GTU.
2631
2632 (define_insn_and_split "cmpint"
2633 [(set (match_operand:SI 0 "register_operand" "=d")
2634 (unspec:SI [(match_operand:CCU 1 "register_operand" "0")]
2635 UNSPEC_CCU_TO_INT))
2636 (clobber (reg:CC CC_REGNUM))]
2637 ""
2638 "#"
2639 "reload_completed"
2640 [(set (match_dup 0) (ashift:SI (match_dup 0) (const_int 2)))
2641 (parallel
2642 [(set (match_dup 0) (ashiftrt:SI (match_dup 0) (const_int 30)))
2643 (clobber (reg:CC CC_REGNUM))])])
2644
2645 (define_insn_and_split "*cmpint_cc"
2646 [(set (reg CC_REGNUM)
2647 (compare (unspec:SI [(match_operand:CCU 1 "register_operand" "0")]
2648 UNSPEC_CCU_TO_INT)
2649 (const_int 0)))
2650 (set (match_operand:SI 0 "register_operand" "=d")
2651 (unspec:SI [(match_dup 1)] UNSPEC_CCU_TO_INT))]
2652 "s390_match_ccmode (insn, CCSmode)"
2653 "#"
2654 "&& reload_completed"
2655 [(set (match_dup 0) (ashift:SI (match_dup 0) (const_int 2)))
2656 (parallel
2657 [(set (match_dup 2) (match_dup 3))
2658 (set (match_dup 0) (ashiftrt:SI (match_dup 0) (const_int 30)))])]
2659 {
2660 rtx result = gen_rtx_ASHIFTRT (SImode, operands[0], GEN_INT (30));
2661 operands[2] = SET_DEST (XVECEXP (PATTERN (curr_insn), 0, 0));
2662 operands[3] = gen_rtx_COMPARE (GET_MODE (operands[2]), result, const0_rtx);
2663 })
2664
2665 (define_insn_and_split "*cmpint_sign"
2666 [(set (match_operand:DI 0 "register_operand" "=d")
2667 (sign_extend:DI (unspec:SI [(match_operand:CCU 1 "register_operand" "0")]
2668 UNSPEC_CCU_TO_INT)))
2669 (clobber (reg:CC CC_REGNUM))]
2670 "TARGET_64BIT"
2671 "#"
2672 "&& reload_completed"
2673 [(set (match_dup 0) (ashift:DI (match_dup 0) (const_int 34)))
2674 (parallel
2675 [(set (match_dup 0) (ashiftrt:DI (match_dup 0) (const_int 62)))
2676 (clobber (reg:CC CC_REGNUM))])])
2677
2678 (define_insn_and_split "*cmpint_sign_cc"
2679 [(set (reg CC_REGNUM)
2680 (compare (ashiftrt:DI (ashift:DI (subreg:DI
2681 (unspec:SI [(match_operand:CCU 1 "register_operand" "0")]
2682 UNSPEC_CCU_TO_INT) 0)
2683 (const_int 32)) (const_int 32))
2684 (const_int 0)))
2685 (set (match_operand:DI 0 "register_operand" "=d")
2686 (sign_extend:DI (unspec:SI [(match_dup 1)] UNSPEC_CCU_TO_INT)))]
2687 "s390_match_ccmode (insn, CCSmode) && TARGET_64BIT"
2688 "#"
2689 "&& reload_completed"
2690 [(set (match_dup 0) (ashift:DI (match_dup 0) (const_int 34)))
2691 (parallel
2692 [(set (match_dup 2) (match_dup 3))
2693 (set (match_dup 0) (ashiftrt:DI (match_dup 0) (const_int 62)))])]
2694 {
2695 rtx result = gen_rtx_ASHIFTRT (DImode, operands[0], GEN_INT (62));
2696 operands[2] = SET_DEST (XVECEXP (PATTERN (curr_insn), 0, 0));
2697 operands[3] = gen_rtx_COMPARE (GET_MODE (operands[2]), result, const0_rtx);
2698 })
2699
2700
2701 ;;
2702 ;;- Conversion instructions.
2703 ;;
2704
2705 (define_insn "*sethighpartsi"
2706 [(set (match_operand:SI 0 "register_operand" "=d,d")
2707 (unspec:SI [(match_operand:BLK 1 "s_operand" "Q,S")
2708 (match_operand 2 "const_int_operand" "n,n")] UNSPEC_ICM))
2709 (clobber (reg:CC CC_REGNUM))]
2710 ""
2711 "@
2712 icm\t%0,%2,%S1
2713 icmy\t%0,%2,%S1"
2714 [(set_attr "op_type" "RS,RSY")])
2715
2716 (define_insn "*sethighpartdi_64"
2717 [(set (match_operand:DI 0 "register_operand" "=d")
2718 (unspec:DI [(match_operand:BLK 1 "s_operand" "QS")
2719 (match_operand 2 "const_int_operand" "n")] UNSPEC_ICM))
2720 (clobber (reg:CC CC_REGNUM))]
2721 "TARGET_64BIT"
2722 "icmh\t%0,%2,%S1"
2723 [(set_attr "op_type" "RSY")])
2724
2725 (define_insn "*sethighpartdi_31"
2726 [(set (match_operand:DI 0 "register_operand" "=d,d")
2727 (unspec:DI [(match_operand:BLK 1 "s_operand" "Q,S")
2728 (match_operand 2 "const_int_operand" "n,n")] UNSPEC_ICM))
2729 (clobber (reg:CC CC_REGNUM))]
2730 "!TARGET_64BIT"
2731 "@
2732 icm\t%0,%2,%S1
2733 icmy\t%0,%2,%S1"
2734 [(set_attr "op_type" "RS,RSY")])
2735
2736 (define_insn_and_split "*extzv<mode>"
2737 [(set (match_operand:GPR 0 "register_operand" "=d")
2738 (zero_extract:GPR (match_operand:QI 1 "s_operand" "QS")
2739 (match_operand 2 "const_int_operand" "n")
2740 (const_int 0)))
2741 (clobber (reg:CC CC_REGNUM))]
2742 "INTVAL (operands[2]) > 0
2743 && INTVAL (operands[2]) <= GET_MODE_BITSIZE (SImode)"
2744 "#"
2745 "&& reload_completed"
2746 [(parallel
2747 [(set (match_dup 0) (unspec:GPR [(match_dup 1) (match_dup 3)] UNSPEC_ICM))
2748 (clobber (reg:CC CC_REGNUM))])
2749 (set (match_dup 0) (lshiftrt:GPR (match_dup 0) (match_dup 2)))]
2750 {
2751 int bitsize = INTVAL (operands[2]);
2752 int size = (bitsize - 1) / BITS_PER_UNIT + 1; /* round up */
2753 int mask = ((1ul << size) - 1) << (GET_MODE_SIZE (SImode) - size);
2754
2755 operands[1] = adjust_address (operands[1], BLKmode, 0);
2756 set_mem_size (operands[1], GEN_INT (size));
2757 operands[2] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode) - bitsize);
2758 operands[3] = GEN_INT (mask);
2759 })
2760
2761 (define_insn_and_split "*extv<mode>"
2762 [(set (match_operand:GPR 0 "register_operand" "=d")
2763 (sign_extract:GPR (match_operand:QI 1 "s_operand" "QS")
2764 (match_operand 2 "const_int_operand" "n")
2765 (const_int 0)))
2766 (clobber (reg:CC CC_REGNUM))]
2767 "INTVAL (operands[2]) > 0
2768 && INTVAL (operands[2]) <= GET_MODE_BITSIZE (SImode)"
2769 "#"
2770 "&& reload_completed"
2771 [(parallel
2772 [(set (match_dup 0) (unspec:GPR [(match_dup 1) (match_dup 3)] UNSPEC_ICM))
2773 (clobber (reg:CC CC_REGNUM))])
2774 (parallel
2775 [(set (match_dup 0) (ashiftrt:GPR (match_dup 0) (match_dup 2)))
2776 (clobber (reg:CC CC_REGNUM))])]
2777 {
2778 int bitsize = INTVAL (operands[2]);
2779 int size = (bitsize - 1) / BITS_PER_UNIT + 1; /* round up */
2780 int mask = ((1ul << size) - 1) << (GET_MODE_SIZE (SImode) - size);
2781
2782 operands[1] = adjust_address (operands[1], BLKmode, 0);
2783 set_mem_size (operands[1], GEN_INT (size));
2784 operands[2] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode) - bitsize);
2785 operands[3] = GEN_INT (mask);
2786 })
2787
2788 ;
2789 ; insv instruction patterns
2790 ;
2791
2792 (define_expand "insv"
2793 [(set (zero_extract (match_operand 0 "nonimmediate_operand" "")
2794 (match_operand 1 "const_int_operand" "")
2795 (match_operand 2 "const_int_operand" ""))
2796 (match_operand 3 "general_operand" ""))]
2797 ""
2798 {
2799 if (s390_expand_insv (operands[0], operands[1], operands[2], operands[3]))
2800 DONE;
2801 FAIL;
2802 })
2803
2804 (define_insn "*insv<mode>_mem_reg"
2805 [(set (zero_extract:P (match_operand:QI 0 "memory_operand" "+Q,S")
2806 (match_operand 1 "const_int_operand" "n,n")
2807 (const_int 0))
2808 (match_operand:P 2 "register_operand" "d,d"))]
2809 "INTVAL (operands[1]) > 0
2810 && INTVAL (operands[1]) <= GET_MODE_BITSIZE (SImode)
2811 && INTVAL (operands[1]) % BITS_PER_UNIT == 0"
2812 {
2813 int size = INTVAL (operands[1]) / BITS_PER_UNIT;
2814
2815 operands[1] = GEN_INT ((1ul << size) - 1);
2816 return (which_alternative == 0) ? "stcm\t%2,%1,%S0"
2817 : "stcmy\t%2,%1,%S0";
2818 }
2819 [(set_attr "op_type" "RS,RSY")])
2820
2821 (define_insn "*insvdi_mem_reghigh"
2822 [(set (zero_extract:DI (match_operand:QI 0 "memory_operand" "+QS")
2823 (match_operand 1 "const_int_operand" "n")
2824 (const_int 0))
2825 (lshiftrt:DI (match_operand:DI 2 "register_operand" "d")
2826 (const_int 32)))]
2827 "TARGET_64BIT
2828 && INTVAL (operands[1]) > 0
2829 && INTVAL (operands[1]) <= GET_MODE_BITSIZE (SImode)
2830 && INTVAL (operands[1]) % BITS_PER_UNIT == 0"
2831 {
2832 int size = INTVAL (operands[1]) / BITS_PER_UNIT;
2833
2834 operands[1] = GEN_INT ((1ul << size) - 1);
2835 return "stcmh\t%2,%1,%S0";
2836 }
2837 [(set_attr "op_type" "RSY")])
2838
2839 (define_insn "*insv<mode>_reg_imm"
2840 [(set (zero_extract:P (match_operand:P 0 "register_operand" "+d")
2841 (const_int 16)
2842 (match_operand 1 "const_int_operand" "n"))
2843 (match_operand:P 2 "const_int_operand" "n"))]
2844 "TARGET_ZARCH
2845 && INTVAL (operands[1]) >= 0
2846 && INTVAL (operands[1]) < BITS_PER_WORD
2847 && INTVAL (operands[1]) % 16 == 0"
2848 {
2849 switch (BITS_PER_WORD - INTVAL (operands[1]))
2850 {
2851 case 64: return "iihh\t%0,%x2"; break;
2852 case 48: return "iihl\t%0,%x2"; break;
2853 case 32: return "iilh\t%0,%x2"; break;
2854 case 16: return "iill\t%0,%x2"; break;
2855 default: gcc_unreachable();
2856 }
2857 }
2858 [(set_attr "op_type" "RI")])
2859
2860 (define_insn "*insv<mode>_reg_extimm"
2861 [(set (zero_extract:P (match_operand:P 0 "register_operand" "+d")
2862 (const_int 32)
2863 (match_operand 1 "const_int_operand" "n"))
2864 (match_operand:P 2 "const_int_operand" "n"))]
2865 "TARGET_EXTIMM
2866 && INTVAL (operands[1]) >= 0
2867 && INTVAL (operands[1]) < BITS_PER_WORD
2868 && INTVAL (operands[1]) % 32 == 0"
2869 {
2870 switch (BITS_PER_WORD - INTVAL (operands[1]))
2871 {
2872 case 64: return "iihf\t%0,%o2"; break;
2873 case 32: return "iilf\t%0,%o2"; break;
2874 default: gcc_unreachable();
2875 }
2876 }
2877 [(set_attr "op_type" "RIL")])
2878
2879 ;
2880 ; extendsidi2 instruction pattern(s).
2881 ;
2882
2883 (define_expand "extendsidi2"
2884 [(set (match_operand:DI 0 "register_operand" "")
2885 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "")))]
2886 ""
2887 {
2888 if (!TARGET_64BIT)
2889 {
2890 emit_insn (gen_rtx_CLOBBER (VOIDmode, operands[0]));
2891 emit_move_insn (gen_highpart (SImode, operands[0]), operands[1]);
2892 emit_move_insn (gen_lowpart (SImode, operands[0]), const0_rtx);
2893 emit_insn (gen_ashrdi3 (operands[0], operands[0], GEN_INT (32)));
2894 DONE;
2895 }
2896 })
2897
2898 (define_insn "*extendsidi2"
2899 [(set (match_operand:DI 0 "register_operand" "=d,d")
2900 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "d,m")))]
2901 "TARGET_64BIT"
2902 "@
2903 lgfr\t%0,%1
2904 lgf\t%0,%1"
2905 [(set_attr "op_type" "RRE,RXY")])
2906
2907 ;
2908 ; extend(hi|qi)(si|di)2 instruction pattern(s).
2909 ;
2910
2911 (define_expand "extend<HQI:mode><DSI:mode>2"
2912 [(set (match_operand:DSI 0 "register_operand" "")
2913 (sign_extend:DSI (match_operand:HQI 1 "nonimmediate_operand" "")))]
2914 ""
2915 {
2916 if (<DSI:MODE>mode == DImode && !TARGET_64BIT)
2917 {
2918 rtx tmp = gen_reg_rtx (SImode);
2919 emit_insn (gen_extend<HQI:mode>si2 (tmp, operands[1]));
2920 emit_insn (gen_extendsidi2 (operands[0], tmp));
2921 DONE;
2922 }
2923 else if (!TARGET_EXTIMM)
2924 {
2925 rtx bitcount = GEN_INT (GET_MODE_BITSIZE (<DSI:MODE>mode) -
2926 GET_MODE_BITSIZE (<HQI:MODE>mode));
2927
2928 operands[1] = gen_lowpart (<DSI:MODE>mode, operands[1]);
2929 emit_insn (gen_ashl<DSI:mode>3 (operands[0], operands[1], bitcount));
2930 emit_insn (gen_ashr<DSI:mode>3 (operands[0], operands[0], bitcount));
2931 DONE;
2932 }
2933 })
2934
2935 ;
2936 ; extendhidi2 instruction pattern(s).
2937 ;
2938
2939 (define_insn "*extendhidi2_extimm"
2940 [(set (match_operand:DI 0 "register_operand" "=d,d")
2941 (sign_extend:DI (match_operand:HI 1 "nonimmediate_operand" "d,m")))]
2942 "TARGET_64BIT && TARGET_EXTIMM"
2943 "@
2944 lghr\t%0,%1
2945 lgh\t%0,%1"
2946 [(set_attr "op_type" "RRE,RXY")])
2947
2948 (define_insn "*extendhidi2"
2949 [(set (match_operand:DI 0 "register_operand" "=d")
2950 (sign_extend:DI (match_operand:HI 1 "memory_operand" "m")))]
2951 "TARGET_64BIT"
2952 "lgh\t%0,%1"
2953 [(set_attr "op_type" "RXY")])
2954
2955 ;
2956 ; extendhisi2 instruction pattern(s).
2957 ;
2958
2959 (define_insn "*extendhisi2_extimm"
2960 [(set (match_operand:SI 0 "register_operand" "=d,d,d")
2961 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "d,R,T")))]
2962 "TARGET_EXTIMM"
2963 "@
2964 lhr\t%0,%1
2965 lh\t%0,%1
2966 lhy\t%0,%1"
2967 [(set_attr "op_type" "RRE,RX,RXY")])
2968
2969 (define_insn "*extendhisi2"
2970 [(set (match_operand:SI 0 "register_operand" "=d,d")
2971 (sign_extend:SI (match_operand:HI 1 "memory_operand" "R,T")))]
2972 "!TARGET_EXTIMM"
2973 "@
2974 lh\t%0,%1
2975 lhy\t%0,%1"
2976 [(set_attr "op_type" "RX,RXY")])
2977
2978 ;
2979 ; extendqi(si|di)2 instruction pattern(s).
2980 ;
2981
2982 ; lbr, lgbr, lb, lgb
2983 (define_insn "*extendqi<mode>2_extimm"
2984 [(set (match_operand:GPR 0 "register_operand" "=d,d")
2985 (sign_extend:GPR (match_operand:QI 1 "nonimmediate_operand" "d,m")))]
2986 "TARGET_EXTIMM"
2987 "@
2988 l<g>br\t%0,%1
2989 l<g>b\t%0,%1"
2990 [(set_attr "op_type" "RRE,RXY")])
2991
2992 ; lb, lgb
2993 (define_insn "*extendqi<mode>2"
2994 [(set (match_operand:GPR 0 "register_operand" "=d")
2995 (sign_extend:GPR (match_operand:QI 1 "memory_operand" "m")))]
2996 "!TARGET_EXTIMM && TARGET_LONG_DISPLACEMENT"
2997 "l<g>b\t%0,%1"
2998 [(set_attr "op_type" "RXY")])
2999
3000 (define_insn_and_split "*extendqi<mode>2_short_displ"
3001 [(set (match_operand:GPR 0 "register_operand" "=d")
3002 (sign_extend:GPR (match_operand:QI 1 "s_operand" "Q")))
3003 (clobber (reg:CC CC_REGNUM))]
3004 "!TARGET_EXTIMM && !TARGET_LONG_DISPLACEMENT"
3005 "#"
3006 "&& reload_completed"
3007 [(parallel
3008 [(set (match_dup 0) (unspec:GPR [(match_dup 1) (const_int 8)] UNSPEC_ICM))
3009 (clobber (reg:CC CC_REGNUM))])
3010 (parallel
3011 [(set (match_dup 0) (ashiftrt:GPR (match_dup 0) (match_dup 2)))
3012 (clobber (reg:CC CC_REGNUM))])]
3013 {
3014 operands[1] = adjust_address (operands[1], BLKmode, 0);
3015 set_mem_size (operands[1], GEN_INT (GET_MODE_SIZE (QImode)));
3016 operands[2] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)
3017 - GET_MODE_BITSIZE (QImode));
3018 })
3019
3020 ;
3021 ; zero_extendsidi2 instruction pattern(s).
3022 ;
3023
3024 (define_expand "zero_extendsidi2"
3025 [(set (match_operand:DI 0 "register_operand" "")
3026 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "")))]
3027 ""
3028 {
3029 if (!TARGET_64BIT)
3030 {
3031 emit_insn (gen_rtx_CLOBBER (VOIDmode, operands[0]));
3032 emit_move_insn (gen_lowpart (SImode, operands[0]), operands[1]);
3033 emit_move_insn (gen_highpart (SImode, operands[0]), const0_rtx);
3034 DONE;
3035 }
3036 })
3037
3038 (define_insn "*zero_extendsidi2"
3039 [(set (match_operand:DI 0 "register_operand" "=d,d")
3040 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "d,m")))]
3041 "TARGET_64BIT"
3042 "@
3043 llgfr\t%0,%1
3044 llgf\t%0,%1"
3045 [(set_attr "op_type" "RRE,RXY")])
3046
3047 ;
3048 ; LLGT-type instructions (zero-extend from 31 bit to 64 bit).
3049 ;
3050
3051 (define_insn "*llgt_sidi"
3052 [(set (match_operand:DI 0 "register_operand" "=d")
3053 (and:DI (subreg:DI (match_operand:SI 1 "memory_operand" "m") 0)
3054 (const_int 2147483647)))]
3055 "TARGET_64BIT"
3056 "llgt\t%0,%1"
3057 [(set_attr "op_type" "RXE")])
3058
3059 (define_insn_and_split "*llgt_sidi_split"
3060 [(set (match_operand:DI 0 "register_operand" "=d")
3061 (and:DI (subreg:DI (match_operand:SI 1 "memory_operand" "m") 0)
3062 (const_int 2147483647)))
3063 (clobber (reg:CC CC_REGNUM))]
3064 "TARGET_64BIT"
3065 "#"
3066 "&& reload_completed"
3067 [(set (match_dup 0)
3068 (and:DI (subreg:DI (match_dup 1) 0)
3069 (const_int 2147483647)))]
3070 "")
3071
3072 (define_insn "*llgt_sisi"
3073 [(set (match_operand:SI 0 "register_operand" "=d,d")
3074 (and:SI (match_operand:SI 1 "nonimmediate_operand" "d,m")
3075 (const_int 2147483647)))]
3076 "TARGET_ZARCH"
3077 "@
3078 llgtr\t%0,%1
3079 llgt\t%0,%1"
3080 [(set_attr "op_type" "RRE,RXE")])
3081
3082 (define_insn "*llgt_didi"
3083 [(set (match_operand:DI 0 "register_operand" "=d,d")
3084 (and:DI (match_operand:DI 1 "nonimmediate_operand" "d,o")
3085 (const_int 2147483647)))]
3086 "TARGET_64BIT"
3087 "@
3088 llgtr\t%0,%1
3089 llgt\t%0,%N1"
3090 [(set_attr "op_type" "RRE,RXE")])
3091
3092 (define_split
3093 [(set (match_operand:GPR 0 "register_operand" "")
3094 (and:GPR (match_operand:GPR 1 "nonimmediate_operand" "")
3095 (const_int 2147483647)))
3096 (clobber (reg:CC CC_REGNUM))]
3097 "TARGET_ZARCH && reload_completed"
3098 [(set (match_dup 0)
3099 (and:GPR (match_dup 1)
3100 (const_int 2147483647)))]
3101 "")
3102
3103 ;
3104 ; zero_extend(hi|qi)(si|di)2 instruction pattern(s).
3105 ;
3106
3107 (define_expand "zero_extend<mode>di2"
3108 [(set (match_operand:DI 0 "register_operand" "")
3109 (zero_extend:DI (match_operand:HQI 1 "nonimmediate_operand" "")))]
3110 ""
3111 {
3112 if (!TARGET_64BIT)
3113 {
3114 rtx tmp = gen_reg_rtx (SImode);
3115 emit_insn (gen_zero_extend<mode>si2 (tmp, operands[1]));
3116 emit_insn (gen_zero_extendsidi2 (operands[0], tmp));
3117 DONE;
3118 }
3119 else if (!TARGET_EXTIMM)
3120 {
3121 rtx bitcount = GEN_INT (GET_MODE_BITSIZE(DImode) -
3122 GET_MODE_BITSIZE(<MODE>mode));
3123 operands[1] = gen_lowpart (DImode, operands[1]);
3124 emit_insn (gen_ashldi3 (operands[0], operands[1], bitcount));
3125 emit_insn (gen_lshrdi3 (operands[0], operands[0], bitcount));
3126 DONE;
3127 }
3128 })
3129
3130 (define_expand "zero_extend<mode>si2"
3131 [(set (match_operand:SI 0 "register_operand" "")
3132 (zero_extend:SI (match_operand:HQI 1 "nonimmediate_operand" "")))]
3133 ""
3134 {
3135 if (!TARGET_EXTIMM)
3136 {
3137 operands[1] = gen_lowpart (SImode, operands[1]);
3138 emit_insn (gen_andsi3 (operands[0], operands[1],
3139 GEN_INT ((1 << GET_MODE_BITSIZE(<MODE>mode)) - 1)));
3140 DONE;
3141 }
3142 })
3143
3144 ; llhr, llcr, llghr, llgcr, llh, llc, llgh, llgc
3145 (define_insn "*zero_extend<HQI:mode><GPR:mode>2_extimm"
3146 [(set (match_operand:GPR 0 "register_operand" "=d,d")
3147 (zero_extend:GPR (match_operand:HQI 1 "nonimmediate_operand" "d,m")))]
3148 "TARGET_EXTIMM"
3149 "@
3150 ll<g><hc>r\t%0,%1
3151 ll<g><hc>\t%0,%1"
3152 [(set_attr "op_type" "RRE,RXY")])
3153
3154 ; llgh, llgc
3155 (define_insn "*zero_extend<HQI:mode><GPR:mode>2"
3156 [(set (match_operand:GPR 0 "register_operand" "=d")
3157 (zero_extend:GPR (match_operand:HQI 1 "memory_operand" "m")))]
3158 "TARGET_ZARCH && !TARGET_EXTIMM"
3159 "llg<hc>\t%0,%1"
3160 [(set_attr "op_type" "RXY")])
3161
3162 (define_insn_and_split "*zero_extendhisi2_31"
3163 [(set (match_operand:SI 0 "register_operand" "=&d")
3164 (zero_extend:SI (match_operand:HI 1 "s_operand" "QS")))
3165 (clobber (reg:CC CC_REGNUM))]
3166 "!TARGET_ZARCH"
3167 "#"
3168 "&& reload_completed"
3169 [(set (match_dup 0) (const_int 0))
3170 (parallel
3171 [(set (strict_low_part (match_dup 2)) (match_dup 1))
3172 (clobber (reg:CC CC_REGNUM))])]
3173 "operands[2] = gen_lowpart (HImode, operands[0]);")
3174
3175 (define_insn_and_split "*zero_extendqisi2_31"
3176 [(set (match_operand:SI 0 "register_operand" "=&d")
3177 (zero_extend:SI (match_operand:QI 1 "memory_operand" "m")))]
3178 "!TARGET_ZARCH"
3179 "#"
3180 "&& reload_completed"
3181 [(set (match_dup 0) (const_int 0))
3182 (set (strict_low_part (match_dup 2)) (match_dup 1))]
3183 "operands[2] = gen_lowpart (QImode, operands[0]);")
3184
3185 ;
3186 ; zero_extendqihi2 instruction pattern(s).
3187 ;
3188
3189 (define_expand "zero_extendqihi2"
3190 [(set (match_operand:HI 0 "register_operand" "")
3191 (zero_extend:HI (match_operand:QI 1 "register_operand" "")))]
3192 "TARGET_ZARCH && !TARGET_EXTIMM"
3193 {
3194 operands[1] = gen_lowpart (HImode, operands[1]);
3195 emit_insn (gen_andhi3 (operands[0], operands[1], GEN_INT (0xff)));
3196 DONE;
3197 })
3198
3199 (define_insn "*zero_extendqihi2_64"
3200 [(set (match_operand:HI 0 "register_operand" "=d")
3201 (zero_extend:HI (match_operand:QI 1 "memory_operand" "m")))]
3202 "TARGET_ZARCH && !TARGET_EXTIMM"
3203 "llgc\t%0,%1"
3204 [(set_attr "op_type" "RXY")])
3205
3206 (define_insn_and_split "*zero_extendqihi2_31"
3207 [(set (match_operand:HI 0 "register_operand" "=&d")
3208 (zero_extend:HI (match_operand:QI 1 "memory_operand" "m")))]
3209 "!TARGET_ZARCH"
3210 "#"
3211 "&& reload_completed"
3212 [(set (match_dup 0) (const_int 0))
3213 (set (strict_low_part (match_dup 2)) (match_dup 1))]
3214 "operands[2] = gen_lowpart (QImode, operands[0]);")
3215
3216 ;
3217 ; fixuns_trunc(dd|td)di2 instruction pattern(s).
3218 ;
3219
3220 (define_expand "fixuns_truncdddi2"
3221 [(parallel
3222 [(set (match_operand:DI 0 "register_operand" "")
3223 (unsigned_fix:DI (match_operand:DD 1 "register_operand" "")))
3224 (clobber (match_scratch:TD 2 "=f"))])]
3225
3226 "TARGET_HARD_FLOAT && TARGET_HARD_DFP"
3227 {
3228 rtx label1 = gen_label_rtx ();
3229 rtx label2 = gen_label_rtx ();
3230 rtx temp = gen_reg_rtx (TDmode);
3231 REAL_VALUE_TYPE cmp, sub;
3232
3233 decimal_real_from_string (&cmp, "9223372036854775808.0"); /* 2^63 */
3234 decimal_real_from_string (&sub, "18446744073709551616.0"); /* 2^64 */
3235
3236 /* 2^63 can't be represented as 64bit DFP number with full precision. The
3237 solution is doing the check and the subtraction in TD mode and using a
3238 TD -> DI convert afterwards. */
3239 emit_insn (gen_extendddtd2 (temp, operands[1]));
3240 temp = force_reg (TDmode, temp);
3241 emit_insn (gen_cmptd (temp,
3242 CONST_DOUBLE_FROM_REAL_VALUE (cmp, TDmode)));
3243 emit_jump_insn (gen_blt (label1));
3244 emit_insn (gen_subtd3 (temp, temp,
3245 CONST_DOUBLE_FROM_REAL_VALUE (sub, TDmode)));
3246 emit_insn (gen_fix_trunctddi2_dfp (operands[0], temp, GEN_INT (11)));
3247 emit_jump (label2);
3248
3249 emit_label (label1);
3250 emit_insn (gen_fix_truncdddi2_dfp (operands[0], operands[1], GEN_INT (9)));
3251 emit_label (label2);
3252 DONE;
3253 })
3254
3255 (define_expand "fixuns_trunctddi2"
3256 [(set (match_operand:DI 0 "register_operand" "")
3257 (unsigned_fix:DI (match_operand:TD 1 "register_operand" "")))]
3258 "TARGET_HARD_FLOAT && TARGET_HARD_DFP"
3259 {
3260 rtx label1 = gen_label_rtx ();
3261 rtx label2 = gen_label_rtx ();
3262 rtx temp = gen_reg_rtx (TDmode);
3263 REAL_VALUE_TYPE cmp, sub;
3264
3265 operands[1] = force_reg (TDmode, operands[1]);
3266 decimal_real_from_string (&cmp, "9223372036854775808.0"); /* 2^63 */
3267 decimal_real_from_string (&sub, "18446744073709551616.0"); /* 2^64 */
3268
3269 emit_insn (gen_cmptd (operands[1],
3270 CONST_DOUBLE_FROM_REAL_VALUE (cmp, TDmode)));
3271 emit_jump_insn (gen_blt (label1));
3272 emit_insn (gen_subtd3 (temp, operands[1],
3273 CONST_DOUBLE_FROM_REAL_VALUE (sub, TDmode)));
3274 emit_insn (gen_fix_trunctddi2_dfp (operands[0], temp, GEN_INT (11)));
3275 emit_jump (label2);
3276
3277 emit_label (label1);
3278 emit_insn (gen_fix_trunctddi2_dfp (operands[0], operands[1], GEN_INT (9)));
3279 emit_label (label2);
3280 DONE;
3281 })
3282
3283 ;
3284 ; fixuns_trunc(sf|df)(si|di)2 and fix_trunc(sf|df)(si|di)2
3285 ; instruction pattern(s).
3286 ;
3287
3288 (define_expand "fixuns_trunc<BFP:mode><GPR:mode>2"
3289 [(set (match_operand:GPR 0 "register_operand" "")
3290 (unsigned_fix:GPR (match_operand:BFP 1 "register_operand" "")))]
3291 "TARGET_HARD_FLOAT"
3292 {
3293 rtx label1 = gen_label_rtx ();
3294 rtx label2 = gen_label_rtx ();
3295 rtx temp = gen_reg_rtx (<BFP:MODE>mode);
3296 REAL_VALUE_TYPE cmp, sub;
3297
3298 operands[1] = force_reg (<BFP:MODE>mode, operands[1]);
3299 real_2expN (&cmp, GET_MODE_BITSIZE(<GPR:MODE>mode) - 1);
3300 real_2expN (&sub, GET_MODE_BITSIZE(<GPR:MODE>mode));
3301
3302 emit_insn (gen_cmp<BFP:mode> (operands[1],
3303 CONST_DOUBLE_FROM_REAL_VALUE (cmp, <BFP:MODE>mode)));
3304 emit_jump_insn (gen_blt (label1));
3305 emit_insn (gen_sub<BFP:mode>3 (temp, operands[1],
3306 CONST_DOUBLE_FROM_REAL_VALUE (sub, <BFP:MODE>mode)));
3307 emit_insn (gen_fix_trunc<BFP:mode><GPR:mode>2_bfp (operands[0], temp,
3308 GEN_INT (7)));
3309 emit_jump (label2);
3310
3311 emit_label (label1);
3312 emit_insn (gen_fix_trunc<BFP:mode><GPR:mode>2_bfp (operands[0],
3313 operands[1], GEN_INT (5)));
3314 emit_label (label2);
3315 DONE;
3316 })
3317
3318 (define_expand "fix_trunc<DSF:mode><GPR:mode>2"
3319 [(set (match_operand:GPR 0 "register_operand" "")
3320 (fix:GPR (match_operand:DSF 1 "register_operand" "")))]
3321 "TARGET_HARD_FLOAT"
3322 {
3323 emit_insn (gen_fix_trunc<DSF:mode><GPR:mode>2_bfp (operands[0], operands[1],
3324 GEN_INT (5)));
3325 DONE;
3326 })
3327
3328 ; cgxbr, cgdbr, cgebr, cfxbr, cfdbr, cfebr
3329 (define_insn "fix_trunc<BFP:mode><GPR:mode>2_bfp"
3330 [(set (match_operand:GPR 0 "register_operand" "=d")
3331 (fix:GPR (match_operand:BFP 1 "register_operand" "f")))
3332 (unspec:GPR [(match_operand:GPR 2 "immediate_operand" "K")] UNSPEC_ROUND)
3333 (clobber (reg:CC CC_REGNUM))]
3334 "TARGET_HARD_FLOAT"
3335 "c<GPR:gf><BFP:xde>br\t%0,%h2,%1"
3336 [(set_attr "op_type" "RRE")
3337 (set_attr "type" "ftoi")])
3338
3339
3340 ;
3341 ; fix_trunc(td|dd)di2 instruction pattern(s).
3342 ;
3343
3344 (define_expand "fix_trunc<mode>di2"
3345 [(set (match_operand:DI 0 "register_operand" "")
3346 (fix:DI (match_operand:DFP 1 "nonimmediate_operand" "")))]
3347 "TARGET_64BIT && TARGET_HARD_FLOAT && TARGET_HARD_DFP"
3348 {
3349 operands[1] = force_reg (<MODE>mode, operands[1]);
3350 emit_insn (gen_fix_trunc<mode>di2_dfp (operands[0], operands[1],
3351 GEN_INT (9)));
3352 DONE;
3353 })
3354
3355 ; cgxtr, cgdtr
3356 (define_insn "fix_trunc<DFP:mode>di2_dfp"
3357 [(set (match_operand:DI 0 "register_operand" "=d")
3358 (fix:DI (match_operand:DFP 1 "register_operand" "f")))
3359 (unspec:DI [(match_operand:DI 2 "immediate_operand" "K")] UNSPEC_ROUND)
3360 (clobber (reg:CC CC_REGNUM))]
3361 "TARGET_64BIT && TARGET_HARD_FLOAT && TARGET_HARD_DFP"
3362 "cg<DFP:xde>tr\t%0,%h2,%1"
3363 [(set_attr "op_type" "RRF")
3364 (set_attr "type" "ftoi")])
3365
3366
3367 ;
3368 ; fix_trunctf(si|di)2 instruction pattern(s).
3369 ;
3370
3371 (define_expand "fix_trunctf<mode>2"
3372 [(parallel [(set (match_operand:GPR 0 "register_operand" "")
3373 (fix:GPR (match_operand:TF 1 "register_operand" "")))
3374 (unspec:GPR [(const_int 5)] UNSPEC_ROUND)
3375 (clobber (reg:CC CC_REGNUM))])]
3376 "TARGET_HARD_FLOAT"
3377 "")
3378
3379
3380 ;
3381 ; float(si|di)(tf|df|sf|td|dd)2 instruction pattern(s).
3382 ;
3383
3384 ; cxgbr, cdgbr, cegbr, cxgtr, cdgtr
3385 (define_insn "floatdi<mode>2"
3386 [(set (match_operand:FP 0 "register_operand" "=f")
3387 (float:FP (match_operand:DI 1 "register_operand" "d")))]
3388 "TARGET_64BIT && TARGET_HARD_FLOAT"
3389 "c<xde>g<bt>r\t%0,%1"
3390 [(set_attr "op_type" "RRE")
3391 (set_attr "type" "itof" )])
3392
3393 ; cxfbr, cdfbr, cefbr
3394 (define_insn "floatsi<mode>2"
3395 [(set (match_operand:BFP 0 "register_operand" "=f")
3396 (float:BFP (match_operand:SI 1 "register_operand" "d")))]
3397 "TARGET_HARD_FLOAT"
3398 "c<xde>fbr\t%0,%1"
3399 [(set_attr "op_type" "RRE")
3400 (set_attr "type" "itof" )])
3401
3402
3403 ;
3404 ; truncdfsf2 instruction pattern(s).
3405 ;
3406
3407 (define_insn "truncdfsf2"
3408 [(set (match_operand:SF 0 "register_operand" "=f")
3409 (float_truncate:SF (match_operand:DF 1 "register_operand" "f")))]
3410 "TARGET_HARD_FLOAT"
3411 "ledbr\t%0,%1"
3412 [(set_attr "op_type" "RRE")
3413 (set_attr "type" "ftruncdf")])
3414
3415 ;
3416 ; trunctf(df|sf)2 instruction pattern(s).
3417 ;
3418
3419 ; ldxbr, lexbr
3420 (define_insn "trunctf<mode>2"
3421 [(set (match_operand:DSF 0 "register_operand" "=f")
3422 (float_truncate:DSF (match_operand:TF 1 "register_operand" "f")))
3423 (clobber (match_scratch:TF 2 "=f"))]
3424 "TARGET_HARD_FLOAT"
3425 "l<xde>xbr\t%2,%1\;l<xde>r\t%0,%2"
3426 [(set_attr "length" "6")
3427 (set_attr "type" "ftrunctf")])
3428
3429 ;
3430 ; trunctddd2 and truncddsd2 instruction pattern(s).
3431 ;
3432
3433 (define_insn "trunctddd2"
3434 [(set (match_operand:DD 0 "register_operand" "=f")
3435 (float_truncate:DD (match_operand:TD 1 "register_operand" "f")))
3436 (clobber (match_scratch:TD 2 "=f"))]
3437 "TARGET_HARD_FLOAT && TARGET_HARD_DFP"
3438 "ldxtr\t%2,0,%1,0\;ldr\t%0,%2"
3439 [(set_attr "length" "6")
3440 (set_attr "type" "ftrunctf")])
3441
3442 (define_insn "truncddsd2"
3443 [(set (match_operand:SD 0 "register_operand" "=f")
3444 (float_truncate:SD (match_operand:DD 1 "register_operand" "f")))]
3445 "TARGET_HARD_FLOAT && TARGET_HARD_DFP"
3446 "ledtr\t%0,0,%1,0"
3447 [(set_attr "op_type" "RRF")
3448 (set_attr "type" "fsimptf")])
3449
3450 ;
3451 ; extend(sf|df)(df|tf)2 instruction pattern(s).
3452 ;
3453
3454 ; ldebr, ldeb, lxdbr, lxdb, lxebr, lxeb
3455 (define_insn "extend<DSF:mode><BFP:mode>2"
3456 [(set (match_operand:BFP 0 "register_operand" "=f,f")
3457 (float_extend:BFP (match_operand:DSF 1 "nonimmediate_operand" "f,R")))]
3458 "TARGET_HARD_FLOAT
3459 && GET_MODE_SIZE (<BFP:MODE>mode) > GET_MODE_SIZE (<DSF:MODE>mode)"
3460 "@
3461 l<BFP:xde><DSF:xde>br\t%0,%1
3462 l<BFP:xde><DSF:xde>b\t%0,%1"
3463 [(set_attr "op_type" "RRE,RXE")
3464 (set_attr "type" "fsimp<BFP:mode>, fload<BFP:mode>")])
3465
3466 ;
3467 ; extendddtd2 and extendsddd2 instruction pattern(s).
3468 ;
3469
3470 (define_insn "extendddtd2"
3471 [(set (match_operand:TD 0 "register_operand" "=f")
3472 (float_extend:TD (match_operand:DD 1 "register_operand" "f")))]
3473 "TARGET_HARD_FLOAT && TARGET_HARD_DFP"
3474 "lxdtr\t%0,%1,0"
3475 [(set_attr "op_type" "RRF")
3476 (set_attr "type" "fsimptf")])
3477
3478 (define_insn "extendsddd2"
3479 [(set (match_operand:DD 0 "register_operand" "=f")
3480 (float_extend:DD (match_operand:SD 1 "register_operand" "f")))]
3481 "TARGET_HARD_FLOAT && TARGET_HARD_DFP"
3482 "ldetr\t%0,%1,0"
3483 [(set_attr "op_type" "RRF")
3484 (set_attr "type" "fsimptf")])
3485
3486 ; Binary <-> Decimal floating point trunc patterns
3487 ;
3488
3489 (define_insn "*trunc<BFP:mode><DFP_ALL:mode>2"
3490 [(set (reg:DFP_ALL FPR0_REGNUM)
3491 (float_truncate:DFP_ALL (reg:BFP FPR2_REGNUM)))
3492 (use (reg:SI GPR0_REGNUM))
3493 (clobber (reg:CC CC_REGNUM))]
3494 "TARGET_HARD_FLOAT && TARGET_DFP"
3495 "pfpo")
3496
3497 (define_insn "*trunc<DFP_ALL:mode><BFP:mode>2"
3498 [(set (reg:BFP FPR0_REGNUM)
3499 (float_truncate:BFP (reg:DFP_ALL FPR2_REGNUM)))
3500 (use (reg:SI GPR0_REGNUM))
3501 (clobber (reg:CC CC_REGNUM))]
3502 "TARGET_HARD_FLOAT && TARGET_DFP"
3503 "pfpo")
3504
3505 (define_expand "trunc<BFP:mode><DFP_ALL:mode>2"
3506 [(set (reg:BFP FPR2_REGNUM) (match_operand:BFP 1 "nonimmediate_operand" ""))
3507 (set (reg:SI GPR0_REGNUM) (match_dup 2))
3508 (parallel
3509 [(set (reg:DFP_ALL FPR0_REGNUM)
3510 (float_truncate:DFP_ALL (reg:BFP FPR2_REGNUM)))
3511 (use (reg:SI GPR0_REGNUM))
3512 (clobber (reg:CC CC_REGNUM))])
3513 (set (match_operand:DFP_ALL 0 "nonimmediate_operand" "")
3514 (reg:DFP_ALL FPR0_REGNUM))]
3515 "TARGET_HARD_FLOAT && TARGET_DFP
3516 && GET_MODE_SIZE (<BFP:MODE>mode) > GET_MODE_SIZE (<DFP_ALL:MODE>mode)"
3517 {
3518 HOST_WIDE_INT flags;
3519
3520 flags = (PFPO_CONVERT |
3521 PFPO_OP_TYPE_<DFP_ALL:MODE> << PFPO_OP0_TYPE_SHIFT |
3522 PFPO_OP_TYPE_<BFP:MODE> << PFPO_OP1_TYPE_SHIFT);
3523
3524 operands[2] = GEN_INT (flags);
3525 })
3526
3527 (define_expand "trunc<DFP_ALL:mode><BFP:mode>2"
3528 [(set (reg:DFP_ALL FPR2_REGNUM)
3529 (match_operand:DFP_ALL 1 "nonimmediate_operand" ""))
3530 (set (reg:SI GPR0_REGNUM) (match_dup 2))
3531 (parallel
3532 [(set (reg:BFP FPR0_REGNUM) (float_truncate:BFP (reg:DFP_ALL FPR2_REGNUM)))
3533 (use (reg:SI GPR0_REGNUM))
3534 (clobber (reg:CC CC_REGNUM))])
3535 (set (match_operand:BFP 0 "nonimmediate_operand" "") (reg:BFP FPR0_REGNUM))]
3536 "TARGET_HARD_FLOAT && TARGET_DFP
3537 && GET_MODE_SIZE (<DFP_ALL:MODE>mode) >= GET_MODE_SIZE (<BFP:MODE>mode)"
3538 {
3539 HOST_WIDE_INT flags;
3540
3541 flags = (PFPO_CONVERT |
3542 PFPO_OP_TYPE_<BFP:MODE> << PFPO_OP0_TYPE_SHIFT |
3543 PFPO_OP_TYPE_<DFP_ALL:MODE> << PFPO_OP1_TYPE_SHIFT);
3544
3545 operands[2] = GEN_INT (flags);
3546 })
3547
3548 ;
3549 ; Binary <-> Decimal floating point extend patterns
3550 ;
3551
3552 (define_insn "*extend<BFP:mode><DFP_ALL:mode>2"
3553 [(set (reg:DFP_ALL FPR0_REGNUM) (float_extend:DFP_ALL (reg:BFP FPR2_REGNUM)))
3554 (use (reg:SI GPR0_REGNUM))
3555 (clobber (reg:CC CC_REGNUM))]
3556 "TARGET_HARD_FLOAT && TARGET_DFP"
3557 "pfpo")
3558
3559 (define_insn "*extend<DFP_ALL:mode><BFP:mode>2"
3560 [(set (reg:BFP FPR0_REGNUM) (float_extend:BFP (reg:DFP_ALL FPR2_REGNUM)))
3561 (use (reg:SI GPR0_REGNUM))
3562 (clobber (reg:CC CC_REGNUM))]
3563 "TARGET_HARD_FLOAT && TARGET_DFP"
3564 "pfpo")
3565
3566 (define_expand "extend<BFP:mode><DFP_ALL:mode>2"
3567 [(set (reg:BFP FPR2_REGNUM) (match_operand:BFP 1 "nonimmediate_operand" ""))
3568 (set (reg:SI GPR0_REGNUM) (match_dup 2))
3569 (parallel
3570 [(set (reg:DFP_ALL FPR0_REGNUM)
3571 (float_extend:DFP_ALL (reg:BFP FPR2_REGNUM)))
3572 (use (reg:SI GPR0_REGNUM))
3573 (clobber (reg:CC CC_REGNUM))])
3574 (set (match_operand:DFP_ALL 0 "nonimmediate_operand" "")
3575 (reg:DFP_ALL FPR0_REGNUM))]
3576 "TARGET_HARD_FLOAT && TARGET_DFP
3577 && GET_MODE_SIZE (<BFP:MODE>mode) <= GET_MODE_SIZE (<DFP_ALL:MODE>mode)"
3578 {
3579 HOST_WIDE_INT flags;
3580
3581 flags = (PFPO_CONVERT |
3582 PFPO_OP_TYPE_<DFP_ALL:MODE> << PFPO_OP0_TYPE_SHIFT |
3583 PFPO_OP_TYPE_<BFP:MODE> << PFPO_OP1_TYPE_SHIFT);
3584
3585 operands[2] = GEN_INT (flags);
3586 })
3587
3588 (define_expand "extend<DFP_ALL:mode><BFP:mode>2"
3589 [(set (reg:DFP_ALL FPR2_REGNUM)
3590 (match_operand:DFP_ALL 1 "nonimmediate_operand" ""))
3591 (set (reg:SI GPR0_REGNUM) (match_dup 2))
3592 (parallel
3593 [(set (reg:BFP FPR0_REGNUM) (float_extend:BFP (reg:DFP_ALL FPR2_REGNUM)))
3594 (use (reg:SI GPR0_REGNUM))
3595 (clobber (reg:CC CC_REGNUM))])
3596 (set (match_operand:BFP 0 "nonimmediate_operand" "") (reg:BFP FPR0_REGNUM))]
3597 "TARGET_HARD_FLOAT && TARGET_DFP
3598 && GET_MODE_SIZE (<DFP_ALL:MODE>mode) < GET_MODE_SIZE (<BFP:MODE>mode)"
3599 {
3600 HOST_WIDE_INT flags;
3601
3602 flags = (PFPO_CONVERT |
3603 PFPO_OP_TYPE_<BFP:MODE> << PFPO_OP0_TYPE_SHIFT |
3604 PFPO_OP_TYPE_<DFP_ALL:MODE> << PFPO_OP1_TYPE_SHIFT);
3605
3606 operands[2] = GEN_INT (flags);
3607 })
3608
3609
3610 ;;
3611 ;; ARITHMETIC OPERATIONS
3612 ;;
3613 ; arithmetic operations set the ConditionCode,
3614 ; because of unpredictable Bits in Register for Halfword and Byte
3615 ; the ConditionCode can be set wrong in operations for Halfword and Byte
3616
3617 ;;
3618 ;;- Add instructions.
3619 ;;
3620
3621 ;
3622 ; addti3 instruction pattern(s).
3623 ;
3624
3625 (define_insn_and_split "addti3"
3626 [(set (match_operand:TI 0 "register_operand" "=&d")
3627 (plus:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
3628 (match_operand:TI 2 "general_operand" "do") ) )
3629 (clobber (reg:CC CC_REGNUM))]
3630 "TARGET_64BIT"
3631 "#"
3632 "&& reload_completed"
3633 [(parallel
3634 [(set (reg:CCL1 CC_REGNUM)
3635 (compare:CCL1 (plus:DI (match_dup 7) (match_dup 8))
3636 (match_dup 7)))
3637 (set (match_dup 6) (plus:DI (match_dup 7) (match_dup 8)))])
3638 (parallel
3639 [(set (match_dup 3) (plus:DI (plus:DI (match_dup 4) (match_dup 5))
3640 (ltu:DI (reg:CCL1 CC_REGNUM) (const_int 0))))
3641 (clobber (reg:CC CC_REGNUM))])]
3642 "operands[3] = operand_subword (operands[0], 0, 0, TImode);
3643 operands[4] = operand_subword (operands[1], 0, 0, TImode);
3644 operands[5] = operand_subword (operands[2], 0, 0, TImode);
3645 operands[6] = operand_subword (operands[0], 1, 0, TImode);
3646 operands[7] = operand_subword (operands[1], 1, 0, TImode);
3647 operands[8] = operand_subword (operands[2], 1, 0, TImode);")
3648
3649 ;
3650 ; adddi3 instruction pattern(s).
3651 ;
3652
3653 (define_expand "adddi3"
3654 [(parallel
3655 [(set (match_operand:DI 0 "register_operand" "")
3656 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
3657 (match_operand:DI 2 "general_operand" "")))
3658 (clobber (reg:CC CC_REGNUM))])]
3659 ""
3660 "")
3661
3662 (define_insn "*adddi3_sign"
3663 [(set (match_operand:DI 0 "register_operand" "=d,d")
3664 (plus:DI (sign_extend:DI (match_operand:SI 2 "general_operand" "d,m"))
3665 (match_operand:DI 1 "register_operand" "0,0")))
3666 (clobber (reg:CC CC_REGNUM))]
3667 "TARGET_64BIT"
3668 "@
3669 agfr\t%0,%2
3670 agf\t%0,%2"
3671 [(set_attr "op_type" "RRE,RXY")])
3672
3673 (define_insn "*adddi3_zero_cc"
3674 [(set (reg CC_REGNUM)
3675 (compare (plus:DI (zero_extend:DI (match_operand:SI 2 "general_operand" "d,m"))
3676 (match_operand:DI 1 "register_operand" "0,0"))
3677 (const_int 0)))
3678 (set (match_operand:DI 0 "register_operand" "=d,d")
3679 (plus:DI (zero_extend:DI (match_dup 2)) (match_dup 1)))]
3680 "s390_match_ccmode (insn, CCLmode) && TARGET_64BIT"
3681 "@
3682 algfr\t%0,%2
3683 algf\t%0,%2"
3684 [(set_attr "op_type" "RRE,RXY")])
3685
3686 (define_insn "*adddi3_zero_cconly"
3687 [(set (reg CC_REGNUM)
3688 (compare (plus:DI (zero_extend:DI (match_operand:SI 2 "general_operand" "d,m"))
3689 (match_operand:DI 1 "register_operand" "0,0"))
3690 (const_int 0)))
3691 (clobber (match_scratch:DI 0 "=d,d"))]
3692 "s390_match_ccmode (insn, CCLmode) && TARGET_64BIT"
3693 "@
3694 algfr\t%0,%2
3695 algf\t%0,%2"
3696 [(set_attr "op_type" "RRE,RXY")])
3697
3698 (define_insn "*adddi3_zero"
3699 [(set (match_operand:DI 0 "register_operand" "=d,d")
3700 (plus:DI (zero_extend:DI (match_operand:SI 2 "general_operand" "d,m"))
3701 (match_operand:DI 1 "register_operand" "0,0")))
3702 (clobber (reg:CC CC_REGNUM))]
3703 "TARGET_64BIT"
3704 "@
3705 algfr\t%0,%2
3706 algf\t%0,%2"
3707 [(set_attr "op_type" "RRE,RXY")])
3708
3709 (define_insn_and_split "*adddi3_31z"
3710 [(set (match_operand:DI 0 "register_operand" "=&d")
3711 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
3712 (match_operand:DI 2 "general_operand" "do") ) )
3713 (clobber (reg:CC CC_REGNUM))]
3714 "!TARGET_64BIT && TARGET_CPU_ZARCH"
3715 "#"
3716 "&& reload_completed"
3717 [(parallel
3718 [(set (reg:CCL1 CC_REGNUM)
3719 (compare:CCL1 (plus:SI (match_dup 7) (match_dup 8))
3720 (match_dup 7)))
3721 (set (match_dup 6) (plus:SI (match_dup 7) (match_dup 8)))])
3722 (parallel
3723 [(set (match_dup 3) (plus:SI (plus:SI (match_dup 4) (match_dup 5))
3724 (ltu:SI (reg:CCL1 CC_REGNUM) (const_int 0))))
3725 (clobber (reg:CC CC_REGNUM))])]
3726 "operands[3] = operand_subword (operands[0], 0, 0, DImode);
3727 operands[4] = operand_subword (operands[1], 0, 0, DImode);
3728 operands[5] = operand_subword (operands[2], 0, 0, DImode);
3729 operands[6] = operand_subword (operands[0], 1, 0, DImode);
3730 operands[7] = operand_subword (operands[1], 1, 0, DImode);
3731 operands[8] = operand_subword (operands[2], 1, 0, DImode);")
3732
3733 (define_insn_and_split "*adddi3_31"
3734 [(set (match_operand:DI 0 "register_operand" "=&d")
3735 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
3736 (match_operand:DI 2 "general_operand" "do") ) )
3737 (clobber (reg:CC CC_REGNUM))]
3738 "!TARGET_CPU_ZARCH"
3739 "#"
3740 "&& reload_completed"
3741 [(parallel
3742 [(set (match_dup 3) (plus:SI (match_dup 4) (match_dup 5)))
3743 (clobber (reg:CC CC_REGNUM))])
3744 (parallel
3745 [(set (reg:CCL1 CC_REGNUM)
3746 (compare:CCL1 (plus:SI (match_dup 7) (match_dup 8))
3747 (match_dup 7)))
3748 (set (match_dup 6) (plus:SI (match_dup 7) (match_dup 8)))])
3749 (set (pc)
3750 (if_then_else (ltu (reg:CCL1 CC_REGNUM) (const_int 0))
3751 (pc)
3752 (label_ref (match_dup 9))))
3753 (parallel
3754 [(set (match_dup 3) (plus:SI (match_dup 3) (const_int 1)))
3755 (clobber (reg:CC CC_REGNUM))])
3756 (match_dup 9)]
3757 "operands[3] = operand_subword (operands[0], 0, 0, DImode);
3758 operands[4] = operand_subword (operands[1], 0, 0, DImode);
3759 operands[5] = operand_subword (operands[2], 0, 0, DImode);
3760 operands[6] = operand_subword (operands[0], 1, 0, DImode);
3761 operands[7] = operand_subword (operands[1], 1, 0, DImode);
3762 operands[8] = operand_subword (operands[2], 1, 0, DImode);
3763 operands[9] = gen_label_rtx ();")
3764
3765 ;
3766 ; addsi3 instruction pattern(s).
3767 ;
3768
3769 (define_expand "addsi3"
3770 [(parallel
3771 [(set (match_operand:SI 0 "register_operand" "")
3772 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "")
3773 (match_operand:SI 2 "general_operand" "")))
3774 (clobber (reg:CC CC_REGNUM))])]
3775 ""
3776 "")
3777
3778 (define_insn "*addsi3_sign"
3779 [(set (match_operand:SI 0 "register_operand" "=d,d")
3780 (plus:SI (sign_extend:SI (match_operand:HI 2 "memory_operand" "R,T"))
3781 (match_operand:SI 1 "register_operand" "0,0")))
3782 (clobber (reg:CC CC_REGNUM))]
3783 ""
3784 "@
3785 ah\t%0,%2
3786 ahy\t%0,%2"
3787 [(set_attr "op_type" "RX,RXY")])
3788
3789 ;
3790 ; add(di|si)3 instruction pattern(s).
3791 ;
3792
3793 ; ar, ahi, alfi, slfi, a, ay, agr, aghi, algfi, slgfi, ag
3794 (define_insn "*add<mode>3"
3795 [(set (match_operand:GPR 0 "register_operand" "=d,d,d,d,d,d")
3796 (plus:GPR (match_operand:GPR 1 "nonimmediate_operand" "%0,0,0,0,0,0")
3797 (match_operand:GPR 2 "general_operand" "d,K,Op,On,R,T") ) )
3798 (clobber (reg:CC CC_REGNUM))]
3799 ""
3800 "@
3801 a<g>r\t%0,%2
3802 a<g>hi\t%0,%h2
3803 al<g>fi\t%0,%2
3804 sl<g>fi\t%0,%n2
3805 a<g>\t%0,%2
3806 a<y>\t%0,%2"
3807 [(set_attr "op_type" "RR<E>,RI,RIL,RIL,RX<Y>,RXY")])
3808
3809 ; alr, alfi, slfi, al, aly, algr, algfi, slgfi, alg
3810 (define_insn "*add<mode>3_carry1_cc"
3811 [(set (reg CC_REGNUM)
3812 (compare (plus:GPR (match_operand:GPR 1 "nonimmediate_operand" "%0,0,0,0,0")
3813 (match_operand:GPR 2 "general_operand" "d,Op,On,R,T"))
3814 (match_dup 1)))
3815 (set (match_operand:GPR 0 "register_operand" "=d,d,d,d,d")
3816 (plus:GPR (match_dup 1) (match_dup 2)))]
3817 "s390_match_ccmode (insn, CCL1mode)"
3818 "@
3819 al<g>r\t%0,%2
3820 al<g>fi\t%0,%2
3821 sl<g>fi\t%0,%n2
3822 al<g>\t%0,%2
3823 al<y>\t%0,%2"
3824 [(set_attr "op_type" "RR<E>,RIL,RIL,RX<Y>,RXY")])
3825
3826 ; alr, al, aly, algr, alg
3827 (define_insn "*add<mode>3_carry1_cconly"
3828 [(set (reg CC_REGNUM)
3829 (compare (plus:GPR (match_operand:GPR 1 "nonimmediate_operand" "%0,0,0")
3830 (match_operand:GPR 2 "general_operand" "d,R,T"))
3831 (match_dup 1)))
3832 (clobber (match_scratch:GPR 0 "=d,d,d"))]
3833 "s390_match_ccmode (insn, CCL1mode)"
3834 "@
3835 al<g>r\t%0,%2
3836 al<g>\t%0,%2
3837 al<y>\t%0,%2"
3838 [(set_attr "op_type" "RR<E>,RX<Y>,RXY")])
3839
3840 ; alr, alfi, slfi, al, aly, algr, algfi, slgfi, alg
3841 (define_insn "*add<mode>3_carry2_cc"
3842 [(set (reg CC_REGNUM)
3843 (compare (plus:GPR (match_operand:GPR 1 "nonimmediate_operand" "%0,0,0,0,0")
3844 (match_operand:GPR 2 "general_operand" "d,Op,On,R,T"))
3845 (match_dup 2)))
3846 (set (match_operand:GPR 0 "register_operand" "=d,d,d,d,d")
3847 (plus:GPR (match_dup 1) (match_dup 2)))]
3848 "s390_match_ccmode (insn, CCL1mode)"
3849 "@
3850 al<g>r\t%0,%2
3851 al<g>fi\t%0,%2
3852 sl<g>fi\t%0,%n2
3853 al<g>\t%0,%2
3854 al<y>\t%0,%2"
3855 [(set_attr "op_type" "RR<E>,RIL,RIL,RX<Y>,RXY")])
3856
3857 ; alr, al, aly, algr, alg
3858 (define_insn "*add<mode>3_carry2_cconly"
3859 [(set (reg CC_REGNUM)
3860 (compare (plus:GPR (match_operand:GPR 1 "nonimmediate_operand" "%0,0,0")
3861 (match_operand:GPR 2 "general_operand" "d,R,T"))
3862 (match_dup 2)))
3863 (clobber (match_scratch:GPR 0 "=d,d,d"))]
3864 "s390_match_ccmode (insn, CCL1mode)"
3865 "@
3866 al<g>r\t%0,%2
3867 al<g>\t%0,%2
3868 al<y>\t%0,%2"
3869 [(set_attr "op_type" "RR<E>,RX<Y>,RXY")])
3870
3871 ; alr, alfi, slfi, al, aly, algr, algfi, slgfi, alg
3872 (define_insn "*add<mode>3_cc"
3873 [(set (reg CC_REGNUM)
3874 (compare (plus:GPR (match_operand:GPR 1 "nonimmediate_operand" "%0,0,0,0,0")
3875 (match_operand:GPR 2 "general_operand" "d,Op,On,R,T"))
3876 (const_int 0)))
3877 (set (match_operand:GPR 0 "register_operand" "=d,d,d,d,d")
3878 (plus:GPR (match_dup 1) (match_dup 2)))]
3879 "s390_match_ccmode (insn, CCLmode)"
3880 "@
3881 al<g>r\t%0,%2
3882 al<g>fi\t%0,%2
3883 sl<g>fi\t%0,%n2
3884 al<g>\t%0,%2
3885 al<y>\t%0,%2"
3886 [(set_attr "op_type" "RR<E>,RIL,RIL,RX<Y>,RXY")])
3887
3888 ; alr, al, aly, algr, alg
3889 (define_insn "*add<mode>3_cconly"
3890 [(set (reg CC_REGNUM)
3891 (compare (plus:GPR (match_operand:GPR 1 "nonimmediate_operand" "%0,0,0")
3892 (match_operand:GPR 2 "general_operand" "d,R,T"))
3893 (const_int 0)))
3894 (clobber (match_scratch:GPR 0 "=d,d,d"))]
3895 "s390_match_ccmode (insn, CCLmode)"
3896 "@
3897 al<g>r\t%0,%2
3898 al<g>\t%0,%2
3899 al<y>\t%0,%2"
3900 [(set_attr "op_type" "RR<E>,RX<Y>,RXY")])
3901
3902 ; alr, al, aly, algr, alg
3903 (define_insn "*add<mode>3_cconly2"
3904 [(set (reg CC_REGNUM)
3905 (compare (match_operand:GPR 1 "nonimmediate_operand" "%0,0,0")
3906 (neg:GPR (match_operand:GPR 2 "general_operand" "d,R,T"))))
3907 (clobber (match_scratch:GPR 0 "=d,d,d"))]
3908 "s390_match_ccmode(insn, CCLmode)"
3909 "@
3910 al<g>r\t%0,%2
3911 al<g>\t%0,%2
3912 al<y>\t%0,%2"
3913 [(set_attr "op_type" "RR<E>,RX<Y>,RXY")])
3914
3915 ; ahi, afi, aghi, agfi
3916 (define_insn "*add<mode>3_imm_cc"
3917 [(set (reg CC_REGNUM)
3918 (compare (plus:GPR (match_operand:GPR 1 "nonimmediate_operand" "0,0")
3919 (match_operand:GPR 2 "const_int_operand" "K,Os"))
3920 (const_int 0)))
3921 (set (match_operand:GPR 0 "register_operand" "=d,d")
3922 (plus:GPR (match_dup 1) (match_dup 2)))]
3923 "s390_match_ccmode (insn, CCAmode)
3924 && (CONST_OK_FOR_CONSTRAINT_P (INTVAL (operands[2]), 'K', \"K\")
3925 || CONST_OK_FOR_CONSTRAINT_P (INTVAL (operands[2]), 'O', \"Os\"))
3926 && INTVAL (operands[2]) != -((HOST_WIDE_INT)1 << (GET_MODE_BITSIZE(<MODE>mode) - 1))"
3927 "@
3928 a<g>hi\t%0,%h2
3929 a<g>fi\t%0,%2"
3930 [(set_attr "op_type" "RI,RIL")])
3931
3932 ;
3933 ; add(tf|df|sf|td|dd)3 instruction pattern(s).
3934 ;
3935
3936 ; axbr, adbr, aebr, axb, adb, aeb, adtr, axtr
3937 (define_insn "add<mode>3"
3938 [(set (match_operand:FP 0 "register_operand" "=f, f")
3939 (plus:FP (match_operand:FP 1 "nonimmediate_operand" "%<f0>,0")
3940 (match_operand:FP 2 "general_operand" " f,<Rf>")))
3941 (clobber (reg:CC CC_REGNUM))]
3942 "TARGET_HARD_FLOAT"
3943 "@
3944 a<xde><bt>r\t%0,<op1>%2
3945 a<xde>b\t%0,%2"
3946 [(set_attr "op_type" "<RRer>,RXE")
3947 (set_attr "type" "fsimp<bfp>")])
3948
3949 ; axbr, adbr, aebr, axb, adb, aeb, adtr, axtr
3950 (define_insn "*add<mode>3_cc"
3951 [(set (reg CC_REGNUM)
3952 (compare (plus:FP (match_operand:FP 1 "nonimmediate_operand" "%<f0>,0")
3953 (match_operand:FP 2 "general_operand" " f,<Rf>"))
3954 (match_operand:FP 3 "const0_operand" "")))
3955 (set (match_operand:FP 0 "register_operand" "=f,f")
3956 (plus:FP (match_dup 1) (match_dup 2)))]
3957 "s390_match_ccmode (insn, CCSmode) && TARGET_HARD_FLOAT"
3958 "@
3959 a<xde><bt>r\t%0,<op1>%2
3960 a<xde>b\t%0,%2"
3961 [(set_attr "op_type" "<RRer>,RXE")
3962 (set_attr "type" "fsimp<bfp>")])
3963
3964 ; axbr, adbr, aebr, axb, adb, aeb, adtr, axtr
3965 (define_insn "*add<mode>3_cconly"
3966 [(set (reg CC_REGNUM)
3967 (compare (plus:FP (match_operand:FP 1 "nonimmediate_operand" "%<f0>,0")
3968 (match_operand:FP 2 "general_operand" " f,<Rf>"))
3969 (match_operand:FP 3 "const0_operand" "")))
3970 (clobber (match_scratch:FP 0 "=f,f"))]
3971 "s390_match_ccmode (insn, CCSmode) && TARGET_HARD_FLOAT"
3972 "@
3973 a<xde><bt>r\t%0,<op1>%2
3974 a<xde>b\t%0,%2"
3975 [(set_attr "op_type" "<RRer>,RXE")
3976 (set_attr "type" "fsimp<bfp>")])
3977
3978
3979 ;;
3980 ;;- Subtract instructions.
3981 ;;
3982
3983 ;
3984 ; subti3 instruction pattern(s).
3985 ;
3986
3987 (define_insn_and_split "subti3"
3988 [(set (match_operand:TI 0 "register_operand" "=&d")
3989 (minus:TI (match_operand:TI 1 "register_operand" "0")
3990 (match_operand:TI 2 "general_operand" "do") ) )
3991 (clobber (reg:CC CC_REGNUM))]
3992 "TARGET_64BIT"
3993 "#"
3994 "&& reload_completed"
3995 [(parallel
3996 [(set (reg:CCL2 CC_REGNUM)
3997 (compare:CCL2 (minus:DI (match_dup 7) (match_dup 8))
3998 (match_dup 7)))
3999 (set (match_dup 6) (minus:DI (match_dup 7) (match_dup 8)))])
4000 (parallel
4001 [(set (match_dup 3) (minus:DI (minus:DI (match_dup 4) (match_dup 5))
4002 (gtu:DI (reg:CCL2 CC_REGNUM) (const_int 0))))
4003 (clobber (reg:CC CC_REGNUM))])]
4004 "operands[3] = operand_subword (operands[0], 0, 0, TImode);
4005 operands[4] = operand_subword (operands[1], 0, 0, TImode);
4006 operands[5] = operand_subword (operands[2], 0, 0, TImode);
4007 operands[6] = operand_subword (operands[0], 1, 0, TImode);
4008 operands[7] = operand_subword (operands[1], 1, 0, TImode);
4009 operands[8] = operand_subword (operands[2], 1, 0, TImode);")
4010
4011 ;
4012 ; subdi3 instruction pattern(s).
4013 ;
4014
4015 (define_expand "subdi3"
4016 [(parallel
4017 [(set (match_operand:DI 0 "register_operand" "")
4018 (minus:DI (match_operand:DI 1 "register_operand" "")
4019 (match_operand:DI 2 "general_operand" "")))
4020 (clobber (reg:CC CC_REGNUM))])]
4021 ""
4022 "")
4023
4024 (define_insn "*subdi3_sign"
4025 [(set (match_operand:DI 0 "register_operand" "=d,d")
4026 (minus:DI (match_operand:DI 1 "register_operand" "0,0")
4027 (sign_extend:DI (match_operand:SI 2 "general_operand" "d,m"))))
4028 (clobber (reg:CC CC_REGNUM))]
4029 "TARGET_64BIT"
4030 "@
4031 sgfr\t%0,%2
4032 sgf\t%0,%2"
4033 [(set_attr "op_type" "RRE,RXY")])
4034
4035 (define_insn "*subdi3_zero_cc"
4036 [(set (reg CC_REGNUM)
4037 (compare (minus:DI (match_operand:DI 1 "register_operand" "0,0")
4038 (zero_extend:DI (match_operand:SI 2 "general_operand" "d,m")))
4039 (const_int 0)))
4040 (set (match_operand:DI 0 "register_operand" "=d,d")
4041 (minus:DI (match_dup 1) (zero_extend:DI (match_dup 2))))]
4042 "s390_match_ccmode (insn, CCLmode) && TARGET_64BIT"
4043 "@
4044 slgfr\t%0,%2
4045 slgf\t%0,%2"
4046 [(set_attr "op_type" "RRE,RXY")])
4047
4048 (define_insn "*subdi3_zero_cconly"
4049 [(set (reg CC_REGNUM)
4050 (compare (minus:DI (match_operand:DI 1 "register_operand" "0,0")
4051 (zero_extend:DI (match_operand:SI 2 "general_operand" "d,m")))
4052 (const_int 0)))
4053 (clobber (match_scratch:DI 0 "=d,d"))]
4054 "s390_match_ccmode (insn, CCLmode) && TARGET_64BIT"
4055 "@
4056 slgfr\t%0,%2
4057 slgf\t%0,%2"
4058 [(set_attr "op_type" "RRE,RXY")])
4059
4060 (define_insn "*subdi3_zero"
4061 [(set (match_operand:DI 0 "register_operand" "=d,d")
4062 (minus:DI (match_operand:DI 1 "register_operand" "0,0")
4063 (zero_extend:DI (match_operand:SI 2 "general_operand" "d,m"))))
4064 (clobber (reg:CC CC_REGNUM))]
4065 "TARGET_64BIT"
4066 "@
4067 slgfr\t%0,%2
4068 slgf\t%0,%2"
4069 [(set_attr "op_type" "RRE,RXY")])
4070
4071 (define_insn_and_split "*subdi3_31z"
4072 [(set (match_operand:DI 0 "register_operand" "=&d")
4073 (minus:DI (match_operand:DI 1 "register_operand" "0")
4074 (match_operand:DI 2 "general_operand" "do") ) )
4075 (clobber (reg:CC CC_REGNUM))]
4076 "!TARGET_64BIT && TARGET_CPU_ZARCH"
4077 "#"
4078 "&& reload_completed"
4079 [(parallel
4080 [(set (reg:CCL2 CC_REGNUM)
4081 (compare:CCL2 (minus:SI (match_dup 7) (match_dup 8))
4082 (match_dup 7)))
4083 (set (match_dup 6) (minus:SI (match_dup 7) (match_dup 8)))])
4084 (parallel
4085 [(set (match_dup 3) (minus:SI (minus:SI (match_dup 4) (match_dup 5))
4086 (gtu:SI (reg:CCL2 CC_REGNUM) (const_int 0))))
4087 (clobber (reg:CC CC_REGNUM))])]
4088 "operands[3] = operand_subword (operands[0], 0, 0, DImode);
4089 operands[4] = operand_subword (operands[1], 0, 0, DImode);
4090 operands[5] = operand_subword (operands[2], 0, 0, DImode);
4091 operands[6] = operand_subword (operands[0], 1, 0, DImode);
4092 operands[7] = operand_subword (operands[1], 1, 0, DImode);
4093 operands[8] = operand_subword (operands[2], 1, 0, DImode);")
4094
4095 (define_insn_and_split "*subdi3_31"
4096 [(set (match_operand:DI 0 "register_operand" "=&d")
4097 (minus:DI (match_operand:DI 1 "register_operand" "0")
4098 (match_operand:DI 2 "general_operand" "do") ) )
4099 (clobber (reg:CC CC_REGNUM))]
4100 "!TARGET_CPU_ZARCH"
4101 "#"
4102 "&& reload_completed"
4103 [(parallel
4104 [(set (match_dup 3) (minus:SI (match_dup 4) (match_dup 5)))
4105 (clobber (reg:CC CC_REGNUM))])
4106 (parallel
4107 [(set (reg:CCL2 CC_REGNUM)
4108 (compare:CCL2 (minus:SI (match_dup 7) (match_dup 8))
4109 (match_dup 7)))
4110 (set (match_dup 6) (minus:SI (match_dup 7) (match_dup 8)))])
4111 (set (pc)
4112 (if_then_else (gtu (reg:CCL2 CC_REGNUM) (const_int 0))
4113 (pc)
4114 (label_ref (match_dup 9))))
4115 (parallel
4116 [(set (match_dup 3) (plus:SI (match_dup 3) (const_int -1)))
4117 (clobber (reg:CC CC_REGNUM))])
4118 (match_dup 9)]
4119 "operands[3] = operand_subword (operands[0], 0, 0, DImode);
4120 operands[4] = operand_subword (operands[1], 0, 0, DImode);
4121 operands[5] = operand_subword (operands[2], 0, 0, DImode);
4122 operands[6] = operand_subword (operands[0], 1, 0, DImode);
4123 operands[7] = operand_subword (operands[1], 1, 0, DImode);
4124 operands[8] = operand_subword (operands[2], 1, 0, DImode);
4125 operands[9] = gen_label_rtx ();")
4126
4127 ;
4128 ; subsi3 instruction pattern(s).
4129 ;
4130
4131 (define_expand "subsi3"
4132 [(parallel
4133 [(set (match_operand:SI 0 "register_operand" "")
4134 (minus:SI (match_operand:SI 1 "register_operand" "")
4135 (match_operand:SI 2 "general_operand" "")))
4136 (clobber (reg:CC CC_REGNUM))])]
4137 ""
4138 "")
4139
4140 (define_insn "*subsi3_sign"
4141 [(set (match_operand:SI 0 "register_operand" "=d,d")
4142 (minus:SI (match_operand:SI 1 "register_operand" "0,0")
4143 (sign_extend:SI (match_operand:HI 2 "memory_operand" "R,T"))))
4144 (clobber (reg:CC CC_REGNUM))]
4145 ""
4146 "@
4147 sh\t%0,%2
4148 shy\t%0,%2"
4149 [(set_attr "op_type" "RX,RXY")])
4150
4151 ;
4152 ; sub(di|si)3 instruction pattern(s).
4153 ;
4154
4155 ; sr, s, sy, sgr, sg
4156 (define_insn "*sub<mode>3"
4157 [(set (match_operand:GPR 0 "register_operand" "=d,d,d")
4158 (minus:GPR (match_operand:GPR 1 "register_operand" "0,0,0")
4159 (match_operand:GPR 2 "general_operand" "d,R,T") ) )
4160 (clobber (reg:CC CC_REGNUM))]
4161 ""
4162 "@
4163 s<g>r\t%0,%2
4164 s<g>\t%0,%2
4165 s<y>\t%0,%2"
4166 [(set_attr "op_type" "RR<E>,RX<Y>,RXY")])
4167
4168 ; slr, sl, sly, slgr, slg
4169 (define_insn "*sub<mode>3_borrow_cc"
4170 [(set (reg CC_REGNUM)
4171 (compare (minus:GPR (match_operand:GPR 1 "register_operand" "0,0,0")
4172 (match_operand:GPR 2 "general_operand" "d,R,T"))
4173 (match_dup 1)))
4174 (set (match_operand:GPR 0 "register_operand" "=d,d,d")
4175 (minus:GPR (match_dup 1) (match_dup 2)))]
4176 "s390_match_ccmode (insn, CCL2mode)"
4177 "@
4178 sl<g>r\t%0,%2
4179 sl<g>\t%0,%2
4180 sl<y>\t%0,%2"
4181 [(set_attr "op_type" "RR<E>,RX<Y>,RXY")])
4182
4183 ; slr, sl, sly, slgr, slg
4184 (define_insn "*sub<mode>3_borrow_cconly"
4185 [(set (reg CC_REGNUM)
4186 (compare (minus:GPR (match_operand:GPR 1 "register_operand" "0,0,0")
4187 (match_operand:GPR 2 "general_operand" "d,R,T"))
4188 (match_dup 1)))
4189 (clobber (match_scratch:GPR 0 "=d,d,d"))]
4190 "s390_match_ccmode (insn, CCL2mode)"
4191 "@
4192 sl<g>r\t%0,%2
4193 sl<g>\t%0,%2
4194 sl<y>\t%0,%2"
4195 [(set_attr "op_type" "RR<E>,RX<Y>,RXY")])
4196
4197 ; slr, sl, sly, slgr, slg
4198 (define_insn "*sub<mode>3_cc"
4199 [(set (reg CC_REGNUM)
4200 (compare (minus:GPR (match_operand:GPR 1 "register_operand" "0,0,0")
4201 (match_operand:GPR 2 "general_operand" "d,R,T"))
4202 (const_int 0)))
4203 (set (match_operand:GPR 0 "register_operand" "=d,d,d")
4204 (minus:GPR (match_dup 1) (match_dup 2)))]
4205 "s390_match_ccmode (insn, CCLmode)"
4206 "@
4207 sl<g>r\t%0,%2
4208 sl<g>\t%0,%2
4209 sl<y>\t%0,%2"
4210 [(set_attr "op_type" "RR<E>,RX<Y>,RXY")])
4211
4212 ; slr, sl, sly, slgr, slg
4213 (define_insn "*sub<mode>3_cc2"
4214 [(set (reg CC_REGNUM)
4215 (compare (match_operand:GPR 1 "register_operand" "0,0,0")
4216 (match_operand:GPR 2 "general_operand" "d,R,T")))
4217 (set (match_operand:GPR 0 "register_operand" "=d,d,d")
4218 (minus:GPR (match_dup 1) (match_dup 2)))]
4219 "s390_match_ccmode (insn, CCL3mode)"
4220 "@
4221 sl<g>r\t%0,%2
4222 sl<g>\t%0,%2
4223 sl<y>\t%0,%2"
4224 [(set_attr "op_type" "RR<E>,RX<Y>,RXY")])
4225
4226 ; slr, sl, sly, slgr, slg
4227 (define_insn "*sub<mode>3_cconly"
4228 [(set (reg CC_REGNUM)
4229 (compare (minus:GPR (match_operand:GPR 1 "register_operand" "0,0,0")
4230 (match_operand:GPR 2 "general_operand" "d,R,T"))
4231 (const_int 0)))
4232 (clobber (match_scratch:GPR 0 "=d,d,d"))]
4233 "s390_match_ccmode (insn, CCLmode)"
4234 "@
4235 sl<g>r\t%0,%2
4236 sl<g>\t%0,%2
4237 sl<y>\t%0,%2"
4238 [(set_attr "op_type" "RR<E>,RX<Y>,RXY")])
4239
4240 ; slr, sl, sly, slgr, slg
4241 (define_insn "*sub<mode>3_cconly2"
4242 [(set (reg CC_REGNUM)
4243 (compare (match_operand:GPR 1 "register_operand" "0,0,0")
4244 (match_operand:GPR 2 "general_operand" "d,R,T")))
4245 (clobber (match_scratch:GPR 0 "=d,d,d"))]
4246 "s390_match_ccmode (insn, CCL3mode)"
4247 "@
4248 sl<g>r\t%0,%2
4249 sl<g>\t%0,%2
4250 sl<y>\t%0,%2"
4251 [(set_attr "op_type" "RR<E>,RX<Y>,RXY")])
4252
4253 ;
4254 ; sub(tf|df|sf|td|dd)3 instruction pattern(s).
4255 ;
4256
4257 ; sxbr, sdbr, sebr, sxb, sdb, seb, sxtr, sdtr
4258 (define_insn "sub<mode>3"
4259 [(set (match_operand:FP 0 "register_operand" "=f, f")
4260 (minus:FP (match_operand:FP 1 "register_operand" "<f0>,0")
4261 (match_operand:FP 2 "general_operand" "f,<Rf>")))
4262 (clobber (reg:CC CC_REGNUM))]
4263 "TARGET_HARD_FLOAT"
4264 "@
4265 s<xde><bt>r\t%0,<op1>%2
4266 s<xde>b\t%0,%2"
4267 [(set_attr "op_type" "<RRer>,RXE")
4268 (set_attr "type" "fsimp<bfp>")])
4269
4270 ; sxbr, sdbr, sebr, sxb, sdb, seb, sxtr, sdtr
4271 (define_insn "*sub<mode>3_cc"
4272 [(set (reg CC_REGNUM)
4273 (compare (minus:FP (match_operand:FP 1 "nonimmediate_operand" "<f0>,0")
4274 (match_operand:FP 2 "general_operand" "f,<Rf>"))
4275 (match_operand:FP 3 "const0_operand" "")))
4276 (set (match_operand:FP 0 "register_operand" "=f,f")
4277 (minus:FP (match_dup 1) (match_dup 2)))]
4278 "s390_match_ccmode (insn, CCSmode) && TARGET_HARD_FLOAT"
4279 "@
4280 s<xde><bt>r\t%0,<op1>%2
4281 s<xde>b\t%0,%2"
4282 [(set_attr "op_type" "<RRer>,RXE")
4283 (set_attr "type" "fsimp<bfp>")])
4284
4285 ; sxbr, sdbr, sebr, sxb, sdb, seb, sxtr, sdtr
4286 (define_insn "*sub<mode>3_cconly"
4287 [(set (reg CC_REGNUM)
4288 (compare (minus:FP (match_operand:FP 1 "nonimmediate_operand" "<f0>,0")
4289 (match_operand:FP 2 "general_operand" "f,<Rf>"))
4290 (match_operand:FP 3 "const0_operand" "")))
4291 (clobber (match_scratch:FP 0 "=f,f"))]
4292 "s390_match_ccmode (insn, CCSmode) && TARGET_HARD_FLOAT"
4293 "@
4294 s<xde><bt>r\t%0,<op1>%2
4295 s<xde>b\t%0,%2"
4296 [(set_attr "op_type" "<RRer>,RXE")
4297 (set_attr "type" "fsimp<bfp>")])
4298
4299
4300 ;;
4301 ;;- Conditional add/subtract instructions.
4302 ;;
4303
4304 ;
4305 ; add(di|si)cc instruction pattern(s).
4306 ;
4307
4308 ; alcr, alc, alcgr, alcg
4309 (define_insn "*add<mode>3_alc_cc"
4310 [(set (reg CC_REGNUM)
4311 (compare
4312 (plus:GPR (plus:GPR (match_operand:GPR 1 "nonimmediate_operand" "%0,0")
4313 (match_operand:GPR 2 "general_operand" "d,m"))
4314 (match_operand:GPR 3 "s390_alc_comparison" ""))
4315 (const_int 0)))
4316 (set (match_operand:GPR 0 "register_operand" "=d,d")
4317 (plus:GPR (plus:GPR (match_dup 1) (match_dup 2)) (match_dup 3)))]
4318 "s390_match_ccmode (insn, CCLmode) && TARGET_CPU_ZARCH"
4319 "@
4320 alc<g>r\t%0,%2
4321 alc<g>\t%0,%2"
4322 [(set_attr "op_type" "RRE,RXY")])
4323
4324 ; alcr, alc, alcgr, alcg
4325 (define_insn "*add<mode>3_alc"
4326 [(set (match_operand:GPR 0 "register_operand" "=d,d")
4327 (plus:GPR (plus:GPR (match_operand:GPR 1 "nonimmediate_operand" "%0,0")
4328 (match_operand:GPR 2 "general_operand" "d,m"))
4329 (match_operand:GPR 3 "s390_alc_comparison" "")))
4330 (clobber (reg:CC CC_REGNUM))]
4331 "TARGET_CPU_ZARCH"
4332 "@
4333 alc<g>r\t%0,%2
4334 alc<g>\t%0,%2"
4335 [(set_attr "op_type" "RRE,RXY")])
4336
4337 ; slbr, slb, slbgr, slbg
4338 (define_insn "*sub<mode>3_slb_cc"
4339 [(set (reg CC_REGNUM)
4340 (compare
4341 (minus:GPR (minus:GPR (match_operand:GPR 1 "nonimmediate_operand" "0,0")
4342 (match_operand:GPR 2 "general_operand" "d,m"))
4343 (match_operand:GPR 3 "s390_slb_comparison" ""))
4344 (const_int 0)))
4345 (set (match_operand:GPR 0 "register_operand" "=d,d")
4346 (minus:GPR (minus:GPR (match_dup 1) (match_dup 2)) (match_dup 3)))]
4347 "s390_match_ccmode (insn, CCLmode) && TARGET_CPU_ZARCH"
4348 "@
4349 slb<g>r\t%0,%2
4350 slb<g>\t%0,%2"
4351 [(set_attr "op_type" "RRE,RXY")])
4352
4353 ; slbr, slb, slbgr, slbg
4354 (define_insn "*sub<mode>3_slb"
4355 [(set (match_operand:GPR 0 "register_operand" "=d,d")
4356 (minus:GPR (minus:GPR (match_operand:GPR 1 "nonimmediate_operand" "0,0")
4357 (match_operand:GPR 2 "general_operand" "d,m"))
4358 (match_operand:GPR 3 "s390_slb_comparison" "")))
4359 (clobber (reg:CC CC_REGNUM))]
4360 "TARGET_CPU_ZARCH"
4361 "@
4362 slb<g>r\t%0,%2
4363 slb<g>\t%0,%2"
4364 [(set_attr "op_type" "RRE,RXY")])
4365
4366 (define_expand "add<mode>cc"
4367 [(match_operand:GPR 0 "register_operand" "")
4368 (match_operand 1 "comparison_operator" "")
4369 (match_operand:GPR 2 "register_operand" "")
4370 (match_operand:GPR 3 "const_int_operand" "")]
4371 "TARGET_CPU_ZARCH"
4372 "if (!s390_expand_addcc (GET_CODE (operands[1]),
4373 s390_compare_op0, s390_compare_op1,
4374 operands[0], operands[2],
4375 operands[3])) FAIL; DONE;")
4376
4377 ;
4378 ; scond instruction pattern(s).
4379 ;
4380
4381 (define_insn_and_split "*scond<mode>"
4382 [(set (match_operand:GPR 0 "register_operand" "=&d")
4383 (match_operand:GPR 1 "s390_alc_comparison" ""))
4384 (clobber (reg:CC CC_REGNUM))]
4385 "TARGET_CPU_ZARCH"
4386 "#"
4387 "&& reload_completed"
4388 [(set (match_dup 0) (const_int 0))
4389 (parallel
4390 [(set (match_dup 0) (plus:GPR (plus:GPR (match_dup 0) (match_dup 0))
4391 (match_dup 1)))
4392 (clobber (reg:CC CC_REGNUM))])]
4393 "")
4394
4395 (define_insn_and_split "*scond<mode>_neg"
4396 [(set (match_operand:GPR 0 "register_operand" "=&d")
4397 (match_operand:GPR 1 "s390_slb_comparison" ""))
4398 (clobber (reg:CC CC_REGNUM))]
4399 "TARGET_CPU_ZARCH"
4400 "#"
4401 "&& reload_completed"
4402 [(set (match_dup 0) (const_int 0))
4403 (parallel
4404 [(set (match_dup 0) (minus:GPR (minus:GPR (match_dup 0) (match_dup 0))
4405 (match_dup 1)))
4406 (clobber (reg:CC CC_REGNUM))])
4407 (parallel
4408 [(set (match_dup 0) (neg:GPR (match_dup 0)))
4409 (clobber (reg:CC CC_REGNUM))])]
4410 "")
4411
4412
4413 (define_expand "s<code>"
4414 [(set (match_operand:SI 0 "register_operand" "")
4415 (SCOND (match_dup 0)
4416 (match_dup 0)))]
4417 "TARGET_CPU_ZARCH"
4418 "if (!s390_expand_addcc (<CODE>, s390_compare_op0, s390_compare_op1,
4419 operands[0], const0_rtx, const1_rtx)) FAIL; DONE;")
4420
4421 (define_expand "seq"
4422 [(parallel
4423 [(set (match_operand:SI 0 "register_operand" "=d")
4424 (match_dup 1))
4425 (clobber (reg:CC CC_REGNUM))])
4426 (parallel
4427 [(set (match_dup 0) (xor:SI (match_dup 0) (const_int 1)))
4428 (clobber (reg:CC CC_REGNUM))])]
4429 ""
4430 {
4431 if (!s390_compare_emitted || GET_MODE (s390_compare_emitted) != CCZ1mode)
4432 FAIL;
4433 operands[1] = s390_emit_compare (NE, s390_compare_op0, s390_compare_op1);
4434 PUT_MODE (operands[1], SImode);
4435 })
4436
4437 (define_insn_and_split "*sne"
4438 [(set (match_operand:SI 0 "register_operand" "=d")
4439 (ne:SI (match_operand:CCZ1 1 "register_operand" "0")
4440 (const_int 0)))
4441 (clobber (reg:CC CC_REGNUM))]
4442 ""
4443 "#"
4444 "reload_completed"
4445 [(parallel
4446 [(set (match_dup 0) (ashiftrt:SI (match_dup 0) (const_int 28)))
4447 (clobber (reg:CC CC_REGNUM))])])
4448
4449
4450 ;;
4451 ;;- Multiply instructions.
4452 ;;
4453
4454 ;
4455 ; muldi3 instruction pattern(s).
4456 ;
4457
4458 (define_insn "*muldi3_sign"
4459 [(set (match_operand:DI 0 "register_operand" "=d,d")
4460 (mult:DI (sign_extend:DI (match_operand:SI 2 "nonimmediate_operand" "d,m"))
4461 (match_operand:DI 1 "register_operand" "0,0")))]
4462 "TARGET_64BIT"
4463 "@
4464 msgfr\t%0,%2
4465 msgf\t%0,%2"
4466 [(set_attr "op_type" "RRE,RXY")
4467 (set_attr "type" "imuldi")])
4468
4469 (define_insn "muldi3"
4470 [(set (match_operand:DI 0 "register_operand" "=d,d,d")
4471 (mult:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
4472 (match_operand:DI 2 "general_operand" "d,K,m")))]
4473 "TARGET_64BIT"
4474 "@
4475 msgr\t%0,%2
4476 mghi\t%0,%h2
4477 msg\t%0,%2"
4478 [(set_attr "op_type" "RRE,RI,RXY")
4479 (set_attr "type" "imuldi")])
4480
4481 ;
4482 ; mulsi3 instruction pattern(s).
4483 ;
4484
4485 (define_insn "*mulsi3_sign"
4486 [(set (match_operand:SI 0 "register_operand" "=d")
4487 (mult:SI (sign_extend:SI (match_operand:HI 2 "memory_operand" "R"))
4488 (match_operand:SI 1 "register_operand" "0")))]
4489 ""
4490 "mh\t%0,%2"
4491 [(set_attr "op_type" "RX")
4492 (set_attr "type" "imulhi")])
4493
4494 (define_insn "mulsi3"
4495 [(set (match_operand:SI 0 "register_operand" "=d,d,d,d")
4496 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,0,0")
4497 (match_operand:SI 2 "general_operand" "d,K,R,T")))]
4498 ""
4499 "@
4500 msr\t%0,%2
4501 mhi\t%0,%h2
4502 ms\t%0,%2
4503 msy\t%0,%2"
4504 [(set_attr "op_type" "RRE,RI,RX,RXY")
4505 (set_attr "type" "imulsi,imulhi,imulsi,imulsi")])
4506
4507 ;
4508 ; mulsidi3 instruction pattern(s).
4509 ;
4510
4511 (define_insn "mulsidi3"
4512 [(set (match_operand:DI 0 "register_operand" "=d,d")
4513 (mult:DI (sign_extend:DI
4514 (match_operand:SI 1 "register_operand" "%0,0"))
4515 (sign_extend:DI
4516 (match_operand:SI 2 "nonimmediate_operand" "d,R"))))]
4517 "!TARGET_64BIT"
4518 "@
4519 mr\t%0,%2
4520 m\t%0,%2"
4521 [(set_attr "op_type" "RR,RX")
4522 (set_attr "type" "imulsi")])
4523
4524 ;
4525 ; umulsidi3 instruction pattern(s).
4526 ;
4527
4528 (define_insn "umulsidi3"
4529 [(set (match_operand:DI 0 "register_operand" "=d,d")
4530 (mult:DI (zero_extend:DI
4531 (match_operand:SI 1 "register_operand" "%0,0"))
4532 (zero_extend:DI
4533 (match_operand:SI 2 "nonimmediate_operand" "d,m"))))]
4534 "!TARGET_64BIT && TARGET_CPU_ZARCH"
4535 "@
4536 mlr\t%0,%2
4537 ml\t%0,%2"
4538 [(set_attr "op_type" "RRE,RXY")
4539 (set_attr "type" "imulsi")])
4540
4541 ;
4542 ; mul(tf|df|sf|td|dd)3 instruction pattern(s).
4543 ;
4544
4545 ; mxbr mdbr, meebr, mxb, mxb, meeb, mdtr, mxtr
4546 (define_insn "mul<mode>3"
4547 [(set (match_operand:FP 0 "register_operand" "=f,f")
4548 (mult:FP (match_operand:FP 1 "nonimmediate_operand" "%<f0>,0")
4549 (match_operand:FP 2 "general_operand" "f,<Rf>")))]
4550 "TARGET_HARD_FLOAT"
4551 "@
4552 m<xdee><bt>r\t%0,<op1>%2
4553 m<xdee>b\t%0,%2"
4554 [(set_attr "op_type" "<RRer>,RXE")
4555 (set_attr "type" "fmul<bfp>")])
4556
4557 ; maxbr, madbr, maebr, maxb, madb, maeb
4558 (define_insn "*fmadd<mode>"
4559 [(set (match_operand:DSF 0 "register_operand" "=f,f")
4560 (plus:DSF (mult:DSF (match_operand:DSF 1 "register_operand" "%f,f")
4561 (match_operand:DSF 2 "nonimmediate_operand" "f,R"))
4562 (match_operand:DSF 3 "register_operand" "0,0")))]
4563 "TARGET_HARD_FLOAT && TARGET_FUSED_MADD"
4564 "@
4565 ma<xde>br\t%0,%1,%2
4566 ma<xde>b\t%0,%1,%2"
4567 [(set_attr "op_type" "RRE,RXE")
4568 (set_attr "type" "fmul<mode>")])
4569
4570 ; msxbr, msdbr, msebr, msxb, msdb, mseb
4571 (define_insn "*fmsub<mode>"
4572 [(set (match_operand:DSF 0 "register_operand" "=f,f")
4573 (minus:DSF (mult:DSF (match_operand:DSF 1 "register_operand" "f,f")
4574 (match_operand:DSF 2 "nonimmediate_operand" "f,R"))
4575 (match_operand:DSF 3 "register_operand" "0,0")))]
4576 "TARGET_HARD_FLOAT && TARGET_FUSED_MADD"
4577 "@
4578 ms<xde>br\t%0,%1,%2
4579 ms<xde>b\t%0,%1,%2"
4580 [(set_attr "op_type" "RRE,RXE")
4581 (set_attr "type" "fmul<mode>")])
4582
4583 ;;
4584 ;;- Divide and modulo instructions.
4585 ;;
4586
4587 ;
4588 ; divmoddi4 instruction pattern(s).
4589 ;
4590
4591 (define_expand "divmoddi4"
4592 [(parallel [(set (match_operand:DI 0 "general_operand" "")
4593 (div:DI (match_operand:DI 1 "register_operand" "")
4594 (match_operand:DI 2 "general_operand" "")))
4595 (set (match_operand:DI 3 "general_operand" "")
4596 (mod:DI (match_dup 1) (match_dup 2)))])
4597 (clobber (match_dup 4))]
4598 "TARGET_64BIT"
4599 {
4600 rtx insn, div_equal, mod_equal;
4601
4602 div_equal = gen_rtx_DIV (DImode, operands[1], operands[2]);
4603 mod_equal = gen_rtx_MOD (DImode, operands[1], operands[2]);
4604
4605 operands[4] = gen_reg_rtx(TImode);
4606 emit_insn (gen_divmodtidi3 (operands[4], operands[1], operands[2]));
4607
4608 insn = emit_move_insn (operands[0], gen_lowpart (DImode, operands[4]));
4609 set_unique_reg_note (insn, REG_EQUAL, div_equal);
4610
4611 insn = emit_move_insn (operands[3], gen_highpart (DImode, operands[4]));
4612 set_unique_reg_note (insn, REG_EQUAL, mod_equal);
4613
4614 DONE;
4615 })
4616
4617 (define_insn "divmodtidi3"
4618 [(set (match_operand:TI 0 "register_operand" "=d,d")
4619 (ior:TI
4620 (ashift:TI
4621 (zero_extend:TI
4622 (mod:DI (match_operand:DI 1 "register_operand" "0,0")
4623 (match_operand:DI 2 "general_operand" "d,m")))
4624 (const_int 64))
4625 (zero_extend:TI (div:DI (match_dup 1) (match_dup 2)))))]
4626 "TARGET_64BIT"
4627 "@
4628 dsgr\t%0,%2
4629 dsg\t%0,%2"
4630 [(set_attr "op_type" "RRE,RXY")
4631 (set_attr "type" "idiv")])
4632
4633 (define_insn "divmodtisi3"
4634 [(set (match_operand:TI 0 "register_operand" "=d,d")
4635 (ior:TI
4636 (ashift:TI
4637 (zero_extend:TI
4638 (mod:DI (match_operand:DI 1 "register_operand" "0,0")
4639 (sign_extend:DI
4640 (match_operand:SI 2 "nonimmediate_operand" "d,m"))))
4641 (const_int 64))
4642 (zero_extend:TI
4643 (div:DI (match_dup 1) (sign_extend:DI (match_dup 2))))))]
4644 "TARGET_64BIT"
4645 "@
4646 dsgfr\t%0,%2
4647 dsgf\t%0,%2"
4648 [(set_attr "op_type" "RRE,RXY")
4649 (set_attr "type" "idiv")])
4650
4651 ;
4652 ; udivmoddi4 instruction pattern(s).
4653 ;
4654
4655 (define_expand "udivmoddi4"
4656 [(parallel [(set (match_operand:DI 0 "general_operand" "")
4657 (udiv:DI (match_operand:DI 1 "general_operand" "")
4658 (match_operand:DI 2 "nonimmediate_operand" "")))
4659 (set (match_operand:DI 3 "general_operand" "")
4660 (umod:DI (match_dup 1) (match_dup 2)))])
4661 (clobber (match_dup 4))]
4662 "TARGET_64BIT"
4663 {
4664 rtx insn, div_equal, mod_equal, equal;
4665
4666 div_equal = gen_rtx_UDIV (DImode, operands[1], operands[2]);
4667 mod_equal = gen_rtx_UMOD (DImode, operands[1], operands[2]);
4668 equal = gen_rtx_IOR (TImode,
4669 gen_rtx_ASHIFT (TImode,
4670 gen_rtx_ZERO_EXTEND (TImode, mod_equal),
4671 GEN_INT (64)),
4672 gen_rtx_ZERO_EXTEND (TImode, div_equal));
4673
4674 operands[4] = gen_reg_rtx(TImode);
4675 emit_insn (gen_rtx_CLOBBER (VOIDmode, operands[4]));
4676 emit_move_insn (gen_lowpart (DImode, operands[4]), operands[1]);
4677 emit_move_insn (gen_highpart (DImode, operands[4]), const0_rtx);
4678
4679 insn = emit_insn (gen_udivmodtidi3 (operands[4], operands[4], operands[2]));
4680 set_unique_reg_note (insn, REG_EQUAL, equal);
4681
4682 insn = emit_move_insn (operands[0], gen_lowpart (DImode, operands[4]));
4683 set_unique_reg_note (insn, REG_EQUAL, div_equal);
4684
4685 insn = emit_move_insn (operands[3], gen_highpart (DImode, operands[4]));
4686 set_unique_reg_note (insn, REG_EQUAL, mod_equal);
4687
4688 DONE;
4689 })
4690
4691 (define_insn "udivmodtidi3"
4692 [(set (match_operand:TI 0 "register_operand" "=d,d")
4693 (ior:TI
4694 (ashift:TI
4695 (zero_extend:TI
4696 (truncate:DI
4697 (umod:TI (match_operand:TI 1 "register_operand" "0,0")
4698 (zero_extend:TI
4699 (match_operand:DI 2 "nonimmediate_operand" "d,m")))))
4700 (const_int 64))
4701 (zero_extend:TI
4702 (truncate:DI
4703 (udiv:TI (match_dup 1) (zero_extend:TI (match_dup 2)))))))]
4704 "TARGET_64BIT"
4705 "@
4706 dlgr\t%0,%2
4707 dlg\t%0,%2"
4708 [(set_attr "op_type" "RRE,RXY")
4709 (set_attr "type" "idiv")])
4710
4711 ;
4712 ; divmodsi4 instruction pattern(s).
4713 ;
4714
4715 (define_expand "divmodsi4"
4716 [(parallel [(set (match_operand:SI 0 "general_operand" "")
4717 (div:SI (match_operand:SI 1 "general_operand" "")
4718 (match_operand:SI 2 "nonimmediate_operand" "")))
4719 (set (match_operand:SI 3 "general_operand" "")
4720 (mod:SI (match_dup 1) (match_dup 2)))])
4721 (clobber (match_dup 4))]
4722 "!TARGET_64BIT"
4723 {
4724 rtx insn, div_equal, mod_equal, equal;
4725
4726 div_equal = gen_rtx_DIV (SImode, operands[1], operands[2]);
4727 mod_equal = gen_rtx_MOD (SImode, operands[1], operands[2]);
4728 equal = gen_rtx_IOR (DImode,
4729 gen_rtx_ASHIFT (DImode,
4730 gen_rtx_ZERO_EXTEND (DImode, mod_equal),
4731 GEN_INT (32)),
4732 gen_rtx_ZERO_EXTEND (DImode, div_equal));
4733
4734 operands[4] = gen_reg_rtx(DImode);
4735 emit_insn (gen_extendsidi2 (operands[4], operands[1]));
4736
4737 insn = emit_insn (gen_divmoddisi3 (operands[4], operands[4], operands[2]));
4738 set_unique_reg_note (insn, REG_EQUAL, equal);
4739
4740 insn = emit_move_insn (operands[0], gen_lowpart (SImode, operands[4]));
4741 set_unique_reg_note (insn, REG_EQUAL, div_equal);
4742
4743 insn = emit_move_insn (operands[3], gen_highpart (SImode, operands[4]));
4744 set_unique_reg_note (insn, REG_EQUAL, mod_equal);
4745
4746 DONE;
4747 })
4748
4749 (define_insn "divmoddisi3"
4750 [(set (match_operand:DI 0 "register_operand" "=d,d")
4751 (ior:DI
4752 (ashift:DI
4753 (zero_extend:DI
4754 (truncate:SI
4755 (mod:DI (match_operand:DI 1 "register_operand" "0,0")
4756 (sign_extend:DI
4757 (match_operand:SI 2 "nonimmediate_operand" "d,R")))))
4758 (const_int 32))
4759 (zero_extend:DI
4760 (truncate:SI
4761 (div:DI (match_dup 1) (sign_extend:DI (match_dup 2)))))))]
4762 "!TARGET_64BIT"
4763 "@
4764 dr\t%0,%2
4765 d\t%0,%2"
4766 [(set_attr "op_type" "RR,RX")
4767 (set_attr "type" "idiv")])
4768
4769 ;
4770 ; udivsi3 and umodsi3 instruction pattern(s).
4771 ;
4772
4773 (define_expand "udivmodsi4"
4774 [(parallel [(set (match_operand:SI 0 "general_operand" "")
4775 (udiv:SI (match_operand:SI 1 "general_operand" "")
4776 (match_operand:SI 2 "nonimmediate_operand" "")))
4777 (set (match_operand:SI 3 "general_operand" "")
4778 (umod:SI (match_dup 1) (match_dup 2)))])
4779 (clobber (match_dup 4))]
4780 "!TARGET_64BIT && TARGET_CPU_ZARCH"
4781 {
4782 rtx insn, div_equal, mod_equal, equal;
4783
4784 div_equal = gen_rtx_UDIV (SImode, operands[1], operands[2]);
4785 mod_equal = gen_rtx_UMOD (SImode, operands[1], operands[2]);
4786 equal = gen_rtx_IOR (DImode,
4787 gen_rtx_ASHIFT (DImode,
4788 gen_rtx_ZERO_EXTEND (DImode, mod_equal),
4789 GEN_INT (32)),
4790 gen_rtx_ZERO_EXTEND (DImode, div_equal));
4791
4792 operands[4] = gen_reg_rtx(DImode);
4793 emit_insn (gen_rtx_CLOBBER (VOIDmode, operands[4]));
4794 emit_move_insn (gen_lowpart (SImode, operands[4]), operands[1]);
4795 emit_move_insn (gen_highpart (SImode, operands[4]), const0_rtx);
4796
4797 insn = emit_insn (gen_udivmoddisi3 (operands[4], operands[4], operands[2]));
4798 set_unique_reg_note (insn, REG_EQUAL, equal);
4799
4800 insn = emit_move_insn (operands[0], gen_lowpart (SImode, operands[4]));
4801 set_unique_reg_note (insn, REG_EQUAL, div_equal);
4802
4803 insn = emit_move_insn (operands[3], gen_highpart (SImode, operands[4]));
4804 set_unique_reg_note (insn, REG_EQUAL, mod_equal);
4805
4806 DONE;
4807 })
4808
4809 (define_insn "udivmoddisi3"
4810 [(set (match_operand:DI 0 "register_operand" "=d,d")
4811 (ior:DI
4812 (ashift:DI
4813 (zero_extend:DI
4814 (truncate:SI
4815 (umod:DI (match_operand:DI 1 "register_operand" "0,0")
4816 (zero_extend:DI
4817 (match_operand:SI 2 "nonimmediate_operand" "d,m")))))
4818 (const_int 32))
4819 (zero_extend:DI
4820 (truncate:SI
4821 (udiv:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))))]
4822 "!TARGET_64BIT && TARGET_CPU_ZARCH"
4823 "@
4824 dlr\t%0,%2
4825 dl\t%0,%2"
4826 [(set_attr "op_type" "RRE,RXY")
4827 (set_attr "type" "idiv")])
4828
4829 (define_expand "udivsi3"
4830 [(set (match_operand:SI 0 "register_operand" "=d")
4831 (udiv:SI (match_operand:SI 1 "general_operand" "")
4832 (match_operand:SI 2 "general_operand" "")))
4833 (clobber (match_dup 3))]
4834 "!TARGET_64BIT && !TARGET_CPU_ZARCH"
4835 {
4836 rtx insn, udiv_equal, umod_equal, equal;
4837
4838 udiv_equal = gen_rtx_UDIV (SImode, operands[1], operands[2]);
4839 umod_equal = gen_rtx_UMOD (SImode, operands[1], operands[2]);
4840 equal = gen_rtx_IOR (DImode,
4841 gen_rtx_ASHIFT (DImode,
4842 gen_rtx_ZERO_EXTEND (DImode, umod_equal),
4843 GEN_INT (32)),
4844 gen_rtx_ZERO_EXTEND (DImode, udiv_equal));
4845
4846 operands[3] = gen_reg_rtx (DImode);
4847
4848 if (CONSTANT_P (operands[2]))
4849 {
4850 if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0)
4851 {
4852 rtx label1 = gen_label_rtx ();
4853
4854 operands[1] = make_safe_from (operands[1], operands[0]);
4855 emit_move_insn (operands[0], const0_rtx);
4856 emit_insn (gen_cmpsi (operands[1], operands[2]));
4857 emit_jump_insn (gen_bltu (label1));
4858 emit_move_insn (operands[0], const1_rtx);
4859 emit_label (label1);
4860 }
4861 else
4862 {
4863 operands[2] = force_reg (SImode, operands[2]);
4864 operands[2] = make_safe_from (operands[2], operands[0]);
4865
4866 emit_insn (gen_zero_extendsidi2 (operands[3], operands[1]));
4867 insn = emit_insn (gen_divmoddisi3 (operands[3], operands[3],
4868 operands[2]));
4869 set_unique_reg_note (insn, REG_EQUAL, equal);
4870
4871 insn = emit_move_insn (operands[0],
4872 gen_lowpart (SImode, operands[3]));
4873 set_unique_reg_note (insn, REG_EQUAL, udiv_equal);
4874 }
4875 }
4876 else
4877 {
4878 rtx label1 = gen_label_rtx ();
4879 rtx label2 = gen_label_rtx ();
4880 rtx label3 = gen_label_rtx ();
4881
4882 operands[1] = force_reg (SImode, operands[1]);
4883 operands[1] = make_safe_from (operands[1], operands[0]);
4884 operands[2] = force_reg (SImode, operands[2]);
4885 operands[2] = make_safe_from (operands[2], operands[0]);
4886
4887 emit_move_insn (operands[0], const0_rtx);
4888 emit_insn (gen_cmpsi (operands[2], operands[1]));
4889 emit_jump_insn (gen_bgtu (label3));
4890 emit_insn (gen_cmpsi (operands[2], const0_rtx));
4891 emit_jump_insn (gen_blt (label2));
4892 emit_insn (gen_cmpsi (operands[2], const1_rtx));
4893 emit_jump_insn (gen_beq (label1));
4894 emit_insn (gen_zero_extendsidi2 (operands[3], operands[1]));
4895 insn = emit_insn (gen_divmoddisi3 (operands[3], operands[3],
4896 operands[2]));
4897 set_unique_reg_note (insn, REG_EQUAL, equal);
4898
4899 insn = emit_move_insn (operands[0],
4900 gen_lowpart (SImode, operands[3]));
4901 set_unique_reg_note (insn, REG_EQUAL, udiv_equal);
4902
4903 emit_jump (label3);
4904 emit_label (label1);
4905 emit_move_insn (operands[0], operands[1]);
4906 emit_jump (label3);
4907 emit_label (label2);
4908 emit_move_insn (operands[0], const1_rtx);
4909 emit_label (label3);
4910 }
4911 emit_move_insn (operands[0], operands[0]);
4912 DONE;
4913 })
4914
4915 (define_expand "umodsi3"
4916 [(set (match_operand:SI 0 "register_operand" "=d")
4917 (umod:SI (match_operand:SI 1 "nonimmediate_operand" "")
4918 (match_operand:SI 2 "nonimmediate_operand" "")))
4919 (clobber (match_dup 3))]
4920 "!TARGET_64BIT && !TARGET_CPU_ZARCH"
4921 {
4922 rtx insn, udiv_equal, umod_equal, equal;
4923
4924 udiv_equal = gen_rtx_UDIV (SImode, operands[1], operands[2]);
4925 umod_equal = gen_rtx_UMOD (SImode, operands[1], operands[2]);
4926 equal = gen_rtx_IOR (DImode,
4927 gen_rtx_ASHIFT (DImode,
4928 gen_rtx_ZERO_EXTEND (DImode, umod_equal),
4929 GEN_INT (32)),
4930 gen_rtx_ZERO_EXTEND (DImode, udiv_equal));
4931
4932 operands[3] = gen_reg_rtx (DImode);
4933
4934 if (CONSTANT_P (operands[2]))
4935 {
4936 if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) <= 0)
4937 {
4938 rtx label1 = gen_label_rtx ();
4939
4940 operands[1] = make_safe_from (operands[1], operands[0]);
4941 emit_move_insn (operands[0], operands[1]);
4942 emit_insn (gen_cmpsi (operands[0], operands[2]));
4943 emit_jump_insn (gen_bltu (label1));
4944 emit_insn (gen_abssi2 (operands[0], operands[2]));
4945 emit_insn (gen_addsi3 (operands[0], operands[0], operands[1]));
4946 emit_label (label1);
4947 }
4948 else
4949 {
4950 operands[2] = force_reg (SImode, operands[2]);
4951 operands[2] = make_safe_from (operands[2], operands[0]);
4952
4953 emit_insn (gen_zero_extendsidi2 (operands[3], operands[1]));
4954 insn = emit_insn (gen_divmoddisi3 (operands[3], operands[3],
4955 operands[2]));
4956 set_unique_reg_note (insn, REG_EQUAL, equal);
4957
4958 insn = emit_move_insn (operands[0],
4959 gen_highpart (SImode, operands[3]));
4960 set_unique_reg_note (insn, REG_EQUAL, umod_equal);
4961 }
4962 }
4963 else
4964 {
4965 rtx label1 = gen_label_rtx ();
4966 rtx label2 = gen_label_rtx ();
4967 rtx label3 = gen_label_rtx ();
4968
4969 operands[1] = force_reg (SImode, operands[1]);
4970 operands[1] = make_safe_from (operands[1], operands[0]);
4971 operands[2] = force_reg (SImode, operands[2]);
4972 operands[2] = make_safe_from (operands[2], operands[0]);
4973
4974 emit_move_insn(operands[0], operands[1]);
4975 emit_insn (gen_cmpsi (operands[2], operands[1]));
4976 emit_jump_insn (gen_bgtu (label3));
4977 emit_insn (gen_cmpsi (operands[2], const0_rtx));
4978 emit_jump_insn (gen_blt (label2));
4979 emit_insn (gen_cmpsi (operands[2], const1_rtx));
4980 emit_jump_insn (gen_beq (label1));
4981 emit_insn (gen_zero_extendsidi2 (operands[3], operands[1]));
4982 insn = emit_insn (gen_divmoddisi3 (operands[3], operands[3],
4983 operands[2]));
4984 set_unique_reg_note (insn, REG_EQUAL, equal);
4985
4986 insn = emit_move_insn (operands[0],
4987 gen_highpart (SImode, operands[3]));
4988 set_unique_reg_note (insn, REG_EQUAL, umod_equal);
4989
4990 emit_jump (label3);
4991 emit_label (label1);
4992 emit_move_insn (operands[0], const0_rtx);
4993 emit_jump (label3);
4994 emit_label (label2);
4995 emit_insn (gen_subsi3 (operands[0], operands[0], operands[2]));
4996 emit_label (label3);
4997 }
4998 DONE;
4999 })
5000
5001 ;
5002 ; div(df|sf)3 instruction pattern(s).
5003 ;
5004
5005 ; dxbr, ddbr, debr, dxb, ddb, deb, ddtr, dxtr
5006 (define_insn "div<mode>3"
5007 [(set (match_operand:FP 0 "register_operand" "=f,f")
5008 (div:FP (match_operand:FP 1 "register_operand" "<f0>,0")
5009 (match_operand:FP 2 "general_operand" "f,<Rf>")))]
5010 "TARGET_HARD_FLOAT"
5011 "@
5012 d<xde><bt>r\t%0,<op1>%2
5013 d<xde>b\t%0,%2"
5014 [(set_attr "op_type" "<RRer>,RXE")
5015 (set_attr "type" "fdiv<bfp>")])
5016
5017
5018 ;;
5019 ;;- And instructions.
5020 ;;
5021
5022 (define_expand "and<mode>3"
5023 [(set (match_operand:INT 0 "nonimmediate_operand" "")
5024 (and:INT (match_operand:INT 1 "nonimmediate_operand" "")
5025 (match_operand:INT 2 "general_operand" "")))
5026 (clobber (reg:CC CC_REGNUM))]
5027 ""
5028 "s390_expand_logical_operator (AND, <MODE>mode, operands); DONE;")
5029
5030 ;
5031 ; anddi3 instruction pattern(s).
5032 ;
5033
5034 (define_insn "*anddi3_cc"
5035 [(set (reg CC_REGNUM)
5036 (compare (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
5037 (match_operand:DI 2 "general_operand" "d,m"))
5038 (const_int 0)))
5039 (set (match_operand:DI 0 "register_operand" "=d,d")
5040 (and:DI (match_dup 1) (match_dup 2)))]
5041 "s390_match_ccmode(insn, CCTmode) && TARGET_64BIT"
5042 "@
5043 ngr\t%0,%2
5044 ng\t%0,%2"
5045 [(set_attr "op_type" "RRE,RXY")])
5046
5047 (define_insn "*anddi3_cconly"
5048 [(set (reg CC_REGNUM)
5049 (compare (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
5050 (match_operand:DI 2 "general_operand" "d,m"))
5051 (const_int 0)))
5052 (clobber (match_scratch:DI 0 "=d,d"))]
5053 "s390_match_ccmode(insn, CCTmode) && TARGET_64BIT
5054 /* Do not steal TM patterns. */
5055 && s390_single_part (operands[2], DImode, HImode, 0) < 0"
5056 "@
5057 ngr\t%0,%2
5058 ng\t%0,%2"
5059 [(set_attr "op_type" "RRE,RXY")])
5060
5061 (define_insn "*anddi3_extimm"
5062 [(set (match_operand:DI 0 "nonimmediate_operand" "=d,d,d,d,d,d,d,d,d,d,AQ,Q")
5063 (and:DI (match_operand:DI 1 "nonimmediate_operand"
5064 "%d,o,0,0,0,0,0,0,0,0,0,0")
5065 (match_operand:DI 2 "general_operand"
5066 "M,M,N0HDF,N1HDF,N2HDF,N3HDF,N0SDF,N1SDF,d,m,NxQDF,Q")))
5067 (clobber (reg:CC CC_REGNUM))]
5068 "TARGET_64BIT && TARGET_EXTIMM && s390_logical_operator_ok_p (operands)"
5069 "@
5070 #
5071 #
5072 nihh\t%0,%j2
5073 nihl\t%0,%j2
5074 nilh\t%0,%j2
5075 nill\t%0,%j2
5076 nihf\t%0,%m2
5077 nilf\t%0,%m2
5078 ngr\t%0,%2
5079 ng\t%0,%2
5080 #
5081 #"
5082 [(set_attr "op_type" "RRE,RXE,RI,RI,RI,RI,RIL,RIL,RRE,RXY,SI,SS")])
5083
5084 (define_insn "*anddi3"
5085 [(set (match_operand:DI 0 "nonimmediate_operand" "=d,d,d,d,d,d,d,d,AQ,Q")
5086 (and:DI (match_operand:DI 1 "nonimmediate_operand"
5087 "%d,o,0,0,0,0,0,0,0,0")
5088 (match_operand:DI 2 "general_operand"
5089 "M,M,N0HDF,N1HDF,N2HDF,N3HDF,d,m,NxQDF,Q")))
5090 (clobber (reg:CC CC_REGNUM))]
5091 "TARGET_64BIT && !TARGET_EXTIMM && s390_logical_operator_ok_p (operands)"
5092 "@
5093 #
5094 #
5095 nihh\t%0,%j2
5096 nihl\t%0,%j2
5097 nilh\t%0,%j2
5098 nill\t%0,%j2
5099 ngr\t%0,%2
5100 ng\t%0,%2
5101 #
5102 #"
5103 [(set_attr "op_type" "RRE,RXE,RI,RI,RI,RI,RRE,RXY,SI,SS")])
5104
5105 (define_split
5106 [(set (match_operand:DI 0 "s_operand" "")
5107 (and:DI (match_dup 0) (match_operand:DI 1 "immediate_operand" "")))
5108 (clobber (reg:CC CC_REGNUM))]
5109 "reload_completed"
5110 [(parallel
5111 [(set (match_dup 0) (and:QI (match_dup 0) (match_dup 1)))
5112 (clobber (reg:CC CC_REGNUM))])]
5113 "s390_narrow_logical_operator (AND, &operands[0], &operands[1]);")
5114
5115
5116 ;
5117 ; andsi3 instruction pattern(s).
5118 ;
5119
5120 (define_insn "*andsi3_cc"
5121 [(set (reg CC_REGNUM)
5122 (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,0,0")
5123 (match_operand:SI 2 "general_operand" "Os,d,R,T"))
5124 (const_int 0)))
5125 (set (match_operand:SI 0 "register_operand" "=d,d,d,d")
5126 (and:SI (match_dup 1) (match_dup 2)))]
5127 "s390_match_ccmode(insn, CCTmode)"
5128 "@
5129 nilf\t%0,%o2
5130 nr\t%0,%2
5131 n\t%0,%2
5132 ny\t%0,%2"
5133 [(set_attr "op_type" "RIL,RR,RX,RXY")])
5134
5135 (define_insn "*andsi3_cconly"
5136 [(set (reg CC_REGNUM)
5137 (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,0,0")
5138 (match_operand:SI 2 "general_operand" "Os,d,R,T"))
5139 (const_int 0)))
5140 (clobber (match_scratch:SI 0 "=d,d,d,d"))]
5141 "s390_match_ccmode(insn, CCTmode)
5142 /* Do not steal TM patterns. */
5143 && s390_single_part (operands[2], SImode, HImode, 0) < 0"
5144 "@
5145 nilf\t%0,%o2
5146 nr\t%0,%2
5147 n\t%0,%2
5148 ny\t%0,%2"
5149 [(set_attr "op_type" "RIL,RR,RX,RXY")])
5150
5151 (define_insn "*andsi3_zarch"
5152 [(set (match_operand:SI 0 "nonimmediate_operand" "=d,d,d,d,d,d,d,d,AQ,Q")
5153 (and:SI (match_operand:SI 1 "nonimmediate_operand"
5154 "%d,o,0,0,0,0,0,0,0,0")
5155 (match_operand:SI 2 "general_operand"
5156 "M,M,N0HSF,N1HSF,Os,d,R,T,NxQSF,Q")))
5157 (clobber (reg:CC CC_REGNUM))]
5158 "TARGET_ZARCH && s390_logical_operator_ok_p (operands)"
5159 "@
5160 #
5161 #
5162 nilh\t%0,%j2
5163 nill\t%0,%j2
5164 nilf\t%0,%o2
5165 nr\t%0,%2
5166 n\t%0,%2
5167 ny\t%0,%2
5168 #
5169 #"
5170 [(set_attr "op_type" "RRE,RXE,RI,RI,RIL,RR,RX,RXY,SI,SS")])
5171
5172 (define_insn "*andsi3_esa"
5173 [(set (match_operand:SI 0 "nonimmediate_operand" "=d,d,AQ,Q")
5174 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,0,0")
5175 (match_operand:SI 2 "general_operand" "d,R,NxQSF,Q")))
5176 (clobber (reg:CC CC_REGNUM))]
5177 "!TARGET_ZARCH && s390_logical_operator_ok_p (operands)"
5178 "@
5179 nr\t%0,%2
5180 n\t%0,%2
5181 #
5182 #"
5183 [(set_attr "op_type" "RR,RX,SI,SS")])
5184
5185 (define_split
5186 [(set (match_operand:SI 0 "s_operand" "")
5187 (and:SI (match_dup 0) (match_operand:SI 1 "immediate_operand" "")))
5188 (clobber (reg:CC CC_REGNUM))]
5189 "reload_completed"
5190 [(parallel
5191 [(set (match_dup 0) (and:QI (match_dup 0) (match_dup 1)))
5192 (clobber (reg:CC CC_REGNUM))])]
5193 "s390_narrow_logical_operator (AND, &operands[0], &operands[1]);")
5194
5195 ;
5196 ; andhi3 instruction pattern(s).
5197 ;
5198
5199 (define_insn "*andhi3_zarch"
5200 [(set (match_operand:HI 0 "nonimmediate_operand" "=d,d,AQ,Q")
5201 (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,0,0")
5202 (match_operand:HI 2 "general_operand" "d,n,NxQHF,Q")))
5203 (clobber (reg:CC CC_REGNUM))]
5204 "TARGET_ZARCH && s390_logical_operator_ok_p (operands)"
5205 "@
5206 nr\t%0,%2
5207 nill\t%0,%x2
5208 #
5209 #"
5210 [(set_attr "op_type" "RR,RI,SI,SS")])
5211
5212 (define_insn "*andhi3_esa"
5213 [(set (match_operand:HI 0 "nonimmediate_operand" "=d,AQ,Q")
5214 (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,0")
5215 (match_operand:HI 2 "general_operand" "d,NxQHF,Q")))
5216 (clobber (reg:CC CC_REGNUM))]
5217 "!TARGET_ZARCH && s390_logical_operator_ok_p (operands)"
5218 "@
5219 nr\t%0,%2
5220 #
5221 #"
5222 [(set_attr "op_type" "RR,SI,SS")])
5223
5224 (define_split
5225 [(set (match_operand:HI 0 "s_operand" "")
5226 (and:HI (match_dup 0) (match_operand:HI 1 "immediate_operand" "")))
5227 (clobber (reg:CC CC_REGNUM))]
5228 "reload_completed"
5229 [(parallel
5230 [(set (match_dup 0) (and:QI (match_dup 0) (match_dup 1)))
5231 (clobber (reg:CC CC_REGNUM))])]
5232 "s390_narrow_logical_operator (AND, &operands[0], &operands[1]);")
5233
5234 ;
5235 ; andqi3 instruction pattern(s).
5236 ;
5237
5238 (define_insn "*andqi3_zarch"
5239 [(set (match_operand:QI 0 "nonimmediate_operand" "=d,d,Q,S,Q")
5240 (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,0,0")
5241 (match_operand:QI 2 "general_operand" "d,n,n,n,Q")))
5242 (clobber (reg:CC CC_REGNUM))]
5243 "TARGET_ZARCH && s390_logical_operator_ok_p (operands)"
5244 "@
5245 nr\t%0,%2
5246 nill\t%0,%b2
5247 ni\t%S0,%b2
5248 niy\t%S0,%b2
5249 #"
5250 [(set_attr "op_type" "RR,RI,SI,SIY,SS")])
5251
5252 (define_insn "*andqi3_esa"
5253 [(set (match_operand:QI 0 "nonimmediate_operand" "=d,Q,Q")
5254 (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
5255 (match_operand:QI 2 "general_operand" "d,n,Q")))
5256 (clobber (reg:CC CC_REGNUM))]
5257 "!TARGET_ZARCH && s390_logical_operator_ok_p (operands)"
5258 "@
5259 nr\t%0,%2
5260 ni\t%S0,%b2
5261 #"
5262 [(set_attr "op_type" "RR,SI,SS")])
5263
5264 ;
5265 ; Block and (NC) patterns.
5266 ;
5267
5268 (define_insn "*nc"
5269 [(set (match_operand:BLK 0 "memory_operand" "=Q")
5270 (and:BLK (match_dup 0)
5271 (match_operand:BLK 1 "memory_operand" "Q")))
5272 (use (match_operand 2 "const_int_operand" "n"))
5273 (clobber (reg:CC CC_REGNUM))]
5274 "INTVAL (operands[2]) >= 1 && INTVAL (operands[2]) <= 256"
5275 "nc\t%O0(%2,%R0),%S1"
5276 [(set_attr "op_type" "SS")])
5277
5278 (define_split
5279 [(set (match_operand 0 "memory_operand" "")
5280 (and (match_dup 0)
5281 (match_operand 1 "memory_operand" "")))
5282 (clobber (reg:CC CC_REGNUM))]
5283 "reload_completed
5284 && GET_MODE (operands[0]) == GET_MODE (operands[1])
5285 && GET_MODE_SIZE (GET_MODE (operands[0])) > 0"
5286 [(parallel
5287 [(set (match_dup 0) (and:BLK (match_dup 0) (match_dup 1)))
5288 (use (match_dup 2))
5289 (clobber (reg:CC CC_REGNUM))])]
5290 {
5291 operands[2] = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[0])));
5292 operands[0] = adjust_address (operands[0], BLKmode, 0);
5293 operands[1] = adjust_address (operands[1], BLKmode, 0);
5294 })
5295
5296 (define_peephole2
5297 [(parallel
5298 [(set (match_operand:BLK 0 "memory_operand" "")
5299 (and:BLK (match_dup 0)
5300 (match_operand:BLK 1 "memory_operand" "")))
5301 (use (match_operand 2 "const_int_operand" ""))
5302 (clobber (reg:CC CC_REGNUM))])
5303 (parallel
5304 [(set (match_operand:BLK 3 "memory_operand" "")
5305 (and:BLK (match_dup 3)
5306 (match_operand:BLK 4 "memory_operand" "")))
5307 (use (match_operand 5 "const_int_operand" ""))
5308 (clobber (reg:CC CC_REGNUM))])]
5309 "s390_offset_p (operands[0], operands[3], operands[2])
5310 && s390_offset_p (operands[1], operands[4], operands[2])
5311 && !s390_overlap_p (operands[0], operands[1],
5312 INTVAL (operands[2]) + INTVAL (operands[5]))
5313 && INTVAL (operands[2]) + INTVAL (operands[5]) <= 256"
5314 [(parallel
5315 [(set (match_dup 6) (and:BLK (match_dup 6) (match_dup 7)))
5316 (use (match_dup 8))
5317 (clobber (reg:CC CC_REGNUM))])]
5318 "operands[6] = gen_rtx_MEM (BLKmode, XEXP (operands[0], 0));
5319 operands[7] = gen_rtx_MEM (BLKmode, XEXP (operands[1], 0));
5320 operands[8] = GEN_INT (INTVAL (operands[2]) + INTVAL (operands[5]));")
5321
5322
5323 ;;
5324 ;;- Bit set (inclusive or) instructions.
5325 ;;
5326
5327 (define_expand "ior<mode>3"
5328 [(set (match_operand:INT 0 "nonimmediate_operand" "")
5329 (ior:INT (match_operand:INT 1 "nonimmediate_operand" "")
5330 (match_operand:INT 2 "general_operand" "")))
5331 (clobber (reg:CC CC_REGNUM))]
5332 ""
5333 "s390_expand_logical_operator (IOR, <MODE>mode, operands); DONE;")
5334
5335 ;
5336 ; iordi3 instruction pattern(s).
5337 ;
5338
5339 (define_insn "*iordi3_cc"
5340 [(set (reg CC_REGNUM)
5341 (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
5342 (match_operand:DI 2 "general_operand" "d,m"))
5343 (const_int 0)))
5344 (set (match_operand:DI 0 "register_operand" "=d,d")
5345 (ior:DI (match_dup 1) (match_dup 2)))]
5346 "s390_match_ccmode(insn, CCTmode) && TARGET_64BIT"
5347 "@
5348 ogr\t%0,%2
5349 og\t%0,%2"
5350 [(set_attr "op_type" "RRE,RXY")])
5351
5352 (define_insn "*iordi3_cconly"
5353 [(set (reg CC_REGNUM)
5354 (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
5355 (match_operand:DI 2 "general_operand" "d,m"))
5356 (const_int 0)))
5357 (clobber (match_scratch:DI 0 "=d,d"))]
5358 "s390_match_ccmode(insn, CCTmode) && TARGET_64BIT"
5359 "@
5360 ogr\t%0,%2
5361 og\t%0,%2"
5362 [(set_attr "op_type" "RRE,RXY")])
5363
5364 (define_insn "*iordi3_extimm"
5365 [(set (match_operand:DI 0 "nonimmediate_operand" "=d,d,d,d,d,d,d,d,AQ,Q")
5366 (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,0,0,0,0,0,0,0")
5367 (match_operand:DI 2 "general_operand"
5368 "N0HD0,N1HD0,N2HD0,N3HD0,N0SD0,N1SD0,d,m,NxQD0,Q")))
5369 (clobber (reg:CC CC_REGNUM))]
5370 "TARGET_64BIT && TARGET_EXTIMM && s390_logical_operator_ok_p (operands)"
5371 "@
5372 oihh\t%0,%i2
5373 oihl\t%0,%i2
5374 oilh\t%0,%i2
5375 oill\t%0,%i2
5376 oihf\t%0,%k2
5377 oilf\t%0,%k2
5378 ogr\t%0,%2
5379 og\t%0,%2
5380 #
5381 #"
5382 [(set_attr "op_type" "RI,RI,RI,RI,RIL,RIL,RRE,RXY,SI,SS")])
5383
5384 (define_insn "*iordi3"
5385 [(set (match_operand:DI 0 "nonimmediate_operand" "=d,d,d,d,d,d,AQ,Q")
5386 (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,0,0,0,0,0")
5387 (match_operand:DI 2 "general_operand"
5388 "N0HD0,N1HD0,N2HD0,N3HD0,d,m,NxQD0,Q")))
5389 (clobber (reg:CC CC_REGNUM))]
5390 "TARGET_64BIT && !TARGET_EXTIMM && s390_logical_operator_ok_p (operands)"
5391 "@
5392 oihh\t%0,%i2
5393 oihl\t%0,%i2
5394 oilh\t%0,%i2
5395 oill\t%0,%i2
5396 ogr\t%0,%2
5397 og\t%0,%2
5398 #
5399 #"
5400 [(set_attr "op_type" "RI,RI,RI,RI,RRE,RXY,SI,SS")])
5401
5402 (define_split
5403 [(set (match_operand:DI 0 "s_operand" "")
5404 (ior:DI (match_dup 0) (match_operand:DI 1 "immediate_operand" "")))
5405 (clobber (reg:CC CC_REGNUM))]
5406 "reload_completed"
5407 [(parallel
5408 [(set (match_dup 0) (ior:QI (match_dup 0) (match_dup 1)))
5409 (clobber (reg:CC CC_REGNUM))])]
5410 "s390_narrow_logical_operator (IOR, &operands[0], &operands[1]);")
5411
5412 ;
5413 ; iorsi3 instruction pattern(s).
5414 ;
5415
5416 (define_insn "*iorsi3_cc"
5417 [(set (reg CC_REGNUM)
5418 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,0,0")
5419 (match_operand:SI 2 "general_operand" "Os,d,R,T"))
5420 (const_int 0)))
5421 (set (match_operand:SI 0 "register_operand" "=d,d,d,d")
5422 (ior:SI (match_dup 1) (match_dup 2)))]
5423 "s390_match_ccmode(insn, CCTmode)"
5424 "@
5425 oilf\t%0,%o2
5426 or\t%0,%2
5427 o\t%0,%2
5428 oy\t%0,%2"
5429 [(set_attr "op_type" "RIL,RR,RX,RXY")])
5430
5431 (define_insn "*iorsi3_cconly"
5432 [(set (reg CC_REGNUM)
5433 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,0,0")
5434 (match_operand:SI 2 "general_operand" "Os,d,R,T"))
5435 (const_int 0)))
5436 (clobber (match_scratch:SI 0 "=d,d,d,d"))]
5437 "s390_match_ccmode(insn, CCTmode)"
5438 "@
5439 oilf\t%0,%o2
5440 or\t%0,%2
5441 o\t%0,%2
5442 oy\t%0,%2"
5443 [(set_attr "op_type" "RIL,RR,RX,RXY")])
5444
5445 (define_insn "*iorsi3_zarch"
5446 [(set (match_operand:SI 0 "nonimmediate_operand" "=d,d,d,d,d,d,AQ,Q")
5447 (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,0,0,0,0,0,0")
5448 (match_operand:SI 2 "general_operand" "N0HS0,N1HS0,Os,d,R,T,NxQS0,Q")))
5449 (clobber (reg:CC CC_REGNUM))]
5450 "TARGET_ZARCH && s390_logical_operator_ok_p (operands)"
5451 "@
5452 oilh\t%0,%i2
5453 oill\t%0,%i2
5454 oilf\t%0,%o2
5455 or\t%0,%2
5456 o\t%0,%2
5457 oy\t%0,%2
5458 #
5459 #"
5460 [(set_attr "op_type" "RI,RI,RIL,RR,RX,RXY,SI,SS")])
5461
5462 (define_insn "*iorsi3_esa"
5463 [(set (match_operand:SI 0 "nonimmediate_operand" "=d,d,AQ,Q")
5464 (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,0,0")
5465 (match_operand:SI 2 "general_operand" "d,R,NxQS0,Q")))
5466 (clobber (reg:CC CC_REGNUM))]
5467 "!TARGET_ZARCH && s390_logical_operator_ok_p (operands)"
5468 "@
5469 or\t%0,%2
5470 o\t%0,%2
5471 #
5472 #"
5473 [(set_attr "op_type" "RR,RX,SI,SS")])
5474
5475 (define_split
5476 [(set (match_operand:SI 0 "s_operand" "")
5477 (ior:SI (match_dup 0) (match_operand:SI 1 "immediate_operand" "")))
5478 (clobber (reg:CC CC_REGNUM))]
5479 "reload_completed"
5480 [(parallel
5481 [(set (match_dup 0) (ior:QI (match_dup 0) (match_dup 1)))
5482 (clobber (reg:CC CC_REGNUM))])]
5483 "s390_narrow_logical_operator (IOR, &operands[0], &operands[1]);")
5484
5485 ;
5486 ; iorhi3 instruction pattern(s).
5487 ;
5488
5489 (define_insn "*iorhi3_zarch"
5490 [(set (match_operand:HI 0 "nonimmediate_operand" "=d,d,AQ,Q")
5491 (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,0,0")
5492 (match_operand:HI 2 "general_operand" "d,n,NxQH0,Q")))
5493 (clobber (reg:CC CC_REGNUM))]
5494 "TARGET_ZARCH && s390_logical_operator_ok_p (operands)"
5495 "@
5496 or\t%0,%2
5497 oill\t%0,%x2
5498 #
5499 #"
5500 [(set_attr "op_type" "RR,RI,SI,SS")])
5501
5502 (define_insn "*iorhi3_esa"
5503 [(set (match_operand:HI 0 "nonimmediate_operand" "=d,AQ,Q")
5504 (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,0")
5505 (match_operand:HI 2 "general_operand" "d,NxQH0,Q")))
5506 (clobber (reg:CC CC_REGNUM))]
5507 "!TARGET_ZARCH && s390_logical_operator_ok_p (operands)"
5508 "@
5509 or\t%0,%2
5510 #
5511 #"
5512 [(set_attr "op_type" "RR,SI,SS")])
5513
5514 (define_split
5515 [(set (match_operand:HI 0 "s_operand" "")
5516 (ior:HI (match_dup 0) (match_operand:HI 1 "immediate_operand" "")))
5517 (clobber (reg:CC CC_REGNUM))]
5518 "reload_completed"
5519 [(parallel
5520 [(set (match_dup 0) (ior:QI (match_dup 0) (match_dup 1)))
5521 (clobber (reg:CC CC_REGNUM))])]
5522 "s390_narrow_logical_operator (IOR, &operands[0], &operands[1]);")
5523
5524 ;
5525 ; iorqi3 instruction pattern(s).
5526 ;
5527
5528 (define_insn "*iorqi3_zarch"
5529 [(set (match_operand:QI 0 "nonimmediate_operand" "=d,d,Q,S,Q")
5530 (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,0,0")
5531 (match_operand:QI 2 "general_operand" "d,n,n,n,Q")))
5532 (clobber (reg:CC CC_REGNUM))]
5533 "TARGET_ZARCH && s390_logical_operator_ok_p (operands)"
5534 "@
5535 or\t%0,%2
5536 oill\t%0,%b2
5537 oi\t%S0,%b2
5538 oiy\t%S0,%b2
5539 #"
5540 [(set_attr "op_type" "RR,RI,SI,SIY,SS")])
5541
5542 (define_insn "*iorqi3_esa"
5543 [(set (match_operand:QI 0 "nonimmediate_operand" "=d,Q,Q")
5544 (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
5545 (match_operand:QI 2 "general_operand" "d,n,Q")))
5546 (clobber (reg:CC CC_REGNUM))]
5547 "!TARGET_ZARCH && s390_logical_operator_ok_p (operands)"
5548 "@
5549 or\t%0,%2
5550 oi\t%S0,%b2
5551 #"
5552 [(set_attr "op_type" "RR,SI,SS")])
5553
5554 ;
5555 ; Block inclusive or (OC) patterns.
5556 ;
5557
5558 (define_insn "*oc"
5559 [(set (match_operand:BLK 0 "memory_operand" "=Q")
5560 (ior:BLK (match_dup 0)
5561 (match_operand:BLK 1 "memory_operand" "Q")))
5562 (use (match_operand 2 "const_int_operand" "n"))
5563 (clobber (reg:CC CC_REGNUM))]
5564 "INTVAL (operands[2]) >= 1 && INTVAL (operands[2]) <= 256"
5565 "oc\t%O0(%2,%R0),%S1"
5566 [(set_attr "op_type" "SS")])
5567
5568 (define_split
5569 [(set (match_operand 0 "memory_operand" "")
5570 (ior (match_dup 0)
5571 (match_operand 1 "memory_operand" "")))
5572 (clobber (reg:CC CC_REGNUM))]
5573 "reload_completed
5574 && GET_MODE (operands[0]) == GET_MODE (operands[1])
5575 && GET_MODE_SIZE (GET_MODE (operands[0])) > 0"
5576 [(parallel
5577 [(set (match_dup 0) (ior:BLK (match_dup 0) (match_dup 1)))
5578 (use (match_dup 2))
5579 (clobber (reg:CC CC_REGNUM))])]
5580 {
5581 operands[2] = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[0])));
5582 operands[0] = adjust_address (operands[0], BLKmode, 0);
5583 operands[1] = adjust_address (operands[1], BLKmode, 0);
5584 })
5585
5586 (define_peephole2
5587 [(parallel
5588 [(set (match_operand:BLK 0 "memory_operand" "")
5589 (ior:BLK (match_dup 0)
5590 (match_operand:BLK 1 "memory_operand" "")))
5591 (use (match_operand 2 "const_int_operand" ""))
5592 (clobber (reg:CC CC_REGNUM))])
5593 (parallel
5594 [(set (match_operand:BLK 3 "memory_operand" "")
5595 (ior:BLK (match_dup 3)
5596 (match_operand:BLK 4 "memory_operand" "")))
5597 (use (match_operand 5 "const_int_operand" ""))
5598 (clobber (reg:CC CC_REGNUM))])]
5599 "s390_offset_p (operands[0], operands[3], operands[2])
5600 && s390_offset_p (operands[1], operands[4], operands[2])
5601 && !s390_overlap_p (operands[0], operands[1],
5602 INTVAL (operands[2]) + INTVAL (operands[5]))
5603 && INTVAL (operands[2]) + INTVAL (operands[5]) <= 256"
5604 [(parallel
5605 [(set (match_dup 6) (ior:BLK (match_dup 6) (match_dup 7)))
5606 (use (match_dup 8))
5607 (clobber (reg:CC CC_REGNUM))])]
5608 "operands[6] = gen_rtx_MEM (BLKmode, XEXP (operands[0], 0));
5609 operands[7] = gen_rtx_MEM (BLKmode, XEXP (operands[1], 0));
5610 operands[8] = GEN_INT (INTVAL (operands[2]) + INTVAL (operands[5]));")
5611
5612
5613 ;;
5614 ;;- Xor instructions.
5615 ;;
5616
5617 (define_expand "xor<mode>3"
5618 [(set (match_operand:INT 0 "nonimmediate_operand" "")
5619 (xor:INT (match_operand:INT 1 "nonimmediate_operand" "")
5620 (match_operand:INT 2 "general_operand" "")))
5621 (clobber (reg:CC CC_REGNUM))]
5622 ""
5623 "s390_expand_logical_operator (XOR, <MODE>mode, operands); DONE;")
5624
5625 ;
5626 ; xordi3 instruction pattern(s).
5627 ;
5628
5629 (define_insn "*xordi3_cc"
5630 [(set (reg CC_REGNUM)
5631 (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
5632 (match_operand:DI 2 "general_operand" "d,m"))
5633 (const_int 0)))
5634 (set (match_operand:DI 0 "register_operand" "=d,d")
5635 (xor:DI (match_dup 1) (match_dup 2)))]
5636 "s390_match_ccmode(insn, CCTmode) && TARGET_64BIT"
5637 "@
5638 xgr\t%0,%2
5639 xg\t%0,%2"
5640 [(set_attr "op_type" "RRE,RXY")])
5641
5642 (define_insn "*xordi3_cconly"
5643 [(set (reg CC_REGNUM)
5644 (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
5645 (match_operand:DI 2 "general_operand" "d,m"))
5646 (const_int 0)))
5647 (clobber (match_scratch:DI 0 "=d,d"))]
5648 "s390_match_ccmode(insn, CCTmode) && TARGET_64BIT"
5649 "@
5650 xgr\t%0,%2
5651 xr\t%0,%2"
5652 [(set_attr "op_type" "RRE,RXY")])
5653
5654 (define_insn "*xordi3_extimm"
5655 [(set (match_operand:DI 0 "nonimmediate_operand" "=d,d,d,d,AQ,Q")
5656 (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,0,0,0")
5657 (match_operand:DI 2 "general_operand" "N0SD0,N1SD0,d,m,NxQD0,Q")))
5658 (clobber (reg:CC CC_REGNUM))]
5659 "TARGET_64BIT && TARGET_EXTIMM && s390_logical_operator_ok_p (operands)"
5660 "@
5661 xihf\t%0,%k2
5662 xilf\t%0,%k2
5663 xgr\t%0,%2
5664 xg\t%0,%2
5665 #
5666 #"
5667 [(set_attr "op_type" "RIL,RIL,RRE,RXY,SI,SS")])
5668
5669 (define_insn "*xordi3"
5670 [(set (match_operand:DI 0 "nonimmediate_operand" "=d,d,AQ,Q")
5671 (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,0")
5672 (match_operand:DI 2 "general_operand" "d,m,NxQD0,Q")))
5673 (clobber (reg:CC CC_REGNUM))]
5674 "TARGET_64BIT && !TARGET_EXTIMM && s390_logical_operator_ok_p (operands)"
5675 "@
5676 xgr\t%0,%2
5677 xg\t%0,%2
5678 #
5679 #"
5680 [(set_attr "op_type" "RRE,RXY,SI,SS")])
5681
5682 (define_split
5683 [(set (match_operand:DI 0 "s_operand" "")
5684 (xor:DI (match_dup 0) (match_operand:DI 1 "immediate_operand" "")))
5685 (clobber (reg:CC CC_REGNUM))]
5686 "reload_completed"
5687 [(parallel
5688 [(set (match_dup 0) (xor:QI (match_dup 0) (match_dup 1)))
5689 (clobber (reg:CC CC_REGNUM))])]
5690 "s390_narrow_logical_operator (XOR, &operands[0], &operands[1]);")
5691
5692 ;
5693 ; xorsi3 instruction pattern(s).
5694 ;
5695
5696 (define_insn "*xorsi3_cc"
5697 [(set (reg CC_REGNUM)
5698 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,0,0")
5699 (match_operand:SI 2 "general_operand" "Os,d,R,T"))
5700 (const_int 0)))
5701 (set (match_operand:SI 0 "register_operand" "=d,d,d,d")
5702 (xor:SI (match_dup 1) (match_dup 2)))]
5703 "s390_match_ccmode(insn, CCTmode)"
5704 "@
5705 xilf\t%0,%o2
5706 xr\t%0,%2
5707 x\t%0,%2
5708 xy\t%0,%2"
5709 [(set_attr "op_type" "RIL,RR,RX,RXY")])
5710
5711 (define_insn "*xorsi3_cconly"
5712 [(set (reg CC_REGNUM)
5713 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,0,0")
5714 (match_operand:SI 2 "general_operand" "Os,d,R,T"))
5715 (const_int 0)))
5716 (clobber (match_scratch:SI 0 "=d,d,d,d"))]
5717 "s390_match_ccmode(insn, CCTmode)"
5718 "@
5719 xilf\t%0,%o2
5720 xr\t%0,%2
5721 x\t%0,%2
5722 xy\t%0,%2"
5723 [(set_attr "op_type" "RIL,RR,RX,RXY")])
5724
5725 (define_insn "*xorsi3"
5726 [(set (match_operand:SI 0 "nonimmediate_operand" "=d,d,d,d,AQ,Q")
5727 (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,0,0,0,0")
5728 (match_operand:SI 2 "general_operand" "Os,d,R,T,NxQS0,Q")))
5729 (clobber (reg:CC CC_REGNUM))]
5730 "s390_logical_operator_ok_p (operands)"
5731 "@
5732 xilf\t%0,%o2
5733 xr\t%0,%2
5734 x\t%0,%2
5735 xy\t%0,%2
5736 #
5737 #"
5738 [(set_attr "op_type" "RIL,RR,RX,RXY,SI,SS")])
5739
5740 (define_split
5741 [(set (match_operand:SI 0 "s_operand" "")
5742 (xor:SI (match_dup 0) (match_operand:SI 1 "immediate_operand" "")))
5743 (clobber (reg:CC CC_REGNUM))]
5744 "reload_completed"
5745 [(parallel
5746 [(set (match_dup 0) (xor:QI (match_dup 0) (match_dup 1)))
5747 (clobber (reg:CC CC_REGNUM))])]
5748 "s390_narrow_logical_operator (XOR, &operands[0], &operands[1]);")
5749
5750 ;
5751 ; xorhi3 instruction pattern(s).
5752 ;
5753
5754 (define_insn "*xorhi3"
5755 [(set (match_operand:HI 0 "nonimmediate_operand" "=d,d,AQ,Q")
5756 (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,0,0")
5757 (match_operand:HI 2 "general_operand" "Os,d,NxQH0,Q")))
5758 (clobber (reg:CC CC_REGNUM))]
5759 "s390_logical_operator_ok_p (operands)"
5760 "@
5761 xilf\t%0,%x2
5762 xr\t%0,%2
5763 #
5764 #"
5765 [(set_attr "op_type" "RIL,RR,SI,SS")])
5766
5767 (define_split
5768 [(set (match_operand:HI 0 "s_operand" "")
5769 (xor:HI (match_dup 0) (match_operand:HI 1 "immediate_operand" "")))
5770 (clobber (reg:CC CC_REGNUM))]
5771 "reload_completed"
5772 [(parallel
5773 [(set (match_dup 0) (xor:QI (match_dup 0) (match_dup 1)))
5774 (clobber (reg:CC CC_REGNUM))])]
5775 "s390_narrow_logical_operator (XOR, &operands[0], &operands[1]);")
5776
5777 ;
5778 ; xorqi3 instruction pattern(s).
5779 ;
5780
5781 (define_insn "*xorqi3"
5782 [(set (match_operand:QI 0 "nonimmediate_operand" "=d,d,Q,S,Q")
5783 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,0,0")
5784 (match_operand:QI 2 "general_operand" "Os,d,n,n,Q")))
5785 (clobber (reg:CC CC_REGNUM))]
5786 "s390_logical_operator_ok_p (operands)"
5787 "@
5788 xilf\t%0,%b2
5789 xr\t%0,%2
5790 xi\t%S0,%b2
5791 xiy\t%S0,%b2
5792 #"
5793 [(set_attr "op_type" "RIL,RR,SI,SIY,SS")])
5794
5795 ;
5796 ; Block exclusive or (XC) patterns.
5797 ;
5798
5799 (define_insn "*xc"
5800 [(set (match_operand:BLK 0 "memory_operand" "=Q")
5801 (xor:BLK (match_dup 0)
5802 (match_operand:BLK 1 "memory_operand" "Q")))
5803 (use (match_operand 2 "const_int_operand" "n"))
5804 (clobber (reg:CC CC_REGNUM))]
5805 "INTVAL (operands[2]) >= 1 && INTVAL (operands[2]) <= 256"
5806 "xc\t%O0(%2,%R0),%S1"
5807 [(set_attr "op_type" "SS")])
5808
5809 (define_split
5810 [(set (match_operand 0 "memory_operand" "")
5811 (xor (match_dup 0)
5812 (match_operand 1 "memory_operand" "")))
5813 (clobber (reg:CC CC_REGNUM))]
5814 "reload_completed
5815 && GET_MODE (operands[0]) == GET_MODE (operands[1])
5816 && GET_MODE_SIZE (GET_MODE (operands[0])) > 0"
5817 [(parallel
5818 [(set (match_dup 0) (xor:BLK (match_dup 0) (match_dup 1)))
5819 (use (match_dup 2))
5820 (clobber (reg:CC CC_REGNUM))])]
5821 {
5822 operands[2] = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[0])));
5823 operands[0] = adjust_address (operands[0], BLKmode, 0);
5824 operands[1] = adjust_address (operands[1], BLKmode, 0);
5825 })
5826
5827 (define_peephole2
5828 [(parallel
5829 [(set (match_operand:BLK 0 "memory_operand" "")
5830 (xor:BLK (match_dup 0)
5831 (match_operand:BLK 1 "memory_operand" "")))
5832 (use (match_operand 2 "const_int_operand" ""))
5833 (clobber (reg:CC CC_REGNUM))])
5834 (parallel
5835 [(set (match_operand:BLK 3 "memory_operand" "")
5836 (xor:BLK (match_dup 3)
5837 (match_operand:BLK 4 "memory_operand" "")))
5838 (use (match_operand 5 "const_int_operand" ""))
5839 (clobber (reg:CC CC_REGNUM))])]
5840 "s390_offset_p (operands[0], operands[3], operands[2])
5841 && s390_offset_p (operands[1], operands[4], operands[2])
5842 && !s390_overlap_p (operands[0], operands[1],
5843 INTVAL (operands[2]) + INTVAL (operands[5]))
5844 && INTVAL (operands[2]) + INTVAL (operands[5]) <= 256"
5845 [(parallel
5846 [(set (match_dup 6) (xor:BLK (match_dup 6) (match_dup 7)))
5847 (use (match_dup 8))
5848 (clobber (reg:CC CC_REGNUM))])]
5849 "operands[6] = gen_rtx_MEM (BLKmode, XEXP (operands[0], 0));
5850 operands[7] = gen_rtx_MEM (BLKmode, XEXP (operands[1], 0));
5851 operands[8] = GEN_INT (INTVAL (operands[2]) + INTVAL (operands[5]));")
5852
5853 ;
5854 ; Block xor (XC) patterns with src == dest.
5855 ;
5856
5857 (define_insn "*xc_zero"
5858 [(set (match_operand:BLK 0 "memory_operand" "=Q")
5859 (const_int 0))
5860 (use (match_operand 1 "const_int_operand" "n"))
5861 (clobber (reg:CC CC_REGNUM))]
5862 "INTVAL (operands[1]) >= 1 && INTVAL (operands[1]) <= 256"
5863 "xc\t%O0(%1,%R0),%S0"
5864 [(set_attr "op_type" "SS")])
5865
5866 (define_peephole2
5867 [(parallel
5868 [(set (match_operand:BLK 0 "memory_operand" "")
5869 (const_int 0))
5870 (use (match_operand 1 "const_int_operand" ""))
5871 (clobber (reg:CC CC_REGNUM))])
5872 (parallel
5873 [(set (match_operand:BLK 2 "memory_operand" "")
5874 (const_int 0))
5875 (use (match_operand 3 "const_int_operand" ""))
5876 (clobber (reg:CC CC_REGNUM))])]
5877 "s390_offset_p (operands[0], operands[2], operands[1])
5878 && INTVAL (operands[1]) + INTVAL (operands[3]) <= 256"
5879 [(parallel
5880 [(set (match_dup 4) (const_int 0))
5881 (use (match_dup 5))
5882 (clobber (reg:CC CC_REGNUM))])]
5883 "operands[4] = gen_rtx_MEM (BLKmode, XEXP (operands[0], 0));
5884 operands[5] = GEN_INT (INTVAL (operands[1]) + INTVAL (operands[3]));")
5885
5886
5887 ;;
5888 ;;- Negate instructions.
5889 ;;
5890
5891 ;
5892 ; neg(di|si)2 instruction pattern(s).
5893 ;
5894
5895 (define_expand "neg<mode>2"
5896 [(parallel
5897 [(set (match_operand:DSI 0 "register_operand" "=d")
5898 (neg:DSI (match_operand:DSI 1 "register_operand" "d")))
5899 (clobber (reg:CC CC_REGNUM))])]
5900 ""
5901 "")
5902
5903 (define_insn "*negdi2_sign_cc"
5904 [(set (reg CC_REGNUM)
5905 (compare (neg:DI (ashiftrt:DI (ashift:DI (subreg:DI
5906 (match_operand:SI 1 "register_operand" "d") 0)
5907 (const_int 32)) (const_int 32)))
5908 (const_int 0)))
5909 (set (match_operand:DI 0 "register_operand" "=d")
5910 (neg:DI (sign_extend:DI (match_dup 1))))]
5911 "TARGET_64BIT && s390_match_ccmode (insn, CCAmode)"
5912 "lcgfr\t%0,%1"
5913 [(set_attr "op_type" "RRE")])
5914
5915 (define_insn "*negdi2_sign"
5916 [(set (match_operand:DI 0 "register_operand" "=d")
5917 (neg:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "d"))))
5918 (clobber (reg:CC CC_REGNUM))]
5919 "TARGET_64BIT"
5920 "lcgfr\t%0,%1"
5921 [(set_attr "op_type" "RRE")])
5922
5923 ; lcr, lcgr
5924 (define_insn "*neg<mode>2_cc"
5925 [(set (reg CC_REGNUM)
5926 (compare (neg:GPR (match_operand:GPR 1 "register_operand" "d"))
5927 (const_int 0)))
5928 (set (match_operand:GPR 0 "register_operand" "=d")
5929 (neg:GPR (match_dup 1)))]
5930 "s390_match_ccmode (insn, CCAmode)"
5931 "lc<g>r\t%0,%1"
5932 [(set_attr "op_type" "RR<E>")])
5933
5934 ; lcr, lcgr
5935 (define_insn "*neg<mode>2_cconly"
5936 [(set (reg CC_REGNUM)
5937 (compare (neg:GPR (match_operand:GPR 1 "register_operand" "d"))
5938 (const_int 0)))
5939 (clobber (match_scratch:GPR 0 "=d"))]
5940 "s390_match_ccmode (insn, CCAmode)"
5941 "lc<g>r\t%0,%1"
5942 [(set_attr "op_type" "RR<E>")])
5943
5944 ; lcr, lcgr
5945 (define_insn "*neg<mode>2"
5946 [(set (match_operand:GPR 0 "register_operand" "=d")
5947 (neg:GPR (match_operand:GPR 1 "register_operand" "d")))
5948 (clobber (reg:CC CC_REGNUM))]
5949 ""
5950 "lc<g>r\t%0,%1"
5951 [(set_attr "op_type" "RR<E>")])
5952
5953 (define_insn_and_split "*negdi2_31"
5954 [(set (match_operand:DI 0 "register_operand" "=d")
5955 (neg:DI (match_operand:DI 1 "register_operand" "d")))
5956 (clobber (reg:CC CC_REGNUM))]
5957 "!TARGET_64BIT"
5958 "#"
5959 "&& reload_completed"
5960 [(parallel
5961 [(set (match_dup 2) (neg:SI (match_dup 3)))
5962 (clobber (reg:CC CC_REGNUM))])
5963 (parallel
5964 [(set (reg:CCAP CC_REGNUM)
5965 (compare:CCAP (neg:SI (match_dup 5)) (const_int 0)))
5966 (set (match_dup 4) (neg:SI (match_dup 5)))])
5967 (set (pc)
5968 (if_then_else (ne (reg:CCAP CC_REGNUM) (const_int 0))
5969 (pc)
5970 (label_ref (match_dup 6))))
5971 (parallel
5972 [(set (match_dup 2) (plus:SI (match_dup 2) (const_int -1)))
5973 (clobber (reg:CC CC_REGNUM))])
5974 (match_dup 6)]
5975 "operands[2] = operand_subword (operands[0], 0, 0, DImode);
5976 operands[3] = operand_subword (operands[1], 0, 0, DImode);
5977 operands[4] = operand_subword (operands[0], 1, 0, DImode);
5978 operands[5] = operand_subword (operands[1], 1, 0, DImode);
5979 operands[6] = gen_label_rtx ();")
5980
5981 ;
5982 ; neg(df|sf)2 instruction pattern(s).
5983 ;
5984
5985 (define_expand "neg<mode>2"
5986 [(parallel
5987 [(set (match_operand:BFP 0 "register_operand" "=f")
5988 (neg:BFP (match_operand:BFP 1 "register_operand" "f")))
5989 (clobber (reg:CC CC_REGNUM))])]
5990 "TARGET_HARD_FLOAT"
5991 "")
5992
5993 ; lcxbr, lcdbr, lcebr
5994 (define_insn "*neg<mode>2_cc"
5995 [(set (reg CC_REGNUM)
5996 (compare (neg:BFP (match_operand:BFP 1 "register_operand" "f"))
5997 (match_operand:BFP 2 "const0_operand" "")))
5998 (set (match_operand:BFP 0 "register_operand" "=f")
5999 (neg:BFP (match_dup 1)))]
6000 "s390_match_ccmode (insn, CCSmode) && TARGET_HARD_FLOAT"
6001 "lc<xde>br\t%0,%1"
6002 [(set_attr "op_type" "RRE")
6003 (set_attr "type" "fsimp<mode>")])
6004
6005 ; lcxbr, lcdbr, lcebr
6006 (define_insn "*neg<mode>2_cconly"
6007 [(set (reg CC_REGNUM)
6008 (compare (neg:BFP (match_operand:BFP 1 "register_operand" "f"))
6009 (match_operand:BFP 2 "const0_operand" "")))
6010 (clobber (match_scratch:BFP 0 "=f"))]
6011 "s390_match_ccmode (insn, CCSmode) && TARGET_HARD_FLOAT"
6012 "lc<xde>br\t%0,%1"
6013 [(set_attr "op_type" "RRE")
6014 (set_attr "type" "fsimp<mode>")])
6015
6016 ; lcdfr
6017 (define_insn "*neg<mode>2_nocc"
6018 [(set (match_operand:FP 0 "register_operand" "=f")
6019 (neg:FP (match_operand:FP 1 "register_operand" "<fT0>")))]
6020 "TARGET_HARD_FLOAT && TARGET_DFP"
6021 "lcdfr\t%0,%1"
6022 [(set_attr "op_type" "RRE")
6023 (set_attr "type" "fsimp<bfp>")])
6024
6025 ; lcxbr, lcdbr, lcebr
6026 (define_insn "*neg<mode>2"
6027 [(set (match_operand:BFP 0 "register_operand" "=f")
6028 (neg:BFP (match_operand:BFP 1 "register_operand" "f")))
6029 (clobber (reg:CC CC_REGNUM))]
6030 "TARGET_HARD_FLOAT"
6031 "lc<xde>br\t%0,%1"
6032 [(set_attr "op_type" "RRE")
6033 (set_attr "type" "fsimp<mode>")])
6034
6035
6036 ;;
6037 ;;- Absolute value instructions.
6038 ;;
6039
6040 ;
6041 ; abs(di|si)2 instruction pattern(s).
6042 ;
6043
6044 (define_insn "*absdi2_sign_cc"
6045 [(set (reg CC_REGNUM)
6046 (compare (abs:DI (ashiftrt:DI (ashift:DI (subreg:DI
6047 (match_operand:SI 1 "register_operand" "d") 0)
6048 (const_int 32)) (const_int 32)))
6049 (const_int 0)))
6050 (set (match_operand:DI 0 "register_operand" "=d")
6051 (abs:DI (sign_extend:DI (match_dup 1))))]
6052 "TARGET_64BIT && s390_match_ccmode (insn, CCAmode)"
6053 "lpgfr\t%0,%1"
6054 [(set_attr "op_type" "RRE")])
6055
6056 (define_insn "*absdi2_sign"
6057 [(set (match_operand:DI 0 "register_operand" "=d")
6058 (abs:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "d"))))
6059 (clobber (reg:CC CC_REGNUM))]
6060 "TARGET_64BIT"
6061 "lpgfr\t%0,%1"
6062 [(set_attr "op_type" "RRE")])
6063
6064 ; lpr, lpgr
6065 (define_insn "*abs<mode>2_cc"
6066 [(set (reg CC_REGNUM)
6067 (compare (abs:GPR (match_operand:DI 1 "register_operand" "d"))
6068 (const_int 0)))
6069 (set (match_operand:GPR 0 "register_operand" "=d")
6070 (abs:GPR (match_dup 1)))]
6071 "s390_match_ccmode (insn, CCAmode)"
6072 "lp<g>r\t%0,%1"
6073 [(set_attr "op_type" "RR<E>")])
6074
6075 ; lpr, lpgr
6076 (define_insn "*abs<mode>2_cconly"
6077 [(set (reg CC_REGNUM)
6078 (compare (abs:GPR (match_operand:GPR 1 "register_operand" "d"))
6079 (const_int 0)))
6080 (clobber (match_scratch:GPR 0 "=d"))]
6081 "s390_match_ccmode (insn, CCAmode)"
6082 "lp<g>r\t%0,%1"
6083 [(set_attr "op_type" "RR<E>")])
6084
6085 ; lpr, lpgr
6086 (define_insn "abs<mode>2"
6087 [(set (match_operand:GPR 0 "register_operand" "=d")
6088 (abs:GPR (match_operand:GPR 1 "register_operand" "d")))
6089 (clobber (reg:CC CC_REGNUM))]
6090 ""
6091 "lp<g>r\t%0,%1"
6092 [(set_attr "op_type" "RR<E>")])
6093
6094 ;
6095 ; abs(df|sf)2 instruction pattern(s).
6096 ;
6097
6098 (define_expand "abs<mode>2"
6099 [(parallel
6100 [(set (match_operand:BFP 0 "register_operand" "=f")
6101 (abs:BFP (match_operand:BFP 1 "register_operand" "f")))
6102 (clobber (reg:CC CC_REGNUM))])]
6103 "TARGET_HARD_FLOAT"
6104 "")
6105
6106 ; lpxbr, lpdbr, lpebr
6107 (define_insn "*abs<mode>2_cc"
6108 [(set (reg CC_REGNUM)
6109 (compare (abs:BFP (match_operand:BFP 1 "register_operand" "f"))
6110 (match_operand:BFP 2 "const0_operand" "")))
6111 (set (match_operand:BFP 0 "register_operand" "=f")
6112 (abs:BFP (match_dup 1)))]
6113 "s390_match_ccmode (insn, CCSmode) && TARGET_HARD_FLOAT"
6114 "lp<xde>br\t%0,%1"
6115 [(set_attr "op_type" "RRE")
6116 (set_attr "type" "fsimp<mode>")])
6117
6118 ; lpxbr, lpdbr, lpebr
6119 (define_insn "*abs<mode>2_cconly"
6120 [(set (reg CC_REGNUM)
6121 (compare (abs:BFP (match_operand:BFP 1 "register_operand" "f"))
6122 (match_operand:BFP 2 "const0_operand" "")))
6123 (clobber (match_scratch:BFP 0 "=f"))]
6124 "s390_match_ccmode (insn, CCSmode) && TARGET_HARD_FLOAT"
6125 "lp<xde>br\t%0,%1"
6126 [(set_attr "op_type" "RRE")
6127 (set_attr "type" "fsimp<mode>")])
6128
6129 ; lpdfr
6130 (define_insn "*abs<mode>2_nocc"
6131 [(set (match_operand:FP 0 "register_operand" "=f")
6132 (abs:FP (match_operand:FP 1 "register_operand" "<fT0>")))]
6133 "TARGET_HARD_FLOAT && TARGET_DFP"
6134 "lpdfr\t%0,%1"
6135 [(set_attr "op_type" "RRE")
6136 (set_attr "type" "fsimp<bfp>")])
6137
6138 ; lpxbr, lpdbr, lpebr
6139 (define_insn "*abs<mode>2"
6140 [(set (match_operand:BFP 0 "register_operand" "=f")
6141 (abs:BFP (match_operand:BFP 1 "register_operand" "f")))
6142 (clobber (reg:CC CC_REGNUM))]
6143 "TARGET_HARD_FLOAT"
6144 "lp<xde>br\t%0,%1"
6145 [(set_attr "op_type" "RRE")
6146 (set_attr "type" "fsimp<mode>")])
6147
6148
6149 ;;
6150 ;;- Negated absolute value instructions
6151 ;;
6152
6153 ;
6154 ; Integer
6155 ;
6156
6157 (define_insn "*negabsdi2_sign_cc"
6158 [(set (reg CC_REGNUM)
6159 (compare (neg:DI (abs:DI (ashiftrt:DI (ashift:DI (subreg:DI
6160 (match_operand:SI 1 "register_operand" "d") 0)
6161 (const_int 32)) (const_int 32))))
6162 (const_int 0)))
6163 (set (match_operand:DI 0 "register_operand" "=d")
6164 (neg:DI (abs:DI (sign_extend:DI (match_dup 1)))))]
6165 "TARGET_64BIT && s390_match_ccmode (insn, CCAmode)"
6166 "lngfr\t%0,%1"
6167 [(set_attr "op_type" "RRE")])
6168
6169 (define_insn "*negabsdi2_sign"
6170 [(set (match_operand:DI 0 "register_operand" "=d")
6171 (neg:DI (abs:DI (sign_extend:DI
6172 (match_operand:SI 1 "register_operand" "d")))))
6173 (clobber (reg:CC CC_REGNUM))]
6174 "TARGET_64BIT"
6175 "lngfr\t%0,%1"
6176 [(set_attr "op_type" "RRE")])
6177
6178 ; lnr, lngr
6179 (define_insn "*negabs<mode>2_cc"
6180 [(set (reg CC_REGNUM)
6181 (compare (neg:GPR (abs:GPR (match_operand:GPR 1 "register_operand" "d")))
6182 (const_int 0)))
6183 (set (match_operand:GPR 0 "register_operand" "=d")
6184 (neg:GPR (abs:GPR (match_dup 1))))]
6185 "s390_match_ccmode (insn, CCAmode)"
6186 "ln<g>r\t%0,%1"
6187 [(set_attr "op_type" "RR<E>")])
6188
6189 ; lnr, lngr
6190 (define_insn "*negabs<mode>2_cconly"
6191 [(set (reg CC_REGNUM)
6192 (compare (neg:GPR (abs:GPR (match_operand:GPR 1 "register_operand" "d")))
6193 (const_int 0)))
6194 (clobber (match_scratch:GPR 0 "=d"))]
6195 "s390_match_ccmode (insn, CCAmode)"
6196 "ln<g>r\t%0,%1"
6197 [(set_attr "op_type" "RR<E>")])
6198
6199 ; lnr, lngr
6200 (define_insn "*negabs<mode>2"
6201 [(set (match_operand:GPR 0 "register_operand" "=d")
6202 (neg:GPR (abs:GPR (match_operand:GPR 1 "register_operand" "d"))))
6203 (clobber (reg:CC CC_REGNUM))]
6204 ""
6205 "ln<g>r\t%0,%1"
6206 [(set_attr "op_type" "RR<E>")])
6207
6208 ;
6209 ; Floating point
6210 ;
6211
6212 ; lnxbr, lndbr, lnebr
6213 (define_insn "*negabs<mode>2_cc"
6214 [(set (reg CC_REGNUM)
6215 (compare (neg:BFP (abs:BFP (match_operand:BFP 1 "register_operand" "f")))
6216 (match_operand:BFP 2 "const0_operand" "")))
6217 (set (match_operand:BFP 0 "register_operand" "=f")
6218 (neg:BFP (abs:BFP (match_dup 1))))]
6219 "s390_match_ccmode (insn, CCSmode) && TARGET_HARD_FLOAT"
6220 "ln<xde>br\t%0,%1"
6221 [(set_attr "op_type" "RRE")
6222 (set_attr "type" "fsimp<mode>")])
6223
6224 ; lnxbr, lndbr, lnebr
6225 (define_insn "*negabs<mode>2_cconly"
6226 [(set (reg CC_REGNUM)
6227 (compare (neg:BFP (abs:BFP (match_operand:BFP 1 "register_operand" "f")))
6228 (match_operand:BFP 2 "const0_operand" "")))
6229 (clobber (match_scratch:BFP 0 "=f"))]
6230 "s390_match_ccmode (insn, CCSmode) && TARGET_HARD_FLOAT"
6231 "ln<xde>br\t%0,%1"
6232 [(set_attr "op_type" "RRE")
6233 (set_attr "type" "fsimp<mode>")])
6234
6235 ; lndfr
6236 (define_insn "*negabs<mode>2_nocc"
6237 [(set (match_operand:FP 0 "register_operand" "=f")
6238 (neg:FP (abs:FP (match_operand:BFP 1 "register_operand" "<fT0>"))))]
6239 "TARGET_HARD_FLOAT && TARGET_DFP"
6240 "lndfr\t%0,%1"
6241 [(set_attr "op_type" "RRE")
6242 (set_attr "type" "fsimp<bfp>")])
6243
6244 ; lnxbr, lndbr, lnebr
6245 (define_insn "*negabs<mode>2"
6246 [(set (match_operand:BFP 0 "register_operand" "=f")
6247 (neg:BFP (abs:BFP (match_operand:BFP 1 "register_operand" "f"))))
6248 (clobber (reg:CC CC_REGNUM))]
6249 "TARGET_HARD_FLOAT"
6250 "ln<xde>br\t%0,%1"
6251 [(set_attr "op_type" "RRE")
6252 (set_attr "type" "fsimp<mode>")])
6253
6254 ;;
6255 ;;- Copy sign instructions
6256 ;;
6257
6258 ; cpsdr
6259 (define_insn "copysign<mode>3"
6260 [(set (match_operand:FP 0 "register_operand" "=f")
6261 (unspec:FP [(match_operand:FP 1 "register_operand" "<fT0>")
6262 (match_operand:FP 2 "register_operand" "f")]
6263 UNSPEC_COPYSIGN))]
6264 "TARGET_HARD_FLOAT && TARGET_DFP"
6265 "cpsdr\t%0,%2,%1"
6266 [(set_attr "op_type" "RRF")
6267 (set_attr "type" "fsimp<bfp>")])
6268
6269 ;;
6270 ;;- Square root instructions.
6271 ;;
6272
6273 ;
6274 ; sqrt(df|sf)2 instruction pattern(s).
6275 ;
6276
6277 ; sqxbr, sqdbr, sqebr, sqxb, sqdb, sqeb
6278 (define_insn "sqrt<mode>2"
6279 [(set (match_operand:BFP 0 "register_operand" "=f,f")
6280 (sqrt:BFP (match_operand:BFP 1 "general_operand" "f,<Rf>")))]
6281 "TARGET_HARD_FLOAT"
6282 "@
6283 sq<xde>br\t%0,%1
6284 sq<xde>b\t%0,%1"
6285 [(set_attr "op_type" "RRE,RXE")
6286 (set_attr "type" "fsqrt<mode>")])
6287
6288
6289 ;;
6290 ;;- One complement instructions.
6291 ;;
6292
6293 ;
6294 ; one_cmpl(di|si|hi|qi)2 instruction pattern(s).
6295 ;
6296
6297 (define_expand "one_cmpl<mode>2"
6298 [(parallel
6299 [(set (match_operand:INT 0 "register_operand" "")
6300 (xor:INT (match_operand:INT 1 "register_operand" "")
6301 (const_int -1)))
6302 (clobber (reg:CC CC_REGNUM))])]
6303 ""
6304 "")
6305
6306
6307 ;;
6308 ;; Find leftmost bit instructions.
6309 ;;
6310
6311 (define_expand "clzdi2"
6312 [(set (match_operand:DI 0 "register_operand" "=d")
6313 (clz:DI (match_operand:DI 1 "register_operand" "d")))]
6314 "TARGET_EXTIMM && TARGET_64BIT"
6315 {
6316 rtx insn, clz_equal;
6317 rtx wide_reg = gen_reg_rtx (TImode);
6318 rtx msb = gen_rtx_CONST_INT (DImode, (unsigned HOST_WIDE_INT) 1 << 63);
6319
6320 clz_equal = gen_rtx_CLZ (DImode, operands[1]);
6321
6322 emit_insn (gen_clztidi2 (wide_reg, operands[1], msb));
6323
6324 insn = emit_move_insn (operands[0], gen_highpart (DImode, wide_reg));
6325 set_unique_reg_note (insn, REG_EQUAL, clz_equal);
6326
6327 DONE;
6328 })
6329
6330 (define_insn "clztidi2"
6331 [(set (match_operand:TI 0 "register_operand" "=d")
6332 (ior:TI
6333 (ashift:TI
6334 (zero_extend:TI
6335 (xor:DI (match_operand:DI 1 "register_operand" "d")
6336 (lshiftrt (match_operand:DI 2 "const_int_operand" "")
6337 (subreg:SI (clz:DI (match_dup 1)) 4))))
6338
6339 (const_int 64))
6340 (zero_extend:TI (clz:DI (match_dup 1)))))
6341 (clobber (reg:CC CC_REGNUM))]
6342 "(unsigned HOST_WIDE_INT) INTVAL (operands[2])
6343 == (unsigned HOST_WIDE_INT) 1 << 63
6344 && TARGET_EXTIMM && TARGET_64BIT"
6345 "flogr\t%0,%1"
6346 [(set_attr "op_type" "RRE")])
6347
6348
6349 ;;
6350 ;;- Rotate instructions.
6351 ;;
6352
6353 ;
6354 ; rotl(di|si)3 instruction pattern(s).
6355 ;
6356
6357 ; rll, rllg
6358 (define_insn "rotl<mode>3"
6359 [(set (match_operand:GPR 0 "register_operand" "=d")
6360 (rotate:GPR (match_operand:GPR 1 "register_operand" "d")
6361 (match_operand:SI 2 "shift_count_or_setmem_operand" "Y")))]
6362 "TARGET_CPU_ZARCH"
6363 "rll<g>\t%0,%1,%Y2"
6364 [(set_attr "op_type" "RSE")
6365 (set_attr "atype" "reg")])
6366
6367 ; rll, rllg
6368 (define_insn "*rotl<mode>3_and"
6369 [(set (match_operand:GPR 0 "register_operand" "=d")
6370 (rotate:GPR (match_operand:GPR 1 "register_operand" "d")
6371 (and:SI (match_operand:SI 2 "shift_count_or_setmem_operand" "Y")
6372 (match_operand:SI 3 "const_int_operand" "n"))))]
6373 "TARGET_CPU_ZARCH && (INTVAL (operands[3]) & 63) == 63"
6374 "rll<g>\t%0,%1,%Y2"
6375 [(set_attr "op_type" "RSE")
6376 (set_attr "atype" "reg")])
6377
6378
6379 ;;
6380 ;;- Shift instructions.
6381 ;;
6382
6383 ;
6384 ; (ashl|lshr)(di|si)3 instruction pattern(s).
6385 ;
6386
6387 (define_expand "<shift><mode>3"
6388 [(set (match_operand:DSI 0 "register_operand" "")
6389 (SHIFT:DSI (match_operand:DSI 1 "register_operand" "")
6390 (match_operand:SI 2 "shift_count_or_setmem_operand" "")))]
6391 ""
6392 "")
6393
6394 ; sldl, srdl
6395 (define_insn "*<shift>di3_31"
6396 [(set (match_operand:DI 0 "register_operand" "=d")
6397 (SHIFT:DI (match_operand:DI 1 "register_operand" "0")
6398 (match_operand:SI 2 "shift_count_or_setmem_operand" "Y")))]
6399 "!TARGET_64BIT"
6400 "s<lr>dl\t%0,%Y2"
6401 [(set_attr "op_type" "RS")
6402 (set_attr "atype" "reg")])
6403
6404 ; sll, srl, sllg, srlg
6405 (define_insn "*<shift><mode>3"
6406 [(set (match_operand:GPR 0 "register_operand" "=d")
6407 (SHIFT:GPR (match_operand:GPR 1 "register_operand" "<d0>")
6408 (match_operand:SI 2 "shift_count_or_setmem_operand" "Y")))]
6409 ""
6410 "s<lr>l<g>\t%0,<1>%Y2"
6411 [(set_attr "op_type" "RS<E>")
6412 (set_attr "atype" "reg")])
6413
6414 ; sldl, srdl
6415 (define_insn "*<shift>di3_31_and"
6416 [(set (match_operand:DI 0 "register_operand" "=d")
6417 (SHIFT:DI (match_operand:DI 1 "register_operand" "0")
6418 (and:SI (match_operand:SI 2 "shift_count_or_setmem_operand" "Y")
6419 (match_operand:SI 3 "const_int_operand" "n"))))]
6420 "!TARGET_64BIT && (INTVAL (operands[3]) & 63) == 63"
6421 "s<lr>dl\t%0,%Y2"
6422 [(set_attr "op_type" "RS")
6423 (set_attr "atype" "reg")])
6424
6425 ; sll, srl, sllg, srlg
6426 (define_insn "*<shift><mode>3_and"
6427 [(set (match_operand:GPR 0 "register_operand" "=d")
6428 (SHIFT:GPR (match_operand:GPR 1 "register_operand" "<d0>")
6429 (and:SI (match_operand:SI 2 "shift_count_or_setmem_operand" "Y")
6430 (match_operand:SI 3 "const_int_operand" "n"))))]
6431 "(INTVAL (operands[3]) & 63) == 63"
6432 "s<lr>l<g>\t%0,<1>%Y2"
6433 [(set_attr "op_type" "RS<E>")
6434 (set_attr "atype" "reg")])
6435
6436 ;
6437 ; ashr(di|si)3 instruction pattern(s).
6438 ;
6439
6440 (define_expand "ashr<mode>3"
6441 [(parallel
6442 [(set (match_operand:DSI 0 "register_operand" "")
6443 (ashiftrt:DSI (match_operand:DSI 1 "register_operand" "")
6444 (match_operand:SI 2 "shift_count_or_setmem_operand" "")))
6445 (clobber (reg:CC CC_REGNUM))])]
6446 ""
6447 "")
6448
6449 (define_insn "*ashrdi3_cc_31"
6450 [(set (reg CC_REGNUM)
6451 (compare (ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
6452 (match_operand:SI 2 "shift_count_or_setmem_operand" "Y"))
6453 (const_int 0)))
6454 (set (match_operand:DI 0 "register_operand" "=d")
6455 (ashiftrt:DI (match_dup 1) (match_dup 2)))]
6456 "!TARGET_64BIT && s390_match_ccmode(insn, CCSmode)"
6457 "srda\t%0,%Y2"
6458 [(set_attr "op_type" "RS")
6459 (set_attr "atype" "reg")])
6460
6461 (define_insn "*ashrdi3_cconly_31"
6462 [(set (reg CC_REGNUM)
6463 (compare (ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
6464 (match_operand:SI 2 "shift_count_or_setmem_operand" "Y"))
6465 (const_int 0)))
6466 (clobber (match_scratch:DI 0 "=d"))]
6467 "!TARGET_64BIT && s390_match_ccmode(insn, CCSmode)"
6468 "srda\t%0,%Y2"
6469 [(set_attr "op_type" "RS")
6470 (set_attr "atype" "reg")])
6471
6472 (define_insn "*ashrdi3_31"
6473 [(set (match_operand:DI 0 "register_operand" "=d")
6474 (ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
6475 (match_operand:SI 2 "shift_count_or_setmem_operand" "Y")))
6476 (clobber (reg:CC CC_REGNUM))]
6477 "!TARGET_64BIT"
6478 "srda\t%0,%Y2"
6479 [(set_attr "op_type" "RS")
6480 (set_attr "atype" "reg")])
6481
6482 ; sra, srag
6483 (define_insn "*ashr<mode>3_cc"
6484 [(set (reg CC_REGNUM)
6485 (compare (ashiftrt:GPR (match_operand:GPR 1 "register_operand" "<d0>")
6486 (match_operand:SI 2 "shift_count_or_setmem_operand" "Y"))
6487 (const_int 0)))
6488 (set (match_operand:GPR 0 "register_operand" "=d")
6489 (ashiftrt:GPR (match_dup 1) (match_dup 2)))]
6490 "s390_match_ccmode(insn, CCSmode)"
6491 "sra<g>\t%0,<1>%Y2"
6492 [(set_attr "op_type" "RS<E>")
6493 (set_attr "atype" "reg")])
6494
6495 ; sra, srag
6496 (define_insn "*ashr<mode>3_cconly"
6497 [(set (reg CC_REGNUM)
6498 (compare (ashiftrt:GPR (match_operand:GPR 1 "register_operand" "<d0>")
6499 (match_operand:SI 2 "shift_count_or_setmem_operand" "Y"))
6500 (const_int 0)))
6501 (clobber (match_scratch:GPR 0 "=d"))]
6502 "s390_match_ccmode(insn, CCSmode)"
6503 "sra<g>\t%0,<1>%Y2"
6504 [(set_attr "op_type" "RS<E>")
6505 (set_attr "atype" "reg")])
6506
6507 ; sra, srag
6508 (define_insn "*ashr<mode>3"
6509 [(set (match_operand:GPR 0 "register_operand" "=d")
6510 (ashiftrt:GPR (match_operand:GPR 1 "register_operand" "<d0>")
6511 (match_operand:SI 2 "shift_count_or_setmem_operand" "Y")))
6512 (clobber (reg:CC CC_REGNUM))]
6513 ""
6514 "sra<g>\t%0,<1>%Y2"
6515 [(set_attr "op_type" "RS<E>")
6516 (set_attr "atype" "reg")])
6517
6518
6519 ; shift pattern with implicit ANDs
6520
6521 (define_insn "*ashrdi3_cc_31_and"
6522 [(set (reg CC_REGNUM)
6523 (compare (ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
6524 (and:SI (match_operand:SI 2 "shift_count_or_setmem_operand" "Y")
6525 (match_operand:SI 3 "const_int_operand" "n")))
6526 (const_int 0)))
6527 (set (match_operand:DI 0 "register_operand" "=d")
6528 (ashiftrt:DI (match_dup 1) (and:SI (match_dup 2) (match_dup 3))))]
6529 "!TARGET_64BIT && s390_match_ccmode(insn, CCSmode)
6530 && (INTVAL (operands[3]) & 63) == 63"
6531 "srda\t%0,%Y2"
6532 [(set_attr "op_type" "RS")
6533 (set_attr "atype" "reg")])
6534
6535 (define_insn "*ashrdi3_cconly_31_and"
6536 [(set (reg CC_REGNUM)
6537 (compare (ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
6538 (and:SI (match_operand:SI 2 "shift_count_or_setmem_operand" "Y")
6539 (match_operand:SI 3 "const_int_operand" "n")))
6540 (const_int 0)))
6541 (clobber (match_scratch:DI 0 "=d"))]
6542 "!TARGET_64BIT && s390_match_ccmode(insn, CCSmode)
6543 && (INTVAL (operands[3]) & 63) == 63"
6544 "srda\t%0,%Y2"
6545 [(set_attr "op_type" "RS")
6546 (set_attr "atype" "reg")])
6547
6548 (define_insn "*ashrdi3_31_and"
6549 [(set (match_operand:DI 0 "register_operand" "=d")
6550 (ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
6551 (and:SI (match_operand:SI 2 "shift_count_or_setmem_operand" "Y")
6552 (match_operand:SI 3 "const_int_operand" "n"))))
6553 (clobber (reg:CC CC_REGNUM))]
6554 "!TARGET_64BIT && (INTVAL (operands[3]) & 63) == 63"
6555 "srda\t%0,%Y2"
6556 [(set_attr "op_type" "RS")
6557 (set_attr "atype" "reg")])
6558
6559 ; sra, srag
6560 (define_insn "*ashr<mode>3_cc_and"
6561 [(set (reg CC_REGNUM)
6562 (compare (ashiftrt:GPR (match_operand:GPR 1 "register_operand" "<d0>")
6563 (and:SI (match_operand:SI 2 "shift_count_or_setmem_operand" "Y")
6564 (match_operand:SI 3 "const_int_operand" "n")))
6565 (const_int 0)))
6566 (set (match_operand:GPR 0 "register_operand" "=d")
6567 (ashiftrt:GPR (match_dup 1) (and:SI (match_dup 2) (match_dup 3))))]
6568 "s390_match_ccmode(insn, CCSmode) && (INTVAL (operands[3]) & 63) == 63"
6569 "sra<g>\t%0,<1>%Y2"
6570 [(set_attr "op_type" "RS<E>")
6571 (set_attr "atype" "reg")])
6572
6573 ; sra, srag
6574 (define_insn "*ashr<mode>3_cconly_and"
6575 [(set (reg CC_REGNUM)
6576 (compare (ashiftrt:GPR (match_operand:GPR 1 "register_operand" "<d0>")
6577 (and:SI (match_operand:SI 2 "shift_count_or_setmem_operand" "Y")
6578 (match_operand:SI 3 "const_int_operand" "n")))
6579 (const_int 0)))
6580 (clobber (match_scratch:GPR 0 "=d"))]
6581 "s390_match_ccmode(insn, CCSmode) && (INTVAL (operands[3]) & 63) == 63"
6582 "sra<g>\t%0,<1>%Y2"
6583 [(set_attr "op_type" "RS<E>")
6584 (set_attr "atype" "reg")])
6585
6586 ; sra, srag
6587 (define_insn "*ashr<mode>3_and"
6588 [(set (match_operand:GPR 0 "register_operand" "=d")
6589 (ashiftrt:GPR (match_operand:GPR 1 "register_operand" "<d0>")
6590 (and:SI (match_operand:SI 2 "shift_count_or_setmem_operand" "Y")
6591 (match_operand:SI 3 "const_int_operand" "n"))))
6592 (clobber (reg:CC CC_REGNUM))]
6593 "(INTVAL (operands[3]) & 63) == 63"
6594 "sra<g>\t%0,<1>%Y2"
6595 [(set_attr "op_type" "RS<E>")
6596 (set_attr "atype" "reg")])
6597
6598
6599 ;;
6600 ;; Branch instruction patterns.
6601 ;;
6602
6603 (define_expand "b<code>"
6604 [(set (pc)
6605 (if_then_else (COMPARE (match_operand 0 "" "")
6606 (const_int 0))
6607 (match_dup 0)
6608 (pc)))]
6609 ""
6610 "s390_emit_jump (operands[0],
6611 s390_emit_compare (<CODE>, s390_compare_op0, s390_compare_op1)); DONE;")
6612
6613
6614 ;;
6615 ;;- Conditional jump instructions.
6616 ;;
6617
6618 (define_insn "*cjump_64"
6619 [(set (pc)
6620 (if_then_else
6621 (match_operator 1 "s390_comparison" [(reg CC_REGNUM) (const_int 0)])
6622 (label_ref (match_operand 0 "" ""))
6623 (pc)))]
6624 "TARGET_CPU_ZARCH"
6625 {
6626 if (get_attr_length (insn) == 4)
6627 return "j%C1\t%l0";
6628 else
6629 return "jg%C1\t%l0";
6630 }
6631 [(set_attr "op_type" "RI")
6632 (set_attr "type" "branch")
6633 (set (attr "length")
6634 (if_then_else (lt (abs (minus (pc) (match_dup 0))) (const_int 60000))
6635 (const_int 4) (const_int 6)))])
6636
6637 (define_insn "*cjump_31"
6638 [(set (pc)
6639 (if_then_else
6640 (match_operator 1 "s390_comparison" [(reg CC_REGNUM) (const_int 0)])
6641 (label_ref (match_operand 0 "" ""))
6642 (pc)))]
6643 "!TARGET_CPU_ZARCH"
6644 {
6645 gcc_assert (get_attr_length (insn) == 4);
6646 return "j%C1\t%l0";
6647 }
6648 [(set_attr "op_type" "RI")
6649 (set_attr "type" "branch")
6650 (set (attr "length")
6651 (if_then_else (eq (symbol_ref "flag_pic") (const_int 0))
6652 (if_then_else (lt (abs (minus (pc) (match_dup 0))) (const_int 60000))
6653 (const_int 4) (const_int 6))
6654 (if_then_else (lt (abs (minus (pc) (match_dup 0))) (const_int 60000))
6655 (const_int 4) (const_int 8))))])
6656
6657 (define_insn "*cjump_long"
6658 [(set (pc)
6659 (if_then_else
6660 (match_operator 1 "s390_comparison" [(reg CC_REGNUM) (const_int 0)])
6661 (match_operand 0 "address_operand" "U")
6662 (pc)))]
6663 ""
6664 {
6665 if (get_attr_op_type (insn) == OP_TYPE_RR)
6666 return "b%C1r\t%0";
6667 else
6668 return "b%C1\t%a0";
6669 }
6670 [(set (attr "op_type")
6671 (if_then_else (match_operand 0 "register_operand" "")
6672 (const_string "RR") (const_string "RX")))
6673 (set_attr "type" "branch")
6674 (set_attr "atype" "agen")])
6675
6676
6677 ;;
6678 ;;- Negated conditional jump instructions.
6679 ;;
6680
6681 (define_insn "*icjump_64"
6682 [(set (pc)
6683 (if_then_else
6684 (match_operator 1 "s390_comparison" [(reg CC_REGNUM) (const_int 0)])
6685 (pc)
6686 (label_ref (match_operand 0 "" ""))))]
6687 "TARGET_CPU_ZARCH"
6688 {
6689 if (get_attr_length (insn) == 4)
6690 return "j%D1\t%l0";
6691 else
6692 return "jg%D1\t%l0";
6693 }
6694 [(set_attr "op_type" "RI")
6695 (set_attr "type" "branch")
6696 (set (attr "length")
6697 (if_then_else (lt (abs (minus (pc) (match_dup 0))) (const_int 60000))
6698 (const_int 4) (const_int 6)))])
6699
6700 (define_insn "*icjump_31"
6701 [(set (pc)
6702 (if_then_else
6703 (match_operator 1 "s390_comparison" [(reg CC_REGNUM) (const_int 0)])
6704 (pc)
6705 (label_ref (match_operand 0 "" ""))))]
6706 "!TARGET_CPU_ZARCH"
6707 {
6708 gcc_assert (get_attr_length (insn) == 4);
6709 return "j%D1\t%l0";
6710 }
6711 [(set_attr "op_type" "RI")
6712 (set_attr "type" "branch")
6713 (set (attr "length")
6714 (if_then_else (eq (symbol_ref "flag_pic") (const_int 0))
6715 (if_then_else (lt (abs (minus (pc) (match_dup 0))) (const_int 60000))
6716 (const_int 4) (const_int 6))
6717 (if_then_else (lt (abs (minus (pc) (match_dup 0))) (const_int 60000))
6718 (const_int 4) (const_int 8))))])
6719
6720 (define_insn "*icjump_long"
6721 [(set (pc)
6722 (if_then_else
6723 (match_operator 1 "s390_comparison" [(reg CC_REGNUM) (const_int 0)])
6724 (pc)
6725 (match_operand 0 "address_operand" "U")))]
6726 ""
6727 {
6728 if (get_attr_op_type (insn) == OP_TYPE_RR)
6729 return "b%D1r\t%0";
6730 else
6731 return "b%D1\t%a0";
6732 }
6733 [(set (attr "op_type")
6734 (if_then_else (match_operand 0 "register_operand" "")
6735 (const_string "RR") (const_string "RX")))
6736 (set_attr "type" "branch")
6737 (set_attr "atype" "agen")])
6738
6739 ;;
6740 ;;- Trap instructions.
6741 ;;
6742
6743 (define_insn "trap"
6744 [(trap_if (const_int 1) (const_int 0))]
6745 ""
6746 "j\t.+2"
6747 [(set_attr "op_type" "RI")
6748 (set_attr "type" "branch")])
6749
6750 (define_expand "conditional_trap"
6751 [(trap_if (match_operand 0 "comparison_operator" "")
6752 (match_operand 1 "general_operand" ""))]
6753 ""
6754 {
6755 if (operands[1] != const0_rtx) FAIL;
6756 operands[0] = s390_emit_compare (GET_CODE (operands[0]),
6757 s390_compare_op0, s390_compare_op1);
6758 })
6759
6760 (define_insn "*trap"
6761 [(trap_if (match_operator 0 "s390_comparison" [(reg CC_REGNUM) (const_int 0)])
6762 (const_int 0))]
6763 ""
6764 "j%C0\t.+2";
6765 [(set_attr "op_type" "RI")
6766 (set_attr "type" "branch")])
6767
6768 ;;
6769 ;;- Loop instructions.
6770 ;;
6771 ;; This is all complicated by the fact that since this is a jump insn
6772 ;; we must handle our own output reloads.
6773
6774 (define_expand "doloop_end"
6775 [(use (match_operand 0 "" "")) ; loop pseudo
6776 (use (match_operand 1 "" "")) ; iterations; zero if unknown
6777 (use (match_operand 2 "" "")) ; max iterations
6778 (use (match_operand 3 "" "")) ; loop level
6779 (use (match_operand 4 "" ""))] ; label
6780 ""
6781 {
6782 if (GET_MODE (operands[0]) == SImode && !TARGET_CPU_ZARCH)
6783 emit_jump_insn (gen_doloop_si31 (operands[4], operands[0], operands[0]));
6784 else if (GET_MODE (operands[0]) == SImode && TARGET_CPU_ZARCH)
6785 emit_jump_insn (gen_doloop_si64 (operands[4], operands[0], operands[0]));
6786 else if (GET_MODE (operands[0]) == DImode && TARGET_64BIT)
6787 emit_jump_insn (gen_doloop_di (operands[4], operands[0], operands[0]));
6788 else
6789 FAIL;
6790
6791 DONE;
6792 })
6793
6794 (define_insn_and_split "doloop_si64"
6795 [(set (pc)
6796 (if_then_else
6797 (ne (match_operand:SI 1 "register_operand" "d,d,d")
6798 (const_int 1))
6799 (label_ref (match_operand 0 "" ""))
6800 (pc)))
6801 (set (match_operand:SI 2 "nonimmediate_operand" "=1,?X,?X")
6802 (plus:SI (match_dup 1) (const_int -1)))
6803 (clobber (match_scratch:SI 3 "=X,&1,&?d"))
6804 (clobber (reg:CC CC_REGNUM))]
6805 "TARGET_CPU_ZARCH"
6806 {
6807 if (which_alternative != 0)
6808 return "#";
6809 else if (get_attr_length (insn) == 4)
6810 return "brct\t%1,%l0";
6811 else
6812 return "ahi\t%1,-1\;jgne\t%l0";
6813 }
6814 "&& reload_completed
6815 && (! REG_P (operands[2])
6816 || ! rtx_equal_p (operands[1], operands[2]))"
6817 [(set (match_dup 3) (match_dup 1))
6818 (parallel [(set (reg:CCAN CC_REGNUM)
6819 (compare:CCAN (plus:SI (match_dup 3) (const_int -1))
6820 (const_int 0)))
6821 (set (match_dup 3) (plus:SI (match_dup 3) (const_int -1)))])
6822 (set (match_dup 2) (match_dup 3))
6823 (set (pc) (if_then_else (ne (reg:CCAN CC_REGNUM) (const_int 0))
6824 (label_ref (match_dup 0))
6825 (pc)))]
6826 ""
6827 [(set_attr "op_type" "RI")
6828 (set_attr "type" "branch")
6829 (set (attr "length")
6830 (if_then_else (lt (abs (minus (pc) (match_dup 0))) (const_int 60000))
6831 (const_int 4) (const_int 10)))])
6832
6833 (define_insn_and_split "doloop_si31"
6834 [(set (pc)
6835 (if_then_else
6836 (ne (match_operand:SI 1 "register_operand" "d,d,d")
6837 (const_int 1))
6838 (label_ref (match_operand 0 "" ""))
6839 (pc)))
6840 (set (match_operand:SI 2 "nonimmediate_operand" "=1,?X,?X")
6841 (plus:SI (match_dup 1) (const_int -1)))
6842 (clobber (match_scratch:SI 3 "=X,&1,&?d"))
6843 (clobber (reg:CC CC_REGNUM))]
6844 "!TARGET_CPU_ZARCH"
6845 {
6846 if (which_alternative != 0)
6847 return "#";
6848 else if (get_attr_length (insn) == 4)
6849 return "brct\t%1,%l0";
6850 else
6851 gcc_unreachable ();
6852 }
6853 "&& reload_completed
6854 && (! REG_P (operands[2])
6855 || ! rtx_equal_p (operands[1], operands[2]))"
6856 [(set (match_dup 3) (match_dup 1))
6857 (parallel [(set (reg:CCAN CC_REGNUM)
6858 (compare:CCAN (plus:SI (match_dup 3) (const_int -1))
6859 (const_int 0)))
6860 (set (match_dup 3) (plus:SI (match_dup 3) (const_int -1)))])
6861 (set (match_dup 2) (match_dup 3))
6862 (set (pc) (if_then_else (ne (reg:CCAN CC_REGNUM) (const_int 0))
6863 (label_ref (match_dup 0))
6864 (pc)))]
6865 ""
6866 [(set_attr "op_type" "RI")
6867 (set_attr "type" "branch")
6868 (set (attr "length")
6869 (if_then_else (eq (symbol_ref "flag_pic") (const_int 0))
6870 (if_then_else (lt (abs (minus (pc) (match_dup 0))) (const_int 60000))
6871 (const_int 4) (const_int 6))
6872 (if_then_else (lt (abs (minus (pc) (match_dup 0))) (const_int 60000))
6873 (const_int 4) (const_int 8))))])
6874
6875 (define_insn "*doloop_si_long"
6876 [(set (pc)
6877 (if_then_else
6878 (ne (match_operand:SI 1 "register_operand" "d")
6879 (const_int 1))
6880 (match_operand 0 "address_operand" "U")
6881 (pc)))
6882 (set (match_operand:SI 2 "register_operand" "=1")
6883 (plus:SI (match_dup 1) (const_int -1)))
6884 (clobber (match_scratch:SI 3 "=X"))
6885 (clobber (reg:CC CC_REGNUM))]
6886 "!TARGET_CPU_ZARCH"
6887 {
6888 if (get_attr_op_type (insn) == OP_TYPE_RR)
6889 return "bctr\t%1,%0";
6890 else
6891 return "bct\t%1,%a0";
6892 }
6893 [(set (attr "op_type")
6894 (if_then_else (match_operand 0 "register_operand" "")
6895 (const_string "RR") (const_string "RX")))
6896 (set_attr "type" "branch")
6897 (set_attr "atype" "agen")])
6898
6899 (define_insn_and_split "doloop_di"
6900 [(set (pc)
6901 (if_then_else
6902 (ne (match_operand:DI 1 "register_operand" "d,d,d")
6903 (const_int 1))
6904 (label_ref (match_operand 0 "" ""))
6905 (pc)))
6906 (set (match_operand:DI 2 "nonimmediate_operand" "=1,?X,?X")
6907 (plus:DI (match_dup 1) (const_int -1)))
6908 (clobber (match_scratch:DI 3 "=X,&1,&?d"))
6909 (clobber (reg:CC CC_REGNUM))]
6910 "TARGET_64BIT"
6911 {
6912 if (which_alternative != 0)
6913 return "#";
6914 else if (get_attr_length (insn) == 4)
6915 return "brctg\t%1,%l0";
6916 else
6917 return "aghi\t%1,-1\;jgne\t%l0";
6918 }
6919 "&& reload_completed
6920 && (! REG_P (operands[2])
6921 || ! rtx_equal_p (operands[1], operands[2]))"
6922 [(set (match_dup 3) (match_dup 1))
6923 (parallel [(set (reg:CCAN CC_REGNUM)
6924 (compare:CCAN (plus:DI (match_dup 3) (const_int -1))
6925 (const_int 0)))
6926 (set (match_dup 3) (plus:DI (match_dup 3) (const_int -1)))])
6927 (set (match_dup 2) (match_dup 3))
6928 (set (pc) (if_then_else (ne (reg:CCAN CC_REGNUM) (const_int 0))
6929 (label_ref (match_dup 0))
6930 (pc)))]
6931 ""
6932 [(set_attr "op_type" "RI")
6933 (set_attr "type" "branch")
6934 (set (attr "length")
6935 (if_then_else (lt (abs (minus (pc) (match_dup 0))) (const_int 60000))
6936 (const_int 4) (const_int 10)))])
6937
6938 ;;
6939 ;;- Unconditional jump instructions.
6940 ;;
6941
6942 ;
6943 ; jump instruction pattern(s).
6944 ;
6945
6946 (define_expand "jump"
6947 [(match_operand 0 "" "")]
6948 ""
6949 "s390_emit_jump (operands[0], NULL_RTX); DONE;")
6950
6951 (define_insn "*jump64"
6952 [(set (pc) (label_ref (match_operand 0 "" "")))]
6953 "TARGET_CPU_ZARCH"
6954 {
6955 if (get_attr_length (insn) == 4)
6956 return "j\t%l0";
6957 else
6958 return "jg\t%l0";
6959 }
6960 [(set_attr "op_type" "RI")
6961 (set_attr "type" "branch")
6962 (set (attr "length")
6963 (if_then_else (lt (abs (minus (pc) (match_dup 0))) (const_int 60000))
6964 (const_int 4) (const_int 6)))])
6965
6966 (define_insn "*jump31"
6967 [(set (pc) (label_ref (match_operand 0 "" "")))]
6968 "!TARGET_CPU_ZARCH"
6969 {
6970 gcc_assert (get_attr_length (insn) == 4);
6971 return "j\t%l0";
6972 }
6973 [(set_attr "op_type" "RI")
6974 (set_attr "type" "branch")
6975 (set (attr "length")
6976 (if_then_else (eq (symbol_ref "flag_pic") (const_int 0))
6977 (if_then_else (lt (abs (minus (pc) (match_dup 0))) (const_int 60000))
6978 (const_int 4) (const_int 6))
6979 (if_then_else (lt (abs (minus (pc) (match_dup 0))) (const_int 60000))
6980 (const_int 4) (const_int 8))))])
6981
6982 ;
6983 ; indirect-jump instruction pattern(s).
6984 ;
6985
6986 (define_insn "indirect_jump"
6987 [(set (pc) (match_operand 0 "address_operand" "U"))]
6988 ""
6989 {
6990 if (get_attr_op_type (insn) == OP_TYPE_RR)
6991 return "br\t%0";
6992 else
6993 return "b\t%a0";
6994 }
6995 [(set (attr "op_type")
6996 (if_then_else (match_operand 0 "register_operand" "")
6997 (const_string "RR") (const_string "RX")))
6998 (set_attr "type" "branch")
6999 (set_attr "atype" "agen")])
7000
7001 ;
7002 ; casesi instruction pattern(s).
7003 ;
7004
7005 (define_insn "casesi_jump"
7006 [(set (pc) (match_operand 0 "address_operand" "U"))
7007 (use (label_ref (match_operand 1 "" "")))]
7008 ""
7009 {
7010 if (get_attr_op_type (insn) == OP_TYPE_RR)
7011 return "br\t%0";
7012 else
7013 return "b\t%a0";
7014 }
7015 [(set (attr "op_type")
7016 (if_then_else (match_operand 0 "register_operand" "")
7017 (const_string "RR") (const_string "RX")))
7018 (set_attr "type" "branch")
7019 (set_attr "atype" "agen")])
7020
7021 (define_expand "casesi"
7022 [(match_operand:SI 0 "general_operand" "")
7023 (match_operand:SI 1 "general_operand" "")
7024 (match_operand:SI 2 "general_operand" "")
7025 (label_ref (match_operand 3 "" ""))
7026 (label_ref (match_operand 4 "" ""))]
7027 ""
7028 {
7029 rtx index = gen_reg_rtx (SImode);
7030 rtx base = gen_reg_rtx (Pmode);
7031 rtx target = gen_reg_rtx (Pmode);
7032
7033 emit_move_insn (index, operands[0]);
7034 emit_insn (gen_subsi3 (index, index, operands[1]));
7035 emit_cmp_and_jump_insns (index, operands[2], GTU, NULL_RTX, SImode, 1,
7036 operands[4]);
7037
7038 if (Pmode != SImode)
7039 index = convert_to_mode (Pmode, index, 1);
7040 if (GET_CODE (index) != REG)
7041 index = copy_to_mode_reg (Pmode, index);
7042
7043 if (TARGET_64BIT)
7044 emit_insn (gen_ashldi3 (index, index, GEN_INT (3)));
7045 else
7046 emit_insn (gen_ashlsi3 (index, index, const2_rtx));
7047
7048 emit_move_insn (base, gen_rtx_LABEL_REF (Pmode, operands[3]));
7049
7050 index = gen_const_mem (Pmode, gen_rtx_PLUS (Pmode, base, index));
7051 emit_move_insn (target, index);
7052
7053 if (flag_pic)
7054 target = gen_rtx_PLUS (Pmode, base, target);
7055 emit_jump_insn (gen_casesi_jump (target, operands[3]));
7056
7057 DONE;
7058 })
7059
7060
7061 ;;
7062 ;;- Jump to subroutine.
7063 ;;
7064 ;;
7065
7066 ;
7067 ; untyped call instruction pattern(s).
7068 ;
7069
7070 ;; Call subroutine returning any type.
7071 (define_expand "untyped_call"
7072 [(parallel [(call (match_operand 0 "" "")
7073 (const_int 0))
7074 (match_operand 1 "" "")
7075 (match_operand 2 "" "")])]
7076 ""
7077 {
7078 int i;
7079
7080 emit_call_insn (gen_call (operands[0], const0_rtx, const0_rtx));
7081
7082 for (i = 0; i < XVECLEN (operands[2], 0); i++)
7083 {
7084 rtx set = XVECEXP (operands[2], 0, i);
7085 emit_move_insn (SET_DEST (set), SET_SRC (set));
7086 }
7087
7088 /* The optimizer does not know that the call sets the function value
7089 registers we stored in the result block. We avoid problems by
7090 claiming that all hard registers are used and clobbered at this
7091 point. */
7092 emit_insn (gen_blockage ());
7093
7094 DONE;
7095 })
7096
7097 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
7098 ;; all of memory. This blocks insns from being moved across this point.
7099
7100 (define_insn "blockage"
7101 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
7102 ""
7103 ""
7104 [(set_attr "type" "none")
7105 (set_attr "length" "0")])
7106
7107 ;
7108 ; sibcall patterns
7109 ;
7110
7111 (define_expand "sibcall"
7112 [(call (match_operand 0 "" "")
7113 (match_operand 1 "" ""))]
7114 ""
7115 {
7116 s390_emit_call (XEXP (operands[0], 0), NULL_RTX, NULL_RTX, NULL_RTX);
7117 DONE;
7118 })
7119
7120 (define_insn "*sibcall_br"
7121 [(call (mem:QI (reg SIBCALL_REGNUM))
7122 (match_operand 0 "const_int_operand" "n"))]
7123 "SIBLING_CALL_P (insn)
7124 && GET_MODE (XEXP (XEXP (PATTERN (insn), 0), 0)) == Pmode"
7125 "br\t%%r1"
7126 [(set_attr "op_type" "RR")
7127 (set_attr "type" "branch")
7128 (set_attr "atype" "agen")])
7129
7130 (define_insn "*sibcall_brc"
7131 [(call (mem:QI (match_operand 0 "bras_sym_operand" "X"))
7132 (match_operand 1 "const_int_operand" "n"))]
7133 "SIBLING_CALL_P (insn) && TARGET_SMALL_EXEC"
7134 "j\t%0"
7135 [(set_attr "op_type" "RI")
7136 (set_attr "type" "branch")])
7137
7138 (define_insn "*sibcall_brcl"
7139 [(call (mem:QI (match_operand 0 "bras_sym_operand" "X"))
7140 (match_operand 1 "const_int_operand" "n"))]
7141 "SIBLING_CALL_P (insn) && TARGET_CPU_ZARCH"
7142 "jg\t%0"
7143 [(set_attr "op_type" "RIL")
7144 (set_attr "type" "branch")])
7145
7146 ;
7147 ; sibcall_value patterns
7148 ;
7149
7150 (define_expand "sibcall_value"
7151 [(set (match_operand 0 "" "")
7152 (call (match_operand 1 "" "")
7153 (match_operand 2 "" "")))]
7154 ""
7155 {
7156 s390_emit_call (XEXP (operands[1], 0), NULL_RTX, operands[0], NULL_RTX);
7157 DONE;
7158 })
7159
7160 (define_insn "*sibcall_value_br"
7161 [(set (match_operand 0 "" "")
7162 (call (mem:QI (reg SIBCALL_REGNUM))
7163 (match_operand 1 "const_int_operand" "n")))]
7164 "SIBLING_CALL_P (insn)
7165 && GET_MODE (XEXP (XEXP (XEXP (PATTERN (insn), 1), 0), 0)) == Pmode"
7166 "br\t%%r1"
7167 [(set_attr "op_type" "RR")
7168 (set_attr "type" "branch")
7169 (set_attr "atype" "agen")])
7170
7171 (define_insn "*sibcall_value_brc"
7172 [(set (match_operand 0 "" "")
7173 (call (mem:QI (match_operand 1 "bras_sym_operand" "X"))
7174 (match_operand 2 "const_int_operand" "n")))]
7175 "SIBLING_CALL_P (insn) && TARGET_SMALL_EXEC"
7176 "j\t%1"
7177 [(set_attr "op_type" "RI")
7178 (set_attr "type" "branch")])
7179
7180 (define_insn "*sibcall_value_brcl"
7181 [(set (match_operand 0 "" "")
7182 (call (mem:QI (match_operand 1 "bras_sym_operand" "X"))
7183 (match_operand 2 "const_int_operand" "n")))]
7184 "SIBLING_CALL_P (insn) && TARGET_CPU_ZARCH"
7185 "jg\t%1"
7186 [(set_attr "op_type" "RIL")
7187 (set_attr "type" "branch")])
7188
7189
7190 ;
7191 ; call instruction pattern(s).
7192 ;
7193
7194 (define_expand "call"
7195 [(call (match_operand 0 "" "")
7196 (match_operand 1 "" ""))
7197 (use (match_operand 2 "" ""))]
7198 ""
7199 {
7200 s390_emit_call (XEXP (operands[0], 0), NULL_RTX, NULL_RTX,
7201 gen_rtx_REG (Pmode, RETURN_REGNUM));
7202 DONE;
7203 })
7204
7205 (define_insn "*bras"
7206 [(call (mem:QI (match_operand 0 "bras_sym_operand" "X"))
7207 (match_operand 1 "const_int_operand" "n"))
7208 (clobber (match_operand 2 "register_operand" "=r"))]
7209 "!SIBLING_CALL_P (insn)
7210 && TARGET_SMALL_EXEC
7211 && GET_MODE (operands[2]) == Pmode"
7212 "bras\t%2,%0"
7213 [(set_attr "op_type" "RI")
7214 (set_attr "type" "jsr")])
7215
7216 (define_insn "*brasl"
7217 [(call (mem:QI (match_operand 0 "bras_sym_operand" "X"))
7218 (match_operand 1 "const_int_operand" "n"))
7219 (clobber (match_operand 2 "register_operand" "=r"))]
7220 "!SIBLING_CALL_P (insn)
7221 && TARGET_CPU_ZARCH
7222 && GET_MODE (operands[2]) == Pmode"
7223 "brasl\t%2,%0"
7224 [(set_attr "op_type" "RIL")
7225 (set_attr "type" "jsr")])
7226
7227 (define_insn "*basr"
7228 [(call (mem:QI (match_operand 0 "address_operand" "U"))
7229 (match_operand 1 "const_int_operand" "n"))
7230 (clobber (match_operand 2 "register_operand" "=r"))]
7231 "!SIBLING_CALL_P (insn) && GET_MODE (operands[2]) == Pmode"
7232 {
7233 if (get_attr_op_type (insn) == OP_TYPE_RR)
7234 return "basr\t%2,%0";
7235 else
7236 return "bas\t%2,%a0";
7237 }
7238 [(set (attr "op_type")
7239 (if_then_else (match_operand 0 "register_operand" "")
7240 (const_string "RR") (const_string "RX")))
7241 (set_attr "type" "jsr")
7242 (set_attr "atype" "agen")])
7243
7244 ;
7245 ; call_value instruction pattern(s).
7246 ;
7247
7248 (define_expand "call_value"
7249 [(set (match_operand 0 "" "")
7250 (call (match_operand 1 "" "")
7251 (match_operand 2 "" "")))
7252 (use (match_operand 3 "" ""))]
7253 ""
7254 {
7255 s390_emit_call (XEXP (operands[1], 0), NULL_RTX, operands[0],
7256 gen_rtx_REG (Pmode, RETURN_REGNUM));
7257 DONE;
7258 })
7259
7260 (define_insn "*bras_r"
7261 [(set (match_operand 0 "" "")
7262 (call (mem:QI (match_operand 1 "bras_sym_operand" "X"))
7263 (match_operand:SI 2 "const_int_operand" "n")))
7264 (clobber (match_operand 3 "register_operand" "=r"))]
7265 "!SIBLING_CALL_P (insn)
7266 && TARGET_SMALL_EXEC
7267 && GET_MODE (operands[3]) == Pmode"
7268 "bras\t%3,%1"
7269 [(set_attr "op_type" "RI")
7270 (set_attr "type" "jsr")])
7271
7272 (define_insn "*brasl_r"
7273 [(set (match_operand 0 "" "")
7274 (call (mem:QI (match_operand 1 "bras_sym_operand" "X"))
7275 (match_operand 2 "const_int_operand" "n")))
7276 (clobber (match_operand 3 "register_operand" "=r"))]
7277 "!SIBLING_CALL_P (insn)
7278 && TARGET_CPU_ZARCH
7279 && GET_MODE (operands[3]) == Pmode"
7280 "brasl\t%3,%1"
7281 [(set_attr "op_type" "RIL")
7282 (set_attr "type" "jsr")])
7283
7284 (define_insn "*basr_r"
7285 [(set (match_operand 0 "" "")
7286 (call (mem:QI (match_operand 1 "address_operand" "U"))
7287 (match_operand 2 "const_int_operand" "n")))
7288 (clobber (match_operand 3 "register_operand" "=r"))]
7289 "!SIBLING_CALL_P (insn) && GET_MODE (operands[3]) == Pmode"
7290 {
7291 if (get_attr_op_type (insn) == OP_TYPE_RR)
7292 return "basr\t%3,%1";
7293 else
7294 return "bas\t%3,%a1";
7295 }
7296 [(set (attr "op_type")
7297 (if_then_else (match_operand 1 "register_operand" "")
7298 (const_string "RR") (const_string "RX")))
7299 (set_attr "type" "jsr")
7300 (set_attr "atype" "agen")])
7301
7302 ;;
7303 ;;- Thread-local storage support.
7304 ;;
7305
7306 (define_expand "get_tp_64"
7307 [(set (match_operand:DI 0 "nonimmediate_operand" "") (reg:DI TP_REGNUM))]
7308 "TARGET_64BIT"
7309 "")
7310
7311 (define_expand "get_tp_31"
7312 [(set (match_operand:SI 0 "nonimmediate_operand" "") (reg:SI TP_REGNUM))]
7313 "!TARGET_64BIT"
7314 "")
7315
7316 (define_expand "set_tp_64"
7317 [(set (reg:DI TP_REGNUM) (match_operand:DI 0 "nonimmediate_operand" ""))
7318 (set (reg:DI TP_REGNUM) (unspec_volatile:DI [(reg:DI TP_REGNUM)] UNSPECV_SET_TP))]
7319 "TARGET_64BIT"
7320 "")
7321
7322 (define_expand "set_tp_31"
7323 [(set (reg:SI TP_REGNUM) (match_operand:SI 0 "nonimmediate_operand" ""))
7324 (set (reg:SI TP_REGNUM) (unspec_volatile:SI [(reg:SI TP_REGNUM)] UNSPECV_SET_TP))]
7325 "!TARGET_64BIT"
7326 "")
7327
7328 (define_insn "*set_tp"
7329 [(set (reg TP_REGNUM) (unspec_volatile [(reg TP_REGNUM)] UNSPECV_SET_TP))]
7330 ""
7331 ""
7332 [(set_attr "type" "none")
7333 (set_attr "length" "0")])
7334
7335 (define_insn "*tls_load_64"
7336 [(set (match_operand:DI 0 "register_operand" "=d")
7337 (unspec:DI [(match_operand:DI 1 "memory_operand" "m")
7338 (match_operand:DI 2 "" "")]
7339 UNSPEC_TLS_LOAD))]
7340 "TARGET_64BIT"
7341 "lg\t%0,%1%J2"
7342 [(set_attr "op_type" "RXE")])
7343
7344 (define_insn "*tls_load_31"
7345 [(set (match_operand:SI 0 "register_operand" "=d,d")
7346 (unspec:SI [(match_operand:SI 1 "memory_operand" "R,T")
7347 (match_operand:SI 2 "" "")]
7348 UNSPEC_TLS_LOAD))]
7349 "!TARGET_64BIT"
7350 "@
7351 l\t%0,%1%J2
7352 ly\t%0,%1%J2"
7353 [(set_attr "op_type" "RX,RXY")])
7354
7355 (define_insn "*bras_tls"
7356 [(set (match_operand 0 "" "")
7357 (call (mem:QI (match_operand 1 "bras_sym_operand" "X"))
7358 (match_operand 2 "const_int_operand" "n")))
7359 (clobber (match_operand 3 "register_operand" "=r"))
7360 (use (match_operand 4 "" ""))]
7361 "!SIBLING_CALL_P (insn)
7362 && TARGET_SMALL_EXEC
7363 && GET_MODE (operands[3]) == Pmode"
7364 "bras\t%3,%1%J4"
7365 [(set_attr "op_type" "RI")
7366 (set_attr "type" "jsr")])
7367
7368 (define_insn "*brasl_tls"
7369 [(set (match_operand 0 "" "")
7370 (call (mem:QI (match_operand 1 "bras_sym_operand" "X"))
7371 (match_operand 2 "const_int_operand" "n")))
7372 (clobber (match_operand 3 "register_operand" "=r"))
7373 (use (match_operand 4 "" ""))]
7374 "!SIBLING_CALL_P (insn)
7375 && TARGET_CPU_ZARCH
7376 && GET_MODE (operands[3]) == Pmode"
7377 "brasl\t%3,%1%J4"
7378 [(set_attr "op_type" "RIL")
7379 (set_attr "type" "jsr")])
7380
7381 (define_insn "*basr_tls"
7382 [(set (match_operand 0 "" "")
7383 (call (mem:QI (match_operand 1 "address_operand" "U"))
7384 (match_operand 2 "const_int_operand" "n")))
7385 (clobber (match_operand 3 "register_operand" "=r"))
7386 (use (match_operand 4 "" ""))]
7387 "!SIBLING_CALL_P (insn) && GET_MODE (operands[3]) == Pmode"
7388 {
7389 if (get_attr_op_type (insn) == OP_TYPE_RR)
7390 return "basr\t%3,%1%J4";
7391 else
7392 return "bas\t%3,%a1%J4";
7393 }
7394 [(set (attr "op_type")
7395 (if_then_else (match_operand 1 "register_operand" "")
7396 (const_string "RR") (const_string "RX")))
7397 (set_attr "type" "jsr")
7398 (set_attr "atype" "agen")])
7399
7400 ;;
7401 ;;- Atomic operations
7402 ;;
7403
7404 ;
7405 ; memory barrier pattern.
7406 ;
7407
7408 (define_expand "memory_barrier"
7409 [(set (mem:BLK (match_dup 0))
7410 (unspec_volatile:BLK [(mem:BLK (match_dup 0))] UNSPECV_MB))]
7411 ""
7412 {
7413 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (DImode));
7414 MEM_VOLATILE_P (operands[0]) = 1;
7415 })
7416
7417 (define_insn "*memory_barrier"
7418 [(set (match_operand:BLK 0 "" "")
7419 (unspec_volatile:BLK [(match_operand:BLK 1 "" "")] UNSPECV_MB))]
7420 ""
7421 "bcr\t15,0"
7422 [(set_attr "op_type" "RR")])
7423
7424 ;
7425 ; compare and swap patterns.
7426 ;
7427
7428 (define_expand "sync_compare_and_swap<mode>"
7429 [(parallel
7430 [(set (match_operand:TDSI 0 "register_operand" "")
7431 (match_operand:TDSI 1 "memory_operand" ""))
7432 (set (match_dup 1)
7433 (unspec_volatile:TDSI
7434 [(match_dup 1)
7435 (match_operand:TDSI 2 "register_operand" "")
7436 (match_operand:TDSI 3 "register_operand" "")]
7437 UNSPECV_CAS))
7438 (set (reg:CCZ1 CC_REGNUM)
7439 (compare:CCZ1 (match_dup 1) (match_dup 2)))])]
7440 "")
7441
7442 (define_expand "sync_compare_and_swap<mode>"
7443 [(parallel
7444 [(set (match_operand:HQI 0 "register_operand" "")
7445 (match_operand:HQI 1 "memory_operand" ""))
7446 (set (match_dup 1)
7447 (unspec_volatile:HQI
7448 [(match_dup 1)
7449 (match_operand:HQI 2 "general_operand" "")
7450 (match_operand:HQI 3 "general_operand" "")]
7451 UNSPECV_CAS))
7452 (set (reg:CCZ1 CC_REGNUM)
7453 (compare:CCZ1 (match_dup 1) (match_dup 2)))])]
7454 ""
7455 "s390_expand_cs_hqi (<MODE>mode, operands[0], operands[1],
7456 operands[2], operands[3]); DONE;")
7457
7458 (define_expand "sync_compare_and_swap_cc<mode>"
7459 [(parallel
7460 [(set (match_operand:TDSI 0 "register_operand" "")
7461 (match_operand:TDSI 1 "memory_operand" ""))
7462 (set (match_dup 1)
7463 (unspec_volatile:TDSI
7464 [(match_dup 1)
7465 (match_operand:TDSI 2 "register_operand" "")
7466 (match_operand:TDSI 3 "register_operand" "")]
7467 UNSPECV_CAS))
7468 (set (match_dup 4)
7469 (compare:CCZ1 (match_dup 1) (match_dup 2)))])]
7470 ""
7471 {
7472 /* Emulate compare. */
7473 operands[4] = gen_rtx_REG (CCZ1mode, CC_REGNUM);
7474 s390_compare_op0 = operands[1];
7475 s390_compare_op1 = operands[2];
7476 s390_compare_emitted = operands[4];
7477 })
7478
7479 ; cds, cdsg
7480 (define_insn "*sync_compare_and_swap<mode>"
7481 [(set (match_operand:DP 0 "register_operand" "=r")
7482 (match_operand:DP 1 "memory_operand" "+Q"))
7483 (set (match_dup 1)
7484 (unspec_volatile:DP
7485 [(match_dup 1)
7486 (match_operand:DP 2 "register_operand" "0")
7487 (match_operand:DP 3 "register_operand" "r")]
7488 UNSPECV_CAS))
7489 (set (reg:CCZ1 CC_REGNUM)
7490 (compare:CCZ1 (match_dup 1) (match_dup 2)))]
7491 ""
7492 "cds<tg>\t%0,%3,%S1"
7493 [(set_attr "op_type" "RS<TE>")
7494 (set_attr "type" "sem")])
7495
7496 ; cs, csg
7497 (define_insn "*sync_compare_and_swap<mode>"
7498 [(set (match_operand:GPR 0 "register_operand" "=r")
7499 (match_operand:GPR 1 "memory_operand" "+Q"))
7500 (set (match_dup 1)
7501 (unspec_volatile:GPR
7502 [(match_dup 1)
7503 (match_operand:GPR 2 "register_operand" "0")
7504 (match_operand:GPR 3 "register_operand" "r")]
7505 UNSPECV_CAS))
7506 (set (reg:CCZ1 CC_REGNUM)
7507 (compare:CCZ1 (match_dup 1) (match_dup 2)))]
7508 ""
7509 "cs<g>\t%0,%3,%S1"
7510 [(set_attr "op_type" "RS<E>")
7511 (set_attr "type" "sem")])
7512
7513
7514 ;
7515 ; Other atomic instruction patterns.
7516 ;
7517
7518 (define_expand "sync_lock_test_and_set<mode>"
7519 [(match_operand:HQI 0 "register_operand")
7520 (match_operand:HQI 1 "memory_operand")
7521 (match_operand:HQI 2 "general_operand")]
7522 ""
7523 "s390_expand_atomic (<MODE>mode, SET, operands[0], operands[1],
7524 operands[2], false); DONE;")
7525
7526 (define_expand "sync_<atomic><mode>"
7527 [(set (match_operand:HQI 0 "memory_operand")
7528 (ATOMIC:HQI (match_dup 0)
7529 (match_operand:HQI 1 "general_operand")))]
7530 ""
7531 "s390_expand_atomic (<MODE>mode, <CODE>, NULL_RTX, operands[0],
7532 operands[1], false); DONE;")
7533
7534 (define_expand "sync_old_<atomic><mode>"
7535 [(set (match_operand:HQI 0 "register_operand")
7536 (match_operand:HQI 1 "memory_operand"))
7537 (set (match_dup 1)
7538 (ATOMIC:HQI (match_dup 1)
7539 (match_operand:HQI 2 "general_operand")))]
7540 ""
7541 "s390_expand_atomic (<MODE>mode, <CODE>, operands[0], operands[1],
7542 operands[2], false); DONE;")
7543
7544 (define_expand "sync_new_<atomic><mode>"
7545 [(set (match_operand:HQI 0 "register_operand")
7546 (ATOMIC:HQI (match_operand:HQI 1 "memory_operand")
7547 (match_operand:HQI 2 "general_operand")))
7548 (set (match_dup 1) (ATOMIC:HQI (match_dup 1) (match_dup 2)))]
7549 ""
7550 "s390_expand_atomic (<MODE>mode, <CODE>, operands[0], operands[1],
7551 operands[2], true); DONE;")
7552
7553 ;;
7554 ;;- Miscellaneous instructions.
7555 ;;
7556
7557 ;
7558 ; allocate stack instruction pattern(s).
7559 ;
7560
7561 (define_expand "allocate_stack"
7562 [(match_operand 0 "general_operand" "")
7563 (match_operand 1 "general_operand" "")]
7564 "TARGET_BACKCHAIN"
7565 {
7566 rtx temp = gen_reg_rtx (Pmode);
7567
7568 emit_move_insn (temp, s390_back_chain_rtx ());
7569 anti_adjust_stack (operands[1]);
7570 emit_move_insn (s390_back_chain_rtx (), temp);
7571
7572 emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
7573 DONE;
7574 })
7575
7576
7577 ;
7578 ; setjmp instruction pattern.
7579 ;
7580
7581 (define_expand "builtin_setjmp_receiver"
7582 [(match_operand 0 "" "")]
7583 "flag_pic"
7584 {
7585 emit_insn (s390_load_got ());
7586 emit_insn (gen_rtx_USE (VOIDmode, pic_offset_table_rtx));
7587 DONE;
7588 })
7589
7590 ;; These patterns say how to save and restore the stack pointer. We need not
7591 ;; save the stack pointer at function level since we are careful to
7592 ;; preserve the backchain. At block level, we have to restore the backchain
7593 ;; when we restore the stack pointer.
7594 ;;
7595 ;; For nonlocal gotos, we must save both the stack pointer and its
7596 ;; backchain and restore both. Note that in the nonlocal case, the
7597 ;; save area is a memory location.
7598
7599 (define_expand "save_stack_function"
7600 [(match_operand 0 "general_operand" "")
7601 (match_operand 1 "general_operand" "")]
7602 ""
7603 "DONE;")
7604
7605 (define_expand "restore_stack_function"
7606 [(match_operand 0 "general_operand" "")
7607 (match_operand 1 "general_operand" "")]
7608 ""
7609 "DONE;")
7610
7611 (define_expand "restore_stack_block"
7612 [(match_operand 0 "register_operand" "")
7613 (match_operand 1 "register_operand" "")]
7614 "TARGET_BACKCHAIN"
7615 {
7616 rtx temp = gen_reg_rtx (Pmode);
7617
7618 emit_move_insn (temp, s390_back_chain_rtx ());
7619 emit_move_insn (operands[0], operands[1]);
7620 emit_move_insn (s390_back_chain_rtx (), temp);
7621
7622 DONE;
7623 })
7624
7625 (define_expand "save_stack_nonlocal"
7626 [(match_operand 0 "memory_operand" "")
7627 (match_operand 1 "register_operand" "")]
7628 ""
7629 {
7630 enum machine_mode mode = TARGET_64BIT ? OImode : TImode;
7631 rtx base = gen_rtx_REG (Pmode, BASE_REGNUM);
7632
7633 /* Copy the backchain to the first word, sp to the second and the
7634 literal pool base to the third. */
7635
7636 if (TARGET_BACKCHAIN)
7637 {
7638 rtx temp = force_reg (Pmode, s390_back_chain_rtx ());
7639 emit_move_insn (operand_subword (operands[0], 0, 0, mode), temp);
7640 }
7641
7642 emit_move_insn (operand_subword (operands[0], 1, 0, mode), operands[1]);
7643 emit_move_insn (operand_subword (operands[0], 2, 0, mode), base);
7644
7645 DONE;
7646 })
7647
7648 (define_expand "restore_stack_nonlocal"
7649 [(match_operand 0 "register_operand" "")
7650 (match_operand 1 "memory_operand" "")]
7651 ""
7652 {
7653 enum machine_mode mode = TARGET_64BIT ? OImode : TImode;
7654 rtx base = gen_rtx_REG (Pmode, BASE_REGNUM);
7655 rtx temp = NULL_RTX;
7656
7657 /* Restore the backchain from the first word, sp from the second and the
7658 literal pool base from the third. */
7659
7660 if (TARGET_BACKCHAIN)
7661 temp = force_reg (Pmode, operand_subword (operands[1], 0, 0, mode));
7662
7663 emit_move_insn (base, operand_subword (operands[1], 2, 0, mode));
7664 emit_move_insn (operands[0], operand_subword (operands[1], 1, 0, mode));
7665
7666 if (temp)
7667 emit_move_insn (s390_back_chain_rtx (), temp);
7668
7669 emit_insn (gen_rtx_USE (VOIDmode, base));
7670 DONE;
7671 })
7672
7673 (define_expand "exception_receiver"
7674 [(const_int 0)]
7675 ""
7676 {
7677 s390_set_has_landing_pad_p (true);
7678 DONE;
7679 })
7680
7681 ;
7682 ; nop instruction pattern(s).
7683 ;
7684
7685 (define_insn "nop"
7686 [(const_int 0)]
7687 ""
7688 "lr\t0,0"
7689 [(set_attr "op_type" "RR")])
7690
7691
7692 ;
7693 ; Special literal pool access instruction pattern(s).
7694 ;
7695
7696 (define_insn "*pool_entry"
7697 [(unspec_volatile [(match_operand 0 "consttable_operand" "X")]
7698 UNSPECV_POOL_ENTRY)]
7699 ""
7700 {
7701 enum machine_mode mode = GET_MODE (PATTERN (insn));
7702 unsigned int align = GET_MODE_BITSIZE (mode);
7703 s390_output_pool_entry (operands[0], mode, align);
7704 return "";
7705 }
7706 [(set (attr "length")
7707 (symbol_ref "GET_MODE_SIZE (GET_MODE (PATTERN (insn)))"))])
7708
7709 (define_insn "pool_align"
7710 [(unspec_volatile [(match_operand 0 "const_int_operand" "n")]
7711 UNSPECV_POOL_ALIGN)]
7712 ""
7713 ".align\t%0"
7714 [(set (attr "length") (symbol_ref "INTVAL (operands[0])"))])
7715
7716 (define_insn "pool_section_start"
7717 [(unspec_volatile [(const_int 1)] UNSPECV_POOL_SECTION)]
7718 ""
7719 ".section\t.rodata"
7720 [(set_attr "length" "0")])
7721
7722 (define_insn "pool_section_end"
7723 [(unspec_volatile [(const_int 0)] UNSPECV_POOL_SECTION)]
7724 ""
7725 ".previous"
7726 [(set_attr "length" "0")])
7727
7728 (define_insn "main_base_31_small"
7729 [(set (match_operand 0 "register_operand" "=a")
7730 (unspec [(label_ref (match_operand 1 "" ""))] UNSPEC_MAIN_BASE))]
7731 "!TARGET_CPU_ZARCH && GET_MODE (operands[0]) == Pmode"
7732 "basr\t%0,0"
7733 [(set_attr "op_type" "RR")
7734 (set_attr "type" "la")])
7735
7736 (define_insn "main_base_31_large"
7737 [(set (match_operand 0 "register_operand" "=a")
7738 (unspec [(label_ref (match_operand 1 "" ""))] UNSPEC_MAIN_BASE))
7739 (set (pc) (label_ref (match_operand 2 "" "")))]
7740 "!TARGET_CPU_ZARCH && GET_MODE (operands[0]) == Pmode"
7741 "bras\t%0,%2"
7742 [(set_attr "op_type" "RI")])
7743
7744 (define_insn "main_base_64"
7745 [(set (match_operand 0 "register_operand" "=a")
7746 (unspec [(label_ref (match_operand 1 "" ""))] UNSPEC_MAIN_BASE))]
7747 "TARGET_CPU_ZARCH && GET_MODE (operands[0]) == Pmode"
7748 "larl\t%0,%1"
7749 [(set_attr "op_type" "RIL")
7750 (set_attr "type" "larl")])
7751
7752 (define_insn "main_pool"
7753 [(set (match_operand 0 "register_operand" "=a")
7754 (unspec_volatile [(const_int 0)] UNSPECV_MAIN_POOL))]
7755 "GET_MODE (operands[0]) == Pmode"
7756 {
7757 gcc_unreachable ();
7758 }
7759 [(set (attr "type")
7760 (if_then_else (ne (symbol_ref "TARGET_CPU_ZARCH") (const_int 0))
7761 (const_string "larl") (const_string "la")))])
7762
7763 (define_insn "reload_base_31"
7764 [(set (match_operand 0 "register_operand" "=a")
7765 (unspec [(label_ref (match_operand 1 "" ""))] UNSPEC_RELOAD_BASE))]
7766 "!TARGET_CPU_ZARCH && GET_MODE (operands[0]) == Pmode"
7767 "basr\t%0,0\;la\t%0,%1-.(%0)"
7768 [(set_attr "length" "6")
7769 (set_attr "type" "la")])
7770
7771 (define_insn "reload_base_64"
7772 [(set (match_operand 0 "register_operand" "=a")
7773 (unspec [(label_ref (match_operand 1 "" ""))] UNSPEC_RELOAD_BASE))]
7774 "TARGET_CPU_ZARCH && GET_MODE (operands[0]) == Pmode"
7775 "larl\t%0,%1"
7776 [(set_attr "op_type" "RIL")
7777 (set_attr "type" "larl")])
7778
7779 (define_insn "pool"
7780 [(unspec_volatile [(match_operand 0 "const_int_operand" "n")] UNSPECV_POOL)]
7781 ""
7782 {
7783 gcc_unreachable ();
7784 }
7785 [(set (attr "length") (symbol_ref "INTVAL (operands[0])"))])
7786
7787 ;;
7788 ;; Insns related to generating the function prologue and epilogue.
7789 ;;
7790
7791
7792 (define_expand "prologue"
7793 [(use (const_int 0))]
7794 ""
7795 "s390_emit_prologue (); DONE;")
7796
7797 (define_expand "epilogue"
7798 [(use (const_int 1))]
7799 ""
7800 "s390_emit_epilogue (false); DONE;")
7801
7802 (define_expand "sibcall_epilogue"
7803 [(use (const_int 0))]
7804 ""
7805 "s390_emit_epilogue (true); DONE;")
7806
7807 (define_insn "*return"
7808 [(return)
7809 (use (match_operand 0 "register_operand" "a"))]
7810 "GET_MODE (operands[0]) == Pmode"
7811 "br\t%0"
7812 [(set_attr "op_type" "RR")
7813 (set_attr "type" "jsr")
7814 (set_attr "atype" "agen")])
7815
7816
7817 ;; Instruction definition to extend a 31-bit pointer into a 64-bit
7818 ;; pointer. This is used for compatibility.
7819
7820 (define_expand "ptr_extend"
7821 [(set (match_operand:DI 0 "register_operand" "=r")
7822 (match_operand:SI 1 "register_operand" "r"))]
7823 "TARGET_64BIT"
7824 {
7825 emit_insn (gen_anddi3 (operands[0],
7826 gen_lowpart (DImode, operands[1]),
7827 GEN_INT (0x7fffffff)));
7828 DONE;
7829 })
7830
7831 ;; Instruction definition to expand eh_return macro to support
7832 ;; swapping in special linkage return addresses.
7833
7834 (define_expand "eh_return"
7835 [(use (match_operand 0 "register_operand" ""))]
7836 "TARGET_TPF"
7837 {
7838 s390_emit_tpf_eh_return (operands[0]);
7839 DONE;
7840 })
7841
7842 ;
7843 ; Stack Protector Patterns
7844 ;
7845
7846 (define_expand "stack_protect_set"
7847 [(set (match_operand 0 "memory_operand" "")
7848 (match_operand 1 "memory_operand" ""))]
7849 ""
7850 {
7851 #ifdef TARGET_THREAD_SSP_OFFSET
7852 operands[1]
7853 = gen_rtx_MEM (Pmode, gen_rtx_PLUS (Pmode, s390_get_thread_pointer (),
7854 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
7855 #endif
7856 if (TARGET_64BIT)
7857 emit_insn (gen_stack_protect_setdi (operands[0], operands[1]));
7858 else
7859 emit_insn (gen_stack_protect_setsi (operands[0], operands[1]));
7860
7861 DONE;
7862 })
7863
7864 (define_insn "stack_protect_set<mode>"
7865 [(set (match_operand:DSI 0 "memory_operand" "=Q")
7866 (unspec:DSI [(match_operand:DSI 1 "memory_operand" "Q")] UNSPEC_SP_SET))]
7867 ""
7868 "mvc\t%O0(%G0,%R0),%S1"
7869 [(set_attr "op_type" "SS")])
7870
7871 (define_expand "stack_protect_test"
7872 [(set (reg:CC CC_REGNUM)
7873 (compare (match_operand 0 "memory_operand" "")
7874 (match_operand 1 "memory_operand" "")))
7875 (match_operand 2 "" "")]
7876 ""
7877 {
7878 #ifdef TARGET_THREAD_SSP_OFFSET
7879 operands[1]
7880 = gen_rtx_MEM (Pmode, gen_rtx_PLUS (Pmode, s390_get_thread_pointer (),
7881 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
7882 #endif
7883 s390_compare_op0 = operands[0];
7884 s390_compare_op1 = operands[1];
7885 s390_compare_emitted = gen_rtx_REG (CCZmode, CC_REGNUM);
7886
7887 if (TARGET_64BIT)
7888 emit_insn (gen_stack_protect_testdi (operands[0], operands[1]));
7889 else
7890 emit_insn (gen_stack_protect_testsi (operands[0], operands[1]));
7891
7892 emit_jump_insn (gen_beq (operands[2]));
7893
7894 DONE;
7895 })
7896
7897 (define_insn "stack_protect_test<mode>"
7898 [(set (reg:CCZ CC_REGNUM)
7899 (unspec:CCZ [(match_operand:DSI 0 "memory_operand" "Q")
7900 (match_operand:DSI 1 "memory_operand" "Q")] UNSPEC_SP_TEST))]
7901 ""
7902 "clc\t%O0(%G0,%R0),%S1"
7903 [(set_attr "op_type" "SS")])