Import gcc-2.8.1.tar.bz2
[official-gcc.git] / gcc / config / alpha / alpha.md
blob1feddc5eb6d6b4fcea7ad067e2316fb89154243b
1 ;; Machine description for DEC Alpha for GNU C compiler
2 ;; Copyright (C) 1992, 93, 94, 95, 96, 1997 Free Software Foundation, Inc.
3 ;; Contributed by Richard Kenner (kenner@vlsi1.ultra.nyu.edu)
5 ;; This file is part of GNU CC.
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.
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.
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.
22 ;;- See file "rtl.def" for documentation on define_insn, match_*, et. al.
24 ;; Processor type -- this attribute must exactly match the processor_type
25 ;; enumeration in alpha.h.
27 (define_attr "cpu" "ev4,ev5,ev6"
28   (const (symbol_ref "alpha_cpu")))
30 ;; Define an insn type attribute.  This is used in function unit delay
31 ;; computations, among other purposes.  For the most part, we use the names
32 ;; defined in the EV4 documentation, but add a few that we have to know about
33 ;; separately.
35 (define_attr "type"
36   "ld,st,ibr,fbr,jsr,iadd,ilog,shift,cmov,icmp,imull,imulq,fadd,fmul,fcpys,fdivs,fdivt,ldsym,isubr"
37   (const_string "iadd"))
39 ;; The TRAP_TYPE attribute marks instructions that may generate traps
40 ;; (which are imprecise and may need a trapb if software completion
41 ;; is desired).
42 (define_attr "trap" "yes,no" (const_string "no"))
44 ;; For the EV4 we include four function units: ABOX, which computes the address,
45 ;; BBOX, used for branches, EBOX, used for integer operations, and FBOX,
46 ;; used for FP operations.
48 ;; We assume that we have been successful in getting double issues and
49 ;; hence multiply all costs by two insns per cycle.  The minimum time in
50 ;; a function unit is 2 cycle, which will tend to produce the double
51 ;; issues.
53 ;; Memory delivers its result in three cycles.
54 (define_function_unit "ev4_abox" 1 0
55   (and (eq_attr "cpu" "ev4")
56        (eq_attr "type" "ld,st"))
57   6 2)
59 ;; Branches have no delay cost, but do tie up the unit for two cycles.
60 (define_function_unit "ev4_bbox" 1 1
61   (and (eq_attr "cpu" "ev4")
62        (eq_attr "type" "ibr,fbr,jsr"))
63   4 4)
65 ;; Arithmetic insns are normally have their results available after two
66 ;; cycles.  There are a number of exceptions.  They are encoded in
67 ;; ADJUST_COST.  Some of the other insns have similar exceptions.
69 (define_function_unit "ev4_ebox" 1 0
70   (and (eq_attr "cpu" "ev4")
71        (eq_attr "type" "iadd,ilog,ldsym,shift,cmov,icmp"))
72   4 2)
74 ;; These really don't take up the integer pipeline, but they do occupy
75 ;; IBOX1; we approximate here.
77 (define_function_unit "ev4_ebox" 1 0
78   (and (eq_attr "cpu" "ev4")
79        (eq_attr "type" "imull"))
80   42 2)
82 (define_function_unit "ev4_ebox" 1 0
83   (and (eq_attr "cpu" "ev4")
84        (eq_attr "type" "imulq"))
85   46 2)
87 (define_function_unit "ev4_imult" 1 0
88   (and (eq_attr "cpu" "ev4")
89        (eq_attr "type" "imull"))
90   42 38)
92 (define_function_unit "ev4_imult" 1 0
93   (and (eq_attr "cpu" "ev4")
94        (eq_attr "type" "imulq"))
95   46 42)
97 (define_function_unit "ev4_fbox" 1 0
98   (and (eq_attr "cpu" "ev4")
99        (eq_attr "type" "fadd,fmul,fcpys"))
100   12 2)
102 (define_function_unit "ev4_fbox" 1 0
103   (and (eq_attr "cpu" "ev4")
104        (eq_attr "type" "fdivs"))
105   68 0)
107 (define_function_unit "ev4_fbox" 1 0
108   (and (eq_attr "cpu" "ev4")
109        (eq_attr "type" "fdivt"))
110   126 0)
112 (define_function_unit "ev4_divider" 1 0
113   (and (eq_attr "cpu" "ev4")
114        (eq_attr "type" "fdivs"))
115   68 60)
117 (define_function_unit "ev4_divider" 1 0
118   (and (eq_attr "cpu" "ev4")
119        (eq_attr "type" "fdivt"))
120   126 118)
122 ;; EV5 scheduling.  EV5 can issue 4 insns per clock.
123 ;; Multiply all costs by 4.  We consider the EV6 and EV5 for now.
125 ;; EV5 has two integer units.
126 (define_function_unit "ev5_ebox" 2 0
127   (and (eq_attr "cpu" "ev5,ev6")
128        (eq_attr "type" "iadd,ilog,icmp,ldsym"))
129   4 4)
131 ;; Memory takes at least 2 clocks.
132 ;; Conditional moves always take 2 ticks.
133 (define_function_unit "ev5_ebox" 2 0
134   (and (eq_attr "cpu" "ev5,ev6")
135        (eq_attr "type" "ld,cmov"))
136   8 4)
138 ;; Loads can dual issue.  Store cannot; nor can loads + stores.
139 ;; Model this with a mythical load/store unit.
140 (define_function_unit "ev5_ldst" 1 0
141   (and (eq_attr "cpu" "ev5,ev6")
142        (eq_attr "type" "ld"))
143   8 4 [(eq_attr "type" "st")])
145 (define_function_unit "ev5_ldst" 1 0
146   (and (eq_attr "cpu" "ev5,ev6")
147        (eq_attr "type" "st"))
148   4 4)
150 (define_function_unit "ev5_ebox" 2 0
151   (and (eq_attr "cpu" "ev5,ev6")
152        (eq_attr "type" "imull"))
153   32 4)
155 (define_function_unit "ev5_ebox" 2 0
156   (and (eq_attr "cpu" "ev5,ev6")
157        (eq_attr "type" "imulq"))
158   48 4)
160 ;; Multiplies also use the integer multiplier.
161 (define_function_unit "ev5_imult" 1 0
162   (and (eq_attr "cpu" "ev5,ev6")
163        (eq_attr "type" "imull"))
164   16 8)
166 (define_function_unit "ev5_imult" 1 0
167   (and (eq_attr "cpu" "ev5,ev6")
168        (eq_attr "type" "imulq"))
169   48 32)
171 ;; There is only 1 shifter/zapper.
172 (define_function_unit "ev5_shift" 1 0
173   (and (eq_attr "cpu" "ev5,ev6")
174        (eq_attr "type" "shift"))
175   4 4)
177 ;; We pretend EV5 has symmetrical 2 fpus,
178 ;; even though cpys is the only insn that can issue on either unit.
179 (define_function_unit "ev5_fpu" 2 0
180   (and (eq_attr "cpu" "ev5,ev6")
181        (eq_attr "type" "fadd,fmul,fcpys"))
182   16 4)
183   
184 ;; Multiplies (resp. adds) also use the fmul (resp. fadd) units.
185 (define_function_unit "ev5_fpmul" 1 0
186   (and (eq_attr "cpu" "ev5,ev6")
187        (eq_attr "type" "fmul"))
188   16 4)
190 (define_function_unit "ev5_fpadd" 1 0
191   (and (eq_attr "cpu" "ev5,ev6")
192        (eq_attr "type" "fadd"))
193   16 4)
195 (define_function_unit "ev5_fpadd" 1 0
196   (and (eq_attr "cpu" "ev5,ev6")
197        (eq_attr "type" "fbr"))
198   4 4)
200 (define_function_unit "ev5_fpadd" 1 0
201   (and (eq_attr "cpu" "ev5,ev6")
202        (eq_attr "type" "fdivs"))
203   60 4)
205 (define_function_unit "ev5_fpadd" 1 0
206   (and (eq_attr "cpu" "ev5,ev6")
207        (eq_attr "type" "fdivt"))
208   88 4)
210 ;; First define the arithmetic insns.  Note that the 32-bit forms also
211 ;; sign-extend.
213 ;; Note that we can do sign extensions in both FP and integer registers.
214 ;; However, the result must be in the same type of register as the input.
215 ;; The register preferencing code can't handle this case very well, so, for
216 ;; now, don't let the FP case show up here for preferencing.  Also,
217 ;; sign-extends in FP registers take two instructions.
218 (define_insn "extendsidi2"
219   [(set (match_operand:DI 0 "register_operand" "=r,r,*f")
220         (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "r,m,*f")))]
221   ""
222   "@
223    addl %1,$31,%0
224    ldl %0,%1
225    cvtql %1,%0\;cvtlq %0,%0"
226   [(set_attr "type" "iadd,ld,fadd")])
228 ;; Do addsi3 the way expand_binop would do if we didn't have one.  This
229 ;; generates better code.  We have the anonymous addsi3 pattern below in
230 ;; case combine wants to make it.
231 (define_expand "addsi3"
232   [(set (match_operand:SI 0 "register_operand" "")
233         (plus:SI (match_operand:SI 1 "reg_or_0_operand" "")
234                  (match_operand:SI 2 "add_operand" "")))]
235   ""
236   "
237 { emit_insn (gen_rtx (SET, VOIDmode, gen_lowpart (DImode, operands[0]),
238                       gen_rtx (PLUS, DImode,
239                                gen_lowpart (DImode, operands[1]),
240                                gen_lowpart (DImode, operands[2]))));
241   DONE;
242 } ")
244 (define_insn ""
245   [(set (match_operand:SI 0 "register_operand" "=r,r,r,r")
246         (plus:SI (match_operand:SI 1 "reg_or_0_operand" "%rJ,rJ,rJ,rJ")
247                  (match_operand:SI 2 "add_operand" "rI,O,K,L")))]
248   ""
249   "@
250    addl %r1,%2,%0
251    subl %r1,%n2,%0
252    lda %0,%2(%r1)
253    ldah %0,%h2(%r1)")
255 (define_split
256   [(set (match_operand:SI 0 "register_operand" "")
257         (plus:SI (match_operand:SI 1 "register_operand" "")
258                  (match_operand:SI 2 "const_int_operand" "")))]
259   "! add_operand (operands[2], SImode)"
260   [(set (match_dup 0) (plus:SI (match_dup 1) (match_dup 3)))
261    (set (match_dup 0) (plus:SI (match_dup 0) (match_dup 4)))]
262   "
264   HOST_WIDE_INT val = INTVAL (operands[2]);
265   HOST_WIDE_INT low = (val & 0xffff) - 2 * (val & 0x8000);
266   HOST_WIDE_INT rest = val - low;
268   operands[3] = GEN_INT (rest);
269   operands[4] = GEN_INT (low);
272 (define_insn ""
273   [(set (match_operand:DI 0 "register_operand" "=r,r")
274         (sign_extend:DI
275          (plus:SI (match_operand:SI 1 "reg_or_0_operand" "%rJ,rJ")
276                   (match_operand:SI 2 "sext_add_operand" "rI,O"))))]
277   ""
278   "@
279    addl %r1,%2,%0
280    subl %r1,%n2,%0")
282 (define_split
283   [(set (match_operand:DI 0 "register_operand" "")
284         (sign_extend:DI
285          (plus:SI (match_operand:SI 1 "register_operand" "")
286                   (match_operand:SI 2 "const_int_operand" ""))))
287    (clobber (match_operand:SI 3 "register_operand" ""))]
288   "! sext_add_operand (operands[2], SImode) && INTVAL (operands[2]) > 0
289    && INTVAL (operands[2]) % 4 == 0"
290   [(set (match_dup 3) (match_dup 4))
291    (set (match_dup 0) (sign_extend:DI (plus:SI (mult:SI (match_dup 3)
292                                                         (match_dup 5))
293                                                (match_dup 1))))]
294   "
296   HOST_WIDE_INT val = INTVAL (operands[2]) / 4;
297   int mult = 4;
299   if (val % 2 == 0)
300     val /= 2, mult = 8;
302   operands[4] = GEN_INT (val);
303   operands[5] = GEN_INT (mult);
306 (define_split
307   [(set (match_operand:DI 0 "register_operand" "")
308         (sign_extend:DI
309          (plus:SI (match_operator:SI 1 "comparison_operator"
310                                      [(match_operand 2 "" "")
311                                       (match_operand 3 "" "")])
312                   (match_operand:SI 4 "add_operand" ""))))
313    (clobber (match_operand:DI 5 "register_operand" ""))]
314   ""
315   [(set (match_dup 5) (match_dup 6))
316    (set (match_dup 0) (sign_extend:DI (plus:SI (match_dup 7) (match_dup 4))))]
317   "
319   operands[6] = gen_rtx (GET_CODE (operands[1]), DImode,
320                          operands[2], operands[3]);
321   operands[7] = gen_lowpart (SImode, operands[5]);
324 (define_insn "adddi3"
325   [(set (match_operand:DI 0 "register_operand" "=r,r,r,r")
326         (plus:DI (match_operand:DI 1 "reg_or_0_operand" "%rJ,rJ,rJ,rJ")
327                  (match_operand:DI 2 "add_operand" "rI,O,K,L")))]
328   ""
329   "@
330    addq %r1,%2,%0
331    subq %r1,%n2,%0
332    lda %0,%2(%r1)
333    ldah %0,%h2(%r1)")
335 ;; Don't do this if we are adjusting SP since we don't want to do
336 ;; it in two steps. 
337 (define_split
338   [(set (match_operand:DI 0 "register_operand" "")
339         (plus:DI (match_operand:DI 1 "register_operand" "")
340                  (match_operand:DI 2 "const_int_operand" "")))]
341   "! add_operand (operands[2], DImode)
342    && REGNO (operands[0]) != STACK_POINTER_REGNUM"
343   [(set (match_dup 0) (plus:DI (match_dup 1) (match_dup 3)))
344    (set (match_dup 0) (plus:DI (match_dup 0) (match_dup 4)))]
345   "
347   HOST_WIDE_INT val = INTVAL (operands[2]);
348   HOST_WIDE_INT low = (val & 0xffff) - 2 * (val & 0x8000);
349   HOST_WIDE_INT rest = val - low;
351   operands[3] = GEN_INT (rest);
352   operands[4] = GEN_INT (low);
355 (define_insn ""
356   [(set (match_operand:SI 0 "register_operand" "=r,r")
357         (plus:SI (mult:SI (match_operand:SI 1 "reg_or_0_operand" "rJ,rJ")
358                           (match_operand:SI 2 "const48_operand" "I,I"))
359                  (match_operand:SI 3 "sext_add_operand" "rI,O")))]
360   ""
361   "@
362    s%2addl %r1,%3,%0
363    s%2subl %r1,%n3,%0")
365 (define_insn ""
366   [(set (match_operand:DI 0 "register_operand" "=r,r")
367         (sign_extend:DI
368          (plus:SI (mult:SI (match_operand:SI 1 "reg_or_0_operand" "rJ,rJ")
369                            (match_operand:SI 2 "const48_operand" "I,I"))
370                   (match_operand:SI 3 "sext_add_operand" "rI,O"))))]
371   ""
372   "@
373    s%2addl %r1,%3,%0
374    s%2subl %r1,%n3,%0")
376 (define_split
377   [(set (match_operand:DI 0 "register_operand" "")
378         (sign_extend:DI
379          (plus:SI (mult:SI (match_operator:SI 1 "comparison_operator"
380                                               [(match_operand 2 "" "")
381                                                (match_operand 3 "" "")])
382                            (match_operand:SI 4 "const48_operand" ""))
383                   (match_operand:SI 5 "add_operand" ""))))
384    (clobber (match_operand:DI 6 "register_operand" ""))]
385   ""
386   [(set (match_dup 6) (match_dup 7))
387    (set (match_dup 0)
388         (sign_extend:DI (plus:SI (mult:SI (match_dup 8) (match_dup 4))
389                                  (match_dup 5))))]
390   "
392   operands[7] = gen_rtx (GET_CODE (operands[1]), DImode,
393                          operands[2], operands[3]);
394   operands[8] = gen_lowpart (SImode, operands[6]);
397 (define_insn ""
398   [(set (match_operand:DI 0 "register_operand" "=r,r")
399         (plus:DI (mult:DI (match_operand:DI 1 "reg_or_0_operand" "rJ,rJ")
400                           (match_operand:DI 2 "const48_operand" "I,I"))
401                  (match_operand:DI 3 "reg_or_8bit_operand" "rI,O")))]
402   ""
403   "@
404    s%2addq %r1,%3,%0
405    s%2subq %1,%n3,%0")
407 ;; These variants of the above insns can occur if the third operand
408 ;; is the frame pointer.  This is a kludge, but there doesn't
409 ;; seem to be a way around it.  Only recognize them while reloading.
411 (define_insn ""
412   [(set (match_operand:DI 0 "some_operand" "=&r")
413         (plus:DI (plus:DI (match_operand:DI 1 "some_operand" "r")
414                           (match_operand:DI 2 "some_operand" "r"))
415                  (match_operand:DI 3 "some_operand" "rIOKL")))]
416   "reload_in_progress"
417   "#")
419 (define_split
420   [(set (match_operand:DI 0 "register_operand" "")
421         (plus:DI (plus:DI (match_operand:DI 1 "register_operand" "")
422                           (match_operand:DI 2 "register_operand" ""))
423                  (match_operand:DI 3 "add_operand" "")))]
424   "reload_completed"
425   [(set (match_dup 0) (plus:DI (match_dup 1) (match_dup 2)))
426    (set (match_dup 0) (plus:DI (match_dup 0) (match_dup 3)))]
427   "")
428                                            
429 (define_insn ""
430   [(set (match_operand:SI 0 "some_operand" "=&r")
431         (plus:SI (plus:SI (mult:SI (match_operand:SI 1 "some_operand" "rJ")
432                                    (match_operand:SI 2 "const48_operand" "I"))
433                           (match_operand:SI 3 "some_operand" "r"))
434                  (match_operand:SI 4 "some_operand" "rIOKL")))]
435   "reload_in_progress"
436   "#")
438 (define_split
439   [(set (match_operand:SI 0 "register_operand" "r")
440         (plus:SI (plus:SI (mult:SI (match_operand:SI 1 "reg_or_0_operand" "")
441                                    (match_operand:SI 2 "const48_operand" ""))
442                           (match_operand:SI 3 "register_operand" ""))
443                  (match_operand:SI 4 "add_operand" "rIOKL")))]
444   "reload_completed"
445   [(set (match_dup 0)
446         (plus:SI (mult:SI (match_dup 1) (match_dup 2)) (match_dup 3)))
447    (set (match_dup 0) (plus:SI (match_dup 0) (match_dup 4)))]
448   "")
450 (define_insn ""
451   [(set (match_operand:DI 0 "some_operand" "=&r")
452         (sign_extend:DI
453          (plus:SI (plus:SI
454                    (mult:SI (match_operand:SI 1 "some_operand" "rJ")
455                             (match_operand:SI 2 "const48_operand" "I"))
456                    (match_operand:SI 3 "some_operand" "r"))
457                   (match_operand:SI 4 "some_operand" "rIOKL"))))]
458   "reload_in_progress"
459   "#")
461 (define_split
462   [(set (match_operand:DI 0 "register_operand" "")
463         (sign_extend:DI
464          (plus:SI (plus:SI
465                    (mult:SI (match_operand:SI 1 "reg_or_0_operand" "")
466                             (match_operand:SI 2 "const48_operand" ""))
467                    (match_operand:SI 3 "register_operand" ""))
468                   (match_operand:SI 4 "add_operand" ""))))]
469   "reload_completed"
470   [(set (match_dup 5)
471         (plus:SI (mult:SI (match_dup 1) (match_dup 2)) (match_dup 3)))
472    (set (match_dup 0) (sign_extend:DI (plus:SI (match_dup 5) (match_dup 4))))]
473   "
474 { operands[5] = gen_lowpart (SImode, operands[0]);
477 (define_insn ""
478   [(set (match_operand:DI 0 "some_operand" "=&r")
479         (plus:DI (plus:DI (mult:DI (match_operand:DI 1 "some_operand" "rJ")
480                                    (match_operand:DI 2 "const48_operand" "I"))
481                           (match_operand:DI 3 "some_operand" "r"))
482                  (match_operand:DI 4 "some_operand" "rIOKL")))]
483   "reload_in_progress"
484   "#")
486 (define_split
487   [(set (match_operand:DI 0 "register_operand" "=")
488         (plus:DI (plus:DI (mult:DI (match_operand:DI 1 "reg_or_0_operand" "")
489                                    (match_operand:DI 2 "const48_operand" ""))
490                           (match_operand:DI 3 "register_operand" ""))
491                  (match_operand:DI 4 "add_operand" "")))]
492   "reload_completed"
493   [(set (match_dup 0)
494         (plus:DI (mult:DI (match_dup 1) (match_dup 2)) (match_dup 3)))
495    (set (match_dup 0) (plus:DI (match_dup 0) (match_dup 4)))]
496   "")
498 (define_insn "negsi2"
499   [(set (match_operand:SI 0 "register_operand" "=r")
500         (neg:SI (match_operand:SI 1 "reg_or_8bit_operand" "rI")))]
501   ""
502   "subl $31,%1,%0")
504 (define_insn ""
505   [(set (match_operand:DI 0 "register_operand" "=r")
506         (sign_extend:DI (neg:SI
507                          (match_operand:SI 1 "reg_or_8bit_operand" "rI"))))]
508   ""
509   "subl $31,%1,%0")
511 (define_insn "negdi2"
512   [(set (match_operand:DI 0 "register_operand" "=r")
513         (neg:DI (match_operand:DI 1 "reg_or_8bit_operand" "rI")))]
514   ""
515   "subq $31,%1,%0")
517 (define_expand "subsi3"
518   [(set (match_operand:SI 0 "register_operand" "")
519         (minus:SI (match_operand:SI 1 "reg_or_0_operand" "")
520                   (match_operand:SI 2 "reg_or_8bit_operand" "")))]
521   ""
522   "
523 { emit_insn (gen_rtx (SET, VOIDmode, gen_lowpart (DImode, operands[0]),
524                       gen_rtx (MINUS, DImode,
525                                gen_lowpart (DImode, operands[1]),
526                                gen_lowpart (DImode, operands[2]))));
527   DONE;
529 } ")
531 (define_insn ""
532   [(set (match_operand:SI 0 "register_operand" "=r")
533         (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rJ")
534                   (match_operand:SI 2 "reg_or_8bit_operand" "rI")))]
535   ""
536   "subl %r1,%2,%0")
538 (define_insn ""
539   [(set (match_operand:DI 0 "register_operand" "=r")
540         (sign_extend:DI (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rJ")
541                                   (match_operand:SI 2 "reg_or_8bit_operand" "rI"))))]
542   ""
543   "subl %r1,%2,%0")
545 (define_insn "subdi3"
546   [(set (match_operand:DI 0 "register_operand" "=r")
547         (minus:DI (match_operand:DI 1 "reg_or_0_operand" "rJ")
548                   (match_operand:DI 2 "reg_or_8bit_operand" "rI")))]
549   ""
550   "subq %r1,%2,%0")
552 (define_insn ""
553   [(set (match_operand:SI 0 "register_operand" "=r")
554         (minus:SI (mult:SI (match_operand:SI 1 "reg_or_0_operand" "rJ")
555                            (match_operand:SI 2 "const48_operand" "I"))
556                   (match_operand:SI 3 "reg_or_8bit_operand" "rI")))]
557   ""
558   "s%2subl %r1,%3,%0")
560 (define_insn ""
561   [(set (match_operand:DI 0 "register_operand" "=r")
562         (sign_extend:DI
563          (minus:SI (mult:SI (match_operand:SI 1 "reg_or_0_operand" "rJ")
564                             (match_operand:SI 2 "const48_operand" "I"))
565                    (match_operand:SI 3 "reg_or_8bit_operand" "rI"))))]
566   ""
567   "s%2subl %r1,%3,%0")
569 (define_insn ""
570   [(set (match_operand:DI 0 "register_operand" "=r")
571         (minus:DI (mult:DI (match_operand:DI 1 "reg_or_0_operand" "rJ")
572                            (match_operand:DI 2 "const48_operand" "I"))
573                   (match_operand:DI 3 "reg_or_8bit_operand" "rI")))]
574   ""
575   "s%2subq %r1,%3,%0")
577 (define_insn "mulsi3"
578   [(set (match_operand:SI 0 "register_operand" "=r")
579         (mult:SI (match_operand:SI 1 "reg_or_0_operand" "%rJ")
580                  (match_operand:SI 2 "reg_or_0_operand" "rJ")))]
581   ""
582   "mull %r1,%r2,%0"
583   [(set_attr "type" "imull")])
585 (define_insn ""
586   [(set (match_operand:DI 0 "register_operand" "=r")
587         (sign_extend:DI (mult:SI (match_operand:SI 1 "reg_or_0_operand" "%rJ")
588                                  (match_operand:SI 2 "reg_or_0_operand" "rJ"))))]
589   ""
590   "mull %r1,%r2,%0"
591   [(set_attr "type" "imull")])
593 (define_insn "muldi3"
594   [(set (match_operand:DI 0 "register_operand" "=r")
595         (mult:DI (match_operand:DI 1 "reg_or_0_operand" "%rJ")
596                  (match_operand:DI 2 "reg_or_0_operand" "rJ")))]
597   ""
598   "mulq %r1,%r2,%0"
599   [(set_attr "type" "imulq")])
601 (define_insn "umuldi3_highpart"
602   [(set (match_operand:DI 0 "register_operand" "=r")
603         (truncate:DI
604          (lshiftrt:TI
605           (mult:TI (zero_extend:TI (match_operand:DI 1 "register_operand" "r"))
606                    (zero_extend:TI (match_operand:DI 2 "register_operand" "r")))
607           (const_int 64))))]
608   ""
609   "umulh %1,%2,%0"
610   [(set_attr "type" "imulq")])
612 (define_insn ""
613   [(set (match_operand:DI 0 "register_operand" "=r")
614         (truncate:DI
615          (lshiftrt:TI
616           (mult:TI (zero_extend:TI (match_operand:DI 1 "register_operand" "r"))
617                    (match_operand:TI 2 "cint8_operand" "I"))
618           (const_int 64))))]
619   ""
620   "umulh %1,%2,%0"
621   [(set_attr "type" "imulq")])
623 ;; The divide and remainder operations always take their inputs from
624 ;; r24 and r25, put their output in r27, and clobber r23 and r28.
626 ;; ??? comment out the divsi routines since the library functions
627 ;; don't seem to do the right thing with the high 32-bits of a
628 ;; register nonzero.
630 ;(define_expand "divsi3"
631 ;  [(set (reg:SI 24) (match_operand:SI 1 "input_operand" ""))
632 ;   (set (reg:SI 25) (match_operand:SI 2 "input_operand" ""))
633 ;   (parallel [(set (reg:SI 27)
634 ;                  (div:SI (reg:SI 24)
635 ;                          (reg:SI 25)))
636 ;             (clobber (reg:DI 23))
637 ;             (clobber (reg:DI 28))])
638 ;   (set (match_operand:SI 0 "general_operand" "")
639 ;       (reg:SI 27))]
640 ;  "!TARGET_OPEN_VMS"
641 ;  "")
643 ;(define_expand "udivsi3"
644 ;  [(set (reg:SI 24) (match_operand:SI 1 "input_operand" ""))
645 ;   (set (reg:SI 25) (match_operand:SI 2 "input_operand" ""))
646 ;   (parallel [(set (reg:SI 27)
647 ;                  (udiv:SI (reg:SI 24)
648 ;                           (reg:SI 25)))
649 ;             (clobber (reg:DI 23))
650 ;             (clobber (reg:DI 28))])
651 ;   (set (match_operand:SI 0 "general_operand" "")
652 ;       (reg:SI 27))]
653 ;  "!TARGET_OPEN_VMS"
654 ;  "")
656 ;(define_expand "modsi3"
657 ;  [(set (reg:SI 24) (match_operand:SI 1 "input_operand" ""))
658 ;   (set (reg:SI 25) (match_operand:SI 2 "input_operand" ""))
659 ;   (parallel [(set (reg:SI 27)
660 ;                  (mod:SI (reg:SI 24)
661 ;                          (reg:SI 25)))
662 ;             (clobber (reg:DI 23))
663 ;             (clobber (reg:DI 28))])
664 ;   (set (match_operand:SI 0 "general_operand" "")
665 ;       (reg:SI 27))]
666 ;  "!TARGET_OPEN_VMS"
667 ;  "")
669 ;(define_expand "umodsi3"
670 ;  [(set (reg:SI 24) (match_operand:SI 1 "input_operand" ""))
671 ;   (set (reg:SI 25) (match_operand:SI 2 "input_operand" ""))
672 ;   (parallel [(set (reg:SI 27)
673 ;                  (umod:SI (reg:SI 24)
674 ;                           (reg:SI 25)))
675 ;             (clobber (reg:DI 23))
676 ;             (clobber (reg:DI 28))])
677 ;   (set (match_operand:SI 0 "general_operand" "")
678 ;       (reg:SI 27))]
679 ;  "!TARGET_OPEN_VMS"
680 ;  "")
682 (define_expand "divdi3"
683   [(set (reg:DI 24) (match_operand:DI 1 "input_operand" ""))
684    (set (reg:DI 25) (match_operand:DI 2 "input_operand" ""))
685    (parallel [(set (reg:DI 27)
686                    (div:DI (reg:DI 24)
687                            (reg:DI 25)))
688               (clobber (reg:DI 23))
689               (clobber (reg:DI 28))])
690    (set (match_operand:DI 0 "general_operand" "")
691         (reg:DI 27))]
692   "!TARGET_OPEN_VMS"
693   "")
695 (define_expand "udivdi3"
696   [(set (reg:DI 24) (match_operand:DI 1 "input_operand" ""))
697    (set (reg:DI 25) (match_operand:DI 2 "input_operand" ""))
698    (parallel [(set (reg:DI 27)
699                    (udiv:DI (reg:DI 24)
700                             (reg:DI 25)))
701               (clobber (reg:DI 23))
702               (clobber (reg:DI 28))])
703    (set (match_operand:DI 0 "general_operand" "")
704         (reg:DI 27))]
705   "!TARGET_OPEN_VMS"
706   "")
708 (define_expand "moddi3"
709   [(set (reg:DI 24) (match_operand:DI 1 "input_operand" ""))
710    (set (reg:DI 25) (match_operand:DI 2 "input_operand" ""))
711    (parallel [(set (reg:DI 27)
712                    (mod:DI (reg:DI 24)
713                            (reg:DI 25)))
714               (clobber (reg:DI 23))
715               (clobber (reg:DI 28))])
716    (set (match_operand:DI 0 "general_operand" "")
717         (reg:DI 27))]
718   "!TARGET_OPEN_VMS"
719   "")
721 (define_expand "umoddi3"
722   [(set (reg:DI 24) (match_operand:DI 1 "input_operand" ""))
723    (set (reg:DI 25) (match_operand:DI 2 "input_operand" ""))
724    (parallel [(set (reg:DI 27)
725                    (umod:DI (reg:DI 24)
726                             (reg:DI 25)))
727               (clobber (reg:DI 23))
728               (clobber (reg:DI 28))])
729    (set (match_operand:DI 0 "general_operand" "")
730         (reg:DI 27))]
731   "!TARGET_OPEN_VMS"
732   "")
734 ;(define_insn ""
735 ;  [(set (reg:SI 27)
736 ;       (match_operator:SI 1 "divmod_operator"
737 ;                       [(reg:SI 24) (reg:SI 25)]))
738 ;   (clobber (reg:DI 23))
739 ;   (clobber (reg:DI 28))]
740 ;  "!TARGET_OPEN_VMS"
741 ;  "%E1 $24,$25,$27"
742 ;  [(set_attr "type" "isubr")])
744 (define_insn ""
745   [(set (reg:DI 27)
746         (match_operator:DI 1 "divmod_operator"
747                         [(reg:DI 24) (reg:DI 25)]))
748    (clobber (reg:DI 23))
749    (clobber (reg:DI 28))]
750   "!TARGET_OPEN_VMS"
751   "%E1 $24,$25,$27"
752   [(set_attr "type" "isubr")])
754 ;; Next are the basic logical operations.  These only exist in DImode.
756 (define_insn "anddi3"
757   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
758         (and:DI (match_operand:DI 1 "reg_or_0_operand" "%rJ,rJ,rJ")
759                 (match_operand:DI 2 "and_operand" "rI,N,MH")))]
760   ""
761   "@
762    and %r1,%2,%0
763    bic %r1,%N2,%0
764    zapnot %r1,%m2,%0"
765   [(set_attr "type" "ilog,ilog,shift")])
767 ;; There are times when we can split an AND into two AND insns.  This occurs
768 ;; when we can first clear any bytes and then clear anything else.  For
769 ;; example "I & 0xffff07" is "(I & 0xffffff) & 0xffffffffffffff07".
770 ;; Only do this when running on 64-bit host since the computations are
771 ;; too messy otherwise.
773 (define_split
774   [(set (match_operand:DI 0 "register_operand" "")
775         (and:DI (match_operand:DI 1 "register_operand" "")
776                 (match_operand:DI 2 "const_int_operand" "")))]
777   "HOST_BITS_PER_WIDE_INT == 64 && ! and_operand (operands[2], DImode)"
778   [(set (match_dup 0) (and:DI (match_dup 1) (match_dup 3)))
779    (set (match_dup 0) (and:DI (match_dup 0) (match_dup 4)))]
780   "
782   unsigned HOST_WIDE_INT mask1 = INTVAL (operands[2]);
783   unsigned HOST_WIDE_INT mask2 = mask1;
784   int i;
786   /* For each byte that isn't all zeros, make it all ones.  */
787   for (i = 0; i < 64; i += 8)
788     if ((mask1 & ((HOST_WIDE_INT) 0xff << i)) != 0)
789       mask1 |= (HOST_WIDE_INT) 0xff << i;
791   /* Now turn on any bits we've just turned off.  */
792   mask2 |= ~ mask1;
794   operands[3] = GEN_INT (mask1);
795   operands[4] = GEN_INT (mask2);
798 (define_insn "zero_extendqihi2"
799   [(set (match_operand:HI 0 "register_operand" "=r")
800         (zero_extend:HI (match_operand:QI 1 "register_operand" "r")))]
801   ""
802   "zapnot %1,1,%0"
803   [(set_attr "type" "shift")])
805 (define_insn ""
806   [(set (match_operand:SI 0 "register_operand" "=r,r")
807         (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "r,m")))]
808   "TARGET_BWX"
809   "@
810    zapnot %1,1,%0
811    ldbu %0,%1"
812   [(set_attr "type" "shift,ld")])
814 (define_insn ""
815   [(set (match_operand:SI 0 "register_operand" "=r")
816         (zero_extend:SI (match_operand:QI 1 "register_operand" "r")))]
817   "! TARGET_BWX"
818   "zapnot %1,1,%0"
819   [(set_attr "type" "shift")])
821 (define_expand "zero_extendqisi2"
822   [(set (match_operand:SI 0 "register_operand" "")
823         (zero_extend:SI (match_operand:QI 1 "register_operand" "")))]
824   ""
825   "")
827 (define_insn ""
828   [(set (match_operand:DI 0 "register_operand" "=r,r")
829         (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand" "r,m")))]
830   "TARGET_BWX"
831   "@
832    zapnot %1,1,%0
833    ldbu %0,%1"
834   [(set_attr "type" "shift,ld")])
836 (define_insn ""
837   [(set (match_operand:DI 0 "register_operand" "=r")
838         (zero_extend:DI (match_operand:QI 1 "register_operand" "r")))]
839   "! TARGET_BWX"
840   "zapnot %1,1,%0"
841   [(set_attr "type" "shift")])
842   
843 (define_expand "zero_extendqidi2"
844   [(set (match_operand:DI 0 "register_operand" "")
845         (zero_extend:DI (match_operand:QI 1 "register_operand" "")))]
846   ""
847   "")
848   
849 (define_insn ""
850   [(set (match_operand:SI 0 "register_operand" "=r,r")
851         (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "r,m")))]
852   "TARGET_BWX"
853   "@
854    zapnot %1,3,%0
855    ldwu %0,%1"
856   [(set_attr "type" "shift,ld")])
858 (define_insn ""
859   [(set (match_operand:SI 0 "register_operand" "=r")
860         (zero_extend:SI (match_operand:HI 1 "register_operand" "r")))]
861   "! TARGET_BWX"
862   "zapnot %1,3,%0"
863   [(set_attr "type" "shift")])
865 (define_expand "zero_extendhisi2"
866   [(set (match_operand:SI 0 "register_operand" "")
867         (zero_extend:SI (match_operand:HI 1 "register_operand" "")))]
868   ""
869   "")
871 (define_insn ""
872   [(set (match_operand:DI 0 "register_operand" "=r,r")
873         (zero_extend:DI (match_operand:HI 1 "nonimmediate_operand" "r,m")))]
874   "TARGET_BWX"
875   "@
876    zapnot %1,3,%0
877    ldwu %0,%1"
878   [(set_attr "type" "shift,ld")])
880 (define_insn ""
881   [(set (match_operand:DI 0 "register_operand" "=r")
882         (zero_extend:DI (match_operand:HI 1 "register_operand" "r")))]
883   ""
884   "zapnot %1,3,%0"
885   [(set_attr "type" "shift")])
887 (define_expand "zero_extendhidi2"
888   [(set (match_operand:DI 0 "register_operand" "")
889         (zero_extend:DI (match_operand:HI 1 "register_operand" "")))]
890   ""
891   "")
893 (define_insn "zero_extendsidi2"
894   [(set (match_operand:DI 0 "register_operand" "=r")
895         (zero_extend:DI (match_operand:SI 1 "register_operand" "r")))]
896   ""
897   "zapnot %1,15,%0"
898   [(set_attr "type" "shift")])
900 (define_insn  ""
901   [(set (match_operand:DI 0 "register_operand" "=r")
902         (and:DI (not:DI (match_operand:DI 1 "reg_or_8bit_operand" "rI"))
903                 (match_operand:DI 2 "reg_or_0_operand" "rJ")))]
904   ""
905   "bic %r2,%1,%0"
906   [(set_attr "type" "ilog")])
908 (define_insn "iordi3"
909   [(set (match_operand:DI 0 "register_operand" "=r,r")
910         (ior:DI (match_operand:DI 1 "reg_or_0_operand" "%rJ,rJ")
911                 (match_operand:DI 2 "or_operand" "rI,N")))]
912   ""
913   "@
914    bis %r1,%2,%0
915    ornot %r1,%N2,%0"
916   [(set_attr "type" "ilog")])
918 (define_insn "one_cmpldi2"
919   [(set (match_operand:DI 0 "register_operand" "=r")
920         (not:DI (match_operand:DI 1 "reg_or_8bit_operand" "rI")))]
921   ""
922   "ornot $31,%1,%0"
923   [(set_attr "type" "ilog")])
925 (define_insn ""
926   [(set (match_operand:DI 0 "register_operand" "=r")
927         (ior:DI (not:DI (match_operand:DI 1 "reg_or_8bit_operand" "rI"))
928                 (match_operand:DI 2 "reg_or_0_operand" "rJ")))]
929   ""
930   "ornot %r2,%1,%0"
931   [(set_attr "type" "ilog")])
933 (define_insn "xordi3"
934   [(set (match_operand:DI 0 "register_operand" "=r,r")
935         (xor:DI (match_operand:DI 1 "reg_or_0_operand" "%rJ,rJ")
936                 (match_operand:DI 2 "or_operand" "rI,N")))]
937   ""
938   "@
939    xor %r1,%2,%0
940    eqv %r1,%N2,%0"
941   [(set_attr "type" "ilog")])
943 (define_insn ""
944   [(set (match_operand:DI 0 "register_operand" "=r")
945         (not:DI (xor:DI (match_operand:DI 1 "register_operand" "%rJ")
946                         (match_operand:DI 2 "register_operand" "rI"))))]
947   ""
948   "eqv %r1,%2,%0"
949   [(set_attr "type" "ilog")])
951 ;; Handle the FFS insn if we support CIX. 
953 (define_expand "ffsdi2"
954   [(set (match_dup 2)
955         (unspec [(match_operand:DI 1 "register_operand" "")] 1))
956    (set (match_dup 3)
957         (plus:DI (match_dup 2) (const_int 1)))
958    (set (match_operand:DI 0 "register_operand" "")
959         (if_then_else:DI (eq (match_dup 1) (const_int 0))
960                          (const_int 0) (match_dup 3)))]
961   "TARGET_CIX"
962   "
964   operands[2] = gen_reg_rtx (DImode);
965   operands[3] = gen_reg_rtx (DImode);
968 (define_insn ""
969   [(set (match_operand:DI 0 "register_operand" "=r")
970         (unspec [(match_operand:DI 1 "register_operand" "r")] 1))]
971   "TARGET_CIX"
972   "cttz %1,%0"
973   [(set_attr "type" "shift")])
975 ;; Next come the shifts and the various extract and insert operations.
977 (define_insn "ashldi3"
978   [(set (match_operand:DI 0 "register_operand" "=r,r")
979         (ashift:DI (match_operand:DI 1 "reg_or_0_operand" "rJ,rJ")
980                    (match_operand:DI 2 "reg_or_6bit_operand" "P,rI")))]
981   ""
982   "*
984   switch (which_alternative)
985     {
986     case 0:
987       if (operands[2] == const1_rtx)
988         return \"addq %r1,%r1,%0\";
989       else
990         return \"s%P2addq %r1,0,%0\";
991     case 1:
992       return \"sll %r1,%2,%0\";
993     }
995   [(set_attr "type" "iadd,shift")])
997 ;; ??? The following pattern is made by combine, but earlier phases
998 ;; (specifically flow) can't handle it.  This occurs in jump.c.  Deal
999 ;; with this in a better way at some point.
1000 ;;(define_insn ""
1001 ;;  [(set (match_operand:DI 0 "register_operand" "=r")
1002 ;;      (sign_extend:DI
1003 ;;       (subreg:SI (ashift:DI (match_operand:DI 1 "reg_or_0_operand" "rJ")
1004 ;;                             (match_operand:DI 2 "const_int_operand" "P"))
1005 ;;                  0)))]
1006 ;;  "INTVAL (operands[2]) >= 1 && INTVAL (operands[2]) <= 3"
1007 ;;  "*
1009 ;;  if (operands[2] == const1_rtx)
1010 ;;    return \"addl %r1,%r1,%0\";
1011 ;;  else
1012 ;;    return \"s%P2addl %r1,0,%0\";
1013 ;; }"
1014 ;;  [(set_attr "type" "iadd")])
1015                           
1016 (define_insn "lshrdi3"
1017   [(set (match_operand:DI 0 "register_operand" "=r")
1018         (lshiftrt:DI (match_operand:DI 1 "reg_or_0_operand" "rJ")
1019                      (match_operand:DI 2 "reg_or_6bit_operand" "rI")))]
1020   ""
1021   "srl %r1,%2,%0"
1022   [(set_attr "type" "shift")])
1024 (define_insn "ashrdi3"
1025   [(set (match_operand:DI 0 "register_operand" "=r")
1026         (ashiftrt:DI (match_operand:DI 1 "reg_or_0_operand" "rJ")
1027                      (match_operand:DI 2 "reg_or_6bit_operand" "rI")))]
1028   ""
1029   "sra %r1,%2,%0"
1030   [(set_attr "type" "shift")])
1032 (define_expand "extendqihi2"
1033   [(set (match_dup 2)
1034         (ashift:DI (match_operand:QI 1 "some_operand" "")
1035                    (const_int 56)))
1036    (set (match_operand:HI 0 "register_operand" "")
1037         (ashiftrt:DI (match_dup 2)
1038                      (const_int 56)))]
1039   ""
1040   "
1042   if (TARGET_BWX)
1043     {
1044       emit_insn (gen_extendqihi2x (operands[0],
1045                                    force_reg (QImode, operands[1])));
1046       DONE;
1047     }
1049  /* If we have an unaligned MEM, extend to DImode (which we do
1050      specially) and then copy to the result.  */
1051   if (unaligned_memory_operand (operands[1], HImode))
1052     {
1053       rtx temp = gen_reg_rtx (DImode);
1055       emit_insn (gen_extendqidi2 (temp, operands[1]));
1056       emit_move_insn (operands[0], gen_lowpart (HImode, temp));
1057       DONE;
1058     }
1060   operands[0] = gen_lowpart (DImode, operands[0]);
1061   operands[1] = gen_lowpart (DImode, force_reg (QImode, operands[1]));
1062   operands[2] = gen_reg_rtx (DImode);
1065 (define_insn "extendqidi2x"
1066   [(set (match_operand:DI 0 "register_operand" "=r")
1067         (sign_extend:DI (match_operand:QI 1 "register_operand" "r")))]
1068   "TARGET_BWX"
1069   "sextb %1,%0"
1070   [(set_attr "type" "shift")])
1072 (define_insn "extendhidi2x"
1073   [(set (match_operand:DI 0 "register_operand" "=r")
1074         (sign_extend:DI (match_operand:HI 1 "register_operand" "r")))]
1075   "TARGET_BWX"
1076   "sextw %1,%0"
1077   [(set_attr "type" "shift")])
1079 (define_insn "extendqisi2x"
1080   [(set (match_operand:SI 0 "register_operand" "=r")
1081         (sign_extend:SI (match_operand:QI 1 "register_operand" "r")))]
1082   "TARGET_BWX"
1083   "sextb %1,%0"
1084   [(set_attr "type" "shift")])
1086 (define_insn "extendhisi2x"
1087   [(set (match_operand:SI 0 "register_operand" "=r")
1088         (sign_extend:SI (match_operand:HI 1 "register_operand" "r")))]
1089   "TARGET_BWX"
1090   "sextw %1,%0"
1091   [(set_attr "type" "shift")])
1093 (define_insn "extendqihi2x"
1094   [(set (match_operand:HI 0 "register_operand" "=r")
1095         (sign_extend:HI (match_operand:QI 1 "register_operand" "r")))]
1096   "TARGET_BWX"
1097   "sextb %1,%0"
1098   [(set_attr "type" "shift")])
1100 (define_expand "extendqisi2"
1101   [(set (match_dup 2)
1102         (ashift:DI (match_operand:QI 1 "some_operand" "")
1103                    (const_int 56)))
1104    (set (match_operand:SI 0 "register_operand" "")
1105         (ashiftrt:DI (match_dup 2)
1106                      (const_int 56)))]
1107   ""
1108   "
1110   if (TARGET_BWX)
1111     {
1112       emit_insn (gen_extendqisi2x (operands[0],
1113                                    force_reg (QImode, operands[1])));
1114       DONE;
1115     }
1117   /* If we have an unaligned MEM, extend to a DImode form of
1118      the result (which we do specially).  */
1119   if (unaligned_memory_operand (operands[1], QImode))
1120     {
1121       rtx temp = gen_reg_rtx (DImode);
1123       emit_insn (gen_extendqidi2 (temp, operands[1]));
1124       emit_move_insn (operands[0], gen_lowpart (SImode, temp));
1125       DONE;
1126     }
1128   operands[0] = gen_lowpart (DImode, operands[0]);
1129   operands[1] = gen_lowpart (DImode, force_reg (QImode, operands[1]));
1130   operands[2] = gen_reg_rtx (DImode);
1133 (define_expand "extendqidi2"
1134   [(set (match_dup 2)
1135         (ashift:DI (match_operand:QI 1 "some_operand" "")
1136                    (const_int 56)))
1137    (set (match_operand:DI 0 "register_operand" "")
1138         (ashiftrt:DI (match_dup 2)
1139                      (const_int 56)))]
1140   ""
1141   "
1142 { extern rtx get_unaligned_address ();
1144   if (TARGET_BWX)
1145     {
1146       emit_insn (gen_extendqidi2x (operands[0],
1147                                    force_reg (QImode, operands[1])));
1148       DONE;
1149     }
1151   if (unaligned_memory_operand (operands[1], QImode))
1152     {
1153       rtx seq
1154         = gen_unaligned_extendqidi (operands[0],
1155                                     get_unaligned_address (operands[1], 1));
1157       alpha_set_memflags (seq, operands[1]);
1158       emit_insn (seq);
1159       DONE;
1160     }
1162   operands[1] = gen_lowpart (DImode, force_reg (QImode, operands[1]));
1163   operands[2] = gen_reg_rtx (DImode);
1166 (define_expand "extendhisi2"
1167   [(set (match_dup 2)
1168         (ashift:DI (match_operand:HI 1 "some_operand" "")
1169                    (const_int 48)))
1170    (set (match_operand:SI 0 "register_operand" "")
1171         (ashiftrt:DI (match_dup 2)
1172                      (const_int 48)))]
1173   ""
1174   "
1176   if (TARGET_BWX)
1177     {
1178       emit_insn (gen_extendhisi2x (operands[0],
1179                                    force_reg (HImode, operands[1])));
1180       DONE;
1181     }
1183   /* If we have an unaligned MEM, extend to a DImode form of
1184      the result (which we do specially).  */
1185   if (unaligned_memory_operand (operands[1], HImode))
1186     {
1187       rtx temp = gen_reg_rtx (DImode);
1189       emit_insn (gen_extendhidi2 (temp, operands[1]));
1190       emit_move_insn (operands[0], gen_lowpart (SImode, temp));
1191       DONE;
1192     }
1194   operands[0] = gen_lowpart (DImode, operands[0]);
1195   operands[1] = gen_lowpart (DImode, force_reg (HImode, operands[1]));
1196   operands[2] = gen_reg_rtx (DImode);
1199 (define_expand "extendhidi2"
1200   [(set (match_dup 2)
1201         (ashift:DI (match_operand:HI 1 "some_operand" "")
1202                    (const_int 48)))
1203    (set (match_operand:DI 0 "register_operand" "")
1204         (ashiftrt:DI (match_dup 2)
1205                      (const_int 48)))]
1206   ""
1207   "
1208 { extern rtx get_unaligned_address ();
1210   if (TARGET_BWX)
1211     {
1212       emit_insn (gen_extendhidi2x (operands[0],
1213                                    force_reg (HImode, operands[1])));
1214       DONE;
1215     }
1217   if (unaligned_memory_operand (operands[1], HImode))
1218     {
1219       rtx seq
1220         = gen_unaligned_extendhidi (operands[0],
1221                                     get_unaligned_address (operands[1], 2));
1223       alpha_set_memflags (seq, operands[1]);
1224       emit_insn (seq);
1225       DONE;
1226     }
1228   operands[1] = gen_lowpart (DImode, force_reg (HImode, operands[1]));
1229   operands[2] = gen_reg_rtx (DImode);
1232 ;; Here's how we sign extend an unaligned byte and halfword.  Doing this
1233 ;; as a pattern saves one instruction.  The code is similar to that for
1234 ;; the unaligned loads (see below).
1236 ;; Operand 1 is the address + 1 (+2 for HI), operand 0 is the result.
1237 (define_expand "unaligned_extendqidi"
1238   [(set (match_dup 2) (match_operand:DI 1 "address_operand" ""))
1239    (set (match_dup 3)
1240         (mem:DI (and:DI (plus:DI (match_dup 2) (const_int -1))
1241                         (const_int -8))))
1242    (set (match_dup 4)
1243         (ashift:DI (match_dup 3)
1244                    (minus:DI (const_int 56)
1245                              (ashift:DI
1246                               (and:DI (plus:DI (match_dup 2) (const_int -1))
1247                                       (const_int 7))
1248                               (const_int 3)))))
1249    (set (subreg:DI (match_operand:QI 0 "register_operand" "") 0)
1250         (ashiftrt:DI (match_dup 4) (const_int 56)))]
1251   ""
1252   "
1253 { operands[2] = gen_reg_rtx (DImode);
1254   operands[3] = gen_reg_rtx (DImode);
1255   operands[4] = gen_reg_rtx (DImode);
1258 (define_expand "unaligned_extendhidi"
1259   [(set (match_dup 2) (match_operand:DI 1 "address_operand" ""))
1260    (set (match_dup 3)
1261         (mem:DI (and:DI (plus:DI (match_dup 2) (const_int -2))
1262                         (const_int -8))))
1263    (set (match_dup 4)
1264         (ashift:DI (match_dup 3)
1265                    (minus:DI (const_int 56)
1266                              (ashift:DI
1267                               (and:DI (plus:DI (match_dup 2) (const_int -1))
1268                                       (const_int 7))
1269                               (const_int 3)))))
1270    (set (subreg:DI (match_operand:QI 0 "register_operand" "") 0)
1271         (ashiftrt:DI (match_dup 4) (const_int 48)))]
1272   ""
1273   "
1274 { operands[2] = gen_reg_rtx (DImode);
1275   operands[3] = gen_reg_rtx (DImode);
1276   operands[4] = gen_reg_rtx (DImode);
1279 (define_insn ""
1280   [(set (match_operand:DI 0 "register_operand" "=r")
1281         (zero_extract:DI (match_operand:DI 1 "reg_or_0_operand" "rJ")
1282                          (match_operand:DI 2 "mode_width_operand" "n")
1283                          (match_operand:DI 3 "mul8_operand" "I")))]
1284   ""
1285   "ext%M2l %r1,%s3,%0"
1286   [(set_attr "type" "shift")])
1288 (define_insn ""
1289   [(set (match_operand:DI 0 "register_operand" "=r")
1290         (zero_extract:DI (match_operand:DI 1 "reg_or_0_operand" "rJ")
1291                          (match_operand:DI 2 "mode_width_operand" "n")
1292                          (ashift:DI (match_operand:DI 3 "reg_or_8bit_operand" "rI")
1293                                     (const_int 3))))]
1294   ""
1295   "ext%M2l %r1,%3,%0"
1296   [(set_attr "type" "shift")])
1298 (define_insn ""
1299   [(set (match_operand:DI 0 "register_operand" "=r")
1300         (ashift:DI
1301          (match_operand:DI 1 "reg_or_0_operand" "rJ")
1302           (minus:DI (const_int 56)
1303                     (ashift:DI
1304                      (and:DI
1305                       (plus:DI (match_operand:DI 2 "reg_or_8bit_operand" "rI")
1306                                (const_int -1))
1307                       (const_int 7))
1308                      (const_int 3)))))]
1309   ""
1310   "extqh %r1,%2,%0"
1311   [(set_attr "type" "shift")])
1313 (define_insn ""
1314   [(set (match_operand:DI 0 "register_operand" "=r")
1315         (ashift:DI
1316          (and:DI (match_operand:DI 1 "reg_or_0_operand" "rJ")
1317                  (const_int 2147483647))
1318          (minus:DI (const_int 56)
1319                     (ashift:DI
1320                      (and:DI
1321                       (plus:DI (match_operand:DI 2 "reg_or_8bit_operand" "rI")
1322                                (const_int -1))
1323                       (const_int 7))
1324                      (const_int 3)))))]
1325   ""
1326   "extlh %r1,%2,%0"
1327   [(set_attr "type" "shift")])
1329 (define_insn ""
1330   [(set (match_operand:DI 0 "register_operand" "=r")
1331         (ashift:DI
1332          (and:DI (match_operand:DI 1 "reg_or_0_operand" "rJ")
1333                  (const_int 65535))
1334          (minus:DI (const_int 56)
1335                     (ashift:DI
1336                      (and:DI
1337                       (plus:DI (match_operand:DI 2 "reg_or_8bit_operand" "rI")
1338                                (const_int -1))
1339                       (const_int 7))
1340                      (const_int 3)))))]
1341   ""
1342   "extwh %r1,%2,%0"
1343   [(set_attr "type" "shift")])
1345 ;; This converts an extXl into an extXh with an appropriate adjustment
1346 ;; to the address calculation.
1348 ;;(define_split
1349 ;;  [(set (match_operand:DI 0 "register_operand" "")
1350 ;;      (ashift:DI (zero_extract:DI (match_operand:DI 1 "register_operand" "")
1351 ;;                                  (match_operand:DI 2 "mode_width_operand" "")
1352 ;;                                  (ashift:DI (match_operand:DI 3 "" "")
1353 ;;                                             (const_int 3)))
1354 ;;                 (match_operand:DI 4 "const_int_operand" "")))
1355 ;;   (clobber (match_operand:DI 5 "register_operand" ""))]
1356 ;;  "INTVAL (operands[4]) == 64 - INTVAL (operands[2])"
1357 ;;  [(set (match_dup 5) (match_dup 6))
1358 ;;   (set (match_dup 0)
1359 ;;      (ashift:DI (zero_extract:DI (match_dup 1) (match_dup 2)
1360 ;;                                  (ashift:DI (plus:DI (match_dup 5)
1361 ;;                                                      (match_dup 7))
1362 ;;                                             (const_int 3)))
1363 ;;                 (match_dup 4)))]
1364 ;;  "
1366 ;;  operands[6] = plus_constant (operands[3], 
1367 ;;                             INTVAL (operands[2]) / BITS_PER_UNIT);
1368 ;;  operands[7] = GEN_INT (- INTVAL (operands[2]) / BITS_PER_UNIT);
1369 ;;}")
1370   
1371 (define_insn ""
1372   [(set (match_operand:DI 0 "register_operand" "=r")
1373         (ashift:DI (zero_extend:DI (match_operand:QI 1 "register_operand" "r"))
1374                    (match_operand:DI 2 "mul8_operand" "I")))]
1375   ""
1376   "insbl %1,%s2,%0"
1377   [(set_attr "type" "shift")])
1379 (define_insn ""
1380   [(set (match_operand:DI 0 "register_operand" "=r")
1381         (ashift:DI (zero_extend:DI (match_operand:HI 1 "register_operand" "r"))
1382                    (match_operand:DI 2 "mul8_operand" "I")))]
1383   ""
1384   "inswl %1,%s2,%0"
1385   [(set_attr "type" "shift")])
1387 (define_insn ""
1388   [(set (match_operand:DI 0 "register_operand" "=r")
1389         (ashift:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
1390                    (match_operand:DI 2 "mul8_operand" "I")))]
1391   ""
1392   "insll %1,%s2,%0"
1393   [(set_attr "type" "shift")])
1395 (define_insn ""
1396   [(set (match_operand:DI 0 "register_operand" "=r")
1397         (ashift:DI (zero_extend:DI (match_operand:QI 1 "register_operand" "r"))
1398                    (ashift:DI (match_operand:DI 2 "reg_or_8bit_operand" "rI")
1399                               (const_int 3))))]
1400   ""
1401   "insbl %1,%2,%0"
1402   [(set_attr "type" "shift")])
1404 (define_insn ""
1405   [(set (match_operand:DI 0 "register_operand" "=r")
1406         (ashift:DI (zero_extend:DI (match_operand:HI 1 "register_operand" "r"))
1407                    (ashift:DI (match_operand:DI 2 "reg_or_8bit_operand" "rI")
1408                               (const_int 3))))]
1409   ""
1410   "inswl %1,%2,%0"
1411   [(set_attr "type" "shift")])
1413 (define_insn ""
1414   [(set (match_operand:DI 0 "register_operand" "=r")
1415         (ashift:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
1416                    (ashift:DI (match_operand:DI 2 "reg_or_8bit_operand" "rI")
1417                               (const_int 3))))]
1418   ""
1419   "insll %1,%2,%0"
1420   [(set_attr "type" "shift")])
1422 ;; We do not include the insXh insns because they are complex to express
1423 ;; and it does not appear that we would ever want to generate them.
1425 (define_insn ""
1426   [(set (match_operand:DI 0 "register_operand" "=r")
1427         (and:DI (not:DI (ashift:DI
1428                          (match_operand:DI 2 "mode_mask_operand" "n")
1429                          (ashift:DI
1430                           (match_operand:DI 3 "reg_or_8bit_operand" "rI")
1431                           (const_int 3))))
1432                 (match_operand:DI 1 "reg_or_0_operand" "rJ")))]
1433   ""
1434   "msk%U2l %r1,%3,%0"
1435   [(set_attr "type" "shift")])
1437 ;; We do not include the mskXh insns because it does not appear we would ever
1438 ;; generate one.
1440 ;; Floating-point operations.  All the double-precision insns can extend
1441 ;; from single, so indicate that.  The exception are the ones that simply
1442 ;; play with the sign bits; it's not clear what to do there.
1444 (define_insn "abssf2"
1445   [(set (match_operand:SF 0 "register_operand" "=f")
1446         (abs:SF (match_operand:SF 1 "reg_or_fp0_operand" "fG")))]
1447   "TARGET_FP"
1448   "cpys $f31,%R1,%0"
1449   [(set_attr "type" "fcpys")])
1451 (define_insn "absdf2"
1452   [(set (match_operand:DF 0 "register_operand" "=f")
1453         (abs:DF (match_operand:DF 1 "reg_or_fp0_operand" "fG")))]
1454   "TARGET_FP"
1455   "cpys $f31,%R1,%0"
1456   [(set_attr "type" "fcpys")])
1458 (define_insn "negsf2"
1459   [(set (match_operand:SF 0 "register_operand" "=f")
1460         (neg:SF (match_operand:SF 1 "reg_or_fp0_operand" "fG")))]
1461   "TARGET_FP"
1462   "cpysn %R1,%R1,%0"
1463   [(set_attr "type" "fadd")])
1465 (define_insn "negdf2"
1466   [(set (match_operand:DF 0 "register_operand" "=f")
1467         (neg:DF (match_operand:DF 1 "reg_or_fp0_operand" "fG")))]
1468   "TARGET_FP"
1469   "cpysn %R1,%R1,%0"
1470   [(set_attr "type" "fadd")])
1472 (define_insn ""
1473   [(set (match_operand:SF 0 "register_operand" "=&f")
1474         (plus:SF (match_operand:SF 1 "reg_or_fp0_operand" "%fG")
1475                  (match_operand:SF 2 "reg_or_fp0_operand" "fG")))]
1476   "TARGET_FP && alpha_tp == ALPHA_TP_INSN"
1477   "add%,%)%& %R1,%R2,%0"
1478   [(set_attr "type" "fadd")
1479    (set_attr "trap" "yes")])
1481 (define_insn "addsf3"
1482   [(set (match_operand:SF 0 "register_operand" "=f")
1483         (plus:SF (match_operand:SF 1 "reg_or_fp0_operand" "%fG")
1484                  (match_operand:SF 2 "reg_or_fp0_operand" "fG")))]
1485   "TARGET_FP"
1486   "add%,%)%& %R1,%R2,%0"
1487   [(set_attr "type" "fadd")
1488    (set_attr "trap" "yes")])
1490 (define_insn ""
1491   [(set (match_operand:DF 0 "register_operand" "=&f")
1492         (plus:DF (match_operand:DF 1 "reg_or_fp0_operand" "%fG")
1493                  (match_operand:DF 2 "reg_or_fp0_operand" "fG")))]
1494   "TARGET_FP && alpha_tp == ALPHA_TP_INSN"
1495   "add%-%)%& %R1,%R2,%0"
1496   [(set_attr "type" "fadd")
1497    (set_attr "trap" "yes")])
1499 (define_insn "adddf3"
1500   [(set (match_operand:DF 0 "register_operand" "=f")
1501         (plus:DF (match_operand:DF 1 "reg_or_fp0_operand" "%fG")
1502                  (match_operand:DF 2 "reg_or_fp0_operand" "fG")))]
1503   "TARGET_FP"
1504   "add%-%)%& %R1,%R2,%0"
1505   [(set_attr "type" "fadd")
1506    (set_attr "trap" "yes")])
1508 (define_insn ""
1509   [(set (match_operand:DF 0 "register_operand" "=f")
1510         (plus:DF (float_extend:DF
1511                   (match_operand:SF 1 "reg_or_fp0_operand" "fG"))
1512                  (match_operand:DF 2 "reg_or_fp0_operand" "fG")))]
1513   "TARGET_FP && alpha_tp != ALPHA_TP_INSN"
1514   "add%-%)%& %R1,%R2,%0"
1515   [(set_attr "type" "fadd")
1516    (set_attr "trap" "yes")])
1518 (define_insn ""
1519   [(set (match_operand:DF 0 "register_operand" "=f")
1520         (plus:DF (float_extend:DF
1521                   (match_operand:SF 1 "reg_or_fp0_operand" "%fG"))
1522                  (float_extend:DF
1523                   (match_operand:SF 2 "reg_or_fp0_operand" "fG"))))]
1524   "TARGET_FP && alpha_tp != ALPHA_TP_INSN"
1525   "add%-%)%& %R1,%R2,%0"
1526   [(set_attr "type" "fadd")
1527    (set_attr "trap" "yes")])
1529 (define_insn "fix_truncdfdi2"
1530   [(set (match_operand:DI 0 "register_operand" "=f")
1531         (fix:DI (match_operand:DF 1 "reg_or_fp0_operand" "fG")))]
1532   "TARGET_FP"
1533   "cvt%-qc %R1,%0"
1534   [(set_attr "type" "fadd")])
1536 (define_insn "fix_truncsfdi2"
1537   [(set (match_operand:DI 0 "register_operand" "=f")
1538         (fix:DI (float_extend:DF
1539                  (match_operand:SF 1 "reg_or_fp0_operand" "fG"))))]
1540   "TARGET_FP"
1541   "cvt%-qc %R1,%0"
1542   [(set_attr "type" "fadd")])
1544 (define_insn "floatdisf2"
1545   [(set (match_operand:SF 0 "register_operand" "=f")
1546         (float:SF (match_operand:DI 1 "register_operand" "f")))]
1547   "TARGET_FP"
1548   "cvtq%,%+%& %1,%0"
1549   [(set_attr "type" "fadd")
1550    (set_attr "trap" "yes")])
1552 (define_insn ""
1553   [(set (match_operand:DF 0 "register_operand" "=&f")
1554         (float:DF (match_operand:DI 1 "register_operand" "f")))]
1555   "TARGET_FP && alpha_tp == ALPHA_TP_INSN"
1556   "cvtq%-%+%& %1,%0"
1557   [(set_attr "type" "fadd")
1558    (set_attr "trap" "yes")])
1560 (define_insn "floatdidf2"
1561   [(set (match_operand:DF 0 "register_operand" "=f")
1562         (float:DF (match_operand:DI 1 "register_operand" "f")))]
1563   "TARGET_FP"
1564   "cvtq%-%+%& %1,%0"
1565   [(set_attr "type" "fadd")
1566    (set_attr "trap" "yes")])
1568 (define_expand "extendsfdf2"
1569   [(use (match_operand:DF 0 "register_operand" ""))
1570    (use (match_operand:SF 1 "nonimmediate_operand" ""))]
1571   "TARGET_FP"
1574   if (alpha_tp == ALPHA_TP_INSN)
1575     emit_insn (gen_extendsfdf2_tp (operands[0],
1576                                    force_reg (SFmode, operands[1])));
1577   else
1578     emit_insn (gen_extendsfdf2_no_tp (operands[0], operands[1]));
1580   DONE;
1582 ;; FIXME
1583 (define_insn "extendsfdf2_tp"
1584   [(set (match_operand:DF 0 "register_operand" "=&f")
1585         (float_extend:DF (match_operand:SF 1 "register_operand" "f")))]
1586   "TARGET_FP && alpha_tp == ALPHA_TP_INSN"
1587   "cvtsts %1,%0"
1588   [(set_attr "type" "fadd")
1589    (set_attr "trap" "yes")])
1591 (define_insn "extendsfdf2_no_tp"
1592   [(set (match_operand:DF 0 "register_operand" "=f,f,m")
1593         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "f,m,f")))]
1594   "TARGET_FP && alpha_tp != ALPHA_TP_INSN"
1595   "@
1596    cpys %1,%1,%0
1597    ld%, %0,%1
1598    st%- %1,%0"
1599   [(set_attr "type" "fcpys,ld,st")
1600    (set_attr "trap" "yes")])
1602 (define_insn ""
1603   [(set (match_operand:SF 0 "register_operand" "=&f")
1604         (float_truncate:SF (match_operand:DF 1 "reg_or_fp0_operand" "fG")))]
1605   "TARGET_FP && alpha_tp == ALPHA_TP_INSN"
1606   "cvt%-%,%)%& %R1,%0"
1607   [(set_attr "type" "fadd")
1608    (set_attr "trap" "yes")])
1610 (define_insn "truncdfsf2"
1611   [(set (match_operand:SF 0 "register_operand" "=f")
1612         (float_truncate:SF (match_operand:DF 1 "reg_or_fp0_operand" "fG")))]
1613   "TARGET_FP"
1614   "cvt%-%,%)%& %R1,%0"
1615   [(set_attr "type" "fadd")
1616    (set_attr "trap" "yes")])
1618 (define_insn ""
1619   [(set (match_operand:SF 0 "register_operand" "=&f")
1620         (div:SF (match_operand:SF 1 "reg_or_fp0_operand" "fG")
1621                 (match_operand:SF 2 "reg_or_fp0_operand" "fG")))]
1622   "TARGET_FP && alpha_tp == ALPHA_TP_INSN"
1623   "div%,%)%& %R1,%R2,%0"
1624   [(set_attr "type" "fdivs")
1625    (set_attr "trap" "yes")])
1627 (define_insn "divsf3"
1628   [(set (match_operand:SF 0 "register_operand" "=f")
1629         (div:SF (match_operand:SF 1 "reg_or_fp0_operand" "fG")
1630                 (match_operand:SF 2 "reg_or_fp0_operand" "fG")))]
1631   "TARGET_FP"
1632   "div%,%)%& %R1,%R2,%0"
1633   [(set_attr "type" "fdivs")
1634    (set_attr "trap" "yes")])
1636 (define_insn ""
1637   [(set (match_operand:DF 0 "register_operand" "=&f")
1638         (div:DF (match_operand:DF 1 "reg_or_fp0_operand" "fG")
1639                 (match_operand:DF 2 "reg_or_fp0_operand" "fG")))]
1640   "TARGET_FP && alpha_tp == ALPHA_TP_INSN"
1641   "div%-%)%& %R1,%R2,%0"
1642   [(set_attr "type" "fdivt")
1643    (set_attr "trap" "yes")])
1645 (define_insn "divdf3"
1646   [(set (match_operand:DF 0 "register_operand" "=f")
1647         (div:DF (match_operand:DF 1 "reg_or_fp0_operand" "fG")
1648                 (match_operand:DF 2 "reg_or_fp0_operand" "fG")))]
1649   "TARGET_FP"
1650   "div%-%)%& %R1,%R2,%0"
1651   [(set_attr "type" "fdivt")
1652    (set_attr "trap" "yes")])
1654 (define_insn ""
1655   [(set (match_operand:DF 0 "register_operand" "=f")
1656         (div:DF (float_extend:DF (match_operand:SF 1 "reg_or_fp0_operand" "fG"))
1657                 (match_operand:DF 2 "reg_or_fp0_operand" "fG")))]
1658   "TARGET_FP && alpha_tp != ALPHA_TP_INSN"
1659   "div%-%)%& %R1,%R2,%0"
1660   [(set_attr "type" "fdivt")
1661    (set_attr "trap" "yes")])
1663 (define_insn ""
1664   [(set (match_operand:DF 0 "register_operand" "=f")
1665         (div:DF (match_operand:DF 1 "reg_or_fp0_operand" "fG")
1666                 (float_extend:DF
1667                  (match_operand:SF 2 "reg_or_fp0_operand" "fG"))))]
1668   "TARGET_FP && alpha_tp != ALPHA_TP_INSN"
1669   "div%-%)%& %R1,%R2,%0"
1670   [(set_attr "type" "fdivt")
1671    (set_attr "trap" "yes")])
1673 (define_insn ""
1674   [(set (match_operand:DF 0 "register_operand" "=f")
1675         (div:DF (float_extend:DF (match_operand:SF 1 "reg_or_fp0_operand" "fG"))
1676                 (float_extend:DF (match_operand:SF 2 "reg_or_fp0_operand" "fG"))))]
1677   "TARGET_FP && alpha_tp != ALPHA_TP_INSN"
1678   "div%-%)%& %R1,%R2,%0"
1679   [(set_attr "type" "fdivt")
1680    (set_attr "trap" "yes")])
1682 (define_insn ""
1683   [(set (match_operand:SF 0 "register_operand" "=&f")
1684         (mult:SF (match_operand:SF 1 "reg_or_fp0_operand" "%fG")
1685                  (match_operand:SF 2 "reg_or_fp0_operand" "fG")))]
1686   "TARGET_FP && alpha_tp == ALPHA_TP_INSN"
1687   "mul%,%)%& %R1,%R2,%0"
1688   [(set_attr "type" "fmul")
1689    (set_attr "trap" "yes")])
1691 (define_insn "mulsf3"
1692   [(set (match_operand:SF 0 "register_operand" "=f")
1693         (mult:SF (match_operand:SF 1 "reg_or_fp0_operand" "%fG")
1694                  (match_operand:SF 2 "reg_or_fp0_operand" "fG")))]
1695   "TARGET_FP"
1696   "mul%,%)%& %R1,%R2,%0"
1697   [(set_attr "type" "fmul")
1698    (set_attr "trap" "yes")])
1700 (define_insn ""
1701   [(set (match_operand:DF 0 "register_operand" "=&f")
1702         (mult:DF (match_operand:DF 1 "reg_or_fp0_operand" "%fG")
1703                  (match_operand:DF 2 "reg_or_fp0_operand" "fG")))]
1704   "TARGET_FP && alpha_tp == ALPHA_TP_INSN"
1705   "mul%-%)%& %R1,%R2,%0"
1706   [(set_attr "type" "fmul")
1707    (set_attr "trap" "yes")])
1709 (define_insn "muldf3"
1710   [(set (match_operand:DF 0 "register_operand" "=f")
1711         (mult:DF (match_operand:DF 1 "reg_or_fp0_operand" "%fG")
1712                  (match_operand:DF 2 "reg_or_fp0_operand" "fG")))]
1713   "TARGET_FP"
1714   "mul%-%)%& %R1,%R2,%0"
1715   [(set_attr "type" "fmul")
1716    (set_attr "trap" "yes")])
1718 (define_insn ""
1719   [(set (match_operand:DF 0 "register_operand" "=f")
1720         (mult:DF (float_extend:DF
1721                   (match_operand:SF 1 "reg_or_fp0_operand" "fG"))
1722                  (match_operand:DF 2 "reg_or_fp0_operand" "fG")))]
1723   "TARGET_FP && alpha_tp != ALPHA_TP_INSN"
1724   "mul%-%)%& %R1,%R2,%0"
1725   [(set_attr "type" "fmul")
1726    (set_attr "trap" "yes")])
1728 (define_insn ""
1729   [(set (match_operand:DF 0 "register_operand" "=f")
1730         (mult:DF (float_extend:DF
1731                   (match_operand:SF 1 "reg_or_fp0_operand" "%fG"))
1732                  (float_extend:DF
1733                   (match_operand:SF 2 "reg_or_fp0_operand" "fG"))))]
1734   "TARGET_FP && alpha_tp != ALPHA_TP_INSN"
1735   "mul%-%)%& %R1,%R2,%0"
1736   [(set_attr "type" "fmul")
1737    (set_attr "trap" "yes")])
1739 (define_insn ""
1740   [(set (match_operand:SF 0 "register_operand" "=&f")
1741         (minus:SF (match_operand:SF 1 "reg_or_fp0_operand" "fG")
1742                   (match_operand:SF 2 "reg_or_fp0_operand" "fG")))]
1743   "TARGET_FP && alpha_tp == ALPHA_TP_INSN"
1744   "sub%,%)%& %R1,%R2,%0"
1745   [(set_attr "type" "fadd")
1746    (set_attr "trap" "yes")])
1748 (define_insn "subsf3"
1749   [(set (match_operand:SF 0 "register_operand" "=f")
1750         (minus:SF (match_operand:SF 1 "reg_or_fp0_operand" "fG")
1751                   (match_operand:SF 2 "reg_or_fp0_operand" "fG")))]
1752   "TARGET_FP"
1753   "sub%,%)%& %R1,%R2,%0"
1754   [(set_attr "type" "fadd")
1755    (set_attr "trap" "yes")])
1757 (define_insn ""
1758   [(set (match_operand:DF 0 "register_operand" "=&f")
1759         (minus:DF (match_operand:DF 1 "reg_or_fp0_operand" "fG")
1760                   (match_operand:DF 2 "reg_or_fp0_operand" "fG")))]
1761   "TARGET_FP && alpha_tp == ALPHA_TP_INSN"
1762   "sub%-%)%& %R1,%R2,%0"
1763   [(set_attr "type" "fadd")
1764    (set_attr "trap" "yes")])
1766 (define_insn "subdf3"
1767   [(set (match_operand:DF 0 "register_operand" "=f")
1768         (minus:DF (match_operand:DF 1 "reg_or_fp0_operand" "fG")
1769                   (match_operand:DF 2 "reg_or_fp0_operand" "fG")))]
1770   "TARGET_FP"
1771   "sub%-%)%& %R1,%R2,%0"
1772   [(set_attr "type" "fadd")
1773    (set_attr "trap" "yes")])
1775 (define_insn ""
1776   [(set (match_operand:DF 0 "register_operand" "=f")
1777         (minus:DF (float_extend:DF
1778                    (match_operand:SF 1 "reg_or_fp0_operand" "fG"))
1779                   (match_operand:DF 2 "reg_or_fp0_operand" "fG")))]
1780   "TARGET_FP && alpha_tp != ALPHA_TP_INSN"
1781   "sub%-%)%& %R1,%R2,%0"
1782   [(set_attr "type" "fadd")
1783    (set_attr "trap" "yes")])
1785 (define_insn ""
1786   [(set (match_operand:DF 0 "register_operand" "=f")
1787         (minus:DF (match_operand:DF 1 "reg_or_fp0_operand" "fG")
1788                   (float_extend:DF
1789                    (match_operand:SF 2 "reg_or_fp0_operand" "fG"))))]
1790   "TARGET_FP && alpha_tp != ALPHA_TP_INSN"
1791   "sub%-%)%& %R1,%R2,%0"
1792   [(set_attr "type" "fadd")
1793    (set_attr "trap" "yes")])
1795 (define_insn ""
1796   [(set (match_operand:DF 0 "register_operand" "=f")
1797         (minus:DF (float_extend:DF
1798                    (match_operand:SF 1 "reg_or_fp0_operand" "fG"))
1799                   (float_extend:DF
1800                    (match_operand:SF 2 "reg_or_fp0_operand" "fG"))))]
1801   "TARGET_FP && alpha_tp != ALPHA_TP_INSN"
1802   "sub%-%)%& %R1,%R2,%0"
1803   [(set_attr "type" "fadd")
1804    (set_attr "trap" "yes")])
1806 (define_insn "sqrtsf2"
1807   [(set (match_operand:SF 0 "register_operand" "=f")
1808         (sqrt:SF (match_operand:SF 1 "reg_or_fp0_operand" "fG")))]
1809   "TARGET_FP && TARGET_CIX"
1810   "sqrt%, %1,%0"
1811   [(set_attr "type" "fdivs")
1812    (set_attr "trap" "yes")])
1814 (define_insn "sqrtdf2"
1815   [(set (match_operand:DF 0 "register_operand" "=f")
1816         (sqrt:DF (match_operand:DF 1 "reg_or_fp0_operand" "fG")))]
1817   "TARGET_FP && TARGET_CIX"
1818   "sqrt%- %1,%0"
1819   [(set_attr "type" "fdivt")
1820    (set_attr "trap" "yes")])
1822 (define_insn ""
1823   [(set (match_operand:DF 0 "register_operand" "=f")
1824         (sqrt:DF (float_extend:DF
1825                   (match_operand:SF 1 "reg_or_fp0_operand" "fG"))))]
1826   "TARGET_FP && TARGET_CIX&& alpha_tp != ALPHA_TP_INSN"
1827   "sqrt%- %1,%0"
1828   [(set_attr "type" "fdivt")
1829    (set_attr "trap" "yes")])
1831 ;; Next are all the integer comparisons, and conditional moves and branches
1832 ;; and some of the related define_expand's and define_split's.
1834 (define_insn ""
1835   [(set (match_operand:DI 0 "register_operand" "=r")
1836         (match_operator:DI 1 "alpha_comparison_operator"
1837                            [(match_operand:DI 2 "reg_or_0_operand" "rJ")
1838                             (match_operand:DI 3 "reg_or_8bit_operand" "rI")]))]
1839   ""
1840   "cmp%C1 %r2,%3,%0"
1841   [(set_attr "type" "icmp")])
1843 (define_insn ""
1844   [(set (match_operand:DI 0 "register_operand" "=r")
1845         (match_operator:DI 1 "alpha_swapped_comparison_operator"
1846                            [(match_operand:DI 2 "reg_or_8bit_operand" "rI")
1847                             (match_operand:DI 3 "reg_or_0_operand" "rJ")]))]
1848   ""
1849   "cmp%c1 %r3,%2,%0"
1850   [(set_attr "type" "icmp")])
1852 ;; This pattern exists so conditional moves of SImode values are handled.
1853 ;; Comparisons are still done in DImode though.
1855 (define_insn ""
1856   [(set (match_operand:SI 0 "register_operand" "=r,r,r,r")
1857         (if_then_else:DI
1858          (match_operator 2 "signed_comparison_operator"
1859                          [(match_operand:DI 3 "reg_or_0_operand" "rJ,rJ,J,J")
1860                           (match_operand:DI 4 "reg_or_0_operand" "J,J,rJ,rJ")])
1861          (match_operand:SI 1 "reg_or_8bit_operand" "rI,0,rI,0")
1862          (match_operand:SI 5 "reg_or_8bit_operand" "0,rI,0,rI")))]
1863   "operands[3] == const0_rtx || operands[4] == const0_rtx"
1864   "@
1865    cmov%C2 %r3,%1,%0
1866    cmov%D2 %r3,%5,%0
1867    cmov%c2 %r4,%1,%0
1868    cmov%d2 %r4,%5,%0"
1869   [(set_attr "type" "cmov")])
1871 (define_insn ""
1872   [(set (match_operand:DI 0 "register_operand" "=r,r,r,r")
1873         (if_then_else:DI
1874          (match_operator 2 "signed_comparison_operator"
1875                          [(match_operand:DI 3 "reg_or_0_operand" "rJ,rJ,J,J")
1876                           (match_operand:DI 4 "reg_or_0_operand" "J,J,rJ,rJ")])
1877          (match_operand:DI 1 "reg_or_8bit_operand" "rI,0,rI,0")
1878          (match_operand:DI 5 "reg_or_8bit_operand" "0,rI,0,rI")))]
1879   "operands[3] == const0_rtx || operands[4] == const0_rtx"
1880   "@
1881    cmov%C2 %r3,%1,%0
1882    cmov%D2 %r3,%5,%0
1883    cmov%c2 %r4,%1,%0
1884    cmov%d2 %r4,%5,%0"
1885   [(set_attr "type" "cmov")])
1887 (define_insn ""
1888   [(set (match_operand:DI 0 "register_operand" "=r,r")
1889         (if_then_else:DI
1890          (eq (zero_extract:DI (match_operand:DI 2 "reg_or_0_operand" "rJ,rJ")
1891                               (const_int 1)
1892                               (const_int 0))
1893              (const_int 0))
1894          (match_operand:DI 1 "reg_or_8bit_operand" "rI,0")
1895          (match_operand:DI 3 "reg_or_8bit_operand" "0,rI")))]
1896   ""
1897   "@
1898    cmovlbc %r2,%1,%0
1899    cmovlbs %r2,%3,%0"
1900   [(set_attr "type" "cmov")])
1902 (define_insn ""
1903   [(set (match_operand:DI 0 "register_operand" "=r,r")
1904         (if_then_else:DI
1905          (ne (zero_extract:DI (match_operand:DI 2 "reg_or_0_operand" "rJ,rJ")
1906                               (const_int 1)
1907                               (const_int 0))
1908              (const_int 0))
1909          (match_operand:DI 1 "reg_or_8bit_operand" "rI,0")
1910          (match_operand:DI 3 "reg_or_8bit_operand" "0,rI")))]
1911   ""
1912   "@
1913    cmovlbs %r2,%1,%0
1914    cmovlbc %r2,%3,%0"
1915   [(set_attr "type" "cmov")])
1917 ;; This form is added since combine thinks that an IF_THEN_ELSE with both
1918 ;; arms constant is a single insn, so it won't try to form it if combine
1919 ;; knows they are really two insns.  This occurs in divides by powers
1920 ;; of two.
1922 (define_insn ""
1923   [(set (match_operand:DI 0 "register_operand" "=r")
1924         (if_then_else:DI
1925          (match_operator 2 "signed_comparison_operator"
1926                          [(match_operand:DI 3 "reg_or_0_operand" "rJ")
1927                           (const_int 0)])
1928          (plus:DI (match_dup 0)
1929                   (match_operand:DI 1 "reg_or_8bit_operand" "rI"))
1930          (match_dup 0)))
1931    (clobber (match_scratch:DI 4 "=&r"))]
1932   ""
1933   "addq %0,%1,%4\;cmov%C2 %r3,%4,%0"
1934   [(set_attr "type" "cmov")])
1936 (define_split
1937   [(set (match_operand:DI 0 "register_operand" "")
1938         (if_then_else:DI
1939          (match_operator 2 "signed_comparison_operator"
1940                          [(match_operand:DI 3 "reg_or_0_operand" "")
1941                           (const_int 0)])
1942          (plus:DI (match_dup 0)
1943                   (match_operand:DI 1 "reg_or_8bit_operand" ""))
1944          (match_dup 0)))
1945    (clobber (match_operand:DI 4 "register_operand" ""))]
1946   ""
1947   [(set (match_dup 4) (plus:DI (match_dup 0) (match_dup 1)))
1948    (set (match_dup 0) (if_then_else:DI (match_op_dup 2
1949                                                      [(match_dup 3)
1950                                                       (const_int 0)])
1951                                        (match_dup 4) (match_dup 0)))]
1952   "")
1954 (define_split
1955   [(parallel
1956     [(set (match_operand:DI 0 "register_operand" "")
1957           (if_then_else:DI
1958            (match_operator 1 "comparison_operator"
1959                            [(zero_extract:DI (match_operand:DI 2 "register_operand" "")
1960                                              (const_int 1)
1961                                              (match_operand:DI 3 "const_int_operand" ""))
1962                             (const_int 0)])
1963            (match_operand:DI 4 "reg_or_8bit_operand" "")
1964            (match_operand:DI 5 "reg_or_8bit_operand" "")))
1965      (clobber (match_operand:DI 6 "register_operand" ""))])]
1966   "INTVAL (operands[3]) != 0"
1967   [(set (match_dup 6)
1968         (lshiftrt:DI (match_dup 2) (match_dup 3)))
1969    (set (match_dup 0)
1970         (if_then_else:DI (match_op_dup 1
1971                                        [(zero_extract:DI (match_dup 6)
1972                                                          (const_int 1)
1973                                                          (const_int 0))
1974                                         (const_int 0)])
1975                          (match_dup 4)
1976                          (match_dup 5)))]
1977   "")
1979 ;; For ABS, we have two choices, depending on whether the input and output
1980 ;; registers are the same or not.
1981 (define_expand "absdi2"
1982   [(set (match_operand:DI 0 "register_operand" "")
1983         (abs:DI (match_operand:DI 1 "register_operand" "")))]
1984   ""
1985   "
1986 { if (rtx_equal_p (operands[0], operands[1]))
1987     emit_insn (gen_absdi2_same (operands[0], gen_reg_rtx (DImode)));
1988   else
1989     emit_insn (gen_absdi2_diff (operands[0], operands[1]));
1991   DONE;
1994 (define_expand "absdi2_same"
1995   [(set (match_operand:DI 1 "register_operand" "")
1996         (neg:DI (match_operand:DI 0 "register_operand" "")))
1997    (set (match_dup 0)
1998         (if_then_else:DI (ge (match_dup 0) (const_int 0))
1999                          (match_dup 0)
2000                          (match_dup 1)))]
2001   ""
2002   "")
2004 (define_expand "absdi2_diff"
2005   [(set (match_operand:DI 0 "register_operand" "")
2006         (neg:DI (match_operand:DI 1 "register_operand" "")))
2007    (set (match_dup 0)
2008         (if_then_else:DI (lt (match_dup 1) (const_int 0))
2009                          (match_dup 0)
2010                          (match_dup 1)))]
2011   ""
2012   "")
2014 (define_split
2015   [(set (match_operand:DI 0 "register_operand" "")
2016         (abs:DI (match_dup 0)))
2017    (clobber (match_operand:DI 2 "register_operand" ""))]
2018   ""
2019   [(set (match_dup 1) (neg:DI (match_dup 0)))
2020    (set (match_dup 0) (if_then_else:DI (ge (match_dup 0) (const_int 0))
2021                                        (match_dup 0) (match_dup 1)))]
2022   "")
2024 (define_split
2025   [(set (match_operand:DI 0 "register_operand" "")
2026         (abs:DI (match_operand:DI 1 "register_operand" "")))]
2027   "! rtx_equal_p (operands[0], operands[1])"
2028   [(set (match_dup 0) (neg:DI (match_dup 1)))
2029    (set (match_dup 0) (if_then_else:DI (lt (match_dup 1) (const_int 0))
2030                                        (match_dup 0) (match_dup 1)))]
2031   "")
2033 (define_split
2034   [(set (match_operand:DI 0 "register_operand" "")
2035         (neg:DI (abs:DI (match_dup 0))))
2036    (clobber (match_operand:DI 2 "register_operand" ""))]
2037   ""
2038   [(set (match_dup 1) (neg:DI (match_dup 0)))
2039    (set (match_dup 0) (if_then_else:DI (le (match_dup 0) (const_int 0))
2040                                        (match_dup 0) (match_dup 1)))]
2041   "")
2043 (define_split
2044   [(set (match_operand:DI 0 "register_operand" "")
2045         (neg:DI (abs:DI (match_operand:DI 1 "register_operand" ""))))]
2046   "! rtx_equal_p (operands[0], operands[1])"
2047   [(set (match_dup 0) (neg:DI (match_dup 1)))
2048    (set (match_dup 0) (if_then_else:DI (gt (match_dup 1) (const_int 0))
2049                                        (match_dup 0) (match_dup 1)))]
2050   "")
2052 (define_insn "sminqi3"
2053   [(set (match_operand:QI 0 "register_operand" "=r")
2054         (smin:SI (match_operand:QI 1 "reg_or_0_operand" "%rJ")
2055                  (match_operand:QI 2 "reg_or_8bit_operand" "rI")))]
2056   "TARGET_MAX"
2057   "minsb8 %r1,%2,%0"
2058   [(set_attr "type" "shift")])
2060 (define_insn "uminqi3"
2061   [(set (match_operand:QI 0 "register_operand" "=r")
2062         (umin:SI (match_operand:QI 1 "reg_or_0_operand" "%rJ")
2063                  (match_operand:QI 2 "reg_or_8bit_operand" "rI")))]
2064   "TARGET_MAX"
2065   "minub8 %r1,%2,%0"
2066   [(set_attr "type" "shift")])
2068 (define_insn "smaxqi3"
2069   [(set (match_operand:QI 0 "register_operand" "=r")
2070         (smax:SI (match_operand:QI 1 "reg_or_0_operand" "%rJ")
2071                  (match_operand:QI 2 "reg_or_8bit_operand" "rI")))]
2072   "TARGET_MAX"
2073   "maxsb8 %r1,%2,%0"
2074   [(set_attr "type" "shift")])
2076 (define_insn "umaxqi3"
2077   [(set (match_operand:QI 0 "register_operand" "=r")
2078         (umax:SI (match_operand:QI 1 "reg_or_0_operand" "%rJ")
2079                  (match_operand:QI 2 "reg_or_8bit_operand" "rI")))]
2080   "TARGET_MAX"
2081   "maxub8 %r1,%2,%0"
2082   [(set_attr "type" "shift")])
2084 (define_insn "sminhi3"
2085   [(set (match_operand:HI 0 "register_operand" "=r")
2086         (smin:SI (match_operand:HI 1 "reg_or_0_operand" "%rJ")
2087                  (match_operand:HI 2 "reg_or_8bit_operand" "rI")))]
2088   "TARGET_MAX"
2089   "minsw4 %r1,%2,%0"
2090   [(set_attr "type" "shift")])
2092 (define_insn "uminhi3"
2093   [(set (match_operand:HI 0 "register_operand" "=r")
2094         (umin:SI (match_operand:HI 1 "reg_or_0_operand" "%rJ")
2095                  (match_operand:HI 2 "reg_or_8bit_operand" "rI")))]
2096   "TARGET_MAX"
2097   "minuw4 %r1,%2,%0"
2098   [(set_attr "type" "shift")])
2100 (define_insn "smaxhi3"
2101   [(set (match_operand:HI 0 "register_operand" "=r")
2102         (smax:SI (match_operand:HI 1 "reg_or_0_operand" "%rJ")
2103                  (match_operand:HI 2 "reg_or_8bit_operand" "rI")))]
2104   "TARGET_MAX"
2105   "maxsw4 %r1,%2,%0"
2106   [(set_attr "type" "shift")])
2108 (define_insn "umaxhi3"
2109   [(set (match_operand:HI 0 "register_operand" "=r")
2110         (umax:SI (match_operand:HI 1 "reg_or_0_operand" "%rJ")
2111                  (match_operand:HI 2 "reg_or_8bit_operand" "rI")))]
2112   "TARGET_MAX"
2113   "maxuw4 %r1,%2,%0"
2114   [(set_attr "type" "shift")])
2116 (define_expand "smaxdi3"
2117   [(set (match_dup 3)
2118         (le:DI (match_operand:DI 1 "reg_or_0_operand" "")
2119                (match_operand:DI 2 "reg_or_8bit_operand" "")))
2120    (set (match_operand:DI 0 "register_operand" "")
2121         (if_then_else:DI (eq (match_dup 3) (const_int 0))
2122                          (match_dup 1) (match_dup 2)))]
2123   ""
2124   "
2125 { operands[3] = gen_reg_rtx (DImode);
2128 (define_split
2129   [(set (match_operand:DI 0 "register_operand" "")
2130         (smax:DI (match_operand:DI 1 "reg_or_0_operand" "")
2131                  (match_operand:DI 2 "reg_or_8bit_operand" "")))
2132    (clobber (match_operand:DI 3 "register_operand" ""))]
2133   "operands[2] != const0_rtx"
2134   [(set (match_dup 3) (le:DI (match_dup 1) (match_dup 2)))
2135    (set (match_dup 0) (if_then_else:DI (eq (match_dup 3) (const_int 0))
2136                                        (match_dup 1) (match_dup 2)))]
2137   "")
2139 (define_insn ""
2140   [(set (match_operand:DI 0 "register_operand" "=r")
2141         (smax:DI (match_operand:DI 1 "register_operand" "0")
2142                  (const_int 0)))]
2143   ""
2144   "cmovlt %0,0,%0"
2145   [(set_attr "type" "cmov")])
2147 (define_expand "smindi3"
2148   [(set (match_dup 3)
2149         (lt:DI (match_operand:DI 1 "reg_or_0_operand" "")
2150                (match_operand:DI 2 "reg_or_8bit_operand" "")))
2151    (set (match_operand:DI 0 "register_operand" "")
2152         (if_then_else:DI (ne (match_dup 3) (const_int 0))
2153                          (match_dup 1) (match_dup 2)))]
2154   ""
2155   "
2156 { operands[3] = gen_reg_rtx (DImode);
2159 (define_split
2160   [(set (match_operand:DI 0 "register_operand" "")
2161         (smin:DI (match_operand:DI 1 "reg_or_0_operand" "")
2162                  (match_operand:DI 2 "reg_or_8bit_operand" "")))
2163    (clobber (match_operand:DI 3 "register_operand" ""))]
2164   "operands[2] != const0_rtx"
2165   [(set (match_dup 3) (lt:DI (match_dup 1) (match_dup 2)))
2166    (set (match_dup 0) (if_then_else:DI (ne (match_dup 3) (const_int 0))
2167                                        (match_dup 1) (match_dup 2)))]
2168   "")
2170 (define_insn ""
2171   [(set (match_operand:DI 0 "register_operand" "=r")
2172         (smin:DI (match_operand:DI 1 "register_operand" "0")
2173                  (const_int 0)))]
2174   ""
2175   "cmovgt %0,0,%0"
2176   [(set_attr "type" "cmov")])
2178 (define_expand "umaxdi3"
2179   [(set (match_dup 3) 
2180         (leu:DI (match_operand:DI 1 "reg_or_0_operand" "")
2181                 (match_operand:DI 2 "reg_or_8bit_operand" "")))
2182    (set (match_operand:DI 0 "register_operand" "")
2183         (if_then_else:DI (eq (match_dup 3) (const_int 0))
2184                          (match_dup 1) (match_dup 2)))]
2185   ""
2186   "
2187 { operands[3] = gen_reg_rtx (DImode);
2190 (define_split
2191   [(set (match_operand:DI 0 "register_operand" "")
2192         (umax:DI (match_operand:DI 1 "reg_or_0_operand" "")
2193                  (match_operand:DI 2 "reg_or_8bit_operand" "")))
2194    (clobber (match_operand:DI 3 "register_operand" ""))]
2195   "operands[2] != const0_rtx"
2196   [(set (match_dup 3) (leu:DI (match_dup 1) (match_dup 2)))
2197    (set (match_dup 0) (if_then_else:DI (eq (match_dup 3) (const_int 0))
2198                                        (match_dup 1) (match_dup 2)))]
2199   "")
2201 (define_expand "umindi3"
2202   [(set (match_dup 3)
2203         (ltu:DI (match_operand:DI 1 "reg_or_0_operand" "")
2204                 (match_operand:DI 2 "reg_or_8bit_operand" "")))
2205    (set (match_operand:DI 0 "register_operand" "")
2206         (if_then_else:DI (ne (match_dup 3) (const_int 0))
2207                          (match_dup 1) (match_dup 2)))]
2208   ""
2209   "
2210 { operands[3] = gen_reg_rtx (DImode);
2213 (define_split
2214   [(set (match_operand:DI 0 "register_operand" "")
2215         (umin:DI (match_operand:DI 1 "reg_or_0_operand" "")
2216                  (match_operand:DI 2 "reg_or_8bit_operand" "")))
2217    (clobber (match_operand:DI 3 "register_operand" ""))]
2218   "operands[2] != const0_rtx"
2219   [(set (match_dup 3) (ltu:DI (match_dup 1) (match_dup 2)))
2220    (set (match_dup 0) (if_then_else:DI (ne (match_dup 3) (const_int 0))
2221                                        (match_dup 1) (match_dup 2)))]
2222   "")
2224 (define_insn ""
2225   [(set (pc)
2226         (if_then_else
2227          (match_operator 1 "signed_comparison_operator"
2228                          [(match_operand:DI 2 "reg_or_0_operand" "rJ")
2229                           (const_int 0)])
2230          (label_ref (match_operand 0 "" ""))
2231          (pc)))]
2232   ""
2233   "b%C1 %r2,%0"
2234   [(set_attr "type" "ibr")])
2236 (define_insn ""
2237   [(set (pc)
2238         (if_then_else
2239          (match_operator 1 "signed_comparison_operator"
2240                          [(const_int 0)
2241                           (match_operand:DI 2 "register_operand" "r")])
2242          (label_ref (match_operand 0 "" ""))
2243          (pc)))]
2244   ""
2245   "b%c1 %2,%0"
2246   [(set_attr "type" "ibr")])
2248 (define_insn ""
2249   [(set (pc)
2250         (if_then_else
2251          (ne (zero_extract:DI (match_operand:DI 1 "reg_or_0_operand" "rJ")
2252                               (const_int 1)
2253                               (const_int 0))
2254              (const_int 0))
2255          (label_ref (match_operand 0 "" ""))
2256          (pc)))]
2257   ""
2258   "blbs %r1,%0"
2259   [(set_attr "type" "ibr")])
2261 (define_insn ""
2262   [(set (pc)
2263         (if_then_else
2264          (eq (zero_extract:DI (match_operand:DI 1 "reg_or_0_operand" "rJ")
2265                               (const_int 1)
2266                               (const_int 0))
2267              (const_int 0))
2268          (label_ref (match_operand 0 "" ""))
2269          (pc)))]
2270   ""
2271   "blbc %r1,%0"
2272   [(set_attr "type" "ibr")])
2274 (define_split
2275   [(parallel
2276     [(set (pc)
2277           (if_then_else
2278            (match_operator 1 "comparison_operator"
2279                            [(zero_extract:DI (match_operand:DI 2 "register_operand" "")
2280                                              (const_int 1)
2281                                              (match_operand:DI 3 "const_int_operand" ""))
2282                             (const_int 0)])
2283            (label_ref (match_operand 0 "" ""))
2284            (pc)))
2285      (clobber (match_operand:DI 4 "register_operand" ""))])]
2286   "INTVAL (operands[3]) != 0"
2287   [(set (match_dup 4)
2288         (lshiftrt:DI (match_dup 2) (match_dup 3)))
2289    (set (pc)
2290         (if_then_else (match_op_dup 1
2291                                     [(zero_extract:DI (match_dup 4)
2292                                                       (const_int 1)
2293                                                       (const_int 0))
2294                                      (const_int 0)])
2295                       (label_ref (match_dup 0))
2296                       (pc)))]
2297   "")
2299 ;; The following are the corresponding floating-point insns.  Recall
2300 ;; we need to have variants that expand the arguments from SF mode
2301 ;; to DFmode.
2303 (define_insn ""
2304   [(set (match_operand:DF 0 "register_operand" "=&f")
2305         (match_operator:DF 1 "alpha_comparison_operator"
2306                            [(match_operand:DF 2 "reg_or_fp0_operand" "fG")
2307                             (match_operand:DF 3 "reg_or_fp0_operand" "fG")]))]
2308   "TARGET_FP && alpha_tp == ALPHA_TP_INSN"
2309   "cmp%-%C1%' %R2,%R3,%0"
2310   [(set_attr "type" "fadd")
2311    (set_attr "trap" "yes")])
2313 (define_insn ""
2314   [(set (match_operand:DF 0 "register_operand" "=f")
2315         (match_operator:DF 1 "alpha_comparison_operator"
2316                            [(match_operand:DF 2 "reg_or_fp0_operand" "fG")
2317                             (match_operand:DF 3 "reg_or_fp0_operand" "fG")]))]
2318   "TARGET_FP && alpha_tp != ALPHA_TP_INSN"
2319   "cmp%-%C1%' %R2,%R3,%0"
2320   [(set_attr "type" "fadd")
2321    (set_attr "trap" "yes")])
2323 (define_insn ""
2324   [(set (match_operand:DF 0 "register_operand" "=f")
2325         (match_operator:DF 1 "alpha_comparison_operator"
2326                            [(float_extend:DF
2327                              (match_operand:SF 2 "reg_or_fp0_operand" "fG"))
2328                             (match_operand:DF 3 "reg_or_fp0_operand" "fG")]))]
2329   "TARGET_FP && alpha_tp != ALPHA_TP_INSN"
2330   "cmp%-%C1%' %R2,%R3,%0"
2331   [(set_attr "type" "fadd")
2332    (set_attr "trap" "yes")])
2334 (define_insn ""
2335   [(set (match_operand:DF 0 "register_operand" "=f")
2336         (match_operator:DF 1 "alpha_comparison_operator"
2337                            [(match_operand:DF 2 "reg_or_fp0_operand" "fG")
2338                             (float_extend:DF
2339                              (match_operand:SF 3 "reg_or_fp0_operand" "fG"))]))]
2340   "TARGET_FP && alpha_tp != ALPHA_TP_INSN"
2341   "cmp%-%C1%' %R2,%R3,%0"
2342   [(set_attr "type" "fadd")
2343    (set_attr "trap" "yes")])
2345 (define_insn ""
2346   [(set (match_operand:DF 0 "register_operand" "=f")
2347         (match_operator:DF 1 "alpha_comparison_operator"
2348                            [(float_extend:DF
2349                              (match_operand:SF 2 "reg_or_fp0_operand" "fG"))
2350                             (float_extend:DF
2351                              (match_operand:SF 3 "reg_or_fp0_operand" "fG"))]))]
2352   "TARGET_FP && alpha_tp != ALPHA_TP_INSN"
2353   "cmp%-%C1%' %R2,%R3,%0"
2354   [(set_attr "type" "fadd")
2355    (set_attr "trap" "yes")])
2357 (define_insn ""
2358   [(set (match_operand:DF 0 "register_operand" "=&f,f")
2359         (if_then_else:DF 
2360          (match_operator 3 "signed_comparison_operator"
2361                          [(match_operand:DF 4 "reg_or_fp0_operand" "fG,fG")
2362                           (match_operand:DF 2 "fp0_operand" "G,G")])
2363          (match_operand:DF 1 "reg_or_fp0_operand" "fG,0")
2364          (match_operand:DF 5 "reg_or_fp0_operand" "0,fG")))]
2365   "TARGET_FP && alpha_tp == ALPHA_TP_INSN"
2366   "@
2367    fcmov%C3 %R4,%R1,%0
2368    fcmov%D3 %R4,%R5,%0"
2369   [(set_attr "type" "fadd")])
2371 (define_insn ""
2372   [(set (match_operand:DF 0 "register_operand" "=f,f")
2373         (if_then_else:DF 
2374          (match_operator 3 "signed_comparison_operator"
2375                          [(match_operand:DF 4 "reg_or_fp0_operand" "fG,fG")
2376                           (match_operand:DF 2 "fp0_operand" "G,G")])
2377          (match_operand:DF 1 "reg_or_fp0_operand" "fG,0")
2378          (match_operand:DF 5 "reg_or_fp0_operand" "0,fG")))]
2379   "TARGET_FP && alpha_tp != ALPHA_TP_INSN"
2380   "@
2381    fcmov%C3 %R4,%R1,%0
2382    fcmov%D3 %R4,%R5,%0"
2383   [(set_attr "type" "fadd")])
2385 (define_insn ""
2386   [(set (match_operand:SF 0 "register_operand" "=&f,f")
2387         (if_then_else:SF 
2388          (match_operator 3 "signed_comparison_operator"
2389                          [(match_operand:DF 4 "reg_or_fp0_operand" "fG,fG")
2390                           (match_operand:DF 2 "fp0_operand" "G,G")])
2391          (match_operand:SF 1 "reg_or_fp0_operand" "fG,0")
2392          (match_operand:SF 5 "reg_or_fp0_operand" "0,fG")))]
2393   "TARGET_FP && alpha_tp == ALPHA_TP_INSN"
2394   "@
2395    fcmov%C3 %R4,%R1,%0
2396    fcmov%D3 %R4,%R5,%0"
2397   [(set_attr "type" "fadd")])
2399 (define_insn ""
2400   [(set (match_operand:SF 0 "register_operand" "=f,f")
2401         (if_then_else:SF 
2402          (match_operator 3 "signed_comparison_operator"
2403                          [(match_operand:DF 4 "reg_or_fp0_operand" "fG,fG")
2404                           (match_operand:DF 2 "fp0_operand" "G,G")])
2405          (match_operand:SF 1 "reg_or_fp0_operand" "fG,0")
2406          (match_operand:SF 5 "reg_or_fp0_operand" "0,fG")))]
2407   "TARGET_FP && alpha_tp != ALPHA_TP_INSN"
2408   "@
2409    fcmov%C3 %R4,%R1,%0
2410    fcmov%D3 %R4,%R5,%0"
2411   [(set_attr "type" "fadd")])
2413 (define_insn ""
2414   [(set (match_operand:DF 0 "register_operand" "=f,f")
2415         (if_then_else:DF 
2416          (match_operator 3 "signed_comparison_operator"
2417                          [(match_operand:DF 4 "reg_or_fp0_operand" "fG,fG")
2418                           (match_operand:DF 2 "fp0_operand" "G,G")])
2419          (float_extend:DF (match_operand:SF 1 "reg_or_fp0_operand" "fG,0"))
2420          (match_operand:DF 5 "reg_or_fp0_operand" "0,fG")))]
2421   "TARGET_FP && alpha_tp != ALPHA_TP_INSN"
2422   "@
2423    fcmov%C3 %R4,%R1,%0
2424    fcmov%D3 %R4,%R5,%0"
2425   [(set_attr "type" "fadd")])
2427 (define_insn ""
2428   [(set (match_operand:DF 0 "register_operand" "=f,f")
2429         (if_then_else:DF 
2430          (match_operator 3 "signed_comparison_operator"
2431                          [(float_extend:DF 
2432                            (match_operand:SF 4 "reg_or_fp0_operand" "fG,fG"))
2433                           (match_operand:DF 2 "fp0_operand" "G,G")])
2434          (match_operand:DF 1 "reg_or_fp0_operand" "fG,0")
2435          (match_operand:DF 5 "reg_or_fp0_operand" "0,fG")))]
2436   "TARGET_FP && alpha_tp != ALPHA_TP_INSN"
2437   "@
2438    fcmov%C3 %R4,%R1,%0
2439    fcmov%D3 %R4,%R5,%0"
2440   [(set_attr "type" "fadd")])
2442 (define_insn ""
2443   [(set (match_operand:SF 0 "register_operand" "=f,f")
2444         (if_then_else:SF 
2445          (match_operator 3 "signed_comparison_operator"
2446                          [(float_extend:DF
2447                            (match_operand:SF 4 "reg_or_fp0_operand" "fG,fG"))
2448                           (match_operand:DF 2 "fp0_operand" "G,G")])
2449          (match_operand:SF 1 "reg_or_fp0_operand" "fG,0")
2450          (match_operand:SF 5 "reg_or_fp0_operand" "0,fG")))]
2451   "TARGET_FP && alpha_tp != ALPHA_TP_INSN"
2452   "@
2453    fcmov%C3 %R4,%R1,%0
2454    fcmov%D3 %R4,%R5,%0"
2455   [(set_attr "type" "fadd")])
2457 (define_insn ""
2458   [(set (match_operand:DF 0 "register_operand" "=f,f")
2459         (if_then_else:DF 
2460          (match_operator 3 "signed_comparison_operator"
2461                          [(float_extend:DF
2462                            (match_operand:SF 4 "reg_or_fp0_operand" "fG,fG"))
2463                           (match_operand:DF 2 "fp0_operand" "G,G")])
2464          (float_extend:DF (match_operand:SF 1 "reg_or_fp0_operand" "fG,0"))
2465          (match_operand:DF 5 "reg_or_fp0_operand" "0,fG")))]
2466   "TARGET_FP && alpha_tp != ALPHA_TP_INSN"
2467   "@
2468    fcmov%C3 %R4,%R1,%0
2469    fcmov%D3 %R4,%R5,%0"
2470   [(set_attr "type" "fadd")])
2472 (define_expand "maxdf3"
2473   [(set (match_dup 3)
2474         (le:DF (match_operand:DF 1 "reg_or_fp0_operand" "")
2475                (match_operand:DF 2 "reg_or_fp0_operand" "")))
2476    (set (match_operand:DF 0 "register_operand" "")
2477         (if_then_else:DF (eq (match_dup 3) (match_dup 4))
2478                          (match_dup 1) (match_dup 2)))]
2479   "TARGET_FP"
2480   "
2481 { operands[3] = gen_reg_rtx (DFmode);
2482   operands[4] = CONST0_RTX (DFmode);
2485 (define_expand "mindf3"
2486   [(set (match_dup 3)
2487         (lt:DF (match_operand:DF 1 "reg_or_fp0_operand" "")
2488                (match_operand:DF 2 "reg_or_fp0_operand" "")))
2489    (set (match_operand:DF 0 "register_operand" "")
2490         (if_then_else:DF (ne (match_dup 3) (match_dup 4))
2491                          (match_dup 1) (match_dup 2)))]
2492   "TARGET_FP"
2493   "
2494 { operands[3] = gen_reg_rtx (DFmode);
2495   operands[4] = CONST0_RTX (DFmode);
2498 (define_expand "maxsf3"
2499   [(set (match_dup 3)
2500         (le:DF (float_extend:DF (match_operand:SF 1 "reg_or_fp0_operand" ""))
2501                (float_extend:DF (match_operand:SF 2 "reg_or_fp0_operand" ""))))
2502    (set (match_operand:SF 0 "register_operand" "")
2503         (if_then_else:SF (eq (match_dup 3) (match_dup 4))
2504                          (match_dup 1) (match_dup 2)))]
2505   "TARGET_FP"
2506   "
2507 { operands[3] = gen_reg_rtx (DFmode);
2508   operands[4] = CONST0_RTX (DFmode);
2511 (define_expand "minsf3"
2512   [(set (match_dup 3)
2513         (lt:DF (float_extend:DF (match_operand:SF 1 "reg_or_fp0_operand" ""))
2514                (float_extend:DF (match_operand:SF 2 "reg_or_fp0_operand" ""))))
2515    (set (match_operand:SF 0 "register_operand" "")
2516         (if_then_else:SF (ne (match_dup 3) (match_dup 4))
2517                       (match_dup 1) (match_dup 2)))]
2518   "TARGET_FP"
2519   "
2520 { operands[3] = gen_reg_rtx (DFmode);
2521   operands[4] = CONST0_RTX (DFmode);
2524 (define_insn ""
2525   [(set (pc)
2526         (if_then_else
2527          (match_operator 1 "signed_comparison_operator"
2528                          [(match_operand:DF 2 "reg_or_fp0_operand" "fG")
2529                           (match_operand:DF 3 "fp0_operand" "G")])
2530          (label_ref (match_operand 0 "" ""))
2531          (pc)))]
2532   "TARGET_FP"
2533   "fb%C1 %R2,%0"
2534   [(set_attr "type" "fbr")])
2536 (define_insn ""
2537   [(set (pc)
2538         (if_then_else
2539          (match_operator 1 "signed_comparison_operator"
2540                          [(float_extend:DF
2541                            (match_operand:SF 2 "reg_or_fp0_operand" "fG"))
2542                           (match_operand:DF 3 "fp0_operand" "G")])
2543          (label_ref (match_operand 0 "" ""))
2544          (pc)))]
2545   "TARGET_FP"
2546   "fb%C1 %R2,%0"
2547   [(set_attr "type" "fbr")])
2549 ;; These are the main define_expand's used to make conditional branches
2550 ;; and compares.
2552 (define_expand "cmpdf"
2553   [(set (cc0) (compare (match_operand:DF 0 "reg_or_fp0_operand" "")
2554                        (match_operand:DF 1 "reg_or_fp0_operand" "")))]
2555   "TARGET_FP"
2556   "
2558   alpha_compare_op0 = operands[0];
2559   alpha_compare_op1 = operands[1];
2560   alpha_compare_fp_p = 1;
2561   DONE;
2564 (define_expand "cmpdi"
2565   [(set (cc0) (compare (match_operand:DI 0 "reg_or_0_operand" "")
2566                        (match_operand:DI 1 "reg_or_8bit_operand" "")))]
2567   ""
2568   "
2570   alpha_compare_op0 = operands[0];
2571   alpha_compare_op1 = operands[1];
2572   alpha_compare_fp_p = 0;
2573   DONE;
2576 (define_expand "beq"
2577   [(set (match_dup 1) (match_dup 2))
2578    (set (pc)
2579         (if_then_else (match_dup 3)
2580                       (label_ref (match_operand 0 "" ""))
2581                       (pc)))]
2582   ""
2583   "
2585   enum machine_mode mode;
2586   enum rtx_code compare_code = EQ, branch_code = NE;
2588   if (alpha_compare_fp_p)
2589     mode = DFmode;
2590   else
2591     {
2592       mode = DImode;
2593       /* We want to use cmpeq/bne when we can, since there is a zero-delay
2594          bypass between logicals and br/cmov on the 21164.  But we don't
2595          want to force valid immediate constants into registers needlessly.  */
2596       if (GET_CODE (alpha_compare_op1) == CONST_INT
2597           && ((INTVAL (alpha_compare_op1) >= -0x8000
2598                && INTVAL (alpha_compare_op1) < 0)
2599               || (INTVAL (alpha_compare_op1) > 0xff
2600                   && INTVAL (alpha_compare_op1) < 0x8000)))
2601         {
2602           compare_code = PLUS, branch_code = EQ;
2603           alpha_compare_op1 = GEN_INT (- INTVAL (alpha_compare_op1));
2604         }
2605     }
2607   operands[1] = gen_reg_rtx (mode);
2608   operands[2] = gen_rtx (compare_code, mode,
2609                          alpha_compare_op0, alpha_compare_op1);
2610   operands[3] = gen_rtx (branch_code, VOIDmode,
2611                          operands[1], CONST0_RTX (mode));
2614 (define_expand "bne"
2615   [(set (match_dup 1) (match_dup 2))
2616    (set (pc)
2617         (if_then_else (match_dup 3)
2618                       (label_ref (match_operand 0 "" ""))
2619                       (pc)))]
2620   ""
2621   "
2623   enum machine_mode mode;
2624   enum rtx_code compare_code = EQ, branch_code = EQ;
2626   if (alpha_compare_fp_p)
2627     mode = DFmode;
2628   else
2629     {
2630       mode = DImode;
2631       /* We want to use cmpeq/bne when we can, since there is a zero-delay
2632          bypass between logicals and br/cmov on the 21164.  But we don't
2633          want to force valid immediate constants into registers needlessly.  */
2634       if (GET_CODE (alpha_compare_op1) == CONST_INT
2635           && ((INTVAL (alpha_compare_op1) >= -0x8000
2636                && INTVAL (alpha_compare_op1) < 0)
2637               || (INTVAL (alpha_compare_op1) > 0xff
2638                   && INTVAL (alpha_compare_op1) < 0x8000)))
2639         {
2640           compare_code = PLUS, branch_code = NE;
2641           alpha_compare_op1 = GEN_INT (- INTVAL (alpha_compare_op1));
2642         }
2643     }
2645   operands[1] = gen_reg_rtx (mode);
2646   operands[2] = gen_rtx (compare_code, mode,
2647                          alpha_compare_op0, alpha_compare_op1);
2648   operands[3] = gen_rtx (branch_code, VOIDmode,
2649                          operands[1], CONST0_RTX (mode));
2652 (define_expand "blt"
2653   [(set (match_dup 1) (match_dup 2))
2654    (set (pc)
2655         (if_then_else (match_dup 3)
2656                       (label_ref (match_operand 0 "" ""))
2657                       (pc)))]
2658   ""
2659   "
2661   enum machine_mode mode = alpha_compare_fp_p ? DFmode : DImode;
2662   operands[1] = gen_reg_rtx (mode);
2663   operands[2] = gen_rtx (LT, mode, alpha_compare_op0, alpha_compare_op1);
2664   operands[3] = gen_rtx (NE, VOIDmode, operands[1], CONST0_RTX (mode));
2667 (define_expand "ble"
2668   [(set (match_dup 1) (match_dup 2))
2669    (set (pc)
2670         (if_then_else (match_dup 3)
2671                       (label_ref (match_operand 0 "" ""))
2672                       (pc)))]
2673   ""
2674   "
2676   enum machine_mode mode = alpha_compare_fp_p ? DFmode : DImode;
2677   operands[1] = gen_reg_rtx (mode);
2678   operands[2] = gen_rtx (LE, mode, alpha_compare_op0, alpha_compare_op1);
2679   operands[3] = gen_rtx (NE, VOIDmode, operands[1], CONST0_RTX (mode));
2682 (define_expand "bgt"
2683   [(set (match_dup 1) (match_dup 2))
2684    (set (pc)
2685         (if_then_else (match_dup 3)
2686                       (label_ref (match_operand 0 "" ""))
2687                       (pc)))]
2688   ""
2689   "
2691   if (alpha_compare_fp_p)
2692     {
2693       operands[1] = gen_reg_rtx (DFmode);
2694       operands[2] = gen_rtx (LT, DFmode, alpha_compare_op1, alpha_compare_op0);
2695       operands[3] = gen_rtx (NE, VOIDmode, operands[1], CONST0_RTX (DFmode));
2696     }
2697   else
2698     {
2699       operands[1] = gen_reg_rtx (DImode);
2700       operands[2] = gen_rtx (LE, DImode, alpha_compare_op0, alpha_compare_op1);
2701       operands[3] = gen_rtx (EQ, VOIDmode, operands[1], const0_rtx);
2702     }
2705 (define_expand "bge"
2706   [(set (match_dup 1) (match_dup 2))
2707    (set (pc)
2708         (if_then_else (match_dup 3)
2709                       (label_ref (match_operand 0 "" ""))
2710                       (pc)))]
2711   ""
2712   "
2714   if (alpha_compare_fp_p)
2715     {
2716       operands[1] = gen_reg_rtx (DFmode);
2717       operands[2] = gen_rtx (LE, DFmode, alpha_compare_op1, alpha_compare_op0);
2718       operands[3] = gen_rtx (NE, VOIDmode, operands[1], CONST0_RTX (DFmode));
2719     }
2720   else
2721     {
2722       operands[1] = gen_reg_rtx (DImode);
2723       operands[2] = gen_rtx (LT, DImode, alpha_compare_op0, alpha_compare_op1);
2724       operands[3] = gen_rtx (EQ, VOIDmode, operands[1], const0_rtx);
2725     }
2728 (define_expand "bltu"
2729   [(set (match_dup 1) (match_dup 2))
2730    (set (pc)
2731         (if_then_else (match_dup 3)
2732                       (label_ref (match_operand 0 "" ""))
2733                       (pc)))]
2734   ""
2735   "
2737   operands[1] = gen_reg_rtx (DImode);
2738   operands[2] = gen_rtx (LTU, DImode, alpha_compare_op0, alpha_compare_op1);
2739   operands[3] = gen_rtx (NE, VOIDmode, operands[1], const0_rtx);
2742 (define_expand "bleu"
2743   [(set (match_dup 1) (match_dup 2))
2744    (set (pc)
2745         (if_then_else (match_dup 3)
2746                       (label_ref (match_operand 0 "" ""))
2747                       (pc)))]
2748   ""
2749   "
2751   operands[1] = gen_reg_rtx (DImode);
2752   operands[2] = gen_rtx (LEU, DImode, alpha_compare_op0, alpha_compare_op1);
2753   operands[3] = gen_rtx (NE, VOIDmode, operands[1], const0_rtx);
2756 (define_expand "bgtu"
2757   [(set (match_dup 1) (match_dup 2))
2758    (set (pc)
2759         (if_then_else (match_dup 3)
2760                       (label_ref (match_operand 0 "" ""))
2761                       (pc)))]
2762   ""
2763   "
2765   operands[1] = gen_reg_rtx (DImode);
2766   operands[2] = gen_rtx (LEU, DImode, alpha_compare_op0, alpha_compare_op1);
2767   operands[3] = gen_rtx (EQ, VOIDmode, operands[1], const0_rtx);
2770 (define_expand "bgeu"
2771   [(set (match_dup 1) (match_dup 2))
2772    (set (pc)
2773         (if_then_else (match_dup 3)
2774                       (label_ref (match_operand 0 "" ""))
2775                       (pc)))]
2776   ""
2777   "
2779   operands[1] = gen_reg_rtx (DImode);
2780   operands[2] = gen_rtx (LTU, DImode, alpha_compare_op0, alpha_compare_op1);
2781   operands[3] = gen_rtx (EQ, VOIDmode, operands[1], const0_rtx);
2784 (define_expand "seq"
2785   [(set (match_operand:DI 0 "register_operand" "")
2786         (match_dup 1))]
2787   ""
2788   "
2790   if (alpha_compare_fp_p)
2791     FAIL;
2793   operands[1] = gen_rtx (EQ, DImode, alpha_compare_op0, alpha_compare_op1);
2796 (define_expand "sne"
2797   [(set (match_operand:DI 0 "register_operand" "")
2798         (match_dup 1))
2799    (set (match_dup 0) (xor:DI (match_dup 0) (const_int 1)))]
2800   ""
2801   "
2803   if (alpha_compare_fp_p)
2804     FAIL;
2806   operands[1] = gen_rtx (EQ, DImode, alpha_compare_op0, alpha_compare_op1);
2809 (define_expand "slt"
2810   [(set (match_operand:DI 0 "register_operand" "")
2811         (match_dup 1))]
2812   ""
2813   "
2815   if (alpha_compare_fp_p)
2816     FAIL;
2818   operands[1] = gen_rtx (LT, DImode, alpha_compare_op0, alpha_compare_op1);
2821 (define_expand "sle"
2822   [(set (match_operand:DI 0 "register_operand" "")
2823         (match_dup 1))]
2824   ""
2825   "
2827   if (alpha_compare_fp_p)
2828     FAIL;
2830   operands[1] = gen_rtx (LE, DImode, alpha_compare_op0, alpha_compare_op1);
2833 (define_expand "sgt"
2834   [(set (match_operand:DI 0 "register_operand" "")
2835         (match_dup 1))]
2836   ""
2837   "
2839   if (alpha_compare_fp_p)
2840     FAIL;
2842   operands[1] = gen_rtx (LT, DImode, force_reg (DImode, alpha_compare_op1),
2843                          alpha_compare_op0);
2846 (define_expand "sge"
2847   [(set (match_operand:DI 0 "register_operand" "")
2848         (match_dup 1))]
2849   ""
2850   "
2852   if (alpha_compare_fp_p)
2853     FAIL;
2855   operands[1] = gen_rtx (LE, DImode, force_reg (DImode, alpha_compare_op1),
2856                          alpha_compare_op0);
2859 (define_expand "sltu"
2860   [(set (match_operand:DI 0 "register_operand" "")
2861         (match_dup 1))]
2862   ""
2863   "
2865   if (alpha_compare_fp_p)
2866     FAIL;
2868   operands[1] = gen_rtx (LTU, DImode, alpha_compare_op0, alpha_compare_op1);
2871 (define_expand "sleu"
2872   [(set (match_operand:DI 0 "register_operand" "")
2873         (match_dup 1))]
2874   ""
2875   "
2877   if (alpha_compare_fp_p)
2878     FAIL;
2880   operands[1] = gen_rtx (LEU, DImode, alpha_compare_op0, alpha_compare_op1);
2883 (define_expand "sgtu"
2884   [(set (match_operand:DI 0 "register_operand" "")
2885         (match_dup 1))]
2886   ""
2887   "
2889   if (alpha_compare_fp_p)
2890     FAIL;
2892   operands[1] = gen_rtx (LTU, DImode, force_reg (DImode, alpha_compare_op1),
2893                          alpha_compare_op0);
2896 (define_expand "sgeu"
2897   [(set (match_operand:DI 0 "register_operand" "")
2898         (match_dup 1))]
2899   ""
2900   "
2902   if (alpha_compare_fp_p)
2903     FAIL;
2905   operands[1] = gen_rtx (LEU, DImode, force_reg (DImode, alpha_compare_op1),
2906                          alpha_compare_op0);
2909 ;; These are the main define_expand's used to make conditional moves.
2911 (define_expand "movsicc"
2912   [(set (match_operand:SI 0 "register_operand" "")
2913         (if_then_else:DI (match_operand 1 "comparison_operator" "")
2914                          (match_operand:SI 2 "reg_or_8bit_operand" "")
2915                          (match_operand:SI 3 "reg_or_8bit_operand" "")))]
2916   ""
2917   "
2919   if ((operands[1] = alpha_emit_conditional_move (operands[1], SImode)) == 0)
2920     FAIL;
2923 (define_expand "movdicc"
2924   [(set (match_operand:DI 0 "register_operand" "")
2925         (if_then_else:DI (match_operand 1 "comparison_operator" "")
2926                          (match_operand:DI 2 "reg_or_8bit_operand" "")
2927                          (match_operand:DI 3 "reg_or_8bit_operand" "")))]
2928   ""
2929   "
2931   if ((operands[1] = alpha_emit_conditional_move (operands[1], DImode)) == 0)
2932     FAIL;
2935 (define_expand "movsfcc"
2936   [(set (match_operand:SF 0 "register_operand" "")
2937         (if_then_else:SF (match_operand 1 "comparison_operator" "")
2938                          (match_operand:SF 2 "reg_or_8bit_operand" "")
2939                          (match_operand:SF 3 "reg_or_8bit_operand" "")))]
2940   ""
2941   "
2943   if ((operands[1] = alpha_emit_conditional_move (operands[1], SFmode)) == 0)
2944     FAIL;
2947 (define_expand "movdfcc"
2948   [(set (match_operand:DF 0 "register_operand" "")
2949         (if_then_else:DF (match_operand 1 "comparison_operator" "")
2950                          (match_operand:DF 2 "reg_or_8bit_operand" "")
2951                          (match_operand:DF 3 "reg_or_8bit_operand" "")))]
2952   ""
2953   "
2955   if ((operands[1] = alpha_emit_conditional_move (operands[1], DFmode)) == 0)
2956     FAIL;
2959 ;; These define_split definitions are used in cases when comparisons have
2960 ;; not be stated in the correct way and we need to reverse the second
2961 ;; comparison.  For example, x >= 7 has to be done as x < 6 with the
2962 ;; comparison that tests the result being reversed.  We have one define_split
2963 ;; for each use of a comparison.  They do not match valid insns and need
2964 ;; not generate valid insns.
2966 ;; We can also handle equality comparisons (and inequality comparisons in
2967 ;; cases where the resulting add cannot overflow) by doing an add followed by
2968 ;; a comparison with zero.  This is faster since the addition takes one
2969 ;; less cycle than a compare when feeding into a conditional move.
2970 ;; For this case, we also have an SImode pattern since we can merge the add
2971 ;; and sign extend and the order doesn't matter.
2973 ;; We do not do this for floating-point, since it isn't clear how the "wrong"
2974 ;; operation could have been generated.
2976 (define_split
2977   [(set (match_operand:DI 0 "register_operand" "")
2978         (if_then_else:DI
2979          (match_operator 1 "comparison_operator"
2980                          [(match_operand:DI 2 "reg_or_0_operand" "")
2981                           (match_operand:DI 3 "reg_or_cint_operand" "")])
2982          (match_operand:DI 4 "reg_or_cint_operand" "")
2983          (match_operand:DI 5 "reg_or_cint_operand" "")))
2984    (clobber (match_operand:DI 6 "register_operand" ""))]
2985   "operands[3] != const0_rtx"
2986   [(set (match_dup 6) (match_dup 7))
2987    (set (match_dup 0)
2988         (if_then_else:DI (match_dup 8) (match_dup 4) (match_dup 5)))]
2989   "
2990 { enum rtx_code code = GET_CODE (operands[1]);
2991   int unsignedp = (code == GEU || code == LEU || code == GTU || code == LTU);
2993   /* If we are comparing for equality with a constant and that constant
2994      appears in the arm when the register equals the constant, use the
2995      register since that is more likely to match (and to produce better code
2996      if both would).  */
2998   if (code == EQ && GET_CODE (operands[3]) == CONST_INT
2999       && rtx_equal_p (operands[4], operands[3]))
3000     operands[4] = operands[2];
3002   else if (code == NE && GET_CODE (operands[3]) == CONST_INT
3003            && rtx_equal_p (operands[5], operands[3]))
3004     operands[5] = operands[2];
3006   if (code == NE || code == EQ
3007       || (extended_count (operands[2], DImode, unsignedp) >= 1
3008           && extended_count (operands[3], DImode, unsignedp) >= 1))
3009     {
3010       if (GET_CODE (operands[3]) == CONST_INT)
3011         operands[7] = gen_rtx (PLUS, DImode, operands[2],
3012                                GEN_INT (- INTVAL (operands[3])));
3013       else
3014         operands[7] = gen_rtx (MINUS, DImode, operands[2], operands[3]);
3016       operands[8] = gen_rtx (code, VOIDmode, operands[6], const0_rtx);
3017     }
3019   else if (code == EQ || code == LE || code == LT
3020            || code == LEU || code == LTU)
3021     {
3022       operands[7] = gen_rtx (code, DImode, operands[2], operands[3]);
3023       operands[8] = gen_rtx (NE, VOIDmode, operands[6], const0_rtx);
3024     }
3025   else
3026     {
3027       operands[7] = gen_rtx (reverse_condition (code), DImode, operands[2],
3028                              operands[3]);
3029       operands[8] = gen_rtx (EQ, VOIDmode, operands[6], const0_rtx);
3030     }
3033 (define_split
3034   [(set (match_operand:DI 0 "register_operand" "")
3035         (if_then_else:DI
3036          (match_operator 1 "comparison_operator"
3037                          [(match_operand:SI 2 "reg_or_0_operand" "")
3038                           (match_operand:SI 3 "reg_or_cint_operand" "")])
3039          (match_operand:DI 4 "reg_or_8bit_operand" "")
3040          (match_operand:DI 5 "reg_or_8bit_operand" "")))
3041    (clobber (match_operand:DI 6 "register_operand" ""))]
3042   "operands[3] != const0_rtx
3043    && (GET_CODE (operands[1]) == EQ || GET_CODE (operands[1]) == NE)"
3044   [(set (match_dup 6) (match_dup 7))
3045    (set (match_dup 0)
3046         (if_then_else:DI (match_dup 8) (match_dup 4) (match_dup 5)))]
3047   "
3048 { enum rtx_code code = GET_CODE (operands[1]);
3049   int unsignedp = (code == GEU || code == LEU || code == GTU || code == LTU);
3050   rtx tem;
3052   if ((code != NE && code != EQ
3053        && ! (extended_count (operands[2], DImode, unsignedp) >= 1
3054              && extended_count (operands[3], DImode, unsignedp) >= 1)))
3055     FAIL;
3057   if (GET_CODE (operands[3]) == CONST_INT)
3058     tem = gen_rtx (PLUS, SImode, operands[2],
3059                    GEN_INT (- INTVAL (operands[3])));
3060   else
3061     tem = gen_rtx (MINUS, SImode, operands[2], operands[3]);
3063   operands[7] = gen_rtx (SIGN_EXTEND, DImode, tem);
3064   operands[8] = gen_rtx (GET_CODE (operands[1]), VOIDmode, operands[6],
3065                          const0_rtx);
3068 (define_split
3069   [(set (pc)
3070         (if_then_else
3071          (match_operator 1 "comparison_operator"
3072                          [(match_operand:DI 2 "reg_or_0_operand" "")
3073                           (match_operand:DI 3 "reg_or_cint_operand" "")])
3074          (label_ref (match_operand 0 "" ""))
3075          (pc)))
3076    (clobber (match_operand:DI 4 "register_operand" ""))]
3077   "operands[3] != const0_rtx"
3078   [(set (match_dup 4) (match_dup 5))
3079    (set (pc) (if_then_else (match_dup 6) (label_ref (match_dup 0)) (pc)))]
3080   "
3081 { enum rtx_code code = GET_CODE (operands[1]);
3082   int unsignedp = (code == GEU || code == LEU || code == GTU || code == LTU);
3084   if (code == NE || code == EQ
3085       || (extended_count (operands[2], DImode, unsignedp) >= 1
3086           && extended_count (operands[3], DImode, unsignedp) >= 1))
3087     {
3088       if (GET_CODE (operands[3]) == CONST_INT)
3089         operands[5] = gen_rtx (PLUS, DImode, operands[2],
3090                                GEN_INT (- INTVAL (operands[3])));
3091       else
3092         operands[5] = gen_rtx (MINUS, DImode, operands[2], operands[3]);
3094       operands[6] = gen_rtx (code, VOIDmode, operands[4], const0_rtx);
3095     }
3097   else if (code == EQ || code == LE || code == LT
3098            || code == LEU || code == LTU)
3099     {
3100       operands[5] = gen_rtx (code, DImode, operands[2], operands[3]);
3101       operands[6] = gen_rtx (NE, VOIDmode, operands[4], const0_rtx);
3102     }
3103   else
3104     {
3105       operands[5] = gen_rtx (reverse_condition (code), DImode, operands[2],
3106                              operands[3]);
3107       operands[6] = gen_rtx (EQ, VOIDmode, operands[4], const0_rtx);
3108     }
3111 (define_split
3112   [(set (pc)
3113         (if_then_else
3114          (match_operator 1 "comparison_operator"
3115                          [(match_operand:SI 2 "reg_or_0_operand" "")
3116                           (match_operand:SI 3 "const_int_operand" "")])
3117          (label_ref (match_operand 0 "" ""))
3118          (pc)))
3119    (clobber (match_operand:DI 4 "register_operand" ""))]
3120   "operands[3] != const0_rtx
3121    && (GET_CODE (operands[1]) == EQ || GET_CODE (operands[1]) == NE)"
3122   [(set (match_dup 4) (match_dup 5))
3123    (set (pc) (if_then_else (match_dup 6) (label_ref (match_dup 0)) (pc)))]
3124   "
3125 { rtx tem;
3127   if (GET_CODE (operands[3]) == CONST_INT)
3128     tem = gen_rtx (PLUS, SImode, operands[2],
3129                    GEN_INT (- INTVAL (operands[3])));
3130   else
3131     tem = gen_rtx (MINUS, SImode, operands[2], operands[3]);
3132   
3133   operands[5] = gen_rtx (SIGN_EXTEND, DImode, tem);
3134   operands[6] = gen_rtx (GET_CODE (operands[1]), VOIDmode,
3135                          operands[4], const0_rtx);
3138 ;; We can convert such things as "a > 0xffff" to "t = a & ~ 0xffff; t != 0".
3139 ;; This eliminates one, and sometimes two, insns when the AND can be done
3140 ;; with a ZAP.
3141 (define_split
3142   [(set (match_operand:DI 0 "register_operand" "")
3143         (match_operator 1 "comparison_operator"
3144                         [(match_operand:DI 2 "register_operand" "")
3145                          (match_operand:DI 3 "const_int_operand" "")]))
3146    (clobber (match_operand:DI 4 "register_operand" ""))]
3147   "exact_log2 (INTVAL (operands[3]) + 1) >= 0
3148    && (GET_CODE (operands[1]) == GTU
3149        || GET_CODE (operands[1]) == LEU
3150        || ((GET_CODE (operands[1]) == GT || GET_CODE (operands[1]) == LE)
3151            && extended_count (operands[2], DImode, 1) > 0))"
3152   [(set (match_dup 4) (and:DI (match_dup 2) (match_dup 5)))
3153    (set (match_dup 0) (match_dup 6))]
3154   "
3156   operands[5] = GEN_INT (~ INTVAL (operands[3]));
3157   operands[6] = gen_rtx (((GET_CODE (operands[1]) == GTU
3158                            || GET_CODE (operands[1]) == GT)
3159                           ? NE : EQ),
3160                          DImode, operands[4], const0_rtx);
3163 ;; Here are the CALL and unconditional branch insns.  Calls on NT and OSF
3164 ;; work differently, so we have different patterns for each.
3166 (define_expand "call"
3167   [(use (match_operand:DI 0 "" ""))
3168    (use (match_operand 1 "" ""))
3169    (use (match_operand 2 "" ""))
3170    (use (match_operand 3 "" ""))]
3171   ""
3172   "
3173 { if (TARGET_WINDOWS_NT)
3174     emit_call_insn (gen_call_nt (operands[0], operands[1]));
3175   else if (TARGET_OPEN_VMS)
3176     emit_call_insn (gen_call_vms (operands[0], operands[2]));
3177   else
3178     emit_call_insn (gen_call_osf (operands[0], operands[1]));
3180   DONE;
3183 (define_expand "call_osf"
3184   [(parallel [(call (mem:DI (match_operand 0 "" ""))
3185                     (match_operand 1 "" ""))
3186               (clobber (reg:DI 27))
3187               (clobber (reg:DI 26))])]
3188   ""
3189   "
3190 { if (GET_CODE (operands[0]) != MEM)
3191     abort ();
3193   operands[0] = XEXP (operands[0], 0);
3195   if (GET_CODE (operands[0]) != SYMBOL_REF
3196       && ! (GET_CODE (operands[0]) == REG && REGNO (operands[0]) == 27))
3197     {
3198       rtx tem = gen_rtx (REG, DImode, 27);
3199       emit_move_insn (tem, operands[0]);
3200       operands[0] = tem;
3201     }
3204 (define_expand "call_nt"
3205   [(parallel [(call (mem:DI (match_operand:DI 0 "" ""))
3206                     (match_operand 1 "" ""))
3207               (clobber (reg:DI 26))])]
3208   ""
3209   "
3210 { if (GET_CODE (operands[0]) != MEM)
3211     abort ();
3212   operands[0] = XEXP (operands[0], 0);
3214   if (GET_CODE (operands[1]) != SYMBOL_REF
3215       && ! (GET_CODE (operands[1]) == REG && REGNO (operands[1]) == 27))
3216     {
3217       rtx tem = gen_rtx (REG, DImode, 27);
3218       emit_move_insn (tem, operands[1]);
3219       operands[1] = tem;
3220     }
3224 ;; call openvms/alpha
3225 ;; op 0: symbol ref for called function
3226 ;; op 1: next_arg_reg (argument information value for R25)
3228 (define_expand "call_vms"
3229   [(parallel [(call (mem:DI (match_operand 0 "" ""))
3230                     (match_operand 1 "" ""))
3231               (use (match_dup 2))
3232               (use (reg:DI 25))
3233               (use (reg:DI 26))
3234               (clobber (reg:DI 27))])]
3235   ""
3236   "
3237 { if (GET_CODE (operands[0]) != MEM)
3238     abort ();
3240   operands[0] = XEXP (operands[0], 0);
3242   /* Always load AI with argument information, then handle symbolic and
3243      indirect call differently.  Load RA and set operands[2] to PV in
3244      both cases.  */
3246   emit_move_insn (gen_rtx (REG, DImode, 25), operands[1]);
3247   if (GET_CODE (operands[0]) == SYMBOL_REF)
3248     {
3249       extern char *savealloc ();
3250       char *symbol = XSTR (operands[0], 0);
3251       char *linksym = savealloc (strlen (symbol) + 5);
3252       rtx linkage;
3254       alpha_need_linkage (symbol, 0);
3256       strcpy (linksym, symbol);
3257       strcat (linksym, \"..lk\");
3258       linkage = gen_rtx (SYMBOL_REF, Pmode, linksym);
3260       emit_move_insn (gen_rtx (REG, Pmode, 26), gen_rtx (MEM, Pmode, linkage));
3262       operands[2]
3263         = validize_mem (gen_rtx (MEM, Pmode, plus_constant (linkage, 8)));
3264     }
3265   else
3266     {
3267       emit_move_insn (gen_rtx (REG, Pmode, 26),
3268                       gen_rtx (MEM, Pmode, plus_constant (operands[0], 8)));
3270       operands[2] = operands[0];
3271     }
3275 (define_expand "call_value"
3276   [(use (match_operand 0 "" ""))
3277    (use (match_operand:DI 1 "" ""))
3278    (use (match_operand 2 "" ""))
3279    (use (match_operand 3 "" ""))
3280    (use (match_operand 4 "" ""))]
3281   ""
3282   "
3283 { if (TARGET_WINDOWS_NT)
3284     emit_call_insn (gen_call_value_nt (operands[0], operands[1], operands[2]));
3285   else if (TARGET_OPEN_VMS)
3286     emit_call_insn (gen_call_value_vms (operands[0], operands[1],
3287                                         operands[3]));
3288   else
3289     emit_call_insn (gen_call_value_osf (operands[0], operands[1],
3290                                         operands[2]));
3291   DONE;
3294 (define_expand "call_value_osf"
3295   [(parallel [(set (match_operand 0 "" "")
3296                    (call (mem:DI (match_operand 1 "" ""))
3297                          (match_operand 2 "" "")))
3298               (clobber (reg:DI 27))
3299               (clobber (reg:DI 26))])]
3300   ""
3301   "
3302 { if (GET_CODE (operands[1]) != MEM)
3303     abort ();
3305   operands[1] = XEXP (operands[1], 0);
3307   if (GET_CODE (operands[1]) != SYMBOL_REF
3308       && ! (GET_CODE (operands[1]) == REG && REGNO (operands[1]) == 27))
3309     {
3310       rtx tem = gen_rtx (REG, DImode, 27);
3311       emit_move_insn (tem, operands[1]);
3312       operands[1] = tem;
3313     }
3316 (define_expand "call_value_nt"
3317   [(parallel [(set (match_operand 0 "" "")
3318                    (call (mem:DI (match_operand:DI 1 "" ""))
3319                          (match_operand 2 "" "")))
3320               (clobber (reg:DI 26))])]
3321   ""
3322   "
3323 { if (GET_CODE (operands[1]) != MEM)
3324     abort ();
3326   operands[1] = XEXP (operands[1], 0);
3327   if (GET_CODE (operands[1]) != SYMBOL_REF
3328       && ! (GET_CODE (operands[1]) == REG && REGNO (operands[1]) == 27))
3329     {
3330       rtx tem = gen_rtx (REG, DImode, 27);
3331       emit_move_insn (tem, operands[1]);
3332       operands[1] = tem;
3333     }
3336 (define_expand "call_value_vms"
3337   [(parallel [(set (match_operand 0 "" "")
3338                    (call (mem:DI (match_operand:DI 1 "" ""))
3339                          (match_operand 2 "" "")))
3340               (use (match_dup 3))
3341               (use (reg:DI 25))
3342               (use (reg:DI 26))
3343               (clobber (reg:DI 27))])]
3344   ""
3345   "
3346 { if (GET_CODE (operands[1]) != MEM)
3347     abort ();
3349   operands[1] = XEXP (operands[1], 0);
3351   /* Always load AI with argument information, then handle symbolic and
3352      indirect call differently.  Load RA and set operands[3] to PV in
3353      both cases.  */
3355   emit_move_insn (gen_rtx (REG, DImode, 25), operands[2]);
3356   if (GET_CODE (operands[1]) == SYMBOL_REF)
3357     {
3358       extern char *savealloc ();
3359       char *symbol = XSTR (operands[1], 0);
3360       char *linksym = savealloc (strlen (symbol) + 5);
3361       rtx linkage;
3363       alpha_need_linkage (symbol, 0);
3364       strcpy (linksym, symbol);
3365       strcat (linksym, \"..lk\");
3366       linkage = gen_rtx (SYMBOL_REF, Pmode, linksym);
3368       emit_move_insn (gen_rtx (REG, Pmode, 26), gen_rtx (MEM, Pmode, linkage));
3370       operands[3]
3371         = validize_mem (gen_rtx (MEM, Pmode, plus_constant (linkage, 8)));
3372     }
3373   else
3374     {
3375       emit_move_insn (gen_rtx (REG, Pmode, 26),
3376                       gen_rtx (MEM, Pmode, plus_constant (operands[1], 8)));
3378       operands[3] = operands[1];
3379     }
3382 (define_insn ""
3383   [(call (mem:DI (match_operand:DI 0 "call_operand" "r,R,i"))
3384          (match_operand 1 "" ""))
3385    (clobber (reg:DI 27))
3386    (clobber (reg:DI 26))]
3387   "! TARGET_WINDOWS_NT && ! TARGET_OPEN_VMS && alpha_tp == ALPHA_TP_INSN"
3388   "@
3389    jsr $26,($27),0\;trapb\;ldgp $29,4($26)
3390    bsr $26,%0..ng\;trapb
3391    jsr $26,%0\;trapb\;ldgp $29,4($26)"
3392   [(set_attr "type" "jsr,jsr,ibr")])
3393       
3394 (define_insn ""
3395   [(call (mem:DI (match_operand:DI 0 "call_operand" "r,R,i"))
3396          (match_operand 1 "" ""))
3397    (clobber (reg:DI 27))
3398    (clobber (reg:DI 26))]
3399   "! TARGET_WINDOWS_NT && ! TARGET_OPEN_VMS"
3400   "@
3401    jsr $26,($27),0\;ldgp $29,0($26)
3402    bsr $26,%0..ng
3403    jsr $26,%0\;ldgp $29,0($26)"
3404   [(set_attr "type" "jsr,jsr,ibr")])
3405       
3406 (define_insn ""
3407   [(call (mem:DI (match_operand:DI 0 "call_operand" "r,i"))
3408          (match_operand 1 "" ""))
3409    (clobber (reg:DI 26))]
3410   "TARGET_WINDOWS_NT"
3411   "@
3412    jsr $26,(%0)
3413    bsr $26,%0"
3414   [(set_attr "type" "jsr")])
3415       
3416 (define_insn ""
3417   [(call (mem:DI (match_operand:DI 0 "call_operand" "r,i"))
3418          (match_operand 1 "" ""))
3419    (use (match_operand:DI 2 "general_operand" "r,m"))
3420    (use (reg:DI 25))
3421    (use (reg:DI 26))
3422    (clobber (reg:DI 27))]
3423   "TARGET_OPEN_VMS"
3424   "@
3425    bis %2,%2,$27\;jsr $26,0\;ldq $27,0($29)
3426    ldq $27,%2\;jsr $26,%0\;ldq $27,0($29)"
3427   [(set_attr "type" "jsr")])
3429 (define_insn ""
3430   [(set (match_operand 0 "register_operand" "=rf,rf,rf")
3431         (call (mem:DI (match_operand:DI 1 "call_operand" "r,R,i"))
3432               (match_operand 2 "" "")))
3433    (clobber (reg:DI 27))
3434    (clobber (reg:DI 26))]
3435   "! TARGET_WINDOWS_NT && ! TARGET_OPEN_VMS && alpha_tp == ALPHA_TP_INSN"
3436   "@
3437    jsr $26,($27),0\;trapb\;ldgp $29,4($26)
3438    bsr $26,%1..ng\;trapb
3439    jsr $26,%1\;trapb\;ldgp $29,4($26)"
3440   [(set_attr "type" "jsr,jsr,ibr")])
3442 (define_insn ""
3443   [(set (match_operand 0 "register_operand" "=rf,rf,rf")
3444         (call (mem:DI (match_operand:DI 1 "call_operand" "r,R,i"))
3445               (match_operand 2 "" "")))
3446    (clobber (reg:DI 27))
3447    (clobber (reg:DI 26))]
3448   "! TARGET_WINDOWS_NT && ! TARGET_OPEN_VMS"
3449   "@
3450    jsr $26,($27),0\;ldgp $29,0($26)
3451    bsr $26,%1..ng
3452    jsr $26,%1\;ldgp $29,0($26)"
3453   [(set_attr "type" "jsr,jsr,ibr")])
3455 (define_insn ""
3456   [(set (match_operand 0 "register_operand" "=rf,rf")
3457         (call (mem:DI (match_operand:DI 1 "call_operand" "r,i"))
3458               (match_operand 2 "" "")))
3459    (clobber (reg:DI 26))]
3460   "TARGET_WINDOWS_NT"
3461   "@
3462    jsr $26,(%1)
3463    bsr $26,%1"
3464   [(set_attr "type" "jsr")])
3466 (define_insn ""
3467   [(set (match_operand 0 "register_operand" "")
3468         (call (mem:DI (match_operand:DI 1 "call_operand" "r,i"))
3469               (match_operand 2 "" "")))
3470    (use (match_operand:DI 3 "general_operand" "r,m"))
3471    (use (reg:DI 25))
3472    (use (reg:DI 26))
3473    (clobber (reg:DI 27))]
3474   "TARGET_OPEN_VMS"
3475   "@
3476    bis %3,%3,$27\;jsr $26,0\;ldq $27,0($29)
3477    ldq $27,%3\;jsr $26,%1\;ldq $27,0($29)"
3478   [(set_attr "type" "jsr")])
3480 ;; Call subroutine returning any type.
3482 (define_expand "untyped_call"
3483   [(parallel [(call (match_operand 0 "" "")
3484                     (const_int 0))
3485               (match_operand 1 "" "")
3486               (match_operand 2 "" "")])]
3487   ""
3488   "
3490   int i;
3492   emit_call_insn (gen_call (operands[0], const0_rtx, NULL, const0_rtx));
3494   for (i = 0; i < XVECLEN (operands[2], 0); i++)
3495     {
3496       rtx set = XVECEXP (operands[2], 0, i);
3497       emit_move_insn (SET_DEST (set), SET_SRC (set));
3498     }
3500   /* The optimizer does not know that the call sets the function value
3501      registers we stored in the result block.  We avoid problems by
3502      claiming that all hard registers are used and clobbered at this
3503      point.  */
3504   emit_insn (gen_blockage ());
3506   DONE;
3509 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
3510 ;; all of memory.  This blocks insns from being moved across this point.
3512 (define_insn "blockage"
3513   [(unspec_volatile [(const_int 0)] 1)]
3514   ""
3515   "")
3517 (define_insn "jump"
3518   [(set (pc)
3519         (label_ref (match_operand 0 "" "")))]
3520   ""
3521   "br $31,%l0"
3522   [(set_attr "type" "ibr")])
3524 (define_insn "return"
3525   [(return)]
3526   "direct_return ()"
3527   "ret $31,($26),1"
3528   [(set_attr "type" "ibr")])
3530 (define_insn "indirect_jump"
3531   [(set (pc) (match_operand:DI 0 "register_operand" "r"))]
3532   ""
3533   "jmp $31,(%0),0"
3534   [(set_attr "type" "ibr")])
3536 (define_insn "nop"
3537   [(const_int 0)]
3538   ""
3539   "bis $31,$31,$31"
3540   [(set_attr "type" "ilog")])
3542 (define_expand "tablejump"
3543   [(use (match_operand:SI 0 "register_operand" ""))
3544    (use (match_operand:SI 1 "" ""))]
3545   ""
3546   "
3548   if (TARGET_WINDOWS_NT)
3549     emit_jump_insn (gen_tablejump_nt (operands[0], operands[1]));
3550   else if (TARGET_OPEN_VMS)
3551     emit_jump_insn (gen_tablejump_vms (operands[0], operands[1]));
3552   else
3553     emit_jump_insn (gen_tablejump_osf (operands[0], operands[1]));
3555   DONE;
3558 (define_expand "tablejump_osf"
3559   [(set (match_dup 3)
3560         (sign_extend:DI (match_operand:SI 0 "register_operand" "")))
3561    (parallel [(set (pc)
3562                    (plus:DI (match_dup 3)
3563                             (label_ref:DI (match_operand 1 "" ""))))
3564               (clobber (match_scratch:DI 2 "=r"))])]
3565   ""
3566   "
3567 { operands[3] = gen_reg_rtx (DImode); }")
3569 (define_expand "tablejump_nt"
3570   [(set (match_dup 3)
3571         (sign_extend:DI (match_operand:SI 0 "register_operand" "")))
3572    (parallel [(set (pc)
3573                    (match_dup 3))
3574               (use (label_ref (match_operand 1 "" "")))])]
3575   ""
3576   "
3577 { operands[3] = gen_reg_rtx (DImode); }")
3580 ;; tablejump, openVMS way
3581 ;; op 0: offset
3582 ;; op 1: label preceding jump-table
3584 (define_expand "tablejump_vms"
3585   [(set (match_dup 2)
3586       (match_operand:DI 0 "register_operand" ""))
3587         (set (pc)
3588         (plus:DI (match_dup 2)
3589                 (label_ref:DI (match_operand 1 "" ""))))]
3590   ""
3591   "
3592 { operands[2] = gen_reg_rtx (DImode); }")
3594 (define_insn ""
3595   [(set (pc)
3596         (plus:DI (match_operand:DI 0 "register_operand" "r")
3597                  (label_ref:DI (match_operand 1 "" ""))))
3598    (clobber (match_scratch:DI 2 "=r"))]
3599   "! TARGET_WINDOWS_NT && ! TARGET_OPEN_VMS && next_active_insn (insn) != 0
3600    && GET_CODE (PATTERN (next_active_insn (insn))) == ADDR_DIFF_VEC
3601    && PREV_INSN (next_active_insn (insn)) == operands[1]"
3602   "*
3603 { rtx best_label = 0;
3604   rtx jump_table_insn = next_active_insn (operands[1]);
3606   if (GET_CODE (jump_table_insn) == JUMP_INSN
3607       && GET_CODE (PATTERN (jump_table_insn)) == ADDR_DIFF_VEC)
3608     {
3609       rtx jump_table = PATTERN (jump_table_insn);
3610       int n_labels = XVECLEN (jump_table, 1);
3611       int best_count = -1;
3612       int i, j;
3614       for (i = 0; i < n_labels; i++)
3615         {
3616           int count = 1;
3618           for (j = i + 1; j < n_labels; j++)
3619             if (XEXP (XVECEXP (jump_table, 1, i), 0)
3620                 == XEXP (XVECEXP (jump_table, 1, j), 0))
3621               count++;
3623           if (count > best_count)
3624             best_count = count, best_label = XVECEXP (jump_table, 1, i);
3625         }
3626     }
3628   if (best_label)
3629     {
3630       operands[3] = best_label;
3631       return \"addq %0,$29,%2\;jmp $31,(%2),%3\";
3632     }
3633   else
3634     return \"addq %0,$29,%2\;jmp $31,(%2),0\";
3636   [(set_attr "type" "ibr")])
3638 (define_insn ""
3639   [(set (pc)
3640         (match_operand:DI 0 "register_operand" "r"))
3641    (use (label_ref (match_operand 1 "" "")))]
3642   "TARGET_WINDOWS_NT && next_active_insn (insn) != 0
3643    && GET_CODE (PATTERN (next_active_insn (insn))) == ADDR_DIFF_VEC
3644    && PREV_INSN (next_active_insn (insn)) == operands[1]"
3645   "*
3646 { rtx best_label = 0;
3647   rtx jump_table_insn = next_active_insn (operands[1]);
3649   if (GET_CODE (jump_table_insn) == JUMP_INSN
3650       && GET_CODE (PATTERN (jump_table_insn)) == ADDR_DIFF_VEC)
3651     {
3652       rtx jump_table = PATTERN (jump_table_insn);
3653       int n_labels = XVECLEN (jump_table, 1);
3654       int best_count = -1;
3655       int i, j;
3657       for (i = 0; i < n_labels; i++)
3658         {
3659           int count = 1;
3661           for (j = i + 1; j < n_labels; j++)
3662             if (XEXP (XVECEXP (jump_table, 1, i), 0)
3663                 == XEXP (XVECEXP (jump_table, 1, j), 0))
3664               count++;
3666           if (count > best_count)
3667             best_count = count, best_label = XVECEXP (jump_table, 1, i);
3668         }
3669     }
3671   if (best_label)
3672     {
3673       operands[2] = best_label;
3674       return \"jmp $31,(%0),%2\";
3675     }
3676   else
3677     return \"jmp $31,(%0),0\";
3679   [(set_attr "type" "ibr")])
3682 ;; op 0 is table offset
3683 ;; op 1 is table label
3686 (define_insn ""
3687   [(set (pc)
3688         (plus:DI (match_operand 0 "register_operand" "r")
3689                 (label_ref (match_operand 1 "" ""))))]
3690   "TARGET_OPEN_VMS"
3691   "jmp $31,(%0),0"
3692   [(set_attr "type" "ibr")])
3694 ;; Cache flush.  Used by INITIALIZE_TRAMPOLINE.  0x86 is PAL_imb, but we don't
3695 ;; want to have to include pal.h in our .s file.
3696 (define_insn ""
3697   [(unspec_volatile [(const_int 0)] 0)]
3698   ""
3699   "call_pal 0x86"
3700   [(set_attr "type" "isubr")])
3702 ;; Finally, we have the basic data motion insns.  The byte and word insns
3703 ;; are done via define_expand.  Start with the floating-point insns, since
3704 ;; they are simpler.
3706 (define_insn ""
3707   [(set (match_operand:SF 0 "nonimmediate_operand" "=r,r,m,f,f,f,m")
3708         (match_operand:SF 1 "input_operand" "rG,m,rG,f,G,m,fG"))]
3709   "register_operand (operands[0], SFmode)
3710    || reg_or_fp0_operand (operands[1], SFmode)"
3711   "@
3712    bis %r1,%r1,%0
3713    ldl %0,%1
3714    stl %r1,%0
3715    cpys %1,%1,%0
3716    cpys $f31,$f31,%0
3717    ld%, %0,%1
3718    st%, %R1,%0"
3719   [(set_attr "type" "ilog,ld,st,fcpys,fcpys,ld,st")])
3721 (define_insn ""
3722   [(set (match_operand:DF 0 "nonimmediate_operand" "=r,r,m,f,f,f,m")
3723         (match_operand:DF 1 "input_operand" "rG,m,rG,f,G,m,fG"))]
3724   "register_operand (operands[0], DFmode)
3725    || reg_or_fp0_operand (operands[1], DFmode)"
3726   "@
3727    bis %r1,%r1,%0
3728    ldq %0,%1
3729    stq %r1,%0
3730    cpys %1,%1,%0
3731    cpys $f31,$f31,%0
3732    ld%- %0,%1
3733    st%- %R1,%0"
3734   [(set_attr "type" "ilog,ld,st,fcpys,fcpys,ld,st")])
3736 (define_expand "movsf"
3737   [(set (match_operand:SF 0 "nonimmediate_operand" "")
3738         (match_operand:SF 1 "general_operand" ""))]
3739   ""
3740   "
3742   if (GET_CODE (operands[0]) == MEM
3743       && ! reg_or_fp0_operand (operands[1], SFmode))
3744     operands[1] = force_reg (SFmode, operands[1]);
3747 (define_expand "movdf"
3748   [(set (match_operand:DF 0 "nonimmediate_operand" "")
3749         (match_operand:DF 1 "general_operand" ""))]
3750   ""
3751   "
3753   if (GET_CODE (operands[0]) == MEM
3754       && ! reg_or_fp0_operand (operands[1], DFmode))
3755     operands[1] = force_reg (DFmode, operands[1]);
3758 (define_insn ""
3759   [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,r,r,r,r,m,f,f,f,m")
3760         (match_operand:SI 1 "input_operand" "r,J,I,K,L,m,rJ,f,J,m,fG"))]
3761   "! TARGET_WINDOWS_NT && ! TARGET_OPEN_VMS && ! TARGET_CIX
3762    && (register_operand (operands[0], SImode)
3763        || reg_or_0_operand (operands[1], SImode))"
3764   "@
3765    bis %1,%1,%0
3766    bis $31,$31,%0
3767    bis $31,%1,%0
3768    lda %0,%1
3769    ldah %0,%h1
3770    ldl %0,%1
3771    stl %r1,%0
3772    cpys %1,%1,%0
3773    cpys $f31,$f31,%0
3774    ld%, %0,%1
3775    st%, %R1,%0"
3776   [(set_attr "type" "ilog,ilog,ilog,iadd,iadd,ld,st,fcpys,fcpys,ld,st")])
3778 (define_insn ""
3779   [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,r,r,r,r,m,f,f,f,m,r,f")
3780         (match_operand:SI 1 "input_operand" "r,J,I,K,L,m,rJ,f,J,m,fG,f,r"))]
3781   "! TARGET_WINDOWS_NT && ! TARGET_OPEN_VMS && TARGET_CIX
3782    && (register_operand (operands[0], SImode)
3783        || reg_or_0_operand (operands[1], SImode))"
3784   "@
3785    bis %1,%1,%0
3786    bis $31,$31,%0
3787    bis $31,%1,%0
3788    lda %0,%1
3789    ldah %0,%h1
3790    ldl %0,%1
3791    stl %r1,%0
3792    cpys %1,%1,%0
3793    cpys $f31,$f31,%0
3794    ld%, %0,%1
3795    st%, %R1,%0
3796    ftois %1,%0
3797    itof%, %1,%0"
3798   [(set_attr "type" "ilog,ilog,ilog,iadd,iadd,ld,st,fcpys,fcpys,ld,st,ld,st")])
3800 (define_insn ""
3801   [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,r,r,r,r,r,m,f,f,f,m")
3802         (match_operand:SI 1 "input_operand" "r,J,I,K,L,s,m,rJ,f,J,m,fG"))]
3803   "(TARGET_WINDOWS_NT || TARGET_OPEN_VMS)
3804     && (register_operand (operands[0], SImode)
3805         || reg_or_0_operand (operands[1], SImode))"
3806   "@
3807    bis %1,%1,%0
3808    bis $31,$31,%0
3809    bis $31,%1,%0
3810    lda %0,%1
3811    ldah %0,%h1
3812    lda %0,%1
3813    ldl %0,%1
3814    stl %r1,%0
3815    cpys %1,%1,%0
3816    cpys $f31,$f31,%0
3817    ld%, %0,%1
3818    st%, %R1,%0"
3819   [(set_attr "type" "ilog,ilog,ilog,iadd,iadd,ldsym,ld,st,fcpys,fcpys,ld,st")])
3821 (define_insn ""
3822   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,r,f,f")
3823         (match_operand:HI 1 "input_operand" "r,J,I,n,f,J"))]
3824   "! TARGET_BWX
3825    && (register_operand (operands[0], HImode)
3826        || register_operand (operands[1], HImode))"
3827   "@
3828    bis %1,%1,%0
3829    bis $31,$31,%0
3830    bis $31,%1,%0
3831    lda %0,%L1
3832    cpys %1,%1,%0
3833    cpys $f31,$f31,%0"
3834   [(set_attr "type" "ilog,ilog,ilog,iadd,fcpys,fcpys")])
3836 (define_insn ""
3837   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,r,r,m,f,f")
3838         (match_operand:HI 1 "input_operand" "r,J,I,n,m,rJ,f,J"))]
3839   "TARGET_BWX
3840    && (register_operand (operands[0], HImode)
3841        || reg_or_0_operand (operands[1], HImode))"
3842   "@
3843    bis %1,%1,%0
3844    bis $31,$31,%0
3845    bis $31,%1,%0
3846    lda %0,%L1
3847    ldwu %0,%1
3848    stw %r1,%0
3849    cpys %1,%1,%0
3850    cpys $f31,$f31,%0"
3851   [(set_attr "type" "ilog,ilog,ilog,iadd,ld,st,fcpys,fcpys")])
3853 (define_insn ""
3854   [(set (match_operand:QI 0 "nonimmediate_operand" "=r,r,r,r,f,f")
3855         (match_operand:QI 1 "input_operand" "r,J,I,n,f,J"))]
3856   "! TARGET_BWX
3857    && (register_operand (operands[0], QImode)
3858        || register_operand (operands[1], QImode))"
3859   "@
3860    bis %1,%1,%0
3861    bis $31,$31,%0
3862    bis $31,%1,%0
3863    lda %0,%L1
3864    cpys %1,%1,%0
3865    cpys $f31,$f31,%0"
3866   [(set_attr "type" "ilog,ilog,ilog,iadd,fcpys,fcpys")])
3868 (define_insn ""
3869   [(set (match_operand:QI 0 "nonimmediate_operand" "=r,r,r,r,r,m,f,f")
3870         (match_operand:QI 1 "input_operand" "r,J,I,n,m,rJ,f,J"))]
3871   "TARGET_BWX
3872    && (register_operand (operands[0], QImode)
3873        || reg_or_0_operand (operands[1], QImode))"
3874   "@
3875    bis %1,%1,%0
3876    bis $31,$31,%0
3877    bis $31,%1,%0
3878    lda %0,%L1
3879    ldbu %0,%1
3880    stb %r1,%0
3881    cpys %1,%1,%0
3882    cpys $f31,$f31,%0"
3883   [(set_attr "type" "ilog,ilog,ilog,iadd,ld,st,fcpys,fcpys")])
3885 ;; We do two major things here: handle mem->mem and construct long
3886 ;; constants.
3888 (define_expand "movsi"
3889   [(set (match_operand:SI 0 "general_operand" "")
3890         (match_operand:SI 1 "general_operand" ""))]
3891   ""
3892   "
3894   if (GET_CODE (operands[0]) == MEM
3895       && ! reg_or_0_operand (operands[1], SImode))
3896     operands[1] = force_reg (SImode, operands[1]);
3898   if (! CONSTANT_P (operands[1]) || input_operand (operands[1], SImode))
3899     ;
3900   else if (GET_CODE (operands[1]) == CONST_INT)
3901     {
3902       operands[1]
3903         = alpha_emit_set_const (operands[0], SImode, INTVAL (operands[1]), 3);
3904       if (rtx_equal_p (operands[0], operands[1]))
3905         DONE;
3906     }
3909 ;; Split a load of a large constant into the appropriate two-insn
3910 ;; sequence.
3912 (define_split
3913   [(set (match_operand:SI 0 "register_operand" "")
3914         (match_operand:SI 1 "const_int_operand" ""))]
3915   "! add_operand (operands[1], SImode)"
3916   [(set (match_dup 0) (match_dup 2))
3917    (set (match_dup 0) (plus:SI (match_dup 0) (match_dup 3)))]
3918   "
3919 { rtx tem
3920     = alpha_emit_set_const (operands[0], SImode, INTVAL (operands[1]), 2);
3922   if (tem == operands[0])
3923     DONE;
3924   else
3925     FAIL;
3928 (define_insn ""
3929   [(set (match_operand:DI 0 "general_operand" "=r,r,r,r,r,r,r,m,f,f,f,Q")
3930         (match_operand:DI 1 "input_operand" "r,J,I,K,L,s,m,rJ,f,J,Q,fG"))]
3931   "! TARGET_CIX
3932    && (register_operand (operands[0], DImode)
3933        || reg_or_0_operand (operands[1], DImode))"
3934   "@
3935    bis %1,%1,%0
3936    bis $31,$31,%0
3937    bis $31,%1,%0
3938    lda %0,%1
3939    ldah %0,%h1
3940    lda %0,%1
3941    ldq%A1 %0,%1
3942    stq%A0 %r1,%0
3943    cpys %1,%1,%0
3944    cpys $f31,$f31,%0
3945    ldt %0,%1
3946    stt %R1,%0"
3947   [(set_attr "type" "ilog,ilog,ilog,iadd,iadd,ldsym,ld,st,fcpys,fcpys,ld,st")])
3949 (define_insn ""
3950   [(set (match_operand:DI 0 "general_operand" "=r,r,r,r,r,r,r,m,f,f,f,Q,r,f")
3951         (match_operand:DI 1 "input_operand" "r,J,I,K,L,s,m,rJ,f,J,Q,fG,f,r"))]
3952   "TARGET_CIX
3953    && (register_operand (operands[0], DImode)
3954        || reg_or_0_operand (operands[1], DImode))"
3955   "@
3956    bis %1,%1,%0
3957    bis $31,$31,%0
3958    bis $31,%1,%0
3959    lda %0,%1
3960    ldah %0,%h1
3961    lda %0,%1
3962    ldq%A1 %0,%1
3963    stq%A0 %r1,%0
3964    cpys %1,%1,%0
3965    cpys $f31,$f31,%0
3966    ldt %0,%1
3967    stt %R1,%0
3968    ftoit %1,%0
3969    itoft %1,%0"
3970   [(set_attr "type" "ilog,ilog,ilog,iadd,iadd,ldsym,ld,st,fcpys,fcpys,ld,st,ld,st")])
3972 ;; We do three major things here: handle mem->mem, put 64-bit constants in
3973 ;; memory, and construct long 32-bit constants.
3975 (define_expand "movdi"
3976   [(set (match_operand:DI 0 "general_operand" "")
3977         (match_operand:DI 1 "general_operand" ""))]
3978   ""
3979   "
3981   rtx tem;
3983   if (GET_CODE (operands[0]) == MEM
3984       && ! reg_or_0_operand (operands[1], DImode))
3985     operands[1] = force_reg (DImode, operands[1]);
3987   if (! CONSTANT_P (operands[1]) || input_operand (operands[1], DImode))
3988     ;
3989   else if (GET_CODE (operands[1]) == CONST_INT
3990            && (tem = alpha_emit_set_const (operands[0], DImode,
3991                                            INTVAL (operands[1]), 3)) != 0)
3992     {
3993       if (rtx_equal_p (tem, operands[0]))
3994         DONE;
3995       else
3996         operands[1] = tem;
3997     }
3998   else if (TARGET_BUILD_CONSTANTS
3999            && GET_CODE (operands[1]) == CONST_INT)
4000     {
4001 #if HOST_BITS_PER_WIDE_INT == 64
4002       tem = alpha_emit_set_long_const (operands[0], INTVAL (operands[1]));
4003       if (rtx_equal_p (tem, operands[0]))
4004         DONE;
4005       else
4006         operands[1] = tem;
4007 #else
4008       abort();
4009 #endif
4010     }
4011   else if (CONSTANT_P (operands[1]))
4012     {
4013       operands[1] = force_const_mem (DImode, operands[1]);
4014       if (reload_in_progress)
4015         {
4016           emit_move_insn (operands[0], XEXP (operands[1], 0));
4017           operands[1] = copy_rtx (operands[1]);
4018           XEXP (operands[1], 0) = operands[0];
4019         }
4020       else
4021         operands[1] = validize_mem (operands[1]);
4022     }
4023   else
4024     abort ();
4027 ;; Split a load of a large constant into the appropriate two-insn
4028 ;; sequence.
4030 (define_split
4031   [(set (match_operand:DI 0 "register_operand" "")
4032         (match_operand:DI 1 "const_int_operand" ""))]
4033   "! add_operand (operands[1], DImode)"
4034   [(set (match_dup 0) (match_dup 2))
4035    (set (match_dup 0) (plus:DI (match_dup 0) (match_dup 3)))]
4036   "
4037 { rtx tem
4038     = alpha_emit_set_const (operands[0], DImode, INTVAL (operands[1]), 2);
4040   if (tem == operands[0])
4041     DONE;
4042   else
4043     FAIL;
4046 ;; These are the partial-word cases.
4048 ;; First we have the code to load an aligned word.  Operand 0 is the register
4049 ;; in which to place the result.  It's mode is QImode or HImode.  Operand 1
4050 ;; is an SImode MEM at the low-order byte of the proper word.  Operand 2 is the
4051 ;; number of bits within the word that the value is.  Operand 3 is an SImode
4052 ;; scratch register.  If operand 0 is a hard register, operand 3 may be the
4053 ;; same register.  It is allowed to conflict with operand 1 as well.
4055 (define_expand "aligned_loadqi"
4056   [(set (match_operand:SI 3 "register_operand" "")
4057         (match_operand:SI 1 "memory_operand" ""))
4058    (set (subreg:DI (match_operand:QI 0 "register_operand" "") 0)
4059         (zero_extract:DI (subreg:DI (match_dup 3) 0)
4060                          (const_int 8)
4061                          (match_operand:DI 2 "const_int_operand" "")))]
4062          
4063   ""
4064   "")
4065   
4066 (define_expand "aligned_loadhi"
4067   [(set (match_operand:SI 3 "register_operand" "")
4068         (match_operand:SI 1 "memory_operand" ""))
4069    (set (subreg:DI (match_operand:HI 0 "register_operand" "") 0)
4070         (zero_extract:DI (subreg:DI (match_dup 3) 0)
4071                          (const_int 16)
4072                          (match_operand:DI 2 "const_int_operand" "")))]
4073          
4074   ""
4075   "")
4076   
4077 ;; Similar for unaligned loads, where we use the sequence from the
4078 ;; Alpha Architecture manual.
4080 ;; Operand 1 is the address.  Operands 2 and 3 are temporaries, where
4081 ;; operand 3 can overlap the input and output registers.
4083 (define_expand "unaligned_loadqi"
4084   [(set (match_operand:DI 2 "register_operand" "")
4085         (mem:DI (and:DI (match_operand:DI 1 "address_operand" "")
4086                         (const_int -8))))
4087    (set (match_operand:DI 3 "register_operand" "")
4088         (match_dup 1))
4089    (set (subreg:DI (match_operand:QI 0 "register_operand" "") 0)
4090         (zero_extract:DI (match_dup 2)
4091                          (const_int 8)
4092                          (ashift:DI (match_dup 3) (const_int 3))))]
4093   ""
4094   "")
4096 (define_expand "unaligned_loadhi"
4097   [(set (match_operand:DI 2 "register_operand" "")
4098         (mem:DI (and:DI (match_operand:DI 1 "address_operand" "")
4099                         (const_int -8))))
4100    (set (match_operand:DI 3 "register_operand" "")
4101         (match_dup 1))
4102    (set (subreg:DI (match_operand:QI 0 "register_operand" "") 0)
4103         (zero_extract:DI (match_dup 2)
4104                          (const_int 16)
4105                          (ashift:DI (match_dup 3) (const_int 3))))]
4106   ""
4107   "")
4109 ;; Storing an aligned byte or word requires two temporaries.  Operand 0 is the
4110 ;; aligned SImode MEM.  Operand 1 is the register containing the 
4111 ;; byte or word to store.  Operand 2 is the number of bits within the word that
4112 ;; the value should be placed.  Operands 3 and 4 are SImode temporaries.
4114 (define_expand "aligned_store"
4115   [(set (match_operand:SI 3 "register_operand" "")
4116         (match_operand:SI 0 "memory_operand" ""))
4117    (set (subreg:DI (match_dup 3) 0)
4118         (and:DI (subreg:DI (match_dup 3) 0) (match_dup 5)))
4119    (set (subreg:DI (match_operand:SI 4 "register_operand" "") 0)
4120         (ashift:DI (zero_extend:DI (match_operand 1 "register_operand" ""))
4121                    (match_operand:DI 2 "const_int_operand" "")))
4122    (set (subreg:DI (match_dup 4) 0)
4123         (ior:DI (subreg:DI (match_dup 4) 0) (subreg:DI (match_dup 3) 0)))
4124    (set (match_dup 0) (match_dup 4))]
4125   ""
4126   "
4127 { operands[5] = GEN_INT (~ (GET_MODE_MASK (GET_MODE (operands[1]))
4128                             << INTVAL (operands[2])));
4131 ;; For the unaligned byte and halfword cases, we use code similar to that
4132 ;; in the ;; Architecture book, but reordered to lower the number of registers
4133 ;; required.  Operand 0 is the address.  Operand 1 is the data to store.
4134 ;; Operands 2, 3, and 4 are DImode temporaries, where operands 2 and 4 may
4135 ;; be the same temporary, if desired.  If the address is in a register,
4136 ;; operand 2 can be that register.
4138 (define_expand "unaligned_storeqi"
4139   [(set (match_operand:DI 3 "register_operand" "")
4140         (mem:DI (and:DI (match_operand:DI 0 "address_operand" "")
4141                         (const_int -8))))
4142    (set (match_operand:DI 2 "register_operand" "")
4143         (match_dup 0))
4144    (set (match_dup 3)
4145         (and:DI (not:DI (ashift:DI (const_int 255)
4146                                    (ashift:DI (match_dup 2) (const_int 3))))
4147                 (match_dup 3)))
4148    (set (match_operand:DI 4 "register_operand" "")
4149         (ashift:DI (zero_extend:DI (match_operand:QI 1 "register_operand" ""))
4150                    (ashift:DI (match_dup 2) (const_int 3))))
4151    (set (match_dup 4) (ior:DI (match_dup 4) (match_dup 3)))
4152    (set (mem:DI (and:DI (match_dup 0) (const_int -8)))
4153         (match_dup 4))]
4154   ""
4155   "")
4157 (define_expand "unaligned_storehi"
4158   [(set (match_operand:DI 3 "register_operand" "")
4159         (mem:DI (and:DI (match_operand:DI 0 "address_operand" "")
4160                         (const_int -8))))
4161    (set (match_operand:DI 2 "register_operand" "")
4162         (match_dup 0))
4163    (set (match_dup 3)
4164         (and:DI (not:DI (ashift:DI (const_int 65535)
4165                                    (ashift:DI (match_dup 2) (const_int 3))))
4166                 (match_dup 3)))
4167    (set (match_operand:DI 4 "register_operand" "")
4168         (ashift:DI (zero_extend:DI (match_operand:HI 1 "register_operand" ""))
4169                    (ashift:DI (match_dup 2) (const_int 3))))
4170    (set (match_dup 4) (ior:DI (match_dup 4) (match_dup 3)))
4171    (set (mem:DI (and:DI (match_dup 0) (const_int -8)))
4172         (match_dup 4))]
4173   ""
4174   "")
4176 ;; Here are the define_expand's for QI and HI moves that use the above
4177 ;; patterns.  We have the normal sets, plus the ones that need scratch
4178 ;; registers for reload.
4180 (define_expand "movqi"
4181   [(set (match_operand:QI 0 "general_operand" "")
4182         (match_operand:QI 1 "general_operand" ""))]
4183   ""
4184   "
4185 { extern rtx get_unaligned_address ();
4187   if (TARGET_BWX)
4188     {
4189       if (GET_CODE (operands[0]) == MEM
4190           && ! reg_or_0_operand (operands[1], QImode))
4191         operands[1] = force_reg (QImode, operands[1]);
4193       if (GET_CODE (operands[1]) == CONST_INT
4194                && ! input_operand (operands[1], QImode))
4195         {
4196           operands[1] = alpha_emit_set_const (operands[0], QImode,
4197                                               INTVAL (operands[1]), 3);
4199           if (rtx_equal_p (operands[0], operands[1]))
4200             DONE;
4201         }
4203       goto def;
4204     }
4206   /* If the output is not a register, the input must be.  */
4207   if (GET_CODE (operands[0]) == MEM)
4208     operands[1] = force_reg (QImode, operands[1]);
4210   /* Handle four memory cases, unaligned and aligned for either the input
4211      or the output.  The only case where we can be called during reload is
4212      for aligned loads; all other cases require temporaries.  */
4214   if (GET_CODE (operands[1]) == MEM
4215       || (GET_CODE (operands[1]) == SUBREG
4216           && GET_CODE (SUBREG_REG (operands[1])) == MEM)
4217       || (reload_in_progress && GET_CODE (operands[1]) == REG
4218           && REGNO (operands[1]) >= FIRST_PSEUDO_REGISTER)
4219       || (reload_in_progress && GET_CODE (operands[1]) == SUBREG
4220           && GET_CODE (SUBREG_REG (operands[1])) == REG
4221           && REGNO (SUBREG_REG (operands[1])) >= FIRST_PSEUDO_REGISTER))
4222     {
4223       if (aligned_memory_operand (operands[1], QImode))
4224         {
4225           rtx aligned_mem, bitnum;
4226           rtx scratch = (reload_in_progress
4227                          ? gen_rtx (REG, SImode, REGNO (operands[0]))
4228                          : gen_reg_rtx (SImode));
4230           get_aligned_mem (operands[1], &aligned_mem, &bitnum);
4232           emit_insn (gen_aligned_loadqi (operands[0], aligned_mem, bitnum,
4233                                          scratch));
4234         }
4235       else
4236         {
4237           /* Don't pass these as parameters since that makes the generated
4238              code depend on parameter evaluation order which will cause
4239              bootstrap failures.  */
4241           rtx temp1 = gen_reg_rtx (DImode);
4242           rtx temp2 = gen_reg_rtx (DImode);
4243           rtx seq
4244             = gen_unaligned_loadqi (operands[0],
4245                                     get_unaligned_address (operands[1], 0),
4246                                     temp1, temp2);
4248           alpha_set_memflags (seq, operands[1]);
4249           emit_insn (seq);
4250         }
4252       DONE;
4253     }
4255   else if (GET_CODE (operands[0]) == MEM
4256            || (GET_CODE (operands[0]) == SUBREG 
4257                && GET_CODE (SUBREG_REG (operands[0])) == MEM)
4258            || (reload_in_progress && GET_CODE (operands[0]) == REG
4259                && REGNO (operands[0]) >= FIRST_PSEUDO_REGISTER)
4260            || (reload_in_progress && GET_CODE (operands[0]) == SUBREG
4261                && GET_CODE (SUBREG_REG (operands[0])) == REG
4262                && REGNO (operands[0]) >= FIRST_PSEUDO_REGISTER))
4263     {
4264       if (aligned_memory_operand (operands[0], QImode))
4265         {
4266           rtx aligned_mem, bitnum;
4267           rtx temp1 = gen_reg_rtx (SImode);
4268           rtx temp2 = gen_reg_rtx (SImode);
4270           get_aligned_mem (operands[0], &aligned_mem, &bitnum);
4272           emit_insn (gen_aligned_store (aligned_mem, operands[1], bitnum,
4273                                         temp1, temp2));
4274         }
4275       else
4276         {
4277           rtx temp1 = gen_reg_rtx (DImode);
4278           rtx temp2 = gen_reg_rtx (DImode);
4279           rtx temp3 = gen_reg_rtx (DImode);
4280           rtx seq
4281             = gen_unaligned_storeqi (get_unaligned_address (operands[0], 0),
4282                                            operands[1], temp1, temp2, temp3);
4284           alpha_set_memflags (seq, operands[0]);
4285           emit_insn (seq);
4286         }
4287       DONE;
4288     }
4289  def:;
4292 (define_expand "movhi"
4293   [(set (match_operand:HI 0 "general_operand" "")
4294         (match_operand:HI 1 "general_operand" ""))]
4295   ""
4296   "
4297 { extern rtx get_unaligned_address ();
4299   if (TARGET_BWX)
4300     {
4301       if (GET_CODE (operands[0]) == MEM
4302           && ! reg_or_0_operand (operands[1], HImode))
4303         operands[1] = force_reg (HImode, operands[1]);
4305       if (GET_CODE (operands[1]) == CONST_INT
4306                && ! input_operand (operands[1], HImode))
4307         {
4308           operands[1] = alpha_emit_set_const (operands[0], HImode,
4309                                               INTVAL (operands[1]), 3);
4311           if (rtx_equal_p (operands[0], operands[1]))
4312             DONE;
4313         }
4315       goto def;
4316     }
4318   /* If the output is not a register, the input must be.  */
4319   if (GET_CODE (operands[0]) == MEM)
4320     operands[1] = force_reg (HImode, operands[1]);
4322   /* Handle four memory cases, unaligned and aligned for either the input
4323      or the output.  The only case where we can be called during reload is
4324      for aligned loads; all other cases require temporaries.  */
4326   if (GET_CODE (operands[1]) == MEM
4327       || (GET_CODE (operands[1]) == SUBREG
4328           && GET_CODE (SUBREG_REG (operands[1])) == MEM)
4329       || (reload_in_progress && GET_CODE (operands[1]) == REG
4330           && REGNO (operands[1]) >= FIRST_PSEUDO_REGISTER)
4331       || (reload_in_progress && GET_CODE (operands[1]) == SUBREG
4332           && GET_CODE (SUBREG_REG (operands[1])) == REG
4333           && REGNO (SUBREG_REG (operands[1])) >= FIRST_PSEUDO_REGISTER))
4334     {
4335       if (aligned_memory_operand (operands[1], HImode))
4336         {
4337           rtx aligned_mem, bitnum;
4338           rtx scratch = (reload_in_progress
4339                          ? gen_rtx (REG, SImode, REGNO (operands[0]))
4340                          : gen_reg_rtx (SImode));
4342           get_aligned_mem (operands[1], &aligned_mem, &bitnum);
4344           emit_insn (gen_aligned_loadhi (operands[0], aligned_mem, bitnum,
4345                                          scratch));
4346         }
4347       else
4348         {
4349           /* Don't pass these as parameters since that makes the generated
4350              code depend on parameter evaluation order which will cause
4351              bootstrap failures.  */
4353           rtx temp1 = gen_reg_rtx (DImode);
4354           rtx temp2 = gen_reg_rtx (DImode);
4355           rtx seq
4356             = gen_unaligned_loadhi (operands[0],
4357                                     get_unaligned_address (operands[1], 0),
4358                                     temp1, temp2);
4360           alpha_set_memflags (seq, operands[1]);
4361           emit_insn (seq);
4362         }
4364       DONE;
4365     }
4367   else if (GET_CODE (operands[0]) == MEM
4368            || (GET_CODE (operands[0]) == SUBREG 
4369                && GET_CODE (SUBREG_REG (operands[0])) == MEM)
4370            || (reload_in_progress && GET_CODE (operands[0]) == REG
4371                && REGNO (operands[0]) >= FIRST_PSEUDO_REGISTER)
4372            || (reload_in_progress && GET_CODE (operands[0]) == SUBREG
4373                && GET_CODE (SUBREG_REG (operands[0])) == REG
4374                && REGNO (operands[0]) >= FIRST_PSEUDO_REGISTER))
4375     {
4376       if (aligned_memory_operand (operands[0], HImode))
4377         {
4378           rtx aligned_mem, bitnum;
4379           rtx temp1 = gen_reg_rtx (SImode);
4380           rtx temp2 = gen_reg_rtx (SImode);
4382           get_aligned_mem (operands[0], &aligned_mem, &bitnum);
4384           emit_insn (gen_aligned_store (aligned_mem, operands[1], bitnum,
4385                                         temp1, temp2));
4386         }
4387       else
4388         {
4389           rtx temp1 = gen_reg_rtx (DImode);
4390           rtx temp2 = gen_reg_rtx (DImode);
4391           rtx temp3 = gen_reg_rtx (DImode);
4392           rtx seq
4393             = gen_unaligned_storehi (get_unaligned_address (operands[0], 0),
4394                                      operands[1], temp1, temp2, temp3);
4396           alpha_set_memflags (seq, operands[0]);
4397           emit_insn (seq);
4398         }
4400       DONE;
4401     }
4402  def:;
4405 ;; Here are the versions for reload.  Note that in the unaligned cases
4406 ;; we know that the operand must not be a pseudo-register because stack
4407 ;; slots are always aligned references.
4409 (define_expand "reload_inqi"
4410   [(parallel [(match_operand:QI 0 "register_operand" "=r")
4411               (match_operand:QI 1 "unaligned_memory_operand" "m")
4412               (match_operand:TI 2 "register_operand" "=&r")])]
4413   "! TARGET_BWX"
4414   "
4415 { extern rtx get_unaligned_address ();
4416   rtx addr = get_unaligned_address (operands[1], 0);
4417   /* It is possible that one of the registers we got for operands[2]
4418      might coincide with that of operands[0] (which is why we made
4419      it TImode).  Pick the other one to use as our scratch.  */
4420   rtx scratch = gen_rtx (REG, DImode,
4421                          REGNO (operands[0]) == REGNO (operands[2]) 
4422                          ? REGNO (operands[2]) + 1 : REGNO (operands[2]));
4423   rtx seq = gen_unaligned_loadqi (operands[0], addr, scratch,
4424                                   gen_rtx (REG, DImode, REGNO (operands[0])));
4426   alpha_set_memflags (seq, operands[1]);
4427   emit_insn (seq);
4428   DONE;
4431 (define_expand "reload_inhi"
4432   [(parallel [(match_operand:HI 0 "register_operand" "=r")
4433               (match_operand:HI 1 "unaligned_memory_operand" "m")
4434               (match_operand:TI 2 "register_operand" "=&r")])]
4435   "! TARGET_BWX"
4436   "
4437 { extern rtx get_unaligned_address ();
4438   rtx addr = get_unaligned_address (operands[1], 0);
4439   /* It is possible that one of the registers we got for operands[2]
4440      might coincide with that of operands[0] (which is why we made
4441      it TImode).  Pick the other one to use as our scratch.  */
4442   rtx scratch = gen_rtx (REG, DImode,
4443                          REGNO (operands[0]) == REGNO (operands[2]) 
4444                          ? REGNO (operands[2]) + 1 : REGNO (operands[2]));
4445   rtx seq = gen_unaligned_loadhi (operands[0], addr, scratch,
4446                                   gen_rtx (REG, DImode, REGNO (operands[0])));
4448   alpha_set_memflags (seq, operands[1]);
4449   emit_insn (seq);
4450   DONE;
4453 (define_expand "reload_outqi"
4454   [(parallel [(match_operand:QI 0 "any_memory_operand" "=m")
4455               (match_operand:QI 1 "register_operand" "r")
4456               (match_operand:TI 2 "register_operand" "=&r")])]
4457   "! TARGET_BWX"
4458   "
4459 { extern rtx get_unaligned_address ();
4461   if (aligned_memory_operand (operands[0], QImode))
4462     {
4463       rtx aligned_mem, bitnum;
4465       get_aligned_mem (operands[0], &aligned_mem, &bitnum);
4467       emit_insn (gen_aligned_store (aligned_mem, operands[1], bitnum,
4468                                     gen_rtx (REG, SImode, REGNO (operands[2])),
4469                                     gen_rtx (REG, SImode,
4470                                              REGNO (operands[2]) + 1)));
4471     }
4472   else
4473     {
4474       rtx addr = get_unaligned_address (operands[0], 0);
4475       rtx scratch1 = gen_rtx (REG, DImode, REGNO (operands[2]));
4476       rtx scratch2 = gen_rtx (REG, DImode, REGNO (operands[2]) + 1);
4477       rtx scratch3 = scratch1;
4478       rtx seq;
4480       if (GET_CODE (addr) == REG)
4481         scratch1 = addr;
4483       seq = gen_unaligned_storeqi (addr, operands[1], scratch1,
4484                                    scratch2, scratch3);
4485       alpha_set_memflags (seq, operands[0]);
4486       emit_insn (seq);
4487     }
4489   DONE;
4492 (define_expand "reload_outhi"
4493   [(parallel [(match_operand:HI 0 "any_memory_operand" "=m")
4494               (match_operand:HI 1 "register_operand" "r")
4495               (match_operand:TI 2 "register_operand" "=&r")])]
4496   "! TARGET_BWX"
4497   "
4498 { extern rtx get_unaligned_address ();
4500   if (aligned_memory_operand (operands[0], HImode))
4501     {
4502       rtx aligned_mem, bitnum;
4504       get_aligned_mem (operands[0], &aligned_mem, &bitnum);
4506       emit_insn (gen_aligned_store (aligned_mem, operands[1], bitnum,
4507                                     gen_rtx (REG, SImode, REGNO (operands[2])),
4508                                     gen_rtx (REG, SImode,
4509                                              REGNO (operands[2]) + 1)));
4510     }
4511   else
4512     {
4513       rtx addr = get_unaligned_address (operands[0], 0);
4514       rtx scratch1 = gen_rtx (REG, DImode, REGNO (operands[2]));
4515       rtx scratch2 = gen_rtx (REG, DImode, REGNO (operands[2]) + 1);
4516       rtx scratch3 = scratch1;
4517       rtx seq;
4519       if (GET_CODE (addr) == REG)
4520         scratch1 = addr;
4522       seq = gen_unaligned_storehi (addr, operands[1], scratch1,
4523                                    scratch2, scratch3);
4524       alpha_set_memflags (seq, operands[0]);
4525       emit_insn (seq);
4526     }
4528   DONE;
4531 ;; Subroutine of stack space allocation.  Perform a stack probe.
4532 (define_expand "probe_stack"
4533   [(set (match_dup 1) (match_operand:DI 0 "const_int_operand" ""))]
4534   ""
4535   "
4537   operands[1] = gen_rtx (MEM, DImode, plus_constant (stack_pointer_rtx,
4538                                                      INTVAL (operands[0])));
4539   MEM_VOLATILE_P (operands[1]) = 1;
4541   operands[0] = const0_rtx;
4544 ;; This is how we allocate stack space.  If we are allocating a
4545 ;; constant amount of space and we know it is less than 4096
4546 ;; bytes, we need do nothing.
4548 ;; If it is more than 4096 bytes, we need to probe the stack
4549 ;; periodically. 
4550 (define_expand "allocate_stack"
4551   [(set (reg:DI 30)
4552         (plus:DI (reg:DI 30)
4553                  (match_operand:DI 1 "reg_or_cint_operand" "")))
4554    (set (match_operand:DI 0 "register_operand" "=r")
4555         (match_dup 2))]
4556   ""
4557   "
4559   if (GET_CODE (operands[1]) == CONST_INT
4560       && INTVAL (operands[1]) < 32768)
4561     {
4562       if (INTVAL (operands[1]) >= 4096)
4563         {
4564           /* We do this the same way as in the prologue and generate explicit
4565              probes.  Then we update the stack by the constant.  */
4567           int probed = 4096;
4569           emit_insn (gen_probe_stack (GEN_INT (- probed)));
4570           while (probed + 8192 < INTVAL (operands[1]))
4571             emit_insn (gen_probe_stack (GEN_INT (- (probed += 8192))));
4573           if (probed + 4096 < INTVAL (operands[1]))
4574             emit_insn (gen_probe_stack (GEN_INT (- INTVAL(operands[1]))));
4575         }
4577       operands[1] = GEN_INT (- INTVAL (operands[1]));
4578       operands[2] = virtual_stack_dynamic_rtx;
4579     }
4580   else
4581     {
4582       rtx out_label = 0;
4583       rtx loop_label = gen_label_rtx ();
4584       rtx want = gen_reg_rtx (Pmode);
4585       rtx tmp = gen_reg_rtx (Pmode);
4586       rtx memref;
4588       emit_insn (gen_subdi3 (want, stack_pointer_rtx,
4589                              force_reg (Pmode, operands[1])));
4590       emit_insn (gen_adddi3 (tmp, stack_pointer_rtx, GEN_INT (-4096)));
4592       if (GET_CODE (operands[1]) != CONST_INT)
4593         {
4594           out_label = gen_label_rtx ();
4595           emit_insn (gen_cmpdi (want, tmp));
4596           emit_jump_insn (gen_bgeu (out_label));
4597         }
4599       emit_label (loop_label);
4600       memref = gen_rtx (MEM, DImode, tmp);
4601       MEM_VOLATILE_P (memref) = 1;
4602       emit_move_insn (memref, const0_rtx);
4603       emit_insn (gen_adddi3 (tmp, tmp, GEN_INT(-8192)));
4604       emit_insn (gen_cmpdi (tmp, want));
4605       emit_jump_insn (gen_bgtu (loop_label));
4606       if (obey_regdecls)
4607         gen_rtx (USE, VOIDmode, tmp);
4609       memref = gen_rtx (MEM, DImode, want);
4610       MEM_VOLATILE_P (memref) = 1;
4611       emit_move_insn (memref, const0_rtx);
4613       if (out_label)
4614         emit_label (out_label);
4616       emit_move_insn (stack_pointer_rtx, want);
4617       emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
4618       DONE;
4619     }
4622 (define_insn "exception_receiver"
4623   [(unspec_volatile [(const_int 0)] 2)]
4624   "! TARGET_OPEN_VMS && ! TARGET_WINDOWS_NT"
4625   ".long 0xc3a00000\;ldgp $29,0($29)")
4627 (define_expand "nonlocal_goto_receiver"
4628   [(unspec_volatile [(const_int 0)] 1)
4629    (set (reg:DI 27) (mem:DI (reg:DI 29)))
4630    (unspec_volatile [(const_int 0)] 1)
4631    (use (reg:DI 27))]
4632   "TARGET_OPEN_VMS"
4633   "")
4635 (define_insn "arg_home"
4636   [(unspec [(const_int 0)] 0)
4637    (use (reg:DI 1))
4638    (use (reg:DI 25))
4639    (use (reg:DI 16))
4640    (use (reg:DI 17))
4641    (use (reg:DI 18))
4642    (use (reg:DI 19))
4643    (use (reg:DI 20))
4644    (use (reg:DI 21))
4645    (use (reg:DI 48))
4646    (use (reg:DI 49))
4647    (use (reg:DI 50))
4648    (use (reg:DI 51))
4649    (use (reg:DI 52))
4650    (use (reg:DI 53))
4651    (clobber (mem:BLK (const_int 0)))
4652    (clobber (reg:DI 24))
4653    (clobber (reg:DI 25))
4654    (clobber (reg:DI 0))]
4655   "TARGET_OPEN_VMS"
4656   "lda $0,ots$home_args\;ldq $0,8($0)\;jsr $0,ots$home_args")