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