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