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