alpha.h (enum reg_class): Add PV_REG.
[gcc.git] / gcc / config / alpha / alpha.md
1 ;; Machine description for DEC Alpha for GNU C compiler
2 ;; Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
3 ;; 2000 Free Software Foundation, Inc.
4 ;; Contributed by Richard Kenner (kenner@vlsi1.ultra.nyu.edu)
5 ;;
6 ;; This file is part of GNU CC.
7 ;;
8 ;; GNU CC is free software; you can redistribute it and/or modify
9 ;; it under the terms of the GNU General Public License as published by
10 ;; the Free Software Foundation; either version 2, or (at your option)
11 ;; any later version.
12 ;;
13 ;; GNU CC is distributed in the hope that it will be useful,
14 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
15 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 ;; GNU General Public License for more details.
17 ;;
18 ;; You should have received a copy of the GNU General Public License
19 ;; along with GNU CC; see the file COPYING. If not, write to
20 ;; the Free Software Foundation, 59 Temple Place - Suite 330,
21 ;; Boston, MA 02111-1307, USA.
22
23 ;;- See file "rtl.def" for documentation on define_insn, match_*, et. al.
24
25 ;; Uses of UNSPEC in this file:
26 ;;
27 ;; 0 arg_home
28 ;; 1 cttz
29 ;; 2 insxh
30 ;; 3 mskxh
31 ;; 5 cvtql
32 ;; 6 nt_lda
33 ;;
34 ;; UNSPEC_VOLATILE:
35 ;;
36 ;; 0 imb
37 ;; 1 blockage
38 ;; 2 builtin_setjmp_receiver
39 ;; 3 builtin_longjmp
40 ;; 4 trapb
41 ;; 5 prologue_stack_probe_loop
42 ;; 6 realign
43 ;; 7 exception_receiver
44 ;; 8 prologue_mcount
45 ;; 9 prologue_ldgp_1
46 ;; 10 prologue_ldgp_2
47 \f
48 ;; Processor type -- this attribute must exactly match the processor_type
49 ;; enumeration in alpha.h.
50
51 (define_attr "cpu" "ev4,ev5,ev6"
52 (const (symbol_ref "alpha_cpu")))
53
54 ;; Define an insn type attribute. This is used in function unit delay
55 ;; computations, among other purposes. For the most part, we use the names
56 ;; defined in the EV4 documentation, but add a few that we have to know about
57 ;; separately.
58
59 (define_attr "type"
60 "ild,fld,ldsym,ist,fst,ibr,fbr,jsr,iadd,ilog,shift,icmov,fcmov,icmp,imul,fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi"
61 (const_string "iadd"))
62
63 ;; Describe a user's asm statement.
64 (define_asm_attributes
65 [(set_attr "type" "multi")])
66
67 ;; Define the operand size an insn operates on. Used primarily by mul
68 ;; and div operations that have size dependant timings.
69
70 (define_attr "opsize" "si,di,udi" (const_string "di"))
71
72 ;; The TRAP_TYPE attribute marks instructions that may generate traps
73 ;; (which are imprecise and may need a trapb if software completion
74 ;; is desired).
75
76 (define_attr "trap" "no,yes" (const_string "no"))
77
78 ;; The length of an instruction sequence in bytes.
79
80 (define_attr "length" "" (const_int 4))
81 \f
82 ;; On EV4 there are two classes of resources to consider: resources needed
83 ;; to issue, and resources needed to execute. IBUS[01] are in the first
84 ;; category. ABOX, BBOX, EBOX, FBOX, IMUL & FDIV make up the second.
85 ;; (There are a few other register-like resources, but ...)
86
87 ; First, describe all of the issue constraints with single cycle delays.
88 ; All insns need a bus, but all except loads require one or the other.
89 (define_function_unit "ev4_ibus0" 1 0
90 (and (eq_attr "cpu" "ev4")
91 (eq_attr "type" "fst,fbr,iadd,imul,ilog,shift,icmov,icmp"))
92 1 1)
93
94 (define_function_unit "ev4_ibus1" 1 0
95 (and (eq_attr "cpu" "ev4")
96 (eq_attr "type" "ist,ibr,jsr,fadd,fcmov,fcpys,fmul,fdiv,misc"))
97 1 1)
98
99 ; Memory delivers its result in three cycles. Actually return one and
100 ; take care of this in adjust_cost, since we want to handle user-defined
101 ; memory latencies.
102 (define_function_unit "ev4_abox" 1 0
103 (and (eq_attr "cpu" "ev4")
104 (eq_attr "type" "ild,fld,ldsym,ist,fst"))
105 1 1)
106
107 ; Branches have no delay cost, but do tie up the unit for two cycles.
108 (define_function_unit "ev4_bbox" 1 1
109 (and (eq_attr "cpu" "ev4")
110 (eq_attr "type" "ibr,fbr,jsr"))
111 2 2)
112
113 ; Arithmetic insns are normally have their results available after
114 ; two cycles. There are a number of exceptions. They are encoded in
115 ; ADJUST_COST. Some of the other insns have similar exceptions.
116 (define_function_unit "ev4_ebox" 1 0
117 (and (eq_attr "cpu" "ev4")
118 (eq_attr "type" "iadd,ilog,shift,icmov,icmp,misc"))
119 2 1)
120
121 (define_function_unit "imul" 1 0
122 (and (eq_attr "cpu" "ev4")
123 (and (eq_attr "type" "imul")
124 (eq_attr "opsize" "si")))
125 21 19)
126
127 (define_function_unit "imul" 1 0
128 (and (eq_attr "cpu" "ev4")
129 (and (eq_attr "type" "imul")
130 (eq_attr "opsize" "!si")))
131 23 21)
132
133 (define_function_unit "ev4_fbox" 1 0
134 (and (eq_attr "cpu" "ev4")
135 (eq_attr "type" "fadd,fmul,fcpys,fcmov"))
136 6 1)
137
138 (define_function_unit "fdiv" 1 0
139 (and (eq_attr "cpu" "ev4")
140 (and (eq_attr "type" "fdiv")
141 (eq_attr "opsize" "si")))
142 34 30)
143
144 (define_function_unit "fdiv" 1 0
145 (and (eq_attr "cpu" "ev4")
146 (and (eq_attr "type" "fdiv")
147 (eq_attr "opsize" "di")))
148 63 59)
149 \f
150 ;; EV5 scheduling. EV5 can issue 4 insns per clock.
151 ;;
152 ;; EV5 has two asymetric integer units. Model this with E0 & E1 along
153 ;; with the combined resource EBOX.
154
155 (define_function_unit "ev5_ebox" 2 0
156 (and (eq_attr "cpu" "ev5")
157 (eq_attr "type" "!fbr,fcmov,fadd,fmul,fcpys,fdiv"))
158 1 1)
159
160 ; Memory takes at least 2 clocks. Return one from here and fix up with
161 ; user-defined latencies in adjust_cost.
162 (define_function_unit "ev5_ebox" 2 0
163 (and (eq_attr "cpu" "ev5")
164 (eq_attr "type" "ild,fld,ldsym"))
165 1 1)
166
167 ; Loads can dual issue with one another, but loads and stores do not mix.
168 (define_function_unit "ev5_e0" 1 0
169 (and (eq_attr "cpu" "ev5")
170 (eq_attr "type" "ild,fld,ldsym"))
171 1 1
172 [(eq_attr "type" "ist,fst")])
173
174 ; Stores, shifts, multiplies can only issue to E0
175 (define_function_unit "ev5_e0" 1 0
176 (and (eq_attr "cpu" "ev5")
177 (eq_attr "type" "ist,fst,shift,imul"))
178 1 1)
179
180 ; Motion video insns also issue only to E0, and take two ticks.
181 (define_function_unit "ev5_e0" 1 0
182 (and (eq_attr "cpu" "ev5")
183 (eq_attr "type" "mvi"))
184 2 1)
185
186 ; Conditional moves always take 2 ticks.
187 (define_function_unit "ev5_ebox" 2 0
188 (and (eq_attr "cpu" "ev5")
189 (eq_attr "type" "icmov"))
190 2 1)
191
192 ; Branches can only issue to E1
193 (define_function_unit "ev5_e1" 1 0
194 (and (eq_attr "cpu" "ev5")
195 (eq_attr "type" "ibr,jsr"))
196 1 1)
197
198 ; Multiplies also use the integer multiplier.
199 ; ??? How to: "No instruction can be issued to pipe E0 exactly two
200 ; cycles before an integer multiplication completes."
201 (define_function_unit "imul" 1 0
202 (and (eq_attr "cpu" "ev5")
203 (and (eq_attr "type" "imul")
204 (eq_attr "opsize" "si")))
205 8 4)
206
207 (define_function_unit "imul" 1 0
208 (and (eq_attr "cpu" "ev5")
209 (and (eq_attr "type" "imul")
210 (eq_attr "opsize" "di")))
211 12 8)
212
213 (define_function_unit "imul" 1 0
214 (and (eq_attr "cpu" "ev5")
215 (and (eq_attr "type" "imul")
216 (eq_attr "opsize" "udi")))
217 14 8)
218
219 ;; Similarly for the FPU we have two asymetric units. But fcpys can issue
220 ;; on either so we have to play the game again.
221
222 (define_function_unit "ev5_fbox" 2 0
223 (and (eq_attr "cpu" "ev5")
224 (eq_attr "type" "fadd,fcmov,fmul,fcpys,fbr,fdiv"))
225 4 1)
226
227 (define_function_unit "ev5_fm" 1 0
228 (and (eq_attr "cpu" "ev5")
229 (eq_attr "type" "fmul"))
230 4 1)
231
232 ; Add and cmov as you would expect; fbr never produces a result;
233 ; fdiv issues through fa to the divider,
234 (define_function_unit "ev5_fa" 1 0
235 (and (eq_attr "cpu" "ev5")
236 (eq_attr "type" "fadd,fcmov,fbr,fdiv"))
237 4 1)
238
239 ; ??? How to: "No instruction can be issued to pipe FA exactly five
240 ; cycles before a floating point divide completes."
241 (define_function_unit "fdiv" 1 0
242 (and (eq_attr "cpu" "ev5")
243 (and (eq_attr "type" "fdiv")
244 (eq_attr "opsize" "si")))
245 15 15) ; 15 to 31 data dependant
246
247 (define_function_unit "fdiv" 1 0
248 (and (eq_attr "cpu" "ev5")
249 (and (eq_attr "type" "fdiv")
250 (eq_attr "opsize" "di")))
251 22 22) ; 22 to 60 data dependant
252 \f
253 ;; EV6 scheduling. EV6 can issue 4 insns per clock.
254 ;;
255 ;; EV6 has two symmetric pairs ("clusters") of two asymetric integer units
256 ;; ("upper" and "lower"), yielding pipe names U0, U1, L0, L1.
257
258 ;; Conditional moves decompose into two independant primitives, each
259 ;; taking one cycle. Since ev6 is out-of-order, we can't see anything
260 ;; but two cycles.
261 (define_function_unit "ev6_ebox" 4 0
262 (and (eq_attr "cpu" "ev6")
263 (eq_attr "type" "icmov"))
264 2 1)
265
266 (define_function_unit "ev6_ebox" 4 0
267 (and (eq_attr "cpu" "ev6")
268 (eq_attr "type" "!fbr,fcmov,fadd,fmul,fcpys,fdiv,fsqrt"))
269 1 1)
270
271 ;; Integer loads take at least 3 clocks, and only issue to lower units.
272 ;; Return one from here and fix up with user-defined latencies in adjust_cost.
273 (define_function_unit "ev6_l" 2 0
274 (and (eq_attr "cpu" "ev6")
275 (eq_attr "type" "ild,ldsym,ist,fst"))
276 1 1)
277
278 ;; FP loads take at least 4 clocks. Return two from here...
279 (define_function_unit "ev6_l" 2 0
280 (and (eq_attr "cpu" "ev6")
281 (eq_attr "type" "fld"))
282 2 1)
283
284 ;; Motion video insns also issue only to U0, and take three ticks.
285 (define_function_unit "ev6_u0" 1 0
286 (and (eq_attr "cpu" "ev6")
287 (eq_attr "type" "mvi"))
288 3 1)
289
290 (define_function_unit "ev6_u" 2 0
291 (and (eq_attr "cpu" "ev6")
292 (eq_attr "type" "mvi"))
293 3 1)
294
295 ;; Shifts issue to either upper pipe.
296 (define_function_unit "ev6_u" 2 0
297 (and (eq_attr "cpu" "ev6")
298 (eq_attr "type" "shift"))
299 1 1)
300
301 ;; Multiplies issue only to U1, and all take 7 ticks.
302 ;; Rather than create a new function unit just for U1, reuse IMUL
303 (define_function_unit "imul" 1 0
304 (and (eq_attr "cpu" "ev6")
305 (eq_attr "type" "imul"))
306 7 1)
307
308 (define_function_unit "ev6_u" 2 0
309 (and (eq_attr "cpu" "ev6")
310 (eq_attr "type" "imul"))
311 7 1)
312
313 ;; Branches issue to either upper pipe
314 (define_function_unit "ev6_u" 2 0
315 (and (eq_attr "cpu" "ev6")
316 (eq_attr "type" "ibr"))
317 3 1)
318
319 ;; Calls only issue to L0.
320 (define_function_unit "ev6_l0" 1 0
321 (and (eq_attr "cpu" "ev6")
322 (eq_attr "type" "jsr"))
323 1 1)
324
325 (define_function_unit "ev6_l" 2 0
326 (and (eq_attr "cpu" "ev6")
327 (eq_attr "type" "jsr"))
328 1 1)
329
330 ;; Ftoi/itof only issue to lower pipes
331 (define_function_unit "ev6_l" 2 0
332 (and (eq_attr "cpu" "ev6")
333 (eq_attr "type" "ftoi"))
334 3 1)
335
336 (define_function_unit "ev6_l" 2 0
337 (and (eq_attr "cpu" "ev6")
338 (eq_attr "type" "itof"))
339 4 1)
340
341 ;; For the FPU we are very similar to EV5, except there's no insn that
342 ;; can issue to fm & fa, so we get to leave that out.
343
344 (define_function_unit "ev6_fm" 1 0
345 (and (eq_attr "cpu" "ev6")
346 (eq_attr "type" "fmul"))
347 4 1)
348
349 (define_function_unit "ev6_fa" 1 0
350 (and (eq_attr "cpu" "ev6")
351 (eq_attr "type" "fadd,fcpys,fbr,fdiv,fsqrt"))
352 4 1)
353
354 (define_function_unit "ev6_fa" 1 0
355 (and (eq_attr "cpu" "ev6")
356 (eq_attr "type" "fcmov"))
357 8 1)
358
359 (define_function_unit "fdiv" 1 0
360 (and (eq_attr "cpu" "ev6")
361 (and (eq_attr "type" "fdiv")
362 (eq_attr "opsize" "si")))
363 12 10)
364
365 (define_function_unit "fdiv" 1 0
366 (and (eq_attr "cpu" "ev6")
367 (and (eq_attr "type" "fdiv")
368 (eq_attr "opsize" "di")))
369 15 13)
370
371 (define_function_unit "fsqrt" 1 0
372 (and (eq_attr "cpu" "ev6")
373 (and (eq_attr "type" "fsqrt")
374 (eq_attr "opsize" "si")))
375 16 14)
376
377 (define_function_unit "fsqrt" 1 0
378 (and (eq_attr "cpu" "ev6")
379 (and (eq_attr "type" "fsqrt")
380 (eq_attr "opsize" "di")))
381 32 30)
382
383 ; ??? The FPU communicates with memory and the integer register file
384 ; via two fp store units. We need a slot in the fst immediately, and
385 ; a slot in LOW after the operand data is ready. At which point the
386 ; data may be moved either to the store queue or the integer register
387 ; file and the insn retired.
388
389 \f
390 ;; First define the arithmetic insns. Note that the 32-bit forms also
391 ;; sign-extend.
392
393 ;; Handle 32-64 bit extension from memory to a floating point register
394 ;; specially, since this ocurrs frequently in int->double conversions.
395 ;;
396 ;; Note that while we must retain the =f case in the insn for reload's
397 ;; benefit, it should be eliminated after reload, so we should never emit
398 ;; code for that case. But we don't reject the possibility.
399
400 (define_expand "extendsidi2"
401 [(set (match_operand:DI 0 "register_operand" "")
402 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "")))]
403 ""
404 "")
405
406 (define_insn "*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 1 "divmod_operator"
990 [(reg:DI 24) (reg:DI 25)])))
991 (clobber (reg:DI 23))
992 (clobber (reg:DI 28))]
993 "!TARGET_OPEN_VMS"
994 "%E1 $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 1 "divmod_operator"
1001 [(reg:DI 24) (reg:DI 25)]))
1002 (clobber (reg:DI 23))
1003 (clobber (reg:DI 28))]
1004 "!TARGET_OPEN_VMS"
1005 "%E1 $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 "*andnot"
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 ""
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 "
1885 {
1886 int move;
1887 rtx tmp;
1888
1889 alpha_split_tfmode_pair (operands);
1890
1891 move = 1;
1892 if (rtx_equal_p (operands[0], operands[2]))
1893 move = 0;
1894 else if (rtx_equal_p (operands[1], operands[2]))
1895 move = -1;
1896
1897 if (move < 0)
1898 emit_move_insn (operands[0], operands[2]);
1899
1900 tmp = gen_rtx_NOT (DImode, operands[4]);
1901 tmp = gen_rtx_AND (DImode, tmp, operands[3]);
1902 emit_insn (gen_rtx_SET (VOIDmode, operands[1], tmp));
1903
1904 if (move > 0)
1905 emit_move_insn (operands[0], operands[2]);
1906 DONE;
1907 }")
1908
1909 (define_insn "negsf2"
1910 [(set (match_operand:SF 0 "register_operand" "=f")
1911 (neg:SF (match_operand:SF 1 "reg_or_fp0_operand" "fG")))]
1912 "TARGET_FP"
1913 "cpysn %R1,%R1,%0"
1914 [(set_attr "type" "fadd")])
1915
1916 (define_insn "negdf2"
1917 [(set (match_operand:DF 0 "register_operand" "=f")
1918 (neg:DF (match_operand:DF 1 "reg_or_fp0_operand" "fG")))]
1919 "TARGET_FP"
1920 "cpysn %R1,%R1,%0"
1921 [(set_attr "type" "fadd")])
1922
1923 (define_expand "negtf2"
1924 [(parallel [(set (match_operand:TF 0 "register_operand" "")
1925 (neg:TF (match_operand:TF 1 "reg_or_fp0_operand" "")))
1926 (use (match_dup 2))])]
1927 "TARGET_HAS_XFLOATING_LIBS"
1928 "
1929 {
1930 #if HOST_BITS_PER_WIDE_INT >= 64
1931 operands[2] = force_reg (DImode, GEN_INT (0x8000000000000000));
1932 #else
1933 operands[2] = force_reg (DImode, immed_double_const (0, 0x80000000, DImode));
1934 #endif
1935 }")
1936
1937 (define_insn_and_split "*negtf_internal"
1938 [(set (match_operand:TF 0 "register_operand" "=r")
1939 (neg:TF (match_operand:TF 1 "reg_or_fp0_operand" "rG")))
1940 (use (match_operand:DI 2 "register_operand" "=r"))]
1941 "TARGET_HAS_XFLOATING_LIBS"
1942 "#"
1943 "&& reload_completed"
1944 [(const_int 0)]
1945 "
1946 {
1947 int move;
1948
1949 alpha_split_tfmode_pair (operands);
1950
1951 move = 1;
1952 if (rtx_equal_p (operands[0], operands[2]))
1953 move = 0;
1954 else if (rtx_equal_p (operands[1], operands[2]))
1955 move = -1;
1956
1957 if (move < 0)
1958 emit_move_insn (operands[0], operands[2]);
1959
1960 emit_insn (gen_xordi3 (operands[1], operands[3], operands[4]));
1961
1962 if (move > 0)
1963 emit_move_insn (operands[0], operands[2]);
1964 DONE;
1965 }")
1966
1967 (define_insn "*addsf_ieee"
1968 [(set (match_operand:SF 0 "register_operand" "=&f")
1969 (plus:SF (match_operand:SF 1 "reg_or_fp0_operand" "%fG")
1970 (match_operand:SF 2 "reg_or_fp0_operand" "fG")))]
1971 "TARGET_FP && alpha_fptm >= ALPHA_FPTM_SU"
1972 "add%,%)%& %R1,%R2,%0"
1973 [(set_attr "type" "fadd")
1974 (set_attr "trap" "yes")])
1975
1976 (define_insn "addsf3"
1977 [(set (match_operand:SF 0 "register_operand" "=f")
1978 (plus:SF (match_operand:SF 1 "reg_or_fp0_operand" "%fG")
1979 (match_operand:SF 2 "reg_or_fp0_operand" "fG")))]
1980 "TARGET_FP"
1981 "add%,%)%& %R1,%R2,%0"
1982 [(set_attr "type" "fadd")
1983 (set_attr "trap" "yes")])
1984
1985 (define_insn "*adddf_ieee"
1986 [(set (match_operand:DF 0 "register_operand" "=&f")
1987 (plus:DF (match_operand:DF 1 "reg_or_fp0_operand" "%fG")
1988 (match_operand:DF 2 "reg_or_fp0_operand" "fG")))]
1989 "TARGET_FP && alpha_fptm >= ALPHA_FPTM_SU"
1990 "add%-%)%& %R1,%R2,%0"
1991 [(set_attr "type" "fadd")
1992 (set_attr "trap" "yes")])
1993
1994 (define_insn "adddf3"
1995 [(set (match_operand:DF 0 "register_operand" "=f")
1996 (plus:DF (match_operand:DF 1 "reg_or_fp0_operand" "%fG")
1997 (match_operand:DF 2 "reg_or_fp0_operand" "fG")))]
1998 "TARGET_FP"
1999 "add%-%)%& %R1,%R2,%0"
2000 [(set_attr "type" "fadd")
2001 (set_attr "trap" "yes")])
2002
2003 (define_insn "*adddf_ext1"
2004 [(set (match_operand:DF 0 "register_operand" "=f")
2005 (plus:DF (float_extend:DF
2006 (match_operand:SF 1 "reg_or_fp0_operand" "fG"))
2007 (match_operand:DF 2 "reg_or_fp0_operand" "fG")))]
2008 "TARGET_FP && alpha_fptm < ALPHA_FPTM_SU"
2009 "add%-%)%& %R1,%R2,%0"
2010 [(set_attr "type" "fadd")
2011 (set_attr "trap" "yes")])
2012
2013 (define_insn "*adddf_ext2"
2014 [(set (match_operand:DF 0 "register_operand" "=f")
2015 (plus:DF (float_extend:DF
2016 (match_operand:SF 1 "reg_or_fp0_operand" "%fG"))
2017 (float_extend:DF
2018 (match_operand:SF 2 "reg_or_fp0_operand" "fG"))))]
2019 "TARGET_FP && alpha_fptm < ALPHA_FPTM_SU"
2020 "add%-%)%& %R1,%R2,%0"
2021 [(set_attr "type" "fadd")
2022 (set_attr "trap" "yes")])
2023
2024 (define_expand "addtf3"
2025 [(use (match_operand 0 "register_operand" ""))
2026 (use (match_operand 1 "general_operand" ""))
2027 (use (match_operand 2 "general_operand" ""))]
2028 "TARGET_HAS_XFLOATING_LIBS"
2029 "alpha_emit_xfloating_arith (PLUS, operands); DONE;")
2030
2031 ;; Define conversion operators between DFmode and SImode, using the cvtql
2032 ;; instruction. To allow combine et al to do useful things, we keep the
2033 ;; operation as a unit until after reload, at which point we split the
2034 ;; instructions.
2035 ;;
2036 ;; Note that we (attempt to) only consider this optimization when the
2037 ;; ultimate destination is memory. If we will be doing further integer
2038 ;; processing, it is cheaper to do the truncation in the int regs.
2039
2040 (define_insn "*cvtql"
2041 [(set (match_operand:SI 0 "register_operand" "=f")
2042 (unspec:SI [(match_operand:DI 1 "reg_or_fp0_operand" "fG")] 5))]
2043 "TARGET_FP"
2044 "cvtql%` %R1,%0"
2045 [(set_attr "type" "fadd")
2046 (set_attr "trap" "yes")])
2047
2048 (define_insn_and_split "*fix_truncdfsi_ieee"
2049 [(set (match_operand:SI 0 "memory_operand" "=m")
2050 (subreg:SI (fix:DI (match_operand:DF 1 "reg_or_fp0_operand" "fG")) 0))
2051 (clobber (match_scratch:DI 2 "=&f"))
2052 (clobber (match_scratch:SI 3 "=&f"))]
2053 "TARGET_FP && alpha_fptm >= ALPHA_FPTM_SU"
2054 "#"
2055 "&& reload_completed"
2056 [(set (match_dup 2) (fix:DI (match_dup 1)))
2057 (set (match_dup 3) (unspec:SI [(match_dup 2)] 5))
2058 (set (match_dup 0) (match_dup 3))]
2059 ""
2060 [(set_attr "type" "fadd")
2061 (set_attr "trap" "yes")])
2062
2063 (define_insn_and_split "*fix_truncdfsi_internal"
2064 [(set (match_operand:SI 0 "memory_operand" "=m")
2065 (subreg:SI (fix:DI (match_operand:DF 1 "reg_or_fp0_operand" "fG")) 0))
2066 (clobber (match_scratch:DI 2 "=f"))]
2067 "TARGET_FP && alpha_fptm < ALPHA_FPTM_SU"
2068 "#"
2069 "&& reload_completed"
2070 [(set (match_dup 2) (fix:DI (match_dup 1)))
2071 (set (match_dup 3) (unspec:SI [(match_dup 2)] 5))
2072 (set (match_dup 0) (match_dup 3))]
2073 ;; Due to REG_CANNOT_CHANGE_SIZE issues, we cannot simply use SUBREG.
2074 "operands[3] = gen_rtx_REG (SImode, REGNO (operands[2]));"
2075 [(set_attr "type" "fadd")
2076 (set_attr "trap" "yes")])
2077
2078 (define_insn "*fix_truncdfdi_ieee"
2079 [(set (match_operand:DI 0 "reg_no_subreg_operand" "=&f")
2080 (fix:DI (match_operand:DF 1 "reg_or_fp0_operand" "fG")))]
2081 "TARGET_FP && alpha_fptm >= ALPHA_FPTM_SU"
2082 "cvt%-q%(c %R1,%0"
2083 [(set_attr "type" "fadd")
2084 (set_attr "trap" "yes")])
2085
2086 (define_insn "fix_truncdfdi2"
2087 [(set (match_operand:DI 0 "reg_no_subreg_operand" "=f")
2088 (fix:DI (match_operand:DF 1 "reg_or_fp0_operand" "fG")))]
2089 "TARGET_FP"
2090 "cvt%-q%(c %R1,%0"
2091 [(set_attr "type" "fadd")
2092 (set_attr "trap" "yes")])
2093
2094 ;; Likewise between SFmode and SImode.
2095
2096 (define_insn_and_split "*fix_truncsfsi_ieee"
2097 [(set (match_operand:SI 0 "memory_operand" "=m")
2098 (subreg:SI (fix:DI (float_extend:DF
2099 (match_operand:SF 1 "reg_or_fp0_operand" "fG"))) 0))
2100 (clobber (match_scratch:DI 2 "=&f"))
2101 (clobber (match_scratch:SI 3 "=&f"))]
2102 "TARGET_FP && alpha_fptm >= ALPHA_FPTM_SU"
2103 "#"
2104 "&& reload_completed"
2105 [(set (match_dup 2) (fix:DI (float_extend:DF (match_dup 1))))
2106 (set (match_dup 3) (unspec:SI [(match_dup 2)] 5))
2107 (set (match_dup 0) (match_dup 3))]
2108 ""
2109 [(set_attr "type" "fadd")
2110 (set_attr "trap" "yes")])
2111
2112 (define_insn_and_split "*fix_truncsfsi_internal"
2113 [(set (match_operand:SI 0 "memory_operand" "=m")
2114 (subreg:SI (fix:DI (float_extend:DF
2115 (match_operand:SF 1 "reg_or_fp0_operand" "fG"))) 0))
2116 (clobber (match_scratch:DI 2 "=f"))]
2117 "TARGET_FP && alpha_fptm < ALPHA_FPTM_SU"
2118 "#"
2119 "&& reload_completed"
2120 [(set (match_dup 2) (fix:DI (float_extend:DF (match_dup 1))))
2121 (set (match_dup 3) (unspec:SI [(match_dup 2)] 5))
2122 (set (match_dup 0) (match_dup 3))]
2123 ;; Due to REG_CANNOT_CHANGE_SIZE issues, we cannot simply use SUBREG.
2124 "operands[3] = gen_rtx_REG (SImode, REGNO (operands[2]));"
2125 [(set_attr "type" "fadd")
2126 (set_attr "trap" "yes")])
2127
2128 (define_insn "*fix_truncsfdi_ieee"
2129 [(set (match_operand:DI 0 "reg_no_subreg_operand" "=&f")
2130 (fix:DI (float_extend:DF
2131 (match_operand:SF 1 "reg_or_fp0_operand" "fG"))))]
2132 "TARGET_FP && alpha_fptm >= ALPHA_FPTM_SU"
2133 "cvt%-q%(c %R1,%0"
2134 [(set_attr "type" "fadd")
2135 (set_attr "trap" "yes")])
2136
2137 (define_insn "fix_truncsfdi2"
2138 [(set (match_operand:DI 0 "reg_no_subreg_operand" "=f")
2139 (fix:DI (float_extend:DF
2140 (match_operand:SF 1 "reg_or_fp0_operand" "fG"))))]
2141 "TARGET_FP"
2142 "cvt%-q%(c %R1,%0"
2143 [(set_attr "type" "fadd")
2144 (set_attr "trap" "yes")])
2145
2146 (define_expand "fix_trunctfdi2"
2147 [(use (match_operand:DI 0 "register_operand" ""))
2148 (use (match_operand:TF 1 "general_operand" ""))]
2149 "TARGET_HAS_XFLOATING_LIBS"
2150 "alpha_emit_xfloating_cvt (FIX, operands); DONE;")
2151
2152 (define_insn "*floatdisf_ieee"
2153 [(set (match_operand:SF 0 "register_operand" "=&f")
2154 (float:SF (match_operand:DI 1 "reg_no_subreg_operand" "f")))]
2155 "TARGET_FP && alpha_fptm >= ALPHA_FPTM_SU"
2156 "cvtq%,%+%& %1,%0"
2157 [(set_attr "type" "fadd")
2158 (set_attr "trap" "yes")])
2159
2160 (define_insn "floatdisf2"
2161 [(set (match_operand:SF 0 "register_operand" "=f")
2162 (float:SF (match_operand:DI 1 "reg_no_subreg_operand" "f")))]
2163 "TARGET_FP"
2164 "cvtq%,%+%& %1,%0"
2165 [(set_attr "type" "fadd")
2166 (set_attr "trap" "yes")])
2167
2168 (define_insn "*floatdidf_ieee"
2169 [(set (match_operand:DF 0 "register_operand" "=&f")
2170 (float:DF (match_operand:DI 1 "reg_no_subreg_operand" "f")))]
2171 "TARGET_FP && alpha_fptm >= ALPHA_FPTM_SU"
2172 "cvtq%-%+%& %1,%0"
2173 [(set_attr "type" "fadd")
2174 (set_attr "trap" "yes")])
2175
2176 (define_insn "floatdidf2"
2177 [(set (match_operand:DF 0 "register_operand" "=f")
2178 (float:DF (match_operand:DI 1 "reg_no_subreg_operand" "f")))]
2179 "TARGET_FP"
2180 "cvtq%-%+%& %1,%0"
2181 [(set_attr "type" "fadd")
2182 (set_attr "trap" "yes")])
2183
2184 (define_expand "floatditf2"
2185 [(use (match_operand:TF 0 "register_operand" ""))
2186 (use (match_operand:DI 1 "general_operand" ""))]
2187 "TARGET_HAS_XFLOATING_LIBS"
2188 "alpha_emit_xfloating_cvt (FLOAT, operands); DONE;")
2189
2190 (define_expand "floatunsdisf2"
2191 [(use (match_operand:SF 0 "register_operand" ""))
2192 (use (match_operand:DI 1 "register_operand" ""))]
2193 "TARGET_FP"
2194 "alpha_emit_floatuns (operands); DONE;")
2195
2196 (define_expand "floatunsdidf2"
2197 [(use (match_operand:DF 0 "register_operand" ""))
2198 (use (match_operand:DI 1 "register_operand" ""))]
2199 "TARGET_FP"
2200 "alpha_emit_floatuns (operands); DONE;")
2201
2202 (define_expand "floatunsditf2"
2203 [(use (match_operand:TF 0 "register_operand" ""))
2204 (use (match_operand:DI 1 "general_operand" ""))]
2205 "TARGET_HAS_XFLOATING_LIBS"
2206 "alpha_emit_xfloating_cvt (UNSIGNED_FLOAT, operands); DONE;")
2207
2208 (define_expand "extendsfdf2"
2209 [(set (match_operand:DF 0 "register_operand" "")
2210 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "")))]
2211 "TARGET_FP"
2212 "
2213 {
2214 if (alpha_fptm >= ALPHA_FPTM_SU)
2215 operands[1] = force_reg (SFmode, operands[1]);
2216 }")
2217
2218 (define_insn "*extendsfdf2_ieee"
2219 [(set (match_operand:DF 0 "register_operand" "=&f")
2220 (float_extend:DF (match_operand:SF 1 "register_operand" "f")))]
2221 "TARGET_FP && alpha_fptm >= ALPHA_FPTM_SU"
2222 "cvtsts %1,%0"
2223 [(set_attr "type" "fadd")
2224 (set_attr "trap" "yes")])
2225
2226 (define_insn "*extendsfdf2_internal"
2227 [(set (match_operand:DF 0 "register_operand" "=f,f,m")
2228 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "f,m,f")))]
2229 "TARGET_FP && alpha_fptm < ALPHA_FPTM_SU"
2230 "@
2231 fmov %1,%0
2232 ld%, %0,%1
2233 st%- %1,%0"
2234 [(set_attr "type" "fcpys,fld,fst")])
2235
2236 (define_expand "extendsftf2"
2237 [(use (match_operand:TF 0 "register_operand" ""))
2238 (use (match_operand:SF 1 "general_operand" ""))]
2239 "TARGET_HAS_XFLOATING_LIBS"
2240 "
2241 {
2242 rtx tmp = gen_reg_rtx (DFmode);
2243 emit_insn (gen_extendsfdf2 (tmp, operands[1]));
2244 emit_insn (gen_extenddftf2 (operands[0], tmp));
2245 DONE;
2246 }")
2247
2248 (define_expand "extenddftf2"
2249 [(use (match_operand:TF 0 "register_operand" ""))
2250 (use (match_operand:DF 1 "general_operand" ""))]
2251 "TARGET_HAS_XFLOATING_LIBS"
2252 "alpha_emit_xfloating_cvt (FLOAT_EXTEND, operands); DONE;")
2253
2254 (define_insn "*truncdfsf2_ieee"
2255 [(set (match_operand:SF 0 "register_operand" "=&f")
2256 (float_truncate:SF (match_operand:DF 1 "reg_or_fp0_operand" "fG")))]
2257 "TARGET_FP && alpha_fptm >= ALPHA_FPTM_SU"
2258 "cvt%-%,%)%& %R1,%0"
2259 [(set_attr "type" "fadd")
2260 (set_attr "trap" "yes")])
2261
2262 (define_insn "truncdfsf2"
2263 [(set (match_operand:SF 0 "register_operand" "=f")
2264 (float_truncate:SF (match_operand:DF 1 "reg_or_fp0_operand" "fG")))]
2265 "TARGET_FP"
2266 "cvt%-%,%)%& %R1,%0"
2267 [(set_attr "type" "fadd")
2268 (set_attr "trap" "yes")])
2269
2270 (define_expand "trunctfdf2"
2271 [(use (match_operand:DF 0 "register_operand" ""))
2272 (use (match_operand:TF 1 "general_operand" ""))]
2273 "TARGET_HAS_XFLOATING_LIBS"
2274 "alpha_emit_xfloating_cvt (FLOAT_TRUNCATE, operands); DONE;")
2275
2276 (define_expand "trunctfsf2"
2277 [(use (match_operand:SF 0 "register_operand" ""))
2278 (use (match_operand:TF 1 "general_operand" ""))]
2279 "TARGET_FP && TARGET_HAS_XFLOATING_LIBS"
2280 "
2281 {
2282 rtx tmpf, sticky, arg, lo, hi;
2283
2284 tmpf = gen_reg_rtx (DFmode);
2285 sticky = gen_reg_rtx (DImode);
2286 arg = copy_to_mode_reg (TFmode, operands[1]);
2287 lo = gen_lowpart (DImode, arg);
2288 hi = gen_highpart (DImode, arg);
2289
2290 /* Convert the low word of the TFmode value into a sticky rounding bit,
2291 then or it into the low bit of the high word. This leaves the sticky
2292 bit at bit 48 of the fraction, which is representable in DFmode,
2293 which prevents rounding error in the final conversion to SFmode. */
2294
2295 emit_insn (gen_rtx_SET (VOIDmode, sticky,
2296 gen_rtx_NE (DImode, lo, const0_rtx)));
2297 emit_insn (gen_iordi3 (hi, hi, sticky));
2298 emit_insn (gen_trunctfdf2 (tmpf, arg));
2299 emit_insn (gen_truncdfsf2 (operands[0], tmpf));
2300 DONE;
2301 }")
2302
2303 (define_insn "*divsf3_ieee"
2304 [(set (match_operand:SF 0 "register_operand" "=&f")
2305 (div:SF (match_operand:SF 1 "reg_or_fp0_operand" "fG")
2306 (match_operand:SF 2 "reg_or_fp0_operand" "fG")))]
2307 "TARGET_FP && alpha_fptm >= ALPHA_FPTM_SU"
2308 "div%,%)%& %R1,%R2,%0"
2309 [(set_attr "type" "fdiv")
2310 (set_attr "opsize" "si")
2311 (set_attr "trap" "yes")])
2312
2313 (define_insn "divsf3"
2314 [(set (match_operand:SF 0 "register_operand" "=f")
2315 (div:SF (match_operand:SF 1 "reg_or_fp0_operand" "fG")
2316 (match_operand:SF 2 "reg_or_fp0_operand" "fG")))]
2317 "TARGET_FP"
2318 "div%,%)%& %R1,%R2,%0"
2319 [(set_attr "type" "fdiv")
2320 (set_attr "opsize" "si")
2321 (set_attr "trap" "yes")])
2322
2323 (define_insn "*divdf3_ieee"
2324 [(set (match_operand:DF 0 "register_operand" "=&f")
2325 (div:DF (match_operand:DF 1 "reg_or_fp0_operand" "fG")
2326 (match_operand:DF 2 "reg_or_fp0_operand" "fG")))]
2327 "TARGET_FP && alpha_fptm >= ALPHA_FPTM_SU"
2328 "div%-%)%& %R1,%R2,%0"
2329 [(set_attr "type" "fdiv")
2330 (set_attr "trap" "yes")])
2331
2332 (define_insn "divdf3"
2333 [(set (match_operand:DF 0 "register_operand" "=f")
2334 (div:DF (match_operand:DF 1 "reg_or_fp0_operand" "fG")
2335 (match_operand:DF 2 "reg_or_fp0_operand" "fG")))]
2336 "TARGET_FP"
2337 "div%-%)%& %R1,%R2,%0"
2338 [(set_attr "type" "fdiv")
2339 (set_attr "trap" "yes")])
2340
2341 (define_insn "*divdf_ext1"
2342 [(set (match_operand:DF 0 "register_operand" "=f")
2343 (div:DF (float_extend:DF (match_operand:SF 1 "reg_or_fp0_operand" "fG"))
2344 (match_operand:DF 2 "reg_or_fp0_operand" "fG")))]
2345 "TARGET_FP && alpha_fptm < ALPHA_FPTM_SU"
2346 "div%-%)%& %R1,%R2,%0"
2347 [(set_attr "type" "fdiv")
2348 (set_attr "trap" "yes")])
2349
2350 (define_insn "*divdf_ext2"
2351 [(set (match_operand:DF 0 "register_operand" "=f")
2352 (div:DF (match_operand:DF 1 "reg_or_fp0_operand" "fG")
2353 (float_extend:DF
2354 (match_operand:SF 2 "reg_or_fp0_operand" "fG"))))]
2355 "TARGET_FP && alpha_fptm < ALPHA_FPTM_SU"
2356 "div%-%)%& %R1,%R2,%0"
2357 [(set_attr "type" "fdiv")
2358 (set_attr "trap" "yes")])
2359
2360 (define_insn "*divdf_ext3"
2361 [(set (match_operand:DF 0 "register_operand" "=f")
2362 (div:DF (float_extend:DF (match_operand:SF 1 "reg_or_fp0_operand" "fG"))
2363 (float_extend:DF (match_operand:SF 2 "reg_or_fp0_operand" "fG"))))]
2364 "TARGET_FP && alpha_fptm < ALPHA_FPTM_SU"
2365 "div%-%)%& %R1,%R2,%0"
2366 [(set_attr "type" "fdiv")
2367 (set_attr "trap" "yes")])
2368
2369 (define_expand "divtf3"
2370 [(use (match_operand 0 "register_operand" ""))
2371 (use (match_operand 1 "general_operand" ""))
2372 (use (match_operand 2 "general_operand" ""))]
2373 "TARGET_HAS_XFLOATING_LIBS"
2374 "alpha_emit_xfloating_arith (DIV, operands); DONE;")
2375
2376 (define_insn "*mulsf3_ieee"
2377 [(set (match_operand:SF 0 "register_operand" "=&f")
2378 (mult:SF (match_operand:SF 1 "reg_or_fp0_operand" "%fG")
2379 (match_operand:SF 2 "reg_or_fp0_operand" "fG")))]
2380 "TARGET_FP && alpha_fptm >= ALPHA_FPTM_SU"
2381 "mul%,%)%& %R1,%R2,%0"
2382 [(set_attr "type" "fmul")
2383 (set_attr "trap" "yes")])
2384
2385 (define_insn "mulsf3"
2386 [(set (match_operand:SF 0 "register_operand" "=f")
2387 (mult:SF (match_operand:SF 1 "reg_or_fp0_operand" "%fG")
2388 (match_operand:SF 2 "reg_or_fp0_operand" "fG")))]
2389 "TARGET_FP"
2390 "mul%,%)%& %R1,%R2,%0"
2391 [(set_attr "type" "fmul")
2392 (set_attr "trap" "yes")])
2393
2394 (define_insn "*muldf3_ieee"
2395 [(set (match_operand:DF 0 "register_operand" "=&f")
2396 (mult:DF (match_operand:DF 1 "reg_or_fp0_operand" "%fG")
2397 (match_operand:DF 2 "reg_or_fp0_operand" "fG")))]
2398 "TARGET_FP && alpha_fptm >= ALPHA_FPTM_SU"
2399 "mul%-%)%& %R1,%R2,%0"
2400 [(set_attr "type" "fmul")
2401 (set_attr "trap" "yes")])
2402
2403 (define_insn "muldf3"
2404 [(set (match_operand:DF 0 "register_operand" "=f")
2405 (mult:DF (match_operand:DF 1 "reg_or_fp0_operand" "%fG")
2406 (match_operand:DF 2 "reg_or_fp0_operand" "fG")))]
2407 "TARGET_FP"
2408 "mul%-%)%& %R1,%R2,%0"
2409 [(set_attr "type" "fmul")
2410 (set_attr "trap" "yes")])
2411
2412 (define_insn "*muldf_ext1"
2413 [(set (match_operand:DF 0 "register_operand" "=f")
2414 (mult:DF (float_extend:DF
2415 (match_operand:SF 1 "reg_or_fp0_operand" "fG"))
2416 (match_operand:DF 2 "reg_or_fp0_operand" "fG")))]
2417 "TARGET_FP && alpha_fptm < ALPHA_FPTM_SU"
2418 "mul%-%)%& %R1,%R2,%0"
2419 [(set_attr "type" "fmul")
2420 (set_attr "trap" "yes")])
2421
2422 (define_insn "*muldf_ext2"
2423 [(set (match_operand:DF 0 "register_operand" "=f")
2424 (mult:DF (float_extend:DF
2425 (match_operand:SF 1 "reg_or_fp0_operand" "%fG"))
2426 (float_extend:DF
2427 (match_operand:SF 2 "reg_or_fp0_operand" "fG"))))]
2428 "TARGET_FP && alpha_fptm < ALPHA_FPTM_SU"
2429 "mul%-%)%& %R1,%R2,%0"
2430 [(set_attr "type" "fmul")
2431 (set_attr "trap" "yes")])
2432
2433 (define_expand "multf3"
2434 [(use (match_operand 0 "register_operand" ""))
2435 (use (match_operand 1 "general_operand" ""))
2436 (use (match_operand 2 "general_operand" ""))]
2437 "TARGET_HAS_XFLOATING_LIBS"
2438 "alpha_emit_xfloating_arith (MULT, operands); DONE;")
2439
2440 (define_insn "*subsf3_ieee"
2441 [(set (match_operand:SF 0 "register_operand" "=&f")
2442 (minus:SF (match_operand:SF 1 "reg_or_fp0_operand" "fG")
2443 (match_operand:SF 2 "reg_or_fp0_operand" "fG")))]
2444 "TARGET_FP && alpha_fptm >= ALPHA_FPTM_SU"
2445 "sub%,%)%& %R1,%R2,%0"
2446 [(set_attr "type" "fadd")
2447 (set_attr "trap" "yes")])
2448
2449 (define_insn "subsf3"
2450 [(set (match_operand:SF 0 "register_operand" "=f")
2451 (minus:SF (match_operand:SF 1 "reg_or_fp0_operand" "fG")
2452 (match_operand:SF 2 "reg_or_fp0_operand" "fG")))]
2453 "TARGET_FP"
2454 "sub%,%)%& %R1,%R2,%0"
2455 [(set_attr "type" "fadd")
2456 (set_attr "trap" "yes")])
2457
2458 (define_insn "*subdf3_ieee"
2459 [(set (match_operand:DF 0 "register_operand" "=&f")
2460 (minus:DF (match_operand:DF 1 "reg_or_fp0_operand" "fG")
2461 (match_operand:DF 2 "reg_or_fp0_operand" "fG")))]
2462 "TARGET_FP && alpha_fptm >= ALPHA_FPTM_SU"
2463 "sub%-%)%& %R1,%R2,%0"
2464 [(set_attr "type" "fadd")
2465 (set_attr "trap" "yes")])
2466
2467 (define_insn "subdf3"
2468 [(set (match_operand:DF 0 "register_operand" "=f")
2469 (minus:DF (match_operand:DF 1 "reg_or_fp0_operand" "fG")
2470 (match_operand:DF 2 "reg_or_fp0_operand" "fG")))]
2471 "TARGET_FP"
2472 "sub%-%)%& %R1,%R2,%0"
2473 [(set_attr "type" "fadd")
2474 (set_attr "trap" "yes")])
2475
2476 (define_insn "*subdf_ext1"
2477 [(set (match_operand:DF 0 "register_operand" "=f")
2478 (minus:DF (float_extend:DF
2479 (match_operand:SF 1 "reg_or_fp0_operand" "fG"))
2480 (match_operand:DF 2 "reg_or_fp0_operand" "fG")))]
2481 "TARGET_FP && alpha_fptm < ALPHA_FPTM_SU"
2482 "sub%-%)%& %R1,%R2,%0"
2483 [(set_attr "type" "fadd")
2484 (set_attr "trap" "yes")])
2485
2486 (define_insn "*subdf_ext2"
2487 [(set (match_operand:DF 0 "register_operand" "=f")
2488 (minus:DF (match_operand:DF 1 "reg_or_fp0_operand" "fG")
2489 (float_extend:DF
2490 (match_operand:SF 2 "reg_or_fp0_operand" "fG"))))]
2491 "TARGET_FP && alpha_fptm < ALPHA_FPTM_SU"
2492 "sub%-%)%& %R1,%R2,%0"
2493 [(set_attr "type" "fadd")
2494 (set_attr "trap" "yes")])
2495
2496 (define_insn "*subdf_ext3"
2497 [(set (match_operand:DF 0 "register_operand" "=f")
2498 (minus:DF (float_extend:DF
2499 (match_operand:SF 1 "reg_or_fp0_operand" "fG"))
2500 (float_extend:DF
2501 (match_operand:SF 2 "reg_or_fp0_operand" "fG"))))]
2502 "TARGET_FP && alpha_fptm < ALPHA_FPTM_SU"
2503 "sub%-%)%& %R1,%R2,%0"
2504 [(set_attr "type" "fadd")
2505 (set_attr "trap" "yes")])
2506
2507 (define_expand "subtf3"
2508 [(use (match_operand 0 "register_operand" ""))
2509 (use (match_operand 1 "general_operand" ""))
2510 (use (match_operand 2 "general_operand" ""))]
2511 "TARGET_HAS_XFLOATING_LIBS"
2512 "alpha_emit_xfloating_arith (MINUS, operands); DONE;")
2513
2514 (define_insn "*sqrtsf2_ieee"
2515 [(set (match_operand:SF 0 "register_operand" "=&f")
2516 (sqrt:SF (match_operand:SF 1 "reg_or_fp0_operand" "fG")))]
2517 "TARGET_FP && TARGET_FIX && alpha_fptm >= ALPHA_FPTM_SU"
2518 "sqrt%,%)%& %R1,%0"
2519 [(set_attr "type" "fsqrt")
2520 (set_attr "opsize" "si")
2521 (set_attr "trap" "yes")])
2522
2523 (define_insn "sqrtsf2"
2524 [(set (match_operand:SF 0 "register_operand" "=f")
2525 (sqrt:SF (match_operand:SF 1 "reg_or_fp0_operand" "fG")))]
2526 "TARGET_FP && TARGET_FIX"
2527 "sqrt%,%)%& %R1,%0"
2528 [(set_attr "type" "fsqrt")
2529 (set_attr "opsize" "si")
2530 (set_attr "trap" "yes")])
2531
2532 (define_insn "*sqrtdf2_ieee"
2533 [(set (match_operand:DF 0 "register_operand" "=&f")
2534 (sqrt:DF (match_operand:DF 1 "reg_or_fp0_operand" "fG")))]
2535 "TARGET_FP && TARGET_FIX && alpha_fptm >= ALPHA_FPTM_SU"
2536 "sqrt%-%)%& %R1,%0"
2537 [(set_attr "type" "fsqrt")
2538 (set_attr "trap" "yes")])
2539
2540 (define_insn "sqrtdf2"
2541 [(set (match_operand:DF 0 "register_operand" "=f")
2542 (sqrt:DF (match_operand:DF 1 "reg_or_fp0_operand" "fG")))]
2543 "TARGET_FP && TARGET_FIX"
2544 "sqrt%-%)%& %1,%0"
2545 [(set_attr "type" "fsqrt")
2546 (set_attr "trap" "yes")])
2547 \f
2548 ;; Next are all the integer comparisons, and conditional moves and branches
2549 ;; and some of the related define_expand's and define_split's.
2550
2551 (define_insn "*setcc_internal"
2552 [(set (match_operand 0 "register_operand" "=r")
2553 (match_operator 1 "alpha_comparison_operator"
2554 [(match_operand:DI 2 "register_operand" "r")
2555 (match_operand:DI 3 "reg_or_8bit_operand" "rI")]))]
2556 "GET_MODE_CLASS (GET_MODE (operands[0])) == MODE_INT
2557 && GET_MODE_SIZE (GET_MODE (operands[0])) <= 8
2558 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
2559 "cmp%C1 %2,%3,%0"
2560 [(set_attr "type" "icmp")])
2561
2562 ;; Yes, we can technically support reg_or_8bit_operand in operand 2,
2563 ;; but that's non-canonical rtl and allowing that causes inefficiencies
2564 ;; from cse on.
2565 (define_insn "*setcc_swapped_internal"
2566 [(set (match_operand 0 "register_operand" "=r")
2567 (match_operator 1 "alpha_swapped_comparison_operator"
2568 [(match_operand:DI 2 "register_operand" "r")
2569 (match_operand:DI 3 "reg_or_0_operand" "rJ")]))]
2570 "GET_MODE_CLASS (GET_MODE (operands[0])) == MODE_INT
2571 && GET_MODE_SIZE (GET_MODE (operands[0])) <= 8
2572 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
2573 "cmp%c1 %r3,%2,%0"
2574 [(set_attr "type" "icmp")])
2575
2576 ;; Use match_operator rather than ne directly so that we can match
2577 ;; multiple integer modes.
2578 (define_insn "*setne_internal"
2579 [(set (match_operand 0 "register_operand" "=r")
2580 (match_operator 1 "signed_comparison_operator"
2581 [(match_operand:DI 2 "register_operand" "r")
2582 (const_int 0)]))]
2583 "GET_MODE_CLASS (GET_MODE (operands[0])) == MODE_INT
2584 && GET_MODE_SIZE (GET_MODE (operands[0])) <= 8
2585 && GET_CODE (operands[1]) == NE
2586 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
2587 "cmpult $31,%2,%0"
2588 [(set_attr "type" "icmp")])
2589
2590 ;; The mode folding trick can't be used with const_int operands, since
2591 ;; reload needs to know the proper mode.
2592 ;;
2593 ;; Use add_operand instead of the more seemingly natural reg_or_8bit_operand
2594 ;; in order to create more pairs of constants. As long as we're allowing
2595 ;; two constants at the same time, and will have to reload one of them...
2596
2597 (define_insn "*movqicc_internal"
2598 [(set (match_operand:QI 0 "register_operand" "=r,r,r,r")
2599 (if_then_else:QI
2600 (match_operator 2 "signed_comparison_operator"
2601 [(match_operand:DI 3 "reg_or_0_operand" "rJ,rJ,J,J")
2602 (match_operand:DI 4 "reg_or_0_operand" "J,J,rJ,rJ")])
2603 (match_operand:QI 1 "add_operand" "rI,0,rI,0")
2604 (match_operand:QI 5 "add_operand" "0,rI,0,rI")))]
2605 "(operands[3] == const0_rtx || operands[4] == const0_rtx)"
2606 "@
2607 cmov%C2 %r3,%1,%0
2608 cmov%D2 %r3,%5,%0
2609 cmov%c2 %r4,%1,%0
2610 cmov%d2 %r4,%5,%0"
2611 [(set_attr "type" "icmov")])
2612
2613 (define_insn "*movhicc_internal"
2614 [(set (match_operand:HI 0 "register_operand" "=r,r,r,r")
2615 (if_then_else:HI
2616 (match_operator 2 "signed_comparison_operator"
2617 [(match_operand:DI 3 "reg_or_0_operand" "rJ,rJ,J,J")
2618 (match_operand:DI 4 "reg_or_0_operand" "J,J,rJ,rJ")])
2619 (match_operand:HI 1 "add_operand" "rI,0,rI,0")
2620 (match_operand:HI 5 "add_operand" "0,rI,0,rI")))]
2621 "(operands[3] == const0_rtx || operands[4] == const0_rtx)"
2622 "@
2623 cmov%C2 %r3,%1,%0
2624 cmov%D2 %r3,%5,%0
2625 cmov%c2 %r4,%1,%0
2626 cmov%d2 %r4,%5,%0"
2627 [(set_attr "type" "icmov")])
2628
2629 (define_insn "*movsicc_internal"
2630 [(set (match_operand:SI 0 "register_operand" "=r,r,r,r")
2631 (if_then_else:SI
2632 (match_operator 2 "signed_comparison_operator"
2633 [(match_operand:DI 3 "reg_or_0_operand" "rJ,rJ,J,J")
2634 (match_operand:DI 4 "reg_or_0_operand" "J,J,rJ,rJ")])
2635 (match_operand:SI 1 "add_operand" "rI,0,rI,0")
2636 (match_operand:SI 5 "add_operand" "0,rI,0,rI")))]
2637 "(operands[3] == const0_rtx || operands[4] == const0_rtx)"
2638 "@
2639 cmov%C2 %r3,%1,%0
2640 cmov%D2 %r3,%5,%0
2641 cmov%c2 %r4,%1,%0
2642 cmov%d2 %r4,%5,%0"
2643 [(set_attr "type" "icmov")])
2644
2645 (define_insn "*movdicc_internal"
2646 [(set (match_operand:DI 0 "register_operand" "=r,r,r,r")
2647 (if_then_else:DI
2648 (match_operator 2 "signed_comparison_operator"
2649 [(match_operand:DI 3 "reg_or_0_operand" "rJ,rJ,J,J")
2650 (match_operand:DI 4 "reg_or_0_operand" "J,J,rJ,rJ")])
2651 (match_operand:DI 1 "add_operand" "rI,0,rI,0")
2652 (match_operand:DI 5 "add_operand" "0,rI,0,rI")))]
2653 "(operands[3] == const0_rtx || operands[4] == const0_rtx)"
2654 "@
2655 cmov%C2 %r3,%1,%0
2656 cmov%D2 %r3,%5,%0
2657 cmov%c2 %r4,%1,%0
2658 cmov%d2 %r4,%5,%0"
2659 [(set_attr "type" "icmov")])
2660
2661 (define_insn "*movqicc_lbc"
2662 [(set (match_operand:QI 0 "register_operand" "=r,r")
2663 (if_then_else:QI
2664 (eq (zero_extract:DI (match_operand:DI 2 "reg_or_0_operand" "rJ,rJ")
2665 (const_int 1)
2666 (const_int 0))
2667 (const_int 0))
2668 (match_operand:QI 1 "reg_or_8bit_operand" "rI,0")
2669 (match_operand:QI 3 "reg_or_8bit_operand" "0,rI")))]
2670 ""
2671 "@
2672 cmovlbc %r2,%1,%0
2673 cmovlbs %r2,%3,%0"
2674 [(set_attr "type" "icmov")])
2675
2676 (define_insn "*movhicc_lbc"
2677 [(set (match_operand:HI 0 "register_operand" "=r,r")
2678 (if_then_else:HI
2679 (eq (zero_extract:DI (match_operand:DI 2 "reg_or_0_operand" "rJ,rJ")
2680 (const_int 1)
2681 (const_int 0))
2682 (const_int 0))
2683 (match_operand:HI 1 "reg_or_8bit_operand" "rI,0")
2684 (match_operand:HI 3 "reg_or_8bit_operand" "0,rI")))]
2685 ""
2686 "@
2687 cmovlbc %r2,%1,%0
2688 cmovlbs %r2,%3,%0"
2689 [(set_attr "type" "icmov")])
2690
2691 (define_insn "*movsicc_lbc"
2692 [(set (match_operand:SI 0 "register_operand" "=r,r")
2693 (if_then_else:SI
2694 (eq (zero_extract:DI (match_operand:DI 2 "reg_or_0_operand" "rJ,rJ")
2695 (const_int 1)
2696 (const_int 0))
2697 (const_int 0))
2698 (match_operand:SI 1 "reg_or_8bit_operand" "rI,0")
2699 (match_operand:SI 3 "reg_or_8bit_operand" "0,rI")))]
2700 ""
2701 "@
2702 cmovlbc %r2,%1,%0
2703 cmovlbs %r2,%3,%0"
2704 [(set_attr "type" "icmov")])
2705
2706 (define_insn "*movdicc_lbc"
2707 [(set (match_operand:DI 0 "register_operand" "=r,r")
2708 (if_then_else:DI
2709 (eq (zero_extract:DI (match_operand:DI 2 "reg_or_0_operand" "rJ,rJ")
2710 (const_int 1)
2711 (const_int 0))
2712 (const_int 0))
2713 (match_operand:DI 1 "reg_or_8bit_operand" "rI,0")
2714 (match_operand:DI 3 "reg_or_8bit_operand" "0,rI")))]
2715 ""
2716 "@
2717 cmovlbc %r2,%1,%0
2718 cmovlbs %r2,%3,%0"
2719 [(set_attr "type" "icmov")])
2720
2721 (define_insn "*movqicc_lbs"
2722 [(set (match_operand:QI 0 "register_operand" "=r,r")
2723 (if_then_else:QI
2724 (ne (zero_extract:DI (match_operand:DI 2 "reg_or_0_operand" "rJ,rJ")
2725 (const_int 1)
2726 (const_int 0))
2727 (const_int 0))
2728 (match_operand:QI 1 "reg_or_8bit_operand" "rI,0")
2729 (match_operand:QI 3 "reg_or_8bit_operand" "0,rI")))]
2730 ""
2731 "@
2732 cmovlbs %r2,%1,%0
2733 cmovlbc %r2,%3,%0"
2734 [(set_attr "type" "icmov")])
2735
2736 (define_insn "*movhicc_lbs"
2737 [(set (match_operand:HI 0 "register_operand" "=r,r")
2738 (if_then_else:HI
2739 (ne (zero_extract:DI (match_operand:DI 2 "reg_or_0_operand" "rJ,rJ")
2740 (const_int 1)
2741 (const_int 0))
2742 (const_int 0))
2743 (match_operand:HI 1 "reg_or_8bit_operand" "rI,0")
2744 (match_operand:HI 3 "reg_or_8bit_operand" "0,rI")))]
2745 ""
2746 "@
2747 cmovlbs %r2,%1,%0
2748 cmovlbc %r2,%3,%0"
2749 [(set_attr "type" "icmov")])
2750
2751 (define_insn "*movsicc_lbs"
2752 [(set (match_operand:SI 0 "register_operand" "=r,r")
2753 (if_then_else:SI
2754 (ne (zero_extract:DI (match_operand:DI 2 "reg_or_0_operand" "rJ,rJ")
2755 (const_int 1)
2756 (const_int 0))
2757 (const_int 0))
2758 (match_operand:SI 1 "reg_or_8bit_operand" "rI,0")
2759 (match_operand:SI 3 "reg_or_8bit_operand" "0,rI")))]
2760 ""
2761 "@
2762 cmovlbs %r2,%1,%0
2763 cmovlbc %r2,%3,%0"
2764 [(set_attr "type" "icmov")])
2765
2766 (define_insn "*movdicc_lbs"
2767 [(set (match_operand:DI 0 "register_operand" "=r,r")
2768 (if_then_else:DI
2769 (ne (zero_extract:DI (match_operand:DI 2 "reg_or_0_operand" "rJ,rJ")
2770 (const_int 1)
2771 (const_int 0))
2772 (const_int 0))
2773 (match_operand:DI 1 "reg_or_8bit_operand" "rI,0")
2774 (match_operand:DI 3 "reg_or_8bit_operand" "0,rI")))]
2775 ""
2776 "@
2777 cmovlbs %r2,%1,%0
2778 cmovlbc %r2,%3,%0"
2779 [(set_attr "type" "icmov")])
2780
2781 ;; For ABS, we have two choices, depending on whether the input and output
2782 ;; registers are the same or not.
2783 (define_expand "absdi2"
2784 [(set (match_operand:DI 0 "register_operand" "")
2785 (abs:DI (match_operand:DI 1 "register_operand" "")))]
2786 ""
2787 "
2788 { if (rtx_equal_p (operands[0], operands[1]))
2789 emit_insn (gen_absdi2_same (operands[0], gen_reg_rtx (DImode)));
2790 else
2791 emit_insn (gen_absdi2_diff (operands[0], operands[1]));
2792
2793 DONE;
2794 }")
2795
2796 (define_expand "absdi2_same"
2797 [(set (match_operand:DI 1 "register_operand" "")
2798 (neg:DI (match_operand:DI 0 "register_operand" "")))
2799 (set (match_dup 0)
2800 (if_then_else:DI (ge (match_dup 0) (const_int 0))
2801 (match_dup 0)
2802 (match_dup 1)))]
2803 ""
2804 "")
2805
2806 (define_expand "absdi2_diff"
2807 [(set (match_operand:DI 0 "register_operand" "")
2808 (neg:DI (match_operand:DI 1 "register_operand" "")))
2809 (set (match_dup 0)
2810 (if_then_else:DI (lt (match_dup 1) (const_int 0))
2811 (match_dup 0)
2812 (match_dup 1)))]
2813 ""
2814 "")
2815
2816 (define_split
2817 [(set (match_operand:DI 0 "register_operand" "")
2818 (abs:DI (match_dup 0)))
2819 (clobber (match_operand:DI 1 "register_operand" ""))]
2820 ""
2821 [(set (match_dup 1) (neg:DI (match_dup 0)))
2822 (set (match_dup 0) (if_then_else:DI (ge (match_dup 0) (const_int 0))
2823 (match_dup 0) (match_dup 1)))]
2824 "")
2825
2826 (define_split
2827 [(set (match_operand:DI 0 "register_operand" "")
2828 (abs:DI (match_operand:DI 1 "register_operand" "")))]
2829 "! rtx_equal_p (operands[0], operands[1])"
2830 [(set (match_dup 0) (neg:DI (match_dup 1)))
2831 (set (match_dup 0) (if_then_else:DI (lt (match_dup 1) (const_int 0))
2832 (match_dup 0) (match_dup 1)))]
2833 "")
2834
2835 (define_split
2836 [(set (match_operand:DI 0 "register_operand" "")
2837 (neg:DI (abs:DI (match_dup 0))))
2838 (clobber (match_operand:DI 1 "register_operand" ""))]
2839 ""
2840 [(set (match_dup 1) (neg:DI (match_dup 0)))
2841 (set (match_dup 0) (if_then_else:DI (le (match_dup 0) (const_int 0))
2842 (match_dup 0) (match_dup 1)))]
2843 "")
2844
2845 (define_split
2846 [(set (match_operand:DI 0 "register_operand" "")
2847 (neg:DI (abs:DI (match_operand:DI 1 "register_operand" ""))))]
2848 "! rtx_equal_p (operands[0], operands[1])"
2849 [(set (match_dup 0) (neg:DI (match_dup 1)))
2850 (set (match_dup 0) (if_then_else:DI (gt (match_dup 1) (const_int 0))
2851 (match_dup 0) (match_dup 1)))]
2852 "")
2853
2854 (define_insn "sminqi3"
2855 [(set (match_operand:QI 0 "register_operand" "=r")
2856 (smin:QI (match_operand:QI 1 "reg_or_0_operand" "%rJ")
2857 (match_operand:QI 2 "reg_or_8bit_operand" "rI")))]
2858 "TARGET_MAX"
2859 "minsb8 %r1,%2,%0"
2860 [(set_attr "type" "mvi")])
2861
2862 (define_insn "uminqi3"
2863 [(set (match_operand:QI 0 "register_operand" "=r")
2864 (umin:QI (match_operand:QI 1 "reg_or_0_operand" "%rJ")
2865 (match_operand:QI 2 "reg_or_8bit_operand" "rI")))]
2866 "TARGET_MAX"
2867 "minub8 %r1,%2,%0"
2868 [(set_attr "type" "mvi")])
2869
2870 (define_insn "smaxqi3"
2871 [(set (match_operand:QI 0 "register_operand" "=r")
2872 (smax:QI (match_operand:QI 1 "reg_or_0_operand" "%rJ")
2873 (match_operand:QI 2 "reg_or_8bit_operand" "rI")))]
2874 "TARGET_MAX"
2875 "maxsb8 %r1,%2,%0"
2876 [(set_attr "type" "mvi")])
2877
2878 (define_insn "umaxqi3"
2879 [(set (match_operand:QI 0 "register_operand" "=r")
2880 (umax:QI (match_operand:QI 1 "reg_or_0_operand" "%rJ")
2881 (match_operand:QI 2 "reg_or_8bit_operand" "rI")))]
2882 "TARGET_MAX"
2883 "maxub8 %r1,%2,%0"
2884 [(set_attr "type" "mvi")])
2885
2886 (define_insn "sminhi3"
2887 [(set (match_operand:HI 0 "register_operand" "=r")
2888 (smin:HI (match_operand:HI 1 "reg_or_0_operand" "%rJ")
2889 (match_operand:HI 2 "reg_or_8bit_operand" "rI")))]
2890 "TARGET_MAX"
2891 "minsw4 %r1,%2,%0"
2892 [(set_attr "type" "mvi")])
2893
2894 (define_insn "uminhi3"
2895 [(set (match_operand:HI 0 "register_operand" "=r")
2896 (umin:HI (match_operand:HI 1 "reg_or_0_operand" "%rJ")
2897 (match_operand:HI 2 "reg_or_8bit_operand" "rI")))]
2898 "TARGET_MAX"
2899 "minuw4 %r1,%2,%0"
2900 [(set_attr "type" "mvi")])
2901
2902 (define_insn "smaxhi3"
2903 [(set (match_operand:HI 0 "register_operand" "=r")
2904 (smax:HI (match_operand:HI 1 "reg_or_0_operand" "%rJ")
2905 (match_operand:HI 2 "reg_or_8bit_operand" "rI")))]
2906 "TARGET_MAX"
2907 "maxsw4 %r1,%2,%0"
2908 [(set_attr "type" "mvi")])
2909
2910 (define_insn "umaxhi3"
2911 [(set (match_operand:HI 0 "register_operand" "=r")
2912 (umax:HI (match_operand:HI 1 "reg_or_0_operand" "%rJ")
2913 (match_operand:HI 2 "reg_or_8bit_operand" "rI")))]
2914 "TARGET_MAX"
2915 "maxuw4 %r1,%2,%0"
2916 [(set_attr "type" "shift")])
2917
2918 (define_expand "smaxdi3"
2919 [(set (match_dup 3)
2920 (le:DI (match_operand:DI 1 "reg_or_0_operand" "")
2921 (match_operand:DI 2 "reg_or_8bit_operand" "")))
2922 (set (match_operand:DI 0 "register_operand" "")
2923 (if_then_else:DI (eq (match_dup 3) (const_int 0))
2924 (match_dup 1) (match_dup 2)))]
2925 ""
2926 "
2927 { operands[3] = gen_reg_rtx (DImode);
2928 }")
2929
2930 (define_split
2931 [(set (match_operand:DI 0 "register_operand" "")
2932 (smax:DI (match_operand:DI 1 "reg_or_0_operand" "")
2933 (match_operand:DI 2 "reg_or_8bit_operand" "")))
2934 (clobber (match_operand:DI 3 "register_operand" ""))]
2935 "operands[2] != const0_rtx"
2936 [(set (match_dup 3) (le:DI (match_dup 1) (match_dup 2)))
2937 (set (match_dup 0) (if_then_else:DI (eq (match_dup 3) (const_int 0))
2938 (match_dup 1) (match_dup 2)))]
2939 "")
2940
2941 (define_insn "*smax_const0"
2942 [(set (match_operand:DI 0 "register_operand" "=r")
2943 (smax:DI (match_operand:DI 1 "register_operand" "0")
2944 (const_int 0)))]
2945 ""
2946 "cmovlt %0,0,%0"
2947 [(set_attr "type" "icmov")])
2948
2949 (define_expand "smindi3"
2950 [(set (match_dup 3)
2951 (lt:DI (match_operand:DI 1 "reg_or_0_operand" "")
2952 (match_operand:DI 2 "reg_or_8bit_operand" "")))
2953 (set (match_operand:DI 0 "register_operand" "")
2954 (if_then_else:DI (ne (match_dup 3) (const_int 0))
2955 (match_dup 1) (match_dup 2)))]
2956 ""
2957 "
2958 { operands[3] = gen_reg_rtx (DImode);
2959 }")
2960
2961 (define_split
2962 [(set (match_operand:DI 0 "register_operand" "")
2963 (smin:DI (match_operand:DI 1 "reg_or_0_operand" "")
2964 (match_operand:DI 2 "reg_or_8bit_operand" "")))
2965 (clobber (match_operand:DI 3 "register_operand" ""))]
2966 "operands[2] != const0_rtx"
2967 [(set (match_dup 3) (lt:DI (match_dup 1) (match_dup 2)))
2968 (set (match_dup 0) (if_then_else:DI (ne (match_dup 3) (const_int 0))
2969 (match_dup 1) (match_dup 2)))]
2970 "")
2971
2972 (define_insn "*smin_const0"
2973 [(set (match_operand:DI 0 "register_operand" "=r")
2974 (smin:DI (match_operand:DI 1 "register_operand" "0")
2975 (const_int 0)))]
2976 ""
2977 "cmovgt %0,0,%0"
2978 [(set_attr "type" "icmov")])
2979
2980 (define_expand "umaxdi3"
2981 [(set (match_dup 3)
2982 (leu:DI (match_operand:DI 1 "reg_or_0_operand" "")
2983 (match_operand:DI 2 "reg_or_8bit_operand" "")))
2984 (set (match_operand:DI 0 "register_operand" "")
2985 (if_then_else:DI (eq (match_dup 3) (const_int 0))
2986 (match_dup 1) (match_dup 2)))]
2987 ""
2988 "operands[3] = gen_reg_rtx (DImode);")
2989
2990 (define_split
2991 [(set (match_operand:DI 0 "register_operand" "")
2992 (umax:DI (match_operand:DI 1 "reg_or_0_operand" "")
2993 (match_operand:DI 2 "reg_or_8bit_operand" "")))
2994 (clobber (match_operand:DI 3 "register_operand" ""))]
2995 "operands[2] != const0_rtx"
2996 [(set (match_dup 3) (leu:DI (match_dup 1) (match_dup 2)))
2997 (set (match_dup 0) (if_then_else:DI (eq (match_dup 3) (const_int 0))
2998 (match_dup 1) (match_dup 2)))]
2999 "")
3000
3001 (define_expand "umindi3"
3002 [(set (match_dup 3)
3003 (ltu:DI (match_operand:DI 1 "reg_or_0_operand" "")
3004 (match_operand:DI 2 "reg_or_8bit_operand" "")))
3005 (set (match_operand:DI 0 "register_operand" "")
3006 (if_then_else:DI (ne (match_dup 3) (const_int 0))
3007 (match_dup 1) (match_dup 2)))]
3008 ""
3009 "operands[3] = gen_reg_rtx (DImode);")
3010
3011 (define_split
3012 [(set (match_operand:DI 0 "register_operand" "")
3013 (umin:DI (match_operand:DI 1 "reg_or_0_operand" "")
3014 (match_operand:DI 2 "reg_or_8bit_operand" "")))
3015 (clobber (match_operand:DI 3 "register_operand" ""))]
3016 "operands[2] != const0_rtx"
3017 [(set (match_dup 3) (ltu:DI (match_dup 1) (match_dup 2)))
3018 (set (match_dup 0) (if_then_else:DI (ne (match_dup 3) (const_int 0))
3019 (match_dup 1) (match_dup 2)))]
3020 "")
3021
3022 (define_insn "*bcc_normal"
3023 [(set (pc)
3024 (if_then_else
3025 (match_operator 1 "signed_comparison_operator"
3026 [(match_operand:DI 2 "reg_or_0_operand" "rJ")
3027 (const_int 0)])
3028 (label_ref (match_operand 0 "" ""))
3029 (pc)))]
3030 ""
3031 "b%C1 %r2,%0"
3032 [(set_attr "type" "ibr")])
3033
3034 (define_insn "*bcc_reverse"
3035 [(set (pc)
3036 (if_then_else
3037 (match_operator 1 "signed_comparison_operator"
3038 [(match_operand:DI 2 "register_operand" "r")
3039 (const_int 0)])
3040
3041 (pc)
3042 (label_ref (match_operand 0 "" ""))))]
3043 ""
3044 "b%c1 %2,%0"
3045 [(set_attr "type" "ibr")])
3046
3047 (define_insn "*blbs_normal"
3048 [(set (pc)
3049 (if_then_else
3050 (ne (zero_extract:DI (match_operand:DI 1 "reg_or_0_operand" "rJ")
3051 (const_int 1)
3052 (const_int 0))
3053 (const_int 0))
3054 (label_ref (match_operand 0 "" ""))
3055 (pc)))]
3056 ""
3057 "blbs %r1,%0"
3058 [(set_attr "type" "ibr")])
3059
3060 (define_insn "*blbc_normal"
3061 [(set (pc)
3062 (if_then_else
3063 (eq (zero_extract:DI (match_operand:DI 1 "reg_or_0_operand" "rJ")
3064 (const_int 1)
3065 (const_int 0))
3066 (const_int 0))
3067 (label_ref (match_operand 0 "" ""))
3068 (pc)))]
3069 ""
3070 "blbc %r1,%0"
3071 [(set_attr "type" "ibr")])
3072
3073 (define_split
3074 [(parallel
3075 [(set (pc)
3076 (if_then_else
3077 (match_operator 1 "comparison_operator"
3078 [(zero_extract:DI (match_operand:DI 2 "register_operand" "")
3079 (const_int 1)
3080 (match_operand:DI 3 "const_int_operand" ""))
3081 (const_int 0)])
3082 (label_ref (match_operand 0 "" ""))
3083 (pc)))
3084 (clobber (match_operand:DI 4 "register_operand" ""))])]
3085 "INTVAL (operands[3]) != 0"
3086 [(set (match_dup 4)
3087 (lshiftrt:DI (match_dup 2) (match_dup 3)))
3088 (set (pc)
3089 (if_then_else (match_op_dup 1
3090 [(zero_extract:DI (match_dup 4)
3091 (const_int 1)
3092 (const_int 0))
3093 (const_int 0)])
3094 (label_ref (match_dup 0))
3095 (pc)))]
3096 "")
3097 \f
3098 ;; The following are the corresponding floating-point insns. Recall
3099 ;; we need to have variants that expand the arguments from SFmode
3100 ;; to DFmode.
3101
3102 (define_insn "*cmpdf_ieee"
3103 [(set (match_operand:DF 0 "register_operand" "=&f")
3104 (match_operator:DF 1 "alpha_fp_comparison_operator"
3105 [(match_operand:DF 2 "reg_or_fp0_operand" "fG")
3106 (match_operand:DF 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_internal"
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 (match_operand:DF 3 "reg_or_fp0_operand" "fG")]))]
3117 "TARGET_FP && alpha_fptm < ALPHA_FPTM_SU"
3118 "cmp%-%C1%' %R2,%R3,%0"
3119 [(set_attr "type" "fadd")
3120 (set_attr "trap" "yes")])
3121
3122 (define_insn "*cmpdf_ieee_ext1"
3123 [(set (match_operand:DF 0 "register_operand" "=&f")
3124 (match_operator:DF 1 "alpha_fp_comparison_operator"
3125 [(float_extend:DF
3126 (match_operand:SF 2 "reg_or_fp0_operand" "fG"))
3127 (match_operand:DF 3 "reg_or_fp0_operand" "fG")]))]
3128 "TARGET_FP && alpha_fptm >= ALPHA_FPTM_SU"
3129 "cmp%-%C1%' %R2,%R3,%0"
3130 [(set_attr "type" "fadd")
3131 (set_attr "trap" "yes")])
3132
3133 (define_insn "*cmpdf_ext1"
3134 [(set (match_operand:DF 0 "register_operand" "=f")
3135 (match_operator:DF 1 "alpha_fp_comparison_operator"
3136 [(float_extend:DF
3137 (match_operand:SF 2 "reg_or_fp0_operand" "fG"))
3138 (match_operand:DF 3 "reg_or_fp0_operand" "fG")]))]
3139 "TARGET_FP && alpha_fptm < ALPHA_FPTM_SU"
3140 "cmp%-%C1%' %R2,%R3,%0"
3141 [(set_attr "type" "fadd")
3142 (set_attr "trap" "yes")])
3143
3144 (define_insn "*cmpdf_ieee_ext2"
3145 [(set (match_operand:DF 0 "register_operand" "=&f")
3146 (match_operator:DF 1 "alpha_fp_comparison_operator"
3147 [(match_operand:DF 2 "reg_or_fp0_operand" "fG")
3148 (float_extend:DF
3149 (match_operand:SF 3 "reg_or_fp0_operand" "fG"))]))]
3150 "TARGET_FP && alpha_fptm >= ALPHA_FPTM_SU"
3151 "cmp%-%C1%' %R2,%R3,%0"
3152 [(set_attr "type" "fadd")
3153 (set_attr "trap" "yes")])
3154
3155 (define_insn "*cmpdf_ext2"
3156 [(set (match_operand:DF 0 "register_operand" "=f")
3157 (match_operator:DF 1 "alpha_fp_comparison_operator"
3158 [(match_operand:DF 2 "reg_or_fp0_operand" "fG")
3159 (float_extend:DF
3160 (match_operand:SF 3 "reg_or_fp0_operand" "fG"))]))]
3161 "TARGET_FP && alpha_fptm < ALPHA_FPTM_SU"
3162 "cmp%-%C1%' %R2,%R3,%0"
3163 [(set_attr "type" "fadd")
3164 (set_attr "trap" "yes")])
3165
3166 (define_insn "*cmpdf_ieee_ext3"
3167 [(set (match_operand:DF 0 "register_operand" "=&f")
3168 (match_operator:DF 1 "alpha_fp_comparison_operator"
3169 [(float_extend:DF
3170 (match_operand:SF 2 "reg_or_fp0_operand" "fG"))
3171 (float_extend:DF
3172 (match_operand:SF 3 "reg_or_fp0_operand" "fG"))]))]
3173 "TARGET_FP && alpha_fptm >= ALPHA_FPTM_SU"
3174 "cmp%-%C1%' %R2,%R3,%0"
3175 [(set_attr "type" "fadd")
3176 (set_attr "trap" "yes")])
3177
3178 (define_insn "*cmpdf_ext3"
3179 [(set (match_operand:DF 0 "register_operand" "=f")
3180 (match_operator:DF 1 "alpha_fp_comparison_operator"
3181 [(float_extend:DF
3182 (match_operand:SF 2 "reg_or_fp0_operand" "fG"))
3183 (float_extend:DF
3184 (match_operand:SF 3 "reg_or_fp0_operand" "fG"))]))]
3185 "TARGET_FP && alpha_fptm < ALPHA_FPTM_SU"
3186 "cmp%-%C1%' %R2,%R3,%0"
3187 [(set_attr "type" "fadd")
3188 (set_attr "trap" "yes")])
3189
3190 (define_insn "*movdfcc_internal"
3191 [(set (match_operand:DF 0 "register_operand" "=f,f")
3192 (if_then_else:DF
3193 (match_operator 3 "signed_comparison_operator"
3194 [(match_operand:DF 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 "*movsfcc_internal"
3205 [(set (match_operand:SF 0 "register_operand" "=f,f")
3206 (if_then_else:SF
3207 (match_operator 3 "signed_comparison_operator"
3208 [(match_operand:DF 4 "reg_or_fp0_operand" "fG,fG")
3209 (match_operand:DF 2 "fp0_operand" "G,G")])
3210 (match_operand:SF 1 "reg_or_fp0_operand" "fG,0")
3211 (match_operand:SF 5 "reg_or_fp0_operand" "0,fG")))]
3212 "TARGET_FP"
3213 "@
3214 fcmov%C3 %R4,%R1,%0
3215 fcmov%D3 %R4,%R5,%0"
3216 [(set_attr "type" "fcmov")])
3217
3218 (define_insn "*movdfcc_ext1"
3219 [(set (match_operand:DF 0 "register_operand" "=f,f")
3220 (if_then_else:DF
3221 (match_operator 3 "signed_comparison_operator"
3222 [(match_operand:DF 4 "reg_or_fp0_operand" "fG,fG")
3223 (match_operand:DF 2 "fp0_operand" "G,G")])
3224 (float_extend:DF (match_operand:SF 1 "reg_or_fp0_operand" "fG,0"))
3225 (match_operand:DF 5 "reg_or_fp0_operand" "0,fG")))]
3226 "TARGET_FP"
3227 "@
3228 fcmov%C3 %R4,%R1,%0
3229 fcmov%D3 %R4,%R5,%0"
3230 [(set_attr "type" "fcmov")])
3231
3232 (define_insn "*movdfcc_ext2"
3233 [(set (match_operand:DF 0 "register_operand" "=f,f")
3234 (if_then_else:DF
3235 (match_operator 3 "signed_comparison_operator"
3236 [(float_extend:DF
3237 (match_operand:SF 4 "reg_or_fp0_operand" "fG,fG"))
3238 (match_operand:DF 2 "fp0_operand" "G,G")])
3239 (match_operand:DF 1 "reg_or_fp0_operand" "fG,0")
3240 (match_operand:DF 5 "reg_or_fp0_operand" "0,fG")))]
3241 "TARGET_FP"
3242 "@
3243 fcmov%C3 %R4,%R1,%0
3244 fcmov%D3 %R4,%R5,%0"
3245 [(set_attr "type" "fcmov")])
3246
3247 (define_insn "*movdfcc_ext3"
3248 [(set (match_operand:SF 0 "register_operand" "=f,f")
3249 (if_then_else:SF
3250 (match_operator 3 "signed_comparison_operator"
3251 [(float_extend:DF
3252 (match_operand:SF 4 "reg_or_fp0_operand" "fG,fG"))
3253 (match_operand:DF 2 "fp0_operand" "G,G")])
3254 (match_operand:SF 1 "reg_or_fp0_operand" "fG,0")
3255 (match_operand:SF 5 "reg_or_fp0_operand" "0,fG")))]
3256 "TARGET_FP"
3257 "@
3258 fcmov%C3 %R4,%R1,%0
3259 fcmov%D3 %R4,%R5,%0"
3260 [(set_attr "type" "fcmov")])
3261
3262 (define_insn "*movdfcc_ext4"
3263 [(set (match_operand:DF 0 "register_operand" "=f,f")
3264 (if_then_else:DF
3265 (match_operator 3 "signed_comparison_operator"
3266 [(float_extend:DF
3267 (match_operand:SF 4 "reg_or_fp0_operand" "fG,fG"))
3268 (match_operand:DF 2 "fp0_operand" "G,G")])
3269 (float_extend:DF (match_operand:SF 1 "reg_or_fp0_operand" "fG,0"))
3270 (match_operand:DF 5 "reg_or_fp0_operand" "0,fG")))]
3271 "TARGET_FP"
3272 "@
3273 fcmov%C3 %R4,%R1,%0
3274 fcmov%D3 %R4,%R5,%0"
3275 [(set_attr "type" "fcmov")])
3276
3277 (define_expand "maxdf3"
3278 [(set (match_dup 3)
3279 (le:DF (match_operand:DF 1 "reg_or_fp0_operand" "")
3280 (match_operand:DF 2 "reg_or_fp0_operand" "")))
3281 (set (match_operand:DF 0 "register_operand" "")
3282 (if_then_else:DF (eq (match_dup 3) (match_dup 4))
3283 (match_dup 1) (match_dup 2)))]
3284 "TARGET_FP"
3285 "
3286 { operands[3] = gen_reg_rtx (DFmode);
3287 operands[4] = CONST0_RTX (DFmode);
3288 }")
3289
3290 (define_expand "mindf3"
3291 [(set (match_dup 3)
3292 (lt:DF (match_operand:DF 1 "reg_or_fp0_operand" "")
3293 (match_operand:DF 2 "reg_or_fp0_operand" "")))
3294 (set (match_operand:DF 0 "register_operand" "")
3295 (if_then_else:DF (ne (match_dup 3) (match_dup 4))
3296 (match_dup 1) (match_dup 2)))]
3297 "TARGET_FP"
3298 "
3299 { operands[3] = gen_reg_rtx (DFmode);
3300 operands[4] = CONST0_RTX (DFmode);
3301 }")
3302
3303 (define_expand "maxsf3"
3304 [(set (match_dup 3)
3305 (le:DF (float_extend:DF (match_operand:SF 1 "reg_or_fp0_operand" ""))
3306 (float_extend:DF (match_operand:SF 2 "reg_or_fp0_operand" ""))))
3307 (set (match_operand:SF 0 "register_operand" "")
3308 (if_then_else:SF (eq (match_dup 3) (match_dup 4))
3309 (match_dup 1) (match_dup 2)))]
3310 "TARGET_FP"
3311 "
3312 { operands[3] = gen_reg_rtx (DFmode);
3313 operands[4] = CONST0_RTX (DFmode);
3314 }")
3315
3316 (define_expand "minsf3"
3317 [(set (match_dup 3)
3318 (lt:DF (float_extend:DF (match_operand:SF 1 "reg_or_fp0_operand" ""))
3319 (float_extend:DF (match_operand:SF 2 "reg_or_fp0_operand" ""))))
3320 (set (match_operand:SF 0 "register_operand" "")
3321 (if_then_else:SF (ne (match_dup 3) (match_dup 4))
3322 (match_dup 1) (match_dup 2)))]
3323 "TARGET_FP"
3324 "
3325 { operands[3] = gen_reg_rtx (DFmode);
3326 operands[4] = CONST0_RTX (DFmode);
3327 }")
3328
3329 (define_insn "*fbcc_normal"
3330 [(set (pc)
3331 (if_then_else
3332 (match_operator 1 "signed_comparison_operator"
3333 [(match_operand:DF 2 "reg_or_fp0_operand" "fG")
3334 (match_operand:DF 3 "fp0_operand" "G")])
3335 (label_ref (match_operand 0 "" ""))
3336 (pc)))]
3337 "TARGET_FP"
3338 "fb%C1 %R2,%0"
3339 [(set_attr "type" "fbr")])
3340
3341 (define_insn "*fbcc_ext_normal"
3342 [(set (pc)
3343 (if_then_else
3344 (match_operator 1 "signed_comparison_operator"
3345 [(float_extend:DF
3346 (match_operand:SF 2 "reg_or_fp0_operand" "fG"))
3347 (match_operand:DF 3 "fp0_operand" "G")])
3348 (label_ref (match_operand 0 "" ""))
3349 (pc)))]
3350 "TARGET_FP"
3351 "fb%C1 %R2,%0"
3352 [(set_attr "type" "fbr")])
3353 \f
3354 ;; These are the main define_expand's used to make conditional branches
3355 ;; and compares.
3356
3357 (define_expand "cmpdf"
3358 [(set (cc0) (compare (match_operand:DF 0 "reg_or_fp0_operand" "")
3359 (match_operand:DF 1 "reg_or_fp0_operand" "")))]
3360 "TARGET_FP"
3361 "
3362 {
3363 alpha_compare.op0 = operands[0];
3364 alpha_compare.op1 = operands[1];
3365 alpha_compare.fp_p = 1;
3366 DONE;
3367 }")
3368
3369 (define_expand "cmptf"
3370 [(set (cc0) (compare (match_operand:TF 0 "general_operand" "")
3371 (match_operand:TF 1 "general_operand" "")))]
3372 "TARGET_HAS_XFLOATING_LIBS"
3373 "
3374 {
3375 alpha_compare.op0 = operands[0];
3376 alpha_compare.op1 = operands[1];
3377 alpha_compare.fp_p = 1;
3378 DONE;
3379 }")
3380
3381 (define_expand "cmpdi"
3382 [(set (cc0) (compare (match_operand:DI 0 "general_operand" "")
3383 (match_operand:DI 1 "general_operand" "")))]
3384 ""
3385 "
3386 {
3387 alpha_compare.op0 = operands[0];
3388 alpha_compare.op1 = operands[1];
3389 alpha_compare.fp_p = 0;
3390 DONE;
3391 }")
3392
3393 (define_expand "beq"
3394 [(set (pc)
3395 (if_then_else (match_dup 1)
3396 (label_ref (match_operand 0 "" ""))
3397 (pc)))]
3398 ""
3399 "{ operands[1] = alpha_emit_conditional_branch (EQ); }")
3400
3401 (define_expand "bne"
3402 [(set (pc)
3403 (if_then_else (match_dup 1)
3404 (label_ref (match_operand 0 "" ""))
3405 (pc)))]
3406 ""
3407 "{ operands[1] = alpha_emit_conditional_branch (NE); }")
3408
3409 (define_expand "blt"
3410 [(set (pc)
3411 (if_then_else (match_dup 1)
3412 (label_ref (match_operand 0 "" ""))
3413 (pc)))]
3414 ""
3415 "{ operands[1] = alpha_emit_conditional_branch (LT); }")
3416
3417 (define_expand "ble"
3418 [(set (pc)
3419 (if_then_else (match_dup 1)
3420 (label_ref (match_operand 0 "" ""))
3421 (pc)))]
3422 ""
3423 "{ operands[1] = alpha_emit_conditional_branch (LE); }")
3424
3425 (define_expand "bgt"
3426 [(set (pc)
3427 (if_then_else (match_dup 1)
3428 (label_ref (match_operand 0 "" ""))
3429 (pc)))]
3430 ""
3431 "{ operands[1] = alpha_emit_conditional_branch (GT); }")
3432
3433 (define_expand "bge"
3434 [(set (pc)
3435 (if_then_else (match_dup 1)
3436 (label_ref (match_operand 0 "" ""))
3437 (pc)))]
3438 ""
3439 "{ operands[1] = alpha_emit_conditional_branch (GE); }")
3440
3441 (define_expand "bltu"
3442 [(set (pc)
3443 (if_then_else (match_dup 1)
3444 (label_ref (match_operand 0 "" ""))
3445 (pc)))]
3446 ""
3447 "{ operands[1] = alpha_emit_conditional_branch (LTU); }")
3448
3449 (define_expand "bleu"
3450 [(set (pc)
3451 (if_then_else (match_dup 1)
3452 (label_ref (match_operand 0 "" ""))
3453 (pc)))]
3454 ""
3455 "{ operands[1] = alpha_emit_conditional_branch (LEU); }")
3456
3457 (define_expand "bgtu"
3458 [(set (pc)
3459 (if_then_else (match_dup 1)
3460 (label_ref (match_operand 0 "" ""))
3461 (pc)))]
3462 ""
3463 "{ operands[1] = alpha_emit_conditional_branch (GTU); }")
3464
3465 (define_expand "bgeu"
3466 [(set (pc)
3467 (if_then_else (match_dup 1)
3468 (label_ref (match_operand 0 "" ""))
3469 (pc)))]
3470 ""
3471 "{ operands[1] = alpha_emit_conditional_branch (GEU); }")
3472
3473 (define_expand "bunordered"
3474 [(set (pc)
3475 (if_then_else (match_dup 1)
3476 (label_ref (match_operand 0 "" ""))
3477 (pc)))]
3478 ""
3479 "{ operands[1] = alpha_emit_conditional_branch (UNORDERED); }")
3480
3481 (define_expand "bordered"
3482 [(set (pc)
3483 (if_then_else (match_dup 1)
3484 (label_ref (match_operand 0 "" ""))
3485 (pc)))]
3486 ""
3487 "{ operands[1] = alpha_emit_conditional_branch (ORDERED); }")
3488
3489 (define_expand "seq"
3490 [(set (match_operand:DI 0 "register_operand" "")
3491 (match_dup 1))]
3492 ""
3493 "{ if ((operands[1] = alpha_emit_setcc (EQ)) == NULL_RTX) FAIL; }")
3494
3495 (define_expand "sne"
3496 [(set (match_operand:DI 0 "register_operand" "")
3497 (match_dup 1))]
3498 ""
3499 "{ if ((operands[1] = alpha_emit_setcc (NE)) == NULL_RTX) FAIL; }")
3500
3501 (define_expand "slt"
3502 [(set (match_operand:DI 0 "register_operand" "")
3503 (match_dup 1))]
3504 ""
3505 "{ if ((operands[1] = alpha_emit_setcc (LT)) == NULL_RTX) FAIL; }")
3506
3507 (define_expand "sle"
3508 [(set (match_operand:DI 0 "register_operand" "")
3509 (match_dup 1))]
3510 ""
3511 "{ if ((operands[1] = alpha_emit_setcc (LE)) == NULL_RTX) FAIL; }")
3512
3513 (define_expand "sgt"
3514 [(set (match_operand:DI 0 "register_operand" "")
3515 (match_dup 1))]
3516 ""
3517 "{ if ((operands[1] = alpha_emit_setcc (GT)) == NULL_RTX) FAIL; }")
3518
3519 (define_expand "sge"
3520 [(set (match_operand:DI 0 "register_operand" "")
3521 (match_dup 1))]
3522 ""
3523 "{ if ((operands[1] = alpha_emit_setcc (GE)) == NULL_RTX) FAIL; }")
3524
3525 (define_expand "sltu"
3526 [(set (match_operand:DI 0 "register_operand" "")
3527 (match_dup 1))]
3528 ""
3529 "{ if ((operands[1] = alpha_emit_setcc (LTU)) == NULL_RTX) FAIL; }")
3530
3531 (define_expand "sleu"
3532 [(set (match_operand:DI 0 "register_operand" "")
3533 (match_dup 1))]
3534 ""
3535 "{ if ((operands[1] = alpha_emit_setcc (LEU)) == NULL_RTX) FAIL; }")
3536
3537 (define_expand "sgtu"
3538 [(set (match_operand:DI 0 "register_operand" "")
3539 (match_dup 1))]
3540 ""
3541 "{ if ((operands[1] = alpha_emit_setcc (GTU)) == NULL_RTX) FAIL; }")
3542
3543 (define_expand "sgeu"
3544 [(set (match_operand:DI 0 "register_operand" "")
3545 (match_dup 1))]
3546 ""
3547 "{ if ((operands[1] = alpha_emit_setcc (GEU)) == NULL_RTX) FAIL; }")
3548
3549 (define_expand "sunordered"
3550 [(set (match_operand:DI 0 "register_operand" "")
3551 (match_dup 1))]
3552 ""
3553 "{ if ((operands[1] = alpha_emit_setcc (UNORDERED)) == NULL_RTX) FAIL; }")
3554
3555 (define_expand "sordered"
3556 [(set (match_operand:DI 0 "register_operand" "")
3557 (match_dup 1))]
3558 ""
3559 "{ if ((operands[1] = alpha_emit_setcc (ORDERED)) == NULL_RTX) FAIL; }")
3560 \f
3561 ;; These are the main define_expand's used to make conditional moves.
3562
3563 (define_expand "movsicc"
3564 [(set (match_operand:SI 0 "register_operand" "")
3565 (if_then_else:SI (match_operand 1 "comparison_operator" "")
3566 (match_operand:SI 2 "reg_or_8bit_operand" "")
3567 (match_operand:SI 3 "reg_or_8bit_operand" "")))]
3568 ""
3569 "
3570 {
3571 if ((operands[1] = alpha_emit_conditional_move (operands[1], SImode)) == 0)
3572 FAIL;
3573 }")
3574
3575 (define_expand "movdicc"
3576 [(set (match_operand:DI 0 "register_operand" "")
3577 (if_then_else:DI (match_operand 1 "comparison_operator" "")
3578 (match_operand:DI 2 "reg_or_8bit_operand" "")
3579 (match_operand:DI 3 "reg_or_8bit_operand" "")))]
3580 ""
3581 "
3582 {
3583 if ((operands[1] = alpha_emit_conditional_move (operands[1], DImode)) == 0)
3584 FAIL;
3585 }")
3586
3587 (define_expand "movsfcc"
3588 [(set (match_operand:SF 0 "register_operand" "")
3589 (if_then_else:SF (match_operand 1 "comparison_operator" "")
3590 (match_operand:SF 2 "reg_or_8bit_operand" "")
3591 (match_operand:SF 3 "reg_or_8bit_operand" "")))]
3592 ""
3593 "
3594 {
3595 if ((operands[1] = alpha_emit_conditional_move (operands[1], SFmode)) == 0)
3596 FAIL;
3597 }")
3598
3599 (define_expand "movdfcc"
3600 [(set (match_operand:DF 0 "register_operand" "")
3601 (if_then_else:DF (match_operand 1 "comparison_operator" "")
3602 (match_operand:DF 2 "reg_or_8bit_operand" "")
3603 (match_operand:DF 3 "reg_or_8bit_operand" "")))]
3604 ""
3605 "
3606 {
3607 if ((operands[1] = alpha_emit_conditional_move (operands[1], DFmode)) == 0)
3608 FAIL;
3609 }")
3610 \f
3611 ;; These define_split definitions are used in cases when comparisons have
3612 ;; not be stated in the correct way and we need to reverse the second
3613 ;; comparison. For example, x >= 7 has to be done as x < 6 with the
3614 ;; comparison that tests the result being reversed. We have one define_split
3615 ;; for each use of a comparison. They do not match valid insns and need
3616 ;; not generate valid insns.
3617 ;;
3618 ;; We can also handle equality comparisons (and inequality comparisons in
3619 ;; cases where the resulting add cannot overflow) by doing an add followed by
3620 ;; a comparison with zero. This is faster since the addition takes one
3621 ;; less cycle than a compare when feeding into a conditional move.
3622 ;; For this case, we also have an SImode pattern since we can merge the add
3623 ;; and sign extend and the order doesn't matter.
3624 ;;
3625 ;; We do not do this for floating-point, since it isn't clear how the "wrong"
3626 ;; operation could have been generated.
3627
3628 (define_split
3629 [(set (match_operand:DI 0 "register_operand" "")
3630 (if_then_else:DI
3631 (match_operator 1 "comparison_operator"
3632 [(match_operand:DI 2 "reg_or_0_operand" "")
3633 (match_operand:DI 3 "reg_or_cint_operand" "")])
3634 (match_operand:DI 4 "reg_or_cint_operand" "")
3635 (match_operand:DI 5 "reg_or_cint_operand" "")))
3636 (clobber (match_operand:DI 6 "register_operand" ""))]
3637 "operands[3] != const0_rtx"
3638 [(set (match_dup 6) (match_dup 7))
3639 (set (match_dup 0)
3640 (if_then_else:DI (match_dup 8) (match_dup 4) (match_dup 5)))]
3641 "
3642 { enum rtx_code code = GET_CODE (operands[1]);
3643 int unsignedp = (code == GEU || code == LEU || code == GTU || code == LTU);
3644
3645 /* If we are comparing for equality with a constant and that constant
3646 appears in the arm when the register equals the constant, use the
3647 register since that is more likely to match (and to produce better code
3648 if both would). */
3649
3650 if (code == EQ && GET_CODE (operands[3]) == CONST_INT
3651 && rtx_equal_p (operands[4], operands[3]))
3652 operands[4] = operands[2];
3653
3654 else if (code == NE && GET_CODE (operands[3]) == CONST_INT
3655 && rtx_equal_p (operands[5], operands[3]))
3656 operands[5] = operands[2];
3657
3658 if (code == NE || code == EQ
3659 || (extended_count (operands[2], DImode, unsignedp) >= 1
3660 && extended_count (operands[3], DImode, unsignedp) >= 1))
3661 {
3662 if (GET_CODE (operands[3]) == CONST_INT)
3663 operands[7] = gen_rtx_PLUS (DImode, operands[2],
3664 GEN_INT (- INTVAL (operands[3])));
3665 else
3666 operands[7] = gen_rtx_MINUS (DImode, operands[2], operands[3]);
3667
3668 operands[8] = gen_rtx_fmt_ee (code, VOIDmode, operands[6], const0_rtx);
3669 }
3670
3671 else if (code == EQ || code == LE || code == LT
3672 || code == LEU || code == LTU)
3673 {
3674 operands[7] = gen_rtx_fmt_ee (code, DImode, operands[2], operands[3]);
3675 operands[8] = gen_rtx_NE (VOIDmode, operands[6], const0_rtx);
3676 }
3677 else
3678 {
3679 operands[7] = gen_rtx_fmt_ee (reverse_condition (code), DImode,
3680 operands[2], operands[3]);
3681 operands[8] = gen_rtx_EQ (VOIDmode, operands[6], const0_rtx);
3682 }
3683 }")
3684
3685 (define_split
3686 [(set (match_operand:DI 0 "register_operand" "")
3687 (if_then_else:DI
3688 (match_operator 1 "comparison_operator"
3689 [(match_operand:SI 2 "reg_or_0_operand" "")
3690 (match_operand:SI 3 "reg_or_cint_operand" "")])
3691 (match_operand:DI 4 "reg_or_8bit_operand" "")
3692 (match_operand:DI 5 "reg_or_8bit_operand" "")))
3693 (clobber (match_operand:DI 6 "register_operand" ""))]
3694 "operands[3] != const0_rtx
3695 && (GET_CODE (operands[1]) == EQ || GET_CODE (operands[1]) == NE)"
3696 [(set (match_dup 6) (match_dup 7))
3697 (set (match_dup 0)
3698 (if_then_else:DI (match_dup 8) (match_dup 4) (match_dup 5)))]
3699 "
3700 { enum rtx_code code = GET_CODE (operands[1]);
3701 int unsignedp = (code == GEU || code == LEU || code == GTU || code == LTU);
3702 rtx tem;
3703
3704 if ((code != NE && code != EQ
3705 && ! (extended_count (operands[2], DImode, unsignedp) >= 1
3706 && extended_count (operands[3], DImode, unsignedp) >= 1)))
3707 FAIL;
3708
3709 if (GET_CODE (operands[3]) == CONST_INT)
3710 tem = gen_rtx_PLUS (SImode, operands[2],
3711 GEN_INT (- INTVAL (operands[3])));
3712 else
3713 tem = gen_rtx_MINUS (SImode, operands[2], operands[3]);
3714
3715 operands[7] = gen_rtx_SIGN_EXTEND (DImode, tem);
3716 operands[8] = gen_rtx_fmt_ee (GET_CODE (operands[1]), VOIDmode,
3717 operands[6], const0_rtx);
3718 }")
3719
3720 (define_split
3721 [(set (pc)
3722 (if_then_else
3723 (match_operator 1 "comparison_operator"
3724 [(match_operand:DI 2 "reg_or_0_operand" "")
3725 (match_operand:DI 3 "reg_or_cint_operand" "")])
3726 (label_ref (match_operand 0 "" ""))
3727 (pc)))
3728 (clobber (match_operand:DI 4 "register_operand" ""))]
3729 "operands[3] != const0_rtx"
3730 [(set (match_dup 4) (match_dup 5))
3731 (set (pc) (if_then_else (match_dup 6) (label_ref (match_dup 0)) (pc)))]
3732 "
3733 { enum rtx_code code = GET_CODE (operands[1]);
3734 int unsignedp = (code == GEU || code == LEU || code == GTU || code == LTU);
3735
3736 if (code == NE || code == EQ
3737 || (extended_count (operands[2], DImode, unsignedp) >= 1
3738 && extended_count (operands[3], DImode, unsignedp) >= 1))
3739 {
3740 if (GET_CODE (operands[3]) == CONST_INT)
3741 operands[5] = gen_rtx_PLUS (DImode, operands[2],
3742 GEN_INT (- INTVAL (operands[3])));
3743 else
3744 operands[5] = gen_rtx_MINUS (DImode, operands[2], operands[3]);
3745
3746 operands[6] = gen_rtx_fmt_ee (code, VOIDmode, operands[4], const0_rtx);
3747 }
3748
3749 else if (code == EQ || code == LE || code == LT
3750 || code == LEU || code == LTU)
3751 {
3752 operands[5] = gen_rtx_fmt_ee (code, DImode, operands[2], operands[3]);
3753 operands[6] = gen_rtx_NE (VOIDmode, operands[4], const0_rtx);
3754 }
3755 else
3756 {
3757 operands[5] = gen_rtx_fmt_ee (reverse_condition (code), DImode,
3758 operands[2], operands[3]);
3759 operands[6] = gen_rtx_EQ (VOIDmode, operands[4], const0_rtx);
3760 }
3761 }")
3762
3763 (define_split
3764 [(set (pc)
3765 (if_then_else
3766 (match_operator 1 "comparison_operator"
3767 [(match_operand:SI 2 "reg_or_0_operand" "")
3768 (match_operand:SI 3 "const_int_operand" "")])
3769 (label_ref (match_operand 0 "" ""))
3770 (pc)))
3771 (clobber (match_operand:DI 4 "register_operand" ""))]
3772 "operands[3] != const0_rtx
3773 && (GET_CODE (operands[1]) == EQ || GET_CODE (operands[1]) == NE)"
3774 [(set (match_dup 4) (match_dup 5))
3775 (set (pc) (if_then_else (match_dup 6) (label_ref (match_dup 0)) (pc)))]
3776 "
3777 { rtx tem;
3778
3779 if (GET_CODE (operands[3]) == CONST_INT)
3780 tem = gen_rtx_PLUS (SImode, operands[2],
3781 GEN_INT (- INTVAL (operands[3])));
3782 else
3783 tem = gen_rtx_MINUS (SImode, operands[2], operands[3]);
3784
3785 operands[5] = gen_rtx_SIGN_EXTEND (DImode, tem);
3786 operands[6] = gen_rtx_fmt_ee (GET_CODE (operands[1]), VOIDmode,
3787 operands[4], const0_rtx);
3788 }")
3789
3790 ;; We can convert such things as "a > 0xffff" to "t = a & ~ 0xffff; t != 0".
3791 ;; This eliminates one, and sometimes two, insns when the AND can be done
3792 ;; with a ZAP.
3793 (define_split
3794 [(set (match_operand:DI 0 "register_operand" "")
3795 (match_operator:DI 1 "comparison_operator"
3796 [(match_operand:DI 2 "register_operand" "")
3797 (match_operand:DI 3 "const_int_operand" "")]))
3798 (clobber (match_operand:DI 4 "register_operand" ""))]
3799 "exact_log2 (INTVAL (operands[3]) + 1) >= 0
3800 && (GET_CODE (operands[1]) == GTU
3801 || GET_CODE (operands[1]) == LEU
3802 || ((GET_CODE (operands[1]) == GT || GET_CODE (operands[1]) == LE)
3803 && extended_count (operands[2], DImode, 1) > 0))"
3804 [(set (match_dup 4) (and:DI (match_dup 2) (match_dup 5)))
3805 (set (match_dup 0) (match_dup 6))]
3806 "
3807 {
3808 operands[5] = GEN_INT (~ INTVAL (operands[3]));
3809 operands[6] = gen_rtx_fmt_ee (((GET_CODE (operands[1]) == GTU
3810 || GET_CODE (operands[1]) == GT)
3811 ? NE : EQ),
3812 DImode, operands[4], const0_rtx);
3813 }")
3814
3815 ;; Prefer to use cmp and arithmetic when possible instead of a cmove.
3816
3817 (define_split
3818 [(set (match_operand 0 "register_operand" "")
3819 (if_then_else (match_operator 1 "signed_comparison_operator"
3820 [(match_operand:DI 2 "reg_or_0_operand" "")
3821 (const_int 0)])
3822 (match_operand 3 "const_int_operand" "")
3823 (match_operand 4 "const_int_operand" "")))]
3824 ""
3825 [(const_int 0)]
3826 "
3827 {
3828 if (alpha_split_conditional_move (GET_CODE (operands[1]), operands[0],
3829 operands[2], operands[3], operands[4]))
3830 DONE;
3831 else
3832 FAIL;
3833 }")
3834
3835 ;; ??? Why combine is allowed to create such non-canonical rtl, I don't know.
3836 ;; Oh well, we match it in movcc, so it must be partially our fault.
3837 (define_split
3838 [(set (match_operand 0 "register_operand" "")
3839 (if_then_else (match_operator 1 "signed_comparison_operator"
3840 [(const_int 0)
3841 (match_operand:DI 2 "reg_or_0_operand" "")])
3842 (match_operand 3 "const_int_operand" "")
3843 (match_operand 4 "const_int_operand" "")))]
3844 ""
3845 [(const_int 0)]
3846 "
3847 {
3848 if (alpha_split_conditional_move (swap_condition (GET_CODE (operands[1])),
3849 operands[0], operands[2], operands[3],
3850 operands[4]))
3851 DONE;
3852 else
3853 FAIL;
3854 }")
3855
3856 (define_insn_and_split "*cmp_sadd_di"
3857 [(set (match_operand:DI 0 "register_operand" "=r")
3858 (plus:DI (if_then_else:DI
3859 (match_operator 1 "alpha_zero_comparison_operator"
3860 [(match_operand:DI 2 "reg_or_0_operand" "rJ")
3861 (const_int 0)])
3862 (match_operand:DI 3 "const48_operand" "I")
3863 (const_int 0))
3864 (match_operand:DI 4 "sext_add_operand" "rIO")))
3865 (clobber (match_scratch:DI 5 "=r"))]
3866 ""
3867 "#"
3868 "! no_new_pseudos || reload_completed"
3869 [(set (match_dup 5)
3870 (match_op_dup:DI 1 [(match_dup 2) (const_int 0)]))
3871 (set (match_dup 0)
3872 (plus:DI (mult:DI (match_dup 5) (match_dup 3))
3873 (match_dup 4)))]
3874 "
3875 {
3876 if (! no_new_pseudos)
3877 operands[5] = gen_reg_rtx (DImode);
3878 else if (reg_overlap_mentioned_p (operands[5], operands[4]))
3879 operands[5] = operands[0];
3880 }")
3881
3882 (define_insn_and_split "*cmp_sadd_si"
3883 [(set (match_operand:SI 0 "register_operand" "=r")
3884 (plus:SI (if_then_else:SI
3885 (match_operator 1 "alpha_zero_comparison_operator"
3886 [(match_operand:DI 2 "reg_or_0_operand" "rJ")
3887 (const_int 0)])
3888 (match_operand:SI 3 "const48_operand" "I")
3889 (const_int 0))
3890 (match_operand:SI 4 "sext_add_operand" "rIO")))
3891 (clobber (match_scratch:SI 5 "=r"))]
3892 ""
3893 "#"
3894 "! no_new_pseudos || reload_completed"
3895 [(set (match_dup 5)
3896 (match_op_dup:SI 1 [(match_dup 2) (const_int 0)]))
3897 (set (match_dup 0)
3898 (plus:SI (mult:SI (match_dup 5) (match_dup 3))
3899 (match_dup 4)))]
3900 "
3901 {
3902 if (! no_new_pseudos)
3903 operands[5] = gen_reg_rtx (DImode);
3904 else if (reg_overlap_mentioned_p (operands[5], operands[4]))
3905 operands[5] = operands[0];
3906 }")
3907
3908 (define_insn_and_split "*cmp_sadd_sidi"
3909 [(set (match_operand:DI 0 "register_operand" "=r")
3910 (sign_extend:DI
3911 (plus:SI (if_then_else:SI
3912 (match_operator 1 "alpha_zero_comparison_operator"
3913 [(match_operand:DI 2 "reg_or_0_operand" "rJ")
3914 (const_int 0)])
3915 (match_operand:SI 3 "const48_operand" "I")
3916 (const_int 0))
3917 (match_operand:SI 4 "sext_add_operand" "rIO"))))
3918 (clobber (match_scratch:SI 5 "=r"))]
3919 ""
3920 "#"
3921 "! no_new_pseudos || reload_completed"
3922 [(set (match_dup 5)
3923 (match_op_dup:SI 1 [(match_dup 2) (const_int 0)]))
3924 (set (match_dup 0)
3925 (sign_extend:DI (plus:SI (mult:SI (match_dup 5) (match_dup 3))
3926 (match_dup 4))))]
3927 "
3928 {
3929 if (! no_new_pseudos)
3930 operands[5] = gen_reg_rtx (DImode);
3931 else if (reg_overlap_mentioned_p (operands[5], operands[4]))
3932 operands[5] = operands[0];
3933 }")
3934
3935 (define_insn_and_split "*cmp_ssub_di"
3936 [(set (match_operand:DI 0 "register_operand" "=r")
3937 (minus:DI (if_then_else:DI
3938 (match_operator 1 "alpha_zero_comparison_operator"
3939 [(match_operand:DI 2 "reg_or_0_operand" "rJ")
3940 (const_int 0)])
3941 (match_operand:DI 3 "const48_operand" "I")
3942 (const_int 0))
3943 (match_operand:DI 4 "reg_or_8bit_operand" "rI")))
3944 (clobber (match_scratch:DI 5 "=r"))]
3945 ""
3946 "#"
3947 "! no_new_pseudos || reload_completed"
3948 [(set (match_dup 5)
3949 (match_op_dup:DI 1 [(match_dup 2) (const_int 0)]))
3950 (set (match_dup 0)
3951 (minus:DI (mult:DI (match_dup 5) (match_dup 3))
3952 (match_dup 4)))]
3953 "
3954 {
3955 if (! no_new_pseudos)
3956 operands[5] = gen_reg_rtx (DImode);
3957 else if (reg_overlap_mentioned_p (operands[5], operands[4]))
3958 operands[5] = operands[0];
3959 }")
3960
3961 (define_insn_and_split "*cmp_ssub_si"
3962 [(set (match_operand:SI 0 "register_operand" "=r")
3963 (minus:SI (if_then_else:SI
3964 (match_operator 1 "alpha_zero_comparison_operator"
3965 [(match_operand:DI 2 "reg_or_0_operand" "rJ")
3966 (const_int 0)])
3967 (match_operand:SI 3 "const48_operand" "I")
3968 (const_int 0))
3969 (match_operand:SI 4 "reg_or_8bit_operand" "rI")))
3970 (clobber (match_scratch:SI 5 "=r"))]
3971 ""
3972 "#"
3973 "! no_new_pseudos || reload_completed"
3974 [(set (match_dup 5)
3975 (match_op_dup:SI 1 [(match_dup 2) (const_int 0)]))
3976 (set (match_dup 0)
3977 (minus:SI (mult:SI (match_dup 5) (match_dup 3))
3978 (match_dup 4)))]
3979 "
3980 {
3981 if (! no_new_pseudos)
3982 operands[5] = gen_reg_rtx (DImode);
3983 else if (reg_overlap_mentioned_p (operands[5], operands[4]))
3984 operands[5] = operands[0];
3985 }")
3986
3987 (define_insn_and_split "*cmp_ssub_sidi"
3988 [(set (match_operand:DI 0 "register_operand" "=r")
3989 (sign_extend:DI
3990 (minus:SI (if_then_else:SI
3991 (match_operator 1 "alpha_zero_comparison_operator"
3992 [(match_operand:DI 2 "reg_or_0_operand" "rJ")
3993 (const_int 0)])
3994 (match_operand:SI 3 "const48_operand" "I")
3995 (const_int 0))
3996 (match_operand:SI 4 "reg_or_8bit_operand" "rI"))))
3997 (clobber (match_scratch:SI 5 "=r"))]
3998 ""
3999 "#"
4000 "! no_new_pseudos || reload_completed"
4001 [(set (match_dup 5)
4002 (match_op_dup:SI 1 [(match_dup 2) (const_int 0)]))
4003 (set (match_dup 0)
4004 (sign_extend:DI (minus:SI (mult:SI (match_dup 5) (match_dup 3))
4005 (match_dup 4))))]
4006 "
4007 {
4008 if (! no_new_pseudos)
4009 operands[5] = gen_reg_rtx (DImode);
4010 else if (reg_overlap_mentioned_p (operands[5], operands[4]))
4011 operands[5] = operands[0];
4012 }")
4013 \f
4014 ;; Here are the CALL and unconditional branch insns. Calls on NT and OSF
4015 ;; work differently, so we have different patterns for each.
4016
4017 (define_expand "call"
4018 [(use (match_operand:DI 0 "" ""))
4019 (use (match_operand 1 "" ""))
4020 (use (match_operand 2 "" ""))
4021 (use (match_operand 3 "" ""))]
4022 ""
4023 "
4024 { if (TARGET_WINDOWS_NT)
4025 emit_call_insn (gen_call_nt (operands[0], operands[1]));
4026 else if (TARGET_OPEN_VMS)
4027 emit_call_insn (gen_call_vms (operands[0], operands[2]));
4028 else
4029 emit_call_insn (gen_call_osf (operands[0], operands[1]));
4030
4031 DONE;
4032 }")
4033
4034 (define_expand "sibcall"
4035 [(call (mem:DI (match_operand 0 "" ""))
4036 (match_operand 1 "" ""))]
4037 "!TARGET_OPEN_VMS && !TARGET_WINDOWS_NT"
4038 "
4039 {
4040 if (GET_CODE (operands[0]) != MEM)
4041 abort ();
4042 operands[0] = XEXP (operands[0], 0);
4043 }")
4044
4045 (define_expand "call_osf"
4046 [(parallel [(call (mem:DI (match_operand 0 "" ""))
4047 (match_operand 1 "" ""))
4048 (clobber (reg:DI 27))
4049 (clobber (reg:DI 26))])]
4050 ""
4051 "
4052 { if (GET_CODE (operands[0]) != MEM)
4053 abort ();
4054
4055 operands[0] = XEXP (operands[0], 0);
4056
4057 if (GET_CODE (operands[0]) != SYMBOL_REF
4058 && ! (GET_CODE (operands[0]) == REG && REGNO (operands[0]) == 27))
4059 {
4060 rtx tem = gen_rtx_REG (DImode, 27);
4061 emit_move_insn (tem, operands[0]);
4062 operands[0] = tem;
4063 }
4064 }")
4065
4066 (define_expand "call_nt"
4067 [(parallel [(call (mem:DI (match_operand 0 "" ""))
4068 (match_operand 1 "" ""))
4069 (clobber (reg:DI 26))])]
4070 ""
4071 "
4072 { if (GET_CODE (operands[0]) != MEM)
4073 abort ();
4074
4075 operands[0] = XEXP (operands[0], 0);
4076 if (GET_CODE (operands[0]) != SYMBOL_REF && GET_CODE (operands[0]) != REG)
4077 operands[0] = force_reg (DImode, operands[0]);
4078 }")
4079
4080 ;;
4081 ;; call openvms/alpha
4082 ;; op 0: symbol ref for called function
4083 ;; op 1: next_arg_reg (argument information value for R25)
4084 ;;
4085 (define_expand "call_vms"
4086 [(parallel [(call (mem:DI (match_operand 0 "" ""))
4087 (match_operand 1 "" ""))
4088 (use (match_dup 2))
4089 (use (reg:DI 25))
4090 (use (reg:DI 26))
4091 (clobber (reg:DI 27))])]
4092 ""
4093 "
4094 { if (GET_CODE (operands[0]) != MEM)
4095 abort ();
4096
4097 operands[0] = XEXP (operands[0], 0);
4098
4099 /* Always load AI with argument information, then handle symbolic and
4100 indirect call differently. Load RA and set operands[2] to PV in
4101 both cases. */
4102
4103 emit_move_insn (gen_rtx_REG (DImode, 25), operands[1]);
4104 if (GET_CODE (operands[0]) == SYMBOL_REF)
4105 {
4106 rtx linkage = alpha_need_linkage (XSTR (operands[0], 0), 0);
4107
4108 emit_move_insn (gen_rtx_REG (Pmode, 26), gen_rtx_MEM (Pmode, linkage));
4109 operands[2]
4110 = validize_mem (gen_rtx_MEM (Pmode, plus_constant (linkage, 8)));
4111 }
4112 else
4113 {
4114 emit_move_insn (gen_rtx_REG (Pmode, 26),
4115 gen_rtx_MEM (Pmode, plus_constant (operands[0], 8)));
4116 operands[2] = operands[0];
4117 }
4118
4119 }")
4120
4121 (define_expand "call_value"
4122 [(use (match_operand 0 "" ""))
4123 (use (match_operand:DI 1 "" ""))
4124 (use (match_operand 2 "" ""))
4125 (use (match_operand 3 "" ""))
4126 (use (match_operand 4 "" ""))]
4127 ""
4128 "
4129 { if (TARGET_WINDOWS_NT)
4130 emit_call_insn (gen_call_value_nt (operands[0], operands[1], operands[2]));
4131 else if (TARGET_OPEN_VMS)
4132 emit_call_insn (gen_call_value_vms (operands[0], operands[1],
4133 operands[3]));
4134 else
4135 emit_call_insn (gen_call_value_osf (operands[0], operands[1],
4136 operands[2]));
4137 DONE;
4138 }")
4139
4140 (define_expand "sibcall_value"
4141 [(set (match_operand 0 "" "")
4142 (call (mem:DI (match_operand 1 "" ""))
4143 (match_operand 2 "" "")))]
4144 "!TARGET_OPEN_VMS && !TARGET_WINDOWS_NT"
4145 "
4146 {
4147 if (GET_CODE (operands[1]) != MEM)
4148 abort ();
4149 operands[1] = XEXP (operands[1], 0);
4150 }")
4151
4152 (define_expand "call_value_osf"
4153 [(parallel [(set (match_operand 0 "" "")
4154 (call (mem:DI (match_operand 1 "" ""))
4155 (match_operand 2 "" "")))
4156 (clobber (reg:DI 27))
4157 (clobber (reg:DI 26))])]
4158 ""
4159 "
4160 { if (GET_CODE (operands[1]) != MEM)
4161 abort ();
4162
4163 operands[1] = XEXP (operands[1], 0);
4164
4165 if (GET_CODE (operands[1]) != SYMBOL_REF
4166 && ! (GET_CODE (operands[1]) == REG && REGNO (operands[1]) == 27))
4167 {
4168 rtx tem = gen_rtx_REG (DImode, 27);
4169 emit_move_insn (tem, operands[1]);
4170 operands[1] = tem;
4171 }
4172 }")
4173
4174 (define_expand "call_value_nt"
4175 [(parallel [(set (match_operand 0 "" "")
4176 (call (mem:DI (match_operand 1 "" ""))
4177 (match_operand 2 "" "")))
4178 (clobber (reg:DI 26))])]
4179 ""
4180 "
4181 { if (GET_CODE (operands[1]) != MEM)
4182 abort ();
4183
4184 operands[1] = XEXP (operands[1], 0);
4185 if (GET_CODE (operands[1]) != SYMBOL_REF && GET_CODE (operands[1]) != REG)
4186 operands[1] = force_reg (DImode, operands[1]);
4187 }")
4188
4189 (define_expand "call_value_vms"
4190 [(parallel [(set (match_operand 0 "" "")
4191 (call (mem:DI (match_operand:DI 1 "" ""))
4192 (match_operand 2 "" "")))
4193 (use (match_dup 3))
4194 (use (reg:DI 25))
4195 (use (reg:DI 26))
4196 (clobber (reg:DI 27))])]
4197 ""
4198 "
4199 { if (GET_CODE (operands[1]) != MEM)
4200 abort ();
4201
4202 operands[1] = XEXP (operands[1], 0);
4203
4204 /* Always load AI with argument information, then handle symbolic and
4205 indirect call differently. Load RA and set operands[3] to PV in
4206 both cases. */
4207
4208 emit_move_insn (gen_rtx_REG (DImode, 25), operands[2]);
4209 if (GET_CODE (operands[1]) == SYMBOL_REF)
4210 {
4211 rtx linkage = alpha_need_linkage (XSTR (operands[1], 0), 0);
4212
4213 emit_move_insn (gen_rtx_REG (Pmode, 26), gen_rtx_MEM (Pmode, linkage));
4214 operands[3]
4215 = validize_mem (gen_rtx_MEM (Pmode, plus_constant (linkage, 8)));
4216 }
4217 else
4218 {
4219 emit_move_insn (gen_rtx_REG (Pmode, 26),
4220 gen_rtx_MEM (Pmode, plus_constant (operands[1], 8)));
4221 operands[3] = operands[1];
4222 }
4223 }")
4224
4225 (define_insn "*call_osf_1"
4226 [(call (mem:DI (match_operand:DI 0 "call_operand" "c,R,i"))
4227 (match_operand 1 "" ""))
4228 (clobber (reg:DI 27))
4229 (clobber (reg:DI 26))]
4230 "! TARGET_WINDOWS_NT && ! TARGET_OPEN_VMS"
4231 "@
4232 jsr $26,($27),0\;ldgp $29,0($26)
4233 bsr $26,$%0..ng
4234 jsr $26,%0\;ldgp $29,0($26)"
4235 [(set_attr "type" "jsr")
4236 (set_attr "length" "12,*,16")])
4237
4238 (define_insn "*sibcall_osf_1"
4239 [(call (mem:DI (match_operand:DI 0 "call_operand" "R,i"))
4240 (match_operand 1 "" ""))]
4241 "! TARGET_WINDOWS_NT && ! TARGET_OPEN_VMS"
4242 "@
4243 br $31,$%0..ng
4244 jmp $31,%0"
4245 [(set_attr "type" "jsr")
4246 (set_attr "length" "*,8")])
4247
4248 (define_insn "*call_nt_1"
4249 [(call (mem:DI (match_operand:DI 0 "call_operand" "r,R,i"))
4250 (match_operand 1 "" ""))
4251 (clobber (reg:DI 26))]
4252 "TARGET_WINDOWS_NT"
4253 "@
4254 jsr $26,(%0)
4255 bsr $26,%0
4256 jsr $26,%0"
4257 [(set_attr "type" "jsr")
4258 (set_attr "length" "*,*,12")])
4259
4260 (define_insn "*call_vms_1"
4261 [(call (mem:DI (match_operand:DI 0 "call_operand" "r,i"))
4262 (match_operand 1 "" ""))
4263 (use (match_operand:DI 2 "nonimmediate_operand" "r,m"))
4264 (use (reg:DI 25))
4265 (use (reg:DI 26))
4266 (clobber (reg:DI 27))]
4267 "TARGET_OPEN_VMS"
4268 "@
4269 mov %2,$27\;jsr $26,0\;ldq $27,0($29)
4270 ldq $27,%2\;jsr $26,%0\;ldq $27,0($29)"
4271 [(set_attr "type" "jsr")
4272 (set_attr "length" "12,16")])
4273
4274 ;; Call subroutine returning any type.
4275
4276 (define_expand "untyped_call"
4277 [(parallel [(call (match_operand 0 "" "")
4278 (const_int 0))
4279 (match_operand 1 "" "")
4280 (match_operand 2 "" "")])]
4281 ""
4282 "
4283 {
4284 int i;
4285
4286 emit_call_insn (GEN_CALL (operands[0], const0_rtx, NULL, const0_rtx));
4287
4288 for (i = 0; i < XVECLEN (operands[2], 0); i++)
4289 {
4290 rtx set = XVECEXP (operands[2], 0, i);
4291 emit_move_insn (SET_DEST (set), SET_SRC (set));
4292 }
4293
4294 /* The optimizer does not know that the call sets the function value
4295 registers we stored in the result block. We avoid problems by
4296 claiming that all hard registers are used and clobbered at this
4297 point. */
4298 emit_insn (gen_blockage ());
4299
4300 DONE;
4301 }")
4302
4303 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
4304 ;; all of memory. This blocks insns from being moved across this point.
4305
4306 (define_insn "blockage"
4307 [(unspec_volatile [(const_int 0)] 1)]
4308 ""
4309 ""
4310 [(set_attr "length" "0")])
4311
4312 (define_insn "jump"
4313 [(set (pc)
4314 (label_ref (match_operand 0 "" "")))]
4315 ""
4316 "br $31,%l0"
4317 [(set_attr "type" "ibr")])
4318
4319 (define_expand "return"
4320 [(return)]
4321 "direct_return ()"
4322 "")
4323
4324 (define_insn "*return_internal"
4325 [(return)]
4326 "reload_completed"
4327 "ret $31,($26),1"
4328 [(set_attr "type" "ibr")])
4329
4330 (define_insn "indirect_jump"
4331 [(set (pc) (match_operand:DI 0 "register_operand" "r"))]
4332 ""
4333 "jmp $31,(%0),0"
4334 [(set_attr "type" "ibr")])
4335
4336 (define_expand "tablejump"
4337 [(use (match_operand:SI 0 "register_operand" ""))
4338 (use (match_operand:SI 1 "" ""))]
4339 ""
4340 "
4341 {
4342 if (TARGET_WINDOWS_NT)
4343 emit_jump_insn (gen_tablejump_nt (operands[0], operands[1]));
4344 else if (TARGET_OPEN_VMS)
4345 emit_jump_insn (gen_tablejump_vms (operands[0], operands[1]));
4346 else
4347 emit_jump_insn (gen_tablejump_osf (operands[0], operands[1]));
4348
4349 DONE;
4350 }")
4351
4352 (define_expand "tablejump_osf"
4353 [(set (match_dup 3)
4354 (sign_extend:DI (match_operand:SI 0 "register_operand" "")))
4355 (parallel [(set (pc)
4356 (plus:DI (match_dup 3)
4357 (label_ref (match_operand 1 "" ""))))
4358 (clobber (match_scratch:DI 2 "=r"))])]
4359 ""
4360 "
4361 { operands[3] = gen_reg_rtx (DImode); }")
4362
4363 (define_expand "tablejump_nt"
4364 [(set (match_dup 3)
4365 (sign_extend:DI (match_operand:SI 0 "register_operand" "")))
4366 (parallel [(set (pc)
4367 (match_dup 3))
4368 (use (label_ref (match_operand 1 "" "")))])]
4369 ""
4370 "
4371 { operands[3] = gen_reg_rtx (DImode); }")
4372
4373 ;;
4374 ;; tablejump, openVMS way
4375 ;; op 0: offset
4376 ;; op 1: label preceding jump-table
4377 ;;
4378 (define_expand "tablejump_vms"
4379 [(set (match_dup 2)
4380 (match_operand:DI 0 "register_operand" ""))
4381 (set (pc)
4382 (plus:DI (match_dup 2)
4383 (label_ref (match_operand 1 "" ""))))]
4384 ""
4385 "
4386 { operands[2] = gen_reg_rtx (DImode); }")
4387
4388 (define_insn "*tablejump_osf_internal"
4389 [(set (pc)
4390 (plus (match_operand:DI 0 "register_operand" "r")
4391 (label_ref (match_operand 1 "" ""))))
4392 (clobber (match_scratch:DI 2 "=r"))]
4393 "! TARGET_WINDOWS_NT && ! TARGET_OPEN_VMS && next_active_insn (insn) != 0
4394 && GET_CODE (PATTERN (next_active_insn (insn))) == ADDR_DIFF_VEC
4395 && PREV_INSN (next_active_insn (insn)) == operands[1]"
4396 "*
4397 { rtx best_label = 0;
4398 rtx jump_table_insn = next_active_insn (operands[1]);
4399
4400 if (GET_CODE (jump_table_insn) == JUMP_INSN
4401 && GET_CODE (PATTERN (jump_table_insn)) == ADDR_DIFF_VEC)
4402 {
4403 rtx jump_table = PATTERN (jump_table_insn);
4404 int n_labels = XVECLEN (jump_table, 1);
4405 int best_count = -1;
4406 int i, j;
4407
4408 for (i = 0; i < n_labels; i++)
4409 {
4410 int count = 1;
4411
4412 for (j = i + 1; j < n_labels; j++)
4413 if (XEXP (XVECEXP (jump_table, 1, i), 0)
4414 == XEXP (XVECEXP (jump_table, 1, j), 0))
4415 count++;
4416
4417 if (count > best_count)
4418 best_count = count, best_label = XVECEXP (jump_table, 1, i);
4419 }
4420 }
4421
4422 if (best_label)
4423 {
4424 operands[3] = best_label;
4425 return \"addq %0,$29,%2\;jmp $31,(%2),%3\";
4426 }
4427 else
4428 return \"addq %0,$29,%2\;jmp $31,(%2),0\";
4429 }"
4430 [(set_attr "type" "ibr")
4431 (set_attr "length" "8")])
4432
4433 (define_insn "*tablejump_nt_internal"
4434 [(set (pc)
4435 (match_operand:DI 0 "register_operand" "r"))
4436 (use (label_ref (match_operand 1 "" "")))]
4437 "TARGET_WINDOWS_NT && next_active_insn (insn) != 0
4438 && GET_CODE (PATTERN (next_active_insn (insn))) == ADDR_DIFF_VEC
4439 && PREV_INSN (next_active_insn (insn)) == operands[1]"
4440 "*
4441 { rtx best_label = 0;
4442 rtx jump_table_insn = next_active_insn (operands[1]);
4443
4444 if (GET_CODE (jump_table_insn) == JUMP_INSN
4445 && GET_CODE (PATTERN (jump_table_insn)) == ADDR_DIFF_VEC)
4446 {
4447 rtx jump_table = PATTERN (jump_table_insn);
4448 int n_labels = XVECLEN (jump_table, 1);
4449 int best_count = -1;
4450 int i, j;
4451
4452 for (i = 0; i < n_labels; i++)
4453 {
4454 int count = 1;
4455
4456 for (j = i + 1; j < n_labels; j++)
4457 if (XEXP (XVECEXP (jump_table, 1, i), 0)
4458 == XEXP (XVECEXP (jump_table, 1, j), 0))
4459 count++;
4460
4461 if (count > best_count)
4462 best_count = count, best_label = XVECEXP (jump_table, 1, i);
4463 }
4464 }
4465
4466 if (best_label)
4467 {
4468 operands[2] = best_label;
4469 return \"jmp $31,(%0),%2\";
4470 }
4471 else
4472 return \"jmp $31,(%0),0\";
4473 }"
4474 [(set_attr "type" "ibr")])
4475
4476 ;;
4477 ;; op 0 is table offset
4478 ;; op 1 is table label
4479 ;;
4480
4481 (define_insn "*tablejump_vms_internal"
4482 [(set (pc)
4483 (plus (match_operand:DI 0 "register_operand" "r")
4484 (label_ref (match_operand 1 "" ""))))]
4485 "TARGET_OPEN_VMS"
4486 "jmp $31,(%0),0"
4487 [(set_attr "type" "ibr")])
4488
4489 ;; Cache flush. Used by INITIALIZE_TRAMPOLINE. 0x86 is PAL_imb, but we don't
4490 ;; want to have to include pal.h in our .s file.
4491 ;;
4492 ;; Technically the type for call_pal is jsr, but we use that for determining
4493 ;; if we need a GP. Use ibr instead since it has the same EV5 scheduling
4494 ;; characteristics.
4495 (define_insn "imb"
4496 [(unspec_volatile [(const_int 0)] 0)]
4497 ""
4498 "call_pal 0x86"
4499 [(set_attr "type" "ibr")])
4500 \f
4501 ;; Finally, we have the basic data motion insns. The byte and word insns
4502 ;; are done via define_expand. Start with the floating-point insns, since
4503 ;; they are simpler.
4504
4505 (define_insn "*movsf_nofix"
4506 [(set (match_operand:SF 0 "nonimmediate_operand" "=f,f,*r,*r,m,m")
4507 (match_operand:SF 1 "input_operand" "fG,m,*rG,m,fG,*r"))]
4508 "TARGET_FPREGS && ! TARGET_FIX
4509 && (register_operand (operands[0], SFmode)
4510 || reg_or_fp0_operand (operands[1], SFmode))"
4511 "@
4512 fmov %R1,%0
4513 ld%, %0,%1
4514 mov %r1,%0
4515 ldl %0,%1
4516 st%, %R1,%0
4517 stl %r1,%0"
4518 [(set_attr "type" "fcpys,fld,ilog,ild,fst,ist")])
4519
4520 (define_insn "*movsf_fix"
4521 [(set (match_operand:SF 0 "nonimmediate_operand" "=f,f,*r,*r,m,m,f,*r")
4522 (match_operand:SF 1 "input_operand" "fG,m,*rG,m,fG,*r,*r,f"))]
4523 "TARGET_FPREGS && TARGET_FIX
4524 && (register_operand (operands[0], SFmode)
4525 || reg_or_fp0_operand (operands[1], SFmode))"
4526 "@
4527 fmov %R1,%0
4528 ld%, %0,%1
4529 mov %r1,%0
4530 ldl %0,%1
4531 st%, %R1,%0
4532 stl %r1,%0
4533 itofs %1,%0
4534 ftois %1,%0"
4535 [(set_attr "type" "fcpys,fld,ilog,ild,fst,ist,itof,ftoi")])
4536
4537 (define_insn "*movsf_nofp"
4538 [(set (match_operand:SF 0 "nonimmediate_operand" "=r,r,m")
4539 (match_operand:SF 1 "input_operand" "rG,m,r"))]
4540 "! TARGET_FPREGS
4541 && (register_operand (operands[0], SFmode)
4542 || reg_or_fp0_operand (operands[1], SFmode))"
4543 "@
4544 mov %r1,%0
4545 ldl %0,%1
4546 stl %r1,%0"
4547 [(set_attr "type" "ilog,ild,ist")])
4548
4549 (define_insn "*movdf_nofix"
4550 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,f,*r,*r,m,m")
4551 (match_operand:DF 1 "input_operand" "fG,m,*rG,m,fG,*r"))]
4552 "TARGET_FPREGS && ! TARGET_FIX
4553 && (register_operand (operands[0], DFmode)
4554 || reg_or_fp0_operand (operands[1], DFmode))"
4555 "@
4556 fmov %R1,%0
4557 ld%- %0,%1
4558 mov %r1,%0
4559 ldq %0,%1
4560 st%- %R1,%0
4561 stq %r1,%0"
4562 [(set_attr "type" "fcpys,fld,ilog,ild,fst,ist")])
4563
4564 (define_insn "*movdf_fix"
4565 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,f,*r,*r,m,m,f,*r")
4566 (match_operand:DF 1 "input_operand" "fG,m,*rG,m,fG,*r,*r,f"))]
4567 "TARGET_FPREGS && TARGET_FIX
4568 && (register_operand (operands[0], DFmode)
4569 || reg_or_fp0_operand (operands[1], DFmode))"
4570 "@
4571 fmov %R1,%0
4572 ld%- %0,%1
4573 mov %r1,%0
4574 ldq %0,%1
4575 st%- %R1,%0
4576 stq %r1,%0
4577 itoft %1,%0
4578 ftoit %1,%0"
4579 [(set_attr "type" "fcpys,fld,ilog,ild,fst,ist,itof,ftoi")])
4580
4581 (define_insn "*movdf_nofp"
4582 [(set (match_operand:DF 0 "nonimmediate_operand" "=r,r,m")
4583 (match_operand:DF 1 "input_operand" "rG,m,r"))]
4584 "! TARGET_FPREGS
4585 && (register_operand (operands[0], DFmode)
4586 || reg_or_fp0_operand (operands[1], DFmode))"
4587 "@
4588 mov %r1,%0
4589 ldq %0,%1
4590 stq %r1,%0"
4591 [(set_attr "type" "ilog,ild,ist")])
4592
4593 ;; Subregs suck for register allocation. Pretend we can move TFmode
4594 ;; data between general registers until after reload.
4595
4596 (define_insn_and_split "*movtf_internal"
4597 [(set (match_operand:TF 0 "nonimmediate_operand" "=r,o")
4598 (match_operand:TF 1 "input_operand" "roG,r"))]
4599 "register_operand (operands[0], TFmode)
4600 || reg_or_fp0_operand (operands[1], TFmode)"
4601 "#"
4602 "reload_completed"
4603 [(set (match_dup 0) (match_dup 2))
4604 (set (match_dup 1) (match_dup 3))]
4605 "
4606 {
4607 alpha_split_tfmode_pair (operands);
4608 if (rtx_equal_p (operands[0], operands[3]))
4609 {
4610 rtx tmp;
4611 tmp = operands[0], operands[0] = operands[1], operands[1] = tmp;
4612 tmp = operands[2], operands[2] = operands[3], operands[3] = tmp;
4613 }
4614 }")
4615
4616 (define_expand "movsf"
4617 [(set (match_operand:SF 0 "nonimmediate_operand" "")
4618 (match_operand:SF 1 "general_operand" ""))]
4619 ""
4620 "
4621 {
4622 if (GET_CODE (operands[0]) == MEM
4623 && ! reg_or_fp0_operand (operands[1], SFmode))
4624 operands[1] = force_reg (SFmode, operands[1]);
4625 }")
4626
4627 (define_expand "movdf"
4628 [(set (match_operand:DF 0 "nonimmediate_operand" "")
4629 (match_operand:DF 1 "general_operand" ""))]
4630 ""
4631 "
4632 {
4633 if (GET_CODE (operands[0]) == MEM
4634 && ! reg_or_fp0_operand (operands[1], DFmode))
4635 operands[1] = force_reg (DFmode, operands[1]);
4636 }")
4637
4638 (define_expand "movtf"
4639 [(set (match_operand:TF 0 "nonimmediate_operand" "")
4640 (match_operand:TF 1 "general_operand" ""))]
4641 ""
4642 "
4643 {
4644 if (GET_CODE (operands[0]) == MEM
4645 && ! reg_or_fp0_operand (operands[1], TFmode))
4646 operands[1] = force_reg (TFmode, operands[1]);
4647 }")
4648
4649 (define_insn "*movsi_nofix"
4650 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,r,r,m,*f,*f,m")
4651 (match_operand:SI 1 "input_operand" "rJ,K,L,m,rJ,*fJ,m,*f"))]
4652 "! TARGET_WINDOWS_NT && ! TARGET_OPEN_VMS && ! TARGET_FIX
4653 && (register_operand (operands[0], SImode)
4654 || reg_or_0_operand (operands[1], SImode))"
4655 "@
4656 mov %r1,%0
4657 lda %0,%1
4658 ldah %0,%h1
4659 ldl %0,%1
4660 stl %r1,%0
4661 fmov %R1,%0
4662 ld%, %0,%1
4663 st%, %R1,%0"
4664 [(set_attr "type" "ilog,iadd,iadd,ild,ist,fcpys,fld,fst")])
4665
4666 (define_insn "*movsf_fix"
4667 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,r,r,m,*f,*f,m,r,*f")
4668 (match_operand:SI 1 "input_operand" "rJ,K,L,m,rJ,*fJ,m,*f,*f,r"))]
4669 "! TARGET_WINDOWS_NT && ! TARGET_OPEN_VMS && TARGET_FIX
4670 && (register_operand (operands[0], SImode)
4671 || reg_or_0_operand (operands[1], SImode))"
4672 "@
4673 mov %r1,%0
4674 lda %0,%1
4675 ldah %0,%h1
4676 ldl %0,%1
4677 stl %r1,%0
4678 fmov %R1,%0
4679 ld%, %0,%1
4680 st%, %R1,%0
4681 ftois %1,%0
4682 itofs %1,%0"
4683 [(set_attr "type" "ilog,iadd,iadd,ild,ist,fcpys,fld,fst,ftoi,itof")])
4684
4685 (define_insn "*movsi_nt_vms"
4686 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,r,r,r,m,*f,*f,m")
4687 (match_operand:SI 1 "input_operand" "rJ,K,L,s,m,rJ,*fJ,m,*f"))]
4688 "(TARGET_WINDOWS_NT || TARGET_OPEN_VMS)
4689 && (register_operand (operands[0], SImode)
4690 || reg_or_0_operand (operands[1], SImode))"
4691 "@
4692 mov %1,%0
4693 lda %0,%1
4694 ldah %0,%h1
4695 lda %0,%1
4696 ldl %0,%1
4697 stl %r1,%0
4698 fmov %R1,%0
4699 ld%, %0,%1
4700 st%, %R1,%0"
4701 [(set_attr "type" "ilog,iadd,iadd,ldsym,ild,ist,fcpys,fld,fst")])
4702
4703 (define_insn "*movhi_nobwx"
4704 [(set (match_operand:HI 0 "register_operand" "=r,r")
4705 (match_operand:HI 1 "input_operand" "rJ,n"))]
4706 "! TARGET_BWX
4707 && (register_operand (operands[0], HImode)
4708 || register_operand (operands[1], HImode))"
4709 "@
4710 mov %r1,%0
4711 lda %0,%L1"
4712 [(set_attr "type" "ilog,iadd")])
4713
4714 (define_insn "*movhi_bwx"
4715 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
4716 (match_operand:HI 1 "input_operand" "rJ,n,m,rJ"))]
4717 "TARGET_BWX
4718 && (register_operand (operands[0], HImode)
4719 || reg_or_0_operand (operands[1], HImode))"
4720 "@
4721 mov %r1,%0
4722 lda %0,%L1
4723 ldwu %0,%1
4724 stw %r1,%0"
4725 [(set_attr "type" "ilog,iadd,ild,ist")])
4726
4727 (define_insn "*movqi_nobwx"
4728 [(set (match_operand:QI 0 "register_operand" "=r,r")
4729 (match_operand:QI 1 "input_operand" "rJ,n"))]
4730 "! TARGET_BWX
4731 && (register_operand (operands[0], QImode)
4732 || register_operand (operands[1], QImode))"
4733 "@
4734 mov %r1,%0
4735 lda %0,%L1"
4736 [(set_attr "type" "ilog,iadd")])
4737
4738 (define_insn "*movqi_bwx"
4739 [(set (match_operand:QI 0 "nonimmediate_operand" "=r,r,r,m")
4740 (match_operand:QI 1 "input_operand" "rJ,n,m,rJ"))]
4741 "TARGET_BWX
4742 && (register_operand (operands[0], QImode)
4743 || reg_or_0_operand (operands[1], QImode))"
4744 "@
4745 mov %r1,%0
4746 lda %0,%L1
4747 ldbu %0,%1
4748 stb %r1,%0"
4749 [(set_attr "type" "ilog,iadd,ild,ist")])
4750
4751 ;; We do two major things here: handle mem->mem and construct long
4752 ;; constants.
4753
4754 (define_expand "movsi"
4755 [(set (match_operand:SI 0 "nonimmediate_operand" "")
4756 (match_operand:SI 1 "general_operand" ""))]
4757 ""
4758 "
4759 {
4760 if (GET_CODE (operands[0]) == MEM
4761 && ! reg_or_0_operand (operands[1], SImode))
4762 operands[1] = force_reg (SImode, operands[1]);
4763
4764 if (! CONSTANT_P (operands[1]) || input_operand (operands[1], SImode))
4765 ;
4766 else if (GET_CODE (operands[1]) == CONST_INT)
4767 {
4768 operands[1]
4769 = alpha_emit_set_const (operands[0], SImode, INTVAL (operands[1]), 3);
4770 if (rtx_equal_p (operands[0], operands[1]))
4771 DONE;
4772 }
4773 }")
4774
4775 ;; Split a load of a large constant into the appropriate two-insn
4776 ;; sequence.
4777
4778 (define_split
4779 [(set (match_operand:SI 0 "register_operand" "")
4780 (match_operand:SI 1 "const_int_operand" ""))]
4781 "! add_operand (operands[1], SImode)"
4782 [(set (match_dup 0) (match_dup 2))
4783 (set (match_dup 0) (plus:SI (match_dup 0) (match_dup 3)))]
4784 "
4785 { rtx tem
4786 = alpha_emit_set_const (operands[0], SImode, INTVAL (operands[1]), 2);
4787
4788 if (tem == operands[0])
4789 DONE;
4790 else
4791 FAIL;
4792 }")
4793
4794 (define_insn "*movdi_nofix"
4795 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,r,r,r,m,*f,*f,Q")
4796 (match_operand:DI 1 "input_operand" "rJ,K,L,s,m,rJ,*fJ,Q,*f"))]
4797 "! TARGET_FIX
4798 && (register_operand (operands[0], DImode)
4799 || reg_or_0_operand (operands[1], DImode))"
4800 "@
4801 mov %r1,%0
4802 lda %0,%1
4803 ldah %0,%h1
4804 lda %0,%1
4805 ldq%A1 %0,%1
4806 stq%A0 %r1,%0
4807 fmov %R1,%0
4808 ldt %0,%1
4809 stt %R1,%0"
4810 [(set_attr "type" "ilog,iadd,iadd,ldsym,ild,ist,fcpys,fld,fst")])
4811
4812 (define_insn "*movdi_fix"
4813 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,r,r,r,m,*f,*f,Q,r,*f")
4814 (match_operand:DI 1 "input_operand" "rJ,K,L,s,m,rJ,*fJ,Q,*f,*f,r"))]
4815 "TARGET_FIX
4816 && (register_operand (operands[0], DImode)
4817 || reg_or_0_operand (operands[1], DImode))"
4818 "@
4819 mov %r1,%0
4820 lda %0,%1
4821 ldah %0,%h1
4822 lda %0,%1
4823 ldq%A1 %0,%1
4824 stq%A0 %r1,%0
4825 fmov %R1,%0
4826 ldt %0,%1
4827 stt %R1,%0
4828 ftoit %1,%0
4829 itoft %1,%0"
4830 [(set_attr "type" "ilog,iadd,iadd,ldsym,ild,ist,fcpys,fld,fst,ftoi,itof")])
4831
4832 ;; We do three major things here: handle mem->mem, put 64-bit constants in
4833 ;; memory, and construct long 32-bit constants.
4834
4835 (define_expand "movdi"
4836 [(set (match_operand:DI 0 "nonimmediate_operand" "")
4837 (match_operand:DI 1 "general_operand" ""))]
4838 ""
4839 "
4840 {
4841 rtx tem;
4842
4843 if (GET_CODE (operands[0]) == MEM
4844 && ! reg_or_0_operand (operands[1], DImode))
4845 operands[1] = force_reg (DImode, operands[1]);
4846
4847 if (! CONSTANT_P (operands[1]) || input_operand (operands[1], DImode))
4848 ;
4849 else if (GET_CODE (operands[1]) == CONST_INT
4850 && (tem = alpha_emit_set_const (operands[0], DImode,
4851 INTVAL (operands[1]), 3)) != 0)
4852 {
4853 if (rtx_equal_p (tem, operands[0]))
4854 DONE;
4855 else
4856 operands[1] = tem;
4857 }
4858 else if (CONSTANT_P (operands[1]))
4859 {
4860 if (TARGET_BUILD_CONSTANTS)
4861 {
4862 HOST_WIDE_INT i0, i1;
4863
4864 if (GET_CODE (operands[1]) == CONST_INT)
4865 {
4866 i0 = INTVAL (operands[1]);
4867 i1 = -(i0 < 0);
4868 }
4869 else if (GET_CODE (operands[1]) == CONST_DOUBLE)
4870 {
4871 #if HOST_BITS_PER_WIDE_INT >= 64
4872 i0 = CONST_DOUBLE_LOW (operands[1]);
4873 i1 = -(i0 < 0);
4874 #else
4875 i0 = CONST_DOUBLE_LOW (operands[1]);
4876 i1 = CONST_DOUBLE_HIGH (operands[1]);
4877 #endif
4878 }
4879 else
4880 abort();
4881
4882 tem = alpha_emit_set_long_const (operands[0], i0, i1);
4883 if (rtx_equal_p (tem, operands[0]))
4884 DONE;
4885 else
4886 operands[1] = tem;
4887 }
4888 else
4889 {
4890 operands[1] = force_const_mem (DImode, operands[1]);
4891 if (reload_in_progress)
4892 {
4893 emit_move_insn (operands[0], XEXP (operands[1], 0));
4894 operands[1] = copy_rtx (operands[1]);
4895 XEXP (operands[1], 0) = operands[0];
4896 }
4897 else
4898 operands[1] = validize_mem (operands[1]);
4899 }
4900 }
4901 else
4902 abort ();
4903 }")
4904
4905 ;; Split a load of a large constant into the appropriate two-insn
4906 ;; sequence.
4907
4908 (define_split
4909 [(set (match_operand:DI 0 "register_operand" "")
4910 (match_operand:DI 1 "const_int_operand" ""))]
4911 "! add_operand (operands[1], DImode)"
4912 [(set (match_dup 0) (match_dup 2))
4913 (set (match_dup 0) (plus:DI (match_dup 0) (match_dup 3)))]
4914 "
4915 { rtx tem
4916 = alpha_emit_set_const (operands[0], DImode, INTVAL (operands[1]), 2);
4917
4918 if (tem == operands[0])
4919 DONE;
4920 else
4921 FAIL;
4922 }")
4923
4924 ;; These are the partial-word cases.
4925 ;;
4926 ;; First we have the code to load an aligned word. Operand 0 is the register
4927 ;; in which to place the result. It's mode is QImode or HImode. Operand 1
4928 ;; is an SImode MEM at the low-order byte of the proper word. Operand 2 is the
4929 ;; number of bits within the word that the value is. Operand 3 is an SImode
4930 ;; scratch register. If operand 0 is a hard register, operand 3 may be the
4931 ;; same register. It is allowed to conflict with operand 1 as well.
4932
4933 (define_expand "aligned_loadqi"
4934 [(set (match_operand:SI 3 "register_operand" "")
4935 (match_operand:SI 1 "memory_operand" ""))
4936 (set (subreg:DI (match_operand:QI 0 "register_operand" "") 0)
4937 (zero_extract:DI (subreg:DI (match_dup 3) 0)
4938 (const_int 8)
4939 (match_operand:DI 2 "const_int_operand" "")))]
4940
4941 ""
4942 "")
4943
4944 (define_expand "aligned_loadhi"
4945 [(set (match_operand:SI 3 "register_operand" "")
4946 (match_operand:SI 1 "memory_operand" ""))
4947 (set (subreg:DI (match_operand:HI 0 "register_operand" "") 0)
4948 (zero_extract:DI (subreg:DI (match_dup 3) 0)
4949 (const_int 16)
4950 (match_operand:DI 2 "const_int_operand" "")))]
4951
4952 ""
4953 "")
4954
4955 ;; Similar for unaligned loads, where we use the sequence from the
4956 ;; Alpha Architecture manual.
4957 ;;
4958 ;; Operand 1 is the address. Operands 2 and 3 are temporaries, where
4959 ;; operand 3 can overlap the input and output registers.
4960
4961 (define_expand "unaligned_loadqi"
4962 [(set (match_operand:DI 2 "register_operand" "")
4963 (mem:DI (and:DI (match_operand:DI 1 "address_operand" "")
4964 (const_int -8))))
4965 (set (match_operand:DI 3 "register_operand" "")
4966 (match_dup 1))
4967 (set (subreg:DI (match_operand:QI 0 "register_operand" "") 0)
4968 (zero_extract:DI (match_dup 2)
4969 (const_int 8)
4970 (ashift:DI (match_dup 3) (const_int 3))))]
4971 ""
4972 "")
4973
4974 (define_expand "unaligned_loadhi"
4975 [(set (match_operand:DI 2 "register_operand" "")
4976 (mem:DI (and:DI (match_operand:DI 1 "address_operand" "")
4977 (const_int -8))))
4978 (set (match_operand:DI 3 "register_operand" "")
4979 (match_dup 1))
4980 (set (subreg:DI (match_operand:QI 0 "register_operand" "") 0)
4981 (zero_extract:DI (match_dup 2)
4982 (const_int 16)
4983 (ashift:DI (match_dup 3) (const_int 3))))]
4984 ""
4985 "")
4986
4987 ;; Storing an aligned byte or word requires two temporaries. Operand 0 is the
4988 ;; aligned SImode MEM. Operand 1 is the register containing the
4989 ;; byte or word to store. Operand 2 is the number of bits within the word that
4990 ;; the value should be placed. Operands 3 and 4 are SImode temporaries.
4991
4992 (define_expand "aligned_store"
4993 [(set (match_operand:SI 3 "register_operand" "")
4994 (match_operand:SI 0 "memory_operand" ""))
4995 (set (subreg:DI (match_dup 3) 0)
4996 (and:DI (subreg:DI (match_dup 3) 0) (match_dup 5)))
4997 (set (subreg:DI (match_operand:SI 4 "register_operand" "") 0)
4998 (ashift:DI (zero_extend:DI (match_operand 1 "register_operand" ""))
4999 (match_operand:DI 2 "const_int_operand" "")))
5000 (set (subreg:DI (match_dup 4) 0)
5001 (ior:DI (subreg:DI (match_dup 4) 0) (subreg:DI (match_dup 3) 0)))
5002 (set (match_dup 0) (match_dup 4))]
5003 ""
5004 "
5005 { operands[5] = GEN_INT (~ (GET_MODE_MASK (GET_MODE (operands[1]))
5006 << INTVAL (operands[2])));
5007 }")
5008
5009 ;; For the unaligned byte and halfword cases, we use code similar to that
5010 ;; in the ;; Architecture book, but reordered to lower the number of registers
5011 ;; required. Operand 0 is the address. Operand 1 is the data to store.
5012 ;; Operands 2, 3, and 4 are DImode temporaries, where operands 2 and 4 may
5013 ;; be the same temporary, if desired. If the address is in a register,
5014 ;; operand 2 can be that register.
5015
5016 (define_expand "unaligned_storeqi"
5017 [(set (match_operand:DI 3 "register_operand" "")
5018 (mem:DI (and:DI (match_operand:DI 0 "address_operand" "")
5019 (const_int -8))))
5020 (set (match_operand:DI 2 "register_operand" "")
5021 (match_dup 0))
5022 (set (match_dup 3)
5023 (and:DI (not:DI (ashift:DI (const_int 255)
5024 (ashift:DI (match_dup 2) (const_int 3))))
5025 (match_dup 3)))
5026 (set (match_operand:DI 4 "register_operand" "")
5027 (ashift:DI (zero_extend:DI (match_operand:QI 1 "register_operand" ""))
5028 (ashift:DI (match_dup 2) (const_int 3))))
5029 (set (match_dup 4) (ior:DI (match_dup 4) (match_dup 3)))
5030 (set (mem:DI (and:DI (match_dup 0) (const_int -8)))
5031 (match_dup 4))]
5032 ""
5033 "")
5034
5035 (define_expand "unaligned_storehi"
5036 [(set (match_operand:DI 3 "register_operand" "")
5037 (mem:DI (and:DI (match_operand:DI 0 "address_operand" "")
5038 (const_int -8))))
5039 (set (match_operand:DI 2 "register_operand" "")
5040 (match_dup 0))
5041 (set (match_dup 3)
5042 (and:DI (not:DI (ashift:DI (const_int 65535)
5043 (ashift:DI (match_dup 2) (const_int 3))))
5044 (match_dup 3)))
5045 (set (match_operand:DI 4 "register_operand" "")
5046 (ashift:DI (zero_extend:DI (match_operand:HI 1 "register_operand" ""))
5047 (ashift:DI (match_dup 2) (const_int 3))))
5048 (set (match_dup 4) (ior:DI (match_dup 4) (match_dup 3)))
5049 (set (mem:DI (and:DI (match_dup 0) (const_int -8)))
5050 (match_dup 4))]
5051 ""
5052 "")
5053 \f
5054 ;; Here are the define_expand's for QI and HI moves that use the above
5055 ;; patterns. We have the normal sets, plus the ones that need scratch
5056 ;; registers for reload.
5057
5058 (define_expand "movqi"
5059 [(set (match_operand:QI 0 "nonimmediate_operand" "")
5060 (match_operand:QI 1 "general_operand" ""))]
5061 ""
5062 "
5063 {
5064 if (TARGET_BWX)
5065 {
5066 if (GET_CODE (operands[0]) == MEM
5067 && ! reg_or_0_operand (operands[1], QImode))
5068 operands[1] = force_reg (QImode, operands[1]);
5069
5070 if (GET_CODE (operands[1]) == CONST_INT
5071 && ! input_operand (operands[1], QImode))
5072 {
5073 operands[1] = alpha_emit_set_const (operands[0], QImode,
5074 INTVAL (operands[1]), 3);
5075
5076 if (rtx_equal_p (operands[0], operands[1]))
5077 DONE;
5078 }
5079
5080 goto def;
5081 }
5082
5083 /* If the output is not a register, the input must be. */
5084 if (GET_CODE (operands[0]) == MEM)
5085 operands[1] = force_reg (QImode, operands[1]);
5086
5087 /* Handle four memory cases, unaligned and aligned for either the input
5088 or the output. The only case where we can be called during reload is
5089 for aligned loads; all other cases require temporaries. */
5090
5091 if (GET_CODE (operands[1]) == MEM
5092 || (GET_CODE (operands[1]) == SUBREG
5093 && GET_CODE (SUBREG_REG (operands[1])) == MEM)
5094 || (reload_in_progress && GET_CODE (operands[1]) == REG
5095 && REGNO (operands[1]) >= FIRST_PSEUDO_REGISTER)
5096 || (reload_in_progress && GET_CODE (operands[1]) == SUBREG
5097 && GET_CODE (SUBREG_REG (operands[1])) == REG
5098 && REGNO (SUBREG_REG (operands[1])) >= FIRST_PSEUDO_REGISTER))
5099 {
5100 if (aligned_memory_operand (operands[1], QImode))
5101 {
5102 if (reload_in_progress)
5103 {
5104 emit_insn (gen_reload_inqi_help
5105 (operands[0], operands[1],
5106 gen_rtx_REG (SImode, REGNO (operands[0]))));
5107 }
5108 else
5109 {
5110 rtx aligned_mem, bitnum;
5111 rtx scratch = gen_reg_rtx (SImode);
5112
5113 get_aligned_mem (operands[1], &aligned_mem, &bitnum);
5114
5115 emit_insn (gen_aligned_loadqi (operands[0], aligned_mem, bitnum,
5116 scratch));
5117 }
5118 }
5119 else
5120 {
5121 /* Don't pass these as parameters since that makes the generated
5122 code depend on parameter evaluation order which will cause
5123 bootstrap failures. */
5124
5125 rtx temp1 = gen_reg_rtx (DImode);
5126 rtx temp2 = gen_reg_rtx (DImode);
5127 rtx seq
5128 = gen_unaligned_loadqi (operands[0],
5129 get_unaligned_address (operands[1], 0),
5130 temp1, temp2);
5131
5132 alpha_set_memflags (seq, operands[1]);
5133 emit_insn (seq);
5134 }
5135
5136 DONE;
5137 }
5138
5139 else if (GET_CODE (operands[0]) == MEM
5140 || (GET_CODE (operands[0]) == SUBREG
5141 && GET_CODE (SUBREG_REG (operands[0])) == MEM)
5142 || (reload_in_progress && GET_CODE (operands[0]) == REG
5143 && REGNO (operands[0]) >= FIRST_PSEUDO_REGISTER)
5144 || (reload_in_progress && GET_CODE (operands[0]) == SUBREG
5145 && GET_CODE (SUBREG_REG (operands[0])) == REG
5146 && REGNO (operands[0]) >= FIRST_PSEUDO_REGISTER))
5147 {
5148 if (aligned_memory_operand (operands[0], QImode))
5149 {
5150 rtx aligned_mem, bitnum;
5151 rtx temp1 = gen_reg_rtx (SImode);
5152 rtx temp2 = gen_reg_rtx (SImode);
5153
5154 get_aligned_mem (operands[0], &aligned_mem, &bitnum);
5155
5156 emit_insn (gen_aligned_store (aligned_mem, operands[1], bitnum,
5157 temp1, temp2));
5158 }
5159 else
5160 {
5161 rtx temp1 = gen_reg_rtx (DImode);
5162 rtx temp2 = gen_reg_rtx (DImode);
5163 rtx temp3 = gen_reg_rtx (DImode);
5164 rtx seq
5165 = gen_unaligned_storeqi (get_unaligned_address (operands[0], 0),
5166 operands[1], temp1, temp2, temp3);
5167
5168 alpha_set_memflags (seq, operands[0]);
5169 emit_insn (seq);
5170 }
5171 DONE;
5172 }
5173 def:;
5174 }")
5175
5176 (define_expand "movhi"
5177 [(set (match_operand:HI 0 "nonimmediate_operand" "")
5178 (match_operand:HI 1 "general_operand" ""))]
5179 ""
5180 "
5181 {
5182 if (TARGET_BWX)
5183 {
5184 if (GET_CODE (operands[0]) == MEM
5185 && ! reg_or_0_operand (operands[1], HImode))
5186 operands[1] = force_reg (HImode, operands[1]);
5187
5188 if (GET_CODE (operands[1]) == CONST_INT
5189 && ! input_operand (operands[1], HImode))
5190 {
5191 operands[1] = alpha_emit_set_const (operands[0], HImode,
5192 INTVAL (operands[1]), 3);
5193
5194 if (rtx_equal_p (operands[0], operands[1]))
5195 DONE;
5196 }
5197
5198 goto def;
5199 }
5200
5201 /* If the output is not a register, the input must be. */
5202 if (GET_CODE (operands[0]) == MEM)
5203 operands[1] = force_reg (HImode, operands[1]);
5204
5205 /* Handle four memory cases, unaligned and aligned for either the input
5206 or the output. The only case where we can be called during reload is
5207 for aligned loads; all other cases require temporaries. */
5208
5209 if (GET_CODE (operands[1]) == MEM
5210 || (GET_CODE (operands[1]) == SUBREG
5211 && GET_CODE (SUBREG_REG (operands[1])) == MEM)
5212 || (reload_in_progress && GET_CODE (operands[1]) == REG
5213 && REGNO (operands[1]) >= FIRST_PSEUDO_REGISTER)
5214 || (reload_in_progress && GET_CODE (operands[1]) == SUBREG
5215 && GET_CODE (SUBREG_REG (operands[1])) == REG
5216 && REGNO (SUBREG_REG (operands[1])) >= FIRST_PSEUDO_REGISTER))
5217 {
5218 if (aligned_memory_operand (operands[1], HImode))
5219 {
5220 if (reload_in_progress)
5221 {
5222 emit_insn (gen_reload_inhi_help
5223 (operands[0], operands[1],
5224 gen_rtx_REG (SImode, REGNO (operands[0]))));
5225 }
5226 else
5227 {
5228 rtx aligned_mem, bitnum;
5229 rtx scratch = gen_reg_rtx (SImode);
5230
5231 get_aligned_mem (operands[1], &aligned_mem, &bitnum);
5232
5233 emit_insn (gen_aligned_loadhi (operands[0], aligned_mem, bitnum,
5234 scratch));
5235 }
5236 }
5237 else
5238 {
5239 /* Don't pass these as parameters since that makes the generated
5240 code depend on parameter evaluation order which will cause
5241 bootstrap failures. */
5242
5243 rtx temp1 = gen_reg_rtx (DImode);
5244 rtx temp2 = gen_reg_rtx (DImode);
5245 rtx seq
5246 = gen_unaligned_loadhi (operands[0],
5247 get_unaligned_address (operands[1], 0),
5248 temp1, temp2);
5249
5250 alpha_set_memflags (seq, operands[1]);
5251 emit_insn (seq);
5252 }
5253
5254 DONE;
5255 }
5256
5257 else if (GET_CODE (operands[0]) == MEM
5258 || (GET_CODE (operands[0]) == SUBREG
5259 && GET_CODE (SUBREG_REG (operands[0])) == MEM)
5260 || (reload_in_progress && GET_CODE (operands[0]) == REG
5261 && REGNO (operands[0]) >= FIRST_PSEUDO_REGISTER)
5262 || (reload_in_progress && GET_CODE (operands[0]) == SUBREG
5263 && GET_CODE (SUBREG_REG (operands[0])) == REG
5264 && REGNO (operands[0]) >= FIRST_PSEUDO_REGISTER))
5265 {
5266 if (aligned_memory_operand (operands[0], HImode))
5267 {
5268 rtx aligned_mem, bitnum;
5269 rtx temp1 = gen_reg_rtx (SImode);
5270 rtx temp2 = gen_reg_rtx (SImode);
5271
5272 get_aligned_mem (operands[0], &aligned_mem, &bitnum);
5273
5274 emit_insn (gen_aligned_store (aligned_mem, operands[1], bitnum,
5275 temp1, temp2));
5276 }
5277 else
5278 {
5279 rtx temp1 = gen_reg_rtx (DImode);
5280 rtx temp2 = gen_reg_rtx (DImode);
5281 rtx temp3 = gen_reg_rtx (DImode);
5282 rtx seq
5283 = gen_unaligned_storehi (get_unaligned_address (operands[0], 0),
5284 operands[1], temp1, temp2, temp3);
5285
5286 alpha_set_memflags (seq, operands[0]);
5287 emit_insn (seq);
5288 }
5289
5290 DONE;
5291 }
5292 def:;
5293 }")
5294
5295 ;; Here are the versions for reload. Note that in the unaligned cases
5296 ;; we know that the operand must not be a pseudo-register because stack
5297 ;; slots are always aligned references.
5298
5299 (define_expand "reload_inqi"
5300 [(parallel [(match_operand:QI 0 "register_operand" "=r")
5301 (match_operand:QI 1 "any_memory_operand" "m")
5302 (match_operand:TI 2 "register_operand" "=&r")])]
5303 "! TARGET_BWX"
5304 "
5305 {
5306 rtx scratch, seq;
5307
5308 if (GET_CODE (operands[1]) != MEM)
5309 abort ();
5310
5311 if (aligned_memory_operand (operands[1], QImode))
5312 {
5313 seq = gen_reload_inqi_help (operands[0], operands[1],
5314 gen_rtx_REG (SImode, REGNO (operands[2])));
5315 }
5316 else
5317 {
5318 rtx addr;
5319
5320 /* It is possible that one of the registers we got for operands[2]
5321 might coincide with that of operands[0] (which is why we made
5322 it TImode). Pick the other one to use as our scratch. */
5323 if (REGNO (operands[0]) == REGNO (operands[2]))
5324 scratch = gen_rtx_REG (DImode, REGNO (operands[2]) + 1);
5325 else
5326 scratch = gen_rtx_REG (DImode, REGNO (operands[2]));
5327
5328 addr = get_unaligned_address (operands[1], 0);
5329 seq = gen_unaligned_loadqi (operands[0], addr, scratch,
5330 gen_rtx_REG (DImode, REGNO (operands[0])));
5331 alpha_set_memflags (seq, operands[1]);
5332 }
5333 emit_insn (seq);
5334 DONE;
5335 }")
5336
5337 (define_expand "reload_inhi"
5338 [(parallel [(match_operand:HI 0 "register_operand" "=r")
5339 (match_operand:HI 1 "any_memory_operand" "m")
5340 (match_operand:TI 2 "register_operand" "=&r")])]
5341 "! TARGET_BWX"
5342 "
5343 {
5344 rtx scratch, seq;
5345
5346 if (GET_CODE (operands[1]) != MEM)
5347 abort ();
5348
5349 if (aligned_memory_operand (operands[1], HImode))
5350 {
5351 seq = gen_reload_inhi_help (operands[0], operands[1],
5352 gen_rtx_REG (SImode, REGNO (operands[2])));
5353 }
5354 else
5355 {
5356 rtx addr;
5357
5358 /* It is possible that one of the registers we got for operands[2]
5359 might coincide with that of operands[0] (which is why we made
5360 it TImode). Pick the other one to use as our scratch. */
5361 if (REGNO (operands[0]) == REGNO (operands[2]))
5362 scratch = gen_rtx_REG (DImode, REGNO (operands[2]) + 1);
5363 else
5364 scratch = gen_rtx_REG (DImode, REGNO (operands[2]));
5365
5366 addr = get_unaligned_address (operands[1], 0);
5367 seq = gen_unaligned_loadhi (operands[0], addr, scratch,
5368 gen_rtx_REG (DImode, REGNO (operands[0])));
5369 alpha_set_memflags (seq, operands[1]);
5370 }
5371 emit_insn (seq);
5372 DONE;
5373 }")
5374
5375 (define_expand "reload_outqi"
5376 [(parallel [(match_operand:QI 0 "any_memory_operand" "=m")
5377 (match_operand:QI 1 "register_operand" "r")
5378 (match_operand:TI 2 "register_operand" "=&r")])]
5379 "! TARGET_BWX"
5380 "
5381 {
5382 if (GET_CODE (operands[0]) != MEM)
5383 abort ();
5384
5385 if (aligned_memory_operand (operands[0], QImode))
5386 {
5387 emit_insn (gen_reload_outqi_help
5388 (operands[0], operands[1],
5389 gen_rtx_REG (SImode, REGNO (operands[2])),
5390 gen_rtx_REG (SImode, REGNO (operands[2]) + 1)));
5391 }
5392 else
5393 {
5394 rtx addr = get_unaligned_address (operands[0], 0);
5395 rtx scratch1 = gen_rtx_REG (DImode, REGNO (operands[2]));
5396 rtx scratch2 = gen_rtx_REG (DImode, REGNO (operands[2]) + 1);
5397 rtx scratch3 = scratch1;
5398 rtx seq;
5399
5400 if (GET_CODE (addr) == REG)
5401 scratch1 = addr;
5402
5403 seq = gen_unaligned_storeqi (addr, operands[1], scratch1,
5404 scratch2, scratch3);
5405 alpha_set_memflags (seq, operands[0]);
5406 emit_insn (seq);
5407 }
5408 DONE;
5409 }")
5410
5411 (define_expand "reload_outhi"
5412 [(parallel [(match_operand:HI 0 "any_memory_operand" "=m")
5413 (match_operand:HI 1 "register_operand" "r")
5414 (match_operand:TI 2 "register_operand" "=&r")])]
5415 "! TARGET_BWX"
5416 "
5417 {
5418 if (GET_CODE (operands[0]) != MEM)
5419 abort ();
5420
5421 if (aligned_memory_operand (operands[0], HImode))
5422 {
5423 emit_insn (gen_reload_outhi_help
5424 (operands[0], operands[1],
5425 gen_rtx_REG (SImode, REGNO (operands[2])),
5426 gen_rtx_REG (SImode, REGNO (operands[2]) + 1)));
5427 }
5428 else
5429 {
5430 rtx addr = get_unaligned_address (operands[0], 0);
5431 rtx scratch1 = gen_rtx_REG (DImode, REGNO (operands[2]));
5432 rtx scratch2 = gen_rtx_REG (DImode, REGNO (operands[2]) + 1);
5433 rtx scratch3 = scratch1;
5434 rtx seq;
5435
5436 if (GET_CODE (addr) == REG)
5437 scratch1 = addr;
5438
5439 seq = gen_unaligned_storehi (addr, operands[1], scratch1,
5440 scratch2, scratch3);
5441 alpha_set_memflags (seq, operands[0]);
5442 emit_insn (seq);
5443 }
5444 DONE;
5445 }")
5446
5447 ;; Helpers for the above. The way reload is structured, we can't
5448 ;; always get a proper address for a stack slot during reload_foo
5449 ;; expansion, so we must delay our address manipulations until after.
5450
5451 (define_insn "reload_inqi_help"
5452 [(set (match_operand:QI 0 "register_operand" "=r")
5453 (match_operand:QI 1 "memory_operand" "m"))
5454 (clobber (match_operand:SI 2 "register_operand" "=r"))]
5455 "! TARGET_BWX && (reload_in_progress || reload_completed)"
5456 "#")
5457
5458 (define_insn "reload_inhi_help"
5459 [(set (match_operand:HI 0 "register_operand" "=r")
5460 (match_operand:HI 1 "memory_operand" "m"))
5461 (clobber (match_operand:SI 2 "register_operand" "=r"))]
5462 "! TARGET_BWX && (reload_in_progress || reload_completed)"
5463 "#")
5464
5465 (define_insn "reload_outqi_help"
5466 [(set (match_operand:QI 0 "memory_operand" "=m")
5467 (match_operand:QI 1 "register_operand" "r"))
5468 (clobber (match_operand:SI 2 "register_operand" "=r"))
5469 (clobber (match_operand:SI 3 "register_operand" "=r"))]
5470 "! TARGET_BWX && (reload_in_progress || reload_completed)"
5471 "#")
5472
5473 (define_insn "reload_outhi_help"
5474 [(set (match_operand:HI 0 "memory_operand" "=m")
5475 (match_operand:HI 1 "register_operand" "r"))
5476 (clobber (match_operand:SI 2 "register_operand" "=r"))
5477 (clobber (match_operand:SI 3 "register_operand" "=r"))]
5478 "! TARGET_BWX && (reload_in_progress || reload_completed)"
5479 "#")
5480
5481 (define_split
5482 [(set (match_operand:QI 0 "register_operand" "")
5483 (match_operand:QI 1 "memory_operand" ""))
5484 (clobber (match_operand:SI 2 "register_operand" ""))]
5485 "! TARGET_BWX && reload_completed"
5486 [(const_int 0)]
5487 "
5488 {
5489 rtx aligned_mem, bitnum;
5490 get_aligned_mem (operands[1], &aligned_mem, &bitnum);
5491 emit_insn (gen_aligned_loadqi (operands[0], aligned_mem, bitnum,
5492 operands[2]));
5493 DONE;
5494 }")
5495
5496 (define_split
5497 [(set (match_operand:HI 0 "register_operand" "")
5498 (match_operand:HI 1 "memory_operand" ""))
5499 (clobber (match_operand:SI 2 "register_operand" ""))]
5500 "! TARGET_BWX && reload_completed"
5501 [(const_int 0)]
5502 "
5503 {
5504 rtx aligned_mem, bitnum;
5505 get_aligned_mem (operands[1], &aligned_mem, &bitnum);
5506 emit_insn (gen_aligned_loadhi (operands[0], aligned_mem, bitnum,
5507 operands[2]));
5508 DONE;
5509 }")
5510
5511 (define_split
5512 [(set (match_operand:QI 0 "memory_operand" "")
5513 (match_operand:QI 1 "register_operand" ""))
5514 (clobber (match_operand:SI 2 "register_operand" ""))
5515 (clobber (match_operand:SI 3 "register_operand" ""))]
5516 "! TARGET_BWX && reload_completed"
5517 [(const_int 0)]
5518 "
5519 {
5520 rtx aligned_mem, bitnum;
5521 get_aligned_mem (operands[0], &aligned_mem, &bitnum);
5522 emit_insn (gen_aligned_store (aligned_mem, operands[1], bitnum,
5523 operands[2], operands[3]));
5524 DONE;
5525 }")
5526
5527 (define_split
5528 [(set (match_operand:HI 0 "memory_operand" "")
5529 (match_operand:HI 1 "register_operand" ""))
5530 (clobber (match_operand:SI 2 "register_operand" ""))
5531 (clobber (match_operand:SI 3 "register_operand" ""))]
5532 "! TARGET_BWX && reload_completed"
5533 [(const_int 0)]
5534 "
5535 {
5536 rtx aligned_mem, bitnum;
5537 get_aligned_mem (operands[0], &aligned_mem, &bitnum);
5538 emit_insn (gen_aligned_store (aligned_mem, operands[1], bitnum,
5539 operands[2], operands[3]));
5540 DONE;
5541 }")
5542 \f
5543 ;; Bit field extract patterns which use ext[wlq][lh]
5544
5545 (define_expand "extv"
5546 [(set (match_operand:DI 0 "register_operand" "")
5547 (sign_extract:DI (match_operand:QI 1 "memory_operand" "")
5548 (match_operand:DI 2 "immediate_operand" "")
5549 (match_operand:DI 3 "immediate_operand" "")))]
5550 ""
5551 "
5552 {
5553 /* We can do 16, 32 and 64 bit fields, if aligned on byte boundaries. */
5554 if (INTVAL (operands[3]) % 8 != 0
5555 || (INTVAL (operands[2]) != 16
5556 && INTVAL (operands[2]) != 32
5557 && INTVAL (operands[2]) != 64))
5558 FAIL;
5559
5560 /* From mips.md: extract_bit_field doesn't verify that our source
5561 matches the predicate, so we force it to be a MEM here. */
5562 if (GET_CODE (operands[1]) != MEM)
5563 FAIL;
5564
5565 alpha_expand_unaligned_load (operands[0], operands[1],
5566 INTVAL (operands[2]) / 8,
5567 INTVAL (operands[3]) / 8, 1);
5568 DONE;
5569 }")
5570
5571 (define_expand "extzv"
5572 [(set (match_operand:DI 0 "register_operand" "")
5573 (zero_extract:DI (match_operand:DI 1 "nonimmediate_operand" "")
5574 (match_operand:DI 2 "immediate_operand" "")
5575 (match_operand:DI 3 "immediate_operand" "")))]
5576 ""
5577 "
5578 {
5579 /* We can do 8, 16, 32 and 64 bit fields, if aligned on byte boundaries. */
5580 if (INTVAL (operands[3]) % 8 != 0
5581 || (INTVAL (operands[2]) != 8
5582 && INTVAL (operands[2]) != 16
5583 && INTVAL (operands[2]) != 32
5584 && INTVAL (operands[2]) != 64))
5585 FAIL;
5586
5587 if (GET_CODE (operands[1]) == MEM)
5588 {
5589 /* Fail 8 bit fields, falling back on a simple byte load. */
5590 if (INTVAL (operands[2]) == 8)
5591 FAIL;
5592
5593 alpha_expand_unaligned_load (operands[0], operands[1],
5594 INTVAL (operands[2]) / 8,
5595 INTVAL (operands[3]) / 8, 0);
5596 DONE;
5597 }
5598 }")
5599
5600 (define_expand "insv"
5601 [(set (zero_extract:DI (match_operand:QI 0 "memory_operand" "")
5602 (match_operand:DI 1 "immediate_operand" "")
5603 (match_operand:DI 2 "immediate_operand" ""))
5604 (match_operand:DI 3 "register_operand" ""))]
5605 ""
5606 "
5607 {
5608 /* We can do 16, 32 and 64 bit fields, if aligned on byte boundaries. */
5609 if (INTVAL (operands[2]) % 8 != 0
5610 || (INTVAL (operands[1]) != 16
5611 && INTVAL (operands[1]) != 32
5612 && INTVAL (operands[1]) != 64))
5613 FAIL;
5614
5615 /* From mips.md: store_bit_field doesn't verify that our source
5616 matches the predicate, so we force it to be a MEM here. */
5617 if (GET_CODE (operands[0]) != MEM)
5618 FAIL;
5619
5620 alpha_expand_unaligned_store (operands[0], operands[3],
5621 INTVAL (operands[1]) / 8,
5622 INTVAL (operands[2]) / 8);
5623 DONE;
5624 }")
5625
5626 ;; Block move/clear, see alpha.c for more details.
5627 ;; Argument 0 is the destination
5628 ;; Argument 1 is the source
5629 ;; Argument 2 is the length
5630 ;; Argument 3 is the alignment
5631
5632 (define_expand "movstrqi"
5633 [(parallel [(set (match_operand:BLK 0 "memory_operand" "")
5634 (match_operand:BLK 1 "memory_operand" ""))
5635 (use (match_operand:DI 2 "immediate_operand" ""))
5636 (use (match_operand:DI 3 "immediate_operand" ""))])]
5637 ""
5638 "
5639 {
5640 if (alpha_expand_block_move (operands))
5641 DONE;
5642 else
5643 FAIL;
5644 }")
5645
5646 (define_expand "clrstrqi"
5647 [(parallel [(set (match_operand:BLK 0 "memory_operand" "")
5648 (const_int 0))
5649 (use (match_operand:DI 1 "immediate_operand" ""))
5650 (use (match_operand:DI 2 "immediate_operand" ""))])]
5651 ""
5652 "
5653 {
5654 if (alpha_expand_block_clear (operands))
5655 DONE;
5656 else
5657 FAIL;
5658 }")
5659 \f
5660 ;; Subroutine of stack space allocation. Perform a stack probe.
5661 (define_expand "probe_stack"
5662 [(set (match_dup 1) (match_operand:DI 0 "const_int_operand" ""))]
5663 ""
5664 "
5665 {
5666 operands[1] = gen_rtx_MEM (DImode, plus_constant (stack_pointer_rtx,
5667 INTVAL (operands[0])));
5668 MEM_VOLATILE_P (operands[1]) = 1;
5669
5670 operands[0] = const0_rtx;
5671 }")
5672
5673 ;; This is how we allocate stack space. If we are allocating a
5674 ;; constant amount of space and we know it is less than 4096
5675 ;; bytes, we need do nothing.
5676 ;;
5677 ;; If it is more than 4096 bytes, we need to probe the stack
5678 ;; periodically.
5679 (define_expand "allocate_stack"
5680 [(set (reg:DI 30)
5681 (plus:DI (reg:DI 30)
5682 (match_operand:DI 1 "reg_or_cint_operand" "")))
5683 (set (match_operand:DI 0 "register_operand" "=r")
5684 (match_dup 2))]
5685 ""
5686 "
5687 {
5688 if (GET_CODE (operands[1]) == CONST_INT
5689 && INTVAL (operands[1]) < 32768)
5690 {
5691 if (INTVAL (operands[1]) >= 4096)
5692 {
5693 /* We do this the same way as in the prologue and generate explicit
5694 probes. Then we update the stack by the constant. */
5695
5696 int probed = 4096;
5697
5698 emit_insn (gen_probe_stack (GEN_INT (- probed)));
5699 while (probed + 8192 < INTVAL (operands[1]))
5700 emit_insn (gen_probe_stack (GEN_INT (- (probed += 8192))));
5701
5702 if (probed + 4096 < INTVAL (operands[1]))
5703 emit_insn (gen_probe_stack (GEN_INT (- INTVAL(operands[1]))));
5704 }
5705
5706 operands[1] = GEN_INT (- INTVAL (operands[1]));
5707 operands[2] = virtual_stack_dynamic_rtx;
5708 }
5709 else
5710 {
5711 rtx out_label = 0;
5712 rtx loop_label = gen_label_rtx ();
5713 rtx want = gen_reg_rtx (Pmode);
5714 rtx tmp = gen_reg_rtx (Pmode);
5715 rtx memref;
5716
5717 emit_insn (gen_subdi3 (want, stack_pointer_rtx,
5718 force_reg (Pmode, operands[1])));
5719 emit_insn (gen_adddi3 (tmp, stack_pointer_rtx, GEN_INT (-4096)));
5720
5721 if (GET_CODE (operands[1]) != CONST_INT)
5722 {
5723 out_label = gen_label_rtx ();
5724 emit_insn (gen_cmpdi (want, tmp));
5725 emit_jump_insn (gen_bgeu (out_label));
5726 }
5727
5728 emit_label (loop_label);
5729 memref = gen_rtx_MEM (DImode, tmp);
5730 MEM_VOLATILE_P (memref) = 1;
5731 emit_move_insn (memref, const0_rtx);
5732 emit_insn (gen_adddi3 (tmp, tmp, GEN_INT(-8192)));
5733 emit_insn (gen_cmpdi (tmp, want));
5734 emit_jump_insn (gen_bgtu (loop_label));
5735
5736 memref = gen_rtx_MEM (DImode, want);
5737 MEM_VOLATILE_P (memref) = 1;
5738 emit_move_insn (memref, const0_rtx);
5739
5740 if (out_label)
5741 emit_label (out_label);
5742
5743 emit_move_insn (stack_pointer_rtx, want);
5744 emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
5745 DONE;
5746 }
5747 }")
5748
5749 ;; This is used by alpha_expand_prolog to do the same thing as above,
5750 ;; except we cannot at that time generate new basic blocks, so we hide
5751 ;; the loop in this one insn.
5752
5753 (define_insn "prologue_stack_probe_loop"
5754 [(unspec_volatile [(match_operand:DI 0 "register_operand" "r")
5755 (match_operand:DI 1 "register_operand" "r")] 5)]
5756 ""
5757 "*
5758 {
5759 operands[2] = gen_label_rtx ();
5760 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, \"L\",
5761 CODE_LABEL_NUMBER (operands[2]));
5762
5763 return \"stq $31,-8192(%1)\;subq %0,1,%0\;lda %1,-8192(%1)\;bne %0,%l2\";
5764 }"
5765 [(set_attr "length" "16")
5766 (set_attr "type" "multi")])
5767
5768 (define_expand "prologue"
5769 [(clobber (const_int 0))]
5770 ""
5771 "
5772 {
5773 alpha_expand_prologue ();
5774 DONE;
5775 }")
5776
5777 ;; These take care of emitting the ldgp insn in the prologue. This will be
5778 ;; an lda/ldah pair and we want to align them properly. So we have two
5779 ;; unspec_volatile insns, the first of which emits the ldgp assembler macro
5780 ;; and the second of which emits nothing. However, both are marked as type
5781 ;; IADD (the default) so the alignment code in alpha.c does the right thing
5782 ;; with them.
5783
5784 (define_expand "prologue_ldgp"
5785 [(unspec_volatile [(const_int 0)] 9)
5786 (unspec_volatile [(const_int 0)] 10)]
5787 ""
5788 "")
5789
5790 (define_insn "*prologue_ldgp_1"
5791 [(unspec_volatile [(const_int 0)] 9)]
5792 "! TARGET_OPEN_VMS && ! TARGET_WINDOWS_NT"
5793 "ldgp $29,0($27)\\n$%~..ng:")
5794
5795 (define_insn "*prologue_ldgp_2"
5796 [(unspec_volatile [(const_int 0)] 10)]
5797 "! TARGET_OPEN_VMS && ! TARGET_WINDOWS_NT"
5798 "")
5799
5800 ;; The _mcount profiling hook has special calling conventions, and
5801 ;; does not clobber all the registers that a normal call would. So
5802 ;; hide the fact this is a call at all.
5803
5804 (define_insn "prologue_mcount"
5805 [(unspec_volatile [(const_int 0)] 8)]
5806 ""
5807 "lda $28,_mcount\;jsr $28,($28),_mcount"
5808 [(set_attr "type" "multi")
5809 (set_attr "length" "8")])
5810
5811 (define_insn "init_fp"
5812 [(set (match_operand:DI 0 "register_operand" "=r")
5813 (match_operand:DI 1 "register_operand" "r"))
5814 (clobber (mem:BLK (match_operand:DI 2 "register_operand" "=r")))]
5815 ""
5816 "mov %1,%0")
5817
5818 (define_expand "epilogue"
5819 [(return)]
5820 ""
5821 "
5822 {
5823 alpha_expand_epilogue ();
5824 }")
5825
5826 (define_expand "sibcall_epilogue"
5827 [(return)]
5828 "!TARGET_OPEN_VMS && !TARGET_WINDOWS_NT"
5829 "
5830 {
5831 alpha_expand_epilogue ();
5832 DONE;
5833 }")
5834
5835 (define_expand "eh_epilogue"
5836 [(use (match_operand:DI 0 "register_operand" "r"))
5837 (use (match_operand:DI 1 "register_operand" "r"))
5838 (use (match_operand:DI 2 "register_operand" "r"))]
5839 "! TARGET_OPEN_VMS"
5840 "
5841 {
5842 cfun->machine->eh_epilogue_sp_ofs = operands[1];
5843 if (GET_CODE (operands[2]) != REG || REGNO (operands[2]) != 26)
5844 {
5845 rtx ra = gen_rtx_REG (Pmode, 26);
5846 emit_move_insn (ra, operands[2]);
5847 operands[2] = ra;
5848 }
5849 }")
5850
5851 ;; In creating a large stack frame, NT _must_ use ldah+lda to load
5852 ;; the frame size into a register. We use this pattern to ensure
5853 ;; we get lda instead of addq.
5854 (define_insn "nt_lda"
5855 [(set (match_operand:DI 0 "register_operand" "=r")
5856 (unspec:DI [(match_dup 0)
5857 (match_operand:DI 1 "const_int_operand" "n")] 6))]
5858 ""
5859 "lda %0,%1(%0)")
5860
5861 (define_expand "builtin_longjmp"
5862 [(unspec_volatile [(match_operand:DI 0 "register_operand" "r")] 3)]
5863 "! TARGET_OPEN_VMS && ! TARGET_WINDOWS_NT"
5864 "
5865 {
5866 /* The elements of the buffer are, in order: */
5867 rtx fp = gen_rtx_MEM (Pmode, operands[0]);
5868 rtx lab = gen_rtx_MEM (Pmode, plus_constant (operands[0], 8));
5869 rtx stack = gen_rtx_MEM (Pmode, plus_constant (operands[0], 16));
5870 rtx pv = gen_rtx_REG (Pmode, 27);
5871
5872 /* This bit is the same as expand_builtin_longjmp. */
5873 emit_move_insn (hard_frame_pointer_rtx, fp);
5874 emit_move_insn (pv, lab);
5875 emit_stack_restore (SAVE_NONLOCAL, stack, NULL_RTX);
5876 emit_insn (gen_rtx_USE (VOIDmode, hard_frame_pointer_rtx));
5877 emit_insn (gen_rtx_USE (VOIDmode, stack_pointer_rtx));
5878
5879 /* Load the label we are jumping through into $27 so that we know
5880 where to look for it when we get back to setjmp's function for
5881 restoring the gp. */
5882 emit_indirect_jump (pv);
5883 DONE;
5884 }")
5885
5886 (define_insn "*builtin_setjmp_receiver_sub_label"
5887 [(unspec_volatile [(label_ref (match_operand 0 "" ""))] 2)]
5888 "! TARGET_OPEN_VMS && ! TARGET_WINDOWS_NT && TARGET_AS_CAN_SUBTRACT_LABELS"
5889 "\\n$LSJ%=:\;ldgp $29,$LSJ%=-%l0($27)"
5890 [(set_attr "length" "8")
5891 (set_attr "type" "multi")])
5892
5893 (define_insn "builtin_setjmp_receiver"
5894 [(unspec_volatile [(label_ref (match_operand 0 "" ""))] 2)]
5895 "! TARGET_OPEN_VMS && ! TARGET_WINDOWS_NT"
5896 "br $29,$LSJ%=\\n$LSJ%=:\;ldgp $29,0($29)"
5897 [(set_attr "length" "12")
5898 (set_attr "type" "multi")])
5899
5900 (define_insn "exception_receiver"
5901 [(unspec_volatile [(const_int 0)] 7)]
5902 "! TARGET_OPEN_VMS && ! TARGET_WINDOWS_NT"
5903 "br $29,$LSJ%=\\n$LSJ%=:\;ldgp $29,0($29)"
5904 [(set_attr "length" "12")
5905 (set_attr "type" "multi")])
5906
5907 (define_expand "nonlocal_goto_receiver"
5908 [(unspec_volatile [(const_int 0)] 1)
5909 (set (reg:DI 27) (mem:DI (reg:DI 29)))
5910 (unspec_volatile [(const_int 0)] 1)
5911 (use (reg:DI 27))]
5912 "TARGET_OPEN_VMS"
5913 "")
5914
5915 (define_insn "arg_home"
5916 [(unspec [(const_int 0)] 0)
5917 (use (reg:DI 1))
5918 (use (reg:DI 25))
5919 (use (reg:DI 16))
5920 (use (reg:DI 17))
5921 (use (reg:DI 18))
5922 (use (reg:DI 19))
5923 (use (reg:DI 20))
5924 (use (reg:DI 21))
5925 (use (reg:DI 48))
5926 (use (reg:DI 49))
5927 (use (reg:DI 50))
5928 (use (reg:DI 51))
5929 (use (reg:DI 52))
5930 (use (reg:DI 53))
5931 (clobber (mem:BLK (const_int 0)))
5932 (clobber (reg:DI 24))
5933 (clobber (reg:DI 25))
5934 (clobber (reg:DI 0))]
5935 "TARGET_OPEN_VMS"
5936 "lda $0,OTS$HOME_ARGS\;ldq $0,8($0)\;jsr $0,OTS$HOME_ARGS"
5937 [(set_attr "length" "16")
5938 (set_attr "type" "multi")])
5939
5940 ;; Close the trap shadow of preceeding instructions. This is generated
5941 ;; by alpha_reorg.
5942
5943 (define_insn "trapb"
5944 [(unspec_volatile [(const_int 0)] 4)]
5945 ""
5946 "trapb"
5947 [(set_attr "type" "misc")])
5948
5949 ;; No-op instructions used by machine-dependant reorg to preserve
5950 ;; alignment for instruction issue.
5951
5952 (define_insn "nop"
5953 [(const_int 0)]
5954 ""
5955 "nop"
5956 [(set_attr "type" "ilog")])
5957
5958 (define_insn "fnop"
5959 [(const_int 1)]
5960 "TARGET_FP"
5961 "fnop"
5962 [(set_attr "type" "fcpys")])
5963
5964 (define_insn "unop"
5965 [(const_int 2)]
5966 ""
5967 "unop")
5968
5969 (define_insn "realign"
5970 [(unspec_volatile [(match_operand 0 "immediate_operand" "i")] 6)]
5971 ""
5972 ".align %0 #realign")
5973
5974 ;; The call patterns are at the end of the file because their
5975 ;; wildcard operand0 interferes with nice recognition.
5976
5977 (define_insn "*call_value_osf_1"
5978 [(set (match_operand 0 "" "")
5979 (call (mem:DI (match_operand:DI 1 "call_operand" "c,R,i"))
5980 (match_operand 2 "" "")))
5981 (clobber (reg:DI 27))
5982 (clobber (reg:DI 26))]
5983 "! TARGET_WINDOWS_NT && ! TARGET_OPEN_VMS"
5984 "@
5985 jsr $26,($27),0\;ldgp $29,0($26)
5986 bsr $26,$%1..ng
5987 jsr $26,%1\;ldgp $29,0($26)"
5988 [(set_attr "type" "jsr")
5989 (set_attr "length" "12,*,16")])
5990
5991 (define_insn "*sibcall_value_osf_1"
5992 [(set (match_operand 0 "" "")
5993 (call (mem:DI (match_operand:DI 1 "call_operand" "R,i"))
5994 (match_operand 2 "" "")))]
5995 "! TARGET_WINDOWS_NT && ! TARGET_OPEN_VMS"
5996 "@
5997 br $31,$%1..ng
5998 jmp $31,%1"
5999 [(set_attr "type" "jsr")
6000 (set_attr "length" "*,8")])
6001
6002 (define_insn "*call_value_nt_1"
6003 [(set (match_operand 0 "" "")
6004 (call (mem:DI (match_operand:DI 1 "call_operand" "r,R,i"))
6005 (match_operand 2 "" "")))
6006 (clobber (reg:DI 26))]
6007 "TARGET_WINDOWS_NT"
6008 "@
6009 jsr $26,(%1)
6010 bsr $26,%1
6011 jsr $26,%1"
6012 [(set_attr "type" "jsr")
6013 (set_attr "length" "*,*,12")])
6014
6015 (define_insn "*call_value_vms_1"
6016 [(set (match_operand 0 "" "")
6017 (call (mem:DI (match_operand:DI 1 "call_operand" "r,i"))
6018 (match_operand 2 "" "")))
6019 (use (match_operand:DI 3 "nonimmediate_operand" "r,m"))
6020 (use (reg:DI 25))
6021 (use (reg:DI 26))
6022 (clobber (reg:DI 27))]
6023 "TARGET_OPEN_VMS"
6024 "@
6025 mov %3,$27\;jsr $26,0\;ldq $27,0($29)
6026 ldq $27,%3\;jsr $26,%1\;ldq $27,0($29)"
6027 [(set_attr "type" "jsr")
6028 (set_attr "length" "12,16")])