OSDN Git Service

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