]> git.ipfire.org Git - thirdparty/gcc.git/blob - gcc/config/alpha/alpha.md
Update copyright years.
[thirdparty/gcc.git] / gcc / config / alpha / alpha.md
1 ;; Machine description for DEC Alpha for GNU C compiler
2 ;; Copyright (C) 1992-2016 Free Software Foundation, Inc.
3 ;; Contributed by Richard Kenner (kenner@vlsi1.ultra.nyu.edu)
4 ;;
5 ;; This file is part of GCC.
6 ;;
7 ;; GCC is free software; you can redistribute it and/or modify
8 ;; it under the terms of the GNU General Public License as published by
9 ;; the Free Software Foundation; either version 3, or (at your option)
10 ;; any later version.
11 ;;
12 ;; GCC is distributed in the hope that it will be useful,
13 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
14 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 ;; GNU General Public License for more details.
16 ;;
17 ;; You should have received a copy of the GNU General Public License
18 ;; along with GCC; see the file COPYING3. If not see
19 ;; <http://www.gnu.org/licenses/>.
20
21 ;;- See file "rtl.def" for documentation on define_insn, match_*, et. al.
22
23 ;; Uses of UNSPEC in this file:
24
25 (define_c_enum "unspec" [
26 UNSPEC_XFLT_COMPARE
27 UNSPEC_ARG_HOME
28 UNSPEC_LDGP1
29 UNSPEC_INSXH
30 UNSPEC_MSKXH
31 UNSPEC_CVTQL
32 UNSPEC_CVTLQ
33 UNSPEC_LDGP2
34 UNSPEC_LITERAL
35 UNSPEC_LITUSE
36 UNSPEC_SIBCALL
37 UNSPEC_SYMBOL
38
39 ;; TLS Support
40 UNSPEC_TLSGD_CALL
41 UNSPEC_TLSLDM_CALL
42 UNSPEC_TLSGD
43 UNSPEC_TLSLDM
44 UNSPEC_DTPREL
45 UNSPEC_TPREL
46 UNSPEC_TP
47
48 ;; Builtins
49 UNSPEC_CMPBGE
50 UNSPEC_ZAP
51 UNSPEC_AMASK
52 UNSPEC_IMPLVER
53 UNSPEC_PERR
54 UNSPEC_COPYSIGN
55
56 ;; Atomic operations
57 UNSPEC_MB
58 UNSPEC_ATOMIC
59 UNSPEC_CMPXCHG
60 UNSPEC_XCHG
61 ])
62
63 ;; UNSPEC_VOLATILE:
64
65 (define_c_enum "unspecv" [
66 UNSPECV_IMB
67 UNSPECV_BLOCKAGE
68 UNSPECV_SETJMPR ; builtin_setjmp_receiver
69 UNSPECV_LONGJMP ; builtin_longjmp
70 UNSPECV_TRAPB
71 UNSPECV_PSPL ; prologue_stack_probe_loop
72 UNSPECV_REALIGN
73 UNSPECV_EHR ; exception_receiver
74 UNSPECV_MCOUNT
75 UNSPECV_FORCE_MOV
76 UNSPECV_LDGP1
77 UNSPECV_PLDGP2 ; prologue ldgp
78 UNSPECV_SET_TP
79 UNSPECV_RPCC
80 UNSPECV_SETJMPR_ER ; builtin_setjmp_receiver fragment
81 UNSPECV_LL ; load-locked
82 UNSPECV_SC ; store-conditional
83 UNSPECV_CMPXCHG
84 ])
85
86 ;; On non-BWX targets, CQImode must be handled the similarly to HImode
87 ;; when generating reloads.
88 (define_mode_iterator RELOAD12 [QI HI CQI])
89 (define_mode_attr reloadmode [(QI "qi") (HI "hi") (CQI "hi")])
90
91 ;; Other mode iterators
92 (define_mode_iterator IMODE [QI HI SI DI])
93 (define_mode_iterator I12MODE [QI HI])
94 (define_mode_iterator I124MODE [QI HI SI])
95 (define_mode_iterator I24MODE [HI SI])
96 (define_mode_iterator I248MODE [HI SI DI])
97 (define_mode_iterator I48MODE [SI DI])
98
99 (define_mode_attr DWI [(SI "DI") (DI "TI")])
100 (define_mode_attr modesuffix [(QI "b") (HI "w") (SI "l") (DI "q")
101 (V8QI "b8") (V4HI "w4")
102 (SF "%,") (DF "%-")])
103 (define_mode_attr vecmodesuffix [(QI "b8") (HI "w4")])
104
105 (define_code_iterator any_maxmin [smax smin umax umin])
106
107 (define_code_attr maxmin [(smax "maxs") (smin "mins")
108 (umax "maxu") (umin "minu")])
109
110 ;; Where necessary, the suffixes _le and _be are used to distinguish between
111 ;; little-endian and big-endian patterns.
112 ;;
113 ;; Note that the Unicos/Mk assembler does not support the following
114 ;; opcodes: mov, fmov, nop, fnop, unop.
115 \f
116 ;; Processor type -- this attribute must exactly match the processor_type
117 ;; enumeration in alpha.h.
118
119 (define_attr "tune" "ev4,ev5,ev6"
120 (const (symbol_ref "((enum attr_tune) alpha_tune)")))
121
122 ;; Define an insn type attribute. This is used in function unit delay
123 ;; computations, among other purposes. For the most part, we use the names
124 ;; defined in the EV4 documentation, but add a few that we have to know about
125 ;; separately.
126
127 (define_attr "type"
128 "ild,fld,ldsym,ist,fst,ibr,callpal,fbr,jsr,iadd,ilog,shift,icmov,fcmov,
129 icmp,imul,fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,mb,ld_l,st_c,
130 multi,none"
131 (const_string "iadd"))
132
133 ;; Describe a user's asm statement.
134 (define_asm_attributes
135 [(set_attr "type" "multi")])
136
137 ;; Define the operand size an insn operates on. Used primarily by mul
138 ;; and div operations that have size dependent timings.
139
140 (define_attr "opsize" "si,di,udi"
141 (const_string "di"))
142
143 ;; The TRAP attribute marks instructions that may generate traps
144 ;; (which are imprecise and may need a trapb if software completion
145 ;; is desired).
146
147 (define_attr "trap" "no,yes"
148 (const_string "no"))
149
150 ;; The ROUND_SUFFIX attribute marks which instructions require a
151 ;; rounding-mode suffix. The value NONE indicates no suffix,
152 ;; the value NORMAL indicates a suffix controlled by alpha_fprm.
153
154 (define_attr "round_suffix" "none,normal,c"
155 (const_string "none"))
156
157 ;; The TRAP_SUFFIX attribute marks instructions requiring a trap-mode suffix:
158 ;; NONE no suffix
159 ;; SU accepts only /su (cmpt et al)
160 ;; SUI accepts only /sui (cvtqt and cvtqs)
161 ;; V_SV accepts /v and /sv (cvtql only)
162 ;; V_SV_SVI accepts /v, /sv and /svi (cvttq only)
163 ;; U_SU_SUI accepts /u, /su and /sui (most fp instructions)
164 ;;
165 ;; The actual suffix emitted is controlled by alpha_fptm.
166
167 (define_attr "trap_suffix" "none,su,sui,v_sv,v_sv_svi,u_su_sui"
168 (const_string "none"))
169
170 ;; The length of an instruction sequence in bytes.
171
172 (define_attr "length" ""
173 (const_int 4))
174
175 ;; The USEGP attribute marks instructions that have relocations that use
176 ;; the GP.
177
178 (define_attr "usegp" "no,yes"
179 (cond [(eq_attr "type" "ldsym,jsr")
180 (const_string "yes")
181 (eq_attr "type" "ild,fld,ist,fst")
182 (symbol_ref "((enum attr_usegp) alpha_find_lo_sum_using_gp (insn))")
183 ]
184 (const_string "no")))
185
186 ;; The CANNOT_COPY attribute marks instructions with relocations that
187 ;; cannot easily be duplicated. This includes insns with gpdisp relocs
188 ;; since they have to stay in 1-1 correspondence with one another. This
189 ;; also includes jsr insns, since they must stay in correspondence with
190 ;; the immediately following gpdisp instructions.
191
192 (define_attr "cannot_copy" "false,true"
193 (const_string "false"))
194
195 ;; Used to control the "enabled" attribute on a per-instruction basis.
196 ;; For convenience, conflate ABI issues re loading of addresses with
197 ;; an "isa".
198 (define_attr "isa" "base,bwx,max,fix,cix,vms,ner,er"
199 (const_string "base"))
200
201 (define_attr "enabled" ""
202 (cond [(eq_attr "isa" "bwx") (symbol_ref "TARGET_BWX")
203 (eq_attr "isa" "max") (symbol_ref "TARGET_MAX")
204 (eq_attr "isa" "fix") (symbol_ref "TARGET_FIX")
205 (eq_attr "isa" "cix") (symbol_ref "TARGET_CIX")
206 (eq_attr "isa" "vms") (symbol_ref "TARGET_ABI_OPEN_VMS")
207 (eq_attr "isa" "ner") (symbol_ref "!TARGET_EXPLICIT_RELOCS")
208 (eq_attr "isa" "er") (symbol_ref "TARGET_EXPLICIT_RELOCS")
209 ]
210 (const_int 1)))
211 \f
212 ;; Include scheduling descriptions.
213
214 (include "ev4.md")
215 (include "ev5.md")
216 (include "ev6.md")
217
218 \f
219 ;; Operand and operator predicates and constraints
220
221 (include "predicates.md")
222 (include "constraints.md")
223
224 \f
225 ;; First define the arithmetic insns. Note that the 32-bit forms also
226 ;; sign-extend.
227
228 ;; Handle 32-64 bit extension from memory to a floating point register
229 ;; specially, since this occurs frequently in int->double conversions.
230 ;;
231 ;; Note that while we must retain the =f case in the insn for reload's
232 ;; benefit, it should be eliminated after reload, so we should never emit
233 ;; code for that case. But we don't reject the possibility.
234
235 (define_expand "extendsidi2"
236 [(set (match_operand:DI 0 "register_operand")
237 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand")))])
238
239 (define_insn "*cvtlq"
240 [(set (match_operand:DI 0 "register_operand" "=f")
241 (unspec:DI [(match_operand:SF 1 "reg_or_0_operand" "fG")]
242 UNSPEC_CVTLQ))]
243 ""
244 "cvtlq %1,%0"
245 [(set_attr "type" "fadd")])
246
247 (define_insn "*extendsidi2_1"
248 [(set (match_operand:DI 0 "register_operand" "=r,r,!*f")
249 (sign_extend:DI
250 (match_operand:SI 1 "nonimmediate_operand" "r,m,m")))]
251 ""
252 "@
253 addl $31,%1,%0
254 ldl %0,%1
255 lds %0,%1\;cvtlq %0,%0"
256 [(set_attr "type" "iadd,ild,fld")
257 (set_attr "length" "*,*,8")])
258
259 (define_split
260 [(set (match_operand:DI 0 "hard_fp_register_operand")
261 (sign_extend:DI (match_operand:SI 1 "memory_operand")))]
262 "reload_completed"
263 [(set (match_dup 2) (match_dup 1))
264 (set (match_dup 0) (unspec:DI [(match_dup 2)] UNSPEC_CVTLQ))]
265 {
266 operands[1] = adjust_address (operands[1], SFmode, 0);
267 operands[2] = gen_rtx_REG (SFmode, REGNO (operands[0]));
268 })
269
270 ;; Optimize sign-extension of SImode loads. This shows up in the wake of
271 ;; reload when converting fp->int.
272
273 (define_peephole2
274 [(set (match_operand:SI 0 "hard_int_register_operand")
275 (match_operand:SI 1 "memory_operand"))
276 (set (match_operand:DI 2 "hard_int_register_operand")
277 (sign_extend:DI (match_dup 0)))]
278 "true_regnum (operands[0]) == true_regnum (operands[2])
279 || peep2_reg_dead_p (2, operands[0])"
280 [(set (match_dup 2)
281 (sign_extend:DI (match_dup 1)))])
282
283 (define_insn "addsi3"
284 [(set (match_operand:SI 0 "register_operand" "=r,r,r,r")
285 (plus:SI (match_operand:SI 1 "reg_or_0_operand" "%rJ,rJ,rJ,rJ")
286 (match_operand:SI 2 "add_operand" "rI,O,K,L")))]
287 ""
288 "@
289 addl %r1,%2,%0
290 subl %r1,%n2,%0
291 lda %0,%2(%r1)
292 ldah %0,%h2(%r1)")
293
294 (define_split
295 [(set (match_operand:SI 0 "register_operand")
296 (plus:SI (match_operand:SI 1 "register_operand")
297 (match_operand:SI 2 "const_int_operand")))]
298 "! add_operand (operands[2], SImode)"
299 [(set (match_dup 0) (plus:SI (match_dup 1) (match_dup 3)))
300 (set (match_dup 0) (plus:SI (match_dup 0) (match_dup 4)))]
301 {
302 HOST_WIDE_INT val = INTVAL (operands[2]);
303 HOST_WIDE_INT low = (val & 0xffff) - 2 * (val & 0x8000);
304 HOST_WIDE_INT rest = val - low;
305
306 operands[3] = GEN_INT (rest);
307 operands[4] = GEN_INT (low);
308 })
309
310 (define_insn "*addsi_se"
311 [(set (match_operand:DI 0 "register_operand" "=r,r")
312 (sign_extend:DI
313 (plus:SI (match_operand:SI 1 "reg_or_0_operand" "%rJ,rJ")
314 (match_operand:SI 2 "sext_add_operand" "rI,O"))))]
315 ""
316 "@
317 addl %r1,%2,%0
318 subl %r1,%n2,%0")
319
320 (define_insn "*addsi_se2"
321 [(set (match_operand:DI 0 "register_operand" "=r,r")
322 (sign_extend:DI
323 (subreg:SI (plus:DI (match_operand:DI 1 "reg_or_0_operand" "%rJ,rJ")
324 (match_operand:DI 2 "sext_add_operand" "rI,O"))
325 0)))]
326 ""
327 "@
328 addl %r1,%2,%0
329 subl %r1,%n2,%0")
330
331 (define_split
332 [(set (match_operand:DI 0 "register_operand")
333 (sign_extend:DI
334 (plus:SI (match_operand:SI 1 "reg_not_elim_operand")
335 (match_operand:SI 2 "const_int_operand"))))
336 (clobber (match_operand:SI 3 "reg_not_elim_operand"))]
337 "! sext_add_operand (operands[2], SImode) && INTVAL (operands[2]) > 0
338 && INTVAL (operands[2]) % 4 == 0"
339 [(set (match_dup 3) (match_dup 4))
340 (set (match_dup 0) (sign_extend:DI (plus:SI (mult:SI (match_dup 3)
341 (match_dup 5))
342 (match_dup 1))))]
343 {
344 HOST_WIDE_INT val = INTVAL (operands[2]) / 4;
345 int mult = 4;
346
347 if (val % 2 == 0)
348 val /= 2, mult = 8;
349
350 operands[4] = GEN_INT (val);
351 operands[5] = GEN_INT (mult);
352 })
353
354 (define_split
355 [(set (match_operand:DI 0 "register_operand")
356 (sign_extend:DI
357 (plus:SI (match_operator:SI 1 "comparison_operator"
358 [(match_operand 2)
359 (match_operand 3)])
360 (match_operand:SI 4 "add_operand"))))
361 (clobber (match_operand:DI 5 "register_operand"))]
362 ""
363 [(set (match_dup 5) (match_dup 6))
364 (set (match_dup 0) (sign_extend:DI (plus:SI (match_dup 7) (match_dup 4))))]
365 {
366 operands[6] = gen_rtx_fmt_ee (GET_CODE (operands[1]), DImode,
367 operands[2], operands[3]);
368 operands[7] = gen_lowpart (SImode, operands[5]);
369 })
370
371 (define_expand "adddi3"
372 [(set (match_operand:DI 0 "register_operand")
373 (plus:DI (match_operand:DI 1 "register_operand")
374 (match_operand:DI 2 "add_operand")))])
375
376 (define_insn "*adddi_er_lo16_dtp"
377 [(set (match_operand:DI 0 "register_operand" "=r")
378 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
379 (match_operand:DI 2 "dtp16_symbolic_operand")))]
380 "HAVE_AS_TLS"
381 "lda %0,%2(%1)\t\t!dtprel")
382
383 (define_insn "*adddi_er_hi32_dtp"
384 [(set (match_operand:DI 0 "register_operand" "=r")
385 (plus:DI (match_operand:DI 1 "register_operand" "r")
386 (high:DI (match_operand:DI 2 "dtp32_symbolic_operand"))))]
387 "HAVE_AS_TLS"
388 "ldah %0,%2(%1)\t\t!dtprelhi")
389
390 (define_insn "*adddi_er_lo32_dtp"
391 [(set (match_operand:DI 0 "register_operand" "=r")
392 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
393 (match_operand:DI 2 "dtp32_symbolic_operand")))]
394 "HAVE_AS_TLS"
395 "lda %0,%2(%1)\t\t!dtprello")
396
397 (define_insn "*adddi_er_lo16_tp"
398 [(set (match_operand:DI 0 "register_operand" "=r")
399 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
400 (match_operand:DI 2 "tp16_symbolic_operand")))]
401 "HAVE_AS_TLS"
402 "lda %0,%2(%1)\t\t!tprel")
403
404 (define_insn "*adddi_er_hi32_tp"
405 [(set (match_operand:DI 0 "register_operand" "=r")
406 (plus:DI (match_operand:DI 1 "register_operand" "r")
407 (high:DI (match_operand:DI 2 "tp32_symbolic_operand"))))]
408 "HAVE_AS_TLS"
409 "ldah %0,%2(%1)\t\t!tprelhi")
410
411 (define_insn "*adddi_er_lo32_tp"
412 [(set (match_operand:DI 0 "register_operand" "=r")
413 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
414 (match_operand:DI 2 "tp32_symbolic_operand")))]
415 "HAVE_AS_TLS"
416 "lda %0,%2(%1)\t\t!tprello")
417
418 (define_insn "*adddi_er_high_l"
419 [(set (match_operand:DI 0 "register_operand" "=r")
420 (plus:DI (match_operand:DI 1 "register_operand" "r")
421 (high:DI (match_operand:DI 2 "local_symbolic_operand"))))]
422 "TARGET_EXPLICIT_RELOCS && reload_completed"
423 "ldah %0,%2(%1)\t\t!gprelhigh"
424 [(set_attr "usegp" "yes")])
425
426 (define_split
427 [(set (match_operand:DI 0 "register_operand")
428 (high:DI (match_operand:DI 1 "local_symbolic_operand")))]
429 "TARGET_EXPLICIT_RELOCS && reload_completed"
430 [(set (match_dup 0)
431 (plus:DI (match_dup 2) (high:DI (match_dup 1))))]
432 "operands[2] = pic_offset_table_rtx;")
433
434 ;; We used to expend quite a lot of effort choosing addq/subq/lda.
435 ;; With complications like
436 ;;
437 ;; The NT stack unwind code can't handle a subq to adjust the stack
438 ;; (that's a bug, but not one we can do anything about). As of NT4.0 SP3,
439 ;; the exception handling code will loop if a subq is used and an
440 ;; exception occurs.
441 ;;
442 ;; The 19980616 change to emit prologues as RTL also confused some
443 ;; versions of GDB, which also interprets prologues. This has been
444 ;; fixed as of GDB 4.18, but it does not harm to unconditionally
445 ;; use lda here.
446 ;;
447 ;; and the fact that the three insns schedule exactly the same, it's
448 ;; just not worth the effort.
449
450 (define_insn "*adddi_internal"
451 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
452 (plus:DI (match_operand:DI 1 "register_operand" "%r,r,r")
453 (match_operand:DI 2 "add_operand" "r,K,L")))]
454 ""
455 "@
456 addq %1,%2,%0
457 lda %0,%2(%1)
458 ldah %0,%h2(%1)")
459
460 ;; ??? Allow large constants when basing off the frame pointer or some
461 ;; virtual register that may eliminate to the frame pointer. This is
462 ;; done because register elimination offsets will change the hi/lo split,
463 ;; and if we split before reload, we will require additional instructions.
464
465 (define_insn "*adddi_fp_hack"
466 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
467 (plus:DI (match_operand:DI 1 "reg_no_subreg_operand" "r,r,r")
468 (match_operand:DI 2 "const_int_operand" "K,L,n")))]
469 "NONSTRICT_REG_OK_FP_BASE_P (operands[1])
470 && INTVAL (operands[2]) >= 0
471 /* This is the largest constant an lda+ldah pair can add, minus
472 an upper bound on the displacement between SP and AP during
473 register elimination. See INITIAL_ELIMINATION_OFFSET. */
474 && INTVAL (operands[2])
475 < (0x7fff8000
476 - FIRST_PSEUDO_REGISTER * UNITS_PER_WORD
477 - ALPHA_ROUND(crtl->outgoing_args_size)
478 - (ALPHA_ROUND (get_frame_size ()
479 + max_reg_num () * UNITS_PER_WORD
480 + crtl->args.pretend_args_size)
481 - crtl->args.pretend_args_size))"
482 "@
483 lda %0,%2(%1)
484 ldah %0,%h2(%1)
485 #")
486
487 ;; Don't do this if we are adjusting SP since we don't want to do it
488 ;; in two steps. Don't split FP sources for the reason listed above.
489 (define_split
490 [(set (match_operand:DI 0 "register_operand")
491 (plus:DI (match_operand:DI 1 "register_operand")
492 (match_operand:DI 2 "const_int_operand")))]
493 "! add_operand (operands[2], DImode)
494 && operands[0] != stack_pointer_rtx
495 && operands[1] != frame_pointer_rtx
496 && operands[1] != arg_pointer_rtx"
497 [(set (match_dup 0) (plus:DI (match_dup 1) (match_dup 3)))
498 (set (match_dup 0) (plus:DI (match_dup 0) (match_dup 4)))]
499 {
500 HOST_WIDE_INT val = INTVAL (operands[2]);
501 HOST_WIDE_INT low = (val & 0xffff) - 2 * (val & 0x8000);
502 HOST_WIDE_INT rest = val - low;
503 rtx rest_rtx = GEN_INT (rest);
504
505 operands[4] = GEN_INT (low);
506 if (satisfies_constraint_L (rest_rtx))
507 operands[3] = rest_rtx;
508 else if (can_create_pseudo_p ())
509 {
510 operands[3] = gen_reg_rtx (DImode);
511 emit_move_insn (operands[3], operands[2]);
512 emit_insn (gen_adddi3 (operands[0], operands[1], operands[3]));
513 DONE;
514 }
515 else
516 FAIL;
517 })
518
519 (define_insn "*sadd<modesuffix>"
520 [(set (match_operand:I48MODE 0 "register_operand" "=r,r")
521 (plus:I48MODE
522 (mult:I48MODE (match_operand:I48MODE 1 "reg_not_elim_operand" "r,r")
523 (match_operand:I48MODE 2 "const48_operand" "I,I"))
524 (match_operand:I48MODE 3 "sext_add_operand" "rI,O")))]
525 ""
526 "@
527 s%2add<modesuffix> %1,%3,%0
528 s%2sub<modesuffix> %1,%n3,%0")
529
530 (define_insn "*saddl_se"
531 [(set (match_operand:DI 0 "register_operand" "=r,r")
532 (sign_extend:DI
533 (plus:SI (mult:SI (match_operand:SI 1 "reg_not_elim_operand" "r,r")
534 (match_operand:SI 2 "const48_operand" "I,I"))
535 (match_operand:SI 3 "sext_add_operand" "rI,O"))))]
536 ""
537 "@
538 s%2addl %1,%3,%0
539 s%2subl %1,%n3,%0")
540
541 (define_split
542 [(set (match_operand:DI 0 "register_operand")
543 (sign_extend:DI
544 (plus:SI (mult:SI (match_operator:SI 1 "comparison_operator"
545 [(match_operand 2)
546 (match_operand 3)])
547 (match_operand:SI 4 "const48_operand"))
548 (match_operand:SI 5 "sext_add_operand"))))
549 (clobber (match_operand:DI 6 "reg_not_elim_operand"))]
550 ""
551 [(set (match_dup 6) (match_dup 7))
552 (set (match_dup 0)
553 (sign_extend:DI (plus:SI (mult:SI (match_dup 8) (match_dup 4))
554 (match_dup 5))))]
555 {
556 operands[7] = gen_rtx_fmt_ee (GET_CODE (operands[1]), DImode,
557 operands[2], operands[3]);
558 operands[8] = gen_lowpart (SImode, operands[6]);
559 })
560
561 (define_insn "addv<mode>3"
562 [(set (match_operand:I48MODE 0 "register_operand" "=r,r")
563 (plus:I48MODE (match_operand:I48MODE 1 "reg_or_0_operand" "%rJ,rJ")
564 (match_operand:I48MODE 2 "sext_add_operand" "rI,O")))
565 (trap_if (ne (plus:<DWI> (sign_extend:<DWI> (match_dup 1))
566 (sign_extend:<DWI> (match_dup 2)))
567 (sign_extend:<DWI> (plus:I48MODE (match_dup 1)
568 (match_dup 2))))
569 (const_int 0))]
570 ""
571 "@
572 add<modesuffix>v %r1,%2,%0
573 sub<modesuffix>v %r1,%n2,%0")
574
575 (define_insn "neg<mode>2"
576 [(set (match_operand:I48MODE 0 "register_operand" "=r")
577 (neg:I48MODE (match_operand:I48MODE 1 "reg_or_8bit_operand" "rI")))]
578 ""
579 "sub<modesuffix> $31,%1,%0")
580
581 (define_insn "*negsi_se"
582 [(set (match_operand:DI 0 "register_operand" "=r")
583 (sign_extend:DI (neg:SI
584 (match_operand:SI 1 "reg_or_8bit_operand" "rI"))))]
585 ""
586 "subl $31,%1,%0")
587
588 (define_insn "negv<mode>2"
589 [(set (match_operand:I48MODE 0 "register_operand" "=r")
590 (neg:I48MODE (match_operand:I48MODE 1 "register_operand" "r")))
591 (trap_if (ne (neg:<DWI> (sign_extend:<DWI> (match_dup 1)))
592 (sign_extend:<DWI> (neg:I48MODE (match_dup 1))))
593 (const_int 0))]
594 ""
595 "sub<modesuffix>v $31,%1,%0")
596
597 (define_insn "sub<mode>3"
598 [(set (match_operand:I48MODE 0 "register_operand" "=r")
599 (minus:I48MODE (match_operand:I48MODE 1 "reg_or_0_operand" "rJ")
600 (match_operand:I48MODE 2 "reg_or_8bit_operand" "rI")))]
601 ""
602 "sub<modesuffix> %r1,%2,%0")
603
604 (define_insn "*subsi_se"
605 [(set (match_operand:DI 0 "register_operand" "=r")
606 (sign_extend:DI
607 (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rJ")
608 (match_operand:SI 2 "reg_or_8bit_operand" "rI"))))]
609 ""
610 "subl %r1,%2,%0")
611
612 (define_insn "*subsi_se2"
613 [(set (match_operand:DI 0 "register_operand" "=r")
614 (sign_extend:DI
615 (subreg:SI (minus:DI (match_operand:DI 1 "reg_or_0_operand" "rJ")
616 (match_operand:DI 2 "reg_or_8bit_operand" "rI"))
617 0)))]
618 ""
619 "subl %r1,%2,%0")
620
621 (define_insn "*ssub<modesuffix>"
622 [(set (match_operand:I48MODE 0 "register_operand" "=r")
623 (minus:I48MODE
624 (mult:I48MODE (match_operand:I48MODE 1 "reg_not_elim_operand" "r")
625 (match_operand:I48MODE 2 "const48_operand" "I"))
626 (match_operand:I48MODE 3 "reg_or_8bit_operand" "rI")))]
627 ""
628 "s%2sub<modesuffix> %1,%3,%0")
629
630 (define_insn "*ssubl_se"
631 [(set (match_operand:DI 0 "register_operand" "=r")
632 (sign_extend:DI
633 (minus:SI (mult:SI (match_operand:SI 1 "reg_not_elim_operand" "r")
634 (match_operand:SI 2 "const48_operand" "I"))
635 (match_operand:SI 3 "reg_or_8bit_operand" "rI"))))]
636 ""
637 "s%2subl %1,%3,%0")
638
639 (define_insn "subv<mode>3"
640 [(set (match_operand:I48MODE 0 "register_operand" "=r")
641 (minus:I48MODE (match_operand:I48MODE 1 "reg_or_0_operand" "rJ")
642 (match_operand:I48MODE 2 "reg_or_8bit_operand" "rI")))
643 (trap_if (ne (minus:<DWI> (sign_extend:<DWI> (match_dup 1))
644 (sign_extend:<DWI> (match_dup 2)))
645 (sign_extend:<DWI> (minus:I48MODE (match_dup 1)
646 (match_dup 2))))
647 (const_int 0))]
648 ""
649 "sub<modesuffix>v %r1,%2,%0")
650
651 (define_insn "mul<mode>3"
652 [(set (match_operand:I48MODE 0 "register_operand" "=r")
653 (mult:I48MODE (match_operand:I48MODE 1 "reg_or_0_operand" "%rJ")
654 (match_operand:I48MODE 2 "reg_or_8bit_operand" "rI")))]
655 ""
656 "mul<modesuffix> %r1,%2,%0"
657 [(set_attr "type" "imul")
658 (set_attr "opsize" "<mode>")])
659
660 (define_insn "*mulsi_se"
661 [(set (match_operand:DI 0 "register_operand" "=r")
662 (sign_extend:DI
663 (mult:SI (match_operand:SI 1 "reg_or_0_operand" "%rJ")
664 (match_operand:SI 2 "reg_or_8bit_operand" "rI"))))]
665 ""
666 "mull %r1,%2,%0"
667 [(set_attr "type" "imul")
668 (set_attr "opsize" "si")])
669
670 (define_insn "mulv<mode>3"
671 [(set (match_operand:I48MODE 0 "register_operand" "=r")
672 (mult:I48MODE (match_operand:I48MODE 1 "reg_or_0_operand" "%rJ")
673 (match_operand:I48MODE 2 "reg_or_8bit_operand" "rI")))
674 (trap_if (ne (mult:<DWI> (sign_extend:<DWI> (match_dup 1))
675 (sign_extend:<DWI> (match_dup 2)))
676 (sign_extend:<DWI> (mult:I48MODE (match_dup 1)
677 (match_dup 2))))
678 (const_int 0))]
679 ""
680 "mul<modesuffix>v %r1,%2,%0"
681 [(set_attr "type" "imul")
682 (set_attr "opsize" "<mode>")])
683
684 (define_expand "umuldi3_highpart"
685 [(set (match_operand:DI 0 "register_operand")
686 (truncate:DI
687 (lshiftrt:TI
688 (mult:TI (zero_extend:TI
689 (match_operand:DI 1 "register_operand"))
690 (match_operand:DI 2 "reg_or_8bit_operand"))
691 (const_int 64))))]
692 ""
693 {
694 if (REG_P (operands[2]))
695 operands[2] = gen_rtx_ZERO_EXTEND (TImode, operands[2]);
696 })
697
698 (define_insn "*umuldi3_highpart_reg"
699 [(set (match_operand:DI 0 "register_operand" "=r")
700 (truncate:DI
701 (lshiftrt:TI
702 (mult:TI (zero_extend:TI
703 (match_operand:DI 1 "register_operand" "r"))
704 (zero_extend:TI
705 (match_operand:DI 2 "register_operand" "r")))
706 (const_int 64))))]
707 ""
708 "umulh %1,%2,%0"
709 [(set_attr "type" "imul")
710 (set_attr "opsize" "udi")])
711
712 (define_insn "*umuldi3_highpart_const"
713 [(set (match_operand:DI 0 "register_operand" "=r")
714 (truncate:DI
715 (lshiftrt:TI
716 (mult:TI (zero_extend:TI (match_operand:DI 1 "register_operand" "r"))
717 (match_operand:TI 2 "cint8_operand" "I"))
718 (const_int 64))))]
719 ""
720 "umulh %1,%2,%0"
721 [(set_attr "type" "imul")
722 (set_attr "opsize" "udi")])
723
724 (define_expand "umulditi3"
725 [(set (match_operand:TI 0 "register_operand")
726 (mult:TI
727 (zero_extend:TI (match_operand:DI 1 "reg_no_subreg_operand"))
728 (zero_extend:TI (match_operand:DI 2 "reg_no_subreg_operand"))))]
729 ""
730 {
731 rtx l = gen_reg_rtx (DImode), h = gen_reg_rtx (DImode);
732 emit_insn (gen_muldi3 (l, operands[1], operands[2]));
733 emit_insn (gen_umuldi3_highpart (h, operands[1], operands[2]));
734 emit_move_insn (gen_lowpart (DImode, operands[0]), l);
735 emit_move_insn (gen_highpart (DImode, operands[0]), h);
736 DONE;
737 })
738 \f
739 ;; The divide and remainder operations take their inputs from r24 and
740 ;; r25, put their output in r27, and clobber r23 and r28 on all systems.
741 ;;
742 ;; ??? Force sign-extension here because some versions of OSF/1 and
743 ;; Interix/NT don't do the right thing if the inputs are not properly
744 ;; sign-extended. But Linux, for instance, does not have this
745 ;; problem. Is it worth the complication here to eliminate the sign
746 ;; extension?
747
748 (define_code_iterator any_divmod [div mod udiv umod])
749
750 (define_expand "<code>si3"
751 [(set (match_dup 3)
752 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand")))
753 (set (match_dup 4)
754 (sign_extend:DI (match_operand:SI 2 "nonimmediate_operand")))
755 (parallel [(set (match_dup 5)
756 (sign_extend:DI
757 (any_divmod:SI (match_dup 3) (match_dup 4))))
758 (clobber (reg:DI 23))
759 (clobber (reg:DI 28))])
760 (set (match_operand:SI 0 "nonimmediate_operand")
761 (subreg:SI (match_dup 5) 0))]
762 "TARGET_ABI_OSF"
763 {
764 operands[3] = gen_reg_rtx (DImode);
765 operands[4] = gen_reg_rtx (DImode);
766 operands[5] = gen_reg_rtx (DImode);
767 })
768
769 (define_expand "<code>di3"
770 [(parallel [(set (match_operand:DI 0 "register_operand")
771 (any_divmod:DI
772 (match_operand:DI 1 "register_operand")
773 (match_operand:DI 2 "register_operand")))
774 (clobber (reg:DI 23))
775 (clobber (reg:DI 28))])]
776 "TARGET_ABI_OSF")
777
778 ;; Lengths of 8 for ldq $t12,__divq($gp); jsr $t9,($t12),__divq as
779 ;; expanded by the assembler.
780
781 (define_insn_and_split "*divmodsi_internal_er"
782 [(set (match_operand:DI 0 "register_operand" "=c")
783 (sign_extend:DI (match_operator:SI 3 "divmod_operator"
784 [(match_operand:DI 1 "register_operand" "a")
785 (match_operand:DI 2 "register_operand" "b")])))
786 (clobber (reg:DI 23))
787 (clobber (reg:DI 28))]
788 "TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF"
789 "#"
790 "&& reload_completed"
791 [(parallel [(set (match_dup 0)
792 (sign_extend:DI (match_dup 3)))
793 (use (match_dup 0))
794 (use (match_dup 4))
795 (clobber (reg:DI 23))
796 (clobber (reg:DI 28))])]
797 {
798 const char *str;
799 switch (GET_CODE (operands[3]))
800 {
801 case DIV:
802 str = "__divl";
803 break;
804 case UDIV:
805 str = "__divlu";
806 break;
807 case MOD:
808 str = "__reml";
809 break;
810 case UMOD:
811 str = "__remlu";
812 break;
813 default:
814 gcc_unreachable ();
815 }
816 operands[4] = GEN_INT (alpha_next_sequence_number++);
817 emit_insn (gen_movdi_er_high_g (operands[0], pic_offset_table_rtx,
818 gen_rtx_SYMBOL_REF (DImode, str),
819 operands[4]));
820 }
821 [(set_attr "type" "jsr")
822 (set_attr "length" "8")])
823
824 (define_insn "*divmodsi_internal_er_1"
825 [(set (match_operand:DI 0 "register_operand" "=c")
826 (sign_extend:DI (match_operator:SI 3 "divmod_operator"
827 [(match_operand:DI 1 "register_operand" "a")
828 (match_operand:DI 2 "register_operand" "b")])))
829 (use (match_operand:DI 4 "register_operand" "c"))
830 (use (match_operand 5 "const_int_operand"))
831 (clobber (reg:DI 23))
832 (clobber (reg:DI 28))]
833 "TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF"
834 "jsr $23,($27),__%E3%j5"
835 [(set_attr "type" "jsr")
836 (set_attr "length" "4")])
837
838 (define_insn "*divmodsi_internal"
839 [(set (match_operand:DI 0 "register_operand" "=c")
840 (sign_extend:DI (match_operator:SI 3 "divmod_operator"
841 [(match_operand:DI 1 "register_operand" "a")
842 (match_operand:DI 2 "register_operand" "b")])))
843 (clobber (reg:DI 23))
844 (clobber (reg:DI 28))]
845 "TARGET_ABI_OSF"
846 "%E3 %1,%2,%0"
847 [(set_attr "type" "jsr")
848 (set_attr "length" "8")])
849
850 (define_insn_and_split "*divmoddi_internal_er"
851 [(set (match_operand:DI 0 "register_operand" "=c")
852 (match_operator:DI 3 "divmod_operator"
853 [(match_operand:DI 1 "register_operand" "a")
854 (match_operand:DI 2 "register_operand" "b")]))
855 (clobber (reg:DI 23))
856 (clobber (reg:DI 28))]
857 "TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF"
858 "#"
859 "&& reload_completed"
860 [(parallel [(set (match_dup 0) (match_dup 3))
861 (use (match_dup 0))
862 (use (match_dup 4))
863 (clobber (reg:DI 23))
864 (clobber (reg:DI 28))])]
865 {
866 const char *str;
867 switch (GET_CODE (operands[3]))
868 {
869 case DIV:
870 str = "__divq";
871 break;
872 case UDIV:
873 str = "__divqu";
874 break;
875 case MOD:
876 str = "__remq";
877 break;
878 case UMOD:
879 str = "__remqu";
880 break;
881 default:
882 gcc_unreachable ();
883 }
884 operands[4] = GEN_INT (alpha_next_sequence_number++);
885 emit_insn (gen_movdi_er_high_g (operands[0], pic_offset_table_rtx,
886 gen_rtx_SYMBOL_REF (DImode, str),
887 operands[4]));
888 }
889 [(set_attr "type" "jsr")
890 (set_attr "length" "8")])
891
892 (define_insn "*divmoddi_internal_er_1"
893 [(set (match_operand:DI 0 "register_operand" "=c")
894 (match_operator:DI 3 "divmod_operator"
895 [(match_operand:DI 1 "register_operand" "a")
896 (match_operand:DI 2 "register_operand" "b")]))
897 (use (match_operand:DI 4 "register_operand" "c"))
898 (use (match_operand 5 "const_int_operand"))
899 (clobber (reg:DI 23))
900 (clobber (reg:DI 28))]
901 "TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF"
902 "jsr $23,($27),__%E3%j5"
903 [(set_attr "type" "jsr")
904 (set_attr "length" "4")])
905
906 (define_insn "*divmoddi_internal"
907 [(set (match_operand:DI 0 "register_operand" "=c")
908 (match_operator:DI 3 "divmod_operator"
909 [(match_operand:DI 1 "register_operand" "a")
910 (match_operand:DI 2 "register_operand" "b")]))
911 (clobber (reg:DI 23))
912 (clobber (reg:DI 28))]
913 "TARGET_ABI_OSF"
914 "%E3 %1,%2,%0"
915 [(set_attr "type" "jsr")
916 (set_attr "length" "8")])
917 \f
918 ;; Next are the basic logical operations. We only expose the DImode operations
919 ;; to the rtl expanders, but SImode versions exist for combine as well as for
920 ;; the atomic operation splitters.
921
922 (define_insn "*andsi_internal"
923 [(set (match_operand:SI 0 "register_operand" "=r,r,r")
924 (and:SI (match_operand:SI 1 "reg_or_0_operand" "%rJ,rJ,rJ")
925 (match_operand:SI 2 "and_operand" "rI,N,M")))]
926 ""
927 "@
928 and %r1,%2,%0
929 bic %r1,%N2,%0
930 zapnot %r1,%m2,%0"
931 [(set_attr "type" "ilog,ilog,shift")])
932
933 (define_insn "anddi3"
934 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
935 (and:DI (match_operand:DI 1 "reg_or_0_operand" "%rJ,rJ,rJ")
936 (match_operand:DI 2 "and_operand" "rI,N,M")))]
937 ""
938 "@
939 and %r1,%2,%0
940 bic %r1,%N2,%0
941 zapnot %r1,%m2,%0"
942 [(set_attr "type" "ilog,ilog,shift")])
943
944 ;; There are times when we can split an AND into two AND insns. This occurs
945 ;; when we can first clear any bytes and then clear anything else. For
946 ;; example "I & 0xffff07" is "(I & 0xffffff) & 0xffffffffffffff07".
947 ;; Only do this when running on 64-bit host since the computations are
948 ;; too messy otherwise.
949
950 (define_split
951 [(set (match_operand:DI 0 "register_operand")
952 (and:DI (match_operand:DI 1 "register_operand")
953 (match_operand:DI 2 "const_int_operand")))]
954 "! and_operand (operands[2], DImode)"
955 [(set (match_dup 0) (and:DI (match_dup 1) (match_dup 3)))
956 (set (match_dup 0) (and:DI (match_dup 0) (match_dup 4)))]
957 {
958 unsigned HOST_WIDE_INT mask1 = INTVAL (operands[2]);
959 unsigned HOST_WIDE_INT mask2 = mask1;
960 int i;
961
962 /* For each byte that isn't all zeros, make it all ones. */
963 for (i = 0; i < 64; i += 8)
964 if ((mask1 & ((HOST_WIDE_INT) 0xff << i)) != 0)
965 mask1 |= (HOST_WIDE_INT) 0xff << i;
966
967 /* Now turn on any bits we've just turned off. */
968 mask2 |= ~ mask1;
969
970 operands[3] = GEN_INT (mask1);
971 operands[4] = GEN_INT (mask2);
972 })
973
974 (define_insn "zero_extendqi<mode>2"
975 [(set (match_operand:I248MODE 0 "register_operand" "=r,r")
976 (zero_extend:I248MODE
977 (match_operand:QI 1 "reg_or_bwx_memory_operand" "r,m")))]
978 ""
979 "@
980 and %1,0xff,%0
981 ldbu %0,%1"
982 [(set_attr "type" "ilog,ild")
983 (set_attr "isa" "*,bwx")])
984
985 (define_insn "zero_extendhi<mode>2"
986 [(set (match_operand:I48MODE 0 "register_operand" "=r,r")
987 (zero_extend:I48MODE
988 (match_operand:HI 1 "reg_or_bwx_memory_operand" "r,m")))]
989 ""
990 "@
991 zapnot %1,3,%0
992 ldwu %0,%1"
993 [(set_attr "type" "shift,ild")
994 (set_attr "isa" "*,bwx")])
995
996 (define_insn "zero_extendsidi2"
997 [(set (match_operand:DI 0 "register_operand" "=r")
998 (zero_extend:DI (match_operand:SI 1 "register_operand" "r")))]
999 ""
1000 "zapnot %1,15,%0"
1001 [(set_attr "type" "shift")])
1002
1003 (define_insn "andnot<mode>3"
1004 [(set (match_operand:I48MODE 0 "register_operand" "=r")
1005 (and:I48MODE
1006 (not:I48MODE (match_operand:I48MODE 1 "reg_or_8bit_operand" "rI"))
1007 (match_operand:I48MODE 2 "reg_or_0_operand" "rJ")))]
1008 ""
1009 "bic %r2,%1,%0"
1010 [(set_attr "type" "ilog")])
1011
1012 (define_insn "*iorsi_internal"
1013 [(set (match_operand:SI 0 "register_operand" "=r,r")
1014 (ior:SI (match_operand:SI 1 "reg_or_0_operand" "%rJ,rJ")
1015 (match_operand:SI 2 "or_operand" "rI,N")))]
1016 ""
1017 "@
1018 bis %r1,%2,%0
1019 ornot %r1,%N2,%0"
1020 [(set_attr "type" "ilog")])
1021
1022 (define_insn "iordi3"
1023 [(set (match_operand:DI 0 "register_operand" "=r,r")
1024 (ior:DI (match_operand:DI 1 "reg_or_0_operand" "%rJ,rJ")
1025 (match_operand:DI 2 "or_operand" "rI,N")))]
1026 ""
1027 "@
1028 bis %r1,%2,%0
1029 ornot %r1,%N2,%0"
1030 [(set_attr "type" "ilog")])
1031
1032 (define_insn "*one_cmplsi_internal"
1033 [(set (match_operand:SI 0 "register_operand" "=r")
1034 (not:SI (match_operand:SI 1 "reg_or_8bit_operand" "rI")))]
1035 ""
1036 "ornot $31,%1,%0"
1037 [(set_attr "type" "ilog")])
1038
1039 (define_insn "one_cmpldi2"
1040 [(set (match_operand:DI 0 "register_operand" "=r")
1041 (not:DI (match_operand:DI 1 "reg_or_8bit_operand" "rI")))]
1042 ""
1043 "ornot $31,%1,%0"
1044 [(set_attr "type" "ilog")])
1045
1046 (define_insn "*iornot<mode>3"
1047 [(set (match_operand:I48MODE 0 "register_operand" "=r")
1048 (ior:I48MODE
1049 (not:I48MODE (match_operand:I48MODE 1 "reg_or_8bit_operand" "rI"))
1050 (match_operand:I48MODE 2 "reg_or_0_operand" "rJ")))]
1051 ""
1052 "ornot %r2,%1,%0"
1053 [(set_attr "type" "ilog")])
1054
1055 (define_insn "*xorsi_internal"
1056 [(set (match_operand:SI 0 "register_operand" "=r,r")
1057 (xor:SI (match_operand:SI 1 "reg_or_0_operand" "%rJ,rJ")
1058 (match_operand:SI 2 "or_operand" "rI,N")))]
1059 ""
1060 "@
1061 xor %r1,%2,%0
1062 eqv %r1,%N2,%0"
1063 [(set_attr "type" "ilog")])
1064
1065 (define_insn "xordi3"
1066 [(set (match_operand:DI 0 "register_operand" "=r,r")
1067 (xor:DI (match_operand:DI 1 "reg_or_0_operand" "%rJ,rJ")
1068 (match_operand:DI 2 "or_operand" "rI,N")))]
1069 ""
1070 "@
1071 xor %r1,%2,%0
1072 eqv %r1,%N2,%0"
1073 [(set_attr "type" "ilog")])
1074
1075 (define_insn "*xornot<mode>3"
1076 [(set (match_operand:I48MODE 0 "register_operand" "=r")
1077 (not:I48MODE (xor:I48MODE
1078 (match_operand:I48MODE 1 "register_operand" "%rJ")
1079 (match_operand:I48MODE 2 "register_operand" "rI"))))]
1080 ""
1081 "eqv %r1,%2,%0"
1082 [(set_attr "type" "ilog")])
1083 \f
1084 ;; Handle FFS and related insns iff we support CIX.
1085
1086 (define_expand "ffsdi2"
1087 [(set (match_dup 2)
1088 (ctz:DI (match_operand:DI 1 "register_operand")))
1089 (set (match_dup 3)
1090 (plus:DI (match_dup 2) (const_int 1)))
1091 (set (match_operand:DI 0 "register_operand")
1092 (if_then_else:DI (eq (match_dup 1) (const_int 0))
1093 (const_int 0) (match_dup 3)))]
1094 "TARGET_CIX"
1095 {
1096 operands[2] = gen_reg_rtx (DImode);
1097 operands[3] = gen_reg_rtx (DImode);
1098 })
1099
1100 (define_insn "clzdi2"
1101 [(set (match_operand:DI 0 "register_operand" "=r")
1102 (clz:DI (match_operand:DI 1 "register_operand" "r")))]
1103 "TARGET_CIX"
1104 "ctlz %1,%0"
1105 [(set_attr "type" "mvi")])
1106
1107 (define_insn "ctzdi2"
1108 [(set (match_operand:DI 0 "register_operand" "=r")
1109 (ctz:DI (match_operand:DI 1 "register_operand" "r")))]
1110 "TARGET_CIX"
1111 "cttz %1,%0"
1112 [(set_attr "type" "mvi")])
1113
1114 (define_insn "popcountdi2"
1115 [(set (match_operand:DI 0 "register_operand" "=r")
1116 (popcount:DI (match_operand:DI 1 "register_operand" "r")))]
1117 "TARGET_CIX"
1118 "ctpop %1,%0"
1119 [(set_attr "type" "mvi")])
1120
1121 (define_expand "bswapsi2"
1122 [(set (match_operand:SI 0 "register_operand")
1123 (bswap:SI (match_operand:SI 1 "register_operand")))]
1124 "!optimize_size"
1125 {
1126 rtx t0, t1;
1127
1128 t0 = gen_reg_rtx (DImode);
1129 t1 = gen_reg_rtx (DImode);
1130
1131 emit_insn (gen_inslh (t0, gen_lowpart (DImode, operands[1]), GEN_INT (7)));
1132 emit_insn (gen_inswl_const (t1, gen_lowpart (HImode, operands[1]),
1133 GEN_INT (24)));
1134 emit_insn (gen_iordi3 (t1, t0, t1));
1135 emit_insn (gen_lshrdi3 (t0, t1, GEN_INT (16)));
1136 emit_insn (gen_anddi3 (t1, t1, alpha_expand_zap_mask (0x5)));
1137 emit_insn (gen_anddi3 (t0, t0, alpha_expand_zap_mask (0xa)));
1138 emit_insn (gen_addsi3 (operands[0], gen_lowpart (SImode, t0),
1139 gen_lowpart (SImode, t1)));
1140 DONE;
1141 })
1142
1143 (define_expand "bswapdi2"
1144 [(set (match_operand:DI 0 "register_operand")
1145 (bswap:DI (match_operand:DI 1 "register_operand")))]
1146 "!optimize_size"
1147 {
1148 rtx t0, t1;
1149
1150 t0 = gen_reg_rtx (DImode);
1151 t1 = gen_reg_rtx (DImode);
1152
1153 /* This method of shifting and masking is not specific to Alpha, but
1154 is only profitable on Alpha because of our handy byte zap insn. */
1155
1156 emit_insn (gen_lshrdi3 (t0, operands[1], GEN_INT (32)));
1157 emit_insn (gen_ashldi3 (t1, operands[1], GEN_INT (32)));
1158 emit_insn (gen_iordi3 (t1, t0, t1));
1159
1160 emit_insn (gen_lshrdi3 (t0, t1, GEN_INT (16)));
1161 emit_insn (gen_ashldi3 (t1, t1, GEN_INT (16)));
1162 emit_insn (gen_anddi3 (t0, t0, alpha_expand_zap_mask (0xcc)));
1163 emit_insn (gen_anddi3 (t1, t1, alpha_expand_zap_mask (0x33)));
1164 emit_insn (gen_iordi3 (t1, t0, t1));
1165
1166 emit_insn (gen_lshrdi3 (t0, t1, GEN_INT (8)));
1167 emit_insn (gen_ashldi3 (t1, t1, GEN_INT (8)));
1168 emit_insn (gen_anddi3 (t0, t0, alpha_expand_zap_mask (0xaa)));
1169 emit_insn (gen_anddi3 (t1, t1, alpha_expand_zap_mask (0x55)));
1170 emit_insn (gen_iordi3 (operands[0], t0, t1));
1171 DONE;
1172 })
1173 \f
1174 ;; Next come the shifts and the various extract and insert operations.
1175
1176 (define_insn "ashldi3"
1177 [(set (match_operand:DI 0 "register_operand" "=r,r")
1178 (ashift:DI (match_operand:DI 1 "reg_or_0_operand" "rJ,rJ")
1179 (match_operand:DI 2 "reg_or_6bit_operand" "P,rS")))]
1180 ""
1181 {
1182 switch (which_alternative)
1183 {
1184 case 0:
1185 if (operands[2] == const1_rtx)
1186 return "addq %r1,%r1,%0";
1187 else
1188 return "s%P2addq %r1,0,%0";
1189 case 1:
1190 return "sll %r1,%2,%0";
1191 default:
1192 gcc_unreachable ();
1193 }
1194 }
1195 [(set_attr "type" "iadd,shift")])
1196
1197 (define_insn "*ashldi_se"
1198 [(set (match_operand:DI 0 "register_operand" "=r")
1199 (sign_extend:DI
1200 (subreg:SI (ashift:DI (match_operand:DI 1 "reg_or_0_operand" "rJ")
1201 (match_operand:DI 2 "const_int_operand" "P"))
1202 0)))]
1203 "INTVAL (operands[2]) >= 1 && INTVAL (operands[2]) <= 3"
1204 {
1205 if (operands[2] == const1_rtx)
1206 return "addl %r1,%r1,%0";
1207 else
1208 return "s%P2addl %r1,0,%0";
1209 }
1210 [(set_attr "type" "iadd")])
1211
1212 (define_insn "lshrdi3"
1213 [(set (match_operand:DI 0 "register_operand" "=r")
1214 (lshiftrt:DI (match_operand:DI 1 "reg_or_0_operand" "rJ")
1215 (match_operand:DI 2 "reg_or_6bit_operand" "rS")))]
1216 ""
1217 "srl %r1,%2,%0"
1218 [(set_attr "type" "shift")])
1219
1220 (define_insn "ashrdi3"
1221 [(set (match_operand:DI 0 "register_operand" "=r")
1222 (ashiftrt:DI (match_operand:DI 1 "reg_or_0_operand" "rJ")
1223 (match_operand:DI 2 "reg_or_6bit_operand" "rS")))]
1224 ""
1225 "sra %r1,%2,%0"
1226 [(set_attr "type" "shift")])
1227
1228 (define_insn "extendqi<mode>2"
1229 [(set (match_operand:I24MODE 0 "register_operand" "=r")
1230 (sign_extend:I24MODE
1231 (match_operand:QI 1 "register_operand" "r")))]
1232 "TARGET_BWX"
1233 "sextb %1,%0"
1234 [(set_attr "type" "shift")])
1235
1236 (define_expand "extendqidi2"
1237 [(set (match_operand:DI 0 "register_operand")
1238 (sign_extend:DI (match_operand:QI 1 "general_operand")))]
1239 ""
1240 {
1241 if (TARGET_BWX)
1242 operands[1] = force_reg (QImode, operands[1]);
1243 else
1244 {
1245 rtx x, t1, t2, i56;
1246
1247 if (unaligned_memory_operand (operands[1], QImode))
1248 {
1249 x = gen_unaligned_extendqidi (operands[0], XEXP (operands[1], 0));
1250 alpha_set_memflags (x, operands[1]);
1251 emit_insn (x);
1252 DONE;
1253 }
1254
1255 t1 = gen_reg_rtx (DImode);
1256 t2 = gen_reg_rtx (DImode);
1257 i56 = GEN_INT (56);
1258
1259 x = gen_lowpart (DImode, force_reg (QImode, operands[1]));
1260 emit_move_insn (t1, x);
1261 emit_insn (gen_ashldi3 (t2, t1, i56));
1262 emit_insn (gen_ashrdi3 (operands[0], t2, i56));
1263 DONE;
1264 }
1265 })
1266
1267 (define_insn "*extendqidi2_bwx"
1268 [(set (match_operand:DI 0 "register_operand" "=r")
1269 (sign_extend:DI (match_operand:QI 1 "register_operand" "r")))]
1270 "TARGET_BWX"
1271 "sextb %1,%0"
1272 [(set_attr "type" "shift")])
1273
1274 (define_insn "extendhisi2"
1275 [(set (match_operand:SI 0 "register_operand" "=r")
1276 (sign_extend:SI (match_operand:HI 1 "register_operand" "r")))]
1277 "TARGET_BWX"
1278 "sextw %1,%0"
1279 [(set_attr "type" "shift")])
1280
1281 (define_expand "extendhidi2"
1282 [(set (match_operand:DI 0 "register_operand")
1283 (sign_extend:DI (match_operand:HI 1 "general_operand")))]
1284 ""
1285 {
1286 if (TARGET_BWX)
1287 operands[1] = force_reg (HImode, operands[1]);
1288 else
1289 {
1290 rtx x, t1, t2, i48;
1291
1292 if (unaligned_memory_operand (operands[1], HImode))
1293 {
1294 x = gen_unaligned_extendhidi (operands[0], XEXP (operands[1], 0));
1295 alpha_set_memflags (x, operands[1]);
1296 emit_insn (x);
1297 DONE;
1298 }
1299
1300 t1 = gen_reg_rtx (DImode);
1301 t2 = gen_reg_rtx (DImode);
1302 i48 = GEN_INT (48);
1303
1304 x = gen_lowpart (DImode, force_reg (HImode, operands[1]));
1305 emit_move_insn (t1, x);
1306 emit_insn (gen_ashldi3 (t2, t1, i48));
1307 emit_insn (gen_ashrdi3 (operands[0], t2, i48));
1308 DONE;
1309 }
1310 })
1311
1312 (define_insn "*extendhidi2_bwx"
1313 [(set (match_operand:DI 0 "register_operand" "=r")
1314 (sign_extend:DI (match_operand:HI 1 "register_operand" "r")))]
1315 "TARGET_BWX"
1316 "sextw %1,%0"
1317 [(set_attr "type" "shift")])
1318
1319 ;; Here's how we sign extend an unaligned byte and halfword. Doing this
1320 ;; as a pattern saves one instruction. The code is similar to that for
1321 ;; the unaligned loads (see below).
1322 ;;
1323 ;; Operand 1 is the address, operand 0 is the result.
1324
1325 (define_expand "unaligned_extendqidi"
1326 [(set (match_dup 3)
1327 (mem:DI (and:DI (match_operand:DI 1 "address_operand") (const_int -8))))
1328 (set (match_dup 4)
1329 (ashift:DI (match_dup 3)
1330 (minus:DI (const_int 64)
1331 (ashift:DI
1332 (and:DI (match_dup 2) (const_int 7))
1333 (const_int 3)))))
1334 (set (match_operand:QI 0 "register_operand")
1335 (ashiftrt:DI (match_dup 4) (const_int 56)))]
1336 ""
1337 {
1338 operands[0] = gen_lowpart (DImode, operands[0]);
1339 operands[2] = get_unaligned_offset (operands[1], 1);
1340 operands[3] = gen_reg_rtx (DImode);
1341 operands[4] = gen_reg_rtx (DImode);
1342 })
1343
1344 (define_expand "unaligned_extendhidi"
1345 [(set (match_dup 3)
1346 (mem:DI (and:DI (match_operand:DI 1 "address_operand") (const_int -8))))
1347 (set (match_dup 4)
1348 (ashift:DI (match_dup 3)
1349 (minus:DI (const_int 64)
1350 (ashift:DI
1351 (and:DI (match_dup 2) (const_int 7))
1352 (const_int 3)))))
1353 (set (match_operand:HI 0 "register_operand")
1354 (ashiftrt:DI (match_dup 4) (const_int 48)))]
1355 ""
1356 {
1357 operands[0] = gen_lowpart (DImode, operands[0]);
1358 operands[2] = get_unaligned_offset (operands[1], 2);
1359 operands[3] = gen_reg_rtx (DImode);
1360 operands[4] = gen_reg_rtx (DImode);
1361 })
1362
1363 (define_insn "*extxl_const"
1364 [(set (match_operand:DI 0 "register_operand" "=r")
1365 (zero_extract:DI (match_operand:DI 1 "reg_or_0_operand" "rJ")
1366 (match_operand:DI 2 "mode_width_operand" "n")
1367 (match_operand:DI 3 "mul8_operand" "I")))]
1368 ""
1369 "ext%M2l %r1,%s3,%0"
1370 [(set_attr "type" "shift")])
1371
1372 (define_insn "extxl"
1373 [(set (match_operand:DI 0 "register_operand" "=r")
1374 (zero_extract:DI
1375 (match_operand:DI 1 "reg_or_0_operand" "rJ")
1376 (match_operand:DI 2 "mode_width_operand" "n")
1377 (ashift:DI (match_operand:DI 3 "reg_or_8bit_operand" "rI")
1378 (const_int 3))))]
1379 ""
1380 "ext%M2l %r1,%3,%0"
1381 [(set_attr "type" "shift")])
1382
1383 ;; Combine has some strange notion of preserving existing undefined behavior
1384 ;; in shifts larger than a word size. So capture these patterns that it
1385 ;; should have turned into zero_extracts.
1386
1387 (define_insn "*extxl_1"
1388 [(set (match_operand:DI 0 "register_operand" "=r")
1389 (and:DI (lshiftrt:DI (match_operand:DI 1 "reg_or_0_operand" "rJ")
1390 (ashift:DI (match_operand:DI 2 "reg_or_8bit_operand" "rI")
1391 (const_int 3)))
1392 (match_operand:DI 3 "mode_mask_operand" "n")))]
1393 ""
1394 "ext%U3l %1,%2,%0"
1395 [(set_attr "type" "shift")])
1396
1397 (define_insn "*extql_2"
1398 [(set (match_operand:DI 0 "register_operand" "=r")
1399 (lshiftrt:DI (match_operand:DI 1 "reg_or_0_operand" "rJ")
1400 (ashift:DI (match_operand:DI 2 "reg_or_8bit_operand" "rI")
1401 (const_int 3))))]
1402 ""
1403 "extql %1,%2,%0"
1404 [(set_attr "type" "shift")])
1405
1406 (define_insn "extqh"
1407 [(set (match_operand:DI 0 "register_operand" "=r")
1408 (ashift:DI
1409 (match_operand:DI 1 "reg_or_0_operand" "rJ")
1410 (minus:DI (const_int 64)
1411 (ashift:DI
1412 (and:DI
1413 (match_operand:DI 2 "reg_or_8bit_operand" "rI")
1414 (const_int 7))
1415 (const_int 3)))))]
1416 ""
1417 "extqh %r1,%2,%0"
1418 [(set_attr "type" "shift")])
1419
1420 (define_insn "extwh"
1421 [(set (match_operand:DI 0 "register_operand" "=r")
1422 (ashift:DI
1423 (and:DI (match_operand:DI 1 "reg_or_0_operand" "rJ")
1424 (const_int 65535))
1425 (minus:DI (const_int 64)
1426 (ashift:DI
1427 (and:DI
1428 (match_operand:DI 2 "reg_or_8bit_operand" "rI")
1429 (const_int 7))
1430 (const_int 3)))))]
1431 ""
1432 "extwh %r1,%2,%0"
1433 [(set_attr "type" "shift")])
1434
1435 (define_insn "extlh"
1436 [(set (match_operand:DI 0 "register_operand" "=r")
1437 (ashift:DI
1438 (and:DI (match_operand:DI 1 "reg_or_0_operand" "rJ")
1439 (const_int 2147483647))
1440 (minus:DI (const_int 64)
1441 (ashift:DI
1442 (and:DI
1443 (match_operand:DI 2 "reg_or_8bit_operand" "rI")
1444 (const_int 7))
1445 (const_int 3)))))]
1446 ""
1447 "extlh %r1,%2,%0"
1448 [(set_attr "type" "shift")])
1449
1450 ;; This converts an extXl into an extXh with an appropriate adjustment
1451 ;; to the address calculation.
1452
1453 ;;(define_split
1454 ;; [(set (match_operand:DI 0 "register_operand")
1455 ;; (ashift:DI (zero_extract:DI (match_operand:DI 1 "register_operand")
1456 ;; (match_operand:DI 2 "mode_width_operand")
1457 ;; (ashift:DI (match_operand:DI 3)
1458 ;; (const_int 3)))
1459 ;; (match_operand:DI 4 "const_int_operand")))
1460 ;; (clobber (match_operand:DI 5 "register_operand"))]
1461 ;; "INTVAL (operands[4]) == 64 - INTVAL (operands[2])"
1462 ;; [(set (match_dup 5) (match_dup 6))
1463 ;; (set (match_dup 0)
1464 ;; (ashift:DI (zero_extract:DI (match_dup 1) (match_dup 2)
1465 ;; (ashift:DI (plus:DI (match_dup 5)
1466 ;; (match_dup 7))
1467 ;; (const_int 3)))
1468 ;; (match_dup 4)))]
1469 ;; "
1470 ;;{
1471 ;; operands[6] = plus_constant (DImode, operands[3],
1472 ;; INTVAL (operands[2]) / BITS_PER_UNIT);
1473 ;; operands[7] = GEN_INT (- INTVAL (operands[2]) / BITS_PER_UNIT);
1474 ;;}")
1475
1476 (define_insn "ins<modesuffix>l_const"
1477 [(set (match_operand:DI 0 "register_operand" "=r")
1478 (ashift:DI (zero_extend:DI
1479 (match_operand:I124MODE 1 "register_operand" "r"))
1480 (match_operand:DI 2 "mul8_operand" "I")))]
1481 ""
1482 "ins<modesuffix>l %1,%s2,%0"
1483 [(set_attr "type" "shift")])
1484
1485 (define_insn "ins<modesuffix>l"
1486 [(set (match_operand:DI 0 "register_operand" "=r")
1487 (ashift:DI (zero_extend:DI
1488 (match_operand:I124MODE 1 "register_operand" "r"))
1489 (ashift:DI (match_operand:DI 2 "reg_or_8bit_operand" "rI")
1490 (const_int 3))))]
1491 ""
1492 "ins<modesuffix>l %1,%2,%0"
1493 [(set_attr "type" "shift")])
1494
1495 (define_insn "insql"
1496 [(set (match_operand:DI 0 "register_operand" "=r")
1497 (ashift:DI (match_operand:DI 1 "register_operand" "r")
1498 (ashift:DI (match_operand:DI 2 "reg_or_8bit_operand" "rI")
1499 (const_int 3))))]
1500 ""
1501 "insql %1,%2,%0"
1502 [(set_attr "type" "shift")])
1503
1504 ;; Combine has this sometimes habit of moving the and outside of the
1505 ;; shift, making life more interesting.
1506
1507 (define_insn "*insxl"
1508 [(set (match_operand:DI 0 "register_operand" "=r")
1509 (and:DI (ashift:DI (match_operand:DI 1 "register_operand" "r")
1510 (match_operand:DI 2 "mul8_operand" "I"))
1511 (match_operand:DI 3 "const_int_operand" "i")))]
1512 "((unsigned HOST_WIDE_INT) 0xff << INTVAL (operands[2])
1513 == (unsigned HOST_WIDE_INT) INTVAL (operands[3]))
1514 || ((unsigned HOST_WIDE_INT) 0xffff << INTVAL (operands[2])
1515 == (unsigned HOST_WIDE_INT) INTVAL (operands[3]))
1516 || ((unsigned HOST_WIDE_INT) 0xffffffff << INTVAL (operands[2])
1517 == (unsigned HOST_WIDE_INT) INTVAL (operands[3]))"
1518 {
1519 if ((unsigned HOST_WIDE_INT) 0xff << INTVAL (operands[2])
1520 == (unsigned HOST_WIDE_INT) INTVAL (operands[3]))
1521 return "insbl %1,%s2,%0";
1522 if ((unsigned HOST_WIDE_INT) 0xffff << INTVAL (operands[2])
1523 == (unsigned HOST_WIDE_INT) INTVAL (operands[3]))
1524 return "inswl %1,%s2,%0";
1525 if ((unsigned HOST_WIDE_INT) 0xffffffff << INTVAL (operands[2])
1526 == (unsigned HOST_WIDE_INT) INTVAL (operands[3]))
1527 return "insll %1,%s2,%0";
1528
1529 gcc_unreachable ();
1530 }
1531 [(set_attr "type" "shift")])
1532
1533 ;; We do not include the insXh insns because they are complex to express
1534 ;; and it does not appear that we would ever want to generate them.
1535 ;;
1536 ;; Since we need them for block moves, though, cop out and use unspec.
1537
1538 (define_insn "insxh"
1539 [(set (match_operand:DI 0 "register_operand" "=r")
1540 (unspec:DI [(match_operand:DI 1 "register_operand" "r")
1541 (match_operand:DI 2 "mode_width_operand" "n")
1542 (match_operand:DI 3 "reg_or_8bit_operand" "rI")]
1543 UNSPEC_INSXH))]
1544 ""
1545 "ins%M2h %1,%3,%0"
1546 [(set_attr "type" "shift")])
1547
1548 (define_insn "mskxl"
1549 [(set (match_operand:DI 0 "register_operand" "=r")
1550 (and:DI (not:DI (ashift:DI
1551 (match_operand:DI 2 "mode_mask_operand" "n")
1552 (ashift:DI
1553 (match_operand:DI 3 "reg_or_8bit_operand" "rI")
1554 (const_int 3))))
1555 (match_operand:DI 1 "reg_or_0_operand" "rJ")))]
1556 ""
1557 "msk%U2l %r1,%3,%0"
1558 [(set_attr "type" "shift")])
1559
1560 ;; We do not include the mskXh insns because it does not appear we would
1561 ;; ever generate one.
1562 ;;
1563 ;; Again, we do for block moves and we use unspec again.
1564
1565 (define_insn "mskxh"
1566 [(set (match_operand:DI 0 "register_operand" "=r")
1567 (unspec:DI [(match_operand:DI 1 "register_operand" "r")
1568 (match_operand:DI 2 "mode_width_operand" "n")
1569 (match_operand:DI 3 "reg_or_8bit_operand" "rI")]
1570 UNSPEC_MSKXH))]
1571 ""
1572 "msk%M2h %1,%3,%0"
1573 [(set_attr "type" "shift")])
1574
1575 ;; Prefer AND + NE over LSHIFTRT + AND.
1576
1577 (define_insn_and_split "*ze_and_ne"
1578 [(set (match_operand:DI 0 "register_operand" "=r")
1579 (zero_extract:DI (match_operand:DI 1 "reg_or_0_operand" "rJ")
1580 (const_int 1)
1581 (match_operand 2 "const_int_operand" "I")))]
1582 "(unsigned HOST_WIDE_INT) INTVAL (operands[2]) < 8"
1583 "#"
1584 "(unsigned HOST_WIDE_INT) INTVAL (operands[2]) < 8"
1585 [(set (match_dup 0)
1586 (and:DI (match_dup 1) (match_dup 3)))
1587 (set (match_dup 0)
1588 (ne:DI (match_dup 0) (const_int 0)))]
1589 "operands[3] = GEN_INT (1 << INTVAL (operands[2]));")
1590 \f
1591 ;; Floating-point operations. All the double-precision insns can extend
1592 ;; from single, so indicate that. The exception are the ones that simply
1593 ;; play with the sign bits; it's not clear what to do there.
1594
1595 (define_mode_iterator FMODE [SF DF])
1596
1597 (define_mode_attr opmode [(SF "si") (DF "di")])
1598
1599 (define_insn "abs<mode>2"
1600 [(set (match_operand:FMODE 0 "register_operand" "=f")
1601 (abs:FMODE (match_operand:FMODE 1 "reg_or_0_operand" "fG")))]
1602 "TARGET_FP"
1603 "cpys $f31,%R1,%0"
1604 [(set_attr "type" "fcpys")])
1605
1606 (define_insn "*nabs<mode>2"
1607 [(set (match_operand:FMODE 0 "register_operand" "=f")
1608 (neg:FMODE
1609 (abs:FMODE (match_operand:FMODE 1 "reg_or_0_operand" "fG"))))]
1610 "TARGET_FP"
1611 "cpysn $f31,%R1,%0"
1612 [(set_attr "type" "fadd")])
1613
1614 (define_expand "abstf2"
1615 [(parallel [(set (match_operand:TF 0 "register_operand")
1616 (abs:TF (match_operand:TF 1 "reg_or_0_operand")))
1617 (use (match_dup 2))])]
1618 "TARGET_HAS_XFLOATING_LIBS"
1619 "operands[2] = force_reg (DImode, GEN_INT (HOST_WIDE_INT_1U << 63));")
1620
1621 (define_insn_and_split "*abstf_internal"
1622 [(set (match_operand:TF 0 "register_operand" "=r")
1623 (abs:TF (match_operand:TF 1 "reg_or_0_operand" "rG")))
1624 (use (match_operand:DI 2 "register_operand" "r"))]
1625 "TARGET_HAS_XFLOATING_LIBS"
1626 "#"
1627 "&& reload_completed"
1628 [(const_int 0)]
1629 "alpha_split_tfmode_frobsign (operands, gen_andnotdi3); DONE;")
1630
1631 (define_insn "neg<mode>2"
1632 [(set (match_operand:FMODE 0 "register_operand" "=f")
1633 (neg:FMODE (match_operand:FMODE 1 "reg_or_0_operand" "fG")))]
1634 "TARGET_FP"
1635 "cpysn %R1,%R1,%0"
1636 [(set_attr "type" "fadd")])
1637
1638 (define_expand "negtf2"
1639 [(parallel [(set (match_operand:TF 0 "register_operand")
1640 (neg:TF (match_operand:TF 1 "reg_or_0_operand")))
1641 (use (match_dup 2))])]
1642 "TARGET_HAS_XFLOATING_LIBS"
1643 "operands[2] = force_reg (DImode, GEN_INT (HOST_WIDE_INT_1U << 63));")
1644
1645 (define_insn_and_split "*negtf_internal"
1646 [(set (match_operand:TF 0 "register_operand" "=r")
1647 (neg:TF (match_operand:TF 1 "reg_or_0_operand" "rG")))
1648 (use (match_operand:DI 2 "register_operand" "r"))]
1649 "TARGET_HAS_XFLOATING_LIBS"
1650 "#"
1651 "&& reload_completed"
1652 [(const_int 0)]
1653 "alpha_split_tfmode_frobsign (operands, gen_xordi3); DONE;")
1654
1655 (define_insn "copysign<mode>3"
1656 [(set (match_operand:FMODE 0 "register_operand" "=f")
1657 (unspec:FMODE [(match_operand:FMODE 1 "reg_or_0_operand" "fG")
1658 (match_operand:FMODE 2 "reg_or_0_operand" "fG")]
1659 UNSPEC_COPYSIGN))]
1660 "TARGET_FP"
1661 "cpys %R2,%R1,%0"
1662 [(set_attr "type" "fadd")])
1663
1664 (define_insn "*ncopysign<mode>3"
1665 [(set (match_operand:FMODE 0 "register_operand" "=f")
1666 (neg:FMODE
1667 (unspec:FMODE [(match_operand:FMODE 1 "reg_or_0_operand" "fG")
1668 (match_operand:FMODE 2 "reg_or_0_operand" "fG")]
1669 UNSPEC_COPYSIGN)))]
1670 "TARGET_FP"
1671 "cpysn %R2,%R1,%0"
1672 [(set_attr "type" "fadd")])
1673
1674 (define_insn "*add<mode>3_ieee"
1675 [(set (match_operand:FMODE 0 "register_operand" "=&f")
1676 (plus:FMODE (match_operand:FMODE 1 "reg_or_0_operand" "%fG")
1677 (match_operand:FMODE 2 "reg_or_0_operand" "fG")))]
1678 "TARGET_FP && alpha_fptm >= ALPHA_FPTM_SU"
1679 "add<modesuffix>%/ %R1,%R2,%0"
1680 [(set_attr "type" "fadd")
1681 (set_attr "trap" "yes")
1682 (set_attr "round_suffix" "normal")
1683 (set_attr "trap_suffix" "u_su_sui")])
1684
1685 (define_insn "add<mode>3"
1686 [(set (match_operand:FMODE 0 "register_operand" "=f")
1687 (plus:FMODE (match_operand:FMODE 1 "reg_or_0_operand" "%fG")
1688 (match_operand:FMODE 2 "reg_or_0_operand" "fG")))]
1689 "TARGET_FP"
1690 "add<modesuffix>%/ %R1,%R2,%0"
1691 [(set_attr "type" "fadd")
1692 (set_attr "trap" "yes")
1693 (set_attr "round_suffix" "normal")
1694 (set_attr "trap_suffix" "u_su_sui")])
1695
1696 (define_insn "*adddf_ext1"
1697 [(set (match_operand:DF 0 "register_operand" "=f")
1698 (plus:DF (float_extend:DF
1699 (match_operand:SF 1 "reg_or_0_operand" "fG"))
1700 (match_operand:DF 2 "reg_or_0_operand" "fG")))]
1701 "TARGET_FP && alpha_fptm < ALPHA_FPTM_SU"
1702 "add%-%/ %R1,%R2,%0"
1703 [(set_attr "type" "fadd")
1704 (set_attr "trap" "yes")
1705 (set_attr "round_suffix" "normal")
1706 (set_attr "trap_suffix" "u_su_sui")])
1707
1708 (define_insn "*adddf_ext2"
1709 [(set (match_operand:DF 0 "register_operand" "=f")
1710 (plus:DF (float_extend:DF
1711 (match_operand:SF 1 "reg_or_0_operand" "%fG"))
1712 (float_extend:DF
1713 (match_operand:SF 2 "reg_or_0_operand" "fG"))))]
1714 "TARGET_FP && alpha_fptm < ALPHA_FPTM_SU"
1715 "add%-%/ %R1,%R2,%0"
1716 [(set_attr "type" "fadd")
1717 (set_attr "trap" "yes")
1718 (set_attr "round_suffix" "normal")
1719 (set_attr "trap_suffix" "u_su_sui")])
1720
1721 (define_expand "addtf3"
1722 [(use (match_operand:TF 0 "register_operand"))
1723 (use (match_operand:TF 1 "general_operand"))
1724 (use (match_operand:TF 2 "general_operand"))]
1725 "TARGET_HAS_XFLOATING_LIBS"
1726 "alpha_emit_xfloating_arith (PLUS, operands); DONE;")
1727
1728 (define_insn "*sub<mode>3_ieee"
1729 [(set (match_operand:FMODE 0 "register_operand" "=&f")
1730 (minus:FMODE (match_operand:FMODE 1 "reg_or_0_operand" "fG")
1731 (match_operand:FMODE 2 "reg_or_0_operand" "fG")))]
1732 "TARGET_FP && alpha_fptm >= ALPHA_FPTM_SU"
1733 "sub<modesuffix>%/ %R1,%R2,%0"
1734 [(set_attr "type" "fadd")
1735 (set_attr "trap" "yes")
1736 (set_attr "round_suffix" "normal")
1737 (set_attr "trap_suffix" "u_su_sui")])
1738
1739 (define_insn "sub<mode>3"
1740 [(set (match_operand:FMODE 0 "register_operand" "=f")
1741 (minus:FMODE (match_operand:FMODE 1 "reg_or_0_operand" "fG")
1742 (match_operand:FMODE 2 "reg_or_0_operand" "fG")))]
1743 "TARGET_FP"
1744 "sub<modesuffix>%/ %R1,%R2,%0"
1745 [(set_attr "type" "fadd")
1746 (set_attr "trap" "yes")
1747 (set_attr "round_suffix" "normal")
1748 (set_attr "trap_suffix" "u_su_sui")])
1749
1750 (define_insn "*subdf_ext1"
1751 [(set (match_operand:DF 0 "register_operand" "=f")
1752 (minus:DF (float_extend:DF
1753 (match_operand:SF 1 "reg_or_0_operand" "fG"))
1754 (match_operand:DF 2 "reg_or_0_operand" "fG")))]
1755 "TARGET_FP && alpha_fptm < ALPHA_FPTM_SU"
1756 "sub%-%/ %R1,%R2,%0"
1757 [(set_attr "type" "fadd")
1758 (set_attr "trap" "yes")
1759 (set_attr "round_suffix" "normal")
1760 (set_attr "trap_suffix" "u_su_sui")])
1761
1762 (define_insn "*subdf_ext2"
1763 [(set (match_operand:DF 0 "register_operand" "=f")
1764 (minus:DF (match_operand:DF 1 "reg_or_0_operand" "fG")
1765 (float_extend:DF
1766 (match_operand:SF 2 "reg_or_0_operand" "fG"))))]
1767 "TARGET_FP && alpha_fptm < ALPHA_FPTM_SU"
1768 "sub%-%/ %R1,%R2,%0"
1769 [(set_attr "type" "fadd")
1770 (set_attr "trap" "yes")
1771 (set_attr "round_suffix" "normal")
1772 (set_attr "trap_suffix" "u_su_sui")])
1773
1774 (define_insn "*subdf_ext3"
1775 [(set (match_operand:DF 0 "register_operand" "=f")
1776 (minus:DF (float_extend:DF
1777 (match_operand:SF 1 "reg_or_0_operand" "fG"))
1778 (float_extend:DF
1779 (match_operand:SF 2 "reg_or_0_operand" "fG"))))]
1780 "TARGET_FP && alpha_fptm < ALPHA_FPTM_SU"
1781 "sub%-%/ %R1,%R2,%0"
1782 [(set_attr "type" "fadd")
1783 (set_attr "trap" "yes")
1784 (set_attr "round_suffix" "normal")
1785 (set_attr "trap_suffix" "u_su_sui")])
1786
1787 (define_expand "subtf3"
1788 [(use (match_operand:TF 0 "register_operand"))
1789 (use (match_operand:TF 1 "general_operand"))
1790 (use (match_operand:TF 2 "general_operand"))]
1791 "TARGET_HAS_XFLOATING_LIBS"
1792 "alpha_emit_xfloating_arith (MINUS, operands); DONE;")
1793
1794 (define_insn "*mul<mode>3_ieee"
1795 [(set (match_operand:FMODE 0 "register_operand" "=&f")
1796 (mult:FMODE (match_operand:FMODE 1 "reg_or_0_operand" "%fG")
1797 (match_operand:FMODE 2 "reg_or_0_operand" "fG")))]
1798 "TARGET_FP && alpha_fptm >= ALPHA_FPTM_SU"
1799 "mul<modesuffix>%/ %R1,%R2,%0"
1800 [(set_attr "type" "fmul")
1801 (set_attr "trap" "yes")
1802 (set_attr "round_suffix" "normal")
1803 (set_attr "trap_suffix" "u_su_sui")])
1804
1805 (define_insn "mul<mode>3"
1806 [(set (match_operand:FMODE 0 "register_operand" "=f")
1807 (mult:FMODE (match_operand:FMODE 1 "reg_or_0_operand" "%fG")
1808 (match_operand:FMODE 2 "reg_or_0_operand" "fG")))]
1809 "TARGET_FP"
1810 "mul<modesuffix>%/ %R1,%R2,%0"
1811 [(set_attr "type" "fmul")
1812 (set_attr "trap" "yes")
1813 (set_attr "round_suffix" "normal")
1814 (set_attr "trap_suffix" "u_su_sui")])
1815
1816 (define_insn "*muldf_ext1"
1817 [(set (match_operand:DF 0 "register_operand" "=f")
1818 (mult:DF (float_extend:DF
1819 (match_operand:SF 1 "reg_or_0_operand" "fG"))
1820 (match_operand:DF 2 "reg_or_0_operand" "fG")))]
1821 "TARGET_FP && alpha_fptm < ALPHA_FPTM_SU"
1822 "mul%-%/ %R1,%R2,%0"
1823 [(set_attr "type" "fmul")
1824 (set_attr "trap" "yes")
1825 (set_attr "round_suffix" "normal")
1826 (set_attr "trap_suffix" "u_su_sui")])
1827
1828 (define_insn "*muldf_ext2"
1829 [(set (match_operand:DF 0 "register_operand" "=f")
1830 (mult:DF (float_extend:DF
1831 (match_operand:SF 1 "reg_or_0_operand" "%fG"))
1832 (float_extend:DF
1833 (match_operand:SF 2 "reg_or_0_operand" "fG"))))]
1834 "TARGET_FP && alpha_fptm < ALPHA_FPTM_SU"
1835 "mul%-%/ %R1,%R2,%0"
1836 [(set_attr "type" "fmul")
1837 (set_attr "trap" "yes")
1838 (set_attr "round_suffix" "normal")
1839 (set_attr "trap_suffix" "u_su_sui")])
1840
1841 (define_expand "multf3"
1842 [(use (match_operand:TF 0 "register_operand"))
1843 (use (match_operand:TF 1 "general_operand"))
1844 (use (match_operand:TF 2 "general_operand"))]
1845 "TARGET_HAS_XFLOATING_LIBS"
1846 "alpha_emit_xfloating_arith (MULT, operands); DONE;")
1847
1848 (define_insn "*div<mode>3_ieee"
1849 [(set (match_operand:FMODE 0 "register_operand" "=&f")
1850 (div:FMODE (match_operand:FMODE 1 "reg_or_0_operand" "fG")
1851 (match_operand:FMODE 2 "reg_or_0_operand" "fG")))]
1852 "TARGET_FP && alpha_fptm >= ALPHA_FPTM_SU"
1853 "div<modesuffix>%/ %R1,%R2,%0"
1854 [(set_attr "type" "fdiv")
1855 (set_attr "opsize" "<opmode>")
1856 (set_attr "trap" "yes")
1857 (set_attr "round_suffix" "normal")
1858 (set_attr "trap_suffix" "u_su_sui")])
1859
1860 (define_insn "div<mode>3"
1861 [(set (match_operand:FMODE 0 "register_operand" "=f")
1862 (div:FMODE (match_operand:FMODE 1 "reg_or_0_operand" "fG")
1863 (match_operand:FMODE 2 "reg_or_0_operand" "fG")))]
1864 "TARGET_FP"
1865 "div<modesuffix>%/ %R1,%R2,%0"
1866 [(set_attr "type" "fdiv")
1867 (set_attr "opsize" "<opmode>")
1868 (set_attr "trap" "yes")
1869 (set_attr "round_suffix" "normal")
1870 (set_attr "trap_suffix" "u_su_sui")])
1871
1872 (define_insn "*divdf_ext1"
1873 [(set (match_operand:DF 0 "register_operand" "=f")
1874 (div:DF (float_extend:DF (match_operand:SF 1 "reg_or_0_operand" "fG"))
1875 (match_operand:DF 2 "reg_or_0_operand" "fG")))]
1876 "TARGET_FP && alpha_fptm < ALPHA_FPTM_SU"
1877 "div%-%/ %R1,%R2,%0"
1878 [(set_attr "type" "fdiv")
1879 (set_attr "trap" "yes")
1880 (set_attr "round_suffix" "normal")
1881 (set_attr "trap_suffix" "u_su_sui")])
1882
1883 (define_insn "*divdf_ext2"
1884 [(set (match_operand:DF 0 "register_operand" "=f")
1885 (div:DF (match_operand:DF 1 "reg_or_0_operand" "fG")
1886 (float_extend:DF
1887 (match_operand:SF 2 "reg_or_0_operand" "fG"))))]
1888 "TARGET_FP && alpha_fptm < ALPHA_FPTM_SU"
1889 "div%-%/ %R1,%R2,%0"
1890 [(set_attr "type" "fdiv")
1891 (set_attr "trap" "yes")
1892 (set_attr "round_suffix" "normal")
1893 (set_attr "trap_suffix" "u_su_sui")])
1894
1895 (define_insn "*divdf_ext3"
1896 [(set (match_operand:DF 0 "register_operand" "=f")
1897 (div:DF (float_extend:DF
1898 (match_operand:SF 1 "reg_or_0_operand" "fG"))
1899 (float_extend:DF
1900 (match_operand:SF 2 "reg_or_0_operand" "fG"))))]
1901 "TARGET_FP && alpha_fptm < ALPHA_FPTM_SU"
1902 "div%-%/ %R1,%R2,%0"
1903 [(set_attr "type" "fdiv")
1904 (set_attr "trap" "yes")
1905 (set_attr "round_suffix" "normal")
1906 (set_attr "trap_suffix" "u_su_sui")])
1907
1908 (define_expand "divtf3"
1909 [(use (match_operand:TF 0 "register_operand"))
1910 (use (match_operand:TF 1 "general_operand"))
1911 (use (match_operand:TF 2 "general_operand"))]
1912 "TARGET_HAS_XFLOATING_LIBS"
1913 "alpha_emit_xfloating_arith (DIV, operands); DONE;")
1914
1915 (define_insn "*sqrt<mode>2_ieee"
1916 [(set (match_operand:FMODE 0 "register_operand" "=&f")
1917 (sqrt:FMODE (match_operand:FMODE 1 "reg_or_0_operand" "fG")))]
1918 "TARGET_FP && TARGET_FIX && alpha_fptm >= ALPHA_FPTM_SU"
1919 "sqrt<modesuffix>%/ %R1,%0"
1920 [(set_attr "type" "fsqrt")
1921 (set_attr "opsize" "<opmode>")
1922 (set_attr "trap" "yes")
1923 (set_attr "round_suffix" "normal")
1924 (set_attr "trap_suffix" "u_su_sui")])
1925
1926 (define_insn "sqrt<mode>2"
1927 [(set (match_operand:FMODE 0 "register_operand" "=f")
1928 (sqrt:FMODE (match_operand:FMODE 1 "reg_or_0_operand" "fG")))]
1929 "TARGET_FP && TARGET_FIX"
1930 "sqrt<modesuffix>%/ %R1,%0"
1931 [(set_attr "type" "fsqrt")
1932 (set_attr "opsize" "<opmode>")
1933 (set_attr "trap" "yes")
1934 (set_attr "round_suffix" "normal")
1935 (set_attr "trap_suffix" "u_su_sui")])
1936
1937 ;; Define conversion operators between DFmode and SImode, using the cvtql
1938 ;; instruction. To allow combine et al to do useful things, we keep the
1939 ;; operation as a unit until after reload, at which point we split the
1940 ;; instructions.
1941 ;;
1942 ;; Note that we (attempt to) only consider this optimization when the
1943 ;; ultimate destination is memory. If we will be doing further integer
1944 ;; processing, it is cheaper to do the truncation in the int regs.
1945
1946 (define_insn "*cvtql"
1947 [(set (match_operand:SF 0 "register_operand" "=f")
1948 (unspec:SF [(match_operand:DI 1 "reg_or_0_operand" "fG")]
1949 UNSPEC_CVTQL))]
1950 "TARGET_FP"
1951 "cvtql%/ %R1,%0"
1952 [(set_attr "type" "fadd")
1953 (set_attr "trap" "yes")
1954 (set_attr "trap_suffix" "v_sv")])
1955
1956 (define_insn_and_split "*fix_truncdfsi_ieee"
1957 [(set (match_operand:SI 0 "memory_operand" "=m")
1958 (subreg:SI
1959 (match_operator:DI 4 "fix_operator"
1960 [(match_operand:DF 1 "reg_or_0_operand" "fG")]) 0))
1961 (clobber (match_scratch:DI 2 "=&f"))
1962 (clobber (match_scratch:SF 3 "=&f"))]
1963 "TARGET_FP && alpha_fptm >= ALPHA_FPTM_SU"
1964 "#"
1965 "&& reload_completed"
1966 [(set (match_dup 2) (match_op_dup 4 [(match_dup 1)]))
1967 (set (match_dup 3) (unspec:SF [(match_dup 2)] UNSPEC_CVTQL))
1968 (set (match_dup 5) (match_dup 3))]
1969 {
1970 operands[5] = adjust_address (operands[0], SFmode, 0);
1971 }
1972 [(set_attr "type" "fadd")
1973 (set_attr "trap" "yes")])
1974
1975 (define_insn_and_split "*fix_truncdfsi_internal"
1976 [(set (match_operand:SI 0 "memory_operand" "=m")
1977 (subreg:SI
1978 (match_operator:DI 3 "fix_operator"
1979 [(match_operand:DF 1 "reg_or_0_operand" "fG")]) 0))
1980 (clobber (match_scratch:DI 2 "=f"))]
1981 "TARGET_FP && alpha_fptm < ALPHA_FPTM_SU"
1982 "#"
1983 "&& reload_completed"
1984 [(set (match_dup 2) (match_op_dup 3 [(match_dup 1)]))
1985 (set (match_dup 4) (unspec:SF [(match_dup 2)] UNSPEC_CVTQL))
1986 (set (match_dup 5) (match_dup 4))]
1987 {
1988 operands[4] = gen_rtx_REG (SFmode, REGNO (operands[2]));
1989 operands[5] = adjust_address (operands[0], SFmode, 0);
1990 }
1991 [(set_attr "type" "fadd")
1992 (set_attr "trap" "yes")])
1993
1994 (define_insn "*fix_truncdfdi_ieee"
1995 [(set (match_operand:DI 0 "reg_no_subreg_operand" "=&f")
1996 (match_operator:DI 2 "fix_operator"
1997 [(match_operand:DF 1 "reg_or_0_operand" "fG")]))]
1998 "TARGET_FP && alpha_fptm >= ALPHA_FPTM_SU"
1999 "cvt%-q%/ %R1,%0"
2000 [(set_attr "type" "fadd")
2001 (set_attr "trap" "yes")
2002 (set_attr "round_suffix" "c")
2003 (set_attr "trap_suffix" "v_sv_svi")])
2004
2005 (define_insn "*fix_truncdfdi2"
2006 [(set (match_operand:DI 0 "reg_no_subreg_operand" "=f")
2007 (match_operator:DI 2 "fix_operator"
2008 [(match_operand:DF 1 "reg_or_0_operand" "fG")]))]
2009 "TARGET_FP"
2010 "cvt%-q%/ %R1,%0"
2011 [(set_attr "type" "fadd")
2012 (set_attr "trap" "yes")
2013 (set_attr "round_suffix" "c")
2014 (set_attr "trap_suffix" "v_sv_svi")])
2015
2016 (define_expand "fix_truncdfdi2"
2017 [(set (match_operand:DI 0 "reg_no_subreg_operand")
2018 (fix:DI (match_operand:DF 1 "reg_or_0_operand")))]
2019 "TARGET_FP")
2020
2021 (define_expand "fixuns_truncdfdi2"
2022 [(set (match_operand:DI 0 "reg_no_subreg_operand")
2023 (unsigned_fix:DI (match_operand:DF 1 "reg_or_0_operand")))]
2024 "TARGET_FP")
2025
2026 ;; Likewise between SFmode and SImode.
2027
2028 (define_insn_and_split "*fix_truncsfsi_ieee"
2029 [(set (match_operand:SI 0 "memory_operand" "=m")
2030 (subreg:SI
2031 (match_operator:DI 4 "fix_operator"
2032 [(float_extend:DF
2033 (match_operand:SF 1 "reg_or_0_operand" "fG"))]) 0))
2034 (clobber (match_scratch:DI 2 "=&f"))
2035 (clobber (match_scratch:SF 3 "=&f"))]
2036 "TARGET_FP && alpha_fptm >= ALPHA_FPTM_SU"
2037 "#"
2038 "&& reload_completed"
2039 [(set (match_dup 2) (match_op_dup 4 [(float_extend:DF (match_dup 1))]))
2040 (set (match_dup 3) (unspec:SF [(match_dup 2)] UNSPEC_CVTQL))
2041 (set (match_dup 5) (match_dup 3))]
2042 "operands[5] = adjust_address (operands[0], SFmode, 0);"
2043 [(set_attr "type" "fadd")
2044 (set_attr "trap" "yes")])
2045
2046 (define_insn_and_split "*fix_truncsfsi_internal"
2047 [(set (match_operand:SI 0 "memory_operand" "=m")
2048 (subreg:SI
2049 (match_operator:DI 3 "fix_operator"
2050 [(float_extend:DF
2051 (match_operand:SF 1 "reg_or_0_operand" "fG"))]) 0))
2052 (clobber (match_scratch:DI 2 "=f"))]
2053 "TARGET_FP && alpha_fptm < ALPHA_FPTM_SU"
2054 "#"
2055 "&& reload_completed"
2056 [(set (match_dup 2) (match_op_dup 3 [(float_extend:DF (match_dup 1))]))
2057 (set (match_dup 4) (unspec:SF [(match_dup 2)] UNSPEC_CVTQL))
2058 (set (match_dup 5) (match_dup 4))]
2059 {
2060 operands[4] = gen_rtx_REG (SFmode, REGNO (operands[2]));
2061 operands[5] = adjust_address (operands[0], SFmode, 0);
2062 }
2063 [(set_attr "type" "fadd")
2064 (set_attr "trap" "yes")])
2065
2066 (define_insn "*fix_truncsfdi_ieee"
2067 [(set (match_operand:DI 0 "reg_no_subreg_operand" "=&f")
2068 (match_operator:DI 2 "fix_operator"
2069 [(float_extend:DF (match_operand:SF 1 "reg_or_0_operand" "fG"))]))]
2070 "TARGET_FP && alpha_fptm >= ALPHA_FPTM_SU"
2071 "cvt%-q%/ %R1,%0"
2072 [(set_attr "type" "fadd")
2073 (set_attr "trap" "yes")
2074 (set_attr "round_suffix" "c")
2075 (set_attr "trap_suffix" "v_sv_svi")])
2076
2077 (define_insn "*fix_truncsfdi2"
2078 [(set (match_operand:DI 0 "reg_no_subreg_operand" "=f")
2079 (match_operator:DI 2 "fix_operator"
2080 [(float_extend:DF (match_operand:SF 1 "reg_or_0_operand" "fG"))]))]
2081 "TARGET_FP"
2082 "cvt%-q%/ %R1,%0"
2083 [(set_attr "type" "fadd")
2084 (set_attr "trap" "yes")
2085 (set_attr "round_suffix" "c")
2086 (set_attr "trap_suffix" "v_sv_svi")])
2087
2088 (define_expand "fix_truncsfdi2"
2089 [(set (match_operand:DI 0 "reg_no_subreg_operand")
2090 (fix:DI (float_extend:DF (match_operand:SF 1 "reg_or_0_operand"))))]
2091 "TARGET_FP")
2092
2093 (define_expand "fixuns_truncsfdi2"
2094 [(set (match_operand:DI 0 "reg_no_subreg_operand")
2095 (unsigned_fix:DI
2096 (float_extend:DF (match_operand:SF 1 "reg_or_0_operand"))))]
2097 "TARGET_FP")
2098
2099 (define_expand "fix_trunctfdi2"
2100 [(use (match_operand:DI 0 "register_operand"))
2101 (use (match_operand:TF 1 "general_operand"))]
2102 "TARGET_HAS_XFLOATING_LIBS"
2103 "alpha_emit_xfloating_cvt (FIX, operands); DONE;")
2104
2105 (define_expand "fixuns_trunctfdi2"
2106 [(use (match_operand:DI 0 "register_operand"))
2107 (use (match_operand:TF 1 "general_operand"))]
2108 "TARGET_HAS_XFLOATING_LIBS"
2109 "alpha_emit_xfloating_cvt (UNSIGNED_FIX, operands); DONE;")
2110
2111 (define_insn "*floatdisf_ieee"
2112 [(set (match_operand:SF 0 "register_operand" "=&f")
2113 (float:SF (match_operand:DI 1 "reg_no_subreg_operand" "f")))]
2114 "TARGET_FP && alpha_fptm >= ALPHA_FPTM_SU"
2115 "cvtq%,%/ %1,%0"
2116 [(set_attr "type" "fadd")
2117 (set_attr "trap" "yes")
2118 (set_attr "round_suffix" "normal")
2119 (set_attr "trap_suffix" "sui")])
2120
2121 (define_insn "floatdisf2"
2122 [(set (match_operand:SF 0 "register_operand" "=f")
2123 (float:SF (match_operand:DI 1 "reg_no_subreg_operand" "f")))]
2124 "TARGET_FP"
2125 "cvtq%,%/ %1,%0"
2126 [(set_attr "type" "fadd")
2127 (set_attr "trap" "yes")
2128 (set_attr "round_suffix" "normal")
2129 (set_attr "trap_suffix" "sui")])
2130
2131 (define_insn_and_split "*floatsisf2_ieee"
2132 [(set (match_operand:SF 0 "register_operand" "=&f")
2133 (float:SF (match_operand:SI 1 "memory_operand" "m")))
2134 (clobber (match_scratch:DI 2 "=&f"))
2135 (clobber (match_scratch:SF 3 "=&f"))]
2136 "TARGET_FP && alpha_fptm >= ALPHA_FPTM_SU"
2137 "#"
2138 "&& reload_completed"
2139 [(set (match_dup 3) (match_dup 1))
2140 (set (match_dup 2) (unspec:DI [(match_dup 3)] UNSPEC_CVTLQ))
2141 (set (match_dup 0) (float:SF (match_dup 2)))]
2142 "operands[1] = adjust_address (operands[1], SFmode, 0);")
2143
2144 (define_insn_and_split "*floatsisf2"
2145 [(set (match_operand:SF 0 "register_operand" "=f")
2146 (float:SF (match_operand:SI 1 "memory_operand" "m")))]
2147 "TARGET_FP"
2148 "#"
2149 "&& reload_completed"
2150 [(set (match_dup 0) (match_dup 1))
2151 (set (match_dup 2) (unspec:DI [(match_dup 0)] UNSPEC_CVTLQ))
2152 (set (match_dup 0) (float:SF (match_dup 2)))]
2153 {
2154 operands[1] = adjust_address (operands[1], SFmode, 0);
2155 operands[2] = gen_rtx_REG (DImode, REGNO (operands[0]));
2156 })
2157
2158 (define_insn "*floatdidf_ieee"
2159 [(set (match_operand:DF 0 "register_operand" "=&f")
2160 (float:DF (match_operand:DI 1 "reg_no_subreg_operand" "f")))]
2161 "TARGET_FP && alpha_fptm >= ALPHA_FPTM_SU"
2162 "cvtq%-%/ %1,%0"
2163 [(set_attr "type" "fadd")
2164 (set_attr "trap" "yes")
2165 (set_attr "round_suffix" "normal")
2166 (set_attr "trap_suffix" "sui")])
2167
2168 (define_insn "floatdidf2"
2169 [(set (match_operand:DF 0 "register_operand" "=f")
2170 (float:DF (match_operand:DI 1 "reg_no_subreg_operand" "f")))]
2171 "TARGET_FP"
2172 "cvtq%-%/ %1,%0"
2173 [(set_attr "type" "fadd")
2174 (set_attr "trap" "yes")
2175 (set_attr "round_suffix" "normal")
2176 (set_attr "trap_suffix" "sui")])
2177
2178 (define_insn_and_split "*floatsidf2_ieee"
2179 [(set (match_operand:DF 0 "register_operand" "=&f")
2180 (float:DF (match_operand:SI 1 "memory_operand" "m")))
2181 (clobber (match_scratch:DI 2 "=&f"))
2182 (clobber (match_scratch:SF 3 "=&f"))]
2183 "TARGET_FP && alpha_fptm >= ALPHA_FPTM_SU"
2184 "#"
2185 "&& reload_completed"
2186 [(set (match_dup 3) (match_dup 1))
2187 (set (match_dup 2) (unspec:DI [(match_dup 3)] UNSPEC_CVTLQ))
2188 (set (match_dup 0) (float:DF (match_dup 2)))]
2189 "operands[1] = adjust_address (operands[1], SFmode, 0);")
2190
2191 (define_insn_and_split "*floatsidf2"
2192 [(set (match_operand:DF 0 "register_operand" "=f")
2193 (float:DF (match_operand:SI 1 "memory_operand" "m")))]
2194 "TARGET_FP"
2195 "#"
2196 "&& reload_completed"
2197 [(set (match_dup 3) (match_dup 1))
2198 (set (match_dup 2) (unspec:DI [(match_dup 3)] UNSPEC_CVTLQ))
2199 (set (match_dup 0) (float:DF (match_dup 2)))]
2200 {
2201 operands[1] = adjust_address (operands[1], SFmode, 0);
2202 operands[2] = gen_rtx_REG (DImode, REGNO (operands[0]));
2203 operands[3] = gen_rtx_REG (SFmode, REGNO (operands[0]));
2204 })
2205
2206 (define_expand "floatditf2"
2207 [(use (match_operand:TF 0 "register_operand"))
2208 (use (match_operand:DI 1 "general_operand"))]
2209 "TARGET_HAS_XFLOATING_LIBS"
2210 "alpha_emit_xfloating_cvt (FLOAT, operands); DONE;")
2211
2212 (define_expand "floatunsdisf2"
2213 [(use (match_operand:SF 0 "register_operand"))
2214 (use (match_operand:DI 1 "register_operand"))]
2215 "TARGET_FP"
2216 "alpha_emit_floatuns (operands); DONE;")
2217
2218 (define_expand "floatunsdidf2"
2219 [(use (match_operand:DF 0 "register_operand"))
2220 (use (match_operand:DI 1 "register_operand"))]
2221 "TARGET_FP"
2222 "alpha_emit_floatuns (operands); DONE;")
2223
2224 (define_expand "floatunsditf2"
2225 [(use (match_operand:TF 0 "register_operand"))
2226 (use (match_operand:DI 1 "general_operand"))]
2227 "TARGET_HAS_XFLOATING_LIBS"
2228 "alpha_emit_xfloating_cvt (UNSIGNED_FLOAT, operands); DONE;")
2229
2230 (define_expand "extendsfdf2"
2231 [(set (match_operand:DF 0 "register_operand")
2232 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand")))]
2233 "TARGET_FP"
2234 {
2235 if (alpha_fptm >= ALPHA_FPTM_SU)
2236 operands[1] = force_reg (SFmode, operands[1]);
2237 })
2238
2239 ;; The Unicos/Mk assembler doesn't support cvtst, but we've already
2240 ;; asserted that alpha_fptm == ALPHA_FPTM_N.
2241
2242 (define_insn "*extendsfdf2_ieee"
2243 [(set (match_operand:DF 0 "register_operand" "=&f")
2244 (float_extend:DF (match_operand:SF 1 "register_operand" "f")))]
2245 "TARGET_FP && alpha_fptm >= ALPHA_FPTM_SU"
2246 "cvtsts %1,%0"
2247 [(set_attr "type" "fadd")
2248 (set_attr "trap" "yes")])
2249
2250 (define_insn "*extendsfdf2_internal"
2251 [(set (match_operand:DF 0 "register_operand" "=f,f,m")
2252 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "f,m,f")))]
2253 "TARGET_FP && alpha_fptm < ALPHA_FPTM_SU"
2254 "@
2255 cpys %1,%1,%0
2256 ld%, %0,%1
2257 st%- %1,%0"
2258 [(set_attr "type" "fcpys,fld,fst")])
2259
2260 ;; Use register_operand for operand 1 to prevent compress_float_constant
2261 ;; from doing something silly. When optimizing we'll put things back
2262 ;; together anyway.
2263 (define_expand "extendsftf2"
2264 [(use (match_operand:TF 0 "register_operand"))
2265 (use (match_operand:SF 1 "register_operand"))]
2266 "TARGET_HAS_XFLOATING_LIBS"
2267 {
2268 rtx tmp = gen_reg_rtx (DFmode);
2269 emit_insn (gen_extendsfdf2 (tmp, operands[1]));
2270 emit_insn (gen_extenddftf2 (operands[0], tmp));
2271 DONE;
2272 })
2273
2274 (define_expand "extenddftf2"
2275 [(use (match_operand:TF 0 "register_operand"))
2276 (use (match_operand:DF 1 "register_operand"))]
2277 "TARGET_HAS_XFLOATING_LIBS"
2278 "alpha_emit_xfloating_cvt (FLOAT_EXTEND, operands); DONE;")
2279
2280 (define_insn "*truncdfsf2_ieee"
2281 [(set (match_operand:SF 0 "register_operand" "=&f")
2282 (float_truncate:SF (match_operand:DF 1 "reg_or_0_operand" "fG")))]
2283 "TARGET_FP && alpha_fptm >= ALPHA_FPTM_SU"
2284 "cvt%-%,%/ %R1,%0"
2285 [(set_attr "type" "fadd")
2286 (set_attr "trap" "yes")
2287 (set_attr "round_suffix" "normal")
2288 (set_attr "trap_suffix" "u_su_sui")])
2289
2290 (define_insn "truncdfsf2"
2291 [(set (match_operand:SF 0 "register_operand" "=f")
2292 (float_truncate:SF (match_operand:DF 1 "reg_or_0_operand" "fG")))]
2293 "TARGET_FP"
2294 "cvt%-%,%/ %R1,%0"
2295 [(set_attr "type" "fadd")
2296 (set_attr "trap" "yes")
2297 (set_attr "round_suffix" "normal")
2298 (set_attr "trap_suffix" "u_su_sui")])
2299
2300 (define_expand "trunctfdf2"
2301 [(use (match_operand:DF 0 "register_operand"))
2302 (use (match_operand:TF 1 "general_operand"))]
2303 "TARGET_HAS_XFLOATING_LIBS"
2304 "alpha_emit_xfloating_cvt (FLOAT_TRUNCATE, operands); DONE;")
2305
2306 (define_expand "trunctfsf2"
2307 [(use (match_operand:SF 0 "register_operand"))
2308 (use (match_operand:TF 1 "general_operand"))]
2309 "TARGET_FP && TARGET_HAS_XFLOATING_LIBS"
2310 {
2311 rtx tmpf, sticky, arg, lo, hi;
2312
2313 tmpf = gen_reg_rtx (DFmode);
2314 sticky = gen_reg_rtx (DImode);
2315 arg = copy_to_mode_reg (TFmode, operands[1]);
2316 lo = gen_lowpart (DImode, arg);
2317 hi = gen_highpart (DImode, arg);
2318
2319 /* Convert the low word of the TFmode value into a sticky rounding bit,
2320 then or it into the low bit of the high word. This leaves the sticky
2321 bit at bit 48 of the fraction, which is representable in DFmode,
2322 which prevents rounding error in the final conversion to SFmode. */
2323
2324 emit_insn (gen_rtx_SET (sticky, gen_rtx_NE (DImode, lo, const0_rtx)));
2325 emit_insn (gen_iordi3 (hi, hi, sticky));
2326 emit_insn (gen_trunctfdf2 (tmpf, arg));
2327 emit_insn (gen_truncdfsf2 (operands[0], tmpf));
2328 DONE;
2329 })
2330 \f
2331 ;; Next are all the integer comparisons, and conditional moves and branches
2332 ;; and some of the related define_expand's and define_split's.
2333
2334 (define_insn "*setcc_internal"
2335 [(set (match_operand 0 "register_operand" "=r")
2336 (match_operator 1 "alpha_comparison_operator"
2337 [(match_operand:DI 2 "register_operand" "r")
2338 (match_operand:DI 3 "reg_or_8bit_operand" "rI")]))]
2339 "GET_MODE_CLASS (GET_MODE (operands[0])) == MODE_INT
2340 && GET_MODE_SIZE (GET_MODE (operands[0])) <= 8
2341 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
2342 "cmp%C1 %2,%3,%0"
2343 [(set_attr "type" "icmp")])
2344
2345 ;; Yes, we can technically support reg_or_8bit_operand in operand 2,
2346 ;; but that's non-canonical rtl and allowing that causes inefficiencies
2347 ;; from cse on.
2348 (define_insn "*setcc_swapped_internal"
2349 [(set (match_operand 0 "register_operand" "=r")
2350 (match_operator 1 "alpha_swapped_comparison_operator"
2351 [(match_operand:DI 2 "register_operand" "r")
2352 (match_operand:DI 3 "reg_or_0_operand" "rJ")]))]
2353 "GET_MODE_CLASS (GET_MODE (operands[0])) == MODE_INT
2354 && GET_MODE_SIZE (GET_MODE (operands[0])) <= 8
2355 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
2356 "cmp%c1 %r3,%2,%0"
2357 [(set_attr "type" "icmp")])
2358
2359 ;; Use match_operator rather than ne directly so that we can match
2360 ;; multiple integer modes.
2361 (define_insn "*setne_internal"
2362 [(set (match_operand 0 "register_operand" "=r")
2363 (match_operator 1 "signed_comparison_operator"
2364 [(match_operand:DI 2 "register_operand" "r")
2365 (const_int 0)]))]
2366 "GET_MODE_CLASS (GET_MODE (operands[0])) == MODE_INT
2367 && GET_MODE_SIZE (GET_MODE (operands[0])) <= 8
2368 && GET_CODE (operands[1]) == NE
2369 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
2370 "cmpult $31,%2,%0"
2371 [(set_attr "type" "icmp")])
2372
2373 ;; The mode folding trick can't be used with const_int operands, since
2374 ;; reload needs to know the proper mode.
2375 ;;
2376 ;; Use add_operand instead of the more seemingly natural reg_or_8bit_operand
2377 ;; in order to create more pairs of constants. As long as we're allowing
2378 ;; two constants at the same time, and will have to reload one of them...
2379
2380 (define_insn "*mov<mode>cc_internal"
2381 [(set (match_operand:IMODE 0 "register_operand" "=r,r,r,r")
2382 (if_then_else:IMODE
2383 (match_operator 2 "signed_comparison_operator"
2384 [(match_operand:DI 3 "reg_or_0_operand" "rJ,rJ,J,J")
2385 (match_operand:DI 4 "reg_or_0_operand" "J,J,rJ,rJ")])
2386 (match_operand:IMODE 1 "add_operand" "rI,0,rI,0")
2387 (match_operand:IMODE 5 "add_operand" "0,rI,0,rI")))]
2388 "(operands[3] == const0_rtx) ^ (operands[4] == const0_rtx)"
2389 "@
2390 cmov%C2 %r3,%1,%0
2391 cmov%D2 %r3,%5,%0
2392 cmov%c2 %r4,%1,%0
2393 cmov%d2 %r4,%5,%0"
2394 [(set_attr "type" "icmov")])
2395
2396 (define_insn "*mov<mode>cc_lbc"
2397 [(set (match_operand:IMODE 0 "register_operand" "=r,r")
2398 (if_then_else:IMODE
2399 (eq (zero_extract:DI (match_operand:DI 2 "reg_or_0_operand" "rJ,rJ")
2400 (const_int 1)
2401 (const_int 0))
2402 (const_int 0))
2403 (match_operand:IMODE 1 "reg_or_8bit_operand" "rI,0")
2404 (match_operand:IMODE 3 "reg_or_8bit_operand" "0,rI")))]
2405 ""
2406 "@
2407 cmovlbc %r2,%1,%0
2408 cmovlbs %r2,%3,%0"
2409 [(set_attr "type" "icmov")])
2410
2411 (define_insn "*mov<mode>cc_lbs"
2412 [(set (match_operand:IMODE 0 "register_operand" "=r,r")
2413 (if_then_else:IMODE
2414 (ne (zero_extract:DI (match_operand:DI 2 "reg_or_0_operand" "rJ,rJ")
2415 (const_int 1)
2416 (const_int 0))
2417 (const_int 0))
2418 (match_operand:IMODE 1 "reg_or_8bit_operand" "rI,0")
2419 (match_operand:IMODE 3 "reg_or_8bit_operand" "0,rI")))]
2420 ""
2421 "@
2422 cmovlbs %r2,%1,%0
2423 cmovlbc %r2,%3,%0"
2424 [(set_attr "type" "icmov")])
2425
2426 ;; For ABS, we have two choices, depending on whether the input and output
2427 ;; registers are the same or not.
2428 (define_expand "absdi2"
2429 [(set (match_operand:DI 0 "register_operand")
2430 (abs:DI (match_operand:DI 1 "register_operand")))]
2431 ""
2432 {
2433 if (rtx_equal_p (operands[0], operands[1]))
2434 emit_insn (gen_absdi2_same (operands[0], gen_reg_rtx (DImode)));
2435 else
2436 emit_insn (gen_absdi2_diff (operands[0], operands[1]));
2437 DONE;
2438 })
2439
2440 (define_expand "absdi2_same"
2441 [(set (match_operand:DI 1 "register_operand")
2442 (neg:DI (match_operand:DI 0 "register_operand")))
2443 (set (match_dup 0)
2444 (if_then_else:DI (ge (match_dup 0) (const_int 0))
2445 (match_dup 0)
2446 (match_dup 1)))])
2447
2448 (define_expand "absdi2_diff"
2449 [(set (match_operand:DI 0 "register_operand")
2450 (neg:DI (match_operand:DI 1 "register_operand")))
2451 (set (match_dup 0)
2452 (if_then_else:DI (lt (match_dup 1) (const_int 0))
2453 (match_dup 0)
2454 (match_dup 1)))])
2455
2456 (define_split
2457 [(set (match_operand:DI 0 "register_operand")
2458 (abs:DI (match_dup 0)))
2459 (clobber (match_operand:DI 1 "register_operand"))]
2460 ""
2461 [(set (match_dup 1) (neg:DI (match_dup 0)))
2462 (set (match_dup 0) (if_then_else:DI (ge (match_dup 0) (const_int 0))
2463 (match_dup 0) (match_dup 1)))])
2464
2465 (define_split
2466 [(set (match_operand:DI 0 "register_operand")
2467 (abs:DI (match_operand:DI 1 "register_operand")))]
2468 "! rtx_equal_p (operands[0], operands[1])"
2469 [(set (match_dup 0) (neg:DI (match_dup 1)))
2470 (set (match_dup 0) (if_then_else:DI (lt (match_dup 1) (const_int 0))
2471 (match_dup 0) (match_dup 1)))])
2472
2473 (define_split
2474 [(set (match_operand:DI 0 "register_operand")
2475 (neg:DI (abs:DI (match_dup 0))))
2476 (clobber (match_operand:DI 1 "register_operand"))]
2477 ""
2478 [(set (match_dup 1) (neg:DI (match_dup 0)))
2479 (set (match_dup 0) (if_then_else:DI (le (match_dup 0) (const_int 0))
2480 (match_dup 0) (match_dup 1)))])
2481
2482 (define_split
2483 [(set (match_operand:DI 0 "register_operand")
2484 (neg:DI (abs:DI (match_operand:DI 1 "register_operand"))))]
2485 "! rtx_equal_p (operands[0], operands[1])"
2486 [(set (match_dup 0) (neg:DI (match_dup 1)))
2487 (set (match_dup 0) (if_then_else:DI (gt (match_dup 1) (const_int 0))
2488 (match_dup 0) (match_dup 1)))])
2489
2490 (define_insn "<code><mode>3"
2491 [(set (match_operand:I12MODE 0 "register_operand" "=r")
2492 (any_maxmin:I12MODE
2493 (match_operand:I12MODE 1 "reg_or_0_operand" "%rJ")
2494 (match_operand:I12MODE 2 "reg_or_8bit_operand" "rI")))]
2495 "TARGET_MAX"
2496 "<maxmin><vecmodesuffix> %r1,%2,%0"
2497 [(set_attr "type" "mvi")])
2498
2499 (define_expand "smaxdi3"
2500 [(set (match_dup 3)
2501 (le:DI (match_operand:DI 1 "reg_or_0_operand")
2502 (match_operand:DI 2 "reg_or_8bit_operand")))
2503 (set (match_operand:DI 0 "register_operand")
2504 (if_then_else:DI (eq (match_dup 3) (const_int 0))
2505 (match_dup 1) (match_dup 2)))]
2506 ""
2507 "operands[3] = gen_reg_rtx (DImode);")
2508
2509 (define_split
2510 [(set (match_operand:DI 0 "register_operand")
2511 (smax:DI (match_operand:DI 1 "reg_or_0_operand")
2512 (match_operand:DI 2 "reg_or_8bit_operand")))
2513 (clobber (match_operand:DI 3 "register_operand"))]
2514 "operands[2] != const0_rtx"
2515 [(set (match_dup 3) (le:DI (match_dup 1) (match_dup 2)))
2516 (set (match_dup 0) (if_then_else:DI (eq (match_dup 3) (const_int 0))
2517 (match_dup 1) (match_dup 2)))])
2518
2519 (define_insn "*smax_const0"
2520 [(set (match_operand:DI 0 "register_operand" "=r")
2521 (smax:DI (match_operand:DI 1 "register_operand" "0")
2522 (const_int 0)))]
2523 ""
2524 "cmovlt %0,0,%0"
2525 [(set_attr "type" "icmov")])
2526
2527 (define_expand "smindi3"
2528 [(set (match_dup 3)
2529 (lt:DI (match_operand:DI 1 "reg_or_0_operand")
2530 (match_operand:DI 2 "reg_or_8bit_operand")))
2531 (set (match_operand:DI 0 "register_operand")
2532 (if_then_else:DI (ne (match_dup 3) (const_int 0))
2533 (match_dup 1) (match_dup 2)))]
2534 ""
2535 "operands[3] = gen_reg_rtx (DImode);")
2536
2537 (define_split
2538 [(set (match_operand:DI 0 "register_operand")
2539 (smin:DI (match_operand:DI 1 "reg_or_0_operand")
2540 (match_operand:DI 2 "reg_or_8bit_operand")))
2541 (clobber (match_operand:DI 3 "register_operand"))]
2542 "operands[2] != const0_rtx"
2543 [(set (match_dup 3) (lt:DI (match_dup 1) (match_dup 2)))
2544 (set (match_dup 0) (if_then_else:DI (ne (match_dup 3) (const_int 0))
2545 (match_dup 1) (match_dup 2)))])
2546
2547 (define_insn "*smin_const0"
2548 [(set (match_operand:DI 0 "register_operand" "=r")
2549 (smin:DI (match_operand:DI 1 "register_operand" "0")
2550 (const_int 0)))]
2551 ""
2552 "cmovgt %0,0,%0"
2553 [(set_attr "type" "icmov")])
2554
2555 (define_expand "umaxdi3"
2556 [(set (match_dup 3)
2557 (leu:DI (match_operand:DI 1 "reg_or_0_operand")
2558 (match_operand:DI 2 "reg_or_8bit_operand")))
2559 (set (match_operand:DI 0 "register_operand")
2560 (if_then_else:DI (eq (match_dup 3) (const_int 0))
2561 (match_dup 1) (match_dup 2)))]
2562 ""
2563 "operands[3] = gen_reg_rtx (DImode);")
2564
2565 (define_split
2566 [(set (match_operand:DI 0 "register_operand")
2567 (umax:DI (match_operand:DI 1 "reg_or_0_operand")
2568 (match_operand:DI 2 "reg_or_8bit_operand")))
2569 (clobber (match_operand:DI 3 "register_operand"))]
2570 "operands[2] != const0_rtx"
2571 [(set (match_dup 3) (leu:DI (match_dup 1) (match_dup 2)))
2572 (set (match_dup 0) (if_then_else:DI (eq (match_dup 3) (const_int 0))
2573 (match_dup 1) (match_dup 2)))])
2574
2575 (define_expand "umindi3"
2576 [(set (match_dup 3)
2577 (ltu:DI (match_operand:DI 1 "reg_or_0_operand")
2578 (match_operand:DI 2 "reg_or_8bit_operand")))
2579 (set (match_operand:DI 0 "register_operand")
2580 (if_then_else:DI (ne (match_dup 3) (const_int 0))
2581 (match_dup 1) (match_dup 2)))]
2582 ""
2583 "operands[3] = gen_reg_rtx (DImode);")
2584
2585 (define_split
2586 [(set (match_operand:DI 0 "register_operand")
2587 (umin:DI (match_operand:DI 1 "reg_or_0_operand")
2588 (match_operand:DI 2 "reg_or_8bit_operand")))
2589 (clobber (match_operand:DI 3 "register_operand"))]
2590 "operands[2] != const0_rtx"
2591 [(set (match_dup 3) (ltu:DI (match_dup 1) (match_dup 2)))
2592 (set (match_dup 0) (if_then_else:DI (ne (match_dup 3) (const_int 0))
2593 (match_dup 1) (match_dup 2)))])
2594
2595 (define_insn "*bcc_normal"
2596 [(set (pc)
2597 (if_then_else
2598 (match_operator 1 "signed_comparison_operator"
2599 [(match_operand:DI 2 "reg_or_0_operand" "rJ")
2600 (const_int 0)])
2601 (label_ref (match_operand 0))
2602 (pc)))]
2603 ""
2604 "b%C1 %r2,%0"
2605 [(set_attr "type" "ibr")])
2606
2607 (define_insn "*bcc_reverse"
2608 [(set (pc)
2609 (if_then_else
2610 (match_operator 1 "signed_comparison_operator"
2611 [(match_operand:DI 2 "register_operand" "r")
2612 (const_int 0)])
2613
2614 (pc)
2615 (label_ref (match_operand 0))))]
2616 ""
2617 "b%c1 %2,%0"
2618 [(set_attr "type" "ibr")])
2619
2620 (define_insn "*blbs_normal"
2621 [(set (pc)
2622 (if_then_else
2623 (ne (zero_extract:DI (match_operand:DI 1 "reg_or_0_operand" "rJ")
2624 (const_int 1)
2625 (const_int 0))
2626 (const_int 0))
2627 (label_ref (match_operand 0))
2628 (pc)))]
2629 ""
2630 "blbs %r1,%0"
2631 [(set_attr "type" "ibr")])
2632
2633 (define_insn "*blbc_normal"
2634 [(set (pc)
2635 (if_then_else
2636 (eq (zero_extract:DI (match_operand:DI 1 "reg_or_0_operand" "rJ")
2637 (const_int 1)
2638 (const_int 0))
2639 (const_int 0))
2640 (label_ref (match_operand 0))
2641 (pc)))]
2642 ""
2643 "blbc %r1,%0"
2644 [(set_attr "type" "ibr")])
2645
2646 (define_split
2647 [(parallel
2648 [(set (pc)
2649 (if_then_else
2650 (match_operator 1 "comparison_operator"
2651 [(zero_extract:DI (match_operand:DI 2 "register_operand")
2652 (const_int 1)
2653 (match_operand:DI 3 "const_int_operand"))
2654 (const_int 0)])
2655 (label_ref (match_operand 0))
2656 (pc)))
2657 (clobber (match_operand:DI 4 "register_operand"))])]
2658 "INTVAL (operands[3]) != 0"
2659 [(set (match_dup 4)
2660 (lshiftrt:DI (match_dup 2) (match_dup 3)))
2661 (set (pc)
2662 (if_then_else (match_op_dup 1
2663 [(zero_extract:DI (match_dup 4)
2664 (const_int 1)
2665 (const_int 0))
2666 (const_int 0)])
2667 (label_ref (match_dup 0))
2668 (pc)))]
2669 )
2670 \f
2671 ;; The following are the corresponding floating-point insns. Recall
2672 ;; we need to have variants that expand the arguments from SFmode
2673 ;; to DFmode.
2674
2675 (define_insn "*cmpdf_ieee"
2676 [(set (match_operand:DF 0 "register_operand" "=&f")
2677 (match_operator:DF 1 "alpha_fp_comparison_operator"
2678 [(match_operand:DF 2 "reg_or_0_operand" "fG")
2679 (match_operand:DF 3 "reg_or_0_operand" "fG")]))]
2680 "TARGET_FP && alpha_fptm >= ALPHA_FPTM_SU"
2681 "cmp%-%C1%/ %R2,%R3,%0"
2682 [(set_attr "type" "fadd")
2683 (set_attr "trap" "yes")
2684 (set_attr "trap_suffix" "su")])
2685
2686 (define_insn "*cmpdf_internal"
2687 [(set (match_operand:DF 0 "register_operand" "=f")
2688 (match_operator:DF 1 "alpha_fp_comparison_operator"
2689 [(match_operand:DF 2 "reg_or_0_operand" "fG")
2690 (match_operand:DF 3 "reg_or_0_operand" "fG")]))]
2691 "TARGET_FP"
2692 "cmp%-%C1%/ %R2,%R3,%0"
2693 [(set_attr "type" "fadd")
2694 (set_attr "trap" "yes")
2695 (set_attr "trap_suffix" "su")])
2696
2697 (define_insn "*cmpdf_ext1"
2698 [(set (match_operand:DF 0 "register_operand" "=f")
2699 (match_operator:DF 1 "alpha_fp_comparison_operator"
2700 [(float_extend:DF
2701 (match_operand:SF 2 "reg_or_0_operand" "fG"))
2702 (match_operand:DF 3 "reg_or_0_operand" "fG")]))]
2703 "TARGET_FP && alpha_fptm < ALPHA_FPTM_SU"
2704 "cmp%-%C1%/ %R2,%R3,%0"
2705 [(set_attr "type" "fadd")
2706 (set_attr "trap" "yes")
2707 (set_attr "trap_suffix" "su")])
2708
2709 (define_insn "*cmpdf_ext2"
2710 [(set (match_operand:DF 0 "register_operand" "=f")
2711 (match_operator:DF 1 "alpha_fp_comparison_operator"
2712 [(match_operand:DF 2 "reg_or_0_operand" "fG")
2713 (float_extend:DF
2714 (match_operand:SF 3 "reg_or_0_operand" "fG"))]))]
2715 "TARGET_FP && alpha_fptm < ALPHA_FPTM_SU"
2716 "cmp%-%C1%/ %R2,%R3,%0"
2717 [(set_attr "type" "fadd")
2718 (set_attr "trap" "yes")
2719 (set_attr "trap_suffix" "su")])
2720
2721 (define_insn "*cmpdf_ext3"
2722 [(set (match_operand:DF 0 "register_operand" "=f")
2723 (match_operator:DF 1 "alpha_fp_comparison_operator"
2724 [(float_extend:DF
2725 (match_operand:SF 2 "reg_or_0_operand" "fG"))
2726 (float_extend:DF
2727 (match_operand:SF 3 "reg_or_0_operand" "fG"))]))]
2728 "TARGET_FP && alpha_fptm < ALPHA_FPTM_SU"
2729 "cmp%-%C1%/ %R2,%R3,%0"
2730 [(set_attr "type" "fadd")
2731 (set_attr "trap" "yes")
2732 (set_attr "trap_suffix" "su")])
2733
2734 (define_insn "*mov<mode>cc_internal"
2735 [(set (match_operand:FMODE 0 "register_operand" "=f,f")
2736 (if_then_else:FMODE
2737 (match_operator 3 "signed_comparison_operator"
2738 [(match_operand:DF 4 "reg_or_0_operand" "fG,fG")
2739 (match_operand:DF 2 "const0_operand" "G,G")])
2740 (match_operand:FMODE 1 "reg_or_0_operand" "fG,0")
2741 (match_operand:FMODE 5 "reg_or_0_operand" "0,fG")))]
2742 "TARGET_FP"
2743 "@
2744 fcmov%C3 %R4,%R1,%0
2745 fcmov%D3 %R4,%R5,%0"
2746 [(set_attr "type" "fcmov")])
2747
2748 (define_insn "*movdfcc_ext1"
2749 [(set (match_operand:DF 0 "register_operand" "=f,f")
2750 (if_then_else:DF
2751 (match_operator 3 "signed_comparison_operator"
2752 [(match_operand:DF 4 "reg_or_0_operand" "fG,fG")
2753 (match_operand:DF 2 "const0_operand" "G,G")])
2754 (float_extend:DF (match_operand:SF 1 "reg_or_0_operand" "fG,0"))
2755 (match_operand:DF 5 "reg_or_0_operand" "0,fG")))]
2756 "TARGET_FP && alpha_fptm < ALPHA_FPTM_SU"
2757 "@
2758 fcmov%C3 %R4,%R1,%0
2759 fcmov%D3 %R4,%R5,%0"
2760 [(set_attr "type" "fcmov")])
2761
2762 (define_insn "*movdfcc_ext2"
2763 [(set (match_operand:DF 0 "register_operand" "=f,f")
2764 (if_then_else:DF
2765 (match_operator 3 "signed_comparison_operator"
2766 [(float_extend:DF
2767 (match_operand:SF 4 "reg_or_0_operand" "fG,fG"))
2768 (match_operand:DF 2 "const0_operand" "G,G")])
2769 (match_operand:DF 1 "reg_or_0_operand" "fG,0")
2770 (match_operand:DF 5 "reg_or_0_operand" "0,fG")))]
2771 "TARGET_FP && alpha_fptm < ALPHA_FPTM_SU"
2772 "@
2773 fcmov%C3 %R4,%R1,%0
2774 fcmov%D3 %R4,%R5,%0"
2775 [(set_attr "type" "fcmov")])
2776
2777 (define_insn "*movdfcc_ext3"
2778 [(set (match_operand:SF 0 "register_operand" "=f,f")
2779 (if_then_else:SF
2780 (match_operator 3 "signed_comparison_operator"
2781 [(float_extend:DF
2782 (match_operand:SF 4 "reg_or_0_operand" "fG,fG"))
2783 (match_operand:DF 2 "const0_operand" "G,G")])
2784 (match_operand:SF 1 "reg_or_0_operand" "fG,0")
2785 (match_operand:SF 5 "reg_or_0_operand" "0,fG")))]
2786 "TARGET_FP && alpha_fptm < ALPHA_FPTM_SU"
2787 "@
2788 fcmov%C3 %R4,%R1,%0
2789 fcmov%D3 %R4,%R5,%0"
2790 [(set_attr "type" "fcmov")])
2791
2792 (define_insn "*movdfcc_ext4"
2793 [(set (match_operand:DF 0 "register_operand" "=f,f")
2794 (if_then_else:DF
2795 (match_operator 3 "signed_comparison_operator"
2796 [(float_extend:DF
2797 (match_operand:SF 4 "reg_or_0_operand" "fG,fG"))
2798 (match_operand:DF 2 "const0_operand" "G,G")])
2799 (float_extend:DF (match_operand:SF 1 "reg_or_0_operand" "fG,0"))
2800 (match_operand:DF 5 "reg_or_0_operand" "0,fG")))]
2801 "TARGET_FP && alpha_fptm < ALPHA_FPTM_SU"
2802 "@
2803 fcmov%C3 %R4,%R1,%0
2804 fcmov%D3 %R4,%R5,%0"
2805 [(set_attr "type" "fcmov")])
2806
2807 (define_expand "smaxdf3"
2808 [(set (match_dup 3)
2809 (le:DF (match_operand:DF 1 "reg_or_0_operand")
2810 (match_operand:DF 2 "reg_or_0_operand")))
2811 (set (match_operand:DF 0 "register_operand")
2812 (if_then_else:DF (eq (match_dup 3) (match_dup 4))
2813 (match_dup 1) (match_dup 2)))]
2814 "TARGET_FP"
2815 {
2816 operands[3] = gen_reg_rtx (DFmode);
2817 operands[4] = CONST0_RTX (DFmode);
2818 })
2819
2820 (define_expand "smindf3"
2821 [(set (match_dup 3)
2822 (lt:DF (match_operand:DF 1 "reg_or_0_operand")
2823 (match_operand:DF 2 "reg_or_0_operand")))
2824 (set (match_operand:DF 0 "register_operand")
2825 (if_then_else:DF (ne (match_dup 3) (match_dup 4))
2826 (match_dup 1) (match_dup 2)))]
2827 "TARGET_FP"
2828 {
2829 operands[3] = gen_reg_rtx (DFmode);
2830 operands[4] = CONST0_RTX (DFmode);
2831 })
2832
2833 (define_expand "smaxsf3"
2834 [(set (match_dup 3)
2835 (le:DF (float_extend:DF (match_operand:SF 1 "reg_or_0_operand"))
2836 (float_extend:DF (match_operand:SF 2 "reg_or_0_operand"))))
2837 (set (match_operand:SF 0 "register_operand")
2838 (if_then_else:SF (eq (match_dup 3) (match_dup 4))
2839 (match_dup 1) (match_dup 2)))]
2840 "TARGET_FP && alpha_fptm < ALPHA_FPTM_SU"
2841 {
2842 operands[3] = gen_reg_rtx (DFmode);
2843 operands[4] = CONST0_RTX (DFmode);
2844 })
2845
2846 (define_expand "sminsf3"
2847 [(set (match_dup 3)
2848 (lt:DF (float_extend:DF (match_operand:SF 1 "reg_or_0_operand"))
2849 (float_extend:DF (match_operand:SF 2 "reg_or_0_operand"))))
2850 (set (match_operand:SF 0 "register_operand")
2851 (if_then_else:SF (ne (match_dup 3) (match_dup 4))
2852 (match_dup 1) (match_dup 2)))]
2853 "TARGET_FP && alpha_fptm < ALPHA_FPTM_SU"
2854 {
2855 operands[3] = gen_reg_rtx (DFmode);
2856 operands[4] = CONST0_RTX (DFmode);
2857 })
2858
2859 (define_insn "*fbcc_normal"
2860 [(set (pc)
2861 (if_then_else
2862 (match_operator 1 "signed_comparison_operator"
2863 [(match_operand:DF 2 "reg_or_0_operand" "fG")
2864 (match_operand:DF 3 "const0_operand" "G")])
2865 (label_ref (match_operand 0))
2866 (pc)))]
2867 "TARGET_FP"
2868 "fb%C1 %R2,%0"
2869 [(set_attr "type" "fbr")])
2870
2871 (define_insn "*fbcc_ext_normal"
2872 [(set (pc)
2873 (if_then_else
2874 (match_operator 1 "signed_comparison_operator"
2875 [(float_extend:DF
2876 (match_operand:SF 2 "reg_or_0_operand" "fG"))
2877 (match_operand:DF 3 "const0_operand" "G")])
2878 (label_ref (match_operand 0))
2879 (pc)))]
2880 "TARGET_FP"
2881 "fb%C1 %R2,%0"
2882 [(set_attr "type" "fbr")])
2883 \f
2884 ;; These are the main define_expand's used to make conditional branches
2885 ;; and compares.
2886
2887 (define_expand "cbranchdf4"
2888 [(use (match_operator 0 "alpha_cbranch_operator"
2889 [(match_operand:DF 1 "reg_or_0_operand")
2890 (match_operand:DF 2 "reg_or_0_operand")]))
2891 (use (match_operand 3))]
2892 "TARGET_FP"
2893 "alpha_emit_conditional_branch (operands, DFmode); DONE;")
2894
2895 (define_expand "cbranchtf4"
2896 [(use (match_operator 0 "alpha_cbranch_operator"
2897 [(match_operand:TF 1 "general_operand")
2898 (match_operand:TF 2 "general_operand")]))
2899 (use (match_operand 3))]
2900 "TARGET_HAS_XFLOATING_LIBS"
2901 "alpha_emit_conditional_branch (operands, TFmode); DONE;")
2902
2903 (define_expand "cbranchdi4"
2904 [(use (match_operator 0 "alpha_cbranch_operator"
2905 [(match_operand:DI 1 "general_operand")
2906 (match_operand:DI 2 "general_operand")]))
2907 (use (match_operand 3))]
2908 ""
2909 "alpha_emit_conditional_branch (operands, DImode); DONE;")
2910
2911 (define_expand "cstoredf4"
2912 [(use (match_operator:DI 1 "alpha_cbranch_operator"
2913 [(match_operand:DF 2 "reg_or_0_operand")
2914 (match_operand:DF 3 "reg_or_0_operand")]))
2915 (clobber (match_operand:DI 0 "register_operand"))]
2916 "TARGET_FP"
2917 {
2918 if (alpha_emit_setcc (operands, DFmode))
2919 DONE;
2920 else
2921 FAIL;
2922 })
2923
2924 (define_expand "cstoretf4"
2925 [(use (match_operator:DI 1 "alpha_cbranch_operator"
2926 [(match_operand:TF 2 "general_operand")
2927 (match_operand:TF 3 "general_operand")]))
2928 (clobber (match_operand:DI 0 "register_operand"))]
2929 "TARGET_HAS_XFLOATING_LIBS"
2930 {
2931 if (alpha_emit_setcc (operands, TFmode))
2932 DONE;
2933 else
2934 FAIL;
2935 })
2936
2937 (define_expand "cstoredi4"
2938 [(use (match_operator:DI 1 "alpha_cbranch_operator"
2939 [(match_operand:DI 2 "general_operand")
2940 (match_operand:DI 3 "general_operand")]))
2941 (clobber (match_operand:DI 0 "register_operand"))]
2942 ""
2943 {
2944 if (alpha_emit_setcc (operands, DImode))
2945 DONE;
2946 else
2947 FAIL;
2948 })
2949 \f
2950 ;; These are the main define_expand's used to make conditional moves.
2951
2952 (define_expand "mov<mode>cc"
2953 [(set (match_operand:I48MODE 0 "register_operand")
2954 (if_then_else:I48MODE
2955 (match_operand 1 "comparison_operator")
2956 (match_operand:I48MODE 2 "reg_or_8bit_operand")
2957 (match_operand:I48MODE 3 "reg_or_8bit_operand")))]
2958 ""
2959 {
2960 operands[1] = alpha_emit_conditional_move (operands[1], <MODE>mode);
2961 if (operands[1] == 0)
2962 FAIL;
2963 })
2964
2965 (define_expand "mov<mode>cc"
2966 [(set (match_operand:FMODE 0 "register_operand")
2967 (if_then_else:FMODE
2968 (match_operand 1 "comparison_operator")
2969 (match_operand:FMODE 2 "reg_or_8bit_operand")
2970 (match_operand:FMODE 3 "reg_or_8bit_operand")))]
2971 ""
2972 {
2973 operands[1] = alpha_emit_conditional_move (operands[1], <MODE>mode);
2974 if (operands[1] == 0)
2975 FAIL;
2976 })
2977 \f
2978 ;; These define_split definitions are used in cases when comparisons have
2979 ;; not be stated in the correct way and we need to reverse the second
2980 ;; comparison. For example, x >= 7 has to be done as x < 6 with the
2981 ;; comparison that tests the result being reversed. We have one define_split
2982 ;; for each use of a comparison. They do not match valid insns and need
2983 ;; not generate valid insns.
2984 ;;
2985 ;; We can also handle equality comparisons (and inequality comparisons in
2986 ;; cases where the resulting add cannot overflow) by doing an add followed by
2987 ;; a comparison with zero. This is faster since the addition takes one
2988 ;; less cycle than a compare when feeding into a conditional move.
2989 ;; For this case, we also have an SImode pattern since we can merge the add
2990 ;; and sign extend and the order doesn't matter.
2991 ;;
2992 ;; We do not do this for floating-point, since it isn't clear how the "wrong"
2993 ;; operation could have been generated.
2994
2995 (define_split
2996 [(set (match_operand:DI 0 "register_operand")
2997 (if_then_else:DI
2998 (match_operator 1 "comparison_operator"
2999 [(match_operand:DI 2 "reg_or_0_operand")
3000 (match_operand:DI 3 "reg_or_cint_operand")])
3001 (match_operand:DI 4 "reg_or_cint_operand")
3002 (match_operand:DI 5 "reg_or_cint_operand")))
3003 (clobber (match_operand:DI 6 "register_operand"))]
3004 "operands[3] != const0_rtx"
3005 [(set (match_dup 6) (match_dup 7))
3006 (set (match_dup 0)
3007 (if_then_else:DI (match_dup 8) (match_dup 4) (match_dup 5)))]
3008 {
3009 enum rtx_code code = GET_CODE (operands[1]);
3010 int unsignedp = (code == GEU || code == LEU || code == GTU || code == LTU);
3011
3012 /* If we are comparing for equality with a constant and that constant
3013 appears in the arm when the register equals the constant, use the
3014 register since that is more likely to match (and to produce better code
3015 if both would). */
3016
3017 if (code == EQ && CONST_INT_P (operands[3])
3018 && rtx_equal_p (operands[4], operands[3]))
3019 operands[4] = operands[2];
3020
3021 else if (code == NE && CONST_INT_P (operands[3])
3022 && rtx_equal_p (operands[5], operands[3]))
3023 operands[5] = operands[2];
3024
3025 if (code == NE || code == EQ
3026 || (extended_count (operands[2], DImode, unsignedp) >= 1
3027 && extended_count (operands[3], DImode, unsignedp) >= 1))
3028 {
3029 if (CONST_INT_P (operands[3]))
3030 operands[7] = gen_rtx_PLUS (DImode, operands[2],
3031 GEN_INT (- INTVAL (operands[3])));
3032 else
3033 operands[7] = gen_rtx_MINUS (DImode, operands[2], operands[3]);
3034
3035 operands[8] = gen_rtx_fmt_ee (code, VOIDmode, operands[6], const0_rtx);
3036 }
3037
3038 else if (code == EQ || code == LE || code == LT
3039 || code == LEU || code == LTU)
3040 {
3041 operands[7] = gen_rtx_fmt_ee (code, DImode, operands[2], operands[3]);
3042 operands[8] = gen_rtx_NE (VOIDmode, operands[6], const0_rtx);
3043 }
3044 else
3045 {
3046 operands[7] = gen_rtx_fmt_ee (reverse_condition (code), DImode,
3047 operands[2], operands[3]);
3048 operands[8] = gen_rtx_EQ (VOIDmode, operands[6], const0_rtx);
3049 }
3050 })
3051
3052 (define_split
3053 [(set (match_operand:DI 0 "register_operand")
3054 (if_then_else:DI
3055 (match_operator 1 "comparison_operator"
3056 [(match_operand:SI 2 "reg_or_0_operand")
3057 (match_operand:SI 3 "reg_or_cint_operand")])
3058 (match_operand:DI 4 "reg_or_8bit_operand")
3059 (match_operand:DI 5 "reg_or_8bit_operand")))
3060 (clobber (match_operand:DI 6 "register_operand"))]
3061 "operands[3] != const0_rtx
3062 && (GET_CODE (operands[1]) == EQ || GET_CODE (operands[1]) == NE)"
3063 [(set (match_dup 6) (match_dup 7))
3064 (set (match_dup 0)
3065 (if_then_else:DI (match_dup 8) (match_dup 4) (match_dup 5)))]
3066 {
3067 enum rtx_code code = GET_CODE (operands[1]);
3068 int unsignedp = (code == GEU || code == LEU || code == GTU || code == LTU);
3069 rtx tem;
3070
3071 if ((code != NE && code != EQ
3072 && ! (extended_count (operands[2], DImode, unsignedp) >= 1
3073 && extended_count (operands[3], DImode, unsignedp) >= 1)))
3074 FAIL;
3075
3076 if (CONST_INT_P (operands[3]))
3077 tem = gen_rtx_PLUS (SImode, operands[2],
3078 GEN_INT (- INTVAL (operands[3])));
3079 else
3080 tem = gen_rtx_MINUS (SImode, operands[2], operands[3]);
3081
3082 operands[7] = gen_rtx_SIGN_EXTEND (DImode, tem);
3083 operands[8] = gen_rtx_fmt_ee (GET_CODE (operands[1]), VOIDmode,
3084 operands[6], const0_rtx);
3085 })
3086
3087 ;; Prefer to use cmp and arithmetic when possible instead of a cmove.
3088
3089 (define_split
3090 [(set (match_operand 0 "register_operand")
3091 (if_then_else (match_operator 1 "signed_comparison_operator"
3092 [(match_operand:DI 2 "reg_or_0_operand")
3093 (const_int 0)])
3094 (match_operand 3 "const_int_operand")
3095 (match_operand 4 "const_int_operand")))]
3096 ""
3097 [(const_int 0)]
3098 {
3099 if (alpha_split_conditional_move (GET_CODE (operands[1]), operands[0],
3100 operands[2], operands[3], operands[4]))
3101 DONE;
3102 else
3103 FAIL;
3104 })
3105
3106 ;; ??? Why combine is allowed to create such non-canonical rtl, I don't know.
3107 ;; Oh well, we match it in movcc, so it must be partially our fault.
3108 (define_split
3109 [(set (match_operand 0 "register_operand")
3110 (if_then_else (match_operator 1 "signed_comparison_operator"
3111 [(const_int 0)
3112 (match_operand:DI 2 "reg_or_0_operand")])
3113 (match_operand 3 "const_int_operand")
3114 (match_operand 4 "const_int_operand")))]
3115 ""
3116 [(const_int 0)]
3117 {
3118 if (alpha_split_conditional_move (swap_condition (GET_CODE (operands[1])),
3119 operands[0], operands[2], operands[3],
3120 operands[4]))
3121 DONE;
3122 else
3123 FAIL;
3124 })
3125
3126 (define_insn_and_split "*cmp_sadd_di"
3127 [(set (match_operand:DI 0 "register_operand" "=r")
3128 (plus:DI (if_then_else:DI
3129 (match_operator 1 "alpha_zero_comparison_operator"
3130 [(match_operand:DI 2 "reg_or_0_operand" "rJ")
3131 (const_int 0)])
3132 (match_operand:DI 3 "const48_operand" "I")
3133 (const_int 0))
3134 (match_operand:DI 4 "sext_add_operand" "rIO")))
3135 (clobber (match_scratch:DI 5 "=r"))]
3136 ""
3137 "#"
3138 ""
3139 [(set (match_dup 5)
3140 (match_op_dup:DI 1 [(match_dup 2) (const_int 0)]))
3141 (set (match_dup 0)
3142 (plus:DI (mult:DI (match_dup 5) (match_dup 3))
3143 (match_dup 4)))]
3144 {
3145 if (can_create_pseudo_p ())
3146 operands[5] = gen_reg_rtx (DImode);
3147 else if (reg_overlap_mentioned_p (operands[5], operands[4]))
3148 operands[5] = operands[0];
3149 })
3150
3151 (define_insn_and_split "*cmp_sadd_si"
3152 [(set (match_operand:SI 0 "register_operand" "=r")
3153 (plus:SI (if_then_else:SI
3154 (match_operator 1 "alpha_zero_comparison_operator"
3155 [(match_operand:DI 2 "reg_or_0_operand" "rJ")
3156 (const_int 0)])
3157 (match_operand:SI 3 "const48_operand" "I")
3158 (const_int 0))
3159 (match_operand:SI 4 "sext_add_operand" "rIO")))
3160 (clobber (match_scratch:DI 5 "=r"))]
3161 ""
3162 "#"
3163 ""
3164 [(set (match_dup 5)
3165 (match_op_dup:DI 1 [(match_dup 2) (const_int 0)]))
3166 (set (match_dup 0)
3167 (plus:SI (mult:SI (match_dup 6) (match_dup 3))
3168 (match_dup 4)))]
3169 {
3170 if (can_create_pseudo_p ())
3171 operands[5] = gen_reg_rtx (DImode);
3172 else if (reg_overlap_mentioned_p (operands[5], operands[4]))
3173 operands[5] = gen_lowpart (DImode, operands[0]);
3174
3175 operands[6] = gen_lowpart (SImode, operands[5]);
3176 })
3177
3178 (define_insn_and_split "*cmp_sadd_sidi"
3179 [(set (match_operand:DI 0 "register_operand" "=r")
3180 (sign_extend:DI
3181 (plus:SI (if_then_else:SI
3182 (match_operator 1 "alpha_zero_comparison_operator"
3183 [(match_operand:DI 2 "reg_or_0_operand" "rJ")
3184 (const_int 0)])
3185 (match_operand:SI 3 "const48_operand" "I")
3186 (const_int 0))
3187 (match_operand:SI 4 "sext_add_operand" "rIO"))))
3188 (clobber (match_scratch:DI 5 "=r"))]
3189 ""
3190 "#"
3191 ""
3192 [(set (match_dup 5)
3193 (match_op_dup:DI 1 [(match_dup 2) (const_int 0)]))
3194 (set (match_dup 0)
3195 (sign_extend:DI (plus:SI (mult:SI (match_dup 6) (match_dup 3))
3196 (match_dup 4))))]
3197 {
3198 if (can_create_pseudo_p ())
3199 operands[5] = gen_reg_rtx (DImode);
3200 else if (reg_overlap_mentioned_p (operands[5], operands[4]))
3201 operands[5] = operands[0];
3202
3203 operands[6] = gen_lowpart (SImode, operands[5]);
3204 })
3205
3206 (define_insn_and_split "*cmp_ssub_di"
3207 [(set (match_operand:DI 0 "register_operand" "=r")
3208 (minus:DI (if_then_else:DI
3209 (match_operator 1 "alpha_zero_comparison_operator"
3210 [(match_operand:DI 2 "reg_or_0_operand" "rJ")
3211 (const_int 0)])
3212 (match_operand:DI 3 "const48_operand" "I")
3213 (const_int 0))
3214 (match_operand:DI 4 "reg_or_8bit_operand" "rI")))
3215 (clobber (match_scratch:DI 5 "=r"))]
3216 ""
3217 "#"
3218 ""
3219 [(set (match_dup 5)
3220 (match_op_dup:DI 1 [(match_dup 2) (const_int 0)]))
3221 (set (match_dup 0)
3222 (minus:DI (mult:DI (match_dup 5) (match_dup 3))
3223 (match_dup 4)))]
3224 {
3225 if (can_create_pseudo_p ())
3226 operands[5] = gen_reg_rtx (DImode);
3227 else if (reg_overlap_mentioned_p (operands[5], operands[4]))
3228 operands[5] = operands[0];
3229 })
3230
3231 (define_insn_and_split "*cmp_ssub_si"
3232 [(set (match_operand:SI 0 "register_operand" "=r")
3233 (minus:SI (if_then_else:SI
3234 (match_operator 1 "alpha_zero_comparison_operator"
3235 [(match_operand:DI 2 "reg_or_0_operand" "rJ")
3236 (const_int 0)])
3237 (match_operand:SI 3 "const48_operand" "I")
3238 (const_int 0))
3239 (match_operand:SI 4 "reg_or_8bit_operand" "rI")))
3240 (clobber (match_scratch:DI 5 "=r"))]
3241 ""
3242 "#"
3243 ""
3244 [(set (match_dup 5)
3245 (match_op_dup:DI 1 [(match_dup 2) (const_int 0)]))
3246 (set (match_dup 0)
3247 (minus:SI (mult:SI (match_dup 6) (match_dup 3))
3248 (match_dup 4)))]
3249 {
3250 if (can_create_pseudo_p ())
3251 operands[5] = gen_reg_rtx (DImode);
3252 else if (reg_overlap_mentioned_p (operands[5], operands[4]))
3253 operands[5] = gen_lowpart (DImode, operands[0]);
3254
3255 operands[6] = gen_lowpart (SImode, operands[5]);
3256 })
3257
3258 (define_insn_and_split "*cmp_ssub_sidi"
3259 [(set (match_operand:DI 0 "register_operand" "=r")
3260 (sign_extend:DI
3261 (minus:SI (if_then_else:SI
3262 (match_operator 1 "alpha_zero_comparison_operator"
3263 [(match_operand:DI 2 "reg_or_0_operand" "rJ")
3264 (const_int 0)])
3265 (match_operand:SI 3 "const48_operand" "I")
3266 (const_int 0))
3267 (match_operand:SI 4 "reg_or_8bit_operand" "rI"))))
3268 (clobber (match_scratch:DI 5 "=r"))]
3269 ""
3270 "#"
3271 ""
3272 [(set (match_dup 5)
3273 (match_op_dup:DI 1 [(match_dup 2) (const_int 0)]))
3274 (set (match_dup 0)
3275 (sign_extend:DI (minus:SI (mult:SI (match_dup 6) (match_dup 3))
3276 (match_dup 4))))]
3277 {
3278 if (can_create_pseudo_p ())
3279 operands[5] = gen_reg_rtx (DImode);
3280 else if (reg_overlap_mentioned_p (operands[5], operands[4]))
3281 operands[5] = operands[0];
3282
3283 operands[6] = gen_lowpart (SImode, operands[5]);
3284 })
3285 \f
3286 ;; Here are the CALL and unconditional branch insns. Calls on NT and OSF
3287 ;; work differently, so we have different patterns for each.
3288
3289 (define_expand "call"
3290 [(use (match_operand:DI 0))
3291 (use (match_operand 1))
3292 (use (match_operand 2))
3293 (use (match_operand 3))]
3294 ""
3295 {
3296 if (TARGET_ABI_OPEN_VMS)
3297 emit_call_insn (gen_call_vms (operands[0], operands[2]));
3298 else
3299 emit_call_insn (gen_call_osf (operands[0], operands[1]));
3300 DONE;
3301 })
3302
3303 (define_expand "sibcall"
3304 [(parallel [(call (mem:DI (match_operand 0))
3305 (match_operand 1))
3306 (unspec [(reg:DI 29)] UNSPEC_SIBCALL)])]
3307 "TARGET_ABI_OSF"
3308 {
3309 gcc_assert (MEM_P (operands[0]));
3310 operands[0] = XEXP (operands[0], 0);
3311 })
3312
3313 (define_expand "call_osf"
3314 [(parallel [(call (mem:DI (match_operand 0))
3315 (match_operand 1))
3316 (use (reg:DI 29))
3317 (clobber (reg:DI 26))])]
3318 ""
3319 {
3320 gcc_assert (MEM_P (operands[0]));
3321
3322 operands[0] = XEXP (operands[0], 0);
3323 if (! call_operand (operands[0], Pmode))
3324 operands[0] = copy_to_mode_reg (Pmode, operands[0]);
3325 })
3326
3327 ;;
3328 ;; call openvms/alpha
3329 ;; op 0: symbol ref for called function
3330 ;; op 1: next_arg_reg (argument information value for R25)
3331 ;;
3332 (define_expand "call_vms"
3333 [(parallel [(call (mem:DI (match_operand 0))
3334 (match_operand 1))
3335 (use (match_dup 2))
3336 (use (reg:DI 25))
3337 (use (reg:DI 26))
3338 (clobber (reg:DI 27))])]
3339 ""
3340 {
3341 gcc_assert (MEM_P (operands[0]));
3342
3343 operands[0] = XEXP (operands[0], 0);
3344
3345 /* Always load AI with argument information, then handle symbolic and
3346 indirect call differently. Load RA and set operands[2] to PV in
3347 both cases. */
3348
3349 emit_move_insn (gen_rtx_REG (DImode, 25), operands[1]);
3350 if (GET_CODE (operands[0]) == SYMBOL_REF)
3351 {
3352 operands[2] = const0_rtx;
3353 }
3354 else
3355 {
3356 emit_move_insn (gen_rtx_REG (Pmode, 26),
3357 gen_rtx_MEM (Pmode, plus_constant (Pmode,
3358 operands[0], 8)));
3359 operands[2] = operands[0];
3360 }
3361 })
3362
3363 (define_expand "call_value"
3364 [(use (match_operand 0))
3365 (use (match_operand:DI 1))
3366 (use (match_operand 2))
3367 (use (match_operand 3))
3368 (use (match_operand 4))]
3369 ""
3370 {
3371 if (TARGET_ABI_OPEN_VMS)
3372 emit_call_insn (gen_call_value_vms (operands[0], operands[1],
3373 operands[3]));
3374 else
3375 emit_call_insn (gen_call_value_osf (operands[0], operands[1],
3376 operands[2]));
3377 DONE;
3378 })
3379
3380 (define_expand "sibcall_value"
3381 [(parallel [(set (match_operand 0)
3382 (call (mem:DI (match_operand 1))
3383 (match_operand 2)))
3384 (unspec [(reg:DI 29)] UNSPEC_SIBCALL)])]
3385 "TARGET_ABI_OSF"
3386 {
3387 gcc_assert (MEM_P (operands[1]));
3388 operands[1] = XEXP (operands[1], 0);
3389 })
3390
3391 (define_expand "call_value_osf"
3392 [(parallel [(set (match_operand 0)
3393 (call (mem:DI (match_operand 1))
3394 (match_operand 2)))
3395 (use (reg:DI 29))
3396 (clobber (reg:DI 26))])]
3397 ""
3398 {
3399 gcc_assert (MEM_P (operands[1]));
3400
3401 operands[1] = XEXP (operands[1], 0);
3402 if (! call_operand (operands[1], Pmode))
3403 operands[1] = copy_to_mode_reg (Pmode, operands[1]);
3404 })
3405
3406 (define_expand "call_value_vms"
3407 [(parallel [(set (match_operand 0)
3408 (call (mem:DI (match_operand:DI 1))
3409 (match_operand 2)))
3410 (use (match_dup 3))
3411 (use (reg:DI 25))
3412 (use (reg:DI 26))
3413 (clobber (reg:DI 27))])]
3414 ""
3415 {
3416 gcc_assert (MEM_P (operands[1]));
3417
3418 operands[1] = XEXP (operands[1], 0);
3419
3420 /* Always load AI with argument information, then handle symbolic and
3421 indirect call differently. Load RA and set operands[3] to PV in
3422 both cases. */
3423
3424 emit_move_insn (gen_rtx_REG (DImode, 25), operands[2]);
3425 if (GET_CODE (operands[1]) == SYMBOL_REF)
3426 {
3427 operands[3] = const0_rtx;
3428 }
3429 else
3430 {
3431 emit_move_insn (gen_rtx_REG (Pmode, 26),
3432 gen_rtx_MEM (Pmode, plus_constant (Pmode,
3433 operands[1], 8)));
3434 operands[3] = operands[1];
3435 }
3436 })
3437
3438 (define_insn "*call_osf_1_er_noreturn"
3439 [(call (mem:DI (match_operand:DI 0 "call_operand" "c,R,s"))
3440 (match_operand 1))
3441 (use (reg:DI 29))
3442 (clobber (reg:DI 26))]
3443 "TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF
3444 && find_reg_note (insn, REG_NORETURN, NULL_RTX)"
3445 "@
3446 jsr $26,($27),0
3447 bsr $26,%0\t\t!samegp
3448 ldq $27,%0($29)\t\t!literal!%#\;jsr $26,($27),%0\t\t!lituse_jsr!%#"
3449 [(set_attr "type" "jsr")
3450 (set_attr "length" "*,*,8")])
3451
3452 (define_insn "*call_osf_1_er"
3453 [(call (mem:DI (match_operand:DI 0 "call_operand" "c,R,s"))
3454 (match_operand 1))
3455 (use (reg:DI 29))
3456 (clobber (reg:DI 26))]
3457 "TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF"
3458 "@
3459 jsr $26,(%0),0\;ldah $29,0($26)\t\t!gpdisp!%*\;lda $29,0($29)\t\t!gpdisp!%*
3460 bsr $26,%0\t\t!samegp
3461 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!%*"
3462 [(set_attr "type" "jsr")
3463 (set_attr "length" "12,*,16")])
3464
3465 ;; We must use peep2 instead of a split because we need accurate life
3466 ;; information for $gp. Consider the case of { bar(); while (1); }.
3467 (define_peephole2
3468 [(parallel [(call (mem:DI (match_operand:DI 0 "call_operand"))
3469 (match_operand 1))
3470 (use (reg:DI 29))
3471 (clobber (reg:DI 26))])]
3472 "TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF && reload_completed
3473 && ! samegp_function_operand (operands[0], Pmode)
3474 && (peep2_regno_dead_p (1, 29)
3475 || find_reg_note (insn, REG_NORETURN, NULL_RTX))"
3476 [(parallel [(call (mem:DI (match_dup 2))
3477 (match_dup 1))
3478 (use (reg:DI 29))
3479 (use (match_dup 0))
3480 (use (match_dup 3))
3481 (clobber (reg:DI 26))])]
3482 {
3483 if (CONSTANT_P (operands[0]))
3484 {
3485 operands[2] = gen_rtx_REG (Pmode, 27);
3486 operands[3] = GEN_INT (alpha_next_sequence_number++);
3487 emit_insn (gen_movdi_er_high_g (operands[2], pic_offset_table_rtx,
3488 operands[0], operands[3]));
3489 }
3490 else
3491 {
3492 operands[2] = operands[0];
3493 operands[0] = const0_rtx;
3494 operands[3] = const0_rtx;
3495 }
3496 })
3497
3498 (define_peephole2
3499 [(parallel [(call (mem:DI (match_operand:DI 0 "call_operand"))
3500 (match_operand 1))
3501 (use (reg:DI 29))
3502 (clobber (reg:DI 26))])]
3503 "TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF && reload_completed
3504 && ! samegp_function_operand (operands[0], Pmode)
3505 && ! (peep2_regno_dead_p (1, 29)
3506 || find_reg_note (insn, REG_NORETURN, NULL_RTX))"
3507 [(parallel [(call (mem:DI (match_dup 2))
3508 (match_dup 1))
3509 (set (match_dup 5)
3510 (unspec:DI [(match_dup 5) (match_dup 3)] UNSPEC_LDGP1))
3511 (use (match_dup 0))
3512 (use (match_dup 4))
3513 (clobber (reg:DI 26))])
3514 (set (match_dup 5)
3515 (unspec:DI [(match_dup 5) (match_dup 3)] UNSPEC_LDGP2))]
3516 {
3517 if (CONSTANT_P (operands[0]))
3518 {
3519 operands[2] = gen_rtx_REG (Pmode, 27);
3520 operands[4] = GEN_INT (alpha_next_sequence_number++);
3521 emit_insn (gen_movdi_er_high_g (operands[2], pic_offset_table_rtx,
3522 operands[0], operands[4]));
3523 }
3524 else
3525 {
3526 operands[2] = operands[0];
3527 operands[0] = const0_rtx;
3528 operands[4] = const0_rtx;
3529 }
3530 operands[3] = GEN_INT (alpha_next_sequence_number++);
3531 operands[5] = pic_offset_table_rtx;
3532 })
3533
3534 (define_insn "*call_osf_2_er_nogp"
3535 [(call (mem:DI (match_operand:DI 0 "register_operand" "c"))
3536 (match_operand 1))
3537 (use (reg:DI 29))
3538 (use (match_operand 2))
3539 (use (match_operand 3 "const_int_operand"))
3540 (clobber (reg:DI 26))]
3541 "TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF"
3542 "jsr $26,(%0),%2%J3"
3543 [(set_attr "type" "jsr")])
3544
3545 (define_insn "*call_osf_2_er"
3546 [(call (mem:DI (match_operand:DI 0 "register_operand" "c"))
3547 (match_operand 1))
3548 (set (reg:DI 29)
3549 (unspec:DI [(reg:DI 29) (match_operand 4 "const_int_operand")]
3550 UNSPEC_LDGP1))
3551 (use (match_operand 2))
3552 (use (match_operand 3 "const_int_operand"))
3553 (clobber (reg:DI 26))]
3554 "TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF"
3555 "jsr $26,(%0),%2%J3\;ldah $29,0($26)\t\t!gpdisp!%4"
3556 [(set_attr "type" "jsr")
3557 (set_attr "cannot_copy" "true")
3558 (set_attr "length" "8")])
3559
3560 (define_insn "*call_osf_1_noreturn"
3561 [(call (mem:DI (match_operand:DI 0 "call_operand" "c,R,s"))
3562 (match_operand 1))
3563 (use (reg:DI 29))
3564 (clobber (reg:DI 26))]
3565 "! TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF
3566 && find_reg_note (insn, REG_NORETURN, NULL_RTX)"
3567 "@
3568 jsr $26,($27),0
3569 bsr $26,$%0..ng
3570 jsr $26,%0"
3571 [(set_attr "type" "jsr")
3572 (set_attr "length" "*,*,8")])
3573
3574 (define_insn "*call_osf_1"
3575 [(call (mem:DI (match_operand:DI 0 "call_operand" "c,R,s"))
3576 (match_operand 1))
3577 (use (reg:DI 29))
3578 (clobber (reg:DI 26))]
3579 "! TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF"
3580 "@
3581 jsr $26,($27),0\;ldgp $29,0($26)
3582 bsr $26,$%0..ng
3583 jsr $26,%0\;ldgp $29,0($26)"
3584 [(set_attr "type" "jsr")
3585 (set_attr "length" "12,*,16")])
3586
3587 (define_insn "*sibcall_osf_1_er"
3588 [(call (mem:DI (match_operand:DI 0 "symbolic_operand" "R,s"))
3589 (match_operand 1))
3590 (unspec [(reg:DI 29)] UNSPEC_SIBCALL)]
3591 "TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF"
3592 "@
3593 br $31,%0\t\t!samegp
3594 ldq $27,%0($29)\t\t!literal!%#\;jmp $31,($27),%0\t\t!lituse_jsr!%#"
3595 [(set_attr "type" "jsr")
3596 (set_attr "length" "*,8")])
3597
3598 ;; Note that the DEC assembler expands "jmp foo" with $at, which
3599 ;; doesn't do what we want.
3600 (define_insn "*sibcall_osf_1"
3601 [(call (mem:DI (match_operand:DI 0 "symbolic_operand" "R,s"))
3602 (match_operand 1))
3603 (unspec [(reg:DI 29)] UNSPEC_SIBCALL)]
3604 "! TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF"
3605 "@
3606 br $31,$%0..ng
3607 lda $27,%0\;jmp $31,($27),%0"
3608 [(set_attr "type" "jsr")
3609 (set_attr "length" "*,8")])
3610
3611 ; GAS relies on the order and position of instructions output below in order
3612 ; to generate relocs for VMS link to potentially optimize the call.
3613 ; Please do not molest.
3614 (define_insn "*call_vms_1"
3615 [(call (mem:DI (match_operand:DI 0 "call_operand" "r,s"))
3616 (match_operand 1))
3617 (use (match_operand:DI 2 "nonmemory_operand" "r,n"))
3618 (use (reg:DI 25))
3619 (use (reg:DI 26))
3620 (clobber (reg:DI 27))]
3621 "TARGET_ABI_OPEN_VMS"
3622 {
3623 switch (which_alternative)
3624 {
3625 case 0:
3626 return "mov %2,$27\;jsr $26,0\;ldq $27,0($29)";
3627 case 1:
3628 operands [2] = alpha_use_linkage (operands [0], true, false);
3629 operands [3] = alpha_use_linkage (operands [0], false, false);
3630 return "ldq $26,%3\;ldq $27,%2\;jsr $26,%0\;ldq $27,0($29)";
3631 default:
3632 gcc_unreachable ();
3633 }
3634 }
3635 [(set_attr "type" "jsr")
3636 (set_attr "length" "12,16")])
3637
3638 ;; Call subroutine returning any type.
3639
3640 (define_expand "untyped_call"
3641 [(parallel [(call (match_operand 0)
3642 (const_int 0))
3643 (match_operand 1)
3644 (match_operand 2)])]
3645 ""
3646 {
3647 int i;
3648
3649 emit_call_insn (gen_call (operands[0], const0_rtx, NULL, const0_rtx));
3650
3651 for (i = 0; i < XVECLEN (operands[2], 0); i++)
3652 {
3653 rtx set = XVECEXP (operands[2], 0, i);
3654 emit_move_insn (SET_DEST (set), SET_SRC (set));
3655 }
3656
3657 /* The optimizer does not know that the call sets the function value
3658 registers we stored in the result block. We avoid problems by
3659 claiming that all hard registers are used and clobbered at this
3660 point. */
3661 emit_insn (gen_blockage ());
3662
3663 DONE;
3664 })
3665
3666 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
3667 ;; all of memory. This blocks insns from being moved across this point.
3668
3669 (define_insn "blockage"
3670 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
3671 ""
3672 ""
3673 [(set_attr "length" "0")
3674 (set_attr "type" "none")])
3675
3676 (define_insn "jump"
3677 [(set (pc)
3678 (label_ref (match_operand 0)))]
3679 ""
3680 "br $31,%l0"
3681 [(set_attr "type" "ibr")])
3682
3683 (define_expand "return"
3684 [(return)]
3685 "direct_return ()")
3686
3687 (define_insn "*return_internal"
3688 [(return)]
3689 "reload_completed"
3690 "ret $31,($26),1"
3691 [(set_attr "type" "ibr")])
3692
3693 (define_insn "indirect_jump"
3694 [(set (pc) (match_operand:DI 0 "register_operand" "r"))]
3695 ""
3696 "jmp $31,(%0),0"
3697 [(set_attr "type" "ibr")])
3698
3699 (define_expand "tablejump"
3700 [(parallel [(set (pc)
3701 (match_operand 0 "register_operand"))
3702 (use (label_ref:DI (match_operand 1)))])]
3703 ""
3704 {
3705 if (TARGET_ABI_OSF)
3706 {
3707 rtx dest = gen_reg_rtx (DImode);
3708 emit_insn (gen_extendsidi2 (dest, operands[0]));
3709 emit_insn (gen_adddi3 (dest, pic_offset_table_rtx, dest));
3710 operands[0] = dest;
3711 }
3712 })
3713
3714 (define_insn "*tablejump_internal"
3715 [(set (pc)
3716 (match_operand:DI 0 "register_operand" "r"))
3717 (use (label_ref (match_operand 1)))]
3718 ""
3719 "jmp $31,(%0),0"
3720 [(set_attr "type" "ibr")])
3721
3722 ;; Cache flush. Used by alpha_trampoline_init. 0x86 is PAL_imb, but we don't
3723 ;; want to have to include pal.h in our .s file.
3724 (define_insn "imb"
3725 [(unspec_volatile [(const_int 0)] UNSPECV_IMB)]
3726 ""
3727 "call_pal 0x86"
3728 [(set_attr "type" "callpal")])
3729
3730 (define_expand "clear_cache"
3731 [(match_operand:DI 0) ; region start
3732 (match_operand:DI 1)] ; region end
3733 ""
3734 {
3735 emit_insn (gen_imb ());
3736 DONE;
3737 })
3738
3739 ;; BUGCHK is documented common to OSF/1 and VMS PALcode.
3740 (define_insn "trap"
3741 [(trap_if (const_int 1) (const_int 0))]
3742 ""
3743 "call_pal 0x81"
3744 [(set_attr "type" "callpal")])
3745
3746 ;; For userland, we load the thread pointer from the TCB.
3747 ;; For the kernel, we load the per-cpu private value.
3748
3749 (define_insn "get_thread_pointerdi"
3750 [(set (match_operand:DI 0 "register_operand" "=v")
3751 (unspec:DI [(const_int 0)] UNSPEC_TP))]
3752 "TARGET_ABI_OSF"
3753 {
3754 if (TARGET_TLS_KERNEL)
3755 return "call_pal 0x32";
3756 else
3757 return "call_pal 0x9e";
3758 }
3759 [(set_attr "type" "callpal")])
3760
3761 ;; For completeness, and possibly a __builtin function, here's how to
3762 ;; set the thread pointer. Since we don't describe enough of this
3763 ;; quantity for CSE, we have to use a volatile unspec, and then there's
3764 ;; not much point in creating an R16_REG register class.
3765
3766 (define_expand "set_thread_pointerdi"
3767 [(set (reg:DI 16) (match_operand:DI 0 "input_operand"))
3768 (unspec_volatile [(reg:DI 16)] UNSPECV_SET_TP)]
3769 "TARGET_ABI_OSF")
3770
3771 (define_insn "*set_tp"
3772 [(unspec_volatile [(reg:DI 16)] UNSPECV_SET_TP)]
3773 "TARGET_ABI_OSF"
3774 {
3775 if (TARGET_TLS_KERNEL)
3776 return "call_pal 0x31";
3777 else
3778 return "call_pal 0x9f";
3779 }
3780 [(set_attr "type" "callpal")])
3781
3782 ;; Special builtins for establishing and reverting VMS condition handlers.
3783
3784 (define_expand "builtin_establish_vms_condition_handler"
3785 [(set (reg:DI 0) (match_operand:DI 0 "register_operand"))
3786 (use (match_operand:DI 1 "address_operand"))]
3787 "TARGET_ABI_OPEN_VMS"
3788 {
3789 alpha_expand_builtin_establish_vms_condition_handler (operands[0],
3790 operands[1]);
3791 })
3792
3793 (define_expand "builtin_revert_vms_condition_handler"
3794 [(set (reg:DI 0) (match_operand:DI 0 "register_operand"))]
3795 "TARGET_ABI_OPEN_VMS"
3796 "alpha_expand_builtin_revert_vms_condition_handler (operands[0]);")
3797 \f
3798 ;; Finally, we have the basic data motion insns. The byte and word insns
3799 ;; are done via define_expand. Start with the floating-point insns, since
3800 ;; they are simpler.
3801
3802 (define_expand "movsf"
3803 [(set (match_operand:SF 0 "nonimmediate_operand")
3804 (match_operand:SF 1 "general_operand"))]
3805 ""
3806 {
3807 if (MEM_P (operands[0])
3808 && ! reg_or_0_operand (operands[1], SFmode))
3809 operands[1] = force_reg (SFmode, operands[1]);
3810 })
3811
3812 (define_insn "*movsf"
3813 [(set (match_operand:SF 0 "nonimmediate_operand" "=f,f,*r,*r,m,m,f,*r")
3814 (match_operand:SF 1 "input_operand" "fG,m,*rG,m,fG,*r,*r,f"))]
3815 "register_operand (operands[0], SFmode)
3816 || reg_or_0_operand (operands[1], SFmode)"
3817 "@
3818 cpys %R1,%R1,%0
3819 ld%, %0,%1
3820 bis $31,%r1,%0
3821 ldl %0,%1
3822 st%, %R1,%0
3823 stl %r1,%0
3824 itofs %1,%0
3825 ftois %1,%0"
3826 [(set_attr "type" "fcpys,fld,ilog,ild,fst,ist,itof,ftoi")
3827 (set_attr "isa" "*,*,*,*,*,*,fix,fix")])
3828
3829 (define_expand "movdf"
3830 [(set (match_operand:DF 0 "nonimmediate_operand")
3831 (match_operand:DF 1 "general_operand"))]
3832 ""
3833 {
3834 if (MEM_P (operands[0])
3835 && ! reg_or_0_operand (operands[1], DFmode))
3836 operands[1] = force_reg (DFmode, operands[1]);
3837 })
3838
3839 (define_insn "*movdf"
3840 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,f,*r,*r,m,m,f,*r")
3841 (match_operand:DF 1 "input_operand" "fG,m,*rG,m,fG,*r,*r,f"))]
3842 "register_operand (operands[0], DFmode)
3843 || reg_or_0_operand (operands[1], DFmode)"
3844 "@
3845 cpys %R1,%R1,%0
3846 ld%- %0,%1
3847 bis $31,%r1,%0
3848 ldq %0,%1
3849 st%- %R1,%0
3850 stq %r1,%0
3851 itoft %1,%0
3852 ftoit %1,%0"
3853 [(set_attr "type" "fcpys,fld,ilog,ild,fst,ist,itof,ftoi")
3854 (set_attr "isa" "*,*,*,*,*,*,fix,fix")])
3855
3856 ;; Subregs suck for register allocation. Pretend we can move TFmode
3857 ;; data between general registers until after reload.
3858 ;; ??? Is this still true now that we have the lower-subreg pass?
3859
3860 (define_expand "movtf"
3861 [(set (match_operand:TF 0 "nonimmediate_operand")
3862 (match_operand:TF 1 "general_operand"))]
3863 ""
3864 {
3865 if (MEM_P (operands[0])
3866 && ! reg_or_0_operand (operands[1], TFmode))
3867 operands[1] = force_reg (TFmode, operands[1]);
3868 })
3869
3870 (define_insn_and_split "*movtf_internal"
3871 [(set (match_operand:TF 0 "nonimmediate_operand" "=r,o")
3872 (match_operand:TF 1 "input_operand" "roG,rG"))]
3873 "register_operand (operands[0], TFmode)
3874 || reg_or_0_operand (operands[1], TFmode)"
3875 "#"
3876 "reload_completed"
3877 [(set (match_dup 0) (match_dup 2))
3878 (set (match_dup 1) (match_dup 3))]
3879 "alpha_split_tmode_pair (operands, TFmode, true);")
3880
3881 ;; We do two major things here: handle mem->mem and construct long
3882 ;; constants.
3883
3884 (define_expand "movsi"
3885 [(set (match_operand:SI 0 "nonimmediate_operand")
3886 (match_operand:SI 1 "general_operand"))]
3887 ""
3888 {
3889 if (alpha_expand_mov (SImode, operands))
3890 DONE;
3891 })
3892
3893 (define_insn "*movsi"
3894 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,r,r,r,m,r")
3895 (match_operand:SI 1 "input_operand" "rJ,K,L,n,m,rJ,s"))]
3896 "register_operand (operands[0], SImode)
3897 || reg_or_0_operand (operands[1], SImode)"
3898 "@
3899 bis $31,%r1,%0
3900 lda %0,%1($31)
3901 ldah %0,%h1($31)
3902 #
3903 ldl %0,%1
3904 stl %r1,%0
3905 lda %0,%1"
3906 [(set_attr "type" "ilog,iadd,iadd,multi,ild,ist,ldsym")
3907 (set_attr "isa" "*,*,*,*,*,*,vms")])
3908
3909 ;; Split a load of a large constant into the appropriate two-insn
3910 ;; sequence.
3911
3912 (define_split
3913 [(set (match_operand:SI 0 "register_operand")
3914 (match_operand:SI 1 "non_add_const_operand"))]
3915 ""
3916 [(const_int 0)]
3917 {
3918 if (alpha_split_const_mov (SImode, operands))
3919 DONE;
3920 else
3921 FAIL;
3922 })
3923
3924 (define_insn "*movdi_er_low_l"
3925 [(set (match_operand:DI 0 "register_operand" "=r")
3926 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
3927 (match_operand:DI 2 "local_symbolic_operand")))]
3928 "TARGET_EXPLICIT_RELOCS"
3929 {
3930 if (true_regnum (operands[1]) == 29)
3931 return "lda %0,%2(%1)\t\t!gprel";
3932 else
3933 return "lda %0,%2(%1)\t\t!gprellow";
3934 }
3935 [(set_attr "usegp" "yes")])
3936
3937 (define_split
3938 [(set (match_operand:DI 0 "register_operand")
3939 (match_operand:DI 1 "small_symbolic_operand"))]
3940 "TARGET_EXPLICIT_RELOCS && reload_completed"
3941 [(set (match_dup 0)
3942 (lo_sum:DI (match_dup 2) (match_dup 1)))]
3943 "operands[2] = pic_offset_table_rtx;")
3944
3945 (define_split
3946 [(set (match_operand:DI 0 "register_operand")
3947 (match_operand:DI 1 "local_symbolic_operand"))]
3948 "TARGET_EXPLICIT_RELOCS && reload_completed"
3949 [(set (match_dup 0)
3950 (plus:DI (match_dup 2) (high:DI (match_dup 1))))
3951 (set (match_dup 0)
3952 (lo_sum:DI (match_dup 0) (match_dup 1)))]
3953 "operands[2] = pic_offset_table_rtx;")
3954
3955 (define_split
3956 [(match_operand 0 "some_small_symbolic_operand")]
3957 ""
3958 [(match_dup 0)]
3959 "operands[0] = split_small_symbolic_operand (operands[0]);")
3960
3961 ;; Accepts any symbolic, not just global, since function calls that
3962 ;; don't go via bsr still use !literal in hopes of linker relaxation.
3963 (define_insn "movdi_er_high_g"
3964 [(set (match_operand:DI 0 "register_operand" "=r")
3965 (unspec:DI [(match_operand:DI 1 "register_operand" "r")
3966 (match_operand:DI 2 "symbolic_operand")
3967 (match_operand 3 "const_int_operand")]
3968 UNSPEC_LITERAL))]
3969 "TARGET_EXPLICIT_RELOCS"
3970 {
3971 if (INTVAL (operands[3]) == 0)
3972 return "ldq %0,%2(%1)\t\t!literal";
3973 else
3974 return "ldq %0,%2(%1)\t\t!literal!%3";
3975 }
3976 [(set_attr "type" "ldsym")])
3977
3978 (define_split
3979 [(set (match_operand:DI 0 "register_operand")
3980 (match_operand:DI 1 "global_symbolic_operand"))]
3981 "TARGET_EXPLICIT_RELOCS && reload_completed"
3982 [(set (match_dup 0)
3983 (unspec:DI [(match_dup 2)
3984 (match_dup 1)
3985 (const_int 0)] UNSPEC_LITERAL))]
3986 "operands[2] = pic_offset_table_rtx;")
3987
3988 (define_insn "movdi_er_tlsgd"
3989 [(set (match_operand:DI 0 "register_operand" "=r")
3990 (unspec:DI [(match_operand:DI 1 "register_operand" "r")
3991 (match_operand:DI 2 "symbolic_operand")
3992 (match_operand 3 "const_int_operand")]
3993 UNSPEC_TLSGD))]
3994 "HAVE_AS_TLS"
3995 {
3996 if (INTVAL (operands[3]) == 0)
3997 return "lda %0,%2(%1)\t\t!tlsgd";
3998 else
3999 return "lda %0,%2(%1)\t\t!tlsgd!%3";
4000 })
4001
4002 (define_insn "movdi_er_tlsldm"
4003 [(set (match_operand:DI 0 "register_operand" "=r")
4004 (unspec:DI [(match_operand:DI 1 "register_operand" "r")
4005 (match_operand 2 "const_int_operand")]
4006 UNSPEC_TLSLDM))]
4007 "HAVE_AS_TLS"
4008 {
4009 if (INTVAL (operands[2]) == 0)
4010 return "lda %0,%&(%1)\t\t!tlsldm";
4011 else
4012 return "lda %0,%&(%1)\t\t!tlsldm!%2";
4013 })
4014
4015 (define_insn "*movdi_er_gotdtp"
4016 [(set (match_operand:DI 0 "register_operand" "=r")
4017 (unspec:DI [(match_operand:DI 1 "register_operand" "r")
4018 (match_operand:DI 2 "symbolic_operand")]
4019 UNSPEC_DTPREL))]
4020 "HAVE_AS_TLS"
4021 "ldq %0,%2(%1)\t\t!gotdtprel"
4022 [(set_attr "type" "ild")
4023 (set_attr "usegp" "yes")])
4024
4025 (define_split
4026 [(set (match_operand:DI 0 "register_operand")
4027 (match_operand:DI 1 "gotdtp_symbolic_operand"))]
4028 "HAVE_AS_TLS && reload_completed"
4029 [(set (match_dup 0)
4030 (unspec:DI [(match_dup 2)
4031 (match_dup 1)] UNSPEC_DTPREL))]
4032 {
4033 operands[1] = XVECEXP (XEXP (operands[1], 0), 0, 0);
4034 operands[2] = pic_offset_table_rtx;
4035 })
4036
4037 (define_insn "*movdi_er_gottp"
4038 [(set (match_operand:DI 0 "register_operand" "=r")
4039 (unspec:DI [(match_operand:DI 1 "register_operand" "r")
4040 (match_operand:DI 2 "symbolic_operand")]
4041 UNSPEC_TPREL))]
4042 "HAVE_AS_TLS"
4043 "ldq %0,%2(%1)\t\t!gottprel"
4044 [(set_attr "type" "ild")
4045 (set_attr "usegp" "yes")])
4046
4047 (define_split
4048 [(set (match_operand:DI 0 "register_operand")
4049 (match_operand:DI 1 "gottp_symbolic_operand"))]
4050 "HAVE_AS_TLS && reload_completed"
4051 [(set (match_dup 0)
4052 (unspec:DI [(match_dup 2)
4053 (match_dup 1)] UNSPEC_TPREL))]
4054 {
4055 operands[1] = XVECEXP (XEXP (operands[1], 0), 0, 0);
4056 operands[2] = pic_offset_table_rtx;
4057 })
4058
4059 (define_insn "*movdi"
4060 [(set (match_operand:DI 0 "nonimmediate_operand"
4061 "=r,r,r,r,r,r,r,r, m, *f,*f, Q, r,*f")
4062 (match_operand:DI 1 "input_operand"
4063 "rJ,K,L,T,s,n,s,m,rJ,*fJ, Q,*f,*f, r"))]
4064 "register_operand (operands[0], DImode)
4065 || reg_or_0_operand (operands[1], DImode)"
4066 "@
4067 mov %r1,%0
4068 lda %0,%1($31)
4069 ldah %0,%h1($31)
4070 #
4071 #
4072 #
4073 lda %0,%1
4074 ldq%A1 %0,%1
4075 stq%A0 %r1,%0
4076 fmov %R1,%0
4077 ldt %0,%1
4078 stt %R1,%0
4079 ftoit %1,%0
4080 itoft %1,%0"
4081 [(set_attr "type" "ilog,iadd,iadd,iadd,ldsym,multi,ldsym,ild,ist,fcpys,fld,fst,ftoi,itof")
4082 (set_attr "isa" "*,*,*,er,er,*,ner,*,*,*,*,*,fix,fix")
4083 (set_attr "usegp" "*,*,*,yes,*,*,*,*,*,*,*,*,*,*")])
4084
4085 ;; VMS needs to set up "vms_base_regno" for unwinding. This move
4086 ;; often appears dead to the life analysis code, at which point we
4087 ;; die for emitting dead prologue instructions. Force this live.
4088
4089 (define_insn "force_movdi"
4090 [(set (match_operand:DI 0 "register_operand" "=r")
4091 (unspec_volatile:DI [(match_operand:DI 1 "register_operand" "r")]
4092 UNSPECV_FORCE_MOV))]
4093 ""
4094 "mov %1,%0"
4095 [(set_attr "type" "ilog")])
4096
4097 ;; We do three major things here: handle mem->mem, put 64-bit constants in
4098 ;; memory, and construct long 32-bit constants.
4099
4100 (define_expand "movdi"
4101 [(set (match_operand:DI 0 "nonimmediate_operand")
4102 (match_operand:DI 1 "general_operand"))]
4103 ""
4104 {
4105 if (alpha_expand_mov (DImode, operands))
4106 DONE;
4107 })
4108
4109 ;; Split a load of a large constant into the appropriate two-insn
4110 ;; sequence.
4111
4112 (define_split
4113 [(set (match_operand:DI 0 "register_operand")
4114 (match_operand:DI 1 "non_add_const_operand"))]
4115 ""
4116 [(const_int 0)]
4117 {
4118 if (alpha_split_const_mov (DImode, operands))
4119 DONE;
4120 else
4121 FAIL;
4122 })
4123
4124 ;; We need to prevent reload from splitting TImode moves, because it
4125 ;; might decide to overwrite a pointer with the value it points to.
4126 ;; In that case we have to do the loads in the appropriate order so
4127 ;; that the pointer is not destroyed too early.
4128
4129 (define_insn_and_split "*movti_internal"
4130 [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o")
4131 (match_operand:TI 1 "input_operand" "roJ,rJ"))]
4132 "(register_operand (operands[0], TImode)
4133 /* Prevent rematerialization of constants. */
4134 && ! CONSTANT_P (operands[1]))
4135 || reg_or_0_operand (operands[1], TImode)"
4136 "#"
4137 "reload_completed"
4138 [(set (match_dup 0) (match_dup 2))
4139 (set (match_dup 1) (match_dup 3))]
4140 "alpha_split_tmode_pair (operands, TImode, true);")
4141
4142 (define_expand "movti"
4143 [(set (match_operand:TI 0 "nonimmediate_operand")
4144 (match_operand:TI 1 "general_operand"))]
4145 ""
4146 {
4147 if (MEM_P (operands[0])
4148 && ! reg_or_0_operand (operands[1], TImode))
4149 operands[1] = force_reg (TImode, operands[1]);
4150
4151 if (operands[1] == const0_rtx)
4152 ;
4153 /* We must put 64-bit constants in memory. We could keep the
4154 32-bit constants in TImode and rely on the splitter, but
4155 this doesn't seem to be worth the pain. */
4156 else if (CONST_SCALAR_INT_P (operands[1]))
4157 {
4158 rtx in[2], out[2], target;
4159
4160 gcc_assert (can_create_pseudo_p ());
4161
4162 split_double (operands[1], &in[0], &in[1]);
4163
4164 if (in[0] == const0_rtx)
4165 out[0] = const0_rtx;
4166 else
4167 {
4168 out[0] = gen_reg_rtx (DImode);
4169 emit_insn (gen_movdi (out[0], in[0]));
4170 }
4171
4172 if (in[1] == const0_rtx)
4173 out[1] = const0_rtx;
4174 else
4175 {
4176 out[1] = gen_reg_rtx (DImode);
4177 emit_insn (gen_movdi (out[1], in[1]));
4178 }
4179
4180 if (!REG_P (operands[0]))
4181 target = gen_reg_rtx (TImode);
4182 else
4183 target = operands[0];
4184
4185 emit_insn (gen_movdi (operand_subword (target, 0, 0, TImode), out[0]));
4186 emit_insn (gen_movdi (operand_subword (target, 1, 0, TImode), out[1]));
4187
4188 if (target != operands[0])
4189 emit_insn (gen_rtx_SET (operands[0], target));
4190
4191 DONE;
4192 }
4193 })
4194
4195 ;; These are the partial-word cases.
4196 ;;
4197 ;; First we have the code to load an aligned word. Operand 0 is the register
4198 ;; in which to place the result. It's mode is QImode or HImode. Operand 1
4199 ;; is an SImode MEM at the low-order byte of the proper word. Operand 2 is the
4200 ;; number of bits within the word that the value is. Operand 3 is an SImode
4201 ;; scratch register. If operand 0 is a hard register, operand 3 may be the
4202 ;; same register. It is allowed to conflict with operand 1 as well.
4203
4204 (define_expand "aligned_loadqi"
4205 [(set (match_operand:SI 3 "register_operand")
4206 (match_operand:SI 1 "memory_operand"))
4207 (set (match_operand:DI 0 "register_operand")
4208 (zero_extract:DI (subreg:DI (match_dup 3) 0)
4209 (const_int 8)
4210 (match_operand:DI 2 "const_int_operand")))])
4211
4212 (define_expand "aligned_loadhi"
4213 [(set (match_operand:SI 3 "register_operand")
4214 (match_operand:SI 1 "memory_operand"))
4215 (set (match_operand:DI 0 "register_operand")
4216 (zero_extract:DI (subreg:DI (match_dup 3) 0)
4217 (const_int 16)
4218 (match_operand:DI 2 "const_int_operand")))])
4219
4220 ;; Similar for unaligned loads, where we use the sequence from the
4221 ;; Alpha Architecture manual. We have to distinguish between little-endian
4222 ;; and big-endian systems as the sequences are different.
4223 ;;
4224 ;; Operand 1 is the address. Operands 2 and 3 are temporaries, where
4225 ;; operand 3 can overlap the input and output registers.
4226
4227 (define_expand "unaligned_loadqi"
4228 [(set (match_operand:DI 2 "register_operand")
4229 (mem:DI (and:DI (match_operand:DI 1 "address_operand")
4230 (const_int -8))))
4231 (set (match_operand:DI 3 "register_operand")
4232 (match_dup 1))
4233 (set (match_operand:DI 0 "register_operand")
4234 (zero_extract:DI (match_dup 2)
4235 (const_int 8)
4236 (ashift:DI (match_dup 3) (const_int 3))))])
4237
4238 (define_expand "unaligned_loadhi"
4239 [(set (match_operand:DI 2 "register_operand")
4240 (mem:DI (and:DI (match_operand:DI 1 "address_operand")
4241 (const_int -8))))
4242 (set (match_operand:DI 3 "register_operand")
4243 (match_dup 1))
4244 (set (match_operand:DI 0 "register_operand")
4245 (zero_extract:DI (match_dup 2)
4246 (const_int 16)
4247 (ashift:DI (match_dup 3) (const_int 3))))])
4248
4249 ;; Storing an aligned byte or word requires two temporaries. Operand 0 is the
4250 ;; aligned SImode MEM. Operand 1 is the register containing the
4251 ;; byte or word to store. Operand 2 is the number of bits within the word that
4252 ;; the value should be placed. Operands 3 and 4 are SImode temporaries.
4253
4254 (define_expand "aligned_store"
4255 [(set (match_operand:SI 3 "register_operand")
4256 (match_operand:SI 0 "memory_operand"))
4257 (set (subreg:DI (match_dup 3) 0)
4258 (and:DI (subreg:DI (match_dup 3) 0) (match_dup 5)))
4259 (set (subreg:DI (match_operand:SI 4 "register_operand") 0)
4260 (ashift:DI (zero_extend:DI (match_operand 1 "register_operand"))
4261 (match_operand:DI 2 "const_int_operand")))
4262 (set (subreg:DI (match_dup 4) 0)
4263 (ior:DI (subreg:DI (match_dup 4) 0) (subreg:DI (match_dup 3) 0)))
4264 (set (match_dup 0) (match_dup 4))]
4265 ""
4266 {
4267 operands[5] = GEN_INT (~ (GET_MODE_MASK (GET_MODE (operands[1]))
4268 << INTVAL (operands[2])));
4269 })
4270
4271 ;; For the unaligned byte and halfword cases, we use code similar to that
4272 ;; in the ;; Architecture book, but reordered to lower the number of registers
4273 ;; required. Operand 0 is the address. Operand 1 is the data to store.
4274 ;; Operands 2, 3, and 4 are DImode temporaries, where operands 2 and 4 may
4275 ;; be the same temporary, if desired. If the address is in a register,
4276 ;; operand 2 can be that register.
4277
4278 (define_expand "unaligned_store<mode>"
4279 [(set (match_operand:DI 3 "register_operand")
4280 (mem:DI (and:DI (match_operand:DI 0 "address_operand")
4281 (const_int -8))))
4282 (set (match_operand:DI 2 "register_operand")
4283 (match_dup 0))
4284 (set (match_dup 3)
4285 (and:DI (not:DI (ashift:DI (match_dup 5)
4286 (ashift:DI (match_dup 2) (const_int 3))))
4287 (match_dup 3)))
4288 (set (match_operand:DI 4 "register_operand")
4289 (ashift:DI (zero_extend:DI
4290 (match_operand:I12MODE 1 "register_operand"))
4291 (ashift:DI (match_dup 2) (const_int 3))))
4292 (set (match_dup 4) (ior:DI (match_dup 4) (match_dup 3)))
4293 (set (mem:DI (and:DI (match_dup 0) (const_int -8)))
4294 (match_dup 4))]
4295 ""
4296 "operands[5] = GEN_INT (GET_MODE_MASK (<MODE>mode));")
4297
4298 ;; Here are the define_expand's for QI and HI moves that use the above
4299 ;; patterns. We have the normal sets, plus the ones that need scratch
4300 ;; registers for reload.
4301
4302 (define_expand "mov<mode>"
4303 [(set (match_operand:I12MODE 0 "nonimmediate_operand")
4304 (match_operand:I12MODE 1 "general_operand"))]
4305 ""
4306 {
4307 if (TARGET_BWX
4308 ? alpha_expand_mov (<MODE>mode, operands)
4309 : alpha_expand_mov_nobwx (<MODE>mode, operands))
4310 DONE;
4311 })
4312
4313 (define_insn "*movqi"
4314 [(set (match_operand:QI 0 "nonimmediate_operand" "=r,r,r,m")
4315 (match_operand:QI 1 "input_operand" "rJ,n,m,rJ"))]
4316 "register_operand (operands[0], QImode)
4317 || reg_or_0_operand (operands[1], QImode)"
4318 "@
4319 bis $31,%r1,%0
4320 lda %0,%L1($31)
4321 ldbu %0,%1
4322 stb %r1,%0"
4323 [(set_attr "type" "ilog,iadd,ild,ist")
4324 (set_attr "isa" "*,*,bwx,bwx")])
4325
4326 (define_insn "*movhi"
4327 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
4328 (match_operand:HI 1 "input_operand" "rJ,n,m,rJ"))]
4329 "register_operand (operands[0], HImode)
4330 || reg_or_0_operand (operands[1], HImode)"
4331 "@
4332 bis $31,%r1,%0
4333 lda %0,%L1($31)
4334 ldwu %0,%1
4335 stw %r1,%0"
4336 [(set_attr "type" "ilog,iadd,ild,ist")
4337 (set_attr "isa" "*,*,bwx,bwx")])
4338
4339 ;; We need to hook into the extra support that we have for HImode
4340 ;; reloads when BWX insns are not available.
4341 (define_expand "movcqi"
4342 [(set (match_operand:CQI 0 "nonimmediate_operand")
4343 (match_operand:CQI 1 "general_operand"))]
4344 "!TARGET_BWX"
4345 {
4346 if (GET_CODE (operands[0]) == CONCAT || GET_CODE (operands[1]) == CONCAT)
4347 ;
4348 else if (!any_memory_operand (operands[0], CQImode))
4349 {
4350 if (!any_memory_operand (operands[1], CQImode))
4351 {
4352 emit_move_insn (gen_lowpart (HImode, operands[0]),
4353 gen_lowpart (HImode, operands[1]));
4354 DONE;
4355 }
4356 if (aligned_memory_operand (operands[1], CQImode))
4357 {
4358 bool done;
4359 do_aligned1:
4360 operands[1] = gen_lowpart (HImode, operands[1]);
4361 do_aligned2:
4362 operands[0] = gen_lowpart (HImode, operands[0]);
4363 done = alpha_expand_mov_nobwx (HImode, operands);
4364 gcc_assert (done);
4365 DONE;
4366 }
4367 }
4368 else if (aligned_memory_operand (operands[0], CQImode))
4369 {
4370 if (MEM_P (operands[1]))
4371 {
4372 rtx x = gen_reg_rtx (HImode);
4373 emit_move_insn (gen_lowpart (CQImode, x), operands[1]);
4374 operands[1] = x;
4375 goto do_aligned2;
4376 }
4377 goto do_aligned1;
4378 }
4379
4380 gcc_assert (!reload_in_progress);
4381 emit_move_complex_parts (operands[0], operands[1]);
4382 DONE;
4383 })
4384
4385 ;; Here are the versions for reload.
4386 ;;
4387 ;; The aligned input case is recognized early in alpha_secondary_reload
4388 ;; in order to avoid allocating an unnecessary scratch register.
4389 ;;
4390 ;; Note that in the unaligned cases we know that the operand must not be
4391 ;; a pseudo-register because stack slots are always aligned references.
4392
4393 (define_expand "reload_in<mode>"
4394 [(parallel [(match_operand:RELOAD12 0 "register_operand" "=r")
4395 (match_operand:RELOAD12 1 "any_memory_operand" "m")
4396 (match_operand:TI 2 "register_operand" "=&r")])]
4397 "!TARGET_BWX"
4398 {
4399 rtx scratch, seq, addr;
4400 unsigned regno = REGNO (operands[2]);
4401
4402 /* It is possible that one of the registers we got for operands[2]
4403 might coincide with that of operands[0] (which is why we made
4404 it TImode). Pick the other one to use as our scratch. */
4405 if (regno == REGNO (operands[0]))
4406 regno++;
4407 scratch = gen_rtx_REG (DImode, regno);
4408
4409 addr = get_unaligned_address (operands[1]);
4410 operands[0] = gen_rtx_REG (DImode, REGNO (operands[0]));
4411 seq = gen_unaligned_load<reloadmode> (operands[0], addr,
4412 scratch, operands[0]);
4413 alpha_set_memflags (seq, operands[1]);
4414
4415 emit_insn (seq);
4416 DONE;
4417 })
4418
4419 (define_expand "reload_out<mode>"
4420 [(parallel [(match_operand:RELOAD12 0 "any_memory_operand" "=m")
4421 (match_operand:RELOAD12 1 "register_operand" "r")
4422 (match_operand:TI 2 "register_operand" "=&r")])]
4423 "!TARGET_BWX"
4424 {
4425 unsigned regno = REGNO (operands[2]);
4426
4427 if (<MODE>mode == CQImode)
4428 {
4429 operands[0] = gen_lowpart (HImode, operands[0]);
4430 operands[1] = gen_lowpart (HImode, operands[1]);
4431 }
4432
4433 if (aligned_memory_operand (operands[0], <MODE>mode))
4434 {
4435 emit_insn (gen_reload_out<reloadmode>_aligned
4436 (operands[0], operands[1],
4437 gen_rtx_REG (SImode, regno),
4438 gen_rtx_REG (SImode, regno + 1)));
4439 }
4440 else
4441 {
4442 rtx addr = get_unaligned_address (operands[0]);
4443 rtx scratch1 = gen_rtx_REG (DImode, regno);
4444 rtx scratch2 = gen_rtx_REG (DImode, regno + 1);
4445 rtx scratch3 = scratch1;
4446 rtx seq;
4447
4448 if (REG_P (addr))
4449 scratch1 = addr;
4450
4451 seq = gen_unaligned_store<reloadmode> (addr, operands[1], scratch1,
4452 scratch2, scratch3);
4453 alpha_set_memflags (seq, operands[0]);
4454 emit_insn (seq);
4455 }
4456 DONE;
4457 })
4458
4459 ;; Helpers for the above. The way reload is structured, we can't
4460 ;; always get a proper address for a stack slot during reload_foo
4461 ;; expansion, so we must delay our address manipulations until after.
4462
4463 (define_insn_and_split "reload_in<mode>_aligned"
4464 [(set (match_operand:I12MODE 0 "register_operand" "=r")
4465 (match_operand:I12MODE 1 "memory_operand" "m"))]
4466 "!TARGET_BWX && (reload_in_progress || reload_completed)"
4467 "#"
4468 "!TARGET_BWX && reload_completed"
4469 [(const_int 0)]
4470 {
4471 rtx aligned_mem, bitnum;
4472 get_aligned_mem (operands[1], &aligned_mem, &bitnum);
4473 emit_insn (gen_aligned_load<reloadmode>
4474 (gen_lowpart (DImode, operands[0]), aligned_mem, bitnum,
4475 gen_rtx_REG (SImode, REGNO (operands[0]))));
4476 DONE;
4477 })
4478
4479 (define_insn_and_split "reload_out<mode>_aligned"
4480 [(set (match_operand:I12MODE 0 "memory_operand" "=m")
4481 (match_operand:I12MODE 1 "register_operand" "r"))
4482 (clobber (match_operand:SI 2 "register_operand" "=&r"))
4483 (clobber (match_operand:SI 3 "register_operand" "=&r"))]
4484 "!TARGET_BWX && (reload_in_progress || reload_completed)"
4485 "#"
4486 "!TARGET_BWX && reload_completed"
4487 [(const_int 0)]
4488 {
4489 rtx aligned_mem, bitnum;
4490 get_aligned_mem (operands[0], &aligned_mem, &bitnum);
4491 emit_insn (gen_aligned_store (aligned_mem, operands[1], bitnum,
4492 operands[2], operands[3]));
4493 DONE;
4494 })
4495 \f
4496 ;; Vector operations
4497
4498 (define_mode_iterator VEC [V8QI V4HI V2SI])
4499 (define_mode_iterator VEC12 [V8QI V4HI])
4500
4501 (define_expand "mov<mode>"
4502 [(set (match_operand:VEC 0 "nonimmediate_operand")
4503 (match_operand:VEC 1 "general_operand"))]
4504 ""
4505 {
4506 if (alpha_expand_mov (<MODE>mode, operands))
4507 DONE;
4508 })
4509
4510 (define_split
4511 [(set (match_operand:VEC 0 "register_operand")
4512 (match_operand:VEC 1 "non_zero_const_operand"))]
4513 ""
4514 [(const_int 0)]
4515 {
4516 if (alpha_split_const_mov (<MODE>mode, operands))
4517 DONE;
4518 else
4519 FAIL;
4520 })
4521
4522
4523 (define_expand "movmisalign<mode>"
4524 [(set (match_operand:VEC 0 "nonimmediate_operand")
4525 (match_operand:VEC 1 "general_operand"))]
4526 ""
4527 {
4528 alpha_expand_movmisalign (<MODE>mode, operands);
4529 DONE;
4530 })
4531
4532 (define_insn "*mov<mode>_fix"
4533 [(set (match_operand:VEC 0 "nonimmediate_operand" "=r,r,r,m,*f,*f,m,r,*f")
4534 (match_operand:VEC 1 "input_operand" "rW,i,m,rW,*fW,m,*f,*f,r"))]
4535 "register_operand (operands[0], <MODE>mode)
4536 || reg_or_0_operand (operands[1], <MODE>mode)"
4537 "@
4538 bis $31,%r1,%0
4539 #
4540 ldq %0,%1
4541 stq %r1,%0
4542 cpys %R1,%R1,%0
4543 ldt %0,%1
4544 stt %R1,%0
4545 ftoit %1,%0
4546 itoft %1,%0"
4547 [(set_attr "type" "ilog,multi,ild,ist,fcpys,fld,fst,ftoi,itof")
4548 (set_attr "isa" "*,*,*,*,*,*,*,fix,fix")])
4549
4550 (define_insn "<code><mode>3"
4551 [(set (match_operand:VEC12 0 "register_operand" "=r")
4552 (any_maxmin:VEC12
4553 (match_operand:VEC12 1 "reg_or_0_operand" "rW")
4554 (match_operand:VEC12 2 "reg_or_0_operand" "rW")))]
4555 "TARGET_MAX"
4556 "<maxmin><modesuffix> %r1,%r2,%0"
4557 [(set_attr "type" "mvi")])
4558
4559 (define_insn "one_cmpl<mode>2"
4560 [(set (match_operand:VEC 0 "register_operand" "=r")
4561 (not:VEC (match_operand:VEC 1 "register_operand" "r")))]
4562 ""
4563 "ornot $31,%1,%0"
4564 [(set_attr "type" "ilog")])
4565
4566 (define_insn "and<mode>3"
4567 [(set (match_operand:VEC 0 "register_operand" "=r")
4568 (and:VEC (match_operand:VEC 1 "register_operand" "r")
4569 (match_operand:VEC 2 "register_operand" "r")))]
4570 ""
4571 "and %1,%2,%0"
4572 [(set_attr "type" "ilog")])
4573
4574 (define_insn "*andnot<mode>3"
4575 [(set (match_operand:VEC 0 "register_operand" "=r")
4576 (and:VEC (not:VEC (match_operand:VEC 1 "register_operand" "r"))
4577 (match_operand:VEC 2 "register_operand" "r")))]
4578 ""
4579 "bic %2,%1,%0"
4580 [(set_attr "type" "ilog")])
4581
4582 (define_insn "ior<mode>3"
4583 [(set (match_operand:VEC 0 "register_operand" "=r")
4584 (ior:VEC (match_operand:VEC 1 "register_operand" "r")
4585 (match_operand:VEC 2 "register_operand" "r")))]
4586 ""
4587 "bis %1,%2,%0"
4588 [(set_attr "type" "ilog")])
4589
4590 (define_insn "*iornot<mode>3"
4591 [(set (match_operand:VEC 0 "register_operand" "=r")
4592 (ior:VEC (not:DI (match_operand:VEC 1 "register_operand" "r"))
4593 (match_operand:VEC 2 "register_operand" "r")))]
4594 ""
4595 "ornot %2,%1,%0"
4596 [(set_attr "type" "ilog")])
4597
4598 (define_insn "xor<mode>3"
4599 [(set (match_operand:VEC 0 "register_operand" "=r")
4600 (xor:VEC (match_operand:VEC 1 "register_operand" "r")
4601 (match_operand:VEC 2 "register_operand" "r")))]
4602 ""
4603 "xor %1,%2,%0"
4604 [(set_attr "type" "ilog")])
4605
4606 (define_insn "*xornot<mode>3"
4607 [(set (match_operand:VEC 0 "register_operand" "=r")
4608 (not:VEC (xor:VEC (match_operand:VEC 1 "register_operand" "r")
4609 (match_operand:VEC 2 "register_operand" "r"))))]
4610 ""
4611 "eqv %1,%2,%0"
4612 [(set_attr "type" "ilog")])
4613
4614 (define_expand "vec_shl_<mode>"
4615 [(set (match_operand:VEC 0 "register_operand")
4616 (ashift:DI (match_operand:VEC 1 "register_operand")
4617 (match_operand:DI 2 "reg_or_6bit_operand")))]
4618 ""
4619 {
4620 operands[0] = gen_lowpart (DImode, operands[0]);
4621 operands[1] = gen_lowpart (DImode, operands[1]);
4622 })
4623
4624 (define_expand "vec_shr_<mode>"
4625 [(set (match_operand:VEC 0 "register_operand")
4626 (lshiftrt:DI (match_operand:VEC 1 "register_operand")
4627 (match_operand:DI 2 "reg_or_6bit_operand")))]
4628 ""
4629 {
4630 operands[0] = gen_lowpart (DImode, operands[0]);
4631 operands[1] = gen_lowpart (DImode, operands[1]);
4632 })
4633 \f
4634 ;; Bit field extract patterns which use ext[wlq][lh]
4635
4636 (define_expand "extvmisaligndi"
4637 [(set (match_operand:DI 0 "register_operand")
4638 (sign_extract:DI (match_operand:BLK 1 "memory_operand")
4639 (match_operand:DI 2 "const_int_operand")
4640 (match_operand:DI 3 "const_int_operand")))]
4641 ""
4642 {
4643 /* We can do 16, 32 and 64 bit fields, if aligned on byte boundaries. */
4644 if (INTVAL (operands[3]) % 8 != 0
4645 || (INTVAL (operands[2]) != 16
4646 && INTVAL (operands[2]) != 32
4647 && INTVAL (operands[2]) != 64))
4648 FAIL;
4649
4650 alpha_expand_unaligned_load (operands[0], operands[1],
4651 INTVAL (operands[2]) / 8,
4652 INTVAL (operands[3]) / 8, 1);
4653 DONE;
4654 })
4655
4656 (define_expand "extzvdi"
4657 [(set (match_operand:DI 0 "register_operand")
4658 (zero_extract:DI (match_operand:DI 1 "register_operand")
4659 (match_operand:DI 2 "const_int_operand")
4660 (match_operand:DI 3 "const_int_operand")))]
4661 ""
4662 {
4663 /* We can do 8, 16, 32 and 64 bit fields, if aligned on byte boundaries. */
4664 if (INTVAL (operands[3]) % 8 != 0
4665 || (INTVAL (operands[2]) != 8
4666 && INTVAL (operands[2]) != 16
4667 && INTVAL (operands[2]) != 32
4668 && INTVAL (operands[2]) != 64))
4669 FAIL;
4670 })
4671
4672 (define_expand "extzvmisaligndi"
4673 [(set (match_operand:DI 0 "register_operand")
4674 (zero_extract:DI (match_operand:BLK 1 "memory_operand")
4675 (match_operand:DI 2 "const_int_operand")
4676 (match_operand:DI 3 "const_int_operand")))]
4677 ""
4678 {
4679 /* We can do 16, 32 and 64 bit fields, if aligned on byte boundaries.
4680 We fail 8-bit fields, falling back on a simple byte load. */
4681 if (INTVAL (operands[3]) % 8 != 0
4682 || (INTVAL (operands[2]) != 16
4683 && INTVAL (operands[2]) != 32
4684 && INTVAL (operands[2]) != 64))
4685 FAIL;
4686
4687 alpha_expand_unaligned_load (operands[0], operands[1],
4688 INTVAL (operands[2]) / 8,
4689 INTVAL (operands[3]) / 8, 0);
4690 DONE;
4691 })
4692
4693 (define_expand "insvmisaligndi"
4694 [(set (zero_extract:DI (match_operand:BLK 0 "memory_operand")
4695 (match_operand:DI 1 "const_int_operand")
4696 (match_operand:DI 2 "const_int_operand"))
4697 (match_operand:DI 3 "register_operand"))]
4698 ""
4699 {
4700 /* We can do 16, 32 and 64 bit fields, if aligned on byte boundaries. */
4701 if (INTVAL (operands[2]) % 8 != 0
4702 || (INTVAL (operands[1]) != 16
4703 && INTVAL (operands[1]) != 32
4704 && INTVAL (operands[1]) != 64))
4705 FAIL;
4706
4707 alpha_expand_unaligned_store (operands[0], operands[3],
4708 INTVAL (operands[1]) / 8,
4709 INTVAL (operands[2]) / 8);
4710 DONE;
4711 })
4712
4713 ;; Block move/clear, see alpha.c for more details.
4714 ;; Argument 0 is the destination
4715 ;; Argument 1 is the source
4716 ;; Argument 2 is the length
4717 ;; Argument 3 is the alignment
4718
4719 (define_expand "movmemqi"
4720 [(parallel [(set (match_operand:BLK 0 "memory_operand")
4721 (match_operand:BLK 1 "memory_operand"))
4722 (use (match_operand:DI 2 "immediate_operand"))
4723 (use (match_operand:DI 3 "immediate_operand"))])]
4724 ""
4725 {
4726 if (alpha_expand_block_move (operands))
4727 DONE;
4728 else
4729 FAIL;
4730 })
4731
4732 (define_expand "movmemdi"
4733 [(parallel [(set (match_operand:BLK 0 "memory_operand")
4734 (match_operand:BLK 1 "memory_operand"))
4735 (use (match_operand:DI 2 "immediate_operand"))
4736 (use (match_operand:DI 3 "immediate_operand"))
4737 (use (match_dup 4))
4738 (clobber (reg:DI 25))
4739 (clobber (reg:DI 16))
4740 (clobber (reg:DI 17))
4741 (clobber (reg:DI 18))
4742 (clobber (reg:DI 19))
4743 (clobber (reg:DI 20))
4744 (clobber (reg:DI 26))
4745 (clobber (reg:DI 27))])]
4746 "TARGET_ABI_OPEN_VMS"
4747 "operands[4] = gen_rtx_SYMBOL_REF (Pmode, \"OTS$MOVE\");")
4748
4749 (define_insn "*movmemdi_1"
4750 [(set (match_operand:BLK 0 "memory_operand" "=m,m")
4751 (match_operand:BLK 1 "memory_operand" "m,m"))
4752 (use (match_operand:DI 2 "nonmemory_operand" "r,i"))
4753 (use (match_operand:DI 3 "immediate_operand"))
4754 (use (match_operand:DI 4 "call_operand" "i,i"))
4755 (clobber (reg:DI 25))
4756 (clobber (reg:DI 16))
4757 (clobber (reg:DI 17))
4758 (clobber (reg:DI 18))
4759 (clobber (reg:DI 19))
4760 (clobber (reg:DI 20))
4761 (clobber (reg:DI 26))
4762 (clobber (reg:DI 27))]
4763 "TARGET_ABI_OPEN_VMS"
4764 {
4765 operands [5] = alpha_use_linkage (operands [4], false, true);
4766 switch (which_alternative)
4767 {
4768 case 0:
4769 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)";
4770 case 1:
4771 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)";
4772 default:
4773 gcc_unreachable ();
4774 }
4775 }
4776 [(set_attr "type" "multi")
4777 (set_attr "length" "28")])
4778
4779 (define_expand "setmemqi"
4780 [(parallel [(set (match_operand:BLK 0 "memory_operand")
4781 (match_operand 2 "const_int_operand"))
4782 (use (match_operand:DI 1 "immediate_operand"))
4783 (use (match_operand:DI 3 "immediate_operand"))])]
4784 ""
4785 {
4786 /* If value to set is not zero, use the library routine. */
4787 if (operands[2] != const0_rtx)
4788 FAIL;
4789
4790 if (alpha_expand_block_clear (operands))
4791 DONE;
4792 else
4793 FAIL;
4794 })
4795
4796 (define_expand "setmemdi"
4797 [(parallel [(set (match_operand:BLK 0 "memory_operand")
4798 (match_operand 2 "const_int_operand"))
4799 (use (match_operand:DI 1 "immediate_operand"))
4800 (use (match_operand:DI 3 "immediate_operand"))
4801 (use (match_dup 4))
4802 (clobber (reg:DI 25))
4803 (clobber (reg:DI 16))
4804 (clobber (reg:DI 17))
4805 (clobber (reg:DI 26))
4806 (clobber (reg:DI 27))])]
4807 "TARGET_ABI_OPEN_VMS"
4808 {
4809 /* If value to set is not zero, use the library routine. */
4810 if (operands[2] != const0_rtx)
4811 FAIL;
4812
4813 operands[4] = gen_rtx_SYMBOL_REF (Pmode, "OTS$ZERO");
4814 })
4815
4816 (define_insn "*clrmemdi_1"
4817 [(set (match_operand:BLK 0 "memory_operand" "=m,m")
4818 (const_int 0))
4819 (use (match_operand:DI 1 "nonmemory_operand" "r,i"))
4820 (use (match_operand:DI 2 "immediate_operand"))
4821 (use (match_operand:DI 3 "call_operand" "i,i"))
4822 (clobber (reg:DI 25))
4823 (clobber (reg:DI 16))
4824 (clobber (reg:DI 17))
4825 (clobber (reg:DI 26))
4826 (clobber (reg:DI 27))]
4827 "TARGET_ABI_OPEN_VMS"
4828 {
4829 operands [4] = alpha_use_linkage (operands [3], false, true);
4830 switch (which_alternative)
4831 {
4832 case 0:
4833 return "lda $16,%0\;bis $31,%1,$17\;ldq $26,%4\;lda $25,2($31)\;jsr $26,%3\;ldq $27,0($29)";
4834 case 1:
4835 return "lda $16,%0\;lda $17,%1($31)\;ldq $26,%4\;lda $25,2($31)\;jsr $26,%3\;ldq $27,0($29)";
4836 default:
4837 gcc_unreachable ();
4838 }
4839 }
4840 [(set_attr "type" "multi")
4841 (set_attr "length" "24")])
4842
4843 \f
4844 ;; Subroutine of stack space allocation. Perform a stack probe.
4845 (define_expand "probe_stack"
4846 [(set (match_dup 1) (match_operand:DI 0 "const_int_operand"))]
4847 ""
4848 {
4849 operands[1] = gen_rtx_MEM (DImode, plus_constant (Pmode, stack_pointer_rtx,
4850 INTVAL (operands[0])));
4851 MEM_VOLATILE_P (operands[1]) = 1;
4852
4853 operands[0] = const0_rtx;
4854 })
4855
4856 ;; This is how we allocate stack space. If we are allocating a
4857 ;; constant amount of space and we know it is less than 4096
4858 ;; bytes, we need do nothing.
4859 ;;
4860 ;; If it is more than 4096 bytes, we need to probe the stack
4861 ;; periodically.
4862 (define_expand "allocate_stack"
4863 [(set (reg:DI 30)
4864 (plus:DI (reg:DI 30)
4865 (match_operand:DI 1 "reg_or_cint_operand")))
4866 (set (match_operand:DI 0 "register_operand" "=r")
4867 (match_dup 2))]
4868 ""
4869 {
4870 if (CONST_INT_P (operands[1])
4871 && INTVAL (operands[1]) < 32768)
4872 {
4873 if (INTVAL (operands[1]) >= 4096)
4874 {
4875 /* We do this the same way as in the prologue and generate explicit
4876 probes. Then we update the stack by the constant. */
4877
4878 int probed = 4096;
4879
4880 emit_insn (gen_probe_stack (GEN_INT (- probed)));
4881 while (probed + 8192 < INTVAL (operands[1]))
4882 emit_insn (gen_probe_stack (GEN_INT (- (probed += 8192))));
4883
4884 if (probed + 4096 < INTVAL (operands[1]))
4885 emit_insn (gen_probe_stack (GEN_INT (- INTVAL(operands[1]))));
4886 }
4887
4888 operands[1] = GEN_INT (- INTVAL (operands[1]));
4889 operands[2] = virtual_stack_dynamic_rtx;
4890 }
4891 else
4892 {
4893 rtx_code_label *out_label = 0;
4894 rtx_code_label *loop_label = gen_label_rtx ();
4895 rtx want = gen_reg_rtx (Pmode);
4896 rtx tmp = gen_reg_rtx (Pmode);
4897 rtx memref, test;
4898
4899 emit_insn (gen_subdi3 (want, stack_pointer_rtx,
4900 force_reg (Pmode, operands[1])));
4901
4902 if (!CONST_INT_P (operands[1]))
4903 {
4904 rtx limit = GEN_INT (4096);
4905 out_label = gen_label_rtx ();
4906 test = gen_rtx_LTU (VOIDmode, operands[1], limit);
4907 emit_jump_insn
4908 (gen_cbranchdi4 (test, operands[1], limit, out_label));
4909 }
4910
4911 emit_insn (gen_adddi3 (tmp, stack_pointer_rtx, GEN_INT (-4096)));
4912 emit_label (loop_label);
4913 memref = gen_rtx_MEM (DImode, tmp);
4914 MEM_VOLATILE_P (memref) = 1;
4915 emit_move_insn (memref, const0_rtx);
4916 emit_insn (gen_adddi3 (tmp, tmp, GEN_INT(-8192)));
4917 test = gen_rtx_GTU (VOIDmode, tmp, want);
4918 emit_jump_insn (gen_cbranchdi4 (test, tmp, want, loop_label));
4919
4920 memref = gen_rtx_MEM (DImode, want);
4921 MEM_VOLATILE_P (memref) = 1;
4922 emit_move_insn (memref, const0_rtx);
4923
4924 if (out_label)
4925 emit_label (out_label);
4926
4927 emit_move_insn (stack_pointer_rtx, want);
4928 emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
4929 DONE;
4930 }
4931 })
4932
4933 ;; This is used by alpha_expand_prolog to do the same thing as above,
4934 ;; except we cannot at that time generate new basic blocks, so we hide
4935 ;; the loop in this one insn.
4936
4937 (define_insn "prologue_stack_probe_loop"
4938 [(unspec_volatile [(match_operand:DI 0 "register_operand" "r")
4939 (match_operand:DI 1 "register_operand" "r")]
4940 UNSPECV_PSPL)]
4941 ""
4942 {
4943 operands[2] = gen_label_rtx ();
4944 (*targetm.asm_out.internal_label) (asm_out_file, "L",
4945 CODE_LABEL_NUMBER (operands[2]));
4946
4947 return "stq $31,-8192(%1)\;subq %0,1,%0\;lda %1,-8192(%1)\;bne %0,%l2";
4948 }
4949 [(set_attr "length" "16")
4950 (set_attr "type" "multi")])
4951
4952 (define_expand "prologue"
4953 [(const_int 0)]
4954 ""
4955 {
4956 alpha_expand_prologue ();
4957 DONE;
4958 })
4959
4960 ;; These take care of emitting the ldgp insn in the prologue. This will be
4961 ;; an lda/ldah pair and we want to align them properly. So we have two
4962 ;; unspec_volatile insns, the first of which emits the ldgp assembler macro
4963 ;; and the second of which emits nothing. However, both are marked as type
4964 ;; IADD (the default) so the alignment code in alpha.c does the right thing
4965 ;; with them.
4966
4967 (define_expand "prologue_ldgp"
4968 [(set (match_dup 0)
4969 (unspec_volatile:DI [(match_dup 1) (match_dup 2)] UNSPECV_LDGP1))
4970 (set (match_dup 0)
4971 (unspec_volatile:DI [(match_dup 0) (match_dup 2)] UNSPECV_PLDGP2))]
4972 ""
4973 {
4974 operands[0] = pic_offset_table_rtx;
4975 operands[1] = gen_rtx_REG (Pmode, 27);
4976 operands[2] = (TARGET_EXPLICIT_RELOCS
4977 ? GEN_INT (alpha_next_sequence_number++)
4978 : const0_rtx);
4979 })
4980
4981 (define_insn "*ldgp_er_1"
4982 [(set (match_operand:DI 0 "register_operand" "=r")
4983 (unspec_volatile:DI [(match_operand:DI 1 "register_operand" "r")
4984 (match_operand 2 "const_int_operand")]
4985 UNSPECV_LDGP1))]
4986 "TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF"
4987 "ldah %0,0(%1)\t\t!gpdisp!%2"
4988 [(set_attr "cannot_copy" "true")])
4989
4990 (define_insn "*ldgp_er_2"
4991 [(set (match_operand:DI 0 "register_operand" "=r")
4992 (unspec:DI [(match_operand:DI 1 "register_operand" "r")
4993 (match_operand 2 "const_int_operand")]
4994 UNSPEC_LDGP2))]
4995 "TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF"
4996 "lda %0,0(%1)\t\t!gpdisp!%2"
4997 [(set_attr "cannot_copy" "true")])
4998
4999 (define_insn "*prologue_ldgp_er_2"
5000 [(set (match_operand:DI 0 "register_operand" "=r")
5001 (unspec_volatile:DI [(match_operand:DI 1 "register_operand" "r")
5002 (match_operand 2 "const_int_operand")]
5003 UNSPECV_PLDGP2))]
5004 "TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF"
5005 "lda %0,0(%1)\t\t!gpdisp!%2\n$%~..ng:"
5006 [(set_attr "cannot_copy" "true")])
5007
5008 (define_insn "*prologue_ldgp_1"
5009 [(set (match_operand:DI 0 "register_operand" "=r")
5010 (unspec_volatile:DI [(match_operand:DI 1 "register_operand" "r")
5011 (match_operand 2 "const_int_operand")]
5012 UNSPECV_LDGP1))]
5013 ""
5014 "ldgp %0,0(%1)\n$%~..ng:"
5015 [(set_attr "cannot_copy" "true")])
5016
5017 (define_insn "*prologue_ldgp_2"
5018 [(set (match_operand:DI 0 "register_operand" "=r")
5019 (unspec_volatile:DI [(match_operand:DI 1 "register_operand" "r")
5020 (match_operand 2 "const_int_operand")]
5021 UNSPECV_PLDGP2))]
5022 ""
5023 )
5024
5025 ;; The _mcount profiling hook has special calling conventions, and
5026 ;; does not clobber all the registers that a normal call would. So
5027 ;; hide the fact this is a call at all.
5028
5029 (define_insn "prologue_mcount"
5030 [(unspec_volatile [(const_int 0)] UNSPECV_MCOUNT)]
5031 ""
5032 {
5033 if (TARGET_EXPLICIT_RELOCS)
5034 /* Note that we cannot use a lituse_jsr reloc, since _mcount
5035 cannot be called via the PLT. */
5036 return "ldq $28,_mcount($29)\t\t!literal\;jsr $28,($28),_mcount";
5037 else
5038 return "lda $28,_mcount\;jsr $28,($28),_mcount";
5039 }
5040 [(set_attr "type" "multi")
5041 (set_attr "length" "8")])
5042
5043 (define_insn "init_fp"
5044 [(set (match_operand:DI 0 "register_operand" "=r")
5045 (match_operand:DI 1 "register_operand" "r"))
5046 (clobber (mem:BLK (match_operand:DI 2 "register_operand" "=r")))]
5047 ""
5048 "bis $31,%1,%0")
5049
5050 (define_expand "epilogue"
5051 [(return)]
5052 ""
5053 "alpha_expand_epilogue ();")
5054
5055 (define_expand "sibcall_epilogue"
5056 [(return)]
5057 "TARGET_ABI_OSF"
5058 {
5059 alpha_expand_epilogue ();
5060 DONE;
5061 })
5062
5063 (define_expand "builtin_longjmp"
5064 [(use (match_operand:DI 0 "register_operand" "r"))]
5065 "TARGET_ABI_OSF"
5066 {
5067 /* The elements of the buffer are, in order: */
5068 rtx fp = gen_rtx_MEM (Pmode, operands[0]);
5069 rtx lab = gen_rtx_MEM (Pmode, plus_constant (Pmode, operands[0], 8));
5070 rtx stack = gen_rtx_MEM (Pmode, plus_constant (Pmode, operands[0], 16));
5071 rtx pv = gen_rtx_REG (Pmode, 27);
5072
5073 /* This bit is the same as expand_builtin_longjmp. */
5074 emit_move_insn (hard_frame_pointer_rtx, fp);
5075 emit_move_insn (pv, lab);
5076 emit_stack_restore (SAVE_NONLOCAL, stack);
5077 emit_use (hard_frame_pointer_rtx);
5078 emit_use (stack_pointer_rtx);
5079
5080 /* Load the label we are jumping through into $27 so that we know
5081 where to look for it when we get back to setjmp's function for
5082 restoring the gp. */
5083 emit_jump_insn (gen_builtin_longjmp_internal (pv));
5084 emit_barrier ();
5085 DONE;
5086 })
5087
5088 ;; This is effectively a copy of indirect_jump, but constrained such
5089 ;; that register renaming cannot foil our cunning plan with $27.
5090 (define_insn "builtin_longjmp_internal"
5091 [(set (pc)
5092 (unspec_volatile [(match_operand:DI 0 "register_operand" "c")]
5093 UNSPECV_LONGJMP))]
5094 ""
5095 "jmp $31,(%0),0"
5096 [(set_attr "type" "ibr")])
5097
5098 (define_expand "builtin_setjmp_receiver"
5099 [(unspec_volatile [(label_ref (match_operand 0))] UNSPECV_SETJMPR)]
5100 "TARGET_ABI_OSF")
5101
5102 (define_insn_and_split "*builtin_setjmp_receiver_1"
5103 [(unspec_volatile [(match_operand 0)] UNSPECV_SETJMPR)]
5104 "TARGET_ABI_OSF"
5105 {
5106 if (TARGET_EXPLICIT_RELOCS)
5107 return "#";
5108 else
5109 return "br $27,$LSJ%=\n$LSJ%=:\;ldgp $29,0($27)";
5110 }
5111 "&& TARGET_EXPLICIT_RELOCS && reload_completed"
5112 [(set (match_dup 1)
5113 (unspec_volatile:DI [(match_dup 2) (match_dup 3)] UNSPECV_LDGP1))
5114 (set (match_dup 1)
5115 (unspec:DI [(match_dup 1) (match_dup 3)] UNSPEC_LDGP2))]
5116 {
5117 if (prev_nonnote_insn (curr_insn) != XEXP (operands[0], 0))
5118 emit_insn (gen_rtx_UNSPEC_VOLATILE (VOIDmode, gen_rtvec (1, operands[0]),
5119 UNSPECV_SETJMPR_ER));
5120 operands[1] = pic_offset_table_rtx;
5121 operands[2] = gen_rtx_REG (Pmode, 27);
5122 operands[3] = GEN_INT (alpha_next_sequence_number++);
5123 }
5124 [(set_attr "length" "12")
5125 (set_attr "type" "multi")])
5126
5127 (define_insn "*builtin_setjmp_receiver_er_sl_1"
5128 [(unspec_volatile [(match_operand 0)] UNSPECV_SETJMPR_ER)]
5129 "TARGET_ABI_OSF && TARGET_EXPLICIT_RELOCS"
5130 "lda $27,$LSJ%=-%l0($27)\n$LSJ%=:")
5131
5132 ;; When flag_reorder_blocks_and_partition is in effect, compiler puts
5133 ;; exception landing pads in a cold section. To prevent inter-section offset
5134 ;; calculation, a jump to original landing pad is emitted in the place of the
5135 ;; original landing pad. Since landing pad is moved, RA-relative GP
5136 ;; calculation in the prologue of landing pad breaks. To solve this problem,
5137 ;; we use alternative GP load approach.
5138
5139 (define_expand "exception_receiver"
5140 [(unspec_volatile [(match_dup 0)] UNSPECV_EHR)]
5141 "TARGET_ABI_OSF"
5142 {
5143 if (flag_reorder_blocks_and_partition)
5144 operands[0] = alpha_gp_save_rtx ();
5145 else
5146 operands[0] = const0_rtx;
5147 })
5148
5149 (define_insn "*exception_receiver_2"
5150 [(unspec_volatile [(match_operand:DI 0 "memory_operand" "m")] UNSPECV_EHR)]
5151 "TARGET_ABI_OSF && flag_reorder_blocks_and_partition"
5152 "ldq $29,%0"
5153 [(set_attr "type" "ild")])
5154
5155 (define_insn_and_split "*exception_receiver_1"
5156 [(unspec_volatile [(const_int 0)] UNSPECV_EHR)]
5157 "TARGET_ABI_OSF"
5158 {
5159 if (TARGET_EXPLICIT_RELOCS)
5160 return "ldah $29,0($26)\t\t!gpdisp!%*\;lda $29,0($29)\t\t!gpdisp!%*";
5161 else
5162 return "ldgp $29,0($26)";
5163 }
5164 "&& TARGET_EXPLICIT_RELOCS && reload_completed"
5165 [(set (match_dup 0)
5166 (unspec_volatile:DI [(match_dup 1) (match_dup 2)] UNSPECV_LDGP1))
5167 (set (match_dup 0)
5168 (unspec:DI [(match_dup 0) (match_dup 2)] UNSPEC_LDGP2))]
5169 {
5170 operands[0] = pic_offset_table_rtx;
5171 operands[1] = gen_rtx_REG (Pmode, 26);
5172 operands[2] = GEN_INT (alpha_next_sequence_number++);
5173 }
5174 [(set_attr "length" "8")
5175 (set_attr "type" "multi")])
5176
5177 (define_expand "nonlocal_goto_receiver"
5178 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
5179 (set (reg:DI 27) (mem:DI (reg:DI 29)))
5180 (unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
5181 (use (reg:DI 27))]
5182 "TARGET_ABI_OPEN_VMS")
5183
5184 (define_insn "arg_home"
5185 [(unspec [(const_int 0)] UNSPEC_ARG_HOME)
5186 (use (reg:DI 1))
5187 (use (reg:DI 25))
5188 (use (reg:DI 16))
5189 (use (reg:DI 17))
5190 (use (reg:DI 18))
5191 (use (reg:DI 19))
5192 (use (reg:DI 20))
5193 (use (reg:DI 21))
5194 (use (reg:DI 48))
5195 (use (reg:DI 49))
5196 (use (reg:DI 50))
5197 (use (reg:DI 51))
5198 (use (reg:DI 52))
5199 (use (reg:DI 53))
5200 (clobber (mem:BLK (const_int 0)))
5201 (clobber (reg:DI 24))
5202 (clobber (reg:DI 25))
5203 (clobber (reg:DI 0))]
5204 "TARGET_ABI_OPEN_VMS"
5205 "lda $0,OTS$HOME_ARGS\;ldq $0,8($0)\;jsr $0,OTS$HOME_ARGS"
5206 [(set_attr "length" "16")
5207 (set_attr "type" "multi")])
5208
5209 ;; Prefetch data.
5210 ;;
5211 ;; On EV4, these instructions are nops -- no load occurs.
5212 ;;
5213 ;; On EV5, these instructions act as a normal load, and thus can trap
5214 ;; if the address is invalid. The OS may (or may not) handle this in
5215 ;; the entMM fault handler and suppress the fault. If so, then this
5216 ;; has the effect of a read prefetch instruction.
5217 ;;
5218 ;; On EV6, these become official prefetch instructions.
5219
5220 (define_insn "prefetch"
5221 [(prefetch (match_operand:DI 0 "address_operand" "p")
5222 (match_operand:DI 1 "const_int_operand" "n")
5223 (match_operand:DI 2 "const_int_operand" "n"))]
5224 "TARGET_FIXUP_EV5_PREFETCH || alpha_cpu == PROCESSOR_EV6"
5225 {
5226 /* Interpret "no temporal locality" as this data should be evicted once
5227 it is used. The "evict next" alternatives load the data into the cache
5228 and leave the LRU eviction counter pointing to that block. */
5229 static const char * const alt[2][2] = {
5230 {
5231 "ldq $31,%a0", /* read, evict next */
5232 "ldl $31,%a0", /* read, evict last */
5233 },
5234 {
5235 "ldt $f31,%a0", /* write, evict next */
5236 "lds $f31,%a0", /* write, evict last */
5237 }
5238 };
5239
5240 bool write = INTVAL (operands[1]) != 0;
5241 bool lru = INTVAL (operands[2]) != 0;
5242
5243 return alt[write][lru];
5244 }
5245 [(set_attr "type" "ild")])
5246
5247 ;; Close the trap shadow of preceding instructions. This is generated
5248 ;; by alpha_reorg.
5249
5250 (define_insn "trapb"
5251 [(unspec_volatile [(const_int 0)] UNSPECV_TRAPB)]
5252 ""
5253 "trapb"
5254 [(set_attr "type" "misc")])
5255
5256 ;; No-op instructions used by machine-dependent reorg to preserve
5257 ;; alignment for instruction issue.
5258 ;; The Unicos/Mk assembler does not support these opcodes.
5259
5260 (define_insn "nop"
5261 [(const_int 0)]
5262 ""
5263 "bis $31,$31,$31"
5264 [(set_attr "type" "ilog")])
5265
5266 (define_insn "fnop"
5267 [(const_int 1)]
5268 "TARGET_FP"
5269 "cpys $f31,$f31,$f31"
5270 [(set_attr "type" "fcpys")])
5271
5272 (define_insn "unop"
5273 [(const_int 2)]
5274 ""
5275 "ldq_u $31,0($30)")
5276
5277 (define_insn "realign"
5278 [(unspec_volatile [(match_operand 0 "immediate_operand" "i")]
5279 UNSPECV_REALIGN)]
5280 ""
5281 ".align %0 #realign")
5282 \f
5283 ;; Instructions to be emitted from __builtins.
5284
5285 (define_insn "builtin_cmpbge"
5286 [(set (match_operand:DI 0 "register_operand" "=r")
5287 (unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "rJ")
5288 (match_operand:DI 2 "reg_or_8bit_operand" "rI")]
5289 UNSPEC_CMPBGE))]
5290 ""
5291 "cmpbge %r1,%2,%0"
5292 ;; The EV6 data sheets list this as ILOG. OTOH, EV6 doesn't
5293 ;; actually differentiate between ILOG and ICMP in the schedule.
5294 [(set_attr "type" "icmp")])
5295
5296 (define_expand "extbl"
5297 [(match_operand:DI 0 "register_operand")
5298 (match_operand:DI 1 "reg_or_0_operand")
5299 (match_operand:DI 2 "reg_or_8bit_operand")]
5300 ""
5301 {
5302 emit_insn (gen_extxl (operands[0], operands[1], GEN_INT (8), operands[2]));
5303 DONE;
5304 })
5305
5306 (define_expand "extwl"
5307 [(match_operand:DI 0 "register_operand")
5308 (match_operand:DI 1 "reg_or_0_operand")
5309 (match_operand:DI 2 "reg_or_8bit_operand")]
5310 ""
5311 {
5312 emit_insn (gen_extxl (operands[0], operands[1], GEN_INT (16), operands[2]));
5313 DONE;
5314 })
5315
5316 (define_expand "extll"
5317 [(match_operand:DI 0 "register_operand")
5318 (match_operand:DI 1 "reg_or_0_operand")
5319 (match_operand:DI 2 "reg_or_8bit_operand")]
5320 ""
5321 {
5322 emit_insn (gen_extxl (operands[0], operands[1], GEN_INT (32), operands[2]));
5323 DONE;
5324 })
5325
5326 (define_expand "extql"
5327 [(match_operand:DI 0 "register_operand")
5328 (match_operand:DI 1 "reg_or_0_operand")
5329 (match_operand:DI 2 "reg_or_8bit_operand")]
5330 ""
5331 {
5332 emit_insn (gen_extxl (operands[0], operands[1], GEN_INT (64), operands[2]));
5333 DONE;
5334 })
5335
5336 (define_expand "builtin_insbl"
5337 [(match_operand:DI 0 "register_operand")
5338 (match_operand:DI 1 "register_operand")
5339 (match_operand:DI 2 "reg_or_8bit_operand")]
5340 ""
5341 {
5342 operands[1] = gen_lowpart (QImode, operands[1]);
5343 emit_insn (gen_insbl (operands[0], operands[1], operands[2]));
5344 DONE;
5345 })
5346
5347 (define_expand "builtin_inswl"
5348 [(match_operand:DI 0 "register_operand")
5349 (match_operand:DI 1 "register_operand")
5350 (match_operand:DI 2 "reg_or_8bit_operand")]
5351 ""
5352 {
5353 operands[1] = gen_lowpart (HImode, operands[1]);
5354 emit_insn (gen_inswl (operands[0], operands[1], operands[2]));
5355 DONE;
5356 })
5357
5358 (define_expand "builtin_insll"
5359 [(match_operand:DI 0 "register_operand")
5360 (match_operand:DI 1 "register_operand")
5361 (match_operand:DI 2 "reg_or_8bit_operand")]
5362 ""
5363 {
5364 operands[1] = gen_lowpart (SImode, operands[1]);
5365 emit_insn (gen_insll (operands[0], operands[1], operands[2]));
5366 DONE;
5367 })
5368
5369 (define_expand "inswh"
5370 [(match_operand:DI 0 "register_operand")
5371 (match_operand:DI 1 "register_operand")
5372 (match_operand:DI 2 "reg_or_8bit_operand")]
5373 ""
5374 {
5375 emit_insn (gen_insxh (operands[0], operands[1], GEN_INT (16), operands[2]));
5376 DONE;
5377 })
5378
5379 (define_expand "inslh"
5380 [(match_operand:DI 0 "register_operand")
5381 (match_operand:DI 1 "register_operand")
5382 (match_operand:DI 2 "reg_or_8bit_operand")]
5383 ""
5384 {
5385 emit_insn (gen_insxh (operands[0], operands[1], GEN_INT (32), operands[2]));
5386 DONE;
5387 })
5388
5389 (define_expand "insqh"
5390 [(match_operand:DI 0 "register_operand")
5391 (match_operand:DI 1 "register_operand")
5392 (match_operand:DI 2 "reg_or_8bit_operand")]
5393 ""
5394 {
5395 emit_insn (gen_insxh (operands[0], operands[1], GEN_INT (64), operands[2]));
5396 DONE;
5397 })
5398
5399 (define_expand "mskbl"
5400 [(match_operand:DI 0 "register_operand")
5401 (match_operand:DI 1 "reg_or_0_operand")
5402 (match_operand:DI 2 "reg_or_8bit_operand")]
5403 ""
5404 {
5405 rtx mask = GEN_INT (0xff);
5406 emit_insn (gen_mskxl (operands[0], operands[1], mask, operands[2]));
5407 DONE;
5408 })
5409
5410 (define_expand "mskwl"
5411 [(match_operand:DI 0 "register_operand")
5412 (match_operand:DI 1 "reg_or_0_operand")
5413 (match_operand:DI 2 "reg_or_8bit_operand")]
5414 ""
5415 {
5416 rtx mask = GEN_INT (0xffff);
5417 emit_insn (gen_mskxl (operands[0], operands[1], mask, operands[2]));
5418 DONE;
5419 })
5420
5421 (define_expand "mskll"
5422 [(match_operand:DI 0 "register_operand")
5423 (match_operand:DI 1 "reg_or_0_operand")
5424 (match_operand:DI 2 "reg_or_8bit_operand")]
5425 ""
5426 {
5427 rtx mask = gen_int_mode (0xffffffff, DImode);
5428 emit_insn (gen_mskxl (operands[0], operands[1], mask, operands[2]));
5429 DONE;
5430 })
5431
5432 (define_expand "mskql"
5433 [(match_operand:DI 0 "register_operand")
5434 (match_operand:DI 1 "reg_or_0_operand")
5435 (match_operand:DI 2 "reg_or_8bit_operand")]
5436 ""
5437 {
5438 rtx mask = constm1_rtx;
5439 emit_insn (gen_mskxl (operands[0], operands[1], mask, operands[2]));
5440 DONE;
5441 })
5442
5443 (define_expand "mskwh"
5444 [(match_operand:DI 0 "register_operand")
5445 (match_operand:DI 1 "register_operand")
5446 (match_operand:DI 2 "reg_or_8bit_operand")]
5447 ""
5448 {
5449 emit_insn (gen_mskxh (operands[0], operands[1], GEN_INT (16), operands[2]));
5450 DONE;
5451 })
5452
5453 (define_expand "msklh"
5454 [(match_operand:DI 0 "register_operand")
5455 (match_operand:DI 1 "register_operand")
5456 (match_operand:DI 2 "reg_or_8bit_operand")]
5457 ""
5458 {
5459 emit_insn (gen_mskxh (operands[0], operands[1], GEN_INT (32), operands[2]));
5460 DONE;
5461 })
5462
5463 (define_expand "mskqh"
5464 [(match_operand:DI 0 "register_operand")
5465 (match_operand:DI 1 "register_operand")
5466 (match_operand:DI 2 "reg_or_8bit_operand")]
5467 ""
5468 {
5469 emit_insn (gen_mskxh (operands[0], operands[1], GEN_INT (64), operands[2]));
5470 DONE;
5471 })
5472
5473 (define_expand "builtin_zap"
5474 [(set (match_operand:DI 0 "register_operand")
5475 (and:DI (unspec:DI
5476 [(match_operand:DI 2 "reg_or_cint_operand")]
5477 UNSPEC_ZAP)
5478 (match_operand:DI 1 "reg_or_cint_operand")))]
5479 ""
5480 {
5481 if (CONST_INT_P (operands[2]))
5482 {
5483 rtx mask = alpha_expand_zap_mask (INTVAL (operands[2]));
5484
5485 if (mask == const0_rtx)
5486 {
5487 emit_move_insn (operands[0], const0_rtx);
5488 DONE;
5489 }
5490 if (mask == constm1_rtx)
5491 {
5492 emit_move_insn (operands[0], operands[1]);
5493 DONE;
5494 }
5495
5496 operands[1] = force_reg (DImode, operands[1]);
5497 emit_insn (gen_anddi3 (operands[0], operands[1], mask));
5498 DONE;
5499 }
5500
5501 operands[1] = force_reg (DImode, operands[1]);
5502 operands[2] = gen_lowpart (QImode, operands[2]);
5503 })
5504
5505 (define_insn "*builtin_zap_1"
5506 [(set (match_operand:DI 0 "register_operand" "=r,r,r,r")
5507 (and:DI (unspec:DI
5508 [(match_operand:QI 2 "reg_or_cint_operand" "n,n,r,r")]
5509 UNSPEC_ZAP)
5510 (match_operand:DI 1 "reg_or_cint_operand" "n,r,J,r")))]
5511 ""
5512 "@
5513 #
5514 #
5515 bis $31,$31,%0
5516 zap %r1,%2,%0"
5517 [(set_attr "type" "shift,shift,ilog,shift")])
5518
5519 (define_split
5520 [(set (match_operand:DI 0 "register_operand")
5521 (and:DI (unspec:DI
5522 [(match_operand:QI 2 "const_int_operand")]
5523 UNSPEC_ZAP)
5524 (match_operand:DI 1 "const_int_operand")))]
5525 ""
5526 [(const_int 0)]
5527 {
5528 rtx mask = alpha_expand_zap_mask (INTVAL (operands[2]));
5529
5530 operands[1] = gen_int_mode (INTVAL (operands[1]) & INTVAL (mask), DImode);
5531 emit_move_insn (operands[0], operands[1]);
5532 DONE;
5533 })
5534
5535 (define_split
5536 [(set (match_operand:DI 0 "register_operand")
5537 (and:DI (unspec:DI
5538 [(match_operand:QI 2 "const_int_operand")]
5539 UNSPEC_ZAP)
5540 (match_operand:DI 1 "register_operand")))]
5541 ""
5542 [(set (match_dup 0)
5543 (and:DI (match_dup 1) (match_dup 2)))]
5544 {
5545 operands[2] = alpha_expand_zap_mask (INTVAL (operands[2]));
5546 if (operands[2] == const0_rtx)
5547 {
5548 emit_move_insn (operands[0], const0_rtx);
5549 DONE;
5550 }
5551 if (operands[2] == constm1_rtx)
5552 {
5553 emit_move_insn (operands[0], operands[1]);
5554 DONE;
5555 }
5556 })
5557
5558 (define_expand "builtin_zapnot"
5559 [(set (match_operand:DI 0 "register_operand")
5560 (and:DI (unspec:DI
5561 [(not:QI (match_operand:DI 2 "reg_or_cint_operand"))]
5562 UNSPEC_ZAP)
5563 (match_operand:DI 1 "reg_or_cint_operand")))]
5564 ""
5565 {
5566 if (CONST_INT_P (operands[2]))
5567 {
5568 rtx mask = alpha_expand_zap_mask (~ INTVAL (operands[2]));
5569
5570 if (mask == const0_rtx)
5571 {
5572 emit_move_insn (operands[0], const0_rtx);
5573 DONE;
5574 }
5575 if (mask == constm1_rtx)
5576 {
5577 emit_move_insn (operands[0], operands[1]);
5578 DONE;
5579 }
5580
5581 operands[1] = force_reg (DImode, operands[1]);
5582 emit_insn (gen_anddi3 (operands[0], operands[1], mask));
5583 DONE;
5584 }
5585
5586 operands[1] = force_reg (DImode, operands[1]);
5587 operands[2] = gen_lowpart (QImode, operands[2]);
5588 })
5589
5590 (define_insn "*builtin_zapnot_1"
5591 [(set (match_operand:DI 0 "register_operand" "=r")
5592 (and:DI (unspec:DI
5593 [(not:QI (match_operand:QI 2 "register_operand" "r"))]
5594 UNSPEC_ZAP)
5595 (match_operand:DI 1 "reg_or_0_operand" "rJ")))]
5596 ""
5597 "zapnot %r1,%2,%0"
5598 [(set_attr "type" "shift")])
5599
5600 (define_insn "builtin_amask"
5601 [(set (match_operand:DI 0 "register_operand" "=r")
5602 (unspec:DI [(match_operand:DI 1 "reg_or_8bit_operand" "rI")]
5603 UNSPEC_AMASK))]
5604 ""
5605 "amask %1,%0"
5606 [(set_attr "type" "ilog")])
5607
5608 (define_insn "builtin_implver"
5609 [(set (match_operand:DI 0 "register_operand" "=r")
5610 (unspec:DI [(const_int 0)] UNSPEC_IMPLVER))]
5611 ""
5612 "implver %0"
5613 [(set_attr "type" "ilog")])
5614
5615 (define_insn "builtin_rpcc"
5616 [(set (match_operand:DI 0 "register_operand" "=r")
5617 (unspec_volatile:DI [(const_int 0)] UNSPECV_RPCC))]
5618 ""
5619 "rpcc %0"
5620 [(set_attr "type" "ilog")])
5621
5622 (define_expand "builtin_minub8"
5623 [(match_operand:DI 0 "register_operand")
5624 (match_operand:DI 1 "reg_or_0_operand")
5625 (match_operand:DI 2 "reg_or_0_operand")]
5626 "TARGET_MAX"
5627 {
5628 alpha_expand_builtin_vector_binop (gen_uminv8qi3, V8QImode, operands[0],
5629 operands[1], operands[2]);
5630 DONE;
5631 })
5632
5633 (define_expand "builtin_minsb8"
5634 [(match_operand:DI 0 "register_operand")
5635 (match_operand:DI 1 "reg_or_0_operand")
5636 (match_operand:DI 2 "reg_or_0_operand")]
5637 "TARGET_MAX"
5638 {
5639 alpha_expand_builtin_vector_binop (gen_sminv8qi3, V8QImode, operands[0],
5640 operands[1], operands[2]);
5641 DONE;
5642 })
5643
5644 (define_expand "builtin_minuw4"
5645 [(match_operand:DI 0 "register_operand")
5646 (match_operand:DI 1 "reg_or_0_operand")
5647 (match_operand:DI 2 "reg_or_0_operand")]
5648 "TARGET_MAX"
5649 {
5650 alpha_expand_builtin_vector_binop (gen_uminv4hi3, V4HImode, operands[0],
5651 operands[1], operands[2]);
5652 DONE;
5653 })
5654
5655 (define_expand "builtin_minsw4"
5656 [(match_operand:DI 0 "register_operand")
5657 (match_operand:DI 1 "reg_or_0_operand")
5658 (match_operand:DI 2 "reg_or_0_operand")]
5659 "TARGET_MAX"
5660 {
5661 alpha_expand_builtin_vector_binop (gen_sminv4hi3, V4HImode, operands[0],
5662 operands[1], operands[2]);
5663 DONE;
5664 })
5665
5666 (define_expand "builtin_maxub8"
5667 [(match_operand:DI 0 "register_operand")
5668 (match_operand:DI 1 "reg_or_0_operand")
5669 (match_operand:DI 2 "reg_or_0_operand")]
5670 "TARGET_MAX"
5671 {
5672 alpha_expand_builtin_vector_binop (gen_umaxv8qi3, V8QImode, operands[0],
5673 operands[1], operands[2]);
5674 DONE;
5675 })
5676
5677 (define_expand "builtin_maxsb8"
5678 [(match_operand:DI 0 "register_operand")
5679 (match_operand:DI 1 "reg_or_0_operand")
5680 (match_operand:DI 2 "reg_or_0_operand")]
5681 "TARGET_MAX"
5682 {
5683 alpha_expand_builtin_vector_binop (gen_smaxv8qi3, V8QImode, operands[0],
5684 operands[1], operands[2]);
5685 DONE;
5686 })
5687
5688 (define_expand "builtin_maxuw4"
5689 [(match_operand:DI 0 "register_operand")
5690 (match_operand:DI 1 "reg_or_0_operand")
5691 (match_operand:DI 2 "reg_or_0_operand")]
5692 "TARGET_MAX"
5693 {
5694 alpha_expand_builtin_vector_binop (gen_umaxv4hi3, V4HImode, operands[0],
5695 operands[1], operands[2]);
5696 DONE;
5697 })
5698
5699 (define_expand "builtin_maxsw4"
5700 [(match_operand:DI 0 "register_operand")
5701 (match_operand:DI 1 "reg_or_0_operand")
5702 (match_operand:DI 2 "reg_or_0_operand")]
5703 "TARGET_MAX"
5704 {
5705 alpha_expand_builtin_vector_binop (gen_smaxv4hi3, V4HImode, operands[0],
5706 operands[1], operands[2]);
5707 DONE;
5708 })
5709
5710 (define_insn "builtin_perr"
5711 [(set (match_operand:DI 0 "register_operand" "=r")
5712 (unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "%rJ")
5713 (match_operand:DI 2 "reg_or_8bit_operand" "rJ")]
5714 UNSPEC_PERR))]
5715 "TARGET_MAX"
5716 "perr %r1,%r2,%0"
5717 [(set_attr "type" "mvi")])
5718
5719 (define_expand "builtin_pklb"
5720 [(set (match_operand:DI 0 "register_operand")
5721 (vec_concat:V8QI
5722 (vec_concat:V4QI
5723 (truncate:V2QI (match_operand:DI 1 "register_operand"))
5724 (match_dup 2))
5725 (match_dup 3)))]
5726 "TARGET_MAX"
5727 {
5728 operands[0] = gen_lowpart (V8QImode, operands[0]);
5729 operands[1] = gen_lowpart (V2SImode, operands[1]);
5730 operands[2] = CONST0_RTX (V2QImode);
5731 operands[3] = CONST0_RTX (V4QImode);
5732 })
5733
5734 (define_insn "*pklb"
5735 [(set (match_operand:V8QI 0 "register_operand" "=r")
5736 (vec_concat:V8QI
5737 (vec_concat:V4QI
5738 (truncate:V2QI (match_operand:V2SI 1 "register_operand" "r"))
5739 (match_operand:V2QI 2 "const0_operand"))
5740 (match_operand:V4QI 3 "const0_operand")))]
5741 "TARGET_MAX"
5742 "pklb %r1,%0"
5743 [(set_attr "type" "mvi")])
5744
5745 (define_expand "builtin_pkwb"
5746 [(set (match_operand:DI 0 "register_operand")
5747 (vec_concat:V8QI
5748 (truncate:V4QI (match_operand:DI 1 "register_operand"))
5749 (match_dup 2)))]
5750 "TARGET_MAX"
5751 {
5752 operands[0] = gen_lowpart (V8QImode, operands[0]);
5753 operands[1] = gen_lowpart (V4HImode, operands[1]);
5754 operands[2] = CONST0_RTX (V4QImode);
5755 })
5756
5757 (define_insn "*pkwb"
5758 [(set (match_operand:V8QI 0 "register_operand" "=r")
5759 (vec_concat:V8QI
5760 (truncate:V4QI (match_operand:V4HI 1 "register_operand" "r"))
5761 (match_operand:V4QI 2 "const0_operand")))]
5762 "TARGET_MAX"
5763 "pkwb %r1,%0"
5764 [(set_attr "type" "mvi")])
5765
5766 (define_expand "builtin_unpkbl"
5767 [(set (match_operand:DI 0 "register_operand")
5768 (zero_extend:V2SI
5769 (vec_select:V2QI (match_operand:DI 1 "register_operand")
5770 (parallel [(const_int 0) (const_int 1)]))))]
5771 "TARGET_MAX"
5772 {
5773 operands[0] = gen_lowpart (V2SImode, operands[0]);
5774 operands[1] = gen_lowpart (V8QImode, operands[1]);
5775 })
5776
5777 (define_insn "*unpkbl"
5778 [(set (match_operand:V2SI 0 "register_operand" "=r")
5779 (zero_extend:V2SI
5780 (vec_select:V2QI (match_operand:V8QI 1 "reg_or_0_operand" "rW")
5781 (parallel [(const_int 0) (const_int 1)]))))]
5782 "TARGET_MAX"
5783 "unpkbl %r1,%0"
5784 [(set_attr "type" "mvi")])
5785
5786 (define_expand "builtin_unpkbw"
5787 [(set (match_operand:DI 0 "register_operand")
5788 (zero_extend:V4HI
5789 (vec_select:V4QI (match_operand:DI 1 "register_operand")
5790 (parallel [(const_int 0)
5791 (const_int 1)
5792 (const_int 2)
5793 (const_int 3)]))))]
5794 "TARGET_MAX"
5795 {
5796 operands[0] = gen_lowpart (V4HImode, operands[0]);
5797 operands[1] = gen_lowpart (V8QImode, operands[1]);
5798 })
5799
5800 (define_insn "*unpkbw"
5801 [(set (match_operand:V4HI 0 "register_operand" "=r")
5802 (zero_extend:V4HI
5803 (vec_select:V4QI (match_operand:V8QI 1 "reg_or_0_operand" "rW")
5804 (parallel [(const_int 0)
5805 (const_int 1)
5806 (const_int 2)
5807 (const_int 3)]))))]
5808 "TARGET_MAX"
5809 "unpkbw %r1,%0"
5810 [(set_attr "type" "mvi")])
5811 \f
5812 (include "sync.md")
5813 \f
5814 ;; The call patterns are at the end of the file because their
5815 ;; wildcard operand0 interferes with nice recognition.
5816
5817 (define_insn "*call_value_osf_1_er_noreturn"
5818 [(set (match_operand 0)
5819 (call (mem:DI (match_operand:DI 1 "call_operand" "c,R,s"))
5820 (match_operand 2)))
5821 (use (reg:DI 29))
5822 (clobber (reg:DI 26))]
5823 "TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF
5824 && find_reg_note (insn, REG_NORETURN, NULL_RTX)"
5825 "@
5826 jsr $26,($27),0
5827 bsr $26,%1\t\t!samegp
5828 ldq $27,%1($29)\t\t!literal!%#\;jsr $26,($27),%1\t\t!lituse_jsr!%#"
5829 [(set_attr "type" "jsr")
5830 (set_attr "length" "*,*,8")])
5831
5832 (define_insn "*call_value_osf_1_er"
5833 [(set (match_operand 0)
5834 (call (mem:DI (match_operand:DI 1 "call_operand" "c,R,s"))
5835 (match_operand 2)))
5836 (use (reg:DI 29))
5837 (clobber (reg:DI 26))]
5838 "TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF"
5839 "@
5840 jsr $26,(%1),0\;ldah $29,0($26)\t\t!gpdisp!%*\;lda $29,0($29)\t\t!gpdisp!%*
5841 bsr $26,%1\t\t!samegp
5842 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!%*"
5843 [(set_attr "type" "jsr")
5844 (set_attr "length" "12,*,16")])
5845
5846 ;; We must use peep2 instead of a split because we need accurate life
5847 ;; information for $gp. Consider the case of { bar(); while (1); }.
5848 (define_peephole2
5849 [(parallel [(set (match_operand 0)
5850 (call (mem:DI (match_operand:DI 1 "call_operand"))
5851 (match_operand 2)))
5852 (use (reg:DI 29))
5853 (clobber (reg:DI 26))])]
5854 "TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF && reload_completed
5855 && ! samegp_function_operand (operands[1], Pmode)
5856 && (peep2_regno_dead_p (1, 29)
5857 || find_reg_note (insn, REG_NORETURN, NULL_RTX))"
5858 [(parallel [(set (match_dup 0)
5859 (call (mem:DI (match_dup 3))
5860 (match_dup 2)))
5861 (use (reg:DI 29))
5862 (use (match_dup 1))
5863 (use (match_dup 4))
5864 (clobber (reg:DI 26))])]
5865 {
5866 if (CONSTANT_P (operands[1]))
5867 {
5868 operands[3] = gen_rtx_REG (Pmode, 27);
5869 operands[4] = GEN_INT (alpha_next_sequence_number++);
5870 emit_insn (gen_movdi_er_high_g (operands[3], pic_offset_table_rtx,
5871 operands[1], operands[4]));
5872 }
5873 else
5874 {
5875 operands[3] = operands[1];
5876 operands[1] = const0_rtx;
5877 operands[4] = const0_rtx;
5878 }
5879 })
5880
5881 (define_peephole2
5882 [(parallel [(set (match_operand 0)
5883 (call (mem:DI (match_operand:DI 1 "call_operand"))
5884 (match_operand 2)))
5885 (use (reg:DI 29))
5886 (clobber (reg:DI 26))])]
5887 "TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF && reload_completed
5888 && ! samegp_function_operand (operands[1], Pmode)
5889 && ! (peep2_regno_dead_p (1, 29)
5890 || find_reg_note (insn, REG_NORETURN, NULL_RTX))"
5891 [(parallel [(set (match_dup 0)
5892 (call (mem:DI (match_dup 3))
5893 (match_dup 2)))
5894 (set (match_dup 6)
5895 (unspec:DI [(match_dup 6) (match_dup 4)] UNSPEC_LDGP1))
5896 (use (match_dup 1))
5897 (use (match_dup 5))
5898 (clobber (reg:DI 26))])
5899 (set (match_dup 6)
5900 (unspec:DI [(match_dup 6) (match_dup 4)] UNSPEC_LDGP2))]
5901 {
5902 if (CONSTANT_P (operands[1]))
5903 {
5904 operands[3] = gen_rtx_REG (Pmode, 27);
5905 operands[5] = GEN_INT (alpha_next_sequence_number++);
5906 emit_insn (gen_movdi_er_high_g (operands[3], pic_offset_table_rtx,
5907 operands[1], operands[5]));
5908 }
5909 else
5910 {
5911 operands[3] = operands[1];
5912 operands[1] = const0_rtx;
5913 operands[5] = const0_rtx;
5914 }
5915 operands[4] = GEN_INT (alpha_next_sequence_number++);
5916 operands[6] = pic_offset_table_rtx;
5917 })
5918
5919 (define_insn "*call_value_osf_2_er_nogp"
5920 [(set (match_operand 0)
5921 (call (mem:DI (match_operand:DI 1 "register_operand" "c"))
5922 (match_operand 2)))
5923 (use (reg:DI 29))
5924 (use (match_operand 3))
5925 (use (match_operand 4))
5926 (clobber (reg:DI 26))]
5927 "TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF"
5928 "jsr $26,(%1),%3%J4"
5929 [(set_attr "type" "jsr")])
5930
5931 (define_insn "*call_value_osf_2_er"
5932 [(set (match_operand 0)
5933 (call (mem:DI (match_operand:DI 1 "register_operand" "c"))
5934 (match_operand 2)))
5935 (set (reg:DI 29)
5936 (unspec:DI [(reg:DI 29) (match_operand 5 "const_int_operand")]
5937 UNSPEC_LDGP1))
5938 (use (match_operand 3))
5939 (use (match_operand 4))
5940 (clobber (reg:DI 26))]
5941 "TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF"
5942 "jsr $26,(%1),%3%J4\;ldah $29,0($26)\t\t!gpdisp!%5"
5943 [(set_attr "type" "jsr")
5944 (set_attr "cannot_copy" "true")
5945 (set_attr "length" "8")])
5946
5947 (define_insn "*call_value_osf_1_noreturn"
5948 [(set (match_operand 0)
5949 (call (mem:DI (match_operand:DI 1 "call_operand" "c,R,s"))
5950 (match_operand 2)))
5951 (use (reg:DI 29))
5952 (clobber (reg:DI 26))]
5953 "! TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF
5954 && find_reg_note (insn, REG_NORETURN, NULL_RTX)"
5955 "@
5956 jsr $26,($27),0
5957 bsr $26,$%1..ng
5958 jsr $26,%1"
5959 [(set_attr "type" "jsr")
5960 (set_attr "length" "*,*,8")])
5961
5962 (define_int_iterator TLS_CALL
5963 [UNSPEC_TLSGD_CALL
5964 UNSPEC_TLSLDM_CALL])
5965
5966 (define_int_attr tls
5967 [(UNSPEC_TLSGD_CALL "tlsgd")
5968 (UNSPEC_TLSLDM_CALL "tlsldm")])
5969
5970 (define_insn "call_value_osf_<tls>"
5971 [(set (match_operand 0)
5972 (call (mem:DI (match_operand:DI 1 "symbolic_operand"))
5973 (const_int 0)))
5974 (unspec [(match_operand:DI 2 "const_int_operand")] TLS_CALL)
5975 (use (reg:DI 29))
5976 (clobber (reg:DI 26))]
5977 "HAVE_AS_TLS"
5978 "ldq $27,%1($29)\t\t!literal!%2\;jsr $26,($27),%1\t\t!lituse_<tls>!%2\;ldah $29,0($26)\t\t!gpdisp!%*\;lda $29,0($29)\t\t!gpdisp!%*"
5979 [(set_attr "type" "jsr")
5980 (set_attr "length" "16")])
5981
5982 ;; We must use peep2 instead of a split because we need accurate life
5983 ;; information for $gp.
5984 (define_peephole2
5985 [(parallel
5986 [(set (match_operand 0)
5987 (call (mem:DI (match_operand:DI 1 "symbolic_operand"))
5988 (const_int 0)))
5989 (unspec [(match_operand:DI 2 "const_int_operand")] TLS_CALL)
5990 (use (reg:DI 29))
5991 (clobber (reg:DI 26))])]
5992 "HAVE_AS_TLS && reload_completed
5993 && peep2_regno_dead_p (1, 29)"
5994 [(set (match_dup 3)
5995 (unspec:DI [(match_dup 5)
5996 (match_dup 1)
5997 (match_dup 2)] UNSPEC_LITERAL))
5998 (parallel [(set (match_dup 0)
5999 (call (mem:DI (match_dup 3))
6000 (const_int 0)))
6001 (use (match_dup 5))
6002 (use (match_dup 1))
6003 (use (unspec [(match_dup 2)] TLS_CALL))
6004 (clobber (reg:DI 26))])
6005 (set (match_dup 5)
6006 (unspec:DI [(match_dup 5) (match_dup 4)] UNSPEC_LDGP2))]
6007 {
6008 operands[3] = gen_rtx_REG (Pmode, 27);
6009 operands[4] = GEN_INT (alpha_next_sequence_number++);
6010 operands[5] = pic_offset_table_rtx;
6011 })
6012
6013 (define_peephole2
6014 [(parallel
6015 [(set (match_operand 0)
6016 (call (mem:DI (match_operand:DI 1 "symbolic_operand"))
6017 (const_int 0)))
6018 (unspec [(match_operand:DI 2 "const_int_operand")] TLS_CALL)
6019 (use (reg:DI 29))
6020 (clobber (reg:DI 26))])]
6021 "HAVE_AS_TLS && reload_completed
6022 && !peep2_regno_dead_p (1, 29)"
6023 [(set (match_dup 3)
6024 (unspec:DI [(match_dup 5)
6025 (match_dup 1)
6026 (match_dup 2)] UNSPEC_LITERAL))
6027 (parallel [(set (match_dup 0)
6028 (call (mem:DI (match_dup 3))
6029 (const_int 0)))
6030 (set (match_dup 5)
6031 (unspec:DI [(match_dup 5) (match_dup 4)] UNSPEC_LDGP1))
6032 (use (match_dup 1))
6033 (use (unspec [(match_dup 2)] TLS_CALL))
6034 (clobber (reg:DI 26))])
6035 (set (match_dup 5)
6036 (unspec:DI [(match_dup 5) (match_dup 4)] UNSPEC_LDGP2))]
6037 {
6038 operands[3] = gen_rtx_REG (Pmode, 27);
6039 operands[4] = GEN_INT (alpha_next_sequence_number++);
6040 operands[5] = pic_offset_table_rtx;
6041 })
6042
6043 (define_insn "*call_value_osf_1"
6044 [(set (match_operand 0)
6045 (call (mem:DI (match_operand:DI 1 "call_operand" "c,R,s"))
6046 (match_operand 2)))
6047 (use (reg:DI 29))
6048 (clobber (reg:DI 26))]
6049 "! TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF"
6050 "@
6051 jsr $26,($27),0\;ldgp $29,0($26)
6052 bsr $26,$%1..ng
6053 jsr $26,%1\;ldgp $29,0($26)"
6054 [(set_attr "type" "jsr")
6055 (set_attr "length" "12,*,16")])
6056
6057 (define_insn "*sibcall_value_osf_1_er"
6058 [(set (match_operand 0)
6059 (call (mem:DI (match_operand:DI 1 "symbolic_operand" "R,s"))
6060 (match_operand 2)))
6061 (unspec [(reg:DI 29)] UNSPEC_SIBCALL)]
6062 "TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF"
6063 "@
6064 br $31,%1\t\t!samegp
6065 ldq $27,%1($29)\t\t!literal!%#\;jmp $31,($27),%1\t\t!lituse_jsr!%#"
6066 [(set_attr "type" "jsr")
6067 (set_attr "length" "*,8")])
6068
6069 (define_insn "*sibcall_value_osf_1"
6070 [(set (match_operand 0)
6071 (call (mem:DI (match_operand:DI 1 "symbolic_operand" "R,s"))
6072 (match_operand 2)))
6073 (unspec [(reg:DI 29)] UNSPEC_SIBCALL)]
6074 "! TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF"
6075 "@
6076 br $31,$%1..ng
6077 lda $27,%1\;jmp $31,($27),%1"
6078 [(set_attr "type" "jsr")
6079 (set_attr "length" "*,8")])
6080
6081 ; GAS relies on the order and position of instructions output below in order
6082 ; to generate relocs for VMS link to potentially optimize the call.
6083 ; Please do not molest.
6084 (define_insn "*call_value_vms_1"
6085 [(set (match_operand 0)
6086 (call (mem:DI (match_operand:DI 1 "call_operand" "r,s"))
6087 (match_operand 2)))
6088 (use (match_operand:DI 3 "nonmemory_operand" "r,n"))
6089 (use (reg:DI 25))
6090 (use (reg:DI 26))
6091 (clobber (reg:DI 27))]
6092 "TARGET_ABI_OPEN_VMS"
6093 {
6094 switch (which_alternative)
6095 {
6096 case 0:
6097 return "mov %3,$27\;jsr $26,0\;ldq $27,0($29)";
6098 case 1:
6099 operands [3] = alpha_use_linkage (operands [1], true, false);
6100 operands [4] = alpha_use_linkage (operands [1], false, false);
6101 return "ldq $26,%4\;ldq $27,%3\;jsr $26,%1\;ldq $27,0($29)";
6102 default:
6103 gcc_unreachable ();
6104 }
6105 }
6106 [(set_attr "type" "jsr")
6107 (set_attr "length" "12,16")])