OSDN Git Service

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