alpha.md revision 1.5 1 ;; Machine description for DEC Alpha for GNU C compiler
2 ;; Copyright (C) 1992-2015 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 (use (reg:DI 29))]
3774 ""
3775 "call_pal 0x81"
3776 [(set_attr "type" "callpal")])
3777
3778 ;; For userland, we load the thread pointer from the TCB.
3779 ;; For the kernel, we load the per-cpu private value.
3780
3781 (define_insn "get_thread_pointerdi"
3782 [(set (match_operand:DI 0 "register_operand" "=v")
3783 (unspec:DI [(const_int 0)] UNSPEC_TP))]
3784 "TARGET_ABI_OSF"
3785 {
3786 if (TARGET_TLS_KERNEL)
3787 return "call_pal 0x32";
3788 else
3789 return "call_pal 0x9e";
3790 }
3791 [(set_attr "type" "callpal")])
3792
3793 ;; For completeness, and possibly a __builtin function, here's how to
3794 ;; set the thread pointer. Since we don't describe enough of this
3795 ;; quantity for CSE, we have to use a volatile unspec, and then there's
3796 ;; not much point in creating an R16_REG register class.
3797
3798 (define_expand "set_thread_pointerdi"
3799 [(set (reg:DI 16) (match_operand:DI 0 "input_operand"))
3800 (unspec_volatile [(reg:DI 16)] UNSPECV_SET_TP)]
3801 "TARGET_ABI_OSF")
3802
3803 (define_insn "*set_tp"
3804 [(unspec_volatile [(reg:DI 16)] UNSPECV_SET_TP)]
3805 "TARGET_ABI_OSF"
3806 {
3807 if (TARGET_TLS_KERNEL)
3808 return "call_pal 0x31";
3809 else
3810 return "call_pal 0x9f";
3811 }
3812 [(set_attr "type" "callpal")])
3813
3814 ;; Special builtins for establishing and reverting VMS condition handlers.
3815
3816 (define_expand "builtin_establish_vms_condition_handler"
3817 [(set (reg:DI 0) (match_operand:DI 0 "register_operand"))
3818 (use (match_operand:DI 1 "address_operand"))]
3819 "TARGET_ABI_OPEN_VMS"
3820 {
3821 alpha_expand_builtin_establish_vms_condition_handler (operands[0],
3822 operands[1]);
3823 })
3824
3825 (define_expand "builtin_revert_vms_condition_handler"
3826 [(set (reg:DI 0) (match_operand:DI 0 "register_operand"))]
3827 "TARGET_ABI_OPEN_VMS"
3828 "alpha_expand_builtin_revert_vms_condition_handler (operands[0]);")
3829
3831 ;; Finally, we have the basic data motion insns. The byte and word insns
3832 ;; are done via define_expand. Start with the floating-point insns, since
3833 ;; they are simpler.
3834
3835 (define_expand "movsf"
3836 [(set (match_operand:SF 0 "nonimmediate_operand")
3837 (match_operand:SF 1 "general_operand"))]
3838 ""
3839 {
3840 if (MEM_P (operands[0])
3841 && ! reg_or_0_operand (operands[1], SFmode))
3842 operands[1] = force_reg (SFmode, operands[1]);
3843 })
3844
3845 (define_insn "*movsf"
3846 [(set (match_operand:SF 0 "nonimmediate_operand" "=f,f,*r,*r,m,m,f,*r")
3847 (match_operand:SF 1 "input_operand" "fG,m,*rG,m,fG,*r,*r,f"))]
3848 "register_operand (operands[0], SFmode)
3849 || reg_or_0_operand (operands[1], SFmode)"
3850 "@
3851 cpys %R1,%R1,%0
3852 ld%, %0,%1
3853 bis $31,%r1,%0
3854 ldl %0,%1
3855 st%, %R1,%0
3856 stl %r1,%0
3857 itofs %1,%0
3858 ftois %1,%0"
3859 [(set_attr "type" "fcpys,fld,ilog,ild,fst,ist,itof,ftoi")
3860 (set_attr "isa" "*,*,*,*,*,*,fix,fix")])
3861
3862 (define_expand "movdf"
3863 [(set (match_operand:DF 0 "nonimmediate_operand")
3864 (match_operand:DF 1 "general_operand"))]
3865 ""
3866 {
3867 if (MEM_P (operands[0])
3868 && ! reg_or_0_operand (operands[1], DFmode))
3869 operands[1] = force_reg (DFmode, operands[1]);
3870 })
3871
3872 (define_insn "*movdf"
3873 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,f,*r,*r,m,m,f,*r")
3874 (match_operand:DF 1 "input_operand" "fG,m,*rG,m,fG,*r,*r,f"))]
3875 "register_operand (operands[0], DFmode)
3876 || reg_or_0_operand (operands[1], DFmode)"
3877 "@
3878 cpys %R1,%R1,%0
3879 ld%- %0,%1
3880 bis $31,%r1,%0
3881 ldq %0,%1
3882 st%- %R1,%0
3883 stq %r1,%0
3884 itoft %1,%0
3885 ftoit %1,%0"
3886 [(set_attr "type" "fcpys,fld,ilog,ild,fst,ist,itof,ftoi")
3887 (set_attr "isa" "*,*,*,*,*,*,fix,fix")])
3888
3889 ;; Subregs suck for register allocation. Pretend we can move TFmode
3890 ;; data between general registers until after reload.
3891 ;; ??? Is this still true now that we have the lower-subreg pass?
3892
3893 (define_expand "movtf"
3894 [(set (match_operand:TF 0 "nonimmediate_operand")
3895 (match_operand:TF 1 "general_operand"))]
3896 ""
3897 {
3898 if (MEM_P (operands[0])
3899 && ! reg_or_0_operand (operands[1], TFmode))
3900 operands[1] = force_reg (TFmode, operands[1]);
3901 })
3902
3903 (define_insn_and_split "*movtf"
3904 [(set (match_operand:TF 0 "nonimmediate_operand" "=r,o")
3905 (match_operand:TF 1 "input_operand" "roG,rG"))]
3906 "register_operand (operands[0], TFmode)
3907 || reg_or_0_operand (operands[1], TFmode)"
3908 "#"
3909 "reload_completed"
3910 [(set (match_dup 0) (match_dup 2))
3911 (set (match_dup 1) (match_dup 3))]
3912 "alpha_split_tmode_pair (operands, TFmode, true);")
3913
3914 ;; We do two major things here: handle mem->mem and construct long
3915 ;; constants.
3916
3917 (define_expand "movsi"
3918 [(set (match_operand:SI 0 "nonimmediate_operand")
3919 (match_operand:SI 1 "general_operand"))]
3920 ""
3921 {
3922 if (alpha_expand_mov (SImode, operands))
3923 DONE;
3924 })
3925
3926 (define_insn "*movsi"
3927 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,r,r,r,m,r")
3928 (match_operand:SI 1 "input_operand" "rJ,K,L,n,m,rJ,s"))]
3929 "register_operand (operands[0], SImode)
3930 || reg_or_0_operand (operands[1], SImode)"
3931 "@
3932 bis $31,%r1,%0
3933 lda %0,%1($31)
3934 ldah %0,%h1($31)
3935 #
3936 ldl %0,%1
3937 stl %r1,%0
3938 lda %0,%1"
3939 [(set_attr "type" "ilog,iadd,iadd,multi,ild,ist,ldsym")
3940 (set_attr "isa" "*,*,*,*,*,*,vms")])
3941
3942 ;; Split a load of a large constant into the appropriate two-insn
3943 ;; sequence.
3944
3945 (define_split
3946 [(set (match_operand:SI 0 "register_operand")
3947 (match_operand:SI 1 "non_add_const_operand"))]
3948 ""
3949 [(const_int 0)]
3950 {
3951 if (alpha_split_const_mov (SImode, operands))
3952 DONE;
3953 else
3954 FAIL;
3955 })
3956
3957 (define_insn "*movdi_er_low_l"
3958 [(set (match_operand:DI 0 "register_operand" "=r")
3959 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
3960 (match_operand:DI 2 "local_symbolic_operand")))]
3961 "TARGET_EXPLICIT_RELOCS"
3962 {
3963 if (true_regnum (operands[1]) == 29)
3964 return "lda %0,%2(%1)\t\t!gprel";
3965 else
3966 return "lda %0,%2(%1)\t\t!gprellow";
3967 }
3968 [(set_attr "usegp" "yes")])
3969
3970 (define_split
3971 [(set (match_operand:DI 0 "register_operand")
3972 (match_operand:DI 1 "small_symbolic_operand"))]
3973 "TARGET_EXPLICIT_RELOCS && reload_completed"
3974 [(set (match_dup 0)
3975 (lo_sum:DI (match_dup 2) (match_dup 1)))]
3976 "operands[2] = pic_offset_table_rtx;")
3977
3978 (define_split
3979 [(set (match_operand:DI 0 "register_operand")
3980 (match_operand:DI 1 "local_symbolic_operand"))]
3981 "TARGET_EXPLICIT_RELOCS && reload_completed"
3982 [(set (match_dup 0)
3983 (plus:DI (match_dup 2) (high:DI (match_dup 1))))
3984 (set (match_dup 0)
3985 (lo_sum:DI (match_dup 0) (match_dup 1)))]
3986 "operands[2] = pic_offset_table_rtx;")
3987
3988 (define_split
3989 [(match_operand 0 "some_small_symbolic_operand")]
3990 ""
3991 [(match_dup 0)]
3992 "operands[0] = split_small_symbolic_operand (operands[0]);")
3993
3994 ;; Accepts any symbolic, not just global, since function calls that
3995 ;; don't go via bsr still use !literal in hopes of linker relaxation.
3996 (define_insn "movdi_er_high_g"
3997 [(set (match_operand:DI 0 "register_operand" "=r")
3998 (unspec:DI [(match_operand:DI 1 "register_operand" "r")
3999 (match_operand:DI 2 "symbolic_operand")
4000 (match_operand 3 "const_int_operand")]
4001 UNSPEC_LITERAL))]
4002 "TARGET_EXPLICIT_RELOCS"
4003 {
4004 if (INTVAL (operands[3]) == 0)
4005 return "ldq %0,%2(%1)\t\t!literal";
4006 else
4007 return "ldq %0,%2(%1)\t\t!literal!%3";
4008 }
4009 [(set_attr "type" "ldsym")])
4010
4011 (define_split
4012 [(set (match_operand:DI 0 "register_operand")
4013 (match_operand:DI 1 "global_symbolic_operand"))]
4014 "TARGET_EXPLICIT_RELOCS && reload_completed"
4015 [(set (match_dup 0)
4016 (unspec:DI [(match_dup 2)
4017 (match_dup 1)
4018 (const_int 0)] UNSPEC_LITERAL))]
4019 "operands[2] = pic_offset_table_rtx;")
4020
4021 (define_insn "movdi_er_tlsgd"
4022 [(set (match_operand:DI 0 "register_operand" "=r")
4023 (unspec:DI [(match_operand:DI 1 "register_operand" "r")
4024 (match_operand:DI 2 "symbolic_operand")
4025 (match_operand 3 "const_int_operand")]
4026 UNSPEC_TLSGD))]
4027 "HAVE_AS_TLS"
4028 {
4029 if (INTVAL (operands[3]) == 0)
4030 return "lda %0,%2(%1)\t\t!tlsgd";
4031 else
4032 return "lda %0,%2(%1)\t\t!tlsgd!%3";
4033 })
4034
4035 (define_insn "movdi_er_tlsldm"
4036 [(set (match_operand:DI 0 "register_operand" "=r")
4037 (unspec:DI [(match_operand:DI 1 "register_operand" "r")
4038 (match_operand 2 "const_int_operand")]
4039 UNSPEC_TLSLDM))]
4040 "HAVE_AS_TLS"
4041 {
4042 if (INTVAL (operands[2]) == 0)
4043 return "lda %0,%&(%1)\t\t!tlsldm";
4044 else
4045 return "lda %0,%&(%1)\t\t!tlsldm!%2";
4046 })
4047
4048 (define_insn "*movdi_er_gotdtp"
4049 [(set (match_operand:DI 0 "register_operand" "=r")
4050 (unspec:DI [(match_operand:DI 1 "register_operand" "r")
4051 (match_operand:DI 2 "symbolic_operand")]
4052 UNSPEC_DTPREL))]
4053 "HAVE_AS_TLS"
4054 "ldq %0,%2(%1)\t\t!gotdtprel"
4055 [(set_attr "type" "ild")
4056 (set_attr "usegp" "yes")])
4057
4058 (define_split
4059 [(set (match_operand:DI 0 "register_operand")
4060 (match_operand:DI 1 "gotdtp_symbolic_operand"))]
4061 "HAVE_AS_TLS && reload_completed"
4062 [(set (match_dup 0)
4063 (unspec:DI [(match_dup 2)
4064 (match_dup 1)] UNSPEC_DTPREL))]
4065 {
4066 operands[1] = XVECEXP (XEXP (operands[1], 0), 0, 0);
4067 operands[2] = pic_offset_table_rtx;
4068 })
4069
4070 (define_insn "*movdi_er_gottp"
4071 [(set (match_operand:DI 0 "register_operand" "=r")
4072 (unspec:DI [(match_operand:DI 1 "register_operand" "r")
4073 (match_operand:DI 2 "symbolic_operand")]
4074 UNSPEC_TPREL))]
4075 "HAVE_AS_TLS"
4076 "ldq %0,%2(%1)\t\t!gottprel"
4077 [(set_attr "type" "ild")
4078 (set_attr "usegp" "yes")])
4079
4080 (define_split
4081 [(set (match_operand:DI 0 "register_operand")
4082 (match_operand:DI 1 "gottp_symbolic_operand"))]
4083 "HAVE_AS_TLS && reload_completed"
4084 [(set (match_dup 0)
4085 (unspec:DI [(match_dup 2)
4086 (match_dup 1)] UNSPEC_TPREL))]
4087 {
4088 operands[1] = XVECEXP (XEXP (operands[1], 0), 0, 0);
4089 operands[2] = pic_offset_table_rtx;
4090 })
4091
4092 (define_insn "*movdi"
4093 [(set (match_operand:DI 0 "nonimmediate_operand"
4094 "=r,r,r,r,r,r,r,r, m, *f,*f, Q, r,*f")
4095 (match_operand:DI 1 "input_operand"
4096 "rJ,K,L,T,s,n,s,m,rJ,*fJ, Q,*f,*f, r"))]
4097 "register_operand (operands[0], DImode)
4098 || reg_or_0_operand (operands[1], DImode)"
4099 "@
4100 mov %r1,%0
4101 lda %0,%1($31)
4102 ldah %0,%h1($31)
4103 #
4104 #
4105 #
4106 lda %0,%1
4107 ldq%A1 %0,%1
4108 stq%A0 %r1,%0
4109 fmov %R1,%0
4110 ldt %0,%1
4111 stt %R1,%0
4112 ftoit %1,%0
4113 itoft %1,%0"
4114 [(set_attr "type" "ilog,iadd,iadd,iadd,ldsym,multi,ldsym,ild,ist,fcpys,fld,fst,ftoi,itof")
4115 (set_attr "isa" "*,*,*,er,er,*,ner,*,*,*,*,*,fix,fix")
4116 (set_attr "usegp" "*,*,*,yes,*,*,*,*,*,*,*,*,*,*")])
4117
4118 ;; VMS needs to set up "vms_base_regno" for unwinding. This move
4119 ;; often appears dead to the life analysis code, at which point we
4120 ;; die for emitting dead prologue instructions. Force this live.
4121
4122 (define_insn "force_movdi"
4123 [(set (match_operand:DI 0 "register_operand" "=r")
4124 (unspec_volatile:DI [(match_operand:DI 1 "register_operand" "r")]
4125 UNSPECV_FORCE_MOV))]
4126 ""
4127 "mov %1,%0"
4128 [(set_attr "type" "ilog")])
4129
4130 ;; We do three major things here: handle mem->mem, put 64-bit constants in
4131 ;; memory, and construct long 32-bit constants.
4132
4133 (define_expand "movdi"
4134 [(set (match_operand:DI 0 "nonimmediate_operand")
4135 (match_operand:DI 1 "general_operand"))]
4136 ""
4137 {
4138 if (alpha_expand_mov (DImode, operands))
4139 DONE;
4140 })
4141
4142 ;; Split a load of a large constant into the appropriate two-insn
4143 ;; sequence.
4144
4145 (define_split
4146 [(set (match_operand:DI 0 "register_operand")
4147 (match_operand:DI 1 "non_add_const_operand"))]
4148 ""
4149 [(const_int 0)]
4150 {
4151 if (alpha_split_const_mov (DImode, operands))
4152 DONE;
4153 else
4154 FAIL;
4155 })
4156
4157 ;; We need to prevent reload from splitting TImode moves, because it
4158 ;; might decide to overwrite a pointer with the value it points to.
4159 ;; In that case we have to do the loads in the appropriate order so
4160 ;; that the pointer is not destroyed too early.
4161
4162 (define_insn_and_split "*movti_internal"
4163 [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o")
4164 (match_operand:TI 1 "input_operand" "roJ,rJ"))]
4165 "(register_operand (operands[0], TImode)
4166 /* Prevent rematerialization of constants. */
4167 && ! CONSTANT_P (operands[1]))
4168 || reg_or_0_operand (operands[1], TImode)"
4169 "#"
4170 "reload_completed"
4171 [(set (match_dup 0) (match_dup 2))
4172 (set (match_dup 1) (match_dup 3))]
4173 "alpha_split_tmode_pair (operands, TImode, true);")
4174
4175 (define_expand "movti"
4176 [(set (match_operand:TI 0 "nonimmediate_operand")
4177 (match_operand:TI 1 "general_operand"))]
4178 ""
4179 {
4180 if (MEM_P (operands[0])
4181 && ! reg_or_0_operand (operands[1], TImode))
4182 operands[1] = force_reg (TImode, operands[1]);
4183
4184 if (operands[1] == const0_rtx)
4185 ;
4186 /* We must put 64-bit constants in memory. We could keep the
4187 32-bit constants in TImode and rely on the splitter, but
4188 this doesn't seem to be worth the pain. */
4189 else if (CONST_INT_P (operands[1])
4190 || GET_CODE (operands[1]) == CONST_DOUBLE)
4191 {
4192 rtx in[2], out[2], target;
4193
4194 gcc_assert (can_create_pseudo_p ());
4195
4196 split_double (operands[1], &in[0], &in[1]);
4197
4198 if (in[0] == const0_rtx)
4199 out[0] = const0_rtx;
4200 else
4201 {
4202 out[0] = gen_reg_rtx (DImode);
4203 emit_insn (gen_movdi (out[0], in[0]));
4204 }
4205
4206 if (in[1] == const0_rtx)
4207 out[1] = const0_rtx;
4208 else
4209 {
4210 out[1] = gen_reg_rtx (DImode);
4211 emit_insn (gen_movdi (out[1], in[1]));
4212 }
4213
4214 if (!REG_P (operands[0]))
4215 target = gen_reg_rtx (TImode);
4216 else
4217 target = operands[0];
4218
4219 emit_insn (gen_movdi (operand_subword (target, 0, 0, TImode), out[0]));
4220 emit_insn (gen_movdi (operand_subword (target, 1, 0, TImode), out[1]));
4221
4222 if (target != operands[0])
4223 emit_insn (gen_rtx_SET (VOIDmode, operands[0], target));
4224
4225 DONE;
4226 }
4227 })
4228
4229 ;; These are the partial-word cases.
4230 ;;
4231 ;; First we have the code to load an aligned word. Operand 0 is the register
4232 ;; in which to place the result. It's mode is QImode or HImode. Operand 1
4233 ;; is an SImode MEM at the low-order byte of the proper word. Operand 2 is the
4234 ;; number of bits within the word that the value is. Operand 3 is an SImode
4235 ;; scratch register. If operand 0 is a hard register, operand 3 may be the
4236 ;; same register. It is allowed to conflict with operand 1 as well.
4237
4238 (define_expand "aligned_loadqi"
4239 [(set (match_operand:SI 3 "register_operand")
4240 (match_operand:SI 1 "memory_operand"))
4241 (set (match_operand:DI 0 "register_operand")
4242 (zero_extract:DI (subreg:DI (match_dup 3) 0)
4243 (const_int 8)
4244 (match_operand:DI 2 "const_int_operand")))])
4245
4246 (define_expand "aligned_loadhi"
4247 [(set (match_operand:SI 3 "register_operand")
4248 (match_operand:SI 1 "memory_operand"))
4249 (set (match_operand:DI 0 "register_operand")
4250 (zero_extract:DI (subreg:DI (match_dup 3) 0)
4251 (const_int 16)
4252 (match_operand:DI 2 "const_int_operand")))])
4253
4254 ;; Similar for unaligned loads, where we use the sequence from the
4255 ;; Alpha Architecture manual. We have to distinguish between little-endian
4256 ;; and big-endian systems as the sequences are different.
4257 ;;
4258 ;; Operand 1 is the address. Operands 2 and 3 are temporaries, where
4259 ;; operand 3 can overlap the input and output registers.
4260
4261 (define_expand "unaligned_loadqi"
4262 [(set (match_operand:DI 2 "register_operand")
4263 (mem:DI (and:DI (match_operand:DI 1 "address_operand")
4264 (const_int -8))))
4265 (set (match_operand:DI 3 "register_operand")
4266 (match_dup 1))
4267 (set (match_operand:DI 0 "register_operand")
4268 (zero_extract:DI (match_dup 2)
4269 (const_int 8)
4270 (ashift:DI (match_dup 3) (const_int 3))))])
4271
4272 (define_expand "unaligned_loadhi"
4273 [(set (match_operand:DI 2 "register_operand")
4274 (mem:DI (and:DI (match_operand:DI 1 "address_operand")
4275 (const_int -8))))
4276 (set (match_operand:DI 3 "register_operand")
4277 (match_dup 1))
4278 (set (match_operand:DI 0 "register_operand")
4279 (zero_extract:DI (match_dup 2)
4280 (const_int 16)
4281 (ashift:DI (match_dup 3) (const_int 3))))])
4282
4283 ;; Storing an aligned byte or word requires two temporaries. Operand 0 is the
4284 ;; aligned SImode MEM. Operand 1 is the register containing the
4285 ;; byte or word to store. Operand 2 is the number of bits within the word that
4286 ;; the value should be placed. Operands 3 and 4 are SImode temporaries.
4287
4288 (define_expand "aligned_store"
4289 [(set (match_operand:SI 3 "register_operand")
4290 (match_operand:SI 0 "memory_operand"))
4291 (set (subreg:DI (match_dup 3) 0)
4292 (and:DI (subreg:DI (match_dup 3) 0) (match_dup 5)))
4293 (set (subreg:DI (match_operand:SI 4 "register_operand") 0)
4294 (ashift:DI (zero_extend:DI (match_operand 1 "register_operand"))
4295 (match_operand:DI 2 "const_int_operand")))
4296 (set (subreg:DI (match_dup 4) 0)
4297 (ior:DI (subreg:DI (match_dup 4) 0) (subreg:DI (match_dup 3) 0)))
4298 (set (match_dup 0) (match_dup 4))]
4299 ""
4300 {
4301 operands[5] = GEN_INT (~ (GET_MODE_MASK (GET_MODE (operands[1]))
4302 << INTVAL (operands[2])));
4303 })
4304
4305 ;; For the unaligned byte and halfword cases, we use code similar to that
4306 ;; in the ;; Architecture book, but reordered to lower the number of registers
4307 ;; required. Operand 0 is the address. Operand 1 is the data to store.
4308 ;; Operands 2, 3, and 4 are DImode temporaries, where operands 2 and 4 may
4309 ;; be the same temporary, if desired. If the address is in a register,
4310 ;; operand 2 can be that register.
4311
4312 (define_expand "unaligned_store<mode>"
4313 [(set (match_operand:DI 3 "register_operand")
4314 (mem:DI (and:DI (match_operand:DI 0 "address_operand")
4315 (const_int -8))))
4316 (set (match_operand:DI 2 "register_operand")
4317 (match_dup 0))
4318 (set (match_dup 3)
4319 (and:DI (not:DI (ashift:DI (match_dup 5)
4320 (ashift:DI (match_dup 2) (const_int 3))))
4321 (match_dup 3)))
4322 (set (match_operand:DI 4 "register_operand")
4323 (ashift:DI (zero_extend:DI
4324 (match_operand:I12MODE 1 "register_operand"))
4325 (ashift:DI (match_dup 2) (const_int 3))))
4326 (set (match_dup 4) (ior:DI (match_dup 4) (match_dup 3)))
4327 (set (mem:DI (and:DI (match_dup 0) (const_int -8)))
4328 (match_dup 4))]
4329 ""
4330 "operands[5] = GEN_INT (GET_MODE_MASK (<MODE>mode));")
4331
4332 ;; Here are the define_expand's for QI and HI moves that use the above
4333 ;; patterns. We have the normal sets, plus the ones that need scratch
4334 ;; registers for reload.
4335
4336 (define_expand "mov<mode>"
4337 [(set (match_operand:I12MODE 0 "nonimmediate_operand")
4338 (match_operand:I12MODE 1 "general_operand"))]
4339 ""
4340 {
4341 if (TARGET_BWX
4342 ? alpha_expand_mov (<MODE>mode, operands)
4343 : alpha_expand_mov_nobwx (<MODE>mode, operands))
4344 DONE;
4345 })
4346
4347 (define_insn "*movqi"
4348 [(set (match_operand:QI 0 "nonimmediate_operand" "=r,r,r,m")
4349 (match_operand:QI 1 "input_operand" "rJ,n,m,rJ"))]
4350 "register_operand (operands[0], QImode)
4351 || reg_or_0_operand (operands[1], QImode)"
4352 "@
4353 bis $31,%r1,%0
4354 lda %0,%L1($31)
4355 ldbu %0,%1
4356 stb %r1,%0"
4357 [(set_attr "type" "ilog,iadd,ild,ist")
4358 (set_attr "isa" "*,*,bwx,bwx")])
4359
4360 (define_insn "*movhi"
4361 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
4362 (match_operand:HI 1 "input_operand" "rJ,n,m,rJ"))]
4363 "register_operand (operands[0], HImode)
4364 || reg_or_0_operand (operands[1], HImode)"
4365 "@
4366 bis $31,%r1,%0
4367 lda %0,%L1($31)
4368 ldwu %0,%1
4369 stw %r1,%0"
4370 [(set_attr "type" "ilog,iadd,ild,ist")
4371 (set_attr "isa" "*,*,bwx,bwx")])
4372
4373 ;; We need to hook into the extra support that we have for HImode
4374 ;; reloads when BWX insns are not available.
4375 (define_expand "movcqi"
4376 [(set (match_operand:CQI 0 "nonimmediate_operand")
4377 (match_operand:CQI 1 "general_operand"))]
4378 "!TARGET_BWX"
4379 {
4380 if (GET_CODE (operands[0]) == CONCAT || GET_CODE (operands[1]) == CONCAT)
4381 ;
4382 else if (!any_memory_operand (operands[0], CQImode))
4383 {
4384 if (!any_memory_operand (operands[1], CQImode))
4385 {
4386 emit_move_insn (gen_lowpart (HImode, operands[0]),
4387 gen_lowpart (HImode, operands[1]));
4388 DONE;
4389 }
4390 if (aligned_memory_operand (operands[1], CQImode))
4391 {
4392 bool done;
4393 do_aligned1:
4394 operands[1] = gen_lowpart (HImode, operands[1]);
4395 do_aligned2:
4396 operands[0] = gen_lowpart (HImode, operands[0]);
4397 done = alpha_expand_mov_nobwx (HImode, operands);
4398 gcc_assert (done);
4399 DONE;
4400 }
4401 }
4402 else if (aligned_memory_operand (operands[0], CQImode))
4403 {
4404 if (MEM_P (operands[1]))
4405 {
4406 rtx x = gen_reg_rtx (HImode);
4407 emit_move_insn (gen_lowpart (CQImode, x), operands[1]);
4408 operands[1] = x;
4409 goto do_aligned2;
4410 }
4411 goto do_aligned1;
4412 }
4413
4414 gcc_assert (!reload_in_progress);
4415 emit_move_complex_parts (operands[0], operands[1]);
4416 DONE;
4417 })
4418
4419 ;; Here are the versions for reload.
4420 ;;
4421 ;; The aligned input case is recognized early in alpha_secondary_reload
4422 ;; in order to avoid allocating an unnecessary scratch register.
4423 ;;
4424 ;; Note that in the unaligned cases we know that the operand must not be
4425 ;; a pseudo-register because stack slots are always aligned references.
4426
4427 (define_expand "reload_in<mode>"
4428 [(parallel [(match_operand:RELOAD12 0 "register_operand" "=r")
4429 (match_operand:RELOAD12 1 "any_memory_operand" "m")
4430 (match_operand:TI 2 "register_operand" "=&r")])]
4431 "!TARGET_BWX"
4432 {
4433 rtx scratch, seq, addr;
4434 unsigned regno = REGNO (operands[2]);
4435
4436 /* It is possible that one of the registers we got for operands[2]
4437 might coincide with that of operands[0] (which is why we made
4438 it TImode). Pick the other one to use as our scratch. */
4439 if (regno == REGNO (operands[0]))
4440 regno++;
4441 scratch = gen_rtx_REG (DImode, regno);
4442
4443 addr = get_unaligned_address (operands[1]);
4444 operands[0] = gen_rtx_REG (DImode, REGNO (operands[0]));
4445 seq = gen_unaligned_load<reloadmode> (operands[0], addr,
4446 scratch, operands[0]);
4447 alpha_set_memflags (seq, operands[1]);
4448
4449 emit_insn (seq);
4450 DONE;
4451 })
4452
4453 (define_expand "reload_out<mode>"
4454 [(parallel [(match_operand:RELOAD12 0 "any_memory_operand" "=m")
4455 (match_operand:RELOAD12 1 "register_operand" "r")
4456 (match_operand:TI 2 "register_operand" "=&r")])]
4457 "!TARGET_BWX"
4458 {
4459 unsigned regno = REGNO (operands[2]);
4460
4461 if (<MODE>mode == CQImode)
4462 {
4463 operands[0] = gen_lowpart (HImode, operands[0]);
4464 operands[1] = gen_lowpart (HImode, operands[1]);
4465 }
4466
4467 if (aligned_memory_operand (operands[0], <MODE>mode))
4468 {
4469 emit_insn (gen_reload_out<reloadmode>_aligned
4470 (operands[0], operands[1],
4471 gen_rtx_REG (SImode, regno),
4472 gen_rtx_REG (SImode, regno + 1)));
4473 }
4474 else
4475 {
4476 rtx addr = get_unaligned_address (operands[0]);
4477 rtx scratch1 = gen_rtx_REG (DImode, regno);
4478 rtx scratch2 = gen_rtx_REG (DImode, regno + 1);
4479 rtx scratch3 = scratch1;
4480 rtx seq;
4481
4482 if (REG_P (addr))
4483 scratch1 = addr;
4484
4485 seq = gen_unaligned_store<reloadmode> (addr, operands[1], scratch1,
4486 scratch2, scratch3);
4487 alpha_set_memflags (seq, operands[0]);
4488 emit_insn (seq);
4489 }
4490 DONE;
4491 })
4492
4493 ;; Helpers for the above. The way reload is structured, we can't
4494 ;; always get a proper address for a stack slot during reload_foo
4495 ;; expansion, so we must delay our address manipulations until after.
4496
4497 (define_insn_and_split "reload_in<mode>_aligned"
4498 [(set (match_operand:I12MODE 0 "register_operand" "=r")
4499 (match_operand:I12MODE 1 "memory_operand" "m"))]
4500 "!TARGET_BWX && (reload_in_progress || reload_completed)"
4501 "#"
4502 "!TARGET_BWX && reload_completed"
4503 [(const_int 0)]
4504 {
4505 rtx aligned_mem, bitnum;
4506 get_aligned_mem (operands[1], &aligned_mem, &bitnum);
4507 emit_insn (gen_aligned_load<reloadmode>
4508 (gen_lowpart (DImode, operands[0]), aligned_mem, bitnum,
4509 gen_rtx_REG (SImode, REGNO (operands[0]))));
4510 DONE;
4511 })
4512
4513 (define_insn_and_split "reload_out<mode>_aligned"
4514 [(set (match_operand:I12MODE 0 "memory_operand" "=m")
4515 (match_operand:I12MODE 1 "register_operand" "r"))
4516 (clobber (match_operand:SI 2 "register_operand" "=&r"))
4517 (clobber (match_operand:SI 3 "register_operand" "=&r"))]
4518 "!TARGET_BWX && (reload_in_progress || reload_completed)"
4519 "#"
4520 "!TARGET_BWX && reload_completed"
4521 [(const_int 0)]
4522 {
4523 rtx aligned_mem, bitnum;
4524 get_aligned_mem (operands[0], &aligned_mem, &bitnum);
4525 emit_insn (gen_aligned_store (aligned_mem, operands[1], bitnum,
4526 operands[2], operands[3]));
4527 DONE;
4528 })
4529
4531 ;; Vector operations
4532
4533 (define_mode_iterator VEC [V8QI V4HI V2SI])
4534 (define_mode_iterator VEC12 [V8QI V4HI])
4535
4536 (define_expand "mov<mode>"
4537 [(set (match_operand:VEC 0 "nonimmediate_operand")
4538 (match_operand:VEC 1 "general_operand"))]
4539 ""
4540 {
4541 if (alpha_expand_mov (<MODE>mode, operands))
4542 DONE;
4543 })
4544
4545 (define_split
4546 [(set (match_operand:VEC 0 "register_operand")
4547 (match_operand:VEC 1 "non_zero_const_operand"))]
4548 ""
4549 [(const_int 0)]
4550 {
4551 if (alpha_split_const_mov (<MODE>mode, operands))
4552 DONE;
4553 else
4554 FAIL;
4555 })
4556
4557
4558 (define_expand "movmisalign<mode>"
4559 [(set (match_operand:VEC 0 "nonimmediate_operand")
4560 (match_operand:VEC 1 "general_operand"))]
4561 ""
4562 {
4563 alpha_expand_movmisalign (<MODE>mode, operands);
4564 DONE;
4565 })
4566
4567 (define_insn "*mov<mode>_fix"
4568 [(set (match_operand:VEC 0 "nonimmediate_operand" "=r,r,r,m,*f,*f,m,r,*f")
4569 (match_operand:VEC 1 "input_operand" "rW,i,m,rW,*fW,m,*f,*f,r"))]
4570 "register_operand (operands[0], <MODE>mode)
4571 || reg_or_0_operand (operands[1], <MODE>mode)"
4572 "@
4573 bis $31,%r1,%0
4574 #
4575 ldq %0,%1
4576 stq %r1,%0
4577 cpys %R1,%R1,%0
4578 ldt %0,%1
4579 stt %R1,%0
4580 ftoit %1,%0
4581 itoft %1,%0"
4582 [(set_attr "type" "ilog,multi,ild,ist,fcpys,fld,fst,ftoi,itof")
4583 (set_attr "isa" "*,*,*,*,*,*,*,fix,fix")])
4584
4585 (define_insn "<code><mode>3"
4586 [(set (match_operand:VEC12 0 "register_operand" "=r")
4587 (any_maxmin:VEC12
4588 (match_operand:VEC12 1 "reg_or_0_operand" "rW")
4589 (match_operand:VEC12 2 "reg_or_0_operand" "rW")))]
4590 "TARGET_MAX"
4591 "<maxmin><modesuffix> %r1,%r2,%0"
4592 [(set_attr "type" "mvi")])
4593
4594 (define_insn "one_cmpl<mode>2"
4595 [(set (match_operand:VEC 0 "register_operand" "=r")
4596 (not:VEC (match_operand:VEC 1 "register_operand" "r")))]
4597 ""
4598 "ornot $31,%1,%0"
4599 [(set_attr "type" "ilog")])
4600
4601 (define_insn "and<mode>3"
4602 [(set (match_operand:VEC 0 "register_operand" "=r")
4603 (and:VEC (match_operand:VEC 1 "register_operand" "r")
4604 (match_operand:VEC 2 "register_operand" "r")))]
4605 ""
4606 "and %1,%2,%0"
4607 [(set_attr "type" "ilog")])
4608
4609 (define_insn "*andnot<mode>3"
4610 [(set (match_operand:VEC 0 "register_operand" "=r")
4611 (and:VEC (not:VEC (match_operand:VEC 1 "register_operand" "r"))
4612 (match_operand:VEC 2 "register_operand" "r")))]
4613 ""
4614 "bic %2,%1,%0"
4615 [(set_attr "type" "ilog")])
4616
4617 (define_insn "ior<mode>3"
4618 [(set (match_operand:VEC 0 "register_operand" "=r")
4619 (ior:VEC (match_operand:VEC 1 "register_operand" "r")
4620 (match_operand:VEC 2 "register_operand" "r")))]
4621 ""
4622 "bis %1,%2,%0"
4623 [(set_attr "type" "ilog")])
4624
4625 (define_insn "*iornot<mode>3"
4626 [(set (match_operand:VEC 0 "register_operand" "=r")
4627 (ior:VEC (not:DI (match_operand:VEC 1 "register_operand" "r"))
4628 (match_operand:VEC 2 "register_operand" "r")))]
4629 ""
4630 "ornot %2,%1,%0"
4631 [(set_attr "type" "ilog")])
4632
4633 (define_insn "xor<mode>3"
4634 [(set (match_operand:VEC 0 "register_operand" "=r")
4635 (xor:VEC (match_operand:VEC 1 "register_operand" "r")
4636 (match_operand:VEC 2 "register_operand" "r")))]
4637 ""
4638 "xor %1,%2,%0"
4639 [(set_attr "type" "ilog")])
4640
4641 (define_insn "*xornot<mode>3"
4642 [(set (match_operand:VEC 0 "register_operand" "=r")
4643 (not:VEC (xor:VEC (match_operand:VEC 1 "register_operand" "r")
4644 (match_operand:VEC 2 "register_operand" "r"))))]
4645 ""
4646 "eqv %1,%2,%0"
4647 [(set_attr "type" "ilog")])
4648
4649 (define_expand "vec_shl_<mode>"
4650 [(set (match_operand:VEC 0 "register_operand")
4651 (ashift:DI (match_operand:VEC 1 "register_operand")
4652 (match_operand:DI 2 "reg_or_6bit_operand")))]
4653 ""
4654 {
4655 operands[0] = gen_lowpart (DImode, operands[0]);
4656 operands[1] = gen_lowpart (DImode, operands[1]);
4657 })
4658
4659 (define_expand "vec_shr_<mode>"
4660 [(set (match_operand:VEC 0 "register_operand")
4661 (lshiftrt:DI (match_operand:VEC 1 "register_operand")
4662 (match_operand:DI 2 "reg_or_6bit_operand")))]
4663 ""
4664 {
4665 operands[0] = gen_lowpart (DImode, operands[0]);
4666 operands[1] = gen_lowpart (DImode, operands[1]);
4667 })
4668
4670 ;; Bit field extract patterns which use ext[wlq][lh]
4671
4672 (define_expand "extvmisaligndi"
4673 [(set (match_operand:DI 0 "register_operand")
4674 (sign_extract:DI (match_operand:BLK 1 "memory_operand")
4675 (match_operand:DI 2 "const_int_operand")
4676 (match_operand:DI 3 "const_int_operand")))]
4677 ""
4678 {
4679 /* We can do 16, 32 and 64 bit fields, if aligned on byte boundaries. */
4680 if (INTVAL (operands[3]) % 8 != 0
4681 || (INTVAL (operands[2]) != 16
4682 && INTVAL (operands[2]) != 32
4683 && INTVAL (operands[2]) != 64))
4684 FAIL;
4685
4686 alpha_expand_unaligned_load (operands[0], operands[1],
4687 INTVAL (operands[2]) / 8,
4688 INTVAL (operands[3]) / 8, 1);
4689 DONE;
4690 })
4691
4692 (define_expand "extzvdi"
4693 [(set (match_operand:DI 0 "register_operand")
4694 (zero_extract:DI (match_operand:DI 1 "register_operand")
4695 (match_operand:DI 2 "const_int_operand")
4696 (match_operand:DI 3 "const_int_operand")))]
4697 ""
4698 {
4699 /* We can do 8, 16, 32 and 64 bit fields, if aligned on byte boundaries. */
4700 if (INTVAL (operands[3]) % 8 != 0
4701 || (INTVAL (operands[2]) != 8
4702 && INTVAL (operands[2]) != 16
4703 && INTVAL (operands[2]) != 32
4704 && INTVAL (operands[2]) != 64))
4705 FAIL;
4706 })
4707
4708 (define_expand "extzvmisaligndi"
4709 [(set (match_operand:DI 0 "register_operand")
4710 (zero_extract:DI (match_operand:BLK 1 "memory_operand")
4711 (match_operand:DI 2 "const_int_operand")
4712 (match_operand:DI 3 "const_int_operand")))]
4713 ""
4714 {
4715 /* We can do 16, 32 and 64 bit fields, if aligned on byte boundaries.
4716 We fail 8-bit fields, falling back on a simple byte load. */
4717 if (INTVAL (operands[3]) % 8 != 0
4718 || (INTVAL (operands[2]) != 16
4719 && INTVAL (operands[2]) != 32
4720 && INTVAL (operands[2]) != 64))
4721 FAIL;
4722
4723 alpha_expand_unaligned_load (operands[0], operands[1],
4724 INTVAL (operands[2]) / 8,
4725 INTVAL (operands[3]) / 8, 0);
4726 DONE;
4727 })
4728
4729 (define_expand "insvmisaligndi"
4730 [(set (zero_extract:DI (match_operand:BLK 0 "memory_operand")
4731 (match_operand:DI 1 "const_int_operand")
4732 (match_operand:DI 2 "const_int_operand"))
4733 (match_operand:DI 3 "register_operand"))]
4734 ""
4735 {
4736 /* We can do 16, 32 and 64 bit fields, if aligned on byte boundaries. */
4737 if (INTVAL (operands[2]) % 8 != 0
4738 || (INTVAL (operands[1]) != 16
4739 && INTVAL (operands[1]) != 32
4740 && INTVAL (operands[1]) != 64))
4741 FAIL;
4742
4743 alpha_expand_unaligned_store (operands[0], operands[3],
4744 INTVAL (operands[1]) / 8,
4745 INTVAL (operands[2]) / 8);
4746 DONE;
4747 })
4748
4749 ;; Block move/clear, see alpha.c for more details.
4750 ;; Argument 0 is the destination
4751 ;; Argument 1 is the source
4752 ;; Argument 2 is the length
4753 ;; Argument 3 is the alignment
4754
4755 (define_expand "movmemqi"
4756 [(parallel [(set (match_operand:BLK 0 "memory_operand")
4757 (match_operand:BLK 1 "memory_operand"))
4758 (use (match_operand:DI 2 "immediate_operand"))
4759 (use (match_operand:DI 3 "immediate_operand"))])]
4760 ""
4761 {
4762 if (alpha_expand_block_move (operands))
4763 DONE;
4764 else
4765 FAIL;
4766 })
4767
4768 (define_expand "movmemdi"
4769 [(parallel [(set (match_operand:BLK 0 "memory_operand")
4770 (match_operand:BLK 1 "memory_operand"))
4771 (use (match_operand:DI 2 "immediate_operand"))
4772 (use (match_operand:DI 3 "immediate_operand"))
4773 (use (match_dup 4))
4774 (clobber (reg:DI 25))
4775 (clobber (reg:DI 16))
4776 (clobber (reg:DI 17))
4777 (clobber (reg:DI 18))
4778 (clobber (reg:DI 19))
4779 (clobber (reg:DI 20))
4780 (clobber (reg:DI 26))
4781 (clobber (reg:DI 27))])]
4782 "TARGET_ABI_OPEN_VMS"
4783 "operands[4] = gen_rtx_SYMBOL_REF (Pmode, \"OTS$MOVE\");")
4784
4785 (define_insn "*movmemdi_1"
4786 [(set (match_operand:BLK 0 "memory_operand" "=m,m")
4787 (match_operand:BLK 1 "memory_operand" "m,m"))
4788 (use (match_operand:DI 2 "nonmemory_operand" "r,i"))
4789 (use (match_operand:DI 3 "immediate_operand"))
4790 (use (match_operand:DI 4 "call_operand" "i,i"))
4791 (clobber (reg:DI 25))
4792 (clobber (reg:DI 16))
4793 (clobber (reg:DI 17))
4794 (clobber (reg:DI 18))
4795 (clobber (reg:DI 19))
4796 (clobber (reg:DI 20))
4797 (clobber (reg:DI 26))
4798 (clobber (reg:DI 27))]
4799 "TARGET_ABI_OPEN_VMS"
4800 {
4801 operands [5] = alpha_use_linkage (operands [4], false, true);
4802 switch (which_alternative)
4803 {
4804 case 0:
4805 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)";
4806 case 1:
4807 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)";
4808 default:
4809 gcc_unreachable ();
4810 }
4811 }
4812 [(set_attr "type" "multi")
4813 (set_attr "length" "28")])
4814
4815 (define_expand "setmemqi"
4816 [(parallel [(set (match_operand:BLK 0 "memory_operand")
4817 (match_operand 2 "const_int_operand"))
4818 (use (match_operand:DI 1 "immediate_operand"))
4819 (use (match_operand:DI 3 "immediate_operand"))])]
4820 ""
4821 {
4822 /* If value to set is not zero, use the library routine. */
4823 if (operands[2] != const0_rtx)
4824 FAIL;
4825
4826 if (alpha_expand_block_clear (operands))
4827 DONE;
4828 else
4829 FAIL;
4830 })
4831
4832 (define_expand "setmemdi"
4833 [(parallel [(set (match_operand:BLK 0 "memory_operand")
4834 (match_operand 2 "const_int_operand"))
4835 (use (match_operand:DI 1 "immediate_operand"))
4836 (use (match_operand:DI 3 "immediate_operand"))
4837 (use (match_dup 4))
4838 (clobber (reg:DI 25))
4839 (clobber (reg:DI 16))
4840 (clobber (reg:DI 17))
4841 (clobber (reg:DI 26))
4842 (clobber (reg:DI 27))])]
4843 "TARGET_ABI_OPEN_VMS"
4844 {
4845 /* If value to set is not zero, use the library routine. */
4846 if (operands[2] != const0_rtx)
4847 FAIL;
4848
4849 operands[4] = gen_rtx_SYMBOL_REF (Pmode, "OTS$ZERO");
4850 })
4851
4852 (define_insn "*clrmemdi_1"
4853 [(set (match_operand:BLK 0 "memory_operand" "=m,m")
4854 (const_int 0))
4855 (use (match_operand:DI 1 "nonmemory_operand" "r,i"))
4856 (use (match_operand:DI 2 "immediate_operand"))
4857 (use (match_operand:DI 3 "call_operand" "i,i"))
4858 (clobber (reg:DI 25))
4859 (clobber (reg:DI 16))
4860 (clobber (reg:DI 17))
4861 (clobber (reg:DI 26))
4862 (clobber (reg:DI 27))]
4863 "TARGET_ABI_OPEN_VMS"
4864 {
4865 operands [4] = alpha_use_linkage (operands [3], false, true);
4866 switch (which_alternative)
4867 {
4868 case 0:
4869 return "lda $16,%0\;bis $31,%1,$17\;ldq $26,%4\;lda $25,2($31)\;jsr $26,%3\;ldq $27,0($29)";
4870 case 1:
4871 return "lda $16,%0\;lda $17,%1($31)\;ldq $26,%4\;lda $25,2($31)\;jsr $26,%3\;ldq $27,0($29)";
4872 default:
4873 gcc_unreachable ();
4874 }
4875 }
4876 [(set_attr "type" "multi")
4877 (set_attr "length" "24")])
4878
4879
4881 ;; Subroutine of stack space allocation. Perform a stack probe.
4882 (define_expand "probe_stack"
4883 [(set (match_dup 1) (match_operand:DI 0 "const_int_operand"))]
4884 ""
4885 {
4886 operands[1] = gen_rtx_MEM (DImode, plus_constant (Pmode, stack_pointer_rtx,
4887 INTVAL (operands[0])));
4888 MEM_VOLATILE_P (operands[1]) = 1;
4889
4890 operands[0] = const0_rtx;
4891 })
4892
4893 ;; This is how we allocate stack space. If we are allocating a
4894 ;; constant amount of space and we know it is less than 4096
4895 ;; bytes, we need do nothing.
4896 ;;
4897 ;; If it is more than 4096 bytes, we need to probe the stack
4898 ;; periodically.
4899 (define_expand "allocate_stack"
4900 [(set (reg:DI 30)
4901 (plus:DI (reg:DI 30)
4902 (match_operand:DI 1 "reg_or_cint_operand")))
4903 (set (match_operand:DI 0 "register_operand" "=r")
4904 (match_dup 2))]
4905 ""
4906 {
4907 if (CONST_INT_P (operands[1])
4908 && INTVAL (operands[1]) < 32768)
4909 {
4910 if (INTVAL (operands[1]) >= 4096)
4911 {
4912 /* We do this the same way as in the prologue and generate explicit
4913 probes. Then we update the stack by the constant. */
4914
4915 int probed = 4096;
4916
4917 emit_insn (gen_probe_stack (GEN_INT (- probed)));
4918 while (probed + 8192 < INTVAL (operands[1]))
4919 emit_insn (gen_probe_stack (GEN_INT (- (probed += 8192))));
4920
4921 if (probed + 4096 < INTVAL (operands[1]))
4922 emit_insn (gen_probe_stack (GEN_INT (- INTVAL(operands[1]))));
4923 }
4924
4925 operands[1] = GEN_INT (- INTVAL (operands[1]));
4926 operands[2] = virtual_stack_dynamic_rtx;
4927 }
4928 else
4929 {
4930 rtx_code_label *out_label = 0;
4931 rtx_code_label *loop_label = gen_label_rtx ();
4932 rtx want = gen_reg_rtx (Pmode);
4933 rtx tmp = gen_reg_rtx (Pmode);
4934 rtx memref, test;
4935
4936 emit_insn (gen_subdi3 (want, stack_pointer_rtx,
4937 force_reg (Pmode, operands[1])));
4938
4939 if (!CONST_INT_P (operands[1]))
4940 {
4941 rtx limit = GEN_INT (4096);
4942 out_label = gen_label_rtx ();
4943 test = gen_rtx_LTU (VOIDmode, operands[1], limit);
4944 emit_jump_insn
4945 (gen_cbranchdi4 (test, operands[1], limit, out_label));
4946 }
4947
4948 emit_insn (gen_adddi3 (tmp, stack_pointer_rtx, GEN_INT (-4096)));
4949 emit_label (loop_label);
4950 memref = gen_rtx_MEM (DImode, tmp);
4951 MEM_VOLATILE_P (memref) = 1;
4952 emit_move_insn (memref, const0_rtx);
4953 emit_insn (gen_adddi3 (tmp, tmp, GEN_INT(-8192)));
4954 test = gen_rtx_GTU (VOIDmode, tmp, want);
4955 emit_jump_insn (gen_cbranchdi4 (test, tmp, want, loop_label));
4956
4957 memref = gen_rtx_MEM (DImode, want);
4958 MEM_VOLATILE_P (memref) = 1;
4959 emit_move_insn (memref, const0_rtx);
4960
4961 if (out_label)
4962 emit_label (out_label);
4963
4964 emit_move_insn (stack_pointer_rtx, want);
4965 emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
4966 DONE;
4967 }
4968 })
4969
4970 ;; This is used by alpha_expand_prolog to do the same thing as above,
4971 ;; except we cannot at that time generate new basic blocks, so we hide
4972 ;; the loop in this one insn.
4973
4974 (define_insn "prologue_stack_probe_loop"
4975 [(unspec_volatile [(match_operand:DI 0 "register_operand" "r")
4976 (match_operand:DI 1 "register_operand" "r")]
4977 UNSPECV_PSPL)]
4978 ""
4979 {
4980 operands[2] = gen_label_rtx ();
4981 (*targetm.asm_out.internal_label) (asm_out_file, "L",
4982 CODE_LABEL_NUMBER (operands[2]));
4983
4984 return "stq $31,-8192(%1)\;subq %0,1,%0\;lda %1,-8192(%1)\;bne %0,%l2";
4985 }
4986 [(set_attr "length" "16")
4987 (set_attr "type" "multi")])
4988
4989 (define_expand "prologue"
4990 [(const_int 0)]
4991 ""
4992 {
4993 alpha_expand_prologue ();
4994 DONE;
4995 })
4996
4997 ;; These take care of emitting the ldgp insn in the prologue. This will be
4998 ;; an lda/ldah pair and we want to align them properly. So we have two
4999 ;; unspec_volatile insns, the first of which emits the ldgp assembler macro
5000 ;; and the second of which emits nothing. However, both are marked as type
5001 ;; IADD (the default) so the alignment code in alpha.c does the right thing
5002 ;; with them.
5003
5004 (define_expand "prologue_ldgp"
5005 [(set (match_dup 0)
5006 (unspec_volatile:DI [(match_dup 1) (match_dup 2)] UNSPECV_LDGP1))
5007 (set (match_dup 0)
5008 (unspec_volatile:DI [(match_dup 0) (match_dup 2)] UNSPECV_PLDGP2))]
5009 ""
5010 {
5011 operands[0] = pic_offset_table_rtx;
5012 operands[1] = gen_rtx_REG (Pmode, 27);
5013 operands[2] = (TARGET_EXPLICIT_RELOCS
5014 ? GEN_INT (alpha_next_sequence_number++)
5015 : const0_rtx);
5016 })
5017
5018 (define_insn "*ldgp_er_1"
5019 [(set (match_operand:DI 0 "register_operand" "=r")
5020 (unspec_volatile:DI [(match_operand:DI 1 "register_operand" "r")
5021 (match_operand 2 "const_int_operand")]
5022 UNSPECV_LDGP1))]
5023 "TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF"
5024 "ldah %0,0(%1)\t\t!gpdisp!%2"
5025 [(set_attr "cannot_copy" "true")])
5026
5027 (define_insn "*ldgp_er_2"
5028 [(set (match_operand:DI 0 "register_operand" "=r")
5029 (unspec:DI [(match_operand:DI 1 "register_operand" "r")
5030 (match_operand 2 "const_int_operand")]
5031 UNSPEC_LDGP2))]
5032 "TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF"
5033 "lda %0,0(%1)\t\t!gpdisp!%2"
5034 [(set_attr "cannot_copy" "true")])
5035
5036 (define_insn "*prologue_ldgp_er_2"
5037 [(set (match_operand:DI 0 "register_operand" "=r")
5038 (unspec_volatile:DI [(match_operand:DI 1 "register_operand" "r")
5039 (match_operand 2 "const_int_operand")]
5040 UNSPECV_PLDGP2))]
5041 "TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF"
5042 "lda %0,0(%1)\t\t!gpdisp!%2\n$%~..ng:"
5043 [(set_attr "cannot_copy" "true")])
5044
5045 (define_insn "*prologue_ldgp_1"
5046 [(set (match_operand:DI 0 "register_operand" "=r")
5047 (unspec_volatile:DI [(match_operand:DI 1 "register_operand" "r")
5048 (match_operand 2 "const_int_operand")]
5049 UNSPECV_LDGP1))]
5050 ""
5051 "ldgp %0,0(%1)\n$%~..ng:"
5052 [(set_attr "cannot_copy" "true")])
5053
5054 (define_insn "*prologue_ldgp_2"
5055 [(set (match_operand:DI 0 "register_operand" "=r")
5056 (unspec_volatile:DI [(match_operand:DI 1 "register_operand" "r")
5057 (match_operand 2 "const_int_operand")]
5058 UNSPECV_PLDGP2))]
5059 ""
5060 )
5061
5062 ;; The _mcount profiling hook has special calling conventions, and
5063 ;; does not clobber all the registers that a normal call would. So
5064 ;; hide the fact this is a call at all.
5065
5066 (define_insn "prologue_mcount"
5067 [(unspec_volatile [(const_int 0)] UNSPECV_MCOUNT)]
5068 ""
5069 {
5070 if (TARGET_EXPLICIT_RELOCS)
5071 /* Note that we cannot use a lituse_jsr reloc, since _mcount
5072 cannot be called via the PLT. */
5073 return "ldq $28,_mcount($29)\t\t!literal\;jsr $28,($28),_mcount";
5074 else
5075 return "lda $28,_mcount\;jsr $28,($28),_mcount";
5076 }
5077 [(set_attr "type" "multi")
5078 (set_attr "length" "8")])
5079
5080 (define_insn "init_fp"
5081 [(set (match_operand:DI 0 "register_operand" "=r")
5082 (match_operand:DI 1 "register_operand" "r"))
5083 (clobber (mem:BLK (match_operand:DI 2 "register_operand" "=r")))]
5084 ""
5085 "bis $31,%1,%0")
5086
5087 (define_expand "epilogue"
5088 [(return)]
5089 ""
5090 "alpha_expand_epilogue ();")
5091
5092 (define_expand "sibcall_epilogue"
5093 [(return)]
5094 "TARGET_ABI_OSF"
5095 {
5096 alpha_expand_epilogue ();
5097 DONE;
5098 })
5099
5100 (define_expand "builtin_longjmp"
5101 [(use (match_operand:DI 0 "register_operand" "r"))]
5102 "TARGET_ABI_OSF"
5103 {
5104 /* The elements of the buffer are, in order: */
5105 rtx fp = gen_rtx_MEM (Pmode, operands[0]);
5106 rtx lab = gen_rtx_MEM (Pmode, plus_constant (Pmode, operands[0], 8));
5107 rtx stack = gen_rtx_MEM (Pmode, plus_constant (Pmode, operands[0], 16));
5108 rtx pv = gen_rtx_REG (Pmode, 27);
5109
5110 /* This bit is the same as expand_builtin_longjmp. */
5111 emit_move_insn (hard_frame_pointer_rtx, fp);
5112 emit_move_insn (pv, lab);
5113 emit_stack_restore (SAVE_NONLOCAL, stack);
5114 emit_use (hard_frame_pointer_rtx);
5115 emit_use (stack_pointer_rtx);
5116
5117 /* Load the label we are jumping through into $27 so that we know
5118 where to look for it when we get back to setjmp's function for
5119 restoring the gp. */
5120 emit_jump_insn (gen_builtin_longjmp_internal (pv));
5121 emit_barrier ();
5122 DONE;
5123 })
5124
5125 ;; This is effectively a copy of indirect_jump, but constrained such
5126 ;; that register renaming cannot foil our cunning plan with $27.
5127 (define_insn "builtin_longjmp_internal"
5128 [(set (pc)
5129 (unspec_volatile [(match_operand:DI 0 "register_operand" "c")]
5130 UNSPECV_LONGJMP))]
5131 ""
5132 "jmp $31,(%0),0"
5133 [(set_attr "type" "ibr")])
5134
5135 (define_expand "builtin_setjmp_receiver"
5136 [(unspec_volatile [(label_ref (match_operand 0))] UNSPECV_SETJMPR)]
5137 "TARGET_ABI_OSF")
5138
5139 (define_insn_and_split "*builtin_setjmp_receiver_1"
5140 [(unspec_volatile [(match_operand 0)] UNSPECV_SETJMPR)]
5141 "TARGET_ABI_OSF"
5142 {
5143 if (TARGET_EXPLICIT_RELOCS)
5144 return "#";
5145 else
5146 return "br $27,$LSJ%=\n$LSJ%=:\;ldgp $29,0($27)";
5147 }
5148 "&& TARGET_EXPLICIT_RELOCS && reload_completed"
5149 [(set (match_dup 1)
5150 (unspec_volatile:DI [(match_dup 2) (match_dup 3)] UNSPECV_LDGP1))
5151 (set (match_dup 1)
5152 (unspec:DI [(match_dup 1) (match_dup 3)] UNSPEC_LDGP2))]
5153 {
5154 if (prev_nonnote_insn (curr_insn) != XEXP (operands[0], 0))
5155 emit_insn (gen_rtx_UNSPEC_VOLATILE (VOIDmode, gen_rtvec (1, operands[0]),
5156 UNSPECV_SETJMPR_ER));
5157 operands[1] = pic_offset_table_rtx;
5158 operands[2] = gen_rtx_REG (Pmode, 27);
5159 operands[3] = GEN_INT (alpha_next_sequence_number++);
5160 }
5161 [(set_attr "length" "12")
5162 (set_attr "type" "multi")])
5163
5164 (define_insn "*builtin_setjmp_receiver_er_sl_1"
5165 [(unspec_volatile [(match_operand 0)] UNSPECV_SETJMPR_ER)]
5166 "TARGET_ABI_OSF && TARGET_EXPLICIT_RELOCS"
5167 "lda $27,$LSJ%=-%l0($27)\n$LSJ%=:")
5168
5169 ;; When flag_reorder_blocks_and_partition is in effect, compiler puts
5170 ;; exception landing pads in a cold section. To prevent inter-section offset
5171 ;; calculation, a jump to original landing pad is emitted in the place of the
5172 ;; original landing pad. Since landing pad is moved, RA-relative GP
5173 ;; calculation in the prologue of landing pad breaks. To solve this problem,
5174 ;; we use alternative GP load approach.
5175
5176 (define_expand "exception_receiver"
5177 [(unspec_volatile [(match_dup 0)] UNSPECV_EHR)]
5178 "TARGET_ABI_OSF"
5179 {
5180 if (flag_reorder_blocks_and_partition)
5181 operands[0] = alpha_gp_save_rtx ();
5182 else
5183 operands[0] = const0_rtx;
5184 })
5185
5186 (define_insn "*exception_receiver_2"
5187 [(unspec_volatile [(match_operand:DI 0 "memory_operand" "m")] UNSPECV_EHR)]
5188 "TARGET_ABI_OSF && flag_reorder_blocks_and_partition"
5189 "ldq $29,%0"
5190 [(set_attr "type" "ild")])
5191
5192 (define_insn_and_split "*exception_receiver_1"
5193 [(unspec_volatile [(const_int 0)] UNSPECV_EHR)]
5194 "TARGET_ABI_OSF"
5195 {
5196 if (TARGET_EXPLICIT_RELOCS)
5197 return "#";
5198 else
5199 return "ldgp $29,0($26)";
5200 }
5201 "&& TARGET_EXPLICIT_RELOCS && reload_completed"
5202 [(set (match_dup 0)
5203 (unspec_volatile:DI [(match_dup 1) (match_dup 2)] UNSPECV_LDGP1))
5204 (set (match_dup 0)
5205 (unspec:DI [(match_dup 0) (match_dup 2)] UNSPEC_LDGP2))]
5206 {
5207 operands[0] = pic_offset_table_rtx;
5208 operands[1] = gen_rtx_REG (Pmode, 26);
5209 operands[2] = GEN_INT (alpha_next_sequence_number++);
5210 }
5211 [(set_attr "length" "8")
5212 (set_attr "type" "multi")])
5213
5214 (define_expand "nonlocal_goto_receiver"
5215 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
5216 (set (reg:DI 27) (mem:DI (reg:DI 29)))
5217 (unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
5218 (use (reg:DI 27))]
5219 "TARGET_ABI_OPEN_VMS")
5220
5221 (define_insn "arg_home"
5222 [(unspec [(const_int 0)] UNSPEC_ARG_HOME)
5223 (use (reg:DI 1))
5224 (use (reg:DI 25))
5225 (use (reg:DI 16))
5226 (use (reg:DI 17))
5227 (use (reg:DI 18))
5228 (use (reg:DI 19))
5229 (use (reg:DI 20))
5230 (use (reg:DI 21))
5231 (use (reg:DI 48))
5232 (use (reg:DI 49))
5233 (use (reg:DI 50))
5234 (use (reg:DI 51))
5235 (use (reg:DI 52))
5236 (use (reg:DI 53))
5237 (clobber (mem:BLK (const_int 0)))
5238 (clobber (reg:DI 24))
5239 (clobber (reg:DI 25))
5240 (clobber (reg:DI 0))]
5241 "TARGET_ABI_OPEN_VMS"
5242 "lda $0,OTS$HOME_ARGS\;ldq $0,8($0)\;jsr $0,OTS$HOME_ARGS"
5243 [(set_attr "length" "16")
5244 (set_attr "type" "multi")])
5245
5246 ;; Prefetch data.
5247 ;;
5248 ;; On EV4, these instructions are nops -- no load occurs.
5249 ;;
5250 ;; On EV5, these instructions act as a normal load, and thus can trap
5251 ;; if the address is invalid. The OS may (or may not) handle this in
5252 ;; the entMM fault handler and suppress the fault. If so, then this
5253 ;; has the effect of a read prefetch instruction.
5254 ;;
5255 ;; On EV6, these become official prefetch instructions.
5256
5257 (define_insn "prefetch"
5258 [(prefetch (match_operand:DI 0 "address_operand" "p")
5259 (match_operand:DI 1 "const_int_operand" "n")
5260 (match_operand:DI 2 "const_int_operand" "n"))]
5261 "TARGET_FIXUP_EV5_PREFETCH || alpha_cpu == PROCESSOR_EV6"
5262 {
5263 /* Interpret "no temporal locality" as this data should be evicted once
5264 it is used. The "evict next" alternatives load the data into the cache
5265 and leave the LRU eviction counter pointing to that block. */
5266 static const char * const alt[2][2] = {
5267 {
5268 "ldq $31,%a0", /* read, evict next */
5269 "ldl $31,%a0", /* read, evict last */
5270 },
5271 {
5272 "ldt $f31,%a0", /* write, evict next */
5273 "lds $f31,%a0", /* write, evict last */
5274 }
5275 };
5276
5277 bool write = INTVAL (operands[1]) != 0;
5278 bool lru = INTVAL (operands[2]) != 0;
5279
5280 return alt[write][lru];
5281 }
5282 [(set_attr "type" "ild")])
5283
5284 ;; Close the trap shadow of preceding instructions. This is generated
5285 ;; by alpha_reorg.
5286
5287 (define_insn "trapb"
5288 [(unspec_volatile [(const_int 0)] UNSPECV_TRAPB)]
5289 ""
5290 "trapb"
5291 [(set_attr "type" "misc")])
5292
5293 ;; No-op instructions used by machine-dependent reorg to preserve
5294 ;; alignment for instruction issue.
5295 ;; The Unicos/Mk assembler does not support these opcodes.
5296
5297 (define_insn "nop"
5298 [(const_int 0)]
5299 ""
5300 "bis $31,$31,$31"
5301 [(set_attr "type" "ilog")])
5302
5303 (define_insn "fnop"
5304 [(const_int 1)]
5305 "TARGET_FP"
5306 "cpys $f31,$f31,$f31"
5307 [(set_attr "type" "fcpys")])
5308
5309 (define_insn "unop"
5310 [(const_int 2)]
5311 ""
5312 "ldq_u $31,0($30)")
5313
5314 (define_insn "realign"
5315 [(unspec_volatile [(match_operand 0 "immediate_operand" "i")]
5316 UNSPECV_REALIGN)]
5317 ""
5318 ".align %0 #realign")
5319
5321 ;; Instructions to be emitted from __builtins.
5322
5323 (define_insn "builtin_cmpbge"
5324 [(set (match_operand:DI 0 "register_operand" "=r")
5325 (unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "rJ")
5326 (match_operand:DI 2 "reg_or_8bit_operand" "rI")]
5327 UNSPEC_CMPBGE))]
5328 ""
5329 "cmpbge %r1,%2,%0"
5330 ;; The EV6 data sheets list this as ILOG. OTOH, EV6 doesn't
5331 ;; actually differentiate between ILOG and ICMP in the schedule.
5332 [(set_attr "type" "icmp")])
5333
5334 (define_expand "extbl"
5335 [(match_operand:DI 0 "register_operand")
5336 (match_operand:DI 1 "reg_or_0_operand")
5337 (match_operand:DI 2 "reg_or_8bit_operand")]
5338 ""
5339 {
5340 emit_insn (gen_extxl (operands[0], operands[1], GEN_INT (8), operands[2]));
5341 DONE;
5342 })
5343
5344 (define_expand "extwl"
5345 [(match_operand:DI 0 "register_operand")
5346 (match_operand:DI 1 "reg_or_0_operand")
5347 (match_operand:DI 2 "reg_or_8bit_operand")]
5348 ""
5349 {
5350 emit_insn (gen_extxl (operands[0], operands[1], GEN_INT (16), operands[2]));
5351 DONE;
5352 })
5353
5354 (define_expand "extll"
5355 [(match_operand:DI 0 "register_operand")
5356 (match_operand:DI 1 "reg_or_0_operand")
5357 (match_operand:DI 2 "reg_or_8bit_operand")]
5358 ""
5359 {
5360 emit_insn (gen_extxl (operands[0], operands[1], GEN_INT (32), operands[2]));
5361 DONE;
5362 })
5363
5364 (define_expand "extql"
5365 [(match_operand:DI 0 "register_operand")
5366 (match_operand:DI 1 "reg_or_0_operand")
5367 (match_operand:DI 2 "reg_or_8bit_operand")]
5368 ""
5369 {
5370 emit_insn (gen_extxl (operands[0], operands[1], GEN_INT (64), operands[2]));
5371 DONE;
5372 })
5373
5374 (define_expand "builtin_insbl"
5375 [(match_operand:DI 0 "register_operand")
5376 (match_operand:DI 1 "register_operand")
5377 (match_operand:DI 2 "reg_or_8bit_operand")]
5378 ""
5379 {
5380 operands[1] = gen_lowpart (QImode, operands[1]);
5381 emit_insn (gen_insbl (operands[0], operands[1], operands[2]));
5382 DONE;
5383 })
5384
5385 (define_expand "builtin_inswl"
5386 [(match_operand:DI 0 "register_operand")
5387 (match_operand:DI 1 "register_operand")
5388 (match_operand:DI 2 "reg_or_8bit_operand")]
5389 ""
5390 {
5391 operands[1] = gen_lowpart (HImode, operands[1]);
5392 emit_insn (gen_inswl (operands[0], operands[1], operands[2]));
5393 DONE;
5394 })
5395
5396 (define_expand "builtin_insll"
5397 [(match_operand:DI 0 "register_operand")
5398 (match_operand:DI 1 "register_operand")
5399 (match_operand:DI 2 "reg_or_8bit_operand")]
5400 ""
5401 {
5402 operands[1] = gen_lowpart (SImode, operands[1]);
5403 emit_insn (gen_insll (operands[0], operands[1], operands[2]));
5404 DONE;
5405 })
5406
5407 (define_expand "inswh"
5408 [(match_operand:DI 0 "register_operand")
5409 (match_operand:DI 1 "register_operand")
5410 (match_operand:DI 2 "reg_or_8bit_operand")]
5411 ""
5412 {
5413 emit_insn (gen_insxh (operands[0], operands[1], GEN_INT (16), operands[2]));
5414 DONE;
5415 })
5416
5417 (define_expand "inslh"
5418 [(match_operand:DI 0 "register_operand")
5419 (match_operand:DI 1 "register_operand")
5420 (match_operand:DI 2 "reg_or_8bit_operand")]
5421 ""
5422 {
5423 emit_insn (gen_insxh (operands[0], operands[1], GEN_INT (32), operands[2]));
5424 DONE;
5425 })
5426
5427 (define_expand "insqh"
5428 [(match_operand:DI 0 "register_operand")
5429 (match_operand:DI 1 "register_operand")
5430 (match_operand:DI 2 "reg_or_8bit_operand")]
5431 ""
5432 {
5433 emit_insn (gen_insxh (operands[0], operands[1], GEN_INT (64), operands[2]));
5434 DONE;
5435 })
5436
5437 (define_expand "mskbl"
5438 [(match_operand:DI 0 "register_operand")
5439 (match_operand:DI 1 "reg_or_0_operand")
5440 (match_operand:DI 2 "reg_or_8bit_operand")]
5441 ""
5442 {
5443 rtx mask = GEN_INT (0xff);
5444 emit_insn (gen_mskxl (operands[0], operands[1], mask, operands[2]));
5445 DONE;
5446 })
5447
5448 (define_expand "mskwl"
5449 [(match_operand:DI 0 "register_operand")
5450 (match_operand:DI 1 "reg_or_0_operand")
5451 (match_operand:DI 2 "reg_or_8bit_operand")]
5452 ""
5453 {
5454 rtx mask = GEN_INT (0xffff);
5455 emit_insn (gen_mskxl (operands[0], operands[1], mask, operands[2]));
5456 DONE;
5457 })
5458
5459 (define_expand "mskll"
5460 [(match_operand:DI 0 "register_operand")
5461 (match_operand:DI 1 "reg_or_0_operand")
5462 (match_operand:DI 2 "reg_or_8bit_operand")]
5463 ""
5464 {
5465 rtx mask = immed_double_const (0xffffffff, 0, DImode);
5466 emit_insn (gen_mskxl (operands[0], operands[1], mask, operands[2]));
5467 DONE;
5468 })
5469
5470 (define_expand "mskql"
5471 [(match_operand:DI 0 "register_operand")
5472 (match_operand:DI 1 "reg_or_0_operand")
5473 (match_operand:DI 2 "reg_or_8bit_operand")]
5474 ""
5475 {
5476 rtx mask = constm1_rtx;
5477 emit_insn (gen_mskxl (operands[0], operands[1], mask, operands[2]));
5478 DONE;
5479 })
5480
5481 (define_expand "mskwh"
5482 [(match_operand:DI 0 "register_operand")
5483 (match_operand:DI 1 "register_operand")
5484 (match_operand:DI 2 "reg_or_8bit_operand")]
5485 ""
5486 {
5487 emit_insn (gen_mskxh (operands[0], operands[1], GEN_INT (16), operands[2]));
5488 DONE;
5489 })
5490
5491 (define_expand "msklh"
5492 [(match_operand:DI 0 "register_operand")
5493 (match_operand:DI 1 "register_operand")
5494 (match_operand:DI 2 "reg_or_8bit_operand")]
5495 ""
5496 {
5497 emit_insn (gen_mskxh (operands[0], operands[1], GEN_INT (32), operands[2]));
5498 DONE;
5499 })
5500
5501 (define_expand "mskqh"
5502 [(match_operand:DI 0 "register_operand")
5503 (match_operand:DI 1 "register_operand")
5504 (match_operand:DI 2 "reg_or_8bit_operand")]
5505 ""
5506 {
5507 emit_insn (gen_mskxh (operands[0], operands[1], GEN_INT (64), operands[2]));
5508 DONE;
5509 })
5510
5511 (define_expand "builtin_zap"
5512 [(set (match_operand:DI 0 "register_operand")
5513 (and:DI (unspec:DI
5514 [(match_operand:DI 2 "reg_or_cint_operand")]
5515 UNSPEC_ZAP)
5516 (match_operand:DI 1 "reg_or_cint_operand")))]
5517 ""
5518 {
5519 if (CONST_INT_P (operands[2]))
5520 {
5521 rtx mask = alpha_expand_zap_mask (INTVAL (operands[2]));
5522
5523 if (mask == const0_rtx)
5524 {
5525 emit_move_insn (operands[0], const0_rtx);
5526 DONE;
5527 }
5528 if (mask == constm1_rtx)
5529 {
5530 emit_move_insn (operands[0], operands[1]);
5531 DONE;
5532 }
5533
5534 operands[1] = force_reg (DImode, operands[1]);
5535 emit_insn (gen_anddi3 (operands[0], operands[1], mask));
5536 DONE;
5537 }
5538
5539 operands[1] = force_reg (DImode, operands[1]);
5540 operands[2] = gen_lowpart (QImode, operands[2]);
5541 })
5542
5543 (define_insn "*builtin_zap_1"
5544 [(set (match_operand:DI 0 "register_operand" "=r,r,r,r")
5545 (and:DI (unspec:DI
5546 [(match_operand:QI 2 "reg_or_cint_operand" "n,n,r,r")]
5547 UNSPEC_ZAP)
5548 (match_operand:DI 1 "reg_or_cint_operand" "n,r,J,r")))]
5549 ""
5550 "@
5551 #
5552 #
5553 bis $31,$31,%0
5554 zap %r1,%2,%0"
5555 [(set_attr "type" "shift,shift,ilog,shift")])
5556
5557 (define_split
5558 [(set (match_operand:DI 0 "register_operand")
5559 (and:DI (unspec:DI
5560 [(match_operand:QI 2 "const_int_operand")]
5561 UNSPEC_ZAP)
5562 (match_operand:DI 1 "const_int_operand")))]
5563 ""
5564 [(const_int 0)]
5565 {
5566 rtx mask = alpha_expand_zap_mask (INTVAL (operands[2]));
5567 if (HOST_BITS_PER_WIDE_INT >= 64 || CONST_INT_P (mask))
5568 operands[1] = gen_int_mode (INTVAL (operands[1]) & INTVAL (mask), DImode);
5569 else
5570 {
5571 HOST_WIDE_INT c_lo = INTVAL (operands[1]);
5572 HOST_WIDE_INT c_hi = (c_lo < 0 ? -1 : 0);
5573 operands[1] = immed_double_const (c_lo & CONST_DOUBLE_LOW (mask),
5574 c_hi & CONST_DOUBLE_HIGH (mask),
5575 DImode);
5576 }
5577 emit_move_insn (operands[0], operands[1]);
5578 DONE;
5579 })
5580
5581 (define_split
5582 [(set (match_operand:DI 0 "register_operand")
5583 (and:DI (unspec:DI
5584 [(match_operand:QI 2 "const_int_operand")]
5585 UNSPEC_ZAP)
5586 (match_operand:DI 1 "register_operand")))]
5587 ""
5588 [(set (match_dup 0)
5589 (and:DI (match_dup 1) (match_dup 2)))]
5590 {
5591 operands[2] = alpha_expand_zap_mask (INTVAL (operands[2]));
5592 if (operands[2] == const0_rtx)
5593 {
5594 emit_move_insn (operands[0], const0_rtx);
5595 DONE;
5596 }
5597 if (operands[2] == constm1_rtx)
5598 {
5599 emit_move_insn (operands[0], operands[1]);
5600 DONE;
5601 }
5602 })
5603
5604 (define_expand "builtin_zapnot"
5605 [(set (match_operand:DI 0 "register_operand")
5606 (and:DI (unspec:DI
5607 [(not:QI (match_operand:DI 2 "reg_or_cint_operand"))]
5608 UNSPEC_ZAP)
5609 (match_operand:DI 1 "reg_or_cint_operand")))]
5610 ""
5611 {
5612 if (CONST_INT_P (operands[2]))
5613 {
5614 rtx mask = alpha_expand_zap_mask (~ INTVAL (operands[2]));
5615
5616 if (mask == const0_rtx)
5617 {
5618 emit_move_insn (operands[0], const0_rtx);
5619 DONE;
5620 }
5621 if (mask == constm1_rtx)
5622 {
5623 emit_move_insn (operands[0], operands[1]);
5624 DONE;
5625 }
5626
5627 operands[1] = force_reg (DImode, operands[1]);
5628 emit_insn (gen_anddi3 (operands[0], operands[1], mask));
5629 DONE;
5630 }
5631
5632 operands[1] = force_reg (DImode, operands[1]);
5633 operands[2] = gen_lowpart (QImode, operands[2]);
5634 })
5635
5636 (define_insn "*builtin_zapnot_1"
5637 [(set (match_operand:DI 0 "register_operand" "=r")
5638 (and:DI (unspec:DI
5639 [(not:QI (match_operand:QI 2 "register_operand" "r"))]
5640 UNSPEC_ZAP)
5641 (match_operand:DI 1 "reg_or_0_operand" "rJ")))]
5642 ""
5643 "zapnot %r1,%2,%0"
5644 [(set_attr "type" "shift")])
5645
5646 (define_insn "builtin_amask"
5647 [(set (match_operand:DI 0 "register_operand" "=r")
5648 (unspec:DI [(match_operand:DI 1 "reg_or_8bit_operand" "rI")]
5649 UNSPEC_AMASK))]
5650 ""
5651 "amask %1,%0"
5652 [(set_attr "type" "ilog")])
5653
5654 (define_insn "builtin_implver"
5655 [(set (match_operand:DI 0 "register_operand" "=r")
5656 (unspec:DI [(const_int 0)] UNSPEC_IMPLVER))]
5657 ""
5658 "implver %0"
5659 [(set_attr "type" "ilog")])
5660
5661 (define_insn "builtin_rpcc"
5662 [(set (match_operand:DI 0 "register_operand" "=r")
5663 (unspec_volatile:DI [(const_int 0)] UNSPECV_RPCC))]
5664 ""
5665 "rpcc %0"
5666 [(set_attr "type" "ilog")])
5667
5668 (define_expand "builtin_minub8"
5669 [(match_operand:DI 0 "register_operand")
5670 (match_operand:DI 1 "reg_or_0_operand")
5671 (match_operand:DI 2 "reg_or_0_operand")]
5672 "TARGET_MAX"
5673 {
5674 alpha_expand_builtin_vector_binop (gen_uminv8qi3, V8QImode, operands[0],
5675 operands[1], operands[2]);
5676 DONE;
5677 })
5678
5679 (define_expand "builtin_minsb8"
5680 [(match_operand:DI 0 "register_operand")
5681 (match_operand:DI 1 "reg_or_0_operand")
5682 (match_operand:DI 2 "reg_or_0_operand")]
5683 "TARGET_MAX"
5684 {
5685 alpha_expand_builtin_vector_binop (gen_sminv8qi3, V8QImode, operands[0],
5686 operands[1], operands[2]);
5687 DONE;
5688 })
5689
5690 (define_expand "builtin_minuw4"
5691 [(match_operand:DI 0 "register_operand")
5692 (match_operand:DI 1 "reg_or_0_operand")
5693 (match_operand:DI 2 "reg_or_0_operand")]
5694 "TARGET_MAX"
5695 {
5696 alpha_expand_builtin_vector_binop (gen_uminv4hi3, V4HImode, operands[0],
5697 operands[1], operands[2]);
5698 DONE;
5699 })
5700
5701 (define_expand "builtin_minsw4"
5702 [(match_operand:DI 0 "register_operand")
5703 (match_operand:DI 1 "reg_or_0_operand")
5704 (match_operand:DI 2 "reg_or_0_operand")]
5705 "TARGET_MAX"
5706 {
5707 alpha_expand_builtin_vector_binop (gen_sminv4hi3, V4HImode, operands[0],
5708 operands[1], operands[2]);
5709 DONE;
5710 })
5711
5712 (define_expand "builtin_maxub8"
5713 [(match_operand:DI 0 "register_operand")
5714 (match_operand:DI 1 "reg_or_0_operand")
5715 (match_operand:DI 2 "reg_or_0_operand")]
5716 "TARGET_MAX"
5717 {
5718 alpha_expand_builtin_vector_binop (gen_umaxv8qi3, V8QImode, operands[0],
5719 operands[1], operands[2]);
5720 DONE;
5721 })
5722
5723 (define_expand "builtin_maxsb8"
5724 [(match_operand:DI 0 "register_operand")
5725 (match_operand:DI 1 "reg_or_0_operand")
5726 (match_operand:DI 2 "reg_or_0_operand")]
5727 "TARGET_MAX"
5728 {
5729 alpha_expand_builtin_vector_binop (gen_smaxv8qi3, V8QImode, operands[0],
5730 operands[1], operands[2]);
5731 DONE;
5732 })
5733
5734 (define_expand "builtin_maxuw4"
5735 [(match_operand:DI 0 "register_operand")
5736 (match_operand:DI 1 "reg_or_0_operand")
5737 (match_operand:DI 2 "reg_or_0_operand")]
5738 "TARGET_MAX"
5739 {
5740 alpha_expand_builtin_vector_binop (gen_umaxv4hi3, V4HImode, operands[0],
5741 operands[1], operands[2]);
5742 DONE;
5743 })
5744
5745 (define_expand "builtin_maxsw4"
5746 [(match_operand:DI 0 "register_operand")
5747 (match_operand:DI 1 "reg_or_0_operand")
5748 (match_operand:DI 2 "reg_or_0_operand")]
5749 "TARGET_MAX"
5750 {
5751 alpha_expand_builtin_vector_binop (gen_smaxv4hi3, V4HImode, operands[0],
5752 operands[1], operands[2]);
5753 DONE;
5754 })
5755
5756 (define_insn "builtin_perr"
5757 [(set (match_operand:DI 0 "register_operand" "=r")
5758 (unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "%rJ")
5759 (match_operand:DI 2 "reg_or_8bit_operand" "rJ")]
5760 UNSPEC_PERR))]
5761 "TARGET_MAX"
5762 "perr %r1,%r2,%0"
5763 [(set_attr "type" "mvi")])
5764
5765 (define_expand "builtin_pklb"
5766 [(set (match_operand:DI 0 "register_operand")
5767 (vec_concat:V8QI
5768 (vec_concat:V4QI
5769 (truncate:V2QI (match_operand:DI 1 "register_operand"))
5770 (match_dup 2))
5771 (match_dup 3)))]
5772 "TARGET_MAX"
5773 {
5774 operands[0] = gen_lowpart (V8QImode, operands[0]);
5775 operands[1] = gen_lowpart (V2SImode, operands[1]);
5776 operands[2] = CONST0_RTX (V2QImode);
5777 operands[3] = CONST0_RTX (V4QImode);
5778 })
5779
5780 (define_insn "*pklb"
5781 [(set (match_operand:V8QI 0 "register_operand" "=r")
5782 (vec_concat:V8QI
5783 (vec_concat:V4QI
5784 (truncate:V2QI (match_operand:V2SI 1 "register_operand" "r"))
5785 (match_operand:V2QI 2 "const0_operand"))
5786 (match_operand:V4QI 3 "const0_operand")))]
5787 "TARGET_MAX"
5788 "pklb %r1,%0"
5789 [(set_attr "type" "mvi")])
5790
5791 (define_expand "builtin_pkwb"
5792 [(set (match_operand:DI 0 "register_operand")
5793 (vec_concat:V8QI
5794 (truncate:V4QI (match_operand:DI 1 "register_operand"))
5795 (match_dup 2)))]
5796 "TARGET_MAX"
5797 {
5798 operands[0] = gen_lowpart (V8QImode, operands[0]);
5799 operands[1] = gen_lowpart (V4HImode, operands[1]);
5800 operands[2] = CONST0_RTX (V4QImode);
5801 })
5802
5803 (define_insn "*pkwb"
5804 [(set (match_operand:V8QI 0 "register_operand" "=r")
5805 (vec_concat:V8QI
5806 (truncate:V4QI (match_operand:V4HI 1 "register_operand" "r"))
5807 (match_operand:V4QI 2 "const0_operand")))]
5808 "TARGET_MAX"
5809 "pkwb %r1,%0"
5810 [(set_attr "type" "mvi")])
5811
5812 (define_expand "builtin_unpkbl"
5813 [(set (match_operand:DI 0 "register_operand")
5814 (zero_extend:V2SI
5815 (vec_select:V2QI (match_operand:DI 1 "register_operand")
5816 (parallel [(const_int 0) (const_int 1)]))))]
5817 "TARGET_MAX"
5818 {
5819 operands[0] = gen_lowpart (V2SImode, operands[0]);
5820 operands[1] = gen_lowpart (V8QImode, operands[1]);
5821 })
5822
5823 (define_insn "*unpkbl"
5824 [(set (match_operand:V2SI 0 "register_operand" "=r")
5825 (zero_extend:V2SI
5826 (vec_select:V2QI (match_operand:V8QI 1 "reg_or_0_operand" "rW")
5827 (parallel [(const_int 0) (const_int 1)]))))]
5828 "TARGET_MAX"
5829 "unpkbl %r1,%0"
5830 [(set_attr "type" "mvi")])
5831
5832 (define_expand "builtin_unpkbw"
5833 [(set (match_operand:DI 0 "register_operand")
5834 (zero_extend:V4HI
5835 (vec_select:V4QI (match_operand:DI 1 "register_operand")
5836 (parallel [(const_int 0)
5837 (const_int 1)
5838 (const_int 2)
5839 (const_int 3)]))))]
5840 "TARGET_MAX"
5841 {
5842 operands[0] = gen_lowpart (V4HImode, operands[0]);
5843 operands[1] = gen_lowpart (V8QImode, operands[1]);
5844 })
5845
5846 (define_insn "*unpkbw"
5847 [(set (match_operand:V4HI 0 "register_operand" "=r")
5848 (zero_extend:V4HI
5849 (vec_select:V4QI (match_operand:V8QI 1 "reg_or_0_operand" "rW")
5850 (parallel [(const_int 0)
5851 (const_int 1)
5852 (const_int 2)
5853 (const_int 3)]))))]
5854 "TARGET_MAX"
5855 "unpkbw %r1,%0"
5856 [(set_attr "type" "mvi")])
5857
5859 (include "sync.md")
5860
5862 ;; The call patterns are at the end of the file because their
5863 ;; wildcard operand0 interferes with nice recognition.
5864
5865 (define_insn "*call_value_osf_1_er_noreturn"
5866 [(set (match_operand 0)
5867 (call (mem:DI (match_operand:DI 1 "call_operand" "c,R,s"))
5868 (match_operand 2)))
5869 (use (reg:DI 29))
5870 (clobber (reg:DI 26))]
5871 "TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF
5872 && find_reg_note (insn, REG_NORETURN, NULL_RTX)"
5873 "@
5874 jsr $26,($27),0
5875 bsr $26,%1\t\t!samegp
5876 ldq $27,%1($29)\t\t!literal!%#\;jsr $26,($27),%1\t\t!lituse_jsr!%#"
5877 [(set_attr "type" "jsr")
5878 (set_attr "length" "*,*,8")])
5879
5880 (define_insn "*call_value_osf_1_er"
5881 [(set (match_operand 0)
5882 (call (mem:DI (match_operand:DI 1 "call_operand" "c,R,s"))
5883 (match_operand 2)))
5884 (use (reg:DI 29))
5885 (clobber (reg:DI 26))]
5886 "TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF"
5887 "@
5888 jsr $26,(%1),0\;ldah $29,0($26)\t\t!gpdisp!%*\;lda $29,0($29)\t\t!gpdisp!%*
5889 bsr $26,%1\t\t!samegp
5890 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!%*"
5891 [(set_attr "type" "jsr")
5892 (set_attr "length" "12,*,16")])
5893
5894 ;; We must use peep2 instead of a split because we need accurate life
5895 ;; information for $gp. Consider the case of { bar(); while (1); }.
5896 (define_peephole2
5897 [(parallel [(set (match_operand 0)
5898 (call (mem:DI (match_operand:DI 1 "call_operand"))
5899 (match_operand 2)))
5900 (use (reg:DI 29))
5901 (clobber (reg:DI 26))])]
5902 "TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF && reload_completed
5903 && ! samegp_function_operand (operands[1], Pmode)
5904 && (peep2_regno_dead_p (1, 29)
5905 || find_reg_note (insn, REG_NORETURN, NULL_RTX))"
5906 [(parallel [(set (match_dup 0)
5907 (call (mem:DI (match_dup 3))
5908 (match_dup 2)))
5909 (use (reg:DI 29))
5910 (use (match_dup 1))
5911 (use (match_dup 4))
5912 (clobber (reg:DI 26))])]
5913 {
5914 if (CONSTANT_P (operands[1]))
5915 {
5916 operands[3] = gen_rtx_REG (Pmode, 27);
5917 operands[4] = GEN_INT (alpha_next_sequence_number++);
5918 emit_insn (gen_movdi_er_high_g (operands[3], pic_offset_table_rtx,
5919 operands[1], operands[4]));
5920 }
5921 else
5922 {
5923 operands[3] = operands[1];
5924 operands[1] = const0_rtx;
5925 operands[4] = const0_rtx;
5926 }
5927 })
5928
5929 (define_peephole2
5930 [(parallel [(set (match_operand 0)
5931 (call (mem:DI (match_operand:DI 1 "call_operand"))
5932 (match_operand 2)))
5933 (use (reg:DI 29))
5934 (clobber (reg:DI 26))])]
5935 "TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF && reload_completed
5936 && ! samegp_function_operand (operands[1], Pmode)
5937 && ! (peep2_regno_dead_p (1, 29)
5938 || find_reg_note (insn, REG_NORETURN, NULL_RTX))"
5939 [(parallel [(set (match_dup 0)
5940 (call (mem:DI (match_dup 3))
5941 (match_dup 2)))
5942 (set (match_dup 6)
5943 (unspec:DI [(match_dup 6) (match_dup 4)] UNSPEC_LDGP1))
5944 (use (match_dup 1))
5945 (use (match_dup 5))
5946 (clobber (reg:DI 26))])
5947 (set (match_dup 6)
5948 (unspec:DI [(match_dup 6) (match_dup 4)] UNSPEC_LDGP2))]
5949 {
5950 if (CONSTANT_P (operands[1]))
5951 {
5952 operands[3] = gen_rtx_REG (Pmode, 27);
5953 operands[5] = GEN_INT (alpha_next_sequence_number++);
5954 emit_insn (gen_movdi_er_high_g (operands[3], pic_offset_table_rtx,
5955 operands[1], operands[5]));
5956 }
5957 else
5958 {
5959 operands[3] = operands[1];
5960 operands[1] = const0_rtx;
5961 operands[5] = const0_rtx;
5962 }
5963 operands[4] = GEN_INT (alpha_next_sequence_number++);
5964 operands[6] = pic_offset_table_rtx;
5965 })
5966
5967 (define_insn "*call_value_osf_2_er_nogp"
5968 [(set (match_operand 0)
5969 (call (mem:DI (match_operand:DI 1 "register_operand" "c"))
5970 (match_operand 2)))
5971 (use (reg:DI 29))
5972 (use (match_operand 3))
5973 (use (match_operand 4))
5974 (clobber (reg:DI 26))]
5975 "TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF"
5976 "jsr $26,(%1),%3%J4"
5977 [(set_attr "type" "jsr")])
5978
5979 (define_insn "*call_value_osf_2_er"
5980 [(set (match_operand 0)
5981 (call (mem:DI (match_operand:DI 1 "register_operand" "c"))
5982 (match_operand 2)))
5983 (set (reg:DI 29)
5984 (unspec:DI [(reg:DI 29) (match_operand 5 "const_int_operand")]
5985 UNSPEC_LDGP1))
5986 (use (match_operand 3))
5987 (use (match_operand 4))
5988 (clobber (reg:DI 26))]
5989 "TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF"
5990 "jsr $26,(%1),%3%J4\;ldah $29,0($26)\t\t!gpdisp!%5"
5991 [(set_attr "type" "jsr")
5992 (set_attr "cannot_copy" "true")
5993 (set_attr "length" "8")])
5994
5995 (define_insn "*call_value_osf_1_noreturn"
5996 [(set (match_operand 0)
5997 (call (mem:DI (match_operand:DI 1 "call_operand" "c,R,s"))
5998 (match_operand 2)))
5999 (use (reg:DI 29))
6000 (clobber (reg:DI 26))]
6001 "! TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF
6002 && find_reg_note (insn, REG_NORETURN, NULL_RTX)"
6003 "@
6004 jsr $26,($27),0
6005 bsr $26,$%1..ng
6006 jsr $26,%1"
6007 [(set_attr "type" "jsr")
6008 (set_attr "length" "*,*,8")])
6009
6010 (define_int_iterator TLS_CALL
6011 [UNSPEC_TLSGD_CALL
6012 UNSPEC_TLSLDM_CALL])
6013
6014 (define_int_attr tls
6015 [(UNSPEC_TLSGD_CALL "tlsgd")
6016 (UNSPEC_TLSLDM_CALL "tlsldm")])
6017
6018 (define_insn "call_value_osf_<tls>"
6019 [(set (match_operand 0)
6020 (call (mem:DI (match_operand:DI 1 "symbolic_operand"))
6021 (const_int 0)))
6022 (unspec [(match_operand:DI 2 "const_int_operand")] TLS_CALL)
6023 (use (reg:DI 29))
6024 (clobber (reg:DI 26))]
6025 "HAVE_AS_TLS"
6026 "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!%*"
6027 [(set_attr "type" "jsr")
6028 (set_attr "length" "16")])
6029
6030 ;; We must use peep2 instead of a split because we need accurate life
6031 ;; information for $gp.
6032 (define_peephole2
6033 [(parallel
6034 [(set (match_operand 0)
6035 (call (mem:DI (match_operand:DI 1 "symbolic_operand"))
6036 (const_int 0)))
6037 (unspec [(match_operand:DI 2 "const_int_operand")] TLS_CALL)
6038 (use (reg:DI 29))
6039 (clobber (reg:DI 26))])]
6040 "HAVE_AS_TLS && reload_completed
6041 && peep2_regno_dead_p (1, 29)"
6042 [(set (match_dup 3)
6043 (unspec:DI [(match_dup 5)
6044 (match_dup 1)
6045 (match_dup 2)] UNSPEC_LITERAL))
6046 (parallel [(set (match_dup 0)
6047 (call (mem:DI (match_dup 3))
6048 (const_int 0)))
6049 (use (match_dup 5))
6050 (use (match_dup 1))
6051 (use (unspec [(match_dup 2)] TLS_CALL))
6052 (clobber (reg:DI 26))])
6053 (set (match_dup 5)
6054 (unspec:DI [(match_dup 5) (match_dup 4)] UNSPEC_LDGP2))]
6055 {
6056 operands[3] = gen_rtx_REG (Pmode, 27);
6057 operands[4] = GEN_INT (alpha_next_sequence_number++);
6058 operands[5] = pic_offset_table_rtx;
6059 })
6060
6061 (define_peephole2
6062 [(parallel
6063 [(set (match_operand 0)
6064 (call (mem:DI (match_operand:DI 1 "symbolic_operand"))
6065 (const_int 0)))
6066 (unspec [(match_operand:DI 2 "const_int_operand")] TLS_CALL)
6067 (use (reg:DI 29))
6068 (clobber (reg:DI 26))])]
6069 "HAVE_AS_TLS && reload_completed
6070 && !peep2_regno_dead_p (1, 29)"
6071 [(set (match_dup 3)
6072 (unspec:DI [(match_dup 5)
6073 (match_dup 1)
6074 (match_dup 2)] UNSPEC_LITERAL))
6075 (parallel [(set (match_dup 0)
6076 (call (mem:DI (match_dup 3))
6077 (const_int 0)))
6078 (set (match_dup 5)
6079 (unspec:DI [(match_dup 5) (match_dup 4)] UNSPEC_LDGP1))
6080 (use (match_dup 1))
6081 (use (unspec [(match_dup 2)] TLS_CALL))
6082 (clobber (reg:DI 26))])
6083 (set (match_dup 5)
6084 (unspec:DI [(match_dup 5) (match_dup 4)] UNSPEC_LDGP2))]
6085 {
6086 operands[3] = gen_rtx_REG (Pmode, 27);
6087 operands[4] = GEN_INT (alpha_next_sequence_number++);
6088 operands[5] = pic_offset_table_rtx;
6089 })
6090
6091 (define_insn "*call_value_osf_1"
6092 [(set (match_operand 0)
6093 (call (mem:DI (match_operand:DI 1 "call_operand" "c,R,s"))
6094 (match_operand 2)))
6095 (use (reg:DI 29))
6096 (clobber (reg:DI 26))]
6097 "! TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF"
6098 "@
6099 jsr $26,($27),0\;ldgp $29,0($26)
6100 bsr $26,$%1..ng
6101 jsr $26,%1\;ldgp $29,0($26)"
6102 [(set_attr "type" "jsr")
6103 (set_attr "length" "12,*,16")])
6104
6105 (define_insn "*sibcall_value_osf_1_er"
6106 [(set (match_operand 0)
6107 (call (mem:DI (match_operand:DI 1 "symbolic_operand" "R,s"))
6108 (match_operand 2)))
6109 (unspec [(reg:DI 29)] UNSPEC_SIBCALL)]
6110 "TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF"
6111 "@
6112 br $31,%1\t\t!samegp
6113 ldq $27,%1($29)\t\t!literal!%#\;jmp $31,($27),%1\t\t!lituse_jsr!%#"
6114 [(set_attr "type" "jsr")
6115 (set_attr "length" "*,8")])
6116
6117 (define_insn "*sibcall_value_osf_1"
6118 [(set (match_operand 0)
6119 (call (mem:DI (match_operand:DI 1 "symbolic_operand" "R,s"))
6120 (match_operand 2)))
6121 (unspec [(reg:DI 29)] UNSPEC_SIBCALL)]
6122 "! TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF"
6123 "@
6124 br $31,$%1..ng
6125 lda $27,%1\;jmp $31,($27),%1"
6126 [(set_attr "type" "jsr")
6127 (set_attr "length" "*,8")])
6128
6129 ; GAS relies on the order and position of instructions output below in order
6130 ; to generate relocs for VMS link to potentially optimize the call.
6131 ; Please do not molest.
6132 (define_insn "*call_value_vms_1"
6133 [(set (match_operand 0)
6134 (call (mem:DI (match_operand:DI 1 "call_operand" "r,s"))
6135 (match_operand 2)))
6136 (use (match_operand:DI 3 "nonmemory_operand" "r,n"))
6137 (use (reg:DI 25))
6138 (use (reg:DI 26))
6139 (clobber (reg:DI 27))]
6140 "TARGET_ABI_OPEN_VMS"
6141 {
6142 switch (which_alternative)
6143 {
6144 case 0:
6145 return "mov %3,$27\;jsr $26,0\;ldq $27,0($29)";
6146 case 1:
6147 operands [3] = alpha_use_linkage (operands [1], true, false);
6148 operands [4] = alpha_use_linkage (operands [1], false, false);
6149 return "ldq $26,%4\;ldq $27,%3\;jsr $26,%1\;ldq $27,0($29)";
6150 default:
6151 gcc_unreachable ();
6152 }
6153 }
6154 [(set_attr "type" "jsr")
6155 (set_attr "length" "12,16")])
6156