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