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