reload.c (push_secondary_reload): Revert 2000-08-16 change.
[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 "reg_or_0_operand" "")
3353 (match_operand:DI 1 "reg_or_8bit_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 "
3464 {
3465 if (alpha_compare.fp_p)
3466 FAIL;
3467
3468 operands[1] = gen_rtx_EQ (DImode, alpha_compare.op0, alpha_compare.op1);
3469 alpha_compare.op0 = alpha_compare.op1 = NULL_RTX;
3470 }")
3471
3472 (define_expand "sne"
3473 [(set (match_operand:DI 0 "register_operand" "")
3474 (match_dup 1))
3475 (set (match_dup 0) (xor:DI (match_dup 0) (const_int 1)))]
3476 ""
3477 "
3478 {
3479 if (alpha_compare.fp_p)
3480 FAIL;
3481
3482 if (alpha_compare.op1 == const0_rtx)
3483 {
3484 operands[1] = gen_rtx_NE (DImode, alpha_compare.op0, alpha_compare.op1);
3485 alpha_compare.op0 = alpha_compare.op1 = NULL_RTX;
3486 emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[1]));
3487 DONE;
3488 }
3489
3490 operands[1] = gen_rtx_EQ (DImode, alpha_compare.op0, alpha_compare.op1);
3491 alpha_compare.op0 = alpha_compare.op1 = NULL_RTX;
3492 }")
3493
3494 (define_expand "slt"
3495 [(set (match_operand:DI 0 "register_operand" "")
3496 (match_dup 1))]
3497 ""
3498 "
3499 {
3500 if (alpha_compare.fp_p)
3501 FAIL;
3502
3503 operands[1] = gen_rtx_LT (DImode, alpha_compare.op0, alpha_compare.op1);
3504 alpha_compare.op0 = alpha_compare.op1 = NULL_RTX;
3505 }")
3506
3507 (define_expand "sle"
3508 [(set (match_operand:DI 0 "register_operand" "")
3509 (match_dup 1))]
3510 ""
3511 "
3512 {
3513 if (alpha_compare.fp_p)
3514 FAIL;
3515
3516 operands[1] = gen_rtx_LE (DImode, alpha_compare.op0, alpha_compare.op1);
3517 alpha_compare.op0 = alpha_compare.op1 = NULL_RTX;
3518 }")
3519
3520 (define_expand "sgt"
3521 [(set (match_operand:DI 0 "register_operand" "")
3522 (match_dup 1))]
3523 ""
3524 "
3525 {
3526 if (alpha_compare.fp_p)
3527 FAIL;
3528
3529 operands[1] = gen_rtx_LT (DImode, force_reg (DImode, alpha_compare.op1),
3530 alpha_compare.op0);
3531 alpha_compare.op0 = alpha_compare.op1 = NULL_RTX;
3532 }")
3533
3534 (define_expand "sge"
3535 [(set (match_operand:DI 0 "register_operand" "")
3536 (match_dup 1))]
3537 ""
3538 "
3539 {
3540 if (alpha_compare.fp_p)
3541 FAIL;
3542
3543 operands[1] = gen_rtx_LE (DImode, force_reg (DImode, alpha_compare.op1),
3544 alpha_compare.op0);
3545 alpha_compare.op0 = alpha_compare.op1 = NULL_RTX;
3546 }")
3547
3548 (define_expand "sltu"
3549 [(set (match_operand:DI 0 "register_operand" "")
3550 (match_dup 1))]
3551 ""
3552 "
3553 {
3554 if (alpha_compare.fp_p)
3555 FAIL;
3556
3557 operands[1] = gen_rtx_LTU (DImode, alpha_compare.op0, alpha_compare.op1);
3558 alpha_compare.op0 = alpha_compare.op1 = NULL_RTX;
3559 }")
3560
3561 (define_expand "sleu"
3562 [(set (match_operand:DI 0 "register_operand" "")
3563 (match_dup 1))]
3564 ""
3565 "
3566 {
3567 if (alpha_compare.fp_p)
3568 FAIL;
3569
3570 operands[1] = gen_rtx_LEU (DImode, alpha_compare.op0, alpha_compare.op1);
3571 alpha_compare.op0 = alpha_compare.op1 = NULL_RTX;
3572 }")
3573
3574 (define_expand "sgtu"
3575 [(set (match_operand:DI 0 "register_operand" "")
3576 (match_dup 1))]
3577 ""
3578 "
3579 {
3580 if (alpha_compare.fp_p)
3581 FAIL;
3582
3583 operands[1] = gen_rtx_LTU (DImode, force_reg (DImode, alpha_compare.op1),
3584 alpha_compare.op0);
3585 alpha_compare.op0 = alpha_compare.op1 = NULL_RTX;
3586 }")
3587
3588 (define_expand "sgeu"
3589 [(set (match_operand:DI 0 "register_operand" "")
3590 (match_dup 1))]
3591 ""
3592 "
3593 {
3594 if (alpha_compare.fp_p)
3595 FAIL;
3596
3597 operands[1] = gen_rtx_LEU (DImode, force_reg (DImode, alpha_compare.op1),
3598 alpha_compare.op0);
3599 alpha_compare.op0 = alpha_compare.op1 = NULL_RTX;
3600 }")
3601 \f
3602 ;; These are the main define_expand's used to make conditional moves.
3603
3604 (define_expand "movsicc"
3605 [(set (match_operand:SI 0 "register_operand" "")
3606 (if_then_else:SI (match_operand 1 "comparison_operator" "")
3607 (match_operand:SI 2 "reg_or_8bit_operand" "")
3608 (match_operand:SI 3 "reg_or_8bit_operand" "")))]
3609 ""
3610 "
3611 {
3612 if ((operands[1] = alpha_emit_conditional_move (operands[1], SImode)) == 0)
3613 FAIL;
3614 }")
3615
3616 (define_expand "movdicc"
3617 [(set (match_operand:DI 0 "register_operand" "")
3618 (if_then_else:DI (match_operand 1 "comparison_operator" "")
3619 (match_operand:DI 2 "reg_or_8bit_operand" "")
3620 (match_operand:DI 3 "reg_or_8bit_operand" "")))]
3621 ""
3622 "
3623 {
3624 if ((operands[1] = alpha_emit_conditional_move (operands[1], DImode)) == 0)
3625 FAIL;
3626 }")
3627
3628 (define_expand "movsfcc"
3629 [(set (match_operand:SF 0 "register_operand" "")
3630 (if_then_else:SF (match_operand 1 "comparison_operator" "")
3631 (match_operand:SF 2 "reg_or_8bit_operand" "")
3632 (match_operand:SF 3 "reg_or_8bit_operand" "")))]
3633 ""
3634 "
3635 {
3636 if ((operands[1] = alpha_emit_conditional_move (operands[1], SFmode)) == 0)
3637 FAIL;
3638 }")
3639
3640 (define_expand "movdfcc"
3641 [(set (match_operand:DF 0 "register_operand" "")
3642 (if_then_else:DF (match_operand 1 "comparison_operator" "")
3643 (match_operand:DF 2 "reg_or_8bit_operand" "")
3644 (match_operand:DF 3 "reg_or_8bit_operand" "")))]
3645 ""
3646 "
3647 {
3648 if ((operands[1] = alpha_emit_conditional_move (operands[1], DFmode)) == 0)
3649 FAIL;
3650 }")
3651 \f
3652 ;; These define_split definitions are used in cases when comparisons have
3653 ;; not be stated in the correct way and we need to reverse the second
3654 ;; comparison. For example, x >= 7 has to be done as x < 6 with the
3655 ;; comparison that tests the result being reversed. We have one define_split
3656 ;; for each use of a comparison. They do not match valid insns and need
3657 ;; not generate valid insns.
3658 ;;
3659 ;; We can also handle equality comparisons (and inequality comparisons in
3660 ;; cases where the resulting add cannot overflow) by doing an add followed by
3661 ;; a comparison with zero. This is faster since the addition takes one
3662 ;; less cycle than a compare when feeding into a conditional move.
3663 ;; For this case, we also have an SImode pattern since we can merge the add
3664 ;; and sign extend and the order doesn't matter.
3665 ;;
3666 ;; We do not do this for floating-point, since it isn't clear how the "wrong"
3667 ;; operation could have been generated.
3668
3669 (define_split
3670 [(set (match_operand:DI 0 "register_operand" "")
3671 (if_then_else:DI
3672 (match_operator 1 "comparison_operator"
3673 [(match_operand:DI 2 "reg_or_0_operand" "")
3674 (match_operand:DI 3 "reg_or_cint_operand" "")])
3675 (match_operand:DI 4 "reg_or_cint_operand" "")
3676 (match_operand:DI 5 "reg_or_cint_operand" "")))
3677 (clobber (match_operand:DI 6 "register_operand" ""))]
3678 "operands[3] != const0_rtx"
3679 [(set (match_dup 6) (match_dup 7))
3680 (set (match_dup 0)
3681 (if_then_else:DI (match_dup 8) (match_dup 4) (match_dup 5)))]
3682 "
3683 { enum rtx_code code = GET_CODE (operands[1]);
3684 int unsignedp = (code == GEU || code == LEU || code == GTU || code == LTU);
3685
3686 /* If we are comparing for equality with a constant and that constant
3687 appears in the arm when the register equals the constant, use the
3688 register since that is more likely to match (and to produce better code
3689 if both would). */
3690
3691 if (code == EQ && GET_CODE (operands[3]) == CONST_INT
3692 && rtx_equal_p (operands[4], operands[3]))
3693 operands[4] = operands[2];
3694
3695 else if (code == NE && GET_CODE (operands[3]) == CONST_INT
3696 && rtx_equal_p (operands[5], operands[3]))
3697 operands[5] = operands[2];
3698
3699 if (code == NE || code == EQ
3700 || (extended_count (operands[2], DImode, unsignedp) >= 1
3701 && extended_count (operands[3], DImode, unsignedp) >= 1))
3702 {
3703 if (GET_CODE (operands[3]) == CONST_INT)
3704 operands[7] = gen_rtx_PLUS (DImode, operands[2],
3705 GEN_INT (- INTVAL (operands[3])));
3706 else
3707 operands[7] = gen_rtx_MINUS (DImode, operands[2], operands[3]);
3708
3709 operands[8] = gen_rtx_fmt_ee (code, VOIDmode, operands[6], const0_rtx);
3710 }
3711
3712 else if (code == EQ || code == LE || code == LT
3713 || code == LEU || code == LTU)
3714 {
3715 operands[7] = gen_rtx_fmt_ee (code, DImode, operands[2], operands[3]);
3716 operands[8] = gen_rtx_NE (VOIDmode, operands[6], const0_rtx);
3717 }
3718 else
3719 {
3720 operands[7] = gen_rtx_fmt_ee (reverse_condition (code), DImode,
3721 operands[2], operands[3]);
3722 operands[8] = gen_rtx_EQ (VOIDmode, operands[6], const0_rtx);
3723 }
3724 }")
3725
3726 (define_split
3727 [(set (match_operand:DI 0 "register_operand" "")
3728 (if_then_else:DI
3729 (match_operator 1 "comparison_operator"
3730 [(match_operand:SI 2 "reg_or_0_operand" "")
3731 (match_operand:SI 3 "reg_or_cint_operand" "")])
3732 (match_operand:DI 4 "reg_or_8bit_operand" "")
3733 (match_operand:DI 5 "reg_or_8bit_operand" "")))
3734 (clobber (match_operand:DI 6 "register_operand" ""))]
3735 "operands[3] != const0_rtx
3736 && (GET_CODE (operands[1]) == EQ || GET_CODE (operands[1]) == NE)"
3737 [(set (match_dup 6) (match_dup 7))
3738 (set (match_dup 0)
3739 (if_then_else:DI (match_dup 8) (match_dup 4) (match_dup 5)))]
3740 "
3741 { enum rtx_code code = GET_CODE (operands[1]);
3742 int unsignedp = (code == GEU || code == LEU || code == GTU || code == LTU);
3743 rtx tem;
3744
3745 if ((code != NE && code != EQ
3746 && ! (extended_count (operands[2], DImode, unsignedp) >= 1
3747 && extended_count (operands[3], DImode, unsignedp) >= 1)))
3748 FAIL;
3749
3750 if (GET_CODE (operands[3]) == CONST_INT)
3751 tem = gen_rtx_PLUS (SImode, operands[2],
3752 GEN_INT (- INTVAL (operands[3])));
3753 else
3754 tem = gen_rtx_MINUS (SImode, operands[2], operands[3]);
3755
3756 operands[7] = gen_rtx_SIGN_EXTEND (DImode, tem);
3757 operands[8] = gen_rtx_fmt_ee (GET_CODE (operands[1]), VOIDmode,
3758 operands[6], const0_rtx);
3759 }")
3760
3761 (define_split
3762 [(set (pc)
3763 (if_then_else
3764 (match_operator 1 "comparison_operator"
3765 [(match_operand:DI 2 "reg_or_0_operand" "")
3766 (match_operand:DI 3 "reg_or_cint_operand" "")])
3767 (label_ref (match_operand 0 "" ""))
3768 (pc)))
3769 (clobber (match_operand:DI 4 "register_operand" ""))]
3770 "operands[3] != const0_rtx"
3771 [(set (match_dup 4) (match_dup 5))
3772 (set (pc) (if_then_else (match_dup 6) (label_ref (match_dup 0)) (pc)))]
3773 "
3774 { enum rtx_code code = GET_CODE (operands[1]);
3775 int unsignedp = (code == GEU || code == LEU || code == GTU || code == LTU);
3776
3777 if (code == NE || code == EQ
3778 || (extended_count (operands[2], DImode, unsignedp) >= 1
3779 && extended_count (operands[3], DImode, unsignedp) >= 1))
3780 {
3781 if (GET_CODE (operands[3]) == CONST_INT)
3782 operands[5] = gen_rtx_PLUS (DImode, operands[2],
3783 GEN_INT (- INTVAL (operands[3])));
3784 else
3785 operands[5] = gen_rtx_MINUS (DImode, operands[2], operands[3]);
3786
3787 operands[6] = gen_rtx_fmt_ee (code, VOIDmode, operands[4], const0_rtx);
3788 }
3789
3790 else if (code == EQ || code == LE || code == LT
3791 || code == LEU || code == LTU)
3792 {
3793 operands[5] = gen_rtx_fmt_ee (code, DImode, operands[2], operands[3]);
3794 operands[6] = gen_rtx_NE (VOIDmode, operands[4], const0_rtx);
3795 }
3796 else
3797 {
3798 operands[5] = gen_rtx_fmt_ee (reverse_condition (code), DImode,
3799 operands[2], operands[3]);
3800 operands[6] = gen_rtx_EQ (VOIDmode, operands[4], const0_rtx);
3801 }
3802 }")
3803
3804 (define_split
3805 [(set (pc)
3806 (if_then_else
3807 (match_operator 1 "comparison_operator"
3808 [(match_operand:SI 2 "reg_or_0_operand" "")
3809 (match_operand:SI 3 "const_int_operand" "")])
3810 (label_ref (match_operand 0 "" ""))
3811 (pc)))
3812 (clobber (match_operand:DI 4 "register_operand" ""))]
3813 "operands[3] != const0_rtx
3814 && (GET_CODE (operands[1]) == EQ || GET_CODE (operands[1]) == NE)"
3815 [(set (match_dup 4) (match_dup 5))
3816 (set (pc) (if_then_else (match_dup 6) (label_ref (match_dup 0)) (pc)))]
3817 "
3818 { rtx tem;
3819
3820 if (GET_CODE (operands[3]) == CONST_INT)
3821 tem = gen_rtx_PLUS (SImode, operands[2],
3822 GEN_INT (- INTVAL (operands[3])));
3823 else
3824 tem = gen_rtx_MINUS (SImode, operands[2], operands[3]);
3825
3826 operands[5] = gen_rtx_SIGN_EXTEND (DImode, tem);
3827 operands[6] = gen_rtx_fmt_ee (GET_CODE (operands[1]), VOIDmode,
3828 operands[4], const0_rtx);
3829 }")
3830
3831 ;; We can convert such things as "a > 0xffff" to "t = a & ~ 0xffff; t != 0".
3832 ;; This eliminates one, and sometimes two, insns when the AND can be done
3833 ;; with a ZAP.
3834 (define_split
3835 [(set (match_operand:DI 0 "register_operand" "")
3836 (match_operator:DI 1 "comparison_operator"
3837 [(match_operand:DI 2 "register_operand" "")
3838 (match_operand:DI 3 "const_int_operand" "")]))
3839 (clobber (match_operand:DI 4 "register_operand" ""))]
3840 "exact_log2 (INTVAL (operands[3]) + 1) >= 0
3841 && (GET_CODE (operands[1]) == GTU
3842 || GET_CODE (operands[1]) == LEU
3843 || ((GET_CODE (operands[1]) == GT || GET_CODE (operands[1]) == LE)
3844 && extended_count (operands[2], DImode, 1) > 0))"
3845 [(set (match_dup 4) (and:DI (match_dup 2) (match_dup 5)))
3846 (set (match_dup 0) (match_dup 6))]
3847 "
3848 {
3849 operands[5] = GEN_INT (~ INTVAL (operands[3]));
3850 operands[6] = gen_rtx_fmt_ee (((GET_CODE (operands[1]) == GTU
3851 || GET_CODE (operands[1]) == GT)
3852 ? NE : EQ),
3853 DImode, operands[4], const0_rtx);
3854 }")
3855
3856 ;; Prefer to use cmp and arithmetic when possible instead of a cmove.
3857
3858 (define_split
3859 [(set (match_operand 0 "register_operand" "")
3860 (if_then_else (match_operator 1 "signed_comparison_operator"
3861 [(match_operand:DI 2 "reg_or_0_operand" "")
3862 (const_int 0)])
3863 (match_operand 3 "const_int_operand" "")
3864 (match_operand 4 "const_int_operand" "")))]
3865 ""
3866 [(const_int 0)]
3867 "
3868 {
3869 if (alpha_split_conditional_move (GET_CODE (operands[1]), operands[0],
3870 operands[2], operands[3], operands[4]))
3871 DONE;
3872 else
3873 FAIL;
3874 }")
3875
3876 ;; ??? Why combine is allowed to create such non-canonical rtl, I don't know.
3877 ;; Oh well, we match it in movcc, so it must be partially our fault.
3878 (define_split
3879 [(set (match_operand 0 "register_operand" "")
3880 (if_then_else (match_operator 1 "signed_comparison_operator"
3881 [(const_int 0)
3882 (match_operand:DI 2 "reg_or_0_operand" "")])
3883 (match_operand 3 "const_int_operand" "")
3884 (match_operand 4 "const_int_operand" "")))]
3885 ""
3886 [(const_int 0)]
3887 "
3888 {
3889 if (alpha_split_conditional_move (swap_condition (GET_CODE (operands[1])),
3890 operands[0], operands[2], operands[3],
3891 operands[4]))
3892 DONE;
3893 else
3894 FAIL;
3895 }")
3896
3897 (define_insn_and_split "*cmp_sadd_di"
3898 [(set (match_operand:DI 0 "register_operand" "=r")
3899 (plus:DI (if_then_else:DI
3900 (match_operator 1 "alpha_zero_comparison_operator"
3901 [(match_operand:DI 2 "reg_or_0_operand" "rJ")
3902 (const_int 0)])
3903 (match_operand:DI 3 "const48_operand" "I")
3904 (const_int 0))
3905 (match_operand:DI 4 "sext_add_operand" "rIO")))
3906 (clobber (match_scratch:DI 5 "=r"))]
3907 ""
3908 "#"
3909 "! no_new_pseudos || reload_completed"
3910 [(set (match_dup 5)
3911 (match_op_dup:DI 1 [(match_dup 2) (const_int 0)]))
3912 (set (match_dup 0)
3913 (plus:DI (mult:DI (match_dup 5) (match_dup 3))
3914 (match_dup 4)))]
3915 "
3916 {
3917 if (! no_new_pseudos)
3918 operands[5] = gen_reg_rtx (DImode);
3919 else if (reg_overlap_mentioned_p (operands[5], operands[4]))
3920 operands[5] = operands[0];
3921 }")
3922
3923 (define_insn_and_split "*cmp_sadd_si"
3924 [(set (match_operand:SI 0 "register_operand" "=r")
3925 (plus:SI (if_then_else:SI
3926 (match_operator 1 "alpha_zero_comparison_operator"
3927 [(match_operand:DI 2 "reg_or_0_operand" "rJ")
3928 (const_int 0)])
3929 (match_operand:SI 3 "const48_operand" "I")
3930 (const_int 0))
3931 (match_operand:SI 4 "sext_add_operand" "rIO")))
3932 (clobber (match_scratch:SI 5 "=r"))]
3933 ""
3934 "#"
3935 "! no_new_pseudos || reload_completed"
3936 [(set (match_dup 5)
3937 (match_op_dup:SI 1 [(match_dup 2) (const_int 0)]))
3938 (set (match_dup 0)
3939 (plus:SI (mult:SI (match_dup 5) (match_dup 3))
3940 (match_dup 4)))]
3941 "
3942 {
3943 if (! no_new_pseudos)
3944 operands[5] = gen_reg_rtx (DImode);
3945 else if (reg_overlap_mentioned_p (operands[5], operands[4]))
3946 operands[5] = operands[0];
3947 }")
3948
3949 (define_insn_and_split "*cmp_sadd_sidi"
3950 [(set (match_operand:DI 0 "register_operand" "=r")
3951 (sign_extend:DI
3952 (plus:SI (if_then_else:SI
3953 (match_operator 1 "alpha_zero_comparison_operator"
3954 [(match_operand:DI 2 "reg_or_0_operand" "rJ")
3955 (const_int 0)])
3956 (match_operand:SI 3 "const48_operand" "I")
3957 (const_int 0))
3958 (match_operand:SI 4 "sext_add_operand" "rIO"))))
3959 (clobber (match_scratch:SI 5 "=r"))]
3960 ""
3961 "#"
3962 "! no_new_pseudos || reload_completed"
3963 [(set (match_dup 5)
3964 (match_op_dup:SI 1 [(match_dup 2) (const_int 0)]))
3965 (set (match_dup 0)
3966 (sign_extend:DI (plus:SI (mult:SI (match_dup 5) (match_dup 3))
3967 (match_dup 4))))]
3968 "
3969 {
3970 if (! no_new_pseudos)
3971 operands[5] = gen_reg_rtx (DImode);
3972 else if (reg_overlap_mentioned_p (operands[5], operands[4]))
3973 operands[5] = operands[0];
3974 }")
3975
3976 (define_insn_and_split "*cmp_ssub_di"
3977 [(set (match_operand:DI 0 "register_operand" "=r")
3978 (minus:DI (if_then_else:DI
3979 (match_operator 1 "alpha_zero_comparison_operator"
3980 [(match_operand:DI 2 "reg_or_0_operand" "rJ")
3981 (const_int 0)])
3982 (match_operand:DI 3 "const48_operand" "I")
3983 (const_int 0))
3984 (match_operand:DI 4 "reg_or_8bit_operand" "rI")))
3985 (clobber (match_scratch:DI 5 "=r"))]
3986 ""
3987 "#"
3988 "! no_new_pseudos || reload_completed"
3989 [(set (match_dup 5)
3990 (match_op_dup:DI 1 [(match_dup 2) (const_int 0)]))
3991 (set (match_dup 0)
3992 (minus:DI (mult:DI (match_dup 5) (match_dup 3))
3993 (match_dup 4)))]
3994 "
3995 {
3996 if (! no_new_pseudos)
3997 operands[5] = gen_reg_rtx (DImode);
3998 else if (reg_overlap_mentioned_p (operands[5], operands[4]))
3999 operands[5] = operands[0];
4000 }")
4001
4002 (define_insn_and_split "*cmp_ssub_si"
4003 [(set (match_operand:SI 0 "register_operand" "=r")
4004 (minus:SI (if_then_else:SI
4005 (match_operator 1 "alpha_zero_comparison_operator"
4006 [(match_operand:DI 2 "reg_or_0_operand" "rJ")
4007 (const_int 0)])
4008 (match_operand:SI 3 "const48_operand" "I")
4009 (const_int 0))
4010 (match_operand:SI 4 "reg_or_8bit_operand" "rI")))
4011 (clobber (match_scratch:SI 5 "=r"))]
4012 ""
4013 "#"
4014 "! no_new_pseudos || reload_completed"
4015 [(set (match_dup 5)
4016 (match_op_dup:SI 1 [(match_dup 2) (const_int 0)]))
4017 (set (match_dup 0)
4018 (minus:SI (mult:SI (match_dup 5) (match_dup 3))
4019 (match_dup 4)))]
4020 "
4021 {
4022 if (! no_new_pseudos)
4023 operands[5] = gen_reg_rtx (DImode);
4024 else if (reg_overlap_mentioned_p (operands[5], operands[4]))
4025 operands[5] = operands[0];
4026 }")
4027
4028 (define_insn_and_split "*cmp_ssub_sidi"
4029 [(set (match_operand:DI 0 "register_operand" "=r")
4030 (sign_extend:DI
4031 (minus:SI (if_then_else:SI
4032 (match_operator 1 "alpha_zero_comparison_operator"
4033 [(match_operand:DI 2 "reg_or_0_operand" "rJ")
4034 (const_int 0)])
4035 (match_operand:SI 3 "const48_operand" "I")
4036 (const_int 0))
4037 (match_operand:SI 4 "reg_or_8bit_operand" "rI"))))
4038 (clobber (match_scratch:SI 5 "=r"))]
4039 ""
4040 "#"
4041 "! no_new_pseudos || reload_completed"
4042 [(set (match_dup 5)
4043 (match_op_dup:SI 1 [(match_dup 2) (const_int 0)]))
4044 (set (match_dup 0)
4045 (sign_extend:DI (minus:SI (mult:SI (match_dup 5) (match_dup 3))
4046 (match_dup 4))))]
4047 "
4048 {
4049 if (! no_new_pseudos)
4050 operands[5] = gen_reg_rtx (DImode);
4051 else if (reg_overlap_mentioned_p (operands[5], operands[4]))
4052 operands[5] = operands[0];
4053 }")
4054 \f
4055 ;; Here are the CALL and unconditional branch insns. Calls on NT and OSF
4056 ;; work differently, so we have different patterns for each.
4057
4058 (define_expand "call"
4059 [(use (match_operand:DI 0 "" ""))
4060 (use (match_operand 1 "" ""))
4061 (use (match_operand 2 "" ""))
4062 (use (match_operand 3 "" ""))]
4063 ""
4064 "
4065 { if (TARGET_WINDOWS_NT)
4066 emit_call_insn (gen_call_nt (operands[0], operands[1]));
4067 else if (TARGET_OPEN_VMS)
4068 emit_call_insn (gen_call_vms (operands[0], operands[2]));
4069 else
4070 emit_call_insn (gen_call_osf (operands[0], operands[1]));
4071
4072 DONE;
4073 }")
4074
4075 (define_expand "sibcall"
4076 [(call (mem:DI (match_operand 0 "" ""))
4077 (match_operand 1 "" ""))]
4078 "!TARGET_OPEN_VMS && !TARGET_WINDOWS_NT"
4079 "
4080 {
4081 if (GET_CODE (operands[0]) != MEM)
4082 abort ();
4083 operands[0] = XEXP (operands[0], 0);
4084 }")
4085
4086 (define_expand "call_osf"
4087 [(parallel [(call (mem:DI (match_operand 0 "" ""))
4088 (match_operand 1 "" ""))
4089 (clobber (reg:DI 27))
4090 (clobber (reg:DI 26))])]
4091 ""
4092 "
4093 { if (GET_CODE (operands[0]) != MEM)
4094 abort ();
4095
4096 operands[0] = XEXP (operands[0], 0);
4097
4098 if (GET_CODE (operands[0]) != SYMBOL_REF
4099 && ! (GET_CODE (operands[0]) == REG && REGNO (operands[0]) == 27))
4100 {
4101 rtx tem = gen_rtx_REG (DImode, 27);
4102 emit_move_insn (tem, operands[0]);
4103 operands[0] = tem;
4104 }
4105 }")
4106
4107 (define_expand "call_nt"
4108 [(parallel [(call (mem:DI (match_operand 0 "" ""))
4109 (match_operand 1 "" ""))
4110 (clobber (reg:DI 26))])]
4111 ""
4112 "
4113 { if (GET_CODE (operands[0]) != MEM)
4114 abort ();
4115
4116 operands[0] = XEXP (operands[0], 0);
4117 if (GET_CODE (operands[0]) != SYMBOL_REF && GET_CODE (operands[0]) != REG)
4118 operands[0] = force_reg (DImode, operands[0]);
4119 }")
4120
4121 ;;
4122 ;; call openvms/alpha
4123 ;; op 0: symbol ref for called function
4124 ;; op 1: next_arg_reg (argument information value for R25)
4125 ;;
4126 (define_expand "call_vms"
4127 [(parallel [(call (mem:DI (match_operand 0 "" ""))
4128 (match_operand 1 "" ""))
4129 (use (match_dup 2))
4130 (use (reg:DI 25))
4131 (use (reg:DI 26))
4132 (clobber (reg:DI 27))])]
4133 ""
4134 "
4135 { if (GET_CODE (operands[0]) != MEM)
4136 abort ();
4137
4138 operands[0] = XEXP (operands[0], 0);
4139
4140 /* Always load AI with argument information, then handle symbolic and
4141 indirect call differently. Load RA and set operands[2] to PV in
4142 both cases. */
4143
4144 emit_move_insn (gen_rtx_REG (DImode, 25), operands[1]);
4145 if (GET_CODE (operands[0]) == SYMBOL_REF)
4146 {
4147 rtx linkage = alpha_need_linkage (XSTR (operands[0], 0), 0);
4148
4149 emit_move_insn (gen_rtx_REG (Pmode, 26), gen_rtx_MEM (Pmode, linkage));
4150 operands[2]
4151 = validize_mem (gen_rtx_MEM (Pmode, plus_constant (linkage, 8)));
4152 }
4153 else
4154 {
4155 emit_move_insn (gen_rtx_REG (Pmode, 26),
4156 gen_rtx_MEM (Pmode, plus_constant (operands[0], 8)));
4157 operands[2] = operands[0];
4158 }
4159
4160 }")
4161
4162 (define_expand "call_value"
4163 [(use (match_operand 0 "" ""))
4164 (use (match_operand:DI 1 "" ""))
4165 (use (match_operand 2 "" ""))
4166 (use (match_operand 3 "" ""))
4167 (use (match_operand 4 "" ""))]
4168 ""
4169 "
4170 { if (TARGET_WINDOWS_NT)
4171 emit_call_insn (gen_call_value_nt (operands[0], operands[1], operands[2]));
4172 else if (TARGET_OPEN_VMS)
4173 emit_call_insn (gen_call_value_vms (operands[0], operands[1],
4174 operands[3]));
4175 else
4176 emit_call_insn (gen_call_value_osf (operands[0], operands[1],
4177 operands[2]));
4178 DONE;
4179 }")
4180
4181 (define_expand "sibcall_value"
4182 [(set (match_operand 0 "" "")
4183 (call (mem:DI (match_operand 1 "" ""))
4184 (match_operand 2 "" "")))]
4185 "!TARGET_OPEN_VMS && !TARGET_WINDOWS_NT"
4186 "
4187 {
4188 if (GET_CODE (operands[1]) != MEM)
4189 abort ();
4190 operands[1] = XEXP (operands[1], 0);
4191 }")
4192
4193 (define_expand "call_value_osf"
4194 [(parallel [(set (match_operand 0 "" "")
4195 (call (mem:DI (match_operand 1 "" ""))
4196 (match_operand 2 "" "")))
4197 (clobber (reg:DI 27))
4198 (clobber (reg:DI 26))])]
4199 ""
4200 "
4201 { if (GET_CODE (operands[1]) != MEM)
4202 abort ();
4203
4204 operands[1] = XEXP (operands[1], 0);
4205
4206 if (GET_CODE (operands[1]) != SYMBOL_REF
4207 && ! (GET_CODE (operands[1]) == REG && REGNO (operands[1]) == 27))
4208 {
4209 rtx tem = gen_rtx_REG (DImode, 27);
4210 emit_move_insn (tem, operands[1]);
4211 operands[1] = tem;
4212 }
4213 }")
4214
4215 (define_expand "call_value_nt"
4216 [(parallel [(set (match_operand 0 "" "")
4217 (call (mem:DI (match_operand 1 "" ""))
4218 (match_operand 2 "" "")))
4219 (clobber (reg:DI 26))])]
4220 ""
4221 "
4222 { if (GET_CODE (operands[1]) != MEM)
4223 abort ();
4224
4225 operands[1] = XEXP (operands[1], 0);
4226 if (GET_CODE (operands[1]) != SYMBOL_REF && GET_CODE (operands[1]) != REG)
4227 operands[1] = force_reg (DImode, operands[1]);
4228 }")
4229
4230 (define_expand "call_value_vms"
4231 [(parallel [(set (match_operand 0 "" "")
4232 (call (mem:DI (match_operand:DI 1 "" ""))
4233 (match_operand 2 "" "")))
4234 (use (match_dup 3))
4235 (use (reg:DI 25))
4236 (use (reg:DI 26))
4237 (clobber (reg:DI 27))])]
4238 ""
4239 "
4240 { if (GET_CODE (operands[1]) != MEM)
4241 abort ();
4242
4243 operands[1] = XEXP (operands[1], 0);
4244
4245 /* Always load AI with argument information, then handle symbolic and
4246 indirect call differently. Load RA and set operands[3] to PV in
4247 both cases. */
4248
4249 emit_move_insn (gen_rtx_REG (DImode, 25), operands[2]);
4250 if (GET_CODE (operands[1]) == SYMBOL_REF)
4251 {
4252 rtx linkage = alpha_need_linkage (XSTR (operands[1], 0), 0);
4253
4254 emit_move_insn (gen_rtx_REG (Pmode, 26), gen_rtx_MEM (Pmode, linkage));
4255 operands[3]
4256 = validize_mem (gen_rtx_MEM (Pmode, plus_constant (linkage, 8)));
4257 }
4258 else
4259 {
4260 emit_move_insn (gen_rtx_REG (Pmode, 26),
4261 gen_rtx_MEM (Pmode, plus_constant (operands[1], 8)));
4262 operands[3] = operands[1];
4263 }
4264 }")
4265
4266 (define_insn "*call_osf_1"
4267 [(call (mem:DI (match_operand:DI 0 "call_operand" "r,R,i"))
4268 (match_operand 1 "" ""))
4269 (clobber (reg:DI 27))
4270 (clobber (reg:DI 26))]
4271 "! TARGET_WINDOWS_NT && ! TARGET_OPEN_VMS"
4272 "@
4273 jsr $26,($27),0\;ldgp $29,0($26)
4274 bsr $26,$%0..ng
4275 jsr $26,%0\;ldgp $29,0($26)"
4276 [(set_attr "type" "jsr")
4277 (set_attr "length" "12,*,16")])
4278
4279 (define_insn "*sibcall_osf_1"
4280 [(call (mem:DI (match_operand:DI 0 "call_operand" "R,i"))
4281 (match_operand 1 "" ""))]
4282 "! TARGET_WINDOWS_NT && ! TARGET_OPEN_VMS"
4283 "@
4284 br $31,$%0..ng
4285 jmp $31,%0"
4286 [(set_attr "type" "jsr")
4287 (set_attr "length" "*,8")])
4288
4289 (define_insn "*call_nt_1"
4290 [(call (mem:DI (match_operand:DI 0 "call_operand" "r,R,i"))
4291 (match_operand 1 "" ""))
4292 (clobber (reg:DI 26))]
4293 "TARGET_WINDOWS_NT"
4294 "@
4295 jsr $26,(%0)
4296 bsr $26,%0
4297 jsr $26,%0"
4298 [(set_attr "type" "jsr")
4299 (set_attr "length" "*,*,12")])
4300
4301 (define_insn "*call_vms_1"
4302 [(call (mem:DI (match_operand:DI 0 "call_operand" "r,i"))
4303 (match_operand 1 "" ""))
4304 (use (match_operand:DI 2 "nonimmediate_operand" "r,m"))
4305 (use (reg:DI 25))
4306 (use (reg:DI 26))
4307 (clobber (reg:DI 27))]
4308 "TARGET_OPEN_VMS"
4309 "@
4310 mov %2,$27\;jsr $26,0\;ldq $27,0($29)
4311 ldq $27,%2\;jsr $26,%0\;ldq $27,0($29)"
4312 [(set_attr "type" "jsr")
4313 (set_attr "length" "12,16")])
4314
4315 ;; Call subroutine returning any type.
4316
4317 (define_expand "untyped_call"
4318 [(parallel [(call (match_operand 0 "" "")
4319 (const_int 0))
4320 (match_operand 1 "" "")
4321 (match_operand 2 "" "")])]
4322 ""
4323 "
4324 {
4325 int i;
4326
4327 emit_call_insn (GEN_CALL (operands[0], const0_rtx, NULL, const0_rtx));
4328
4329 for (i = 0; i < XVECLEN (operands[2], 0); i++)
4330 {
4331 rtx set = XVECEXP (operands[2], 0, i);
4332 emit_move_insn (SET_DEST (set), SET_SRC (set));
4333 }
4334
4335 /* The optimizer does not know that the call sets the function value
4336 registers we stored in the result block. We avoid problems by
4337 claiming that all hard registers are used and clobbered at this
4338 point. */
4339 emit_insn (gen_blockage ());
4340
4341 DONE;
4342 }")
4343
4344 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
4345 ;; all of memory. This blocks insns from being moved across this point.
4346
4347 (define_insn "blockage"
4348 [(unspec_volatile [(const_int 0)] 1)]
4349 ""
4350 ""
4351 [(set_attr "length" "0")])
4352
4353 (define_insn "jump"
4354 [(set (pc)
4355 (label_ref (match_operand 0 "" "")))]
4356 ""
4357 "br $31,%l0"
4358 [(set_attr "type" "ibr")])
4359
4360 (define_expand "return"
4361 [(return)]
4362 "direct_return ()"
4363 "")
4364
4365 (define_insn "*return_internal"
4366 [(return)]
4367 "reload_completed"
4368 "ret $31,($26),1"
4369 [(set_attr "type" "ibr")])
4370
4371 (define_insn "indirect_jump"
4372 [(set (pc) (match_operand:DI 0 "register_operand" "r"))]
4373 ""
4374 "jmp $31,(%0),0"
4375 [(set_attr "type" "ibr")])
4376
4377 (define_expand "tablejump"
4378 [(use (match_operand:SI 0 "register_operand" ""))
4379 (use (match_operand:SI 1 "" ""))]
4380 ""
4381 "
4382 {
4383 if (TARGET_WINDOWS_NT)
4384 emit_jump_insn (gen_tablejump_nt (operands[0], operands[1]));
4385 else if (TARGET_OPEN_VMS)
4386 emit_jump_insn (gen_tablejump_vms (operands[0], operands[1]));
4387 else
4388 emit_jump_insn (gen_tablejump_osf (operands[0], operands[1]));
4389
4390 DONE;
4391 }")
4392
4393 (define_expand "tablejump_osf"
4394 [(set (match_dup 3)
4395 (sign_extend:DI (match_operand:SI 0 "register_operand" "")))
4396 (parallel [(set (pc)
4397 (plus:DI (match_dup 3)
4398 (label_ref (match_operand 1 "" ""))))
4399 (clobber (match_scratch:DI 2 "=r"))])]
4400 ""
4401 "
4402 { operands[3] = gen_reg_rtx (DImode); }")
4403
4404 (define_expand "tablejump_nt"
4405 [(set (match_dup 3)
4406 (sign_extend:DI (match_operand:SI 0 "register_operand" "")))
4407 (parallel [(set (pc)
4408 (match_dup 3))
4409 (use (label_ref (match_operand 1 "" "")))])]
4410 ""
4411 "
4412 { operands[3] = gen_reg_rtx (DImode); }")
4413
4414 ;;
4415 ;; tablejump, openVMS way
4416 ;; op 0: offset
4417 ;; op 1: label preceding jump-table
4418 ;;
4419 (define_expand "tablejump_vms"
4420 [(set (match_dup 2)
4421 (match_operand:DI 0 "register_operand" ""))
4422 (set (pc)
4423 (plus:DI (match_dup 2)
4424 (label_ref (match_operand 1 "" ""))))]
4425 ""
4426 "
4427 { operands[2] = gen_reg_rtx (DImode); }")
4428
4429 (define_insn ""
4430 [(set (pc)
4431 (plus (match_operand:DI 0 "register_operand" "r")
4432 (label_ref (match_operand 1 "" ""))))
4433 (clobber (match_scratch:DI 2 "=r"))]
4434 "! TARGET_WINDOWS_NT && ! TARGET_OPEN_VMS && next_active_insn (insn) != 0
4435 && GET_CODE (PATTERN (next_active_insn (insn))) == ADDR_DIFF_VEC
4436 && PREV_INSN (next_active_insn (insn)) == operands[1]"
4437 "*
4438 { rtx best_label = 0;
4439 rtx jump_table_insn = next_active_insn (operands[1]);
4440
4441 if (GET_CODE (jump_table_insn) == JUMP_INSN
4442 && GET_CODE (PATTERN (jump_table_insn)) == ADDR_DIFF_VEC)
4443 {
4444 rtx jump_table = PATTERN (jump_table_insn);
4445 int n_labels = XVECLEN (jump_table, 1);
4446 int best_count = -1;
4447 int i, j;
4448
4449 for (i = 0; i < n_labels; i++)
4450 {
4451 int count = 1;
4452
4453 for (j = i + 1; j < n_labels; j++)
4454 if (XEXP (XVECEXP (jump_table, 1, i), 0)
4455 == XEXP (XVECEXP (jump_table, 1, j), 0))
4456 count++;
4457
4458 if (count > best_count)
4459 best_count = count, best_label = XVECEXP (jump_table, 1, i);
4460 }
4461 }
4462
4463 if (best_label)
4464 {
4465 operands[3] = best_label;
4466 return \"addq %0,$29,%2\;jmp $31,(%2),%3\";
4467 }
4468 else
4469 return \"addq %0,$29,%2\;jmp $31,(%2),0\";
4470 }"
4471 [(set_attr "type" "ibr")
4472 (set_attr "length" "8")])
4473
4474 (define_insn ""
4475 [(set (pc)
4476 (match_operand:DI 0 "register_operand" "r"))
4477 (use (label_ref (match_operand 1 "" "")))]
4478 "TARGET_WINDOWS_NT && next_active_insn (insn) != 0
4479 && GET_CODE (PATTERN (next_active_insn (insn))) == ADDR_DIFF_VEC
4480 && PREV_INSN (next_active_insn (insn)) == operands[1]"
4481 "*
4482 { rtx best_label = 0;
4483 rtx jump_table_insn = next_active_insn (operands[1]);
4484
4485 if (GET_CODE (jump_table_insn) == JUMP_INSN
4486 && GET_CODE (PATTERN (jump_table_insn)) == ADDR_DIFF_VEC)
4487 {
4488 rtx jump_table = PATTERN (jump_table_insn);
4489 int n_labels = XVECLEN (jump_table, 1);
4490 int best_count = -1;
4491 int i, j;
4492
4493 for (i = 0; i < n_labels; i++)
4494 {
4495 int count = 1;
4496
4497 for (j = i + 1; j < n_labels; j++)
4498 if (XEXP (XVECEXP (jump_table, 1, i), 0)
4499 == XEXP (XVECEXP (jump_table, 1, j), 0))
4500 count++;
4501
4502 if (count > best_count)
4503 best_count = count, best_label = XVECEXP (jump_table, 1, i);
4504 }
4505 }
4506
4507 if (best_label)
4508 {
4509 operands[2] = best_label;
4510 return \"jmp $31,(%0),%2\";
4511 }
4512 else
4513 return \"jmp $31,(%0),0\";
4514 }"
4515 [(set_attr "type" "ibr")])
4516
4517 ;;
4518 ;; op 0 is table offset
4519 ;; op 1 is table label
4520 ;;
4521
4522 (define_insn ""
4523 [(set (pc)
4524 (plus (match_operand:DI 0 "register_operand" "r")
4525 (label_ref (match_operand 1 "" ""))))]
4526 "TARGET_OPEN_VMS"
4527 "jmp $31,(%0),0"
4528 [(set_attr "type" "ibr")])
4529
4530 ;; Cache flush. Used by INITIALIZE_TRAMPOLINE. 0x86 is PAL_imb, but we don't
4531 ;; want to have to include pal.h in our .s file.
4532 ;;
4533 ;; Technically the type for call_pal is jsr, but we use that for determining
4534 ;; if we need a GP. Use ibr instead since it has the same EV5 scheduling
4535 ;; characteristics.
4536 (define_insn "imb"
4537 [(unspec_volatile [(const_int 0)] 0)]
4538 ""
4539 "call_pal 0x86"
4540 [(set_attr "type" "ibr")])
4541 \f
4542 ;; Finally, we have the basic data motion insns. The byte and word insns
4543 ;; are done via define_expand. Start with the floating-point insns, since
4544 ;; they are simpler.
4545
4546 (define_insn ""
4547 [(set (match_operand:SF 0 "nonimmediate_operand" "=f,f,*r,*r,m,m")
4548 (match_operand:SF 1 "input_operand" "fG,m,*rG,m,fG,*r"))]
4549 "TARGET_FPREGS && ! TARGET_FIX
4550 && (register_operand (operands[0], SFmode)
4551 || reg_or_fp0_operand (operands[1], SFmode))"
4552 "@
4553 fmov %R1,%0
4554 ld%, %0,%1
4555 mov %r1,%0
4556 ldl %0,%1
4557 st%, %R1,%0
4558 stl %r1,%0"
4559 [(set_attr "type" "fcpys,fld,ilog,ild,fst,ist")])
4560
4561 (define_insn ""
4562 [(set (match_operand:SF 0 "nonimmediate_operand" "=f,f,*r,*r,m,m,f,*r")
4563 (match_operand:SF 1 "input_operand" "fG,m,*rG,m,fG,*r,*r,f"))]
4564 "TARGET_FPREGS && TARGET_FIX
4565 && (register_operand (operands[0], SFmode)
4566 || reg_or_fp0_operand (operands[1], SFmode))"
4567 "@
4568 fmov %R1,%0
4569 ld%, %0,%1
4570 mov %r1,%0
4571 ldl %0,%1
4572 st%, %R1,%0
4573 stl %r1,%0
4574 itofs %1,%0
4575 ftois %1,%0"
4576 [(set_attr "type" "fcpys,fld,ilog,ild,fst,ist,itof,ftoi")])
4577
4578 (define_insn ""
4579 [(set (match_operand:SF 0 "nonimmediate_operand" "=r,r,m")
4580 (match_operand:SF 1 "input_operand" "rG,m,r"))]
4581 "! TARGET_FPREGS
4582 && (register_operand (operands[0], SFmode)
4583 || reg_or_fp0_operand (operands[1], SFmode))"
4584 "@
4585 mov %r1,%0
4586 ldl %0,%1
4587 stl %r1,%0"
4588 [(set_attr "type" "ilog,ild,ist")])
4589
4590 (define_insn ""
4591 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,f,*r,*r,m,m")
4592 (match_operand:DF 1 "input_operand" "fG,m,*rG,m,fG,*r"))]
4593 "TARGET_FPREGS && ! TARGET_FIX
4594 && (register_operand (operands[0], DFmode)
4595 || reg_or_fp0_operand (operands[1], DFmode))"
4596 "@
4597 fmov %R1,%0
4598 ld%- %0,%1
4599 mov %r1,%0
4600 ldq %0,%1
4601 st%- %R1,%0
4602 stq %r1,%0"
4603 [(set_attr "type" "fcpys,fld,ilog,ild,fst,ist")])
4604
4605 (define_insn ""
4606 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,f,*r,*r,m,m,f,*r")
4607 (match_operand:DF 1 "input_operand" "fG,m,*rG,m,fG,*r,*r,f"))]
4608 "TARGET_FPREGS && TARGET_FIX
4609 && (register_operand (operands[0], DFmode)
4610 || reg_or_fp0_operand (operands[1], DFmode))"
4611 "@
4612 fmov %R1,%0
4613 ld%- %0,%1
4614 mov %r1,%0
4615 ldq %0,%1
4616 st%- %R1,%0
4617 stq %r1,%0
4618 itoft %1,%0
4619 ftoit %1,%0"
4620 [(set_attr "type" "fcpys,fld,ilog,ild,fst,ist,itof,ftoi")])
4621
4622 (define_insn ""
4623 [(set (match_operand:DF 0 "nonimmediate_operand" "=r,r,m")
4624 (match_operand:DF 1 "input_operand" "rG,m,r"))]
4625 "! TARGET_FPREGS
4626 && (register_operand (operands[0], DFmode)
4627 || reg_or_fp0_operand (operands[1], DFmode))"
4628 "@
4629 mov %r1,%0
4630 ldq %0,%1
4631 stq %r1,%0"
4632 [(set_attr "type" "ilog,ild,ist")])
4633
4634 ;; Subregs suck for register allocation. Pretend we can move TFmode
4635 ;; data between general registers until after reload.
4636 (define_insn ""
4637 [(set (match_operand:TF 0 "nonimmediate_operand" "=r,o")
4638 (match_operand:TF 1 "input_operand" "roG,r"))]
4639 "register_operand (operands[0], TFmode)
4640 || reg_or_fp0_operand (operands[1], TFmode)"
4641 "#")
4642
4643 (define_split
4644 [(set (match_operand:TF 0 "nonimmediate_operand" "")
4645 (match_operand:TF 1 "input_operand" ""))]
4646 "reload_completed"
4647 [(set (match_dup 0) (match_dup 2))
4648 (set (match_dup 1) (match_dup 3))]
4649 "
4650 {
4651 alpha_split_tfmode_pair (operands);
4652 if (rtx_equal_p (operands[0], operands[3]))
4653 {
4654 rtx tmp;
4655 tmp = operands[0], operands[0] = operands[1], operands[1] = tmp;
4656 tmp = operands[2], operands[2] = operands[3], operands[3] = tmp;
4657 }
4658 }")
4659
4660 (define_expand "movsf"
4661 [(set (match_operand:SF 0 "nonimmediate_operand" "")
4662 (match_operand:SF 1 "general_operand" ""))]
4663 ""
4664 "
4665 {
4666 if (GET_CODE (operands[0]) == MEM
4667 && ! reg_or_fp0_operand (operands[1], SFmode))
4668 operands[1] = force_reg (SFmode, operands[1]);
4669 }")
4670
4671 (define_expand "movdf"
4672 [(set (match_operand:DF 0 "nonimmediate_operand" "")
4673 (match_operand:DF 1 "general_operand" ""))]
4674 ""
4675 "
4676 {
4677 if (GET_CODE (operands[0]) == MEM
4678 && ! reg_or_fp0_operand (operands[1], DFmode))
4679 operands[1] = force_reg (DFmode, operands[1]);
4680 }")
4681
4682 (define_expand "movtf"
4683 [(set (match_operand:TF 0 "nonimmediate_operand" "")
4684 (match_operand:TF 1 "general_operand" ""))]
4685 ""
4686 "
4687 {
4688 if (GET_CODE (operands[0]) == MEM
4689 && ! reg_or_fp0_operand (operands[1], TFmode))
4690 operands[1] = force_reg (TFmode, operands[1]);
4691 }")
4692
4693 (define_insn ""
4694 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,r,r,m,*f,*f,m")
4695 (match_operand:SI 1 "input_operand" "rJ,K,L,m,rJ,*fJ,m,*f"))]
4696 "! TARGET_WINDOWS_NT && ! TARGET_OPEN_VMS && ! TARGET_FIX
4697 && (register_operand (operands[0], SImode)
4698 || reg_or_0_operand (operands[1], SImode))"
4699 "@
4700 mov %r1,%0
4701 lda %0,%1
4702 ldah %0,%h1
4703 ldl %0,%1
4704 stl %r1,%0
4705 fmov %R1,%0
4706 ld%, %0,%1
4707 st%, %R1,%0"
4708 [(set_attr "type" "ilog,iadd,iadd,ild,ist,fcpys,fld,fst")])
4709
4710 (define_insn ""
4711 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,r,r,m,*f,*f,m,r,*f")
4712 (match_operand:SI 1 "input_operand" "rJ,K,L,m,rJ,*fJ,m,*f,*f,r"))]
4713 "! TARGET_WINDOWS_NT && ! TARGET_OPEN_VMS && TARGET_FIX
4714 && (register_operand (operands[0], SImode)
4715 || reg_or_0_operand (operands[1], SImode))"
4716 "@
4717 mov %r1,%0
4718 lda %0,%1
4719 ldah %0,%h1
4720 ldl %0,%1
4721 stl %r1,%0
4722 fmov %R1,%0
4723 ld%, %0,%1
4724 st%, %R1,%0
4725 ftois %1,%0
4726 itofs %1,%0"
4727 [(set_attr "type" "ilog,iadd,iadd,ild,ist,fcpys,fld,fst,ftoi,itof")])
4728
4729 (define_insn ""
4730 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,r,r,r,m,*f,*f,m")
4731 (match_operand:SI 1 "input_operand" "rJ,K,L,s,m,rJ,*fJ,m,*f"))]
4732 "(TARGET_WINDOWS_NT || TARGET_OPEN_VMS)
4733 && (register_operand (operands[0], SImode)
4734 || reg_or_0_operand (operands[1], SImode))"
4735 "@
4736 mov %1,%0
4737 lda %0,%1
4738 ldah %0,%h1
4739 lda %0,%1
4740 ldl %0,%1
4741 stl %r1,%0
4742 fmov %R1,%0
4743 ld%, %0,%1
4744 st%, %R1,%0"
4745 [(set_attr "type" "ilog,iadd,iadd,ldsym,ild,ist,fcpys,fld,fst")])
4746
4747 (define_insn ""
4748 [(set (match_operand:HI 0 "register_operand" "=r,r")
4749 (match_operand:HI 1 "input_operand" "rJ,n"))]
4750 "! TARGET_BWX
4751 && (register_operand (operands[0], HImode)
4752 || register_operand (operands[1], HImode))"
4753 "@
4754 mov %r1,%0
4755 lda %0,%L1"
4756 [(set_attr "type" "ilog,iadd")])
4757
4758 (define_insn ""
4759 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
4760 (match_operand:HI 1 "input_operand" "rJ,n,m,rJ"))]
4761 "TARGET_BWX
4762 && (register_operand (operands[0], HImode)
4763 || reg_or_0_operand (operands[1], HImode))"
4764 "@
4765 mov %r1,%0
4766 lda %0,%L1
4767 ldwu %0,%1
4768 stw %r1,%0"
4769 [(set_attr "type" "ilog,iadd,ild,ist")])
4770
4771 (define_insn ""
4772 [(set (match_operand:QI 0 "register_operand" "=r,r")
4773 (match_operand:QI 1 "input_operand" "rJ,n"))]
4774 "! TARGET_BWX
4775 && (register_operand (operands[0], QImode)
4776 || register_operand (operands[1], QImode))"
4777 "@
4778 mov %r1,%0
4779 lda %0,%L1"
4780 [(set_attr "type" "ilog,iadd")])
4781
4782 (define_insn ""
4783 [(set (match_operand:QI 0 "nonimmediate_operand" "=r,r,r,m")
4784 (match_operand:QI 1 "input_operand" "rJ,n,m,rJ"))]
4785 "TARGET_BWX
4786 && (register_operand (operands[0], QImode)
4787 || reg_or_0_operand (operands[1], QImode))"
4788 "@
4789 mov %r1,%0
4790 lda %0,%L1
4791 ldbu %0,%1
4792 stb %r1,%0"
4793 [(set_attr "type" "ilog,iadd,ild,ist")])
4794
4795 ;; We do two major things here: handle mem->mem and construct long
4796 ;; constants.
4797
4798 (define_expand "movsi"
4799 [(set (match_operand:SI 0 "nonimmediate_operand" "")
4800 (match_operand:SI 1 "general_operand" ""))]
4801 ""
4802 "
4803 {
4804 if (GET_CODE (operands[0]) == MEM
4805 && ! reg_or_0_operand (operands[1], SImode))
4806 operands[1] = force_reg (SImode, operands[1]);
4807
4808 if (! CONSTANT_P (operands[1]) || input_operand (operands[1], SImode))
4809 ;
4810 else if (GET_CODE (operands[1]) == CONST_INT)
4811 {
4812 operands[1]
4813 = alpha_emit_set_const (operands[0], SImode, INTVAL (operands[1]), 3);
4814 if (rtx_equal_p (operands[0], operands[1]))
4815 DONE;
4816 }
4817 }")
4818
4819 ;; Split a load of a large constant into the appropriate two-insn
4820 ;; sequence.
4821
4822 (define_split
4823 [(set (match_operand:SI 0 "register_operand" "")
4824 (match_operand:SI 1 "const_int_operand" ""))]
4825 "! add_operand (operands[1], SImode)"
4826 [(set (match_dup 0) (match_dup 2))
4827 (set (match_dup 0) (plus:SI (match_dup 0) (match_dup 3)))]
4828 "
4829 { rtx tem
4830 = alpha_emit_set_const (operands[0], SImode, INTVAL (operands[1]), 2);
4831
4832 if (tem == operands[0])
4833 DONE;
4834 else
4835 FAIL;
4836 }")
4837
4838 (define_insn ""
4839 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,r,r,r,m,*f,*f,Q")
4840 (match_operand:DI 1 "input_operand" "rJ,K,L,s,m,rJ,*fJ,Q,*f"))]
4841 "! TARGET_FIX
4842 && (register_operand (operands[0], DImode)
4843 || reg_or_0_operand (operands[1], DImode))"
4844 "@
4845 mov %r1,%0
4846 lda %0,%1
4847 ldah %0,%h1
4848 lda %0,%1
4849 ldq%A1 %0,%1
4850 stq%A0 %r1,%0
4851 fmov %R1,%0
4852 ldt %0,%1
4853 stt %R1,%0"
4854 [(set_attr "type" "ilog,iadd,iadd,ldsym,ild,ist,fcpys,fld,fst")])
4855
4856 (define_insn ""
4857 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,r,r,r,m,*f,*f,Q,r,*f")
4858 (match_operand:DI 1 "input_operand" "rJ,K,L,s,m,rJ,*fJ,Q,*f,*f,r"))]
4859 "TARGET_FIX
4860 && (register_operand (operands[0], DImode)
4861 || reg_or_0_operand (operands[1], DImode))"
4862 "@
4863 mov %r1,%0
4864 lda %0,%1
4865 ldah %0,%h1
4866 lda %0,%1
4867 ldq%A1 %0,%1
4868 stq%A0 %r1,%0
4869 fmov %R1,%0
4870 ldt %0,%1
4871 stt %R1,%0
4872 ftoit %1,%0
4873 itoft %1,%0"
4874 [(set_attr "type" "ilog,iadd,iadd,ldsym,ild,ist,fcpys,fld,fst,ftoi,itof")])
4875
4876 ;; We do three major things here: handle mem->mem, put 64-bit constants in
4877 ;; memory, and construct long 32-bit constants.
4878
4879 (define_expand "movdi"
4880 [(set (match_operand:DI 0 "nonimmediate_operand" "")
4881 (match_operand:DI 1 "general_operand" ""))]
4882 ""
4883 "
4884 {
4885 rtx tem;
4886
4887 if (GET_CODE (operands[0]) == MEM
4888 && ! reg_or_0_operand (operands[1], DImode))
4889 operands[1] = force_reg (DImode, operands[1]);
4890
4891 if (! CONSTANT_P (operands[1]) || input_operand (operands[1], DImode))
4892 ;
4893 else if (GET_CODE (operands[1]) == CONST_INT
4894 && (tem = alpha_emit_set_const (operands[0], DImode,
4895 INTVAL (operands[1]), 3)) != 0)
4896 {
4897 if (rtx_equal_p (tem, operands[0]))
4898 DONE;
4899 else
4900 operands[1] = tem;
4901 }
4902 else if (CONSTANT_P (operands[1]))
4903 {
4904 if (TARGET_BUILD_CONSTANTS)
4905 {
4906 HOST_WIDE_INT i0, i1;
4907
4908 if (GET_CODE (operands[1]) == CONST_INT)
4909 {
4910 i0 = INTVAL (operands[1]);
4911 i1 = -(i0 < 0);
4912 }
4913 else if (GET_CODE (operands[1]) == CONST_DOUBLE)
4914 {
4915 #if HOST_BITS_PER_WIDE_INT >= 64
4916 i0 = CONST_DOUBLE_LOW (operands[1]);
4917 i1 = -(i0 < 0);
4918 #else
4919 i0 = CONST_DOUBLE_LOW (operands[1]);
4920 i1 = CONST_DOUBLE_HIGH (operands[1]);
4921 #endif
4922 }
4923 else
4924 abort();
4925
4926 tem = alpha_emit_set_long_const (operands[0], i0, i1);
4927 if (rtx_equal_p (tem, operands[0]))
4928 DONE;
4929 else
4930 operands[1] = tem;
4931 }
4932 else
4933 {
4934 operands[1] = force_const_mem (DImode, operands[1]);
4935 if (reload_in_progress)
4936 {
4937 emit_move_insn (operands[0], XEXP (operands[1], 0));
4938 operands[1] = copy_rtx (operands[1]);
4939 XEXP (operands[1], 0) = operands[0];
4940 }
4941 else
4942 operands[1] = validize_mem (operands[1]);
4943 }
4944 }
4945 else
4946 abort ();
4947 }")
4948
4949 ;; Split a load of a large constant into the appropriate two-insn
4950 ;; sequence.
4951
4952 (define_split
4953 [(set (match_operand:DI 0 "register_operand" "")
4954 (match_operand:DI 1 "const_int_operand" ""))]
4955 "! add_operand (operands[1], DImode)"
4956 [(set (match_dup 0) (match_dup 2))
4957 (set (match_dup 0) (plus:DI (match_dup 0) (match_dup 3)))]
4958 "
4959 { rtx tem
4960 = alpha_emit_set_const (operands[0], DImode, INTVAL (operands[1]), 2);
4961
4962 if (tem == operands[0])
4963 DONE;
4964 else
4965 FAIL;
4966 }")
4967
4968 ;; These are the partial-word cases.
4969 ;;
4970 ;; First we have the code to load an aligned word. Operand 0 is the register
4971 ;; in which to place the result. It's mode is QImode or HImode. Operand 1
4972 ;; is an SImode MEM at the low-order byte of the proper word. Operand 2 is the
4973 ;; number of bits within the word that the value is. Operand 3 is an SImode
4974 ;; scratch register. If operand 0 is a hard register, operand 3 may be the
4975 ;; same register. It is allowed to conflict with operand 1 as well.
4976
4977 (define_expand "aligned_loadqi"
4978 [(set (match_operand:SI 3 "register_operand" "")
4979 (match_operand:SI 1 "memory_operand" ""))
4980 (set (subreg:DI (match_operand:QI 0 "register_operand" "") 0)
4981 (zero_extract:DI (subreg:DI (match_dup 3) 0)
4982 (const_int 8)
4983 (match_operand:DI 2 "const_int_operand" "")))]
4984
4985 ""
4986 "")
4987
4988 (define_expand "aligned_loadhi"
4989 [(set (match_operand:SI 3 "register_operand" "")
4990 (match_operand:SI 1 "memory_operand" ""))
4991 (set (subreg:DI (match_operand:HI 0 "register_operand" "") 0)
4992 (zero_extract:DI (subreg:DI (match_dup 3) 0)
4993 (const_int 16)
4994 (match_operand:DI 2 "const_int_operand" "")))]
4995
4996 ""
4997 "")
4998
4999 ;; Similar for unaligned loads, where we use the sequence from the
5000 ;; Alpha Architecture manual.
5001 ;;
5002 ;; Operand 1 is the address. Operands 2 and 3 are temporaries, where
5003 ;; operand 3 can overlap the input and output registers.
5004
5005 (define_expand "unaligned_loadqi"
5006 [(set (match_operand:DI 2 "register_operand" "")
5007 (mem:DI (and:DI (match_operand:DI 1 "address_operand" "")
5008 (const_int -8))))
5009 (set (match_operand:DI 3 "register_operand" "")
5010 (match_dup 1))
5011 (set (subreg:DI (match_operand:QI 0 "register_operand" "") 0)
5012 (zero_extract:DI (match_dup 2)
5013 (const_int 8)
5014 (ashift:DI (match_dup 3) (const_int 3))))]
5015 ""
5016 "")
5017
5018 (define_expand "unaligned_loadhi"
5019 [(set (match_operand:DI 2 "register_operand" "")
5020 (mem:DI (and:DI (match_operand:DI 1 "address_operand" "")
5021 (const_int -8))))
5022 (set (match_operand:DI 3 "register_operand" "")
5023 (match_dup 1))
5024 (set (subreg:DI (match_operand:QI 0 "register_operand" "") 0)
5025 (zero_extract:DI (match_dup 2)
5026 (const_int 16)
5027 (ashift:DI (match_dup 3) (const_int 3))))]
5028 ""
5029 "")
5030
5031 ;; Storing an aligned byte or word requires two temporaries. Operand 0 is the
5032 ;; aligned SImode MEM. Operand 1 is the register containing the
5033 ;; byte or word to store. Operand 2 is the number of bits within the word that
5034 ;; the value should be placed. Operands 3 and 4 are SImode temporaries.
5035
5036 (define_expand "aligned_store"
5037 [(set (match_operand:SI 3 "register_operand" "")
5038 (match_operand:SI 0 "memory_operand" ""))
5039 (set (subreg:DI (match_dup 3) 0)
5040 (and:DI (subreg:DI (match_dup 3) 0) (match_dup 5)))
5041 (set (subreg:DI (match_operand:SI 4 "register_operand" "") 0)
5042 (ashift:DI (zero_extend:DI (match_operand 1 "register_operand" ""))
5043 (match_operand:DI 2 "const_int_operand" "")))
5044 (set (subreg:DI (match_dup 4) 0)
5045 (ior:DI (subreg:DI (match_dup 4) 0) (subreg:DI (match_dup 3) 0)))
5046 (set (match_dup 0) (match_dup 4))]
5047 ""
5048 "
5049 { operands[5] = GEN_INT (~ (GET_MODE_MASK (GET_MODE (operands[1]))
5050 << INTVAL (operands[2])));
5051 }")
5052
5053 ;; For the unaligned byte and halfword cases, we use code similar to that
5054 ;; in the ;; Architecture book, but reordered to lower the number of registers
5055 ;; required. Operand 0 is the address. Operand 1 is the data to store.
5056 ;; Operands 2, 3, and 4 are DImode temporaries, where operands 2 and 4 may
5057 ;; be the same temporary, if desired. If the address is in a register,
5058 ;; operand 2 can be that register.
5059
5060 (define_expand "unaligned_storeqi"
5061 [(set (match_operand:DI 3 "register_operand" "")
5062 (mem:DI (and:DI (match_operand:DI 0 "address_operand" "")
5063 (const_int -8))))
5064 (set (match_operand:DI 2 "register_operand" "")
5065 (match_dup 0))
5066 (set (match_dup 3)
5067 (and:DI (not:DI (ashift:DI (const_int 255)
5068 (ashift:DI (match_dup 2) (const_int 3))))
5069 (match_dup 3)))
5070 (set (match_operand:DI 4 "register_operand" "")
5071 (ashift:DI (zero_extend:DI (match_operand:QI 1 "register_operand" ""))
5072 (ashift:DI (match_dup 2) (const_int 3))))
5073 (set (match_dup 4) (ior:DI (match_dup 4) (match_dup 3)))
5074 (set (mem:DI (and:DI (match_dup 0) (const_int -8)))
5075 (match_dup 4))]
5076 ""
5077 "")
5078
5079 (define_expand "unaligned_storehi"
5080 [(set (match_operand:DI 3 "register_operand" "")
5081 (mem:DI (and:DI (match_operand:DI 0 "address_operand" "")
5082 (const_int -8))))
5083 (set (match_operand:DI 2 "register_operand" "")
5084 (match_dup 0))
5085 (set (match_dup 3)
5086 (and:DI (not:DI (ashift:DI (const_int 65535)
5087 (ashift:DI (match_dup 2) (const_int 3))))
5088 (match_dup 3)))
5089 (set (match_operand:DI 4 "register_operand" "")
5090 (ashift:DI (zero_extend:DI (match_operand:HI 1 "register_operand" ""))
5091 (ashift:DI (match_dup 2) (const_int 3))))
5092 (set (match_dup 4) (ior:DI (match_dup 4) (match_dup 3)))
5093 (set (mem:DI (and:DI (match_dup 0) (const_int -8)))
5094 (match_dup 4))]
5095 ""
5096 "")
5097 \f
5098 ;; Here are the define_expand's for QI and HI moves that use the above
5099 ;; patterns. We have the normal sets, plus the ones that need scratch
5100 ;; registers for reload.
5101
5102 (define_expand "movqi"
5103 [(set (match_operand:QI 0 "nonimmediate_operand" "")
5104 (match_operand:QI 1 "general_operand" ""))]
5105 ""
5106 "
5107 {
5108 if (TARGET_BWX)
5109 {
5110 if (GET_CODE (operands[0]) == MEM
5111 && ! reg_or_0_operand (operands[1], QImode))
5112 operands[1] = force_reg (QImode, operands[1]);
5113
5114 if (GET_CODE (operands[1]) == CONST_INT
5115 && ! input_operand (operands[1], QImode))
5116 {
5117 operands[1] = alpha_emit_set_const (operands[0], QImode,
5118 INTVAL (operands[1]), 3);
5119
5120 if (rtx_equal_p (operands[0], operands[1]))
5121 DONE;
5122 }
5123
5124 goto def;
5125 }
5126
5127 /* If the output is not a register, the input must be. */
5128 if (GET_CODE (operands[0]) == MEM)
5129 operands[1] = force_reg (QImode, operands[1]);
5130
5131 /* Handle four memory cases, unaligned and aligned for either the input
5132 or the output. The only case where we can be called during reload is
5133 for aligned loads; all other cases require temporaries. */
5134
5135 if (GET_CODE (operands[1]) == MEM
5136 || (GET_CODE (operands[1]) == SUBREG
5137 && GET_CODE (SUBREG_REG (operands[1])) == MEM)
5138 || (reload_in_progress && GET_CODE (operands[1]) == REG
5139 && REGNO (operands[1]) >= FIRST_PSEUDO_REGISTER)
5140 || (reload_in_progress && GET_CODE (operands[1]) == SUBREG
5141 && GET_CODE (SUBREG_REG (operands[1])) == REG
5142 && REGNO (SUBREG_REG (operands[1])) >= FIRST_PSEUDO_REGISTER))
5143 {
5144 if (aligned_memory_operand (operands[1], QImode))
5145 {
5146 if (reload_in_progress)
5147 {
5148 emit_insn (gen_reload_inqi_help
5149 (operands[0], operands[1],
5150 gen_rtx_REG (SImode, REGNO (operands[0]))));
5151 }
5152 else
5153 {
5154 rtx aligned_mem, bitnum;
5155 rtx scratch = gen_reg_rtx (SImode);
5156
5157 get_aligned_mem (operands[1], &aligned_mem, &bitnum);
5158
5159 emit_insn (gen_aligned_loadqi (operands[0], aligned_mem, bitnum,
5160 scratch));
5161 }
5162 }
5163 else
5164 {
5165 /* Don't pass these as parameters since that makes the generated
5166 code depend on parameter evaluation order which will cause
5167 bootstrap failures. */
5168
5169 rtx temp1 = gen_reg_rtx (DImode);
5170 rtx temp2 = gen_reg_rtx (DImode);
5171 rtx seq
5172 = gen_unaligned_loadqi (operands[0],
5173 get_unaligned_address (operands[1], 0),
5174 temp1, temp2);
5175
5176 alpha_set_memflags (seq, operands[1]);
5177 emit_insn (seq);
5178 }
5179
5180 DONE;
5181 }
5182
5183 else if (GET_CODE (operands[0]) == MEM
5184 || (GET_CODE (operands[0]) == SUBREG
5185 && GET_CODE (SUBREG_REG (operands[0])) == MEM)
5186 || (reload_in_progress && GET_CODE (operands[0]) == REG
5187 && REGNO (operands[0]) >= FIRST_PSEUDO_REGISTER)
5188 || (reload_in_progress && GET_CODE (operands[0]) == SUBREG
5189 && GET_CODE (SUBREG_REG (operands[0])) == REG
5190 && REGNO (operands[0]) >= FIRST_PSEUDO_REGISTER))
5191 {
5192 if (aligned_memory_operand (operands[0], QImode))
5193 {
5194 rtx aligned_mem, bitnum;
5195 rtx temp1 = gen_reg_rtx (SImode);
5196 rtx temp2 = gen_reg_rtx (SImode);
5197
5198 get_aligned_mem (operands[0], &aligned_mem, &bitnum);
5199
5200 emit_insn (gen_aligned_store (aligned_mem, operands[1], bitnum,
5201 temp1, temp2));
5202 }
5203 else
5204 {
5205 rtx temp1 = gen_reg_rtx (DImode);
5206 rtx temp2 = gen_reg_rtx (DImode);
5207 rtx temp3 = gen_reg_rtx (DImode);
5208 rtx seq
5209 = gen_unaligned_storeqi (get_unaligned_address (operands[0], 0),
5210 operands[1], temp1, temp2, temp3);
5211
5212 alpha_set_memflags (seq, operands[0]);
5213 emit_insn (seq);
5214 }
5215 DONE;
5216 }
5217 def:;
5218 }")
5219
5220 (define_expand "movhi"
5221 [(set (match_operand:HI 0 "nonimmediate_operand" "")
5222 (match_operand:HI 1 "general_operand" ""))]
5223 ""
5224 "
5225 {
5226 if (TARGET_BWX)
5227 {
5228 if (GET_CODE (operands[0]) == MEM
5229 && ! reg_or_0_operand (operands[1], HImode))
5230 operands[1] = force_reg (HImode, operands[1]);
5231
5232 if (GET_CODE (operands[1]) == CONST_INT
5233 && ! input_operand (operands[1], HImode))
5234 {
5235 operands[1] = alpha_emit_set_const (operands[0], HImode,
5236 INTVAL (operands[1]), 3);
5237
5238 if (rtx_equal_p (operands[0], operands[1]))
5239 DONE;
5240 }
5241
5242 goto def;
5243 }
5244
5245 /* If the output is not a register, the input must be. */
5246 if (GET_CODE (operands[0]) == MEM)
5247 operands[1] = force_reg (HImode, operands[1]);
5248
5249 /* Handle four memory cases, unaligned and aligned for either the input
5250 or the output. The only case where we can be called during reload is
5251 for aligned loads; all other cases require temporaries. */
5252
5253 if (GET_CODE (operands[1]) == MEM
5254 || (GET_CODE (operands[1]) == SUBREG
5255 && GET_CODE (SUBREG_REG (operands[1])) == MEM)
5256 || (reload_in_progress && GET_CODE (operands[1]) == REG
5257 && REGNO (operands[1]) >= FIRST_PSEUDO_REGISTER)
5258 || (reload_in_progress && GET_CODE (operands[1]) == SUBREG
5259 && GET_CODE (SUBREG_REG (operands[1])) == REG
5260 && REGNO (SUBREG_REG (operands[1])) >= FIRST_PSEUDO_REGISTER))
5261 {
5262 if (aligned_memory_operand (operands[1], HImode))
5263 {
5264 if (reload_in_progress)
5265 {
5266 emit_insn (gen_reload_inhi_help
5267 (operands[0], operands[1],
5268 gen_rtx_REG (SImode, REGNO (operands[0]))));
5269 }
5270 else
5271 {
5272 rtx aligned_mem, bitnum;
5273 rtx scratch = gen_reg_rtx (SImode);
5274
5275 get_aligned_mem (operands[1], &aligned_mem, &bitnum);
5276
5277 emit_insn (gen_aligned_loadhi (operands[0], aligned_mem, bitnum,
5278 scratch));
5279 }
5280 }
5281 else
5282 {
5283 /* Don't pass these as parameters since that makes the generated
5284 code depend on parameter evaluation order which will cause
5285 bootstrap failures. */
5286
5287 rtx temp1 = gen_reg_rtx (DImode);
5288 rtx temp2 = gen_reg_rtx (DImode);
5289 rtx seq
5290 = gen_unaligned_loadhi (operands[0],
5291 get_unaligned_address (operands[1], 0),
5292 temp1, temp2);
5293
5294 alpha_set_memflags (seq, operands[1]);
5295 emit_insn (seq);
5296 }
5297
5298 DONE;
5299 }
5300
5301 else if (GET_CODE (operands[0]) == MEM
5302 || (GET_CODE (operands[0]) == SUBREG
5303 && GET_CODE (SUBREG_REG (operands[0])) == MEM)
5304 || (reload_in_progress && GET_CODE (operands[0]) == REG
5305 && REGNO (operands[0]) >= FIRST_PSEUDO_REGISTER)
5306 || (reload_in_progress && GET_CODE (operands[0]) == SUBREG
5307 && GET_CODE (SUBREG_REG (operands[0])) == REG
5308 && REGNO (operands[0]) >= FIRST_PSEUDO_REGISTER))
5309 {
5310 if (aligned_memory_operand (operands[0], HImode))
5311 {
5312 rtx aligned_mem, bitnum;
5313 rtx temp1 = gen_reg_rtx (SImode);
5314 rtx temp2 = gen_reg_rtx (SImode);
5315
5316 get_aligned_mem (operands[0], &aligned_mem, &bitnum);
5317
5318 emit_insn (gen_aligned_store (aligned_mem, operands[1], bitnum,
5319 temp1, temp2));
5320 }
5321 else
5322 {
5323 rtx temp1 = gen_reg_rtx (DImode);
5324 rtx temp2 = gen_reg_rtx (DImode);
5325 rtx temp3 = gen_reg_rtx (DImode);
5326 rtx seq
5327 = gen_unaligned_storehi (get_unaligned_address (operands[0], 0),
5328 operands[1], temp1, temp2, temp3);
5329
5330 alpha_set_memflags (seq, operands[0]);
5331 emit_insn (seq);
5332 }
5333
5334 DONE;
5335 }
5336 def:;
5337 }")
5338
5339 ;; Here are the versions for reload. Note that in the unaligned cases
5340 ;; we know that the operand must not be a pseudo-register because stack
5341 ;; slots are always aligned references.
5342
5343 (define_expand "reload_inqi"
5344 [(parallel [(match_operand:QI 0 "register_operand" "=r")
5345 (match_operand:QI 1 "any_memory_operand" "m")
5346 (match_operand:TI 2 "register_operand" "=&r")])]
5347 "! TARGET_BWX"
5348 "
5349 {
5350 rtx scratch, seq;
5351
5352 if (GET_CODE (operands[1]) != MEM)
5353 abort ();
5354
5355 if (aligned_memory_operand (operands[1], QImode))
5356 {
5357 seq = gen_reload_inqi_help (operands[0], operands[1],
5358 gen_rtx_REG (SImode, REGNO (operands[2])));
5359 }
5360 else
5361 {
5362 rtx addr;
5363
5364 /* It is possible that one of the registers we got for operands[2]
5365 might coincide with that of operands[0] (which is why we made
5366 it TImode). Pick the other one to use as our scratch. */
5367 if (REGNO (operands[0]) == REGNO (operands[2]))
5368 scratch = gen_rtx_REG (DImode, REGNO (operands[2]) + 1);
5369 else
5370 scratch = gen_rtx_REG (DImode, REGNO (operands[2]));
5371
5372 addr = get_unaligned_address (operands[1], 0);
5373 seq = gen_unaligned_loadqi (operands[0], addr, scratch,
5374 gen_rtx_REG (DImode, REGNO (operands[0])));
5375 alpha_set_memflags (seq, operands[1]);
5376 }
5377 emit_insn (seq);
5378 DONE;
5379 }")
5380
5381 (define_expand "reload_inhi"
5382 [(parallel [(match_operand:HI 0 "register_operand" "=r")
5383 (match_operand:HI 1 "any_memory_operand" "m")
5384 (match_operand:TI 2 "register_operand" "=&r")])]
5385 "! TARGET_BWX"
5386 "
5387 {
5388 rtx scratch, seq;
5389
5390 if (GET_CODE (operands[1]) != MEM)
5391 abort ();
5392
5393 if (aligned_memory_operand (operands[1], HImode))
5394 {
5395 seq = gen_reload_inhi_help (operands[0], operands[1],
5396 gen_rtx_REG (SImode, REGNO (operands[2])));
5397 }
5398 else
5399 {
5400 rtx addr;
5401
5402 /* It is possible that one of the registers we got for operands[2]
5403 might coincide with that of operands[0] (which is why we made
5404 it TImode). Pick the other one to use as our scratch. */
5405 if (REGNO (operands[0]) == REGNO (operands[2]))
5406 scratch = gen_rtx_REG (DImode, REGNO (operands[2]) + 1);
5407 else
5408 scratch = gen_rtx_REG (DImode, REGNO (operands[2]));
5409
5410 addr = get_unaligned_address (operands[1], 0);
5411 seq = gen_unaligned_loadhi (operands[0], addr, scratch,
5412 gen_rtx_REG (DImode, REGNO (operands[0])));
5413 alpha_set_memflags (seq, operands[1]);
5414 }
5415 emit_insn (seq);
5416 DONE;
5417 }")
5418
5419 (define_expand "reload_outqi"
5420 [(parallel [(match_operand:QI 0 "any_memory_operand" "=m")
5421 (match_operand:QI 1 "register_operand" "r")
5422 (match_operand:TI 2 "register_operand" "=&r")])]
5423 "! TARGET_BWX"
5424 "
5425 {
5426 if (GET_CODE (operands[0]) != MEM)
5427 abort ();
5428
5429 if (aligned_memory_operand (operands[0], QImode))
5430 {
5431 emit_insn (gen_reload_outqi_help
5432 (operands[0], operands[1],
5433 gen_rtx_REG (SImode, REGNO (operands[2])),
5434 gen_rtx_REG (SImode, REGNO (operands[2]) + 1)));
5435 }
5436 else
5437 {
5438 rtx addr = get_unaligned_address (operands[0], 0);
5439 rtx scratch1 = gen_rtx_REG (DImode, REGNO (operands[2]));
5440 rtx scratch2 = gen_rtx_REG (DImode, REGNO (operands[2]) + 1);
5441 rtx scratch3 = scratch1;
5442 rtx seq;
5443
5444 if (GET_CODE (addr) == REG)
5445 scratch1 = addr;
5446
5447 seq = gen_unaligned_storeqi (addr, operands[1], scratch1,
5448 scratch2, scratch3);
5449 alpha_set_memflags (seq, operands[0]);
5450 emit_insn (seq);
5451 }
5452 DONE;
5453 }")
5454
5455 (define_expand "reload_outhi"
5456 [(parallel [(match_operand:HI 0 "any_memory_operand" "=m")
5457 (match_operand:HI 1 "register_operand" "r")
5458 (match_operand:TI 2 "register_operand" "=&r")])]
5459 "! TARGET_BWX"
5460 "
5461 {
5462 if (GET_CODE (operands[0]) != MEM)
5463 abort ();
5464
5465 if (aligned_memory_operand (operands[0], HImode))
5466 {
5467 emit_insn (gen_reload_outhi_help
5468 (operands[0], operands[1],
5469 gen_rtx_REG (SImode, REGNO (operands[2])),
5470 gen_rtx_REG (SImode, REGNO (operands[2]) + 1)));
5471 }
5472 else
5473 {
5474 rtx addr = get_unaligned_address (operands[0], 0);
5475 rtx scratch1 = gen_rtx_REG (DImode, REGNO (operands[2]));
5476 rtx scratch2 = gen_rtx_REG (DImode, REGNO (operands[2]) + 1);
5477 rtx scratch3 = scratch1;
5478 rtx seq;
5479
5480 if (GET_CODE (addr) == REG)
5481 scratch1 = addr;
5482
5483 seq = gen_unaligned_storehi (addr, operands[1], scratch1,
5484 scratch2, scratch3);
5485 alpha_set_memflags (seq, operands[0]);
5486 emit_insn (seq);
5487 }
5488 DONE;
5489 }")
5490
5491 ;; Helpers for the above. The way reload is structured, we can't
5492 ;; always get a proper address for a stack slot during reload_foo
5493 ;; expansion, so we must delay our address manipulations until after.
5494
5495 (define_insn "reload_inqi_help"
5496 [(set (match_operand:QI 0 "register_operand" "=r")
5497 (match_operand:QI 1 "memory_operand" "m"))
5498 (clobber (match_operand:SI 2 "register_operand" "=r"))]
5499 "! TARGET_BWX && (reload_in_progress || reload_completed)"
5500 "#")
5501
5502 (define_insn "reload_inhi_help"
5503 [(set (match_operand:HI 0 "register_operand" "=r")
5504 (match_operand:HI 1 "memory_operand" "m"))
5505 (clobber (match_operand:SI 2 "register_operand" "=r"))]
5506 "! TARGET_BWX && (reload_in_progress || reload_completed)"
5507 "#")
5508
5509 (define_insn "reload_outqi_help"
5510 [(set (match_operand:QI 0 "memory_operand" "=m")
5511 (match_operand:QI 1 "register_operand" "r"))
5512 (clobber (match_operand:SI 2 "register_operand" "=r"))
5513 (clobber (match_operand:SI 3 "register_operand" "=r"))]
5514 "! TARGET_BWX && (reload_in_progress || reload_completed)"
5515 "#")
5516
5517 (define_insn "reload_outhi_help"
5518 [(set (match_operand:HI 0 "memory_operand" "=m")
5519 (match_operand:HI 1 "register_operand" "r"))
5520 (clobber (match_operand:SI 2 "register_operand" "=r"))
5521 (clobber (match_operand:SI 3 "register_operand" "=r"))]
5522 "! TARGET_BWX && (reload_in_progress || reload_completed)"
5523 "#")
5524
5525 (define_split
5526 [(set (match_operand:QI 0 "register_operand" "")
5527 (match_operand:QI 1 "memory_operand" ""))
5528 (clobber (match_operand:SI 2 "register_operand" ""))]
5529 "! TARGET_BWX && reload_completed"
5530 [(const_int 0)]
5531 "
5532 {
5533 rtx aligned_mem, bitnum;
5534 get_aligned_mem (operands[1], &aligned_mem, &bitnum);
5535 emit_insn (gen_aligned_loadqi (operands[0], aligned_mem, bitnum,
5536 operands[2]));
5537 DONE;
5538 }")
5539
5540 (define_split
5541 [(set (match_operand:HI 0 "register_operand" "")
5542 (match_operand:HI 1 "memory_operand" ""))
5543 (clobber (match_operand:SI 2 "register_operand" ""))]
5544 "! TARGET_BWX && reload_completed"
5545 [(const_int 0)]
5546 "
5547 {
5548 rtx aligned_mem, bitnum;
5549 get_aligned_mem (operands[1], &aligned_mem, &bitnum);
5550 emit_insn (gen_aligned_loadhi (operands[0], aligned_mem, bitnum,
5551 operands[2]));
5552 DONE;
5553 }")
5554
5555 (define_split
5556 [(set (match_operand:QI 0 "memory_operand" "")
5557 (match_operand:QI 1 "register_operand" ""))
5558 (clobber (match_operand:SI 2 "register_operand" ""))
5559 (clobber (match_operand:SI 3 "register_operand" ""))]
5560 "! TARGET_BWX && reload_completed"
5561 [(const_int 0)]
5562 "
5563 {
5564 rtx aligned_mem, bitnum;
5565 get_aligned_mem (operands[0], &aligned_mem, &bitnum);
5566 emit_insn (gen_aligned_store (aligned_mem, operands[1], bitnum,
5567 operands[2], operands[3]));
5568 DONE;
5569 }")
5570
5571 (define_split
5572 [(set (match_operand:HI 0 "memory_operand" "")
5573 (match_operand:HI 1 "register_operand" ""))
5574 (clobber (match_operand:SI 2 "register_operand" ""))
5575 (clobber (match_operand:SI 3 "register_operand" ""))]
5576 "! TARGET_BWX && reload_completed"
5577 [(const_int 0)]
5578 "
5579 {
5580 rtx aligned_mem, bitnum;
5581 get_aligned_mem (operands[0], &aligned_mem, &bitnum);
5582 emit_insn (gen_aligned_store (aligned_mem, operands[1], bitnum,
5583 operands[2], operands[3]));
5584 DONE;
5585 }")
5586 \f
5587 ;; Bit field extract patterns which use ext[wlq][lh]
5588
5589 (define_expand "extv"
5590 [(set (match_operand:DI 0 "register_operand" "")
5591 (sign_extract:DI (match_operand:QI 1 "memory_operand" "")
5592 (match_operand:DI 2 "immediate_operand" "")
5593 (match_operand:DI 3 "immediate_operand" "")))]
5594 ""
5595 "
5596 {
5597 /* We can do 16, 32 and 64 bit fields, if aligned on byte boundaries. */
5598 if (INTVAL (operands[3]) % 8 != 0
5599 || (INTVAL (operands[2]) != 16
5600 && INTVAL (operands[2]) != 32
5601 && INTVAL (operands[2]) != 64))
5602 FAIL;
5603
5604 /* From mips.md: extract_bit_field doesn't verify that our source
5605 matches the predicate, so we force it to be a MEM here. */
5606 if (GET_CODE (operands[1]) != MEM)
5607 FAIL;
5608
5609 alpha_expand_unaligned_load (operands[0], operands[1],
5610 INTVAL (operands[2]) / 8,
5611 INTVAL (operands[3]) / 8, 1);
5612 DONE;
5613 }")
5614
5615 (define_expand "extzv"
5616 [(set (match_operand:DI 0 "register_operand" "")
5617 (zero_extract:DI (match_operand:DI 1 "nonimmediate_operand" "")
5618 (match_operand:DI 2 "immediate_operand" "")
5619 (match_operand:DI 3 "immediate_operand" "")))]
5620 ""
5621 "
5622 {
5623 /* We can do 8, 16, 32 and 64 bit fields, if aligned on byte boundaries. */
5624 if (INTVAL (operands[3]) % 8 != 0
5625 || (INTVAL (operands[2]) != 8
5626 && INTVAL (operands[2]) != 16
5627 && INTVAL (operands[2]) != 32
5628 && INTVAL (operands[2]) != 64))
5629 FAIL;
5630
5631 if (GET_CODE (operands[1]) == MEM)
5632 {
5633 /* Fail 8 bit fields, falling back on a simple byte load. */
5634 if (INTVAL (operands[2]) == 8)
5635 FAIL;
5636
5637 alpha_expand_unaligned_load (operands[0], operands[1],
5638 INTVAL (operands[2]) / 8,
5639 INTVAL (operands[3]) / 8, 0);
5640 DONE;
5641 }
5642 }")
5643
5644 (define_expand "insv"
5645 [(set (zero_extract:DI (match_operand:QI 0 "memory_operand" "")
5646 (match_operand:DI 1 "immediate_operand" "")
5647 (match_operand:DI 2 "immediate_operand" ""))
5648 (match_operand:DI 3 "register_operand" ""))]
5649 ""
5650 "
5651 {
5652 /* We can do 16, 32 and 64 bit fields, if aligned on byte boundaries. */
5653 if (INTVAL (operands[2]) % 8 != 0
5654 || (INTVAL (operands[1]) != 16
5655 && INTVAL (operands[1]) != 32
5656 && INTVAL (operands[1]) != 64))
5657 FAIL;
5658
5659 /* From mips.md: store_bit_field doesn't verify that our source
5660 matches the predicate, so we force it to be a MEM here. */
5661 if (GET_CODE (operands[0]) != MEM)
5662 FAIL;
5663
5664 alpha_expand_unaligned_store (operands[0], operands[3],
5665 INTVAL (operands[1]) / 8,
5666 INTVAL (operands[2]) / 8);
5667 DONE;
5668 }")
5669
5670
5671
5672 ;; Block move/clear, see alpha.c for more details.
5673 ;; Argument 0 is the destination
5674 ;; Argument 1 is the source
5675 ;; Argument 2 is the length
5676 ;; Argument 3 is the alignment
5677
5678 (define_expand "movstrqi"
5679 [(parallel [(set (match_operand:BLK 0 "memory_operand" "")
5680 (match_operand:BLK 1 "memory_operand" ""))
5681 (use (match_operand:DI 2 "immediate_operand" ""))
5682 (use (match_operand:DI 3 "immediate_operand" ""))])]
5683 ""
5684 "
5685 {
5686 if (alpha_expand_block_move (operands))
5687 DONE;
5688 else
5689 FAIL;
5690 }")
5691
5692 (define_expand "clrstrqi"
5693 [(parallel [(set (match_operand:BLK 0 "memory_operand" "")
5694 (const_int 0))
5695 (use (match_operand:DI 1 "immediate_operand" ""))
5696 (use (match_operand:DI 2 "immediate_operand" ""))])]
5697 ""
5698 "
5699 {
5700 if (alpha_expand_block_clear (operands))
5701 DONE;
5702 else
5703 FAIL;
5704 }")
5705 \f
5706 ;; Subroutine of stack space allocation. Perform a stack probe.
5707 (define_expand "probe_stack"
5708 [(set (match_dup 1) (match_operand:DI 0 "const_int_operand" ""))]
5709 ""
5710 "
5711 {
5712 operands[1] = gen_rtx_MEM (DImode, plus_constant (stack_pointer_rtx,
5713 INTVAL (operands[0])));
5714 MEM_VOLATILE_P (operands[1]) = 1;
5715
5716 operands[0] = const0_rtx;
5717 }")
5718
5719 ;; This is how we allocate stack space. If we are allocating a
5720 ;; constant amount of space and we know it is less than 4096
5721 ;; bytes, we need do nothing.
5722 ;;
5723 ;; If it is more than 4096 bytes, we need to probe the stack
5724 ;; periodically.
5725 (define_expand "allocate_stack"
5726 [(set (reg:DI 30)
5727 (plus:DI (reg:DI 30)
5728 (match_operand:DI 1 "reg_or_cint_operand" "")))
5729 (set (match_operand:DI 0 "register_operand" "=r")
5730 (match_dup 2))]
5731 ""
5732 "
5733 {
5734 if (GET_CODE (operands[1]) == CONST_INT
5735 && INTVAL (operands[1]) < 32768)
5736 {
5737 if (INTVAL (operands[1]) >= 4096)
5738 {
5739 /* We do this the same way as in the prologue and generate explicit
5740 probes. Then we update the stack by the constant. */
5741
5742 int probed = 4096;
5743
5744 emit_insn (gen_probe_stack (GEN_INT (- probed)));
5745 while (probed + 8192 < INTVAL (operands[1]))
5746 emit_insn (gen_probe_stack (GEN_INT (- (probed += 8192))));
5747
5748 if (probed + 4096 < INTVAL (operands[1]))
5749 emit_insn (gen_probe_stack (GEN_INT (- INTVAL(operands[1]))));
5750 }
5751
5752 operands[1] = GEN_INT (- INTVAL (operands[1]));
5753 operands[2] = virtual_stack_dynamic_rtx;
5754 }
5755 else
5756 {
5757 rtx out_label = 0;
5758 rtx loop_label = gen_label_rtx ();
5759 rtx want = gen_reg_rtx (Pmode);
5760 rtx tmp = gen_reg_rtx (Pmode);
5761 rtx memref;
5762
5763 emit_insn (gen_subdi3 (want, stack_pointer_rtx,
5764 force_reg (Pmode, operands[1])));
5765 emit_insn (gen_adddi3 (tmp, stack_pointer_rtx, GEN_INT (-4096)));
5766
5767 if (GET_CODE (operands[1]) != CONST_INT)
5768 {
5769 out_label = gen_label_rtx ();
5770 emit_insn (gen_cmpdi (want, tmp));
5771 emit_jump_insn (gen_bgeu (out_label));
5772 }
5773
5774 emit_label (loop_label);
5775 memref = gen_rtx_MEM (DImode, tmp);
5776 MEM_VOLATILE_P (memref) = 1;
5777 emit_move_insn (memref, const0_rtx);
5778 emit_insn (gen_adddi3 (tmp, tmp, GEN_INT(-8192)));
5779 emit_insn (gen_cmpdi (tmp, want));
5780 emit_jump_insn (gen_bgtu (loop_label));
5781
5782 memref = gen_rtx_MEM (DImode, want);
5783 MEM_VOLATILE_P (memref) = 1;
5784 emit_move_insn (memref, const0_rtx);
5785
5786 if (out_label)
5787 emit_label (out_label);
5788
5789 emit_move_insn (stack_pointer_rtx, want);
5790 emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
5791 DONE;
5792 }
5793 }")
5794
5795 ;; This is used by alpha_expand_prolog to do the same thing as above,
5796 ;; except we cannot at that time generate new basic blocks, so we hide
5797 ;; the loop in this one insn.
5798
5799 (define_insn "prologue_stack_probe_loop"
5800 [(unspec_volatile [(match_operand:DI 0 "register_operand" "r")
5801 (match_operand:DI 1 "register_operand" "r")] 5)]
5802 ""
5803 "*
5804 {
5805 operands[2] = gen_label_rtx ();
5806 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, \"L\",
5807 CODE_LABEL_NUMBER (operands[2]));
5808
5809 return \"stq $31,-8192(%1)\;subq %0,1,%0\;lda %1,-8192(%1)\;bne %0,%l2\";
5810 }"
5811 [(set_attr "length" "16")
5812 (set_attr "type" "multi")])
5813
5814 (define_expand "prologue"
5815 [(clobber (const_int 0))]
5816 ""
5817 "
5818 {
5819 alpha_expand_prologue ();
5820 DONE;
5821 }")
5822
5823 ;; These take care of emitting the ldgp insn in the prologue. This will be
5824 ;; an lda/ldah pair and we want to align them properly. So we have two
5825 ;; unspec_volatile insns, the first of which emits the ldgp assembler macro
5826 ;; and the second of which emits nothing. However, both are marked as type
5827 ;; IADD (the default) so the alignment code in alpha.c does the right thing
5828 ;; with them.
5829
5830 (define_expand "prologue_ldgp"
5831 [(unspec_volatile [(const_int 0)] 9)
5832 (unspec_volatile [(const_int 0)] 10)]
5833 ""
5834 "")
5835
5836 (define_insn "*prologue_ldgp_1"
5837 [(unspec_volatile [(const_int 0)] 9)]
5838 "! TARGET_OPEN_VMS && ! TARGET_WINDOWS_NT"
5839 "ldgp $29,0($27)\\n$%~..ng:")
5840
5841 (define_insn "*prologue_ldgp_2"
5842 [(unspec_volatile [(const_int 0)] 10)]
5843 "! TARGET_OPEN_VMS && ! TARGET_WINDOWS_NT"
5844 "")
5845
5846 ;; The _mcount profiling hook has special calling conventions, and
5847 ;; does not clobber all the registers that a normal call would. So
5848 ;; hide the fact this is a call at all.
5849
5850 (define_insn "prologue_mcount"
5851 [(unspec_volatile [(const_int 0)] 8)]
5852 ""
5853 "lda $28,_mcount\;jsr $28,($28),_mcount"
5854 [(set_attr "type" "multi")
5855 (set_attr "length" "8")])
5856
5857 (define_insn "init_fp"
5858 [(set (match_operand:DI 0 "register_operand" "=r")
5859 (match_operand:DI 1 "register_operand" "r"))
5860 (clobber (mem:BLK (match_operand:DI 2 "register_operand" "=r")))]
5861 ""
5862 "mov %1,%0")
5863
5864 (define_expand "epilogue"
5865 [(return)]
5866 ""
5867 "
5868 {
5869 alpha_expand_epilogue ();
5870 }")
5871
5872 (define_expand "sibcall_epilogue"
5873 [(return)]
5874 "!TARGET_OPEN_VMS && !TARGET_WINDOWS_NT"
5875 "
5876 {
5877 alpha_expand_epilogue ();
5878 DONE;
5879 }")
5880
5881 (define_expand "eh_epilogue"
5882 [(use (match_operand:DI 0 "register_operand" "r"))
5883 (use (match_operand:DI 1 "register_operand" "r"))
5884 (use (match_operand:DI 2 "register_operand" "r"))]
5885 "! TARGET_OPEN_VMS"
5886 "
5887 {
5888 cfun->machine->eh_epilogue_sp_ofs = operands[1];
5889 if (GET_CODE (operands[2]) != REG || REGNO (operands[2]) != 26)
5890 {
5891 rtx ra = gen_rtx_REG (Pmode, 26);
5892 emit_move_insn (ra, operands[2]);
5893 operands[2] = ra;
5894 }
5895 }")
5896
5897 ;; In creating a large stack frame, NT _must_ use ldah+lda to load
5898 ;; the frame size into a register. We use this pattern to ensure
5899 ;; we get lda instead of addq.
5900 (define_insn "nt_lda"
5901 [(set (match_operand:DI 0 "register_operand" "=r")
5902 (unspec:DI [(match_dup 0)
5903 (match_operand:DI 1 "const_int_operand" "n")] 6))]
5904 ""
5905 "lda %0,%1(%0)")
5906
5907 (define_expand "builtin_longjmp"
5908 [(unspec_volatile [(match_operand:DI 0 "register_operand" "r")] 3)]
5909 "! TARGET_OPEN_VMS && ! TARGET_WINDOWS_NT"
5910 "
5911 {
5912 /* The elements of the buffer are, in order: */
5913 rtx fp = gen_rtx_MEM (Pmode, operands[0]);
5914 rtx lab = gen_rtx_MEM (Pmode, plus_constant (operands[0], 8));
5915 rtx stack = gen_rtx_MEM (Pmode, plus_constant (operands[0], 16));
5916 rtx pv = gen_rtx_REG (Pmode, 27);
5917
5918 /* This bit is the same as expand_builtin_longjmp. */
5919 emit_move_insn (hard_frame_pointer_rtx, fp);
5920 emit_move_insn (pv, lab);
5921 emit_stack_restore (SAVE_NONLOCAL, stack, NULL_RTX);
5922 emit_insn (gen_rtx_USE (VOIDmode, hard_frame_pointer_rtx));
5923 emit_insn (gen_rtx_USE (VOIDmode, stack_pointer_rtx));
5924
5925 /* Load the label we are jumping through into $27 so that we know
5926 where to look for it when we get back to setjmp's function for
5927 restoring the gp. */
5928 emit_indirect_jump (pv);
5929 DONE;
5930 }")
5931
5932 (define_insn "builtin_setjmp_receiver"
5933 [(unspec_volatile [(label_ref (match_operand 0 "" ""))] 2)]
5934 "! TARGET_OPEN_VMS && ! TARGET_WINDOWS_NT && TARGET_AS_CAN_SUBTRACT_LABELS"
5935 "\\n$LSJ%=:\;ldgp $29,$LSJ%=-%l0($27)"
5936 [(set_attr "length" "8")
5937 (set_attr "type" "multi")])
5938
5939 (define_insn ""
5940 [(unspec_volatile [(label_ref (match_operand 0 "" ""))] 2)]
5941 "! TARGET_OPEN_VMS && ! TARGET_WINDOWS_NT"
5942 "br $29,$LSJ%=\\n$LSJ%=:\;ldgp $29,0($29)"
5943 [(set_attr "length" "12")
5944 (set_attr "type" "multi")])
5945
5946 (define_insn "exception_receiver"
5947 [(unspec_volatile [(const_int 0)] 7)]
5948 "! TARGET_OPEN_VMS && ! TARGET_WINDOWS_NT"
5949 "br $29,$LSJ%=\\n$LSJ%=:\;ldgp $29,0($29)"
5950 [(set_attr "length" "12")
5951 (set_attr "type" "multi")])
5952
5953 (define_expand "nonlocal_goto_receiver"
5954 [(unspec_volatile [(const_int 0)] 1)
5955 (set (reg:DI 27) (mem:DI (reg:DI 29)))
5956 (unspec_volatile [(const_int 0)] 1)
5957 (use (reg:DI 27))]
5958 "TARGET_OPEN_VMS"
5959 "")
5960
5961 (define_insn "arg_home"
5962 [(unspec [(const_int 0)] 0)
5963 (use (reg:DI 1))
5964 (use (reg:DI 25))
5965 (use (reg:DI 16))
5966 (use (reg:DI 17))
5967 (use (reg:DI 18))
5968 (use (reg:DI 19))
5969 (use (reg:DI 20))
5970 (use (reg:DI 21))
5971 (use (reg:DI 48))
5972 (use (reg:DI 49))
5973 (use (reg:DI 50))
5974 (use (reg:DI 51))
5975 (use (reg:DI 52))
5976 (use (reg:DI 53))
5977 (clobber (mem:BLK (const_int 0)))
5978 (clobber (reg:DI 24))
5979 (clobber (reg:DI 25))
5980 (clobber (reg:DI 0))]
5981 "TARGET_OPEN_VMS"
5982 "lda $0,OTS$HOME_ARGS\;ldq $0,8($0)\;jsr $0,OTS$HOME_ARGS"
5983 [(set_attr "length" "16")
5984 (set_attr "type" "multi")])
5985
5986 ;; Close the trap shadow of preceeding instructions. This is generated
5987 ;; by alpha_reorg.
5988
5989 (define_insn "trapb"
5990 [(unspec_volatile [(const_int 0)] 4)]
5991 ""
5992 "trapb"
5993 [(set_attr "type" "misc")])
5994
5995 ;; No-op instructions used by machine-dependant reorg to preserve
5996 ;; alignment for instruction issue.
5997
5998 (define_insn "nop"
5999 [(const_int 0)]
6000 ""
6001 "nop"
6002 [(set_attr "type" "ilog")])
6003
6004 (define_insn "fnop"
6005 [(const_int 1)]
6006 "TARGET_FP"
6007 "fnop"
6008 [(set_attr "type" "fcpys")])
6009
6010 (define_insn "unop"
6011 [(const_int 2)]
6012 ""
6013 "unop")
6014
6015 (define_insn "realign"
6016 [(unspec_volatile [(match_operand 0 "immediate_operand" "i")] 6)]
6017 ""
6018 ".align %0 #realign")
6019
6020 ;; The call patterns are at the end of the file because their
6021 ;; wildcard operand0 interferes with nice recognition.
6022
6023 (define_insn "*call_value_osf_1"
6024 [(set (match_operand 0 "" "")
6025 (call (mem:DI (match_operand:DI 1 "call_operand" "r,R,i"))
6026 (match_operand 2 "" "")))
6027 (clobber (reg:DI 27))
6028 (clobber (reg:DI 26))]
6029 "! TARGET_WINDOWS_NT && ! TARGET_OPEN_VMS"
6030 "@
6031 jsr $26,($27),0\;ldgp $29,0($26)
6032 bsr $26,$%1..ng
6033 jsr $26,%1\;ldgp $29,0($26)"
6034 [(set_attr "type" "jsr")
6035 (set_attr "length" "12,*,16")])
6036
6037 (define_insn "*sibcall_value_osf_1"
6038 [(set (match_operand 0 "" "")
6039 (call (mem:DI (match_operand:DI 1 "call_operand" "R,i"))
6040 (match_operand 2 "" "")))]
6041 "! TARGET_WINDOWS_NT && ! TARGET_OPEN_VMS"
6042 "@
6043 br $31,$%1..ng
6044 jmp $31,%1"
6045 [(set_attr "type" "jsr")
6046 (set_attr "length" "*,8")])
6047
6048 (define_insn "*call_value_nt_1"
6049 [(set (match_operand 0 "" "")
6050 (call (mem:DI (match_operand:DI 1 "call_operand" "r,R,i"))
6051 (match_operand 2 "" "")))
6052 (clobber (reg:DI 26))]
6053 "TARGET_WINDOWS_NT"
6054 "@
6055 jsr $26,(%1)
6056 bsr $26,%1
6057 jsr $26,%1"
6058 [(set_attr "type" "jsr")
6059 (set_attr "length" "*,*,12")])
6060
6061 (define_insn "*call_value_vms_1"
6062 [(set (match_operand 0 "" "")
6063 (call (mem:DI (match_operand:DI 1 "call_operand" "r,i"))
6064 (match_operand 2 "" "")))
6065 (use (match_operand:DI 3 "nonimmediate_operand" "r,m"))
6066 (use (reg:DI 25))
6067 (use (reg:DI 26))
6068 (clobber (reg:DI 27))]
6069 "TARGET_OPEN_VMS"
6070 "@
6071 mov %3,$27\;jsr $26,0\;ldq $27,0($29)
6072 ldq $27,%3\;jsr $26,%1\;ldq $27,0($29)"
6073 [(set_attr "type" "jsr")
6074 (set_attr "length" "12,16")])
6075 \f
6076 ;; Peepholes go at the end.
6077
6078 ;; Optimize sign-extension of SImode loads. This shows up in the wake of
6079 ;; reload when converting fp->int.
6080
6081 (define_peephole2
6082 [(set (match_operand:SI 0 "hard_int_register_operand" "")
6083 (match_operand:SI 1 "memory_operand" ""))
6084 (set (match_operand:DI 2 "hard_int_register_operand" "")
6085 (sign_extend:DI (match_dup 0)))]
6086 "true_regnum (operands[0]) == true_regnum (operands[2])
6087 || peep2_reg_dead_p (2, operands[0])"
6088 [(set (match_dup 2)
6089 (sign_extend:DI (match_dup 1)))]
6090 "")
6091
6092 (define_peephole2
6093 [(set (match_operand:SI 0 "hard_int_register_operand" "")
6094 (match_operand:SI 1 "hard_fp_register_operand" ""))
6095 (set (match_operand:DI 2 "hard_int_register_operand" "")
6096 (sign_extend:DI (match_dup 0)))]
6097 "TARGET_FIX
6098 && (true_regnum (operands[0]) == true_regnum (operands[2])
6099 || peep2_reg_dead_p (2, operands[0]))"
6100 [(set (match_dup 2)
6101 (sign_extend:DI (match_dup 1)))]
6102 "")
6103
6104 (define_peephole2
6105 [(set (match_operand:DI 0 "hard_fp_register_operand" "")
6106 (sign_extend:DI (match_operand:SI 1 "hard_fp_register_operand" "")))
6107 (set (match_operand:DI 2 "hard_int_register_operand" "")
6108 (match_dup 0))]
6109 "TARGET_FIX && peep2_reg_dead_p (2, operands[0])"
6110 [(set (match_dup 2)
6111 (sign_extend:DI (match_dup 1)))]
6112 "")