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