OSDN Git Service

* alpha.md (mov patterns): Emit the assembler aliases mov and fmov
[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         == INTVAL (operands[3]))
1695        || ((unsigned HOST_WIDE_INT) 0xffff << INTVAL (operands[2])
1696         == INTVAL (operands[3]))
1697        || ((unsigned HOST_WIDE_INT) 0xffffffff << INTVAL (operands[2])
1698         == INTVAL (operands[3])))"
1699   "*
1700 {
1701 #if HOST_BITS_PER_WIDE_INT == 64
1702   if ((unsigned HOST_WIDE_INT) 0xff << INTVAL (operands[2])
1703       == INTVAL (operands[3]))
1704     return \"insbl %1,%s2,%0\";
1705   if ((unsigned HOST_WIDE_INT) 0xffff << INTVAL (operands[2])
1706       == INTVAL (operands[3]))
1707     return \"inswl %1,%s2,%0\";
1708   if ((unsigned HOST_WIDE_INT) 0xffffffff << INTVAL (operands[2])
1709       == 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 ;; This form is added since combine thinks that an IF_THEN_ELSE with both
2377 ;; arms constant is a single insn, so it won't try to form it if combine
2378 ;; knows they are really two insns.  This occurs in divides by powers
2379 ;; of two.
2380
2381 (define_insn ""
2382   [(set (match_operand:DI 0 "register_operand" "=r")
2383         (if_then_else:DI
2384          (match_operator 2 "signed_comparison_operator"
2385                          [(match_operand:DI 3 "reg_or_0_operand" "rJ")
2386                           (const_int 0)])
2387          (plus:DI (match_dup 0)
2388                   (match_operand:DI 1 "reg_or_8bit_operand" "rI"))
2389          (match_dup 0)))
2390    (clobber (match_scratch:DI 4 "=&r"))]
2391   ""
2392   "addq %0,%1,%4\;cmov%C2 %r3,%4,%0"
2393   [(set_attr "type" "icmov")
2394    (set_attr "length" "8")])
2395
2396 (define_split
2397   [(set (match_operand:DI 0 "register_operand" "")
2398         (if_then_else:DI
2399          (match_operator 2 "signed_comparison_operator"
2400                          [(match_operand:DI 3 "reg_or_0_operand" "")
2401                           (const_int 0)])
2402          (plus:DI (match_dup 0)
2403                   (match_operand:DI 1 "reg_or_8bit_operand" ""))
2404          (match_dup 0)))
2405    (clobber (match_operand:DI 4 "register_operand" ""))]
2406   ""
2407   [(set (match_dup 4) (plus:DI (match_dup 0) (match_dup 1)))
2408    (set (match_dup 0) (if_then_else:DI (match_op_dup 2
2409                                                      [(match_dup 3)
2410                                                       (const_int 0)])
2411                                        (match_dup 4) (match_dup 0)))]
2412   "")
2413
2414 (define_split
2415   [(parallel
2416     [(set (match_operand:DI 0 "register_operand" "")
2417           (if_then_else:DI
2418            (match_operator 1 "comparison_operator"
2419                            [(zero_extract:DI (match_operand:DI 2 "register_operand" "")
2420                                              (const_int 1)
2421                                              (match_operand:DI 3 "const_int_operand" ""))
2422                             (const_int 0)])
2423            (match_operand:DI 4 "reg_or_8bit_operand" "")
2424            (match_operand:DI 5 "reg_or_8bit_operand" "")))
2425      (clobber (match_operand:DI 6 "register_operand" ""))])]
2426   "INTVAL (operands[3]) != 0"
2427   [(set (match_dup 6)
2428         (lshiftrt:DI (match_dup 2) (match_dup 3)))
2429    (set (match_dup 0)
2430         (if_then_else:DI (match_op_dup 1
2431                                        [(zero_extract:DI (match_dup 6)
2432                                                          (const_int 1)
2433                                                          (const_int 0))
2434                                         (const_int 0)])
2435                          (match_dup 4)
2436                          (match_dup 5)))]
2437   "")
2438
2439 ;; For ABS, we have two choices, depending on whether the input and output
2440 ;; registers are the same or not.
2441 (define_expand "absdi2"
2442   [(set (match_operand:DI 0 "register_operand" "")
2443         (abs:DI (match_operand:DI 1 "register_operand" "")))]
2444   ""
2445   "
2446 { if (rtx_equal_p (operands[0], operands[1]))
2447     emit_insn (gen_absdi2_same (operands[0], gen_reg_rtx (DImode)));
2448   else
2449     emit_insn (gen_absdi2_diff (operands[0], operands[1]));
2450
2451   DONE;
2452 }")
2453
2454 (define_expand "absdi2_same"
2455   [(set (match_operand:DI 1 "register_operand" "")
2456         (neg:DI (match_operand:DI 0 "register_operand" "")))
2457    (set (match_dup 0)
2458         (if_then_else:DI (ge (match_dup 0) (const_int 0))
2459                          (match_dup 0)
2460                          (match_dup 1)))]
2461   ""
2462   "")
2463
2464 (define_expand "absdi2_diff"
2465   [(set (match_operand:DI 0 "register_operand" "")
2466         (neg:DI (match_operand:DI 1 "register_operand" "")))
2467    (set (match_dup 0)
2468         (if_then_else:DI (lt (match_dup 1) (const_int 0))
2469                          (match_dup 0)
2470                          (match_dup 1)))]
2471   ""
2472   "")
2473
2474 (define_split
2475   [(set (match_operand:DI 0 "register_operand" "")
2476         (abs:DI (match_dup 0)))
2477    (clobber (match_operand:DI 2 "register_operand" ""))]
2478   ""
2479   [(set (match_dup 1) (neg:DI (match_dup 0)))
2480    (set (match_dup 0) (if_then_else:DI (ge (match_dup 0) (const_int 0))
2481                                        (match_dup 0) (match_dup 1)))]
2482   "")
2483
2484 (define_split
2485   [(set (match_operand:DI 0 "register_operand" "")
2486         (abs:DI (match_operand:DI 1 "register_operand" "")))]
2487   "! rtx_equal_p (operands[0], operands[1])"
2488   [(set (match_dup 0) (neg:DI (match_dup 1)))
2489    (set (match_dup 0) (if_then_else:DI (lt (match_dup 1) (const_int 0))
2490                                        (match_dup 0) (match_dup 1)))]
2491   "")
2492
2493 (define_split
2494   [(set (match_operand:DI 0 "register_operand" "")
2495         (neg:DI (abs:DI (match_dup 0))))
2496    (clobber (match_operand:DI 2 "register_operand" ""))]
2497   ""
2498   [(set (match_dup 1) (neg:DI (match_dup 0)))
2499    (set (match_dup 0) (if_then_else:DI (le (match_dup 0) (const_int 0))
2500                                        (match_dup 0) (match_dup 1)))]
2501   "")
2502
2503 (define_split
2504   [(set (match_operand:DI 0 "register_operand" "")
2505         (neg:DI (abs:DI (match_operand:DI 1 "register_operand" ""))))]
2506   "! rtx_equal_p (operands[0], operands[1])"
2507   [(set (match_dup 0) (neg:DI (match_dup 1)))
2508    (set (match_dup 0) (if_then_else:DI (gt (match_dup 1) (const_int 0))
2509                                        (match_dup 0) (match_dup 1)))]
2510   "")
2511
2512 (define_insn "sminqi3"
2513   [(set (match_operand:QI 0 "register_operand" "=r")
2514         (smin:QI (match_operand:QI 1 "reg_or_0_operand" "%rJ")
2515                  (match_operand:QI 2 "reg_or_8bit_operand" "rI")))]
2516   "TARGET_MAX"
2517   "minsb8 %r1,%2,%0"
2518   [(set_attr "type" "mvi")])
2519
2520 (define_insn "uminqi3"
2521   [(set (match_operand:QI 0 "register_operand" "=r")
2522         (umin:QI (match_operand:QI 1 "reg_or_0_operand" "%rJ")
2523                  (match_operand:QI 2 "reg_or_8bit_operand" "rI")))]
2524   "TARGET_MAX"
2525   "minub8 %r1,%2,%0"
2526   [(set_attr "type" "mvi")])
2527
2528 (define_insn "smaxqi3"
2529   [(set (match_operand:QI 0 "register_operand" "=r")
2530         (smax:QI (match_operand:QI 1 "reg_or_0_operand" "%rJ")
2531                  (match_operand:QI 2 "reg_or_8bit_operand" "rI")))]
2532   "TARGET_MAX"
2533   "maxsb8 %r1,%2,%0"
2534   [(set_attr "type" "mvi")])
2535
2536 (define_insn "umaxqi3"
2537   [(set (match_operand:QI 0 "register_operand" "=r")
2538         (umax:QI (match_operand:QI 1 "reg_or_0_operand" "%rJ")
2539                  (match_operand:QI 2 "reg_or_8bit_operand" "rI")))]
2540   "TARGET_MAX"
2541   "maxub8 %r1,%2,%0"
2542   [(set_attr "type" "mvi")])
2543
2544 (define_insn "sminhi3"
2545   [(set (match_operand:HI 0 "register_operand" "=r")
2546         (smin:HI (match_operand:HI 1 "reg_or_0_operand" "%rJ")
2547                  (match_operand:HI 2 "reg_or_8bit_operand" "rI")))]
2548   "TARGET_MAX"
2549   "minsw4 %r1,%2,%0"
2550   [(set_attr "type" "mvi")])
2551
2552 (define_insn "uminhi3"
2553   [(set (match_operand:HI 0 "register_operand" "=r")
2554         (umin:HI (match_operand:HI 1 "reg_or_0_operand" "%rJ")
2555                  (match_operand:HI 2 "reg_or_8bit_operand" "rI")))]
2556   "TARGET_MAX"
2557   "minuw4 %r1,%2,%0"
2558   [(set_attr "type" "mvi")])
2559
2560 (define_insn "smaxhi3"
2561   [(set (match_operand:HI 0 "register_operand" "=r")
2562         (smax:HI (match_operand:HI 1 "reg_or_0_operand" "%rJ")
2563                  (match_operand:HI 2 "reg_or_8bit_operand" "rI")))]
2564   "TARGET_MAX"
2565   "maxsw4 %r1,%2,%0"
2566   [(set_attr "type" "mvi")])
2567
2568 (define_insn "umaxhi3"
2569   [(set (match_operand:HI 0 "register_operand" "=r")
2570         (umax:HI (match_operand:HI 1 "reg_or_0_operand" "%rJ")
2571                  (match_operand:HI 2 "reg_or_8bit_operand" "rI")))]
2572   "TARGET_MAX"
2573   "maxuw4 %r1,%2,%0"
2574   [(set_attr "type" "shift")])
2575
2576 (define_expand "smaxdi3"
2577   [(set (match_dup 3)
2578         (le:DI (match_operand:DI 1 "reg_or_0_operand" "")
2579                (match_operand:DI 2 "reg_or_8bit_operand" "")))
2580    (set (match_operand:DI 0 "register_operand" "")
2581         (if_then_else:DI (eq (match_dup 3) (const_int 0))
2582                          (match_dup 1) (match_dup 2)))]
2583   ""
2584   "
2585 { operands[3] = gen_reg_rtx (DImode);
2586 }")
2587
2588 (define_split
2589   [(set (match_operand:DI 0 "register_operand" "")
2590         (smax:DI (match_operand:DI 1 "reg_or_0_operand" "")
2591                  (match_operand:DI 2 "reg_or_8bit_operand" "")))
2592    (clobber (match_operand:DI 3 "register_operand" ""))]
2593   "operands[2] != const0_rtx"
2594   [(set (match_dup 3) (le:DI (match_dup 1) (match_dup 2)))
2595    (set (match_dup 0) (if_then_else:DI (eq (match_dup 3) (const_int 0))
2596                                        (match_dup 1) (match_dup 2)))]
2597   "")
2598
2599 (define_insn ""
2600   [(set (match_operand:DI 0 "register_operand" "=r")
2601         (smax:DI (match_operand:DI 1 "register_operand" "0")
2602                  (const_int 0)))]
2603   ""
2604   "cmovlt %0,0,%0"
2605   [(set_attr "type" "icmov")])
2606
2607 (define_expand "smindi3"
2608   [(set (match_dup 3)
2609         (lt:DI (match_operand:DI 1 "reg_or_0_operand" "")
2610                (match_operand:DI 2 "reg_or_8bit_operand" "")))
2611    (set (match_operand:DI 0 "register_operand" "")
2612         (if_then_else:DI (ne (match_dup 3) (const_int 0))
2613                          (match_dup 1) (match_dup 2)))]
2614   ""
2615   "
2616 { operands[3] = gen_reg_rtx (DImode);
2617 }")
2618
2619 (define_split
2620   [(set (match_operand:DI 0 "register_operand" "")
2621         (smin:DI (match_operand:DI 1 "reg_or_0_operand" "")
2622                  (match_operand:DI 2 "reg_or_8bit_operand" "")))
2623    (clobber (match_operand:DI 3 "register_operand" ""))]
2624   "operands[2] != const0_rtx"
2625   [(set (match_dup 3) (lt:DI (match_dup 1) (match_dup 2)))
2626    (set (match_dup 0) (if_then_else:DI (ne (match_dup 3) (const_int 0))
2627                                        (match_dup 1) (match_dup 2)))]
2628   "")
2629
2630 (define_insn ""
2631   [(set (match_operand:DI 0 "register_operand" "=r")
2632         (smin:DI (match_operand:DI 1 "register_operand" "0")
2633                  (const_int 0)))]
2634   ""
2635   "cmovgt %0,0,%0"
2636   [(set_attr "type" "icmov")])
2637
2638 (define_expand "umaxdi3"
2639   [(set (match_dup 3) 
2640         (leu:DI (match_operand:DI 1 "reg_or_0_operand" "")
2641                 (match_operand:DI 2 "reg_or_8bit_operand" "")))
2642    (set (match_operand:DI 0 "register_operand" "")
2643         (if_then_else:DI (eq (match_dup 3) (const_int 0))
2644                          (match_dup 1) (match_dup 2)))]
2645   ""
2646   "
2647 { operands[3] = gen_reg_rtx (DImode);
2648 }")
2649
2650 (define_split
2651   [(set (match_operand:DI 0 "register_operand" "")
2652         (umax:DI (match_operand:DI 1 "reg_or_0_operand" "")
2653                  (match_operand:DI 2 "reg_or_8bit_operand" "")))
2654    (clobber (match_operand:DI 3 "register_operand" ""))]
2655   "operands[2] != const0_rtx"
2656   [(set (match_dup 3) (leu:DI (match_dup 1) (match_dup 2)))
2657    (set (match_dup 0) (if_then_else:DI (eq (match_dup 3) (const_int 0))
2658                                        (match_dup 1) (match_dup 2)))]
2659   "")
2660
2661 (define_expand "umindi3"
2662   [(set (match_dup 3)
2663         (ltu:DI (match_operand:DI 1 "reg_or_0_operand" "")
2664                 (match_operand:DI 2 "reg_or_8bit_operand" "")))
2665    (set (match_operand:DI 0 "register_operand" "")
2666         (if_then_else:DI (ne (match_dup 3) (const_int 0))
2667                          (match_dup 1) (match_dup 2)))]
2668   ""
2669   "
2670 { operands[3] = gen_reg_rtx (DImode);
2671 }")
2672
2673 (define_split
2674   [(set (match_operand:DI 0 "register_operand" "")
2675         (umin:DI (match_operand:DI 1 "reg_or_0_operand" "")
2676                  (match_operand:DI 2 "reg_or_8bit_operand" "")))
2677    (clobber (match_operand:DI 3 "register_operand" ""))]
2678   "operands[2] != const0_rtx"
2679   [(set (match_dup 3) (ltu:DI (match_dup 1) (match_dup 2)))
2680    (set (match_dup 0) (if_then_else:DI (ne (match_dup 3) (const_int 0))
2681                                        (match_dup 1) (match_dup 2)))]
2682   "")
2683
2684 (define_insn ""
2685   [(set (pc)
2686         (if_then_else
2687          (match_operator 1 "signed_comparison_operator"
2688                          [(match_operand:DI 2 "reg_or_0_operand" "rJ")
2689                           (const_int 0)])
2690          (label_ref (match_operand 0 "" ""))
2691          (pc)))]
2692   ""
2693   "b%C1 %r2,%0"
2694   [(set_attr "type" "ibr")])
2695
2696 (define_insn ""
2697   [(set (pc)
2698         (if_then_else
2699          (match_operator 1 "signed_comparison_operator"
2700                          [(const_int 0)
2701                           (match_operand:DI 2 "register_operand" "r")])
2702          (label_ref (match_operand 0 "" ""))
2703          (pc)))]
2704   ""
2705   "b%c1 %2,%0"
2706   [(set_attr "type" "ibr")])
2707
2708 (define_insn ""
2709   [(set (pc)
2710         (if_then_else
2711          (ne (zero_extract:DI (match_operand:DI 1 "reg_or_0_operand" "rJ")
2712                               (const_int 1)
2713                               (const_int 0))
2714              (const_int 0))
2715          (label_ref (match_operand 0 "" ""))
2716          (pc)))]
2717   ""
2718   "blbs %r1,%0"
2719   [(set_attr "type" "ibr")])
2720
2721 (define_insn ""
2722   [(set (pc)
2723         (if_then_else
2724          (eq (zero_extract:DI (match_operand:DI 1 "reg_or_0_operand" "rJ")
2725                               (const_int 1)
2726                               (const_int 0))
2727              (const_int 0))
2728          (label_ref (match_operand 0 "" ""))
2729          (pc)))]
2730   ""
2731   "blbc %r1,%0"
2732   [(set_attr "type" "ibr")])
2733
2734 (define_split
2735   [(parallel
2736     [(set (pc)
2737           (if_then_else
2738            (match_operator 1 "comparison_operator"
2739                            [(zero_extract:DI (match_operand:DI 2 "register_operand" "")
2740                                              (const_int 1)
2741                                              (match_operand:DI 3 "const_int_operand" ""))
2742                             (const_int 0)])
2743            (label_ref (match_operand 0 "" ""))
2744            (pc)))
2745      (clobber (match_operand:DI 4 "register_operand" ""))])]
2746   "INTVAL (operands[3]) != 0"
2747   [(set (match_dup 4)
2748         (lshiftrt:DI (match_dup 2) (match_dup 3)))
2749    (set (pc)
2750         (if_then_else (match_op_dup 1
2751                                     [(zero_extract:DI (match_dup 4)
2752                                                       (const_int 1)
2753                                                       (const_int 0))
2754                                      (const_int 0)])
2755                       (label_ref (match_dup 0))
2756                       (pc)))]
2757   "")
2758 \f
2759 ;; The following are the corresponding floating-point insns.  Recall
2760 ;; we need to have variants that expand the arguments from SF mode
2761 ;; to DFmode.
2762
2763 (define_insn ""
2764   [(set (match_operand:DF 0 "register_operand" "=&f")
2765         (match_operator:DF 1 "alpha_comparison_operator"
2766                            [(match_operand:DF 2 "reg_or_fp0_operand" "fG")
2767                             (match_operand:DF 3 "reg_or_fp0_operand" "fG")]))]
2768   "TARGET_FP && alpha_tp == ALPHA_TP_INSN"
2769   "cmp%-%C1%' %R2,%R3,%0"
2770   [(set_attr "type" "fadd")
2771    (set_attr "trap" "yes")])
2772
2773 (define_insn ""
2774   [(set (match_operand:DF 0 "register_operand" "=f")
2775         (match_operator:DF 1 "alpha_comparison_operator"
2776                            [(match_operand:DF 2 "reg_or_fp0_operand" "fG")
2777                             (match_operand:DF 3 "reg_or_fp0_operand" "fG")]))]
2778   "TARGET_FP && alpha_tp != ALPHA_TP_INSN"
2779   "cmp%-%C1%' %R2,%R3,%0"
2780   [(set_attr "type" "fadd")
2781    (set_attr "trap" "yes")])
2782
2783 (define_insn ""
2784   [(set (match_operand:DF 0 "register_operand" "=&f")
2785         (match_operator:DF 1 "alpha_comparison_operator"
2786                            [(float_extend:DF
2787                              (match_operand:SF 2 "reg_or_fp0_operand" "fG"))
2788                             (match_operand:DF 3 "reg_or_fp0_operand" "fG")]))]
2789   "TARGET_FP && alpha_tp == ALPHA_TP_INSN"
2790   "cmp%-%C1%' %R2,%R3,%0"
2791   [(set_attr "type" "fadd")
2792    (set_attr "trap" "yes")])
2793
2794 (define_insn ""
2795   [(set (match_operand:DF 0 "register_operand" "=f")
2796         (match_operator:DF 1 "alpha_comparison_operator"
2797                            [(float_extend:DF
2798                              (match_operand:SF 2 "reg_or_fp0_operand" "fG"))
2799                             (match_operand:DF 3 "reg_or_fp0_operand" "fG")]))]
2800   "TARGET_FP && alpha_tp != ALPHA_TP_INSN"
2801   "cmp%-%C1%' %R2,%R3,%0"
2802   [(set_attr "type" "fadd")
2803    (set_attr "trap" "yes")])
2804
2805 (define_insn ""
2806   [(set (match_operand:DF 0 "register_operand" "=&f")
2807         (match_operator:DF 1 "alpha_comparison_operator"
2808                            [(match_operand:DF 2 "reg_or_fp0_operand" "fG")
2809                             (float_extend:DF
2810                              (match_operand:SF 3 "reg_or_fp0_operand" "fG"))]))]
2811   "TARGET_FP && alpha_tp == ALPHA_TP_INSN"
2812   "cmp%-%C1%' %R2,%R3,%0"
2813   [(set_attr "type" "fadd")
2814    (set_attr "trap" "yes")])
2815
2816 (define_insn ""
2817   [(set (match_operand:DF 0 "register_operand" "=f")
2818         (match_operator:DF 1 "alpha_comparison_operator"
2819                            [(match_operand:DF 2 "reg_or_fp0_operand" "fG")
2820                             (float_extend:DF
2821                              (match_operand:SF 3 "reg_or_fp0_operand" "fG"))]))]
2822   "TARGET_FP && alpha_tp != ALPHA_TP_INSN"
2823   "cmp%-%C1%' %R2,%R3,%0"
2824   [(set_attr "type" "fadd")
2825    (set_attr "trap" "yes")])
2826
2827 (define_insn ""
2828   [(set (match_operand:DF 0 "register_operand" "=&f")
2829         (match_operator:DF 1 "alpha_comparison_operator"
2830                            [(float_extend:DF
2831                              (match_operand:SF 2 "reg_or_fp0_operand" "fG"))
2832                             (float_extend:DF
2833                              (match_operand:SF 3 "reg_or_fp0_operand" "fG"))]))]
2834   "TARGET_FP && alpha_tp == ALPHA_TP_INSN"
2835   "cmp%-%C1%' %R2,%R3,%0"
2836   [(set_attr "type" "fadd")
2837    (set_attr "trap" "yes")])
2838
2839 (define_insn ""
2840   [(set (match_operand:DF 0 "register_operand" "=f")
2841         (match_operator:DF 1 "alpha_comparison_operator"
2842                            [(float_extend:DF
2843                              (match_operand:SF 2 "reg_or_fp0_operand" "fG"))
2844                             (float_extend:DF
2845                              (match_operand:SF 3 "reg_or_fp0_operand" "fG"))]))]
2846   "TARGET_FP && alpha_tp != ALPHA_TP_INSN"
2847   "cmp%-%C1%' %R2,%R3,%0"
2848   [(set_attr "type" "fadd")
2849    (set_attr "trap" "yes")])
2850
2851 (define_insn ""
2852   [(set (match_operand:DF 0 "register_operand" "=f,f")
2853         (if_then_else:DF 
2854          (match_operator 3 "signed_comparison_operator"
2855                          [(match_operand:DF 4 "reg_or_fp0_operand" "fG,fG")
2856                           (match_operand:DF 2 "fp0_operand" "G,G")])
2857          (match_operand:DF 1 "reg_or_fp0_operand" "fG,0")
2858          (match_operand:DF 5 "reg_or_fp0_operand" "0,fG")))]
2859   "TARGET_FP"
2860   "@
2861    fcmov%C3 %R4,%R1,%0
2862    fcmov%D3 %R4,%R5,%0"
2863   [(set_attr "type" "fcmov")])
2864
2865 (define_insn ""
2866   [(set (match_operand:SF 0 "register_operand" "=f,f")
2867         (if_then_else:SF 
2868          (match_operator 3 "signed_comparison_operator"
2869                          [(match_operand:DF 4 "reg_or_fp0_operand" "fG,fG")
2870                           (match_operand:DF 2 "fp0_operand" "G,G")])
2871          (match_operand:SF 1 "reg_or_fp0_operand" "fG,0")
2872          (match_operand:SF 5 "reg_or_fp0_operand" "0,fG")))]
2873   "TARGET_FP"
2874   "@
2875    fcmov%C3 %R4,%R1,%0
2876    fcmov%D3 %R4,%R5,%0"
2877   [(set_attr "type" "fcmov")])
2878
2879 (define_insn ""
2880   [(set (match_operand:DF 0 "register_operand" "=f,f")
2881         (if_then_else:DF 
2882          (match_operator 3 "signed_comparison_operator"
2883                          [(match_operand:DF 4 "reg_or_fp0_operand" "fG,fG")
2884                           (match_operand:DF 2 "fp0_operand" "G,G")])
2885          (float_extend:DF (match_operand:SF 1 "reg_or_fp0_operand" "fG,0"))
2886          (match_operand:DF 5 "reg_or_fp0_operand" "0,fG")))]
2887   "TARGET_FP"
2888   "@
2889    fcmov%C3 %R4,%R1,%0
2890    fcmov%D3 %R4,%R5,%0"
2891   [(set_attr "type" "fcmov")])
2892
2893 (define_insn ""
2894   [(set (match_operand:DF 0 "register_operand" "=f,f")
2895         (if_then_else:DF 
2896          (match_operator 3 "signed_comparison_operator"
2897                          [(float_extend:DF 
2898                            (match_operand:SF 4 "reg_or_fp0_operand" "fG,fG"))
2899                           (match_operand:DF 2 "fp0_operand" "G,G")])
2900          (match_operand:DF 1 "reg_or_fp0_operand" "fG,0")
2901          (match_operand:DF 5 "reg_or_fp0_operand" "0,fG")))]
2902   "TARGET_FP"
2903   "@
2904    fcmov%C3 %R4,%R1,%0
2905    fcmov%D3 %R4,%R5,%0"
2906   [(set_attr "type" "fcmov")])
2907
2908 (define_insn ""
2909   [(set (match_operand:SF 0 "register_operand" "=f,f")
2910         (if_then_else:SF 
2911          (match_operator 3 "signed_comparison_operator"
2912                          [(float_extend:DF
2913                            (match_operand:SF 4 "reg_or_fp0_operand" "fG,fG"))
2914                           (match_operand:DF 2 "fp0_operand" "G,G")])
2915          (match_operand:SF 1 "reg_or_fp0_operand" "fG,0")
2916          (match_operand:SF 5 "reg_or_fp0_operand" "0,fG")))]
2917   "TARGET_FP"
2918   "@
2919    fcmov%C3 %R4,%R1,%0
2920    fcmov%D3 %R4,%R5,%0"
2921   [(set_attr "type" "fcmov")])
2922
2923 (define_insn ""
2924   [(set (match_operand:DF 0 "register_operand" "=f,f")
2925         (if_then_else:DF 
2926          (match_operator 3 "signed_comparison_operator"
2927                          [(float_extend:DF
2928                            (match_operand:SF 4 "reg_or_fp0_operand" "fG,fG"))
2929                           (match_operand:DF 2 "fp0_operand" "G,G")])
2930          (float_extend:DF (match_operand:SF 1 "reg_or_fp0_operand" "fG,0"))
2931          (match_operand:DF 5 "reg_or_fp0_operand" "0,fG")))]
2932   "TARGET_FP"
2933   "@
2934    fcmov%C3 %R4,%R1,%0
2935    fcmov%D3 %R4,%R5,%0"
2936   [(set_attr "type" "fcmov")])
2937
2938 (define_expand "maxdf3"
2939   [(set (match_dup 3)
2940         (le:DF (match_operand:DF 1 "reg_or_fp0_operand" "")
2941                (match_operand:DF 2 "reg_or_fp0_operand" "")))
2942    (set (match_operand:DF 0 "register_operand" "")
2943         (if_then_else:DF (eq (match_dup 3) (match_dup 4))
2944                          (match_dup 1) (match_dup 2)))]
2945   "TARGET_FP"
2946   "
2947 { operands[3] = gen_reg_rtx (DFmode);
2948   operands[4] = CONST0_RTX (DFmode);
2949 }")
2950
2951 (define_expand "mindf3"
2952   [(set (match_dup 3)
2953         (lt:DF (match_operand:DF 1 "reg_or_fp0_operand" "")
2954                (match_operand:DF 2 "reg_or_fp0_operand" "")))
2955    (set (match_operand:DF 0 "register_operand" "")
2956         (if_then_else:DF (ne (match_dup 3) (match_dup 4))
2957                          (match_dup 1) (match_dup 2)))]
2958   "TARGET_FP"
2959   "
2960 { operands[3] = gen_reg_rtx (DFmode);
2961   operands[4] = CONST0_RTX (DFmode);
2962 }")
2963
2964 (define_expand "maxsf3"
2965   [(set (match_dup 3)
2966         (le:DF (float_extend:DF (match_operand:SF 1 "reg_or_fp0_operand" ""))
2967                (float_extend:DF (match_operand:SF 2 "reg_or_fp0_operand" ""))))
2968    (set (match_operand:SF 0 "register_operand" "")
2969         (if_then_else:SF (eq (match_dup 3) (match_dup 4))
2970                          (match_dup 1) (match_dup 2)))]
2971   "TARGET_FP"
2972   "
2973 { operands[3] = gen_reg_rtx (DFmode);
2974   operands[4] = CONST0_RTX (DFmode);
2975 }")
2976
2977 (define_expand "minsf3"
2978   [(set (match_dup 3)
2979         (lt:DF (float_extend:DF (match_operand:SF 1 "reg_or_fp0_operand" ""))
2980                (float_extend:DF (match_operand:SF 2 "reg_or_fp0_operand" ""))))
2981    (set (match_operand:SF 0 "register_operand" "")
2982         (if_then_else:SF (ne (match_dup 3) (match_dup 4))
2983                       (match_dup 1) (match_dup 2)))]
2984   "TARGET_FP"
2985   "
2986 { operands[3] = gen_reg_rtx (DFmode);
2987   operands[4] = CONST0_RTX (DFmode);
2988 }")
2989
2990 (define_insn ""
2991   [(set (pc)
2992         (if_then_else
2993          (match_operator 1 "signed_comparison_operator"
2994                          [(match_operand:DF 2 "reg_or_fp0_operand" "fG")
2995                           (match_operand:DF 3 "fp0_operand" "G")])
2996          (label_ref (match_operand 0 "" ""))
2997          (pc)))]
2998   "TARGET_FP"
2999   "fb%C1 %R2,%0"
3000   [(set_attr "type" "fbr")])
3001
3002 (define_insn ""
3003   [(set (pc)
3004         (if_then_else
3005          (match_operator 1 "signed_comparison_operator"
3006                          [(float_extend:DF
3007                            (match_operand:SF 2 "reg_or_fp0_operand" "fG"))
3008                           (match_operand:DF 3 "fp0_operand" "G")])
3009          (label_ref (match_operand 0 "" ""))
3010          (pc)))]
3011   "TARGET_FP"
3012   "fb%C1 %R2,%0"
3013   [(set_attr "type" "fbr")])
3014 \f
3015 ;; These are the main define_expand's used to make conditional branches
3016 ;; and compares.
3017
3018 (define_expand "cmpdf"
3019   [(set (cc0) (compare (match_operand:DF 0 "reg_or_fp0_operand" "")
3020                        (match_operand:DF 1 "reg_or_fp0_operand" "")))]
3021   "TARGET_FP"
3022   "
3023 {
3024   alpha_compare_op0 = operands[0];
3025   alpha_compare_op1 = operands[1];
3026   alpha_compare_fp_p = 1;
3027   DONE;
3028 }")
3029
3030 (define_expand "cmpdi"
3031   [(set (cc0) (compare (match_operand:DI 0 "reg_or_0_operand" "")
3032                        (match_operand:DI 1 "reg_or_8bit_operand" "")))]
3033   ""
3034   "
3035 {
3036   alpha_compare_op0 = operands[0];
3037   alpha_compare_op1 = operands[1];
3038   alpha_compare_fp_p = 0;
3039   DONE;
3040 }")
3041
3042 (define_expand "beq"
3043   [(set (pc)
3044         (if_then_else (match_dup 1)
3045                       (label_ref (match_operand 0 "" ""))
3046                       (pc)))]
3047   ""
3048   "{ operands[1] = alpha_emit_conditional_branch (EQ); }")
3049
3050 (define_expand "bne"
3051   [(set (pc)
3052         (if_then_else (match_dup 1)
3053                       (label_ref (match_operand 0 "" ""))
3054                       (pc)))]
3055   ""
3056   "{ operands[1] = alpha_emit_conditional_branch (NE); }")
3057
3058 (define_expand "blt"
3059   [(set (pc)
3060         (if_then_else (match_dup 1)
3061                       (label_ref (match_operand 0 "" ""))
3062                       (pc)))]
3063   ""
3064   "{ operands[1] = alpha_emit_conditional_branch (LT); }")
3065
3066 (define_expand "ble"
3067   [(set (pc)
3068         (if_then_else (match_dup 1)
3069                       (label_ref (match_operand 0 "" ""))
3070                       (pc)))]
3071   ""
3072   "{ operands[1] = alpha_emit_conditional_branch (LE); }")
3073
3074 (define_expand "bgt"
3075   [(set (pc)
3076         (if_then_else (match_dup 1)
3077                       (label_ref (match_operand 0 "" ""))
3078                       (pc)))]
3079   ""
3080   "{ operands[1] = alpha_emit_conditional_branch (GT); }")
3081
3082 (define_expand "bge"
3083   [(set (pc)
3084         (if_then_else (match_dup 1)
3085                       (label_ref (match_operand 0 "" ""))
3086                       (pc)))]
3087   ""
3088   "{ operands[1] = alpha_emit_conditional_branch (GE); }")
3089
3090 (define_expand "bltu"
3091   [(set (pc)
3092         (if_then_else (match_dup 1)
3093                       (label_ref (match_operand 0 "" ""))
3094                       (pc)))]
3095   ""
3096   "{ operands[1] = alpha_emit_conditional_branch (LTU); }")
3097
3098 (define_expand "bleu"
3099   [(set (pc)
3100         (if_then_else (match_dup 1)
3101                       (label_ref (match_operand 0 "" ""))
3102                       (pc)))]
3103   ""
3104   "{ operands[1] = alpha_emit_conditional_branch (LEU); }")
3105
3106 (define_expand "bgtu"
3107   [(set (pc)
3108         (if_then_else (match_dup 1)
3109                       (label_ref (match_operand 0 "" ""))
3110                       (pc)))]
3111   ""
3112   "{ operands[1] = alpha_emit_conditional_branch (GTU); }")
3113
3114 (define_expand "bgeu"
3115   [(set (pc)
3116         (if_then_else (match_dup 1)
3117                       (label_ref (match_operand 0 "" ""))
3118                       (pc)))]
3119   ""
3120   "{ operands[1] = alpha_emit_conditional_branch (GEU); }")
3121
3122 (define_expand "seq"
3123   [(set (match_operand:DI 0 "register_operand" "")
3124         (match_dup 1))]
3125   ""
3126   "
3127 {
3128   if (alpha_compare_fp_p)
3129     FAIL;
3130
3131   operands[1] = gen_rtx_EQ (DImode, alpha_compare_op0, alpha_compare_op1);
3132 }")
3133
3134 (define_expand "sne"
3135   [(set (match_operand:DI 0 "register_operand" "")
3136         (match_dup 1))
3137    (set (match_dup 0) (xor:DI (match_dup 0) (const_int 1)))]
3138   ""
3139   "
3140 {
3141   if (alpha_compare_fp_p)
3142     FAIL;
3143
3144   operands[1] = gen_rtx_EQ (DImode, alpha_compare_op0, alpha_compare_op1);
3145 }")
3146
3147 (define_expand "slt"
3148   [(set (match_operand:DI 0 "register_operand" "")
3149         (match_dup 1))]
3150   ""
3151   "
3152 {
3153   if (alpha_compare_fp_p)
3154     FAIL;
3155
3156   operands[1] = gen_rtx_LT (DImode, alpha_compare_op0, alpha_compare_op1);
3157 }")
3158
3159 (define_expand "sle"
3160   [(set (match_operand:DI 0 "register_operand" "")
3161         (match_dup 1))]
3162   ""
3163   "
3164 {
3165   if (alpha_compare_fp_p)
3166     FAIL;
3167
3168   operands[1] = gen_rtx_LE (DImode, alpha_compare_op0, alpha_compare_op1);
3169 }")
3170
3171 (define_expand "sgt"
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_LT (DImode, force_reg (DImode, alpha_compare_op1),
3181                             alpha_compare_op0);
3182 }")
3183
3184 (define_expand "sge"
3185   [(set (match_operand:DI 0 "register_operand" "")
3186         (match_dup 1))]
3187   ""
3188   "
3189 {
3190   if (alpha_compare_fp_p)
3191     FAIL;
3192
3193   operands[1] = gen_rtx_LE (DImode, force_reg (DImode, alpha_compare_op1),
3194                             alpha_compare_op0);
3195 }")
3196
3197 (define_expand "sltu"
3198   [(set (match_operand:DI 0 "register_operand" "")
3199         (match_dup 1))]
3200   ""
3201   "
3202 {
3203   if (alpha_compare_fp_p)
3204     FAIL;
3205
3206   operands[1] = gen_rtx_LTU (DImode, alpha_compare_op0, alpha_compare_op1);
3207 }")
3208
3209 (define_expand "sleu"
3210   [(set (match_operand:DI 0 "register_operand" "")
3211         (match_dup 1))]
3212   ""
3213   "
3214 {
3215   if (alpha_compare_fp_p)
3216     FAIL;
3217
3218   operands[1] = gen_rtx_LEU (DImode, alpha_compare_op0, alpha_compare_op1);
3219 }")
3220
3221 (define_expand "sgtu"
3222   [(set (match_operand:DI 0 "register_operand" "")
3223         (match_dup 1))]
3224   ""
3225   "
3226 {
3227   if (alpha_compare_fp_p)
3228     FAIL;
3229
3230   operands[1] = gen_rtx_LTU (DImode, force_reg (DImode, alpha_compare_op1),
3231                              alpha_compare_op0);
3232 }")
3233
3234 (define_expand "sgeu"
3235   [(set (match_operand:DI 0 "register_operand" "")
3236         (match_dup 1))]
3237   ""
3238   "
3239 {
3240   if (alpha_compare_fp_p)
3241     FAIL;
3242
3243   operands[1] = gen_rtx_LEU (DImode, force_reg (DImode, alpha_compare_op1),
3244                              alpha_compare_op0);
3245 }")
3246 \f
3247 ;; These are the main define_expand's used to make conditional moves.
3248
3249 (define_expand "movsicc"
3250   [(set (match_operand:SI 0 "register_operand" "")
3251         (if_then_else:SI (match_operand 1 "comparison_operator" "")
3252                          (match_operand:SI 2 "reg_or_8bit_operand" "")
3253                          (match_operand:SI 3 "reg_or_8bit_operand" "")))]
3254   ""
3255   "
3256 {
3257   if ((operands[1] = alpha_emit_conditional_move (operands[1], SImode)) == 0)
3258     FAIL;
3259 }")
3260
3261 (define_expand "movdicc"
3262   [(set (match_operand:DI 0 "register_operand" "")
3263         (if_then_else:DI (match_operand 1 "comparison_operator" "")
3264                          (match_operand:DI 2 "reg_or_8bit_operand" "")
3265                          (match_operand:DI 3 "reg_or_8bit_operand" "")))]
3266   ""
3267   "
3268 {
3269   if ((operands[1] = alpha_emit_conditional_move (operands[1], DImode)) == 0)
3270     FAIL;
3271 }")
3272
3273 (define_expand "movsfcc"
3274   [(set (match_operand:SF 0 "register_operand" "")
3275         (if_then_else:SF (match_operand 1 "comparison_operator" "")
3276                          (match_operand:SF 2 "reg_or_8bit_operand" "")
3277                          (match_operand:SF 3 "reg_or_8bit_operand" "")))]
3278   ""
3279   "
3280 {
3281   if ((operands[1] = alpha_emit_conditional_move (operands[1], SFmode)) == 0)
3282     FAIL;
3283 }")
3284
3285 (define_expand "movdfcc"
3286   [(set (match_operand:DF 0 "register_operand" "")
3287         (if_then_else:DF (match_operand 1 "comparison_operator" "")
3288                          (match_operand:DF 2 "reg_or_8bit_operand" "")
3289                          (match_operand:DF 3 "reg_or_8bit_operand" "")))]
3290   ""
3291   "
3292 {
3293   if ((operands[1] = alpha_emit_conditional_move (operands[1], DFmode)) == 0)
3294     FAIL;
3295 }")
3296 \f
3297 ;; These define_split definitions are used in cases when comparisons have
3298 ;; not be stated in the correct way and we need to reverse the second
3299 ;; comparison.  For example, x >= 7 has to be done as x < 6 with the
3300 ;; comparison that tests the result being reversed.  We have one define_split
3301 ;; for each use of a comparison.  They do not match valid insns and need
3302 ;; not generate valid insns.
3303 ;;
3304 ;; We can also handle equality comparisons (and inequality comparisons in
3305 ;; cases where the resulting add cannot overflow) by doing an add followed by
3306 ;; a comparison with zero.  This is faster since the addition takes one
3307 ;; less cycle than a compare when feeding into a conditional move.
3308 ;; For this case, we also have an SImode pattern since we can merge the add
3309 ;; and sign extend and the order doesn't matter.
3310 ;;
3311 ;; We do not do this for floating-point, since it isn't clear how the "wrong"
3312 ;; operation could have been generated.
3313
3314 (define_split
3315   [(set (match_operand:DI 0 "register_operand" "")
3316         (if_then_else:DI
3317          (match_operator 1 "comparison_operator"
3318                          [(match_operand:DI 2 "reg_or_0_operand" "")
3319                           (match_operand:DI 3 "reg_or_cint_operand" "")])
3320          (match_operand:DI 4 "reg_or_cint_operand" "")
3321          (match_operand:DI 5 "reg_or_cint_operand" "")))
3322    (clobber (match_operand:DI 6 "register_operand" ""))]
3323   "operands[3] != const0_rtx"
3324   [(set (match_dup 6) (match_dup 7))
3325    (set (match_dup 0)
3326         (if_then_else:DI (match_dup 8) (match_dup 4) (match_dup 5)))]
3327   "
3328 { enum rtx_code code = GET_CODE (operands[1]);
3329   int unsignedp = (code == GEU || code == LEU || code == GTU || code == LTU);
3330
3331   /* If we are comparing for equality with a constant and that constant
3332      appears in the arm when the register equals the constant, use the
3333      register since that is more likely to match (and to produce better code
3334      if both would).  */
3335
3336   if (code == EQ && GET_CODE (operands[3]) == CONST_INT
3337       && rtx_equal_p (operands[4], operands[3]))
3338     operands[4] = operands[2];
3339
3340   else if (code == NE && GET_CODE (operands[3]) == CONST_INT
3341            && rtx_equal_p (operands[5], operands[3]))
3342     operands[5] = operands[2];
3343
3344   if (code == NE || code == EQ
3345       || (extended_count (operands[2], DImode, unsignedp) >= 1
3346           && extended_count (operands[3], DImode, unsignedp) >= 1))
3347     {
3348       if (GET_CODE (operands[3]) == CONST_INT)
3349         operands[7] = gen_rtx_PLUS (DImode, operands[2],
3350                                     GEN_INT (- INTVAL (operands[3])));
3351       else
3352         operands[7] = gen_rtx_MINUS (DImode, operands[2], operands[3]);
3353
3354       operands[8] = gen_rtx_fmt_ee (code, VOIDmode, operands[6], const0_rtx);
3355     }
3356
3357   else if (code == EQ || code == LE || code == LT
3358            || code == LEU || code == LTU)
3359     {
3360       operands[7] = gen_rtx_fmt_ee (code, DImode, operands[2], operands[3]);
3361       operands[8] = gen_rtx_NE (VOIDmode, operands[6], const0_rtx);
3362     }
3363   else
3364     {
3365       operands[7] = gen_rtx_fmt_ee (reverse_condition (code), DImode,
3366                                     operands[2], operands[3]);
3367       operands[8] = gen_rtx_EQ (VOIDmode, operands[6], const0_rtx);
3368     }
3369 }")
3370
3371 (define_split
3372   [(set (match_operand:DI 0 "register_operand" "")
3373         (if_then_else:DI
3374          (match_operator 1 "comparison_operator"
3375                          [(match_operand:SI 2 "reg_or_0_operand" "")
3376                           (match_operand:SI 3 "reg_or_cint_operand" "")])
3377          (match_operand:DI 4 "reg_or_8bit_operand" "")
3378          (match_operand:DI 5 "reg_or_8bit_operand" "")))
3379    (clobber (match_operand:DI 6 "register_operand" ""))]
3380   "operands[3] != const0_rtx
3381    && (GET_CODE (operands[1]) == EQ || GET_CODE (operands[1]) == NE)"
3382   [(set (match_dup 6) (match_dup 7))
3383    (set (match_dup 0)
3384         (if_then_else:DI (match_dup 8) (match_dup 4) (match_dup 5)))]
3385   "
3386 { enum rtx_code code = GET_CODE (operands[1]);
3387   int unsignedp = (code == GEU || code == LEU || code == GTU || code == LTU);
3388   rtx tem;
3389
3390   if ((code != NE && code != EQ
3391        && ! (extended_count (operands[2], DImode, unsignedp) >= 1
3392              && extended_count (operands[3], DImode, unsignedp) >= 1)))
3393     FAIL;
3394  
3395   if (GET_CODE (operands[3]) == CONST_INT)
3396     tem = gen_rtx_PLUS (SImode, operands[2],
3397                         GEN_INT (- INTVAL (operands[3])));
3398   else
3399     tem = gen_rtx_MINUS (SImode, operands[2], operands[3]);
3400
3401   operands[7] = gen_rtx_SIGN_EXTEND (DImode, tem);
3402   operands[8] = gen_rtx_fmt_ee (GET_CODE (operands[1]), VOIDmode,
3403                                 operands[6], const0_rtx);
3404 }")
3405
3406 (define_split
3407   [(set (pc)
3408         (if_then_else
3409          (match_operator 1 "comparison_operator"
3410                          [(match_operand:DI 2 "reg_or_0_operand" "")
3411                           (match_operand:DI 3 "reg_or_cint_operand" "")])
3412          (label_ref (match_operand 0 "" ""))
3413          (pc)))
3414    (clobber (match_operand:DI 4 "register_operand" ""))]
3415   "operands[3] != const0_rtx"
3416   [(set (match_dup 4) (match_dup 5))
3417    (set (pc) (if_then_else (match_dup 6) (label_ref (match_dup 0)) (pc)))]
3418   "
3419 { enum rtx_code code = GET_CODE (operands[1]);
3420   int unsignedp = (code == GEU || code == LEU || code == GTU || code == LTU);
3421
3422   if (code == NE || code == EQ
3423       || (extended_count (operands[2], DImode, unsignedp) >= 1
3424           && extended_count (operands[3], DImode, unsignedp) >= 1))
3425     {
3426       if (GET_CODE (operands[3]) == CONST_INT)
3427         operands[5] = gen_rtx_PLUS (DImode, operands[2],
3428                                     GEN_INT (- INTVAL (operands[3])));
3429       else
3430         operands[5] = gen_rtx_MINUS (DImode, operands[2], operands[3]);
3431
3432       operands[6] = gen_rtx_fmt_ee (code, VOIDmode, operands[4], const0_rtx);
3433     }
3434
3435   else if (code == EQ || code == LE || code == LT
3436            || code == LEU || code == LTU)
3437     {
3438       operands[5] = gen_rtx_fmt_ee (code, DImode, operands[2], operands[3]);
3439       operands[6] = gen_rtx_NE (VOIDmode, operands[4], const0_rtx);
3440     }
3441   else
3442     {
3443       operands[5] = gen_rtx_fmt_ee (reverse_condition (code), DImode,
3444                                     operands[2], operands[3]);
3445       operands[6] = gen_rtx_EQ (VOIDmode, operands[4], const0_rtx);
3446     }
3447 }")
3448
3449 (define_split
3450   [(set (pc)
3451         (if_then_else
3452          (match_operator 1 "comparison_operator"
3453                          [(match_operand:SI 2 "reg_or_0_operand" "")
3454                           (match_operand:SI 3 "const_int_operand" "")])
3455          (label_ref (match_operand 0 "" ""))
3456          (pc)))
3457    (clobber (match_operand:DI 4 "register_operand" ""))]
3458   "operands[3] != const0_rtx
3459    && (GET_CODE (operands[1]) == EQ || GET_CODE (operands[1]) == NE)"
3460   [(set (match_dup 4) (match_dup 5))
3461    (set (pc) (if_then_else (match_dup 6) (label_ref (match_dup 0)) (pc)))]
3462   "
3463 { rtx tem;
3464
3465   if (GET_CODE (operands[3]) == CONST_INT)
3466     tem = gen_rtx_PLUS (SImode, operands[2],
3467                         GEN_INT (- INTVAL (operands[3])));
3468   else
3469     tem = gen_rtx_MINUS (SImode, operands[2], operands[3]);
3470   
3471   operands[5] = gen_rtx_SIGN_EXTEND (DImode, tem);
3472   operands[6] = gen_rtx_fmt_ee (GET_CODE (operands[1]), VOIDmode,
3473                                 operands[4], const0_rtx);
3474 }")
3475
3476 ;; We can convert such things as "a > 0xffff" to "t = a & ~ 0xffff; t != 0".
3477 ;; This eliminates one, and sometimes two, insns when the AND can be done
3478 ;; with a ZAP.
3479 (define_split
3480   [(set (match_operand:DI 0 "register_operand" "")
3481         (match_operator 1 "comparison_operator"
3482                         [(match_operand:DI 2 "register_operand" "")
3483                          (match_operand:DI 3 "const_int_operand" "")]))
3484    (clobber (match_operand:DI 4 "register_operand" ""))]
3485   "exact_log2 (INTVAL (operands[3]) + 1) >= 0
3486    && (GET_CODE (operands[1]) == GTU
3487        || GET_CODE (operands[1]) == LEU
3488        || ((GET_CODE (operands[1]) == GT || GET_CODE (operands[1]) == LE)
3489            && extended_count (operands[2], DImode, 1) > 0))"
3490   [(set (match_dup 4) (and:DI (match_dup 2) (match_dup 5)))
3491    (set (match_dup 0) (match_dup 6))]
3492   "
3493 {
3494   operands[5] = GEN_INT (~ INTVAL (operands[3]));
3495   operands[6] = gen_rtx_fmt_ee (((GET_CODE (operands[1]) == GTU
3496                                   || GET_CODE (operands[1]) == GT)
3497                                  ? NE : EQ),
3498                                 DImode, operands[4], const0_rtx);
3499 }")
3500 \f
3501 ;; Here are the CALL and unconditional branch insns.  Calls on NT and OSF
3502 ;; work differently, so we have different patterns for each.
3503
3504 (define_expand "call"
3505   [(use (match_operand:DI 0 "" ""))
3506    (use (match_operand 1 "" ""))
3507    (use (match_operand 2 "" ""))
3508    (use (match_operand 3 "" ""))]
3509   ""
3510   "
3511 { if (TARGET_WINDOWS_NT)
3512     emit_call_insn (gen_call_nt (operands[0], operands[1]));
3513   else if (TARGET_OPEN_VMS)
3514     emit_call_insn (gen_call_vms (operands[0], operands[2]));
3515   else
3516     emit_call_insn (gen_call_osf (operands[0], operands[1]));
3517
3518   DONE;
3519 }")
3520
3521 (define_expand "call_osf"
3522   [(parallel [(call (mem:DI (match_operand 0 "" ""))
3523                     (match_operand 1 "" ""))
3524               (clobber (reg:DI 27))
3525               (clobber (reg:DI 26))])]
3526   ""
3527   "
3528 { if (GET_CODE (operands[0]) != MEM)
3529     abort ();
3530
3531   operands[0] = XEXP (operands[0], 0);
3532
3533   if (GET_CODE (operands[0]) != SYMBOL_REF
3534       && ! (GET_CODE (operands[0]) == REG && REGNO (operands[0]) == 27))
3535     {
3536       rtx tem = gen_rtx_REG (DImode, 27);
3537       emit_move_insn (tem, operands[0]);
3538       operands[0] = tem;
3539     }
3540 }")
3541
3542 (define_expand "call_nt"
3543   [(parallel [(call (mem:DI (match_operand 0 "" ""))
3544                     (match_operand 1 "" ""))
3545               (clobber (reg:DI 26))])]
3546   ""
3547   "
3548 { if (GET_CODE (operands[0]) != MEM)
3549     abort ();
3550
3551   operands[0] = XEXP (operands[0], 0);
3552   if (GET_CODE (operands[0]) != SYMBOL_REF && GET_CODE (operands[0]) != REG)
3553     operands[0] = force_reg (DImode, operands[0]);
3554 }")
3555
3556 ;;
3557 ;; call openvms/alpha
3558 ;; op 0: symbol ref for called function
3559 ;; op 1: next_arg_reg (argument information value for R25)
3560 ;;
3561 (define_expand "call_vms"
3562   [(parallel [(call (mem:DI (match_operand 0 "" ""))
3563                     (match_operand 1 "" ""))
3564               (use (match_dup 2))
3565               (use (reg:DI 25))
3566               (use (reg:DI 26))
3567               (clobber (reg:DI 27))])]
3568   ""
3569   "
3570 { if (GET_CODE (operands[0]) != MEM)
3571     abort ();
3572
3573   operands[0] = XEXP (operands[0], 0);
3574
3575   /* Always load AI with argument information, then handle symbolic and
3576      indirect call differently.  Load RA and set operands[2] to PV in
3577      both cases.  */
3578
3579   emit_move_insn (gen_rtx_REG (DImode, 25), operands[1]);
3580   if (GET_CODE (operands[0]) == SYMBOL_REF)
3581     {
3582       extern char *savealloc ();
3583       char *linksym, *symbol = XSTR (operands[0], 0);
3584       rtx linkage;
3585
3586       if (*symbol == '*')
3587         symbol++;
3588       linksym = savealloc (strlen (symbol) + 6);
3589
3590       alpha_need_linkage (symbol, 0);
3591
3592       linksym[0] = '$';
3593       strcpy (linksym+1, symbol);
3594       strcat (linksym, \"..lk\");
3595       linkage = gen_rtx_SYMBOL_REF (Pmode, linksym);
3596
3597       emit_move_insn (gen_rtx_REG (Pmode, 26), gen_rtx_MEM (Pmode, linkage));
3598
3599       operands[2]
3600         = validize_mem (gen_rtx_MEM (Pmode, plus_constant (linkage, 8)));
3601     }
3602   else
3603     {
3604       emit_move_insn (gen_rtx_REG (Pmode, 26),
3605                       gen_rtx_MEM (Pmode, plus_constant (operands[0], 8)));
3606
3607       operands[2] = operands[0];
3608     }
3609
3610 }")
3611
3612 (define_expand "call_value"
3613   [(use (match_operand 0 "" ""))
3614    (use (match_operand:DI 1 "" ""))
3615    (use (match_operand 2 "" ""))
3616    (use (match_operand 3 "" ""))
3617    (use (match_operand 4 "" ""))]
3618   ""
3619   "
3620 { if (TARGET_WINDOWS_NT)
3621     emit_call_insn (gen_call_value_nt (operands[0], operands[1], operands[2]));
3622   else if (TARGET_OPEN_VMS)
3623     emit_call_insn (gen_call_value_vms (operands[0], operands[1],
3624                                         operands[3]));
3625   else
3626     emit_call_insn (gen_call_value_osf (operands[0], operands[1],
3627                                         operands[2]));
3628   DONE;
3629 }")
3630
3631 (define_expand "call_value_osf"
3632   [(parallel [(set (match_operand 0 "" "")
3633                    (call (mem:DI (match_operand 1 "" ""))
3634                          (match_operand 2 "" "")))
3635               (clobber (reg:DI 27))
3636               (clobber (reg:DI 26))])]
3637   ""
3638   "
3639 { if (GET_CODE (operands[1]) != MEM)
3640     abort ();
3641
3642   operands[1] = XEXP (operands[1], 0);
3643
3644   if (GET_CODE (operands[1]) != SYMBOL_REF
3645       && ! (GET_CODE (operands[1]) == REG && REGNO (operands[1]) == 27))
3646     {
3647       rtx tem = gen_rtx_REG (DImode, 27);
3648       emit_move_insn (tem, operands[1]);
3649       operands[1] = tem;
3650     }
3651 }")
3652
3653 (define_expand "call_value_nt"
3654   [(parallel [(set (match_operand 0 "" "")
3655                    (call (mem:DI (match_operand 1 "" ""))
3656                          (match_operand 2 "" "")))
3657               (clobber (reg:DI 26))])]
3658   ""
3659   "
3660 { if (GET_CODE (operands[1]) != MEM)
3661     abort ();
3662
3663   operands[1] = XEXP (operands[1], 0);
3664   if (GET_CODE (operands[0]) != SYMBOL_REF && GET_CODE (operands[0]) != REG)
3665     operands[1] = force_reg (DImode, operands[1]);
3666 }")
3667
3668 (define_expand "call_value_vms"
3669   [(parallel [(set (match_operand 0 "" "")
3670                    (call (mem:DI (match_operand:DI 1 "" ""))
3671                          (match_operand 2 "" "")))
3672               (use (match_dup 3))
3673               (use (reg:DI 25))
3674               (use (reg:DI 26))
3675               (clobber (reg:DI 27))])]
3676   ""
3677   "
3678 { if (GET_CODE (operands[1]) != MEM)
3679     abort ();
3680
3681   operands[1] = XEXP (operands[1], 0);
3682
3683   /* Always load AI with argument information, then handle symbolic and
3684      indirect call differently.  Load RA and set operands[3] to PV in
3685      both cases.  */
3686
3687   emit_move_insn (gen_rtx_REG (DImode, 25), operands[2]);
3688   if (GET_CODE (operands[1]) == SYMBOL_REF)
3689     {
3690       extern char *savealloc ();
3691       char *linksym, *symbol = XSTR (operands[1], 0);
3692       rtx linkage;
3693
3694       if (*symbol == '*')
3695         symbol++;
3696       linksym = savealloc (strlen (symbol) + 6);
3697
3698       alpha_need_linkage (symbol, 0);
3699       linksym[0] = '$';
3700       strcpy (linksym+1, symbol);
3701       strcat (linksym, \"..lk\");
3702       linkage = gen_rtx_SYMBOL_REF (Pmode, linksym);
3703
3704       emit_move_insn (gen_rtx_REG (Pmode, 26), gen_rtx_MEM (Pmode, linkage));
3705
3706       operands[3]
3707         = validize_mem (gen_rtx_MEM (Pmode, plus_constant (linkage, 8)));
3708     }
3709   else
3710     {
3711       emit_move_insn (gen_rtx_REG (Pmode, 26),
3712                       gen_rtx_MEM (Pmode, plus_constant (operands[1], 8)));
3713
3714       operands[3] = operands[1];
3715     }
3716 }")
3717
3718 (define_insn ""
3719   [(call (mem:DI (match_operand:DI 0 "call_operand" "r,R,i"))
3720          (match_operand 1 "" ""))
3721    (clobber (reg:DI 27))
3722    (clobber (reg:DI 26))]
3723   "! TARGET_WINDOWS_NT && ! TARGET_OPEN_VMS"
3724   "@
3725    jsr $26,($27),0\;ldgp $29,0($26)
3726    bsr $26,$%0..ng
3727    jsr $26,%0\;ldgp $29,0($26)"
3728   [(set_attr "type" "jsr")
3729    (set_attr "length" "12,*,16")])
3730       
3731 (define_insn ""
3732   [(call (mem:DI (match_operand:DI 0 "call_operand" "r,R,i"))
3733          (match_operand 1 "" ""))
3734    (clobber (reg:DI 26))]
3735   "TARGET_WINDOWS_NT"
3736   "@
3737    jsr $26,(%0)
3738    bsr $26,%0
3739    jsr $26,%0"
3740   [(set_attr "type" "jsr")
3741    (set_attr "length" "*,*,12")])
3742       
3743 (define_insn ""
3744   [(call (mem:DI (match_operand:DI 0 "call_operand" "r,i"))
3745          (match_operand 1 "" ""))
3746    (use (match_operand:DI 2 "general_operand" "r,m"))
3747    (use (reg:DI 25))
3748    (use (reg:DI 26))
3749    (clobber (reg:DI 27))]
3750   "TARGET_OPEN_VMS"
3751   "@
3752    mov %2,$27\;jsr $26,0\;ldq $27,0($29)
3753    ldq $27,%2\;jsr $26,%0\;ldq $27,0($29)"
3754   [(set_attr "type" "jsr")
3755    (set_attr "length" "12,16")])
3756
3757 (define_insn ""
3758   [(set (match_operand 0 "register_operand" "=rf,rf,rf")
3759         (call (mem:DI (match_operand:DI 1 "call_operand" "r,R,i"))
3760               (match_operand 2 "" "")))
3761    (clobber (reg:DI 27))
3762    (clobber (reg:DI 26))]
3763   "! TARGET_WINDOWS_NT && ! TARGET_OPEN_VMS"
3764   "@
3765    jsr $26,($27),0\;ldgp $29,0($26)
3766    bsr $26,$%1..ng
3767    jsr $26,%1\;ldgp $29,0($26)"
3768   [(set_attr "type" "jsr")
3769    (set_attr "length" "12,*,16")])
3770
3771 (define_insn ""
3772   [(set (match_operand 0 "register_operand" "=rf,rf,rf")
3773         (call (mem:DI (match_operand:DI 1 "call_operand" "r,R,i"))
3774               (match_operand 2 "" "")))
3775    (clobber (reg:DI 26))]
3776   "TARGET_WINDOWS_NT"
3777   "@
3778    jsr $26,(%1)
3779    bsr $26,%1
3780    jsr $26,%1"
3781   [(set_attr "type" "jsr")
3782    (set_attr "length" "*,*,12")])
3783
3784 (define_insn ""
3785   [(set (match_operand 0 "register_operand" "")
3786         (call (mem:DI (match_operand:DI 1 "call_operand" "r,i"))
3787               (match_operand 2 "" "")))
3788    (use (match_operand:DI 3 "general_operand" "r,m"))
3789    (use (reg:DI 25))
3790    (use (reg:DI 26))
3791    (clobber (reg:DI 27))]
3792   "TARGET_OPEN_VMS"
3793   "@
3794    mov %3,$27\;jsr $26,0\;ldq $27,0($29)
3795    ldq $27,%3\;jsr $26,%1\;ldq $27,0($29)"
3796   [(set_attr "type" "jsr")
3797    (set_attr "length" "12,16")])
3798
3799 ;; Call subroutine returning any type.
3800
3801 (define_expand "untyped_call"
3802   [(parallel [(call (match_operand 0 "" "")
3803                     (const_int 0))
3804               (match_operand 1 "" "")
3805               (match_operand 2 "" "")])]
3806   ""
3807   "
3808 {
3809   int i;
3810
3811   emit_call_insn (gen_call (operands[0], const0_rtx, NULL, const0_rtx));
3812
3813   for (i = 0; i < XVECLEN (operands[2], 0); i++)
3814     {
3815       rtx set = XVECEXP (operands[2], 0, i);
3816       emit_move_insn (SET_DEST (set), SET_SRC (set));
3817     }
3818
3819   /* The optimizer does not know that the call sets the function value
3820      registers we stored in the result block.  We avoid problems by
3821      claiming that all hard registers are used and clobbered at this
3822      point.  */
3823   emit_insn (gen_blockage ());
3824
3825   DONE;
3826 }")
3827
3828 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
3829 ;; all of memory.  This blocks insns from being moved across this point.
3830
3831 (define_insn "blockage"
3832   [(unspec_volatile [(const_int 0)] 1)]
3833   ""
3834   ""
3835   [(set_attr "length" "0")])
3836
3837 (define_insn "jump"
3838   [(set (pc)
3839         (label_ref (match_operand 0 "" "")))]
3840   ""
3841   "br $31,%l0"
3842   [(set_attr "type" "ibr")])
3843
3844 (define_insn "return"
3845   [(return)]
3846   "direct_return ()"
3847   "ret $31,($26),1"
3848   [(set_attr "type" "ibr")])
3849
3850 ;; Use a different pattern for functions which have non-trivial
3851 ;; epilogues so as not to confuse jump and reorg.
3852 (define_insn "return_internal"
3853   [(use (reg:DI 26))
3854    (return)]
3855   ""
3856   "ret $31,($26),1"
3857   [(set_attr "type" "ibr")])
3858
3859 (define_insn "indirect_jump"
3860   [(set (pc) (match_operand:DI 0 "register_operand" "r"))]
3861   ""
3862   "jmp $31,(%0),0"
3863   [(set_attr "type" "ibr")])
3864
3865 (define_expand "tablejump"
3866   [(use (match_operand:SI 0 "register_operand" ""))
3867    (use (match_operand:SI 1 "" ""))]
3868   ""
3869   "
3870 {
3871   if (TARGET_WINDOWS_NT)
3872     emit_jump_insn (gen_tablejump_nt (operands[0], operands[1]));
3873   else if (TARGET_OPEN_VMS)
3874     emit_jump_insn (gen_tablejump_vms (operands[0], operands[1]));
3875   else
3876     emit_jump_insn (gen_tablejump_osf (operands[0], operands[1]));
3877
3878   DONE;
3879 }")
3880
3881 (define_expand "tablejump_osf"
3882   [(set (match_dup 3)
3883         (sign_extend:DI (match_operand:SI 0 "register_operand" "")))
3884    (parallel [(set (pc)
3885                    (plus:DI (match_dup 3)
3886                             (label_ref:DI (match_operand 1 "" ""))))
3887               (clobber (match_scratch:DI 2 "=r"))])]
3888   ""
3889   "
3890 { operands[3] = gen_reg_rtx (DImode); }")
3891
3892 (define_expand "tablejump_nt"
3893   [(set (match_dup 3)
3894         (sign_extend:DI (match_operand:SI 0 "register_operand" "")))
3895    (parallel [(set (pc)
3896                    (match_dup 3))
3897               (use (label_ref (match_operand 1 "" "")))])]
3898   ""
3899   "
3900 { operands[3] = gen_reg_rtx (DImode); }")
3901
3902 ;;
3903 ;; tablejump, openVMS way
3904 ;; op 0: offset
3905 ;; op 1: label preceding jump-table
3906 ;;
3907 (define_expand "tablejump_vms"
3908   [(set (match_dup 2)
3909       (match_operand:DI 0 "register_operand" ""))
3910         (set (pc)
3911         (plus:DI (match_dup 2)
3912                 (label_ref:DI (match_operand 1 "" ""))))]
3913   ""
3914   "
3915 { operands[2] = gen_reg_rtx (DImode); }")
3916
3917 (define_insn ""
3918   [(set (pc)
3919         (plus:DI (match_operand:DI 0 "register_operand" "r")
3920                  (label_ref:DI (match_operand 1 "" ""))))
3921    (clobber (match_scratch:DI 2 "=r"))]
3922   "! TARGET_WINDOWS_NT && ! TARGET_OPEN_VMS && next_active_insn (insn) != 0
3923    && GET_CODE (PATTERN (next_active_insn (insn))) == ADDR_DIFF_VEC
3924    && PREV_INSN (next_active_insn (insn)) == operands[1]"
3925   "*
3926 { rtx best_label = 0;
3927   rtx jump_table_insn = next_active_insn (operands[1]);
3928
3929   if (GET_CODE (jump_table_insn) == JUMP_INSN
3930       && GET_CODE (PATTERN (jump_table_insn)) == ADDR_DIFF_VEC)
3931     {
3932       rtx jump_table = PATTERN (jump_table_insn);
3933       int n_labels = XVECLEN (jump_table, 1);
3934       int best_count = -1;
3935       int i, j;
3936
3937       for (i = 0; i < n_labels; i++)
3938         {
3939           int count = 1;
3940
3941           for (j = i + 1; j < n_labels; j++)
3942             if (XEXP (XVECEXP (jump_table, 1, i), 0)
3943                 == XEXP (XVECEXP (jump_table, 1, j), 0))
3944               count++;
3945
3946           if (count > best_count)
3947             best_count = count, best_label = XVECEXP (jump_table, 1, i);
3948         }
3949     }
3950
3951   if (best_label)
3952     {
3953       operands[3] = best_label;
3954       return \"addq %0,$29,%2\;jmp $31,(%2),%3\";
3955     }
3956   else
3957     return \"addq %0,$29,%2\;jmp $31,(%2),0\";
3958 }"
3959   [(set_attr "type" "ibr")
3960    (set_attr "length" "8")])
3961
3962 (define_insn ""
3963   [(set (pc)
3964         (match_operand:DI 0 "register_operand" "r"))
3965    (use (label_ref (match_operand 1 "" "")))]
3966   "TARGET_WINDOWS_NT && next_active_insn (insn) != 0
3967    && GET_CODE (PATTERN (next_active_insn (insn))) == ADDR_DIFF_VEC
3968    && PREV_INSN (next_active_insn (insn)) == operands[1]"
3969   "*
3970 { rtx best_label = 0;
3971   rtx jump_table_insn = next_active_insn (operands[1]);
3972
3973   if (GET_CODE (jump_table_insn) == JUMP_INSN
3974       && GET_CODE (PATTERN (jump_table_insn)) == ADDR_DIFF_VEC)
3975     {
3976       rtx jump_table = PATTERN (jump_table_insn);
3977       int n_labels = XVECLEN (jump_table, 1);
3978       int best_count = -1;
3979       int i, j;
3980
3981       for (i = 0; i < n_labels; i++)
3982         {
3983           int count = 1;
3984
3985           for (j = i + 1; j < n_labels; j++)
3986             if (XEXP (XVECEXP (jump_table, 1, i), 0)
3987                 == XEXP (XVECEXP (jump_table, 1, j), 0))
3988               count++;
3989
3990           if (count > best_count)
3991             best_count = count, best_label = XVECEXP (jump_table, 1, i);
3992         }
3993     }
3994
3995   if (best_label)
3996     {
3997       operands[2] = best_label;
3998       return \"jmp $31,(%0),%2\";
3999     }
4000   else
4001     return \"jmp $31,(%0),0\";
4002 }"
4003   [(set_attr "type" "ibr")])
4004
4005 ;;
4006 ;; op 0 is table offset
4007 ;; op 1 is table label
4008 ;;
4009
4010 (define_insn ""
4011   [(set (pc)
4012         (plus:DI (match_operand 0 "register_operand" "r")
4013                 (label_ref (match_operand 1 "" ""))))]
4014   "TARGET_OPEN_VMS"
4015   "jmp $31,(%0),0"
4016   [(set_attr "type" "ibr")])
4017
4018 ;; Cache flush.  Used by INITIALIZE_TRAMPOLINE.  0x86 is PAL_imb, but we don't
4019 ;; want to have to include pal.h in our .s file.
4020 ;;
4021 ;; Technically the type for call_pal is jsr, but we use that for determining
4022 ;; if we need a GP.  Use ibr instead since it has the same EV5 scheduling
4023 ;; characteristics.
4024 (define_insn "imb"
4025   [(unspec_volatile [(const_int 0)] 0)]
4026   ""
4027   "call_pal 0x86"
4028   [(set_attr "type" "ibr")])
4029 \f
4030 ;; Finally, we have the basic data motion insns.  The byte and word insns
4031 ;; are done via define_expand.  Start with the floating-point insns, since
4032 ;; they are simpler.
4033
4034 (define_insn ""
4035   [(set (match_operand:SF 0 "nonimmediate_operand" "=r,r,m,f,f,m")
4036         (match_operand:SF 1 "input_operand" "rG,m,r,fG,m,fG"))]
4037   "! TARGET_CIX
4038    && (register_operand (operands[0], SFmode)
4039        || reg_or_fp0_operand (operands[1], SFmode))"
4040   "@
4041    mov %r1,%0
4042    ldl %0,%1
4043    stl %r1,%0
4044    fmov %R1,%0
4045    ld%, %0,%1
4046    st%, %R1,%0"
4047   [(set_attr "type" "ilog,ild,ist,fcpys,fld,fst")])
4048
4049 (define_insn ""
4050   [(set (match_operand:SF 0 "nonimmediate_operand" "=r,r,m,f,f,m,f,*r")
4051         (match_operand:SF 1 "input_operand" "rG,m,r,fG,m,fG,r,*f"))]
4052   "TARGET_CIX
4053    && (register_operand (operands[0], SFmode)
4054        || reg_or_fp0_operand (operands[1], SFmode))"
4055   "@
4056    mov %r1,%0
4057    ldl %0,%1
4058    stl %r1,%0
4059    fmov %R1,%0
4060    ld%, %0,%1
4061    st%, %R1,%0
4062    itofs %1,%0
4063    ftois %1,%0"
4064   [(set_attr "type" "ilog,ild,ist,fcpys,fld,fst,itof,ftoi")])
4065
4066 (define_insn ""
4067   [(set (match_operand:DF 0 "nonimmediate_operand" "=r,r,m,f,f,m")
4068         (match_operand:DF 1 "input_operand" "rG,m,r,fG,m,fG"))]
4069   "! TARGET_CIX
4070    && (register_operand (operands[0], DFmode)
4071        || reg_or_fp0_operand (operands[1], DFmode))"
4072   "@
4073    mov %r1,%0
4074    ldq %0,%1
4075    stq %r1,%0
4076    fmov %R1,%0
4077    ld%- %0,%1
4078    st%- %R1,%0"
4079   [(set_attr "type" "ilog,ild,ist,fcpys,fld,fst")])
4080
4081 (define_insn ""
4082   [(set (match_operand:DF 0 "nonimmediate_operand" "=r,r,m,f,f,m,f,*r")
4083         (match_operand:DF 1 "input_operand" "rG,m,r,fG,m,fG,r,*f"))]
4084   "TARGET_CIX
4085    && (register_operand (operands[0], DFmode)
4086        || reg_or_fp0_operand (operands[1], DFmode))"
4087   "@
4088    mov %r1,%0
4089    ldq %0,%1
4090    stq %r1,%0
4091    fmov %R1,%0
4092    ld%- %0,%1
4093    st%- %R1,%0
4094    itoft %1,%0
4095    ftoit %1,%0"
4096   [(set_attr "type" "ilog,ild,ist,fcpys,fld,fst,itof,ftoi")])
4097
4098 (define_expand "movsf"
4099   [(set (match_operand:SF 0 "nonimmediate_operand" "")
4100         (match_operand:SF 1 "general_operand" ""))]
4101   ""
4102   "
4103 {
4104   if (GET_CODE (operands[0]) == MEM
4105       && ! reg_or_fp0_operand (operands[1], SFmode))
4106     operands[1] = force_reg (SFmode, operands[1]);
4107 }")
4108
4109 (define_expand "movdf"
4110   [(set (match_operand:DF 0 "nonimmediate_operand" "")
4111         (match_operand:DF 1 "general_operand" ""))]
4112   ""
4113   "
4114 {
4115   if (GET_CODE (operands[0]) == MEM
4116       && ! reg_or_fp0_operand (operands[1], DFmode))
4117     operands[1] = force_reg (DFmode, operands[1]);
4118 }")
4119
4120 (define_insn ""
4121   [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,r,r,m,f,f,m")
4122         (match_operand:SI 1 "input_operand" "rJ,K,L,m,rJ,fJ,m,f"))]
4123   "! TARGET_WINDOWS_NT && ! TARGET_OPEN_VMS && ! TARGET_CIX
4124    && (register_operand (operands[0], SImode)
4125        || reg_or_0_operand (operands[1], SImode))"
4126   "@
4127    mov %r1,%0
4128    lda %0,%1
4129    ldah %0,%h1
4130    ldl %0,%1
4131    stl %r1,%0
4132    fmov %R1,%0
4133    ld%, %0,%1
4134    st%, %R1,%0"
4135   [(set_attr "type" "ilog,iadd,iadd,ild,ist,fcpys,fld,fst")])
4136
4137 (define_insn ""
4138   [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,r,r,m,f,f,m,r,*f")
4139         (match_operand:SI 1 "input_operand" "rJ,K,L,m,rJ,fJ,m,f,f,*r"))]
4140   "! TARGET_WINDOWS_NT && ! TARGET_OPEN_VMS && TARGET_CIX
4141    && (register_operand (operands[0], SImode)
4142        || reg_or_0_operand (operands[1], SImode))"
4143   "@
4144    mov %r1,%0
4145    lda %0,%1
4146    ldah %0,%h1
4147    ldl %0,%1
4148    stl %r1,%0
4149    fmov %R1,%0
4150    ld%, %0,%1
4151    st%, %R1,%0
4152    ftois %1,%0
4153    itofs %1,%0"
4154   [(set_attr "type" "ilog,iadd,iadd,ild,ist,fcpys,fld,fst,ftoi,itof")])
4155
4156 (define_insn ""
4157   [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,r,r,r,m,f,f,m")
4158         (match_operand:SI 1 "input_operand" "rJ,K,L,s,m,rJ,fJ,m,f"))]
4159   "(TARGET_WINDOWS_NT || TARGET_OPEN_VMS)
4160     && (register_operand (operands[0], SImode)
4161         || reg_or_0_operand (operands[1], SImode))"
4162   "@
4163    mov %1,%0
4164    lda %0,%1
4165    ldah %0,%h1
4166    lda %0,%1
4167    ldl %0,%1
4168    stl %r1,%0
4169    fmov %R1,%0
4170    ld%, %0,%1
4171    st%, %R1,%0"
4172   [(set_attr "type" "ilog,iadd,iadd,ldsym,ild,ist,fcpys,fld,fst")])
4173
4174 (define_insn ""
4175   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,f")
4176         (match_operand:HI 1 "input_operand" "rJ,n,fJ"))]
4177   "! TARGET_BWX
4178    && (register_operand (operands[0], HImode)
4179        || register_operand (operands[1], HImode))"
4180   "@
4181    mov %r1,%0
4182    lda %0,%L1
4183    fmov %R1,%0"
4184   [(set_attr "type" "ilog,iadd,fcpys")])
4185
4186 (define_insn ""
4187   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m,f")
4188         (match_operand:HI 1 "input_operand" "rJ,n,m,rJ,fJ"))]
4189   "TARGET_BWX
4190    && (register_operand (operands[0], HImode)
4191        || reg_or_0_operand (operands[1], HImode))"
4192   "@
4193    mov %r1,%0
4194    lda %0,%L1
4195    ldwu %0,%1
4196    stw %r1,%0
4197    fmov %R1,%0"
4198   [(set_attr "type" "ilog,iadd,ild,ist,fcpys")])
4199
4200 (define_insn ""
4201   [(set (match_operand:QI 0 "nonimmediate_operand" "=r,r,f")
4202         (match_operand:QI 1 "input_operand" "rJ,n,fJ"))]
4203   "! TARGET_BWX
4204    && (register_operand (operands[0], QImode)
4205        || register_operand (operands[1], QImode))"
4206   "@
4207    mov %r1,%0
4208    lda %0,%L1
4209    fmov %R1,%0"
4210   [(set_attr "type" "ilog,iadd,fcpys")])
4211
4212 (define_insn ""
4213   [(set (match_operand:QI 0 "nonimmediate_operand" "=r,r,r,m,f")
4214         (match_operand:QI 1 "input_operand" "rJ,n,m,rJ,fJ"))]
4215   "TARGET_BWX
4216    && (register_operand (operands[0], QImode)
4217        || reg_or_0_operand (operands[1], QImode))"
4218   "@
4219    mov %r1,%0
4220    lda %0,%L1
4221    ldbu %0,%1
4222    stb %r1,%0
4223    fmov %R1,%0"
4224   [(set_attr "type" "ilog,iadd,ild,ist,fcpys")])
4225
4226 ;; We do two major things here: handle mem->mem and construct long
4227 ;; constants.
4228
4229 (define_expand "movsi"
4230   [(set (match_operand:SI 0 "general_operand" "")
4231         (match_operand:SI 1 "general_operand" ""))]
4232   ""
4233   "
4234 {
4235   if (GET_CODE (operands[0]) == MEM
4236       && ! reg_or_0_operand (operands[1], SImode))
4237     operands[1] = force_reg (SImode, operands[1]);
4238
4239   if (! CONSTANT_P (operands[1]) || input_operand (operands[1], SImode))
4240     ;
4241   else if (GET_CODE (operands[1]) == CONST_INT)
4242     {
4243       operands[1]
4244         = alpha_emit_set_const (operands[0], SImode, INTVAL (operands[1]), 3);
4245       if (rtx_equal_p (operands[0], operands[1]))
4246         DONE;
4247     }
4248 }")
4249
4250 ;; Split a load of a large constant into the appropriate two-insn
4251 ;; sequence.
4252
4253 (define_split
4254   [(set (match_operand:SI 0 "register_operand" "")
4255         (match_operand:SI 1 "const_int_operand" ""))]
4256   "! add_operand (operands[1], SImode)"
4257   [(set (match_dup 0) (match_dup 2))
4258    (set (match_dup 0) (plus:SI (match_dup 0) (match_dup 3)))]
4259   "
4260 { rtx tem
4261     = alpha_emit_set_const (operands[0], SImode, INTVAL (operands[1]), 2);
4262
4263   if (tem == operands[0])
4264     DONE;
4265   else
4266     FAIL;
4267 }")
4268
4269 (define_insn ""
4270   [(set (match_operand:DI 0 "general_operand" "=r,r,r,r,r,m,f,f,Q")
4271         (match_operand:DI 1 "input_operand" "rJ,K,L,s,m,rJ,fJ,Q,f"))]
4272   "! TARGET_CIX
4273    && (register_operand (operands[0], DImode)
4274        || reg_or_0_operand (operands[1], DImode))"
4275   "@
4276    mov %r1,%0
4277    lda %0,%1
4278    ldah %0,%h1
4279    lda %0,%1
4280    ldq%A1 %0,%1
4281    stq%A0 %r1,%0
4282    fmov %R1,%0
4283    ldt %0,%1
4284    stt %R1,%0"
4285   [(set_attr "type" "ilog,iadd,iadd,ldsym,ild,ist,fcpys,fld,fst")])
4286
4287 (define_insn ""
4288   [(set (match_operand:DI 0 "general_operand" "=r,r,r,r,r,m,f,f,Q,r,*f")
4289         (match_operand:DI 1 "input_operand" "rJ,K,L,s,m,rJ,fJ,Q,f,f,*r"))]
4290   "TARGET_CIX
4291    && (register_operand (operands[0], DImode)
4292        || reg_or_0_operand (operands[1], DImode))"
4293   "@
4294    mov %r1,%0
4295    lda %0,%1
4296    ldah %0,%h1
4297    lda %0,%1
4298    ldq%A1 %0,%1
4299    stq%A0 %r1,%0
4300    fmov %R1,%0
4301    ldt %0,%1
4302    stt %R1,%0
4303    ftoit %1,%0
4304    itoft %1,%0"
4305   [(set_attr "type" "ilog,iadd,iadd,ldsym,ild,ist,fcpys,fld,fst,ftoi,itof")])
4306
4307 ;; We do three major things here: handle mem->mem, put 64-bit constants in
4308 ;; memory, and construct long 32-bit constants.
4309
4310 (define_expand "movdi"
4311   [(set (match_operand:DI 0 "general_operand" "")
4312         (match_operand:DI 1 "general_operand" ""))]
4313   ""
4314   "
4315 {
4316   rtx tem;
4317
4318   if (GET_CODE (operands[0]) == MEM
4319       && ! reg_or_0_operand (operands[1], DImode))
4320     operands[1] = force_reg (DImode, operands[1]);
4321
4322   if (! CONSTANT_P (operands[1]) || input_operand (operands[1], DImode))
4323     ;
4324   else if (GET_CODE (operands[1]) == CONST_INT
4325            && (tem = alpha_emit_set_const (operands[0], DImode,
4326                                            INTVAL (operands[1]), 3)) != 0)
4327     {
4328       if (rtx_equal_p (tem, operands[0]))
4329         DONE;
4330       else
4331         operands[1] = tem;
4332     }
4333   else if (CONSTANT_P (operands[1]))
4334     {
4335       if (TARGET_BUILD_CONSTANTS)
4336         {
4337           HOST_WIDE_INT i0, i1;
4338
4339           if (GET_CODE (operands[1]) == CONST_INT)
4340             {
4341               i0 = INTVAL (operands[1]);
4342               i1 = -(i0 < 0);
4343             }
4344           else if (GET_CODE (operands[1]) == CONST_DOUBLE)
4345             {
4346 #if HOST_BITS_PER_WIDE_INT >= 64
4347               i0 = CONST_DOUBLE_LOW (operands[1]);
4348               i1 = -(i0 < 0);
4349 #else
4350               i0 = CONST_DOUBLE_LOW (operands[1]);
4351               i1 = CONST_DOUBLE_HIGH (operands[1]);
4352 #endif
4353             }
4354           else
4355             abort();
4356           
4357           tem = alpha_emit_set_long_const (operands[0], i0, i1);
4358           if (rtx_equal_p (tem, operands[0]))
4359             DONE;
4360           else
4361             operands[1] = tem;
4362         }
4363       else
4364         {
4365           operands[1] = force_const_mem (DImode, operands[1]);
4366           if (reload_in_progress)
4367             {
4368               emit_move_insn (operands[0], XEXP (operands[1], 0));
4369               operands[1] = copy_rtx (operands[1]);
4370               XEXP (operands[1], 0) = operands[0];
4371             }
4372           else
4373             operands[1] = validize_mem (operands[1]);
4374         }
4375     }
4376   else
4377     abort ();
4378 }")
4379
4380 ;; Split a load of a large constant into the appropriate two-insn
4381 ;; sequence.
4382
4383 (define_split
4384   [(set (match_operand:DI 0 "register_operand" "")
4385         (match_operand:DI 1 "const_int_operand" ""))]
4386   "! add_operand (operands[1], DImode)"
4387   [(set (match_dup 0) (match_dup 2))
4388    (set (match_dup 0) (plus:DI (match_dup 0) (match_dup 3)))]
4389   "
4390 { rtx tem
4391     = alpha_emit_set_const (operands[0], DImode, INTVAL (operands[1]), 2);
4392
4393   if (tem == operands[0])
4394     DONE;
4395   else
4396     FAIL;
4397 }")
4398
4399 ;; These are the partial-word cases.
4400 ;;
4401 ;; First we have the code to load an aligned word.  Operand 0 is the register
4402 ;; in which to place the result.  It's mode is QImode or HImode.  Operand 1
4403 ;; is an SImode MEM at the low-order byte of the proper word.  Operand 2 is the
4404 ;; number of bits within the word that the value is.  Operand 3 is an SImode
4405 ;; scratch register.  If operand 0 is a hard register, operand 3 may be the
4406 ;; same register.  It is allowed to conflict with operand 1 as well.
4407
4408 (define_expand "aligned_loadqi"
4409   [(set (match_operand:SI 3 "register_operand" "")
4410         (match_operand:SI 1 "memory_operand" ""))
4411    (set (subreg:DI (match_operand:QI 0 "register_operand" "") 0)
4412         (zero_extract:DI (subreg:DI (match_dup 3) 0)
4413                          (const_int 8)
4414                          (match_operand:DI 2 "const_int_operand" "")))]
4415          
4416   ""
4417   "")
4418   
4419 (define_expand "aligned_loadhi"
4420   [(set (match_operand:SI 3 "register_operand" "")
4421         (match_operand:SI 1 "memory_operand" ""))
4422    (set (subreg:DI (match_operand:HI 0 "register_operand" "") 0)
4423         (zero_extract:DI (subreg:DI (match_dup 3) 0)
4424                          (const_int 16)
4425                          (match_operand:DI 2 "const_int_operand" "")))]
4426          
4427   ""
4428   "")
4429   
4430 ;; Similar for unaligned loads, where we use the sequence from the
4431 ;; Alpha Architecture manual.
4432 ;;
4433 ;; Operand 1 is the address.  Operands 2 and 3 are temporaries, where
4434 ;; operand 3 can overlap the input and output registers.
4435
4436 (define_expand "unaligned_loadqi"
4437   [(set (match_operand:DI 2 "register_operand" "")
4438         (mem:DI (and:DI (match_operand:DI 1 "address_operand" "")
4439                         (const_int -8))))
4440    (set (match_operand:DI 3 "register_operand" "")
4441         (match_dup 1))
4442    (set (subreg:DI (match_operand:QI 0 "register_operand" "") 0)
4443         (zero_extract:DI (match_dup 2)
4444                          (const_int 8)
4445                          (ashift:DI (match_dup 3) (const_int 3))))]
4446   ""
4447   "")
4448
4449 (define_expand "unaligned_loadhi"
4450   [(set (match_operand:DI 2 "register_operand" "")
4451         (mem:DI (and:DI (match_operand:DI 1 "address_operand" "")
4452                         (const_int -8))))
4453    (set (match_operand:DI 3 "register_operand" "")
4454         (match_dup 1))
4455    (set (subreg:DI (match_operand:QI 0 "register_operand" "") 0)
4456         (zero_extract:DI (match_dup 2)
4457                          (const_int 16)
4458                          (ashift:DI (match_dup 3) (const_int 3))))]
4459   ""
4460   "")
4461
4462 ;; Storing an aligned byte or word requires two temporaries.  Operand 0 is the
4463 ;; aligned SImode MEM.  Operand 1 is the register containing the 
4464 ;; byte or word to store.  Operand 2 is the number of bits within the word that
4465 ;; the value should be placed.  Operands 3 and 4 are SImode temporaries.
4466
4467 (define_expand "aligned_store"
4468   [(set (match_operand:SI 3 "register_operand" "")
4469         (match_operand:SI 0 "memory_operand" ""))
4470    (set (subreg:DI (match_dup 3) 0)
4471         (and:DI (subreg:DI (match_dup 3) 0) (match_dup 5)))
4472    (set (subreg:DI (match_operand:SI 4 "register_operand" "") 0)
4473         (ashift:DI (zero_extend:DI (match_operand 1 "register_operand" ""))
4474                    (match_operand:DI 2 "const_int_operand" "")))
4475    (set (subreg:DI (match_dup 4) 0)
4476         (ior:DI (subreg:DI (match_dup 4) 0) (subreg:DI (match_dup 3) 0)))
4477    (set (match_dup 0) (match_dup 4))]
4478   ""
4479   "
4480 { operands[5] = GEN_INT (~ (GET_MODE_MASK (GET_MODE (operands[1]))
4481                             << INTVAL (operands[2])));
4482 }")
4483
4484 ;; For the unaligned byte and halfword cases, we use code similar to that
4485 ;; in the ;; Architecture book, but reordered to lower the number of registers
4486 ;; required.  Operand 0 is the address.  Operand 1 is the data to store.
4487 ;; Operands 2, 3, and 4 are DImode temporaries, where operands 2 and 4 may
4488 ;; be the same temporary, if desired.  If the address is in a register,
4489 ;; operand 2 can be that register.
4490
4491 (define_expand "unaligned_storeqi"
4492   [(set (match_operand:DI 3 "register_operand" "")
4493         (mem:DI (and:DI (match_operand:DI 0 "address_operand" "")
4494                         (const_int -8))))
4495    (set (match_operand:DI 2 "register_operand" "")
4496         (match_dup 0))
4497    (set (match_dup 3)
4498         (and:DI (not:DI (ashift:DI (const_int 255)
4499                                    (ashift:DI (match_dup 2) (const_int 3))))
4500                 (match_dup 3)))
4501    (set (match_operand:DI 4 "register_operand" "")
4502         (ashift:DI (zero_extend:DI (match_operand:QI 1 "register_operand" ""))
4503                    (ashift:DI (match_dup 2) (const_int 3))))
4504    (set (match_dup 4) (ior:DI (match_dup 4) (match_dup 3)))
4505    (set (mem:DI (and:DI (match_dup 0) (const_int -8)))
4506         (match_dup 4))]
4507   ""
4508   "")
4509
4510 (define_expand "unaligned_storehi"
4511   [(set (match_operand:DI 3 "register_operand" "")
4512         (mem:DI (and:DI (match_operand:DI 0 "address_operand" "")
4513                         (const_int -8))))
4514    (set (match_operand:DI 2 "register_operand" "")
4515         (match_dup 0))
4516    (set (match_dup 3)
4517         (and:DI (not:DI (ashift:DI (const_int 65535)
4518                                    (ashift:DI (match_dup 2) (const_int 3))))
4519                 (match_dup 3)))
4520    (set (match_operand:DI 4 "register_operand" "")
4521         (ashift:DI (zero_extend:DI (match_operand:HI 1 "register_operand" ""))
4522                    (ashift:DI (match_dup 2) (const_int 3))))
4523    (set (match_dup 4) (ior:DI (match_dup 4) (match_dup 3)))
4524    (set (mem:DI (and:DI (match_dup 0) (const_int -8)))
4525         (match_dup 4))]
4526   ""
4527   "")
4528 \f
4529 ;; Here are the define_expand's for QI and HI moves that use the above
4530 ;; patterns.  We have the normal sets, plus the ones that need scratch
4531 ;; registers for reload.
4532
4533 (define_expand "movqi"
4534   [(set (match_operand:QI 0 "general_operand" "")
4535         (match_operand:QI 1 "general_operand" ""))]
4536   ""
4537   "
4538 {
4539   if (TARGET_BWX)
4540     {
4541       if (GET_CODE (operands[0]) == MEM
4542           && ! reg_or_0_operand (operands[1], QImode))
4543         operands[1] = force_reg (QImode, operands[1]);
4544
4545       if (GET_CODE (operands[1]) == CONST_INT
4546                && ! input_operand (operands[1], QImode))
4547         {
4548           operands[1] = alpha_emit_set_const (operands[0], QImode,
4549                                               INTVAL (operands[1]), 3);
4550
4551           if (rtx_equal_p (operands[0], operands[1]))
4552             DONE;
4553         }
4554
4555       goto def;
4556     }
4557
4558   /* If the output is not a register, the input must be.  */
4559   if (GET_CODE (operands[0]) == MEM)
4560     operands[1] = force_reg (QImode, operands[1]);
4561
4562   /* Handle four memory cases, unaligned and aligned for either the input
4563      or the output.  The only case where we can be called during reload is
4564      for aligned loads; all other cases require temporaries.  */
4565
4566   if (GET_CODE (operands[1]) == MEM
4567       || (GET_CODE (operands[1]) == SUBREG
4568           && GET_CODE (SUBREG_REG (operands[1])) == MEM)
4569       || (reload_in_progress && GET_CODE (operands[1]) == REG
4570           && REGNO (operands[1]) >= FIRST_PSEUDO_REGISTER)
4571       || (reload_in_progress && GET_CODE (operands[1]) == SUBREG
4572           && GET_CODE (SUBREG_REG (operands[1])) == REG
4573           && REGNO (SUBREG_REG (operands[1])) >= FIRST_PSEUDO_REGISTER))
4574     {
4575       if (aligned_memory_operand (operands[1], QImode))
4576         {
4577           rtx aligned_mem, bitnum;
4578           rtx scratch = (reload_in_progress
4579                          ? gen_rtx_REG (SImode, REGNO (operands[0]))
4580                          : gen_reg_rtx (SImode));
4581
4582           get_aligned_mem (operands[1], &aligned_mem, &bitnum);
4583
4584           emit_insn (gen_aligned_loadqi (operands[0], aligned_mem, bitnum,
4585                                          scratch));
4586         }
4587       else
4588         {
4589           /* Don't pass these as parameters since that makes the generated
4590              code depend on parameter evaluation order which will cause
4591              bootstrap failures.  */
4592
4593           rtx temp1 = gen_reg_rtx (DImode);
4594           rtx temp2 = gen_reg_rtx (DImode);
4595           rtx seq
4596             = gen_unaligned_loadqi (operands[0],
4597                                     get_unaligned_address (operands[1], 0),
4598                                     temp1, temp2);
4599
4600           alpha_set_memflags (seq, operands[1]);
4601           emit_insn (seq);
4602         }
4603
4604       DONE;
4605     }
4606
4607   else if (GET_CODE (operands[0]) == MEM
4608            || (GET_CODE (operands[0]) == SUBREG 
4609                && GET_CODE (SUBREG_REG (operands[0])) == MEM)
4610            || (reload_in_progress && GET_CODE (operands[0]) == REG
4611                && REGNO (operands[0]) >= FIRST_PSEUDO_REGISTER)
4612            || (reload_in_progress && GET_CODE (operands[0]) == SUBREG
4613                && GET_CODE (SUBREG_REG (operands[0])) == REG
4614                && REGNO (operands[0]) >= FIRST_PSEUDO_REGISTER))
4615     {
4616       if (aligned_memory_operand (operands[0], QImode))
4617         {
4618           rtx aligned_mem, bitnum;
4619           rtx temp1 = gen_reg_rtx (SImode);
4620           rtx temp2 = gen_reg_rtx (SImode);
4621
4622           get_aligned_mem (operands[0], &aligned_mem, &bitnum);
4623
4624           emit_insn (gen_aligned_store (aligned_mem, operands[1], bitnum,
4625                                         temp1, temp2));
4626         }
4627       else
4628         {
4629           rtx temp1 = gen_reg_rtx (DImode);
4630           rtx temp2 = gen_reg_rtx (DImode);
4631           rtx temp3 = gen_reg_rtx (DImode);
4632           rtx seq
4633             = gen_unaligned_storeqi (get_unaligned_address (operands[0], 0),
4634                                            operands[1], temp1, temp2, temp3);
4635
4636           alpha_set_memflags (seq, operands[0]);
4637           emit_insn (seq);
4638         }
4639       DONE;
4640     }
4641  def:;
4642 }")
4643
4644 (define_expand "movhi"
4645   [(set (match_operand:HI 0 "general_operand" "")
4646         (match_operand:HI 1 "general_operand" ""))]
4647   ""
4648   "
4649 {
4650   if (TARGET_BWX)
4651     {
4652       if (GET_CODE (operands[0]) == MEM
4653           && ! reg_or_0_operand (operands[1], HImode))
4654         operands[1] = force_reg (HImode, operands[1]);
4655
4656       if (GET_CODE (operands[1]) == CONST_INT
4657                && ! input_operand (operands[1], HImode))
4658         {
4659           operands[1] = alpha_emit_set_const (operands[0], HImode,
4660                                               INTVAL (operands[1]), 3);
4661
4662           if (rtx_equal_p (operands[0], operands[1]))
4663             DONE;
4664         }
4665
4666       goto def;
4667     }
4668
4669   /* If the output is not a register, the input must be.  */
4670   if (GET_CODE (operands[0]) == MEM)
4671     operands[1] = force_reg (HImode, operands[1]);
4672
4673   /* Handle four memory cases, unaligned and aligned for either the input
4674      or the output.  The only case where we can be called during reload is
4675      for aligned loads; all other cases require temporaries.  */
4676
4677   if (GET_CODE (operands[1]) == MEM
4678       || (GET_CODE (operands[1]) == SUBREG
4679           && GET_CODE (SUBREG_REG (operands[1])) == MEM)
4680       || (reload_in_progress && GET_CODE (operands[1]) == REG
4681           && REGNO (operands[1]) >= FIRST_PSEUDO_REGISTER)
4682       || (reload_in_progress && GET_CODE (operands[1]) == SUBREG
4683           && GET_CODE (SUBREG_REG (operands[1])) == REG
4684           && REGNO (SUBREG_REG (operands[1])) >= FIRST_PSEUDO_REGISTER))
4685     {
4686       if (aligned_memory_operand (operands[1], HImode))
4687         {
4688           rtx aligned_mem, bitnum;
4689           rtx scratch = (reload_in_progress
4690                          ? gen_rtx_REG (SImode, REGNO (operands[0]))
4691                          : gen_reg_rtx (SImode));
4692
4693           get_aligned_mem (operands[1], &aligned_mem, &bitnum);
4694
4695           emit_insn (gen_aligned_loadhi (operands[0], aligned_mem, bitnum,
4696                                          scratch));
4697         }
4698       else
4699         {
4700           /* Don't pass these as parameters since that makes the generated
4701              code depend on parameter evaluation order which will cause
4702              bootstrap failures.  */
4703
4704           rtx temp1 = gen_reg_rtx (DImode);
4705           rtx temp2 = gen_reg_rtx (DImode);
4706           rtx seq
4707             = gen_unaligned_loadhi (operands[0],
4708                                     get_unaligned_address (operands[1], 0),
4709                                     temp1, temp2);
4710
4711           alpha_set_memflags (seq, operands[1]);
4712           emit_insn (seq);
4713         }
4714
4715       DONE;
4716     }
4717
4718   else if (GET_CODE (operands[0]) == MEM
4719            || (GET_CODE (operands[0]) == SUBREG 
4720                && GET_CODE (SUBREG_REG (operands[0])) == MEM)
4721            || (reload_in_progress && GET_CODE (operands[0]) == REG
4722                && REGNO (operands[0]) >= FIRST_PSEUDO_REGISTER)
4723            || (reload_in_progress && GET_CODE (operands[0]) == SUBREG
4724                && GET_CODE (SUBREG_REG (operands[0])) == REG
4725                && REGNO (operands[0]) >= FIRST_PSEUDO_REGISTER))
4726     {
4727       if (aligned_memory_operand (operands[0], HImode))
4728         {
4729           rtx aligned_mem, bitnum;
4730           rtx temp1 = gen_reg_rtx (SImode);
4731           rtx temp2 = gen_reg_rtx (SImode);
4732
4733           get_aligned_mem (operands[0], &aligned_mem, &bitnum);
4734
4735           emit_insn (gen_aligned_store (aligned_mem, operands[1], bitnum,
4736                                         temp1, temp2));
4737         }
4738       else
4739         {
4740           rtx temp1 = gen_reg_rtx (DImode);
4741           rtx temp2 = gen_reg_rtx (DImode);
4742           rtx temp3 = gen_reg_rtx (DImode);
4743           rtx seq
4744             = gen_unaligned_storehi (get_unaligned_address (operands[0], 0),
4745                                      operands[1], temp1, temp2, temp3);
4746
4747           alpha_set_memflags (seq, operands[0]);
4748           emit_insn (seq);
4749         }
4750
4751       DONE;
4752     }
4753  def:;
4754 }")
4755
4756 ;; Here are the versions for reload.  Note that in the unaligned cases
4757 ;; we know that the operand must not be a pseudo-register because stack
4758 ;; slots are always aligned references.
4759
4760 (define_expand "reload_inqi"
4761   [(parallel [(match_operand:QI 0 "register_operand" "=r")
4762               (match_operand:QI 1 "unaligned_memory_operand" "m")
4763               (match_operand:TI 2 "register_operand" "=&r")])]
4764   "! TARGET_BWX"
4765   "
4766 {
4767   rtx addr = get_unaligned_address (operands[1], 0);
4768
4769   /* It is possible that one of the registers we got for operands[2]
4770      might coincide with that of operands[0] (which is why we made
4771      it TImode).  Pick the other one to use as our scratch.  */
4772   rtx scratch = gen_rtx_REG (DImode,
4773                              REGNO (operands[0]) == REGNO (operands[2]) 
4774                              ? REGNO (operands[2]) + 1 : REGNO (operands[2]));
4775
4776   rtx seq = gen_unaligned_loadqi (operands[0], addr, scratch,
4777                                   gen_rtx_REG (DImode, REGNO (operands[0])));
4778
4779   alpha_set_memflags (seq, operands[1]);
4780   emit_insn (seq);
4781   DONE;
4782 }")
4783
4784 (define_expand "reload_inhi"
4785   [(parallel [(match_operand:HI 0 "register_operand" "=r")
4786               (match_operand:HI 1 "unaligned_memory_operand" "m")
4787               (match_operand:TI 2 "register_operand" "=&r")])]
4788   "! TARGET_BWX"
4789   "
4790 {
4791   rtx addr = get_unaligned_address (operands[1], 0);
4792
4793   /* It is possible that one of the registers we got for operands[2]
4794      might coincide with that of operands[0] (which is why we made
4795      it TImode).  Pick the other one to use as our scratch.  */
4796   rtx scratch = gen_rtx_REG (DImode,
4797                              REGNO (operands[0]) == REGNO (operands[2]) 
4798                              ? REGNO (operands[2]) + 1 : REGNO (operands[2]));
4799
4800   rtx seq = gen_unaligned_loadhi (operands[0], addr, scratch,
4801                                   gen_rtx_REG (DImode, REGNO (operands[0])));
4802
4803   alpha_set_memflags (seq, operands[1]);
4804   emit_insn (seq);
4805   DONE;
4806 }")
4807
4808 (define_expand "reload_outqi"
4809   [(parallel [(match_operand:QI 0 "any_memory_operand" "=m")
4810               (match_operand:QI 1 "register_operand" "r")
4811               (match_operand:TI 2 "register_operand" "=&r")])]
4812   "! TARGET_BWX"
4813   "
4814 {
4815   if (aligned_memory_operand (operands[0], QImode))
4816     {
4817       rtx aligned_mem, bitnum;
4818
4819       get_aligned_mem (operands[0], &aligned_mem, &bitnum);
4820
4821       emit_insn (gen_aligned_store (aligned_mem, operands[1], bitnum,
4822                                     gen_rtx_REG (SImode, REGNO (operands[2])),
4823                                     gen_rtx_REG (SImode,
4824                                                  REGNO (operands[2]) + 1)));
4825     }
4826   else
4827     {
4828       rtx addr = get_unaligned_address (operands[0], 0);
4829       rtx scratch1 = gen_rtx_REG (DImode, REGNO (operands[2]));
4830       rtx scratch2 = gen_rtx_REG (DImode, REGNO (operands[2]) + 1);
4831       rtx scratch3 = scratch1;
4832       rtx seq;
4833
4834       if (GET_CODE (addr) == REG)
4835         scratch1 = addr;
4836
4837       seq = gen_unaligned_storeqi (addr, operands[1], scratch1,
4838                                    scratch2, scratch3);
4839       alpha_set_memflags (seq, operands[0]);
4840       emit_insn (seq);
4841     }
4842
4843   DONE;
4844 }")
4845
4846 (define_expand "reload_outhi"
4847   [(parallel [(match_operand:HI 0 "any_memory_operand" "=m")
4848               (match_operand:HI 1 "register_operand" "r")
4849               (match_operand:TI 2 "register_operand" "=&r")])]
4850   "! TARGET_BWX"
4851   "
4852 {
4853   if (aligned_memory_operand (operands[0], HImode))
4854     {
4855       rtx aligned_mem, bitnum;
4856
4857       get_aligned_mem (operands[0], &aligned_mem, &bitnum);
4858
4859       emit_insn (gen_aligned_store (aligned_mem, operands[1], bitnum,
4860                                     gen_rtx_REG (SImode, REGNO (operands[2])),
4861                                     gen_rtx_REG (SImode,
4862                                                  REGNO (operands[2]) + 1)));
4863     }
4864   else
4865     {
4866       rtx addr = get_unaligned_address (operands[0], 0);
4867       rtx scratch1 = gen_rtx_REG (DImode, REGNO (operands[2]));
4868       rtx scratch2 = gen_rtx_REG (DImode, REGNO (operands[2]) + 1);
4869       rtx scratch3 = scratch1;
4870       rtx seq;
4871
4872       if (GET_CODE (addr) == REG)
4873         scratch1 = addr;
4874
4875       seq = gen_unaligned_storehi (addr, operands[1], scratch1,
4876                                    scratch2, scratch3);
4877       alpha_set_memflags (seq, operands[0]);
4878       emit_insn (seq);
4879     }
4880
4881   DONE;
4882 }")
4883 \f
4884 ;; Bit field extract patterns which use ext[wlq][lh]
4885
4886 (define_expand "extv"
4887   [(set (match_operand:DI 0 "register_operand" "")
4888         (sign_extract:DI (match_operand:QI 1 "memory_operand" "")
4889                          (match_operand:DI 2 "immediate_operand" "")
4890                          (match_operand:DI 3 "immediate_operand" "")))]
4891   ""
4892   "
4893 {
4894   /* We can do 16, 32 and 64 bit fields, if aligned on byte boundaries.  */
4895   if (INTVAL (operands[3]) % 8 != 0
4896       || (INTVAL (operands[2]) != 16
4897           && INTVAL (operands[2]) != 32
4898           && INTVAL (operands[2]) != 64))
4899     FAIL;
4900
4901   /* From mips.md: extract_bit_field doesn't verify that our source
4902      matches the predicate, so we force it to be a MEM here.  */
4903   if (GET_CODE (operands[1]) != MEM)
4904     FAIL;
4905
4906   alpha_expand_unaligned_load (operands[0], operands[1],
4907                                INTVAL (operands[2]) / 8,
4908                                INTVAL (operands[3]) / 8, 1);
4909   DONE;
4910 }")
4911
4912 (define_expand "extzv"
4913   [(set (match_operand:DI 0 "register_operand" "")
4914         (zero_extract:DI (match_operand:DI 1 "general_operand" "")
4915                          (match_operand:DI 2 "immediate_operand" "")
4916                          (match_operand:DI 3 "immediate_operand" "")))]
4917   ""
4918   "
4919 {
4920   /* We can do 8, 16, 32 and 64 bit fields, if aligned on byte boundaries.  */
4921   if (INTVAL (operands[3]) % 8 != 0
4922       || (INTVAL (operands[2]) != 8
4923           && INTVAL (operands[2]) != 16
4924           && INTVAL (operands[2]) != 32
4925           && INTVAL (operands[2]) != 64))
4926     FAIL;
4927
4928   if (GET_CODE (operands[1]) == MEM)
4929     {
4930       /* Fail 8 bit fields, falling back on a simple byte load.  */
4931       if (INTVAL (operands[2]) == 8)
4932         FAIL;
4933
4934       alpha_expand_unaligned_load (operands[0], operands[1],
4935                                    INTVAL (operands[2]) / 8,
4936                                    INTVAL (operands[3]) / 8, 0);
4937       DONE;
4938     }
4939 }")
4940
4941 (define_expand "insv"
4942   [(set (zero_extract:DI (match_operand:QI 0 "memory_operand" "")
4943                          (match_operand:DI 1 "immediate_operand" "")
4944                          (match_operand:DI 2 "immediate_operand" ""))
4945         (match_operand:DI 3 "register_operand" ""))]
4946   ""
4947   "
4948 {
4949   /* We can do 16, 32 and 64 bit fields, if aligned on byte boundaries.  */
4950   if (INTVAL (operands[2]) % 8 != 0
4951       || (INTVAL (operands[1]) != 16
4952           && INTVAL (operands[1]) != 32
4953           && INTVAL (operands[1]) != 64))
4954     FAIL;
4955
4956   /* From mips.md: store_bit_field doesn't verify that our source
4957      matches the predicate, so we force it to be a MEM here.  */
4958   if (GET_CODE (operands[0]) != MEM)
4959     FAIL;
4960
4961   alpha_expand_unaligned_store (operands[0], operands[3],
4962                                 INTVAL (operands[1]) / 8,
4963                                 INTVAL (operands[2]) / 8);
4964   DONE;
4965 }")
4966
4967
4968
4969 ;; Block move/clear, see alpha.c for more details.
4970 ;; Argument 0 is the destination
4971 ;; Argument 1 is the source
4972 ;; Argument 2 is the length
4973 ;; Argument 3 is the alignment
4974
4975 (define_expand "movstrqi"
4976   [(parallel [(set (match_operand:BLK 0 "general_operand" "")
4977                    (match_operand:BLK 1 "general_operand" ""))
4978               (use (match_operand:DI 2 "immediate_operand" ""))
4979               (use (match_operand:DI 3 "immediate_operand" ""))])]
4980   ""
4981   "
4982 {
4983   if (alpha_expand_block_move (operands))
4984     DONE;
4985   else
4986     FAIL;
4987 }")
4988
4989 (define_expand "clrstrqi"
4990   [(parallel [(set (match_operand:BLK 0 "general_operand" "")
4991                    (const_int 0))
4992               (use (match_operand:DI 1 "immediate_operand" ""))
4993               (use (match_operand:DI 2 "immediate_operand" ""))])]
4994   ""
4995   "
4996 {
4997   if (alpha_expand_block_clear (operands))
4998     DONE;
4999   else
5000     FAIL;
5001 }")
5002 \f
5003 ;; Subroutine of stack space allocation.  Perform a stack probe.
5004 (define_expand "probe_stack"
5005   [(set (match_dup 1) (match_operand:DI 0 "const_int_operand" ""))]
5006   ""
5007   "
5008 {
5009   operands[1] = gen_rtx_MEM (DImode, plus_constant (stack_pointer_rtx,
5010                                                     INTVAL (operands[0])));
5011   MEM_VOLATILE_P (operands[1]) = 1;
5012
5013   operands[0] = const0_rtx;
5014 }")
5015
5016 ;; This is how we allocate stack space.  If we are allocating a
5017 ;; constant amount of space and we know it is less than 4096
5018 ;; bytes, we need do nothing.
5019 ;;
5020 ;; If it is more than 4096 bytes, we need to probe the stack
5021 ;; periodically. 
5022 (define_expand "allocate_stack"
5023   [(set (reg:DI 30)
5024         (plus:DI (reg:DI 30)
5025                  (match_operand:DI 1 "reg_or_cint_operand" "")))
5026    (set (match_operand:DI 0 "register_operand" "=r")
5027         (match_dup 2))]
5028   ""
5029   "
5030 {
5031   if (GET_CODE (operands[1]) == CONST_INT
5032       && INTVAL (operands[1]) < 32768)
5033     {
5034       if (INTVAL (operands[1]) >= 4096)
5035         {
5036           /* We do this the same way as in the prologue and generate explicit
5037              probes.  Then we update the stack by the constant.  */
5038
5039           int probed = 4096;
5040
5041           emit_insn (gen_probe_stack (GEN_INT (- probed)));
5042           while (probed + 8192 < INTVAL (operands[1]))
5043             emit_insn (gen_probe_stack (GEN_INT (- (probed += 8192))));
5044
5045           if (probed + 4096 < INTVAL (operands[1]))
5046             emit_insn (gen_probe_stack (GEN_INT (- INTVAL(operands[1]))));
5047         }
5048
5049       operands[1] = GEN_INT (- INTVAL (operands[1]));
5050       operands[2] = virtual_stack_dynamic_rtx;
5051     }
5052   else
5053     {
5054       rtx out_label = 0;
5055       rtx loop_label = gen_label_rtx ();
5056       rtx want = gen_reg_rtx (Pmode);
5057       rtx tmp = gen_reg_rtx (Pmode);
5058       rtx memref;
5059
5060       emit_insn (gen_subdi3 (want, stack_pointer_rtx,
5061                              force_reg (Pmode, operands[1])));
5062       emit_insn (gen_adddi3 (tmp, stack_pointer_rtx, GEN_INT (-4096)));
5063
5064       if (GET_CODE (operands[1]) != CONST_INT)
5065         {
5066           out_label = gen_label_rtx ();
5067           emit_insn (gen_cmpdi (want, tmp));
5068           emit_jump_insn (gen_bgeu (out_label));
5069         }
5070
5071       emit_label (loop_label);
5072       memref = gen_rtx_MEM (DImode, tmp);
5073       MEM_VOLATILE_P (memref) = 1;
5074       emit_move_insn (memref, const0_rtx);
5075       emit_insn (gen_adddi3 (tmp, tmp, GEN_INT(-8192)));
5076       emit_insn (gen_cmpdi (tmp, want));
5077       emit_jump_insn (gen_bgtu (loop_label));
5078       if (obey_regdecls)
5079         gen_rtx_USE (VOIDmode, tmp);
5080
5081       memref = gen_rtx_MEM (DImode, want);
5082       MEM_VOLATILE_P (memref) = 1;
5083       emit_move_insn (memref, const0_rtx);
5084
5085       if (out_label)
5086         emit_label (out_label);
5087
5088       emit_move_insn (stack_pointer_rtx, want);
5089       emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
5090       DONE;
5091     }
5092 }")
5093
5094 ;; This is used by alpha_expand_prolog to do the same thing as above,
5095 ;; except we cannot at that time generate new basic blocks, so we hide
5096 ;; the loop in this one insn.
5097
5098 (define_insn "prologue_stack_probe_loop"
5099   [(unspec_volatile [(match_operand 0 "register_operand" "r")
5100                      (match_operand 1 "register_operand" "r")] 5)]
5101   ""
5102   "*
5103 {
5104   operands[2] = gen_label_rtx ();
5105   ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, \"L\",
5106                              CODE_LABEL_NUMBER (operands[2]));
5107
5108   return \"stq $31,-8192(%1)\;subq %0,1,%0\;lda %1,-8192(%1)\;bne %0,%l2\";
5109 }"
5110   [(set_attr "length" "16")
5111    (set_attr "type" "multi")])
5112
5113 (define_expand "prologue"
5114   [(clobber (const_int 0))]
5115   ""
5116   "alpha_expand_prologue (); DONE;")
5117
5118 (define_insn "init_fp"
5119   [(set (match_operand:DI 0 "register_operand" "r")
5120         (match_operand:DI 1 "register_operand" "r"))
5121    (clobber (mem:BLK (match_operand:DI 2 "register_operand" "r")))]
5122   ""
5123   "mov %1,%0")
5124
5125 (define_expand "epilogue"
5126   [(clobber (const_int 0))]
5127   ""
5128   "alpha_expand_epilogue (); DONE;")
5129
5130 (define_expand "eh_epilogue"
5131   [(use (match_operand:DI 0 "register_operand" "r"))
5132    (use (match_operand:DI 1 "register_operand" "r"))
5133    (use (match_operand:DI 2 "register_operand" "r"))]
5134   "! TARGET_OPEN_VMS"
5135   "
5136 {
5137   alpha_eh_epilogue_sp_ofs = operands[1];
5138   if (GET_CODE (operands[2]) != REG || REGNO (operands[2]) != 26)
5139     {
5140       rtx ra = gen_rtx_REG (Pmode, 26);
5141       emit_move_insn (ra, operands[2]);
5142       operands[2] = ra;
5143     }
5144 }")
5145
5146 (define_expand "builtin_longjmp"
5147   [(unspec_volatile [(match_operand 0 "register_operand" "r")] 3)]
5148   "! TARGET_OPEN_VMS && ! TARGET_WINDOWS_NT"
5149   "
5150 {
5151   /* The elements of the buffer are, in order:  */
5152   rtx fp = gen_rtx_MEM (Pmode, operands[0]);
5153   rtx lab = gen_rtx_MEM (Pmode, plus_constant (operands[0], 8));
5154   rtx stack = gen_rtx_MEM (Pmode, plus_constant (operands[0], 16));
5155   rtx pv = gen_rtx_REG (Pmode, 27);
5156
5157   /* This bit is the same as expand_builtin_longjmp.  */
5158   emit_move_insn (hard_frame_pointer_rtx, fp);
5159   emit_move_insn (pv, lab);
5160   emit_stack_restore (SAVE_NONLOCAL, stack, NULL_RTX);
5161   emit_insn (gen_rtx_USE (VOIDmode, hard_frame_pointer_rtx));
5162   emit_insn (gen_rtx_USE (VOIDmode, stack_pointer_rtx));
5163
5164   /* Load the label we are jumping through into $27 so that we know
5165      where to look for it when we get back to setjmp's function for
5166      restoring the gp.  */
5167   emit_indirect_jump (pv);
5168   DONE;
5169 }")
5170
5171 (define_insn "builtin_setjmp_receiver"
5172   [(unspec_volatile [(match_operand 0 "" "")] 2)]
5173   "! TARGET_OPEN_VMS && ! TARGET_WINDOWS_NT && TARGET_AS_CAN_SUBTRACT_LABELS"
5174   "\\n$LSJ%=:\;ldgp $29,$LSJ%=-%l0($27)"
5175   [(set_attr "length" "8")
5176    (set_attr "type" "multi")])
5177
5178 (define_insn ""
5179   [(unspec_volatile [(match_operand 0 "" "")] 2)]
5180   "! TARGET_OPEN_VMS && ! TARGET_WINDOWS_NT"
5181   "br $29,$LSJ%=\\n$LSJ%=:\;ldgp $29,0($29)"
5182   [(set_attr "length" "12")
5183    (set_attr "type" "multi")])
5184
5185 (define_insn "exception_receiver"
5186   [(unspec_volatile [(const_int 0)] 7)]
5187   "! TARGET_OPEN_VMS && ! TARGET_WINDOWS_NT"
5188   "br $29,$LSJ%=\\n$LSJ%=:\;ldgp $29,0($29)"
5189   [(set_attr "length" "12")
5190    (set_attr "type" "multi")])
5191
5192 (define_expand "nonlocal_goto_receiver"
5193   [(unspec_volatile [(const_int 0)] 1)
5194    (set (reg:DI 27) (mem:DI (reg:DI 29)))
5195    (unspec_volatile [(const_int 0)] 1)
5196    (use (reg:DI 27))]
5197   "TARGET_OPEN_VMS"
5198   "")
5199
5200 (define_insn "arg_home"
5201   [(unspec [(const_int 0)] 0)
5202    (use (reg:DI 1))
5203    (use (reg:DI 25))
5204    (use (reg:DI 16))
5205    (use (reg:DI 17))
5206    (use (reg:DI 18))
5207    (use (reg:DI 19))
5208    (use (reg:DI 20))
5209    (use (reg:DI 21))
5210    (use (reg:DI 48))
5211    (use (reg:DI 49))
5212    (use (reg:DI 50))
5213    (use (reg:DI 51))
5214    (use (reg:DI 52))
5215    (use (reg:DI 53))
5216    (clobber (mem:BLK (const_int 0)))
5217    (clobber (reg:DI 24))
5218    (clobber (reg:DI 25))
5219    (clobber (reg:DI 0))]
5220   "TARGET_OPEN_VMS"
5221   "lda $0,OTS$HOME_ARGS\;ldq $0,8($0)\;jsr $0,OTS$HOME_ARGS"
5222   [(set_attr "length" "16")
5223    (set_attr "type" "multi")])
5224
5225 ;; Close the trap shadow of preceeding instructions.  This is generated
5226 ;; by alpha_reorg.
5227
5228 (define_insn "trapb"
5229   [(unspec_volatile [(const_int 0)] 4)]
5230   ""
5231   "trapb"
5232   [(set_attr "type" "misc")])
5233
5234 ;; No-op instructions used by machine-dependant reorg to preserve
5235 ;; alignment for instruction issue.
5236
5237 (define_insn "nop"
5238   [(const_int 0)]
5239   ""
5240   "nop"
5241   [(set_attr "type" "ilog")])
5242
5243 (define_insn "fnop"
5244   [(const_int 1)]
5245   "TARGET_FP"
5246   "fnop"
5247   [(set_attr "type" "fcpys")])
5248
5249 (define_insn "unop"
5250   [(const_int 2)]
5251   ""
5252   "unop")
5253
5254 (define_insn "realign"
5255   [(unspec_volatile [(match_operand 0 "immediate_operand" "i")] 6)]
5256   ""
5257   ".align %0 #realign")
5258 \f
5259 ;; Peepholes go at the end.
5260
5261 ;; Optimize sign-extension of SImode loads.  This shows up in the wake of
5262 ;; reload when converting fp->int.
5263 ;;
5264 ;; ??? What to do now that we actually care about the packing and
5265 ;; alignment of instructions?  Perhaps reload can be enlightened, or
5266 ;; the peephole pass moved up after reload but before sched2?
5267 ;
5268 ;(define_peephole
5269 ;  [(set (match_operand:SI 0 "register_operand" "=r")
5270 ;        (match_operand:SI 1 "memory_operand" "m"))
5271 ;   (set (match_operand:DI 2 "register_operand" "=r")
5272 ;        (sign_extend:DI (match_dup 0)))]
5273 ;  "dead_or_set_p (insn, operands[0])"
5274 ;  "ldl %2,%1")
5275 ;
5276 ;(define_peephole
5277 ;  [(set (match_operand:SI 0 "register_operand" "=r")
5278 ;        (match_operand:SI 1 "hard_fp_register_operand" "f"))
5279 ;   (set (match_operand:DI 2 "register_operand" "=r")
5280 ;        (sign_extend:DI (match_dup 0)))]
5281 ;  "TARGET_CIX && dead_or_set_p (insn, operands[0])"
5282 ;  "ftois %1,%2")