OSDN Git Service

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