1 ;; Machine description for DEC Alpha for GNU C compiler
2 ;; Copyright (C) 1992, 1993, 1994, 1995, 1996 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)
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"
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
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 complention
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
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"))
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"))
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"))
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"))
82 (define_function_unit "ev4_ebox" 1 0
83 (and (eq_attr "cpu" "ev4")
84 (eq_attr "type" "imulq"))
87 (define_function_unit "ev4_imult" 1 0
88 (and (eq_attr "cpu" "ev4")
89 (eq_attr "type" "imull"))
92 (define_function_unit "ev4_imult" 1 0
93 (and (eq_attr "cpu" "ev4")
94 (eq_attr "type" "imulq"))
97 (define_function_unit "ev4_fbox" 1 0
98 (and (eq_attr "cpu" "ev4")
99 (eq_attr "type" "fadd,fmul,fcpys"))
102 (define_function_unit "ev4_fbox" 1 0
103 (and (eq_attr "cpu" "ev4")
104 (eq_attr "type" "fdivs"))
107 (define_function_unit "ev4_fbox" 1 0
108 (and (eq_attr "cpu" "ev4")
109 (eq_attr "type" "fdivt"))
112 (define_function_unit "ev4_divider" 1 0
113 (and (eq_attr "cpu" "ev4")
114 (eq_attr "type" "fdivs"))
117 (define_function_unit "ev4_divider" 1 0
118 (and (eq_attr "cpu" "ev4")
119 (eq_attr "type" "fdivt"))
122 ;; EV5 scheduling. EV5 can issue 4 insns per clock.
123 ;; Multiply all costs by 4.
125 ;; EV5 has two integer units.
126 (define_function_unit "ev5_ebox" 2 0
127 (and (eq_attr "cpu" "ev5")
128 (eq_attr "type" "iadd,ilog,icmp,ldsym"))
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")
135 (eq_attr "type" "ld,cmov"))
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")
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")
147 (eq_attr "type" "st"))
150 (define_function_unit "ev5_ebox" 2 0
151 (and (eq_attr "cpu" "ev5")
152 (eq_attr "type" "imull"))
155 (define_function_unit "ev5_ebox" 2 0
156 (and (eq_attr "cpu" "ev5")
157 (eq_attr "type" "imulq"))
160 ;; Multiplies also use the integer multiplier.
161 (define_function_unit "ev5_imult" 1 0
162 (and (eq_attr "cpu" "ev5")
163 (eq_attr "type" "imull"))
166 (define_function_unit "ev5_imult" 1 0
167 (and (eq_attr "cpu" "ev5")
168 (eq_attr "type" "imulq"))
171 ;; There is only 1 shifter/zapper.
172 (define_function_unit "ev5_shift" 1 0
173 (and (eq_attr "cpu" "ev5")
174 (eq_attr "type" "shift"))
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")
181 (eq_attr "type" "fadd,fmul,fcpys"))
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")
187 (eq_attr "type" "fmul"))
190 (define_function_unit "ev5_fpadd" 1 0
191 (and (eq_attr "cpu" "ev5")
192 (eq_attr "type" "fadd"))
195 (define_function_unit "ev5_fpadd" 1 0
196 (and (eq_attr "cpu" "ev5")
197 (eq_attr "type" "fbr"))
200 (define_function_unit "ev5_fpadd" 1 0
201 (and (eq_attr "cpu" "ev5")
202 (eq_attr "type" "fdivs"))
205 (define_function_unit "ev5_fpadd" 1 0
206 (and (eq_attr "cpu" "ev5")
207 (eq_attr "type" "fdivt"))
210 ;; First define the arithmetic insns. Note that the 32-bit forms also
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")))]
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" "")))]
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]))));
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")))]
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)))]
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);
273 [(set (match_operand:DI 0 "register_operand" "=r,r")
275 (plus:SI (match_operand:SI 1 "reg_or_0_operand" "%rJ,rJ")
276 (match_operand:SI 2 "sext_add_operand" "rI,O"))))]
283 [(set (match_operand:DI 0 "register_operand" "")
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)
296 HOST_WIDE_INT val = INTVAL (operands[2]) / 4;
302 operands[4] = GEN_INT (val);
303 operands[5] = GEN_INT (mult);
307 [(set (match_operand:DI 0 "register_operand" "")
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" ""))]
315 [(set (match_dup 5) (match_dup 6))
316 (set (match_dup 0) (sign_extend:DI (plus:SI (match_dup 7) (match_dup 4))))]
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")))]
335 ;; Don't do this if we are adjusting SP since we don't want to do
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)))]
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);
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")))]
366 [(set (match_operand:DI 0 "register_operand" "=r,r")
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"))))]
377 [(set (match_operand:DI 0 "register_operand" "")
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" ""))]
386 [(set (match_dup 6) (match_dup 7))
388 (sign_extend:DI (plus:SI (mult:SI (match_dup 8) (match_dup 4))
392 operands[7] = gen_rtx (GET_CODE (operands[1]), DImode,
393 operands[2], operands[3]);
394 operands[8] = gen_lowpart (SImode, operands[6]);
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")))]
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.
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")))]
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" "")))]
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)))]
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")))]
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")))]
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)))]
451 [(set (match_operand:DI 0 "some_operand" "=&r")
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"))))]
462 [(set (match_operand:DI 0 "register_operand" "")
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" ""))))]
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))))]
474 { operands[5] = gen_lowpart (SImode, operands[0]);
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")))]
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" "")))]
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)))]
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")))]
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"))))]
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")))]
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" "")))]
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]))));
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")))]
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"))))]
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")))]
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")))]
561 [(set (match_operand:DI 0 "register_operand" "=r")
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"))))]
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")))]
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")))]
583 [(set_attr "type" "imull")])
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"))))]
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")))]
599 [(set_attr "type" "imulq")])
601 (define_insn "umuldi3_highpart"
602 [(set (match_operand:DI 0 "register_operand" "=r")
605 (mult:TI (zero_extend:TI (match_operand:DI 1 "register_operand" "r"))
606 (zero_extend:TI (match_operand:DI 2 "register_operand" "r")))
610 [(set_attr "type" "imulq")])
613 [(set (match_operand:DI 0 "register_operand" "=r")
616 (mult:TI (zero_extend:TI (match_operand:DI 1 "register_operand" "r"))
617 (match_operand:TI 2 "cint8_operand" "I"))
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 (define_expand "divsi3"
627 [(set (reg:SI 24) (match_operand:SI 1 "input_operand" ""))
628 (set (reg:SI 25) (match_operand:SI 2 "input_operand" ""))
629 (parallel [(set (reg:SI 27)
632 (clobber (reg:DI 23))
633 (clobber (reg:DI 28))])
634 (set (match_operand:SI 0 "general_operand" "")
639 (define_expand "udivsi3"
640 [(set (reg:SI 24) (match_operand:SI 1 "input_operand" ""))
641 (set (reg:SI 25) (match_operand:SI 2 "input_operand" ""))
642 (parallel [(set (reg:SI 27)
645 (clobber (reg:DI 23))
646 (clobber (reg:DI 28))])
647 (set (match_operand:SI 0 "general_operand" "")
652 (define_expand "modsi3"
653 [(set (reg:SI 24) (match_operand:SI 1 "input_operand" ""))
654 (set (reg:SI 25) (match_operand:SI 2 "input_operand" ""))
655 (parallel [(set (reg:SI 27)
658 (clobber (reg:DI 23))
659 (clobber (reg:DI 28))])
660 (set (match_operand:SI 0 "general_operand" "")
665 (define_expand "umodsi3"
666 [(set (reg:SI 24) (match_operand:SI 1 "input_operand" ""))
667 (set (reg:SI 25) (match_operand:SI 2 "input_operand" ""))
668 (parallel [(set (reg:SI 27)
671 (clobber (reg:DI 23))
672 (clobber (reg:DI 28))])
673 (set (match_operand:SI 0 "general_operand" "")
678 (define_expand "divdi3"
679 [(set (reg:DI 24) (match_operand:DI 1 "input_operand" ""))
680 (set (reg:DI 25) (match_operand:DI 2 "input_operand" ""))
681 (parallel [(set (reg:DI 27)
684 (clobber (reg:DI 23))
685 (clobber (reg:DI 28))])
686 (set (match_operand:DI 0 "general_operand" "")
691 (define_expand "udivdi3"
692 [(set (reg:DI 24) (match_operand:DI 1 "input_operand" ""))
693 (set (reg:DI 25) (match_operand:DI 2 "input_operand" ""))
694 (parallel [(set (reg:DI 27)
697 (clobber (reg:DI 23))
698 (clobber (reg:DI 28))])
699 (set (match_operand:DI 0 "general_operand" "")
704 (define_expand "moddi3"
705 [(set (reg:DI 24) (match_operand:DI 1 "input_operand" ""))
706 (set (reg:DI 25) (match_operand:DI 2 "input_operand" ""))
707 (parallel [(set (reg:DI 27)
710 (clobber (reg:DI 23))
711 (clobber (reg:DI 28))])
712 (set (match_operand:DI 0 "general_operand" "")
717 (define_expand "umoddi3"
718 [(set (reg:DI 24) (match_operand:DI 1 "input_operand" ""))
719 (set (reg:DI 25) (match_operand:DI 2 "input_operand" ""))
720 (parallel [(set (reg:DI 27)
723 (clobber (reg:DI 23))
724 (clobber (reg:DI 28))])
725 (set (match_operand:DI 0 "general_operand" "")
732 (match_operator:SI 1 "divmod_operator"
733 [(reg:SI 24) (reg:SI 25)]))
734 (clobber (reg:DI 23))
735 (clobber (reg:DI 28))]
738 [(set_attr "type" "isubr")])
742 (match_operator:DI 1 "divmod_operator"
743 [(reg:DI 24) (reg:DI 25)]))
744 (clobber (reg:DI 23))
745 (clobber (reg:DI 28))]
748 [(set_attr "type" "isubr")])
750 ;; Next are the basic logical operations. These only exist in DImode.
752 (define_insn "anddi3"
753 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
754 (and:DI (match_operand:DI 1 "reg_or_0_operand" "%rJ,rJ,rJ")
755 (match_operand:DI 2 "and_operand" "rI,N,MH")))]
761 [(set_attr "type" "ilog,ilog,shift")])
763 ;; There are times when we can split an AND into two AND insns. This occurs
764 ;; when we can first clear any bytes and then clear anything else. For
765 ;; example "I & 0xffff07" is "(I & 0xffffff) & 0xffffffffffffff07".
766 ;; Only do this when running on 64-bit host since the computations are
767 ;; too messy otherwise.
770 [(set (match_operand:DI 0 "register_operand" "")
771 (and:DI (match_operand:DI 1 "register_operand" "")
772 (match_operand:DI 2 "const_int_operand" "")))]
773 "HOST_BITS_PER_WIDE_INT == 64 && ! and_operand (operands[2], DImode)"
774 [(set (match_dup 0) (and:DI (match_dup 1) (match_dup 3)))
775 (set (match_dup 0) (and:DI (match_dup 0) (match_dup 4)))]
778 unsigned HOST_WIDE_INT mask1 = INTVAL (operands[2]);
779 unsigned HOST_WIDE_INT mask2 = mask1;
782 /* For each byte that isn't all zeros, make it all ones. */
783 for (i = 0; i < 64; i += 8)
784 if ((mask1 & ((HOST_WIDE_INT) 0xff << i)) != 0)
785 mask1 |= (HOST_WIDE_INT) 0xff << i;
787 /* Now turn on any bits we've just turned off. */
790 operands[3] = GEN_INT (mask1);
791 operands[4] = GEN_INT (mask2);
794 (define_insn "zero_extendqihi2"
795 [(set (match_operand:HI 0 "register_operand" "=r")
796 (zero_extend:HI (match_operand:QI 1 "register_operand" "r")))]
799 [(set_attr "type" "shift")])
801 (define_insn "zero_extendqisi2"
802 [(set (match_operand:SI 0 "register_operand" "=r")
803 (zero_extend:SI (match_operand:QI 1 "register_operand" "r")))]
806 [(set_attr "type" "shift")])
808 (define_insn "zero_extendqidi2"
809 [(set (match_operand:DI 0 "register_operand" "=r")
810 (zero_extend:DI (match_operand:QI 1 "register_operand" "r")))]
813 [(set_attr "type" "shift")])
815 (define_insn "zero_extendhisi2"
816 [(set (match_operand:SI 0 "register_operand" "=r")
817 (zero_extend:SI (match_operand:HI 1 "register_operand" "r")))]
820 [(set_attr "type" "shift")])
822 (define_insn "zero_extendhidi2"
823 [(set (match_operand:DI 0 "register_operand" "=r")
824 (zero_extend:DI (match_operand:HI 1 "register_operand" "r")))]
827 [(set_attr "type" "shift")])
829 (define_insn "zero_extendsidi2"
830 [(set (match_operand:DI 0 "register_operand" "=r")
831 (zero_extend:DI (match_operand:SI 1 "register_operand" "r")))]
834 [(set_attr "type" "shift")])
837 [(set (match_operand:DI 0 "register_operand" "=r")
838 (and:DI (not:DI (match_operand:DI 1 "reg_or_8bit_operand" "rI"))
839 (match_operand:DI 2 "reg_or_0_operand" "rJ")))]
842 [(set_attr "type" "ilog")])
844 (define_insn "iordi3"
845 [(set (match_operand:DI 0 "register_operand" "=r,r")
846 (ior:DI (match_operand:DI 1 "reg_or_0_operand" "%rJ,rJ")
847 (match_operand:DI 2 "or_operand" "rI,N")))]
852 [(set_attr "type" "ilog")])
854 (define_insn "one_cmpldi2"
855 [(set (match_operand:DI 0 "register_operand" "=r")
856 (not:DI (match_operand:DI 1 "reg_or_8bit_operand" "rI")))]
859 [(set_attr "type" "ilog")])
862 [(set (match_operand:DI 0 "register_operand" "=r")
863 (ior:DI (not:DI (match_operand:DI 1 "reg_or_8bit_operand" "rI"))
864 (match_operand:DI 2 "reg_or_0_operand" "rJ")))]
867 [(set_attr "type" "ilog")])
869 (define_insn "xordi3"
870 [(set (match_operand:DI 0 "register_operand" "=r,r")
871 (xor:DI (match_operand:DI 1 "reg_or_0_operand" "%rJ,rJ")
872 (match_operand:DI 2 "or_operand" "rI,N")))]
877 [(set_attr "type" "ilog")])
880 [(set (match_operand:DI 0 "register_operand" "=r")
881 (not:DI (xor:DI (match_operand:DI 1 "register_operand" "%rJ")
882 (match_operand:DI 2 "register_operand" "rI"))))]
885 [(set_attr "type" "ilog")])
887 ;; Next come the shifts and the various extract and insert operations.
889 (define_insn "ashldi3"
890 [(set (match_operand:DI 0 "register_operand" "=r,r")
891 (ashift:DI (match_operand:DI 1 "reg_or_0_operand" "rJ,rJ")
892 (match_operand:DI 2 "reg_or_6bit_operand" "P,rI")))]
896 switch (which_alternative)
899 if (operands[2] == const1_rtx)
900 return \"addq %r1,%r1,%0\";
902 return \"s%P2addq %r1,0,%0\";
904 return \"sll %r1,%2,%0\";
907 [(set_attr "type" "iadd,shift")])
909 ;; ??? The following pattern is made by combine, but earlier phases
910 ;; (specifically flow) can't handle it. This occurs in jump.c. Deal
911 ;; with this in a better way at some point.
913 ;; [(set (match_operand:DI 0 "register_operand" "=r")
915 ;; (subreg:SI (ashift:DI (match_operand:DI 1 "reg_or_0_operand" "rJ")
916 ;; (match_operand:DI 2 "const_int_operand" "P"))
918 ;; "INTVAL (operands[2]) >= 1 && INTVAL (operands[2]) <= 3"
921 ;; if (operands[2] == const1_rtx)
922 ;; return \"addl %r1,%r1,%0\";
924 ;; return \"s%P2addl %r1,0,%0\";
926 ;; [(set_attr "type" "iadd")])
928 (define_insn "lshrdi3"
929 [(set (match_operand:DI 0 "register_operand" "=r")
930 (lshiftrt:DI (match_operand:DI 1 "reg_or_0_operand" "rJ")
931 (match_operand:DI 2 "reg_or_6bit_operand" "rI")))]
934 [(set_attr "type" "shift")])
936 (define_insn "ashrdi3"
937 [(set (match_operand:DI 0 "register_operand" "=r")
938 (ashiftrt:DI (match_operand:DI 1 "reg_or_0_operand" "rJ")
939 (match_operand:DI 2 "reg_or_6bit_operand" "rI")))]
942 [(set_attr "type" "shift")])
944 (define_expand "extendqihi2"
946 (ashift:DI (match_operand:QI 1 "reg_or_unaligned_mem_operand" "")
948 (set (match_operand:HI 0 "register_operand" "")
949 (ashiftrt:DI (match_dup 2)
954 /* If we have a MEM (must be unaligned), extend to DImode (which we do
955 specially) and then copy to the result. */
956 if (GET_CODE (operands[1]) == MEM)
958 rtx temp = gen_reg_rtx (DImode);
960 emit_insn (gen_extendqidi2 (temp, operands[1]));
961 emit_move_insn (operands[0], gen_lowpart (HImode, temp));
965 operands[0] = gen_lowpart (DImode, operands[0]);
966 operands[1] = gen_lowpart (DImode, operands[1]);
967 operands[2] = gen_reg_rtx (DImode);
970 (define_expand "extendqisi2"
972 (ashift:DI (match_operand:QI 1 "reg_or_unaligned_mem_operand" "")
974 (set (match_operand:SI 0 "register_operand" "")
975 (ashiftrt:DI (match_dup 2)
980 /* If we have a MEM (must be unaligned), extend to a DImode form of
981 the result (which we do specially). */
982 if (GET_CODE (operands[1]) == MEM)
984 rtx temp = gen_reg_rtx (DImode);
986 emit_insn (gen_extendqidi2 (temp, operands[1]));
987 emit_move_insn (operands[0], gen_lowpart (SImode, temp));
991 operands[0] = gen_lowpart (DImode, operands[0]);
992 operands[1] = gen_lowpart (DImode, operands[1]);
993 operands[2] = gen_reg_rtx (DImode);
996 (define_expand "extendqidi2"
998 (ashift:DI (match_operand:QI 1 "reg_or_unaligned_mem_operand" "")
1000 (set (match_operand:DI 0 "register_operand" "")
1001 (ashiftrt:DI (match_dup 2)
1005 { extern rtx get_unaligned_address ();
1006 if (GET_CODE (operands[1]) == MEM)
1009 = gen_unaligned_extendqidi (operands[0],
1010 get_unaligned_address (operands[1], 1));
1012 alpha_set_memflags (seq, operands[1]);
1017 operands[1] = gen_lowpart (DImode, operands[1]);
1018 operands[2] = gen_reg_rtx (DImode);
1021 (define_expand "extendhisi2"
1023 (ashift:DI (match_operand:HI 1 "reg_or_unaligned_mem_operand" "")
1025 (set (match_operand:SI 0 "register_operand" "")
1026 (ashiftrt:DI (match_dup 2)
1031 /* If we have a MEM (must be unaligned), extend to a DImode form of
1032 the result (which we do specially). */
1033 if (GET_CODE (operands[1]) == MEM)
1035 rtx temp = gen_reg_rtx (DImode);
1037 emit_insn (gen_extendhidi2 (temp, operands[1]));
1038 emit_move_insn (operands[0], gen_lowpart (SImode, temp));
1042 operands[0] = gen_lowpart (DImode, operands[0]);
1043 operands[1] = gen_lowpart (DImode, operands[1]);
1044 operands[2] = gen_reg_rtx (DImode);
1047 (define_expand "extendhidi2"
1049 (ashift:DI (match_operand:HI 1 "reg_or_unaligned_mem_operand" "")
1051 (set (match_operand:DI 0 "register_operand" "")
1052 (ashiftrt:DI (match_dup 2)
1056 { extern rtx get_unaligned_address ();
1057 if (GET_CODE (operands[1]) == MEM)
1060 = gen_unaligned_extendhidi (operands[0],
1061 get_unaligned_address (operands[1], 2));
1063 alpha_set_memflags (seq, operands[1]);
1068 operands[1] = gen_lowpart (DImode, operands[1]);
1069 operands[2] = gen_reg_rtx (DImode);
1072 ;; Here's how we sign extend an unaligned byte and halfword. Doing this
1073 ;; as a pattern saves one instruction. The code is similar to that for
1074 ;; the unaligned loads (see below).
1076 ;; Operand 1 is the address + 1 (+2 for HI), operand 0 is the result.
1077 (define_expand "unaligned_extendqidi"
1078 [(set (match_dup 2) (match_operand:DI 1 "address_operand" ""))
1080 (mem:DI (and:DI (plus:DI (match_dup 2) (const_int -1))
1083 (ashift:DI (match_dup 3)
1084 (minus:DI (const_int 56)
1086 (and:DI (plus:DI (match_dup 2) (const_int -1))
1089 (set (subreg:DI (match_operand:QI 0 "register_operand" "") 0)
1090 (ashiftrt:DI (match_dup 4) (const_int 56)))]
1093 { operands[2] = gen_reg_rtx (DImode);
1094 operands[3] = gen_reg_rtx (DImode);
1095 operands[4] = gen_reg_rtx (DImode);
1098 (define_expand "unaligned_extendhidi"
1099 [(set (match_dup 2) (match_operand:DI 1 "address_operand" ""))
1101 (mem:DI (and:DI (plus:DI (match_dup 2) (const_int -2))
1104 (ashift:DI (match_dup 3)
1105 (minus:DI (const_int 56)
1107 (and:DI (plus:DI (match_dup 2) (const_int -1))
1110 (set (subreg:DI (match_operand:QI 0 "register_operand" "") 0)
1111 (ashiftrt:DI (match_dup 4) (const_int 48)))]
1114 { operands[2] = gen_reg_rtx (DImode);
1115 operands[3] = gen_reg_rtx (DImode);
1116 operands[4] = gen_reg_rtx (DImode);
1120 [(set (match_operand:DI 0 "register_operand" "=r")
1121 (zero_extract:DI (match_operand:DI 1 "reg_or_0_operand" "rJ")
1122 (match_operand:DI 2 "mode_width_operand" "n")
1123 (match_operand:DI 3 "mul8_operand" "I")))]
1125 "ext%M2l %r1,%s3,%0"
1126 [(set_attr "type" "shift")])
1129 [(set (match_operand:DI 0 "register_operand" "=r")
1130 (zero_extract:DI (match_operand:DI 1 "reg_or_0_operand" "rJ")
1131 (match_operand:DI 2 "mode_width_operand" "n")
1132 (ashift:DI (match_operand:DI 3 "reg_or_8bit_operand" "rI")
1136 [(set_attr "type" "shift")])
1139 [(set (match_operand:DI 0 "register_operand" "=r")
1141 (match_operand:DI 1 "reg_or_0_operand" "rJ")
1142 (minus:DI (const_int 56)
1145 (plus:DI (match_operand:DI 2 "reg_or_8bit_operand" "rI")
1151 [(set_attr "type" "shift")])
1154 [(set (match_operand:DI 0 "register_operand" "=r")
1156 (and:DI (match_operand:DI 1 "reg_or_0_operand" "rJ")
1157 (const_int 2147483647))
1158 (minus:DI (const_int 56)
1161 (plus:DI (match_operand:DI 2 "reg_or_8bit_operand" "rI")
1167 [(set_attr "type" "shift")])
1170 [(set (match_operand:DI 0 "register_operand" "=r")
1172 (and:DI (match_operand:DI 1 "reg_or_0_operand" "rJ")
1174 (minus:DI (const_int 56)
1177 (plus:DI (match_operand:DI 2 "reg_or_8bit_operand" "rI")
1183 [(set_attr "type" "shift")])
1185 ;; This converts an extXl into an extXh with an appropriate adjustment
1186 ;; to the address calculation.
1189 ;; [(set (match_operand:DI 0 "register_operand" "")
1190 ;; (ashift:DI (zero_extract:DI (match_operand:DI 1 "register_operand" "")
1191 ;; (match_operand:DI 2 "mode_width_operand" "")
1192 ;; (ashift:DI (match_operand:DI 3 "" "")
1194 ;; (match_operand:DI 4 "const_int_operand" "")))
1195 ;; (clobber (match_operand:DI 5 "register_operand" ""))]
1196 ;; "INTVAL (operands[4]) == 64 - INTVAL (operands[2])"
1197 ;; [(set (match_dup 5) (match_dup 6))
1198 ;; (set (match_dup 0)
1199 ;; (ashift:DI (zero_extract:DI (match_dup 1) (match_dup 2)
1200 ;; (ashift:DI (plus:DI (match_dup 5)
1206 ;; operands[6] = plus_constant (operands[3],
1207 ;; INTVAL (operands[2]) / BITS_PER_UNIT);
1208 ;; operands[7] = GEN_INT (- INTVAL (operands[2]) / BITS_PER_UNIT);
1212 [(set (match_operand:DI 0 "register_operand" "=r")
1213 (ashift:DI (zero_extend:DI (match_operand:QI 1 "register_operand" "r"))
1214 (match_operand:DI 2 "mul8_operand" "I")))]
1217 [(set_attr "type" "shift")])
1220 [(set (match_operand:DI 0 "register_operand" "=r")
1221 (ashift:DI (zero_extend:DI (match_operand:HI 1 "register_operand" "r"))
1222 (match_operand:DI 2 "mul8_operand" "I")))]
1225 [(set_attr "type" "shift")])
1228 [(set (match_operand:DI 0 "register_operand" "=r")
1229 (ashift:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
1230 (match_operand:DI 2 "mul8_operand" "I")))]
1233 [(set_attr "type" "shift")])
1236 [(set (match_operand:DI 0 "register_operand" "=r")
1237 (ashift:DI (zero_extend:DI (match_operand:QI 1 "register_operand" "r"))
1238 (ashift:DI (match_operand:DI 2 "reg_or_8bit_operand" "rI")
1242 [(set_attr "type" "shift")])
1245 [(set (match_operand:DI 0 "register_operand" "=r")
1246 (ashift:DI (zero_extend:DI (match_operand:HI 1 "register_operand" "r"))
1247 (ashift:DI (match_operand:DI 2 "reg_or_8bit_operand" "rI")
1251 [(set_attr "type" "shift")])
1254 [(set (match_operand:DI 0 "register_operand" "=r")
1255 (ashift:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
1256 (ashift:DI (match_operand:DI 2 "reg_or_8bit_operand" "rI")
1260 [(set_attr "type" "shift")])
1262 ;; We do not include the insXh insns because they are complex to express
1263 ;; and it does not appear that we would ever want to generate them.
1266 [(set (match_operand:DI 0 "register_operand" "=r")
1267 (and:DI (not:DI (ashift:DI
1268 (match_operand:DI 2 "mode_mask_operand" "n")
1270 (match_operand:DI 3 "reg_or_8bit_operand" "rI")
1272 (match_operand:DI 1 "reg_or_0_operand" "rJ")))]
1275 [(set_attr "type" "shift")])
1277 ;; We do not include the mskXh insns because it does not appear we would ever
1280 ;; Floating-point operations. All the double-precision insns can extend
1281 ;; from single, so indicate that. The exception are the ones that simply
1282 ;; play with the sign bits; it's not clear what to do there.
1284 (define_insn "abssf2"
1285 [(set (match_operand:SF 0 "register_operand" "=f")
1286 (abs:SF (match_operand:SF 1 "reg_or_fp0_operand" "fG")))]
1289 [(set_attr "type" "fcpys")])
1291 (define_insn "absdf2"
1292 [(set (match_operand:DF 0 "register_operand" "=f")
1293 (abs:DF (match_operand:DF 1 "reg_or_fp0_operand" "fG")))]
1296 [(set_attr "type" "fcpys")])
1298 (define_insn "negsf2"
1299 [(set (match_operand:SF 0 "register_operand" "=f")
1300 (neg:SF (match_operand:SF 1 "reg_or_fp0_operand" "fG")))]
1303 [(set_attr "type" "fadd")])
1305 (define_insn "negdf2"
1306 [(set (match_operand:DF 0 "register_operand" "=f")
1307 (neg:DF (match_operand:DF 1 "reg_or_fp0_operand" "fG")))]
1310 [(set_attr "type" "fadd")])
1313 [(set (match_operand:SF 0 "register_operand" "=&f")
1314 (plus:SF (match_operand:SF 1 "reg_or_fp0_operand" "%fG")
1315 (match_operand:SF 2 "reg_or_fp0_operand" "fG")))]
1316 "TARGET_FP && alpha_tp == ALPHA_TP_INSN"
1317 "adds%)%& %R1,%R2,%0"
1318 [(set_attr "type" "fadd")
1319 (set_attr "trap" "yes")])
1321 (define_insn "addsf3"
1322 [(set (match_operand:SF 0 "register_operand" "=f")
1323 (plus:SF (match_operand:SF 1 "reg_or_fp0_operand" "%fG")
1324 (match_operand:SF 2 "reg_or_fp0_operand" "fG")))]
1326 "adds%)%& %R1,%R2,%0"
1327 [(set_attr "type" "fadd")
1328 (set_attr "trap" "yes")])
1331 [(set (match_operand:DF 0 "register_operand" "=&f")
1332 (plus:DF (match_operand:DF 1 "reg_or_fp0_operand" "%fG")
1333 (match_operand:DF 2 "reg_or_fp0_operand" "fG")))]
1334 "TARGET_FP && alpha_tp == ALPHA_TP_INSN"
1335 "addt%)%& %R1,%R2,%0"
1336 [(set_attr "type" "fadd")
1337 (set_attr "trap" "yes")])
1339 (define_insn "adddf3"
1340 [(set (match_operand:DF 0 "register_operand" "=f")
1341 (plus:DF (match_operand:DF 1 "reg_or_fp0_operand" "%fG")
1342 (match_operand:DF 2 "reg_or_fp0_operand" "fG")))]
1344 "addt%)%& %R1,%R2,%0"
1345 [(set_attr "type" "fadd")
1346 (set_attr "trap" "yes")])
1349 [(set (match_operand:DF 0 "register_operand" "=f")
1350 (plus:DF (float_extend:DF
1351 (match_operand:SF 1 "reg_or_fp0_operand" "fG"))
1352 (match_operand:DF 2 "reg_or_fp0_operand" "fG")))]
1353 "TARGET_FP && alpha_tp != ALPHA_TP_INSN"
1354 "addt%)%& %R1,%R2,%0"
1355 [(set_attr "type" "fadd")
1356 (set_attr "trap" "yes")])
1359 [(set (match_operand:DF 0 "register_operand" "=f")
1360 (plus:DF (float_extend:DF
1361 (match_operand:SF 1 "reg_or_fp0_operand" "%fG"))
1363 (match_operand:SF 2 "reg_or_fp0_operand" "fG"))))]
1364 "TARGET_FP && alpha_tp != ALPHA_TP_INSN"
1365 "addt%)%& %R1,%R2,%0"
1366 [(set_attr "type" "fadd")
1367 (set_attr "trap" "yes")])
1369 (define_insn "fix_truncdfdi2"
1370 [(set (match_operand:DI 0 "register_operand" "=f")
1371 (fix:DI (match_operand:DF 1 "reg_or_fp0_operand" "fG")))]
1374 [(set_attr "type" "fadd")])
1376 (define_insn "fix_truncsfdi2"
1377 [(set (match_operand:DI 0 "register_operand" "=f")
1378 (fix:DI (float_extend:DF
1379 (match_operand:SF 1 "reg_or_fp0_operand" "fG"))))]
1382 [(set_attr "type" "fadd")])
1384 (define_insn "floatdisf2"
1385 [(set (match_operand:SF 0 "register_operand" "=f")
1386 (float:SF (match_operand:DI 1 "register_operand" "f")))]
1389 [(set_attr "type" "fadd")
1390 (set_attr "trap" "yes")])
1393 [(set (match_operand:DF 0 "register_operand" "=&f")
1394 (float:DF (match_operand:DI 1 "register_operand" "f")))]
1395 "TARGET_FP && alpha_tp == ALPHA_TP_INSN"
1397 [(set_attr "type" "fadd")
1398 (set_attr "trap" "yes")])
1400 (define_insn "floatdidf2"
1401 [(set (match_operand:DF 0 "register_operand" "=f")
1402 (float:DF (match_operand:DI 1 "register_operand" "f")))]
1405 [(set_attr "type" "fadd")
1406 (set_attr "trap" "yes")])
1408 (define_expand "extendsfdf2"
1409 [(use (match_operand:DF 0 "register_operand" ""))
1410 (use (match_operand:SF 1 "nonimmediate_operand" ""))]
1414 if (alpha_tp == ALPHA_TP_INSN)
1415 emit_insn (gen_extendsfdf2_tp (operands[0],
1416 force_reg (SFmode, operands[1])));
1418 emit_insn (gen_extendsfdf2_no_tp (operands[0], operands[1]));
1423 (define_insn "extendsfdf2_tp"
1424 [(set (match_operand:DF 0 "register_operand" "=&f")
1425 (float_extend:DF (match_operand:SF 1 "register_operand" "f")))]
1426 "TARGET_FP && alpha_tp == ALPHA_TP_INSN"
1428 [(set_attr "type" "fadd")
1429 (set_attr "trap" "yes")])
1431 (define_insn "extendsfdf2_no_tp"
1432 [(set (match_operand:DF 0 "register_operand" "=f,f")
1433 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "f,m")))]
1434 "TARGET_FP && alpha_tp != ALPHA_TP_INSN"
1438 [(set_attr "type" "fadd,ld")
1439 (set_attr "trap" "yes")])
1442 [(set (match_operand:SF 0 "register_operand" "=&f")
1443 (float_truncate:SF (match_operand:DF 1 "reg_or_fp0_operand" "fG")))]
1444 "TARGET_FP && alpha_tp == ALPHA_TP_INSN"
1446 [(set_attr "type" "fadd")
1447 (set_attr "trap" "yes")])
1449 (define_insn "truncdfsf2"
1450 [(set (match_operand:SF 0 "register_operand" "=f")
1451 (float_truncate:SF (match_operand:DF 1 "reg_or_fp0_operand" "fG")))]
1454 [(set_attr "type" "fadd")
1455 (set_attr "trap" "yes")])
1458 [(set (match_operand:SF 0 "register_operand" "=&f")
1459 (div:SF (match_operand:SF 1 "reg_or_fp0_operand" "fG")
1460 (match_operand:SF 2 "reg_or_fp0_operand" "fG")))]
1461 "TARGET_FP && alpha_tp == ALPHA_TP_INSN"
1462 "divs%)%& %R1,%R2,%0"
1463 [(set_attr "type" "fdivs")
1464 (set_attr "trap" "yes")])
1466 (define_insn "divsf3"
1467 [(set (match_operand:SF 0 "register_operand" "=f")
1468 (div:SF (match_operand:SF 1 "reg_or_fp0_operand" "fG")
1469 (match_operand:SF 2 "reg_or_fp0_operand" "fG")))]
1471 "divs%)%& %R1,%R2,%0"
1472 [(set_attr "type" "fdivs")
1473 (set_attr "trap" "yes")])
1476 [(set (match_operand:DF 0 "register_operand" "=&f")
1477 (div:DF (match_operand:DF 1 "reg_or_fp0_operand" "fG")
1478 (match_operand:DF 2 "reg_or_fp0_operand" "fG")))]
1479 "TARGET_FP && alpha_tp == ALPHA_TP_INSN"
1480 "divt%)%& %R1,%R2,%0"
1481 [(set_attr "type" "fdivt")
1482 (set_attr "trap" "yes")])
1484 (define_insn "divdf3"
1485 [(set (match_operand:DF 0 "register_operand" "=f")
1486 (div:DF (match_operand:DF 1 "reg_or_fp0_operand" "fG")
1487 (match_operand:DF 2 "reg_or_fp0_operand" "fG")))]
1489 "divt%)%& %R1,%R2,%0"
1490 [(set_attr "type" "fdivt")
1491 (set_attr "trap" "yes")])
1494 [(set (match_operand:DF 0 "register_operand" "=f")
1495 (div:DF (float_extend:DF (match_operand:SF 1 "reg_or_fp0_operand" "fG"))
1496 (match_operand:DF 2 "reg_or_fp0_operand" "fG")))]
1497 "TARGET_FP && alpha_tp != ALPHA_TP_INSN"
1498 "divt%)%& %R1,%R2,%0"
1499 [(set_attr "type" "fdivt")
1500 (set_attr "trap" "yes")])
1503 [(set (match_operand:DF 0 "register_operand" "=f")
1504 (div:DF (match_operand:DF 1 "reg_or_fp0_operand" "fG")
1506 (match_operand:SF 2 "reg_or_fp0_operand" "fG"))))]
1507 "TARGET_FP && alpha_tp != ALPHA_TP_INSN"
1508 "divt%)%& %R1,%R2,%0"
1509 [(set_attr "type" "fdivt")
1510 (set_attr "trap" "yes")])
1513 [(set (match_operand:DF 0 "register_operand" "=f")
1514 (div:DF (float_extend:DF (match_operand:SF 1 "reg_or_fp0_operand" "fG"))
1515 (float_extend:DF (match_operand:SF 2 "reg_or_fp0_operand" "fG"))))]
1516 "TARGET_FP && alpha_tp != ALPHA_TP_INSN"
1517 "divt%)%& %R1,%R2,%0"
1518 [(set_attr "type" "fdivt")
1519 (set_attr "trap" "yes")])
1522 [(set (match_operand:SF 0 "register_operand" "=&f")
1523 (mult:SF (match_operand:SF 1 "reg_or_fp0_operand" "%fG")
1524 (match_operand:SF 2 "reg_or_fp0_operand" "fG")))]
1525 "TARGET_FP && alpha_tp == ALPHA_TP_INSN"
1526 "muls%)%& %R1,%R2,%0"
1527 [(set_attr "type" "fmul")
1528 (set_attr "trap" "yes")])
1530 (define_insn "mulsf3"
1531 [(set (match_operand:SF 0 "register_operand" "=f")
1532 (mult:SF (match_operand:SF 1 "reg_or_fp0_operand" "%fG")
1533 (match_operand:SF 2 "reg_or_fp0_operand" "fG")))]
1535 "muls%)%& %R1,%R2,%0"
1536 [(set_attr "type" "fmul")
1537 (set_attr "trap" "yes")])
1540 [(set (match_operand:DF 0 "register_operand" "=&f")
1541 (mult:DF (match_operand:DF 1 "reg_or_fp0_operand" "%fG")
1542 (match_operand:DF 2 "reg_or_fp0_operand" "fG")))]
1543 "TARGET_FP && alpha_tp == ALPHA_TP_INSN"
1544 "mult%)%& %R1,%R2,%0"
1545 [(set_attr "type" "fmul")
1546 (set_attr "trap" "yes")])
1548 (define_insn "muldf3"
1549 [(set (match_operand:DF 0 "register_operand" "=f")
1550 (mult:DF (match_operand:DF 1 "reg_or_fp0_operand" "%fG")
1551 (match_operand:DF 2 "reg_or_fp0_operand" "fG")))]
1553 "mult%)%& %R1,%R2,%0"
1554 [(set_attr "type" "fmul")
1555 (set_attr "trap" "yes")])
1558 [(set (match_operand:DF 0 "register_operand" "=f")
1559 (mult:DF (float_extend:DF
1560 (match_operand:SF 1 "reg_or_fp0_operand" "fG"))
1561 (match_operand:DF 2 "reg_or_fp0_operand" "fG")))]
1562 "TARGET_FP && alpha_tp != ALPHA_TP_INSN"
1563 "mult%)%& %R1,%R2,%0"
1564 [(set_attr "type" "fmul")
1565 (set_attr "trap" "yes")])
1568 [(set (match_operand:DF 0 "register_operand" "=f")
1569 (mult:DF (float_extend:DF
1570 (match_operand:SF 1 "reg_or_fp0_operand" "%fG"))
1572 (match_operand:SF 2 "reg_or_fp0_operand" "fG"))))]
1573 "TARGET_FP && alpha_tp != ALPHA_TP_INSN"
1574 "mult%)%& %R1,%R2,%0"
1575 [(set_attr "type" "fmul")
1576 (set_attr "trap" "yes")])
1579 [(set (match_operand:SF 0 "register_operand" "=&f")
1580 (minus:SF (match_operand:SF 1 "reg_or_fp0_operand" "fG")
1581 (match_operand:SF 2 "reg_or_fp0_operand" "fG")))]
1582 "TARGET_FP && alpha_tp == ALPHA_TP_INSN"
1583 "subs%)%& %R1,%R2,%0"
1584 [(set_attr "type" "fadd")
1585 (set_attr "trap" "yes")])
1587 (define_insn "subsf3"
1588 [(set (match_operand:SF 0 "register_operand" "=f")
1589 (minus:SF (match_operand:SF 1 "reg_or_fp0_operand" "fG")
1590 (match_operand:SF 2 "reg_or_fp0_operand" "fG")))]
1592 "subs%)%& %R1,%R2,%0"
1593 [(set_attr "type" "fadd")
1594 (set_attr "trap" "yes")])
1597 [(set (match_operand:DF 0 "register_operand" "=&f")
1598 (minus:DF (match_operand:DF 1 "reg_or_fp0_operand" "fG")
1599 (match_operand:DF 2 "reg_or_fp0_operand" "fG")))]
1600 "TARGET_FP && alpha_tp == ALPHA_TP_INSN"
1601 "subt%)%& %R1,%R2,%0"
1602 [(set_attr "type" "fadd")
1603 (set_attr "trap" "yes")])
1605 (define_insn "subdf3"
1606 [(set (match_operand:DF 0 "register_operand" "=f")
1607 (minus:DF (match_operand:DF 1 "reg_or_fp0_operand" "fG")
1608 (match_operand:DF 2 "reg_or_fp0_operand" "fG")))]
1610 "subt%)%& %R1,%R2,%0"
1611 [(set_attr "type" "fadd")
1612 (set_attr "trap" "yes")])
1615 [(set (match_operand:DF 0 "register_operand" "=f")
1616 (minus:DF (float_extend:DF
1617 (match_operand:SF 1 "reg_or_fp0_operand" "fG"))
1618 (match_operand:DF 2 "reg_or_fp0_operand" "fG")))]
1619 "TARGET_FP && alpha_tp != ALPHA_TP_INSN"
1620 "subt%)%& %R1,%R2,%0"
1621 [(set_attr "type" "fadd")
1622 (set_attr "trap" "yes")])
1625 [(set (match_operand:DF 0 "register_operand" "=f")
1626 (minus:DF (match_operand:DF 1 "reg_or_fp0_operand" "fG")
1628 (match_operand:SF 2 "reg_or_fp0_operand" "fG"))))]
1629 "TARGET_FP && alpha_tp != ALPHA_TP_INSN"
1630 "subt%)%& %R1,%R2,%0"
1631 [(set_attr "type" "fadd")
1632 (set_attr "trap" "yes")])
1635 [(set (match_operand:DF 0 "register_operand" "=f")
1636 (minus:DF (float_extend:DF
1637 (match_operand:SF 1 "reg_or_fp0_operand" "fG"))
1639 (match_operand:SF 2 "reg_or_fp0_operand" "fG"))))]
1640 "TARGET_FP && alpha_tp != ALPHA_TP_INSN"
1641 "subt%)%& %R1,%R2,%0"
1642 [(set_attr "type" "fadd")
1643 (set_attr "trap" "yes")])
1645 ;; Next are all the integer comparisons, and conditional moves and branches
1646 ;; and some of the related define_expand's and define_split's.
1649 [(set (match_operand:DI 0 "register_operand" "=r")
1650 (match_operator:DI 1 "alpha_comparison_operator"
1651 [(match_operand:DI 2 "reg_or_0_operand" "rJ")
1652 (match_operand:DI 3 "reg_or_8bit_operand" "rI")]))]
1655 [(set_attr "type" "icmp")])
1657 ;; There are three important special-case that don't fit the above pattern
1658 ;; but which we want to handle here.
1661 [(set (match_operand:DI 0 "register_operand" "=r")
1662 (ne:DI (match_operand:DI 1 "register_operand" "r")
1666 [(set_attr "type" "icmp")])
1669 [(set (match_operand:DI 0 "register_operand" "=r")
1670 (gt:DI (match_operand:DI 1 "register_operand" "r")
1674 [(set_attr "type" "icmp")])
1677 [(set (match_operand:DI 0 "register_operand" "=r")
1678 (ge:DI (match_operand:DI 1 "register_operand" "r")
1682 [(set_attr "type" "icmp")])
1684 ;; This pattern exists so conditional moves of SImode values are handled.
1685 ;; Comparisons are still done in DImode though.
1688 [(set (match_operand:SI 0 "register_operand" "=r,r,r,r")
1690 (match_operator 2 "signed_comparison_operator"
1691 [(match_operand:DI 3 "reg_or_0_operand" "rJ,rJ,J,J")
1692 (match_operand:DI 4 "reg_or_0_operand" "J,J,rJ,rJ")])
1693 (match_operand:SI 1 "reg_or_8bit_operand" "rI,0,rI,0")
1694 (match_operand:SI 5 "reg_or_8bit_operand" "0,rI,0,rI")))]
1695 "operands[3] == const0_rtx || operands[4] == const0_rtx"
1701 [(set_attr "type" "cmov")])
1704 [(set (match_operand:DI 0 "register_operand" "=r,r,r,r")
1706 (match_operator 2 "signed_comparison_operator"
1707 [(match_operand:DI 3 "reg_or_0_operand" "rJ,rJ,J,J")
1708 (match_operand:DI 4 "reg_or_0_operand" "J,J,rJ,rJ")])
1709 (match_operand:DI 1 "reg_or_8bit_operand" "rI,0,rI,0")
1710 (match_operand:DI 5 "reg_or_8bit_operand" "0,rI,0,rI")))]
1711 "operands[3] == const0_rtx || operands[4] == const0_rtx"
1717 [(set_attr "type" "cmov")])
1720 [(set (match_operand:DI 0 "register_operand" "=r,r")
1722 (eq (zero_extract:DI (match_operand:DI 2 "reg_or_0_operand" "rJ,rJ")
1726 (match_operand:DI 1 "reg_or_8bit_operand" "rI,0")
1727 (match_operand:DI 3 "reg_or_8bit_operand" "0,rI")))]
1732 [(set_attr "type" "cmov")])
1735 [(set (match_operand:DI 0 "register_operand" "=r,r")
1737 (ne (zero_extract:DI (match_operand:DI 2 "reg_or_0_operand" "rJ,rJ")
1741 (match_operand:DI 1 "reg_or_8bit_operand" "rI,0")
1742 (match_operand:DI 3 "reg_or_8bit_operand" "0,rI")))]
1747 [(set_attr "type" "cmov")])
1749 ;; This form is added since combine thinks that an IF_THEN_ELSE with both
1750 ;; arms constant is a single insn, so it won't try to form it if combine
1751 ;; knows they are really two insns. This occurs in divides by powers
1755 [(set (match_operand:DI 0 "register_operand" "=r")
1757 (match_operator 2 "signed_comparison_operator"
1758 [(match_operand:DI 3 "reg_or_0_operand" "rJ")
1760 (plus:DI (match_dup 0)
1761 (match_operand:DI 1 "reg_or_8bit_operand" "rI"))
1763 (clobber (match_scratch:DI 4 "=&r"))]
1765 "addq %0,%1,%4\;cmov%C2 %r3,%4,%0"
1766 [(set_attr "type" "cmov")])
1769 [(set (match_operand:DI 0 "register_operand" "")
1771 (match_operator 2 "signed_comparison_operator"
1772 [(match_operand:DI 3 "reg_or_0_operand" "")
1774 (plus:DI (match_dup 0)
1775 (match_operand:DI 1 "reg_or_8bit_operand" ""))
1777 (clobber (match_operand:DI 4 "register_operand" ""))]
1779 [(set (match_dup 4) (plus:DI (match_dup 0) (match_dup 1)))
1780 (set (match_dup 0) (if_then_else:DI (match_op_dup 2
1783 (match_dup 4) (match_dup 0)))]
1788 [(set (match_operand:DI 0 "register_operand" "")
1790 (match_operator 1 "comparison_operator"
1791 [(zero_extract:DI (match_operand:DI 2 "register_operand" "")
1793 (match_operand:DI 3 "const_int_operand" ""))
1795 (match_operand:DI 4 "reg_or_8bit_operand" "")
1796 (match_operand:DI 5 "reg_or_8bit_operand" "")))
1797 (clobber (match_operand:DI 6 "register_operand" ""))])]
1798 "INTVAL (operands[3]) != 0"
1800 (lshiftrt:DI (match_dup 2) (match_dup 3)))
1802 (if_then_else:DI (match_op_dup 1
1803 [(zero_extract:DI (match_dup 6)
1811 ;; For ABS, we have two choices, depending on whether the input and output
1812 ;; registers are the same or not.
1813 (define_expand "absdi2"
1814 [(set (match_operand:DI 0 "register_operand" "")
1815 (abs:DI (match_operand:DI 1 "register_operand" "")))]
1818 { if (rtx_equal_p (operands[0], operands[1]))
1819 emit_insn (gen_absdi2_same (operands[0], gen_reg_rtx (DImode)));
1821 emit_insn (gen_absdi2_diff (operands[0], operands[1]));
1826 (define_expand "absdi2_same"
1827 [(set (match_operand:DI 1 "register_operand" "")
1828 (neg:DI (match_operand:DI 0 "register_operand" "")))
1830 (if_then_else:DI (ge (match_dup 0) (const_int 0))
1836 (define_expand "absdi2_diff"
1837 [(set (match_operand:DI 0 "register_operand" "")
1838 (neg:DI (match_operand:DI 1 "register_operand" "")))
1840 (if_then_else:DI (lt (match_dup 1) (const_int 0))
1847 [(set (match_operand:DI 0 "register_operand" "")
1848 (abs:DI (match_dup 0)))
1849 (clobber (match_operand:DI 2 "register_operand" ""))]
1851 [(set (match_dup 1) (neg:DI (match_dup 0)))
1852 (set (match_dup 0) (if_then_else:DI (ge (match_dup 0) (const_int 0))
1853 (match_dup 0) (match_dup 1)))]
1857 [(set (match_operand:DI 0 "register_operand" "")
1858 (abs:DI (match_operand:DI 1 "register_operand" "")))]
1859 "! rtx_equal_p (operands[0], operands[1])"
1860 [(set (match_dup 0) (neg:DI (match_dup 1)))
1861 (set (match_dup 0) (if_then_else:DI (lt (match_dup 1) (const_int 0))
1862 (match_dup 0) (match_dup 1)))]
1866 [(set (match_operand:DI 0 "register_operand" "")
1867 (neg:DI (abs:DI (match_dup 0))))
1868 (clobber (match_operand:DI 2 "register_operand" ""))]
1870 [(set (match_dup 1) (neg:DI (match_dup 0)))
1871 (set (match_dup 0) (if_then_else:DI (le (match_dup 0) (const_int 0))
1872 (match_dup 0) (match_dup 1)))]
1876 [(set (match_operand:DI 0 "register_operand" "")
1877 (neg:DI (abs:DI (match_operand:DI 1 "register_operand" ""))))]
1878 "! rtx_equal_p (operands[0], operands[1])"
1879 [(set (match_dup 0) (neg:DI (match_dup 1)))
1880 (set (match_dup 0) (if_then_else:DI (gt (match_dup 1) (const_int 0))
1881 (match_dup 0) (match_dup 1)))]
1884 (define_expand "smaxdi3"
1886 (le:DI (match_operand:DI 1 "reg_or_0_operand" "")
1887 (match_operand:DI 2 "reg_or_8bit_operand" "")))
1888 (set (match_operand:DI 0 "register_operand" "")
1889 (if_then_else:DI (eq (match_dup 3) (const_int 0))
1890 (match_dup 1) (match_dup 2)))]
1893 { operands[3] = gen_reg_rtx (DImode);
1897 [(set (match_operand:DI 0 "register_operand" "")
1898 (smax:DI (match_operand:DI 1 "reg_or_0_operand" "")
1899 (match_operand:DI 2 "reg_or_8bit_operand" "")))
1900 (clobber (match_operand:DI 3 "register_operand" ""))]
1901 "operands[2] != const0_rtx"
1902 [(set (match_dup 3) (le:DI (match_dup 1) (match_dup 2)))
1903 (set (match_dup 0) (if_then_else:DI (eq (match_dup 3) (const_int 0))
1904 (match_dup 1) (match_dup 2)))]
1908 [(set (match_operand:DI 0 "register_operand" "=r")
1909 (smax:DI (match_operand:DI 1 "register_operand" "0")
1913 [(set_attr "type" "cmov")])
1915 (define_expand "smindi3"
1917 (lt:DI (match_operand:DI 1 "reg_or_0_operand" "")
1918 (match_operand:DI 2 "reg_or_8bit_operand" "")))
1919 (set (match_operand:DI 0 "register_operand" "")
1920 (if_then_else:DI (ne (match_dup 3) (const_int 0))
1921 (match_dup 1) (match_dup 2)))]
1924 { operands[3] = gen_reg_rtx (DImode);
1928 [(set (match_operand:DI 0 "register_operand" "")
1929 (smin:DI (match_operand:DI 1 "reg_or_0_operand" "")
1930 (match_operand:DI 2 "reg_or_8bit_operand" "")))
1931 (clobber (match_operand:DI 3 "register_operand" ""))]
1932 "operands[2] != const0_rtx"
1933 [(set (match_dup 3) (lt:DI (match_dup 1) (match_dup 2)))
1934 (set (match_dup 0) (if_then_else:DI (ne (match_dup 3) (const_int 0))
1935 (match_dup 1) (match_dup 2)))]
1939 [(set (match_operand:DI 0 "register_operand" "=r")
1940 (smin:DI (match_operand:DI 1 "register_operand" "0")
1944 [(set_attr "type" "cmov")])
1946 (define_expand "umaxdi3"
1948 (leu:DI (match_operand:DI 1 "reg_or_0_operand" "")
1949 (match_operand:DI 2 "reg_or_8bit_operand" "")))
1950 (set (match_operand:DI 0 "register_operand" "")
1951 (if_then_else:DI (eq (match_dup 3) (const_int 0))
1952 (match_dup 1) (match_dup 2)))]
1955 { operands[3] = gen_reg_rtx (DImode);
1959 [(set (match_operand:DI 0 "register_operand" "")
1960 (umax:DI (match_operand:DI 1 "reg_or_0_operand" "")
1961 (match_operand:DI 2 "reg_or_8bit_operand" "")))
1962 (clobber (match_operand:DI 3 "register_operand" ""))]
1963 "operands[2] != const0_rtx"
1964 [(set (match_dup 3) (leu:DI (match_dup 1) (match_dup 2)))
1965 (set (match_dup 0) (if_then_else:DI (eq (match_dup 3) (const_int 0))
1966 (match_dup 1) (match_dup 2)))]
1969 (define_expand "umindi3"
1971 (ltu:DI (match_operand:DI 1 "reg_or_0_operand" "")
1972 (match_operand:DI 2 "reg_or_8bit_operand" "")))
1973 (set (match_operand:DI 0 "register_operand" "")
1974 (if_then_else:DI (ne (match_dup 3) (const_int 0))
1975 (match_dup 1) (match_dup 2)))]
1978 { operands[3] = gen_reg_rtx (DImode);
1982 [(set (match_operand:DI 0 "register_operand" "")
1983 (umin:DI (match_operand:DI 1 "reg_or_0_operand" "")
1984 (match_operand:DI 2 "reg_or_8bit_operand" "")))
1985 (clobber (match_operand:DI 3 "register_operand" ""))]
1986 "operands[2] != const0_rtx"
1987 [(set (match_dup 3) (ltu:DI (match_dup 1) (match_dup 2)))
1988 (set (match_dup 0) (if_then_else:DI (ne (match_dup 3) (const_int 0))
1989 (match_dup 1) (match_dup 2)))]
1995 (match_operator 1 "signed_comparison_operator"
1996 [(match_operand:DI 2 "reg_or_0_operand" "rJ")
1998 (label_ref (match_operand 0 "" ""))
2002 [(set_attr "type" "ibr")])
2007 (ne (zero_extract:DI (match_operand:DI 1 "reg_or_0_operand" "rJ")
2011 (label_ref (match_operand 0 "" ""))
2015 [(set_attr "type" "ibr")])
2020 (eq (zero_extract:DI (match_operand:DI 1 "reg_or_0_operand" "rJ")
2024 (label_ref (match_operand 0 "" ""))
2028 [(set_attr "type" "ibr")])
2034 (match_operator 1 "comparison_operator"
2035 [(zero_extract:DI (match_operand:DI 2 "register_operand" "")
2037 (match_operand:DI 3 "const_int_operand" ""))
2039 (label_ref (match_operand 0 "" ""))
2041 (clobber (match_operand:DI 4 "register_operand" ""))])]
2042 "INTVAL (operands[3]) != 0"
2044 (lshiftrt:DI (match_dup 2) (match_dup 3)))
2046 (if_then_else (match_op_dup 1
2047 [(zero_extract:DI (match_dup 4)
2051 (label_ref (match_dup 0))
2055 ;; The following are the corresponding floating-point insns. Recall
2056 ;; we need to have variants that expand the arguments from SF mode
2060 [(set (match_operand:DF 0 "register_operand" "=&f")
2061 (match_operator:DF 1 "alpha_comparison_operator"
2062 [(match_operand:DF 2 "reg_or_fp0_operand" "fG")
2063 (match_operand:DF 3 "reg_or_fp0_operand" "fG")]))]
2064 "TARGET_FP && alpha_tp == ALPHA_TP_INSN"
2065 "cmpt%C1%' %R2,%R3,%0"
2066 [(set_attr "type" "fadd")
2067 (set_attr "trap" "yes")])
2070 [(set (match_operand:DF 0 "register_operand" "=f")
2071 (match_operator:DF 1 "alpha_comparison_operator"
2072 [(match_operand:DF 2 "reg_or_fp0_operand" "fG")
2073 (match_operand:DF 3 "reg_or_fp0_operand" "fG")]))]
2074 "TARGET_FP && alpha_tp != ALPHA_TP_INSN"
2075 "cmpt%C1%' %R2,%R3,%0"
2076 [(set_attr "type" "fadd")
2077 (set_attr "trap" "yes")])
2080 [(set (match_operand:DF 0 "register_operand" "=f")
2081 (match_operator:DF 1 "alpha_comparison_operator"
2083 (match_operand:SF 2 "reg_or_fp0_operand" "fG"))
2084 (match_operand:DF 3 "reg_or_fp0_operand" "fG")]))]
2085 "TARGET_FP && alpha_tp != ALPHA_TP_INSN"
2086 "cmpt%C1%' %R2,%R3,%0"
2087 [(set_attr "type" "fadd")
2088 (set_attr "trap" "yes")])
2091 [(set (match_operand:DF 0 "register_operand" "=f")
2092 (match_operator:DF 1 "alpha_comparison_operator"
2093 [(match_operand:DF 2 "reg_or_fp0_operand" "fG")
2095 (match_operand:SF 3 "reg_or_fp0_operand" "fG"))]))]
2096 "TARGET_FP && alpha_tp != ALPHA_TP_INSN"
2097 "cmpt%C1%' %R2,%R3,%0"
2098 [(set_attr "type" "fadd")
2099 (set_attr "trap" "yes")])
2102 [(set (match_operand:DF 0 "register_operand" "=f")
2103 (match_operator:DF 1 "alpha_comparison_operator"
2105 (match_operand:SF 2 "reg_or_fp0_operand" "fG"))
2107 (match_operand:SF 3 "reg_or_fp0_operand" "fG"))]))]
2108 "TARGET_FP && alpha_tp != ALPHA_TP_INSN"
2109 "cmpt%C1%' %R2,%R3,%0"
2110 [(set_attr "type" "fadd")
2111 (set_attr "trap" "yes")])
2114 [(set (match_operand:DF 0 "register_operand" "=&f,f")
2116 (match_operator 3 "signed_comparison_operator"
2117 [(match_operand:DF 4 "reg_or_fp0_operand" "fG,fG")
2118 (match_operand:DF 2 "fp0_operand" "G,G")])
2119 (match_operand:DF 1 "reg_or_fp0_operand" "fG,0")
2120 (match_operand:DF 5 "reg_or_fp0_operand" "0,fG")))]
2121 "TARGET_FP && alpha_tp == ALPHA_TP_INSN"
2124 fcmov%D3 %R4,%R5,%0"
2125 [(set_attr "type" "fadd")])
2128 [(set (match_operand:DF 0 "register_operand" "=f,f")
2130 (match_operator 3 "signed_comparison_operator"
2131 [(match_operand:DF 4 "reg_or_fp0_operand" "fG,fG")
2132 (match_operand:DF 2 "fp0_operand" "G,G")])
2133 (match_operand:DF 1 "reg_or_fp0_operand" "fG,0")
2134 (match_operand:DF 5 "reg_or_fp0_operand" "0,fG")))]
2135 "TARGET_FP && alpha_tp != ALPHA_TP_INSN"
2138 fcmov%D3 %R4,%R5,%0"
2139 [(set_attr "type" "fadd")])
2142 [(set (match_operand:SF 0 "register_operand" "=&f,f")
2144 (match_operator 3 "signed_comparison_operator"
2145 [(match_operand:DF 4 "reg_or_fp0_operand" "fG,fG")
2146 (match_operand:DF 2 "fp0_operand" "G,G")])
2147 (match_operand:SF 1 "reg_or_fp0_operand" "fG,0")
2148 (match_operand:SF 5 "reg_or_fp0_operand" "0,fG")))]
2149 "TARGET_FP && alpha_tp == ALPHA_TP_INSN"
2152 fcmov%D3 %R4,%R5,%0"
2153 [(set_attr "type" "fadd")])
2156 [(set (match_operand:SF 0 "register_operand" "=f,f")
2158 (match_operator 3 "signed_comparison_operator"
2159 [(match_operand:DF 4 "reg_or_fp0_operand" "fG,fG")
2160 (match_operand:DF 2 "fp0_operand" "G,G")])
2161 (match_operand:SF 1 "reg_or_fp0_operand" "fG,0")
2162 (match_operand:SF 5 "reg_or_fp0_operand" "0,fG")))]
2163 "TARGET_FP && alpha_tp != ALPHA_TP_INSN"
2166 fcmov%D3 %R4,%R5,%0"
2167 [(set_attr "type" "fadd")])
2170 [(set (match_operand:DF 0 "register_operand" "=f,f")
2172 (match_operator 3 "signed_comparison_operator"
2173 [(match_operand:DF 1 "reg_or_fp0_operand" "fG,fG")
2174 (match_operand:DF 2 "fp0_operand" "G,G")])
2175 (float_extend:DF (match_operand:SF 4 "reg_or_fp0_operand" "fG,0"))
2176 (match_operand:DF 5 "reg_or_fp0_operand" "0,fG")))]
2177 "TARGET_FP && alpha_tp != ALPHA_TP_INSN"
2180 fcmov%D3 %R4,%R5,%0"
2181 [(set_attr "type" "fadd")])
2184 [(set (match_operand:DF 0 "register_operand" "=f,f")
2186 (match_operator 3 "signed_comparison_operator"
2188 (match_operand:SF 4 "reg_or_fp0_operand" "fG,fG"))
2189 (match_operand:DF 2 "fp0_operand" "G,G")])
2190 (match_operand:DF 1 "reg_or_fp0_operand" "fG,0")
2191 (match_operand:DF 5 "reg_or_fp0_operand" "0,fG")))]
2192 "TARGET_FP && alpha_tp != ALPHA_TP_INSN"
2195 fcmov%D3 %R4,%R5,%0"
2196 [(set_attr "type" "fadd")])
2199 [(set (match_operand:SF 0 "register_operand" "=f,f")
2201 (match_operator 3 "signed_comparison_operator"
2203 (match_operand:SF 4 "reg_or_fp0_operand" "fG,fG"))
2204 (match_operand:DF 2 "fp0_operand" "G,G")])
2205 (match_operand:SF 1 "reg_or_fp0_operand" "fG,0")
2206 (match_operand:SF 5 "reg_or_fp0_operand" "0,fG")))]
2207 "TARGET_FP && alpha_tp != ALPHA_TP_INSN"
2210 fcmov%D3 %R4,%R5,%0"
2211 [(set_attr "type" "fadd")])
2214 [(set (match_operand:DF 0 "register_operand" "=f,f")
2216 (match_operator 3 "signed_comparison_operator"
2218 (match_operand:SF 4 "reg_or_fp0_operand" "fG,fG"))
2219 (match_operand:DF 2 "fp0_operand" "G,G")])
2220 (float_extend:DF (match_operand:SF 1 "reg_or_fp0_operand" "fG,0"))
2221 (match_operand:DF 5 "reg_or_fp0_operand" "0,fG")))]
2222 "TARGET_FP && alpha_tp != ALPHA_TP_INSN"
2225 fcmov%D3 %R4,%R5,%0"
2226 [(set_attr "type" "fadd")])
2228 (define_expand "maxdf3"
2230 (le:DF (match_operand:DF 1 "reg_or_fp0_operand" "")
2231 (match_operand:DF 2 "reg_or_fp0_operand" "")))
2232 (set (match_operand:DF 0 "register_operand" "")
2233 (if_then_else:DF (eq (match_dup 3) (match_dup 4))
2234 (match_dup 1) (match_dup 2)))]
2237 { operands[3] = gen_reg_rtx (DFmode);
2238 operands[4] = CONST0_RTX (DFmode);
2241 (define_expand "mindf3"
2243 (lt:DF (match_operand:DF 1 "reg_or_fp0_operand" "")
2244 (match_operand:DF 2 "reg_or_fp0_operand" "")))
2245 (set (match_operand:DF 0 "register_operand" "")
2246 (if_then_else:DF (ne (match_dup 3) (match_dup 4))
2247 (match_dup 1) (match_dup 2)))]
2250 { operands[3] = gen_reg_rtx (DFmode);
2251 operands[4] = CONST0_RTX (DFmode);
2254 (define_expand "maxsf3"
2256 (le:DF (float_extend:DF (match_operand:SF 1 "reg_or_fp0_operand" ""))
2257 (float_extend:DF (match_operand:SF 2 "reg_or_fp0_operand" ""))))
2258 (set (match_operand:SF 0 "register_operand" "")
2259 (if_then_else:SF (eq (match_dup 3) (match_dup 4))
2260 (match_dup 1) (match_dup 2)))]
2263 { operands[3] = gen_reg_rtx (DFmode);
2264 operands[4] = CONST0_RTX (DFmode);
2267 (define_expand "minsf3"
2269 (lt:DF (float_extend:DF (match_operand:SF 1 "reg_or_fp0_operand" ""))
2270 (float_extend:DF (match_operand:SF 2 "reg_or_fp0_operand" ""))))
2271 (set (match_operand:SF 0 "register_operand" "")
2272 (if_then_else:SF (ne (match_dup 3) (match_dup 4))
2273 (match_dup 1) (match_dup 2)))]
2276 { operands[3] = gen_reg_rtx (DFmode);
2277 operands[4] = CONST0_RTX (DFmode);
2283 (match_operator 1 "signed_comparison_operator"
2284 [(match_operand:DF 2 "reg_or_fp0_operand" "fG")
2285 (match_operand:DF 3 "fp0_operand" "G")])
2286 (label_ref (match_operand 0 "" ""))
2290 [(set_attr "type" "fbr")])
2295 (match_operator 1 "signed_comparison_operator"
2297 (match_operand:SF 2 "reg_or_fp0_operand" "fG"))
2298 (match_operand:DF 3 "fp0_operand" "G")])
2299 (label_ref (match_operand 0 "" ""))
2303 [(set_attr "type" "fbr")])
2305 ;; These are the main define_expand's used to make conditional branches
2308 (define_expand "cmpdf"
2309 [(set (cc0) (compare (match_operand:DF 0 "reg_or_fp0_operand" "")
2310 (match_operand:DF 1 "reg_or_fp0_operand" "")))]
2314 alpha_compare_op0 = operands[0];
2315 alpha_compare_op1 = operands[1];
2316 alpha_compare_fp_p = 1;
2320 (define_expand "cmpdi"
2321 [(set (cc0) (compare (match_operand:DI 0 "reg_or_0_operand" "")
2322 (match_operand:DI 1 "reg_or_8bit_operand" "")))]
2326 alpha_compare_op0 = operands[0];
2327 alpha_compare_op1 = operands[1];
2328 alpha_compare_fp_p = 0;
2332 (define_expand "beq"
2333 [(set (match_dup 1) (match_dup 2))
2335 (if_then_else (match_dup 3)
2336 (label_ref (match_operand 0 "" ""))
2341 enum machine_mode mode;
2342 enum rtx_code compare_code, branch_code;
2344 if (alpha_compare_fp_p)
2345 mode = DFmode, compare_code = EQ, branch_code = NE;
2348 mode = DImode, compare_code = MINUS, branch_code = EQ;
2349 if (GET_CODE (alpha_compare_op1) == CONST_INT)
2351 compare_code = PLUS;
2352 alpha_compare_op1 = GEN_INT (- INTVAL (alpha_compare_op1));
2356 operands[1] = gen_reg_rtx (mode);
2357 operands[2] = gen_rtx (compare_code, mode,
2358 alpha_compare_op0, alpha_compare_op1);
2359 operands[3] = gen_rtx (branch_code, VOIDmode,
2360 operands[1], CONST0_RTX (mode));
2363 (define_expand "bne"
2364 [(set (match_dup 1) (match_dup 2))
2366 (if_then_else (match_dup 3)
2367 (label_ref (match_operand 0 "" ""))
2372 enum machine_mode mode;
2373 enum rtx_code compare_code, branch_code;
2375 if (alpha_compare_fp_p)
2376 mode = DFmode, compare_code = EQ, branch_code = EQ;
2379 mode = DImode, compare_code = MINUS, branch_code = NE;
2380 if (GET_CODE (alpha_compare_op1) == CONST_INT)
2382 compare_code = PLUS;
2383 alpha_compare_op1 = GEN_INT (- INTVAL (alpha_compare_op1));
2387 operands[1] = gen_reg_rtx (mode);
2388 operands[2] = gen_rtx (compare_code, mode,
2389 alpha_compare_op0, alpha_compare_op1);
2390 operands[3] = gen_rtx (branch_code, VOIDmode,
2391 operands[1], CONST0_RTX (mode));
2394 (define_expand "blt"
2395 [(set (match_dup 1) (match_dup 2))
2397 (if_then_else (match_dup 3)
2398 (label_ref (match_operand 0 "" ""))
2403 enum machine_mode mode = alpha_compare_fp_p ? DFmode : DImode;
2404 operands[1] = gen_reg_rtx (mode);
2405 operands[2] = gen_rtx (LT, mode, alpha_compare_op0, alpha_compare_op1);
2406 operands[3] = gen_rtx (NE, VOIDmode, operands[1], CONST0_RTX (mode));
2409 (define_expand "ble"
2410 [(set (match_dup 1) (match_dup 2))
2412 (if_then_else (match_dup 3)
2413 (label_ref (match_operand 0 "" ""))
2418 enum machine_mode mode = alpha_compare_fp_p ? DFmode : DImode;
2419 operands[1] = gen_reg_rtx (mode);
2420 operands[2] = gen_rtx (LE, mode, alpha_compare_op0, alpha_compare_op1);
2421 operands[3] = gen_rtx (NE, VOIDmode, operands[1], CONST0_RTX (mode));
2424 (define_expand "bgt"
2425 [(set (match_dup 1) (match_dup 2))
2427 (if_then_else (match_dup 3)
2428 (label_ref (match_operand 0 "" ""))
2433 if (alpha_compare_fp_p)
2435 operands[1] = gen_reg_rtx (DFmode);
2436 operands[2] = gen_rtx (LT, DFmode, alpha_compare_op1, alpha_compare_op0);
2437 operands[3] = gen_rtx (NE, VOIDmode, operands[1], CONST0_RTX (DFmode));
2441 operands[1] = gen_reg_rtx (DImode);
2442 operands[2] = gen_rtx (LE, DImode, alpha_compare_op0, alpha_compare_op1);
2443 operands[3] = gen_rtx (EQ, VOIDmode, operands[1], const0_rtx);
2447 (define_expand "bge"
2448 [(set (match_dup 1) (match_dup 2))
2450 (if_then_else (match_dup 3)
2451 (label_ref (match_operand 0 "" ""))
2456 if (alpha_compare_fp_p)
2458 operands[1] = gen_reg_rtx (DFmode);
2459 operands[2] = gen_rtx (LE, DFmode, alpha_compare_op1, alpha_compare_op0);
2460 operands[3] = gen_rtx (NE, VOIDmode, operands[1], CONST0_RTX (DFmode));
2464 operands[1] = gen_reg_rtx (DImode);
2465 operands[2] = gen_rtx (LT, DImode, alpha_compare_op0, alpha_compare_op1);
2466 operands[3] = gen_rtx (EQ, VOIDmode, operands[1], const0_rtx);
2470 (define_expand "bltu"
2471 [(set (match_dup 1) (match_dup 2))
2473 (if_then_else (match_dup 3)
2474 (label_ref (match_operand 0 "" ""))
2479 operands[1] = gen_reg_rtx (DImode);
2480 operands[2] = gen_rtx (LTU, DImode, alpha_compare_op0, alpha_compare_op1);
2481 operands[3] = gen_rtx (NE, VOIDmode, operands[1], const0_rtx);
2484 (define_expand "bleu"
2485 [(set (match_dup 1) (match_dup 2))
2487 (if_then_else (match_dup 3)
2488 (label_ref (match_operand 0 "" ""))
2493 operands[1] = gen_reg_rtx (DImode);
2494 operands[2] = gen_rtx (LEU, DImode, alpha_compare_op0, alpha_compare_op1);
2495 operands[3] = gen_rtx (NE, VOIDmode, operands[1], const0_rtx);
2498 (define_expand "bgtu"
2499 [(set (match_dup 1) (match_dup 2))
2501 (if_then_else (match_dup 3)
2502 (label_ref (match_operand 0 "" ""))
2507 operands[1] = gen_reg_rtx (DImode);
2508 operands[2] = gen_rtx (LEU, DImode, alpha_compare_op0, alpha_compare_op1);
2509 operands[3] = gen_rtx (EQ, VOIDmode, operands[1], const0_rtx);
2512 (define_expand "bgeu"
2513 [(set (match_dup 1) (match_dup 2))
2515 (if_then_else (match_dup 3)
2516 (label_ref (match_operand 0 "" ""))
2521 operands[1] = gen_reg_rtx (DImode);
2522 operands[2] = gen_rtx (LTU, DImode, alpha_compare_op0, alpha_compare_op1);
2523 operands[3] = gen_rtx (EQ, VOIDmode, operands[1], const0_rtx);
2526 (define_expand "seq"
2527 [(set (match_operand:DI 0 "register_operand" "")
2532 if (alpha_compare_fp_p)
2535 operands[1] = gen_rtx (EQ, DImode, alpha_compare_op0, alpha_compare_op1);
2538 (define_expand "sne"
2539 [(set (match_operand:DI 0 "register_operand" "")
2541 (set (match_dup 0) (xor:DI (match_dup 0) (const_int 1)))]
2545 if (alpha_compare_fp_p)
2548 operands[1] = gen_rtx (EQ, DImode, alpha_compare_op0, alpha_compare_op1);
2551 (define_expand "slt"
2552 [(set (match_operand:DI 0 "register_operand" "")
2557 if (alpha_compare_fp_p)
2560 operands[1] = gen_rtx (LT, DImode, alpha_compare_op0, alpha_compare_op1);
2563 (define_expand "sle"
2564 [(set (match_operand:DI 0 "register_operand" "")
2569 if (alpha_compare_fp_p)
2572 operands[1] = gen_rtx (LE, DImode, alpha_compare_op0, alpha_compare_op1);
2575 (define_expand "sgt"
2576 [(set (match_operand:DI 0 "register_operand" "")
2581 if (alpha_compare_fp_p)
2584 operands[1] = gen_rtx (LT, DImode, force_reg (DImode, alpha_compare_op1),
2588 (define_expand "sge"
2589 [(set (match_operand:DI 0 "register_operand" "")
2594 if (alpha_compare_fp_p)
2597 operands[1] = gen_rtx (LE, DImode, force_reg (DImode, alpha_compare_op1),
2601 (define_expand "sltu"
2602 [(set (match_operand:DI 0 "register_operand" "")
2607 if (alpha_compare_fp_p)
2610 operands[1] = gen_rtx (LTU, DImode, alpha_compare_op0, alpha_compare_op1);
2613 (define_expand "sleu"
2614 [(set (match_operand:DI 0 "register_operand" "")
2619 if (alpha_compare_fp_p)
2622 operands[1] = gen_rtx (LEU, DImode, alpha_compare_op0, alpha_compare_op1);
2625 (define_expand "sgtu"
2626 [(set (match_operand:DI 0 "register_operand" "")
2631 if (alpha_compare_fp_p)
2634 operands[1] = gen_rtx (LTU, DImode, force_reg (DImode, alpha_compare_op1),
2638 (define_expand "sgeu"
2639 [(set (match_operand:DI 0 "register_operand" "")
2644 if (alpha_compare_fp_p)
2647 operands[1] = gen_rtx (LEU, DImode, force_reg (DImode, alpha_compare_op1),
2651 ;; These are the main define_expand's used to make conditional moves.
2653 (define_expand "movsicc"
2654 [(set (match_operand:SI 0 "register_operand" "")
2655 (if_then_else:DI (match_operand 1 "comparison_operator" "")
2656 (match_operand:SI 2 "reg_or_8bit_operand" "")
2657 (match_operand:SI 3 "reg_or_8bit_operand" "")))]
2661 if ((operands[1] = alpha_emit_conditional_move (operands[1], SImode)) == 0)
2665 (define_expand "movdicc"
2666 [(set (match_operand:DI 0 "register_operand" "")
2667 (if_then_else:DI (match_operand 1 "comparison_operator" "")
2668 (match_operand:DI 2 "reg_or_8bit_operand" "")
2669 (match_operand:DI 3 "reg_or_8bit_operand" "")))]
2673 if ((operands[1] = alpha_emit_conditional_move (operands[1], DImode)) == 0)
2677 (define_expand "movsfcc"
2678 [(set (match_operand:SF 0 "register_operand" "")
2679 (if_then_else:SF (match_operand 1 "comparison_operator" "")
2680 (match_operand:SF 2 "reg_or_8bit_operand" "")
2681 (match_operand:SF 3 "reg_or_8bit_operand" "")))]
2685 if ((operands[1] = alpha_emit_conditional_move (operands[1], SFmode)) == 0)
2689 (define_expand "movdfcc"
2690 [(set (match_operand:DF 0 "register_operand" "")
2691 (if_then_else:DF (match_operand 1 "comparison_operator" "")
2692 (match_operand:DF 2 "reg_or_8bit_operand" "")
2693 (match_operand:DF 3 "reg_or_8bit_operand" "")))]
2697 if ((operands[1] = alpha_emit_conditional_move (operands[1], DFmode)) == 0)
2701 ;; These define_split definitions are used in cases when comparisons have
2702 ;; not be stated in the correct way and we need to reverse the second
2703 ;; comparison. For example, x >= 7 has to be done as x < 6 with the
2704 ;; comparison that tests the result being reversed. We have one define_split
2705 ;; for each use of a comparison. They do not match valid insns and need
2706 ;; not generate valid insns.
2708 ;; We can also handle equality comparisons (and inequality comparisons in
2709 ;; cases where the resulting add cannot overflow) by doing an add followed by
2710 ;; a comparison with zero. This is faster since the addition takes one
2711 ;; less cycle than a compare when feeding into a conditional move.
2712 ;; For this case, we also have an SImode pattern since we can merge the add
2713 ;; and sign extend and the order doesn't matter.
2715 ;; We do not do this for floating-point, since it isn't clear how the "wrong"
2716 ;; operation could have been generated.
2719 [(set (match_operand:DI 0 "register_operand" "")
2721 (match_operator 1 "comparison_operator"
2722 [(match_operand:DI 2 "reg_or_0_operand" "")
2723 (match_operand:DI 3 "reg_or_cint_operand" "")])
2724 (match_operand:DI 4 "reg_or_cint_operand" "")
2725 (match_operand:DI 5 "reg_or_cint_operand" "")))
2726 (clobber (match_operand:DI 6 "register_operand" ""))]
2727 "operands[3] != const0_rtx"
2728 [(set (match_dup 6) (match_dup 7))
2730 (if_then_else:DI (match_dup 8) (match_dup 4) (match_dup 5)))]
2732 { enum rtx_code code = GET_CODE (operands[1]);
2733 int unsignedp = (code == GEU || code == LEU || code == GTU || code == LTU);
2735 /* If we are comparing for equality with a constant and that constant
2736 appears in the arm when the register equals the constant, use the
2737 register since that is more likely to match (and to produce better code
2740 if (code == EQ && GET_CODE (operands[3]) == CONST_INT
2741 && rtx_equal_p (operands[4], operands[3]))
2742 operands[4] = operands[2];
2744 else if (code == NE && GET_CODE (operands[3]) == CONST_INT
2745 && rtx_equal_p (operands[5], operands[3]))
2746 operands[5] = operands[2];
2748 if (code == NE || code == EQ
2749 || (extended_count (operands[2], DImode, unsignedp) >= 1
2750 && extended_count (operands[3], DImode, unsignedp) >= 1))
2752 if (GET_CODE (operands[3]) == CONST_INT)
2753 operands[7] = gen_rtx (PLUS, DImode, operands[2],
2754 GEN_INT (- INTVAL (operands[3])));
2756 operands[7] = gen_rtx (MINUS, DImode, operands[2], operands[3]);
2758 operands[8] = gen_rtx (code, VOIDmode, operands[6], const0_rtx);
2761 else if (code == EQ || code == LE || code == LT
2762 || code == LEU || code == LTU)
2764 operands[7] = gen_rtx (code, DImode, operands[2], operands[3]);
2765 operands[8] = gen_rtx (NE, VOIDmode, operands[6], const0_rtx);
2769 operands[7] = gen_rtx (reverse_condition (code), DImode, operands[2],
2771 operands[8] = gen_rtx (EQ, VOIDmode, operands[6], const0_rtx);
2776 [(set (match_operand:DI 0 "register_operand" "")
2778 (match_operator 1 "comparison_operator"
2779 [(match_operand:SI 2 "reg_or_0_operand" "")
2780 (match_operand:SI 3 "reg_or_cint_operand" "")])
2781 (match_operand:DI 4 "reg_or_8bit_operand" "")
2782 (match_operand:DI 5 "reg_or_8bit_operand" "")))
2783 (clobber (match_operand:DI 6 "register_operand" ""))]
2784 "operands[3] != const0_rtx
2785 && (GET_CODE (operands[1]) == EQ || GET_CODE (operands[1]) == NE)"
2786 [(set (match_dup 6) (match_dup 7))
2788 (if_then_else:DI (match_dup 8) (match_dup 4) (match_dup 5)))]
2790 { enum rtx_code code = GET_CODE (operands[1]);
2791 int unsignedp = (code == GEU || code == LEU || code == GTU || code == LTU);
2794 if ((code != NE && code != EQ
2795 && ! (extended_count (operands[2], DImode, unsignedp) >= 1
2796 && extended_count (operands[3], DImode, unsignedp) >= 1)))
2799 if (GET_CODE (operands[3]) == CONST_INT)
2800 tem = gen_rtx (PLUS, SImode, operands[2],
2801 GEN_INT (- INTVAL (operands[3])));
2803 tem = gen_rtx (MINUS, SImode, operands[2], operands[3]);
2805 operands[7] = gen_rtx (SIGN_EXTEND, DImode, tem);
2806 operands[8] = gen_rtx (GET_CODE (operands[1]), VOIDmode, operands[6],
2813 (match_operator 1 "comparison_operator"
2814 [(match_operand:DI 2 "reg_or_0_operand" "")
2815 (match_operand:DI 3 "reg_or_cint_operand" "")])
2816 (label_ref (match_operand 0 "" ""))
2818 (clobber (match_operand:DI 4 "register_operand" ""))]
2819 "operands[3] != const0_rtx"
2820 [(set (match_dup 4) (match_dup 5))
2821 (set (pc) (if_then_else (match_dup 6) (label_ref (match_dup 0)) (pc)))]
2823 { enum rtx_code code = GET_CODE (operands[1]);
2824 int unsignedp = (code == GEU || code == LEU || code == GTU || code == LTU);
2826 if (code == NE || code == EQ
2827 || (extended_count (operands[2], DImode, unsignedp) >= 1
2828 && extended_count (operands[3], DImode, unsignedp) >= 1))
2830 if (GET_CODE (operands[3]) == CONST_INT)
2831 operands[5] = gen_rtx (PLUS, DImode, operands[2],
2832 GEN_INT (- INTVAL (operands[3])));
2834 operands[5] = gen_rtx (MINUS, DImode, operands[2], operands[3]);
2836 operands[6] = gen_rtx (code, VOIDmode, operands[4], const0_rtx);
2839 else if (code == EQ || code == LE || code == LT
2840 || code == LEU || code == LTU)
2842 operands[5] = gen_rtx (code, DImode, operands[2], operands[3]);
2843 operands[6] = gen_rtx (NE, VOIDmode, operands[4], const0_rtx);
2847 operands[5] = gen_rtx (reverse_condition (code), DImode, operands[2],
2849 operands[6] = gen_rtx (EQ, VOIDmode, operands[4], const0_rtx);
2856 (match_operator 1 "comparison_operator"
2857 [(match_operand:SI 2 "reg_or_0_operand" "")
2858 (match_operand:SI 3 "const_int_operand" "")])
2859 (label_ref (match_operand 0 "" ""))
2861 (clobber (match_operand:DI 4 "register_operand" ""))]
2862 "operands[3] != const0_rtx
2863 && (GET_CODE (operands[1]) == EQ || GET_CODE (operands[1]) == NE)"
2864 [(set (match_dup 4) (match_dup 5))
2865 (set (pc) (if_then_else (match_dup 6) (label_ref (match_dup 0)) (pc)))]
2869 if (GET_CODE (operands[3]) == CONST_INT)
2870 tem = gen_rtx (PLUS, SImode, operands[2],
2871 GEN_INT (- INTVAL (operands[3])));
2873 tem = gen_rtx (MINUS, SImode, operands[2], operands[3]);
2875 operands[5] = gen_rtx (SIGN_EXTEND, DImode, tem);
2876 operands[6] = gen_rtx (GET_CODE (operands[1]), VOIDmode,
2877 operands[4], const0_rtx);
2880 ;; We can convert such things as "a > 0xffff" to "t = a & ~ 0xffff; t != 0".
2881 ;; This eliminates one, and sometimes two, insns when the AND can be done
2884 [(set (match_operand:DI 0 "register_operand" "")
2885 (match_operator 1 "comparison_operator"
2886 [(match_operand:DI 2 "register_operand" "")
2887 (match_operand:DI 3 "const_int_operand" "")]))
2888 (clobber (match_operand:DI 4 "register_operand" ""))]
2889 "exact_log2 (INTVAL (operands[3]) + 1) >= 0
2890 && (GET_CODE (operands[1]) == GTU
2891 || GET_CODE (operands[1]) == LEU
2892 || ((GET_CODE (operands[1]) == GT || GET_CODE (operands[1]) == LE)
2893 && extended_count (operands[2], DImode, 1) > 0))"
2894 [(set (match_dup 4) (and:DI (match_dup 2) (match_dup 5)))
2895 (set (match_dup 0) (match_dup 6))]
2898 operands[5] = GEN_INT (~ INTVAL (operands[3]));
2899 operands[6] = gen_rtx (((GET_CODE (operands[1]) == GTU
2900 || GET_CODE (operands[1]) == GT)
2902 DImode, operands[4], const0_rtx);
2905 ;; Here are the CALL and unconditional branch insns. Calls on NT and OSF
2906 ;; work differently, so we have different patterns for each.
2908 (define_expand "call"
2909 [(use (match_operand:DI 0 "" ""))
2910 (use (match_operand 1 "" ""))]
2913 { if (TARGET_WINDOWS_NT)
2914 emit_call_insn (gen_call_nt (operands[0], operands[1]));
2916 emit_call_insn (gen_call_osf (operands[0], operands[1]));
2921 (define_expand "call_osf"
2922 [(parallel [(call (mem:DI (match_operand 0 "" ""))
2923 (match_operand 1 "" ""))
2924 (clobber (reg:DI 27))
2925 (clobber (reg:DI 26))])]
2928 { if (GET_CODE (operands[0]) != MEM)
2931 operands[0] = XEXP (operands[0], 0);
2933 if (GET_CODE (operands[0]) != SYMBOL_REF
2934 && ! (GET_CODE (operands[0]) == REG && REGNO (operands[0]) == 27))
2936 rtx tem = gen_rtx (REG, DImode, 27);
2937 emit_move_insn (tem, operands[0]);
2942 (define_expand "call_nt"
2943 [(parallel [(call (mem:DI (match_operand:DI 0 "" ""))
2944 (match_operand 1 "" ""))
2945 (clobber (reg:DI 26))])]
2948 { if (GET_CODE (operands[0]) != MEM)
2950 operands[0] = XEXP (operands[0], 0);
2952 if (GET_CODE (operands[1]) != SYMBOL_REF
2953 && ! (GET_CODE (operands[1]) == REG && REGNO (operands[1]) == 27))
2955 rtx tem = gen_rtx (REG, DImode, 27);
2956 emit_move_insn (tem, operands[1]);
2961 (define_expand "call_value"
2962 [(use (match_operand 0 "" ""))
2963 (use (match_operand:DI 1 "" ""))
2964 (use (match_operand 2 "" ""))]
2967 { if (TARGET_WINDOWS_NT)
2968 emit_call_insn (gen_call_value_nt (operands[0], operands[1], operands[2]));
2970 emit_call_insn (gen_call_value_osf (operands[0], operands[1],
2975 (define_expand "call_value_osf"
2976 [(parallel [(set (match_operand 0 "" "")
2977 (call (mem:DI (match_operand 1 "" ""))
2978 (match_operand 2 "" "")))
2979 (clobber (reg:DI 27))
2980 (clobber (reg:DI 26))])]
2983 { if (GET_CODE (operands[1]) != MEM)
2986 operands[1] = XEXP (operands[1], 0);
2988 if (GET_CODE (operands[1]) != SYMBOL_REF
2989 && ! (GET_CODE (operands[1]) == REG && REGNO (operands[1]) == 27))
2991 rtx tem = gen_rtx (REG, DImode, 27);
2992 emit_move_insn (tem, operands[1]);
2997 (define_expand "call_value_nt"
2998 [(parallel [(set (match_operand 0 "" "")
2999 (call (mem:DI (match_operand:DI 1 "" ""))
3000 (match_operand 2 "" "")))
3001 (clobber (reg:DI 26))])]
3004 { if (GET_CODE (operands[1]) != MEM)
3007 operands[1] = XEXP (operands[1], 0);
3008 if (GET_CODE (operands[1]) != SYMBOL_REF
3009 && ! (GET_CODE (operands[1]) == REG && REGNO (operands[1]) == 27))
3011 rtx tem = gen_rtx (REG, DImode, 27);
3012 emit_move_insn (tem, operands[1]);
3018 [(call (mem:DI (match_operand:DI 0 "call_operand" "r,R,i"))
3019 (match_operand 1 "" ""))
3020 (clobber (reg:DI 27))
3021 (clobber (reg:DI 26))]
3022 "! TARGET_WINDOWS_NT && alpha_tp == ALPHA_TP_INSN"
3024 jsr $26,($27),0\;trapb\;ldgp $29,4($26)
3025 bsr $26,%0..ng\;trapb
3026 jsr $26,%0\;trapb\;ldgp $29,4($26)"
3027 [(set_attr "type" "jsr,jsr,ibr")])
3030 [(call (mem:DI (match_operand:DI 0 "call_operand" "r,R,i"))
3031 (match_operand 1 "" ""))
3032 (clobber (reg:DI 27))
3033 (clobber (reg:DI 26))]
3034 "! TARGET_WINDOWS_NT"
3036 jsr $26,($27),0\;ldgp $29,0($26)
3038 jsr $26,%0\;ldgp $29,0($26)"
3039 [(set_attr "type" "jsr,jsr,ibr")])
3042 [(call (mem:DI (match_operand:DI 0 "call_operand" "r,i"))
3043 (match_operand 1 "" ""))
3044 (clobber (reg:DI 26))]
3049 [(set_attr "type" "jsr")])
3052 [(set (match_operand 0 "register_operand" "=rf,rf,rf")
3053 (call (mem:DI (match_operand:DI 1 "call_operand" "r,R,i"))
3054 (match_operand 2 "" "")))
3055 (clobber (reg:DI 27))
3056 (clobber (reg:DI 26))]
3057 "! TARGET_WINDOWS_NT && alpha_tp == ALPHA_TP_INSN"
3059 jsr $26,($27),0\;trapb\;ldgp $29,4($26)
3060 bsr $26,%1..ng\;trapb
3061 jsr $26,%1\;trapb\;ldgp $29,4($26)"
3062 [(set_attr "type" "jsr,jsr,ibr")])
3065 [(set (match_operand 0 "register_operand" "=rf,rf,rf")
3066 (call (mem:DI (match_operand:DI 1 "call_operand" "r,R,i"))
3067 (match_operand 2 "" "")))
3068 (clobber (reg:DI 27))
3069 (clobber (reg:DI 26))]
3070 "! TARGET_WINDOWS_NT"
3072 jsr $26,($27),0\;ldgp $29,0($26)
3074 jsr $26,%1\;ldgp $29,0($26)"
3075 [(set_attr "type" "jsr,jsr,ibr")])
3078 [(set (match_operand 0 "register_operand" "=rf,rf")
3079 (call (mem:DI (match_operand:DI 1 "call_operand" "r,i"))
3080 (match_operand 2 "" "")))
3081 (clobber (reg:DI 26))]
3086 [(set_attr "type" "jsr")])
3088 ;; Call subroutine returning any type.
3090 (define_expand "untyped_call"
3091 [(parallel [(call (match_operand 0 "" "")
3093 (match_operand 1 "" "")
3094 (match_operand 2 "" "")])]
3100 emit_call_insn (gen_call (operands[0], const0_rtx, NULL, const0_rtx));
3102 for (i = 0; i < XVECLEN (operands[2], 0); i++)
3104 rtx set = XVECEXP (operands[2], 0, i);
3105 emit_move_insn (SET_DEST (set), SET_SRC (set));
3108 /* The optimizer does not know that the call sets the function value
3109 registers we stored in the result block. We avoid problems by
3110 claiming that all hard registers are used and clobbered at this
3112 emit_insn (gen_blockage ());
3117 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
3118 ;; all of memory. This blocks insns from being moved across this point.
3120 (define_insn "blockage"
3121 [(unspec_volatile [(const_int 0)] 1)]
3127 (label_ref (match_operand 0 "" "")))]
3130 [(set_attr "type" "ibr")])
3132 (define_insn "return"
3136 [(set_attr "type" "ibr")])
3138 (define_insn "indirect_jump"
3139 [(set (pc) (match_operand:DI 0 "register_operand" "r"))]
3142 [(set_attr "type" "ibr")])
3148 [(set_attr "type" "ilog")])
3150 (define_expand "tablejump"
3151 [(use (match_operand:SI 0 "register_operand" ""))
3152 (use (match_operand:SI 1 "" ""))]
3156 if (TARGET_WINDOWS_NT)
3157 emit_jump_insn (gen_tablejump_nt (operands[0], operands[1]));
3159 emit_jump_insn (gen_tablejump_osf (operands[0], operands[1]));
3164 (define_expand "tablejump_osf"
3166 (sign_extend:DI (match_operand:SI 0 "register_operand" "")))
3167 (parallel [(set (pc)
3168 (plus:DI (match_dup 3)
3169 (label_ref:DI (match_operand 1 "" ""))))
3170 (clobber (match_scratch:DI 2 "=r"))])]
3173 { operands[3] = gen_reg_rtx (DImode); }")
3175 (define_expand "tablejump_nt"
3177 (sign_extend:DI (match_operand:SI 0 "register_operand" "")))
3178 (parallel [(set (pc)
3180 (use (label_ref (match_operand 1 "" "")))])]
3183 { operands[3] = gen_reg_rtx (DImode); }")
3187 (plus:DI (match_operand:DI 0 "register_operand" "r")
3188 (label_ref:DI (match_operand 1 "" ""))))
3189 (clobber (match_scratch:DI 2 "=r"))]
3190 "! TARGET_WINDOWS_NT && next_active_insn (insn) != 0
3191 && GET_CODE (PATTERN (next_active_insn (insn))) == ADDR_DIFF_VEC
3192 && PREV_INSN (next_active_insn (insn)) == operands[1]"
3194 { rtx best_label = 0;
3195 rtx jump_table_insn = next_active_insn (operands[1]);
3197 if (GET_CODE (jump_table_insn) == JUMP_INSN
3198 && GET_CODE (PATTERN (jump_table_insn)) == ADDR_DIFF_VEC)
3200 rtx jump_table = PATTERN (jump_table_insn);
3201 int n_labels = XVECLEN (jump_table, 1);
3202 int best_count = -1;
3205 for (i = 0; i < n_labels; i++)
3209 for (j = i + 1; j < n_labels; j++)
3210 if (XEXP (XVECEXP (jump_table, 1, i), 0)
3211 == XEXP (XVECEXP (jump_table, 1, j), 0))
3214 if (count > best_count)
3215 best_count = count, best_label = XVECEXP (jump_table, 1, i);
3221 operands[3] = best_label;
3222 return \"addq %0,$29,%2\;jmp $31,(%2),%3\";
3225 return \"addq %0,$29,%2\;jmp $31,(%2),0\";
3227 [(set_attr "type" "ibr")])
3231 (match_operand:DI 0 "register_operand" "r"))
3232 (use (label_ref (match_operand 1 "" "")))]
3233 "TARGET_WINDOWS_NT && next_active_insn (insn) != 0
3234 && GET_CODE (PATTERN (next_active_insn (insn))) == ADDR_DIFF_VEC
3235 && PREV_INSN (next_active_insn (insn)) == operands[1]"
3237 { rtx best_label = 0;
3238 rtx jump_table_insn = next_active_insn (operands[1]);
3240 if (GET_CODE (jump_table_insn) == JUMP_INSN
3241 && GET_CODE (PATTERN (jump_table_insn)) == ADDR_DIFF_VEC)
3243 rtx jump_table = PATTERN (jump_table_insn);
3244 int n_labels = XVECLEN (jump_table, 1);
3245 int best_count = -1;
3248 for (i = 0; i < n_labels; i++)
3252 for (j = i + 1; j < n_labels; j++)
3253 if (XEXP (XVECEXP (jump_table, 1, i), 0)
3254 == XEXP (XVECEXP (jump_table, 1, j), 0))
3257 if (count > best_count)
3258 best_count = count, best_label = XVECEXP (jump_table, 1, i);
3264 operands[2] = best_label;
3265 return \"jmp $31,(%0),%2\";
3268 return \"jmp $31,(%0),0\";
3270 [(set_attr "type" "ibr")])
3272 ;; Cache flush. Used by INITIALIZE_TRAMPOLINE. 0x86 is PAL_imb, but we don't
3273 ;; want to have to include pal.h in our .s file.
3275 [(unspec_volatile [(const_int 0)] 0)]
3278 [(set_attr "type" "isubr")])
3280 ;; Finally, we have the basic data motion insns. The byte and word insns
3281 ;; are done via define_expand. Start with the floating-point insns, since
3282 ;; they are simpler.
3285 [(set (match_operand:SF 0 "nonimmediate_operand" "=r,r,m,f,f,f,m")
3286 (match_operand:SF 1 "input_operand" "rG,m,rG,f,G,m,fG"))]
3287 "register_operand (operands[0], SFmode)
3288 || reg_or_fp0_operand (operands[1], SFmode)"
3297 [(set_attr "type" "ilog,ld,st,fcpys,fcpys,ld,st")])
3300 [(set (match_operand:DF 0 "nonimmediate_operand" "=r,r,m,f,f,f,m")
3301 (match_operand:DF 1 "input_operand" "rG,m,rG,f,G,m,fG"))]
3302 "register_operand (operands[0], DFmode)
3303 || reg_or_fp0_operand (operands[1], DFmode)"
3312 [(set_attr "type" "ilog,ld,st,fcpys,fcpys,ld,st")])
3314 (define_expand "movsf"
3315 [(set (match_operand:SF 0 "nonimmediate_operand" "")
3316 (match_operand:SF 1 "general_operand" ""))]
3320 if (GET_CODE (operands[0]) == MEM
3321 && ! reg_or_fp0_operand (operands[1], SFmode))
3322 operands[1] = force_reg (SFmode, operands[1]);
3325 (define_expand "movdf"
3326 [(set (match_operand:DF 0 "nonimmediate_operand" "")
3327 (match_operand:DF 1 "general_operand" ""))]
3331 if (GET_CODE (operands[0]) == MEM
3332 && ! reg_or_fp0_operand (operands[1], DFmode))
3333 operands[1] = force_reg (DFmode, operands[1]);
3337 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,r,r,r,r,m,f,f,f,m")
3338 (match_operand:SI 1 "input_operand" "r,J,I,K,L,m,rJ,f,J,m,fG"))]
3339 "! TARGET_WINDOWS_NT && (register_operand (operands[0], SImode)
3340 || reg_or_0_operand (operands[1], SImode))"
3353 [(set_attr "type" "ilog,ilog,ilog,iadd,iadd,ld,st,fcpys,fcpys,ld,st")])
3356 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,r,r,r,r,r,m,f,f,f,m")
3357 (match_operand:SI 1 "input_operand" "r,J,I,K,L,s,m,rJ,f,J,m,fG"))]
3358 "TARGET_WINDOWS_NT && (register_operand (operands[0], SImode)
3359 || reg_or_0_operand (operands[1], SImode))"
3373 [(set_attr "type" "ilog,ilog,ilog,iadd,iadd,ldsym,ld,st,fcpys,fcpys,ld,st")])
3376 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,r,f,f")
3377 (match_operand:HI 1 "input_operand" "r,J,I,n,f,J"))]
3378 "register_operand (operands[0], HImode)
3379 || register_operand (operands[1], HImode)"
3387 [(set_attr "type" "ilog,ilog,ilog,iadd,fcpys,fcpys")])
3390 [(set (match_operand:QI 0 "nonimmediate_operand" "=r,r,r,r,f,f")
3391 (match_operand:QI 1 "input_operand" "r,J,I,n,f,J"))]
3392 "register_operand (operands[0], QImode)
3393 || register_operand (operands[1], QImode)"
3401 [(set_attr "type" "ilog,ilog,ilog,iadd,fcpys,fcpys")])
3403 ;; We do two major things here: handle mem->mem and construct long
3406 (define_expand "movsi"
3407 [(set (match_operand:SI 0 "general_operand" "")
3408 (match_operand:SI 1 "general_operand" ""))]
3412 if (GET_CODE (operands[0]) == MEM
3413 && ! reg_or_0_operand (operands[1], SImode))
3414 operands[1] = force_reg (SImode, operands[1]);
3416 if (! CONSTANT_P (operands[1]) || input_operand (operands[1], SImode))
3418 else if (GET_CODE (operands[1]) == CONST_INT)
3421 = alpha_emit_set_const (operands[0], SImode, INTVAL (operands[1]), 3);
3422 if (rtx_equal_p (operands[0], operands[1]))
3427 ;; Split a load of a large constant into the appropriate two-insn
3431 [(set (match_operand:SI 0 "register_operand" "")
3432 (match_operand:SI 1 "const_int_operand" ""))]
3433 "! add_operand (operands[1], SImode)"
3434 [(set (match_dup 0) (match_dup 2))
3435 (set (match_dup 0) (plus:SI (match_dup 0) (match_dup 3)))]
3438 = alpha_emit_set_const (operands[0], SImode, INTVAL (operands[1]), 2);
3440 if (tem == operands[0])
3447 [(set (match_operand:DI 0 "general_operand" "=r,r,r,r,r,r,r,m,f,f,f,Q")
3448 (match_operand:DI 1 "input_operand" "r,J,I,K,L,s,m,rJ,f,J,Q,fG"))]
3449 "register_operand (operands[0], DImode)
3450 || reg_or_0_operand (operands[1], DImode)"
3464 [(set_attr "type" "ilog,ilog,ilog,iadd,iadd,ldsym,ld,st,fcpys,fcpys,ld,st")])
3466 ;; We do three major things here: handle mem->mem, put 64-bit constants in
3467 ;; memory, and construct long 32-bit constants.
3469 (define_expand "movdi"
3470 [(set (match_operand:DI 0 "general_operand" "")
3471 (match_operand:DI 1 "general_operand" ""))]
3477 if (GET_CODE (operands[0]) == MEM
3478 && ! reg_or_0_operand (operands[1], DImode))
3479 operands[1] = force_reg (DImode, operands[1]);
3481 if (! CONSTANT_P (operands[1]) || input_operand (operands[1], DImode))
3483 else if (GET_CODE (operands[1]) == CONST_INT
3484 && (tem = alpha_emit_set_const (operands[0], DImode,
3485 INTVAL (operands[1]), 3)) != 0)
3487 if (rtx_equal_p (tem, operands[0]))
3492 else if (TARGET_BUILD_CONSTANTS
3493 && GET_CODE (operands[1]) == CONST_INT)
3495 #if HOST_BITS_PER_WIDE_INT == 64
3496 tem = alpha_emit_set_long_const (operands[0], INTVAL (operands[1]));
3497 if (rtx_equal_p (tem, operands[0]))
3505 else if (CONSTANT_P (operands[1]))
3507 operands[1] = force_const_mem (DImode, operands[1]);
3508 if (reload_in_progress)
3510 emit_move_insn (operands[0], XEXP (operands[1], 0));
3511 operands[1] = copy_rtx (operands[1]);
3512 XEXP (operands[1], 0) = operands[0];
3515 operands[1] = validize_mem (operands[1]);
3521 ;; Split a load of a large constant into the appropriate two-insn
3525 [(set (match_operand:DI 0 "register_operand" "")
3526 (match_operand:DI 1 "const_int_operand" ""))]
3527 "! add_operand (operands[1], DImode)"
3528 [(set (match_dup 0) (match_dup 2))
3529 (set (match_dup 0) (plus:DI (match_dup 0) (match_dup 3)))]
3532 = alpha_emit_set_const (operands[0], DImode, INTVAL (operands[1]), 2);
3534 if (tem == operands[0])
3540 ;; These are the partial-word cases.
3542 ;; First we have the code to load an aligned word. Operand 0 is the register
3543 ;; in which to place the result. It's mode is QImode or HImode. Operand 1
3544 ;; is an SImode MEM at the low-order byte of the proper word. Operand 2 is the
3545 ;; number of bits within the word that the value is. Operand 3 is an SImode
3546 ;; scratch register. If operand 0 is a hard register, operand 3 may be the
3547 ;; same register. It is allowed to conflict with operand 1 as well.
3549 (define_expand "aligned_loadqi"
3550 [(set (match_operand:SI 3 "register_operand" "")
3551 (match_operand:SI 1 "memory_operand" ""))
3552 (set (subreg:DI (match_operand:QI 0 "register_operand" "") 0)
3553 (zero_extract:DI (subreg:DI (match_dup 3) 0)
3555 (match_operand:DI 2 "const_int_operand" "")))]
3560 (define_expand "aligned_loadhi"
3561 [(set (match_operand:SI 3 "register_operand" "")
3562 (match_operand:SI 1 "memory_operand" ""))
3563 (set (subreg:DI (match_operand:HI 0 "register_operand" "") 0)
3564 (zero_extract:DI (subreg:DI (match_dup 3) 0)
3566 (match_operand:DI 2 "const_int_operand" "")))]
3571 ;; Similar for unaligned loads, where we use the sequence from the
3572 ;; Alpha Architecture manual.
3574 ;; Operand 1 is the address. Operands 2 and 3 are temporaries, where
3575 ;; operand 3 can overlap the input and output registers.
3577 (define_expand "unaligned_loadqi"
3578 [(set (match_operand:DI 2 "register_operand" "")
3579 (mem:DI (and:DI (match_operand:DI 1 "address_operand" "")
3581 (set (match_operand:DI 3 "register_operand" "")
3583 (set (subreg:DI (match_operand:QI 0 "register_operand" "") 0)
3584 (zero_extract:DI (match_dup 2)
3586 (ashift:DI (match_dup 3) (const_int 3))))]
3590 (define_expand "unaligned_loadhi"
3591 [(set (match_operand:DI 2 "register_operand" "")
3592 (mem:DI (and:DI (match_operand:DI 1 "address_operand" "")
3594 (set (match_operand:DI 3 "register_operand" "")
3596 (set (subreg:DI (match_operand:QI 0 "register_operand" "") 0)
3597 (zero_extract:DI (match_dup 2)
3599 (ashift:DI (match_dup 3) (const_int 3))))]
3603 ;; Storing an aligned byte or word requires two temporaries. Operand 0 is the
3604 ;; aligned SImode MEM. Operand 1 is the register containing the
3605 ;; byte or word to store. Operand 2 is the number of bits within the word that
3606 ;; the value should be placed. Operands 3 and 4 are SImode temporaries.
3608 (define_expand "aligned_store"
3609 [(set (match_operand:SI 3 "register_operand" "")
3610 (match_operand:SI 0 "memory_operand" ""))
3611 (set (subreg:DI (match_dup 3) 0)
3612 (and:DI (subreg:DI (match_dup 3) 0) (match_dup 5)))
3613 (set (subreg:DI (match_operand:SI 4 "register_operand" "") 0)
3614 (ashift:DI (zero_extend:DI (match_operand 1 "register_operand" ""))
3615 (match_operand:DI 2 "const_int_operand" "")))
3616 (set (subreg:DI (match_dup 4) 0)
3617 (ior:DI (subreg:DI (match_dup 4) 0) (subreg:DI (match_dup 3) 0)))
3618 (set (match_dup 0) (match_dup 4))]
3621 { operands[5] = GEN_INT (~ (GET_MODE_MASK (GET_MODE (operands[1]))
3622 << INTVAL (operands[2])));
3625 ;; For the unaligned byte and halfword cases, we use code similar to that
3626 ;; in the ;; Architecture book, but reordered to lower the number of registers
3627 ;; required. Operand 0 is the address. Operand 1 is the data to store.
3628 ;; Operands 2, 3, and 4 are DImode temporaries, where operands 2 and 4 may
3629 ;; be the same temporary, if desired. If the address is in a register,
3630 ;; operand 2 can be that register.
3632 (define_expand "unaligned_storeqi"
3633 [(set (match_operand:DI 3 "register_operand" "")
3634 (mem:DI (and:DI (match_operand:DI 0 "address_operand" "")
3636 (set (match_operand:DI 2 "register_operand" "")
3639 (and:DI (not:DI (ashift:DI (const_int 255)
3640 (ashift:DI (match_dup 2) (const_int 3))))
3642 (set (match_operand:DI 4 "register_operand" "")
3643 (ashift:DI (zero_extend:DI (match_operand:QI 1 "register_operand" ""))
3644 (ashift:DI (match_dup 2) (const_int 3))))
3645 (set (match_dup 4) (ior:DI (match_dup 4) (match_dup 3)))
3646 (set (mem:DI (and:DI (match_dup 0) (const_int -8)))
3651 (define_expand "unaligned_storehi"
3652 [(set (match_operand:DI 3 "register_operand" "")
3653 (mem:DI (and:DI (match_operand:DI 0 "address_operand" "")
3655 (set (match_operand:DI 2 "register_operand" "")
3658 (and:DI (not:DI (ashift:DI (const_int 65535)
3659 (ashift:DI (match_dup 2) (const_int 3))))
3661 (set (match_operand:DI 4 "register_operand" "")
3662 (ashift:DI (zero_extend:DI (match_operand:HI 1 "register_operand" ""))
3663 (ashift:DI (match_dup 2) (const_int 3))))
3664 (set (match_dup 4) (ior:DI (match_dup 4) (match_dup 3)))
3665 (set (mem:DI (and:DI (match_dup 0) (const_int -8)))
3670 ;; Here are the define_expand's for QI and HI moves that use the above
3671 ;; patterns. We have the normal sets, plus the ones that need scratch
3672 ;; registers for reload.
3674 (define_expand "movqi"
3675 [(set (match_operand:QI 0 "general_operand" "")
3676 (match_operand:QI 1 "general_operand" ""))]
3679 { extern rtx get_unaligned_address ();
3681 /* If the output is not a register, the input must be. */
3682 if (GET_CODE (operands[0]) == MEM)
3683 operands[1] = force_reg (QImode, operands[1]);
3685 /* Handle four memory cases, unaligned and aligned for either the input
3686 or the output. The only case where we can be called during reload is
3687 for aligned loads; all other cases require temporaries. */
3689 if (GET_CODE (operands[1]) == MEM
3690 || (GET_CODE (operands[1]) == SUBREG
3691 && GET_CODE (SUBREG_REG (operands[1])) == MEM)
3692 || (reload_in_progress && GET_CODE (operands[1]) == REG
3693 && REGNO (operands[1]) >= FIRST_PSEUDO_REGISTER)
3694 || (reload_in_progress && GET_CODE (operands[1]) == SUBREG
3695 && GET_CODE (SUBREG_REG (operands[1])) == REG
3696 && REGNO (SUBREG_REG (operands[1])) >= FIRST_PSEUDO_REGISTER))
3698 if (aligned_memory_operand (operands[1], QImode))
3700 rtx aligned_mem, bitnum;
3701 rtx scratch = (reload_in_progress
3702 ? gen_rtx (REG, SImode, REGNO (operands[0]))
3703 : gen_reg_rtx (SImode));
3705 get_aligned_mem (operands[1], &aligned_mem, &bitnum);
3707 emit_insn (gen_aligned_loadqi (operands[0], aligned_mem, bitnum,
3712 /* Don't pass these as parameters since that makes the generated
3713 code depend on parameter evaluation order which will cause
3714 bootstrap failures. */
3716 rtx temp1 = gen_reg_rtx (DImode);
3717 rtx temp2 = gen_reg_rtx (DImode);
3719 = gen_unaligned_loadqi (operands[0],
3720 get_unaligned_address (operands[1], 0),
3723 alpha_set_memflags (seq, operands[1]);
3730 else if (GET_CODE (operands[0]) == MEM
3731 || (GET_CODE (operands[0]) == SUBREG
3732 && GET_CODE (SUBREG_REG (operands[0])) == MEM)
3733 || (reload_in_progress && GET_CODE (operands[0]) == REG
3734 && REGNO (operands[0]) >= FIRST_PSEUDO_REGISTER)
3735 || (reload_in_progress && GET_CODE (operands[0]) == SUBREG
3736 && GET_CODE (SUBREG_REG (operands[0])) == REG
3737 && REGNO (operands[0]) >= FIRST_PSEUDO_REGISTER))
3739 if (aligned_memory_operand (operands[0], QImode))
3741 rtx aligned_mem, bitnum;
3742 rtx temp1 = gen_reg_rtx (SImode);
3743 rtx temp2 = gen_reg_rtx (SImode);
3745 get_aligned_mem (operands[0], &aligned_mem, &bitnum);
3747 emit_insn (gen_aligned_store (aligned_mem, operands[1], bitnum,
3752 rtx temp1 = gen_reg_rtx (DImode);
3753 rtx temp2 = gen_reg_rtx (DImode);
3754 rtx temp3 = gen_reg_rtx (DImode);
3756 = gen_unaligned_storeqi (get_unaligned_address (operands[0], 0),
3757 operands[1], temp1, temp2, temp3);
3759 alpha_set_memflags (seq, operands[0]);
3766 (define_expand "movhi"
3767 [(set (match_operand:HI 0 "general_operand" "")
3768 (match_operand:HI 1 "general_operand" ""))]
3771 { extern rtx get_unaligned_address ();
3773 /* If the output is not a register, the input must be. */
3774 if (GET_CODE (operands[0]) == MEM)
3775 operands[1] = force_reg (HImode, operands[1]);
3777 /* Handle four memory cases, unaligned and aligned for either the input
3778 or the output. The only case where we can be called during reload is
3779 for aligned loads; all other cases require temporaries. */
3781 if (GET_CODE (operands[1]) == MEM
3782 || (GET_CODE (operands[1]) == SUBREG
3783 && GET_CODE (SUBREG_REG (operands[1])) == MEM)
3784 || (reload_in_progress && GET_CODE (operands[1]) == REG
3785 && REGNO (operands[1]) >= FIRST_PSEUDO_REGISTER)
3786 || (reload_in_progress && GET_CODE (operands[1]) == SUBREG
3787 && GET_CODE (SUBREG_REG (operands[1])) == REG
3788 && REGNO (SUBREG_REG (operands[1])) >= FIRST_PSEUDO_REGISTER))
3790 if (aligned_memory_operand (operands[1], HImode))
3792 rtx aligned_mem, bitnum;
3793 rtx scratch = (reload_in_progress
3794 ? gen_rtx (REG, SImode, REGNO (operands[0]))
3795 : gen_reg_rtx (SImode));
3797 get_aligned_mem (operands[1], &aligned_mem, &bitnum);
3799 emit_insn (gen_aligned_loadhi (operands[0], aligned_mem, bitnum,
3804 /* Don't pass these as parameters since that makes the generated
3805 code depend on parameter evaluation order which will cause
3806 bootstrap failures. */
3808 rtx temp1 = gen_reg_rtx (DImode);
3809 rtx temp2 = gen_reg_rtx (DImode);
3811 = gen_unaligned_loadhi (operands[0],
3812 get_unaligned_address (operands[1], 0),
3815 alpha_set_memflags (seq, operands[1]);
3822 else if (GET_CODE (operands[0]) == MEM
3823 || (GET_CODE (operands[0]) == SUBREG
3824 && GET_CODE (SUBREG_REG (operands[0])) == MEM)
3825 || (reload_in_progress && GET_CODE (operands[0]) == REG
3826 && REGNO (operands[0]) >= FIRST_PSEUDO_REGISTER)
3827 || (reload_in_progress && GET_CODE (operands[0]) == SUBREG
3828 && GET_CODE (SUBREG_REG (operands[0])) == REG
3829 && REGNO (operands[0]) >= FIRST_PSEUDO_REGISTER))
3831 if (aligned_memory_operand (operands[0], HImode))
3833 rtx aligned_mem, bitnum;
3834 rtx temp1 = gen_reg_rtx (SImode);
3835 rtx temp2 = gen_reg_rtx (SImode);
3837 get_aligned_mem (operands[0], &aligned_mem, &bitnum);
3839 emit_insn (gen_aligned_store (aligned_mem, operands[1], bitnum,
3844 rtx temp1 = gen_reg_rtx (DImode);
3845 rtx temp2 = gen_reg_rtx (DImode);
3846 rtx temp3 = gen_reg_rtx (DImode);
3848 = gen_unaligned_storehi (get_unaligned_address (operands[0], 0),
3849 operands[1], temp1, temp2, temp3);
3851 alpha_set_memflags (seq, operands[0]);
3859 ;; Here are the versions for reload. Note that in the unaligned cases
3860 ;; we know that the operand must not be a pseudo-register because stack
3861 ;; slots are always aligned references.
3863 (define_expand "reload_inqi"
3864 [(parallel [(match_operand:QI 0 "register_operand" "=r")
3865 (match_operand:QI 1 "unaligned_memory_operand" "m")
3866 (match_operand:TI 2 "register_operand" "=&r")])]
3869 { extern rtx get_unaligned_address ();
3870 rtx addr = get_unaligned_address (operands[1], 0);
3871 /* It is possible that one of the registers we got for operands[2]
3872 might coincide with that of operands[0] (which is why we made
3873 it TImode). Pick the other one to use as our scratch. */
3874 rtx scratch = gen_rtx (REG, DImode,
3875 REGNO (operands[0]) == REGNO (operands[2])
3876 ? REGNO (operands[2]) + 1 : REGNO (operands[2]));
3877 rtx seq = gen_unaligned_loadqi (operands[0], addr, scratch,
3878 gen_rtx (REG, DImode, REGNO (operands[0])));
3880 alpha_set_memflags (seq, operands[1]);
3885 (define_expand "reload_inhi"
3886 [(parallel [(match_operand:HI 0 "register_operand" "=r")
3887 (match_operand:HI 1 "unaligned_memory_operand" "m")
3888 (match_operand:TI 2 "register_operand" "=&r")])]
3891 { extern rtx get_unaligned_address ();
3892 rtx addr = get_unaligned_address (operands[1], 0);
3893 /* It is possible that one of the registers we got for operands[2]
3894 might coincide with that of operands[0] (which is why we made
3895 it TImode). Pick the other one to use as our scratch. */
3896 rtx scratch = gen_rtx (REG, DImode,
3897 REGNO (operands[0]) == REGNO (operands[2])
3898 ? REGNO (operands[2]) + 1 : REGNO (operands[2]));
3899 rtx seq = gen_unaligned_loadhi (operands[0], addr, scratch,
3900 gen_rtx (REG, DImode, REGNO (operands[0])));
3902 alpha_set_memflags (seq, operands[1]);
3907 (define_expand "reload_outqi"
3908 [(parallel [(match_operand:QI 0 "any_memory_operand" "=m")
3909 (match_operand:QI 1 "register_operand" "r")
3910 (match_operand:TI 2 "register_operand" "=&r")])]
3913 { extern rtx get_unaligned_address ();
3915 if (aligned_memory_operand (operands[0], QImode))
3917 rtx aligned_mem, bitnum;
3919 get_aligned_mem (operands[0], &aligned_mem, &bitnum);
3921 emit_insn (gen_aligned_store (aligned_mem, operands[1], bitnum,
3922 gen_rtx (REG, SImode, REGNO (operands[2])),
3923 gen_rtx (REG, SImode,
3924 REGNO (operands[2]) + 1)));
3928 rtx addr = get_unaligned_address (operands[0], 0);
3929 rtx scratch1 = gen_rtx (REG, DImode, REGNO (operands[2]));
3930 rtx scratch2 = gen_rtx (REG, DImode, REGNO (operands[2]) + 1);
3931 rtx scratch3 = scratch1;
3934 if (GET_CODE (addr) == REG)
3937 seq = gen_unaligned_storeqi (addr, operands[1], scratch1,
3938 scratch2, scratch3);
3939 alpha_set_memflags (seq, operands[0]);
3946 (define_expand "reload_outhi"
3947 [(parallel [(match_operand:HI 0 "any_memory_operand" "=m")
3948 (match_operand:HI 1 "register_operand" "r")
3949 (match_operand:TI 2 "register_operand" "=&r")])]
3952 { extern rtx get_unaligned_address ();
3954 if (aligned_memory_operand (operands[0], HImode))
3956 rtx aligned_mem, bitnum;
3958 get_aligned_mem (operands[0], &aligned_mem, &bitnum);
3960 emit_insn (gen_aligned_store (aligned_mem, operands[1], bitnum,
3961 gen_rtx (REG, SImode, REGNO (operands[2])),
3962 gen_rtx (REG, SImode,
3963 REGNO (operands[2]) + 1)));
3967 rtx addr = get_unaligned_address (operands[0], 0);
3968 rtx scratch1 = gen_rtx (REG, DImode, REGNO (operands[2]));
3969 rtx scratch2 = gen_rtx (REG, DImode, REGNO (operands[2]) + 1);
3970 rtx scratch3 = scratch1;
3973 if (GET_CODE (addr) == REG)
3976 seq = gen_unaligned_storehi (addr, operands[1], scratch1,
3977 scratch2, scratch3);
3978 alpha_set_memflags (seq, operands[0]);
3985 ;; Subroutine of stack space allocation. Perform a stack probe.
3986 (define_expand "probe_stack"
3987 [(set (match_dup 1) (match_operand:DI 0 "const_int_operand" ""))]
3991 operands[1] = gen_rtx (MEM, DImode, plus_constant (stack_pointer_rtx,
3992 INTVAL (operands[0])));
3993 MEM_VOLATILE_P (operands[1]) = 1;
3995 operands[0] = const0_rtx;
3998 ;; This is how we allocate stack space. If we are allocating a
3999 ;; constant amount of space and we know it is less than 4096
4000 ;; bytes, we need do nothing.
4002 ;; If it is more than 4096 bytes, we need to probe the stack
4004 (define_expand "allocate_stack"
4006 (plus:DI (reg:DI 30)
4007 (match_operand:DI 0 "reg_or_cint_operand" "")))]
4011 if (GET_CODE (operands[0]) == CONST_INT
4012 && INTVAL (operands[0]) < 32768)
4014 if (INTVAL (operands[0]) >= 4096)
4016 /* We do this the same way as in the prologue and generate explicit
4017 probes. Then we update the stack by the constant. */
4021 emit_insn (gen_probe_stack (GEN_INT (- probed)));
4022 while (probed + 8192 < INTVAL (operands[0]))
4023 emit_insn (gen_probe_stack (GEN_INT (- (probed += 8192))));
4025 if (probed + 4096 < INTVAL (operands[0]))
4026 emit_insn (gen_probe_stack (GEN_INT (- INTVAL(operands[0]))));
4029 operands[0] = GEN_INT (- INTVAL (operands[0]));
4034 rtx loop_label = gen_label_rtx ();
4035 rtx want = gen_reg_rtx (Pmode);
4036 rtx tmp = gen_reg_rtx (Pmode);
4039 emit_insn (gen_subdi3 (want, stack_pointer_rtx,
4040 force_reg (Pmode, operands[0])));
4041 emit_insn (gen_adddi3 (tmp, stack_pointer_rtx, GEN_INT (-4096)));
4043 if (GET_CODE (operands[0]) != CONST_INT)
4045 out_label = gen_label_rtx ();
4046 emit_insn (gen_cmpdi (want, tmp));
4047 emit_jump_insn (gen_bgeu (out_label));
4050 emit_label (loop_label);
4051 memref = gen_rtx (MEM, DImode, tmp);
4052 MEM_VOLATILE_P (memref) = 1;
4053 emit_move_insn (memref, const0_rtx);
4054 emit_insn (gen_adddi3 (tmp, tmp, GEN_INT(-8192)));
4055 emit_insn (gen_cmpdi (tmp, want));
4056 emit_jump_insn (gen_bgtu (loop_label));
4057 memref = gen_rtx (MEM, DImode, want);
4058 MEM_VOLATILE_P (memref) = 1;
4059 emit_move_insn (memref, const0_rtx);
4062 emit_label (out_label);
4064 emit_move_insn (stack_pointer_rtx, want);