alpha.md (call_value_osf_1_er peepholes): Fix typo.
[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"
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 && (register_operand (operands[0], SImode)
5300 || reg_or_0_operand (operands[1], SImode))"
5301 "@
5302 bis $31,%1,%0
5303 lda %0,%1
5304 ldah %0,%h1
5305 lda %0,%1
5306 ldl %0,%1
5307 stl %r1,%0
5308 cpys %R1,%R1,%0
5309 ld%, %0,%1
5310 st%, %R1,%0"
5311 [(set_attr "type" "ilog,iadd,iadd,ldsym,ild,ist,fcpys,fld,fst")])
5312
5313 (define_insn "*movhi_nobwx"
5314 [(set (match_operand:HI 0 "register_operand" "=r,r")
5315 (match_operand:HI 1 "input_operand" "rJ,n"))]
5316 "! TARGET_BWX
5317 && (register_operand (operands[0], HImode)
5318 || register_operand (operands[1], HImode))"
5319 "@
5320 bis $31,%r1,%0
5321 lda %0,%L1($31)"
5322 [(set_attr "type" "ilog,iadd")])
5323
5324 (define_insn "*movhi_bwx"
5325 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
5326 (match_operand:HI 1 "input_operand" "rJ,n,m,rJ"))]
5327 "TARGET_BWX
5328 && (register_operand (operands[0], HImode)
5329 || reg_or_0_operand (operands[1], HImode))"
5330 "@
5331 bis $31,%r1,%0
5332 lda %0,%L1($31)
5333 ldwu %0,%1
5334 stw %r1,%0"
5335 [(set_attr "type" "ilog,iadd,ild,ist")])
5336
5337 (define_insn "*movqi_nobwx"
5338 [(set (match_operand:QI 0 "register_operand" "=r,r")
5339 (match_operand:QI 1 "input_operand" "rJ,n"))]
5340 "! TARGET_BWX
5341 && (register_operand (operands[0], QImode)
5342 || register_operand (operands[1], QImode))"
5343 "@
5344 bis $31,%r1,%0
5345 lda %0,%L1($31)"
5346 [(set_attr "type" "ilog,iadd")])
5347
5348 (define_insn "*movqi_bwx"
5349 [(set (match_operand:QI 0 "nonimmediate_operand" "=r,r,r,m")
5350 (match_operand:QI 1 "input_operand" "rJ,n,m,rJ"))]
5351 "TARGET_BWX
5352 && (register_operand (operands[0], QImode)
5353 || reg_or_0_operand (operands[1], QImode))"
5354 "@
5355 bis $31,%r1,%0
5356 lda %0,%L1($31)
5357 ldbu %0,%1
5358 stb %r1,%0"
5359 [(set_attr "type" "ilog,iadd,ild,ist")])
5360
5361 ;; We do two major things here: handle mem->mem and construct long
5362 ;; constants.
5363
5364 (define_expand "movsi"
5365 [(set (match_operand:SI 0 "nonimmediate_operand" "")
5366 (match_operand:SI 1 "general_operand" ""))]
5367 ""
5368 {
5369 if (alpha_expand_mov (SImode, operands))
5370 DONE;
5371 })
5372
5373 ;; Split a load of a large constant into the appropriate two-insn
5374 ;; sequence.
5375
5376 (define_split
5377 [(set (match_operand:SI 0 "register_operand" "")
5378 (match_operand:SI 1 "const_int_operand" ""))]
5379 "! add_operand (operands[1], SImode)"
5380 [(set (match_dup 0) (match_dup 2))
5381 (set (match_dup 0) (plus:SI (match_dup 0) (match_dup 3)))]
5382 {
5383 rtx tem
5384 = alpha_emit_set_const (operands[0], SImode, INTVAL (operands[1]), 2);
5385
5386 if (tem == operands[0])
5387 DONE;
5388 else
5389 FAIL;
5390 })
5391
5392 ;; Split the load of an address into a four-insn sequence on Unicos/Mk.
5393 ;; Always generate a REG_EQUAL note for the last instruction to facilitate
5394 ;; optimisations. If the symbolic operand is a label_ref, generate REG_LABEL
5395 ;; notes and update LABEL_NUSES because this is not done automatically.
5396 ;; Labels may be incorrectly deleted if we don't do this.
5397 ;;
5398 ;; Describing what the individual instructions do correctly is too complicated
5399 ;; so use UNSPECs for each of the three parts of an address.
5400
5401 (define_split
5402 [(set (match_operand:DI 0 "register_operand" "")
5403 (match_operand:DI 1 "symbolic_operand" ""))]
5404 "TARGET_ABI_UNICOSMK && reload_completed"
5405 [(const_int 0)]
5406 {
5407 rtx insn1, insn2, insn3;
5408
5409 insn1 = emit_insn (gen_umk_laum (operands[0], operands[1]));
5410 emit_insn (gen_ashldi3 (operands[0], operands[0], GEN_INT (32)));
5411 insn2 = emit_insn (gen_umk_lalm (operands[0], operands[0], operands[1]));
5412 insn3 = emit_insn (gen_umk_lal (operands[0], operands[0], operands[1]));
5413 REG_NOTES (insn3) = gen_rtx_EXPR_LIST (REG_EQUAL, operands[1],
5414 REG_NOTES (insn3));
5415 if (GET_CODE (operands[1]) == LABEL_REF)
5416 {
5417 rtx label;
5418
5419 label = XEXP (operands[1], 0);
5420 REG_NOTES (insn1) = gen_rtx_EXPR_LIST (REG_LABEL, label,
5421 REG_NOTES (insn1));
5422 REG_NOTES (insn2) = gen_rtx_EXPR_LIST (REG_LABEL, label,
5423 REG_NOTES (insn2));
5424 REG_NOTES (insn3) = gen_rtx_EXPR_LIST (REG_LABEL, label,
5425 REG_NOTES (insn3));
5426 LABEL_NUSES (label) += 3;
5427 }
5428 DONE;
5429 })
5430
5431 ;; Instructions for loading the three parts of an address on Unicos/Mk.
5432
5433 (define_insn "umk_laum"
5434 [(set (match_operand:DI 0 "register_operand" "=r")
5435 (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")]
5436 UNSPEC_UMK_LAUM))]
5437 "TARGET_ABI_UNICOSMK"
5438 "laum %r0,%t1($31)"
5439 [(set_attr "type" "iadd")])
5440
5441 (define_insn "umk_lalm"
5442 [(set (match_operand:DI 0 "register_operand" "=r")
5443 (plus:DI (match_operand:DI 1 "register_operand" "r")
5444 (unspec:DI [(match_operand:DI 2 "symbolic_operand" "")]
5445 UNSPEC_UMK_LALM)))]
5446 "TARGET_ABI_UNICOSMK"
5447 "lalm %r0,%t2(%r1)"
5448 [(set_attr "type" "iadd")])
5449
5450 (define_insn "umk_lal"
5451 [(set (match_operand:DI 0 "register_operand" "=r")
5452 (plus:DI (match_operand:DI 1 "register_operand" "r")
5453 (unspec:DI [(match_operand:DI 2 "symbolic_operand" "")]
5454 UNSPEC_UMK_LAL)))]
5455 "TARGET_ABI_UNICOSMK"
5456 "lal %r0,%t2(%r1)"
5457 [(set_attr "type" "iadd")])
5458
5459 ;; Add a new call information word to the current function's list of CIWs
5460 ;; and load its index into $25. Doing it here ensures that the CIW will be
5461 ;; associated with the correct function even in the presence of inlining.
5462
5463 (define_insn "*umk_load_ciw"
5464 [(set (reg:DI 25)
5465 (unspec:DI [(match_operand 0 "" "")] UNSPEC_UMK_LOAD_CIW))]
5466 "TARGET_ABI_UNICOSMK"
5467 {
5468 operands[0] = unicosmk_add_call_info_word (operands[0]);
5469 return "lda $25,%0";
5470 }
5471 [(set_attr "type" "iadd")])
5472
5473 (define_insn "*movdi_er_low_l"
5474 [(set (match_operand:DI 0 "register_operand" "=r")
5475 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
5476 (match_operand:DI 2 "local_symbolic_operand" "")))]
5477 "TARGET_EXPLICIT_RELOCS"
5478 {
5479 if (true_regnum (operands[1]) == 29)
5480 return "lda %0,%2(%1)\t\t!gprel";
5481 else
5482 return "lda %0,%2(%1)\t\t!gprellow";
5483 })
5484
5485 (define_split
5486 [(set (match_operand:DI 0 "register_operand" "")
5487 (match_operand:DI 1 "small_symbolic_operand" ""))]
5488 "TARGET_EXPLICIT_RELOCS && reload_completed"
5489 [(set (match_dup 0)
5490 (lo_sum:DI (match_dup 2) (match_dup 1)))]
5491 "operands[2] = pic_offset_table_rtx;")
5492
5493 (define_split
5494 [(set (match_operand:DI 0 "register_operand" "")
5495 (match_operand:DI 1 "local_symbolic_operand" ""))]
5496 "TARGET_EXPLICIT_RELOCS && reload_completed"
5497 [(set (match_dup 0)
5498 (plus:DI (match_dup 2) (high:DI (match_dup 1))))
5499 (set (match_dup 0)
5500 (lo_sum:DI (match_dup 0) (match_dup 1)))]
5501 "operands[2] = pic_offset_table_rtx;")
5502
5503 (define_split
5504 [(match_operand 0 "some_small_symbolic_mem_operand" "")]
5505 "TARGET_EXPLICIT_RELOCS && reload_completed"
5506 [(match_dup 0)]
5507 "operands[0] = split_small_symbolic_mem_operand (operands[0]);")
5508
5509 (define_insn "movdi_er_high_g"
5510 [(set (match_operand:DI 0 "register_operand" "=r")
5511 (unspec:DI [(match_operand:DI 1 "register_operand" "r")
5512 (match_operand:DI 2 "global_symbolic_operand" "")
5513 (match_operand 3 "const_int_operand" "")]
5514 UNSPEC_LITERAL))]
5515 "TARGET_EXPLICIT_RELOCS"
5516 {
5517 if (INTVAL (operands[3]) == 0)
5518 return "ldq %0,%2(%1)\t\t!literal";
5519 else
5520 return "ldq %0,%2(%1)\t\t!literal!%3";
5521 }
5522 [(set_attr "type" "ldsym")])
5523
5524 (define_split
5525 [(set (match_operand:DI 0 "register_operand" "")
5526 (match_operand:DI 1 "global_symbolic_operand" ""))]
5527 "TARGET_EXPLICIT_RELOCS && reload_completed"
5528 [(set (match_dup 0)
5529 (unspec:DI [(match_dup 2)
5530 (match_dup 1)
5531 (const_int 0)] UNSPEC_LITERAL))]
5532 "operands[2] = pic_offset_table_rtx;")
5533
5534 (define_insn "*movdi_er_nofix"
5535 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,r,r,r,r,m,*f,*f,Q")
5536 (match_operand:DI 1 "input_operand" "rJ,K,L,T,s,m,rJ,*fJ,Q,*f"))]
5537 "TARGET_EXPLICIT_RELOCS && ! TARGET_FIX
5538 && (register_operand (operands[0], DImode)
5539 || reg_or_0_operand (operands[1], DImode))"
5540 "@
5541 mov %r1,%0
5542 lda %0,%1($31)
5543 ldah %0,%h1($31)
5544 #
5545 #
5546 ldq%A1 %0,%1
5547 stq%A0 %r1,%0
5548 fmov %R1,%0
5549 ldt %0,%1
5550 stt %R1,%0"
5551 [(set_attr "type" "ilog,iadd,iadd,iadd,ldsym,ild,ist,fcpys,fld,fst")])
5552
5553 ;; The 'U' constraint matches symbolic operands on Unicos/Mk. Those should
5554 ;; have been split up by the rules above but we shouldn't reject the
5555 ;; possibility of them getting through.
5556
5557 (define_insn "*movdi_nofix"
5558 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,r,r,r,r,m,*f,*f,Q")
5559 (match_operand:DI 1 "input_operand" "rJ,K,L,U,s,m,rJ,*fJ,Q,*f"))]
5560 "! TARGET_FIX
5561 && (register_operand (operands[0], DImode)
5562 || reg_or_0_operand (operands[1], DImode))"
5563 "@
5564 bis $31,%r1,%0
5565 lda %0,%1($31)
5566 ldah %0,%h1($31)
5567 laum %0,%t1($31)\;sll %0,32,%0\;lalm %0,%t1(%0)\;lal %0,%t1(%0)
5568 lda %0,%1
5569 ldq%A1 %0,%1
5570 stq%A0 %r1,%0
5571 cpys %R1,%R1,%0
5572 ldt %0,%1
5573 stt %R1,%0"
5574 [(set_attr "type" "ilog,iadd,iadd,ldsym,ldsym,ild,ist,fcpys,fld,fst")
5575 (set_attr "length" "*,*,*,16,*,*,*,*,*,*")])
5576
5577 (define_insn "*movdi_er_fix"
5578 [(set (match_operand:DI 0 "nonimmediate_operand"
5579 "=r,r,r,r,r,r, m, *f,*f, Q, r,*f")
5580 (match_operand:DI 1 "input_operand"
5581 "rJ,K,L,T,s,m,rJ,*fJ, Q,*f,*f, r"))]
5582 "TARGET_EXPLICIT_RELOCS && TARGET_FIX
5583 && (register_operand (operands[0], DImode)
5584 || reg_or_0_operand (operands[1], DImode))"
5585 "@
5586 mov %r1,%0
5587 lda %0,%1($31)
5588 ldah %0,%h1($31)
5589 #
5590 #
5591 ldq%A1 %0,%1
5592 stq%A0 %r1,%0
5593 fmov %R1,%0
5594 ldt %0,%1
5595 stt %R1,%0
5596 ftoit %1,%0
5597 itoft %1,%0"
5598 [(set_attr "type" "ilog,iadd,iadd,iadd,ldsym,ild,ist,fcpys,fld,fst,ftoi,itof")])
5599
5600 (define_insn "*movdi_fix"
5601 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,r,r,r,m,*f,*f,Q,r,*f")
5602 (match_operand:DI 1 "input_operand" "rJ,K,L,s,m,rJ,*fJ,Q,*f,*f,r"))]
5603 "! TARGET_EXPLICIT_RELOCS && TARGET_FIX
5604 && (register_operand (operands[0], DImode)
5605 || reg_or_0_operand (operands[1], DImode))"
5606 "@
5607 bis $31,%r1,%0
5608 lda %0,%1($31)
5609 ldah %0,%h1($31)
5610 lda %0,%1
5611 ldq%A1 %0,%1
5612 stq%A0 %r1,%0
5613 cpys %R1,%R1,%0
5614 ldt %0,%1
5615 stt %R1,%0
5616 ftoit %1,%0
5617 itoft %1,%0"
5618 [(set_attr "type" "ilog,iadd,iadd,ldsym,ild,ist,fcpys,fld,fst,ftoi,itof")])
5619
5620 ;; VMS needs to set up "vms_base_regno" for unwinding. This move
5621 ;; often appears dead to the life analysis code, at which point we
5622 ;; abort for emitting dead prologue instructions. Force this live.
5623
5624 (define_insn "force_movdi"
5625 [(set (match_operand:DI 0 "register_operand" "=r")
5626 (unspec_volatile:DI [(match_operand:DI 1 "register_operand" "r")]
5627 UNSPECV_FORCE_MOV))]
5628 ""
5629 "mov %1,%0"
5630 [(set_attr "type" "ilog")])
5631
5632 ;; We do three major things here: handle mem->mem, put 64-bit constants in
5633 ;; memory, and construct long 32-bit constants.
5634
5635 (define_expand "movdi"
5636 [(set (match_operand:DI 0 "nonimmediate_operand" "")
5637 (match_operand:DI 1 "general_operand" ""))]
5638 ""
5639 {
5640 if (alpha_expand_mov (DImode, operands))
5641 DONE;
5642 })
5643
5644 ;; Split a load of a large constant into the appropriate two-insn
5645 ;; sequence.
5646
5647 (define_split
5648 [(set (match_operand:DI 0 "register_operand" "")
5649 (match_operand:DI 1 "const_int_operand" ""))]
5650 "! add_operand (operands[1], DImode)"
5651 [(set (match_dup 0) (match_dup 2))
5652 (set (match_dup 0) (plus:DI (match_dup 0) (match_dup 3)))]
5653 {
5654 rtx tem
5655 = alpha_emit_set_const (operands[0], DImode, INTVAL (operands[1]), 2);
5656
5657 if (tem == operands[0])
5658 DONE;
5659 else
5660 FAIL;
5661 })
5662
5663 ;; These are the partial-word cases.
5664 ;;
5665 ;; First we have the code to load an aligned word. Operand 0 is the register
5666 ;; in which to place the result. It's mode is QImode or HImode. Operand 1
5667 ;; is an SImode MEM at the low-order byte of the proper word. Operand 2 is the
5668 ;; number of bits within the word that the value is. Operand 3 is an SImode
5669 ;; scratch register. If operand 0 is a hard register, operand 3 may be the
5670 ;; same register. It is allowed to conflict with operand 1 as well.
5671
5672 (define_expand "aligned_loadqi"
5673 [(set (match_operand:SI 3 "register_operand" "")
5674 (match_operand:SI 1 "memory_operand" ""))
5675 (set (subreg:DI (match_operand:QI 0 "register_operand" "") 0)
5676 (zero_extract:DI (subreg:DI (match_dup 3) 0)
5677 (const_int 8)
5678 (match_operand:DI 2 "const_int_operand" "")))]
5679
5680 ""
5681 "")
5682
5683 (define_expand "aligned_loadhi"
5684 [(set (match_operand:SI 3 "register_operand" "")
5685 (match_operand:SI 1 "memory_operand" ""))
5686 (set (subreg:DI (match_operand:HI 0 "register_operand" "") 0)
5687 (zero_extract:DI (subreg:DI (match_dup 3) 0)
5688 (const_int 16)
5689 (match_operand:DI 2 "const_int_operand" "")))]
5690
5691 ""
5692 "")
5693
5694 ;; Similar for unaligned loads, where we use the sequence from the
5695 ;; Alpha Architecture manual. We have to distinguish between little-endian
5696 ;; and big-endian systems as the sequences are different.
5697 ;;
5698 ;; Operand 1 is the address. Operands 2 and 3 are temporaries, where
5699 ;; operand 3 can overlap the input and output registers.
5700
5701 (define_expand "unaligned_loadqi"
5702 [(use (match_operand:QI 0 "register_operand" ""))
5703 (use (match_operand:DI 1 "address_operand" ""))
5704 (use (match_operand:DI 2 "register_operand" ""))
5705 (use (match_operand:DI 3 "register_operand" ""))]
5706 ""
5707 {
5708 if (WORDS_BIG_ENDIAN)
5709 emit_insn (gen_unaligned_loadqi_be (operands[0], operands[1],
5710 operands[2], operands[3]));
5711 else
5712 emit_insn (gen_unaligned_loadqi_le (operands[0], operands[1],
5713 operands[2], operands[3]));
5714 DONE;
5715 })
5716
5717 (define_expand "unaligned_loadqi_le"
5718 [(set (match_operand:DI 2 "register_operand" "")
5719 (mem:DI (and:DI (match_operand:DI 1 "address_operand" "")
5720 (const_int -8))))
5721 (set (match_operand:DI 3 "register_operand" "")
5722 (match_dup 1))
5723 (set (subreg:DI (match_operand:QI 0 "register_operand" "") 0)
5724 (zero_extract:DI (match_dup 2)
5725 (const_int 8)
5726 (ashift:DI (match_dup 3) (const_int 3))))]
5727 "! WORDS_BIG_ENDIAN"
5728 "")
5729
5730 (define_expand "unaligned_loadqi_be"
5731 [(set (match_operand:DI 2 "register_operand" "")
5732 (mem:DI (and:DI (match_operand:DI 1 "address_operand" "")
5733 (const_int -8))))
5734 (set (match_operand:DI 3 "register_operand" "")
5735 (match_dup 1))
5736 (set (subreg:DI (match_operand:QI 0 "register_operand" "") 0)
5737 (zero_extract:DI (match_dup 2)
5738 (const_int 8)
5739 (minus:DI
5740 (const_int 56)
5741 (ashift:DI (match_dup 3) (const_int 3)))))]
5742 "WORDS_BIG_ENDIAN"
5743 "")
5744
5745 (define_expand "unaligned_loadhi"
5746 [(use (match_operand:QI 0 "register_operand" ""))
5747 (use (match_operand:DI 1 "address_operand" ""))
5748 (use (match_operand:DI 2 "register_operand" ""))
5749 (use (match_operand:DI 3 "register_operand" ""))]
5750 ""
5751 {
5752 if (WORDS_BIG_ENDIAN)
5753 emit_insn (gen_unaligned_loadhi_be (operands[0], operands[1],
5754 operands[2], operands[3]));
5755 else
5756 emit_insn (gen_unaligned_loadhi_le (operands[0], operands[1],
5757 operands[2], operands[3]));
5758 DONE;
5759 })
5760
5761 (define_expand "unaligned_loadhi_le"
5762 [(set (match_operand:DI 2 "register_operand" "")
5763 (mem:DI (and:DI (match_operand:DI 1 "address_operand" "")
5764 (const_int -8))))
5765 (set (match_operand:DI 3 "register_operand" "")
5766 (match_dup 1))
5767 (set (subreg:DI (match_operand:QI 0 "register_operand" "") 0)
5768 (zero_extract:DI (match_dup 2)
5769 (const_int 16)
5770 (ashift:DI (match_dup 3) (const_int 3))))]
5771 "! WORDS_BIG_ENDIAN"
5772 "")
5773
5774 (define_expand "unaligned_loadhi_be"
5775 [(set (match_operand:DI 2 "register_operand" "")
5776 (mem:DI (and:DI (match_operand:DI 1 "address_operand" "")
5777 (const_int -8))))
5778 (set (match_operand:DI 3 "register_operand" "")
5779 (plus:DI (match_dup 1) (const_int 1)))
5780 (set (subreg:DI (match_operand:QI 0 "register_operand" "") 0)
5781 (zero_extract:DI (match_dup 2)
5782 (const_int 16)
5783 (minus:DI
5784 (const_int 56)
5785 (ashift:DI (match_dup 3) (const_int 3)))))]
5786 "WORDS_BIG_ENDIAN"
5787 "")
5788
5789 ;; Storing an aligned byte or word requires two temporaries. Operand 0 is the
5790 ;; aligned SImode MEM. Operand 1 is the register containing the
5791 ;; byte or word to store. Operand 2 is the number of bits within the word that
5792 ;; the value should be placed. Operands 3 and 4 are SImode temporaries.
5793
5794 (define_expand "aligned_store"
5795 [(set (match_operand:SI 3 "register_operand" "")
5796 (match_operand:SI 0 "memory_operand" ""))
5797 (set (subreg:DI (match_dup 3) 0)
5798 (and:DI (subreg:DI (match_dup 3) 0) (match_dup 5)))
5799 (set (subreg:DI (match_operand:SI 4 "register_operand" "") 0)
5800 (ashift:DI (zero_extend:DI (match_operand 1 "register_operand" ""))
5801 (match_operand:DI 2 "const_int_operand" "")))
5802 (set (subreg:DI (match_dup 4) 0)
5803 (ior:DI (subreg:DI (match_dup 4) 0) (subreg:DI (match_dup 3) 0)))
5804 (set (match_dup 0) (match_dup 4))]
5805 ""
5806 {
5807 operands[5] = GEN_INT (~ (GET_MODE_MASK (GET_MODE (operands[1]))
5808 << INTVAL (operands[2])));
5809 })
5810
5811 ;; For the unaligned byte and halfword cases, we use code similar to that
5812 ;; in the ;; Architecture book, but reordered to lower the number of registers
5813 ;; required. Operand 0 is the address. Operand 1 is the data to store.
5814 ;; Operands 2, 3, and 4 are DImode temporaries, where operands 2 and 4 may
5815 ;; be the same temporary, if desired. If the address is in a register,
5816 ;; operand 2 can be that register.
5817
5818 (define_expand "unaligned_storeqi"
5819 [(use (match_operand:DI 0 "address_operand" ""))
5820 (use (match_operand:QI 1 "register_operand" ""))
5821 (use (match_operand:DI 2 "register_operand" ""))
5822 (use (match_operand:DI 3 "register_operand" ""))
5823 (use (match_operand:DI 4 "register_operand" ""))]
5824 ""
5825 {
5826 if (WORDS_BIG_ENDIAN)
5827 emit_insn (gen_unaligned_storeqi_be (operands[0], operands[1],
5828 operands[2], operands[3],
5829 operands[4]));
5830 else
5831 emit_insn (gen_unaligned_storeqi_le (operands[0], operands[1],
5832 operands[2], operands[3],
5833 operands[4]));
5834 DONE;
5835 })
5836
5837 (define_expand "unaligned_storeqi_le"
5838 [(set (match_operand:DI 3 "register_operand" "")
5839 (mem:DI (and:DI (match_operand:DI 0 "address_operand" "")
5840 (const_int -8))))
5841 (set (match_operand:DI 2 "register_operand" "")
5842 (match_dup 0))
5843 (set (match_dup 3)
5844 (and:DI (not:DI (ashift:DI (const_int 255)
5845 (ashift:DI (match_dup 2) (const_int 3))))
5846 (match_dup 3)))
5847 (set (match_operand:DI 4 "register_operand" "")
5848 (ashift:DI (zero_extend:DI (match_operand:QI 1 "register_operand" ""))
5849 (ashift:DI (match_dup 2) (const_int 3))))
5850 (set (match_dup 4) (ior:DI (match_dup 4) (match_dup 3)))
5851 (set (mem:DI (and:DI (match_dup 0) (const_int -8)))
5852 (match_dup 4))]
5853 "! WORDS_BIG_ENDIAN"
5854 "")
5855
5856 (define_expand "unaligned_storeqi_be"
5857 [(set (match_operand:DI 3 "register_operand" "")
5858 (mem:DI (and:DI (match_operand:DI 0 "address_operand" "")
5859 (const_int -8))))
5860 (set (match_operand:DI 2 "register_operand" "")
5861 (match_dup 0))
5862 (set (match_dup 3)
5863 (and:DI (not:DI (ashift:DI (const_int 255)
5864 (minus:DI (const_int 56)
5865 (ashift:DI (match_dup 2) (const_int 3)))))
5866 (match_dup 3)))
5867 (set (match_operand:DI 4 "register_operand" "")
5868 (ashift:DI (zero_extend:DI (match_operand:QI 1 "register_operand" ""))
5869 (minus:DI (const_int 56)
5870 (ashift:DI (match_dup 2) (const_int 3)))))
5871 (set (match_dup 4) (ior:DI (match_dup 4) (match_dup 3)))
5872 (set (mem:DI (and:DI (match_dup 0) (const_int -8)))
5873 (match_dup 4))]
5874 "WORDS_BIG_ENDIAN"
5875 "")
5876
5877 (define_expand "unaligned_storehi"
5878 [(use (match_operand:DI 0 "address_operand" ""))
5879 (use (match_operand:HI 1 "register_operand" ""))
5880 (use (match_operand:DI 2 "register_operand" ""))
5881 (use (match_operand:DI 3 "register_operand" ""))
5882 (use (match_operand:DI 4 "register_operand" ""))]
5883 ""
5884 {
5885 if (WORDS_BIG_ENDIAN)
5886 emit_insn (gen_unaligned_storehi_be (operands[0], operands[1],
5887 operands[2], operands[3],
5888 operands[4]));
5889 else
5890 emit_insn (gen_unaligned_storehi_le (operands[0], operands[1],
5891 operands[2], operands[3],
5892 operands[4]));
5893 DONE;
5894 })
5895
5896 (define_expand "unaligned_storehi_le"
5897 [(set (match_operand:DI 3 "register_operand" "")
5898 (mem:DI (and:DI (match_operand:DI 0 "address_operand" "")
5899 (const_int -8))))
5900 (set (match_operand:DI 2 "register_operand" "")
5901 (match_dup 0))
5902 (set (match_dup 3)
5903 (and:DI (not:DI (ashift:DI (const_int 65535)
5904 (ashift:DI (match_dup 2) (const_int 3))))
5905 (match_dup 3)))
5906 (set (match_operand:DI 4 "register_operand" "")
5907 (ashift:DI (zero_extend:DI (match_operand:HI 1 "register_operand" ""))
5908 (ashift:DI (match_dup 2) (const_int 3))))
5909 (set (match_dup 4) (ior:DI (match_dup 4) (match_dup 3)))
5910 (set (mem:DI (and:DI (match_dup 0) (const_int -8)))
5911 (match_dup 4))]
5912 "! WORDS_BIG_ENDIAN"
5913 "")
5914
5915 (define_expand "unaligned_storehi_be"
5916 [(set (match_operand:DI 3 "register_operand" "")
5917 (mem:DI (and:DI (match_operand:DI 0 "address_operand" "")
5918 (const_int -8))))
5919 (set (match_operand:DI 2 "register_operand" "")
5920 (plus:DI (match_dup 0) (const_int 1)))
5921 (set (match_dup 3)
5922 (and:DI (not:DI (ashift:DI
5923 (const_int 65535)
5924 (minus:DI (const_int 56)
5925 (ashift:DI (match_dup 2) (const_int 3)))))
5926 (match_dup 3)))
5927 (set (match_operand:DI 4 "register_operand" "")
5928 (ashift:DI (zero_extend:DI (match_operand:HI 1 "register_operand" ""))
5929 (minus:DI (const_int 56)
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 \f
5937 ;; Here are the define_expand's for QI and HI moves that use the above
5938 ;; patterns. We have the normal sets, plus the ones that need scratch
5939 ;; registers for reload.
5940
5941 (define_expand "movqi"
5942 [(set (match_operand:QI 0 "nonimmediate_operand" "")
5943 (match_operand:QI 1 "general_operand" ""))]
5944 ""
5945 {
5946 if (TARGET_BWX
5947 ? alpha_expand_mov (QImode, operands)
5948 : alpha_expand_mov_nobwx (QImode, operands))
5949 DONE;
5950 })
5951
5952 (define_expand "movhi"
5953 [(set (match_operand:HI 0 "nonimmediate_operand" "")
5954 (match_operand:HI 1 "general_operand" ""))]
5955 ""
5956 {
5957 if (TARGET_BWX
5958 ? alpha_expand_mov (HImode, operands)
5959 : alpha_expand_mov_nobwx (HImode, operands))
5960 DONE;
5961 })
5962
5963 ;; Here are the versions for reload. Note that in the unaligned cases
5964 ;; we know that the operand must not be a pseudo-register because stack
5965 ;; slots are always aligned references.
5966
5967 (define_expand "reload_inqi"
5968 [(parallel [(match_operand:QI 0 "register_operand" "=r")
5969 (match_operand:QI 1 "any_memory_operand" "m")
5970 (match_operand:TI 2 "register_operand" "=&r")])]
5971 "! TARGET_BWX"
5972 {
5973 rtx scratch, seq;
5974
5975 if (GET_CODE (operands[1]) != MEM)
5976 abort ();
5977
5978 if (aligned_memory_operand (operands[1], QImode))
5979 {
5980 seq = gen_reload_inqi_help (operands[0], operands[1],
5981 gen_rtx_REG (SImode, REGNO (operands[2])));
5982 }
5983 else
5984 {
5985 rtx addr;
5986
5987 /* It is possible that one of the registers we got for operands[2]
5988 might coincide with that of operands[0] (which is why we made
5989 it TImode). Pick the other one to use as our scratch. */
5990 if (REGNO (operands[0]) == REGNO (operands[2]))
5991 scratch = gen_rtx_REG (DImode, REGNO (operands[2]) + 1);
5992 else
5993 scratch = gen_rtx_REG (DImode, REGNO (operands[2]));
5994
5995 addr = get_unaligned_address (operands[1], 0);
5996 seq = gen_unaligned_loadqi (operands[0], addr, scratch,
5997 gen_rtx_REG (DImode, REGNO (operands[0])));
5998 alpha_set_memflags (seq, operands[1]);
5999 }
6000 emit_insn (seq);
6001 DONE;
6002 })
6003
6004 (define_expand "reload_inhi"
6005 [(parallel [(match_operand:HI 0 "register_operand" "=r")
6006 (match_operand:HI 1 "any_memory_operand" "m")
6007 (match_operand:TI 2 "register_operand" "=&r")])]
6008 "! TARGET_BWX"
6009 {
6010 rtx scratch, seq;
6011
6012 if (GET_CODE (operands[1]) != MEM)
6013 abort ();
6014
6015 if (aligned_memory_operand (operands[1], HImode))
6016 {
6017 seq = gen_reload_inhi_help (operands[0], operands[1],
6018 gen_rtx_REG (SImode, REGNO (operands[2])));
6019 }
6020 else
6021 {
6022 rtx addr;
6023
6024 /* It is possible that one of the registers we got for operands[2]
6025 might coincide with that of operands[0] (which is why we made
6026 it TImode). Pick the other one to use as our scratch. */
6027 if (REGNO (operands[0]) == REGNO (operands[2]))
6028 scratch = gen_rtx_REG (DImode, REGNO (operands[2]) + 1);
6029 else
6030 scratch = gen_rtx_REG (DImode, REGNO (operands[2]));
6031
6032 addr = get_unaligned_address (operands[1], 0);
6033 seq = gen_unaligned_loadhi (operands[0], addr, scratch,
6034 gen_rtx_REG (DImode, REGNO (operands[0])));
6035 alpha_set_memflags (seq, operands[1]);
6036 }
6037 emit_insn (seq);
6038 DONE;
6039 })
6040
6041 (define_expand "reload_outqi"
6042 [(parallel [(match_operand:QI 0 "any_memory_operand" "=m")
6043 (match_operand:QI 1 "register_operand" "r")
6044 (match_operand:TI 2 "register_operand" "=&r")])]
6045 "! TARGET_BWX"
6046 {
6047 if (GET_CODE (operands[0]) != MEM)
6048 abort ();
6049
6050 if (aligned_memory_operand (operands[0], QImode))
6051 {
6052 emit_insn (gen_reload_outqi_help
6053 (operands[0], operands[1],
6054 gen_rtx_REG (SImode, REGNO (operands[2])),
6055 gen_rtx_REG (SImode, REGNO (operands[2]) + 1)));
6056 }
6057 else
6058 {
6059 rtx addr = get_unaligned_address (operands[0], 0);
6060 rtx scratch1 = gen_rtx_REG (DImode, REGNO (operands[2]));
6061 rtx scratch2 = gen_rtx_REG (DImode, REGNO (operands[2]) + 1);
6062 rtx scratch3 = scratch1;
6063 rtx seq;
6064
6065 if (GET_CODE (addr) == REG)
6066 scratch1 = addr;
6067
6068 seq = gen_unaligned_storeqi (addr, operands[1], scratch1,
6069 scratch2, scratch3);
6070 alpha_set_memflags (seq, operands[0]);
6071 emit_insn (seq);
6072 }
6073 DONE;
6074 })
6075
6076 (define_expand "reload_outhi"
6077 [(parallel [(match_operand:HI 0 "any_memory_operand" "=m")
6078 (match_operand:HI 1 "register_operand" "r")
6079 (match_operand:TI 2 "register_operand" "=&r")])]
6080 "! TARGET_BWX"
6081 {
6082 if (GET_CODE (operands[0]) != MEM)
6083 abort ();
6084
6085 if (aligned_memory_operand (operands[0], HImode))
6086 {
6087 emit_insn (gen_reload_outhi_help
6088 (operands[0], operands[1],
6089 gen_rtx_REG (SImode, REGNO (operands[2])),
6090 gen_rtx_REG (SImode, REGNO (operands[2]) + 1)));
6091 }
6092 else
6093 {
6094 rtx addr = get_unaligned_address (operands[0], 0);
6095 rtx scratch1 = gen_rtx_REG (DImode, REGNO (operands[2]));
6096 rtx scratch2 = gen_rtx_REG (DImode, REGNO (operands[2]) + 1);
6097 rtx scratch3 = scratch1;
6098 rtx seq;
6099
6100 if (GET_CODE (addr) == REG)
6101 scratch1 = addr;
6102
6103 seq = gen_unaligned_storehi (addr, operands[1], scratch1,
6104 scratch2, scratch3);
6105 alpha_set_memflags (seq, operands[0]);
6106 emit_insn (seq);
6107 }
6108 DONE;
6109 })
6110
6111 ;; Helpers for the above. The way reload is structured, we can't
6112 ;; always get a proper address for a stack slot during reload_foo
6113 ;; expansion, so we must delay our address manipulations until after.
6114
6115 (define_insn "reload_inqi_help"
6116 [(set (match_operand:QI 0 "register_operand" "=r")
6117 (match_operand:QI 1 "memory_operand" "m"))
6118 (clobber (match_operand:SI 2 "register_operand" "=r"))]
6119 "! TARGET_BWX && (reload_in_progress || reload_completed)"
6120 "#")
6121
6122 (define_insn "reload_inhi_help"
6123 [(set (match_operand:HI 0 "register_operand" "=r")
6124 (match_operand:HI 1 "memory_operand" "m"))
6125 (clobber (match_operand:SI 2 "register_operand" "=r"))]
6126 "! TARGET_BWX && (reload_in_progress || reload_completed)"
6127 "#")
6128
6129 (define_insn "reload_outqi_help"
6130 [(set (match_operand:QI 0 "memory_operand" "=m")
6131 (match_operand:QI 1 "register_operand" "r"))
6132 (clobber (match_operand:SI 2 "register_operand" "=r"))
6133 (clobber (match_operand:SI 3 "register_operand" "=r"))]
6134 "! TARGET_BWX && (reload_in_progress || reload_completed)"
6135 "#")
6136
6137 (define_insn "reload_outhi_help"
6138 [(set (match_operand:HI 0 "memory_operand" "=m")
6139 (match_operand:HI 1 "register_operand" "r"))
6140 (clobber (match_operand:SI 2 "register_operand" "=r"))
6141 (clobber (match_operand:SI 3 "register_operand" "=r"))]
6142 "! TARGET_BWX && (reload_in_progress || reload_completed)"
6143 "#")
6144
6145 (define_split
6146 [(set (match_operand:QI 0 "register_operand" "")
6147 (match_operand:QI 1 "memory_operand" ""))
6148 (clobber (match_operand:SI 2 "register_operand" ""))]
6149 "! TARGET_BWX && reload_completed"
6150 [(const_int 0)]
6151 {
6152 rtx aligned_mem, bitnum;
6153 get_aligned_mem (operands[1], &aligned_mem, &bitnum);
6154
6155 emit_insn (gen_aligned_loadqi (operands[0], aligned_mem, bitnum,
6156 operands[2]));
6157 DONE;
6158 })
6159
6160 (define_split
6161 [(set (match_operand:HI 0 "register_operand" "")
6162 (match_operand:HI 1 "memory_operand" ""))
6163 (clobber (match_operand:SI 2 "register_operand" ""))]
6164 "! TARGET_BWX && reload_completed"
6165 [(const_int 0)]
6166 {
6167 rtx aligned_mem, bitnum;
6168 get_aligned_mem (operands[1], &aligned_mem, &bitnum);
6169
6170 emit_insn (gen_aligned_loadhi (operands[0], aligned_mem, bitnum,
6171 operands[2]));
6172 DONE;
6173 })
6174
6175 (define_split
6176 [(set (match_operand:QI 0 "memory_operand" "")
6177 (match_operand:QI 1 "register_operand" ""))
6178 (clobber (match_operand:SI 2 "register_operand" ""))
6179 (clobber (match_operand:SI 3 "register_operand" ""))]
6180 "! TARGET_BWX && reload_completed"
6181 [(const_int 0)]
6182 {
6183 rtx aligned_mem, bitnum;
6184 get_aligned_mem (operands[0], &aligned_mem, &bitnum);
6185 emit_insn (gen_aligned_store (aligned_mem, operands[1], bitnum,
6186 operands[2], operands[3]));
6187 DONE;
6188 })
6189
6190 (define_split
6191 [(set (match_operand:HI 0 "memory_operand" "")
6192 (match_operand:HI 1 "register_operand" ""))
6193 (clobber (match_operand:SI 2 "register_operand" ""))
6194 (clobber (match_operand:SI 3 "register_operand" ""))]
6195 "! TARGET_BWX && reload_completed"
6196 [(const_int 0)]
6197 {
6198 rtx aligned_mem, bitnum;
6199 get_aligned_mem (operands[0], &aligned_mem, &bitnum);
6200 emit_insn (gen_aligned_store (aligned_mem, operands[1], bitnum,
6201 operands[2], operands[3]));
6202 DONE;
6203 })
6204 \f
6205 ;; Bit field extract patterns which use ext[wlq][lh]
6206
6207 (define_expand "extv"
6208 [(set (match_operand:DI 0 "register_operand" "")
6209 (sign_extract:DI (match_operand:QI 1 "memory_operand" "")
6210 (match_operand:DI 2 "immediate_operand" "")
6211 (match_operand:DI 3 "immediate_operand" "")))]
6212 ""
6213 {
6214 int ofs;
6215
6216 /* We can do 16, 32 and 64 bit fields, if aligned on byte boundaries. */
6217 if (INTVAL (operands[3]) % 8 != 0
6218 || (INTVAL (operands[2]) != 16
6219 && INTVAL (operands[2]) != 32
6220 && INTVAL (operands[2]) != 64))
6221 FAIL;
6222
6223 /* From mips.md: extract_bit_field doesn't verify that our source
6224 matches the predicate, so we force it to be a MEM here. */
6225 if (GET_CODE (operands[1]) != MEM)
6226 FAIL;
6227
6228 /* The bit number is relative to the mode of operand 1 which is
6229 usually QImode (this might actually be a bug in expmed.c). Note
6230 that the bit number is negative in big-endian mode in this case.
6231 We have to convert that to the offset. */
6232 if (WORDS_BIG_ENDIAN)
6233 ofs = GET_MODE_BITSIZE (GET_MODE (operands[1]))
6234 - INTVAL (operands[2]) - INTVAL (operands[3]);
6235 else
6236 ofs = INTVAL (operands[3]);
6237
6238 ofs = ofs / 8;
6239
6240 alpha_expand_unaligned_load (operands[0], operands[1],
6241 INTVAL (operands[2]) / 8,
6242 ofs, 1);
6243 DONE;
6244 })
6245
6246 (define_expand "extzv"
6247 [(set (match_operand:DI 0 "register_operand" "")
6248 (zero_extract:DI (match_operand:DI 1 "nonimmediate_operand" "")
6249 (match_operand:DI 2 "immediate_operand" "")
6250 (match_operand:DI 3 "immediate_operand" "")))]
6251 ""
6252 {
6253 /* We can do 8, 16, 32 and 64 bit fields, if aligned on byte boundaries. */
6254 if (INTVAL (operands[3]) % 8 != 0
6255 || (INTVAL (operands[2]) != 8
6256 && INTVAL (operands[2]) != 16
6257 && INTVAL (operands[2]) != 32
6258 && INTVAL (operands[2]) != 64))
6259 FAIL;
6260
6261 if (GET_CODE (operands[1]) == MEM)
6262 {
6263 int ofs;
6264
6265 /* Fail 8 bit fields, falling back on a simple byte load. */
6266 if (INTVAL (operands[2]) == 8)
6267 FAIL;
6268
6269 /* The bit number is relative to the mode of operand 1 which is
6270 usually QImode (this might actually be a bug in expmed.c). Note
6271 that the bit number is negative in big-endian mode in this case.
6272 We have to convert that to the offset. */
6273 if (WORDS_BIG_ENDIAN)
6274 ofs = GET_MODE_BITSIZE (GET_MODE (operands[1]))
6275 - INTVAL (operands[2]) - INTVAL (operands[3]);
6276 else
6277 ofs = INTVAL (operands[3]);
6278
6279 ofs = ofs / 8;
6280
6281 alpha_expand_unaligned_load (operands[0], operands[1],
6282 INTVAL (operands[2]) / 8,
6283 ofs, 0);
6284 DONE;
6285 }
6286 })
6287
6288 (define_expand "insv"
6289 [(set (zero_extract:DI (match_operand:QI 0 "memory_operand" "")
6290 (match_operand:DI 1 "immediate_operand" "")
6291 (match_operand:DI 2 "immediate_operand" ""))
6292 (match_operand:DI 3 "register_operand" ""))]
6293 ""
6294 {
6295 int ofs;
6296
6297 /* We can do 16, 32 and 64 bit fields, if aligned on byte boundaries. */
6298 if (INTVAL (operands[2]) % 8 != 0
6299 || (INTVAL (operands[1]) != 16
6300 && INTVAL (operands[1]) != 32
6301 && INTVAL (operands[1]) != 64))
6302 FAIL;
6303
6304 /* From mips.md: store_bit_field doesn't verify that our source
6305 matches the predicate, so we force it to be a MEM here. */
6306 if (GET_CODE (operands[0]) != MEM)
6307 FAIL;
6308
6309 /* The bit number is relative to the mode of operand 1 which is
6310 usually QImode (this might actually be a bug in expmed.c). Note
6311 that the bit number is negative in big-endian mode in this case.
6312 We have to convert that to the offset. */
6313 if (WORDS_BIG_ENDIAN)
6314 ofs = GET_MODE_BITSIZE (GET_MODE (operands[0]))
6315 - INTVAL (operands[1]) - INTVAL (operands[2]);
6316 else
6317 ofs = INTVAL (operands[2]);
6318
6319 ofs = ofs / 8;
6320
6321 alpha_expand_unaligned_store (operands[0], operands[3],
6322 INTVAL (operands[1]) / 8, ofs);
6323 DONE;
6324 })
6325
6326 ;; Block move/clear, see alpha.c for more details.
6327 ;; Argument 0 is the destination
6328 ;; Argument 1 is the source
6329 ;; Argument 2 is the length
6330 ;; Argument 3 is the alignment
6331
6332 (define_expand "movstrqi"
6333 [(parallel [(set (match_operand:BLK 0 "memory_operand" "")
6334 (match_operand:BLK 1 "memory_operand" ""))
6335 (use (match_operand:DI 2 "immediate_operand" ""))
6336 (use (match_operand:DI 3 "immediate_operand" ""))])]
6337 ""
6338 {
6339 if (alpha_expand_block_move (operands))
6340 DONE;
6341 else
6342 FAIL;
6343 })
6344
6345 (define_expand "clrstrqi"
6346 [(parallel [(set (match_operand:BLK 0 "memory_operand" "")
6347 (const_int 0))
6348 (use (match_operand:DI 1 "immediate_operand" ""))
6349 (use (match_operand:DI 2 "immediate_operand" ""))])]
6350 ""
6351 {
6352 if (alpha_expand_block_clear (operands))
6353 DONE;
6354 else
6355 FAIL;
6356 })
6357 \f
6358 ;; Subroutine of stack space allocation. Perform a stack probe.
6359 (define_expand "probe_stack"
6360 [(set (match_dup 1) (match_operand:DI 0 "const_int_operand" ""))]
6361 ""
6362 {
6363 operands[1] = gen_rtx_MEM (DImode, plus_constant (stack_pointer_rtx,
6364 INTVAL (operands[0])));
6365 MEM_VOLATILE_P (operands[1]) = 1;
6366
6367 operands[0] = const0_rtx;
6368 })
6369
6370 ;; This is how we allocate stack space. If we are allocating a
6371 ;; constant amount of space and we know it is less than 4096
6372 ;; bytes, we need do nothing.
6373 ;;
6374 ;; If it is more than 4096 bytes, we need to probe the stack
6375 ;; periodically.
6376 (define_expand "allocate_stack"
6377 [(set (reg:DI 30)
6378 (plus:DI (reg:DI 30)
6379 (match_operand:DI 1 "reg_or_cint_operand" "")))
6380 (set (match_operand:DI 0 "register_operand" "=r")
6381 (match_dup 2))]
6382 ""
6383 {
6384 if (GET_CODE (operands[1]) == CONST_INT
6385 && INTVAL (operands[1]) < 32768)
6386 {
6387 if (INTVAL (operands[1]) >= 4096)
6388 {
6389 /* We do this the same way as in the prologue and generate explicit
6390 probes. Then we update the stack by the constant. */
6391
6392 int probed = 4096;
6393
6394 emit_insn (gen_probe_stack (GEN_INT (- probed)));
6395 while (probed + 8192 < INTVAL (operands[1]))
6396 emit_insn (gen_probe_stack (GEN_INT (- (probed += 8192))));
6397
6398 if (probed + 4096 < INTVAL (operands[1]))
6399 emit_insn (gen_probe_stack (GEN_INT (- INTVAL(operands[1]))));
6400 }
6401
6402 operands[1] = GEN_INT (- INTVAL (operands[1]));
6403 operands[2] = virtual_stack_dynamic_rtx;
6404 }
6405 else
6406 {
6407 rtx out_label = 0;
6408 rtx loop_label = gen_label_rtx ();
6409 rtx want = gen_reg_rtx (Pmode);
6410 rtx tmp = gen_reg_rtx (Pmode);
6411 rtx memref;
6412
6413 emit_insn (gen_subdi3 (want, stack_pointer_rtx,
6414 force_reg (Pmode, operands[1])));
6415 emit_insn (gen_adddi3 (tmp, stack_pointer_rtx, GEN_INT (-4096)));
6416
6417 if (GET_CODE (operands[1]) != CONST_INT)
6418 {
6419 out_label = gen_label_rtx ();
6420 emit_insn (gen_cmpdi (want, tmp));
6421 emit_jump_insn (gen_bgeu (out_label));
6422 }
6423
6424 emit_label (loop_label);
6425 memref = gen_rtx_MEM (DImode, tmp);
6426 MEM_VOLATILE_P (memref) = 1;
6427 emit_move_insn (memref, const0_rtx);
6428 emit_insn (gen_adddi3 (tmp, tmp, GEN_INT(-8192)));
6429 emit_insn (gen_cmpdi (tmp, want));
6430 emit_jump_insn (gen_bgtu (loop_label));
6431
6432 memref = gen_rtx_MEM (DImode, want);
6433 MEM_VOLATILE_P (memref) = 1;
6434 emit_move_insn (memref, const0_rtx);
6435
6436 if (out_label)
6437 emit_label (out_label);
6438
6439 emit_move_insn (stack_pointer_rtx, want);
6440 emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
6441 DONE;
6442 }
6443 })
6444
6445 ;; This is used by alpha_expand_prolog to do the same thing as above,
6446 ;; except we cannot at that time generate new basic blocks, so we hide
6447 ;; the loop in this one insn.
6448
6449 (define_insn "prologue_stack_probe_loop"
6450 [(unspec_volatile [(match_operand:DI 0 "register_operand" "r")
6451 (match_operand:DI 1 "register_operand" "r")]
6452 UNSPECV_PSPL)]
6453 ""
6454 {
6455 operands[2] = gen_label_rtx ();
6456 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, "L",
6457 CODE_LABEL_NUMBER (operands[2]));
6458
6459 return "stq $31,-8192(%1)\;subq %0,1,%0\;lda %1,-8192(%1)\;bne %0,%l2";
6460 }
6461 [(set_attr "length" "16")
6462 (set_attr "type" "multi")])
6463
6464 (define_expand "prologue"
6465 [(clobber (const_int 0))]
6466 ""
6467 {
6468 alpha_expand_prologue ();
6469 DONE;
6470 })
6471
6472 ;; These take care of emitting the ldgp insn in the prologue. This will be
6473 ;; an lda/ldah pair and we want to align them properly. So we have two
6474 ;; unspec_volatile insns, the first of which emits the ldgp assembler macro
6475 ;; and the second of which emits nothing. However, both are marked as type
6476 ;; IADD (the default) so the alignment code in alpha.c does the right thing
6477 ;; with them.
6478
6479 (define_expand "prologue_ldgp"
6480 [(set (match_dup 0)
6481 (unspec_volatile:DI [(match_dup 1) (match_dup 2)] UNSPECV_LDGP1))
6482 (set (match_dup 0)
6483 (unspec_volatile:DI [(match_dup 0) (match_dup 2)] UNSPECV_PLDGP2))]
6484 ""
6485 {
6486 operands[0] = pic_offset_table_rtx;
6487 operands[1] = gen_rtx_REG (Pmode, 27);
6488 operands[2] = (TARGET_EXPLICIT_RELOCS
6489 ? GEN_INT (alpha_next_sequence_number++)
6490 : const0_rtx);
6491 })
6492
6493 (define_insn "*ldgp_er_1"
6494 [(set (match_operand:DI 0 "register_operand" "=r")
6495 (unspec_volatile:DI [(match_operand:DI 1 "register_operand" "r")
6496 (match_operand 2 "const_int_operand" "")]
6497 UNSPECV_LDGP1))]
6498 "TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF"
6499 "ldah %0,0(%1)\t\t!gpdisp!%2")
6500
6501 (define_insn "*ldgp_er_2"
6502 [(set (match_operand:DI 0 "register_operand" "=r")
6503 (unspec:DI [(match_operand:DI 1 "register_operand" "r")
6504 (match_operand 2 "const_int_operand" "")]
6505 UNSPEC_LDGP2))]
6506 "TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF"
6507 "lda %0,0(%1)\t\t!gpdisp!%2")
6508
6509 (define_insn "*prologue_ldgp_er_2"
6510 [(set (match_operand:DI 0 "register_operand" "=r")
6511 (unspec_volatile:DI [(match_operand:DI 1 "register_operand" "r")
6512 (match_operand 2 "const_int_operand" "")]
6513 UNSPECV_PLDGP2))]
6514 "TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF"
6515 "lda %0,0(%1)\t\t!gpdisp!%2\n$%~..ng:")
6516
6517 (define_insn "*prologue_ldgp_1"
6518 [(set (match_operand:DI 0 "register_operand" "=r")
6519 (unspec_volatile:DI [(match_operand:DI 1 "register_operand" "r")
6520 (match_operand 2 "const_int_operand" "")]
6521 UNSPECV_LDGP1))]
6522 ""
6523 "ldgp %0,0(%1)\n$%~..ng:")
6524
6525 (define_insn "*prologue_ldgp_2"
6526 [(set (match_operand:DI 0 "register_operand" "=r")
6527 (unspec_volatile:DI [(match_operand:DI 1 "register_operand" "r")
6528 (match_operand 2 "const_int_operand" "")]
6529 UNSPECV_PLDGP2))]
6530 ""
6531 "")
6532
6533 ;; The _mcount profiling hook has special calling conventions, and
6534 ;; does not clobber all the registers that a normal call would. So
6535 ;; hide the fact this is a call at all.
6536
6537 (define_insn "prologue_mcount"
6538 [(unspec_volatile [(const_int 0)] UNSPECV_MCOUNT)]
6539 ""
6540 {
6541 if (TARGET_EXPLICIT_RELOCS)
6542 /* Note that we cannot use a lituse_jsr reloc, since _mcount
6543 cannot be called via the PLT. */
6544 return "ldq $28,_mcount($29)\t\t!literal\;jsr $28,($28),_mcount";
6545 else
6546 return "lda $28,_mcount\;jsr $28,($28),_mcount";
6547 }
6548 [(set_attr "type" "multi")
6549 (set_attr "length" "8")])
6550
6551 (define_insn "init_fp"
6552 [(set (match_operand:DI 0 "register_operand" "=r")
6553 (match_operand:DI 1 "register_operand" "r"))
6554 (clobber (mem:BLK (match_operand:DI 2 "register_operand" "=r")))]
6555 ""
6556 "bis $31,%1,%0")
6557
6558 (define_expand "epilogue"
6559 [(return)]
6560 ""
6561 {
6562 alpha_expand_epilogue ();
6563 })
6564
6565 (define_expand "sibcall_epilogue"
6566 [(return)]
6567 "TARGET_ABI_OSF"
6568 {
6569 alpha_expand_epilogue ();
6570 DONE;
6571 })
6572
6573 ;; In creating a large stack frame, NT _must_ use ldah+lda to load
6574 ;; the frame size into a register. We use this pattern to ensure
6575 ;; we get lda instead of addq.
6576 (define_insn "nt_lda"
6577 [(set (match_operand:DI 0 "register_operand" "=r")
6578 (unspec:DI [(match_dup 0)
6579 (match_operand:DI 1 "const_int_operand" "n")]
6580 UNSPEC_NT_LDA))]
6581 ""
6582 "lda %0,%1(%0)")
6583
6584 (define_expand "builtin_longjmp"
6585 [(use (match_operand:DI 0 "register_operand" "r"))]
6586 "TARGET_ABI_OSF"
6587 {
6588 /* The elements of the buffer are, in order: */
6589 rtx fp = gen_rtx_MEM (Pmode, operands[0]);
6590 rtx lab = gen_rtx_MEM (Pmode, plus_constant (operands[0], 8));
6591 rtx stack = gen_rtx_MEM (Pmode, plus_constant (operands[0], 16));
6592 rtx pv = gen_rtx_REG (Pmode, 27);
6593
6594 /* This bit is the same as expand_builtin_longjmp. */
6595 emit_move_insn (hard_frame_pointer_rtx, fp);
6596 emit_move_insn (pv, lab);
6597 emit_stack_restore (SAVE_NONLOCAL, stack, NULL_RTX);
6598 emit_insn (gen_rtx_USE (VOIDmode, hard_frame_pointer_rtx));
6599 emit_insn (gen_rtx_USE (VOIDmode, stack_pointer_rtx));
6600
6601 /* Load the label we are jumping through into $27 so that we know
6602 where to look for it when we get back to setjmp's function for
6603 restoring the gp. */
6604 emit_jump_insn (gen_builtin_longjmp_internal (pv));
6605 emit_barrier ();
6606 DONE;
6607 })
6608
6609 ;; This is effectively a copy of indirect_jump, but constrained such
6610 ;; that register renaming cannot foil our cunning plan with $27.
6611 (define_insn "builtin_longjmp_internal"
6612 [(set (pc)
6613 (unspec_volatile [(match_operand:DI 0 "register_operand" "c")]
6614 UNSPECV_LONGJMP))]
6615 ""
6616 "jmp $31,(%0),0"
6617 [(set_attr "type" "ibr")])
6618
6619 (define_insn "*builtin_setjmp_receiver_er_sl_1"
6620 [(unspec_volatile [(label_ref (match_operand 0 "" ""))] UNSPECV_SETJMPR)]
6621 "TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF && TARGET_AS_CAN_SUBTRACT_LABELS"
6622 "lda $27,$LSJ%=-%l0($27)\n$LSJ%=:")
6623
6624 (define_insn "*builtin_setjmp_receiver_er_1"
6625 [(unspec_volatile [(label_ref (match_operand 0 "" ""))] UNSPECV_SETJMPR)]
6626 "TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF"
6627 "br $27,$LSJ%=\n$LSJ%=:"
6628 [(set_attr "type" "ibr")])
6629
6630 (define_split
6631 [(unspec_volatile [(label_ref (match_operand 0 "" ""))] UNSPECV_SETJMPR)]
6632 "TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF
6633 && prev_nonnote_insn (insn) == operands[0]"
6634 [(const_int 0)]
6635 "DONE;")
6636
6637 (define_insn "*builtin_setjmp_receiver_1"
6638 [(unspec_volatile [(label_ref (match_operand 0 "" ""))] UNSPECV_SETJMPR)]
6639 "TARGET_ABI_OSF"
6640 "br $27,$LSJ%=\n$LSJ%=:\;ldgp $29,0($27)"
6641 [(set_attr "length" "12")
6642 (set_attr "type" "multi")])
6643
6644 (define_expand "builtin_setjmp_receiver_er"
6645 [(unspec_volatile [(label_ref (match_operand 0 "" ""))] UNSPECV_SETJMPR)
6646 (set (match_dup 1)
6647 (unspec_volatile:DI [(match_dup 2) (match_dup 3)] UNSPECV_LDGP1))
6648 (set (match_dup 1)
6649 (unspec:DI [(match_dup 1) (match_dup 3)] UNSPEC_LDGP2))]
6650 ""
6651 {
6652 operands[1] = pic_offset_table_rtx;
6653 operands[2] = gen_rtx_REG (Pmode, 27);
6654 operands[3] = GEN_INT (alpha_next_sequence_number++);
6655 })
6656
6657 (define_expand "builtin_setjmp_receiver"
6658 [(unspec_volatile [(label_ref (match_operand 0 "" ""))] UNSPECV_SETJMPR)]
6659 "TARGET_ABI_OSF"
6660 {
6661 if (TARGET_EXPLICIT_RELOCS)
6662 {
6663 emit_insn (gen_builtin_setjmp_receiver_er (operands[0]));
6664 DONE;
6665 }
6666 })
6667
6668 (define_expand "exception_receiver_er"
6669 [(set (match_dup 0)
6670 (unspec_volatile:DI [(match_dup 1) (match_dup 2)] UNSPECV_LDGP1))
6671 (set (match_dup 0)
6672 (unspec:DI [(match_dup 0) (match_dup 2)] UNSPEC_LDGP2))]
6673 ""
6674 {
6675 operands[0] = pic_offset_table_rtx;
6676 operands[1] = gen_rtx_REG (Pmode, 26);
6677 operands[2] = GEN_INT (alpha_next_sequence_number++);
6678 })
6679
6680 (define_expand "exception_receiver"
6681 [(unspec_volatile [(match_dup 0)] UNSPECV_EHR)]
6682 "TARGET_ABI_OSF"
6683 {
6684 if (TARGET_LD_BUGGY_LDGP)
6685 operands[0] = alpha_gp_save_rtx ();
6686 else if (TARGET_EXPLICIT_RELOCS)
6687 {
6688 emit_insn (gen_exception_receiver_er ());
6689 DONE;
6690 }
6691 else
6692 operands[0] = const0_rtx;
6693 })
6694
6695 (define_insn "*exception_receiver_1"
6696 [(unspec_volatile [(const_int 0)] UNSPECV_EHR)]
6697 "! TARGET_LD_BUGGY_LDGP"
6698 "ldgp $29,0($26)"
6699 [(set_attr "length" "8")
6700 (set_attr "type" "multi")])
6701
6702 (define_insn "*exception_receiver_2"
6703 [(unspec_volatile [(match_operand:DI 0 "nonimmediate_operand" "r,m")]
6704 UNSPECV_EHR)]
6705 "TARGET_LD_BUGGY_LDGP"
6706 "@
6707 bis $31,%0,$29
6708 ldq $29,%0"
6709 [(set_attr "type" "ilog,ild")])
6710
6711 (define_expand "nonlocal_goto_receiver"
6712 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
6713 (set (reg:DI 27) (mem:DI (reg:DI 29)))
6714 (unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
6715 (use (reg:DI 27))]
6716 "TARGET_ABI_OPEN_VMS"
6717 "")
6718
6719 (define_insn "arg_home"
6720 [(unspec [(const_int 0)] UNSPEC_ARG_HOME)
6721 (use (reg:DI 1))
6722 (use (reg:DI 25))
6723 (use (reg:DI 16))
6724 (use (reg:DI 17))
6725 (use (reg:DI 18))
6726 (use (reg:DI 19))
6727 (use (reg:DI 20))
6728 (use (reg:DI 21))
6729 (use (reg:DI 48))
6730 (use (reg:DI 49))
6731 (use (reg:DI 50))
6732 (use (reg:DI 51))
6733 (use (reg:DI 52))
6734 (use (reg:DI 53))
6735 (clobber (mem:BLK (const_int 0)))
6736 (clobber (reg:DI 24))
6737 (clobber (reg:DI 25))
6738 (clobber (reg:DI 0))]
6739 "TARGET_ABI_OPEN_VMS"
6740 "lda $0,OTS$HOME_ARGS\;ldq $0,8($0)\;jsr $0,OTS$HOME_ARGS"
6741 [(set_attr "length" "16")
6742 (set_attr "type" "multi")])
6743
6744 ;; Load the CIW into r2 for calling __T3E_MISMATCH
6745
6746 (define_expand "umk_mismatch_args"
6747 [(set:DI (match_dup 1) (mem:DI (plus:DI (reg:DI 15) (const_int -16))))
6748 (set:DI (match_dup 2) (mem:DI (plus:DI (match_dup 1) (const_int -32))))
6749 (set:DI (reg:DI 1) (match_operand:DI 0 "const_int_operand" ""))
6750 (set:DI (match_dup 3) (plus:DI (mult:DI (reg:DI 25)
6751 (const_int 8))
6752 (match_dup 2)))
6753 (set:DI (reg:DI 2) (mem:DI (match_dup 3)))]
6754 "TARGET_ABI_UNICOSMK"
6755 {
6756 operands[1] = gen_reg_rtx (DImode);
6757 operands[2] = gen_reg_rtx (DImode);
6758 operands[3] = gen_reg_rtx (DImode);
6759 })
6760
6761 (define_insn "arg_home_umk"
6762 [(unspec [(const_int 0)] UNSPEC_ARG_HOME)
6763 (use (reg:DI 1))
6764 (use (reg:DI 2))
6765 (use (reg:DI 16))
6766 (use (reg:DI 17))
6767 (use (reg:DI 18))
6768 (use (reg:DI 19))
6769 (use (reg:DI 20))
6770 (use (reg:DI 21))
6771 (use (reg:DI 48))
6772 (use (reg:DI 49))
6773 (use (reg:DI 50))
6774 (use (reg:DI 51))
6775 (use (reg:DI 52))
6776 (use (reg:DI 53))
6777 (clobber (mem:BLK (const_int 0)))
6778 (parallel [
6779 (clobber (reg:DI 22))
6780 (clobber (reg:DI 23))
6781 (clobber (reg:DI 24))
6782 (clobber (reg:DI 0))
6783 (clobber (reg:DI 1))
6784 (clobber (reg:DI 2))
6785 (clobber (reg:DI 3))
6786 (clobber (reg:DI 4))
6787 (clobber (reg:DI 5))
6788 (clobber (reg:DI 6))
6789 (clobber (reg:DI 7))
6790 (clobber (reg:DI 8))])]
6791 "TARGET_ABI_UNICOSMK"
6792 "laum $4,__T3E_MISMATCH($31)\;sll $4,32,$4\;lalm $4,__T3E_MISMATCH($4)\;lal $4,__T3E_MISMATCH($4)\;jsr $3,($4)"
6793 [(set_attr "length" "16")
6794 (set_attr "type" "multi")])
6795
6796 ;; Prefetch data.
6797 ;;
6798 ;; On EV4, these instructions are nops -- no load occurs.
6799 ;;
6800 ;; On EV5, these instructions act as a normal load, and thus can trap
6801 ;; if the address is invalid. The OS may (or may not) handle this in
6802 ;; the entMM fault handler and suppress the fault. If so, then this
6803 ;; has the effect of a read prefetch instruction.
6804 ;;
6805 ;; On EV6, these become official prefetch instructions.
6806
6807 (define_insn "prefetch"
6808 [(prefetch (match_operand:DI 0 "address_operand" "p")
6809 (match_operand:DI 1 "const_int_operand" "n")
6810 (match_operand:DI 2 "const_int_operand" "n"))]
6811 "TARGET_FIXUP_EV5_PREFETCH || TARGET_CPU_EV6"
6812 {
6813 /* Interpret "no temporal locality" as this data should be evicted once
6814 it is used. The "evict next" alternatives load the data into the cache
6815 and leave the LRU eviction counter pointing to that block. */
6816 static const char * const alt[2][2] = {
6817 {
6818 "lds $f31,%a0", /* read, evict next */
6819 "ldl $31,%a0", /* read, evict last */
6820 },
6821 {
6822 "ldt $f31,%a0", /* write, evict next */
6823 "ldq $31,%a0", /* write, evict last */
6824 }
6825 };
6826
6827 bool write = INTVAL (operands[1]) != 0;
6828 bool lru = INTVAL (operands[2]) != 0;
6829
6830 return alt[write][lru];
6831 }
6832 [(set_attr "type" "ild")])
6833
6834 ;; Close the trap shadow of preceding instructions. This is generated
6835 ;; by alpha_reorg.
6836
6837 (define_insn "trapb"
6838 [(unspec_volatile [(const_int 0)] UNSPECV_TRAPB)]
6839 ""
6840 "trapb"
6841 [(set_attr "type" "misc")])
6842
6843 ;; No-op instructions used by machine-dependent reorg to preserve
6844 ;; alignment for instruction issue.
6845 ;; The Unicos/Mk assembler does not support these opcodes.
6846
6847 (define_insn "nop"
6848 [(const_int 0)]
6849 ""
6850 "bis $31,$31,$31"
6851 [(set_attr "type" "ilog")])
6852
6853 (define_insn "fnop"
6854 [(const_int 1)]
6855 "TARGET_FP"
6856 "cpys $f31,$f31,$f31"
6857 [(set_attr "type" "fcpys")])
6858
6859 (define_insn "unop"
6860 [(const_int 2)]
6861 ""
6862 "ldq_u $31,0($30)")
6863
6864 ;; On Unicos/Mk we use a macro for aligning code.
6865
6866 (define_insn "realign"
6867 [(unspec_volatile [(match_operand 0 "immediate_operand" "i")]
6868 UNSPECV_REALIGN)]
6869 ""
6870 {
6871 if (TARGET_ABI_UNICOSMK)
6872 return "gcc@code@align %0";
6873 else
6874 return ".align %0 #realign";
6875 })
6876
6877 ;; The call patterns are at the end of the file because their
6878 ;; wildcard operand0 interferes with nice recognition.
6879
6880 (define_insn "*call_value_osf_1_er"
6881 [(set (match_operand 0 "" "")
6882 (call (mem:DI (match_operand:DI 1 "call_operand" "c,R,s"))
6883 (match_operand 2 "" "")))
6884 (use (reg:DI 29))
6885 (clobber (reg:DI 26))]
6886 "TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF"
6887 "@
6888 jsr $26,(%1),0\;ldah $29,0($26)\t\t!gpdisp!%*\;lda $29,0($29)\t\t!gpdisp!%*
6889 bsr $26,$%1..ng
6890 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!%*"
6891 [(set_attr "type" "jsr")
6892 (set_attr "length" "12,*,16")])
6893
6894 ;; We must use peep2 instead of a split because we need accurate life
6895 ;; information for $gp. Consider the case of { bar(); while (1); }.
6896 (define_peephole2
6897 [(parallel [(set (match_operand 0 "" "")
6898 (call (mem:DI (match_operand:DI 1 "call_operand" ""))
6899 (match_operand 2 "" "")))
6900 (use (reg:DI 29))
6901 (clobber (reg:DI 26))])]
6902 "TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF && reload_completed
6903 && ! current_file_function_operand (operands[1], Pmode)
6904 && peep2_regno_dead_p (1, 29)"
6905 [(parallel [(set (match_dup 0)
6906 (call (mem:DI (match_dup 3))
6907 (match_dup 2)))
6908 (set (reg:DI 26) (plus:DI (pc) (const_int 4)))
6909 (unspec_volatile [(reg:DI 29)] UNSPECV_BLOCKAGE)
6910 (use (match_dup 1))
6911 (use (match_dup 4))])]
6912 {
6913 if (CONSTANT_P (operands[1]))
6914 {
6915 operands[3] = gen_rtx_REG (Pmode, 27);
6916 operands[4] = GEN_INT (alpha_next_sequence_number++);
6917 emit_insn (gen_movdi_er_high_g (operands[3], pic_offset_table_rtx,
6918 operands[1], operands[4]));
6919 }
6920 else
6921 {
6922 operands[3] = operands[1];
6923 operands[1] = const0_rtx;
6924 operands[4] = const0_rtx;
6925 }
6926 })
6927
6928 (define_peephole2
6929 [(parallel [(set (match_operand 0 "" "")
6930 (call (mem:DI (match_operand:DI 1 "call_operand" ""))
6931 (match_operand 2 "" "")))
6932 (use (reg:DI 29))
6933 (clobber (reg:DI 26))])]
6934 "TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF && reload_completed
6935 && ! current_file_function_operand (operands[1], Pmode)
6936 && ! peep2_regno_dead_p (1, 29)"
6937 [(parallel [(set (match_dup 0)
6938 (call (mem:DI (match_dup 3))
6939 (match_dup 2)))
6940 (set (reg:DI 26) (plus:DI (pc) (const_int 4)))
6941 (unspec_volatile [(reg:DI 29)] UNSPECV_BLOCKAGE)
6942 (use (match_dup 1))
6943 (use (match_dup 5))])
6944 (set (reg:DI 29)
6945 (unspec_volatile:DI [(reg:DI 26) (match_dup 4)] UNSPECV_LDGP1))
6946 (set (reg:DI 29)
6947 (unspec:DI [(reg:DI 29) (match_dup 4)] UNSPEC_LDGP2))]
6948 {
6949 if (CONSTANT_P (operands[1]))
6950 {
6951 operands[3] = gen_rtx_REG (Pmode, 27);
6952 operands[5] = GEN_INT (alpha_next_sequence_number++);
6953 emit_insn (gen_movdi_er_high_g (operands[3], pic_offset_table_rtx,
6954 operands[1], operands[5]));
6955 }
6956 else
6957 {
6958 operands[3] = operands[1];
6959 operands[1] = const0_rtx;
6960 operands[5] = const0_rtx;
6961 }
6962 operands[4] = GEN_INT (alpha_next_sequence_number++);
6963 })
6964
6965 ;; We add a blockage unspec_volatile to prevent insns from moving down
6966 ;; from above the call to in between the call and the ldah gpdisp.
6967 (define_insn "*call_value_osf_2_er"
6968 [(set (match_operand 0 "" "")
6969 (call (mem:DI (match_operand:DI 1 "register_operand" "c"))
6970 (match_operand 2 "" "")))
6971 (set (reg:DI 26)
6972 (plus:DI (pc) (const_int 4)))
6973 (unspec_volatile [(reg:DI 29)] UNSPECV_BLOCKAGE)
6974 (use (match_operand 3 "" ""))
6975 (use (match_operand 4 "const_int_operand" ""))]
6976 "TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF"
6977 "jsr $26,(%1),%3%J4"
6978 [(set_attr "type" "jsr")])
6979
6980 (define_insn "*call_value_osf_1_noreturn"
6981 [(set (match_operand 0 "" "")
6982 (call (mem:DI (match_operand:DI 1 "call_operand" "c,R,s"))
6983 (match_operand 2 "" "")))
6984 (use (reg:DI 29))
6985 (clobber (reg:DI 26))]
6986 "! TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF
6987 && find_reg_note (insn, REG_NORETURN, NULL_RTX)"
6988 "@
6989 jsr $26,($27),0
6990 bsr $26,$%1..ng
6991 jsr $26,%1"
6992 [(set_attr "type" "jsr")
6993 (set_attr "length" "*,*,8")])
6994
6995 (define_insn "*call_value_osf_1"
6996 [(set (match_operand 0 "" "")
6997 (call (mem:DI (match_operand:DI 1 "call_operand" "c,R,s"))
6998 (match_operand 2 "" "")))
6999 (use (reg:DI 29))
7000 (clobber (reg:DI 26))]
7001 "! TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF"
7002 "@
7003 jsr $26,($27),0\;ldgp $29,0($26)
7004 bsr $26,$%1..ng
7005 jsr $26,%1\;ldgp $29,0($26)"
7006 [(set_attr "type" "jsr")
7007 (set_attr "length" "12,*,16")])
7008
7009 (define_insn "*sibcall_value_osf_1_er"
7010 [(set (match_operand 0 "" "")
7011 (call (mem:DI (match_operand:DI 1 "symbolic_operand" "R,s"))
7012 (match_operand 2 "" "")))
7013 (unspec [(reg:DI 29)] UNSPEC_SIBCALL)]
7014 "TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF"
7015 "@
7016 br $31,$%1..ng
7017 ldq $27,%1($29)\t\t!literal!%#\;jmp $31,($27),%1\t\t!lituse_jsr!%#"
7018 [(set_attr "type" "jsr")
7019 (set_attr "length" "*,8")])
7020
7021 (define_insn "*sibcall_value_osf_1"
7022 [(set (match_operand 0 "" "")
7023 (call (mem:DI (match_operand:DI 1 "symbolic_operand" "R,s"))
7024 (match_operand 2 "" "")))
7025 (unspec [(reg:DI 29)] UNSPEC_SIBCALL)]
7026 "! TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF"
7027 "@
7028 br $31,$%1..ng
7029 lda $27,%1\;jmp $31,($27),%1"
7030 [(set_attr "type" "jsr")
7031 (set_attr "length" "*,8")])
7032
7033 (define_insn "*call_value_nt_1"
7034 [(set (match_operand 0 "" "")
7035 (call (mem:DI (match_operand:DI 1 "call_operand" "r,R,s"))
7036 (match_operand 2 "" "")))
7037 (clobber (reg:DI 26))]
7038 "TARGET_ABI_WINDOWS_NT"
7039 "@
7040 jsr $26,(%1)
7041 bsr $26,%1
7042 jsr $26,%1"
7043 [(set_attr "type" "jsr")
7044 (set_attr "length" "*,*,12")])
7045
7046 (define_insn "*call_value_vms_1"
7047 [(set (match_operand 0 "" "")
7048 (call (mem:DI (match_operand:DI 1 "call_operand" "r,s"))
7049 (match_operand 2 "" "")))
7050 (use (match_operand:DI 3 "nonimmediate_operand" "r,m"))
7051 (use (reg:DI 25))
7052 (use (reg:DI 26))
7053 (clobber (reg:DI 27))]
7054 "TARGET_ABI_OPEN_VMS"
7055 "@
7056 mov %3,$27\;jsr $26,0\;ldq $27,0($29)
7057 ldq $27,%3\;jsr $26,%1\;ldq $27,0($29)"
7058 [(set_attr "type" "jsr")
7059 (set_attr "length" "12,16")])
7060
7061 (define_insn "*call_value_umk"
7062 [(set (match_operand 0 "" "")
7063 (call (mem:DI (match_operand:DI 1 "call_operand" "r"))
7064 (match_operand 2 "" "")))
7065 (use (reg:DI 25))
7066 (clobber (reg:DI 26))]
7067 "TARGET_ABI_UNICOSMK"
7068 "jsr $26,(%1)"
7069 [(set_attr "type" "jsr")])
7070