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