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