OSDN Git Service

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