alpha.c (alpha_emit_conditional_branch): Handle TFmode unordered compares properly.
[gcc.git] / gcc / config / alpha / alpha.md
1 ;; Machine description for DEC Alpha for GNU C compiler
2 ;; Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
3 ;; 2000 Free Software Foundation, Inc.
4 ;; Contributed by Richard Kenner (kenner@vlsi1.ultra.nyu.edu)
5
6 ;; This file is part of GNU CC.
7
8 ;; GNU CC is free software; you can redistribute it and/or modify
9 ;; it under the terms of the GNU General Public License as published by
10 ;; the Free Software Foundation; either version 2, or (at your option)
11 ;; any later version.
12
13 ;; GNU CC is distributed in the hope that it will be useful,
14 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
15 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 ;; GNU General Public License for more details.
17
18 ;; You should have received a copy of the GNU General Public License
19 ;; along with GNU CC; see the file COPYING. If not, write to
20 ;; the Free Software Foundation, 59 Temple Place - Suite 330,
21 ;; Boston, MA 02111-1307, USA.
22
23 ;;- See file "rtl.def" for documentation on define_insn, match_*, et. al.
24
25 ;; Uses of UNSPEC in this file:
26 ;;
27 ;; 0 arg_home
28 ;; 1 cttz
29 ;; 2 insxh
30 ;; 3 mskxh
31 ;; 5 cvtql
32 ;; 6 nt_lda
33 ;;
34 ;; UNSPEC_VOLATILE:
35 ;;
36 ;; 0 imb
37 ;; 1 blockage
38 ;; 2 builtin_setjmp_receiver
39 ;; 3 builtin_longjmp
40 ;; 4 trapb
41 ;; 5 prologue_stack_probe_loop
42 ;; 6 realign
43 ;; 7 exception_receiver
44 ;; 8 prologue_mcount
45 ;; 9 prologue_ldgp_1
46 ;; 10 prologue_ldgp_2
47 \f
48 ;; Processor type -- this attribute must exactly match the processor_type
49 ;; enumeration in alpha.h.
50
51 (define_attr "cpu" "ev4,ev5,ev6"
52 (const (symbol_ref "alpha_cpu")))
53
54 ;; Define an insn type attribute. This is used in function unit delay
55 ;; computations, among other purposes. For the most part, we use the names
56 ;; defined in the EV4 documentation, but add a few that we have to know about
57 ;; separately.
58
59 (define_attr "type"
60 "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"
61 (const_string "iadd"))
62
63 ;; Describe a user's asm statement.
64 (define_asm_attributes
65 [(set_attr "type" "multi")])
66
67 ;; Define the operand size an insn operates on. Used primarily by mul
68 ;; and div operations that have size dependant timings.
69
70 (define_attr "opsize" "si,di,udi" (const_string "di"))
71
72 ;; The TRAP_TYPE attribute marks instructions that may generate traps
73 ;; (which are imprecise and may need a trapb if software completion
74 ;; is desired).
75
76 (define_attr "trap" "no,yes" (const_string "no"))
77
78 ;; The length of an instruction sequence in bytes.
79
80 (define_attr "length" "" (const_int 4))
81 \f
82 ;; On EV4 there are two classes of resources to consider: resources needed
83 ;; to issue, and resources needed to execute. IBUS[01] are in the first
84 ;; category. ABOX, BBOX, EBOX, FBOX, IMUL & FDIV make up the second.
85 ;; (There are a few other register-like resources, but ...)
86
87 ; First, describe all of the issue constraints with single cycle delays.
88 ; All insns need a bus, but all except loads require one or the other.
89 (define_function_unit "ev4_ibus0" 1 0
90 (and (eq_attr "cpu" "ev4")
91 (eq_attr "type" "fst,fbr,iadd,imul,ilog,shift,icmov,icmp"))
92 1 1)
93
94 (define_function_unit "ev4_ibus1" 1 0
95 (and (eq_attr "cpu" "ev4")
96 (eq_attr "type" "ist,ibr,jsr,fadd,fcmov,fcpys,fmul,fdiv,misc"))
97 1 1)
98
99 ; Memory delivers its result in three cycles. Actually return one and
100 ; take care of this in adjust_cost, since we want to handle user-defined
101 ; memory latencies.
102 (define_function_unit "ev4_abox" 1 0
103 (and (eq_attr "cpu" "ev4")
104 (eq_attr "type" "ild,fld,ldsym,ist,fst"))
105 1 1)
106
107 ; Branches have no delay cost, but do tie up the unit for two cycles.
108 (define_function_unit "ev4_bbox" 1 1
109 (and (eq_attr "cpu" "ev4")
110 (eq_attr "type" "ibr,fbr,jsr"))
111 2 2)
112
113 ; Arithmetic insns are normally have their results available after
114 ; two cycles. There are a number of exceptions. They are encoded in
115 ; ADJUST_COST. Some of the other insns have similar exceptions.
116 (define_function_unit "ev4_ebox" 1 0
117 (and (eq_attr "cpu" "ev4")
118 (eq_attr "type" "iadd,ilog,shift,icmov,icmp,misc"))
119 2 1)
120
121 (define_function_unit "imul" 1 0
122 (and (eq_attr "cpu" "ev4")
123 (and (eq_attr "type" "imul")
124 (eq_attr "opsize" "si")))
125 21 19)
126
127 (define_function_unit "imul" 1 0
128 (and (eq_attr "cpu" "ev4")
129 (and (eq_attr "type" "imul")
130 (eq_attr "opsize" "!si")))
131 23 21)
132
133 (define_function_unit "ev4_fbox" 1 0
134 (and (eq_attr "cpu" "ev4")
135 (eq_attr "type" "fadd,fmul,fcpys,fcmov"))
136 6 1)
137
138 (define_function_unit "fdiv" 1 0
139 (and (eq_attr "cpu" "ev4")
140 (and (eq_attr "type" "fdiv")
141 (eq_attr "opsize" "si")))
142 34 30)
143
144 (define_function_unit "fdiv" 1 0
145 (and (eq_attr "cpu" "ev4")
146 (and (eq_attr "type" "fdiv")
147 (eq_attr "opsize" "di")))
148 63 59)
149 \f
150 ;; EV5 scheduling. EV5 can issue 4 insns per clock.
151 ;;
152 ;; EV5 has two asymetric integer units. Model this with E0 & E1 along
153 ;; with the combined resource EBOX.
154
155 (define_function_unit "ev5_ebox" 2 0
156 (and (eq_attr "cpu" "ev5")
157 (eq_attr "type" "!fbr,fcmov,fadd,fmul,fcpys,fdiv"))
158 1 1)
159
160 ; Memory takes at least 2 clocks. Return one from here and fix up with
161 ; user-defined latencies in adjust_cost.
162 (define_function_unit "ev5_ebox" 2 0
163 (and (eq_attr "cpu" "ev5")
164 (eq_attr "type" "ild,fld,ldsym"))
165 1 1)
166
167 ; Loads can dual issue with one another, but loads and stores do not mix.
168 (define_function_unit "ev5_e0" 1 0
169 (and (eq_attr "cpu" "ev5")
170 (eq_attr "type" "ild,fld,ldsym"))
171 1 1
172 [(eq_attr "type" "ist,fst")])
173
174 ; Stores, shifts, multiplies can only issue to E0
175 (define_function_unit "ev5_e0" 1 0
176 (and (eq_attr "cpu" "ev5")
177 (eq_attr "type" "ist,fst,shift,imul"))
178 1 1)
179
180 ; Motion video insns also issue only to E0, and take two ticks.
181 (define_function_unit "ev5_e0" 1 0
182 (and (eq_attr "cpu" "ev5")
183 (eq_attr "type" "mvi"))
184 2 1)
185
186 ; Conditional moves always take 2 ticks.
187 (define_function_unit "ev5_ebox" 2 0
188 (and (eq_attr "cpu" "ev5")
189 (eq_attr "type" "icmov"))
190 2 1)
191
192 ; Branches can only issue to E1
193 (define_function_unit "ev5_e1" 1 0
194 (and (eq_attr "cpu" "ev5")
195 (eq_attr "type" "ibr,jsr"))
196 1 1)
197
198 ; Multiplies also use the integer multiplier.
199 ; ??? How to: "No instruction can be issued to pipe E0 exactly two
200 ; cycles before an integer multiplication completes."
201 (define_function_unit "imul" 1 0
202 (and (eq_attr "cpu" "ev5")
203 (and (eq_attr "type" "imul")
204 (eq_attr "opsize" "si")))
205 8 4)
206
207 (define_function_unit "imul" 1 0
208 (and (eq_attr "cpu" "ev5")
209 (and (eq_attr "type" "imul")
210 (eq_attr "opsize" "di")))
211 12 8)
212
213 (define_function_unit "imul" 1 0
214 (and (eq_attr "cpu" "ev5")
215 (and (eq_attr "type" "imul")
216 (eq_attr "opsize" "udi")))
217 14 8)
218
219 ;; Similarly for the FPU we have two asymetric units. But fcpys can issue
220 ;; on either so we have to play the game again.
221
222 (define_function_unit "ev5_fbox" 2 0
223 (and (eq_attr "cpu" "ev5")
224 (eq_attr "type" "fadd,fcmov,fmul,fcpys,fbr,fdiv"))
225 4 1)
226
227 (define_function_unit "ev5_fm" 1 0
228 (and (eq_attr "cpu" "ev5")
229 (eq_attr "type" "fmul"))
230 4 1)
231
232 ; Add and cmov as you would expect; fbr never produces a result;
233 ; fdiv issues through fa to the divider,
234 (define_function_unit "ev5_fa" 1 0
235 (and (eq_attr "cpu" "ev5")
236 (eq_attr "type" "fadd,fcmov,fbr,fdiv"))
237 4 1)
238
239 ; ??? How to: "No instruction can be issued to pipe FA exactly five
240 ; cycles before a floating point divide completes."
241 (define_function_unit "fdiv" 1 0
242 (and (eq_attr "cpu" "ev5")
243 (and (eq_attr "type" "fdiv")
244 (eq_attr "opsize" "si")))
245 15 15) ; 15 to 31 data dependant
246
247 (define_function_unit "fdiv" 1 0
248 (and (eq_attr "cpu" "ev5")
249 (and (eq_attr "type" "fdiv")
250 (eq_attr "opsize" "di")))
251 22 22) ; 22 to 60 data dependant
252 \f
253 ;; EV6 scheduling. EV6 can issue 4 insns per clock.
254 ;;
255 ;; EV6 has two symmetric pairs ("clusters") of two asymetric integer units
256 ;; ("upper" and "lower"), yielding pipe names U0, U1, L0, L1.
257
258 ;; Conditional moves decompose into two independant primitives, each
259 ;; taking one cycle. Since ev6 is out-of-order, we can't see anything
260 ;; but two cycles.
261 (define_function_unit "ev6_ebox" 4 0
262 (and (eq_attr "cpu" "ev6")
263 (eq_attr "type" "icmov"))
264 2 1)
265
266 (define_function_unit "ev6_ebox" 4 0
267 (and (eq_attr "cpu" "ev6")
268 (eq_attr "type" "!fbr,fcmov,fadd,fmul,fcpys,fdiv,fsqrt"))
269 1 1)
270
271 ;; Integer loads take at least 3 clocks, and only issue to lower units.
272 ;; Return one from here and fix up with user-defined latencies in adjust_cost.
273 (define_function_unit "ev6_l" 2 0
274 (and (eq_attr "cpu" "ev6")
275 (eq_attr "type" "ild,ldsym,ist,fst"))
276 1 1)
277
278 ;; FP loads take at least 4 clocks. Return two from here...
279 (define_function_unit "ev6_l" 2 0
280 (and (eq_attr "cpu" "ev6")
281 (eq_attr "type" "fld"))
282 2 1)
283
284 ;; Motion video insns also issue only to U0, and take three ticks.
285 (define_function_unit "ev6_u0" 1 0
286 (and (eq_attr "cpu" "ev6")
287 (eq_attr "type" "mvi"))
288 3 1)
289
290 (define_function_unit "ev6_u" 2 0
291 (and (eq_attr "cpu" "ev6")
292 (eq_attr "type" "mvi"))
293 3 1)
294
295 ;; Shifts issue to either upper pipe.
296 (define_function_unit "ev6_u" 2 0
297 (and (eq_attr "cpu" "ev6")
298 (eq_attr "type" "shift"))
299 1 1)
300
301 ;; Multiplies issue only to U1, and all take 7 ticks.
302 ;; Rather than create a new function unit just for U1, reuse IMUL
303 (define_function_unit "imul" 1 0
304 (and (eq_attr "cpu" "ev6")
305 (eq_attr "type" "imul"))
306 7 1)
307
308 (define_function_unit "ev6_u" 2 0
309 (and (eq_attr "cpu" "ev6")
310 (eq_attr "type" "imul"))
311 7 1)
312
313 ;; Branches issue to either upper pipe
314 (define_function_unit "ev6_u" 2 0
315 (and (eq_attr "cpu" "ev6")
316 (eq_attr "type" "ibr"))
317 3 1)
318
319 ;; Calls only issue to L0.
320 (define_function_unit "ev6_l0" 1 0
321 (and (eq_attr "cpu" "ev6")
322 (eq_attr "type" "jsr"))
323 1 1)
324
325 (define_function_unit "ev6_l" 2 0
326 (and (eq_attr "cpu" "ev6")
327 (eq_attr "type" "jsr"))
328 1 1)
329
330 ;; Ftoi/itof only issue to lower pipes
331 (define_function_unit "ev6_l" 2 0
332 (and (eq_attr "cpu" "ev6")
333 (eq_attr "type" "ftoi"))
334 3 1)
335
336 (define_function_unit "ev6_l" 2 0
337 (and (eq_attr "cpu" "ev6")
338 (eq_attr "type" "itof"))
339 4 1)
340
341 ;; For the FPU we are very similar to EV5, except there's no insn that
342 ;; can issue to fm & fa, so we get to leave that out.
343
344 (define_function_unit "ev6_fm" 1 0
345 (and (eq_attr "cpu" "ev6")
346 (eq_attr "type" "fmul"))
347 4 1)
348
349 (define_function_unit "ev6_fa" 1 0
350 (and (eq_attr "cpu" "ev6")
351 (eq_attr "type" "fadd,fcpys,fbr,fdiv,fsqrt"))
352 4 1)
353
354 (define_function_unit "ev6_fa" 1 0
355 (and (eq_attr "cpu" "ev6")
356 (eq_attr "type" "fcmov"))
357 8 1)
358
359 (define_function_unit "fdiv" 1 0
360 (and (eq_attr "cpu" "ev6")
361 (and (eq_attr "type" "fdiv")
362 (eq_attr "opsize" "si")))
363 12 10)
364
365 (define_function_unit "fdiv" 1 0
366 (and (eq_attr "cpu" "ev6")
367 (and (eq_attr "type" "fdiv")
368 (eq_attr "opsize" "di")))
369 15 13)
370
371 (define_function_unit "fsqrt" 1 0
372 (and (eq_attr "cpu" "ev6")
373 (and (eq_attr "type" "fsqrt")
374 (eq_attr "opsize" "si")))
375 16 14)
376
377 (define_function_unit "fsqrt" 1 0
378 (and (eq_attr "cpu" "ev6")
379 (and (eq_attr "type" "fsqrt")
380 (eq_attr "opsize" "di")))
381 32 30)
382
383 ; ??? The FPU communicates with memory and the integer register file
384 ; via two fp store units. We need a slot in the fst immediately, and
385 ; a slot in LOW after the operand data is ready. At which point the
386 ; data may be moved either to the store queue or the integer register
387 ; file and the insn retired.
388
389 \f
390 ;; First define the arithmetic insns. Note that the 32-bit forms also
391 ;; sign-extend.
392
393 ;; Handle 32-64 bit extension from memory to a floating point register
394 ;; specially, since this ocurrs frequently in int->double conversions.
395 ;;
396 ;; Note that while we must retain the =f case in the insn for reload's
397 ;; benefit, it should be eliminated after reload, so we should never emit
398 ;; code for that case. But we don't reject the possibility.
399
400 (define_expand "extendsidi2"
401 [(set (match_operand:DI 0 "register_operand" "")
402 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "")))]
403 ""
404 "")
405
406 (define_insn ""
407 [(set (match_operand:DI 0 "register_operand" "=r,r,*f,?*f")
408 (sign_extend:DI
409 (match_operand:SI 1 "nonimmediate_operand" "r,m,*f,m")))]
410 "! TARGET_FIX"
411 "@
412 addl %1,$31,%0
413 ldl %0,%1
414 cvtlq %1,%0
415 lds %0,%1\;cvtlq %0,%0"
416 [(set_attr "type" "iadd,ild,fadd,fld")
417 (set_attr "length" "*,*,*,8")])
418
419 (define_insn ""
420 [(set (match_operand:DI 0 "register_operand" "=r,r,r,*f,?*f")
421 (sign_extend:DI
422 (match_operand:SI 1 "nonimmediate_operand" "r,m,*f,*f,m")))]
423 "TARGET_FIX"
424 "@
425 addl %1,$31,%0
426 ldl %0,%1
427 ftois %1,%0
428 cvtlq %1,%0
429 lds %0,%1\;cvtlq %0,%0"
430 [(set_attr "type" "iadd,ild,ftoi,fadd,fld")
431 (set_attr "length" "*,*,*,*,8")])
432
433 ;; Due to issues with CLASS_CANNOT_CHANGE_SIZE, we cannot use a subreg here.
434 (define_split
435 [(set (match_operand:DI 0 "hard_fp_register_operand" "")
436 (sign_extend:DI (match_operand:SI 1 "memory_operand" "")))]
437 "reload_completed"
438 [(set (match_dup 2) (match_dup 1))
439 (set (match_dup 0) (sign_extend:DI (match_dup 2)))]
440 "operands[2] = gen_rtx_REG (SImode, REGNO (operands[0]));")
441
442 ;; Do addsi3 the way expand_binop would do if we didn't have one. This
443 ;; generates better code. We have the anonymous addsi3 pattern below in
444 ;; case combine wants to make it.
445 (define_expand "addsi3"
446 [(set (match_operand:SI 0 "register_operand" "")
447 (plus:SI (match_operand:SI 1 "reg_or_0_operand" "")
448 (match_operand:SI 2 "add_operand" "")))]
449 ""
450 "
451 {
452 if (optimize)
453 {
454 rtx op1 = gen_lowpart (DImode, operands[1]);
455 rtx op2 = gen_lowpart (DImode, operands[2]);
456
457 if (! cse_not_expected)
458 {
459 rtx tmp = gen_reg_rtx (DImode);
460 emit_insn (gen_adddi3 (tmp, op1, op2));
461 emit_move_insn (gen_lowpart (DImode, operands[0]), tmp);
462 }
463 else
464 emit_insn (gen_adddi3 (gen_lowpart (DImode, operands[0]), op1, op2));
465 DONE;
466 }
467 }")
468
469 (define_insn ""
470 [(set (match_operand:SI 0 "register_operand" "=r,r,r,r")
471 (plus:SI (match_operand:SI 1 "reg_or_0_operand" "%rJ,rJ,rJ,rJ")
472 (match_operand:SI 2 "add_operand" "rI,O,K,L")))]
473 ""
474 "@
475 addl %r1,%2,%0
476 subl %r1,%n2,%0
477 lda %0,%2(%r1)
478 ldah %0,%h2(%r1)")
479
480 (define_split
481 [(set (match_operand:SI 0 "register_operand" "")
482 (plus:SI (match_operand:SI 1 "register_operand" "")
483 (match_operand:SI 2 "const_int_operand" "")))]
484 "! add_operand (operands[2], SImode)"
485 [(set (match_dup 0) (plus:SI (match_dup 1) (match_dup 3)))
486 (set (match_dup 0) (plus:SI (match_dup 0) (match_dup 4)))]
487 "
488 {
489 HOST_WIDE_INT val = INTVAL (operands[2]);
490 HOST_WIDE_INT low = (val & 0xffff) - 2 * (val & 0x8000);
491 HOST_WIDE_INT rest = val - low;
492
493 operands[3] = GEN_INT (rest);
494 operands[4] = GEN_INT (low);
495 }")
496
497 (define_insn ""
498 [(set (match_operand:DI 0 "register_operand" "=r,r")
499 (sign_extend:DI
500 (plus:SI (match_operand:SI 1 "reg_or_0_operand" "%rJ,rJ")
501 (match_operand:SI 2 "sext_add_operand" "rI,O"))))]
502 ""
503 "@
504 addl %r1,%2,%0
505 subl %r1,%n2,%0")
506
507 (define_split
508 [(set (match_operand:DI 0 "register_operand" "")
509 (sign_extend:DI
510 (plus:SI (match_operand:SI 1 "reg_not_elim_operand" "")
511 (match_operand:SI 2 "const_int_operand" ""))))
512 (clobber (match_operand:SI 3 "reg_not_elim_operand" ""))]
513 "! sext_add_operand (operands[2], SImode) && INTVAL (operands[2]) > 0
514 && INTVAL (operands[2]) % 4 == 0"
515 [(set (match_dup 3) (match_dup 4))
516 (set (match_dup 0) (sign_extend:DI (plus:SI (mult:SI (match_dup 3)
517 (match_dup 5))
518 (match_dup 1))))]
519 "
520 {
521 HOST_WIDE_INT val = INTVAL (operands[2]) / 4;
522 int mult = 4;
523
524 if (val % 2 == 0)
525 val /= 2, mult = 8;
526
527 operands[4] = GEN_INT (val);
528 operands[5] = GEN_INT (mult);
529 }")
530
531 (define_split
532 [(set (match_operand:DI 0 "register_operand" "")
533 (sign_extend:DI
534 (plus:SI (match_operator:SI 1 "comparison_operator"
535 [(match_operand 2 "" "")
536 (match_operand 3 "" "")])
537 (match_operand:SI 4 "add_operand" ""))))
538 (clobber (match_operand:DI 5 "register_operand" ""))]
539 ""
540 [(set (match_dup 5) (match_dup 6))
541 (set (match_dup 0) (sign_extend:DI (plus:SI (match_dup 7) (match_dup 4))))]
542 "
543 {
544 operands[6] = gen_rtx_fmt_ee (GET_CODE (operands[1]), DImode,
545 operands[2], operands[3]);
546 operands[7] = gen_lowpart (SImode, operands[5]);
547 }")
548
549 (define_expand "adddi3"
550 [(set (match_operand:DI 0 "register_operand" "")
551 (plus:DI (match_operand:DI 1 "register_operand" "")
552 (match_operand:DI 2 "add_operand" "")))]
553 ""
554 "")
555
556 ;; This pattern exists so that register elimination tries to canonize
557 ;; (plus (plus reg c1) c2).
558
559 (define_insn "*lda"
560 [(set (match_operand:DI 0 "register_operand" "=r")
561 (match_operand:DI 1 "addition_operation" "p"))]
562 ""
563 "lda %0,%a1")
564
565 ;; We used to expend quite a lot of effort choosing addq/subq/lda.
566 ;; With complications like
567 ;;
568 ;; The NT stack unwind code can't handle a subq to adjust the stack
569 ;; (that's a bug, but not one we can do anything about). As of NT4.0 SP3,
570 ;; the exception handling code will loop if a subq is used and an
571 ;; exception occurs.
572 ;;
573 ;; The 19980616 change to emit prologues as RTL also confused some
574 ;; versions of GDB, which also interprets prologues. This has been
575 ;; fixed as of GDB 4.18, but it does not harm to unconditionally
576 ;; use lda here.
577 ;;
578 ;; and the fact that the three insns schedule exactly the same, it's
579 ;; just not worth the effort.
580
581 (define_insn "*adddi_2"
582 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
583 (plus:DI (match_operand:DI 1 "register_operand" "%r,r,r")
584 (match_operand:DI 2 "add_operand" "r,K,L")))]
585 ""
586 "@
587 addq %1,%2,%0
588 lda %0,%2(%1)
589 ldah %0,%h2(%1)")
590
591 ;; ??? Allow large constants when basing off the frame pointer or some
592 ;; virtual register that may eliminate to the frame pointer. This is
593 ;; done because register elimination offsets will change the hi/lo split,
594 ;; and if we split before reload, we will require additional instructions.
595
596 (define_insn ""
597 [(set (match_operand:DI 0 "register_operand" "=r")
598 (plus:DI (match_operand:DI 1 "reg_no_subreg_operand" "r")
599 (match_operand:DI 2 "const_int_operand" "n")))]
600 "REG_OK_FP_BASE_P (operands[1])
601 && INTVAL (operands[2]) >= 0
602 /* This is the largest constant an lda+ldah pair can add, minus
603 an upper bound on the displacement between SP and AP during
604 register elimination. See INITIAL_ELIMINATION_OFFSET. */
605 && INTVAL (operands[2])
606 < (0x7fff8000
607 - FIRST_PSEUDO_REGISTER * UNITS_PER_WORD
608 - ALPHA_ROUND(current_function_outgoing_args_size)
609 - (ALPHA_ROUND (get_frame_size ()
610 + max_reg_num () * UNITS_PER_WORD
611 + current_function_pretend_args_size)
612 - current_function_pretend_args_size))"
613 "#")
614
615 ;; Don't do this if we are adjusting SP since we don't want to do it
616 ;; in two steps. Don't split FP sources for the reason listed above.
617 (define_split
618 [(set (match_operand:DI 0 "register_operand" "")
619 (plus:DI (match_operand:DI 1 "register_operand" "")
620 (match_operand:DI 2 "const_int_operand" "")))]
621 "! add_operand (operands[2], DImode)
622 && operands[0] != stack_pointer_rtx
623 && operands[1] != frame_pointer_rtx
624 && operands[1] != arg_pointer_rtx"
625 [(set (match_dup 0) (plus:DI (match_dup 1) (match_dup 3)))
626 (set (match_dup 0) (plus:DI (match_dup 0) (match_dup 4)))]
627 "
628 {
629 HOST_WIDE_INT val = INTVAL (operands[2]);
630 HOST_WIDE_INT low = (val & 0xffff) - 2 * (val & 0x8000);
631 HOST_WIDE_INT rest = val - low;
632
633 operands[4] = GEN_INT (low);
634 if (CONST_OK_FOR_LETTER_P (rest, 'L'))
635 operands[3] = GEN_INT (rest);
636 else if (! no_new_pseudos)
637 {
638 operands[3] = gen_reg_rtx (DImode);
639 emit_move_insn (operands[3], operands[2]);
640 emit_insn (gen_adddi3 (operands[0], operands[1], operands[3]));
641 DONE;
642 }
643 else
644 FAIL;
645 }")
646
647 (define_insn ""
648 [(set (match_operand:SI 0 "register_operand" "=r,r")
649 (plus:SI (mult:SI (match_operand:SI 1 "reg_not_elim_operand" "r,r")
650 (match_operand:SI 2 "const48_operand" "I,I"))
651 (match_operand:SI 3 "sext_add_operand" "rI,O")))]
652 ""
653 "@
654 s%2addl %1,%3,%0
655 s%2subl %1,%n3,%0")
656
657 (define_insn ""
658 [(set (match_operand:DI 0 "register_operand" "=r,r")
659 (sign_extend:DI
660 (plus:SI (mult:SI (match_operand:SI 1 "reg_not_elim_operand" "r,r")
661 (match_operand:SI 2 "const48_operand" "I,I"))
662 (match_operand:SI 3 "sext_add_operand" "rI,O"))))]
663 ""
664 "@
665 s%2addl %1,%3,%0
666 s%2subl %1,%n3,%0")
667
668 (define_split
669 [(set (match_operand:DI 0 "register_operand" "")
670 (sign_extend:DI
671 (plus:SI (mult:SI (match_operator:SI 1 "comparison_operator"
672 [(match_operand 2 "" "")
673 (match_operand 3 "" "")])
674 (match_operand:SI 4 "const48_operand" ""))
675 (match_operand:SI 5 "sext_add_operand" ""))))
676 (clobber (match_operand:DI 6 "reg_not_elim_operand" ""))]
677 ""
678 [(set (match_dup 6) (match_dup 7))
679 (set (match_dup 0)
680 (sign_extend:DI (plus:SI (mult:SI (match_dup 8) (match_dup 4))
681 (match_dup 5))))]
682 "
683 {
684 operands[7] = gen_rtx_fmt_ee (GET_CODE (operands[1]), DImode,
685 operands[2], operands[3]);
686 operands[8] = gen_lowpart (SImode, operands[6]);
687 }")
688
689 (define_insn ""
690 [(set (match_operand:DI 0 "register_operand" "=r,r")
691 (plus:DI (mult:DI (match_operand:DI 1 "reg_not_elim_operand" "r,r")
692 (match_operand:DI 2 "const48_operand" "I,I"))
693 (match_operand:DI 3 "sext_add_operand" "rI,O")))]
694 ""
695 "@
696 s%2addq %1,%3,%0
697 s%2subq %1,%n3,%0")
698
699 (define_insn "negsi2"
700 [(set (match_operand:SI 0 "register_operand" "=r")
701 (neg:SI (match_operand:SI 1 "reg_or_8bit_operand" "rI")))]
702 ""
703 "subl $31,%1,%0")
704
705 (define_insn ""
706 [(set (match_operand:DI 0 "register_operand" "=r")
707 (sign_extend:DI (neg:SI
708 (match_operand:SI 1 "reg_or_8bit_operand" "rI"))))]
709 ""
710 "subl $31,%1,%0")
711
712 (define_insn "negdi2"
713 [(set (match_operand:DI 0 "register_operand" "=r")
714 (neg:DI (match_operand:DI 1 "reg_or_8bit_operand" "rI")))]
715 ""
716 "subq $31,%1,%0")
717
718 (define_expand "subsi3"
719 [(set (match_operand:SI 0 "register_operand" "")
720 (minus:SI (match_operand:SI 1 "reg_or_0_operand" "")
721 (match_operand:SI 2 "reg_or_8bit_operand" "")))]
722 ""
723 "
724 {
725 if (optimize)
726 {
727 rtx op1 = gen_lowpart (DImode, operands[1]);
728 rtx op2 = gen_lowpart (DImode, operands[2]);
729
730 if (! cse_not_expected)
731 {
732 rtx tmp = gen_reg_rtx (DImode);
733 emit_insn (gen_subdi3 (tmp, op1, op2));
734 emit_move_insn (gen_lowpart (DImode, operands[0]), tmp);
735 }
736 else
737 emit_insn (gen_subdi3 (gen_lowpart (DImode, operands[0]), op1, op2));
738 DONE;
739 }
740 } ")
741
742 (define_insn ""
743 [(set (match_operand:SI 0 "register_operand" "=r")
744 (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rJ")
745 (match_operand:SI 2 "reg_or_8bit_operand" "rI")))]
746 ""
747 "subl %r1,%2,%0")
748
749 (define_insn ""
750 [(set (match_operand:DI 0 "register_operand" "=r")
751 (sign_extend:DI (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rJ")
752 (match_operand:SI 2 "reg_or_8bit_operand" "rI"))))]
753 ""
754 "subl %r1,%2,%0")
755
756 (define_insn "subdi3"
757 [(set (match_operand:DI 0 "register_operand" "=r")
758 (minus:DI (match_operand:DI 1 "reg_or_0_operand" "rJ")
759 (match_operand:DI 2 "reg_or_8bit_operand" "rI")))]
760 ""
761 "subq %r1,%2,%0")
762
763 (define_insn ""
764 [(set (match_operand:SI 0 "register_operand" "=r")
765 (minus:SI (mult:SI (match_operand:SI 1 "reg_not_elim_operand" "r")
766 (match_operand:SI 2 "const48_operand" "I"))
767 (match_operand:SI 3 "reg_or_8bit_operand" "rI")))]
768 ""
769 "s%2subl %1,%3,%0")
770
771 (define_insn ""
772 [(set (match_operand:DI 0 "register_operand" "=r")
773 (sign_extend:DI
774 (minus:SI (mult:SI (match_operand:SI 1 "reg_not_elim_operand" "r")
775 (match_operand:SI 2 "const48_operand" "I"))
776 (match_operand:SI 3 "reg_or_8bit_operand" "rI"))))]
777 ""
778 "s%2subl %1,%3,%0")
779
780 (define_insn ""
781 [(set (match_operand:DI 0 "register_operand" "=r")
782 (minus:DI (mult:DI (match_operand:DI 1 "reg_not_elim_operand" "r")
783 (match_operand:DI 2 "const48_operand" "I"))
784 (match_operand:DI 3 "reg_or_8bit_operand" "rI")))]
785 ""
786 "s%2subq %1,%3,%0")
787
788 (define_insn "mulsi3"
789 [(set (match_operand:SI 0 "register_operand" "=r")
790 (mult:SI (match_operand:SI 1 "reg_or_0_operand" "%rJ")
791 (match_operand:SI 2 "reg_or_8bit_operand" "rI")))]
792 ""
793 "mull %r1,%2,%0"
794 [(set_attr "type" "imul")
795 (set_attr "opsize" "si")])
796
797 (define_insn ""
798 [(set (match_operand:DI 0 "register_operand" "=r")
799 (sign_extend:DI
800 (mult:SI (match_operand:SI 1 "reg_or_0_operand" "%rJ")
801 (match_operand:SI 2 "reg_or_8bit_operand" "rI"))))]
802 ""
803 "mull %r1,%2,%0"
804 [(set_attr "type" "imul")
805 (set_attr "opsize" "si")])
806
807 (define_insn "muldi3"
808 [(set (match_operand:DI 0 "register_operand" "=r")
809 (mult:DI (match_operand:DI 1 "reg_or_0_operand" "%rJ")
810 (match_operand:DI 2 "reg_or_8bit_operand" "rI")))]
811 ""
812 "mulq %r1,%2,%0"
813 [(set_attr "type" "imul")])
814
815 (define_insn "umuldi3_highpart"
816 [(set (match_operand:DI 0 "register_operand" "=r")
817 (truncate:DI
818 (lshiftrt:TI
819 (mult:TI (zero_extend:TI
820 (match_operand:DI 1 "reg_or_0_operand" "%rJ"))
821 (zero_extend:TI
822 (match_operand:DI 2 "reg_or_8bit_operand" "rI")))
823 (const_int 64))))]
824 ""
825 "umulh %r1,%2,%0"
826 [(set_attr "type" "imul")
827 (set_attr "opsize" "udi")])
828
829 (define_insn ""
830 [(set (match_operand:DI 0 "register_operand" "=r")
831 (truncate:DI
832 (lshiftrt:TI
833 (mult:TI (zero_extend:TI (match_operand:DI 1 "register_operand" "r"))
834 (match_operand:TI 2 "cint8_operand" "I"))
835 (const_int 64))))]
836 ""
837 "umulh %1,%2,%0"
838 [(set_attr "type" "imul")
839 (set_attr "opsize" "udi")])
840 \f
841 ;; The divide and remainder operations always take their inputs from
842 ;; r24 and r25, put their output in r27, and clobber r23 and r28.
843
844 ;; ??? Force sign-extension here because some versions of OSF/1 don't
845 ;; do the right thing if the inputs are not properly sign-extended.
846 ;; But Linux, for instance, does not have this problem. Is it worth
847 ;; the complication here to eliminate the sign extension?
848 ;; Interix/NT has the same sign-extension problem.
849
850 (define_expand "divsi3"
851 [(set (reg:DI 24)
852 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "")))
853 (set (reg:DI 25)
854 (sign_extend:DI (match_operand:SI 2 "nonimmediate_operand" "")))
855 (parallel [(set (reg:DI 27)
856 (sign_extend:DI (div:SI (reg:DI 24) (reg:DI 25))))
857 (clobber (reg:DI 23))
858 (clobber (reg:DI 28))])
859 (set (match_operand:SI 0 "nonimmediate_operand" "")
860 (subreg:SI (reg:DI 27) 0))]
861 "!TARGET_OPEN_VMS"
862 "")
863
864 (define_expand "udivsi3"
865 [(set (reg:DI 24)
866 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "")))
867 (set (reg:DI 25)
868 (sign_extend:DI (match_operand:SI 2 "nonimmediate_operand" "")))
869 (parallel [(set (reg:DI 27)
870 (sign_extend:DI (udiv:SI (reg:DI 24) (reg:DI 25))))
871 (clobber (reg:DI 23))
872 (clobber (reg:DI 28))])
873 (set (match_operand:SI 0 "nonimmediate_operand" "")
874 (subreg:SI (reg:DI 27) 0))]
875 "!TARGET_OPEN_VMS"
876 "")
877
878 (define_expand "modsi3"
879 [(set (reg:DI 24)
880 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "")))
881 (set (reg:DI 25)
882 (sign_extend:DI (match_operand:SI 2 "nonimmediate_operand" "")))
883 (parallel [(set (reg:DI 27)
884 (sign_extend:DI (mod:SI (reg:DI 24) (reg:DI 25))))
885 (clobber (reg:DI 23))
886 (clobber (reg:DI 28))])
887 (set (match_operand:SI 0 "nonimmediate_operand" "")
888 (subreg:SI (reg:DI 27) 0))]
889 "!TARGET_OPEN_VMS"
890 "")
891
892 (define_expand "umodsi3"
893 [(set (reg:DI 24)
894 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "")))
895 (set (reg:DI 25)
896 (sign_extend:DI (match_operand:SI 2 "nonimmediate_operand" "")))
897 (parallel [(set (reg:DI 27)
898 (sign_extend:DI (umod:SI (reg:DI 24) (reg:DI 25))))
899 (clobber (reg:DI 23))
900 (clobber (reg:DI 28))])
901 (set (match_operand:SI 0 "nonimmediate_operand" "")
902 (subreg:SI (reg:DI 27) 0))]
903 "!TARGET_OPEN_VMS"
904 "")
905
906 (define_expand "divdi3"
907 [(set (reg:DI 24) (match_operand:DI 1 "input_operand" ""))
908 (set (reg:DI 25) (match_operand:DI 2 "input_operand" ""))
909 (parallel [(set (reg:DI 27)
910 (div:DI (reg:DI 24)
911 (reg:DI 25)))
912 (clobber (reg:DI 23))
913 (clobber (reg:DI 28))])
914 (set (match_operand:DI 0 "nonimmediate_operand" "")
915 (reg:DI 27))]
916 "!TARGET_OPEN_VMS"
917 "")
918
919 (define_expand "udivdi3"
920 [(set (reg:DI 24) (match_operand:DI 1 "input_operand" ""))
921 (set (reg:DI 25) (match_operand:DI 2 "input_operand" ""))
922 (parallel [(set (reg:DI 27)
923 (udiv:DI (reg:DI 24)
924 (reg:DI 25)))
925 (clobber (reg:DI 23))
926 (clobber (reg:DI 28))])
927 (set (match_operand:DI 0 "nonimmediate_operand" "")
928 (reg:DI 27))]
929 "!TARGET_OPEN_VMS"
930 "")
931
932 (define_expand "moddi3"
933 [(set (reg:DI 24) (match_operand:DI 1 "input_operand" ""))
934 (set (reg:DI 25) (match_operand:DI 2 "input_operand" ""))
935 (parallel [(set (reg:DI 27)
936 (mod:DI (reg:DI 24)
937 (reg:DI 25)))
938 (clobber (reg:DI 23))
939 (clobber (reg:DI 28))])
940 (set (match_operand:DI 0 "nonimmediate_operand" "")
941 (reg:DI 27))]
942 "!TARGET_OPEN_VMS"
943 "")
944
945 (define_expand "umoddi3"
946 [(set (reg:DI 24) (match_operand:DI 1 "input_operand" ""))
947 (set (reg:DI 25) (match_operand:DI 2 "input_operand" ""))
948 (parallel [(set (reg:DI 27)
949 (umod:DI (reg:DI 24)
950 (reg:DI 25)))
951 (clobber (reg:DI 23))
952 (clobber (reg:DI 28))])
953 (set (match_operand:DI 0 "nonimmediate_operand" "")
954 (reg:DI 27))]
955 "!TARGET_OPEN_VMS"
956 "")
957
958 ;; Lengths of 8 for ldq $t12,__divq($gp); jsr $t9,($t12),__divq as
959 ;; expanded by the assembler.
960 (define_insn ""
961 [(set (reg:DI 27)
962 (sign_extend:DI (match_operator:SI 1 "divmod_operator"
963 [(reg:DI 24) (reg:DI 25)])))
964 (clobber (reg:DI 23))
965 (clobber (reg:DI 28))]
966 "!TARGET_OPEN_VMS"
967 "%E1 $24,$25,$27"
968 [(set_attr "type" "jsr")
969 (set_attr "length" "8")])
970
971 (define_insn ""
972 [(set (reg:DI 27)
973 (match_operator:DI 1 "divmod_operator"
974 [(reg:DI 24) (reg:DI 25)]))
975 (clobber (reg:DI 23))
976 (clobber (reg:DI 28))]
977 "!TARGET_OPEN_VMS"
978 "%E1 $24,$25,$27"
979 [(set_attr "type" "jsr")
980 (set_attr "length" "8")])
981 \f
982 ;; Next are the basic logical operations. These only exist in DImode.
983
984 (define_insn "anddi3"
985 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
986 (and:DI (match_operand:DI 1 "reg_or_0_operand" "%rJ,rJ,rJ")
987 (match_operand:DI 2 "and_operand" "rI,N,MH")))]
988 ""
989 "@
990 and %r1,%2,%0
991 bic %r1,%N2,%0
992 zapnot %r1,%m2,%0"
993 [(set_attr "type" "ilog,ilog,shift")])
994
995 ;; There are times when we can split an AND into two AND insns. This occurs
996 ;; when we can first clear any bytes and then clear anything else. For
997 ;; example "I & 0xffff07" is "(I & 0xffffff) & 0xffffffffffffff07".
998 ;; Only do this when running on 64-bit host since the computations are
999 ;; too messy otherwise.
1000
1001 (define_split
1002 [(set (match_operand:DI 0 "register_operand" "")
1003 (and:DI (match_operand:DI 1 "register_operand" "")
1004 (match_operand:DI 2 "const_int_operand" "")))]
1005 "HOST_BITS_PER_WIDE_INT == 64 && ! and_operand (operands[2], DImode)"
1006 [(set (match_dup 0) (and:DI (match_dup 1) (match_dup 3)))
1007 (set (match_dup 0) (and:DI (match_dup 0) (match_dup 4)))]
1008 "
1009 {
1010 unsigned HOST_WIDE_INT mask1 = INTVAL (operands[2]);
1011 unsigned HOST_WIDE_INT mask2 = mask1;
1012 int i;
1013
1014 /* For each byte that isn't all zeros, make it all ones. */
1015 for (i = 0; i < 64; i += 8)
1016 if ((mask1 & ((HOST_WIDE_INT) 0xff << i)) != 0)
1017 mask1 |= (HOST_WIDE_INT) 0xff << i;
1018
1019 /* Now turn on any bits we've just turned off. */
1020 mask2 |= ~ mask1;
1021
1022 operands[3] = GEN_INT (mask1);
1023 operands[4] = GEN_INT (mask2);
1024 }")
1025
1026 (define_insn "zero_extendqihi2"
1027 [(set (match_operand:HI 0 "register_operand" "=r")
1028 (zero_extend:HI (match_operand:QI 1 "register_operand" "r")))]
1029 ""
1030 "and %1,0xff,%0"
1031 [(set_attr "type" "ilog")])
1032
1033 (define_insn ""
1034 [(set (match_operand:SI 0 "register_operand" "=r,r")
1035 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "r,m")))]
1036 "TARGET_BWX"
1037 "@
1038 and %1,0xff,%0
1039 ldbu %0,%1"
1040 [(set_attr "type" "ilog,ild")])
1041
1042 (define_insn ""
1043 [(set (match_operand:SI 0 "register_operand" "=r")
1044 (zero_extend:SI (match_operand:QI 1 "register_operand" "r")))]
1045 "! TARGET_BWX"
1046 "and %1,0xff,%0"
1047 [(set_attr "type" "ilog")])
1048
1049 (define_expand "zero_extendqisi2"
1050 [(set (match_operand:SI 0 "register_operand" "")
1051 (zero_extend:SI (match_operand:QI 1 "register_operand" "")))]
1052 ""
1053 "")
1054
1055 (define_insn ""
1056 [(set (match_operand:DI 0 "register_operand" "=r,r")
1057 (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand" "r,m")))]
1058 "TARGET_BWX"
1059 "@
1060 and %1,0xff,%0
1061 ldbu %0,%1"
1062 [(set_attr "type" "ilog,ild")])
1063
1064 (define_insn ""
1065 [(set (match_operand:DI 0 "register_operand" "=r")
1066 (zero_extend:DI (match_operand:QI 1 "register_operand" "r")))]
1067 "! TARGET_BWX"
1068 "and %1,0xff,%0"
1069 [(set_attr "type" "ilog")])
1070
1071 (define_expand "zero_extendqidi2"
1072 [(set (match_operand:DI 0 "register_operand" "")
1073 (zero_extend:DI (match_operand:QI 1 "register_operand" "")))]
1074 ""
1075 "")
1076
1077 (define_insn ""
1078 [(set (match_operand:SI 0 "register_operand" "=r,r")
1079 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "r,m")))]
1080 "TARGET_BWX"
1081 "@
1082 zapnot %1,3,%0
1083 ldwu %0,%1"
1084 [(set_attr "type" "shift,ild")])
1085
1086 (define_insn ""
1087 [(set (match_operand:SI 0 "register_operand" "=r")
1088 (zero_extend:SI (match_operand:HI 1 "register_operand" "r")))]
1089 "! TARGET_BWX"
1090 "zapnot %1,3,%0"
1091 [(set_attr "type" "shift")])
1092
1093 (define_expand "zero_extendhisi2"
1094 [(set (match_operand:SI 0 "register_operand" "")
1095 (zero_extend:SI (match_operand:HI 1 "register_operand" "")))]
1096 ""
1097 "")
1098
1099 (define_insn ""
1100 [(set (match_operand:DI 0 "register_operand" "=r,r")
1101 (zero_extend:DI (match_operand:HI 1 "nonimmediate_operand" "r,m")))]
1102 "TARGET_BWX"
1103 "@
1104 zapnot %1,3,%0
1105 ldwu %0,%1"
1106 [(set_attr "type" "shift,ild")])
1107
1108 (define_insn ""
1109 [(set (match_operand:DI 0 "register_operand" "=r")
1110 (zero_extend:DI (match_operand:HI 1 "register_operand" "r")))]
1111 ""
1112 "zapnot %1,3,%0"
1113 [(set_attr "type" "shift")])
1114
1115 (define_expand "zero_extendhidi2"
1116 [(set (match_operand:DI 0 "register_operand" "")
1117 (zero_extend:DI (match_operand:HI 1 "register_operand" "")))]
1118 ""
1119 "")
1120
1121 (define_insn "zero_extendsidi2"
1122 [(set (match_operand:DI 0 "register_operand" "=r")
1123 (zero_extend:DI (match_operand:SI 1 "register_operand" "r")))]
1124 ""
1125 "zapnot %1,15,%0"
1126 [(set_attr "type" "shift")])
1127
1128 (define_insn ""
1129 [(set (match_operand:DI 0 "register_operand" "=r")
1130 (and:DI (not:DI (match_operand:DI 1 "reg_or_8bit_operand" "rI"))
1131 (match_operand:DI 2 "reg_or_0_operand" "rJ")))]
1132 ""
1133 "bic %r2,%1,%0"
1134 [(set_attr "type" "ilog")])
1135
1136 (define_insn "iordi3"
1137 [(set (match_operand:DI 0 "register_operand" "=r,r")
1138 (ior:DI (match_operand:DI 1 "reg_or_0_operand" "%rJ,rJ")
1139 (match_operand:DI 2 "or_operand" "rI,N")))]
1140 ""
1141 "@
1142 bis %r1,%2,%0
1143 ornot %r1,%N2,%0"
1144 [(set_attr "type" "ilog")])
1145
1146 (define_insn "one_cmpldi2"
1147 [(set (match_operand:DI 0 "register_operand" "=r")
1148 (not:DI (match_operand:DI 1 "reg_or_8bit_operand" "rI")))]
1149 ""
1150 "ornot $31,%1,%0"
1151 [(set_attr "type" "ilog")])
1152
1153 (define_insn ""
1154 [(set (match_operand:DI 0 "register_operand" "=r")
1155 (ior:DI (not:DI (match_operand:DI 1 "reg_or_8bit_operand" "rI"))
1156 (match_operand:DI 2 "reg_or_0_operand" "rJ")))]
1157 ""
1158 "ornot %r2,%1,%0"
1159 [(set_attr "type" "ilog")])
1160
1161 (define_insn "xordi3"
1162 [(set (match_operand:DI 0 "register_operand" "=r,r")
1163 (xor:DI (match_operand:DI 1 "reg_or_0_operand" "%rJ,rJ")
1164 (match_operand:DI 2 "or_operand" "rI,N")))]
1165 ""
1166 "@
1167 xor %r1,%2,%0
1168 eqv %r1,%N2,%0"
1169 [(set_attr "type" "ilog")])
1170
1171 (define_insn ""
1172 [(set (match_operand:DI 0 "register_operand" "=r")
1173 (not:DI (xor:DI (match_operand:DI 1 "register_operand" "%rJ")
1174 (match_operand:DI 2 "register_operand" "rI"))))]
1175 ""
1176 "eqv %r1,%2,%0"
1177 [(set_attr "type" "ilog")])
1178 \f
1179 ;; Handle the FFS insn iff we support CIX.
1180
1181 (define_expand "ffsdi2"
1182 [(set (match_dup 2)
1183 (unspec:DI [(match_operand:DI 1 "register_operand" "")] 1))
1184 (set (match_dup 3)
1185 (plus:DI (match_dup 2) (const_int 1)))
1186 (set (match_operand:DI 0 "register_operand" "")
1187 (if_then_else:DI (eq (match_dup 1) (const_int 0))
1188 (const_int 0) (match_dup 3)))]
1189 "TARGET_CIX"
1190 "
1191 {
1192 operands[2] = gen_reg_rtx (DImode);
1193 operands[3] = gen_reg_rtx (DImode);
1194 }")
1195
1196 (define_insn ""
1197 [(set (match_operand:DI 0 "register_operand" "=r")
1198 (unspec:DI [(match_operand:DI 1 "register_operand" "r")] 1))]
1199 "TARGET_CIX"
1200 "cttz %1,%0"
1201 ; EV6 calls all mvi and cttz/ctlz/popc class imisc, so just
1202 ; reuse the existing type name.
1203 [(set_attr "type" "mvi")])
1204 \f
1205 ;; Next come the shifts and the various extract and insert operations.
1206
1207 (define_insn "ashldi3"
1208 [(set (match_operand:DI 0 "register_operand" "=r,r")
1209 (ashift:DI (match_operand:DI 1 "reg_or_0_operand" "rJ,rJ")
1210 (match_operand:DI 2 "reg_or_6bit_operand" "P,rS")))]
1211 ""
1212 "*
1213 {
1214 switch (which_alternative)
1215 {
1216 case 0:
1217 if (operands[2] == const1_rtx)
1218 return \"addq %r1,%r1,%0\";
1219 else
1220 return \"s%P2addq %r1,0,%0\";
1221 case 1:
1222 return \"sll %r1,%2,%0\";
1223 default:
1224 abort();
1225 }
1226 }"
1227 [(set_attr "type" "iadd,shift")])
1228
1229 ;; ??? The following pattern is made by combine, but earlier phases
1230 ;; (specifically flow) can't handle it. This occurs in jump.c. Deal
1231 ;; with this in a better way at some point.
1232 ;;(define_insn ""
1233 ;; [(set (match_operand:DI 0 "register_operand" "=r")
1234 ;; (sign_extend:DI
1235 ;; (subreg:SI (ashift:DI (match_operand:DI 1 "reg_or_0_operand" "rJ")
1236 ;; (match_operand:DI 2 "const_int_operand" "P"))
1237 ;; 0)))]
1238 ;; "INTVAL (operands[2]) >= 1 && INTVAL (operands[2]) <= 3"
1239 ;; "*
1240 ;;{
1241 ;; if (operands[2] == const1_rtx)
1242 ;; return \"addl %r1,%r1,%0\";
1243 ;; else
1244 ;; return \"s%P2addl %r1,0,%0\";
1245 ;; }"
1246 ;; [(set_attr "type" "iadd")])
1247
1248 (define_insn "lshrdi3"
1249 [(set (match_operand:DI 0 "register_operand" "=r")
1250 (lshiftrt:DI (match_operand:DI 1 "reg_or_0_operand" "rJ")
1251 (match_operand:DI 2 "reg_or_6bit_operand" "rS")))]
1252 ""
1253 "srl %r1,%2,%0"
1254 [(set_attr "type" "shift")])
1255
1256 (define_insn "ashrdi3"
1257 [(set (match_operand:DI 0 "register_operand" "=r")
1258 (ashiftrt:DI (match_operand:DI 1 "reg_or_0_operand" "rJ")
1259 (match_operand:DI 2 "reg_or_6bit_operand" "rS")))]
1260 ""
1261 "sra %r1,%2,%0"
1262 [(set_attr "type" "shift")])
1263
1264 (define_expand "extendqihi2"
1265 [(set (match_dup 2)
1266 (ashift:DI (match_operand:QI 1 "some_operand" "")
1267 (const_int 56)))
1268 (set (match_operand:HI 0 "register_operand" "")
1269 (ashiftrt:DI (match_dup 2)
1270 (const_int 56)))]
1271 ""
1272 "
1273 {
1274 if (TARGET_BWX)
1275 {
1276 emit_insn (gen_extendqihi2x (operands[0],
1277 force_reg (QImode, operands[1])));
1278 DONE;
1279 }
1280
1281 /* If we have an unaligned MEM, extend to DImode (which we do
1282 specially) and then copy to the result. */
1283 if (unaligned_memory_operand (operands[1], HImode))
1284 {
1285 rtx temp = gen_reg_rtx (DImode);
1286
1287 emit_insn (gen_extendqidi2 (temp, operands[1]));
1288 emit_move_insn (operands[0], gen_lowpart (HImode, temp));
1289 DONE;
1290 }
1291
1292 operands[0] = gen_lowpart (DImode, operands[0]);
1293 operands[1] = gen_lowpart (DImode, force_reg (QImode, operands[1]));
1294 operands[2] = gen_reg_rtx (DImode);
1295 }")
1296
1297 (define_insn "extendqidi2x"
1298 [(set (match_operand:DI 0 "register_operand" "=r")
1299 (sign_extend:DI (match_operand:QI 1 "register_operand" "r")))]
1300 "TARGET_BWX"
1301 "sextb %1,%0"
1302 [(set_attr "type" "shift")])
1303
1304 (define_insn "extendhidi2x"
1305 [(set (match_operand:DI 0 "register_operand" "=r")
1306 (sign_extend:DI (match_operand:HI 1 "register_operand" "r")))]
1307 "TARGET_BWX"
1308 "sextw %1,%0"
1309 [(set_attr "type" "shift")])
1310
1311 (define_insn "extendqisi2x"
1312 [(set (match_operand:SI 0 "register_operand" "=r")
1313 (sign_extend:SI (match_operand:QI 1 "register_operand" "r")))]
1314 "TARGET_BWX"
1315 "sextb %1,%0"
1316 [(set_attr "type" "shift")])
1317
1318 (define_insn "extendhisi2x"
1319 [(set (match_operand:SI 0 "register_operand" "=r")
1320 (sign_extend:SI (match_operand:HI 1 "register_operand" "r")))]
1321 "TARGET_BWX"
1322 "sextw %1,%0"
1323 [(set_attr "type" "shift")])
1324
1325 (define_insn "extendqihi2x"
1326 [(set (match_operand:HI 0 "register_operand" "=r")
1327 (sign_extend:HI (match_operand:QI 1 "register_operand" "r")))]
1328 "TARGET_BWX"
1329 "sextb %1,%0"
1330 [(set_attr "type" "shift")])
1331
1332 (define_expand "extendqisi2"
1333 [(set (match_dup 2)
1334 (ashift:DI (match_operand:QI 1 "some_operand" "")
1335 (const_int 56)))
1336 (set (match_operand:SI 0 "register_operand" "")
1337 (ashiftrt:DI (match_dup 2)
1338 (const_int 56)))]
1339 ""
1340 "
1341 {
1342 if (TARGET_BWX)
1343 {
1344 emit_insn (gen_extendqisi2x (operands[0],
1345 force_reg (QImode, operands[1])));
1346 DONE;
1347 }
1348
1349 /* If we have an unaligned MEM, extend to a DImode form of
1350 the result (which we do specially). */
1351 if (unaligned_memory_operand (operands[1], QImode))
1352 {
1353 rtx temp = gen_reg_rtx (DImode);
1354
1355 emit_insn (gen_extendqidi2 (temp, operands[1]));
1356 emit_move_insn (operands[0], gen_lowpart (SImode, temp));
1357 DONE;
1358 }
1359
1360 operands[0] = gen_lowpart (DImode, operands[0]);
1361 operands[1] = gen_lowpart (DImode, force_reg (QImode, operands[1]));
1362 operands[2] = gen_reg_rtx (DImode);
1363 }")
1364
1365 (define_expand "extendqidi2"
1366 [(set (match_dup 2)
1367 (ashift:DI (match_operand:QI 1 "some_operand" "")
1368 (const_int 56)))
1369 (set (match_operand:DI 0 "register_operand" "")
1370 (ashiftrt:DI (match_dup 2)
1371 (const_int 56)))]
1372 ""
1373 "
1374 {
1375 if (TARGET_BWX)
1376 {
1377 emit_insn (gen_extendqidi2x (operands[0],
1378 force_reg (QImode, operands[1])));
1379 DONE;
1380 }
1381
1382 if (unaligned_memory_operand (operands[1], QImode))
1383 {
1384 rtx seq
1385 = gen_unaligned_extendqidi (operands[0],
1386 get_unaligned_address (operands[1], 1));
1387
1388 alpha_set_memflags (seq, operands[1]);
1389 emit_insn (seq);
1390 DONE;
1391 }
1392
1393 operands[1] = gen_lowpart (DImode, force_reg (QImode, operands[1]));
1394 operands[2] = gen_reg_rtx (DImode);
1395 }")
1396
1397 (define_expand "extendhisi2"
1398 [(set (match_dup 2)
1399 (ashift:DI (match_operand:HI 1 "some_operand" "")
1400 (const_int 48)))
1401 (set (match_operand:SI 0 "register_operand" "")
1402 (ashiftrt:DI (match_dup 2)
1403 (const_int 48)))]
1404 ""
1405 "
1406 {
1407 if (TARGET_BWX)
1408 {
1409 emit_insn (gen_extendhisi2x (operands[0],
1410 force_reg (HImode, operands[1])));
1411 DONE;
1412 }
1413
1414 /* If we have an unaligned MEM, extend to a DImode form of
1415 the result (which we do specially). */
1416 if (unaligned_memory_operand (operands[1], HImode))
1417 {
1418 rtx temp = gen_reg_rtx (DImode);
1419
1420 emit_insn (gen_extendhidi2 (temp, operands[1]));
1421 emit_move_insn (operands[0], gen_lowpart (SImode, temp));
1422 DONE;
1423 }
1424
1425 operands[0] = gen_lowpart (DImode, operands[0]);
1426 operands[1] = gen_lowpart (DImode, force_reg (HImode, operands[1]));
1427 operands[2] = gen_reg_rtx (DImode);
1428 }")
1429
1430 (define_expand "extendhidi2"
1431 [(set (match_dup 2)
1432 (ashift:DI (match_operand:HI 1 "some_operand" "")
1433 (const_int 48)))
1434 (set (match_operand:DI 0 "register_operand" "")
1435 (ashiftrt:DI (match_dup 2)
1436 (const_int 48)))]
1437 ""
1438 "
1439 {
1440 if (TARGET_BWX)
1441 {
1442 emit_insn (gen_extendhidi2x (operands[0],
1443 force_reg (HImode, operands[1])));
1444 DONE;
1445 }
1446
1447 if (unaligned_memory_operand (operands[1], HImode))
1448 {
1449 rtx seq
1450 = gen_unaligned_extendhidi (operands[0],
1451 get_unaligned_address (operands[1], 2));
1452
1453 alpha_set_memflags (seq, operands[1]);
1454 emit_insn (seq);
1455 DONE;
1456 }
1457
1458 operands[1] = gen_lowpart (DImode, force_reg (HImode, operands[1]));
1459 operands[2] = gen_reg_rtx (DImode);
1460 }")
1461
1462 ;; Here's how we sign extend an unaligned byte and halfword. Doing this
1463 ;; as a pattern saves one instruction. The code is similar to that for
1464 ;; the unaligned loads (see below).
1465 ;;
1466 ;; Operand 1 is the address + 1 (+2 for HI), operand 0 is the result.
1467 (define_expand "unaligned_extendqidi"
1468 [(set (match_dup 2) (match_operand:DI 1 "address_operand" ""))
1469 (set (match_dup 3)
1470 (mem:DI (and:DI (plus:DI (match_dup 2) (const_int -1))
1471 (const_int -8))))
1472 (set (match_dup 4)
1473 (ashift:DI (match_dup 3)
1474 (minus:DI (const_int 64)
1475 (ashift:DI
1476 (and:DI (match_dup 2) (const_int 7))
1477 (const_int 3)))))
1478 (set (subreg:DI (match_operand:QI 0 "register_operand" "") 0)
1479 (ashiftrt:DI (match_dup 4) (const_int 56)))]
1480 ""
1481 "
1482 { operands[2] = gen_reg_rtx (DImode);
1483 operands[3] = gen_reg_rtx (DImode);
1484 operands[4] = gen_reg_rtx (DImode);
1485 }")
1486
1487 (define_expand "unaligned_extendhidi"
1488 [(set (match_dup 2) (match_operand:DI 1 "address_operand" ""))
1489 (set (match_dup 3)
1490 (mem:DI (and:DI (plus:DI (match_dup 2) (const_int -2))
1491 (const_int -8))))
1492 (set (match_dup 4)
1493 (ashift:DI (match_dup 3)
1494 (minus:DI (const_int 64)
1495 (ashift:DI
1496 (and:DI (match_dup 2) (const_int 7))
1497 (const_int 3)))))
1498 (set (subreg:DI (match_operand:QI 0 "register_operand" "") 0)
1499 (ashiftrt:DI (match_dup 4) (const_int 48)))]
1500 ""
1501 "
1502 { operands[2] = gen_reg_rtx (DImode);
1503 operands[3] = gen_reg_rtx (DImode);
1504 operands[4] = gen_reg_rtx (DImode);
1505 }")
1506
1507 (define_insn ""
1508 [(set (match_operand:DI 0 "register_operand" "=r")
1509 (zero_extract:DI (match_operand:DI 1 "reg_or_0_operand" "rJ")
1510 (match_operand:DI 2 "mode_width_operand" "n")
1511 (match_operand:DI 3 "mul8_operand" "I")))]
1512 ""
1513 "ext%M2l %r1,%s3,%0"
1514 [(set_attr "type" "shift")])
1515
1516 (define_insn "extxl"
1517 [(set (match_operand:DI 0 "register_operand" "=r")
1518 (zero_extract:DI (match_operand:DI 1 "reg_or_0_operand" "rJ")
1519 (match_operand:DI 2 "mode_width_operand" "n")
1520 (ashift:DI (match_operand:DI 3 "reg_or_8bit_operand" "rI")
1521 (const_int 3))))]
1522 ""
1523 "ext%M2l %r1,%3,%0"
1524 [(set_attr "type" "shift")])
1525
1526 ;; Combine has some strange notion of preserving existing undefined behaviour
1527 ;; in shifts larger than a word size. So capture these patterns that it
1528 ;; should have turned into zero_extracts.
1529
1530 (define_insn ""
1531 [(set (match_operand:DI 0 "register_operand" "=r")
1532 (and:DI (lshiftrt:DI (match_operand:DI 1 "reg_or_0_operand" "rJ")
1533 (ashift:DI (match_operand:DI 2 "reg_or_8bit_operand" "rI")
1534 (const_int 3)))
1535 (match_operand:DI 3 "mode_mask_operand" "n")))]
1536 ""
1537 "ext%U3l %1,%2,%0"
1538 [(set_attr "type" "shift")])
1539
1540 (define_insn ""
1541 [(set (match_operand:DI 0 "register_operand" "=r")
1542 (lshiftrt:DI (match_operand:DI 1 "reg_or_0_operand" "rJ")
1543 (ashift:DI (match_operand:DI 2 "reg_or_8bit_operand" "rI")
1544 (const_int 3))))]
1545 ""
1546 "extql %1,%2,%0"
1547 [(set_attr "type" "shift")])
1548
1549 (define_insn "extqh"
1550 [(set (match_operand:DI 0 "register_operand" "=r")
1551 (ashift:DI
1552 (match_operand:DI 1 "reg_or_0_operand" "rJ")
1553 (minus:DI (const_int 64)
1554 (ashift:DI
1555 (and:DI
1556 (match_operand:DI 2 "reg_or_8bit_operand" "rI")
1557 (const_int 7))
1558 (const_int 3)))))]
1559 ""
1560 "extqh %r1,%2,%0"
1561 [(set_attr "type" "shift")])
1562
1563 (define_insn "extlh"
1564 [(set (match_operand:DI 0 "register_operand" "=r")
1565 (ashift:DI
1566 (and:DI (match_operand:DI 1 "reg_or_0_operand" "rJ")
1567 (const_int 2147483647))
1568 (minus:DI (const_int 64)
1569 (ashift:DI
1570 (and:DI
1571 (match_operand:DI 2 "reg_or_8bit_operand" "rI")
1572 (const_int 7))
1573 (const_int 3)))))]
1574 ""
1575 "extlh %r1,%2,%0"
1576 [(set_attr "type" "shift")])
1577
1578 (define_insn "extwh"
1579 [(set (match_operand:DI 0 "register_operand" "=r")
1580 (ashift:DI
1581 (and:DI (match_operand:DI 1 "reg_or_0_operand" "rJ")
1582 (const_int 65535))
1583 (minus:DI (const_int 64)
1584 (ashift:DI
1585 (and:DI
1586 (match_operand:DI 2 "reg_or_8bit_operand" "rI")
1587 (const_int 7))
1588 (const_int 3)))))]
1589 ""
1590 "extwh %r1,%2,%0"
1591 [(set_attr "type" "shift")])
1592
1593 ;; This converts an extXl into an extXh with an appropriate adjustment
1594 ;; to the address calculation.
1595
1596 ;;(define_split
1597 ;; [(set (match_operand:DI 0 "register_operand" "")
1598 ;; (ashift:DI (zero_extract:DI (match_operand:DI 1 "register_operand" "")
1599 ;; (match_operand:DI 2 "mode_width_operand" "")
1600 ;; (ashift:DI (match_operand:DI 3 "" "")
1601 ;; (const_int 3)))
1602 ;; (match_operand:DI 4 "const_int_operand" "")))
1603 ;; (clobber (match_operand:DI 5 "register_operand" ""))]
1604 ;; "INTVAL (operands[4]) == 64 - INTVAL (operands[2])"
1605 ;; [(set (match_dup 5) (match_dup 6))
1606 ;; (set (match_dup 0)
1607 ;; (ashift:DI (zero_extract:DI (match_dup 1) (match_dup 2)
1608 ;; (ashift:DI (plus:DI (match_dup 5)
1609 ;; (match_dup 7))
1610 ;; (const_int 3)))
1611 ;; (match_dup 4)))]
1612 ;; "
1613 ;;{
1614 ;; operands[6] = plus_constant (operands[3],
1615 ;; INTVAL (operands[2]) / BITS_PER_UNIT);
1616 ;; operands[7] = GEN_INT (- INTVAL (operands[2]) / BITS_PER_UNIT);
1617 ;;}")
1618
1619 (define_insn ""
1620 [(set (match_operand:DI 0 "register_operand" "=r")
1621 (ashift:DI (zero_extend:DI (match_operand:QI 1 "register_operand" "r"))
1622 (match_operand:DI 2 "mul8_operand" "I")))]
1623 ""
1624 "insbl %1,%s2,%0"
1625 [(set_attr "type" "shift")])
1626
1627 (define_insn ""
1628 [(set (match_operand:DI 0 "register_operand" "=r")
1629 (ashift:DI (zero_extend:DI (match_operand:HI 1 "register_operand" "r"))
1630 (match_operand:DI 2 "mul8_operand" "I")))]
1631 ""
1632 "inswl %1,%s2,%0"
1633 [(set_attr "type" "shift")])
1634
1635 (define_insn ""
1636 [(set (match_operand:DI 0 "register_operand" "=r")
1637 (ashift:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
1638 (match_operand:DI 2 "mul8_operand" "I")))]
1639 ""
1640 "insll %1,%s2,%0"
1641 [(set_attr "type" "shift")])
1642
1643 (define_insn "insbl"
1644 [(set (match_operand:DI 0 "register_operand" "=r")
1645 (ashift:DI (zero_extend:DI (match_operand:QI 1 "register_operand" "r"))
1646 (ashift:DI (match_operand:DI 2 "reg_or_8bit_operand" "rI")
1647 (const_int 3))))]
1648 ""
1649 "insbl %1,%2,%0"
1650 [(set_attr "type" "shift")])
1651
1652 (define_insn "inswl"
1653 [(set (match_operand:DI 0 "register_operand" "=r")
1654 (ashift:DI (zero_extend:DI (match_operand:HI 1 "register_operand" "r"))
1655 (ashift:DI (match_operand:DI 2 "reg_or_8bit_operand" "rI")
1656 (const_int 3))))]
1657 ""
1658 "inswl %1,%2,%0"
1659 [(set_attr "type" "shift")])
1660
1661 (define_insn "insll"
1662 [(set (match_operand:DI 0 "register_operand" "=r")
1663 (ashift:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
1664 (ashift:DI (match_operand:DI 2 "reg_or_8bit_operand" "rI")
1665 (const_int 3))))]
1666 ""
1667 "insll %1,%2,%0"
1668 [(set_attr "type" "shift")])
1669
1670 (define_insn "insql"
1671 [(set (match_operand:DI 0 "register_operand" "=r")
1672 (ashift:DI (match_operand:DI 1 "register_operand" "r")
1673 (ashift:DI (match_operand:DI 2 "reg_or_8bit_operand" "rI")
1674 (const_int 3))))]
1675 ""
1676 "insql %1,%2,%0"
1677 [(set_attr "type" "shift")])
1678
1679 ;; Combine has this sometimes habit of moving the and outside of the
1680 ;; shift, making life more interesting.
1681
1682 (define_insn ""
1683 [(set (match_operand:DI 0 "register_operand" "=r")
1684 (and:DI (ashift:DI (match_operand:DI 1 "register_operand" "r")
1685 (match_operand:DI 2 "mul8_operand" "I"))
1686 (match_operand:DI 3 "immediate_operand" "i")))]
1687 "HOST_BITS_PER_WIDE_INT == 64
1688 && GET_CODE (operands[3]) == CONST_INT
1689 && (((unsigned HOST_WIDE_INT) 0xff << INTVAL (operands[2])
1690 == (unsigned HOST_WIDE_INT) INTVAL (operands[3]))
1691 || ((unsigned HOST_WIDE_INT) 0xffff << INTVAL (operands[2])
1692 == (unsigned HOST_WIDE_INT) INTVAL (operands[3]))
1693 || ((unsigned HOST_WIDE_INT) 0xffffffff << INTVAL (operands[2])
1694 == (unsigned HOST_WIDE_INT) INTVAL (operands[3])))"
1695 "*
1696 {
1697 #if HOST_BITS_PER_WIDE_INT == 64
1698 if ((unsigned HOST_WIDE_INT) 0xff << INTVAL (operands[2])
1699 == (unsigned HOST_WIDE_INT) INTVAL (operands[3]))
1700 return \"insbl %1,%s2,%0\";
1701 if ((unsigned HOST_WIDE_INT) 0xffff << INTVAL (operands[2])
1702 == (unsigned HOST_WIDE_INT) INTVAL (operands[3]))
1703 return \"inswl %1,%s2,%0\";
1704 if ((unsigned HOST_WIDE_INT) 0xffffffff << INTVAL (operands[2])
1705 == (unsigned HOST_WIDE_INT) INTVAL (operands[3]))
1706 return \"insll %1,%s2,%0\";
1707 #endif
1708 abort();
1709 }"
1710 [(set_attr "type" "shift")])
1711
1712 ;; We do not include the insXh insns because they are complex to express
1713 ;; and it does not appear that we would ever want to generate them.
1714 ;;
1715 ;; Since we need them for block moves, though, cop out and use unspec.
1716
1717 (define_insn "insxh"
1718 [(set (match_operand:DI 0 "register_operand" "=r")
1719 (unspec:DI [(match_operand:DI 1 "register_operand" "r")
1720 (match_operand:DI 2 "mode_width_operand" "n")
1721 (match_operand:DI 3 "reg_or_8bit_operand" "rI")] 2))]
1722 ""
1723 "ins%M2h %1,%3,%0"
1724 [(set_attr "type" "shift")])
1725
1726 (define_insn "mskxl"
1727 [(set (match_operand:DI 0 "register_operand" "=r")
1728 (and:DI (not:DI (ashift:DI
1729 (match_operand:DI 2 "mode_mask_operand" "n")
1730 (ashift:DI
1731 (match_operand:DI 3 "reg_or_8bit_operand" "rI")
1732 (const_int 3))))
1733 (match_operand:DI 1 "reg_or_0_operand" "rJ")))]
1734 ""
1735 "msk%U2l %r1,%3,%0"
1736 [(set_attr "type" "shift")])
1737
1738 ;; We do not include the mskXh insns because it does not appear we would
1739 ;; ever generate one.
1740 ;;
1741 ;; Again, we do for block moves and we use unspec again.
1742
1743 (define_insn "mskxh"
1744 [(set (match_operand:DI 0 "register_operand" "=r")
1745 (unspec:DI [(match_operand:DI 1 "register_operand" "r")
1746 (match_operand:DI 2 "mode_width_operand" "n")
1747 (match_operand:DI 3 "reg_or_8bit_operand" "rI")] 3))]
1748 ""
1749 "msk%M2h %1,%3,%0"
1750 [(set_attr "type" "shift")])
1751
1752 ;; Prefer AND + NE over LSHIFTRT + AND.
1753
1754 (define_insn_and_split "*ze_and_ne"
1755 [(set (match_operand:DI 0 "register_operand" "=r")
1756 (zero_extract:DI (match_operand:DI 1 "reg_or_0_operand" "rJ")
1757 (const_int 1)
1758 (match_operand 2 "const_int_operand" "I")))]
1759 "(unsigned HOST_WIDE_INT) INTVAL (operands[2]) < 8"
1760 "#"
1761 ""
1762 [(set (match_dup 0)
1763 (and:DI (match_dup 1) (match_dup 3)))
1764 (set (match_dup 0)
1765 (ne:DI (match_dup 0) (const_int 0)))]
1766 "operands[3] = GEN_INT (1 << INTVAL (operands[2]));")
1767 \f
1768 ;; Floating-point operations. All the double-precision insns can extend
1769 ;; from single, so indicate that. The exception are the ones that simply
1770 ;; play with the sign bits; it's not clear what to do there.
1771
1772 (define_insn "abssf2"
1773 [(set (match_operand:SF 0 "register_operand" "=f")
1774 (abs:SF (match_operand:SF 1 "reg_or_fp0_operand" "fG")))]
1775 "TARGET_FP"
1776 "cpys $f31,%R1,%0"
1777 [(set_attr "type" "fcpys")])
1778
1779 (define_insn "*nabssf2"
1780 [(set (match_operand:SF 0 "register_operand" "=f")
1781 (neg:SF (abs:SF (match_operand:SF 1 "reg_or_fp0_operand" "fG"))))]
1782 "TARGET_FP"
1783 "cpysn $f31,%R1,%0"
1784 [(set_attr "type" "fadd")])
1785
1786 (define_insn "absdf2"
1787 [(set (match_operand:DF 0 "register_operand" "=f")
1788 (abs:DF (match_operand:DF 1 "reg_or_fp0_operand" "fG")))]
1789 "TARGET_FP"
1790 "cpys $f31,%R1,%0"
1791 [(set_attr "type" "fcpys")])
1792
1793 (define_insn "*nabsdf2"
1794 [(set (match_operand:DF 0 "register_operand" "=f")
1795 (neg:DF (abs:DF (match_operand:DF 1 "reg_or_fp0_operand" "fG"))))]
1796 "TARGET_FP"
1797 "cpysn $f31,%R1,%0"
1798 [(set_attr "type" "fadd")])
1799
1800 (define_expand "abstf2"
1801 [(parallel [(set (match_operand:TF 0 "register_operand" "")
1802 (neg:TF (match_operand:TF 1 "reg_or_fp0_operand" "")))
1803 (use (match_dup 2))])]
1804 "TARGET_HAS_XFLOATING_LIBS"
1805 "
1806 {
1807 #if HOST_BITS_PER_WIDE_INT >= 64
1808 operands[2] = force_reg (DImode, GEN_INT (0x8000000000000000));
1809 #else
1810 operands[2] = force_reg (DImode, immed_double_const (0, 0x80000000, DImode));
1811 #endif
1812 }")
1813
1814 (define_insn ""
1815 [(set (match_operand:TF 0 "register_operand" "=r")
1816 (abs:TF (match_operand:TF 1 "reg_or_fp0_operand" "rG")))
1817 (use (match_operand:DI 2 "register_operand" "=r"))]
1818 "TARGET_HAS_XFLOATING_LIBS"
1819 "#")
1820
1821 (define_split
1822 [(set (match_operand:TF 0 "register_operand" "")
1823 (abs:TF (match_operand:TF 1 "reg_or_fp0_operand" "")))
1824 (use (match_operand:DI 4 "register_operand" ""))]
1825 "reload_completed"
1826 [(const_int 0)]
1827 "
1828 {
1829 int move;
1830 rtx tmp;
1831
1832 alpha_split_tfmode_pair (operands);
1833
1834 move = 1;
1835 if (rtx_equal_p (operands[0], operands[2]))
1836 move = 0;
1837 else if (rtx_equal_p (operands[1], operands[2]))
1838 move = -1;
1839
1840 if (move < 0)
1841 emit_move_insn (operands[0], operands[2]);
1842
1843 tmp = gen_rtx_NOT (DImode, operands[4]);
1844 tmp = gen_rtx_AND (DImode, tmp, operands[3]);
1845 emit_insn (gen_rtx_SET (VOIDmode, operands[1], tmp));
1846
1847 if (move > 0)
1848 emit_move_insn (operands[0], operands[2]);
1849 DONE;
1850 }")
1851
1852 (define_insn "negsf2"
1853 [(set (match_operand:SF 0 "register_operand" "=f")
1854 (neg:SF (match_operand:SF 1 "reg_or_fp0_operand" "fG")))]
1855 "TARGET_FP"
1856 "cpysn %R1,%R1,%0"
1857 [(set_attr "type" "fadd")])
1858
1859 (define_insn "negdf2"
1860 [(set (match_operand:DF 0 "register_operand" "=f")
1861 (neg:DF (match_operand:DF 1 "reg_or_fp0_operand" "fG")))]
1862 "TARGET_FP"
1863 "cpysn %R1,%R1,%0"
1864 [(set_attr "type" "fadd")])
1865
1866 (define_expand "negtf2"
1867 [(parallel [(set (match_operand:TF 0 "register_operand" "")
1868 (neg:TF (match_operand:TF 1 "reg_or_fp0_operand" "")))
1869 (use (match_dup 2))])]
1870 "TARGET_HAS_XFLOATING_LIBS"
1871 "
1872 {
1873 #if HOST_BITS_PER_WIDE_INT >= 64
1874 operands[2] = force_reg (DImode, GEN_INT (0x8000000000000000));
1875 #else
1876 operands[2] = force_reg (DImode, immed_double_const (0, 0x80000000, DImode));
1877 #endif
1878 }")
1879
1880 (define_insn ""
1881 [(set (match_operand:TF 0 "register_operand" "=r")
1882 (neg:TF (match_operand:TF 1 "reg_or_fp0_operand" "rG")))
1883 (use (match_operand:DI 2 "register_operand" "=r"))]
1884 "TARGET_HAS_XFLOATING_LIBS"
1885 "#")
1886
1887 (define_split
1888 [(set (match_operand:TF 0 "register_operand" "")
1889 (neg:TF (match_operand:TF 1 "reg_or_fp0_operand" "")))
1890 (use (match_operand:DI 4 "register_operand" ""))]
1891 "reload_completed"
1892 [(const_int 0)]
1893 "
1894 {
1895 int move;
1896
1897 alpha_split_tfmode_pair (operands);
1898
1899 move = 1;
1900 if (rtx_equal_p (operands[0], operands[2]))
1901 move = 0;
1902 else if (rtx_equal_p (operands[1], operands[2]))
1903 move = -1;
1904
1905 if (move < 0)
1906 emit_move_insn (operands[0], operands[2]);
1907
1908 emit_insn (gen_xordi3 (operands[1], operands[3], operands[4]));
1909
1910 if (move > 0)
1911 emit_move_insn (operands[0], operands[2]);
1912 DONE;
1913 }")
1914
1915 (define_insn ""
1916 [(set (match_operand:SF 0 "register_operand" "=&f")
1917 (plus:SF (match_operand:SF 1 "reg_or_fp0_operand" "%fG")
1918 (match_operand:SF 2 "reg_or_fp0_operand" "fG")))]
1919 "TARGET_FP && alpha_fptm >= ALPHA_FPTM_SU"
1920 "add%,%)%& %R1,%R2,%0"
1921 [(set_attr "type" "fadd")
1922 (set_attr "trap" "yes")])
1923
1924 (define_insn "addsf3"
1925 [(set (match_operand:SF 0 "register_operand" "=f")
1926 (plus:SF (match_operand:SF 1 "reg_or_fp0_operand" "%fG")
1927 (match_operand:SF 2 "reg_or_fp0_operand" "fG")))]
1928 "TARGET_FP"
1929 "add%,%)%& %R1,%R2,%0"
1930 [(set_attr "type" "fadd")
1931 (set_attr "trap" "yes")])
1932
1933 (define_insn ""
1934 [(set (match_operand:DF 0 "register_operand" "=&f")
1935 (plus:DF (match_operand:DF 1 "reg_or_fp0_operand" "%fG")
1936 (match_operand:DF 2 "reg_or_fp0_operand" "fG")))]
1937 "TARGET_FP && alpha_fptm >= ALPHA_FPTM_SU"
1938 "add%-%)%& %R1,%R2,%0"
1939 [(set_attr "type" "fadd")
1940 (set_attr "trap" "yes")])
1941
1942 (define_insn "adddf3"
1943 [(set (match_operand:DF 0 "register_operand" "=f")
1944 (plus:DF (match_operand:DF 1 "reg_or_fp0_operand" "%fG")
1945 (match_operand:DF 2 "reg_or_fp0_operand" "fG")))]
1946 "TARGET_FP"
1947 "add%-%)%& %R1,%R2,%0"
1948 [(set_attr "type" "fadd")
1949 (set_attr "trap" "yes")])
1950
1951 (define_insn ""
1952 [(set (match_operand:DF 0 "register_operand" "=f")
1953 (plus:DF (float_extend:DF
1954 (match_operand:SF 1 "reg_or_fp0_operand" "fG"))
1955 (match_operand:DF 2 "reg_or_fp0_operand" "fG")))]
1956 "TARGET_FP && alpha_fptm < ALPHA_FPTM_SU"
1957 "add%-%)%& %R1,%R2,%0"
1958 [(set_attr "type" "fadd")
1959 (set_attr "trap" "yes")])
1960
1961 (define_insn ""
1962 [(set (match_operand:DF 0 "register_operand" "=f")
1963 (plus:DF (float_extend:DF
1964 (match_operand:SF 1 "reg_or_fp0_operand" "%fG"))
1965 (float_extend:DF
1966 (match_operand:SF 2 "reg_or_fp0_operand" "fG"))))]
1967 "TARGET_FP && alpha_fptm < ALPHA_FPTM_SU"
1968 "add%-%)%& %R1,%R2,%0"
1969 [(set_attr "type" "fadd")
1970 (set_attr "trap" "yes")])
1971
1972 (define_expand "addtf3"
1973 [(use (match_operand 0 "register_operand" ""))
1974 (use (match_operand 1 "general_operand" ""))
1975 (use (match_operand 2 "general_operand" ""))]
1976 "TARGET_HAS_XFLOATING_LIBS"
1977 "alpha_emit_xfloating_arith (PLUS, operands); DONE;")
1978
1979 ;; Define conversion operators between DFmode and SImode, using the cvtql
1980 ;; instruction. To allow combine et al to do useful things, we keep the
1981 ;; operation as a unit until after reload, at which point we split the
1982 ;; instructions.
1983 ;;
1984 ;; Note that we (attempt to) only consider this optimization when the
1985 ;; ultimate destination is memory. If we will be doing further integer
1986 ;; processing, it is cheaper to do the truncation in the int regs.
1987
1988 (define_insn "*cvtql"
1989 [(set (match_operand:SI 0 "register_operand" "=f")
1990 (unspec:SI [(match_operand:DI 1 "reg_or_fp0_operand" "fG")] 5))]
1991 "TARGET_FP"
1992 "cvtql%` %R1,%0"
1993 [(set_attr "type" "fadd")
1994 (set_attr "trap" "yes")])
1995
1996 (define_split
1997 [(set (match_operand:SI 0 "memory_operand" "")
1998 (subreg:SI (fix:DI (match_operand:DF 1 "reg_or_fp0_operand" "")) 0))
1999 (clobber (match_scratch:DI 2 ""))
2000 (clobber (match_scratch:SI 3 ""))]
2001 "TARGET_FP && reload_completed"
2002 [(set (match_dup 2) (fix:DI (match_dup 1)))
2003 (set (match_dup 3) (unspec:SI [(match_dup 2)] 5))
2004 (set (match_dup 0) (match_dup 3))]
2005 "")
2006
2007 (define_split
2008 [(set (match_operand:SI 0 "memory_operand" "")
2009 (subreg:SI (fix:DI (match_operand:DF 1 "reg_or_fp0_operand" "")) 0))
2010 (clobber (match_scratch:DI 2 ""))]
2011 "TARGET_FP && reload_completed"
2012 [(set (match_dup 2) (fix:DI (match_dup 1)))
2013 (set (match_dup 3) (unspec:SI [(match_dup 2)] 5))
2014 (set (match_dup 0) (match_dup 3))]
2015 ;; Due to REG_CANNOT_CHANGE_SIZE issues, we cannot simply use SUBREG.
2016 "operands[3] = gen_rtx_REG (SImode, REGNO (operands[2]));")
2017
2018 (define_insn ""
2019 [(set (match_operand:SI 0 "memory_operand" "=m")
2020 (subreg:SI (fix:DI (match_operand:DF 1 "reg_or_fp0_operand" "fG")) 0))
2021 (clobber (match_scratch:DI 2 "=&f"))
2022 (clobber (match_scratch:SI 3 "=&f"))]
2023 "TARGET_FP && alpha_fptm >= ALPHA_FPTM_SU"
2024 "#"
2025 [(set_attr "type" "fadd")
2026 (set_attr "trap" "yes")])
2027
2028 (define_insn ""
2029 [(set (match_operand:SI 0 "memory_operand" "=m")
2030 (subreg:SI (fix:DI (match_operand:DF 1 "reg_or_fp0_operand" "fG")) 0))
2031 (clobber (match_scratch:DI 2 "=f"))]
2032 "TARGET_FP && alpha_fptm < ALPHA_FPTM_SU"
2033 "#"
2034 [(set_attr "type" "fadd")
2035 (set_attr "trap" "yes")])
2036
2037 (define_insn ""
2038 [(set (match_operand:DI 0 "reg_no_subreg_operand" "=&f")
2039 (fix:DI (match_operand:DF 1 "reg_or_fp0_operand" "fG")))]
2040 "TARGET_FP && alpha_fptm >= ALPHA_FPTM_SU"
2041 "cvt%-q%(c %R1,%0"
2042 [(set_attr "type" "fadd")
2043 (set_attr "trap" "yes")])
2044
2045 (define_insn "fix_truncdfdi2"
2046 [(set (match_operand:DI 0 "reg_no_subreg_operand" "=f")
2047 (fix:DI (match_operand:DF 1 "reg_or_fp0_operand" "fG")))]
2048 "TARGET_FP"
2049 "cvt%-q%(c %R1,%0"
2050 [(set_attr "type" "fadd")
2051 (set_attr "trap" "yes")])
2052
2053 ;; Likewise between SFmode and SImode.
2054
2055 (define_split
2056 [(set (match_operand:SI 0 "memory_operand" "")
2057 (subreg:SI (fix:DI (float_extend:DF
2058 (match_operand:SF 1 "reg_or_fp0_operand" ""))) 0))
2059 (clobber (match_scratch:DI 2 ""))
2060 (clobber (match_scratch:SI 3 ""))]
2061 "TARGET_FP && reload_completed"
2062 [(set (match_dup 2) (fix:DI (float_extend:DF (match_dup 1))))
2063 (set (match_dup 3) (unspec:SI [(match_dup 2)] 5))
2064 (set (match_dup 0) (match_dup 3))]
2065 "")
2066
2067 (define_split
2068 [(set (match_operand:SI 0 "memory_operand" "")
2069 (subreg:SI (fix:DI (float_extend:DF
2070 (match_operand:SF 1 "reg_or_fp0_operand" ""))) 0))
2071 (clobber (match_scratch:DI 2 ""))]
2072 "TARGET_FP && reload_completed"
2073 [(set (match_dup 2) (fix:DI (float_extend:DF (match_dup 1))))
2074 (set (match_dup 3) (unspec:SI [(match_dup 2)] 5))
2075 (set (match_dup 0) (match_dup 3))]
2076 ;; Due to REG_CANNOT_CHANGE_SIZE issues, we cannot simply use SUBREG.
2077 "operands[3] = gen_rtx_REG (SImode, REGNO (operands[2]));")
2078
2079 (define_insn ""
2080 [(set (match_operand:SI 0 "memory_operand" "=m")
2081 (subreg:SI (fix:DI (float_extend:DF
2082 (match_operand:SF 1 "reg_or_fp0_operand" "fG"))) 0))
2083 (clobber (match_scratch:DI 2 "=&f"))
2084 (clobber (match_scratch:SI 3 "=&f"))]
2085 "TARGET_FP && alpha_fptm >= ALPHA_FPTM_SU"
2086 "#"
2087 [(set_attr "type" "fadd")
2088 (set_attr "trap" "yes")])
2089
2090 (define_insn ""
2091 [(set (match_operand:SI 0 "memory_operand" "=m")
2092 (subreg:SI (fix:DI (float_extend:DF
2093 (match_operand:SF 1 "reg_or_fp0_operand" "fG"))) 0))
2094 (clobber (match_scratch:DI 2 "=f"))]
2095 "TARGET_FP && alpha_fptm < ALPHA_FPTM_SU"
2096 "#"
2097 [(set_attr "type" "fadd")
2098 (set_attr "trap" "yes")])
2099
2100 (define_insn ""
2101 [(set (match_operand:DI 0 "reg_no_subreg_operand" "=&f")
2102 (fix:DI (float_extend:DF
2103 (match_operand:SF 1 "reg_or_fp0_operand" "fG"))))]
2104 "TARGET_FP && alpha_fptm >= ALPHA_FPTM_SU"
2105 "cvt%-q%(c %R1,%0"
2106 [(set_attr "type" "fadd")
2107 (set_attr "trap" "yes")])
2108
2109 (define_insn "fix_truncsfdi2"
2110 [(set (match_operand:DI 0 "reg_no_subreg_operand" "=f")
2111 (fix:DI (float_extend:DF
2112 (match_operand:SF 1 "reg_or_fp0_operand" "fG"))))]
2113 "TARGET_FP"
2114 "cvt%-q%(c %R1,%0"
2115 [(set_attr "type" "fadd")
2116 (set_attr "trap" "yes")])
2117
2118 (define_expand "fix_trunctfdi2"
2119 [(use (match_operand:DI 0 "register_operand" ""))
2120 (use (match_operand:TF 1 "general_operand" ""))]
2121 "TARGET_HAS_XFLOATING_LIBS"
2122 "alpha_emit_xfloating_cvt (FIX, operands); DONE;")
2123
2124 (define_insn ""
2125 [(set (match_operand:SF 0 "register_operand" "=&f")
2126 (float:SF (match_operand:DI 1 "reg_no_subreg_operand" "f")))]
2127 "TARGET_FP && alpha_fptm >= ALPHA_FPTM_SU"
2128 "cvtq%,%+%& %1,%0"
2129 [(set_attr "type" "fadd")
2130 (set_attr "trap" "yes")])
2131
2132 (define_insn "floatdisf2"
2133 [(set (match_operand:SF 0 "register_operand" "=f")
2134 (float:SF (match_operand:DI 1 "reg_no_subreg_operand" "f")))]
2135 "TARGET_FP"
2136 "cvtq%,%+%& %1,%0"
2137 [(set_attr "type" "fadd")
2138 (set_attr "trap" "yes")])
2139
2140 (define_insn ""
2141 [(set (match_operand:DF 0 "register_operand" "=&f")
2142 (float:DF (match_operand:DI 1 "reg_no_subreg_operand" "f")))]
2143 "TARGET_FP && alpha_fptm >= ALPHA_FPTM_SU"
2144 "cvtq%-%+%& %1,%0"
2145 [(set_attr "type" "fadd")
2146 (set_attr "trap" "yes")])
2147
2148 (define_insn "floatdidf2"
2149 [(set (match_operand:DF 0 "register_operand" "=f")
2150 (float:DF (match_operand:DI 1 "reg_no_subreg_operand" "f")))]
2151 "TARGET_FP"
2152 "cvtq%-%+%& %1,%0"
2153 [(set_attr "type" "fadd")
2154 (set_attr "trap" "yes")])
2155
2156 (define_expand "floatditf2"
2157 [(use (match_operand:TF 0 "register_operand" ""))
2158 (use (match_operand:DI 1 "general_operand" ""))]
2159 "TARGET_HAS_XFLOATING_LIBS"
2160 "alpha_emit_xfloating_cvt (FLOAT, operands); DONE;")
2161
2162 (define_expand "floatunsdisf2"
2163 [(use (match_operand:SF 0 "register_operand" ""))
2164 (use (match_operand:DI 1 "register_operand" ""))]
2165 "TARGET_FP"
2166 "alpha_emit_floatuns (operands); DONE;")
2167
2168 (define_expand "floatunsdidf2"
2169 [(use (match_operand:DF 0 "register_operand" ""))
2170 (use (match_operand:DI 1 "register_operand" ""))]
2171 "TARGET_FP"
2172 "alpha_emit_floatuns (operands); DONE;")
2173
2174 (define_expand "floatunsditf2"
2175 [(use (match_operand:TF 0 "register_operand" ""))
2176 (use (match_operand:DI 1 "general_operand" ""))]
2177 "TARGET_HAS_XFLOATING_LIBS"
2178 "alpha_emit_xfloating_cvt (UNSIGNED_FLOAT, operands); DONE;")
2179
2180 (define_expand "extendsfdf2"
2181 [(set (match_operand:DF 0 "register_operand" "")
2182 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "")))]
2183 "TARGET_FP"
2184 "
2185 {
2186 if (alpha_fptm >= ALPHA_FPTM_SU)
2187 operands[1] = force_reg (SFmode, operands[1]);
2188 }")
2189
2190 (define_insn ""
2191 [(set (match_operand:DF 0 "register_operand" "=&f")
2192 (float_extend:DF (match_operand:SF 1 "register_operand" "f")))]
2193 "TARGET_FP && alpha_fptm >= ALPHA_FPTM_SU"
2194 "cvtsts %1,%0"
2195 [(set_attr "type" "fadd")
2196 (set_attr "trap" "yes")])
2197
2198 (define_insn ""
2199 [(set (match_operand:DF 0 "register_operand" "=f,f,m")
2200 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "f,m,f")))]
2201 "TARGET_FP && alpha_fptm < ALPHA_FPTM_SU"
2202 "@
2203 fmov %1,%0
2204 ld%, %0,%1
2205 st%- %1,%0"
2206 [(set_attr "type" "fcpys,fld,fst")])
2207
2208 (define_expand "extendsftf2"
2209 [(use (match_operand:TF 0 "register_operand" ""))
2210 (use (match_operand:SF 1 "general_operand" ""))]
2211 "TARGET_HAS_XFLOATING_LIBS"
2212 "
2213 {
2214 rtx tmp = gen_reg_rtx (DFmode);
2215 emit_insn (gen_extendsfdf2 (tmp, operands[1]));
2216 emit_insn (gen_extenddftf2 (operands[0], tmp));
2217 DONE;
2218 }")
2219
2220 (define_expand "extenddftf2"
2221 [(use (match_operand:TF 0 "register_operand" ""))
2222 (use (match_operand:DF 1 "general_operand" ""))]
2223 "TARGET_HAS_XFLOATING_LIBS"
2224 "alpha_emit_xfloating_cvt (FLOAT_EXTEND, operands); DONE;")
2225
2226 (define_insn ""
2227 [(set (match_operand:SF 0 "register_operand" "=&f")
2228 (float_truncate:SF (match_operand:DF 1 "reg_or_fp0_operand" "fG")))]
2229 "TARGET_FP && alpha_fptm >= ALPHA_FPTM_SU"
2230 "cvt%-%,%)%& %R1,%0"
2231 [(set_attr "type" "fadd")
2232 (set_attr "trap" "yes")])
2233
2234 (define_insn "truncdfsf2"
2235 [(set (match_operand:SF 0 "register_operand" "=f")
2236 (float_truncate:SF (match_operand:DF 1 "reg_or_fp0_operand" "fG")))]
2237 "TARGET_FP"
2238 "cvt%-%,%)%& %R1,%0"
2239 [(set_attr "type" "fadd")
2240 (set_attr "trap" "yes")])
2241
2242 (define_expand "trunctfdf2"
2243 [(use (match_operand:DF 0 "register_operand" ""))
2244 (use (match_operand:TF 1 "general_operand" ""))]
2245 "TARGET_HAS_XFLOATING_LIBS"
2246 "alpha_emit_xfloating_cvt (FLOAT_TRUNCATE, operands); DONE;")
2247
2248 (define_expand "trunctfsf2"
2249 [(use (match_operand:SF 0 "register_operand" ""))
2250 (use (match_operand:TF 1 "general_operand" ""))]
2251 "TARGET_FP && TARGET_HAS_XFLOATING_LIBS"
2252 "
2253 {
2254 rtx tmpf, sticky, arg, lo, hi;
2255
2256 tmpf = gen_reg_rtx (DFmode);
2257 sticky = gen_reg_rtx (DImode);
2258 arg = copy_to_mode_reg (TFmode, operands[1]);
2259 lo = gen_lowpart (DImode, arg);
2260 hi = gen_highpart (DImode, arg);
2261
2262 /* Convert the low word of the TFmode value into a sticky rounding bit,
2263 then or it into the low bit of the high word. This leaves the sticky
2264 bit at bit 48 of the fraction, which is representable in DFmode,
2265 which prevents rounding error in the final conversion to SFmode. */
2266
2267 emit_insn (gen_rtx_SET (VOIDmode, sticky,
2268 gen_rtx_NE (DImode, lo, const0_rtx)));
2269 emit_insn (gen_iordi3 (hi, hi, sticky));
2270 emit_insn (gen_trunctfdf2 (tmpf, arg));
2271 emit_insn (gen_truncdfsf2 (operands[0], tmpf));
2272 DONE;
2273 }")
2274
2275 (define_insn ""
2276 [(set (match_operand:SF 0 "register_operand" "=&f")
2277 (div:SF (match_operand:SF 1 "reg_or_fp0_operand" "fG")
2278 (match_operand:SF 2 "reg_or_fp0_operand" "fG")))]
2279 "TARGET_FP && alpha_fptm >= ALPHA_FPTM_SU"
2280 "div%,%)%& %R1,%R2,%0"
2281 [(set_attr "type" "fdiv")
2282 (set_attr "opsize" "si")
2283 (set_attr "trap" "yes")])
2284
2285 (define_insn "divsf3"
2286 [(set (match_operand:SF 0 "register_operand" "=f")
2287 (div:SF (match_operand:SF 1 "reg_or_fp0_operand" "fG")
2288 (match_operand:SF 2 "reg_or_fp0_operand" "fG")))]
2289 "TARGET_FP"
2290 "div%,%)%& %R1,%R2,%0"
2291 [(set_attr "type" "fdiv")
2292 (set_attr "opsize" "si")
2293 (set_attr "trap" "yes")])
2294
2295 (define_insn ""
2296 [(set (match_operand:DF 0 "register_operand" "=&f")
2297 (div:DF (match_operand:DF 1 "reg_or_fp0_operand" "fG")
2298 (match_operand:DF 2 "reg_or_fp0_operand" "fG")))]
2299 "TARGET_FP && alpha_fptm >= ALPHA_FPTM_SU"
2300 "div%-%)%& %R1,%R2,%0"
2301 [(set_attr "type" "fdiv")
2302 (set_attr "trap" "yes")])
2303
2304 (define_insn "divdf3"
2305 [(set (match_operand:DF 0 "register_operand" "=f")
2306 (div:DF (match_operand:DF 1 "reg_or_fp0_operand" "fG")
2307 (match_operand:DF 2 "reg_or_fp0_operand" "fG")))]
2308 "TARGET_FP"
2309 "div%-%)%& %R1,%R2,%0"
2310 [(set_attr "type" "fdiv")
2311 (set_attr "trap" "yes")])
2312
2313 (define_insn ""
2314 [(set (match_operand:DF 0 "register_operand" "=f")
2315 (div:DF (float_extend:DF (match_operand:SF 1 "reg_or_fp0_operand" "fG"))
2316 (match_operand:DF 2 "reg_or_fp0_operand" "fG")))]
2317 "TARGET_FP && alpha_fptm < ALPHA_FPTM_SU"
2318 "div%-%)%& %R1,%R2,%0"
2319 [(set_attr "type" "fdiv")
2320 (set_attr "trap" "yes")])
2321
2322 (define_insn ""
2323 [(set (match_operand:DF 0 "register_operand" "=f")
2324 (div:DF (match_operand:DF 1 "reg_or_fp0_operand" "fG")
2325 (float_extend:DF
2326 (match_operand:SF 2 "reg_or_fp0_operand" "fG"))))]
2327 "TARGET_FP && alpha_fptm < ALPHA_FPTM_SU"
2328 "div%-%)%& %R1,%R2,%0"
2329 [(set_attr "type" "fdiv")
2330 (set_attr "trap" "yes")])
2331
2332 (define_insn ""
2333 [(set (match_operand:DF 0 "register_operand" "=f")
2334 (div:DF (float_extend:DF (match_operand:SF 1 "reg_or_fp0_operand" "fG"))
2335 (float_extend:DF (match_operand:SF 2 "reg_or_fp0_operand" "fG"))))]
2336 "TARGET_FP && alpha_fptm < ALPHA_FPTM_SU"
2337 "div%-%)%& %R1,%R2,%0"
2338 [(set_attr "type" "fdiv")
2339 (set_attr "trap" "yes")])
2340
2341 (define_expand "divtf3"
2342 [(use (match_operand 0 "register_operand" ""))
2343 (use (match_operand 1 "general_operand" ""))
2344 (use (match_operand 2 "general_operand" ""))]
2345 "TARGET_HAS_XFLOATING_LIBS"
2346 "alpha_emit_xfloating_arith (DIV, operands); DONE;")
2347
2348 (define_insn ""
2349 [(set (match_operand:SF 0 "register_operand" "=&f")
2350 (mult:SF (match_operand:SF 1 "reg_or_fp0_operand" "%fG")
2351 (match_operand:SF 2 "reg_or_fp0_operand" "fG")))]
2352 "TARGET_FP && alpha_fptm >= ALPHA_FPTM_SU"
2353 "mul%,%)%& %R1,%R2,%0"
2354 [(set_attr "type" "fmul")
2355 (set_attr "trap" "yes")])
2356
2357 (define_insn "mulsf3"
2358 [(set (match_operand:SF 0 "register_operand" "=f")
2359 (mult:SF (match_operand:SF 1 "reg_or_fp0_operand" "%fG")
2360 (match_operand:SF 2 "reg_or_fp0_operand" "fG")))]
2361 "TARGET_FP"
2362 "mul%,%)%& %R1,%R2,%0"
2363 [(set_attr "type" "fmul")
2364 (set_attr "trap" "yes")])
2365
2366 (define_insn ""
2367 [(set (match_operand:DF 0 "register_operand" "=&f")
2368 (mult:DF (match_operand:DF 1 "reg_or_fp0_operand" "%fG")
2369 (match_operand:DF 2 "reg_or_fp0_operand" "fG")))]
2370 "TARGET_FP && alpha_fptm >= ALPHA_FPTM_SU"
2371 "mul%-%)%& %R1,%R2,%0"
2372 [(set_attr "type" "fmul")
2373 (set_attr "trap" "yes")])
2374
2375 (define_insn "muldf3"
2376 [(set (match_operand:DF 0 "register_operand" "=f")
2377 (mult:DF (match_operand:DF 1 "reg_or_fp0_operand" "%fG")
2378 (match_operand:DF 2 "reg_or_fp0_operand" "fG")))]
2379 "TARGET_FP"
2380 "mul%-%)%& %R1,%R2,%0"
2381 [(set_attr "type" "fmul")
2382 (set_attr "trap" "yes")])
2383
2384 (define_insn ""
2385 [(set (match_operand:DF 0 "register_operand" "=f")
2386 (mult:DF (float_extend:DF
2387 (match_operand:SF 1 "reg_or_fp0_operand" "fG"))
2388 (match_operand:DF 2 "reg_or_fp0_operand" "fG")))]
2389 "TARGET_FP && alpha_fptm < ALPHA_FPTM_SU"
2390 "mul%-%)%& %R1,%R2,%0"
2391 [(set_attr "type" "fmul")
2392 (set_attr "trap" "yes")])
2393
2394 (define_insn ""
2395 [(set (match_operand:DF 0 "register_operand" "=f")
2396 (mult:DF (float_extend:DF
2397 (match_operand:SF 1 "reg_or_fp0_operand" "%fG"))
2398 (float_extend:DF
2399 (match_operand:SF 2 "reg_or_fp0_operand" "fG"))))]
2400 "TARGET_FP && alpha_fptm < ALPHA_FPTM_SU"
2401 "mul%-%)%& %R1,%R2,%0"
2402 [(set_attr "type" "fmul")
2403 (set_attr "trap" "yes")])
2404
2405 (define_expand "multf3"
2406 [(use (match_operand 0 "register_operand" ""))
2407 (use (match_operand 1 "general_operand" ""))
2408 (use (match_operand 2 "general_operand" ""))]
2409 "TARGET_HAS_XFLOATING_LIBS"
2410 "alpha_emit_xfloating_arith (MULT, operands); DONE;")
2411
2412 (define_insn ""
2413 [(set (match_operand:SF 0 "register_operand" "=&f")
2414 (minus:SF (match_operand:SF 1 "reg_or_fp0_operand" "fG")
2415 (match_operand:SF 2 "reg_or_fp0_operand" "fG")))]
2416 "TARGET_FP && alpha_fptm >= ALPHA_FPTM_SU"
2417 "sub%,%)%& %R1,%R2,%0"
2418 [(set_attr "type" "fadd")
2419 (set_attr "trap" "yes")])
2420
2421 (define_insn "subsf3"
2422 [(set (match_operand:SF 0 "register_operand" "=f")
2423 (minus:SF (match_operand:SF 1 "reg_or_fp0_operand" "fG")
2424 (match_operand:SF 2 "reg_or_fp0_operand" "fG")))]
2425 "TARGET_FP"
2426 "sub%,%)%& %R1,%R2,%0"
2427 [(set_attr "type" "fadd")
2428 (set_attr "trap" "yes")])
2429
2430 (define_insn ""
2431 [(set (match_operand:DF 0 "register_operand" "=&f")
2432 (minus:DF (match_operand:DF 1 "reg_or_fp0_operand" "fG")
2433 (match_operand:DF 2 "reg_or_fp0_operand" "fG")))]
2434 "TARGET_FP && alpha_fptm >= ALPHA_FPTM_SU"
2435 "sub%-%)%& %R1,%R2,%0"
2436 [(set_attr "type" "fadd")
2437 (set_attr "trap" "yes")])
2438
2439 (define_insn "subdf3"
2440 [(set (match_operand:DF 0 "register_operand" "=f")
2441 (minus:DF (match_operand:DF 1 "reg_or_fp0_operand" "fG")
2442 (match_operand:DF 2 "reg_or_fp0_operand" "fG")))]
2443 "TARGET_FP"
2444 "sub%-%)%& %R1,%R2,%0"
2445 [(set_attr "type" "fadd")
2446 (set_attr "trap" "yes")])
2447
2448 (define_insn ""
2449 [(set (match_operand:DF 0 "register_operand" "=f")
2450 (minus:DF (float_extend:DF
2451 (match_operand:SF 1 "reg_or_fp0_operand" "fG"))
2452 (match_operand:DF 2 "reg_or_fp0_operand" "fG")))]
2453 "TARGET_FP && alpha_fptm < ALPHA_FPTM_SU"
2454 "sub%-%)%& %R1,%R2,%0"
2455 [(set_attr "type" "fadd")
2456 (set_attr "trap" "yes")])
2457
2458 (define_insn ""
2459 [(set (match_operand:DF 0 "register_operand" "=f")
2460 (minus:DF (match_operand:DF 1 "reg_or_fp0_operand" "fG")
2461 (float_extend:DF
2462 (match_operand:SF 2 "reg_or_fp0_operand" "fG"))))]
2463 "TARGET_FP && alpha_fptm < ALPHA_FPTM_SU"
2464 "sub%-%)%& %R1,%R2,%0"
2465 [(set_attr "type" "fadd")
2466 (set_attr "trap" "yes")])
2467
2468 (define_insn ""
2469 [(set (match_operand:DF 0 "register_operand" "=f")
2470 (minus:DF (float_extend:DF
2471 (match_operand:SF 1 "reg_or_fp0_operand" "fG"))
2472 (float_extend:DF
2473 (match_operand:SF 2 "reg_or_fp0_operand" "fG"))))]
2474 "TARGET_FP && alpha_fptm < ALPHA_FPTM_SU"
2475 "sub%-%)%& %R1,%R2,%0"
2476 [(set_attr "type" "fadd")
2477 (set_attr "trap" "yes")])
2478
2479 (define_expand "subtf3"
2480 [(use (match_operand 0 "register_operand" ""))
2481 (use (match_operand 1 "general_operand" ""))
2482 (use (match_operand 2 "general_operand" ""))]
2483 "TARGET_HAS_XFLOATING_LIBS"
2484 "alpha_emit_xfloating_arith (MINUS, operands); DONE;")
2485
2486 (define_insn ""
2487 [(set (match_operand:SF 0 "register_operand" "=&f")
2488 (sqrt:SF (match_operand:SF 1 "reg_or_fp0_operand" "fG")))]
2489 "TARGET_FP && TARGET_FIX && alpha_fptm >= ALPHA_FPTM_SU"
2490 "sqrt%,%)%& %R1,%0"
2491 [(set_attr "type" "fsqrt")
2492 (set_attr "opsize" "si")
2493 (set_attr "trap" "yes")])
2494
2495 (define_insn "sqrtsf2"
2496 [(set (match_operand:SF 0 "register_operand" "=f")
2497 (sqrt:SF (match_operand:SF 1 "reg_or_fp0_operand" "fG")))]
2498 "TARGET_FP && TARGET_FIX"
2499 "sqrt%,%)%& %R1,%0"
2500 [(set_attr "type" "fsqrt")
2501 (set_attr "opsize" "si")
2502 (set_attr "trap" "yes")])
2503
2504 (define_insn ""
2505 [(set (match_operand:DF 0 "register_operand" "=&f")
2506 (sqrt:DF (match_operand:DF 1 "reg_or_fp0_operand" "fG")))]
2507 "TARGET_FP && TARGET_FIX && alpha_fptm >= ALPHA_FPTM_SU"
2508 "sqrt%-%)%& %R1,%0"
2509 [(set_attr "type" "fsqrt")
2510 (set_attr "trap" "yes")])
2511
2512 (define_insn "sqrtdf2"
2513 [(set (match_operand:DF 0 "register_operand" "=f")
2514 (sqrt:DF (match_operand:DF 1 "reg_or_fp0_operand" "fG")))]
2515 "TARGET_FP && TARGET_FIX"
2516 "sqrt%-%)%& %1,%0"
2517 [(set_attr "type" "fsqrt")
2518 (set_attr "trap" "yes")])
2519 \f
2520 ;; Next are all the integer comparisons, and conditional moves and branches
2521 ;; and some of the related define_expand's and define_split's.
2522
2523 (define_insn "*setcc_internal"
2524 [(set (match_operand 0 "register_operand" "=r")
2525 (match_operator 1 "alpha_comparison_operator"
2526 [(match_operand:DI 2 "reg_or_0_operand" "rJ")
2527 (match_operand:DI 3 "reg_or_8bit_operand" "rI")]))]
2528 "GET_MODE_CLASS (GET_MODE (operands[0])) == MODE_INT
2529 && GET_MODE_SIZE (GET_MODE (operands[0])) <= 8
2530 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
2531 "cmp%C1 %r2,%3,%0"
2532 [(set_attr "type" "icmp")])
2533
2534 (define_insn "*setcc_swapped_internal"
2535 [(set (match_operand 0 "register_operand" "=r")
2536 (match_operator 1 "alpha_swapped_comparison_operator"
2537 [(match_operand:DI 2 "reg_or_8bit_operand" "rI")
2538 (match_operand:DI 3 "reg_or_0_operand" "rJ")]))]
2539 "GET_MODE_CLASS (GET_MODE (operands[0])) == MODE_INT
2540 && GET_MODE_SIZE (GET_MODE (operands[0])) <= 8
2541 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
2542 "cmp%c1 %r3,%2,%0"
2543 [(set_attr "type" "icmp")])
2544
2545 (define_insn "*setne_internal"
2546 [(set (match_operand 0 "register_operand" "=r")
2547 (match_operator 1 "signed_comparison_operator"
2548 [(match_operand:DI 2 "reg_or_8bit_operand" "rI")
2549 (const_int 0)]))]
2550 "GET_MODE_CLASS (GET_MODE (operands[0])) == MODE_INT
2551 && GET_MODE_SIZE (GET_MODE (operands[0])) <= 8
2552 && GET_CODE (operands[1]) == NE
2553 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
2554 "cmpult $31,%2,%0"
2555 [(set_attr "type" "icmp")])
2556
2557 ;; The mode folding trick can't be used with const_int operands, since
2558 ;; reload needs to know the proper mode.
2559 ;;
2560 ;; Use add_operand instead of the more seemingly natural reg_or_8bit_operand
2561 ;; in order to create more pairs of constants. As long as we're allowing
2562 ;; two constants at the same time, and will have to reload one of them...
2563
2564 (define_insn "*movqicc_internal"
2565 [(set (match_operand:QI 0 "register_operand" "=r,r,r,r")
2566 (if_then_else:QI
2567 (match_operator 2 "signed_comparison_operator"
2568 [(match_operand:DI 3 "reg_or_0_operand" "rJ,rJ,J,J")
2569 (match_operand:DI 4 "reg_or_0_operand" "J,J,rJ,rJ")])
2570 (match_operand:QI 1 "add_operand" "rI,0,rI,0")
2571 (match_operand:QI 5 "add_operand" "0,rI,0,rI")))]
2572 "(operands[3] == const0_rtx || operands[4] == const0_rtx)"
2573 "@
2574 cmov%C2 %r3,%1,%0
2575 cmov%D2 %r3,%5,%0
2576 cmov%c2 %r4,%1,%0
2577 cmov%d2 %r4,%5,%0"
2578 [(set_attr "type" "icmov")])
2579
2580 (define_insn "*movhicc_internal"
2581 [(set (match_operand:HI 0 "register_operand" "=r,r,r,r")
2582 (if_then_else:HI
2583 (match_operator 2 "signed_comparison_operator"
2584 [(match_operand:DI 3 "reg_or_0_operand" "rJ,rJ,J,J")
2585 (match_operand:DI 4 "reg_or_0_operand" "J,J,rJ,rJ")])
2586 (match_operand:HI 1 "add_operand" "rI,0,rI,0")
2587 (match_operand:HI 5 "add_operand" "0,rI,0,rI")))]
2588 "(operands[3] == const0_rtx || operands[4] == const0_rtx)"
2589 "@
2590 cmov%C2 %r3,%1,%0
2591 cmov%D2 %r3,%5,%0
2592 cmov%c2 %r4,%1,%0
2593 cmov%d2 %r4,%5,%0"
2594 [(set_attr "type" "icmov")])
2595
2596 (define_insn "*movsicc_internal"
2597 [(set (match_operand:SI 0 "register_operand" "=r,r,r,r")
2598 (if_then_else:SI
2599 (match_operator 2 "signed_comparison_operator"
2600 [(match_operand:DI 3 "reg_or_0_operand" "rJ,rJ,J,J")
2601 (match_operand:DI 4 "reg_or_0_operand" "J,J,rJ,rJ")])
2602 (match_operand:SI 1 "add_operand" "rI,0,rI,0")
2603 (match_operand:SI 5 "add_operand" "0,rI,0,rI")))]
2604 "(operands[3] == const0_rtx || operands[4] == const0_rtx)"
2605 "@
2606 cmov%C2 %r3,%1,%0
2607 cmov%D2 %r3,%5,%0
2608 cmov%c2 %r4,%1,%0
2609 cmov%d2 %r4,%5,%0"
2610 [(set_attr "type" "icmov")])
2611
2612 (define_insn "*movdicc_internal"
2613 [(set (match_operand:DI 0 "register_operand" "=r,r,r,r")
2614 (if_then_else:DI
2615 (match_operator 2 "signed_comparison_operator"
2616 [(match_operand:DI 3 "reg_or_0_operand" "rJ,rJ,J,J")
2617 (match_operand:DI 4 "reg_or_0_operand" "J,J,rJ,rJ")])
2618 (match_operand:DI 1 "add_operand" "rI,0,rI,0")
2619 (match_operand:DI 5 "add_operand" "0,rI,0,rI")))]
2620 "(operands[3] == const0_rtx || operands[4] == const0_rtx)"
2621 "@
2622 cmov%C2 %r3,%1,%0
2623 cmov%D2 %r3,%5,%0
2624 cmov%c2 %r4,%1,%0
2625 cmov%d2 %r4,%5,%0"
2626 [(set_attr "type" "icmov")])
2627
2628 (define_insn "*movqicc_lbc"
2629 [(set (match_operand:QI 0 "register_operand" "=r,r")
2630 (if_then_else:QI
2631 (eq (zero_extract:DI (match_operand:DI 2 "reg_or_0_operand" "rJ,rJ")
2632 (const_int 1)
2633 (const_int 0))
2634 (const_int 0))
2635 (match_operand:QI 1 "reg_or_8bit_operand" "rI,0")
2636 (match_operand:QI 3 "reg_or_8bit_operand" "0,rI")))]
2637 ""
2638 "@
2639 cmovlbc %r2,%1,%0
2640 cmovlbs %r2,%3,%0"
2641 [(set_attr "type" "icmov")])
2642
2643 (define_insn "*movhicc_lbc"
2644 [(set (match_operand:HI 0 "register_operand" "=r,r")
2645 (if_then_else:HI
2646 (eq (zero_extract:DI (match_operand:DI 2 "reg_or_0_operand" "rJ,rJ")
2647 (const_int 1)
2648 (const_int 0))
2649 (const_int 0))
2650 (match_operand:HI 1 "reg_or_8bit_operand" "rI,0")
2651 (match_operand:HI 3 "reg_or_8bit_operand" "0,rI")))]
2652 ""
2653 "@
2654 cmovlbc %r2,%1,%0
2655 cmovlbs %r2,%3,%0"
2656 [(set_attr "type" "icmov")])
2657
2658 (define_insn "*movsicc_lbc"
2659 [(set (match_operand:SI 0 "register_operand" "=r,r")
2660 (if_then_else:SI
2661 (eq (zero_extract:DI (match_operand:DI 2 "reg_or_0_operand" "rJ,rJ")
2662 (const_int 1)
2663 (const_int 0))
2664 (const_int 0))
2665 (match_operand:SI 1 "reg_or_8bit_operand" "rI,0")
2666 (match_operand:SI 3 "reg_or_8bit_operand" "0,rI")))]
2667 ""
2668 "@
2669 cmovlbc %r2,%1,%0
2670 cmovlbs %r2,%3,%0"
2671 [(set_attr "type" "icmov")])
2672
2673 (define_insn "*movdicc_lbc"
2674 [(set (match_operand:DI 0 "register_operand" "=r,r")
2675 (if_then_else:DI
2676 (eq (zero_extract:DI (match_operand:DI 2 "reg_or_0_operand" "rJ,rJ")
2677 (const_int 1)
2678 (const_int 0))
2679 (const_int 0))
2680 (match_operand:DI 1 "reg_or_8bit_operand" "rI,0")
2681 (match_operand:DI 3 "reg_or_8bit_operand" "0,rI")))]
2682 ""
2683 "@
2684 cmovlbc %r2,%1,%0
2685 cmovlbs %r2,%3,%0"
2686 [(set_attr "type" "icmov")])
2687
2688 (define_insn "*movqicc_lbs"
2689 [(set (match_operand:QI 0 "register_operand" "=r,r")
2690 (if_then_else:QI
2691 (ne (zero_extract:DI (match_operand:DI 2 "reg_or_0_operand" "rJ,rJ")
2692 (const_int 1)
2693 (const_int 0))
2694 (const_int 0))
2695 (match_operand:QI 1 "reg_or_8bit_operand" "rI,0")
2696 (match_operand:QI 3 "reg_or_8bit_operand" "0,rI")))]
2697 ""
2698 "@
2699 cmovlbs %r2,%1,%0
2700 cmovlbc %r2,%3,%0"
2701 [(set_attr "type" "icmov")])
2702
2703 (define_insn "*movhicc_lbs"
2704 [(set (match_operand:HI 0 "register_operand" "=r,r")
2705 (if_then_else:HI
2706 (ne (zero_extract:DI (match_operand:DI 2 "reg_or_0_operand" "rJ,rJ")
2707 (const_int 1)
2708 (const_int 0))
2709 (const_int 0))
2710 (match_operand:HI 1 "reg_or_8bit_operand" "rI,0")
2711 (match_operand:HI 3 "reg_or_8bit_operand" "0,rI")))]
2712 ""
2713 "@
2714 cmovlbs %r2,%1,%0
2715 cmovlbc %r2,%3,%0"
2716 [(set_attr "type" "icmov")])
2717
2718 (define_insn "*movsicc_lbs"
2719 [(set (match_operand:SI 0 "register_operand" "=r,r")
2720 (if_then_else:SI
2721 (ne (zero_extract:DI (match_operand:DI 2 "reg_or_0_operand" "rJ,rJ")
2722 (const_int 1)
2723 (const_int 0))
2724 (const_int 0))
2725 (match_operand:SI 1 "reg_or_8bit_operand" "rI,0")
2726 (match_operand:SI 3 "reg_or_8bit_operand" "0,rI")))]
2727 ""
2728 "@
2729 cmovlbs %r2,%1,%0
2730 cmovlbc %r2,%3,%0"
2731 [(set_attr "type" "icmov")])
2732
2733 (define_insn "*movdicc_lbs"
2734 [(set (match_operand:DI 0 "register_operand" "=r,r")
2735 (if_then_else:DI
2736 (ne (zero_extract:DI (match_operand:DI 2 "reg_or_0_operand" "rJ,rJ")
2737 (const_int 1)
2738 (const_int 0))
2739 (const_int 0))
2740 (match_operand:DI 1 "reg_or_8bit_operand" "rI,0")
2741 (match_operand:DI 3 "reg_or_8bit_operand" "0,rI")))]
2742 ""
2743 "@
2744 cmovlbs %r2,%1,%0
2745 cmovlbc %r2,%3,%0"
2746 [(set_attr "type" "icmov")])
2747
2748 ;; For ABS, we have two choices, depending on whether the input and output
2749 ;; registers are the same or not.
2750 (define_expand "absdi2"
2751 [(set (match_operand:DI 0 "register_operand" "")
2752 (abs:DI (match_operand:DI 1 "register_operand" "")))]
2753 ""
2754 "
2755 { if (rtx_equal_p (operands[0], operands[1]))
2756 emit_insn (gen_absdi2_same (operands[0], gen_reg_rtx (DImode)));
2757 else
2758 emit_insn (gen_absdi2_diff (operands[0], operands[1]));
2759
2760 DONE;
2761 }")
2762
2763 (define_expand "absdi2_same"
2764 [(set (match_operand:DI 1 "register_operand" "")
2765 (neg:DI (match_operand:DI 0 "register_operand" "")))
2766 (set (match_dup 0)
2767 (if_then_else:DI (ge (match_dup 0) (const_int 0))
2768 (match_dup 0)
2769 (match_dup 1)))]
2770 ""
2771 "")
2772
2773 (define_expand "absdi2_diff"
2774 [(set (match_operand:DI 0 "register_operand" "")
2775 (neg:DI (match_operand:DI 1 "register_operand" "")))
2776 (set (match_dup 0)
2777 (if_then_else:DI (lt (match_dup 1) (const_int 0))
2778 (match_dup 0)
2779 (match_dup 1)))]
2780 ""
2781 "")
2782
2783 (define_split
2784 [(set (match_operand:DI 0 "register_operand" "")
2785 (abs:DI (match_dup 0)))
2786 (clobber (match_operand:DI 2 "register_operand" ""))]
2787 ""
2788 [(set (match_dup 1) (neg:DI (match_dup 0)))
2789 (set (match_dup 0) (if_then_else:DI (ge (match_dup 0) (const_int 0))
2790 (match_dup 0) (match_dup 1)))]
2791 "")
2792
2793 (define_split
2794 [(set (match_operand:DI 0 "register_operand" "")
2795 (abs:DI (match_operand:DI 1 "register_operand" "")))]
2796 "! rtx_equal_p (operands[0], operands[1])"
2797 [(set (match_dup 0) (neg:DI (match_dup 1)))
2798 (set (match_dup 0) (if_then_else:DI (lt (match_dup 1) (const_int 0))
2799 (match_dup 0) (match_dup 1)))]
2800 "")
2801
2802 (define_split
2803 [(set (match_operand:DI 0 "register_operand" "")
2804 (neg:DI (abs:DI (match_dup 0))))
2805 (clobber (match_operand:DI 2 "register_operand" ""))]
2806 ""
2807 [(set (match_dup 1) (neg:DI (match_dup 0)))
2808 (set (match_dup 0) (if_then_else:DI (le (match_dup 0) (const_int 0))
2809 (match_dup 0) (match_dup 1)))]
2810 "")
2811
2812 (define_split
2813 [(set (match_operand:DI 0 "register_operand" "")
2814 (neg:DI (abs:DI (match_operand:DI 1 "register_operand" ""))))]
2815 "! rtx_equal_p (operands[0], operands[1])"
2816 [(set (match_dup 0) (neg:DI (match_dup 1)))
2817 (set (match_dup 0) (if_then_else:DI (gt (match_dup 1) (const_int 0))
2818 (match_dup 0) (match_dup 1)))]
2819 "")
2820
2821 (define_insn "sminqi3"
2822 [(set (match_operand:QI 0 "register_operand" "=r")
2823 (smin:QI (match_operand:QI 1 "reg_or_0_operand" "%rJ")
2824 (match_operand:QI 2 "reg_or_8bit_operand" "rI")))]
2825 "TARGET_MAX"
2826 "minsb8 %r1,%2,%0"
2827 [(set_attr "type" "mvi")])
2828
2829 (define_insn "uminqi3"
2830 [(set (match_operand:QI 0 "register_operand" "=r")
2831 (umin:QI (match_operand:QI 1 "reg_or_0_operand" "%rJ")
2832 (match_operand:QI 2 "reg_or_8bit_operand" "rI")))]
2833 "TARGET_MAX"
2834 "minub8 %r1,%2,%0"
2835 [(set_attr "type" "mvi")])
2836
2837 (define_insn "smaxqi3"
2838 [(set (match_operand:QI 0 "register_operand" "=r")
2839 (smax:QI (match_operand:QI 1 "reg_or_0_operand" "%rJ")
2840 (match_operand:QI 2 "reg_or_8bit_operand" "rI")))]
2841 "TARGET_MAX"
2842 "maxsb8 %r1,%2,%0"
2843 [(set_attr "type" "mvi")])
2844
2845 (define_insn "umaxqi3"
2846 [(set (match_operand:QI 0 "register_operand" "=r")
2847 (umax:QI (match_operand:QI 1 "reg_or_0_operand" "%rJ")
2848 (match_operand:QI 2 "reg_or_8bit_operand" "rI")))]
2849 "TARGET_MAX"
2850 "maxub8 %r1,%2,%0"
2851 [(set_attr "type" "mvi")])
2852
2853 (define_insn "sminhi3"
2854 [(set (match_operand:HI 0 "register_operand" "=r")
2855 (smin:HI (match_operand:HI 1 "reg_or_0_operand" "%rJ")
2856 (match_operand:HI 2 "reg_or_8bit_operand" "rI")))]
2857 "TARGET_MAX"
2858 "minsw4 %r1,%2,%0"
2859 [(set_attr "type" "mvi")])
2860
2861 (define_insn "uminhi3"
2862 [(set (match_operand:HI 0 "register_operand" "=r")
2863 (umin:HI (match_operand:HI 1 "reg_or_0_operand" "%rJ")
2864 (match_operand:HI 2 "reg_or_8bit_operand" "rI")))]
2865 "TARGET_MAX"
2866 "minuw4 %r1,%2,%0"
2867 [(set_attr "type" "mvi")])
2868
2869 (define_insn "smaxhi3"
2870 [(set (match_operand:HI 0 "register_operand" "=r")
2871 (smax:HI (match_operand:HI 1 "reg_or_0_operand" "%rJ")
2872 (match_operand:HI 2 "reg_or_8bit_operand" "rI")))]
2873 "TARGET_MAX"
2874 "maxsw4 %r1,%2,%0"
2875 [(set_attr "type" "mvi")])
2876
2877 (define_insn "umaxhi3"
2878 [(set (match_operand:HI 0 "register_operand" "=r")
2879 (umax:HI (match_operand:HI 1 "reg_or_0_operand" "%rJ")
2880 (match_operand:HI 2 "reg_or_8bit_operand" "rI")))]
2881 "TARGET_MAX"
2882 "maxuw4 %r1,%2,%0"
2883 [(set_attr "type" "shift")])
2884
2885 (define_expand "smaxdi3"
2886 [(set (match_dup 3)
2887 (le:DI (match_operand:DI 1 "reg_or_0_operand" "")
2888 (match_operand:DI 2 "reg_or_8bit_operand" "")))
2889 (set (match_operand:DI 0 "register_operand" "")
2890 (if_then_else:DI (eq (match_dup 3) (const_int 0))
2891 (match_dup 1) (match_dup 2)))]
2892 ""
2893 "
2894 { operands[3] = gen_reg_rtx (DImode);
2895 }")
2896
2897 (define_split
2898 [(set (match_operand:DI 0 "register_operand" "")
2899 (smax:DI (match_operand:DI 1 "reg_or_0_operand" "")
2900 (match_operand:DI 2 "reg_or_8bit_operand" "")))
2901 (clobber (match_operand:DI 3 "register_operand" ""))]
2902 "operands[2] != const0_rtx"
2903 [(set (match_dup 3) (le:DI (match_dup 1) (match_dup 2)))
2904 (set (match_dup 0) (if_then_else:DI (eq (match_dup 3) (const_int 0))
2905 (match_dup 1) (match_dup 2)))]
2906 "")
2907
2908 (define_insn ""
2909 [(set (match_operand:DI 0 "register_operand" "=r")
2910 (smax:DI (match_operand:DI 1 "register_operand" "0")
2911 (const_int 0)))]
2912 ""
2913 "cmovlt %0,0,%0"
2914 [(set_attr "type" "icmov")])
2915
2916 (define_expand "smindi3"
2917 [(set (match_dup 3)
2918 (lt:DI (match_operand:DI 1 "reg_or_0_operand" "")
2919 (match_operand:DI 2 "reg_or_8bit_operand" "")))
2920 (set (match_operand:DI 0 "register_operand" "")
2921 (if_then_else:DI (ne (match_dup 3) (const_int 0))
2922 (match_dup 1) (match_dup 2)))]
2923 ""
2924 "
2925 { operands[3] = gen_reg_rtx (DImode);
2926 }")
2927
2928 (define_split
2929 [(set (match_operand:DI 0 "register_operand" "")
2930 (smin:DI (match_operand:DI 1 "reg_or_0_operand" "")
2931 (match_operand:DI 2 "reg_or_8bit_operand" "")))
2932 (clobber (match_operand:DI 3 "register_operand" ""))]
2933 "operands[2] != const0_rtx"
2934 [(set (match_dup 3) (lt:DI (match_dup 1) (match_dup 2)))
2935 (set (match_dup 0) (if_then_else:DI (ne (match_dup 3) (const_int 0))
2936 (match_dup 1) (match_dup 2)))]
2937 "")
2938
2939 (define_insn ""
2940 [(set (match_operand:DI 0 "register_operand" "=r")
2941 (smin:DI (match_operand:DI 1 "register_operand" "0")
2942 (const_int 0)))]
2943 ""
2944 "cmovgt %0,0,%0"
2945 [(set_attr "type" "icmov")])
2946
2947 (define_expand "umaxdi3"
2948 [(set (match_dup 3)
2949 (leu:DI (match_operand:DI 1 "reg_or_0_operand" "")
2950 (match_operand:DI 2 "reg_or_8bit_operand" "")))
2951 (set (match_operand:DI 0 "register_operand" "")
2952 (if_then_else:DI (eq (match_dup 3) (const_int 0))
2953 (match_dup 1) (match_dup 2)))]
2954 ""
2955 "
2956 { operands[3] = gen_reg_rtx (DImode);
2957 }")
2958
2959 (define_split
2960 [(set (match_operand:DI 0 "register_operand" "")
2961 (umax:DI (match_operand:DI 1 "reg_or_0_operand" "")
2962 (match_operand:DI 2 "reg_or_8bit_operand" "")))
2963 (clobber (match_operand:DI 3 "register_operand" ""))]
2964 "operands[2] != const0_rtx"
2965 [(set (match_dup 3) (leu:DI (match_dup 1) (match_dup 2)))
2966 (set (match_dup 0) (if_then_else:DI (eq (match_dup 3) (const_int 0))
2967 (match_dup 1) (match_dup 2)))]
2968 "")
2969
2970 (define_expand "umindi3"
2971 [(set (match_dup 3)
2972 (ltu:DI (match_operand:DI 1 "reg_or_0_operand" "")
2973 (match_operand:DI 2 "reg_or_8bit_operand" "")))
2974 (set (match_operand:DI 0 "register_operand" "")
2975 (if_then_else:DI (ne (match_dup 3) (const_int 0))
2976 (match_dup 1) (match_dup 2)))]
2977 ""
2978 "
2979 { operands[3] = gen_reg_rtx (DImode);
2980 }")
2981
2982 (define_split
2983 [(set (match_operand:DI 0 "register_operand" "")
2984 (umin:DI (match_operand:DI 1 "reg_or_0_operand" "")
2985 (match_operand:DI 2 "reg_or_8bit_operand" "")))
2986 (clobber (match_operand:DI 3 "register_operand" ""))]
2987 "operands[2] != const0_rtx"
2988 [(set (match_dup 3) (ltu:DI (match_dup 1) (match_dup 2)))
2989 (set (match_dup 0) (if_then_else:DI (ne (match_dup 3) (const_int 0))
2990 (match_dup 1) (match_dup 2)))]
2991 "")
2992
2993 (define_insn ""
2994 [(set (pc)
2995 (if_then_else
2996 (match_operator 1 "signed_comparison_operator"
2997 [(match_operand:DI 2 "reg_or_0_operand" "rJ")
2998 (const_int 0)])
2999 (label_ref (match_operand 0 "" ""))
3000 (pc)))]
3001 ""
3002 "b%C1 %r2,%0"
3003 [(set_attr "type" "ibr")])
3004
3005 (define_insn ""
3006 [(set (pc)
3007 (if_then_else
3008 (match_operator 1 "signed_comparison_operator"
3009 [(const_int 0)
3010 (match_operand:DI 2 "register_operand" "r")])
3011 (label_ref (match_operand 0 "" ""))
3012 (pc)))]
3013 ""
3014 "b%c1 %2,%0"
3015 [(set_attr "type" "ibr")])
3016
3017 (define_insn ""
3018 [(set (pc)
3019 (if_then_else
3020 (ne (zero_extract:DI (match_operand:DI 1 "reg_or_0_operand" "rJ")
3021 (const_int 1)
3022 (const_int 0))
3023 (const_int 0))
3024 (label_ref (match_operand 0 "" ""))
3025 (pc)))]
3026 ""
3027 "blbs %r1,%0"
3028 [(set_attr "type" "ibr")])
3029
3030 (define_insn ""
3031 [(set (pc)
3032 (if_then_else
3033 (eq (zero_extract:DI (match_operand:DI 1 "reg_or_0_operand" "rJ")
3034 (const_int 1)
3035 (const_int 0))
3036 (const_int 0))
3037 (label_ref (match_operand 0 "" ""))
3038 (pc)))]
3039 ""
3040 "blbc %r1,%0"
3041 [(set_attr "type" "ibr")])
3042
3043 (define_split
3044 [(parallel
3045 [(set (pc)
3046 (if_then_else
3047 (match_operator 1 "comparison_operator"
3048 [(zero_extract:DI (match_operand:DI 2 "register_operand" "")
3049 (const_int 1)
3050 (match_operand:DI 3 "const_int_operand" ""))
3051 (const_int 0)])
3052 (label_ref (match_operand 0 "" ""))
3053 (pc)))
3054 (clobber (match_operand:DI 4 "register_operand" ""))])]
3055 "INTVAL (operands[3]) != 0"
3056 [(set (match_dup 4)
3057 (lshiftrt:DI (match_dup 2) (match_dup 3)))
3058 (set (pc)
3059 (if_then_else (match_op_dup 1
3060 [(zero_extract:DI (match_dup 4)
3061 (const_int 1)
3062 (const_int 0))
3063 (const_int 0)])
3064 (label_ref (match_dup 0))
3065 (pc)))]
3066 "")
3067 \f
3068 ;; The following are the corresponding floating-point insns. Recall
3069 ;; we need to have variants that expand the arguments from SFmode
3070 ;; to DFmode.
3071
3072 (define_insn "*cmpdf_tp"
3073 [(set (match_operand:DF 0 "register_operand" "=&f")
3074 (match_operator:DF 1 "alpha_fp_comparison_operator"
3075 [(match_operand:DF 2 "reg_or_fp0_operand" "fG")
3076 (match_operand:DF 3 "reg_or_fp0_operand" "fG")]))]
3077 "TARGET_FP && alpha_fptm >= ALPHA_FPTM_SU"
3078 "cmp%-%C1%' %R2,%R3,%0"
3079 [(set_attr "type" "fadd")
3080 (set_attr "trap" "yes")])
3081
3082 (define_insn "*cmpdf_no_tp"
3083 [(set (match_operand:DF 0 "register_operand" "=f")
3084 (match_operator:DF 1 "alpha_fp_comparison_operator"
3085 [(match_operand:DF 2 "reg_or_fp0_operand" "fG")
3086 (match_operand:DF 3 "reg_or_fp0_operand" "fG")]))]
3087 "TARGET_FP && alpha_fptm < ALPHA_FPTM_SU"
3088 "cmp%-%C1%' %R2,%R3,%0"
3089 [(set_attr "type" "fadd")
3090 (set_attr "trap" "yes")])
3091
3092 (define_insn ""
3093 [(set (match_operand:DF 0 "register_operand" "=&f")
3094 (match_operator:DF 1 "alpha_fp_comparison_operator"
3095 [(float_extend:DF
3096 (match_operand:SF 2 "reg_or_fp0_operand" "fG"))
3097 (match_operand:DF 3 "reg_or_fp0_operand" "fG")]))]
3098 "TARGET_FP && alpha_fptm >= ALPHA_FPTM_SU"
3099 "cmp%-%C1%' %R2,%R3,%0"
3100 [(set_attr "type" "fadd")
3101 (set_attr "trap" "yes")])
3102
3103 (define_insn ""
3104 [(set (match_operand:DF 0 "register_operand" "=f")
3105 (match_operator:DF 1 "alpha_fp_comparison_operator"
3106 [(float_extend:DF
3107 (match_operand:SF 2 "reg_or_fp0_operand" "fG"))
3108 (match_operand:DF 3 "reg_or_fp0_operand" "fG")]))]
3109 "TARGET_FP && alpha_fptm < ALPHA_FPTM_SU"
3110 "cmp%-%C1%' %R2,%R3,%0"
3111 [(set_attr "type" "fadd")
3112 (set_attr "trap" "yes")])
3113
3114 (define_insn ""
3115 [(set (match_operand:DF 0 "register_operand" "=&f")
3116 (match_operator:DF 1 "alpha_fp_comparison_operator"
3117 [(match_operand:DF 2 "reg_or_fp0_operand" "fG")
3118 (float_extend:DF
3119 (match_operand:SF 3 "reg_or_fp0_operand" "fG"))]))]
3120 "TARGET_FP && alpha_fptm >= ALPHA_FPTM_SU"
3121 "cmp%-%C1%' %R2,%R3,%0"
3122 [(set_attr "type" "fadd")
3123 (set_attr "trap" "yes")])
3124
3125 (define_insn ""
3126 [(set (match_operand:DF 0 "register_operand" "=f")
3127 (match_operator:DF 1 "alpha_fp_comparison_operator"
3128 [(match_operand:DF 2 "reg_or_fp0_operand" "fG")
3129 (float_extend:DF
3130 (match_operand:SF 3 "reg_or_fp0_operand" "fG"))]))]
3131 "TARGET_FP && alpha_fptm < ALPHA_FPTM_SU"
3132 "cmp%-%C1%' %R2,%R3,%0"
3133 [(set_attr "type" "fadd")
3134 (set_attr "trap" "yes")])
3135
3136 (define_insn ""
3137 [(set (match_operand:DF 0 "register_operand" "=&f")
3138 (match_operator:DF 1 "alpha_fp_comparison_operator"
3139 [(float_extend:DF
3140 (match_operand:SF 2 "reg_or_fp0_operand" "fG"))
3141 (float_extend:DF
3142 (match_operand:SF 3 "reg_or_fp0_operand" "fG"))]))]
3143 "TARGET_FP && alpha_fptm >= ALPHA_FPTM_SU"
3144 "cmp%-%C1%' %R2,%R3,%0"
3145 [(set_attr "type" "fadd")
3146 (set_attr "trap" "yes")])
3147
3148 (define_insn ""
3149 [(set (match_operand:DF 0 "register_operand" "=f")
3150 (match_operator:DF 1 "alpha_fp_comparison_operator"
3151 [(float_extend:DF
3152 (match_operand:SF 2 "reg_or_fp0_operand" "fG"))
3153 (float_extend:DF
3154 (match_operand:SF 3 "reg_or_fp0_operand" "fG"))]))]
3155 "TARGET_FP && alpha_fptm < ALPHA_FPTM_SU"
3156 "cmp%-%C1%' %R2,%R3,%0"
3157 [(set_attr "type" "fadd")
3158 (set_attr "trap" "yes")])
3159
3160 (define_insn ""
3161 [(set (match_operand:DF 0 "register_operand" "=f,f")
3162 (if_then_else:DF
3163 (match_operator 3 "signed_comparison_operator"
3164 [(match_operand:DF 4 "reg_or_fp0_operand" "fG,fG")
3165 (match_operand:DF 2 "fp0_operand" "G,G")])
3166 (match_operand:DF 1 "reg_or_fp0_operand" "fG,0")
3167 (match_operand:DF 5 "reg_or_fp0_operand" "0,fG")))]
3168 "TARGET_FP"
3169 "@
3170 fcmov%C3 %R4,%R1,%0
3171 fcmov%D3 %R4,%R5,%0"
3172 [(set_attr "type" "fcmov")])
3173
3174 (define_insn ""
3175 [(set (match_operand:SF 0 "register_operand" "=f,f")
3176 (if_then_else:SF
3177 (match_operator 3 "signed_comparison_operator"
3178 [(match_operand:DF 4 "reg_or_fp0_operand" "fG,fG")
3179 (match_operand:DF 2 "fp0_operand" "G,G")])
3180 (match_operand:SF 1 "reg_or_fp0_operand" "fG,0")
3181 (match_operand:SF 5 "reg_or_fp0_operand" "0,fG")))]
3182 "TARGET_FP"
3183 "@
3184 fcmov%C3 %R4,%R1,%0
3185 fcmov%D3 %R4,%R5,%0"
3186 [(set_attr "type" "fcmov")])
3187
3188 (define_insn ""
3189 [(set (match_operand:DF 0 "register_operand" "=f,f")
3190 (if_then_else:DF
3191 (match_operator 3 "signed_comparison_operator"
3192 [(match_operand:DF 4 "reg_or_fp0_operand" "fG,fG")
3193 (match_operand:DF 2 "fp0_operand" "G,G")])
3194 (float_extend:DF (match_operand:SF 1 "reg_or_fp0_operand" "fG,0"))
3195 (match_operand:DF 5 "reg_or_fp0_operand" "0,fG")))]
3196 "TARGET_FP"
3197 "@
3198 fcmov%C3 %R4,%R1,%0
3199 fcmov%D3 %R4,%R5,%0"
3200 [(set_attr "type" "fcmov")])
3201
3202 (define_insn ""
3203 [(set (match_operand:DF 0 "register_operand" "=f,f")
3204 (if_then_else:DF
3205 (match_operator 3 "signed_comparison_operator"
3206 [(float_extend:DF
3207 (match_operand:SF 4 "reg_or_fp0_operand" "fG,fG"))
3208 (match_operand:DF 2 "fp0_operand" "G,G")])
3209 (match_operand:DF 1 "reg_or_fp0_operand" "fG,0")
3210 (match_operand:DF 5 "reg_or_fp0_operand" "0,fG")))]
3211 "TARGET_FP"
3212 "@
3213 fcmov%C3 %R4,%R1,%0
3214 fcmov%D3 %R4,%R5,%0"
3215 [(set_attr "type" "fcmov")])
3216
3217 (define_insn ""
3218 [(set (match_operand:SF 0 "register_operand" "=f,f")
3219 (if_then_else:SF
3220 (match_operator 3 "signed_comparison_operator"
3221 [(float_extend:DF
3222 (match_operand:SF 4 "reg_or_fp0_operand" "fG,fG"))
3223 (match_operand:DF 2 "fp0_operand" "G,G")])
3224 (match_operand:SF 1 "reg_or_fp0_operand" "fG,0")
3225 (match_operand:SF 5 "reg_or_fp0_operand" "0,fG")))]
3226 "TARGET_FP"
3227 "@
3228 fcmov%C3 %R4,%R1,%0
3229 fcmov%D3 %R4,%R5,%0"
3230 [(set_attr "type" "fcmov")])
3231
3232 (define_insn ""
3233 [(set (match_operand:DF 0 "register_operand" "=f,f")
3234 (if_then_else:DF
3235 (match_operator 3 "signed_comparison_operator"
3236 [(float_extend:DF
3237 (match_operand:SF 4 "reg_or_fp0_operand" "fG,fG"))
3238 (match_operand:DF 2 "fp0_operand" "G,G")])
3239 (float_extend:DF (match_operand:SF 1 "reg_or_fp0_operand" "fG,0"))
3240 (match_operand:DF 5 "reg_or_fp0_operand" "0,fG")))]
3241 "TARGET_FP"
3242 "@
3243 fcmov%C3 %R4,%R1,%0
3244 fcmov%D3 %R4,%R5,%0"
3245 [(set_attr "type" "fcmov")])
3246
3247 (define_expand "maxdf3"
3248 [(set (match_dup 3)
3249 (le:DF (match_operand:DF 1 "reg_or_fp0_operand" "")
3250 (match_operand:DF 2 "reg_or_fp0_operand" "")))
3251 (set (match_operand:DF 0 "register_operand" "")
3252 (if_then_else:DF (eq (match_dup 3) (match_dup 4))
3253 (match_dup 1) (match_dup 2)))]
3254 "TARGET_FP"
3255 "
3256 { operands[3] = gen_reg_rtx (DFmode);
3257 operands[4] = CONST0_RTX (DFmode);
3258 }")
3259
3260 (define_expand "mindf3"
3261 [(set (match_dup 3)
3262 (lt:DF (match_operand:DF 1 "reg_or_fp0_operand" "")
3263 (match_operand:DF 2 "reg_or_fp0_operand" "")))
3264 (set (match_operand:DF 0 "register_operand" "")
3265 (if_then_else:DF (ne (match_dup 3) (match_dup 4))
3266 (match_dup 1) (match_dup 2)))]
3267 "TARGET_FP"
3268 "
3269 { operands[3] = gen_reg_rtx (DFmode);
3270 operands[4] = CONST0_RTX (DFmode);
3271 }")
3272
3273 (define_expand "maxsf3"
3274 [(set (match_dup 3)
3275 (le:DF (float_extend:DF (match_operand:SF 1 "reg_or_fp0_operand" ""))
3276 (float_extend:DF (match_operand:SF 2 "reg_or_fp0_operand" ""))))
3277 (set (match_operand:SF 0 "register_operand" "")
3278 (if_then_else:SF (eq (match_dup 3) (match_dup 4))
3279 (match_dup 1) (match_dup 2)))]
3280 "TARGET_FP"
3281 "
3282 { operands[3] = gen_reg_rtx (DFmode);
3283 operands[4] = CONST0_RTX (DFmode);
3284 }")
3285
3286 (define_expand "minsf3"
3287 [(set (match_dup 3)
3288 (lt:DF (float_extend:DF (match_operand:SF 1 "reg_or_fp0_operand" ""))
3289 (float_extend:DF (match_operand:SF 2 "reg_or_fp0_operand" ""))))
3290 (set (match_operand:SF 0 "register_operand" "")
3291 (if_then_else:SF (ne (match_dup 3) (match_dup 4))
3292 (match_dup 1) (match_dup 2)))]
3293 "TARGET_FP"
3294 "
3295 { operands[3] = gen_reg_rtx (DFmode);
3296 operands[4] = CONST0_RTX (DFmode);
3297 }")
3298
3299 (define_insn ""
3300 [(set (pc)
3301 (if_then_else
3302 (match_operator 1 "signed_comparison_operator"
3303 [(match_operand:DF 2 "reg_or_fp0_operand" "fG")
3304 (match_operand:DF 3 "fp0_operand" "G")])
3305 (label_ref (match_operand 0 "" ""))
3306 (pc)))]
3307 "TARGET_FP"
3308 "fb%C1 %R2,%0"
3309 [(set_attr "type" "fbr")])
3310
3311 (define_insn ""
3312 [(set (pc)
3313 (if_then_else
3314 (match_operator 1 "signed_comparison_operator"
3315 [(float_extend:DF
3316 (match_operand:SF 2 "reg_or_fp0_operand" "fG"))
3317 (match_operand:DF 3 "fp0_operand" "G")])
3318 (label_ref (match_operand 0 "" ""))
3319 (pc)))]
3320 "TARGET_FP"
3321 "fb%C1 %R2,%0"
3322 [(set_attr "type" "fbr")])
3323 \f
3324 ;; These are the main define_expand's used to make conditional branches
3325 ;; and compares.
3326
3327 (define_expand "cmpdf"
3328 [(set (cc0) (compare (match_operand:DF 0 "reg_or_fp0_operand" "")
3329 (match_operand:DF 1 "reg_or_fp0_operand" "")))]
3330 "TARGET_FP"
3331 "
3332 {
3333 alpha_compare.op0 = operands[0];
3334 alpha_compare.op1 = operands[1];
3335 alpha_compare.fp_p = 1;
3336 DONE;
3337 }")
3338
3339 (define_expand "cmptf"
3340 [(set (cc0) (compare (match_operand:TF 0 "general_operand" "")
3341 (match_operand:TF 1 "general_operand" "")))]
3342 "TARGET_HAS_XFLOATING_LIBS"
3343 "
3344 {
3345 alpha_compare.op0 = operands[0];
3346 alpha_compare.op1 = operands[1];
3347 alpha_compare.fp_p = 1;
3348 DONE;
3349 }")
3350
3351 (define_expand "cmpdi"
3352 [(set (cc0) (compare (match_operand:DI 0 "general_operand" "")
3353 (match_operand:DI 1 "general_operand" "")))]
3354 ""
3355 "
3356 {
3357 alpha_compare.op0 = operands[0];
3358 alpha_compare.op1 = operands[1];
3359 alpha_compare.fp_p = 0;
3360 DONE;
3361 }")
3362
3363 (define_expand "beq"
3364 [(set (pc)
3365 (if_then_else (match_dup 1)
3366 (label_ref (match_operand 0 "" ""))
3367 (pc)))]
3368 ""
3369 "{ operands[1] = alpha_emit_conditional_branch (EQ); }")
3370
3371 (define_expand "bne"
3372 [(set (pc)
3373 (if_then_else (match_dup 1)
3374 (label_ref (match_operand 0 "" ""))
3375 (pc)))]
3376 ""
3377 "{ operands[1] = alpha_emit_conditional_branch (NE); }")
3378
3379 (define_expand "blt"
3380 [(set (pc)
3381 (if_then_else (match_dup 1)
3382 (label_ref (match_operand 0 "" ""))
3383 (pc)))]
3384 ""
3385 "{ operands[1] = alpha_emit_conditional_branch (LT); }")
3386
3387 (define_expand "ble"
3388 [(set (pc)
3389 (if_then_else (match_dup 1)
3390 (label_ref (match_operand 0 "" ""))
3391 (pc)))]
3392 ""
3393 "{ operands[1] = alpha_emit_conditional_branch (LE); }")
3394
3395 (define_expand "bgt"
3396 [(set (pc)
3397 (if_then_else (match_dup 1)
3398 (label_ref (match_operand 0 "" ""))
3399 (pc)))]
3400 ""
3401 "{ operands[1] = alpha_emit_conditional_branch (GT); }")
3402
3403 (define_expand "bge"
3404 [(set (pc)
3405 (if_then_else (match_dup 1)
3406 (label_ref (match_operand 0 "" ""))
3407 (pc)))]
3408 ""
3409 "{ operands[1] = alpha_emit_conditional_branch (GE); }")
3410
3411 (define_expand "bltu"
3412 [(set (pc)
3413 (if_then_else (match_dup 1)
3414 (label_ref (match_operand 0 "" ""))
3415 (pc)))]
3416 ""
3417 "{ operands[1] = alpha_emit_conditional_branch (LTU); }")
3418
3419 (define_expand "bleu"
3420 [(set (pc)
3421 (if_then_else (match_dup 1)
3422 (label_ref (match_operand 0 "" ""))
3423 (pc)))]
3424 ""
3425 "{ operands[1] = alpha_emit_conditional_branch (LEU); }")
3426
3427 (define_expand "bgtu"
3428 [(set (pc)
3429 (if_then_else (match_dup 1)
3430 (label_ref (match_operand 0 "" ""))
3431 (pc)))]
3432 ""
3433 "{ operands[1] = alpha_emit_conditional_branch (GTU); }")
3434
3435 (define_expand "bgeu"
3436 [(set (pc)
3437 (if_then_else (match_dup 1)
3438 (label_ref (match_operand 0 "" ""))
3439 (pc)))]
3440 ""
3441 "{ operands[1] = alpha_emit_conditional_branch (GEU); }")
3442
3443 (define_expand "bunordered"
3444 [(set (pc)
3445 (if_then_else (match_dup 1)
3446 (label_ref (match_operand 0 "" ""))
3447 (pc)))]
3448 ""
3449 "{ operands[1] = alpha_emit_conditional_branch (UNORDERED); }")
3450
3451 (define_expand "bordered"
3452 [(set (pc)
3453 (if_then_else (match_dup 1)
3454 (label_ref (match_operand 0 "" ""))
3455 (pc)))]
3456 ""
3457 "{ operands[1] = alpha_emit_conditional_branch (ORDERED); }")
3458
3459 (define_expand "seq"
3460 [(set (match_operand:DI 0 "register_operand" "")
3461 (match_dup 1))]
3462 ""
3463 "{ if ((operands[1] = alpha_emit_setcc (EQ)) == NULL_RTX) FAIL; }")
3464
3465 (define_expand "sne"
3466 [(set (match_operand:DI 0 "register_operand" "")
3467 (match_dup 1))]
3468 ""
3469 "{ if ((operands[1] = alpha_emit_setcc (NE)) == NULL_RTX) FAIL; }")
3470
3471 (define_expand "slt"
3472 [(set (match_operand:DI 0 "register_operand" "")
3473 (match_dup 1))]
3474 ""
3475 "{ if ((operands[1] = alpha_emit_setcc (LT)) == NULL_RTX) FAIL; }")
3476
3477 (define_expand "sle"
3478 [(set (match_operand:DI 0 "register_operand" "")
3479 (match_dup 1))]
3480 ""
3481 "{ if ((operands[1] = alpha_emit_setcc (LE)) == NULL_RTX) FAIL; }")
3482
3483 (define_expand "sgt"
3484 [(set (match_operand:DI 0 "register_operand" "")
3485 (match_dup 1))]
3486 ""
3487 "{ if ((operands[1] = alpha_emit_setcc (GT)) == NULL_RTX) FAIL; }")
3488
3489 (define_expand "sge"
3490 [(set (match_operand:DI 0 "register_operand" "")
3491 (match_dup 1))]
3492 ""
3493 "{ if ((operands[1] = alpha_emit_setcc (GE)) == NULL_RTX) FAIL; }")
3494
3495 (define_expand "sltu"
3496 [(set (match_operand:DI 0 "register_operand" "")
3497 (match_dup 1))]
3498 ""
3499 "{ if ((operands[1] = alpha_emit_setcc (LTU)) == NULL_RTX) FAIL; }")
3500
3501 (define_expand "sleu"
3502 [(set (match_operand:DI 0 "register_operand" "")
3503 (match_dup 1))]
3504 ""
3505 "{ if ((operands[1] = alpha_emit_setcc (LEU)) == NULL_RTX) FAIL; }")
3506
3507 (define_expand "sgtu"
3508 [(set (match_operand:DI 0 "register_operand" "")
3509 (match_dup 1))]
3510 ""
3511 "{ if ((operands[1] = alpha_emit_setcc (GTU)) == NULL_RTX) FAIL; }")
3512
3513 (define_expand "sgeu"
3514 [(set (match_operand:DI 0 "register_operand" "")
3515 (match_dup 1))]
3516 ""
3517 "{ if ((operands[1] = alpha_emit_setcc (GEU)) == NULL_RTX) FAIL; }")
3518
3519 (define_expand "sunordered"
3520 [(set (match_operand:DI 0 "register_operand" "")
3521 (match_dup 1))]
3522 ""
3523 "{ if ((operands[1] = alpha_emit_setcc (UNORDERED)) == NULL_RTX) FAIL; }")
3524
3525 (define_expand "sordered"
3526 [(set (match_operand:DI 0 "register_operand" "")
3527 (match_dup 1))]
3528 ""
3529 "{ if ((operands[1] = alpha_emit_setcc (ORDERED)) == NULL_RTX) FAIL; }")
3530 \f
3531 ;; These are the main define_expand's used to make conditional moves.
3532
3533 (define_expand "movsicc"
3534 [(set (match_operand:SI 0 "register_operand" "")
3535 (if_then_else:SI (match_operand 1 "comparison_operator" "")
3536 (match_operand:SI 2 "reg_or_8bit_operand" "")
3537 (match_operand:SI 3 "reg_or_8bit_operand" "")))]
3538 ""
3539 "
3540 {
3541 if ((operands[1] = alpha_emit_conditional_move (operands[1], SImode)) == 0)
3542 FAIL;
3543 }")
3544
3545 (define_expand "movdicc"
3546 [(set (match_operand:DI 0 "register_operand" "")
3547 (if_then_else:DI (match_operand 1 "comparison_operator" "")
3548 (match_operand:DI 2 "reg_or_8bit_operand" "")
3549 (match_operand:DI 3 "reg_or_8bit_operand" "")))]
3550 ""
3551 "
3552 {
3553 if ((operands[1] = alpha_emit_conditional_move (operands[1], DImode)) == 0)
3554 FAIL;
3555 }")
3556
3557 (define_expand "movsfcc"
3558 [(set (match_operand:SF 0 "register_operand" "")
3559 (if_then_else:SF (match_operand 1 "comparison_operator" "")
3560 (match_operand:SF 2 "reg_or_8bit_operand" "")
3561 (match_operand:SF 3 "reg_or_8bit_operand" "")))]
3562 ""
3563 "
3564 {
3565 if ((operands[1] = alpha_emit_conditional_move (operands[1], SFmode)) == 0)
3566 FAIL;
3567 }")
3568
3569 (define_expand "movdfcc"
3570 [(set (match_operand:DF 0 "register_operand" "")
3571 (if_then_else:DF (match_operand 1 "comparison_operator" "")
3572 (match_operand:DF 2 "reg_or_8bit_operand" "")
3573 (match_operand:DF 3 "reg_or_8bit_operand" "")))]
3574 ""
3575 "
3576 {
3577 if ((operands[1] = alpha_emit_conditional_move (operands[1], DFmode)) == 0)
3578 FAIL;
3579 }")
3580 \f
3581 ;; These define_split definitions are used in cases when comparisons have
3582 ;; not be stated in the correct way and we need to reverse the second
3583 ;; comparison. For example, x >= 7 has to be done as x < 6 with the
3584 ;; comparison that tests the result being reversed. We have one define_split
3585 ;; for each use of a comparison. They do not match valid insns and need
3586 ;; not generate valid insns.
3587 ;;
3588 ;; We can also handle equality comparisons (and inequality comparisons in
3589 ;; cases where the resulting add cannot overflow) by doing an add followed by
3590 ;; a comparison with zero. This is faster since the addition takes one
3591 ;; less cycle than a compare when feeding into a conditional move.
3592 ;; For this case, we also have an SImode pattern since we can merge the add
3593 ;; and sign extend and the order doesn't matter.
3594 ;;
3595 ;; We do not do this for floating-point, since it isn't clear how the "wrong"
3596 ;; operation could have been generated.
3597
3598 (define_split
3599 [(set (match_operand:DI 0 "register_operand" "")
3600 (if_then_else:DI
3601 (match_operator 1 "comparison_operator"
3602 [(match_operand:DI 2 "reg_or_0_operand" "")
3603 (match_operand:DI 3 "reg_or_cint_operand" "")])
3604 (match_operand:DI 4 "reg_or_cint_operand" "")
3605 (match_operand:DI 5 "reg_or_cint_operand" "")))
3606 (clobber (match_operand:DI 6 "register_operand" ""))]
3607 "operands[3] != const0_rtx"
3608 [(set (match_dup 6) (match_dup 7))
3609 (set (match_dup 0)
3610 (if_then_else:DI (match_dup 8) (match_dup 4) (match_dup 5)))]
3611 "
3612 { enum rtx_code code = GET_CODE (operands[1]);
3613 int unsignedp = (code == GEU || code == LEU || code == GTU || code == LTU);
3614
3615 /* If we are comparing for equality with a constant and that constant
3616 appears in the arm when the register equals the constant, use the
3617 register since that is more likely to match (and to produce better code
3618 if both would). */
3619
3620 if (code == EQ && GET_CODE (operands[3]) == CONST_INT
3621 && rtx_equal_p (operands[4], operands[3]))
3622 operands[4] = operands[2];
3623
3624 else if (code == NE && GET_CODE (operands[3]) == CONST_INT
3625 && rtx_equal_p (operands[5], operands[3]))
3626 operands[5] = operands[2];
3627
3628 if (code == NE || code == EQ
3629 || (extended_count (operands[2], DImode, unsignedp) >= 1
3630 && extended_count (operands[3], DImode, unsignedp) >= 1))
3631 {
3632 if (GET_CODE (operands[3]) == CONST_INT)
3633 operands[7] = gen_rtx_PLUS (DImode, operands[2],
3634 GEN_INT (- INTVAL (operands[3])));
3635 else
3636 operands[7] = gen_rtx_MINUS (DImode, operands[2], operands[3]);
3637
3638 operands[8] = gen_rtx_fmt_ee (code, VOIDmode, operands[6], const0_rtx);
3639 }
3640
3641 else if (code == EQ || code == LE || code == LT
3642 || code == LEU || code == LTU)
3643 {
3644 operands[7] = gen_rtx_fmt_ee (code, DImode, operands[2], operands[3]);
3645 operands[8] = gen_rtx_NE (VOIDmode, operands[6], const0_rtx);
3646 }
3647 else
3648 {
3649 operands[7] = gen_rtx_fmt_ee (reverse_condition (code), DImode,
3650 operands[2], operands[3]);
3651 operands[8] = gen_rtx_EQ (VOIDmode, operands[6], const0_rtx);
3652 }
3653 }")
3654
3655 (define_split
3656 [(set (match_operand:DI 0 "register_operand" "")
3657 (if_then_else:DI
3658 (match_operator 1 "comparison_operator"
3659 [(match_operand:SI 2 "reg_or_0_operand" "")
3660 (match_operand:SI 3 "reg_or_cint_operand" "")])
3661 (match_operand:DI 4 "reg_or_8bit_operand" "")
3662 (match_operand:DI 5 "reg_or_8bit_operand" "")))
3663 (clobber (match_operand:DI 6 "register_operand" ""))]
3664 "operands[3] != const0_rtx
3665 && (GET_CODE (operands[1]) == EQ || GET_CODE (operands[1]) == NE)"
3666 [(set (match_dup 6) (match_dup 7))
3667 (set (match_dup 0)
3668 (if_then_else:DI (match_dup 8) (match_dup 4) (match_dup 5)))]
3669 "
3670 { enum rtx_code code = GET_CODE (operands[1]);
3671 int unsignedp = (code == GEU || code == LEU || code == GTU || code == LTU);
3672 rtx tem;
3673
3674 if ((code != NE && code != EQ
3675 && ! (extended_count (operands[2], DImode, unsignedp) >= 1
3676 && extended_count (operands[3], DImode, unsignedp) >= 1)))
3677 FAIL;
3678
3679 if (GET_CODE (operands[3]) == CONST_INT)
3680 tem = gen_rtx_PLUS (SImode, operands[2],
3681 GEN_INT (- INTVAL (operands[3])));
3682 else
3683 tem = gen_rtx_MINUS (SImode, operands[2], operands[3]);
3684
3685 operands[7] = gen_rtx_SIGN_EXTEND (DImode, tem);
3686 operands[8] = gen_rtx_fmt_ee (GET_CODE (operands[1]), VOIDmode,
3687 operands[6], const0_rtx);
3688 }")
3689
3690 (define_split
3691 [(set (pc)
3692 (if_then_else
3693 (match_operator 1 "comparison_operator"
3694 [(match_operand:DI 2 "reg_or_0_operand" "")
3695 (match_operand:DI 3 "reg_or_cint_operand" "")])
3696 (label_ref (match_operand 0 "" ""))
3697 (pc)))
3698 (clobber (match_operand:DI 4 "register_operand" ""))]
3699 "operands[3] != const0_rtx"
3700 [(set (match_dup 4) (match_dup 5))
3701 (set (pc) (if_then_else (match_dup 6) (label_ref (match_dup 0)) (pc)))]
3702 "
3703 { enum rtx_code code = GET_CODE (operands[1]);
3704 int unsignedp = (code == GEU || code == LEU || code == GTU || code == LTU);
3705
3706 if (code == NE || code == EQ
3707 || (extended_count (operands[2], DImode, unsignedp) >= 1
3708 && extended_count (operands[3], DImode, unsignedp) >= 1))
3709 {
3710 if (GET_CODE (operands[3]) == CONST_INT)
3711 operands[5] = gen_rtx_PLUS (DImode, operands[2],
3712 GEN_INT (- INTVAL (operands[3])));
3713 else
3714 operands[5] = gen_rtx_MINUS (DImode, operands[2], operands[3]);
3715
3716 operands[6] = gen_rtx_fmt_ee (code, VOIDmode, operands[4], const0_rtx);
3717 }
3718
3719 else if (code == EQ || code == LE || code == LT
3720 || code == LEU || code == LTU)
3721 {
3722 operands[5] = gen_rtx_fmt_ee (code, DImode, operands[2], operands[3]);
3723 operands[6] = gen_rtx_NE (VOIDmode, operands[4], const0_rtx);
3724 }
3725 else
3726 {
3727 operands[5] = gen_rtx_fmt_ee (reverse_condition (code), DImode,
3728 operands[2], operands[3]);
3729 operands[6] = gen_rtx_EQ (VOIDmode, operands[4], const0_rtx);
3730 }
3731 }")
3732
3733 (define_split
3734 [(set (pc)
3735 (if_then_else
3736 (match_operator 1 "comparison_operator"
3737 [(match_operand:SI 2 "reg_or_0_operand" "")
3738 (match_operand:SI 3 "const_int_operand" "")])
3739 (label_ref (match_operand 0 "" ""))
3740 (pc)))
3741 (clobber (match_operand:DI 4 "register_operand" ""))]
3742 "operands[3] != const0_rtx
3743 && (GET_CODE (operands[1]) == EQ || GET_CODE (operands[1]) == NE)"
3744 [(set (match_dup 4) (match_dup 5))
3745 (set (pc) (if_then_else (match_dup 6) (label_ref (match_dup 0)) (pc)))]
3746 "
3747 { rtx tem;
3748
3749 if (GET_CODE (operands[3]) == CONST_INT)
3750 tem = gen_rtx_PLUS (SImode, operands[2],
3751 GEN_INT (- INTVAL (operands[3])));
3752 else
3753 tem = gen_rtx_MINUS (SImode, operands[2], operands[3]);
3754
3755 operands[5] = gen_rtx_SIGN_EXTEND (DImode, tem);
3756 operands[6] = gen_rtx_fmt_ee (GET_CODE (operands[1]), VOIDmode,
3757 operands[4], const0_rtx);
3758 }")
3759
3760 ;; We can convert such things as "a > 0xffff" to "t = a & ~ 0xffff; t != 0".
3761 ;; This eliminates one, and sometimes two, insns when the AND can be done
3762 ;; with a ZAP.
3763 (define_split
3764 [(set (match_operand:DI 0 "register_operand" "")
3765 (match_operator:DI 1 "comparison_operator"
3766 [(match_operand:DI 2 "register_operand" "")
3767 (match_operand:DI 3 "const_int_operand" "")]))
3768 (clobber (match_operand:DI 4 "register_operand" ""))]
3769 "exact_log2 (INTVAL (operands[3]) + 1) >= 0
3770 && (GET_CODE (operands[1]) == GTU
3771 || GET_CODE (operands[1]) == LEU
3772 || ((GET_CODE (operands[1]) == GT || GET_CODE (operands[1]) == LE)
3773 && extended_count (operands[2], DImode, 1) > 0))"
3774 [(set (match_dup 4) (and:DI (match_dup 2) (match_dup 5)))
3775 (set (match_dup 0) (match_dup 6))]
3776 "
3777 {
3778 operands[5] = GEN_INT (~ INTVAL (operands[3]));
3779 operands[6] = gen_rtx_fmt_ee (((GET_CODE (operands[1]) == GTU
3780 || GET_CODE (operands[1]) == GT)
3781 ? NE : EQ),
3782 DImode, operands[4], const0_rtx);
3783 }")
3784
3785 ;; Prefer to use cmp and arithmetic when possible instead of a cmove.
3786
3787 (define_split
3788 [(set (match_operand 0 "register_operand" "")
3789 (if_then_else (match_operator 1 "signed_comparison_operator"
3790 [(match_operand:DI 2 "reg_or_0_operand" "")
3791 (const_int 0)])
3792 (match_operand 3 "const_int_operand" "")
3793 (match_operand 4 "const_int_operand" "")))]
3794 ""
3795 [(const_int 0)]
3796 "
3797 {
3798 if (alpha_split_conditional_move (GET_CODE (operands[1]), operands[0],
3799 operands[2], operands[3], operands[4]))
3800 DONE;
3801 else
3802 FAIL;
3803 }")
3804
3805 ;; ??? Why combine is allowed to create such non-canonical rtl, I don't know.
3806 ;; Oh well, we match it in movcc, so it must be partially our fault.
3807 (define_split
3808 [(set (match_operand 0 "register_operand" "")
3809 (if_then_else (match_operator 1 "signed_comparison_operator"
3810 [(const_int 0)
3811 (match_operand:DI 2 "reg_or_0_operand" "")])
3812 (match_operand 3 "const_int_operand" "")
3813 (match_operand 4 "const_int_operand" "")))]
3814 ""
3815 [(const_int 0)]
3816 "
3817 {
3818 if (alpha_split_conditional_move (swap_condition (GET_CODE (operands[1])),
3819 operands[0], operands[2], operands[3],
3820 operands[4]))
3821 DONE;
3822 else
3823 FAIL;
3824 }")
3825
3826 (define_insn_and_split "*cmp_sadd_di"
3827 [(set (match_operand:DI 0 "register_operand" "=r")
3828 (plus:DI (if_then_else:DI
3829 (match_operator 1 "alpha_zero_comparison_operator"
3830 [(match_operand:DI 2 "reg_or_0_operand" "rJ")
3831 (const_int 0)])
3832 (match_operand:DI 3 "const48_operand" "I")
3833 (const_int 0))
3834 (match_operand:DI 4 "sext_add_operand" "rIO")))
3835 (clobber (match_scratch:DI 5 "=r"))]
3836 ""
3837 "#"
3838 "! no_new_pseudos || reload_completed"
3839 [(set (match_dup 5)
3840 (match_op_dup:DI 1 [(match_dup 2) (const_int 0)]))
3841 (set (match_dup 0)
3842 (plus:DI (mult:DI (match_dup 5) (match_dup 3))
3843 (match_dup 4)))]
3844 "
3845 {
3846 if (! no_new_pseudos)
3847 operands[5] = gen_reg_rtx (DImode);
3848 else if (reg_overlap_mentioned_p (operands[5], operands[4]))
3849 operands[5] = operands[0];
3850 }")
3851
3852 (define_insn_and_split "*cmp_sadd_si"
3853 [(set (match_operand:SI 0 "register_operand" "=r")
3854 (plus:SI (if_then_else:SI
3855 (match_operator 1 "alpha_zero_comparison_operator"
3856 [(match_operand:DI 2 "reg_or_0_operand" "rJ")
3857 (const_int 0)])
3858 (match_operand:SI 3 "const48_operand" "I")
3859 (const_int 0))
3860 (match_operand:SI 4 "sext_add_operand" "rIO")))
3861 (clobber (match_scratch:SI 5 "=r"))]
3862 ""
3863 "#"
3864 "! no_new_pseudos || reload_completed"
3865 [(set (match_dup 5)
3866 (match_op_dup:SI 1 [(match_dup 2) (const_int 0)]))
3867 (set (match_dup 0)
3868 (plus:SI (mult:SI (match_dup 5) (match_dup 3))
3869 (match_dup 4)))]
3870 "
3871 {
3872 if (! no_new_pseudos)
3873 operands[5] = gen_reg_rtx (DImode);
3874 else if (reg_overlap_mentioned_p (operands[5], operands[4]))
3875 operands[5] = operands[0];
3876 }")
3877
3878 (define_insn_and_split "*cmp_sadd_sidi"
3879 [(set (match_operand:DI 0 "register_operand" "=r")
3880 (sign_extend:DI
3881 (plus:SI (if_then_else:SI
3882 (match_operator 1 "alpha_zero_comparison_operator"
3883 [(match_operand:DI 2 "reg_or_0_operand" "rJ")
3884 (const_int 0)])
3885 (match_operand:SI 3 "const48_operand" "I")
3886 (const_int 0))
3887 (match_operand:SI 4 "sext_add_operand" "rIO"))))
3888 (clobber (match_scratch:SI 5 "=r"))]
3889 ""
3890 "#"
3891 "! no_new_pseudos || reload_completed"
3892 [(set (match_dup 5)
3893 (match_op_dup:SI 1 [(match_dup 2) (const_int 0)]))
3894 (set (match_dup 0)
3895 (sign_extend:DI (plus:SI (mult:SI (match_dup 5) (match_dup 3))
3896 (match_dup 4))))]
3897 "
3898 {
3899 if (! no_new_pseudos)
3900 operands[5] = gen_reg_rtx (DImode);
3901 else if (reg_overlap_mentioned_p (operands[5], operands[4]))
3902 operands[5] = operands[0];
3903 }")
3904
3905 (define_insn_and_split "*cmp_ssub_di"
3906 [(set (match_operand:DI 0 "register_operand" "=r")
3907 (minus:DI (if_then_else:DI
3908 (match_operator 1 "alpha_zero_comparison_operator"
3909 [(match_operand:DI 2 "reg_or_0_operand" "rJ")
3910 (const_int 0)])
3911 (match_operand:DI 3 "const48_operand" "I")
3912 (const_int 0))
3913 (match_operand:DI 4 "reg_or_8bit_operand" "rI")))
3914 (clobber (match_scratch:DI 5 "=r"))]
3915 ""
3916 "#"
3917 "! no_new_pseudos || reload_completed"
3918 [(set (match_dup 5)
3919 (match_op_dup:DI 1 [(match_dup 2) (const_int 0)]))
3920 (set (match_dup 0)
3921 (minus:DI (mult:DI (match_dup 5) (match_dup 3))
3922 (match_dup 4)))]
3923 "
3924 {
3925 if (! no_new_pseudos)
3926 operands[5] = gen_reg_rtx (DImode);
3927 else if (reg_overlap_mentioned_p (operands[5], operands[4]))
3928 operands[5] = operands[0];
3929 }")
3930
3931 (define_insn_and_split "*cmp_ssub_si"
3932 [(set (match_operand:SI 0 "register_operand" "=r")
3933 (minus:SI (if_then_else:SI
3934 (match_operator 1 "alpha_zero_comparison_operator"
3935 [(match_operand:DI 2 "reg_or_0_operand" "rJ")
3936 (const_int 0)])
3937 (match_operand:SI 3 "const48_operand" "I")
3938 (const_int 0))
3939 (match_operand:SI 4 "reg_or_8bit_operand" "rI")))
3940 (clobber (match_scratch:SI 5 "=r"))]
3941 ""
3942 "#"
3943 "! no_new_pseudos || reload_completed"
3944 [(set (match_dup 5)
3945 (match_op_dup:SI 1 [(match_dup 2) (const_int 0)]))
3946 (set (match_dup 0)
3947 (minus:SI (mult:SI (match_dup 5) (match_dup 3))
3948 (match_dup 4)))]
3949 "
3950 {
3951 if (! no_new_pseudos)
3952 operands[5] = gen_reg_rtx (DImode);
3953 else if (reg_overlap_mentioned_p (operands[5], operands[4]))
3954 operands[5] = operands[0];
3955 }")
3956
3957 (define_insn_and_split "*cmp_ssub_sidi"
3958 [(set (match_operand:DI 0 "register_operand" "=r")
3959 (sign_extend:DI
3960 (minus:SI (if_then_else:SI
3961 (match_operator 1 "alpha_zero_comparison_operator"
3962 [(match_operand:DI 2 "reg_or_0_operand" "rJ")
3963 (const_int 0)])
3964 (match_operand:SI 3 "const48_operand" "I")
3965 (const_int 0))
3966 (match_operand:SI 4 "reg_or_8bit_operand" "rI"))))
3967 (clobber (match_scratch:SI 5 "=r"))]
3968 ""
3969 "#"
3970 "! no_new_pseudos || reload_completed"
3971 [(set (match_dup 5)
3972 (match_op_dup:SI 1 [(match_dup 2) (const_int 0)]))
3973 (set (match_dup 0)
3974 (sign_extend:DI (minus:SI (mult:SI (match_dup 5) (match_dup 3))
3975 (match_dup 4))))]
3976 "
3977 {
3978 if (! no_new_pseudos)
3979 operands[5] = gen_reg_rtx (DImode);
3980 else if (reg_overlap_mentioned_p (operands[5], operands[4]))
3981 operands[5] = operands[0];
3982 }")
3983 \f
3984 ;; Here are the CALL and unconditional branch insns. Calls on NT and OSF
3985 ;; work differently, so we have different patterns for each.
3986
3987 (define_expand "call"
3988 [(use (match_operand:DI 0 "" ""))
3989 (use (match_operand 1 "" ""))
3990 (use (match_operand 2 "" ""))
3991 (use (match_operand 3 "" ""))]
3992 ""
3993 "
3994 { if (TARGET_WINDOWS_NT)
3995 emit_call_insn (gen_call_nt (operands[0], operands[1]));
3996 else if (TARGET_OPEN_VMS)
3997 emit_call_insn (gen_call_vms (operands[0], operands[2]));
3998 else
3999 emit_call_insn (gen_call_osf (operands[0], operands[1]));
4000
4001 DONE;
4002 }")
4003
4004 (define_expand "sibcall"
4005 [(call (mem:DI (match_operand 0 "" ""))
4006 (match_operand 1 "" ""))]
4007 "!TARGET_OPEN_VMS && !TARGET_WINDOWS_NT"
4008 "
4009 {
4010 if (GET_CODE (operands[0]) != MEM)
4011 abort ();
4012 operands[0] = XEXP (operands[0], 0);
4013 }")
4014
4015 (define_expand "call_osf"
4016 [(parallel [(call (mem:DI (match_operand 0 "" ""))
4017 (match_operand 1 "" ""))
4018 (clobber (reg:DI 27))
4019 (clobber (reg:DI 26))])]
4020 ""
4021 "
4022 { if (GET_CODE (operands[0]) != MEM)
4023 abort ();
4024
4025 operands[0] = XEXP (operands[0], 0);
4026
4027 if (GET_CODE (operands[0]) != SYMBOL_REF
4028 && ! (GET_CODE (operands[0]) == REG && REGNO (operands[0]) == 27))
4029 {
4030 rtx tem = gen_rtx_REG (DImode, 27);
4031 emit_move_insn (tem, operands[0]);
4032 operands[0] = tem;
4033 }
4034 }")
4035
4036 (define_expand "call_nt"
4037 [(parallel [(call (mem:DI (match_operand 0 "" ""))
4038 (match_operand 1 "" ""))
4039 (clobber (reg:DI 26))])]
4040 ""
4041 "
4042 { if (GET_CODE (operands[0]) != MEM)
4043 abort ();
4044
4045 operands[0] = XEXP (operands[0], 0);
4046 if (GET_CODE (operands[0]) != SYMBOL_REF && GET_CODE (operands[0]) != REG)
4047 operands[0] = force_reg (DImode, operands[0]);
4048 }")
4049
4050 ;;
4051 ;; call openvms/alpha
4052 ;; op 0: symbol ref for called function
4053 ;; op 1: next_arg_reg (argument information value for R25)
4054 ;;
4055 (define_expand "call_vms"
4056 [(parallel [(call (mem:DI (match_operand 0 "" ""))
4057 (match_operand 1 "" ""))
4058 (use (match_dup 2))
4059 (use (reg:DI 25))
4060 (use (reg:DI 26))
4061 (clobber (reg:DI 27))])]
4062 ""
4063 "
4064 { if (GET_CODE (operands[0]) != MEM)
4065 abort ();
4066
4067 operands[0] = XEXP (operands[0], 0);
4068
4069 /* Always load AI with argument information, then handle symbolic and
4070 indirect call differently. Load RA and set operands[2] to PV in
4071 both cases. */
4072
4073 emit_move_insn (gen_rtx_REG (DImode, 25), operands[1]);
4074 if (GET_CODE (operands[0]) == SYMBOL_REF)
4075 {
4076 rtx linkage = alpha_need_linkage (XSTR (operands[0], 0), 0);
4077
4078 emit_move_insn (gen_rtx_REG (Pmode, 26), gen_rtx_MEM (Pmode, linkage));
4079 operands[2]
4080 = validize_mem (gen_rtx_MEM (Pmode, plus_constant (linkage, 8)));
4081 }
4082 else
4083 {
4084 emit_move_insn (gen_rtx_REG (Pmode, 26),
4085 gen_rtx_MEM (Pmode, plus_constant (operands[0], 8)));
4086 operands[2] = operands[0];
4087 }
4088
4089 }")
4090
4091 (define_expand "call_value"
4092 [(use (match_operand 0 "" ""))
4093 (use (match_operand:DI 1 "" ""))
4094 (use (match_operand 2 "" ""))
4095 (use (match_operand 3 "" ""))
4096 (use (match_operand 4 "" ""))]
4097 ""
4098 "
4099 { if (TARGET_WINDOWS_NT)
4100 emit_call_insn (gen_call_value_nt (operands[0], operands[1], operands[2]));
4101 else if (TARGET_OPEN_VMS)
4102 emit_call_insn (gen_call_value_vms (operands[0], operands[1],
4103 operands[3]));
4104 else
4105 emit_call_insn (gen_call_value_osf (operands[0], operands[1],
4106 operands[2]));
4107 DONE;
4108 }")
4109
4110 (define_expand "sibcall_value"
4111 [(set (match_operand 0 "" "")
4112 (call (mem:DI (match_operand 1 "" ""))
4113 (match_operand 2 "" "")))]
4114 "!TARGET_OPEN_VMS && !TARGET_WINDOWS_NT"
4115 "
4116 {
4117 if (GET_CODE (operands[1]) != MEM)
4118 abort ();
4119 operands[1] = XEXP (operands[1], 0);
4120 }")
4121
4122 (define_expand "call_value_osf"
4123 [(parallel [(set (match_operand 0 "" "")
4124 (call (mem:DI (match_operand 1 "" ""))
4125 (match_operand 2 "" "")))
4126 (clobber (reg:DI 27))
4127 (clobber (reg:DI 26))])]
4128 ""
4129 "
4130 { if (GET_CODE (operands[1]) != MEM)
4131 abort ();
4132
4133 operands[1] = XEXP (operands[1], 0);
4134
4135 if (GET_CODE (operands[1]) != SYMBOL_REF
4136 && ! (GET_CODE (operands[1]) == REG && REGNO (operands[1]) == 27))
4137 {
4138 rtx tem = gen_rtx_REG (DImode, 27);
4139 emit_move_insn (tem, operands[1]);
4140 operands[1] = tem;
4141 }
4142 }")
4143
4144 (define_expand "call_value_nt"
4145 [(parallel [(set (match_operand 0 "" "")
4146 (call (mem:DI (match_operand 1 "" ""))
4147 (match_operand 2 "" "")))
4148 (clobber (reg:DI 26))])]
4149 ""
4150 "
4151 { if (GET_CODE (operands[1]) != MEM)
4152 abort ();
4153
4154 operands[1] = XEXP (operands[1], 0);
4155 if (GET_CODE (operands[1]) != SYMBOL_REF && GET_CODE (operands[1]) != REG)
4156 operands[1] = force_reg (DImode, operands[1]);
4157 }")
4158
4159 (define_expand "call_value_vms"
4160 [(parallel [(set (match_operand 0 "" "")
4161 (call (mem:DI (match_operand:DI 1 "" ""))
4162 (match_operand 2 "" "")))
4163 (use (match_dup 3))
4164 (use (reg:DI 25))
4165 (use (reg:DI 26))
4166 (clobber (reg:DI 27))])]
4167 ""
4168 "
4169 { if (GET_CODE (operands[1]) != MEM)
4170 abort ();
4171
4172 operands[1] = XEXP (operands[1], 0);
4173
4174 /* Always load AI with argument information, then handle symbolic and
4175 indirect call differently. Load RA and set operands[3] to PV in
4176 both cases. */
4177
4178 emit_move_insn (gen_rtx_REG (DImode, 25), operands[2]);
4179 if (GET_CODE (operands[1]) == SYMBOL_REF)
4180 {
4181 rtx linkage = alpha_need_linkage (XSTR (operands[1], 0), 0);
4182
4183 emit_move_insn (gen_rtx_REG (Pmode, 26), gen_rtx_MEM (Pmode, linkage));
4184 operands[3]
4185 = validize_mem (gen_rtx_MEM (Pmode, plus_constant (linkage, 8)));
4186 }
4187 else
4188 {
4189 emit_move_insn (gen_rtx_REG (Pmode, 26),
4190 gen_rtx_MEM (Pmode, plus_constant (operands[1], 8)));
4191 operands[3] = operands[1];
4192 }
4193 }")
4194
4195 (define_insn "*call_osf_1"
4196 [(call (mem:DI (match_operand:DI 0 "call_operand" "r,R,i"))
4197 (match_operand 1 "" ""))
4198 (clobber (reg:DI 27))
4199 (clobber (reg:DI 26))]
4200 "! TARGET_WINDOWS_NT && ! TARGET_OPEN_VMS"
4201 "@
4202 jsr $26,($27),0\;ldgp $29,0($26)
4203 bsr $26,$%0..ng
4204 jsr $26,%0\;ldgp $29,0($26)"
4205 [(set_attr "type" "jsr")
4206 (set_attr "length" "12,*,16")])
4207
4208 (define_insn "*sibcall_osf_1"
4209 [(call (mem:DI (match_operand:DI 0 "call_operand" "R,i"))
4210 (match_operand 1 "" ""))]
4211 "! TARGET_WINDOWS_NT && ! TARGET_OPEN_VMS"
4212 "@
4213 br $31,$%0..ng
4214 jmp $31,%0"
4215 [(set_attr "type" "jsr")
4216 (set_attr "length" "*,8")])
4217
4218 (define_insn "*call_nt_1"
4219 [(call (mem:DI (match_operand:DI 0 "call_operand" "r,R,i"))
4220 (match_operand 1 "" ""))
4221 (clobber (reg:DI 26))]
4222 "TARGET_WINDOWS_NT"
4223 "@
4224 jsr $26,(%0)
4225 bsr $26,%0
4226 jsr $26,%0"
4227 [(set_attr "type" "jsr")
4228 (set_attr "length" "*,*,12")])
4229
4230 (define_insn "*call_vms_1"
4231 [(call (mem:DI (match_operand:DI 0 "call_operand" "r,i"))
4232 (match_operand 1 "" ""))
4233 (use (match_operand:DI 2 "nonimmediate_operand" "r,m"))
4234 (use (reg:DI 25))
4235 (use (reg:DI 26))
4236 (clobber (reg:DI 27))]
4237 "TARGET_OPEN_VMS"
4238 "@
4239 mov %2,$27\;jsr $26,0\;ldq $27,0($29)
4240 ldq $27,%2\;jsr $26,%0\;ldq $27,0($29)"
4241 [(set_attr "type" "jsr")
4242 (set_attr "length" "12,16")])
4243
4244 ;; Call subroutine returning any type.
4245
4246 (define_expand "untyped_call"
4247 [(parallel [(call (match_operand 0 "" "")
4248 (const_int 0))
4249 (match_operand 1 "" "")
4250 (match_operand 2 "" "")])]
4251 ""
4252 "
4253 {
4254 int i;
4255
4256 emit_call_insn (GEN_CALL (operands[0], const0_rtx, NULL, const0_rtx));
4257
4258 for (i = 0; i < XVECLEN (operands[2], 0); i++)
4259 {
4260 rtx set = XVECEXP (operands[2], 0, i);
4261 emit_move_insn (SET_DEST (set), SET_SRC (set));
4262 }
4263
4264 /* The optimizer does not know that the call sets the function value
4265 registers we stored in the result block. We avoid problems by
4266 claiming that all hard registers are used and clobbered at this
4267 point. */
4268 emit_insn (gen_blockage ());
4269
4270 DONE;
4271 }")
4272
4273 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
4274 ;; all of memory. This blocks insns from being moved across this point.
4275
4276 (define_insn "blockage"
4277 [(unspec_volatile [(const_int 0)] 1)]
4278 ""
4279 ""
4280 [(set_attr "length" "0")])
4281
4282 (define_insn "jump"
4283 [(set (pc)
4284 (label_ref (match_operand 0 "" "")))]
4285 ""
4286 "br $31,%l0"
4287 [(set_attr "type" "ibr")])
4288
4289 (define_expand "return"
4290 [(return)]
4291 "direct_return ()"
4292 "")
4293
4294 (define_insn "*return_internal"
4295 [(return)]
4296 "reload_completed"
4297 "ret $31,($26),1"
4298 [(set_attr "type" "ibr")])
4299
4300 (define_insn "indirect_jump"
4301 [(set (pc) (match_operand:DI 0 "register_operand" "r"))]
4302 ""
4303 "jmp $31,(%0),0"
4304 [(set_attr "type" "ibr")])
4305
4306 (define_expand "tablejump"
4307 [(use (match_operand:SI 0 "register_operand" ""))
4308 (use (match_operand:SI 1 "" ""))]
4309 ""
4310 "
4311 {
4312 if (TARGET_WINDOWS_NT)
4313 emit_jump_insn (gen_tablejump_nt (operands[0], operands[1]));
4314 else if (TARGET_OPEN_VMS)
4315 emit_jump_insn (gen_tablejump_vms (operands[0], operands[1]));
4316 else
4317 emit_jump_insn (gen_tablejump_osf (operands[0], operands[1]));
4318
4319 DONE;
4320 }")
4321
4322 (define_expand "tablejump_osf"
4323 [(set (match_dup 3)
4324 (sign_extend:DI (match_operand:SI 0 "register_operand" "")))
4325 (parallel [(set (pc)
4326 (plus:DI (match_dup 3)
4327 (label_ref (match_operand 1 "" ""))))
4328 (clobber (match_scratch:DI 2 "=r"))])]
4329 ""
4330 "
4331 { operands[3] = gen_reg_rtx (DImode); }")
4332
4333 (define_expand "tablejump_nt"
4334 [(set (match_dup 3)
4335 (sign_extend:DI (match_operand:SI 0 "register_operand" "")))
4336 (parallel [(set (pc)
4337 (match_dup 3))
4338 (use (label_ref (match_operand 1 "" "")))])]
4339 ""
4340 "
4341 { operands[3] = gen_reg_rtx (DImode); }")
4342
4343 ;;
4344 ;; tablejump, openVMS way
4345 ;; op 0: offset
4346 ;; op 1: label preceding jump-table
4347 ;;
4348 (define_expand "tablejump_vms"
4349 [(set (match_dup 2)
4350 (match_operand:DI 0 "register_operand" ""))
4351 (set (pc)
4352 (plus:DI (match_dup 2)
4353 (label_ref (match_operand 1 "" ""))))]
4354 ""
4355 "
4356 { operands[2] = gen_reg_rtx (DImode); }")
4357
4358 (define_insn ""
4359 [(set (pc)
4360 (plus (match_operand:DI 0 "register_operand" "r")
4361 (label_ref (match_operand 1 "" ""))))
4362 (clobber (match_scratch:DI 2 "=r"))]
4363 "! TARGET_WINDOWS_NT && ! TARGET_OPEN_VMS && next_active_insn (insn) != 0
4364 && GET_CODE (PATTERN (next_active_insn (insn))) == ADDR_DIFF_VEC
4365 && PREV_INSN (next_active_insn (insn)) == operands[1]"
4366 "*
4367 { rtx best_label = 0;
4368 rtx jump_table_insn = next_active_insn (operands[1]);
4369
4370 if (GET_CODE (jump_table_insn) == JUMP_INSN
4371 && GET_CODE (PATTERN (jump_table_insn)) == ADDR_DIFF_VEC)
4372 {
4373 rtx jump_table = PATTERN (jump_table_insn);
4374 int n_labels = XVECLEN (jump_table, 1);
4375 int best_count = -1;
4376 int i, j;
4377
4378 for (i = 0; i < n_labels; i++)
4379 {
4380 int count = 1;
4381
4382 for (j = i + 1; j < n_labels; j++)
4383 if (XEXP (XVECEXP (jump_table, 1, i), 0)
4384 == XEXP (XVECEXP (jump_table, 1, j), 0))
4385 count++;
4386
4387 if (count > best_count)
4388 best_count = count, best_label = XVECEXP (jump_table, 1, i);
4389 }
4390 }
4391
4392 if (best_label)
4393 {
4394 operands[3] = best_label;
4395 return \"addq %0,$29,%2\;jmp $31,(%2),%3\";
4396 }
4397 else
4398 return \"addq %0,$29,%2\;jmp $31,(%2),0\";
4399 }"
4400 [(set_attr "type" "ibr")
4401 (set_attr "length" "8")])
4402
4403 (define_insn ""
4404 [(set (pc)
4405 (match_operand:DI 0 "register_operand" "r"))
4406 (use (label_ref (match_operand 1 "" "")))]
4407 "TARGET_WINDOWS_NT && next_active_insn (insn) != 0
4408 && GET_CODE (PATTERN (next_active_insn (insn))) == ADDR_DIFF_VEC
4409 && PREV_INSN (next_active_insn (insn)) == operands[1]"
4410 "*
4411 { rtx best_label = 0;
4412 rtx jump_table_insn = next_active_insn (operands[1]);
4413
4414 if (GET_CODE (jump_table_insn) == JUMP_INSN
4415 && GET_CODE (PATTERN (jump_table_insn)) == ADDR_DIFF_VEC)
4416 {
4417 rtx jump_table = PATTERN (jump_table_insn);
4418 int n_labels = XVECLEN (jump_table, 1);
4419 int best_count = -1;
4420 int i, j;
4421
4422 for (i = 0; i < n_labels; i++)
4423 {
4424 int count = 1;
4425
4426 for (j = i + 1; j < n_labels; j++)
4427 if (XEXP (XVECEXP (jump_table, 1, i), 0)
4428 == XEXP (XVECEXP (jump_table, 1, j), 0))
4429 count++;
4430
4431 if (count > best_count)
4432 best_count = count, best_label = XVECEXP (jump_table, 1, i);
4433 }
4434 }
4435
4436 if (best_label)
4437 {
4438 operands[2] = best_label;
4439 return \"jmp $31,(%0),%2\";
4440 }
4441 else
4442 return \"jmp $31,(%0),0\";
4443 }"
4444 [(set_attr "type" "ibr")])
4445
4446 ;;
4447 ;; op 0 is table offset
4448 ;; op 1 is table label
4449 ;;
4450
4451 (define_insn ""
4452 [(set (pc)
4453 (plus (match_operand:DI 0 "register_operand" "r")
4454 (label_ref (match_operand 1 "" ""))))]
4455 "TARGET_OPEN_VMS"
4456 "jmp $31,(%0),0"
4457 [(set_attr "type" "ibr")])
4458
4459 ;; Cache flush. Used by INITIALIZE_TRAMPOLINE. 0x86 is PAL_imb, but we don't
4460 ;; want to have to include pal.h in our .s file.
4461 ;;
4462 ;; Technically the type for call_pal is jsr, but we use that for determining
4463 ;; if we need a GP. Use ibr instead since it has the same EV5 scheduling
4464 ;; characteristics.
4465 (define_insn "imb"
4466 [(unspec_volatile [(const_int 0)] 0)]
4467 ""
4468 "call_pal 0x86"
4469 [(set_attr "type" "ibr")])
4470 \f
4471 ;; Finally, we have the basic data motion insns. The byte and word insns
4472 ;; are done via define_expand. Start with the floating-point insns, since
4473 ;; they are simpler.
4474
4475 (define_insn ""
4476 [(set (match_operand:SF 0 "nonimmediate_operand" "=f,f,*r,*r,m,m")
4477 (match_operand:SF 1 "input_operand" "fG,m,*rG,m,fG,*r"))]
4478 "TARGET_FPREGS && ! TARGET_FIX
4479 && (register_operand (operands[0], SFmode)
4480 || reg_or_fp0_operand (operands[1], SFmode))"
4481 "@
4482 fmov %R1,%0
4483 ld%, %0,%1
4484 mov %r1,%0
4485 ldl %0,%1
4486 st%, %R1,%0
4487 stl %r1,%0"
4488 [(set_attr "type" "fcpys,fld,ilog,ild,fst,ist")])
4489
4490 (define_insn ""
4491 [(set (match_operand:SF 0 "nonimmediate_operand" "=f,f,*r,*r,m,m,f,*r")
4492 (match_operand:SF 1 "input_operand" "fG,m,*rG,m,fG,*r,*r,f"))]
4493 "TARGET_FPREGS && TARGET_FIX
4494 && (register_operand (operands[0], SFmode)
4495 || reg_or_fp0_operand (operands[1], SFmode))"
4496 "@
4497 fmov %R1,%0
4498 ld%, %0,%1
4499 mov %r1,%0
4500 ldl %0,%1
4501 st%, %R1,%0
4502 stl %r1,%0
4503 itofs %1,%0
4504 ftois %1,%0"
4505 [(set_attr "type" "fcpys,fld,ilog,ild,fst,ist,itof,ftoi")])
4506
4507 (define_insn ""
4508 [(set (match_operand:SF 0 "nonimmediate_operand" "=r,r,m")
4509 (match_operand:SF 1 "input_operand" "rG,m,r"))]
4510 "! TARGET_FPREGS
4511 && (register_operand (operands[0], SFmode)
4512 || reg_or_fp0_operand (operands[1], SFmode))"
4513 "@
4514 mov %r1,%0
4515 ldl %0,%1
4516 stl %r1,%0"
4517 [(set_attr "type" "ilog,ild,ist")])
4518
4519 (define_insn ""
4520 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,f,*r,*r,m,m")
4521 (match_operand:DF 1 "input_operand" "fG,m,*rG,m,fG,*r"))]
4522 "TARGET_FPREGS && ! TARGET_FIX
4523 && (register_operand (operands[0], DFmode)
4524 || reg_or_fp0_operand (operands[1], DFmode))"
4525 "@
4526 fmov %R1,%0
4527 ld%- %0,%1
4528 mov %r1,%0
4529 ldq %0,%1
4530 st%- %R1,%0
4531 stq %r1,%0"
4532 [(set_attr "type" "fcpys,fld,ilog,ild,fst,ist")])
4533
4534 (define_insn ""
4535 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,f,*r,*r,m,m,f,*r")
4536 (match_operand:DF 1 "input_operand" "fG,m,*rG,m,fG,*r,*r,f"))]
4537 "TARGET_FPREGS && TARGET_FIX
4538 && (register_operand (operands[0], DFmode)
4539 || reg_or_fp0_operand (operands[1], DFmode))"
4540 "@
4541 fmov %R1,%0
4542 ld%- %0,%1
4543 mov %r1,%0
4544 ldq %0,%1
4545 st%- %R1,%0
4546 stq %r1,%0
4547 itoft %1,%0
4548 ftoit %1,%0"
4549 [(set_attr "type" "fcpys,fld,ilog,ild,fst,ist,itof,ftoi")])
4550
4551 (define_insn ""
4552 [(set (match_operand:DF 0 "nonimmediate_operand" "=r,r,m")
4553 (match_operand:DF 1 "input_operand" "rG,m,r"))]
4554 "! TARGET_FPREGS
4555 && (register_operand (operands[0], DFmode)
4556 || reg_or_fp0_operand (operands[1], DFmode))"
4557 "@
4558 mov %r1,%0
4559 ldq %0,%1
4560 stq %r1,%0"
4561 [(set_attr "type" "ilog,ild,ist")])
4562
4563 ;; Subregs suck for register allocation. Pretend we can move TFmode
4564 ;; data between general registers until after reload.
4565 (define_insn ""
4566 [(set (match_operand:TF 0 "nonimmediate_operand" "=r,o")
4567 (match_operand:TF 1 "input_operand" "roG,r"))]
4568 "register_operand (operands[0], TFmode)
4569 || reg_or_fp0_operand (operands[1], TFmode)"
4570 "#")
4571
4572 (define_split
4573 [(set (match_operand:TF 0 "nonimmediate_operand" "")
4574 (match_operand:TF 1 "input_operand" ""))]
4575 "reload_completed"
4576 [(set (match_dup 0) (match_dup 2))
4577 (set (match_dup 1) (match_dup 3))]
4578 "
4579 {
4580 alpha_split_tfmode_pair (operands);
4581 if (rtx_equal_p (operands[0], operands[3]))
4582 {
4583 rtx tmp;
4584 tmp = operands[0], operands[0] = operands[1], operands[1] = tmp;
4585 tmp = operands[2], operands[2] = operands[3], operands[3] = tmp;
4586 }
4587 }")
4588
4589 (define_expand "movsf"
4590 [(set (match_operand:SF 0 "nonimmediate_operand" "")
4591 (match_operand:SF 1 "general_operand" ""))]
4592 ""
4593 "
4594 {
4595 if (GET_CODE (operands[0]) == MEM
4596 && ! reg_or_fp0_operand (operands[1], SFmode))
4597 operands[1] = force_reg (SFmode, operands[1]);
4598 }")
4599
4600 (define_expand "movdf"
4601 [(set (match_operand:DF 0 "nonimmediate_operand" "")
4602 (match_operand:DF 1 "general_operand" ""))]
4603 ""
4604 "
4605 {
4606 if (GET_CODE (operands[0]) == MEM
4607 && ! reg_or_fp0_operand (operands[1], DFmode))
4608 operands[1] = force_reg (DFmode, operands[1]);
4609 }")
4610
4611 (define_expand "movtf"
4612 [(set (match_operand:TF 0 "nonimmediate_operand" "")
4613 (match_operand:TF 1 "general_operand" ""))]
4614 ""
4615 "
4616 {
4617 if (GET_CODE (operands[0]) == MEM
4618 && ! reg_or_fp0_operand (operands[1], TFmode))
4619 operands[1] = force_reg (TFmode, operands[1]);
4620 }")
4621
4622 (define_insn ""
4623 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,r,r,m,*f,*f,m")
4624 (match_operand:SI 1 "input_operand" "rJ,K,L,m,rJ,*fJ,m,*f"))]
4625 "! TARGET_WINDOWS_NT && ! TARGET_OPEN_VMS && ! TARGET_FIX
4626 && (register_operand (operands[0], SImode)
4627 || reg_or_0_operand (operands[1], SImode))"
4628 "@
4629 mov %r1,%0
4630 lda %0,%1
4631 ldah %0,%h1
4632 ldl %0,%1
4633 stl %r1,%0
4634 fmov %R1,%0
4635 ld%, %0,%1
4636 st%, %R1,%0"
4637 [(set_attr "type" "ilog,iadd,iadd,ild,ist,fcpys,fld,fst")])
4638
4639 (define_insn ""
4640 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,r,r,m,*f,*f,m,r,*f")
4641 (match_operand:SI 1 "input_operand" "rJ,K,L,m,rJ,*fJ,m,*f,*f,r"))]
4642 "! TARGET_WINDOWS_NT && ! TARGET_OPEN_VMS && TARGET_FIX
4643 && (register_operand (operands[0], SImode)
4644 || reg_or_0_operand (operands[1], SImode))"
4645 "@
4646 mov %r1,%0
4647 lda %0,%1
4648 ldah %0,%h1
4649 ldl %0,%1
4650 stl %r1,%0
4651 fmov %R1,%0
4652 ld%, %0,%1
4653 st%, %R1,%0
4654 ftois %1,%0
4655 itofs %1,%0"
4656 [(set_attr "type" "ilog,iadd,iadd,ild,ist,fcpys,fld,fst,ftoi,itof")])
4657
4658 (define_insn ""
4659 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,r,r,r,m,*f,*f,m")
4660 (match_operand:SI 1 "input_operand" "rJ,K,L,s,m,rJ,*fJ,m,*f"))]
4661 "(TARGET_WINDOWS_NT || TARGET_OPEN_VMS)
4662 && (register_operand (operands[0], SImode)
4663 || reg_or_0_operand (operands[1], SImode))"
4664 "@
4665 mov %1,%0
4666 lda %0,%1
4667 ldah %0,%h1
4668 lda %0,%1
4669 ldl %0,%1
4670 stl %r1,%0
4671 fmov %R1,%0
4672 ld%, %0,%1
4673 st%, %R1,%0"
4674 [(set_attr "type" "ilog,iadd,iadd,ldsym,ild,ist,fcpys,fld,fst")])
4675
4676 (define_insn ""
4677 [(set (match_operand:HI 0 "register_operand" "=r,r")
4678 (match_operand:HI 1 "input_operand" "rJ,n"))]
4679 "! TARGET_BWX
4680 && (register_operand (operands[0], HImode)
4681 || register_operand (operands[1], HImode))"
4682 "@
4683 mov %r1,%0
4684 lda %0,%L1"
4685 [(set_attr "type" "ilog,iadd")])
4686
4687 (define_insn ""
4688 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
4689 (match_operand:HI 1 "input_operand" "rJ,n,m,rJ"))]
4690 "TARGET_BWX
4691 && (register_operand (operands[0], HImode)
4692 || reg_or_0_operand (operands[1], HImode))"
4693 "@
4694 mov %r1,%0
4695 lda %0,%L1
4696 ldwu %0,%1
4697 stw %r1,%0"
4698 [(set_attr "type" "ilog,iadd,ild,ist")])
4699
4700 (define_insn ""
4701 [(set (match_operand:QI 0 "register_operand" "=r,r")
4702 (match_operand:QI 1 "input_operand" "rJ,n"))]
4703 "! TARGET_BWX
4704 && (register_operand (operands[0], QImode)
4705 || register_operand (operands[1], QImode))"
4706 "@
4707 mov %r1,%0
4708 lda %0,%L1"
4709 [(set_attr "type" "ilog,iadd")])
4710
4711 (define_insn ""
4712 [(set (match_operand:QI 0 "nonimmediate_operand" "=r,r,r,m")
4713 (match_operand:QI 1 "input_operand" "rJ,n,m,rJ"))]
4714 "TARGET_BWX
4715 && (register_operand (operands[0], QImode)
4716 || reg_or_0_operand (operands[1], QImode))"
4717 "@
4718 mov %r1,%0
4719 lda %0,%L1
4720 ldbu %0,%1
4721 stb %r1,%0"
4722 [(set_attr "type" "ilog,iadd,ild,ist")])
4723
4724 ;; We do two major things here: handle mem->mem and construct long
4725 ;; constants.
4726
4727 (define_expand "movsi"
4728 [(set (match_operand:SI 0 "nonimmediate_operand" "")
4729 (match_operand:SI 1 "general_operand" ""))]
4730 ""
4731 "
4732 {
4733 if (GET_CODE (operands[0]) == MEM
4734 && ! reg_or_0_operand (operands[1], SImode))
4735 operands[1] = force_reg (SImode, operands[1]);
4736
4737 if (! CONSTANT_P (operands[1]) || input_operand (operands[1], SImode))
4738 ;
4739 else if (GET_CODE (operands[1]) == CONST_INT)
4740 {
4741 operands[1]
4742 = alpha_emit_set_const (operands[0], SImode, INTVAL (operands[1]), 3);
4743 if (rtx_equal_p (operands[0], operands[1]))
4744 DONE;
4745 }
4746 }")
4747
4748 ;; Split a load of a large constant into the appropriate two-insn
4749 ;; sequence.
4750
4751 (define_split
4752 [(set (match_operand:SI 0 "register_operand" "")
4753 (match_operand:SI 1 "const_int_operand" ""))]
4754 "! add_operand (operands[1], SImode)"
4755 [(set (match_dup 0) (match_dup 2))
4756 (set (match_dup 0) (plus:SI (match_dup 0) (match_dup 3)))]
4757 "
4758 { rtx tem
4759 = alpha_emit_set_const (operands[0], SImode, INTVAL (operands[1]), 2);
4760
4761 if (tem == operands[0])
4762 DONE;
4763 else
4764 FAIL;
4765 }")
4766
4767 (define_insn ""
4768 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,r,r,r,m,*f,*f,Q")
4769 (match_operand:DI 1 "input_operand" "rJ,K,L,s,m,rJ,*fJ,Q,*f"))]
4770 "! TARGET_FIX
4771 && (register_operand (operands[0], DImode)
4772 || reg_or_0_operand (operands[1], DImode))"
4773 "@
4774 mov %r1,%0
4775 lda %0,%1
4776 ldah %0,%h1
4777 lda %0,%1
4778 ldq%A1 %0,%1
4779 stq%A0 %r1,%0
4780 fmov %R1,%0
4781 ldt %0,%1
4782 stt %R1,%0"
4783 [(set_attr "type" "ilog,iadd,iadd,ldsym,ild,ist,fcpys,fld,fst")])
4784
4785 (define_insn ""
4786 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,r,r,r,m,*f,*f,Q,r,*f")
4787 (match_operand:DI 1 "input_operand" "rJ,K,L,s,m,rJ,*fJ,Q,*f,*f,r"))]
4788 "TARGET_FIX
4789 && (register_operand (operands[0], DImode)
4790 || reg_or_0_operand (operands[1], DImode))"
4791 "@
4792 mov %r1,%0
4793 lda %0,%1
4794 ldah %0,%h1
4795 lda %0,%1
4796 ldq%A1 %0,%1
4797 stq%A0 %r1,%0
4798 fmov %R1,%0
4799 ldt %0,%1
4800 stt %R1,%0
4801 ftoit %1,%0
4802 itoft %1,%0"
4803 [(set_attr "type" "ilog,iadd,iadd,ldsym,ild,ist,fcpys,fld,fst,ftoi,itof")])
4804
4805 ;; We do three major things here: handle mem->mem, put 64-bit constants in
4806 ;; memory, and construct long 32-bit constants.
4807
4808 (define_expand "movdi"
4809 [(set (match_operand:DI 0 "nonimmediate_operand" "")
4810 (match_operand:DI 1 "general_operand" ""))]
4811 ""
4812 "
4813 {
4814 rtx tem;
4815
4816 if (GET_CODE (operands[0]) == MEM
4817 && ! reg_or_0_operand (operands[1], DImode))
4818 operands[1] = force_reg (DImode, operands[1]);
4819
4820 if (! CONSTANT_P (operands[1]) || input_operand (operands[1], DImode))
4821 ;
4822 else if (GET_CODE (operands[1]) == CONST_INT
4823 && (tem = alpha_emit_set_const (operands[0], DImode,
4824 INTVAL (operands[1]), 3)) != 0)
4825 {
4826 if (rtx_equal_p (tem, operands[0]))
4827 DONE;
4828 else
4829 operands[1] = tem;
4830 }
4831 else if (CONSTANT_P (operands[1]))
4832 {
4833 if (TARGET_BUILD_CONSTANTS)
4834 {
4835 HOST_WIDE_INT i0, i1;
4836
4837 if (GET_CODE (operands[1]) == CONST_INT)
4838 {
4839 i0 = INTVAL (operands[1]);
4840 i1 = -(i0 < 0);
4841 }
4842 else if (GET_CODE (operands[1]) == CONST_DOUBLE)
4843 {
4844 #if HOST_BITS_PER_WIDE_INT >= 64
4845 i0 = CONST_DOUBLE_LOW (operands[1]);
4846 i1 = -(i0 < 0);
4847 #else
4848 i0 = CONST_DOUBLE_LOW (operands[1]);
4849 i1 = CONST_DOUBLE_HIGH (operands[1]);
4850 #endif
4851 }
4852 else
4853 abort();
4854
4855 tem = alpha_emit_set_long_const (operands[0], i0, i1);
4856 if (rtx_equal_p (tem, operands[0]))
4857 DONE;
4858 else
4859 operands[1] = tem;
4860 }
4861 else
4862 {
4863 operands[1] = force_const_mem (DImode, operands[1]);
4864 if (reload_in_progress)
4865 {
4866 emit_move_insn (operands[0], XEXP (operands[1], 0));
4867 operands[1] = copy_rtx (operands[1]);
4868 XEXP (operands[1], 0) = operands[0];
4869 }
4870 else
4871 operands[1] = validize_mem (operands[1]);
4872 }
4873 }
4874 else
4875 abort ();
4876 }")
4877
4878 ;; Split a load of a large constant into the appropriate two-insn
4879 ;; sequence.
4880
4881 (define_split
4882 [(set (match_operand:DI 0 "register_operand" "")
4883 (match_operand:DI 1 "const_int_operand" ""))]
4884 "! add_operand (operands[1], DImode)"
4885 [(set (match_dup 0) (match_dup 2))
4886 (set (match_dup 0) (plus:DI (match_dup 0) (match_dup 3)))]
4887 "
4888 { rtx tem
4889 = alpha_emit_set_const (operands[0], DImode, INTVAL (operands[1]), 2);
4890
4891 if (tem == operands[0])
4892 DONE;
4893 else
4894 FAIL;
4895 }")
4896
4897 ;; These are the partial-word cases.
4898 ;;
4899 ;; First we have the code to load an aligned word. Operand 0 is the register
4900 ;; in which to place the result. It's mode is QImode or HImode. Operand 1
4901 ;; is an SImode MEM at the low-order byte of the proper word. Operand 2 is the
4902 ;; number of bits within the word that the value is. Operand 3 is an SImode
4903 ;; scratch register. If operand 0 is a hard register, operand 3 may be the
4904 ;; same register. It is allowed to conflict with operand 1 as well.
4905
4906 (define_expand "aligned_loadqi"
4907 [(set (match_operand:SI 3 "register_operand" "")
4908 (match_operand:SI 1 "memory_operand" ""))
4909 (set (subreg:DI (match_operand:QI 0 "register_operand" "") 0)
4910 (zero_extract:DI (subreg:DI (match_dup 3) 0)
4911 (const_int 8)
4912 (match_operand:DI 2 "const_int_operand" "")))]
4913
4914 ""
4915 "")
4916
4917 (define_expand "aligned_loadhi"
4918 [(set (match_operand:SI 3 "register_operand" "")
4919 (match_operand:SI 1 "memory_operand" ""))
4920 (set (subreg:DI (match_operand:HI 0 "register_operand" "") 0)
4921 (zero_extract:DI (subreg:DI (match_dup 3) 0)
4922 (const_int 16)
4923 (match_operand:DI 2 "const_int_operand" "")))]
4924
4925 ""
4926 "")
4927
4928 ;; Similar for unaligned loads, where we use the sequence from the
4929 ;; Alpha Architecture manual.
4930 ;;
4931 ;; Operand 1 is the address. Operands 2 and 3 are temporaries, where
4932 ;; operand 3 can overlap the input and output registers.
4933
4934 (define_expand "unaligned_loadqi"
4935 [(set (match_operand:DI 2 "register_operand" "")
4936 (mem:DI (and:DI (match_operand:DI 1 "address_operand" "")
4937 (const_int -8))))
4938 (set (match_operand:DI 3 "register_operand" "")
4939 (match_dup 1))
4940 (set (subreg:DI (match_operand:QI 0 "register_operand" "") 0)
4941 (zero_extract:DI (match_dup 2)
4942 (const_int 8)
4943 (ashift:DI (match_dup 3) (const_int 3))))]
4944 ""
4945 "")
4946
4947 (define_expand "unaligned_loadhi"
4948 [(set (match_operand:DI 2 "register_operand" "")
4949 (mem:DI (and:DI (match_operand:DI 1 "address_operand" "")
4950 (const_int -8))))
4951 (set (match_operand:DI 3 "register_operand" "")
4952 (match_dup 1))
4953 (set (subreg:DI (match_operand:QI 0 "register_operand" "") 0)
4954 (zero_extract:DI (match_dup 2)
4955 (const_int 16)
4956 (ashift:DI (match_dup 3) (const_int 3))))]
4957 ""
4958 "")
4959
4960 ;; Storing an aligned byte or word requires two temporaries. Operand 0 is the
4961 ;; aligned SImode MEM. Operand 1 is the register containing the
4962 ;; byte or word to store. Operand 2 is the number of bits within the word that
4963 ;; the value should be placed. Operands 3 and 4 are SImode temporaries.
4964
4965 (define_expand "aligned_store"
4966 [(set (match_operand:SI 3 "register_operand" "")
4967 (match_operand:SI 0 "memory_operand" ""))
4968 (set (subreg:DI (match_dup 3) 0)
4969 (and:DI (subreg:DI (match_dup 3) 0) (match_dup 5)))
4970 (set (subreg:DI (match_operand:SI 4 "register_operand" "") 0)
4971 (ashift:DI (zero_extend:DI (match_operand 1 "register_operand" ""))
4972 (match_operand:DI 2 "const_int_operand" "")))
4973 (set (subreg:DI (match_dup 4) 0)
4974 (ior:DI (subreg:DI (match_dup 4) 0) (subreg:DI (match_dup 3) 0)))
4975 (set (match_dup 0) (match_dup 4))]
4976 ""
4977 "
4978 { operands[5] = GEN_INT (~ (GET_MODE_MASK (GET_MODE (operands[1]))
4979 << INTVAL (operands[2])));
4980 }")
4981
4982 ;; For the unaligned byte and halfword cases, we use code similar to that
4983 ;; in the ;; Architecture book, but reordered to lower the number of registers
4984 ;; required. Operand 0 is the address. Operand 1 is the data to store.
4985 ;; Operands 2, 3, and 4 are DImode temporaries, where operands 2 and 4 may
4986 ;; be the same temporary, if desired. If the address is in a register,
4987 ;; operand 2 can be that register.
4988
4989 (define_expand "unaligned_storeqi"
4990 [(set (match_operand:DI 3 "register_operand" "")
4991 (mem:DI (and:DI (match_operand:DI 0 "address_operand" "")
4992 (const_int -8))))
4993 (set (match_operand:DI 2 "register_operand" "")
4994 (match_dup 0))
4995 (set (match_dup 3)
4996 (and:DI (not:DI (ashift:DI (const_int 255)
4997 (ashift:DI (match_dup 2) (const_int 3))))
4998 (match_dup 3)))
4999 (set (match_operand:DI 4 "register_operand" "")
5000 (ashift:DI (zero_extend:DI (match_operand:QI 1 "register_operand" ""))
5001 (ashift:DI (match_dup 2) (const_int 3))))
5002 (set (match_dup 4) (ior:DI (match_dup 4) (match_dup 3)))
5003 (set (mem:DI (and:DI (match_dup 0) (const_int -8)))
5004 (match_dup 4))]
5005 ""
5006 "")
5007
5008 (define_expand "unaligned_storehi"
5009 [(set (match_operand:DI 3 "register_operand" "")
5010 (mem:DI (and:DI (match_operand:DI 0 "address_operand" "")
5011 (const_int -8))))
5012 (set (match_operand:DI 2 "register_operand" "")
5013 (match_dup 0))
5014 (set (match_dup 3)
5015 (and:DI (not:DI (ashift:DI (const_int 65535)
5016 (ashift:DI (match_dup 2) (const_int 3))))
5017 (match_dup 3)))
5018 (set (match_operand:DI 4 "register_operand" "")
5019 (ashift:DI (zero_extend:DI (match_operand:HI 1 "register_operand" ""))
5020 (ashift:DI (match_dup 2) (const_int 3))))
5021 (set (match_dup 4) (ior:DI (match_dup 4) (match_dup 3)))
5022 (set (mem:DI (and:DI (match_dup 0) (const_int -8)))
5023 (match_dup 4))]
5024 ""
5025 "")
5026 \f
5027 ;; Here are the define_expand's for QI and HI moves that use the above
5028 ;; patterns. We have the normal sets, plus the ones that need scratch
5029 ;; registers for reload.
5030
5031 (define_expand "movqi"
5032 [(set (match_operand:QI 0 "nonimmediate_operand" "")
5033 (match_operand:QI 1 "general_operand" ""))]
5034 ""
5035 "
5036 {
5037 if (TARGET_BWX)
5038 {
5039 if (GET_CODE (operands[0]) == MEM
5040 && ! reg_or_0_operand (operands[1], QImode))
5041 operands[1] = force_reg (QImode, operands[1]);
5042
5043 if (GET_CODE (operands[1]) == CONST_INT
5044 && ! input_operand (operands[1], QImode))
5045 {
5046 operands[1] = alpha_emit_set_const (operands[0], QImode,
5047 INTVAL (operands[1]), 3);
5048
5049 if (rtx_equal_p (operands[0], operands[1]))
5050 DONE;
5051 }
5052
5053 goto def;
5054 }
5055
5056 /* If the output is not a register, the input must be. */
5057 if (GET_CODE (operands[0]) == MEM)
5058 operands[1] = force_reg (QImode, operands[1]);
5059
5060 /* Handle four memory cases, unaligned and aligned for either the input
5061 or the output. The only case where we can be called during reload is
5062 for aligned loads; all other cases require temporaries. */
5063
5064 if (GET_CODE (operands[1]) == MEM
5065 || (GET_CODE (operands[1]) == SUBREG
5066 && GET_CODE (SUBREG_REG (operands[1])) == MEM)
5067 || (reload_in_progress && GET_CODE (operands[1]) == REG
5068 && REGNO (operands[1]) >= FIRST_PSEUDO_REGISTER)
5069 || (reload_in_progress && GET_CODE (operands[1]) == SUBREG
5070 && GET_CODE (SUBREG_REG (operands[1])) == REG
5071 && REGNO (SUBREG_REG (operands[1])) >= FIRST_PSEUDO_REGISTER))
5072 {
5073 if (aligned_memory_operand (operands[1], QImode))
5074 {
5075 if (reload_in_progress)
5076 {
5077 emit_insn (gen_reload_inqi_help
5078 (operands[0], operands[1],
5079 gen_rtx_REG (SImode, REGNO (operands[0]))));
5080 }
5081 else
5082 {
5083 rtx aligned_mem, bitnum;
5084 rtx scratch = gen_reg_rtx (SImode);
5085
5086 get_aligned_mem (operands[1], &aligned_mem, &bitnum);
5087
5088 emit_insn (gen_aligned_loadqi (operands[0], aligned_mem, bitnum,
5089 scratch));
5090 }
5091 }
5092 else
5093 {
5094 /* Don't pass these as parameters since that makes the generated
5095 code depend on parameter evaluation order which will cause
5096 bootstrap failures. */
5097
5098 rtx temp1 = gen_reg_rtx (DImode);
5099 rtx temp2 = gen_reg_rtx (DImode);
5100 rtx seq
5101 = gen_unaligned_loadqi (operands[0],
5102 get_unaligned_address (operands[1], 0),
5103 temp1, temp2);
5104
5105 alpha_set_memflags (seq, operands[1]);
5106 emit_insn (seq);
5107 }
5108
5109 DONE;
5110 }
5111
5112 else if (GET_CODE (operands[0]) == MEM
5113 || (GET_CODE (operands[0]) == SUBREG
5114 && GET_CODE (SUBREG_REG (operands[0])) == MEM)
5115 || (reload_in_progress && GET_CODE (operands[0]) == REG
5116 && REGNO (operands[0]) >= FIRST_PSEUDO_REGISTER)
5117 || (reload_in_progress && GET_CODE (operands[0]) == SUBREG
5118 && GET_CODE (SUBREG_REG (operands[0])) == REG
5119 && REGNO (operands[0]) >= FIRST_PSEUDO_REGISTER))
5120 {
5121 if (aligned_memory_operand (operands[0], QImode))
5122 {
5123 rtx aligned_mem, bitnum;
5124 rtx temp1 = gen_reg_rtx (SImode);
5125 rtx temp2 = gen_reg_rtx (SImode);
5126
5127 get_aligned_mem (operands[0], &aligned_mem, &bitnum);
5128
5129 emit_insn (gen_aligned_store (aligned_mem, operands[1], bitnum,
5130 temp1, temp2));
5131 }
5132 else
5133 {
5134 rtx temp1 = gen_reg_rtx (DImode);
5135 rtx temp2 = gen_reg_rtx (DImode);
5136 rtx temp3 = gen_reg_rtx (DImode);
5137 rtx seq
5138 = gen_unaligned_storeqi (get_unaligned_address (operands[0], 0),
5139 operands[1], temp1, temp2, temp3);
5140
5141 alpha_set_memflags (seq, operands[0]);
5142 emit_insn (seq);
5143 }
5144 DONE;
5145 }
5146 def:;
5147 }")
5148
5149 (define_expand "movhi"
5150 [(set (match_operand:HI 0 "nonimmediate_operand" "")
5151 (match_operand:HI 1 "general_operand" ""))]
5152 ""
5153 "
5154 {
5155 if (TARGET_BWX)
5156 {
5157 if (GET_CODE (operands[0]) == MEM
5158 && ! reg_or_0_operand (operands[1], HImode))
5159 operands[1] = force_reg (HImode, operands[1]);
5160
5161 if (GET_CODE (operands[1]) == CONST_INT
5162 && ! input_operand (operands[1], HImode))
5163 {
5164 operands[1] = alpha_emit_set_const (operands[0], HImode,
5165 INTVAL (operands[1]), 3);
5166
5167 if (rtx_equal_p (operands[0], operands[1]))
5168 DONE;
5169 }
5170
5171 goto def;
5172 }
5173
5174 /* If the output is not a register, the input must be. */
5175 if (GET_CODE (operands[0]) == MEM)
5176 operands[1] = force_reg (HImode, operands[1]);
5177
5178 /* Handle four memory cases, unaligned and aligned for either the input
5179 or the output. The only case where we can be called during reload is
5180 for aligned loads; all other cases require temporaries. */
5181
5182 if (GET_CODE (operands[1]) == MEM
5183 || (GET_CODE (operands[1]) == SUBREG
5184 && GET_CODE (SUBREG_REG (operands[1])) == MEM)
5185 || (reload_in_progress && GET_CODE (operands[1]) == REG
5186 && REGNO (operands[1]) >= FIRST_PSEUDO_REGISTER)
5187 || (reload_in_progress && GET_CODE (operands[1]) == SUBREG
5188 && GET_CODE (SUBREG_REG (operands[1])) == REG
5189 && REGNO (SUBREG_REG (operands[1])) >= FIRST_PSEUDO_REGISTER))
5190 {
5191 if (aligned_memory_operand (operands[1], HImode))
5192 {
5193 if (reload_in_progress)
5194 {
5195 emit_insn (gen_reload_inhi_help
5196 (operands[0], operands[1],
5197 gen_rtx_REG (SImode, REGNO (operands[0]))));
5198 }
5199 else
5200 {
5201 rtx aligned_mem, bitnum;
5202 rtx scratch = gen_reg_rtx (SImode);
5203
5204 get_aligned_mem (operands[1], &aligned_mem, &bitnum);
5205
5206 emit_insn (gen_aligned_loadhi (operands[0], aligned_mem, bitnum,
5207 scratch));
5208 }
5209 }
5210 else
5211 {
5212 /* Don't pass these as parameters since that makes the generated
5213 code depend on parameter evaluation order which will cause
5214 bootstrap failures. */
5215
5216 rtx temp1 = gen_reg_rtx (DImode);
5217 rtx temp2 = gen_reg_rtx (DImode);
5218 rtx seq
5219 = gen_unaligned_loadhi (operands[0],
5220 get_unaligned_address (operands[1], 0),
5221 temp1, temp2);
5222
5223 alpha_set_memflags (seq, operands[1]);
5224 emit_insn (seq);
5225 }
5226
5227 DONE;
5228 }
5229
5230 else if (GET_CODE (operands[0]) == MEM
5231 || (GET_CODE (operands[0]) == SUBREG
5232 && GET_CODE (SUBREG_REG (operands[0])) == MEM)
5233 || (reload_in_progress && GET_CODE (operands[0]) == REG
5234 && REGNO (operands[0]) >= FIRST_PSEUDO_REGISTER)
5235 || (reload_in_progress && GET_CODE (operands[0]) == SUBREG
5236 && GET_CODE (SUBREG_REG (operands[0])) == REG
5237 && REGNO (operands[0]) >= FIRST_PSEUDO_REGISTER))
5238 {
5239 if (aligned_memory_operand (operands[0], HImode))
5240 {
5241 rtx aligned_mem, bitnum;
5242 rtx temp1 = gen_reg_rtx (SImode);
5243 rtx temp2 = gen_reg_rtx (SImode);
5244
5245 get_aligned_mem (operands[0], &aligned_mem, &bitnum);
5246
5247 emit_insn (gen_aligned_store (aligned_mem, operands[1], bitnum,
5248 temp1, temp2));
5249 }
5250 else
5251 {
5252 rtx temp1 = gen_reg_rtx (DImode);
5253 rtx temp2 = gen_reg_rtx (DImode);
5254 rtx temp3 = gen_reg_rtx (DImode);
5255 rtx seq
5256 = gen_unaligned_storehi (get_unaligned_address (operands[0], 0),
5257 operands[1], temp1, temp2, temp3);
5258
5259 alpha_set_memflags (seq, operands[0]);
5260 emit_insn (seq);
5261 }
5262
5263 DONE;
5264 }
5265 def:;
5266 }")
5267
5268 ;; Here are the versions for reload. Note that in the unaligned cases
5269 ;; we know that the operand must not be a pseudo-register because stack
5270 ;; slots are always aligned references.
5271
5272 (define_expand "reload_inqi"
5273 [(parallel [(match_operand:QI 0 "register_operand" "=r")
5274 (match_operand:QI 1 "any_memory_operand" "m")
5275 (match_operand:TI 2 "register_operand" "=&r")])]
5276 "! TARGET_BWX"
5277 "
5278 {
5279 rtx scratch, seq;
5280
5281 if (GET_CODE (operands[1]) != MEM)
5282 abort ();
5283
5284 if (aligned_memory_operand (operands[1], QImode))
5285 {
5286 seq = gen_reload_inqi_help (operands[0], operands[1],
5287 gen_rtx_REG (SImode, REGNO (operands[2])));
5288 }
5289 else
5290 {
5291 rtx addr;
5292
5293 /* It is possible that one of the registers we got for operands[2]
5294 might coincide with that of operands[0] (which is why we made
5295 it TImode). Pick the other one to use as our scratch. */
5296 if (REGNO (operands[0]) == REGNO (operands[2]))
5297 scratch = gen_rtx_REG (DImode, REGNO (operands[2]) + 1);
5298 else
5299 scratch = gen_rtx_REG (DImode, REGNO (operands[2]));
5300
5301 addr = get_unaligned_address (operands[1], 0);
5302 seq = gen_unaligned_loadqi (operands[0], addr, scratch,
5303 gen_rtx_REG (DImode, REGNO (operands[0])));
5304 alpha_set_memflags (seq, operands[1]);
5305 }
5306 emit_insn (seq);
5307 DONE;
5308 }")
5309
5310 (define_expand "reload_inhi"
5311 [(parallel [(match_operand:HI 0 "register_operand" "=r")
5312 (match_operand:HI 1 "any_memory_operand" "m")
5313 (match_operand:TI 2 "register_operand" "=&r")])]
5314 "! TARGET_BWX"
5315 "
5316 {
5317 rtx scratch, seq;
5318
5319 if (GET_CODE (operands[1]) != MEM)
5320 abort ();
5321
5322 if (aligned_memory_operand (operands[1], HImode))
5323 {
5324 seq = gen_reload_inhi_help (operands[0], operands[1],
5325 gen_rtx_REG (SImode, REGNO (operands[2])));
5326 }
5327 else
5328 {
5329 rtx addr;
5330
5331 /* It is possible that one of the registers we got for operands[2]
5332 might coincide with that of operands[0] (which is why we made
5333 it TImode). Pick the other one to use as our scratch. */
5334 if (REGNO (operands[0]) == REGNO (operands[2]))
5335 scratch = gen_rtx_REG (DImode, REGNO (operands[2]) + 1);
5336 else
5337 scratch = gen_rtx_REG (DImode, REGNO (operands[2]));
5338
5339 addr = get_unaligned_address (operands[1], 0);
5340 seq = gen_unaligned_loadhi (operands[0], addr, scratch,
5341 gen_rtx_REG (DImode, REGNO (operands[0])));
5342 alpha_set_memflags (seq, operands[1]);
5343 }
5344 emit_insn (seq);
5345 DONE;
5346 }")
5347
5348 (define_expand "reload_outqi"
5349 [(parallel [(match_operand:QI 0 "any_memory_operand" "=m")
5350 (match_operand:QI 1 "register_operand" "r")
5351 (match_operand:TI 2 "register_operand" "=&r")])]
5352 "! TARGET_BWX"
5353 "
5354 {
5355 if (GET_CODE (operands[0]) != MEM)
5356 abort ();
5357
5358 if (aligned_memory_operand (operands[0], QImode))
5359 {
5360 emit_insn (gen_reload_outqi_help
5361 (operands[0], operands[1],
5362 gen_rtx_REG (SImode, REGNO (operands[2])),
5363 gen_rtx_REG (SImode, REGNO (operands[2]) + 1)));
5364 }
5365 else
5366 {
5367 rtx addr = get_unaligned_address (operands[0], 0);
5368 rtx scratch1 = gen_rtx_REG (DImode, REGNO (operands[2]));
5369 rtx scratch2 = gen_rtx_REG (DImode, REGNO (operands[2]) + 1);
5370 rtx scratch3 = scratch1;
5371 rtx seq;
5372
5373 if (GET_CODE (addr) == REG)
5374 scratch1 = addr;
5375
5376 seq = gen_unaligned_storeqi (addr, operands[1], scratch1,
5377 scratch2, scratch3);
5378 alpha_set_memflags (seq, operands[0]);
5379 emit_insn (seq);
5380 }
5381 DONE;
5382 }")
5383
5384 (define_expand "reload_outhi"
5385 [(parallel [(match_operand:HI 0 "any_memory_operand" "=m")
5386 (match_operand:HI 1 "register_operand" "r")
5387 (match_operand:TI 2 "register_operand" "=&r")])]
5388 "! TARGET_BWX"
5389 "
5390 {
5391 if (GET_CODE (operands[0]) != MEM)
5392 abort ();
5393
5394 if (aligned_memory_operand (operands[0], HImode))
5395 {
5396 emit_insn (gen_reload_outhi_help
5397 (operands[0], operands[1],
5398 gen_rtx_REG (SImode, REGNO (operands[2])),
5399 gen_rtx_REG (SImode, REGNO (operands[2]) + 1)));
5400 }
5401 else
5402 {
5403 rtx addr = get_unaligned_address (operands[0], 0);
5404 rtx scratch1 = gen_rtx_REG (DImode, REGNO (operands[2]));
5405 rtx scratch2 = gen_rtx_REG (DImode, REGNO (operands[2]) + 1);
5406 rtx scratch3 = scratch1;
5407 rtx seq;
5408
5409 if (GET_CODE (addr) == REG)
5410 scratch1 = addr;
5411
5412 seq = gen_unaligned_storehi (addr, operands[1], scratch1,
5413 scratch2, scratch3);
5414 alpha_set_memflags (seq, operands[0]);
5415 emit_insn (seq);
5416 }
5417 DONE;
5418 }")
5419
5420 ;; Helpers for the above. The way reload is structured, we can't
5421 ;; always get a proper address for a stack slot during reload_foo
5422 ;; expansion, so we must delay our address manipulations until after.
5423
5424 (define_insn "reload_inqi_help"
5425 [(set (match_operand:QI 0 "register_operand" "=r")
5426 (match_operand:QI 1 "memory_operand" "m"))
5427 (clobber (match_operand:SI 2 "register_operand" "=r"))]
5428 "! TARGET_BWX && (reload_in_progress || reload_completed)"
5429 "#")
5430
5431 (define_insn "reload_inhi_help"
5432 [(set (match_operand:HI 0 "register_operand" "=r")
5433 (match_operand:HI 1 "memory_operand" "m"))
5434 (clobber (match_operand:SI 2 "register_operand" "=r"))]
5435 "! TARGET_BWX && (reload_in_progress || reload_completed)"
5436 "#")
5437
5438 (define_insn "reload_outqi_help"
5439 [(set (match_operand:QI 0 "memory_operand" "=m")
5440 (match_operand:QI 1 "register_operand" "r"))
5441 (clobber (match_operand:SI 2 "register_operand" "=r"))
5442 (clobber (match_operand:SI 3 "register_operand" "=r"))]
5443 "! TARGET_BWX && (reload_in_progress || reload_completed)"
5444 "#")
5445
5446 (define_insn "reload_outhi_help"
5447 [(set (match_operand:HI 0 "memory_operand" "=m")
5448 (match_operand:HI 1 "register_operand" "r"))
5449 (clobber (match_operand:SI 2 "register_operand" "=r"))
5450 (clobber (match_operand:SI 3 "register_operand" "=r"))]
5451 "! TARGET_BWX && (reload_in_progress || reload_completed)"
5452 "#")
5453
5454 (define_split
5455 [(set (match_operand:QI 0 "register_operand" "")
5456 (match_operand:QI 1 "memory_operand" ""))
5457 (clobber (match_operand:SI 2 "register_operand" ""))]
5458 "! TARGET_BWX && reload_completed"
5459 [(const_int 0)]
5460 "
5461 {
5462 rtx aligned_mem, bitnum;
5463 get_aligned_mem (operands[1], &aligned_mem, &bitnum);
5464 emit_insn (gen_aligned_loadqi (operands[0], aligned_mem, bitnum,
5465 operands[2]));
5466 DONE;
5467 }")
5468
5469 (define_split
5470 [(set (match_operand:HI 0 "register_operand" "")
5471 (match_operand:HI 1 "memory_operand" ""))
5472 (clobber (match_operand:SI 2 "register_operand" ""))]
5473 "! TARGET_BWX && reload_completed"
5474 [(const_int 0)]
5475 "
5476 {
5477 rtx aligned_mem, bitnum;
5478 get_aligned_mem (operands[1], &aligned_mem, &bitnum);
5479 emit_insn (gen_aligned_loadhi (operands[0], aligned_mem, bitnum,
5480 operands[2]));
5481 DONE;
5482 }")
5483
5484 (define_split
5485 [(set (match_operand:QI 0 "memory_operand" "")
5486 (match_operand:QI 1 "register_operand" ""))
5487 (clobber (match_operand:SI 2 "register_operand" ""))
5488 (clobber (match_operand:SI 3 "register_operand" ""))]
5489 "! TARGET_BWX && reload_completed"
5490 [(const_int 0)]
5491 "
5492 {
5493 rtx aligned_mem, bitnum;
5494 get_aligned_mem (operands[0], &aligned_mem, &bitnum);
5495 emit_insn (gen_aligned_store (aligned_mem, operands[1], bitnum,
5496 operands[2], operands[3]));
5497 DONE;
5498 }")
5499
5500 (define_split
5501 [(set (match_operand:HI 0 "memory_operand" "")
5502 (match_operand:HI 1 "register_operand" ""))
5503 (clobber (match_operand:SI 2 "register_operand" ""))
5504 (clobber (match_operand:SI 3 "register_operand" ""))]
5505 "! TARGET_BWX && reload_completed"
5506 [(const_int 0)]
5507 "
5508 {
5509 rtx aligned_mem, bitnum;
5510 get_aligned_mem (operands[0], &aligned_mem, &bitnum);
5511 emit_insn (gen_aligned_store (aligned_mem, operands[1], bitnum,
5512 operands[2], operands[3]));
5513 DONE;
5514 }")
5515 \f
5516 ;; Bit field extract patterns which use ext[wlq][lh]
5517
5518 (define_expand "extv"
5519 [(set (match_operand:DI 0 "register_operand" "")
5520 (sign_extract:DI (match_operand:QI 1 "memory_operand" "")
5521 (match_operand:DI 2 "immediate_operand" "")
5522 (match_operand:DI 3 "immediate_operand" "")))]
5523 ""
5524 "
5525 {
5526 /* We can do 16, 32 and 64 bit fields, if aligned on byte boundaries. */
5527 if (INTVAL (operands[3]) % 8 != 0
5528 || (INTVAL (operands[2]) != 16
5529 && INTVAL (operands[2]) != 32
5530 && INTVAL (operands[2]) != 64))
5531 FAIL;
5532
5533 /* From mips.md: extract_bit_field doesn't verify that our source
5534 matches the predicate, so we force it to be a MEM here. */
5535 if (GET_CODE (operands[1]) != MEM)
5536 FAIL;
5537
5538 alpha_expand_unaligned_load (operands[0], operands[1],
5539 INTVAL (operands[2]) / 8,
5540 INTVAL (operands[3]) / 8, 1);
5541 DONE;
5542 }")
5543
5544 (define_expand "extzv"
5545 [(set (match_operand:DI 0 "register_operand" "")
5546 (zero_extract:DI (match_operand:DI 1 "nonimmediate_operand" "")
5547 (match_operand:DI 2 "immediate_operand" "")
5548 (match_operand:DI 3 "immediate_operand" "")))]
5549 ""
5550 "
5551 {
5552 /* We can do 8, 16, 32 and 64 bit fields, if aligned on byte boundaries. */
5553 if (INTVAL (operands[3]) % 8 != 0
5554 || (INTVAL (operands[2]) != 8
5555 && INTVAL (operands[2]) != 16
5556 && INTVAL (operands[2]) != 32
5557 && INTVAL (operands[2]) != 64))
5558 FAIL;
5559
5560 if (GET_CODE (operands[1]) == MEM)
5561 {
5562 /* Fail 8 bit fields, falling back on a simple byte load. */
5563 if (INTVAL (operands[2]) == 8)
5564 FAIL;
5565
5566 alpha_expand_unaligned_load (operands[0], operands[1],
5567 INTVAL (operands[2]) / 8,
5568 INTVAL (operands[3]) / 8, 0);
5569 DONE;
5570 }
5571 }")
5572
5573 (define_expand "insv"
5574 [(set (zero_extract:DI (match_operand:QI 0 "memory_operand" "")
5575 (match_operand:DI 1 "immediate_operand" "")
5576 (match_operand:DI 2 "immediate_operand" ""))
5577 (match_operand:DI 3 "register_operand" ""))]
5578 ""
5579 "
5580 {
5581 /* We can do 16, 32 and 64 bit fields, if aligned on byte boundaries. */
5582 if (INTVAL (operands[2]) % 8 != 0
5583 || (INTVAL (operands[1]) != 16
5584 && INTVAL (operands[1]) != 32
5585 && INTVAL (operands[1]) != 64))
5586 FAIL;
5587
5588 /* From mips.md: store_bit_field doesn't verify that our source
5589 matches the predicate, so we force it to be a MEM here. */
5590 if (GET_CODE (operands[0]) != MEM)
5591 FAIL;
5592
5593 alpha_expand_unaligned_store (operands[0], operands[3],
5594 INTVAL (operands[1]) / 8,
5595 INTVAL (operands[2]) / 8);
5596 DONE;
5597 }")
5598
5599
5600
5601 ;; Block move/clear, see alpha.c for more details.
5602 ;; Argument 0 is the destination
5603 ;; Argument 1 is the source
5604 ;; Argument 2 is the length
5605 ;; Argument 3 is the alignment
5606
5607 (define_expand "movstrqi"
5608 [(parallel [(set (match_operand:BLK 0 "memory_operand" "")
5609 (match_operand:BLK 1 "memory_operand" ""))
5610 (use (match_operand:DI 2 "immediate_operand" ""))
5611 (use (match_operand:DI 3 "immediate_operand" ""))])]
5612 ""
5613 "
5614 {
5615 if (alpha_expand_block_move (operands))
5616 DONE;
5617 else
5618 FAIL;
5619 }")
5620
5621 (define_expand "clrstrqi"
5622 [(parallel [(set (match_operand:BLK 0 "memory_operand" "")
5623 (const_int 0))
5624 (use (match_operand:DI 1 "immediate_operand" ""))
5625 (use (match_operand:DI 2 "immediate_operand" ""))])]
5626 ""
5627 "
5628 {
5629 if (alpha_expand_block_clear (operands))
5630 DONE;
5631 else
5632 FAIL;
5633 }")
5634 \f
5635 ;; Subroutine of stack space allocation. Perform a stack probe.
5636 (define_expand "probe_stack"
5637 [(set (match_dup 1) (match_operand:DI 0 "const_int_operand" ""))]
5638 ""
5639 "
5640 {
5641 operands[1] = gen_rtx_MEM (DImode, plus_constant (stack_pointer_rtx,
5642 INTVAL (operands[0])));
5643 MEM_VOLATILE_P (operands[1]) = 1;
5644
5645 operands[0] = const0_rtx;
5646 }")
5647
5648 ;; This is how we allocate stack space. If we are allocating a
5649 ;; constant amount of space and we know it is less than 4096
5650 ;; bytes, we need do nothing.
5651 ;;
5652 ;; If it is more than 4096 bytes, we need to probe the stack
5653 ;; periodically.
5654 (define_expand "allocate_stack"
5655 [(set (reg:DI 30)
5656 (plus:DI (reg:DI 30)
5657 (match_operand:DI 1 "reg_or_cint_operand" "")))
5658 (set (match_operand:DI 0 "register_operand" "=r")
5659 (match_dup 2))]
5660 ""
5661 "
5662 {
5663 if (GET_CODE (operands[1]) == CONST_INT
5664 && INTVAL (operands[1]) < 32768)
5665 {
5666 if (INTVAL (operands[1]) >= 4096)
5667 {
5668 /* We do this the same way as in the prologue and generate explicit
5669 probes. Then we update the stack by the constant. */
5670
5671 int probed = 4096;
5672
5673 emit_insn (gen_probe_stack (GEN_INT (- probed)));
5674 while (probed + 8192 < INTVAL (operands[1]))
5675 emit_insn (gen_probe_stack (GEN_INT (- (probed += 8192))));
5676
5677 if (probed + 4096 < INTVAL (operands[1]))
5678 emit_insn (gen_probe_stack (GEN_INT (- INTVAL(operands[1]))));
5679 }
5680
5681 operands[1] = GEN_INT (- INTVAL (operands[1]));
5682 operands[2] = virtual_stack_dynamic_rtx;
5683 }
5684 else
5685 {
5686 rtx out_label = 0;
5687 rtx loop_label = gen_label_rtx ();
5688 rtx want = gen_reg_rtx (Pmode);
5689 rtx tmp = gen_reg_rtx (Pmode);
5690 rtx memref;
5691
5692 emit_insn (gen_subdi3 (want, stack_pointer_rtx,
5693 force_reg (Pmode, operands[1])));
5694 emit_insn (gen_adddi3 (tmp, stack_pointer_rtx, GEN_INT (-4096)));
5695
5696 if (GET_CODE (operands[1]) != CONST_INT)
5697 {
5698 out_label = gen_label_rtx ();
5699 emit_insn (gen_cmpdi (want, tmp));
5700 emit_jump_insn (gen_bgeu (out_label));
5701 }
5702
5703 emit_label (loop_label);
5704 memref = gen_rtx_MEM (DImode, tmp);
5705 MEM_VOLATILE_P (memref) = 1;
5706 emit_move_insn (memref, const0_rtx);
5707 emit_insn (gen_adddi3 (tmp, tmp, GEN_INT(-8192)));
5708 emit_insn (gen_cmpdi (tmp, want));
5709 emit_jump_insn (gen_bgtu (loop_label));
5710
5711 memref = gen_rtx_MEM (DImode, want);
5712 MEM_VOLATILE_P (memref) = 1;
5713 emit_move_insn (memref, const0_rtx);
5714
5715 if (out_label)
5716 emit_label (out_label);
5717
5718 emit_move_insn (stack_pointer_rtx, want);
5719 emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
5720 DONE;
5721 }
5722 }")
5723
5724 ;; This is used by alpha_expand_prolog to do the same thing as above,
5725 ;; except we cannot at that time generate new basic blocks, so we hide
5726 ;; the loop in this one insn.
5727
5728 (define_insn "prologue_stack_probe_loop"
5729 [(unspec_volatile [(match_operand:DI 0 "register_operand" "r")
5730 (match_operand:DI 1 "register_operand" "r")] 5)]
5731 ""
5732 "*
5733 {
5734 operands[2] = gen_label_rtx ();
5735 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, \"L\",
5736 CODE_LABEL_NUMBER (operands[2]));
5737
5738 return \"stq $31,-8192(%1)\;subq %0,1,%0\;lda %1,-8192(%1)\;bne %0,%l2\";
5739 }"
5740 [(set_attr "length" "16")
5741 (set_attr "type" "multi")])
5742
5743 (define_expand "prologue"
5744 [(clobber (const_int 0))]
5745 ""
5746 "
5747 {
5748 alpha_expand_prologue ();
5749 DONE;
5750 }")
5751
5752 ;; These take care of emitting the ldgp insn in the prologue. This will be
5753 ;; an lda/ldah pair and we want to align them properly. So we have two
5754 ;; unspec_volatile insns, the first of which emits the ldgp assembler macro
5755 ;; and the second of which emits nothing. However, both are marked as type
5756 ;; IADD (the default) so the alignment code in alpha.c does the right thing
5757 ;; with them.
5758
5759 (define_expand "prologue_ldgp"
5760 [(unspec_volatile [(const_int 0)] 9)
5761 (unspec_volatile [(const_int 0)] 10)]
5762 ""
5763 "")
5764
5765 (define_insn "*prologue_ldgp_1"
5766 [(unspec_volatile [(const_int 0)] 9)]
5767 "! TARGET_OPEN_VMS && ! TARGET_WINDOWS_NT"
5768 "ldgp $29,0($27)\\n$%~..ng:")
5769
5770 (define_insn "*prologue_ldgp_2"
5771 [(unspec_volatile [(const_int 0)] 10)]
5772 "! TARGET_OPEN_VMS && ! TARGET_WINDOWS_NT"
5773 "")
5774
5775 ;; The _mcount profiling hook has special calling conventions, and
5776 ;; does not clobber all the registers that a normal call would. So
5777 ;; hide the fact this is a call at all.
5778
5779 (define_insn "prologue_mcount"
5780 [(unspec_volatile [(const_int 0)] 8)]
5781 ""
5782 "lda $28,_mcount\;jsr $28,($28),_mcount"
5783 [(set_attr "type" "multi")
5784 (set_attr "length" "8")])
5785
5786 (define_insn "init_fp"
5787 [(set (match_operand:DI 0 "register_operand" "=r")
5788 (match_operand:DI 1 "register_operand" "r"))
5789 (clobber (mem:BLK (match_operand:DI 2 "register_operand" "=r")))]
5790 ""
5791 "mov %1,%0")
5792
5793 (define_expand "epilogue"
5794 [(return)]
5795 ""
5796 "
5797 {
5798 alpha_expand_epilogue ();
5799 }")
5800
5801 (define_expand "sibcall_epilogue"
5802 [(return)]
5803 "!TARGET_OPEN_VMS && !TARGET_WINDOWS_NT"
5804 "
5805 {
5806 alpha_expand_epilogue ();
5807 DONE;
5808 }")
5809
5810 (define_expand "eh_epilogue"
5811 [(use (match_operand:DI 0 "register_operand" "r"))
5812 (use (match_operand:DI 1 "register_operand" "r"))
5813 (use (match_operand:DI 2 "register_operand" "r"))]
5814 "! TARGET_OPEN_VMS"
5815 "
5816 {
5817 cfun->machine->eh_epilogue_sp_ofs = operands[1];
5818 if (GET_CODE (operands[2]) != REG || REGNO (operands[2]) != 26)
5819 {
5820 rtx ra = gen_rtx_REG (Pmode, 26);
5821 emit_move_insn (ra, operands[2]);
5822 operands[2] = ra;
5823 }
5824 }")
5825
5826 ;; In creating a large stack frame, NT _must_ use ldah+lda to load
5827 ;; the frame size into a register. We use this pattern to ensure
5828 ;; we get lda instead of addq.
5829 (define_insn "nt_lda"
5830 [(set (match_operand:DI 0 "register_operand" "=r")
5831 (unspec:DI [(match_dup 0)
5832 (match_operand:DI 1 "const_int_operand" "n")] 6))]
5833 ""
5834 "lda %0,%1(%0)")
5835
5836 (define_expand "builtin_longjmp"
5837 [(unspec_volatile [(match_operand:DI 0 "register_operand" "r")] 3)]
5838 "! TARGET_OPEN_VMS && ! TARGET_WINDOWS_NT"
5839 "
5840 {
5841 /* The elements of the buffer are, in order: */
5842 rtx fp = gen_rtx_MEM (Pmode, operands[0]);
5843 rtx lab = gen_rtx_MEM (Pmode, plus_constant (operands[0], 8));
5844 rtx stack = gen_rtx_MEM (Pmode, plus_constant (operands[0], 16));
5845 rtx pv = gen_rtx_REG (Pmode, 27);
5846
5847 /* This bit is the same as expand_builtin_longjmp. */
5848 emit_move_insn (hard_frame_pointer_rtx, fp);
5849 emit_move_insn (pv, lab);
5850 emit_stack_restore (SAVE_NONLOCAL, stack, NULL_RTX);
5851 emit_insn (gen_rtx_USE (VOIDmode, hard_frame_pointer_rtx));
5852 emit_insn (gen_rtx_USE (VOIDmode, stack_pointer_rtx));
5853
5854 /* Load the label we are jumping through into $27 so that we know
5855 where to look for it when we get back to setjmp's function for
5856 restoring the gp. */
5857 emit_indirect_jump (pv);
5858 DONE;
5859 }")
5860
5861 (define_insn "builtin_setjmp_receiver"
5862 [(unspec_volatile [(label_ref (match_operand 0 "" ""))] 2)]
5863 "! TARGET_OPEN_VMS && ! TARGET_WINDOWS_NT && TARGET_AS_CAN_SUBTRACT_LABELS"
5864 "\\n$LSJ%=:\;ldgp $29,$LSJ%=-%l0($27)"
5865 [(set_attr "length" "8")
5866 (set_attr "type" "multi")])
5867
5868 (define_insn ""
5869 [(unspec_volatile [(label_ref (match_operand 0 "" ""))] 2)]
5870 "! TARGET_OPEN_VMS && ! TARGET_WINDOWS_NT"
5871 "br $29,$LSJ%=\\n$LSJ%=:\;ldgp $29,0($29)"
5872 [(set_attr "length" "12")
5873 (set_attr "type" "multi")])
5874
5875 (define_insn "exception_receiver"
5876 [(unspec_volatile [(const_int 0)] 7)]
5877 "! TARGET_OPEN_VMS && ! TARGET_WINDOWS_NT"
5878 "br $29,$LSJ%=\\n$LSJ%=:\;ldgp $29,0($29)"
5879 [(set_attr "length" "12")
5880 (set_attr "type" "multi")])
5881
5882 (define_expand "nonlocal_goto_receiver"
5883 [(unspec_volatile [(const_int 0)] 1)
5884 (set (reg:DI 27) (mem:DI (reg:DI 29)))
5885 (unspec_volatile [(const_int 0)] 1)
5886 (use (reg:DI 27))]
5887 "TARGET_OPEN_VMS"
5888 "")
5889
5890 (define_insn "arg_home"
5891 [(unspec [(const_int 0)] 0)
5892 (use (reg:DI 1))
5893 (use (reg:DI 25))
5894 (use (reg:DI 16))
5895 (use (reg:DI 17))
5896 (use (reg:DI 18))
5897 (use (reg:DI 19))
5898 (use (reg:DI 20))
5899 (use (reg:DI 21))
5900 (use (reg:DI 48))
5901 (use (reg:DI 49))
5902 (use (reg:DI 50))
5903 (use (reg:DI 51))
5904 (use (reg:DI 52))
5905 (use (reg:DI 53))
5906 (clobber (mem:BLK (const_int 0)))
5907 (clobber (reg:DI 24))
5908 (clobber (reg:DI 25))
5909 (clobber (reg:DI 0))]
5910 "TARGET_OPEN_VMS"
5911 "lda $0,OTS$HOME_ARGS\;ldq $0,8($0)\;jsr $0,OTS$HOME_ARGS"
5912 [(set_attr "length" "16")
5913 (set_attr "type" "multi")])
5914
5915 ;; Close the trap shadow of preceeding instructions. This is generated
5916 ;; by alpha_reorg.
5917
5918 (define_insn "trapb"
5919 [(unspec_volatile [(const_int 0)] 4)]
5920 ""
5921 "trapb"
5922 [(set_attr "type" "misc")])
5923
5924 ;; No-op instructions used by machine-dependant reorg to preserve
5925 ;; alignment for instruction issue.
5926
5927 (define_insn "nop"
5928 [(const_int 0)]
5929 ""
5930 "nop"
5931 [(set_attr "type" "ilog")])
5932
5933 (define_insn "fnop"
5934 [(const_int 1)]
5935 "TARGET_FP"
5936 "fnop"
5937 [(set_attr "type" "fcpys")])
5938
5939 (define_insn "unop"
5940 [(const_int 2)]
5941 ""
5942 "unop")
5943
5944 (define_insn "realign"
5945 [(unspec_volatile [(match_operand 0 "immediate_operand" "i")] 6)]
5946 ""
5947 ".align %0 #realign")
5948
5949 ;; The call patterns are at the end of the file because their
5950 ;; wildcard operand0 interferes with nice recognition.
5951
5952 (define_insn "*call_value_osf_1"
5953 [(set (match_operand 0 "" "")
5954 (call (mem:DI (match_operand:DI 1 "call_operand" "r,R,i"))
5955 (match_operand 2 "" "")))
5956 (clobber (reg:DI 27))
5957 (clobber (reg:DI 26))]
5958 "! TARGET_WINDOWS_NT && ! TARGET_OPEN_VMS"
5959 "@
5960 jsr $26,($27),0\;ldgp $29,0($26)
5961 bsr $26,$%1..ng
5962 jsr $26,%1\;ldgp $29,0($26)"
5963 [(set_attr "type" "jsr")
5964 (set_attr "length" "12,*,16")])
5965
5966 (define_insn "*sibcall_value_osf_1"
5967 [(set (match_operand 0 "" "")
5968 (call (mem:DI (match_operand:DI 1 "call_operand" "R,i"))
5969 (match_operand 2 "" "")))]
5970 "! TARGET_WINDOWS_NT && ! TARGET_OPEN_VMS"
5971 "@
5972 br $31,$%1..ng
5973 jmp $31,%1"
5974 [(set_attr "type" "jsr")
5975 (set_attr "length" "*,8")])
5976
5977 (define_insn "*call_value_nt_1"
5978 [(set (match_operand 0 "" "")
5979 (call (mem:DI (match_operand:DI 1 "call_operand" "r,R,i"))
5980 (match_operand 2 "" "")))
5981 (clobber (reg:DI 26))]
5982 "TARGET_WINDOWS_NT"
5983 "@
5984 jsr $26,(%1)
5985 bsr $26,%1
5986 jsr $26,%1"
5987 [(set_attr "type" "jsr")
5988 (set_attr "length" "*,*,12")])
5989
5990 (define_insn "*call_value_vms_1"
5991 [(set (match_operand 0 "" "")
5992 (call (mem:DI (match_operand:DI 1 "call_operand" "r,i"))
5993 (match_operand 2 "" "")))
5994 (use (match_operand:DI 3 "nonimmediate_operand" "r,m"))
5995 (use (reg:DI 25))
5996 (use (reg:DI 26))
5997 (clobber (reg:DI 27))]
5998 "TARGET_OPEN_VMS"
5999 "@
6000 mov %3,$27\;jsr $26,0\;ldq $27,0($29)
6001 ldq $27,%3\;jsr $26,%1\;ldq $27,0($29)"
6002 [(set_attr "type" "jsr")
6003 (set_attr "length" "12,16")])
6004 \f
6005 ;; Peepholes go at the end.
6006
6007 ;; Optimize sign-extension of SImode loads. This shows up in the wake of
6008 ;; reload when converting fp->int.
6009
6010 (define_peephole2
6011 [(set (match_operand:SI 0 "hard_int_register_operand" "")
6012 (match_operand:SI 1 "memory_operand" ""))
6013 (set (match_operand:DI 2 "hard_int_register_operand" "")
6014 (sign_extend:DI (match_dup 0)))]
6015 "true_regnum (operands[0]) == true_regnum (operands[2])
6016 || peep2_reg_dead_p (2, operands[0])"
6017 [(set (match_dup 2)
6018 (sign_extend:DI (match_dup 1)))]
6019 "")
6020
6021 (define_peephole2
6022 [(set (match_operand:SI 0 "hard_int_register_operand" "")
6023 (match_operand:SI 1 "hard_fp_register_operand" ""))
6024 (set (match_operand:DI 2 "hard_int_register_operand" "")
6025 (sign_extend:DI (match_dup 0)))]
6026 "TARGET_FIX
6027 && (true_regnum (operands[0]) == true_regnum (operands[2])
6028 || peep2_reg_dead_p (2, operands[0]))"
6029 [(set (match_dup 2)
6030 (sign_extend:DI (match_dup 1)))]
6031 "")
6032
6033 (define_peephole2
6034 [(set (match_operand:DI 0 "hard_fp_register_operand" "")
6035 (sign_extend:DI (match_operand:SI 1 "hard_fp_register_operand" "")))
6036 (set (match_operand:DI 2 "hard_int_register_operand" "")
6037 (match_dup 0))]
6038 "TARGET_FIX && peep2_reg_dead_p (2, operands[0])"
6039 [(set (match_dup 2)
6040 (sign_extend:DI (match_dup 1)))]
6041 "")