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