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