OSDN Git Service

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