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