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