OSDN Git Service

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