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