OSDN Git Service

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