OSDN Git Service

Fix typo in comments.
[pf3gnuchains/gcc-fork.git] / gcc / config / alpha / alpha.md
1 ;; Machine description for DEC Alpha for GNU C compiler
2 ;; Copyright (C) 1992, 1993, 1994, 1995, 1996 Free Software Foundation, Inc.
3 ;; Contributed by Richard Kenner (kenner@vlsi1.ultra.nyu.edu)
4
5 ;; This file is part of GNU CC.
6
7 ;; GNU CC is free software; you can redistribute it and/or modify
8 ;; it under the terms of the GNU General Public License as published by
9 ;; the Free Software Foundation; either version 2, or (at your option)
10 ;; any later version.
11
12 ;; GNU CC is distributed in the hope that it will be useful,
13 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
14 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 ;; GNU General Public License for more details.
16
17 ;; You should have received a copy of the GNU General Public License
18 ;; along with GNU CC; see the file COPYING.  If not, write to
19 ;; the Free Software Foundation, 59 Temple Place - Suite 330,
20 ;; Boston, MA 02111-1307, USA.
21
22 ;;- See file "rtl.def" for documentation on define_insn, match_*, et. al.
23 \f
24 ;; Define an insn type attribute.  This is used in function unit delay
25 ;; computations, among other purposes.  For the most part, we use the names
26 ;; defined in the EV4 documentation, but add a few that we have to know about
27 ;; separately.
28
29 (define_attr "type"
30   "ld,st,ibr,fbr,jsr,iaddlog,shiftcm,icmp,imull,imulq,fpop,fdivs,fdivt,ldsym,isubr"
31   (const_string "shiftcm"))
32
33 ;; We include four function units: ABOX, which computes the address,
34 ;; BBOX, used for branches, EBOX, used for integer operations, and FBOX,
35 ;; used for FP operations.
36 ;;
37 ;; We assume that we have been successful in getting double issues and
38 ;; hence multiply all costs by two insns per cycle.  The minimum time in
39 ;; a function unit is 2 cycle, which will tend to produce the double
40 ;; issues.
41
42 ;; Memory delivers its result in three cycles.
43 (define_function_unit "abox" 1 0 (eq_attr "type" "ld,ldsym,st") 6 2)
44
45 ;; Branches have no delay cost, but do tie up the unit for two cycles.
46 (define_function_unit "bbox" 1 1 (eq_attr "type" "ibr,fbr,jsr") 4 4)
47
48 ;; Arithmetic insns are normally have their results available after two
49 ;; cycles.  There are a number of exceptions.  They are encoded in
50 ;; ADJUST_COST.  Some of the other insns have similar exceptions.
51
52 (define_function_unit "ebox" 1 0 (eq_attr "type" "iaddlog,shiftcm,icmp") 4 2)
53
54 ;; These really don't take up the integer pipeline, but they do occupy
55 ;; IBOX1; we approximate here.
56
57 (define_function_unit "ebox" 1 0 (eq_attr "type" "imull") 42 2)
58 (define_function_unit "ebox" 1 0 (eq_attr "type" "imulq") 46 2)
59
60 (define_function_unit "imult" 1 0 (eq_attr "type" "imull") 42 38)
61 (define_function_unit "imult" 1 0 (eq_attr "type" "imulq") 46 42)
62
63 (define_function_unit "fbox" 1 0 (eq_attr "type" "fpop") 12 2)
64
65 (define_function_unit "fbox" 1 0 (eq_attr "type" "fdivs") 68 0)
66 (define_function_unit "fbox" 1 0 (eq_attr "type" "fdivt") 126 0)
67
68 (define_function_unit "divider" 1 0 (eq_attr "type" "fdivs") 68 60)
69 (define_function_unit "divider" 1 0 (eq_attr "type" "fdivt") 126 118)
70 \f
71 ;; First define the arithmetic insns.  Note that the 32-bit forms also
72 ;; sign-extend.
73
74 ;; Note that we can do sign extensions in both FP and integer registers.
75 ;; However, the result must be in the same type of register as the input.
76 ;; The register preferencing code can't handle this case very well, so, for
77 ;; now, don't let the FP case show up here for preferencing.  Also,
78 ;; sign-extends in FP registers take two instructions.
79 (define_insn "extendsidi2"
80   [(set (match_operand:DI 0 "register_operand" "=r,r,*f")
81         (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "r,m,*f")))]
82   ""
83   "@
84    addl %1,$31,%0
85    ldl %0,%1
86    cvtql %1,%0\;cvtlq %0,%0"
87   [(set_attr "type" "iaddlog,ld,fpop")])
88
89 ;; Do addsi3 the way expand_binop would do if we didn't have one.  This
90 ;; generates better code.  We have the anonymous addsi3 pattern below in
91 ;; case combine wants to make it.
92 (define_expand "addsi3"
93   [(set (match_operand:SI 0 "register_operand" "")
94         (plus:SI (match_operand:SI 1 "reg_or_0_operand" "")
95                  (match_operand:SI 2 "add_operand" "")))]
96   ""
97   "
98 { emit_insn (gen_rtx (SET, VOIDmode, gen_lowpart (DImode, operands[0]),
99                       gen_rtx (PLUS, DImode,
100                                gen_lowpart (DImode, operands[1]),
101                                gen_lowpart (DImode, operands[2]))));
102   DONE;
103 } ")
104
105 (define_insn ""
106   [(set (match_operand:SI 0 "register_operand" "=r,r,r,r")
107         (plus:SI (match_operand:SI 1 "reg_or_0_operand" "%rJ,rJ,rJ,rJ")
108                  (match_operand:SI 2 "add_operand" "rI,O,K,L")))]
109   ""
110   "@
111    addl %r1,%2,%0
112    subl %r1,%n2,%0
113    lda %0,%2(%r1)
114    ldah %0,%h2(%r1)"
115   [(set_attr "type" "iaddlog")])
116
117 (define_split
118   [(set (match_operand:SI 0 "register_operand" "")
119         (plus:SI (match_operand:SI 1 "register_operand" "")
120                  (match_operand:SI 2 "const_int_operand" "")))]
121   "! add_operand (operands[2], SImode)"
122   [(set (match_dup 0) (plus:SI (match_dup 1) (match_dup 3)))
123    (set (match_dup 0) (plus:SI (match_dup 0) (match_dup 4)))]
124   "
125 {
126   HOST_WIDE_INT val = INTVAL (operands[2]);
127   HOST_WIDE_INT low = (val & 0xffff) - 2 * (val & 0x8000);
128   HOST_WIDE_INT rest = val - low;
129
130   operands[3] = GEN_INT (rest);
131   operands[4] = GEN_INT (low);
132 }")
133
134 (define_insn ""
135   [(set (match_operand:DI 0 "register_operand" "=r,r")
136         (sign_extend:DI
137          (plus:SI (match_operand:SI 1 "reg_or_0_operand" "%rJ,rJ")
138                   (match_operand:SI 2 "sext_add_operand" "rI,O"))))]
139   ""
140   "@
141    addl %r1,%2,%0
142    subl %r1,%n2,%0"
143   [(set_attr "type" "iaddlog")])
144
145 (define_split
146   [(set (match_operand:DI 0 "register_operand" "")
147         (sign_extend:DI
148          (plus:SI (match_operand:SI 1 "register_operand" "")
149                   (match_operand:SI 2 "const_int_operand" ""))))
150    (clobber (match_operand:SI 3 "register_operand" ""))]
151   "! sext_add_operand (operands[2], SImode) && INTVAL (operands[2]) > 0
152    && INTVAL (operands[2]) % 4 == 0"
153   [(set (match_dup 3) (match_dup 4))
154    (set (match_dup 0) (sign_extend:DI (plus:SI (mult:SI (match_dup 3)
155                                                         (match_dup 5))
156                                                (match_dup 1))))]
157   "
158 {
159   HOST_WIDE_INT val = INTVAL (operands[2]) / 4;
160   int mult = 4;
161
162   if (val % 2 == 0)
163     val /= 2, mult = 8;
164
165   operands[4] = GEN_INT (val);
166   operands[5] = GEN_INT (mult);
167 }")
168
169 (define_split
170   [(set (match_operand:DI 0 "register_operand" "")
171         (sign_extend:DI
172          (plus:SI (match_operator:SI 1 "comparison_operator"
173                                      [(match_operand 2 "" "")
174                                       (match_operand 3 "" "")])
175                   (match_operand:SI 4 "add_operand" ""))))
176    (clobber (match_operand:DI 5 "register_operand" ""))]
177   ""
178   [(set (match_dup 5) (match_dup 6))
179    (set (match_dup 0) (sign_extend:DI (plus:SI (match_dup 7) (match_dup 4))))]
180   "
181 {
182   operands[6] = gen_rtx (GET_CODE (operands[1]), DImode,
183                          operands[2], operands[3]);
184   operands[7] = gen_lowpart (SImode, operands[5]);
185 }")
186
187 (define_insn "adddi3"
188   [(set (match_operand:DI 0 "register_operand" "=r,r,r,r")
189         (plus:DI (match_operand:DI 1 "reg_or_0_operand" "%rJ,rJ,rJ,rJ")
190                  (match_operand:DI 2 "add_operand" "rI,O,K,L")))]
191   ""
192   "@
193    addq %r1,%2,%0
194    subq %r1,%n2,%0
195    lda %0,%2(%r1)
196    ldah %0,%h2(%r1)"
197   [(set_attr "type" "iaddlog")])
198
199 ;; Don't do this if we are adjusting SP since we don't want to do
200 ;; it in two steps. 
201 (define_split
202   [(set (match_operand:DI 0 "register_operand" "")
203         (plus:DI (match_operand:DI 1 "register_operand" "")
204                  (match_operand:DI 2 "const_int_operand" "")))]
205   "! add_operand (operands[2], DImode)
206    && REGNO (operands[0]) != STACK_POINTER_REGNUM"
207   [(set (match_dup 0) (plus:DI (match_dup 1) (match_dup 3)))
208    (set (match_dup 0) (plus:DI (match_dup 0) (match_dup 4)))]
209   "
210 {
211   HOST_WIDE_INT val = INTVAL (operands[2]);
212   HOST_WIDE_INT low = (val & 0xffff) - 2 * (val & 0x8000);
213   HOST_WIDE_INT rest = val - low;
214
215   operands[3] = GEN_INT (rest);
216   operands[4] = GEN_INT (low);
217 }")
218
219 (define_insn ""
220   [(set (match_operand:SI 0 "register_operand" "=r,r")
221         (plus:SI (mult:SI (match_operand:SI 1 "reg_or_0_operand" "rJ,rJ")
222                           (match_operand:SI 2 "const48_operand" "I,I"))
223                  (match_operand:SI 3 "sext_add_operand" "rI,O")))]
224   ""
225   "@
226    s%2addl %r1,%3,%0
227    s%2subl %r1,%n3,%0"
228   [(set_attr "type" "iaddlog")])
229
230 (define_insn ""
231   [(set (match_operand:DI 0 "register_operand" "=r,r")
232         (sign_extend:DI
233          (plus:SI (mult:SI (match_operand:SI 1 "reg_or_0_operand" "rJ,rJ")
234                            (match_operand:SI 2 "const48_operand" "I,I"))
235                   (match_operand:SI 3 "sext_add_operand" "rI,O"))))]
236   ""
237   "@
238    s%2addl %r1,%3,%0
239    s%2subl %r1,%n3,%0"
240   [(set_attr "type" "iaddlog")])
241
242 (define_split
243   [(set (match_operand:DI 0 "register_operand" "")
244         (sign_extend:DI
245          (plus:SI (mult:SI (match_operator:SI 1 "comparison_operator"
246                                               [(match_operand 2 "" "")
247                                                (match_operand 3 "" "")])
248                            (match_operand:SI 4 "const48_operand" ""))
249                   (match_operand:SI 5 "add_operand" ""))))
250    (clobber (match_operand:DI 6 "register_operand" ""))]
251   ""
252   [(set (match_dup 6) (match_dup 7))
253    (set (match_dup 0)
254         (sign_extend:DI (plus:SI (mult:SI (match_dup 8) (match_dup 4))
255                                  (match_dup 5))))]
256   "
257 {
258   operands[7] = gen_rtx (GET_CODE (operands[1]), DImode,
259                          operands[2], operands[3]);
260   operands[8] = gen_lowpart (SImode, operands[6]);
261 }")
262
263 (define_insn ""
264   [(set (match_operand:DI 0 "register_operand" "=r,r")
265         (plus:DI (mult:DI (match_operand:DI 1 "reg_or_0_operand" "rJ,rJ")
266                           (match_operand:DI 2 "const48_operand" "I,I"))
267                  (match_operand:DI 3 "reg_or_8bit_operand" "rI,O")))]
268   ""
269   "@
270    s%2addq %r1,%3,%0
271    s%2subq %1,%n3,%0"
272   [(set_attr "type" "iaddlog")])
273
274 ;; These variants of the above insns can occur if the third operand
275 ;; is the frame pointer.  This is a kludge, but there doesn't
276 ;; seem to be a way around it.  Only recognize them while reloading.
277
278 (define_insn ""
279   [(set (match_operand:DI 0 "some_operand" "=&r")
280         (plus:DI (plus:DI (match_operand:DI 1 "some_operand" "r")
281                           (match_operand:DI 2 "some_operand" "r"))
282                  (match_operand:DI 3 "some_operand" "rIOKL")))]
283   "reload_in_progress"
284   "#"
285   [(set_attr "type" "iaddlog")])
286
287 (define_split
288   [(set (match_operand:DI 0 "register_operand" "")
289         (plus:DI (plus:DI (match_operand:DI 1 "register_operand" "")
290                           (match_operand:DI 2 "register_operand" ""))
291                  (match_operand:DI 3 "add_operand" "")))]
292   "reload_completed"
293   [(set (match_dup 0) (plus:DI (match_dup 1) (match_dup 2)))
294    (set (match_dup 0) (plus:DI (match_dup 0) (match_dup 3)))]
295   "")
296                                            
297 (define_insn ""
298   [(set (match_operand:SI 0 "some_operand" "=&r")
299         (plus:SI (plus:SI (mult:SI (match_operand:SI 1 "some_operand" "rJ")
300                                    (match_operand:SI 2 "const48_operand" "I"))
301                           (match_operand:SI 3 "some_operand" "r"))
302                  (match_operand:SI 4 "some_operand" "rIOKL")))]
303   "reload_in_progress"
304   "#"
305   [(set_attr "type" "iaddlog")])
306
307 (define_split
308   [(set (match_operand:SI 0 "register_operand" "r")
309         (plus:SI (plus:SI (mult:SI (match_operand:SI 1 "reg_or_0_operand" "")
310                                    (match_operand:SI 2 "const48_operand" ""))
311                           (match_operand:SI 3 "register_operand" ""))
312                  (match_operand:SI 4 "add_operand" "rIOKL")))]
313   "reload_completed"
314   [(set (match_dup 0)
315         (plus:SI (mult:SI (match_dup 1) (match_dup 2)) (match_dup 3)))
316    (set (match_dup 0) (plus:SI (match_dup 0) (match_dup 4)))]
317   "")
318
319 (define_insn ""
320   [(set (match_operand:DI 0 "some_operand" "=&r")
321         (sign_extend:DI
322          (plus:SI (plus:SI
323                    (mult:SI (match_operand:SI 1 "some_operand" "rJ")
324                             (match_operand:SI 2 "const48_operand" "I"))
325                    (match_operand:SI 3 "some_operand" "r"))
326                   (match_operand:SI 4 "some_operand" "rIOKL"))))]
327   "reload_in_progress"
328   "#"
329   [(set_attr "type" "iaddlog")])
330
331 (define_split
332   [(set (match_operand:DI 0 "register_operand" "")
333         (sign_extend:DI
334          (plus:SI (plus:SI
335                    (mult:SI (match_operand:SI 1 "reg_or_0_operand" "")
336                             (match_operand:SI 2 "const48_operand" ""))
337                    (match_operand:SI 3 "register_operand" ""))
338                   (match_operand:SI 4 "add_operand" ""))))]
339   "reload_completed"
340   [(set (match_dup 5)
341         (plus:SI (mult:SI (match_dup 1) (match_dup 2)) (match_dup 3)))
342    (set (match_dup 0) (sign_extend:DI (plus:SI (match_dup 5) (match_dup 4))))]
343   "
344 { operands[5] = gen_lowpart (SImode, operands[0]);
345 }")
346
347 (define_insn ""
348   [(set (match_operand:DI 0 "some_operand" "=&r")
349         (plus:DI (plus:DI (mult:DI (match_operand:DI 1 "some_operand" "rJ")
350                                    (match_operand:DI 2 "const48_operand" "I"))
351                           (match_operand:DI 3 "some_operand" "r"))
352                  (match_operand:DI 4 "some_operand" "rIOKL")))]
353   "reload_in_progress"
354   "#"
355   [(set_attr "type" "iaddlog")])
356
357 (define_split
358   [(set (match_operand:DI 0 "register_operand" "=")
359         (plus:DI (plus:DI (mult:DI (match_operand:DI 1 "reg_or_0_operand" "")
360                                    (match_operand:DI 2 "const48_operand" ""))
361                           (match_operand:DI 3 "register_operand" ""))
362                  (match_operand:DI 4 "add_operand" "")))]
363   "reload_completed"
364   [(set (match_dup 0)
365         (plus:DI (mult:DI (match_dup 1) (match_dup 2)) (match_dup 3)))
366    (set (match_dup 0) (plus:DI (match_dup 0) (match_dup 4)))]
367   "")
368
369 (define_insn "negsi2"
370   [(set (match_operand:SI 0 "register_operand" "=r")
371         (neg:SI (match_operand:SI 1 "reg_or_8bit_operand" "rI")))]
372   ""
373   "subl $31,%1,%0"
374   [(set_attr "type" "iaddlog")])
375
376 (define_insn ""
377   [(set (match_operand:DI 0 "register_operand" "=r")
378         (sign_extend:DI (neg:SI
379                          (match_operand:SI 1 "reg_or_8bit_operand" "rI"))))]
380   ""
381   "subl $31,%1,%0"
382   [(set_attr "type" "iaddlog")])
383
384 (define_insn "negdi2"
385   [(set (match_operand:DI 0 "register_operand" "=r")
386         (neg:DI (match_operand:DI 1 "reg_or_8bit_operand" "rI")))]
387   ""
388   "subq $31,%1,%0"
389   [(set_attr "type" "iaddlog")])
390
391 (define_expand "subsi3"
392   [(set (match_operand:SI 0 "register_operand" "")
393         (minus:SI (match_operand:SI 1 "reg_or_0_operand" "")
394                   (match_operand:SI 2 "reg_or_8bit_operand" "")))]
395   ""
396   "
397 { emit_insn (gen_rtx (SET, VOIDmode, gen_lowpart (DImode, operands[0]),
398                       gen_rtx (MINUS, DImode,
399                                gen_lowpart (DImode, operands[1]),
400                                gen_lowpart (DImode, operands[2]))));
401   DONE;
402
403 } ")
404
405 (define_insn ""
406   [(set (match_operand:SI 0 "register_operand" "=r")
407         (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rJ")
408                   (match_operand:SI 2 "reg_or_8bit_operand" "rI")))]
409   ""
410   "subl %r1,%2,%0"
411   [(set_attr "type" "iaddlog")])
412
413 (define_insn ""
414   [(set (match_operand:DI 0 "register_operand" "=r")
415         (sign_extend:DI (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rJ")
416                                   (match_operand:SI 2 "reg_or_8bit_operand" "rI"))))]
417   ""
418   "subl %r1,%2,%0"
419   [(set_attr "type" "iaddlog")])
420
421 (define_insn "subdi3"
422   [(set (match_operand:DI 0 "register_operand" "=r")
423         (minus:DI (match_operand:DI 1 "reg_or_0_operand" "rJ")
424                   (match_operand:DI 2 "reg_or_8bit_operand" "rI")))]
425   ""
426   "subq %r1,%2,%0"
427   [(set_attr "type" "iaddlog")])
428
429 (define_insn ""
430   [(set (match_operand:SI 0 "register_operand" "=r")
431         (minus:SI (mult:SI (match_operand:SI 1 "reg_or_0_operand" "rJ")
432                            (match_operand:SI 2 "const48_operand" "I"))
433                   (match_operand:SI 3 "reg_or_8bit_operand" "rI")))]
434   ""
435   "s%2subl %r1,%3,%0"
436   [(set_attr "type" "iaddlog")])
437
438 (define_insn ""
439   [(set (match_operand:DI 0 "register_operand" "=r")
440         (sign_extend:DI
441          (minus:SI (mult:SI (match_operand:SI 1 "reg_or_0_operand" "rJ")
442                             (match_operand:SI 2 "const48_operand" "I"))
443                    (match_operand:SI 3 "reg_or_8bit_operand" "rI"))))]
444   ""
445   "s%2subl %r1,%3,%0"
446   [(set_attr "type" "iaddlog")])
447
448 (define_insn ""
449   [(set (match_operand:DI 0 "register_operand" "=r")
450         (minus:DI (mult:DI (match_operand:DI 1 "reg_or_0_operand" "rJ")
451                            (match_operand:DI 2 "const48_operand" "I"))
452                   (match_operand:DI 3 "reg_or_8bit_operand" "rI")))]
453   ""
454   "s%2subq %r1,%3,%0"
455   [(set_attr "type" "iaddlog")])
456
457 (define_insn "mulsi3"
458   [(set (match_operand:SI 0 "register_operand" "=r")
459         (mult:SI (match_operand:SI 1 "reg_or_0_operand" "%rJ")
460                  (match_operand:SI 2 "reg_or_0_operand" "rJ")))]
461   ""
462   "mull %r1,%r2,%0"
463   [(set_attr "type" "imull")])
464
465 (define_insn ""
466   [(set (match_operand:DI 0 "register_operand" "=r")
467         (sign_extend:DI (mult:SI (match_operand:SI 1 "reg_or_0_operand" "%rJ")
468                                  (match_operand:SI 2 "reg_or_0_operand" "rJ"))))]
469   ""
470   "mull %r1,%r2,%0"
471   [(set_attr "type" "imull")])
472
473 (define_insn "muldi3"
474   [(set (match_operand:DI 0 "register_operand" "=r")
475         (mult:DI (match_operand:DI 1 "reg_or_0_operand" "%rJ")
476                  (match_operand:DI 2 "reg_or_0_operand" "rJ")))]
477   ""
478   "mulq %r1,%r2,%0"
479   [(set_attr "type" "imulq")])
480
481 (define_insn "umuldi3_highpart"
482   [(set (match_operand:DI 0 "register_operand" "=r")
483         (truncate:DI
484          (lshiftrt:TI
485           (mult:TI (zero_extend:TI (match_operand:DI 1 "register_operand" "r"))
486                    (zero_extend:TI (match_operand:DI 2 "register_operand" "r")))
487           (const_int 64))))]
488   ""
489   "umulh %1,%2,%0"
490   [(set_attr "type" "imulq")])
491
492 (define_insn ""
493   [(set (match_operand:DI 0 "register_operand" "=r")
494         (truncate:DI
495          (lshiftrt:TI
496           (mult:TI (zero_extend:TI (match_operand:DI 1 "register_operand" "r"))
497                    (match_operand:TI 2 "cint8_operand" "I"))
498           (const_int 64))))]
499   ""
500   "umulh %1,%2,%0"
501   [(set_attr "type" "imulq")])
502 \f
503 ;; The divide and remainder operations always take their inputs from
504 ;; r24 and r25, put their output in r27, and clobber r23 and r28.
505
506 (define_expand "divsi3"
507   [(set (reg:SI 24) (match_operand:SI 1 "input_operand" ""))
508    (set (reg:SI 25) (match_operand:SI 2 "input_operand" ""))
509    (parallel [(set (reg:SI 27)
510                    (div:SI (reg:SI 24)
511                            (reg:SI 25)))
512               (clobber (reg:DI 23))
513               (clobber (reg:DI 28))])
514    (set (match_operand:SI 0 "general_operand" "")
515         (reg:SI 27))]
516   ""
517   "")
518
519 (define_expand "udivsi3"
520   [(set (reg:SI 24) (match_operand:SI 1 "input_operand" ""))
521    (set (reg:SI 25) (match_operand:SI 2 "input_operand" ""))
522    (parallel [(set (reg:SI 27)
523                    (udiv:SI (reg:SI 24)
524                             (reg:SI 25)))
525               (clobber (reg:DI 23))
526               (clobber (reg:DI 28))])
527    (set (match_operand:SI 0 "general_operand" "")
528         (reg:SI 27))]
529   ""
530   "")
531
532 (define_expand "modsi3"
533   [(set (reg:SI 24) (match_operand:SI 1 "input_operand" ""))
534    (set (reg:SI 25) (match_operand:SI 2 "input_operand" ""))
535    (parallel [(set (reg:SI 27)
536                    (mod:SI (reg:SI 24)
537                            (reg:SI 25)))
538               (clobber (reg:DI 23))
539               (clobber (reg:DI 28))])
540    (set (match_operand:SI 0 "general_operand" "")
541         (reg:SI 27))]
542   ""
543   "")
544
545 (define_expand "umodsi3"
546   [(set (reg:SI 24) (match_operand:SI 1 "input_operand" ""))
547    (set (reg:SI 25) (match_operand:SI 2 "input_operand" ""))
548    (parallel [(set (reg:SI 27)
549                    (umod:SI (reg:SI 24)
550                             (reg:SI 25)))
551               (clobber (reg:DI 23))
552               (clobber (reg:DI 28))])
553    (set (match_operand:SI 0 "general_operand" "")
554         (reg:SI 27))]
555   ""
556   "")
557
558 (define_expand "divdi3"
559   [(set (reg:DI 24) (match_operand:DI 1 "input_operand" ""))
560    (set (reg:DI 25) (match_operand:DI 2 "input_operand" ""))
561    (parallel [(set (reg:DI 27)
562                    (div:DI (reg:DI 24)
563                            (reg:DI 25)))
564               (clobber (reg:DI 23))
565               (clobber (reg:DI 28))])
566    (set (match_operand:DI 0 "general_operand" "")
567         (reg:DI 27))]
568   ""
569   "")
570
571 (define_expand "udivdi3"
572   [(set (reg:DI 24) (match_operand:DI 1 "input_operand" ""))
573    (set (reg:DI 25) (match_operand:DI 2 "input_operand" ""))
574    (parallel [(set (reg:DI 27)
575                    (udiv:DI (reg:DI 24)
576                             (reg:DI 25)))
577               (clobber (reg:DI 23))
578               (clobber (reg:DI 28))])
579    (set (match_operand:DI 0 "general_operand" "")
580         (reg:DI 27))]
581   ""
582   "")
583
584 (define_expand "moddi3"
585   [(set (reg:DI 24) (match_operand:DI 1 "input_operand" ""))
586    (set (reg:DI 25) (match_operand:DI 2 "input_operand" ""))
587    (parallel [(set (reg:DI 27)
588                    (mod:DI (reg:DI 24)
589                            (reg:DI 25)))
590               (clobber (reg:DI 23))
591               (clobber (reg:DI 28))])
592    (set (match_operand:DI 0 "general_operand" "")
593         (reg:DI 27))]
594   ""
595   "")
596
597 (define_expand "umoddi3"
598   [(set (reg:DI 24) (match_operand:DI 1 "input_operand" ""))
599    (set (reg:DI 25) (match_operand:DI 2 "input_operand" ""))
600    (parallel [(set (reg:DI 27)
601                    (umod:DI (reg:DI 24)
602                             (reg:DI 25)))
603               (clobber (reg:DI 23))
604               (clobber (reg:DI 28))])
605    (set (match_operand:DI 0 "general_operand" "")
606         (reg:DI 27))]
607   ""
608   "")
609
610 (define_insn ""
611   [(set (reg:SI 27)
612         (match_operator:SI 1 "divmod_operator"
613                         [(reg:SI 24) (reg:SI 25)]))
614    (clobber (reg:DI 23))
615    (clobber (reg:DI 28))]
616   ""
617   "%E1 $24,$25,$27"
618   [(set_attr "type" "isubr")])
619
620 (define_insn ""
621   [(set (reg:DI 27)
622         (match_operator:DI 1 "divmod_operator"
623                         [(reg:DI 24) (reg:DI 25)]))
624    (clobber (reg:DI 23))
625    (clobber (reg:DI 28))]
626   ""
627   "%E1 $24,$25,$27"
628   [(set_attr "type" "isubr")])
629 \f
630 ;; Next are the basic logical operations.  These only exist in DImode.
631
632 (define_insn "anddi3"
633   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
634         (and:DI (match_operand:DI 1 "reg_or_0_operand" "%rJ,rJ,rJ")
635                 (match_operand:DI 2 "and_operand" "rI,N,MH")))]
636   ""
637   "@
638    and %r1,%2,%0
639    bic %r1,%N2,%0
640    zapnot %r1,%m2,%0"
641   [(set_attr "type" "iaddlog,iaddlog,shiftcm")])
642
643 ;; There are times when we can split an AND into two AND insns.  This occurs
644 ;; when we can first clear any bytes and then clear anything else.  For
645 ;; example "I & 0xffff07" is "(I & 0xffffff) & 0xffffffffffffff07".
646 ;; Only do this when running on 64-bit host since the computations are
647 ;; too messy otherwise.
648
649 (define_split
650   [(set (match_operand:DI 0 "register_operand" "")
651         (and:DI (match_operand:DI 1 "register_operand" "")
652                 (match_operand:DI 2 "const_int_operand" "")))]
653   "HOST_BITS_PER_WIDE_INT == 64 && ! and_operand (operands[2], DImode)"
654   [(set (match_dup 0) (and:DI (match_dup 1) (match_dup 3)))
655    (set (match_dup 0) (and:DI (match_dup 0) (match_dup 4)))]
656   "
657 {
658   unsigned HOST_WIDE_INT mask1 = INTVAL (operands[2]);
659   unsigned HOST_WIDE_INT mask2 = mask1;
660   int i;
661
662   /* For each byte that isn't all zeros, make it all ones.  */
663   for (i = 0; i < 64; i += 8)
664     if ((mask1 & ((HOST_WIDE_INT) 0xff << i)) != 0)
665       mask1 |= (HOST_WIDE_INT) 0xff << i;
666
667   /* Now turn on any bits we've just turned off.  */
668   mask2 |= ~ mask1;
669
670   operands[3] = GEN_INT (mask1);
671   operands[4] = GEN_INT (mask2);
672 }")
673
674 (define_insn "zero_extendqihi2"
675   [(set (match_operand:HI 0 "register_operand" "=r")
676         (zero_extend:HI (match_operand:QI 1 "register_operand" "r")))]
677   ""
678   "zapnot %1,1,%0"
679   [(set_attr "type" "iaddlog")])
680
681 (define_insn "zero_extendqisi2"
682   [(set (match_operand:SI 0 "register_operand" "=r")
683         (zero_extend:SI (match_operand:QI 1 "register_operand" "r")))]
684   ""
685   "zapnot %1,1,%0"
686   [(set_attr "type" "iaddlog")])
687
688 (define_insn "zero_extendqidi2"
689   [(set (match_operand:DI 0 "register_operand" "=r")
690         (zero_extend:DI (match_operand:QI 1 "register_operand" "r")))]
691   ""
692   "zapnot %1,1,%0"
693   [(set_attr "type" "iaddlog")])
694
695 (define_insn "zero_extendhisi2"
696   [(set (match_operand:SI 0 "register_operand" "=r")
697         (zero_extend:SI (match_operand:HI 1 "register_operand" "r")))]
698   ""
699   "zapnot %1,3,%0"
700   [(set_attr "type" "iaddlog")])
701
702 (define_insn "zero_extendhidi2"
703   [(set (match_operand:DI 0 "register_operand" "=r")
704         (zero_extend:DI (match_operand:HI 1 "register_operand" "r")))]
705   ""
706   "zapnot %1,3,%0"
707   [(set_attr "type" "iaddlog")])
708
709 (define_insn "zero_extendsidi2"
710   [(set (match_operand:DI 0 "register_operand" "=r")
711         (zero_extend:DI (match_operand:SI 1 "register_operand" "r")))]
712   ""
713   "zapnot %1,15,%0"
714   [(set_attr "type" "iaddlog")])
715
716 (define_insn  ""
717   [(set (match_operand:DI 0 "register_operand" "=r")
718         (and:DI (not:DI (match_operand:DI 1 "reg_or_8bit_operand" "rI"))
719                 (match_operand:DI 2 "reg_or_0_operand" "rJ")))]
720   ""
721   "bic %r2,%1,%0"
722   [(set_attr "type" "iaddlog")])
723
724 (define_insn "iordi3"
725   [(set (match_operand:DI 0 "register_operand" "=r,r")
726         (ior:DI (match_operand:DI 1 "reg_or_0_operand" "%rJ,rJ")
727                 (match_operand:DI 2 "or_operand" "rI,N")))]
728   ""
729   "@
730    bis %r1,%2,%0
731    ornot %r1,%N2,%0"
732   [(set_attr "type" "iaddlog")])
733
734 (define_insn "one_cmpldi2"
735   [(set (match_operand:DI 0 "register_operand" "=r")
736         (not:DI (match_operand:DI 1 "reg_or_8bit_operand" "rI")))]
737   ""
738   "ornot $31,%1,%0"
739   [(set_attr "type" "iaddlog")])
740
741 (define_insn ""
742   [(set (match_operand:DI 0 "register_operand" "=r")
743         (ior:DI (not:DI (match_operand:DI 1 "reg_or_8bit_operand" "rI"))
744                 (match_operand:DI 2 "reg_or_0_operand" "rJ")))]
745   ""
746   "ornot %r2,%1,%0"
747   [(set_attr "type" "iaddlog")])
748
749 (define_insn "xordi3"
750   [(set (match_operand:DI 0 "register_operand" "=r,r")
751         (xor:DI (match_operand:DI 1 "reg_or_0_operand" "%rJ,rJ")
752                 (match_operand:DI 2 "or_operand" "rI,N")))]
753   ""
754   "@
755    xor %r1,%2,%0
756    eqv %r1,%N2,%0"
757   [(set_attr "type" "iaddlog")])
758
759 (define_insn ""
760   [(set (match_operand:DI 0 "register_operand" "=r")
761         (not:DI (xor:DI (match_operand:DI 1 "register_operand" "%rJ")
762                         (match_operand:DI 2 "register_operand" "rI"))))]
763   ""
764   "eqv %r1,%2,%0"
765   [(set_attr "type" "iaddlog")])
766 \f
767 ;; Next come the shifts and the various extract and insert operations.
768
769 (define_insn "ashldi3"
770   [(set (match_operand:DI 0 "register_operand" "=r,r")
771         (ashift:DI (match_operand:DI 1 "reg_or_0_operand" "rJ,rJ")
772                    (match_operand:DI 2 "reg_or_6bit_operand" "P,rI")))]
773   ""
774   "*
775 {
776   switch (which_alternative)
777     {
778     case 0:
779       if (operands[2] == const1_rtx)
780         return \"addq %r1,%r1,%0\";
781       else
782         return \"s%P2addq %r1,0,%0\";
783     case 1:
784       return \"sll %r1,%2,%0\";
785     }
786 }"
787   [(set_attr "type" "iaddlog,shiftcm")])
788
789 ;; ??? The following pattern is made by combine, but earlier phases
790 ;; (specifically flow) can't handle it.  This occurs in jump.c.  Deal
791 ;; with this in a better way at some point.
792 ;;(define_insn ""
793 ;;  [(set (match_operand:DI 0 "register_operand" "=r")
794 ;;      (sign_extend:DI
795 ;;       (subreg:SI (ashift:DI (match_operand:DI 1 "reg_or_0_operand" "rJ")
796 ;;                             (match_operand:DI 2 "const_int_operand" "P"))
797 ;;                  0)))]
798 ;;  "INTVAL (operands[2]) >= 1 && INTVAL (operands[2]) <= 3"
799 ;;  "*
800 ;;{
801 ;;  if (operands[2] == const1_rtx)
802 ;;    return \"addl %r1,%r1,%0\";
803 ;;  else
804 ;;    return \"s%P2addl %r1,0,%0\";
805 ;; }"
806 ;;  [(set_attr "type" "iaddlog")])
807                           
808 (define_insn "lshrdi3"
809   [(set (match_operand:DI 0 "register_operand" "=r")
810         (lshiftrt:DI (match_operand:DI 1 "reg_or_0_operand" "rJ")
811                      (match_operand:DI 2 "reg_or_6bit_operand" "rI")))]
812   ""
813   "srl %r1,%2,%0")
814
815 (define_insn "ashrdi3"
816   [(set (match_operand:DI 0 "register_operand" "=r")
817         (ashiftrt:DI (match_operand:DI 1 "reg_or_0_operand" "rJ")
818                      (match_operand:DI 2 "reg_or_6bit_operand" "rI")))]
819   ""
820   "sra %r1,%2,%0")
821
822 (define_expand "extendqihi2"
823   [(set (match_dup 2)
824         (ashift:DI (match_operand:QI 1 "reg_or_unaligned_mem_operand" "")
825                    (const_int 56)))
826    (set (match_operand:HI 0 "register_operand" "")
827         (ashiftrt:DI (match_dup 2)
828                      (const_int 56)))]
829   ""
830   "
831 {
832   /* If we have a MEM (must be unaligned), extend to DImode (which we do
833         specially) and then copy to the result.  */
834   if (GET_CODE (operands[1]) == MEM)
835     {
836       rtx temp = gen_reg_rtx (DImode);
837
838       emit_insn (gen_extendqidi2 (temp, operands[1]));
839       emit_move_insn (operands[0], gen_lowpart (HImode, temp));
840       DONE;
841     }
842
843   operands[0] = gen_lowpart (DImode, operands[0]);
844   operands[1] = gen_lowpart (DImode, operands[1]);
845   operands[2] = gen_reg_rtx (DImode);
846 }")
847
848 (define_expand "extendqisi2"
849   [(set (match_dup 2)
850         (ashift:DI (match_operand:QI 1 "reg_or_unaligned_mem_operand" "")
851                    (const_int 56)))
852    (set (match_operand:SI 0 "register_operand" "")
853         (ashiftrt:DI (match_dup 2)
854                      (const_int 56)))]
855   ""
856   "
857 {
858   /* If we have a MEM (must be unaligned), extend to a DImode form of
859      the result (which we do specially).  */
860   if (GET_CODE (operands[1]) == MEM)
861     {
862       rtx temp = gen_reg_rtx (DImode);
863
864       emit_insn (gen_extendqidi2 (temp, operands[1]));
865       emit_move_insn (operands[0], gen_lowpart (SImode, temp));
866       DONE;
867     }
868
869   operands[0] = gen_lowpart (DImode, operands[0]);
870   operands[1] = gen_lowpart (DImode, operands[1]);
871   operands[2] = gen_reg_rtx (DImode);
872 }")
873
874 (define_expand "extendqidi2"
875   [(set (match_dup 2)
876         (ashift:DI (match_operand:QI 1 "reg_or_unaligned_mem_operand" "")
877                    (const_int 56)))
878    (set (match_operand:DI 0 "register_operand" "")
879         (ashiftrt:DI (match_dup 2)
880                      (const_int 56)))]
881   ""
882   "
883 { extern rtx get_unaligned_address ();
884   if (GET_CODE (operands[1]) == MEM)
885     {
886       rtx seq
887         = gen_unaligned_extendqidi (operands[0],
888                                     get_unaligned_address (operands[1], 1));
889
890       alpha_set_memflags (seq, operands[1]);
891       emit_insn (seq);
892       DONE;
893     }
894
895   operands[1] = gen_lowpart (DImode, operands[1]);
896   operands[2] = gen_reg_rtx (DImode);
897 }")
898
899 (define_expand "extendhisi2"
900   [(set (match_dup 2)
901         (ashift:DI (match_operand:HI 1 "reg_or_unaligned_mem_operand" "")
902                    (const_int 48)))
903    (set (match_operand:SI 0 "register_operand" "")
904         (ashiftrt:DI (match_dup 2)
905                      (const_int 48)))]
906   ""
907   "
908 {
909   /* If we have a MEM (must be unaligned), extend to a DImode form of
910      the result (which we do specially).  */
911   if (GET_CODE (operands[1]) == MEM)
912     {
913       rtx temp = gen_reg_rtx (DImode);
914
915       emit_insn (gen_extendhidi2 (temp, operands[1]));
916       emit_move_insn (operands[0], gen_lowpart (SImode, temp));
917       DONE;
918     }
919
920   operands[0] = gen_lowpart (DImode, operands[0]);
921   operands[1] = gen_lowpart (DImode, operands[1]);
922   operands[2] = gen_reg_rtx (DImode);
923 }")
924
925 (define_expand "extendhidi2"
926   [(set (match_dup 2)
927         (ashift:DI (match_operand:HI 1 "reg_or_unaligned_mem_operand" "")
928                    (const_int 48)))
929    (set (match_operand:DI 0 "register_operand" "")
930         (ashiftrt:DI (match_dup 2)
931                      (const_int 48)))]
932   ""
933   "
934 { extern rtx get_unaligned_address ();
935   if (GET_CODE (operands[1]) == MEM)
936     {
937       rtx seq
938         = gen_unaligned_extendhidi (operands[0],
939                                     get_unaligned_address (operands[1], 2));
940
941       alpha_set_memflags (seq, operands[1]);
942       emit_insn (seq);
943       DONE;
944     }
945
946   operands[1] = gen_lowpart (DImode, operands[1]);
947   operands[2] = gen_reg_rtx (DImode);
948 }")
949
950 ;; Here's how we sign extend an unaligned byte and halfword.  Doing this
951 ;; as a pattern saves one instruction.  The code is similar to that for
952 ;; the unaligned loads (see below).
953 ;;
954 ;; Operand 1 is the address + 1 (+2 for HI), operand 0 is the result.
955 (define_expand "unaligned_extendqidi"
956   [(set (match_dup 2) (match_operand:DI 1 "address_operand" ""))
957    (set (match_dup 3)
958         (mem:DI (and:DI (plus:DI (match_dup 2) (const_int -1))
959                         (const_int -8))))
960    (set (match_dup 4)
961         (ashift:DI (match_dup 3)
962                    (minus:DI (const_int 56)
963                              (ashift:DI
964                               (and:DI (plus:DI (match_dup 2) (const_int -1))
965                                       (const_int 7))
966                               (const_int 3)))))
967    (set (subreg:DI (match_operand:QI 0 "register_operand" "") 0)
968         (ashiftrt:DI (match_dup 4) (const_int 56)))]
969   ""
970   "
971 { operands[2] = gen_reg_rtx (DImode);
972   operands[3] = gen_reg_rtx (DImode);
973   operands[4] = gen_reg_rtx (DImode);
974 }")
975
976 (define_expand "unaligned_extendhidi"
977   [(set (match_dup 2) (match_operand:DI 1 "address_operand" ""))
978    (set (match_dup 3)
979         (mem:DI (and:DI (plus:DI (match_dup 2) (const_int -2))
980                         (const_int -8))))
981    (set (match_dup 4)
982         (ashift:DI (match_dup 3)
983                    (minus:DI (const_int 56)
984                              (ashift:DI
985                               (and:DI (plus:DI (match_dup 2) (const_int -1))
986                                       (const_int 7))
987                               (const_int 3)))))
988    (set (subreg:DI (match_operand:QI 0 "register_operand" "") 0)
989         (ashiftrt:DI (match_dup 4) (const_int 48)))]
990   ""
991   "
992 { operands[2] = gen_reg_rtx (DImode);
993   operands[3] = gen_reg_rtx (DImode);
994   operands[4] = gen_reg_rtx (DImode);
995 }")
996
997 (define_insn ""
998   [(set (match_operand:DI 0 "register_operand" "=r")
999         (zero_extract:DI (match_operand:DI 1 "reg_or_0_operand" "rJ")
1000                          (match_operand:DI 2 "mode_width_operand" "n")
1001                          (match_operand:DI 3 "mul8_operand" "I")))]
1002   ""
1003   "ext%M2l %r1,%s3,%0")
1004
1005 (define_insn ""
1006   [(set (match_operand:DI 0 "register_operand" "=r")
1007         (zero_extract:DI (match_operand:DI 1 "reg_or_0_operand" "rJ")
1008                          (match_operand:DI 2 "mode_width_operand" "n")
1009                          (ashift:DI (match_operand:DI 3 "reg_or_8bit_operand" "rI")
1010                                     (const_int 3))))]
1011   ""
1012   "ext%M2l %r1,%3,%0")
1013
1014 (define_insn ""
1015   [(set (match_operand:DI 0 "register_operand" "=r")
1016         (ashift:DI
1017          (match_operand:DI 1 "reg_or_0_operand" "rJ")
1018           (minus:DI (const_int 56)
1019                     (ashift:DI
1020                      (and:DI
1021                       (plus:DI (match_operand:DI 2 "reg_or_8bit_operand" "rI")
1022                                (const_int -1))
1023                       (const_int 7))
1024                      (const_int 3)))))]
1025   ""
1026   "extqh %r1,%2,%0")
1027
1028 (define_insn ""
1029   [(set (match_operand:DI 0 "register_operand" "=r")
1030         (ashift:DI
1031          (and:DI (match_operand:DI 1 "reg_or_0_operand" "rJ")
1032                  (const_int 2147483647))
1033          (minus:DI (const_int 56)
1034                     (ashift:DI
1035                      (and:DI
1036                       (plus:DI (match_operand:DI 2 "reg_or_8bit_operand" "rI")
1037                                (const_int -1))
1038                       (const_int 7))
1039                      (const_int 3)))))]
1040   ""
1041   "extlh %r1,%2,%0")
1042
1043 (define_insn ""
1044   [(set (match_operand:DI 0 "register_operand" "=r")
1045         (ashift:DI
1046          (and:DI (match_operand:DI 1 "reg_or_0_operand" "rJ")
1047                  (const_int 65535))
1048          (minus:DI (const_int 56)
1049                     (ashift:DI
1050                      (and:DI
1051                       (plus:DI (match_operand:DI 2 "reg_or_8bit_operand" "rI")
1052                                (const_int -1))
1053                       (const_int 7))
1054                      (const_int 3)))))]
1055   ""
1056   "extwh %r1,%2,%0")
1057
1058 ;; This converts an extXl into an extXh with an appropriate adjustment
1059 ;; to the address calculation.
1060
1061 ;;(define_split
1062 ;;  [(set (match_operand:DI 0 "register_operand" "")
1063 ;;      (ashift:DI (zero_extract:DI (match_operand:DI 1 "register_operand" "")
1064 ;;                                  (match_operand:DI 2 "mode_width_operand" "")
1065 ;;                                  (ashift:DI (match_operand:DI 3 "" "")
1066 ;;                                             (const_int 3)))
1067 ;;                 (match_operand:DI 4 "const_int_operand" "")))
1068 ;;   (clobber (match_operand:DI 5 "register_operand" ""))]
1069 ;;  "INTVAL (operands[4]) == 64 - INTVAL (operands[2])"
1070 ;;  [(set (match_dup 5) (match_dup 6))
1071 ;;   (set (match_dup 0)
1072 ;;      (ashift:DI (zero_extract:DI (match_dup 1) (match_dup 2)
1073 ;;                                  (ashift:DI (plus:DI (match_dup 5)
1074 ;;                                                      (match_dup 7))
1075 ;;                                             (const_int 3)))
1076 ;;                 (match_dup 4)))]
1077 ;;  "
1078 ;;{
1079 ;;  operands[6] = plus_constant (operands[3], 
1080 ;;                             INTVAL (operands[2]) / BITS_PER_UNIT);
1081 ;;  operands[7] = GEN_INT (- INTVAL (operands[2]) / BITS_PER_UNIT);
1082 ;;}")
1083   
1084 (define_insn ""
1085   [(set (match_operand:DI 0 "register_operand" "=r")
1086         (ashift:DI (zero_extend:DI (match_operand:QI 1 "register_operand" "r"))
1087                    (match_operand:DI 2 "mul8_operand" "I")))]
1088   ""
1089   "insbl %1,%s2,%0")
1090
1091 (define_insn ""
1092   [(set (match_operand:DI 0 "register_operand" "=r")
1093         (ashift:DI (zero_extend:DI (match_operand:HI 1 "register_operand" "r"))
1094                    (match_operand:DI 2 "mul8_operand" "I")))]
1095   ""
1096   "inswl %1,%s2,%0")
1097
1098 (define_insn ""
1099   [(set (match_operand:DI 0 "register_operand" "=r")
1100         (ashift:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
1101                    (match_operand:DI 2 "mul8_operand" "I")))]
1102   ""
1103   "insll %1,%s2,%0")
1104
1105 (define_insn ""
1106   [(set (match_operand:DI 0 "register_operand" "=r")
1107         (ashift:DI (zero_extend:DI (match_operand:QI 1 "register_operand" "r"))
1108                    (ashift:DI (match_operand:DI 2 "reg_or_8bit_operand" "rI")
1109                               (const_int 3))))]
1110   ""
1111   "insbl %1,%2,%0")
1112
1113 (define_insn ""
1114   [(set (match_operand:DI 0 "register_operand" "=r")
1115         (ashift:DI (zero_extend:DI (match_operand:HI 1 "register_operand" "r"))
1116                    (ashift:DI (match_operand:DI 2 "reg_or_8bit_operand" "rI")
1117                               (const_int 3))))]
1118   ""
1119   "inswl %1,%2,%0")
1120
1121 (define_insn ""
1122   [(set (match_operand:DI 0 "register_operand" "=r")
1123         (ashift:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
1124                    (ashift:DI (match_operand:DI 2 "reg_or_8bit_operand" "rI")
1125                               (const_int 3))))]
1126   ""
1127   "insll %1,%2,%0")
1128
1129 ;; We do not include the insXh insns because they are complex to express
1130 ;; and it does not appear that we would ever want to generate them.
1131
1132 (define_insn ""
1133   [(set (match_operand:DI 0 "register_operand" "=r")
1134         (and:DI (not:DI (ashift:DI
1135                          (match_operand:DI 2 "mode_mask_operand" "n")
1136                          (ashift:DI
1137                           (match_operand:DI 3 "reg_or_8bit_operand" "rI")
1138                           (const_int 3))))
1139                 (match_operand:DI 1 "reg_or_0_operand" "rJ")))]
1140   ""
1141   "msk%U2l %r1,%3,%0")
1142
1143 ;; We do not include the mskXh insns because it does not appear we would ever
1144 ;; generate one.
1145 \f
1146 ;; Floating-point operations.  All the double-precision insns can extend
1147 ;; from single, so indicate that.  The exception are the ones that simply
1148 ;; play with the sign bits; it's not clear what to do there.
1149
1150 (define_insn "abssf2"
1151   [(set (match_operand:SF 0 "register_operand" "=f")
1152         (abs:SF (match_operand:SF 1 "reg_or_fp0_operand" "fG")))]
1153   "TARGET_FP"
1154   "cpys $f31,%R1,%0"
1155   [(set_attr "type" "fpop")])
1156
1157 (define_insn "absdf2"
1158   [(set (match_operand:DF 0 "register_operand" "=f")
1159         (abs:DF (match_operand:DF 1 "reg_or_fp0_operand" "fG")))]
1160   "TARGET_FP"
1161   "cpys $f31,%R1,%0"
1162   [(set_attr "type" "fpop")])
1163
1164 (define_insn "negsf2"
1165   [(set (match_operand:SF 0 "register_operand" "=f")
1166         (neg:SF (match_operand:SF 1 "reg_or_fp0_operand" "fG")))]
1167   "TARGET_FP"
1168   "cpysn %R1,%R1,%0"
1169   [(set_attr "type" "fpop")])
1170
1171 (define_insn "negdf2"
1172   [(set (match_operand:DF 0 "register_operand" "=f")
1173         (neg:DF (match_operand:DF 1 "reg_or_fp0_operand" "fG")))]
1174   "TARGET_FP"
1175   "cpysn %R1,%R1,%0"
1176   [(set_attr "type" "fpop")])
1177
1178 (define_insn "addsf3"
1179   [(set (match_operand:SF 0 "register_operand" "=f")
1180         (plus:SF (match_operand:SF 1 "reg_or_fp0_operand" "%fG")
1181                  (match_operand:SF 2 "reg_or_fp0_operand" "fG")))]
1182   "TARGET_FP"
1183   "adds %R1,%R2,%0"
1184   [(set_attr "type" "fpop")])
1185
1186 (define_insn "adddf3"
1187   [(set (match_operand:DF 0 "register_operand" "=f")
1188         (plus:DF (match_operand:DF 1 "reg_or_fp0_operand" "%fG")
1189                  (match_operand:DF 2 "reg_or_fp0_operand" "fG")))]
1190   "TARGET_FP"
1191   "addt %R1,%R2,%0"
1192   [(set_attr "type" "fpop")])
1193
1194 (define_insn ""
1195   [(set (match_operand:DF 0 "register_operand" "=f")
1196         (plus:DF (float_extend:DF
1197                   (match_operand:SF 1 "reg_or_fp0_operand" "fG"))
1198                  (match_operand:DF 2 "reg_or_fp0_operand" "fG")))]
1199   "TARGET_FP"
1200   "addt %R1,%R2,%0"
1201   [(set_attr "type" "fpop")])
1202
1203 (define_insn ""
1204   [(set (match_operand:DF 0 "register_operand" "=f")
1205         (plus:DF (float_extend:DF
1206                   (match_operand:SF 1 "reg_or_fp0_operand" "%fG"))
1207                  (float_extend:DF
1208                   (match_operand:SF 2 "reg_or_fp0_operand" "fG"))))]
1209   "TARGET_FP"
1210   "addt %R1,%R2,%0"
1211   [(set_attr "type" "fpop")])
1212
1213 (define_insn "fix_truncdfdi2"
1214   [(set (match_operand:DI 0 "register_operand" "=f")
1215         (fix:DI (match_operand:DF 1 "reg_or_fp0_operand" "fG")))]
1216   "TARGET_FP"
1217   "cvttqc %R1,%0"
1218   [(set_attr "type" "fpop")])
1219
1220 (define_insn "fix_truncsfdi2"
1221   [(set (match_operand:DI 0 "register_operand" "=f")
1222         (fix:DI (float_extend:DF
1223                  (match_operand:SF 1 "reg_or_fp0_operand" "fG"))))]
1224   "TARGET_FP"
1225   "cvttqc %R1,%0"
1226   [(set_attr "type" "fpop")])
1227
1228 (define_insn "floatdisf2"
1229   [(set (match_operand:SF 0 "register_operand" "=f")
1230         (float:SF (match_operand:DI 1 "register_operand" "f")))]
1231   "TARGET_FP"
1232   "cvtqs %1,%0"
1233   [(set_attr "type" "fpop")])
1234
1235 (define_insn "floatdidf2"
1236   [(set (match_operand:DF 0 "register_operand" "=f")
1237         (float:DF (match_operand:DI 1 "register_operand" "f")))]
1238   "TARGET_FP"
1239   "cvtqt %1,%0"
1240   [(set_attr "type" "fpop")])
1241
1242 (define_insn "extendsfdf2"
1243   [(set (match_operand:DF 0 "register_operand" "=f,f")
1244         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "f,m")))]
1245   "TARGET_FP"
1246   "@
1247    addt $f31,%1,%0
1248    lds %0,%1"
1249   [(set_attr "type" "fpop,ld")])
1250
1251 (define_insn "truncdfsf2"
1252   [(set (match_operand:SF 0 "register_operand" "=f")
1253         (float_truncate:SF (match_operand:DF 1 "reg_or_fp0_operand" "fG")))]
1254   "TARGET_FP"
1255   "cvtts %R1,%0"
1256   [(set_attr "type" "fpop")])
1257
1258 (define_insn "divsf3"
1259   [(set (match_operand:SF 0 "register_operand" "=f")
1260         (div:SF (match_operand:SF 1 "reg_or_fp0_operand" "fG")
1261                 (match_operand:SF 2 "reg_or_fp0_operand" "fG")))]
1262   "TARGET_FP"
1263   "divs %R1,%R2,%0"
1264   [(set_attr "type" "fdivs")])
1265
1266 (define_insn "divdf3"
1267   [(set (match_operand:DF 0 "register_operand" "=f")
1268         (div:DF (match_operand:DF 1 "reg_or_fp0_operand" "fG")
1269                 (match_operand:DF 2 "reg_or_fp0_operand" "fG")))]
1270   "TARGET_FP"
1271   "divt %R1,%R2,%0"
1272   [(set_attr "type" "fdivt")])
1273
1274 (define_insn ""
1275   [(set (match_operand:DF 0 "register_operand" "=f")
1276         (div:DF (float_extend:DF (match_operand:SF 1 "reg_or_fp0_operand" "fG"))
1277                 (match_operand:DF 2 "reg_or_fp0_operand" "fG")))]
1278   "TARGET_FP"
1279   "divt %R1,%R2,%0"
1280   [(set_attr "type" "fdivt")])
1281
1282 (define_insn ""
1283   [(set (match_operand:DF 0 "register_operand" "=f")
1284         (div:DF (match_operand:DF 1 "reg_or_fp0_operand" "fG")
1285                 (float_extend:DF
1286                  (match_operand:SF 2 "reg_or_fp0_operand" "fG"))))]
1287   "TARGET_FP"
1288   "divt %R1,%R2,%0"
1289   [(set_attr "type" "fdivt")])
1290
1291 (define_insn ""
1292   [(set (match_operand:DF 0 "register_operand" "=f")
1293         (div:DF (float_extend:DF (match_operand:SF 1 "reg_or_fp0_operand" "fG"))
1294                 (float_extend:DF (match_operand:SF 2 "reg_or_fp0_operand" "fG"))))]
1295   "TARGET_FP"
1296   "divt %R1,%R2,%0"
1297   [(set_attr "type" "fdivt")])
1298
1299 (define_insn "mulsf3"
1300   [(set (match_operand:SF 0 "register_operand" "=f")
1301         (mult:SF (match_operand:SF 1 "reg_or_fp0_operand" "%fG")
1302                  (match_operand:SF 2 "reg_or_fp0_operand" "fG")))]
1303   "TARGET_FP"
1304   "muls %R1,%R2,%0"
1305   [(set_attr "type" "fpop")])
1306
1307 (define_insn "muldf3"
1308   [(set (match_operand:DF 0 "register_operand" "=f")
1309         (mult:DF (match_operand:DF 1 "reg_or_fp0_operand" "%fG")
1310                  (match_operand:DF 2 "reg_or_fp0_operand" "fG")))]
1311   "TARGET_FP"
1312   "mult %R1,%R2,%0"
1313   [(set_attr "type" "fpop")])
1314
1315 (define_insn ""
1316   [(set (match_operand:DF 0 "register_operand" "=f")
1317         (mult:DF (float_extend:DF
1318                   (match_operand:SF 1 "reg_or_fp0_operand" "fG"))
1319                  (match_operand:DF 2 "reg_or_fp0_operand" "fG")))]
1320   "TARGET_FP"
1321   "mult %R1,%R2,%0"
1322   [(set_attr "type" "fpop")])
1323
1324 (define_insn ""
1325   [(set (match_operand:DF 0 "register_operand" "=f")
1326         (mult:DF (float_extend:DF
1327                   (match_operand:SF 1 "reg_or_fp0_operand" "%fG"))
1328                  (float_extend:DF
1329                   (match_operand:SF 2 "reg_or_fp0_operand" "fG"))))]
1330   "TARGET_FP"
1331   "mult %R1,%R2,%0"
1332   [(set_attr "type" "fpop")])
1333
1334 (define_insn "subsf3"
1335   [(set (match_operand:SF 0 "register_operand" "=f")
1336         (minus:SF (match_operand:SF 1 "reg_or_fp0_operand" "fG")
1337                   (match_operand:SF 2 "reg_or_fp0_operand" "fG")))]
1338   "TARGET_FP"
1339   "subs %R1,%R2,%0"
1340   [(set_attr "type" "fpop")])
1341
1342 (define_insn "subdf3"
1343   [(set (match_operand:DF 0 "register_operand" "=f")
1344         (minus:DF (match_operand:DF 1 "reg_or_fp0_operand" "fG")
1345                   (match_operand:DF 2 "reg_or_fp0_operand" "fG")))]
1346   "TARGET_FP"
1347   "subt %R1,%R2,%0"
1348   [(set_attr "type" "fpop")])
1349
1350 (define_insn ""
1351   [(set (match_operand:DF 0 "register_operand" "=f")
1352         (minus:DF (float_extend:DF
1353                    (match_operand:SF 1 "reg_or_fp0_operand" "fG"))
1354                   (match_operand:DF 2 "reg_or_fp0_operand" "fG")))]
1355   "TARGET_FP"
1356   "subt %R1,%R2,%0"
1357   [(set_attr "type" "fpop")])
1358
1359 (define_insn ""
1360   [(set (match_operand:DF 0 "register_operand" "=f")
1361         (minus:DF (match_operand:DF 1 "reg_or_fp0_operand" "fG")
1362                   (float_extend:DF
1363                    (match_operand:SF 2 "reg_or_fp0_operand" "fG"))))]
1364   "TARGET_FP"
1365   "subt %R1,%R2,%0"
1366   [(set_attr "type" "fpop")])
1367
1368 (define_insn ""
1369   [(set (match_operand:DF 0 "register_operand" "=f")
1370         (minus:DF (float_extend:DF
1371                    (match_operand:SF 1 "reg_or_fp0_operand" "fG"))
1372                   (float_extend:DF
1373                    (match_operand:SF 2 "reg_or_fp0_operand" "fG"))))]
1374   "TARGET_FP"
1375   "subt %R1,%R2,%0"
1376   [(set_attr "type" "fpop")])
1377 \f
1378 ;; Next are all the integer comparisons, and conditional moves and branches
1379 ;; and some of the related define_expand's and define_split's.
1380
1381 (define_insn ""
1382   [(set (match_operand:DI 0 "register_operand" "=r")
1383         (match_operator:DI 1 "alpha_comparison_operator"
1384                            [(match_operand:DI 2 "reg_or_0_operand" "rJ")
1385                             (match_operand:DI 3 "reg_or_8bit_operand" "rI")]))]
1386   ""
1387   "cmp%C1 %r2,%3,%0"
1388   [(set_attr "type" "icmp")])
1389
1390 ;; There are three important special-case that don't fit the above pattern
1391 ;; but which we want to handle here.
1392
1393 (define_insn ""
1394   [(set (match_operand:DI 0 "register_operand" "=r")
1395         (ne:DI (match_operand:DI 1 "register_operand" "r")
1396                (const_int 0)))]
1397   ""
1398   "cmpult $31,%1,%0"
1399   [(set_attr "type" "icmp")])
1400
1401 (define_insn ""
1402   [(set (match_operand:DI 0 "register_operand" "=r")
1403         (gt:DI (match_operand:DI 1 "register_operand" "r")
1404                (const_int 0)))]
1405   ""
1406   "cmplt $31,%1,%0"
1407   [(set_attr "type" "icmp")])
1408
1409 (define_insn ""
1410   [(set (match_operand:DI 0 "register_operand" "=r")
1411         (ge:DI (match_operand:DI 1 "register_operand" "r")
1412                (const_int 0)))]
1413   ""
1414   "cmple $31,%1,%0"
1415   [(set_attr "type" "icmp")])
1416
1417 ;; This pattern exists so conditional moves of SImode values are handled.
1418 ;; Comparisons are still done in DImode though.
1419
1420 (define_insn ""
1421   [(set (match_operand:SI 0 "register_operand" "=r,r,r,r")
1422         (if_then_else:DI
1423          (match_operator 2 "signed_comparison_operator"
1424                          [(match_operand:DI 3 "reg_or_0_operand" "rJ,rJ,J,J")
1425                           (match_operand:DI 4 "reg_or_0_operand" "J,J,rJ,rJ")])
1426          (match_operand:SI 1 "reg_or_8bit_operand" "rI,0,rI,0")
1427          (match_operand:SI 5 "reg_or_8bit_operand" "0,rI,0,rI")))]
1428   "operands[3] == const0_rtx || operands[4] == const0_rtx"
1429   "@
1430    cmov%C2 %r3,%1,%0
1431    cmov%D2 %r3,%5,%0
1432    cmov%c2 %r4,%1,%0
1433    cmov%d2 %r4,%5,%0")
1434
1435 (define_insn ""
1436   [(set (match_operand:DI 0 "register_operand" "=r,r,r,r")
1437         (if_then_else:DI
1438          (match_operator 2 "signed_comparison_operator"
1439                          [(match_operand:DI 3 "reg_or_0_operand" "rJ,rJ,J,J")
1440                           (match_operand:DI 4 "reg_or_0_operand" "J,J,rJ,rJ")])
1441          (match_operand:DI 1 "reg_or_8bit_operand" "rI,0,rI,0")
1442          (match_operand:DI 5 "reg_or_8bit_operand" "0,rI,0,rI")))]
1443   "operands[3] == const0_rtx || operands[4] == const0_rtx"
1444   "@
1445    cmov%C2 %r3,%1,%0
1446    cmov%D2 %r3,%5,%0
1447    cmov%c2 %r4,%1,%0
1448    cmov%d2 %r4,%5,%0")
1449
1450 (define_insn ""
1451   [(set (match_operand:DI 0 "register_operand" "=r,r")
1452         (if_then_else:DI
1453          (eq (zero_extract:DI (match_operand:DI 2 "reg_or_0_operand" "rJ,rJ")
1454                               (const_int 1)
1455                               (const_int 0))
1456              (const_int 0))
1457          (match_operand:DI 1 "reg_or_8bit_operand" "rI,0")
1458          (match_operand:DI 3 "reg_or_8bit_operand" "0,rI")))]
1459   ""
1460   "@
1461    cmovlbc %r2,%1,%0
1462    cmovlbs %r2,%3,%0")
1463
1464 (define_insn ""
1465   [(set (match_operand:DI 0 "register_operand" "=r,r")
1466         (if_then_else:DI
1467          (ne (zero_extract:DI (match_operand:DI 2 "reg_or_0_operand" "rJ,rJ")
1468                               (const_int 1)
1469                               (const_int 0))
1470              (const_int 0))
1471          (match_operand:DI 1 "reg_or_8bit_operand" "rI,0")
1472          (match_operand:DI 3 "reg_or_8bit_operand" "0,rI")))]
1473   ""
1474   "@
1475    cmovlbs %r2,%1,%0
1476    cmovlbc %r2,%3,%0")
1477
1478 ;; This form is added since combine thinks that an IF_THEN_ELSE with both
1479 ;; arms constant is a single insn, so it won't try to form it if combine
1480 ;; knows they are really two insns.  This occurs in divides by powers
1481 ;; of two.
1482
1483 (define_insn ""
1484   [(set (match_operand:DI 0 "register_operand" "=r")
1485         (if_then_else:DI
1486          (match_operator 2 "signed_comparison_operator"
1487                          [(match_operand:DI 3 "reg_or_0_operand" "rJ")
1488                           (const_int 0)])
1489          (plus:DI (match_dup 0)
1490                   (match_operand:DI 1 "reg_or_8bit_operand" "rI"))
1491          (match_dup 0)))
1492    (clobber (match_scratch:DI 4 "=&r"))]
1493   ""
1494   "addq %0,%1,%4\;cmov%C2 %r3,%4,%0")
1495
1496 (define_split
1497   [(set (match_operand:DI 0 "register_operand" "")
1498         (if_then_else:DI
1499          (match_operator 2 "signed_comparison_operator"
1500                          [(match_operand:DI 3 "reg_or_0_operand" "")
1501                           (const_int 0)])
1502          (plus:DI (match_dup 0)
1503                   (match_operand:DI 1 "reg_or_8bit_operand" ""))
1504          (match_dup 0)))
1505    (clobber (match_operand:DI 4 "register_operand" ""))]
1506   ""
1507   [(set (match_dup 4) (plus:DI (match_dup 0) (match_dup 1)))
1508    (set (match_dup 0) (if_then_else:DI (match_op_dup 2
1509                                                      [(match_dup 3)
1510                                                       (const_int 0)])
1511                                        (match_dup 4) (match_dup 0)))]
1512   "")
1513
1514 (define_split
1515   [(parallel
1516     [(set (match_operand:DI 0 "register_operand" "")
1517           (if_then_else:DI
1518            (match_operator 1 "comparison_operator"
1519                            [(zero_extract:DI (match_operand:DI 2 "register_operand" "")
1520                                              (const_int 1)
1521                                              (match_operand:DI 3 "const_int_operand" ""))
1522                             (const_int 0)])
1523            (match_operand:DI 4 "reg_or_8bit_operand" "")
1524            (match_operand:DI 5 "reg_or_8bit_operand" "")))
1525      (clobber (match_operand:DI 6 "register_operand" ""))])]
1526   "INTVAL (operands[3]) != 0"
1527   [(set (match_dup 6)
1528         (lshiftrt:DI (match_dup 2) (match_dup 3)))
1529    (set (match_dup 0)
1530         (if_then_else:DI (match_op_dup 1
1531                                        [(zero_extract:DI (match_dup 6)
1532                                                          (const_int 1)
1533                                                          (const_int 0))
1534                                         (const_int 0)])
1535                          (match_dup 4)
1536                          (match_dup 5)))]
1537   "")
1538
1539 ;; For ABS, we have two choices, depending on whether the input and output
1540 ;; registers are the same or not.
1541 (define_expand "absdi2"
1542   [(set (match_operand:DI 0 "register_operand" "")
1543         (abs:DI (match_operand:DI 1 "register_operand" "")))]
1544   ""
1545   "
1546 { if (rtx_equal_p (operands[0], operands[1]))
1547     emit_insn (gen_absdi2_same (operands[0], gen_reg_rtx (DImode)));
1548   else
1549     emit_insn (gen_absdi2_diff (operands[0], operands[1]));
1550
1551   DONE;
1552 }")
1553
1554 (define_expand "absdi2_same"
1555   [(set (match_operand:DI 1 "register_operand" "")
1556         (neg:DI (match_operand:DI 0 "register_operand" "")))
1557    (set (match_dup 0)
1558         (if_then_else:DI (ge (match_dup 0) (const_int 0))
1559                          (match_dup 0)
1560                          (match_dup 1)))]
1561   ""
1562   "")
1563
1564 (define_expand "absdi2_diff"
1565   [(set (match_operand:DI 0 "register_operand" "")
1566         (neg:DI (match_operand:DI 1 "register_operand" "")))
1567    (set (match_dup 0)
1568         (if_then_else:DI (lt (match_dup 1) (const_int 0))
1569                          (match_dup 0)
1570                          (match_dup 1)))]
1571   ""
1572   "")
1573
1574 (define_split
1575   [(set (match_operand:DI 0 "register_operand" "")
1576         (abs:DI (match_dup 0)))
1577    (clobber (match_operand:DI 2 "register_operand" ""))]
1578   ""
1579   [(set (match_dup 1) (neg:DI (match_dup 0)))
1580    (set (match_dup 0) (if_then_else:DI (ge (match_dup 0) (const_int 0))
1581                                        (match_dup 0) (match_dup 1)))]
1582   "")
1583
1584 (define_split
1585   [(set (match_operand:DI 0 "register_operand" "")
1586         (abs:DI (match_operand:DI 1 "register_operand" "")))]
1587   "! rtx_equal_p (operands[0], operands[1])"
1588   [(set (match_dup 0) (neg:DI (match_dup 1)))
1589    (set (match_dup 0) (if_then_else:DI (lt (match_dup 1) (const_int 0))
1590                                        (match_dup 0) (match_dup 1)))]
1591   "")
1592
1593 (define_split
1594   [(set (match_operand:DI 0 "register_operand" "")
1595         (neg:DI (abs:DI (match_dup 0))))
1596    (clobber (match_operand:DI 2 "register_operand" ""))]
1597   ""
1598   [(set (match_dup 1) (neg:DI (match_dup 0)))
1599    (set (match_dup 0) (if_then_else:DI (le (match_dup 0) (const_int 0))
1600                                        (match_dup 0) (match_dup 1)))]
1601   "")
1602
1603 (define_split
1604   [(set (match_operand:DI 0 "register_operand" "")
1605         (neg:DI (abs:DI (match_operand:DI 1 "register_operand" ""))))]
1606   "! rtx_equal_p (operands[0], operands[1])"
1607   [(set (match_dup 0) (neg:DI (match_dup 1)))
1608    (set (match_dup 0) (if_then_else:DI (gt (match_dup 1) (const_int 0))
1609                                        (match_dup 0) (match_dup 1)))]
1610   "")
1611
1612 (define_expand "smaxdi3"
1613   [(set (match_dup 3)
1614         (le:DI (match_operand:DI 1 "reg_or_0_operand" "")
1615                (match_operand:DI 2 "reg_or_8bit_operand" "")))
1616    (set (match_operand:DI 0 "register_operand" "")
1617         (if_then_else:DI (eq (match_dup 3) (const_int 0))
1618                          (match_dup 1) (match_dup 2)))]
1619   ""
1620   "
1621 { operands[3] = gen_reg_rtx (DImode);
1622 }")
1623
1624 (define_split
1625   [(set (match_operand:DI 0 "register_operand" "")
1626         (smax:DI (match_operand:DI 1 "reg_or_0_operand" "")
1627                  (match_operand:DI 2 "reg_or_8bit_operand" "")))
1628    (clobber (match_operand:DI 3 "register_operand" ""))]
1629   "operands[2] != const0_rtx"
1630   [(set (match_dup 3) (le:DI (match_dup 1) (match_dup 2)))
1631    (set (match_dup 0) (if_then_else:DI (eq (match_dup 3) (const_int 0))
1632                                        (match_dup 1) (match_dup 2)))]
1633   "")
1634
1635 (define_insn ""
1636   [(set (match_operand:DI 0 "register_operand" "=r")
1637         (smax:DI (match_operand:DI 1 "register_operand" "0")
1638                  (const_int 0)))]
1639   ""
1640   "cmovlt %0,0,%0")
1641
1642 (define_expand "smindi3"
1643   [(set (match_dup 3)
1644         (lt:DI (match_operand:DI 1 "reg_or_0_operand" "")
1645                (match_operand:DI 2 "reg_or_8bit_operand" "")))
1646    (set (match_operand:DI 0 "register_operand" "")
1647         (if_then_else:DI (ne (match_dup 3) (const_int 0))
1648                          (match_dup 1) (match_dup 2)))]
1649   ""
1650   "
1651 { operands[3] = gen_reg_rtx (DImode);
1652 }")
1653
1654 (define_split
1655   [(set (match_operand:DI 0 "register_operand" "")
1656         (smin:DI (match_operand:DI 1 "reg_or_0_operand" "")
1657                  (match_operand:DI 2 "reg_or_8bit_operand" "")))
1658    (clobber (match_operand:DI 3 "register_operand" ""))]
1659   "operands[2] != const0_rtx"
1660   [(set (match_dup 3) (lt:DI (match_dup 1) (match_dup 2)))
1661    (set (match_dup 0) (if_then_else:DI (ne (match_dup 3) (const_int 0))
1662                                        (match_dup 1) (match_dup 2)))]
1663   "")
1664
1665 (define_insn ""
1666   [(set (match_operand:DI 0 "register_operand" "=r")
1667         (smin:DI (match_operand:DI 1 "register_operand" "0")
1668                  (const_int 0)))]
1669   ""
1670   "cmovgt %0,0,%0")
1671
1672 (define_expand "umaxdi3"
1673   [(set (match_dup 3) 
1674         (leu:DI (match_operand:DI 1 "reg_or_0_operand" "")
1675                 (match_operand:DI 2 "reg_or_8bit_operand" "")))
1676    (set (match_operand:DI 0 "register_operand" "")
1677         (if_then_else:DI (eq (match_dup 3) (const_int 0))
1678                          (match_dup 1) (match_dup 2)))]
1679   ""
1680   "
1681 { operands[3] = gen_reg_rtx (DImode);
1682 }")
1683
1684 (define_split
1685   [(set (match_operand:DI 0 "register_operand" "")
1686         (umax:DI (match_operand:DI 1 "reg_or_0_operand" "")
1687                  (match_operand:DI 2 "reg_or_8bit_operand" "")))
1688    (clobber (match_operand:DI 3 "register_operand" ""))]
1689   "operands[2] != const0_rtx"
1690   [(set (match_dup 3) (leu:DI (match_dup 1) (match_dup 2)))
1691    (set (match_dup 0) (if_then_else:DI (eq (match_dup 3) (const_int 0))
1692                                        (match_dup 1) (match_dup 2)))]
1693   "")
1694
1695 (define_expand "umindi3"
1696   [(set (match_dup 3)
1697         (ltu:DI (match_operand:DI 1 "reg_or_0_operand" "")
1698                 (match_operand:DI 2 "reg_or_8bit_operand" "")))
1699    (set (match_operand:DI 0 "register_operand" "")
1700         (if_then_else:DI (ne (match_dup 3) (const_int 0))
1701                          (match_dup 1) (match_dup 2)))]
1702   ""
1703   "
1704 { operands[3] = gen_reg_rtx (DImode);
1705 }")
1706
1707 (define_split
1708   [(set (match_operand:DI 0 "register_operand" "")
1709         (umin:DI (match_operand:DI 1 "reg_or_0_operand" "")
1710                  (match_operand:DI 2 "reg_or_8bit_operand" "")))
1711    (clobber (match_operand:DI 3 "register_operand" ""))]
1712   "operands[2] != const0_rtx"
1713   [(set (match_dup 3) (ltu:DI (match_dup 1) (match_dup 2)))
1714    (set (match_dup 0) (if_then_else:DI (ne (match_dup 3) (const_int 0))
1715                                        (match_dup 1) (match_dup 2)))]
1716   "")
1717
1718 (define_insn ""
1719   [(set (pc)
1720         (if_then_else
1721          (match_operator 1 "signed_comparison_operator"
1722                          [(match_operand:DI 2 "reg_or_0_operand" "rJ")
1723                           (const_int 0)])
1724          (label_ref (match_operand 0 "" ""))
1725          (pc)))]
1726   ""
1727   "b%C1 %r2,%0"
1728   [(set_attr "type" "ibr")])
1729
1730 (define_insn ""
1731   [(set (pc)
1732         (if_then_else
1733          (ne (zero_extract:DI (match_operand:DI 1 "reg_or_0_operand" "rJ")
1734                               (const_int 1)
1735                               (const_int 0))
1736              (const_int 0))
1737          (label_ref (match_operand 0 "" ""))
1738          (pc)))]
1739   ""
1740   "blbs %r1,%0"
1741   [(set_attr "type" "ibr")])
1742
1743 (define_insn ""
1744   [(set (pc)
1745         (if_then_else
1746          (eq (zero_extract:DI (match_operand:DI 1 "reg_or_0_operand" "rJ")
1747                               (const_int 1)
1748                               (const_int 0))
1749              (const_int 0))
1750          (label_ref (match_operand 0 "" ""))
1751          (pc)))]
1752   ""
1753   "blbc %r1,%0"
1754   [(set_attr "type" "ibr")])
1755
1756 (define_split
1757   [(parallel
1758     [(set (pc)
1759           (if_then_else
1760            (match_operator 1 "comparison_operator"
1761                            [(zero_extract:DI (match_operand:DI 2 "register_operand" "")
1762                                              (const_int 1)
1763                                              (match_operand:DI 3 "const_int_operand" ""))
1764                             (const_int 0)])
1765            (label_ref (match_operand 0 "" ""))
1766            (pc)))
1767      (clobber (match_operand:DI 4 "register_operand" ""))])]
1768   "INTVAL (operands[3]) != 0"
1769   [(set (match_dup 4)
1770         (lshiftrt:DI (match_dup 2) (match_dup 3)))
1771    (set (pc)
1772         (if_then_else (match_op_dup 1
1773                                     [(zero_extract:DI (match_dup 4)
1774                                                       (const_int 1)
1775                                                       (const_int 0))
1776                                      (const_int 0)])
1777                       (label_ref (match_dup 0))
1778                       (pc)))]
1779   "")
1780 \f
1781 ;; The following are the corresponding floating-point insns.  Recall
1782 ;; we need to have variants that expand the arguments from SF mode
1783 ;; to DFmode.
1784
1785 (define_insn ""
1786   [(set (match_operand:DF 0 "register_operand" "=f")
1787         (match_operator:DF 1 "alpha_comparison_operator"
1788                            [(match_operand:DF 2 "reg_or_fp0_operand" "fG")
1789                             (match_operand:DF 3 "reg_or_fp0_operand" "fG")]))]
1790   "TARGET_FP"
1791   "cmpt%C1 %R2,%R3,%0"
1792   [(set_attr "type" "fpop")])
1793
1794 (define_insn ""
1795   [(set (match_operand:DF 0 "register_operand" "=f")
1796         (match_operator:DF 1 "alpha_comparison_operator"
1797                            [(float_extend:DF
1798                              (match_operand:SF 2 "reg_or_fp0_operand" "fG"))
1799                             (match_operand:DF 3 "reg_or_fp0_operand" "fG")]))]
1800   "TARGET_FP"
1801   "cmpt%C1 %R2,%R3,%0"
1802   [(set_attr "type" "fpop")])
1803
1804 (define_insn ""
1805   [(set (match_operand:DF 0 "register_operand" "=f")
1806         (match_operator:DF 1 "alpha_comparison_operator"
1807                            [(match_operand:DF 2 "reg_or_fp0_operand" "fG")
1808                             (float_extend:DF
1809                              (match_operand:SF 3 "reg_or_fp0_operand" "fG"))]))]
1810   "TARGET_FP"
1811   "cmpt%C1 %R2,%R3,%0"
1812   [(set_attr "type" "fpop")])
1813
1814 (define_insn ""
1815   [(set (match_operand:DF 0 "register_operand" "=f")
1816         (match_operator:DF 1 "alpha_comparison_operator"
1817                            [(float_extend:DF
1818                              (match_operand:SF 2 "reg_or_fp0_operand" "fG"))
1819                             (float_extend:DF
1820                              (match_operand:SF 3 "reg_or_fp0_operand" "fG"))]))]
1821   "TARGET_FP"
1822   "cmpt%C1 %R2,%R3,%0"
1823   [(set_attr "type" "fpop")])
1824
1825 (define_insn ""
1826   [(set (match_operand:DF 0 "register_operand" "=f,f")
1827         (if_then_else:DF 
1828          (match_operator 3 "signed_comparison_operator"
1829                          [(match_operand:DF 4 "reg_or_fp0_operand" "fG,fG")
1830                           (match_operand:DF 2 "fp0_operand" "G,G")])
1831          (match_operand:DF 1 "reg_or_fp0_operand" "fG,0")
1832          (match_operand:DF 5 "reg_or_fp0_operand" "0,fG")))]
1833   "TARGET_FP"
1834   "@
1835    fcmov%C3 %R4,%R1,%0
1836    fcmov%D3 %R4,%R5,%0"
1837   [(set_attr "type" "fpop")])
1838
1839 (define_insn ""
1840   [(set (match_operand:SF 0 "register_operand" "=f,f")
1841         (if_then_else:SF 
1842          (match_operator 3 "signed_comparison_operator"
1843                          [(match_operand:DF 4 "reg_or_fp0_operand" "fG,fG")
1844                           (match_operand:DF 2 "fp0_operand" "G,G")])
1845          (match_operand:SF 1 "reg_or_fp0_operand" "fG,0")
1846          (match_operand:SF 5 "reg_or_fp0_operand" "0,fG")))]
1847   "TARGET_FP"
1848   "@
1849    fcmov%C3 %R4,%R1,%0
1850    fcmov%D3 %R4,%R5,%0"
1851   [(set_attr "type" "fpop")])
1852
1853 (define_insn ""
1854   [(set (match_operand:DF 0 "register_operand" "=f,f")
1855         (if_then_else:DF 
1856          (match_operator 3 "signed_comparison_operator"
1857                          [(match_operand:DF 1 "reg_or_fp0_operand" "fG,fG")
1858                           (match_operand:DF 2 "fp0_operand" "G,G")])
1859          (float_extend:DF (match_operand:SF 4 "reg_or_fp0_operand" "fG,0"))
1860          (match_operand:DF 5 "reg_or_fp0_operand" "0,fG")))]
1861   "TARGET_FP"
1862   "@
1863    fcmov%C3 %R4,%R1,%0
1864    fcmov%D3 %R4,%R5,%0"
1865   [(set_attr "type" "fpop")])
1866
1867 (define_insn ""
1868   [(set (match_operand:DF 0 "register_operand" "=f,f")
1869         (if_then_else:DF 
1870          (match_operator 3 "signed_comparison_operator"
1871                          [(float_extend:DF 
1872                            (match_operand:SF 4 "reg_or_fp0_operand" "fG,fG"))
1873                           (match_operand:DF 2 "fp0_operand" "G,G")])
1874          (match_operand:DF 1 "reg_or_fp0_operand" "fG,0")
1875          (match_operand:DF 5 "reg_or_fp0_operand" "0,fG")))]
1876   "TARGET_FP"
1877   "@
1878    fcmov%C3 %R4,%R1,%0
1879    fcmov%D3 %R4,%R5,%0"
1880   [(set_attr "type" "fpop")])
1881
1882 (define_insn ""
1883   [(set (match_operand:SF 0 "register_operand" "=f,f")
1884         (if_then_else:SF 
1885          (match_operator 3 "signed_comparison_operator"
1886                          [(float_extend:DF
1887                            (match_operand:SF 4 "reg_or_fp0_operand" "fG,fG"))
1888                           (match_operand:DF 2 "fp0_operand" "G,G")])
1889          (match_operand:SF 1 "reg_or_fp0_operand" "fG,0")
1890          (match_operand:SF 5 "reg_or_fp0_operand" "0,fG")))]
1891   "TARGET_FP"
1892   "@
1893    fcmov%C3 %R4,%R1,%0
1894    fcmov%D3 %R4,%R5,%0"
1895   [(set_attr "type" "fpop")])
1896
1897 (define_insn ""
1898   [(set (match_operand:DF 0 "register_operand" "=f,f")
1899         (if_then_else:DF 
1900          (match_operator 3 "signed_comparison_operator"
1901                          [(float_extend:DF
1902                            (match_operand:SF 4 "reg_or_fp0_operand" "fG,fG"))
1903                           (match_operand:DF 2 "fp0_operand" "G,G")])
1904          (float_extend:DF (match_operand:SF 1 "reg_or_fp0_operand" "fG,0"))
1905          (match_operand:DF 5 "reg_or_fp0_operand" "0,fG")))]
1906   "TARGET_FP"
1907   "@
1908    fcmov%C3 %R4,%R1,%0
1909    fcmov%D3 %R4,%R5,%0"
1910   [(set_attr "type" "fpop")])
1911
1912 (define_expand "maxdf3"
1913   [(set (match_dup 3)
1914         (le:DF (match_operand:DF 1 "reg_or_fp0_operand" "")
1915                (match_operand:DF 2 "reg_or_fp0_operand" "")))
1916    (set (match_operand:DF 0 "register_operand" "")
1917         (if_then_else:DF (eq (match_dup 3) (match_dup 4))
1918                          (match_dup 1) (match_dup 2)))]
1919   "TARGET_FP"
1920   "
1921 { operands[3] = gen_reg_rtx (DFmode);
1922   operands[4] = CONST0_RTX (DFmode);
1923 }")
1924
1925 (define_expand "mindf3"
1926   [(set (match_dup 3)
1927         (lt:DF (match_operand:DF 1 "reg_or_fp0_operand" "")
1928                (match_operand:DF 2 "reg_or_fp0_operand" "")))
1929    (set (match_operand:DF 0 "register_operand" "")
1930         (if_then_else:DF (ne (match_dup 3) (match_dup 4))
1931                          (match_dup 1) (match_dup 2)))]
1932   "TARGET_FP"
1933   "
1934 { operands[3] = gen_reg_rtx (DFmode);
1935   operands[4] = CONST0_RTX (DFmode);
1936 }")
1937
1938 (define_expand "maxsf3"
1939   [(set (match_dup 3)
1940         (le:DF (float_extend:DF (match_operand:SF 1 "reg_or_fp0_operand" ""))
1941                (float_extend:DF (match_operand:SF 2 "reg_or_fp0_operand" ""))))
1942    (set (match_operand:SF 0 "register_operand" "")
1943         (if_then_else:SF (eq (match_dup 3) (match_dup 4))
1944                          (match_dup 1) (match_dup 2)))]
1945   "TARGET_FP"
1946   "
1947 { operands[3] = gen_reg_rtx (DFmode);
1948   operands[4] = CONST0_RTX (DFmode);
1949 }")
1950
1951 (define_expand "minsf3"
1952   [(set (match_dup 3)
1953         (lt:DF (float_extend:DF (match_operand:SF 1 "reg_or_fp0_operand" ""))
1954                (float_extend:DF (match_operand:SF 2 "reg_or_fp0_operand" ""))))
1955    (set (match_operand:SF 0 "register_operand" "")
1956         (if_then_else:SF (ne (match_dup 3) (match_dup 4))
1957                       (match_dup 1) (match_dup 2)))]
1958   "TARGET_FP"
1959   "
1960 { operands[3] = gen_reg_rtx (DFmode);
1961   operands[4] = CONST0_RTX (DFmode);
1962 }")
1963
1964 (define_insn ""
1965   [(set (pc)
1966         (if_then_else
1967          (match_operator 1 "signed_comparison_operator"
1968                          [(match_operand:DF 2 "reg_or_fp0_operand" "fG")
1969                           (match_operand:DF 3 "fp0_operand" "G")])
1970          (label_ref (match_operand 0 "" ""))
1971          (pc)))]
1972   "TARGET_FP"
1973   "fb%C1 %R2,%0"
1974   [(set_attr "type" "fbr")])
1975
1976 (define_insn ""
1977   [(set (pc)
1978         (if_then_else
1979          (match_operator 1 "signed_comparison_operator"
1980                          [(float_extend:DF
1981                            (match_operand:SF 2 "reg_or_fp0_operand" "fG"))
1982                           (match_operand:DF 3 "fp0_operand" "G")])
1983          (label_ref (match_operand 0 "" ""))
1984          (pc)))]
1985   "TARGET_FP"
1986   "fb%C1 %R2,%0"
1987   [(set_attr "type" "fbr")])
1988 \f
1989 ;; These are the main define_expand's used to make conditional branches
1990 ;; and compares.
1991
1992 (define_expand "cmpdf"
1993   [(set (cc0) (compare (match_operand:DF 0 "reg_or_fp0_operand" "")
1994                        (match_operand:DF 1 "reg_or_fp0_operand" "")))]
1995   "TARGET_FP"
1996   "
1997 {
1998   alpha_compare_op0 = operands[0];
1999   alpha_compare_op1 = operands[1];
2000   alpha_compare_fp_p = 1;
2001   DONE;
2002 }")
2003
2004 (define_expand "cmpdi"
2005   [(set (cc0) (compare (match_operand:DI 0 "reg_or_0_operand" "")
2006                        (match_operand:DI 1 "reg_or_8bit_operand" "")))]
2007   ""
2008   "
2009 {
2010   alpha_compare_op0 = operands[0];
2011   alpha_compare_op1 = operands[1];
2012   alpha_compare_fp_p = 0;
2013   DONE;
2014 }")
2015
2016 (define_expand "beq"
2017   [(set (match_dup 1) (match_dup 2))
2018    (set (pc)
2019         (if_then_else (match_dup 3)
2020                       (label_ref (match_operand 0 "" ""))
2021                       (pc)))]
2022   ""
2023   "
2024 {
2025   enum machine_mode mode;
2026   enum rtx_code compare_code, branch_code;
2027
2028   if (alpha_compare_fp_p)
2029     mode = DFmode, compare_code = EQ, branch_code = NE;
2030   else
2031     {
2032       mode = DImode, compare_code = MINUS, branch_code = EQ;
2033       if (GET_CODE (alpha_compare_op1) == CONST_INT)
2034         {
2035           compare_code = PLUS;
2036           alpha_compare_op1 = GEN_INT (- INTVAL (alpha_compare_op1));
2037         }
2038     }
2039
2040   operands[1] = gen_reg_rtx (mode);
2041   operands[2] = gen_rtx (compare_code, mode,
2042                          alpha_compare_op0, alpha_compare_op1);
2043   operands[3] = gen_rtx (branch_code, VOIDmode,
2044                          operands[1], CONST0_RTX (mode));
2045 }")
2046
2047 (define_expand "bne"
2048   [(set (match_dup 1) (match_dup 2))
2049    (set (pc)
2050         (if_then_else (match_dup 3)
2051                       (label_ref (match_operand 0 "" ""))
2052                       (pc)))]
2053   ""
2054   "
2055 {
2056   enum machine_mode mode;
2057   enum rtx_code compare_code, branch_code;
2058
2059   if (alpha_compare_fp_p)
2060     mode = DFmode, compare_code = EQ, branch_code = EQ;
2061   else
2062     {
2063       mode = DImode, compare_code = MINUS, branch_code = NE;
2064       if (GET_CODE (alpha_compare_op1) == CONST_INT)
2065         {
2066           compare_code = PLUS;
2067           alpha_compare_op1 = GEN_INT (- INTVAL (alpha_compare_op1));
2068         }
2069     }
2070
2071   operands[1] = gen_reg_rtx (mode);
2072   operands[2] = gen_rtx (compare_code, mode,
2073                          alpha_compare_op0, alpha_compare_op1);
2074   operands[3] = gen_rtx (branch_code, VOIDmode,
2075                          operands[1], CONST0_RTX (mode));
2076 }")
2077
2078 (define_expand "blt"
2079   [(set (match_dup 1) (match_dup 2))
2080    (set (pc)
2081         (if_then_else (match_dup 3)
2082                       (label_ref (match_operand 0 "" ""))
2083                       (pc)))]
2084   ""
2085   "
2086 {
2087   enum machine_mode mode = alpha_compare_fp_p ? DFmode : DImode;
2088   operands[1] = gen_reg_rtx (mode);
2089   operands[2] = gen_rtx (LT, mode, alpha_compare_op0, alpha_compare_op1);
2090   operands[3] = gen_rtx (NE, VOIDmode, operands[1], CONST0_RTX (mode));
2091 }")
2092
2093 (define_expand "ble"
2094   [(set (match_dup 1) (match_dup 2))
2095    (set (pc)
2096         (if_then_else (match_dup 3)
2097                       (label_ref (match_operand 0 "" ""))
2098                       (pc)))]
2099   ""
2100   "
2101 {
2102   enum machine_mode mode = alpha_compare_fp_p ? DFmode : DImode;
2103   operands[1] = gen_reg_rtx (mode);
2104   operands[2] = gen_rtx (LE, mode, alpha_compare_op0, alpha_compare_op1);
2105   operands[3] = gen_rtx (NE, VOIDmode, operands[1], CONST0_RTX (mode));
2106 }")
2107
2108 (define_expand "bgt"
2109   [(set (match_dup 1) (match_dup 2))
2110    (set (pc)
2111         (if_then_else (match_dup 3)
2112                       (label_ref (match_operand 0 "" ""))
2113                       (pc)))]
2114   ""
2115   "
2116 {
2117   if (alpha_compare_fp_p)
2118     {
2119       operands[1] = gen_reg_rtx (DFmode);
2120       operands[2] = gen_rtx (LT, DFmode, alpha_compare_op1, alpha_compare_op0);
2121       operands[3] = gen_rtx (NE, VOIDmode, operands[1], CONST0_RTX (DFmode));
2122     }
2123   else
2124     {
2125       operands[1] = gen_reg_rtx (DImode);
2126       operands[2] = gen_rtx (LE, DImode, alpha_compare_op0, alpha_compare_op1);
2127       operands[3] = gen_rtx (EQ, VOIDmode, operands[1], const0_rtx);
2128     }
2129 }")
2130
2131 (define_expand "bge"
2132   [(set (match_dup 1) (match_dup 2))
2133    (set (pc)
2134         (if_then_else (match_dup 3)
2135                       (label_ref (match_operand 0 "" ""))
2136                       (pc)))]
2137   ""
2138   "
2139 {
2140   if (alpha_compare_fp_p)
2141     {
2142       operands[1] = gen_reg_rtx (DFmode);
2143       operands[2] = gen_rtx (LE, DFmode, alpha_compare_op1, alpha_compare_op0);
2144       operands[3] = gen_rtx (NE, VOIDmode, operands[1], CONST0_RTX (DFmode));
2145     }
2146   else
2147     {
2148       operands[1] = gen_reg_rtx (DImode);
2149       operands[2] = gen_rtx (LT, DImode, alpha_compare_op0, alpha_compare_op1);
2150       operands[3] = gen_rtx (EQ, VOIDmode, operands[1], const0_rtx);
2151     }
2152 }")
2153
2154 (define_expand "bltu"
2155   [(set (match_dup 1) (match_dup 2))
2156    (set (pc)
2157         (if_then_else (match_dup 3)
2158                       (label_ref (match_operand 0 "" ""))
2159                       (pc)))]
2160   ""
2161   "
2162 {
2163   operands[1] = gen_reg_rtx (DImode);
2164   operands[2] = gen_rtx (LTU, DImode, alpha_compare_op0, alpha_compare_op1);
2165   operands[3] = gen_rtx (NE, VOIDmode, operands[1], const0_rtx);
2166 }")
2167
2168 (define_expand "bleu"
2169   [(set (match_dup 1) (match_dup 2))
2170    (set (pc)
2171         (if_then_else (match_dup 3)
2172                       (label_ref (match_operand 0 "" ""))
2173                       (pc)))]
2174   ""
2175   "
2176 {
2177   operands[1] = gen_reg_rtx (DImode);
2178   operands[2] = gen_rtx (LEU, DImode, alpha_compare_op0, alpha_compare_op1);
2179   operands[3] = gen_rtx (NE, VOIDmode, operands[1], const0_rtx);
2180 }")
2181
2182 (define_expand "bgtu"
2183   [(set (match_dup 1) (match_dup 2))
2184    (set (pc)
2185         (if_then_else (match_dup 3)
2186                       (label_ref (match_operand 0 "" ""))
2187                       (pc)))]
2188   ""
2189   "
2190 {
2191   operands[1] = gen_reg_rtx (DImode);
2192   operands[2] = gen_rtx (LEU, DImode, alpha_compare_op0, alpha_compare_op1);
2193   operands[3] = gen_rtx (EQ, VOIDmode, operands[1], const0_rtx);
2194 }")
2195
2196 (define_expand "bgeu"
2197   [(set (match_dup 1) (match_dup 2))
2198    (set (pc)
2199         (if_then_else (match_dup 3)
2200                       (label_ref (match_operand 0 "" ""))
2201                       (pc)))]
2202   ""
2203   "
2204 {
2205   operands[1] = gen_reg_rtx (DImode);
2206   operands[2] = gen_rtx (LTU, DImode, alpha_compare_op0, alpha_compare_op1);
2207   operands[3] = gen_rtx (EQ, VOIDmode, operands[1], const0_rtx);
2208 }")
2209
2210 (define_expand "seq"
2211   [(set (match_operand:DI 0 "register_operand" "")
2212         (match_dup 1))]
2213   ""
2214   "
2215 {
2216   if (alpha_compare_fp_p)
2217     FAIL;
2218
2219   operands[1] = gen_rtx (EQ, DImode, alpha_compare_op0, alpha_compare_op1);
2220 }")
2221
2222 (define_expand "sne"
2223   [(set (match_operand:DI 0 "register_operand" "")
2224         (match_dup 1))
2225    (set (match_dup 0) (xor:DI (match_dup 0) (const_int 1)))]
2226   ""
2227   "
2228 {
2229   if (alpha_compare_fp_p)
2230     FAIL;
2231
2232   operands[1] = gen_rtx (EQ, DImode, alpha_compare_op0, alpha_compare_op1);
2233 }")
2234
2235 (define_expand "slt"
2236   [(set (match_operand:DI 0 "register_operand" "")
2237         (match_dup 1))]
2238   ""
2239   "
2240 {
2241   if (alpha_compare_fp_p)
2242     FAIL;
2243
2244   operands[1] = gen_rtx (LT, DImode, alpha_compare_op0, alpha_compare_op1);
2245 }")
2246
2247 (define_expand "sle"
2248   [(set (match_operand:DI 0 "register_operand" "")
2249         (match_dup 1))]
2250   ""
2251   "
2252 {
2253   if (alpha_compare_fp_p)
2254     FAIL;
2255
2256   operands[1] = gen_rtx (LE, DImode, alpha_compare_op0, alpha_compare_op1);
2257 }")
2258
2259 (define_expand "sgt"
2260   [(set (match_operand:DI 0 "register_operand" "")
2261         (match_dup 1))]
2262   ""
2263   "
2264 {
2265   if (alpha_compare_fp_p)
2266     FAIL;
2267
2268   operands[1] = gen_rtx (LT, DImode, force_reg (DImode, alpha_compare_op1),
2269                          alpha_compare_op0);
2270 }")
2271
2272 (define_expand "sge"
2273   [(set (match_operand:DI 0 "register_operand" "")
2274         (match_dup 1))]
2275   ""
2276   "
2277 {
2278   if (alpha_compare_fp_p)
2279     FAIL;
2280
2281   operands[1] = gen_rtx (LE, DImode, force_reg (DImode, alpha_compare_op1),
2282                          alpha_compare_op0);
2283 }")
2284
2285 (define_expand "sltu"
2286   [(set (match_operand:DI 0 "register_operand" "")
2287         (match_dup 1))]
2288   ""
2289   "
2290 {
2291   if (alpha_compare_fp_p)
2292     FAIL;
2293
2294   operands[1] = gen_rtx (LTU, DImode, alpha_compare_op0, alpha_compare_op1);
2295 }")
2296
2297 (define_expand "sleu"
2298   [(set (match_operand:DI 0 "register_operand" "")
2299         (match_dup 1))]
2300   ""
2301   "
2302 {
2303   if (alpha_compare_fp_p)
2304     FAIL;
2305
2306   operands[1] = gen_rtx (LEU, DImode, alpha_compare_op0, alpha_compare_op1);
2307 }")
2308
2309 (define_expand "sgtu"
2310   [(set (match_operand:DI 0 "register_operand" "")
2311         (match_dup 1))]
2312   ""
2313   "
2314 {
2315   if (alpha_compare_fp_p)
2316     FAIL;
2317
2318   operands[1] = gen_rtx (LTU, DImode, force_reg (DImode, alpha_compare_op1),
2319                          alpha_compare_op0);
2320 }")
2321
2322 (define_expand "sgeu"
2323   [(set (match_operand:DI 0 "register_operand" "")
2324         (match_dup 1))]
2325   ""
2326   "
2327 {
2328   if (alpha_compare_fp_p)
2329     FAIL;
2330
2331   operands[1] = gen_rtx (LEU, DImode, force_reg (DImode, alpha_compare_op1),
2332                          alpha_compare_op0);
2333 }")
2334 \f
2335 ;; These are the main define_expand's used to make conditional moves.
2336
2337 (define_expand "movsicc"
2338   [(set (match_dup 4) (match_operand 1 "comparison_operator" ""))
2339    (set (match_operand:SI 0 "register_operand" "")
2340         (if_then_else:DI (match_dup 5)
2341                          (match_operand:SI 2 "reg_or_8bit_operand" "")
2342                          (match_operand:SI 3 "reg_or_8bit_operand" "")))]
2343   ""
2344   "
2345 {
2346   rtx op0,op1;
2347   enum rtx_code code = GET_CODE (operands[1]), code2 = NE;
2348
2349   if (alpha_compare_fp_p)
2350     FAIL;
2351   switch (code)
2352     {
2353     case EQ: case LE: case LT:
2354       op0 = alpha_compare_op0;
2355       op1 = alpha_compare_op1;
2356       break;
2357     case NE:
2358       code = code2 = EQ;
2359       op0 = alpha_compare_op0;
2360       op1 = alpha_compare_op1;
2361       break;
2362     case GE:
2363       code = LE;
2364       op0 = force_reg (DImode, alpha_compare_op1);
2365       op1 = alpha_compare_op0;
2366       break;
2367     case GT:
2368       code = LT;
2369       op0 = force_reg (DImode, alpha_compare_op1);
2370       op1 = alpha_compare_op0;
2371       break;
2372     default:
2373       FAIL;
2374     }
2375   operands[1] = gen_rtx (code, DImode, op0, op1);
2376   operands[4] = gen_reg_rtx (DImode);
2377   operands[5] = gen_rtx (code2, VOIDmode, operands[4], CONST0_RTX (DImode));
2378 }")
2379
2380 (define_expand "movdicc"
2381   [(set (match_dup 4) (match_operand 1 "comparison_operator" ""))
2382    (set (match_operand:DI 0 "register_operand" "")
2383         (if_then_else:DI (match_dup 5)
2384                          (match_operand:DI 2 "reg_or_8bit_operand" "")
2385                          (match_operand:DI 3 "reg_or_8bit_operand" "")))]
2386   ""
2387   "
2388 {
2389   rtx op0,op1;
2390   enum rtx_code code = GET_CODE (operands[1]), code2 = NE;
2391
2392   if (alpha_compare_fp_p)
2393     FAIL;
2394   switch (code)
2395     {
2396     case EQ: case LE: case LT:
2397       op0 = alpha_compare_op0;
2398       op1 = alpha_compare_op1;
2399       break;
2400     case NE:
2401       code = code2 = EQ;
2402       op0 = alpha_compare_op0;
2403       op1 = alpha_compare_op1;
2404       break;
2405     case GE:
2406       code = LE;
2407       op0 = force_reg (DImode, alpha_compare_op1);
2408       op1 = alpha_compare_op0;
2409       break;
2410     case GT:
2411       code = LT;
2412       op0 = force_reg (DImode, alpha_compare_op1);
2413       op1 = alpha_compare_op0;
2414       break;
2415     default:
2416       FAIL;
2417     }
2418   operands[1] = gen_rtx (code, DImode, op0, op1);
2419   operands[4] = gen_reg_rtx (DImode);
2420   operands[5] = gen_rtx (code2, VOIDmode, operands[4], CONST0_RTX (DImode));
2421 }")
2422
2423 (define_expand "movsfcc"
2424   [(set (match_dup 4) (match_operand 1 "comparison_operator" ""))
2425    (set (match_operand:SF 0 "register_operand" "")
2426         (if_then_else:SF (match_dup 5)
2427                          (match_operand:SF 2 "reg_or_fp0_operand" "")
2428                          (match_operand:SF 3 "reg_or_fp0_operand" "")))]
2429   ""
2430   "
2431 {
2432   rtx op0,op1;
2433   enum rtx_code code = GET_CODE (operands[1]), code2 = NE;
2434
2435   if (!alpha_compare_fp_p)
2436     FAIL;
2437   switch (code)
2438     {
2439     case EQ: case LE: case LT:
2440       op0 = alpha_compare_op0;
2441       op1 = alpha_compare_op1;
2442       break;
2443     case NE:
2444       /* There isn't a cmptne insn.  */
2445       code = code2 = EQ;
2446       op0 = alpha_compare_op0;
2447       op1 = alpha_compare_op1;
2448       break;
2449     case GE:
2450       code = LE;
2451       op0 = force_reg (DFmode, alpha_compare_op1);
2452       op1 = alpha_compare_op0;
2453       break;
2454     case GT:
2455       code = LT;
2456       op0 = force_reg (DFmode, alpha_compare_op1);
2457       op1 = alpha_compare_op0;
2458       break;
2459     default:
2460       FAIL;
2461     }
2462   operands[1] = gen_rtx (code, DFmode, op0, op1);
2463   operands[4] = gen_reg_rtx (DFmode);
2464   operands[5] = gen_rtx (code2, VOIDmode, operands[4], CONST0_RTX (DFmode));
2465 }")
2466
2467 (define_expand "movdfcc"
2468   [(set (match_dup 4) (match_operand 1 "comparison_operator" ""))
2469    (set (match_operand:DF 0 "register_operand" "")
2470         (if_then_else:DF (match_dup 5)
2471                          (match_operand:DF 2 "reg_or_fp0_operand" "")
2472                          (match_operand:DF 3 "reg_or_fp0_operand" "")))]
2473   ""
2474   "
2475 {
2476   rtx op0,op1;
2477   enum rtx_code code = GET_CODE (operands[1]), code2 = NE;
2478
2479   if (!alpha_compare_fp_p)
2480     FAIL;
2481   switch (code)
2482     {
2483     case EQ: case LE: case LT:
2484       op0 = alpha_compare_op0;
2485       op1 = alpha_compare_op1;
2486       break;
2487     case NE:
2488       /* There isn't a cmptne insn.  */
2489       code = code2 = EQ;
2490       op0 = alpha_compare_op0;
2491       op1 = alpha_compare_op1;
2492       break;
2493     case GE:
2494       code = LE;
2495       op0 = force_reg (DFmode, alpha_compare_op1);
2496       op1 = alpha_compare_op0;
2497       break;
2498     case GT:
2499       code = LT;
2500       op0 = force_reg (DFmode, alpha_compare_op1);
2501       op1 = alpha_compare_op0;
2502       break;
2503     default:
2504       FAIL;
2505     }
2506   operands[1] = gen_rtx (code, DFmode, op0, op1);
2507   operands[4] = gen_reg_rtx (DFmode);
2508   operands[5] = gen_rtx (code2, VOIDmode, operands[4], CONST0_RTX (DFmode));
2509 }")
2510 \f
2511 ;; These define_split definitions are used in cases when comparisons have
2512 ;; not be stated in the correct way and we need to reverse the second
2513 ;; comparison.  For example, x >= 7 has to be done as x < 6 with the
2514 ;; comparison that tests the result being reversed.  We have one define_split
2515 ;; for each use of a comparison.  They do not match valid insns and need
2516 ;; not generate valid insns.
2517 ;;
2518 ;; We can also handle equality comparisons (and inequality comparisons in
2519 ;; cases where the resulting add cannot overflow) by doing an add followed by
2520 ;; a comparison with zero.  This is faster since the addition takes one
2521 ;; less cycle than a compare when feeding into a conditional move.
2522 ;; For this case, we also have an SImode pattern since we can merge the add
2523 ;; and sign extend and the order doesn't matter.
2524 ;;
2525 ;; We do not do this for floating-point, since it isn't clear how the "wrong"
2526 ;; operation could have been generated.
2527
2528 (define_split
2529   [(set (match_operand:DI 0 "register_operand" "")
2530         (if_then_else:DI
2531          (match_operator 1 "comparison_operator"
2532                          [(match_operand:DI 2 "reg_or_0_operand" "")
2533                           (match_operand:DI 3 "reg_or_cint_operand" "")])
2534          (match_operand:DI 4 "reg_or_cint_operand" "")
2535          (match_operand:DI 5 "reg_or_cint_operand" "")))
2536    (clobber (match_operand:DI 6 "register_operand" ""))]
2537   "operands[3] != const0_rtx"
2538   [(set (match_dup 6) (match_dup 7))
2539    (set (match_dup 0)
2540         (if_then_else:DI (match_dup 8) (match_dup 4) (match_dup 5)))]
2541   "
2542 { enum rtx_code code = GET_CODE (operands[1]);
2543   int unsignedp = (code == GEU || code == LEU || code == GTU || code == LTU);
2544
2545   /* If we are comparing for equality with a constant and that constant
2546      appears in the arm when the register equals the constant, use the
2547      register since that is more likely to match (and to produce better code
2548      if both would).  */
2549
2550   if (code == EQ && GET_CODE (operands[3]) == CONST_INT
2551       && rtx_equal_p (operands[4], operands[3]))
2552     operands[4] = operands[2];
2553
2554   else if (code == NE && GET_CODE (operands[3]) == CONST_INT
2555            && rtx_equal_p (operands[5], operands[3]))
2556     operands[5] = operands[2];
2557
2558   if (code == NE || code == EQ
2559       || (extended_count (operands[2], DImode, unsignedp) >= 1
2560           && extended_count (operands[3], DImode, unsignedp) >= 1))
2561     {
2562       if (GET_CODE (operands[3]) == CONST_INT)
2563         operands[7] = gen_rtx (PLUS, DImode, operands[2],
2564                                GEN_INT (- INTVAL (operands[3])));
2565       else
2566         operands[7] = gen_rtx (MINUS, DImode, operands[2], operands[3]);
2567
2568       operands[8] = gen_rtx (code, VOIDmode, operands[6], const0_rtx);
2569     }
2570
2571   else if (code == EQ || code == LE || code == LT
2572            || code == LEU || code == LTU)
2573     {
2574       operands[7] = gen_rtx (code, DImode, operands[2], operands[3]);
2575       operands[8] = gen_rtx (NE, VOIDmode, operands[6], const0_rtx);
2576     }
2577   else
2578     {
2579       operands[7] = gen_rtx (reverse_condition (code), DImode, operands[2],
2580                              operands[3]);
2581       operands[8] = gen_rtx (EQ, VOIDmode, operands[6], const0_rtx);
2582     }
2583 }")
2584
2585 (define_split
2586   [(set (match_operand:DI 0 "register_operand" "")
2587         (if_then_else:DI
2588          (match_operator 1 "comparison_operator"
2589                          [(match_operand:SI 2 "reg_or_0_operand" "")
2590                           (match_operand:SI 3 "reg_or_cint_operand" "")])
2591          (match_operand:DI 4 "reg_or_8bit_operand" "")
2592          (match_operand:DI 5 "reg_or_8bit_operand" "")))
2593    (clobber (match_operand:DI 6 "register_operand" ""))]
2594   "operands[3] != const0_rtx
2595    && (GET_CODE (operands[1]) == EQ || GET_CODE (operands[1]) == NE)"
2596   [(set (match_dup 6) (match_dup 7))
2597    (set (match_dup 0)
2598         (if_then_else:DI (match_dup 8) (match_dup 4) (match_dup 5)))]
2599   "
2600 { enum rtx_code code = GET_CODE (operands[1]);
2601   int unsignedp = (code == GEU || code == LEU || code == GTU || code == LTU);
2602   rtx tem;
2603
2604   if ((code != NE && code != EQ
2605        && ! (extended_count (operands[2], DImode, unsignedp) >= 1
2606              && extended_count (operands[3], DImode, unsignedp) >= 1)))
2607     FAIL;
2608  
2609   if (GET_CODE (operands[3]) == CONST_INT)
2610     tem = gen_rtx (PLUS, SImode, operands[2],
2611                    GEN_INT (- INTVAL (operands[3])));
2612   else
2613     tem = gen_rtx (MINUS, SImode, operands[2], operands[3]);
2614
2615   operands[7] = gen_rtx (SIGN_EXTEND, DImode, tem);
2616   operands[8] = gen_rtx (GET_CODE (operands[1]), VOIDmode, operands[6],
2617                          const0_rtx);
2618 }")
2619
2620 (define_split
2621   [(set (pc)
2622         (if_then_else
2623          (match_operator 1 "comparison_operator"
2624                          [(match_operand:DI 2 "reg_or_0_operand" "")
2625                           (match_operand:DI 3 "reg_or_cint_operand" "")])
2626          (label_ref (match_operand 0 "" ""))
2627          (pc)))
2628    (clobber (match_operand:DI 4 "register_operand" ""))]
2629   "operands[3] != const0_rtx"
2630   [(set (match_dup 4) (match_dup 5))
2631    (set (pc) (if_then_else (match_dup 6) (label_ref (match_dup 0)) (pc)))]
2632   "
2633 { enum rtx_code code = GET_CODE (operands[1]);
2634   int unsignedp = (code == GEU || code == LEU || code == GTU || code == LTU);
2635
2636   if (code == NE || code == EQ
2637       || (extended_count (operands[2], DImode, unsignedp) >= 1
2638           && extended_count (operands[3], DImode, unsignedp) >= 1))
2639     {
2640       if (GET_CODE (operands[3]) == CONST_INT)
2641         operands[5] = gen_rtx (PLUS, DImode, operands[2],
2642                                GEN_INT (- INTVAL (operands[3])));
2643       else
2644         operands[5] = gen_rtx (MINUS, DImode, operands[2], operands[3]);
2645
2646       operands[6] = gen_rtx (code, VOIDmode, operands[4], const0_rtx);
2647     }
2648
2649   else if (code == EQ || code == LE || code == LT
2650            || code == LEU || code == LTU)
2651     {
2652       operands[5] = gen_rtx (code, DImode, operands[2], operands[3]);
2653       operands[6] = gen_rtx (NE, VOIDmode, operands[4], const0_rtx);
2654     }
2655   else
2656     {
2657       operands[5] = gen_rtx (reverse_condition (code), DImode, operands[2],
2658                              operands[3]);
2659       operands[6] = gen_rtx (EQ, VOIDmode, operands[4], const0_rtx);
2660     }
2661 }")
2662
2663 (define_split
2664   [(set (pc)
2665         (if_then_else
2666          (match_operator 1 "comparison_operator"
2667                          [(match_operand:SI 2 "reg_or_0_operand" "")
2668                           (match_operand:SI 3 "const_int_operand" "")])
2669          (label_ref (match_operand 0 "" ""))
2670          (pc)))
2671    (clobber (match_operand:DI 4 "register_operand" ""))]
2672   "operands[3] != const0_rtx
2673    && (GET_CODE (operands[1]) == EQ || GET_CODE (operands[1]) == NE)"
2674   [(set (match_dup 4) (match_dup 5))
2675    (set (pc) (if_then_else (match_dup 6) (label_ref (match_dup 0)) (pc)))]
2676   "
2677 { rtx tem;
2678
2679   if (GET_CODE (operands[3]) == CONST_INT)
2680     tem = gen_rtx (PLUS, SImode, operands[2],
2681                    GEN_INT (- INTVAL (operands[3])));
2682   else
2683     tem = gen_rtx (MINUS, SImode, operands[2], operands[3]);
2684   
2685   operands[5] = gen_rtx (SIGN_EXTEND, DImode, tem);
2686   operands[6] = gen_rtx (GET_CODE (operands[1]), VOIDmode,
2687                          operands[4], const0_rtx);
2688 }")
2689
2690 ;; We can convert such things as "a > 0xffff" to "t = a & ~ 0xffff; t != 0".
2691 ;; This eliminates one, and sometimes two, insns when the AND can be done
2692 ;; with a ZAP.
2693 (define_split
2694   [(set (match_operand:DI 0 "register_operand" "")
2695         (match_operator 1 "comparison_operator"
2696                         [(match_operand:DI 2 "register_operand" "")
2697                          (match_operand:DI 3 "const_int_operand" "")]))
2698    (clobber (match_operand:DI 4 "register_operand" ""))]
2699   "exact_log2 (INTVAL (operands[3]) + 1) >= 0
2700    && (GET_CODE (operands[1]) == GTU
2701        || GET_CODE (operands[1]) == LEU
2702        || ((GET_CODE (operands[1]) == GT || GET_CODE (operands[1]) == LE)
2703            && extended_count (operands[2], DImode, 1) > 0))"
2704   [(set (match_dup 4) (and:DI (match_dup 2) (match_dup 5)))
2705    (set (match_dup 0) (match_dup 6))]
2706   "
2707 {
2708   operands[5] = GEN_INT (~ INTVAL (operands[3]));
2709   operands[6] = gen_rtx (((GET_CODE (operands[1]) == GTU
2710                            || GET_CODE (operands[1]) == GT)
2711                           ? NE : EQ),
2712                          DImode, operands[4], const0_rtx);
2713 }")
2714 \f
2715 ;; Here are the CALL and unconditional branch insns.  Calls on NT and OSF
2716 ;; work differently, so we have different patterns for each.
2717
2718 (define_expand "call"
2719   [(use (match_operand:DI 0 "" ""))
2720    (use (match_operand 1 "" ""))]
2721   ""
2722   "
2723 { if (WINDOWS_NT)
2724     emit_call_insn (gen_call_nt (operands[0], operands[1]));
2725   else
2726     emit_call_insn (gen_call_osf (operands[0], operands[1]));
2727
2728   DONE;
2729 }")
2730
2731 (define_expand "call_osf"
2732   [(parallel [(call (mem:DI (match_operand 0 "" ""))
2733                     (match_operand 1 "" ""))
2734               (clobber (reg:DI 27))
2735               (clobber (reg:DI 26))])]
2736   ""
2737   "
2738 { if (GET_CODE (operands[0]) != MEM)
2739     abort ();
2740
2741   operands[0] = XEXP (operands[0], 0);
2742
2743   if (GET_CODE (operands[0]) != SYMBOL_REF
2744       && ! (GET_CODE (operands[0]) == REG && REGNO (operands[0]) == 27))
2745     {
2746       rtx tem = gen_rtx (REG, DImode, 27);
2747       emit_move_insn (tem, operands[0]);
2748       operands[0] = tem;
2749     }
2750 }")
2751
2752 (define_expand "call_nt"
2753   [(parallel [(call (mem:DI (match_operand:DI 0 "" ""))
2754                     (match_operand 1 "" ""))
2755               (clobber (reg:DI 26))])]
2756   ""
2757   "
2758 { if (GET_CODE (operands[0]) != MEM)
2759     abort ();
2760   operands[0] = XEXP (operands[0], 0);
2761
2762   if (GET_CODE (operands[1]) != SYMBOL_REF
2763       && ! (GET_CODE (operands[1]) == REG && REGNO (operands[1]) == 27))
2764     {
2765       rtx tem = gen_rtx (REG, DImode, 27);
2766       emit_move_insn (tem, operands[1]);
2767       operands[1] = tem;
2768     }
2769 }")
2770
2771 (define_expand "call_value"
2772   [(use (match_operand 0 "" ""))
2773    (use (match_operand:DI 1 "" ""))
2774    (use (match_operand 2 "" ""))]
2775   ""
2776   "
2777 { if (WINDOWS_NT)
2778     emit_call_insn (gen_call_value_nt (operands[0], operands[1], operands[2]));
2779   else
2780     emit_call_insn (gen_call_value_osf (operands[0], operands[1],
2781                                         operands[2]));
2782   DONE;
2783 }")
2784
2785 (define_expand "call_value_osf"
2786   [(parallel [(set (match_operand 0 "" "")
2787                    (call (mem:DI (match_operand 1 "" ""))
2788                          (match_operand 2 "" "")))
2789               (clobber (reg:DI 27))
2790               (clobber (reg:DI 26))])]
2791   ""
2792   "
2793 { if (GET_CODE (operands[1]) != MEM)
2794     abort ();
2795
2796   operands[1] = XEXP (operands[1], 0);
2797
2798   if (GET_CODE (operands[1]) != SYMBOL_REF
2799       && ! (GET_CODE (operands[1]) == REG && REGNO (operands[1]) == 27))
2800     {
2801       rtx tem = gen_rtx (REG, DImode, 27);
2802       emit_move_insn (tem, operands[1]);
2803       operands[1] = tem;
2804     }
2805 }")
2806
2807 (define_expand "call_value_nt"
2808   [(parallel [(set (match_operand 0 "" "")
2809                    (call (mem:DI (match_operand:DI 1 "" ""))
2810                          (match_operand 2 "" "")))
2811               (clobber (reg:DI 26))])]
2812   ""
2813   "
2814 { if (GET_CODE (operands[1]) != MEM)
2815     abort ();
2816
2817   operands[1] = XEXP (operands[1], 0);
2818   if (GET_CODE (operands[1]) != SYMBOL_REF
2819       && ! (GET_CODE (operands[1]) == REG && REGNO (operands[1]) == 27))
2820     {
2821       rtx tem = gen_rtx (REG, DImode, 27);
2822       emit_move_insn (tem, operands[1]);
2823       operands[1] = tem;
2824     }
2825 }")
2826
2827 (define_insn ""
2828   [(call (mem:DI (match_operand:DI 0 "call_operand" "r,R,i"))
2829          (match_operand 1 "" ""))
2830    (clobber (reg:DI 27))
2831    (clobber (reg:DI 26))]
2832   "! WINDOWS_NT"
2833   "@
2834    jsr $26,($27),0\;ldgp $29,0($26)
2835    bsr $26,%0..ng
2836    jsr $26,%0\;ldgp $29,0($26)"
2837   [(set_attr "type" "jsr,jsr,ibr")])
2838       
2839 (define_insn ""
2840   [(call (mem:DI (match_operand:DI 0 "call_operand" "r,i"))
2841          (match_operand 1 "" ""))
2842    (clobber (reg:DI 26))]
2843   "WINDOWS_NT"
2844   "@
2845    jsr $26,(%0)
2846    bsr $26,%0"
2847   [(set_attr "type" "jsr")])
2848       
2849 (define_insn ""
2850   [(set (match_operand 0 "register_operand" "=rf,rf,rf")
2851         (call (mem:DI (match_operand:DI 1 "call_operand" "r,R,i"))
2852               (match_operand 2 "" "")))
2853    (clobber (reg:DI 27))
2854    (clobber (reg:DI 26))]
2855   "! WINDOWS_NT"
2856   "@
2857    jsr $26,($27),0\;ldgp $29,0($26)
2858    bsr $26,%1..ng
2859    jsr $26,%1\;ldgp $29,0($26)"
2860   [(set_attr "type" "jsr,jsr,ibr")])
2861
2862 (define_insn ""
2863   [(set (match_operand 0 "register_operand" "=rf,rf")
2864         (call (mem:DI (match_operand:DI 1 "call_operand" "r,i"))
2865               (match_operand 2 "" "")))
2866    (clobber (reg:DI 26))]
2867   "WINDOWS_NT"
2868   "@
2869    jsr $26,(%1)
2870    bsr $26,%1"
2871   [(set_attr "type" "jsr")])
2872
2873 ;; Call subroutine returning any type.
2874
2875 (define_expand "untyped_call"
2876   [(parallel [(call (match_operand 0 "" "")
2877                     (const_int 0))
2878               (match_operand 1 "" "")
2879               (match_operand 2 "" "")])]
2880   ""
2881   "
2882 {
2883   int i;
2884
2885   emit_call_insn (gen_call (operands[0], const0_rtx, NULL, const0_rtx));
2886
2887   for (i = 0; i < XVECLEN (operands[2], 0); i++)
2888     {
2889       rtx set = XVECEXP (operands[2], 0, i);
2890       emit_move_insn (SET_DEST (set), SET_SRC (set));
2891     }
2892
2893   /* The optimizer does not know that the call sets the function value
2894      registers we stored in the result block.  We avoid problems by
2895      claiming that all hard registers are used and clobbered at this
2896      point.  */
2897   emit_insn (gen_blockage ());
2898
2899   DONE;
2900 }")
2901
2902 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
2903 ;; all of memory.  This blocks insns from being moved across this point.
2904
2905 (define_insn "blockage"
2906   [(unspec_volatile [(const_int 0)] 1)]
2907   ""
2908   "")
2909
2910 (define_insn "jump"
2911   [(set (pc)
2912         (label_ref (match_operand 0 "" "")))]
2913   ""
2914   "br $31,%l0"
2915   [(set_attr "type" "ibr")])
2916
2917 (define_insn "return"
2918   [(return)]
2919   "direct_return ()"
2920   "ret $31,($26),1"
2921   [(set_attr "type" "ibr")])
2922
2923 (define_insn "indirect_jump"
2924   [(set (pc) (match_operand:DI 0 "register_operand" "r"))]
2925   ""
2926   "jmp $31,(%0),0"
2927   [(set_attr "type" "ibr")])
2928
2929 (define_insn "nop"
2930   [(const_int 0)]
2931   ""
2932   "bis $31,$31,$31"
2933   [(set_attr "type" "iaddlog")])
2934
2935 (define_expand "tablejump"
2936   [(use (match_operand:SI 0 "register_operand" ""))
2937    (use (match_operand:SI 1 "" ""))]
2938   ""
2939   "
2940 {
2941   if (WINDOWS_NT)
2942     emit_jump_insn (gen_tablejump_nt (operands[0], operands[1]));
2943   else
2944     emit_jump_insn (gen_tablejump_osf (operands[0], operands[1]));
2945
2946   DONE;
2947 }")
2948
2949 (define_expand "tablejump_osf"
2950   [(set (match_dup 3)
2951         (sign_extend:DI (match_operand:SI 0 "register_operand" "")))
2952    (parallel [(set (pc)
2953                    (plus:DI (match_dup 3)
2954                             (label_ref:DI (match_operand 1 "" ""))))
2955               (clobber (match_scratch:DI 2 "=r"))])]
2956   ""
2957   "
2958 { operands[3] = gen_reg_rtx (DImode); }")
2959
2960 (define_expand "tablejump_nt"
2961   [(set (match_dup 3)
2962         (sign_extend:DI (match_operand:SI 0 "register_operand" "")))
2963    (parallel [(set (pc)
2964                    (match_dup 3))
2965               (use (label_ref (match_operand 1 "" "")))])]
2966   ""
2967   "
2968 { operands[3] = gen_reg_rtx (DImode); }")
2969
2970 (define_insn ""
2971   [(set (pc)
2972         (plus:DI (match_operand:DI 0 "register_operand" "r")
2973                  (label_ref:DI (match_operand 1 "" ""))))
2974    (clobber (match_scratch:DI 2 "=r"))]
2975   "! WINDOWS_NT && next_active_insn (insn) != 0
2976    && GET_CODE (PATTERN (next_active_insn (insn))) == ADDR_DIFF_VEC
2977    && PREV_INSN (next_active_insn (insn)) == operands[1]"
2978   "*
2979 { rtx best_label = 0;
2980   rtx jump_table_insn = next_active_insn (operands[1]);
2981
2982   if (GET_CODE (jump_table_insn) == JUMP_INSN
2983       && GET_CODE (PATTERN (jump_table_insn)) == ADDR_DIFF_VEC)
2984     {
2985       rtx jump_table = PATTERN (jump_table_insn);
2986       int n_labels = XVECLEN (jump_table, 1);
2987       int best_count = -1;
2988       int i, j;
2989
2990       for (i = 0; i < n_labels; i++)
2991         {
2992           int count = 1;
2993
2994           for (j = i + 1; j < n_labels; j++)
2995             if (XEXP (XVECEXP (jump_table, 1, i), 0)
2996                 == XEXP (XVECEXP (jump_table, 1, j), 0))
2997               count++;
2998
2999           if (count > best_count)
3000             best_count = count, best_label = XVECEXP (jump_table, 1, i);
3001         }
3002     }
3003
3004   if (best_label)
3005     {
3006       operands[3] = best_label;
3007       return \"addq %0,$29,%2\;jmp $31,(%2),%3\";
3008     }
3009   else
3010     return \"addq %0,$29,%2\;jmp $31,(%2),0\";
3011 }"
3012   [(set_attr "type" "ibr")])
3013
3014 (define_insn ""
3015   [(set (pc)
3016         (match_operand:DI 0 "register_operand" "r"))
3017    (use (label_ref (match_operand 1 "" "")))]
3018   "WINDOWS_NT && next_active_insn (insn) != 0
3019    && GET_CODE (PATTERN (next_active_insn (insn))) == ADDR_DIFF_VEC
3020    && PREV_INSN (next_active_insn (insn)) == operands[1]"
3021   "*
3022 { rtx best_label = 0;
3023   rtx jump_table_insn = next_active_insn (operands[1]);
3024
3025   if (GET_CODE (jump_table_insn) == JUMP_INSN
3026       && GET_CODE (PATTERN (jump_table_insn)) == ADDR_DIFF_VEC)
3027     {
3028       rtx jump_table = PATTERN (jump_table_insn);
3029       int n_labels = XVECLEN (jump_table, 1);
3030       int best_count = -1;
3031       int i, j;
3032
3033       for (i = 0; i < n_labels; i++)
3034         {
3035           int count = 1;
3036
3037           for (j = i + 1; j < n_labels; j++)
3038             if (XEXP (XVECEXP (jump_table, 1, i), 0)
3039                 == XEXP (XVECEXP (jump_table, 1, j), 0))
3040               count++;
3041
3042           if (count > best_count)
3043             best_count = count, best_label = XVECEXP (jump_table, 1, i);
3044         }
3045     }
3046
3047   if (best_label)
3048     {
3049       operands[2] = best_label;
3050       return \"jmp $31,(%0),%2\";
3051     }
3052   else
3053     return \"jmp $31,(%0),0\";
3054 }"
3055   [(set_attr "type" "ibr")])
3056
3057 ;; Cache flush.  Used by INITIALIZE_TRAMPOLINE.  0x86 is PAL_imb, but we don't
3058 ;; want to have to include pal.h in our .s file.
3059 (define_insn ""
3060   [(unspec_volatile [(const_int 0)] 0)]
3061   ""
3062   "call_pal 0x86")
3063 \f
3064 ;; Finally, we have the basic data motion insns.  The byte and word insns
3065 ;; are done via define_expand.  Start with the floating-point insns, since
3066 ;; they are simpler.
3067
3068 (define_insn ""
3069   [(set (match_operand:SF 0 "nonimmediate_operand" "=r,r,m,f,f,f,m")
3070         (match_operand:SF 1 "input_operand" "rG,m,rG,f,G,m,fG"))]
3071   "register_operand (operands[0], SFmode)
3072    || reg_or_fp0_operand (operands[1], SFmode)"
3073   "@
3074    bis %r1,%r1,%0
3075    ldl %0,%1
3076    stl %r1,%0
3077    cpys %1,%1,%0
3078    cpys $f31,$f31,%0
3079    lds %0,%1
3080    sts %R1,%0"
3081   [(set_attr "type" "iaddlog,ld,st,fpop,fpop,ld,st")])
3082
3083 (define_insn ""
3084   [(set (match_operand:DF 0 "nonimmediate_operand" "=r,r,m,f,f,f,m")
3085         (match_operand:DF 1 "input_operand" "rG,m,rG,f,G,m,fG"))]
3086   "register_operand (operands[0], DFmode)
3087    || reg_or_fp0_operand (operands[1], DFmode)"
3088   "@
3089    bis %r1,%r1,%0
3090    ldq %0,%1
3091    stq %r1,%0
3092    cpys %1,%1,%0
3093    cpys $f31,$f31,%0
3094    ldt %0,%1
3095    stt %R1,%0"
3096   [(set_attr "type" "iaddlog,ld,st,fpop,fpop,ld,st")])
3097
3098 (define_expand "movsf"
3099   [(set (match_operand:SF 0 "nonimmediate_operand" "")
3100         (match_operand:SF 1 "general_operand" ""))]
3101   ""
3102   "
3103 {
3104   if (GET_CODE (operands[0]) == MEM
3105       && ! reg_or_fp0_operand (operands[1], SFmode))
3106     operands[1] = force_reg (SFmode, operands[1]);
3107 }")
3108
3109 (define_expand "movdf"
3110   [(set (match_operand:DF 0 "nonimmediate_operand" "")
3111         (match_operand:DF 1 "general_operand" ""))]
3112   ""
3113   "
3114 {
3115   if (GET_CODE (operands[0]) == MEM
3116       && ! reg_or_fp0_operand (operands[1], DFmode))
3117     operands[1] = force_reg (DFmode, operands[1]);
3118 }")
3119
3120 (define_insn ""
3121   [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,r,r,r,r,m,f,f,f,m")
3122         (match_operand:SI 1 "input_operand" "r,J,I,K,L,m,rJ,f,J,m,fG"))]
3123   "! WINDOWS_NT && (register_operand (operands[0], SImode)
3124                     || reg_or_0_operand (operands[1], SImode))"
3125   "@
3126    bis %1,%1,%0
3127    bis $31,$31,%0
3128    bis $31,%1,%0
3129    lda %0,%1
3130    ldah %0,%h1
3131    ldl %0,%1
3132    stl %r1,%0
3133    cpys %1,%1,%0
3134    cpys $f31,$f31,%0
3135    lds %0,%1
3136    sts %R1,%0"
3137   [(set_attr "type" "iaddlog,iaddlog,iaddlog,iaddlog,iaddlog,ld,st,fpop,fpop,ld,st")])
3138
3139 (define_insn ""
3140   [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,r,r,r,r,r,m,f,f,f,m")
3141         (match_operand:SI 1 "input_operand" "r,J,I,K,L,s,m,rJ,f,J,m,fG"))]
3142   "WINDOWS_NT && (register_operand (operands[0], SImode)
3143                   || reg_or_0_operand (operands[1], SImode))"
3144   "@
3145    bis %1,%1,%0
3146    bis $31,$31,%0
3147    bis $31,%1,%0
3148    lda %0,%1
3149    ldah %0,%h1
3150    lda %0,%1
3151    ldl %0,%1
3152    stl %r1,%0
3153    cpys %1,%1,%0
3154    cpys $f31,$f31,%0
3155    lds %0,%1
3156    sts %R1,%0"
3157   [(set_attr "type" "iaddlog,iaddlog,iaddlog,iaddlog,iaddlog,ldsym,ld,st,fpop,fpop,ld,st")])
3158
3159 (define_insn ""
3160   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,r,f,f")
3161         (match_operand:HI 1 "input_operand" "r,J,I,n,f,J"))]
3162   "register_operand (operands[0], HImode)
3163    || register_operand (operands[1], HImode)"
3164   "@
3165    bis %1,%1,%0
3166    bis $31,$31,%0
3167    bis $31,%1,%0
3168    lda %0,%L1
3169    cpys %1,%1,%0
3170    cpys $f31,$f31,%0"
3171   [(set_attr "type" "iaddlog,iaddlog,iaddlog,iaddlog,fpop,fpop")])
3172
3173 (define_insn ""
3174   [(set (match_operand:QI 0 "nonimmediate_operand" "=r,r,r,r,f,f")
3175         (match_operand:QI 1 "input_operand" "r,J,I,n,f,J"))]
3176   "register_operand (operands[0], QImode)
3177    || register_operand (operands[1], QImode)"
3178   "@
3179    bis %1,%1,%0
3180    bis $31,$31,%0
3181    bis $31,%1,%0
3182    lda %0,%L1
3183    cpys %1,%1,%0
3184    cpys $f31,$f31,%0"
3185   [(set_attr "type" "iaddlog,iaddlog,iaddlog,iaddlog,fpop,fpop")])
3186
3187 ;; We do two major things here: handle mem->mem and construct long
3188 ;; constants.
3189
3190 (define_expand "movsi"
3191   [(set (match_operand:SI 0 "general_operand" "")
3192         (match_operand:SI 1 "general_operand" ""))]
3193   ""
3194   "
3195 {
3196   if (GET_CODE (operands[0]) == MEM
3197       && ! reg_or_0_operand (operands[1], SImode))
3198     operands[1] = force_reg (SImode, operands[1]);
3199
3200   if (! CONSTANT_P (operands[1]) || input_operand (operands[1], SImode))
3201     ;
3202   else if (GET_CODE (operands[1]) == CONST_INT)
3203     {
3204       operands[1]
3205         = alpha_emit_set_const (operands[0], SImode, INTVAL (operands[1]), 3);
3206       if (rtx_equal_p (operands[0], operands[1]))
3207         DONE;
3208     }
3209 }")
3210
3211 ;; Split a load of a large constant into the appropriate two-insn
3212 ;; sequence.
3213
3214 (define_split
3215   [(set (match_operand:SI 0 "register_operand" "")
3216         (match_operand:SI 1 "const_int_operand" ""))]
3217   "! add_operand (operands[1], SImode)"
3218   [(set (match_dup 0) (match_dup 2))
3219    (set (match_dup 0) (plus:SI (match_dup 0) (match_dup 3)))]
3220   "
3221 { rtx tem
3222     = alpha_emit_set_const (operands[0], SImode, INTVAL (operands[1]), 2);
3223
3224   if (tem == operands[0])
3225     DONE;
3226   else
3227     FAIL;
3228 }")
3229
3230 (define_insn ""
3231   [(set (match_operand:DI 0 "general_operand" "=r,r,r,r,r,r,r,m,f,f,f,Q")
3232         (match_operand:DI 1 "input_operand" "r,J,I,K,L,s,m,rJ,f,J,Q,fG"))]
3233   "register_operand (operands[0], DImode)
3234    || reg_or_0_operand (operands[1], DImode)"
3235   "@
3236    bis %1,%1,%0
3237    bis $31,$31,%0
3238    bis $31,%1,%0
3239    lda %0,%1
3240    ldah %0,%h1
3241    lda %0,%1
3242    ldq%A1 %0,%1
3243    stq%A0 %r1,%0
3244    cpys %1,%1,%0
3245    cpys $f31,$f31,%0
3246    ldt %0,%1
3247    stt %R1,%0"
3248   [(set_attr "type" "iaddlog,iaddlog,iaddlog,iaddlog,iaddlog,ldsym,ld,st,fpop,fpop,ld,st")])
3249
3250 ;; We do three major things here: handle mem->mem, put 64-bit constants in
3251 ;; memory, and construct long 32-bit constants.
3252
3253 (define_expand "movdi"
3254   [(set (match_operand:DI 0 "general_operand" "")
3255         (match_operand:DI 1 "general_operand" ""))]
3256   ""
3257   "
3258 {
3259   rtx tem;
3260
3261   if (GET_CODE (operands[0]) == MEM
3262       && ! reg_or_0_operand (operands[1], DImode))
3263     operands[1] = force_reg (DImode, operands[1]);
3264
3265   if (! CONSTANT_P (operands[1]) || input_operand (operands[1], DImode))
3266     ;
3267   else if (GET_CODE (operands[1]) == CONST_INT
3268            && (tem = alpha_emit_set_const (operands[0], DImode,
3269                                            INTVAL (operands[1]), 3)) != 0)
3270     {
3271       if (rtx_equal_p (tem, operands[0]))
3272         DONE;
3273       else
3274         operands[1] = tem;
3275     }
3276   else if (CONSTANT_P (operands[1]))
3277     {
3278       operands[1] = force_const_mem (DImode, operands[1]);
3279       if (reload_in_progress)
3280         {
3281           emit_move_insn (operands[0], XEXP (operands[1], 0));
3282           operands[1] = copy_rtx (operands[1]);
3283           XEXP (operands[1], 0) = operands[0];
3284         }
3285       else
3286         operands[1] = validize_mem (operands[1]);
3287     }
3288   else
3289     abort ();
3290 }")
3291
3292 ;; Split a load of a large constant into the appropriate two-insn
3293 ;; sequence.
3294
3295 (define_split
3296   [(set (match_operand:DI 0 "register_operand" "")
3297         (match_operand:DI 1 "const_int_operand" ""))]
3298   "! add_operand (operands[1], DImode)"
3299   [(set (match_dup 0) (match_dup 2))
3300    (set (match_dup 0) (plus:DI (match_dup 0) (match_dup 3)))]
3301   "
3302 { rtx tem
3303     = alpha_emit_set_const (operands[0], DImode, INTVAL (operands[1]), 2);
3304
3305   if (tem == operands[0])
3306     DONE;
3307   else
3308     FAIL;
3309 }")
3310
3311 ;; These are the partial-word cases.
3312 ;;
3313 ;; First we have the code to load an aligned word.  Operand 0 is the register
3314 ;; in which to place the result.  It's mode is QImode or HImode.  Operand 1
3315 ;; is an SImode MEM at the low-order byte of the proper word.  Operand 2 is the
3316 ;; number of bits within the word that the value is.  Operand 3 is an SImode
3317 ;; scratch register.  If operand 0 is a hard register, operand 3 may be the
3318 ;; same register.  It is allowed to conflict with operand 1 as well.
3319
3320 (define_expand "aligned_loadqi"
3321   [(set (match_operand:SI 3 "register_operand" "")
3322         (match_operand:SI 1 "memory_operand" ""))
3323    (set (subreg:DI (match_operand:QI 0 "register_operand" "") 0)
3324         (zero_extract:DI (subreg:DI (match_dup 3) 0)
3325                          (const_int 8)
3326                          (match_operand:DI 2 "const_int_operand" "")))]
3327          
3328   ""
3329   "")
3330   
3331 (define_expand "aligned_loadhi"
3332   [(set (match_operand:SI 3 "register_operand" "")
3333         (match_operand:SI 1 "memory_operand" ""))
3334    (set (subreg:DI (match_operand:HI 0 "register_operand" "") 0)
3335         (zero_extract:DI (subreg:DI (match_dup 3) 0)
3336                          (const_int 16)
3337                          (match_operand:DI 2 "const_int_operand" "")))]
3338          
3339   ""
3340   "")
3341   
3342 ;; Similar for unaligned loads, where we use the sequence from the
3343 ;; Alpha Architecture manual.
3344 ;;
3345 ;; Operand 1 is the address.  Operands 2 and 3 are temporaries, where
3346 ;; operand 3 can overlap the input and output registers.
3347
3348 (define_expand "unaligned_loadqi"
3349   [(set (match_operand:DI 2 "register_operand" "")
3350         (mem:DI (and:DI (match_operand:DI 1 "address_operand" "")
3351                         (const_int -8))))
3352    (set (match_operand:DI 3 "register_operand" "")
3353         (match_dup 1))
3354    (set (subreg:DI (match_operand:QI 0 "register_operand" "") 0)
3355         (zero_extract:DI (match_dup 2)
3356                          (const_int 8)
3357                          (ashift:DI (match_dup 3) (const_int 3))))]
3358   ""
3359   "")
3360
3361 (define_expand "unaligned_loadhi"
3362   [(set (match_operand:DI 2 "register_operand" "")
3363         (mem:DI (and:DI (match_operand:DI 1 "address_operand" "")
3364                         (const_int -8))))
3365    (set (match_operand:DI 3 "register_operand" "")
3366         (match_dup 1))
3367    (set (subreg:DI (match_operand:QI 0 "register_operand" "") 0)
3368         (zero_extract:DI (match_dup 2)
3369                          (const_int 16)
3370                          (ashift:DI (match_dup 3) (const_int 3))))]
3371   ""
3372   "")
3373
3374 ;; Storing an aligned byte or word requires two temporaries.  Operand 0 is the
3375 ;; aligned SImode MEM.  Operand 1 is the register containing the 
3376 ;; byte or word to store.  Operand 2 is the number of bits within the word that
3377 ;; the value should be placed.  Operands 3 and 4 are SImode temporaries.
3378
3379 (define_expand "aligned_store"
3380   [(set (match_operand:SI 3 "register_operand" "")
3381         (match_operand:SI 0 "memory_operand" ""))
3382    (set (subreg:DI (match_dup 3) 0)
3383         (and:DI (subreg:DI (match_dup 3) 0) (match_dup 5)))
3384    (set (subreg:DI (match_operand:SI 4 "register_operand" "") 0)
3385         (ashift:DI (zero_extend:DI (match_operand 1 "register_operand" ""))
3386                    (match_operand:DI 2 "const_int_operand" "")))
3387    (set (subreg:DI (match_dup 4) 0)
3388         (ior:DI (subreg:DI (match_dup 4) 0) (subreg:DI (match_dup 3) 0)))
3389    (set (match_dup 0) (match_dup 4))]
3390   ""
3391   "
3392 { operands[5] = GEN_INT (~ (GET_MODE_MASK (GET_MODE (operands[1]))
3393                             << INTVAL (operands[2])));
3394 }")
3395
3396 ;; For the unaligned byte and halfword cases, we use code similar to that
3397 ;; in the ;; Architecture book, but reordered to lower the number of registers
3398 ;; required.  Operand 0 is the address.  Operand 1 is the data to store.
3399 ;; Operands 2, 3, and 4 are DImode temporaries, where operands 2 and 4 may
3400 ;; be the same temporary, if desired.  If the address is in a register,
3401 ;; operand 2 can be that register.
3402
3403 (define_expand "unaligned_storeqi"
3404   [(set (match_operand:DI 3 "register_operand" "")
3405         (mem:DI (and:DI (match_operand:DI 0 "address_operand" "")
3406                         (const_int -8))))
3407    (set (match_operand:DI 2 "register_operand" "")
3408         (match_dup 0))
3409    (set (match_dup 3)
3410         (and:DI (not:DI (ashift:DI (const_int 255)
3411                                    (ashift:DI (match_dup 2) (const_int 3))))
3412                 (match_dup 3)))
3413    (set (match_operand:DI 4 "register_operand" "")
3414         (ashift:DI (zero_extend:DI (match_operand:QI 1 "register_operand" ""))
3415                    (ashift:DI (match_dup 2) (const_int 3))))
3416    (set (match_dup 4) (ior:DI (match_dup 4) (match_dup 3)))
3417    (set (mem:DI (and:DI (match_dup 0) (const_int -8)))
3418         (match_dup 4))]
3419   ""
3420   "")
3421
3422 (define_expand "unaligned_storehi"
3423   [(set (match_operand:DI 3 "register_operand" "")
3424         (mem:DI (and:DI (match_operand:DI 0 "address_operand" "")
3425                         (const_int -8))))
3426    (set (match_operand:DI 2 "register_operand" "")
3427         (match_dup 0))
3428    (set (match_dup 3)
3429         (and:DI (not:DI (ashift:DI (const_int 65535)
3430                                    (ashift:DI (match_dup 2) (const_int 3))))
3431                 (match_dup 3)))
3432    (set (match_operand:DI 4 "register_operand" "")
3433         (ashift:DI (zero_extend:DI (match_operand:HI 1 "register_operand" ""))
3434                    (ashift:DI (match_dup 2) (const_int 3))))
3435    (set (match_dup 4) (ior:DI (match_dup 4) (match_dup 3)))
3436    (set (mem:DI (and:DI (match_dup 0) (const_int -8)))
3437         (match_dup 4))]
3438   ""
3439   "")
3440 \f
3441 ;; Here are the define_expand's for QI and HI moves that use the above
3442 ;; patterns.  We have the normal sets, plus the ones that need scratch
3443 ;; registers for reload.
3444
3445 (define_expand "movqi"
3446   [(set (match_operand:QI 0 "general_operand" "")
3447         (match_operand:QI 1 "general_operand" ""))]
3448   ""
3449   "
3450 { extern rtx get_unaligned_address ();
3451
3452   /* If the output is not a register, the input must be.  */
3453   if (GET_CODE (operands[0]) == MEM)
3454     operands[1] = force_reg (QImode, operands[1]);
3455
3456   /* Handle four memory cases, unaligned and aligned for either the input
3457      or the output.  The only case where we can be called during reload is
3458      for aligned loads; all other cases require temporaries.  */
3459
3460   if (GET_CODE (operands[1]) == MEM
3461       || (GET_CODE (operands[1]) == SUBREG
3462           && GET_CODE (SUBREG_REG (operands[1])) == MEM)
3463       || (reload_in_progress && GET_CODE (operands[1]) == REG
3464           && REGNO (operands[1]) >= FIRST_PSEUDO_REGISTER)
3465       || (reload_in_progress && GET_CODE (operands[1]) == SUBREG
3466           && GET_CODE (SUBREG_REG (operands[1])) == REG
3467           && REGNO (SUBREG_REG (operands[1])) >= FIRST_PSEUDO_REGISTER))
3468     {
3469       if (aligned_memory_operand (operands[1], QImode))
3470         {
3471           rtx aligned_mem, bitnum;
3472           rtx scratch = (reload_in_progress
3473                          ? gen_rtx (REG, SImode, REGNO (operands[0]))
3474                          : gen_reg_rtx (SImode));
3475
3476           get_aligned_mem (operands[1], &aligned_mem, &bitnum);
3477
3478           emit_insn (gen_aligned_loadqi (operands[0], aligned_mem, bitnum,
3479                                          scratch));
3480         }
3481       else
3482         {
3483           /* Don't pass these as parameters since that makes the generated
3484              code depend on parameter evaluation order which will cause
3485              bootstrap failures.  */
3486
3487           rtx temp1 = gen_reg_rtx (DImode);
3488           rtx temp2 = gen_reg_rtx (DImode);
3489           rtx seq
3490             = gen_unaligned_loadqi (operands[0],
3491                                     get_unaligned_address (operands[1], 0),
3492                                     temp1, temp2);
3493
3494           alpha_set_memflags (seq, operands[1]);
3495           emit_insn (seq);
3496         }
3497
3498       DONE;
3499     }
3500
3501   else if (GET_CODE (operands[0]) == MEM
3502            || (GET_CODE (operands[0]) == SUBREG 
3503                && GET_CODE (SUBREG_REG (operands[0])) == MEM)
3504            || (reload_in_progress && GET_CODE (operands[0]) == REG
3505                && REGNO (operands[0]) >= FIRST_PSEUDO_REGISTER)
3506            || (reload_in_progress && GET_CODE (operands[0]) == SUBREG
3507                && GET_CODE (SUBREG_REG (operands[0])) == REG
3508                && REGNO (operands[0]) >= FIRST_PSEUDO_REGISTER))
3509     {
3510       if (aligned_memory_operand (operands[0], QImode))
3511         {
3512           rtx aligned_mem, bitnum;
3513           rtx temp1 = gen_reg_rtx (SImode);
3514           rtx temp2 = gen_reg_rtx (SImode);
3515
3516           get_aligned_mem (operands[0], &aligned_mem, &bitnum);
3517
3518           emit_insn (gen_aligned_store (aligned_mem, operands[1], bitnum,
3519                                         temp1, temp2));
3520         }
3521       else
3522         {
3523           rtx temp1 = gen_reg_rtx (DImode);
3524           rtx temp2 = gen_reg_rtx (DImode);
3525           rtx temp3 = gen_reg_rtx (DImode);
3526           rtx seq
3527             = gen_unaligned_storeqi (get_unaligned_address (operands[0], 0),
3528                                            operands[1], temp1, temp2, temp3);
3529
3530           alpha_set_memflags (seq, operands[0]);
3531           emit_insn (seq);
3532         }
3533       DONE;
3534     }
3535 }")
3536
3537 (define_expand "movhi"
3538   [(set (match_operand:HI 0 "general_operand" "")
3539         (match_operand:HI 1 "general_operand" ""))]
3540   ""
3541   "
3542 { extern rtx get_unaligned_address ();
3543
3544   /* If the output is not a register, the input must be.  */
3545   if (GET_CODE (operands[0]) == MEM)
3546     operands[1] = force_reg (HImode, operands[1]);
3547
3548   /* Handle four memory cases, unaligned and aligned for either the input
3549      or the output.  The only case where we can be called during reload is
3550      for aligned loads; all other cases require temporaries.  */
3551
3552   if (GET_CODE (operands[1]) == MEM
3553       || (GET_CODE (operands[1]) == SUBREG
3554           && GET_CODE (SUBREG_REG (operands[1])) == MEM)
3555       || (reload_in_progress && GET_CODE (operands[1]) == REG
3556           && REGNO (operands[1]) >= FIRST_PSEUDO_REGISTER)
3557       || (reload_in_progress && GET_CODE (operands[1]) == SUBREG
3558           && GET_CODE (SUBREG_REG (operands[1])) == REG
3559           && REGNO (SUBREG_REG (operands[1])) >= FIRST_PSEUDO_REGISTER))
3560     {
3561       if (aligned_memory_operand (operands[1], HImode))
3562         {
3563           rtx aligned_mem, bitnum;
3564           rtx scratch = (reload_in_progress
3565                          ? gen_rtx (REG, SImode, REGNO (operands[0]))
3566                          : gen_reg_rtx (SImode));
3567
3568           get_aligned_mem (operands[1], &aligned_mem, &bitnum);
3569
3570           emit_insn (gen_aligned_loadhi (operands[0], aligned_mem, bitnum,
3571                                          scratch));
3572         }
3573       else
3574         {
3575           /* Don't pass these as parameters since that makes the generated
3576              code depend on parameter evaluation order which will cause
3577              bootstrap failures.  */
3578
3579           rtx temp1 = gen_reg_rtx (DImode);
3580           rtx temp2 = gen_reg_rtx (DImode);
3581           rtx seq
3582             = gen_unaligned_loadhi (operands[0],
3583                                     get_unaligned_address (operands[1], 0),
3584                                     temp1, temp2);
3585
3586           alpha_set_memflags (seq, operands[1]);
3587           emit_insn (seq);
3588         }
3589
3590       DONE;
3591     }
3592
3593   else if (GET_CODE (operands[0]) == MEM
3594            || (GET_CODE (operands[0]) == SUBREG 
3595                && GET_CODE (SUBREG_REG (operands[0])) == MEM)
3596            || (reload_in_progress && GET_CODE (operands[0]) == REG
3597                && REGNO (operands[0]) >= FIRST_PSEUDO_REGISTER)
3598            || (reload_in_progress && GET_CODE (operands[0]) == SUBREG
3599                && GET_CODE (SUBREG_REG (operands[0])) == REG
3600                && REGNO (operands[0]) >= FIRST_PSEUDO_REGISTER))
3601     {
3602       if (aligned_memory_operand (operands[0], HImode))
3603         {
3604           rtx aligned_mem, bitnum;
3605           rtx temp1 = gen_reg_rtx (SImode);
3606           rtx temp2 = gen_reg_rtx (SImode);
3607
3608           get_aligned_mem (operands[0], &aligned_mem, &bitnum);
3609
3610           emit_insn (gen_aligned_store (aligned_mem, operands[1], bitnum,
3611                                         temp1, temp2));
3612         }
3613       else
3614         {
3615           rtx temp1 = gen_reg_rtx (DImode);
3616           rtx temp2 = gen_reg_rtx (DImode);
3617           rtx temp3 = gen_reg_rtx (DImode);
3618           rtx seq
3619             = gen_unaligned_storehi (get_unaligned_address (operands[0], 0),
3620                                      operands[1], temp1, temp2, temp3);
3621
3622           alpha_set_memflags (seq, operands[0]);
3623           emit_insn (seq);
3624         }
3625
3626       DONE;
3627     }
3628 }")
3629
3630 ;; Here are the versions for reload.  Note that in the unaligned cases
3631 ;; we know that the operand must not be a pseudo-register because stack
3632 ;; slots are always aligned references.
3633
3634 (define_expand "reload_inqi"
3635   [(parallel [(match_operand:QI 0 "register_operand" "=r")
3636               (match_operand:QI 1 "unaligned_memory_operand" "m")
3637               (match_operand:TI 2 "register_operand" "=&r")])]
3638   ""
3639   "
3640 { extern rtx get_unaligned_address ();
3641   rtx addr = get_unaligned_address (operands[1], 0);
3642   /* It is possible that one of the registers we got for operands[2]
3643      might coincide with that of operands[0] (which is why we made
3644      it TImode).  Pick the other one to use as our scratch.  */
3645   rtx scratch = gen_rtx (REG, DImode,
3646                          REGNO (operands[0]) == REGNO (operands[2]) 
3647                          ? REGNO (operands[2]) + 1 : REGNO (operands[2]));
3648   rtx seq = gen_unaligned_loadqi (operands[0], addr, scratch,
3649                                   gen_rtx (REG, DImode, REGNO (operands[0])));
3650
3651   alpha_set_memflags (seq, operands[1]);
3652   emit_insn (seq);
3653   DONE;
3654 }")
3655
3656 (define_expand "reload_inhi"
3657   [(parallel [(match_operand:HI 0 "register_operand" "=r")
3658               (match_operand:HI 1 "unaligned_memory_operand" "m")
3659               (match_operand:TI 2 "register_operand" "=&r")])]
3660   ""
3661   "
3662 { extern rtx get_unaligned_address ();
3663   rtx addr = get_unaligned_address (operands[1], 0);
3664   /* It is possible that one of the registers we got for operands[2]
3665      might coincide with that of operands[0] (which is why we made
3666      it TImode).  Pick the other one to use as our scratch.  */
3667   rtx scratch = gen_rtx (REG, DImode,
3668                          REGNO (operands[0]) == REGNO (operands[2]) 
3669                          ? REGNO (operands[2]) + 1 : REGNO (operands[2]));
3670   rtx seq = gen_unaligned_loadhi (operands[0], addr, scratch,
3671                                   gen_rtx (REG, DImode, REGNO (operands[0])));
3672
3673   alpha_set_memflags (seq, operands[1]);
3674   emit_insn (seq);
3675   DONE;
3676 }")
3677
3678 (define_expand "reload_outqi"
3679   [(parallel [(match_operand:QI 0 "any_memory_operand" "=m")
3680               (match_operand:QI 1 "register_operand" "r")
3681               (match_operand:TI 2 "register_operand" "=&r")])]
3682   ""
3683   "
3684 { extern rtx get_unaligned_address ();
3685
3686   if (aligned_memory_operand (operands[0], QImode))
3687     {
3688       rtx aligned_mem, bitnum;
3689
3690       get_aligned_mem (operands[0], &aligned_mem, &bitnum);
3691
3692       emit_insn (gen_aligned_store (aligned_mem, operands[1], bitnum,
3693                                     gen_rtx (REG, SImode, REGNO (operands[2])),
3694                                     gen_rtx (REG, SImode,
3695                                              REGNO (operands[2]) + 1)));
3696     }
3697   else
3698     {
3699       rtx addr = get_unaligned_address (operands[0], 0);
3700       rtx scratch1 = gen_rtx (REG, DImode, REGNO (operands[2]));
3701       rtx scratch2 = gen_rtx (REG, DImode, REGNO (operands[2]) + 1);
3702       rtx scratch3 = scratch1;
3703       rtx seq;
3704
3705       if (GET_CODE (addr) == REG)
3706         scratch1 = addr;
3707
3708       seq = gen_unaligned_storeqi (addr, operands[1], scratch1,
3709                                    scratch2, scratch3);
3710       alpha_set_memflags (seq, operands[0]);
3711       emit_insn (seq);
3712     }
3713
3714   DONE;
3715 }")
3716
3717 (define_expand "reload_outhi"
3718   [(parallel [(match_operand:HI 0 "any_memory_operand" "=m")
3719               (match_operand:HI 1 "register_operand" "r")
3720               (match_operand:TI 2 "register_operand" "=&r")])]
3721   ""
3722   "
3723 { extern rtx get_unaligned_address ();
3724
3725   if (aligned_memory_operand (operands[0], HImode))
3726     {
3727       rtx aligned_mem, bitnum;
3728
3729       get_aligned_mem (operands[0], &aligned_mem, &bitnum);
3730
3731       emit_insn (gen_aligned_store (aligned_mem, operands[1], bitnum,
3732                                     gen_rtx (REG, SImode, REGNO (operands[2])),
3733                                     gen_rtx (REG, SImode,
3734                                              REGNO (operands[2]) + 1)));
3735     }
3736   else
3737     {
3738       rtx addr = get_unaligned_address (operands[0], 0);
3739       rtx scratch1 = gen_rtx (REG, DImode, REGNO (operands[2]));
3740       rtx scratch2 = gen_rtx (REG, DImode, REGNO (operands[2]) + 1);
3741       rtx scratch3 = scratch1;
3742       rtx seq;
3743
3744       if (GET_CODE (addr) == REG)
3745         scratch1 = addr;
3746
3747       seq = gen_unaligned_storehi (addr, operands[1], scratch1,
3748                                    scratch2, scratch3);
3749       alpha_set_memflags (seq, operands[0]);
3750       emit_insn (seq);
3751     }
3752
3753   DONE;
3754 }")
3755 \f
3756 ;; Subroutine of stack space allocation.  Perform a stack probe.
3757 (define_expand "probe_stack"
3758   [(set (match_dup 1) (match_operand:DI 0 "const_int_operand" ""))]
3759   ""
3760   "
3761 {
3762   operands[1] = gen_rtx (MEM, DImode, plus_constant (stack_pointer_rtx,
3763                                                      INTVAL (operands[0])));
3764   MEM_VOLATILE_P (operands[1]) = 1;
3765
3766   operands[0] = const0_rtx;
3767 }")
3768
3769 ;; This is how we allocate stack space.  If we are allocating a
3770 ;; constant amount of space and we know it is less than 4096
3771 ;; bytes, we need do nothing.
3772 ;;
3773 ;; If it is more than 4096 bytes, we need to probe the stack
3774 ;; periodically. 
3775 (define_expand "allocate_stack"
3776   [(set (reg:DI 30)
3777         (plus:DI (reg:DI 30)
3778                  (match_operand:DI 0 "reg_or_cint_operand" "")))]
3779   ""
3780   "
3781 {
3782   if (GET_CODE (operands[0]) == CONST_INT
3783            && INTVAL (operands[0]) < 32768)
3784     {
3785       if (INTVAL (operands[0]) >= 4096)
3786         {
3787           /* We do this the same way as in the prologue and generate explicit
3788              probes.  Then we update the stack by the constant.  */
3789
3790           int probed = 4096;
3791
3792           emit_insn (gen_probe_stack (GEN_INT (- probed)));
3793           while (probed + 8192 < INTVAL (operands[0]))
3794             emit_insn (gen_probe_stack (GEN_INT (- (probed += 8192))));
3795
3796           if (probed + 4096 < INTVAL (operands[0]))
3797             emit_insn (gen_probe_stack (GEN_INT (- INTVAL(operands[0]))));
3798         }
3799
3800       operands[0] = GEN_INT (- INTVAL (operands[0]));
3801     }
3802   else
3803     {
3804       rtx out_label = 0;
3805       rtx loop_label = gen_label_rtx ();
3806       rtx want = gen_reg_rtx (Pmode);
3807       rtx tmp = gen_reg_rtx (Pmode);
3808       rtx memref;
3809
3810       emit_insn (gen_subdi3 (want, stack_pointer_rtx,
3811                              force_reg (Pmode, operands[0])));
3812       emit_insn (gen_adddi3 (tmp, stack_pointer_rtx, GEN_INT (-4096)));
3813
3814       if (GET_CODE (operands[0]) != CONST_INT)
3815         {
3816           out_label = gen_label_rtx ();
3817           emit_insn (gen_cmpdi (want, tmp));
3818           emit_jump_insn (gen_bgeu (out_label));
3819         }
3820
3821       emit_label (loop_label);
3822       memref = gen_rtx (MEM, DImode, tmp);
3823       MEM_VOLATILE_P (memref) = 1;
3824       emit_move_insn (memref, const0_rtx);
3825       emit_insn (gen_adddi3 (tmp, tmp, GEN_INT(-8192)));
3826       emit_insn (gen_cmpdi (tmp, want));
3827       emit_jump_insn (gen_bgtu (loop_label));
3828       memref = gen_rtx (MEM, DImode, want);
3829       MEM_VOLATILE_P (memref) = 1;
3830       emit_move_insn (memref, const0_rtx);
3831
3832       if (out_label)
3833         emit_label (out_label);
3834
3835       emit_move_insn (stack_pointer_rtx, want);
3836
3837       DONE;
3838     }
3839 }")