1 ;; Machine description for DEC Alpha for GNU C compiler
2 ;; Copyright (C) 1992, 93-98, 1999 Free Software Foundation, Inc.
3 ;; Contributed by Richard Kenner (kenner@vlsi1.ultra.nyu.edu)
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 (define_function_unit "ev5_ebox" 2 0
159 (and (eq_attr "cpu" "ev5")
160 (eq_attr "type" "ild,fld,ldsym"))
163 ; Loads can dual issue with one another, but loads and stores do not mix.
164 (define_function_unit "ev5_e0" 1 0
165 (and (eq_attr "cpu" "ev5")
166 (eq_attr "type" "ild,fld,ldsym"))
168 [(eq_attr "type" "ist,fst")])
170 ; Stores, shifts, multiplies can only issue to E0
171 (define_function_unit "ev5_e0" 1 0
172 (and (eq_attr "cpu" "ev5")
173 (eq_attr "type" "ist,fst,shift,imul"))
176 ; Motion video insns also issue only to E0, and take two ticks.
177 (define_function_unit "ev5_e0" 1 0
178 (and (eq_attr "cpu" "ev5")
179 (eq_attr "type" "mvi"))
182 ; Conditional moves always take 2 ticks.
183 (define_function_unit "ev5_ebox" 2 0
184 (and (eq_attr "cpu" "ev5")
185 (eq_attr "type" "icmov"))
188 ; Branches can only issue to E1
189 (define_function_unit "ev5_e1" 1 0
190 (and (eq_attr "cpu" "ev5")
191 (eq_attr "type" "ibr,jsr"))
194 ; Multiplies also use the integer multiplier.
195 ; ??? How to: "No instruction can be issued to pipe E0 exactly two
196 ; cycles before an integer multiplication completes."
197 (define_function_unit "imul" 1 0
198 (and (eq_attr "cpu" "ev5")
199 (and (eq_attr "type" "imul")
200 (eq_attr "opsize" "si")))
203 (define_function_unit "imul" 1 0
204 (and (eq_attr "cpu" "ev5")
205 (and (eq_attr "type" "imul")
206 (eq_attr "opsize" "di")))
209 (define_function_unit "imul" 1 0
210 (and (eq_attr "cpu" "ev5")
211 (and (eq_attr "type" "imul")
212 (eq_attr "opsize" "udi")))
215 ;; Similarly for the FPU we have two asymetric units. But fcpys can issue
216 ;; on either so we have to play the game again.
218 (define_function_unit "ev5_fbox" 2 0
219 (and (eq_attr "cpu" "ev5")
220 (eq_attr "type" "fadd,fcmov,fmul,fcpys,fbr,fdiv"))
223 (define_function_unit "ev5_fm" 1 0
224 (and (eq_attr "cpu" "ev5")
225 (eq_attr "type" "fmul"))
228 ; Add and cmov as you would expect; fbr never produces a result;
229 ; fdiv issues through fa to the divider,
230 (define_function_unit "ev5_fa" 1 0
231 (and (eq_attr "cpu" "ev5")
232 (eq_attr "type" "fadd,fcmov,fbr,fdiv"))
235 ; ??? How to: "No instruction can be issued to pipe FA exactly five
236 ; cycles before a floating point divide completes."
237 (define_function_unit "fdiv" 1 0
238 (and (eq_attr "cpu" "ev5")
239 (and (eq_attr "type" "fdiv")
240 (eq_attr "opsize" "si")))
241 15 15) ; 15 to 31 data dependant
243 (define_function_unit "fdiv" 1 0
244 (and (eq_attr "cpu" "ev5")
245 (and (eq_attr "type" "fdiv")
246 (eq_attr "opsize" "di")))
247 22 22) ; 22 to 60 data dependant
249 ;; EV6 scheduling. EV6 can issue 4 insns per clock.
251 ;; EV6 has two symmetric pairs ("clusters") of two asymetric integer units
252 ;; ("upper" and "lower"), yielding pipe names U0, U1, L0, L1.
254 ;; Conditional moves decompose into two independant primitives, each
255 ;; taking one cycle. Since ev6 is out-of-order, we can't see anything
257 (define_function_unit "ev6_ebox" 4 0
258 (and (eq_attr "cpu" "ev6")
259 (eq_attr "type" "icmov"))
262 (define_function_unit "ev6_ebox" 4 0
263 (and (eq_attr "cpu" "ev6")
264 (eq_attr "type" "!fbr,fcmov,fadd,fmul,fcpys,fdiv,fsqrt"))
267 ;; Integer loads take at least 3 clocks, and only issue to lower units.
268 ;; Return one from here and fix up with user-defined latencies in adjust_cost.
269 (define_function_unit "ev6_l" 2 0
270 (and (eq_attr "cpu" "ev6")
271 (eq_attr "type" "ild,ldsym,ist,fst"))
274 ;; FP loads take at least 4 clocks. Return two from here...
275 (define_function_unit "ev6_l" 2 0
276 (and (eq_attr "cpu" "ev6")
277 (eq_attr "type" "fld"))
280 ;; Motion video insns also issue only to U0, and take three ticks.
281 (define_function_unit "ev6_u0" 1 0
282 (and (eq_attr "cpu" "ev6")
283 (eq_attr "type" "mvi"))
286 (define_function_unit "ev6_u" 2 0
287 (and (eq_attr "cpu" "ev6")
288 (eq_attr "type" "mvi"))
291 ;; Shifts issue to either upper pipe.
292 (define_function_unit "ev6_u" 2 0
293 (and (eq_attr "cpu" "ev6")
294 (eq_attr "type" "shift"))
297 ;; Multiplies issue only to U1, and all take 7 ticks.
298 ;; Rather than create a new function unit just for U1, reuse IMUL
299 (define_function_unit "imul" 1 0
300 (and (eq_attr "cpu" "ev6")
301 (eq_attr "type" "imul"))
304 (define_function_unit "ev6_u" 2 0
305 (and (eq_attr "cpu" "ev6")
306 (eq_attr "type" "imul"))
309 ;; Branches issue to either upper pipe
310 (define_function_unit "ev6_u" 2 0
311 (and (eq_attr "cpu" "ev6")
312 (eq_attr "type" "ibr"))
315 ;; Calls only issue to L0.
316 (define_function_unit "ev6_l0" 1 0
317 (and (eq_attr "cpu" "ev6")
318 (eq_attr "type" "jsr"))
321 (define_function_unit "ev6_l" 2 0
322 (and (eq_attr "cpu" "ev6")
323 (eq_attr "type" "jsr"))
326 ;; Ftoi/itof only issue to lower pipes
327 (define_function_unit "ev6_l" 2 0
328 (and (eq_attr "cpu" "ev6")
329 (eq_attr "type" "ftoi"))
332 (define_function_unit "ev6_l" 2 0
333 (and (eq_attr "cpu" "ev6")
334 (eq_attr "type" "itof"))
337 ;; For the FPU we are very similar to EV5, except there's no insn that
338 ;; can issue to fm & fa, so we get to leave that out.
340 (define_function_unit "ev6_fm" 1 0
341 (and (eq_attr "cpu" "ev6")
342 (eq_attr "type" "fmul"))
345 (define_function_unit "ev6_fa" 1 0
346 (and (eq_attr "cpu" "ev6")
347 (eq_attr "type" "fadd,fcpys,fbr,fdiv,fsqrt"))
350 (define_function_unit "ev6_fa" 1 0
351 (and (eq_attr "cpu" "ev6")
352 (eq_attr "type" "fcmov"))
355 (define_function_unit "fdiv" 1 0
356 (and (eq_attr "cpu" "ev6")
357 (and (eq_attr "type" "fdiv")
358 (eq_attr "opsize" "si")))
361 (define_function_unit "fdiv" 1 0
362 (and (eq_attr "cpu" "ev6")
363 (and (eq_attr "type" "fdiv")
364 (eq_attr "opsize" "di")))
367 (define_function_unit "fsqrt" 1 0
368 (and (eq_attr "cpu" "ev6")
369 (and (eq_attr "type" "fsqrt")
370 (eq_attr "opsize" "si")))
373 (define_function_unit "fsqrt" 1 0
374 (and (eq_attr "cpu" "ev6")
375 (and (eq_attr "type" "fsqrt")
376 (eq_attr "opsize" "di")))
379 ; ??? The FPU communicates with memory and the integer register file
380 ; via two fp store units. We need a slot in the fst immediately, and
381 ; a slot in LOW after the operand data is ready. At which point the
382 ; data may be moved either to the store queue or the integer register
383 ; file and the insn retired.
386 ;; First define the arithmetic insns. Note that the 32-bit forms also
389 ;; Handle 32-64 bit extension from memory to a floating point register
390 ;; specially, since this ocurrs frequently in int->double conversions.
392 ;; Note that while we must retain the =f case in the insn for reload's
393 ;; benefit, it should be eliminated after reload, so we should never emit
394 ;; code for that case. But we don't reject the possibility.
396 (define_expand "extendsidi2"
397 [(set (match_operand:DI 0 "register_operand" "")
398 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "")))]
403 [(set (match_operand:DI 0 "register_operand" "=r,r,*f,?*f")
405 (match_operand:SI 1 "nonimmediate_operand" "r,m,*f,m")))]
411 lds %0,%1\;cvtlq %0,%0"
412 [(set_attr "type" "iadd,ild,fadd,fld")
413 (set_attr "length" "*,*,*,8")])
416 [(set (match_operand:DI 0 "register_operand" "=r,r,r,*f,?*f")
418 (match_operand:SI 1 "nonimmediate_operand" "r,m,*f,*f,m")))]
425 lds %0,%1\;cvtlq %0,%0"
426 [(set_attr "type" "iadd,ild,ftoi,fadd,fld")
427 (set_attr "length" "*,*,*,*,8")])
429 ;; Due to issues with CLASS_CANNOT_CHANGE_SIZE, we cannot use a subreg here.
431 [(set (match_operand:DI 0 "hard_fp_register_operand" "")
432 (sign_extend:DI (match_operand:SI 1 "memory_operand" "")))]
434 [(set (match_dup 2) (match_dup 1))
435 (set (match_dup 0) (sign_extend:DI (match_dup 2)))]
436 "operands[2] = gen_rtx_REG (SImode, REGNO (operands[0]));")
438 ;; Do addsi3 the way expand_binop would do if we didn't have one. This
439 ;; generates better code. We have the anonymous addsi3 pattern below in
440 ;; case combine wants to make it.
441 (define_expand "addsi3"
442 [(set (match_operand:SI 0 "register_operand" "")
443 (plus:SI (match_operand:SI 1 "reg_or_0_operand" "")
444 (match_operand:SI 2 "add_operand" "")))]
450 rtx op1 = gen_lowpart (DImode, operands[1]);
451 rtx op2 = gen_lowpart (DImode, operands[2]);
453 if (! cse_not_expected)
455 rtx tmp = gen_reg_rtx (DImode);
456 emit_insn (gen_adddi3 (tmp, op1, op2));
457 emit_move_insn (gen_lowpart (DImode, operands[0]), tmp);
460 emit_insn (gen_adddi3 (gen_lowpart (DImode, operands[0]), op1, op2));
466 [(set (match_operand:SI 0 "register_operand" "=r,r,r,r")
467 (plus:SI (match_operand:SI 1 "reg_or_0_operand" "%rJ,rJ,rJ,rJ")
468 (match_operand:SI 2 "add_operand" "rI,O,K,L")))]
477 [(set (match_operand:SI 0 "register_operand" "")
478 (plus:SI (match_operand:SI 1 "register_operand" "")
479 (match_operand:SI 2 "const_int_operand" "")))]
480 "! add_operand (operands[2], SImode)"
481 [(set (match_dup 0) (plus:SI (match_dup 1) (match_dup 3)))
482 (set (match_dup 0) (plus:SI (match_dup 0) (match_dup 4)))]
485 HOST_WIDE_INT val = INTVAL (operands[2]);
486 HOST_WIDE_INT low = (val & 0xffff) - 2 * (val & 0x8000);
487 HOST_WIDE_INT rest = val - low;
489 operands[3] = GEN_INT (rest);
490 operands[4] = GEN_INT (low);
494 [(set (match_operand:DI 0 "register_operand" "=r,r")
496 (plus:SI (match_operand:SI 1 "reg_or_0_operand" "%rJ,rJ")
497 (match_operand:SI 2 "sext_add_operand" "rI,O"))))]
504 [(set (match_operand:DI 0 "register_operand" "")
506 (plus:SI (match_operand:SI 1 "reg_not_elim_operand" "")
507 (match_operand:SI 2 "const_int_operand" ""))))
508 (clobber (match_operand:SI 3 "reg_not_elim_operand" ""))]
509 "! sext_add_operand (operands[2], SImode) && INTVAL (operands[2]) > 0
510 && INTVAL (operands[2]) % 4 == 0"
511 [(set (match_dup 3) (match_dup 4))
512 (set (match_dup 0) (sign_extend:DI (plus:SI (mult:SI (match_dup 3)
517 HOST_WIDE_INT val = INTVAL (operands[2]) / 4;
523 operands[4] = GEN_INT (val);
524 operands[5] = GEN_INT (mult);
528 [(set (match_operand:DI 0 "register_operand" "")
530 (plus:SI (match_operator:SI 1 "comparison_operator"
531 [(match_operand 2 "" "")
532 (match_operand 3 "" "")])
533 (match_operand:SI 4 "add_operand" ""))))
534 (clobber (match_operand:DI 5 "register_operand" ""))]
536 [(set (match_dup 5) (match_dup 6))
537 (set (match_dup 0) (sign_extend:DI (plus:SI (match_dup 7) (match_dup 4))))]
540 operands[6] = gen_rtx_fmt_ee (GET_CODE (operands[1]), DImode,
541 operands[2], operands[3]);
542 operands[7] = gen_lowpart (SImode, operands[5]);
545 (define_expand "adddi3"
546 [(set (match_operand:DI 0 "register_operand" "")
547 (plus:DI (match_operand:DI 1 "register_operand" "")
548 (match_operand:DI 2 "add_operand" "")))]
552 ;; This pattern exists so that register elimination tries to canonize
553 ;; (plus (plus reg c1) c2).
556 [(set (match_operand:DI 0 "register_operand" "=r")
557 (match_operand:DI 1 "addition_operation" "p"))]
561 ;; We used to expend quite a lot of effort choosing addq/subq/lda.
562 ;; With complications like
564 ;; The NT stack unwind code can't handle a subq to adjust the stack
565 ;; (that's a bug, but not one we can do anything about). As of NT4.0 SP3,
566 ;; the exception handling code will loop if a subq is used and an
569 ;; The 19980616 change to emit prologues as RTL also confused some
570 ;; versions of GDB, which also interprets prologues. This has been
571 ;; fixed as of GDB 4.18, but it does not harm to unconditionally
574 ;; and the fact that the three insns schedule exactly the same, it's
575 ;; just not worth the effort.
577 (define_insn "*adddi_2"
578 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
579 (plus:DI (match_operand:DI 1 "register_operand" "%r,r,r")
580 (match_operand:DI 2 "add_operand" "r,K,L")))]
587 ;; ??? Allow large constants when basing off the frame pointer or some
588 ;; virtual register that may eliminate to the frame pointer. This is
589 ;; done because register elimination offsets will change the hi/lo split,
590 ;; and if we split before reload, we will require additional instructions.
593 [(set (match_operand:DI 0 "register_operand" "=r")
594 (plus:DI (match_operand:DI 1 "reg_no_subreg_operand" "r")
595 (match_operand:DI 2 "const_int_operand" "n")))]
596 "REG_OK_FP_BASE_P (operands[1])
597 && INTVAL (operands[2]) >= 0
598 /* This is the largest constant an lda+ldah pair can add, minus
599 an upper bound on the displacement between SP and AP during
600 register elimination. See INITIAL_ELIMINATION_OFFSET. */
601 && INTVAL (operands[2])
603 - FIRST_PSEUDO_REGISTER * UNITS_PER_WORD
604 - ALPHA_ROUND(current_function_outgoing_args_size)
605 - (ALPHA_ROUND (get_frame_size ()
606 + max_reg_num () * UNITS_PER_WORD
607 + current_function_pretend_args_size)
608 - current_function_pretend_args_size))"
611 ;; Don't do this if we are adjusting SP since we don't want to do it
612 ;; in two steps. Don't split FP sources for the reason listed above.
614 [(set (match_operand:DI 0 "register_operand" "")
615 (plus:DI (match_operand:DI 1 "register_operand" "")
616 (match_operand:DI 2 "const_int_operand" "")))]
617 "! add_operand (operands[2], DImode)
618 && operands[0] != stack_pointer_rtx
619 && operands[1] != frame_pointer_rtx
620 && operands[1] != arg_pointer_rtx"
621 [(set (match_dup 0) (plus:DI (match_dup 1) (match_dup 3)))
622 (set (match_dup 0) (plus:DI (match_dup 0) (match_dup 4)))]
625 HOST_WIDE_INT val = INTVAL (operands[2]);
626 HOST_WIDE_INT low = (val & 0xffff) - 2 * (val & 0x8000);
627 HOST_WIDE_INT rest = val - low;
629 operands[4] = GEN_INT (low);
630 if (CONST_OK_FOR_LETTER_P (rest, 'L'))
631 operands[3] = GEN_INT (rest);
632 else if (! no_new_pseudos)
634 operands[3] = gen_reg_rtx (DImode);
635 emit_move_insn (operands[3], operands[2]);
636 emit_insn (gen_adddi3 (operands[0], operands[1], operands[3]));
644 [(set (match_operand:SI 0 "register_operand" "=r,r")
645 (plus:SI (mult:SI (match_operand:SI 1 "reg_not_elim_operand" "r,r")
646 (match_operand:SI 2 "const48_operand" "I,I"))
647 (match_operand:SI 3 "sext_add_operand" "rI,O")))]
654 [(set (match_operand:DI 0 "register_operand" "=r,r")
656 (plus:SI (mult:SI (match_operand:SI 1 "reg_not_elim_operand" "r,r")
657 (match_operand:SI 2 "const48_operand" "I,I"))
658 (match_operand:SI 3 "sext_add_operand" "rI,O"))))]
665 [(set (match_operand:DI 0 "register_operand" "")
667 (plus:SI (mult:SI (match_operator:SI 1 "comparison_operator"
668 [(match_operand 2 "" "")
669 (match_operand 3 "" "")])
670 (match_operand:SI 4 "const48_operand" ""))
671 (match_operand:SI 5 "sext_add_operand" ""))))
672 (clobber (match_operand:DI 6 "reg_not_elim_operand" ""))]
674 [(set (match_dup 6) (match_dup 7))
676 (sign_extend:DI (plus:SI (mult:SI (match_dup 8) (match_dup 4))
680 operands[7] = gen_rtx_fmt_ee (GET_CODE (operands[1]), DImode,
681 operands[2], operands[3]);
682 operands[8] = gen_lowpart (SImode, operands[6]);
686 [(set (match_operand:DI 0 "register_operand" "=r,r")
687 (plus:DI (mult:DI (match_operand:DI 1 "reg_not_elim_operand" "r,r")
688 (match_operand:DI 2 "const48_operand" "I,I"))
689 (match_operand:DI 3 "sext_add_operand" "rI,O")))]
695 (define_insn "negsi2"
696 [(set (match_operand:SI 0 "register_operand" "=r")
697 (neg:SI (match_operand:SI 1 "reg_or_8bit_operand" "rI")))]
702 [(set (match_operand:DI 0 "register_operand" "=r")
703 (sign_extend:DI (neg:SI
704 (match_operand:SI 1 "reg_or_8bit_operand" "rI"))))]
708 (define_insn "negdi2"
709 [(set (match_operand:DI 0 "register_operand" "=r")
710 (neg:DI (match_operand:DI 1 "reg_or_8bit_operand" "rI")))]
714 (define_expand "subsi3"
715 [(set (match_operand:SI 0 "register_operand" "")
716 (minus:SI (match_operand:SI 1 "reg_or_0_operand" "")
717 (match_operand:SI 2 "reg_or_8bit_operand" "")))]
723 rtx op1 = gen_lowpart (DImode, operands[1]);
724 rtx op2 = gen_lowpart (DImode, operands[2]);
726 if (! cse_not_expected)
728 rtx tmp = gen_reg_rtx (DImode);
729 emit_insn (gen_subdi3 (tmp, op1, op2));
730 emit_move_insn (gen_lowpart (DImode, operands[0]), tmp);
733 emit_insn (gen_subdi3 (gen_lowpart (DImode, operands[0]), op1, op2));
739 [(set (match_operand:SI 0 "register_operand" "=r")
740 (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rJ")
741 (match_operand:SI 2 "reg_or_8bit_operand" "rI")))]
746 [(set (match_operand:DI 0 "register_operand" "=r")
747 (sign_extend:DI (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rJ")
748 (match_operand:SI 2 "reg_or_8bit_operand" "rI"))))]
752 (define_insn "subdi3"
753 [(set (match_operand:DI 0 "register_operand" "=r")
754 (minus:DI (match_operand:DI 1 "reg_or_0_operand" "rJ")
755 (match_operand:DI 2 "reg_or_8bit_operand" "rI")))]
760 [(set (match_operand:SI 0 "register_operand" "=r")
761 (minus:SI (mult:SI (match_operand:SI 1 "reg_not_elim_operand" "r")
762 (match_operand:SI 2 "const48_operand" "I"))
763 (match_operand:SI 3 "reg_or_8bit_operand" "rI")))]
768 [(set (match_operand:DI 0 "register_operand" "=r")
770 (minus:SI (mult:SI (match_operand:SI 1 "reg_not_elim_operand" "r")
771 (match_operand:SI 2 "const48_operand" "I"))
772 (match_operand:SI 3 "reg_or_8bit_operand" "rI"))))]
777 [(set (match_operand:DI 0 "register_operand" "=r")
778 (minus:DI (mult:DI (match_operand:DI 1 "reg_not_elim_operand" "r")
779 (match_operand:DI 2 "const48_operand" "I"))
780 (match_operand:DI 3 "reg_or_8bit_operand" "rI")))]
784 (define_insn "mulsi3"
785 [(set (match_operand:SI 0 "register_operand" "=r")
786 (mult:SI (match_operand:SI 1 "reg_or_0_operand" "%rJ")
787 (match_operand:SI 2 "reg_or_8bit_operand" "rI")))]
790 [(set_attr "type" "imul")
791 (set_attr "opsize" "si")])
794 [(set (match_operand:DI 0 "register_operand" "=r")
796 (mult:SI (match_operand:SI 1 "reg_or_0_operand" "%rJ")
797 (match_operand:SI 2 "reg_or_8bit_operand" "rI"))))]
800 [(set_attr "type" "imul")
801 (set_attr "opsize" "si")])
803 (define_insn "muldi3"
804 [(set (match_operand:DI 0 "register_operand" "=r")
805 (mult:DI (match_operand:DI 1 "reg_or_0_operand" "%rJ")
806 (match_operand:DI 2 "reg_or_8bit_operand" "rI")))]
809 [(set_attr "type" "imul")])
811 (define_insn "umuldi3_highpart"
812 [(set (match_operand:DI 0 "register_operand" "=r")
815 (mult:TI (zero_extend:TI
816 (match_operand:DI 1 "reg_or_0_operand" "%rJ"))
818 (match_operand:DI 2 "reg_or_8bit_operand" "rI")))
822 [(set_attr "type" "imul")
823 (set_attr "opsize" "udi")])
826 [(set (match_operand:DI 0 "register_operand" "=r")
829 (mult:TI (zero_extend:TI (match_operand:DI 1 "register_operand" "r"))
830 (match_operand:TI 2 "cint8_operand" "I"))
834 [(set_attr "type" "imul")
835 (set_attr "opsize" "udi")])
837 ;; The divide and remainder operations always take their inputs from
838 ;; r24 and r25, put their output in r27, and clobber r23 and r28.
840 ;; ??? Force sign-extension here because some versions of OSF/1 don't
841 ;; do the right thing if the inputs are not properly sign-extended.
842 ;; But Linux, for instance, does not have this problem. Is it worth
843 ;; the complication here to eliminate the sign extension?
844 ;; Interix/NT has the same sign-extension problem.
846 (define_expand "divsi3"
848 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "")))
850 (sign_extend:DI (match_operand:SI 2 "nonimmediate_operand" "")))
851 (parallel [(set (reg:DI 27)
852 (sign_extend:DI (div:SI (reg:DI 24) (reg:DI 25))))
853 (clobber (reg:DI 23))
854 (clobber (reg:DI 28))])
855 (set (match_operand:SI 0 "nonimmediate_operand" "")
856 (subreg:SI (reg:DI 27) 0))]
860 (define_expand "udivsi3"
862 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "")))
864 (sign_extend:DI (match_operand:SI 2 "nonimmediate_operand" "")))
865 (parallel [(set (reg:DI 27)
866 (sign_extend:DI (udiv:SI (reg:DI 24) (reg:DI 25))))
867 (clobber (reg:DI 23))
868 (clobber (reg:DI 28))])
869 (set (match_operand:SI 0 "nonimmediate_operand" "")
870 (subreg:SI (reg:DI 27) 0))]
874 (define_expand "modsi3"
876 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "")))
878 (sign_extend:DI (match_operand:SI 2 "nonimmediate_operand" "")))
879 (parallel [(set (reg:DI 27)
880 (sign_extend:DI (mod:SI (reg:DI 24) (reg:DI 25))))
881 (clobber (reg:DI 23))
882 (clobber (reg:DI 28))])
883 (set (match_operand:SI 0 "nonimmediate_operand" "")
884 (subreg:SI (reg:DI 27) 0))]
888 (define_expand "umodsi3"
890 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "")))
892 (sign_extend:DI (match_operand:SI 2 "nonimmediate_operand" "")))
893 (parallel [(set (reg:DI 27)
894 (sign_extend:DI (umod:SI (reg:DI 24) (reg:DI 25))))
895 (clobber (reg:DI 23))
896 (clobber (reg:DI 28))])
897 (set (match_operand:SI 0 "nonimmediate_operand" "")
898 (subreg:SI (reg:DI 27) 0))]
902 (define_expand "divdi3"
903 [(set (reg:DI 24) (match_operand:DI 1 "input_operand" ""))
904 (set (reg:DI 25) (match_operand:DI 2 "input_operand" ""))
905 (parallel [(set (reg:DI 27)
908 (clobber (reg:DI 23))
909 (clobber (reg:DI 28))])
910 (set (match_operand:DI 0 "nonimmediate_operand" "")
915 (define_expand "udivdi3"
916 [(set (reg:DI 24) (match_operand:DI 1 "input_operand" ""))
917 (set (reg:DI 25) (match_operand:DI 2 "input_operand" ""))
918 (parallel [(set (reg:DI 27)
921 (clobber (reg:DI 23))
922 (clobber (reg:DI 28))])
923 (set (match_operand:DI 0 "nonimmediate_operand" "")
928 (define_expand "moddi3"
929 [(set (reg:DI 24) (match_operand:DI 1 "input_operand" ""))
930 (set (reg:DI 25) (match_operand:DI 2 "input_operand" ""))
931 (parallel [(set (reg:DI 27)
934 (clobber (reg:DI 23))
935 (clobber (reg:DI 28))])
936 (set (match_operand:DI 0 "nonimmediate_operand" "")
941 (define_expand "umoddi3"
942 [(set (reg:DI 24) (match_operand:DI 1 "input_operand" ""))
943 (set (reg:DI 25) (match_operand:DI 2 "input_operand" ""))
944 (parallel [(set (reg:DI 27)
947 (clobber (reg:DI 23))
948 (clobber (reg:DI 28))])
949 (set (match_operand:DI 0 "nonimmediate_operand" "")
954 ;; Lengths of 8 for ldq $t12,__divq($gp); jsr $t9,($t12),__divq as
955 ;; expanded by the assembler.
958 (sign_extend:DI (match_operator:SI 1 "divmod_operator"
959 [(reg:DI 24) (reg:DI 25)])))
960 (clobber (reg:DI 23))
961 (clobber (reg:DI 28))]
964 [(set_attr "type" "jsr")
965 (set_attr "length" "8")])
969 (match_operator:DI 1 "divmod_operator"
970 [(reg:DI 24) (reg:DI 25)]))
971 (clobber (reg:DI 23))
972 (clobber (reg:DI 28))]
975 [(set_attr "type" "jsr")
976 (set_attr "length" "8")])
978 ;; Next are the basic logical operations. These only exist in DImode.
980 (define_insn "anddi3"
981 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
982 (and:DI (match_operand:DI 1 "reg_or_0_operand" "%rJ,rJ,rJ")
983 (match_operand:DI 2 "and_operand" "rI,N,MH")))]
989 [(set_attr "type" "ilog,ilog,shift")])
991 ;; There are times when we can split an AND into two AND insns. This occurs
992 ;; when we can first clear any bytes and then clear anything else. For
993 ;; example "I & 0xffff07" is "(I & 0xffffff) & 0xffffffffffffff07".
994 ;; Only do this when running on 64-bit host since the computations are
995 ;; too messy otherwise.
998 [(set (match_operand:DI 0 "register_operand" "")
999 (and:DI (match_operand:DI 1 "register_operand" "")
1000 (match_operand:DI 2 "const_int_operand" "")))]
1001 "HOST_BITS_PER_WIDE_INT == 64 && ! and_operand (operands[2], DImode)"
1002 [(set (match_dup 0) (and:DI (match_dup 1) (match_dup 3)))
1003 (set (match_dup 0) (and:DI (match_dup 0) (match_dup 4)))]
1006 unsigned HOST_WIDE_INT mask1 = INTVAL (operands[2]);
1007 unsigned HOST_WIDE_INT mask2 = mask1;
1010 /* For each byte that isn't all zeros, make it all ones. */
1011 for (i = 0; i < 64; i += 8)
1012 if ((mask1 & ((HOST_WIDE_INT) 0xff << i)) != 0)
1013 mask1 |= (HOST_WIDE_INT) 0xff << i;
1015 /* Now turn on any bits we've just turned off. */
1018 operands[3] = GEN_INT (mask1);
1019 operands[4] = GEN_INT (mask2);
1022 (define_insn "zero_extendqihi2"
1023 [(set (match_operand:HI 0 "register_operand" "=r")
1024 (zero_extend:HI (match_operand:QI 1 "register_operand" "r")))]
1027 [(set_attr "type" "ilog")])
1030 [(set (match_operand:SI 0 "register_operand" "=r,r")
1031 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "r,m")))]
1036 [(set_attr "type" "ilog,ild")])
1039 [(set (match_operand:SI 0 "register_operand" "=r")
1040 (zero_extend:SI (match_operand:QI 1 "register_operand" "r")))]
1043 [(set_attr "type" "ilog")])
1045 (define_expand "zero_extendqisi2"
1046 [(set (match_operand:SI 0 "register_operand" "")
1047 (zero_extend:SI (match_operand:QI 1 "register_operand" "")))]
1052 [(set (match_operand:DI 0 "register_operand" "=r,r")
1053 (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand" "r,m")))]
1058 [(set_attr "type" "ilog,ild")])
1061 [(set (match_operand:DI 0 "register_operand" "=r")
1062 (zero_extend:DI (match_operand:QI 1 "register_operand" "r")))]
1065 [(set_attr "type" "ilog")])
1067 (define_expand "zero_extendqidi2"
1068 [(set (match_operand:DI 0 "register_operand" "")
1069 (zero_extend:DI (match_operand:QI 1 "register_operand" "")))]
1074 [(set (match_operand:SI 0 "register_operand" "=r,r")
1075 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "r,m")))]
1080 [(set_attr "type" "shift,ild")])
1083 [(set (match_operand:SI 0 "register_operand" "=r")
1084 (zero_extend:SI (match_operand:HI 1 "register_operand" "r")))]
1087 [(set_attr "type" "shift")])
1089 (define_expand "zero_extendhisi2"
1090 [(set (match_operand:SI 0 "register_operand" "")
1091 (zero_extend:SI (match_operand:HI 1 "register_operand" "")))]
1096 [(set (match_operand:DI 0 "register_operand" "=r,r")
1097 (zero_extend:DI (match_operand:HI 1 "nonimmediate_operand" "r,m")))]
1102 [(set_attr "type" "shift,ild")])
1105 [(set (match_operand:DI 0 "register_operand" "=r")
1106 (zero_extend:DI (match_operand:HI 1 "register_operand" "r")))]
1109 [(set_attr "type" "shift")])
1111 (define_expand "zero_extendhidi2"
1112 [(set (match_operand:DI 0 "register_operand" "")
1113 (zero_extend:DI (match_operand:HI 1 "register_operand" "")))]
1117 (define_insn "zero_extendsidi2"
1118 [(set (match_operand:DI 0 "register_operand" "=r")
1119 (zero_extend:DI (match_operand:SI 1 "register_operand" "r")))]
1122 [(set_attr "type" "shift")])
1125 [(set (match_operand:DI 0 "register_operand" "=r")
1126 (and:DI (not:DI (match_operand:DI 1 "reg_or_8bit_operand" "rI"))
1127 (match_operand:DI 2 "reg_or_0_operand" "rJ")))]
1130 [(set_attr "type" "ilog")])
1132 (define_insn "iordi3"
1133 [(set (match_operand:DI 0 "register_operand" "=r,r")
1134 (ior:DI (match_operand:DI 1 "reg_or_0_operand" "%rJ,rJ")
1135 (match_operand:DI 2 "or_operand" "rI,N")))]
1140 [(set_attr "type" "ilog")])
1142 (define_insn "one_cmpldi2"
1143 [(set (match_operand:DI 0 "register_operand" "=r")
1144 (not:DI (match_operand:DI 1 "reg_or_8bit_operand" "rI")))]
1147 [(set_attr "type" "ilog")])
1150 [(set (match_operand:DI 0 "register_operand" "=r")
1151 (ior:DI (not:DI (match_operand:DI 1 "reg_or_8bit_operand" "rI"))
1152 (match_operand:DI 2 "reg_or_0_operand" "rJ")))]
1155 [(set_attr "type" "ilog")])
1157 (define_insn "xordi3"
1158 [(set (match_operand:DI 0 "register_operand" "=r,r")
1159 (xor:DI (match_operand:DI 1 "reg_or_0_operand" "%rJ,rJ")
1160 (match_operand:DI 2 "or_operand" "rI,N")))]
1165 [(set_attr "type" "ilog")])
1168 [(set (match_operand:DI 0 "register_operand" "=r")
1169 (not:DI (xor:DI (match_operand:DI 1 "register_operand" "%rJ")
1170 (match_operand:DI 2 "register_operand" "rI"))))]
1173 [(set_attr "type" "ilog")])
1175 ;; Handle the FFS insn iff we support CIX.
1177 ;; These didn't make it into EV6 pass 2 as planned. Instead they
1178 ;; cropped cttz/ctlz/ctpop from the old CIX and renamed it FIX for
1179 ;; "Square Root and Floating Point Convert Extension".
1181 ;; I'm assured that these insns will make it into EV67 (first pass
1182 ;; due Summer 1999), presumably with a new AMASK bit, and presumably
1183 ;; will still be named CIX.
1185 (define_expand "ffsdi2"
1187 (unspec:DI [(match_operand:DI 1 "register_operand" "")] 1))
1189 (plus:DI (match_dup 2) (const_int 1)))
1190 (set (match_operand:DI 0 "register_operand" "")
1191 (if_then_else:DI (eq (match_dup 1) (const_int 0))
1192 (const_int 0) (match_dup 3)))]
1196 operands[2] = gen_reg_rtx (DImode);
1197 operands[3] = gen_reg_rtx (DImode);
1201 [(set (match_operand:DI 0 "register_operand" "=r")
1202 (unspec:DI [(match_operand:DI 1 "register_operand" "r")] 1))]
1205 ; EV6 calls all mvi and cttz/ctlz/popc class imisc, so just
1206 ; reuse the existing type name.
1207 [(set_attr "type" "mvi")])
1209 ;; Next come the shifts and the various extract and insert operations.
1211 (define_insn "ashldi3"
1212 [(set (match_operand:DI 0 "register_operand" "=r,r")
1213 (ashift:DI (match_operand:DI 1 "reg_or_0_operand" "rJ,rJ")
1214 (match_operand:DI 2 "reg_or_6bit_operand" "P,rS")))]
1218 switch (which_alternative)
1221 if (operands[2] == const1_rtx)
1222 return \"addq %r1,%r1,%0\";
1224 return \"s%P2addq %r1,0,%0\";
1226 return \"sll %r1,%2,%0\";
1231 [(set_attr "type" "iadd,shift")])
1233 ;; ??? The following pattern is made by combine, but earlier phases
1234 ;; (specifically flow) can't handle it. This occurs in jump.c. Deal
1235 ;; with this in a better way at some point.
1237 ;; [(set (match_operand:DI 0 "register_operand" "=r")
1239 ;; (subreg:SI (ashift:DI (match_operand:DI 1 "reg_or_0_operand" "rJ")
1240 ;; (match_operand:DI 2 "const_int_operand" "P"))
1242 ;; "INTVAL (operands[2]) >= 1 && INTVAL (operands[2]) <= 3"
1245 ;; if (operands[2] == const1_rtx)
1246 ;; return \"addl %r1,%r1,%0\";
1248 ;; return \"s%P2addl %r1,0,%0\";
1250 ;; [(set_attr "type" "iadd")])
1252 (define_insn "lshrdi3"
1253 [(set (match_operand:DI 0 "register_operand" "=r")
1254 (lshiftrt:DI (match_operand:DI 1 "reg_or_0_operand" "rJ")
1255 (match_operand:DI 2 "reg_or_6bit_operand" "rS")))]
1258 [(set_attr "type" "shift")])
1260 (define_insn "ashrdi3"
1261 [(set (match_operand:DI 0 "register_operand" "=r")
1262 (ashiftrt:DI (match_operand:DI 1 "reg_or_0_operand" "rJ")
1263 (match_operand:DI 2 "reg_or_6bit_operand" "rS")))]
1266 [(set_attr "type" "shift")])
1268 (define_expand "extendqihi2"
1270 (ashift:DI (match_operand:QI 1 "some_operand" "")
1272 (set (match_operand:HI 0 "register_operand" "")
1273 (ashiftrt:DI (match_dup 2)
1280 emit_insn (gen_extendqihi2x (operands[0],
1281 force_reg (QImode, operands[1])));
1285 /* If we have an unaligned MEM, extend to DImode (which we do
1286 specially) and then copy to the result. */
1287 if (unaligned_memory_operand (operands[1], HImode))
1289 rtx temp = gen_reg_rtx (DImode);
1291 emit_insn (gen_extendqidi2 (temp, operands[1]));
1292 emit_move_insn (operands[0], gen_lowpart (HImode, temp));
1296 operands[0] = gen_lowpart (DImode, operands[0]);
1297 operands[1] = gen_lowpart (DImode, force_reg (QImode, operands[1]));
1298 operands[2] = gen_reg_rtx (DImode);
1301 (define_insn "extendqidi2x"
1302 [(set (match_operand:DI 0 "register_operand" "=r")
1303 (sign_extend:DI (match_operand:QI 1 "register_operand" "r")))]
1306 [(set_attr "type" "shift")])
1308 (define_insn "extendhidi2x"
1309 [(set (match_operand:DI 0 "register_operand" "=r")
1310 (sign_extend:DI (match_operand:HI 1 "register_operand" "r")))]
1313 [(set_attr "type" "shift")])
1315 (define_insn "extendqisi2x"
1316 [(set (match_operand:SI 0 "register_operand" "=r")
1317 (sign_extend:SI (match_operand:QI 1 "register_operand" "r")))]
1320 [(set_attr "type" "shift")])
1322 (define_insn "extendhisi2x"
1323 [(set (match_operand:SI 0 "register_operand" "=r")
1324 (sign_extend:SI (match_operand:HI 1 "register_operand" "r")))]
1327 [(set_attr "type" "shift")])
1329 (define_insn "extendqihi2x"
1330 [(set (match_operand:HI 0 "register_operand" "=r")
1331 (sign_extend:HI (match_operand:QI 1 "register_operand" "r")))]
1334 [(set_attr "type" "shift")])
1336 (define_expand "extendqisi2"
1338 (ashift:DI (match_operand:QI 1 "some_operand" "")
1340 (set (match_operand:SI 0 "register_operand" "")
1341 (ashiftrt:DI (match_dup 2)
1348 emit_insn (gen_extendqisi2x (operands[0],
1349 force_reg (QImode, operands[1])));
1353 /* If we have an unaligned MEM, extend to a DImode form of
1354 the result (which we do specially). */
1355 if (unaligned_memory_operand (operands[1], QImode))
1357 rtx temp = gen_reg_rtx (DImode);
1359 emit_insn (gen_extendqidi2 (temp, operands[1]));
1360 emit_move_insn (operands[0], gen_lowpart (SImode, temp));
1364 operands[0] = gen_lowpart (DImode, operands[0]);
1365 operands[1] = gen_lowpart (DImode, force_reg (QImode, operands[1]));
1366 operands[2] = gen_reg_rtx (DImode);
1369 (define_expand "extendqidi2"
1371 (ashift:DI (match_operand:QI 1 "some_operand" "")
1373 (set (match_operand:DI 0 "register_operand" "")
1374 (ashiftrt:DI (match_dup 2)
1381 emit_insn (gen_extendqidi2x (operands[0],
1382 force_reg (QImode, operands[1])));
1386 if (unaligned_memory_operand (operands[1], QImode))
1389 = gen_unaligned_extendqidi (operands[0],
1390 get_unaligned_address (operands[1], 1));
1392 alpha_set_memflags (seq, operands[1]);
1397 operands[1] = gen_lowpart (DImode, force_reg (QImode, operands[1]));
1398 operands[2] = gen_reg_rtx (DImode);
1401 (define_expand "extendhisi2"
1403 (ashift:DI (match_operand:HI 1 "some_operand" "")
1405 (set (match_operand:SI 0 "register_operand" "")
1406 (ashiftrt:DI (match_dup 2)
1413 emit_insn (gen_extendhisi2x (operands[0],
1414 force_reg (HImode, operands[1])));
1418 /* If we have an unaligned MEM, extend to a DImode form of
1419 the result (which we do specially). */
1420 if (unaligned_memory_operand (operands[1], HImode))
1422 rtx temp = gen_reg_rtx (DImode);
1424 emit_insn (gen_extendhidi2 (temp, operands[1]));
1425 emit_move_insn (operands[0], gen_lowpart (SImode, temp));
1429 operands[0] = gen_lowpart (DImode, operands[0]);
1430 operands[1] = gen_lowpart (DImode, force_reg (HImode, operands[1]));
1431 operands[2] = gen_reg_rtx (DImode);
1434 (define_expand "extendhidi2"
1436 (ashift:DI (match_operand:HI 1 "some_operand" "")
1438 (set (match_operand:DI 0 "register_operand" "")
1439 (ashiftrt:DI (match_dup 2)
1446 emit_insn (gen_extendhidi2x (operands[0],
1447 force_reg (HImode, operands[1])));
1451 if (unaligned_memory_operand (operands[1], HImode))
1454 = gen_unaligned_extendhidi (operands[0],
1455 get_unaligned_address (operands[1], 2));
1457 alpha_set_memflags (seq, operands[1]);
1462 operands[1] = gen_lowpart (DImode, force_reg (HImode, operands[1]));
1463 operands[2] = gen_reg_rtx (DImode);
1466 ;; Here's how we sign extend an unaligned byte and halfword. Doing this
1467 ;; as a pattern saves one instruction. The code is similar to that for
1468 ;; the unaligned loads (see below).
1470 ;; Operand 1 is the address + 1 (+2 for HI), operand 0 is the result.
1471 (define_expand "unaligned_extendqidi"
1472 [(set (match_dup 2) (match_operand:DI 1 "address_operand" ""))
1474 (mem:DI (and:DI (plus:DI (match_dup 2) (const_int -1))
1477 (ashift:DI (match_dup 3)
1478 (minus:DI (const_int 64)
1480 (and:DI (match_dup 2) (const_int 7))
1482 (set (subreg:DI (match_operand:QI 0 "register_operand" "") 0)
1483 (ashiftrt:DI (match_dup 4) (const_int 56)))]
1486 { operands[2] = gen_reg_rtx (DImode);
1487 operands[3] = gen_reg_rtx (DImode);
1488 operands[4] = gen_reg_rtx (DImode);
1491 (define_expand "unaligned_extendhidi"
1492 [(set (match_dup 2) (match_operand:DI 1 "address_operand" ""))
1494 (mem:DI (and:DI (plus:DI (match_dup 2) (const_int -2))
1497 (ashift:DI (match_dup 3)
1498 (minus:DI (const_int 64)
1500 (and:DI (match_dup 2) (const_int 7))
1502 (set (subreg:DI (match_operand:QI 0 "register_operand" "") 0)
1503 (ashiftrt:DI (match_dup 4) (const_int 48)))]
1506 { operands[2] = gen_reg_rtx (DImode);
1507 operands[3] = gen_reg_rtx (DImode);
1508 operands[4] = gen_reg_rtx (DImode);
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 (match_operand:DI 3 "mul8_operand" "I")))]
1517 "ext%M2l %r1,%s3,%0"
1518 [(set_attr "type" "shift")])
1520 (define_insn "extxl"
1521 [(set (match_operand:DI 0 "register_operand" "=r")
1522 (zero_extract:DI (match_operand:DI 1 "reg_or_0_operand" "rJ")
1523 (match_operand:DI 2 "mode_width_operand" "n")
1524 (ashift:DI (match_operand:DI 3 "reg_or_8bit_operand" "rI")
1528 [(set_attr "type" "shift")])
1530 ;; Combine has some strange notion of preserving existing undefined behaviour
1531 ;; in shifts larger than a word size. So capture these patterns that it
1532 ;; should have turned into zero_extracts.
1535 [(set (match_operand:DI 0 "register_operand" "=r")
1536 (and:DI (lshiftrt:DI (match_operand:DI 1 "reg_or_0_operand" "rJ")
1537 (ashift:DI (match_operand:DI 2 "reg_or_8bit_operand" "rI")
1539 (match_operand:DI 3 "mode_mask_operand" "n")))]
1542 [(set_attr "type" "shift")])
1545 [(set (match_operand:DI 0 "register_operand" "=r")
1546 (lshiftrt:DI (match_operand:DI 1 "reg_or_0_operand" "rJ")
1547 (ashift:DI (match_operand:DI 2 "reg_or_8bit_operand" "rI")
1551 [(set_attr "type" "shift")])
1553 (define_insn "extqh"
1554 [(set (match_operand:DI 0 "register_operand" "=r")
1556 (match_operand:DI 1 "reg_or_0_operand" "rJ")
1557 (minus:DI (const_int 64)
1560 (match_operand:DI 2 "reg_or_8bit_operand" "rI")
1565 [(set_attr "type" "shift")])
1567 (define_insn "extlh"
1568 [(set (match_operand:DI 0 "register_operand" "=r")
1570 (and:DI (match_operand:DI 1 "reg_or_0_operand" "rJ")
1571 (const_int 2147483647))
1572 (minus:DI (const_int 64)
1575 (match_operand:DI 2 "reg_or_8bit_operand" "rI")
1580 [(set_attr "type" "shift")])
1582 (define_insn "extwh"
1583 [(set (match_operand:DI 0 "register_operand" "=r")
1585 (and:DI (match_operand:DI 1 "reg_or_0_operand" "rJ")
1587 (minus:DI (const_int 64)
1590 (match_operand:DI 2 "reg_or_8bit_operand" "rI")
1595 [(set_attr "type" "shift")])
1597 ;; This converts an extXl into an extXh with an appropriate adjustment
1598 ;; to the address calculation.
1601 ;; [(set (match_operand:DI 0 "register_operand" "")
1602 ;; (ashift:DI (zero_extract:DI (match_operand:DI 1 "register_operand" "")
1603 ;; (match_operand:DI 2 "mode_width_operand" "")
1604 ;; (ashift:DI (match_operand:DI 3 "" "")
1606 ;; (match_operand:DI 4 "const_int_operand" "")))
1607 ;; (clobber (match_operand:DI 5 "register_operand" ""))]
1608 ;; "INTVAL (operands[4]) == 64 - INTVAL (operands[2])"
1609 ;; [(set (match_dup 5) (match_dup 6))
1610 ;; (set (match_dup 0)
1611 ;; (ashift:DI (zero_extract:DI (match_dup 1) (match_dup 2)
1612 ;; (ashift:DI (plus:DI (match_dup 5)
1618 ;; operands[6] = plus_constant (operands[3],
1619 ;; INTVAL (operands[2]) / BITS_PER_UNIT);
1620 ;; operands[7] = GEN_INT (- INTVAL (operands[2]) / BITS_PER_UNIT);
1624 [(set (match_operand:DI 0 "register_operand" "=r")
1625 (ashift:DI (zero_extend:DI (match_operand:QI 1 "register_operand" "r"))
1626 (match_operand:DI 2 "mul8_operand" "I")))]
1629 [(set_attr "type" "shift")])
1632 [(set (match_operand:DI 0 "register_operand" "=r")
1633 (ashift:DI (zero_extend:DI (match_operand:HI 1 "register_operand" "r"))
1634 (match_operand:DI 2 "mul8_operand" "I")))]
1637 [(set_attr "type" "shift")])
1640 [(set (match_operand:DI 0 "register_operand" "=r")
1641 (ashift:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
1642 (match_operand:DI 2 "mul8_operand" "I")))]
1645 [(set_attr "type" "shift")])
1647 (define_insn "insbl"
1648 [(set (match_operand:DI 0 "register_operand" "=r")
1649 (ashift:DI (zero_extend:DI (match_operand:QI 1 "register_operand" "r"))
1650 (ashift:DI (match_operand:DI 2 "reg_or_8bit_operand" "rI")
1654 [(set_attr "type" "shift")])
1656 (define_insn "inswl"
1657 [(set (match_operand:DI 0 "register_operand" "=r")
1658 (ashift:DI (zero_extend:DI (match_operand:HI 1 "register_operand" "r"))
1659 (ashift:DI (match_operand:DI 2 "reg_or_8bit_operand" "rI")
1663 [(set_attr "type" "shift")])
1665 (define_insn "insll"
1666 [(set (match_operand:DI 0 "register_operand" "=r")
1667 (ashift:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
1668 (ashift:DI (match_operand:DI 2 "reg_or_8bit_operand" "rI")
1672 [(set_attr "type" "shift")])
1674 (define_insn "insql"
1675 [(set (match_operand:DI 0 "register_operand" "=r")
1676 (ashift:DI (match_operand:DI 1 "register_operand" "r")
1677 (ashift:DI (match_operand:DI 2 "reg_or_8bit_operand" "rI")
1681 [(set_attr "type" "shift")])
1683 ;; Combine has this sometimes habit of moving the and outside of the
1684 ;; shift, making life more interesting.
1687 [(set (match_operand:DI 0 "register_operand" "=r")
1688 (and:DI (ashift:DI (match_operand:DI 1 "register_operand" "r")
1689 (match_operand:DI 2 "mul8_operand" "I"))
1690 (match_operand:DI 3 "immediate_operand" "i")))]
1691 "HOST_BITS_PER_WIDE_INT == 64
1692 && GET_CODE (operands[3]) == CONST_INT
1693 && (((unsigned HOST_WIDE_INT) 0xff << INTVAL (operands[2])
1694 == (unsigned HOST_WIDE_INT) INTVAL (operands[3]))
1695 || ((unsigned HOST_WIDE_INT) 0xffff << INTVAL (operands[2])
1696 == (unsigned HOST_WIDE_INT) INTVAL (operands[3]))
1697 || ((unsigned HOST_WIDE_INT) 0xffffffff << INTVAL (operands[2])
1698 == (unsigned HOST_WIDE_INT) INTVAL (operands[3])))"
1701 #if HOST_BITS_PER_WIDE_INT == 64
1702 if ((unsigned HOST_WIDE_INT) 0xff << INTVAL (operands[2])
1703 == (unsigned HOST_WIDE_INT) INTVAL (operands[3]))
1704 return \"insbl %1,%s2,%0\";
1705 if ((unsigned HOST_WIDE_INT) 0xffff << INTVAL (operands[2])
1706 == (unsigned HOST_WIDE_INT) INTVAL (operands[3]))
1707 return \"inswl %1,%s2,%0\";
1708 if ((unsigned HOST_WIDE_INT) 0xffffffff << INTVAL (operands[2])
1709 == (unsigned HOST_WIDE_INT) INTVAL (operands[3]))
1710 return \"insll %1,%s2,%0\";
1714 [(set_attr "type" "shift")])
1716 ;; We do not include the insXh insns because they are complex to express
1717 ;; and it does not appear that we would ever want to generate them.
1719 ;; Since we need them for block moves, though, cop out and use unspec.
1721 (define_insn "insxh"
1722 [(set (match_operand:DI 0 "register_operand" "=r")
1723 (unspec:DI [(match_operand:DI 1 "register_operand" "r")
1724 (match_operand:DI 2 "mode_width_operand" "n")
1725 (match_operand:DI 3 "reg_or_8bit_operand" "rI")] 2))]
1728 [(set_attr "type" "shift")])
1730 (define_insn "mskxl"
1731 [(set (match_operand:DI 0 "register_operand" "=r")
1732 (and:DI (not:DI (ashift:DI
1733 (match_operand:DI 2 "mode_mask_operand" "n")
1735 (match_operand:DI 3 "reg_or_8bit_operand" "rI")
1737 (match_operand:DI 1 "reg_or_0_operand" "rJ")))]
1740 [(set_attr "type" "shift")])
1742 ;; We do not include the mskXh insns because it does not appear we would
1743 ;; ever generate one.
1745 ;; Again, we do for block moves and we use unspec again.
1747 (define_insn "mskxh"
1748 [(set (match_operand:DI 0 "register_operand" "=r")
1749 (unspec:DI [(match_operand:DI 1 "register_operand" "r")
1750 (match_operand:DI 2 "mode_width_operand" "n")
1751 (match_operand:DI 3 "reg_or_8bit_operand" "rI")] 3))]
1754 [(set_attr "type" "shift")])
1756 ;; Floating-point operations. All the double-precision insns can extend
1757 ;; from single, so indicate that. The exception are the ones that simply
1758 ;; play with the sign bits; it's not clear what to do there.
1760 (define_insn "abssf2"
1761 [(set (match_operand:SF 0 "register_operand" "=f")
1762 (abs:SF (match_operand:SF 1 "reg_or_fp0_operand" "fG")))]
1765 [(set_attr "type" "fcpys")])
1767 (define_insn "absdf2"
1768 [(set (match_operand:DF 0 "register_operand" "=f")
1769 (abs:DF (match_operand:DF 1 "reg_or_fp0_operand" "fG")))]
1772 [(set_attr "type" "fcpys")])
1774 (define_insn "negsf2"
1775 [(set (match_operand:SF 0 "register_operand" "=f")
1776 (neg:SF (match_operand:SF 1 "reg_or_fp0_operand" "fG")))]
1779 [(set_attr "type" "fadd")])
1781 (define_insn "negdf2"
1782 [(set (match_operand:DF 0 "register_operand" "=f")
1783 (neg:DF (match_operand:DF 1 "reg_or_fp0_operand" "fG")))]
1786 [(set_attr "type" "fadd")])
1789 [(set (match_operand:SF 0 "register_operand" "=&f")
1790 (plus:SF (match_operand:SF 1 "reg_or_fp0_operand" "%fG")
1791 (match_operand:SF 2 "reg_or_fp0_operand" "fG")))]
1792 "TARGET_FP && alpha_fptm >= ALPHA_FPTM_SU"
1793 "add%,%)%& %R1,%R2,%0"
1794 [(set_attr "type" "fadd")
1795 (set_attr "trap" "yes")])
1797 (define_insn "addsf3"
1798 [(set (match_operand:SF 0 "register_operand" "=f")
1799 (plus:SF (match_operand:SF 1 "reg_or_fp0_operand" "%fG")
1800 (match_operand:SF 2 "reg_or_fp0_operand" "fG")))]
1802 "add%,%)%& %R1,%R2,%0"
1803 [(set_attr "type" "fadd")
1804 (set_attr "trap" "yes")])
1807 [(set (match_operand:DF 0 "register_operand" "=&f")
1808 (plus:DF (match_operand:DF 1 "reg_or_fp0_operand" "%fG")
1809 (match_operand:DF 2 "reg_or_fp0_operand" "fG")))]
1810 "TARGET_FP && alpha_fptm >= ALPHA_FPTM_SU"
1811 "add%-%)%& %R1,%R2,%0"
1812 [(set_attr "type" "fadd")
1813 (set_attr "trap" "yes")])
1815 (define_insn "adddf3"
1816 [(set (match_operand:DF 0 "register_operand" "=f")
1817 (plus:DF (match_operand:DF 1 "reg_or_fp0_operand" "%fG")
1818 (match_operand:DF 2 "reg_or_fp0_operand" "fG")))]
1820 "add%-%)%& %R1,%R2,%0"
1821 [(set_attr "type" "fadd")
1822 (set_attr "trap" "yes")])
1825 [(set (match_operand:DF 0 "register_operand" "=f")
1826 (plus:DF (float_extend:DF
1827 (match_operand:SF 1 "reg_or_fp0_operand" "fG"))
1828 (match_operand:DF 2 "reg_or_fp0_operand" "fG")))]
1829 "TARGET_FP && alpha_fptm < ALPHA_FPTM_SU"
1830 "add%-%)%& %R1,%R2,%0"
1831 [(set_attr "type" "fadd")
1832 (set_attr "trap" "yes")])
1835 [(set (match_operand:DF 0 "register_operand" "=f")
1836 (plus:DF (float_extend:DF
1837 (match_operand:SF 1 "reg_or_fp0_operand" "%fG"))
1839 (match_operand:SF 2 "reg_or_fp0_operand" "fG"))))]
1840 "TARGET_FP && alpha_fptm < ALPHA_FPTM_SU"
1841 "add%-%)%& %R1,%R2,%0"
1842 [(set_attr "type" "fadd")
1843 (set_attr "trap" "yes")])
1845 (define_expand "addtf3"
1846 [(use (match_operand 0 "register_operand" ""))
1847 (use (match_operand 1 "general_operand" ""))
1848 (use (match_operand 2 "general_operand" ""))]
1849 "TARGET_HAS_XFLOATING_LIBS"
1850 "alpha_emit_xfloating_arith (PLUS, operands); DONE;")
1852 ;; Define conversion operators between DFmode and SImode, using the cvtql
1853 ;; instruction. To allow combine et al to do useful things, we keep the
1854 ;; operation as a unit until after reload, at which point we split the
1857 ;; Note that we (attempt to) only consider this optimization when the
1858 ;; ultimate destination is memory. If we will be doing further integer
1859 ;; processing, it is cheaper to do the truncation in the int regs.
1861 (define_insn "*cvtql"
1862 [(set (match_operand:SI 0 "register_operand" "=f")
1863 (unspec:SI [(match_operand:DI 1 "reg_or_fp0_operand" "fG")] 5))]
1866 [(set_attr "type" "fadd")
1867 (set_attr "trap" "yes")])
1870 [(set (match_operand:SI 0 "memory_operand" "")
1871 (subreg:SI (fix:DI (match_operand:DF 1 "reg_or_fp0_operand" "")) 0))
1872 (clobber (match_scratch:DI 2 ""))
1873 (clobber (match_scratch:SI 3 ""))]
1874 "TARGET_FP && reload_completed"
1875 [(set (match_dup 2) (fix:DI (match_dup 1)))
1876 (set (match_dup 3) (unspec:SI [(match_dup 2)] 5))
1877 (set (match_dup 0) (match_dup 3))]
1881 [(set (match_operand:SI 0 "memory_operand" "")
1882 (subreg:SI (fix:DI (match_operand:DF 1 "reg_or_fp0_operand" "")) 0))
1883 (clobber (match_scratch:DI 2 ""))]
1884 "TARGET_FP && reload_completed"
1885 [(set (match_dup 2) (fix:DI (match_dup 1)))
1886 (set (match_dup 3) (unspec:SI [(match_dup 2)] 5))
1887 (set (match_dup 0) (match_dup 3))]
1888 ;; Due to REG_CANNOT_CHANGE_SIZE issues, we cannot simply use SUBREG.
1889 "operands[3] = gen_rtx_REG (SImode, REGNO (operands[2]));")
1892 [(set (match_operand:SI 0 "memory_operand" "=m")
1893 (subreg:SI (fix:DI (match_operand:DF 1 "reg_or_fp0_operand" "fG")) 0))
1894 (clobber (match_scratch:DI 2 "=&f"))
1895 (clobber (match_scratch:SI 3 "=&f"))]
1896 "TARGET_FP && alpha_fptm >= ALPHA_FPTM_SU"
1898 [(set_attr "type" "fadd")
1899 (set_attr "trap" "yes")])
1902 [(set (match_operand:SI 0 "memory_operand" "=m")
1903 (subreg:SI (fix:DI (match_operand:DF 1 "reg_or_fp0_operand" "fG")) 0))
1904 (clobber (match_scratch:DI 2 "=f"))]
1905 "TARGET_FP && alpha_fptm < ALPHA_FPTM_SU"
1907 [(set_attr "type" "fadd")
1908 (set_attr "trap" "yes")])
1911 [(set (match_operand:DI 0 "reg_no_subreg_operand" "=&f")
1912 (fix:DI (match_operand:DF 1 "reg_or_fp0_operand" "fG")))]
1913 "TARGET_FP && alpha_fptm >= ALPHA_FPTM_SU"
1915 [(set_attr "type" "fadd")
1916 (set_attr "trap" "yes")])
1918 (define_insn "fix_truncdfdi2"
1919 [(set (match_operand:DI 0 "reg_no_subreg_operand" "=f")
1920 (fix:DI (match_operand:DF 1 "reg_or_fp0_operand" "fG")))]
1923 [(set_attr "type" "fadd")
1924 (set_attr "trap" "yes")])
1926 ;; Likewise between SFmode and SImode.
1929 [(set (match_operand:SI 0 "memory_operand" "")
1930 (subreg:SI (fix:DI (float_extend:DF
1931 (match_operand:SF 1 "reg_or_fp0_operand" ""))) 0))
1932 (clobber (match_scratch:DI 2 ""))
1933 (clobber (match_scratch:SI 3 ""))]
1934 "TARGET_FP && reload_completed"
1935 [(set (match_dup 2) (fix:DI (float_extend:DF (match_dup 1))))
1936 (set (match_dup 3) (unspec:SI [(match_dup 2)] 5))
1937 (set (match_dup 0) (match_dup 3))]
1941 [(set (match_operand:SI 0 "memory_operand" "")
1942 (subreg:SI (fix:DI (float_extend:DF
1943 (match_operand:SF 1 "reg_or_fp0_operand" ""))) 0))
1944 (clobber (match_scratch:DI 2 ""))]
1945 "TARGET_FP && reload_completed"
1946 [(set (match_dup 2) (fix:DI (float_extend:DF (match_dup 1))))
1947 (set (match_dup 3) (unspec:SI [(match_dup 2)] 5))
1948 (set (match_dup 0) (match_dup 3))]
1949 ;; Due to REG_CANNOT_CHANGE_SIZE issues, we cannot simply use SUBREG.
1950 "operands[3] = gen_rtx_REG (SImode, REGNO (operands[2]));")
1953 [(set (match_operand:SI 0 "memory_operand" "=m")
1954 (subreg:SI (fix:DI (float_extend:DF
1955 (match_operand:SF 1 "reg_or_fp0_operand" "fG"))) 0))
1956 (clobber (match_scratch:DI 2 "=&f"))
1957 (clobber (match_scratch:SI 3 "=&f"))]
1958 "TARGET_FP && alpha_fptm >= ALPHA_FPTM_SU"
1960 [(set_attr "type" "fadd")
1961 (set_attr "trap" "yes")])
1964 [(set (match_operand:SI 0 "memory_operand" "=m")
1965 (subreg:SI (fix:DI (float_extend:DF
1966 (match_operand:SF 1 "reg_or_fp0_operand" "fG"))) 0))
1967 (clobber (match_scratch:DI 2 "=f"))]
1968 "TARGET_FP && alpha_fptm < ALPHA_FPTM_SU"
1970 [(set_attr "type" "fadd")
1971 (set_attr "trap" "yes")])
1974 [(set (match_operand:DI 0 "reg_no_subreg_operand" "=&f")
1975 (fix:DI (float_extend:DF
1976 (match_operand:SF 1 "reg_or_fp0_operand" "fG"))))]
1977 "TARGET_FP && alpha_fptm >= ALPHA_FPTM_SU"
1979 [(set_attr "type" "fadd")
1980 (set_attr "trap" "yes")])
1982 (define_insn "fix_truncsfdi2"
1983 [(set (match_operand:DI 0 "reg_no_subreg_operand" "=f")
1984 (fix:DI (float_extend:DF
1985 (match_operand:SF 1 "reg_or_fp0_operand" "fG"))))]
1988 [(set_attr "type" "fadd")
1989 (set_attr "trap" "yes")])
1991 (define_expand "fix_trunctfdi2"
1992 [(use (match_operand:DI 0 "register_operand" ""))
1993 (use (match_operand:TF 1 "general_operand" ""))]
1994 "TARGET_HAS_XFLOATING_LIBS"
1995 "alpha_emit_xfloating_cvt (FIX, operands); DONE;")
1998 [(set (match_operand:SF 0 "register_operand" "=&f")
1999 (float:SF (match_operand:DI 1 "reg_no_subreg_operand" "f")))]
2000 "TARGET_FP && alpha_fptm >= ALPHA_FPTM_SU"
2002 [(set_attr "type" "fadd")
2003 (set_attr "trap" "yes")])
2005 (define_insn "floatdisf2"
2006 [(set (match_operand:SF 0 "register_operand" "=f")
2007 (float:SF (match_operand:DI 1 "reg_no_subreg_operand" "f")))]
2010 [(set_attr "type" "fadd")
2011 (set_attr "trap" "yes")])
2014 [(set (match_operand:DF 0 "register_operand" "=&f")
2015 (float:DF (match_operand:DI 1 "reg_no_subreg_operand" "f")))]
2016 "TARGET_FP && alpha_fptm >= ALPHA_FPTM_SU"
2018 [(set_attr "type" "fadd")
2019 (set_attr "trap" "yes")])
2021 (define_insn "floatdidf2"
2022 [(set (match_operand:DF 0 "register_operand" "=f")
2023 (float:DF (match_operand:DI 1 "reg_no_subreg_operand" "f")))]
2026 [(set_attr "type" "fadd")
2027 (set_attr "trap" "yes")])
2029 (define_expand "floatditf2"
2030 [(use (match_operand:TF 0 "register_operand" ""))
2031 (use (match_operand:DI 1 "general_operand" ""))]
2032 "TARGET_HAS_XFLOATING_LIBS"
2033 "alpha_emit_xfloating_cvt (FLOAT, operands); DONE;")
2035 (define_expand "floatunsditf2"
2036 [(use (match_operand:TF 0 "register_operand" ""))
2037 (use (match_operand:DI 1 "general_operand" ""))]
2038 "TARGET_HAS_XFLOATING_LIBS"
2039 "alpha_emit_xfloating_cvt (UNSIGNED_FLOAT, operands); DONE;")
2041 (define_expand "extendsfdf2"
2042 [(use (match_operand:DF 0 "register_operand" ""))
2043 (use (match_operand:SF 1 "nonimmediate_operand" ""))]
2047 if (alpha_fptm >= ALPHA_FPTM_SU)
2048 emit_insn (gen_extendsfdf2_tp (operands[0],
2049 force_reg (SFmode, operands[1])));
2051 emit_insn (gen_extendsfdf2_no_tp (operands[0], operands[1]));
2056 (define_insn "extendsfdf2_tp"
2057 [(set (match_operand:DF 0 "register_operand" "=&f")
2058 (float_extend:DF (match_operand:SF 1 "register_operand" "f")))]
2059 "TARGET_FP && alpha_fptm >= ALPHA_FPTM_SU"
2061 [(set_attr "type" "fadd")
2062 (set_attr "trap" "yes")])
2064 (define_insn "extendsfdf2_no_tp"
2065 [(set (match_operand:DF 0 "register_operand" "=f,f,m")
2066 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "f,m,f")))]
2067 "TARGET_FP && alpha_fptm < ALPHA_FPTM_SU"
2072 [(set_attr "type" "fcpys,fld,fst")
2073 (set_attr "trap" "yes")])
2075 (define_expand "extenddftf2"
2076 [(use (match_operand:TF 0 "register_operand" ""))
2077 (use (match_operand:DF 1 "general_operand" ""))]
2078 "TARGET_HAS_XFLOATING_LIBS"
2079 "alpha_emit_xfloating_cvt (FLOAT_EXTEND, operands); DONE;")
2082 [(set (match_operand:SF 0 "register_operand" "=&f")
2083 (float_truncate:SF (match_operand:DF 1 "reg_or_fp0_operand" "fG")))]
2084 "TARGET_FP && alpha_fptm >= ALPHA_FPTM_SU"
2085 "cvt%-%,%)%& %R1,%0"
2086 [(set_attr "type" "fadd")
2087 (set_attr "trap" "yes")])
2089 (define_insn "truncdfsf2"
2090 [(set (match_operand:SF 0 "register_operand" "=f")
2091 (float_truncate:SF (match_operand:DF 1 "reg_or_fp0_operand" "fG")))]
2093 "cvt%-%,%)%& %R1,%0"
2094 [(set_attr "type" "fadd")
2095 (set_attr "trap" "yes")])
2097 (define_expand "trunctfdf2"
2098 [(use (match_operand:DF 0 "register_operand" ""))
2099 (use (match_operand:TF 1 "general_operand" ""))]
2100 "TARGET_HAS_XFLOATING_LIBS"
2101 "alpha_emit_xfloating_cvt (FLOAT_TRUNCATE, operands); DONE;")
2104 [(set (match_operand:SF 0 "register_operand" "=&f")
2105 (div:SF (match_operand:SF 1 "reg_or_fp0_operand" "fG")
2106 (match_operand:SF 2 "reg_or_fp0_operand" "fG")))]
2107 "TARGET_FP && alpha_fptm >= ALPHA_FPTM_SU"
2108 "div%,%)%& %R1,%R2,%0"
2109 [(set_attr "type" "fdiv")
2110 (set_attr "opsize" "si")
2111 (set_attr "trap" "yes")])
2113 (define_insn "divsf3"
2114 [(set (match_operand:SF 0 "register_operand" "=f")
2115 (div:SF (match_operand:SF 1 "reg_or_fp0_operand" "fG")
2116 (match_operand:SF 2 "reg_or_fp0_operand" "fG")))]
2118 "div%,%)%& %R1,%R2,%0"
2119 [(set_attr "type" "fdiv")
2120 (set_attr "opsize" "si")
2121 (set_attr "trap" "yes")])
2124 [(set (match_operand:DF 0 "register_operand" "=&f")
2125 (div:DF (match_operand:DF 1 "reg_or_fp0_operand" "fG")
2126 (match_operand:DF 2 "reg_or_fp0_operand" "fG")))]
2127 "TARGET_FP && alpha_fptm >= ALPHA_FPTM_SU"
2128 "div%-%)%& %R1,%R2,%0"
2129 [(set_attr "type" "fdiv")
2130 (set_attr "trap" "yes")])
2132 (define_insn "divdf3"
2133 [(set (match_operand:DF 0 "register_operand" "=f")
2134 (div:DF (match_operand:DF 1 "reg_or_fp0_operand" "fG")
2135 (match_operand:DF 2 "reg_or_fp0_operand" "fG")))]
2137 "div%-%)%& %R1,%R2,%0"
2138 [(set_attr "type" "fdiv")
2139 (set_attr "trap" "yes")])
2142 [(set (match_operand:DF 0 "register_operand" "=f")
2143 (div:DF (float_extend:DF (match_operand:SF 1 "reg_or_fp0_operand" "fG"))
2144 (match_operand:DF 2 "reg_or_fp0_operand" "fG")))]
2145 "TARGET_FP && alpha_fptm < ALPHA_FPTM_SU"
2146 "div%-%)%& %R1,%R2,%0"
2147 [(set_attr "type" "fdiv")
2148 (set_attr "trap" "yes")])
2151 [(set (match_operand:DF 0 "register_operand" "=f")
2152 (div:DF (match_operand:DF 1 "reg_or_fp0_operand" "fG")
2154 (match_operand:SF 2 "reg_or_fp0_operand" "fG"))))]
2155 "TARGET_FP && alpha_fptm < ALPHA_FPTM_SU"
2156 "div%-%)%& %R1,%R2,%0"
2157 [(set_attr "type" "fdiv")
2158 (set_attr "trap" "yes")])
2161 [(set (match_operand:DF 0 "register_operand" "=f")
2162 (div:DF (float_extend:DF (match_operand:SF 1 "reg_or_fp0_operand" "fG"))
2163 (float_extend:DF (match_operand:SF 2 "reg_or_fp0_operand" "fG"))))]
2164 "TARGET_FP && alpha_fptm < ALPHA_FPTM_SU"
2165 "div%-%)%& %R1,%R2,%0"
2166 [(set_attr "type" "fdiv")
2167 (set_attr "trap" "yes")])
2169 (define_expand "divtf3"
2170 [(use (match_operand 0 "register_operand" ""))
2171 (use (match_operand 1 "general_operand" ""))
2172 (use (match_operand 2 "general_operand" ""))]
2173 "TARGET_HAS_XFLOATING_LIBS"
2174 "alpha_emit_xfloating_arith (DIV, operands); DONE;")
2177 [(set (match_operand:SF 0 "register_operand" "=&f")
2178 (mult:SF (match_operand:SF 1 "reg_or_fp0_operand" "%fG")
2179 (match_operand:SF 2 "reg_or_fp0_operand" "fG")))]
2180 "TARGET_FP && alpha_fptm >= ALPHA_FPTM_SU"
2181 "mul%,%)%& %R1,%R2,%0"
2182 [(set_attr "type" "fmul")
2183 (set_attr "trap" "yes")])
2185 (define_insn "mulsf3"
2186 [(set (match_operand:SF 0 "register_operand" "=f")
2187 (mult:SF (match_operand:SF 1 "reg_or_fp0_operand" "%fG")
2188 (match_operand:SF 2 "reg_or_fp0_operand" "fG")))]
2190 "mul%,%)%& %R1,%R2,%0"
2191 [(set_attr "type" "fmul")
2192 (set_attr "trap" "yes")])
2195 [(set (match_operand:DF 0 "register_operand" "=&f")
2196 (mult:DF (match_operand:DF 1 "reg_or_fp0_operand" "%fG")
2197 (match_operand:DF 2 "reg_or_fp0_operand" "fG")))]
2198 "TARGET_FP && alpha_fptm >= ALPHA_FPTM_SU"
2199 "mul%-%)%& %R1,%R2,%0"
2200 [(set_attr "type" "fmul")
2201 (set_attr "trap" "yes")])
2203 (define_insn "muldf3"
2204 [(set (match_operand:DF 0 "register_operand" "=f")
2205 (mult:DF (match_operand:DF 1 "reg_or_fp0_operand" "%fG")
2206 (match_operand:DF 2 "reg_or_fp0_operand" "fG")))]
2208 "mul%-%)%& %R1,%R2,%0"
2209 [(set_attr "type" "fmul")
2210 (set_attr "trap" "yes")])
2213 [(set (match_operand:DF 0 "register_operand" "=f")
2214 (mult:DF (float_extend:DF
2215 (match_operand:SF 1 "reg_or_fp0_operand" "fG"))
2216 (match_operand:DF 2 "reg_or_fp0_operand" "fG")))]
2217 "TARGET_FP && alpha_fptm < ALPHA_FPTM_SU"
2218 "mul%-%)%& %R1,%R2,%0"
2219 [(set_attr "type" "fmul")
2220 (set_attr "trap" "yes")])
2223 [(set (match_operand:DF 0 "register_operand" "=f")
2224 (mult:DF (float_extend:DF
2225 (match_operand:SF 1 "reg_or_fp0_operand" "%fG"))
2227 (match_operand:SF 2 "reg_or_fp0_operand" "fG"))))]
2228 "TARGET_FP && alpha_fptm < ALPHA_FPTM_SU"
2229 "mul%-%)%& %R1,%R2,%0"
2230 [(set_attr "type" "fmul")
2231 (set_attr "trap" "yes")])
2233 (define_expand "multf3"
2234 [(use (match_operand 0 "register_operand" ""))
2235 (use (match_operand 1 "general_operand" ""))
2236 (use (match_operand 2 "general_operand" ""))]
2237 "TARGET_HAS_XFLOATING_LIBS"
2238 "alpha_emit_xfloating_arith (MULT, operands); DONE;")
2241 [(set (match_operand:SF 0 "register_operand" "=&f")
2242 (minus:SF (match_operand:SF 1 "reg_or_fp0_operand" "fG")
2243 (match_operand:SF 2 "reg_or_fp0_operand" "fG")))]
2244 "TARGET_FP && alpha_fptm >= ALPHA_FPTM_SU"
2245 "sub%,%)%& %R1,%R2,%0"
2246 [(set_attr "type" "fadd")
2247 (set_attr "trap" "yes")])
2249 (define_insn "subsf3"
2250 [(set (match_operand:SF 0 "register_operand" "=f")
2251 (minus:SF (match_operand:SF 1 "reg_or_fp0_operand" "fG")
2252 (match_operand:SF 2 "reg_or_fp0_operand" "fG")))]
2254 "sub%,%)%& %R1,%R2,%0"
2255 [(set_attr "type" "fadd")
2256 (set_attr "trap" "yes")])
2259 [(set (match_operand:DF 0 "register_operand" "=&f")
2260 (minus:DF (match_operand:DF 1 "reg_or_fp0_operand" "fG")
2261 (match_operand:DF 2 "reg_or_fp0_operand" "fG")))]
2262 "TARGET_FP && alpha_fptm >= ALPHA_FPTM_SU"
2263 "sub%-%)%& %R1,%R2,%0"
2264 [(set_attr "type" "fadd")
2265 (set_attr "trap" "yes")])
2267 (define_insn "subdf3"
2268 [(set (match_operand:DF 0 "register_operand" "=f")
2269 (minus:DF (match_operand:DF 1 "reg_or_fp0_operand" "fG")
2270 (match_operand:DF 2 "reg_or_fp0_operand" "fG")))]
2272 "sub%-%)%& %R1,%R2,%0"
2273 [(set_attr "type" "fadd")
2274 (set_attr "trap" "yes")])
2277 [(set (match_operand:DF 0 "register_operand" "=f")
2278 (minus:DF (float_extend:DF
2279 (match_operand:SF 1 "reg_or_fp0_operand" "fG"))
2280 (match_operand:DF 2 "reg_or_fp0_operand" "fG")))]
2281 "TARGET_FP && alpha_fptm < ALPHA_FPTM_SU"
2282 "sub%-%)%& %R1,%R2,%0"
2283 [(set_attr "type" "fadd")
2284 (set_attr "trap" "yes")])
2287 [(set (match_operand:DF 0 "register_operand" "=f")
2288 (minus:DF (match_operand:DF 1 "reg_or_fp0_operand" "fG")
2290 (match_operand:SF 2 "reg_or_fp0_operand" "fG"))))]
2291 "TARGET_FP && alpha_fptm < ALPHA_FPTM_SU"
2292 "sub%-%)%& %R1,%R2,%0"
2293 [(set_attr "type" "fadd")
2294 (set_attr "trap" "yes")])
2297 [(set (match_operand:DF 0 "register_operand" "=f")
2298 (minus:DF (float_extend:DF
2299 (match_operand:SF 1 "reg_or_fp0_operand" "fG"))
2301 (match_operand:SF 2 "reg_or_fp0_operand" "fG"))))]
2302 "TARGET_FP && alpha_fptm < ALPHA_FPTM_SU"
2303 "sub%-%)%& %R1,%R2,%0"
2304 [(set_attr "type" "fadd")
2305 (set_attr "trap" "yes")])
2307 (define_expand "subtf3"
2308 [(use (match_operand 0 "register_operand" ""))
2309 (use (match_operand 1 "general_operand" ""))
2310 (use (match_operand 2 "general_operand" ""))]
2311 "TARGET_HAS_XFLOATING_LIBS"
2312 "alpha_emit_xfloating_arith (MINUS, operands); DONE;")
2315 [(set (match_operand:SF 0 "register_operand" "=&f")
2316 (sqrt:SF (match_operand:SF 1 "reg_or_fp0_operand" "fG")))]
2317 "TARGET_FP && TARGET_FIX && alpha_fptm >= ALPHA_FPTM_SU"
2319 [(set_attr "type" "fsqrt")
2320 (set_attr "opsize" "si")
2321 (set_attr "trap" "yes")])
2323 (define_insn "sqrtsf2"
2324 [(set (match_operand:SF 0 "register_operand" "=f")
2325 (sqrt:SF (match_operand:SF 1 "reg_or_fp0_operand" "fG")))]
2326 "TARGET_FP && TARGET_FIX"
2328 [(set_attr "type" "fsqrt")
2329 (set_attr "opsize" "si")
2330 (set_attr "trap" "yes")])
2333 [(set (match_operand:DF 0 "register_operand" "=&f")
2334 (sqrt:DF (match_operand:DF 1 "reg_or_fp0_operand" "fG")))]
2335 "TARGET_FP && TARGET_FIX && alpha_fptm >= ALPHA_FPTM_SU"
2337 [(set_attr "type" "fsqrt")
2338 (set_attr "trap" "yes")])
2340 (define_insn "sqrtdf2"
2341 [(set (match_operand:DF 0 "register_operand" "=f")
2342 (sqrt:DF (match_operand:DF 1 "reg_or_fp0_operand" "fG")))]
2343 "TARGET_FP && TARGET_FIX"
2345 [(set_attr "type" "fsqrt")
2346 (set_attr "trap" "yes")])
2348 ;; Next are all the integer comparisons, and conditional moves and branches
2349 ;; and some of the related define_expand's and define_split's.
2352 [(set (match_operand:DI 0 "register_operand" "=r")
2353 (match_operator:DI 1 "alpha_comparison_operator"
2354 [(match_operand:DI 2 "reg_or_0_operand" "rJ")
2355 (match_operand:DI 3 "reg_or_8bit_operand" "rI")]))]
2358 [(set_attr "type" "icmp")])
2361 [(set (match_operand:DI 0 "register_operand" "=r")
2362 (match_operator:DI 1 "alpha_swapped_comparison_operator"
2363 [(match_operand:DI 2 "reg_or_8bit_operand" "rI")
2364 (match_operand:DI 3 "reg_or_0_operand" "rJ")]))]
2367 [(set_attr "type" "icmp")])
2369 ;; This pattern exists so conditional moves of SImode values are handled.
2370 ;; Comparisons are still done in DImode though.
2373 [(set (match_operand:SI 0 "register_operand" "=r,r,r,r")
2375 (match_operator 2 "signed_comparison_operator"
2376 [(match_operand:DI 3 "reg_or_0_operand" "rJ,rJ,J,J")
2377 (match_operand:DI 4 "reg_or_0_operand" "J,J,rJ,rJ")])
2378 (match_operand:SI 1 "reg_or_8bit_operand" "rI,0,rI,0")
2379 (match_operand:SI 5 "reg_or_8bit_operand" "0,rI,0,rI")))]
2380 "operands[3] == const0_rtx || operands[4] == const0_rtx"
2386 [(set_attr "type" "icmov")])
2389 [(set (match_operand:DI 0 "register_operand" "=r,r,r,r")
2391 (match_operator 2 "signed_comparison_operator"
2392 [(match_operand:DI 3 "reg_or_0_operand" "rJ,rJ,J,J")
2393 (match_operand:DI 4 "reg_or_0_operand" "J,J,rJ,rJ")])
2394 (match_operand:DI 1 "reg_or_8bit_operand" "rI,0,rI,0")
2395 (match_operand:DI 5 "reg_or_8bit_operand" "0,rI,0,rI")))]
2396 "operands[3] == const0_rtx || operands[4] == const0_rtx"
2402 [(set_attr "type" "icmov")])
2405 [(set (match_operand:DI 0 "register_operand" "=r,r")
2407 (eq (zero_extract:DI (match_operand:DI 2 "reg_or_0_operand" "rJ,rJ")
2411 (match_operand:DI 1 "reg_or_8bit_operand" "rI,0")
2412 (match_operand:DI 3 "reg_or_8bit_operand" "0,rI")))]
2417 [(set_attr "type" "icmov")])
2420 [(set (match_operand:DI 0 "register_operand" "=r,r")
2422 (ne (zero_extract:DI (match_operand:DI 2 "reg_or_0_operand" "rJ,rJ")
2426 (match_operand:DI 1 "reg_or_8bit_operand" "rI,0")
2427 (match_operand:DI 3 "reg_or_8bit_operand" "0,rI")))]
2432 [(set_attr "type" "icmov")])
2434 ;; For ABS, we have two choices, depending on whether the input and output
2435 ;; registers are the same or not.
2436 (define_expand "absdi2"
2437 [(set (match_operand:DI 0 "register_operand" "")
2438 (abs:DI (match_operand:DI 1 "register_operand" "")))]
2441 { if (rtx_equal_p (operands[0], operands[1]))
2442 emit_insn (gen_absdi2_same (operands[0], gen_reg_rtx (DImode)));
2444 emit_insn (gen_absdi2_diff (operands[0], operands[1]));
2449 (define_expand "absdi2_same"
2450 [(set (match_operand:DI 1 "register_operand" "")
2451 (neg:DI (match_operand:DI 0 "register_operand" "")))
2453 (if_then_else:DI (ge (match_dup 0) (const_int 0))
2459 (define_expand "absdi2_diff"
2460 [(set (match_operand:DI 0 "register_operand" "")
2461 (neg:DI (match_operand:DI 1 "register_operand" "")))
2463 (if_then_else:DI (lt (match_dup 1) (const_int 0))
2470 [(set (match_operand:DI 0 "register_operand" "")
2471 (abs:DI (match_dup 0)))
2472 (clobber (match_operand:DI 2 "register_operand" ""))]
2474 [(set (match_dup 1) (neg:DI (match_dup 0)))
2475 (set (match_dup 0) (if_then_else:DI (ge (match_dup 0) (const_int 0))
2476 (match_dup 0) (match_dup 1)))]
2480 [(set (match_operand:DI 0 "register_operand" "")
2481 (abs:DI (match_operand:DI 1 "register_operand" "")))]
2482 "! rtx_equal_p (operands[0], operands[1])"
2483 [(set (match_dup 0) (neg:DI (match_dup 1)))
2484 (set (match_dup 0) (if_then_else:DI (lt (match_dup 1) (const_int 0))
2485 (match_dup 0) (match_dup 1)))]
2489 [(set (match_operand:DI 0 "register_operand" "")
2490 (neg:DI (abs:DI (match_dup 0))))
2491 (clobber (match_operand:DI 2 "register_operand" ""))]
2493 [(set (match_dup 1) (neg:DI (match_dup 0)))
2494 (set (match_dup 0) (if_then_else:DI (le (match_dup 0) (const_int 0))
2495 (match_dup 0) (match_dup 1)))]
2499 [(set (match_operand:DI 0 "register_operand" "")
2500 (neg:DI (abs:DI (match_operand:DI 1 "register_operand" ""))))]
2501 "! rtx_equal_p (operands[0], operands[1])"
2502 [(set (match_dup 0) (neg:DI (match_dup 1)))
2503 (set (match_dup 0) (if_then_else:DI (gt (match_dup 1) (const_int 0))
2504 (match_dup 0) (match_dup 1)))]
2507 (define_insn "sminqi3"
2508 [(set (match_operand:QI 0 "register_operand" "=r")
2509 (smin:QI (match_operand:QI 1 "reg_or_0_operand" "%rJ")
2510 (match_operand:QI 2 "reg_or_8bit_operand" "rI")))]
2513 [(set_attr "type" "mvi")])
2515 (define_insn "uminqi3"
2516 [(set (match_operand:QI 0 "register_operand" "=r")
2517 (umin:QI (match_operand:QI 1 "reg_or_0_operand" "%rJ")
2518 (match_operand:QI 2 "reg_or_8bit_operand" "rI")))]
2521 [(set_attr "type" "mvi")])
2523 (define_insn "smaxqi3"
2524 [(set (match_operand:QI 0 "register_operand" "=r")
2525 (smax:QI (match_operand:QI 1 "reg_or_0_operand" "%rJ")
2526 (match_operand:QI 2 "reg_or_8bit_operand" "rI")))]
2529 [(set_attr "type" "mvi")])
2531 (define_insn "umaxqi3"
2532 [(set (match_operand:QI 0 "register_operand" "=r")
2533 (umax:QI (match_operand:QI 1 "reg_or_0_operand" "%rJ")
2534 (match_operand:QI 2 "reg_or_8bit_operand" "rI")))]
2537 [(set_attr "type" "mvi")])
2539 (define_insn "sminhi3"
2540 [(set (match_operand:HI 0 "register_operand" "=r")
2541 (smin:HI (match_operand:HI 1 "reg_or_0_operand" "%rJ")
2542 (match_operand:HI 2 "reg_or_8bit_operand" "rI")))]
2545 [(set_attr "type" "mvi")])
2547 (define_insn "uminhi3"
2548 [(set (match_operand:HI 0 "register_operand" "=r")
2549 (umin:HI (match_operand:HI 1 "reg_or_0_operand" "%rJ")
2550 (match_operand:HI 2 "reg_or_8bit_operand" "rI")))]
2553 [(set_attr "type" "mvi")])
2555 (define_insn "smaxhi3"
2556 [(set (match_operand:HI 0 "register_operand" "=r")
2557 (smax:HI (match_operand:HI 1 "reg_or_0_operand" "%rJ")
2558 (match_operand:HI 2 "reg_or_8bit_operand" "rI")))]
2561 [(set_attr "type" "mvi")])
2563 (define_insn "umaxhi3"
2564 [(set (match_operand:HI 0 "register_operand" "=r")
2565 (umax:HI (match_operand:HI 1 "reg_or_0_operand" "%rJ")
2566 (match_operand:HI 2 "reg_or_8bit_operand" "rI")))]
2569 [(set_attr "type" "shift")])
2571 (define_expand "smaxdi3"
2573 (le:DI (match_operand:DI 1 "reg_or_0_operand" "")
2574 (match_operand:DI 2 "reg_or_8bit_operand" "")))
2575 (set (match_operand:DI 0 "register_operand" "")
2576 (if_then_else:DI (eq (match_dup 3) (const_int 0))
2577 (match_dup 1) (match_dup 2)))]
2580 { operands[3] = gen_reg_rtx (DImode);
2584 [(set (match_operand:DI 0 "register_operand" "")
2585 (smax:DI (match_operand:DI 1 "reg_or_0_operand" "")
2586 (match_operand:DI 2 "reg_or_8bit_operand" "")))
2587 (clobber (match_operand:DI 3 "register_operand" ""))]
2588 "operands[2] != const0_rtx"
2589 [(set (match_dup 3) (le:DI (match_dup 1) (match_dup 2)))
2590 (set (match_dup 0) (if_then_else:DI (eq (match_dup 3) (const_int 0))
2591 (match_dup 1) (match_dup 2)))]
2595 [(set (match_operand:DI 0 "register_operand" "=r")
2596 (smax:DI (match_operand:DI 1 "register_operand" "0")
2600 [(set_attr "type" "icmov")])
2602 (define_expand "smindi3"
2604 (lt:DI (match_operand:DI 1 "reg_or_0_operand" "")
2605 (match_operand:DI 2 "reg_or_8bit_operand" "")))
2606 (set (match_operand:DI 0 "register_operand" "")
2607 (if_then_else:DI (ne (match_dup 3) (const_int 0))
2608 (match_dup 1) (match_dup 2)))]
2611 { operands[3] = gen_reg_rtx (DImode);
2615 [(set (match_operand:DI 0 "register_operand" "")
2616 (smin:DI (match_operand:DI 1 "reg_or_0_operand" "")
2617 (match_operand:DI 2 "reg_or_8bit_operand" "")))
2618 (clobber (match_operand:DI 3 "register_operand" ""))]
2619 "operands[2] != const0_rtx"
2620 [(set (match_dup 3) (lt:DI (match_dup 1) (match_dup 2)))
2621 (set (match_dup 0) (if_then_else:DI (ne (match_dup 3) (const_int 0))
2622 (match_dup 1) (match_dup 2)))]
2626 [(set (match_operand:DI 0 "register_operand" "=r")
2627 (smin:DI (match_operand:DI 1 "register_operand" "0")
2631 [(set_attr "type" "icmov")])
2633 (define_expand "umaxdi3"
2635 (leu:DI (match_operand:DI 1 "reg_or_0_operand" "")
2636 (match_operand:DI 2 "reg_or_8bit_operand" "")))
2637 (set (match_operand:DI 0 "register_operand" "")
2638 (if_then_else:DI (eq (match_dup 3) (const_int 0))
2639 (match_dup 1) (match_dup 2)))]
2642 { operands[3] = gen_reg_rtx (DImode);
2646 [(set (match_operand:DI 0 "register_operand" "")
2647 (umax:DI (match_operand:DI 1 "reg_or_0_operand" "")
2648 (match_operand:DI 2 "reg_or_8bit_operand" "")))
2649 (clobber (match_operand:DI 3 "register_operand" ""))]
2650 "operands[2] != const0_rtx"
2651 [(set (match_dup 3) (leu:DI (match_dup 1) (match_dup 2)))
2652 (set (match_dup 0) (if_then_else:DI (eq (match_dup 3) (const_int 0))
2653 (match_dup 1) (match_dup 2)))]
2656 (define_expand "umindi3"
2658 (ltu:DI (match_operand:DI 1 "reg_or_0_operand" "")
2659 (match_operand:DI 2 "reg_or_8bit_operand" "")))
2660 (set (match_operand:DI 0 "register_operand" "")
2661 (if_then_else:DI (ne (match_dup 3) (const_int 0))
2662 (match_dup 1) (match_dup 2)))]
2665 { operands[3] = gen_reg_rtx (DImode);
2669 [(set (match_operand:DI 0 "register_operand" "")
2670 (umin:DI (match_operand:DI 1 "reg_or_0_operand" "")
2671 (match_operand:DI 2 "reg_or_8bit_operand" "")))
2672 (clobber (match_operand:DI 3 "register_operand" ""))]
2673 "operands[2] != const0_rtx"
2674 [(set (match_dup 3) (ltu:DI (match_dup 1) (match_dup 2)))
2675 (set (match_dup 0) (if_then_else:DI (ne (match_dup 3) (const_int 0))
2676 (match_dup 1) (match_dup 2)))]
2682 (match_operator 1 "signed_comparison_operator"
2683 [(match_operand:DI 2 "reg_or_0_operand" "rJ")
2685 (label_ref (match_operand 0 "" ""))
2689 [(set_attr "type" "ibr")])
2694 (match_operator 1 "signed_comparison_operator"
2696 (match_operand:DI 2 "register_operand" "r")])
2697 (label_ref (match_operand 0 "" ""))
2701 [(set_attr "type" "ibr")])
2706 (ne (zero_extract:DI (match_operand:DI 1 "reg_or_0_operand" "rJ")
2710 (label_ref (match_operand 0 "" ""))
2714 [(set_attr "type" "ibr")])
2719 (eq (zero_extract:DI (match_operand:DI 1 "reg_or_0_operand" "rJ")
2723 (label_ref (match_operand 0 "" ""))
2727 [(set_attr "type" "ibr")])
2733 (match_operator 1 "comparison_operator"
2734 [(zero_extract:DI (match_operand:DI 2 "register_operand" "")
2736 (match_operand:DI 3 "const_int_operand" ""))
2738 (label_ref (match_operand 0 "" ""))
2740 (clobber (match_operand:DI 4 "register_operand" ""))])]
2741 "INTVAL (operands[3]) != 0"
2743 (lshiftrt:DI (match_dup 2) (match_dup 3)))
2745 (if_then_else (match_op_dup 1
2746 [(zero_extract:DI (match_dup 4)
2750 (label_ref (match_dup 0))
2754 ;; The following are the corresponding floating-point insns. Recall
2755 ;; we need to have variants that expand the arguments from SF mode
2759 [(set (match_operand:DF 0 "register_operand" "=&f")
2760 (match_operator:DF 1 "alpha_comparison_operator"
2761 [(match_operand:DF 2 "reg_or_fp0_operand" "fG")
2762 (match_operand:DF 3 "reg_or_fp0_operand" "fG")]))]
2763 "TARGET_FP && alpha_fptm >= ALPHA_FPTM_SU"
2764 "cmp%-%C1%' %R2,%R3,%0"
2765 [(set_attr "type" "fadd")
2766 (set_attr "trap" "yes")])
2769 [(set (match_operand:DF 0 "register_operand" "=f")
2770 (match_operator:DF 1 "alpha_comparison_operator"
2771 [(match_operand:DF 2 "reg_or_fp0_operand" "fG")
2772 (match_operand:DF 3 "reg_or_fp0_operand" "fG")]))]
2773 "TARGET_FP && alpha_fptm < ALPHA_FPTM_SU"
2774 "cmp%-%C1%' %R2,%R3,%0"
2775 [(set_attr "type" "fadd")
2776 (set_attr "trap" "yes")])
2779 [(set (match_operand:DF 0 "register_operand" "=&f")
2780 (match_operator:DF 1 "alpha_comparison_operator"
2782 (match_operand:SF 2 "reg_or_fp0_operand" "fG"))
2783 (match_operand:DF 3 "reg_or_fp0_operand" "fG")]))]
2784 "TARGET_FP && alpha_fptm >= ALPHA_FPTM_SU"
2785 "cmp%-%C1%' %R2,%R3,%0"
2786 [(set_attr "type" "fadd")
2787 (set_attr "trap" "yes")])
2790 [(set (match_operand:DF 0 "register_operand" "=f")
2791 (match_operator:DF 1 "alpha_comparison_operator"
2793 (match_operand:SF 2 "reg_or_fp0_operand" "fG"))
2794 (match_operand:DF 3 "reg_or_fp0_operand" "fG")]))]
2795 "TARGET_FP && alpha_fptm < ALPHA_FPTM_SU"
2796 "cmp%-%C1%' %R2,%R3,%0"
2797 [(set_attr "type" "fadd")
2798 (set_attr "trap" "yes")])
2801 [(set (match_operand:DF 0 "register_operand" "=&f")
2802 (match_operator:DF 1 "alpha_comparison_operator"
2803 [(match_operand:DF 2 "reg_or_fp0_operand" "fG")
2805 (match_operand:SF 3 "reg_or_fp0_operand" "fG"))]))]
2806 "TARGET_FP && alpha_fptm >= ALPHA_FPTM_SU"
2807 "cmp%-%C1%' %R2,%R3,%0"
2808 [(set_attr "type" "fadd")
2809 (set_attr "trap" "yes")])
2812 [(set (match_operand:DF 0 "register_operand" "=f")
2813 (match_operator:DF 1 "alpha_comparison_operator"
2814 [(match_operand:DF 2 "reg_or_fp0_operand" "fG")
2816 (match_operand:SF 3 "reg_or_fp0_operand" "fG"))]))]
2817 "TARGET_FP && alpha_fptm < ALPHA_FPTM_SU"
2818 "cmp%-%C1%' %R2,%R3,%0"
2819 [(set_attr "type" "fadd")
2820 (set_attr "trap" "yes")])
2823 [(set (match_operand:DF 0 "register_operand" "=&f")
2824 (match_operator:DF 1 "alpha_comparison_operator"
2826 (match_operand:SF 2 "reg_or_fp0_operand" "fG"))
2828 (match_operand:SF 3 "reg_or_fp0_operand" "fG"))]))]
2829 "TARGET_FP && alpha_fptm >= ALPHA_FPTM_SU"
2830 "cmp%-%C1%' %R2,%R3,%0"
2831 [(set_attr "type" "fadd")
2832 (set_attr "trap" "yes")])
2835 [(set (match_operand:DF 0 "register_operand" "=f")
2836 (match_operator:DF 1 "alpha_comparison_operator"
2838 (match_operand:SF 2 "reg_or_fp0_operand" "fG"))
2840 (match_operand:SF 3 "reg_or_fp0_operand" "fG"))]))]
2841 "TARGET_FP && alpha_fptm < ALPHA_FPTM_SU"
2842 "cmp%-%C1%' %R2,%R3,%0"
2843 [(set_attr "type" "fadd")
2844 (set_attr "trap" "yes")])
2847 [(set (match_operand:DF 0 "register_operand" "=f,f")
2849 (match_operator 3 "signed_comparison_operator"
2850 [(match_operand:DF 4 "reg_or_fp0_operand" "fG,fG")
2851 (match_operand:DF 2 "fp0_operand" "G,G")])
2852 (match_operand:DF 1 "reg_or_fp0_operand" "fG,0")
2853 (match_operand:DF 5 "reg_or_fp0_operand" "0,fG")))]
2857 fcmov%D3 %R4,%R5,%0"
2858 [(set_attr "type" "fcmov")])
2861 [(set (match_operand:SF 0 "register_operand" "=f,f")
2863 (match_operator 3 "signed_comparison_operator"
2864 [(match_operand:DF 4 "reg_or_fp0_operand" "fG,fG")
2865 (match_operand:DF 2 "fp0_operand" "G,G")])
2866 (match_operand:SF 1 "reg_or_fp0_operand" "fG,0")
2867 (match_operand:SF 5 "reg_or_fp0_operand" "0,fG")))]
2871 fcmov%D3 %R4,%R5,%0"
2872 [(set_attr "type" "fcmov")])
2875 [(set (match_operand:DF 0 "register_operand" "=f,f")
2877 (match_operator 3 "signed_comparison_operator"
2878 [(match_operand:DF 4 "reg_or_fp0_operand" "fG,fG")
2879 (match_operand:DF 2 "fp0_operand" "G,G")])
2880 (float_extend:DF (match_operand:SF 1 "reg_or_fp0_operand" "fG,0"))
2881 (match_operand:DF 5 "reg_or_fp0_operand" "0,fG")))]
2885 fcmov%D3 %R4,%R5,%0"
2886 [(set_attr "type" "fcmov")])
2889 [(set (match_operand:DF 0 "register_operand" "=f,f")
2891 (match_operator 3 "signed_comparison_operator"
2893 (match_operand:SF 4 "reg_or_fp0_operand" "fG,fG"))
2894 (match_operand:DF 2 "fp0_operand" "G,G")])
2895 (match_operand:DF 1 "reg_or_fp0_operand" "fG,0")
2896 (match_operand:DF 5 "reg_or_fp0_operand" "0,fG")))]
2900 fcmov%D3 %R4,%R5,%0"
2901 [(set_attr "type" "fcmov")])
2904 [(set (match_operand:SF 0 "register_operand" "=f,f")
2906 (match_operator 3 "signed_comparison_operator"
2908 (match_operand:SF 4 "reg_or_fp0_operand" "fG,fG"))
2909 (match_operand:DF 2 "fp0_operand" "G,G")])
2910 (match_operand:SF 1 "reg_or_fp0_operand" "fG,0")
2911 (match_operand:SF 5 "reg_or_fp0_operand" "0,fG")))]
2915 fcmov%D3 %R4,%R5,%0"
2916 [(set_attr "type" "fcmov")])
2919 [(set (match_operand:DF 0 "register_operand" "=f,f")
2921 (match_operator 3 "signed_comparison_operator"
2923 (match_operand:SF 4 "reg_or_fp0_operand" "fG,fG"))
2924 (match_operand:DF 2 "fp0_operand" "G,G")])
2925 (float_extend:DF (match_operand:SF 1 "reg_or_fp0_operand" "fG,0"))
2926 (match_operand:DF 5 "reg_or_fp0_operand" "0,fG")))]
2930 fcmov%D3 %R4,%R5,%0"
2931 [(set_attr "type" "fcmov")])
2933 (define_expand "maxdf3"
2935 (le:DF (match_operand:DF 1 "reg_or_fp0_operand" "")
2936 (match_operand:DF 2 "reg_or_fp0_operand" "")))
2937 (set (match_operand:DF 0 "register_operand" "")
2938 (if_then_else:DF (eq (match_dup 3) (match_dup 4))
2939 (match_dup 1) (match_dup 2)))]
2942 { operands[3] = gen_reg_rtx (DFmode);
2943 operands[4] = CONST0_RTX (DFmode);
2946 (define_expand "mindf3"
2948 (lt:DF (match_operand:DF 1 "reg_or_fp0_operand" "")
2949 (match_operand:DF 2 "reg_or_fp0_operand" "")))
2950 (set (match_operand:DF 0 "register_operand" "")
2951 (if_then_else:DF (ne (match_dup 3) (match_dup 4))
2952 (match_dup 1) (match_dup 2)))]
2955 { operands[3] = gen_reg_rtx (DFmode);
2956 operands[4] = CONST0_RTX (DFmode);
2959 (define_expand "maxsf3"
2961 (le:DF (float_extend:DF (match_operand:SF 1 "reg_or_fp0_operand" ""))
2962 (float_extend:DF (match_operand:SF 2 "reg_or_fp0_operand" ""))))
2963 (set (match_operand:SF 0 "register_operand" "")
2964 (if_then_else:SF (eq (match_dup 3) (match_dup 4))
2965 (match_dup 1) (match_dup 2)))]
2968 { operands[3] = gen_reg_rtx (DFmode);
2969 operands[4] = CONST0_RTX (DFmode);
2972 (define_expand "minsf3"
2974 (lt:DF (float_extend:DF (match_operand:SF 1 "reg_or_fp0_operand" ""))
2975 (float_extend:DF (match_operand:SF 2 "reg_or_fp0_operand" ""))))
2976 (set (match_operand:SF 0 "register_operand" "")
2977 (if_then_else:SF (ne (match_dup 3) (match_dup 4))
2978 (match_dup 1) (match_dup 2)))]
2981 { operands[3] = gen_reg_rtx (DFmode);
2982 operands[4] = CONST0_RTX (DFmode);
2988 (match_operator 1 "signed_comparison_operator"
2989 [(match_operand:DF 2 "reg_or_fp0_operand" "fG")
2990 (match_operand:DF 3 "fp0_operand" "G")])
2991 (label_ref (match_operand 0 "" ""))
2995 [(set_attr "type" "fbr")])
3000 (match_operator 1 "signed_comparison_operator"
3002 (match_operand:SF 2 "reg_or_fp0_operand" "fG"))
3003 (match_operand:DF 3 "fp0_operand" "G")])
3004 (label_ref (match_operand 0 "" ""))
3008 [(set_attr "type" "fbr")])
3010 ;; These are the main define_expand's used to make conditional branches
3013 (define_expand "cmpdf"
3014 [(set (cc0) (compare (match_operand:DF 0 "reg_or_fp0_operand" "")
3015 (match_operand:DF 1 "reg_or_fp0_operand" "")))]
3019 alpha_compare.op0 = operands[0];
3020 alpha_compare.op1 = operands[1];
3021 alpha_compare.fp_p = 1;
3025 (define_expand "cmptf"
3026 [(set (cc0) (compare (match_operand:TF 0 "general_operand" "")
3027 (match_operand:TF 1 "general_operand" "")))]
3028 "TARGET_HAS_XFLOATING_LIBS"
3031 alpha_compare.op0 = operands[0];
3032 alpha_compare.op1 = operands[1];
3033 alpha_compare.fp_p = 1;
3037 (define_expand "cmpdi"
3038 [(set (cc0) (compare (match_operand:DI 0 "reg_or_0_operand" "")
3039 (match_operand:DI 1 "reg_or_8bit_operand" "")))]
3043 alpha_compare.op0 = operands[0];
3044 alpha_compare.op1 = operands[1];
3045 alpha_compare.fp_p = 0;
3049 (define_expand "beq"
3051 (if_then_else (match_dup 1)
3052 (label_ref (match_operand 0 "" ""))
3055 "{ operands[1] = alpha_emit_conditional_branch (EQ); }")
3057 (define_expand "bne"
3059 (if_then_else (match_dup 1)
3060 (label_ref (match_operand 0 "" ""))
3063 "{ operands[1] = alpha_emit_conditional_branch (NE); }")
3065 (define_expand "blt"
3067 (if_then_else (match_dup 1)
3068 (label_ref (match_operand 0 "" ""))
3071 "{ operands[1] = alpha_emit_conditional_branch (LT); }")
3073 (define_expand "ble"
3075 (if_then_else (match_dup 1)
3076 (label_ref (match_operand 0 "" ""))
3079 "{ operands[1] = alpha_emit_conditional_branch (LE); }")
3081 (define_expand "bgt"
3083 (if_then_else (match_dup 1)
3084 (label_ref (match_operand 0 "" ""))
3087 "{ operands[1] = alpha_emit_conditional_branch (GT); }")
3089 (define_expand "bge"
3091 (if_then_else (match_dup 1)
3092 (label_ref (match_operand 0 "" ""))
3095 "{ operands[1] = alpha_emit_conditional_branch (GE); }")
3097 (define_expand "bltu"
3099 (if_then_else (match_dup 1)
3100 (label_ref (match_operand 0 "" ""))
3103 "{ operands[1] = alpha_emit_conditional_branch (LTU); }")
3105 (define_expand "bleu"
3107 (if_then_else (match_dup 1)
3108 (label_ref (match_operand 0 "" ""))
3111 "{ operands[1] = alpha_emit_conditional_branch (LEU); }")
3113 (define_expand "bgtu"
3115 (if_then_else (match_dup 1)
3116 (label_ref (match_operand 0 "" ""))
3119 "{ operands[1] = alpha_emit_conditional_branch (GTU); }")
3121 (define_expand "bgeu"
3123 (if_then_else (match_dup 1)
3124 (label_ref (match_operand 0 "" ""))
3127 "{ operands[1] = alpha_emit_conditional_branch (GEU); }")
3129 (define_expand "seq"
3130 [(set (match_operand:DI 0 "register_operand" "")
3135 if (alpha_compare.fp_p)
3138 operands[1] = gen_rtx_EQ (DImode, alpha_compare.op0, alpha_compare.op1);
3139 alpha_compare.op0 = alpha_compare.op1 = NULL_RTX;
3142 (define_expand "sne"
3143 [(set (match_operand:DI 0 "register_operand" "")
3145 (set (match_dup 0) (xor:DI (match_dup 0) (const_int 1)))]
3149 if (alpha_compare.fp_p)
3152 if (alpha_compare.op1 == const0_rtx)
3154 emit_insn (gen_sgtu (operands[0]));
3158 operands[1] = gen_rtx_EQ (DImode, alpha_compare.op0, alpha_compare.op1);
3159 alpha_compare.op0 = alpha_compare.op1 = NULL_RTX;
3162 (define_expand "slt"
3163 [(set (match_operand:DI 0 "register_operand" "")
3168 if (alpha_compare.fp_p)
3171 operands[1] = gen_rtx_LT (DImode, alpha_compare.op0, alpha_compare.op1);
3172 alpha_compare.op0 = alpha_compare.op1 = NULL_RTX;
3175 (define_expand "sle"
3176 [(set (match_operand:DI 0 "register_operand" "")
3181 if (alpha_compare.fp_p)
3184 operands[1] = gen_rtx_LE (DImode, alpha_compare.op0, alpha_compare.op1);
3185 alpha_compare.op0 = alpha_compare.op1 = NULL_RTX;
3188 (define_expand "sgt"
3189 [(set (match_operand:DI 0 "register_operand" "")
3194 if (alpha_compare.fp_p)
3197 operands[1] = gen_rtx_LT (DImode, force_reg (DImode, alpha_compare.op1),
3199 alpha_compare.op0 = alpha_compare.op1 = NULL_RTX;
3202 (define_expand "sge"
3203 [(set (match_operand:DI 0 "register_operand" "")
3208 if (alpha_compare.fp_p)
3211 operands[1] = gen_rtx_LE (DImode, force_reg (DImode, alpha_compare.op1),
3213 alpha_compare.op0 = alpha_compare.op1 = NULL_RTX;
3216 (define_expand "sltu"
3217 [(set (match_operand:DI 0 "register_operand" "")
3222 if (alpha_compare.fp_p)
3225 operands[1] = gen_rtx_LTU (DImode, alpha_compare.op0, alpha_compare.op1);
3226 alpha_compare.op0 = alpha_compare.op1 = NULL_RTX;
3229 (define_expand "sleu"
3230 [(set (match_operand:DI 0 "register_operand" "")
3235 if (alpha_compare.fp_p)
3238 operands[1] = gen_rtx_LEU (DImode, alpha_compare.op0, alpha_compare.op1);
3239 alpha_compare.op0 = alpha_compare.op1 = NULL_RTX;
3242 (define_expand "sgtu"
3243 [(set (match_operand:DI 0 "register_operand" "")
3248 if (alpha_compare.fp_p)
3251 operands[1] = gen_rtx_LTU (DImode, force_reg (DImode, alpha_compare.op1),
3253 alpha_compare.op0 = alpha_compare.op1 = NULL_RTX;
3256 (define_expand "sgeu"
3257 [(set (match_operand:DI 0 "register_operand" "")
3262 if (alpha_compare.fp_p)
3265 operands[1] = gen_rtx_LEU (DImode, force_reg (DImode, alpha_compare.op1),
3267 alpha_compare.op0 = alpha_compare.op1 = NULL_RTX;
3270 ;; These are the main define_expand's used to make conditional moves.
3272 (define_expand "movsicc"
3273 [(set (match_operand:SI 0 "register_operand" "")
3274 (if_then_else:SI (match_operand 1 "comparison_operator" "")
3275 (match_operand:SI 2 "reg_or_8bit_operand" "")
3276 (match_operand:SI 3 "reg_or_8bit_operand" "")))]
3280 if ((operands[1] = alpha_emit_conditional_move (operands[1], SImode)) == 0)
3284 (define_expand "movdicc"
3285 [(set (match_operand:DI 0 "register_operand" "")
3286 (if_then_else:DI (match_operand 1 "comparison_operator" "")
3287 (match_operand:DI 2 "reg_or_8bit_operand" "")
3288 (match_operand:DI 3 "reg_or_8bit_operand" "")))]
3292 if ((operands[1] = alpha_emit_conditional_move (operands[1], DImode)) == 0)
3296 (define_expand "movsfcc"
3297 [(set (match_operand:SF 0 "register_operand" "")
3298 (if_then_else:SF (match_operand 1 "comparison_operator" "")
3299 (match_operand:SF 2 "reg_or_8bit_operand" "")
3300 (match_operand:SF 3 "reg_or_8bit_operand" "")))]
3304 if ((operands[1] = alpha_emit_conditional_move (operands[1], SFmode)) == 0)
3308 (define_expand "movdfcc"
3309 [(set (match_operand:DF 0 "register_operand" "")
3310 (if_then_else:DF (match_operand 1 "comparison_operator" "")
3311 (match_operand:DF 2 "reg_or_8bit_operand" "")
3312 (match_operand:DF 3 "reg_or_8bit_operand" "")))]
3316 if ((operands[1] = alpha_emit_conditional_move (operands[1], DFmode)) == 0)
3320 ;; These define_split definitions are used in cases when comparisons have
3321 ;; not be stated in the correct way and we need to reverse the second
3322 ;; comparison. For example, x >= 7 has to be done as x < 6 with the
3323 ;; comparison that tests the result being reversed. We have one define_split
3324 ;; for each use of a comparison. They do not match valid insns and need
3325 ;; not generate valid insns.
3327 ;; We can also handle equality comparisons (and inequality comparisons in
3328 ;; cases where the resulting add cannot overflow) by doing an add followed by
3329 ;; a comparison with zero. This is faster since the addition takes one
3330 ;; less cycle than a compare when feeding into a conditional move.
3331 ;; For this case, we also have an SImode pattern since we can merge the add
3332 ;; and sign extend and the order doesn't matter.
3334 ;; We do not do this for floating-point, since it isn't clear how the "wrong"
3335 ;; operation could have been generated.
3338 [(set (match_operand:DI 0 "register_operand" "")
3340 (match_operator 1 "comparison_operator"
3341 [(match_operand:DI 2 "reg_or_0_operand" "")
3342 (match_operand:DI 3 "reg_or_cint_operand" "")])
3343 (match_operand:DI 4 "reg_or_cint_operand" "")
3344 (match_operand:DI 5 "reg_or_cint_operand" "")))
3345 (clobber (match_operand:DI 6 "register_operand" ""))]
3346 "operands[3] != const0_rtx"
3347 [(set (match_dup 6) (match_dup 7))
3349 (if_then_else:DI (match_dup 8) (match_dup 4) (match_dup 5)))]
3351 { enum rtx_code code = GET_CODE (operands[1]);
3352 int unsignedp = (code == GEU || code == LEU || code == GTU || code == LTU);
3354 /* If we are comparing for equality with a constant and that constant
3355 appears in the arm when the register equals the constant, use the
3356 register since that is more likely to match (and to produce better code
3359 if (code == EQ && GET_CODE (operands[3]) == CONST_INT
3360 && rtx_equal_p (operands[4], operands[3]))
3361 operands[4] = operands[2];
3363 else if (code == NE && GET_CODE (operands[3]) == CONST_INT
3364 && rtx_equal_p (operands[5], operands[3]))
3365 operands[5] = operands[2];
3367 if (code == NE || code == EQ
3368 || (extended_count (operands[2], DImode, unsignedp) >= 1
3369 && extended_count (operands[3], DImode, unsignedp) >= 1))
3371 if (GET_CODE (operands[3]) == CONST_INT)
3372 operands[7] = gen_rtx_PLUS (DImode, operands[2],
3373 GEN_INT (- INTVAL (operands[3])));
3375 operands[7] = gen_rtx_MINUS (DImode, operands[2], operands[3]);
3377 operands[8] = gen_rtx_fmt_ee (code, VOIDmode, operands[6], const0_rtx);
3380 else if (code == EQ || code == LE || code == LT
3381 || code == LEU || code == LTU)
3383 operands[7] = gen_rtx_fmt_ee (code, DImode, operands[2], operands[3]);
3384 operands[8] = gen_rtx_NE (VOIDmode, operands[6], const0_rtx);
3388 operands[7] = gen_rtx_fmt_ee (reverse_condition (code), DImode,
3389 operands[2], operands[3]);
3390 operands[8] = gen_rtx_EQ (VOIDmode, operands[6], const0_rtx);
3395 [(set (match_operand:DI 0 "register_operand" "")
3397 (match_operator 1 "comparison_operator"
3398 [(match_operand:SI 2 "reg_or_0_operand" "")
3399 (match_operand:SI 3 "reg_or_cint_operand" "")])
3400 (match_operand:DI 4 "reg_or_8bit_operand" "")
3401 (match_operand:DI 5 "reg_or_8bit_operand" "")))
3402 (clobber (match_operand:DI 6 "register_operand" ""))]
3403 "operands[3] != const0_rtx
3404 && (GET_CODE (operands[1]) == EQ || GET_CODE (operands[1]) == NE)"
3405 [(set (match_dup 6) (match_dup 7))
3407 (if_then_else:DI (match_dup 8) (match_dup 4) (match_dup 5)))]
3409 { enum rtx_code code = GET_CODE (operands[1]);
3410 int unsignedp = (code == GEU || code == LEU || code == GTU || code == LTU);
3413 if ((code != NE && code != EQ
3414 && ! (extended_count (operands[2], DImode, unsignedp) >= 1
3415 && extended_count (operands[3], DImode, unsignedp) >= 1)))
3418 if (GET_CODE (operands[3]) == CONST_INT)
3419 tem = gen_rtx_PLUS (SImode, operands[2],
3420 GEN_INT (- INTVAL (operands[3])));
3422 tem = gen_rtx_MINUS (SImode, operands[2], operands[3]);
3424 operands[7] = gen_rtx_SIGN_EXTEND (DImode, tem);
3425 operands[8] = gen_rtx_fmt_ee (GET_CODE (operands[1]), VOIDmode,
3426 operands[6], const0_rtx);
3432 (match_operator 1 "comparison_operator"
3433 [(match_operand:DI 2 "reg_or_0_operand" "")
3434 (match_operand:DI 3 "reg_or_cint_operand" "")])
3435 (label_ref (match_operand 0 "" ""))
3437 (clobber (match_operand:DI 4 "register_operand" ""))]
3438 "operands[3] != const0_rtx"
3439 [(set (match_dup 4) (match_dup 5))
3440 (set (pc) (if_then_else (match_dup 6) (label_ref (match_dup 0)) (pc)))]
3442 { enum rtx_code code = GET_CODE (operands[1]);
3443 int unsignedp = (code == GEU || code == LEU || code == GTU || code == LTU);
3445 if (code == NE || code == EQ
3446 || (extended_count (operands[2], DImode, unsignedp) >= 1
3447 && extended_count (operands[3], DImode, unsignedp) >= 1))
3449 if (GET_CODE (operands[3]) == CONST_INT)
3450 operands[5] = gen_rtx_PLUS (DImode, operands[2],
3451 GEN_INT (- INTVAL (operands[3])));
3453 operands[5] = gen_rtx_MINUS (DImode, operands[2], operands[3]);
3455 operands[6] = gen_rtx_fmt_ee (code, VOIDmode, operands[4], const0_rtx);
3458 else if (code == EQ || code == LE || code == LT
3459 || code == LEU || code == LTU)
3461 operands[5] = gen_rtx_fmt_ee (code, DImode, operands[2], operands[3]);
3462 operands[6] = gen_rtx_NE (VOIDmode, operands[4], const0_rtx);
3466 operands[5] = gen_rtx_fmt_ee (reverse_condition (code), DImode,
3467 operands[2], operands[3]);
3468 operands[6] = gen_rtx_EQ (VOIDmode, operands[4], const0_rtx);
3475 (match_operator 1 "comparison_operator"
3476 [(match_operand:SI 2 "reg_or_0_operand" "")
3477 (match_operand:SI 3 "const_int_operand" "")])
3478 (label_ref (match_operand 0 "" ""))
3480 (clobber (match_operand:DI 4 "register_operand" ""))]
3481 "operands[3] != const0_rtx
3482 && (GET_CODE (operands[1]) == EQ || GET_CODE (operands[1]) == NE)"
3483 [(set (match_dup 4) (match_dup 5))
3484 (set (pc) (if_then_else (match_dup 6) (label_ref (match_dup 0)) (pc)))]
3488 if (GET_CODE (operands[3]) == CONST_INT)
3489 tem = gen_rtx_PLUS (SImode, operands[2],
3490 GEN_INT (- INTVAL (operands[3])));
3492 tem = gen_rtx_MINUS (SImode, operands[2], operands[3]);
3494 operands[5] = gen_rtx_SIGN_EXTEND (DImode, tem);
3495 operands[6] = gen_rtx_fmt_ee (GET_CODE (operands[1]), VOIDmode,
3496 operands[4], const0_rtx);
3499 ;; We can convert such things as "a > 0xffff" to "t = a & ~ 0xffff; t != 0".
3500 ;; This eliminates one, and sometimes two, insns when the AND can be done
3503 [(set (match_operand:DI 0 "register_operand" "")
3504 (match_operator:DI 1 "comparison_operator"
3505 [(match_operand:DI 2 "register_operand" "")
3506 (match_operand:DI 3 "const_int_operand" "")]))
3507 (clobber (match_operand:DI 4 "register_operand" ""))]
3508 "exact_log2 (INTVAL (operands[3]) + 1) >= 0
3509 && (GET_CODE (operands[1]) == GTU
3510 || GET_CODE (operands[1]) == LEU
3511 || ((GET_CODE (operands[1]) == GT || GET_CODE (operands[1]) == LE)
3512 && extended_count (operands[2], DImode, 1) > 0))"
3513 [(set (match_dup 4) (and:DI (match_dup 2) (match_dup 5)))
3514 (set (match_dup 0) (match_dup 6))]
3517 operands[5] = GEN_INT (~ INTVAL (operands[3]));
3518 operands[6] = gen_rtx_fmt_ee (((GET_CODE (operands[1]) == GTU
3519 || GET_CODE (operands[1]) == GT)
3521 DImode, operands[4], const0_rtx);
3524 ;; Here are the CALL and unconditional branch insns. Calls on NT and OSF
3525 ;; work differently, so we have different patterns for each.
3527 (define_expand "call"
3528 [(use (match_operand:DI 0 "" ""))
3529 (use (match_operand 1 "" ""))
3530 (use (match_operand 2 "" ""))
3531 (use (match_operand 3 "" ""))]
3534 { if (TARGET_WINDOWS_NT)
3535 emit_call_insn (gen_call_nt (operands[0], operands[1]));
3536 else if (TARGET_OPEN_VMS)
3537 emit_call_insn (gen_call_vms (operands[0], operands[2]));
3539 emit_call_insn (gen_call_osf (operands[0], operands[1]));
3544 (define_expand "call_osf"
3545 [(parallel [(call (mem:DI (match_operand 0 "" ""))
3546 (match_operand 1 "" ""))
3547 (clobber (reg:DI 27))
3548 (clobber (reg:DI 26))])]
3551 { if (GET_CODE (operands[0]) != MEM)
3554 operands[0] = XEXP (operands[0], 0);
3556 if (GET_CODE (operands[0]) != SYMBOL_REF
3557 && ! (GET_CODE (operands[0]) == REG && REGNO (operands[0]) == 27))
3559 rtx tem = gen_rtx_REG (DImode, 27);
3560 emit_move_insn (tem, operands[0]);
3565 (define_expand "call_nt"
3566 [(parallel [(call (mem:DI (match_operand 0 "" ""))
3567 (match_operand 1 "" ""))
3568 (clobber (reg:DI 26))])]
3571 { if (GET_CODE (operands[0]) != MEM)
3574 operands[0] = XEXP (operands[0], 0);
3575 if (GET_CODE (operands[0]) != SYMBOL_REF && GET_CODE (operands[0]) != REG)
3576 operands[0] = force_reg (DImode, operands[0]);
3580 ;; call openvms/alpha
3581 ;; op 0: symbol ref for called function
3582 ;; op 1: next_arg_reg (argument information value for R25)
3584 (define_expand "call_vms"
3585 [(parallel [(call (mem:DI (match_operand 0 "" ""))
3586 (match_operand 1 "" ""))
3590 (clobber (reg:DI 27))])]
3593 { if (GET_CODE (operands[0]) != MEM)
3596 operands[0] = XEXP (operands[0], 0);
3598 /* Always load AI with argument information, then handle symbolic and
3599 indirect call differently. Load RA and set operands[2] to PV in
3602 emit_move_insn (gen_rtx_REG (DImode, 25), operands[1]);
3603 if (GET_CODE (operands[0]) == SYMBOL_REF)
3605 extern char *savealloc ();
3606 char *linksym, *symbol = XSTR (operands[0], 0);
3611 linksym = savealloc (strlen (symbol) + 6);
3613 alpha_need_linkage (symbol, 0);
3616 strcpy (linksym+1, symbol);
3617 strcat (linksym, \"..lk\");
3618 linkage = gen_rtx_SYMBOL_REF (Pmode, linksym);
3620 emit_move_insn (gen_rtx_REG (Pmode, 26), gen_rtx_MEM (Pmode, linkage));
3623 = validize_mem (gen_rtx_MEM (Pmode, plus_constant (linkage, 8)));
3627 emit_move_insn (gen_rtx_REG (Pmode, 26),
3628 gen_rtx_MEM (Pmode, plus_constant (operands[0], 8)));
3630 operands[2] = operands[0];
3635 (define_expand "call_value"
3636 [(use (match_operand 0 "" ""))
3637 (use (match_operand:DI 1 "" ""))
3638 (use (match_operand 2 "" ""))
3639 (use (match_operand 3 "" ""))
3640 (use (match_operand 4 "" ""))]
3643 { if (TARGET_WINDOWS_NT)
3644 emit_call_insn (gen_call_value_nt (operands[0], operands[1], operands[2]));
3645 else if (TARGET_OPEN_VMS)
3646 emit_call_insn (gen_call_value_vms (operands[0], operands[1],
3649 emit_call_insn (gen_call_value_osf (operands[0], operands[1],
3654 (define_expand "call_value_osf"
3655 [(parallel [(set (match_operand 0 "" "")
3656 (call (mem:DI (match_operand 1 "" ""))
3657 (match_operand 2 "" "")))
3658 (clobber (reg:DI 27))
3659 (clobber (reg:DI 26))])]
3662 { if (GET_CODE (operands[1]) != MEM)
3665 operands[1] = XEXP (operands[1], 0);
3667 if (GET_CODE (operands[1]) != SYMBOL_REF
3668 && ! (GET_CODE (operands[1]) == REG && REGNO (operands[1]) == 27))
3670 rtx tem = gen_rtx_REG (DImode, 27);
3671 emit_move_insn (tem, operands[1]);
3676 (define_expand "call_value_nt"
3677 [(parallel [(set (match_operand 0 "" "")
3678 (call (mem:DI (match_operand 1 "" ""))
3679 (match_operand 2 "" "")))
3680 (clobber (reg:DI 26))])]
3683 { if (GET_CODE (operands[1]) != MEM)
3686 operands[1] = XEXP (operands[1], 0);
3687 if (GET_CODE (operands[1]) != SYMBOL_REF && GET_CODE (operands[1]) != REG)
3688 operands[1] = force_reg (DImode, operands[1]);
3691 (define_expand "call_value_vms"
3692 [(parallel [(set (match_operand 0 "" "")
3693 (call (mem:DI (match_operand:DI 1 "" ""))
3694 (match_operand 2 "" "")))
3698 (clobber (reg:DI 27))])]
3701 { if (GET_CODE (operands[1]) != MEM)
3704 operands[1] = XEXP (operands[1], 0);
3706 /* Always load AI with argument information, then handle symbolic and
3707 indirect call differently. Load RA and set operands[3] to PV in
3710 emit_move_insn (gen_rtx_REG (DImode, 25), operands[2]);
3711 if (GET_CODE (operands[1]) == SYMBOL_REF)
3713 extern char *savealloc ();
3714 char *linksym, *symbol = XSTR (operands[1], 0);
3719 linksym = savealloc (strlen (symbol) + 6);
3721 alpha_need_linkage (symbol, 0);
3723 strcpy (linksym+1, symbol);
3724 strcat (linksym, \"..lk\");
3725 linkage = gen_rtx_SYMBOL_REF (Pmode, linksym);
3727 emit_move_insn (gen_rtx_REG (Pmode, 26), gen_rtx_MEM (Pmode, linkage));
3730 = validize_mem (gen_rtx_MEM (Pmode, plus_constant (linkage, 8)));
3734 emit_move_insn (gen_rtx_REG (Pmode, 26),
3735 gen_rtx_MEM (Pmode, plus_constant (operands[1], 8)));
3737 operands[3] = operands[1];
3742 [(call (mem:DI (match_operand:DI 0 "call_operand" "r,R,i"))
3743 (match_operand 1 "" ""))
3744 (clobber (reg:DI 27))
3745 (clobber (reg:DI 26))]
3746 "! TARGET_WINDOWS_NT && ! TARGET_OPEN_VMS"
3748 jsr $26,($27),0\;ldgp $29,0($26)
3750 jsr $26,%0\;ldgp $29,0($26)"
3751 [(set_attr "type" "jsr")
3752 (set_attr "length" "12,*,16")])
3755 [(call (mem:DI (match_operand:DI 0 "call_operand" "r,R,i"))
3756 (match_operand 1 "" ""))
3757 (clobber (reg:DI 26))]
3763 [(set_attr "type" "jsr")
3764 (set_attr "length" "*,*,12")])
3767 [(call (mem:DI (match_operand:DI 0 "call_operand" "r,i"))
3768 (match_operand 1 "" ""))
3769 (use (match_operand:DI 2 "nonimmediate_operand" "r,m"))
3772 (clobber (reg:DI 27))]
3775 mov %2,$27\;jsr $26,0\;ldq $27,0($29)
3776 ldq $27,%2\;jsr $26,%0\;ldq $27,0($29)"
3777 [(set_attr "type" "jsr")
3778 (set_attr "length" "12,16")])
3780 ;; Call subroutine returning any type.
3782 (define_expand "untyped_call"
3783 [(parallel [(call (match_operand 0 "" "")
3785 (match_operand 1 "" "")
3786 (match_operand 2 "" "")])]
3792 emit_call_insn (gen_call (operands[0], const0_rtx, NULL, const0_rtx));
3794 for (i = 0; i < XVECLEN (operands[2], 0); i++)
3796 rtx set = XVECEXP (operands[2], 0, i);
3797 emit_move_insn (SET_DEST (set), SET_SRC (set));
3800 /* The optimizer does not know that the call sets the function value
3801 registers we stored in the result block. We avoid problems by
3802 claiming that all hard registers are used and clobbered at this
3804 emit_insn (gen_blockage ());
3809 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
3810 ;; all of memory. This blocks insns from being moved across this point.
3812 (define_insn "blockage"
3813 [(unspec_volatile [(const_int 0)] 1)]
3816 [(set_attr "length" "0")])
3820 (label_ref (match_operand 0 "" "")))]
3823 [(set_attr "type" "ibr")])
3825 (define_insn "return"
3829 [(set_attr "type" "ibr")])
3831 ;; Use a different pattern for functions which have non-trivial
3832 ;; epilogues so as not to confuse jump and reorg.
3833 (define_insn "return_internal"
3838 [(set_attr "type" "ibr")])
3840 (define_insn "indirect_jump"
3841 [(set (pc) (match_operand:DI 0 "register_operand" "r"))]
3844 [(set_attr "type" "ibr")])
3846 (define_expand "tablejump"
3847 [(use (match_operand:SI 0 "register_operand" ""))
3848 (use (match_operand:SI 1 "" ""))]
3852 if (TARGET_WINDOWS_NT)
3853 emit_jump_insn (gen_tablejump_nt (operands[0], operands[1]));
3854 else if (TARGET_OPEN_VMS)
3855 emit_jump_insn (gen_tablejump_vms (operands[0], operands[1]));
3857 emit_jump_insn (gen_tablejump_osf (operands[0], operands[1]));
3862 (define_expand "tablejump_osf"
3864 (sign_extend:DI (match_operand:SI 0 "register_operand" "")))
3865 (parallel [(set (pc)
3866 (plus:DI (match_dup 3)
3867 (label_ref (match_operand 1 "" ""))))
3868 (clobber (match_scratch:DI 2 "=r"))])]
3871 { operands[3] = gen_reg_rtx (DImode); }")
3873 (define_expand "tablejump_nt"
3875 (sign_extend:DI (match_operand:SI 0 "register_operand" "")))
3876 (parallel [(set (pc)
3878 (use (label_ref (match_operand 1 "" "")))])]
3881 { operands[3] = gen_reg_rtx (DImode); }")
3884 ;; tablejump, openVMS way
3886 ;; op 1: label preceding jump-table
3888 (define_expand "tablejump_vms"
3890 (match_operand:DI 0 "register_operand" ""))
3892 (plus:DI (match_dup 2)
3893 (label_ref (match_operand 1 "" ""))))]
3896 { operands[2] = gen_reg_rtx (DImode); }")
3900 (plus (match_operand:DI 0 "register_operand" "r")
3901 (label_ref (match_operand 1 "" ""))))
3902 (clobber (match_scratch:DI 2 "=r"))]
3903 "! TARGET_WINDOWS_NT && ! TARGET_OPEN_VMS && next_active_insn (insn) != 0
3904 && GET_CODE (PATTERN (next_active_insn (insn))) == ADDR_DIFF_VEC
3905 && PREV_INSN (next_active_insn (insn)) == operands[1]"
3907 { rtx best_label = 0;
3908 rtx jump_table_insn = next_active_insn (operands[1]);
3910 if (GET_CODE (jump_table_insn) == JUMP_INSN
3911 && GET_CODE (PATTERN (jump_table_insn)) == ADDR_DIFF_VEC)
3913 rtx jump_table = PATTERN (jump_table_insn);
3914 int n_labels = XVECLEN (jump_table, 1);
3915 int best_count = -1;
3918 for (i = 0; i < n_labels; i++)
3922 for (j = i + 1; j < n_labels; j++)
3923 if (XEXP (XVECEXP (jump_table, 1, i), 0)
3924 == XEXP (XVECEXP (jump_table, 1, j), 0))
3927 if (count > best_count)
3928 best_count = count, best_label = XVECEXP (jump_table, 1, i);
3934 operands[3] = best_label;
3935 return \"addq %0,$29,%2\;jmp $31,(%2),%3\";
3938 return \"addq %0,$29,%2\;jmp $31,(%2),0\";
3940 [(set_attr "type" "ibr")
3941 (set_attr "length" "8")])
3945 (match_operand:DI 0 "register_operand" "r"))
3946 (use (label_ref (match_operand 1 "" "")))]
3947 "TARGET_WINDOWS_NT && next_active_insn (insn) != 0
3948 && GET_CODE (PATTERN (next_active_insn (insn))) == ADDR_DIFF_VEC
3949 && PREV_INSN (next_active_insn (insn)) == operands[1]"
3951 { rtx best_label = 0;
3952 rtx jump_table_insn = next_active_insn (operands[1]);
3954 if (GET_CODE (jump_table_insn) == JUMP_INSN
3955 && GET_CODE (PATTERN (jump_table_insn)) == ADDR_DIFF_VEC)
3957 rtx jump_table = PATTERN (jump_table_insn);
3958 int n_labels = XVECLEN (jump_table, 1);
3959 int best_count = -1;
3962 for (i = 0; i < n_labels; i++)
3966 for (j = i + 1; j < n_labels; j++)
3967 if (XEXP (XVECEXP (jump_table, 1, i), 0)
3968 == XEXP (XVECEXP (jump_table, 1, j), 0))
3971 if (count > best_count)
3972 best_count = count, best_label = XVECEXP (jump_table, 1, i);
3978 operands[2] = best_label;
3979 return \"jmp $31,(%0),%2\";
3982 return \"jmp $31,(%0),0\";
3984 [(set_attr "type" "ibr")])
3987 ;; op 0 is table offset
3988 ;; op 1 is table label
3993 (plus (match_operand:DI 0 "register_operand" "r")
3994 (label_ref (match_operand 1 "" ""))))]
3997 [(set_attr "type" "ibr")])
3999 ;; Cache flush. Used by INITIALIZE_TRAMPOLINE. 0x86 is PAL_imb, but we don't
4000 ;; want to have to include pal.h in our .s file.
4002 ;; Technically the type for call_pal is jsr, but we use that for determining
4003 ;; if we need a GP. Use ibr instead since it has the same EV5 scheduling
4006 [(unspec_volatile [(const_int 0)] 0)]
4009 [(set_attr "type" "ibr")])
4011 ;; Finally, we have the basic data motion insns. The byte and word insns
4012 ;; are done via define_expand. Start with the floating-point insns, since
4013 ;; they are simpler.
4016 [(set (match_operand:SF 0 "nonimmediate_operand" "=f,f,*r,*r,m,m")
4017 (match_operand:SF 1 "input_operand" "fG,m,*rG,m,fG,*r"))]
4019 && (register_operand (operands[0], SFmode)
4020 || reg_or_fp0_operand (operands[1], SFmode))"
4028 [(set_attr "type" "fcpys,fld,ilog,ild,fst,ist")])
4031 [(set (match_operand:SF 0 "nonimmediate_operand" "=f,f,*r,*r,m,m,f,*r")
4032 (match_operand:SF 1 "input_operand" "fG,m,*rG,m,fG,*r,*r,f"))]
4034 && (register_operand (operands[0], SFmode)
4035 || reg_or_fp0_operand (operands[1], SFmode))"
4045 [(set_attr "type" "fcpys,fld,ilog,ild,fst,ist,itof,ftoi")])
4048 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,f,*r,*r,m,m")
4049 (match_operand:DF 1 "input_operand" "fG,m,*rG,m,fG,*r"))]
4051 && (register_operand (operands[0], DFmode)
4052 || reg_or_fp0_operand (operands[1], DFmode))"
4060 [(set_attr "type" "fcpys,fld,ilog,ild,fst,ist")])
4063 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,f,*r,*r,m,m,f,*r")
4064 (match_operand:DF 1 "input_operand" "fG,m,*rG,m,fG,*r,*r,f"))]
4066 && (register_operand (operands[0], DFmode)
4067 || reg_or_fp0_operand (operands[1], DFmode))"
4077 [(set_attr "type" "fcpys,fld,ilog,ild,fst,ist,itof,ftoi")])
4079 (define_expand "movsf"
4080 [(set (match_operand:SF 0 "nonimmediate_operand" "")
4081 (match_operand:SF 1 "general_operand" ""))]
4085 if (GET_CODE (operands[0]) == MEM
4086 && ! reg_or_fp0_operand (operands[1], SFmode))
4087 operands[1] = force_reg (SFmode, operands[1]);
4090 (define_expand "movdf"
4091 [(set (match_operand:DF 0 "nonimmediate_operand" "")
4092 (match_operand:DF 1 "general_operand" ""))]
4096 if (GET_CODE (operands[0]) == MEM
4097 && ! reg_or_fp0_operand (operands[1], DFmode))
4098 operands[1] = force_reg (DFmode, operands[1]);
4102 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,r,r,m,*f,*f,m")
4103 (match_operand:SI 1 "input_operand" "rJ,K,L,m,rJ,*fJ,m,*f"))]
4104 "! TARGET_WINDOWS_NT && ! TARGET_OPEN_VMS && ! TARGET_FIX
4105 && (register_operand (operands[0], SImode)
4106 || reg_or_0_operand (operands[1], SImode))"
4116 [(set_attr "type" "ilog,iadd,iadd,ild,ist,fcpys,fld,fst")])
4119 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,r,r,m,*f,*f,m,r,*f")
4120 (match_operand:SI 1 "input_operand" "rJ,K,L,m,rJ,*fJ,m,*f,*f,r"))]
4121 "! TARGET_WINDOWS_NT && ! TARGET_OPEN_VMS && TARGET_FIX
4122 && (register_operand (operands[0], SImode)
4123 || reg_or_0_operand (operands[1], SImode))"
4135 [(set_attr "type" "ilog,iadd,iadd,ild,ist,fcpys,fld,fst,ftoi,itof")])
4138 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,r,r,r,m,*f,*f,m")
4139 (match_operand:SI 1 "input_operand" "rJ,K,L,s,m,rJ,*fJ,m,*f"))]
4140 "(TARGET_WINDOWS_NT || TARGET_OPEN_VMS)
4141 && (register_operand (operands[0], SImode)
4142 || reg_or_0_operand (operands[1], SImode))"
4153 [(set_attr "type" "ilog,iadd,iadd,ldsym,ild,ist,fcpys,fld,fst")])
4156 [(set (match_operand:HI 0 "register_operand" "=r,r")
4157 (match_operand:HI 1 "input_operand" "rJ,n"))]
4159 && (register_operand (operands[0], HImode)
4160 || register_operand (operands[1], HImode))"
4164 [(set_attr "type" "ilog,iadd")])
4167 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
4168 (match_operand:HI 1 "input_operand" "rJ,n,m,rJ"))]
4170 && (register_operand (operands[0], HImode)
4171 || reg_or_0_operand (operands[1], HImode))"
4177 [(set_attr "type" "ilog,iadd,ild,ist")])
4180 [(set (match_operand:QI 0 "register_operand" "=r,r")
4181 (match_operand:QI 1 "input_operand" "rJ,n"))]
4183 && (register_operand (operands[0], QImode)
4184 || register_operand (operands[1], QImode))"
4188 [(set_attr "type" "ilog,iadd")])
4191 [(set (match_operand:QI 0 "nonimmediate_operand" "=r,r,r,m")
4192 (match_operand:QI 1 "input_operand" "rJ,n,m,rJ"))]
4194 && (register_operand (operands[0], QImode)
4195 || reg_or_0_operand (operands[1], QImode))"
4201 [(set_attr "type" "ilog,iadd,ild,ist")])
4203 ;; We do two major things here: handle mem->mem and construct long
4206 (define_expand "movsi"
4207 [(set (match_operand:SI 0 "nonimmediate_operand" "")
4208 (match_operand:SI 1 "general_operand" ""))]
4212 if (GET_CODE (operands[0]) == MEM
4213 && ! reg_or_0_operand (operands[1], SImode))
4214 operands[1] = force_reg (SImode, operands[1]);
4216 if (! CONSTANT_P (operands[1]) || input_operand (operands[1], SImode))
4218 else if (GET_CODE (operands[1]) == CONST_INT)
4221 = alpha_emit_set_const (operands[0], SImode, INTVAL (operands[1]), 3);
4222 if (rtx_equal_p (operands[0], operands[1]))
4227 ;; Split a load of a large constant into the appropriate two-insn
4231 [(set (match_operand:SI 0 "register_operand" "")
4232 (match_operand:SI 1 "const_int_operand" ""))]
4233 "! add_operand (operands[1], SImode)"
4234 [(set (match_dup 0) (match_dup 2))
4235 (set (match_dup 0) (plus:SI (match_dup 0) (match_dup 3)))]
4238 = alpha_emit_set_const (operands[0], SImode, INTVAL (operands[1]), 2);
4240 if (tem == operands[0])
4247 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,r,r,r,m,*f,*f,Q")
4248 (match_operand:DI 1 "input_operand" "rJ,K,L,s,m,rJ,*fJ,Q,*f"))]
4250 && (register_operand (operands[0], DImode)
4251 || reg_or_0_operand (operands[1], DImode))"
4262 [(set_attr "type" "ilog,iadd,iadd,ldsym,ild,ist,fcpys,fld,fst")])
4265 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,r,r,r,m,*f,*f,Q,r,*f")
4266 (match_operand:DI 1 "input_operand" "rJ,K,L,s,m,rJ,*fJ,Q,*f,*f,r"))]
4268 && (register_operand (operands[0], DImode)
4269 || reg_or_0_operand (operands[1], DImode))"
4282 [(set_attr "type" "ilog,iadd,iadd,ldsym,ild,ist,fcpys,fld,fst,ftoi,itof")])
4284 ;; We do three major things here: handle mem->mem, put 64-bit constants in
4285 ;; memory, and construct long 32-bit constants.
4287 (define_expand "movdi"
4288 [(set (match_operand:DI 0 "nonimmediate_operand" "")
4289 (match_operand:DI 1 "general_operand" ""))]
4295 if (GET_CODE (operands[0]) == MEM
4296 && ! reg_or_0_operand (operands[1], DImode))
4297 operands[1] = force_reg (DImode, operands[1]);
4299 if (! CONSTANT_P (operands[1]) || input_operand (operands[1], DImode))
4301 else if (GET_CODE (operands[1]) == CONST_INT
4302 && (tem = alpha_emit_set_const (operands[0], DImode,
4303 INTVAL (operands[1]), 3)) != 0)
4305 if (rtx_equal_p (tem, operands[0]))
4310 else if (CONSTANT_P (operands[1]))
4312 if (TARGET_BUILD_CONSTANTS)
4314 HOST_WIDE_INT i0, i1;
4316 if (GET_CODE (operands[1]) == CONST_INT)
4318 i0 = INTVAL (operands[1]);
4321 else if (GET_CODE (operands[1]) == CONST_DOUBLE)
4323 #if HOST_BITS_PER_WIDE_INT >= 64
4324 i0 = CONST_DOUBLE_LOW (operands[1]);
4327 i0 = CONST_DOUBLE_LOW (operands[1]);
4328 i1 = CONST_DOUBLE_HIGH (operands[1]);
4334 tem = alpha_emit_set_long_const (operands[0], i0, i1);
4335 if (rtx_equal_p (tem, operands[0]))
4342 operands[1] = force_const_mem (DImode, operands[1]);
4343 if (reload_in_progress)
4345 emit_move_insn (operands[0], XEXP (operands[1], 0));
4346 operands[1] = copy_rtx (operands[1]);
4347 XEXP (operands[1], 0) = operands[0];
4350 operands[1] = validize_mem (operands[1]);
4357 ;; Split a load of a large constant into the appropriate two-insn
4361 [(set (match_operand:DI 0 "register_operand" "")
4362 (match_operand:DI 1 "const_int_operand" ""))]
4363 "! add_operand (operands[1], DImode)"
4364 [(set (match_dup 0) (match_dup 2))
4365 (set (match_dup 0) (plus:DI (match_dup 0) (match_dup 3)))]
4368 = alpha_emit_set_const (operands[0], DImode, INTVAL (operands[1]), 2);
4370 if (tem == operands[0])
4376 ;; These are the partial-word cases.
4378 ;; First we have the code to load an aligned word. Operand 0 is the register
4379 ;; in which to place the result. It's mode is QImode or HImode. Operand 1
4380 ;; is an SImode MEM at the low-order byte of the proper word. Operand 2 is the
4381 ;; number of bits within the word that the value is. Operand 3 is an SImode
4382 ;; scratch register. If operand 0 is a hard register, operand 3 may be the
4383 ;; same register. It is allowed to conflict with operand 1 as well.
4385 (define_expand "aligned_loadqi"
4386 [(set (match_operand:SI 3 "register_operand" "")
4387 (match_operand:SI 1 "memory_operand" ""))
4388 (set (subreg:DI (match_operand:QI 0 "register_operand" "") 0)
4389 (zero_extract:DI (subreg:DI (match_dup 3) 0)
4391 (match_operand:DI 2 "const_int_operand" "")))]
4396 (define_expand "aligned_loadhi"
4397 [(set (match_operand:SI 3 "register_operand" "")
4398 (match_operand:SI 1 "memory_operand" ""))
4399 (set (subreg:DI (match_operand:HI 0 "register_operand" "") 0)
4400 (zero_extract:DI (subreg:DI (match_dup 3) 0)
4402 (match_operand:DI 2 "const_int_operand" "")))]
4407 ;; Similar for unaligned loads, where we use the sequence from the
4408 ;; Alpha Architecture manual.
4410 ;; Operand 1 is the address. Operands 2 and 3 are temporaries, where
4411 ;; operand 3 can overlap the input and output registers.
4413 (define_expand "unaligned_loadqi"
4414 [(set (match_operand:DI 2 "register_operand" "")
4415 (mem:DI (and:DI (match_operand:DI 1 "address_operand" "")
4417 (set (match_operand:DI 3 "register_operand" "")
4419 (set (subreg:DI (match_operand:QI 0 "register_operand" "") 0)
4420 (zero_extract:DI (match_dup 2)
4422 (ashift:DI (match_dup 3) (const_int 3))))]
4426 (define_expand "unaligned_loadhi"
4427 [(set (match_operand:DI 2 "register_operand" "")
4428 (mem:DI (and:DI (match_operand:DI 1 "address_operand" "")
4430 (set (match_operand:DI 3 "register_operand" "")
4432 (set (subreg:DI (match_operand:QI 0 "register_operand" "") 0)
4433 (zero_extract:DI (match_dup 2)
4435 (ashift:DI (match_dup 3) (const_int 3))))]
4439 ;; Storing an aligned byte or word requires two temporaries. Operand 0 is the
4440 ;; aligned SImode MEM. Operand 1 is the register containing the
4441 ;; byte or word to store. Operand 2 is the number of bits within the word that
4442 ;; the value should be placed. Operands 3 and 4 are SImode temporaries.
4444 (define_expand "aligned_store"
4445 [(set (match_operand:SI 3 "register_operand" "")
4446 (match_operand:SI 0 "memory_operand" ""))
4447 (set (subreg:DI (match_dup 3) 0)
4448 (and:DI (subreg:DI (match_dup 3) 0) (match_dup 5)))
4449 (set (subreg:DI (match_operand:SI 4 "register_operand" "") 0)
4450 (ashift:DI (zero_extend:DI (match_operand 1 "register_operand" ""))
4451 (match_operand:DI 2 "const_int_operand" "")))
4452 (set (subreg:DI (match_dup 4) 0)
4453 (ior:DI (subreg:DI (match_dup 4) 0) (subreg:DI (match_dup 3) 0)))
4454 (set (match_dup 0) (match_dup 4))]
4457 { operands[5] = GEN_INT (~ (GET_MODE_MASK (GET_MODE (operands[1]))
4458 << INTVAL (operands[2])));
4461 ;; For the unaligned byte and halfword cases, we use code similar to that
4462 ;; in the ;; Architecture book, but reordered to lower the number of registers
4463 ;; required. Operand 0 is the address. Operand 1 is the data to store.
4464 ;; Operands 2, 3, and 4 are DImode temporaries, where operands 2 and 4 may
4465 ;; be the same temporary, if desired. If the address is in a register,
4466 ;; operand 2 can be that register.
4468 (define_expand "unaligned_storeqi"
4469 [(set (match_operand:DI 3 "register_operand" "")
4470 (mem:DI (and:DI (match_operand:DI 0 "address_operand" "")
4472 (set (match_operand:DI 2 "register_operand" "")
4475 (and:DI (not:DI (ashift:DI (const_int 255)
4476 (ashift:DI (match_dup 2) (const_int 3))))
4478 (set (match_operand:DI 4 "register_operand" "")
4479 (ashift:DI (zero_extend:DI (match_operand:QI 1 "register_operand" ""))
4480 (ashift:DI (match_dup 2) (const_int 3))))
4481 (set (match_dup 4) (ior:DI (match_dup 4) (match_dup 3)))
4482 (set (mem:DI (and:DI (match_dup 0) (const_int -8)))
4487 (define_expand "unaligned_storehi"
4488 [(set (match_operand:DI 3 "register_operand" "")
4489 (mem:DI (and:DI (match_operand:DI 0 "address_operand" "")
4491 (set (match_operand:DI 2 "register_operand" "")
4494 (and:DI (not:DI (ashift:DI (const_int 65535)
4495 (ashift:DI (match_dup 2) (const_int 3))))
4497 (set (match_operand:DI 4 "register_operand" "")
4498 (ashift:DI (zero_extend:DI (match_operand:HI 1 "register_operand" ""))
4499 (ashift:DI (match_dup 2) (const_int 3))))
4500 (set (match_dup 4) (ior:DI (match_dup 4) (match_dup 3)))
4501 (set (mem:DI (and:DI (match_dup 0) (const_int -8)))
4506 ;; Here are the define_expand's for QI and HI moves that use the above
4507 ;; patterns. We have the normal sets, plus the ones that need scratch
4508 ;; registers for reload.
4510 (define_expand "movqi"
4511 [(set (match_operand:QI 0 "nonimmediate_operand" "")
4512 (match_operand:QI 1 "general_operand" ""))]
4518 if (GET_CODE (operands[0]) == MEM
4519 && ! reg_or_0_operand (operands[1], QImode))
4520 operands[1] = force_reg (QImode, operands[1]);
4522 if (GET_CODE (operands[1]) == CONST_INT
4523 && ! input_operand (operands[1], QImode))
4525 operands[1] = alpha_emit_set_const (operands[0], QImode,
4526 INTVAL (operands[1]), 3);
4528 if (rtx_equal_p (operands[0], operands[1]))
4535 /* If the output is not a register, the input must be. */
4536 if (GET_CODE (operands[0]) == MEM)
4537 operands[1] = force_reg (QImode, operands[1]);
4539 /* Handle four memory cases, unaligned and aligned for either the input
4540 or the output. The only case where we can be called during reload is
4541 for aligned loads; all other cases require temporaries. */
4543 if (GET_CODE (operands[1]) == MEM
4544 || (GET_CODE (operands[1]) == SUBREG
4545 && GET_CODE (SUBREG_REG (operands[1])) == MEM)
4546 || (reload_in_progress && GET_CODE (operands[1]) == REG
4547 && REGNO (operands[1]) >= FIRST_PSEUDO_REGISTER)
4548 || (reload_in_progress && GET_CODE (operands[1]) == SUBREG
4549 && GET_CODE (SUBREG_REG (operands[1])) == REG
4550 && REGNO (SUBREG_REG (operands[1])) >= FIRST_PSEUDO_REGISTER))
4552 if (aligned_memory_operand (operands[1], QImode))
4554 if (reload_in_progress)
4556 emit_insn (gen_reload_inqi_help
4557 (operands[0], operands[1],
4558 gen_rtx_REG (SImode, REGNO (operands[0]))));
4562 rtx aligned_mem, bitnum;
4563 rtx scratch = gen_reg_rtx (SImode);
4565 get_aligned_mem (operands[1], &aligned_mem, &bitnum);
4567 emit_insn (gen_aligned_loadqi (operands[0], aligned_mem, bitnum,
4573 /* Don't pass these as parameters since that makes the generated
4574 code depend on parameter evaluation order which will cause
4575 bootstrap failures. */
4577 rtx temp1 = gen_reg_rtx (DImode);
4578 rtx temp2 = gen_reg_rtx (DImode);
4580 = gen_unaligned_loadqi (operands[0],
4581 get_unaligned_address (operands[1], 0),
4584 alpha_set_memflags (seq, operands[1]);
4591 else if (GET_CODE (operands[0]) == MEM
4592 || (GET_CODE (operands[0]) == SUBREG
4593 && GET_CODE (SUBREG_REG (operands[0])) == MEM)
4594 || (reload_in_progress && GET_CODE (operands[0]) == REG
4595 && REGNO (operands[0]) >= FIRST_PSEUDO_REGISTER)
4596 || (reload_in_progress && GET_CODE (operands[0]) == SUBREG
4597 && GET_CODE (SUBREG_REG (operands[0])) == REG
4598 && REGNO (operands[0]) >= FIRST_PSEUDO_REGISTER))
4600 if (aligned_memory_operand (operands[0], QImode))
4602 rtx aligned_mem, bitnum;
4603 rtx temp1 = gen_reg_rtx (SImode);
4604 rtx temp2 = gen_reg_rtx (SImode);
4606 get_aligned_mem (operands[0], &aligned_mem, &bitnum);
4608 emit_insn (gen_aligned_store (aligned_mem, operands[1], bitnum,
4613 rtx temp1 = gen_reg_rtx (DImode);
4614 rtx temp2 = gen_reg_rtx (DImode);
4615 rtx temp3 = gen_reg_rtx (DImode);
4617 = gen_unaligned_storeqi (get_unaligned_address (operands[0], 0),
4618 operands[1], temp1, temp2, temp3);
4620 alpha_set_memflags (seq, operands[0]);
4628 (define_expand "movhi"
4629 [(set (match_operand:HI 0 "nonimmediate_operand" "")
4630 (match_operand:HI 1 "general_operand" ""))]
4636 if (GET_CODE (operands[0]) == MEM
4637 && ! reg_or_0_operand (operands[1], HImode))
4638 operands[1] = force_reg (HImode, operands[1]);
4640 if (GET_CODE (operands[1]) == CONST_INT
4641 && ! input_operand (operands[1], HImode))
4643 operands[1] = alpha_emit_set_const (operands[0], HImode,
4644 INTVAL (operands[1]), 3);
4646 if (rtx_equal_p (operands[0], operands[1]))
4653 /* If the output is not a register, the input must be. */
4654 if (GET_CODE (operands[0]) == MEM)
4655 operands[1] = force_reg (HImode, operands[1]);
4657 /* Handle four memory cases, unaligned and aligned for either the input
4658 or the output. The only case where we can be called during reload is
4659 for aligned loads; all other cases require temporaries. */
4661 if (GET_CODE (operands[1]) == MEM
4662 || (GET_CODE (operands[1]) == SUBREG
4663 && GET_CODE (SUBREG_REG (operands[1])) == MEM)
4664 || (reload_in_progress && GET_CODE (operands[1]) == REG
4665 && REGNO (operands[1]) >= FIRST_PSEUDO_REGISTER)
4666 || (reload_in_progress && GET_CODE (operands[1]) == SUBREG
4667 && GET_CODE (SUBREG_REG (operands[1])) == REG
4668 && REGNO (SUBREG_REG (operands[1])) >= FIRST_PSEUDO_REGISTER))
4670 if (aligned_memory_operand (operands[1], HImode))
4672 if (reload_in_progress)
4674 emit_insn (gen_reload_inhi_help
4675 (operands[0], operands[1],
4676 gen_rtx_REG (SImode, REGNO (operands[0]))));
4680 rtx aligned_mem, bitnum;
4681 rtx scratch = gen_reg_rtx (SImode);
4683 get_aligned_mem (operands[1], &aligned_mem, &bitnum);
4685 emit_insn (gen_aligned_loadhi (operands[0], aligned_mem, bitnum,
4691 /* Don't pass these as parameters since that makes the generated
4692 code depend on parameter evaluation order which will cause
4693 bootstrap failures. */
4695 rtx temp1 = gen_reg_rtx (DImode);
4696 rtx temp2 = gen_reg_rtx (DImode);
4698 = gen_unaligned_loadhi (operands[0],
4699 get_unaligned_address (operands[1], 0),
4702 alpha_set_memflags (seq, operands[1]);
4709 else if (GET_CODE (operands[0]) == MEM
4710 || (GET_CODE (operands[0]) == SUBREG
4711 && GET_CODE (SUBREG_REG (operands[0])) == MEM)
4712 || (reload_in_progress && GET_CODE (operands[0]) == REG
4713 && REGNO (operands[0]) >= FIRST_PSEUDO_REGISTER)
4714 || (reload_in_progress && GET_CODE (operands[0]) == SUBREG
4715 && GET_CODE (SUBREG_REG (operands[0])) == REG
4716 && REGNO (operands[0]) >= FIRST_PSEUDO_REGISTER))
4718 if (aligned_memory_operand (operands[0], HImode))
4720 rtx aligned_mem, bitnum;
4721 rtx temp1 = gen_reg_rtx (SImode);
4722 rtx temp2 = gen_reg_rtx (SImode);
4724 get_aligned_mem (operands[0], &aligned_mem, &bitnum);
4726 emit_insn (gen_aligned_store (aligned_mem, operands[1], bitnum,
4731 rtx temp1 = gen_reg_rtx (DImode);
4732 rtx temp2 = gen_reg_rtx (DImode);
4733 rtx temp3 = gen_reg_rtx (DImode);
4735 = gen_unaligned_storehi (get_unaligned_address (operands[0], 0),
4736 operands[1], temp1, temp2, temp3);
4738 alpha_set_memflags (seq, operands[0]);
4747 ;; Here are the versions for reload. Note that in the unaligned cases
4748 ;; we know that the operand must not be a pseudo-register because stack
4749 ;; slots are always aligned references.
4751 (define_expand "reload_inqi"
4752 [(parallel [(match_operand:QI 0 "register_operand" "=r")
4753 (match_operand:QI 1 "any_memory_operand" "m")
4754 (match_operand:TI 2 "register_operand" "=&r")])]
4760 if (GET_CODE (operands[1]) != MEM)
4763 if (aligned_memory_operand (operands[1], QImode))
4765 seq = gen_reload_inqi_help (operands[0], operands[1],
4766 gen_rtx_REG (SImode, REGNO (operands[2])));
4772 /* It is possible that one of the registers we got for operands[2]
4773 might coincide with that of operands[0] (which is why we made
4774 it TImode). Pick the other one to use as our scratch. */
4775 if (REGNO (operands[0]) == REGNO (operands[2]))
4776 scratch = gen_rtx_REG (DImode, REGNO (operands[2]) + 1);
4778 scratch = gen_rtx_REG (DImode, REGNO (operands[2]));
4780 addr = get_unaligned_address (operands[1], 0);
4781 seq = gen_unaligned_loadqi (operands[0], addr, scratch,
4782 gen_rtx_REG (DImode, REGNO (operands[0])));
4783 alpha_set_memflags (seq, operands[1]);
4789 (define_expand "reload_inhi"
4790 [(parallel [(match_operand:HI 0 "register_operand" "=r")
4791 (match_operand:HI 1 "any_memory_operand" "m")
4792 (match_operand:TI 2 "register_operand" "=&r")])]
4798 if (GET_CODE (operands[1]) != MEM)
4801 if (aligned_memory_operand (operands[1], HImode))
4803 seq = gen_reload_inhi_help (operands[0], operands[1],
4804 gen_rtx_REG (SImode, REGNO (operands[2])));
4810 /* It is possible that one of the registers we got for operands[2]
4811 might coincide with that of operands[0] (which is why we made
4812 it TImode). Pick the other one to use as our scratch. */
4813 if (REGNO (operands[0]) == REGNO (operands[2]))
4814 scratch = gen_rtx_REG (DImode, REGNO (operands[2]) + 1);
4816 scratch = gen_rtx_REG (DImode, REGNO (operands[2]));
4818 addr = get_unaligned_address (operands[1], 0);
4819 seq = gen_unaligned_loadhi (operands[0], addr, scratch,
4820 gen_rtx_REG (DImode, REGNO (operands[0])));
4821 alpha_set_memflags (seq, operands[1]);
4827 (define_expand "reload_outqi"
4828 [(parallel [(match_operand:QI 0 "any_memory_operand" "=m")
4829 (match_operand:QI 1 "register_operand" "r")
4830 (match_operand:TI 2 "register_operand" "=&r")])]
4834 if (GET_CODE (operands[0]) != MEM)
4837 if (aligned_memory_operand (operands[0], QImode))
4839 emit_insn (gen_reload_outqi_help
4840 (operands[0], operands[1],
4841 gen_rtx_REG (SImode, REGNO (operands[2])),
4842 gen_rtx_REG (SImode, REGNO (operands[2]) + 1)));
4846 rtx addr = get_unaligned_address (operands[0], 0);
4847 rtx scratch1 = gen_rtx_REG (DImode, REGNO (operands[2]));
4848 rtx scratch2 = gen_rtx_REG (DImode, REGNO (operands[2]) + 1);
4849 rtx scratch3 = scratch1;
4852 if (GET_CODE (addr) == REG)
4855 seq = gen_unaligned_storeqi (addr, operands[1], scratch1,
4856 scratch2, scratch3);
4857 alpha_set_memflags (seq, operands[0]);
4863 (define_expand "reload_outhi"
4864 [(parallel [(match_operand:HI 0 "any_memory_operand" "=m")
4865 (match_operand:HI 1 "register_operand" "r")
4866 (match_operand:TI 2 "register_operand" "=&r")])]
4870 if (GET_CODE (operands[0]) != MEM)
4873 if (aligned_memory_operand (operands[0], HImode))
4875 emit_insn (gen_reload_outhi_help
4876 (operands[0], operands[1],
4877 gen_rtx_REG (SImode, REGNO (operands[2])),
4878 gen_rtx_REG (SImode, REGNO (operands[2]) + 1)));
4882 rtx addr = get_unaligned_address (operands[0], 0);
4883 rtx scratch1 = gen_rtx_REG (DImode, REGNO (operands[2]));
4884 rtx scratch2 = gen_rtx_REG (DImode, REGNO (operands[2]) + 1);
4885 rtx scratch3 = scratch1;
4888 if (GET_CODE (addr) == REG)
4891 seq = gen_unaligned_storehi (addr, operands[1], scratch1,
4892 scratch2, scratch3);
4893 alpha_set_memflags (seq, operands[0]);
4899 ;; Helpers for the above. The way reload is structured, we can't
4900 ;; always get a proper address for a stack slot during reload_foo
4901 ;; expansion, so we must delay our address manipulations until after.
4903 (define_insn "reload_inqi_help"
4904 [(set (match_operand:QI 0 "register_operand" "=r")
4905 (match_operand:QI 1 "memory_operand" "m"))
4906 (clobber (match_operand:SI 2 "register_operand" "=r"))]
4907 "! TARGET_BWX && (reload_in_progress || reload_completed)"
4910 (define_insn "reload_inhi_help"
4911 [(set (match_operand:HI 0 "register_operand" "=r")
4912 (match_operand:HI 1 "memory_operand" "m"))
4913 (clobber (match_operand:SI 2 "register_operand" "=r"))]
4914 "! TARGET_BWX && (reload_in_progress || reload_completed)"
4917 (define_insn "reload_outqi_help"
4918 [(set (match_operand:QI 0 "memory_operand" "=m")
4919 (match_operand:QI 1 "register_operand" "r"))
4920 (clobber (match_operand:SI 2 "register_operand" "=r"))
4921 (clobber (match_operand:SI 3 "register_operand" "=r"))]
4922 "! TARGET_BWX && (reload_in_progress || reload_completed)"
4925 (define_insn "reload_outhi_help"
4926 [(set (match_operand:HI 0 "memory_operand" "=m")
4927 (match_operand:HI 1 "register_operand" "r"))
4928 (clobber (match_operand:SI 2 "register_operand" "=r"))
4929 (clobber (match_operand:SI 3 "register_operand" "=r"))]
4930 "! TARGET_BWX && (reload_in_progress || reload_completed)"
4934 [(set (match_operand:QI 0 "register_operand" "")
4935 (match_operand:QI 1 "memory_operand" ""))
4936 (clobber (match_operand:SI 2 "register_operand" ""))]
4937 "! TARGET_BWX && reload_completed"
4941 rtx aligned_mem, bitnum;
4942 get_aligned_mem (operands[1], &aligned_mem, &bitnum);
4943 emit_insn (gen_aligned_loadqi (operands[0], aligned_mem, bitnum,
4949 [(set (match_operand:HI 0 "register_operand" "")
4950 (match_operand:HI 1 "memory_operand" ""))
4951 (clobber (match_operand:SI 2 "register_operand" ""))]
4952 "! TARGET_BWX && reload_completed"
4956 rtx aligned_mem, bitnum;
4957 get_aligned_mem (operands[1], &aligned_mem, &bitnum);
4958 emit_insn (gen_aligned_loadhi (operands[0], aligned_mem, bitnum,
4964 [(set (match_operand:QI 0 "memory_operand" "")
4965 (match_operand:QI 1 "register_operand" ""))
4966 (clobber (match_operand:SI 2 "register_operand" ""))
4967 (clobber (match_operand:SI 3 "register_operand" ""))]
4968 "! TARGET_BWX && reload_completed"
4972 rtx aligned_mem, bitnum;
4973 get_aligned_mem (operands[0], &aligned_mem, &bitnum);
4974 emit_insn (gen_aligned_store (aligned_mem, operands[1], bitnum,
4975 operands[2], operands[3]));
4980 [(set (match_operand:HI 0 "memory_operand" "")
4981 (match_operand:HI 1 "register_operand" ""))
4982 (clobber (match_operand:SI 2 "register_operand" ""))
4983 (clobber (match_operand:SI 3 "register_operand" ""))]
4984 "! TARGET_BWX && reload_completed"
4988 rtx aligned_mem, bitnum;
4989 get_aligned_mem (operands[0], &aligned_mem, &bitnum);
4990 emit_insn (gen_aligned_store (aligned_mem, operands[1], bitnum,
4991 operands[2], operands[3]));
4995 ;; Bit field extract patterns which use ext[wlq][lh]
4997 (define_expand "extv"
4998 [(set (match_operand:DI 0 "register_operand" "")
4999 (sign_extract:DI (match_operand:QI 1 "memory_operand" "")
5000 (match_operand:DI 2 "immediate_operand" "")
5001 (match_operand:DI 3 "immediate_operand" "")))]
5005 /* We can do 16, 32 and 64 bit fields, if aligned on byte boundaries. */
5006 if (INTVAL (operands[3]) % 8 != 0
5007 || (INTVAL (operands[2]) != 16
5008 && INTVAL (operands[2]) != 32
5009 && INTVAL (operands[2]) != 64))
5012 /* From mips.md: extract_bit_field doesn't verify that our source
5013 matches the predicate, so we force it to be a MEM here. */
5014 if (GET_CODE (operands[1]) != MEM)
5017 alpha_expand_unaligned_load (operands[0], operands[1],
5018 INTVAL (operands[2]) / 8,
5019 INTVAL (operands[3]) / 8, 1);
5023 (define_expand "extzv"
5024 [(set (match_operand:DI 0 "register_operand" "")
5025 (zero_extract:DI (match_operand:DI 1 "nonimmediate_operand" "")
5026 (match_operand:DI 2 "immediate_operand" "")
5027 (match_operand:DI 3 "immediate_operand" "")))]
5031 /* We can do 8, 16, 32 and 64 bit fields, if aligned on byte boundaries. */
5032 if (INTVAL (operands[3]) % 8 != 0
5033 || (INTVAL (operands[2]) != 8
5034 && INTVAL (operands[2]) != 16
5035 && INTVAL (operands[2]) != 32
5036 && INTVAL (operands[2]) != 64))
5039 if (GET_CODE (operands[1]) == MEM)
5041 /* Fail 8 bit fields, falling back on a simple byte load. */
5042 if (INTVAL (operands[2]) == 8)
5045 alpha_expand_unaligned_load (operands[0], operands[1],
5046 INTVAL (operands[2]) / 8,
5047 INTVAL (operands[3]) / 8, 0);
5052 (define_expand "insv"
5053 [(set (zero_extract:DI (match_operand:QI 0 "memory_operand" "")
5054 (match_operand:DI 1 "immediate_operand" "")
5055 (match_operand:DI 2 "immediate_operand" ""))
5056 (match_operand:DI 3 "register_operand" ""))]
5060 /* We can do 16, 32 and 64 bit fields, if aligned on byte boundaries. */
5061 if (INTVAL (operands[2]) % 8 != 0
5062 || (INTVAL (operands[1]) != 16
5063 && INTVAL (operands[1]) != 32
5064 && INTVAL (operands[1]) != 64))
5067 /* From mips.md: store_bit_field doesn't verify that our source
5068 matches the predicate, so we force it to be a MEM here. */
5069 if (GET_CODE (operands[0]) != MEM)
5072 alpha_expand_unaligned_store (operands[0], operands[3],
5073 INTVAL (operands[1]) / 8,
5074 INTVAL (operands[2]) / 8);
5080 ;; Block move/clear, see alpha.c for more details.
5081 ;; Argument 0 is the destination
5082 ;; Argument 1 is the source
5083 ;; Argument 2 is the length
5084 ;; Argument 3 is the alignment
5086 (define_expand "movstrqi"
5087 [(parallel [(set (match_operand:BLK 0 "memory_operand" "")
5088 (match_operand:BLK 1 "memory_operand" ""))
5089 (use (match_operand:DI 2 "immediate_operand" ""))
5090 (use (match_operand:DI 3 "immediate_operand" ""))])]
5094 if (alpha_expand_block_move (operands))
5100 (define_expand "clrstrqi"
5101 [(parallel [(set (match_operand:BLK 0 "memory_operand" "")
5103 (use (match_operand:DI 1 "immediate_operand" ""))
5104 (use (match_operand:DI 2 "immediate_operand" ""))])]
5108 if (alpha_expand_block_clear (operands))
5114 ;; Subroutine of stack space allocation. Perform a stack probe.
5115 (define_expand "probe_stack"
5116 [(set (match_dup 1) (match_operand:DI 0 "const_int_operand" ""))]
5120 operands[1] = gen_rtx_MEM (DImode, plus_constant (stack_pointer_rtx,
5121 INTVAL (operands[0])));
5122 MEM_VOLATILE_P (operands[1]) = 1;
5124 operands[0] = const0_rtx;
5127 ;; This is how we allocate stack space. If we are allocating a
5128 ;; constant amount of space and we know it is less than 4096
5129 ;; bytes, we need do nothing.
5131 ;; If it is more than 4096 bytes, we need to probe the stack
5133 (define_expand "allocate_stack"
5135 (plus:DI (reg:DI 30)
5136 (match_operand:DI 1 "reg_or_cint_operand" "")))
5137 (set (match_operand:DI 0 "register_operand" "=r")
5142 if (GET_CODE (operands[1]) == CONST_INT
5143 && INTVAL (operands[1]) < 32768)
5145 if (INTVAL (operands[1]) >= 4096)
5147 /* We do this the same way as in the prologue and generate explicit
5148 probes. Then we update the stack by the constant. */
5152 emit_insn (gen_probe_stack (GEN_INT (- probed)));
5153 while (probed + 8192 < INTVAL (operands[1]))
5154 emit_insn (gen_probe_stack (GEN_INT (- (probed += 8192))));
5156 if (probed + 4096 < INTVAL (operands[1]))
5157 emit_insn (gen_probe_stack (GEN_INT (- INTVAL(operands[1]))));
5160 operands[1] = GEN_INT (- INTVAL (operands[1]));
5161 operands[2] = virtual_stack_dynamic_rtx;
5166 rtx loop_label = gen_label_rtx ();
5167 rtx want = gen_reg_rtx (Pmode);
5168 rtx tmp = gen_reg_rtx (Pmode);
5171 emit_insn (gen_subdi3 (want, stack_pointer_rtx,
5172 force_reg (Pmode, operands[1])));
5173 emit_insn (gen_adddi3 (tmp, stack_pointer_rtx, GEN_INT (-4096)));
5175 if (GET_CODE (operands[1]) != CONST_INT)
5177 out_label = gen_label_rtx ();
5178 emit_insn (gen_cmpdi (want, tmp));
5179 emit_jump_insn (gen_bgeu (out_label));
5182 emit_label (loop_label);
5183 memref = gen_rtx_MEM (DImode, tmp);
5184 MEM_VOLATILE_P (memref) = 1;
5185 emit_move_insn (memref, const0_rtx);
5186 emit_insn (gen_adddi3 (tmp, tmp, GEN_INT(-8192)));
5187 emit_insn (gen_cmpdi (tmp, want));
5188 emit_jump_insn (gen_bgtu (loop_label));
5190 memref = gen_rtx_MEM (DImode, want);
5191 MEM_VOLATILE_P (memref) = 1;
5192 emit_move_insn (memref, const0_rtx);
5195 emit_label (out_label);
5197 emit_move_insn (stack_pointer_rtx, want);
5198 emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
5203 ;; This is used by alpha_expand_prolog to do the same thing as above,
5204 ;; except we cannot at that time generate new basic blocks, so we hide
5205 ;; the loop in this one insn.
5207 (define_insn "prologue_stack_probe_loop"
5208 [(unspec_volatile [(match_operand:DI 0 "register_operand" "r")
5209 (match_operand:DI 1 "register_operand" "r")] 5)]
5213 operands[2] = gen_label_rtx ();
5214 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, \"L\",
5215 CODE_LABEL_NUMBER (operands[2]));
5217 return \"stq $31,-8192(%1)\;subq %0,1,%0\;lda %1,-8192(%1)\;bne %0,%l2\";
5219 [(set_attr "length" "16")
5220 (set_attr "type" "multi")])
5222 (define_expand "prologue"
5223 [(clobber (const_int 0))]
5225 "alpha_expand_prologue (); DONE;")
5227 (define_insn "init_fp"
5228 [(set (match_operand:DI 0 "register_operand" "=r")
5229 (match_operand:DI 1 "register_operand" "r"))
5230 (clobber (mem:BLK (match_operand:DI 2 "register_operand" "=r")))]
5234 (define_expand "epilogue"
5235 [(clobber (const_int 0))]
5237 "alpha_expand_epilogue (); DONE;")
5239 (define_expand "eh_epilogue"
5240 [(use (match_operand:DI 0 "register_operand" "r"))
5241 (use (match_operand:DI 1 "register_operand" "r"))
5242 (use (match_operand:DI 2 "register_operand" "r"))]
5246 cfun->machine->eh_epilogue_sp_ofs = operands[1];
5247 if (GET_CODE (operands[2]) != REG || REGNO (operands[2]) != 26)
5249 rtx ra = gen_rtx_REG (Pmode, 26);
5250 emit_move_insn (ra, operands[2]);
5255 ;; In creating a large stack frame, NT _must_ use ldah+lda to load
5256 ;; the frame size into a register. We use this pattern to ensure
5257 ;; we get lda instead of addq.
5258 (define_insn "nt_lda"
5259 [(set (match_operand:DI 0 "register_operand" "=r")
5260 (unspec:DI [(match_dup 0)
5261 (match_operand:DI 1 "const_int_operand" "n")] 6))]
5265 (define_expand "builtin_longjmp"
5266 [(unspec_volatile [(match_operand:DI 0 "register_operand" "r")] 3)]
5267 "! TARGET_OPEN_VMS && ! TARGET_WINDOWS_NT"
5270 /* The elements of the buffer are, in order: */
5271 rtx fp = gen_rtx_MEM (Pmode, operands[0]);
5272 rtx lab = gen_rtx_MEM (Pmode, plus_constant (operands[0], 8));
5273 rtx stack = gen_rtx_MEM (Pmode, plus_constant (operands[0], 16));
5274 rtx pv = gen_rtx_REG (Pmode, 27);
5276 /* This bit is the same as expand_builtin_longjmp. */
5277 emit_move_insn (hard_frame_pointer_rtx, fp);
5278 emit_move_insn (pv, lab);
5279 emit_stack_restore (SAVE_NONLOCAL, stack, NULL_RTX);
5280 emit_insn (gen_rtx_USE (VOIDmode, hard_frame_pointer_rtx));
5281 emit_insn (gen_rtx_USE (VOIDmode, stack_pointer_rtx));
5283 /* Load the label we are jumping through into $27 so that we know
5284 where to look for it when we get back to setjmp's function for
5285 restoring the gp. */
5286 emit_indirect_jump (pv);
5290 (define_insn "builtin_setjmp_receiver"
5291 [(unspec_volatile [(label_ref (match_operand 0 "" ""))] 2)]
5292 "! TARGET_OPEN_VMS && ! TARGET_WINDOWS_NT && TARGET_AS_CAN_SUBTRACT_LABELS"
5293 "\\n$LSJ%=:\;ldgp $29,$LSJ%=-%l0($27)"
5294 [(set_attr "length" "8")
5295 (set_attr "type" "multi")])
5298 [(unspec_volatile [(label_ref (match_operand 0 "" ""))] 2)]
5299 "! TARGET_OPEN_VMS && ! TARGET_WINDOWS_NT"
5300 "br $29,$LSJ%=\\n$LSJ%=:\;ldgp $29,0($29)"
5301 [(set_attr "length" "12")
5302 (set_attr "type" "multi")])
5304 (define_insn "exception_receiver"
5305 [(unspec_volatile [(const_int 0)] 7)]
5306 "! TARGET_OPEN_VMS && ! TARGET_WINDOWS_NT"
5307 "br $29,$LSJ%=\\n$LSJ%=:\;ldgp $29,0($29)"
5308 [(set_attr "length" "12")
5309 (set_attr "type" "multi")])
5311 (define_expand "nonlocal_goto_receiver"
5312 [(unspec_volatile [(const_int 0)] 1)
5313 (set (reg:DI 27) (mem:DI (reg:DI 29)))
5314 (unspec_volatile [(const_int 0)] 1)
5319 (define_insn "arg_home"
5320 [(unspec [(const_int 0)] 0)
5335 (clobber (mem:BLK (const_int 0)))
5336 (clobber (reg:DI 24))
5337 (clobber (reg:DI 25))
5338 (clobber (reg:DI 0))]
5340 "lda $0,OTS$HOME_ARGS\;ldq $0,8($0)\;jsr $0,OTS$HOME_ARGS"
5341 [(set_attr "length" "16")
5342 (set_attr "type" "multi")])
5344 ;; Close the trap shadow of preceeding instructions. This is generated
5347 (define_insn "trapb"
5348 [(unspec_volatile [(const_int 0)] 4)]
5351 [(set_attr "type" "misc")])
5353 ;; No-op instructions used by machine-dependant reorg to preserve
5354 ;; alignment for instruction issue.
5360 [(set_attr "type" "ilog")])
5366 [(set_attr "type" "fcpys")])
5373 (define_insn "realign"
5374 [(unspec_volatile [(match_operand 0 "immediate_operand" "i")] 6)]
5376 ".align %0 #realign")
5378 ;; The call patterns are at the end of the file because their
5379 ;; wildcard operand0 interferes with nice recognition.
5382 [(set (match_operand 0 "" "")
5383 (call (mem:DI (match_operand:DI 1 "call_operand" "r,R,i"))
5384 (match_operand 2 "" "")))
5385 (clobber (reg:DI 27))
5386 (clobber (reg:DI 26))]
5387 "! TARGET_WINDOWS_NT && ! TARGET_OPEN_VMS"
5389 jsr $26,($27),0\;ldgp $29,0($26)
5391 jsr $26,%1\;ldgp $29,0($26)"
5392 [(set_attr "type" "jsr")
5393 (set_attr "length" "12,*,16")])
5396 [(set (match_operand 0 "" "")
5397 (call (mem:DI (match_operand:DI 1 "call_operand" "r,R,i"))
5398 (match_operand 2 "" "")))
5399 (clobber (reg:DI 26))]
5405 [(set_attr "type" "jsr")
5406 (set_attr "length" "*,*,12")])
5409 [(set (match_operand 0 "" "")
5410 (call (mem:DI (match_operand:DI 1 "call_operand" "r,i"))
5411 (match_operand 2 "" "")))
5412 (use (match_operand:DI 3 "nonimmediate_operand" "r,m"))
5415 (clobber (reg:DI 27))]
5418 mov %3,$27\;jsr $26,0\;ldq $27,0($29)
5419 ldq $27,%3\;jsr $26,%1\;ldq $27,0($29)"
5420 [(set_attr "type" "jsr")
5421 (set_attr "length" "12,16")])
5424 ;; Peepholes go at the end.
5426 ;; Optimize sign-extension of SImode loads. This shows up in the wake of
5427 ;; reload when converting fp->int.
5430 [(set (match_operand:SI 0 "register_operand" "=r")
5431 (match_operand:SI 1 "memory_operand" "m"))
5432 (set (match_operand:DI 2 "register_operand" "=r")
5433 (sign_extend:DI (match_dup 0)))]
5434 "dead_or_set_p (next_nonnote_insn (insn), operands[0])"
5436 (sign_extend:DI (match_dup 1)))]
5440 [(set (match_operand:SI 0 "register_operand" "=r")
5441 (match_operand:SI 1 "hard_fp_register_operand" "f"))
5442 (set (match_operand:DI 2 "register_operand" "=r")
5443 (sign_extend:DI (match_dup 0)))]
5444 "TARGET_FIX && dead_or_set_p (next_nonnote_insn (insn), operands[0])"
5446 (sign_extend:DI (match_dup 1)))]