OSDN Git Service

(unaligned_{load,store}hi): Clear low bit of address before using as operand
[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 (match_operand:DI 4 "register_operand" "")
2722         (and:DI (match_dup 1) (const_int -2)))
2723    (set (subreg:DI (match_operand:HI 0 "register_operand" "") 0)
2724         (zero_extract:DI (match_dup 3)
2725                          (const_int 16)
2726                          (ashift:DI (match_dup 4) (const_int 3))))]
2727   ""
2728   "")
2729        
2730 ;; Storing an aligned byte or word requires two temporaries.  Operand 0 is the
2731 ;; aligned SImode MEM.  Operand 1 is the register containing the 
2732 ;; byte or word to store.  Operand 2 is the number of bits within the word that
2733 ;; the value should be placed.  Operands 3 and 4 are SImode temporaries.
2734
2735 (define_expand "aligned_store"
2736   [(set (match_operand:SI 3 "register_operand" "")
2737         (match_operand:SI 0 "memory_operand" ""))
2738    (set (subreg:DI (match_dup 3) 0)
2739         (and:DI (subreg:DI (match_dup 3) 0) (match_dup 5)))
2740    (set (subreg:DI (match_operand:SI 4 "register_operand" "") 0)
2741         (ashift:DI (zero_extend:DI (match_operand 1 "register_operand" ""))
2742                    (match_operand:DI 2 "const_int_operand" "")))
2743    (set (subreg:DI (match_dup 4) 0)
2744         (ior:DI (subreg:DI (match_dup 4) 0) (subreg:DI (match_dup 3) 0)))
2745    (set (match_dup 0) (match_dup 4))]
2746   ""
2747   "
2748 { operands[5] = GEN_INT (~ (GET_MODE_MASK (GET_MODE (operands[1]))
2749                             << INTVAL (operands[2])));
2750 }")
2751
2752 ;; For the unaligned byte case, we use code similar to that in the
2753 ;; Architecture book, but reordered to lower the number of registers
2754 ;; required.  Operand 0 is the address.  Operand 1 is the data to store.
2755 ;; Operands 2, 3, and 4 are DImode temporaries, where the last two may
2756 ;; be the same temporary, if desired.  If the address is in a register,
2757 ;; operand 2 can be that register.
2758
2759 (define_expand "unaligned_storeqi"
2760   [(set (match_operand:DI 3 "register_operand" "")
2761         (mem:DI (and:DI (match_operand:DI 0 "address_operand" "")
2762                         (const_int -8))))
2763    (set (match_operand:DI 2 "register_operand" "")
2764         (match_dup 0))
2765    (set (match_dup 3)
2766         (and:DI (not:DI (ashift:DI (const_int 255)
2767                                    (ashift:DI (match_dup 2) (const_int 3))))
2768                 (match_dup 3)))
2769    (set (match_operand:DI 4 "register_operand" "")
2770         (ashift:DI (zero_extend:DI (match_operand:QI 1 "register_operand" ""))
2771                    (ashift:DI (match_dup 2) (const_int 3))))
2772    (set (match_dup 4) (ior:DI (match_dup 4) (match_dup 3)))
2773    (set (mem:DI (and:DI (match_dup 0) (const_int -8)))
2774         (match_dup 4))]
2775   ""
2776   "")
2777
2778 ;; This is the code for storing into an unaligned short.  It uses the same
2779 ;; trick as loading from an unaligned short.  It needs lots of temporaries.
2780 ;; However, during reload, we only have two registers available.  So we
2781 ;; repeat code so that only two temporaries are available.  During RTL
2782 ;; generation, we can use different pseudos for each temporary and CSE
2783 ;; will remove the redundancies.  During reload, we have to settle with
2784 ;; what we get.  Luckily, unaligned accesses of this kind produced during
2785 ;; reload are quite rare.
2786 ;;
2787 ;; Operand 0 is the address of the memory location.  Operand 1 contains the
2788 ;; data to store.  The rest of the operands are all temporaries, with
2789 ;; various overlap possibilities during reload.  See reload_outhi for
2790 ;; details of this use.
2791
2792 (define_expand "unaligned_storehi"
2793   [(set (match_operand:DI 2 "register_operand" "")
2794         (match_operand:DI 0 "address_operand" ""))
2795    (set (match_operand:DI 3 "register_operand" "")
2796         (and:DI (match_dup 2) (const_int -7)))
2797    (set (match_operand:DI 4 "register_operand" "")
2798         (mem:DI (match_dup 3)))
2799    (set (match_operand:DI 10 "register_operand" "")
2800         (and:DI (match_dup 2) (const_int -2)))
2801    (set (match_operand:DI 5 "register_operand" "")
2802         (and:DI (not:DI (ashift:DI (const_int 65535)
2803                                    (ashift:DI (match_dup 10) (const_int 3))))
2804                 (match_dup 4)))
2805    (set (match_operand:DI 6 "register_operand" "")
2806         (ashift:DI (zero_extend:DI (match_operand:HI 1 "register_operand" ""))
2807                    (ashift:DI (match_dup 10) (const_int 3))))
2808    (set (match_operand:DI 7 "register_operand" "")
2809         (ior:DI (match_dup 5) (match_dup 6)))
2810    (set (match_operand:DI 8 "register_operand" "") (match_dup 0))
2811    (set (match_operand:DI 9 "register_operand" "")
2812         (and:DI (match_dup 8) (const_int -7)))
2813    (set (mem:DI (match_dup 9)) (match_dup 7))]
2814   ""
2815   "")
2816 \f
2817 ;; Here are the define_expand's for QI and HI moves that use the above
2818 ;; patterns.  We have the normal sets, plus the ones that need scratch
2819 ;; registers for reload.
2820
2821 (define_expand "movqi"
2822   [(set (match_operand:QI 0 "general_operand" "")
2823         (match_operand:QI 1 "general_operand" ""))]
2824   ""
2825   "
2826 { extern rtx get_unaligned_address ();
2827
2828   /* If the output is not a register, the input must be.  */
2829   if (GET_CODE (operands[0]) == MEM)
2830     operands[1] = force_reg (QImode, operands[1]);
2831
2832   /* Handle four memory cases, unaligned and aligned for either the input
2833      or the output.  The only case where we can be called during reload is
2834      for aligned loads; all other cases require temporaries.  */
2835
2836   if (GET_CODE (operands[1]) == MEM
2837       || (GET_CODE (operands[1]) == SUBREG
2838           && GET_CODE (SUBREG_REG (operands[1])) == MEM)
2839       || (reload_in_progress && GET_CODE (operands[1]) == REG
2840           && REGNO (operands[1]) >= FIRST_PSEUDO_REGISTER)
2841       || (reload_in_progress && GET_CODE (operands[1]) == SUBREG
2842           && GET_CODE (SUBREG_REG (operands[1])) == REG
2843           && REGNO (SUBREG_REG (operands[1])) >= FIRST_PSEUDO_REGISTER))
2844     {
2845       if (aligned_memory_operand (operands[1], QImode))
2846         {
2847           rtx aligned_mem, bitnum;
2848           rtx scratch = (reload_in_progress
2849                          ? gen_rtx (REG, SImode, REGNO (operands[0]))
2850                          : gen_reg_rtx (SImode));
2851
2852           get_aligned_mem (operands[1], &aligned_mem, &bitnum);
2853
2854           emit_insn (gen_aligned_loadqi (operands[0], aligned_mem, bitnum,
2855                                          scratch));
2856         }
2857       else
2858         {
2859           /* Don't pass these as parameters since that makes the generated
2860              code depend on parameter evaluation order which will cause
2861              bootstrap failures.  */
2862
2863           rtx temp1 = gen_reg_rtx (DImode);
2864           rtx temp2 = gen_reg_rtx (DImode);
2865           rtx seq = gen_unaligned_loadqi (operands[0],
2866                                           get_unaligned_address (operands[1]),
2867                                           temp1, temp2);
2868
2869           alpha_set_memflags (seq, operands[1]);
2870           emit_insn (seq);
2871         }
2872
2873       DONE;
2874     }
2875
2876   else if (GET_CODE (operands[0]) == MEM
2877            || (GET_CODE (operands[0]) == SUBREG 
2878                && GET_CODE (SUBREG_REG (operands[0])) == MEM)
2879            || (reload_in_progress && GET_CODE (operands[0]) == REG
2880                && REGNO (operands[0]) >= FIRST_PSEUDO_REGISTER)
2881            || (reload_in_progress && GET_CODE (operands[0]) == SUBREG
2882                && GET_CODE (SUBREG_REG (operands[0])) == REG
2883                && REGNO (operands[0]) >= FIRST_PSEUDO_REGISTER))
2884     {
2885       if (aligned_memory_operand (operands[0], QImode))
2886         {
2887           rtx aligned_mem, bitnum;
2888           rtx temp1 = gen_reg_rtx (SImode);
2889           rtx temp2 = gen_reg_rtx (SImode);
2890
2891           get_aligned_mem (operands[0], &aligned_mem, &bitnum);
2892
2893           emit_insn (gen_aligned_store (aligned_mem, operands[1], bitnum,
2894                                         temp1, temp2));
2895         }
2896       else
2897         {
2898           rtx temp1 = gen_reg_rtx (DImode);
2899           rtx temp2 = gen_reg_rtx (DImode);
2900           rtx temp3 = gen_reg_rtx (DImode);
2901           rtx seq = gen_unaligned_storeqi (get_unaligned_address (operands[0]),
2902                                            operands[1], temp1, temp2, temp3);
2903
2904           alpha_set_memflags (seq, operands[0]);
2905           emit_insn (seq);
2906         }
2907       DONE;
2908     }
2909 }")
2910
2911 (define_expand "movhi"
2912   [(set (match_operand:HI 0 "general_operand" "")
2913         (match_operand:HI 1 "general_operand" ""))]
2914   ""
2915   "
2916 { extern rtx get_unaligned_address ();
2917
2918   /* If the output is not a register, the input must be.  */
2919   if (GET_CODE (operands[0]) == MEM)
2920     operands[1] = force_reg (HImode, operands[1]);
2921
2922   /* Handle four memory cases, unaligned and aligned for either the input
2923      or the output.  The only case where we can be called during reload is
2924      for aligned loads; all other cases require temporaries.  */
2925
2926   if (GET_CODE (operands[1]) == MEM
2927       || (GET_CODE (operands[1]) == SUBREG
2928           && GET_CODE (SUBREG_REG (operands[1])) == MEM)
2929       || (reload_in_progress && GET_CODE (operands[1]) == REG
2930           && REGNO (operands[1]) >= FIRST_PSEUDO_REGISTER)
2931       || (reload_in_progress && GET_CODE (operands[1]) == SUBREG
2932           && GET_CODE (SUBREG_REG (operands[1])) == REG
2933           && REGNO (SUBREG_REG (operands[1])) >= FIRST_PSEUDO_REGISTER))
2934     {
2935       if (aligned_memory_operand (operands[1], HImode))
2936         {
2937           rtx aligned_mem, bitnum;
2938           rtx scratch = (reload_in_progress
2939                          ? gen_rtx (REG, SImode, REGNO (operands[0]))
2940                          : gen_reg_rtx (SImode));
2941
2942           get_aligned_mem (operands[1], &aligned_mem, &bitnum);
2943
2944           emit_insn (gen_aligned_loadhi (operands[0], aligned_mem, bitnum,
2945                                          scratch));
2946         }
2947       else
2948         {
2949           rtx addr
2950             = force_reg (DImode,
2951                          force_operand (get_unaligned_address (operands[1]),
2952                                         NULL_RTX));
2953           rtx scratch1 = gen_reg_rtx (DImode);
2954           rtx scratch2 = gen_reg_rtx (DImode);
2955           rtx scratch3 = gen_reg_rtx (DImode);
2956
2957           rtx seq = gen_unaligned_loadhi (operands[0], addr, scratch1,
2958                                           scratch2, scratch3);
2959
2960           alpha_set_memflags (seq, operands[1]);
2961           emit_insn (seq);
2962         }
2963
2964       DONE;
2965     }
2966
2967   else if (GET_CODE (operands[0]) == MEM
2968            || (GET_CODE (operands[0]) == SUBREG 
2969                && GET_CODE (SUBREG_REG (operands[0])) == MEM)
2970            || (reload_in_progress && GET_CODE (operands[0]) == REG
2971                && REGNO (operands[0]) >= FIRST_PSEUDO_REGISTER)
2972            || (reload_in_progress && GET_CODE (operands[0]) == SUBREG
2973                && GET_CODE (SUBREG_REG (operands[0])) == REG
2974                && REGNO (operands[0]) >= FIRST_PSEUDO_REGISTER))
2975     {
2976       if (aligned_memory_operand (operands[0], HImode))
2977         {
2978           rtx aligned_mem, bitnum;
2979           rtx temp1 = gen_reg_rtx (SImode);
2980           rtx temp2 = gen_reg_rtx (SImode);
2981
2982           get_aligned_mem (operands[0], &aligned_mem, &bitnum);
2983
2984           emit_insn (gen_aligned_store (aligned_mem, operands[1], bitnum,
2985                                         temp1, temp2));
2986         }
2987       else
2988         {
2989           rtx temp1 = gen_reg_rtx (DImode);
2990           rtx temp2 = gen_reg_rtx (DImode);
2991           rtx temp3 = gen_reg_rtx (DImode);
2992           rtx temp4 = gen_reg_rtx (DImode);
2993           rtx temp5 = gen_reg_rtx (DImode);
2994           rtx temp6 = gen_reg_rtx (DImode);
2995           rtx temp7 = gen_reg_rtx (DImode);
2996           rtx temp8 = gen_reg_rtx (DImode);
2997           rtx temp9 = gen_reg_rtx (DImode);
2998
2999           rtx seq = gen_unaligned_storehi (get_unaligned_address (operands[0]),
3000                                            operands[1], temp1, temp2,temp3,
3001                                            temp4, temp5, temp6,temp7,
3002                                            temp8, temp9);
3003
3004           alpha_set_memflags (seq, operands[0]);
3005           emit_insn (seq);
3006         }
3007
3008       DONE;
3009     }
3010 }")
3011
3012 ;; Here are the versions for reload.  Note that in the unaligned cases
3013 ;; we know that the operand must not be a pseudo-register because stack
3014 ;; slots are always aligned references.
3015
3016 (define_expand "reload_inqi"
3017   [(parallel [(match_operand:QI 0 "register_operand" "=r")
3018               (match_operand:QI 1 "unaligned_memory_operand" "m")
3019               (match_operand:DI 2 "register_operand" "=&r")])]
3020   ""
3021   "
3022 { extern rtx get_unaligned_address ();
3023   rtx addr = get_unaligned_address (operands[1]);
3024   rtx seq = gen_unaligned_loadqi (operands[0], addr, operands[2],
3025                                   gen_rtx (REG, DImode, REGNO (operands[0])));
3026
3027   alpha_set_memflags (seq, operands[1]);
3028   emit_insn (seq);
3029   DONE;
3030 }")
3031
3032 (define_expand "reload_inhi"
3033   [(parallel [(match_operand:HI 0 "register_operand" "=r")
3034               (match_operand:HI 1 "unaligned_memory_operand" "m")
3035               (match_operand:TI 2 "register_operand" "=&r")])]
3036   ""
3037   "
3038 { extern rtx get_unaligned_address ();
3039   rtx addr = get_unaligned_address (operands[1]);
3040   rtx scratch1 = gen_rtx (REG, DImode, REGNO (operands[2]));
3041   rtx scratch2 = gen_rtx (REG, DImode, REGNO (operands[2]) + 1);
3042   rtx seq;
3043
3044   if (GET_CODE (addr) != REG)
3045     {
3046       emit_insn (gen_rtx (SET, VOIDmode, scratch2, addr));
3047       addr = scratch2;
3048     }
3049       
3050   seq = gen_unaligned_loadhi (operands[0], addr, scratch1, scratch1, scratch2);
3051   alpha_set_memflags (seq, operands[1]);
3052   emit_insn (seq);
3053   DONE;
3054 }")
3055
3056 (define_expand "reload_outqi"
3057   [(parallel [(match_operand:QI 0 "any_memory_operand" "=m")
3058               (match_operand:QI 1 "register_operand" "r")
3059               (match_operand:TI 2 "register_operand" "=&r")])]
3060   ""
3061   "
3062 { extern rtx get_unaligned_address ();
3063
3064   if (aligned_memory_operand (operands[0], QImode))
3065     {
3066       rtx aligned_mem, bitnum;
3067
3068       get_aligned_mem (operands[0], &aligned_mem, &bitnum);
3069
3070       emit_insn (gen_aligned_store (aligned_mem, operands[1], bitnum,
3071                                     gen_rtx (REG, SImode, REGNO (operands[2])),
3072                                     gen_rtx (REG, SImode,
3073                                              REGNO (operands[2]) + 1)));
3074     }
3075   else
3076     {
3077       rtx addr = get_unaligned_address (operands[0]);
3078       rtx scratch1 = gen_rtx (REG, DImode, REGNO (operands[2]));
3079       rtx scratch2 = gen_rtx (REG, DImode, REGNO (operands[2]) + 1);
3080       rtx seq;
3081
3082       if (GET_CODE (addr) == REG)
3083         scratch1 = addr;
3084
3085       seq = gen_unaligned_storeqi (addr, operands[1], scratch1,
3086                                    scratch2, scratch2);
3087       alpha_set_memflags (seq, operands[0]);
3088       emit_insn (seq);
3089     }
3090
3091   DONE;
3092 }")
3093
3094 (define_expand "reload_outhi"
3095   [(parallel [(match_operand:HI 0 "any_memory_operand" "=m")
3096               (match_operand:HI 1 "register_operand" "r")
3097               (match_operand:TI 2 "register_operand" "=&r")])]
3098   ""
3099   "
3100 { extern rtx get_unaligned_address ();
3101
3102   if (aligned_memory_operand (operands[0], HImode))
3103     {
3104       rtx aligned_mem, bitnum;
3105
3106       get_aligned_mem (operands[0], &aligned_mem, &bitnum);
3107
3108       emit_insn (gen_aligned_store (aligned_mem, operands[1], bitnum,
3109                                     gen_rtx (REG, SImode, REGNO (operands[2])),
3110                                     gen_rtx (REG, SImode,
3111                                              REGNO (operands[2]) + 1)));
3112     }
3113   else
3114     {
3115       rtx addr = get_unaligned_address (operands[0]);
3116       rtx scratch1 = gen_rtx (REG, DImode, REGNO (operands[2]));
3117       rtx scratch2 = gen_rtx (REG, DImode, REGNO (operands[2]) + 1);
3118       rtx scratch_a = GET_CODE (addr) == REG ? addr : scratch1;
3119       rtx seq;
3120
3121       seq = gen_unaligned_storehi (addr, operands[1], scratch_a,
3122                                    scratch2, scratch2, scratch2,
3123                                    scratch1, scratch2, scratch_a,
3124                                    scratch1, scratch_a);
3125       alpha_set_memflags (seq, operands[0]);
3126       emit_insn (seq);
3127     }
3128
3129   DONE;
3130 }")
3131 \f
3132 ;; Subroutine of stack space allocation.  Perform a stack probe.
3133 (define_expand "probe_stack"
3134   [(set (match_dup 1) (match_operand:DI 0 "const_int_operand" ""))]
3135   ""
3136   "
3137 {
3138   operands[0] = gen_rtx (MEM, DImode, plus_constant (stack_pointer_rtx,
3139                                                      INTVAL (operands[0])));
3140   MEM_VOLATILE_P (operands[0]) = 1;
3141
3142   operands[1] = gen_reg_rtx (DImode);
3143 }")
3144
3145 ;; This is how we allocate stack space.  If we are allocating a
3146 ;; constant amount of space and we know it is less than 4096
3147 ;; bytes, we need do nothing.
3148 ;;
3149 ;; If it is more than 4096 bytes, we need to probe the stack
3150 ;; periodically. 
3151 (define_expand "allocate_stack"
3152   [(set (reg:DI 30)
3153         (plus:DI (reg:DI 30)
3154                  (match_operand:DI 0 "reg_or_cint_operand" "")))]
3155   ""
3156   "
3157 {
3158   if (GET_CODE (operands[0]) == CONST_INT
3159            && INTVAL (operands[0]) < 32768)
3160     {
3161       if (INTVAL (operands[0]) >= 4096)
3162         {
3163           /* We do this the same way as in the prologue and generate explicit
3164              probes.  Then we update the stack by the constant.  */
3165
3166           int probed = 4096;
3167
3168           emit_insn (gen_probe_stack (GEN_INT (- probed)));
3169           while (probed + 8192 < INTVAL (operands[0]))
3170             emit_insn (gen_probe_stack (GEN_INT (- (probed += 8192))));
3171
3172           if (probed + 4096 < INTVAL (operands[0]))
3173             emit_insn (gen_probe_stack (GEN_INT (- (probed += 4096))));
3174         }
3175
3176       operands[0] = GEN_INT (- INTVAL (operands[0]));
3177     }
3178   else
3179     {
3180       rtx out_label = 0;
3181       rtx loop_label = gen_label_rtx ();
3182       rtx count = gen_reg_rtx (DImode);
3183       rtx access = gen_reg_rtx (Pmode);
3184       rtx memref = gen_rtx (MEM, DImode, access);
3185
3186       MEM_VOLATILE_P (memref) = 1;
3187
3188       /* If the amount to be allocated is not a constant, we only need to
3189          do something special if it is >= 4096.  */
3190
3191       if (GET_CODE (operands[0]) != CONST_INT)
3192         {
3193           operands[0] = force_reg (DImode, operands[0]);
3194           out_label = gen_label_rtx ();
3195           emit_insn (gen_cmpdi (operands[0],
3196                                 force_reg (DImode, GEN_INT (4096))));
3197           emit_jump_insn (gen_ble (out_label));
3198
3199           /* Compute COUNT = (N + 4096) / 8192.  N is known positive.  */
3200           emit_insn (gen_adddi3 (count, operands[0], GEN_INT (4096)));
3201           emit_insn (gen_lshrdi3 (count, count, GEN_INT (13)));
3202         }
3203       else
3204         emit_move_insn (count, GEN_INT ((INTVAL (operands[0]) + 4096) >> 13));
3205
3206       /* ACCESS = SP + 4096.  */
3207       emit_insn (gen_adddi3 (access, stack_pointer_rtx, GEN_INT (4096)));
3208       emit_label (loop_label);
3209
3210       /* Each iteration subtracts 8192 from ACCESS and references it.  */
3211       emit_insn (gen_adddi3 (count, count, constm1_rtx));
3212       emit_insn (gen_adddi3 (access, access, GEN_INT (-8192)));
3213       emit_move_insn (gen_reg_rtx (DImode), memref);
3214       emit_insn (gen_cmpdi (count, const0_rtx));
3215       emit_jump_insn (gen_bgt (loop_label));
3216
3217       if (out_label)
3218         emit_label (out_label);
3219
3220       /* We need to subtract operands[0] from SP.  We know it isn't a
3221          constant less than 32768, so we know we have to load it into
3222          a register.  */
3223
3224       emit_insn (gen_subdi3 (stack_pointer_rtx, stack_pointer_rtx,
3225                              force_reg (Pmode, operands[0])));
3226
3227       /* Now, unless we have a constant and we know that we are within
3228          4096 from the end, we need to access sp + 4096.  */
3229       if (! (GET_CODE (operands[0]) == CONST_INT
3230              && (INTVAL (operands[0]) % 8192) < 4096))
3231         emit_insn (gen_probe_stack (GEN_INT (4096)));
3232
3233       DONE;
3234     }
3235 }")