OSDN Git Service

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