OSDN Git Service

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