s390.md revision 107590
1107590Sobrien;;- Machine description for GNU compiler -- S/390 / zSeries version.
2107590Sobrien;;  Copyright (C) 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
3107590Sobrien;;  Contributed by Hartmut Penner (hpenner@de.ibm.com) and
4107590Sobrien;;                 Ulrich Weigand (uweigand@de.ibm.com).
5107590Sobrien;; This file is part of GNU CC.
6107590Sobrien
7107590Sobrien;; GNU CC is free software; you can redistribute it and/or modify
8107590Sobrien;; it under the terms of the GNU General Public License as published by
9107590Sobrien;; the Free Software Foundation; either version 2, or (at your option)
10107590Sobrien;; any later version.
11107590Sobrien
12107590Sobrien;; GNU CC is distributed in the hope that it will be useful,
13107590Sobrien;; but WITHOUT ANY WARRANTY; without even the implied warranty of
14107590Sobrien;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15107590Sobrien;; GNU General Public License for more details.
16107590Sobrien
17107590Sobrien;; You should have received a copy of the GNU General Public License
18107590Sobrien;; along with GNU CC; see the file COPYING.  If not, write to
19107590Sobrien;; the Free Software Foundation, 59 Temple Place - Suite 330,
20107590Sobrien;; Boston, MA 02111-1307, USA.
21107590Sobrien
22107590Sobrien;;
23107590Sobrien;; Special constraints for s/390 machine description:
24107590Sobrien;;
25107590Sobrien;;    a -- Any address register from 1 to 15.
26107590Sobrien;;    d -- Any register from 0 to 15.
27107590Sobrien;;    I -- An 8-bit constant (0..255).
28107590Sobrien;;    J -- A 12-bit constant (0..4095).
29107590Sobrien;;    K -- A 16-bit constant (-32768..32767).
30107590Sobrien;;    Q -- A memory reference without index-register.
31107590Sobrien;;    S -- Valid operand for the LARL instruction.
32107590Sobrien;;
33107590Sobrien;; Special formats used for outputting 390 instructions.
34107590Sobrien;;
35107590Sobrien;;   %b -- Print a constant byte integer.               xy
36107590Sobrien;;   %h -- Print a signed 16-bit.                       wxyz
37107590Sobrien;;   %N -- Print next register (second word of a DImode reg) or next word.
38107590Sobrien;;   %M -- Print next register (second word of a TImode reg) or next word.
39107590Sobrien;;   %O -- Print the offset of a memory reference (PLUS (REG) (CONST_INT)).
40107590Sobrien;;   %R -- Print the register of a memory reference (PLUS (REG) (CONST_INT)).
41107590Sobrien;;
42107590Sobrien;; We have a special constraint for pattern matching.
43107590Sobrien;;
44107590Sobrien;;   s_operand -- Matches a valid S operand in a RS, SI or SS type instruction.
45107590Sobrien;;
46107590Sobrien
47107590Sobrien
48107590Sobrien;; Define an insn type attribute.  This is used in function unit delay
49107590Sobrien;; computations.
50107590Sobrien
51107590Sobrien(define_attr "type" "none,integer,load,lr,la,lm,stm,cs,vs,store,imul,lmul,fmul,idiv,ldiv,fdiv,branch,jsr,other,o2,o3"
52107590Sobrien  (const_string "integer"))
53107590Sobrien
54107590Sobrien;; Insn are devide in two classes:
55107590Sobrien;;   mem: Insn accessing memory
56107590Sobrien;;   reg: Insn operands all in registers
57107590Sobrien
58107590Sobrien(define_attr "atype" "reg,mem"
59107590Sobrien  (const_string "reg"))
60107590Sobrien
61107590Sobrien;; Generic pipeline function unit.  
62107590Sobrien
63107590Sobrien(define_function_unit "integer" 1 0
64107590Sobrien  (eq_attr "type" "none") 0 0)
65107590Sobrien
66107590Sobrien(define_function_unit "integer" 1 0
67107590Sobrien  (eq_attr "type" "integer") 1 1)
68107590Sobrien
69107590Sobrien(define_function_unit "integer" 1 0
70107590Sobrien  (eq_attr "type" "load") 1 1)
71107590Sobrien
72107590Sobrien(define_function_unit "integer" 1 0
73107590Sobrien  (eq_attr "type" "la") 1 1)
74107590Sobrien
75107590Sobrien(define_function_unit "integer" 1 0
76107590Sobrien  (eq_attr "type" "lr") 1 1)
77107590Sobrien
78107590Sobrien(define_function_unit "integer" 1 0
79107590Sobrien  (eq_attr "type" "store") 1 1)
80107590Sobrien
81107590Sobrien(define_function_unit "integer" 1 0
82107590Sobrien  (eq_attr "type" "lm") 2 2)
83107590Sobrien
84107590Sobrien(define_function_unit "integer" 1 0
85107590Sobrien  (eq_attr "type" "stm") 2 2)
86107590Sobrien
87107590Sobrien(define_function_unit "integer" 1 0
88107590Sobrien  (eq_attr "type" "cs") 5 5)
89107590Sobrien
90107590Sobrien(define_function_unit "integer" 1 0
91107590Sobrien  (eq_attr "type" "vs") 30 30)
92107590Sobrien
93107590Sobrien(define_function_unit "integer" 1 0
94107590Sobrien  (eq_attr "type" "jsr") 5 5)
95107590Sobrien
96107590Sobrien(define_function_unit "integer" 1 0
97107590Sobrien  (eq_attr "type" "imul") 7 7)
98107590Sobrien
99107590Sobrien(define_function_unit "integer" 1 0
100107590Sobrien  (eq_attr "type" "fmul") 6 6)
101107590Sobrien
102107590Sobrien(define_function_unit "integer" 1 0
103107590Sobrien  (eq_attr "type" "idiv") 33 33)
104107590Sobrien
105107590Sobrien(define_function_unit "integer" 1 0
106107590Sobrien  (eq_attr "type" "fdiv") 33 33)
107107590Sobrien
108107590Sobrien(define_function_unit "integer" 1 0
109107590Sobrien  (eq_attr "type" "o2") 2 2)
110107590Sobrien
111107590Sobrien(define_function_unit "integer" 1 0
112107590Sobrien  (eq_attr "type" "o3") 3 3)
113107590Sobrien
114107590Sobrien(define_function_unit "integer" 1 0
115107590Sobrien  (eq_attr "type" "other") 5 5)
116107590Sobrien
117107590Sobrien;; Operand type. Used to default length attribute values
118107590Sobrien
119107590Sobrien(define_attr "op_type"
120107590Sobrien  "NN,E,RR,RRE,RX,RS,RSI,RI,SI,S,SS,SSE,RXE,RSE,RIL,RIE"
121107590Sobrien  (const_string "RX"))
122107590Sobrien
123107590Sobrien;; Length in bytes.
124107590Sobrien
125107590Sobrien(define_attr "length" ""
126107590Sobrien(cond [ (eq_attr "op_type" "E")    (const_int 2)
127107590Sobrien         (eq_attr "op_type" "RR")  (const_int 2)
128107590Sobrien         (eq_attr "op_type" "RX")  (const_int 4)
129107590Sobrien         (eq_attr "op_type" "RI")  (const_int 4)
130107590Sobrien         (eq_attr "op_type" "RRE") (const_int 4)
131107590Sobrien         (eq_attr "op_type" "RS")  (const_int 4)
132107590Sobrien         (eq_attr "op_type" "RSI") (const_int 4)
133107590Sobrien         (eq_attr "op_type" "RX")  (const_int 4)
134107590Sobrien         (eq_attr "op_type" "S")   (const_int 4)
135107590Sobrien         (eq_attr "op_type" "SI")  (const_int 4)
136107590Sobrien         (eq_attr "op_type" "SS")  (const_int 6)
137107590Sobrien         (eq_attr "op_type" "SSE") (const_int 6)
138107590Sobrien         (eq_attr "op_type" "RXE") (const_int 6)
139107590Sobrien         (eq_attr "op_type" "RSE") (const_int 6)
140107590Sobrien         (eq_attr "op_type" "RIL") (const_int 6)]
141107590Sobrien         (const_int 4)))
142107590Sobrien
143107590Sobrien;; Define attributes for `asm' insns.
144107590Sobrien
145107590Sobrien(define_asm_attributes [(set_attr "type" "other")
146107590Sobrien                        (set_attr "op_type" "NN")])
147107590Sobrien
148107590Sobrien;;
149107590Sobrien;;  Condition Codes
150107590Sobrien;;
151107590Sobrien;
152107590Sobrien;   CCL:  Zero     Nonzero   Zero      Nonzero      (AL, ALR, SL, SLR, N, NC, NI, NR, O, OC, OI, OR, X, XC, XI, XR)
153107590Sobrien;   CCA:  Zero     <Zero     >Zero     Overflow     (A, AR, AH, AHI, S, SR, SH, SHI, LTR, LCR, LNR, LPR, SLA, SLDA, SLA, SRDA)
154107590Sobrien;   CCU:  Equal    ULess     UGreater  --           (CL, CLR, CLI, CLM)
155107590Sobrien;   CCS:  Equal    SLess     SGreater  --           (C, CR, CH, CHI, ICM)
156107590Sobrien;   CCT:  Zero     Mixed     Mixed     Ones         (TM, TMH, TML)
157107590Sobrien 
158107590Sobrien;   CCZ  -> CCL / CCZ1
159107590Sobrien;   CCZ1 -> CCA/CCU/CCS/CCT
160107590Sobrien;   CCS  -> CCA
161107590Sobrien 
162107590Sobrien;   String:    CLC, CLCL, CLCLE, CLST, CUSE, MVCL, MVCLE, MVPG, MVST, SRST
163107590Sobrien;   Clobber:   CKSM, CFC, CS, CDS, CUUTF, CUTFU, PLO, SPM, STCK, STCKE, TS, TRT, TRE, UPT
164107590Sobrien
165107590Sobrien
166107590Sobrien;;
167107590Sobrien;;- Compare instructions.
168107590Sobrien;;
169107590Sobrien
170107590Sobrien(define_expand "cmpdi"
171107590Sobrien  [(set (reg:CC 33)
172107590Sobrien        (compare:CC (match_operand:DI 0 "register_operand" "")
173107590Sobrien                    (match_operand:DI 1 "general_operand" "")))]
174107590Sobrien  "TARGET_64BIT"
175107590Sobrien  "
176107590Sobrien{
177107590Sobrien  s390_compare_op0 = operands[0];
178107590Sobrien  s390_compare_op1 = operands[1];
179107590Sobrien  DONE;
180107590Sobrien}")
181107590Sobrien
182107590Sobrien(define_expand "cmpsi"
183107590Sobrien  [(set (reg:CC 33)
184107590Sobrien        (compare:CC (match_operand:SI 0 "register_operand" "")
185107590Sobrien                    (match_operand:SI 1 "general_operand" "")))]
186107590Sobrien  ""
187107590Sobrien  "
188107590Sobrien{
189107590Sobrien  s390_compare_op0 = operands[0];
190107590Sobrien  s390_compare_op1 = operands[1];
191107590Sobrien  DONE;
192107590Sobrien}")
193107590Sobrien
194107590Sobrien;(define_expand "cmphi"
195107590Sobrien;  [(set (reg:CC 33)
196107590Sobrien;        (compare:CC (match_operand:HI 0 "register_operand" "")
197107590Sobrien;                    (match_operand:HI 1 "general_operand" "")))]
198107590Sobrien;  ""
199107590Sobrien;  "
200107590Sobrien;{
201107590Sobrien;  s390_compare_op0 = operands[0];
202107590Sobrien;  s390_compare_op1 = operands[1];
203107590Sobrien;  DONE;
204107590Sobrien;}")
205107590Sobrien
206107590Sobrien;(define_expand "cmpqi"
207107590Sobrien;  [(set (reg:CC 33)
208107590Sobrien;        (compare:CC (match_operand:QI 0 "register_operand" "")
209107590Sobrien;                    (match_operand:QI 1 "general_operand" "")))]
210107590Sobrien;  ""
211107590Sobrien;  "
212107590Sobrien;{
213107590Sobrien;  s390_compare_op0 = operands[0];
214107590Sobrien;  s390_compare_op1 = operands[1];
215107590Sobrien;  DONE;
216107590Sobrien;}")
217107590Sobrien
218107590Sobrien(define_expand "cmpdf"
219107590Sobrien  [(set (reg:CC 33)
220107590Sobrien        (compare:CC (match_operand:DF 0 "register_operand" "")
221107590Sobrien                    (match_operand:DF 1 "general_operand" "")))]
222107590Sobrien  "TARGET_HARD_FLOAT"
223107590Sobrien  "
224107590Sobrien{
225107590Sobrien  s390_compare_op0 = operands[0];
226107590Sobrien  s390_compare_op1 = operands[1];
227107590Sobrien  DONE;
228107590Sobrien}")
229107590Sobrien
230107590Sobrien(define_expand "cmpsf"
231107590Sobrien  [(set (reg:CC 33)
232107590Sobrien        (compare:CC (match_operand:SF 0 "register_operand" "")
233107590Sobrien                    (match_operand:SF 1 "general_operand" "")))]
234107590Sobrien  "TARGET_HARD_FLOAT"
235107590Sobrien  "
236107590Sobrien{
237107590Sobrien  s390_compare_op0 = operands[0];
238107590Sobrien  s390_compare_op1 = operands[1];
239107590Sobrien  DONE;
240107590Sobrien}")
241107590Sobrien
242107590Sobrien
243107590Sobrien; DI instructions
244107590Sobrien
245107590Sobrien(define_insn "*cmpdi_tm2"
246107590Sobrien  [(set (reg 33)
247107590Sobrien        (compare (zero_extract:DI (match_operand:DI 0 "register_operand" "d")
248107590Sobrien	                          (match_operand:DI 1 "const_int_operand" "n")
249107590Sobrien                                  (match_operand:DI 2 "const_int_operand" "n"))
250107590Sobrien                 (const_int 0)))]
251107590Sobrien  "s390_match_ccmode(insn, CCTmode) && TARGET_64BIT
252107590Sobrien   && INTVAL (operands[1]) >= 1 && INTVAL (operands[2]) >= 0 
253107590Sobrien   && INTVAL (operands[1]) + INTVAL (operands[2]) <= 64
254107590Sobrien   && (INTVAL (operands[1]) + INTVAL (operands[2]) - 1) >> 4
255107590Sobrien      == INTVAL (operands[2]) >> 4"
256107590Sobrien  "*
257107590Sobrien{
258107590Sobrien  int part = INTVAL (operands[2]) >> 4;
259107590Sobrien  int block = (1 << INTVAL (operands[1])) - 1;
260107590Sobrien  int shift = 16 - INTVAL (operands[1]) - (INTVAL (operands[2]) & 15);
261107590Sobrien
262107590Sobrien  operands[2] = GEN_INT (block << shift);
263107590Sobrien
264107590Sobrien  switch (part)
265107590Sobrien    {
266107590Sobrien      case 0: return \"tmhh\\t%0,%x2\";
267107590Sobrien      case 1: return \"tmhl\\t%0,%x2\";
268107590Sobrien      case 2: return \"tmlh\\t%0,%x2\";
269107590Sobrien      case 3: return \"tmll\\t%0,%x2\";
270107590Sobrien      default: abort ();
271107590Sobrien    }
272107590Sobrien}"
273107590Sobrien  [(set_attr "op_type" "RI")])
274107590Sobrien
275107590Sobrien(define_insn "*cmpdi_tm_reg"
276107590Sobrien  [(set (reg 33)
277107590Sobrien        (compare (and:DI (match_operand:DI 0 "register_operand" "%d")
278107590Sobrien                         (match_operand:DI 1 "immediate_operand" "n"))
279107590Sobrien                 (const_int 0)))]
280107590Sobrien  "s390_match_ccmode(insn, CCTmode) && TARGET_64BIT
281107590Sobrien   && s390_single_hi (operands[1], DImode, 0) >= 0"
282107590Sobrien  "*
283107590Sobrien{
284107590Sobrien  int part = s390_single_hi (operands[1], DImode, 0);
285107590Sobrien  operands[1] = GEN_INT (s390_extract_hi (operands[1], DImode, part));
286107590Sobrien
287107590Sobrien  switch (part)
288107590Sobrien    {
289107590Sobrien      case 0: return \"tmhh\\t%0,%x1\";
290107590Sobrien      case 1: return \"tmhl\\t%0,%x1\";
291107590Sobrien      case 2: return \"tmlh\\t%0,%x1\";
292107590Sobrien      case 3: return \"tmll\\t%0,%x1\";
293107590Sobrien      default: abort ();
294107590Sobrien    }
295107590Sobrien}"
296107590Sobrien  [(set_attr "op_type" "RI")])
297107590Sobrien
298107590Sobrien(define_insn "*cmpdi_tm_mem"
299107590Sobrien  [(set (reg 33)
300107590Sobrien        (compare (and:DI (match_operand:DI 0 "s_operand" "%Qo")
301107590Sobrien                         (match_operand:DI 1 "immediate_operand" "n"))
302107590Sobrien                 (const_int 0)))]
303107590Sobrien  "s390_match_ccmode(insn, CCTmode) && TARGET_64BIT
304107590Sobrien   && s390_single_qi (operands[1], DImode, 0) >= 0"
305107590Sobrien  "*
306107590Sobrien{
307107590Sobrien  int part = s390_single_qi (operands[1], DImode, 0);
308107590Sobrien  operands[1] = GEN_INT (s390_extract_qi (operands[1], DImode, part));
309107590Sobrien
310107590Sobrien  operands[0] = gen_rtx_MEM (QImode, 
311107590Sobrien			     plus_constant (XEXP (operands[0], 0), part));
312107590Sobrien  return \"tm\\t%0,%b1\";
313107590Sobrien}"
314107590Sobrien  [(set_attr "op_type" "SI")
315107590Sobrien   (set_attr "atype"   "mem")])
316107590Sobrien
317107590Sobrien(define_insn "*ltgr"
318107590Sobrien  [(set (reg 33)
319107590Sobrien        (compare (match_operand:DI 0 "register_operand" "d")
320107590Sobrien                 (match_operand:DI 1 "const0_operand" "")))
321107590Sobrien   (set (match_operand:DI 2 "register_operand" "=d")
322107590Sobrien        (match_dup 0))]
323107590Sobrien  "s390_match_ccmode(insn, CCSmode) && TARGET_64BIT"
324107590Sobrien  "ltgr\\t%2,%0"
325107590Sobrien  [(set_attr "op_type" "RRE")])
326107590Sobrien
327107590Sobrien(define_insn "*cmpdi_ccs_0_64"
328107590Sobrien  [(set (reg 33)
329107590Sobrien        (compare (match_operand:DI 0 "register_operand" "d")
330107590Sobrien                 (match_operand:DI 1 "const0_operand" "")))]
331107590Sobrien  "s390_match_ccmode(insn, CCSmode) && TARGET_64BIT"
332107590Sobrien  "ltgr\\t%0,%0"
333107590Sobrien  [(set_attr "op_type" "RRE")])
334107590Sobrien
335107590Sobrien(define_insn "*cmpdi_ccs_0_31"
336107590Sobrien  [(set (reg 33)
337107590Sobrien        (compare (match_operand:DI 0 "register_operand" "d")
338107590Sobrien                 (match_operand:DI 1 "const0_operand" "")))]
339107590Sobrien  "s390_match_ccmode(insn, CCSmode)"
340107590Sobrien  "srda\\t%0,0"
341107590Sobrien  [(set_attr "op_type" "RS")])
342107590Sobrien
343107590Sobrien(define_insn "*cmpdi_ccs"
344107590Sobrien  [(set (reg 33)
345107590Sobrien        (compare (match_operand:DI 0 "register_operand" "d,d,d")
346107590Sobrien                 (match_operand:DI 1 "general_operand" "d,K,m")))]
347107590Sobrien  "s390_match_ccmode(insn, CCSmode) && TARGET_64BIT"
348107590Sobrien  "@
349107590Sobrien   cgr\\t%0,%1
350107590Sobrien   cghi\\t%0,%c1
351107590Sobrien   cg\\t%0,%1"
352107590Sobrien  [(set_attr "op_type" "RRE,RI,RXE")
353107590Sobrien   (set_attr "atype"    "reg,reg,mem")])
354107590Sobrien   
355107590Sobrien(define_insn "*cmpdi_ccu"
356107590Sobrien  [(set (reg 33)
357107590Sobrien        (compare (match_operand:DI 0 "register_operand" "d,d")
358107590Sobrien                 (match_operand:DI 1 "general_operand" "d,m")))]
359107590Sobrien  "s390_match_ccmode(insn, CCUmode) && TARGET_64BIT"
360107590Sobrien  "@
361107590Sobrien   clgr\\t%0,%1
362107590Sobrien   clg\\t%0,%1"
363107590Sobrien  [(set_attr "op_type" "RRE,RXE")
364107590Sobrien   (set_attr "atype"   "reg,mem")])
365107590Sobrien
366107590Sobrien(define_insn "*cmpdi_ccu_mem"
367107590Sobrien  [(set (reg 33)
368107590Sobrien        (compare (match_operand:DI 0 "s_operand" "oQ")
369107590Sobrien                 (match_operand:DI 1 "s_imm_operand" "oQ")))]
370107590Sobrien  "s390_match_ccmode(insn, CCUmode)"
371107590Sobrien  "clc\\t%O0(8,%R0),%1"
372107590Sobrien  [(set_attr "op_type" "SS")
373107590Sobrien   (set_attr "atype"   "mem")])
374107590Sobrien
375107590Sobrien; SI instructions
376107590Sobrien
377107590Sobrien(define_insn "*cmpsi_tm2"
378107590Sobrien  [(set (reg 33)
379107590Sobrien        (compare (zero_extract:SI (match_operand:SI 0 "register_operand" "d")
380107590Sobrien	                          (match_operand:SI 1 "const_int_operand" "n")
381107590Sobrien                                  (match_operand:SI 2 "const_int_operand" "n"))
382107590Sobrien                 (const_int 0)))]
383107590Sobrien  "s390_match_ccmode(insn, CCTmode)
384107590Sobrien   && INTVAL (operands[1]) >= 1 && INTVAL (operands[2]) >= 0 
385107590Sobrien   && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
386107590Sobrien   && (INTVAL (operands[1]) + INTVAL (operands[2]) - 1) >> 4
387107590Sobrien      == INTVAL (operands[2]) >> 4"
388107590Sobrien  "*
389107590Sobrien{
390107590Sobrien  int part = INTVAL (operands[2]) >> 4;
391107590Sobrien  int block = (1 << INTVAL (operands[1])) - 1;
392107590Sobrien  int shift = 16 - INTVAL (operands[1]) - (INTVAL (operands[2]) & 15);
393107590Sobrien
394107590Sobrien  operands[2] = GEN_INT (block << shift);
395107590Sobrien
396107590Sobrien  switch (part)
397107590Sobrien    {
398107590Sobrien      case 0: return \"tmh\\t%0,%x2\";
399107590Sobrien      case 1: return \"tml\\t%0,%x2\";
400107590Sobrien      default: abort ();
401107590Sobrien    }
402107590Sobrien}"
403107590Sobrien  [(set_attr "op_type" "RI")])
404107590Sobrien
405107590Sobrien(define_insn "*cmpsi_tm_reg"
406107590Sobrien  [(set (reg 33)
407107590Sobrien        (compare (and:SI (match_operand:SI 0 "register_operand" "%d")
408107590Sobrien                         (match_operand:SI 1 "immediate_operand" "n"))
409107590Sobrien                 (const_int 0)))]
410107590Sobrien  "s390_match_ccmode(insn, CCTmode)
411107590Sobrien   && s390_single_hi (operands[1], SImode, 0) >= 0"
412107590Sobrien  "*
413107590Sobrien{
414107590Sobrien  int part = s390_single_hi (operands[1], SImode, 0);
415107590Sobrien  operands[1] = GEN_INT (s390_extract_hi (operands[1], SImode, part));
416107590Sobrien
417107590Sobrien  switch (part)
418107590Sobrien    {
419107590Sobrien      case 0: return \"tmh\\t%0,%x1\";
420107590Sobrien      case 1: return \"tml\\t%0,%x1\";
421107590Sobrien      default: abort ();
422107590Sobrien    }
423107590Sobrien}"
424107590Sobrien  [(set_attr "op_type" "RI")])
425107590Sobrien
426107590Sobrien(define_insn "*cmpsi_tm_mem"
427107590Sobrien  [(set (reg 33)
428107590Sobrien        (compare (and:SI (match_operand:SI 0 "s_operand" "%Qo")
429107590Sobrien                         (match_operand:SI 1 "immediate_operand" "n"))
430107590Sobrien                 (const_int 0)))]
431107590Sobrien  "s390_match_ccmode(insn, CCTmode)
432107590Sobrien   && s390_single_qi (operands[1], SImode, 0) >= 0"
433107590Sobrien  "*
434107590Sobrien{
435107590Sobrien  int part = s390_single_qi (operands[1], SImode, 0);
436107590Sobrien  operands[1] = GEN_INT (s390_extract_qi (operands[1], SImode, part));
437107590Sobrien
438107590Sobrien  operands[0] = gen_rtx_MEM (QImode, 
439107590Sobrien			     plus_constant (XEXP (operands[0], 0), part));
440107590Sobrien  return \"tm\\t%0,%b1\";
441107590Sobrien}"
442107590Sobrien  [(set_attr "op_type" "SI")
443107590Sobrien   (set_attr "atype"   "mem")])
444107590Sobrien
445107590Sobrien(define_insn "*ltr"
446107590Sobrien  [(set (reg 33)
447107590Sobrien        (compare (match_operand:SI 0 "register_operand" "d")
448107590Sobrien                 (match_operand:SI 1 "const0_operand" "")))
449107590Sobrien   (set (match_operand:SI 2 "register_operand" "=d")
450107590Sobrien        (match_dup 0))]
451107590Sobrien  "s390_match_ccmode(insn, CCSmode)"
452107590Sobrien  "ltr\\t%2,%0"
453107590Sobrien  [(set_attr "op_type" "RR")])
454107590Sobrien
455107590Sobrien(define_insn "*icm15"
456107590Sobrien  [(set (reg 33)
457107590Sobrien        (compare (match_operand:SI 0 "s_operand" "Qo")
458107590Sobrien                 (match_operand:SI 1 "const0_operand" "")))
459107590Sobrien   (set (match_operand:SI 2 "register_operand" "=d")
460107590Sobrien        (match_dup 0))]
461107590Sobrien  "s390_match_ccmode(insn, CCSmode)"
462107590Sobrien  "icm\\t%2,15,%0"
463107590Sobrien  [(set_attr "op_type" "RS")
464107590Sobrien   (set_attr "atype"   "mem")])
465107590Sobrien
466107590Sobrien(define_insn "*icm15_cconly"
467107590Sobrien  [(set (reg 33)
468107590Sobrien        (compare (match_operand:SI 0 "s_operand" "Qo")
469107590Sobrien                 (match_operand:SI 1 "const0_operand" "")))
470107590Sobrien   (clobber (match_scratch:SI 2 "=d"))]
471107590Sobrien  "s390_match_ccmode(insn, CCSmode)"
472107590Sobrien  "icm\\t%2,15,%0"
473107590Sobrien  [(set_attr "op_type" "RS")
474107590Sobrien   (set_attr "atype"   "mem")])
475107590Sobrien
476107590Sobrien(define_insn "*cmpsi_ccs_0"
477107590Sobrien  [(set (reg 33)
478107590Sobrien        (compare (match_operand:SI 0 "register_operand" "d")
479107590Sobrien                 (match_operand:SI 1 "const0_operand" "")))]
480107590Sobrien  "s390_match_ccmode(insn, CCSmode)"
481107590Sobrien  "ltr\\t%0,%0"
482107590Sobrien  [(set_attr "op_type" "RR")])
483107590Sobrien
484107590Sobrien(define_insn "*cmpsidi_ccs"
485107590Sobrien  [(set (reg 33)
486107590Sobrien        (compare (match_operand:SI 0 "register_operand" "d")
487107590Sobrien                 (sign_extend:SI (match_operand:HI 1 "memory_operand" "m"))))]
488107590Sobrien  "s390_match_ccmode(insn, CCSmode)"
489107590Sobrien  "ch\\t%0,%1"
490107590Sobrien  [(set_attr "op_type" "RR")
491107590Sobrien   (set_attr "atype"   "mem")])
492107590Sobrien
493107590Sobrien(define_insn "*cmpsi_ccs"
494107590Sobrien  [(set (reg 33)
495107590Sobrien        (compare (match_operand:SI 0 "register_operand" "d,d,d")
496107590Sobrien                 (match_operand:SI 1 "general_operand" "d,K,m")))]
497107590Sobrien  "s390_match_ccmode(insn, CCSmode)"
498107590Sobrien  "@
499107590Sobrien   cr\\t%0,%1
500107590Sobrien   chi\\t%0,%c1
501107590Sobrien   c\\t%0,%1"
502107590Sobrien  [(set_attr "op_type" "RR,RI,RX")
503107590Sobrien   (set_attr "atype"   "reg,reg,mem")])
504107590Sobrien   
505107590Sobrien(define_insn "*cmpsi_ccu"
506107590Sobrien  [(set (reg 33)
507107590Sobrien        (compare (match_operand:SI 0 "register_operand" "d,d")
508107590Sobrien                 (match_operand:SI 1 "general_operand" "d,m")))]
509107590Sobrien  "s390_match_ccmode(insn, CCUmode)"
510107590Sobrien  "@
511107590Sobrien   clr\\t%0,%1
512107590Sobrien   cl\\t%0,%1"
513107590Sobrien  [(set_attr "op_type" "RR,RX")
514107590Sobrien   (set_attr "atype"   "reg,mem")])
515107590Sobrien
516107590Sobrien(define_insn "*cmpsi_ccu_mem"
517107590Sobrien  [(set (reg 33)
518107590Sobrien        (compare (match_operand:SI 0 "s_operand" "oQ")
519107590Sobrien                 (match_operand:SI 1 "s_imm_operand" "oQ")))]
520107590Sobrien  "s390_match_ccmode(insn, CCUmode)"
521107590Sobrien  "clc\\t%O0(4,%R0),%1"
522107590Sobrien   [(set_attr "op_type" "SS")
523107590Sobrien    (set_attr "atype"   "mem")])
524107590Sobrien
525107590Sobrien
526107590Sobrien; HI instructions
527107590Sobrien
528107590Sobrien(define_insn "*cmphi_tm_sub"
529107590Sobrien  [(set (reg 33)
530107590Sobrien        (compare (and:SI (subreg:SI (match_operand:HI 0 "s_operand" "%Qo") 0)
531107590Sobrien                         (match_operand:SI 1 "immediate_operand" "n"))
532107590Sobrien                 (const_int 0)))]
533107590Sobrien  "s390_match_ccmode(insn, CCTmode)
534107590Sobrien   && s390_single_qi (operands[1], HImode, 0) >= 0"
535107590Sobrien  "*
536107590Sobrien{
537107590Sobrien  int part = s390_single_qi (operands[1], HImode, 0);
538107590Sobrien  operands[1] = GEN_INT (s390_extract_qi (operands[1], HImode, part));
539107590Sobrien
540107590Sobrien  operands[0] = gen_rtx_MEM (QImode, 
541107590Sobrien			     plus_constant (XEXP (operands[0], 0), part));
542107590Sobrien  return \"tm\\t%0,%b1\";
543107590Sobrien}"
544107590Sobrien  [(set_attr "op_type" "SI")
545107590Sobrien   (set_attr "atype"   "mem")])
546107590Sobrien
547107590Sobrien(define_insn "*icm3"
548107590Sobrien  [(set (reg 33)
549107590Sobrien        (compare (match_operand:HI 0 "s_operand" "Qo")
550107590Sobrien                 (match_operand:HI 1 "const0_operand" "")))
551107590Sobrien   (set (match_operand:HI 2 "register_operand" "=d")
552107590Sobrien        (match_dup 0))]
553107590Sobrien  "s390_match_ccmode(insn, CCSmode)"
554107590Sobrien  "icm\\t%2,3,%0"
555107590Sobrien  [(set_attr "op_type" "RS")
556107590Sobrien   (set_attr "atype"   "mem")])
557107590Sobrien
558107590Sobrien(define_insn "*cmphi_cct_0"
559107590Sobrien  [(set (reg 33)
560107590Sobrien        (compare (match_operand:HI 0 "register_operand" "d")
561107590Sobrien                 (match_operand:HI 1 "const0_operand"   "")))]
562107590Sobrien  "s390_match_ccmode(insn, CCTmode)"
563107590Sobrien  "tml\\t%0,65535"
564107590Sobrien  [(set_attr "op_type" "RX")])
565107590Sobrien
566107590Sobrien(define_insn "*cmphi_ccs_0"
567107590Sobrien  [(set (reg 33)
568107590Sobrien        (compare (match_operand:HI 0 "s_operand" "Qo")
569107590Sobrien                 (match_operand:HI 1 "const0_operand" "")))
570107590Sobrien   (clobber (match_scratch:HI 2 "=d"))]
571107590Sobrien  "s390_match_ccmode(insn, CCSmode)"
572107590Sobrien  "icm\\t%2,3,%0"
573107590Sobrien  [(set_attr "op_type" "RS")
574107590Sobrien   (set_attr "atype"   "mem")])
575107590Sobrien
576107590Sobrien(define_insn "*cmphi_ccu"
577107590Sobrien  [(set (reg 33)
578107590Sobrien        (compare (match_operand:HI 0 "register_operand" "d")
579107590Sobrien                 (match_operand:HI 1 "s_imm_operand" "Qo")))]
580107590Sobrien  "s390_match_ccmode(insn, CCUmode)"
581107590Sobrien  "clm\\t%0,3,%1"
582107590Sobrien  [(set_attr "op_type" "RS")
583107590Sobrien   (set_attr "atype"   "mem")])
584107590Sobrien
585107590Sobrien(define_insn "*cmphi_ccu_mem"
586107590Sobrien  [(set (reg 33)
587107590Sobrien        (compare (match_operand:HI 0 "s_operand" "oQ")
588107590Sobrien                 (match_operand:HI 1 "s_imm_operand" "oQ")))]
589107590Sobrien  "s390_match_ccmode(insn, CCUmode)"
590107590Sobrien  "clc\\t%O0(2,%R0),%1"
591107590Sobrien  [(set_attr "op_type" "SS")
592107590Sobrien   (set_attr "atype"   "mem")])
593107590Sobrien
594107590Sobrien
595107590Sobrien; QI instructions
596107590Sobrien
597107590Sobrien(define_insn "*cmpqi_tm2"
598107590Sobrien  [(set (reg 33)
599107590Sobrien        (compare (zero_extract:SI (match_operand:QI 0 "s_operand" "Qo")
600107590Sobrien	                          (match_operand:SI 1 "const_int_operand" "n")
601107590Sobrien                                  (match_operand:SI 2 "const_int_operand" "n"))
602107590Sobrien                 (const_int 0)))]
603107590Sobrien  "s390_match_ccmode(insn, CCTmode)
604107590Sobrien   && INTVAL (operands[1]) >= 1 && INTVAL (operands[2]) >= 0 
605107590Sobrien   && INTVAL (operands[1]) + INTVAL (operands[2]) <= 8"
606107590Sobrien  "*
607107590Sobrien{
608107590Sobrien  int block = (1 << INTVAL (operands[1])) - 1;
609107590Sobrien  int shift = 8 - INTVAL (operands[1]) - INTVAL (operands[2]);
610107590Sobrien
611107590Sobrien  operands[2] = GEN_INT (block << shift);
612107590Sobrien  return \"tm\\t%0,%b2\";
613107590Sobrien}"
614107590Sobrien  [(set_attr "op_type" "SI")
615107590Sobrien   (set_attr "atype"   "mem")])
616107590Sobrien
617107590Sobrien(define_insn "*cmpqi_tm"
618107590Sobrien  [(set (reg 33)
619107590Sobrien        (compare (and:QI (match_operand:QI 0 "nonimmediate_operand" "%d,Q")
620107590Sobrien                         (match_operand:QI 1 "immediate_operand" "n,n"))
621107590Sobrien                 (const_int 0)))]
622107590Sobrien  "s390_match_ccmode(insn, CCTmode)"
623107590Sobrien  "@
624107590Sobrien   tml\\t%0,%b1
625107590Sobrien   tm\\t%0,%b1"
626107590Sobrien  [(set_attr "op_type" "RI,SI")
627107590Sobrien   (set_attr "atype"   "reg,mem")])
628107590Sobrien
629107590Sobrien(define_insn "*cmpqi_tm_sub"
630107590Sobrien  [(set (reg 33)
631107590Sobrien        (compare (and:SI (subreg:SI (match_operand:QI 0 "s_operand" "%Qo") 0)
632107590Sobrien                         (match_operand:SI 1 "immediate_operand" "n"))
633107590Sobrien                 (const_int 0)))]
634107590Sobrien  "s390_match_ccmode(insn, CCTmode)"
635107590Sobrien  "tm\\t%0,%b1"
636107590Sobrien  [(set_attr "op_type" "SI")
637107590Sobrien   (set_attr "atype"   "mem")])
638107590Sobrien
639107590Sobrien(define_insn "*icm1"
640107590Sobrien  [(set (reg 33)
641107590Sobrien        (compare (match_operand:QI 0 "s_operand" "Qo")
642107590Sobrien                 (match_operand:QI 1 "const0_operand" "")))
643107590Sobrien   (set (match_operand:QI 2 "register_operand" "=d")
644107590Sobrien        (match_dup 0))]
645107590Sobrien  "s390_match_ccmode(insn, CCSmode)"
646107590Sobrien  "icm\\t%2,1,%0"
647107590Sobrien  [(set_attr "op_type" "RS")
648107590Sobrien   (set_attr "atype"   "mem")])
649107590Sobrien
650107590Sobrien(define_insn "*tm_0"
651107590Sobrien  [(set (reg 33)
652107590Sobrien        (compare (zero_extend:SI (and:QI (match_operand:QI 0 "s_operand" "Qo")
653107590Sobrien                                         (match_operand:QI 1 "immediate_operand" "")))
654107590Sobrien                 (const_int 0)))]
655107590Sobrien  "s390_match_ccmode(insn, CCTmode) &&
656107590Sobrien   INTVAL(operands[1]) >= 0 && INTVAL(operands[1]) < 256"
657107590Sobrien  "tm\\t%0,%1"
658107590Sobrien  [(set_attr "op_type" "RI")
659107590Sobrien   (set_attr "atype"   "mem")])
660107590Sobrien
661107590Sobrien(define_insn "*cmpqi_cct_0"
662107590Sobrien  [(set (reg 33)
663107590Sobrien        (compare (match_operand:QI 0 "register_operand" "d")
664107590Sobrien                 (match_operand:QI 1 "const0_operand"   "")))]
665107590Sobrien  "s390_match_ccmode(insn, CCTmode)"
666107590Sobrien  "tml\\t%0,255"
667107590Sobrien  [(set_attr "op_type" "RI")])
668107590Sobrien
669107590Sobrien(define_insn "*cmpqi_ccs_0"
670107590Sobrien  [(set (reg 33)
671107590Sobrien        (compare (match_operand:QI 0 "s_operand" "Qo")
672107590Sobrien                 (match_operand:QI 1 "const0_operand" "")))
673107590Sobrien   (clobber (match_scratch:QI 2 "=d"))]
674107590Sobrien  "s390_match_ccmode(insn, CCSmode)"
675107590Sobrien  "icm\\t%2,1,%0"
676107590Sobrien  [(set_attr "op_type" "RS")
677107590Sobrien   (set_attr "atype"   "mem")])
678107590Sobrien
679107590Sobrien(define_insn "*cmpqi_ccu_0"
680107590Sobrien  [(set (reg 33)
681107590Sobrien        (compare (match_operand:QI 0 "s_operand"      "Qo")
682107590Sobrien                 (match_operand:QI 1 "const0_operand" "")))]
683107590Sobrien  "s390_match_ccmode(insn, CCUmode)"
684107590Sobrien  "cli\\t%0,0"
685107590Sobrien  [(set_attr "op_type" "SI")
686107590Sobrien   (set_attr "atype"   "mem")])
687107590Sobrien
688107590Sobrien(define_insn "*cmpqi_ccu"
689107590Sobrien  [(set (reg 33)
690107590Sobrien        (compare (match_operand:QI 0 "register_operand" "d")
691107590Sobrien                 (match_operand:QI 1 "s_imm_operand" "Qo")))]
692107590Sobrien  "s390_match_ccmode(insn, CCUmode)"
693107590Sobrien  "clm\\t%0,1,%1"
694107590Sobrien  [(set_attr "op_type" "RS")
695107590Sobrien   (set_attr "atype"   "mem")])
696107590Sobrien
697107590Sobrien(define_insn "*cmpqi_ccu_immed"
698107590Sobrien  [(set (reg 33)
699107590Sobrien        (compare (match_operand:QI 0 "s_operand" "Qo")
700107590Sobrien                 (match_operand:QI 1 "const_int_operand" "n")))]
701107590Sobrien  "s390_match_ccmode(insn, CCUmode) &&
702107590Sobrien   INTVAL(operands[1]) >= 0 && INTVAL(operands[1]) < 256"
703107590Sobrien  "cli\\t%0,%1"
704107590Sobrien  [(set_attr "op_type" "SI")
705107590Sobrien   (set_attr "atype"   "mem")])
706107590Sobrien
707107590Sobrien(define_insn "*cmpqi_ccu_mem"
708107590Sobrien  [(set (reg 33)
709107590Sobrien        (compare (match_operand:QI 0 "s_operand" "oQ")
710107590Sobrien                 (match_operand:QI 1 "s_imm_operand" "oQ")))]
711107590Sobrien  "s390_match_ccmode(insn, CCUmode)"
712107590Sobrien  "clc\\t%O0(1,%R0),%1"
713107590Sobrien  [(set_attr "op_type" "SS")
714107590Sobrien   (set_attr "atype"   "mem")])
715107590Sobrien
716107590Sobrien
717107590Sobrien; DF instructions
718107590Sobrien
719107590Sobrien(define_insn "*cmpdf_ccs_0"
720107590Sobrien  [(set (reg 33)
721107590Sobrien        (compare (match_operand:DF 0 "register_operand" "f")
722107590Sobrien                 (match_operand:DF 1 "const0_operand" "")))]
723107590Sobrien  "s390_match_ccmode(insn, CCSmode) && TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT"
724107590Sobrien  "ltdbr\\t%0,%0"
725107590Sobrien   [(set_attr "op_type" "RRE")])
726107590Sobrien
727107590Sobrien(define_insn "*cmpdf_ccs_0_ibm"
728107590Sobrien  [(set (reg 33)
729107590Sobrien        (compare (match_operand:DF 0 "register_operand" "f")
730107590Sobrien                 (match_operand:DF 1 "const0_operand" "")))]
731107590Sobrien  "s390_match_ccmode(insn, CCSmode) && TARGET_HARD_FLOAT && TARGET_IBM_FLOAT"
732107590Sobrien  "ltdr\\t%0,%0"
733107590Sobrien   [(set_attr "op_type" "RR")])
734107590Sobrien
735107590Sobrien(define_insn "*cmpdf_ccs"
736107590Sobrien  [(set (reg 33)
737107590Sobrien        (compare (match_operand:DF 0 "register_operand" "f,f")
738107590Sobrien                 (match_operand:DF 1 "general_operand" "f,m")))]
739107590Sobrien  "s390_match_ccmode(insn, CCSmode) && TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT"
740107590Sobrien  "@
741107590Sobrien   cdbr\\t%0,%1
742107590Sobrien   cdb\\t%0,%1"
743107590Sobrien   [(set_attr "op_type" "RRE,RXE")
744107590Sobrien    (set_attr "atype"   "reg,mem")])  
745107590Sobrien
746107590Sobrien(define_insn "*cmpdf_ccs_ibm"
747107590Sobrien  [(set (reg 33)
748107590Sobrien        (compare (match_operand:DF 0 "register_operand" "f,f")
749107590Sobrien                 (match_operand:DF 1 "general_operand" "f,m")))]
750107590Sobrien  "s390_match_ccmode(insn, CCSmode) && TARGET_HARD_FLOAT && TARGET_IBM_FLOAT"
751107590Sobrien  "@
752107590Sobrien   cdr\\t%0,%1
753107590Sobrien   cd\\t%0,%1"
754107590Sobrien   [(set_attr "op_type" "RR,RX")
755107590Sobrien    (set_attr "atype"   "reg,mem")])  
756107590Sobrien
757107590Sobrien
758107590Sobrien; SF instructions
759107590Sobrien
760107590Sobrien(define_insn "*cmpsf_ccs_0"
761107590Sobrien  [(set (reg 33)
762107590Sobrien        (compare (match_operand:SF 0 "register_operand" "f")
763107590Sobrien                 (match_operand:SF 1 "const0_operand" "")))]
764107590Sobrien  "s390_match_ccmode(insn, CCSmode) && TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT"
765107590Sobrien  "ltebr\\t%0,%0"
766107590Sobrien   [(set_attr "op_type" "RRE")])
767107590Sobrien
768107590Sobrien(define_insn "*cmpsf_ccs_0_ibm"
769107590Sobrien  [(set (reg 33)
770107590Sobrien        (compare (match_operand:SF 0 "register_operand" "f")
771107590Sobrien                 (match_operand:SF 1 "const0_operand" "")))]
772107590Sobrien  "s390_match_ccmode(insn, CCSmode) && TARGET_HARD_FLOAT && TARGET_IBM_FLOAT"
773107590Sobrien  "lter\\t%0,%0"
774107590Sobrien   [(set_attr "op_type" "RR")])
775107590Sobrien
776107590Sobrien(define_insn "*cmpsf_ccs"
777107590Sobrien  [(set (reg 33)
778107590Sobrien        (compare (match_operand:SF 0 "register_operand" "f,f")
779107590Sobrien                 (match_operand:SF 1 "general_operand" "f,m")))]
780107590Sobrien  "s390_match_ccmode(insn, CCSmode) && TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT"
781107590Sobrien  "@
782107590Sobrien   cebr\\t%0,%1
783107590Sobrien   ceb\\t%0,%1"
784107590Sobrien  [(set_attr "op_type" "RRE,RXE")
785107590Sobrien   (set_attr "atype"   "reg,mem")])
786107590Sobrien
787107590Sobrien(define_insn "*cmpsf_ccs"
788107590Sobrien  [(set (reg 33)
789107590Sobrien        (compare (match_operand:SF 0 "register_operand" "f,f")
790107590Sobrien                 (match_operand:SF 1 "general_operand" "f,m")))]
791107590Sobrien  "s390_match_ccmode(insn, CCSmode) && TARGET_HARD_FLOAT && TARGET_IBM_FLOAT"
792107590Sobrien  "@
793107590Sobrien   cer\\t%0,%1
794107590Sobrien   ce\\t%0,%1"
795107590Sobrien  [(set_attr "op_type" "RR,RX")
796107590Sobrien   (set_attr "atype"   "reg,mem")])
797107590Sobrien
798107590Sobrien
799107590Sobrien;;
800107590Sobrien;;- Move instructions.
801107590Sobrien;;
802107590Sobrien
803107590Sobrien;
804107590Sobrien; movti instruction pattern(s).
805107590Sobrien;
806107590Sobrien
807107590Sobrien(define_insn "*movti_ss"
808107590Sobrien  [(set (match_operand:TI 0 "s_operand" "=Qo")
809107590Sobrien        (match_operand:TI 1 "s_imm_operand" "Qo"))]
810107590Sobrien  ""
811107590Sobrien  "mvc\\t%O0(16,%R0),%1"	
812107590Sobrien  [(set_attr "op_type" "SS")
813107590Sobrien   (set_attr "atype"   "mem")])
814107590Sobrien
815107590Sobrien(define_insn "movti"
816107590Sobrien  [(set (match_operand:TI 0 "nonimmediate_operand" "=d,Q,d,m")
817107590Sobrien        (match_operand:TI 1 "general_operand" "Q,d,dKm,d"))]
818107590Sobrien  "TARGET_64BIT"
819107590Sobrien  "@
820107590Sobrien   lmg\\t%0,%N0,%1
821107590Sobrien   stmg\\t%1,%N1,%0
822107590Sobrien   #
823107590Sobrien   #"
824107590Sobrien  [(set_attr "op_type" "RSE,RSE,NN,NN")
825107590Sobrien   (set_attr "atype"   "mem")])
826107590Sobrien
827107590Sobrien(define_split
828107590Sobrien  [(set (match_operand:TI 0 "nonimmediate_operand" "")
829107590Sobrien        (match_operand:TI 1 "general_operand" ""))]
830107590Sobrien  "TARGET_64BIT && reload_completed
831107590Sobrien   && !s_operand (operands[0], VOIDmode)
832107590Sobrien   && !s_operand (operands[1], VOIDmode)
833107590Sobrien   && (register_operand (operands[0], VOIDmode)
834107590Sobrien       || register_operand (operands[1], VOIDmode))
835107590Sobrien   && (!register_operand (operands[0], VOIDmode)
836107590Sobrien       || !reg_overlap_mentioned_p (operand_subword (operands[0], 0, 0, TImode),
837107590Sobrien                                    operands[1])
838107590Sobrien       || !reg_overlap_mentioned_p (operand_subword (operands[0], 1, 0, TImode),
839107590Sobrien                                    operands[1]))"
840107590Sobrien  [(set (match_dup 2) (match_dup 4))
841107590Sobrien   (set (match_dup 3) (match_dup 5))]
842107590Sobrien  "
843107590Sobrien{
844107590Sobrien  if (!register_operand (operands[0], VOIDmode)
845107590Sobrien      || !reg_overlap_mentioned_p (operand_subword (operands[0], 0, 0, TImode),
846107590Sobrien                                   operands[1]))
847107590Sobrien    {
848107590Sobrien      operands[2] = operand_subword (operands[0], 0, 0, TImode);
849107590Sobrien      operands[3] = operand_subword (operands[0], 1, 0, TImode);
850107590Sobrien      operands[4] = operand_subword (operands[1], 0, 0, TImode);
851107590Sobrien      operands[5] = operand_subword (operands[1], 1, 0, TImode);
852107590Sobrien    }
853107590Sobrien  else
854107590Sobrien    {
855107590Sobrien      operands[2] = operand_subword (operands[0], 1, 0, TImode);
856107590Sobrien      operands[3] = operand_subword (operands[0], 0, 0, TImode);
857107590Sobrien      operands[4] = operand_subword (operands[1], 1, 0, TImode);
858107590Sobrien      operands[5] = operand_subword (operands[1], 0, 0, TImode);
859107590Sobrien    }
860107590Sobrien}")
861107590Sobrien
862107590Sobrien(define_split
863107590Sobrien  [(set (match_operand:TI 0 "register_operand" "")
864107590Sobrien        (match_operand:TI 1 "memory_operand" ""))]
865107590Sobrien  "TARGET_64BIT && reload_completed
866107590Sobrien   && !s_operand (operands[1], VOIDmode)"
867107590Sobrien  [(set (match_dup 2) (match_dup 3))
868107590Sobrien   (set (match_dup 0) (mem:TI (match_dup 2)))]
869107590Sobrien  "operands[2] = operand_subword (operands[0], 1, 0, TImode);
870107590Sobrien   operands[3] = legitimize_la_operand (XEXP (operands[1], 0));")
871107590Sobrien
872107590Sobrien;
873107590Sobrien; movdi instruction pattern(s).
874107590Sobrien;
875107590Sobrien
876107590Sobrien;; If generating PIC code and operands[1] is a symbolic CONST, emit a
877107590Sobrien;; move to get the address of the symbolic object from the GOT.
878107590Sobrien
879107590Sobrien(define_expand "movdi"
880107590Sobrien  [(set (match_operand:DI 0 "general_operand" "")
881107590Sobrien        (match_operand:DI 1 "general_operand" ""))]
882107590Sobrien  ""
883107590Sobrien  "
884107590Sobrien{
885107590Sobrien  /* Handle PIC symbolic constants.  */
886107590Sobrien  if (TARGET_64BIT && flag_pic && SYMBOLIC_CONST (operands[1]))
887107590Sobrien    emit_pic_move (operands, DImode);
888107590Sobrien
889107590Sobrien  /* During and after reload, we need to force constants
890107590Sobrien     to the literal pool ourselves, if necessary.  */
891107590Sobrien  if ((reload_in_progress || reload_completed)
892107590Sobrien      && CONSTANT_P (operands[1]) 
893107590Sobrien      && (!legitimate_reload_constant_p (operands[1])
894107590Sobrien          || fp_operand (operands[0], VOIDmode)))
895107590Sobrien    operands[1] = force_const_mem (DImode, operands[1]);
896107590Sobrien}")
897107590Sobrien
898107590Sobrien(define_insn "*movdi_lhi"
899107590Sobrien  [(set (match_operand:DI 0 "register_operand" "=d")
900107590Sobrien        (match_operand:DI 1 "immediate_operand" "K"))]
901107590Sobrien  "TARGET_64BIT
902107590Sobrien   && GET_CODE (operands[1]) == CONST_INT
903107590Sobrien   && CONST_OK_FOR_LETTER_P (INTVAL (operands[1]), 'K')
904107590Sobrien   && !fp_operand (operands[0], VOIDmode)"
905107590Sobrien  "lghi\\t%0,%h1"
906107590Sobrien  [(set_attr "op_type" "RI")
907107590Sobrien   (set_attr "atype"   "reg")])
908107590Sobrien
909107590Sobrien(define_insn "*movdi_lli"
910107590Sobrien  [(set (match_operand:DI 0 "register_operand" "=d")
911107590Sobrien        (match_operand:DI 1 "immediate_operand" "n"))]
912107590Sobrien  "TARGET_64BIT && s390_single_hi (operands[1], DImode, 0) >= 0
913107590Sobrien   && !fp_operand (operands[0], VOIDmode)"
914107590Sobrien  "*
915107590Sobrien{
916107590Sobrien  int part = s390_single_hi (operands[1], DImode, 0);
917107590Sobrien  operands[1] = GEN_INT (s390_extract_hi (operands[1], DImode, part));
918107590Sobrien
919107590Sobrien  switch (part)
920107590Sobrien    {
921107590Sobrien      case 0: return \"llihh\\t%0,%x1\";
922107590Sobrien      case 1: return \"llihl\\t%0,%x1\";
923107590Sobrien      case 2: return \"llilh\\t%0,%x1\";
924107590Sobrien      case 3: return \"llill\\t%0,%x1\";
925107590Sobrien      default: abort ();
926107590Sobrien    }
927107590Sobrien}"
928107590Sobrien  [(set_attr "op_type" "RI")
929107590Sobrien   (set_attr "atype"   "reg")])
930107590Sobrien
931107590Sobrien(define_insn "*movdi_larl"
932107590Sobrien  [(set (match_operand:DI 0 "register_operand" "=d")
933107590Sobrien        (match_operand:DI 1 "larl_operand" "X"))]
934107590Sobrien  "TARGET_64BIT
935107590Sobrien   && !fp_operand (operands[0], VOIDmode)"
936107590Sobrien  "larl\\t%0,%1"
937107590Sobrien   [(set_attr "op_type" "RIL")
938107590Sobrien    (set_attr "atype"   "reg")
939107590Sobrien    (set_attr "type"    "la")])
940107590Sobrien
941107590Sobrien(define_insn "*movdi_ss"
942107590Sobrien  [(set (match_operand:DI 0 "s_operand" "=Qo")
943107590Sobrien        (match_operand:DI 1 "s_imm_operand" "Qo"))]
944107590Sobrien  ""
945107590Sobrien  "mvc\\t%O0(8,%R0),%1"	
946107590Sobrien  [(set_attr "op_type" "SS")
947107590Sobrien   (set_attr "atype"   "mem")])
948107590Sobrien
949107590Sobrien(define_insn "*movdi_64"
950107590Sobrien  [(set (match_operand:DI 0 "nonimmediate_operand" "=d,d,m,!*f,!*f,!m")
951107590Sobrien        (match_operand:DI 1 "general_operand" "d,m,d,*f,m,*f"))]
952107590Sobrien  "TARGET_64BIT"
953107590Sobrien  "@
954107590Sobrien   lgr\\t%0,%1
955107590Sobrien   lg\\t%0,%1
956107590Sobrien   stg\\t%1,%0
957107590Sobrien   ldr\\t%0,%1
958107590Sobrien   ld\\t%0,%1
959107590Sobrien   std\\t%1,%0"
960107590Sobrien  [(set_attr "op_type" "RRE,RXE,RXE,RR,RX,RX")
961107590Sobrien   (set_attr "atype"   "reg,mem,mem,reg,mem,mem")])
962107590Sobrien
963107590Sobrien(define_insn "*movdi_31"
964107590Sobrien  [(set (match_operand:DI 0 "nonimmediate_operand" "=d,Q,d,m,!*f,!*f,!m")
965107590Sobrien        (match_operand:DI 1 "general_operand" "Q,d,dKm,d,*f,m,*f"))]
966107590Sobrien  "!TARGET_64BIT"
967107590Sobrien  "@
968107590Sobrien   lm\\t%0,%N0,%1
969107590Sobrien   stm\\t%1,%N1,%0
970107590Sobrien   #
971107590Sobrien   #
972107590Sobrien   ldr\\t%0,%1
973107590Sobrien   ld\\t%0,%1
974107590Sobrien   std\\t%1,%0"
975107590Sobrien  [(set_attr "op_type" "RS,RS,NN,NN,RR,RX,RX")
976107590Sobrien   (set_attr "atype"   "mem,mem,*,*,reg,mem,mem")])
977107590Sobrien
978107590Sobrien(define_split
979107590Sobrien  [(set (match_operand:DI 0 "nonimmediate_operand" "")
980107590Sobrien        (match_operand:DI 1 "general_operand" ""))]
981107590Sobrien  "!TARGET_64BIT && reload_completed
982107590Sobrien   && !fp_operand (operands[0], VOIDmode)
983107590Sobrien   && !fp_operand (operands[1], VOIDmode)
984107590Sobrien   && !s_operand (operands[0], VOIDmode)
985107590Sobrien   && !s_operand (operands[1], VOIDmode)
986107590Sobrien   && (register_operand (operands[0], VOIDmode)
987107590Sobrien       || register_operand (operands[1], VOIDmode))
988107590Sobrien   && (!register_operand (operands[0], VOIDmode)
989107590Sobrien       || !reg_overlap_mentioned_p (operand_subword (operands[0], 0, 0, DImode),
990107590Sobrien                                    operands[1])
991107590Sobrien       || !reg_overlap_mentioned_p (operand_subword (operands[0], 1, 0, DImode),
992107590Sobrien                                    operands[1]))"
993107590Sobrien  [(set (match_dup 2) (match_dup 4))
994107590Sobrien   (set (match_dup 3) (match_dup 5))]
995107590Sobrien  "
996107590Sobrien{
997107590Sobrien  if (!register_operand (operands[0], VOIDmode)
998107590Sobrien      || !reg_overlap_mentioned_p (operand_subword (operands[0], 0, 0, DImode),
999107590Sobrien                                   operands[1]))
1000107590Sobrien    {
1001107590Sobrien      operands[2] = operand_subword (operands[0], 0, 0, DImode);
1002107590Sobrien      operands[3] = operand_subword (operands[0], 1, 0, DImode);
1003107590Sobrien      operands[4] = operand_subword (operands[1], 0, 0, DImode);
1004107590Sobrien      operands[5] = operand_subword (operands[1], 1, 0, DImode);
1005107590Sobrien    }
1006107590Sobrien  else
1007107590Sobrien    {
1008107590Sobrien      operands[2] = operand_subword (operands[0], 1, 0, DImode);
1009107590Sobrien      operands[3] = operand_subword (operands[0], 0, 0, DImode);
1010107590Sobrien      operands[4] = operand_subword (operands[1], 1, 0, DImode);
1011107590Sobrien      operands[5] = operand_subword (operands[1], 0, 0, DImode);
1012107590Sobrien    }
1013107590Sobrien}")
1014107590Sobrien
1015107590Sobrien(define_split
1016107590Sobrien  [(set (match_operand:DI 0 "register_operand" "")
1017107590Sobrien        (match_operand:DI 1 "memory_operand" ""))]
1018107590Sobrien  "!TARGET_64BIT && reload_completed
1019107590Sobrien   && !fp_operand (operands[0], VOIDmode)
1020107590Sobrien   && !fp_operand (operands[1], VOIDmode)
1021107590Sobrien   && !s_operand (operands[1], VOIDmode)"
1022107590Sobrien  [(set (match_dup 2) (match_dup 3))
1023107590Sobrien   (set (match_dup 0) (mem:DI (match_dup 2)))]
1024107590Sobrien  "operands[2] = operand_subword (operands[0], 1, 0, DImode);
1025107590Sobrien   operands[3] = legitimize_la_operand (XEXP (operands[1], 0));")
1026107590Sobrien
1027107590Sobrien;
1028107590Sobrien; movsi instruction pattern(s).
1029107590Sobrien;
1030107590Sobrien
1031107590Sobrien;; If generating PIC code and operands[1] is a symbolic CONST, emit a
1032107590Sobrien;; move to get the address of the symbolic object from the GOT.
1033107590Sobrien
1034107590Sobrien(define_expand "movsi"
1035107590Sobrien  [(set (match_operand:SI 0 "general_operand" "")
1036107590Sobrien        (match_operand:SI 1 "general_operand" ""))]
1037107590Sobrien  ""
1038107590Sobrien  "
1039107590Sobrien{
1040107590Sobrien  /* Handle PIC symbolic constants.  */
1041107590Sobrien  if (!TARGET_64BIT && flag_pic && SYMBOLIC_CONST (operands[1]))
1042107590Sobrien    emit_pic_move (operands, SImode);
1043107590Sobrien
1044107590Sobrien  /* expr.c tries to load an effective address using 
1045107590Sobrien     force_reg.  This fails because we don't have a 
1046107590Sobrien     generic load_address pattern.  Convert the move
1047107590Sobrien     to a proper arithmetic operation instead, unless
1048107590Sobrien     it is guaranteed to be OK.  */
1049107590Sobrien  if (GET_CODE (operands[1]) == PLUS
1050107590Sobrien      && !legitimate_la_operand_p (operands[1]))
1051107590Sobrien    {
1052107590Sobrien      operands[1] = force_operand (operands[1], operands[0]);
1053107590Sobrien      if (operands[1] == operands[0])
1054107590Sobrien        DONE;
1055107590Sobrien    }
1056107590Sobrien
1057107590Sobrien  /* During and after reload, we need to force constants
1058107590Sobrien     to the literal pool ourselves, if necessary.  */
1059107590Sobrien  if ((reload_in_progress || reload_completed)
1060107590Sobrien      && CONSTANT_P (operands[1]) 
1061107590Sobrien      && (!legitimate_reload_constant_p (operands[1])
1062107590Sobrien          || fp_operand (operands[0], VOIDmode)))
1063107590Sobrien    operands[1] = force_const_mem (SImode, operands[1]);
1064107590Sobrien}")
1065107590Sobrien
1066107590Sobrien(define_insn "*movsi_lhi"
1067107590Sobrien  [(set (match_operand:SI 0 "register_operand" "=d")
1068107590Sobrien        (match_operand:SI 1 "immediate_operand" "K"))]
1069107590Sobrien  "GET_CODE (operands[1]) == CONST_INT
1070107590Sobrien   && CONST_OK_FOR_LETTER_P (INTVAL (operands[1]), 'K')
1071107590Sobrien   && !fp_operand (operands[0], VOIDmode)"
1072107590Sobrien  "lhi\\t%0,%h1"
1073107590Sobrien  [(set_attr "op_type" "RI")])
1074107590Sobrien
1075107590Sobrien(define_insn "*movsi_lli"
1076107590Sobrien  [(set (match_operand:SI 0 "register_operand" "=d")
1077107590Sobrien        (match_operand:SI 1 "immediate_operand" "n"))]
1078107590Sobrien  "TARGET_64BIT && s390_single_hi (operands[1], SImode, 0) >= 0
1079107590Sobrien   && !fp_operand (operands[0], VOIDmode)"
1080107590Sobrien  "*
1081107590Sobrien{
1082107590Sobrien  int part = s390_single_hi (operands[1], SImode, 0);
1083107590Sobrien  operands[1] = GEN_INT (s390_extract_hi (operands[1], SImode, part));
1084107590Sobrien
1085107590Sobrien  switch (part)
1086107590Sobrien    {
1087107590Sobrien      case 0: return \"llilh\\t%0,%x1\";
1088107590Sobrien      case 1: return \"llill\\t%0,%x1\";
1089107590Sobrien      default: abort ();
1090107590Sobrien    }
1091107590Sobrien}"
1092107590Sobrien  [(set_attr "op_type" "RI")])
1093107590Sobrien
1094107590Sobrien(define_insn "*movsi_ss"
1095107590Sobrien  [(set (match_operand:SI 0 "s_operand" "=Qo")
1096107590Sobrien        (match_operand:SI 1 "s_imm_operand" "Qo"))]
1097107590Sobrien  ""
1098107590Sobrien  "mvc\\t%O0(4,%R0),%1"	
1099107590Sobrien  [(set_attr "op_type" "SS")
1100107590Sobrien   (set_attr "atype"   "mem")])
1101107590Sobrien
1102107590Sobrien(define_insn "*movsi"
1103107590Sobrien  [(set (match_operand:SI 0 "nonimmediate_operand" "=d,d,m,!*f,!*f,!m")
1104107590Sobrien        (match_operand:SI 1 "general_operand" "d,m,d,*f,m,*f"))]
1105107590Sobrien  ""
1106107590Sobrien  "@
1107107590Sobrien   lr\\t%0,%1
1108107590Sobrien   l\\t%0,%1
1109107590Sobrien   st\\t%1,%0
1110107590Sobrien   ler\\t%0,%1
1111107590Sobrien   le\\t%0,%1
1112107590Sobrien   ste\\t%1,%0"
1113107590Sobrien  [(set_attr "op_type" "RR,RX,RX,RR,RX,RX")
1114107590Sobrien   (set_attr "atype"   "reg,mem,mem,reg,mem,mem")])
1115107590Sobrien
1116107590Sobrien
1117107590Sobrien;
1118107590Sobrien; movhi instruction pattern(s).
1119107590Sobrien;
1120107590Sobrien
1121107590Sobrien(define_insn "movhi"
1122107590Sobrien  [(set (match_operand:HI 0 "nonimmediate_operand" "=d,d,d,m")
1123107590Sobrien        (match_operand:HI 1 "general_operand" "d,n,m,d"))]
1124107590Sobrien  ""
1125107590Sobrien  "@
1126107590Sobrien   lr\\t%0,%1
1127107590Sobrien   lhi\\t%0,%h1
1128107590Sobrien   lh\\t%0,%1
1129107590Sobrien   sth\\t%1,%0"
1130107590Sobrien  [(set_attr "op_type" "RR,RI,RX,RX")
1131107590Sobrien   (set_attr "atype"   "reg,reg,mem,mem")])
1132107590Sobrien
1133107590Sobrien
1134107590Sobrien;
1135107590Sobrien; movqi instruction pattern(s).
1136107590Sobrien;
1137107590Sobrien
1138107590Sobrien(define_insn "movqi_64"
1139107590Sobrien  [(set (match_operand:QI 0 "nonimmediate_operand" "=d,d,d,m,Q")
1140107590Sobrien        (match_operand:QI 1 "general_operand" "d,n,m,d,n"))]
1141107590Sobrien  "TARGET_64BIT"
1142107590Sobrien  "@
1143107590Sobrien   lr\\t%0,%1
1144107590Sobrien   lhi\\t%0,%b1
1145107590Sobrien   llgc\\t%0,%1
1146107590Sobrien   stc\\t%1,%0
1147107590Sobrien   mvi\\t%0,%b1"
1148107590Sobrien  [(set_attr "op_type" "RR,RI,RXE,RX,SI")
1149107590Sobrien   (set_attr "atype"   "reg,reg,mem,mem,mem")])
1150107590Sobrien
1151107590Sobrien
1152107590Sobrien(define_insn "movqi"
1153107590Sobrien  [(set (match_operand:QI 0 "nonimmediate_operand" "=d,d,d,m,Q")
1154107590Sobrien        (match_operand:QI 1 "general_operand" "d,n,m,d,n"))]
1155107590Sobrien  ""
1156107590Sobrien  "@
1157107590Sobrien   lr\\t%0,%1
1158107590Sobrien   lhi\\t%0,%b1
1159107590Sobrien   ic\\t%0,%1
1160107590Sobrien   stc\\t%1,%0
1161107590Sobrien   mvi\\t%0,%b1"
1162107590Sobrien  [(set_attr "op_type" "RR,RI,RX,RX,SI")
1163107590Sobrien   (set_attr "atype"   "reg,reg,mem,mem,mem")])
1164107590Sobrien
1165107590Sobrien
1166107590Sobrien;
1167107590Sobrien; moveqstrictqi instruction pattern(s).
1168107590Sobrien;
1169107590Sobrien
1170107590Sobrien(define_insn "*movstrictqi"
1171107590Sobrien  [(set (strict_low_part (match_operand:QI 0 "register_operand" "+d"))
1172107590Sobrien                         (match_operand:QI 1 "memory_operand" "m"))]
1173107590Sobrien  ""
1174107590Sobrien  "ic\\t%0,%1"
1175107590Sobrien  [(set_attr "op_type"  "RX")
1176107590Sobrien   (set_attr "atype"    "mem")])
1177107590Sobrien
1178107590Sobrien;
1179107590Sobrien; movstricthi instruction pattern(s).
1180107590Sobrien;
1181107590Sobrien
1182107590Sobrien(define_insn "*movstricthi"
1183107590Sobrien  [(set (strict_low_part (match_operand:HI 0 "register_operand" "+d"))
1184107590Sobrien                         (match_operand:HI 1 "s_imm_operand" "Qo"))
1185107590Sobrien   (clobber (reg:CC 33))]
1186107590Sobrien  ""
1187107590Sobrien  "icm\\t%0,3,%1"
1188107590Sobrien  [(set_attr "op_type" "RS")
1189107590Sobrien   (set_attr "atype"   "mem")])
1190107590Sobrien
1191107590Sobrien
1192107590Sobrien;
1193107590Sobrien; movstrictsi instruction pattern(s).
1194107590Sobrien;
1195107590Sobrien
1196107590Sobrien(define_insn "movestrictsi"
1197107590Sobrien  [(set (strict_low_part (match_operand:SI 0 "register_operand" "+d,d"))
1198107590Sobrien                         (match_operand:SI 1 "general_operand" "d,m"))]
1199107590Sobrien  "TARGET_64BIT"
1200107590Sobrien  "@
1201107590Sobrien   lr\\t%0,%1
1202107590Sobrien   l\\t%0,%1"
1203107590Sobrien  [(set_attr "op_type" "RR,RS")
1204107590Sobrien   (set_attr "atype"   "reg,mem")])
1205107590Sobrien
1206107590Sobrien
1207107590Sobrien;
1208107590Sobrien; movdf instruction pattern(s).
1209107590Sobrien;
1210107590Sobrien
1211107590Sobrien(define_expand "movdf"
1212107590Sobrien  [(set (match_operand:DF 0 "nonimmediate_operand" "")
1213107590Sobrien        (match_operand:DF 1 "general_operand"  ""))]
1214107590Sobrien  ""
1215107590Sobrien  "
1216107590Sobrien{
1217107590Sobrien  /* During and after reload, we need to force constants
1218107590Sobrien     to the literal pool ourselves, if necessary.  */
1219107590Sobrien  if ((reload_in_progress || reload_completed)
1220107590Sobrien      && CONSTANT_P (operands[1]))
1221107590Sobrien    operands[1] = force_const_mem (DFmode, operands[1]);
1222107590Sobrien}")
1223107590Sobrien
1224107590Sobrien(define_insn "*movdf_ss"
1225107590Sobrien  [(set (match_operand:DF 0 "s_operand" "=Qo")
1226107590Sobrien        (match_operand:DF 1 "s_imm_operand" "Qo"))]
1227107590Sobrien  ""
1228107590Sobrien  "mvc\\t%O0(8,%R0),%1"	
1229107590Sobrien  [(set_attr "op_type" "SS")
1230107590Sobrien   (set_attr "atype"   "mem")])
1231107590Sobrien
1232107590Sobrien(define_insn "*movdf_64"
1233107590Sobrien  [(set (match_operand:DF 0 "nonimmediate_operand" "=f,f,m,d,d,m")
1234107590Sobrien        (match_operand:DF 1 "general_operand" "f,m,f,d,m,d"))]
1235107590Sobrien  "TARGET_64BIT"
1236107590Sobrien  "@
1237107590Sobrien   ldr\\t%0,%1
1238107590Sobrien   ld\\t%0,%1
1239107590Sobrien   std\\t%1,%0
1240107590Sobrien   lgr\\t%0,%1
1241107590Sobrien   lg\\t%0,%1
1242107590Sobrien   stg\\t%1,%0"
1243107590Sobrien  [(set_attr "op_type" "RR,RX,RX,RRE,RXE,RXE")
1244107590Sobrien   (set_attr "atype"   "reg,mem,mem,reg,mem,mem")])
1245107590Sobrien
1246107590Sobrien(define_insn "*movdf_31"
1247107590Sobrien  [(set (match_operand:DF 0 "nonimmediate_operand" "=f,f,m,d,Q,d,m")
1248107590Sobrien        (match_operand:DF 1 "general_operand" "f,m,f,Q,d,dKm,d"))]
1249107590Sobrien  "!TARGET_64BIT"
1250107590Sobrien  "@
1251107590Sobrien   ldr\\t%0,%1
1252107590Sobrien   ld\\t%0,%1
1253107590Sobrien   std\\t%1,%0
1254107590Sobrien   lm\\t%0,%N0,%1
1255107590Sobrien   stm\\t%1,%N1,%0
1256107590Sobrien   #
1257107590Sobrien   #"
1258107590Sobrien  [(set_attr "op_type" "RR,RX,RX,RS,RS,NN,NN")
1259107590Sobrien   (set_attr "atype"   "reg,mem,mem,mem,mem,*,*")])
1260107590Sobrien
1261107590Sobrien(define_split
1262107590Sobrien  [(set (match_operand:DF 0 "nonimmediate_operand" "")
1263107590Sobrien        (match_operand:DF 1 "general_operand" ""))]
1264107590Sobrien  "!TARGET_64BIT && reload_completed
1265107590Sobrien   && !fp_operand (operands[0], VOIDmode)
1266107590Sobrien   && !fp_operand (operands[1], VOIDmode)
1267107590Sobrien   && !s_operand (operands[0], VOIDmode)
1268107590Sobrien   && !s_operand (operands[1], VOIDmode)
1269107590Sobrien   && (register_operand (operands[0], VOIDmode)
1270107590Sobrien       || register_operand (operands[1], VOIDmode))
1271107590Sobrien   && (!register_operand (operands[0], VOIDmode)
1272107590Sobrien       || !reg_overlap_mentioned_p (operand_subword (operands[0], 0, 0, DFmode),
1273107590Sobrien                                    operands[1])
1274107590Sobrien       || !reg_overlap_mentioned_p (operand_subword (operands[0], 1, 0, DFmode),
1275107590Sobrien                                    operands[1]))"
1276107590Sobrien  [(set (match_dup 2) (match_dup 4))
1277107590Sobrien   (set (match_dup 3) (match_dup 5))]
1278107590Sobrien  "
1279107590Sobrien{
1280107590Sobrien  if (!register_operand (operands[0], VOIDmode)
1281107590Sobrien      || !reg_overlap_mentioned_p (operand_subword (operands[0], 0, 0, DFmode),
1282107590Sobrien                                   operands[1]))
1283107590Sobrien    {
1284107590Sobrien      operands[2] = operand_subword (operands[0], 0, 0, DFmode);
1285107590Sobrien      operands[3] = operand_subword (operands[0], 1, 0, DFmode);
1286107590Sobrien      operands[4] = operand_subword (operands[1], 0, 0, DFmode);
1287107590Sobrien      operands[5] = operand_subword (operands[1], 1, 0, DFmode);
1288107590Sobrien    }
1289107590Sobrien  else
1290107590Sobrien    {
1291107590Sobrien      operands[2] = operand_subword (operands[0], 1, 0, DFmode);
1292107590Sobrien      operands[3] = operand_subword (operands[0], 0, 0, DFmode);
1293107590Sobrien      operands[4] = operand_subword (operands[1], 1, 0, DFmode);
1294107590Sobrien      operands[5] = operand_subword (operands[1], 0, 0, DFmode);
1295107590Sobrien    }
1296107590Sobrien}")
1297107590Sobrien
1298107590Sobrien(define_split
1299107590Sobrien  [(set (match_operand:DF 0 "register_operand" "")
1300107590Sobrien        (match_operand:DF 1 "memory_operand" ""))]
1301107590Sobrien  "!TARGET_64BIT && reload_completed
1302107590Sobrien   && !fp_operand (operands[0], VOIDmode)
1303107590Sobrien   && !fp_operand (operands[1], VOIDmode)
1304107590Sobrien   && !s_operand (operands[1], VOIDmode)"
1305107590Sobrien  [(set (match_dup 2) (match_dup 3))
1306107590Sobrien   (set (match_dup 0) (mem:DI (match_dup 2)))]
1307107590Sobrien  "operands[2] = operand_subword (operands[0], 1, 0, DFmode);
1308107590Sobrien   operands[3] = legitimize_la_operand (XEXP (operands[1], 0));")
1309107590Sobrien
1310107590Sobrien;
1311107590Sobrien; movsf instruction pattern(s).
1312107590Sobrien;
1313107590Sobrien
1314107590Sobrien(define_expand "movsf"
1315107590Sobrien  [(set (match_operand:SF 0 "nonimmediate_operand" "")
1316107590Sobrien        (match_operand:SF 1 "general_operand"  ""))]
1317107590Sobrien  ""
1318107590Sobrien  "
1319107590Sobrien{
1320107590Sobrien  /* During and after reload, we need to force constants
1321107590Sobrien     to the literal pool ourselves, if necessary.  */
1322107590Sobrien  if ((reload_in_progress || reload_completed)
1323107590Sobrien      && CONSTANT_P (operands[1]))
1324107590Sobrien    operands[1] = force_const_mem (SFmode, operands[1]);
1325107590Sobrien}")
1326107590Sobrien
1327107590Sobrien(define_insn "*movsf_ss"
1328107590Sobrien  [(set (match_operand:SF 0 "s_operand" "=Qo")
1329107590Sobrien        (match_operand:SF 1 "s_imm_operand" "Qo"))]
1330107590Sobrien  ""
1331107590Sobrien  "mvc\\t%O0(4,%R0),%1"	
1332107590Sobrien  [(set_attr "op_type" "SS")
1333107590Sobrien   (set_attr "atype"   "mem")])
1334107590Sobrien
1335107590Sobrien(define_insn "*movsf"
1336107590Sobrien  [(set (match_operand:SF 0 "nonimmediate_operand" "=f,f,m,d,d,m")
1337107590Sobrien        (match_operand:SF 1 "general_operand" "f,m,f,d,m,d"))]
1338107590Sobrien  ""
1339107590Sobrien  "@
1340107590Sobrien   ler\\t%0,%1
1341107590Sobrien   le\\t%0,%1
1342107590Sobrien   ste\\t%1,%0
1343107590Sobrien   lr\\t%0,%1
1344107590Sobrien   l\\t%0,%1
1345107590Sobrien   st\\t%1,%0"
1346107590Sobrien  [(set_attr "op_type" "RR,RX,RX,RR,RX,RX")
1347107590Sobrien   (set_attr "atype"   "reg,mem,mem,reg,mem,mem")])
1348107590Sobrien
1349107590Sobrien;
1350107590Sobrien; load_multiple pattern(s).
1351107590Sobrien;
1352107590Sobrien
1353107590Sobrien(define_expand "load_multiple"
1354107590Sobrien  [(match_par_dup 3 [(set (match_operand 0 "" "")
1355107590Sobrien			  (match_operand 1 "" ""))
1356107590Sobrien		     (use (match_operand 2 "" ""))])]
1357107590Sobrien  ""
1358107590Sobrien  "
1359107590Sobrien{
1360107590Sobrien  int regno;
1361107590Sobrien  int count;
1362107590Sobrien  rtx from;
1363107590Sobrien  int i, off;
1364107590Sobrien
1365107590Sobrien  /* Support only loading a constant number of fixed-point registers from
1366107590Sobrien     memory and only bother with this if more than two */
1367107590Sobrien  if (GET_CODE (operands[2]) != CONST_INT
1368107590Sobrien      || INTVAL (operands[2]) < 2
1369107590Sobrien      || INTVAL (operands[2]) > 16
1370107590Sobrien      || GET_CODE (operands[1]) != MEM
1371107590Sobrien      || GET_CODE (operands[0]) != REG
1372107590Sobrien      || REGNO (operands[0]) >= 16)
1373107590Sobrien    FAIL;
1374107590Sobrien
1375107590Sobrien  count = INTVAL (operands[2]);
1376107590Sobrien  regno = REGNO (operands[0]);
1377107590Sobrien
1378107590Sobrien  operands[3] = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (count));
1379107590Sobrien  if (no_new_pseudos)
1380107590Sobrien    {
1381107590Sobrien      if (GET_CODE (XEXP (operands[1], 0)) == REG)
1382107590Sobrien	{
1383107590Sobrien	  from = XEXP (operands[1], 0);
1384107590Sobrien	  off = 0;
1385107590Sobrien	}
1386107590Sobrien      else if (GET_CODE (XEXP (operands[1], 0)) == PLUS
1387107590Sobrien	       && GET_CODE (XEXP (XEXP (operands[1], 0), 0)) == REG
1388107590Sobrien	       && GET_CODE (XEXP (XEXP (operands[1], 0), 1)) == CONST_INT)
1389107590Sobrien	{
1390107590Sobrien	  from = XEXP (XEXP (operands[1], 0), 0);
1391107590Sobrien	  off = INTVAL (XEXP (XEXP (operands[1], 0), 1));
1392107590Sobrien	}
1393107590Sobrien      else
1394107590Sobrien	FAIL;
1395107590Sobrien
1396107590Sobrien      if (from == frame_pointer_rtx || from == arg_pointer_rtx)
1397107590Sobrien	FAIL;
1398107590Sobrien    }
1399107590Sobrien  else
1400107590Sobrien    {
1401107590Sobrien      from = force_reg (Pmode, XEXP (operands[1], 0));
1402107590Sobrien      off = 0;
1403107590Sobrien    }
1404107590Sobrien
1405107590Sobrien  for (i = 0; i < count; i++)
1406107590Sobrien    XVECEXP (operands[3], 0, i)
1407107590Sobrien      = gen_rtx_SET (VOIDmode, gen_rtx_REG (Pmode, regno + i),
1408107590Sobrien		     change_address (operands[1], Pmode,
1409107590Sobrien				     plus_constant (from,
1410107590Sobrien						    off + i * UNITS_PER_WORD)));
1411107590Sobrien}")
1412107590Sobrien
1413107590Sobrien(define_insn "*load_multiple_di"
1414107590Sobrien  [(match_parallel 0 "load_multiple_operation"
1415107590Sobrien		   [(set (match_operand:DI 1 "register_operand" "=r")
1416107590Sobrien			 (match_operand:DI 2 "s_operand" "oQ"))])]
1417107590Sobrien  ""
1418107590Sobrien  "*
1419107590Sobrien{
1420107590Sobrien  int words = XVECLEN (operands[0], 0);
1421107590Sobrien
1422107590Sobrien  if (XVECLEN (operands[0], 0) == 1)
1423107590Sobrien    return \"lg\\t%1,0(%2)\";
1424107590Sobrien
1425107590Sobrien  operands[0] = gen_rtx_REG (DImode, REGNO (operands[1]) + words - 1);
1426107590Sobrien    return \"lmg\\t%1,%0,%2\";
1427107590Sobrien}"
1428107590Sobrien   [(set_attr "op_type" "RXE")
1429107590Sobrien    (set_attr "atype"   "mem")
1430107590Sobrien    (set_attr "type"    "lm")])
1431107590Sobrien
1432107590Sobrien(define_insn "*load_multiple_si"
1433107590Sobrien  [(match_parallel 0 "load_multiple_operation"
1434107590Sobrien		   [(set (match_operand:SI 1 "register_operand" "=r")
1435107590Sobrien			 (match_operand:SI 2 "s_operand" "oQ"))])]
1436107590Sobrien  ""
1437107590Sobrien  "*
1438107590Sobrien{
1439107590Sobrien  int words = XVECLEN (operands[0], 0);
1440107590Sobrien
1441107590Sobrien  if (XVECLEN (operands[0], 0) == 1)
1442107590Sobrien    return \"l\\t%1,0(%2)\";
1443107590Sobrien
1444107590Sobrien  operands[0] = gen_rtx_REG (SImode, REGNO (operands[1]) + words - 1);
1445107590Sobrien    return \"lm\\t%1,%0,%2\";
1446107590Sobrien}"
1447107590Sobrien   [(set_attr "op_type" "RXE")
1448107590Sobrien    (set_attr "atype"   "mem")
1449107590Sobrien    (set_attr "type"    "lm")])
1450107590Sobrien
1451107590Sobrien;
1452107590Sobrien; store multiple pattern(s). 
1453107590Sobrien;
1454107590Sobrien
1455107590Sobrien(define_expand "store_multiple"
1456107590Sobrien  [(match_par_dup 3 [(set (match_operand 0 "" "")
1457107590Sobrien			  (match_operand 1 "" ""))
1458107590Sobrien		     (use (match_operand 2 "" ""))])]
1459107590Sobrien  ""
1460107590Sobrien  "
1461107590Sobrien{
1462107590Sobrien  int regno;
1463107590Sobrien  int count;
1464107590Sobrien  rtx to;
1465107590Sobrien  int i, off;
1466107590Sobrien
1467107590Sobrien  /* Support only storing a constant number of fixed-point registers to
1468107590Sobrien     memory and only bother with this if more than two.  */
1469107590Sobrien  if (GET_CODE (operands[2]) != CONST_INT
1470107590Sobrien      || INTVAL (operands[2]) < 2
1471107590Sobrien      || INTVAL (operands[2]) > 16
1472107590Sobrien      || GET_CODE (operands[0]) != MEM
1473107590Sobrien      || GET_CODE (operands[1]) != REG
1474107590Sobrien      || REGNO (operands[1]) >= 16)
1475107590Sobrien    FAIL;
1476107590Sobrien
1477107590Sobrien  count = INTVAL (operands[2]);
1478107590Sobrien  regno = REGNO (operands[1]);
1479107590Sobrien
1480107590Sobrien  operands[3] = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (count));
1481107590Sobrien
1482107590Sobrien  if (no_new_pseudos)
1483107590Sobrien    {
1484107590Sobrien      if (GET_CODE (XEXP (operands[0], 0)) == REG)
1485107590Sobrien	{
1486107590Sobrien	  to = XEXP (operands[0], 0);
1487107590Sobrien	  off = 0;
1488107590Sobrien	}
1489107590Sobrien      else if (GET_CODE (XEXP (operands[0], 0)) == PLUS
1490107590Sobrien	       && GET_CODE (XEXP (XEXP (operands[0], 0), 0)) == REG
1491107590Sobrien	       && GET_CODE (XEXP (XEXP (operands[0], 0), 1)) == CONST_INT)
1492107590Sobrien	{
1493107590Sobrien	  to = XEXP (XEXP (operands[0], 0), 0);
1494107590Sobrien	  off = INTVAL (XEXP (XEXP (operands[0], 0), 1));
1495107590Sobrien	}
1496107590Sobrien      else
1497107590Sobrien	FAIL;
1498107590Sobrien
1499107590Sobrien      if (to == frame_pointer_rtx || to == arg_pointer_rtx)
1500107590Sobrien	FAIL;
1501107590Sobrien    }
1502107590Sobrien  else	
1503107590Sobrien    {
1504107590Sobrien      to = force_reg (Pmode, XEXP (operands[0], 0));
1505107590Sobrien      off = 0;
1506107590Sobrien    }
1507107590Sobrien
1508107590Sobrien  for (i = 0; i < count; i++)
1509107590Sobrien    XVECEXP (operands[3], 0, i)
1510107590Sobrien      = gen_rtx_SET (VOIDmode,
1511107590Sobrien		     change_address (operands[0], Pmode,
1512107590Sobrien				     plus_constant (to,
1513107590Sobrien						    off + i * UNITS_PER_WORD)),
1514107590Sobrien		     gen_rtx_REG (Pmode, regno + i));
1515107590Sobrien}")
1516107590Sobrien
1517107590Sobrien(define_insn "*store_multiple_di"
1518107590Sobrien  [(match_parallel 0 "store_multiple_operation"
1519107590Sobrien		   [(set (match_operand:DI 1 "s_operand" "=oQ")
1520107590Sobrien			 (match_operand:DI 2 "register_operand" "r"))])]
1521107590Sobrien  ""
1522107590Sobrien  "*
1523107590Sobrien{
1524107590Sobrien  int words = XVECLEN (operands[0], 0);
1525107590Sobrien
1526107590Sobrien  if (XVECLEN (operands[0], 0) == 1)
1527107590Sobrien    return \"stg\\t%1,0(%2)\";
1528107590Sobrien
1529107590Sobrien  operands[0] = gen_rtx_REG (DImode, REGNO (operands[2]) + words - 1);
1530107590Sobrien    return \"stmg\\t%2,%0,%1\";
1531107590Sobrien}"
1532107590Sobrien   [(set_attr "op_type" "RXE")
1533107590Sobrien    (set_attr "atype"   "mem")
1534107590Sobrien    (set_attr "type"    "stm")])
1535107590Sobrien
1536107590Sobrien
1537107590Sobrien(define_insn "*store_multiple_si"
1538107590Sobrien  [(match_parallel 0 "store_multiple_operation"
1539107590Sobrien		   [(set (match_operand:SI 1 "s_operand" "=oQ")
1540107590Sobrien			 (match_operand:SI 2 "register_operand" "r"))])]
1541107590Sobrien  ""
1542107590Sobrien  "*
1543107590Sobrien{
1544107590Sobrien  int words = XVECLEN (operands[0], 0);
1545107590Sobrien
1546107590Sobrien  if (XVECLEN (operands[0], 0) == 1)
1547107590Sobrien    return \"st\\t%1,0(%2)\";
1548107590Sobrien
1549107590Sobrien  operands[0] = gen_rtx_REG (SImode, REGNO (operands[2]) + words - 1);
1550107590Sobrien    return \"stm\\t%2,%0,%1\";
1551107590Sobrien}"
1552107590Sobrien   [(set_attr "op_type" "RXE")
1553107590Sobrien    (set_attr "atype"   "mem")
1554107590Sobrien    (set_attr "type"    "stm")])
1555107590Sobrien
1556107590Sobrien;;
1557107590Sobrien;; String instructions.
1558107590Sobrien;;
1559107590Sobrien
1560107590Sobrien;
1561107590Sobrien; movstrdi instruction pattern(s).
1562107590Sobrien;
1563107590Sobrien
1564107590Sobrien(define_expand "movstrdi"
1565107590Sobrien   [(set (match_operand:BLK 0 "general_operand" "")
1566107590Sobrien         (match_operand:BLK 1 "general_operand" ""))
1567107590Sobrien    (use (match_operand:DI 2 "general_operand" ""))
1568107590Sobrien    (match_operand 3 "" "")]
1569107590Sobrien    "TARGET_64BIT"
1570107590Sobrien    "
1571107590Sobrien{
1572107590Sobrien  rtx addr0, addr1;
1573107590Sobrien
1574107590Sobrien  addr0 = force_operand (XEXP (operands[0], 0), NULL_RTX);
1575107590Sobrien  addr1 = force_operand (XEXP (operands[1], 0), NULL_RTX);
1576107590Sobrien
1577107590Sobrien  if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) <= 256)
1578107590Sobrien    {
1579107590Sobrien      operands[0] = change_address (operands[0], VOIDmode, addr0);
1580107590Sobrien      operands[1] = change_address (operands[1], VOIDmode, addr1);
1581107590Sobrien      operands[2] = GEN_INT (INTVAL (operands[2]) - 1);
1582107590Sobrien
1583107590Sobrien      emit_insn (gen_movstrdi_short (operands[0], operands[1], operands[2]));
1584107590Sobrien      DONE;
1585107590Sobrien    } 
1586107590Sobrien  else 
1587107590Sobrien    {
1588107590Sobrien      if (TARGET_MVCLE) 
1589107590Sobrien	{
1590107590Sobrien          /* implementation suggested by  Richard Henderson <rth@cygnus.com> */
1591107590Sobrien          rtx reg0 = gen_reg_rtx (TImode);
1592107590Sobrien          rtx reg1 = gen_reg_rtx (TImode);
1593107590Sobrien          rtx len = operands[2];
1594107590Sobrien
1595107590Sobrien          if (! CONSTANT_P (len))
1596107590Sobrien            len = force_reg (DImode, len);
1597107590Sobrien
1598107590Sobrien          /* Load up the address+length pairs.  */
1599107590Sobrien
1600107590Sobrien          emit_move_insn (gen_highpart (DImode, reg0), addr0);
1601107590Sobrien          emit_move_insn (gen_lowpart (DImode, reg0), len);
1602107590Sobrien
1603107590Sobrien          emit_move_insn (gen_highpart (DImode, reg1), addr1);
1604107590Sobrien          emit_move_insn (gen_lowpart (DImode, reg1), len);
1605107590Sobrien
1606107590Sobrien          /* MOVE */
1607107590Sobrien          emit_insn (gen_movstrdi_64 (reg0, reg1, reg0, reg1));
1608107590Sobrien          DONE;
1609107590Sobrien        }
1610107590Sobrien      else
1611107590Sobrien	{
1612107590Sobrien          rtx label1 = gen_label_rtx ();
1613107590Sobrien          rtx label2 = gen_label_rtx ();
1614107590Sobrien          rtx reg0, reg1, len, blocks;
1615107590Sobrien      		
1616107590Sobrien          reg0 = gen_reg_rtx (DImode);
1617107590Sobrien          reg1 = gen_reg_rtx (DImode);
1618107590Sobrien          len = gen_reg_rtx (DImode);
1619107590Sobrien          blocks = gen_reg_rtx (DImode);
1620107590Sobrien
1621107590Sobrien          emit_move_insn (len, operands[2]);	
1622107590Sobrien          emit_insn (gen_cmpdi (len, const0_rtx));
1623107590Sobrien          emit_jump_insn (gen_beq (label1));
1624107590Sobrien          emit_move_insn (reg0, addr0);
1625107590Sobrien          emit_move_insn (reg1, addr1);
1626107590Sobrien          emit_insn (gen_adddi3 (len, len, constm1_rtx));
1627107590Sobrien          emit_insn (gen_ashrdi3 (blocks, len, GEN_INT (8)));
1628107590Sobrien          emit_insn (gen_cmpdi (blocks, const0_rtx));
1629107590Sobrien          emit_jump_insn (gen_beq (label2));
1630107590Sobrien          emit_insn (gen_movstrdi_long (reg0, reg1, reg0, reg1, blocks, blocks));
1631107590Sobrien          emit_label (label2); 
1632107590Sobrien	  operands[0] = change_address (operands[0], VOIDmode, reg0);
1633107590Sobrien	  operands[1] = change_address (operands[1], VOIDmode, reg1);
1634107590Sobrien          emit_insn (gen_movstrdi_short (operands[0], operands[1], len));
1635107590Sobrien          emit_label (label1); 
1636107590Sobrien          DONE;	   
1637107590Sobrien       }	 
1638107590Sobrien    }
1639107590Sobrien}")
1640107590Sobrien
1641107590Sobrien;
1642107590Sobrien; movstrsi instruction pattern(s).
1643107590Sobrien;
1644107590Sobrien
1645107590Sobrien(define_expand "movstrsi"
1646107590Sobrien   [(set (match_operand:BLK 0 "general_operand" "")
1647107590Sobrien         (match_operand:BLK 1 "general_operand" ""))
1648107590Sobrien    (use (match_operand:SI 2 "general_operand" ""))
1649107590Sobrien    (match_operand 3 "" "")]
1650107590Sobrien    "!TARGET_64BIT"
1651107590Sobrien    "
1652107590Sobrien{
1653107590Sobrien  rtx addr0 = force_operand (XEXP (operands[0], 0), NULL_RTX);
1654107590Sobrien  rtx addr1 = force_operand (XEXP (operands[1], 0), NULL_RTX);
1655107590Sobrien
1656107590Sobrien  if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) <= 256)
1657107590Sobrien    {
1658107590Sobrien      operands[0] = change_address (operands[0], VOIDmode, addr0);
1659107590Sobrien      operands[1] = change_address (operands[1], VOIDmode, addr1);
1660107590Sobrien      operands[2] = GEN_INT (INTVAL (operands[2]) - 1);
1661107590Sobrien
1662107590Sobrien      emit_insn (gen_movstrsi_short (operands[0], operands[1], operands[2]));
1663107590Sobrien      DONE;
1664107590Sobrien    } 
1665107590Sobrien  else 
1666107590Sobrien    {
1667107590Sobrien      if (TARGET_MVCLE) 
1668107590Sobrien	{
1669107590Sobrien          /* implementation suggested by  Richard Henderson <rth@cygnus.com> */
1670107590Sobrien          rtx reg0 = gen_reg_rtx (DImode);
1671107590Sobrien          rtx reg1 = gen_reg_rtx (DImode);
1672107590Sobrien          rtx len = operands[2];
1673107590Sobrien
1674107590Sobrien
1675107590Sobrien          if (! CONSTANT_P (len))
1676107590Sobrien            len = force_reg (SImode, len);
1677107590Sobrien
1678107590Sobrien          /* Load up the address+length pairs.  */
1679107590Sobrien
1680107590Sobrien          emit_move_insn (gen_highpart (SImode, reg0), addr0);
1681107590Sobrien          emit_move_insn (gen_lowpart (SImode, reg0), len);
1682107590Sobrien
1683107590Sobrien          emit_move_insn (gen_highpart (SImode, reg1), addr1);
1684107590Sobrien          emit_move_insn (gen_lowpart (SImode, reg1), len);
1685107590Sobrien
1686107590Sobrien          /* MOVE */
1687107590Sobrien          emit_insn (gen_movstrsi_31 (reg0, reg1, reg0, reg1));
1688107590Sobrien          DONE;
1689107590Sobrien        }
1690107590Sobrien      else
1691107590Sobrien	{
1692107590Sobrien          rtx label1 = gen_label_rtx ();
1693107590Sobrien          rtx label2 = gen_label_rtx ();
1694107590Sobrien          rtx reg0, reg1, len, blocks;
1695107590Sobrien      		
1696107590Sobrien          reg0 = gen_reg_rtx (SImode);
1697107590Sobrien          reg1 = gen_reg_rtx (SImode);
1698107590Sobrien	  len = gen_reg_rtx (SImode); 
1699107590Sobrien	  blocks = gen_reg_rtx (SImode); 
1700107590Sobrien	  
1701107590Sobrien	  emit_move_insn (len, operands[2]);
1702107590Sobrien          emit_insn (gen_cmpsi (len, const0_rtx));
1703107590Sobrien          emit_jump_insn (gen_beq (label1));
1704107590Sobrien          emit_move_insn (reg0, addr0);
1705107590Sobrien          emit_move_insn (reg1, addr1);
1706107590Sobrien          emit_insn (gen_addsi3 (len, len, constm1_rtx));
1707107590Sobrien          emit_insn (gen_ashrsi3 (blocks, len, GEN_INT (8)));
1708107590Sobrien          emit_insn (gen_cmpsi (blocks, const0_rtx));
1709107590Sobrien          emit_jump_insn (gen_beq (label2));
1710107590Sobrien          emit_insn (gen_movstrsi_long (reg0, reg1, reg0, reg1, blocks, blocks));
1711107590Sobrien          emit_label (label2); 
1712107590Sobrien	  operands[0] = change_address (operands[0], VOIDmode, reg0);
1713107590Sobrien	  operands[1] = change_address (operands[1], VOIDmode, reg1);
1714107590Sobrien          emit_insn (gen_movstrsi_short (operands[0], operands[1], len));
1715107590Sobrien          emit_label (label1); 
1716107590Sobrien          DONE;	   
1717107590Sobrien       }	 
1718107590Sobrien    }
1719107590Sobrien}")
1720107590Sobrien
1721107590Sobrien; Move a block that is up to 256 bytes in length.
1722107590Sobrien; The block length is taken as (operands[2] % 256) + 1.
1723107590Sobrien
1724107590Sobrien(define_insn "movstrdi_short"
1725107590Sobrien  [(set (match_operand:BLK 0 "s_operand" "=oQ,oQ")
1726107590Sobrien        (match_operand:BLK 1 "s_operand" "oQ,oQ"))
1727107590Sobrien   (use (match_operand:DI 2 "nonmemory_operand" "n,a"))
1728107590Sobrien   (clobber (match_scratch:DI 3 "=X,&a"))]
1729107590Sobrien  "TARGET_64BIT"
1730107590Sobrien  "*
1731107590Sobrien{
1732107590Sobrien  switch (which_alternative)
1733107590Sobrien    {
1734107590Sobrien      case 0:
1735107590Sobrien	return \"mvc\\t%O0(%b2+1,%R0),%1\";
1736107590Sobrien
1737107590Sobrien      case 1:
1738107590Sobrien	output_asm_insn (\"bras\\t%3,.+10\", operands);
1739107590Sobrien	output_asm_insn (\"mvc\\t%O0(1,%R0),%1\", operands);
1740107590Sobrien	return \"ex\\t%2,0(%3)\";
1741107590Sobrien
1742107590Sobrien      default:
1743107590Sobrien        abort ();
1744107590Sobrien    }
1745107590Sobrien}"
1746107590Sobrien  [(set_attr "op_type" "SS,NN")
1747107590Sobrien   (set_attr "atype"   "mem,mem")
1748107590Sobrien   (set_attr "length"  "*,14")])
1749107590Sobrien
1750107590Sobrien(define_insn "movstrsi_short"
1751107590Sobrien  [(set (match_operand:BLK 0 "s_operand" "=oQ,oQ")
1752107590Sobrien        (match_operand:BLK 1 "s_operand" "oQ,oQ"))
1753107590Sobrien   (use (match_operand:SI 2 "nonmemory_operand" "n,a"))
1754107590Sobrien   (clobber (match_scratch:SI 3 "=X,&a"))]
1755107590Sobrien  "!TARGET_64BIT"
1756107590Sobrien  "*
1757107590Sobrien{
1758107590Sobrien  switch (which_alternative)
1759107590Sobrien    {
1760107590Sobrien      case 0:
1761107590Sobrien	return \"mvc\\t%O0(%b2+1,%R0),%1\";
1762107590Sobrien
1763107590Sobrien      case 1:
1764107590Sobrien	output_asm_insn (\"bras\\t%3,.+10\", operands);
1765107590Sobrien	output_asm_insn (\"mvc\\t%O0(1,%R0),%1\", operands);
1766107590Sobrien	return \"ex\\t%2,0(%3)\";
1767107590Sobrien
1768107590Sobrien      default:
1769107590Sobrien        abort ();
1770107590Sobrien    }
1771107590Sobrien}"
1772107590Sobrien  [(set_attr "op_type" "SS,NN")
1773107590Sobrien   (set_attr "atype"   "mem,mem")
1774107590Sobrien   (set_attr "length"  "*,14")])
1775107590Sobrien
1776107590Sobrien; Move a block that is a multiple of 256 bytes in length
1777107590Sobrien
1778107590Sobrien(define_insn "movstrdi_long"
1779107590Sobrien  [(set (match_operand:DI 4 "register_operand" "=d")
1780107590Sobrien        (const_int 0))
1781107590Sobrien   (set (match_operand:DI 0 "register_operand" "=a")
1782107590Sobrien        (plus:DI (match_operand:DI 2 "register_operand" "0")
1783107590Sobrien                 (ashift:DI (match_operand:DI 5 "register_operand" "4")
1784107590Sobrien                            (const_int 8))))
1785107590Sobrien   (set (match_operand:DI 1 "register_operand" "=a")
1786107590Sobrien        (plus:DI (match_operand:DI 3 "register_operand" "1")
1787107590Sobrien                 (ashift:DI (match_dup 5) (const_int 8))))
1788107590Sobrien   (set (mem:BLK (match_dup 2))
1789107590Sobrien        (mem:BLK (match_dup 3)))
1790107590Sobrien   (use (match_dup 5))]
1791107590Sobrien  "TARGET_64BIT"
1792107590Sobrien  "*
1793107590Sobrien{
1794107590Sobrien  output_asm_insn (\"mvc\\t0(256,%0),0(%1)\", operands);
1795107590Sobrien  output_asm_insn (\"la\\t%0,256(%0)\", operands);
1796107590Sobrien  output_asm_insn (\"la\\t%1,256(%1)\", operands);
1797107590Sobrien  return \"brct\\t%4,.-14\";
1798107590Sobrien}"
1799107590Sobrien  [(set_attr "op_type" "NN")
1800107590Sobrien   (set_attr "atype"   "mem")
1801107590Sobrien   (set_attr "length"  "18")])
1802107590Sobrien
1803107590Sobrien(define_insn "movstrsi_long"
1804107590Sobrien  [(set (match_operand:SI 4 "register_operand" "=d")
1805107590Sobrien        (const_int 0))
1806107590Sobrien   (set (match_operand:SI 0 "register_operand" "=a")
1807107590Sobrien        (plus:SI (match_operand:SI 2 "register_operand" "0")
1808107590Sobrien                 (ashift:SI (match_operand:SI 5 "register_operand" "4")
1809107590Sobrien                            (const_int 8))))
1810107590Sobrien   (set (match_operand:SI 1 "register_operand" "=a")
1811107590Sobrien        (plus:SI (match_operand:SI 3 "register_operand" "1")
1812107590Sobrien                 (ashift:SI (match_dup 5) (const_int 8))))
1813107590Sobrien   (set (mem:BLK (match_dup 2))
1814107590Sobrien        (mem:BLK (match_dup 3)))
1815107590Sobrien   (use (match_dup 5))]
1816107590Sobrien  "!TARGET_64BIT"
1817107590Sobrien  "*
1818107590Sobrien{
1819107590Sobrien  output_asm_insn (\"mvc\\t0(256,%0),0(%1)\", operands);
1820107590Sobrien  output_asm_insn (\"la\\t%0,256(%0)\", operands);
1821107590Sobrien  output_asm_insn (\"la\\t%1,256(%1)\", operands);
1822107590Sobrien  return \"brct\\t%4,.-14\";
1823107590Sobrien}"
1824107590Sobrien  [(set_attr "op_type" "NN")
1825107590Sobrien   (set_attr "atype"   "mem")
1826107590Sobrien   (set_attr "length"  "18")])
1827107590Sobrien
1828107590Sobrien; Move a block that is larger than 255 bytes in length.
1829107590Sobrien
1830107590Sobrien(define_insn "movstrdi_64"
1831107590Sobrien  [(set (match_operand:TI 0 "register_operand" "=d")
1832107590Sobrien        (ashift:TI (plus:TI (match_operand:TI 2 "register_operand" "0")
1833107590Sobrien                            (lshiftrt:TI (match_dup 2) (const_int 64)))
1834107590Sobrien                   (const_int 64)))
1835107590Sobrien   (set (match_operand:TI 1 "register_operand" "=d")
1836107590Sobrien        (ashift:TI (plus:TI (match_operand:TI 3 "register_operand" "1")
1837107590Sobrien                            (lshiftrt:TI (match_dup 3) (const_int 64)))
1838107590Sobrien                   (const_int 64)))
1839107590Sobrien   (set (mem:BLK (subreg:DI (match_dup 2) 0))
1840107590Sobrien        (mem:BLK (subreg:DI (match_dup 3) 0)))
1841107590Sobrien   (clobber (reg:CC 33))]
1842107590Sobrien  "TARGET_64BIT"
1843107590Sobrien  "mvcle\\t%0,%1,0\;jo\\t.-4"
1844107590Sobrien  [(set_attr "op_type" "NN")
1845107590Sobrien   (set_attr "atype"   "mem")
1846107590Sobrien   (set_attr "length"  "8")])
1847107590Sobrien
1848107590Sobrien(define_insn "movstrsi_31"
1849107590Sobrien  [(set (match_operand:DI 0 "register_operand" "=d")
1850107590Sobrien        (ashift:DI (plus:DI (match_operand:DI 2 "register_operand" "0")
1851107590Sobrien                            (lshiftrt:DI (match_dup 2) (const_int 32)))
1852107590Sobrien                   (const_int 32)))
1853107590Sobrien   (set (match_operand:DI 1 "register_operand" "=d")
1854107590Sobrien        (ashift:DI (plus:DI (match_operand:DI 3 "register_operand" "1")
1855107590Sobrien                            (lshiftrt:DI (match_dup 3) (const_int 32)))
1856107590Sobrien                   (const_int 32)))
1857107590Sobrien   (set (mem:BLK (subreg:SI (match_dup 2) 0))
1858107590Sobrien        (mem:BLK (subreg:SI (match_dup 3) 0)))
1859107590Sobrien   (clobber (reg:CC 33))]
1860107590Sobrien  "!TARGET_64BIT"
1861107590Sobrien  "mvcle\\t%0,%1,0\;jo\\t.-4"
1862107590Sobrien   [(set_attr "op_type" "NN")
1863107590Sobrien    (set_attr "atype" "mem")
1864107590Sobrien    (set_attr "length"  "8")])
1865107590Sobrien
1866107590Sobrien;
1867107590Sobrien; clrstrdi instruction pattern(s).
1868107590Sobrien;
1869107590Sobrien
1870107590Sobrien(define_expand "clrstrdi"
1871107590Sobrien  [(set (match_operand:BLK 0 "general_operand" "")
1872107590Sobrien        (const_int 0))
1873107590Sobrien   (use (match_operand:DI 1 "general_operand" ""))
1874107590Sobrien   (match_operand 2 "" "")]
1875107590Sobrien  "TARGET_64BIT"
1876107590Sobrien  "
1877107590Sobrien{
1878107590Sobrien   rtx addr = force_operand (XEXP (operands[0], 0), NULL_RTX);
1879107590Sobrien
1880107590Sobrien   operands[0] = change_address (operands[0], VOIDmode, addr);
1881107590Sobrien
1882107590Sobrien   if (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) < 256)
1883107590Sobrien     {
1884107590Sobrien        emit_insn (gen_clrstrsico (operands[0], operands[1]));
1885107590Sobrien        DONE;
1886107590Sobrien     }
1887107590Sobrien   else
1888107590Sobrien     {
1889107590Sobrien      rtx reg0 = gen_reg_rtx (TImode);
1890107590Sobrien      rtx reg1 = gen_reg_rtx (TImode);
1891107590Sobrien      rtx len = operands[1];
1892107590Sobrien
1893107590Sobrien      if (! CONSTANT_P (len))
1894107590Sobrien          len = force_reg (DImode, len);
1895107590Sobrien
1896107590Sobrien      /* Load up the address+length pairs.  */
1897107590Sobrien
1898107590Sobrien      emit_move_insn (gen_highpart (DImode, reg0), addr);
1899107590Sobrien      emit_move_insn (gen_lowpart (DImode, reg0), len);
1900107590Sobrien
1901107590Sobrien      emit_move_insn (gen_lowpart (DImode, reg1), const0_rtx);
1902107590Sobrien 
1903107590Sobrien      /* Clear! */
1904107590Sobrien      emit_insn (gen_clrstrsi_64 (reg0, reg1, reg0));
1905107590Sobrien      DONE;	
1906107590Sobrien     }
1907107590Sobrien}")
1908107590Sobrien
1909107590Sobrien;
1910107590Sobrien; clrstrsi instruction pattern(s).
1911107590Sobrien;
1912107590Sobrien
1913107590Sobrien(define_expand "clrstrsi"
1914107590Sobrien  [(set (match_operand:BLK 0 "general_operand" "")
1915107590Sobrien        (const_int 0))
1916107590Sobrien   (use (match_operand:SI 1 "general_operand" ""))
1917107590Sobrien   (match_operand 2 "" "")]
1918107590Sobrien   "!TARGET_64BIT"
1919107590Sobrien   "
1920107590Sobrien{
1921107590Sobrien   rtx addr = force_operand (XEXP (operands[0], 0), NULL_RTX);
1922107590Sobrien
1923107590Sobrien   operands[0] = change_address (operands[0], VOIDmode, addr);
1924107590Sobrien
1925107590Sobrien   if (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) < 256)
1926107590Sobrien     {
1927107590Sobrien        emit_insn (gen_clrstrsico (operands[0], operands[1]));
1928107590Sobrien        DONE;
1929107590Sobrien     }
1930107590Sobrien   else
1931107590Sobrien     {
1932107590Sobrien      rtx reg0 = gen_reg_rtx (DImode);
1933107590Sobrien      rtx reg1 = gen_reg_rtx (DImode);
1934107590Sobrien      rtx len = operands[1];
1935107590Sobrien
1936107590Sobrien      if (! CONSTANT_P (len))
1937107590Sobrien          len = force_reg (SImode, len);
1938107590Sobrien
1939107590Sobrien      /* Load up the address+length pairs.  */
1940107590Sobrien
1941107590Sobrien      emit_move_insn (gen_highpart (SImode, reg0), addr);
1942107590Sobrien      emit_move_insn (gen_lowpart (SImode, reg0), len);
1943107590Sobrien
1944107590Sobrien      emit_move_insn (gen_lowpart (SImode, reg1), const0_rtx);
1945107590Sobrien 
1946107590Sobrien      /* CLear! */
1947107590Sobrien      emit_insn (gen_clrstrsi_31 (reg0, reg1, reg0));
1948107590Sobrien      DONE;	
1949107590Sobrien     }
1950107590Sobrien}")
1951107590Sobrien
1952107590Sobrien; Clear memory with length less than 256 bytes 
1953107590Sobrien
1954107590Sobrien(define_insn "clrstrsico"
1955107590Sobrien  [(set (match_operand:BLK 0 "s_operand" "=Qo")
1956107590Sobrien        (const_int 0))
1957107590Sobrien   (use (match_operand 1 "immediate_operand" "I"))
1958107590Sobrien   (clobber (reg:CC 33))]
1959107590Sobrien  ""
1960107590Sobrien  "xc\\t%O0(%1,%R0),%0"	
1961107590Sobrien  [(set_attr "op_type" "RS")
1962107590Sobrien   (set_attr "type"    "cs")
1963107590Sobrien   (set_attr "atype"   "mem")])
1964107590Sobrien
1965107590Sobrien; Clear memory with length greater 256 bytes or lenght not constant
1966107590Sobrien
1967107590Sobrien(define_insn "clrstrsi_64"
1968107590Sobrien  [(set (match_operand:TI 0 "register_operand" "=d")
1969107590Sobrien        (ashift:TI (plus:TI (match_operand:TI 2 "register_operand" "0")
1970107590Sobrien                            (lshiftrt:TI (match_dup 2) (const_int 64)))
1971107590Sobrien                   (const_int 64)))
1972107590Sobrien   (set (mem:BLK (subreg:DI (match_dup 2) 0))
1973107590Sobrien        (const_int 0))
1974107590Sobrien   (use (match_operand:TI 1 "register_operand" "d"))
1975107590Sobrien   (clobber (reg:CC 33))]
1976107590Sobrien  "TARGET_64BIT"
1977107590Sobrien  "mvcle\\t%0,%1,0\;jo\\t.-4"
1978107590Sobrien  [(set_attr "op_type" "NN")
1979107590Sobrien   (set_attr "atype"   "mem")
1980107590Sobrien   (set_attr "type"    "vs")
1981107590Sobrien   (set_attr "length"  "8")])
1982107590Sobrien
1983107590Sobrien(define_insn "clrstrsi_31"
1984107590Sobrien  [(set (match_operand:DI 0 "register_operand" "=d")
1985107590Sobrien        (ashift:DI (plus:DI (match_operand:DI 2 "register_operand" "0")
1986107590Sobrien                            (lshiftrt:DI (match_dup 2) (const_int 32)))
1987107590Sobrien                   (const_int 32)))
1988107590Sobrien   (set (mem:BLK (subreg:SI (match_dup 2) 0))
1989107590Sobrien        (const_int 0))
1990107590Sobrien   (use (match_operand:DI 1 "register_operand" "d"))
1991107590Sobrien   (clobber (reg:CC 33))]
1992107590Sobrien  "!TARGET_64BIT"
1993107590Sobrien  "mvcle\\t%0,%1,0\;jo\\t.-4"
1994107590Sobrien  [(set_attr "op_type" "NN")
1995107590Sobrien   (set_attr "atype"   "mem")
1996107590Sobrien   (set_attr "type"    "vs")
1997107590Sobrien   (set_attr "length"  "8")])
1998107590Sobrien
1999107590Sobrien;
2000107590Sobrien; cmpstrdi instruction pattern(s).
2001107590Sobrien;
2002107590Sobrien
2003107590Sobrien(define_expand "cmpstrdi"
2004107590Sobrien   [(set (match_operand:DI 0 "register_operand" "")
2005107590Sobrien         (compare:DI (match_operand:BLK 1 "s_operand" "")
2006107590Sobrien                  (match_operand:BLK 2 "s_operand" "") ) )
2007107590Sobrien             (use (match_operand:DI 3  "general_operand" ""))
2008107590Sobrien             (use (match_operand:DI 4  "" ""))]
2009107590Sobrien   "TARGET_64BIT"
2010107590Sobrien   "
2011107590Sobrien{
2012107590Sobrien  rtx addr0, addr1;
2013107590Sobrien
2014107590Sobrien  /* for pre/post increment */
2015107590Sobrien  operands[1] = protect_from_queue (operands[1], 0);
2016107590Sobrien  operands[2] = protect_from_queue (operands[2], 0);
2017107590Sobrien  operands[3] = protect_from_queue (operands[3], 0);
2018107590Sobrien
2019107590Sobrien  addr0 = force_operand (XEXP (operands[1], 0), NULL_RTX);
2020107590Sobrien  addr1 = force_operand (XEXP (operands[2], 0), NULL_RTX);
2021107590Sobrien
2022107590Sobrien  if (GET_CODE (operands[3]) == CONST_INT && INTVAL (operands[3]) < 256) 
2023107590Sobrien    {
2024107590Sobrien      if (INTVAL (operands[3]) == 0) {
2025107590Sobrien	emit_move_insn (operands[0], operands[3]);
2026107590Sobrien	DONE;
2027107590Sobrien      }
2028107590Sobrien
2029107590Sobrien      operands[1] = change_address (operands[1], VOIDmode, addr0);
2030107590Sobrien      operands[2] = change_address (operands[2], VOIDmode, addr1);
2031107590Sobrien
2032107590Sobrien      emit_insn (gen_cmpstr_const (operands[1], operands[2], operands[3]));
2033107590Sobrien      emit_insn (gen_cmpint_di (operands[0]));
2034107590Sobrien      DONE;
2035107590Sobrien    }
2036107590Sobrien  else
2037107590Sobrien    {	
2038107590Sobrien      /* implementation suggested by  Richard Henderson <rth@cygnus.com> */
2039107590Sobrien      rtx reg0 = gen_reg_rtx (TImode);
2040107590Sobrien      rtx reg1 = gen_reg_rtx (TImode);
2041107590Sobrien      rtx len = operands[3];
2042107590Sobrien
2043107590Sobrien      if (! CONSTANT_P (len))
2044107590Sobrien          len = force_reg (DImode, len);
2045107590Sobrien
2046107590Sobrien      /* Load up the address+length pairs.  */
2047107590Sobrien      emit_move_insn (gen_highpart (DImode, reg0), addr0); 
2048107590Sobrien      emit_move_insn (gen_lowpart (DImode, reg0), len);
2049107590Sobrien
2050107590Sobrien      emit_move_insn (gen_highpart (DImode, reg1), addr1);
2051107590Sobrien      emit_move_insn (gen_lowpart (DImode, reg1), len);
2052107590Sobrien
2053107590Sobrien      /* Compare! */
2054107590Sobrien      emit_insn (gen_cmpstr_64 (reg0, reg1, reg0, reg1));
2055107590Sobrien      emit_insn (gen_cmpint_di (operands[0]));
2056107590Sobrien      DONE;
2057107590Sobrien    }
2058107590Sobrien}")
2059107590Sobrien
2060107590Sobrien;
2061107590Sobrien; cmpstrsi instruction pattern(s).
2062107590Sobrien;
2063107590Sobrien
2064107590Sobrien(define_expand "cmpstrsi"
2065107590Sobrien   [(set (match_operand:SI 0 "register_operand" "")
2066107590Sobrien         (compare:SI (match_operand:BLK 1 "s_operand" "")
2067107590Sobrien                  (match_operand:BLK 2 "s_operand" "") ) )
2068107590Sobrien             (use (match_operand:SI 3  "general_operand" ""))
2069107590Sobrien             (use (match_operand:SI 4  "" ""))]
2070107590Sobrien   ""
2071107590Sobrien   "
2072107590Sobrien{
2073107590Sobrien  rtx addr0, addr1;
2074107590Sobrien
2075107590Sobrien  /* for pre/post increment */
2076107590Sobrien  operands[1] = protect_from_queue (operands[1], 0);
2077107590Sobrien  operands[2] = protect_from_queue (operands[2], 0);
2078107590Sobrien  operands[3] = protect_from_queue (operands[3], 0);
2079107590Sobrien
2080107590Sobrien  addr0 = force_operand (XEXP (operands[1], 0), NULL_RTX);
2081107590Sobrien  addr1 = force_operand (XEXP (operands[2], 0), NULL_RTX);
2082107590Sobrien
2083107590Sobrien  if (GET_CODE (operands[3]) == CONST_INT && INTVAL (operands[3]) < 256) 
2084107590Sobrien    {
2085107590Sobrien      if (INTVAL (operands[3]) == 0) {
2086107590Sobrien	emit_move_insn (operands[0], operands[3]);
2087107590Sobrien	DONE;
2088107590Sobrien      }
2089107590Sobrien
2090107590Sobrien      operands[1] = change_address (operands[1], VOIDmode, addr0);
2091107590Sobrien      operands[2] = change_address (operands[2], VOIDmode, addr1);
2092107590Sobrien
2093107590Sobrien      emit_insn (gen_cmpstr_const (operands[1], operands[2], operands[3]));
2094107590Sobrien      emit_insn (gen_cmpint_si (operands[0]));
2095107590Sobrien      DONE;
2096107590Sobrien    }
2097107590Sobrien  else
2098107590Sobrien    {	
2099107590Sobrien      /* implementation suggested by  Richard Henderson <rth@cygnus.com> */
2100107590Sobrien      rtx reg0, reg1;
2101107590Sobrien      rtx len = operands[3];
2102107590Sobrien
2103107590Sobrien      if (TARGET_64BIT)
2104107590Sobrien	{
2105107590Sobrien	  reg0 = gen_reg_rtx (TImode);
2106107590Sobrien	  reg1 = gen_reg_rtx (TImode);
2107107590Sobrien	}
2108107590Sobrien      else
2109107590Sobrien	{
2110107590Sobrien	  reg0 = gen_reg_rtx (DImode);
2111107590Sobrien	  reg1 = gen_reg_rtx (DImode);
2112107590Sobrien        }  
2113107590Sobrien
2114107590Sobrien      /* Load up the address+length pairs.  */
2115107590Sobrien      emit_move_insn (gen_highpart (Pmode, reg0), addr0); 
2116107590Sobrien      convert_move (gen_lowpart (Pmode, reg0), len, 1);
2117107590Sobrien
2118107590Sobrien      emit_move_insn (gen_highpart (Pmode, reg1), addr1);
2119107590Sobrien      convert_move (gen_lowpart (Pmode, reg1), len, 1);
2120107590Sobrien
2121107590Sobrien      /* Compare! */
2122107590Sobrien      if (TARGET_64BIT) 
2123107590Sobrien          emit_insn (gen_cmpstr_64 (reg0, reg1, reg0, reg1));
2124107590Sobrien      else
2125107590Sobrien          emit_insn (gen_cmpstr_31 (reg0, reg1, reg0, reg1));
2126107590Sobrien
2127107590Sobrien      emit_insn (gen_cmpint_si (operands[0]));
2128107590Sobrien      DONE;
2129107590Sobrien    }
2130107590Sobrien}")
2131107590Sobrien
2132107590Sobrien; Compare a block that is less than 256 bytes in length.
2133107590Sobrien
2134107590Sobrien(define_insn "cmpstr_const"
2135107590Sobrien  [(set (reg:CCS 33)
2136107590Sobrien        (compare:CCS (match_operand:BLK 0 "s_operand" "oQ")
2137107590Sobrien                     (match_operand:BLK 1 "s_operand" "oQ")))
2138107590Sobrien   (use (match_operand 2 "immediate_operand" "I"))]
2139107590Sobrien  "(unsigned) INTVAL (operands[2]) < 256"
2140107590Sobrien  "clc\\t%O0(%c2,%R0),%1"
2141107590Sobrien  [(set_attr "op_type" "SS")
2142107590Sobrien   (set_attr "atype"   "mem")
2143107590Sobrien   (set_attr "type"    "cs")])
2144107590Sobrien
2145107590Sobrien; Compare a block that is larger than 255 bytes in length.
2146107590Sobrien
2147107590Sobrien(define_insn "cmpstr_64"
2148107590Sobrien  [(clobber (match_operand:TI 0 "register_operand" "=d"))
2149107590Sobrien   (clobber (match_operand:TI 1 "register_operand" "=d"))
2150107590Sobrien   (set (reg:CCS 33)
2151107590Sobrien        (compare:CCS (mem:BLK (subreg:DI (match_operand:TI 2 "register_operand" "0") 0))
2152107590Sobrien                     (mem:BLK (subreg:DI (match_operand:TI 3 "register_operand" "1") 0))))]
2153107590Sobrien  "TARGET_64BIT"
2154107590Sobrien  "clcl\\t%0,%1"
2155107590Sobrien  [(set_attr "op_type" "RR")
2156107590Sobrien   (set_attr "atype"   "mem")
2157107590Sobrien   (set_attr "type"    "vs")])
2158107590Sobrien
2159107590Sobrien(define_insn "cmpstr_31"
2160107590Sobrien  [(clobber (match_operand:DI 0 "register_operand" "=d"))
2161107590Sobrien   (clobber (match_operand:DI 1 "register_operand" "=d"))
2162107590Sobrien   (set (reg:CCS 33)
2163107590Sobrien        (compare:CCS (mem:BLK (subreg:SI (match_operand:DI 2 "register_operand" "0") 0))
2164107590Sobrien                     (mem:BLK (subreg:SI (match_operand:DI 3 "register_operand" "1") 0))))]
2165107590Sobrien  "!TARGET_64BIT"
2166107590Sobrien  "clcl\\t%0,%1"
2167107590Sobrien  [(set_attr "op_type" "RR")
2168107590Sobrien   (set_attr "atype"   "mem")
2169107590Sobrien   (set_attr "type"    "vs")])
2170107590Sobrien
2171107590Sobrien; Convert condition code to integer in range (-1, 0, 1)
2172107590Sobrien
2173107590Sobrien(define_insn "cmpint_si"
2174107590Sobrien  [(set (match_operand:SI 0 "register_operand" "=d")
2175107590Sobrien        (compare:SI (reg:CCS 33) (const_int 0)))]
2176107590Sobrien  ""
2177107590Sobrien  "*
2178107590Sobrien{
2179107590Sobrien   output_asm_insn (\"lhi\\t%0,1\", operands);
2180107590Sobrien   output_asm_insn (\"jh\\t.+12\", operands);
2181107590Sobrien   output_asm_insn (\"jl\\t.+6\", operands);
2182107590Sobrien   output_asm_insn (\"sr\\t%0,%0\", operands);
2183107590Sobrien   return \"lcr\\t%0,%0\";
2184107590Sobrien}"
2185107590Sobrien  [(set_attr "op_type" "NN")
2186107590Sobrien   (set_attr "length"  "16")
2187107590Sobrien   (set_attr "atype"   "reg")
2188107590Sobrien   (set_attr "type"    "other")])
2189107590Sobrien
2190107590Sobrien(define_insn "cmpint_di"
2191107590Sobrien  [(set (match_operand:DI 0 "register_operand" "=d")
2192107590Sobrien        (compare:DI (reg:CCS 33) (const_int 0)))]
2193107590Sobrien  "TARGET_64BIT"
2194107590Sobrien  "*
2195107590Sobrien{
2196107590Sobrien   output_asm_insn (\"lghi\\t%0,1\", operands);
2197107590Sobrien   output_asm_insn (\"jh\\t.+12\", operands);
2198107590Sobrien   output_asm_insn (\"jl\\t.+6\", operands);
2199107590Sobrien   output_asm_insn (\"sgr\\t%0,%0\", operands);
2200107590Sobrien   return \"lcgr\\t%0,%0\";
2201107590Sobrien}"
2202107590Sobrien  [(set_attr "op_type" "NN")
2203107590Sobrien   (set_attr "length"  "22")
2204107590Sobrien   (set_attr "atype"   "reg")
2205107590Sobrien   (set_attr "type"    "other")])
2206107590Sobrien
2207107590Sobrien
2208107590Sobrien;;
2209107590Sobrien;;- Conversion instructions.
2210107590Sobrien;;
2211107590Sobrien
2212107590Sobrien(define_insn "*sethighqisi"
2213107590Sobrien  [(set (match_operand:SI 0 "register_operand" "=d")
2214107590Sobrien        (unspec:SI [(match_operand:QI 1 "s_operand" "Qo")] 10))
2215107590Sobrien   (clobber (reg:CC 33))]
2216107590Sobrien  ""
2217107590Sobrien  "icm\\t%0,8,%1"
2218107590Sobrien  [(set_attr "op_type" "RS")
2219107590Sobrien   (set_attr "atype"   "mem")])
2220107590Sobrien
2221107590Sobrien(define_insn "*sethighhisi"
2222107590Sobrien  [(set (match_operand:SI 0 "register_operand" "=d")
2223107590Sobrien        (unspec:SI [(match_operand:HI 1 "s_operand" "Qo")] 10))
2224107590Sobrien   (clobber (reg:CC 33))]
2225107590Sobrien  ""
2226107590Sobrien  "icm\\t%0,12,%1"
2227107590Sobrien  [(set_attr "op_type" "RS")
2228107590Sobrien   (set_attr "atype"   "mem")])
2229107590Sobrien
2230107590Sobrien(define_insn "*sethighqidi_64"
2231107590Sobrien  [(set (match_operand:DI 0 "register_operand" "=d")
2232107590Sobrien        (unspec:DI [(match_operand:QI 1 "s_operand" "Qo")] 10))
2233107590Sobrien   (clobber (reg:CC 33))]
2234107590Sobrien  "TARGET_64BIT"
2235107590Sobrien  "icmh\\t%0,8,%1"
2236107590Sobrien  [(set_attr "op_type" "RSE")
2237107590Sobrien   (set_attr "atype"   "mem")])
2238107590Sobrien
2239107590Sobrien(define_insn "*sethighqidi_31"
2240107590Sobrien  [(set (match_operand:DI 0 "register_operand" "=d")
2241107590Sobrien        (unspec:DI [(match_operand:QI 1 "s_operand" "Qo")] 10))
2242107590Sobrien   (clobber (reg:CC 33))]
2243107590Sobrien  "!TARGET_64BIT"
2244107590Sobrien  "icm\\t%0,8,%1"
2245107590Sobrien  [(set_attr "op_type" "RS")
2246107590Sobrien   (set_attr "atype"   "mem")])
2247107590Sobrien
2248107590Sobrien(define_split
2249107590Sobrien  [(set (match_operand:SI 0 "register_operand" "")
2250107590Sobrien        (zero_extract:SI (match_operand:QI 1 "s_operand" "")
2251107590Sobrien                         (match_operand 2 "const_int_operand" "")
2252107590Sobrien                         (const_int 0)))]
2253107590Sobrien  "!TARGET_64BIT && !reload_completed
2254107590Sobrien   && INTVAL (operands[2]) > 0 && INTVAL (operands[2]) < 8"
2255107590Sobrien  [(parallel
2256107590Sobrien    [(set (match_dup 0) (unspec:SI [(match_dup 1)] 10))
2257107590Sobrien     (clobber (reg:CC 33))])
2258107590Sobrien    (set (match_dup 0) (lshiftrt:SI (match_dup 0) (match_dup 2)))]
2259107590Sobrien  "
2260107590Sobrien{
2261107590Sobrien  operands[2] = GEN_INT (32 - INTVAL (operands[2]));
2262107590Sobrien  operands[1] = change_address (operands[1], QImode, 0);
2263107590Sobrien}")
2264107590Sobrien
2265107590Sobrien(define_split
2266107590Sobrien  [(set (match_operand:SI 0 "register_operand" "")
2267107590Sobrien        (zero_extract:SI (match_operand:QI 1 "s_operand" "")
2268107590Sobrien                         (match_operand 2 "const_int_operand" "")
2269107590Sobrien                         (const_int 0)))]
2270107590Sobrien  "!TARGET_64BIT && !reload_completed
2271107590Sobrien   && INTVAL (operands[2]) >= 8 && INTVAL (operands[2]) < 16"
2272107590Sobrien  [(parallel
2273107590Sobrien    [(set (match_dup 0) (unspec:SI [(match_dup 1)] 10))
2274107590Sobrien     (clobber (reg:CC 33))])
2275107590Sobrien    (set (match_dup 0) (lshiftrt:SI (match_dup 0) (match_dup 2)))]
2276107590Sobrien  "
2277107590Sobrien{
2278107590Sobrien  operands[2] = GEN_INT (32 - INTVAL (operands[2]));
2279107590Sobrien  operands[1] = change_address (operands[1], HImode, 0);
2280107590Sobrien}")
2281107590Sobrien
2282107590Sobrien;
2283107590Sobrien; extendsidi2 instruction pattern(s).
2284107590Sobrien;
2285107590Sobrien
2286107590Sobrien(define_expand "extendsidi2"
2287107590Sobrien  [(set (match_operand:DI 0 "register_operand" "")
2288107590Sobrien        (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "")))]
2289107590Sobrien  ""
2290107590Sobrien  "
2291107590Sobrien{
2292107590Sobrien  if (!TARGET_64BIT)
2293107590Sobrien    {
2294107590Sobrien      emit_insn (gen_rtx_CLOBBER (VOIDmode, operands[0]));
2295107590Sobrien      emit_move_insn (gen_highpart (SImode, operands[0]), operands[1]);
2296107590Sobrien      emit_move_insn (gen_lowpart (SImode, operands[0]), const0_rtx);
2297107590Sobrien      emit_insn (gen_ashrdi3 (operands[0], operands[0], GEN_INT (32)));
2298107590Sobrien      DONE;
2299107590Sobrien    }
2300107590Sobrien}
2301107590Sobrien")
2302107590Sobrien
2303107590Sobrien(define_insn "*extendsidi2"
2304107590Sobrien  [(set (match_operand:DI 0 "register_operand" "=d,d")
2305107590Sobrien        (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "d,m")))]
2306107590Sobrien  "TARGET_64BIT"
2307107590Sobrien  "@
2308107590Sobrien   lgfr\\t%0,%1
2309107590Sobrien   lgf\\t%0,%1"
2310107590Sobrien  [(set_attr "op_type" "RRE,RXE")
2311107590Sobrien   (set_attr "atype"   "reg,mem")])
2312107590Sobrien
2313107590Sobrien;
2314107590Sobrien; extendhidi2 instruction pattern(s).
2315107590Sobrien;
2316107590Sobrien
2317107590Sobrien(define_expand "extendhidi2"
2318107590Sobrien  [(set (match_operand:DI 0 "register_operand" "")
2319107590Sobrien        (sign_extend:DI (match_operand:HI 1 "register_operand" "")))]
2320107590Sobrien  ""
2321107590Sobrien  "
2322107590Sobrien{
2323107590Sobrien  if (!TARGET_64BIT)
2324107590Sobrien    {
2325107590Sobrien      rtx tmp = gen_reg_rtx (SImode);
2326107590Sobrien      emit_insn (gen_extendhisi2 (tmp, operands[1]));
2327107590Sobrien      emit_insn (gen_extendsidi2 (operands[0], tmp));
2328107590Sobrien      DONE;
2329107590Sobrien    }
2330107590Sobrien  else
2331107590Sobrien    {
2332107590Sobrien      operands[1] = gen_lowpart (DImode, operands[1]);
2333107590Sobrien      emit_insn (gen_ashldi3 (operands[0], operands[1], GEN_INT (48)));
2334107590Sobrien      emit_insn (gen_ashrdi3 (operands[0], operands[0], GEN_INT (48))); 
2335107590Sobrien      DONE;
2336107590Sobrien    }
2337107590Sobrien}
2338107590Sobrien")
2339107590Sobrien
2340107590Sobrien(define_insn "*extendhidi2"
2341107590Sobrien  [(set (match_operand:DI 0 "register_operand" "=d")
2342107590Sobrien        (sign_extend:DI (match_operand:HI 1 "memory_operand" "m")))]
2343107590Sobrien  "TARGET_64BIT"
2344107590Sobrien  "lgh\\t%0,%1"
2345107590Sobrien  [(set_attr "op_type" "RXE")
2346107590Sobrien   (set_attr "atype"   "mem")])
2347107590Sobrien
2348107590Sobrien;
2349107590Sobrien; extendqidi2 instruction pattern(s).
2350107590Sobrien;
2351107590Sobrien
2352107590Sobrien(define_expand "extendqidi2"
2353107590Sobrien  [(set (match_operand:DI 0 "register_operand" "")
2354107590Sobrien        (sign_extend:DI (match_operand:QI 1 "register_operand" "")))]
2355107590Sobrien  ""
2356107590Sobrien  "
2357107590Sobrien{
2358107590Sobrien  if (!TARGET_64BIT)
2359107590Sobrien    {
2360107590Sobrien      rtx tmp = gen_reg_rtx (SImode);
2361107590Sobrien      emit_insn (gen_extendqisi2 (tmp, operands[1]));
2362107590Sobrien      emit_insn (gen_extendsidi2 (operands[0], tmp));
2363107590Sobrien      DONE;
2364107590Sobrien    }
2365107590Sobrien  else
2366107590Sobrien    {
2367107590Sobrien      operands[1] = gen_lowpart (DImode, operands[1]);
2368107590Sobrien      emit_insn (gen_ashldi3 (operands[0], operands[1], GEN_INT (56)));
2369107590Sobrien      emit_insn (gen_ashrdi3 (operands[0], operands[0], GEN_INT (56))); 
2370107590Sobrien      DONE;
2371107590Sobrien    }
2372107590Sobrien}
2373107590Sobrien")
2374107590Sobrien
2375107590Sobrien(define_split
2376107590Sobrien  [(set (match_operand:DI 0 "register_operand" "")
2377107590Sobrien        (sign_extend:DI (match_operand:QI 1 "s_operand" "")))]
2378107590Sobrien  "TARGET_64BIT && !reload_completed"
2379107590Sobrien  [(parallel
2380107590Sobrien    [(set (match_dup 0) (unspec:DI [(match_dup 1)] 10))
2381107590Sobrien     (clobber (reg:CC 33))])
2382107590Sobrien   (parallel
2383107590Sobrien    [(set (match_dup 0) (ashiftrt:DI (match_dup 0) (const_int 56)))
2384107590Sobrien     (clobber (reg:CC 33))])]
2385107590Sobrien  "")
2386107590Sobrien
2387107590Sobrien;
2388107590Sobrien; extendhisi2 instruction pattern(s).
2389107590Sobrien;
2390107590Sobrien
2391107590Sobrien(define_expand "extendhisi2"
2392107590Sobrien  [(set (match_operand:SI 0 "register_operand" "")
2393107590Sobrien        (sign_extend:SI (match_operand:HI 1 "register_operand" "")))]
2394107590Sobrien  ""
2395107590Sobrien  "
2396107590Sobrien{
2397107590Sobrien  operands[1] = gen_lowpart (SImode, operands[1]);
2398107590Sobrien  emit_insn (gen_ashlsi3 (operands[0], operands[1], GEN_INT (16)));
2399107590Sobrien  emit_insn (gen_ashrsi3 (operands[0], operands[0], GEN_INT (16))); 
2400107590Sobrien  DONE;
2401107590Sobrien}
2402107590Sobrien")
2403107590Sobrien
2404107590Sobrien(define_insn "*extendhisi2"
2405107590Sobrien  [(set (match_operand:SI 0 "register_operand" "=d")
2406107590Sobrien        (sign_extend:SI (match_operand:HI 1 "memory_operand" "m")))]
2407107590Sobrien  ""
2408107590Sobrien  "lh\\t%0,%1"
2409107590Sobrien  [(set_attr "op_type" "RX")
2410107590Sobrien   (set_attr "atype"   "mem")])
2411107590Sobrien
2412107590Sobrien;
2413107590Sobrien; extendqisi2 instruction pattern(s).
2414107590Sobrien;
2415107590Sobrien
2416107590Sobrien(define_expand "extendqisi2"
2417107590Sobrien  [(set (match_operand:SI 0 "register_operand" "")
2418107590Sobrien        (sign_extend:SI (match_operand:QI 1 "register_operand" "")))]
2419107590Sobrien  ""
2420107590Sobrien  "
2421107590Sobrien{
2422107590Sobrien  operands[1] = gen_lowpart (SImode, operands[1]);
2423107590Sobrien  emit_insn (gen_ashlsi3 (operands[0], operands[1], GEN_INT (24)));
2424107590Sobrien  emit_insn (gen_ashrsi3 (operands[0], operands[0], GEN_INT (24))); 
2425107590Sobrien  DONE;
2426107590Sobrien}
2427107590Sobrien")
2428107590Sobrien
2429107590Sobrien(define_split
2430107590Sobrien  [(set (match_operand:SI 0 "register_operand" "")
2431107590Sobrien        (sign_extend:SI (match_operand:QI 1 "s_operand" "")))]
2432107590Sobrien  "!reload_completed"
2433107590Sobrien  [(parallel
2434107590Sobrien    [(set (match_dup 0) (unspec:SI [(match_dup 1)] 10))
2435107590Sobrien     (clobber (reg:CC 33))])
2436107590Sobrien   (parallel
2437107590Sobrien    [(set (match_dup 0) (ashiftrt:SI (match_dup 0) (const_int 24)))
2438107590Sobrien     (clobber (reg:CC 33))])]
2439107590Sobrien  "")
2440107590Sobrien
2441107590Sobrien;
2442107590Sobrien; extendqihi2 instruction pattern(s).
2443107590Sobrien;
2444107590Sobrien
2445107590Sobrien
2446107590Sobrien;
2447107590Sobrien; zero_extendsidi2 instruction pattern(s).
2448107590Sobrien;
2449107590Sobrien
2450107590Sobrien(define_expand "zero_extendsidi2"
2451107590Sobrien  [(set (match_operand:DI 0 "register_operand" "")
2452107590Sobrien        (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "")))]
2453107590Sobrien  ""
2454107590Sobrien  "
2455107590Sobrien{
2456107590Sobrien  if (!TARGET_64BIT)
2457107590Sobrien    {
2458107590Sobrien      emit_insn (gen_rtx_CLOBBER (VOIDmode, operands[0]));
2459107590Sobrien      emit_move_insn (gen_lowpart (SImode, operands[0]), operands[1]);
2460107590Sobrien      emit_move_insn (gen_highpart (SImode, operands[0]), const0_rtx);
2461107590Sobrien      DONE;
2462107590Sobrien    }
2463107590Sobrien}
2464107590Sobrien")
2465107590Sobrien
2466107590Sobrien(define_insn "*zero_extendsidi2"
2467107590Sobrien  [(set (match_operand:DI 0 "register_operand" "=d,d")
2468107590Sobrien        (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "d,m")))]
2469107590Sobrien  "TARGET_64BIT"
2470107590Sobrien  "@
2471107590Sobrien   llgfr\\t%0,%1
2472107590Sobrien   llgf\\t%0,%1"
2473107590Sobrien  [(set_attr "op_type" "RRE,RXE")
2474107590Sobrien   (set_attr "atype"   "reg,mem")])
2475107590Sobrien
2476107590Sobrien;
2477107590Sobrien; zero_extendhidi2 instruction pattern(s).
2478107590Sobrien;
2479107590Sobrien
2480107590Sobrien(define_expand "zero_extendhidi2"
2481107590Sobrien  [(set (match_operand:DI 0 "register_operand" "")
2482107590Sobrien        (zero_extend:DI (match_operand:HI 1 "register_operand" "")))]
2483107590Sobrien  ""
2484107590Sobrien  "
2485107590Sobrien{
2486107590Sobrien  if (!TARGET_64BIT)
2487107590Sobrien    {
2488107590Sobrien      rtx tmp = gen_reg_rtx (SImode);
2489107590Sobrien      emit_insn (gen_zero_extendhisi2 (tmp, operands[1]));
2490107590Sobrien      emit_insn (gen_zero_extendsidi2 (operands[0], tmp));
2491107590Sobrien      DONE;
2492107590Sobrien    }
2493107590Sobrien  else
2494107590Sobrien    {
2495107590Sobrien      operands[1] = gen_lowpart (DImode, operands[1]);
2496107590Sobrien      emit_insn (gen_ashldi3 (operands[0], operands[1], GEN_INT (48)));
2497107590Sobrien      emit_insn (gen_lshrdi3 (operands[0], operands[0], GEN_INT (48))); 
2498107590Sobrien      DONE;
2499107590Sobrien    }
2500107590Sobrien}
2501107590Sobrien")
2502107590Sobrien
2503107590Sobrien(define_insn "*zero_extendhidi2"
2504107590Sobrien  [(set (match_operand:DI 0 "register_operand" "=d")
2505107590Sobrien        (zero_extend:DI (match_operand:HI 1 "memory_operand" "m")))]
2506107590Sobrien  "TARGET_64BIT"
2507107590Sobrien  "llgh\\t%0,%1"
2508107590Sobrien  [(set_attr "op_type" "RXE")
2509107590Sobrien   (set_attr "atype"   "mem")])
2510107590Sobrien
2511107590Sobrien;
2512107590Sobrien; zero_extendqidi2 instruction pattern(s)
2513107590Sobrien;
2514107590Sobrien
2515107590Sobrien(define_expand "zero_extendqidi2"
2516107590Sobrien  [(set (match_operand:DI 0 "register_operand" "")
2517107590Sobrien        (zero_extend:DI (match_operand:QI 1 "register_operand" "")))]
2518107590Sobrien  ""
2519107590Sobrien  "
2520107590Sobrien{
2521107590Sobrien  if (!TARGET_64BIT)
2522107590Sobrien    {
2523107590Sobrien      rtx tmp = gen_reg_rtx (SImode);
2524107590Sobrien      emit_insn (gen_zero_extendqisi2 (tmp, operands[1]));
2525107590Sobrien      emit_insn (gen_zero_extendsidi2 (operands[0], tmp));
2526107590Sobrien      DONE;
2527107590Sobrien    }
2528107590Sobrien  else
2529107590Sobrien    {
2530107590Sobrien      operands[1] = gen_lowpart (DImode, operands[1]);
2531107590Sobrien      emit_insn (gen_ashldi3 (operands[0], operands[1], GEN_INT (56)));
2532107590Sobrien      emit_insn (gen_lshrdi3 (operands[0], operands[0], GEN_INT (56))); 
2533107590Sobrien      DONE;
2534107590Sobrien    }
2535107590Sobrien}
2536107590Sobrien")
2537107590Sobrien
2538107590Sobrien(define_insn "*zero_extendqidi2"
2539107590Sobrien  [(set (match_operand:DI 0 "register_operand" "=d")
2540107590Sobrien        (zero_extend:DI (match_operand:QI 1 "memory_operand" "m")))]
2541107590Sobrien  "TARGET_64BIT"
2542107590Sobrien  "llgc\\t%0,%1"
2543107590Sobrien  [(set_attr "op_type" "RXE")
2544107590Sobrien   (set_attr "atype"   "mem")])
2545107590Sobrien
2546107590Sobrien;
2547107590Sobrien; zero_extendhisi2 instruction pattern(s).
2548107590Sobrien;
2549107590Sobrien
2550107590Sobrien(define_expand "zero_extendhisi2"
2551107590Sobrien  [(set (match_operand:SI 0 "register_operand" "")
2552107590Sobrien        (zero_extend:SI (match_operand:HI 1 "register_operand" "")))]
2553107590Sobrien  ""
2554107590Sobrien  "
2555107590Sobrien{
2556107590Sobrien  operands[1] = gen_lowpart (SImode, operands[1]);
2557107590Sobrien  emit_insn (gen_andsi3 (operands[0], operands[1], GEN_INT (0xffff)));
2558107590Sobrien  DONE;
2559107590Sobrien}
2560107590Sobrien")
2561107590Sobrien
2562107590Sobrien(define_insn "*zero_extendhisi2_64"
2563107590Sobrien  [(set (match_operand:SI 0 "register_operand" "=d")
2564107590Sobrien        (zero_extend:SI (match_operand:HI 1 "memory_operand" "m")))]
2565107590Sobrien  "TARGET_64BIT"
2566107590Sobrien  "llgh\\t%0,%1"
2567107590Sobrien  [(set_attr "op_type" "RXE")
2568107590Sobrien   (set_attr "atype"   "mem")])
2569107590Sobrien 
2570107590Sobrien;
2571107590Sobrien; zero_extendqisi2 instruction pattern(s).
2572107590Sobrien;
2573107590Sobrien
2574107590Sobrien(define_expand "zero_extendqisi2"
2575107590Sobrien  [(set (match_operand:SI 0 "register_operand" "")
2576107590Sobrien        (zero_extend:SI (match_operand:QI 1 "register_operand" "")))]
2577107590Sobrien  ""
2578107590Sobrien  "
2579107590Sobrien{
2580107590Sobrien  operands[1] = gen_lowpart (SImode, operands[1]);
2581107590Sobrien  emit_insn (gen_andsi3 (operands[0], operands[1], GEN_INT (0xff)));
2582107590Sobrien  DONE;
2583107590Sobrien}
2584107590Sobrien")
2585107590Sobrien
2586107590Sobrien(define_insn "*zero_extendqisi2_64"
2587107590Sobrien  [(set (match_operand:SI 0 "register_operand" "=d")
2588107590Sobrien        (zero_extend:SI (match_operand:QI 1 "memory_operand" "m")))]
2589107590Sobrien  "TARGET_64BIT"
2590107590Sobrien  "llgc\\t%0,%1"
2591107590Sobrien  [(set_attr "op_type" "RXE")
2592107590Sobrien   (set_attr "atype"   "mem")])
2593107590Sobrien 
2594107590Sobrien;
2595107590Sobrien; zero_extendqihi2 instruction pattern(s).
2596107590Sobrien;
2597107590Sobrien
2598107590Sobrien(define_expand "zero_extendqihi2"
2599107590Sobrien  [(set (match_operand:HI 0 "register_operand" "")
2600107590Sobrien        (zero_extend:HI (match_operand:QI 1 "register_operand" "")))]
2601107590Sobrien  "TARGET_64BIT"
2602107590Sobrien  "
2603107590Sobrien{
2604107590Sobrien  operands[1] = gen_lowpart (HImode, operands[1]);
2605107590Sobrien  emit_insn (gen_andhi3 (operands[0], operands[1], GEN_INT (0xff)));
2606107590Sobrien  DONE;
2607107590Sobrien}
2608107590Sobrien")
2609107590Sobrien
2610107590Sobrien(define_insn "*zero_extendqihi2_64"
2611107590Sobrien  [(set (match_operand:HI 0 "register_operand" "=d")
2612107590Sobrien        (zero_extend:HI (match_operand:QI 1 "memory_operand" "m")))
2613107590Sobrien   (clobber (reg:CC 33))]
2614107590Sobrien  "TARGET_64BIT"
2615107590Sobrien  "llgc\\t%0,%1"
2616107590Sobrien  [(set_attr "op_type" "RXE")
2617107590Sobrien   (set_attr "atype"   "mem")])
2618107590Sobrien
2619107590Sobrien;
2620107590Sobrien; fixuns_truncdfdi2 and fix_truncdfsi2 instruction pattern(s).
2621107590Sobrien;
2622107590Sobrien
2623107590Sobrien(define_expand "fixuns_truncdfdi2"
2624107590Sobrien  [(set (match_operand:DI 0 "register_operand" "")
2625107590Sobrien        (unsigned_fix:DI (match_operand:DF 1 "register_operand" "")))]
2626107590Sobrien  "TARGET_64BIT && TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT"
2627107590Sobrien  "
2628107590Sobrien{
2629107590Sobrien  rtx label1 = gen_label_rtx ();
2630107590Sobrien  rtx label2 = gen_label_rtx ();
2631107590Sobrien  rtx temp = gen_reg_rtx (DFmode);
2632107590Sobrien  operands[1] = force_reg (DFmode, operands[1]);
2633107590Sobrien
2634107590Sobrien  emit_insn (gen_cmpdf (operands[1], 
2635107590Sobrien	CONST_DOUBLE_FROM_REAL_VALUE (
2636107590Sobrien          REAL_VALUE_ATOF (\"9223372036854775808.0\", DFmode), DFmode)));
2637107590Sobrien  emit_jump_insn (gen_blt (label1));
2638107590Sobrien  emit_insn (gen_subdf3 (temp, operands[1],
2639107590Sobrien	CONST_DOUBLE_FROM_REAL_VALUE (
2640107590Sobrien          REAL_VALUE_ATOF (\"18446744073709551616.0\", DFmode), DFmode)));
2641107590Sobrien  emit_insn (gen_fix_truncdfdi2_ieee (operands[0], temp, GEN_INT(7)));
2642107590Sobrien  emit_jump (label2);
2643107590Sobrien
2644107590Sobrien  emit_label (label1);
2645107590Sobrien  emit_insn (gen_fix_truncdfdi2_ieee (operands[0], operands[1], GEN_INT(5)));
2646107590Sobrien  emit_label (label2);
2647107590Sobrien  DONE;
2648107590Sobrien}")
2649107590Sobrien
2650107590Sobrien(define_expand "fix_truncdfdi2"
2651107590Sobrien  [(set (match_operand:DI 0 "register_operand" "")
2652107590Sobrien        (fix:DI (match_operand:DF 1 "nonimmediate_operand" "")))]
2653107590Sobrien  "TARGET_64BIT && TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT"
2654107590Sobrien  "
2655107590Sobrien{
2656107590Sobrien  operands[1] = force_reg (DFmode, operands[1]);
2657107590Sobrien  emit_insn (gen_fix_truncdfdi2_ieee (operands[0], operands[1], GEN_INT(5)));
2658107590Sobrien  DONE;
2659107590Sobrien}")
2660107590Sobrien
2661107590Sobrien(define_insn "fix_truncdfdi2_ieee"
2662107590Sobrien  [(set (match_operand:DI 0 "register_operand" "=d")
2663107590Sobrien        (fix:DI (match_operand:DF 1 "register_operand" "f")))
2664107590Sobrien   (unspec:DI [(match_operand:DI 2 "immediate_operand" "K")] 1)
2665107590Sobrien   (clobber (reg:CC 33))]
2666107590Sobrien  "TARGET_64BIT && TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT"
2667107590Sobrien  "cgdbr\\t%0,%h2,%1"
2668107590Sobrien  [(set_attr "op_type" "RRE")
2669107590Sobrien   (set_attr "type"    "other")])
2670107590Sobrien
2671107590Sobrien;
2672107590Sobrien; fixuns_truncdfsi2 and fix_truncdfsi2 instruction pattern(s).
2673107590Sobrien;
2674107590Sobrien
2675107590Sobrien(define_expand "fixuns_truncdfsi2"
2676107590Sobrien  [(set (match_operand:SI 0 "register_operand" "")
2677107590Sobrien        (unsigned_fix:SI (match_operand:DF 1 "register_operand" "")))]
2678107590Sobrien  "TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT"
2679107590Sobrien  "
2680107590Sobrien{
2681107590Sobrien  rtx label1 = gen_label_rtx ();
2682107590Sobrien  rtx label2 = gen_label_rtx ();
2683107590Sobrien  rtx temp = gen_reg_rtx (DFmode);
2684107590Sobrien
2685107590Sobrien  operands[1] = force_reg (DFmode,operands[1]);
2686107590Sobrien  emit_insn (gen_cmpdf (operands[1], 
2687107590Sobrien	CONST_DOUBLE_FROM_REAL_VALUE (
2688107590Sobrien          REAL_VALUE_ATOF (\"2147483648.0\", DFmode), DFmode)));
2689107590Sobrien  emit_jump_insn (gen_blt (label1));
2690107590Sobrien  emit_insn (gen_subdf3 (temp, operands[1],
2691107590Sobrien	CONST_DOUBLE_FROM_REAL_VALUE (
2692107590Sobrien          REAL_VALUE_ATOF (\"4294967296.0\", DFmode), DFmode)));
2693107590Sobrien  emit_insn (gen_fix_truncdfsi2_ieee (operands[0], temp, GEN_INT (7)));
2694107590Sobrien  emit_jump (label2);
2695107590Sobrien
2696107590Sobrien  emit_label (label1);
2697107590Sobrien  emit_insn (gen_fix_truncdfsi2_ieee (operands[0], operands[1], GEN_INT (5)));
2698107590Sobrien  emit_label (label2);
2699107590Sobrien  DONE;
2700107590Sobrien}")
2701107590Sobrien
2702107590Sobrien(define_expand "fix_truncdfsi2"
2703107590Sobrien  [(set (match_operand:SI 0 "register_operand" "")
2704107590Sobrien        (fix:SI (match_operand:DF 1 "nonimmediate_operand" "")))]
2705107590Sobrien  "TARGET_HARD_FLOAT"
2706107590Sobrien  "
2707107590Sobrien{
2708107590Sobrien  if (TARGET_IBM_FLOAT) 
2709107590Sobrien    {
2710107590Sobrien      /* This is the algorithm from POP chapter A.5.7.2.  */
2711107590Sobrien
2712107590Sobrien      rtx temp   = assign_stack_local (BLKmode, 2 * UNITS_PER_WORD, BITS_PER_WORD);
2713107590Sobrien      rtx two31r = s390_gen_rtx_const_DI (0x4f000000, 0x08000000);
2714107590Sobrien      rtx two32  = s390_gen_rtx_const_DI (0x4e000001, 0x00000000);
2715107590Sobrien
2716107590Sobrien      operands[1] = force_reg (DFmode, operands[1]);
2717107590Sobrien      emit_insn (gen_fix_truncdfsi2_ibm (operands[0], operands[1], 
2718107590Sobrien					 two31r, two32, temp));
2719107590Sobrien    } 
2720107590Sobrien  else 
2721107590Sobrien    {
2722107590Sobrien      operands[1] = force_reg (DFmode, operands[1]);
2723107590Sobrien      emit_insn (gen_fix_truncdfsi2_ieee (operands[0], operands[1], GEN_INT (5)));
2724107590Sobrien    }
2725107590Sobrien
2726107590Sobrien  DONE;
2727107590Sobrien}")
2728107590Sobrien
2729107590Sobrien(define_insn "fix_truncdfsi2_ieee"
2730107590Sobrien  [(set (match_operand:SI 0 "register_operand" "=d")
2731107590Sobrien        (fix:SI (match_operand:DF 1 "register_operand" "f")))
2732107590Sobrien    (unspec:SI [(match_operand:SI 2 "immediate_operand" "K")] 1)
2733107590Sobrien    (clobber (reg:CC 33))]
2734107590Sobrien  "TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT"
2735107590Sobrien  "cfdbr\\t%0,%h2,%1"
2736107590Sobrien   [(set_attr "op_type" "RRE")
2737107590Sobrien    (set_attr "type"    "other" )])
2738107590Sobrien
2739107590Sobrien(define_insn "fix_truncdfsi2_ibm"
2740107590Sobrien  [(set (match_operand:SI 0 "register_operand" "=d")
2741107590Sobrien        (fix:SI (match_operand:DF 1 "nonimmediate_operand" "+f")))
2742107590Sobrien   (use (match_operand:DI 2 "immediate_operand" "m"))
2743107590Sobrien   (use (match_operand:DI 3 "immediate_operand" "m"))
2744107590Sobrien   (use (match_operand:BLK 4 "memory_operand" "m"))
2745107590Sobrien   (clobber (reg:CC 33))]
2746107590Sobrien  "TARGET_HARD_FLOAT && TARGET_IBM_FLOAT"
2747107590Sobrien  "*
2748107590Sobrien{
2749107590Sobrien   output_asm_insn (\"sd\\t%1,%2\", operands);
2750107590Sobrien   output_asm_insn (\"aw\\t%1,%3\", operands);
2751107590Sobrien   output_asm_insn (\"std\\t%1,%4\", operands);
2752107590Sobrien   output_asm_insn (\"xi\\t%N4,128\", operands);
2753107590Sobrien   return \"l\\t%0,%N4\";
2754107590Sobrien}"
2755107590Sobrien  [(set_attr "op_type" "NN")
2756107590Sobrien   (set_attr "type"    "other")
2757107590Sobrien   (set_attr "length"  "20")])
2758107590Sobrien
2759107590Sobrien;
2760107590Sobrien; fixuns_truncsfdi2 and fix_truncsfdi2 instruction pattern(s).
2761107590Sobrien;
2762107590Sobrien
2763107590Sobrien(define_expand "fixuns_truncsfdi2"
2764107590Sobrien  [(set (match_operand:DI 0 "register_operand" "")
2765107590Sobrien        (unsigned_fix:DI (match_operand:SF 1 "register_operand" "")))]
2766107590Sobrien  "TARGET_64BIT && TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT"
2767107590Sobrien  "
2768107590Sobrien{
2769107590Sobrien  rtx label1 = gen_label_rtx ();
2770107590Sobrien  rtx label2 = gen_label_rtx ();
2771107590Sobrien  rtx temp = gen_reg_rtx (SFmode);
2772107590Sobrien
2773107590Sobrien  operands[1] = force_reg (SFmode, operands[1]);
2774107590Sobrien  emit_insn (gen_cmpsf (operands[1], 
2775107590Sobrien	CONST_DOUBLE_FROM_REAL_VALUE (
2776107590Sobrien          REAL_VALUE_ATOF (\"9223372036854775808.0\", SFmode), SFmode)));
2777107590Sobrien  emit_jump_insn (gen_blt (label1));
2778107590Sobrien
2779107590Sobrien  emit_insn (gen_subsf3 (temp, operands[1],
2780107590Sobrien	CONST_DOUBLE_FROM_REAL_VALUE (
2781107590Sobrien          REAL_VALUE_ATOF (\"18446744073709551616.0\", SFmode), SFmode)));
2782107590Sobrien  emit_insn (gen_fix_truncsfdi2_ieee (operands[0], temp, GEN_INT(7)));
2783107590Sobrien  emit_jump (label2);
2784107590Sobrien
2785107590Sobrien  emit_label (label1);
2786107590Sobrien  emit_insn (gen_fix_truncsfdi2_ieee (operands[0], operands[1], GEN_INT(5)));
2787107590Sobrien  emit_label (label2);
2788107590Sobrien  DONE;
2789107590Sobrien}")
2790107590Sobrien
2791107590Sobrien(define_expand "fix_truncsfdi2"
2792107590Sobrien  [(set (match_operand:DI 0 "register_operand" "")
2793107590Sobrien        (fix:DI (match_operand:SF 1 "nonimmediate_operand" "")))]
2794107590Sobrien  "TARGET_64BIT && TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT"
2795107590Sobrien  "
2796107590Sobrien{
2797107590Sobrien  operands[1] = force_reg (SFmode, operands[1]);
2798107590Sobrien  emit_insn (gen_fix_truncsfdi2_ieee (operands[0], operands[1], GEN_INT(5)));
2799107590Sobrien  DONE;
2800107590Sobrien}")
2801107590Sobrien
2802107590Sobrien(define_insn "fix_truncsfdi2_ieee"
2803107590Sobrien  [(set (match_operand:DI 0 "register_operand" "=d")
2804107590Sobrien        (fix:DI (match_operand:SF 1 "register_operand"  "f")))
2805107590Sobrien   (unspec:DI [(match_operand:DI 2 "immediate_operand" "K")] 1)
2806107590Sobrien   (clobber (reg:CC 33))]
2807107590Sobrien  "TARGET_64BIT && TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT"
2808107590Sobrien  "cgebr\\t%0,%h2,%1"
2809107590Sobrien  [(set_attr "op_type" "RRE")
2810107590Sobrien   (set_attr "type"    "other")])
2811107590Sobrien
2812107590Sobrien;
2813107590Sobrien; fixuns_truncsfsi2 and fix_truncsfsi2 instruction pattern(s).
2814107590Sobrien;
2815107590Sobrien
2816107590Sobrien(define_expand "fixuns_truncsfsi2"
2817107590Sobrien  [(set (match_operand:SI 0 "register_operand" "")
2818107590Sobrien        (unsigned_fix:SI (match_operand:SF 1 "register_operand" "")))]
2819107590Sobrien  "TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT"
2820107590Sobrien  "
2821107590Sobrien{
2822107590Sobrien  rtx label1 = gen_label_rtx ();
2823107590Sobrien  rtx label2 = gen_label_rtx ();
2824107590Sobrien  rtx temp = gen_reg_rtx (SFmode);
2825107590Sobrien
2826107590Sobrien  operands[1] = force_reg (SFmode, operands[1]);
2827107590Sobrien  emit_insn (gen_cmpsf (operands[1],
2828107590Sobrien	CONST_DOUBLE_FROM_REAL_VALUE (
2829107590Sobrien          REAL_VALUE_ATOF (\"2147483648.0\", SFmode), SFmode)));
2830107590Sobrien  emit_jump_insn (gen_blt (label1));
2831107590Sobrien  emit_insn (gen_subsf3 (temp, operands[1],
2832107590Sobrien	CONST_DOUBLE_FROM_REAL_VALUE (
2833107590Sobrien          REAL_VALUE_ATOF (\"4294967296.0\", SFmode), SFmode)));
2834107590Sobrien  emit_insn (gen_fix_truncsfsi2_ieee (operands[0], temp, GEN_INT (7)));
2835107590Sobrien  emit_jump (label2);
2836107590Sobrien
2837107590Sobrien  emit_label (label1);
2838107590Sobrien  emit_insn (gen_fix_truncsfsi2_ieee (operands[0], operands[1], GEN_INT (5)));
2839107590Sobrien  emit_label (label2);
2840107590Sobrien  DONE;
2841107590Sobrien}")
2842107590Sobrien
2843107590Sobrien(define_expand "fix_truncsfsi2"
2844107590Sobrien  [(set (match_operand:SI 0 "register_operand" "")
2845107590Sobrien        (fix:SI (match_operand:SF 1 "nonimmediate_operand" "")))]
2846107590Sobrien  "TARGET_HARD_FLOAT"
2847107590Sobrien  "
2848107590Sobrien{
2849107590Sobrien  if (TARGET_IBM_FLOAT)
2850107590Sobrien    {
2851107590Sobrien      /* Convert to DFmode and then use the POP algorithm.  */
2852107590Sobrien      rtx temp = gen_reg_rtx (DFmode);
2853107590Sobrien      emit_insn (gen_extendsfdf2 (temp, operands[1]));
2854107590Sobrien      emit_insn (gen_fix_truncdfsi2 (operands[0], temp));
2855107590Sobrien    }
2856107590Sobrien  else
2857107590Sobrien    {
2858107590Sobrien      operands[1] = force_reg (SFmode, operands[1]);
2859107590Sobrien      emit_insn (gen_fix_truncsfsi2_ieee (operands[0], operands[1], GEN_INT (5)));
2860107590Sobrien    }
2861107590Sobrien
2862107590Sobrien  DONE;
2863107590Sobrien}")
2864107590Sobrien
2865107590Sobrien(define_insn "fix_truncsfsi2_ieee"
2866107590Sobrien  [(set (match_operand:SI 0 "register_operand" "=d")
2867107590Sobrien        (fix:SI (match_operand:SF 1 "register_operand" "f")))
2868107590Sobrien    (unspec:SI [(match_operand:SI 2 "immediate_operand" "K")] 1)
2869107590Sobrien    (clobber (reg:CC 33))]
2870107590Sobrien  "TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT"
2871107590Sobrien  "cfebr\\t%0,%h2,%1"
2872107590Sobrien  [(set_attr "op_type" "RRE")
2873107590Sobrien   (set_attr "type"    "other")])
2874107590Sobrien
2875107590Sobrien;
2876107590Sobrien; floatdidf2 instruction pattern(s).
2877107590Sobrien;
2878107590Sobrien
2879107590Sobrien(define_insn "floatdidf2"
2880107590Sobrien  [(set (match_operand:DF 0 "register_operand" "=f")
2881107590Sobrien        (float:DF (match_operand:DI 1 "register_operand" "d")))
2882107590Sobrien   (clobber (reg:CC 33))]
2883107590Sobrien  "TARGET_64BIT && TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT"
2884107590Sobrien  "cdgbr\\t%0,%1"
2885107590Sobrien  [(set_attr "op_type" "RRE")
2886107590Sobrien   (set_attr "type"    "other" )])
2887107590Sobrien
2888107590Sobrien;
2889107590Sobrien; floatdisf2 instruction pattern(s).
2890107590Sobrien;
2891107590Sobrien
2892107590Sobrien(define_insn "floatdisf2"
2893107590Sobrien  [(set (match_operand:SF 0 "register_operand" "=f")
2894107590Sobrien        (float:SF (match_operand:DI 1 "register_operand" "d")))
2895107590Sobrien   (clobber (reg:CC 33))]
2896107590Sobrien  "TARGET_64BIT && TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT"
2897107590Sobrien  "cegbr\\t%0,%1"
2898107590Sobrien  [(set_attr "op_type" "RRE")
2899107590Sobrien   (set_attr "type"    "other" )])
2900107590Sobrien
2901107590Sobrien;
2902107590Sobrien; floatsidf2 instruction pattern(s).
2903107590Sobrien;
2904107590Sobrien
2905107590Sobrien(define_expand "floatsidf2"
2906107590Sobrien  [(parallel
2907107590Sobrien    [(set (match_operand:DF 0 "register_operand" "")
2908107590Sobrien          (float:DF (match_operand:SI 1 "register_operand" "")))
2909107590Sobrien     (clobber (reg:CC 33))])]
2910107590Sobrien  "TARGET_HARD_FLOAT"
2911107590Sobrien  "
2912107590Sobrien{
2913107590Sobrien  if (TARGET_IBM_FLOAT) 
2914107590Sobrien    {
2915107590Sobrien      /* This is the algorithm from POP chapter A.5.7.1.  */
2916107590Sobrien
2917107590Sobrien      rtx temp  = assign_stack_local (BLKmode, 2 * UNITS_PER_WORD, BITS_PER_WORD);
2918107590Sobrien      rtx two31 = s390_gen_rtx_const_DI (0x4e000000, 0x80000000);	   
2919107590Sobrien
2920107590Sobrien      emit_insn (gen_floatsidf2_ibm (operands[0], operands[1], two31, temp));
2921107590Sobrien      DONE;
2922107590Sobrien    }
2923107590Sobrien}")
2924107590Sobrien
2925107590Sobrien(define_insn "floatsidf2_ieee"
2926107590Sobrien  [(set (match_operand:DF 0 "register_operand" "=f")
2927107590Sobrien        (float:DF (match_operand:SI 1 "register_operand"  "d")))
2928107590Sobrien   (clobber (reg:CC 33))]
2929107590Sobrien  "TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT"
2930107590Sobrien  "cdfbr\\t%0,%1"
2931107590Sobrien  [(set_attr "op_type" "RRE")
2932107590Sobrien   (set_attr "type"   "other" )])
2933107590Sobrien
2934107590Sobrien(define_insn "floatsidf2_ibm"
2935107590Sobrien  [(set (match_operand:DF 0 "register_operand" "=f")
2936107590Sobrien        (float:DF (match_operand:SI 1 "register_operand" "d")))
2937107590Sobrien   (use (match_operand:DI 2 "immediate_operand" "m"))
2938107590Sobrien   (use (match_operand:BLK 3 "memory_operand" "m"))
2939107590Sobrien   (clobber (reg:CC 33))]
2940107590Sobrien  "TARGET_HARD_FLOAT && TARGET_IBM_FLOAT"
2941107590Sobrien  "*
2942107590Sobrien{
2943107590Sobrien   output_asm_insn (\"st\\t%1,%N3\", operands);
2944107590Sobrien   output_asm_insn (\"xi\\t%N3,128\", operands);
2945107590Sobrien   output_asm_insn (\"mvc\\t%O3(4,%R3),%2\", operands);
2946107590Sobrien   output_asm_insn (\"ld\\t%0,%3\", operands);
2947107590Sobrien   return \"sd\\t%0,%2\";
2948107590Sobrien}"
2949107590Sobrien  [(set_attr "op_type" "NN")
2950107590Sobrien   (set_attr "type"    "other" )
2951107590Sobrien   (set_attr "length"  "20")])
2952107590Sobrien
2953107590Sobrien;
2954107590Sobrien; floatsisf2 instruction pattern(s).
2955107590Sobrien;
2956107590Sobrien
2957107590Sobrien(define_expand "floatsisf2"
2958107590Sobrien  [(parallel
2959107590Sobrien    [(set (match_operand:SF 0 "register_operand" "")
2960107590Sobrien          (float:SF (match_operand:SI 1 "register_operand" "")))
2961107590Sobrien     (clobber (reg:CC 33))])]
2962107590Sobrien  "TARGET_HARD_FLOAT"
2963107590Sobrien  "
2964107590Sobrien{
2965107590Sobrien  if (TARGET_IBM_FLOAT)
2966107590Sobrien    {
2967107590Sobrien      /* Use the POP algorithm to convert to DFmode and then truncate.  */
2968107590Sobrien      rtx temp = gen_reg_rtx (DFmode);
2969107590Sobrien      emit_insn (gen_floatsidf2 (temp, operands[1]));
2970107590Sobrien      emit_insn (gen_truncdfsf2 (operands[0], temp));
2971107590Sobrien      DONE;
2972107590Sobrien    }
2973107590Sobrien}")
2974107590Sobrien
2975107590Sobrien(define_insn "floatsisf2_ieee"
2976107590Sobrien  [(set (match_operand:SF 0 "register_operand" "=f")
2977107590Sobrien        (float:SF (match_operand:SI 1 "register_operand" "d")))
2978107590Sobrien   (clobber (reg:CC 33))]
2979107590Sobrien  "TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT"
2980107590Sobrien  "cefbr\\t%0,%1"
2981107590Sobrien  [(set_attr "op_type" "RRE")
2982107590Sobrien   (set_attr "type"    "other" )])
2983107590Sobrien
2984107590Sobrien;
2985107590Sobrien; truncdfsf2 instruction pattern(s).
2986107590Sobrien;
2987107590Sobrien
2988107590Sobrien(define_expand "truncdfsf2"
2989107590Sobrien  [(set (match_operand:SF 0 "register_operand" "")
2990107590Sobrien        (float_truncate:SF (match_operand:DF 1 "general_operand" "")))]
2991107590Sobrien  "TARGET_HARD_FLOAT"
2992107590Sobrien  "")
2993107590Sobrien
2994107590Sobrien(define_insn "truncdfsf2_ieee"
2995107590Sobrien  [(set (match_operand:SF 0 "register_operand" "=f")
2996107590Sobrien        (float_truncate:SF (match_operand:DF 1 "general_operand" "f")))]
2997107590Sobrien  "TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT"
2998107590Sobrien  "ledbr\\t%0,%1"
2999107590Sobrien  [(set_attr "op_type"  "RRE")])
3000107590Sobrien
3001107590Sobrien(define_insn "truncdfsf2_ibm"
3002107590Sobrien  [(set (match_operand:SF 0 "register_operand" "=f,f")
3003107590Sobrien        (float_truncate:SF (match_operand:DF 1 "general_operand" "f,m")))]
3004107590Sobrien  "TARGET_HARD_FLOAT && TARGET_IBM_FLOAT"
3005107590Sobrien  "@
3006107590Sobrien   lrer\\t%0,%1
3007107590Sobrien   le\\t%0,%1"
3008107590Sobrien  [(set_attr "op_type"  "RR,RX")
3009107590Sobrien   (set_attr "atype"    "reg,mem")])
3010107590Sobrien
3011107590Sobrien;
3012107590Sobrien; extendsfdf2 instruction pattern(s).
3013107590Sobrien;
3014107590Sobrien
3015107590Sobrien(define_expand "extendsfdf2"
3016107590Sobrien  [(set (match_operand:DF 0 "register_operand" "")
3017107590Sobrien        (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "")))]
3018107590Sobrien  "TARGET_HARD_FLOAT"
3019107590Sobrien  "
3020107590Sobrien{
3021107590Sobrien  if (TARGET_IBM_FLOAT)
3022107590Sobrien    {
3023107590Sobrien      emit_insn (gen_extendsfdf2_ibm (operands[0], operands[1]));
3024107590Sobrien      DONE;
3025107590Sobrien    }
3026107590Sobrien}")
3027107590Sobrien
3028107590Sobrien(define_insn "extendsfdf2_ieee"
3029107590Sobrien  [(set (match_operand:DF 0 "register_operand" "=f,f")
3030107590Sobrien        (float_extend:DF (match_operand:SF 1 "nonimmediate_operand"  "f,m")))]
3031107590Sobrien  "TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT"
3032107590Sobrien  "@
3033107590Sobrien   ldebr\\t%0,%1
3034107590Sobrien   ldeb\\t%0,%1"
3035107590Sobrien  [(set_attr "op_type"  "RRE,RXE")])
3036107590Sobrien
3037107590Sobrien(define_insn "extendsfdf2_ibm"
3038107590Sobrien  [(set (match_operand:DF 0 "register_operand" "=f,f")
3039107590Sobrien        (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "f,m")))
3040107590Sobrien   (clobber (reg:CC 33))]
3041107590Sobrien  "TARGET_HARD_FLOAT && TARGET_IBM_FLOAT"
3042107590Sobrien  "@
3043107590Sobrien   sdr\\t%0,%0\;ler\\t%0,%1
3044107590Sobrien   sdr\\t%0,%0\;le\\t%0,%1"
3045107590Sobrien  [(set_attr "op_type"  "RRE,RXE")
3046107590Sobrien   (set_attr "atype"    "reg,mem")
3047107590Sobrien   (set_attr "type"     "o2,o2")]) 
3048107590Sobrien
3049107590Sobrien
3050107590Sobrien;;
3051107590Sobrien;; ARITHMETRIC OPERATIONS
3052107590Sobrien;;
3053107590Sobrien;  arithmetric operations set the ConditionCode,
3054107590Sobrien;  because of unpredictable Bits in Register for Halfword and Byte
3055107590Sobrien;  the ConditionCode can be set wrong in operations for Halfword and Byte
3056107590Sobrien
3057107590Sobrien;;
3058107590Sobrien;;- Add instructions.
3059107590Sobrien;;
3060107590Sobrien
3061107590Sobrien;
3062107590Sobrien; adddi3 instruction pattern(s).
3063107590Sobrien;
3064107590Sobrien
3065107590Sobrien(define_insn "addaddr_esame"
3066107590Sobrien  [(set (match_operand:DI 0 "register_operand" "=a,a")
3067107590Sobrien        (plus:DI (match_operand:DI 1 "register_operand" "%a,a")
3068107590Sobrien                 (match_operand:DI 2 "nonmemory_operand" "J,a")))]
3069107590Sobrien  "TARGET_64BIT && (((REGNO (operands[1]) == STACK_POINTER_REGNUM ) ||
3070107590Sobrien     (REGNO (operands[1]) == BASE_REGISTER)) && 
3071107590Sobrien	(GET_CODE (operands[2]) == REG ||
3072107590Sobrien	 CONST_OK_FOR_LETTER_P (INTVAL (operands[2]),'J')))"
3073107590Sobrien  "@
3074107590Sobrien   la\\t%0,%c2(,%1)
3075107590Sobrien   la\\t%0,0(%1,%2)"
3076107590Sobrien  [(set_attr "op_type" "RX")
3077107590Sobrien   (set_attr "atype"   "mem")
3078107590Sobrien   (set_attr "type"    "la")])
3079107590Sobrien
3080107590Sobrien(define_insn "adddi3_64"
3081107590Sobrien  [(set (match_operand:DI 0 "register_operand" "=d,d,d")
3082107590Sobrien        (plus:DI (match_operand:DI 1 "register_operand" "%0,0,0")
3083107590Sobrien                 (match_operand:DI 2 "general_operand" "d,K,m") ) )
3084107590Sobrien   (clobber (reg:CC 33))]
3085107590Sobrien  "TARGET_64BIT"
3086107590Sobrien  "@
3087107590Sobrien   agr\\t%0,%2
3088107590Sobrien   aghi\\t%0,%h2
3089107590Sobrien   ag\\t%0,%2"
3090107590Sobrien  [(set_attr "op_type"  "RRE,RI,RXE")
3091107590Sobrien   (set_attr "atype"    "reg,reg,mem")])
3092107590Sobrien
3093107590Sobrien(define_insn "adddi3_31"
3094107590Sobrien  [(set (match_operand:DI 0 "register_operand" "=d,d")
3095107590Sobrien        (plus:DI (match_operand:DI 1 "register_operand" "0,0")
3096107590Sobrien                 (match_operand:DI 2 "general_operand" "d,m") ) )
3097107590Sobrien   (clobber (reg:CC 33))]
3098107590Sobrien  "!TARGET_64BIT"
3099107590Sobrien  "*
3100107590Sobrien{
3101107590Sobrien   switch (which_alternative)
3102107590Sobrien     {
3103107590Sobrien     case 0: /* d <- d */
3104107590Sobrien       output_asm_insn (\"ar\\t%0,%2\", operands);
3105107590Sobrien       output_asm_insn (\"alr\\t%N0,%N2\", operands);
3106107590Sobrien       break;
3107107590Sobrien
3108107590Sobrien     case 1: /* d <- m */
3109107590Sobrien       output_asm_insn (\"a\\t%0,%2\", operands);
3110107590Sobrien       output_asm_insn (\"al\\t%N0,%N2\", operands);
3111107590Sobrien       break;
3112107590Sobrien
3113107590Sobrien     default:
3114107590Sobrien       abort ();
3115107590Sobrien     }
3116107590Sobrien
3117107590Sobrien   output_asm_insn (\"brc\\t12,.+8\", operands);
3118107590Sobrien   return \"ahi\\t%0,1\";
3119107590Sobrien}"
3120107590Sobrien  [(set_attr "op_type" "NN,NN")
3121107590Sobrien   (set_attr "atype"   "reg,mem")
3122107590Sobrien   (set_attr "type"    "o2,o2")
3123107590Sobrien   (set_attr "length"  "12,16")])
3124107590Sobrien
3125107590Sobrien(define_expand "adddi3"
3126107590Sobrien  [(set (match_operand:DI 0 "register_operand" "")
3127107590Sobrien        (plus:DI (match_operand:DI 1 "register_operand" "")
3128107590Sobrien                 (match_operand:DI 2 "general_operand" "")))]
3129107590Sobrien  ""
3130107590Sobrien  "
3131107590Sobrien{
3132107590Sobrien  if (TARGET_64BIT)
3133107590Sobrien    emit_insn(gen_adddi3_64 (operands[0],operands[1],operands[2]));
3134107590Sobrien  else
3135107590Sobrien    emit_insn(gen_adddi3_31 (operands[0],operands[1],operands[2]));
3136107590Sobrien  DONE;		
3137107590Sobrien}")
3138107590Sobrien
3139107590Sobrien(define_insn "*la_64"
3140107590Sobrien  [(set (match_operand:DI 0 "register_operand" "=d")
3141107590Sobrien        (match_operand:QI 1 "address_operand" "p"))]
3142107590Sobrien  "TARGET_64BIT"
3143107590Sobrien  "la\\t%0,%a1"      
3144107590Sobrien  [(set_attr "op_type" "RX")
3145107590Sobrien   (set_attr "atype"   "mem")
3146107590Sobrien   (set_attr "type"    "la")])
3147107590Sobrien
3148107590Sobrien(define_expand "reload_indi"
3149107590Sobrien  [(parallel [(match_operand:DI 0 "register_operand" "=a")
3150107590Sobrien              (match_operand:DI 1 "s390_plus_operand" "")
3151107590Sobrien              (match_operand:TI 2 "register_operand" "=&a")])]
3152107590Sobrien  "TARGET_64BIT"
3153107590Sobrien  "
3154107590Sobrien{
3155107590Sobrien  s390_expand_plus_operand (operands[0], operands[1], operands[2]);
3156107590Sobrien  DONE;
3157107590Sobrien}")
3158107590Sobrien
3159107590Sobrien 
3160107590Sobrien;
3161107590Sobrien; addsi3 instruction pattern(s).
3162107590Sobrien;
3163107590Sobrien
3164107590Sobrien(define_insn "*la_ccclobber"
3165107590Sobrien  [(set (match_operand:SI 0 "register_operand" "=d")
3166107590Sobrien        (match_operand:QI 1 "address_operand"  "p"))
3167107590Sobrien   (clobber (reg:CC 33))]
3168107590Sobrien  "legitimate_la_operand_p (operands[1])"
3169107590Sobrien  "la\\t%0,%a1"
3170107590Sobrien   [(set_attr "op_type"  "RX")
3171107590Sobrien    (set_attr "atype"    "mem")
3172107590Sobrien    (set_attr "type"     "la")])
3173107590Sobrien
3174107590Sobrien(define_insn "*addsi3_cc"
3175107590Sobrien  [(set (reg 33) 
3176107590Sobrien        (compare (plus:SI (match_operand:SI 1 "register_operand" "%0,0")
3177107590Sobrien                          (match_operand:SI 2 "nonimmediate_operand" "d,m"))
3178107590Sobrien                 (const_int 0)))
3179107590Sobrien   (set (match_operand:SI 0 "register_operand" "=d,d")
3180107590Sobrien        (plus:SI (match_dup 1) (match_dup 2)))]
3181107590Sobrien  "s390_match_ccmode(insn, CCLmode)"
3182107590Sobrien  "@
3183107590Sobrien   alr\\t%0,%2
3184107590Sobrien   al\\t%0,%2"
3185107590Sobrien  [(set_attr "op_type"  "RR,RX")
3186107590Sobrien   (set_attr "atype"    "reg,mem")])  
3187107590Sobrien
3188107590Sobrien(define_insn "*addsi3_cconly"
3189107590Sobrien  [(set (reg 33) 
3190107590Sobrien        (compare (plus:SI (match_operand:SI 1 "register_operand" "%0,0")
3191107590Sobrien                          (match_operand:SI 2 "general_operand" "d,m"))
3192107590Sobrien                 (const_int 0)))
3193107590Sobrien   (clobber (match_scratch:SI 0 "=d,d"))]
3194107590Sobrien  "s390_match_ccmode(insn, CCLmode)"
3195107590Sobrien  "@
3196107590Sobrien   alr\\t%0,%2
3197107590Sobrien   al\\t%0,%2"
3198107590Sobrien  [(set_attr "op_type"  "RR,RX")
3199107590Sobrien   (set_attr "atype"    "reg,mem")])  
3200107590Sobrien
3201107590Sobrien(define_insn "*addsi3_cconly2"
3202107590Sobrien  [(set (reg 33) 
3203107590Sobrien        (compare (match_operand:SI 1 "register_operand" "%0,0")
3204107590Sobrien                 (neg:SI (match_operand:SI 2 "general_operand" "d,m"))))
3205107590Sobrien   (clobber (match_scratch:SI 0 "=d,d"))]
3206107590Sobrien  "s390_match_ccmode(insn, CCLmode)"
3207107590Sobrien  "@
3208107590Sobrien   alr\\t%0,%2
3209107590Sobrien   al\\t%0,%2"
3210107590Sobrien  [(set_attr "op_type"  "RR,RX")
3211107590Sobrien   (set_attr "atype"    "reg,mem")])  
3212107590Sobrien
3213107590Sobrien(define_insn "addsi3"
3214107590Sobrien  [(set (match_operand:SI 0 "register_operand" "=d,d,d")
3215107590Sobrien        (plus:SI (match_operand:SI 1 "register_operand" "%0,0,0")
3216107590Sobrien                 (match_operand:SI 2 "general_operand" "d,K,m")))
3217107590Sobrien   (clobber (reg:CC 33))]
3218107590Sobrien  ""
3219107590Sobrien  "@
3220107590Sobrien   ar\\t%0,%2
3221107590Sobrien   ahi\\t%0,%h2
3222107590Sobrien   a\\t%0,%2"
3223107590Sobrien  [(set_attr "op_type"  "RR,RI,RX")
3224107590Sobrien   (set_attr "atype"    "reg,reg,mem")])
3225107590Sobrien
3226107590Sobrien(define_insn "*addsi3_inv"
3227107590Sobrien  [(set (match_operand:SI 0 "register_operand" "=d,d,d")
3228107590Sobrien        (plus:SI (match_operand:SI 1 "general_operand" "%d,K,m")
3229107590Sobrien                 (match_operand:SI 2 "register_operand" "0,0,0")))
3230107590Sobrien   (clobber (reg:CC 33))]
3231107590Sobrien  ""
3232107590Sobrien  "@
3233107590Sobrien   ar\\t%0,%1
3234107590Sobrien   ahi\\t%0,%h1
3235107590Sobrien   a\\t%0,%1"
3236107590Sobrien  [(set_attr "op_type"  "RR,RI,RX")
3237107590Sobrien   (set_attr "atype"    "reg,reg,mem")])
3238107590Sobrien
3239107590Sobrien(define_insn "*la_31"
3240107590Sobrien  [(set (match_operand:SI 0 "register_operand" "=d")
3241107590Sobrien        (match_operand:QI 1 "address_operand" "p"))]
3242107590Sobrien  "legitimate_la_operand_p (operands[1])"
3243107590Sobrien  "la\\t%0,%a1"
3244107590Sobrien  [(set_attr "op_type"  "RX")
3245107590Sobrien   (set_attr "atype"    "mem")
3246107590Sobrien   (set_attr "type"     "la")])
3247107590Sobrien
3248107590Sobrien(define_expand "reload_insi"
3249107590Sobrien  [(parallel [(match_operand:SI 0 "register_operand" "=a")
3250107590Sobrien              (match_operand:SI 1 "s390_plus_operand" "")
3251107590Sobrien              (match_operand:DI 2 "register_operand" "=&a")])]
3252107590Sobrien  "!TARGET_64BIT"
3253107590Sobrien  "
3254107590Sobrien{
3255107590Sobrien  s390_expand_plus_operand (operands[0], operands[1], operands[2]);
3256107590Sobrien  DONE;
3257107590Sobrien}")
3258107590Sobrien
3259107590Sobrien
3260107590Sobrien;
3261107590Sobrien; addhi3 instruction pattern(s).
3262107590Sobrien;
3263107590Sobrien
3264107590Sobrien(define_insn "addhi3"
3265107590Sobrien  [(set (match_operand:HI 0 "register_operand" "=d,d,d")
3266107590Sobrien        (plus:HI (match_operand:HI 1 "register_operand" "%0,0,0")
3267107590Sobrien                 (match_operand:HI 2 "general_operand" "d,K,m")))
3268107590Sobrien   (clobber (reg:CC 33))]
3269107590Sobrien  ""
3270107590Sobrien  "@
3271107590Sobrien   ar\\t%0,%2
3272107590Sobrien   ahi\\t%0,%h2
3273107590Sobrien   ah\\t%0,%2"
3274107590Sobrien  [(set_attr "op_type"  "RR,RI,RX")
3275107590Sobrien   (set_attr "atype"    "reg,reg,mem")])
3276107590Sobrien
3277107590Sobrien
3278107590Sobrien;
3279107590Sobrien; addqi3 instruction pattern(s).
3280107590Sobrien;
3281107590Sobrien
3282107590Sobrien(define_insn "addqi3"
3283107590Sobrien  [(set (match_operand:QI 0 "register_operand" "=d,d")
3284107590Sobrien        (plus:QI (match_operand:QI 1 "register_operand" "%0,0")
3285107590Sobrien                 (match_operand:QI 2 "general_operand" "a,n")))
3286107590Sobrien   (clobber (reg:CC 33))]
3287107590Sobrien  ""
3288107590Sobrien  "@
3289107590Sobrien   ar\\t%0,%2
3290107590Sobrien   ahi\\t%0,%h2"
3291107590Sobrien  [(set_attr "op_type"  "RX,RX")
3292107590Sobrien   (set_attr "atype"    "reg,mem")])
3293107590Sobrien
3294107590Sobrien
3295107590Sobrien;
3296107590Sobrien; adddf3 instruction pattern(s).
3297107590Sobrien;
3298107590Sobrien
3299107590Sobrien(define_expand "adddf3"
3300107590Sobrien  [(parallel
3301107590Sobrien    [(set (match_operand:DF 0 "register_operand" "=f,f")
3302107590Sobrien          (plus:DF (match_operand:DF 1 "register_operand" "%0,0")
3303107590Sobrien                   (match_operand:DF 2 "general_operand" "f,m")))
3304107590Sobrien     (clobber (reg:CC 33))])]
3305107590Sobrien  "TARGET_HARD_FLOAT"
3306107590Sobrien  "")
3307107590Sobrien
3308107590Sobrien(define_insn "*adddf3"
3309107590Sobrien  [(set (match_operand:DF 0 "register_operand" "=f,f")
3310107590Sobrien        (plus:DF (match_operand:DF 1 "register_operand" "%0,0")
3311107590Sobrien                 (match_operand:DF 2 "general_operand" "f,m")))
3312107590Sobrien   (clobber (reg:CC 33))]
3313107590Sobrien  "TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT"
3314107590Sobrien  "@
3315107590Sobrien   adbr\\t%0,%2
3316107590Sobrien   adb\\t%0,%2"
3317107590Sobrien  [(set_attr "op_type"  "RRE,RXE")
3318107590Sobrien   (set_attr "atype"    "reg,mem")])
3319107590Sobrien
3320107590Sobrien(define_insn "*adddf3_ibm"
3321107590Sobrien  [(set (match_operand:DF 0 "register_operand" "=f,f")
3322107590Sobrien        (plus:DF (match_operand:DF 1 "register_operand" "%0,0")
3323107590Sobrien                 (match_operand:DF 2 "general_operand" "f,m")))
3324107590Sobrien   (clobber (reg:CC 33))]
3325107590Sobrien  "TARGET_HARD_FLOAT && TARGET_IBM_FLOAT"
3326107590Sobrien  "@
3327107590Sobrien   adr\\t%0,%2
3328107590Sobrien   ad\\t%0,%2"
3329107590Sobrien  [(set_attr "op_type"  "RR,RX")
3330107590Sobrien   (set_attr "atype"    "reg,mem")])
3331107590Sobrien
3332107590Sobrien;
3333107590Sobrien; addsf3 instruction pattern(s).
3334107590Sobrien;
3335107590Sobrien
3336107590Sobrien(define_expand "addsf3"
3337107590Sobrien  [(parallel
3338107590Sobrien    [(set (match_operand:SF 0 "register_operand" "=f,f")
3339107590Sobrien          (plus:SF (match_operand:SF 1 "register_operand" "%0,0")
3340107590Sobrien                   (match_operand:SF 2 "general_operand" "f,m")))
3341107590Sobrien     (clobber (reg:CC 33))])]
3342107590Sobrien  "TARGET_HARD_FLOAT"
3343107590Sobrien  "")
3344107590Sobrien
3345107590Sobrien(define_insn "*addsf3"
3346107590Sobrien  [(set (match_operand:SF 0 "register_operand" "=f,f")
3347107590Sobrien        (plus:SF (match_operand:SF 1 "register_operand" "%0,0")
3348107590Sobrien                 (match_operand:SF 2 "general_operand" "f,m")))
3349107590Sobrien   (clobber (reg:CC 33))]
3350107590Sobrien  "TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT"
3351107590Sobrien  "@
3352107590Sobrien   aebr\\t%0,%2
3353107590Sobrien   aeb\\t%0,%2"
3354107590Sobrien  [(set_attr "op_type"  "RRE,RXE")
3355107590Sobrien   (set_attr "atype"    "reg,mem")])
3356107590Sobrien
3357107590Sobrien(define_insn "*addsf3"
3358107590Sobrien  [(set (match_operand:SF 0 "register_operand" "=f,f")
3359107590Sobrien        (plus:SF (match_operand:SF 1 "register_operand" "%0,0")
3360107590Sobrien                 (match_operand:SF 2 "general_operand" "f,m")))
3361107590Sobrien   (clobber (reg:CC 33))]
3362107590Sobrien  "TARGET_HARD_FLOAT && TARGET_IBM_FLOAT"
3363107590Sobrien  "@
3364107590Sobrien   aer\\t%0,%2
3365107590Sobrien   ae\\t%0,%2"
3366107590Sobrien  [(set_attr "op_type"  "RR,RX")
3367107590Sobrien   (set_attr "atype"    "reg,mem")])
3368107590Sobrien
3369107590Sobrien
3370107590Sobrien;;
3371107590Sobrien;;- Subtract instructions.
3372107590Sobrien;;
3373107590Sobrien
3374107590Sobrien;
3375107590Sobrien; subdi3 instruction pattern(s).
3376107590Sobrien;
3377107590Sobrien
3378107590Sobrien(define_insn "*subdi3_64"
3379107590Sobrien  [(set (match_operand:DI 0 "register_operand" "=d,d")
3380107590Sobrien        (minus:DI (match_operand:DI 1 "register_operand" "0,0")
3381107590Sobrien                  (match_operand:DI 2 "general_operand" "d,m") ) )
3382107590Sobrien   (clobber (reg:CC 33))]
3383107590Sobrien  "TARGET_64BIT"
3384107590Sobrien  "@
3385107590Sobrien   sgr\\t%0,%2
3386107590Sobrien   sg\\t%0,%2"
3387107590Sobrien  [(set_attr "op_type"  "RRE,RRE")
3388107590Sobrien   (set_attr "atype"    "reg,mem")])
3389107590Sobrien
3390107590Sobrien(define_insn "subdi3"
3391107590Sobrien  [(set (match_operand:DI 0 "register_operand" "=d,d")
3392107590Sobrien        (minus:DI (match_operand:DI 1 "register_operand" "0,0")
3393107590Sobrien                  (match_operand:DI 2 "general_operand" "d,m")))
3394107590Sobrien   (clobber (reg:CC 33))]
3395107590Sobrien  ""
3396107590Sobrien  "*
3397107590Sobrien{
3398107590Sobrien   switch (which_alternative)
3399107590Sobrien     {
3400107590Sobrien     case 0: /* d <- d */
3401107590Sobrien       output_asm_insn (\"sr\\t%0,%2\", operands);
3402107590Sobrien       output_asm_insn (\"slr\\t%N0,%N2\", operands);
3403107590Sobrien       break;
3404107590Sobrien     case 1: /* d <- m */
3405107590Sobrien       output_asm_insn (\"s\\t%0,%2\", operands);
3406107590Sobrien       output_asm_insn (\"sl\\t%N0,%N2\", operands);
3407107590Sobrien       break;
3408107590Sobrien
3409107590Sobrien     default:
3410107590Sobrien       abort ();
3411107590Sobrien     }
3412107590Sobrien
3413107590Sobrien   output_asm_insn (\"brc\\t11,.+8\", operands);
3414107590Sobrien   return \"ahi\\t%0,-1\";
3415107590Sobrien}"
3416107590Sobrien  [(set_attr "op_type"  "NN,NN")
3417107590Sobrien   (set_attr "atype"    "reg,mem")
3418107590Sobrien   (set_attr "type"     "other,other")
3419107590Sobrien   (set_attr "length"   "12,16")])
3420107590Sobrien
3421107590Sobrien;
3422107590Sobrien; subsi3 instruction pattern(s).
3423107590Sobrien;
3424107590Sobrien
3425107590Sobrien(define_insn "*subsi3_cc"
3426107590Sobrien  [(set (reg 33)
3427107590Sobrien        (compare (minus:SI (match_operand:SI 1 "register_operand" "0,0")
3428107590Sobrien                           (match_operand:SI 2 "general_operand" "d,m"))
3429107590Sobrien                 (const_int 0)))
3430107590Sobrien   (set (match_operand:SI 0 "register_operand" "=d,d")
3431107590Sobrien        (minus:SI (match_dup 1) (match_dup 2)))]
3432107590Sobrien  "s390_match_ccmode(insn, CCLmode)"
3433107590Sobrien  "@
3434107590Sobrien   slr\\t%0,%2
3435107590Sobrien   sl\\t%0,%2"
3436107590Sobrien  [(set_attr "op_type"  "RR,RX")
3437107590Sobrien   (set_attr "atype"    "reg,mem")])
3438107590Sobrien
3439107590Sobrien(define_insn "*subsi3_cconly"
3440107590Sobrien  [(set (reg 33)
3441107590Sobrien        (compare (minus:SI (match_operand:SI 1 "register_operand" "0,0")
3442107590Sobrien                           (match_operand:SI 2 "general_operand" "d,m"))
3443107590Sobrien                 (const_int 0)))
3444107590Sobrien   (clobber (match_scratch:SI 0 "=d,d"))]
3445107590Sobrien  "s390_match_ccmode(insn, CCLmode)"
3446107590Sobrien  "@
3447107590Sobrien   slr\\t%0,%2
3448107590Sobrien   sl\\t%0,%2"
3449107590Sobrien  [(set_attr "op_type"  "RR,RX")
3450107590Sobrien   (set_attr "atype"    "reg,mem")])
3451107590Sobrien
3452107590Sobrien(define_insn "subsi3"
3453107590Sobrien  [(set (match_operand:SI 0 "register_operand" "=d,d")
3454107590Sobrien        (minus:SI (match_operand:SI 1 "register_operand" "0,0")
3455107590Sobrien                  (match_operand:SI 2 "general_operand" "d,m")))
3456107590Sobrien   (clobber (reg:CC 33))]
3457107590Sobrien  ""
3458107590Sobrien  "@
3459107590Sobrien   sr\\t%0,%2
3460107590Sobrien   s\\t%0,%2"
3461107590Sobrien  [(set_attr "op_type"  "RR,RX")
3462107590Sobrien   (set_attr "atype"    "reg,mem")])
3463107590Sobrien
3464107590Sobrien;
3465107590Sobrien; subhi3 instruction pattern(s).
3466107590Sobrien;
3467107590Sobrien
3468107590Sobrien(define_insn "subhi3"
3469107590Sobrien  [(set (match_operand:HI 0 "register_operand" "=d,d")
3470107590Sobrien        (minus:HI (match_operand:HI 1 "register_operand" "0,0")
3471107590Sobrien                  (match_operand:HI 2 "general_operand" "d,m")))
3472107590Sobrien   (clobber (reg:CC 33))]
3473107590Sobrien  ""
3474107590Sobrien  "@
3475107590Sobrien   sr\\t%0,%2
3476107590Sobrien   sh\\t%0,%2"
3477107590Sobrien  [(set_attr "op_type"  "RR,RX")
3478107590Sobrien   (set_attr "atype"    "reg,mem")])
3479107590Sobrien
3480107590Sobrien;
3481107590Sobrien; subqi3 instruction pattern(s).
3482107590Sobrien;
3483107590Sobrien
3484107590Sobrien(define_insn "subqi3"
3485107590Sobrien  [(set (match_operand:QI 0 "register_operand" "=d")
3486107590Sobrien        (minus:QI (match_operand:QI 1 "register_operand" "0")
3487107590Sobrien                  (match_operand:QI 2 "register_operand" "d")))
3488107590Sobrien   (clobber (reg:CC 33))]
3489107590Sobrien  ""
3490107590Sobrien  "sr\\t%0,%2"
3491107590Sobrien   [(set_attr "op_type"  "RR")])
3492107590Sobrien
3493107590Sobrien;
3494107590Sobrien; subdf3 instruction pattern(s).
3495107590Sobrien;
3496107590Sobrien
3497107590Sobrien(define_expand "subdf3"
3498107590Sobrien  [(parallel
3499107590Sobrien    [(set (match_operand:DF 0 "register_operand" "=f,f")
3500107590Sobrien          (minus:DF (match_operand:DF 1 "register_operand" "0,0")
3501107590Sobrien                    (match_operand:DF 2 "general_operand" "f,m")))
3502107590Sobrien     (clobber (reg:CC 33))])]
3503107590Sobrien  "TARGET_HARD_FLOAT"
3504107590Sobrien  "")
3505107590Sobrien
3506107590Sobrien(define_insn "*subdf3"
3507107590Sobrien  [(set (match_operand:DF 0 "register_operand" "=f,f")
3508107590Sobrien        (minus:DF (match_operand:DF 1 "register_operand" "0,0")
3509107590Sobrien                  (match_operand:DF 2 "general_operand" "f,m")))
3510107590Sobrien   (clobber (reg:CC 33))]
3511107590Sobrien  "TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT"
3512107590Sobrien  "@
3513107590Sobrien   sdbr\\t%0,%2
3514107590Sobrien   sdb\\t%0,%2"
3515107590Sobrien  [(set_attr "op_type"  "RRE,RXE")
3516107590Sobrien   (set_attr "atype"    "reg,mem")])
3517107590Sobrien
3518107590Sobrien(define_insn "*subdf3_ibm"
3519107590Sobrien  [(set (match_operand:DF 0 "register_operand" "=f,f")
3520107590Sobrien        (minus:DF (match_operand:DF 1 "register_operand" "0,0")
3521107590Sobrien                  (match_operand:DF 2 "general_operand" "f,m")))
3522107590Sobrien   (clobber (reg:CC 33))]
3523107590Sobrien  "TARGET_HARD_FLOAT && TARGET_IBM_FLOAT"
3524107590Sobrien  "@
3525107590Sobrien   sdr\\t%0,%2
3526107590Sobrien   sd\\t%0,%2"
3527107590Sobrien  [(set_attr "op_type"  "RR,RX")
3528107590Sobrien   (set_attr "atype"    "reg,mem")])
3529107590Sobrien
3530107590Sobrien;
3531107590Sobrien; subsf3 instruction pattern(s).
3532107590Sobrien;
3533107590Sobrien
3534107590Sobrien(define_expand "subsf3"
3535107590Sobrien  [(parallel
3536107590Sobrien    [(set (match_operand:SF 0 "register_operand" "=f,f")
3537107590Sobrien          (minus:SF (match_operand:SF 1 "register_operand" "0,0")
3538107590Sobrien                    (match_operand:SF 2 "general_operand" "f,m")))
3539107590Sobrien     (clobber (reg:CC 33))])]
3540107590Sobrien  "TARGET_HARD_FLOAT"
3541107590Sobrien  "")
3542107590Sobrien
3543107590Sobrien(define_insn "*subsf3"
3544107590Sobrien  [(set (match_operand:SF 0 "register_operand" "=f,f")
3545107590Sobrien        (minus:SF (match_operand:SF 1 "register_operand" "0,0")
3546107590Sobrien                  (match_operand:SF 2 "general_operand" "f,m")))
3547107590Sobrien   (clobber (reg:CC 33))]
3548107590Sobrien  "TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT"
3549107590Sobrien  "@
3550107590Sobrien   sebr\\t%0,%2
3551107590Sobrien   seb\\t%0,%2"
3552107590Sobrien  [(set_attr "op_type"  "RRE,RXE")
3553107590Sobrien   (set_attr "atype"    "reg,mem")])
3554107590Sobrien
3555107590Sobrien(define_insn "*subsf3_ibm"
3556107590Sobrien  [(set (match_operand:SF 0 "register_operand" "=f,f")
3557107590Sobrien        (minus:SF (match_operand:SF 1 "register_operand" "0,0")
3558107590Sobrien                  (match_operand:SF 2 "general_operand" "f,m")))
3559107590Sobrien   (clobber (reg:CC 33))]
3560107590Sobrien  "TARGET_HARD_FLOAT && TARGET_IBM_FLOAT"
3561107590Sobrien  "@
3562107590Sobrien   ser\\t%0,%2
3563107590Sobrien   se\\t%0,%2"
3564107590Sobrien  [(set_attr "op_type"  "RR,RX")
3565107590Sobrien   (set_attr "atype"    "reg,mem")])
3566107590Sobrien
3567107590Sobrien
3568107590Sobrien;;
3569107590Sobrien;;- Multiply instructions.
3570107590Sobrien;;
3571107590Sobrien
3572107590Sobrien;
3573107590Sobrien; muldi3 instruction pattern(s).
3574107590Sobrien;
3575107590Sobrien
3576107590Sobrien(define_insn "muldi3"
3577107590Sobrien  [(set (match_operand:DI 0 "register_operand" "=d,d,d")
3578107590Sobrien        (mult:DI (match_operand:DI 1 "register_operand" "%0,0,0")
3579107590Sobrien                 (match_operand:DI 2 "general_operand" "d,K,m")))
3580107590Sobrien   (clobber (reg:CC 33))]
3581107590Sobrien  "TARGET_64BIT"
3582107590Sobrien  "@
3583107590Sobrien   msgr\\t%0,%2
3584107590Sobrien   mghi\\t%0,%h2
3585107590Sobrien   msg\\t%0,%2"
3586107590Sobrien  [(set_attr "op_type"  "RRE,RI,RX")
3587107590Sobrien   (set_attr "atype"    "reg,reg,mem")
3588107590Sobrien   (set_attr "type"     "imul")])
3589107590Sobrien
3590107590Sobrien;
3591107590Sobrien; mulsi3 instruction pattern(s).
3592107590Sobrien;
3593107590Sobrien
3594107590Sobrien(define_insn "mulsi3"
3595107590Sobrien  [(set (match_operand:SI 0 "register_operand" "=d,d,d")
3596107590Sobrien        (mult:SI  (match_operand:SI 1 "register_operand" "%0,0,0")
3597107590Sobrien                  (match_operand:SI 2 "general_operand" "d,K,m")))
3598107590Sobrien   (clobber (reg:CC 33))]
3599107590Sobrien  ""
3600107590Sobrien  "@
3601107590Sobrien   msr\\t%0,%2
3602107590Sobrien   mhi\\t%0,%h2
3603107590Sobrien   ms\\t%0,%2"
3604107590Sobrien  [(set_attr "op_type"  "RRE,RI,RX")
3605107590Sobrien   (set_attr "atype"    "reg,reg,mem")
3606107590Sobrien   (set_attr "type"     "imul")])
3607107590Sobrien
3608107590Sobrien;
3609107590Sobrien; mulsidi3 instruction pattern(s).
3610107590Sobrien;
3611107590Sobrien
3612107590Sobrien(define_expand "mulsidi3"
3613107590Sobrien  [(set (match_operand:DI 0 "register_operand" "")
3614107590Sobrien	(mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" ""))
3615107590Sobrien		 (sign_extend:DI (match_operand:SI 2 "nonimmediate_operand" ""))))]
3616107590Sobrien  "!TARGET_64BIT"
3617107590Sobrien  "
3618107590Sobrien{
3619107590Sobrien  rtx insn;
3620107590Sobrien
3621107590Sobrien  emit_insn (gen_zero_extendsidi2 (operands[0], operands[1]));
3622107590Sobrien  insn = emit_insn (gen_mulsi_6432 (operands[0], operands[0], operands[2]));
3623107590Sobrien
3624107590Sobrien  REG_NOTES (insn) =
3625107590Sobrien	gen_rtx_EXPR_LIST (REG_EQUAL, 
3626107590Sobrien                           gen_rtx_MULT (DImode, 
3627107590Sobrien				gen_rtx_SIGN_EXTEND (DImode, operands[1]),
3628107590Sobrien				gen_rtx_SIGN_EXTEND (DImode, operands[2])),
3629107590Sobrien			   REG_NOTES (insn));
3630107590Sobrien  DONE;
3631107590Sobrien}")
3632107590Sobrien 
3633107590Sobrien(define_insn "mulsi_6432"
3634107590Sobrien   [(set (match_operand:DI 0 "register_operand" "=d,d")
3635107590Sobrien         (mult:DI (sign_extend:DI 
3636107590Sobrien	            (truncate:SI (match_operand:DI 1 "register_operand" "0,0")))
3637107590Sobrien                  (sign_extend:DI
3638107590Sobrien	            (match_operand:SI 2 "nonimmediate_operand" "d,m"))))
3639107590Sobrien    (clobber (reg:CC 33))]
3640107590Sobrien   "!TARGET_64BIT"
3641107590Sobrien   "@
3642107590Sobrien    mr\\t%0,%2
3643107590Sobrien    m\\t%0,%2"
3644107590Sobrien  [(set_attr "op_type"  "RR,RX")
3645107590Sobrien   (set_attr "atype"    "reg,mem")
3646107590Sobrien   (set_attr "type"     "imul")])
3647107590Sobrien 
3648107590Sobrien;
3649107590Sobrien; muldf3 instruction pattern(s).
3650107590Sobrien;
3651107590Sobrien
3652107590Sobrien(define_expand "muldf3"
3653107590Sobrien  [(parallel
3654107590Sobrien    [(set (match_operand:DF 0 "register_operand" "=f,f")
3655107590Sobrien          (mult:DF (match_operand:DF 1 "register_operand" "%0,0")
3656107590Sobrien                   (match_operand:DF 2 "general_operand" "f,m")))
3657107590Sobrien     (clobber (reg:CC 33))])]
3658107590Sobrien  "TARGET_HARD_FLOAT"
3659107590Sobrien  "")
3660107590Sobrien
3661107590Sobrien(define_insn "*muldf3"
3662107590Sobrien  [(set (match_operand:DF 0 "register_operand" "=f,f")
3663107590Sobrien        (mult:DF (match_operand:DF 1 "register_operand" "%0,0")
3664107590Sobrien                 (match_operand:DF 2 "general_operand" "f,m")))
3665107590Sobrien   (clobber (reg:CC 33))]
3666107590Sobrien  "TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT"
3667107590Sobrien  "@
3668107590Sobrien   mdbr\\t%0,%2
3669107590Sobrien   mdb\\t%0,%2"
3670107590Sobrien  [(set_attr "op_type"  "RRE,RXE")
3671107590Sobrien   (set_attr "type"     "fmul")
3672107590Sobrien   (set_attr "atype"    "reg,mem")])
3673107590Sobrien
3674107590Sobrien(define_insn "*muldf3_ibm"
3675107590Sobrien  [(set (match_operand:DF 0 "register_operand" "=f,f")
3676107590Sobrien        (mult:DF (match_operand:DF 1 "register_operand" "%0,0")
3677107590Sobrien                 (match_operand:DF 2 "general_operand" "f,m")))
3678107590Sobrien   (clobber (reg:CC 33))]
3679107590Sobrien  "TARGET_HARD_FLOAT && TARGET_IBM_FLOAT"
3680107590Sobrien  "@
3681107590Sobrien   mdr\\t%0,%2
3682107590Sobrien   md\\t%0,%2"
3683107590Sobrien  [(set_attr "op_type"  "RR,RX")
3684107590Sobrien   (set_attr "type"    "fmul")
3685107590Sobrien   (set_attr "atype"    "reg,mem")])
3686107590Sobrien
3687107590Sobrien;
3688107590Sobrien; mulsf3 instruction pattern(s).
3689107590Sobrien;
3690107590Sobrien
3691107590Sobrien(define_expand "mulsf3"
3692107590Sobrien  [(parallel
3693107590Sobrien    [(set (match_operand:SF 0 "register_operand" "=f,f")
3694107590Sobrien          (mult:SF (match_operand:SF 1 "register_operand" "%0,0")
3695107590Sobrien                   (match_operand:SF 2 "general_operand" "f,m")))
3696107590Sobrien     (clobber (reg:CC 33))])]
3697107590Sobrien  "TARGET_HARD_FLOAT"
3698107590Sobrien  "")
3699107590Sobrien
3700107590Sobrien(define_insn "*mulsf3"
3701107590Sobrien  [(set (match_operand:SF 0 "register_operand" "=f,f")
3702107590Sobrien        (mult:SF (match_operand:SF 1 "register_operand" "%0,0")
3703107590Sobrien                 (match_operand:SF 2 "general_operand" "f,m")))
3704107590Sobrien   (clobber (reg:CC 33))]
3705107590Sobrien  "TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT"
3706107590Sobrien  "@
3707107590Sobrien   meebr\\t%0,%2
3708107590Sobrien   meeb\\t%0,%2"
3709107590Sobrien  [(set_attr "op_type"  "RRE,RXE")
3710107590Sobrien   (set_attr "type"     "fmul")
3711107590Sobrien   (set_attr "atype"    "reg,mem")])
3712107590Sobrien
3713107590Sobrien(define_insn "*mulsf3_ibm"
3714107590Sobrien  [(set (match_operand:SF 0 "register_operand" "=f,f")
3715107590Sobrien        (mult:SF (match_operand:SF 1 "register_operand" "%0,0")
3716107590Sobrien                 (match_operand:SF 2 "general_operand" "f,m")))
3717107590Sobrien   (clobber (reg:CC 33))]
3718107590Sobrien  "TARGET_HARD_FLOAT && TARGET_IBM_FLOAT"
3719107590Sobrien  "@
3720107590Sobrien   mer\\t%0,%2
3721107590Sobrien   me\\t%0,%2"
3722107590Sobrien  [(set_attr "op_type"  "RR,RX")
3723107590Sobrien   (set_attr "type"     "fmul")
3724107590Sobrien   (set_attr "atype"    "reg,mem")])
3725107590Sobrien
3726107590Sobrien
3727107590Sobrien;;
3728107590Sobrien;;- Divide and modulo instructions.
3729107590Sobrien;;
3730107590Sobrien
3731107590Sobrien;
3732107590Sobrien; divmoddi4 instruction pattern(s).
3733107590Sobrien;
3734107590Sobrien
3735107590Sobrien(define_expand "divmoddi4"
3736107590Sobrien  [(parallel [(set (match_operand:DI 0 "general_operand" "")
3737107590Sobrien		   (div:DI (match_operand:DI 1 "general_operand" "")
3738107590Sobrien			   (match_operand:DI 2 "general_operand" "")))
3739107590Sobrien	      (set (match_operand:DI 3 "general_operand" "")
3740107590Sobrien		   (mod:DI (match_dup 1) (match_dup 2)))])
3741107590Sobrien   (clobber (match_dup 4))]
3742107590Sobrien  "TARGET_64BIT"
3743107590Sobrien  "
3744107590Sobrien{
3745107590Sobrien  rtx insn, div_equal, mod_equal, equal;
3746107590Sobrien
3747107590Sobrien  div_equal = gen_rtx_DIV (DImode, operands[1], operands[2]);
3748107590Sobrien  mod_equal = gen_rtx_MOD (DImode, operands[1], operands[2]);
3749107590Sobrien  equal = gen_rtx_IOR (TImode,
3750107590Sobrien		       gen_rtx_ZERO_EXTEND (TImode, div_equal),
3751107590Sobrien		       gen_rtx_ASHIFT (TImode,
3752107590Sobrien				       gen_rtx_ZERO_EXTEND (TImode, mod_equal),
3753107590Sobrien				       GEN_INT (64)));
3754107590Sobrien
3755107590Sobrien  operands[4] = gen_reg_rtx(TImode);
3756107590Sobrien  emit_insn (gen_rtx_CLOBBER (VOIDmode, operands[4]));
3757107590Sobrien  emit_move_insn (gen_lowpart (DImode, operands[4]), operands[1]);
3758107590Sobrien  emit_move_insn (gen_highpart (DImode, operands[4]), const0_rtx);
3759107590Sobrien  insn = emit_insn (gen_divmodtidi3 (operands[4], operands[4], operands[2]));
3760107590Sobrien  REG_NOTES (insn) =
3761107590Sobrien	gen_rtx_EXPR_LIST (REG_EQUAL, equal, REG_NOTES (insn));
3762107590Sobrien
3763107590Sobrien  insn = emit_move_insn (operands[0], gen_lowpart (DImode, operands[4]));
3764107590Sobrien  REG_NOTES (insn) =
3765107590Sobrien        gen_rtx_EXPR_LIST (REG_EQUAL, div_equal, REG_NOTES (insn));
3766107590Sobrien
3767107590Sobrien  insn = emit_move_insn (operands[3], gen_highpart (DImode, operands[4]));
3768107590Sobrien  REG_NOTES (insn) =
3769107590Sobrien        gen_rtx_EXPR_LIST (REG_EQUAL, mod_equal, REG_NOTES (insn));
3770107590Sobrien
3771107590Sobrien  DONE;
3772107590Sobrien}")
3773107590Sobrien
3774107590Sobrien(define_insn "divmodtidi3"
3775107590Sobrien  [(set (match_operand:TI 0 "register_operand" "=d,d")
3776107590Sobrien        (ior:TI
3777107590Sobrien          (zero_extend:TI
3778107590Sobrien            (div:DI (truncate:DI (match_operand:TI 1 "register_operand" "0,0"))
3779107590Sobrien                    (match_operand:DI 2 "general_operand" "d,m")))
3780107590Sobrien          (ashift:TI
3781107590Sobrien            (zero_extend:TI
3782107590Sobrien              (mod:DI (truncate:DI (match_dup 1)) 
3783107590Sobrien                      (match_dup 2)))
3784107590Sobrien            (const_int 64))))]
3785107590Sobrien  "TARGET_64BIT"
3786107590Sobrien  "@
3787107590Sobrien   dsgr\\t%0,%2
3788107590Sobrien   dsg\\t%0,%2"
3789107590Sobrien  [(set_attr "op_type"  "RRE,RXE")
3790107590Sobrien   (set_attr "type"     "idiv")
3791107590Sobrien   (set_attr "atype"    "reg,mem")])
3792107590Sobrien
3793107590Sobrien(define_insn "divmodtisi3"
3794107590Sobrien  [(set (match_operand:TI 0 "register_operand" "=d,d")
3795107590Sobrien        (ior:TI
3796107590Sobrien          (zero_extend:TI
3797107590Sobrien            (div:DI (truncate:DI (match_operand:TI 1 "register_operand" "0,0"))
3798107590Sobrien                    (sign_extend:DI (match_operand:SI 2 "nonimmediate_operand" "d,m"))))
3799107590Sobrien          (ashift:TI
3800107590Sobrien            (zero_extend:TI
3801107590Sobrien              (mod:DI (truncate:DI (match_dup 1)) 
3802107590Sobrien                      (sign_extend:DI (match_dup 2))))
3803107590Sobrien            (const_int 64))))]
3804107590Sobrien  "TARGET_64BIT"
3805107590Sobrien  "@
3806107590Sobrien   dsgfr\\t%0,%2
3807107590Sobrien   dsgf\\t%0,%2"
3808107590Sobrien  [(set_attr "op_type"  "RRE,RXE")
3809107590Sobrien   (set_attr "type"     "idiv")
3810107590Sobrien   (set_attr "atype"    "reg,mem")])
3811107590Sobrien
3812107590Sobrien;
3813107590Sobrien; udivmoddi4 instruction pattern(s).
3814107590Sobrien;
3815107590Sobrien
3816107590Sobrien(define_expand "udivmoddi4"
3817107590Sobrien  [(parallel [(set (match_operand:DI 0 "general_operand" "")
3818107590Sobrien		   (udiv:DI (match_operand:DI 1 "general_operand" "")
3819107590Sobrien			    (match_operand:DI 2 "nonimmediate_operand" "")))
3820107590Sobrien	      (set (match_operand:DI 3 "general_operand" "")
3821107590Sobrien		   (umod:DI (match_dup 1) (match_dup 2)))])
3822107590Sobrien   (clobber (match_dup 4))]
3823107590Sobrien  "TARGET_64BIT"
3824107590Sobrien  "
3825107590Sobrien{
3826107590Sobrien  rtx insn, div_equal, mod_equal, equal;
3827107590Sobrien
3828107590Sobrien  div_equal = gen_rtx_UDIV (DImode, operands[1], operands[2]);
3829107590Sobrien  mod_equal = gen_rtx_UMOD (DImode, operands[1], operands[2]);
3830107590Sobrien  equal = gen_rtx_IOR (TImode,
3831107590Sobrien		       gen_rtx_ZERO_EXTEND (TImode, div_equal),
3832107590Sobrien		       gen_rtx_ASHIFT (TImode,
3833107590Sobrien				       gen_rtx_ZERO_EXTEND (TImode, mod_equal),
3834107590Sobrien				       GEN_INT (64)));
3835107590Sobrien
3836107590Sobrien  operands[4] = gen_reg_rtx(TImode);
3837107590Sobrien  emit_insn (gen_rtx_CLOBBER (VOIDmode, operands[4]));
3838107590Sobrien  emit_move_insn (gen_lowpart (DImode, operands[4]), operands[1]);
3839107590Sobrien  emit_move_insn (gen_highpart (DImode, operands[4]), const0_rtx);
3840107590Sobrien  insn = emit_insn (gen_udivmodtidi3 (operands[4], operands[4], operands[2]));
3841107590Sobrien  REG_NOTES (insn) =
3842107590Sobrien	gen_rtx_EXPR_LIST (REG_EQUAL, equal, REG_NOTES (insn));
3843107590Sobrien
3844107590Sobrien  insn = emit_move_insn (operands[0], gen_lowpart (DImode, operands[4]));
3845107590Sobrien  REG_NOTES (insn) =
3846107590Sobrien        gen_rtx_EXPR_LIST (REG_EQUAL, div_equal, REG_NOTES (insn));
3847107590Sobrien
3848107590Sobrien  insn = emit_move_insn (operands[3], gen_highpart (DImode, operands[4]));
3849107590Sobrien  REG_NOTES (insn) =
3850107590Sobrien        gen_rtx_EXPR_LIST (REG_EQUAL, mod_equal, REG_NOTES (insn));
3851107590Sobrien
3852107590Sobrien  DONE;
3853107590Sobrien}")
3854107590Sobrien
3855107590Sobrien(define_insn "udivmodtidi3"
3856107590Sobrien  [(set (match_operand:TI 0 "register_operand" "=d,d")
3857107590Sobrien        (ior:TI (zero_extend:TI 
3858107590Sobrien                  (truncate:DI
3859107590Sobrien                    (udiv:TI (match_operand:TI 1 "register_operand" "0,0")
3860107590Sobrien                             (zero_extend:TI
3861107590Sobrien                               (match_operand:DI 2 "nonimmediate_operand" "d,m")))))
3862107590Sobrien                (ashift:TI
3863107590Sobrien                  (zero_extend:TI
3864107590Sobrien                    (truncate:DI
3865107590Sobrien                      (umod:TI (match_dup 1) (zero_extend:TI (match_dup 2)))))
3866107590Sobrien                  (const_int 64))))]
3867107590Sobrien  "TARGET_64BIT"
3868107590Sobrien  "@
3869107590Sobrien   dlgr\\t%0,%2
3870107590Sobrien   dlg\\t%0,%2"
3871107590Sobrien  [(set_attr "op_type"  "RRE,RXE")
3872107590Sobrien   (set_attr "type"     "idiv")
3873107590Sobrien   (set_attr "atype"    "reg,mem")])
3874107590Sobrien
3875107590Sobrien;
3876107590Sobrien; divmodsi4 instruction pattern(s).
3877107590Sobrien;
3878107590Sobrien
3879107590Sobrien(define_expand "divmodsi4"
3880107590Sobrien  [(parallel [(set (match_operand:SI 0 "general_operand" "")
3881107590Sobrien		   (div:SI (match_operand:SI 1 "general_operand" "")
3882107590Sobrien			   (match_operand:SI 2 "nonimmediate_operand" "")))
3883107590Sobrien	      (set (match_operand:SI 3 "general_operand" "")
3884107590Sobrien		   (mod:SI (match_dup 1) (match_dup 2)))])
3885107590Sobrien   (clobber (match_dup 4))]
3886107590Sobrien  "!TARGET_64BIT"
3887107590Sobrien  "
3888107590Sobrien{
3889107590Sobrien  rtx insn, div_equal, mod_equal, equal;
3890107590Sobrien
3891107590Sobrien  div_equal = gen_rtx_DIV (SImode, operands[1], operands[2]);
3892107590Sobrien  mod_equal = gen_rtx_MOD (SImode, operands[1], operands[2]);
3893107590Sobrien  equal = gen_rtx_IOR (DImode,
3894107590Sobrien		       gen_rtx_ZERO_EXTEND (DImode, div_equal),
3895107590Sobrien		       gen_rtx_ASHIFT (DImode,
3896107590Sobrien				       gen_rtx_ZERO_EXTEND (DImode, mod_equal),
3897107590Sobrien				       GEN_INT (32)));
3898107590Sobrien
3899107590Sobrien  operands[4] = gen_reg_rtx(DImode);
3900107590Sobrien  emit_insn (gen_extendsidi2 (operands[4], operands[1]));
3901107590Sobrien  insn = emit_insn (gen_divmoddisi3 (operands[4], operands[4], operands[2]));
3902107590Sobrien  REG_NOTES (insn) =
3903107590Sobrien	gen_rtx_EXPR_LIST (REG_EQUAL, equal, REG_NOTES (insn));
3904107590Sobrien
3905107590Sobrien  insn = emit_move_insn (operands[0], gen_lowpart (SImode, operands[4]));
3906107590Sobrien  REG_NOTES (insn) =
3907107590Sobrien        gen_rtx_EXPR_LIST (REG_EQUAL, div_equal, REG_NOTES (insn));
3908107590Sobrien
3909107590Sobrien  insn = emit_move_insn (operands[3], gen_highpart (SImode, operands[4]));
3910107590Sobrien  REG_NOTES (insn) =
3911107590Sobrien        gen_rtx_EXPR_LIST (REG_EQUAL, mod_equal, REG_NOTES (insn));
3912107590Sobrien
3913107590Sobrien  DONE;
3914107590Sobrien}")
3915107590Sobrien
3916107590Sobrien(define_insn "divmoddisi3"
3917107590Sobrien  [(set (match_operand:DI 0 "register_operand" "=d,d")
3918107590Sobrien        (ior:DI (zero_extend:DI
3919107590Sobrien                  (truncate:SI
3920107590Sobrien                    (div:DI (match_operand:DI 1 "register_operand" "0,0")
3921107590Sobrien                            (sign_extend:DI 
3922107590Sobrien                              (match_operand:SI 2 "nonimmediate_operand" "d,m")))))
3923107590Sobrien                (ashift:DI
3924107590Sobrien                  (zero_extend:DI
3925107590Sobrien                    (truncate:SI
3926107590Sobrien                      (mod:DI (match_dup 1) (sign_extend:SI (match_dup 2)))))
3927107590Sobrien                  (const_int 32))))]
3928107590Sobrien  "!TARGET_64BIT"
3929107590Sobrien  "@
3930107590Sobrien   dr\\t%0,%2
3931107590Sobrien   d\\t%0,%2"
3932107590Sobrien  [(set_attr "op_type"  "RR,RX")
3933107590Sobrien   (set_attr "type"     "idiv")
3934107590Sobrien   (set_attr "atype"    "reg,mem")])
3935107590Sobrien
3936107590Sobrien;
3937107590Sobrien; udivsi3 and umodsi3 instruction pattern(s).
3938107590Sobrien;
3939107590Sobrien
3940107590Sobrien
3941107590Sobrien(define_expand "udivsi3"
3942107590Sobrien  [(set (match_operand:SI 0 "register_operand" "=d")
3943107590Sobrien        (udiv:SI (match_operand:SI 1 "general_operand" "")
3944107590Sobrien                 (match_operand:SI 2 "general_operand" "")))
3945107590Sobrien   (clobber (match_dup 3))]
3946107590Sobrien  "!TARGET_64BIT"
3947107590Sobrien  "
3948107590Sobrien{
3949107590Sobrien  rtx insn, udiv_equal, umod_equal, equal;
3950107590Sobrien
3951107590Sobrien  udiv_equal = gen_rtx_UDIV (SImode, operands[1], operands[2]);
3952107590Sobrien  umod_equal = gen_rtx_UMOD (SImode, operands[1], operands[2]);
3953107590Sobrien  equal = gen_rtx_IOR (DImode,
3954107590Sobrien		       gen_rtx_ZERO_EXTEND (DImode, udiv_equal),
3955107590Sobrien		       gen_rtx_ASHIFT (DImode,
3956107590Sobrien				       gen_rtx_ZERO_EXTEND (DImode, umod_equal),
3957107590Sobrien				       GEN_INT (32)));
3958107590Sobrien
3959107590Sobrien  operands[3] = gen_reg_rtx (DImode);
3960107590Sobrien
3961107590Sobrien  if (CONSTANT_P (operands[2]))
3962107590Sobrien    {
3963107590Sobrien      if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0)
3964107590Sobrien        {
3965107590Sobrien          rtx label1 = gen_label_rtx ();
3966107590Sobrien
3967107590Sobrien	  operands[1] = make_safe_from (operands[1], operands[0]);
3968107590Sobrien          emit_move_insn (operands[0], const0_rtx);
3969107590Sobrien          emit_insn (gen_cmpsi (operands[1], operands[2]));
3970107590Sobrien          emit_jump_insn (gen_bltu (label1));
3971107590Sobrien          emit_move_insn (operands[0], const1_rtx);
3972107590Sobrien          emit_label (label1);
3973107590Sobrien        }
3974107590Sobrien      else
3975107590Sobrien        {
3976107590Sobrien          operands[2] = force_reg (SImode, operands[2]);	
3977107590Sobrien          operands[2] = make_safe_from (operands[2], operands[0]);	
3978107590Sobrien
3979107590Sobrien	  emit_insn (gen_zero_extendsidi2 (operands[3], operands[1]));
3980107590Sobrien	  insn = emit_insn (gen_divmoddisi3 (operands[3], operands[3],
3981107590Sobrien					     operands[2]));
3982107590Sobrien	  REG_NOTES (insn) =
3983107590Sobrien	    gen_rtx_EXPR_LIST (REG_EQUAL, equal, REG_NOTES (insn));
3984107590Sobrien	  
3985107590Sobrien	  insn = emit_move_insn (operands[0], 
3986107590Sobrien				 gen_lowpart (SImode, operands[3]));
3987107590Sobrien	  REG_NOTES (insn) =
3988107590Sobrien	    gen_rtx_EXPR_LIST (REG_EQUAL, 
3989107590Sobrien			       udiv_equal, REG_NOTES (insn));
3990107590Sobrien        }
3991107590Sobrien    }
3992107590Sobrien  else
3993107590Sobrien    {  
3994107590Sobrien      rtx label1 = gen_label_rtx ();
3995107590Sobrien      rtx label2 = gen_label_rtx ();
3996107590Sobrien      rtx label3 = gen_label_rtx ();
3997107590Sobrien
3998107590Sobrien      operands[1] = force_reg (SImode, operands[1]);	
3999107590Sobrien      operands[1] = make_safe_from (operands[1], operands[0]);	
4000107590Sobrien      operands[2] = force_reg (SImode, operands[2]);	
4001107590Sobrien      operands[2] = make_safe_from (operands[2], operands[0]);	
4002107590Sobrien
4003107590Sobrien      emit_move_insn (operands[0], const0_rtx);
4004107590Sobrien      emit_insn (gen_cmpsi (operands[2], operands[1]));
4005107590Sobrien      emit_jump_insn (gen_bgtu (label3));
4006107590Sobrien      emit_insn (gen_cmpsi (operands[2], const1_rtx));
4007107590Sobrien      emit_jump_insn (gen_blt (label2));
4008107590Sobrien      emit_insn (gen_cmpsi (operands[2], const1_rtx));
4009107590Sobrien      emit_jump_insn (gen_beq (label1));
4010107590Sobrien      emit_insn (gen_zero_extendsidi2 (operands[3], operands[1]));
4011107590Sobrien      insn = emit_insn (gen_divmoddisi3 (operands[3], operands[3],
4012107590Sobrien					 operands[2]));
4013107590Sobrien      REG_NOTES (insn) =
4014107590Sobrien      gen_rtx_EXPR_LIST (REG_EQUAL, equal, REG_NOTES (insn));
4015107590Sobrien      
4016107590Sobrien      insn = emit_move_insn (operands[0], 
4017107590Sobrien			     gen_lowpart (SImode, operands[3]));
4018107590Sobrien      REG_NOTES (insn) =
4019107590Sobrien      gen_rtx_EXPR_LIST (REG_EQUAL, 
4020107590Sobrien			       udiv_equal, REG_NOTES (insn));
4021107590Sobrien      emit_jump (label3);
4022107590Sobrien      emit_label (label1);
4023107590Sobrien      emit_move_insn (operands[0], operands[1]);
4024107590Sobrien      emit_jump (label3);
4025107590Sobrien      emit_label (label2);
4026107590Sobrien      emit_move_insn (operands[0], const1_rtx);
4027107590Sobrien      emit_label (label3);
4028107590Sobrien    }
4029107590Sobrien  emit_move_insn (operands[0], operands[0]);	
4030107590Sobrien  DONE;
4031107590Sobrien}")
4032107590Sobrien
4033107590Sobrien(define_expand "umodsi3"
4034107590Sobrien  [(set (match_operand:SI 0 "register_operand" "=d")
4035107590Sobrien        (umod:SI (match_operand:SI 1 "nonimmediate_operand" "")
4036107590Sobrien                 (match_operand:SI 2 "nonimmediate_operand" "")))
4037107590Sobrien   (clobber (match_dup 3))]
4038107590Sobrien  "!TARGET_64BIT"
4039107590Sobrien  "
4040107590Sobrien{
4041107590Sobrien  rtx insn, udiv_equal, umod_equal, equal;
4042107590Sobrien
4043107590Sobrien  udiv_equal = gen_rtx_UDIV (SImode, operands[1], operands[2]);
4044107590Sobrien  umod_equal = gen_rtx_UMOD (SImode, operands[1], operands[2]);
4045107590Sobrien  equal = gen_rtx_IOR (DImode,
4046107590Sobrien		       gen_rtx_ZERO_EXTEND (DImode, udiv_equal),
4047107590Sobrien		       gen_rtx_ASHIFT (DImode,
4048107590Sobrien				       gen_rtx_ZERO_EXTEND (DImode, umod_equal),
4049107590Sobrien				       GEN_INT (32)));
4050107590Sobrien
4051107590Sobrien  operands[3] = gen_reg_rtx (DImode);
4052107590Sobrien
4053107590Sobrien  if (CONSTANT_P (operands[2]))
4054107590Sobrien    {
4055107590Sobrien      if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) <= 0)
4056107590Sobrien        {
4057107590Sobrien          rtx label1 = gen_label_rtx ();
4058107590Sobrien
4059107590Sobrien          operands[1] = make_safe_from (operands[1], operands[0]);
4060107590Sobrien	  emit_move_insn (operands[0], operands[1]);
4061107590Sobrien          emit_insn (gen_cmpsi (operands[0], operands[2]));
4062107590Sobrien          emit_jump_insn (gen_bltu (label1));
4063107590Sobrien	  emit_insn (gen_abssi2 (operands[0], operands[2]));
4064107590Sobrien          emit_insn (gen_addsi3 (operands[0], operands[0], operands[1]));
4065107590Sobrien          emit_label (label1);
4066107590Sobrien        }
4067107590Sobrien      else
4068107590Sobrien        {
4069107590Sobrien          operands[2] = force_reg (SImode, operands[2]);	
4070107590Sobrien          operands[2] = make_safe_from (operands[2], operands[0]);	
4071107590Sobrien
4072107590Sobrien	  emit_insn (gen_zero_extendsidi2 (operands[3], operands[1]));
4073107590Sobrien	  insn = emit_insn (gen_divmoddisi3 (operands[3], operands[3],
4074107590Sobrien					     operands[2]));
4075107590Sobrien	  REG_NOTES (insn) =
4076107590Sobrien	    gen_rtx_EXPR_LIST (REG_EQUAL, equal, REG_NOTES (insn));
4077107590Sobrien	  
4078107590Sobrien	  insn = emit_move_insn (operands[0], 
4079107590Sobrien				 gen_highpart (SImode, operands[3]));
4080107590Sobrien	  REG_NOTES (insn) =
4081107590Sobrien	    gen_rtx_EXPR_LIST (REG_EQUAL, 
4082107590Sobrien			       umod_equal, REG_NOTES (insn));
4083107590Sobrien        }
4084107590Sobrien    }
4085107590Sobrien  else
4086107590Sobrien    {
4087107590Sobrien      rtx label1 = gen_label_rtx ();
4088107590Sobrien      rtx label2 = gen_label_rtx ();
4089107590Sobrien      rtx label3 = gen_label_rtx ();
4090107590Sobrien
4091107590Sobrien      operands[1] = force_reg (SImode, operands[1]);	
4092107590Sobrien      operands[1] = make_safe_from (operands[1], operands[0]);	
4093107590Sobrien      operands[2] = force_reg (SImode, operands[2]);	
4094107590Sobrien      operands[2] = make_safe_from (operands[2], operands[0]);	
4095107590Sobrien
4096107590Sobrien      emit_move_insn(operands[0], operands[1]);	
4097107590Sobrien      emit_insn (gen_cmpsi (operands[2], operands[1]));
4098107590Sobrien      emit_jump_insn (gen_bgtu (label3));
4099107590Sobrien      emit_insn (gen_cmpsi (operands[2], const1_rtx));
4100107590Sobrien      emit_jump_insn (gen_blt (label2));
4101107590Sobrien      emit_insn (gen_cmpsi (operands[2], const1_rtx));
4102107590Sobrien      emit_jump_insn (gen_beq (label1));
4103107590Sobrien      emit_insn (gen_zero_extendsidi2 (operands[3], operands[1]));
4104107590Sobrien      insn = emit_insn (gen_divmoddisi3 (operands[3], operands[3],
4105107590Sobrien					 operands[2]));
4106107590Sobrien      REG_NOTES (insn) =
4107107590Sobrien      gen_rtx_EXPR_LIST (REG_EQUAL, equal, REG_NOTES (insn));
4108107590Sobrien      
4109107590Sobrien      insn = emit_move_insn (operands[0], 
4110107590Sobrien			     gen_highpart (SImode, operands[3]));
4111107590Sobrien      REG_NOTES (insn) =
4112107590Sobrien      gen_rtx_EXPR_LIST (REG_EQUAL, 
4113107590Sobrien			 umod_equal, REG_NOTES (insn));
4114107590Sobrien      emit_jump (label3);
4115107590Sobrien      emit_label (label1);
4116107590Sobrien      emit_move_insn (operands[0], const0_rtx);
4117107590Sobrien      emit_jump (label3);
4118107590Sobrien      emit_label (label2);
4119107590Sobrien      emit_insn (gen_subsi3 (operands[0], operands[0], operands[2]));
4120107590Sobrien      emit_label (label3);
4121107590Sobrien    }
4122107590Sobrien  DONE;
4123107590Sobrien}")
4124107590Sobrien
4125107590Sobrien;
4126107590Sobrien; divdf3 instruction pattern(s).
4127107590Sobrien;
4128107590Sobrien
4129107590Sobrien(define_expand "divdf3"
4130107590Sobrien  [(parallel
4131107590Sobrien    [(set (match_operand:DF 0 "register_operand" "=f,f")
4132107590Sobrien          (div:DF (match_operand:DF 1 "register_operand" "0,0")
4133107590Sobrien                  (match_operand:DF 2 "general_operand" "f,m")))
4134107590Sobrien     (clobber (reg:CC 33))])]
4135107590Sobrien  "TARGET_HARD_FLOAT"
4136107590Sobrien  "")
4137107590Sobrien
4138107590Sobrien(define_insn "*divdf3"
4139107590Sobrien  [(set (match_operand:DF 0 "register_operand" "=f,f")
4140107590Sobrien        (div:DF (match_operand:DF 1 "register_operand" "0,0")
4141107590Sobrien                (match_operand:DF 2 "general_operand" "f,m")))
4142107590Sobrien   (clobber (reg:CC 33))]
4143107590Sobrien  "TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT"
4144107590Sobrien  "@
4145107590Sobrien   ddbr\\t%0,%2
4146107590Sobrien   ddb\\t%0,%2"
4147107590Sobrien  [(set_attr "op_type"  "RRE,RXE")
4148107590Sobrien   (set_attr "type"     "fdiv")
4149107590Sobrien   (set_attr "atype"    "reg,mem")])
4150107590Sobrien
4151107590Sobrien(define_insn "*divdf3_ibm"
4152107590Sobrien  [(set (match_operand:DF 0 "register_operand" "=f,f")
4153107590Sobrien        (div:DF (match_operand:DF 1 "register_operand" "0,0")
4154107590Sobrien                (match_operand:DF 2 "general_operand" "f,m")))
4155107590Sobrien   (clobber (reg:CC 33))]
4156107590Sobrien  "TARGET_HARD_FLOAT && TARGET_IBM_FLOAT"
4157107590Sobrien  "@
4158107590Sobrien   ddr\\t%0,%2
4159107590Sobrien   dd\\t%0,%2"
4160107590Sobrien  [(set_attr "op_type"  "RR,RX")
4161107590Sobrien   (set_attr "type"     "fdiv")
4162107590Sobrien   (set_attr "atype"    "reg,mem")])
4163107590Sobrien
4164107590Sobrien;
4165107590Sobrien; divsf3 instruction pattern(s).
4166107590Sobrien;
4167107590Sobrien
4168107590Sobrien(define_expand "divsf3"
4169107590Sobrien  [(parallel
4170107590Sobrien    [(set (match_operand:SF 0 "register_operand" "=f,f")
4171107590Sobrien          (div:SF (match_operand:SF 1 "register_operand" "0,0")
4172107590Sobrien                  (match_operand:SF 2 "general_operand" "f,m")))
4173107590Sobrien     (clobber (reg:CC 33))])]
4174107590Sobrien  "TARGET_HARD_FLOAT"
4175107590Sobrien  "")
4176107590Sobrien
4177107590Sobrien(define_insn "*divsf3"
4178107590Sobrien  [(set (match_operand:SF 0 "register_operand" "=f,f")
4179107590Sobrien        (div:SF (match_operand:SF 1 "register_operand" "0,0")
4180107590Sobrien                (match_operand:SF 2 "general_operand" "f,m")))
4181107590Sobrien   (clobber (reg:CC 33))]
4182107590Sobrien  "TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT"
4183107590Sobrien  "@
4184107590Sobrien   debr\\t%0,%2
4185107590Sobrien   deb\\t%0,%2"
4186107590Sobrien  [(set_attr "op_type"  "RRE,RXE")
4187107590Sobrien   (set_attr "type"     "fdiv")
4188107590Sobrien   (set_attr "atype"    "reg,mem")])
4189107590Sobrien
4190107590Sobrien(define_insn "*divsf3"
4191107590Sobrien  [(set (match_operand:SF 0 "register_operand" "=f,f")
4192107590Sobrien        (div:SF (match_operand:SF 1 "register_operand" "0,0")
4193107590Sobrien                (match_operand:SF 2 "general_operand" "f,m")))
4194107590Sobrien   (clobber (reg:CC 33))]
4195107590Sobrien  "TARGET_HARD_FLOAT && TARGET_IBM_FLOAT"
4196107590Sobrien  "@
4197107590Sobrien   der\\t%0,%2
4198107590Sobrien   de\\t%0,%2"
4199107590Sobrien  [(set_attr "op_type"  "RR,RX")
4200107590Sobrien   (set_attr "type"     "fdiv")
4201107590Sobrien   (set_attr "atype"    "reg,mem")])
4202107590Sobrien
4203107590Sobrien
4204107590Sobrien;;
4205107590Sobrien;;- And instructions.
4206107590Sobrien;;
4207107590Sobrien
4208107590Sobrien;
4209107590Sobrien; anddi3 instruction pattern(s).
4210107590Sobrien;
4211107590Sobrien
4212107590Sobrien(define_insn "*anddi3_cc"
4213107590Sobrien  [(set (reg 33)
4214107590Sobrien        (compare (and:DI (match_operand:DI 1 "register_operand" "%0,0")
4215107590Sobrien                         (match_operand:DI 2 "general_operand" "d,m"))
4216107590Sobrien                 (const_int 0)))
4217107590Sobrien   (set (match_operand:DI 0 "register_operand" "=d,d")
4218107590Sobrien        (and:DI (match_dup 1) (match_dup 2)))]
4219107590Sobrien  "s390_match_ccmode(insn, CCTmode) && TARGET_64BIT"
4220107590Sobrien  "@
4221107590Sobrien   ngr\\t%0,%2
4222107590Sobrien   ng\\t%0,%2"
4223107590Sobrien  [(set_attr "op_type"  "RRE,RXE")
4224107590Sobrien   (set_attr "atype"    "reg,mem")])
4225107590Sobrien
4226107590Sobrien(define_insn "*anddi3_cconly"
4227107590Sobrien  [(set (reg 33)
4228107590Sobrien        (compare (and:DI (match_operand:DI 1 "register_operand" "%0,0")
4229107590Sobrien                         (match_operand:DI 2 "general_operand" "d,m"))
4230107590Sobrien                 (const_int 0)))
4231107590Sobrien   (clobber (match_scratch:DI 0 "=d,d"))]
4232107590Sobrien  "s390_match_ccmode(insn, CCTmode) && TARGET_64BIT"
4233107590Sobrien  "@
4234107590Sobrien   ngr\\t%0,%2
4235107590Sobrien   ng\\t%0,%2"
4236107590Sobrien  [(set_attr "op_type"  "RRE,RXE")
4237107590Sobrien   (set_attr "atype"    "reg,mem")])
4238107590Sobrien
4239107590Sobrien(define_insn "*anddi3_ni"
4240107590Sobrien  [(set (match_operand:DI 0 "register_operand" "=d")
4241107590Sobrien        (and:DI (match_operand:DI 1 "register_operand" "%0")
4242107590Sobrien                (match_operand:DI 2 "immediate_operand" "n")))
4243107590Sobrien   (clobber (reg:CC 33))]
4244107590Sobrien  "TARGET_64BIT && s390_single_hi (operands[2], DImode, -1) >= 0"
4245107590Sobrien  "*
4246107590Sobrien{
4247107590Sobrien  int part = s390_single_hi (operands[2], DImode, -1);
4248107590Sobrien  operands[2] = GEN_INT (s390_extract_hi (operands[2], DImode, part));
4249107590Sobrien
4250107590Sobrien  switch (part)
4251107590Sobrien    {
4252107590Sobrien      case 0: return \"nihh\\t%0,%x2\";
4253107590Sobrien      case 1: return \"nihl\\t%0,%x2\";
4254107590Sobrien      case 2: return \"nilh\\t%0,%x2\";
4255107590Sobrien      case 3: return \"nill\\t%0,%x2\";
4256107590Sobrien      default: abort ();
4257107590Sobrien    }
4258107590Sobrien}"
4259107590Sobrien  [(set_attr "op_type"  "RI")
4260107590Sobrien   (set_attr "atype"    "reg")])
4261107590Sobrien
4262107590Sobrien(define_insn "anddi3"
4263107590Sobrien  [(set (match_operand:DI 0 "register_operand" "=d,d")
4264107590Sobrien        (and:DI (match_operand:DI 1 "register_operand" "%0,0")
4265107590Sobrien                (match_operand:DI 2 "general_operand" "d,m")))
4266107590Sobrien   (clobber (reg:CC 33))]
4267107590Sobrien  "TARGET_64BIT"
4268107590Sobrien  "@
4269107590Sobrien   ngr\\t%0,%2
4270107590Sobrien   ng\\t%0,%2"
4271107590Sobrien  [(set_attr "op_type"  "RRE,RXE")
4272107590Sobrien   (set_attr "atype"    "reg,mem")])
4273107590Sobrien
4274107590Sobrien(define_insn "*anddi3_ss"
4275107590Sobrien  [(set (match_operand:DI 0 "s_operand" "=Qo")
4276107590Sobrien        (and:DI (match_dup 0)
4277107590Sobrien                (match_operand:DI 1 "s_imm_operand" "Qo")))
4278107590Sobrien   (clobber (reg:CC 33))]
4279107590Sobrien  ""
4280107590Sobrien  "nc\\t%O0(8,%R0),%1"
4281107590Sobrien  [(set_attr "op_type"  "SS")
4282107590Sobrien   (set_attr "atype"    "mem")])
4283107590Sobrien
4284107590Sobrien(define_insn "*anddi3_ss_inv"
4285107590Sobrien  [(set (match_operand:DI 0 "s_operand" "=Qo")
4286107590Sobrien        (and:DI (match_operand:DI 1 "s_imm_operand" "Qo")
4287107590Sobrien                (match_dup 0)))
4288107590Sobrien   (clobber (reg:CC 33))]
4289107590Sobrien  ""
4290107590Sobrien  "nc\\t%O0(8,%R0),%1"
4291107590Sobrien  [(set_attr "op_type"  "SS")
4292107590Sobrien   (set_attr "atype"    "mem")])
4293107590Sobrien
4294107590Sobrien;
4295107590Sobrien; andsi3 instruction pattern(s).
4296107590Sobrien;
4297107590Sobrien
4298107590Sobrien(define_insn "*andsi3_cc"
4299107590Sobrien  [(set (reg 33)
4300107590Sobrien        (compare (and:SI (match_operand:SI 1 "register_operand" "%0,0")
4301107590Sobrien                         (match_operand:SI 2 "general_operand" "d,m"))
4302107590Sobrien                 (const_int 0)))
4303107590Sobrien   (set (match_operand:SI 0 "register_operand" "=d,d")
4304107590Sobrien        (and:SI (match_dup 1) (match_dup 2)))]
4305107590Sobrien  "s390_match_ccmode(insn, CCTmode)"
4306107590Sobrien  "@
4307107590Sobrien   nr\\t%0,%2
4308107590Sobrien   n\\t%0,%2"
4309107590Sobrien  [(set_attr "op_type"  "RR,RX")
4310107590Sobrien   (set_attr "atype"    "reg,mem")])
4311107590Sobrien
4312107590Sobrien(define_insn "*andsi3_cconly"
4313107590Sobrien  [(set (reg 33)
4314107590Sobrien        (compare (and:SI (match_operand:SI 1 "register_operand" "%0,0")
4315107590Sobrien                         (match_operand:SI 2 "general_operand" "d,m"))
4316107590Sobrien                 (const_int 0)))
4317107590Sobrien   (clobber (match_scratch:SI 0 "=d,d"))]
4318107590Sobrien  "s390_match_ccmode(insn, CCTmode)"
4319107590Sobrien  "@
4320107590Sobrien   nr\\t%0,%2
4321107590Sobrien   n\\t%0,%2"
4322107590Sobrien  [(set_attr "op_type"  "RR,RX")
4323107590Sobrien   (set_attr "atype"    "reg,mem")])
4324107590Sobrien
4325107590Sobrien(define_insn "*andsi3_ni"
4326107590Sobrien  [(set (match_operand:SI 0 "register_operand" "=d")
4327107590Sobrien        (and:SI (match_operand:SI 1 "register_operand" "%0")
4328107590Sobrien                (match_operand:SI 2 "immediate_operand" "n")))
4329107590Sobrien   (clobber (reg:CC 33))]
4330107590Sobrien  "TARGET_64BIT && s390_single_hi (operands[2], SImode, -1) >= 0"
4331107590Sobrien  "*
4332107590Sobrien{
4333107590Sobrien  int part = s390_single_hi (operands[2], SImode, -1);
4334107590Sobrien  operands[2] = GEN_INT (s390_extract_hi (operands[2], SImode, part));
4335107590Sobrien
4336107590Sobrien  switch (part)
4337107590Sobrien    {
4338107590Sobrien      case 0: return \"nilh\\t%0,%x2\";
4339107590Sobrien      case 1: return \"nill\\t%0,%x2\";
4340107590Sobrien      default: abort ();
4341107590Sobrien    }
4342107590Sobrien}"
4343107590Sobrien  [(set_attr "op_type"  "RI")
4344107590Sobrien   (set_attr "atype"    "reg")])
4345107590Sobrien
4346107590Sobrien(define_insn "andsi3"
4347107590Sobrien  [(set (match_operand:SI 0 "register_operand" "=d,d")
4348107590Sobrien        (and:SI (match_operand:SI 1 "register_operand" "%0,0")
4349107590Sobrien                (match_operand:SI 2 "general_operand" "d,m")))
4350107590Sobrien   (clobber (reg:CC 33))]
4351107590Sobrien  ""
4352107590Sobrien  "@
4353107590Sobrien   nr\\t%0,%2
4354107590Sobrien   n\\t%0,%2"
4355107590Sobrien  [(set_attr "op_type"  "RR,RX")
4356107590Sobrien   (set_attr "atype"    "reg,mem")])
4357107590Sobrien
4358107590Sobrien(define_insn "*andsi3_ss"
4359107590Sobrien  [(set (match_operand:SI 0 "s_operand" "=Qo")
4360107590Sobrien        (and:SI (match_dup 0)
4361107590Sobrien                (match_operand:SI 1 "s_imm_operand" "Qo")))
4362107590Sobrien   (clobber (reg:CC 33))]
4363107590Sobrien  ""
4364107590Sobrien  "nc\\t%O0(4,%R0),%1"
4365107590Sobrien  [(set_attr "op_type"  "SS")
4366107590Sobrien   (set_attr "atype"    "mem")])
4367107590Sobrien
4368107590Sobrien(define_insn "*andsi3_ss_inv"
4369107590Sobrien  [(set (match_operand:SI 0 "s_operand" "=Qo")
4370107590Sobrien        (and:SI (match_operand:SI 1 "s_imm_operand" "Qo")
4371107590Sobrien                (match_dup 0)))
4372107590Sobrien   (clobber (reg:CC 33))]
4373107590Sobrien  ""
4374107590Sobrien  "nc\\t%O0(4,%R0),%1"
4375107590Sobrien  [(set_attr "op_type"  "SS")
4376107590Sobrien   (set_attr "atype"    "mem")])
4377107590Sobrien
4378107590Sobrien;
4379107590Sobrien; andhi3 instruction pattern(s).
4380107590Sobrien;
4381107590Sobrien
4382107590Sobrien(define_insn "*andhi3_ni"
4383107590Sobrien  [(set (match_operand:HI 0 "register_operand" "=d,d")
4384107590Sobrien        (and:HI (match_operand:HI 1 "register_operand" "%0,0")
4385107590Sobrien                (match_operand:HI 2 "nonmemory_operand" "d,n")))
4386107590Sobrien   (clobber (reg:CC 33))]
4387107590Sobrien  "TARGET_64BIT"
4388107590Sobrien  "@
4389107590Sobrien   nr\\t%0,%2
4390107590Sobrien   nill\\t%0,%x2"
4391107590Sobrien  [(set_attr "op_type"  "RR,RI")
4392107590Sobrien   (set_attr "atype"    "reg")])
4393107590Sobrien
4394107590Sobrien(define_insn "andhi3"
4395107590Sobrien  [(set (match_operand:HI 0 "register_operand" "=d")
4396107590Sobrien        (and:HI (match_operand:HI 1 "register_operand" "%0")
4397107590Sobrien                (match_operand:HI 2 "nonmemory_operand" "d")))
4398107590Sobrien   (clobber (reg:CC 33))]
4399107590Sobrien  ""
4400107590Sobrien  "nr\\t%0,%2"
4401107590Sobrien  [(set_attr "op_type"  "RR")
4402107590Sobrien   (set_attr "atype"    "reg")])
4403107590Sobrien
4404107590Sobrien(define_insn "*andhi3_ss"
4405107590Sobrien  [(set (match_operand:HI 0 "s_operand" "=Qo")
4406107590Sobrien        (and:HI (match_dup 0)
4407107590Sobrien                (match_operand:HI 1 "s_imm_operand" "Qo")))
4408107590Sobrien   (clobber (reg:CC 33))]
4409107590Sobrien  ""
4410107590Sobrien  "nc\\t%O0(2,%R0),%1"
4411107590Sobrien  [(set_attr "op_type"  "SS")
4412107590Sobrien   (set_attr "atype"    "mem")])
4413107590Sobrien
4414107590Sobrien(define_insn "*andhi3_ss_inv"
4415107590Sobrien  [(set (match_operand:HI 0 "s_operand" "=Qo")
4416107590Sobrien        (and:HI (match_operand:HI 1 "s_imm_operand" "Qo")
4417107590Sobrien                (match_dup 0)))
4418107590Sobrien   (clobber (reg:CC 33))]
4419107590Sobrien  ""
4420107590Sobrien  "nc\\t%O0(2,%R0),%1"
4421107590Sobrien  [(set_attr "op_type"  "SS")
4422107590Sobrien   (set_attr "atype"    "mem")])
4423107590Sobrien
4424107590Sobrien;
4425107590Sobrien; andqi3 instruction pattern(s).
4426107590Sobrien;
4427107590Sobrien
4428107590Sobrien(define_insn "*andqi3_ni"
4429107590Sobrien  [(set (match_operand:QI 0 "register_operand" "=d,d")
4430107590Sobrien        (and:QI (match_operand:QI 1 "register_operand" "%0,0")
4431107590Sobrien                (match_operand:QI 2 "nonmemory_operand" "d,n")))
4432107590Sobrien   (clobber (reg:CC 33))]
4433107590Sobrien  "TARGET_64BIT"
4434107590Sobrien  "@
4435107590Sobrien   nr\\t%0,%2
4436107590Sobrien   nill\\t%0,%b2"
4437107590Sobrien  [(set_attr "op_type"  "RR,RI")
4438107590Sobrien   (set_attr "atype"    "reg")])
4439107590Sobrien
4440107590Sobrien(define_insn "andqi3"
4441107590Sobrien  [(set (match_operand:QI 0 "register_operand" "=d")
4442107590Sobrien        (and:QI (match_operand:QI 1 "register_operand" "%0")
4443107590Sobrien                (match_operand:QI 2 "nonmemory_operand" "d")))
4444107590Sobrien   (clobber (reg:CC 33))]
4445107590Sobrien  ""
4446107590Sobrien  "nr\\t%0,%2"
4447107590Sobrien  [(set_attr "op_type"  "RR")
4448107590Sobrien   (set_attr "atype"    "reg")])
4449107590Sobrien
4450107590Sobrien(define_insn "*andqi3_ss"
4451107590Sobrien  [(set (match_operand:QI 0 "s_operand" "=Qo,Qo")
4452107590Sobrien        (and:QI (match_dup 0)
4453107590Sobrien                (match_operand:QI 1 "s_imm_operand" "n,Qo")))
4454107590Sobrien   (clobber (reg:CC 33))]
4455107590Sobrien  ""
4456107590Sobrien  "@
4457107590Sobrien   ni\\t%0,%b1
4458107590Sobrien   nc\\t%O0(1,%R0),%1"
4459107590Sobrien  [(set_attr "op_type"  "SI,SS")
4460107590Sobrien   (set_attr "atype"    "mem")])
4461107590Sobrien
4462107590Sobrien(define_insn "*andqi3_ss_inv"
4463107590Sobrien  [(set (match_operand:QI 0 "s_operand" "=Qo,Qo")
4464107590Sobrien        (and:QI (match_operand:QI 1 "s_imm_operand" "n,Qo")
4465107590Sobrien                (match_dup 0)))
4466107590Sobrien   (clobber (reg:CC 33))]
4467107590Sobrien  ""
4468107590Sobrien  "@
4469107590Sobrien   ni\\t%0,%b1
4470107590Sobrien   nc\\t%O0(1,%R0),%1"
4471107590Sobrien  [(set_attr "op_type"  "SI,SS")
4472107590Sobrien   (set_attr "atype"    "mem")])
4473107590Sobrien
4474107590Sobrien
4475107590Sobrien;;
4476107590Sobrien;;- Bit set (inclusive or) instructions.
4477107590Sobrien;;
4478107590Sobrien
4479107590Sobrien;
4480107590Sobrien; iordi3 instruction pattern(s).
4481107590Sobrien;
4482107590Sobrien
4483107590Sobrien(define_insn "*iordi3_cc"
4484107590Sobrien  [(set (reg 33)
4485107590Sobrien        (compare (ior:DI (match_operand:DI 1 "register_operand" "%0,0")
4486107590Sobrien                         (match_operand:DI 2 "general_operand" "d,m"))
4487107590Sobrien                 (const_int 0)))
4488107590Sobrien   (set (match_operand:DI 0 "register_operand" "=d,d")
4489107590Sobrien        (ior:DI (match_dup 1) (match_dup 2)))]
4490107590Sobrien  "s390_match_ccmode(insn, CCTmode) && TARGET_64BIT"
4491107590Sobrien  "@
4492107590Sobrien   ogr\\t%0,%2
4493107590Sobrien   og\\t%0,%2"
4494107590Sobrien  [(set_attr "op_type"  "RRE,RXE")
4495107590Sobrien   (set_attr "atype"    "reg,mem")])
4496107590Sobrien
4497107590Sobrien(define_insn "*iordi3_cconly"
4498107590Sobrien  [(set (reg 33)
4499107590Sobrien        (compare (ior:DI (match_operand:DI 1 "register_operand" "%0,0")
4500107590Sobrien                         (match_operand:DI 2 "general_operand" "d,m"))
4501107590Sobrien                 (const_int 0)))
4502107590Sobrien   (clobber (match_scratch:DI 0 "=d,d"))]
4503107590Sobrien  "s390_match_ccmode(insn, CCTmode) && TARGET_64BIT"
4504107590Sobrien  "@
4505107590Sobrien   ogr\\t%0,%2
4506107590Sobrien   og\\t%0,%2"
4507107590Sobrien  [(set_attr "op_type"  "RRE,RXE")
4508107590Sobrien   (set_attr "atype"    "reg,mem")])
4509107590Sobrien
4510107590Sobrien(define_insn "*iordi3_oi"
4511107590Sobrien  [(set (match_operand:DI 0 "register_operand" "=d")
4512107590Sobrien        (ior:DI (match_operand:DI 1 "register_operand" "%0")
4513107590Sobrien                (match_operand:DI 2 "immediate_operand" "n")))
4514107590Sobrien   (clobber (reg:CC 33))]
4515107590Sobrien  "TARGET_64BIT && s390_single_hi (operands[2], DImode, 0) >= 0"
4516107590Sobrien  "*
4517107590Sobrien{
4518107590Sobrien  int part = s390_single_hi (operands[2], DImode, 0);
4519107590Sobrien  operands[2] = GEN_INT (s390_extract_hi (operands[2], DImode, part));
4520107590Sobrien
4521107590Sobrien  switch (part)
4522107590Sobrien    {
4523107590Sobrien      case 0: return \"oihh\\t%0,%x2\";
4524107590Sobrien      case 1: return \"oihl\\t%0,%x2\";
4525107590Sobrien      case 2: return \"oilh\\t%0,%x2\";
4526107590Sobrien      case 3: return \"oill\\t%0,%x2\";
4527107590Sobrien      default: abort ();
4528107590Sobrien    }
4529107590Sobrien}"
4530107590Sobrien  [(set_attr "op_type"  "RI")
4531107590Sobrien   (set_attr "atype"    "reg")])
4532107590Sobrien
4533107590Sobrien(define_insn "iordi3"
4534107590Sobrien  [(set (match_operand:DI 0 "register_operand" "=d,d")
4535107590Sobrien        (ior:DI (match_operand:DI 1 "register_operand" "%0,0")
4536107590Sobrien                (match_operand:DI 2 "general_operand" "d,m")))
4537107590Sobrien   (clobber (reg:CC 33))]
4538107590Sobrien  "TARGET_64BIT"
4539107590Sobrien  "@
4540107590Sobrien   ogr\\t%0,%2
4541107590Sobrien   og\\t%0,%2"
4542107590Sobrien  [(set_attr "op_type"  "RRE,RXE")
4543107590Sobrien   (set_attr "atype"    "reg,mem")])
4544107590Sobrien
4545107590Sobrien(define_insn "*iordi3_ss"
4546107590Sobrien  [(set (match_operand:DI 0 "s_operand" "=Qo")
4547107590Sobrien        (ior:DI (match_dup 0)
4548107590Sobrien                (match_operand:DI 1 "s_imm_operand" "Qo")))
4549107590Sobrien   (clobber (reg:CC 33))]
4550107590Sobrien  ""
4551107590Sobrien  "oc\\t%O0(8,%R0),%1"
4552107590Sobrien  [(set_attr "op_type"  "SS")
4553107590Sobrien   (set_attr "atype"    "mem")])
4554107590Sobrien
4555107590Sobrien(define_insn "*iordi3_ss_inv"
4556107590Sobrien  [(set (match_operand:DI 0 "s_operand" "=Qo")
4557107590Sobrien        (ior:DI (match_operand:DI 1 "s_imm_operand" "Qo")
4558107590Sobrien                (match_dup 0)))
4559107590Sobrien   (clobber (reg:CC 33))]
4560107590Sobrien  ""
4561107590Sobrien  "oc\\t%O0(8,%R0),%1"
4562107590Sobrien  [(set_attr "op_type"  "SS")
4563107590Sobrien   (set_attr "atype"    "mem")])
4564107590Sobrien
4565107590Sobrien;
4566107590Sobrien; iorsi3 instruction pattern(s).
4567107590Sobrien;
4568107590Sobrien
4569107590Sobrien(define_insn "*iorsi3_cc"
4570107590Sobrien  [(set (reg 33)
4571107590Sobrien        (compare (ior:SI (match_operand:SI 1 "register_operand" "%0,0")
4572107590Sobrien                         (match_operand:SI 2 "general_operand" "d,m"))
4573107590Sobrien                 (const_int 0)))
4574107590Sobrien   (set (match_operand:SI 0 "register_operand" "=d,d")
4575107590Sobrien        (ior:SI (match_dup 1) (match_dup 2)))]
4576107590Sobrien  "s390_match_ccmode(insn, CCTmode)"
4577107590Sobrien  "@
4578107590Sobrien   or\\t%0,%2
4579107590Sobrien   o\\t%0,%2"
4580107590Sobrien  [(set_attr "op_type"  "RR,RX")
4581107590Sobrien   (set_attr "atype"    "reg,mem")])
4582107590Sobrien
4583107590Sobrien(define_insn "*iorsi3_cconly"
4584107590Sobrien  [(set (reg 33)
4585107590Sobrien        (compare (ior:SI (match_operand:SI 1 "register_operand" "%0,0")
4586107590Sobrien                         (match_operand:SI 2 "general_operand" "d,m"))
4587107590Sobrien                 (const_int 0)))
4588107590Sobrien   (clobber (match_scratch:SI 0 "=d,d"))]
4589107590Sobrien  "s390_match_ccmode(insn, CCTmode)"
4590107590Sobrien  "@
4591107590Sobrien   or\\t%0,%2
4592107590Sobrien   o\\t%0,%2"
4593107590Sobrien  [(set_attr "op_type"  "RR,RX")
4594107590Sobrien   (set_attr "atype"    "reg,mem")])
4595107590Sobrien
4596107590Sobrien(define_insn "*iorsi3_oi"
4597107590Sobrien  [(set (match_operand:SI 0 "register_operand" "=d")
4598107590Sobrien        (ior:SI (match_operand:SI 1 "register_operand" "%0")
4599107590Sobrien                (match_operand:SI 2 "immediate_operand" "n")))
4600107590Sobrien   (clobber (reg:CC 33))]
4601107590Sobrien  "TARGET_64BIT && s390_single_hi (operands[2], SImode, 0) >= 0"
4602107590Sobrien  "*
4603107590Sobrien{
4604107590Sobrien  int part = s390_single_hi (operands[2], SImode, 0);
4605107590Sobrien  operands[2] = GEN_INT (s390_extract_hi (operands[2], SImode, part));
4606107590Sobrien
4607107590Sobrien  switch (part)
4608107590Sobrien    {
4609107590Sobrien      case 0: return \"oilh\\t%0,%x2\";
4610107590Sobrien      case 1: return \"oill\\t%0,%x2\";
4611107590Sobrien      default: abort ();
4612107590Sobrien    }
4613107590Sobrien}"
4614107590Sobrien  [(set_attr "op_type"  "RI")
4615107590Sobrien   (set_attr "atype"    "reg")])
4616107590Sobrien
4617107590Sobrien(define_insn "iorsi3"
4618107590Sobrien  [(set (match_operand:SI 0 "register_operand" "=d,d")
4619107590Sobrien        (ior:SI (match_operand:SI 1 "register_operand" "%0,0")
4620107590Sobrien                (match_operand:SI 2 "general_operand" "d,m")))
4621107590Sobrien   (clobber (reg:CC 33))]
4622107590Sobrien  ""
4623107590Sobrien  "@
4624107590Sobrien   or\\t%0,%2
4625107590Sobrien   o\\t%0,%2"
4626107590Sobrien  [(set_attr "op_type"  "RR,RX")
4627107590Sobrien   (set_attr "atype"    "reg,mem")])
4628107590Sobrien
4629107590Sobrien(define_insn "*iorsi3_ss"
4630107590Sobrien  [(set (match_operand:SI 0 "s_operand" "=Qo")
4631107590Sobrien        (ior:SI (match_dup 0)
4632107590Sobrien                (match_operand:SI 1 "s_imm_operand" "Qo")))
4633107590Sobrien   (clobber (reg:CC 33))]
4634107590Sobrien  ""
4635107590Sobrien  "oc\\t%O0(4,%R0),%1"
4636107590Sobrien  [(set_attr "op_type"  "SS")
4637107590Sobrien   (set_attr "atype"    "mem")])
4638107590Sobrien
4639107590Sobrien(define_insn "*iorsi3_ss_inv"
4640107590Sobrien  [(set (match_operand:SI 0 "s_operand" "=Qo")
4641107590Sobrien        (ior:SI (match_operand:SI 1 "s_imm_operand" "Qo")
4642107590Sobrien                (match_dup 0)))
4643107590Sobrien   (clobber (reg:CC 33))]
4644107590Sobrien  ""
4645107590Sobrien  "oc\\t%O0(4,%R0),%1"
4646107590Sobrien  [(set_attr "op_type"  "SS")
4647107590Sobrien   (set_attr "atype"    "mem")])
4648107590Sobrien
4649107590Sobrien;
4650107590Sobrien; iorhi3 instruction pattern(s).
4651107590Sobrien;
4652107590Sobrien
4653107590Sobrien(define_insn "*iorhi3_oi"
4654107590Sobrien  [(set (match_operand:HI 0 "register_operand" "=d,d")
4655107590Sobrien        (ior:HI (match_operand:HI 1 "register_operand" "%0,0")
4656107590Sobrien                (match_operand:HI 2 "nonmemory_operand" "d,n")))
4657107590Sobrien   (clobber (reg:CC 33))]
4658107590Sobrien  "TARGET_64BIT"
4659107590Sobrien  "@
4660107590Sobrien   or\\t%0,%2
4661107590Sobrien   oill\\t%0,%x2"
4662107590Sobrien  [(set_attr "op_type"  "RR,RI")
4663107590Sobrien   (set_attr "atype"    "reg")])
4664107590Sobrien
4665107590Sobrien(define_insn "iorhi3"
4666107590Sobrien  [(set (match_operand:HI 0 "register_operand" "=d")
4667107590Sobrien        (ior:HI (match_operand:HI 1 "register_operand" "%0")
4668107590Sobrien                (match_operand:HI 2 "nonmemory_operand" "d")))
4669107590Sobrien   (clobber (reg:CC 33))]
4670107590Sobrien  ""
4671107590Sobrien  "or\\t%0,%2"
4672107590Sobrien  [(set_attr "op_type"  "RR")
4673107590Sobrien   (set_attr "atype"    "reg")])
4674107590Sobrien
4675107590Sobrien(define_insn "*iorhi3_ss"
4676107590Sobrien  [(set (match_operand:HI 0 "s_operand" "=Qo")
4677107590Sobrien        (ior:HI (match_dup 0)
4678107590Sobrien                (match_operand:HI 1 "s_imm_operand" "Qo")))
4679107590Sobrien   (clobber (reg:CC 33))]
4680107590Sobrien  ""
4681107590Sobrien  "oc\\t%O0(2,%R0),%1"
4682107590Sobrien  [(set_attr "op_type"  "SS")
4683107590Sobrien   (set_attr "atype"    "mem")])
4684107590Sobrien
4685107590Sobrien(define_insn "*iorhi3_ss_inv"
4686107590Sobrien  [(set (match_operand:HI 0 "s_operand" "=Qo")
4687107590Sobrien        (ior:HI (match_operand:HI 1 "s_imm_operand" "Qo")
4688107590Sobrien                (match_dup 0)))
4689107590Sobrien   (clobber (reg:CC 33))]
4690107590Sobrien  ""
4691107590Sobrien  "oc\\t%O0(2,%R0),%1"
4692107590Sobrien  [(set_attr "op_type"  "SS")
4693107590Sobrien   (set_attr "atype"    "mem")])
4694107590Sobrien
4695107590Sobrien;
4696107590Sobrien; iorqi3 instruction pattern(s).
4697107590Sobrien;
4698107590Sobrien
4699107590Sobrien(define_insn "*iorqi3_oi"
4700107590Sobrien  [(set (match_operand:QI 0 "register_operand" "=d,d")
4701107590Sobrien        (ior:QI (match_operand:QI 1 "register_operand" "%0,0")
4702107590Sobrien                (match_operand:QI 2 "nonmemory_operand" "d,n")))
4703107590Sobrien   (clobber (reg:CC 33))]
4704107590Sobrien  "TARGET_64BIT"
4705107590Sobrien  "@
4706107590Sobrien   or\\t%0,%2
4707107590Sobrien   oill\\t%0,%b2"
4708107590Sobrien  [(set_attr "op_type"  "RR,RI")
4709107590Sobrien   (set_attr "atype"    "reg")])
4710107590Sobrien
4711107590Sobrien(define_insn "iorqi3"
4712107590Sobrien  [(set (match_operand:QI 0 "register_operand" "=d")
4713107590Sobrien        (ior:QI (match_operand:QI 1 "register_operand" "%0")
4714107590Sobrien                (match_operand:QI 2 "nonmemory_operand" "d")))
4715107590Sobrien   (clobber (reg:CC 33))]
4716107590Sobrien  ""
4717107590Sobrien  "or\\t%0,%2"
4718107590Sobrien  [(set_attr "op_type"  "RR")
4719107590Sobrien   (set_attr "atype"    "reg")])
4720107590Sobrien
4721107590Sobrien(define_insn "*iorqi3_ss"
4722107590Sobrien  [(set (match_operand:QI 0 "s_operand" "=Qo,Qo")
4723107590Sobrien        (ior:QI (match_dup 0)
4724107590Sobrien                (match_operand:QI 1 "s_imm_operand" "n,Qo")))
4725107590Sobrien   (clobber (reg:CC 33))]
4726107590Sobrien  ""
4727107590Sobrien  "@
4728107590Sobrien   oi\\t%0,%b1
4729107590Sobrien   oc\\t%O0(1,%R0),%1"
4730107590Sobrien  [(set_attr "op_type"  "SI,SS")
4731107590Sobrien   (set_attr "atype"    "reg,mem")])
4732107590Sobrien
4733107590Sobrien(define_insn "*iorqi3_ss_inv"
4734107590Sobrien  [(set (match_operand:QI 0 "s_operand" "=Qo,Qo")
4735107590Sobrien        (ior:QI (match_operand:QI 1 "s_imm_operand" "n,Qo")
4736107590Sobrien                (match_dup 0)))
4737107590Sobrien   (clobber (reg:CC 33))]
4738107590Sobrien  ""
4739107590Sobrien  "@
4740107590Sobrien   oi\\t%0,%b1
4741107590Sobrien   oc\\t%O0(1,%R0),%1"
4742107590Sobrien  [(set_attr "op_type"  "SI,SS")
4743107590Sobrien   (set_attr "atype"    "reg,mem")])
4744107590Sobrien
4745107590Sobrien
4746107590Sobrien;;
4747107590Sobrien;;- Xor instructions.
4748107590Sobrien;;
4749107590Sobrien
4750107590Sobrien;
4751107590Sobrien; xordi3 instruction pattern(s).
4752107590Sobrien;
4753107590Sobrien
4754107590Sobrien(define_insn "*xordi3_cc"
4755107590Sobrien  [(set (reg 33)
4756107590Sobrien        (compare (xor:DI (match_operand:DI 1 "register_operand" "%0,0")
4757107590Sobrien                         (match_operand:DI 2 "general_operand" "d,m"))
4758107590Sobrien                 (const_int 0)))
4759107590Sobrien   (set (match_operand:DI 0 "register_operand" "=d,d")
4760107590Sobrien        (xor:DI (match_dup 1) (match_dup 2)))]
4761107590Sobrien  "s390_match_ccmode(insn, CCTmode) && TARGET_64BIT"
4762107590Sobrien  "@
4763107590Sobrien   xgr\\t%0,%2
4764107590Sobrien   xg\\t%0,%2"
4765107590Sobrien  [(set_attr "op_type"  "RRE,RXE")
4766107590Sobrien   (set_attr "atype"    "reg,mem")])
4767107590Sobrien
4768107590Sobrien(define_insn "*xordi3_cconly"
4769107590Sobrien  [(set (reg 33)
4770107590Sobrien        (compare (xor:DI (match_operand:DI 1 "register_operand" "%0,0")
4771107590Sobrien                         (match_operand:DI 2 "general_operand" "d,m"))
4772107590Sobrien                 (const_int 0)))
4773107590Sobrien   (clobber (match_scratch:DI 0 "=d,d"))]
4774107590Sobrien  "s390_match_ccmode(insn, CCTmode) && TARGET_64BIT"
4775107590Sobrien  "@
4776107590Sobrien   xgr\\t%0,%2
4777107590Sobrien   xr\\t%0,%2"
4778107590Sobrien  [(set_attr "op_type"  "RRE,RXE")
4779107590Sobrien   (set_attr "atype"    "reg,mem")])
4780107590Sobrien
4781107590Sobrien(define_insn "xordi3"
4782107590Sobrien  [(set (match_operand:DI 0 "register_operand" "=d,d")
4783107590Sobrien        (xor:DI (match_operand:DI 1 "register_operand" "%0,0")
4784107590Sobrien                (match_operand:DI 2 "general_operand" "d,m")))
4785107590Sobrien   (clobber (reg:CC 33))]
4786107590Sobrien  "TARGET_64BIT"
4787107590Sobrien  "@
4788107590Sobrien   xgr\\t%0,%2
4789107590Sobrien   xg\\t%0,%2"
4790107590Sobrien  [(set_attr "op_type"  "RRE,RXE")
4791107590Sobrien   (set_attr "atype"    "reg,mem")])
4792107590Sobrien
4793107590Sobrien(define_insn "*xordi3_ss"
4794107590Sobrien  [(set (match_operand:DI 0 "s_operand" "=Qo")
4795107590Sobrien        (xor:DI (match_dup 0)
4796107590Sobrien                (match_operand:DI 1 "s_imm_operand" "Qo")))
4797107590Sobrien   (clobber (reg:CC 33))]
4798107590Sobrien  ""
4799107590Sobrien  "xc\\t%O0(8,%R0),%1"
4800107590Sobrien  [(set_attr "op_type"  "SS")
4801107590Sobrien   (set_attr "atype"    "mem")])
4802107590Sobrien
4803107590Sobrien(define_insn "*xordi3_ss_inv"
4804107590Sobrien  [(set (match_operand:DI 0 "s_operand" "=Qo")
4805107590Sobrien        (xor:DI (match_operand:DI 1 "s_imm_operand" "Qo")
4806107590Sobrien                (match_dup 0)))
4807107590Sobrien   (clobber (reg:CC 33))]
4808107590Sobrien  ""
4809107590Sobrien  "xc\\t%O0(8,%R0),%1"
4810107590Sobrien  [(set_attr "op_type"  "SS")
4811107590Sobrien   (set_attr "atype"    "mem")])
4812107590Sobrien
4813107590Sobrien;
4814107590Sobrien; xorsi3 instruction pattern(s).
4815107590Sobrien;
4816107590Sobrien
4817107590Sobrien(define_insn "*xorsi3_cc"
4818107590Sobrien  [(set (reg 33)
4819107590Sobrien        (compare (xor:SI (match_operand:SI 1 "register_operand" "%0,0")
4820107590Sobrien                         (match_operand:SI 2 "general_operand" "d,m"))
4821107590Sobrien                 (const_int 0)))
4822107590Sobrien   (set (match_operand:SI 0 "register_operand" "=d,d")
4823107590Sobrien        (xor:SI (match_dup 1) (match_dup 2)))]
4824107590Sobrien  "s390_match_ccmode(insn, CCTmode)"
4825107590Sobrien  "@
4826107590Sobrien   xr\\t%0,%2
4827107590Sobrien   x\\t%0,%2"
4828107590Sobrien  [(set_attr "op_type"  "RR,RX")
4829107590Sobrien   (set_attr "atype"    "reg,mem")])
4830107590Sobrien
4831107590Sobrien(define_insn "*xorsi3_cconly"
4832107590Sobrien  [(set (reg 33)
4833107590Sobrien        (compare (xor:SI (match_operand:SI 1 "register_operand" "%0,0")
4834107590Sobrien                         (match_operand:SI 2 "general_operand" "d,m"))
4835107590Sobrien                 (const_int 0)))
4836107590Sobrien   (clobber (match_scratch:SI 0 "=d,d"))]
4837107590Sobrien  "s390_match_ccmode(insn, CCTmode)"
4838107590Sobrien  "@
4839107590Sobrien   xr\\t%0,%2
4840107590Sobrien   x\\t%0,%2"
4841107590Sobrien  [(set_attr "op_type"  "RR,RX")
4842107590Sobrien   (set_attr "atype"    "reg,mem")])
4843107590Sobrien
4844107590Sobrien(define_insn "xorsi3"
4845107590Sobrien  [(set (match_operand:SI 0 "register_operand" "=d,d")
4846107590Sobrien        (xor:SI (match_operand:SI 1 "register_operand" "%0,0")
4847107590Sobrien                (match_operand:SI 2 "general_operand" "d,m")))
4848107590Sobrien   (clobber (reg:CC 33))]
4849107590Sobrien  ""
4850107590Sobrien  "@
4851107590Sobrien   xr\\t%0,%2
4852107590Sobrien   x\\t%0,%2"
4853107590Sobrien  [(set_attr "op_type"  "RR,RX")
4854107590Sobrien   (set_attr "atype"    "reg,mem")])
4855107590Sobrien
4856107590Sobrien(define_insn "*xorsi3_ss"
4857107590Sobrien  [(set (match_operand:SI 0 "s_operand" "=Qo")
4858107590Sobrien        (xor:SI (match_dup 0)
4859107590Sobrien                (match_operand:SI 1 "s_imm_operand" "Qo")))
4860107590Sobrien   (clobber (reg:CC 33))]
4861107590Sobrien  ""
4862107590Sobrien  "xc\\t%O0(4,%R0),%1"
4863107590Sobrien  [(set_attr "op_type"  "SS")
4864107590Sobrien   (set_attr "atype"    "mem")])
4865107590Sobrien
4866107590Sobrien(define_insn "*xorsi3_ss_inv"
4867107590Sobrien  [(set (match_operand:SI 0 "s_operand" "=Qo")
4868107590Sobrien        (xor:SI (match_operand:SI 1 "s_imm_operand" "Qo")
4869107590Sobrien                (match_dup 0)))
4870107590Sobrien   (clobber (reg:CC 33))]
4871107590Sobrien  ""
4872107590Sobrien  "xc\\t%O0(4,%R0),%1"
4873107590Sobrien  [(set_attr "op_type"  "SS")
4874107590Sobrien   (set_attr "atype"    "mem")])
4875107590Sobrien
4876107590Sobrien;
4877107590Sobrien; xorhi3 instruction pattern(s).
4878107590Sobrien;
4879107590Sobrien
4880107590Sobrien(define_insn "xorhi3"
4881107590Sobrien  [(set (match_operand:HI 0 "register_operand" "=d")
4882107590Sobrien        (xor:HI (match_operand:HI 1 "register_operand" "%0")
4883107590Sobrien                (match_operand:HI 2 "nonmemory_operand" "d")))
4884107590Sobrien   (clobber (reg:CC 33))]
4885107590Sobrien  ""
4886107590Sobrien  "xr\\t%0,%2"
4887107590Sobrien  [(set_attr "op_type"  "RR")
4888107590Sobrien   (set_attr "atype"    "reg")])
4889107590Sobrien
4890107590Sobrien(define_insn "*xorhi3_ss"
4891107590Sobrien  [(set (match_operand:HI 0 "s_operand" "=Qo")
4892107590Sobrien        (xor:HI (match_dup 0)
4893107590Sobrien                (match_operand:HI 1 "s_imm_operand" "Qo")))
4894107590Sobrien   (clobber (reg:CC 33))]
4895107590Sobrien  ""
4896107590Sobrien  "xc\\t%O0(2,%R0),%1"
4897107590Sobrien  [(set_attr "op_type"  "SS")
4898107590Sobrien   (set_attr "atype"    "mem")])
4899107590Sobrien
4900107590Sobrien(define_insn "*xorhi3_ss_inv"
4901107590Sobrien  [(set (match_operand:HI 0 "s_operand" "=Qo")
4902107590Sobrien        (xor:HI (match_operand:HI 1 "s_imm_operand" "Qo")
4903107590Sobrien                (match_dup 0)))
4904107590Sobrien   (clobber (reg:CC 33))]
4905107590Sobrien  ""
4906107590Sobrien  "xc\\t%O0(2,%R0),%1"
4907107590Sobrien  [(set_attr "op_type"  "SS")
4908107590Sobrien   (set_attr "atype"    "mem")])
4909107590Sobrien
4910107590Sobrien;
4911107590Sobrien; xorqi3 instruction pattern(s).
4912107590Sobrien;
4913107590Sobrien
4914107590Sobrien(define_insn "xorqi3"
4915107590Sobrien  [(set (match_operand:QI 0 "register_operand" "=d")
4916107590Sobrien        (xor:QI (match_operand:QI 1 "register_operand" "%0")
4917107590Sobrien                (match_operand:QI 2 "nonmemory_operand" "d")))
4918107590Sobrien   (clobber (reg:CC 33))]
4919107590Sobrien  ""
4920107590Sobrien  "xr\\t%0,%2"
4921107590Sobrien  [(set_attr "op_type"  "RR")
4922107590Sobrien   (set_attr "atype"    "reg")])
4923107590Sobrien
4924107590Sobrien(define_insn "*xorqi3_ss"
4925107590Sobrien  [(set (match_operand:QI 0 "s_operand" "=Qo,Qo")
4926107590Sobrien        (xor:QI (match_dup 0)
4927107590Sobrien                (match_operand:QI 1 "s_imm_operand" "n,Qo")))
4928107590Sobrien   (clobber (reg:CC 33))]
4929107590Sobrien  ""
4930107590Sobrien  "@
4931107590Sobrien   xi\\t%0,%b1
4932107590Sobrien   xc\\t%O0(1,%R0),%1"
4933107590Sobrien  [(set_attr "op_type"  "SI,SS")
4934107590Sobrien   (set_attr "atype"    "mem")])
4935107590Sobrien
4936107590Sobrien(define_insn "*xorqi3_ss_inv"
4937107590Sobrien  [(set (match_operand:QI 0 "s_operand" "=Qo,Qo")
4938107590Sobrien        (xor:QI (match_operand:QI 1 "s_imm_operand" "n,Qo")
4939107590Sobrien                (match_dup 0)))
4940107590Sobrien   (clobber (reg:CC 33))]
4941107590Sobrien  ""
4942107590Sobrien  "@
4943107590Sobrien   xi\\t%0,%b1
4944107590Sobrien   xc\\t%O0(1,%R0),%1"
4945107590Sobrien  [(set_attr "op_type"  "SI,SS")
4946107590Sobrien   (set_attr "atype"    "mem")])
4947107590Sobrien
4948107590Sobrien
4949107590Sobrien;;
4950107590Sobrien;;- Negate instructions.
4951107590Sobrien;;
4952107590Sobrien
4953107590Sobrien;
4954107590Sobrien; negdi2 instruction pattern(s).
4955107590Sobrien;
4956107590Sobrien
4957107590Sobrien(define_expand "negdi2"
4958107590Sobrien  [(parallel
4959107590Sobrien    [(set (match_operand:DI 0 "register_operand" "=d")
4960107590Sobrien          (neg:DI (match_operand:DI 1 "register_operand" "d")))
4961107590Sobrien     (clobber (reg:CC 33))])]
4962107590Sobrien  ""
4963107590Sobrien  "")
4964107590Sobrien
4965107590Sobrien(define_insn "*negdi2_64"
4966107590Sobrien  [(set (match_operand:DI 0 "register_operand" "=d")
4967107590Sobrien        (neg:DI (match_operand:DI 1 "register_operand" "d")))
4968107590Sobrien   (clobber (reg:CC 33))]
4969107590Sobrien  "TARGET_64BIT"
4970107590Sobrien  "lcgr\\t%0,%1"
4971107590Sobrien  [(set_attr "op_type"  "RR")])
4972107590Sobrien
4973107590Sobrien(define_insn "*negdi2_31"
4974107590Sobrien  [(set (match_operand:DI 0 "register_operand" "=d")
4975107590Sobrien        (neg:DI (match_operand:DI 1 "register_operand" "d")))
4976107590Sobrien   (clobber (reg:CC 33))]
4977107590Sobrien  "!TARGET_64BIT"
4978107590Sobrien  "*
4979107590Sobrien{
4980107590Sobrien  rtx xop[1];
4981107590Sobrien  xop[0] = gen_label_rtx ();
4982107590Sobrien  output_asm_insn (\"lcr\\t%0,%1\", operands);
4983107590Sobrien  output_asm_insn (\"lcr\\t%N0,%N1\", operands);
4984107590Sobrien  output_asm_insn (\"je\\t%l0\", xop);
4985107590Sobrien  output_asm_insn (\"bctr\\t%0,0\", operands);
4986107590Sobrien  ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, \"L\",
4987107590Sobrien			     CODE_LABEL_NUMBER (xop[0]));
4988107590Sobrien  return \"\";
4989107590Sobrien}"
4990107590Sobrien  [(set_attr "op_type"  "NN")
4991107590Sobrien   (set_attr "type"     "other")
4992107590Sobrien   (set_attr "length"   "10")])
4993107590Sobrien
4994107590Sobrien;
4995107590Sobrien; negsi2 instruction pattern(s).
4996107590Sobrien;
4997107590Sobrien
4998107590Sobrien(define_insn "negsi2"
4999107590Sobrien  [(set (match_operand:SI 0 "register_operand" "=d")
5000107590Sobrien        (neg:SI (match_operand:SI 1 "register_operand" "d")))
5001107590Sobrien   (clobber (reg:CC 33))]
5002107590Sobrien  ""
5003107590Sobrien  "lcr\\t%0,%1"
5004107590Sobrien  [(set_attr "op_type"  "RR")])
5005107590Sobrien
5006107590Sobrien;
5007107590Sobrien; negdf2 instruction pattern(s).
5008107590Sobrien;
5009107590Sobrien
5010107590Sobrien(define_expand "negdf2"
5011107590Sobrien  [(parallel
5012107590Sobrien    [(set (match_operand:DF 0 "register_operand" "=f")
5013107590Sobrien          (neg:DF (match_operand:DF 1 "register_operand" "f")))
5014107590Sobrien     (clobber (reg:CC 33))])]
5015107590Sobrien  "TARGET_HARD_FLOAT"
5016107590Sobrien  "")
5017107590Sobrien
5018107590Sobrien(define_insn "*negdf2"
5019107590Sobrien  [(set (match_operand:DF 0 "register_operand" "=f")
5020107590Sobrien        (neg:DF (match_operand:DF 1 "register_operand" "f")))
5021107590Sobrien   (clobber (reg:CC 33))]
5022107590Sobrien  "TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT"
5023107590Sobrien  "lcdbr\\t%0,%1"
5024107590Sobrien  [(set_attr "op_type"  "RRE")])
5025107590Sobrien
5026107590Sobrien(define_insn "*negdf2_ibm"
5027107590Sobrien  [(set (match_operand:DF 0 "register_operand" "=f")
5028107590Sobrien        (neg:DF (match_operand:DF 1 "register_operand" "f")))
5029107590Sobrien   (clobber (reg:CC 33))]
5030107590Sobrien  "TARGET_HARD_FLOAT && TARGET_IBM_FLOAT"
5031107590Sobrien  "lcdr\\t%0,%1"
5032107590Sobrien  [(set_attr "op_type"  "RR")])
5033107590Sobrien
5034107590Sobrien;
5035107590Sobrien; negsf2 instruction pattern(s).
5036107590Sobrien;
5037107590Sobrien
5038107590Sobrien(define_expand "negsf2"
5039107590Sobrien  [(parallel
5040107590Sobrien    [(set (match_operand:SF 0 "register_operand" "=f")
5041107590Sobrien          (neg:SF (match_operand:SF 1 "register_operand" "f")))
5042107590Sobrien     (clobber (reg:CC 33))])]
5043107590Sobrien  "TARGET_HARD_FLOAT"
5044107590Sobrien  "")
5045107590Sobrien
5046107590Sobrien(define_insn "*negsf2"
5047107590Sobrien  [(set (match_operand:SF 0 "register_operand" "=f")
5048107590Sobrien        (neg:SF (match_operand:SF 1 "register_operand" "f")))
5049107590Sobrien   (clobber (reg:CC 33))]
5050107590Sobrien  "TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT"
5051107590Sobrien  "lcebr\\t%0,%1"
5052107590Sobrien  [(set_attr "op_type"  "RRE")])
5053107590Sobrien
5054107590Sobrien(define_insn "*negsf2"
5055107590Sobrien  [(set (match_operand:SF 0 "register_operand" "=f")
5056107590Sobrien        (neg:SF (match_operand:SF 1 "register_operand" "f")))
5057107590Sobrien   (clobber (reg:CC 33))]
5058107590Sobrien  "TARGET_HARD_FLOAT && TARGET_IBM_FLOAT"
5059107590Sobrien  "lcer\\t%0,%1"
5060107590Sobrien  [(set_attr "op_type"  "RR")])
5061107590Sobrien
5062107590Sobrien
5063107590Sobrien;;
5064107590Sobrien;;- Absolute value instructions.
5065107590Sobrien;;
5066107590Sobrien
5067107590Sobrien;
5068107590Sobrien; absdi2 instruction pattern(s).
5069107590Sobrien;
5070107590Sobrien
5071107590Sobrien(define_insn "absdi2"
5072107590Sobrien  [(set (match_operand:DI 0 "register_operand" "=d")
5073107590Sobrien        (abs:DI (match_operand:DI 1 "register_operand" "d")))
5074107590Sobrien   (clobber (reg:CC 33))]
5075107590Sobrien  "TARGET_64BIT"
5076107590Sobrien  "lpgr\\t%0,%1"
5077107590Sobrien  [(set_attr "op_type"  "RRE")])
5078107590Sobrien
5079107590Sobrien;
5080107590Sobrien; abssi2 instruction pattern(s).
5081107590Sobrien;
5082107590Sobrien
5083107590Sobrien(define_insn "abssi2"
5084107590Sobrien  [(set (match_operand:SI 0 "register_operand" "=d")
5085107590Sobrien        (abs:SI (match_operand:SI 1 "register_operand" "d")))
5086107590Sobrien   (clobber (reg:CC 33))]
5087107590Sobrien  ""
5088107590Sobrien  "lpr\\t%0,%1"
5089107590Sobrien  [(set_attr "op_type"  "RR")])
5090107590Sobrien
5091107590Sobrien;
5092107590Sobrien; absdf2 instruction pattern(s).
5093107590Sobrien;
5094107590Sobrien
5095107590Sobrien(define_expand "absdf2"
5096107590Sobrien  [(parallel
5097107590Sobrien    [(set (match_operand:DF 0 "register_operand" "=f")
5098107590Sobrien          (abs:DF (match_operand:DF 1 "register_operand" "f")))
5099107590Sobrien     (clobber (reg:CC 33))])]
5100107590Sobrien  "TARGET_HARD_FLOAT"
5101107590Sobrien  "")
5102107590Sobrien
5103107590Sobrien(define_insn "*absdf2"
5104107590Sobrien  [(set (match_operand:DF 0 "register_operand" "=f")
5105107590Sobrien        (abs:DF (match_operand:DF 1 "register_operand" "f")))
5106107590Sobrien   (clobber (reg:CC 33))]
5107107590Sobrien  "TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT"
5108107590Sobrien  "lpdbr\\t%0,%1"
5109107590Sobrien  [(set_attr "op_type"  "RRE")])
5110107590Sobrien
5111107590Sobrien(define_insn "*absdf2_ibm"
5112107590Sobrien  [(set (match_operand:DF 0 "register_operand" "=f")
5113107590Sobrien        (abs:DF (match_operand:DF 1 "register_operand" "f")))
5114107590Sobrien   (clobber (reg:CC 33))]
5115107590Sobrien  "TARGET_HARD_FLOAT && TARGET_IBM_FLOAT"
5116107590Sobrien  "lpdr\\t%0,%1"
5117107590Sobrien  [(set_attr "op_type"  "RR")])
5118107590Sobrien
5119107590Sobrien;
5120107590Sobrien; abssf2 instruction pattern(s).
5121107590Sobrien;
5122107590Sobrien
5123107590Sobrien(define_expand "abssf2"
5124107590Sobrien  [(parallel
5125107590Sobrien    [(set (match_operand:SF 0 "register_operand" "=f")
5126107590Sobrien          (abs:SF (match_operand:SF 1 "register_operand" "f")))
5127107590Sobrien     (clobber (reg:CC 33))])]
5128107590Sobrien  "TARGET_HARD_FLOAT"
5129107590Sobrien  "")
5130107590Sobrien
5131107590Sobrien(define_insn "*abssf2"
5132107590Sobrien  [(set (match_operand:SF 0 "register_operand" "=f")
5133107590Sobrien        (abs:SF (match_operand:SF 1 "register_operand" "f")))
5134107590Sobrien   (clobber (reg:CC 33))]
5135107590Sobrien  "TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT"
5136107590Sobrien  "lpebr\\t%0,%1"
5137107590Sobrien  [(set_attr "op_type"  "RRE")])
5138107590Sobrien
5139107590Sobrien(define_insn "*abssf2_ibm"
5140107590Sobrien  [(set (match_operand:SF 0 "register_operand" "=f")
5141107590Sobrien        (abs:SF (match_operand:SF 1 "register_operand" "f")))
5142107590Sobrien   (clobber (reg:CC 33))]
5143107590Sobrien  "TARGET_HARD_FLOAT && TARGET_IBM_FLOAT"
5144107590Sobrien  "lper\\t%0,%1"
5145107590Sobrien  [(set_attr "op_type"  "RR")])
5146107590Sobrien
5147107590Sobrien;;
5148107590Sobrien;;- Square root instructions.
5149107590Sobrien;;
5150107590Sobrien
5151107590Sobrien;
5152107590Sobrien; sqrtdf2 instruction pattern(s).
5153107590Sobrien;
5154107590Sobrien
5155107590Sobrien(define_insn "sqrtdf2"
5156107590Sobrien  [(set (match_operand:DF 0 "register_operand" "=f,f")
5157107590Sobrien	(sqrt:DF (match_operand:DF 1 "general_operand" "f,m")))]
5158107590Sobrien  "TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT"
5159107590Sobrien  "@
5160107590Sobrien   sqdbr\\t%0,%1
5161107590Sobrien   sqdb\\t%0,%1"
5162107590Sobrien  [(set_attr "op_type"  "RRE,RSE")])
5163107590Sobrien
5164107590Sobrien;
5165107590Sobrien; sqrtsf2 instruction pattern(s).
5166107590Sobrien;
5167107590Sobrien
5168107590Sobrien(define_insn "sqrtsf2"
5169107590Sobrien  [(set (match_operand:SF 0 "register_operand" "=f,f")
5170107590Sobrien	(sqrt:SF (match_operand:SF 1 "general_operand" "f,m")))]
5171107590Sobrien  "TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT"
5172107590Sobrien  "@
5173107590Sobrien   sqebr\\t%0,%1
5174107590Sobrien   sqeb\\t%0,%1"
5175107590Sobrien  [(set_attr "op_type"  "RRE,RSE")])
5176107590Sobrien
5177107590Sobrien;;
5178107590Sobrien;;- One complement instructions.
5179107590Sobrien;;
5180107590Sobrien
5181107590Sobrien;
5182107590Sobrien; one_cmpldi2 instruction pattern(s).
5183107590Sobrien;
5184107590Sobrien 
5185107590Sobrien(define_expand "one_cmpldi2"
5186107590Sobrien  [(parallel
5187107590Sobrien    [(set (match_operand:DI 0 "register_operand" "")
5188107590Sobrien          (xor:DI (match_operand:DI 1 "register_operand" "")
5189107590Sobrien                  (const_int -1)))
5190107590Sobrien     (clobber (reg:CC 33))])]
5191107590Sobrien  "TARGET_64BIT"
5192107590Sobrien  "")
5193107590Sobrien 
5194107590Sobrien;
5195107590Sobrien; one_cmplsi2 instruction pattern(s).
5196107590Sobrien;
5197107590Sobrien 
5198107590Sobrien(define_expand "one_cmplsi2"
5199107590Sobrien  [(parallel
5200107590Sobrien    [(set (match_operand:SI 0 "register_operand" "")
5201107590Sobrien          (xor:SI (match_operand:SI 1 "register_operand" "")
5202107590Sobrien                  (const_int -1)))
5203107590Sobrien     (clobber (reg:CC 33))])]
5204107590Sobrien  ""
5205107590Sobrien  "")
5206107590Sobrien 
5207107590Sobrien;
5208107590Sobrien; one_cmplhi2 instruction pattern(s).
5209107590Sobrien;
5210107590Sobrien 
5211107590Sobrien(define_expand "one_cmplhi2"
5212107590Sobrien  [(parallel
5213107590Sobrien    [(set (match_operand:HI 0 "register_operand" "")
5214107590Sobrien          (xor:HI (match_operand:HI 1 "register_operand" "")
5215107590Sobrien                  (const_int -1)))
5216107590Sobrien     (clobber (reg:CC 33))])]
5217107590Sobrien  ""
5218107590Sobrien  "")
5219107590Sobrien 
5220107590Sobrien;
5221107590Sobrien; one_cmplqi2 instruction pattern(s).
5222107590Sobrien;
5223107590Sobrien 
5224107590Sobrien(define_expand "one_cmplqi2"
5225107590Sobrien  [(parallel
5226107590Sobrien    [(set (match_operand:QI 0 "register_operand" "")
5227107590Sobrien          (xor:QI (match_operand:QI 1 "register_operand" "")
5228107590Sobrien                  (const_int -1)))
5229107590Sobrien     (clobber (reg:CC 33))])]
5230107590Sobrien  ""
5231107590Sobrien  "")
5232107590Sobrien
5233107590Sobrien
5234107590Sobrien;;
5235107590Sobrien;;- Rotate instructions.
5236107590Sobrien;;
5237107590Sobrien
5238107590Sobrien;
5239107590Sobrien; rotldi3 instruction pattern(s).
5240107590Sobrien;
5241107590Sobrien
5242107590Sobrien(define_insn "rotldi3"
5243107590Sobrien  [(set (match_operand:DI 0 "register_operand" "=d,d")
5244107590Sobrien	(rotate:DI (match_operand:DI 1 "register_operand" "d,d")
5245107590Sobrien		   (match_operand:SI 2 "nonmemory_operand" "J,a")))]
5246107590Sobrien  "TARGET_64BIT"
5247107590Sobrien  "@
5248107590Sobrien   rllg\\t%0,%1,%c2
5249107590Sobrien   rllg\\t%0,%1,0(%2)"
5250107590Sobrien  [(set_attr "op_type"  "RSE")])
5251107590Sobrien
5252107590Sobrien;
5253107590Sobrien; rotlsi3 instruction pattern(s).
5254107590Sobrien;
5255107590Sobrien
5256107590Sobrien(define_insn "rotlsi3"
5257107590Sobrien  [(set (match_operand:SI 0 "register_operand" "=d,d")
5258107590Sobrien	(rotate:SI (match_operand:SI 1 "register_operand" "d,d")
5259107590Sobrien		   (match_operand:SI 2 "nonmemory_operand" "J,a")))]
5260107590Sobrien  "TARGET_64BIT"
5261107590Sobrien  "@
5262107590Sobrien   rll\\t%0,%1,%c2
5263107590Sobrien   rll\\t%0,%1,0(%2)"
5264107590Sobrien  [(set_attr "op_type"  "RSE")])
5265107590Sobrien
5266107590Sobrien
5267107590Sobrien;;
5268107590Sobrien;;- Arithmetic shift instructions.
5269107590Sobrien;;
5270107590Sobrien
5271107590Sobrien;
5272107590Sobrien; ashldi3 instruction pattern(s).
5273107590Sobrien;
5274107590Sobrien
5275107590Sobrien(define_expand "ashldi3"
5276107590Sobrien  [(set (match_operand:DI 0 "register_operand" "")
5277107590Sobrien        (ashift:DI (match_operand:DI 1 "register_operand" "")
5278107590Sobrien                   (match_operand:SI 2 "nonmemory_operand" "")))]
5279107590Sobrien  ""
5280107590Sobrien  "")
5281107590Sobrien
5282107590Sobrien(define_insn "*ashldi3_31"
5283107590Sobrien  [(set (match_operand:DI 0 "register_operand" "=d,d")
5284107590Sobrien        (ashift:DI (match_operand:DI 1 "register_operand" "0,0")
5285107590Sobrien                   (match_operand:SI 2 "nonmemory_operand" "J,a")))]
5286107590Sobrien  "!TARGET_64BIT"
5287107590Sobrien  "@
5288107590Sobrien   sldl\\t%0,%c2
5289107590Sobrien   sldl\\t%0,0(%2)"     
5290107590Sobrien  [(set_attr "op_type"  "RS")])
5291107590Sobrien
5292107590Sobrien(define_insn "*ashldi3_64"
5293107590Sobrien  [(set (match_operand:DI 0 "register_operand" "=d,d")
5294107590Sobrien        (ashift:DI (match_operand:DI 1 "register_operand" "d,d")
5295107590Sobrien                   (match_operand:SI 2 "nonmemory_operand" "J,a")))]
5296107590Sobrien  "TARGET_64BIT"
5297107590Sobrien  "@
5298107590Sobrien   sllg\\t%0,%1,%2
5299107590Sobrien   sllg\\t%0,%1,0(%2)"
5300107590Sobrien  [(set_attr "op_type"  "RSE")])
5301107590Sobrien
5302107590Sobrien;
5303107590Sobrien; ashrdi3 instruction pattern(s).
5304107590Sobrien;
5305107590Sobrien
5306107590Sobrien(define_expand "ashrdi3"
5307107590Sobrien  [(parallel
5308107590Sobrien    [(set (match_operand:DI 0 "register_operand" "")
5309107590Sobrien          (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
5310107590Sobrien                       (match_operand:SI 2 "nonmemory_operand" "")))
5311107590Sobrien     (clobber (reg:CC 33))])]
5312107590Sobrien  ""
5313107590Sobrien  "")
5314107590Sobrien
5315107590Sobrien(define_insn "*ashrdi3_cc_31"
5316107590Sobrien  [(set (reg 33)
5317107590Sobrien        (compare (ashiftrt:DI (match_operand:DI 1 "register_operand" "0,0")
5318107590Sobrien                              (match_operand:SI 2 "nonmemory_operand" "J,a"))
5319107590Sobrien                 (const_int 0)))
5320107590Sobrien   (set (match_operand:DI 0 "register_operand" "=d,d")
5321107590Sobrien        (ashiftrt:DI (match_dup 1) (match_dup 2)))]
5322107590Sobrien  "!TARGET_64BIT && s390_match_ccmode(insn, CCSmode)"
5323107590Sobrien  "@
5324107590Sobrien   srda\\t%0,%c2
5325107590Sobrien   srda\\t%0,0(%2)"     
5326107590Sobrien  [(set_attr "op_type"  "RS")])
5327107590Sobrien
5328107590Sobrien(define_insn "*ashrdi3_cconly_31"
5329107590Sobrien  [(set (reg 33)
5330107590Sobrien        (compare (ashiftrt:DI (match_operand:DI 1 "register_operand" "0,0")
5331107590Sobrien                              (match_operand:SI 2 "nonmemory_operand" "J,a"))
5332107590Sobrien                 (const_int 0)))
5333107590Sobrien   (clobber (match_scratch:DI 0 "=d,d"))]
5334107590Sobrien  "!TARGET_64BIT && s390_match_ccmode(insn, CCSmode)"
5335107590Sobrien  "@
5336107590Sobrien   srda\\t%0,%c2
5337107590Sobrien   srda\\t%0,0(%2)"     
5338107590Sobrien  [(set_attr "op_type"  "RS")])
5339107590Sobrien
5340107590Sobrien(define_insn "*ashrdi3_31"
5341107590Sobrien  [(set (match_operand:DI 0 "register_operand" "=d,d")
5342107590Sobrien        (ashiftrt:DI (match_operand:DI 1 "register_operand" "0,0")
5343107590Sobrien                     (match_operand:SI 2 "nonmemory_operand" "J,a")))
5344107590Sobrien   (clobber (reg:CC 33))]
5345107590Sobrien  "!TARGET_64BIT"
5346107590Sobrien  "@
5347107590Sobrien   srda\\t%0,%c2
5348107590Sobrien   srda\\t%0,0(%2)"     
5349107590Sobrien  [(set_attr "op_type"  "RS")])
5350107590Sobrien
5351107590Sobrien(define_insn "*ashrdi3_cc_64"
5352107590Sobrien  [(set (reg 33)
5353107590Sobrien        (compare (ashiftrt:DI (match_operand:DI 1 "register_operand" "d,d")
5354107590Sobrien                              (match_operand:SI 2 "nonmemory_operand" "J,a"))
5355107590Sobrien                 (const_int 0)))
5356107590Sobrien   (set (match_operand:DI 0 "register_operand" "=d,d")
5357107590Sobrien        (ashiftrt:DI (match_dup 1) (match_dup 2)))]
5358107590Sobrien  "s390_match_ccmode(insn, CCSmode) && TARGET_64BIT"
5359107590Sobrien  "@
5360107590Sobrien   srag\\t%0,%1,%c2
5361107590Sobrien   srag\\t%0,%1,0(%2)"
5362107590Sobrien  [(set_attr "op_type"  "RSE")])
5363107590Sobrien
5364107590Sobrien(define_insn "*ashrdi3_cconly_64"
5365107590Sobrien  [(set (reg 33)
5366107590Sobrien        (compare (ashiftrt:DI (match_operand:DI 1 "register_operand" "d,d")
5367107590Sobrien                              (match_operand:SI 2 "nonmemory_operand" "J,a"))
5368107590Sobrien                 (const_int 0)))
5369107590Sobrien   (clobber (match_scratch:DI 0 "=d,d"))]
5370107590Sobrien  "s390_match_ccmode(insn, CCSmode) && TARGET_64BIT"
5371107590Sobrien  "@
5372107590Sobrien   srag\\t%0,%1,%c2
5373107590Sobrien   srag\\t%0,%1,0(%2)"
5374107590Sobrien  [(set_attr "op_type"  "RSE")])
5375107590Sobrien
5376107590Sobrien(define_insn "*ashrdi3_64"
5377107590Sobrien  [(set (match_operand:DI 0 "register_operand" "=d,d")
5378107590Sobrien        (ashiftrt:DI (match_operand:DI 1 "register_operand" "d,d")
5379107590Sobrien                     (match_operand:SI 2 "nonmemory_operand" "J,a")))
5380107590Sobrien   (clobber (reg:CC 33))]
5381107590Sobrien  "TARGET_64BIT"
5382107590Sobrien  "@
5383107590Sobrien   srag\\t%0,%1,%c2
5384107590Sobrien   srag\\t%0,%1,0(%2)"
5385107590Sobrien  [(set_attr "op_type"  "RSE")])
5386107590Sobrien
5387107590Sobrien;
5388107590Sobrien; ashlsi3 instruction pattern(s).
5389107590Sobrien;
5390107590Sobrien
5391107590Sobrien(define_insn "ashlsi3"
5392107590Sobrien  [(set (match_operand:SI 0 "register_operand" "=d,d")
5393107590Sobrien        (ashift:SI (match_operand:SI 1 "register_operand" "0,0")
5394107590Sobrien                   (match_operand:SI 2 "nonmemory_operand" "J,a")))]
5395107590Sobrien  ""
5396107590Sobrien  "@
5397107590Sobrien   sll\\t%0,%c2
5398107590Sobrien   sll\\t%0,0(%2)"
5399107590Sobrien  [(set_attr "op_type"  "RS")])
5400107590Sobrien
5401107590Sobrien;
5402107590Sobrien; ashrsi3 instruction pattern(s).
5403107590Sobrien;
5404107590Sobrien
5405107590Sobrien(define_insn "*ashrsi3_cc"
5406107590Sobrien  [(set (reg 33)
5407107590Sobrien        (compare (ashiftrt:SI (match_operand:SI 1 "register_operand" "0,0")
5408107590Sobrien                              (match_operand:SI 2 "nonmemory_operand" "J,a"))
5409107590Sobrien                 (const_int 0)))
5410107590Sobrien   (set (match_operand:SI 0 "register_operand" "=d,d")
5411107590Sobrien        (ashiftrt:SI (match_dup 1) (match_dup 2)))]
5412107590Sobrien  "s390_match_ccmode(insn, CCSmode)"
5413107590Sobrien  "@
5414107590Sobrien   sra\\t%0,%c2
5415107590Sobrien   sra\\t%0,0(%2)"
5416107590Sobrien  [(set_attr "op_type"  "RS")])
5417107590Sobrien
5418107590Sobrien(define_insn "*ashrsi3_cconly"
5419107590Sobrien  [(set (reg 33)
5420107590Sobrien        (compare (ashiftrt:SI (match_operand:SI 1 "register_operand" "0,0")
5421107590Sobrien                              (match_operand:SI 2 "nonmemory_operand" "J,a"))
5422107590Sobrien                 (const_int 0)))
5423107590Sobrien   (clobber (match_scratch:SI 0 "=d,d"))]
5424107590Sobrien  "s390_match_ccmode(insn, CCSmode)"
5425107590Sobrien  "@
5426107590Sobrien   sra\\t%0,%c2
5427107590Sobrien   sra\\t%0,0(%2)"
5428107590Sobrien  [(set_attr "op_type"  "RS")])
5429107590Sobrien
5430107590Sobrien(define_insn "ashrsi3"
5431107590Sobrien  [(set (match_operand:SI 0 "register_operand" "=d,d")
5432107590Sobrien        (ashiftrt:SI (match_operand:SI 1 "register_operand" "0,0")
5433107590Sobrien                     (match_operand:SI 2 "nonmemory_operand" "J,a")))
5434107590Sobrien   (clobber (reg:CC 33))]
5435107590Sobrien  ""
5436107590Sobrien  "@
5437107590Sobrien   sra\\t%0,%c2
5438107590Sobrien   sra\\t%0,0(%2)"
5439107590Sobrien  [(set_attr "op_type"  "RS")])
5440107590Sobrien
5441107590Sobrien
5442107590Sobrien;;
5443107590Sobrien;;- logical shift instructions.
5444107590Sobrien;;
5445107590Sobrien
5446107590Sobrien;
5447107590Sobrien; lshrdi3 instruction pattern(s).
5448107590Sobrien;
5449107590Sobrien
5450107590Sobrien(define_expand "lshrdi3"
5451107590Sobrien  [(set (match_operand:DI 0 "register_operand" "")
5452107590Sobrien        (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
5453107590Sobrien                     (match_operand:SI 2 "nonmemory_operand" "")))]
5454107590Sobrien  ""
5455107590Sobrien  "")
5456107590Sobrien
5457107590Sobrien(define_insn "*lshrdi3_31"
5458107590Sobrien  [(set (match_operand:DI 0 "register_operand" "=d,d")
5459107590Sobrien        (lshiftrt:DI (match_operand:DI 1 "register_operand" "0,0")
5460107590Sobrien                     (match_operand:SI 2 "nonmemory_operand" "J,a")))]
5461107590Sobrien  "!TARGET_64BIT"
5462107590Sobrien  "@
5463107590Sobrien   srdl\\t%0,%c2
5464107590Sobrien   srdl\\t%0,0(%2)"     
5465107590Sobrien   [(set_attr "op_type"  "RS,RS")])
5466107590Sobrien
5467107590Sobrien(define_insn "*lshrdi3_64"
5468107590Sobrien  [(set (match_operand:DI 0 "register_operand" "=d,d")
5469107590Sobrien        (lshiftrt:DI (match_operand:DI 1 "register_operand" "d,d")
5470107590Sobrien                     (match_operand:SI 2 "nonmemory_operand" "J,a")))]
5471107590Sobrien  "TARGET_64BIT"
5472107590Sobrien  "@
5473107590Sobrien   srlg\\t%0,%1,%c2
5474107590Sobrien   srlg\\t%0,%1,0(%2)"
5475107590Sobrien  [(set_attr "op_type"  "RSE,RSE")])
5476107590Sobrien
5477107590Sobrien;
5478107590Sobrien; lshrsi3 instruction pattern(s).
5479107590Sobrien;
5480107590Sobrien
5481107590Sobrien(define_insn "lshrsi3"
5482107590Sobrien  [(set (match_operand:SI 0 "register_operand" "=d,d")
5483107590Sobrien        (lshiftrt:SI (match_operand:SI 1 "register_operand" "0,0")
5484107590Sobrien                     (match_operand:SI 2 "nonmemory_operand" "J,a")))]
5485107590Sobrien  ""
5486107590Sobrien  "@
5487107590Sobrien   srl\\t%0,%c2
5488107590Sobrien   srl\\t%0,0(%2)"
5489107590Sobrien  [(set_attr "op_type"  "RS")])
5490107590Sobrien
5491107590Sobrien
5492107590Sobrien;;
5493107590Sobrien;; Branch instruction patterns.
5494107590Sobrien;;
5495107590Sobrien
5496107590Sobrien(define_expand "beq"
5497107590Sobrien  [(set (reg:CCZ 33) (compare:CCZ (match_dup 1) (match_dup 2)))
5498107590Sobrien   (set (pc)
5499107590Sobrien        (if_then_else (eq (reg:CCZ 33) (const_int 0))
5500107590Sobrien                      (label_ref (match_operand 0 "" ""))
5501107590Sobrien                      (pc)))]
5502107590Sobrien  ""
5503107590Sobrien  "{ operands[1] = s390_compare_op0; operands[2] = s390_compare_op1; }")
5504107590Sobrien
5505107590Sobrien(define_expand "bne"
5506107590Sobrien  [(set (reg:CCZ 33) (compare:CCZ (match_dup 1) (match_dup 2)))
5507107590Sobrien   (set (pc)
5508107590Sobrien        (if_then_else (ne (reg:CCZ 33) (const_int 0))
5509107590Sobrien                      (label_ref (match_operand 0 "" ""))
5510107590Sobrien                      (pc)))]
5511107590Sobrien  ""
5512107590Sobrien  "{ operands[1] = s390_compare_op0; operands[2] = s390_compare_op1; }")
5513107590Sobrien
5514107590Sobrien(define_expand "bgt"
5515107590Sobrien  [(set (reg:CCS 33) (compare:CCS (match_dup 1) (match_dup 2)))
5516107590Sobrien   (set (pc)
5517107590Sobrien        (if_then_else (gt (reg:CCS 33) (const_int 0))
5518107590Sobrien                      (label_ref (match_operand 0 "" ""))
5519107590Sobrien                      (pc)))]
5520107590Sobrien  ""
5521107590Sobrien  "{ operands[1] = s390_compare_op0; operands[2] = s390_compare_op1; }")
5522107590Sobrien
5523107590Sobrien(define_expand "bgtu"
5524107590Sobrien  [(set (reg:CCU 33) (compare:CCU (match_dup 1) (match_dup 2)))
5525107590Sobrien   (set (pc)
5526107590Sobrien        (if_then_else (gtu (reg:CCU 33) (const_int 0))
5527107590Sobrien                      (label_ref (match_operand 0 "" ""))
5528107590Sobrien                      (pc)))]
5529107590Sobrien  ""
5530107590Sobrien  "{ operands[1] = s390_compare_op0; operands[2] = s390_compare_op1; }")
5531107590Sobrien
5532107590Sobrien(define_expand "blt"
5533107590Sobrien  [(set (reg:CCS 33) (compare:CCS (match_dup 1) (match_dup 2)))
5534107590Sobrien   (set (pc)
5535107590Sobrien        (if_then_else (lt (reg:CCS 33) (const_int 0))
5536107590Sobrien                      (label_ref (match_operand 0 "" ""))
5537107590Sobrien                      (pc)))]
5538107590Sobrien  ""
5539107590Sobrien  "{ operands[1] = s390_compare_op0; operands[2] = s390_compare_op1; }")
5540107590Sobrien
5541107590Sobrien(define_expand "bltu"
5542107590Sobrien  [(set (reg:CCU 33) (compare:CCU (match_dup 1) (match_dup 2)))
5543107590Sobrien   (set (pc)
5544107590Sobrien        (if_then_else (ltu (reg:CCU 33) (const_int 0))
5545107590Sobrien                      (label_ref (match_operand 0 "" ""))
5546107590Sobrien                      (pc)))]
5547107590Sobrien  ""
5548107590Sobrien  "{ operands[1] = s390_compare_op0; operands[2] = s390_compare_op1; }")
5549107590Sobrien
5550107590Sobrien(define_expand "bge"
5551107590Sobrien  [(set (reg:CCS 33) (compare:CCS (match_dup 1) (match_dup 2)))
5552107590Sobrien   (set (pc)
5553107590Sobrien        (if_then_else (ge (reg:CCS 33) (const_int 0))
5554107590Sobrien                      (label_ref (match_operand 0 "" ""))
5555107590Sobrien                      (pc)))]
5556107590Sobrien  ""
5557107590Sobrien  "{ operands[1] = s390_compare_op0; operands[2] = s390_compare_op1; }")
5558107590Sobrien
5559107590Sobrien(define_expand "bgeu"
5560107590Sobrien  [(set (reg:CCU 33) (compare:CCU (match_dup 1) (match_dup 2)))
5561107590Sobrien   (set (pc)
5562107590Sobrien        (if_then_else (geu (reg:CCU 33) (const_int 0))
5563107590Sobrien                      (label_ref (match_operand 0 "" ""))
5564107590Sobrien                      (pc)))]
5565107590Sobrien  ""
5566107590Sobrien  "{ operands[1] = s390_compare_op0; operands[2] = s390_compare_op1; }")
5567107590Sobrien
5568107590Sobrien(define_expand "ble"
5569107590Sobrien  [(set (reg:CCS 33) (compare:CCS (match_dup 1) (match_dup 2)))
5570107590Sobrien   (set (pc)
5571107590Sobrien        (if_then_else (le (reg:CCS 33) (const_int 0))
5572107590Sobrien                      (label_ref (match_operand 0 "" ""))
5573107590Sobrien                      (pc)))]
5574107590Sobrien  ""
5575107590Sobrien  "{ operands[1] = s390_compare_op0; operands[2] = s390_compare_op1; }")
5576107590Sobrien
5577107590Sobrien(define_expand "bleu"
5578107590Sobrien  [(set (reg:CCU 33) (compare:CCU (match_dup 1) (match_dup 2)))
5579107590Sobrien   (set (pc)
5580107590Sobrien        (if_then_else (leu (reg:CCU 33) (const_int 0))
5581107590Sobrien                      (label_ref (match_operand 0 "" ""))
5582107590Sobrien                      (pc)))]
5583107590Sobrien  ""
5584107590Sobrien  "{ operands[1] = s390_compare_op0; operands[2] = s390_compare_op1; }")
5585107590Sobrien
5586107590Sobrien(define_expand "bunordered"
5587107590Sobrien  [(set (reg:CCS 33) (compare:CCS (match_dup 1) (match_dup 2)))
5588107590Sobrien   (set (pc)
5589107590Sobrien        (if_then_else (unordered (reg:CCS 33) (const_int 0))
5590107590Sobrien                      (label_ref (match_operand 0 "" ""))
5591107590Sobrien                      (pc)))]
5592107590Sobrien  ""
5593107590Sobrien  "{ operands[1] = s390_compare_op0; operands[2] = s390_compare_op1; }")
5594107590Sobrien
5595107590Sobrien(define_expand "bordered"
5596107590Sobrien  [(set (reg:CCS 33) (compare:CCS (match_dup 1) (match_dup 2)))
5597107590Sobrien   (set (pc)
5598107590Sobrien        (if_then_else (ordered (reg:CCS 33) (const_int 0))
5599107590Sobrien                      (label_ref (match_operand 0 "" ""))
5600107590Sobrien                      (pc)))]
5601107590Sobrien  ""
5602107590Sobrien  "{ operands[1] = s390_compare_op0; operands[2] = s390_compare_op1; }")
5603107590Sobrien
5604107590Sobrien(define_expand "buneq"
5605107590Sobrien  [(set (reg:CCS 33) (compare:CCS (match_dup 1) (match_dup 2)))
5606107590Sobrien   (set (pc)
5607107590Sobrien        (if_then_else (uneq (reg:CCS 33) (const_int 0))
5608107590Sobrien                      (label_ref (match_operand 0 "" ""))
5609107590Sobrien                      (pc)))]
5610107590Sobrien  ""
5611107590Sobrien  "{ operands[1] = s390_compare_op0; operands[2] = s390_compare_op1; }")
5612107590Sobrien
5613107590Sobrien(define_expand "bungt"
5614107590Sobrien  [(set (reg:CCS 33) (compare:CCS (match_dup 1) (match_dup 2)))
5615107590Sobrien   (set (pc)
5616107590Sobrien        (if_then_else (ungt (reg:CCS 33) (const_int 0))
5617107590Sobrien                      (label_ref (match_operand 0 "" ""))
5618107590Sobrien                      (pc)))]
5619107590Sobrien  ""
5620107590Sobrien  "{ operands[1] = s390_compare_op0; operands[2] = s390_compare_op1; }")
5621107590Sobrien
5622107590Sobrien(define_expand "bunlt"
5623107590Sobrien  [(set (reg:CCS 33) (compare:CCS (match_dup 1) (match_dup 2)))
5624107590Sobrien   (set (pc)
5625107590Sobrien        (if_then_else (unlt (reg:CCS 33) (const_int 0))
5626107590Sobrien                      (label_ref (match_operand 0 "" ""))
5627107590Sobrien                      (pc)))]
5628107590Sobrien  ""
5629107590Sobrien  "{ operands[1] = s390_compare_op0; operands[2] = s390_compare_op1; }")
5630107590Sobrien
5631107590Sobrien(define_expand "bunge"
5632107590Sobrien  [(set (reg:CCS 33) (compare:CCS (match_dup 1) (match_dup 2)))
5633107590Sobrien   (set (pc)
5634107590Sobrien        (if_then_else (unge (reg:CCS 33) (const_int 0))
5635107590Sobrien                      (label_ref (match_operand 0 "" ""))
5636107590Sobrien                      (pc)))]
5637107590Sobrien  ""
5638107590Sobrien  "{ operands[1] = s390_compare_op0; operands[2] = s390_compare_op1; }")
5639107590Sobrien
5640107590Sobrien(define_expand "bunle"
5641107590Sobrien  [(set (reg:CCS 33) (compare:CCS (match_dup 1) (match_dup 2)))
5642107590Sobrien   (set (pc)
5643107590Sobrien        (if_then_else (unle (reg:CCS 33) (const_int 0))
5644107590Sobrien                      (label_ref (match_operand 0 "" ""))
5645107590Sobrien                      (pc)))]
5646107590Sobrien  ""
5647107590Sobrien  "{ operands[1] = s390_compare_op0; operands[2] = s390_compare_op1; }")
5648107590Sobrien
5649107590Sobrien(define_expand "bltgt"
5650107590Sobrien  [(set (reg:CCS 33) (compare:CCS (match_dup 1) (match_dup 2)))
5651107590Sobrien   (set (pc)
5652107590Sobrien        (if_then_else (ltgt (reg:CCS 33) (const_int 0))
5653107590Sobrien                      (label_ref (match_operand 0 "" ""))
5654107590Sobrien                      (pc)))]
5655107590Sobrien  ""
5656107590Sobrien  "{ operands[1] = s390_compare_op0; operands[2] = s390_compare_op1; }")
5657107590Sobrien
5658107590Sobrien
5659107590Sobrien;;
5660107590Sobrien;;- Conditional jump instructions.
5661107590Sobrien;;
5662107590Sobrien
5663107590Sobrien(define_insn "cjump"
5664107590Sobrien [(set (pc)
5665107590Sobrien       (if_then_else 
5666107590Sobrien         (match_operator 1 "comparison_operator" [(reg 33) (const_int 0)])
5667107590Sobrien	 (label_ref (match_operand 0 "" ""))
5668107590Sobrien	 (pc)))]
5669107590Sobrien  ""
5670107590Sobrien  "*
5671107590Sobrien{
5672107590Sobrien  if (get_attr_length (insn) == 4)
5673107590Sobrien    return \"j%C1\\t%l0\";
5674107590Sobrien  else if (TARGET_64BIT)
5675107590Sobrien    return \"jg%C1\\t%l0\";
5676107590Sobrien  else
5677107590Sobrien    abort ();
5678107590Sobrien}"
5679107590Sobrien  [(set_attr "op_type" "RI")
5680107590Sobrien   (set (attr "length")
5681107590Sobrien        (cond [(lt (abs (minus (pc) (match_dup 0))) (const_int 60000))
5682107590Sobrien                (const_int 4)
5683107590Sobrien               (ne (symbol_ref "TARGET_64BIT") (const_int 0))
5684107590Sobrien                 (const_int 6)
5685107590Sobrien	       (ne (symbol_ref "s390_pool_overflow") (const_int 0))
5686107590Sobrien                 (if_then_else (eq (symbol_ref "flag_pic") (const_int 0))
5687107590Sobrien                               (const_int 12) (const_int 14))
5688107590Sobrien               (eq (symbol_ref "flag_pic") (const_int 0))
5689107590Sobrien                 (const_int 6)] (const_int 8)))])
5690107590Sobrien
5691107590Sobrien(define_insn "*cjump_long"
5692107590Sobrien [(set (pc)
5693107590Sobrien       (if_then_else
5694107590Sobrien         (match_operator 1 "comparison_operator" [(reg 33) (const_int 0)])
5695107590Sobrien	 (match_operand 0 "address_operand" "p")
5696107590Sobrien	 (pc)))]
5697107590Sobrien  ""
5698107590Sobrien  "*
5699107590Sobrien{
5700107590Sobrien  if (get_attr_op_type (insn) == OP_TYPE_RR)
5701107590Sobrien    return \"b%C1r\\t%0\";
5702107590Sobrien  else
5703107590Sobrien    return \"b%C1\\t%a0\";
5704107590Sobrien}"
5705107590Sobrien  [(set (attr "op_type") 
5706107590Sobrien        (if_then_else (match_operand 0 "register_operand" "")
5707107590Sobrien                      (const_string "RR") (const_string "RX")))
5708107590Sobrien   (set_attr "atype" "mem")])
5709107590Sobrien
5710107590Sobrien
5711107590Sobrien;;
5712107590Sobrien;;- Negated conditional jump instructions.
5713107590Sobrien;;
5714107590Sobrien
5715107590Sobrien(define_insn "icjump"
5716107590Sobrien [(set (pc)
5717107590Sobrien       (if_then_else
5718107590Sobrien         (match_operator 1 "comparison_operator" [(reg 33) (const_int 0)])
5719107590Sobrien         (pc) 
5720107590Sobrien	 (label_ref (match_operand 0 "" ""))))]
5721107590Sobrien  ""
5722107590Sobrien  "*
5723107590Sobrien{  
5724107590Sobrien  if (get_attr_length (insn) == 4)
5725107590Sobrien    return \"j%D1\\t%l0\";
5726107590Sobrien  else if (TARGET_64BIT)
5727107590Sobrien    return \"jg%D1\\t%l0\";
5728107590Sobrien  else
5729107590Sobrien    abort ();
5730107590Sobrien}"
5731107590Sobrien  [(set_attr "op_type" "RI")
5732107590Sobrien   (set (attr "length")
5733107590Sobrien        (cond [(lt (abs (minus (pc) (match_dup 0))) (const_int 60000))
5734107590Sobrien                (const_int 4)
5735107590Sobrien               (ne (symbol_ref "TARGET_64BIT") (const_int 0))
5736107590Sobrien                 (const_int 6)
5737107590Sobrien	       (ne (symbol_ref "s390_pool_overflow") (const_int 0))
5738107590Sobrien                 (if_then_else (eq (symbol_ref "flag_pic") (const_int 0))
5739107590Sobrien                               (const_int 12) (const_int 14))
5740107590Sobrien               (eq (symbol_ref "flag_pic") (const_int 0))
5741107590Sobrien                 (const_int 6)] (const_int 8)))])
5742107590Sobrien
5743107590Sobrien(define_insn "*icjump_long"
5744107590Sobrien [(set (pc)
5745107590Sobrien       (if_then_else
5746107590Sobrien         (match_operator 1 "comparison_operator" [(reg 33) (const_int 0)])
5747107590Sobrien         (pc)
5748107590Sobrien	 (match_operand 0 "address_operand" "p")))]
5749107590Sobrien  ""
5750107590Sobrien  "*
5751107590Sobrien{
5752107590Sobrien  if (get_attr_op_type (insn) == OP_TYPE_RR)
5753107590Sobrien    return \"b%D1r\\t%0\";
5754107590Sobrien  else
5755107590Sobrien    return \"b%D1\\t%a0\";
5756107590Sobrien}"
5757107590Sobrien  [(set (attr "op_type") 
5758107590Sobrien        (if_then_else (match_operand 0 "register_operand" "")
5759107590Sobrien                      (const_string "RR") (const_string "RX")))
5760107590Sobrien   (set_attr "atype" "mem")])
5761107590Sobrien
5762107590Sobrien
5763107590Sobrien;;
5764107590Sobrien;;- Subtract one and jump if not zero.
5765107590Sobrien;;
5766107590Sobrien
5767107590Sobrien;(define_expand "decrement_and_branch_on_count"
5768107590Sobrien;  [(use (match_operand 0 "register_operand" ""))
5769107590Sobrien;   (use (label_ref (match_operand 1 "" "")))]
5770107590Sobrien;  ""
5771107590Sobrien;  "
5772107590Sobrien;{
5773107590Sobrien;/*  if (TARGET_64BIT)
5774107590Sobrien;    emit_jump_insn (gen_brctdi (operands[0], operands[1]));
5775107590Sobrien;  else */
5776107590Sobrien;    emit_jump_insn (gen_brctsi (operands[0], operands[1]));
5777107590Sobrien;  DONE;
5778107590Sobrien;}")
5779107590Sobrien;
5780107590Sobrien;(define_insn "brctsi"
5781107590Sobrien;  [(set (pc)
5782107590Sobrien;        (if_then_else
5783107590Sobrien;           (ne (match_operand:SI 0 "register_operand" "+a")
5784107590Sobrien;               (const_int 1))
5785107590Sobrien;           (label_ref (match_operand 1 "" ""))
5786107590Sobrien;           (pc)))
5787107590Sobrien;   (set (match_dup 0)
5788107590Sobrien;        (plus:SI (match_dup 0) (const_int -1)))]
5789107590Sobrien;  ""
5790107590Sobrien;  "brct\\t%0,%l1"
5791107590Sobrien;   [(set_attr "op_type" "RI")
5792107590Sobrien;    (set_attr "type"    "branch")]
5793107590Sobrien;)
5794107590Sobrien;
5795107590Sobrien;(define_insn "ibrctsi"
5796107590Sobrien;  [(set (pc)
5797107590Sobrien;        (if_then_else
5798107590Sobrien;          (eq (match_operand:SI 0 "register_operand" "+a")
5799107590Sobrien;              (const_int 1))
5800107590Sobrien;          (pc)
5801107590Sobrien;          (label_ref (match_operand 1 "" ""))))
5802107590Sobrien;   (set (match_dup 0)
5803107590Sobrien;        (plus:SI (match_dup 0) (const_int -1)))]
5804107590Sobrien;  ""
5805107590Sobrien;  "brct\\t%0,%l1"
5806107590Sobrien;   [(set_attr "op_type" "RI")
5807107590Sobrien;    (set_attr "type"    "branch")]
5808107590Sobrien;)
5809107590Sobrien
5810107590Sobrien
5811107590Sobrien;;
5812107590Sobrien;;- Unconditional jump instructions.
5813107590Sobrien;;
5814107590Sobrien
5815107590Sobrien;
5816107590Sobrien; jump instruction pattern(s).
5817107590Sobrien;
5818107590Sobrien
5819107590Sobrien(define_insn "jump"
5820107590Sobrien  [(set (pc) (label_ref (match_operand 0 "" "")))]
5821107590Sobrien  ""
5822107590Sobrien  "*
5823107590Sobrien{
5824107590Sobrien  if (get_attr_length (insn) == 4)
5825107590Sobrien    return \"j\\t%l0\";
5826107590Sobrien  else if (TARGET_64BIT)
5827107590Sobrien    return \"jg\\t%l0\";
5828107590Sobrien  else
5829107590Sobrien    abort ();
5830107590Sobrien}"
5831107590Sobrien  [(set_attr "op_type" "RI")
5832107590Sobrien   (set (attr "length")
5833107590Sobrien        (cond [(lt (abs (minus (pc) (match_dup 0))) (const_int 60000))
5834107590Sobrien                (const_int 4)
5835107590Sobrien               (ne (symbol_ref "TARGET_64BIT") (const_int 0))
5836107590Sobrien                 (const_int 6)
5837107590Sobrien               (eq (symbol_ref "flag_pic") (const_int 0))
5838107590Sobrien                 (const_int 6)] (const_int 8)))])
5839107590Sobrien
5840107590Sobrien;
5841107590Sobrien; indirect-jump instruction pattern(s).
5842107590Sobrien;
5843107590Sobrien
5844107590Sobrien(define_insn "indirect_jump"
5845107590Sobrien [(set (pc) (match_operand 0 "address_operand" "p"))]
5846107590Sobrien  ""
5847107590Sobrien  "*
5848107590Sobrien{
5849107590Sobrien  if (get_attr_op_type (insn) == OP_TYPE_RR)
5850107590Sobrien    return \"br\\t%0\";
5851107590Sobrien  else
5852107590Sobrien    return \"b\\t%a0\";
5853107590Sobrien}"
5854107590Sobrien  [(set (attr "op_type") 
5855107590Sobrien        (if_then_else (match_operand 0 "register_operand" "")
5856107590Sobrien                      (const_string "RR") (const_string "RX")))
5857107590Sobrien   (set_attr "atype" "mem")])
5858107590Sobrien
5859107590Sobrien;
5860107590Sobrien; casesi instruction pattern(s).
5861107590Sobrien;
5862107590Sobrien
5863107590Sobrien(define_insn "casesi_jump"
5864107590Sobrien [(set (pc) (match_operand 0 "address_operand" "p"))
5865107590Sobrien   (use (label_ref (match_operand 1 "" "")))]
5866107590Sobrien  ""
5867107590Sobrien  "*
5868107590Sobrien{
5869107590Sobrien  if (get_attr_op_type (insn) == OP_TYPE_RR)
5870107590Sobrien    return \"br\\t%0\";
5871107590Sobrien  else
5872107590Sobrien    return \"b\\t%a0\";
5873107590Sobrien}"
5874107590Sobrien  [(set (attr "op_type") 
5875107590Sobrien        (if_then_else (match_operand 0 "register_operand" "")
5876107590Sobrien                      (const_string "RR") (const_string "RX")))
5877107590Sobrien   (set_attr "atype" "mem")])
5878107590Sobrien
5879107590Sobrien(define_expand "casesi"
5880107590Sobrien  [(match_operand:SI 0 "general_operand" "")
5881107590Sobrien   (match_operand:SI 1 "general_operand" "")
5882107590Sobrien   (match_operand:SI 2 "general_operand" "")
5883107590Sobrien   (label_ref (match_operand 3 "" ""))
5884107590Sobrien   (label_ref (match_operand 4 "" ""))]
5885107590Sobrien  ""
5886107590Sobrien  "
5887107590Sobrien{
5888107590Sobrien   rtx index  = gen_reg_rtx (SImode);
5889107590Sobrien   rtx base   = gen_reg_rtx (Pmode);
5890107590Sobrien   rtx target = gen_reg_rtx (Pmode);
5891107590Sobrien
5892107590Sobrien   emit_move_insn (index, operands[0]);
5893107590Sobrien   emit_insn (gen_subsi3 (index, index, operands[1]));
5894107590Sobrien   emit_cmp_and_jump_insns (index, operands[2], GTU, NULL_RTX, SImode, 1,
5895107590Sobrien                            operands[4]);
5896107590Sobrien
5897107590Sobrien   if (Pmode != SImode)
5898107590Sobrien     index = convert_to_mode (Pmode, index, 1);
5899107590Sobrien   if (GET_CODE (index) != REG)
5900107590Sobrien     index = copy_to_mode_reg (Pmode, index);
5901107590Sobrien
5902107590Sobrien   if (TARGET_64BIT)
5903107590Sobrien       emit_insn (gen_ashldi3 (index, index, GEN_INT (3)));
5904107590Sobrien   else
5905107590Sobrien       emit_insn (gen_ashlsi3 (index, index, GEN_INT (2)));
5906107590Sobrien
5907107590Sobrien   emit_move_insn (base, gen_rtx_LABEL_REF (Pmode, operands[3]));
5908107590Sobrien
5909107590Sobrien   index = gen_rtx_MEM (Pmode, gen_rtx_PLUS (Pmode, base, index));
5910107590Sobrien   emit_move_insn (target, index);
5911107590Sobrien
5912107590Sobrien   if (flag_pic)
5913107590Sobrien     target = gen_rtx_PLUS (Pmode, base, target);
5914107590Sobrien   emit_jump_insn (gen_casesi_jump (target, operands[3]));
5915107590Sobrien
5916107590Sobrien   DONE;
5917107590Sobrien}")
5918107590Sobrien
5919107590Sobrien
5920107590Sobrien;;
5921107590Sobrien;;- Jump to subroutine.
5922107590Sobrien;;
5923107590Sobrien;;
5924107590Sobrien
5925107590Sobrien;
5926107590Sobrien; untyped call instruction pattern(s).
5927107590Sobrien;
5928107590Sobrien
5929107590Sobrien;; Call subroutine returning any type.
5930107590Sobrien(define_expand "untyped_call"
5931107590Sobrien  [(parallel [(call (match_operand 0 "" "")
5932107590Sobrien                    (const_int 0))
5933107590Sobrien              (match_operand 1 "" "")
5934107590Sobrien              (match_operand 2 "" "")])]
5935107590Sobrien  ""
5936107590Sobrien  "
5937107590Sobrien{
5938107590Sobrien  int i;
5939107590Sobrien
5940107590Sobrien  emit_call_insn (gen_call (operands[0], const0_rtx, const0_rtx));
5941107590Sobrien
5942107590Sobrien  for (i = 0; i < XVECLEN (operands[2], 0); i++)
5943107590Sobrien    {
5944107590Sobrien      rtx set = XVECEXP (operands[2], 0, i);
5945107590Sobrien      emit_move_insn (SET_DEST (set), SET_SRC (set));
5946107590Sobrien    }
5947107590Sobrien
5948107590Sobrien  /* The optimizer does not know that the call sets the function value
5949107590Sobrien     registers we stored in the result block.  We avoid problems by
5950107590Sobrien     claiming that all hard registers are used and clobbered at this
5951107590Sobrien     point.  */
5952107590Sobrien  emit_insn (gen_blockage ());
5953107590Sobrien
5954107590Sobrien  DONE;
5955107590Sobrien}")
5956107590Sobrien
5957107590Sobrien;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
5958107590Sobrien;; all of memory.  This blocks insns from being moved across this point.
5959107590Sobrien
5960107590Sobrien(define_insn "blockage"
5961107590Sobrien  [(unspec_volatile [(const_int 0)] 0)]
5962107590Sobrien  ""
5963107590Sobrien  ""
5964107590Sobrien  [(set_attr "type"    "none")])
5965107590Sobrien
5966107590Sobrien
5967107590Sobrien
5968107590Sobrien;
5969107590Sobrien; call instruction pattern(s).
5970107590Sobrien;
5971107590Sobrien
5972107590Sobrien(define_expand "call"
5973107590Sobrien  [(call (match_operand 0 "" "")
5974107590Sobrien         (match_operand 1 "" ""))
5975107590Sobrien   (use (match_operand 2 "" ""))]
5976107590Sobrien  ""
5977107590Sobrien  "
5978107590Sobrien{
5979107590Sobrien  int plt_call = 0;
5980107590Sobrien  rtx insn;
5981107590Sobrien
5982107590Sobrien  /* Direct function calls need special treatment.  */
5983107590Sobrien  if (GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF)
5984107590Sobrien    {
5985107590Sobrien      rtx sym = XEXP (operands[0], 0);
5986107590Sobrien
5987107590Sobrien      /* When calling a global routine in PIC mode, we must
5988107590Sobrien         replace the symbol itself with the PLT stub.  */
5989107590Sobrien      if (flag_pic && !SYMBOL_REF_FLAG (sym))
5990107590Sobrien        {
5991107590Sobrien          sym = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, sym), 113);
5992107590Sobrien          sym = gen_rtx_CONST (Pmode, sym);
5993107590Sobrien
5994107590Sobrien	  plt_call = 1;
5995107590Sobrien        }
5996107590Sobrien
5997107590Sobrien      /* Unless we can use the bras(l) insn, force the 
5998107590Sobrien         routine address into a register.  */
5999107590Sobrien      if (!TARGET_SMALL_EXEC && !TARGET_64BIT)
6000107590Sobrien        {
6001107590Sobrien          rtx target = gen_reg_rtx (Pmode);
6002107590Sobrien          emit_move_insn (target, sym);
6003107590Sobrien          sym = target;
6004107590Sobrien        }
6005107590Sobrien
6006107590Sobrien      operands[0] = gen_rtx_MEM (QImode, sym);
6007107590Sobrien    }
6008107590Sobrien
6009107590Sobrien  /* Emit insn.  */
6010107590Sobrien  insn = emit_call_insn (gen_call_exp (operands[0], operands[1],
6011107590Sobrien  				       gen_rtx_REG (Pmode, RETURN_REGNUM)));
6012107590Sobrien
6013107590Sobrien  /* In 31-bit, we must load the GOT register even if the 
6014107590Sobrien     compiler doesn't know about it, because the PLT glue 
6015107590Sobrien     code uses it.  In 64-bit, this is not necessary.  */
6016107590Sobrien  if (plt_call && !TARGET_64BIT)
6017107590Sobrien    {
6018107590Sobrien      current_function_uses_pic_offset_table = 1;
6019107590Sobrien      use_reg (&CALL_INSN_FUNCTION_USAGE (insn), pic_offset_table_rtx);
6020107590Sobrien    }
6021107590Sobrien
6022107590Sobrien  DONE;
6023107590Sobrien}")
6024107590Sobrien
6025107590Sobrien(define_expand "call_exp"
6026107590Sobrien  [(parallel [(call (match_operand 0 "" "")
6027107590Sobrien                    (match_operand 1 "" ""))
6028107590Sobrien              (clobber (match_operand 2 "" ""))])]
6029107590Sobrien  ""
6030107590Sobrien  "")
6031107590Sobrien
6032107590Sobrien(define_insn "brasl"
6033107590Sobrien  [(call (mem:QI (match_operand:DI 0 "bras_sym_operand" "X"))
6034107590Sobrien         (match_operand:SI 1 "const_int_operand" "n"))
6035107590Sobrien   (clobber (match_operand:DI 2 "register_operand" "=r"))]
6036107590Sobrien  "TARGET_64BIT"
6037107590Sobrien  "brasl\\t%2,%0"
6038107590Sobrien  [(set_attr "op_type" "RIL")
6039107590Sobrien   (set_attr "type"    "jsr")])
6040107590Sobrien
6041107590Sobrien(define_insn "bras"
6042107590Sobrien  [(call (mem:QI (match_operand:SI 0 "bras_sym_operand" "X"))
6043107590Sobrien         (match_operand:SI 1 "const_int_operand" "n"))
6044107590Sobrien   (clobber (match_operand:SI 2 "register_operand" "=r"))]
6045107590Sobrien  "TARGET_SMALL_EXEC"
6046107590Sobrien  "bras\\t%2,%0"
6047107590Sobrien  [(set_attr "op_type" "RI")
6048107590Sobrien   (set_attr "type"    "jsr")])
6049107590Sobrien
6050107590Sobrien(define_insn "basr_64"
6051107590Sobrien  [(call (mem:QI (match_operand:DI 0 "register_operand" "a"))
6052107590Sobrien         (match_operand:SI 1 "const_int_operand" "n"))
6053107590Sobrien   (clobber (match_operand:DI 2 "register_operand" "=r"))]
6054107590Sobrien  "TARGET_64BIT"
6055107590Sobrien  "basr\\t%2,%0"
6056107590Sobrien  [(set_attr "op_type" "RR")
6057107590Sobrien   (set_attr "type"    "jsr")
6058107590Sobrien   (set_attr "atype"   "mem")])
6059107590Sobrien
6060107590Sobrien(define_insn "basr_31"
6061107590Sobrien  [(call (mem:QI (match_operand:SI 0 "register_operand" "a"))
6062107590Sobrien         (match_operand:SI 1 "const_int_operand" "n"))
6063107590Sobrien   (clobber (match_operand:SI 2 "register_operand" "=r"))]
6064107590Sobrien  "!TARGET_64BIT"
6065107590Sobrien  "basr\\t%2,%0"
6066107590Sobrien  [(set_attr "op_type" "RR")
6067107590Sobrien   (set_attr "type"    "jsr")
6068107590Sobrien   (set_attr "atype"    "mem")])
6069107590Sobrien
6070107590Sobrien(define_insn "bas_64"
6071107590Sobrien  [(call (mem:QI (match_operand:QI 0 "address_operand" "p"))
6072107590Sobrien         (match_operand:SI 1 "const_int_operand" "n"))
6073107590Sobrien   (clobber (match_operand:DI 2 "register_operand" "=r"))]
6074107590Sobrien  "TARGET_64BIT"
6075107590Sobrien  "bas\\t%2,%a0"
6076107590Sobrien  [(set_attr "op_type" "RX")
6077107590Sobrien   (set_attr "type"    "jsr")
6078107590Sobrien   (set_attr "atype"   "mem")])
6079107590Sobrien
6080107590Sobrien(define_insn "bas_31"
6081107590Sobrien  [(call (mem:QI (match_operand:QI 0 "address_operand" "p"))
6082107590Sobrien         (match_operand:SI 1 "const_int_operand" "n"))
6083107590Sobrien   (clobber (match_operand:SI 2 "register_operand" "=r"))]
6084107590Sobrien  "!TARGET_64BIT"
6085107590Sobrien  "bas\\t%2,%a0"
6086107590Sobrien  [(set_attr "op_type" "RX")
6087107590Sobrien   (set_attr "type"    "jsr")
6088107590Sobrien   (set_attr "atype"   "mem")])
6089107590Sobrien
6090107590Sobrien
6091107590Sobrien;
6092107590Sobrien; call_value instruction pattern(s).
6093107590Sobrien;
6094107590Sobrien
6095107590Sobrien(define_expand "call_value"
6096107590Sobrien  [(set (match_operand 0 "" "")
6097107590Sobrien        (call (match_operand 1 "" "")
6098107590Sobrien              (match_operand 2 "" "")))
6099107590Sobrien   (use (match_operand 3 "" ""))]
6100107590Sobrien  ""
6101107590Sobrien  "
6102107590Sobrien{
6103107590Sobrien  int plt_call = 0;
6104107590Sobrien  rtx insn;
6105107590Sobrien
6106107590Sobrien  /* Direct function calls need special treatment.  */
6107107590Sobrien  if (GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF)
6108107590Sobrien    {
6109107590Sobrien      rtx sym = XEXP (operands[1], 0);
6110107590Sobrien
6111107590Sobrien      /* When calling a global routine in PIC mode, we must
6112107590Sobrien         replace the symbol itself with the PLT stub.  */
6113107590Sobrien      if (flag_pic && !SYMBOL_REF_FLAG (sym))
6114107590Sobrien        {
6115107590Sobrien          sym = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, sym), 113);
6116107590Sobrien          sym = gen_rtx_CONST (Pmode, sym);
6117107590Sobrien
6118107590Sobrien	  plt_call = 1;
6119107590Sobrien        }
6120107590Sobrien
6121107590Sobrien      /* Unless we can use the bras(l) insn, force the 
6122107590Sobrien         routine address into a register.  */
6123107590Sobrien      if (!TARGET_SMALL_EXEC && !TARGET_64BIT)
6124107590Sobrien        {
6125107590Sobrien          rtx target = gen_reg_rtx (Pmode);
6126107590Sobrien          emit_move_insn (target, sym);
6127107590Sobrien          sym = target;
6128107590Sobrien        }
6129107590Sobrien
6130107590Sobrien      operands[1] = gen_rtx_MEM (QImode, sym);
6131107590Sobrien    }
6132107590Sobrien
6133107590Sobrien  /* Emit insn.  */
6134107590Sobrien  insn = emit_call_insn (
6135107590Sobrien	    gen_call_value_exp (operands[0], operands[1], operands[2],
6136107590Sobrien  				gen_rtx_REG (Pmode, RETURN_REGNUM)));
6137107590Sobrien
6138107590Sobrien  /* In 31-bit, we must load the GOT register even if the 
6139107590Sobrien     compiler doesn't know about it, because the PLT glue 
6140107590Sobrien     code uses it.  In 64-bit, this is not necessary.  */
6141107590Sobrien  if (plt_call && !TARGET_64BIT)
6142107590Sobrien    {
6143107590Sobrien      current_function_uses_pic_offset_table = 1;
6144107590Sobrien      use_reg (&CALL_INSN_FUNCTION_USAGE (insn), pic_offset_table_rtx);
6145107590Sobrien    }
6146107590Sobrien
6147107590Sobrien  DONE;
6148107590Sobrien}")
6149107590Sobrien
6150107590Sobrien(define_expand "call_value_exp"
6151107590Sobrien  [(parallel [(set (match_operand 0 "" "")
6152107590Sobrien                   (call (match_operand 1 "" "")
6153107590Sobrien                         (match_operand 2 "" "")))
6154107590Sobrien              (clobber (match_operand 3 "" ""))])]
6155107590Sobrien  ""
6156107590Sobrien  "")
6157107590Sobrien
6158107590Sobrien(define_insn "brasl_r"
6159107590Sobrien  [(set (match_operand 0 "register_operand" "=df")
6160107590Sobrien        (call (mem:QI (match_operand:DI 1 "bras_sym_operand" "X"))
6161107590Sobrien              (match_operand:SI 2 "const_int_operand" "n")))
6162107590Sobrien   (clobber (match_operand:DI 3 "register_operand" "=r"))]
6163107590Sobrien  "TARGET_64BIT"
6164107590Sobrien  "brasl\\t%3,%1"
6165107590Sobrien  [(set_attr "op_type" "RIL")
6166107590Sobrien   (set_attr "type"    "jsr")])
6167107590Sobrien
6168107590Sobrien(define_insn "bras_r"
6169107590Sobrien  [(set (match_operand 0 "register_operand" "=df")
6170107590Sobrien        (call (mem:QI (match_operand:SI 1 "bras_sym_operand" "X"))
6171107590Sobrien              (match_operand:SI 2 "const_int_operand" "n")))
6172107590Sobrien   (clobber (match_operand:SI 3 "register_operand" "=r"))]
6173107590Sobrien  "TARGET_SMALL_EXEC"
6174107590Sobrien  "bras\\t%3,%1"
6175107590Sobrien  [(set_attr "op_type" "RI")
6176107590Sobrien   (set_attr "type"    "jsr")])
6177107590Sobrien
6178107590Sobrien(define_insn "basr_r_64"
6179107590Sobrien  [(set (match_operand 0 "register_operand" "=df")
6180107590Sobrien        (call (mem:QI (match_operand:DI 1 "register_operand" "a"))
6181107590Sobrien              (match_operand:SI 2 "const_int_operand" "n")))
6182107590Sobrien   (clobber (match_operand:DI 3 "register_operand" "=r"))]
6183107590Sobrien  "TARGET_64BIT"
6184107590Sobrien  "basr\\t%3,%1"
6185107590Sobrien  [(set_attr "op_type" "RR")
6186107590Sobrien   (set_attr "type"    "jsr")])
6187107590Sobrien
6188107590Sobrien(define_insn "basr_r_31"
6189107590Sobrien  [(set (match_operand 0 "register_operand" "=df")
6190107590Sobrien        (call (mem:QI (match_operand:SI 1 "register_operand" "a"))
6191107590Sobrien              (match_operand:SI 2 "const_int_operand" "n")))
6192107590Sobrien   (clobber (match_operand:SI 3 "register_operand" "=r"))]
6193107590Sobrien  "!TARGET_64BIT"
6194107590Sobrien  "basr\\t%3,%1"
6195107590Sobrien  [(set_attr "op_type" "RR")
6196107590Sobrien   (set_attr "type"    "jsr")
6197107590Sobrien   (set_attr "atype"   "mem")])
6198107590Sobrien
6199107590Sobrien(define_insn "bas_r_64"
6200107590Sobrien  [(set (match_operand 0 "register_operand" "=df")
6201107590Sobrien        (call (mem:QI (match_operand:QI 1 "address_operand" "p"))
6202107590Sobrien              (match_operand:SI 2 "const_int_operand" "n")))
6203107590Sobrien   (clobber (match_operand:DI 3 "register_operand" "=r"))]
6204107590Sobrien  "TARGET_64BIT"
6205107590Sobrien  "bas\\t%3,%a1"
6206107590Sobrien  [(set_attr "op_type" "RX")
6207107590Sobrien   (set_attr "type"    "jsr")
6208107590Sobrien   (set_attr "atype"   "mem")])
6209107590Sobrien
6210107590Sobrien(define_insn "bas_r_31"
6211107590Sobrien  [(set (match_operand 0 "register_operand" "=df")
6212107590Sobrien        (call (mem:QI (match_operand:QI 1 "address_operand" "p"))
6213107590Sobrien              (match_operand:SI 2 "const_int_operand" "n")))
6214107590Sobrien   (clobber (match_operand:SI 3 "register_operand" "=r"))]
6215107590Sobrien  "!TARGET_64BIT"
6216107590Sobrien  "bas\\t%3,%a1"
6217107590Sobrien   [(set_attr "op_type" "RX")
6218107590Sobrien    (set_attr "type"    "jsr")
6219107590Sobrien    (set_attr "atype"   "mem")])
6220107590Sobrien
6221107590Sobrien
6222107590Sobrien;;
6223107590Sobrien;;- Miscellaneous instructions.
6224107590Sobrien;;
6225107590Sobrien
6226107590Sobrien;
6227107590Sobrien; allocate stack instruction pattern(s).
6228107590Sobrien;
6229107590Sobrien
6230107590Sobrien(define_expand "allocate_stack"
6231107590Sobrien  [(set (reg 15)
6232107590Sobrien        (plus (reg 15) (match_operand 1 "general_operand" "")))
6233107590Sobrien   (set (match_operand 0 "general_operand" "")
6234107590Sobrien        (reg 15))]
6235107590Sobrien ""
6236107590Sobrien "
6237107590Sobrien{
6238107590Sobrien    rtx stack = gen_rtx (REG, Pmode, STACK_POINTER_REGNUM);
6239107590Sobrien    rtx chain = gen_rtx (MEM, Pmode, stack);
6240107590Sobrien    rtx temp = gen_reg_rtx (Pmode);
6241107590Sobrien	
6242107590Sobrien    emit_move_insn (temp, chain);
6243107590Sobrien
6244107590Sobrien    if (TARGET_64BIT)
6245107590Sobrien      emit_insn (gen_adddi3 (stack, stack, negate_rtx (Pmode, operands[1])));
6246107590Sobrien    else
6247107590Sobrien      emit_insn (gen_addsi3 (stack, stack, negate_rtx (Pmode, operands[1])));
6248107590Sobrien
6249107590Sobrien    emit_move_insn (chain, temp);
6250107590Sobrien
6251107590Sobrien    emit_move_insn (operands[0], virtual_stack_dynamic_rtx);	
6252107590Sobrien    DONE;
6253107590Sobrien}")
6254107590Sobrien
6255107590Sobrien
6256107590Sobrien;
6257107590Sobrien; setjmp/longjmp instruction pattern(s).
6258107590Sobrien;
6259107590Sobrien
6260107590Sobrien(define_expand "builtin_setjmp_setup"
6261107590Sobrien  [(unspec [(match_operand 0 "register_operand" "a")] 1)]
6262107590Sobrien  ""
6263107590Sobrien  "
6264107590Sobrien{
6265107590Sobrien  rtx base = gen_rtx_MEM (Pmode, plus_constant (operands[0], 4 * GET_MODE_SIZE (Pmode)));
6266107590Sobrien  rtx basereg = gen_rtx_REG (Pmode, BASE_REGISTER);
6267107590Sobrien
6268107590Sobrien  emit_move_insn (base, basereg);
6269107590Sobrien  DONE;
6270107590Sobrien}")
6271107590Sobrien
6272107590Sobrien(define_expand "builtin_setjmp_receiver"
6273107590Sobrien  [(unspec_volatile [(label_ref (match_operand 0 "" ""))] 2)]
6274107590Sobrien  "flag_pic"
6275107590Sobrien  "
6276107590Sobrien{
6277107590Sobrien  rtx gotreg = gen_rtx_REG (Pmode, PIC_OFFSET_TABLE_REGNUM);
6278107590Sobrien  rtx got = gen_rtx_SYMBOL_REF (Pmode, \"_GLOBAL_OFFSET_TABLE_\");
6279107590Sobrien  SYMBOL_REF_FLAG (got) = 1;
6280107590Sobrien
6281107590Sobrien  emit_move_insn (gotreg, got);
6282107590Sobrien  emit_insn (gen_rtx_USE (VOIDmode, gotreg));
6283107590Sobrien  DONE;
6284107590Sobrien}")
6285107590Sobrien
6286107590Sobrien(define_expand "builtin_longjmp"
6287107590Sobrien  [(unspec_volatile [(match_operand 0 "register_operand" "r")] 3)]
6288107590Sobrien  ""
6289107590Sobrien  "
6290107590Sobrien{
6291107590Sobrien  /* The elements of the buffer are, in order:  */
6292107590Sobrien  rtx fp = gen_rtx_MEM (Pmode, operands[0]);
6293107590Sobrien  rtx lab = gen_rtx_MEM (Pmode, plus_constant (operands[0], GET_MODE_SIZE (Pmode)));
6294107590Sobrien  rtx stack = gen_rtx_MEM (Pmode, plus_constant (operands[0], 2 * GET_MODE_SIZE (Pmode)));
6295107590Sobrien  rtx base = gen_rtx_MEM (Pmode, plus_constant (operands[0], 4 * GET_MODE_SIZE (Pmode)));
6296107590Sobrien  rtx basereg = gen_rtx_REG (Pmode, BASE_REGISTER);
6297107590Sobrien  rtx jmp = gen_rtx_REG (Pmode, 14);
6298107590Sobrien
6299107590Sobrien  emit_move_insn (jmp, lab);
6300107590Sobrien  emit_move_insn (basereg, base);
6301107590Sobrien  emit_stack_restore (SAVE_NONLOCAL, stack, NULL_RTX);
6302107590Sobrien  emit_move_insn (hard_frame_pointer_rtx, fp);
6303107590Sobrien
6304107590Sobrien  emit_insn (gen_rtx_USE (VOIDmode, hard_frame_pointer_rtx));
6305107590Sobrien  emit_insn (gen_rtx_USE (VOIDmode, stack_pointer_rtx));
6306107590Sobrien  emit_insn (gen_rtx_USE (VOIDmode, basereg));
6307107590Sobrien  emit_indirect_jump (jmp);
6308107590Sobrien  DONE;
6309107590Sobrien}")
6310107590Sobrien
6311107590Sobrien
6312107590Sobrien;; These patterns say how to save and restore the stack pointer.  We need not
6313107590Sobrien;; save the stack pointer at function level since we are careful to
6314107590Sobrien;; preserve the backchain.  At block level, we have to restore the backchain
6315107590Sobrien;; when we restore the stack pointer.
6316107590Sobrien;;
6317107590Sobrien;; For nonlocal gotos, we must save both the stack pointer and its
6318107590Sobrien;; backchain and restore both.  Note that in the nonlocal case, the
6319107590Sobrien;; save area is a memory location.
6320107590Sobrien
6321107590Sobrien(define_expand "save_stack_function"
6322107590Sobrien  [(match_operand 0 "general_operand" "")
6323107590Sobrien   (match_operand 1 "general_operand" "")]
6324107590Sobrien  ""
6325107590Sobrien  "DONE;")
6326107590Sobrien
6327107590Sobrien(define_expand "restore_stack_function"
6328107590Sobrien  [(match_operand 0 "general_operand" "")
6329107590Sobrien   (match_operand 1 "general_operand" "")]
6330107590Sobrien  ""
6331107590Sobrien  "DONE;")
6332107590Sobrien
6333107590Sobrien(define_expand "restore_stack_block"
6334107590Sobrien  [(use (match_operand 0 "register_operand" ""))
6335107590Sobrien   (set (match_dup 2) (match_dup 3))
6336107590Sobrien   (set (match_dup 0) (match_operand 1 "register_operand" ""))
6337107590Sobrien   (set (match_dup 3) (match_dup 2))]
6338107590Sobrien  ""
6339107590Sobrien  "
6340107590Sobrien{
6341107590Sobrien  operands[2] = gen_reg_rtx (Pmode);
6342107590Sobrien  operands[3] = gen_rtx_MEM (Pmode, operands[0]);
6343107590Sobrien}")
6344107590Sobrien
6345107590Sobrien(define_expand "save_stack_nonlocal"
6346107590Sobrien  [(match_operand 0 "memory_operand" "")
6347107590Sobrien   (match_operand 1 "register_operand" "")]
6348107590Sobrien  ""
6349107590Sobrien  "
6350107590Sobrien{
6351107590Sobrien  rtx temp = gen_reg_rtx (Pmode);
6352107590Sobrien
6353107590Sobrien  /* Copy the backchain to the first word, sp to the second.  */
6354107590Sobrien  emit_move_insn (temp, gen_rtx_MEM (Pmode, operands[1]));
6355107590Sobrien  emit_move_insn (operand_subword (operands[0], 0, 0,
6356107590Sobrien                 TARGET_64BIT ? TImode : DImode),
6357107590Sobrien                 temp);
6358107590Sobrien  emit_move_insn (operand_subword (operands[0], 1, 0,
6359107590Sobrien                 TARGET_64BIT ? TImode : DImode),
6360107590Sobrien                 operands[1]);
6361107590Sobrien  DONE;
6362107590Sobrien}")
6363107590Sobrien
6364107590Sobrien(define_expand "restore_stack_nonlocal"
6365107590Sobrien  [(match_operand 0 "register_operand" "")
6366107590Sobrien   (match_operand 1 "memory_operand" "")]
6367107590Sobrien  ""
6368107590Sobrien  "
6369107590Sobrien{
6370107590Sobrien  rtx temp = gen_reg_rtx (Pmode);
6371107590Sobrien
6372107590Sobrien  /* Restore the backchain from the first word, sp from the second.  */
6373107590Sobrien  emit_move_insn (temp,
6374107590Sobrien                 operand_subword (operands[1], 0, 0,
6375107590Sobrien                 TARGET_64BIT ? TImode : DImode));
6376107590Sobrien  emit_move_insn (operands[0],
6377107590Sobrien                 operand_subword (operands[1], 1, 0,
6378107590Sobrien                 TARGET_64BIT ? TImode : DImode));
6379107590Sobrien  emit_move_insn (gen_rtx_MEM (Pmode, operands[0]), temp);
6380107590Sobrien  DONE;
6381107590Sobrien}")
6382107590Sobrien
6383107590Sobrien
6384107590Sobrien;
6385107590Sobrien; nop instruction pattern(s).
6386107590Sobrien;
6387107590Sobrien
6388107590Sobrien(define_insn "nop"
6389107590Sobrien  [(const_int 0)]
6390107590Sobrien  ""
6391107590Sobrien  "lr\\t0,0"
6392107590Sobrien  [(set_attr "op_type" "RR")])
6393107590Sobrien
6394107590Sobrien
6395107590Sobrien;
6396107590Sobrien; Special literal pool access instruction pattern(s).
6397107590Sobrien;
6398107590Sobrien
6399107590Sobrien(define_insn "consttable_qi"
6400107590Sobrien  [(unspec_volatile [(match_operand:QI 0 "consttable_operand" "X")] 200)]
6401107590Sobrien  ""
6402107590Sobrien  "*
6403107590Sobrien{
6404107590Sobrien  assemble_integer (operands[0], 1, BITS_PER_UNIT, 1);
6405107590Sobrien  return \"\";
6406107590Sobrien}"
6407107590Sobrien  [(set_attr "op_type"  "NN")
6408107590Sobrien   (set_attr "length"   "1")])
6409107590Sobrien
6410107590Sobrien(define_insn "consttable_hi"
6411107590Sobrien  [(unspec_volatile [(match_operand:HI 0 "consttable_operand" "X")] 201)]
6412107590Sobrien  ""
6413107590Sobrien  "*
6414107590Sobrien{
6415107590Sobrien  assemble_integer (operands[0], 2, 2*BITS_PER_UNIT, 1);
6416107590Sobrien  return \"\";
6417107590Sobrien}"
6418107590Sobrien  [(set_attr "op_type"  "NN")
6419107590Sobrien   (set_attr "length"   "2")])
6420107590Sobrien
6421107590Sobrien(define_insn "consttable_si"
6422107590Sobrien  [(unspec_volatile [(match_operand:SI 0 "consttable_operand" "X")] 202)]
6423107590Sobrien  ""
6424107590Sobrien  "*
6425107590Sobrien{
6426107590Sobrien  if (!TARGET_64BIT && flag_pic && SYMBOLIC_CONST (operands[0]))
6427107590Sobrien    return \".long\\t%0\";
6428107590Sobrien
6429107590Sobrien  assemble_integer (operands[0], 4, 4*BITS_PER_UNIT, 1);
6430107590Sobrien  return \"\";
6431107590Sobrien}"
6432107590Sobrien  [(set_attr "op_type"  "NN")
6433107590Sobrien   (set_attr "length"   "4")])
6434107590Sobrien
6435107590Sobrien(define_insn "consttable_di"
6436107590Sobrien  [(unspec_volatile [(match_operand:DI 0 "consttable_operand" "X")] 203)]
6437107590Sobrien  ""
6438107590Sobrien  "*
6439107590Sobrien{
6440107590Sobrien  assemble_integer (operands[0], 8, 8*BITS_PER_UNIT, 1);
6441107590Sobrien  return \"\";
6442107590Sobrien}"
6443107590Sobrien  [(set_attr "op_type"  "NN")
6444107590Sobrien   (set_attr "length"   "8")])
6445107590Sobrien
6446107590Sobrien(define_insn "consttable_sf"
6447107590Sobrien  [(unspec_volatile [(match_operand:SF 0 "consttable_operand" "X")] 204)]
6448107590Sobrien  ""
6449107590Sobrien  "*
6450107590Sobrien{
6451107590Sobrien  REAL_VALUE_TYPE r;
6452107590Sobrien
6453107590Sobrien  if (GET_CODE (operands[0]) != CONST_DOUBLE)
6454107590Sobrien    abort ();
6455107590Sobrien
6456107590Sobrien  REAL_VALUE_FROM_CONST_DOUBLE (r, operands[0]);
6457107590Sobrien  assemble_real (r, SFmode, 4*BITS_PER_UNIT);
6458107590Sobrien  return \"\";
6459107590Sobrien}"
6460107590Sobrien  [(set_attr "op_type"  "NN")
6461107590Sobrien   (set_attr "length"   "4")])
6462107590Sobrien
6463107590Sobrien(define_insn "consttable_df"
6464107590Sobrien  [(unspec_volatile [(match_operand:DF 0 "consttable_operand" "X")] 205)]
6465107590Sobrien  ""
6466107590Sobrien  "*
6467107590Sobrien{
6468107590Sobrien  REAL_VALUE_TYPE r;
6469107590Sobrien
6470107590Sobrien  if (GET_CODE (operands[0]) != CONST_DOUBLE)
6471107590Sobrien    abort ();
6472107590Sobrien
6473107590Sobrien  REAL_VALUE_FROM_CONST_DOUBLE (r, operands[0]);
6474107590Sobrien  assemble_real (r, DFmode, 8*BITS_PER_UNIT);
6475107590Sobrien  return \"\";
6476107590Sobrien}"
6477107590Sobrien  [(set_attr "op_type"  "NN")
6478107590Sobrien   (set_attr "length"   "8")])
6479107590Sobrien
6480107590Sobrien(define_insn "pool_start_31"
6481107590Sobrien  [(unspec_volatile [(const_int 0)] 206)]
6482107590Sobrien  "!TARGET_64BIT"
6483107590Sobrien  ".align\\t4"
6484107590Sobrien  [(set_attr "op_type"  "NN")
6485107590Sobrien   (set_attr "length"   "2")])
6486107590Sobrien
6487107590Sobrien(define_insn "pool_end_31"
6488107590Sobrien  [(unspec_volatile [(const_int 0)] 207)]
6489107590Sobrien  "!TARGET_64BIT"
6490107590Sobrien  ".align\\t2"
6491107590Sobrien  [(set_attr "op_type"  "NN")
6492107590Sobrien   (set_attr "length"   "2")])
6493107590Sobrien
6494107590Sobrien(define_insn "pool_start_64"
6495107590Sobrien  [(unspec_volatile [(const_int 0)] 206)]
6496107590Sobrien  "TARGET_64BIT"
6497107590Sobrien  ".section\\t.rodata\;.align\\t8"
6498107590Sobrien  [(set_attr "op_type"  "NN")
6499107590Sobrien   (set_attr "length"   "0")])
6500107590Sobrien
6501107590Sobrien(define_insn "pool_end_64"
6502107590Sobrien  [(unspec_volatile [(const_int 0)] 207)]
6503107590Sobrien  "TARGET_64BIT"
6504107590Sobrien  ".previous"
6505107590Sobrien  [(set_attr "op_type"  "NN")
6506107590Sobrien   (set_attr "length"   "0")])
6507107590Sobrien
6508107590Sobrien(define_insn "reload_base"
6509107590Sobrien  [(set (match_operand:SI 0 "register_operand" "=a")
6510107590Sobrien        (unspec:SI [(label_ref (match_operand 1 "" ""))] 210))]
6511107590Sobrien  "!TARGET_64BIT"
6512107590Sobrien  "basr\\t%0,0\;la\\t%0,%1-.(%0)"
6513107590Sobrien  [(set_attr "op_type" "NN")
6514107590Sobrien   (set_attr "type"    "la")
6515107590Sobrien   (set_attr "length"  "6")])
6516107590Sobrien
6517107590Sobrien(define_insn "reload_base2"
6518107590Sobrien  [(set (match_operand:SI 0 "register_operand" "=a")
6519107590Sobrien        (unspec:SI [(label_ref (match_operand 1 "" ""))] 211))]
6520107590Sobrien  "!TARGET_64BIT"
6521107590Sobrien  "la\\t%0,%1-.(%0)"
6522107590Sobrien  [(set_attr "op_type" "NN")
6523107590Sobrien   (set_attr "type"    "la")
6524107590Sobrien   (set_attr "length"  "4")])
6525107590Sobrien
6526107590Sobrien
6527107590Sobrien;;
6528107590Sobrien;; Insns related to generating the function prologue and epilogue.
6529107590Sobrien;;
6530107590Sobrien
6531107590Sobrien
6532107590Sobrien(define_expand "prologue"
6533107590Sobrien  [(use (const_int 0))]
6534107590Sobrien  ""
6535107590Sobrien  "
6536107590Sobrien{
6537107590Sobrien      s390_emit_prologue ();
6538107590Sobrien      DONE;
6539107590Sobrien}")
6540107590Sobrien
6541107590Sobrien(define_expand "epilogue"
6542107590Sobrien  [(use (const_int 1))]
6543107590Sobrien  ""
6544107590Sobrien  "
6545107590Sobrien{
6546107590Sobrien      s390_emit_epilogue ();
6547107590Sobrien      DONE;
6548107590Sobrien}")
6549107590Sobrien
6550107590Sobrien
6551107590Sobrien(define_insn "*return_si"
6552107590Sobrien  [(return)
6553107590Sobrien   (use (match_operand:SI 0 "register_operand" "a"))]
6554107590Sobrien  "!TARGET_64BIT"
6555107590Sobrien  "br\\t%0"
6556107590Sobrien  [(set_attr "op_type" "RR")
6557107590Sobrien   (set_attr "type"    "jsr")		
6558107590Sobrien   (set_attr "atype"   "mem")])
6559107590Sobrien
6560107590Sobrien(define_insn "*return_di"
6561107590Sobrien  [(return)
6562107590Sobrien   (use (match_operand:DI 0 "register_operand" "a"))]
6563107590Sobrien  "TARGET_64BIT"
6564107590Sobrien  "br\\t%0"
6565107590Sobrien  [(set_attr "op_type" "RR")
6566107590Sobrien   (set_attr "type"    "jsr")		
6567107590Sobrien   (set_attr "atype"   "mem")])
6568107590Sobrien
6569107590Sobrien
6570107590Sobrien(define_insn "lit"
6571107590Sobrien  [(set (reg 13) (pc))
6572107590Sobrien   (unspec_volatile [(const_int 0)] 200)]
6573107590Sobrien  ""
6574107590Sobrien  "*
6575107590Sobrien{
6576107590Sobrien   s390_output_constant_pool (asm_out_file);
6577107590Sobrien   return \"\";
6578107590Sobrien}"
6579107590Sobrien  [(set_attr "op_type" "NN")
6580107590Sobrien   (set_attr "type"    "integer")])
6581107590Sobrien
6582107590Sobrien
6583107590Sobrien;;
6584107590Sobrien;; Peephole optimization patterns.
6585107590Sobrien;;
6586107590Sobrien
6587107590Sobrien(define_peephole
6588107590Sobrien  [(set (match_operand:SI 0 "memory_operand" "m")
6589107590Sobrien        (match_operand:SI 1 "register_operand" "d"))
6590107590Sobrien   (set (match_dup 1)
6591107590Sobrien        (match_dup 0))]
6592107590Sobrien ""
6593107590Sobrien "st\\t%1,%0")
6594107590Sobrien
6595107590Sobrien(define_peephole
6596107590Sobrien  [(set (match_operand:SI 0 "memory_operand" "m")
6597107590Sobrien        (match_operand:SI 1 "register_operand" "d"))
6598107590Sobrien   (set (match_dup 0)
6599107590Sobrien        (match_dup 1))]
6600107590Sobrien ""
6601107590Sobrien "st\\t%1,%0")
6602107590Sobrien
6603107590Sobrien(define_peephole
6604107590Sobrien  [(set (match_operand:SI 0 "register_operand" "")
6605107590Sobrien        (match_operand:SI 1 "register_operand" ""))
6606107590Sobrien   (parallel
6607107590Sobrien    [(set (match_dup 0)
6608107590Sobrien          (plus:SI (match_dup 0)
6609107590Sobrien                   (match_operand:SI 2 "immediate_operand" "")))
6610107590Sobrien     (clobber (reg:CC 33))])]
6611107590Sobrien "(REGNO (operands[0]) == STACK_POINTER_REGNUM ||
6612107590Sobrien   REGNO (operands[1]) == STACK_POINTER_REGNUM ||
6613107590Sobrien   REGNO (operands[0]) == BASE_REGISTER ||
6614107590Sobrien   REGNO (operands[1]) == BASE_REGISTER) &&
6615107590Sobrien  INTVAL (operands[2]) > 0 && INTVAL (operands[2]) < 4096"
6616107590Sobrien "la\\t%0,%c2(%1)")
6617107590Sobrien
6618107590Sobrien;
6619107590Sobrien; peepholes for fast char instructions
6620107590Sobrien;
6621107590Sobrien
6622107590Sobrien;(define_peephole
6623107590Sobrien;  [(set (match_operand:QI 0 "register_operand" "d")
6624107590Sobrien;        (match_operand:QI 1 "s_operand" "Q"))
6625107590Sobrien;  (set  (match_operand:SI 2 "register_operand" "0")
6626107590Sobrien;        (zero_extend:SI (match_dup 0)))]
6627107590Sobrien; "REGNO(operands[0]) == REGNO(operands[2])"
6628107590Sobrien; "icm\\t%0,8,%1\;srl\\t%0,24")
6629107590Sobrien
6630107590Sobrien;(define_peephole
6631107590Sobrien;  [(set (match_operand:QI 0 "register_operand" "d")
6632107590Sobrien;        (match_operand:QI 1 "s_operand" "Q"))
6633107590Sobrien;   (set (match_operand:SI 2 "register_operand" "0")
6634107590Sobrien;        (sign_extend:SI (match_dup 0)))]
6635107590Sobrien; "REGNO(operands[0]) == REGNO(operands[2])"
6636107590Sobrien; "icm\\t%0,8,%1\;sra\\t%0,24")
6637107590Sobrien
6638107590Sobrien(define_peephole
6639107590Sobrien  [(set (match_operand:QI 0 "register_operand" "d")
6640107590Sobrien        (match_operand:QI 1 "immediate_operand" "J"))
6641107590Sobrien   (set (match_operand:SI 2 "register_operand" "0" )
6642107590Sobrien        (sign_extend:SI (match_dup 0) ) )]
6643107590Sobrien "REGNO(operands[0]) == REGNO(operands[2])"
6644107590Sobrien "lhi\\t%0,%h1")
6645107590Sobrien
6646107590Sobrien;
6647107590Sobrien; peepholes for fast short instructions
6648107590Sobrien;
6649107590Sobrien
6650107590Sobrien;(define_peephole
6651107590Sobrien;  [(set (match_operand:HI 0 "register_operand" "d")
6652107590Sobrien;        (match_operand:HI 1 "s_operand" "Q"))
6653107590Sobrien;   (set (match_operand:SI 2 "register_operand" "0" )
6654107590Sobrien;        (zero_extend:SI (match_dup 0)))]
6655107590Sobrien; "REGNO(operands[0]) == REGNO(operands[2])"
6656107590Sobrien; "icm\\t%0,12,%1\;srl\\t%0,16")
6657107590Sobrien
6658107590Sobrien(define_peephole
6659107590Sobrien  [(set (match_operand:HI 0 "register_operand" "d")
6660107590Sobrien        (match_operand:HI 1 "memory_operand" "m"))
6661107590Sobrien   (set (match_operand:SI 2 "register_operand" "0" )
6662107590Sobrien        (sign_extend:SI (match_dup 0)))]
6663107590Sobrien "REGNO(operands[0]) == REGNO(operands[2])"
6664107590Sobrien "lh\\t%0,%1")
6665107590Sobrien
6666107590Sobrien(define_peephole
6667107590Sobrien  [(set (match_operand:HI 0 "register_operand" "d")
6668107590Sobrien        (match_operand:HI 1 "immediate_operand" "K"))
6669107590Sobrien   (set (match_operand:SI 2 "register_operand" "0" )
6670107590Sobrien        (sign_extend:SI (match_dup 0) ) )]
6671107590Sobrien "REGNO(operands[0]) == REGNO(operands[2])"
6672107590Sobrien "lhi\\t%0,%h1")
6673107590Sobrien
6674107590Sobrien;
6675107590Sobrien; peepholes for divide instructions
6676107590Sobrien;
6677107590Sobrien
6678107590Sobrien(define_peephole
6679107590Sobrien  [(set (match_operand:DI 0 "register_operand" "d")
6680107590Sobrien        (match_operand:DI 1 "memory_operand" "m"))
6681107590Sobrien   (set (match_dup 0)
6682107590Sobrien        (lshiftrt:DI (match_dup 0)
6683107590Sobrien        (match_operand:SI 2 "immediate_operand" "J")))
6684107590Sobrien   (set (match_dup 0)
6685107590Sobrien        (div:SI (match_dup 0)
6686107590Sobrien        (match_operand:SI 3 "nonimmediate_operand" "g")))
6687107590Sobrien   (set (match_dup 1)
6688107590Sobrien        (match_dup 0))]
6689107590Sobrien  ""
6690107590Sobrien  "*
6691107590Sobrien{
6692107590Sobrien   output_asm_insn (\"l\\t%0,%1\", operands);
6693107590Sobrien   output_asm_insn (\"srdl\\t%0,%b2\", operands);
6694107590Sobrien
6695107590Sobrien   if (REG_P (operands[3]))
6696107590Sobrien     output_asm_insn (\"dr\\t%0,%3\", operands);
6697107590Sobrien   else
6698107590Sobrien     output_asm_insn (\"d\\t%0,%3\", operands);
6699107590Sobrien
6700107590Sobrien   return \"st\\t%N0,%N1\";
6701107590Sobrien}")
6702107590Sobrien
6703107590Sobrien(define_peephole
6704107590Sobrien  [(set (match_operand:DI 0 "register_operand" "d")
6705107590Sobrien        (match_operand:DI 1 "memory_operand" "m"))
6706107590Sobrien   (set (match_dup 0)
6707107590Sobrien        (lshiftrt:DI (match_dup 0)
6708107590Sobrien        (match_operand:SI 2 "immediate_operand" "J")))
6709107590Sobrien   (set (match_dup 0)
6710107590Sobrien        (mod:SI (match_dup 0)
6711107590Sobrien        (match_operand:SI 3 "nonimmediate_operand" "g")))
6712107590Sobrien   (set (match_dup 1)
6713107590Sobrien        (match_dup 0))]
6714107590Sobrien  ""
6715107590Sobrien  "*
6716107590Sobrien{
6717107590Sobrien   output_asm_insn (\"l\\t%0,%1\", operands);
6718107590Sobrien   output_asm_insn (\"srdl\\t%0,%b2\", operands);
6719107590Sobrien
6720107590Sobrien   if (REG_P (operands[3]))
6721107590Sobrien     output_asm_insn (\"dr\\t%0,%3\", operands);
6722107590Sobrien   else
6723107590Sobrien     output_asm_insn (\"d\\t%0,%3\", operands);
6724107590Sobrien
6725107590Sobrien   return \"st\\t%0,%1\";
6726107590Sobrien}")
6727107590Sobrien
6728