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