OSDN Git Service

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