OSDN Git Service

* builtins.c, c-pragma.h, c-typeck.c, cgraph.c, cgraphunit.c,
[pf3gnuchains/gcc-fork.git] / gcc / config / s390 / s390.md
1 ;;- Machine description for GNU compiler -- S/390 / zSeries version.
2 ;;  Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006
3 ;;  Free Software Foundation, Inc.
4 ;;  Contributed by Hartmut Penner (hpenner@de.ibm.com) and
5 ;;                 Ulrich Weigand (uweigand@de.ibm.com).
6
7 ;; This file is part of GCC.
8
9 ;; GCC is free software; you can redistribute it and/or modify it under
10 ;; the terms of the GNU General Public License as published by the Free
11 ;; Software Foundation; either version 2, or (at your option) any later
12 ;; version.
13
14 ;; GCC is distributed in the hope that it will be useful, but WITHOUT ANY
15 ;; WARRANTY; without even the implied warranty of MERCHANTABILITY or
16 ;; FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
17 ;; for more details.
18
19 ;; You should have received a copy of the GNU General Public License
20 ;; along with GCC; see the file COPYING.  If not, write to the Free
21 ;; Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
22 ;; 02110-1301, USA.
23
24 ;;
25 ;; Special constraints for s/390 machine description:
26 ;;
27 ;;    a -- Any address register from 1 to 15.
28 ;;    c -- Condition code register 33.
29 ;;    d -- Any register from 0 to 15.
30 ;;    f -- Floating point registers.
31 ;;    t -- Access registers 36 and 37.
32 ;;    G -- Const double zero operand
33 ;;    I -- An 8-bit constant (0..255).
34 ;;    J -- A 12-bit constant (0..4095).
35 ;;    K -- A 16-bit constant (-32768..32767).
36 ;;    L -- Value appropriate as displacement.
37 ;;         (0..4095) for short displacement
38 ;;         (-524288..524287) for long displacement
39 ;;    M -- Constant integer with a value of 0x7fffffff.
40 ;;    N -- Multiple letter constraint followed by 4 parameter letters.
41 ;;         0..9,x:  number of the part counting from most to least significant
42 ;;         H,Q:     mode of the part
43 ;;         D,S,H:   mode of the containing operand
44 ;;         0,F:     value of the other parts (F - all bits set)
45 ;;
46 ;;         The constraint matches if the specified part of a constant
47 ;;         has a value different from its other parts.  If the letter x
48 ;;         is specified instead of a part number, the constraint matches
49 ;;         if there is any single part with non-default value.
50 ;;    O -- Multiple letter constraint followed by 1 parameter.
51 ;;         s:  Signed extended immediate value (-2G .. 2G-1).
52 ;;         p:  Positive extended immediate value (0 .. 4G-1).
53 ;;         n:  Negative extended immediate value (-4G .. -1).
54 ;;         These constraints do not accept any operand if the machine does
55 ;;         not provide the extended-immediate facility.
56 ;;    P -- Any integer constant that can be loaded without literal pool.
57 ;;    Q -- Memory reference without index register and with short displacement.
58 ;;    R -- Memory reference with index register and short displacement.
59 ;;    S -- Memory reference without index register but with long displacement.
60 ;;    T -- Memory reference with index register and long displacement.
61 ;;    A -- Multiple letter constraint followed by Q, R, S, or T:
62 ;;         Offsettable memory reference of type specified by second letter.
63 ;;    B -- Multiple letter constraint followed by Q, R, S, or T:
64 ;;         Memory reference of the type specified by second letter that
65 ;;         does *not* refer to a literal pool entry.
66 ;;    U -- Pointer with short displacement.
67 ;;    W -- Pointer with long displacement.
68 ;;    Y -- Shift count operand.
69 ;;
70 ;; Special formats used for outputting 390 instructions.
71 ;;
72 ;;     %C: print opcode suffix for branch condition.
73 ;;     %D: print opcode suffix for inverse branch condition.
74 ;;     %J: print tls_load/tls_gdcall/tls_ldcall suffix
75 ;;     %G: print the size of the operand in bytes.
76 ;;     %O: print only the displacement of a memory reference.
77 ;;     %R: print only the base register of a memory reference.
78 ;;     %S: print S-type memory reference (base+displacement).
79 ;;     %N: print the second word of a DImode operand.
80 ;;     %M: print the second word of a TImode operand.
81 ;;     %Y: print shift count operand.
82 ;;  
83 ;;     %b: print integer X as if it's an unsigned byte.
84 ;;     %x: print integer X as if it's an unsigned halfword.
85 ;;     %h: print integer X as if it's a signed halfword.
86 ;;     %i: print the first nonzero HImode part of X.
87 ;;     %j: print the first HImode part unequal to -1 of X.
88 ;;     %k: print the first nonzero SImode part of X.
89 ;;     %m: print the first SImode part unequal to -1 of X.
90 ;;     %o: print integer X as if it's an unsigned 32bit word.
91 ;;
92 ;; We have a special constraint for pattern matching.
93 ;;
94 ;;   s_operand -- Matches a valid S operand in a RS, SI or SS type instruction.
95 ;;
96
97 ;;
98 ;; UNSPEC usage
99 ;;
100
101 (define_constants
102   [; Miscellaneous
103    (UNSPEC_ROUND                1)
104    (UNSPEC_CMPINT               2)
105    (UNSPEC_ICM                  10)
106
107    ; GOT/PLT and lt-relative accesses
108    (UNSPEC_LTREL_OFFSET         100)
109    (UNSPEC_LTREL_BASE           101)
110    (UNSPEC_GOTENT               110)
111    (UNSPEC_GOT                  111)
112    (UNSPEC_GOTOFF               112)
113    (UNSPEC_PLT                  113)
114    (UNSPEC_PLTOFF               114)
115
116    ; Literal pool
117    (UNSPEC_RELOAD_BASE          210)
118    (UNSPEC_MAIN_BASE            211)
119    (UNSPEC_LTREF                212)
120    (UNSPEC_INSN                 213)
121    (UNSPEC_EXECUTE              214)
122
123    ; TLS relocation specifiers
124    (UNSPEC_TLSGD                500)
125    (UNSPEC_TLSLDM               501)
126    (UNSPEC_NTPOFF               502)
127    (UNSPEC_DTPOFF               503)
128    (UNSPEC_GOTNTPOFF            504)
129    (UNSPEC_INDNTPOFF            505)
130
131    ; TLS support
132    (UNSPEC_TLSLDM_NTPOFF        511)
133    (UNSPEC_TLS_LOAD             512)
134
135    ; String Functions
136    (UNSPEC_SRST                 600)
137    (UNSPEC_MVST                 601)
138    
139    ; Stack Smashing Protector
140    (UNSPEC_SP_SET               700)
141    (UNSPEC_SP_TEST              701)
142  ])
143
144 ;;
145 ;; UNSPEC_VOLATILE usage
146 ;;
147
148 (define_constants
149   [; Blockage
150    (UNSPECV_BLOCKAGE            0)
151
152    ; TPF Support
153    (UNSPECV_TPF_PROLOGUE        20)
154    (UNSPECV_TPF_EPILOGUE        21)
155
156    ; Literal pool
157    (UNSPECV_POOL                200)
158    (UNSPECV_POOL_SECTION        201)
159    (UNSPECV_POOL_ALIGN          202)
160    (UNSPECV_POOL_ENTRY          203)
161    (UNSPECV_MAIN_POOL           300)
162
163    ; TLS support
164    (UNSPECV_SET_TP              500)
165
166    ; Atomic Support
167    (UNSPECV_MB                  700)
168    (UNSPECV_CAS                 701)
169   ])
170
171 ;;
172 ;; Registers
173 ;;
174
175 (define_constants
176   [
177    ; Sibling call register.
178    (SIBCALL_REGNUM               1)
179    ; Literal pool base register.
180    (BASE_REGNUM                 13)
181    ; Return address register.
182    (RETURN_REGNUM               14)
183    ; Condition code register.
184    (CC_REGNUM                   33)
185    ; Thread local storage pointer register. 
186    (TP_REGNUM                   36)
187   ])
188
189
190 ;; Instruction operand type as used in the Principles of Operation.
191 ;; Used to determine defaults for length and other attribute values.
192
193 (define_attr "op_type"
194   "NN,E,RR,RRE,RX,RS,RSI,RI,SI,S,SS,SSE,RXE,RSE,RIL,RIE,RXY,RSY,SIY"
195   (const_string "NN"))
196
197 ;; Instruction type attribute used for scheduling.
198
199 (define_attr "type" "none,integer,load,lr,la,larl,lm,stm,
200                      cs,vs,store,sem,idiv,
201                      imulhi,imulsi,imuldi,
202                      branch,jsr,fsimptf,fsimpdf,fsimpsf,
203                      floadtf,floaddf,floadsf,fstoredf,fstoresf,
204                      fmultf,fmuldf,fmulsf,fdivtf,fdivdf,fdivsf,
205                      ftoi,itof,fsqrttf,fsqrtdf,fsqrtsf,
206                      ftrunctf,ftruncdf,other"
207   (cond [(eq_attr "op_type" "NN")  (const_string "other")
208          (eq_attr "op_type" "SS")  (const_string "cs")]
209     (const_string "integer")))
210
211 ;; Another attribute used for scheduling purposes:
212 ;;   agen: Instruction uses the address generation unit
213 ;;   reg: Instruction does not use the agen unit
214
215 (define_attr "atype" "agen,reg"
216   (if_then_else (eq_attr "op_type" "E,RR,RI,RRE")  
217                 (const_string "reg")
218                 (const_string "agen")))
219
220 ;; Length in bytes.
221
222 (define_attr "length" ""
223   (cond [(eq_attr "op_type" "E,RR")                   (const_int 2)
224          (eq_attr "op_type" "RX,RI,RRE,RS,RSI,S,SI")  (const_int 4)]
225     (const_int 6)))
226
227
228 ;; Processor type.  This attribute must exactly match the processor_type
229 ;; enumeration in s390.h.  The current machine description does not
230 ;; distinguish between g5 and g6, but there are differences between the two
231 ;; CPUs could in theory be modeled.
232
233 (define_attr "cpu" "g5,g6,z900,z990,z9_109"
234   (const (symbol_ref "s390_tune")))
235
236 ;; Pipeline description for z900.  For lack of anything better,
237 ;; this description is also used for the g5 and g6.
238 (include "2064.md")
239
240 ;; Pipeline description for z990. 
241 (include "2084.md")
242
243 ;; Predicates
244 (include "predicates.md")
245
246 ;; Other includes
247 (include "tpf.md")
248
249 ;; Macros
250
251 ;; This mode macro allows floating point patterns to be generated from the
252 ;; same template.
253 (define_mode_macro FPR [TF DF SF])
254 (define_mode_macro DSF [DF SF])
255
256 ;; These mode macros allow 31-bit and 64-bit TDSI patterns to be generated
257 ;; from the same template.
258 (define_mode_macro TDSI [(TI "TARGET_64BIT") DI SI])
259
260 ;; These mode macros allow 31-bit and 64-bit GPR patterns to be generated
261 ;; from the same template.
262 (define_mode_macro GPR [(DI "TARGET_64BIT") SI])
263 (define_mode_macro DSI [DI SI])
264
265 ;; This mode macro allows :P to be used for patterns that operate on
266 ;; pointer-sized quantities.  Exactly one of the two alternatives will match.
267 (define_mode_macro DP  [(TI "TARGET_64BIT") (DI "!TARGET_64BIT")])
268 (define_mode_macro P [(DI "TARGET_64BIT") (SI "!TARGET_64BIT")])
269
270 ;; This mode macro allows the QI and HI patterns to be defined from
271 ;; the same template.
272 (define_mode_macro HQI [HI QI])
273
274 ;; This mode macro allows the integer patterns to be defined from the
275 ;; same template.
276 (define_mode_macro INT [(DI "TARGET_64BIT") SI HI QI])
277
278 ;; This macro allows to unify all 'bCOND' expander patterns.
279 (define_code_macro COMPARE [eq ne gt gtu lt ltu ge geu le leu unordered 
280                             ordered uneq unlt ungt unle unge ltgt])
281
282 ;; This macro allows to unify all 'sCOND' patterns.
283 (define_code_macro SCOND [ltu gtu leu geu])
284
285 ;; This macro allows some 'ashift' and 'lshiftrt' pattern to be defined from
286 ;; the same template.
287 (define_code_macro SHIFT [ashift lshiftrt])
288
289 ;; These macros allow to combine most atomic operations.
290 (define_code_macro ATOMIC [and ior xor plus minus mult])
291 (define_code_attr atomic [(and "and") (ior "ior") (xor "xor") 
292                           (plus "add") (minus "sub") (mult "nand")])
293
294
295 ;; In FPR templates, a string like "lt<de>br" will expand to "ltxbr" in TFmode,
296 ;; "ltdbr" in DFmode, and "ltebr" in SFmode.
297 (define_mode_attr xde [(TF "x") (DF "d") (SF "e")])
298
299 ;; In FPR templates, a string like "m<dee>br" will expand to "mxbr" in TFmode,
300 ;; "mdbr" in DFmode, and "meebr" in SFmode.
301 (define_mode_attr xdee [(TF "x") (DF "d") (SF "ee")])
302
303 ;; In FPR templates, "<RRe>" will expand to "RRE" in TFmode and "RR" otherwise.
304 ;; Likewise for "<RXe>".
305 (define_mode_attr RRe [(TF "RRE") (DF "RR") (SF "RR")])
306 (define_mode_attr RXe [(TF "RXE") (DF "RX") (SF "RX")])
307
308 ;; In FPR templates, "<Rf>" will expand to "f" in TFmode and "R" otherwise.
309 ;; This is used to disable the memory alternative in TFmode patterns.
310 (define_mode_attr Rf [(TF "f") (DF "R") (SF "R")])
311
312 ;; In GPR and P templates, a constraint like "<d0>" will expand to "d" in DImode
313 ;; and "0" in SImode. This allows to combine instructions of which the 31bit
314 ;; version only operates on one register.
315 (define_mode_attr d0 [(DI "d") (SI "0")])
316
317 ;; In combination with d0 this allows to combine instructions of which the 31bit
318 ;; version only operates on one register. The DImode version needs an additional
319 ;; register for the assembler output.
320 (define_mode_attr 1 [(DI "%1,") (SI "")])
321   
322 ;; In SHIFT templates, a string like "s<lr>dl" will expand to "sldl" in 
323 ;; 'ashift' and "srdl" in 'lshiftrt'.
324 (define_code_attr lr [(ashift "l") (lshiftrt "r")])
325
326 ;; In SHIFT templates, this attribute holds the correct standard name for the
327 ;; pattern itself and the corresponding function calls. 
328 (define_code_attr shift [(ashift "ashl") (lshiftrt "lshr")])
329
330 ;; This attribute handles differences in the instruction 'type' and will result
331 ;; in "RRE" for DImode and "RR" for SImode.
332 (define_mode_attr E [(DI "E") (SI "")])
333
334 ;; This attribute handles differences in the instruction 'type' and makes RX<Y>
335 ;; to result in "RXY" for DImode and "RX" for SImode.
336 (define_mode_attr Y [(DI "Y") (SI "")])
337
338 ;; This attribute handles differences in the instruction 'type' and will result
339 ;; in "RSE" for TImode and "RS" for DImode.
340 (define_mode_attr TE [(TI "E") (DI "")])
341
342 ;; In GPR templates, a string like "lc<g>r" will expand to "lcgr" in DImode
343 ;; and "lcr" in SImode.
344 (define_mode_attr g [(DI "g") (SI "")])
345
346 ;; In GPR templates, a string like "sl<y>" will expand to "slg" in DImode
347 ;; and "sly" in SImode. This is useful because on 64bit the ..g instructions
348 ;; were enhanced with long displacements whereas 31bit instructions got a ..y
349 ;; variant for long displacements.
350 (define_mode_attr y [(DI "g") (SI "y")])
351
352 ;; In DP templates, a string like "cds<g>" will expand to "cdsg" in TImode
353 ;; and "cds" in DImode.
354 (define_mode_attr tg [(TI "g") (DI "")])
355
356 ;; In GPR templates, a string like "c<gf>dbr" will expand to "cgdbr" in DImode
357 ;; and "cfdbr" in SImode.
358 (define_mode_attr gf [(DI "g") (SI "f")])
359
360 ;; ICM mask required to load MODE value into the lowest subreg
361 ;; of a SImode register.
362 (define_mode_attr icm_lo [(HI "3") (QI "1")])
363
364 ;; In HQI templates, a string like "llg<hc>" will expand to "llgh" in
365 ;; HImode and "llgc" in QImode.
366 (define_mode_attr hc [(HI "h") (QI "c")])
367
368 ;; In P templates, the mode <DBL> will expand to "TI" in DImode and "DI"
369 ;; in SImode.
370 (define_mode_attr DBL [(DI "TI") (SI "DI")])
371
372 ;; Maximum unsigned integer that fits in MODE.
373 (define_mode_attr max_uint [(HI "65535") (QI "255")])
374
375
376 ;;
377 ;;- Compare instructions.
378 ;;
379
380 (define_expand "cmp<mode>"
381   [(set (reg:CC CC_REGNUM)
382         (compare:CC (match_operand:GPR 0 "register_operand" "")
383                     (match_operand:GPR 1 "general_operand" "")))]
384   ""
385 {
386   s390_compare_op0 = operands[0];
387   s390_compare_op1 = operands[1];
388   DONE;
389 })
390
391 (define_expand "cmp<mode>"
392   [(set (reg:CC CC_REGNUM)
393         (compare:CC (match_operand:FPR 0 "register_operand" "")
394                     (match_operand:FPR 1 "general_operand" "")))]
395   "TARGET_HARD_FLOAT"
396 {
397   s390_compare_op0 = operands[0];
398   s390_compare_op1 = operands[1];
399   DONE;
400 })
401
402
403 ; Test-under-Mask instructions
404
405 (define_insn "*tmqi_mem"
406   [(set (reg CC_REGNUM)
407         (compare (and:QI (match_operand:QI 0 "memory_operand" "Q,S")
408                          (match_operand:QI 1 "immediate_operand" "n,n"))
409                  (match_operand:QI 2 "immediate_operand" "n,n")))]
410   "s390_match_ccmode (insn, s390_tm_ccmode (operands[1], operands[2], false))"
411   "@
412    tm\t%S0,%b1
413    tmy\t%S0,%b1"
414   [(set_attr "op_type" "SI,SIY")])
415
416 (define_insn "*tmdi_reg"
417   [(set (reg CC_REGNUM)
418         (compare (and:DI (match_operand:DI 0 "nonimmediate_operand" "d,d,d,d")
419                          (match_operand:DI 1 "immediate_operand"
420                                              "N0HD0,N1HD0,N2HD0,N3HD0"))
421                  (match_operand:DI 2 "immediate_operand" "n,n,n,n")))]
422   "TARGET_64BIT
423    && s390_match_ccmode (insn, s390_tm_ccmode (operands[1], operands[2], true))
424    && s390_single_part (operands[1], DImode, HImode, 0) >= 0"
425   "@
426    tmhh\t%0,%i1
427    tmhl\t%0,%i1
428    tmlh\t%0,%i1
429    tmll\t%0,%i1"
430   [(set_attr "op_type" "RI")])
431
432 (define_insn "*tmsi_reg"
433   [(set (reg CC_REGNUM)
434         (compare (and:SI (match_operand:SI 0 "nonimmediate_operand" "d,d")
435                          (match_operand:SI 1 "immediate_operand" "N0HS0,N1HS0"))
436                  (match_operand:SI 2 "immediate_operand" "n,n")))]
437   "s390_match_ccmode (insn, s390_tm_ccmode (operands[1], operands[2], true))
438    && s390_single_part (operands[1], SImode, HImode, 0) >= 0"
439   "@
440    tmh\t%0,%i1
441    tml\t%0,%i1"
442   [(set_attr "op_type" "RI")])
443
444 (define_insn "*tm<mode>_full"
445   [(set (reg CC_REGNUM)
446         (compare (match_operand:HQI 0 "register_operand" "d")
447                  (match_operand:HQI 1 "immediate_operand" "n")))]
448   "s390_match_ccmode (insn, s390_tm_ccmode (constm1_rtx, operands[1], true))"
449   "tml\t%0,<max_uint>"
450   [(set_attr "op_type" "RI")])
451
452
453 ;
454 ; Load-and-Test instructions
455 ;
456
457 ; tst(di|si) instruction pattern(s).
458
459 (define_insn "*tstdi_sign"
460   [(set (reg CC_REGNUM)
461         (compare (ashiftrt:DI (ashift:DI (subreg:DI (match_operand:SI 0 "register_operand" "d") 0)
462                                          (const_int 32)) (const_int 32))
463                  (match_operand:DI 1 "const0_operand" "")))
464    (set (match_operand:DI 2 "register_operand" "=d")
465         (sign_extend:DI (match_dup 0)))]
466   "s390_match_ccmode(insn, CCSmode) && TARGET_64BIT"
467   "ltgfr\t%2,%0"
468   [(set_attr "op_type" "RRE")])
469
470 (define_insn "*tst<mode>_extimm"
471   [(set (reg CC_REGNUM)
472         (compare (match_operand:GPR 0 "nonimmediate_operand" "d,m")
473                  (match_operand:GPR 1 "const0_operand" "")))
474    (set (match_operand:GPR 2 "register_operand" "=d,d")
475         (match_dup 0))]
476   "s390_match_ccmode(insn, CCSmode) && TARGET_EXTIMM"
477   "@
478    lt<g>r\t%2,%0
479    lt<g>\t%2,%0"
480   [(set_attr "op_type" "RR<E>,RXY")])
481
482 (define_insn "*tst<mode>_cconly_extimm"
483   [(set (reg CC_REGNUM)
484         (compare (match_operand:GPR 0 "nonimmediate_operand" "d,m")
485                  (match_operand:GPR 1 "const0_operand" "")))
486    (clobber (match_scratch:GPR 2 "=X,d"))]
487   "s390_match_ccmode(insn, CCSmode) && TARGET_EXTIMM"
488   "@
489    lt<g>r\t%0,%0
490    lt<g>\t%2,%0"
491   [(set_attr "op_type" "RR<E>,RXY")])
492
493 (define_insn "*tstdi"
494   [(set (reg CC_REGNUM)
495         (compare (match_operand:DI 0 "register_operand" "d")
496                  (match_operand:DI 1 "const0_operand" "")))
497    (set (match_operand:DI 2 "register_operand" "=d")
498         (match_dup 0))]
499   "s390_match_ccmode(insn, CCSmode) && TARGET_64BIT && !TARGET_EXTIMM"
500   "ltgr\t%2,%0"
501   [(set_attr "op_type" "RRE")])
502
503 (define_insn "*tstsi"
504   [(set (reg CC_REGNUM)
505         (compare (match_operand:SI 0 "nonimmediate_operand" "d,Q,S")
506                  (match_operand:SI 1 "const0_operand" "")))
507    (set (match_operand:SI 2 "register_operand" "=d,d,d")
508         (match_dup 0))]
509   "s390_match_ccmode(insn, CCSmode) && !TARGET_EXTIMM"
510   "@
511    ltr\t%2,%0
512    icm\t%2,15,%S0
513    icmy\t%2,15,%S0"
514   [(set_attr "op_type" "RR,RS,RSY")])
515
516 (define_insn "*tstsi_cconly"
517   [(set (reg CC_REGNUM)
518         (compare (match_operand:SI 0 "nonimmediate_operand" "d,Q,S")
519                  (match_operand:SI 1 "const0_operand" "")))
520    (clobber (match_scratch:SI 2 "=X,d,d"))]
521   "s390_match_ccmode(insn, CCSmode)"
522   "@
523    ltr\t%0,%0
524    icm\t%2,15,%S0
525    icmy\t%2,15,%S0"
526   [(set_attr "op_type" "RR,RS,RSY")])
527
528 (define_insn "*tstdi_cconly_31"
529   [(set (reg CC_REGNUM)
530         (compare (match_operand:DI 0 "register_operand" "d")
531                  (match_operand:DI 1 "const0_operand" "")))]
532   "s390_match_ccmode(insn, CCSmode) && !TARGET_64BIT"
533   "srda\t%0,0"
534   [(set_attr "op_type" "RS")
535    (set_attr "atype"   "reg")])
536
537 (define_insn "*tst<mode>_cconly2"
538   [(set (reg CC_REGNUM)
539         (compare (match_operand:GPR 0 "register_operand" "d")
540                  (match_operand:GPR 1 "const0_operand" "")))]
541   "s390_match_ccmode(insn, CCSmode)"
542   "lt<g>r\t%0,%0"
543   [(set_attr "op_type" "RR<E>")])
544
545 ; tst(hi|qi) instruction pattern(s).
546
547 (define_insn "*tst<mode>CCT"
548   [(set (reg CC_REGNUM)
549         (compare (match_operand:HQI 0 "nonimmediate_operand" "?Q,?S,d")
550                  (match_operand:HQI 1 "const0_operand" "")))
551    (set (match_operand:HQI 2 "register_operand" "=d,d,0")
552         (match_dup 0))]
553   "s390_match_ccmode(insn, CCTmode)"
554   "@
555    icm\t%2,<icm_lo>,%S0
556    icmy\t%2,<icm_lo>,%S0
557    tml\t%0,<max_uint>"
558   [(set_attr "op_type" "RS,RSY,RI")])
559
560 (define_insn "*tsthiCCT_cconly"
561   [(set (reg CC_REGNUM)
562         (compare (match_operand:HI 0 "nonimmediate_operand" "Q,S,d")
563                  (match_operand:HI 1 "const0_operand" "")))
564    (clobber (match_scratch:HI 2 "=d,d,X"))]
565   "s390_match_ccmode(insn, CCTmode)"
566   "@
567    icm\t%2,3,%S0
568    icmy\t%2,3,%S0
569    tml\t%0,65535"
570   [(set_attr "op_type" "RS,RSY,RI")])
571
572 (define_insn "*tstqiCCT_cconly"
573   [(set (reg CC_REGNUM)
574         (compare (match_operand:QI 0 "nonimmediate_operand" "?Q,?S,d")
575                  (match_operand:QI 1 "const0_operand" "")))]
576   "s390_match_ccmode(insn, CCTmode)"
577   "@
578    cli\t%S0,0
579    cliy\t%S0,0
580    tml\t%0,255"
581   [(set_attr "op_type" "SI,SIY,RI")])
582
583 (define_insn "*tst<mode>"
584   [(set (reg CC_REGNUM)
585         (compare (match_operand:HQI 0 "s_operand" "Q,S")
586                  (match_operand:HQI 1 "const0_operand" "")))
587    (set (match_operand:HQI 2 "register_operand" "=d,d")
588         (match_dup 0))]
589   "s390_match_ccmode(insn, CCSmode)"
590   "@
591    icm\t%2,<icm_lo>,%S0
592    icmy\t%2,<icm_lo>,%S0"
593   [(set_attr "op_type" "RS,RSY")])
594
595 (define_insn "*tst<mode>_cconly"
596   [(set (reg CC_REGNUM)
597         (compare (match_operand:HQI 0 "s_operand" "Q,S")
598                  (match_operand:HQI 1 "const0_operand" "")))
599    (clobber (match_scratch:HQI 2 "=d,d"))]
600   "s390_match_ccmode(insn, CCSmode)"
601   "@
602    icm\t%2,<icm_lo>,%S0
603    icmy\t%2,<icm_lo>,%S0"
604   [(set_attr "op_type" "RS,RSY")])
605
606
607 ; Compare (equality) instructions
608
609 (define_insn "*cmpdi_cct"
610   [(set (reg CC_REGNUM)
611         (compare (match_operand:DI 0 "nonimmediate_operand" "%d,d,d,d,Q")
612                  (match_operand:DI 1 "general_operand" "d,K,Os,m,BQ")))]
613   "s390_match_ccmode (insn, CCTmode) && TARGET_64BIT"
614   "@
615    cgr\t%0,%1
616    cghi\t%0,%h1
617    cgfi\t%0,%1
618    cg\t%0,%1
619    #"
620   [(set_attr "op_type" "RRE,RI,RIL,RXY,SS")])
621
622 (define_insn "*cmpsi_cct"
623   [(set (reg CC_REGNUM)
624         (compare (match_operand:SI 0 "nonimmediate_operand" "%d,d,d,d,d,Q")
625                  (match_operand:SI 1 "general_operand" "d,K,Os,R,T,BQ")))]
626   "s390_match_ccmode (insn, CCTmode)"
627   "@
628    cr\t%0,%1
629    chi\t%0,%h1
630    cfi\t%0,%1
631    c\t%0,%1
632    cy\t%0,%1
633    #"
634   [(set_attr "op_type" "RR,RI,RIL,RX,RXY,SS")])
635
636
637 ; Compare (signed) instructions
638
639 (define_insn "*cmpdi_ccs_sign"
640   [(set (reg CC_REGNUM)
641         (compare (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "d,m"))
642                  (match_operand:DI 0 "register_operand" "d,d")))]
643   "s390_match_ccmode(insn, CCSRmode) && TARGET_64BIT"
644   "@
645    cgfr\t%0,%1
646    cgf\t%0,%1"
647   [(set_attr "op_type" "RRE,RXY")])
648
649 (define_insn "*cmpsi_ccs_sign"
650   [(set (reg CC_REGNUM)
651         (compare (sign_extend:SI (match_operand:HI 1 "memory_operand" "R,T"))
652                  (match_operand:SI 0 "register_operand" "d,d")))]
653   "s390_match_ccmode(insn, CCSRmode)"
654   "@
655    ch\t%0,%1
656    chy\t%0,%1"
657   [(set_attr "op_type" "RX,RXY")])
658
659 (define_insn "*cmp<mode>_ccs"
660   [(set (reg CC_REGNUM)
661         (compare (match_operand:GPR 0 "register_operand" "d,d,d,d,d")
662                  (match_operand:GPR 1 "general_operand" "d,K,Os,R,T")))]
663   "s390_match_ccmode(insn, CCSmode)"
664   "@
665    c<g>r\t%0,%1
666    c<g>hi\t%0,%h1
667    c<g>fi\t%0,%1
668    c<g>\t%0,%1
669    c<y>\t%0,%1"
670   [(set_attr "op_type" "RR<E>,RI,RIL,RX<Y>,RXY")])
671
672
673 ; Compare (unsigned) instructions
674
675 (define_insn "*cmpdi_ccu_zero"
676   [(set (reg CC_REGNUM)
677         (compare (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "d,m"))
678                  (match_operand:DI 0 "register_operand" "d,d")))]
679   "s390_match_ccmode (insn, CCURmode) && TARGET_64BIT"
680   "@
681    clgfr\t%0,%1
682    clgf\t%0,%1"
683   [(set_attr "op_type" "RRE,RXY")])
684
685 (define_insn "*cmpdi_ccu"
686   [(set (reg CC_REGNUM)
687         (compare (match_operand:DI 0 "nonimmediate_operand" "d,d,d,Q,BQ")
688                  (match_operand:DI 1 "general_operand" "d,Op,m,BQ,Q")))]
689   "s390_match_ccmode (insn, CCUmode) && TARGET_64BIT"
690   "@
691    clgr\t%0,%1
692    clgfi\t%0,%1
693    clg\t%0,%1
694    #
695    #"
696   [(set_attr "op_type" "RRE,RIL,RXY,SS,SS")])
697
698 (define_insn "*cmpsi_ccu"
699   [(set (reg CC_REGNUM)
700         (compare (match_operand:SI 0 "nonimmediate_operand" "d,d,d,d,Q,BQ")
701                  (match_operand:SI 1 "general_operand" "d,Os,R,T,BQ,Q")))]
702   "s390_match_ccmode (insn, CCUmode)"
703   "@
704    clr\t%0,%1
705    clfi\t%0,%o1
706    cl\t%0,%1
707    cly\t%0,%1
708    #
709    #"
710   [(set_attr "op_type" "RR,RIL,RX,RXY,SS,SS")])
711
712 (define_insn "*cmphi_ccu"
713   [(set (reg CC_REGNUM)
714         (compare (match_operand:HI 0 "nonimmediate_operand" "d,d,Q,BQ")
715                  (match_operand:HI 1 "general_operand" "Q,S,BQ,Q")))]
716   "s390_match_ccmode (insn, CCUmode)
717    && !register_operand (operands[1], HImode)"
718   "@
719    clm\t%0,3,%S1
720    clmy\t%0,3,%S1
721    #
722    #"
723   [(set_attr "op_type" "RS,RSY,SS,SS")])
724
725 (define_insn "*cmpqi_ccu"
726   [(set (reg CC_REGNUM)
727         (compare (match_operand:QI 0 "nonimmediate_operand" "d,d,Q,S,Q,BQ")
728                  (match_operand:QI 1 "general_operand" "Q,S,n,n,BQ,Q")))]
729   "s390_match_ccmode (insn, CCUmode)
730    && !register_operand (operands[1], QImode)"
731   "@
732    clm\t%0,1,%S1
733    clmy\t%0,1,%S1
734    cli\t%S0,%b1
735    cliy\t%S0,%b1
736    #
737    #"
738   [(set_attr "op_type" "RS,RSY,SI,SIY,SS,SS")])
739
740
741 ; Block compare (CLC) instruction patterns.
742
743 (define_insn "*clc"
744   [(set (reg CC_REGNUM)
745         (compare (match_operand:BLK 0 "memory_operand" "Q")
746                  (match_operand:BLK 1 "memory_operand" "Q")))
747    (use (match_operand 2 "const_int_operand" "n"))]
748   "s390_match_ccmode (insn, CCUmode)
749    && INTVAL (operands[2]) >= 1 && INTVAL (operands[2]) <= 256"
750   "clc\t%O0(%2,%R0),%S1"
751   [(set_attr "op_type" "SS")])
752
753 (define_split
754   [(set (reg CC_REGNUM)
755         (compare (match_operand 0 "memory_operand" "")
756                  (match_operand 1 "memory_operand" "")))]
757   "reload_completed
758    && s390_match_ccmode (insn, CCUmode)
759    && GET_MODE (operands[0]) == GET_MODE (operands[1])
760    && GET_MODE_SIZE (GET_MODE (operands[0])) > 0"
761   [(parallel
762     [(set (match_dup 0) (match_dup 1))
763      (use (match_dup 2))])]
764 {
765   operands[2] = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[0])));
766   operands[0] = adjust_address (operands[0], BLKmode, 0);
767   operands[1] = adjust_address (operands[1], BLKmode, 0);
768
769   operands[1] = gen_rtx_COMPARE (GET_MODE (SET_DEST (PATTERN (curr_insn))),
770                                  operands[0], operands[1]);
771   operands[0] = SET_DEST (PATTERN (curr_insn));
772 })
773
774
775 ; (DF|SF) instructions
776
777 (define_insn "*cmp<mode>_ccs_0"
778   [(set (reg CC_REGNUM)
779         (compare (match_operand:FPR 0 "register_operand" "f")
780                  (match_operand:FPR 1 "const0_operand" "")))]
781   "s390_match_ccmode(insn, CCSmode) && TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT"
782   "lt<xde>br\t%0,%0"
783    [(set_attr "op_type" "RRE")
784     (set_attr "type"  "fsimp<mode>")])
785
786 (define_insn "*cmp<mode>_ccs_0_ibm"
787   [(set (reg CC_REGNUM)
788         (compare (match_operand:FPR 0 "register_operand" "f")
789                  (match_operand:FPR 1 "const0_operand" "")))]
790   "s390_match_ccmode(insn, CCSmode) && TARGET_HARD_FLOAT && TARGET_IBM_FLOAT"
791   "lt<xde>r\t%0,%0"
792    [(set_attr "op_type" "<RRe>")
793     (set_attr "type"  "fsimp<mode>")])
794
795 (define_insn "*cmp<mode>_ccs"
796   [(set (reg CC_REGNUM)
797         (compare (match_operand:FPR 0 "register_operand" "f,f")
798                  (match_operand:FPR 1 "general_operand" "f,<Rf>")))]
799   "s390_match_ccmode(insn, CCSmode) && TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT"
800   "@
801    c<xde>br\t%0,%1
802    c<xde>b\t%0,%1"
803    [(set_attr "op_type" "RRE,RXE")
804     (set_attr "type"  "fsimp<mode>")])
805
806 (define_insn "*cmp<mode>_ccs_ibm"
807   [(set (reg CC_REGNUM)
808         (compare (match_operand:FPR 0 "register_operand" "f,f")
809                  (match_operand:FPR 1 "general_operand" "f,<Rf>")))]
810   "s390_match_ccmode(insn, CCSmode) && TARGET_HARD_FLOAT && TARGET_IBM_FLOAT"
811   "@
812    c<xde>r\t%0,%1
813    c<xde>\t%0,%1"
814    [(set_attr "op_type" "<RRe>,<RXe>")
815     (set_attr "type"  "fsimp<mode>")])
816
817
818 ;;
819 ;;- Move instructions.
820 ;;
821
822 ;
823 ; movti instruction pattern(s).
824 ;
825
826 (define_insn "movti"
827   [(set (match_operand:TI 0 "nonimmediate_operand" "=d,QS,d,o,Q")
828         (match_operand:TI 1 "general_operand" "QS,d,dPm,d,Q"))]
829   "TARGET_64BIT"
830   "@
831    lmg\t%0,%N0,%S1
832    stmg\t%1,%N1,%S0
833    #
834    #
835    #"
836   [(set_attr "op_type" "RSY,RSY,*,*,SS")
837    (set_attr "type" "lm,stm,*,*,*")])
838
839 (define_split
840   [(set (match_operand:TI 0 "nonimmediate_operand" "")
841         (match_operand:TI 1 "general_operand" ""))]
842   "TARGET_64BIT && reload_completed
843    && s390_split_ok_p (operands[0], operands[1], TImode, 0)"
844   [(set (match_dup 2) (match_dup 4))
845    (set (match_dup 3) (match_dup 5))]
846 {
847   operands[2] = operand_subword (operands[0], 0, 0, TImode);
848   operands[3] = operand_subword (operands[0], 1, 0, TImode);
849   operands[4] = operand_subword (operands[1], 0, 0, TImode);
850   operands[5] = operand_subword (operands[1], 1, 0, TImode);
851 })
852
853 (define_split
854   [(set (match_operand:TI 0 "nonimmediate_operand" "")
855         (match_operand:TI 1 "general_operand" ""))]
856   "TARGET_64BIT && reload_completed
857    && s390_split_ok_p (operands[0], operands[1], TImode, 1)"
858   [(set (match_dup 2) (match_dup 4))
859    (set (match_dup 3) (match_dup 5))]
860 {
861   operands[2] = operand_subword (operands[0], 1, 0, TImode);
862   operands[3] = operand_subword (operands[0], 0, 0, TImode);
863   operands[4] = operand_subword (operands[1], 1, 0, TImode);
864   operands[5] = operand_subword (operands[1], 0, 0, TImode);
865 })
866
867 (define_split
868   [(set (match_operand:TI 0 "register_operand" "")
869         (match_operand:TI 1 "memory_operand" ""))]
870   "TARGET_64BIT && reload_completed
871    && !s_operand (operands[1], VOIDmode)"
872   [(set (match_dup 0) (match_dup 1))]
873 {
874   rtx addr = operand_subword (operands[0], 1, 0, TImode);
875   s390_load_address (addr, XEXP (operands[1], 0));
876   operands[1] = replace_equiv_address (operands[1], addr);
877 })
878
879 (define_expand "reload_outti"
880   [(parallel [(match_operand:TI 0 "" "")
881               (match_operand:TI 1 "register_operand" "d")
882               (match_operand:DI 2 "register_operand" "=&a")])]
883   "TARGET_64BIT"
884 {
885   gcc_assert (MEM_P (operands[0]));
886   s390_load_address (operands[2], find_replacement (&XEXP (operands[0], 0)));
887   operands[0] = replace_equiv_address (operands[0], operands[2]);
888   emit_move_insn (operands[0], operands[1]);
889   DONE;
890 })
891
892 ;
893 ; movdi instruction pattern(s).
894 ;
895
896 (define_expand "movdi"
897   [(set (match_operand:DI 0 "general_operand" "")
898         (match_operand:DI 1 "general_operand" ""))]
899   ""
900 {
901   /* Handle symbolic constants.  */
902   if (TARGET_64BIT && SYMBOLIC_CONST (operands[1]))
903     emit_symbolic_move (operands);
904 })
905
906 (define_insn "*movdi_larl"
907   [(set (match_operand:DI 0 "register_operand" "=d")
908         (match_operand:DI 1 "larl_operand" "X"))]
909   "TARGET_64BIT
910    && !FP_REG_P (operands[0])"
911   "larl\t%0,%1"
912    [(set_attr "op_type" "RIL")
913     (set_attr "type"    "larl")])
914
915 (define_insn "*movdi_64extimm"
916   [(set (match_operand:DI 0 "nonimmediate_operand"
917                             "=d,d,d,d,d,d,d,d,d,d,d,m,!*f,!*f,!*f,!R,!T,d,t,Q,t,?Q")
918         (match_operand:DI 1 "general_operand"
919                             "K,N0HD0,N1HD0,N2HD0,N3HD0,Os,N0SD0,N1SD0,L,d,m,d,*f,R,T,*f,*f,t,d,t,Q,?Q"))]
920   "TARGET_64BIT && TARGET_EXTIMM"
921   "@
922    lghi\t%0,%h1
923    llihh\t%0,%i1
924    llihl\t%0,%i1
925    llilh\t%0,%i1
926    llill\t%0,%i1
927    lgfi\t%0,%1
928    llihf\t%0,%k1
929    llilf\t%0,%k1
930    lay\t%0,%a1
931    lgr\t%0,%1
932    lg\t%0,%1
933    stg\t%1,%0
934    ldr\t%0,%1
935    ld\t%0,%1
936    ldy\t%0,%1
937    std\t%1,%0
938    stdy\t%1,%0
939    #
940    #
941    stam\t%1,%N1,%S0
942    lam\t%0,%N0,%S1
943    #"
944   [(set_attr "op_type" "RI,RI,RI,RI,RI,RIL,RIL,RIL,RXY,RRE,RXY,RXY,
945                         RR,RX,RXY,RX,RXY,*,*,RS,RS,SS")
946    (set_attr "type" "*,*,*,*,*,*,*,*,la,lr,load,store,
947                      floaddf,floaddf,floaddf,fstoredf,fstoredf,*,*,*,*,*")])
948
949 (define_insn "*movdi_64"
950   [(set (match_operand:DI 0 "nonimmediate_operand"
951                             "=d,d,d,d,d,d,d,d,m,!*f,!*f,!*f,!R,!T,d,t,Q,t,?Q")
952         (match_operand:DI 1 "general_operand"
953                             "K,N0HD0,N1HD0,N2HD0,N3HD0,L,d,m,d,*f,R,T,*f,*f,t,d,t,Q,?Q"))]
954   "TARGET_64BIT && !TARGET_EXTIMM"
955   "@
956    lghi\t%0,%h1
957    llihh\t%0,%i1
958    llihl\t%0,%i1
959    llilh\t%0,%i1
960    llill\t%0,%i1
961    lay\t%0,%a1
962    lgr\t%0,%1
963    lg\t%0,%1
964    stg\t%1,%0
965    ldr\t%0,%1
966    ld\t%0,%1
967    ldy\t%0,%1
968    std\t%1,%0
969    stdy\t%1,%0
970    #
971    #
972    stam\t%1,%N1,%S0
973    lam\t%0,%N0,%S1
974    #"
975   [(set_attr "op_type" "RI,RI,RI,RI,RI,RXY,RRE,RXY,RXY,
976                         RR,RX,RXY,RX,RXY,*,*,RS,RS,SS")
977    (set_attr "type" "*,*,*,*,*,la,lr,load,store,
978                      floaddf,floaddf,floaddf,fstoredf,fstoredf,*,*,*,*,*")])
979
980 (define_split
981   [(set (match_operand:DI 0 "register_operand" "")
982         (match_operand:DI 1 "register_operand" ""))]
983   "TARGET_64BIT && ACCESS_REG_P (operands[1])"
984   [(set (match_dup 2) (match_dup 3))
985    (set (match_dup 0) (ashift:DI (match_dup 0) (const_int 32)))
986    (set (strict_low_part (match_dup 2)) (match_dup 4))]
987   "operands[2] = gen_lowpart (SImode, operands[0]);
988    s390_split_access_reg (operands[1], &operands[4], &operands[3]);")
989
990 (define_split
991   [(set (match_operand:DI 0 "register_operand" "")
992         (match_operand:DI 1 "register_operand" ""))]
993   "TARGET_64BIT && ACCESS_REG_P (operands[0])
994    && dead_or_set_p (insn, operands[1])"
995   [(set (match_dup 3) (match_dup 2))
996    (set (match_dup 1) (lshiftrt:DI (match_dup 1) (const_int 32)))
997    (set (match_dup 4) (match_dup 2))]
998   "operands[2] = gen_lowpart (SImode, operands[1]);
999    s390_split_access_reg (operands[0], &operands[3], &operands[4]);")
1000
1001 (define_split
1002   [(set (match_operand:DI 0 "register_operand" "")
1003         (match_operand:DI 1 "register_operand" ""))]
1004   "TARGET_64BIT && ACCESS_REG_P (operands[0])
1005    && !dead_or_set_p (insn, operands[1])"
1006   [(set (match_dup 3) (match_dup 2))
1007    (set (match_dup 1) (rotate:DI (match_dup 1) (const_int 32)))
1008    (set (match_dup 4) (match_dup 2))
1009    (set (match_dup 1) (rotate:DI (match_dup 1) (const_int 32)))]
1010   "operands[2] = gen_lowpart (SImode, operands[1]);
1011    s390_split_access_reg (operands[0], &operands[3], &operands[4]);")
1012
1013 (define_insn "*movdi_31"
1014   [(set (match_operand:DI 0 "nonimmediate_operand" "=d,d,Q,S,d,o,!*f,!*f,!*f,!R,!T,Q")
1015         (match_operand:DI 1 "general_operand" "Q,S,d,d,dPm,d,*f,R,T,*f,*f,Q"))]
1016   "!TARGET_64BIT"
1017   "@
1018    lm\t%0,%N0,%S1
1019    lmy\t%0,%N0,%S1
1020    stm\t%1,%N1,%S0
1021    stmy\t%1,%N1,%S0
1022    #
1023    #
1024    ldr\t%0,%1
1025    ld\t%0,%1
1026    ldy\t%0,%1
1027    std\t%1,%0
1028    stdy\t%1,%0
1029    #"
1030   [(set_attr "op_type" "RS,RSY,RS,RSY,*,*,RR,RX,RXY,RX,RXY,SS")
1031    (set_attr "type" "lm,lm,stm,stm,*,*,floaddf,floaddf,floaddf,fstoredf,fstoredf,*")])
1032
1033 (define_split
1034   [(set (match_operand:DI 0 "nonimmediate_operand" "")
1035         (match_operand:DI 1 "general_operand" ""))]
1036   "!TARGET_64BIT && reload_completed
1037    && s390_split_ok_p (operands[0], operands[1], DImode, 0)"
1038   [(set (match_dup 2) (match_dup 4))
1039    (set (match_dup 3) (match_dup 5))]
1040 {
1041   operands[2] = operand_subword (operands[0], 0, 0, DImode);
1042   operands[3] = operand_subword (operands[0], 1, 0, DImode);
1043   operands[4] = operand_subword (operands[1], 0, 0, DImode);
1044   operands[5] = operand_subword (operands[1], 1, 0, DImode);
1045 })
1046
1047 (define_split
1048   [(set (match_operand:DI 0 "nonimmediate_operand" "")
1049         (match_operand:DI 1 "general_operand" ""))]
1050   "!TARGET_64BIT && reload_completed
1051    && s390_split_ok_p (operands[0], operands[1], DImode, 1)"
1052   [(set (match_dup 2) (match_dup 4))
1053    (set (match_dup 3) (match_dup 5))]
1054 {
1055   operands[2] = operand_subword (operands[0], 1, 0, DImode);
1056   operands[3] = operand_subword (operands[0], 0, 0, DImode);
1057   operands[4] = operand_subword (operands[1], 1, 0, DImode);
1058   operands[5] = operand_subword (operands[1], 0, 0, DImode);
1059 })
1060
1061 (define_split
1062   [(set (match_operand:DI 0 "register_operand" "")
1063         (match_operand:DI 1 "memory_operand" ""))]
1064   "!TARGET_64BIT && reload_completed
1065    && !FP_REG_P (operands[0])
1066    && !s_operand (operands[1], VOIDmode)"
1067   [(set (match_dup 0) (match_dup 1))]
1068 {
1069   rtx addr = operand_subword (operands[0], 1, 0, DImode);
1070   s390_load_address (addr, XEXP (operands[1], 0));
1071   operands[1] = replace_equiv_address (operands[1], addr);
1072 })
1073
1074 (define_expand "reload_outdi"
1075   [(parallel [(match_operand:DI 0 "" "")
1076               (match_operand:DI 1 "register_operand" "d")
1077               (match_operand:SI 2 "register_operand" "=&a")])]
1078   "!TARGET_64BIT"
1079 {
1080   gcc_assert (MEM_P (operands[0]));
1081   s390_load_address (operands[2], find_replacement (&XEXP (operands[0], 0)));
1082   operands[0] = replace_equiv_address (operands[0], operands[2]);
1083   emit_move_insn (operands[0], operands[1]);
1084   DONE;
1085 })
1086
1087 (define_peephole2
1088   [(set (match_operand:DI 0 "register_operand" "")
1089         (mem:DI (match_operand 1 "address_operand" "")))]
1090   "TARGET_64BIT
1091    && !FP_REG_P (operands[0])
1092    && GET_CODE (operands[1]) == SYMBOL_REF
1093    && CONSTANT_POOL_ADDRESS_P (operands[1])
1094    && get_pool_mode (operands[1]) == DImode
1095    && legitimate_reload_constant_p (get_pool_constant (operands[1]))"
1096   [(set (match_dup 0) (match_dup 2))]
1097   "operands[2] = get_pool_constant (operands[1]);")
1098
1099 (define_insn "*la_64"
1100   [(set (match_operand:DI 0 "register_operand" "=d,d")
1101         (match_operand:QI 1 "address_operand" "U,W"))]
1102   "TARGET_64BIT"
1103   "@
1104    la\t%0,%a1
1105    lay\t%0,%a1"
1106   [(set_attr "op_type" "RX,RXY")
1107    (set_attr "type"    "la")])
1108
1109 (define_peephole2
1110   [(parallel
1111     [(set (match_operand:DI 0 "register_operand" "")
1112           (match_operand:QI 1 "address_operand" ""))
1113      (clobber (reg:CC CC_REGNUM))])]
1114   "TARGET_64BIT
1115    && preferred_la_operand_p (operands[1], const0_rtx)"
1116   [(set (match_dup 0) (match_dup 1))]
1117   "")
1118
1119 (define_peephole2
1120   [(set (match_operand:DI 0 "register_operand" "")
1121         (match_operand:DI 1 "register_operand" ""))
1122    (parallel
1123     [(set (match_dup 0)
1124           (plus:DI (match_dup 0)
1125                    (match_operand:DI 2 "nonmemory_operand" "")))
1126      (clobber (reg:CC CC_REGNUM))])]
1127   "TARGET_64BIT
1128    && !reg_overlap_mentioned_p (operands[0], operands[2])
1129    && preferred_la_operand_p (operands[1], operands[2])"
1130   [(set (match_dup 0) (plus:DI (match_dup 1) (match_dup 2)))]
1131   "")
1132
1133 (define_expand "reload_indi"
1134   [(parallel [(match_operand:DI 0 "register_operand" "=a")
1135               (match_operand:DI 1 "s390_plus_operand" "")
1136               (match_operand:DI 2 "register_operand" "=&a")])]
1137   "TARGET_64BIT"
1138 {
1139   s390_expand_plus_operand (operands[0], operands[1], operands[2]);
1140   DONE;
1141 })
1142
1143 ;
1144 ; movsi instruction pattern(s).
1145 ;
1146
1147 (define_expand "movsi"
1148   [(set (match_operand:SI 0 "general_operand" "")
1149         (match_operand:SI 1 "general_operand" ""))]
1150   ""
1151 {
1152   /* Handle symbolic constants.  */
1153   if (!TARGET_64BIT && SYMBOLIC_CONST (operands[1]))
1154     emit_symbolic_move (operands);
1155 })
1156
1157 (define_insn "*movsi_larl"
1158   [(set (match_operand:SI 0 "register_operand" "=d")
1159         (match_operand:SI 1 "larl_operand" "X"))]
1160   "!TARGET_64BIT && TARGET_CPU_ZARCH
1161    && !FP_REG_P (operands[0])"
1162   "larl\t%0,%1"
1163    [(set_attr "op_type" "RIL")
1164     (set_attr "type"    "larl")])
1165
1166 (define_insn "*movsi_zarch"
1167   [(set (match_operand:SI 0 "nonimmediate_operand"
1168                             "=d,d,d,d,d,d,d,d,R,T,!*f,!*f,!*f,!R,!T,d,t,Q,t,?Q")
1169         (match_operand:SI 1 "general_operand"
1170                             "K,N0HS0,N1HS0,Os,L,d,R,T,d,d,*f,R,T,*f,*f,t,d,t,Q,?Q"))]
1171   "TARGET_ZARCH"
1172   "@
1173    lhi\t%0,%h1
1174    llilh\t%0,%i1
1175    llill\t%0,%i1
1176    iilf\t%0,%o1
1177    lay\t%0,%a1
1178    lr\t%0,%1
1179    l\t%0,%1
1180    ly\t%0,%1
1181    st\t%1,%0
1182    sty\t%1,%0
1183    ler\t%0,%1
1184    le\t%0,%1
1185    ley\t%0,%1
1186    ste\t%1,%0
1187    stey\t%1,%0
1188    ear\t%0,%1
1189    sar\t%0,%1
1190    stam\t%1,%1,%S0
1191    lam\t%0,%0,%S1
1192    #"
1193   [(set_attr "op_type" "RI,RI,RI,RIL,RXY,RR,RX,RXY,RX,RXY,
1194                         RR,RX,RXY,RX,RXY,RRE,RRE,RS,RS,SS")
1195    (set_attr "type" "*,*,*,*,la,lr,load,load,store,store,
1196                      floadsf,floadsf,floadsf,fstoresf,fstoresf,*,*,*,*,*")])
1197
1198 (define_insn "*movsi_esa"
1199   [(set (match_operand:SI 0 "nonimmediate_operand" "=d,d,d,R,!*f,!*f,!R,d,t,Q,t,?Q")
1200         (match_operand:SI 1 "general_operand" "K,d,R,d,*f,R,*f,t,d,t,Q,?Q"))]
1201   "!TARGET_ZARCH"
1202   "@
1203    lhi\t%0,%h1
1204    lr\t%0,%1
1205    l\t%0,%1
1206    st\t%1,%0
1207    ler\t%0,%1
1208    le\t%0,%1
1209    ste\t%1,%0
1210    ear\t%0,%1
1211    sar\t%0,%1
1212    stam\t%1,%1,%S0
1213    lam\t%0,%0,%S1
1214    #"
1215   [(set_attr "op_type" "RI,RR,RX,RX,RR,RX,RX,RRE,RRE,RS,RS,SS")
1216    (set_attr "type" "*,lr,load,store,floadsf,floadsf,fstoresf,*,*,*,*,*")])
1217
1218 (define_peephole2
1219   [(set (match_operand:SI 0 "register_operand" "")
1220         (mem:SI (match_operand 1 "address_operand" "")))]
1221   "!FP_REG_P (operands[0])
1222    && GET_CODE (operands[1]) == SYMBOL_REF
1223    && CONSTANT_POOL_ADDRESS_P (operands[1])
1224    && get_pool_mode (operands[1]) == SImode
1225    && legitimate_reload_constant_p (get_pool_constant (operands[1]))"
1226   [(set (match_dup 0) (match_dup 2))]
1227   "operands[2] = get_pool_constant (operands[1]);")
1228
1229 (define_insn "*la_31"
1230   [(set (match_operand:SI 0 "register_operand" "=d,d")
1231         (match_operand:QI 1 "address_operand" "U,W"))]
1232   "!TARGET_64BIT && legitimate_la_operand_p (operands[1])"
1233   "@
1234    la\t%0,%a1
1235    lay\t%0,%a1"
1236   [(set_attr "op_type"  "RX,RXY")
1237    (set_attr "type"     "la")])
1238
1239 (define_peephole2
1240   [(parallel
1241     [(set (match_operand:SI 0 "register_operand" "")
1242           (match_operand:QI 1 "address_operand" ""))
1243      (clobber (reg:CC CC_REGNUM))])]
1244   "!TARGET_64BIT
1245    && preferred_la_operand_p (operands[1], const0_rtx)"
1246   [(set (match_dup 0) (match_dup 1))]
1247   "")
1248
1249 (define_peephole2
1250   [(set (match_operand:SI 0 "register_operand" "")
1251         (match_operand:SI 1 "register_operand" ""))
1252    (parallel
1253     [(set (match_dup 0)
1254           (plus:SI (match_dup 0)
1255                    (match_operand:SI 2 "nonmemory_operand" "")))
1256      (clobber (reg:CC CC_REGNUM))])]
1257   "!TARGET_64BIT
1258    && !reg_overlap_mentioned_p (operands[0], operands[2])
1259    && preferred_la_operand_p (operands[1], operands[2])"
1260   [(set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))]
1261   "")
1262
1263 (define_insn "*la_31_and"
1264   [(set (match_operand:SI 0 "register_operand" "=d,d")
1265         (and:SI (match_operand:QI 1 "address_operand" "U,W")
1266                 (const_int 2147483647)))]
1267   "!TARGET_64BIT"
1268   "@
1269    la\t%0,%a1
1270    lay\t%0,%a1"
1271   [(set_attr "op_type"  "RX,RXY")
1272    (set_attr "type"     "la")])
1273
1274 (define_insn_and_split "*la_31_and_cc"
1275   [(set (match_operand:SI 0 "register_operand" "=d")
1276         (and:SI (match_operand:QI 1 "address_operand" "p")
1277                 (const_int 2147483647)))
1278    (clobber (reg:CC CC_REGNUM))]
1279   "!TARGET_64BIT"
1280   "#"
1281   "&& reload_completed"
1282   [(set (match_dup 0)
1283         (and:SI (match_dup 1) (const_int 2147483647)))]
1284   ""
1285   [(set_attr "op_type"  "RX")
1286    (set_attr "type"     "la")])
1287
1288 (define_insn "force_la_31"
1289   [(set (match_operand:SI 0 "register_operand" "=d,d")
1290         (match_operand:QI 1 "address_operand" "U,W"))
1291    (use (const_int 0))]
1292   "!TARGET_64BIT"
1293   "@
1294    la\t%0,%a1
1295    lay\t%0,%a1"
1296   [(set_attr "op_type"  "RX")
1297    (set_attr "type"     "la")])
1298
1299 (define_expand "reload_insi"
1300   [(parallel [(match_operand:SI 0 "register_operand" "=a")
1301               (match_operand:SI 1 "s390_plus_operand" "")
1302               (match_operand:SI 2 "register_operand" "=&a")])]
1303   "!TARGET_64BIT"
1304 {
1305   s390_expand_plus_operand (operands[0], operands[1], operands[2]);
1306   DONE;
1307 })
1308
1309 ;
1310 ; movhi instruction pattern(s).
1311 ;
1312
1313 (define_expand "movhi"
1314   [(set (match_operand:HI 0 "nonimmediate_operand" "")
1315         (match_operand:HI 1 "general_operand" ""))]
1316   ""
1317 {
1318   /* Make it explicit that loading a register from memory
1319      always sign-extends (at least) to SImode.  */
1320   if (optimize && !no_new_pseudos
1321       && register_operand (operands[0], VOIDmode)
1322       && GET_CODE (operands[1]) == MEM)
1323     {
1324       rtx tmp = gen_reg_rtx (SImode);
1325       rtx ext = gen_rtx_SIGN_EXTEND (SImode, operands[1]);
1326       emit_insn (gen_rtx_SET (VOIDmode, tmp, ext));
1327       operands[1] = gen_lowpart (HImode, tmp);
1328     }
1329 })
1330
1331 (define_insn "*movhi"
1332   [(set (match_operand:HI 0 "nonimmediate_operand" "=d,d,d,d,R,T,?Q")
1333         (match_operand:HI 1 "general_operand" "d,n,R,T,d,d,?Q"))]
1334   ""
1335   "@
1336    lr\t%0,%1
1337    lhi\t%0,%h1
1338    lh\t%0,%1
1339    lhy\t%0,%1
1340    sth\t%1,%0
1341    sthy\t%1,%0
1342    #"
1343   [(set_attr "op_type" "RR,RI,RX,RXY,RX,RXY,SS")
1344    (set_attr "type" "lr,*,*,*,store,store,*")])
1345
1346 (define_peephole2
1347   [(set (match_operand:HI 0 "register_operand" "")
1348         (mem:HI (match_operand 1 "address_operand" "")))]
1349   "GET_CODE (operands[1]) == SYMBOL_REF
1350    && CONSTANT_POOL_ADDRESS_P (operands[1])
1351    && get_pool_mode (operands[1]) == HImode
1352    && GET_CODE (get_pool_constant (operands[1])) == CONST_INT"
1353   [(set (match_dup 0) (match_dup 2))]
1354   "operands[2] = get_pool_constant (operands[1]);")
1355
1356 ;
1357 ; movqi instruction pattern(s).
1358 ;
1359
1360 (define_expand "movqi"
1361   [(set (match_operand:QI 0 "nonimmediate_operand" "")
1362         (match_operand:QI 1 "general_operand" ""))]
1363   ""
1364 {
1365   /* On z/Architecture, zero-extending from memory to register
1366      is just as fast as a QImode load.  */
1367   if (TARGET_ZARCH && optimize && !no_new_pseudos
1368       && register_operand (operands[0], VOIDmode)
1369       && GET_CODE (operands[1]) == MEM)
1370     {
1371       rtx tmp = gen_reg_rtx (word_mode);
1372       rtx ext = gen_rtx_ZERO_EXTEND (word_mode, operands[1]);
1373       emit_insn (gen_rtx_SET (VOIDmode, tmp, ext));
1374       operands[1] = gen_lowpart (QImode, tmp);
1375     }
1376 })
1377
1378 (define_insn "*movqi"
1379   [(set (match_operand:QI 0 "nonimmediate_operand" "=d,d,d,d,R,T,Q,S,?Q")
1380         (match_operand:QI 1 "general_operand" "d,n,R,T,d,d,n,n,?Q"))]
1381   ""
1382   "@
1383    lr\t%0,%1
1384    lhi\t%0,%b1
1385    ic\t%0,%1
1386    icy\t%0,%1
1387    stc\t%1,%0
1388    stcy\t%1,%0
1389    mvi\t%S0,%b1
1390    mviy\t%S0,%b1
1391    #"
1392   [(set_attr "op_type" "RR,RI,RX,RXY,RX,RXY,SI,SIY,SS")
1393    (set_attr "type" "lr,*,*,*,store,store,store,store,*")])
1394
1395 (define_peephole2
1396   [(set (match_operand:QI 0 "nonimmediate_operand" "")
1397         (mem:QI (match_operand 1 "address_operand" "")))]
1398   "GET_CODE (operands[1]) == SYMBOL_REF
1399    && CONSTANT_POOL_ADDRESS_P (operands[1])
1400    && get_pool_mode (operands[1]) == QImode
1401    && GET_CODE (get_pool_constant (operands[1])) == CONST_INT"
1402   [(set (match_dup 0) (match_dup 2))]
1403   "operands[2] = get_pool_constant (operands[1]);")
1404
1405 ;
1406 ; movstrictqi instruction pattern(s).
1407 ;
1408
1409 (define_insn "*movstrictqi"
1410   [(set (strict_low_part (match_operand:QI 0 "register_operand" "+d,d"))
1411                          (match_operand:QI 1 "memory_operand" "R,T"))]
1412   ""
1413   "@
1414    ic\t%0,%1
1415    icy\t%0,%1"
1416   [(set_attr "op_type"  "RX,RXY")])
1417
1418 ;
1419 ; movstricthi instruction pattern(s).
1420 ;
1421
1422 (define_insn "*movstricthi"
1423   [(set (strict_low_part (match_operand:HI 0 "register_operand" "+d,d"))
1424                          (match_operand:HI 1 "memory_operand" "Q,S"))
1425    (clobber (reg:CC CC_REGNUM))]
1426   ""
1427   "@
1428    icm\t%0,3,%S1
1429    icmy\t%0,3,%S1"
1430   [(set_attr "op_type" "RS,RSY")])
1431
1432 ;
1433 ; movstrictsi instruction pattern(s).
1434 ;
1435
1436 (define_insn "movstrictsi"
1437   [(set (strict_low_part (match_operand:SI 0 "register_operand" "+d,d,d,d"))
1438                          (match_operand:SI 1 "general_operand" "d,R,T,t"))]
1439   "TARGET_64BIT"
1440   "@
1441    lr\t%0,%1
1442    l\t%0,%1
1443    ly\t%0,%1
1444    ear\t%0,%1"
1445   [(set_attr "op_type" "RR,RX,RXY,RRE")
1446    (set_attr "type" "lr,load,load,*")])
1447
1448 ;
1449 ; movtf instruction pattern(s).
1450 ;
1451
1452 (define_expand "movtf"
1453   [(set (match_operand:TF 0 "nonimmediate_operand" "")
1454         (match_operand:TF 1 "general_operand"       ""))]
1455   ""
1456   "")
1457
1458 (define_insn "*movtf_64"
1459   [(set (match_operand:TF 0 "nonimmediate_operand" "=f,f,f,o,d,QS,d,o,Q")
1460         (match_operand:TF 1 "general_operand"       "G,f,o,f,QS,d,dm,d,Q"))]
1461   "TARGET_64BIT"
1462   "@
1463    lzxr\t%0
1464    lxr\t%0,%1
1465    #
1466    #
1467    lmg\t%0,%N0,%S1
1468    stmg\t%1,%N1,%S0
1469    #
1470    #
1471    #"
1472   [(set_attr "op_type" "RRE,RRE,*,*,RSY,RSY,*,*,*")
1473    (set_attr "type"    "fsimptf,fsimptf,*,*,lm,stm,*,*,*")])
1474
1475 (define_insn "*movtf_31"
1476   [(set (match_operand:TF 0 "nonimmediate_operand" "=f,f,f,o,Q")
1477         (match_operand:TF 1 "general_operand"       "G,f,o,f,Q"))]
1478   "!TARGET_64BIT"
1479   "@
1480    lzxr\t%0
1481    lxr\t%0,%1
1482    #
1483    #
1484    #"
1485   [(set_attr "op_type" "RRE,RRE,*,*,*")
1486    (set_attr "type"    "fsimptf,fsimptf,*,*,*")])
1487
1488 ; TFmode in GPRs splitters
1489
1490 (define_split
1491   [(set (match_operand:TF 0 "nonimmediate_operand" "")
1492         (match_operand:TF 1 "general_operand" ""))]
1493   "TARGET_64BIT && reload_completed
1494    && s390_split_ok_p (operands[0], operands[1], TFmode, 0)"
1495   [(set (match_dup 2) (match_dup 4))
1496    (set (match_dup 3) (match_dup 5))]
1497 {
1498   operands[2] = operand_subword (operands[0], 0, 0, TFmode);
1499   operands[3] = operand_subword (operands[0], 1, 0, TFmode);
1500   operands[4] = operand_subword (operands[1], 0, 0, TFmode);
1501   operands[5] = operand_subword (operands[1], 1, 0, TFmode);
1502 })
1503
1504 (define_split
1505   [(set (match_operand:TF 0 "nonimmediate_operand" "")
1506         (match_operand:TF 1 "general_operand" ""))]
1507   "TARGET_64BIT && reload_completed
1508    && s390_split_ok_p (operands[0], operands[1], TFmode, 1)"
1509   [(set (match_dup 2) (match_dup 4))
1510    (set (match_dup 3) (match_dup 5))]
1511 {
1512   operands[2] = operand_subword (operands[0], 1, 0, TFmode);
1513   operands[3] = operand_subword (operands[0], 0, 0, TFmode);
1514   operands[4] = operand_subword (operands[1], 1, 0, TFmode);
1515   operands[5] = operand_subword (operands[1], 0, 0, TFmode);
1516 })
1517
1518 (define_split
1519   [(set (match_operand:TF 0 "register_operand" "")
1520         (match_operand:TF 1 "memory_operand" ""))]
1521   "TARGET_64BIT && reload_completed
1522    && !FP_REG_P (operands[0])
1523    && !s_operand (operands[1], VOIDmode)"
1524   [(set (match_dup 0) (match_dup 1))]
1525 {
1526   rtx addr = operand_subword (operands[0], 1, 0, DFmode);
1527   s390_load_address (addr, XEXP (operands[1], 0));
1528   operands[1] = replace_equiv_address (operands[1], addr);
1529 })
1530
1531 ; TFmode in FPRs splitters
1532
1533 (define_split
1534   [(set (match_operand:TF 0 "register_operand" "")
1535         (match_operand:TF 1 "memory_operand" ""))]
1536   "reload_completed && offsettable_memref_p (operands[1]) 
1537    && FP_REG_P (operands[0])"
1538   [(set (match_dup 2) (match_dup 4))
1539    (set (match_dup 3) (match_dup 5))]
1540 {
1541   operands[2] = simplify_gen_subreg (DFmode, operands[0], TFmode, 0);
1542   operands[3] = simplify_gen_subreg (DFmode, operands[0], TFmode, 8);
1543   operands[4] = adjust_address_nv (operands[1], DFmode, 0);
1544   operands[5] = adjust_address_nv (operands[1], DFmode, 8);
1545 })
1546
1547 (define_split
1548   [(set (match_operand:TF 0 "memory_operand" "")
1549         (match_operand:TF 1 "register_operand" ""))]
1550   "reload_completed && offsettable_memref_p (operands[0])
1551    && FP_REG_P (operands[1])"
1552   [(set (match_dup 2) (match_dup 4))
1553    (set (match_dup 3) (match_dup 5))]
1554 {
1555   operands[2] = adjust_address_nv (operands[0], DFmode, 0);
1556   operands[3] = adjust_address_nv (operands[0], DFmode, 8);
1557   operands[4] = simplify_gen_subreg (DFmode, operands[1], TFmode, 0);
1558   operands[5] = simplify_gen_subreg (DFmode, operands[1], TFmode, 8);
1559 })
1560
1561 (define_expand "reload_outtf"
1562   [(parallel [(match_operand:TF 0 "" "")
1563               (match_operand:TF 1 "register_operand" "f")
1564               (match_operand:SI 2 "register_operand" "=&a")])]
1565   ""
1566 {
1567   rtx addr = gen_lowpart (Pmode, operands[2]);
1568
1569   gcc_assert (MEM_P (operands[0]));
1570   s390_load_address (addr, find_replacement (&XEXP (operands[0], 0)));
1571   operands[0] = replace_equiv_address (operands[0], addr);
1572   emit_move_insn (operands[0], operands[1]);
1573   DONE;
1574 })
1575
1576 (define_expand "reload_intf"
1577   [(parallel [(match_operand:TF 0 "register_operand" "=f")
1578               (match_operand:TF 1 "" "")
1579               (match_operand:SI 2 "register_operand" "=&a")])]
1580   ""
1581 {
1582   rtx addr = gen_lowpart (Pmode, operands[2]);
1583  
1584   gcc_assert (MEM_P (operands[1]));
1585   s390_load_address (addr, find_replacement (&XEXP (operands[1], 0)));
1586   operands[1] = replace_equiv_address (operands[1], addr);
1587   emit_move_insn (operands[0], operands[1]);
1588   DONE;
1589 })
1590
1591 ;
1592 ; movdf instruction pattern(s).
1593 ;
1594
1595 (define_expand "movdf"
1596   [(set (match_operand:DF 0 "nonimmediate_operand" "")
1597         (match_operand:DF 1 "general_operand"  ""))]
1598   ""
1599   "")
1600
1601 (define_insn "*movdf_64"
1602   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,f,f,f,R,T,d,d,m,?Q")
1603         (match_operand:DF 1 "general_operand" "G,f,R,T,f,f,d,m,d,?Q"))]
1604   "TARGET_64BIT"
1605   "@
1606    lzdr\t%0
1607    ldr\t%0,%1
1608    ld\t%0,%1
1609    ldy\t%0,%1
1610    std\t%1,%0
1611    stdy\t%1,%0
1612    lgr\t%0,%1
1613    lg\t%0,%1
1614    stg\t%1,%0
1615    #"
1616   [(set_attr "op_type" "RRE,RR,RX,RXY,RX,RXY,RRE,RXY,RXY,SS")
1617    (set_attr "type" "fsimpdf,floaddf,floaddf,floaddf,fstoredf,fstoredf,lr,load,store,*")])
1618
1619 (define_insn "*movdf_31"
1620   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,f,f,f,R,T,d,d,Q,S,d,o,Q")
1621         (match_operand:DF 1 "general_operand" "G,f,R,T,f,f,Q,S,d,d,dPm,d,Q"))]
1622   "!TARGET_64BIT"
1623   "@
1624    lzdr\t%0
1625    ldr\t%0,%1
1626    ld\t%0,%1
1627    ldy\t%0,%1
1628    std\t%1,%0
1629    stdy\t%1,%0
1630    lm\t%0,%N0,%S1
1631    lmy\t%0,%N0,%S1
1632    stm\t%1,%N1,%S0
1633    stmy\t%1,%N1,%S0
1634    #
1635    #
1636    #"
1637   [(set_attr "op_type" "RRE,RR,RX,RXY,RX,RXY,RS,RSY,RS,RSY,*,*,SS")
1638    (set_attr "type" "fsimpdf,floaddf,floaddf,floaddf,fstoredf,fstoredf,\
1639                      lm,lm,stm,stm,*,*,*")])
1640
1641 (define_split
1642   [(set (match_operand:DF 0 "nonimmediate_operand" "")
1643         (match_operand:DF 1 "general_operand" ""))]
1644   "!TARGET_64BIT && reload_completed
1645    && s390_split_ok_p (operands[0], operands[1], DFmode, 0)"
1646   [(set (match_dup 2) (match_dup 4))
1647    (set (match_dup 3) (match_dup 5))]
1648 {
1649   operands[2] = operand_subword (operands[0], 0, 0, DFmode);
1650   operands[3] = operand_subword (operands[0], 1, 0, DFmode);
1651   operands[4] = operand_subword (operands[1], 0, 0, DFmode);
1652   operands[5] = operand_subword (operands[1], 1, 0, DFmode);
1653 })
1654
1655 (define_split
1656   [(set (match_operand:DF 0 "nonimmediate_operand" "")
1657         (match_operand:DF 1 "general_operand" ""))]
1658   "!TARGET_64BIT && reload_completed
1659    && s390_split_ok_p (operands[0], operands[1], DFmode, 1)"
1660   [(set (match_dup 2) (match_dup 4))
1661    (set (match_dup 3) (match_dup 5))]
1662 {
1663   operands[2] = operand_subword (operands[0], 1, 0, DFmode);
1664   operands[3] = operand_subword (operands[0], 0, 0, DFmode);
1665   operands[4] = operand_subword (operands[1], 1, 0, DFmode);
1666   operands[5] = operand_subword (operands[1], 0, 0, DFmode);
1667 })
1668
1669 (define_split
1670   [(set (match_operand:DF 0 "register_operand" "")
1671         (match_operand:DF 1 "memory_operand" ""))]
1672   "!TARGET_64BIT && reload_completed
1673    && !FP_REG_P (operands[0])
1674    && !s_operand (operands[1], VOIDmode)"
1675   [(set (match_dup 0) (match_dup 1))]
1676 {
1677   rtx addr = operand_subword (operands[0], 1, 0, DFmode);
1678   s390_load_address (addr, XEXP (operands[1], 0));
1679   operands[1] = replace_equiv_address (operands[1], addr);
1680 })
1681
1682 (define_expand "reload_outdf"
1683   [(parallel [(match_operand:DF 0 "" "")
1684               (match_operand:DF 1 "register_operand" "d")
1685               (match_operand:SI 2 "register_operand" "=&a")])]
1686   "!TARGET_64BIT"
1687 {
1688   gcc_assert (MEM_P (operands[0]));
1689   s390_load_address (operands[2], find_replacement (&XEXP (operands[0], 0)));
1690   operands[0] = replace_equiv_address (operands[0], operands[2]);
1691   emit_move_insn (operands[0], operands[1]);
1692   DONE;
1693 })
1694
1695 ;
1696 ; movsf instruction pattern(s).
1697 ;
1698
1699 (define_insn "movsf"
1700   [(set (match_operand:SF 0 "nonimmediate_operand" "=f,f,f,f,R,T,d,d,d,R,T,?Q")
1701         (match_operand:SF 1 "general_operand" "G,f,R,T,f,f,d,R,T,d,d,?Q"))]
1702   ""
1703   "@
1704    lzer\t%0
1705    ler\t%0,%1
1706    le\t%0,%1
1707    ley\t%0,%1
1708    ste\t%1,%0
1709    stey\t%1,%0
1710    lr\t%0,%1
1711    l\t%0,%1
1712    ly\t%0,%1
1713    st\t%1,%0
1714    sty\t%1,%0
1715    #"
1716   [(set_attr "op_type" "RRE,RR,RX,RXY,RX,RXY,RR,RX,RXY,RX,RXY,SS")
1717    (set_attr "type" "fsimpsf,floadsf,floadsf,floadsf,fstoresf,fstoresf,
1718                      lr,load,load,store,store,*")])
1719
1720 ;
1721 ; movcc instruction pattern
1722 ;
1723
1724 (define_insn "movcc"
1725   [(set (match_operand:CC 0 "nonimmediate_operand" "=d,c,d,d,d,R,T")
1726         (match_operand:CC 1 "nonimmediate_operand" "d,d,c,R,T,d,d"))]
1727   ""
1728   "@
1729    lr\t%0,%1
1730    tmh\t%1,12288
1731    ipm\t%0
1732    st\t%0,%1
1733    sty\t%0,%1
1734    l\t%1,%0
1735    ly\t%1,%0"
1736   [(set_attr "op_type" "RR,RI,RRE,RX,RXY,RX,RXY")
1737    (set_attr "type" "lr,*,*,store,store,load,load")])
1738
1739 ;
1740 ; Block move (MVC) patterns.
1741 ;
1742
1743 (define_insn "*mvc"
1744   [(set (match_operand:BLK 0 "memory_operand" "=Q")
1745         (match_operand:BLK 1 "memory_operand" "Q"))
1746    (use (match_operand 2 "const_int_operand" "n"))]
1747   "INTVAL (operands[2]) >= 1 && INTVAL (operands[2]) <= 256"
1748   "mvc\t%O0(%2,%R0),%S1"
1749   [(set_attr "op_type" "SS")])
1750
1751 (define_split
1752   [(set (match_operand 0 "memory_operand" "")
1753         (match_operand 1 "memory_operand" ""))]
1754   "reload_completed
1755    && GET_MODE (operands[0]) == GET_MODE (operands[1])
1756    && GET_MODE_SIZE (GET_MODE (operands[0])) > 0"
1757   [(parallel
1758     [(set (match_dup 0) (match_dup 1))
1759      (use (match_dup 2))])]
1760 {
1761   operands[2] = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[0])));
1762   operands[0] = adjust_address (operands[0], BLKmode, 0);
1763   operands[1] = adjust_address (operands[1], BLKmode, 0);
1764 })
1765
1766 (define_peephole2
1767   [(parallel
1768     [(set (match_operand:BLK 0 "memory_operand" "")
1769           (match_operand:BLK 1 "memory_operand" ""))
1770      (use (match_operand 2 "const_int_operand" ""))])
1771    (parallel
1772     [(set (match_operand:BLK 3 "memory_operand" "")
1773           (match_operand:BLK 4 "memory_operand" ""))
1774      (use (match_operand 5 "const_int_operand" ""))])]
1775   "s390_offset_p (operands[0], operands[3], operands[2])
1776    && s390_offset_p (operands[1], operands[4], operands[2])
1777    && !s390_overlap_p (operands[0], operands[1], 
1778                        INTVAL (operands[2]) + INTVAL (operands[5]))
1779    && INTVAL (operands[2]) + INTVAL (operands[5]) <= 256"
1780   [(parallel
1781     [(set (match_dup 6) (match_dup 7))
1782      (use (match_dup 8))])]
1783   "operands[6] = gen_rtx_MEM (BLKmode, XEXP (operands[0], 0));
1784    operands[7] = gen_rtx_MEM (BLKmode, XEXP (operands[1], 0));
1785    operands[8] = GEN_INT (INTVAL (operands[2]) + INTVAL (operands[5]));")
1786
1787
1788 ;
1789 ; load_multiple pattern(s).
1790 ;
1791 ; ??? Due to reload problems with replacing registers inside match_parallel
1792 ; we currently support load_multiple/store_multiple only after reload.
1793 ;
1794
1795 (define_expand "load_multiple"
1796   [(match_par_dup 3 [(set (match_operand 0 "" "")
1797                           (match_operand 1 "" ""))
1798                      (use (match_operand 2 "" ""))])]
1799   "reload_completed"
1800 {
1801   enum machine_mode mode;
1802   int regno;
1803   int count;
1804   rtx from;
1805   int i, off;
1806
1807   /* Support only loading a constant number of fixed-point registers from
1808      memory and only bother with this if more than two */
1809   if (GET_CODE (operands[2]) != CONST_INT
1810       || INTVAL (operands[2]) < 2
1811       || INTVAL (operands[2]) > 16
1812       || GET_CODE (operands[1]) != MEM
1813       || GET_CODE (operands[0]) != REG
1814       || REGNO (operands[0]) >= 16)
1815     FAIL;
1816
1817   count = INTVAL (operands[2]);
1818   regno = REGNO (operands[0]);
1819   mode = GET_MODE (operands[0]);
1820   if (mode != SImode && mode != word_mode)
1821     FAIL;
1822
1823   operands[3] = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (count));
1824   if (no_new_pseudos)
1825     {
1826       if (GET_CODE (XEXP (operands[1], 0)) == REG)
1827         {
1828           from = XEXP (operands[1], 0);
1829           off = 0;
1830         }
1831       else if (GET_CODE (XEXP (operands[1], 0)) == PLUS
1832                && GET_CODE (XEXP (XEXP (operands[1], 0), 0)) == REG
1833                && GET_CODE (XEXP (XEXP (operands[1], 0), 1)) == CONST_INT)
1834         {
1835           from = XEXP (XEXP (operands[1], 0), 0);
1836           off = INTVAL (XEXP (XEXP (operands[1], 0), 1));
1837         }
1838       else
1839         FAIL;
1840     }
1841   else
1842     {
1843       from = force_reg (Pmode, XEXP (operands[1], 0));
1844       off = 0;
1845     }
1846
1847   for (i = 0; i < count; i++)
1848     XVECEXP (operands[3], 0, i)
1849       = gen_rtx_SET (VOIDmode, gen_rtx_REG (mode, regno + i),
1850                      change_address (operands[1], mode,
1851                        plus_constant (from, off + i * GET_MODE_SIZE (mode))));
1852 })
1853
1854 (define_insn "*load_multiple_di"
1855   [(match_parallel 0 "load_multiple_operation"
1856                    [(set (match_operand:DI 1 "register_operand" "=r")
1857                          (match_operand:DI 2 "s_operand" "QS"))])]
1858   "reload_completed && word_mode == DImode"
1859 {
1860   int words = XVECLEN (operands[0], 0);
1861   operands[0] = gen_rtx_REG (DImode, REGNO (operands[1]) + words - 1);
1862   return "lmg\t%1,%0,%S2";
1863 }
1864    [(set_attr "op_type" "RSY")
1865     (set_attr "type"    "lm")])
1866
1867 (define_insn "*load_multiple_si"
1868   [(match_parallel 0 "load_multiple_operation"
1869                    [(set (match_operand:SI 1 "register_operand" "=r,r")
1870                          (match_operand:SI 2 "s_operand" "Q,S"))])]
1871   "reload_completed"
1872 {
1873   int words = XVECLEN (operands[0], 0);
1874   operands[0] = gen_rtx_REG (SImode, REGNO (operands[1]) + words - 1);
1875   return which_alternative == 0 ? "lm\t%1,%0,%S2" : "lmy\t%1,%0,%S2";
1876 }
1877    [(set_attr "op_type" "RS,RSY")
1878     (set_attr "type"    "lm")])
1879
1880 ;
1881 ; store multiple pattern(s).
1882 ;
1883
1884 (define_expand "store_multiple"
1885   [(match_par_dup 3 [(set (match_operand 0 "" "")
1886                           (match_operand 1 "" ""))
1887                      (use (match_operand 2 "" ""))])]
1888   "reload_completed"
1889 {
1890   enum machine_mode mode;
1891   int regno;
1892   int count;
1893   rtx to;
1894   int i, off;
1895
1896   /* Support only storing a constant number of fixed-point registers to
1897      memory and only bother with this if more than two.  */
1898   if (GET_CODE (operands[2]) != CONST_INT
1899       || INTVAL (operands[2]) < 2
1900       || INTVAL (operands[2]) > 16
1901       || GET_CODE (operands[0]) != MEM
1902       || GET_CODE (operands[1]) != REG
1903       || REGNO (operands[1]) >= 16)
1904     FAIL;
1905
1906   count = INTVAL (operands[2]);
1907   regno = REGNO (operands[1]);
1908   mode = GET_MODE (operands[1]);
1909   if (mode != SImode && mode != word_mode)
1910     FAIL;
1911
1912   operands[3] = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (count));
1913
1914   if (no_new_pseudos)
1915     {
1916       if (GET_CODE (XEXP (operands[0], 0)) == REG)
1917         {
1918           to = XEXP (operands[0], 0);
1919           off = 0;
1920         }
1921       else if (GET_CODE (XEXP (operands[0], 0)) == PLUS
1922                && GET_CODE (XEXP (XEXP (operands[0], 0), 0)) == REG
1923                && GET_CODE (XEXP (XEXP (operands[0], 0), 1)) == CONST_INT)
1924         {
1925           to = XEXP (XEXP (operands[0], 0), 0);
1926           off = INTVAL (XEXP (XEXP (operands[0], 0), 1));
1927         }
1928       else
1929         FAIL;
1930     }
1931   else
1932     {
1933       to = force_reg (Pmode, XEXP (operands[0], 0));
1934       off = 0;
1935     }
1936
1937   for (i = 0; i < count; i++)
1938     XVECEXP (operands[3], 0, i)
1939       = gen_rtx_SET (VOIDmode,
1940                      change_address (operands[0], mode,
1941                        plus_constant (to, off + i * GET_MODE_SIZE (mode))),
1942                      gen_rtx_REG (mode, regno + i));
1943 })
1944
1945 (define_insn "*store_multiple_di"
1946   [(match_parallel 0 "store_multiple_operation"
1947                    [(set (match_operand:DI 1 "s_operand" "=QS")
1948                          (match_operand:DI 2 "register_operand" "r"))])]
1949   "reload_completed && word_mode == DImode"
1950 {
1951   int words = XVECLEN (operands[0], 0);
1952   operands[0] = gen_rtx_REG (DImode, REGNO (operands[2]) + words - 1);
1953   return "stmg\t%2,%0,%S1";
1954 }
1955    [(set_attr "op_type" "RSY")
1956     (set_attr "type"    "stm")])
1957
1958
1959 (define_insn "*store_multiple_si"
1960   [(match_parallel 0 "store_multiple_operation"
1961                    [(set (match_operand:SI 1 "s_operand" "=Q,S")
1962                          (match_operand:SI 2 "register_operand" "r,r"))])]
1963   "reload_completed"
1964 {
1965   int words = XVECLEN (operands[0], 0);
1966   operands[0] = gen_rtx_REG (SImode, REGNO (operands[2]) + words - 1);
1967   return which_alternative == 0 ? "stm\t%2,%0,%S1" : "stmy\t%2,%0,%S1";
1968 }
1969    [(set_attr "op_type" "RS,RSY")
1970     (set_attr "type"    "stm")])
1971
1972 ;;
1973 ;; String instructions.
1974 ;;
1975
1976 (define_insn "*execute"
1977   [(match_parallel 0 ""
1978     [(unspec [(match_operand 1 "register_operand" "a")
1979               (match_operand:BLK 2 "memory_operand" "R")
1980               (match_operand 3 "" "")] UNSPEC_EXECUTE)])]
1981   "GET_MODE_CLASS (GET_MODE (operands[1])) == MODE_INT
1982    && GET_MODE_SIZE (GET_MODE (operands[1])) <= UNITS_PER_WORD"
1983   "ex\t%1,%2"
1984   [(set_attr "op_type" "RX")
1985    (set_attr "type" "cs")])
1986
1987
1988 ;
1989 ; strlenM instruction pattern(s).
1990 ;
1991
1992 (define_expand "strlen<mode>"
1993   [(set (reg:SI 0) (match_operand:SI 2 "immediate_operand" ""))
1994    (parallel
1995     [(set (match_dup 4)
1996           (unspec:P [(const_int 0)
1997                       (match_operand:BLK 1 "memory_operand" "")
1998                       (reg:SI 0)
1999                       (match_operand 3 "immediate_operand" "")] UNSPEC_SRST))
2000      (clobber (scratch:P))
2001      (clobber (reg:CC CC_REGNUM))])
2002    (parallel
2003     [(set (match_operand:P 0 "register_operand" "")
2004           (minus:P (match_dup 4) (match_dup 5)))
2005      (clobber (reg:CC CC_REGNUM))])]
2006   ""
2007 {
2008   operands[4] = gen_reg_rtx (Pmode);
2009   operands[5] = gen_reg_rtx (Pmode);
2010   emit_move_insn (operands[5], force_operand (XEXP (operands[1], 0), NULL_RTX));
2011   operands[1] = replace_equiv_address (operands[1], operands[5]);
2012 })
2013
2014 (define_insn "*strlen<mode>"
2015   [(set (match_operand:P 0 "register_operand" "=a")
2016         (unspec:P [(match_operand:P 2 "general_operand" "0")
2017                     (mem:BLK (match_operand:P 3 "register_operand" "1"))
2018                     (reg:SI 0)
2019                     (match_operand 4 "immediate_operand" "")] UNSPEC_SRST))
2020    (clobber (match_scratch:P 1 "=a"))
2021    (clobber (reg:CC CC_REGNUM))]
2022   ""
2023   "srst\t%0,%1\;jo\t.-4"
2024   [(set_attr "length" "8")
2025    (set_attr "type" "vs")])
2026
2027 ;
2028 ; cmpstrM instruction pattern(s).
2029 ;
2030
2031 (define_expand "cmpstrsi"
2032   [(set (reg:SI 0) (const_int 0))
2033    (parallel
2034     [(clobber (match_operand 3 "" ""))
2035      (clobber (match_dup 4))
2036      (set (reg:CCU CC_REGNUM)
2037           (compare:CCU (match_operand:BLK 1 "memory_operand" "")
2038                        (match_operand:BLK 2 "memory_operand" "")))
2039      (use (reg:SI 0))])
2040    (parallel
2041     [(set (match_operand:SI 0 "register_operand" "=d")
2042           (unspec:SI [(reg:CCU CC_REGNUM)] UNSPEC_CMPINT))
2043      (clobber (reg:CC CC_REGNUM))])]
2044   ""
2045 {
2046   /* As the result of CMPINT is inverted compared to what we need,
2047      we have to swap the operands.  */
2048   rtx op1 = operands[2];
2049   rtx op2 = operands[1];
2050   rtx addr1 = gen_reg_rtx (Pmode);
2051   rtx addr2 = gen_reg_rtx (Pmode);
2052
2053   emit_move_insn (addr1, force_operand (XEXP (op1, 0), NULL_RTX));
2054   emit_move_insn (addr2, force_operand (XEXP (op2, 0), NULL_RTX));
2055   operands[1] = replace_equiv_address_nv (op1, addr1);
2056   operands[2] = replace_equiv_address_nv (op2, addr2);
2057   operands[3] = addr1;
2058   operands[4] = addr2;
2059 })
2060
2061 (define_insn "*cmpstr<mode>"
2062   [(clobber (match_operand:P 0 "register_operand" "=d"))
2063    (clobber (match_operand:P 1 "register_operand" "=d"))
2064    (set (reg:CCU CC_REGNUM)
2065         (compare:CCU (mem:BLK (match_operand:P 2 "register_operand" "0"))
2066                      (mem:BLK (match_operand:P 3 "register_operand" "1"))))
2067    (use (reg:SI 0))]
2068   ""
2069   "clst\t%0,%1\;jo\t.-4"
2070   [(set_attr "length" "8")
2071    (set_attr "type" "vs")])
2072  
2073 ;
2074 ; movstr instruction pattern.
2075 ;
2076
2077 (define_expand "movstr"
2078   [(set (reg:SI 0) (const_int 0))
2079    (parallel 
2080     [(clobber (match_dup 3))
2081      (set (match_operand:BLK 1 "memory_operand" "")
2082           (match_operand:BLK 2 "memory_operand" ""))
2083      (set (match_operand 0 "register_operand" "")
2084           (unspec [(match_dup 1) 
2085                    (match_dup 2)
2086                    (reg:SI 0)] UNSPEC_MVST))
2087      (clobber (reg:CC CC_REGNUM))])]
2088   ""
2089 {
2090   rtx addr1 = gen_reg_rtx (Pmode);
2091   rtx addr2 = gen_reg_rtx (Pmode);
2092
2093   emit_move_insn (addr1, force_operand (XEXP (operands[1], 0), NULL_RTX));
2094   emit_move_insn (addr2, force_operand (XEXP (operands[2], 0), NULL_RTX));
2095   operands[1] = replace_equiv_address_nv (operands[1], addr1);
2096   operands[2] = replace_equiv_address_nv (operands[2], addr2);
2097   operands[3] = addr2;
2098 })
2099
2100 (define_insn "*movstr"
2101   [(clobber (match_operand:P 2 "register_operand" "=d"))
2102    (set (mem:BLK (match_operand:P 1 "register_operand" "0"))
2103         (mem:BLK (match_operand:P 3 "register_operand" "2")))
2104    (set (match_operand:P 0 "register_operand" "=d")
2105         (unspec [(mem:BLK (match_dup 1)) 
2106                  (mem:BLK (match_dup 3))
2107                  (reg:SI 0)] UNSPEC_MVST))
2108    (clobber (reg:CC CC_REGNUM))]
2109   ""
2110   "mvst\t%1,%2\;jo\t.-4"
2111   [(set_attr "length" "8")
2112    (set_attr "type" "vs")])
2113   
2114
2115 ;
2116 ; movmemM instruction pattern(s).
2117 ;
2118
2119 (define_expand "movmem<mode>"
2120   [(set (match_operand:BLK 0 "memory_operand" "")
2121         (match_operand:BLK 1 "memory_operand" ""))
2122    (use (match_operand:GPR 2 "general_operand" ""))
2123    (match_operand 3 "" "")]
2124   ""
2125   "s390_expand_movmem (operands[0], operands[1], operands[2]); DONE;")
2126
2127 ; Move a block that is up to 256 bytes in length.
2128 ; The block length is taken as (operands[2] % 256) + 1.
2129
2130 (define_expand "movmem_short"
2131   [(parallel
2132     [(set (match_operand:BLK 0 "memory_operand" "")
2133           (match_operand:BLK 1 "memory_operand" ""))
2134      (use (match_operand 2 "nonmemory_operand" ""))
2135      (use (const:BLK (unspec:BLK [(const_int 0)] UNSPEC_INSN)))
2136      (clobber (match_dup 3))])]
2137   ""
2138   "operands[3] = gen_rtx_SCRATCH (Pmode);")
2139
2140 (define_insn "*movmem_short"
2141   [(set (match_operand:BLK 0 "memory_operand" "=Q,Q,Q")
2142         (match_operand:BLK 1 "memory_operand" "Q,Q,Q"))
2143    (use (match_operand 2 "nonmemory_operand" "n,a,a"))
2144    (use (match_operand 3 "immediate_operand" "X,R,X"))
2145    (clobber (match_scratch 4 "=X,X,&a"))]
2146   "(GET_MODE (operands[2]) == Pmode || GET_MODE (operands[2]) == VOIDmode)
2147    && GET_MODE (operands[4]) == Pmode"
2148   "#"
2149   [(set_attr "type" "cs")])
2150
2151 (define_split
2152   [(set (match_operand:BLK 0 "memory_operand" "")
2153         (match_operand:BLK 1 "memory_operand" ""))
2154    (use (match_operand 2 "const_int_operand" ""))
2155    (use (match_operand 3 "immediate_operand" ""))
2156    (clobber (scratch))]
2157   "reload_completed"
2158   [(parallel
2159     [(set (match_dup 0) (match_dup 1))
2160      (use (match_dup 2))])]
2161   "operands[2] = GEN_INT ((INTVAL (operands[2]) & 0xff) + 1);")
2162
2163 (define_split
2164   [(set (match_operand:BLK 0 "memory_operand" "")
2165         (match_operand:BLK 1 "memory_operand" ""))
2166    (use (match_operand 2 "register_operand" ""))
2167    (use (match_operand 3 "memory_operand" ""))
2168    (clobber (scratch))]
2169   "reload_completed"
2170   [(parallel
2171     [(unspec [(match_dup 2) (match_dup 3)
2172               (const_int 0)] UNSPEC_EXECUTE)
2173      (set (match_dup 0) (match_dup 1))
2174      (use (const_int 1))])]
2175   "")
2176
2177 (define_split
2178   [(set (match_operand:BLK 0 "memory_operand" "")
2179         (match_operand:BLK 1 "memory_operand" ""))
2180    (use (match_operand 2 "register_operand" ""))
2181    (use (const:BLK (unspec:BLK [(const_int 0)] UNSPEC_INSN)))
2182    (clobber (match_operand 3 "register_operand" ""))]
2183   "reload_completed && TARGET_CPU_ZARCH"
2184   [(set (match_dup 3) (label_ref (match_dup 4)))
2185    (parallel
2186     [(unspec [(match_dup 2) (mem:BLK (match_dup 3)) 
2187               (label_ref (match_dup 4))] UNSPEC_EXECUTE)
2188      (set (match_dup 0) (match_dup 1))
2189      (use (const_int 1))])]
2190   "operands[4] = gen_label_rtx ();")
2191
2192 ; Move a block of arbitrary length.
2193
2194 (define_expand "movmem_long"
2195   [(parallel
2196     [(clobber (match_dup 2))
2197      (clobber (match_dup 3))
2198      (set (match_operand:BLK 0 "memory_operand" "")
2199           (match_operand:BLK 1 "memory_operand" ""))
2200      (use (match_operand 2 "general_operand" ""))
2201      (use (match_dup 3))
2202      (clobber (reg:CC CC_REGNUM))])]
2203   ""
2204 {
2205   enum machine_mode dword_mode = word_mode == DImode ? TImode : DImode;
2206   rtx reg0 = gen_reg_rtx (dword_mode);
2207   rtx reg1 = gen_reg_rtx (dword_mode);
2208   rtx addr0 = gen_lowpart (Pmode, gen_highpart (word_mode, reg0));
2209   rtx addr1 = gen_lowpart (Pmode, gen_highpart (word_mode, reg1));
2210   rtx len0 = gen_lowpart (Pmode, reg0);
2211   rtx len1 = gen_lowpart (Pmode, reg1);
2212
2213   emit_insn (gen_rtx_CLOBBER (VOIDmode, reg0));
2214   emit_move_insn (addr0, force_operand (XEXP (operands[0], 0), NULL_RTX));
2215   emit_move_insn (len0, operands[2]);
2216
2217   emit_insn (gen_rtx_CLOBBER (VOIDmode, reg1));
2218   emit_move_insn (addr1, force_operand (XEXP (operands[1], 0), NULL_RTX));
2219   emit_move_insn (len1, operands[2]);
2220
2221   operands[0] = replace_equiv_address_nv (operands[0], addr0);
2222   operands[1] = replace_equiv_address_nv (operands[1], addr1);
2223   operands[2] = reg0;
2224   operands[3] = reg1;
2225 })
2226
2227 (define_insn "*movmem_long"
2228   [(clobber (match_operand:<DBL> 0 "register_operand" "=d"))
2229    (clobber (match_operand:<DBL> 1 "register_operand" "=d"))
2230    (set (mem:BLK (subreg:P (match_operand:<DBL> 2 "register_operand" "0") 0))
2231         (mem:BLK (subreg:P (match_operand:<DBL> 3 "register_operand" "1") 0)))
2232    (use (match_dup 2))
2233    (use (match_dup 3))
2234    (clobber (reg:CC CC_REGNUM))]
2235   ""
2236   "mvcle\t%0,%1,0\;jo\t.-4"
2237   [(set_attr "length" "8")
2238    (set_attr "type" "vs")])
2239
2240 ;
2241 ; setmemM instruction pattern(s).
2242 ;
2243
2244 (define_expand "setmem<mode>"
2245   [(set (match_operand:BLK 0 "memory_operand" "")
2246         (match_operand:QI 2 "general_operand" ""))
2247    (use (match_operand:GPR 1 "general_operand" ""))
2248    (match_operand 3 "" "")]
2249   ""
2250   "s390_expand_setmem (operands[0], operands[1], operands[2]); DONE;")
2251
2252 ; Clear a block that is up to 256 bytes in length.
2253 ; The block length is taken as (operands[1] % 256) + 1.
2254
2255 (define_expand "clrmem_short"
2256   [(parallel
2257     [(set (match_operand:BLK 0 "memory_operand" "")
2258           (const_int 0))
2259      (use (match_operand 1 "nonmemory_operand" ""))
2260      (use (const:BLK (unspec:BLK [(const_int 0)] UNSPEC_INSN)))
2261      (clobber (match_dup 2))
2262      (clobber (reg:CC CC_REGNUM))])]
2263   ""
2264   "operands[2] = gen_rtx_SCRATCH (Pmode);")
2265
2266 (define_insn "*clrmem_short"
2267   [(set (match_operand:BLK 0 "memory_operand" "=Q,Q,Q")
2268         (const_int 0))
2269    (use (match_operand 1 "nonmemory_operand" "n,a,a"))
2270    (use (match_operand 2 "immediate_operand" "X,R,X"))
2271    (clobber (match_scratch 3 "=X,X,&a"))
2272    (clobber (reg:CC CC_REGNUM))]
2273   "(GET_MODE (operands[1]) == Pmode || GET_MODE (operands[1]) == VOIDmode)
2274    && GET_MODE (operands[3]) == Pmode"
2275   "#"
2276   [(set_attr "type" "cs")])
2277
2278 (define_split
2279   [(set (match_operand:BLK 0 "memory_operand" "")
2280         (const_int 0))
2281    (use (match_operand 1 "const_int_operand" ""))
2282    (use (match_operand 2 "immediate_operand" ""))
2283    (clobber (scratch))
2284    (clobber (reg:CC CC_REGNUM))]
2285   "reload_completed"
2286   [(parallel
2287     [(set (match_dup 0) (const_int 0))
2288      (use (match_dup 1))
2289      (clobber (reg:CC CC_REGNUM))])]
2290   "operands[1] = GEN_INT ((INTVAL (operands[1]) & 0xff) + 1);")
2291
2292 (define_split
2293   [(set (match_operand:BLK 0 "memory_operand" "")
2294         (const_int 0))
2295    (use (match_operand 1 "register_operand" ""))
2296    (use (match_operand 2 "memory_operand" ""))
2297    (clobber (scratch))
2298    (clobber (reg:CC CC_REGNUM))]
2299   "reload_completed"
2300   [(parallel
2301     [(unspec [(match_dup 1) (match_dup 2)
2302               (const_int 0)] UNSPEC_EXECUTE)
2303      (set (match_dup 0) (const_int 0))
2304      (use (const_int 1))
2305      (clobber (reg:CC CC_REGNUM))])]
2306   "")
2307
2308 (define_split
2309   [(set (match_operand:BLK 0 "memory_operand" "")
2310         (const_int 0))
2311    (use (match_operand 1 "register_operand" ""))
2312    (use (const:BLK (unspec:BLK [(const_int 0)] UNSPEC_INSN)))
2313    (clobber (match_operand 2 "register_operand" ""))
2314    (clobber (reg:CC CC_REGNUM))]
2315   "reload_completed && TARGET_CPU_ZARCH"
2316   [(set (match_dup 2) (label_ref (match_dup 3)))
2317    (parallel
2318     [(unspec [(match_dup 1) (mem:BLK (match_dup 2)) 
2319               (label_ref (match_dup 3))] UNSPEC_EXECUTE)
2320      (set (match_dup 0) (const_int 0))
2321      (use (const_int 1))
2322      (clobber (reg:CC CC_REGNUM))])]
2323   "operands[3] = gen_label_rtx ();")
2324
2325 ; Initialize a block of arbitrary length with (operands[2] % 256). 
2326
2327 (define_expand "setmem_long"
2328   [(parallel
2329     [(clobber (match_dup 1))
2330      (set (match_operand:BLK 0 "memory_operand" "")
2331           (match_operand 2 "shift_count_or_setmem_operand" ""))
2332      (use (match_operand 1 "general_operand" ""))
2333      (use (match_dup 3))
2334      (clobber (reg:CC CC_REGNUM))])]
2335   ""
2336 {
2337   enum machine_mode dword_mode = word_mode == DImode ? TImode : DImode;
2338   rtx reg0 = gen_reg_rtx (dword_mode);
2339   rtx reg1 = gen_reg_rtx (dword_mode);
2340   rtx addr0 = gen_lowpart (Pmode, gen_highpart (word_mode, reg0));
2341   rtx len0 = gen_lowpart (Pmode, reg0);
2342
2343   emit_insn (gen_rtx_CLOBBER (VOIDmode, reg0));
2344   emit_move_insn (addr0, force_operand (XEXP (operands[0], 0), NULL_RTX));
2345   emit_move_insn (len0, operands[1]);
2346
2347   emit_move_insn (reg1, const0_rtx);
2348
2349   operands[0] = replace_equiv_address_nv (operands[0], addr0);
2350   operands[1] = reg0;
2351   operands[3] = reg1;
2352 })
2353
2354 (define_insn "*setmem_long"
2355   [(clobber (match_operand:<DBL> 0 "register_operand" "=d"))
2356    (set (mem:BLK (subreg:P (match_operand:<DBL> 3 "register_operand" "0") 0))
2357         (match_operand 2 "shift_count_or_setmem_operand" "Y"))
2358    (use (match_dup 3))
2359    (use (match_operand:<DBL> 1 "register_operand" "d"))
2360    (clobber (reg:CC CC_REGNUM))]
2361   ""
2362   "mvcle\t%0,%1,%Y2\;jo\t.-4"
2363   [(set_attr "length" "8")
2364    (set_attr "type" "vs")])
2365
2366 (define_insn "*setmem_long_and"
2367   [(clobber (match_operand:<DBL> 0 "register_operand" "=d"))
2368    (set (mem:BLK (subreg:P (match_operand:<DBL> 3 "register_operand" "0") 0))
2369         (and (match_operand 2 "shift_count_or_setmem_operand" "Y")
2370              (match_operand 4 "const_int_operand"             "n")))
2371    (use (match_dup 3))
2372    (use (match_operand:<DBL> 1 "register_operand" "d"))
2373    (clobber (reg:CC CC_REGNUM))]
2374   "(INTVAL (operands[4]) & 255) == 255"
2375   "mvcle\t%0,%1,%Y2\;jo\t.-4"
2376   [(set_attr "length" "8")
2377    (set_attr "type" "vs")])
2378 ;
2379 ; cmpmemM instruction pattern(s).
2380 ;
2381
2382 (define_expand "cmpmemsi"
2383   [(set (match_operand:SI 0 "register_operand" "")
2384         (compare:SI (match_operand:BLK 1 "memory_operand" "")
2385                     (match_operand:BLK 2 "memory_operand" "") ) )
2386    (use (match_operand:SI 3 "general_operand" ""))
2387    (use (match_operand:SI 4 "" ""))]
2388   ""
2389   "s390_expand_cmpmem (operands[0], operands[1],
2390                        operands[2], operands[3]); DONE;")
2391
2392 ; Compare a block that is up to 256 bytes in length.
2393 ; The block length is taken as (operands[2] % 256) + 1.
2394
2395 (define_expand "cmpmem_short"
2396   [(parallel
2397     [(set (reg:CCU CC_REGNUM)
2398           (compare:CCU (match_operand:BLK 0 "memory_operand" "")
2399                        (match_operand:BLK 1 "memory_operand" "")))
2400      (use (match_operand 2 "nonmemory_operand" ""))
2401      (use (const:BLK (unspec:BLK [(const_int 0)] UNSPEC_INSN)))
2402      (clobber (match_dup 3))])]
2403   ""
2404   "operands[3] = gen_rtx_SCRATCH (Pmode);")
2405
2406 (define_insn "*cmpmem_short"
2407   [(set (reg:CCU CC_REGNUM)
2408         (compare:CCU (match_operand:BLK 0 "memory_operand" "Q,Q,Q")
2409                      (match_operand:BLK 1 "memory_operand" "Q,Q,Q")))
2410    (use (match_operand 2 "nonmemory_operand" "n,a,a"))
2411    (use (match_operand 3 "immediate_operand" "X,R,X"))
2412    (clobber (match_scratch 4 "=X,X,&a"))]
2413   "(GET_MODE (operands[2]) == Pmode || GET_MODE (operands[2]) == VOIDmode)
2414    && GET_MODE (operands[4]) == Pmode"
2415   "#"
2416   [(set_attr "type" "cs")])
2417
2418 (define_split
2419   [(set (reg:CCU CC_REGNUM)
2420         (compare:CCU (match_operand:BLK 0 "memory_operand" "")
2421                      (match_operand:BLK 1 "memory_operand" "")))
2422    (use (match_operand 2 "const_int_operand" ""))
2423    (use (match_operand 3 "immediate_operand" ""))
2424    (clobber (scratch))]
2425   "reload_completed"
2426   [(parallel
2427     [(set (reg:CCU CC_REGNUM) (compare:CCU (match_dup 0) (match_dup 1)))
2428      (use (match_dup 2))])]
2429   "operands[2] = GEN_INT ((INTVAL (operands[2]) & 0xff) + 1);")
2430
2431 (define_split
2432   [(set (reg:CCU CC_REGNUM)
2433         (compare:CCU (match_operand:BLK 0 "memory_operand" "")
2434                      (match_operand:BLK 1 "memory_operand" "")))
2435    (use (match_operand 2 "register_operand" ""))
2436    (use (match_operand 3 "memory_operand" ""))
2437    (clobber (scratch))]
2438   "reload_completed"
2439   [(parallel
2440     [(unspec [(match_dup 2) (match_dup 3)
2441               (const_int 0)] UNSPEC_EXECUTE)
2442      (set (reg:CCU CC_REGNUM) (compare:CCU (match_dup 0) (match_dup 1)))
2443      (use (const_int 1))])]
2444   "")
2445
2446 (define_split
2447   [(set (reg:CCU CC_REGNUM)
2448         (compare:CCU (match_operand:BLK 0 "memory_operand" "")
2449                      (match_operand:BLK 1 "memory_operand" "")))
2450    (use (match_operand 2 "register_operand" ""))
2451    (use (const:BLK (unspec:BLK [(const_int 0)] UNSPEC_INSN)))
2452    (clobber (match_operand 3 "register_operand" ""))]
2453   "reload_completed && TARGET_CPU_ZARCH"
2454   [(set (match_dup 3) (label_ref (match_dup 4)))
2455    (parallel
2456     [(unspec [(match_dup 2) (mem:BLK (match_dup 3)) 
2457               (label_ref (match_dup 4))] UNSPEC_EXECUTE)
2458      (set (reg:CCU CC_REGNUM) (compare:CCU (match_dup 0) (match_dup 1)))
2459      (use (const_int 1))])]
2460   "operands[4] = gen_label_rtx ();")
2461
2462 ; Compare a block of arbitrary length.
2463
2464 (define_expand "cmpmem_long"
2465   [(parallel
2466     [(clobber (match_dup 2))
2467      (clobber (match_dup 3))
2468      (set (reg:CCU CC_REGNUM)
2469           (compare:CCU (match_operand:BLK 0 "memory_operand" "")
2470                        (match_operand:BLK 1 "memory_operand" "")))
2471      (use (match_operand 2 "general_operand" ""))
2472      (use (match_dup 3))])]
2473   ""
2474 {
2475   enum machine_mode dword_mode = word_mode == DImode ? TImode : DImode;
2476   rtx reg0 = gen_reg_rtx (dword_mode);
2477   rtx reg1 = gen_reg_rtx (dword_mode);
2478   rtx addr0 = gen_lowpart (Pmode, gen_highpart (word_mode, reg0));
2479   rtx addr1 = gen_lowpart (Pmode, gen_highpart (word_mode, reg1));
2480   rtx len0 = gen_lowpart (Pmode, reg0);
2481   rtx len1 = gen_lowpart (Pmode, reg1);
2482
2483   emit_insn (gen_rtx_CLOBBER (VOIDmode, reg0));
2484   emit_move_insn (addr0, force_operand (XEXP (operands[0], 0), NULL_RTX));
2485   emit_move_insn (len0, operands[2]);
2486
2487   emit_insn (gen_rtx_CLOBBER (VOIDmode, reg1));
2488   emit_move_insn (addr1, force_operand (XEXP (operands[1], 0), NULL_RTX));
2489   emit_move_insn (len1, operands[2]);
2490
2491   operands[0] = replace_equiv_address_nv (operands[0], addr0);
2492   operands[1] = replace_equiv_address_nv (operands[1], addr1);
2493   operands[2] = reg0;
2494   operands[3] = reg1;
2495 })
2496
2497 (define_insn "*cmpmem_long"
2498   [(clobber (match_operand:<DBL> 0 "register_operand" "=d"))
2499    (clobber (match_operand:<DBL> 1 "register_operand" "=d"))
2500    (set (reg:CCU CC_REGNUM)
2501         (compare:CCU (mem:BLK (subreg:P (match_operand:<DBL> 2 "register_operand" "0") 0))
2502                      (mem:BLK (subreg:P (match_operand:<DBL> 3 "register_operand" "1") 0))))
2503    (use (match_dup 2))
2504    (use (match_dup 3))]
2505   ""
2506   "clcle\t%0,%1,0\;jo\t.-4"
2507   [(set_attr "length" "8")
2508    (set_attr "type" "vs")])
2509
2510 ; Convert CCUmode condition code to integer.
2511 ; Result is zero if EQ, positive if LTU, negative if GTU.
2512
2513 (define_insn_and_split "cmpint"
2514   [(set (match_operand:SI 0 "register_operand" "=d")
2515         (unspec:SI [(match_operand:CCU 1 "register_operand" "0")]
2516                    UNSPEC_CMPINT))
2517    (clobber (reg:CC CC_REGNUM))]
2518   ""
2519   "#"
2520   "reload_completed"
2521   [(set (match_dup 0) (ashift:SI (match_dup 0) (const_int 2)))
2522    (parallel
2523     [(set (match_dup 0) (ashiftrt:SI (match_dup 0) (const_int 30)))
2524      (clobber (reg:CC CC_REGNUM))])])
2525
2526 (define_insn_and_split "*cmpint_cc"
2527   [(set (reg CC_REGNUM)
2528         (compare (unspec:SI [(match_operand:CCU 1 "register_operand" "0")]
2529                             UNSPEC_CMPINT)
2530                  (const_int 0)))
2531    (set (match_operand:SI 0 "register_operand" "=d")
2532         (unspec:SI [(match_dup 1)] UNSPEC_CMPINT))]
2533   "s390_match_ccmode (insn, CCSmode)"
2534   "#"
2535   "&& reload_completed"
2536   [(set (match_dup 0) (ashift:SI (match_dup 0) (const_int 2)))
2537    (parallel
2538     [(set (match_dup 2) (match_dup 3))
2539      (set (match_dup 0) (ashiftrt:SI (match_dup 0) (const_int 30)))])]
2540 {
2541   rtx result = gen_rtx_ASHIFTRT (SImode, operands[0], GEN_INT (30));
2542   operands[2] = SET_DEST (XVECEXP (PATTERN (curr_insn), 0, 0));
2543   operands[3] = gen_rtx_COMPARE (GET_MODE (operands[2]), result, const0_rtx);
2544 })
2545
2546 (define_insn_and_split "*cmpint_sign"
2547   [(set (match_operand:DI 0 "register_operand" "=d")
2548         (sign_extend:DI (unspec:SI [(match_operand:CCU 1 "register_operand" "0")]
2549                                    UNSPEC_CMPINT)))
2550    (clobber (reg:CC CC_REGNUM))]
2551   "TARGET_64BIT"
2552   "#"
2553   "&& reload_completed"
2554   [(set (match_dup 0) (ashift:DI (match_dup 0) (const_int 34)))
2555    (parallel
2556     [(set (match_dup 0) (ashiftrt:DI (match_dup 0) (const_int 62)))
2557      (clobber (reg:CC CC_REGNUM))])])
2558
2559 (define_insn_and_split "*cmpint_sign_cc"
2560   [(set (reg CC_REGNUM)
2561         (compare (ashiftrt:DI (ashift:DI (subreg:DI 
2562                    (unspec:SI [(match_operand:CCU 1 "register_operand" "0")]
2563                               UNSPEC_CMPINT) 0)
2564                    (const_int 32)) (const_int 32))
2565                  (const_int 0)))
2566    (set (match_operand:DI 0 "register_operand" "=d")
2567         (sign_extend:DI (unspec:SI [(match_dup 1)] UNSPEC_CMPINT)))]
2568   "s390_match_ccmode (insn, CCSmode) && TARGET_64BIT"
2569   "#"
2570   "&& reload_completed"
2571   [(set (match_dup 0) (ashift:DI (match_dup 0) (const_int 34)))
2572    (parallel
2573     [(set (match_dup 2) (match_dup 3))
2574      (set (match_dup 0) (ashiftrt:DI (match_dup 0) (const_int 62)))])]
2575 {
2576   rtx result = gen_rtx_ASHIFTRT (DImode, operands[0], GEN_INT (62));
2577   operands[2] = SET_DEST (XVECEXP (PATTERN (curr_insn), 0, 0));
2578   operands[3] = gen_rtx_COMPARE (GET_MODE (operands[2]), result, const0_rtx);
2579 })
2580
2581
2582 ;;
2583 ;;- Conversion instructions.
2584 ;;
2585
2586 (define_insn "*sethighpartsi"
2587   [(set (match_operand:SI 0 "register_operand" "=d,d")
2588         (unspec:SI [(match_operand:BLK 1 "s_operand" "Q,S")
2589                     (match_operand 2 "const_int_operand" "n,n")] UNSPEC_ICM))
2590    (clobber (reg:CC CC_REGNUM))]
2591   ""
2592   "@
2593    icm\t%0,%2,%S1
2594    icmy\t%0,%2,%S1"
2595   [(set_attr "op_type" "RS,RSY")])
2596
2597 (define_insn "*sethighpartdi_64"
2598   [(set (match_operand:DI 0 "register_operand" "=d")
2599         (unspec:DI [(match_operand:BLK 1 "s_operand" "QS")
2600                     (match_operand 2 "const_int_operand" "n")] UNSPEC_ICM))
2601    (clobber (reg:CC CC_REGNUM))]
2602   "TARGET_64BIT"
2603   "icmh\t%0,%2,%S1"
2604   [(set_attr "op_type" "RSY")])
2605
2606 (define_insn "*sethighpartdi_31"
2607   [(set (match_operand:DI 0 "register_operand" "=d,d")
2608         (unspec:DI [(match_operand:BLK 1 "s_operand" "Q,S")
2609                     (match_operand 2 "const_int_operand" "n,n")] UNSPEC_ICM))
2610    (clobber (reg:CC CC_REGNUM))]
2611   "!TARGET_64BIT"
2612   "@
2613    icm\t%0,%2,%S1
2614    icmy\t%0,%2,%S1"
2615   [(set_attr "op_type" "RS,RSY")])
2616
2617 (define_insn_and_split "*extzv<mode>"
2618   [(set (match_operand:GPR 0 "register_operand" "=d")
2619         (zero_extract:GPR (match_operand:QI 1 "s_operand" "QS")
2620                           (match_operand 2 "const_int_operand" "n")
2621                           (const_int 0)))
2622    (clobber (reg:CC CC_REGNUM))]
2623   "INTVAL (operands[2]) > 0
2624    && INTVAL (operands[2]) <= GET_MODE_BITSIZE (SImode)"
2625   "#"
2626   "&& reload_completed"
2627   [(parallel
2628     [(set (match_dup 0) (unspec:GPR [(match_dup 1) (match_dup 3)] UNSPEC_ICM))
2629      (clobber (reg:CC CC_REGNUM))])
2630    (set (match_dup 0) (lshiftrt:GPR (match_dup 0) (match_dup 2)))]
2631 {
2632   int bitsize = INTVAL (operands[2]);
2633   int size = (bitsize - 1) / BITS_PER_UNIT + 1; /* round up */
2634   int mask = ((1ul << size) - 1) << (GET_MODE_SIZE (SImode) - size);
2635
2636   operands[1] = adjust_address (operands[1], BLKmode, 0);
2637   set_mem_size (operands[1], GEN_INT (size));
2638   operands[2] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode) - bitsize);
2639   operands[3] = GEN_INT (mask);
2640 })
2641
2642 (define_insn_and_split "*extv<mode>"
2643   [(set (match_operand:GPR 0 "register_operand" "=d")
2644         (sign_extract:GPR (match_operand:QI 1 "s_operand" "QS")
2645                           (match_operand 2 "const_int_operand" "n")
2646                           (const_int 0)))
2647    (clobber (reg:CC CC_REGNUM))]
2648   "INTVAL (operands[2]) > 0
2649    && INTVAL (operands[2]) <= GET_MODE_BITSIZE (SImode)"
2650   "#"
2651   "&& reload_completed"
2652   [(parallel
2653     [(set (match_dup 0) (unspec:GPR [(match_dup 1) (match_dup 3)] UNSPEC_ICM))
2654      (clobber (reg:CC CC_REGNUM))])
2655    (parallel
2656     [(set (match_dup 0) (ashiftrt:GPR (match_dup 0) (match_dup 2)))
2657      (clobber (reg:CC CC_REGNUM))])]
2658 {
2659   int bitsize = INTVAL (operands[2]);
2660   int size = (bitsize - 1) / BITS_PER_UNIT + 1; /* round up */
2661   int mask = ((1ul << size) - 1) << (GET_MODE_SIZE (SImode) - size);
2662
2663   operands[1] = adjust_address (operands[1], BLKmode, 0);
2664   set_mem_size (operands[1], GEN_INT (size));
2665   operands[2] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode) - bitsize);
2666   operands[3] = GEN_INT (mask);
2667 })
2668
2669 ;
2670 ; insv instruction patterns
2671 ;
2672
2673 (define_expand "insv"
2674   [(set (zero_extract (match_operand 0 "nonimmediate_operand" "")
2675                       (match_operand 1 "const_int_operand" "")
2676                       (match_operand 2 "const_int_operand" ""))
2677         (match_operand 3 "general_operand" ""))]
2678   ""
2679 {
2680   if (s390_expand_insv (operands[0], operands[1], operands[2], operands[3]))
2681     DONE;
2682   FAIL;
2683 })
2684
2685 (define_insn "*insv<mode>_mem_reg"
2686   [(set (zero_extract:P (match_operand:QI 0 "memory_operand" "+Q,S")
2687                         (match_operand 1 "const_int_operand" "n,n")
2688                         (const_int 0))
2689         (match_operand:P 2 "register_operand" "d,d"))]
2690   "INTVAL (operands[1]) > 0
2691    && INTVAL (operands[1]) <= GET_MODE_BITSIZE (SImode)
2692    && INTVAL (operands[1]) % BITS_PER_UNIT == 0"
2693 {
2694     int size = INTVAL (operands[1]) / BITS_PER_UNIT;
2695
2696     operands[1] = GEN_INT ((1ul << size) - 1);
2697     return (which_alternative == 0) ? "stcm\t%2,%1,%S0" 
2698                                     : "stcmy\t%2,%1,%S0";
2699 }
2700   [(set_attr "op_type" "RS,RSY")])
2701
2702 (define_insn "*insvdi_mem_reghigh"
2703   [(set (zero_extract:DI (match_operand:QI 0 "memory_operand" "+QS")
2704                          (match_operand 1 "const_int_operand" "n")
2705                          (const_int 0))
2706         (lshiftrt:DI (match_operand:DI 2 "register_operand" "d")
2707                      (const_int 32)))]
2708   "TARGET_64BIT
2709    && INTVAL (operands[1]) > 0
2710    && INTVAL (operands[1]) <= GET_MODE_BITSIZE (SImode)
2711    && INTVAL (operands[1]) % BITS_PER_UNIT == 0"
2712 {
2713     int size = INTVAL (operands[1]) / BITS_PER_UNIT;
2714
2715     operands[1] = GEN_INT ((1ul << size) - 1);
2716     return "stcmh\t%2,%1,%S0";
2717 }
2718 [(set_attr "op_type" "RSY")])
2719
2720 (define_insn "*insv<mode>_reg_imm"
2721   [(set (zero_extract:P (match_operand:P 0 "register_operand" "+d")
2722                         (const_int 16)
2723                         (match_operand 1 "const_int_operand" "n"))
2724         (match_operand:P 2 "const_int_operand" "n"))]
2725   "TARGET_ZARCH
2726    && INTVAL (operands[1]) >= 0
2727    && INTVAL (operands[1]) < BITS_PER_WORD
2728    && INTVAL (operands[1]) % 16 == 0"
2729 {
2730   switch (BITS_PER_WORD - INTVAL (operands[1]))
2731     {
2732       case 64: return "iihh\t%0,%x2"; break;
2733       case 48: return "iihl\t%0,%x2"; break;
2734       case 32: return "iilh\t%0,%x2"; break;
2735       case 16: return "iill\t%0,%x2"; break;
2736       default: gcc_unreachable();
2737     }
2738 }
2739   [(set_attr "op_type" "RI")])
2740
2741 (define_insn "*insv<mode>_reg_extimm"
2742   [(set (zero_extract:P (match_operand:P 0 "register_operand" "+d")
2743                         (const_int 32)
2744                         (match_operand 1 "const_int_operand" "n"))
2745         (match_operand:P 2 "const_int_operand" "n"))]
2746   "TARGET_EXTIMM
2747    && INTVAL (operands[1]) >= 0
2748    && INTVAL (operands[1]) < BITS_PER_WORD
2749    && INTVAL (operands[1]) % 32 == 0"
2750 {
2751   switch (BITS_PER_WORD - INTVAL (operands[1]))
2752     {
2753       case 64: return "iihf\t%0,%o2"; break;
2754       case 32: return "iilf\t%0,%o2"; break;
2755       default: gcc_unreachable();
2756     }
2757 }
2758   [(set_attr "op_type" "RIL")])
2759
2760 ;
2761 ; extendsidi2 instruction pattern(s).
2762 ;
2763
2764 (define_expand "extendsidi2"
2765   [(set (match_operand:DI 0 "register_operand" "")
2766         (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "")))]
2767   ""
2768 {
2769   if (!TARGET_64BIT)
2770     {
2771       emit_insn (gen_rtx_CLOBBER (VOIDmode, operands[0]));
2772       emit_move_insn (gen_highpart (SImode, operands[0]), operands[1]);
2773       emit_move_insn (gen_lowpart (SImode, operands[0]), const0_rtx);
2774       emit_insn (gen_ashrdi3 (operands[0], operands[0], GEN_INT (32)));
2775       DONE;
2776     }
2777 })
2778
2779 (define_insn "*extendsidi2"
2780   [(set (match_operand:DI 0 "register_operand" "=d,d")
2781         (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "d,m")))]
2782   "TARGET_64BIT"
2783   "@
2784    lgfr\t%0,%1
2785    lgf\t%0,%1"
2786   [(set_attr "op_type" "RRE,RXY")])
2787
2788 ;
2789 ; extend(hi|qi)(si|di)2 instruction pattern(s).
2790 ;
2791
2792 (define_expand "extend<HQI:mode><DSI:mode>2"
2793   [(set (match_operand:DSI 0 "register_operand" "")
2794         (sign_extend:DSI (match_operand:HQI 1 "nonimmediate_operand" "")))]
2795   ""
2796 {
2797   if (<DSI:MODE>mode == DImode && !TARGET_64BIT)
2798     {
2799       rtx tmp = gen_reg_rtx (SImode);
2800       emit_insn (gen_extend<HQI:mode>si2 (tmp, operands[1]));
2801       emit_insn (gen_extendsidi2 (operands[0], tmp));
2802       DONE;
2803     }
2804   else if (!TARGET_EXTIMM)
2805     {
2806       rtx bitcount = GEN_INT (GET_MODE_BITSIZE (<DSI:MODE>mode) -
2807                               GET_MODE_BITSIZE (<HQI:MODE>mode));
2808
2809       operands[1] = gen_lowpart (<DSI:MODE>mode, operands[1]);
2810       emit_insn (gen_ashl<DSI:mode>3 (operands[0], operands[1], bitcount));
2811       emit_insn (gen_ashr<DSI:mode>3 (operands[0], operands[0], bitcount));
2812       DONE;
2813     }
2814 })
2815
2816 ;
2817 ; extendhidi2 instruction pattern(s).
2818 ;
2819
2820 (define_insn "*extendhidi2_extimm"
2821   [(set (match_operand:DI 0 "register_operand" "=d,d")
2822         (sign_extend:DI (match_operand:HI 1 "nonimmediate_operand" "d,m")))]
2823   "TARGET_64BIT && TARGET_EXTIMM"
2824   "@
2825    lghr\t%0,%1
2826    lgh\t%0,%1"
2827   [(set_attr "op_type" "RRE,RXY")])
2828
2829 (define_insn "*extendhidi2"
2830   [(set (match_operand:DI 0 "register_operand" "=d")
2831         (sign_extend:DI (match_operand:HI 1 "memory_operand" "m")))]
2832   "TARGET_64BIT"
2833   "lgh\t%0,%1"
2834   [(set_attr "op_type" "RXY")])
2835
2836 ;
2837 ; extendhisi2 instruction pattern(s).
2838 ;
2839
2840 (define_insn "*extendhisi2_extimm"
2841   [(set (match_operand:SI 0 "register_operand" "=d,d,d")
2842         (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "d,R,T")))]
2843   "TARGET_EXTIMM"
2844   "@
2845    lhr\t%0,%1
2846    lh\t%0,%1
2847    lhy\t%0,%1"
2848   [(set_attr "op_type" "RRE,RX,RXY")])
2849
2850 (define_insn "*extendhisi2"
2851   [(set (match_operand:SI 0 "register_operand" "=d,d")
2852         (sign_extend:SI (match_operand:HI 1 "memory_operand" "R,T")))]
2853   "!TARGET_EXTIMM"
2854   "@
2855    lh\t%0,%1
2856    lhy\t%0,%1"
2857   [(set_attr "op_type" "RX,RXY")])
2858
2859 ;
2860 ; extendqi(si|di)2 instruction pattern(s).
2861 ;
2862
2863 (define_insn "*extendqi<mode>2_extimm"
2864   [(set (match_operand:GPR 0 "register_operand" "=d,d")
2865         (sign_extend:GPR (match_operand:QI 1 "nonimmediate_operand" "d,m")))]
2866   "TARGET_EXTIMM"
2867   "@
2868    l<g>br\t%0,%1
2869    l<g>b\t%0,%1"
2870   [(set_attr "op_type" "RRE,RXY")])
2871
2872 (define_insn "*extendqi<mode>2"
2873   [(set (match_operand:GPR 0 "register_operand" "=d")
2874         (sign_extend:GPR (match_operand:QI 1 "memory_operand" "m")))]
2875   "!TARGET_EXTIMM && TARGET_LONG_DISPLACEMENT"
2876   "l<g>b\t%0,%1"
2877   [(set_attr "op_type" "RXY")])
2878
2879 (define_insn_and_split "*extendqi<mode>2_short_displ"
2880   [(set (match_operand:GPR 0 "register_operand" "=d")
2881         (sign_extend:GPR (match_operand:QI 1 "s_operand" "Q")))
2882    (clobber (reg:CC CC_REGNUM))]
2883   "!TARGET_EXTIMM && !TARGET_LONG_DISPLACEMENT"
2884   "#"
2885   "&& reload_completed"
2886   [(parallel
2887     [(set (match_dup 0) (unspec:GPR [(match_dup 1) (const_int 8)] UNSPEC_ICM))
2888      (clobber (reg:CC CC_REGNUM))])
2889    (parallel
2890     [(set (match_dup 0) (ashiftrt:GPR (match_dup 0) (match_dup 2)))
2891      (clobber (reg:CC CC_REGNUM))])]
2892 {
2893   operands[1] = adjust_address (operands[1], BLKmode, 0);
2894   set_mem_size (operands[1], GEN_INT (GET_MODE_SIZE (QImode)));
2895   operands[2] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)
2896                          - GET_MODE_BITSIZE (QImode));
2897 })
2898
2899 ;
2900 ; zero_extendsidi2 instruction pattern(s).
2901 ;
2902
2903 (define_expand "zero_extendsidi2"
2904   [(set (match_operand:DI 0 "register_operand" "")
2905         (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "")))]
2906   ""
2907 {
2908   if (!TARGET_64BIT)
2909     {
2910       emit_insn (gen_rtx_CLOBBER (VOIDmode, operands[0]));
2911       emit_move_insn (gen_lowpart (SImode, operands[0]), operands[1]);
2912       emit_move_insn (gen_highpart (SImode, operands[0]), const0_rtx);
2913       DONE;
2914     }
2915 })
2916
2917 (define_insn "*zero_extendsidi2"
2918   [(set (match_operand:DI 0 "register_operand" "=d,d")
2919         (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "d,m")))]
2920   "TARGET_64BIT"
2921   "@
2922    llgfr\t%0,%1
2923    llgf\t%0,%1"
2924   [(set_attr "op_type" "RRE,RXY")])
2925
2926 ;
2927 ; LLGT-type instructions (zero-extend from 31 bit to 64 bit).
2928 ;
2929
2930 (define_insn "*llgt_sidi"
2931   [(set (match_operand:DI 0 "register_operand" "=d")
2932         (and:DI (subreg:DI (match_operand:SI 1 "memory_operand" "m") 0)
2933                 (const_int 2147483647)))]
2934   "TARGET_64BIT"
2935   "llgt\t%0,%1"
2936   [(set_attr "op_type"  "RXE")])
2937
2938 (define_insn_and_split "*llgt_sidi_split"
2939   [(set (match_operand:DI 0 "register_operand" "=d")
2940         (and:DI (subreg:DI (match_operand:SI 1 "memory_operand" "m") 0)
2941                 (const_int 2147483647)))
2942    (clobber (reg:CC CC_REGNUM))]
2943   "TARGET_64BIT"
2944   "#"
2945   "&& reload_completed"
2946   [(set (match_dup 0)
2947         (and:DI (subreg:DI (match_dup 1) 0)
2948                 (const_int 2147483647)))]
2949   "")
2950
2951 (define_insn "*llgt_sisi"
2952   [(set (match_operand:SI 0 "register_operand" "=d,d")
2953         (and:SI (match_operand:SI 1 "nonimmediate_operand" "d,m")
2954                 (const_int 2147483647)))]
2955   "TARGET_ZARCH"
2956   "@
2957    llgtr\t%0,%1
2958    llgt\t%0,%1"
2959   [(set_attr "op_type"  "RRE,RXE")])
2960
2961 (define_insn "*llgt_didi"
2962   [(set (match_operand:DI 0 "register_operand" "=d,d")
2963         (and:DI (match_operand:DI 1 "nonimmediate_operand" "d,o")
2964                 (const_int 2147483647)))]
2965   "TARGET_64BIT"
2966   "@
2967    llgtr\t%0,%1
2968    llgt\t%0,%N1"
2969   [(set_attr "op_type"  "RRE,RXE")])
2970
2971 (define_split
2972   [(set (match_operand:GPR 0 "register_operand" "")
2973         (and:GPR (match_operand:GPR 1 "nonimmediate_operand" "")
2974                  (const_int 2147483647)))
2975    (clobber (reg:CC CC_REGNUM))]
2976   "TARGET_ZARCH && reload_completed"
2977   [(set (match_dup 0)
2978         (and:GPR (match_dup 1)
2979                  (const_int 2147483647)))]
2980   "")
2981
2982 ;
2983 ; zero_extend(hi|qi)(si|di)2 instruction pattern(s).
2984 ;
2985
2986 (define_expand "zero_extend<mode>di2"
2987   [(set (match_operand:DI 0 "register_operand" "")
2988         (zero_extend:DI (match_operand:HQI 1 "nonimmediate_operand" "")))]
2989   ""
2990 {
2991   if (!TARGET_64BIT)
2992     {
2993       rtx tmp = gen_reg_rtx (SImode);
2994       emit_insn (gen_zero_extend<mode>si2 (tmp, operands[1]));
2995       emit_insn (gen_zero_extendsidi2 (operands[0], tmp));
2996       DONE;
2997     }
2998   else if (!TARGET_EXTIMM)
2999     {
3000       rtx bitcount = GEN_INT (GET_MODE_BITSIZE(DImode) - 
3001                               GET_MODE_BITSIZE(<MODE>mode));
3002       operands[1] = gen_lowpart (DImode, operands[1]);
3003       emit_insn (gen_ashldi3 (operands[0], operands[1], bitcount));
3004       emit_insn (gen_lshrdi3 (operands[0], operands[0], bitcount));
3005       DONE;
3006     }
3007 })
3008
3009 (define_expand "zero_extend<mode>si2"
3010   [(set (match_operand:SI 0 "register_operand" "")
3011         (zero_extend:SI (match_operand:HQI 1 "nonimmediate_operand" "")))]
3012   ""
3013 {
3014   if (!TARGET_EXTIMM)
3015     {
3016       operands[1] = gen_lowpart (SImode, operands[1]);
3017       emit_insn (gen_andsi3 (operands[0], operands[1], 
3018                    GEN_INT ((1 << GET_MODE_BITSIZE(<MODE>mode)) - 1)));
3019       DONE;
3020     }
3021 })
3022
3023 (define_insn "*zero_extend<HQI:mode><GPR:mode>2_extimm"
3024   [(set (match_operand:GPR 0 "register_operand" "=d,d")
3025         (zero_extend:GPR (match_operand:HQI 1 "nonimmediate_operand" "d,m")))]
3026   "TARGET_EXTIMM"
3027   "@
3028    ll<g><hc>r\t%0,%1
3029    ll<g><hc>\t%0,%1"
3030   [(set_attr "op_type" "RRE,RXY")])
3031
3032 (define_insn "*zero_extend<HQI:mode><GPR:mode>2"
3033   [(set (match_operand:GPR 0 "register_operand" "=d")
3034         (zero_extend:GPR (match_operand:HQI 1 "memory_operand" "m")))]
3035   "TARGET_ZARCH && !TARGET_EXTIMM"
3036   "llg<hc>\t%0,%1"
3037   [(set_attr "op_type" "RXY")])
3038
3039 (define_insn_and_split "*zero_extendhisi2_31"
3040   [(set (match_operand:SI 0 "register_operand" "=&d")
3041         (zero_extend:SI (match_operand:HI 1 "s_operand" "QS")))
3042    (clobber (reg:CC CC_REGNUM))]
3043   "!TARGET_ZARCH"
3044   "#"
3045   "&& reload_completed"
3046   [(set (match_dup 0) (const_int 0))
3047    (parallel
3048     [(set (strict_low_part (match_dup 2)) (match_dup 1))
3049      (clobber (reg:CC CC_REGNUM))])]
3050   "operands[2] = gen_lowpart (HImode, operands[0]);")
3051
3052 (define_insn_and_split "*zero_extendqisi2_31"
3053   [(set (match_operand:SI 0 "register_operand" "=&d")
3054         (zero_extend:SI (match_operand:QI 1 "memory_operand" "m")))]
3055   "!TARGET_ZARCH"
3056   "#"
3057   "&& reload_completed"
3058   [(set (match_dup 0) (const_int 0))
3059    (set (strict_low_part (match_dup 2)) (match_dup 1))]
3060   "operands[2] = gen_lowpart (QImode, operands[0]);")
3061
3062 ;
3063 ; zero_extendqihi2 instruction pattern(s).
3064 ;
3065
3066 (define_expand "zero_extendqihi2"
3067   [(set (match_operand:HI 0 "register_operand" "")
3068         (zero_extend:HI (match_operand:QI 1 "register_operand" "")))]
3069   "TARGET_ZARCH && !TARGET_EXTIMM"
3070 {
3071   operands[1] = gen_lowpart (HImode, operands[1]);
3072   emit_insn (gen_andhi3 (operands[0], operands[1], GEN_INT (0xff)));
3073   DONE;
3074 })
3075
3076 (define_insn "*zero_extendqihi2_64"
3077   [(set (match_operand:HI 0 "register_operand" "=d")
3078         (zero_extend:HI (match_operand:QI 1 "memory_operand" "m")))]
3079   "TARGET_ZARCH && !TARGET_EXTIMM"
3080   "llgc\t%0,%1"
3081   [(set_attr "op_type" "RXY")])
3082
3083 (define_insn_and_split "*zero_extendqihi2_31"
3084   [(set (match_operand:HI 0 "register_operand" "=&d")
3085         (zero_extend:HI (match_operand:QI 1 "memory_operand" "m")))]
3086   "!TARGET_ZARCH"
3087   "#"
3088   "&& reload_completed"
3089   [(set (match_dup 0) (const_int 0))
3090    (set (strict_low_part (match_dup 2)) (match_dup 1))]
3091   "operands[2] = gen_lowpart (QImode, operands[0]);")
3092
3093
3094 ;
3095 ; fixuns_trunc(sf|df)(si|di)2 and fix_trunc(sf|df)(si|di)2 instruction pattern(s).
3096 ;
3097
3098 (define_expand "fixuns_trunc<FPR:mode><GPR:mode>2"
3099   [(set (match_operand:GPR 0 "register_operand" "")
3100         (unsigned_fix:GPR (match_operand:FPR 1 "register_operand" "")))]
3101   "TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT"
3102 {
3103   rtx label1 = gen_label_rtx ();
3104   rtx label2 = gen_label_rtx ();
3105   rtx temp = gen_reg_rtx (<FPR:MODE>mode);
3106   REAL_VALUE_TYPE cmp, sub;
3107   
3108   operands[1] = force_reg (<FPR:MODE>mode, operands[1]);
3109   real_2expN (&cmp, GET_MODE_BITSIZE(<GPR:MODE>mode) - 1);
3110   real_2expN (&sub, GET_MODE_BITSIZE(<GPR:MODE>mode));
3111   
3112   emit_insn (gen_cmp<FPR:mode> (operands[1],
3113         CONST_DOUBLE_FROM_REAL_VALUE (cmp, <FPR:MODE>mode)));
3114   emit_jump_insn (gen_blt (label1));
3115   emit_insn (gen_sub<FPR:mode>3 (temp, operands[1],
3116         CONST_DOUBLE_FROM_REAL_VALUE (sub, <FPR:MODE>mode)));
3117   emit_insn (gen_fix_trunc<FPR:mode><GPR:mode>2_ieee (operands[0], temp,
3118         GEN_INT(7)));
3119   emit_jump (label2);
3120
3121   emit_label (label1);
3122   emit_insn (gen_fix_trunc<FPR:mode><GPR:mode>2_ieee (operands[0],
3123         operands[1], GEN_INT(5)));
3124   emit_label (label2);
3125   DONE;
3126 })
3127
3128 (define_expand "fix_trunc<mode>di2"
3129   [(set (match_operand:DI 0 "register_operand" "")
3130         (fix:DI (match_operand:DSF 1 "nonimmediate_operand" "")))]
3131   "TARGET_64BIT && TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT"
3132 {
3133   operands[1] = force_reg (<MODE>mode, operands[1]);
3134   emit_insn (gen_fix_trunc<mode>di2_ieee (operands[0], operands[1],
3135       GEN_INT(5)));
3136   DONE;
3137 })
3138
3139 (define_insn "fix_trunc<FPR:mode><GPR:mode>2_ieee"
3140   [(set (match_operand:GPR 0 "register_operand" "=d")
3141         (fix:GPR (match_operand:FPR 1 "register_operand" "f")))
3142    (unspec:GPR [(match_operand:GPR 2 "immediate_operand" "K")] UNSPEC_ROUND)
3143    (clobber (reg:CC CC_REGNUM))]
3144   "TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT"
3145   "c<GPR:gf><FPR:xde>br\t%0,%h2,%1"
3146   [(set_attr "op_type" "RRE")
3147    (set_attr "type"    "ftoi")])
3148
3149 ;
3150 ; fix_trunctf(si|di)2 instruction pattern(s).
3151 ;
3152
3153 (define_expand "fix_trunctf<mode>2"
3154   [(parallel [(set (match_operand:GPR 0 "register_operand" "")
3155                    (fix:GPR (match_operand:TF 1 "register_operand" "")))
3156               (unspec:GPR [(const_int 5)] UNSPEC_ROUND)
3157               (clobber (reg:CC CC_REGNUM))])]
3158   "TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT"
3159   "")
3160
3161 ;
3162 ; fix_truncdfsi2 instruction pattern(s).
3163 ;
3164
3165 (define_expand "fix_truncdfsi2"
3166   [(set (match_operand:SI 0 "register_operand" "")
3167         (fix:SI (match_operand:DF 1 "nonimmediate_operand" "")))]
3168   "TARGET_HARD_FLOAT"
3169 {
3170   if (TARGET_IBM_FLOAT)
3171     {
3172       /* This is the algorithm from POP chapter A.5.7.2.  */
3173
3174       rtx temp   = assign_stack_local (BLKmode, 8, BITS_PER_WORD);
3175       rtx two31r = s390_gen_rtx_const_DI (0x4f000000, 0x08000000);
3176       rtx two32  = s390_gen_rtx_const_DI (0x4e000001, 0x00000000);
3177
3178       operands[1] = force_reg (DFmode, operands[1]);
3179       emit_insn (gen_fix_truncdfsi2_ibm (operands[0], operands[1],
3180                                          two31r, two32, temp));
3181     }
3182   else
3183     {
3184       operands[1] = force_reg (DFmode, operands[1]);
3185       emit_insn (gen_fix_truncdfsi2_ieee (operands[0], operands[1], GEN_INT (5)));
3186     }
3187
3188   DONE;
3189 })
3190
3191 (define_insn "fix_truncdfsi2_ibm"
3192   [(set (match_operand:SI 0 "register_operand" "=d")
3193         (fix:SI (match_operand:DF 1 "nonimmediate_operand" "+f")))
3194    (use (match_operand:DI 2 "immediate_operand" "m"))
3195    (use (match_operand:DI 3 "immediate_operand" "m"))
3196    (use (match_operand:BLK 4 "memory_operand" "m"))
3197    (clobber (reg:CC CC_REGNUM))]
3198   "TARGET_HARD_FLOAT && TARGET_IBM_FLOAT"
3199 {
3200    output_asm_insn ("sd\t%1,%2", operands);
3201    output_asm_insn ("aw\t%1,%3", operands);
3202    output_asm_insn ("std\t%1,%4", operands);
3203    output_asm_insn ("xi\t%N4,128", operands);
3204    return "l\t%0,%N4";
3205 }
3206   [(set_attr "length" "20")])
3207
3208 ;
3209 ; fix_truncsfsi2 instruction pattern(s).
3210 ;
3211
3212 (define_expand "fix_truncsfsi2"
3213   [(set (match_operand:SI 0 "register_operand" "")
3214         (fix:SI (match_operand:SF 1 "nonimmediate_operand" "")))]
3215   "TARGET_HARD_FLOAT"
3216 {
3217   if (TARGET_IBM_FLOAT)
3218     {
3219       /* Convert to DFmode and then use the POP algorithm.  */
3220       rtx temp = gen_reg_rtx (DFmode);
3221       emit_insn (gen_extendsfdf2 (temp, operands[1]));
3222       emit_insn (gen_fix_truncdfsi2 (operands[0], temp));
3223     }
3224   else
3225     {
3226       operands[1] = force_reg (SFmode, operands[1]);
3227       emit_insn (gen_fix_truncsfsi2_ieee (operands[0], operands[1], GEN_INT (5)));
3228     }
3229
3230   DONE;
3231 })
3232
3233 ;
3234 ; float(si|di)(tf|df|sf)2 instruction pattern(s).
3235 ;
3236
3237 (define_insn "floatdi<mode>2"
3238   [(set (match_operand:FPR 0 "register_operand" "=f")
3239         (float:FPR (match_operand:DI 1 "register_operand" "d")))]
3240   "TARGET_64BIT && TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT"
3241   "c<xde>gbr\t%0,%1"
3242   [(set_attr "op_type" "RRE")
3243    (set_attr "type"    "itof" )])
3244
3245 (define_insn "floatsi<mode>2_ieee"
3246   [(set (match_operand:FPR 0 "register_operand" "=f")
3247         (float:FPR (match_operand:SI 1 "register_operand" "d")))]
3248   "TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT"
3249   "c<xde>fbr\t%0,%1"
3250   [(set_attr "op_type" "RRE")
3251    (set_attr "type"   "itof" )])
3252
3253
3254 ;
3255 ; floatsi(tf|df)2 instruction pattern(s).
3256 ;
3257
3258 (define_expand "floatsitf2"
3259   [(set (match_operand:TF 0 "register_operand" "")
3260         (float:TF (match_operand:SI 1 "register_operand" "")))]
3261   "TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT"
3262   "")
3263
3264 (define_expand "floatsidf2"
3265   [(set (match_operand:DF 0 "register_operand" "")
3266         (float:DF (match_operand:SI 1 "register_operand" "")))]
3267   "TARGET_HARD_FLOAT"
3268 {
3269   if (TARGET_IBM_FLOAT)
3270     {
3271       /* This is the algorithm from POP chapter A.5.7.1.  */
3272
3273       rtx temp  = assign_stack_local (BLKmode, 8, BITS_PER_WORD);
3274       rtx two31 = s390_gen_rtx_const_DI (0x4e000000, 0x80000000);
3275
3276       emit_insn (gen_floatsidf2_ibm (operands[0], operands[1], two31, temp));
3277       DONE;
3278     }
3279 })
3280
3281 (define_insn "floatsidf2_ibm"
3282   [(set (match_operand:DF 0 "register_operand" "=f")
3283         (float:DF (match_operand:SI 1 "register_operand" "d")))
3284    (use (match_operand:DI 2 "immediate_operand" "m"))
3285    (use (match_operand:BLK 3 "memory_operand" "m"))
3286    (clobber (reg:CC CC_REGNUM))]
3287   "TARGET_HARD_FLOAT && TARGET_IBM_FLOAT"
3288 {
3289    output_asm_insn ("st\t%1,%N3", operands);
3290    output_asm_insn ("xi\t%N3,128", operands);
3291    output_asm_insn ("mvc\t%O3(4,%R3),%2", operands);
3292    output_asm_insn ("ld\t%0,%3", operands);
3293    return "sd\t%0,%2";
3294 }
3295   [(set_attr "length" "20")])
3296
3297 ;
3298 ; floatsisf2 instruction pattern(s).
3299 ;
3300
3301 (define_expand "floatsisf2"
3302   [(set (match_operand:SF 0 "register_operand" "")
3303         (float:SF (match_operand:SI 1 "register_operand" "")))]
3304   "TARGET_HARD_FLOAT"
3305 {
3306   if (TARGET_IBM_FLOAT)
3307     {
3308       /* Use the POP algorithm to convert to DFmode and then truncate.  */
3309       rtx temp = gen_reg_rtx (DFmode);
3310       emit_insn (gen_floatsidf2 (temp, operands[1]));
3311       emit_insn (gen_truncdfsf2 (operands[0], temp));
3312       DONE;
3313     }
3314 })
3315
3316 ;
3317 ; truncdfsf2 instruction pattern(s).
3318 ;
3319
3320 (define_expand "truncdfsf2"
3321   [(set (match_operand:SF 0 "register_operand" "")
3322         (float_truncate:SF (match_operand:DF 1 "register_operand" "")))]
3323   "TARGET_HARD_FLOAT"
3324   "")
3325
3326 (define_insn "truncdfsf2_ieee"
3327   [(set (match_operand:SF 0 "register_operand" "=f")
3328         (float_truncate:SF (match_operand:DF 1 "register_operand" "f")))]
3329   "TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT"
3330   "ledbr\t%0,%1"
3331   [(set_attr "op_type"  "RRE")
3332    (set_attr "type"   "ftruncdf")])
3333
3334 (define_insn "truncdfsf2_ibm"
3335   [(set (match_operand:SF 0 "register_operand" "=f,f")
3336         (float_truncate:SF (match_operand:DF 1 "nonimmediate_operand" "f,R")))]
3337   "TARGET_HARD_FLOAT && TARGET_IBM_FLOAT"
3338   "@
3339    ler\t%0,%1
3340    le\t%0,%1"
3341   [(set_attr "op_type"  "RR,RX")
3342    (set_attr "type"   "floadsf")])
3343
3344 ;
3345 ; trunctfdf2 instruction pattern(s).
3346 ;
3347
3348 (define_expand "trunctfdf2"
3349   [(parallel 
3350     [(set (match_operand:DF 0 "register_operand" "")
3351           (float_truncate:DF (match_operand:TF 1 "register_operand" "")))
3352      (clobber (match_scratch:TF 2 "=f"))])]
3353   "TARGET_HARD_FLOAT"
3354   "")
3355
3356 (define_insn "*trunctfdf2_ieee"
3357   [(set (match_operand:DF 0 "register_operand" "=f")
3358         (float_truncate:DF (match_operand:TF 1 "register_operand" "f")))
3359    (clobber (match_scratch:TF 2 "=f"))]
3360   "TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT"
3361   "ldxbr\t%2,%1\;ldr\t%0,%2"
3362   [(set_attr "length" "6")
3363    (set_attr "type"   "ftrunctf")])   
3364
3365 (define_insn "*trunctfdf2_ibm"
3366   [(set (match_operand:DF 0 "register_operand" "=f")
3367         (float_truncate:DF (match_operand:TF 1 "register_operand" "f")))
3368    (clobber (match_scratch:TF 2 "=f"))]
3369   "TARGET_HARD_FLOAT && TARGET_IBM_FLOAT"
3370   "ldxr\t%2,%1\;ldr\t%0,%2"
3371   [(set_attr "length"  "4")
3372    (set_attr "type"   "ftrunctf")])
3373
3374 ;
3375 ; trunctfsf2 instruction pattern(s).
3376 ;
3377
3378 (define_expand "trunctfsf2"
3379   [(parallel 
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"
3384   "")
3385
3386 (define_insn "*trunctfsf2_ieee"
3387   [(set (match_operand:SF 0 "register_operand" "=f")
3388         (float_truncate:SF (match_operand:TF 1 "register_operand" "f")))
3389    (clobber (match_scratch:TF 2 "=f"))]
3390   "TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT"
3391   "lexbr\t%2,%1\;ler\t%0,%2"
3392   [(set_attr "length"  "6")
3393    (set_attr "type"   "ftrunctf")])
3394
3395 (define_insn "*trunctfsf2_ibm"
3396   [(set (match_operand:SF 0 "register_operand" "=f")
3397         (float_truncate:SF (match_operand:TF 1 "register_operand" "f")))
3398    (clobber (match_scratch:TF 2 "=f"))]
3399   "TARGET_HARD_FLOAT && TARGET_IBM_FLOAT"
3400   "lexr\t%2,%1\;ler\t%0,%2"
3401   [(set_attr "length"  "6")
3402    (set_attr "type"   "ftrunctf")])
3403
3404 ;
3405 ; extendsfdf2 instruction pattern(s).
3406 ;
3407
3408 (define_expand "extendsfdf2"
3409   [(set (match_operand:DF 0 "register_operand" "")
3410         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "")))]
3411   "TARGET_HARD_FLOAT"
3412 {
3413   if (TARGET_IBM_FLOAT)
3414     {
3415       emit_insn (gen_extendsfdf2_ibm (operands[0], operands[1]));
3416       DONE;
3417     }
3418 })
3419
3420 (define_insn "extendsfdf2_ieee"
3421   [(set (match_operand:DF 0 "register_operand" "=f,f")
3422         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand"  "f,R")))]
3423   "TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT"
3424   "@
3425    ldebr\t%0,%1
3426    ldeb\t%0,%1"
3427   [(set_attr "op_type"  "RRE,RXE")
3428    (set_attr "type"   "fsimpsf, floadsf")])
3429
3430 (define_insn "extendsfdf2_ibm"
3431   [(set (match_operand:DF 0 "register_operand" "=f,f")
3432         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "f,R")))
3433    (clobber (reg:CC CC_REGNUM))]
3434   "TARGET_HARD_FLOAT && TARGET_IBM_FLOAT"
3435   "@
3436    sdr\t%0,%0\;ler\t%0,%1
3437    sdr\t%0,%0\;le\t%0,%1"
3438   [(set_attr "length"   "4,6")
3439    (set_attr "type"     "floadsf")])
3440
3441 ;
3442 ; extenddftf2 instruction pattern(s).
3443 ;
3444
3445 (define_expand "extenddftf2"
3446   [(set (match_operand:TF 0 "register_operand" "")
3447         (float_extend:TF (match_operand:DF 1 "nonimmediate_operand" "")))]
3448   "TARGET_HARD_FLOAT"
3449   "")
3450
3451 (define_insn "*extenddftf2_ieee"
3452   [(set (match_operand:TF 0 "register_operand" "=f,f")
3453         (float_extend:TF (match_operand:DF 1 "nonimmediate_operand" "f,R")))]
3454   "TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT"
3455   "@
3456    lxdbr\t%0,%1
3457    lxdb\t%0,%1"
3458   [(set_attr "op_type"  "RRE,RXE")
3459    (set_attr "type"   "fsimptf, floadtf")])
3460
3461 (define_insn "*extenddftf2_ibm"
3462   [(set (match_operand:TF 0 "register_operand" "=f,f")
3463         (float_extend:TF (match_operand:DF 1 "nonimmediate_operand" "f,R")))]
3464   "TARGET_HARD_FLOAT && TARGET_IBM_FLOAT"
3465   "@
3466    lxdr\t%0,%1
3467    lxd\t%0,%1"
3468   [(set_attr "op_type"  "RRE,RXE")
3469    (set_attr "type"   "fsimptf, floadtf")])
3470
3471 ;
3472 ; extendsftf2 instruction pattern(s).
3473 ;
3474
3475 (define_expand "extendsftf2"
3476   [(set (match_operand:TF 0 "register_operand" "")
3477         (float_extend:TF (match_operand:SF 1 "nonimmediate_operand" "")))]
3478   "TARGET_HARD_FLOAT"
3479   "")
3480
3481 (define_insn "*extendsftf2_ieee"
3482   [(set (match_operand:TF 0 "register_operand" "=f,f")
3483         (float_extend:TF (match_operand:SF 1 "nonimmediate_operand" "f,R")))]
3484   "TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT"
3485   "@
3486    lxebr\t%0,%1
3487    lxeb\t%0,%1"
3488   [(set_attr "op_type"  "RRE,RXE")
3489    (set_attr "type"   "fsimptf, floadtf")])
3490
3491 (define_insn "*extendsftf2_ibm"
3492   [(set (match_operand:TF 0 "register_operand" "=f,f")
3493         (float_extend:TF (match_operand:SF 1 "nonimmediate_operand" "f,R")))]
3494   "TARGET_HARD_FLOAT && TARGET_IBM_FLOAT"
3495   "@
3496    lxer\t%0,%1
3497    lxe\t%0,%1"
3498   [(set_attr "op_type"  "RRE,RXE")
3499    (set_attr "type"   "fsimptf, floadtf")])
3500
3501
3502 ;;
3503 ;; ARITHMETIC OPERATIONS
3504 ;;
3505 ;  arithmetic operations set the ConditionCode,
3506 ;  because of unpredictable Bits in Register for Halfword and Byte
3507 ;  the ConditionCode can be set wrong in operations for Halfword and Byte
3508
3509 ;;
3510 ;;- Add instructions.
3511 ;;
3512
3513 ;
3514 ; addti3 instruction pattern(s).
3515 ;
3516
3517 (define_insn_and_split "addti3"
3518   [(set (match_operand:TI 0 "register_operand" "=&d")
3519         (plus:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
3520                  (match_operand:TI 2 "general_operand" "do") ) )
3521    (clobber (reg:CC CC_REGNUM))]
3522   "TARGET_64BIT"
3523   "#"
3524   "&& reload_completed"
3525   [(parallel
3526     [(set (reg:CCL1 CC_REGNUM)
3527           (compare:CCL1 (plus:DI (match_dup 7) (match_dup 8))
3528                         (match_dup 7)))
3529      (set (match_dup 6) (plus:DI (match_dup 7) (match_dup 8)))])
3530    (parallel
3531     [(set (match_dup 3) (plus:DI (plus:DI (match_dup 4) (match_dup 5))
3532                                  (ltu:DI (reg:CCL1 CC_REGNUM) (const_int 0))))
3533      (clobber (reg:CC CC_REGNUM))])]
3534   "operands[3] = operand_subword (operands[0], 0, 0, TImode);
3535    operands[4] = operand_subword (operands[1], 0, 0, TImode);
3536    operands[5] = operand_subword (operands[2], 0, 0, TImode);
3537    operands[6] = operand_subword (operands[0], 1, 0, TImode);
3538    operands[7] = operand_subword (operands[1], 1, 0, TImode);
3539    operands[8] = operand_subword (operands[2], 1, 0, TImode);")
3540
3541 ;