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