OSDN Git Service

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