OSDN Git Service

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