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