alpha.md revision 1.7 1 ;; Machine description for DEC Alpha for GNU C compiler
2 ;; Copyright (C) 1992-2016 Free Software Foundation, Inc.
3 ;; Contributed by Richard Kenner (kenner (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,M")))]
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,M")))]
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 "! 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 "general_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 "general_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 "const_int_operand" "i")))]
1520 "((unsigned HOST_WIDE_INT) 0xff << INTVAL (operands[2])
1521 == (unsigned HOST_WIDE_INT) INTVAL (operands[3]))
1522 || ((unsigned HOST_WIDE_INT) 0xffff << INTVAL (operands[2])
1523 == (unsigned HOST_WIDE_INT) INTVAL (operands[3]))
1524 || ((unsigned HOST_WIDE_INT) 0xffffffff << INTVAL (operands[2])
1525 == (unsigned HOST_WIDE_INT) INTVAL (operands[3]))"
1526 {
1527 if ((unsigned HOST_WIDE_INT) 0xff << INTVAL (operands[2])
1528 == (unsigned HOST_WIDE_INT) INTVAL (operands[3]))
1529 return "insbl %1,%s2,%0";
1530 if ((unsigned HOST_WIDE_INT) 0xffff << INTVAL (operands[2])
1531 == (unsigned HOST_WIDE_INT) INTVAL (operands[3]))
1532 return "inswl %1,%s2,%0";
1533 if ((unsigned HOST_WIDE_INT) 0xffffffff << INTVAL (operands[2])
1534 == (unsigned HOST_WIDE_INT) INTVAL (operands[3]))
1535 return "insll %1,%s2,%0";
1536
1537 gcc_unreachable ();
1538 }
1539 [(set_attr "type" "shift")])
1540
1541 ;; We do not include the insXh insns because they are complex to express
1542 ;; and it does not appear that we would ever want to generate them.
1543 ;;
1544 ;; Since we need them for block moves, though, cop out and use unspec.
1545
1546 (define_insn "insxh"
1547 [(set (match_operand:DI 0 "register_operand" "=r")
1548 (unspec:DI [(match_operand:DI 1 "register_operand" "r")
1549 (match_operand:DI 2 "mode_width_operand" "n")
1550 (match_operand:DI 3 "reg_or_8bit_operand" "rI")]
1551 UNSPEC_INSXH))]
1552 ""
1553 "ins%M2h %1,%3,%0"
1554 [(set_attr "type" "shift")])
1555
1556 (define_insn "mskxl"
1557 [(set (match_operand:DI 0 "register_operand" "=r")
1558 (and:DI (not:DI (ashift:DI
1559 (match_operand:DI 2 "mode_mask_operand" "n")
1560 (ashift:DI
1561 (match_operand:DI 3 "reg_or_8bit_operand" "rI")
1562 (const_int 3))))
1563 (match_operand:DI 1 "reg_or_0_operand" "rJ")))]
1564 ""
1565 "msk%U2l %r1,%3,%0"
1566 [(set_attr "type" "shift")])
1567
1568 ;; We do not include the mskXh insns because it does not appear we would
1569 ;; ever generate one.
1570 ;;
1571 ;; Again, we do for block moves and we use unspec again.
1572
1573 (define_insn "mskxh"
1574 [(set (match_operand:DI 0 "register_operand" "=r")
1575 (unspec:DI [(match_operand:DI 1 "register_operand" "r")
1576 (match_operand:DI 2 "mode_width_operand" "n")
1577 (match_operand:DI 3 "reg_or_8bit_operand" "rI")]
1578 UNSPEC_MSKXH))]
1579 ""
1580 "msk%M2h %1,%3,%0"
1581 [(set_attr "type" "shift")])
1582
1583 ;; Prefer AND + NE over LSHIFTRT + AND.
1584
1585 (define_insn_and_split "*ze_and_ne"
1586 [(set (match_operand:DI 0 "register_operand" "=r")
1587 (zero_extract:DI (match_operand:DI 1 "reg_or_0_operand" "rJ")
1588 (const_int 1)
1589 (match_operand 2 "const_int_operand" "I")))]
1590 "(unsigned HOST_WIDE_INT) INTVAL (operands[2]) < 8"
1591 "#"
1592 "(unsigned HOST_WIDE_INT) INTVAL (operands[2]) < 8"
1593 [(set (match_dup 0)
1594 (and:DI (match_dup 1) (match_dup 3)))
1595 (set (match_dup 0)
1596 (ne:DI (match_dup 0) (const_int 0)))]
1597 "operands[3] = GEN_INT (1 << INTVAL (operands[2]));")
1598
1600 ;; Floating-point operations. All the double-precision insns can extend
1601 ;; from single, so indicate that. The exception are the ones that simply
1602 ;; play with the sign bits; it's not clear what to do there.
1603
1604 (define_mode_iterator FMODE [SF DF])
1605
1606 (define_mode_attr opmode [(SF "si") (DF "di")])
1607
1608 (define_insn "abs<mode>2"
1609 [(set (match_operand:FMODE 0 "register_operand" "=f")
1610 (abs:FMODE (match_operand:FMODE 1 "reg_or_0_operand" "fG")))]
1611 "TARGET_FP"
1612 "cpys $f31,%R1,%0"
1613 [(set_attr "type" "fcpys")])
1614
1615 (define_insn "*nabs<mode>2"
1616 [(set (match_operand:FMODE 0 "register_operand" "=f")
1617 (neg:FMODE
1618 (abs:FMODE (match_operand:FMODE 1 "reg_or_0_operand" "fG"))))]
1619 "TARGET_FP"
1620 "cpysn $f31,%R1,%0"
1621 [(set_attr "type" "fadd")])
1622
1623 (define_expand "abstf2"
1624 [(parallel [(set (match_operand:TF 0 "register_operand")
1625 (abs:TF (match_operand:TF 1 "reg_or_0_operand")))
1626 (use (match_dup 2))])]
1627 "TARGET_HAS_XFLOATING_LIBS"
1628 "operands[2] = force_reg (DImode, GEN_INT (HOST_WIDE_INT_1U << 63));")
1629
1630 (define_insn_and_split "*abstf_internal"
1631 [(set (match_operand:TF 0 "register_operand" "=r")
1632 (abs:TF (match_operand:TF 1 "reg_or_0_operand" "rG")))
1633 (use (match_operand:DI 2 "register_operand" "r"))]
1634 "TARGET_HAS_XFLOATING_LIBS"
1635 "#"
1636 "&& reload_completed"
1637 [(const_int 0)]
1638 "alpha_split_tfmode_frobsign (operands, gen_andnotdi3); DONE;")
1639
1640 (define_insn "neg<mode>2"
1641 [(set (match_operand:FMODE 0 "register_operand" "=f")
1642 (neg:FMODE (match_operand:FMODE 1 "reg_or_0_operand" "fG")))]
1643 "TARGET_FP"
1644 "cpysn %R1,%R1,%0"
1645 [(set_attr "type" "fadd")])
1646
1647 (define_expand "negtf2"
1648 [(parallel [(set (match_operand:TF 0 "register_operand")
1649 (neg:TF (match_operand:TF 1 "reg_or_0_operand")))
1650 (use (match_dup 2))])]
1651 "TARGET_HAS_XFLOATING_LIBS"
1652 "operands[2] = force_reg (DImode, GEN_INT (HOST_WIDE_INT_1U << 63));")
1653
1654 (define_insn_and_split "*negtf_internal"
1655 [(set (match_operand:TF 0 "register_operand" "=r")
1656 (neg:TF (match_operand:TF 1 "reg_or_0_operand" "rG")))
1657 (use (match_operand:DI 2 "register_operand" "r"))]
1658 "TARGET_HAS_XFLOATING_LIBS"
1659 "#"
1660 "&& reload_completed"
1661 [(const_int 0)]
1662 "alpha_split_tfmode_frobsign (operands, gen_xordi3); DONE;")
1663
1664 (define_insn "copysign<mode>3"
1665 [(set (match_operand:FMODE 0 "register_operand" "=f")
1666 (unspec:FMODE [(match_operand:FMODE 1 "reg_or_0_operand" "fG")
1667 (match_operand:FMODE 2 "reg_or_0_operand" "fG")]
1668 UNSPEC_COPYSIGN))]
1669 "TARGET_FP"
1670 "cpys %R2,%R1,%0"
1671 [(set_attr "type" "fadd")])
1672
1673 (define_insn "*ncopysign<mode>3"
1674 [(set (match_operand:FMODE 0 "register_operand" "=f")
1675 (neg:FMODE
1676 (unspec:FMODE [(match_operand:FMODE 1 "reg_or_0_operand" "fG")
1677 (match_operand:FMODE 2 "reg_or_0_operand" "fG")]
1678 UNSPEC_COPYSIGN)))]
1679 "TARGET_FP"
1680 "cpysn %R2,%R1,%0"
1681 [(set_attr "type" "fadd")])
1682
1683 (define_insn "*add<mode>3_ieee"
1684 [(set (match_operand:FMODE 0 "register_operand" "=&f")
1685 (plus:FMODE (match_operand:FMODE 1 "reg_or_0_operand" "%fG")
1686 (match_operand:FMODE 2 "reg_or_0_operand" "fG")))]
1687 "TARGET_FP && alpha_fptm >= ALPHA_FPTM_SU"
1688 "add<modesuffix>%/ %R1,%R2,%0"
1689 [(set_attr "type" "fadd")
1690 (set_attr "trap" "yes")
1691 (set_attr "round_suffix" "normal")
1692 (set_attr "trap_suffix" "u_su_sui")])
1693
1694 (define_insn "add<mode>3"
1695 [(set (match_operand:FMODE 0 "register_operand" "=f")
1696 (plus:FMODE (match_operand:FMODE 1 "reg_or_0_operand" "%fG")
1697 (match_operand:FMODE 2 "reg_or_0_operand" "fG")))]
1698 "TARGET_FP"
1699 "add<modesuffix>%/ %R1,%R2,%0"
1700 [(set_attr "type" "fadd")
1701 (set_attr "trap" "yes")
1702 (set_attr "round_suffix" "normal")
1703 (set_attr "trap_suffix" "u_su_sui")])
1704
1705 (define_insn "*adddf_ext1"
1706 [(set (match_operand:DF 0 "register_operand" "=f")
1707 (plus:DF (float_extend:DF
1708 (match_operand:SF 1 "reg_or_0_operand" "fG"))
1709 (match_operand:DF 2 "reg_or_0_operand" "fG")))]
1710 "TARGET_FP && alpha_fptm < ALPHA_FPTM_SU"
1711 "add%-%/ %R1,%R2,%0"
1712 [(set_attr "type" "fadd")
1713 (set_attr "trap" "yes")
1714 (set_attr "round_suffix" "normal")
1715 (set_attr "trap_suffix" "u_su_sui")])
1716
1717 (define_insn "*adddf_ext2"
1718 [(set (match_operand:DF 0 "register_operand" "=f")
1719 (plus:DF (float_extend:DF
1720 (match_operand:SF 1 "reg_or_0_operand" "%fG"))
1721 (float_extend:DF
1722 (match_operand:SF 2 "reg_or_0_operand" "fG"))))]
1723 "TARGET_FP && alpha_fptm < ALPHA_FPTM_SU"
1724 "add%-%/ %R1,%R2,%0"
1725 [(set_attr "type" "fadd")
1726 (set_attr "trap" "yes")
1727 (set_attr "round_suffix" "normal")
1728 (set_attr "trap_suffix" "u_su_sui")])
1729
1730 (define_expand "addtf3"
1731 [(use (match_operand:TF 0 "register_operand"))
1732 (use (match_operand:TF 1 "general_operand"))
1733 (use (match_operand:TF 2 "general_operand"))]
1734 "TARGET_HAS_XFLOATING_LIBS"
1735 "alpha_emit_xfloating_arith (PLUS, operands); DONE;")
1736
1737 (define_insn "*sub<mode>3_ieee"
1738 [(set (match_operand:FMODE 0 "register_operand" "=&f")
1739 (minus:FMODE (match_operand:FMODE 1 "reg_or_0_operand" "fG")
1740 (match_operand:FMODE 2 "reg_or_0_operand" "fG")))]
1741 "TARGET_FP && alpha_fptm >= ALPHA_FPTM_SU"
1742 "sub<modesuffix>%/ %R1,%R2,%0"
1743 [(set_attr "type" "fadd")
1744 (set_attr "trap" "yes")
1745 (set_attr "round_suffix" "normal")
1746 (set_attr "trap_suffix" "u_su_sui")])
1747
1748 (define_insn "sub<mode>3"
1749 [(set (match_operand:FMODE 0 "register_operand" "=f")
1750 (minus:FMODE (match_operand:FMODE 1 "reg_or_0_operand" "fG")
1751 (match_operand:FMODE 2 "reg_or_0_operand" "fG")))]
1752 "TARGET_FP"
1753 "sub<modesuffix>%/ %R1,%R2,%0"
1754 [(set_attr "type" "fadd")
1755 (set_attr "trap" "yes")
1756 (set_attr "round_suffix" "normal")
1757 (set_attr "trap_suffix" "u_su_sui")])
1758
1759 (define_insn "*subdf_ext1"
1760 [(set (match_operand:DF 0 "register_operand" "=f")
1761 (minus:DF (float_extend:DF
1762 (match_operand:SF 1 "reg_or_0_operand" "fG"))
1763 (match_operand:DF 2 "reg_or_0_operand" "fG")))]
1764 "TARGET_FP && alpha_fptm < ALPHA_FPTM_SU"
1765 "sub%-%/ %R1,%R2,%0"
1766 [(set_attr "type" "fadd")
1767 (set_attr "trap" "yes")
1768 (set_attr "round_suffix" "normal")
1769 (set_attr "trap_suffix" "u_su_sui")])
1770
1771 (define_insn "*subdf_ext2"
1772 [(set (match_operand:DF 0 "register_operand" "=f")
1773 (minus:DF (match_operand:DF 1 "reg_or_0_operand" "fG")
1774 (float_extend:DF
1775 (match_operand:SF 2 "reg_or_0_operand" "fG"))))]
1776 "TARGET_FP && alpha_fptm < ALPHA_FPTM_SU"
1777 "sub%-%/ %R1,%R2,%0"
1778 [(set_attr "type" "fadd")
1779 (set_attr "trap" "yes")
1780 (set_attr "round_suffix" "normal")
1781 (set_attr "trap_suffix" "u_su_sui")])
1782
1783 (define_insn "*subdf_ext3"
1784 [(set (match_operand:DF 0 "register_operand" "=f")
1785 (minus:DF (float_extend:DF
1786 (match_operand:SF 1 "reg_or_0_operand" "fG"))
1787 (float_extend:DF
1788 (match_operand:SF 2 "reg_or_0_operand" "fG"))))]
1789 "TARGET_FP && alpha_fptm < ALPHA_FPTM_SU"
1790 "sub%-%/ %R1,%R2,%0"
1791 [(set_attr "type" "fadd")
1792 (set_attr "trap" "yes")
1793 (set_attr "round_suffix" "normal")
1794 (set_attr "trap_suffix" "u_su_sui")])
1795
1796 (define_expand "subtf3"
1797 [(use (match_operand:TF 0 "register_operand"))
1798 (use (match_operand:TF 1 "general_operand"))
1799 (use (match_operand:TF 2 "general_operand"))]
1800 "TARGET_HAS_XFLOATING_LIBS"
1801 "alpha_emit_xfloating_arith (MINUS, operands); DONE;")
1802
1803 (define_insn "*mul<mode>3_ieee"
1804 [(set (match_operand:FMODE 0 "register_operand" "=&f")
1805 (mult:FMODE (match_operand:FMODE 1 "reg_or_0_operand" "%fG")
1806 (match_operand:FMODE 2 "reg_or_0_operand" "fG")))]
1807 "TARGET_FP && alpha_fptm >= ALPHA_FPTM_SU"
1808 "mul<modesuffix>%/ %R1,%R2,%0"
1809 [(set_attr "type" "fmul")
1810 (set_attr "trap" "yes")
1811 (set_attr "round_suffix" "normal")
1812 (set_attr "trap_suffix" "u_su_sui")])
1813
1814 (define_insn "mul<mode>3"
1815 [(set (match_operand:FMODE 0 "register_operand" "=f")
1816 (mult:FMODE (match_operand:FMODE 1 "reg_or_0_operand" "%fG")
1817 (match_operand:FMODE 2 "reg_or_0_operand" "fG")))]
1818 "TARGET_FP"
1819 "mul<modesuffix>%/ %R1,%R2,%0"
1820 [(set_attr "type" "fmul")
1821 (set_attr "trap" "yes")
1822 (set_attr "round_suffix" "normal")
1823 (set_attr "trap_suffix" "u_su_sui")])
1824
1825 (define_insn "*muldf_ext1"
1826 [(set (match_operand:DF 0 "register_operand" "=f")
1827 (mult:DF (float_extend:DF
1828 (match_operand:SF 1 "reg_or_0_operand" "fG"))
1829 (match_operand:DF 2 "reg_or_0_operand" "fG")))]
1830 "TARGET_FP && alpha_fptm < ALPHA_FPTM_SU"
1831 "mul%-%/ %R1,%R2,%0"
1832 [(set_attr "type" "fmul")
1833 (set_attr "trap" "yes")
1834 (set_attr "round_suffix" "normal")
1835 (set_attr "trap_suffix" "u_su_sui")])
1836
1837 (define_insn "*muldf_ext2"
1838 [(set (match_operand:DF 0 "register_operand" "=f")
1839 (mult:DF (float_extend:DF
1840 (match_operand:SF 1 "reg_or_0_operand" "%fG"))
1841 (float_extend:DF
1842 (match_operand:SF 2 "reg_or_0_operand" "fG"))))]
1843 "TARGET_FP && alpha_fptm < ALPHA_FPTM_SU"
1844 "mul%-%/ %R1,%R2,%0"
1845 [(set_attr "type" "fmul")
1846 (set_attr "trap" "yes")
1847 (set_attr "round_suffix" "normal")
1848 (set_attr "trap_suffix" "u_su_sui")])
1849
1850 (define_expand "multf3"
1851 [(use (match_operand:TF 0 "register_operand"))
1852 (use (match_operand:TF 1 "general_operand"))
1853 (use (match_operand:TF 2 "general_operand"))]
1854 "TARGET_HAS_XFLOATING_LIBS"
1855 "alpha_emit_xfloating_arith (MULT, operands); DONE;")
1856
1857 (define_insn "*div<mode>3_ieee"
1858 [(set (match_operand:FMODE 0 "register_operand" "=&f")
1859 (div:FMODE (match_operand:FMODE 1 "reg_or_0_operand" "fG")
1860 (match_operand:FMODE 2 "reg_or_0_operand" "fG")))]
1861 "TARGET_FP && alpha_fptm >= ALPHA_FPTM_SU"
1862 "div<modesuffix>%/ %R1,%R2,%0"
1863 [(set_attr "type" "fdiv")
1864 (set_attr "opsize" "<opmode>")
1865 (set_attr "trap" "yes")
1866 (set_attr "round_suffix" "normal")
1867 (set_attr "trap_suffix" "u_su_sui")])
1868
1869 (define_insn "div<mode>3"
1870 [(set (match_operand:FMODE 0 "register_operand" "=f")
1871 (div:FMODE (match_operand:FMODE 1 "reg_or_0_operand" "fG")
1872 (match_operand:FMODE 2 "reg_or_0_operand" "fG")))]
1873 "TARGET_FP"
1874 "div<modesuffix>%/ %R1,%R2,%0"
1875 [(set_attr "type" "fdiv")
1876 (set_attr "opsize" "<opmode>")
1877 (set_attr "trap" "yes")
1878 (set_attr "round_suffix" "normal")
1879 (set_attr "trap_suffix" "u_su_sui")])
1880
1881 (define_insn "*divdf_ext1"
1882 [(set (match_operand:DF 0 "register_operand" "=f")
1883 (div:DF (float_extend:DF (match_operand:SF 1 "reg_or_0_operand" "fG"))
1884 (match_operand:DF 2 "reg_or_0_operand" "fG")))]
1885 "TARGET_FP && alpha_fptm < ALPHA_FPTM_SU"
1886 "div%-%/ %R1,%R2,%0"
1887 [(set_attr "type" "fdiv")
1888 (set_attr "trap" "yes")
1889 (set_attr "round_suffix" "normal")
1890 (set_attr "trap_suffix" "u_su_sui")])
1891
1892 (define_insn "*divdf_ext2"
1893 [(set (match_operand:DF 0 "register_operand" "=f")
1894 (div:DF (match_operand:DF 1 "reg_or_0_operand" "fG")
1895 (float_extend:DF
1896 (match_operand:SF 2 "reg_or_0_operand" "fG"))))]
1897 "TARGET_FP && alpha_fptm < ALPHA_FPTM_SU"
1898 "div%-%/ %R1,%R2,%0"
1899 [(set_attr "type" "fdiv")
1900 (set_attr "trap" "yes")
1901 (set_attr "round_suffix" "normal")
1902 (set_attr "trap_suffix" "u_su_sui")])
1903
1904 (define_insn "*divdf_ext3"
1905 [(set (match_operand:DF 0 "register_operand" "=f")
1906 (div:DF (float_extend:DF
1907 (match_operand:SF 1 "reg_or_0_operand" "fG"))
1908 (float_extend:DF
1909 (match_operand:SF 2 "reg_or_0_operand" "fG"))))]
1910 "TARGET_FP && alpha_fptm < ALPHA_FPTM_SU"
1911 "div%-%/ %R1,%R2,%0"
1912 [(set_attr "type" "fdiv")
1913 (set_attr "trap" "yes")
1914 (set_attr "round_suffix" "normal")
1915 (set_attr "trap_suffix" "u_su_sui")])
1916
1917 (define_expand "divtf3"
1918 [(use (match_operand:TF 0 "register_operand"))
1919 (use (match_operand:TF 1 "general_operand"))
1920 (use (match_operand:TF 2 "general_operand"))]
1921 "TARGET_HAS_XFLOATING_LIBS"
1922 "alpha_emit_xfloating_arith (DIV, operands); DONE;")
1923
1924 (define_insn "*sqrt<mode>2_ieee"
1925 [(set (match_operand:FMODE 0 "register_operand" "=&f")
1926 (sqrt:FMODE (match_operand:FMODE 1 "reg_or_0_operand" "fG")))]
1927 "TARGET_FP && TARGET_FIX && alpha_fptm >= ALPHA_FPTM_SU"
1928 "sqrt<modesuffix>%/ %R1,%0"
1929 [(set_attr "type" "fsqrt")
1930 (set_attr "opsize" "<opmode>")
1931 (set_attr "trap" "yes")
1932 (set_attr "round_suffix" "normal")
1933 (set_attr "trap_suffix" "u_su_sui")])
1934
1935 (define_insn "sqrt<mode>2"
1936 [(set (match_operand:FMODE 0 "register_operand" "=f")
1937 (sqrt:FMODE (match_operand:FMODE 1 "reg_or_0_operand" "fG")))]
1938 "TARGET_FP && TARGET_FIX"
1939 "sqrt<modesuffix>%/ %R1,%0"
1940 [(set_attr "type" "fsqrt")
1941 (set_attr "opsize" "<opmode>")
1942 (set_attr "trap" "yes")
1943 (set_attr "round_suffix" "normal")
1944 (set_attr "trap_suffix" "u_su_sui")])
1945
1946 ;; Define conversion operators between DFmode and SImode, using the cvtql
1947 ;; instruction. To allow combine et al to do useful things, we keep the
1948 ;; operation as a unit until after reload, at which point we split the
1949 ;; instructions.
1950 ;;
1951 ;; Note that we (attempt to) only consider this optimization when the
1952 ;; ultimate destination is memory. If we will be doing further integer
1953 ;; processing, it is cheaper to do the truncation in the int regs.
1954
1955 (define_insn "*cvtql"
1956 [(set (match_operand:SF 0 "register_operand" "=f")
1957 (unspec:SF [(match_operand:DI 1 "reg_or_0_operand" "fG")]
1958 UNSPEC_CVTQL))]
1959 "TARGET_FP"
1960 "cvtql%/ %R1,%0"
1961 [(set_attr "type" "fadd")
1962 (set_attr "trap" "yes")
1963 (set_attr "trap_suffix" "v_sv")])
1964
1965 (define_insn_and_split "*fix_truncdfsi_ieee"
1966 [(set (match_operand:SI 0 "memory_operand" "=m")
1967 (subreg:SI
1968 (match_operator:DI 4 "fix_operator"
1969 [(match_operand:DF 1 "reg_or_0_operand" "fG")]) 0))
1970 (clobber (match_scratch:DI 2 "=&f"))
1971 (clobber (match_scratch:SF 3 "=&f"))]
1972 "TARGET_FP && alpha_fptm >= ALPHA_FPTM_SU"
1973 "#"
1974 "&& reload_completed"
1975 [(set (match_dup 2) (match_op_dup 4 [(match_dup 1)]))
1976 (set (match_dup 3) (unspec:SF [(match_dup 2)] UNSPEC_CVTQL))
1977 (set (match_dup 5) (match_dup 3))]
1978 {
1979 operands[5] = adjust_address (operands[0], SFmode, 0);
1980 }
1981 [(set_attr "type" "fadd")
1982 (set_attr "trap" "yes")])
1983
1984 (define_insn_and_split "*fix_truncdfsi_internal"
1985 [(set (match_operand:SI 0 "memory_operand" "=m")
1986 (subreg:SI
1987 (match_operator:DI 3 "fix_operator"
1988 [(match_operand:DF 1 "reg_or_0_operand" "fG")]) 0))
1989 (clobber (match_scratch:DI 2 "=f"))]
1990 "TARGET_FP && alpha_fptm < ALPHA_FPTM_SU"
1991 "#"
1992 "&& reload_completed"
1993 [(set (match_dup 2) (match_op_dup 3 [(match_dup 1)]))
1994 (set (match_dup 4) (unspec:SF [(match_dup 2)] UNSPEC_CVTQL))
1995 (set (match_dup 5) (match_dup 4))]
1996 {
1997 operands[4] = gen_rtx_REG (SFmode, REGNO (operands[2]));
1998 operands[5] = adjust_address (operands[0], SFmode, 0);
1999 }
2000 [(set_attr "type" "fadd")
2001 (set_attr "trap" "yes")])
2002
2003 (define_insn "*fix_truncdfdi_ieee"
2004 [(set (match_operand:DI 0 "reg_no_subreg_operand" "=&f")
2005 (match_operator:DI 2 "fix_operator"
2006 [(match_operand:DF 1 "reg_or_0_operand" "fG")]))]
2007 "TARGET_FP && alpha_fptm >= ALPHA_FPTM_SU"
2008 "cvt%-q%/ %R1,%0"
2009 [(set_attr "type" "fadd")
2010 (set_attr "trap" "yes")
2011 (set_attr "round_suffix" "c")
2012 (set_attr "trap_suffix" "v_sv_svi")])
2013
2014 (define_insn "*fix_truncdfdi2"
2015 [(set (match_operand:DI 0 "reg_no_subreg_operand" "=f")
2016 (match_operator:DI 2 "fix_operator"
2017 [(match_operand:DF 1 "reg_or_0_operand" "fG")]))]
2018 "TARGET_FP"
2019 "cvt%-q%/ %R1,%0"
2020 [(set_attr "type" "fadd")
2021 (set_attr "trap" "yes")
2022 (set_attr "round_suffix" "c")
2023 (set_attr "trap_suffix" "v_sv_svi")])
2024
2025 (define_expand "fix_truncdfdi2"
2026 [(set (match_operand:DI 0 "reg_no_subreg_operand")
2027 (fix:DI (match_operand:DF 1 "reg_or_0_operand")))]
2028 "TARGET_FP")
2029
2030 (define_expand "fixuns_truncdfdi2"
2031 [(set (match_operand:DI 0 "reg_no_subreg_operand")
2032 (unsigned_fix:DI (match_operand:DF 1 "reg_or_0_operand")))]
2033 "TARGET_FP")
2034
2035 ;; Likewise between SFmode and SImode.
2036
2037 (define_insn_and_split "*fix_truncsfsi_ieee"
2038 [(set (match_operand:SI 0 "memory_operand" "=m")
2039 (subreg:SI
2040 (match_operator:DI 4 "fix_operator"
2041 [(float_extend:DF
2042 (match_operand:SF 1 "reg_or_0_operand" "fG"))]) 0))
2043 (clobber (match_scratch:DI 2 "=&f"))
2044 (clobber (match_scratch:SF 3 "=&f"))]
2045 "TARGET_FP && alpha_fptm >= ALPHA_FPTM_SU"
2046 "#"
2047 "&& reload_completed"
2048 [(set (match_dup 2) (match_op_dup 4 [(float_extend:DF (match_dup 1))]))
2049 (set (match_dup 3) (unspec:SF [(match_dup 2)] UNSPEC_CVTQL))
2050 (set (match_dup 5) (match_dup 3))]
2051 "operands[5] = adjust_address (operands[0], SFmode, 0);"
2052 [(set_attr "type" "fadd")
2053 (set_attr "trap" "yes")])
2054
2055 (define_insn_and_split "*fix_truncsfsi_internal"
2056 [(set (match_operand:SI 0 "memory_operand" "=m")
2057 (subreg:SI
2058 (match_operator:DI 3 "fix_operator"
2059 [(float_extend:DF
2060 (match_operand:SF 1 "reg_or_0_operand" "fG"))]) 0))
2061 (clobber (match_scratch:DI 2 "=f"))]
2062 "TARGET_FP && alpha_fptm < ALPHA_FPTM_SU"
2063 "#"
2064 "&& reload_completed"
2065 [(set (match_dup 2) (match_op_dup 3 [(float_extend:DF (match_dup 1))]))
2066 (set (match_dup 4) (unspec:SF [(match_dup 2)] UNSPEC_CVTQL))
2067 (set (match_dup 5) (match_dup 4))]
2068 {
2069 operands[4] = gen_rtx_REG (SFmode, REGNO (operands[2]));
2070 operands[5] = adjust_address (operands[0], SFmode, 0);
2071 }
2072 [(set_attr "type" "fadd")
2073 (set_attr "trap" "yes")])
2074
2075 (define_insn "*fix_truncsfdi_ieee"
2076 [(set (match_operand:DI 0 "reg_no_subreg_operand" "=&f")
2077 (match_operator:DI 2 "fix_operator"
2078 [(float_extend:DF (match_operand:SF 1 "reg_or_0_operand" "fG"))]))]
2079 "TARGET_FP && alpha_fptm >= ALPHA_FPTM_SU"
2080 "cvt%-q%/ %R1,%0"
2081 [(set_attr "type" "fadd")
2082 (set_attr "trap" "yes")
2083 (set_attr "round_suffix" "c")
2084 (set_attr "trap_suffix" "v_sv_svi")])
2085
2086 (define_insn "*fix_truncsfdi2"
2087 [(set (match_operand:DI 0 "reg_no_subreg_operand" "=f")
2088 (match_operator:DI 2 "fix_operator"
2089 [(float_extend:DF (match_operand:SF 1 "reg_or_0_operand" "fG"))]))]
2090 "TARGET_FP"
2091 "cvt%-q%/ %R1,%0"
2092 [(set_attr "type" "fadd")
2093 (set_attr "trap" "yes")
2094 (set_attr "round_suffix" "c")
2095 (set_attr "trap_suffix" "v_sv_svi")])
2096
2097 (define_expand "fix_truncsfdi2"
2098 [(set (match_operand:DI 0 "reg_no_subreg_operand")
2099 (fix:DI (float_extend:DF (match_operand:SF 1 "reg_or_0_operand"))))]
2100 "TARGET_FP")
2101
2102 (define_expand "fixuns_truncsfdi2"
2103 [(set (match_operand:DI 0 "reg_no_subreg_operand")
2104 (unsigned_fix:DI
2105 (float_extend:DF (match_operand:SF 1 "reg_or_0_operand"))))]
2106 "TARGET_FP")
2107
2108 (define_expand "fix_trunctfdi2"
2109 [(use (match_operand:DI 0 "register_operand"))
2110 (use (match_operand:TF 1 "general_operand"))]
2111 "TARGET_HAS_XFLOATING_LIBS"
2112 "alpha_emit_xfloating_cvt (FIX, operands); DONE;")
2113
2114 (define_expand "fixuns_trunctfdi2"
2115 [(use (match_operand:DI 0 "register_operand"))
2116 (use (match_operand:TF 1 "general_operand"))]
2117 "TARGET_HAS_XFLOATING_LIBS"
2118 "alpha_emit_xfloating_cvt (UNSIGNED_FIX, operands); DONE;")
2119
2120 (define_insn "*floatdisf_ieee"
2121 [(set (match_operand:SF 0 "register_operand" "=&f")
2122 (float:SF (match_operand:DI 1 "reg_no_subreg_operand" "f")))]
2123 "TARGET_FP && alpha_fptm >= ALPHA_FPTM_SU"
2124 "cvtq%,%/ %1,%0"
2125 [(set_attr "type" "fadd")
2126 (set_attr "trap" "yes")
2127 (set_attr "round_suffix" "normal")
2128 (set_attr "trap_suffix" "sui")])
2129
2130 (define_insn "floatdisf2"
2131 [(set (match_operand:SF 0 "register_operand" "=f")
2132 (float:SF (match_operand:DI 1 "reg_no_subreg_operand" "f")))]
2133 "TARGET_FP"
2134 "cvtq%,%/ %1,%0"
2135 [(set_attr "type" "fadd")
2136 (set_attr "trap" "yes")
2137 (set_attr "round_suffix" "normal")
2138 (set_attr "trap_suffix" "sui")])
2139
2140 (define_insn_and_split "*floatsisf2_ieee"
2141 [(set (match_operand:SF 0 "register_operand" "=&f")
2142 (float:SF (match_operand:SI 1 "memory_operand" "m")))
2143 (clobber (match_scratch:DI 2 "=&f"))
2144 (clobber (match_scratch:SF 3 "=&f"))]
2145 "TARGET_FP && alpha_fptm >= ALPHA_FPTM_SU"
2146 "#"
2147 "&& reload_completed"
2148 [(set (match_dup 3) (match_dup 1))
2149 (set (match_dup 2) (unspec:DI [(match_dup 3)] UNSPEC_CVTLQ))
2150 (set (match_dup 0) (float:SF (match_dup 2)))]
2151 "operands[1] = adjust_address (operands[1], SFmode, 0);")
2152
2153 (define_insn_and_split "*floatsisf2"
2154 [(set (match_operand:SF 0 "register_operand" "=f")
2155 (float:SF (match_operand:SI 1 "memory_operand" "m")))]
2156 "TARGET_FP"
2157 "#"
2158 "&& reload_completed"
2159 [(set (match_dup 0) (match_dup 1))
2160 (set (match_dup 2) (unspec:DI [(match_dup 0)] UNSPEC_CVTLQ))
2161 (set (match_dup 0) (float:SF (match_dup 2)))]
2162 {
2163 operands[1] = adjust_address (operands[1], SFmode, 0);
2164 operands[2] = gen_rtx_REG (DImode, REGNO (operands[0]));
2165 })
2166
2167 (define_insn "*floatdidf_ieee"
2168 [(set (match_operand:DF 0 "register_operand" "=&f")
2169 (float:DF (match_operand:DI 1 "reg_no_subreg_operand" "f")))]
2170 "TARGET_FP && alpha_fptm >= ALPHA_FPTM_SU"
2171 "cvtq%-%/ %1,%0"
2172 [(set_attr "type" "fadd")
2173 (set_attr "trap" "yes")
2174 (set_attr "round_suffix" "normal")
2175 (set_attr "trap_suffix" "sui")])
2176
2177 (define_insn "floatdidf2"
2178 [(set (match_operand:DF 0 "register_operand" "=f")
2179 (float:DF (match_operand:DI 1 "reg_no_subreg_operand" "f")))]
2180 "TARGET_FP"
2181 "cvtq%-%/ %1,%0"
2182 [(set_attr "type" "fadd")
2183 (set_attr "trap" "yes")
2184 (set_attr "round_suffix" "normal")
2185 (set_attr "trap_suffix" "sui")])
2186
2187 (define_insn_and_split "*floatsidf2_ieee"
2188 [(set (match_operand:DF 0 "register_operand" "=&f")
2189 (float:DF (match_operand:SI 1 "memory_operand" "m")))
2190 (clobber (match_scratch:DI 2 "=&f"))
2191 (clobber (match_scratch:SF 3 "=&f"))]
2192 "TARGET_FP && alpha_fptm >= ALPHA_FPTM_SU"
2193 "#"
2194 "&& reload_completed"
2195 [(set (match_dup 3) (match_dup 1))
2196 (set (match_dup 2) (unspec:DI [(match_dup 3)] UNSPEC_CVTLQ))
2197 (set (match_dup 0) (float:DF (match_dup 2)))]
2198 "operands[1] = adjust_address (operands[1], SFmode, 0);")
2199
2200 (define_insn_and_split "*floatsidf2"
2201 [(set (match_operand:DF 0 "register_operand" "=f")
2202 (float:DF (match_operand:SI 1 "memory_operand" "m")))]
2203 "TARGET_FP"
2204 "#"
2205 "&& reload_completed"
2206 [(set (match_dup 3) (match_dup 1))
2207 (set (match_dup 2) (unspec:DI [(match_dup 3)] UNSPEC_CVTLQ))
2208 (set (match_dup 0) (float:DF (match_dup 2)))]
2209 {
2210 operands[1] = adjust_address (operands[1], SFmode, 0);
2211 operands[2] = gen_rtx_REG (DImode, REGNO (operands[0]));
2212 operands[3] = gen_rtx_REG (SFmode, REGNO (operands[0]));
2213 })
2214
2215 (define_expand "floatditf2"
2216 [(use (match_operand:TF 0 "register_operand"))
2217 (use (match_operand:DI 1 "general_operand"))]
2218 "TARGET_HAS_XFLOATING_LIBS"
2219 "alpha_emit_xfloating_cvt (FLOAT, operands); DONE;")
2220
2221 (define_expand "floatunsdisf2"
2222 [(use (match_operand:SF 0 "register_operand"))
2223 (use (match_operand:DI 1 "register_operand"))]
2224 "TARGET_FP"
2225 "alpha_emit_floatuns (operands); DONE;")
2226
2227 (define_expand "floatunsdidf2"
2228 [(use (match_operand:DF 0 "register_operand"))
2229 (use (match_operand:DI 1 "register_operand"))]
2230 "TARGET_FP"
2231 "alpha_emit_floatuns (operands); DONE;")
2232
2233 (define_expand "floatunsditf2"
2234 [(use (match_operand:TF 0 "register_operand"))
2235 (use (match_operand:DI 1 "general_operand"))]
2236 "TARGET_HAS_XFLOATING_LIBS"
2237 "alpha_emit_xfloating_cvt (UNSIGNED_FLOAT, operands); DONE;")
2238
2239 (define_expand "extendsfdf2"
2240 [(set (match_operand:DF 0 "register_operand")
2241 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand")))]
2242 "TARGET_FP"
2243 {
2244 if (alpha_fptm >= ALPHA_FPTM_SU)
2245 operands[1] = force_reg (SFmode, operands[1]);
2246 })
2247
2248 ;; The Unicos/Mk assembler doesn't support cvtst, but we've already
2249 ;; asserted that alpha_fptm == ALPHA_FPTM_N.
2250
2251 (define_insn "*extendsfdf2_ieee"
2252 [(set (match_operand:DF 0 "register_operand" "=&f")
2253 (float_extend:DF (match_operand:SF 1 "register_operand" "f")))]
2254 "TARGET_FP && alpha_fptm >= ALPHA_FPTM_SU"
2255 "cvtsts %1,%0"
2256 [(set_attr "type" "fadd")
2257 (set_attr "trap" "yes")])
2258
2259 (define_insn "*extendsfdf2_internal"
2260 [(set (match_operand:DF 0 "register_operand" "=f,f,m")
2261 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "f,m,f")))]
2262 "TARGET_FP && alpha_fptm < ALPHA_FPTM_SU"
2263 "@
2264 cpys %1,%1,%0
2265 ld%, %0,%1
2266 st%- %1,%0"
2267 [(set_attr "type" "fcpys,fld,fst")])
2268
2269 ;; Use register_operand for operand 1 to prevent compress_float_constant
2270 ;; from doing something silly. When optimizing we'll put things back
2271 ;; together anyway.
2272 (define_expand "extendsftf2"
2273 [(use (match_operand:TF 0 "register_operand"))
2274 (use (match_operand:SF 1 "register_operand"))]
2275 "TARGET_HAS_XFLOATING_LIBS"
2276 {
2277 rtx tmp = gen_reg_rtx (DFmode);
2278 emit_insn (gen_extendsfdf2 (tmp, operands[1]));
2279 emit_insn (gen_extenddftf2 (operands[0], tmp));
2280 DONE;
2281 })
2282
2283 (define_expand "extenddftf2"
2284 [(use (match_operand:TF 0 "register_operand"))
2285 (use (match_operand:DF 1 "register_operand"))]
2286 "TARGET_HAS_XFLOATING_LIBS"
2287 "alpha_emit_xfloating_cvt (FLOAT_EXTEND, operands); DONE;")
2288
2289 (define_insn "*truncdfsf2_ieee"
2290 [(set (match_operand:SF 0 "register_operand" "=&f")
2291 (float_truncate:SF (match_operand:DF 1 "reg_or_0_operand" "fG")))]
2292 "TARGET_FP && alpha_fptm >= ALPHA_FPTM_SU"
2293 "cvt%-%,%/ %R1,%0"
2294 [(set_attr "type" "fadd")
2295 (set_attr "trap" "yes")
2296 (set_attr "round_suffix" "normal")
2297 (set_attr "trap_suffix" "u_su_sui")])
2298
2299 (define_insn "truncdfsf2"
2300 [(set (match_operand:SF 0 "register_operand" "=f")
2301 (float_truncate:SF (match_operand:DF 1 "reg_or_0_operand" "fG")))]
2302 "TARGET_FP"
2303 "cvt%-%,%/ %R1,%0"
2304 [(set_attr "type" "fadd")
2305 (set_attr "trap" "yes")
2306 (set_attr "round_suffix" "normal")
2307 (set_attr "trap_suffix" "u_su_sui")])
2308
2309 (define_expand "trunctfdf2"
2310 [(use (match_operand:DF 0 "register_operand"))
2311 (use (match_operand:TF 1 "general_operand"))]
2312 "TARGET_HAS_XFLOATING_LIBS"
2313 "alpha_emit_xfloating_cvt (FLOAT_TRUNCATE, operands); DONE;")
2314
2315 (define_expand "trunctfsf2"
2316 [(use (match_operand:SF 0 "register_operand"))
2317 (use (match_operand:TF 1 "general_operand"))]
2318 "TARGET_FP && TARGET_HAS_XFLOATING_LIBS"
2319 {
2320 rtx tmpf, sticky, arg, lo, hi;
2321
2322 tmpf = gen_reg_rtx (DFmode);
2323 sticky = gen_reg_rtx (DImode);
2324 arg = copy_to_mode_reg (TFmode, operands[1]);
2325 lo = gen_lowpart (DImode, arg);
2326 hi = gen_highpart (DImode, arg);
2327
2328 /* Convert the low word of the TFmode value into a sticky rounding bit,
2329 then or it into the low bit of the high word. This leaves the sticky
2330 bit at bit 48 of the fraction, which is representable in DFmode,
2331 which prevents rounding error in the final conversion to SFmode. */
2332
2333 emit_insn (gen_rtx_SET (sticky, gen_rtx_NE (DImode, lo, const0_rtx)));
2334 emit_insn (gen_iordi3 (hi, hi, sticky));
2335 emit_insn (gen_trunctfdf2 (tmpf, arg));
2336 emit_insn (gen_truncdfsf2 (operands[0], tmpf));
2337 DONE;
2338 })
2339
2341 ;; Next are all the integer comparisons, and conditional moves and branches
2342 ;; and some of the related define_expand's and define_split's.
2343
2344 (define_insn "*setcc_internal"
2345 [(set (match_operand 0 "register_operand" "=r")
2346 (match_operator 1 "alpha_comparison_operator"
2347 [(match_operand:DI 2 "register_operand" "r")
2348 (match_operand:DI 3 "reg_or_8bit_operand" "rI")]))]
2349 "GET_MODE_CLASS (GET_MODE (operands[0])) == MODE_INT
2350 && GET_MODE_SIZE (GET_MODE (operands[0])) <= 8
2351 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
2352 "cmp%C1 %2,%3,%0"
2353 [(set_attr "type" "icmp")])
2354
2355 ;; Yes, we can technically support reg_or_8bit_operand in operand 2,
2356 ;; but that's non-canonical rtl and allowing that causes inefficiencies
2357 ;; from cse on.
2358 (define_insn "*setcc_swapped_internal"
2359 [(set (match_operand 0 "register_operand" "=r")
2360 (match_operator 1 "alpha_swapped_comparison_operator"
2361 [(match_operand:DI 2 "register_operand" "r")
2362 (match_operand:DI 3 "reg_or_0_operand" "rJ")]))]
2363 "GET_MODE_CLASS (GET_MODE (operands[0])) == MODE_INT
2364 && GET_MODE_SIZE (GET_MODE (operands[0])) <= 8
2365 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
2366 "cmp%c1 %r3,%2,%0"
2367 [(set_attr "type" "icmp")])
2368
2369 ;; Use match_operator rather than ne directly so that we can match
2370 ;; multiple integer modes.
2371 (define_insn "*setne_internal"
2372 [(set (match_operand 0 "register_operand" "=r")
2373 (match_operator 1 "signed_comparison_operator"
2374 [(match_operand:DI 2 "register_operand" "r")
2375 (const_int 0)]))]
2376 "GET_MODE_CLASS (GET_MODE (operands[0])) == MODE_INT
2377 && GET_MODE_SIZE (GET_MODE (operands[0])) <= 8
2378 && GET_CODE (operands[1]) == NE
2379 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
2380 "cmpult $31,%2,%0"
2381 [(set_attr "type" "icmp")])
2382
2383 ;; The mode folding trick can't be used with const_int operands, since
2384 ;; reload needs to know the proper mode.
2385 ;;
2386 ;; Use add_operand instead of the more seemingly natural reg_or_8bit_operand
2387 ;; in order to create more pairs of constants. As long as we're allowing
2388 ;; two constants at the same time, and will have to reload one of them...
2389
2390 (define_insn "*mov<mode>cc_internal"
2391 [(set (match_operand:IMODE 0 "register_operand" "=r,r,r,r")
2392 (if_then_else:IMODE
2393 (match_operator 2 "signed_comparison_operator"
2394 [(match_operand:DI 3 "reg_or_0_operand" "rJ,rJ,J,J")
2395 (match_operand:DI 4 "reg_or_0_operand" "J,J,rJ,rJ")])
2396 (match_operand:IMODE 1 "add_operand" "rI,0,rI,0")
2397 (match_operand:IMODE 5 "add_operand" "0,rI,0,rI")))]
2398 "(operands[3] == const0_rtx) ^ (operands[4] == const0_rtx)"
2399 "@
2400 cmov%C2 %r3,%1,%0
2401 cmov%D2 %r3,%5,%0
2402 cmov%c2 %r4,%1,%0
2403 cmov%d2 %r4,%5,%0"
2404 [(set_attr "type" "icmov")])
2405
2406 (define_insn "*mov<mode>cc_lbc"
2407 [(set (match_operand:IMODE 0 "register_operand" "=r,r")
2408 (if_then_else:IMODE
2409 (eq (zero_extract:DI (match_operand:DI 2 "reg_or_0_operand" "rJ,rJ")
2410 (const_int 1)
2411 (const_int 0))
2412 (const_int 0))
2413 (match_operand:IMODE 1 "reg_or_8bit_operand" "rI,0")
2414 (match_operand:IMODE 3 "reg_or_8bit_operand" "0,rI")))]
2415 ""
2416 "@
2417 cmovlbc %r2,%1,%0
2418 cmovlbs %r2,%3,%0"
2419 [(set_attr "type" "icmov")])
2420
2421 (define_insn "*mov<mode>cc_lbs"
2422 [(set (match_operand:IMODE 0 "register_operand" "=r,r")
2423 (if_then_else:IMODE
2424 (ne (zero_extract:DI (match_operand:DI 2 "reg_or_0_operand" "rJ,rJ")
2425 (const_int 1)
2426 (const_int 0))
2427 (const_int 0))
2428 (match_operand:IMODE 1 "reg_or_8bit_operand" "rI,0")
2429 (match_operand:IMODE 3 "reg_or_8bit_operand" "0,rI")))]
2430 ""
2431 "@
2432 cmovlbs %r2,%1,%0
2433 cmovlbc %r2,%3,%0"
2434 [(set_attr "type" "icmov")])
2435
2436 ;; For ABS, we have two choices, depending on whether the input and output
2437 ;; registers are the same or not.
2438 (define_expand "absdi2"
2439 [(set (match_operand:DI 0 "register_operand")
2440 (abs:DI (match_operand:DI 1 "register_operand")))]
2441 ""
2442 {
2443 if (rtx_equal_p (operands[0], operands[1]))
2444 emit_insn (gen_absdi2_same (operands[0], gen_reg_rtx (DImode)));
2445 else
2446 emit_insn (gen_absdi2_diff (operands[0], operands[1]));
2447 DONE;
2448 })
2449
2450 (define_expand "absdi2_same"
2451 [(set (match_operand:DI 1 "register_operand")
2452 (neg:DI (match_operand:DI 0 "register_operand")))
2453 (set (match_dup 0)
2454 (if_then_else:DI (ge (match_dup 0) (const_int 0))
2455 (match_dup 0)
2456 (match_dup 1)))])
2457
2458 (define_expand "absdi2_diff"
2459 [(set (match_operand:DI 0 "register_operand")
2460 (neg:DI (match_operand:DI 1 "register_operand")))
2461 (set (match_dup 0)
2462 (if_then_else:DI (lt (match_dup 1) (const_int 0))
2463 (match_dup 0)
2464 (match_dup 1)))])
2465
2466 (define_split
2467 [(set (match_operand:DI 0 "register_operand")
2468 (abs:DI (match_dup 0)))
2469 (clobber (match_operand:DI 1 "register_operand"))]
2470 ""
2471 [(set (match_dup 1) (neg:DI (match_dup 0)))
2472 (set (match_dup 0) (if_then_else:DI (ge (match_dup 0) (const_int 0))
2473 (match_dup 0) (match_dup 1)))])
2474
2475 (define_split
2476 [(set (match_operand:DI 0 "register_operand")
2477 (abs:DI (match_operand:DI 1 "register_operand")))]
2478 "! rtx_equal_p (operands[0], operands[1])"
2479 [(set (match_dup 0) (neg:DI (match_dup 1)))
2480 (set (match_dup 0) (if_then_else:DI (lt (match_dup 1) (const_int 0))
2481 (match_dup 0) (match_dup 1)))])
2482
2483 (define_split
2484 [(set (match_operand:DI 0 "register_operand")
2485 (neg:DI (abs:DI (match_dup 0))))
2486 (clobber (match_operand:DI 1 "register_operand"))]
2487 ""
2488 [(set (match_dup 1) (neg:DI (match_dup 0)))
2489 (set (match_dup 0) (if_then_else:DI (le (match_dup 0) (const_int 0))
2490 (match_dup 0) (match_dup 1)))])
2491
2492 (define_split
2493 [(set (match_operand:DI 0 "register_operand")
2494 (neg:DI (abs:DI (match_operand:DI 1 "register_operand"))))]
2495 "! rtx_equal_p (operands[0], operands[1])"
2496 [(set (match_dup 0) (neg:DI (match_dup 1)))
2497 (set (match_dup 0) (if_then_else:DI (gt (match_dup 1) (const_int 0))
2498 (match_dup 0) (match_dup 1)))])
2499
2500 (define_insn "<code><mode>3"
2501 [(set (match_operand:I12MODE 0 "register_operand" "=r")
2502 (any_maxmin:I12MODE
2503 (match_operand:I12MODE 1 "reg_or_0_operand" "%rJ")
2504 (match_operand:I12MODE 2 "reg_or_8bit_operand" "rI")))]
2505 "TARGET_MAX"
2506 "<maxmin><vecmodesuffix> %r1,%2,%0"
2507 [(set_attr "type" "mvi")])
2508
2509 (define_expand "smaxdi3"
2510 [(set (match_dup 3)
2511 (le:DI (match_operand:DI 1 "reg_or_0_operand")
2512 (match_operand:DI 2 "reg_or_8bit_operand")))
2513 (set (match_operand:DI 0 "register_operand")
2514 (if_then_else:DI (eq (match_dup 3) (const_int 0))
2515 (match_dup 1) (match_dup 2)))]
2516 ""
2517 "operands[3] = gen_reg_rtx (DImode);")
2518
2519 (define_split
2520 [(set (match_operand:DI 0 "register_operand")
2521 (smax:DI (match_operand:DI 1 "reg_or_0_operand")
2522 (match_operand:DI 2 "reg_or_8bit_operand")))
2523 (clobber (match_operand:DI 3 "register_operand"))]
2524 "operands[2] != const0_rtx"
2525 [(set (match_dup 3) (le:DI (match_dup 1) (match_dup 2)))
2526 (set (match_dup 0) (if_then_else:DI (eq (match_dup 3) (const_int 0))
2527 (match_dup 1) (match_dup 2)))])
2528
2529 (define_insn "*smax_const0"
2530 [(set (match_operand:DI 0 "register_operand" "=r")
2531 (smax:DI (match_operand:DI 1 "register_operand" "0")
2532 (const_int 0)))]
2533 ""
2534 "cmovlt %0,0,%0"
2535 [(set_attr "type" "icmov")])
2536
2537 (define_expand "smindi3"
2538 [(set (match_dup 3)
2539 (lt:DI (match_operand:DI 1 "reg_or_0_operand")
2540 (match_operand:DI 2 "reg_or_8bit_operand")))
2541 (set (match_operand:DI 0 "register_operand")
2542 (if_then_else:DI (ne (match_dup 3) (const_int 0))
2543 (match_dup 1) (match_dup 2)))]
2544 ""
2545 "operands[3] = gen_reg_rtx (DImode);")
2546
2547 (define_split
2548 [(set (match_operand:DI 0 "register_operand")
2549 (smin:DI (match_operand:DI 1 "reg_or_0_operand")
2550 (match_operand:DI 2 "reg_or_8bit_operand")))
2551 (clobber (match_operand:DI 3 "register_operand"))]
2552 "operands[2] != const0_rtx"
2553 [(set (match_dup 3) (lt:DI (match_dup 1) (match_dup 2)))
2554 (set (match_dup 0) (if_then_else:DI (ne (match_dup 3) (const_int 0))
2555 (match_dup 1) (match_dup 2)))])
2556
2557 (define_insn "*smin_const0"
2558 [(set (match_operand:DI 0 "register_operand" "=r")
2559 (smin:DI (match_operand:DI 1 "register_operand" "0")
2560 (const_int 0)))]
2561 ""
2562 "cmovgt %0,0,%0"
2563 [(set_attr "type" "icmov")])
2564
2565 (define_expand "umaxdi3"
2566 [(set (match_dup 3)
2567 (leu:DI (match_operand:DI 1 "reg_or_0_operand")
2568 (match_operand:DI 2 "reg_or_8bit_operand")))
2569 (set (match_operand:DI 0 "register_operand")
2570 (if_then_else:DI (eq (match_dup 3) (const_int 0))
2571 (match_dup 1) (match_dup 2)))]
2572 ""
2573 "operands[3] = gen_reg_rtx (DImode);")
2574
2575 (define_split
2576 [(set (match_operand:DI 0 "register_operand")
2577 (umax:DI (match_operand:DI 1 "reg_or_0_operand")
2578 (match_operand:DI 2 "reg_or_8bit_operand")))
2579 (clobber (match_operand:DI 3 "register_operand"))]
2580 "operands[2] != const0_rtx"
2581 [(set (match_dup 3) (leu:DI (match_dup 1) (match_dup 2)))
2582 (set (match_dup 0) (if_then_else:DI (eq (match_dup 3) (const_int 0))
2583 (match_dup 1) (match_dup 2)))])
2584
2585 (define_expand "umindi3"
2586 [(set (match_dup 3)
2587 (ltu:DI (match_operand:DI 1 "reg_or_0_operand")
2588 (match_operand:DI 2 "reg_or_8bit_operand")))
2589 (set (match_operand:DI 0 "register_operand")
2590 (if_then_else:DI (ne (match_dup 3) (const_int 0))
2591 (match_dup 1) (match_dup 2)))]
2592 ""
2593 "operands[3] = gen_reg_rtx (DImode);")
2594
2595 (define_split
2596 [(set (match_operand:DI 0 "register_operand")
2597 (umin:DI (match_operand:DI 1 "reg_or_0_operand")
2598 (match_operand:DI 2 "reg_or_8bit_operand")))
2599 (clobber (match_operand:DI 3 "register_operand"))]
2600 "operands[2] != const0_rtx"
2601 [(set (match_dup 3) (ltu:DI (match_dup 1) (match_dup 2)))
2602 (set (match_dup 0) (if_then_else:DI (ne (match_dup 3) (const_int 0))
2603 (match_dup 1) (match_dup 2)))])
2604
2605 (define_insn "*bcc_normal"
2606 [(set (pc)
2607 (if_then_else
2608 (match_operator 1 "signed_comparison_operator"
2609 [(match_operand:DI 2 "reg_or_0_operand" "rJ")
2610 (const_int 0)])
2611 (label_ref (match_operand 0))
2612 (pc)))]
2613 ""
2614 "b%C1 %r2,%0"
2615 [(set_attr "type" "ibr")])
2616
2617 (define_insn "*bcc_reverse"
2618 [(set (pc)
2619 (if_then_else
2620 (match_operator 1 "signed_comparison_operator"
2621 [(match_operand:DI 2 "register_operand" "r")
2622 (const_int 0)])
2623
2624 (pc)
2625 (label_ref (match_operand 0))))]
2626 ""
2627 "b%c1 %2,%0"
2628 [(set_attr "type" "ibr")])
2629
2630 (define_insn "*blbs_normal"
2631 [(set (pc)
2632 (if_then_else
2633 (ne (zero_extract:DI (match_operand:DI 1 "reg_or_0_operand" "rJ")
2634 (const_int 1)
2635 (const_int 0))
2636 (const_int 0))
2637 (label_ref (match_operand 0))
2638 (pc)))]
2639 ""
2640 "blbs %r1,%0"
2641 [(set_attr "type" "ibr")])
2642
2643 (define_insn "*blbc_normal"
2644 [(set (pc)
2645 (if_then_else
2646 (eq (zero_extract:DI (match_operand:DI 1 "reg_or_0_operand" "rJ")
2647 (const_int 1)
2648 (const_int 0))
2649 (const_int 0))
2650 (label_ref (match_operand 0))
2651 (pc)))]
2652 ""
2653 "blbc %r1,%0"
2654 [(set_attr "type" "ibr")])
2655
2656 (define_split
2657 [(parallel
2658 [(set (pc)
2659 (if_then_else
2660 (match_operator 1 "comparison_operator"
2661 [(zero_extract:DI (match_operand:DI 2 "register_operand")
2662 (const_int 1)
2663 (match_operand:DI 3 "const_int_operand"))
2664 (const_int 0)])
2665 (label_ref (match_operand 0))
2666 (pc)))
2667 (clobber (match_operand:DI 4 "register_operand"))])]
2668 "INTVAL (operands[3]) != 0"
2669 [(set (match_dup 4)
2670 (lshiftrt:DI (match_dup 2) (match_dup 3)))
2671 (set (pc)
2672 (if_then_else (match_op_dup 1
2673 [(zero_extract:DI (match_dup 4)
2674 (const_int 1)
2675 (const_int 0))
2676 (const_int 0)])
2677 (label_ref (match_dup 0))
2678 (pc)))]
2679 )
2680
2682 ;; The following are the corresponding floating-point insns. Recall
2683 ;; we need to have variants that expand the arguments from SFmode
2684 ;; to DFmode.
2685
2686 (define_insn "*cmpdf_ieee"
2687 [(set (match_operand:DF 0 "register_operand" "=&f")
2688 (match_operator:DF 1 "alpha_fp_comparison_operator"
2689 [(match_operand:DF 2 "reg_or_0_operand" "fG")
2690 (match_operand:DF 3 "reg_or_0_operand" "fG")]))]
2691 "TARGET_FP && alpha_fptm >= ALPHA_FPTM_SU"
2692 "cmp%-%C1%/ %R2,%R3,%0"
2693 [(set_attr "type" "fadd")
2694 (set_attr "trap" "yes")
2695 (set_attr "trap_suffix" "su")])
2696
2697 (define_insn "*cmpdf_internal"
2698 [(set (match_operand:DF 0 "register_operand" "=f")
2699 (match_operator:DF 1 "alpha_fp_comparison_operator"
2700 [(match_operand:DF 2 "reg_or_0_operand" "fG")
2701 (match_operand:DF 3 "reg_or_0_operand" "fG")]))]
2702 "TARGET_FP"
2703 "cmp%-%C1%/ %R2,%R3,%0"
2704 [(set_attr "type" "fadd")
2705 (set_attr "trap" "yes")
2706 (set_attr "trap_suffix" "su")])
2707
2708 (define_insn "*cmpdf_ext1"
2709 [(set (match_operand:DF 0 "register_operand" "=f")
2710 (match_operator:DF 1 "alpha_fp_comparison_operator"
2711 [(float_extend:DF
2712 (match_operand:SF 2 "reg_or_0_operand" "fG"))
2713 (match_operand:DF 3 "reg_or_0_operand" "fG")]))]
2714 "TARGET_FP && alpha_fptm < ALPHA_FPTM_SU"
2715 "cmp%-%C1%/ %R2,%R3,%0"
2716 [(set_attr "type" "fadd")
2717 (set_attr "trap" "yes")
2718 (set_attr "trap_suffix" "su")])
2719
2720 (define_insn "*cmpdf_ext2"
2721 [(set (match_operand:DF 0 "register_operand" "=f")
2722 (match_operator:DF 1 "alpha_fp_comparison_operator"
2723 [(match_operand:DF 2 "reg_or_0_operand" "fG")
2724 (float_extend:DF
2725 (match_operand:SF 3 "reg_or_0_operand" "fG"))]))]
2726 "TARGET_FP && alpha_fptm < ALPHA_FPTM_SU"
2727 "cmp%-%C1%/ %R2,%R3,%0"
2728 [(set_attr "type" "fadd")
2729 (set_attr "trap" "yes")
2730 (set_attr "trap_suffix" "su")])
2731
2732 (define_insn "*cmpdf_ext3"
2733 [(set (match_operand:DF 0 "register_operand" "=f")
2734 (match_operator:DF 1 "alpha_fp_comparison_operator"
2735 [(float_extend:DF
2736 (match_operand:SF 2 "reg_or_0_operand" "fG"))
2737 (float_extend:DF
2738 (match_operand:SF 3 "reg_or_0_operand" "fG"))]))]
2739 "TARGET_FP && alpha_fptm < ALPHA_FPTM_SU"
2740 "cmp%-%C1%/ %R2,%R3,%0"
2741 [(set_attr "type" "fadd")
2742 (set_attr "trap" "yes")
2743 (set_attr "trap_suffix" "su")])
2744
2745 (define_insn "*mov<mode>cc_internal"
2746 [(set (match_operand:FMODE 0 "register_operand" "=f,f")
2747 (if_then_else:FMODE
2748 (match_operator 3 "signed_comparison_operator"
2749 [(match_operand:DF 4 "reg_or_0_operand" "fG,fG")
2750 (match_operand:DF 2 "const0_operand" "G,G")])
2751 (match_operand:FMODE 1 "reg_or_0_operand" "fG,0")
2752 (match_operand:FMODE 5 "reg_or_0_operand" "0,fG")))]
2753 "TARGET_FP"
2754 "@
2755 fcmov%C3 %R4,%R1,%0
2756 fcmov%D3 %R4,%R5,%0"
2757 [(set_attr "type" "fcmov")])
2758
2759 (define_insn "*movdfcc_ext1"
2760 [(set (match_operand:DF 0 "register_operand" "=f,f")
2761 (if_then_else:DF
2762 (match_operator 3 "signed_comparison_operator"
2763 [(match_operand:DF 4 "reg_or_0_operand" "fG,fG")
2764 (match_operand:DF 2 "const0_operand" "G,G")])
2765 (float_extend:DF (match_operand:SF 1 "reg_or_0_operand" "fG,0"))
2766 (match_operand:DF 5 "reg_or_0_operand" "0,fG")))]
2767 "TARGET_FP && alpha_fptm < ALPHA_FPTM_SU"
2768 "@
2769 fcmov%C3 %R4,%R1,%0
2770 fcmov%D3 %R4,%R5,%0"
2771 [(set_attr "type" "fcmov")])
2772
2773 (define_insn "*movdfcc_ext2"
2774 [(set (match_operand:DF 0 "register_operand" "=f,f")
2775 (if_then_else:DF
2776 (match_operator 3 "signed_comparison_operator"
2777 [(float_extend:DF
2778 (match_operand:SF 4 "reg_or_0_operand" "fG,fG"))
2779 (match_operand:DF 2 "const0_operand" "G,G")])
2780 (match_operand:DF 1 "reg_or_0_operand" "fG,0")
2781 (match_operand:DF 5 "reg_or_0_operand" "0,fG")))]
2782 "TARGET_FP && alpha_fptm < ALPHA_FPTM_SU"
2783 "@
2784 fcmov%C3 %R4,%R1,%0
2785 fcmov%D3 %R4,%R5,%0"
2786 [(set_attr "type" "fcmov")])
2787
2788 (define_insn "*movdfcc_ext3"
2789 [(set (match_operand:SF 0 "register_operand" "=f,f")
2790 (if_then_else:SF
2791 (match_operator 3 "signed_comparison_operator"
2792 [(float_extend:DF
2793 (match_operand:SF 4 "reg_or_0_operand" "fG,fG"))
2794 (match_operand:DF 2 "const0_operand" "G,G")])
2795 (match_operand:SF 1 "reg_or_0_operand" "fG,0")
2796 (match_operand:SF 5 "reg_or_0_operand" "0,fG")))]
2797 "TARGET_FP && alpha_fptm < ALPHA_FPTM_SU"
2798 "@
2799 fcmov%C3 %R4,%R1,%0
2800 fcmov%D3 %R4,%R5,%0"
2801 [(set_attr "type" "fcmov")])
2802
2803 (define_insn "*movdfcc_ext4"
2804 [(set (match_operand:DF 0 "register_operand" "=f,f")
2805 (if_then_else:DF
2806 (match_operator 3 "signed_comparison_operator"
2807 [(float_extend:DF
2808 (match_operand:SF 4 "reg_or_0_operand" "fG,fG"))
2809 (match_operand:DF 2 "const0_operand" "G,G")])
2810 (float_extend:DF (match_operand:SF 1 "reg_or_0_operand" "fG,0"))
2811 (match_operand:DF 5 "reg_or_0_operand" "0,fG")))]
2812 "TARGET_FP && alpha_fptm < ALPHA_FPTM_SU"
2813 "@
2814 fcmov%C3 %R4,%R1,%0
2815 fcmov%D3 %R4,%R5,%0"
2816 [(set_attr "type" "fcmov")])
2817
2818 (define_expand "smaxdf3"
2819 [(set (match_dup 3)
2820 (le:DF (match_operand:DF 1 "reg_or_0_operand")
2821 (match_operand:DF 2 "reg_or_0_operand")))
2822 (set (match_operand:DF 0 "register_operand")
2823 (if_then_else:DF (eq (match_dup 3) (match_dup 4))
2824 (match_dup 1) (match_dup 2)))]
2825 "TARGET_FP"
2826 {
2827 operands[3] = gen_reg_rtx (DFmode);
2828 operands[4] = CONST0_RTX (DFmode);
2829 })
2830
2831 (define_expand "smindf3"
2832 [(set (match_dup 3)
2833 (lt:DF (match_operand:DF 1 "reg_or_0_operand")
2834 (match_operand:DF 2 "reg_or_0_operand")))
2835 (set (match_operand:DF 0 "register_operand")
2836 (if_then_else:DF (ne (match_dup 3) (match_dup 4))
2837 (match_dup 1) (match_dup 2)))]
2838 "TARGET_FP"
2839 {
2840 operands[3] = gen_reg_rtx (DFmode);
2841 operands[4] = CONST0_RTX (DFmode);
2842 })
2843
2844 (define_expand "smaxsf3"
2845 [(set (match_dup 3)
2846 (le:DF (float_extend:DF (match_operand:SF 1 "reg_or_0_operand"))
2847 (float_extend:DF (match_operand:SF 2 "reg_or_0_operand"))))
2848 (set (match_operand:SF 0 "register_operand")
2849 (if_then_else:SF (eq (match_dup 3) (match_dup 4))
2850 (match_dup 1) (match_dup 2)))]
2851 "TARGET_FP && alpha_fptm < ALPHA_FPTM_SU"
2852 {
2853 operands[3] = gen_reg_rtx (DFmode);
2854 operands[4] = CONST0_RTX (DFmode);
2855 })
2856
2857 (define_expand "sminsf3"
2858 [(set (match_dup 3)
2859 (lt:DF (float_extend:DF (match_operand:SF 1 "reg_or_0_operand"))
2860 (float_extend:DF (match_operand:SF 2 "reg_or_0_operand"))))
2861 (set (match_operand:SF 0 "register_operand")
2862 (if_then_else:SF (ne (match_dup 3) (match_dup 4))
2863 (match_dup 1) (match_dup 2)))]
2864 "TARGET_FP && alpha_fptm < ALPHA_FPTM_SU"
2865 {
2866 operands[3] = gen_reg_rtx (DFmode);
2867 operands[4] = CONST0_RTX (DFmode);
2868 })
2869
2870 (define_insn "*fbcc_normal"
2871 [(set (pc)
2872 (if_then_else
2873 (match_operator 1 "signed_comparison_operator"
2874 [(match_operand:DF 2 "reg_or_0_operand" "fG")
2875 (match_operand:DF 3 "const0_operand" "G")])
2876 (label_ref (match_operand 0))
2877 (pc)))]
2878 "TARGET_FP"
2879 "fb%C1 %R2,%0"
2880 [(set_attr "type" "fbr")])
2881
2882 (define_insn "*fbcc_ext_normal"
2883 [(set (pc)
2884 (if_then_else
2885 (match_operator 1 "signed_comparison_operator"
2886 [(float_extend:DF
2887 (match_operand:SF 2 "reg_or_0_operand" "fG"))
2888 (match_operand:DF 3 "const0_operand" "G")])
2889 (label_ref (match_operand 0))
2890 (pc)))]
2891 "TARGET_FP"
2892 "fb%C1 %R2,%0"
2893 [(set_attr "type" "fbr")])
2894
2896 ;; These are the main define_expand's used to make conditional branches
2897 ;; and compares.
2898
2899 (define_expand "cbranchdf4"
2900 [(use (match_operator 0 "alpha_cbranch_operator"
2901 [(match_operand:DF 1 "reg_or_0_operand")
2902 (match_operand:DF 2 "reg_or_0_operand")]))
2903 (use (match_operand 3))]
2904 "TARGET_FP"
2905 "alpha_emit_conditional_branch (operands, DFmode); DONE;")
2906
2907 (define_expand "cbranchtf4"
2908 [(use (match_operator 0 "alpha_cbranch_operator"
2909 [(match_operand:TF 1 "general_operand")
2910 (match_operand:TF 2 "general_operand")]))
2911 (use (match_operand 3))]
2912 "TARGET_HAS_XFLOATING_LIBS"
2913 "alpha_emit_conditional_branch (operands, TFmode); DONE;")
2914
2915 (define_expand "cbranchdi4"
2916 [(use (match_operator 0 "alpha_cbranch_operator"
2917 [(match_operand:DI 1 "general_operand")
2918 (match_operand:DI 2 "general_operand")]))
2919 (use (match_operand 3))]
2920 ""
2921 "alpha_emit_conditional_branch (operands, DImode); DONE;")
2922
2923 (define_expand "cstoredf4"
2924 [(use (match_operator:DI 1 "alpha_cbranch_operator"
2925 [(match_operand:DF 2 "reg_or_0_operand")
2926 (match_operand:DF 3 "reg_or_0_operand")]))
2927 (clobber (match_operand:DI 0 "register_operand"))]
2928 "TARGET_FP"
2929 {
2930 if (alpha_emit_setcc (operands, DFmode))
2931 DONE;
2932 else
2933 FAIL;
2934 })
2935
2936 (define_expand "cstoretf4"
2937 [(use (match_operator:DI 1 "alpha_cbranch_operator"
2938 [(match_operand:TF 2 "general_operand")
2939 (match_operand:TF 3 "general_operand")]))
2940 (clobber (match_operand:DI 0 "register_operand"))]
2941 "TARGET_HAS_XFLOATING_LIBS"
2942 {
2943 if (alpha_emit_setcc (operands, TFmode))
2944 DONE;
2945 else
2946 FAIL;
2947 })
2948
2949 (define_expand "cstoredi4"
2950 [(use (match_operator:DI 1 "alpha_cbranch_operator"
2951 [(match_operand:DI 2 "general_operand")
2952 (match_operand:DI 3 "general_operand")]))
2953 (clobber (match_operand:DI 0 "register_operand"))]
2954 ""
2955 {
2956 if (alpha_emit_setcc (operands, DImode))
2957 DONE;
2958 else
2959 FAIL;
2960 })
2961
2963 ;; These are the main define_expand's used to make conditional moves.
2964
2965 (define_expand "mov<mode>cc"
2966 [(set (match_operand:I48MODE 0 "register_operand")
2967 (if_then_else:I48MODE
2968 (match_operand 1 "comparison_operator")
2969 (match_operand:I48MODE 2 "reg_or_8bit_operand")
2970 (match_operand:I48MODE 3 "reg_or_8bit_operand")))]
2971 ""
2972 {
2973 operands[1] = alpha_emit_conditional_move (operands[1], <MODE>mode);
2974 if (operands[1] == 0)
2975 FAIL;
2976 })
2977
2978 (define_expand "mov<mode>cc"
2979 [(set (match_operand:FMODE 0 "register_operand")
2980 (if_then_else:FMODE
2981 (match_operand 1 "comparison_operator")
2982 (match_operand:FMODE 2 "reg_or_8bit_operand")
2983 (match_operand:FMODE 3 "reg_or_8bit_operand")))]
2984 ""
2985 {
2986 operands[1] = alpha_emit_conditional_move (operands[1], <MODE>mode);
2987 if (operands[1] == 0)
2988 FAIL;
2989 })
2990
2992 ;; These define_split definitions are used in cases when comparisons have
2993 ;; not be stated in the correct way and we need to reverse the second
2994 ;; comparison. For example, x >= 7 has to be done as x < 6 with the
2995 ;; comparison that tests the result being reversed. We have one define_split
2996 ;; for each use of a comparison. They do not match valid insns and need
2997 ;; not generate valid insns.
2998 ;;
2999 ;; We can also handle equality comparisons (and inequality comparisons in
3000 ;; cases where the resulting add cannot overflow) by doing an add followed by
3001 ;; a comparison with zero. This is faster since the addition takes one
3002 ;; less cycle than a compare when feeding into a conditional move.
3003 ;; For this case, we also have an SImode pattern since we can merge the add
3004 ;; and sign extend and the order doesn't matter.
3005 ;;
3006 ;; We do not do this for floating-point, since it isn't clear how the "wrong"
3007 ;; operation could have been generated.
3008
3009 (define_split
3010 [(set (match_operand:DI 0 "register_operand")
3011 (if_then_else:DI
3012 (match_operator 1 "comparison_operator"
3013 [(match_operand:DI 2 "reg_or_0_operand")
3014 (match_operand:DI 3 "reg_or_cint_operand")])
3015 (match_operand:DI 4 "reg_or_cint_operand")
3016 (match_operand:DI 5 "reg_or_cint_operand")))
3017 (clobber (match_operand:DI 6 "register_operand"))]
3018 "operands[3] != const0_rtx"
3019 [(set (match_dup 6) (match_dup 7))
3020 (set (match_dup 0)
3021 (if_then_else:DI (match_dup 8) (match_dup 4) (match_dup 5)))]
3022 {
3023 enum rtx_code code = GET_CODE (operands[1]);
3024 int unsignedp = (code == GEU || code == LEU || code == GTU || code == LTU);
3025
3026 /* If we are comparing for equality with a constant and that constant
3027 appears in the arm when the register equals the constant, use the
3028 register since that is more likely to match (and to produce better code
3029 if both would). */
3030
3031 if (code == EQ && CONST_INT_P (operands[3])
3032 && rtx_equal_p (operands[4], operands[3]))
3033 operands[4] = operands[2];
3034
3035 else if (code == NE && CONST_INT_P (operands[3])
3036 && rtx_equal_p (operands[5], operands[3]))
3037 operands[5] = operands[2];
3038
3039 if (code == NE || code == EQ
3040 || (extended_count (operands[2], DImode, unsignedp) >= 1
3041 && extended_count (operands[3], DImode, unsignedp) >= 1))
3042 {
3043 if (CONST_INT_P (operands[3]))
3044 operands[7] = gen_rtx_PLUS (DImode, operands[2],
3045 GEN_INT (- INTVAL (operands[3])));
3046 else
3047 operands[7] = gen_rtx_MINUS (DImode, operands[2], operands[3]);
3048
3049 operands[8] = gen_rtx_fmt_ee (code, VOIDmode, operands[6], const0_rtx);
3050 }
3051
3052 else if (code == EQ || code == LE || code == LT
3053 || code == LEU || code == LTU)
3054 {
3055 operands[7] = gen_rtx_fmt_ee (code, DImode, operands[2], operands[3]);
3056 operands[8] = gen_rtx_NE (VOIDmode, operands[6], const0_rtx);
3057 }
3058 else
3059 {
3060 operands[7] = gen_rtx_fmt_ee (reverse_condition (code), DImode,
3061 operands[2], operands[3]);
3062 operands[8] = gen_rtx_EQ (VOIDmode, operands[6], const0_rtx);
3063 }
3064 })
3065
3066 (define_split
3067 [(set (match_operand:DI 0 "register_operand")
3068 (if_then_else:DI
3069 (match_operator 1 "comparison_operator"
3070 [(match_operand:SI 2 "reg_or_0_operand")
3071 (match_operand:SI 3 "reg_or_cint_operand")])
3072 (match_operand:DI 4 "reg_or_8bit_operand")
3073 (match_operand:DI 5 "reg_or_8bit_operand")))
3074 (clobber (match_operand:DI 6 "register_operand"))]
3075 "operands[3] != const0_rtx
3076 && (GET_CODE (operands[1]) == EQ || GET_CODE (operands[1]) == NE)"
3077 [(set (match_dup 6) (match_dup 7))
3078 (set (match_dup 0)
3079 (if_then_else:DI (match_dup 8) (match_dup 4) (match_dup 5)))]
3080 {
3081 enum rtx_code code = GET_CODE (operands[1]);
3082 int unsignedp = (code == GEU || code == LEU || code == GTU || code == LTU);
3083 rtx tem;
3084
3085 if ((code != NE && code != EQ
3086 && ! (extended_count (operands[2], DImode, unsignedp) >= 1
3087 && extended_count (operands[3], DImode, unsignedp) >= 1)))
3088 FAIL;
3089
3090 if (CONST_INT_P (operands[3]))
3091 tem = gen_rtx_PLUS (SImode, operands[2],
3092 GEN_INT (- INTVAL (operands[3])));
3093 else
3094 tem = gen_rtx_MINUS (SImode, operands[2], operands[3]);
3095
3096 operands[7] = gen_rtx_SIGN_EXTEND (DImode, tem);
3097 operands[8] = gen_rtx_fmt_ee (GET_CODE (operands[1]), VOIDmode,
3098 operands[6], const0_rtx);
3099 })
3100
3101 ;; Prefer to use cmp and arithmetic when possible instead of a cmove.
3102
3103 (define_split
3104 [(set (match_operand 0 "register_operand")
3105 (if_then_else (match_operator 1 "signed_comparison_operator"
3106 [(match_operand:DI 2 "reg_or_0_operand")
3107 (const_int 0)])
3108 (match_operand 3 "const_int_operand")
3109 (match_operand 4 "const_int_operand")))]
3110 ""
3111 [(const_int 0)]
3112 {
3113 if (alpha_split_conditional_move (GET_CODE (operands[1]), operands[0],
3114 operands[2], operands[3], operands[4]))
3115 DONE;
3116 else
3117 FAIL;
3118 })
3119
3120 ;; ??? Why combine is allowed to create such non-canonical rtl, I don't know.
3121 ;; Oh well, we match it in movcc, so it must be partially our fault.
3122 (define_split
3123 [(set (match_operand 0 "register_operand")
3124 (if_then_else (match_operator 1 "signed_comparison_operator"
3125 [(const_int 0)
3126 (match_operand:DI 2 "reg_or_0_operand")])
3127 (match_operand 3 "const_int_operand")
3128 (match_operand 4 "const_int_operand")))]
3129 ""
3130 [(const_int 0)]
3131 {
3132 if (alpha_split_conditional_move (swap_condition (GET_CODE (operands[1])),
3133 operands[0], operands[2], operands[3],
3134 operands[4]))
3135 DONE;
3136 else
3137 FAIL;
3138 })
3139
3140 (define_insn_and_split "*cmp_sadd_di"
3141 [(set (match_operand:DI 0 "register_operand" "=r")
3142 (plus:DI (if_then_else:DI
3143 (match_operator 1 "alpha_zero_comparison_operator"
3144 [(match_operand:DI 2 "reg_or_0_operand" "rJ")
3145 (const_int 0)])
3146 (match_operand:DI 3 "const48_operand" "I")
3147 (const_int 0))
3148 (match_operand:DI 4 "sext_add_operand" "rIO")))
3149 (clobber (match_scratch:DI 5 "=r"))]
3150 ""
3151 "#"
3152 ""
3153 [(set (match_dup 5)
3154 (match_op_dup:DI 1 [(match_dup 2) (const_int 0)]))
3155 (set (match_dup 0)
3156 (plus:DI (mult:DI (match_dup 5) (match_dup 3))
3157 (match_dup 4)))]
3158 {
3159 if (can_create_pseudo_p ())
3160 operands[5] = gen_reg_rtx (DImode);
3161 else if (reg_overlap_mentioned_p (operands[5], operands[4]))
3162 operands[5] = operands[0];
3163 })
3164
3165 (define_insn_and_split "*cmp_sadd_si"
3166 [(set (match_operand:SI 0 "register_operand" "=r")
3167 (plus:SI (if_then_else:SI
3168 (match_operator 1 "alpha_zero_comparison_operator"
3169 [(match_operand:DI 2 "reg_or_0_operand" "rJ")
3170 (const_int 0)])
3171 (match_operand:SI 3 "const48_operand" "I")
3172 (const_int 0))
3173 (match_operand:SI 4 "sext_add_operand" "rIO")))
3174 (clobber (match_scratch:DI 5 "=r"))]
3175 ""
3176 "#"
3177 ""
3178 [(set (match_dup 5)
3179 (match_op_dup:DI 1 [(match_dup 2) (const_int 0)]))
3180 (set (match_dup 0)
3181 (plus:SI (mult:SI (match_dup 6) (match_dup 3))
3182 (match_dup 4)))]
3183 {
3184 if (can_create_pseudo_p ())
3185 operands[5] = gen_reg_rtx (DImode);
3186 else if (reg_overlap_mentioned_p (operands[5], operands[4]))
3187 operands[5] = gen_lowpart (DImode, operands[0]);
3188
3189 operands[6] = gen_lowpart (SImode, operands[5]);
3190 })
3191
3192 (define_insn_and_split "*cmp_sadd_sidi"
3193 [(set (match_operand:DI 0 "register_operand" "=r")
3194 (sign_extend:DI
3195 (plus:SI (if_then_else:SI
3196 (match_operator 1 "alpha_zero_comparison_operator"
3197 [(match_operand:DI 2 "reg_or_0_operand" "rJ")
3198 (const_int 0)])
3199 (match_operand:SI 3 "const48_operand" "I")
3200 (const_int 0))
3201 (match_operand:SI 4 "sext_add_operand" "rIO"))))
3202 (clobber (match_scratch:DI 5 "=r"))]
3203 ""
3204 "#"
3205 ""
3206 [(set (match_dup 5)
3207 (match_op_dup:DI 1 [(match_dup 2) (const_int 0)]))
3208 (set (match_dup 0)
3209 (sign_extend:DI (plus:SI (mult:SI (match_dup 6) (match_dup 3))
3210 (match_dup 4))))]
3211 {
3212 if (can_create_pseudo_p ())
3213 operands[5] = gen_reg_rtx (DImode);
3214 else if (reg_overlap_mentioned_p (operands[5], operands[4]))
3215 operands[5] = operands[0];
3216
3217 operands[6] = gen_lowpart (SImode, operands[5]);
3218 })
3219
3220 (define_insn_and_split "*cmp_ssub_di"
3221 [(set (match_operand:DI 0 "register_operand" "=r")
3222 (minus:DI (if_then_else:DI
3223 (match_operator 1 "alpha_zero_comparison_operator"
3224 [(match_operand:DI 2 "reg_or_0_operand" "rJ")
3225 (const_int 0)])
3226 (match_operand:DI 3 "const48_operand" "I")
3227 (const_int 0))
3228 (match_operand:DI 4 "reg_or_8bit_operand" "rI")))
3229 (clobber (match_scratch:DI 5 "=r"))]
3230 ""
3231 "#"
3232 ""
3233 [(set (match_dup 5)
3234 (match_op_dup:DI 1 [(match_dup 2) (const_int 0)]))
3235 (set (match_dup 0)
3236 (minus:DI (mult:DI (match_dup 5) (match_dup 3))
3237 (match_dup 4)))]
3238 {
3239 if (can_create_pseudo_p ())
3240 operands[5] = gen_reg_rtx (DImode);
3241 else if (reg_overlap_mentioned_p (operands[5], operands[4]))
3242 operands[5] = operands[0];
3243 })
3244
3245 (define_insn_and_split "*cmp_ssub_si"
3246 [(set (match_operand:SI 0 "register_operand" "=r")
3247 (minus:SI (if_then_else:SI
3248 (match_operator 1 "alpha_zero_comparison_operator"
3249 [(match_operand:DI 2 "reg_or_0_operand" "rJ")
3250 (const_int 0)])
3251 (match_operand:SI 3 "const48_operand" "I")
3252 (const_int 0))
3253 (match_operand:SI 4 "reg_or_8bit_operand" "rI")))
3254 (clobber (match_scratch:DI 5 "=r"))]
3255 ""
3256 "#"
3257 ""
3258 [(set (match_dup 5)
3259 (match_op_dup:DI 1 [(match_dup 2) (const_int 0)]))
3260 (set (match_dup 0)
3261 (minus:SI (mult:SI (match_dup 6) (match_dup 3))
3262 (match_dup 4)))]
3263 {
3264 if (can_create_pseudo_p ())
3265 operands[5] = gen_reg_rtx (DImode);
3266 else if (reg_overlap_mentioned_p (operands[5], operands[4]))
3267 operands[5] = gen_lowpart (DImode, operands[0]);
3268
3269 operands[6] = gen_lowpart (SImode, operands[5]);
3270 })
3271
3272 (define_insn_and_split "*cmp_ssub_sidi"
3273 [(set (match_operand:DI 0 "register_operand" "=r")
3274 (sign_extend:DI
3275 (minus:SI (if_then_else:SI
3276 (match_operator 1 "alpha_zero_comparison_operator"
3277 [(match_operand:DI 2 "reg_or_0_operand" "rJ")
3278 (const_int 0)])
3279 (match_operand:SI 3 "const48_operand" "I")
3280 (const_int 0))
3281 (match_operand:SI 4 "reg_or_8bit_operand" "rI"))))
3282 (clobber (match_scratch:DI 5 "=r"))]
3283 ""
3284 "#"
3285 ""
3286 [(set (match_dup 5)
3287 (match_op_dup:DI 1 [(match_dup 2) (const_int 0)]))
3288 (set (match_dup 0)
3289 (sign_extend:DI (minus:SI (mult:SI (match_dup 6) (match_dup 3))
3290 (match_dup 4))))]
3291 {
3292 if (can_create_pseudo_p ())
3293 operands[5] = gen_reg_rtx (DImode);
3294 else if (reg_overlap_mentioned_p (operands[5], operands[4]))
3295 operands[5] = operands[0];
3296
3297 operands[6] = gen_lowpart (SImode, operands[5]);
3298 })
3299
3301 ;; Here are the CALL and unconditional branch insns. Calls on NT and OSF
3302 ;; work differently, so we have different patterns for each.
3303
3304 (define_expand "call"
3305 [(use (match_operand:DI 0))
3306 (use (match_operand 1))
3307 (use (match_operand 2))
3308 (use (match_operand 3))]
3309 ""
3310 {
3311 if (TARGET_ABI_OPEN_VMS)
3312 emit_call_insn (gen_call_vms (operands[0], operands[2]));
3313 else
3314 emit_call_insn (gen_call_osf (operands[0], operands[1]));
3315 DONE;
3316 })
3317
3318 (define_expand "sibcall"
3319 [(parallel [(call (mem:DI (match_operand 0))
3320 (match_operand 1))
3321 (unspec [(reg:DI 29)] UNSPEC_SIBCALL)])]
3322 "TARGET_ABI_OSF"
3323 {
3324 gcc_assert (MEM_P (operands[0]));
3325 operands[0] = XEXP (operands[0], 0);
3326 })
3327
3328 (define_expand "call_osf"
3329 [(parallel [(call (mem:DI (match_operand 0))
3330 (match_operand 1))
3331 (use (reg:DI 29))
3332 (clobber (reg:DI 26))])]
3333 ""
3334 {
3335 gcc_assert (MEM_P (operands[0]));
3336
3337 operands[0] = XEXP (operands[0], 0);
3338 if (! call_operand (operands[0], Pmode))
3339 operands[0] = copy_to_mode_reg (Pmode, operands[0]);
3340 })
3341
3342 ;;
3343 ;; call openvms/alpha
3344 ;; op 0: symbol ref for called function
3345 ;; op 1: next_arg_reg (argument information value for R25)
3346 ;;
3347 (define_expand "call_vms"
3348 [(parallel [(call (mem:DI (match_operand 0))
3349 (match_operand 1))
3350 (use (match_dup 2))
3351 (use (reg:DI 25))
3352 (use (reg:DI 26))
3353 (clobber (reg:DI 27))])]
3354 ""
3355 {
3356 gcc_assert (MEM_P (operands[0]));
3357
3358 operands[0] = XEXP (operands[0], 0);
3359
3360 /* Always load AI with argument information, then handle symbolic and
3361 indirect call differently. Load RA and set operands[2] to PV in
3362 both cases. */
3363
3364 emit_move_insn (gen_rtx_REG (DImode, 25), operands[1]);
3365 if (GET_CODE (operands[0]) == SYMBOL_REF)
3366 {
3367 operands[2] = const0_rtx;
3368 }
3369 else
3370 {
3371 emit_move_insn (gen_rtx_REG (Pmode, 26),
3372 gen_rtx_MEM (Pmode, plus_constant (Pmode,
3373 operands[0], 8)));
3374 operands[2] = operands[0];
3375 }
3376 })
3377
3378 (define_expand "call_value"
3379 [(use (match_operand 0))
3380 (use (match_operand:DI 1))
3381 (use (match_operand 2))
3382 (use (match_operand 3))
3383 (use (match_operand 4))]
3384 ""
3385 {
3386 if (TARGET_ABI_OPEN_VMS)
3387 emit_call_insn (gen_call_value_vms (operands[0], operands[1],
3388 operands[3]));
3389 else
3390 emit_call_insn (gen_call_value_osf (operands[0], operands[1],
3391 operands[2]));
3392 DONE;
3393 })
3394
3395 (define_expand "sibcall_value"
3396 [(parallel [(set (match_operand 0)
3397 (call (mem:DI (match_operand 1))
3398 (match_operand 2)))
3399 (unspec [(reg:DI 29)] UNSPEC_SIBCALL)])]
3400 "TARGET_ABI_OSF"
3401 {
3402 gcc_assert (MEM_P (operands[1]));
3403 operands[1] = XEXP (operands[1], 0);
3404 })
3405
3406 (define_expand "call_value_osf"
3407 [(parallel [(set (match_operand 0)
3408 (call (mem:DI (match_operand 1))
3409 (match_operand 2)))
3410 (use (reg:DI 29))
3411 (clobber (reg:DI 26))])]
3412 ""
3413 {
3414 gcc_assert (MEM_P (operands[1]));
3415
3416 operands[1] = XEXP (operands[1], 0);
3417 if (! call_operand (operands[1], Pmode))
3418 operands[1] = copy_to_mode_reg (Pmode, operands[1]);
3419 })
3420
3421 (define_expand "call_value_vms"
3422 [(parallel [(set (match_operand 0)
3423 (call (mem:DI (match_operand:DI 1))
3424 (match_operand 2)))
3425 (use (match_dup 3))
3426 (use (reg:DI 25))
3427 (use (reg:DI 26))
3428 (clobber (reg:DI 27))])]
3429 ""
3430 {
3431 gcc_assert (MEM_P (operands[1]));
3432
3433 operands[1] = XEXP (operands[1], 0);
3434
3435 /* Always load AI with argument information, then handle symbolic and
3436 indirect call differently. Load RA and set operands[3] to PV in
3437 both cases. */
3438
3439 emit_move_insn (gen_rtx_REG (DImode, 25), operands[2]);
3440 if (GET_CODE (operands[1]) == SYMBOL_REF)
3441 {
3442 operands[3] = const0_rtx;
3443 }
3444 else
3445 {
3446 emit_move_insn (gen_rtx_REG (Pmode, 26),
3447 gen_rtx_MEM (Pmode, plus_constant (Pmode,
3448 operands[1], 8)));
3449 operands[3] = operands[1];
3450 }
3451 })
3452
3453 (define_insn "*call_osf_1_er_noreturn"
3454 [(call (mem:DI (match_operand:DI 0 "call_operand" "c,R,s"))
3455 (match_operand 1))
3456 (use (reg:DI 29))
3457 (clobber (reg:DI 26))]
3458 "TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF
3459 && find_reg_note (insn, REG_NORETURN, NULL_RTX)"
3460 "@
3461 jsr $26,($27),0
3462 bsr $26,%0\t\t!samegp
3463 ldq $27,%0($29)\t\t!literal!%#\;jsr $26,($27),%0\t\t!lituse_jsr!%#"
3464 [(set_attr "type" "jsr")
3465 (set_attr "length" "*,*,8")])
3466
3467 (define_insn "*call_osf_1_er"
3468 [(call (mem:DI (match_operand:DI 0 "call_operand" "c,R,s"))
3469 (match_operand 1))
3470 (use (reg:DI 29))
3471 (clobber (reg:DI 26))]
3472 "TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF"
3473 "@
3474 jsr $26,(%0),0\;ldah $29,0($26)\t\t!gpdisp!%*\;lda $29,0($29)\t\t!gpdisp!%*
3475 bsr $26,%0\t\t!samegp
3476 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!%*"
3477 [(set_attr "type" "jsr")
3478 (set_attr "length" "12,*,16")])
3479
3480 ;; We must use peep2 instead of a split because we need accurate life
3481 ;; information for $gp. Consider the case of { bar(); while (1); }.
3482 (define_peephole2
3483 [(parallel [(call (mem:DI (match_operand:DI 0 "call_operand"))
3484 (match_operand 1))
3485 (use (reg:DI 29))
3486 (clobber (reg:DI 26))])]
3487 "TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF && reload_completed
3488 && ! samegp_function_operand (operands[0], Pmode)
3489 && (peep2_regno_dead_p (1, 29)
3490 || find_reg_note (insn, REG_NORETURN, NULL_RTX))"
3491 [(parallel [(call (mem:DI (match_dup 2))
3492 (match_dup 1))
3493 (use (reg:DI 29))
3494 (use (match_dup 0))
3495 (use (match_dup 3))
3496 (clobber (reg:DI 26))])]
3497 {
3498 if (CONSTANT_P (operands[0]))
3499 {
3500 operands[2] = gen_rtx_REG (Pmode, 27);
3501 operands[3] = GEN_INT (alpha_next_sequence_number++);
3502 emit_insn (gen_movdi_er_high_g (operands[2], pic_offset_table_rtx,
3503 operands[0], operands[3]));
3504 }
3505 else
3506 {
3507 operands[2] = operands[0];
3508 operands[0] = const0_rtx;
3509 operands[3] = const0_rtx;
3510 }
3511 })
3512
3513 (define_peephole2
3514 [(parallel [(call (mem:DI (match_operand:DI 0 "call_operand"))
3515 (match_operand 1))
3516 (use (reg:DI 29))
3517 (clobber (reg:DI 26))])]
3518 "TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF && reload_completed
3519 && ! samegp_function_operand (operands[0], Pmode)
3520 && ! (peep2_regno_dead_p (1, 29)
3521 || find_reg_note (insn, REG_NORETURN, NULL_RTX))"
3522 [(parallel [(call (mem:DI (match_dup 2))
3523 (match_dup 1))
3524 (set (match_dup 5)
3525 (unspec:DI [(match_dup 5) (match_dup 3)] UNSPEC_LDGP1))
3526 (use (match_dup 0))
3527 (use (match_dup 4))
3528 (clobber (reg:DI 26))])
3529 (set (match_dup 5)
3530 (unspec:DI [(match_dup 5) (match_dup 3)] UNSPEC_LDGP2))]
3531 {
3532 if (CONSTANT_P (operands[0]))
3533 {
3534 operands[2] = gen_rtx_REG (Pmode, 27);
3535 operands[4] = GEN_INT (alpha_next_sequence_number++);
3536 emit_insn (gen_movdi_er_high_g (operands[2], pic_offset_table_rtx,
3537 operands[0], operands[4]));
3538 }
3539 else
3540 {
3541 operands[2] = operands[0];
3542 operands[0] = const0_rtx;
3543 operands[4] = const0_rtx;
3544 }
3545 operands[3] = GEN_INT (alpha_next_sequence_number++);
3546 operands[5] = pic_offset_table_rtx;
3547 })
3548
3549 (define_insn "*call_osf_2_er_nogp"
3550 [(call (mem:DI (match_operand:DI 0 "register_operand" "c"))
3551 (match_operand 1))
3552 (use (reg:DI 29))
3553 (use (match_operand 2))
3554 (use (match_operand 3 "const_int_operand"))
3555 (clobber (reg:DI 26))]
3556 "TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF"
3557 "jsr $26,(%0),%2%J3"
3558 [(set_attr "type" "jsr")])
3559
3560 (define_insn "*call_osf_2_er"
3561 [(call (mem:DI (match_operand:DI 0 "register_operand" "c"))
3562 (match_operand 1))
3563 (set (reg:DI 29)
3564 (unspec:DI [(reg:DI 29) (match_operand 4 "const_int_operand")]
3565 UNSPEC_LDGP1))
3566 (use (match_operand 2))
3567 (use (match_operand 3 "const_int_operand"))
3568 (clobber (reg:DI 26))]
3569 "TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF"
3570 "jsr $26,(%0),%2%J3\;ldah $29,0($26)\t\t!gpdisp!%4"
3571 [(set_attr "type" "jsr")
3572 (set_attr "cannot_copy" "true")
3573 (set_attr "length" "8")])
3574
3575 (define_insn "*call_osf_1_noreturn"
3576 [(call (mem:DI (match_operand:DI 0 "call_operand" "c,R,s"))
3577 (match_operand 1))
3578 (use (reg:DI 29))
3579 (clobber (reg:DI 26))]
3580 "! TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF
3581 && find_reg_note (insn, REG_NORETURN, NULL_RTX)"
3582 "@
3583 jsr $26,($27),0
3584 bsr $26,$%0..ng
3585 jsr $26,%0"
3586 [(set_attr "type" "jsr")
3587 (set_attr "length" "*,*,8")])
3588
3589 (define_insn "*call_osf_1"
3590 [(call (mem:DI (match_operand:DI 0 "call_operand" "c,R,s"))
3591 (match_operand 1))
3592 (use (reg:DI 29))
3593 (clobber (reg:DI 26))]
3594 "! TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF"
3595 "@
3596 jsr $26,($27),0\;ldgp $29,0($26)
3597 bsr $26,$%0..ng
3598 jsr $26,%0\;ldgp $29,0($26)"
3599 [(set_attr "type" "jsr")
3600 (set_attr "length" "12,*,16")])
3601
3602 (define_insn "*sibcall_osf_1_er"
3603 [(call (mem:DI (match_operand:DI 0 "symbolic_operand" "R,s"))
3604 (match_operand 1))
3605 (unspec [(reg:DI 29)] UNSPEC_SIBCALL)]
3606 "TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF"
3607 "@
3608 br $31,%0\t\t!samegp
3609 ldq $27,%0($29)\t\t!literal!%#\;jmp $31,($27),%0\t\t!lituse_jsr!%#"
3610 [(set_attr "type" "jsr")
3611 (set_attr "length" "*,8")])
3612
3613 ;; Note that the DEC assembler expands "jmp foo" with $at, which
3614 ;; doesn't do what we want.
3615 (define_insn "*sibcall_osf_1"
3616 [(call (mem:DI (match_operand:DI 0 "symbolic_operand" "R,s"))
3617 (match_operand 1))
3618 (unspec [(reg:DI 29)] UNSPEC_SIBCALL)]
3619 "! TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF"
3620 "@
3621 br $31,$%0..ng
3622 lda $27,%0\;jmp $31,($27),%0"
3623 [(set_attr "type" "jsr")
3624 (set_attr "length" "*,8")])
3625
3626 ; GAS relies on the order and position of instructions output below in order
3627 ; to generate relocs for VMS link to potentially optimize the call.
3628 ; Please do not molest.
3629 (define_insn "*call_vms_1"
3630 [(call (mem:DI (match_operand:DI 0 "call_operand" "r,s"))
3631 (match_operand 1))
3632 (use (match_operand:DI 2 "nonmemory_operand" "r,n"))
3633 (use (reg:DI 25))
3634 (use (reg:DI 26))
3635 (clobber (reg:DI 27))]
3636 "TARGET_ABI_OPEN_VMS"
3637 {
3638 switch (which_alternative)
3639 {
3640 case 0:
3641 return "mov %2,$27\;jsr $26,0\;ldq $27,0($29)";
3642 case 1:
3643 operands [2] = alpha_use_linkage (operands [0], true, false);
3644 operands [3] = alpha_use_linkage (operands [0], false, false);
3645 return "ldq $26,%3\;ldq $27,%2\;jsr $26,%0\;ldq $27,0($29)";
3646 default:
3647 gcc_unreachable ();
3648 }
3649 }
3650 [(set_attr "type" "jsr")
3651 (set_attr "length" "12,16")])
3652
3653 ;; Call subroutine returning any type.
3654
3655 (define_expand "untyped_call"
3656 [(parallel [(call (match_operand 0)
3657 (const_int 0))
3658 (match_operand 1)
3659 (match_operand 2)])]
3660 ""
3661 {
3662 int i;
3663
3664 emit_call_insn (gen_call (operands[0], const0_rtx, NULL, const0_rtx));
3665
3666 for (i = 0; i < XVECLEN (operands[2], 0); i++)
3667 {
3668 rtx set = XVECEXP (operands[2], 0, i);
3669 emit_move_insn (SET_DEST (set), SET_SRC (set));
3670 }
3671
3672 /* The optimizer does not know that the call sets the function value
3673 registers we stored in the result block. We avoid problems by
3674 claiming that all hard registers are used and clobbered at this
3675 point. */
3676 emit_insn (gen_blockage ());
3677
3678 DONE;
3679 })
3680
3681 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
3682 ;; all of memory. This blocks insns from being moved across this point.
3683
3684 (define_insn "blockage"
3685 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
3686 ""
3687 ""
3688 [(set_attr "length" "0")
3689 (set_attr "type" "none")])
3690
3691 (define_insn "jump"
3692 [(set (pc)
3693 (label_ref (match_operand 0)))]
3694 ""
3695 "br $31,%l0"
3696 [(set_attr "type" "ibr")])
3697
3698 (define_expand "return"
3699 [(return)]
3700 "direct_return ()")
3701
3702 (define_insn "*return_internal"
3703 [(return)]
3704 "reload_completed"
3705 "ret $31,($26),1"
3706 [(set_attr "type" "ibr")])
3707
3708 (define_insn "indirect_jump"
3709 [(set (pc) (match_operand:DI 0 "register_operand" "r"))]
3710 ""
3711 "jmp $31,(%0),0"
3712 [(set_attr "type" "ibr")])
3713
3714 (define_expand "tablejump"
3715 [(parallel [(set (pc)
3716 (match_operand 0 "register_operand"))
3717 (use (label_ref:DI (match_operand 1)))])]
3718 ""
3719 {
3720 if (TARGET_ABI_OSF)
3721 {
3722 rtx dest = gen_reg_rtx (DImode);
3723 emit_insn (gen_extendsidi2 (dest, operands[0]));
3724 emit_insn (gen_adddi3 (dest, pic_offset_table_rtx, dest));
3725 operands[0] = dest;
3726 }
3727 })
3728
3729 (define_insn "*tablejump_internal"
3730 [(set (pc)
3731 (match_operand:DI 0 "register_operand" "r"))
3732 (use (label_ref (match_operand 1)))]
3733 ""
3734 "jmp $31,(%0),0"
3735 [(set_attr "type" "ibr")])
3736
3737 ;; Cache flush. Used by alpha_trampoline_init. 0x86 is PAL_imb, but we don't
3738 ;; want to have to include pal.h in our .s file.
3739 (define_insn "imb"
3740 [(unspec_volatile [(const_int 0)] UNSPECV_IMB)]
3741 ""
3742 "call_pal 0x86"
3743 [(set_attr "type" "callpal")])
3744
3745 (define_expand "clear_cache"
3746 [(match_operand:DI 0) ; region start
3747 (match_operand:DI 1)] ; region end
3748 ""
3749 {
3750 emit_insn (gen_imb ());
3751 DONE;
3752 })
3753
3754 ;; BUGCHK is documented common to OSF/1 and VMS PALcode.
3755 (define_insn "trap"
3756 [(trap_if (const_int 1) (const_int 0))
3757 (use (reg:DI 29))]
3758 ""
3759 "call_pal 0x81"
3760 [(set_attr "type" "callpal")])
3761
3762 ;; For userland, we load the thread pointer from the TCB.
3763 ;; For the kernel, we load the per-cpu private value.
3764
3765 (define_insn "get_thread_pointerdi"
3766 [(set (match_operand:DI 0 "register_operand" "=v")
3767 (unspec:DI [(const_int 0)] UNSPEC_TP))]
3768 "TARGET_ABI_OSF"
3769 {
3770 if (TARGET_TLS_KERNEL)
3771 return "call_pal 0x32";
3772 else
3773 return "call_pal 0x9e";
3774 }
3775 [(set_attr "type" "callpal")])
3776
3777 ;; For completeness, and possibly a __builtin function, here's how to
3778 ;; set the thread pointer. Since we don't describe enough of this
3779 ;; quantity for CSE, we have to use a volatile unspec, and then there's
3780 ;; not much point in creating an R16_REG register class.
3781
3782 (define_expand "set_thread_pointerdi"
3783 [(set (reg:DI 16) (match_operand:DI 0 "input_operand"))
3784 (unspec_volatile [(reg:DI 16)] UNSPECV_SET_TP)]
3785 "TARGET_ABI_OSF")
3786
3787 (define_insn "*set_tp"
3788 [(unspec_volatile [(reg:DI 16)] UNSPECV_SET_TP)]
3789 "TARGET_ABI_OSF"
3790 {
3791 if (TARGET_TLS_KERNEL)
3792 return "call_pal 0x31";
3793 else
3794 return "call_pal 0x9f";
3795 }
3796 [(set_attr "type" "callpal")])
3797
3798 ;; Special builtins for establishing and reverting VMS condition handlers.
3799
3800 (define_expand "builtin_establish_vms_condition_handler"
3801 [(set (reg:DI 0) (match_operand:DI 0 "register_operand"))
3802 (use (match_operand:DI 1 "address_operand"))]
3803 "TARGET_ABI_OPEN_VMS"
3804 {
3805 alpha_expand_builtin_establish_vms_condition_handler (operands[0],
3806 operands[1]);
3807 })
3808
3809 (define_expand "builtin_revert_vms_condition_handler"
3810 [(set (reg:DI 0) (match_operand:DI 0 "register_operand"))]
3811 "TARGET_ABI_OPEN_VMS"
3812 "alpha_expand_builtin_revert_vms_condition_handler (operands[0]);")
3813
3815 ;; Finally, we have the basic data motion insns. The byte and word insns
3816 ;; are done via define_expand. Start with the floating-point insns, since
3817 ;; they are simpler.
3818
3819 (define_expand "movsf"
3820 [(set (match_operand:SF 0 "nonimmediate_operand")
3821 (match_operand:SF 1 "general_operand"))]
3822 ""
3823 {
3824 if (MEM_P (operands[0])
3825 && ! reg_or_0_operand (operands[1], SFmode))
3826 operands[1] = force_reg (SFmode, operands[1]);
3827 })
3828
3829 (define_insn "*movsf"
3830 [(set (match_operand:SF 0 "nonimmediate_operand" "=f,f,*r,*r,m,m,f,*r")
3831 (match_operand:SF 1 "input_operand" "fG,m,*rG,m,fG,*r,*r,f"))]
3832 "register_operand (operands[0], SFmode)
3833 || reg_or_0_operand (operands[1], SFmode)"
3834 "@
3835 cpys %R1,%R1,%0
3836 ld%, %0,%1
3837 bis $31,%r1,%0
3838 ldl %0,%1
3839 st%, %R1,%0
3840 stl %r1,%0
3841 itofs %1,%0
3842 ftois %1,%0"
3843 [(set_attr "type" "fcpys,fld,ilog,ild,fst,ist,itof,ftoi")
3844 (set_attr "isa" "*,*,*,*,*,*,fix,fix")])
3845
3846 (define_expand "movdf"
3847 [(set (match_operand:DF 0 "nonimmediate_operand")
3848 (match_operand:DF 1 "general_operand"))]
3849 ""
3850 {
3851 if (MEM_P (operands[0])
3852 && ! reg_or_0_operand (operands[1], DFmode))
3853 operands[1] = force_reg (DFmode, operands[1]);
3854 })
3855
3856 (define_insn "*movdf"
3857 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,f,*r,*r,m,m,f,*r")
3858 (match_operand:DF 1 "input_operand" "fG,m,*rG,m,fG,*r,*r,f"))]
3859 "register_operand (operands[0], DFmode)
3860 || reg_or_0_operand (operands[1], DFmode)"
3861 "@
3862 cpys %R1,%R1,%0
3863 ld%- %0,%1
3864 bis $31,%r1,%0
3865 ldq %0,%1
3866 st%- %R1,%0
3867 stq %r1,%0
3868 itoft %1,%0
3869 ftoit %1,%0"
3870 [(set_attr "type" "fcpys,fld,ilog,ild,fst,ist,itof,ftoi")
3871 (set_attr "isa" "*,*,*,*,*,*,fix,fix")])
3872
3873 ;; Subregs suck for register allocation. Pretend we can move TFmode
3874 ;; data between general registers until after reload.
3875 ;; ??? Is this still true now that we have the lower-subreg pass?
3876
3877 (define_expand "movtf"
3878 [(set (match_operand:TF 0 "nonimmediate_operand")
3879 (match_operand:TF 1 "general_operand"))]
3880 ""
3881 {
3882 if (MEM_P (operands[0])
3883 && ! reg_or_0_operand (operands[1], TFmode))
3884 operands[1] = force_reg (TFmode, operands[1]);
3885 })
3886
3887 (define_insn_and_split "*movtf_internal"
3888 [(set (match_operand:TF 0 "nonimmediate_operand" "=r,o")
3889 (match_operand:TF 1 "input_operand" "roG,rG"))]
3890 "register_operand (operands[0], TFmode)
3891 || reg_or_0_operand (operands[1], TFmode)"
3892 "#"
3893 "reload_completed"
3894 [(set (match_dup 0) (match_dup 2))
3895 (set (match_dup 1) (match_dup 3))]
3896 "alpha_split_tmode_pair (operands, TFmode, true);")
3897
3898 ;; We do two major things here: handle mem->mem and construct long
3899 ;; constants.
3900
3901 (define_expand "movsi"
3902 [(set (match_operand:SI 0 "nonimmediate_operand")
3903 (match_operand:SI 1 "general_operand"))]
3904 ""
3905 {
3906 if (alpha_expand_mov (SImode, operands))
3907 DONE;
3908 })
3909
3910 (define_insn "*movsi"
3911 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,r,r,r,m,r")
3912 (match_operand:SI 1 "input_operand" "rJ,K,L,n,m,rJ,s"))]
3913 "register_operand (operands[0], SImode)
3914 || reg_or_0_operand (operands[1], SImode)"
3915 "@
3916 bis $31,%r1,%0
3917 lda %0,%1($31)
3918 ldah %0,%h1($31)
3919 #
3920 ldl %0,%1
3921 stl %r1,%0
3922 lda %0,%1"
3923 [(set_attr "type" "ilog,iadd,iadd,multi,ild,ist,ldsym")
3924 (set_attr "isa" "*,*,*,*,*,*,vms")])
3925
3926 ;; Split a load of a large constant into the appropriate two-insn
3927 ;; sequence.
3928
3929 (define_split
3930 [(set (match_operand:SI 0 "register_operand")
3931 (match_operand:SI 1 "non_add_const_operand"))]
3932 ""
3933 [(const_int 0)]
3934 {
3935 if (alpha_split_const_mov (SImode, operands))
3936 DONE;
3937 else
3938 FAIL;
3939 })
3940
3941 (define_insn "*movdi_er_low_l"
3942 [(set (match_operand:DI 0 "register_operand" "=r")
3943 (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
3944 (match_operand:DI 2 "local_symbolic_operand")))]
3945 "TARGET_EXPLICIT_RELOCS"
3946 {
3947 if (true_regnum (operands[1]) == 29)
3948 return "lda %0,%2(%1)\t\t!gprel";
3949 else
3950 return "lda %0,%2(%1)\t\t!gprellow";
3951 }
3952 [(set_attr "usegp" "yes")])
3953
3954 (define_split
3955 [(set (match_operand:DI 0 "register_operand")
3956 (match_operand:DI 1 "small_symbolic_operand"))]
3957 "TARGET_EXPLICIT_RELOCS && reload_completed"
3958 [(set (match_dup 0)
3959 (lo_sum:DI (match_dup 2) (match_dup 1)))]
3960 "operands[2] = pic_offset_table_rtx;")
3961
3962 (define_split
3963 [(set (match_operand:DI 0 "register_operand")
3964 (match_operand:DI 1 "local_symbolic_operand"))]
3965 "TARGET_EXPLICIT_RELOCS && reload_completed"
3966 [(set (match_dup 0)
3967 (plus:DI (match_dup 2) (high:DI (match_dup 1))))
3968 (set (match_dup 0)
3969 (lo_sum:DI (match_dup 0) (match_dup 1)))]
3970 "operands[2] = pic_offset_table_rtx;")
3971
3972 (define_split
3973 [(match_operand 0 "some_small_symbolic_operand")]
3974 ""
3975 [(match_dup 0)]
3976 "operands[0] = split_small_symbolic_operand (operands[0]);")
3977
3978 ;; Accepts any symbolic, not just global, since function calls that
3979 ;; don't go via bsr still use !literal in hopes of linker relaxation.
3980 (define_insn "movdi_er_high_g"
3981 [(set (match_operand:DI 0 "register_operand" "=r")
3982 (unspec:DI [(match_operand:DI 1 "register_operand" "r")
3983 (match_operand:DI 2 "symbolic_operand")
3984 (match_operand 3 "const_int_operand")]
3985 UNSPEC_LITERAL))]
3986 "TARGET_EXPLICIT_RELOCS"
3987 {
3988 if (INTVAL (operands[3]) == 0)
3989 return "ldq %0,%2(%1)\t\t!literal";
3990 else
3991 return "ldq %0,%2(%1)\t\t!literal!%3";
3992 }
3993 [(set_attr "type" "ldsym")])
3994
3995 (define_split
3996 [(set (match_operand:DI 0 "register_operand")
3997 (match_operand:DI 1 "global_symbolic_operand"))]
3998 "TARGET_EXPLICIT_RELOCS && reload_completed"
3999 [(set (match_dup 0)
4000 (unspec:DI [(match_dup 2)
4001 (match_dup 1)
4002 (const_int 0)] UNSPEC_LITERAL))]
4003 "operands[2] = pic_offset_table_rtx;")
4004
4005 (define_insn "movdi_er_tlsgd"
4006 [(set (match_operand:DI 0 "register_operand" "=r")
4007 (unspec:DI [(match_operand:DI 1 "register_operand" "r")
4008 (match_operand:DI 2 "symbolic_operand")
4009 (match_operand 3 "const_int_operand")]
4010 UNSPEC_TLSGD))]
4011 "HAVE_AS_TLS"
4012 {
4013 if (INTVAL (operands[3]) == 0)
4014 return "lda %0,%2(%1)\t\t!tlsgd";
4015 else
4016 return "lda %0,%2(%1)\t\t!tlsgd!%3";
4017 })
4018
4019 (define_insn "movdi_er_tlsldm"
4020 [(set (match_operand:DI 0 "register_operand" "=r")
4021 (unspec:DI [(match_operand:DI 1 "register_operand" "r")
4022 (match_operand 2 "const_int_operand")]
4023 UNSPEC_TLSLDM))]
4024 "HAVE_AS_TLS"
4025 {
4026 if (INTVAL (operands[2]) == 0)
4027 return "lda %0,%&(%1)\t\t!tlsldm";
4028 else
4029 return "lda %0,%&(%1)\t\t!tlsldm!%2";
4030 })
4031
4032 (define_insn "*movdi_er_gotdtp"
4033 [(set (match_operand:DI 0 "register_operand" "=r")
4034 (unspec:DI [(match_operand:DI 1 "register_operand" "r")
4035 (match_operand:DI 2 "symbolic_operand")]
4036 UNSPEC_DTPREL))]
4037 "HAVE_AS_TLS"
4038 "ldq %0,%2(%1)\t\t!gotdtprel"
4039 [(set_attr "type" "ild")
4040 (set_attr "usegp" "yes")])
4041
4042 (define_split
4043 [(set (match_operand:DI 0 "register_operand")
4044 (match_operand:DI 1 "gotdtp_symbolic_operand"))]
4045 "HAVE_AS_TLS && reload_completed"
4046 [(set (match_dup 0)
4047 (unspec:DI [(match_dup 2)
4048 (match_dup 1)] UNSPEC_DTPREL))]
4049 {
4050 operands[1] = XVECEXP (XEXP (operands[1], 0), 0, 0);
4051 operands[2] = pic_offset_table_rtx;
4052 })
4053
4054 (define_insn "*movdi_er_gottp"
4055 [(set (match_operand:DI 0 "register_operand" "=r")
4056 (unspec:DI [(match_operand:DI 1 "register_operand" "r")
4057 (match_operand:DI 2 "symbolic_operand")]
4058 UNSPEC_TPREL))]
4059 "HAVE_AS_TLS"
4060 "ldq %0,%2(%1)\t\t!gottprel"
4061 [(set_attr "type" "ild")
4062 (set_attr "usegp" "yes")])
4063
4064 (define_split
4065 [(set (match_operand:DI 0 "register_operand")
4066 (match_operand:DI 1 "gottp_symbolic_operand"))]
4067 "HAVE_AS_TLS && reload_completed"
4068 [(set (match_dup 0)
4069 (unspec:DI [(match_dup 2)
4070 (match_dup 1)] UNSPEC_TPREL))]
4071 {
4072 operands[1] = XVECEXP (XEXP (operands[1], 0), 0, 0);
4073 operands[2] = pic_offset_table_rtx;
4074 })
4075
4076 (define_insn "*movdi"
4077 [(set (match_operand:DI 0 "nonimmediate_operand"
4078 "=r,r,r,r,r,r,r,r, m, *f,*f, Q, r,*f")
4079 (match_operand:DI 1 "input_operand"
4080 "rJ,K,L,T,s,n,s,m,rJ,*fJ, Q,*f,*f, r"))]
4081 "register_operand (operands[0], DImode)
4082 || reg_or_0_operand (operands[1], DImode)"
4083 "@
4084 mov %r1,%0
4085 lda %0,%1($31)
4086 ldah %0,%h1($31)
4087 #
4088 #
4089 #
4090 lda %0,%1
4091 ldq%A1 %0,%1
4092 stq%A0 %r1,%0
4093 fmov %R1,%0
4094 ldt %0,%1
4095 stt %R1,%0
4096 ftoit %1,%0
4097 itoft %1,%0"
4098 [(set_attr "type" "ilog,iadd,iadd,iadd,ldsym,multi,ldsym,ild,ist,fcpys,fld,fst,ftoi,itof")
4099 (set_attr "isa" "*,*,*,er,er,*,ner,*,*,*,*,*,fix,fix")
4100 (set_attr "usegp" "*,*,*,yes,*,*,*,*,*,*,*,*,*,*")])
4101
4102 ;; VMS needs to set up "vms_base_regno" for unwinding. This move
4103 ;; often appears dead to the life analysis code, at which point we
4104 ;; die for emitting dead prologue instructions. Force this live.
4105
4106 (define_insn "force_movdi"
4107 [(set (match_operand:DI 0 "register_operand" "=r")
4108 (unspec_volatile:DI [(match_operand:DI 1 "register_operand" "r")]
4109 UNSPECV_FORCE_MOV))]
4110 ""
4111 "mov %1,%0"
4112 [(set_attr "type" "ilog")])
4113
4114 ;; We do three major things here: handle mem->mem, put 64-bit constants in
4115 ;; memory, and construct long 32-bit constants.
4116
4117 (define_expand "movdi"
4118 [(set (match_operand:DI 0 "nonimmediate_operand")
4119 (match_operand:DI 1 "general_operand"))]
4120 ""
4121 {
4122 if (alpha_expand_mov (DImode, operands))
4123 DONE;
4124 })
4125
4126 ;; Split a load of a large constant into the appropriate two-insn
4127 ;; sequence.
4128
4129 (define_split
4130 [(set (match_operand:DI 0 "register_operand")
4131 (match_operand:DI 1 "non_add_const_operand"))]
4132 ""
4133 [(const_int 0)]
4134 {
4135 if (alpha_split_const_mov (DImode, operands))
4136 DONE;
4137 else
4138 FAIL;
4139 })
4140
4141 ;; We need to prevent reload from splitting TImode moves, because it
4142 ;; might decide to overwrite a pointer with the value it points to.
4143 ;; In that case we have to do the loads in the appropriate order so
4144 ;; that the pointer is not destroyed too early.
4145
4146 (define_insn_and_split "*movti_internal"
4147 [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o")
4148 (match_operand:TI 1 "input_operand" "roJ,rJ"))]
4149 "(register_operand (operands[0], TImode)
4150 /* Prevent rematerialization of constants. */
4151 && ! CONSTANT_P (operands[1]))
4152 || reg_or_0_operand (operands[1], TImode)"
4153 "#"
4154 "reload_completed"
4155 [(set (match_dup 0) (match_dup 2))
4156 (set (match_dup 1) (match_dup 3))]
4157 "alpha_split_tmode_pair (operands, TImode, true);")
4158
4159 (define_expand "movti"
4160 [(set (match_operand:TI 0 "nonimmediate_operand")
4161 (match_operand:TI 1 "general_operand"))]
4162 ""
4163 {
4164 if (MEM_P (operands[0])
4165 && ! reg_or_0_operand (operands[1], TImode))
4166 operands[1] = force_reg (TImode, operands[1]);
4167
4168 if (operands[1] == const0_rtx)
4169 ;
4170 /* We must put 64-bit constants in memory. We could keep the
4171 32-bit constants in TImode and rely on the splitter, but
4172 this doesn't seem to be worth the pain. */
4173 else if (CONST_SCALAR_INT_P (operands[1]))
4174 {
4175 rtx in[2], out[2], target;
4176
4177 gcc_assert (can_create_pseudo_p ());
4178
4179 split_double (operands[1], &in[0], &in[1]);
4180
4181 if (in[0] == const0_rtx)
4182 out[0] = const0_rtx;
4183 else
4184 {
4185 out[0] = gen_reg_rtx (DImode);
4186 emit_insn (gen_movdi (out[0], in[0]));
4187 }
4188
4189 if (in[1] == const0_rtx)
4190 out[1] = const0_rtx;
4191 else
4192 {
4193 out[1] = gen_reg_rtx (DImode);
4194 emit_insn (gen_movdi (out[1], in[1]));
4195 }
4196
4197 if (!REG_P (operands[0]))
4198 target = gen_reg_rtx (TImode);
4199 else
4200 target = operands[0];
4201
4202 emit_insn (gen_movdi (operand_subword (target, 0, 0, TImode), out[0]));
4203 emit_insn (gen_movdi (operand_subword (target, 1, 0, TImode), out[1]));
4204
4205 if (target != operands[0])
4206 emit_insn (gen_rtx_SET (operands[0], target));
4207
4208 DONE;
4209 }
4210 })
4211
4212 ;; These are the partial-word cases.
4213 ;;
4214 ;; First we have the code to load an aligned word. Operand 0 is the register
4215 ;; in which to place the result. It's mode is QImode or HImode. Operand 1
4216 ;; is an SImode MEM at the low-order byte of the proper word. Operand 2 is the
4217 ;; number of bits within the word that the value is. Operand 3 is an SImode
4218 ;; scratch register. If operand 0 is a hard register, operand 3 may be the
4219 ;; same register. It is allowed to conflict with operand 1 as well.
4220
4221 (define_expand "aligned_loadqi"
4222 [(set (match_operand:SI 3 "register_operand")
4223 (match_operand:SI 1 "memory_operand"))
4224 (set (match_operand:DI 0 "register_operand")
4225 (zero_extract:DI (subreg:DI (match_dup 3) 0)
4226 (const_int 8)
4227 (match_operand:DI 2 "const_int_operand")))])
4228
4229 (define_expand "aligned_loadhi"
4230 [(set (match_operand:SI 3 "register_operand")
4231 (match_operand:SI 1 "memory_operand"))
4232 (set (match_operand:DI 0 "register_operand")
4233 (zero_extract:DI (subreg:DI (match_dup 3) 0)
4234 (const_int 16)
4235 (match_operand:DI 2 "const_int_operand")))])
4236
4237 ;; Similar for unaligned loads, where we use the sequence from the
4238 ;; Alpha Architecture manual. We have to distinguish between little-endian
4239 ;; and big-endian systems as the sequences are different.
4240 ;;
4241 ;; Operand 1 is the address. Operands 2 and 3 are temporaries, where
4242 ;; operand 3 can overlap the input and output registers.
4243
4244 (define_expand "unaligned_loadqi"
4245 [(set (match_operand:DI 2 "register_operand")
4246 (mem:DI (and:DI (match_operand:DI 1 "address_operand")
4247 (const_int -8))))
4248 (set (match_operand:DI 3 "register_operand")
4249 (match_dup 1))
4250 (set (match_operand:DI 0 "register_operand")
4251 (zero_extract:DI (match_dup 2)
4252 (const_int 8)
4253 (ashift:DI (match_dup 3) (const_int 3))))])
4254
4255 (define_expand "unaligned_loadhi"
4256 [(set (match_operand:DI 2 "register_operand")
4257 (mem:DI (and:DI (match_operand:DI 1 "address_operand")
4258 (const_int -8))))
4259 (set (match_operand:DI 3 "register_operand")
4260 (match_dup 1))
4261 (set (match_operand:DI 0 "register_operand")
4262 (zero_extract:DI (match_dup 2)
4263 (const_int 16)
4264 (ashift:DI (match_dup 3) (const_int 3))))])
4265
4266 ;; Storing an aligned byte or word requires two temporaries. Operand 0 is the
4267 ;; aligned SImode MEM. Operand 1 is the register containing the
4268 ;; byte or word to store. Operand 2 is the number of bits within the word that
4269 ;; the value should be placed. Operands 3 and 4 are SImode temporaries.
4270
4271 (define_expand "aligned_store"
4272 [(set (match_operand:SI 3 "register_operand")
4273 (match_operand:SI 0 "memory_operand"))
4274 (set (subreg:DI (match_dup 3) 0)
4275 (and:DI (subreg:DI (match_dup 3) 0) (match_dup 5)))
4276 (set (subreg:DI (match_operand:SI 4 "register_operand") 0)
4277 (ashift:DI (zero_extend:DI (match_operand 1 "register_operand"))
4278 (match_operand:DI 2 "const_int_operand")))
4279 (set (subreg:DI (match_dup 4) 0)
4280 (ior:DI (subreg:DI (match_dup 4) 0) (subreg:DI (match_dup 3) 0)))
4281 (set (match_dup 0) (match_dup 4))]
4282 ""
4283 {
4284 operands[5] = GEN_INT (~ (GET_MODE_MASK (GET_MODE (operands[1]))
4285 << INTVAL (operands[2])));
4286 })
4287
4288 ;; For the unaligned byte and halfword cases, we use code similar to that
4289 ;; in the ;; Architecture book, but reordered to lower the number of registers
4290 ;; required. Operand 0 is the address. Operand 1 is the data to store.
4291 ;; Operands 2, 3, and 4 are DImode temporaries, where operands 2 and 4 may
4292 ;; be the same temporary, if desired. If the address is in a register,
4293 ;; operand 2 can be that register.
4294
4295 (define_expand "unaligned_store<mode>"
4296 [(set (match_operand:DI 3 "register_operand")
4297 (mem:DI (and:DI (match_operand:DI 0 "address_operand")
4298 (const_int -8))))
4299 (set (match_operand:DI 2 "register_operand")
4300 (match_dup 0))
4301 (set (match_dup 3)
4302 (and:DI (not:DI (ashift:DI (match_dup 5)
4303 (ashift:DI (match_dup 2) (const_int 3))))
4304 (match_dup 3)))
4305 (set (match_operand:DI 4 "register_operand")
4306 (ashift:DI (zero_extend:DI
4307 (match_operand:I12MODE 1 "register_operand"))
4308 (ashift:DI (match_dup 2) (const_int 3))))
4309 (set (match_dup 4) (ior:DI (match_dup 4) (match_dup 3)))
4310 (set (mem:DI (and:DI (match_dup 0) (const_int -8)))
4311 (match_dup 4))]
4312 ""
4313 "operands[5] = GEN_INT (GET_MODE_MASK (<MODE>mode));")
4314
4315 ;; Here are the define_expand's for QI and HI moves that use the above
4316 ;; patterns. We have the normal sets, plus the ones that need scratch
4317 ;; registers for reload.
4318
4319 (define_expand "mov<mode>"
4320 [(set (match_operand:I12MODE 0 "nonimmediate_operand")
4321 (match_operand:I12MODE 1 "general_operand"))]
4322 ""
4323 {
4324 if (TARGET_BWX
4325 ? alpha_expand_mov (<MODE>mode, operands)
4326 : alpha_expand_mov_nobwx (<MODE>mode, operands))
4327 DONE;
4328 })
4329
4330 (define_insn "*movqi"
4331 [(set (match_operand:QI 0 "nonimmediate_operand" "=r,r,r,m")
4332 (match_operand:QI 1 "input_operand" "rJ,n,m,rJ"))]
4333 "register_operand (operands[0], QImode)
4334 || reg_or_0_operand (operands[1], QImode)"
4335 "@
4336 bis $31,%r1,%0
4337 lda %0,%L1($31)
4338 ldbu %0,%1
4339 stb %r1,%0"
4340 [(set_attr "type" "ilog,iadd,ild,ist")
4341 (set_attr "isa" "*,*,bwx,bwx")])
4342
4343 (define_insn "*movhi"
4344 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
4345 (match_operand:HI 1 "input_operand" "rJ,n,m,rJ"))]
4346 "register_operand (operands[0], HImode)
4347 || reg_or_0_operand (operands[1], HImode)"
4348 "@
4349 bis $31,%r1,%0
4350 lda %0,%L1($31)
4351 ldwu %0,%1
4352 stw %r1,%0"
4353 [(set_attr "type" "ilog,iadd,ild,ist")
4354 (set_attr "isa" "*,*,bwx,bwx")])
4355
4356 ;; We need to hook into the extra support that we have for HImode
4357 ;; reloads when BWX insns are not available.
4358 (define_expand "movcqi"
4359 [(set (match_operand:CQI 0 "nonimmediate_operand")
4360 (match_operand:CQI 1 "general_operand"))]
4361 "!TARGET_BWX"
4362 {
4363 if (GET_CODE (operands[0]) == CONCAT || GET_CODE (operands[1]) == CONCAT)
4364 ;
4365 else if (!any_memory_operand (operands[0], CQImode))
4366 {
4367 if (!any_memory_operand (operands[1], CQImode))
4368 {
4369 emit_move_insn (gen_lowpart (HImode, operands[0]),
4370 gen_lowpart (HImode, operands[1]));
4371 DONE;
4372 }
4373 if (aligned_memory_operand (operands[1], CQImode))
4374 {
4375 bool done;
4376 do_aligned1:
4377 operands[1] = gen_lowpart (HImode, operands[1]);
4378 do_aligned2:
4379 operands[0] = gen_lowpart (HImode, operands[0]);
4380 done = alpha_expand_mov_nobwx (HImode, operands);
4381 gcc_assert (done);
4382 DONE;
4383 }
4384 }
4385 else if (aligned_memory_operand (operands[0], CQImode))
4386 {
4387 if (MEM_P (operands[1]))
4388 {
4389 rtx x = gen_reg_rtx (HImode);
4390 emit_move_insn (gen_lowpart (CQImode, x), operands[1]);
4391 operands[1] = x;
4392 goto do_aligned2;
4393 }
4394 goto do_aligned1;
4395 }
4396
4397 gcc_assert (!reload_in_progress);
4398 emit_move_complex_parts (operands[0], operands[1]);
4399 DONE;
4400 })
4401
4402 ;; Here are the versions for reload.
4403 ;;
4404 ;; The aligned input case is recognized early in alpha_secondary_reload
4405 ;; in order to avoid allocating an unnecessary scratch register.
4406 ;;
4407 ;; Note that in the unaligned cases we know that the operand must not be
4408 ;; a pseudo-register because stack slots are always aligned references.
4409
4410 (define_expand "reload_in<mode>"
4411 [(parallel [(match_operand:RELOAD12 0 "register_operand" "=r")
4412 (match_operand:RELOAD12 1 "any_memory_operand" "m")
4413 (match_operand:TI 2 "register_operand" "=&r")])]
4414 "!TARGET_BWX"
4415 {
4416 rtx scratch, seq, addr;
4417 unsigned regno = REGNO (operands[2]);
4418
4419 /* It is possible that one of the registers we got for operands[2]
4420 might coincide with that of operands[0] (which is why we made
4421 it TImode). Pick the other one to use as our scratch. */
4422 if (regno == REGNO (operands[0]))
4423 regno++;
4424 scratch = gen_rtx_REG (DImode, regno);
4425
4426 addr = get_unaligned_address (operands[1]);
4427 operands[0] = gen_rtx_REG (DImode, REGNO (operands[0]));
4428 seq = gen_unaligned_load<reloadmode> (operands[0], addr,
4429 scratch, operands[0]);
4430 alpha_set_memflags (seq, operands[1]);
4431
4432 emit_insn (seq);
4433 DONE;
4434 })
4435
4436 (define_expand "reload_out<mode>"
4437 [(parallel [(match_operand:RELOAD12 0 "any_memory_operand" "=m")
4438 (match_operand:RELOAD12 1 "register_operand" "r")
4439 (match_operand:TI 2 "register_operand" "=&r")])]
4440 "!TARGET_BWX"
4441 {
4442 unsigned regno = REGNO (operands[2]);
4443
4444 if (<MODE>mode == CQImode)
4445 {
4446 operands[0] = gen_lowpart (HImode, operands[0]);
4447 operands[1] = gen_lowpart (HImode, operands[1]);
4448 }
4449
4450 if (aligned_memory_operand (operands[0], <MODE>mode))
4451 {
4452 emit_insn (gen_reload_out<reloadmode>_aligned
4453 (operands[0], operands[1],
4454 gen_rtx_REG (SImode, regno),
4455 gen_rtx_REG (SImode, regno + 1)));
4456 }
4457 else
4458 {
4459 rtx addr = get_unaligned_address (operands[0]);
4460 rtx scratch1 = gen_rtx_REG (DImode, regno);
4461 rtx scratch2 = gen_rtx_REG (DImode, regno + 1);
4462 rtx scratch3 = scratch1;
4463 rtx seq;
4464
4465 if (REG_P (addr))
4466 scratch1 = addr;
4467
4468 seq = gen_unaligned_store<reloadmode> (addr, operands[1], scratch1,
4469 scratch2, scratch3);
4470 alpha_set_memflags (seq, operands[0]);
4471 emit_insn (seq);
4472 }
4473 DONE;
4474 })
4475
4476 ;; Helpers for the above. The way reload is structured, we can't
4477 ;; always get a proper address for a stack slot during reload_foo
4478 ;; expansion, so we must delay our address manipulations until after.
4479
4480 (define_insn_and_split "reload_in<mode>_aligned"
4481 [(set (match_operand:I12MODE 0 "register_operand" "=r")
4482 (match_operand:I12MODE 1 "memory_operand" "m"))]
4483 "!TARGET_BWX && (reload_in_progress || reload_completed)"
4484 "#"
4485 "!TARGET_BWX && reload_completed"
4486 [(const_int 0)]
4487 {
4488 rtx aligned_mem, bitnum;
4489 get_aligned_mem (operands[1], &aligned_mem, &bitnum);
4490 emit_insn (gen_aligned_load<reloadmode>
4491 (gen_lowpart (DImode, operands[0]), aligned_mem, bitnum,
4492 gen_rtx_REG (SImode, REGNO (operands[0]))));
4493 DONE;
4494 })
4495
4496 (define_insn_and_split "reload_out<mode>_aligned"
4497 [(set (match_operand:I12MODE 0 "memory_operand" "=m")
4498 (match_operand:I12MODE 1 "register_operand" "r"))
4499 (clobber (match_operand:SI 2 "register_operand" "=&r"))
4500 (clobber (match_operand:SI 3 "register_operand" "=&r"))]
4501 "!TARGET_BWX && (reload_in_progress || reload_completed)"
4502 "#"
4503 "!TARGET_BWX && reload_completed"
4504 [(const_int 0)]
4505 {
4506 rtx aligned_mem, bitnum;
4507 get_aligned_mem (operands[0], &aligned_mem, &bitnum);
4508 emit_insn (gen_aligned_store (aligned_mem, operands[1], bitnum,
4509 operands[2], operands[3]));
4510 DONE;
4511 })
4512
4514 ;; Vector operations
4515
4516 (define_mode_iterator VEC [V8QI V4HI V2SI])
4517 (define_mode_iterator VEC12 [V8QI V4HI])
4518
4519 (define_expand "mov<mode>"
4520 [(set (match_operand:VEC 0 "nonimmediate_operand")
4521 (match_operand:VEC 1 "general_operand"))]
4522 ""
4523 {
4524 if (alpha_expand_mov (<MODE>mode, operands))
4525 DONE;
4526 })
4527
4528 (define_split
4529 [(set (match_operand:VEC 0 "register_operand")
4530 (match_operand:VEC 1 "non_zero_const_operand"))]
4531 ""
4532 [(const_int 0)]
4533 {
4534 if (alpha_split_const_mov (<MODE>mode, operands))
4535 DONE;
4536 else
4537 FAIL;
4538 })
4539
4540
4541 (define_expand "movmisalign<mode>"
4542 [(set (match_operand:VEC 0 "nonimmediate_operand")
4543 (match_operand:VEC 1 "general_operand"))]
4544 ""
4545 {
4546 alpha_expand_movmisalign (<MODE>mode, operands);
4547 DONE;
4548 })
4549
4550 (define_insn "*mov<mode>_fix"
4551 [(set (match_operand:VEC 0 "nonimmediate_operand" "=r,r,r,m,*f,*f,m,r,*f")
4552 (match_operand:VEC 1 "input_operand" "rW,i,m,rW,*fW,m,*f,*f,r"))]
4553 "register_operand (operands[0], <MODE>mode)
4554 || reg_or_0_operand (operands[1], <MODE>mode)"
4555 "@
4556 bis $31,%r1,%0
4557 #
4558 ldq %0,%1
4559 stq %r1,%0
4560 cpys %R1,%R1,%0
4561 ldt %0,%1
4562 stt %R1,%0
4563 ftoit %1,%0
4564 itoft %1,%0"
4565 [(set_attr "type" "ilog,multi,ild,ist,fcpys,fld,fst,ftoi,itof")
4566 (set_attr "isa" "*,*,*,*,*,*,*,fix,fix")])
4567
4568 (define_insn "<code><mode>3"
4569 [(set (match_operand:VEC12 0 "register_operand" "=r")
4570 (any_maxmin:VEC12
4571 (match_operand:VEC12 1 "reg_or_0_operand" "rW")
4572 (match_operand:VEC12 2 "reg_or_0_operand" "rW")))]
4573 "TARGET_MAX"
4574 "<maxmin><modesuffix> %r1,%r2,%0"
4575 [(set_attr "type" "mvi")])
4576
4577 (define_insn "one_cmpl<mode>2"
4578 [(set (match_operand:VEC 0 "register_operand" "=r")
4579 (not:VEC (match_operand:VEC 1 "register_operand" "r")))]
4580 ""
4581 "ornot $31,%1,%0"
4582 [(set_attr "type" "ilog")])
4583
4584 (define_insn "and<mode>3"
4585 [(set (match_operand:VEC 0 "register_operand" "=r")
4586 (and:VEC (match_operand:VEC 1 "register_operand" "r")
4587 (match_operand:VEC 2 "register_operand" "r")))]
4588 ""
4589 "and %1,%2,%0"
4590 [(set_attr "type" "ilog")])
4591
4592 (define_insn "*andnot<mode>3"
4593 [(set (match_operand:VEC 0 "register_operand" "=r")
4594 (and:VEC (not:VEC (match_operand:VEC 1 "register_operand" "r"))
4595 (match_operand:VEC 2 "register_operand" "r")))]
4596 ""
4597 "bic %2,%1,%0"
4598 [(set_attr "type" "ilog")])
4599
4600 (define_insn "ior<mode>3"
4601 [(set (match_operand:VEC 0 "register_operand" "=r")
4602 (ior:VEC (match_operand:VEC 1 "register_operand" "r")
4603 (match_operand:VEC 2 "register_operand" "r")))]
4604 ""
4605 "bis %1,%2,%0"
4606 [(set_attr "type" "ilog")])
4607
4608 (define_insn "*iornot<mode>3"
4609 [(set (match_operand:VEC 0 "register_operand" "=r")
4610 (ior:VEC (not:DI (match_operand:VEC 1 "register_operand" "r"))
4611 (match_operand:VEC 2 "register_operand" "r")))]
4612 ""
4613 "ornot %2,%1,%0"
4614 [(set_attr "type" "ilog")])
4615
4616 (define_insn "xor<mode>3"
4617 [(set (match_operand:VEC 0 "register_operand" "=r")
4618 (xor:VEC (match_operand:VEC 1 "register_operand" "r")
4619 (match_operand:VEC 2 "register_operand" "r")))]
4620 ""
4621 "xor %1,%2,%0"
4622 [(set_attr "type" "ilog")])
4623
4624 (define_insn "*xornot<mode>3"
4625 [(set (match_operand:VEC 0 "register_operand" "=r")
4626 (not:VEC (xor:VEC (match_operand:VEC 1 "register_operand" "r")
4627 (match_operand:VEC 2 "register_operand" "r"))))]
4628 ""
4629 "eqv %1,%2,%0"
4630 [(set_attr "type" "ilog")])
4631
4632 (define_expand "vec_shl_<mode>"
4633 [(set (match_operand:VEC 0 "register_operand")
4634 (ashift:DI (match_operand:VEC 1 "register_operand")
4635 (match_operand:DI 2 "reg_or_6bit_operand")))]
4636 ""
4637 {
4638 operands[0] = gen_lowpart (DImode, operands[0]);
4639 operands[1] = gen_lowpart (DImode, operands[1]);
4640 })
4641
4642 (define_expand "vec_shr_<mode>"
4643 [(set (match_operand:VEC 0 "register_operand")
4644 (lshiftrt:DI (match_operand:VEC 1 "register_operand")
4645 (match_operand:DI 2 "reg_or_6bit_operand")))]
4646 ""
4647 {
4648 operands[0] = gen_lowpart (DImode, operands[0]);
4649 operands[1] = gen_lowpart (DImode, operands[1]);
4650 })
4651
4653 ;; Bit field extract patterns which use ext[wlq][lh]
4654
4655 (define_expand "extvmisaligndi"
4656 [(set (match_operand:DI 0 "register_operand")
4657 (sign_extract:DI (match_operand:BLK 1 "memory_operand")
4658 (match_operand:DI 2 "const_int_operand")
4659 (match_operand:DI 3 "const_int_operand")))]
4660 ""
4661 {
4662 /* We can do 16, 32 and 64 bit fields, if aligned on byte boundaries. */
4663 if (INTVAL (operands[3]) % 8 != 0
4664 || (INTVAL (operands[2]) != 16
4665 && INTVAL (operands[2]) != 32
4666 && INTVAL (operands[2]) != 64))
4667 FAIL;
4668
4669 alpha_expand_unaligned_load (operands[0], operands[1],
4670 INTVAL (operands[2]) / 8,
4671 INTVAL (operands[3]) / 8, 1);
4672 DONE;
4673 })
4674
4675 (define_expand "extzvdi"
4676 [(set (match_operand:DI 0 "register_operand")
4677 (zero_extract:DI (match_operand:DI 1 "register_operand")
4678 (match_operand:DI 2 "const_int_operand")
4679 (match_operand:DI 3 "const_int_operand")))]
4680 ""
4681 {
4682 /* We can do 8, 16, 32 and 64 bit fields, if aligned on byte boundaries. */
4683 if (INTVAL (operands[3]) % 8 != 0
4684 || (INTVAL (operands[2]) != 8
4685 && INTVAL (operands[2]) != 16
4686 && INTVAL (operands[2]) != 32
4687 && INTVAL (operands[2]) != 64))
4688 FAIL;
4689 })
4690
4691 (define_expand "extzvmisaligndi"
4692 [(set (match_operand:DI 0 "register_operand")
4693 (zero_extract:DI (match_operand:BLK 1 "memory_operand")
4694 (match_operand:DI 2 "const_int_operand")
4695 (match_operand:DI 3 "const_int_operand")))]
4696 ""
4697 {
4698 /* We can do 16, 32 and 64 bit fields, if aligned on byte boundaries.
4699 We fail 8-bit fields, falling back on a simple byte load. */
4700 if (INTVAL (operands[3]) % 8 != 0
4701 || (INTVAL (operands[2]) != 16
4702 && INTVAL (operands[2]) != 32
4703 && INTVAL (operands[2]) != 64))
4704 FAIL;
4705
4706 alpha_expand_unaligned_load (operands[0], operands[1],
4707 INTVAL (operands[2]) / 8,
4708 INTVAL (operands[3]) / 8, 0);
4709 DONE;
4710 })
4711
4712 (define_expand "insvmisaligndi"
4713 [(set (zero_extract:DI (match_operand:BLK 0 "memory_operand")
4714 (match_operand:DI 1 "const_int_operand")
4715 (match_operand:DI 2 "const_int_operand"))
4716 (match_operand:DI 3 "register_operand"))]
4717 ""
4718 {
4719 /* We can do 16, 32 and 64 bit fields, if aligned on byte boundaries. */
4720 if (INTVAL (operands[2]) % 8 != 0
4721 || (INTVAL (operands[1]) != 16
4722 && INTVAL (operands[1]) != 32
4723 && INTVAL (operands[1]) != 64))
4724 FAIL;
4725
4726 alpha_expand_unaligned_store (operands[0], operands[3],
4727 INTVAL (operands[1]) / 8,
4728 INTVAL (operands[2]) / 8);
4729 DONE;
4730 })
4731
4732 ;; Block move/clear, see alpha.c for more details.
4733 ;; Argument 0 is the destination
4734 ;; Argument 1 is the source
4735 ;; Argument 2 is the length
4736 ;; Argument 3 is the alignment
4737
4738 (define_expand "movmemqi"
4739 [(parallel [(set (match_operand:BLK 0 "memory_operand")
4740 (match_operand:BLK 1 "memory_operand"))
4741 (use (match_operand:DI 2 "immediate_operand"))
4742 (use (match_operand:DI 3 "immediate_operand"))])]
4743 ""
4744 {
4745 if (alpha_expand_block_move (operands))
4746 DONE;
4747 else
4748 FAIL;
4749 })
4750
4751 (define_expand "movmemdi"
4752 [(parallel [(set (match_operand:BLK 0 "memory_operand")
4753 (match_operand:BLK 1 "memory_operand"))
4754 (use (match_operand:DI 2 "immediate_operand"))
4755 (use (match_operand:DI 3 "immediate_operand"))
4756 (use (match_dup 4))
4757 (clobber (reg:DI 25))
4758 (clobber (reg:DI 16))
4759 (clobber (reg:DI 17))
4760 (clobber (reg:DI 18))
4761 (clobber (reg:DI 19))
4762 (clobber (reg:DI 20))
4763 (clobber (reg:DI 26))
4764 (clobber (reg:DI 27))])]
4765 "TARGET_ABI_OPEN_VMS"
4766 "operands[4] = gen_rtx_SYMBOL_REF (Pmode, \"OTS$MOVE\");")
4767
4768 (define_insn "*movmemdi_1"
4769 [(set (match_operand:BLK 0 "memory_operand" "=m,m")
4770 (match_operand:BLK 1 "memory_operand" "m,m"))
4771 (use (match_operand:DI 2 "nonmemory_operand" "r,i"))
4772 (use (match_operand:DI 3 "immediate_operand"))
4773 (use (match_operand:DI 4 "call_operand" "i,i"))
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 {
4784 operands [5] = alpha_use_linkage (operands [4], false, true);
4785 switch (which_alternative)
4786 {
4787 case 0:
4788 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)";
4789 case 1:
4790 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)";
4791 default:
4792 gcc_unreachable ();
4793 }
4794 }
4795 [(set_attr "type" "multi")
4796 (set_attr "length" "28")])
4797
4798 (define_expand "setmemqi"
4799 [(parallel [(set (match_operand:BLK 0 "memory_operand")
4800 (match_operand 2 "const_int_operand"))
4801 (use (match_operand:DI 1 "immediate_operand"))
4802 (use (match_operand:DI 3 "immediate_operand"))])]
4803 ""
4804 {
4805 /* If value to set is not zero, use the library routine. */
4806 if (operands[2] != const0_rtx)
4807 FAIL;
4808
4809 if (alpha_expand_block_clear (operands))
4810 DONE;
4811 else
4812 FAIL;
4813 })
4814
4815 (define_expand "setmemdi"
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 (use (match_dup 4))
4821 (clobber (reg:DI 25))
4822 (clobber (reg:DI 16))
4823 (clobber (reg:DI 17))
4824 (clobber (reg:DI 26))
4825 (clobber (reg:DI 27))])]
4826 "TARGET_ABI_OPEN_VMS"
4827 {
4828 /* If value to set is not zero, use the library routine. */
4829 if (operands[2] != const0_rtx)
4830 FAIL;
4831
4832 operands[4] = gen_rtx_SYMBOL_REF (Pmode, "OTS$ZERO");
4833 })
4834
4835 (define_insn "*clrmemdi_1"
4836 [(set (match_operand:BLK 0 "memory_operand" "=m,m")
4837 (const_int 0))
4838 (use (match_operand:DI 1 "nonmemory_operand" "r,i"))
4839 (use (match_operand:DI 2 "immediate_operand"))
4840 (use (match_operand:DI 3 "call_operand" "i,i"))
4841 (clobber (reg:DI 25))
4842 (clobber (reg:DI 16))
4843 (clobber (reg:DI 17))
4844 (clobber (reg:DI 26))
4845 (clobber (reg:DI 27))]
4846 "TARGET_ABI_OPEN_VMS"
4847 {
4848 operands [4] = alpha_use_linkage (operands [3], false, true);
4849 switch (which_alternative)
4850 {
4851 case 0:
4852 return "lda $16,%0\;bis $31,%1,$17\;ldq $26,%4\;lda $25,2($31)\;jsr $26,%3\;ldq $27,0($29)";
4853 case 1:
4854 return "lda $16,%0\;lda $17,%1($31)\;ldq $26,%4\;lda $25,2($31)\;jsr $26,%3\;ldq $27,0($29)";
4855 default:
4856 gcc_unreachable ();
4857 }
4858 }
4859 [(set_attr "type" "multi")
4860 (set_attr "length" "24")])
4861
4862
4864 ;; Subroutine of stack space allocation. Perform a stack probe.
4865 (define_expand "stack_probe_internal"
4866 [(set (match_dup 1) (match_operand:DI 0 "const_int_operand"))]
4867 ""
4868 {
4869 operands[1] = gen_rtx_MEM (DImode, plus_constant (Pmode, stack_pointer_rtx,
4870 INTVAL (operands[0])));
4871 MEM_VOLATILE_P (operands[1]) = 1;
4872
4873 operands[0] = const0_rtx;
4874 })
4875
4876 ;; This is how we allocate stack space. If we are allocating a
4877 ;; constant amount of space and we know it is less than 4096
4878 ;; bytes, we need do nothing.
4879 ;;
4880 ;; If it is more than 4096 bytes, we need to probe the stack
4881 ;; periodically.
4882 (define_expand "allocate_stack"
4883 [(set (reg:DI 30)
4884 (plus:DI (reg:DI 30)
4885 (match_operand:DI 1 "reg_or_cint_operand")))
4886 (set (match_operand:DI 0 "register_operand" "=r")
4887 (match_dup 2))]
4888 ""
4889 {
4890 if (CONST_INT_P (operands[1])
4891 && INTVAL (operands[1]) < 32768)
4892 {
4893 if (INTVAL (operands[1]) >= 4096)
4894 {
4895 /* We do this the same way as in the prologue and generate explicit
4896 probes. Then we update the stack by the constant. */
4897
4898 int probed = 4096;
4899
4900 emit_insn (gen_stack_probe_internal (GEN_INT (- probed)));
4901 while (probed + 8192 < INTVAL (operands[1]))
4902 emit_insn (gen_stack_probe_internal
4903 (GEN_INT (- (probed += 8192))));
4904
4905 if (probed + 4096 < INTVAL (operands[1]))
4906 emit_insn (gen_stack_probe_internal
4907 (GEN_INT (- INTVAL(operands[1]))));
4908 }
4909
4910 operands[1] = GEN_INT (- INTVAL (operands[1]));
4911 operands[2] = virtual_stack_dynamic_rtx;
4912 }
4913 else
4914 {
4915 rtx_code_label *out_label = 0;
4916 rtx_code_label *loop_label = gen_label_rtx ();
4917 rtx want = gen_reg_rtx (Pmode);
4918 rtx tmp = gen_reg_rtx (Pmode);
4919 rtx memref, test;
4920
4921 emit_insn (gen_subdi3 (want, stack_pointer_rtx,
4922 force_reg (Pmode, operands[1])));
4923
4924 if (!CONST_INT_P (operands[1]))
4925 {
4926 rtx limit = GEN_INT (4096);
4927 out_label = gen_label_rtx ();
4928 test = gen_rtx_LTU (VOIDmode, operands[1], limit);
4929 emit_jump_insn
4930 (gen_cbranchdi4 (test, operands[1], limit, out_label));
4931 }
4932
4933 emit_insn (gen_adddi3 (tmp, stack_pointer_rtx, GEN_INT (-4096)));
4934 emit_label (loop_label);
4935 memref = gen_rtx_MEM (DImode, tmp);
4936 MEM_VOLATILE_P (memref) = 1;
4937 emit_move_insn (memref, const0_rtx);
4938 emit_insn (gen_adddi3 (tmp, tmp, GEN_INT(-8192)));
4939 test = gen_rtx_GTU (VOIDmode, tmp, want);
4940 emit_jump_insn (gen_cbranchdi4 (test, tmp, want, loop_label));
4941
4942 memref = gen_rtx_MEM (DImode, want);
4943 MEM_VOLATILE_P (memref) = 1;
4944 emit_move_insn (memref, const0_rtx);
4945
4946 if (out_label)
4947 emit_label (out_label);
4948
4949 emit_move_insn (stack_pointer_rtx, want);
4950 emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
4951 DONE;
4952 }
4953 })
4954
4955 ;; This is used by alpha_expand_prolog to do the same thing as above,
4956 ;; except we cannot at that time generate new basic blocks, so we hide
4957 ;; the loop in this one insn.
4958
4959 (define_insn "prologue_stack_probe_loop"
4960 [(unspec_volatile [(match_operand:DI 0 "register_operand" "r")
4961 (match_operand:DI 1 "register_operand" "r")]
4962 UNSPECV_PSPL)]
4963 ""
4964 {
4965 operands[2] = gen_label_rtx ();
4966 (*targetm.asm_out.internal_label) (asm_out_file, "L",
4967 CODE_LABEL_NUMBER (operands[2]));
4968
4969 return "stq $31,-8192(%1)\;subq %0,1,%0\;lda %1,-8192(%1)\;bne %0,%l2";
4970 }
4971 [(set_attr "length" "16")
4972 (set_attr "type" "multi")])
4973
4974 (define_expand "prologue"
4975 [(const_int 0)]
4976 ""
4977 {
4978 alpha_expand_prologue ();
4979 DONE;
4980 })
4981
4982 ;; These take care of emitting the ldgp insn in the prologue. This will be
4983 ;; an lda/ldah pair and we want to align them properly. So we have two
4984 ;; unspec_volatile insns, the first of which emits the ldgp assembler macro
4985 ;; and the second of which emits nothing. However, both are marked as type
4986 ;; IADD (the default) so the alignment code in alpha.c does the right thing
4987 ;; with them.
4988
4989 (define_expand "prologue_ldgp"
4990 [(set (match_dup 0)
4991 (unspec_volatile:DI [(match_dup 1) (match_dup 2)] UNSPECV_LDGP1))
4992 (set (match_dup 0)
4993 (unspec_volatile:DI [(match_dup 0) (match_dup 2)] UNSPECV_PLDGP2))]
4994 ""
4995 {
4996 operands[0] = pic_offset_table_rtx;
4997 operands[1] = gen_rtx_REG (Pmode, 27);
4998 operands[2] = (TARGET_EXPLICIT_RELOCS
4999 ? GEN_INT (alpha_next_sequence_number++)
5000 : const0_rtx);
5001 })
5002
5003 (define_insn "*ldgp_er_1"
5004 [(set (match_operand:DI 0 "register_operand" "=r")
5005 (unspec_volatile:DI [(match_operand:DI 1 "register_operand" "r")
5006 (match_operand 2 "const_int_operand")]
5007 UNSPECV_LDGP1))]
5008 "TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF"
5009 "ldah %0,0(%1)\t\t!gpdisp!%2"
5010 [(set_attr "cannot_copy" "true")])
5011
5012 (define_insn "*ldgp_er_2"
5013 [(set (match_operand:DI 0 "register_operand" "=r")
5014 (unspec:DI [(match_operand:DI 1 "register_operand" "r")
5015 (match_operand 2 "const_int_operand")]
5016 UNSPEC_LDGP2))]
5017 "TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF"
5018 "lda %0,0(%1)\t\t!gpdisp!%2"
5019 [(set_attr "cannot_copy" "true")])
5020
5021 (define_insn "*prologue_ldgp_er_2"
5022 [(set (match_operand:DI 0 "register_operand" "=r")
5023 (unspec_volatile:DI [(match_operand:DI 1 "register_operand" "r")
5024 (match_operand 2 "const_int_operand")]
5025 UNSPECV_PLDGP2))]
5026 "TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF"
5027 "lda %0,0(%1)\t\t!gpdisp!%2\n$%~..ng:"
5028 [(set_attr "cannot_copy" "true")])
5029
5030 (define_insn "*prologue_ldgp_1"
5031 [(set (match_operand:DI 0 "register_operand" "=r")
5032 (unspec_volatile:DI [(match_operand:DI 1 "register_operand" "r")
5033 (match_operand 2 "const_int_operand")]
5034 UNSPECV_LDGP1))]
5035 ""
5036 "ldgp %0,0(%1)\n$%~..ng:"
5037 [(set_attr "cannot_copy" "true")])
5038
5039 (define_insn "*prologue_ldgp_2"
5040 [(set (match_operand:DI 0 "register_operand" "=r")
5041 (unspec_volatile:DI [(match_operand:DI 1 "register_operand" "r")
5042 (match_operand 2 "const_int_operand")]
5043 UNSPECV_PLDGP2))]
5044 ""
5045 )
5046
5047 ;; The _mcount profiling hook has special calling conventions, and
5048 ;; does not clobber all the registers that a normal call would. So
5049 ;; hide the fact this is a call at all.
5050
5051 (define_insn "prologue_mcount"
5052 [(unspec_volatile [(const_int 0)] UNSPECV_MCOUNT)]
5053 ""
5054 {
5055 if (TARGET_EXPLICIT_RELOCS)
5056 /* Note that we cannot use a lituse_jsr reloc, since _mcount
5057 cannot be called via the PLT. */
5058 return "ldq $28,_mcount($29)\t\t!literal\;jsr $28,($28),_mcount";
5059 else
5060 return "lda $28,_mcount\;jsr $28,($28),_mcount";
5061 }
5062 [(set_attr "type" "multi")
5063 (set_attr "length" "8")])
5064
5065 (define_insn "init_fp"
5066 [(set (match_operand:DI 0 "register_operand" "=r")
5067 (match_operand:DI 1 "register_operand" "r"))
5068 (clobber (mem:BLK (match_operand:DI 2 "register_operand" "=r")))]
5069 ""
5070 "bis $31,%1,%0")
5071
5072 (define_expand "epilogue"
5073 [(return)]
5074 ""
5075 "alpha_expand_epilogue ();")
5076
5077 (define_expand "sibcall_epilogue"
5078 [(return)]
5079 "TARGET_ABI_OSF"
5080 {
5081 alpha_expand_epilogue ();
5082 DONE;
5083 })
5084
5085 (define_expand "builtin_longjmp"
5086 [(use (match_operand:DI 0 "register_operand" "r"))]
5087 "TARGET_ABI_OSF"
5088 {
5089 /* The elements of the buffer are, in order: */
5090 rtx fp = gen_rtx_MEM (Pmode, operands[0]);
5091 rtx lab = gen_rtx_MEM (Pmode, plus_constant (Pmode, operands[0], 8));
5092 rtx stack = gen_rtx_MEM (Pmode, plus_constant (Pmode, operands[0], 16));
5093 rtx pv = gen_rtx_REG (Pmode, 27);
5094
5095 /* This bit is the same as expand_builtin_longjmp. */
5096 emit_move_insn (hard_frame_pointer_rtx, fp);
5097 emit_move_insn (pv, lab);
5098 emit_stack_restore (SAVE_NONLOCAL, stack);
5099 emit_use (hard_frame_pointer_rtx);
5100 emit_use (stack_pointer_rtx);
5101
5102 /* Load the label we are jumping through into $27 so that we know
5103 where to look for it when we get back to setjmp's function for
5104 restoring the gp. */
5105 emit_jump_insn (gen_builtin_longjmp_internal (pv));
5106 emit_barrier ();
5107 DONE;
5108 })
5109
5110 ;; This is effectively a copy of indirect_jump, but constrained such
5111 ;; that register renaming cannot foil our cunning plan with $27.
5112 (define_insn "builtin_longjmp_internal"
5113 [(set (pc)
5114 (unspec_volatile [(match_operand:DI 0 "register_operand" "c")]
5115 UNSPECV_LONGJMP))]
5116 ""
5117 "jmp $31,(%0),0"
5118 [(set_attr "type" "ibr")])
5119
5120 (define_expand "builtin_setjmp_receiver"
5121 [(unspec_volatile [(label_ref (match_operand 0))] UNSPECV_SETJMPR)]
5122 "TARGET_ABI_OSF")
5123
5124 (define_insn_and_split "*builtin_setjmp_receiver_1"
5125 [(unspec_volatile [(match_operand 0)] UNSPECV_SETJMPR)]
5126 "TARGET_ABI_OSF"
5127 {
5128 if (TARGET_EXPLICIT_RELOCS)
5129 return "#";
5130 else
5131 return "br $27,$LSJ%=\n$LSJ%=:\;ldgp $29,0($27)";
5132 }
5133 "&& TARGET_EXPLICIT_RELOCS && reload_completed"
5134 [(set (match_dup 1)
5135 (unspec_volatile:DI [(match_dup 2) (match_dup 3)] UNSPECV_LDGP1))
5136 (set (match_dup 1)
5137 (unspec:DI [(match_dup 1) (match_dup 3)] UNSPEC_LDGP2))]
5138 {
5139 if (prev_nonnote_insn (curr_insn) != XEXP (operands[0], 0))
5140 emit_insn (gen_rtx_UNSPEC_VOLATILE (VOIDmode, gen_rtvec (1, operands[0]),
5141 UNSPECV_SETJMPR_ER));
5142 operands[1] = pic_offset_table_rtx;
5143 operands[2] = gen_rtx_REG (Pmode, 27);
5144 operands[3] = GEN_INT (alpha_next_sequence_number++);
5145 }
5146 [(set_attr "length" "12")
5147 (set_attr "type" "multi")])
5148
5149 (define_insn "*builtin_setjmp_receiver_er_sl_1"
5150 [(unspec_volatile [(match_operand 0)] UNSPECV_SETJMPR_ER)]
5151 "TARGET_ABI_OSF && TARGET_EXPLICIT_RELOCS"
5152 "lda $27,$LSJ%=-%l0($27)\n$LSJ%=:")
5153
5154 ;; When flag_reorder_blocks_and_partition is in effect, compiler puts
5155 ;; exception landing pads in a cold section. To prevent inter-section offset
5156 ;; calculation, a jump to original landing pad is emitted in the place of the
5157 ;; original landing pad. Since landing pad is moved, RA-relative GP
5158 ;; calculation in the prologue of landing pad breaks. To solve this problem,
5159 ;; we use alternative GP load approach.
5160
5161 (define_expand "exception_receiver"
5162 [(unspec_volatile [(match_dup 0)] UNSPECV_EHR)]
5163 "TARGET_ABI_OSF"
5164 {
5165 if (flag_reorder_blocks_and_partition)
5166 operands[0] = alpha_gp_save_rtx ();
5167 else
5168 operands[0] = const0_rtx;
5169 })
5170
5171 (define_insn "*exception_receiver_2"
5172 [(unspec_volatile [(match_operand:DI 0 "memory_operand" "m")] UNSPECV_EHR)]
5173 "TARGET_ABI_OSF && flag_reorder_blocks_and_partition"
5174 "ldq $29,%0"
5175 [(set_attr "type" "ild")])
5176
5177 (define_insn_and_split "*exception_receiver_1"
5178 [(unspec_volatile [(const_int 0)] UNSPECV_EHR)]
5179 "TARGET_ABI_OSF"
5180 {
5181 if (TARGET_EXPLICIT_RELOCS)
5182 return "#";
5183 else
5184 return "ldgp $29,0($26)";
5185 }
5186 "&& TARGET_EXPLICIT_RELOCS && reload_completed"
5187 [(set (match_dup 0)
5188 (unspec_volatile:DI [(match_dup 1) (match_dup 2)] UNSPECV_LDGP1))
5189 (set (match_dup 0)
5190 (unspec:DI [(match_dup 0) (match_dup 2)] UNSPEC_LDGP2))]
5191 {
5192 operands[0] = pic_offset_table_rtx;
5193 operands[1] = gen_rtx_REG (Pmode, 26);
5194 operands[2] = GEN_INT (alpha_next_sequence_number++);
5195 }
5196 [(set_attr "length" "8")
5197 (set_attr "type" "multi")])
5198
5199 (define_expand "nonlocal_goto_receiver"
5200 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
5201 (set (reg:DI 27) (mem:DI (reg:DI 29)))
5202 (unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
5203 (use (reg:DI 27))]
5204 "TARGET_ABI_OPEN_VMS")
5205
5206 (define_insn "arg_home"
5207 [(unspec [(const_int 0)] UNSPEC_ARG_HOME)
5208 (use (reg:DI 1))
5209 (use (reg:DI 25))
5210 (use (reg:DI 16))
5211 (use (reg:DI 17))
5212 (use (reg:DI 18))
5213 (use (reg:DI 19))
5214 (use (reg:DI 20))
5215 (use (reg:DI 21))
5216 (use (reg:DI 48))
5217 (use (reg:DI 49))
5218 (use (reg:DI 50))
5219 (use (reg:DI 51))
5220 (use (reg:DI 52))
5221 (use (reg:DI 53))
5222 (clobber (mem:BLK (const_int 0)))
5223 (clobber (reg:DI 24))
5224 (clobber (reg:DI 25))
5225 (clobber (reg:DI 0))]
5226 "TARGET_ABI_OPEN_VMS"
5227 "lda $0,OTS$HOME_ARGS\;ldq $0,8($0)\;jsr $0,OTS$HOME_ARGS"
5228 [(set_attr "length" "16")
5229 (set_attr "type" "multi")])
5230
5231 ;; Prefetch data.
5232 ;;
5233 ;; On EV4, these instructions are nops -- no load occurs.
5234 ;;
5235 ;; On EV5, these instructions act as a normal load, and thus can trap
5236 ;; if the address is invalid. The OS may (or may not) handle this in
5237 ;; the entMM fault handler and suppress the fault. If so, then this
5238 ;; has the effect of a read prefetch instruction.
5239 ;;
5240 ;; On EV6, these become official prefetch instructions.
5241
5242 (define_insn "prefetch"
5243 [(prefetch (match_operand:DI 0 "address_operand" "p")
5244 (match_operand:DI 1 "const_int_operand" "n")
5245 (match_operand:DI 2 "const_int_operand" "n"))]
5246 "TARGET_FIXUP_EV5_PREFETCH || alpha_cpu == PROCESSOR_EV6"
5247 {
5248 /* Interpret "no temporal locality" as this data should be evicted once
5249 it is used. The "evict next" alternatives load the data into the cache
5250 and leave the LRU eviction counter pointing to that block. */
5251 static const char * const alt[2][2] = {
5252 {
5253 "ldq $31,%a0", /* read, evict next */
5254 "ldl $31,%a0", /* read, evict last */
5255 },
5256 {
5257 "ldt $f31,%a0", /* write, evict next */
5258 "lds $f31,%a0", /* write, evict last */
5259 }
5260 };
5261
5262 bool write = INTVAL (operands[1]) != 0;
5263 bool lru = INTVAL (operands[2]) != 0;
5264
5265 return alt[write][lru];
5266 }
5267 [(set_attr "type" "ild")])
5268
5269 ;; Close the trap shadow of preceding instructions. This is generated
5270 ;; by alpha_reorg.
5271
5272 (define_insn "trapb"
5273 [(unspec_volatile [(const_int 0)] UNSPECV_TRAPB)]
5274 ""
5275 "trapb"
5276 [(set_attr "type" "misc")])
5277
5278 ;; No-op instructions used by machine-dependent reorg to preserve
5279 ;; alignment for instruction issue.
5280 ;; The Unicos/Mk assembler does not support these opcodes.
5281
5282 (define_insn "nop"
5283 [(const_int 0)]
5284 ""
5285 "bis $31,$31,$31"
5286 [(set_attr "type" "ilog")])
5287
5288 (define_insn "fnop"
5289 [(const_int 1)]
5290 "TARGET_FP"
5291 "cpys $f31,$f31,$f31"
5292 [(set_attr "type" "fcpys")])
5293
5294 (define_insn "unop"
5295 [(const_int 2)]
5296 ""
5297 "ldq_u $31,0($30)")
5298
5299 (define_insn "realign"
5300 [(unspec_volatile [(match_operand 0 "immediate_operand" "i")]
5301 UNSPECV_REALIGN)]
5302 ""
5303 ".align %0 #realign")
5304
5306 ;; Instructions to be emitted from __builtins.
5307
5308 (define_insn "builtin_cmpbge"
5309 [(set (match_operand:DI 0 "register_operand" "=r")
5310 (unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "rJ")
5311 (match_operand:DI 2 "reg_or_8bit_operand" "rI")]
5312 UNSPEC_CMPBGE))]
5313 ""
5314 "cmpbge %r1,%2,%0"
5315 ;; The EV6 data sheets list this as ILOG. OTOH, EV6 doesn't
5316 ;; actually differentiate between ILOG and ICMP in the schedule.
5317 [(set_attr "type" "icmp")])
5318
5319 (define_expand "extbl"
5320 [(match_operand:DI 0 "register_operand")
5321 (match_operand:DI 1 "reg_or_0_operand")
5322 (match_operand:DI 2 "reg_or_8bit_operand")]
5323 ""
5324 {
5325 emit_insn (gen_extxl (operands[0], operands[1], GEN_INT (8), operands[2]));
5326 DONE;
5327 })
5328
5329 (define_expand "extwl"
5330 [(match_operand:DI 0 "register_operand")
5331 (match_operand:DI 1 "reg_or_0_operand")
5332 (match_operand:DI 2 "reg_or_8bit_operand")]
5333 ""
5334 {
5335 emit_insn (gen_extxl (operands[0], operands[1], GEN_INT (16), operands[2]));
5336 DONE;
5337 })
5338
5339 (define_expand "extll"
5340 [(match_operand:DI 0 "register_operand")
5341 (match_operand:DI 1 "reg_or_0_operand")
5342 (match_operand:DI 2 "reg_or_8bit_operand")]
5343 ""
5344 {
5345 emit_insn (gen_extxl (operands[0], operands[1], GEN_INT (32), operands[2]));
5346 DONE;
5347 })
5348
5349 (define_expand "extql"
5350 [(match_operand:DI 0 "register_operand")
5351 (match_operand:DI 1 "reg_or_0_operand")
5352 (match_operand:DI 2 "reg_or_8bit_operand")]
5353 ""
5354 {
5355 emit_insn (gen_extxl (operands[0], operands[1], GEN_INT (64), operands[2]));
5356 DONE;
5357 })
5358
5359 (define_expand "builtin_insbl"
5360 [(match_operand:DI 0 "register_operand")
5361 (match_operand:DI 1 "register_operand")
5362 (match_operand:DI 2 "reg_or_8bit_operand")]
5363 ""
5364 {
5365 operands[1] = gen_lowpart (QImode, operands[1]);
5366 emit_insn (gen_insbl (operands[0], operands[1], operands[2]));
5367 DONE;
5368 })
5369
5370 (define_expand "builtin_inswl"
5371 [(match_operand:DI 0 "register_operand")
5372 (match_operand:DI 1 "register_operand")
5373 (match_operand:DI 2 "reg_or_8bit_operand")]
5374 ""
5375 {
5376 operands[1] = gen_lowpart (HImode, operands[1]);
5377 emit_insn (gen_inswl (operands[0], operands[1], operands[2]));
5378 DONE;
5379 })
5380
5381 (define_expand "builtin_insll"
5382 [(match_operand:DI 0 "register_operand")
5383 (match_operand:DI 1 "register_operand")
5384 (match_operand:DI 2 "reg_or_8bit_operand")]
5385 ""
5386 {
5387 operands[1] = gen_lowpart (SImode, operands[1]);
5388 emit_insn (gen_insll (operands[0], operands[1], operands[2]));
5389 DONE;
5390 })
5391
5392 (define_expand "inswh"
5393 [(match_operand:DI 0 "register_operand")
5394 (match_operand:DI 1 "register_operand")
5395 (match_operand:DI 2 "reg_or_8bit_operand")]
5396 ""
5397 {
5398 emit_insn (gen_insxh (operands[0], operands[1], GEN_INT (16), operands[2]));
5399 DONE;
5400 })
5401
5402 (define_expand "inslh"
5403 [(match_operand:DI 0 "register_operand")
5404 (match_operand:DI 1 "register_operand")
5405 (match_operand:DI 2 "reg_or_8bit_operand")]
5406 ""
5407 {
5408 emit_insn (gen_insxh (operands[0], operands[1], GEN_INT (32), operands[2]));
5409 DONE;
5410 })
5411
5412 (define_expand "insqh"
5413 [(match_operand:DI 0 "register_operand")
5414 (match_operand:DI 1 "register_operand")
5415 (match_operand:DI 2 "reg_or_8bit_operand")]
5416 ""
5417 {
5418 emit_insn (gen_insxh (operands[0], operands[1], GEN_INT (64), operands[2]));
5419 DONE;
5420 })
5421
5422 (define_expand "mskbl"
5423 [(match_operand:DI 0 "register_operand")
5424 (match_operand:DI 1 "reg_or_0_operand")
5425 (match_operand:DI 2 "reg_or_8bit_operand")]
5426 ""
5427 {
5428 rtx mask = GEN_INT (0xff);
5429 emit_insn (gen_mskxl (operands[0], operands[1], mask, operands[2]));
5430 DONE;
5431 })
5432
5433 (define_expand "mskwl"
5434 [(match_operand:DI 0 "register_operand")
5435 (match_operand:DI 1 "reg_or_0_operand")
5436 (match_operand:DI 2 "reg_or_8bit_operand")]
5437 ""
5438 {
5439 rtx mask = GEN_INT (0xffff);
5440 emit_insn (gen_mskxl (operands[0], operands[1], mask, operands[2]));
5441 DONE;
5442 })
5443
5444 (define_expand "mskll"
5445 [(match_operand:DI 0 "register_operand")
5446 (match_operand:DI 1 "reg_or_0_operand")
5447 (match_operand:DI 2 "reg_or_8bit_operand")]
5448 ""
5449 {
5450 rtx mask = gen_int_mode (0xffffffff, DImode);
5451 emit_insn (gen_mskxl (operands[0], operands[1], mask, operands[2]));
5452 DONE;
5453 })
5454
5455 (define_expand "mskql"
5456 [(match_operand:DI 0 "register_operand")
5457 (match_operand:DI 1 "reg_or_0_operand")
5458 (match_operand:DI 2 "reg_or_8bit_operand")]
5459 ""
5460 {
5461 rtx mask = constm1_rtx;
5462 emit_insn (gen_mskxl (operands[0], operands[1], mask, operands[2]));
5463 DONE;
5464 })
5465
5466 (define_expand "mskwh"
5467 [(match_operand:DI 0 "register_operand")
5468 (match_operand:DI 1 "register_operand")
5469 (match_operand:DI 2 "reg_or_8bit_operand")]
5470 ""
5471 {
5472 emit_insn (gen_mskxh (operands[0], operands[1], GEN_INT (16), operands[2]));
5473 DONE;
5474 })
5475
5476 (define_expand "msklh"
5477 [(match_operand:DI 0 "register_operand")
5478 (match_operand:DI 1 "register_operand")
5479 (match_operand:DI 2 "reg_or_8bit_operand")]
5480 ""
5481 {
5482 emit_insn (gen_mskxh (operands[0], operands[1], GEN_INT (32), operands[2]));
5483 DONE;
5484 })
5485
5486 (define_expand "mskqh"
5487 [(match_operand:DI 0 "register_operand")
5488 (match_operand:DI 1 "register_operand")
5489 (match_operand:DI 2 "reg_or_8bit_operand")]
5490 ""
5491 {
5492 emit_insn (gen_mskxh (operands[0], operands[1], GEN_INT (64), operands[2]));
5493 DONE;
5494 })
5495
5496 (define_expand "builtin_zap"
5497 [(set (match_operand:DI 0 "register_operand")
5498 (and:DI (unspec:DI
5499 [(match_operand:DI 2 "reg_or_cint_operand")]
5500 UNSPEC_ZAP)
5501 (match_operand:DI 1 "reg_or_cint_operand")))]
5502 ""
5503 {
5504 if (CONST_INT_P (operands[2]))
5505 {
5506 rtx mask = alpha_expand_zap_mask (INTVAL (operands[2]));
5507
5508 if (mask == const0_rtx)
5509 {
5510 emit_move_insn (operands[0], const0_rtx);
5511 DONE;
5512 }
5513 if (mask == constm1_rtx)
5514 {
5515 emit_move_insn (operands[0], operands[1]);
5516 DONE;
5517 }
5518
5519 operands[1] = force_reg (DImode, operands[1]);
5520 emit_insn (gen_anddi3 (operands[0], operands[1], mask));
5521 DONE;
5522 }
5523
5524 operands[1] = force_reg (DImode, operands[1]);
5525 operands[2] = gen_lowpart (QImode, operands[2]);
5526 })
5527
5528 (define_insn "*builtin_zap_1"
5529 [(set (match_operand:DI 0 "register_operand" "=r,r,r,r")
5530 (and:DI (unspec:DI
5531 [(match_operand:QI 2 "reg_or_cint_operand" "n,n,r,r")]
5532 UNSPEC_ZAP)
5533 (match_operand:DI 1 "reg_or_cint_operand" "n,r,J,r")))]
5534 ""
5535 "@
5536 #
5537 #
5538 bis $31,$31,%0
5539 zap %r1,%2,%0"
5540 [(set_attr "type" "shift,shift,ilog,shift")])
5541
5542 (define_split
5543 [(set (match_operand:DI 0 "register_operand")
5544 (and:DI (unspec:DI
5545 [(match_operand:QI 2 "const_int_operand")]
5546 UNSPEC_ZAP)
5547 (match_operand:DI 1 "const_int_operand")))]
5548 ""
5549 [(const_int 0)]
5550 {
5551 rtx mask = alpha_expand_zap_mask (INTVAL (operands[2]));
5552
5553 operands[1] = gen_int_mode (INTVAL (operands[1]) & INTVAL (mask), DImode);
5554 emit_move_insn (operands[0], operands[1]);
5555 DONE;
5556 })
5557
5558 (define_split
5559 [(set (match_operand:DI 0 "register_operand")
5560 (and:DI (unspec:DI
5561 [(match_operand:QI 2 "const_int_operand")]
5562 UNSPEC_ZAP)
5563 (match_operand:DI 1 "register_operand")))]
5564 ""
5565 [(set (match_dup 0)
5566 (and:DI (match_dup 1) (match_dup 2)))]
5567 {
5568 operands[2] = alpha_expand_zap_mask (INTVAL (operands[2]));
5569 if (operands[2] == const0_rtx)
5570 {
5571 emit_move_insn (operands[0], const0_rtx);
5572 DONE;
5573 }
5574 if (operands[2] == constm1_rtx)
5575 {
5576 emit_move_insn (operands[0], operands[1]);
5577 DONE;
5578 }
5579 })
5580
5581 (define_expand "builtin_zapnot"
5582 [(set (match_operand:DI 0 "register_operand")
5583 (and:DI (unspec:DI
5584 [(not:QI (match_operand:DI 2 "reg_or_cint_operand"))]
5585 UNSPEC_ZAP)
5586 (match_operand:DI 1 "reg_or_cint_operand")))]
5587 ""
5588 {
5589 if (CONST_INT_P (operands[2]))
5590 {
5591 rtx mask = alpha_expand_zap_mask (~ INTVAL (operands[2]));
5592
5593 if (mask == const0_rtx)
5594 {
5595 emit_move_insn (operands[0], const0_rtx);
5596 DONE;
5597 }
5598 if (mask == constm1_rtx)
5599 {
5600 emit_move_insn (operands[0], operands[1]);
5601 DONE;
5602 }
5603
5604 operands[1] = force_reg (DImode, operands[1]);
5605 emit_insn (gen_anddi3 (operands[0], operands[1], mask));
5606 DONE;
5607 }
5608
5609 operands[1] = force_reg (DImode, operands[1]);
5610 operands[2] = gen_lowpart (QImode, operands[2]);
5611 })
5612
5613 (define_insn "*builtin_zapnot_1"
5614 [(set (match_operand:DI 0 "register_operand" "=r")
5615 (and:DI (unspec:DI
5616 [(not:QI (match_operand:QI 2 "register_operand" "r"))]
5617 UNSPEC_ZAP)
5618 (match_operand:DI 1 "reg_or_0_operand" "rJ")))]
5619 ""
5620 "zapnot %r1,%2,%0"
5621 [(set_attr "type" "shift")])
5622
5623 (define_insn "builtin_amask"
5624 [(set (match_operand:DI 0 "register_operand" "=r")
5625 (unspec:DI [(match_operand:DI 1 "reg_or_8bit_operand" "rI")]
5626 UNSPEC_AMASK))]
5627 ""
5628 "amask %1,%0"
5629 [(set_attr "type" "ilog")])
5630
5631 (define_insn "builtin_implver"
5632 [(set (match_operand:DI 0 "register_operand" "=r")
5633 (unspec:DI [(const_int 0)] UNSPEC_IMPLVER))]
5634 ""
5635 "implver %0"
5636 [(set_attr "type" "ilog")])
5637
5638 (define_insn "builtin_rpcc"
5639 [(set (match_operand:DI 0 "register_operand" "=r")
5640 (unspec_volatile:DI [(const_int 0)] UNSPECV_RPCC))]
5641 ""
5642 "rpcc %0"
5643 [(set_attr "type" "ilog")])
5644
5645 (define_expand "builtin_minub8"
5646 [(match_operand:DI 0 "register_operand")
5647 (match_operand:DI 1 "reg_or_0_operand")
5648 (match_operand:DI 2 "reg_or_0_operand")]
5649 "TARGET_MAX"
5650 {
5651 alpha_expand_builtin_vector_binop (gen_uminv8qi3, V8QImode, operands[0],
5652 operands[1], operands[2]);
5653 DONE;
5654 })
5655
5656 (define_expand "builtin_minsb8"
5657 [(match_operand:DI 0 "register_operand")
5658 (match_operand:DI 1 "reg_or_0_operand")
5659 (match_operand:DI 2 "reg_or_0_operand")]
5660 "TARGET_MAX"
5661 {
5662 alpha_expand_builtin_vector_binop (gen_sminv8qi3, V8QImode, operands[0],
5663 operands[1], operands[2]);
5664 DONE;
5665 })
5666
5667 (define_expand "builtin_minuw4"
5668 [(match_operand:DI 0 "register_operand")
5669 (match_operand:DI 1 "reg_or_0_operand")
5670 (match_operand:DI 2 "reg_or_0_operand")]
5671 "TARGET_MAX"
5672 {
5673 alpha_expand_builtin_vector_binop (gen_uminv4hi3, V4HImode, operands[0],
5674 operands[1], operands[2]);
5675 DONE;
5676 })
5677
5678 (define_expand "builtin_minsw4"
5679 [(match_operand:DI 0 "register_operand")
5680 (match_operand:DI 1 "reg_or_0_operand")
5681 (match_operand:DI 2 "reg_or_0_operand")]
5682 "TARGET_MAX"
5683 {
5684 alpha_expand_builtin_vector_binop (gen_sminv4hi3, V4HImode, operands[0],
5685 operands[1], operands[2]);
5686 DONE;
5687 })
5688
5689 (define_expand "builtin_maxub8"
5690 [(match_operand:DI 0 "register_operand")
5691 (match_operand:DI 1 "reg_or_0_operand")
5692 (match_operand:DI 2 "reg_or_0_operand")]
5693 "TARGET_MAX"
5694 {
5695 alpha_expand_builtin_vector_binop (gen_umaxv8qi3, V8QImode, operands[0],
5696 operands[1], operands[2]);
5697 DONE;
5698 })
5699
5700 (define_expand "builtin_maxsb8"
5701 [(match_operand:DI 0 "register_operand")
5702 (match_operand:DI 1 "reg_or_0_operand")
5703 (match_operand:DI 2 "reg_or_0_operand")]
5704 "TARGET_MAX"
5705 {
5706 alpha_expand_builtin_vector_binop (gen_smaxv8qi3, V8QImode, operands[0],
5707 operands[1], operands[2]);
5708 DONE;
5709 })
5710
5711 (define_expand "builtin_maxuw4"
5712 [(match_operand:DI 0 "register_operand")
5713 (match_operand:DI 1 "reg_or_0_operand")
5714 (match_operand:DI 2 "reg_or_0_operand")]
5715 "TARGET_MAX"
5716 {
5717 alpha_expand_builtin_vector_binop (gen_umaxv4hi3, V4HImode, operands[0],
5718 operands[1], operands[2]);
5719 DONE;
5720 })
5721
5722 (define_expand "builtin_maxsw4"
5723 [(match_operand:DI 0 "register_operand")
5724 (match_operand:DI 1 "reg_or_0_operand")
5725 (match_operand:DI 2 "reg_or_0_operand")]
5726 "TARGET_MAX"
5727 {
5728 alpha_expand_builtin_vector_binop (gen_smaxv4hi3, V4HImode, operands[0],
5729 operands[1], operands[2]);
5730 DONE;
5731 })
5732
5733 (define_insn "builtin_perr"
5734 [(set (match_operand:DI 0 "register_operand" "=r")
5735 (unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "%rJ")
5736 (match_operand:DI 2 "reg_or_8bit_operand" "rJ")]
5737 UNSPEC_PERR))]
5738 "TARGET_MAX"
5739 "perr %r1,%r2,%0"
5740 [(set_attr "type" "mvi")])
5741
5742 (define_expand "builtin_pklb"
5743 [(set (match_operand:DI 0 "register_operand")
5744 (vec_concat:V8QI
5745 (vec_concat:V4QI
5746 (truncate:V2QI (match_operand:DI 1 "register_operand"))
5747 (match_dup 2))
5748 (match_dup 3)))]
5749 "TARGET_MAX"
5750 {
5751 operands[0] = gen_lowpart (V8QImode, operands[0]);
5752 operands[1] = gen_lowpart (V2SImode, operands[1]);
5753 operands[2] = CONST0_RTX (V2QImode);
5754 operands[3] = CONST0_RTX (V4QImode);
5755 })
5756
5757 (define_insn "*pklb"
5758 [(set (match_operand:V8QI 0 "register_operand" "=r")
5759 (vec_concat:V8QI
5760 (vec_concat:V4QI
5761 (truncate:V2QI (match_operand:V2SI 1 "register_operand" "r"))
5762 (match_operand:V2QI 2 "const0_operand"))
5763 (match_operand:V4QI 3 "const0_operand")))]
5764 "TARGET_MAX"
5765 "pklb %r1,%0"
5766 [(set_attr "type" "mvi")])
5767
5768 (define_expand "builtin_pkwb"
5769 [(set (match_operand:DI 0 "register_operand")
5770 (vec_concat:V8QI
5771 (truncate:V4QI (match_operand:DI 1 "register_operand"))
5772 (match_dup 2)))]
5773 "TARGET_MAX"
5774 {
5775 operands[0] = gen_lowpart (V8QImode, operands[0]);
5776 operands[1] = gen_lowpart (V4HImode, operands[1]);
5777 operands[2] = CONST0_RTX (V4QImode);
5778 })
5779
5780 (define_insn "*pkwb"
5781 [(set (match_operand:V8QI 0 "register_operand" "=r")
5782 (vec_concat:V8QI
5783 (truncate:V4QI (match_operand:V4HI 1 "register_operand" "r"))
5784 (match_operand:V4QI 2 "const0_operand")))]
5785 "TARGET_MAX"
5786 "pkwb %r1,%0"
5787 [(set_attr "type" "mvi")])
5788
5789 (define_expand "builtin_unpkbl"
5790 [(set (match_operand:DI 0 "register_operand")
5791 (zero_extend:V2SI
5792 (vec_select:V2QI (match_operand:DI 1 "register_operand")
5793 (parallel [(const_int 0) (const_int 1)]))))]
5794 "TARGET_MAX"
5795 {
5796 operands[0] = gen_lowpart (V2SImode, operands[0]);
5797 operands[1] = gen_lowpart (V8QImode, operands[1]);
5798 })
5799
5800 (define_insn "*unpkbl"
5801 [(set (match_operand:V2SI 0 "register_operand" "=r")
5802 (zero_extend:V2SI
5803 (vec_select:V2QI (match_operand:V8QI 1 "reg_or_0_operand" "rW")
5804 (parallel [(const_int 0) (const_int 1)]))))]
5805 "TARGET_MAX"
5806 "unpkbl %r1,%0"
5807 [(set_attr "type" "mvi")])
5808
5809 (define_expand "builtin_unpkbw"
5810 [(set (match_operand:DI 0 "register_operand")
5811 (zero_extend:V4HI
5812 (vec_select:V4QI (match_operand:DI 1 "register_operand")
5813 (parallel [(const_int 0)
5814 (const_int 1)
5815 (const_int 2)
5816 (const_int 3)]))))]
5817 "TARGET_MAX"
5818 {
5819 operands[0] = gen_lowpart (V4HImode, operands[0]);
5820 operands[1] = gen_lowpart (V8QImode, operands[1]);
5821 })
5822
5823 (define_insn "*unpkbw"
5824 [(set (match_operand:V4HI 0 "register_operand" "=r")
5825 (zero_extend:V4HI
5826 (vec_select:V4QI (match_operand:V8QI 1 "reg_or_0_operand" "rW")
5827 (parallel [(const_int 0)
5828 (const_int 1)
5829 (const_int 2)
5830 (const_int 3)]))))]
5831 "TARGET_MAX"
5832 "unpkbw %r1,%0"
5833 [(set_attr "type" "mvi")])
5834
5836 (include "sync.md")
5837
5839 ;; The call patterns are at the end of the file because their
5840 ;; wildcard operand0 interferes with nice recognition.
5841
5842 (define_insn "*call_value_osf_1_er_noreturn"
5843 [(set (match_operand 0)
5844 (call (mem:DI (match_operand:DI 1 "call_operand" "c,R,s"))
5845 (match_operand 2)))
5846 (use (reg:DI 29))
5847 (clobber (reg:DI 26))]
5848 "TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF
5849 && find_reg_note (insn, REG_NORETURN, NULL_RTX)"
5850 "@
5851 jsr $26,($27),0
5852 bsr $26,%1\t\t!samegp
5853 ldq $27,%1($29)\t\t!literal!%#\;jsr $26,($27),%1\t\t!lituse_jsr!%#"
5854 [(set_attr "type" "jsr")
5855 (set_attr "length" "*,*,8")])
5856
5857 (define_insn "*call_value_osf_1_er"
5858 [(set (match_operand 0)
5859 (call (mem:DI (match_operand:DI 1 "call_operand" "c,R,s"))
5860 (match_operand 2)))
5861 (use (reg:DI 29))
5862 (clobber (reg:DI 26))]
5863 "TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF"
5864 "@
5865 jsr $26,(%1),0\;ldah $29,0($26)\t\t!gpdisp!%*\;lda $29,0($29)\t\t!gpdisp!%*
5866 bsr $26,%1\t\t!samegp
5867 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!%*"
5868 [(set_attr "type" "jsr")
5869 (set_attr "length" "12,*,16")])
5870
5871 ;; We must use peep2 instead of a split because we need accurate life
5872 ;; information for $gp. Consider the case of { bar(); while (1); }.
5873 (define_peephole2
5874 [(parallel [(set (match_operand 0)
5875 (call (mem:DI (match_operand:DI 1 "call_operand"))
5876 (match_operand 2)))
5877 (use (reg:DI 29))
5878 (clobber (reg:DI 26))])]
5879 "TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF && reload_completed
5880 && ! samegp_function_operand (operands[1], Pmode)
5881 && (peep2_regno_dead_p (1, 29)
5882 || find_reg_note (insn, REG_NORETURN, NULL_RTX))"
5883 [(parallel [(set (match_dup 0)
5884 (call (mem:DI (match_dup 3))
5885 (match_dup 2)))
5886 (use (reg:DI 29))
5887 (use (match_dup 1))
5888 (use (match_dup 4))
5889 (clobber (reg:DI 26))])]
5890 {
5891 if (CONSTANT_P (operands[1]))
5892 {
5893 operands[3] = gen_rtx_REG (Pmode, 27);
5894 operands[4] = GEN_INT (alpha_next_sequence_number++);
5895 emit_insn (gen_movdi_er_high_g (operands[3], pic_offset_table_rtx,
5896 operands[1], operands[4]));
5897 }
5898 else
5899 {
5900 operands[3] = operands[1];
5901 operands[1] = const0_rtx;
5902 operands[4] = const0_rtx;
5903 }
5904 })
5905
5906 (define_peephole2
5907 [(parallel [(set (match_operand 0)
5908 (call (mem:DI (match_operand:DI 1 "call_operand"))
5909 (match_operand 2)))
5910 (use (reg:DI 29))
5911 (clobber (reg:DI 26))])]
5912 "TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF && reload_completed
5913 && ! samegp_function_operand (operands[1], Pmode)
5914 && ! (peep2_regno_dead_p (1, 29)
5915 || find_reg_note (insn, REG_NORETURN, NULL_RTX))"
5916 [(parallel [(set (match_dup 0)
5917 (call (mem:DI (match_dup 3))
5918 (match_dup 2)))
5919 (set (match_dup 6)
5920 (unspec:DI [(match_dup 6) (match_dup 4)] UNSPEC_LDGP1))
5921 (use (match_dup 1))
5922 (use (match_dup 5))
5923 (clobber (reg:DI 26))])
5924 (set (match_dup 6)
5925 (unspec:DI [(match_dup 6) (match_dup 4)] UNSPEC_LDGP2))]
5926 {
5927 if (CONSTANT_P (operands[1]))
5928 {
5929 operands[3] = gen_rtx_REG (Pmode, 27);
5930 operands[5] = GEN_INT (alpha_next_sequence_number++);
5931 emit_insn (gen_movdi_er_high_g (operands[3], pic_offset_table_rtx,
5932 operands[1], operands[5]));
5933 }
5934 else
5935 {
5936 operands[3] = operands[1];
5937 operands[1] = const0_rtx;
5938 operands[5] = const0_rtx;
5939 }
5940 operands[4] = GEN_INT (alpha_next_sequence_number++);
5941 operands[6] = pic_offset_table_rtx;
5942 })
5943
5944 (define_insn "*call_value_osf_2_er_nogp"
5945 [(set (match_operand 0)
5946 (call (mem:DI (match_operand:DI 1 "register_operand" "c"))
5947 (match_operand 2)))
5948 (use (reg:DI 29))
5949 (use (match_operand 3))
5950 (use (match_operand 4))
5951 (clobber (reg:DI 26))]
5952 "TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF"
5953 "jsr $26,(%1),%3%J4"
5954 [(set_attr "type" "jsr")])
5955
5956 (define_insn "*call_value_osf_2_er"
5957 [(set (match_operand 0)
5958 (call (mem:DI (match_operand:DI 1 "register_operand" "c"))
5959 (match_operand 2)))
5960 (set (reg:DI 29)
5961 (unspec:DI [(reg:DI 29) (match_operand 5 "const_int_operand")]
5962 UNSPEC_LDGP1))
5963 (use (match_operand 3))
5964 (use (match_operand 4))
5965 (clobber (reg:DI 26))]
5966 "TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF"
5967 "jsr $26,(%1),%3%J4\;ldah $29,0($26)\t\t!gpdisp!%5"
5968 [(set_attr "type" "jsr")
5969 (set_attr "cannot_copy" "true")
5970 (set_attr "length" "8")])
5971
5972 (define_insn "*call_value_osf_1_noreturn"
5973 [(set (match_operand 0)
5974 (call (mem:DI (match_operand:DI 1 "call_operand" "c,R,s"))
5975 (match_operand 2)))
5976 (use (reg:DI 29))
5977 (clobber (reg:DI 26))]
5978 "! TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF
5979 && find_reg_note (insn, REG_NORETURN, NULL_RTX)"
5980 "@
5981 jsr $26,($27),0
5982 bsr $26,$%1..ng
5983 jsr $26,%1"
5984 [(set_attr "type" "jsr")
5985 (set_attr "length" "*,*,8")])
5986
5987 (define_int_iterator TLS_CALL
5988 [UNSPEC_TLSGD_CALL
5989 UNSPEC_TLSLDM_CALL])
5990
5991 (define_int_attr tls
5992 [(UNSPEC_TLSGD_CALL "tlsgd")
5993 (UNSPEC_TLSLDM_CALL "tlsldm")])
5994
5995 (define_insn "call_value_osf_<tls>"
5996 [(set (match_operand 0)
5997 (call (mem:DI (match_operand:DI 1 "symbolic_operand"))
5998 (const_int 0)))
5999 (unspec [(match_operand:DI 2 "const_int_operand")] TLS_CALL)
6000 (use (reg:DI 29))
6001 (clobber (reg:DI 26))]
6002 "HAVE_AS_TLS"
6003 "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!%*"
6004 [(set_attr "type" "jsr")
6005 (set_attr "length" "16")])
6006
6007 ;; We must use peep2 instead of a split because we need accurate life
6008 ;; information for $gp.
6009 (define_peephole2
6010 [(parallel
6011 [(set (match_operand 0)
6012 (call (mem:DI (match_operand:DI 1 "symbolic_operand"))
6013 (const_int 0)))
6014 (unspec [(match_operand:DI 2 "const_int_operand")] TLS_CALL)
6015 (use (reg:DI 29))
6016 (clobber (reg:DI 26))])]
6017 "HAVE_AS_TLS && reload_completed
6018 && peep2_regno_dead_p (1, 29)"
6019 [(set (match_dup 3)
6020 (unspec:DI [(match_dup 5)
6021 (match_dup 1)
6022 (match_dup 2)] UNSPEC_LITERAL))
6023 (parallel [(set (match_dup 0)
6024 (call (mem:DI (match_dup 3))
6025 (const_int 0)))
6026 (use (match_dup 5))
6027 (use (match_dup 1))
6028 (use (unspec [(match_dup 2)] TLS_CALL))
6029 (clobber (reg:DI 26))])
6030 (set (match_dup 5)
6031 (unspec:DI [(match_dup 5) (match_dup 4)] UNSPEC_LDGP2))]
6032 {
6033 operands[3] = gen_rtx_REG (Pmode, 27);
6034 operands[4] = GEN_INT (alpha_next_sequence_number++);
6035 operands[5] = pic_offset_table_rtx;
6036 })
6037
6038 (define_peephole2
6039 [(parallel
6040 [(set (match_operand 0)
6041 (call (mem:DI (match_operand:DI 1 "symbolic_operand"))
6042 (const_int 0)))
6043 (unspec [(match_operand:DI 2 "const_int_operand")] TLS_CALL)
6044 (use (reg:DI 29))
6045 (clobber (reg:DI 26))])]
6046 "HAVE_AS_TLS && reload_completed
6047 && !peep2_regno_dead_p (1, 29)"
6048 [(set (match_dup 3)
6049 (unspec:DI [(match_dup 5)
6050 (match_dup 1)
6051 (match_dup 2)] UNSPEC_LITERAL))
6052 (parallel [(set (match_dup 0)
6053 (call (mem:DI (match_dup 3))
6054 (const_int 0)))
6055 (set (match_dup 5)
6056 (unspec:DI [(match_dup 5) (match_dup 4)] UNSPEC_LDGP1))
6057 (use (match_dup 1))
6058 (use (unspec [(match_dup 2)] TLS_CALL))
6059 (clobber (reg:DI 26))])
6060 (set (match_dup 5)
6061 (unspec:DI [(match_dup 5) (match_dup 4)] UNSPEC_LDGP2))]
6062 {
6063 operands[3] = gen_rtx_REG (Pmode, 27);
6064 operands[4] = GEN_INT (alpha_next_sequence_number++);
6065 operands[5] = pic_offset_table_rtx;
6066 })
6067
6068 (define_insn "*call_value_osf_1"
6069 [(set (match_operand 0)
6070 (call (mem:DI (match_operand:DI 1 "call_operand" "c,R,s"))
6071 (match_operand 2)))
6072 (use (reg:DI 29))
6073 (clobber (reg:DI 26))]
6074 "! TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF"
6075 "@
6076 jsr $26,($27),0\;ldgp $29,0($26)
6077 bsr $26,$%1..ng
6078 jsr $26,%1\;ldgp $29,0($26)"
6079 [(set_attr "type" "jsr")
6080 (set_attr "length" "12,*,16")])
6081
6082 (define_insn "*sibcall_value_osf_1_er"
6083 [(set (match_operand 0)
6084 (call (mem:DI (match_operand:DI 1 "symbolic_operand" "R,s"))
6085 (match_operand 2)))
6086 (unspec [(reg:DI 29)] UNSPEC_SIBCALL)]
6087 "TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF"
6088 "@
6089 br $31,%1\t\t!samegp
6090 ldq $27,%1($29)\t\t!literal!%#\;jmp $31,($27),%1\t\t!lituse_jsr!%#"
6091 [(set_attr "type" "jsr")
6092 (set_attr "length" "*,8")])
6093
6094 (define_insn "*sibcall_value_osf_1"
6095 [(set (match_operand 0)
6096 (call (mem:DI (match_operand:DI 1 "symbolic_operand" "R,s"))
6097 (match_operand 2)))
6098 (unspec [(reg:DI 29)] UNSPEC_SIBCALL)]
6099 "! TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF"
6100 "@
6101 br $31,$%1..ng
6102 lda $27,%1\;jmp $31,($27),%1"
6103 [(set_attr "type" "jsr")
6104 (set_attr "length" "*,8")])
6105
6106 ; GAS relies on the order and position of instructions output below in order
6107 ; to generate relocs for VMS link to potentially optimize the call.
6108 ; Please do not molest.
6109 (define_insn "*call_value_vms_1"
6110 [(set (match_operand 0)
6111 (call (mem:DI (match_operand:DI 1 "call_operand" "r,s"))
6112 (match_operand 2)))
6113 (use (match_operand:DI 3 "nonmemory_operand" "r,n"))
6114 (use (reg:DI 25))
6115 (use (reg:DI 26))
6116 (clobber (reg:DI 27))]
6117 "TARGET_ABI_OPEN_VMS"
6118 {
6119 switch (which_alternative)
6120 {
6121 case 0:
6122 return "mov %3,$27\;jsr $26,0\;ldq $27,0($29)";
6123 case 1:
6124 operands [3] = alpha_use_linkage (operands [1], true, false);
6125 operands [4] = alpha_use_linkage (operands [1], false, false);
6126 return "ldq $26,%4\;ldq $27,%3\;jsr $26,%1\;ldq $27,0($29)";
6127 default:
6128 gcc_unreachable ();
6129 }
6130 }
6131 [(set_attr "type" "jsr")
6132 (set_attr "length" "12,16")])
6133