OSDN Git Service

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