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