1 ;; Machine description for DEC Alpha for GNU C compiler
2 ;; Copyright (C) 1992, 93, 94, 95, 96, 97, 1998 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 ;; Uses of UNSPEC in this file:
37 ;; 2 builtin_setjmp_receiver
40 ;; 5 prologue_stack_probe_loop
42 ;; 7 exception_receiver
44 ;; Processor type -- this attribute must exactly match the processor_type
45 ;; enumeration in alpha.h.
47 (define_attr "cpu" "ev4,ev5,ev6"
48 (const (symbol_ref "alpha_cpu")))
50 ;; Define an insn type attribute. This is used in function unit delay
51 ;; computations, among other purposes. For the most part, we use the names
52 ;; defined in the EV4 documentation, but add a few that we have to know about
56 "ild,fld,ldsym,ist,fst,ibr,fbr,jsr,iadd,ilog,shift,icmov,fcmov,icmp,imul,fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi"
57 (const_string "iadd"))
59 ;; Describe a user's asm statement.
60 (define_asm_attributes
61 [(set_attr "type" "multi")])
63 ;; Define the operand size an insn operates on. Used primarily by mul
64 ;; and div operations that have size dependant timings.
66 (define_attr "opsize" "si,di,udi" (const_string "di"))
68 ;; The TRAP_TYPE attribute marks instructions that may generate traps
69 ;; (which are imprecise and may need a trapb if software completion
72 (define_attr "trap" "no,yes" (const_string "no"))
74 ;; The length of an instruction sequence in bytes.
76 (define_attr "length" "" (const_int 4))
78 ;; On EV4 there are two classes of resources to consider: resources needed
79 ;; to issue, and resources needed to execute. IBUS[01] are in the first
80 ;; category. ABOX, BBOX, EBOX, FBOX, IMUL & FDIV make up the second.
81 ;; (There are a few other register-like resources, but ...)
83 ; First, describe all of the issue constraints with single cycle delays.
84 ; All insns need a bus, but all except loads require one or the other.
85 (define_function_unit "ev4_ibus0" 1 0
86 (and (eq_attr "cpu" "ev4")
87 (eq_attr "type" "fst,fbr,iadd,imul,ilog,shift,icmov,icmp"))
90 (define_function_unit "ev4_ibus1" 1 0
91 (and (eq_attr "cpu" "ev4")
92 (eq_attr "type" "ist,ibr,jsr,fadd,fcmov,fcpys,fmul,fdiv,misc"))
95 ; Memory delivers its result in three cycles. Actually return one and
96 ; take care of this in adjust_cost, since we want to handle user-defined
98 (define_function_unit "ev4_abox" 1 0
99 (and (eq_attr "cpu" "ev4")
100 (eq_attr "type" "ild,fld,ldsym,ist,fst"))
103 ; Branches have no delay cost, but do tie up the unit for two cycles.
104 (define_function_unit "ev4_bbox" 1 1
105 (and (eq_attr "cpu" "ev4")
106 (eq_attr "type" "ibr,fbr,jsr"))
109 ; Arithmetic insns are normally have their results available after
110 ; two cycles. There are a number of exceptions. They are encoded in
111 ; ADJUST_COST. Some of the other insns have similar exceptions.
112 (define_function_unit "ev4_ebox" 1 0
113 (and (eq_attr "cpu" "ev4")
114 (eq_attr "type" "iadd,ilog,shift,icmov,icmp,misc"))
117 (define_function_unit "imul" 1 0
118 (and (eq_attr "cpu" "ev4")
119 (and (eq_attr "type" "imul")
120 (eq_attr "opsize" "si")))
123 (define_function_unit "imul" 1 0
124 (and (eq_attr "cpu" "ev4")
125 (and (eq_attr "type" "imul")
126 (eq_attr "opsize" "!si")))
129 (define_function_unit "ev4_fbox" 1 0
130 (and (eq_attr "cpu" "ev4")
131 (eq_attr "type" "fadd,fmul,fcpys,fcmov"))
134 (define_function_unit "fdiv" 1 0
135 (and (eq_attr "cpu" "ev4")
136 (and (eq_attr "type" "fdiv")
137 (eq_attr "opsize" "si")))
140 (define_function_unit "fdiv" 1 0
141 (and (eq_attr "cpu" "ev4")
142 (and (eq_attr "type" "fdiv")
143 (eq_attr "opsize" "di")))
146 ;; EV5 scheduling. EV5 can issue 4 insns per clock.
148 ;; EV5 has two asymetric integer units. Model this with E0 & E1 along
149 ;; with the combined resource EBOX.
151 (define_function_unit "ev5_ebox" 2 0
152 (and (eq_attr "cpu" "ev5")
153 (eq_attr "type" "!fbr,fcmov,fadd,fmul,fcpys,fdiv"))
156 ; Memory takes at least 2 clocks. Return one from here and fix up with
157 ; user-defined latencies in adjust_cost.
158 ; ??? How to: "An instruction of class LD cannot be issued in the _second_
159 ; cycle after an instruction of class ST is issued."
160 (define_function_unit "ev5_ebox" 2 0
161 (and (eq_attr "cpu" "ev5")
162 (eq_attr "type" "ild,fld,ldsym"))
165 ; Stores, shifts, multiplies can only issue to E0
166 (define_function_unit "ev5_e0" 1 0
167 (and (eq_attr "cpu" "ev5")
168 (eq_attr "type" "ist,fst,shift,imul"))
171 ; Motion video insns also issue only to E0, and take two ticks.
172 (define_function_unit "ev5_e0" 1 0
173 (and (eq_attr "cpu" "ev5")
174 (eq_attr "type" "mvi"))
177 ; Conditional moves always take 2 ticks.
178 (define_function_unit "ev5_ebox" 2 0
179 (and (eq_attr "cpu" "ev5")
180 (eq_attr "type" "icmov"))
183 ; Branches can only issue to E1
184 (define_function_unit "ev5_e1" 1 0
185 (and (eq_attr "cpu" "ev5")
186 (eq_attr "type" "ibr,jsr"))
189 ; Multiplies also use the integer multiplier.
190 ; ??? How to: "No instruction can be issued to pipe E0 exactly two
191 ; cycles before an integer multiplication completes."
192 (define_function_unit "imul" 1 0
193 (and (eq_attr "cpu" "ev5")
194 (and (eq_attr "type" "imul")
195 (eq_attr "opsize" "si")))
198 (define_function_unit "imul" 1 0
199 (and (eq_attr "cpu" "ev5")
200 (and (eq_attr "type" "imul")
201 (eq_attr "opsize" "di")))
204 (define_function_unit "imul" 1 0
205 (and (eq_attr "cpu" "ev5")
206 (and (eq_attr "type" "imul")
207 (eq_attr "opsize" "udi")))
210 ;; Similarly for the FPU we have two asymetric units. But fcpys can issue
211 ;; on either so we have to play the game again.
213 (define_function_unit "ev5_fbox" 2 0
214 (and (eq_attr "cpu" "ev5")
215 (eq_attr "type" "fadd,fcmov,fmul,fcpys,fbr,fdiv"))
218 (define_function_unit "ev5_fm" 1 0
219 (and (eq_attr "cpu" "ev5")
220 (eq_attr "type" "fmul"))
223 ; Add and cmov as you would expect; fbr never produces a result;
224 ; fdiv issues through fa to the divider,
225 (define_function_unit "ev5_fa" 1 0
226 (and (eq_attr "cpu" "ev5")
227 (eq_attr "type" "fadd,fcmov,fbr,fdiv"))
230 ; ??? How to: "No instruction can be issued to pipe FA exactly five
231 ; cycles before a floating point divide completes."
232 (define_function_unit "fdiv" 1 0
233 (and (eq_attr "cpu" "ev5")
234 (and (eq_attr "type" "fdiv")
235 (eq_attr "opsize" "si")))
236 15 15) ; 15 to 31 data dependant
238 (define_function_unit "fdiv" 1 0
239 (and (eq_attr "cpu" "ev5")
240 (and (eq_attr "type" "fdiv")
241 (eq_attr "opsize" "di")))
242 22 22) ; 22 to 60 data dependant
244 ;; EV6 scheduling. EV6 can issue 4 insns per clock.
246 ;; EV6 has two symmetric pairs ("clusters") of two asymetric integer units
247 ;; ("upper" and "lower"), yielding pipe names U0, U1, L0, L1.
249 ;; Conditional moves decompose into two independant primitives, each
250 ;; taking one cycle. Since ev6 is out-of-order, we can't see anything
252 (define_function_unit "ev6_ebox" 4 0
253 (and (eq_attr "cpu" "ev6")
254 (eq_attr "type" "icmov"))
257 (define_function_unit "ev6_ebox" 4 0
258 (and (eq_attr "cpu" "ev6")
259 (eq_attr "type" "!fbr,fcmov,fadd,fmul,fcpys,fdiv,fsqrt"))
262 ;; Integer loads take at least 3 clocks, and only issue to lower units.
263 ;; Return one from here and fix up with user-defined latencies in adjust_cost.
264 (define_function_unit "ev6_l" 2 0
265 (and (eq_attr "cpu" "ev6")
266 (eq_attr "type" "ild,ldsym,ist,fst"))
269 ;; FP loads take at least 4 clocks. Return two from here...
270 (define_function_unit "ev6_l" 2 0
271 (and (eq_attr "cpu" "ev6")
272 (eq_attr "type" "fld"))
275 ;; Motion video insns also issue only to U0, and take three ticks.
276 (define_function_unit "ev6_u0" 1 0
277 (and (eq_attr "cpu" "ev6")
278 (eq_attr "type" "mvi"))
281 (define_function_unit "ev6_u" 2 0
282 (and (eq_attr "cpu" "ev6")
283 (eq_attr "type" "mvi"))
286 ;; Shifts issue to either upper pipe.
287 (define_function_unit "ev6_u" 2 0
288 (and (eq_attr "cpu" "ev6")
289 (eq_attr "type" "shift"))
292 ;; Multiplies issue only to U1, and all take 7 ticks.
293 ;; Rather than create a new function unit just for U1, reuse IMUL
294 (define_function_unit "imul" 1 0
295 (and (eq_attr "cpu" "ev6")
296 (eq_attr "type" "imul"))
299 (define_function_unit "ev6_u" 2 0
300 (and (eq_attr "cpu" "ev6")
301 (eq_attr "type" "imul"))
304 ;; Branches issue to either upper pipe
305 (define_function_unit "ev6_u" 2 0
306 (and (eq_attr "cpu" "ev6")
307 (eq_attr "type" "ibr"))
310 ;; Calls only issue to L0.
311 (define_function_unit "ev6_l0" 1 0
312 (and (eq_attr "cpu" "ev6")
313 (eq_attr "type" "jsr"))
316 (define_function_unit "ev6_l" 2 0
317 (and (eq_attr "cpu" "ev6")
318 (eq_attr "type" "jsr"))
321 ;; Ftoi/itof only issue to lower pipes
322 (define_function_unit "ev6_l" 2 0
323 (and (eq_attr "cpu" "ev6")
324 (eq_attr "type" "ftoi"))
327 (define_function_unit "ev6_l" 2 0
328 (and (eq_attr "cpu" "ev6")
329 (eq_attr "type" "itof"))
332 ;; For the FPU we are very similar to EV5, except there's no insn that
333 ;; can issue to fm & fa, so we get to leave that out.
335 (define_function_unit "ev6_fm" 1 0
336 (and (eq_attr "cpu" "ev6")
337 (eq_attr "type" "fmul"))
340 (define_function_unit "ev6_fa" 1 0
341 (and (eq_attr "cpu" "ev6")
342 (eq_attr "type" "fadd,fcpys,fbr,fdiv,fsqrt"))
345 (define_function_unit "ev6_fa" 1 0
346 (and (eq_attr "cpu" "ev6")
347 (eq_attr "type" "fcmov"))
350 (define_function_unit "fdiv" 1 0
351 (and (eq_attr "cpu" "ev6")
352 (and (eq_attr "type" "fdiv")
353 (eq_attr "opsize" "si")))
356 (define_function_unit "fdiv" 1 0
357 (and (eq_attr "cpu" "ev6")
358 (and (eq_attr "type" "fdiv")
359 (eq_attr "opsize" "di")))
362 (define_function_unit "fsqrt" 1 0
363 (and (eq_attr "cpu" "ev6")
364 (and (eq_attr "type" "fsqrt")
365 (eq_attr "opsize" "si")))
368 (define_function_unit "fsqrt" 1 0
369 (and (eq_attr "cpu" "ev6")
370 (and (eq_attr "type" "fsqrt")
371 (eq_attr "opsize" "di")))
374 ; ??? The FPU communicates with memory and the integer register file
375 ; via two fp store units. We need a slot in the fst immediately, and
376 ; a slot in LOW after the operand data is ready. At which point the
377 ; data may be moved either to the store queue or the integer register
378 ; file and the insn retired.
381 ;; First define the arithmetic insns. Note that the 32-bit forms also
384 ;; Handle 32-64 bit extension from memory to a floating point register
385 ;; specially, since this ocurrs frequently in int->double conversions.
386 ;; This is done with a define_split after reload converting the plain
387 ;; sign-extension into a load+unspec, which of course results in lds+cvtlq.
389 ;; Note that while we must retain the =f case in the insn for reload's
390 ;; benefit, it should be eliminated after reload, so we should never emit
391 ;; code for that case. But we don't reject the possibility.
393 (define_insn "extendsidi2"
394 [(set (match_operand:DI 0 "register_operand" "=r,r,?f")
395 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "r,m,m")))]
400 lds %0,%1\;cvtlq %0,%0"
401 [(set_attr "type" "iadd,ild,fld")
402 (set_attr "length" "*,*,8")])
404 ;; Due to issues with CLASS_CANNOT_CHANGE_SIZE, we cannot use a subreg here.
406 [(set (match_operand:DI 0 "hard_fp_register_operand" "")
407 (sign_extend:DI (match_operand:SI 1 "memory_operand" "")))]
409 [(set (match_dup 2) (match_dup 1))
410 (set (match_dup 0) (unspec:DI [(match_dup 2)] 4))]
411 "operands[2] = gen_rtx_REG (SImode, REGNO (operands[0]));")
414 [(set (match_operand:DI 0 "register_operand" "=f")
415 (unspec:DI [(match_operand:SI 1 "register_operand" "f")] 4))]
418 [(set_attr "type" "fadd")])
420 ;; Do addsi3 the way expand_binop would do if we didn't have one. This
421 ;; generates better code. We have the anonymous addsi3 pattern below in
422 ;; case combine wants to make it.
423 (define_expand "addsi3"
424 [(set (match_operand:SI 0 "register_operand" "")
425 (plus:SI (match_operand:SI 1 "reg_or_0_operand" "")
426 (match_operand:SI 2 "add_operand" "")))]
430 rtx op1 = gen_lowpart (DImode, operands[1]);
431 rtx op2 = gen_lowpart (DImode, operands[2]);
433 if (! cse_not_expected)
435 rtx tmp = gen_reg_rtx (DImode);
436 emit_insn (gen_adddi3 (tmp, op1, op2));
437 emit_move_insn (operands[0], gen_lowpart (SImode, tmp));
440 emit_insn (gen_adddi3 (gen_lowpart (DImode, operands[0]), op1, op2));
445 [(set (match_operand:SI 0 "register_operand" "=r,r,r,r")
446 (plus:SI (match_operand:SI 1 "reg_or_0_operand" "%rJ,rJ,rJ,rJ")
447 (match_operand:SI 2 "add_operand" "rI,O,K,L")))]
456 [(set (match_operand:SI 0 "register_operand" "")
457 (plus:SI (match_operand:SI 1 "register_operand" "")
458 (match_operand:SI 2 "const_int_operand" "")))]
459 "! add_operand (operands[2], SImode)"
460 [(set (match_dup 0) (plus:SI (match_dup 1) (match_dup 3)))
461 (set (match_dup 0) (plus:SI (match_dup 0) (match_dup 4)))]
464 HOST_WIDE_INT val = INTVAL (operands[2]);
465 HOST_WIDE_INT low = (val & 0xffff) - 2 * (val & 0x8000);
466 HOST_WIDE_INT rest = val - low;
468 operands[3] = GEN_INT (rest);
469 operands[4] = GEN_INT (low);
473 [(set (match_operand:DI 0 "register_operand" "=r,r")
475 (plus:SI (match_operand:SI 1 "reg_or_0_operand" "%rJ,rJ")
476 (match_operand:SI 2 "sext_add_operand" "rI,O"))))]
483 [(set (match_operand:DI 0 "register_operand" "")
485 (plus:SI (match_operand:SI 1 "register_operand" "")
486 (match_operand:SI 2 "const_int_operand" ""))))
487 (clobber (match_operand:SI 3 "reg_not_elim_operand" ""))]
488 "! sext_add_operand (operands[2], SImode) && INTVAL (operands[2]) > 0
489 && INTVAL (operands[2]) % 4 == 0"
490 [(set (match_dup 3) (match_dup 4))
491 (set (match_dup 0) (sign_extend:DI (plus:SI (mult:SI (match_dup 3)
496 HOST_WIDE_INT val = INTVAL (operands[2]) / 4;
502 operands[4] = GEN_INT (val);
503 operands[5] = GEN_INT (mult);
507 [(set (match_operand:DI 0 "register_operand" "")
509 (plus:SI (match_operator:SI 1 "comparison_operator"
510 [(match_operand 2 "" "")
511 (match_operand 3 "" "")])
512 (match_operand:SI 4 "add_operand" ""))))
513 (clobber (match_operand:DI 5 "register_operand" ""))]
515 [(set (match_dup 5) (match_dup 6))
516 (set (match_dup 0) (sign_extend:DI (plus:SI (match_dup 7) (match_dup 4))))]
519 operands[6] = gen_rtx_fmt_ee (GET_CODE (operands[1]), DImode,
520 operands[2], operands[3]);
521 operands[7] = gen_lowpart (SImode, operands[5]);
524 (define_insn "adddi3"
525 [(set (match_operand:DI 0 "register_operand" "=r,r,r,r")
526 (plus:DI (match_operand:DI 1 "reg_or_0_operand" "%rJ,rJ,rJ,rJ")
527 (match_operand:DI 2 "add_operand" "rI,O,K,L")))]
535 ;; Don't do this if we are adjusting SP since we don't want to do
538 [(set (match_operand:DI 0 "register_operand" "")
539 (plus:DI (match_operand:DI 1 "register_operand" "")
540 (match_operand:DI 2 "const_int_operand" "")))]
541 "! add_operand (operands[2], DImode)
542 && REGNO (operands[0]) != STACK_POINTER_REGNUM"
543 [(set (match_dup 0) (plus:DI (match_dup 1) (match_dup 3)))
544 (set (match_dup 0) (plus:DI (match_dup 0) (match_dup 4)))]
547 HOST_WIDE_INT val = INTVAL (operands[2]);
548 HOST_WIDE_INT low = (val & 0xffff) - 2 * (val & 0x8000);
549 HOST_WIDE_INT rest = val - low;
551 operands[3] = GEN_INT (rest);
552 operands[4] = GEN_INT (low);
556 [(set (match_operand:SI 0 "register_operand" "=r,r")
557 (plus:SI (mult:SI (match_operand:SI 1 "reg_not_elim_operand" "r,r")
558 (match_operand:SI 2 "const48_operand" "I,I"))
559 (match_operand:SI 3 "sext_add_operand" "rI,O")))]
566 [(set (match_operand:DI 0 "register_operand" "=r,r")
568 (plus:SI (mult:SI (match_operand:SI 1 "reg_not_elim_operand" "r,r")
569 (match_operand:SI 2 "const48_operand" "I,I"))
570 (match_operand:SI 3 "sext_add_operand" "rI,O"))))]
577 [(set (match_operand:DI 0 "register_operand" "")
579 (plus:SI (mult:SI (match_operator:SI 1 "comparison_operator"
580 [(match_operand 2 "" "")
581 (match_operand 3 "" "")])
582 (match_operand:SI 4 "const48_operand" ""))
583 (match_operand:SI 5 "add_operand" ""))))
584 (clobber (match_operand:DI 6 "reg_not_elim_operand" ""))]
586 [(set (match_dup 6) (match_dup 7))
588 (sign_extend:DI (plus:SI (mult:SI (match_dup 8) (match_dup 4))
592 operands[7] = gen_rtx_fmt_ee (GET_CODE (operands[1]), DImode,
593 operands[2], operands[3]);
594 operands[8] = gen_lowpart (SImode, operands[6]);
598 [(set (match_operand:DI 0 "register_operand" "=r,r")
599 (plus:DI (mult:DI (match_operand:DI 1 "reg_not_elim_operand" "r,r")
600 (match_operand:DI 2 "const48_operand" "I,I"))
601 (match_operand:DI 3 "sext_add_operand" "rI,O")))]
607 ;; These variants of the above insns can occur if the third operand
608 ;; is the frame pointer. This is a kludge, but there doesn't
609 ;; seem to be a way around it. Only recognize them while reloading.
612 [(set (match_operand:DI 0 "some_operand" "=&r")
613 (plus:DI (plus:DI (match_operand:DI 1 "some_operand" "r")
614 (match_operand:DI 2 "some_operand" "r"))
615 (match_operand:DI 3 "some_operand" "rIOKL")))]
620 [(set (match_operand:DI 0 "register_operand" "")
621 (plus:DI (plus:DI (match_operand:DI 1 "register_operand" "")
622 (match_operand:DI 2 "register_operand" ""))
623 (match_operand:DI 3 "add_operand" "")))]
625 [(set (match_dup 0) (plus:DI (match_dup 1) (match_dup 2)))
626 (set (match_dup 0) (plus:DI (match_dup 0) (match_dup 3)))]
630 [(set (match_operand:SI 0 "some_operand" "=&r")
631 (plus:SI (plus:SI (mult:SI (match_operand:SI 1 "some_operand" "rJ")
632 (match_operand:SI 2 "const48_operand" "I"))
633 (match_operand:SI 3 "some_operand" "r"))
634 (match_operand:SI 4 "some_operand" "rIOKL")))]
639 [(set (match_operand:SI 0 "register_operand" "r")
640 (plus:SI (plus:SI (mult:SI (match_operand:SI 1 "reg_or_0_operand" "")
641 (match_operand:SI 2 "const48_operand" ""))
642 (match_operand:SI 3 "register_operand" ""))
643 (match_operand:SI 4 "add_operand" "rIOKL")))]
646 (plus:SI (mult:SI (match_dup 1) (match_dup 2)) (match_dup 3)))
647 (set (match_dup 0) (plus:SI (match_dup 0) (match_dup 4)))]
651 [(set (match_operand:DI 0 "some_operand" "=&r")
654 (mult:SI (match_operand:SI 1 "some_operand" "rJ")
655 (match_operand:SI 2 "const48_operand" "I"))
656 (match_operand:SI 3 "some_operand" "r"))
657 (match_operand:SI 4 "some_operand" "rIOKL"))))]
662 [(set (match_operand:DI 0 "register_operand" "")
665 (mult:SI (match_operand:SI 1 "reg_or_0_operand" "")
666 (match_operand:SI 2 "const48_operand" ""))
667 (match_operand:SI 3 "register_operand" ""))
668 (match_operand:SI 4 "add_operand" ""))))]
671 (plus:SI (mult:SI (match_dup 1) (match_dup 2)) (match_dup 3)))
672 (set (match_dup 0) (sign_extend:DI (plus:SI (match_dup 5) (match_dup 4))))]
673 "operands[5] = gen_lowpart (SImode, operands[0]);")
676 [(set (match_operand:DI 0 "some_operand" "=&r")
677 (plus:DI (plus:DI (mult:DI (match_operand:DI 1 "some_operand" "rJ")
678 (match_operand:DI 2 "const48_operand" "I"))
679 (match_operand:DI 3 "some_operand" "r"))
680 (match_operand:DI 4 "some_operand" "rIOKL")))]
685 [(set (match_operand:DI 0 "register_operand" "=")
686 (plus:DI (plus:DI (mult:DI (match_operand:DI 1 "reg_or_0_operand" "")
687 (match_operand:DI 2 "const48_operand" ""))
688 (match_operand:DI 3 "register_operand" ""))
689 (match_operand:DI 4 "add_operand" "")))]
692 (plus:DI (mult:DI (match_dup 1) (match_dup 2)) (match_dup 3)))
693 (set (match_dup 0) (plus:DI (match_dup 0) (match_dup 4)))]
696 (define_insn "negsi2"
697 [(set (match_operand:SI 0 "register_operand" "=r")
698 (neg:SI (match_operand:SI 1 "reg_or_8bit_operand" "rI")))]
703 [(set (match_operand:DI 0 "register_operand" "=r")
704 (sign_extend:DI (neg:SI
705 (match_operand:SI 1 "reg_or_8bit_operand" "rI"))))]
709 (define_insn "negdi2"
710 [(set (match_operand:DI 0 "register_operand" "=r")
711 (neg:DI (match_operand:DI 1 "reg_or_8bit_operand" "rI")))]
715 (define_expand "subsi3"
716 [(set (match_operand:SI 0 "register_operand" "")
717 (minus:SI (match_operand:SI 1 "reg_or_0_operand" "")
718 (match_operand:SI 2 "reg_or_8bit_operand" "")))]
722 rtx op1 = gen_lowpart (DImode, operands[1]);
723 rtx op2 = gen_lowpart (DImode, operands[2]);
725 if (! cse_not_expected)
727 rtx tmp = gen_reg_rtx (DImode);
728 emit_insn (gen_subdi3 (tmp, op1, op2));
729 emit_move_insn (operands[0], gen_lowpart (SImode, tmp));
732 emit_insn (gen_subdi3 (gen_lowpart (DImode, operands[0]), op1, op2));
737 [(set (match_operand:SI 0 "register_operand" "=r")
738 (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rJ")
739 (match_operand:SI 2 "reg_or_8bit_operand" "rI")))]
744 [(set (match_operand:DI 0 "register_operand" "=r")
745 (sign_extend:DI (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rJ")
746 (match_operand:SI 2 "reg_or_8bit_operand" "rI"))))]
750 (define_insn "subdi3"
751 [(set (match_operand:DI 0 "register_operand" "=r")
752 (minus:DI (match_operand:DI 1 "reg_or_0_operand" "rJ")
753 (match_operand:DI 2 "reg_or_8bit_operand" "rI")))]
758 [(set (match_operand:SI 0 "register_operand" "=r")
759 (minus:SI (mult:SI (match_operand:SI 1 "reg_not_elim_operand" "r")
760 (match_operand:SI 2 "const48_operand" "I"))
761 (match_operand:SI 3 "reg_or_8bit_operand" "rI")))]
766 [(set (match_operand:DI 0 "register_operand" "=r")
768 (minus:SI (mult:SI (match_operand:SI 1 "reg_not_elim_operand" "r")
769 (match_operand:SI 2 "const48_operand" "I"))
770 (match_operand:SI 3 "reg_or_8bit_operand" "rI"))))]
775 [(set (match_operand:DI 0 "register_operand" "=r")
776 (minus:DI (mult:DI (match_operand:DI 1 "reg_not_elim_operand" "r")
777 (match_operand:DI 2 "const48_operand" "I"))
778 (match_operand:DI 3 "reg_or_8bit_operand" "rI")))]
782 (define_insn "mulsi3"
783 [(set (match_operand:SI 0 "register_operand" "=r")
784 (mult:SI (match_operand:SI 1 "reg_or_0_operand" "%rJ")
785 (match_operand:SI 2 "reg_or_8bit_operand" "rI")))]
788 [(set_attr "type" "imul")
789 (set_attr "opsize" "si")])
792 [(set (match_operand:DI 0 "register_operand" "=r")
794 (mult:SI (match_operand:SI 1 "reg_or_0_operand" "%rJ")
795 (match_operand:SI 2 "reg_or_8bit_operand" "rI"))))]
798 [(set_attr "type" "imul")
799 (set_attr "opsize" "si")])
801 (define_insn "muldi3"
802 [(set (match_operand:DI 0 "register_operand" "=r")
803 (mult:DI (match_operand:DI 1 "reg_or_0_operand" "%rJ")
804 (match_operand:DI 2 "reg_or_8bit_operand" "rI")))]
807 [(set_attr "type" "imul")])
809 (define_insn "umuldi3_highpart"
810 [(set (match_operand:DI 0 "register_operand" "=r")
813 (mult:TI (zero_extend:TI
814 (match_operand:DI 1 "reg_or_0_operand" "%rJ"))
816 (match_operand:DI 2 "reg_or_8bit_operand" "rI")))
820 [(set_attr "type" "imul")
821 (set_attr "opsize" "udi")])
824 [(set (match_operand:DI 0 "register_operand" "=r")
827 (mult:TI (zero_extend:TI (match_operand:DI 1 "register_operand" "r"))
828 (match_operand:TI 2 "cint8_operand" "I"))
832 [(set_attr "type" "imul")
833 (set_attr "opsize" "udi")])
835 ;; The divide and remainder operations always take their inputs from
836 ;; r24 and r25, put their output in r27, and clobber r23 and r28.
838 ;; ??? Force sign-extension here because some versions of OSF/1 don't
839 ;; do the right thing if the inputs are not properly sign-extended.
840 ;; But Linux, for instance, does not have this problem. Is it worth
841 ;; the complication here to eliminate the sign extension?
843 (define_expand "divsi3"
845 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "")))
847 (sign_extend:DI (match_operand:SI 2 "nonimmediate_operand" "")))
848 (parallel [(set (reg:DI 27)
849 (sign_extend:DI (div:SI (reg:DI 24) (reg:DI 25))))
850 (clobber (reg:DI 23))
851 (clobber (reg:DI 28))])
852 (set (match_operand:SI 0 "general_operand" "")
853 (subreg:SI (reg:DI 27) 0))]
857 (define_expand "udivsi3"
859 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "")))
861 (sign_extend:DI (match_operand:SI 2 "nonimmediate_operand" "")))
862 (parallel [(set (reg:DI 27)
863 (sign_extend:DI (udiv:SI (reg:DI 24) (reg:DI 25))))
864 (clobber (reg:DI 23))
865 (clobber (reg:DI 28))])
866 (set (match_operand:SI 0 "general_operand" "")
867 (subreg:SI (reg:DI 27) 0))]
871 (define_expand "modsi3"
873 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "")))
875 (sign_extend:DI (match_operand:SI 2 "nonimmediate_operand" "")))
876 (parallel [(set (reg:DI 27)
877 (sign_extend:DI (mod:SI (reg:DI 24) (reg:DI 25))))
878 (clobber (reg:DI 23))
879 (clobber (reg:DI 28))])
880 (set (match_operand:SI 0 "general_operand" "")
881 (subreg:SI (reg:DI 27) 0))]
885 (define_expand "umodsi3"
887 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "")))
889 (sign_extend:DI (match_operand:SI 2 "nonimmediate_operand" "")))
890 (parallel [(set (reg:DI 27)
891 (sign_extend:DI (umod:SI (reg:DI 24) (reg:DI 25))))
892 (clobber (reg:DI 23))
893 (clobber (reg:DI 28))])
894 (set (match_operand:SI 0 "general_operand" "")
895 (subreg:SI (reg:DI 27) 0))]
899 (define_expand "divdi3"
900 [(set (reg:DI 24) (match_operand:DI 1 "input_operand" ""))
901 (set (reg:DI 25) (match_operand:DI 2 "input_operand" ""))
902 (parallel [(set (reg:DI 27)
905 (clobber (reg:DI 23))
906 (clobber (reg:DI 28))])
907 (set (match_operand:DI 0 "general_operand" "")
912 (define_expand "udivdi3"
913 [(set (reg:DI 24) (match_operand:DI 1 "input_operand" ""))
914 (set (reg:DI 25) (match_operand:DI 2 "input_operand" ""))
915 (parallel [(set (reg:DI 27)
918 (clobber (reg:DI 23))
919 (clobber (reg:DI 28))])
920 (set (match_operand:DI 0 "general_operand" "")
925 (define_expand "moddi3"
926 [(set (reg:DI 24) (match_operand:DI 1 "input_operand" ""))
927 (set (reg:DI 25) (match_operand:DI 2 "input_operand" ""))
928 (parallel [(set (reg:DI 27)
931 (clobber (reg:DI 23))
932 (clobber (reg:DI 28))])
933 (set (match_operand:DI 0 "general_operand" "")
938 (define_expand "umoddi3"
939 [(set (reg:DI 24) (match_operand:DI 1 "input_operand" ""))
940 (set (reg:DI 25) (match_operand:DI 2 "input_operand" ""))
941 (parallel [(set (reg:DI 27)
944 (clobber (reg:DI 23))
945 (clobber (reg:DI 28))])
946 (set (match_operand:DI 0 "general_operand" "")
951 ;; Lengths of 8 for ldq $t12,__divq($gp); jsr $t9,($t12),__divq as
952 ;; expanded by the assembler.
955 (sign_extend:DI (match_operator:SI 1 "divmod_operator"
956 [(reg:DI 24) (reg:DI 25)])))
957 (clobber (reg:DI 23))
958 (clobber (reg:DI 28))]
961 [(set_attr "type" "jsr")
962 (set_attr "length" "8")])
966 (match_operator:DI 1 "divmod_operator"
967 [(reg:DI 24) (reg:DI 25)]))
968 (clobber (reg:DI 23))
969 (clobber (reg:DI 28))]
972 [(set_attr "type" "jsr")
973 (set_attr "length" "8")])
975 ;; Next are the basic logical operations. These only exist in DImode.
977 (define_insn "anddi3"
978 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
979 (and:DI (match_operand:DI 1 "reg_or_0_operand" "%rJ,rJ,rJ")
980 (match_operand:DI 2 "and_operand" "rI,N,MH")))]
986 [(set_attr "type" "ilog,ilog,shift")])
988 ;; There are times when we can split an AND into two AND insns. This occurs
989 ;; when we can first clear any bytes and then clear anything else. For
990 ;; example "I & 0xffff07" is "(I & 0xffffff) & 0xffffffffffffff07".
991 ;; Only do this when running on 64-bit host since the computations are
992 ;; too messy otherwise.
995 [(set (match_operand:DI 0 "register_operand" "")
996 (and:DI (match_operand:DI 1 "register_operand" "")
997 (match_operand:DI 2 "const_int_operand" "")))]
998 "HOST_BITS_PER_WIDE_INT == 64 && ! and_operand (operands[2], DImode)"
999 [(set (match_dup 0) (and:DI (match_dup 1) (match_dup 3)))
1000 (set (match_dup 0) (and:DI (match_dup 0) (match_dup 4)))]
1003 unsigned HOST_WIDE_INT mask1 = INTVAL (operands[2]);
1004 unsigned HOST_WIDE_INT mask2 = mask1;
1007 /* For each byte that isn't all zeros, make it all ones. */
1008 for (i = 0; i < 64; i += 8)
1009 if ((mask1 & ((HOST_WIDE_INT) 0xff << i)) != 0)
1010 mask1 |= (HOST_WIDE_INT) 0xff << i;
1012 /* Now turn on any bits we've just turned off. */
1015 operands[3] = GEN_INT (mask1);
1016 operands[4] = GEN_INT (mask2);
1019 (define_insn "zero_extendqihi2"
1020 [(set (match_operand:HI 0 "register_operand" "=r")
1021 (zero_extend:HI (match_operand:QI 1 "register_operand" "r")))]
1024 [(set_attr "type" "ilog")])
1027 [(set (match_operand:SI 0 "register_operand" "=r,r")
1028 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "r,m")))]
1033 [(set_attr "type" "ilog,ild")])
1036 [(set (match_operand:SI 0 "register_operand" "=r")
1037 (zero_extend:SI (match_operand:QI 1 "register_operand" "r")))]
1040 [(set_attr "type" "ilog")])
1042 (define_expand "zero_extendqisi2"
1043 [(set (match_operand:SI 0 "register_operand" "")
1044 (zero_extend:SI (match_operand:QI 1 "register_operand" "")))]
1049 [(set (match_operand:DI 0 "register_operand" "=r,r")
1050 (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand" "r,m")))]
1055 [(set_attr "type" "ilog,ild")])
1058 [(set (match_operand:DI 0 "register_operand" "=r")
1059 (zero_extend:DI (match_operand:QI 1 "register_operand" "r")))]
1062 [(set_attr "type" "ilog")])
1064 (define_expand "zero_extendqidi2"
1065 [(set (match_operand:DI 0 "register_operand" "")
1066 (zero_extend:DI (match_operand:QI 1 "register_operand" "")))]
1071 [(set (match_operand:SI 0 "register_operand" "=r,r")
1072 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "r,m")))]
1077 [(set_attr "type" "shift,ild")])
1080 [(set (match_operand:SI 0 "register_operand" "=r")
1081 (zero_extend:SI (match_operand:HI 1 "register_operand" "r")))]
1084 [(set_attr "type" "shift")])
1086 (define_expand "zero_extendhisi2"
1087 [(set (match_operand:SI 0 "register_operand" "")
1088 (zero_extend:SI (match_operand:HI 1 "register_operand" "")))]
1093 [(set (match_operand:DI 0 "register_operand" "=r,r")
1094 (zero_extend:DI (match_operand:HI 1 "nonimmediate_operand" "r,m")))]
1099 [(set_attr "type" "shift,ild")])
1102 [(set (match_operand:DI 0 "register_operand" "=r")
1103 (zero_extend:DI (match_operand:HI 1 "register_operand" "r")))]
1106 [(set_attr "type" "shift")])
1108 (define_expand "zero_extendhidi2"
1109 [(set (match_operand:DI 0 "register_operand" "")
1110 (zero_extend:DI (match_operand:HI 1 "register_operand" "")))]
1114 (define_insn "zero_extendsidi2"
1115 [(set (match_operand:DI 0 "register_operand" "=r")
1116 (zero_extend:DI (match_operand:SI 1 "register_operand" "r")))]
1119 [(set_attr "type" "shift")])
1122 [(set (match_operand:DI 0 "register_operand" "=r")
1123 (and:DI (not:DI (match_operand:DI 1 "reg_or_8bit_operand" "rI"))
1124 (match_operand:DI 2 "reg_or_0_operand" "rJ")))]
1127 [(set_attr "type" "ilog")])
1129 (define_insn "iordi3"
1130 [(set (match_operand:DI 0 "register_operand" "=r,r")
1131 (ior:DI (match_operand:DI 1 "reg_or_0_operand" "%rJ,rJ")
1132 (match_operand:DI 2 "or_operand" "rI,N")))]
1137 [(set_attr "type" "ilog")])
1139 (define_insn "one_cmpldi2"
1140 [(set (match_operand:DI 0 "register_operand" "=r")
1141 (not:DI (match_operand:DI 1 "reg_or_8bit_operand" "rI")))]
1144 [(set_attr "type" "ilog")])
1147 [(set (match_operand:DI 0 "register_operand" "=r")
1148 (ior:DI (not:DI (match_operand:DI 1 "reg_or_8bit_operand" "rI"))
1149 (match_operand:DI 2 "reg_or_0_operand" "rJ")))]
1152 [(set_attr "type" "ilog")])
1154 (define_insn "xordi3"
1155 [(set (match_operand:DI 0 "register_operand" "=r,r")
1156 (xor:DI (match_operand:DI 1 "reg_or_0_operand" "%rJ,rJ")
1157 (match_operand:DI 2 "or_operand" "rI,N")))]
1162 [(set_attr "type" "ilog")])
1165 [(set (match_operand:DI 0 "register_operand" "=r")
1166 (not:DI (xor:DI (match_operand:DI 1 "register_operand" "%rJ")
1167 (match_operand:DI 2 "register_operand" "rI"))))]
1170 [(set_attr "type" "ilog")])
1172 ;; Handle the FFS insn if we support CIX.
1174 (define_expand "ffsdi2"
1176 (unspec [(match_operand:DI 1 "register_operand" "")] 1))
1178 (plus:DI (match_dup 2) (const_int 1)))
1179 (set (match_operand:DI 0 "register_operand" "")
1180 (if_then_else:DI (eq (match_dup 1) (const_int 0))
1181 (const_int 0) (match_dup 3)))]
1185 operands[2] = gen_reg_rtx (DImode);
1186 operands[3] = gen_reg_rtx (DImode);
1190 [(set (match_operand:DI 0 "register_operand" "=r")
1191 (unspec [(match_operand:DI 1 "register_operand" "r")] 1))]
1194 ; ev6 calls all mvi and cttz/ctlz/popc class imisc, so just
1195 ; reuse the existing type name.
1196 [(set_attr "type" "mvi")])
1198 ;; Next come the shifts and the various extract and insert operations.
1200 (define_insn "ashldi3"
1201 [(set (match_operand:DI 0 "register_operand" "=r,r")
1202 (ashift:DI (match_operand:DI 1 "reg_or_0_operand" "rJ,rJ")
1203 (match_operand:DI 2 "reg_or_6bit_operand" "P,rS")))]
1207 switch (which_alternative)
1210 if (operands[2] == const1_rtx)
1211 return \"addq %r1,%r1,%0\";
1213 return \"s%P2addq %r1,0,%0\";
1215 return \"sll %r1,%2,%0\";
1220 [(set_attr "type" "iadd,shift")])
1222 ;; ??? The following pattern is made by combine, but earlier phases
1223 ;; (specifically flow) can't handle it. This occurs in jump.c. Deal
1224 ;; with this in a better way at some point.
1226 ;; [(set (match_operand:DI 0 "register_operand" "=r")
1228 ;; (subreg:SI (ashift:DI (match_operand:DI 1 "reg_or_0_operand" "rJ")
1229 ;; (match_operand:DI 2 "const_int_operand" "P"))
1231 ;; "INTVAL (operands[2]) >= 1 && INTVAL (operands[2]) <= 3"
1234 ;; if (operands[2] == const1_rtx)
1235 ;; return \"addl %r1,%r1,%0\";
1237 ;; return \"s%P2addl %r1,0,%0\";
1239 ;; [(set_attr "type" "iadd")])
1241 (define_insn "lshrdi3"
1242 [(set (match_operand:DI 0 "register_operand" "=r")
1243 (lshiftrt:DI (match_operand:DI 1 "reg_or_0_operand" "rJ")
1244 (match_operand:DI 2 "reg_or_6bit_operand" "rS")))]
1247 [(set_attr "type" "shift")])
1249 (define_insn "ashrdi3"
1250 [(set (match_operand:DI 0 "register_operand" "=r")
1251 (ashiftrt:DI (match_operand:DI 1 "reg_or_0_operand" "rJ")
1252 (match_operand:DI 2 "reg_or_6bit_operand" "rS")))]
1255 [(set_attr "type" "shift")])
1257 (define_expand "extendqihi2"
1259 (ashift:DI (match_operand:QI 1 "some_operand" "")
1261 (set (match_operand:HI 0 "register_operand" "")
1262 (ashiftrt:DI (match_dup 2)
1269 emit_insn (gen_extendqihi2x (operands[0],
1270 force_reg (QImode, operands[1])));
1274 /* If we have an unaligned MEM, extend to DImode (which we do
1275 specially) and then copy to the result. */
1276 if (unaligned_memory_operand (operands[1], HImode))
1278 rtx temp = gen_reg_rtx (DImode);
1280 emit_insn (gen_extendqidi2 (temp, operands[1]));
1281 emit_move_insn (operands[0], gen_lowpart (HImode, temp));
1285 operands[0] = gen_lowpart (DImode, operands[0]);
1286 operands[1] = gen_lowpart (DImode, force_reg (QImode, operands[1]));
1287 operands[2] = gen_reg_rtx (DImode);
1290 (define_insn "extendqidi2x"
1291 [(set (match_operand:DI 0 "register_operand" "=r")
1292 (sign_extend:DI (match_operand:QI 1 "register_operand" "r")))]
1295 [(set_attr "type" "shift")])
1297 (define_insn "extendhidi2x"
1298 [(set (match_operand:DI 0 "register_operand" "=r")
1299 (sign_extend:DI (match_operand:HI 1 "register_operand" "r")))]
1302 [(set_attr "type" "shift")])
1304 (define_insn "extendqisi2x"
1305 [(set (match_operand:SI 0 "register_operand" "=r")
1306 (sign_extend:SI (match_operand:QI 1 "register_operand" "r")))]
1309 [(set_attr "type" "shift")])
1311 (define_insn "extendhisi2x"
1312 [(set (match_operand:SI 0 "register_operand" "=r")
1313 (sign_extend:SI (match_operand:HI 1 "register_operand" "r")))]
1316 [(set_attr "type" "shift")])
1318 (define_insn "extendqihi2x"
1319 [(set (match_operand:HI 0 "register_operand" "=r")
1320 (sign_extend:HI (match_operand:QI 1 "register_operand" "r")))]
1323 [(set_attr "type" "shift")])
1325 (define_expand "extendqisi2"
1327 (ashift:DI (match_operand:QI 1 "some_operand" "")
1329 (set (match_operand:SI 0 "register_operand" "")
1330 (ashiftrt:DI (match_dup 2)
1337 emit_insn (gen_extendqisi2x (operands[0],
1338 force_reg (QImode, operands[1])));
1342 /* If we have an unaligned MEM, extend to a DImode form of
1343 the result (which we do specially). */
1344 if (unaligned_memory_operand (operands[1], QImode))
1346 rtx temp = gen_reg_rtx (DImode);
1348 emit_insn (gen_extendqidi2 (temp, operands[1]));
1349 emit_move_insn (operands[0], gen_lowpart (SImode, temp));
1353 operands[0] = gen_lowpart (DImode, operands[0]);
1354 operands[1] = gen_lowpart (DImode, force_reg (QImode, operands[1]));
1355 operands[2] = gen_reg_rtx (DImode);
1358 (define_expand "extendqidi2"
1360 (ashift:DI (match_operand:QI 1 "some_operand" "")
1362 (set (match_operand:DI 0 "register_operand" "")
1363 (ashiftrt:DI (match_dup 2)
1370 emit_insn (gen_extendqidi2x (operands[0],
1371 force_reg (QImode, operands[1])));
1375 if (unaligned_memory_operand (operands[1], QImode))
1378 = gen_unaligned_extendqidi (operands[0],
1379 get_unaligned_address (operands[1], 1));
1381 alpha_set_memflags (seq, operands[1]);
1386 operands[1] = gen_lowpart (DImode, force_reg (QImode, operands[1]));
1387 operands[2] = gen_reg_rtx (DImode);
1390 (define_expand "extendhisi2"
1392 (ashift:DI (match_operand:HI 1 "some_operand" "")
1394 (set (match_operand:SI 0 "register_operand" "")
1395 (ashiftrt:DI (match_dup 2)
1402 emit_insn (gen_extendhisi2x (operands[0],
1403 force_reg (HImode, operands[1])));
1407 /* If we have an unaligned MEM, extend to a DImode form of
1408 the result (which we do specially). */
1409 if (unaligned_memory_operand (operands[1], HImode))
1411 rtx temp = gen_reg_rtx (DImode);
1413 emit_insn (gen_extendhidi2 (temp, operands[1]));
1414 emit_move_insn (operands[0], gen_lowpart (SImode, temp));
1418 operands[0] = gen_lowpart (DImode, operands[0]);
1419 operands[1] = gen_lowpart (DImode, force_reg (HImode, operands[1]));
1420 operands[2] = gen_reg_rtx (DImode);
1423 (define_expand "extendhidi2"
1425 (ashift:DI (match_operand:HI 1 "some_operand" "")
1427 (set (match_operand:DI 0 "register_operand" "")
1428 (ashiftrt:DI (match_dup 2)
1435 emit_insn (gen_extendhidi2x (operands[0],
1436 force_reg (HImode, operands[1])));
1440 if (unaligned_memory_operand (operands[1], HImode))
1443 = gen_unaligned_extendhidi (operands[0],
1444 get_unaligned_address (operands[1], 2));
1446 alpha_set_memflags (seq, operands[1]);
1451 operands[1] = gen_lowpart (DImode, force_reg (HImode, operands[1]));
1452 operands[2] = gen_reg_rtx (DImode);
1455 ;; Here's how we sign extend an unaligned byte and halfword. Doing this
1456 ;; as a pattern saves one instruction. The code is similar to that for
1457 ;; the unaligned loads (see below).
1459 ;; Operand 1 is the address + 1 (+2 for HI), operand 0 is the result.
1460 (define_expand "unaligned_extendqidi"
1461 [(set (match_dup 2) (match_operand:DI 1 "address_operand" ""))
1463 (mem:DI (and:DI (plus:DI (match_dup 2) (const_int -1))
1466 (ashift:DI (match_dup 3)
1467 (minus:DI (const_int 56)
1469 (and:DI (plus:DI (match_dup 2) (const_int -1))
1472 (set (subreg:DI (match_operand:QI 0 "register_operand" "") 0)
1473 (ashiftrt:DI (match_dup 4) (const_int 56)))]
1476 { operands[2] = gen_reg_rtx (DImode);
1477 operands[3] = gen_reg_rtx (DImode);
1478 operands[4] = gen_reg_rtx (DImode);
1481 (define_expand "unaligned_extendhidi"
1482 [(set (match_dup 2) (match_operand:DI 1 "address_operand" ""))
1484 (mem:DI (and:DI (plus:DI (match_dup 2) (const_int -2))
1487 (ashift:DI (match_dup 3)
1488 (minus:DI (const_int 56)
1490 (and:DI (plus:DI (match_dup 2) (const_int -1))
1493 (set (subreg:DI (match_operand:QI 0 "register_operand" "") 0)
1494 (ashiftrt:DI (match_dup 4) (const_int 48)))]
1497 { operands[2] = gen_reg_rtx (DImode);
1498 operands[3] = gen_reg_rtx (DImode);
1499 operands[4] = gen_reg_rtx (DImode);
1503 [(set (match_operand:DI 0 "register_operand" "=r")
1504 (zero_extract:DI (match_operand:DI 1 "reg_or_0_operand" "rJ")
1505 (match_operand:DI 2 "mode_width_operand" "n")
1506 (match_operand:DI 3 "mul8_operand" "I")))]
1508 "ext%M2l %r1,%s3,%0"
1509 [(set_attr "type" "shift")])
1511 (define_insn "extxl"
1512 [(set (match_operand:DI 0 "register_operand" "=r")
1513 (zero_extract:DI (match_operand:DI 1 "reg_or_0_operand" "rJ")
1514 (match_operand:DI 2 "mode_width_operand" "n")
1515 (ashift:DI (match_operand:DI 3 "reg_or_8bit_operand" "rI")
1519 [(set_attr "type" "shift")])
1521 ;; Combine has some strange notion of preserving existing undefined behaviour
1522 ;; in shifts larger than a word size. So capture these patterns that it
1523 ;; should have turned into zero_extracts.
1526 [(set (match_operand:DI 0 "register_operand" "=r")
1527 (and (lshiftrt:DI (match_operand:DI 1 "reg_or_0_operand" "rJ")
1528 (ashift:DI (match_operand:DI 2 "reg_or_8bit_operand" "rI")
1530 (match_operand:DI 3 "mode_mask_operand" "n")))]
1533 [(set_attr "type" "shift")])
1536 [(set (match_operand:DI 0 "register_operand" "=r")
1537 (lshiftrt:DI (match_operand:DI 1 "reg_or_0_operand" "rJ")
1538 (ashift:DI (match_operand:DI 2 "reg_or_8bit_operand" "rI")
1542 [(set_attr "type" "shift")])
1544 (define_insn "extqh"
1545 [(set (match_operand:DI 0 "register_operand" "=r")
1547 (match_operand:DI 1 "reg_or_0_operand" "rJ")
1548 (minus:DI (const_int 56)
1551 (plus:DI (match_operand:DI 2 "reg_or_8bit_operand" "rI")
1557 [(set_attr "type" "shift")])
1559 (define_insn "extlh"
1560 [(set (match_operand:DI 0 "register_operand" "=r")
1562 (and:DI (match_operand:DI 1 "reg_or_0_operand" "rJ")
1563 (const_int 2147483647))
1564 (minus:DI (const_int 56)
1567 (plus:DI (match_operand:DI 2 "reg_or_8bit_operand" "rI")
1573 [(set_attr "type" "shift")])
1575 (define_insn "extwh"
1576 [(set (match_operand:DI 0 "register_operand" "=r")
1578 (and:DI (match_operand:DI 1 "reg_or_0_operand" "rJ")
1580 (minus:DI (const_int 56)
1583 (plus:DI (match_operand:DI 2 "reg_or_8bit_operand" "rI")
1589 [(set_attr "type" "shift")])
1591 ;; This converts an extXl into an extXh with an appropriate adjustment
1592 ;; to the address calculation.
1595 ;; [(set (match_operand:DI 0 "register_operand" "")
1596 ;; (ashift:DI (zero_extract:DI (match_operand:DI 1 "register_operand" "")
1597 ;; (match_operand:DI 2 "mode_width_operand" "")
1598 ;; (ashift:DI (match_operand:DI 3 "" "")
1600 ;; (match_operand:DI 4 "const_int_operand" "")))
1601 ;; (clobber (match_operand:DI 5 "register_operand" ""))]
1602 ;; "INTVAL (operands[4]) == 64 - INTVAL (operands[2])"
1603 ;; [(set (match_dup 5) (match_dup 6))
1604 ;; (set (match_dup 0)
1605 ;; (ashift:DI (zero_extract:DI (match_dup 1) (match_dup 2)
1606 ;; (ashift:DI (plus:DI (match_dup 5)
1612 ;; operands[6] = plus_constant (operands[3],
1613 ;; INTVAL (operands[2]) / BITS_PER_UNIT);
1614 ;; operands[7] = GEN_INT (- INTVAL (operands[2]) / BITS_PER_UNIT);
1618 [(set (match_operand:DI 0 "register_operand" "=r")
1619 (ashift:DI (zero_extend:DI (match_operand:QI 1 "register_operand" "r"))
1620 (match_operand:DI 2 "mul8_operand" "I")))]
1623 [(set_attr "type" "shift")])
1626 [(set (match_operand:DI 0 "register_operand" "=r")
1627 (ashift:DI (zero_extend:DI (match_operand:HI 1 "register_operand" "r"))
1628 (match_operand:DI 2 "mul8_operand" "I")))]
1631 [(set_attr "type" "shift")])
1634 [(set (match_operand:DI 0 "register_operand" "=r")
1635 (ashift:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
1636 (match_operand:DI 2 "mul8_operand" "I")))]
1639 [(set_attr "type" "shift")])
1641 (define_insn "insbl"
1642 [(set (match_operand:DI 0 "register_operand" "=r")
1643 (ashift:DI (zero_extend:DI (match_operand:QI 1 "register_operand" "r"))
1644 (ashift:DI (match_operand:DI 2 "reg_or_8bit_operand" "rI")
1648 [(set_attr "type" "shift")])
1650 (define_insn "inswl"
1651 [(set (match_operand:DI 0 "register_operand" "=r")
1652 (ashift:DI (zero_extend:DI (match_operand:HI 1 "register_operand" "r"))
1653 (ashift:DI (match_operand:DI 2 "reg_or_8bit_operand" "rI")
1657 [(set_attr "type" "shift")])
1659 (define_insn "insll"
1660 [(set (match_operand:DI 0 "register_operand" "=r")
1661 (ashift:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
1662 (ashift:DI (match_operand:DI 2 "reg_or_8bit_operand" "rI")
1666 [(set_attr "type" "shift")])
1668 (define_insn "insql"
1669 [(set (match_operand:DI 0 "register_operand" "=r")
1670 (ashift:DI (match_operand:DI 1 "register_operand" "r")
1671 (ashift:DI (match_operand:DI 2 "reg_or_8bit_operand" "rI")
1675 [(set_attr "type" "shift")])
1677 ;; Combine has this sometimes habit of moving the and outside of the
1678 ;; shift, making life more interesting.
1681 [(set (match_operand:DI 0 "register_operand" "=r")
1682 (and:DI (ashift:DI (match_operand:DI 1 "register_operand" "r")
1683 (match_operand:DI 2 "mul8_operand" "I"))
1684 (match_operand:DI 3 "immediate_operand" "i")))]
1685 "HOST_BITS_PER_WIDE_INT == 64
1686 && GET_CODE (operands[3]) == CONST_INT
1687 && (((unsigned HOST_WIDE_INT) 0xff << INTVAL (operands[2])
1688 == INTVAL (operands[3]))
1689 || ((unsigned HOST_WIDE_INT) 0xffff << INTVAL (operands[2])
1690 == INTVAL (operands[3]))
1691 || ((unsigned HOST_WIDE_INT) 0xffffffff << INTVAL (operands[2])
1692 == INTVAL (operands[3])))"
1695 #if HOST_BITS_PER_WIDE_INT == 64
1696 if ((unsigned HOST_WIDE_INT) 0xff << INTVAL (operands[2])
1697 == INTVAL (operands[3]))
1698 return \"insbl %1,%s2,%0\";
1699 if ((unsigned HOST_WIDE_INT) 0xffff << INTVAL (operands[2])
1700 == INTVAL (operands[3]))
1701 return \"inswl %1,%s2,%0\";
1702 if ((unsigned HOST_WIDE_INT) 0xffffffff << INTVAL (operands[2])
1703 == INTVAL (operands[3]))
1704 return \"insll %1,%s2,%0\";
1708 [(set_attr "type" "shift")])
1710 ;; We do not include the insXh insns because they are complex to express
1711 ;; and it does not appear that we would ever want to generate them.
1713 ;; Since we need them for block moves, though, cop out and use unspec.
1715 (define_insn "insxh"
1716 [(set (match_operand:DI 0 "register_operand" "=r")
1717 (unspec [(match_operand:DI 1 "register_operand" "r")
1718 (match_operand:DI 2 "mode_width_operand" "n")
1719 (match_operand:DI 3 "reg_or_8bit_operand" "rI")] 2))]
1722 [(set_attr "type" "shift")])
1724 (define_insn "mskxl"
1725 [(set (match_operand:DI 0 "register_operand" "=r")
1726 (and:DI (not:DI (ashift:DI
1727 (match_operand:DI 2 "mode_mask_operand" "n")
1729 (match_operand:DI 3 "reg_or_8bit_operand" "rI")
1731 (match_operand:DI 1 "reg_or_0_operand" "rJ")))]
1734 [(set_attr "type" "shift")])
1736 ;; We do not include the mskXh insns because it does not appear we would
1737 ;; ever generate one.
1739 ;; Again, we do for block moves and we use unspec again.
1741 (define_insn "mskxh"
1742 [(set (match_operand:DI 0 "register_operand" "=r")
1743 (unspec [(match_operand:DI 1 "register_operand" "r")
1744 (match_operand:DI 2 "mode_width_operand" "n")
1745 (match_operand:DI 3 "reg_or_8bit_operand" "rI")] 3))]
1748 [(set_attr "type" "shift")])
1750 ;; Floating-point operations. All the double-precision insns can extend
1751 ;; from single, so indicate that. The exception are the ones that simply
1752 ;; play with the sign bits; it's not clear what to do there.
1754 (define_insn "abssf2"
1755 [(set (match_operand:SF 0 "register_operand" "=f")
1756 (abs:SF (match_operand:SF 1 "reg_or_fp0_operand" "fG")))]
1759 [(set_attr "type" "fcpys")])
1761 (define_insn "absdf2"
1762 [(set (match_operand:DF 0 "register_operand" "=f")
1763 (abs:DF (match_operand:DF 1 "reg_or_fp0_operand" "fG")))]
1766 [(set_attr "type" "fcpys")])
1768 (define_insn "negsf2"
1769 [(set (match_operand:SF 0 "register_operand" "=f")
1770 (neg:SF (match_operand:SF 1 "reg_or_fp0_operand" "fG")))]
1773 [(set_attr "type" "fadd")])
1775 (define_insn "negdf2"
1776 [(set (match_operand:DF 0 "register_operand" "=f")
1777 (neg:DF (match_operand:DF 1 "reg_or_fp0_operand" "fG")))]
1780 [(set_attr "type" "fadd")])
1783 [(set (match_operand:SF 0 "register_operand" "=&f")
1784 (plus:SF (match_operand:SF 1 "reg_or_fp0_operand" "%fG")
1785 (match_operand:SF 2 "reg_or_fp0_operand" "fG")))]
1786 "TARGET_FP && alpha_tp == ALPHA_TP_INSN"
1787 "add%,%)%& %R1,%R2,%0"
1788 [(set_attr "type" "fadd")
1789 (set_attr "trap" "yes")])
1791 (define_insn "addsf3"
1792 [(set (match_operand:SF 0 "register_operand" "=f")
1793 (plus:SF (match_operand:SF 1 "reg_or_fp0_operand" "%fG")
1794 (match_operand:SF 2 "reg_or_fp0_operand" "fG")))]
1796 "add%,%)%& %R1,%R2,%0"
1797 [(set_attr "type" "fadd")
1798 (set_attr "trap" "yes")])
1801 [(set (match_operand:DF 0 "register_operand" "=&f")
1802 (plus:DF (match_operand:DF 1 "reg_or_fp0_operand" "%fG")
1803 (match_operand:DF 2 "reg_or_fp0_operand" "fG")))]
1804 "TARGET_FP && alpha_tp == ALPHA_TP_INSN"
1805 "add%-%)%& %R1,%R2,%0"
1806 [(set_attr "type" "fadd")
1807 (set_attr "trap" "yes")])
1809 (define_insn "adddf3"
1810 [(set (match_operand:DF 0 "register_operand" "=f")
1811 (plus:DF (match_operand:DF 1 "reg_or_fp0_operand" "%fG")
1812 (match_operand:DF 2 "reg_or_fp0_operand" "fG")))]
1814 "add%-%)%& %R1,%R2,%0"
1815 [(set_attr "type" "fadd")
1816 (set_attr "trap" "yes")])
1819 [(set (match_operand:DF 0 "register_operand" "=f")
1820 (plus:DF (float_extend:DF
1821 (match_operand:SF 1 "reg_or_fp0_operand" "fG"))
1822 (match_operand:DF 2 "reg_or_fp0_operand" "fG")))]
1823 "TARGET_FP && alpha_tp != ALPHA_TP_INSN"
1824 "add%-%)%& %R1,%R2,%0"
1825 [(set_attr "type" "fadd")
1826 (set_attr "trap" "yes")])
1829 [(set (match_operand:DF 0 "register_operand" "=f")
1830 (plus:DF (float_extend:DF
1831 (match_operand:SF 1 "reg_or_fp0_operand" "%fG"))
1833 (match_operand:SF 2 "reg_or_fp0_operand" "fG"))))]
1834 "TARGET_FP && alpha_tp != ALPHA_TP_INSN"
1835 "add%-%)%& %R1,%R2,%0"
1836 [(set_attr "type" "fadd")
1837 (set_attr "trap" "yes")])
1839 ;; Define conversion operators between DFmode and SImode, using the cvtql
1840 ;; instruction. To allow combine et al to do useful things, we keep the
1841 ;; operation as a unit until after reload, at which point we split the
1844 ;; Note that we (attempt to) only consider this optimization when the
1845 ;; ultimate destination is memory. If we will be doing further integer
1846 ;; processing, it is cheaper to do the truncation in the int regs.
1848 (define_insn "*cvtql"
1849 [(set (match_operand:SI 0 "register_operand" "=f")
1850 (unspec:SI [(match_operand:DI 1 "reg_or_fp0_operand" "fG")] 5))]
1853 [(set_attr "type" "fadd")
1854 (set_attr "trap" "yes")])
1857 [(set (match_operand:SI 0 "memory_operand" "")
1858 (subreg:SI (fix:DI (match_operand:DF 1 "reg_or_fp0_operand" "")) 0))
1859 (clobber (match_scratch:DI 2 ""))
1860 (clobber (match_scratch:SI 3 ""))]
1861 "TARGET_FP && reload_completed"
1862 [(set (match_dup 2) (fix:DI (match_dup 1)))
1863 (set (match_dup 3) (unspec:SI [(match_dup 2)] 5))
1864 (set (match_dup 0) (match_dup 3))]
1868 [(set (match_operand:SI 0 "memory_operand" "")
1869 (subreg:SI (fix:DI (match_operand:DF 1 "reg_or_fp0_operand" "")) 0))
1870 (clobber (match_scratch:DI 2 ""))]
1871 "TARGET_FP && reload_completed"
1872 [(set (match_dup 2) (fix:DI (match_dup 1)))
1873 (set (match_dup 3) (unspec:SI [(match_dup 2)] 5))
1874 (set (match_dup 0) (match_dup 3))]
1875 ;; Due to REG_CANNOT_CHANGE_SIZE issues, we cannot simply use SUBREG.
1876 "operands[3] = gen_rtx_REG (SImode, REGNO (operands[2]));")
1879 [(set (match_operand:SI 0 "memory_operand" "=m")
1880 (subreg:SI (fix:DI (match_operand:DF 1 "reg_or_fp0_operand" "fG")) 0))
1881 (clobber (match_scratch:DI 2 "=&f"))
1882 (clobber (match_scratch:SI 3 "=&f"))]
1883 "TARGET_FP && alpha_tp == ALPHA_TP_INSN"
1885 [(set_attr "type" "fadd")
1886 (set_attr "trap" "yes")])
1889 [(set (match_operand:SI 0 "memory_operand" "=m")
1890 (subreg:SI (fix:DI (match_operand:DF 1 "reg_or_fp0_operand" "fG")) 0))
1891 (clobber (match_scratch:DI 2 "=f"))]
1892 "TARGET_FP && alpha_tp != ALPHA_TP_INSN"
1894 [(set_attr "type" "fadd")
1895 (set_attr "trap" "yes")])
1898 [(set (match_operand:DI 0 "register_operand" "=&f")
1899 (fix:DI (match_operand:DF 1 "reg_or_fp0_operand" "fG")))]
1900 "TARGET_FP && alpha_tp == ALPHA_TP_INSN"
1902 [(set_attr "type" "fadd")
1903 (set_attr "trap" "yes")])
1905 (define_insn "fix_truncdfdi2"
1906 [(set (match_operand:DI 0 "register_operand" "=f")
1907 (fix:DI (match_operand:DF 1 "reg_or_fp0_operand" "fG")))]
1910 [(set_attr "type" "fadd")
1911 (set_attr "trap" "yes")])
1913 ;; Likewise between SFmode and SImode.
1916 [(set (match_operand:SI 0 "memory_operand" "")
1917 (subreg:SI (fix:DI (float_extend:DF
1918 (match_operand:SF 1 "reg_or_fp0_operand" ""))) 0))
1919 (clobber (match_scratch:DI 2 ""))
1920 (clobber (match_scratch:SI 3 ""))]
1921 "TARGET_FP && reload_completed"
1922 [(set (match_dup 2) (fix:DI (float_extend:DF (match_dup 1))))
1923 (set (match_dup 3) (unspec:SI [(match_dup 2)] 5))
1924 (set (match_dup 0) (match_dup 3))]
1928 [(set (match_operand:SI 0 "memory_operand" "")
1929 (subreg:SI (fix:DI (float_extend:DF
1930 (match_operand:SF 1 "reg_or_fp0_operand" ""))) 0))
1931 (clobber (match_scratch:DI 2 ""))]
1932 "TARGET_FP && reload_completed"
1933 [(set (match_dup 2) (fix:DI (float_extend:DF (match_dup 1))))
1934 (set (match_dup 3) (unspec:SI [(match_dup 2)] 5))
1935 (set (match_dup 0) (match_dup 3))]
1936 ;; Due to REG_CANNOT_CHANGE_SIZE issues, we cannot simply use SUBREG.
1937 "operands[3] = gen_rtx_REG (SImode, REGNO (operands[2]));")
1940 [(set (match_operand:SI 0 "memory_operand" "=m")
1941 (subreg:SI (fix:DI (float_extend:DF
1942 (match_operand:SF 1 "reg_or_fp0_operand" "fG"))) 0))
1943 (clobber (match_scratch:DI 2 "=&f"))
1944 (clobber (match_scratch:SI 3 "=&f"))]
1945 "TARGET_FP && alpha_tp == ALPHA_TP_INSN"
1947 [(set_attr "type" "fadd")
1948 (set_attr "trap" "yes")])
1951 [(set (match_operand:SI 0 "memory_operand" "=m")
1952 (subreg:SI (fix:DI (float_extend:DF
1953 (match_operand:SF 1 "reg_or_fp0_operand" "fG"))) 0))
1954 (clobber (match_scratch:DI 2 "=f"))]
1955 "TARGET_FP && alpha_tp != ALPHA_TP_INSN"
1957 [(set_attr "type" "fadd")
1958 (set_attr "trap" "yes")])
1961 [(set (match_operand:DI 0 "register_operand" "=&f")
1962 (fix:DI (float_extend:DF
1963 (match_operand:SF 1 "reg_or_fp0_operand" "fG"))))]
1964 "TARGET_FP && alpha_tp == ALPHA_TP_INSN"
1966 [(set_attr "type" "fadd")
1967 (set_attr "trap" "yes")])
1969 (define_insn "fix_truncsfdi2"
1970 [(set (match_operand:DI 0 "register_operand" "=f")
1971 (fix:DI (float_extend:DF
1972 (match_operand:SF 1 "reg_or_fp0_operand" "fG"))))]
1975 [(set_attr "type" "fadd")
1976 (set_attr "trap" "yes")])
1979 [(set (match_operand:SF 0 "register_operand" "=&f")
1980 (float:SF (match_operand:DI 1 "register_operand" "f")))]
1981 "TARGET_FP && alpha_tp == ALPHA_TP_INSN"
1983 [(set_attr "type" "fadd")
1984 (set_attr "trap" "yes")])
1986 (define_insn "floatdisf2"
1987 [(set (match_operand:SF 0 "register_operand" "=f")
1988 (float:SF (match_operand:DI 1 "register_operand" "f")))]
1991 [(set_attr "type" "fadd")
1992 (set_attr "trap" "yes")])
1995 [(set (match_operand:DF 0 "register_operand" "=&f")
1996 (float:DF (match_operand:DI 1 "register_operand" "f")))]
1997 "TARGET_FP && alpha_tp == ALPHA_TP_INSN"
1999 [(set_attr "type" "fadd")
2000 (set_attr "trap" "yes")])
2002 (define_insn "floatdidf2"
2003 [(set (match_operand:DF 0 "register_operand" "=f")
2004 (float:DF (match_operand:DI 1 "register_operand" "f")))]
2007 [(set_attr "type" "fadd")
2008 (set_attr "trap" "yes")])
2010 (define_expand "extendsfdf2"
2011 [(use (match_operand:DF 0 "register_operand" ""))
2012 (use (match_operand:SF 1 "nonimmediate_operand" ""))]
2016 if (alpha_tp == ALPHA_TP_INSN)
2017 emit_insn (gen_extendsfdf2_tp (operands[0],
2018 force_reg (SFmode, operands[1])));
2020 emit_insn (gen_extendsfdf2_no_tp (operands[0], operands[1]));
2025 (define_insn "extendsfdf2_tp"
2026 [(set (match_operand:DF 0 "register_operand" "=&f")
2027 (float_extend:DF (match_operand:SF 1 "register_operand" "f")))]
2028 "TARGET_FP && alpha_tp == ALPHA_TP_INSN"
2030 [(set_attr "type" "fadd")
2031 (set_attr "trap" "yes")])
2033 (define_insn "extendsfdf2_no_tp"
2034 [(set (match_operand:DF 0 "register_operand" "=f,f,m")
2035 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "f,m,f")))]
2036 "TARGET_FP && alpha_tp != ALPHA_TP_INSN"
2041 [(set_attr "type" "fcpys,fld,fst")
2042 (set_attr "trap" "yes")])
2045 [(set (match_operand:SF 0 "register_operand" "=&f")
2046 (float_truncate:SF (match_operand:DF 1 "reg_or_fp0_operand" "fG")))]
2047 "TARGET_FP && alpha_tp == ALPHA_TP_INSN"
2048 "cvt%-%,%)%& %R1,%0"
2049 [(set_attr "type" "fadd")
2050 (set_attr "trap" "yes")])
2052 (define_insn "truncdfsf2"
2053 [(set (match_operand:SF 0 "register_operand" "=f")
2054 (float_truncate:SF (match_operand:DF 1 "reg_or_fp0_operand" "fG")))]
2056 "cvt%-%,%)%& %R1,%0"
2057 [(set_attr "type" "fadd")
2058 (set_attr "trap" "yes")])
2061 [(set (match_operand:SF 0 "register_operand" "=&f")
2062 (div:SF (match_operand:SF 1 "reg_or_fp0_operand" "fG")
2063 (match_operand:SF 2 "reg_or_fp0_operand" "fG")))]
2064 "TARGET_FP && alpha_tp == ALPHA_TP_INSN"
2065 "div%,%)%& %R1,%R2,%0"
2066 [(set_attr "type" "fdiv")
2067 (set_attr "opsize" "si")
2068 (set_attr "trap" "yes")])
2070 (define_insn "divsf3"
2071 [(set (match_operand:SF 0 "register_operand" "=f")
2072 (div:SF (match_operand:SF 1 "reg_or_fp0_operand" "fG")
2073 (match_operand:SF 2 "reg_or_fp0_operand" "fG")))]
2075 "div%,%)%& %R1,%R2,%0"
2076 [(set_attr "type" "fdiv")
2077 (set_attr "opsize" "si")
2078 (set_attr "trap" "yes")])
2081 [(set (match_operand:DF 0 "register_operand" "=&f")
2082 (div:DF (match_operand:DF 1 "reg_or_fp0_operand" "fG")
2083 (match_operand:DF 2 "reg_or_fp0_operand" "fG")))]
2084 "TARGET_FP && alpha_tp == ALPHA_TP_INSN"
2085 "div%-%)%& %R1,%R2,%0"
2086 [(set_attr "type" "fdiv")
2087 (set_attr "trap" "yes")])
2089 (define_insn "divdf3"
2090 [(set (match_operand:DF 0 "register_operand" "=f")
2091 (div:DF (match_operand:DF 1 "reg_or_fp0_operand" "fG")
2092 (match_operand:DF 2 "reg_or_fp0_operand" "fG")))]
2094 "div%-%)%& %R1,%R2,%0"
2095 [(set_attr "type" "fdiv")
2096 (set_attr "trap" "yes")])
2099 [(set (match_operand:DF 0 "register_operand" "=f")
2100 (div:DF (float_extend:DF (match_operand:SF 1 "reg_or_fp0_operand" "fG"))
2101 (match_operand:DF 2 "reg_or_fp0_operand" "fG")))]
2102 "TARGET_FP && alpha_tp != ALPHA_TP_INSN"
2103 "div%-%)%& %R1,%R2,%0"
2104 [(set_attr "type" "fdiv")
2105 (set_attr "trap" "yes")])
2108 [(set (match_operand:DF 0 "register_operand" "=f")
2109 (div:DF (match_operand:DF 1 "reg_or_fp0_operand" "fG")
2111 (match_operand:SF 2 "reg_or_fp0_operand" "fG"))))]
2112 "TARGET_FP && alpha_tp != ALPHA_TP_INSN"
2113 "div%-%)%& %R1,%R2,%0"
2114 [(set_attr "type" "fdiv")
2115 (set_attr "trap" "yes")])
2118 [(set (match_operand:DF 0 "register_operand" "=f")
2119 (div:DF (float_extend:DF (match_operand:SF 1 "reg_or_fp0_operand" "fG"))
2120 (float_extend:DF (match_operand:SF 2 "reg_or_fp0_operand" "fG"))))]
2121 "TARGET_FP && alpha_tp != ALPHA_TP_INSN"
2122 "div%-%)%& %R1,%R2,%0"
2123 [(set_attr "type" "fdiv")
2124 (set_attr "trap" "yes")])
2127 [(set (match_operand:SF 0 "register_operand" "=&f")
2128 (mult:SF (match_operand:SF 1 "reg_or_fp0_operand" "%fG")
2129 (match_operand:SF 2 "reg_or_fp0_operand" "fG")))]
2130 "TARGET_FP && alpha_tp == ALPHA_TP_INSN"
2131 "mul%,%)%& %R1,%R2,%0"
2132 [(set_attr "type" "fmul")
2133 (set_attr "trap" "yes")])
2135 (define_insn "mulsf3"
2136 [(set (match_operand:SF 0 "register_operand" "=f")
2137 (mult:SF (match_operand:SF 1 "reg_or_fp0_operand" "%fG")
2138 (match_operand:SF 2 "reg_or_fp0_operand" "fG")))]
2140 "mul%,%)%& %R1,%R2,%0"
2141 [(set_attr "type" "fmul")
2142 (set_attr "trap" "yes")])
2145 [(set (match_operand:DF 0 "register_operand" "=&f")
2146 (mult:DF (match_operand:DF 1 "reg_or_fp0_operand" "%fG")
2147 (match_operand:DF 2 "reg_or_fp0_operand" "fG")))]
2148 "TARGET_FP && alpha_tp == ALPHA_TP_INSN"
2149 "mul%-%)%& %R1,%R2,%0"
2150 [(set_attr "type" "fmul")
2151 (set_attr "trap" "yes")])
2153 (define_insn "muldf3"
2154 [(set (match_operand:DF 0 "register_operand" "=f")
2155 (mult:DF (match_operand:DF 1 "reg_or_fp0_operand" "%fG")
2156 (match_operand:DF 2 "reg_or_fp0_operand" "fG")))]
2158 "mul%-%)%& %R1,%R2,%0"
2159 [(set_attr "type" "fmul")
2160 (set_attr "trap" "yes")])
2163 [(set (match_operand:DF 0 "register_operand" "=f")
2164 (mult:DF (float_extend:DF
2165 (match_operand:SF 1 "reg_or_fp0_operand" "fG"))
2166 (match_operand:DF 2 "reg_or_fp0_operand" "fG")))]
2167 "TARGET_FP && alpha_tp != ALPHA_TP_INSN"
2168 "mul%-%)%& %R1,%R2,%0"
2169 [(set_attr "type" "fmul")
2170 (set_attr "trap" "yes")])
2173 [(set (match_operand:DF 0 "register_operand" "=f")
2174 (mult:DF (float_extend:DF
2175 (match_operand:SF 1 "reg_or_fp0_operand" "%fG"))
2177 (match_operand:SF 2 "reg_or_fp0_operand" "fG"))))]
2178 "TARGET_FP && alpha_tp != ALPHA_TP_INSN"
2179 "mul%-%)%& %R1,%R2,%0"
2180 [(set_attr "type" "fmul")
2181 (set_attr "trap" "yes")])
2184 [(set (match_operand:SF 0 "register_operand" "=&f")
2185 (minus:SF (match_operand:SF 1 "reg_or_fp0_operand" "fG")
2186 (match_operand:SF 2 "reg_or_fp0_operand" "fG")))]
2187 "TARGET_FP && alpha_tp == ALPHA_TP_INSN"
2188 "sub%,%)%& %R1,%R2,%0"
2189 [(set_attr "type" "fadd")
2190 (set_attr "trap" "yes")])
2192 (define_insn "subsf3"
2193 [(set (match_operand:SF 0 "register_operand" "=f")
2194 (minus:SF (match_operand:SF 1 "reg_or_fp0_operand" "fG")
2195 (match_operand:SF 2 "reg_or_fp0_operand" "fG")))]
2197 "sub%,%)%& %R1,%R2,%0"
2198 [(set_attr "type" "fadd")
2199 (set_attr "trap" "yes")])
2202 [(set (match_operand:DF 0 "register_operand" "=&f")
2203 (minus:DF (match_operand:DF 1 "reg_or_fp0_operand" "fG")
2204 (match_operand:DF 2 "reg_or_fp0_operand" "fG")))]
2205 "TARGET_FP && alpha_tp == ALPHA_TP_INSN"
2206 "sub%-%)%& %R1,%R2,%0"
2207 [(set_attr "type" "fadd")
2208 (set_attr "trap" "yes")])
2210 (define_insn "subdf3"
2211 [(set (match_operand:DF 0 "register_operand" "=f")
2212 (minus:DF (match_operand:DF 1 "reg_or_fp0_operand" "fG")
2213 (match_operand:DF 2 "reg_or_fp0_operand" "fG")))]
2215 "sub%-%)%& %R1,%R2,%0"
2216 [(set_attr "type" "fadd")
2217 (set_attr "trap" "yes")])
2220 [(set (match_operand:DF 0 "register_operand" "=f")
2221 (minus:DF (float_extend:DF
2222 (match_operand:SF 1 "reg_or_fp0_operand" "fG"))
2223 (match_operand:DF 2 "reg_or_fp0_operand" "fG")))]
2224 "TARGET_FP && alpha_tp != ALPHA_TP_INSN"
2225 "sub%-%)%& %R1,%R2,%0"
2226 [(set_attr "type" "fadd")
2227 (set_attr "trap" "yes")])
2230 [(set (match_operand:DF 0 "register_operand" "=f")
2231 (minus:DF (match_operand:DF 1 "reg_or_fp0_operand" "fG")
2233 (match_operand:SF 2 "reg_or_fp0_operand" "fG"))))]
2234 "TARGET_FP && alpha_tp != ALPHA_TP_INSN"
2235 "sub%-%)%& %R1,%R2,%0"
2236 [(set_attr "type" "fadd")
2237 (set_attr "trap" "yes")])
2240 [(set (match_operand:DF 0 "register_operand" "=f")
2241 (minus:DF (float_extend:DF
2242 (match_operand:SF 1 "reg_or_fp0_operand" "fG"))
2244 (match_operand:SF 2 "reg_or_fp0_operand" "fG"))))]
2245 "TARGET_FP && alpha_tp != ALPHA_TP_INSN"
2246 "sub%-%)%& %R1,%R2,%0"
2247 [(set_attr "type" "fadd")
2248 (set_attr "trap" "yes")])
2251 [(set (match_operand:SF 0 "register_operand" "=&f")
2252 (sqrt:SF (match_operand:SF 1 "reg_or_fp0_operand" "fG")))]
2253 "TARGET_FP && TARGET_CIX && alpha_tp == ALPHA_TP_INSN"
2255 [(set_attr "type" "fsqrt")
2256 (set_attr "opsize" "si")
2257 (set_attr "trap" "yes")])
2259 (define_insn "sqrtsf2"
2260 [(set (match_operand:SF 0 "register_operand" "=f")
2261 (sqrt:SF (match_operand:SF 1 "reg_or_fp0_operand" "fG")))]
2262 "TARGET_FP && TARGET_CIX"
2264 [(set_attr "type" "fsqrt")
2265 (set_attr "opsize" "si")
2266 (set_attr "trap" "yes")])
2269 [(set (match_operand:DF 0 "register_operand" "=&f")
2270 (sqrt:DF (match_operand:DF 1 "reg_or_fp0_operand" "fG")))]
2271 "TARGET_FP && TARGET_CIX && alpha_tp == ALPHA_TP_INSN"
2273 [(set_attr "type" "fsqrt")
2274 (set_attr "trap" "yes")])
2276 (define_insn "sqrtdf2"
2277 [(set (match_operand:DF 0 "register_operand" "=f")
2278 (sqrt:DF (match_operand:DF 1 "reg_or_fp0_operand" "fG")))]
2279 "TARGET_FP && TARGET_CIX"
2281 [(set_attr "type" "fsqrt")
2282 (set_attr "trap" "yes")])
2284 ;; Next are all the integer comparisons, and conditional moves and branches
2285 ;; and some of the related define_expand's and define_split's.
2288 [(set (match_operand:DI 0 "register_operand" "=r")
2289 (match_operator:DI 1 "alpha_comparison_operator"
2290 [(match_operand:DI 2 "reg_or_0_operand" "rJ")
2291 (match_operand:DI 3 "reg_or_8bit_operand" "rI")]))]
2294 [(set_attr "type" "icmp")])
2297 [(set (match_operand:DI 0 "register_operand" "=r")
2298 (match_operator:DI 1 "alpha_swapped_comparison_operator"
2299 [(match_operand:DI 2 "reg_or_8bit_operand" "rI")
2300 (match_operand:DI 3 "reg_or_0_operand" "rJ")]))]
2303 [(set_attr "type" "icmp")])
2305 ;; This pattern exists so conditional moves of SImode values are handled.
2306 ;; Comparisons are still done in DImode though.
2309 [(set (match_operand:SI 0 "register_operand" "=r,r,r,r")
2311 (match_operator 2 "signed_comparison_operator"
2312 [(match_operand:DI 3 "reg_or_0_operand" "rJ,rJ,J,J")
2313 (match_operand:DI 4 "reg_or_0_operand" "J,J,rJ,rJ")])
2314 (match_operand:SI 1 "reg_or_8bit_operand" "rI,0,rI,0")
2315 (match_operand:SI 5 "reg_or_8bit_operand" "0,rI,0,rI")))]
2316 "operands[3] == const0_rtx || operands[4] == const0_rtx"
2322 [(set_attr "type" "icmov")])
2325 [(set (match_operand:DI 0 "register_operand" "=r,r,r,r")
2327 (match_operator 2 "signed_comparison_operator"
2328 [(match_operand:DI 3 "reg_or_0_operand" "rJ,rJ,J,J")
2329 (match_operand:DI 4 "reg_or_0_operand" "J,J,rJ,rJ")])
2330 (match_operand:DI 1 "reg_or_8bit_operand" "rI,0,rI,0")
2331 (match_operand:DI 5 "reg_or_8bit_operand" "0,rI,0,rI")))]
2332 "operands[3] == const0_rtx || operands[4] == const0_rtx"
2338 [(set_attr "type" "icmov")])
2341 [(set (match_operand:DI 0 "register_operand" "=r,r")
2343 (eq (zero_extract:DI (match_operand:DI 2 "reg_or_0_operand" "rJ,rJ")
2347 (match_operand:DI 1 "reg_or_8bit_operand" "rI,0")
2348 (match_operand:DI 3 "reg_or_8bit_operand" "0,rI")))]
2353 [(set_attr "type" "icmov")])
2356 [(set (match_operand:DI 0 "register_operand" "=r,r")
2358 (ne (zero_extract:DI (match_operand:DI 2 "reg_or_0_operand" "rJ,rJ")
2362 (match_operand:DI 1 "reg_or_8bit_operand" "rI,0")
2363 (match_operand:DI 3 "reg_or_8bit_operand" "0,rI")))]
2368 [(set_attr "type" "icmov")])
2370 ;; This form is added since combine thinks that an IF_THEN_ELSE with both
2371 ;; arms constant is a single insn, so it won't try to form it if combine
2372 ;; knows they are really two insns. This occurs in divides by powers
2376 [(set (match_operand:DI 0 "register_operand" "=r")
2378 (match_operator 2 "signed_comparison_operator"
2379 [(match_operand:DI 3 "reg_or_0_operand" "rJ")
2381 (plus:DI (match_dup 0)
2382 (match_operand:DI 1 "reg_or_8bit_operand" "rI"))
2384 (clobber (match_scratch:DI 4 "=&r"))]
2386 "addq %0,%1,%4\;cmov%C2 %r3,%4,%0"
2387 [(set_attr "type" "icmov")
2388 (set_attr "length" "8")])
2391 [(set (match_operand:DI 0 "register_operand" "")
2393 (match_operator 2 "signed_comparison_operator"
2394 [(match_operand:DI 3 "reg_or_0_operand" "")
2396 (plus:DI (match_dup 0)
2397 (match_operand:DI 1 "reg_or_8bit_operand" ""))
2399 (clobber (match_operand:DI 4 "register_operand" ""))]
2401 [(set (match_dup 4) (plus:DI (match_dup 0) (match_dup 1)))
2402 (set (match_dup 0) (if_then_else:DI (match_op_dup 2
2405 (match_dup 4) (match_dup 0)))]
2410 [(set (match_operand:DI 0 "register_operand" "")
2412 (match_operator 1 "comparison_operator"
2413 [(zero_extract:DI (match_operand:DI 2 "register_operand" "")
2415 (match_operand:DI 3 "const_int_operand" ""))
2417 (match_operand:DI 4 "reg_or_8bit_operand" "")
2418 (match_operand:DI 5 "reg_or_8bit_operand" "")))
2419 (clobber (match_operand:DI 6 "register_operand" ""))])]
2420 "INTVAL (operands[3]) != 0"
2422 (lshiftrt:DI (match_dup 2) (match_dup 3)))
2424 (if_then_else:DI (match_op_dup 1
2425 [(zero_extract:DI (match_dup 6)
2433 ;; For ABS, we have two choices, depending on whether the input and output
2434 ;; registers are the same or not.
2435 (define_expand "absdi2"
2436 [(set (match_operand:DI 0 "register_operand" "")
2437 (abs:DI (match_operand:DI 1 "register_operand" "")))]
2440 { if (rtx_equal_p (operands[0], operands[1]))
2441 emit_insn (gen_absdi2_same (operands[0], gen_reg_rtx (DImode)));
2443 emit_insn (gen_absdi2_diff (operands[0], operands[1]));
2448 (define_expand "absdi2_same"
2449 [(set (match_operand:DI 1 "register_operand" "")
2450 (neg:DI (match_operand:DI 0 "register_operand" "")))
2452 (if_then_else:DI (ge (match_dup 0) (const_int 0))
2458 (define_expand "absdi2_diff"
2459 [(set (match_operand:DI 0 "register_operand" "")
2460 (neg:DI (match_operand:DI 1 "register_operand" "")))
2462 (if_then_else:DI (lt (match_dup 1) (const_int 0))
2469 [(set (match_operand:DI 0 "register_operand" "")
2470 (abs:DI (match_dup 0)))
2471 (clobber (match_operand:DI 2 "register_operand" ""))]
2473 [(set (match_dup 1) (neg:DI (match_dup 0)))
2474 (set (match_dup 0) (if_then_else:DI (ge (match_dup 0) (const_int 0))
2475 (match_dup 0) (match_dup 1)))]
2479 [(set (match_operand:DI 0 "register_operand" "")
2480 (abs:DI (match_operand:DI 1 "register_operand" "")))]
2481 "! rtx_equal_p (operands[0], operands[1])"
2482 [(set (match_dup 0) (neg:DI (match_dup 1)))
2483 (set (match_dup 0) (if_then_else:DI (lt (match_dup 1) (const_int 0))
2484 (match_dup 0) (match_dup 1)))]
2488 [(set (match_operand:DI 0 "register_operand" "")
2489 (neg:DI (abs:DI (match_dup 0))))
2490 (clobber (match_operand:DI 2 "register_operand" ""))]
2492 [(set (match_dup 1) (neg:DI (match_dup 0)))
2493 (set (match_dup 0) (if_then_else:DI (le (match_dup 0) (const_int 0))
2494 (match_dup 0) (match_dup 1)))]
2498 [(set (match_operand:DI 0 "register_operand" "")
2499 (neg:DI (abs:DI (match_operand:DI 1 "register_operand" ""))))]
2500 "! rtx_equal_p (operands[0], operands[1])"
2501 [(set (match_dup 0) (neg:DI (match_dup 1)))
2502 (set (match_dup 0) (if_then_else:DI (gt (match_dup 1) (const_int 0))
2503 (match_dup 0) (match_dup 1)))]
2506 (define_insn "sminqi3"
2507 [(set (match_operand:QI 0 "register_operand" "=r")
2508 (smin:QI (match_operand:QI 1 "reg_or_0_operand" "%rJ")
2509 (match_operand:QI 2 "reg_or_8bit_operand" "rI")))]
2512 [(set_attr "type" "mvi")])
2514 (define_insn "uminqi3"
2515 [(set (match_operand:QI 0 "register_operand" "=r")
2516 (umin:QI (match_operand:QI 1 "reg_or_0_operand" "%rJ")
2517 (match_operand:QI 2 "reg_or_8bit_operand" "rI")))]
2520 [(set_attr "type" "mvi")])
2522 (define_insn "smaxqi3"
2523 [(set (match_operand:QI 0 "register_operand" "=r")
2524 (smax:QI (match_operand:QI 1 "reg_or_0_operand" "%rJ")
2525 (match_operand:QI 2 "reg_or_8bit_operand" "rI")))]
2528 [(set_attr "type" "mvi")])
2530 (define_insn "umaxqi3"
2531 [(set (match_operand:QI 0 "register_operand" "=r")
2532 (umax:QI (match_operand:QI 1 "reg_or_0_operand" "%rJ")
2533 (match_operand:QI 2 "reg_or_8bit_operand" "rI")))]
2536 [(set_attr "type" "mvi")])
2538 (define_insn "sminhi3"
2539 [(set (match_operand:HI 0 "register_operand" "=r")
2540 (smin:HI (match_operand:HI 1 "reg_or_0_operand" "%rJ")
2541 (match_operand:HI 2 "reg_or_8bit_operand" "rI")))]
2544 [(set_attr "type" "mvi")])
2546 (define_insn "uminhi3"
2547 [(set (match_operand:HI 0 "register_operand" "=r")
2548 (umin:HI (match_operand:HI 1 "reg_or_0_operand" "%rJ")
2549 (match_operand:HI 2 "reg_or_8bit_operand" "rI")))]
2552 [(set_attr "type" "mvi")])
2554 (define_insn "smaxhi3"
2555 [(set (match_operand:HI 0 "register_operand" "=r")
2556 (smax:HI (match_operand:HI 1 "reg_or_0_operand" "%rJ")
2557 (match_operand:HI 2 "reg_or_8bit_operand" "rI")))]
2560 [(set_attr "type" "mvi")])
2562 (define_insn "umaxhi3"
2563 [(set (match_operand:HI 0 "register_operand" "=r")
2564 (umax:HI (match_operand:HI 1 "reg_or_0_operand" "%rJ")
2565 (match_operand:HI 2 "reg_or_8bit_operand" "rI")))]
2568 [(set_attr "type" "shift")])
2570 (define_expand "smaxdi3"
2572 (le:DI (match_operand:DI 1 "reg_or_0_operand" "")
2573 (match_operand:DI 2 "reg_or_8bit_operand" "")))
2574 (set (match_operand:DI 0 "register_operand" "")
2575 (if_then_else:DI (eq (match_dup 3) (const_int 0))
2576 (match_dup 1) (match_dup 2)))]
2579 { operands[3] = gen_reg_rtx (DImode);
2583 [(set (match_operand:DI 0 "register_operand" "")
2584 (smax:DI (match_operand:DI 1 "reg_or_0_operand" "")
2585 (match_operand:DI 2 "reg_or_8bit_operand" "")))
2586 (clobber (match_operand:DI 3 "register_operand" ""))]
2587 "operands[2] != const0_rtx"
2588 [(set (match_dup 3) (le:DI (match_dup 1) (match_dup 2)))
2589 (set (match_dup 0) (if_then_else:DI (eq (match_dup 3) (const_int 0))
2590 (match_dup 1) (match_dup 2)))]
2594 [(set (match_operand:DI 0 "register_operand" "=r")
2595 (smax:DI (match_operand:DI 1 "register_operand" "0")
2599 [(set_attr "type" "icmov")])
2601 (define_expand "smindi3"
2603 (lt:DI (match_operand:DI 1 "reg_or_0_operand" "")
2604 (match_operand:DI 2 "reg_or_8bit_operand" "")))
2605 (set (match_operand:DI 0 "register_operand" "")
2606 (if_then_else:DI (ne (match_dup 3) (const_int 0))
2607 (match_dup 1) (match_dup 2)))]
2610 { operands[3] = gen_reg_rtx (DImode);
2614 [(set (match_operand:DI 0 "register_operand" "")
2615 (smin:DI (match_operand:DI 1 "reg_or_0_operand" "")
2616 (match_operand:DI 2 "reg_or_8bit_operand" "")))
2617 (clobber (match_operand:DI 3 "register_operand" ""))]
2618 "operands[2] != const0_rtx"
2619 [(set (match_dup 3) (lt:DI (match_dup 1) (match_dup 2)))
2620 (set (match_dup 0) (if_then_else:DI (ne (match_dup 3) (const_int 0))
2621 (match_dup 1) (match_dup 2)))]
2625 [(set (match_operand:DI 0 "register_operand" "=r")
2626 (smin:DI (match_operand:DI 1 "register_operand" "0")
2630 [(set_attr "type" "icmov")])
2632 (define_expand "umaxdi3"
2634 (leu:DI (match_operand:DI 1 "reg_or_0_operand" "")
2635 (match_operand:DI 2 "reg_or_8bit_operand" "")))
2636 (set (match_operand:DI 0 "register_operand" "")
2637 (if_then_else:DI (eq (match_dup 3) (const_int 0))
2638 (match_dup 1) (match_dup 2)))]
2641 { operands[3] = gen_reg_rtx (DImode);
2645 [(set (match_operand:DI 0 "register_operand" "")
2646 (umax:DI (match_operand:DI 1 "reg_or_0_operand" "")
2647 (match_operand:DI 2 "reg_or_8bit_operand" "")))
2648 (clobber (match_operand:DI 3 "register_operand" ""))]
2649 "operands[2] != const0_rtx"
2650 [(set (match_dup 3) (leu:DI (match_dup 1) (match_dup 2)))
2651 (set (match_dup 0) (if_then_else:DI (eq (match_dup 3) (const_int 0))
2652 (match_dup 1) (match_dup 2)))]
2655 (define_expand "umindi3"
2657 (ltu:DI (match_operand:DI 1 "reg_or_0_operand" "")
2658 (match_operand:DI 2 "reg_or_8bit_operand" "")))
2659 (set (match_operand:DI 0 "register_operand" "")
2660 (if_then_else:DI (ne (match_dup 3) (const_int 0))
2661 (match_dup 1) (match_dup 2)))]
2664 { operands[3] = gen_reg_rtx (DImode);
2668 [(set (match_operand:DI 0 "register_operand" "")
2669 (umin:DI (match_operand:DI 1 "reg_or_0_operand" "")
2670 (match_operand:DI 2 "reg_or_8bit_operand" "")))
2671 (clobber (match_operand:DI 3 "register_operand" ""))]
2672 "operands[2] != const0_rtx"
2673 [(set (match_dup 3) (ltu:DI (match_dup 1) (match_dup 2)))
2674 (set (match_dup 0) (if_then_else:DI (ne (match_dup 3) (const_int 0))
2675 (match_dup 1) (match_dup 2)))]
2681 (match_operator 1 "signed_comparison_operator"
2682 [(match_operand:DI 2 "reg_or_0_operand" "rJ")
2684 (label_ref (match_operand 0 "" ""))
2688 [(set_attr "type" "ibr")])
2693 (match_operator 1 "signed_comparison_operator"
2695 (match_operand:DI 2 "register_operand" "r")])
2696 (label_ref (match_operand 0 "" ""))
2700 [(set_attr "type" "ibr")])
2705 (ne (zero_extract:DI (match_operand:DI 1 "reg_or_0_operand" "rJ")
2709 (label_ref (match_operand 0 "" ""))
2713 [(set_attr "type" "ibr")])
2718 (eq (zero_extract:DI (match_operand:DI 1 "reg_or_0_operand" "rJ")
2722 (label_ref (match_operand 0 "" ""))
2726 [(set_attr "type" "ibr")])
2732 (match_operator 1 "comparison_operator"
2733 [(zero_extract:DI (match_operand:DI 2 "register_operand" "")
2735 (match_operand:DI 3 "const_int_operand" ""))
2737 (label_ref (match_operand 0 "" ""))
2739 (clobber (match_operand:DI 4 "register_operand" ""))])]
2740 "INTVAL (operands[3]) != 0"
2742 (lshiftrt:DI (match_dup 2) (match_dup 3)))
2744 (if_then_else (match_op_dup 1
2745 [(zero_extract:DI (match_dup 4)
2749 (label_ref (match_dup 0))
2753 ;; The following are the corresponding floating-point insns. Recall
2754 ;; we need to have variants that expand the arguments from SF mode
2758 [(set (match_operand:DF 0 "register_operand" "=&f")
2759 (match_operator:DF 1 "alpha_comparison_operator"
2760 [(match_operand:DF 2 "reg_or_fp0_operand" "fG")
2761 (match_operand:DF 3 "reg_or_fp0_operand" "fG")]))]
2762 "TARGET_FP && alpha_tp == ALPHA_TP_INSN"
2763 "cmp%-%C1%' %R2,%R3,%0"
2764 [(set_attr "type" "fadd")
2765 (set_attr "trap" "yes")])
2768 [(set (match_operand:DF 0 "register_operand" "=f")
2769 (match_operator:DF 1 "alpha_comparison_operator"
2770 [(match_operand:DF 2 "reg_or_fp0_operand" "fG")
2771 (match_operand:DF 3 "reg_or_fp0_operand" "fG")]))]
2772 "TARGET_FP && alpha_tp != ALPHA_TP_INSN"
2773 "cmp%-%C1%' %R2,%R3,%0"
2774 [(set_attr "type" "fadd")
2775 (set_attr "trap" "yes")])
2778 [(set (match_operand:DF 0 "register_operand" "=&f")
2779 (match_operator:DF 1 "alpha_comparison_operator"
2781 (match_operand:SF 2 "reg_or_fp0_operand" "fG"))
2782 (match_operand:DF 3 "reg_or_fp0_operand" "fG")]))]
2783 "TARGET_FP && alpha_tp == ALPHA_TP_INSN"
2784 "cmp%-%C1%' %R2,%R3,%0"
2785 [(set_attr "type" "fadd")
2786 (set_attr "trap" "yes")])
2789 [(set (match_operand:DF 0 "register_operand" "=f")
2790 (match_operator:DF 1 "alpha_comparison_operator"
2792 (match_operand:SF 2 "reg_or_fp0_operand" "fG"))
2793 (match_operand:DF 3 "reg_or_fp0_operand" "fG")]))]
2794 "TARGET_FP && alpha_tp != ALPHA_TP_INSN"
2795 "cmp%-%C1%' %R2,%R3,%0"
2796 [(set_attr "type" "fadd")
2797 (set_attr "trap" "yes")])
2800 [(set (match_operand:DF 0 "register_operand" "=&f")
2801 (match_operator:DF 1 "alpha_comparison_operator"
2802 [(match_operand:DF 2 "reg_or_fp0_operand" "fG")
2804 (match_operand:SF 3 "reg_or_fp0_operand" "fG"))]))]
2805 "TARGET_FP && alpha_tp == ALPHA_TP_INSN"
2806 "cmp%-%C1%' %R2,%R3,%0"
2807 [(set_attr "type" "fadd")
2808 (set_attr "trap" "yes")])
2811 [(set (match_operand:DF 0 "register_operand" "=f")
2812 (match_operator:DF 1 "alpha_comparison_operator"
2813 [(match_operand:DF 2 "reg_or_fp0_operand" "fG")
2815 (match_operand:SF 3 "reg_or_fp0_operand" "fG"))]))]
2816 "TARGET_FP && alpha_tp != ALPHA_TP_INSN"
2817 "cmp%-%C1%' %R2,%R3,%0"
2818 [(set_attr "type" "fadd")
2819 (set_attr "trap" "yes")])
2822 [(set (match_operand:DF 0 "register_operand" "=&f")
2823 (match_operator:DF 1 "alpha_comparison_operator"
2825 (match_operand:SF 2 "reg_or_fp0_operand" "fG"))
2827 (match_operand:SF 3 "reg_or_fp0_operand" "fG"))]))]
2828 "TARGET_FP && alpha_tp == ALPHA_TP_INSN"
2829 "cmp%-%C1%' %R2,%R3,%0"
2830 [(set_attr "type" "fadd")
2831 (set_attr "trap" "yes")])
2834 [(set (match_operand:DF 0 "register_operand" "=f")
2835 (match_operator:DF 1 "alpha_comparison_operator"
2837 (match_operand:SF 2 "reg_or_fp0_operand" "fG"))
2839 (match_operand:SF 3 "reg_or_fp0_operand" "fG"))]))]
2840 "TARGET_FP && alpha_tp != ALPHA_TP_INSN"
2841 "cmp%-%C1%' %R2,%R3,%0"
2842 [(set_attr "type" "fadd")
2843 (set_attr "trap" "yes")])
2846 [(set (match_operand:DF 0 "register_operand" "=f,f")
2848 (match_operator 3 "signed_comparison_operator"
2849 [(match_operand:DF 4 "reg_or_fp0_operand" "fG,fG")
2850 (match_operand:DF 2 "fp0_operand" "G,G")])
2851 (match_operand:DF 1 "reg_or_fp0_operand" "fG,0")
2852 (match_operand:DF 5 "reg_or_fp0_operand" "0,fG")))]
2856 fcmov%D3 %R4,%R5,%0"
2857 [(set_attr "type" "fcmov")])
2860 [(set (match_operand:SF 0 "register_operand" "=f,f")
2862 (match_operator 3 "signed_comparison_operator"
2863 [(match_operand:DF 4 "reg_or_fp0_operand" "fG,fG")
2864 (match_operand:DF 2 "fp0_operand" "G,G")])
2865 (match_operand:SF 1 "reg_or_fp0_operand" "fG,0")
2866 (match_operand:SF 5 "reg_or_fp0_operand" "0,fG")))]
2870 fcmov%D3 %R4,%R5,%0"
2871 [(set_attr "type" "fcmov")])
2874 [(set (match_operand:DF 0 "register_operand" "=f,f")
2876 (match_operator 3 "signed_comparison_operator"
2877 [(match_operand:DF 4 "reg_or_fp0_operand" "fG,fG")
2878 (match_operand:DF 2 "fp0_operand" "G,G")])
2879 (float_extend:DF (match_operand:SF 1 "reg_or_fp0_operand" "fG,0"))
2880 (match_operand:DF 5 "reg_or_fp0_operand" "0,fG")))]
2884 fcmov%D3 %R4,%R5,%0"
2885 [(set_attr "type" "fcmov")])
2888 [(set (match_operand:DF 0 "register_operand" "=f,f")
2890 (match_operator 3 "signed_comparison_operator"
2892 (match_operand:SF 4 "reg_or_fp0_operand" "fG,fG"))
2893 (match_operand:DF 2 "fp0_operand" "G,G")])
2894 (match_operand:DF 1 "reg_or_fp0_operand" "fG,0")
2895 (match_operand:DF 5 "reg_or_fp0_operand" "0,fG")))]
2899 fcmov%D3 %R4,%R5,%0"
2900 [(set_attr "type" "fcmov")])
2903 [(set (match_operand:SF 0 "register_operand" "=f,f")
2905 (match_operator 3 "signed_comparison_operator"
2907 (match_operand:SF 4 "reg_or_fp0_operand" "fG,fG"))
2908 (match_operand:DF 2 "fp0_operand" "G,G")])
2909 (match_operand:SF 1 "reg_or_fp0_operand" "fG,0")
2910 (match_operand:SF 5 "reg_or_fp0_operand" "0,fG")))]
2914 fcmov%D3 %R4,%R5,%0"
2915 [(set_attr "type" "fcmov")])
2918 [(set (match_operand:DF 0 "register_operand" "=f,f")
2920 (match_operator 3 "signed_comparison_operator"
2922 (match_operand:SF 4 "reg_or_fp0_operand" "fG,fG"))
2923 (match_operand:DF 2 "fp0_operand" "G,G")])
2924 (float_extend:DF (match_operand:SF 1 "reg_or_fp0_operand" "fG,0"))
2925 (match_operand:DF 5 "reg_or_fp0_operand" "0,fG")))]
2929 fcmov%D3 %R4,%R5,%0"
2930 [(set_attr "type" "fcmov")])
2932 (define_expand "maxdf3"
2934 (le:DF (match_operand:DF 1 "reg_or_fp0_operand" "")
2935 (match_operand:DF 2 "reg_or_fp0_operand" "")))
2936 (set (match_operand:DF 0 "register_operand" "")
2937 (if_then_else:DF (eq (match_dup 3) (match_dup 4))
2938 (match_dup 1) (match_dup 2)))]
2941 { operands[3] = gen_reg_rtx (DFmode);
2942 operands[4] = CONST0_RTX (DFmode);
2945 (define_expand "mindf3"
2947 (lt:DF (match_operand:DF 1 "reg_or_fp0_operand" "")
2948 (match_operand:DF 2 "reg_or_fp0_operand" "")))
2949 (set (match_operand:DF 0 "register_operand" "")
2950 (if_then_else:DF (ne (match_dup 3) (match_dup 4))
2951 (match_dup 1) (match_dup 2)))]
2954 { operands[3] = gen_reg_rtx (DFmode);
2955 operands[4] = CONST0_RTX (DFmode);
2958 (define_expand "maxsf3"
2960 (le:DF (float_extend:DF (match_operand:SF 1 "reg_or_fp0_operand" ""))
2961 (float_extend:DF (match_operand:SF 2 "reg_or_fp0_operand" ""))))
2962 (set (match_operand:SF 0 "register_operand" "")
2963 (if_then_else:SF (eq (match_dup 3) (match_dup 4))
2964 (match_dup 1) (match_dup 2)))]
2967 { operands[3] = gen_reg_rtx (DFmode);
2968 operands[4] = CONST0_RTX (DFmode);
2971 (define_expand "minsf3"
2973 (lt:DF (float_extend:DF (match_operand:SF 1 "reg_or_fp0_operand" ""))
2974 (float_extend:DF (match_operand:SF 2 "reg_or_fp0_operand" ""))))
2975 (set (match_operand:SF 0 "register_operand" "")
2976 (if_then_else:SF (ne (match_dup 3) (match_dup 4))
2977 (match_dup 1) (match_dup 2)))]
2980 { operands[3] = gen_reg_rtx (DFmode);
2981 operands[4] = CONST0_RTX (DFmode);
2987 (match_operator 1 "signed_comparison_operator"
2988 [(match_operand:DF 2 "reg_or_fp0_operand" "fG")
2989 (match_operand:DF 3 "fp0_operand" "G")])
2990 (label_ref (match_operand 0 "" ""))
2994 [(set_attr "type" "fbr")])
2999 (match_operator 1 "signed_comparison_operator"
3001 (match_operand:SF 2 "reg_or_fp0_operand" "fG"))
3002 (match_operand:DF 3 "fp0_operand" "G")])
3003 (label_ref (match_operand 0 "" ""))
3007 [(set_attr "type" "fbr")])
3009 ;; These are the main define_expand's used to make conditional branches
3012 (define_expand "cmpdf"
3013 [(set (cc0) (compare (match_operand:DF 0 "reg_or_fp0_operand" "")
3014 (match_operand:DF 1 "reg_or_fp0_operand" "")))]
3018 alpha_compare_op0 = operands[0];
3019 alpha_compare_op1 = operands[1];
3020 alpha_compare_fp_p = 1;
3024 (define_expand "cmpdi"
3025 [(set (cc0) (compare (match_operand:DI 0 "reg_or_0_operand" "")
3026 (match_operand:DI 1 "reg_or_8bit_operand" "")))]
3030 alpha_compare_op0 = operands[0];
3031 alpha_compare_op1 = operands[1];
3032 alpha_compare_fp_p = 0;
3036 (define_expand "beq"
3038 (if_then_else (match_dup 1)
3039 (label_ref (match_operand 0 "" ""))
3042 "{ operands[1] = alpha_emit_conditional_branch (EQ); }")
3044 (define_expand "bne"
3046 (if_then_else (match_dup 1)
3047 (label_ref (match_operand 0 "" ""))
3050 "{ operands[1] = alpha_emit_conditional_branch (NE); }")
3052 (define_expand "blt"
3054 (if_then_else (match_dup 1)
3055 (label_ref (match_operand 0 "" ""))
3058 "{ operands[1] = alpha_emit_conditional_branch (LT); }")
3060 (define_expand "ble"
3062 (if_then_else (match_dup 1)
3063 (label_ref (match_operand 0 "" ""))
3066 "{ operands[1] = alpha_emit_conditional_branch (LE); }")
3068 (define_expand "bgt"
3070 (if_then_else (match_dup 1)
3071 (label_ref (match_operand 0 "" ""))
3074 "{ operands[1] = alpha_emit_conditional_branch (GT); }")
3076 (define_expand "bge"
3078 (if_then_else (match_dup 1)
3079 (label_ref (match_operand 0 "" ""))
3082 "{ operands[1] = alpha_emit_conditional_branch (GE); }")
3084 (define_expand "bltu"
3086 (if_then_else (match_dup 1)
3087 (label_ref (match_operand 0 "" ""))
3090 "{ operands[1] = alpha_emit_conditional_branch (LTU); }")
3092 (define_expand "bleu"
3094 (if_then_else (match_dup 1)
3095 (label_ref (match_operand 0 "" ""))
3098 "{ operands[1] = alpha_emit_conditional_branch (LEU); }")
3100 (define_expand "bgtu"
3102 (if_then_else (match_dup 1)
3103 (label_ref (match_operand 0 "" ""))
3106 "{ operands[1] = alpha_emit_conditional_branch (GTU); }")
3108 (define_expand "bgeu"
3110 (if_then_else (match_dup 1)
3111 (label_ref (match_operand 0 "" ""))
3114 "{ operands[1] = alpha_emit_conditional_branch (GEU); }")
3116 (define_expand "seq"
3117 [(set (match_operand:DI 0 "register_operand" "")
3122 if (alpha_compare_fp_p)
3125 operands[1] = gen_rtx_EQ (DImode, alpha_compare_op0, alpha_compare_op1);
3128 (define_expand "sne"
3129 [(set (match_operand:DI 0 "register_operand" "")
3131 (set (match_dup 0) (xor:DI (match_dup 0) (const_int 1)))]
3135 if (alpha_compare_fp_p)
3138 operands[1] = gen_rtx_EQ (DImode, alpha_compare_op0, alpha_compare_op1);
3141 (define_expand "slt"
3142 [(set (match_operand:DI 0 "register_operand" "")
3147 if (alpha_compare_fp_p)
3150 operands[1] = gen_rtx_LT (DImode, alpha_compare_op0, alpha_compare_op1);
3153 (define_expand "sle"
3154 [(set (match_operand:DI 0 "register_operand" "")
3159 if (alpha_compare_fp_p)
3162 operands[1] = gen_rtx_LE (DImode, alpha_compare_op0, alpha_compare_op1);
3165 (define_expand "sgt"
3166 [(set (match_operand:DI 0 "register_operand" "")
3171 if (alpha_compare_fp_p)
3174 operands[1] = gen_rtx_LT (DImode, force_reg (DImode, alpha_compare_op1),
3178 (define_expand "sge"
3179 [(set (match_operand:DI 0 "register_operand" "")
3184 if (alpha_compare_fp_p)
3187 operands[1] = gen_rtx_LE (DImode, force_reg (DImode, alpha_compare_op1),
3191 (define_expand "sltu"
3192 [(set (match_operand:DI 0 "register_operand" "")
3197 if (alpha_compare_fp_p)
3200 operands[1] = gen_rtx_LTU (DImode, alpha_compare_op0, alpha_compare_op1);
3203 (define_expand "sleu"
3204 [(set (match_operand:DI 0 "register_operand" "")
3209 if (alpha_compare_fp_p)
3212 operands[1] = gen_rtx_LEU (DImode, alpha_compare_op0, alpha_compare_op1);
3215 (define_expand "sgtu"
3216 [(set (match_operand:DI 0 "register_operand" "")
3221 if (alpha_compare_fp_p)
3224 operands[1] = gen_rtx_LTU (DImode, force_reg (DImode, alpha_compare_op1),
3228 (define_expand "sgeu"
3229 [(set (match_operand:DI 0 "register_operand" "")
3234 if (alpha_compare_fp_p)
3237 operands[1] = gen_rtx_LEU (DImode, force_reg (DImode, alpha_compare_op1),
3241 ;; These are the main define_expand's used to make conditional moves.
3243 (define_expand "movsicc"
3244 [(set (match_operand:SI 0 "register_operand" "")
3245 (if_then_else:SI (match_operand 1 "comparison_operator" "")
3246 (match_operand:SI 2 "reg_or_8bit_operand" "")
3247 (match_operand:SI 3 "reg_or_8bit_operand" "")))]
3251 if ((operands[1] = alpha_emit_conditional_move (operands[1], SImode)) == 0)
3255 (define_expand "movdicc"
3256 [(set (match_operand:DI 0 "register_operand" "")
3257 (if_then_else:DI (match_operand 1 "comparison_operator" "")
3258 (match_operand:DI 2 "reg_or_8bit_operand" "")
3259 (match_operand:DI 3 "reg_or_8bit_operand" "")))]
3263 if ((operands[1] = alpha_emit_conditional_move (operands[1], DImode)) == 0)
3267 (define_expand "movsfcc"
3268 [(set (match_operand:SF 0 "register_operand" "")
3269 (if_then_else:SF (match_operand 1 "comparison_operator" "")
3270 (match_operand:SF 2 "reg_or_8bit_operand" "")
3271 (match_operand:SF 3 "reg_or_8bit_operand" "")))]
3275 if ((operands[1] = alpha_emit_conditional_move (operands[1], SFmode)) == 0)
3279 (define_expand "movdfcc"
3280 [(set (match_operand:DF 0 "register_operand" "")
3281 (if_then_else:DF (match_operand 1 "comparison_operator" "")
3282 (match_operand:DF 2 "reg_or_8bit_operand" "")
3283 (match_operand:DF 3 "reg_or_8bit_operand" "")))]
3287 if ((operands[1] = alpha_emit_conditional_move (operands[1], DFmode)) == 0)
3291 ;; These define_split definitions are used in cases when comparisons have
3292 ;; not be stated in the correct way and we need to reverse the second
3293 ;; comparison. For example, x >= 7 has to be done as x < 6 with the
3294 ;; comparison that tests the result being reversed. We have one define_split
3295 ;; for each use of a comparison. They do not match valid insns and need
3296 ;; not generate valid insns.
3298 ;; We can also handle equality comparisons (and inequality comparisons in
3299 ;; cases where the resulting add cannot overflow) by doing an add followed by
3300 ;; a comparison with zero. This is faster since the addition takes one
3301 ;; less cycle than a compare when feeding into a conditional move.
3302 ;; For this case, we also have an SImode pattern since we can merge the add
3303 ;; and sign extend and the order doesn't matter.
3305 ;; We do not do this for floating-point, since it isn't clear how the "wrong"
3306 ;; operation could have been generated.
3309 [(set (match_operand:DI 0 "register_operand" "")
3311 (match_operator 1 "comparison_operator"
3312 [(match_operand:DI 2 "reg_or_0_operand" "")
3313 (match_operand:DI 3 "reg_or_cint_operand" "")])
3314 (match_operand:DI 4 "reg_or_cint_operand" "")
3315 (match_operand:DI 5 "reg_or_cint_operand" "")))
3316 (clobber (match_operand:DI 6 "register_operand" ""))]
3317 "operands[3] != const0_rtx"
3318 [(set (match_dup 6) (match_dup 7))
3320 (if_then_else:DI (match_dup 8) (match_dup 4) (match_dup 5)))]
3322 { enum rtx_code code = GET_CODE (operands[1]);
3323 int unsignedp = (code == GEU || code == LEU || code == GTU || code == LTU);
3325 /* If we are comparing for equality with a constant and that constant
3326 appears in the arm when the register equals the constant, use the
3327 register since that is more likely to match (and to produce better code
3330 if (code == EQ && GET_CODE (operands[3]) == CONST_INT
3331 && rtx_equal_p (operands[4], operands[3]))
3332 operands[4] = operands[2];
3334 else if (code == NE && GET_CODE (operands[3]) == CONST_INT
3335 && rtx_equal_p (operands[5], operands[3]))
3336 operands[5] = operands[2];
3338 if (code == NE || code == EQ
3339 || (extended_count (operands[2], DImode, unsignedp) >= 1
3340 && extended_count (operands[3], DImode, unsignedp) >= 1))
3342 if (GET_CODE (operands[3]) == CONST_INT)
3343 operands[7] = gen_rtx_PLUS (DImode, operands[2],
3344 GEN_INT (- INTVAL (operands[3])));
3346 operands[7] = gen_rtx_MINUS (DImode, operands[2], operands[3]);
3348 operands[8] = gen_rtx_fmt_ee (code, VOIDmode, operands[6], const0_rtx);
3351 else if (code == EQ || code == LE || code == LT
3352 || code == LEU || code == LTU)
3354 operands[7] = gen_rtx_fmt_ee (code, DImode, operands[2], operands[3]);
3355 operands[8] = gen_rtx_NE (VOIDmode, operands[6], const0_rtx);
3359 operands[7] = gen_rtx_fmt_ee (reverse_condition (code), DImode,
3360 operands[2], operands[3]);
3361 operands[8] = gen_rtx_EQ (VOIDmode, operands[6], const0_rtx);
3366 [(set (match_operand:DI 0 "register_operand" "")
3368 (match_operator 1 "comparison_operator"
3369 [(match_operand:SI 2 "reg_or_0_operand" "")
3370 (match_operand:SI 3 "reg_or_cint_operand" "")])
3371 (match_operand:DI 4 "reg_or_8bit_operand" "")
3372 (match_operand:DI 5 "reg_or_8bit_operand" "")))
3373 (clobber (match_operand:DI 6 "register_operand" ""))]
3374 "operands[3] != const0_rtx
3375 && (GET_CODE (operands[1]) == EQ || GET_CODE (operands[1]) == NE)"
3376 [(set (match_dup 6) (match_dup 7))
3378 (if_then_else:DI (match_dup 8) (match_dup 4) (match_dup 5)))]
3380 { enum rtx_code code = GET_CODE (operands[1]);
3381 int unsignedp = (code == GEU || code == LEU || code == GTU || code == LTU);
3384 if ((code != NE && code != EQ
3385 && ! (extended_count (operands[2], DImode, unsignedp) >= 1
3386 && extended_count (operands[3], DImode, unsignedp) >= 1)))
3389 if (GET_CODE (operands[3]) == CONST_INT)
3390 tem = gen_rtx_PLUS (SImode, operands[2],
3391 GEN_INT (- INTVAL (operands[3])));
3393 tem = gen_rtx_MINUS (SImode, operands[2], operands[3]);
3395 operands[7] = gen_rtx_SIGN_EXTEND (DImode, tem);
3396 operands[8] = gen_rtx_fmt_ee (GET_CODE (operands[1]), VOIDmode,
3397 operands[6], const0_rtx);
3403 (match_operator 1 "comparison_operator"
3404 [(match_operand:DI 2 "reg_or_0_operand" "")
3405 (match_operand:DI 3 "reg_or_cint_operand" "")])
3406 (label_ref (match_operand 0 "" ""))
3408 (clobber (match_operand:DI 4 "register_operand" ""))]
3409 "operands[3] != const0_rtx"
3410 [(set (match_dup 4) (match_dup 5))
3411 (set (pc) (if_then_else (match_dup 6) (label_ref (match_dup 0)) (pc)))]
3413 { enum rtx_code code = GET_CODE (operands[1]);
3414 int unsignedp = (code == GEU || code == LEU || code == GTU || code == LTU);
3416 if (code == NE || code == EQ
3417 || (extended_count (operands[2], DImode, unsignedp) >= 1
3418 && extended_count (operands[3], DImode, unsignedp) >= 1))
3420 if (GET_CODE (operands[3]) == CONST_INT)
3421 operands[5] = gen_rtx_PLUS (DImode, operands[2],
3422 GEN_INT (- INTVAL (operands[3])));
3424 operands[5] = gen_rtx_MINUS (DImode, operands[2], operands[3]);
3426 operands[6] = gen_rtx_fmt_ee (code, VOIDmode, operands[4], const0_rtx);
3429 else if (code == EQ || code == LE || code == LT
3430 || code == LEU || code == LTU)
3432 operands[5] = gen_rtx_fmt_ee (code, DImode, operands[2], operands[3]);
3433 operands[6] = gen_rtx_NE (VOIDmode, operands[4], const0_rtx);
3437 operands[5] = gen_rtx_fmt_ee (reverse_condition (code), DImode,
3438 operands[2], operands[3]);
3439 operands[6] = gen_rtx_EQ (VOIDmode, operands[4], const0_rtx);
3446 (match_operator 1 "comparison_operator"
3447 [(match_operand:SI 2 "reg_or_0_operand" "")
3448 (match_operand:SI 3 "const_int_operand" "")])
3449 (label_ref (match_operand 0 "" ""))
3451 (clobber (match_operand:DI 4 "register_operand" ""))]
3452 "operands[3] != const0_rtx
3453 && (GET_CODE (operands[1]) == EQ || GET_CODE (operands[1]) == NE)"
3454 [(set (match_dup 4) (match_dup 5))
3455 (set (pc) (if_then_else (match_dup 6) (label_ref (match_dup 0)) (pc)))]
3459 if (GET_CODE (operands[3]) == CONST_INT)
3460 tem = gen_rtx_PLUS (SImode, operands[2],
3461 GEN_INT (- INTVAL (operands[3])));
3463 tem = gen_rtx_MINUS (SImode, operands[2], operands[3]);
3465 operands[5] = gen_rtx_SIGN_EXTEND (DImode, tem);
3466 operands[6] = gen_rtx_fmt_ee (GET_CODE (operands[1]), VOIDmode,
3467 operands[4], const0_rtx);
3470 ;; We can convert such things as "a > 0xffff" to "t = a & ~ 0xffff; t != 0".
3471 ;; This eliminates one, and sometimes two, insns when the AND can be done
3474 [(set (match_operand:DI 0 "register_operand" "")
3475 (match_operator 1 "comparison_operator"
3476 [(match_operand:DI 2 "register_operand" "")
3477 (match_operand:DI 3 "const_int_operand" "")]))
3478 (clobber (match_operand:DI 4 "register_operand" ""))]
3479 "exact_log2 (INTVAL (operands[3]) + 1) >= 0
3480 && (GET_CODE (operands[1]) == GTU
3481 || GET_CODE (operands[1]) == LEU
3482 || ((GET_CODE (operands[1]) == GT || GET_CODE (operands[1]) == LE)
3483 && extended_count (operands[2], DImode, 1) > 0))"
3484 [(set (match_dup 4) (and:DI (match_dup 2) (match_dup 5)))
3485 (set (match_dup 0) (match_dup 6))]
3488 operands[5] = GEN_INT (~ INTVAL (operands[3]));
3489 operands[6] = gen_rtx_fmt_ee (((GET_CODE (operands[1]) == GTU
3490 || GET_CODE (operands[1]) == GT)
3492 DImode, operands[4], const0_rtx);
3495 ;; Here are the CALL and unconditional branch insns. Calls on NT and OSF
3496 ;; work differently, so we have different patterns for each.
3498 (define_expand "call"
3499 [(use (match_operand:DI 0 "" ""))
3500 (use (match_operand 1 "" ""))
3501 (use (match_operand 2 "" ""))
3502 (use (match_operand 3 "" ""))]
3505 { if (TARGET_WINDOWS_NT)
3506 emit_call_insn (gen_call_nt (operands[0], operands[1]));
3507 else if (TARGET_OPEN_VMS)
3508 emit_call_insn (gen_call_vms (operands[0], operands[2]));
3510 emit_call_insn (gen_call_osf (operands[0], operands[1]));
3515 (define_expand "call_osf"
3516 [(parallel [(call (mem:DI (match_operand 0 "" ""))
3517 (match_operand 1 "" ""))
3518 (clobber (reg:DI 27))
3519 (clobber (reg:DI 26))])]
3522 { if (GET_CODE (operands[0]) != MEM)
3525 operands[0] = XEXP (operands[0], 0);
3527 if (GET_CODE (operands[0]) != SYMBOL_REF
3528 && ! (GET_CODE (operands[0]) == REG && REGNO (operands[0]) == 27))
3530 rtx tem = gen_rtx_REG (DImode, 27);
3531 emit_move_insn (tem, operands[0]);
3536 (define_expand "call_nt"
3537 [(parallel [(call (mem:DI (match_operand 0 "" ""))
3538 (match_operand 1 "" ""))
3539 (clobber (reg:DI 26))])]
3542 { if (GET_CODE (operands[0]) != MEM)
3545 operands[0] = XEXP (operands[0], 0);
3546 if (GET_CODE (operands[0]) != SYMBOL_REF && GET_CODE (operands[0]) != REG)
3547 operands[0] = force_reg (DImode, operands[0]);
3551 ;; call openvms/alpha
3552 ;; op 0: symbol ref for called function
3553 ;; op 1: next_arg_reg (argument information value for R25)
3555 (define_expand "call_vms"
3556 [(parallel [(call (mem:DI (match_operand 0 "" ""))
3557 (match_operand 1 "" ""))
3561 (clobber (reg:DI 27))])]
3564 { if (GET_CODE (operands[0]) != MEM)
3567 operands[0] = XEXP (operands[0], 0);
3569 /* Always load AI with argument information, then handle symbolic and
3570 indirect call differently. Load RA and set operands[2] to PV in
3573 emit_move_insn (gen_rtx_REG (DImode, 25), operands[1]);
3574 if (GET_CODE (operands[0]) == SYMBOL_REF)
3576 extern char *savealloc ();
3577 char *linksym, *symbol = XSTR (operands[0], 0);
3582 linksym = savealloc (strlen (symbol) + 6);
3584 alpha_need_linkage (symbol, 0);
3587 strcpy (linksym+1, symbol);
3588 strcat (linksym, \"..lk\");
3589 linkage = gen_rtx_SYMBOL_REF (Pmode, linksym);
3591 emit_move_insn (gen_rtx_REG (Pmode, 26), gen_rtx_MEM (Pmode, linkage));
3594 = validize_mem (gen_rtx_MEM (Pmode, plus_constant (linkage, 8)));
3598 emit_move_insn (gen_rtx_REG (Pmode, 26),
3599 gen_rtx_MEM (Pmode, plus_constant (operands[0], 8)));
3601 operands[2] = operands[0];
3606 (define_expand "call_value"
3607 [(use (match_operand 0 "" ""))
3608 (use (match_operand:DI 1 "" ""))
3609 (use (match_operand 2 "" ""))
3610 (use (match_operand 3 "" ""))
3611 (use (match_operand 4 "" ""))]
3614 { if (TARGET_WINDOWS_NT)
3615 emit_call_insn (gen_call_value_nt (operands[0], operands[1], operands[2]));
3616 else if (TARGET_OPEN_VMS)
3617 emit_call_insn (gen_call_value_vms (operands[0], operands[1],
3620 emit_call_insn (gen_call_value_osf (operands[0], operands[1],
3625 (define_expand "call_value_osf"
3626 [(parallel [(set (match_operand 0 "" "")
3627 (call (mem:DI (match_operand 1 "" ""))
3628 (match_operand 2 "" "")))
3629 (clobber (reg:DI 27))
3630 (clobber (reg:DI 26))])]
3633 { if (GET_CODE (operands[1]) != MEM)
3636 operands[1] = XEXP (operands[1], 0);
3638 if (GET_CODE (operands[1]) != SYMBOL_REF
3639 && ! (GET_CODE (operands[1]) == REG && REGNO (operands[1]) == 27))
3641 rtx tem = gen_rtx_REG (DImode, 27);
3642 emit_move_insn (tem, operands[1]);
3647 (define_expand "call_value_nt"
3648 [(parallel [(set (match_operand 0 "" "")
3649 (call (mem:DI (match_operand 1 "" ""))
3650 (match_operand 2 "" "")))
3651 (clobber (reg:DI 26))])]
3654 { if (GET_CODE (operands[1]) != MEM)
3657 operands[1] = XEXP (operands[1], 0);
3658 if (GET_CODE (operands[0]) != SYMBOL_REF && GET_CODE (operands[0]) != REG)
3659 operands[1] = force_reg (DImode, operands[1]);
3662 (define_expand "call_value_vms"
3663 [(parallel [(set (match_operand 0 "" "")
3664 (call (mem:DI (match_operand:DI 1 "" ""))
3665 (match_operand 2 "" "")))
3669 (clobber (reg:DI 27))])]
3672 { if (GET_CODE (operands[1]) != MEM)
3675 operands[1] = XEXP (operands[1], 0);
3677 /* Always load AI with argument information, then handle symbolic and
3678 indirect call differently. Load RA and set operands[3] to PV in
3681 emit_move_insn (gen_rtx_REG (DImode, 25), operands[2]);
3682 if (GET_CODE (operands[1]) == SYMBOL_REF)
3684 extern char *savealloc ();
3685 char *linksym, *symbol = XSTR (operands[1], 0);
3690 linksym = savealloc (strlen (symbol) + 6);
3692 alpha_need_linkage (symbol, 0);
3694 strcpy (linksym+1, symbol);
3695 strcat (linksym, \"..lk\");
3696 linkage = gen_rtx_SYMBOL_REF (Pmode, linksym);
3698 emit_move_insn (gen_rtx_REG (Pmode, 26), gen_rtx_MEM (Pmode, linkage));
3701 = validize_mem (gen_rtx_MEM (Pmode, plus_constant (linkage, 8)));
3705 emit_move_insn (gen_rtx_REG (Pmode, 26),
3706 gen_rtx_MEM (Pmode, plus_constant (operands[1], 8)));
3708 operands[3] = operands[1];
3713 [(call (mem:DI (match_operand:DI 0 "call_operand" "r,R,i"))
3714 (match_operand 1 "" ""))
3715 (clobber (reg:DI 27))
3716 (clobber (reg:DI 26))]
3717 "! TARGET_WINDOWS_NT && ! TARGET_OPEN_VMS"
3719 jsr $26,($27),0\;ldgp $29,0($26)
3721 jsr $26,%0\;ldgp $29,0($26)"
3722 [(set_attr "type" "jsr")
3723 (set_attr "length" "12,*,16")])
3726 [(call (mem:DI (match_operand:DI 0 "call_operand" "r,R,i"))
3727 (match_operand 1 "" ""))
3728 (clobber (reg:DI 26))]
3734 [(set_attr "type" "jsr")
3735 (set_attr "length" "*,*,12")])
3738 [(call (mem:DI (match_operand:DI 0 "call_operand" "r,i"))
3739 (match_operand 1 "" ""))
3740 (use (match_operand:DI 2 "general_operand" "r,m"))
3743 (clobber (reg:DI 27))]
3746 bis %2,%2,$27\;jsr $26,0\;ldq $27,0($29)
3747 ldq $27,%2\;jsr $26,%0\;ldq $27,0($29)"
3748 [(set_attr "type" "jsr")
3749 (set_attr "length" "12,16")])
3752 [(set (match_operand 0 "register_operand" "=rf,rf,rf")
3753 (call (mem:DI (match_operand:DI 1 "call_operand" "r,R,i"))
3754 (match_operand 2 "" "")))
3755 (clobber (reg:DI 27))
3756 (clobber (reg:DI 26))]
3757 "! TARGET_WINDOWS_NT && ! TARGET_OPEN_VMS"
3759 jsr $26,($27),0\;ldgp $29,0($26)
3761 jsr $26,%1\;ldgp $29,0($26)"
3762 [(set_attr "type" "jsr")
3763 (set_attr "length" "12,*,16")])
3766 [(set (match_operand 0 "register_operand" "=rf,rf,rf")
3767 (call (mem:DI (match_operand:DI 1 "call_operand" "r,R,i"))
3768 (match_operand 2 "" "")))
3769 (clobber (reg:DI 26))]
3775 [(set_attr "type" "jsr")
3776 (set_attr "length" "*,*,12")])
3779 [(set (match_operand 0 "register_operand" "")
3780 (call (mem:DI (match_operand:DI 1 "call_operand" "r,i"))
3781 (match_operand 2 "" "")))
3782 (use (match_operand:DI 3 "general_operand" "r,m"))
3785 (clobber (reg:DI 27))]
3788 bis %3,%3,$27\;jsr $26,0\;ldq $27,0($29)
3789 ldq $27,%3\;jsr $26,%1\;ldq $27,0($29)"
3790 [(set_attr "type" "jsr")
3791 (set_attr "length" "12,16")])
3793 ;; Call subroutine returning any type.
3795 (define_expand "untyped_call"
3796 [(parallel [(call (match_operand 0 "" "")
3798 (match_operand 1 "" "")
3799 (match_operand 2 "" "")])]
3805 emit_call_insn (gen_call (operands[0], const0_rtx, NULL, const0_rtx));
3807 for (i = 0; i < XVECLEN (operands[2], 0); i++)
3809 rtx set = XVECEXP (operands[2], 0, i);
3810 emit_move_insn (SET_DEST (set), SET_SRC (set));
3813 /* The optimizer does not know that the call sets the function value
3814 registers we stored in the result block. We avoid problems by
3815 claiming that all hard registers are used and clobbered at this
3817 emit_insn (gen_blockage ());
3822 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
3823 ;; all of memory. This blocks insns from being moved across this point.
3825 (define_insn "blockage"
3826 [(unspec_volatile [(const_int 0)] 1)]
3829 [(set_attr "length" "0")])
3833 (label_ref (match_operand 0 "" "")))]
3836 [(set_attr "type" "ibr")])
3838 (define_insn "return"
3842 [(set_attr "type" "ibr")])
3844 ;; Use a different pattern for functions which have non-trivial
3845 ;; epilogues so as not to confuse jump and reorg.
3846 (define_insn "return_internal"
3851 [(set_attr "type" "ibr")])
3853 (define_insn "indirect_jump"
3854 [(set (pc) (match_operand:DI 0 "register_operand" "r"))]
3857 [(set_attr "type" "ibr")])
3859 (define_expand "tablejump"
3860 [(use (match_operand:SI 0 "register_operand" ""))
3861 (use (match_operand:SI 1 "" ""))]
3865 if (TARGET_WINDOWS_NT)
3866 emit_jump_insn (gen_tablejump_nt (operands[0], operands[1]));
3867 else if (TARGET_OPEN_VMS)
3868 emit_jump_insn (gen_tablejump_vms (operands[0], operands[1]));
3870 emit_jump_insn (gen_tablejump_osf (operands[0], operands[1]));
3875 (define_expand "tablejump_osf"
3877 (sign_extend:DI (match_operand:SI 0 "register_operand" "")))
3878 (parallel [(set (pc)
3879 (plus:DI (match_dup 3)
3880 (label_ref:DI (match_operand 1 "" ""))))
3881 (clobber (match_scratch:DI 2 "=r"))])]
3884 { operands[3] = gen_reg_rtx (DImode); }")
3886 (define_expand "tablejump_nt"
3888 (sign_extend:DI (match_operand:SI 0 "register_operand" "")))
3889 (parallel [(set (pc)
3891 (use (label_ref (match_operand 1 "" "")))])]
3894 { operands[3] = gen_reg_rtx (DImode); }")
3897 ;; tablejump, openVMS way
3899 ;; op 1: label preceding jump-table
3901 (define_expand "tablejump_vms"
3903 (match_operand:DI 0 "register_operand" ""))
3905 (plus:DI (match_dup 2)
3906 (label_ref:DI (match_operand 1 "" ""))))]
3909 { operands[2] = gen_reg_rtx (DImode); }")
3913 (plus:DI (match_operand:DI 0 "register_operand" "r")
3914 (label_ref:DI (match_operand 1 "" ""))))
3915 (clobber (match_scratch:DI 2 "=r"))]
3916 "! TARGET_WINDOWS_NT && ! TARGET_OPEN_VMS && next_active_insn (insn) != 0
3917 && GET_CODE (PATTERN (next_active_insn (insn))) == ADDR_DIFF_VEC
3918 && PREV_INSN (next_active_insn (insn)) == operands[1]"
3920 { rtx best_label = 0;
3921 rtx jump_table_insn = next_active_insn (operands[1]);
3923 if (GET_CODE (jump_table_insn) == JUMP_INSN
3924 && GET_CODE (PATTERN (jump_table_insn)) == ADDR_DIFF_VEC)
3926 rtx jump_table = PATTERN (jump_table_insn);
3927 int n_labels = XVECLEN (jump_table, 1);
3928 int best_count = -1;
3931 for (i = 0; i < n_labels; i++)
3935 for (j = i + 1; j < n_labels; j++)
3936 if (XEXP (XVECEXP (jump_table, 1, i), 0)
3937 == XEXP (XVECEXP (jump_table, 1, j), 0))
3940 if (count > best_count)
3941 best_count = count, best_label = XVECEXP (jump_table, 1, i);
3947 operands[3] = best_label;
3948 return \"addq %0,$29,%2\;jmp $31,(%2),%3\";
3951 return \"addq %0,$29,%2\;jmp $31,(%2),0\";
3953 [(set_attr "type" "ibr")
3954 (set_attr "length" "8")])
3958 (match_operand:DI 0 "register_operand" "r"))
3959 (use (label_ref (match_operand 1 "" "")))]
3960 "TARGET_WINDOWS_NT && next_active_insn (insn) != 0
3961 && GET_CODE (PATTERN (next_active_insn (insn))) == ADDR_DIFF_VEC
3962 && PREV_INSN (next_active_insn (insn)) == operands[1]"
3964 { rtx best_label = 0;
3965 rtx jump_table_insn = next_active_insn (operands[1]);
3967 if (GET_CODE (jump_table_insn) == JUMP_INSN
3968 && GET_CODE (PATTERN (jump_table_insn)) == ADDR_DIFF_VEC)
3970 rtx jump_table = PATTERN (jump_table_insn);
3971 int n_labels = XVECLEN (jump_table, 1);
3972 int best_count = -1;
3975 for (i = 0; i < n_labels; i++)
3979 for (j = i + 1; j < n_labels; j++)
3980 if (XEXP (XVECEXP (jump_table, 1, i), 0)
3981 == XEXP (XVECEXP (jump_table, 1, j), 0))
3984 if (count > best_count)
3985 best_count = count, best_label = XVECEXP (jump_table, 1, i);
3991 operands[2] = best_label;
3992 return \"jmp $31,(%0),%2\";
3995 return \"jmp $31,(%0),0\";
3997 [(set_attr "type" "ibr")])
4000 ;; op 0 is table offset
4001 ;; op 1 is table label
4006 (plus:DI (match_operand 0 "register_operand" "r")
4007 (label_ref (match_operand 1 "" ""))))]
4010 [(set_attr "type" "ibr")])
4012 ;; Cache flush. Used by INITIALIZE_TRAMPOLINE. 0x86 is PAL_imb, but we don't
4013 ;; want to have to include pal.h in our .s file.
4015 ;; Technically the type for call_pal is jsr, but we use that for determining
4016 ;; if we need a GP. Use ibr instead since it has the same EV5 scheduling
4019 [(unspec_volatile [(const_int 0)] 0)]
4022 [(set_attr "type" "ibr")])
4024 ;; Finally, we have the basic data motion insns. The byte and word insns
4025 ;; are done via define_expand. Start with the floating-point insns, since
4026 ;; they are simpler.
4029 [(set (match_operand:SF 0 "nonimmediate_operand" "=r,r,m,f,f,f,m")
4030 (match_operand:SF 1 "input_operand" "rG,m,rG,f,G,m,fG"))]
4032 && (register_operand (operands[0], SFmode)
4033 || reg_or_fp0_operand (operands[1], SFmode))"
4042 [(set_attr "type" "ilog,ild,ist,fcpys,fcpys,fld,fst")])
4045 [(set (match_operand:SF 0 "nonimmediate_operand" "=r,r,m,f,f,f,m,f,*r")
4046 (match_operand:SF 1 "input_operand" "rG,m,rG,f,G,m,fG,r,*f"))]
4048 && (register_operand (operands[0], SFmode)
4049 || reg_or_fp0_operand (operands[1], SFmode))"
4060 [(set_attr "type" "ilog,ild,ist,fcpys,fcpys,fld,fst,itof,ftoi")])
4063 [(set (match_operand:DF 0 "nonimmediate_operand" "=r,r,m,f,f,f,m")
4064 (match_operand:DF 1 "input_operand" "rG,m,rG,f,G,m,fG"))]
4066 && (register_operand (operands[0], DFmode)
4067 || reg_or_fp0_operand (operands[1], DFmode))"
4076 [(set_attr "type" "ilog,ild,ist,fcpys,fcpys,fld,fst")])
4079 [(set (match_operand:DF 0 "nonimmediate_operand" "=r,r,m,f,f,f,m,f,*r")
4080 (match_operand:DF 1 "input_operand" "rG,m,rG,f,G,m,fG,r,*f"))]
4082 && (register_operand (operands[0], DFmode)
4083 || reg_or_fp0_operand (operands[1], DFmode))"
4094 [(set_attr "type" "ilog,ild,ist,fcpys,fcpys,fld,fst,itof,ftoi")])
4096 (define_expand "movsf"
4097 [(set (match_operand:SF 0 "nonimmediate_operand" "")
4098 (match_operand:SF 1 "general_operand" ""))]
4102 if (GET_CODE (operands[0]) == MEM
4103 && ! reg_or_fp0_operand (operands[1], SFmode))
4104 operands[1] = force_reg (SFmode, operands[1]);
4107 (define_expand "movdf"
4108 [(set (match_operand:DF 0 "nonimmediate_operand" "")
4109 (match_operand:DF 1 "general_operand" ""))]
4113 if (GET_CODE (operands[0]) == MEM
4114 && ! reg_or_fp0_operand (operands[1], DFmode))
4115 operands[1] = force_reg (DFmode, operands[1]);
4119 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,r,r,r,r,m,f,f,f,m")
4120 (match_operand:SI 1 "input_operand" "r,J,I,K,L,m,rJ,f,J,m,fG"))]
4121 "! TARGET_WINDOWS_NT && ! TARGET_OPEN_VMS && ! TARGET_CIX
4122 && (register_operand (operands[0], SImode)
4123 || reg_or_0_operand (operands[1], SImode))"
4136 [(set_attr "type" "ilog,ilog,ilog,iadd,iadd,ild,ist,fcpys,fcpys,fld,fst")])
4139 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,r,r,r,r,m,f,f,f,m,r,*f")
4140 (match_operand:SI 1 "input_operand" "r,J,I,K,L,m,rJ,f,J,m,fG,f,*r"))]
4141 "! TARGET_WINDOWS_NT && ! TARGET_OPEN_VMS && TARGET_CIX
4142 && (register_operand (operands[0], SImode)
4143 || reg_or_0_operand (operands[1], SImode))"
4158 [(set_attr "type" "ilog,ilog,ilog,iadd,iadd,ild,ist,fcpys,fcpys,fld,fst,ftoi,itof")])
4161 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,r,r,r,r,r,m,f,f,f,m")
4162 (match_operand:SI 1 "input_operand" "r,J,I,K,L,s,m,rJ,f,J,m,fG"))]
4163 "(TARGET_WINDOWS_NT || TARGET_OPEN_VMS)
4164 && (register_operand (operands[0], SImode)
4165 || reg_or_0_operand (operands[1], SImode))"
4179 [(set_attr "type" "ilog,ilog,ilog,iadd,iadd,ldsym,ild,ist,fcpys,fcpys,fld,fst")])
4182 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,r,f,f")
4183 (match_operand:HI 1 "input_operand" "r,J,I,n,f,J"))]
4185 && (register_operand (operands[0], HImode)
4186 || register_operand (operands[1], HImode))"
4194 [(set_attr "type" "ilog,ilog,ilog,iadd,fcpys,fcpys")])
4197 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,r,r,m,f,f")
4198 (match_operand:HI 1 "input_operand" "r,J,I,n,m,rJ,f,J"))]
4200 && (register_operand (operands[0], HImode)
4201 || reg_or_0_operand (operands[1], HImode))"
4211 [(set_attr "type" "ilog,ilog,ilog,iadd,ild,ist,fcpys,fcpys")])
4214 [(set (match_operand:QI 0 "nonimmediate_operand" "=r,r,r,r,f,f")
4215 (match_operand:QI 1 "input_operand" "r,J,I,n,f,J"))]
4217 && (register_operand (operands[0], QImode)
4218 || register_operand (operands[1], QImode))"
4226 [(set_attr "type" "ilog,ilog,ilog,iadd,fcpys,fcpys")])
4229 [(set (match_operand:QI 0 "nonimmediate_operand" "=r,r,r,r,r,m,f,f")
4230 (match_operand:QI 1 "input_operand" "r,J,I,n,m,rJ,f,J"))]
4232 && (register_operand (operands[0], QImode)
4233 || reg_or_0_operand (operands[1], QImode))"
4243 [(set_attr "type" "ilog,ilog,ilog,iadd,ild,ist,fcpys,fcpys")])
4245 ;; We do two major things here: handle mem->mem and construct long
4248 (define_expand "movsi"
4249 [(set (match_operand:SI 0 "general_operand" "")
4250 (match_operand:SI 1 "general_operand" ""))]
4254 if (GET_CODE (operands[0]) == MEM
4255 && ! reg_or_0_operand (operands[1], SImode))
4256 operands[1] = force_reg (SImode, operands[1]);
4258 if (! CONSTANT_P (operands[1]) || input_operand (operands[1], SImode))
4260 else if (GET_CODE (operands[1]) == CONST_INT)
4263 = alpha_emit_set_const (operands[0], SImode, INTVAL (operands[1]), 3);
4264 if (rtx_equal_p (operands[0], operands[1]))
4269 ;; Split a load of a large constant into the appropriate two-insn
4273 [(set (match_operand:SI 0 "register_operand" "")
4274 (match_operand:SI 1 "const_int_operand" ""))]
4275 "! add_operand (operands[1], SImode)"
4276 [(set (match_dup 0) (match_dup 2))
4277 (set (match_dup 0) (plus:SI (match_dup 0) (match_dup 3)))]
4280 = alpha_emit_set_const (operands[0], SImode, INTVAL (operands[1]), 2);
4282 if (tem == operands[0])
4289 [(set (match_operand:DI 0 "general_operand" "=r,r,r,r,r,r,r,m,f,f,f,Q")
4290 (match_operand:DI 1 "input_operand" "r,J,I,K,L,s,m,rJ,f,J,Q,fG"))]
4292 && (register_operand (operands[0], DImode)
4293 || reg_or_0_operand (operands[1], DImode))"
4307 [(set_attr "type" "ilog,ilog,ilog,iadd,iadd,ldsym,ild,ist,fcpys,fcpys,fld,fst")])
4310 [(set (match_operand:DI 0 "general_operand" "=r,r,r,r,r,r,r,m,f,f,f,Q,r,*f")
4311 (match_operand:DI 1 "input_operand" "r,J,I,K,L,s,m,rJ,f,J,Q,fG,f,*r"))]
4313 && (register_operand (operands[0], DImode)
4314 || reg_or_0_operand (operands[1], DImode))"
4330 [(set_attr "type" "ilog,ilog,ilog,iadd,iadd,ldsym,ild,ist,fcpys,fcpys,fld,fst,ftoi,itof")])
4332 ;; We do three major things here: handle mem->mem, put 64-bit constants in
4333 ;; memory, and construct long 32-bit constants.
4335 (define_expand "movdi"
4336 [(set (match_operand:DI 0 "general_operand" "")
4337 (match_operand:DI 1 "general_operand" ""))]
4343 if (GET_CODE (operands[0]) == MEM
4344 && ! reg_or_0_operand (operands[1], DImode))
4345 operands[1] = force_reg (DImode, operands[1]);
4347 if (! CONSTANT_P (operands[1]) || input_operand (operands[1], DImode))
4349 else if (GET_CODE (operands[1]) == CONST_INT
4350 && (tem = alpha_emit_set_const (operands[0], DImode,
4351 INTVAL (operands[1]), 3)) != 0)
4353 if (rtx_equal_p (tem, operands[0]))
4358 else if (CONSTANT_P (operands[1]))
4360 if (TARGET_BUILD_CONSTANTS)
4362 HOST_WIDE_INT i0, i1;
4364 if (GET_CODE (operands[1]) == CONST_INT)
4366 i0 = INTVAL (operands[1]);
4369 else if (GET_CODE (operands[1]) == CONST_DOUBLE)
4371 #if HOST_BITS_PER_WIDE_INT >= 64
4372 i0 = CONST_DOUBLE_LOW (operands[1]);
4375 i0 = CONST_DOUBLE_LOW (operands[1]);
4376 i1 = CONST_DOUBLE_HIGH (operands[1]);
4382 tem = alpha_emit_set_long_const (operands[0], i0, i1);
4383 if (rtx_equal_p (tem, operands[0]))
4390 operands[1] = force_const_mem (DImode, operands[1]);
4391 if (reload_in_progress)
4393 emit_move_insn (operands[0], XEXP (operands[1], 0));
4394 operands[1] = copy_rtx (operands[1]);
4395 XEXP (operands[1], 0) = operands[0];
4398 operands[1] = validize_mem (operands[1]);
4405 ;; Split a load of a large constant into the appropriate two-insn
4409 [(set (match_operand:DI 0 "register_operand" "")
4410 (match_operand:DI 1 "const_int_operand" ""))]
4411 "! add_operand (operands[1], DImode)"
4412 [(set (match_dup 0) (match_dup 2))
4413 (set (match_dup 0) (plus:DI (match_dup 0) (match_dup 3)))]
4416 = alpha_emit_set_const (operands[0], DImode, INTVAL (operands[1]), 2);
4418 if (tem == operands[0])
4424 ;; These are the partial-word cases.
4426 ;; First we have the code to load an aligned word. Operand 0 is the register
4427 ;; in which to place the result. It's mode is QImode or HImode. Operand 1
4428 ;; is an SImode MEM at the low-order byte of the proper word. Operand 2 is the
4429 ;; number of bits within the word that the value is. Operand 3 is an SImode
4430 ;; scratch register. If operand 0 is a hard register, operand 3 may be the
4431 ;; same register. It is allowed to conflict with operand 1 as well.
4433 (define_expand "aligned_loadqi"
4434 [(set (match_operand:SI 3 "register_operand" "")
4435 (match_operand:SI 1 "memory_operand" ""))
4436 (set (subreg:DI (match_operand:QI 0 "register_operand" "") 0)
4437 (zero_extract:DI (subreg:DI (match_dup 3) 0)
4439 (match_operand:DI 2 "const_int_operand" "")))]
4444 (define_expand "aligned_loadhi"
4445 [(set (match_operand:SI 3 "register_operand" "")
4446 (match_operand:SI 1 "memory_operand" ""))
4447 (set (subreg:DI (match_operand:HI 0 "register_operand" "") 0)
4448 (zero_extract:DI (subreg:DI (match_dup 3) 0)
4450 (match_operand:DI 2 "const_int_operand" "")))]
4455 ;; Similar for unaligned loads, where we use the sequence from the
4456 ;; Alpha Architecture manual.
4458 ;; Operand 1 is the address. Operands 2 and 3 are temporaries, where
4459 ;; operand 3 can overlap the input and output registers.
4461 (define_expand "unaligned_loadqi"
4462 [(set (match_operand:DI 2 "register_operand" "")
4463 (mem:DI (and:DI (match_operand:DI 1 "address_operand" "")
4465 (set (match_operand:DI 3 "register_operand" "")
4467 (set (subreg:DI (match_operand:QI 0 "register_operand" "") 0)
4468 (zero_extract:DI (match_dup 2)
4470 (ashift:DI (match_dup 3) (const_int 3))))]
4474 (define_expand "unaligned_loadhi"
4475 [(set (match_operand:DI 2 "register_operand" "")
4476 (mem:DI (and:DI (match_operand:DI 1 "address_operand" "")
4478 (set (match_operand:DI 3 "register_operand" "")
4480 (set (subreg:DI (match_operand:QI 0 "register_operand" "") 0)
4481 (zero_extract:DI (match_dup 2)
4483 (ashift:DI (match_dup 3) (const_int 3))))]
4487 ;; Storing an aligned byte or word requires two temporaries. Operand 0 is the
4488 ;; aligned SImode MEM. Operand 1 is the register containing the
4489 ;; byte or word to store. Operand 2 is the number of bits within the word that
4490 ;; the value should be placed. Operands 3 and 4 are SImode temporaries.
4492 (define_expand "aligned_store"
4493 [(set (match_operand:SI 3 "register_operand" "")
4494 (match_operand:SI 0 "memory_operand" ""))
4495 (set (subreg:DI (match_dup 3) 0)
4496 (and:DI (subreg:DI (match_dup 3) 0) (match_dup 5)))
4497 (set (subreg:DI (match_operand:SI 4 "register_operand" "") 0)
4498 (ashift:DI (zero_extend:DI (match_operand 1 "register_operand" ""))
4499 (match_operand:DI 2 "const_int_operand" "")))
4500 (set (subreg:DI (match_dup 4) 0)
4501 (ior:DI (subreg:DI (match_dup 4) 0) (subreg:DI (match_dup 3) 0)))
4502 (set (match_dup 0) (match_dup 4))]
4505 { operands[5] = GEN_INT (~ (GET_MODE_MASK (GET_MODE (operands[1]))
4506 << INTVAL (operands[2])));
4509 ;; For the unaligned byte and halfword cases, we use code similar to that
4510 ;; in the ;; Architecture book, but reordered to lower the number of registers
4511 ;; required. Operand 0 is the address. Operand 1 is the data to store.
4512 ;; Operands 2, 3, and 4 are DImode temporaries, where operands 2 and 4 may
4513 ;; be the same temporary, if desired. If the address is in a register,
4514 ;; operand 2 can be that register.
4516 (define_expand "unaligned_storeqi"
4517 [(set (match_operand:DI 3 "register_operand" "")
4518 (mem:DI (and:DI (match_operand:DI 0 "address_operand" "")
4520 (set (match_operand:DI 2 "register_operand" "")
4523 (and:DI (not:DI (ashift:DI (const_int 255)
4524 (ashift:DI (match_dup 2) (const_int 3))))
4526 (set (match_operand:DI 4 "register_operand" "")
4527 (ashift:DI (zero_extend:DI (match_operand:QI 1 "register_operand" ""))
4528 (ashift:DI (match_dup 2) (const_int 3))))
4529 (set (match_dup 4) (ior:DI (match_dup 4) (match_dup 3)))
4530 (set (mem:DI (and:DI (match_dup 0) (const_int -8)))
4535 (define_expand "unaligned_storehi"
4536 [(set (match_operand:DI 3 "register_operand" "")
4537 (mem:DI (and:DI (match_operand:DI 0 "address_operand" "")
4539 (set (match_operand:DI 2 "register_operand" "")
4542 (and:DI (not:DI (ashift:DI (const_int 65535)
4543 (ashift:DI (match_dup 2) (const_int 3))))
4545 (set (match_operand:DI 4 "register_operand" "")
4546 (ashift:DI (zero_extend:DI (match_operand:HI 1 "register_operand" ""))
4547 (ashift:DI (match_dup 2) (const_int 3))))
4548 (set (match_dup 4) (ior:DI (match_dup 4) (match_dup 3)))
4549 (set (mem:DI (and:DI (match_dup 0) (const_int -8)))
4554 ;; Here are the define_expand's for QI and HI moves that use the above
4555 ;; patterns. We have the normal sets, plus the ones that need scratch
4556 ;; registers for reload.
4558 (define_expand "movqi"
4559 [(set (match_operand:QI 0 "general_operand" "")
4560 (match_operand:QI 1 "general_operand" ""))]
4566 if (GET_CODE (operands[0]) == MEM
4567 && ! reg_or_0_operand (operands[1], QImode))
4568 operands[1] = force_reg (QImode, operands[1]);
4570 if (GET_CODE (operands[1]) == CONST_INT
4571 && ! input_operand (operands[1], QImode))
4573 operands[1] = alpha_emit_set_const (operands[0], QImode,
4574 INTVAL (operands[1]), 3);
4576 if (rtx_equal_p (operands[0], operands[1]))
4583 /* If the output is not a register, the input must be. */
4584 if (GET_CODE (operands[0]) == MEM)
4585 operands[1] = force_reg (QImode, operands[1]);
4587 /* Handle four memory cases, unaligned and aligned for either the input
4588 or the output. The only case where we can be called during reload is
4589 for aligned loads; all other cases require temporaries. */
4591 if (GET_CODE (operands[1]) == MEM
4592 || (GET_CODE (operands[1]) == SUBREG
4593 && GET_CODE (SUBREG_REG (operands[1])) == MEM)
4594 || (reload_in_progress && GET_CODE (operands[1]) == REG
4595 && REGNO (operands[1]) >= FIRST_PSEUDO_REGISTER)
4596 || (reload_in_progress && GET_CODE (operands[1]) == SUBREG
4597 && GET_CODE (SUBREG_REG (operands[1])) == REG
4598 && REGNO (SUBREG_REG (operands[1])) >= FIRST_PSEUDO_REGISTER))
4600 if (aligned_memory_operand (operands[1], QImode))
4602 rtx aligned_mem, bitnum;
4603 rtx scratch = (reload_in_progress
4604 ? gen_rtx_REG (SImode, REGNO (operands[0]))
4605 : gen_reg_rtx (SImode));
4607 get_aligned_mem (operands[1], &aligned_mem, &bitnum);
4609 emit_insn (gen_aligned_loadqi (operands[0], aligned_mem, bitnum,
4614 /* Don't pass these as parameters since that makes the generated
4615 code depend on parameter evaluation order which will cause
4616 bootstrap failures. */
4618 rtx temp1 = gen_reg_rtx (DImode);
4619 rtx temp2 = gen_reg_rtx (DImode);
4621 = gen_unaligned_loadqi (operands[0],
4622 get_unaligned_address (operands[1], 0),
4625 alpha_set_memflags (seq, operands[1]);
4632 else if (GET_CODE (operands[0]) == MEM
4633 || (GET_CODE (operands[0]) == SUBREG
4634 && GET_CODE (SUBREG_REG (operands[0])) == MEM)
4635 || (reload_in_progress && GET_CODE (operands[0]) == REG
4636 && REGNO (operands[0]) >= FIRST_PSEUDO_REGISTER)
4637 || (reload_in_progress && GET_CODE (operands[0]) == SUBREG
4638 && GET_CODE (SUBREG_REG (operands[0])) == REG
4639 && REGNO (operands[0]) >= FIRST_PSEUDO_REGISTER))
4641 if (aligned_memory_operand (operands[0], QImode))
4643 rtx aligned_mem, bitnum;
4644 rtx temp1 = gen_reg_rtx (SImode);
4645 rtx temp2 = gen_reg_rtx (SImode);
4647 get_aligned_mem (operands[0], &aligned_mem, &bitnum);
4649 emit_insn (gen_aligned_store (aligned_mem, operands[1], bitnum,
4654 rtx temp1 = gen_reg_rtx (DImode);
4655 rtx temp2 = gen_reg_rtx (DImode);
4656 rtx temp3 = gen_reg_rtx (DImode);
4658 = gen_unaligned_storeqi (get_unaligned_address (operands[0], 0),
4659 operands[1], temp1, temp2, temp3);
4661 alpha_set_memflags (seq, operands[0]);
4669 (define_expand "movhi"
4670 [(set (match_operand:HI 0 "general_operand" "")
4671 (match_operand:HI 1 "general_operand" ""))]
4677 if (GET_CODE (operands[0]) == MEM
4678 && ! reg_or_0_operand (operands[1], HImode))
4679 operands[1] = force_reg (HImode, operands[1]);
4681 if (GET_CODE (operands[1]) == CONST_INT
4682 && ! input_operand (operands[1], HImode))
4684 operands[1] = alpha_emit_set_const (operands[0], HImode,
4685 INTVAL (operands[1]), 3);
4687 if (rtx_equal_p (operands[0], operands[1]))
4694 /* If the output is not a register, the input must be. */
4695 if (GET_CODE (operands[0]) == MEM)
4696 operands[1] = force_reg (HImode, operands[1]);
4698 /* Handle four memory cases, unaligned and aligned for either the input
4699 or the output. The only case where we can be called during reload is
4700 for aligned loads; all other cases require temporaries. */
4702 if (GET_CODE (operands[1]) == MEM
4703 || (GET_CODE (operands[1]) == SUBREG
4704 && GET_CODE (SUBREG_REG (operands[1])) == MEM)
4705 || (reload_in_progress && GET_CODE (operands[1]) == REG
4706 && REGNO (operands[1]) >= FIRST_PSEUDO_REGISTER)
4707 || (reload_in_progress && GET_CODE (operands[1]) == SUBREG
4708 && GET_CODE (SUBREG_REG (operands[1])) == REG
4709 && REGNO (SUBREG_REG (operands[1])) >= FIRST_PSEUDO_REGISTER))
4711 if (aligned_memory_operand (operands[1], HImode))
4713 rtx aligned_mem, bitnum;
4714 rtx scratch = (reload_in_progress
4715 ? gen_rtx_REG (SImode, REGNO (operands[0]))
4716 : gen_reg_rtx (SImode));
4718 get_aligned_mem (operands[1], &aligned_mem, &bitnum);
4720 emit_insn (gen_aligned_loadhi (operands[0], aligned_mem, bitnum,
4725 /* Don't pass these as parameters since that makes the generated
4726 code depend on parameter evaluation order which will cause
4727 bootstrap failures. */
4729 rtx temp1 = gen_reg_rtx (DImode);
4730 rtx temp2 = gen_reg_rtx (DImode);
4732 = gen_unaligned_loadhi (operands[0],
4733 get_unaligned_address (operands[1], 0),
4736 alpha_set_memflags (seq, operands[1]);
4743 else if (GET_CODE (operands[0]) == MEM
4744 || (GET_CODE (operands[0]) == SUBREG
4745 && GET_CODE (SUBREG_REG (operands[0])) == MEM)
4746 || (reload_in_progress && GET_CODE (operands[0]) == REG
4747 && REGNO (operands[0]) >= FIRST_PSEUDO_REGISTER)
4748 || (reload_in_progress && GET_CODE (operands[0]) == SUBREG
4749 && GET_CODE (SUBREG_REG (operands[0])) == REG
4750 && REGNO (operands[0]) >= FIRST_PSEUDO_REGISTER))
4752 if (aligned_memory_operand (operands[0], HImode))
4754 rtx aligned_mem, bitnum;
4755 rtx temp1 = gen_reg_rtx (SImode);
4756 rtx temp2 = gen_reg_rtx (SImode);
4758 get_aligned_mem (operands[0], &aligned_mem, &bitnum);
4760 emit_insn (gen_aligned_store (aligned_mem, operands[1], bitnum,
4765 rtx temp1 = gen_reg_rtx (DImode);
4766 rtx temp2 = gen_reg_rtx (DImode);
4767 rtx temp3 = gen_reg_rtx (DImode);
4769 = gen_unaligned_storehi (get_unaligned_address (operands[0], 0),
4770 operands[1], temp1, temp2, temp3);
4772 alpha_set_memflags (seq, operands[0]);
4781 ;; Here are the versions for reload. Note that in the unaligned cases
4782 ;; we know that the operand must not be a pseudo-register because stack
4783 ;; slots are always aligned references.
4785 (define_expand "reload_inqi"
4786 [(parallel [(match_operand:QI 0 "register_operand" "=r")
4787 (match_operand:QI 1 "unaligned_memory_operand" "m")
4788 (match_operand:TI 2 "register_operand" "=&r")])]
4792 rtx addr = get_unaligned_address (operands[1], 0);
4794 /* It is possible that one of the registers we got for operands[2]
4795 might coincide with that of operands[0] (which is why we made
4796 it TImode). Pick the other one to use as our scratch. */
4797 rtx scratch = gen_rtx_REG (DImode,
4798 REGNO (operands[0]) == REGNO (operands[2])
4799 ? REGNO (operands[2]) + 1 : REGNO (operands[2]));
4801 rtx seq = gen_unaligned_loadqi (operands[0], addr, scratch,
4802 gen_rtx_REG (DImode, REGNO (operands[0])));
4804 alpha_set_memflags (seq, operands[1]);
4809 (define_expand "reload_inhi"
4810 [(parallel [(match_operand:HI 0 "register_operand" "=r")
4811 (match_operand:HI 1 "unaligned_memory_operand" "m")
4812 (match_operand:TI 2 "register_operand" "=&r")])]
4816 rtx addr = get_unaligned_address (operands[1], 0);
4818 /* It is possible that one of the registers we got for operands[2]
4819 might coincide with that of operands[0] (which is why we made
4820 it TImode). Pick the other one to use as our scratch. */
4821 rtx scratch = gen_rtx_REG (DImode,
4822 REGNO (operands[0]) == REGNO (operands[2])
4823 ? REGNO (operands[2]) + 1 : REGNO (operands[2]));
4825 rtx seq = gen_unaligned_loadhi (operands[0], addr, scratch,
4826 gen_rtx_REG (DImode, REGNO (operands[0])));
4828 alpha_set_memflags (seq, operands[1]);
4833 (define_expand "reload_outqi"
4834 [(parallel [(match_operand:QI 0 "any_memory_operand" "=m")
4835 (match_operand:QI 1 "register_operand" "r")
4836 (match_operand:TI 2 "register_operand" "=&r")])]
4840 if (aligned_memory_operand (operands[0], QImode))
4842 rtx aligned_mem, bitnum;
4844 get_aligned_mem (operands[0], &aligned_mem, &bitnum);
4846 emit_insn (gen_aligned_store (aligned_mem, operands[1], bitnum,
4847 gen_rtx_REG (SImode, REGNO (operands[2])),
4848 gen_rtx_REG (SImode,
4849 REGNO (operands[2]) + 1)));
4853 rtx addr = get_unaligned_address (operands[0], 0);
4854 rtx scratch1 = gen_rtx_REG (DImode, REGNO (operands[2]));
4855 rtx scratch2 = gen_rtx_REG (DImode, REGNO (operands[2]) + 1);
4856 rtx scratch3 = scratch1;
4859 if (GET_CODE (addr) == REG)
4862 seq = gen_unaligned_storeqi (addr, operands[1], scratch1,
4863 scratch2, scratch3);
4864 alpha_set_memflags (seq, operands[0]);
4871 (define_expand "reload_outhi"
4872 [(parallel [(match_operand:HI 0 "any_memory_operand" "=m")
4873 (match_operand:HI 1 "register_operand" "r")
4874 (match_operand:TI 2 "register_operand" "=&r")])]
4878 if (aligned_memory_operand (operands[0], HImode))
4880 rtx aligned_mem, bitnum;
4882 get_aligned_mem (operands[0], &aligned_mem, &bitnum);
4884 emit_insn (gen_aligned_store (aligned_mem, operands[1], bitnum,
4885 gen_rtx_REG (SImode, REGNO (operands[2])),
4886 gen_rtx_REG (SImode,
4887 REGNO (operands[2]) + 1)));
4891 rtx addr = get_unaligned_address (operands[0], 0);
4892 rtx scratch1 = gen_rtx_REG (DImode, REGNO (operands[2]));
4893 rtx scratch2 = gen_rtx_REG (DImode, REGNO (operands[2]) + 1);
4894 rtx scratch3 = scratch1;
4897 if (GET_CODE (addr) == REG)
4900 seq = gen_unaligned_storehi (addr, operands[1], scratch1,
4901 scratch2, scratch3);
4902 alpha_set_memflags (seq, operands[0]);
4909 ;; Bit field extract patterns which use ext[wlq][lh]
4911 (define_expand "extv"
4912 [(set (match_operand:DI 0 "register_operand" "")
4913 (sign_extract:DI (match_operand:QI 1 "memory_operand" "")
4914 (match_operand:DI 2 "immediate_operand" "")
4915 (match_operand:DI 3 "immediate_operand" "")))]
4919 /* We can do 16, 32 and 64 bit fields, if aligned on byte boundaries. */
4920 if (INTVAL (operands[3]) % 8 != 0
4921 || (INTVAL (operands[2]) != 16
4922 && INTVAL (operands[2]) != 32
4923 && INTVAL (operands[2]) != 64))
4926 /* From mips.md: extract_bit_field doesn't verify that our source
4927 matches the predicate, so we force it to be a MEM here. */
4928 if (GET_CODE (operands[1]) != MEM)
4931 alpha_expand_unaligned_load (operands[0], operands[1],
4932 INTVAL (operands[2]) / 8,
4933 INTVAL (operands[3]) / 8, 1);
4937 (define_expand "extzv"
4938 [(set (match_operand:DI 0 "register_operand" "")
4939 (zero_extract:DI (match_operand:DI 1 "general_operand" "")
4940 (match_operand:DI 2 "immediate_operand" "")
4941 (match_operand:DI 3 "immediate_operand" "")))]
4945 /* We can do 8, 16, 32 and 64 bit fields, if aligned on byte boundaries. */
4946 if (INTVAL (operands[3]) % 8 != 0
4947 || (INTVAL (operands[2]) != 8
4948 && INTVAL (operands[2]) != 16
4949 && INTVAL (operands[2]) != 32
4950 && INTVAL (operands[2]) != 64))
4953 if (GET_CODE (operands[1]) == MEM)
4955 /* Fail 8 bit fields, falling back on a simple byte load. */
4956 if (INTVAL (operands[2]) == 8)
4959 alpha_expand_unaligned_load (operands[0], operands[1],
4960 INTVAL (operands[2]) / 8,
4961 INTVAL (operands[3]) / 8, 0);
4966 (define_expand "insv"
4967 [(set (zero_extract:DI (match_operand:QI 0 "memory_operand" "")
4968 (match_operand:DI 1 "immediate_operand" "")
4969 (match_operand:DI 2 "immediate_operand" ""))
4970 (match_operand:DI 3 "register_operand" ""))]
4974 /* We can do 16, 32 and 64 bit fields, if aligned on byte boundaries. */
4975 if (INTVAL (operands[2]) % 8 != 0
4976 || (INTVAL (operands[1]) != 16
4977 && INTVAL (operands[1]) != 32
4978 && INTVAL (operands[1]) != 64))
4981 /* From mips.md: store_bit_field doesn't verify that our source
4982 matches the predicate, so we force it to be a MEM here. */
4983 if (GET_CODE (operands[0]) != MEM)
4986 alpha_expand_unaligned_store (operands[0], operands[3],
4987 INTVAL (operands[1]) / 8,
4988 INTVAL (operands[2]) / 8);
4994 ;; Block move/clear, see alpha.c for more details.
4995 ;; Argument 0 is the destination
4996 ;; Argument 1 is the source
4997 ;; Argument 2 is the length
4998 ;; Argument 3 is the alignment
5000 (define_expand "movstrqi"
5001 [(parallel [(set (match_operand:BLK 0 "general_operand" "")
5002 (match_operand:BLK 1 "general_operand" ""))
5003 (use (match_operand:DI 2 "immediate_operand" ""))
5004 (use (match_operand:DI 3 "immediate_operand" ""))])]
5008 if (alpha_expand_block_move (operands))
5014 (define_expand "clrstrqi"
5015 [(parallel [(set (match_operand:BLK 0 "general_operand" "")
5017 (use (match_operand:DI 1 "immediate_operand" ""))
5018 (use (match_operand:DI 2 "immediate_operand" ""))])]
5022 if (alpha_expand_block_clear (operands))
5028 ;; Subroutine of stack space allocation. Perform a stack probe.
5029 (define_expand "probe_stack"
5030 [(set (match_dup 1) (match_operand:DI 0 "const_int_operand" ""))]
5034 operands[1] = gen_rtx_MEM (DImode, plus_constant (stack_pointer_rtx,
5035 INTVAL (operands[0])));
5036 MEM_VOLATILE_P (operands[1]) = 1;
5038 operands[0] = const0_rtx;
5041 ;; This is how we allocate stack space. If we are allocating a
5042 ;; constant amount of space and we know it is less than 4096
5043 ;; bytes, we need do nothing.
5045 ;; If it is more than 4096 bytes, we need to probe the stack
5047 (define_expand "allocate_stack"
5049 (plus:DI (reg:DI 30)
5050 (match_operand:DI 1 "reg_or_cint_operand" "")))
5051 (set (match_operand:DI 0 "register_operand" "=r")
5056 if (GET_CODE (operands[1]) == CONST_INT
5057 && INTVAL (operands[1]) < 32768)
5059 if (INTVAL (operands[1]) >= 4096)
5061 /* We do this the same way as in the prologue and generate explicit
5062 probes. Then we update the stack by the constant. */
5066 emit_insn (gen_probe_stack (GEN_INT (- probed)));
5067 while (probed + 8192 < INTVAL (operands[1]))
5068 emit_insn (gen_probe_stack (GEN_INT (- (probed += 8192))));
5070 if (probed + 4096 < INTVAL (operands[1]))
5071 emit_insn (gen_probe_stack (GEN_INT (- INTVAL(operands[1]))));
5074 operands[1] = GEN_INT (- INTVAL (operands[1]));
5075 operands[2] = virtual_stack_dynamic_rtx;
5080 rtx loop_label = gen_label_rtx ();
5081 rtx want = gen_reg_rtx (Pmode);
5082 rtx tmp = gen_reg_rtx (Pmode);
5085 emit_insn (gen_subdi3 (want, stack_pointer_rtx,
5086 force_reg (Pmode, operands[1])));
5087 emit_insn (gen_adddi3 (tmp, stack_pointer_rtx, GEN_INT (-4096)));
5089 if (GET_CODE (operands[1]) != CONST_INT)
5091 out_label = gen_label_rtx ();
5092 emit_insn (gen_cmpdi (want, tmp));
5093 emit_jump_insn (gen_bgeu (out_label));
5096 emit_label (loop_label);
5097 memref = gen_rtx_MEM (DImode, tmp);
5098 MEM_VOLATILE_P (memref) = 1;
5099 emit_move_insn (memref, const0_rtx);
5100 emit_insn (gen_adddi3 (tmp, tmp, GEN_INT(-8192)));
5101 emit_insn (gen_cmpdi (tmp, want));
5102 emit_jump_insn (gen_bgtu (loop_label));
5104 gen_rtx_USE (VOIDmode, tmp);
5106 memref = gen_rtx_MEM (DImode, want);
5107 MEM_VOLATILE_P (memref) = 1;
5108 emit_move_insn (memref, const0_rtx);
5111 emit_label (out_label);
5113 emit_move_insn (stack_pointer_rtx, want);
5114 emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
5119 ;; This is used by alpha_expand_prolog to do the same thing as above,
5120 ;; except we cannot at that time generate new basic blocks, so we hide
5121 ;; the loop in this one insn.
5123 (define_insn "prologue_stack_probe_loop"
5124 [(unspec_volatile [(match_operand 0 "register_operand" "r")
5125 (match_operand 1 "register_operand" "r")] 5)]
5129 static int label_no;
5130 int count_regno = REGNO (operands[0]);
5131 int ptr_regno = REGNO (operands[1]);
5134 /* Ho hum, output the hard way to get the label at the beginning of
5135 the line. Wish there were a magic char you could get
5136 asm_output_printf to do that. Then we could use %= as well and
5137 get rid of the label_no bits here too. */
5139 ASM_GENERATE_INTERNAL_LABEL (label, \"LSC\", label_no);
5140 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, \"LSC\", label_no++);
5142 fprintf (asm_out_file, \"\\tstq $31,-8192($%d)\\n\", ptr_regno);
5143 fprintf (asm_out_file, \"\\tsubq $%d,1,$%d\\n\", count_regno, count_regno);
5144 fprintf (asm_out_file, \"\\tlda $%d,-8192($%d)\\n\", ptr_regno, ptr_regno);
5145 fprintf (asm_out_file, \"\\tbne $%d,\", count_regno);
5146 assemble_name (asm_out_file, label);
5147 putc ('\\n', asm_out_file);
5151 [(set_attr "length" "16")
5152 (set_attr "type" "multi")])
5154 (define_expand "prologue"
5155 [(clobber (const_int 0))]
5157 "alpha_expand_prologue (); DONE;")
5159 (define_insn "init_fp"
5160 [(set (match_operand:DI 0 "register_operand" "r")
5161 (match_operand:DI 1 "register_operand" "r"))
5162 (clobber (mem:BLK (match_operand:DI 2 "register_operand" "r")))]
5166 (define_expand "epilogue"
5167 [(clobber (const_int 0))]
5169 "alpha_expand_epilogue (); DONE;")
5171 (define_expand "eh_epilogue"
5172 [(use (match_operand:DI 0 "register_operand" "r"))
5173 (use (match_operand:DI 1 "register_operand" "r"))
5174 (use (match_operand:DI 2 "register_operand" "r"))]
5178 alpha_eh_epilogue_sp_ofs = operands[1];
5179 if (GET_CODE (operands[2]) != REG || REGNO (operands[2]) != 26)
5181 rtx ra = gen_rtx_REG (Pmode, 26);
5182 emit_move_insn (ra, operands[2]);
5187 (define_expand "builtin_longjmp"
5188 [(unspec_volatile [(match_operand 0 "register_operand" "r")] 3)]
5189 "! TARGET_OPEN_VMS && ! TARGET_WINDOWS_NT"
5192 /* The elements of the buffer are, in order: */
5193 rtx fp = gen_rtx_MEM (Pmode, operands[0]);
5194 rtx lab = gen_rtx_MEM (Pmode, plus_constant (operands[0], 8));
5195 rtx stack = gen_rtx_MEM (Pmode, plus_constant (operands[0], 16));
5196 rtx pv = gen_rtx_REG (Pmode, 27);
5198 /* This bit is the same as expand_builtin_longjmp. */
5199 emit_move_insn (hard_frame_pointer_rtx, fp);
5200 emit_move_insn (pv, lab);
5201 emit_stack_restore (SAVE_NONLOCAL, stack, NULL_RTX);
5202 emit_insn (gen_rtx_USE (VOIDmode, hard_frame_pointer_rtx));
5203 emit_insn (gen_rtx_USE (VOIDmode, stack_pointer_rtx));
5205 /* Load the label we are jumping through into $27 so that we know
5206 where to look for it when we get back to setjmp's function for
5207 restoring the gp. */
5208 emit_indirect_jump (pv);
5211 (define_insn "builtin_setjmp_receiver"
5212 [(unspec_volatile [(match_operand 0 "" "")] 2)]
5213 "! TARGET_OPEN_VMS && ! TARGET_WINDOWS_NT && TARGET_AS_CAN_SUBTRACT_LABELS"
5214 "\\n$LSJ%=:\;ldgp $29,$LSJ%=-%l0($27)"
5215 [(set_attr "length" "8")
5216 (set_attr "type" "multi")])
5219 [(unspec_volatile [(match_operand 0 "" "")] 2)]
5220 "! TARGET_OPEN_VMS && ! TARGET_WINDOWS_NT"
5221 "br $29,$LSJ%=\\n$LSJ%=:\;ldgp $29,0($29)"
5222 [(set_attr "length" "12")
5223 (set_attr "type" "multi")])
5225 (define_insn "exception_receiver"
5226 [(unspec_volatile [(const_int 0)] 7)]
5227 "! TARGET_OPEN_VMS && ! TARGET_WINDOWS_NT"
5228 "br $29,$LSJ%=\\n$LSJ%=:\;ldgp $29,0($29)"
5229 [(set_attr "length" "12")
5230 (set_attr "type" "multi")])
5232 (define_expand "nonlocal_goto_receiver"
5233 [(unspec_volatile [(const_int 0)] 1)
5234 (set (reg:DI 27) (mem:DI (reg:DI 29)))
5235 (unspec_volatile [(const_int 0)] 1)
5240 (define_insn "arg_home"
5241 [(unspec [(const_int 0)] 0)
5256 (clobber (mem:BLK (const_int 0)))
5257 (clobber (reg:DI 24))
5258 (clobber (reg:DI 25))
5259 (clobber (reg:DI 0))]
5261 "lda $0,OTS$HOME_ARGS\;ldq $0,8($0)\;jsr $0,OTS$HOME_ARGS"
5262 [(set_attr "length" "16")
5263 (set_attr "type" "multi")])
5265 ;; Close the trap shadow of preceeding instructions. This is generated
5268 (define_insn "trapb"
5269 [(unspec_volatile [(const_int 0)] 4)]
5272 [(set_attr "type" "misc")])
5274 ;; No-op instructions used by machine-dependant reorg to preserve
5275 ;; alignment for instruction issue.
5281 [(set_attr "type" "ilog")])
5287 [(set_attr "type" "fcpys")])
5294 (define_insn "realign"
5295 [(unspec_volatile [(match_operand 0 "immediate_operand" "i")] 6)]
5297 ".align %0 #realign")
5299 ;; Peepholes go at the end.
5301 ;; Optimize sign-extension of SImode loads. This shows up in the wake of
5302 ;; reload when converting fp->int.
5304 ;; ??? What to do now that we actually care about the packing and
5305 ;; alignment of instructions? Perhaps reload can be enlightened, or
5306 ;; the peephole pass moved up after reload but before sched2?
5309 ; [(set (match_operand:SI 0 "register_operand" "=r")
5310 ; (match_operand:SI 1 "memory_operand" "m"))
5311 ; (set (match_operand:DI 2 "register_operand" "=r")
5312 ; (sign_extend:DI (match_dup 0)))]
5313 ; "dead_or_set_p (insn, operands[0])"
5317 ; [(set (match_operand:SI 0 "register_operand" "=r")
5318 ; (match_operand:SI 1 "hard_fp_register_operand" "f"))
5319 ; (set (match_operand:DI 2 "register_operand" "=r")
5320 ; (sign_extend:DI (match_dup 0)))]
5321 ; "TARGET_CIX && dead_or_set_p (insn, operands[0])"