OSDN Git Service

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