xref: /openbsd/gnu/gcc/gcc/config/alpha/alpha.md (revision 7014c930)
1404b540aSrobert;; Machine description for DEC Alpha for GNU C compiler
2404b540aSrobert;; Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
3404b540aSrobert;; 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
4404b540aSrobert;; Contributed by Richard Kenner (kenner@vlsi1.ultra.nyu.edu)
5404b540aSrobert;;
6404b540aSrobert;; This file is part of GCC.
7404b540aSrobert;;
8404b540aSrobert;; GCC is free software; you can redistribute it and/or modify
9404b540aSrobert;; it under the terms of the GNU General Public License as published by
10404b540aSrobert;; the Free Software Foundation; either version 2, or (at your option)
11404b540aSrobert;; any later version.
12404b540aSrobert;;
13404b540aSrobert;; GCC is distributed in the hope that it will be useful,
14404b540aSrobert;; but WITHOUT ANY WARRANTY; without even the implied warranty of
15404b540aSrobert;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16404b540aSrobert;; GNU General Public License for more details.
17404b540aSrobert;;
18404b540aSrobert;; You should have received a copy of the GNU General Public License
19404b540aSrobert;; along with GCC; see the file COPYING.  If not, write to
20404b540aSrobert;; the Free Software Foundation, 51 Franklin Street, Fifth Floor,
21404b540aSrobert;; Boston, MA 02110-1301, USA.
22404b540aSrobert
23404b540aSrobert;;- See file "rtl.def" for documentation on define_insn, match_*, et. al.
24404b540aSrobert
25404b540aSrobert;; Uses of UNSPEC in this file:
26404b540aSrobert
27404b540aSrobert(define_constants
28404b540aSrobert  [(UNSPEC_ARG_HOME	0)
29404b540aSrobert   (UNSPEC_INSXH	2)
30404b540aSrobert   (UNSPEC_MSKXH	3)
31404b540aSrobert   (UNSPEC_CVTQL	4)
32404b540aSrobert   (UNSPEC_CVTLQ	5)
33404b540aSrobert   (UNSPEC_UMK_LAUM	6)
34404b540aSrobert   (UNSPEC_UMK_LALM	7)
35404b540aSrobert   (UNSPEC_UMK_LAL	8)
36404b540aSrobert   (UNSPEC_UMK_LOAD_CIW	9)
37404b540aSrobert   (UNSPEC_LDGP2	10)
38404b540aSrobert   (UNSPEC_LITERAL	11)
39404b540aSrobert   (UNSPEC_LITUSE	12)
40404b540aSrobert   (UNSPEC_SIBCALL	13)
41404b540aSrobert   (UNSPEC_SYMBOL	14)
42404b540aSrobert
43404b540aSrobert   ;; TLS Support
44404b540aSrobert   (UNSPEC_TLSGD_CALL	15)
45404b540aSrobert   (UNSPEC_TLSLDM_CALL	16)
46404b540aSrobert   (UNSPEC_TLSGD	17)
47404b540aSrobert   (UNSPEC_TLSLDM	18)
48404b540aSrobert   (UNSPEC_DTPREL	19)
49404b540aSrobert   (UNSPEC_TPREL	20)
50404b540aSrobert   (UNSPEC_TP		21)
51404b540aSrobert
52404b540aSrobert   ;; Builtins
53404b540aSrobert   (UNSPEC_CMPBGE	22)
54404b540aSrobert   (UNSPEC_ZAP		23)
55404b540aSrobert   (UNSPEC_AMASK	24)
56404b540aSrobert   (UNSPEC_IMPLVER	25)
57404b540aSrobert   (UNSPEC_PERR		26)
58404b540aSrobert   (UNSPEC_COPYSIGN     27)
59404b540aSrobert
60404b540aSrobert   ;; Atomic operations
61404b540aSrobert   (UNSPEC_MB		28)
62404b540aSrobert   (UNSPEC_ATOMIC	31)
63404b540aSrobert   (UNSPEC_CMPXCHG	32)
64404b540aSrobert   (UNSPEC_XCHG		33)
65404b540aSrobert  ])
66404b540aSrobert
67404b540aSrobert;; UNSPEC_VOLATILE:
68404b540aSrobert
69404b540aSrobert(define_constants
70404b540aSrobert  [(UNSPECV_IMB		0)
71404b540aSrobert   (UNSPECV_BLOCKAGE	1)
72404b540aSrobert   (UNSPECV_SETJMPR	2)	; builtin_setjmp_receiver
73404b540aSrobert   (UNSPECV_LONGJMP	3)	; builtin_longjmp
74404b540aSrobert   (UNSPECV_TRAPB	4)
75404b540aSrobert   (UNSPECV_PSPL	5)	; prologue_stack_probe_loop
76404b540aSrobert   (UNSPECV_REALIGN	6)
77404b540aSrobert   (UNSPECV_EHR		7)	; exception_receiver
78404b540aSrobert   (UNSPECV_MCOUNT	8)
79404b540aSrobert   (UNSPECV_FORCE_MOV	9)
80404b540aSrobert   (UNSPECV_LDGP1	10)
81404b540aSrobert   (UNSPECV_PLDGP2	11)	; prologue ldgp
82404b540aSrobert   (UNSPECV_SET_TP	12)
83404b540aSrobert   (UNSPECV_RPCC	13)
84404b540aSrobert   (UNSPECV_SETJMPR_ER	14)	; builtin_setjmp_receiver fragment
85404b540aSrobert   (UNSPECV_LL		15)	; load-locked
86404b540aSrobert   (UNSPECV_SC		16)	; store-conditional
87404b540aSrobert  ])
88404b540aSrobert
89404b540aSrobert;; Where necessary, the suffixes _le and _be are used to distinguish between
90404b540aSrobert;; little-endian and big-endian patterns.
91404b540aSrobert;;
92404b540aSrobert;; Note that the Unicos/Mk assembler does not support the following
93404b540aSrobert;; opcodes: mov, fmov, nop, fnop, unop.
94404b540aSrobert
95404b540aSrobert;; Processor type -- this attribute must exactly match the processor_type
96404b540aSrobert;; enumeration in alpha.h.
97404b540aSrobert
98404b540aSrobert(define_attr "tune" "ev4,ev5,ev6"
99404b540aSrobert  (const (symbol_ref "alpha_tune")))
100404b540aSrobert
101404b540aSrobert;; Define an insn type attribute.  This is used in function unit delay
102404b540aSrobert;; computations, among other purposes.  For the most part, we use the names
103404b540aSrobert;; defined in the EV4 documentation, but add a few that we have to know about
104404b540aSrobert;; separately.
105404b540aSrobert
106404b540aSrobert(define_attr "type"
107404b540aSrobert  "ild,fld,ldsym,ist,fst,ibr,callpal,fbr,jsr,iadd,ilog,shift,icmov,fcmov,
108404b540aSrobert   icmp,imul,fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,mb,ld_l,st_c,
109404b540aSrobert   multi,none"
110404b540aSrobert  (const_string "iadd"))
111404b540aSrobert
112404b540aSrobert;; Describe a user's asm statement.
113404b540aSrobert(define_asm_attributes
114404b540aSrobert  [(set_attr "type" "multi")])
115404b540aSrobert
116404b540aSrobert;; Define the operand size an insn operates on.  Used primarily by mul
117404b540aSrobert;; and div operations that have size dependent timings.
118404b540aSrobert
119404b540aSrobert(define_attr "opsize" "si,di,udi"
120404b540aSrobert  (const_string "di"))
121404b540aSrobert
122404b540aSrobert;; The TRAP attribute marks instructions that may generate traps
123404b540aSrobert;; (which are imprecise and may need a trapb if software completion
124404b540aSrobert;; is desired).
125404b540aSrobert
126404b540aSrobert(define_attr "trap" "no,yes"
127404b540aSrobert  (const_string "no"))
128404b540aSrobert
129404b540aSrobert;; The ROUND_SUFFIX attribute marks which instructions require a
130404b540aSrobert;; rounding-mode suffix.  The value NONE indicates no suffix,
131404b540aSrobert;; the value NORMAL indicates a suffix controlled by alpha_fprm.
132404b540aSrobert
133404b540aSrobert(define_attr "round_suffix" "none,normal,c"
134404b540aSrobert  (const_string "none"))
135404b540aSrobert
136404b540aSrobert;; The TRAP_SUFFIX attribute marks instructions requiring a trap-mode suffix:
137404b540aSrobert;;   NONE	no suffix
138404b540aSrobert;;   SU		accepts only /su (cmpt et al)
139404b540aSrobert;;   SUI	accepts only /sui (cvtqt and cvtqs)
140404b540aSrobert;;   V_SV	accepts /v and /sv (cvtql only)
141404b540aSrobert;;   V_SV_SVI	accepts /v, /sv and /svi (cvttq only)
142404b540aSrobert;;   U_SU_SUI	accepts /u, /su and /sui (most fp instructions)
143404b540aSrobert;;
144404b540aSrobert;; The actual suffix emitted is controlled by alpha_fptm.
145404b540aSrobert
146404b540aSrobert(define_attr "trap_suffix" "none,su,sui,v_sv,v_sv_svi,u_su_sui"
147404b540aSrobert  (const_string "none"))
148404b540aSrobert
149404b540aSrobert;; The length of an instruction sequence in bytes.
150404b540aSrobert
151404b540aSrobert(define_attr "length" ""
152404b540aSrobert  (const_int 4))
153404b540aSrobert
154404b540aSrobert;; The USEGP attribute marks instructions that have relocations that use
155404b540aSrobert;; the GP.
156404b540aSrobert
157404b540aSrobert(define_attr "usegp" "no,yes"
158404b540aSrobert  (cond [(eq_attr "type" "ldsym,jsr")
159404b540aSrobert	   (const_string "yes")
160404b540aSrobert	 (eq_attr "type" "ild,fld,ist,fst")
161404b540aSrobert	   (symbol_ref "alpha_find_lo_sum_using_gp(insn)")
162404b540aSrobert	]
163404b540aSrobert	(const_string "no")))
164404b540aSrobert
165404b540aSrobert;; The CANNOT_COPY attribute marks instructions with relocations that
166404b540aSrobert;; cannot easily be duplicated.  This includes insns with gpdisp relocs
167404b540aSrobert;; since they have to stay in 1-1 correspondence with one another.  This
168404b540aSrobert;; also includes jsr insns, since they must stay in correspondence with
169404b540aSrobert;; the immediately following gpdisp instructions.
170404b540aSrobert
171404b540aSrobert(define_attr "cannot_copy" "false,true"
172404b540aSrobert  (const_string "false"))
173404b540aSrobert
174404b540aSrobert;; Include scheduling descriptions.
175404b540aSrobert
176404b540aSrobert(include "ev4.md")
177404b540aSrobert(include "ev5.md")
178404b540aSrobert(include "ev6.md")
179404b540aSrobert
180404b540aSrobert
181404b540aSrobert;; Include predicate definitions
182404b540aSrobert
183404b540aSrobert(include "predicates.md")
184404b540aSrobert
185404b540aSrobert
186404b540aSrobert;; First define the arithmetic insns.  Note that the 32-bit forms also
187404b540aSrobert;; sign-extend.
188404b540aSrobert
189404b540aSrobert;; Handle 32-64 bit extension from memory to a floating point register
190404b540aSrobert;; specially, since this occurs frequently in int->double conversions.
191404b540aSrobert;;
192404b540aSrobert;; Note that while we must retain the =f case in the insn for reload's
193404b540aSrobert;; benefit, it should be eliminated after reload, so we should never emit
194404b540aSrobert;; code for that case.  But we don't reject the possibility.
195404b540aSrobert
196404b540aSrobert(define_expand "extendsidi2"
197404b540aSrobert  [(set (match_operand:DI 0 "register_operand" "")
198404b540aSrobert	(sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "")))]
199404b540aSrobert  ""
200404b540aSrobert  "")
201404b540aSrobert
202404b540aSrobert(define_insn "*cvtlq"
203404b540aSrobert  [(set (match_operand:DI 0 "register_operand" "=f")
204404b540aSrobert	(unspec:DI [(match_operand:SF 1 "reg_or_0_operand" "fG")]
205404b540aSrobert		   UNSPEC_CVTLQ))]
206404b540aSrobert  ""
207404b540aSrobert  "cvtlq %1,%0"
208404b540aSrobert  [(set_attr "type" "fadd")])
209404b540aSrobert
210404b540aSrobert(define_insn "*extendsidi2_1"
211404b540aSrobert  [(set (match_operand:DI 0 "register_operand" "=r,r,!*f")
212404b540aSrobert	(sign_extend:DI
213404b540aSrobert	  (match_operand:SI 1 "nonimmediate_operand" "r,m,m")))]
214404b540aSrobert  ""
215404b540aSrobert  "@
216404b540aSrobert   addl $31,%1,%0
217404b540aSrobert   ldl %0,%1
218404b540aSrobert   lds %0,%1\;cvtlq %0,%0"
219404b540aSrobert  [(set_attr "type" "iadd,ild,fld")
220404b540aSrobert   (set_attr "length" "*,*,8")])
221404b540aSrobert
222404b540aSrobert(define_split
223404b540aSrobert  [(set (match_operand:DI 0 "hard_fp_register_operand" "")
224404b540aSrobert	(sign_extend:DI (match_operand:SI 1 "memory_operand" "")))]
225404b540aSrobert  "reload_completed"
226404b540aSrobert  [(set (match_dup 2) (match_dup 1))
227404b540aSrobert   (set (match_dup 0) (unspec:DI [(match_dup 2)] UNSPEC_CVTLQ))]
228404b540aSrobert{
229404b540aSrobert  operands[1] = adjust_address (operands[1], SFmode, 0);
230404b540aSrobert  operands[2] = gen_rtx_REG (SFmode, REGNO (operands[0]));
231404b540aSrobert})
232404b540aSrobert
233404b540aSrobert;; Optimize sign-extension of SImode loads.  This shows up in the wake of
234404b540aSrobert;; reload when converting fp->int.
235404b540aSrobert
236404b540aSrobert(define_peephole2
237404b540aSrobert  [(set (match_operand:SI 0 "hard_int_register_operand" "")
238404b540aSrobert        (match_operand:SI 1 "memory_operand" ""))
239404b540aSrobert   (set (match_operand:DI 2 "hard_int_register_operand" "")
240404b540aSrobert        (sign_extend:DI (match_dup 0)))]
241404b540aSrobert  "true_regnum (operands[0]) == true_regnum (operands[2])
242404b540aSrobert   || peep2_reg_dead_p (2, operands[0])"
243404b540aSrobert  [(set (match_dup 2)
244404b540aSrobert	(sign_extend:DI (match_dup 1)))]
245404b540aSrobert  "")
246404b540aSrobert
247404b540aSrobert;; Don't say we have addsi3 if optimizing.  This generates better code.  We
248404b540aSrobert;; have the anonymous addsi3 pattern below in case combine wants to make it.
249404b540aSrobert(define_expand "addsi3"
250404b540aSrobert  [(set (match_operand:SI 0 "register_operand" "")
251404b540aSrobert	(plus:SI (match_operand:SI 1 "reg_or_0_operand" "")
252404b540aSrobert		 (match_operand:SI 2 "add_operand" "")))]
253404b540aSrobert  "! optimize"
254404b540aSrobert  "")
255404b540aSrobert
256404b540aSrobert(define_insn "*addsi_internal"
257404b540aSrobert  [(set (match_operand:SI 0 "register_operand" "=r,r,r,r")
258404b540aSrobert	(plus:SI (match_operand:SI 1 "reg_or_0_operand" "%rJ,rJ,rJ,rJ")
259404b540aSrobert		 (match_operand:SI 2 "add_operand" "rI,O,K,L")))]
260404b540aSrobert  ""
261404b540aSrobert  "@
262404b540aSrobert   addl %r1,%2,%0
263404b540aSrobert   subl %r1,%n2,%0
264404b540aSrobert   lda %0,%2(%r1)
265404b540aSrobert   ldah %0,%h2(%r1)")
266404b540aSrobert
267404b540aSrobert(define_split
268404b540aSrobert  [(set (match_operand:SI 0 "register_operand" "")
269404b540aSrobert	(plus:SI (match_operand:SI 1 "register_operand" "")
270404b540aSrobert		 (match_operand:SI 2 "const_int_operand" "")))]
271404b540aSrobert  "! add_operand (operands[2], SImode)"
272404b540aSrobert  [(set (match_dup 0) (plus:SI (match_dup 1) (match_dup 3)))
273404b540aSrobert   (set (match_dup 0) (plus:SI (match_dup 0) (match_dup 4)))]
274404b540aSrobert{
275404b540aSrobert  HOST_WIDE_INT val = INTVAL (operands[2]);
276404b540aSrobert  HOST_WIDE_INT low = (val & 0xffff) - 2 * (val & 0x8000);
277404b540aSrobert  HOST_WIDE_INT rest = val - low;
278404b540aSrobert
279404b540aSrobert  operands[3] = GEN_INT (rest);
280404b540aSrobert  operands[4] = GEN_INT (low);
281404b540aSrobert})
282404b540aSrobert
283404b540aSrobert(define_insn "*addsi_se"
284404b540aSrobert  [(set (match_operand:DI 0 "register_operand" "=r,r")
285404b540aSrobert	(sign_extend:DI
286404b540aSrobert	 (plus:SI (match_operand:SI 1 "reg_or_0_operand" "%rJ,rJ")
287404b540aSrobert		  (match_operand:SI 2 "sext_add_operand" "rI,O"))))]
288404b540aSrobert  ""
289404b540aSrobert  "@
290404b540aSrobert   addl %r1,%2,%0
291404b540aSrobert   subl %r1,%n2,%0")
292404b540aSrobert
293404b540aSrobert(define_insn "*addsi_se2"
294404b540aSrobert  [(set (match_operand:DI 0 "register_operand" "=r,r")
295404b540aSrobert	(sign_extend:DI
296404b540aSrobert	 (subreg:SI (plus:DI (match_operand:DI 1 "reg_or_0_operand" "%rJ,rJ")
297404b540aSrobert			     (match_operand:DI 2 "sext_add_operand" "rI,O"))
298404b540aSrobert		    0)))]
299404b540aSrobert  ""
300404b540aSrobert  "@
301404b540aSrobert   addl %r1,%2,%0
302404b540aSrobert   subl %r1,%n2,%0")
303404b540aSrobert
304404b540aSrobert(define_split
305404b540aSrobert  [(set (match_operand:DI 0 "register_operand" "")
306404b540aSrobert	(sign_extend:DI
307404b540aSrobert	 (plus:SI (match_operand:SI 1 "reg_not_elim_operand" "")
308404b540aSrobert		  (match_operand:SI 2 "const_int_operand" ""))))
309404b540aSrobert   (clobber (match_operand:SI 3 "reg_not_elim_operand" ""))]
310404b540aSrobert  "! sext_add_operand (operands[2], SImode) && INTVAL (operands[2]) > 0
311404b540aSrobert   && INTVAL (operands[2]) % 4 == 0"
312404b540aSrobert  [(set (match_dup 3) (match_dup 4))
313404b540aSrobert   (set (match_dup 0) (sign_extend:DI (plus:SI (mult:SI (match_dup 3)
314404b540aSrobert							(match_dup 5))
315404b540aSrobert					       (match_dup 1))))]
316404b540aSrobert{
317404b540aSrobert  HOST_WIDE_INT val = INTVAL (operands[2]) / 4;
318404b540aSrobert  int mult = 4;
319404b540aSrobert
320404b540aSrobert  if (val % 2 == 0)
321404b540aSrobert    val /= 2, mult = 8;
322404b540aSrobert
323404b540aSrobert  operands[4] = GEN_INT (val);
324404b540aSrobert  operands[5] = GEN_INT (mult);
325404b540aSrobert})
326404b540aSrobert
327404b540aSrobert(define_split
328404b540aSrobert  [(set (match_operand:DI 0 "register_operand" "")
329404b540aSrobert	(sign_extend:DI
330404b540aSrobert	 (plus:SI (match_operator:SI 1 "comparison_operator"
331404b540aSrobert				     [(match_operand 2 "" "")
332404b540aSrobert				      (match_operand 3 "" "")])
333404b540aSrobert		  (match_operand:SI 4 "add_operand" ""))))
334404b540aSrobert   (clobber (match_operand:DI 5 "register_operand" ""))]
335404b540aSrobert  ""
336404b540aSrobert  [(set (match_dup 5) (match_dup 6))
337404b540aSrobert   (set (match_dup 0) (sign_extend:DI (plus:SI (match_dup 7) (match_dup 4))))]
338404b540aSrobert{
339404b540aSrobert  operands[6] = gen_rtx_fmt_ee (GET_CODE (operands[1]), DImode,
340404b540aSrobert				operands[2], operands[3]);
341404b540aSrobert  operands[7] = gen_lowpart (SImode, operands[5]);
342404b540aSrobert})
343404b540aSrobert
344404b540aSrobert(define_insn "addvsi3"
345404b540aSrobert  [(set (match_operand:SI 0 "register_operand" "=r,r")
346404b540aSrobert	(plus:SI (match_operand:SI 1 "reg_or_0_operand" "%rJ,rJ")
347404b540aSrobert		 (match_operand:SI 2 "sext_add_operand" "rI,O")))
348404b540aSrobert   (trap_if (ne (plus:DI (sign_extend:DI (match_dup 1))
349404b540aSrobert			 (sign_extend:DI (match_dup 2)))
350404b540aSrobert		(sign_extend:DI (plus:SI (match_dup 1)
351404b540aSrobert					 (match_dup 2))))
352404b540aSrobert	    (const_int 0))]
353404b540aSrobert  ""
354404b540aSrobert  "@
355404b540aSrobert   addlv %r1,%2,%0
356404b540aSrobert   sublv %r1,%n2,%0")
357404b540aSrobert
358404b540aSrobert(define_expand "adddi3"
359404b540aSrobert  [(set (match_operand:DI 0 "register_operand" "")
360404b540aSrobert	(plus:DI (match_operand:DI 1 "register_operand" "")
361404b540aSrobert		 (match_operand:DI 2 "add_operand" "")))]
362404b540aSrobert  ""
363404b540aSrobert  "")
364404b540aSrobert
365404b540aSrobert(define_insn "*adddi_er_lo16_dtp"
366404b540aSrobert  [(set (match_operand:DI 0 "register_operand" "=r")
367404b540aSrobert	(lo_sum:DI (match_operand:DI 1 "register_operand" "r")
368404b540aSrobert		   (match_operand:DI 2 "dtp16_symbolic_operand" "")))]
369404b540aSrobert  "HAVE_AS_TLS"
370404b540aSrobert  "lda %0,%2(%1)\t\t!dtprel")
371404b540aSrobert
372404b540aSrobert(define_insn "*adddi_er_hi32_dtp"
373404b540aSrobert  [(set (match_operand:DI 0 "register_operand" "=r")
374404b540aSrobert	(plus:DI (match_operand:DI 1 "register_operand" "r")
375404b540aSrobert		 (high:DI (match_operand:DI 2 "dtp32_symbolic_operand" ""))))]
376404b540aSrobert  "HAVE_AS_TLS"
377404b540aSrobert  "ldah %0,%2(%1)\t\t!dtprelhi")
378404b540aSrobert
379404b540aSrobert(define_insn "*adddi_er_lo32_dtp"
380404b540aSrobert  [(set (match_operand:DI 0 "register_operand" "=r")
381404b540aSrobert	(lo_sum:DI (match_operand:DI 1 "register_operand" "r")
382404b540aSrobert		   (match_operand:DI 2 "dtp32_symbolic_operand" "")))]
383404b540aSrobert  "HAVE_AS_TLS"
384404b540aSrobert  "lda %0,%2(%1)\t\t!dtprello")
385404b540aSrobert
386404b540aSrobert(define_insn "*adddi_er_lo16_tp"
387404b540aSrobert  [(set (match_operand:DI 0 "register_operand" "=r")
388404b540aSrobert	(lo_sum:DI (match_operand:DI 1 "register_operand" "r")
389404b540aSrobert		   (match_operand:DI 2 "tp16_symbolic_operand" "")))]
390404b540aSrobert  "HAVE_AS_TLS"
391404b540aSrobert  "lda %0,%2(%1)\t\t!tprel")
392404b540aSrobert
393404b540aSrobert(define_insn "*adddi_er_hi32_tp"
394404b540aSrobert  [(set (match_operand:DI 0 "register_operand" "=r")
395404b540aSrobert	(plus:DI (match_operand:DI 1 "register_operand" "r")
396404b540aSrobert		 (high:DI (match_operand:DI 2 "tp32_symbolic_operand" ""))))]
397404b540aSrobert  "HAVE_AS_TLS"
398404b540aSrobert  "ldah %0,%2(%1)\t\t!tprelhi")
399404b540aSrobert
400404b540aSrobert(define_insn "*adddi_er_lo32_tp"
401404b540aSrobert  [(set (match_operand:DI 0 "register_operand" "=r")
402404b540aSrobert	(lo_sum:DI (match_operand:DI 1 "register_operand" "r")
403404b540aSrobert		   (match_operand:DI 2 "tp32_symbolic_operand" "")))]
404404b540aSrobert  "HAVE_AS_TLS"
405404b540aSrobert  "lda %0,%2(%1)\t\t!tprello")
406404b540aSrobert
407404b540aSrobert(define_insn "*adddi_er_high_l"
408404b540aSrobert  [(set (match_operand:DI 0 "register_operand" "=r")
409404b540aSrobert	(plus:DI (match_operand:DI 1 "register_operand" "r")
410404b540aSrobert		 (high:DI (match_operand:DI 2 "local_symbolic_operand" ""))))]
411404b540aSrobert  "TARGET_EXPLICIT_RELOCS && reload_completed"
412404b540aSrobert  "ldah %0,%2(%1)\t\t!gprelhigh"
413404b540aSrobert  [(set_attr "usegp" "yes")])
414404b540aSrobert
415404b540aSrobert(define_split
416404b540aSrobert  [(set (match_operand:DI 0 "register_operand" "")
417404b540aSrobert        (high:DI (match_operand:DI 1 "local_symbolic_operand" "")))]
418404b540aSrobert  "TARGET_EXPLICIT_RELOCS && reload_completed"
419404b540aSrobert  [(set (match_dup 0)
420404b540aSrobert	(plus:DI (match_dup 2) (high:DI (match_dup 1))))]
421404b540aSrobert  "operands[2] = pic_offset_table_rtx;")
422404b540aSrobert
423404b540aSrobert;; We used to expend quite a lot of effort choosing addq/subq/lda.
424404b540aSrobert;; With complications like
425404b540aSrobert;;
426404b540aSrobert;;   The NT stack unwind code can't handle a subq to adjust the stack
427404b540aSrobert;;   (that's a bug, but not one we can do anything about).  As of NT4.0 SP3,
428404b540aSrobert;;   the exception handling code will loop if a subq is used and an
429404b540aSrobert;;   exception occurs.
430404b540aSrobert;;
431404b540aSrobert;;   The 19980616 change to emit prologues as RTL also confused some
432404b540aSrobert;;   versions of GDB, which also interprets prologues.  This has been
433404b540aSrobert;;   fixed as of GDB 4.18, but it does not harm to unconditionally
434404b540aSrobert;;   use lda here.
435404b540aSrobert;;
436404b540aSrobert;; and the fact that the three insns schedule exactly the same, it's
437404b540aSrobert;; just not worth the effort.
438404b540aSrobert
439404b540aSrobert(define_insn "*adddi_internal"
440404b540aSrobert  [(set (match_operand:DI 0 "register_operand" "=r,r,r")
441404b540aSrobert	(plus:DI (match_operand:DI 1 "register_operand" "%r,r,r")
442404b540aSrobert		 (match_operand:DI 2 "add_operand" "r,K,L")))]
443404b540aSrobert  ""
444404b540aSrobert  "@
445404b540aSrobert   addq %1,%2,%0
446404b540aSrobert   lda %0,%2(%1)
447404b540aSrobert   ldah %0,%h2(%1)")
448404b540aSrobert
449404b540aSrobert;; ??? Allow large constants when basing off the frame pointer or some
450404b540aSrobert;; virtual register that may eliminate to the frame pointer.  This is
451404b540aSrobert;; done because register elimination offsets will change the hi/lo split,
452404b540aSrobert;; and if we split before reload, we will require additional instructions.
453404b540aSrobert
454404b540aSrobert(define_insn "*adddi_fp_hack"
455404b540aSrobert  [(set (match_operand:DI 0 "register_operand" "=r,r,r")
456404b540aSrobert        (plus:DI (match_operand:DI 1 "reg_no_subreg_operand" "r,r,r")
457404b540aSrobert		 (match_operand:DI 2 "const_int_operand" "K,L,n")))]
458404b540aSrobert  "NONSTRICT_REG_OK_FP_BASE_P (operands[1])
459404b540aSrobert   && INTVAL (operands[2]) >= 0
460404b540aSrobert   /* This is the largest constant an lda+ldah pair can add, minus
461404b540aSrobert      an upper bound on the displacement between SP and AP during
462404b540aSrobert      register elimination.  See INITIAL_ELIMINATION_OFFSET.  */
463404b540aSrobert   && INTVAL (operands[2])
464404b540aSrobert	< (0x7fff8000
465404b540aSrobert	   - FIRST_PSEUDO_REGISTER * UNITS_PER_WORD
466404b540aSrobert	   - ALPHA_ROUND(current_function_outgoing_args_size)
467404b540aSrobert	   - (ALPHA_ROUND (get_frame_size ()
468404b540aSrobert			   + max_reg_num () * UNITS_PER_WORD
469404b540aSrobert			   + current_function_pretend_args_size)
470404b540aSrobert	      - current_function_pretend_args_size))"
471404b540aSrobert  "@
472404b540aSrobert   lda %0,%2(%1)
473404b540aSrobert   ldah %0,%h2(%1)
474404b540aSrobert   #")
475404b540aSrobert
476404b540aSrobert;; Don't do this if we are adjusting SP since we don't want to do it
477404b540aSrobert;; in two steps.  Don't split FP sources for the reason listed above.
478404b540aSrobert(define_split
479404b540aSrobert  [(set (match_operand:DI 0 "register_operand" "")
480404b540aSrobert	(plus:DI (match_operand:DI 1 "register_operand" "")
481404b540aSrobert		 (match_operand:DI 2 "const_int_operand" "")))]
482404b540aSrobert  "! add_operand (operands[2], DImode)
483404b540aSrobert   && operands[0] != stack_pointer_rtx
484404b540aSrobert   && operands[1] != frame_pointer_rtx
485404b540aSrobert   && operands[1] != arg_pointer_rtx"
486404b540aSrobert  [(set (match_dup 0) (plus:DI (match_dup 1) (match_dup 3)))
487404b540aSrobert   (set (match_dup 0) (plus:DI (match_dup 0) (match_dup 4)))]
488404b540aSrobert{
489404b540aSrobert  HOST_WIDE_INT val = INTVAL (operands[2]);
490404b540aSrobert  HOST_WIDE_INT low = (val & 0xffff) - 2 * (val & 0x8000);
491404b540aSrobert  HOST_WIDE_INT rest = val - low;
492404b540aSrobert
493404b540aSrobert  operands[4] = GEN_INT (low);
494404b540aSrobert  if (CONST_OK_FOR_LETTER_P (rest, 'L'))
495404b540aSrobert    operands[3] = GEN_INT (rest);
496404b540aSrobert  else if (! no_new_pseudos)
497404b540aSrobert    {
498404b540aSrobert      operands[3] = gen_reg_rtx (DImode);
499404b540aSrobert      emit_move_insn (operands[3], operands[2]);
500404b540aSrobert      emit_insn (gen_adddi3 (operands[0], operands[1], operands[3]));
501404b540aSrobert      DONE;
502404b540aSrobert    }
503404b540aSrobert  else
504404b540aSrobert    FAIL;
505404b540aSrobert})
506404b540aSrobert
507404b540aSrobert(define_insn "*saddl"
508404b540aSrobert  [(set (match_operand:SI 0 "register_operand" "=r,r")
509404b540aSrobert	(plus:SI (mult:SI (match_operand:SI 1 "reg_not_elim_operand" "r,r")
510404b540aSrobert			  (match_operand:SI 2 "const48_operand" "I,I"))
511404b540aSrobert		 (match_operand:SI 3 "sext_add_operand" "rI,O")))]
512404b540aSrobert  ""
513404b540aSrobert  "@
514404b540aSrobert   s%2addl %1,%3,%0
515404b540aSrobert   s%2subl %1,%n3,%0")
516404b540aSrobert
517404b540aSrobert(define_insn "*saddl_se"
518404b540aSrobert  [(set (match_operand:DI 0 "register_operand" "=r,r")
519404b540aSrobert	(sign_extend:DI
520404b540aSrobert	 (plus:SI (mult:SI (match_operand:SI 1 "reg_not_elim_operand" "r,r")
521404b540aSrobert			   (match_operand:SI 2 "const48_operand" "I,I"))
522404b540aSrobert		  (match_operand:SI 3 "sext_add_operand" "rI,O"))))]
523404b540aSrobert  ""
524404b540aSrobert  "@
525404b540aSrobert   s%2addl %1,%3,%0
526404b540aSrobert   s%2subl %1,%n3,%0")
527404b540aSrobert
528404b540aSrobert(define_split
529404b540aSrobert  [(set (match_operand:DI 0 "register_operand" "")
530404b540aSrobert	(sign_extend:DI
531404b540aSrobert	 (plus:SI (mult:SI (match_operator:SI 1 "comparison_operator"
532404b540aSrobert					      [(match_operand 2 "" "")
533404b540aSrobert					       (match_operand 3 "" "")])
534404b540aSrobert			   (match_operand:SI 4 "const48_operand" ""))
535404b540aSrobert		  (match_operand:SI 5 "sext_add_operand" ""))))
536404b540aSrobert   (clobber (match_operand:DI 6 "reg_not_elim_operand" ""))]
537404b540aSrobert  ""
538404b540aSrobert  [(set (match_dup 6) (match_dup 7))
539404b540aSrobert   (set (match_dup 0)
540404b540aSrobert	(sign_extend:DI (plus:SI (mult:SI (match_dup 8) (match_dup 4))
541404b540aSrobert				 (match_dup 5))))]
542404b540aSrobert{
543404b540aSrobert  operands[7] = gen_rtx_fmt_ee (GET_CODE (operands[1]), DImode,
544404b540aSrobert				operands[2], operands[3]);
545404b540aSrobert  operands[8] = gen_lowpart (SImode, operands[6]);
546404b540aSrobert})
547404b540aSrobert
548404b540aSrobert(define_insn "*saddq"
549404b540aSrobert  [(set (match_operand:DI 0 "register_operand" "=r,r")
550404b540aSrobert	(plus:DI (mult:DI (match_operand:DI 1 "reg_not_elim_operand" "r,r")
551404b540aSrobert			  (match_operand:DI 2 "const48_operand" "I,I"))
552404b540aSrobert		 (match_operand:DI 3 "sext_add_operand" "rI,O")))]
553404b540aSrobert  ""
554404b540aSrobert  "@
555404b540aSrobert   s%2addq %1,%3,%0
556404b540aSrobert   s%2subq %1,%n3,%0")
557404b540aSrobert
558404b540aSrobert(define_insn "addvdi3"
559404b540aSrobert  [(set (match_operand:DI 0 "register_operand" "=r,r")
560404b540aSrobert	(plus:DI (match_operand:DI 1 "reg_or_0_operand" "%rJ,rJ")
561404b540aSrobert		 (match_operand:DI 2 "sext_add_operand" "rI,O")))
562404b540aSrobert   (trap_if (ne (plus:TI (sign_extend:TI (match_dup 1))
563404b540aSrobert			 (sign_extend:TI (match_dup 2)))
564404b540aSrobert		(sign_extend:TI (plus:DI (match_dup 1)
565404b540aSrobert					 (match_dup 2))))
566404b540aSrobert	    (const_int 0))]
567404b540aSrobert  ""
568404b540aSrobert  "@
569404b540aSrobert   addqv %r1,%2,%0
570404b540aSrobert   subqv %r1,%n2,%0")
571404b540aSrobert
572404b540aSrobert(define_insn "negsi2"
573404b540aSrobert  [(set (match_operand:SI 0 "register_operand" "=r")
574404b540aSrobert	(neg:SI (match_operand:SI 1 "reg_or_8bit_operand" "rI")))]
575404b540aSrobert  ""
576404b540aSrobert  "subl $31,%1,%0")
577404b540aSrobert
578404b540aSrobert(define_insn "*negsi_se"
579404b540aSrobert  [(set (match_operand:DI 0 "register_operand" "=r")
580404b540aSrobert	(sign_extend:DI (neg:SI
581404b540aSrobert			 (match_operand:SI 1 "reg_or_8bit_operand" "rI"))))]
582404b540aSrobert  ""
583404b540aSrobert  "subl $31,%1,%0")
584404b540aSrobert
585404b540aSrobert(define_insn "negvsi2"
586404b540aSrobert  [(set (match_operand:SI 0 "register_operand" "=r")
587404b540aSrobert	(neg:SI (match_operand:SI 1 "register_operand" "r")))
588404b540aSrobert   (trap_if (ne (neg:DI (sign_extend:DI (match_dup 1)))
589404b540aSrobert		(sign_extend:DI (neg:SI (match_dup 1))))
590404b540aSrobert	    (const_int 0))]
591404b540aSrobert  ""
592404b540aSrobert  "sublv $31,%1,%0")
593404b540aSrobert
594404b540aSrobert(define_insn "negdi2"
595404b540aSrobert  [(set (match_operand:DI 0 "register_operand" "=r")
596404b540aSrobert	(neg:DI (match_operand:DI 1 "reg_or_8bit_operand" "rI")))]
597404b540aSrobert  ""
598404b540aSrobert  "subq $31,%1,%0")
599404b540aSrobert
600404b540aSrobert(define_insn "negvdi2"
601404b540aSrobert  [(set (match_operand:DI 0 "register_operand" "=r")
602404b540aSrobert	(neg:DI (match_operand:DI 1 "register_operand" "r")))
603404b540aSrobert   (trap_if (ne (neg:TI (sign_extend:TI (match_dup 1)))
604404b540aSrobert		(sign_extend:TI (neg:DI (match_dup 1))))
605404b540aSrobert	    (const_int 0))]
606404b540aSrobert  ""
607404b540aSrobert  "subqv $31,%1,%0")
608404b540aSrobert
609404b540aSrobert(define_expand "subsi3"
610404b540aSrobert  [(set (match_operand:SI 0 "register_operand" "")
611404b540aSrobert	(minus:SI (match_operand:SI 1 "reg_or_0_operand" "")
612404b540aSrobert		  (match_operand:SI 2 "reg_or_8bit_operand" "")))]
613404b540aSrobert  "! optimize"
614404b540aSrobert  "")
615404b540aSrobert
616404b540aSrobert(define_insn "*subsi_internal"
617404b540aSrobert  [(set (match_operand:SI 0 "register_operand" "=r")
618404b540aSrobert	(minus:SI (match_operand:SI 1 "reg_or_0_operand" "rJ")
619404b540aSrobert		  (match_operand:SI 2 "reg_or_8bit_operand" "rI")))]
620404b540aSrobert  ""
621404b540aSrobert  "subl %r1,%2,%0")
622404b540aSrobert
623404b540aSrobert(define_insn "*subsi_se"
624404b540aSrobert  [(set (match_operand:DI 0 "register_operand" "=r")
625404b540aSrobert	(sign_extend:DI (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rJ")
626404b540aSrobert				  (match_operand:SI 2 "reg_or_8bit_operand" "rI"))))]
627404b540aSrobert  ""
628404b540aSrobert  "subl %r1,%2,%0")
629404b540aSrobert
630404b540aSrobert(define_insn "*subsi_se2"
631404b540aSrobert  [(set (match_operand:DI 0 "register_operand" "=r")
632404b540aSrobert	(sign_extend:DI
633404b540aSrobert	 (subreg:SI (minus:DI (match_operand:DI 1 "reg_or_0_operand" "rJ")
634404b540aSrobert			      (match_operand:DI 2 "reg_or_8bit_operand" "rI"))
635404b540aSrobert		    0)))]
636404b540aSrobert  ""
637404b540aSrobert  "subl %r1,%2,%0")
638404b540aSrobert
639404b540aSrobert(define_insn "subvsi3"
640404b540aSrobert  [(set (match_operand:SI 0 "register_operand" "=r")
641404b540aSrobert	(minus:SI (match_operand:SI 1 "reg_or_0_operand" "rJ")
642404b540aSrobert		  (match_operand:SI 2 "reg_or_8bit_operand" "rI")))
643404b540aSrobert   (trap_if (ne (minus:DI (sign_extend:DI (match_dup 1))
644404b540aSrobert			  (sign_extend:DI (match_dup 2)))
645404b540aSrobert		(sign_extend:DI (minus:SI (match_dup 1)
646404b540aSrobert					  (match_dup 2))))
647404b540aSrobert	    (const_int 0))]
648404b540aSrobert  ""
649404b540aSrobert  "sublv %r1,%2,%0")
650404b540aSrobert
651404b540aSrobert(define_insn "subdi3"
652404b540aSrobert  [(set (match_operand:DI 0 "register_operand" "=r")
653404b540aSrobert	(minus:DI (match_operand:DI 1 "reg_or_0_operand" "rJ")
654404b540aSrobert		  (match_operand:DI 2 "reg_or_8bit_operand" "rI")))]
655404b540aSrobert  ""
656404b540aSrobert  "subq %r1,%2,%0")
657404b540aSrobert
658404b540aSrobert(define_insn "*ssubl"
659404b540aSrobert  [(set (match_operand:SI 0 "register_operand" "=r")
660404b540aSrobert	(minus:SI (mult:SI (match_operand:SI 1 "reg_not_elim_operand" "r")
661404b540aSrobert			   (match_operand:SI 2 "const48_operand" "I"))
662404b540aSrobert		  (match_operand:SI 3 "reg_or_8bit_operand" "rI")))]
663404b540aSrobert  ""
664404b540aSrobert  "s%2subl %1,%3,%0")
665404b540aSrobert
666404b540aSrobert(define_insn "*ssubl_se"
667404b540aSrobert  [(set (match_operand:DI 0 "register_operand" "=r")
668404b540aSrobert	(sign_extend:DI
669404b540aSrobert	 (minus:SI (mult:SI (match_operand:SI 1 "reg_not_elim_operand" "r")
670404b540aSrobert			    (match_operand:SI 2 "const48_operand" "I"))
671404b540aSrobert		   (match_operand:SI 3 "reg_or_8bit_operand" "rI"))))]
672404b540aSrobert  ""
673404b540aSrobert  "s%2subl %1,%3,%0")
674404b540aSrobert
675404b540aSrobert(define_insn "*ssubq"
676404b540aSrobert  [(set (match_operand:DI 0 "register_operand" "=r")
677404b540aSrobert	(minus:DI (mult:DI (match_operand:DI 1 "reg_not_elim_operand" "r")
678404b540aSrobert			   (match_operand:DI 2 "const48_operand" "I"))
679404b540aSrobert		  (match_operand:DI 3 "reg_or_8bit_operand" "rI")))]
680404b540aSrobert  ""
681404b540aSrobert  "s%2subq %1,%3,%0")
682404b540aSrobert
683404b540aSrobert(define_insn "subvdi3"
684404b540aSrobert  [(set (match_operand:DI 0 "register_operand" "=r")
685404b540aSrobert	(minus:DI (match_operand:DI 1 "reg_or_0_operand" "rJ")
686404b540aSrobert		  (match_operand:DI 2 "reg_or_8bit_operand" "rI")))
687404b540aSrobert   (trap_if (ne (minus:TI (sign_extend:TI (match_dup 1))
688404b540aSrobert			  (sign_extend:TI (match_dup 2)))
689404b540aSrobert		(sign_extend:TI (minus:DI (match_dup 1)
690404b540aSrobert					  (match_dup 2))))
691404b540aSrobert	    (const_int 0))]
692404b540aSrobert  ""
693404b540aSrobert  "subqv %r1,%2,%0")
694404b540aSrobert
695404b540aSrobert;; The Unicos/Mk assembler doesn't support mull.
696404b540aSrobert
697404b540aSrobert(define_insn "mulsi3"
698404b540aSrobert  [(set (match_operand:SI 0 "register_operand" "=r")
699404b540aSrobert	(mult:SI (match_operand:SI 1 "reg_or_0_operand" "%rJ")
700404b540aSrobert		 (match_operand:SI 2 "reg_or_8bit_operand" "rI")))]
701404b540aSrobert  "!TARGET_ABI_UNICOSMK"
702404b540aSrobert  "mull %r1,%2,%0"
703404b540aSrobert  [(set_attr "type" "imul")
704404b540aSrobert   (set_attr "opsize" "si")])
705404b540aSrobert
706404b540aSrobert(define_insn "*mulsi_se"
707404b540aSrobert  [(set (match_operand:DI 0 "register_operand" "=r")
708404b540aSrobert	(sign_extend:DI
709404b540aSrobert	  (mult:SI (match_operand:SI 1 "reg_or_0_operand" "%rJ")
710404b540aSrobert		   (match_operand:SI 2 "reg_or_8bit_operand" "rI"))))]
711404b540aSrobert  "!TARGET_ABI_UNICOSMK"
712404b540aSrobert  "mull %r1,%2,%0"
713404b540aSrobert  [(set_attr "type" "imul")
714404b540aSrobert   (set_attr "opsize" "si")])
715404b540aSrobert
716404b540aSrobert(define_insn "mulvsi3"
717404b540aSrobert  [(set (match_operand:SI 0 "register_operand" "=r")
718404b540aSrobert	(mult:SI (match_operand:SI 1 "reg_or_0_operand" "%rJ")
719404b540aSrobert		 (match_operand:SI 2 "reg_or_8bit_operand" "rI")))
720404b540aSrobert   (trap_if (ne (mult:DI (sign_extend:DI (match_dup 1))
721404b540aSrobert			 (sign_extend:DI (match_dup 2)))
722404b540aSrobert		(sign_extend:DI (mult:SI (match_dup 1)
723404b540aSrobert					 (match_dup 2))))
724404b540aSrobert	    (const_int 0))]
725404b540aSrobert  "!TARGET_ABI_UNICOSMK"
726404b540aSrobert  "mullv %r1,%2,%0"
727404b540aSrobert  [(set_attr "type" "imul")
728404b540aSrobert   (set_attr "opsize" "si")])
729404b540aSrobert
730404b540aSrobert(define_insn "muldi3"
731404b540aSrobert  [(set (match_operand:DI 0 "register_operand" "=r")
732404b540aSrobert	(mult:DI (match_operand:DI 1 "reg_or_0_operand" "%rJ")
733404b540aSrobert		 (match_operand:DI 2 "reg_or_8bit_operand" "rI")))]
734404b540aSrobert  ""
735404b540aSrobert  "mulq %r1,%2,%0"
736404b540aSrobert  [(set_attr "type" "imul")])
737404b540aSrobert
738404b540aSrobert(define_insn "mulvdi3"
739404b540aSrobert  [(set (match_operand:DI 0 "register_operand" "=r")
740404b540aSrobert	(mult:DI (match_operand:DI 1 "reg_or_0_operand" "%rJ")
741404b540aSrobert		 (match_operand:DI 2 "reg_or_8bit_operand" "rI")))
742404b540aSrobert   (trap_if (ne (mult:TI (sign_extend:TI (match_dup 1))
743404b540aSrobert			 (sign_extend:TI (match_dup 2)))
744404b540aSrobert		(sign_extend:TI (mult:DI (match_dup 1)
745404b540aSrobert					 (match_dup 2))))
746404b540aSrobert	    (const_int 0))]
747404b540aSrobert  ""
748404b540aSrobert  "mulqv %r1,%2,%0"
749404b540aSrobert  [(set_attr "type" "imul")])
750404b540aSrobert
751404b540aSrobert(define_expand "umuldi3_highpart"
752404b540aSrobert  [(set (match_operand:DI 0 "register_operand" "")
753404b540aSrobert	(truncate:DI
754404b540aSrobert	 (lshiftrt:TI
755404b540aSrobert	  (mult:TI (zero_extend:TI
756404b540aSrobert		     (match_operand:DI 1 "register_operand" ""))
757404b540aSrobert		   (match_operand:DI 2 "reg_or_8bit_operand" ""))
758404b540aSrobert	  (const_int 64))))]
759404b540aSrobert  ""
760404b540aSrobert{
761404b540aSrobert  if (REG_P (operands[2]))
762404b540aSrobert    operands[2] = gen_rtx_ZERO_EXTEND (TImode, operands[2]);
763404b540aSrobert})
764404b540aSrobert
765404b540aSrobert(define_insn "*umuldi3_highpart_reg"
766404b540aSrobert  [(set (match_operand:DI 0 "register_operand" "=r")
767404b540aSrobert	(truncate:DI
768404b540aSrobert	 (lshiftrt:TI
769404b540aSrobert	  (mult:TI (zero_extend:TI
770404b540aSrobert		     (match_operand:DI 1 "register_operand" "r"))
771404b540aSrobert		   (zero_extend:TI
772404b540aSrobert		     (match_operand:DI 2 "register_operand" "r")))
773404b540aSrobert	  (const_int 64))))]
774404b540aSrobert  ""
775404b540aSrobert  "umulh %1,%2,%0"
776404b540aSrobert  [(set_attr "type" "imul")
777404b540aSrobert   (set_attr "opsize" "udi")])
778404b540aSrobert
779404b540aSrobert(define_insn "*umuldi3_highpart_const"
780404b540aSrobert  [(set (match_operand:DI 0 "register_operand" "=r")
781404b540aSrobert	(truncate:DI
782404b540aSrobert	 (lshiftrt:TI
783404b540aSrobert	  (mult:TI (zero_extend:TI (match_operand:DI 1 "register_operand" "r"))
784404b540aSrobert		   (match_operand:TI 2 "cint8_operand" "I"))
785404b540aSrobert	  (const_int 64))))]
786404b540aSrobert  ""
787404b540aSrobert  "umulh %1,%2,%0"
788404b540aSrobert  [(set_attr "type" "imul")
789404b540aSrobert   (set_attr "opsize" "udi")])
790404b540aSrobert
791404b540aSrobert;; The divide and remainder operations take their inputs from r24 and
792404b540aSrobert;; r25, put their output in r27, and clobber r23 and r28 on all
793404b540aSrobert;; systems except Unicos/Mk. On Unicos, the standard library provides
794404b540aSrobert;; subroutines which use the standard calling convention and work on
795404b540aSrobert;; DImode operands.
796404b540aSrobert
797404b540aSrobert;; ??? Force sign-extension here because some versions of OSF/1 and
798404b540aSrobert;; Interix/NT don't do the right thing if the inputs are not properly
799404b540aSrobert;; sign-extended.  But Linux, for instance, does not have this
800404b540aSrobert;; problem.  Is it worth the complication here to eliminate the sign
801404b540aSrobert;; extension?
802404b540aSrobert
803404b540aSrobert(define_expand "divsi3"
804404b540aSrobert  [(set (match_dup 3)
805404b540aSrobert	(sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "")))
806404b540aSrobert   (set (match_dup 4)
807404b540aSrobert	(sign_extend:DI (match_operand:SI 2 "nonimmediate_operand" "")))
808404b540aSrobert   (parallel [(set (match_dup 5)
809404b540aSrobert		   (sign_extend:DI (div:SI (match_dup 3) (match_dup 4))))
810404b540aSrobert	      (clobber (reg:DI 23))
811404b540aSrobert	      (clobber (reg:DI 28))])
812404b540aSrobert   (set (match_operand:SI 0 "nonimmediate_operand" "")
813404b540aSrobert	(subreg:SI (match_dup 5) 0))]
814404b540aSrobert  "! TARGET_ABI_OPEN_VMS && ! TARGET_ABI_UNICOSMK"
815404b540aSrobert{
816404b540aSrobert  operands[3] = gen_reg_rtx (DImode);
817404b540aSrobert  operands[4] = gen_reg_rtx (DImode);
818404b540aSrobert  operands[5] = gen_reg_rtx (DImode);
819404b540aSrobert})
820404b540aSrobert
821404b540aSrobert(define_expand "udivsi3"
822404b540aSrobert  [(set (match_dup 3)
823404b540aSrobert	(sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "")))
824404b540aSrobert   (set (match_dup 4)
825404b540aSrobert	(sign_extend:DI (match_operand:SI 2 "nonimmediate_operand" "")))
826404b540aSrobert   (parallel [(set (match_dup 5)
827404b540aSrobert		   (sign_extend:DI (udiv:SI (match_dup 3) (match_dup 4))))
828404b540aSrobert	      (clobber (reg:DI 23))
829404b540aSrobert	      (clobber (reg:DI 28))])
830404b540aSrobert   (set (match_operand:SI 0 "nonimmediate_operand" "")
831404b540aSrobert	(subreg:SI (match_dup 5) 0))]
832404b540aSrobert  "! TARGET_ABI_OPEN_VMS && ! TARGET_ABI_UNICOSMK"
833404b540aSrobert{
834404b540aSrobert  operands[3] = gen_reg_rtx (DImode);
835404b540aSrobert  operands[4] = gen_reg_rtx (DImode);
836404b540aSrobert  operands[5] = gen_reg_rtx (DImode);
837404b540aSrobert})
838404b540aSrobert
839404b540aSrobert(define_expand "modsi3"
840404b540aSrobert  [(set (match_dup 3)
841404b540aSrobert	(sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "")))
842404b540aSrobert   (set (match_dup 4)
843404b540aSrobert	(sign_extend:DI (match_operand:SI 2 "nonimmediate_operand" "")))
844404b540aSrobert   (parallel [(set (match_dup 5)
845404b540aSrobert		   (sign_extend:DI (mod:SI (match_dup 3) (match_dup 4))))
846404b540aSrobert	      (clobber (reg:DI 23))
847404b540aSrobert	      (clobber (reg:DI 28))])
848404b540aSrobert   (set (match_operand:SI 0 "nonimmediate_operand" "")
849404b540aSrobert	(subreg:SI (match_dup 5) 0))]
850404b540aSrobert  "! TARGET_ABI_OPEN_VMS && ! TARGET_ABI_UNICOSMK"
851404b540aSrobert{
852404b540aSrobert  operands[3] = gen_reg_rtx (DImode);
853404b540aSrobert  operands[4] = gen_reg_rtx (DImode);
854404b540aSrobert  operands[5] = gen_reg_rtx (DImode);
855404b540aSrobert})
856404b540aSrobert
857404b540aSrobert(define_expand "umodsi3"
858404b540aSrobert  [(set (match_dup 3)
859404b540aSrobert	(sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "")))
860404b540aSrobert   (set (match_dup 4)
861404b540aSrobert	(sign_extend:DI (match_operand:SI 2 "nonimmediate_operand" "")))
862404b540aSrobert   (parallel [(set (match_dup 5)
863404b540aSrobert		   (sign_extend:DI (umod:SI (match_dup 3) (match_dup 4))))
864404b540aSrobert	      (clobber (reg:DI 23))
865404b540aSrobert	      (clobber (reg:DI 28))])
866404b540aSrobert   (set (match_operand:SI 0 "nonimmediate_operand" "")
867404b540aSrobert	(subreg:SI (match_dup 5) 0))]
868404b540aSrobert  "! TARGET_ABI_OPEN_VMS && ! TARGET_ABI_UNICOSMK"
869404b540aSrobert{
870404b540aSrobert  operands[3] = gen_reg_rtx (DImode);
871404b540aSrobert  operands[4] = gen_reg_rtx (DImode);
872404b540aSrobert  operands[5] = gen_reg_rtx (DImode);
873404b540aSrobert})
874404b540aSrobert
875404b540aSrobert(define_expand "divdi3"
876404b540aSrobert  [(parallel [(set (match_operand:DI 0 "register_operand" "")
877404b540aSrobert		   (div:DI (match_operand:DI 1 "register_operand" "")
878404b540aSrobert			   (match_operand:DI 2 "register_operand" "")))
879404b540aSrobert	      (clobber (reg:DI 23))
880404b540aSrobert	      (clobber (reg:DI 28))])]
881404b540aSrobert  "! TARGET_ABI_OPEN_VMS && ! TARGET_ABI_UNICOSMK"
882404b540aSrobert  "")
883404b540aSrobert
884404b540aSrobert(define_expand "udivdi3"
885404b540aSrobert  [(parallel [(set (match_operand:DI 0 "register_operand" "")
886404b540aSrobert		   (udiv:DI (match_operand:DI 1 "register_operand" "")
887404b540aSrobert			    (match_operand:DI 2 "register_operand" "")))
888404b540aSrobert	      (clobber (reg:DI 23))
889404b540aSrobert	      (clobber (reg:DI 28))])]
890404b540aSrobert  "! TARGET_ABI_OPEN_VMS && ! TARGET_ABI_UNICOSMK"
891404b540aSrobert  "")
892404b540aSrobert
893404b540aSrobert(define_expand "moddi3"
894404b540aSrobert  [(use (match_operand:DI 0 "register_operand" ""))
895404b540aSrobert   (use (match_operand:DI 1 "register_operand" ""))
896404b540aSrobert   (use (match_operand:DI 2 "register_operand" ""))]
897404b540aSrobert  "!TARGET_ABI_OPEN_VMS"
898404b540aSrobert{
899404b540aSrobert  if (TARGET_ABI_UNICOSMK)
900404b540aSrobert    emit_insn (gen_moddi3_umk (operands[0], operands[1], operands[2]));
901404b540aSrobert  else
902404b540aSrobert    emit_insn (gen_moddi3_dft (operands[0], operands[1], operands[2]));
903404b540aSrobert  DONE;
904404b540aSrobert})
905404b540aSrobert
906404b540aSrobert(define_expand "moddi3_dft"
907404b540aSrobert  [(parallel [(set (match_operand:DI 0 "register_operand" "")
908404b540aSrobert		   (mod:DI (match_operand:DI 1 "register_operand" "")
909404b540aSrobert			   (match_operand:DI 2 "register_operand" "")))
910404b540aSrobert	      (clobber (reg:DI 23))
911404b540aSrobert	      (clobber (reg:DI 28))])]
912404b540aSrobert  "! TARGET_ABI_OPEN_VMS && ! TARGET_ABI_UNICOSMK"
913404b540aSrobert  "")
914404b540aSrobert
915404b540aSrobert;; On Unicos/Mk, we do as the system's C compiler does:
916404b540aSrobert;; compute the quotient, multiply and subtract.
917404b540aSrobert
918404b540aSrobert(define_expand "moddi3_umk"
919404b540aSrobert  [(use (match_operand:DI 0 "register_operand" ""))
920404b540aSrobert   (use (match_operand:DI 1 "register_operand" ""))
921404b540aSrobert   (use (match_operand:DI 2 "register_operand" ""))]
922404b540aSrobert  "TARGET_ABI_UNICOSMK"
923404b540aSrobert{
924404b540aSrobert  rtx div, mul = gen_reg_rtx (DImode);
925404b540aSrobert
926404b540aSrobert  div = expand_binop (DImode, sdiv_optab, operands[1], operands[2],
927404b540aSrobert		      NULL_RTX, 0, OPTAB_LIB);
928404b540aSrobert  div = force_reg (DImode, div);
929404b540aSrobert  emit_insn (gen_muldi3 (mul, operands[2], div));
930404b540aSrobert  emit_insn (gen_subdi3 (operands[0], operands[1], mul));
931404b540aSrobert  DONE;
932404b540aSrobert})
933404b540aSrobert
934404b540aSrobert(define_expand "umoddi3"
935404b540aSrobert  [(use (match_operand:DI 0 "register_operand" ""))
936404b540aSrobert   (use (match_operand:DI 1 "register_operand" ""))
937404b540aSrobert   (use (match_operand:DI 2 "register_operand" ""))]
938404b540aSrobert  "! TARGET_ABI_OPEN_VMS"
939404b540aSrobert{
940404b540aSrobert  if (TARGET_ABI_UNICOSMK)
941404b540aSrobert    emit_insn (gen_umoddi3_umk (operands[0], operands[1], operands[2]));
942404b540aSrobert  else
943404b540aSrobert    emit_insn (gen_umoddi3_dft (operands[0], operands[1], operands[2]));
944404b540aSrobert  DONE;
945404b540aSrobert})
946404b540aSrobert
947404b540aSrobert(define_expand "umoddi3_dft"
948404b540aSrobert  [(parallel [(set (match_operand:DI 0 "register_operand" "")
949404b540aSrobert		   (umod:DI (match_operand:DI 1 "register_operand" "")
950404b540aSrobert			    (match_operand:DI 2 "register_operand" "")))
951404b540aSrobert	      (clobber (reg:DI 23))
952404b540aSrobert	      (clobber (reg:DI 28))])]
953404b540aSrobert  "! TARGET_ABI_OPEN_VMS && ! TARGET_ABI_UNICOSMK"
954404b540aSrobert  "")
955404b540aSrobert
956404b540aSrobert(define_expand "umoddi3_umk"
957404b540aSrobert  [(use (match_operand:DI 0 "register_operand" ""))
958404b540aSrobert   (use (match_operand:DI 1 "register_operand" ""))
959404b540aSrobert   (use (match_operand:DI 2 "register_operand" ""))]
960404b540aSrobert  "TARGET_ABI_UNICOSMK"
961404b540aSrobert{
962404b540aSrobert  rtx div, mul = gen_reg_rtx (DImode);
963404b540aSrobert
964404b540aSrobert  div = expand_binop (DImode, udiv_optab, operands[1], operands[2],
965404b540aSrobert		      NULL_RTX, 1, OPTAB_LIB);
966404b540aSrobert  div = force_reg (DImode, div);
967404b540aSrobert  emit_insn (gen_muldi3 (mul, operands[2], div));
968404b540aSrobert  emit_insn (gen_subdi3 (operands[0], operands[1], mul));
969404b540aSrobert  DONE;
970404b540aSrobert})
971404b540aSrobert
972404b540aSrobert;; Lengths of 8 for ldq $t12,__divq($gp); jsr $t9,($t12),__divq as
973404b540aSrobert;; expanded by the assembler.
974404b540aSrobert
975404b540aSrobert(define_insn_and_split "*divmodsi_internal_er"
976404b540aSrobert  [(set (match_operand:DI 0 "register_operand" "=c")
977404b540aSrobert	(sign_extend:DI (match_operator:SI 3 "divmod_operator"
978404b540aSrobert			[(match_operand:DI 1 "register_operand" "a")
979404b540aSrobert			 (match_operand:DI 2 "register_operand" "b")])))
980404b540aSrobert   (clobber (reg:DI 23))
981404b540aSrobert   (clobber (reg:DI 28))]
982404b540aSrobert  "TARGET_EXPLICIT_RELOCS && ! TARGET_ABI_OPEN_VMS"
983404b540aSrobert  "#"
984404b540aSrobert  "&& reload_completed"
985404b540aSrobert  [(parallel [(set (match_dup 0)
986404b540aSrobert		   (sign_extend:DI (match_dup 3)))
987404b540aSrobert	      (use (match_dup 0))
988404b540aSrobert	      (use (match_dup 4))
989404b540aSrobert	      (clobber (reg:DI 23))
990404b540aSrobert	      (clobber (reg:DI 28))])]
991404b540aSrobert{
992404b540aSrobert  const char *str;
993404b540aSrobert  switch (GET_CODE (operands[3]))
994404b540aSrobert    {
995404b540aSrobert    case DIV:
996404b540aSrobert      str = "__divl";
997404b540aSrobert      break;
998404b540aSrobert    case UDIV:
999404b540aSrobert      str = "__divlu";
1000404b540aSrobert      break;
1001404b540aSrobert    case MOD:
1002404b540aSrobert      str = "__reml";
1003404b540aSrobert      break;
1004404b540aSrobert    case UMOD:
1005404b540aSrobert      str = "__remlu";
1006404b540aSrobert      break;
1007404b540aSrobert    default:
1008404b540aSrobert      gcc_unreachable ();
1009404b540aSrobert    }
1010404b540aSrobert  operands[4] = GEN_INT (alpha_next_sequence_number++);
1011404b540aSrobert  emit_insn (gen_movdi_er_high_g (operands[0], pic_offset_table_rtx,
1012404b540aSrobert				  gen_rtx_SYMBOL_REF (DImode, str),
1013404b540aSrobert				  operands[4]));
1014404b540aSrobert}
1015404b540aSrobert  [(set_attr "type" "jsr")
1016404b540aSrobert   (set_attr "length" "8")])
1017404b540aSrobert
1018404b540aSrobert(define_insn "*divmodsi_internal_er_1"
1019404b540aSrobert  [(set (match_operand:DI 0 "register_operand" "=c")
1020404b540aSrobert	(sign_extend:DI (match_operator:SI 3 "divmod_operator"
1021404b540aSrobert                        [(match_operand:DI 1 "register_operand" "a")
1022404b540aSrobert                         (match_operand:DI 2 "register_operand" "b")])))
1023404b540aSrobert   (use (match_operand:DI 4 "register_operand" "c"))
1024404b540aSrobert   (use (match_operand 5 "const_int_operand" ""))
1025404b540aSrobert   (clobber (reg:DI 23))
1026404b540aSrobert   (clobber (reg:DI 28))]
1027404b540aSrobert  "TARGET_EXPLICIT_RELOCS && ! TARGET_ABI_OPEN_VMS"
1028404b540aSrobert  "jsr $23,($27),__%E3%j5"
1029404b540aSrobert  [(set_attr "type" "jsr")
1030404b540aSrobert   (set_attr "length" "4")])
1031404b540aSrobert
1032404b540aSrobert(define_insn "*divmodsi_internal"
1033404b540aSrobert  [(set (match_operand:DI 0 "register_operand" "=c")
1034404b540aSrobert	(sign_extend:DI (match_operator:SI 3 "divmod_operator"
1035404b540aSrobert			[(match_operand:DI 1 "register_operand" "a")
1036404b540aSrobert			 (match_operand:DI 2 "register_operand" "b")])))
1037404b540aSrobert   (clobber (reg:DI 23))
1038404b540aSrobert   (clobber (reg:DI 28))]
1039404b540aSrobert  "! TARGET_ABI_OPEN_VMS && ! TARGET_ABI_UNICOSMK"
1040404b540aSrobert  "%E3 %1,%2,%0"
1041404b540aSrobert  [(set_attr "type" "jsr")
1042404b540aSrobert   (set_attr "length" "8")])
1043404b540aSrobert
1044404b540aSrobert(define_insn_and_split "*divmoddi_internal_er"
1045404b540aSrobert  [(set (match_operand:DI 0 "register_operand" "=c")
1046404b540aSrobert	(match_operator:DI 3 "divmod_operator"
1047404b540aSrobert			[(match_operand:DI 1 "register_operand" "a")
1048404b540aSrobert			 (match_operand:DI 2 "register_operand" "b")]))
1049404b540aSrobert   (clobber (reg:DI 23))
1050404b540aSrobert   (clobber (reg:DI 28))]
1051404b540aSrobert  "TARGET_EXPLICIT_RELOCS && ! TARGET_ABI_OPEN_VMS"
1052404b540aSrobert  "#"
1053404b540aSrobert  "&& reload_completed"
1054404b540aSrobert  [(parallel [(set (match_dup 0) (match_dup 3))
1055404b540aSrobert	      (use (match_dup 0))
1056404b540aSrobert	      (use (match_dup 4))
1057404b540aSrobert	      (clobber (reg:DI 23))
1058404b540aSrobert	      (clobber (reg:DI 28))])]
1059404b540aSrobert{
1060404b540aSrobert  const char *str;
1061404b540aSrobert  switch (GET_CODE (operands[3]))
1062404b540aSrobert    {
1063404b540aSrobert    case DIV:
1064404b540aSrobert      str = "__divq";
1065404b540aSrobert      break;
1066404b540aSrobert    case UDIV:
1067404b540aSrobert      str = "__divqu";
1068404b540aSrobert      break;
1069404b540aSrobert    case MOD:
1070404b540aSrobert      str = "__remq";
1071404b540aSrobert      break;
1072404b540aSrobert    case UMOD:
1073404b540aSrobert      str = "__remqu";
1074404b540aSrobert      break;
1075404b540aSrobert    default:
1076404b540aSrobert      gcc_unreachable ();
1077404b540aSrobert    }
1078404b540aSrobert  operands[4] = GEN_INT (alpha_next_sequence_number++);
1079404b540aSrobert  emit_insn (gen_movdi_er_high_g (operands[0], pic_offset_table_rtx,
1080404b540aSrobert				  gen_rtx_SYMBOL_REF (DImode, str),
1081404b540aSrobert				  operands[4]));
1082404b540aSrobert}
1083404b540aSrobert  [(set_attr "type" "jsr")
1084404b540aSrobert   (set_attr "length" "8")])
1085404b540aSrobert
1086404b540aSrobert(define_insn "*divmoddi_internal_er_1"
1087404b540aSrobert  [(set (match_operand:DI 0 "register_operand" "=c")
1088404b540aSrobert	(match_operator:DI 3 "divmod_operator"
1089404b540aSrobert                        [(match_operand:DI 1 "register_operand" "a")
1090404b540aSrobert                         (match_operand:DI 2 "register_operand" "b")]))
1091404b540aSrobert   (use (match_operand:DI 4 "register_operand" "c"))
1092404b540aSrobert   (use (match_operand 5 "const_int_operand" ""))
1093404b540aSrobert   (clobber (reg:DI 23))
1094404b540aSrobert   (clobber (reg:DI 28))]
1095404b540aSrobert  "TARGET_EXPLICIT_RELOCS && ! TARGET_ABI_OPEN_VMS"
1096404b540aSrobert  "jsr $23,($27),__%E3%j5"
1097404b540aSrobert  [(set_attr "type" "jsr")
1098404b540aSrobert   (set_attr "length" "4")])
1099404b540aSrobert
1100404b540aSrobert(define_insn "*divmoddi_internal"
1101404b540aSrobert  [(set (match_operand:DI 0 "register_operand" "=c")
1102404b540aSrobert	(match_operator:DI 3 "divmod_operator"
1103404b540aSrobert			[(match_operand:DI 1 "register_operand" "a")
1104404b540aSrobert			 (match_operand:DI 2 "register_operand" "b")]))
1105404b540aSrobert   (clobber (reg:DI 23))
1106404b540aSrobert   (clobber (reg:DI 28))]
1107404b540aSrobert  "! TARGET_ABI_OPEN_VMS && ! TARGET_ABI_UNICOSMK"
1108404b540aSrobert  "%E3 %1,%2,%0"
1109404b540aSrobert  [(set_attr "type" "jsr")
1110404b540aSrobert   (set_attr "length" "8")])
1111404b540aSrobert
1112404b540aSrobert;; Next are the basic logical operations.  We only expose the DImode operations
1113404b540aSrobert;; to the rtl expanders, but SImode versions exist for combine as well as for
1114404b540aSrobert;; the atomic operation splitters.
1115404b540aSrobert
1116404b540aSrobert(define_insn "*andsi_internal"
1117404b540aSrobert  [(set (match_operand:SI 0 "register_operand" "=r,r,r")
1118404b540aSrobert	(and:SI (match_operand:SI 1 "reg_or_0_operand" "%rJ,rJ,rJ")
1119404b540aSrobert		(match_operand:SI 2 "and_operand" "rI,N,MH")))]
1120404b540aSrobert  ""
1121404b540aSrobert  "@
1122404b540aSrobert   and %r1,%2,%0
1123404b540aSrobert   bic %r1,%N2,%0
1124404b540aSrobert   zapnot %r1,%m2,%0"
1125404b540aSrobert  [(set_attr "type" "ilog,ilog,shift")])
1126404b540aSrobert
1127404b540aSrobert(define_insn "anddi3"
1128404b540aSrobert  [(set (match_operand:DI 0 "register_operand" "=r,r,r")
1129404b540aSrobert	(and:DI (match_operand:DI 1 "reg_or_0_operand" "%rJ,rJ,rJ")
1130404b540aSrobert		(match_operand:DI 2 "and_operand" "rI,N,MH")))]
1131404b540aSrobert  ""
1132404b540aSrobert  "@
1133404b540aSrobert   and %r1,%2,%0
1134404b540aSrobert   bic %r1,%N2,%0
1135404b540aSrobert   zapnot %r1,%m2,%0"
1136404b540aSrobert  [(set_attr "type" "ilog,ilog,shift")])
1137404b540aSrobert
1138404b540aSrobert;; There are times when we can split an AND into two AND insns.  This occurs
1139404b540aSrobert;; when we can first clear any bytes and then clear anything else.  For
1140404b540aSrobert;; example "I & 0xffff07" is "(I & 0xffffff) & 0xffffffffffffff07".
1141404b540aSrobert;; Only do this when running on 64-bit host since the computations are
1142404b540aSrobert;; too messy otherwise.
1143404b540aSrobert
1144404b540aSrobert(define_split
1145404b540aSrobert  [(set (match_operand:DI 0 "register_operand" "")
1146404b540aSrobert	(and:DI (match_operand:DI 1 "register_operand" "")
1147404b540aSrobert		(match_operand:DI 2 "const_int_operand" "")))]
1148404b540aSrobert  "HOST_BITS_PER_WIDE_INT == 64 && ! and_operand (operands[2], DImode)"
1149404b540aSrobert  [(set (match_dup 0) (and:DI (match_dup 1) (match_dup 3)))
1150404b540aSrobert   (set (match_dup 0) (and:DI (match_dup 0) (match_dup 4)))]
1151404b540aSrobert{
1152404b540aSrobert  unsigned HOST_WIDE_INT mask1 = INTVAL (operands[2]);
1153404b540aSrobert  unsigned HOST_WIDE_INT mask2 = mask1;
1154404b540aSrobert  int i;
1155404b540aSrobert
1156404b540aSrobert  /* For each byte that isn't all zeros, make it all ones.  */
1157404b540aSrobert  for (i = 0; i < 64; i += 8)
1158404b540aSrobert    if ((mask1 & ((HOST_WIDE_INT) 0xff << i)) != 0)
1159404b540aSrobert      mask1 |= (HOST_WIDE_INT) 0xff << i;
1160404b540aSrobert
1161404b540aSrobert  /* Now turn on any bits we've just turned off.  */
1162404b540aSrobert  mask2 |= ~ mask1;
1163404b540aSrobert
1164404b540aSrobert  operands[3] = GEN_INT (mask1);
1165404b540aSrobert  operands[4] = GEN_INT (mask2);
1166404b540aSrobert})
1167404b540aSrobert
1168404b540aSrobert(define_expand "zero_extendqihi2"
1169404b540aSrobert  [(set (match_operand:HI 0 "register_operand" "")
1170404b540aSrobert	(zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))]
1171404b540aSrobert  ""
1172404b540aSrobert{
1173404b540aSrobert  if (! TARGET_BWX)
1174404b540aSrobert    operands[1] = force_reg (QImode, operands[1]);
1175404b540aSrobert})
1176404b540aSrobert
1177404b540aSrobert(define_insn "*zero_extendqihi2_bwx"
1178404b540aSrobert  [(set (match_operand:HI 0 "register_operand" "=r,r")
1179404b540aSrobert	(zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "r,m")))]
1180404b540aSrobert  "TARGET_BWX"
1181404b540aSrobert  "@
1182404b540aSrobert   and %1,0xff,%0
1183404b540aSrobert   ldbu %0,%1"
1184404b540aSrobert  [(set_attr "type" "ilog,ild")])
1185404b540aSrobert
1186404b540aSrobert(define_insn "*zero_extendqihi2_nobwx"
1187404b540aSrobert  [(set (match_operand:HI 0 "register_operand" "=r")
1188404b540aSrobert	(zero_extend:HI (match_operand:QI 1 "register_operand" "r")))]
1189404b540aSrobert  "! TARGET_BWX"
1190404b540aSrobert  "and %1,0xff,%0"
1191404b540aSrobert  [(set_attr "type" "ilog")])
1192404b540aSrobert
1193404b540aSrobert(define_expand "zero_extendqisi2"
1194404b540aSrobert  [(set (match_operand:SI 0 "register_operand" "")
1195404b540aSrobert	(zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))]
1196404b540aSrobert  ""
1197404b540aSrobert{
1198404b540aSrobert  if (! TARGET_BWX)
1199404b540aSrobert    operands[1] = force_reg (QImode, operands[1]);
1200404b540aSrobert})
1201404b540aSrobert
1202404b540aSrobert(define_insn "*zero_extendqisi2_bwx"
1203404b540aSrobert  [(set (match_operand:SI 0 "register_operand" "=r,r")
1204404b540aSrobert	(zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "r,m")))]
1205404b540aSrobert  "TARGET_BWX"
1206404b540aSrobert  "@
1207404b540aSrobert   and %1,0xff,%0
1208404b540aSrobert   ldbu %0,%1"
1209404b540aSrobert  [(set_attr "type" "ilog,ild")])
1210404b540aSrobert
1211404b540aSrobert(define_insn "*zero_extendqisi2_nobwx"
1212404b540aSrobert  [(set (match_operand:SI 0 "register_operand" "=r")
1213404b540aSrobert	(zero_extend:SI (match_operand:QI 1 "register_operand" "r")))]
1214404b540aSrobert  "! TARGET_BWX"
1215404b540aSrobert  "and %1,0xff,%0"
1216404b540aSrobert  [(set_attr "type" "ilog")])
1217404b540aSrobert
1218404b540aSrobert(define_expand "zero_extendqidi2"
1219404b540aSrobert  [(set (match_operand:DI 0 "register_operand" "")
1220404b540aSrobert	(zero_extend:DI (match_operand:QI 1 "nonimmediate_operand" "")))]
1221404b540aSrobert  ""
1222404b540aSrobert{
1223404b540aSrobert  if (! TARGET_BWX)
1224404b540aSrobert    operands[1] = force_reg (QImode, operands[1]);
1225404b540aSrobert})
1226404b540aSrobert
1227404b540aSrobert(define_insn "*zero_extendqidi2_bwx"
1228404b540aSrobert  [(set (match_operand:DI 0 "register_operand" "=r,r")
1229404b540aSrobert	(zero_extend:DI (match_operand:QI 1 "nonimmediate_operand" "r,m")))]
1230404b540aSrobert  "TARGET_BWX"
1231404b540aSrobert  "@
1232404b540aSrobert   and %1,0xff,%0
1233404b540aSrobert   ldbu %0,%1"
1234404b540aSrobert  [(set_attr "type" "ilog,ild")])
1235404b540aSrobert
1236404b540aSrobert(define_insn "*zero_extendqidi2_nobwx"
1237404b540aSrobert  [(set (match_operand:DI 0 "register_operand" "=r")
1238404b540aSrobert	(zero_extend:DI (match_operand:QI 1 "register_operand" "r")))]
1239404b540aSrobert  "! TARGET_BWX"
1240404b540aSrobert  "and %1,0xff,%0"
1241404b540aSrobert  [(set_attr "type" "ilog")])
1242404b540aSrobert
1243404b540aSrobert(define_expand "zero_extendhisi2"
1244404b540aSrobert  [(set (match_operand:SI 0 "register_operand" "")
1245404b540aSrobert	(zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
1246404b540aSrobert  ""
1247404b540aSrobert{
1248404b540aSrobert  if (! TARGET_BWX)
1249404b540aSrobert    operands[1] = force_reg (HImode, operands[1]);
1250404b540aSrobert})
1251404b540aSrobert
1252404b540aSrobert(define_insn "*zero_extendhisi2_bwx"
1253404b540aSrobert  [(set (match_operand:SI 0 "register_operand" "=r,r")
1254404b540aSrobert	(zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "r,m")))]
1255404b540aSrobert  "TARGET_BWX"
1256404b540aSrobert  "@
1257404b540aSrobert   zapnot %1,3,%0
1258404b540aSrobert   ldwu %0,%1"
1259404b540aSrobert  [(set_attr "type" "shift,ild")])
1260404b540aSrobert
1261404b540aSrobert(define_insn "*zero_extendhisi2_nobwx"
1262404b540aSrobert  [(set (match_operand:SI 0 "register_operand" "=r")
1263404b540aSrobert	(zero_extend:SI (match_operand:HI 1 "register_operand" "r")))]
1264404b540aSrobert  "! TARGET_BWX"
1265404b540aSrobert  "zapnot %1,3,%0"
1266404b540aSrobert  [(set_attr "type" "shift")])
1267404b540aSrobert
1268404b540aSrobert(define_expand "zero_extendhidi2"
1269404b540aSrobert  [(set (match_operand:DI 0 "register_operand" "")
1270404b540aSrobert	(zero_extend:DI (match_operand:HI 1 "nonimmediate_operand" "")))]
1271404b540aSrobert  ""
1272404b540aSrobert{
1273404b540aSrobert  if (! TARGET_BWX)
1274404b540aSrobert    operands[1] = force_reg (HImode, operands[1]);
1275404b540aSrobert})
1276404b540aSrobert
1277404b540aSrobert(define_insn "*zero_extendhidi2_bwx"
1278404b540aSrobert  [(set (match_operand:DI 0 "register_operand" "=r,r")
1279404b540aSrobert	(zero_extend:DI (match_operand:HI 1 "nonimmediate_operand" "r,m")))]
1280404b540aSrobert  "TARGET_BWX"
1281404b540aSrobert  "@
1282404b540aSrobert   zapnot %1,3,%0
1283404b540aSrobert   ldwu %0,%1"
1284404b540aSrobert  [(set_attr "type" "shift,ild")])
1285404b540aSrobert
1286404b540aSrobert(define_insn "*zero_extendhidi2_nobwx"
1287404b540aSrobert  [(set (match_operand:DI 0 "register_operand" "=r")
1288404b540aSrobert	(zero_extend:DI (match_operand:HI 1 "register_operand" "r")))]
1289404b540aSrobert  ""
1290404b540aSrobert  "zapnot %1,3,%0"
1291404b540aSrobert  [(set_attr "type" "shift")])
1292404b540aSrobert
1293404b540aSrobert(define_insn "zero_extendsidi2"
1294404b540aSrobert  [(set (match_operand:DI 0 "register_operand" "=r")
1295404b540aSrobert	(zero_extend:DI (match_operand:SI 1 "register_operand" "r")))]
1296404b540aSrobert  ""
1297404b540aSrobert  "zapnot %1,15,%0"
1298404b540aSrobert  [(set_attr "type" "shift")])
1299404b540aSrobert
1300404b540aSrobert(define_insn "*andnotsi3"
1301404b540aSrobert  [(set (match_operand:SI 0 "register_operand" "=r")
1302404b540aSrobert	(and:SI (not:SI (match_operand:SI 1 "reg_or_8bit_operand" "rI"))
1303404b540aSrobert		(match_operand:SI 2 "reg_or_0_operand" "rJ")))]
1304404b540aSrobert  ""
1305404b540aSrobert  "bic %r2,%1,%0"
1306404b540aSrobert  [(set_attr "type" "ilog")])
1307404b540aSrobert
1308404b540aSrobert(define_insn "andnotdi3"
1309404b540aSrobert  [(set (match_operand:DI 0 "register_operand" "=r")
1310404b540aSrobert	(and:DI (not:DI (match_operand:DI 1 "reg_or_8bit_operand" "rI"))
1311404b540aSrobert		(match_operand:DI 2 "reg_or_0_operand" "rJ")))]
1312404b540aSrobert  ""
1313404b540aSrobert  "bic %r2,%1,%0"
1314404b540aSrobert  [(set_attr "type" "ilog")])
1315404b540aSrobert
1316404b540aSrobert(define_insn "*iorsi_internal"
1317404b540aSrobert  [(set (match_operand:SI 0 "register_operand" "=r,r")
1318404b540aSrobert	(ior:SI (match_operand:SI 1 "reg_or_0_operand" "%rJ,rJ")
1319404b540aSrobert		(match_operand:SI 2 "or_operand" "rI,N")))]
1320404b540aSrobert  ""
1321404b540aSrobert  "@
1322404b540aSrobert   bis %r1,%2,%0
1323404b540aSrobert   ornot %r1,%N2,%0"
1324404b540aSrobert  [(set_attr "type" "ilog")])
1325404b540aSrobert
1326404b540aSrobert(define_insn "iordi3"
1327404b540aSrobert  [(set (match_operand:DI 0 "register_operand" "=r,r")
1328404b540aSrobert	(ior:DI (match_operand:DI 1 "reg_or_0_operand" "%rJ,rJ")
1329404b540aSrobert		(match_operand:DI 2 "or_operand" "rI,N")))]
1330404b540aSrobert  ""
1331404b540aSrobert  "@
1332404b540aSrobert   bis %r1,%2,%0
1333404b540aSrobert   ornot %r1,%N2,%0"
1334404b540aSrobert  [(set_attr "type" "ilog")])
1335404b540aSrobert
1336404b540aSrobert(define_insn "*one_cmplsi_internal"
1337404b540aSrobert  [(set (match_operand:SI 0 "register_operand" "=r")
1338404b540aSrobert	(not:SI (match_operand:SI 1 "reg_or_8bit_operand" "rI")))]
1339404b540aSrobert  ""
1340404b540aSrobert  "ornot $31,%1,%0"
1341404b540aSrobert  [(set_attr "type" "ilog")])
1342404b540aSrobert
1343404b540aSrobert(define_insn "one_cmpldi2"
1344404b540aSrobert  [(set (match_operand:DI 0 "register_operand" "=r")
1345404b540aSrobert	(not:DI (match_operand:DI 1 "reg_or_8bit_operand" "rI")))]
1346404b540aSrobert  ""
1347404b540aSrobert  "ornot $31,%1,%0"
1348404b540aSrobert  [(set_attr "type" "ilog")])
1349404b540aSrobert
1350404b540aSrobert(define_insn "*iornotsi3"
1351404b540aSrobert  [(set (match_operand:SI 0 "register_operand" "=r")
1352404b540aSrobert	(ior:SI (not:SI (match_operand:SI 1 "reg_or_8bit_operand" "rI"))
1353404b540aSrobert		(match_operand:SI 2 "reg_or_0_operand" "rJ")))]
1354404b540aSrobert  ""
1355404b540aSrobert  "ornot %r2,%1,%0"
1356404b540aSrobert  [(set_attr "type" "ilog")])
1357404b540aSrobert
1358404b540aSrobert(define_insn "*iornotdi3"
1359404b540aSrobert  [(set (match_operand:DI 0 "register_operand" "=r")
1360404b540aSrobert	(ior:DI (not:DI (match_operand:DI 1 "reg_or_8bit_operand" "rI"))
1361404b540aSrobert		(match_operand:DI 2 "reg_or_0_operand" "rJ")))]
1362404b540aSrobert  ""
1363404b540aSrobert  "ornot %r2,%1,%0"
1364404b540aSrobert  [(set_attr "type" "ilog")])
1365404b540aSrobert
1366404b540aSrobert(define_insn "*xorsi_internal"
1367404b540aSrobert  [(set (match_operand:SI 0 "register_operand" "=r,r")
1368404b540aSrobert	(xor:SI (match_operand:SI 1 "reg_or_0_operand" "%rJ,rJ")
1369404b540aSrobert		(match_operand:SI 2 "or_operand" "rI,N")))]
1370404b540aSrobert  ""
1371404b540aSrobert  "@
1372404b540aSrobert   xor %r1,%2,%0
1373404b540aSrobert   eqv %r1,%N2,%0"
1374404b540aSrobert  [(set_attr "type" "ilog")])
1375404b540aSrobert
1376404b540aSrobert(define_insn "xordi3"
1377404b540aSrobert  [(set (match_operand:DI 0 "register_operand" "=r,r")
1378404b540aSrobert	(xor:DI (match_operand:DI 1 "reg_or_0_operand" "%rJ,rJ")
1379404b540aSrobert		(match_operand:DI 2 "or_operand" "rI,N")))]
1380404b540aSrobert  ""
1381404b540aSrobert  "@
1382404b540aSrobert   xor %r1,%2,%0
1383404b540aSrobert   eqv %r1,%N2,%0"
1384404b540aSrobert  [(set_attr "type" "ilog")])
1385404b540aSrobert
1386404b540aSrobert(define_insn "*xornotsi3"
1387404b540aSrobert  [(set (match_operand:SI 0 "register_operand" "=r")
1388404b540aSrobert	(not:SI (xor:SI (match_operand:SI 1 "register_operand" "%rJ")
1389404b540aSrobert			(match_operand:SI 2 "register_operand" "rI"))))]
1390404b540aSrobert  ""
1391404b540aSrobert  "eqv %r1,%2,%0"
1392404b540aSrobert  [(set_attr "type" "ilog")])
1393404b540aSrobert
1394404b540aSrobert(define_insn "*xornotdi3"
1395404b540aSrobert  [(set (match_operand:DI 0 "register_operand" "=r")
1396404b540aSrobert	(not:DI (xor:DI (match_operand:DI 1 "register_operand" "%rJ")
1397404b540aSrobert			(match_operand:DI 2 "register_operand" "rI"))))]
1398404b540aSrobert  ""
1399404b540aSrobert  "eqv %r1,%2,%0"
1400404b540aSrobert  [(set_attr "type" "ilog")])
1401404b540aSrobert
1402404b540aSrobert;; Handle FFS and related insns iff we support CIX.
1403404b540aSrobert
1404404b540aSrobert(define_expand "ffsdi2"
1405404b540aSrobert  [(set (match_dup 2)
1406404b540aSrobert	(ctz:DI (match_operand:DI 1 "register_operand" "")))
1407404b540aSrobert   (set (match_dup 3)
1408404b540aSrobert	(plus:DI (match_dup 2) (const_int 1)))
1409404b540aSrobert   (set (match_operand:DI 0 "register_operand" "")
1410404b540aSrobert	(if_then_else:DI (eq (match_dup 1) (const_int 0))
1411404b540aSrobert			 (const_int 0) (match_dup 3)))]
1412404b540aSrobert  "TARGET_CIX"
1413404b540aSrobert{
1414404b540aSrobert  operands[2] = gen_reg_rtx (DImode);
1415404b540aSrobert  operands[3] = gen_reg_rtx (DImode);
1416404b540aSrobert})
1417404b540aSrobert
1418404b540aSrobert(define_insn "clzdi2"
1419404b540aSrobert  [(set (match_operand:DI 0 "register_operand" "=r")
1420404b540aSrobert	(clz:DI (match_operand:DI 1 "register_operand" "r")))]
1421404b540aSrobert  "TARGET_CIX"
1422404b540aSrobert  "ctlz %1,%0"
1423404b540aSrobert  [(set_attr "type" "mvi")])
1424404b540aSrobert
1425404b540aSrobert(define_insn "ctzdi2"
1426404b540aSrobert  [(set (match_operand:DI 0 "register_operand" "=r")
1427404b540aSrobert	(ctz:DI (match_operand:DI 1 "register_operand" "r")))]
1428404b540aSrobert  "TARGET_CIX"
1429404b540aSrobert  "cttz %1,%0"
1430404b540aSrobert  [(set_attr "type" "mvi")])
1431404b540aSrobert
1432404b540aSrobert(define_insn "popcountdi2"
1433404b540aSrobert  [(set (match_operand:DI 0 "register_operand" "=r")
1434404b540aSrobert	(popcount:DI (match_operand:DI 1 "register_operand" "r")))]
1435404b540aSrobert  "TARGET_CIX"
1436404b540aSrobert  "ctpop %1,%0"
1437404b540aSrobert  [(set_attr "type" "mvi")])
1438404b540aSrobert
1439404b540aSrobert;; Next come the shifts and the various extract and insert operations.
1440404b540aSrobert
1441404b540aSrobert(define_insn "ashldi3"
1442404b540aSrobert  [(set (match_operand:DI 0 "register_operand" "=r,r")
1443404b540aSrobert	(ashift:DI (match_operand:DI 1 "reg_or_0_operand" "rJ,rJ")
1444404b540aSrobert		   (match_operand:DI 2 "reg_or_6bit_operand" "P,rS")))]
1445404b540aSrobert  ""
1446404b540aSrobert{
1447404b540aSrobert  switch (which_alternative)
1448404b540aSrobert    {
1449404b540aSrobert    case 0:
1450404b540aSrobert      if (operands[2] == const1_rtx)
1451404b540aSrobert	return "addq %r1,%r1,%0";
1452404b540aSrobert      else
1453404b540aSrobert	return "s%P2addq %r1,0,%0";
1454404b540aSrobert    case 1:
1455404b540aSrobert      return "sll %r1,%2,%0";
1456404b540aSrobert    default:
1457404b540aSrobert      gcc_unreachable ();
1458404b540aSrobert    }
1459404b540aSrobert}
1460404b540aSrobert  [(set_attr "type" "iadd,shift")])
1461404b540aSrobert
1462404b540aSrobert(define_insn "*ashldi_se"
1463404b540aSrobert  [(set (match_operand:DI 0 "register_operand" "=r")
1464404b540aSrobert	(sign_extend:DI
1465404b540aSrobert	 (subreg:SI (ashift:DI (match_operand:DI 1 "reg_or_0_operand" "rJ")
1466404b540aSrobert			       (match_operand:DI 2 "const_int_operand" "P"))
1467404b540aSrobert		    0)))]
1468404b540aSrobert  "INTVAL (operands[2]) >= 1 && INTVAL (operands[2]) <= 3"
1469404b540aSrobert{
1470404b540aSrobert  if (operands[2] == const1_rtx)
1471404b540aSrobert    return "addl %r1,%r1,%0";
1472404b540aSrobert  else
1473404b540aSrobert    return "s%P2addl %r1,0,%0";
1474404b540aSrobert}
1475404b540aSrobert  [(set_attr "type" "iadd")])
1476404b540aSrobert
1477404b540aSrobert(define_insn "lshrdi3"
1478404b540aSrobert  [(set (match_operand:DI 0 "register_operand" "=r")
1479404b540aSrobert	(lshiftrt:DI (match_operand:DI 1 "reg_or_0_operand" "rJ")
1480404b540aSrobert		     (match_operand:DI 2 "reg_or_6bit_operand" "rS")))]
1481404b540aSrobert  ""
1482404b540aSrobert  "srl %r1,%2,%0"
1483404b540aSrobert  [(set_attr "type" "shift")])
1484404b540aSrobert
1485404b540aSrobert(define_insn "ashrdi3"
1486404b540aSrobert  [(set (match_operand:DI 0 "register_operand" "=r")
1487404b540aSrobert	(ashiftrt:DI (match_operand:DI 1 "reg_or_0_operand" "rJ")
1488404b540aSrobert		     (match_operand:DI 2 "reg_or_6bit_operand" "rS")))]
1489404b540aSrobert  ""
1490404b540aSrobert  "sra %r1,%2,%0"
1491404b540aSrobert  [(set_attr "type" "shift")])
1492404b540aSrobert
1493404b540aSrobert(define_expand "extendqihi2"
1494404b540aSrobert  [(set (match_dup 2)
1495404b540aSrobert	(ashift:DI (match_operand:QI 1 "some_operand" "")
1496404b540aSrobert		   (const_int 56)))
1497404b540aSrobert   (set (match_operand:HI 0 "register_operand" "")
1498404b540aSrobert	(ashiftrt:DI (match_dup 2)
1499404b540aSrobert		     (const_int 56)))]
1500404b540aSrobert  ""
1501404b540aSrobert{
1502404b540aSrobert  if (TARGET_BWX)
1503404b540aSrobert    {
1504404b540aSrobert      emit_insn (gen_extendqihi2x (operands[0],
1505404b540aSrobert				   force_reg (QImode, operands[1])));
1506404b540aSrobert      DONE;
1507404b540aSrobert    }
1508404b540aSrobert
1509404b540aSrobert /* If we have an unaligned MEM, extend to DImode (which we do
1510404b540aSrobert     specially) and then copy to the result.  */
1511404b540aSrobert  if (unaligned_memory_operand (operands[1], HImode))
1512404b540aSrobert    {
1513404b540aSrobert      rtx temp = gen_reg_rtx (DImode);
1514404b540aSrobert
1515404b540aSrobert      emit_insn (gen_extendqidi2 (temp, operands[1]));
1516404b540aSrobert      emit_move_insn (operands[0], gen_lowpart (HImode, temp));
1517404b540aSrobert      DONE;
1518404b540aSrobert    }
1519404b540aSrobert
1520404b540aSrobert  operands[0] = gen_lowpart (DImode, operands[0]);
1521404b540aSrobert  operands[1] = gen_lowpart (DImode, force_reg (QImode, operands[1]));
1522404b540aSrobert  operands[2] = gen_reg_rtx (DImode);
1523404b540aSrobert})
1524404b540aSrobert
1525404b540aSrobert(define_insn "extendqidi2x"
1526404b540aSrobert  [(set (match_operand:DI 0 "register_operand" "=r")
1527404b540aSrobert	(sign_extend:DI (match_operand:QI 1 "register_operand" "r")))]
1528404b540aSrobert  "TARGET_BWX"
1529404b540aSrobert  "sextb %1,%0"
1530404b540aSrobert  [(set_attr "type" "shift")])
1531404b540aSrobert
1532404b540aSrobert(define_insn "extendhidi2x"
1533404b540aSrobert  [(set (match_operand:DI 0 "register_operand" "=r")
1534404b540aSrobert	(sign_extend:DI (match_operand:HI 1 "register_operand" "r")))]
1535404b540aSrobert  "TARGET_BWX"
1536404b540aSrobert  "sextw %1,%0"
1537404b540aSrobert  [(set_attr "type" "shift")])
1538404b540aSrobert
1539404b540aSrobert(define_insn "extendqisi2x"
1540404b540aSrobert  [(set (match_operand:SI 0 "register_operand" "=r")
1541404b540aSrobert	(sign_extend:SI (match_operand:QI 1 "register_operand" "r")))]
1542404b540aSrobert  "TARGET_BWX"
1543404b540aSrobert  "sextb %1,%0"
1544404b540aSrobert  [(set_attr "type" "shift")])
1545404b540aSrobert
1546404b540aSrobert(define_insn "extendhisi2x"
1547404b540aSrobert  [(set (match_operand:SI 0 "register_operand" "=r")
1548404b540aSrobert	(sign_extend:SI (match_operand:HI 1 "register_operand" "r")))]
1549404b540aSrobert  "TARGET_BWX"
1550404b540aSrobert  "sextw %1,%0"
1551404b540aSrobert  [(set_attr "type" "shift")])
1552404b540aSrobert
1553404b540aSrobert(define_insn "extendqihi2x"
1554404b540aSrobert  [(set (match_operand:HI 0 "register_operand" "=r")
1555404b540aSrobert	(sign_extend:HI (match_operand:QI 1 "register_operand" "r")))]
1556404b540aSrobert  "TARGET_BWX"
1557404b540aSrobert  "sextb %1,%0"
1558404b540aSrobert  [(set_attr "type" "shift")])
1559404b540aSrobert
1560404b540aSrobert(define_expand "extendqisi2"
1561404b540aSrobert  [(set (match_dup 2)
1562404b540aSrobert	(ashift:DI (match_operand:QI 1 "some_operand" "")
1563404b540aSrobert		   (const_int 56)))
1564404b540aSrobert   (set (match_operand:SI 0 "register_operand" "")
1565404b540aSrobert	(ashiftrt:DI (match_dup 2)
1566404b540aSrobert		     (const_int 56)))]
1567404b540aSrobert  ""
1568404b540aSrobert{
1569404b540aSrobert  if (TARGET_BWX)
1570404b540aSrobert    {
1571404b540aSrobert      emit_insn (gen_extendqisi2x (operands[0],
1572404b540aSrobert				   force_reg (QImode, operands[1])));
1573404b540aSrobert      DONE;
1574404b540aSrobert    }
1575404b540aSrobert
1576404b540aSrobert  /* If we have an unaligned MEM, extend to a DImode form of
1577404b540aSrobert     the result (which we do specially).  */
1578404b540aSrobert  if (unaligned_memory_operand (operands[1], QImode))
1579404b540aSrobert    {
1580404b540aSrobert      rtx temp = gen_reg_rtx (DImode);
1581404b540aSrobert
1582404b540aSrobert      emit_insn (gen_extendqidi2 (temp, operands[1]));
1583404b540aSrobert      emit_move_insn (operands[0], gen_lowpart (SImode, temp));
1584404b540aSrobert      DONE;
1585404b540aSrobert    }
1586404b540aSrobert
1587404b540aSrobert  operands[0] = gen_lowpart (DImode, operands[0]);
1588404b540aSrobert  operands[1] = gen_lowpart (DImode, force_reg (QImode, operands[1]));
1589404b540aSrobert  operands[2] = gen_reg_rtx (DImode);
1590404b540aSrobert})
1591404b540aSrobert
1592404b540aSrobert(define_expand "extendqidi2"
1593404b540aSrobert  [(set (match_dup 2)
1594404b540aSrobert	(ashift:DI (match_operand:QI 1 "some_operand" "")
1595404b540aSrobert		   (const_int 56)))
1596404b540aSrobert   (set (match_operand:DI 0 "register_operand" "")
1597404b540aSrobert	(ashiftrt:DI (match_dup 2)
1598404b540aSrobert		     (const_int 56)))]
1599404b540aSrobert  ""
1600404b540aSrobert{
1601404b540aSrobert  if (TARGET_BWX)
1602404b540aSrobert    {
1603404b540aSrobert      emit_insn (gen_extendqidi2x (operands[0],
1604404b540aSrobert				   force_reg (QImode, operands[1])));
1605404b540aSrobert      DONE;
1606404b540aSrobert    }
1607404b540aSrobert
1608404b540aSrobert  if (unaligned_memory_operand (operands[1], QImode))
1609404b540aSrobert    {
1610404b540aSrobert      rtx seq = gen_unaligned_extendqidi (operands[0], XEXP (operands[1], 0));
1611404b540aSrobert      alpha_set_memflags (seq, operands[1]);
1612404b540aSrobert      emit_insn (seq);
1613404b540aSrobert      DONE;
1614404b540aSrobert    }
1615404b540aSrobert
1616404b540aSrobert  operands[1] = gen_lowpart (DImode, force_reg (QImode, operands[1]));
1617404b540aSrobert  operands[2] = gen_reg_rtx (DImode);
1618404b540aSrobert})
1619404b540aSrobert
1620404b540aSrobert(define_expand "extendhisi2"
1621404b540aSrobert  [(set (match_dup 2)
1622404b540aSrobert	(ashift:DI (match_operand:HI 1 "some_operand" "")
1623404b540aSrobert		   (const_int 48)))
1624404b540aSrobert   (set (match_operand:SI 0 "register_operand" "")
1625404b540aSrobert	(ashiftrt:DI (match_dup 2)
1626404b540aSrobert		     (const_int 48)))]
1627404b540aSrobert  ""
1628404b540aSrobert{
1629404b540aSrobert  if (TARGET_BWX)
1630404b540aSrobert    {
1631404b540aSrobert      emit_insn (gen_extendhisi2x (operands[0],
1632404b540aSrobert				   force_reg (HImode, operands[1])));
1633404b540aSrobert      DONE;
1634404b540aSrobert    }
1635404b540aSrobert
1636404b540aSrobert  /* If we have an unaligned MEM, extend to a DImode form of
1637404b540aSrobert     the result (which we do specially).  */
1638404b540aSrobert  if (unaligned_memory_operand (operands[1], HImode))
1639404b540aSrobert    {
1640404b540aSrobert      rtx temp = gen_reg_rtx (DImode);
1641404b540aSrobert
1642404b540aSrobert      emit_insn (gen_extendhidi2 (temp, operands[1]));
1643404b540aSrobert      emit_move_insn (operands[0], gen_lowpart (SImode, temp));
1644404b540aSrobert      DONE;
1645404b540aSrobert    }
1646404b540aSrobert
1647404b540aSrobert  operands[0] = gen_lowpart (DImode, operands[0]);
1648404b540aSrobert  operands[1] = gen_lowpart (DImode, force_reg (HImode, operands[1]));
1649404b540aSrobert  operands[2] = gen_reg_rtx (DImode);
1650404b540aSrobert})
1651404b540aSrobert
1652404b540aSrobert(define_expand "extendhidi2"
1653404b540aSrobert  [(set (match_dup 2)
1654404b540aSrobert	(ashift:DI (match_operand:HI 1 "some_operand" "")
1655404b540aSrobert		   (const_int 48)))
1656404b540aSrobert   (set (match_operand:DI 0 "register_operand" "")
1657404b540aSrobert	(ashiftrt:DI (match_dup 2)
1658404b540aSrobert		     (const_int 48)))]
1659404b540aSrobert  ""
1660404b540aSrobert{
1661404b540aSrobert  if (TARGET_BWX)
1662404b540aSrobert    {
1663404b540aSrobert      emit_insn (gen_extendhidi2x (operands[0],
1664404b540aSrobert				   force_reg (HImode, operands[1])));
1665404b540aSrobert      DONE;
1666404b540aSrobert    }
1667404b540aSrobert
1668404b540aSrobert  if (unaligned_memory_operand (operands[1], HImode))
1669404b540aSrobert    {
1670404b540aSrobert      rtx seq = gen_unaligned_extendhidi (operands[0], XEXP (operands[1], 0));
1671404b540aSrobert
1672404b540aSrobert      alpha_set_memflags (seq, operands[1]);
1673404b540aSrobert      emit_insn (seq);
1674404b540aSrobert      DONE;
1675404b540aSrobert    }
1676404b540aSrobert
1677404b540aSrobert  operands[1] = gen_lowpart (DImode, force_reg (HImode, operands[1]));
1678404b540aSrobert  operands[2] = gen_reg_rtx (DImode);
1679404b540aSrobert})
1680404b540aSrobert
1681404b540aSrobert;; Here's how we sign extend an unaligned byte and halfword.  Doing this
1682404b540aSrobert;; as a pattern saves one instruction.  The code is similar to that for
1683404b540aSrobert;; the unaligned loads (see below).
1684404b540aSrobert;;
1685404b540aSrobert;; Operand 1 is the address, operand 0 is the result.
1686404b540aSrobert(define_expand "unaligned_extendqidi"
1687404b540aSrobert  [(use (match_operand:QI 0 "register_operand" ""))
1688404b540aSrobert   (use (match_operand:DI 1 "address_operand" ""))]
1689404b540aSrobert  ""
1690404b540aSrobert{
1691404b540aSrobert  operands[0] = gen_lowpart (DImode, operands[0]);
1692404b540aSrobert  if (WORDS_BIG_ENDIAN)
1693404b540aSrobert    emit_insn (gen_unaligned_extendqidi_be (operands[0], operands[1]));
1694404b540aSrobert  else
1695404b540aSrobert    emit_insn (gen_unaligned_extendqidi_le (operands[0], operands[1]));
1696404b540aSrobert  DONE;
1697404b540aSrobert})
1698404b540aSrobert
1699404b540aSrobert(define_expand "unaligned_extendqidi_le"
1700404b540aSrobert  [(set (match_dup 3)
1701404b540aSrobert	(mem:DI (and:DI (match_operand:DI 1 "" "") (const_int -8))))
1702404b540aSrobert   (set (match_dup 4)
1703404b540aSrobert	(ashift:DI (match_dup 3)
1704*7014c930Smartynas		   (minus:DI (const_int 56)
1705404b540aSrobert			     (ashift:DI
1706*7014c930Smartynas			      (and:DI (plus:DI (match_dup 2) (const_int -1))
1707*7014c930Smartynas				      (const_int 7))
1708404b540aSrobert			      (const_int 3)))))
1709404b540aSrobert   (set (match_operand:DI 0 "register_operand" "")
1710404b540aSrobert	(ashiftrt:DI (match_dup 4) (const_int 56)))]
1711404b540aSrobert  "! WORDS_BIG_ENDIAN"
1712404b540aSrobert{
1713404b540aSrobert  operands[2] = get_unaligned_offset (operands[1], 1);
1714404b540aSrobert  operands[3] = gen_reg_rtx (DImode);
1715404b540aSrobert  operands[4] = gen_reg_rtx (DImode);
1716404b540aSrobert})
1717404b540aSrobert
1718404b540aSrobert(define_expand "unaligned_extendqidi_be"
1719404b540aSrobert  [(set (match_dup 3)
1720404b540aSrobert	(mem:DI (and:DI (match_operand:DI 1 "" "") (const_int -8))))
1721404b540aSrobert   (set (match_dup 4)
1722404b540aSrobert	(ashift:DI (match_dup 3)
1723404b540aSrobert		   (ashift:DI
1724404b540aSrobert		     (and:DI
1725404b540aSrobert		       (plus:DI (match_dup 2) (const_int 1))
1726404b540aSrobert		       (const_int 7))
1727404b540aSrobert		     (const_int 3))))
1728404b540aSrobert   (set (match_operand:DI 0 "register_operand" "")
1729404b540aSrobert	(ashiftrt:DI (match_dup 4) (const_int 56)))]
1730404b540aSrobert  "WORDS_BIG_ENDIAN"
1731404b540aSrobert{
1732404b540aSrobert  operands[2] = get_unaligned_offset (operands[1], -1);
1733404b540aSrobert  operands[3] = gen_reg_rtx (DImode);
1734404b540aSrobert  operands[4] = gen_reg_rtx (DImode);
1735404b540aSrobert})
1736404b540aSrobert
1737404b540aSrobert(define_expand "unaligned_extendhidi"
1738404b540aSrobert  [(use (match_operand:QI 0 "register_operand" ""))
1739404b540aSrobert   (use (match_operand:DI 1 "address_operand" ""))]
1740404b540aSrobert  ""
1741404b540aSrobert{
1742404b540aSrobert  operands[0] = gen_lowpart (DImode, operands[0]);
1743404b540aSrobert  if (WORDS_BIG_ENDIAN)
1744404b540aSrobert    emit_insn (gen_unaligned_extendhidi_be (operands[0], operands[1]));
1745404b540aSrobert  else
1746404b540aSrobert    emit_insn (gen_unaligned_extendhidi_le (operands[0], operands[1]));
1747404b540aSrobert  DONE;
1748404b540aSrobert})
1749404b540aSrobert
1750404b540aSrobert(define_expand "unaligned_extendhidi_le"
1751404b540aSrobert  [(set (match_dup 3)
1752404b540aSrobert	(mem:DI (and:DI (match_operand:DI 1 "" "") (const_int -8))))
1753404b540aSrobert   (set (match_dup 4)
1754404b540aSrobert	(ashift:DI (match_dup 3)
1755*7014c930Smartynas		   (minus:DI (const_int 56)
1756404b540aSrobert			     (ashift:DI
1757*7014c930Smartynas			      (and:DI (plus:DI (match_dup 2) (const_int -1))
1758*7014c930Smartynas				      (const_int 7))
1759404b540aSrobert			      (const_int 3)))))
1760404b540aSrobert   (set (match_operand:DI 0 "register_operand" "")
1761404b540aSrobert	(ashiftrt:DI (match_dup 4) (const_int 48)))]
1762404b540aSrobert  "! WORDS_BIG_ENDIAN"
1763404b540aSrobert{
1764404b540aSrobert  operands[2] = get_unaligned_offset (operands[1], 2);
1765404b540aSrobert  operands[3] = gen_reg_rtx (DImode);
1766404b540aSrobert  operands[4] = gen_reg_rtx (DImode);
1767404b540aSrobert})
1768404b540aSrobert
1769404b540aSrobert(define_expand "unaligned_extendhidi_be"
1770404b540aSrobert  [(set (match_dup 3)
1771404b540aSrobert	(mem:DI (and:DI (match_operand:DI 1 "" "") (const_int -8))))
1772404b540aSrobert   (set (match_dup 4)
1773404b540aSrobert	(ashift:DI (match_dup 3)
1774404b540aSrobert		   (ashift:DI
1775404b540aSrobert		     (and:DI
1776404b540aSrobert		       (plus:DI (match_dup 2) (const_int 1))
1777404b540aSrobert		       (const_int 7))
1778404b540aSrobert		     (const_int 3))))
1779404b540aSrobert   (set (match_operand:DI 0 "register_operand" "")
1780404b540aSrobert	(ashiftrt:DI (match_dup 4) (const_int 48)))]
1781404b540aSrobert  "WORDS_BIG_ENDIAN"
1782404b540aSrobert{
1783404b540aSrobert  operands[2] = get_unaligned_offset (operands[1], -1);
1784404b540aSrobert  operands[3] = gen_reg_rtx (DImode);
1785404b540aSrobert  operands[4] = gen_reg_rtx (DImode);
1786404b540aSrobert})
1787404b540aSrobert
1788404b540aSrobert(define_insn "*extxl_const"
1789404b540aSrobert  [(set (match_operand:DI 0 "register_operand" "=r")
1790404b540aSrobert	(zero_extract:DI (match_operand:DI 1 "reg_or_0_operand" "rJ")
1791404b540aSrobert			 (match_operand:DI 2 "mode_width_operand" "n")
1792404b540aSrobert			 (match_operand:DI 3 "mul8_operand" "I")))]
1793404b540aSrobert  ""
1794404b540aSrobert  "ext%M2l %r1,%s3,%0"
1795404b540aSrobert  [(set_attr "type" "shift")])
1796404b540aSrobert
1797404b540aSrobert(define_insn "extxl_le"
1798404b540aSrobert  [(set (match_operand:DI 0 "register_operand" "=r")
1799404b540aSrobert	(zero_extract:DI (match_operand:DI 1 "reg_or_0_operand" "rJ")
1800404b540aSrobert			 (match_operand:DI 2 "mode_width_operand" "n")
1801404b540aSrobert			 (ashift:DI (match_operand:DI 3 "reg_or_8bit_operand" "rI")
1802404b540aSrobert				    (const_int 3))))]
1803404b540aSrobert  "! WORDS_BIG_ENDIAN"
1804404b540aSrobert  "ext%M2l %r1,%3,%0"
1805404b540aSrobert  [(set_attr "type" "shift")])
1806404b540aSrobert
1807404b540aSrobert(define_insn "extxl_be"
1808404b540aSrobert  [(set (match_operand:DI 0 "register_operand" "=r")
1809404b540aSrobert	(zero_extract:DI (match_operand:DI 1 "reg_or_0_operand" "rJ")
1810404b540aSrobert			 (match_operand:DI 2 "mode_width_operand" "n")
1811404b540aSrobert			 (minus:DI
1812404b540aSrobert			   (const_int 56)
1813404b540aSrobert			   (ashift:DI
1814404b540aSrobert			     (match_operand:DI 3 "reg_or_8bit_operand" "rI")
1815404b540aSrobert			     (const_int 3)))))]
1816404b540aSrobert  "WORDS_BIG_ENDIAN"
1817404b540aSrobert  "ext%M2l %r1,%3,%0"
1818404b540aSrobert  [(set_attr "type" "shift")])
1819404b540aSrobert
1820404b540aSrobert;; Combine has some strange notion of preserving existing undefined behavior
1821404b540aSrobert;; in shifts larger than a word size.  So capture these patterns that it
1822404b540aSrobert;; should have turned into zero_extracts.
1823404b540aSrobert
1824404b540aSrobert(define_insn "*extxl_1_le"
1825404b540aSrobert  [(set (match_operand:DI 0 "register_operand" "=r")
1826404b540aSrobert	(and:DI (lshiftrt:DI (match_operand:DI 1 "reg_or_0_operand" "rJ")
1827404b540aSrobert		  (ashift:DI (match_operand:DI 2 "reg_or_8bit_operand" "rI")
1828404b540aSrobert			     (const_int 3)))
1829404b540aSrobert	     (match_operand:DI 3 "mode_mask_operand" "n")))]
1830404b540aSrobert  "! WORDS_BIG_ENDIAN"
1831404b540aSrobert  "ext%U3l %1,%2,%0"
1832404b540aSrobert  [(set_attr "type" "shift")])
1833404b540aSrobert
1834404b540aSrobert(define_insn "*extxl_1_be"
1835404b540aSrobert  [(set (match_operand:DI 0 "register_operand" "=r")
1836404b540aSrobert	(and:DI (lshiftrt:DI
1837404b540aSrobert		  (match_operand:DI 1 "reg_or_0_operand" "rJ")
1838404b540aSrobert		  (minus:DI (const_int 56)
1839404b540aSrobert		    (ashift:DI (match_operand:DI 2 "reg_or_8bit_operand" "rI")
1840404b540aSrobert			       (const_int 3))))
1841404b540aSrobert		(match_operand:DI 3 "mode_mask_operand" "n")))]
1842404b540aSrobert  "WORDS_BIG_ENDIAN"
1843404b540aSrobert  "ext%U3l %1,%2,%0"
1844404b540aSrobert  [(set_attr "type" "shift")])
1845404b540aSrobert
1846404b540aSrobert(define_insn "*extql_2_le"
1847404b540aSrobert  [(set (match_operand:DI 0 "register_operand" "=r")
1848404b540aSrobert	(lshiftrt:DI (match_operand:DI 1 "reg_or_0_operand" "rJ")
1849404b540aSrobert	  (ashift:DI (match_operand:DI 2 "reg_or_8bit_operand" "rI")
1850404b540aSrobert		     (const_int 3))))]
1851404b540aSrobert  "! WORDS_BIG_ENDIAN"
1852404b540aSrobert  "extql %1,%2,%0"
1853404b540aSrobert  [(set_attr "type" "shift")])
1854404b540aSrobert
1855404b540aSrobert(define_insn "*extql_2_be"
1856404b540aSrobert  [(set (match_operand:DI 0 "register_operand" "=r")
1857404b540aSrobert	(lshiftrt:DI
1858404b540aSrobert	  (match_operand:DI 1 "reg_or_0_operand" "rJ")
1859404b540aSrobert	  (minus:DI (const_int 56)
1860404b540aSrobert		    (ashift:DI
1861404b540aSrobert		      (match_operand:DI 2 "reg_or_8bit_operand" "rI")
1862404b540aSrobert		      (const_int 3)))))]
1863404b540aSrobert  "WORDS_BIG_ENDIAN"
1864404b540aSrobert  "extql %1,%2,%0"
1865404b540aSrobert  [(set_attr "type" "shift")])
1866404b540aSrobert
1867404b540aSrobert(define_insn "extqh_le"
1868404b540aSrobert  [(set (match_operand:DI 0 "register_operand" "=r")
1869404b540aSrobert	(ashift:DI
1870404b540aSrobert	 (match_operand:DI 1 "reg_or_0_operand" "rJ")
1871*7014c930Smartynas	  (minus:DI (const_int 56)
1872404b540aSrobert		    (ashift:DI
1873404b540aSrobert		     (and:DI
1874*7014c930Smartynas		      (plus:DI (match_operand:DI 2 "reg_or_8bit_operand" "rI")
1875*7014c930Smartynas			       (const_int -1))
1876404b540aSrobert		      (const_int 7))
1877404b540aSrobert		     (const_int 3)))))]
1878404b540aSrobert  "! WORDS_BIG_ENDIAN"
1879404b540aSrobert  "extqh %r1,%2,%0"
1880404b540aSrobert  [(set_attr "type" "shift")])
1881404b540aSrobert
1882404b540aSrobert(define_insn "extqh_be"
1883404b540aSrobert  [(set (match_operand:DI 0 "register_operand" "=r")
1884404b540aSrobert	(ashift:DI
1885404b540aSrobert	  (match_operand:DI 1 "reg_or_0_operand" "rJ")
1886404b540aSrobert	  (ashift:DI
1887404b540aSrobert	    (and:DI
1888404b540aSrobert	      (plus:DI (match_operand:DI 2 "reg_or_8bit_operand" "rI")
1889404b540aSrobert		       (const_int 1))
1890404b540aSrobert	      (const_int 7))
1891404b540aSrobert	    (const_int 3))))]
1892404b540aSrobert  "WORDS_BIG_ENDIAN"
1893404b540aSrobert  "extqh %r1,%2,%0"
1894404b540aSrobert  [(set_attr "type" "shift")])
1895404b540aSrobert
1896404b540aSrobert(define_insn "extlh_le"
1897404b540aSrobert  [(set (match_operand:DI 0 "register_operand" "=r")
1898404b540aSrobert	(ashift:DI
1899404b540aSrobert	 (and:DI (match_operand:DI 1 "reg_or_0_operand" "rJ")
1900404b540aSrobert		 (const_int 2147483647))
1901*7014c930Smartynas	 (minus:DI (const_int 56)
1902404b540aSrobert		    (ashift:DI
1903404b540aSrobert		     (and:DI
1904*7014c930Smartynas		      (plus:DI (match_operand:DI 2 "reg_or_8bit_operand" "rI")
1905*7014c930Smartynas			       (const_int -1))
1906404b540aSrobert		      (const_int 7))
1907404b540aSrobert		     (const_int 3)))))]
1908404b540aSrobert  "! WORDS_BIG_ENDIAN"
1909404b540aSrobert  "extlh %r1,%2,%0"
1910404b540aSrobert  [(set_attr "type" "shift")])
1911404b540aSrobert
1912404b540aSrobert(define_insn "extlh_be"
1913404b540aSrobert  [(set (match_operand:DI 0 "register_operand" "=r")
1914404b540aSrobert	(and:DI
1915404b540aSrobert	  (ashift:DI
1916404b540aSrobert	    (match_operand:DI 1 "reg_or_0_operand" "rJ")
1917404b540aSrobert	    (ashift:DI
1918404b540aSrobert	      (and:DI
1919404b540aSrobert		(plus:DI
1920404b540aSrobert		  (match_operand:DI 2 "reg_or_8bit_operand" "rI")
1921404b540aSrobert		  (const_int 1))
1922404b540aSrobert		(const_int 7))
1923404b540aSrobert	      (const_int 3)))
1924404b540aSrobert	  (const_int 2147483647)))]
1925404b540aSrobert  "WORDS_BIG_ENDIAN"
1926404b540aSrobert  "extlh %r1,%2,%0"
1927404b540aSrobert  [(set_attr "type" "shift")])
1928404b540aSrobert
1929404b540aSrobert(define_insn "extwh_le"
1930404b540aSrobert  [(set (match_operand:DI 0 "register_operand" "=r")
1931404b540aSrobert	(ashift:DI
1932404b540aSrobert	 (and:DI (match_operand:DI 1 "reg_or_0_operand" "rJ")
1933404b540aSrobert		 (const_int 65535))
1934*7014c930Smartynas	 (minus:DI (const_int 56)
1935404b540aSrobert		    (ashift:DI
1936404b540aSrobert		     (and:DI
1937*7014c930Smartynas		      (plus:DI (match_operand:DI 2 "reg_or_8bit_operand" "rI")
1938*7014c930Smartynas			       (const_int -1))
1939404b540aSrobert		      (const_int 7))
1940404b540aSrobert		     (const_int 3)))))]
1941404b540aSrobert  "! WORDS_BIG_ENDIAN"
1942404b540aSrobert  "extwh %r1,%2,%0"
1943404b540aSrobert  [(set_attr "type" "shift")])
1944404b540aSrobert
1945404b540aSrobert(define_insn "extwh_be"
1946404b540aSrobert  [(set (match_operand:DI 0 "register_operand" "=r")
1947404b540aSrobert	(and:DI
1948404b540aSrobert	  (ashift:DI (match_operand:DI 1 "reg_or_0_operand" "rJ")
1949404b540aSrobert		     (ashift:DI
1950404b540aSrobert		       (and:DI
1951404b540aSrobert			 (plus:DI
1952404b540aSrobert			   (match_operand:DI 2 "reg_or_8bit_operand" "rI")
1953404b540aSrobert			   (const_int 1))
1954404b540aSrobert			 (const_int 7))
1955404b540aSrobert		       (const_int 3)))
1956404b540aSrobert	  (const_int 65535)))]
1957404b540aSrobert  "WORDS_BIG_ENDIAN"
1958404b540aSrobert  "extwh %r1,%2,%0"
1959404b540aSrobert  [(set_attr "type" "shift")])
1960404b540aSrobert
1961404b540aSrobert;; This converts an extXl into an extXh with an appropriate adjustment
1962404b540aSrobert;; to the address calculation.
1963404b540aSrobert
1964404b540aSrobert;;(define_split
1965404b540aSrobert;;  [(set (match_operand:DI 0 "register_operand" "")
1966404b540aSrobert;;	(ashift:DI (zero_extract:DI (match_operand:DI 1 "register_operand" "")
1967404b540aSrobert;;				    (match_operand:DI 2 "mode_width_operand" "")
1968404b540aSrobert;;				    (ashift:DI (match_operand:DI 3 "" "")
1969404b540aSrobert;;					       (const_int 3)))
1970404b540aSrobert;;		   (match_operand:DI 4 "const_int_operand" "")))
1971404b540aSrobert;;   (clobber (match_operand:DI 5 "register_operand" ""))]
1972404b540aSrobert;;  "INTVAL (operands[4]) == 64 - INTVAL (operands[2])"
1973404b540aSrobert;;  [(set (match_dup 5) (match_dup 6))
1974404b540aSrobert;;   (set (match_dup 0)
1975404b540aSrobert;;	(ashift:DI (zero_extract:DI (match_dup 1) (match_dup 2)
1976404b540aSrobert;;				    (ashift:DI (plus:DI (match_dup 5)
1977404b540aSrobert;;							(match_dup 7))
1978404b540aSrobert;;					       (const_int 3)))
1979404b540aSrobert;;		   (match_dup 4)))]
1980404b540aSrobert;;  "
1981404b540aSrobert;;{
1982404b540aSrobert;;  operands[6] = plus_constant (operands[3],
1983404b540aSrobert;;			       INTVAL (operands[2]) / BITS_PER_UNIT);
1984404b540aSrobert;;  operands[7] = GEN_INT (- INTVAL (operands[2]) / BITS_PER_UNIT);
1985404b540aSrobert;;}")
1986404b540aSrobert
1987404b540aSrobert(define_insn "*insbl_const"
1988404b540aSrobert  [(set (match_operand:DI 0 "register_operand" "=r")
1989404b540aSrobert	(ashift:DI (zero_extend:DI (match_operand:QI 1 "register_operand" "r"))
1990404b540aSrobert		   (match_operand:DI 2 "mul8_operand" "I")))]
1991404b540aSrobert  ""
1992404b540aSrobert  "insbl %1,%s2,%0"
1993404b540aSrobert  [(set_attr "type" "shift")])
1994404b540aSrobert
1995404b540aSrobert(define_insn "*inswl_const"
1996404b540aSrobert  [(set (match_operand:DI 0 "register_operand" "=r")
1997404b540aSrobert	(ashift:DI (zero_extend:DI (match_operand:HI 1 "register_operand" "r"))
1998404b540aSrobert		   (match_operand:DI 2 "mul8_operand" "I")))]
1999404b540aSrobert  ""
2000404b540aSrobert  "inswl %1,%s2,%0"
2001404b540aSrobert  [(set_attr "type" "shift")])
2002404b540aSrobert
2003404b540aSrobert(define_insn "*insll_const"
2004404b540aSrobert  [(set (match_operand:DI 0 "register_operand" "=r")
2005404b540aSrobert	(ashift:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
2006404b540aSrobert		   (match_operand:DI 2 "mul8_operand" "I")))]
2007404b540aSrobert  ""
2008404b540aSrobert  "insll %1,%s2,%0"
2009404b540aSrobert  [(set_attr "type" "shift")])
2010404b540aSrobert
2011404b540aSrobert(define_insn "insbl_le"
2012404b540aSrobert  [(set (match_operand:DI 0 "register_operand" "=r")
2013404b540aSrobert	(ashift:DI (zero_extend:DI (match_operand:QI 1 "register_operand" "r"))
2014404b540aSrobert		   (ashift:DI (match_operand:DI 2 "reg_or_8bit_operand" "rI")
2015404b540aSrobert			      (const_int 3))))]
2016404b540aSrobert  "! WORDS_BIG_ENDIAN"
2017404b540aSrobert  "insbl %1,%2,%0"
2018404b540aSrobert  [(set_attr "type" "shift")])
2019404b540aSrobert
2020404b540aSrobert(define_insn "insbl_be"
2021404b540aSrobert [(set (match_operand:DI 0 "register_operand" "=r")
2022404b540aSrobert       (ashift:DI (zero_extend:DI (match_operand:QI 1 "register_operand" "r"))
2023404b540aSrobert	 (minus:DI (const_int 56)
2024404b540aSrobert	   (ashift:DI (match_operand:DI 2 "reg_or_8bit_operand" "rI")
2025404b540aSrobert		      (const_int 3)))))]
2026404b540aSrobert  "WORDS_BIG_ENDIAN"
2027404b540aSrobert  "insbl %1,%2,%0"
2028404b540aSrobert  [(set_attr "type" "shift")])
2029404b540aSrobert
2030404b540aSrobert(define_insn "inswl_le"
2031404b540aSrobert  [(set (match_operand:DI 0 "register_operand" "=r")
2032404b540aSrobert	(ashift:DI (zero_extend:DI (match_operand:HI 1 "register_operand" "r"))
2033404b540aSrobert		   (ashift:DI (match_operand:DI 2 "reg_or_8bit_operand" "rI")
2034404b540aSrobert			      (const_int 3))))]
2035404b540aSrobert  "! WORDS_BIG_ENDIAN"
2036404b540aSrobert  "inswl %1,%2,%0"
2037404b540aSrobert  [(set_attr "type" "shift")])
2038404b540aSrobert
2039404b540aSrobert(define_insn "inswl_be"
2040404b540aSrobert  [(set (match_operand:DI 0 "register_operand" "=r")
2041404b540aSrobert	(ashift:DI (zero_extend:DI (match_operand:HI 1 "register_operand" "r"))
2042404b540aSrobert	  (minus:DI (const_int 56)
2043404b540aSrobert	    (ashift:DI (match_operand:DI 2 "reg_or_8bit_operand" "rI")
2044404b540aSrobert		       (const_int 3)))))]
2045404b540aSrobert  "WORDS_BIG_ENDIAN"
2046404b540aSrobert  "inswl %1,%2,%0"
2047404b540aSrobert  [(set_attr "type" "shift")])
2048404b540aSrobert
2049404b540aSrobert(define_insn "insll_le"
2050404b540aSrobert  [(set (match_operand:DI 0 "register_operand" "=r")
2051404b540aSrobert	(ashift:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
2052404b540aSrobert		   (ashift:DI (match_operand:DI 2 "reg_or_8bit_operand" "rI")
2053404b540aSrobert			      (const_int 3))))]
2054404b540aSrobert  "! WORDS_BIG_ENDIAN"
2055404b540aSrobert  "insll %1,%2,%0"
2056404b540aSrobert  [(set_attr "type" "shift")])
2057404b540aSrobert
2058404b540aSrobert(define_insn "insll_be"
2059404b540aSrobert  [(set (match_operand:DI 0 "register_operand" "=r")
2060404b540aSrobert	(ashift:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
2061404b540aSrobert	  (minus:DI (const_int 56)
2062404b540aSrobert	    (ashift:DI (match_operand:DI 2 "reg_or_8bit_operand" "rI")
2063404b540aSrobert		       (const_int 3)))))]
2064404b540aSrobert  "WORDS_BIG_ENDIAN"
2065404b540aSrobert  "insll %1,%2,%0"
2066404b540aSrobert  [(set_attr "type" "shift")])
2067404b540aSrobert
2068404b540aSrobert(define_insn "insql_le"
2069404b540aSrobert  [(set (match_operand:DI 0 "register_operand" "=r")
2070404b540aSrobert	(ashift:DI (match_operand:DI 1 "register_operand" "r")
2071404b540aSrobert		   (ashift:DI (match_operand:DI 2 "reg_or_8bit_operand" "rI")
2072404b540aSrobert			      (const_int 3))))]
2073404b540aSrobert  "! WORDS_BIG_ENDIAN"
2074404b540aSrobert  "insql %1,%2,%0"
2075404b540aSrobert  [(set_attr "type" "shift")])
2076404b540aSrobert
2077404b540aSrobert(define_insn "insql_be"
2078404b540aSrobert  [(set (match_operand:DI 0 "register_operand" "=r")
2079404b540aSrobert	(ashift:DI (match_operand:DI 1 "register_operand" "r")
2080404b540aSrobert	  (minus:DI (const_int 56)
2081404b540aSrobert	    (ashift:DI (match_operand:DI 2 "reg_or_8bit_operand" "rI")
2082404b540aSrobert		       (const_int 3)))))]
2083404b540aSrobert  "WORDS_BIG_ENDIAN"
2084404b540aSrobert  "insql %1,%2,%0"
2085404b540aSrobert  [(set_attr "type" "shift")])
2086404b540aSrobert
2087404b540aSrobert;; Combine has this sometimes habit of moving the and outside of the
2088404b540aSrobert;; shift, making life more interesting.
2089404b540aSrobert
2090404b540aSrobert(define_insn "*insxl"
2091404b540aSrobert  [(set (match_operand:DI 0 "register_operand" "=r")
2092404b540aSrobert	(and:DI (ashift:DI (match_operand:DI 1 "register_operand" "r")
2093404b540aSrobert		   	   (match_operand:DI 2 "mul8_operand" "I"))
2094404b540aSrobert		(match_operand:DI 3 "immediate_operand" "i")))]
2095404b540aSrobert  "HOST_BITS_PER_WIDE_INT == 64
2096404b540aSrobert   && GET_CODE (operands[3]) == CONST_INT
2097404b540aSrobert   && (((unsigned HOST_WIDE_INT) 0xff << INTVAL (operands[2])
2098404b540aSrobert        == (unsigned HOST_WIDE_INT) INTVAL (operands[3]))
2099404b540aSrobert       || ((unsigned HOST_WIDE_INT) 0xffff << INTVAL (operands[2])
2100404b540aSrobert        == (unsigned HOST_WIDE_INT) INTVAL (operands[3]))
2101404b540aSrobert       || ((unsigned HOST_WIDE_INT) 0xffffffff << INTVAL (operands[2])
2102404b540aSrobert        == (unsigned HOST_WIDE_INT) INTVAL (operands[3])))"
2103404b540aSrobert{
2104404b540aSrobert#if HOST_BITS_PER_WIDE_INT == 64
2105404b540aSrobert  if ((unsigned HOST_WIDE_INT) 0xff << INTVAL (operands[2])
2106404b540aSrobert      == (unsigned HOST_WIDE_INT) INTVAL (operands[3]))
2107404b540aSrobert    return "insbl %1,%s2,%0";
2108404b540aSrobert  if ((unsigned HOST_WIDE_INT) 0xffff << INTVAL (operands[2])
2109404b540aSrobert      == (unsigned HOST_WIDE_INT) INTVAL (operands[3]))
2110404b540aSrobert    return "inswl %1,%s2,%0";
2111404b540aSrobert  if ((unsigned HOST_WIDE_INT) 0xffffffff << INTVAL (operands[2])
2112404b540aSrobert      == (unsigned HOST_WIDE_INT) INTVAL (operands[3]))
2113404b540aSrobert    return "insll %1,%s2,%0";
2114404b540aSrobert#endif
2115404b540aSrobert  gcc_unreachable ();
2116404b540aSrobert}
2117404b540aSrobert  [(set_attr "type" "shift")])
2118404b540aSrobert
2119404b540aSrobert;; We do not include the insXh insns because they are complex to express
2120404b540aSrobert;; and it does not appear that we would ever want to generate them.
2121404b540aSrobert;;
2122404b540aSrobert;; Since we need them for block moves, though, cop out and use unspec.
2123404b540aSrobert
2124404b540aSrobert(define_insn "insxh"
2125404b540aSrobert  [(set (match_operand:DI 0 "register_operand" "=r")
2126404b540aSrobert	(unspec:DI [(match_operand:DI 1 "register_operand" "r")
2127404b540aSrobert		    (match_operand:DI 2 "mode_width_operand" "n")
2128404b540aSrobert		    (match_operand:DI 3 "reg_or_8bit_operand" "rI")]
2129404b540aSrobert		   UNSPEC_INSXH))]
2130404b540aSrobert  ""
2131404b540aSrobert  "ins%M2h %1,%3,%0"
2132404b540aSrobert  [(set_attr "type" "shift")])
2133404b540aSrobert
2134404b540aSrobert(define_insn "mskxl_le"
2135404b540aSrobert  [(set (match_operand:DI 0 "register_operand" "=r")
2136404b540aSrobert	(and:DI (not:DI (ashift:DI
2137404b540aSrobert			 (match_operand:DI 2 "mode_mask_operand" "n")
2138404b540aSrobert			 (ashift:DI
2139404b540aSrobert			  (match_operand:DI 3 "reg_or_8bit_operand" "rI")
2140404b540aSrobert			  (const_int 3))))
2141404b540aSrobert		(match_operand:DI 1 "reg_or_0_operand" "rJ")))]
2142404b540aSrobert  "! WORDS_BIG_ENDIAN"
2143404b540aSrobert  "msk%U2l %r1,%3,%0"
2144404b540aSrobert  [(set_attr "type" "shift")])
2145404b540aSrobert
2146404b540aSrobert(define_insn "mskxl_be"
2147404b540aSrobert  [(set (match_operand:DI 0 "register_operand" "=r")
2148404b540aSrobert	(and:DI (not:DI (ashift:DI
2149404b540aSrobert			  (match_operand:DI 2 "mode_mask_operand" "n")
2150404b540aSrobert			  (minus:DI (const_int 56)
2151404b540aSrobert			    (ashift:DI
2152404b540aSrobert			      (match_operand:DI 3 "reg_or_8bit_operand" "rI")
2153404b540aSrobert			      (const_int 3)))))
2154404b540aSrobert		(match_operand:DI 1 "reg_or_0_operand" "rJ")))]
2155404b540aSrobert  "WORDS_BIG_ENDIAN"
2156404b540aSrobert  "msk%U2l %r1,%3,%0"
2157404b540aSrobert  [(set_attr "type" "shift")])
2158404b540aSrobert
2159404b540aSrobert;; We do not include the mskXh insns because it does not appear we would
2160404b540aSrobert;; ever generate one.
2161404b540aSrobert;;
2162404b540aSrobert;; Again, we do for block moves and we use unspec again.
2163404b540aSrobert
2164404b540aSrobert(define_insn "mskxh"
2165404b540aSrobert  [(set (match_operand:DI 0 "register_operand" "=r")
2166404b540aSrobert	(unspec:DI [(match_operand:DI 1 "register_operand" "r")
2167404b540aSrobert		    (match_operand:DI 2 "mode_width_operand" "n")
2168404b540aSrobert		    (match_operand:DI 3 "reg_or_8bit_operand" "rI")]
2169404b540aSrobert		   UNSPEC_MSKXH))]
2170404b540aSrobert  ""
2171404b540aSrobert  "msk%M2h %1,%3,%0"
2172404b540aSrobert  [(set_attr "type" "shift")])
2173404b540aSrobert
2174404b540aSrobert;; Prefer AND + NE over LSHIFTRT + AND.
2175404b540aSrobert
2176404b540aSrobert(define_insn_and_split "*ze_and_ne"
2177404b540aSrobert  [(set (match_operand:DI 0 "register_operand" "=r")
2178404b540aSrobert	(zero_extract:DI (match_operand:DI 1 "reg_or_0_operand" "rJ")
2179404b540aSrobert			 (const_int 1)
2180404b540aSrobert			 (match_operand 2 "const_int_operand" "I")))]
2181404b540aSrobert  "(unsigned HOST_WIDE_INT) INTVAL (operands[2]) < 8"
2182404b540aSrobert  "#"
2183404b540aSrobert  "(unsigned HOST_WIDE_INT) INTVAL (operands[2]) < 8"
2184404b540aSrobert  [(set (match_dup 0)
2185404b540aSrobert	(and:DI (match_dup 1) (match_dup 3)))
2186404b540aSrobert   (set (match_dup 0)
2187404b540aSrobert	(ne:DI (match_dup 0) (const_int 0)))]
2188404b540aSrobert  "operands[3] = GEN_INT (1 << INTVAL (operands[2]));")
2189404b540aSrobert
2190404b540aSrobert;; Floating-point operations.  All the double-precision insns can extend
2191404b540aSrobert;; from single, so indicate that.  The exception are the ones that simply
2192404b540aSrobert;; play with the sign bits; it's not clear what to do there.
2193404b540aSrobert
2194404b540aSrobert(define_insn "abssf2"
2195404b540aSrobert  [(set (match_operand:SF 0 "register_operand" "=f")
2196404b540aSrobert	(abs:SF (match_operand:SF 1 "reg_or_0_operand" "fG")))]
2197404b540aSrobert  "TARGET_FP"
2198404b540aSrobert  "cpys $f31,%R1,%0"
2199404b540aSrobert  [(set_attr "type" "fcpys")])
2200404b540aSrobert
2201404b540aSrobert(define_insn "*nabssf2"
2202404b540aSrobert  [(set (match_operand:SF 0 "register_operand" "=f")
2203404b540aSrobert	(neg:SF (abs:SF (match_operand:SF 1 "reg_or_0_operand" "fG"))))]
2204404b540aSrobert  "TARGET_FP"
2205404b540aSrobert  "cpysn $f31,%R1,%0"
2206404b540aSrobert  [(set_attr "type" "fadd")])
2207404b540aSrobert
2208404b540aSrobert(define_insn "absdf2"
2209404b540aSrobert  [(set (match_operand:DF 0 "register_operand" "=f")
2210404b540aSrobert	(abs:DF (match_operand:DF 1 "reg_or_0_operand" "fG")))]
2211404b540aSrobert  "TARGET_FP"
2212404b540aSrobert  "cpys $f31,%R1,%0"
2213404b540aSrobert  [(set_attr "type" "fcpys")])
2214404b540aSrobert
2215404b540aSrobert(define_insn "*nabsdf2"
2216404b540aSrobert  [(set (match_operand:DF 0 "register_operand" "=f")
2217404b540aSrobert	(neg:DF (abs:DF (match_operand:DF 1 "reg_or_0_operand" "fG"))))]
2218404b540aSrobert  "TARGET_FP"
2219404b540aSrobert  "cpysn $f31,%R1,%0"
2220404b540aSrobert  [(set_attr "type" "fadd")])
2221404b540aSrobert
2222404b540aSrobert(define_expand "abstf2"
2223404b540aSrobert  [(parallel [(set (match_operand:TF 0 "register_operand" "")
2224404b540aSrobert		   (abs:TF (match_operand:TF 1 "reg_or_0_operand" "")))
2225404b540aSrobert	      (use (match_dup 2))])]
2226404b540aSrobert  "TARGET_HAS_XFLOATING_LIBS"
2227404b540aSrobert{
2228404b540aSrobert#if HOST_BITS_PER_WIDE_INT >= 64
2229404b540aSrobert  operands[2] = force_reg (DImode, GEN_INT ((HOST_WIDE_INT) 1 << 63));
2230404b540aSrobert#else
2231404b540aSrobert  operands[2] = force_reg (DImode, immed_double_const (0, 0x80000000, DImode));
2232404b540aSrobert#endif
2233404b540aSrobert})
2234404b540aSrobert
2235404b540aSrobert(define_insn_and_split "*abstf_internal"
2236404b540aSrobert  [(set (match_operand:TF 0 "register_operand" "=r")
2237404b540aSrobert	(abs:TF (match_operand:TF 1 "reg_or_0_operand" "rG")))
2238404b540aSrobert   (use (match_operand:DI 2 "register_operand" "r"))]
2239404b540aSrobert  "TARGET_HAS_XFLOATING_LIBS"
2240404b540aSrobert  "#"
2241404b540aSrobert  "&& reload_completed"
2242404b540aSrobert  [(const_int 0)]
2243404b540aSrobert  "alpha_split_tfmode_frobsign (operands, gen_andnotdi3); DONE;")
2244404b540aSrobert
2245404b540aSrobert(define_insn "negsf2"
2246404b540aSrobert  [(set (match_operand:SF 0 "register_operand" "=f")
2247404b540aSrobert	(neg:SF (match_operand:SF 1 "reg_or_0_operand" "fG")))]
2248404b540aSrobert  "TARGET_FP"
2249404b540aSrobert  "cpysn %R1,%R1,%0"
2250404b540aSrobert  [(set_attr "type" "fadd")])
2251404b540aSrobert
2252404b540aSrobert(define_insn "negdf2"
2253404b540aSrobert  [(set (match_operand:DF 0 "register_operand" "=f")
2254404b540aSrobert	(neg:DF (match_operand:DF 1 "reg_or_0_operand" "fG")))]
2255404b540aSrobert  "TARGET_FP"
2256404b540aSrobert  "cpysn %R1,%R1,%0"
2257404b540aSrobert  [(set_attr "type" "fadd")])
2258404b540aSrobert
2259404b540aSrobert(define_expand "negtf2"
2260404b540aSrobert  [(parallel [(set (match_operand:TF 0 "register_operand" "")
2261404b540aSrobert		   (neg:TF (match_operand:TF 1 "reg_or_0_operand" "")))
2262404b540aSrobert	      (use (match_dup 2))])]
2263404b540aSrobert  "TARGET_HAS_XFLOATING_LIBS"
2264404b540aSrobert{
2265404b540aSrobert#if HOST_BITS_PER_WIDE_INT >= 64
2266404b540aSrobert  operands[2] = force_reg (DImode, GEN_INT ((HOST_WIDE_INT) 1 << 63));
2267404b540aSrobert#else
2268404b540aSrobert  operands[2] = force_reg (DImode, immed_double_const (0, 0x80000000, DImode));
2269404b540aSrobert#endif
2270404b540aSrobert})
2271404b540aSrobert
2272404b540aSrobert(define_insn_and_split "*negtf_internal"
2273404b540aSrobert  [(set (match_operand:TF 0 "register_operand" "=r")
2274404b540aSrobert	(neg:TF (match_operand:TF 1 "reg_or_0_operand" "rG")))
2275404b540aSrobert   (use (match_operand:DI 2 "register_operand" "r"))]
2276404b540aSrobert  "TARGET_HAS_XFLOATING_LIBS"
2277404b540aSrobert  "#"
2278404b540aSrobert  "&& reload_completed"
2279404b540aSrobert  [(const_int 0)]
2280404b540aSrobert  "alpha_split_tfmode_frobsign (operands, gen_xordi3); DONE;")
2281404b540aSrobert
2282404b540aSrobert(define_insn "copysignsf3"
2283404b540aSrobert  [(set (match_operand:SF 0 "register_operand" "=f")
2284404b540aSrobert	(unspec:SF [(match_operand:SF 1 "reg_or_0_operand" "fG")
2285404b540aSrobert		    (match_operand:SF 2 "reg_or_0_operand" "fG")]
2286404b540aSrobert		   UNSPEC_COPYSIGN))]
2287404b540aSrobert  "TARGET_FP"
2288404b540aSrobert  "cpys %R2,%R1,%0"
2289404b540aSrobert  [(set_attr "type" "fadd")])
2290404b540aSrobert
2291404b540aSrobert(define_insn "*ncopysignsf3"
2292404b540aSrobert  [(set (match_operand:SF 0 "register_operand" "=f")
2293404b540aSrobert	(neg:SF (unspec:SF [(match_operand:SF 1 "reg_or_0_operand" "fG")
2294404b540aSrobert			    (match_operand:SF 2 "reg_or_0_operand" "fG")]
2295404b540aSrobert			   UNSPEC_COPYSIGN)))]
2296404b540aSrobert  "TARGET_FP"
2297404b540aSrobert  "cpysn %R2,%R1,%0"
2298404b540aSrobert  [(set_attr "type" "fadd")])
2299404b540aSrobert
2300404b540aSrobert(define_insn "copysigndf3"
2301404b540aSrobert  [(set (match_operand:DF 0 "register_operand" "=f")
2302404b540aSrobert	(unspec:DF [(match_operand:DF 1 "reg_or_0_operand" "fG")
2303404b540aSrobert		    (match_operand:DF 2 "reg_or_0_operand" "fG")]
2304404b540aSrobert		   UNSPEC_COPYSIGN))]
2305404b540aSrobert  "TARGET_FP"
2306404b540aSrobert  "cpys %R2,%R1,%0"
2307404b540aSrobert  [(set_attr "type" "fadd")])
2308404b540aSrobert
2309404b540aSrobert(define_insn "*ncopysigndf3"
2310404b540aSrobert  [(set (match_operand:DF 0 "register_operand" "=f")
2311404b540aSrobert	(neg:DF (unspec:DF [(match_operand:DF 1 "reg_or_0_operand" "fG")
2312404b540aSrobert			    (match_operand:DF 2 "reg_or_0_operand" "fG")]
2313404b540aSrobert			   UNSPEC_COPYSIGN)))]
2314404b540aSrobert  "TARGET_FP"
2315404b540aSrobert  "cpysn %R2,%R1,%0"
2316404b540aSrobert  [(set_attr "type" "fadd")])
2317404b540aSrobert
2318404b540aSrobert(define_insn "*addsf_ieee"
2319404b540aSrobert  [(set (match_operand:SF 0 "register_operand" "=&f")
2320404b540aSrobert	(plus:SF (match_operand:SF 1 "reg_or_0_operand" "%fG")
2321404b540aSrobert		 (match_operand:SF 2 "reg_or_0_operand" "fG")))]
2322404b540aSrobert  "TARGET_FP && alpha_fptm >= ALPHA_FPTM_SU"
2323404b540aSrobert  "add%,%/ %R1,%R2,%0"
2324404b540aSrobert  [(set_attr "type" "fadd")
2325404b540aSrobert   (set_attr "trap" "yes")
2326404b540aSrobert   (set_attr "round_suffix" "normal")
2327404b540aSrobert   (set_attr "trap_suffix" "u_su_sui")])
2328404b540aSrobert
2329404b540aSrobert(define_insn "addsf3"
2330404b540aSrobert  [(set (match_operand:SF 0 "register_operand" "=f")
2331404b540aSrobert	(plus:SF (match_operand:SF 1 "reg_or_0_operand" "%fG")
2332404b540aSrobert		 (match_operand:SF 2 "reg_or_0_operand" "fG")))]
2333404b540aSrobert  "TARGET_FP"
2334404b540aSrobert  "add%,%/ %R1,%R2,%0"
2335404b540aSrobert  [(set_attr "type" "fadd")
2336404b540aSrobert   (set_attr "trap" "yes")
2337404b540aSrobert   (set_attr "round_suffix" "normal")
2338404b540aSrobert   (set_attr "trap_suffix" "u_su_sui")])
2339404b540aSrobert
2340404b540aSrobert(define_insn "*adddf_ieee"
2341404b540aSrobert  [(set (match_operand:DF 0 "register_operand" "=&f")
2342404b540aSrobert	(plus:DF (match_operand:DF 1 "reg_or_0_operand" "%fG")
2343404b540aSrobert		 (match_operand:DF 2 "reg_or_0_operand" "fG")))]
2344404b540aSrobert  "TARGET_FP && alpha_fptm >= ALPHA_FPTM_SU"
2345404b540aSrobert  "add%-%/ %R1,%R2,%0"
2346404b540aSrobert  [(set_attr "type" "fadd")
2347404b540aSrobert   (set_attr "trap" "yes")
2348404b540aSrobert   (set_attr "round_suffix" "normal")
2349404b540aSrobert   (set_attr "trap_suffix" "u_su_sui")])
2350404b540aSrobert
2351404b540aSrobert(define_insn "adddf3"
2352404b540aSrobert  [(set (match_operand:DF 0 "register_operand" "=f")
2353404b540aSrobert	(plus:DF (match_operand:DF 1 "reg_or_0_operand" "%fG")
2354404b540aSrobert		 (match_operand:DF 2 "reg_or_0_operand" "fG")))]
2355404b540aSrobert  "TARGET_FP"
2356404b540aSrobert  "add%-%/ %R1,%R2,%0"
2357404b540aSrobert  [(set_attr "type" "fadd")
2358404b540aSrobert   (set_attr "trap" "yes")
2359404b540aSrobert   (set_attr "round_suffix" "normal")
2360404b540aSrobert   (set_attr "trap_suffix" "u_su_sui")])
2361404b540aSrobert
2362404b540aSrobert(define_insn "*adddf_ext1"
2363404b540aSrobert  [(set (match_operand:DF 0 "register_operand" "=f")
2364404b540aSrobert	(plus:DF (float_extend:DF
2365404b540aSrobert		  (match_operand:SF 1 "reg_or_0_operand" "fG"))
2366404b540aSrobert		 (match_operand:DF 2 "reg_or_0_operand" "fG")))]
2367404b540aSrobert  "TARGET_FP && alpha_fptm < ALPHA_FPTM_SU"
2368404b540aSrobert  "add%-%/ %R1,%R2,%0"
2369404b540aSrobert  [(set_attr "type" "fadd")
2370404b540aSrobert   (set_attr "trap" "yes")
2371404b540aSrobert   (set_attr "round_suffix" "normal")
2372404b540aSrobert   (set_attr "trap_suffix" "u_su_sui")])
2373404b540aSrobert
2374404b540aSrobert(define_insn "*adddf_ext2"
2375404b540aSrobert  [(set (match_operand:DF 0 "register_operand" "=f")
2376404b540aSrobert	(plus:DF (float_extend:DF
2377404b540aSrobert		  (match_operand:SF 1 "reg_or_0_operand" "%fG"))
2378404b540aSrobert		 (float_extend:DF
2379404b540aSrobert		  (match_operand:SF 2 "reg_or_0_operand" "fG"))))]
2380404b540aSrobert  "TARGET_FP && alpha_fptm < ALPHA_FPTM_SU"
2381404b540aSrobert  "add%-%/ %R1,%R2,%0"
2382404b540aSrobert  [(set_attr "type" "fadd")
2383404b540aSrobert   (set_attr "trap" "yes")
2384404b540aSrobert   (set_attr "round_suffix" "normal")
2385404b540aSrobert   (set_attr "trap_suffix" "u_su_sui")])
2386404b540aSrobert
2387404b540aSrobert(define_expand "addtf3"
2388404b540aSrobert  [(use (match_operand 0 "register_operand" ""))
2389404b540aSrobert   (use (match_operand 1 "general_operand" ""))
2390404b540aSrobert   (use (match_operand 2 "general_operand" ""))]
2391404b540aSrobert  "TARGET_HAS_XFLOATING_LIBS"
2392404b540aSrobert  "alpha_emit_xfloating_arith (PLUS, operands); DONE;")
2393404b540aSrobert
2394404b540aSrobert;; Define conversion operators between DFmode and SImode, using the cvtql
2395404b540aSrobert;; instruction.  To allow combine et al to do useful things, we keep the
2396404b540aSrobert;; operation as a unit until after reload, at which point we split the
2397404b540aSrobert;; instructions.
2398404b540aSrobert;;
2399404b540aSrobert;; Note that we (attempt to) only consider this optimization when the
2400404b540aSrobert;; ultimate destination is memory.  If we will be doing further integer
2401404b540aSrobert;; processing, it is cheaper to do the truncation in the int regs.
2402404b540aSrobert
2403404b540aSrobert(define_insn "*cvtql"
2404404b540aSrobert  [(set (match_operand:SF 0 "register_operand" "=f")
2405404b540aSrobert	(unspec:SF [(match_operand:DI 1 "reg_or_0_operand" "fG")]
2406404b540aSrobert		   UNSPEC_CVTQL))]
2407404b540aSrobert  "TARGET_FP"
2408404b540aSrobert  "cvtql%/ %R1,%0"
2409404b540aSrobert  [(set_attr "type" "fadd")
2410404b540aSrobert   (set_attr "trap" "yes")
2411404b540aSrobert   (set_attr "trap_suffix" "v_sv")])
2412404b540aSrobert
2413404b540aSrobert(define_insn_and_split "*fix_truncdfsi_ieee"
2414404b540aSrobert  [(set (match_operand:SI 0 "memory_operand" "=m")
2415404b540aSrobert	(subreg:SI
2416404b540aSrobert	  (match_operator:DI 4 "fix_operator"
2417404b540aSrobert	    [(match_operand:DF 1 "reg_or_0_operand" "fG")]) 0))
2418404b540aSrobert   (clobber (match_scratch:DI 2 "=&f"))
2419404b540aSrobert   (clobber (match_scratch:SF 3 "=&f"))]
2420404b540aSrobert  "TARGET_FP && alpha_fptm >= ALPHA_FPTM_SU"
2421404b540aSrobert  "#"
2422404b540aSrobert  "&& reload_completed"
2423404b540aSrobert  [(set (match_dup 2) (match_op_dup 4 [(match_dup 1)]))
2424404b540aSrobert   (set (match_dup 3) (unspec:SF [(match_dup 2)] UNSPEC_CVTQL))
2425404b540aSrobert   (set (match_dup 5) (match_dup 3))]
2426404b540aSrobert{
2427404b540aSrobert  operands[5] = adjust_address (operands[0], SFmode, 0);
2428404b540aSrobert}
2429404b540aSrobert  [(set_attr "type" "fadd")
2430404b540aSrobert   (set_attr "trap" "yes")])
2431404b540aSrobert
2432404b540aSrobert(define_insn_and_split "*fix_truncdfsi_internal"
2433404b540aSrobert  [(set (match_operand:SI 0 "memory_operand" "=m")
2434404b540aSrobert	(subreg:SI
2435404b540aSrobert	  (match_operator:DI 3 "fix_operator"
2436404b540aSrobert	    [(match_operand:DF 1 "reg_or_0_operand" "fG")]) 0))
2437404b540aSrobert   (clobber (match_scratch:DI 2 "=f"))]
2438404b540aSrobert  "TARGET_FP && alpha_fptm < ALPHA_FPTM_SU"
2439404b540aSrobert  "#"
2440404b540aSrobert  "&& reload_completed"
2441404b540aSrobert  [(set (match_dup 2) (match_op_dup 3 [(match_dup 1)]))
2442404b540aSrobert   (set (match_dup 4) (unspec:SF [(match_dup 2)] UNSPEC_CVTQL))
2443404b540aSrobert   (set (match_dup 5) (match_dup 4))]
2444404b540aSrobert{
2445404b540aSrobert  operands[4] = gen_rtx_REG (SFmode, REGNO (operands[2]));
2446404b540aSrobert  operands[5] = adjust_address (operands[0], SFmode, 0);
2447404b540aSrobert}
2448404b540aSrobert  [(set_attr "type" "fadd")
2449404b540aSrobert   (set_attr "trap" "yes")])
2450404b540aSrobert
2451404b540aSrobert(define_insn "*fix_truncdfdi_ieee"
2452404b540aSrobert  [(set (match_operand:DI 0 "reg_no_subreg_operand" "=&f")
2453404b540aSrobert	(match_operator:DI 2 "fix_operator"
2454404b540aSrobert	  [(match_operand:DF 1 "reg_or_0_operand" "fG")]))]
2455404b540aSrobert  "TARGET_FP && alpha_fptm >= ALPHA_FPTM_SU"
2456404b540aSrobert  "cvt%-q%/ %R1,%0"
2457404b540aSrobert  [(set_attr "type" "fadd")
2458404b540aSrobert   (set_attr "trap" "yes")
2459404b540aSrobert   (set_attr "round_suffix" "c")
2460404b540aSrobert   (set_attr "trap_suffix" "v_sv_svi")])
2461404b540aSrobert
2462404b540aSrobert(define_insn "*fix_truncdfdi2"
2463404b540aSrobert  [(set (match_operand:DI 0 "reg_no_subreg_operand" "=f")
2464404b540aSrobert	(match_operator:DI 2 "fix_operator"
2465404b540aSrobert	  [(match_operand:DF 1 "reg_or_0_operand" "fG")]))]
2466404b540aSrobert  "TARGET_FP"
2467404b540aSrobert  "cvt%-q%/ %R1,%0"
2468404b540aSrobert  [(set_attr "type" "fadd")
2469404b540aSrobert   (set_attr "trap" "yes")
2470404b540aSrobert   (set_attr "round_suffix" "c")
2471404b540aSrobert   (set_attr "trap_suffix" "v_sv_svi")])
2472404b540aSrobert
2473404b540aSrobert(define_expand "fix_truncdfdi2"
2474404b540aSrobert  [(set (match_operand:DI 0 "reg_no_subreg_operand" "")
2475404b540aSrobert	(fix:DI (match_operand:DF 1 "reg_or_0_operand" "")))]
2476404b540aSrobert  "TARGET_FP"
2477404b540aSrobert  "")
2478404b540aSrobert
2479404b540aSrobert(define_expand "fixuns_truncdfdi2"
2480404b540aSrobert  [(set (match_operand:DI 0 "reg_no_subreg_operand" "")
2481404b540aSrobert	(unsigned_fix:DI (match_operand:DF 1 "reg_or_0_operand" "")))]
2482404b540aSrobert  "TARGET_FP"
2483404b540aSrobert  "")
2484404b540aSrobert
2485404b540aSrobert;; Likewise between SFmode and SImode.
2486404b540aSrobert
2487404b540aSrobert(define_insn_and_split "*fix_truncsfsi_ieee"
2488404b540aSrobert  [(set (match_operand:SI 0 "memory_operand" "=m")
2489404b540aSrobert	(subreg:SI
2490404b540aSrobert	  (match_operator:DI 4 "fix_operator"
2491404b540aSrobert	    [(float_extend:DF
2492404b540aSrobert	       (match_operand:SF 1 "reg_or_0_operand" "fG"))]) 0))
2493404b540aSrobert   (clobber (match_scratch:DI 2 "=&f"))
2494404b540aSrobert   (clobber (match_scratch:SF 3 "=&f"))]
2495404b540aSrobert  "TARGET_FP && alpha_fptm >= ALPHA_FPTM_SU"
2496404b540aSrobert  "#"
2497404b540aSrobert  "&& reload_completed"
2498404b540aSrobert  [(set (match_dup 2) (match_op_dup 4 [(float_extend:DF (match_dup 1))]))
2499404b540aSrobert   (set (match_dup 3) (unspec:SF [(match_dup 2)] UNSPEC_CVTQL))
2500404b540aSrobert   (set (match_dup 5) (match_dup 3))]
2501404b540aSrobert{
2502404b540aSrobert  operands[5] = adjust_address (operands[0], SFmode, 0);
2503404b540aSrobert}
2504404b540aSrobert  [(set_attr "type" "fadd")
2505404b540aSrobert   (set_attr "trap" "yes")])
2506404b540aSrobert
2507404b540aSrobert(define_insn_and_split "*fix_truncsfsi_internal"
2508404b540aSrobert  [(set (match_operand:SI 0 "memory_operand" "=m")
2509404b540aSrobert	(subreg:SI
2510404b540aSrobert	  (match_operator:DI 3 "fix_operator"
2511404b540aSrobert	    [(float_extend:DF
2512404b540aSrobert	       (match_operand:SF 1 "reg_or_0_operand" "fG"))]) 0))
2513404b540aSrobert   (clobber (match_scratch:DI 2 "=f"))]
2514404b540aSrobert  "TARGET_FP && alpha_fptm < ALPHA_FPTM_SU"
2515404b540aSrobert  "#"
2516404b540aSrobert  "&& reload_completed"
2517404b540aSrobert  [(set (match_dup 2) (match_op_dup 3 [(float_extend:DF (match_dup 1))]))
2518404b540aSrobert   (set (match_dup 4) (unspec:SF [(match_dup 2)] UNSPEC_CVTQL))
2519404b540aSrobert   (set (match_dup 5) (match_dup 4))]
2520404b540aSrobert{
2521404b540aSrobert  operands[4] = gen_rtx_REG (SFmode, REGNO (operands[2]));
2522404b540aSrobert  operands[5] = adjust_address (operands[0], SFmode, 0);
2523404b540aSrobert}
2524404b540aSrobert  [(set_attr "type" "fadd")
2525404b540aSrobert   (set_attr "trap" "yes")])
2526404b540aSrobert
2527404b540aSrobert(define_insn "*fix_truncsfdi_ieee"
2528404b540aSrobert  [(set (match_operand:DI 0 "reg_no_subreg_operand" "=&f")
2529404b540aSrobert	(match_operator:DI 2 "fix_operator"
2530404b540aSrobert	  [(float_extend:DF (match_operand:SF 1 "reg_or_0_operand" "fG"))]))]
2531404b540aSrobert  "TARGET_FP && alpha_fptm >= ALPHA_FPTM_SU"
2532404b540aSrobert  "cvt%-q%/ %R1,%0"
2533404b540aSrobert  [(set_attr "type" "fadd")
2534404b540aSrobert   (set_attr "trap" "yes")
2535404b540aSrobert   (set_attr "round_suffix" "c")
2536404b540aSrobert   (set_attr "trap_suffix" "v_sv_svi")])
2537404b540aSrobert
2538404b540aSrobert(define_insn "*fix_truncsfdi2"
2539404b540aSrobert  [(set (match_operand:DI 0 "reg_no_subreg_operand" "=f")
2540404b540aSrobert	(match_operator:DI 2 "fix_operator"
2541404b540aSrobert	  [(float_extend:DF (match_operand:SF 1 "reg_or_0_operand" "fG"))]))]
2542404b540aSrobert  "TARGET_FP"
2543404b540aSrobert  "cvt%-q%/ %R1,%0"
2544404b540aSrobert  [(set_attr "type" "fadd")
2545404b540aSrobert   (set_attr "trap" "yes")
2546404b540aSrobert   (set_attr "round_suffix" "c")
2547404b540aSrobert   (set_attr "trap_suffix" "v_sv_svi")])
2548404b540aSrobert
2549404b540aSrobert(define_expand "fix_truncsfdi2"
2550404b540aSrobert  [(set (match_operand:DI 0 "reg_no_subreg_operand" "")
2551404b540aSrobert	(fix:DI (float_extend:DF (match_operand:SF 1 "reg_or_0_operand" ""))))]
2552404b540aSrobert  "TARGET_FP"
2553404b540aSrobert  "")
2554404b540aSrobert
2555404b540aSrobert(define_expand "fixuns_truncsfdi2"
2556404b540aSrobert  [(set (match_operand:DI 0 "reg_no_subreg_operand" "")
2557404b540aSrobert	(unsigned_fix:DI
2558404b540aSrobert	  (float_extend:DF (match_operand:SF 1 "reg_or_0_operand" ""))))]
2559404b540aSrobert  "TARGET_FP"
2560404b540aSrobert  "")
2561404b540aSrobert
2562404b540aSrobert(define_expand "fix_trunctfdi2"
2563404b540aSrobert  [(use (match_operand:DI 0 "register_operand" ""))
2564404b540aSrobert   (use (match_operand:TF 1 "general_operand" ""))]
2565404b540aSrobert  "TARGET_HAS_XFLOATING_LIBS"
2566404b540aSrobert  "alpha_emit_xfloating_cvt (FIX, operands); DONE;")
2567404b540aSrobert
2568404b540aSrobert(define_expand "fixuns_trunctfdi2"
2569404b540aSrobert  [(use (match_operand:DI 0 "register_operand" ""))
2570404b540aSrobert   (use (match_operand:TF 1 "general_operand" ""))]
2571404b540aSrobert  "TARGET_HAS_XFLOATING_LIBS"
2572404b540aSrobert  "alpha_emit_xfloating_cvt (UNSIGNED_FIX, operands); DONE;")
2573404b540aSrobert
2574404b540aSrobert(define_insn "*floatdisf_ieee"
2575404b540aSrobert  [(set (match_operand:SF 0 "register_operand" "=&f")
2576404b540aSrobert	(float:SF (match_operand:DI 1 "reg_no_subreg_operand" "f")))]
2577404b540aSrobert  "TARGET_FP && alpha_fptm >= ALPHA_FPTM_SU"
2578404b540aSrobert  "cvtq%,%/ %1,%0"
2579404b540aSrobert  [(set_attr "type" "fadd")
2580404b540aSrobert   (set_attr "trap" "yes")
2581404b540aSrobert   (set_attr "round_suffix" "normal")
2582404b540aSrobert   (set_attr "trap_suffix" "sui")])
2583404b540aSrobert
2584404b540aSrobert(define_insn "floatdisf2"
2585404b540aSrobert  [(set (match_operand:SF 0 "register_operand" "=f")
2586404b540aSrobert	(float:SF (match_operand:DI 1 "reg_no_subreg_operand" "f")))]
2587404b540aSrobert  "TARGET_FP"
2588404b540aSrobert  "cvtq%,%/ %1,%0"
2589404b540aSrobert  [(set_attr "type" "fadd")
2590404b540aSrobert   (set_attr "trap" "yes")
2591404b540aSrobert   (set_attr "round_suffix" "normal")
2592404b540aSrobert   (set_attr "trap_suffix" "sui")])
2593404b540aSrobert
2594404b540aSrobert(define_insn_and_split "*floatsisf2_ieee"
2595404b540aSrobert  [(set (match_operand:SF 0 "register_operand" "=&f")
2596404b540aSrobert	(float:SF (match_operand:SI 1 "memory_operand" "m")))
2597404b540aSrobert   (clobber (match_scratch:DI 2 "=&f"))
2598404b540aSrobert   (clobber (match_scratch:SF 3 "=&f"))]
2599404b540aSrobert  "TARGET_FP && alpha_fptm >= ALPHA_FPTM_SU"
2600404b540aSrobert  "#"
2601404b540aSrobert  "&& reload_completed"
2602404b540aSrobert  [(set (match_dup 3) (match_dup 1))
2603404b540aSrobert   (set (match_dup 2) (unspec:DI [(match_dup 3)] UNSPEC_CVTLQ))
2604404b540aSrobert   (set (match_dup 0) (float:SF (match_dup 2)))]
2605404b540aSrobert{
2606404b540aSrobert  operands[1] = adjust_address (operands[1], SFmode, 0);
2607404b540aSrobert})
2608404b540aSrobert
2609404b540aSrobert(define_insn_and_split "*floatsisf2"
2610404b540aSrobert  [(set (match_operand:SF 0 "register_operand" "=f")
2611404b540aSrobert	(float:SF (match_operand:SI 1 "memory_operand" "m")))]
2612404b540aSrobert  "TARGET_FP"
2613404b540aSrobert  "#"
2614404b540aSrobert  "&& reload_completed"
2615404b540aSrobert  [(set (match_dup 0) (match_dup 1))
2616404b540aSrobert   (set (match_dup 2) (unspec:DI [(match_dup 0)] UNSPEC_CVTLQ))
2617404b540aSrobert   (set (match_dup 0) (float:SF (match_dup 2)))]
2618404b540aSrobert{
2619404b540aSrobert  operands[1] = adjust_address (operands[1], SFmode, 0);
2620404b540aSrobert  operands[2] = gen_rtx_REG (DImode, REGNO (operands[0]));
2621404b540aSrobert})
2622404b540aSrobert
2623404b540aSrobert(define_insn "*floatdidf_ieee"
2624404b540aSrobert  [(set (match_operand:DF 0 "register_operand" "=&f")
2625404b540aSrobert	(float:DF (match_operand:DI 1 "reg_no_subreg_operand" "f")))]
2626404b540aSrobert  "TARGET_FP && alpha_fptm >= ALPHA_FPTM_SU"
2627404b540aSrobert  "cvtq%-%/ %1,%0"
2628404b540aSrobert  [(set_attr "type" "fadd")
2629404b540aSrobert   (set_attr "trap" "yes")
2630404b540aSrobert   (set_attr "round_suffix" "normal")
2631404b540aSrobert   (set_attr "trap_suffix" "sui")])
2632404b540aSrobert
2633404b540aSrobert(define_insn "floatdidf2"
2634404b540aSrobert  [(set (match_operand:DF 0 "register_operand" "=f")
2635404b540aSrobert	(float:DF (match_operand:DI 1 "reg_no_subreg_operand" "f")))]
2636404b540aSrobert  "TARGET_FP"
2637404b540aSrobert  "cvtq%-%/ %1,%0"
2638404b540aSrobert  [(set_attr "type" "fadd")
2639404b540aSrobert   (set_attr "trap" "yes")
2640404b540aSrobert   (set_attr "round_suffix" "normal")
2641404b540aSrobert   (set_attr "trap_suffix" "sui")])
2642404b540aSrobert
2643404b540aSrobert(define_insn_and_split "*floatsidf2_ieee"
2644404b540aSrobert  [(set (match_operand:DF 0 "register_operand" "=&f")
2645404b540aSrobert	(float:DF (match_operand:SI 1 "memory_operand" "m")))
2646404b540aSrobert   (clobber (match_scratch:DI 2 "=&f"))
2647404b540aSrobert   (clobber (match_scratch:SF 3 "=&f"))]
2648404b540aSrobert  "TARGET_FP && alpha_fptm >= ALPHA_FPTM_SU"
2649404b540aSrobert  "#"
2650404b540aSrobert  "&& reload_completed"
2651404b540aSrobert  [(set (match_dup 3) (match_dup 1))
2652404b540aSrobert   (set (match_dup 2) (unspec:DI [(match_dup 3)] UNSPEC_CVTLQ))
2653404b540aSrobert   (set (match_dup 0) (float:DF (match_dup 2)))]
2654404b540aSrobert{
2655404b540aSrobert  operands[1] = adjust_address (operands[1], SFmode, 0);
2656404b540aSrobert})
2657404b540aSrobert
2658404b540aSrobert(define_insn_and_split "*floatsidf2"
2659404b540aSrobert  [(set (match_operand:DF 0 "register_operand" "=f")
2660404b540aSrobert	(float:DF (match_operand:SI 1 "memory_operand" "m")))]
2661404b540aSrobert  "TARGET_FP"
2662404b540aSrobert  "#"
2663404b540aSrobert  "&& reload_completed"
2664404b540aSrobert  [(set (match_dup 3) (match_dup 1))
2665404b540aSrobert   (set (match_dup 2) (unspec:DI [(match_dup 3)] UNSPEC_CVTLQ))
2666404b540aSrobert   (set (match_dup 0) (float:DF (match_dup 2)))]
2667404b540aSrobert{
2668404b540aSrobert  operands[1] = adjust_address (operands[1], SFmode, 0);
2669404b540aSrobert  operands[2] = gen_rtx_REG (DImode, REGNO (operands[0]));
2670404b540aSrobert  operands[3] = gen_rtx_REG (SFmode, REGNO (operands[0]));
2671404b540aSrobert})
2672404b540aSrobert
2673404b540aSrobert(define_expand "floatditf2"
2674404b540aSrobert  [(use (match_operand:TF 0 "register_operand" ""))
2675404b540aSrobert   (use (match_operand:DI 1 "general_operand" ""))]
2676404b540aSrobert  "TARGET_HAS_XFLOATING_LIBS"
2677404b540aSrobert  "alpha_emit_xfloating_cvt (FLOAT, operands); DONE;")
2678404b540aSrobert
2679404b540aSrobert(define_expand "floatunsdisf2"
2680404b540aSrobert  [(use (match_operand:SF 0 "register_operand" ""))
2681404b540aSrobert   (use (match_operand:DI 1 "register_operand" ""))]
2682404b540aSrobert  "TARGET_FP"
2683404b540aSrobert  "alpha_emit_floatuns (operands); DONE;")
2684404b540aSrobert
2685404b540aSrobert(define_expand "floatunsdidf2"
2686404b540aSrobert  [(use (match_operand:DF 0 "register_operand" ""))
2687404b540aSrobert   (use (match_operand:DI 1 "register_operand" ""))]
2688404b540aSrobert  "TARGET_FP"
2689404b540aSrobert  "alpha_emit_floatuns (operands); DONE;")
2690404b540aSrobert
2691404b540aSrobert(define_expand "floatunsditf2"
2692404b540aSrobert  [(use (match_operand:TF 0 "register_operand" ""))
2693404b540aSrobert   (use (match_operand:DI 1 "general_operand" ""))]
2694404b540aSrobert  "TARGET_HAS_XFLOATING_LIBS"
2695404b540aSrobert  "alpha_emit_xfloating_cvt (UNSIGNED_FLOAT, operands); DONE;")
2696404b540aSrobert
2697404b540aSrobert(define_expand "extendsfdf2"
2698404b540aSrobert  [(set (match_operand:DF 0 "register_operand" "")
2699404b540aSrobert	(float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "")))]
2700404b540aSrobert  "TARGET_FP"
2701404b540aSrobert{
2702404b540aSrobert  if (alpha_fptm >= ALPHA_FPTM_SU)
2703404b540aSrobert    operands[1] = force_reg (SFmode, operands[1]);
2704404b540aSrobert})
2705404b540aSrobert
2706404b540aSrobert;; The Unicos/Mk assembler doesn't support cvtst, but we've already
2707404b540aSrobert;; asserted that alpha_fptm == ALPHA_FPTM_N.
2708404b540aSrobert
2709404b540aSrobert(define_insn "*extendsfdf2_ieee"
2710404b540aSrobert  [(set (match_operand:DF 0 "register_operand" "=&f")
2711404b540aSrobert	(float_extend:DF (match_operand:SF 1 "register_operand" "f")))]
2712404b540aSrobert  "TARGET_FP && alpha_fptm >= ALPHA_FPTM_SU"
2713404b540aSrobert  "cvtsts %1,%0"
2714404b540aSrobert  [(set_attr "type" "fadd")
2715404b540aSrobert   (set_attr "trap" "yes")])
2716404b540aSrobert
2717404b540aSrobert(define_insn "*extendsfdf2_internal"
2718404b540aSrobert  [(set (match_operand:DF 0 "register_operand" "=f,f,m")
2719404b540aSrobert	(float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "f,m,f")))]
2720404b540aSrobert  "TARGET_FP && alpha_fptm < ALPHA_FPTM_SU"
2721404b540aSrobert  "@
2722404b540aSrobert   cpys %1,%1,%0
2723404b540aSrobert   ld%, %0,%1
2724404b540aSrobert   st%- %1,%0"
2725404b540aSrobert  [(set_attr "type" "fcpys,fld,fst")])
2726404b540aSrobert
2727404b540aSrobert;; Use register_operand for operand 1 to prevent compress_float_constant
2728404b540aSrobert;; from doing something silly.  When optimizing we'll put things back
2729404b540aSrobert;; together anyway.
2730404b540aSrobert(define_expand "extendsftf2"
2731404b540aSrobert  [(use (match_operand:TF 0 "register_operand" ""))
2732404b540aSrobert   (use (match_operand:SF 1 "register_operand" ""))]
2733404b540aSrobert  "TARGET_HAS_XFLOATING_LIBS"
2734404b540aSrobert{
2735404b540aSrobert  rtx tmp = gen_reg_rtx (DFmode);
2736404b540aSrobert  emit_insn (gen_extendsfdf2 (tmp, operands[1]));
2737404b540aSrobert  emit_insn (gen_extenddftf2 (operands[0], tmp));
2738404b540aSrobert  DONE;
2739404b540aSrobert})
2740404b540aSrobert
2741404b540aSrobert(define_expand "extenddftf2"
2742404b540aSrobert  [(use (match_operand:TF 0 "register_operand" ""))
2743404b540aSrobert   (use (match_operand:DF 1 "register_operand" ""))]
2744404b540aSrobert  "TARGET_HAS_XFLOATING_LIBS"
2745404b540aSrobert  "alpha_emit_xfloating_cvt (FLOAT_EXTEND, operands); DONE;")
2746404b540aSrobert
2747404b540aSrobert(define_insn "*truncdfsf2_ieee"
2748404b540aSrobert  [(set (match_operand:SF 0 "register_operand" "=&f")
2749404b540aSrobert	(float_truncate:SF (match_operand:DF 1 "reg_or_0_operand" "fG")))]
2750404b540aSrobert  "TARGET_FP && alpha_fptm >= ALPHA_FPTM_SU"
2751404b540aSrobert  "cvt%-%,%/ %R1,%0"
2752404b540aSrobert  [(set_attr "type" "fadd")
2753404b540aSrobert   (set_attr "trap" "yes")
2754404b540aSrobert   (set_attr "round_suffix" "normal")
2755404b540aSrobert   (set_attr "trap_suffix" "u_su_sui")])
2756404b540aSrobert
2757404b540aSrobert(define_insn "truncdfsf2"
2758404b540aSrobert  [(set (match_operand:SF 0 "register_operand" "=f")
2759404b540aSrobert	(float_truncate:SF (match_operand:DF 1 "reg_or_0_operand" "fG")))]
2760404b540aSrobert  "TARGET_FP"
2761404b540aSrobert  "cvt%-%,%/ %R1,%0"
2762404b540aSrobert  [(set_attr "type" "fadd")
2763404b540aSrobert   (set_attr "trap" "yes")
2764404b540aSrobert   (set_attr "round_suffix" "normal")
2765404b540aSrobert   (set_attr "trap_suffix" "u_su_sui")])
2766404b540aSrobert
2767404b540aSrobert(define_expand "trunctfdf2"
2768404b540aSrobert  [(use (match_operand:DF 0 "register_operand" ""))
2769404b540aSrobert   (use (match_operand:TF 1 "general_operand" ""))]
2770404b540aSrobert  "TARGET_HAS_XFLOATING_LIBS"
2771404b540aSrobert  "alpha_emit_xfloating_cvt (FLOAT_TRUNCATE, operands); DONE;")
2772404b540aSrobert
2773404b540aSrobert(define_expand "trunctfsf2"
2774404b540aSrobert  [(use (match_operand:SF 0 "register_operand" ""))
2775404b540aSrobert   (use (match_operand:TF 1 "general_operand" ""))]
2776404b540aSrobert  "TARGET_FP && TARGET_HAS_XFLOATING_LIBS"
2777404b540aSrobert{
2778404b540aSrobert  rtx tmpf, sticky, arg, lo, hi;
2779404b540aSrobert
2780404b540aSrobert  tmpf = gen_reg_rtx (DFmode);
2781404b540aSrobert  sticky = gen_reg_rtx (DImode);
2782404b540aSrobert  arg = copy_to_mode_reg (TFmode, operands[1]);
2783404b540aSrobert  lo = gen_lowpart (DImode, arg);
2784404b540aSrobert  hi = gen_highpart (DImode, arg);
2785404b540aSrobert
2786404b540aSrobert  /* Convert the low word of the TFmode value into a sticky rounding bit,
2787404b540aSrobert     then or it into the low bit of the high word.  This leaves the sticky
2788404b540aSrobert     bit at bit 48 of the fraction, which is representable in DFmode,
2789404b540aSrobert     which prevents rounding error in the final conversion to SFmode.  */
2790404b540aSrobert
2791404b540aSrobert  emit_insn (gen_rtx_SET (VOIDmode, sticky,
2792404b540aSrobert			  gen_rtx_NE (DImode, lo, const0_rtx)));
2793404b540aSrobert  emit_insn (gen_iordi3 (hi, hi, sticky));
2794404b540aSrobert  emit_insn (gen_trunctfdf2 (tmpf, arg));
2795404b540aSrobert  emit_insn (gen_truncdfsf2 (operands[0], tmpf));
2796404b540aSrobert  DONE;
2797404b540aSrobert})
2798404b540aSrobert
2799404b540aSrobert(define_insn "*divsf3_ieee"
2800404b540aSrobert  [(set (match_operand:SF 0 "register_operand" "=&f")
2801404b540aSrobert	(div:SF (match_operand:SF 1 "reg_or_0_operand" "fG")
2802404b540aSrobert		(match_operand:SF 2 "reg_or_0_operand" "fG")))]
2803404b540aSrobert  "TARGET_FP && alpha_fptm >= ALPHA_FPTM_SU"
2804404b540aSrobert  "div%,%/ %R1,%R2,%0"
2805404b540aSrobert  [(set_attr "type" "fdiv")
2806404b540aSrobert   (set_attr "opsize" "si")
2807404b540aSrobert   (set_attr "trap" "yes")
2808404b540aSrobert   (set_attr "round_suffix" "normal")
2809404b540aSrobert   (set_attr "trap_suffix" "u_su_sui")])
2810404b540aSrobert
2811404b540aSrobert(define_insn "divsf3"
2812404b540aSrobert  [(set (match_operand:SF 0 "register_operand" "=f")
2813404b540aSrobert	(div:SF (match_operand:SF 1 "reg_or_0_operand" "fG")
2814404b540aSrobert		(match_operand:SF 2 "reg_or_0_operand" "fG")))]
2815404b540aSrobert  "TARGET_FP"
2816404b540aSrobert  "div%,%/ %R1,%R2,%0"
2817404b540aSrobert  [(set_attr "type" "fdiv")
2818404b540aSrobert   (set_attr "opsize" "si")
2819404b540aSrobert   (set_attr "trap" "yes")
2820404b540aSrobert   (set_attr "round_suffix" "normal")
2821404b540aSrobert   (set_attr "trap_suffix" "u_su_sui")])
2822404b540aSrobert
2823404b540aSrobert(define_insn "*divdf3_ieee"
2824404b540aSrobert  [(set (match_operand:DF 0 "register_operand" "=&f")
2825404b540aSrobert	(div:DF (match_operand:DF 1 "reg_or_0_operand" "fG")
2826404b540aSrobert		(match_operand:DF 2 "reg_or_0_operand" "fG")))]
2827404b540aSrobert  "TARGET_FP && alpha_fptm >= ALPHA_FPTM_SU"
2828404b540aSrobert  "div%-%/ %R1,%R2,%0"
2829404b540aSrobert  [(set_attr "type" "fdiv")
2830404b540aSrobert   (set_attr "trap" "yes")
2831404b540aSrobert   (set_attr "round_suffix" "normal")
2832404b540aSrobert   (set_attr "trap_suffix" "u_su_sui")])
2833404b540aSrobert
2834404b540aSrobert(define_insn "divdf3"
2835404b540aSrobert  [(set (match_operand:DF 0 "register_operand" "=f")
2836404b540aSrobert	(div:DF (match_operand:DF 1 "reg_or_0_operand" "fG")
2837404b540aSrobert		(match_operand:DF 2 "reg_or_0_operand" "fG")))]
2838404b540aSrobert  "TARGET_FP"
2839404b540aSrobert  "div%-%/ %R1,%R2,%0"
2840404b540aSrobert  [(set_attr "type" "fdiv")
2841404b540aSrobert   (set_attr "trap" "yes")
2842404b540aSrobert   (set_attr "round_suffix" "normal")
2843404b540aSrobert   (set_attr "trap_suffix" "u_su_sui")])
2844404b540aSrobert
2845404b540aSrobert(define_insn "*divdf_ext1"
2846404b540aSrobert  [(set (match_operand:DF 0 "register_operand" "=f")
2847404b540aSrobert	(div:DF (float_extend:DF (match_operand:SF 1 "reg_or_0_operand" "fG"))
2848404b540aSrobert		(match_operand:DF 2 "reg_or_0_operand" "fG")))]
2849404b540aSrobert  "TARGET_FP && alpha_fptm < ALPHA_FPTM_SU"
2850404b540aSrobert  "div%-%/ %R1,%R2,%0"
2851404b540aSrobert  [(set_attr "type" "fdiv")
2852404b540aSrobert   (set_attr "trap" "yes")
2853404b540aSrobert   (set_attr "round_suffix" "normal")
2854404b540aSrobert   (set_attr "trap_suffix" "u_su_sui")])
2855404b540aSrobert
2856404b540aSrobert(define_insn "*divdf_ext2"
2857404b540aSrobert  [(set (match_operand:DF 0 "register_operand" "=f")
2858404b540aSrobert	(div:DF (match_operand:DF 1 "reg_or_0_operand" "fG")
2859404b540aSrobert		(float_extend:DF
2860404b540aSrobert		 (match_operand:SF 2 "reg_or_0_operand" "fG"))))]
2861404b540aSrobert  "TARGET_FP && alpha_fptm < ALPHA_FPTM_SU"
2862404b540aSrobert  "div%-%/ %R1,%R2,%0"
2863404b540aSrobert  [(set_attr "type" "fdiv")
2864404b540aSrobert   (set_attr "trap" "yes")
2865404b540aSrobert   (set_attr "round_suffix" "normal")
2866404b540aSrobert   (set_attr "trap_suffix" "u_su_sui")])
2867404b540aSrobert
2868404b540aSrobert(define_insn "*divdf_ext3"
2869404b540aSrobert  [(set (match_operand:DF 0 "register_operand" "=f")
2870404b540aSrobert	(div:DF (float_extend:DF (match_operand:SF 1 "reg_or_0_operand" "fG"))
2871404b540aSrobert		(float_extend:DF (match_operand:SF 2 "reg_or_0_operand" "fG"))))]
2872404b540aSrobert  "TARGET_FP && alpha_fptm < ALPHA_FPTM_SU"
2873404b540aSrobert  "div%-%/ %R1,%R2,%0"
2874404b540aSrobert  [(set_attr "type" "fdiv")
2875404b540aSrobert   (set_attr "trap" "yes")
2876404b540aSrobert   (set_attr "round_suffix" "normal")
2877404b540aSrobert   (set_attr "trap_suffix" "u_su_sui")])
2878404b540aSrobert
2879404b540aSrobert(define_expand "divtf3"
2880404b540aSrobert  [(use (match_operand 0 "register_operand" ""))
2881404b540aSrobert   (use (match_operand 1 "general_operand" ""))
2882404b540aSrobert   (use (match_operand 2 "general_operand" ""))]
2883404b540aSrobert  "TARGET_HAS_XFLOATING_LIBS"
2884404b540aSrobert  "alpha_emit_xfloating_arith (DIV, operands); DONE;")
2885404b540aSrobert
2886404b540aSrobert(define_insn "*mulsf3_ieee"
2887404b540aSrobert  [(set (match_operand:SF 0 "register_operand" "=&f")
2888404b540aSrobert	(mult:SF (match_operand:SF 1 "reg_or_0_operand" "%fG")
2889404b540aSrobert		 (match_operand:SF 2 "reg_or_0_operand" "fG")))]
2890404b540aSrobert  "TARGET_FP && alpha_fptm >= ALPHA_FPTM_SU"
2891404b540aSrobert  "mul%,%/ %R1,%R2,%0"
2892404b540aSrobert  [(set_attr "type" "fmul")
2893404b540aSrobert   (set_attr "trap" "yes")
2894404b540aSrobert   (set_attr "round_suffix" "normal")
2895404b540aSrobert   (set_attr "trap_suffix" "u_su_sui")])
2896404b540aSrobert
2897404b540aSrobert(define_insn "mulsf3"
2898404b540aSrobert  [(set (match_operand:SF 0 "register_operand" "=f")
2899404b540aSrobert	(mult:SF (match_operand:SF 1 "reg_or_0_operand" "%fG")
2900404b540aSrobert		 (match_operand:SF 2 "reg_or_0_operand" "fG")))]
2901404b540aSrobert  "TARGET_FP"
2902404b540aSrobert  "mul%,%/ %R1,%R2,%0"
2903404b540aSrobert  [(set_attr "type" "fmul")
2904404b540aSrobert   (set_attr "trap" "yes")
2905404b540aSrobert   (set_attr "round_suffix" "normal")
2906404b540aSrobert   (set_attr "trap_suffix" "u_su_sui")])
2907404b540aSrobert
2908404b540aSrobert(define_insn "*muldf3_ieee"
2909404b540aSrobert  [(set (match_operand:DF 0 "register_operand" "=&f")
2910404b540aSrobert	(mult:DF (match_operand:DF 1 "reg_or_0_operand" "%fG")
2911404b540aSrobert		 (match_operand:DF 2 "reg_or_0_operand" "fG")))]
2912404b540aSrobert  "TARGET_FP && alpha_fptm >= ALPHA_FPTM_SU"
2913404b540aSrobert  "mul%-%/ %R1,%R2,%0"
2914404b540aSrobert  [(set_attr "type" "fmul")
2915404b540aSrobert   (set_attr "trap" "yes")
2916404b540aSrobert   (set_attr "round_suffix" "normal")
2917404b540aSrobert   (set_attr "trap_suffix" "u_su_sui")])
2918404b540aSrobert
2919404b540aSrobert(define_insn "muldf3"
2920404b540aSrobert  [(set (match_operand:DF 0 "register_operand" "=f")
2921404b540aSrobert	(mult:DF (match_operand:DF 1 "reg_or_0_operand" "%fG")
2922404b540aSrobert		 (match_operand:DF 2 "reg_or_0_operand" "fG")))]
2923404b540aSrobert  "TARGET_FP"
2924404b540aSrobert  "mul%-%/ %R1,%R2,%0"
2925404b540aSrobert  [(set_attr "type" "fmul")
2926404b540aSrobert   (set_attr "trap" "yes")
2927404b540aSrobert   (set_attr "round_suffix" "normal")
2928404b540aSrobert   (set_attr "trap_suffix" "u_su_sui")])
2929404b540aSrobert
2930404b540aSrobert(define_insn "*muldf_ext1"
2931404b540aSrobert  [(set (match_operand:DF 0 "register_operand" "=f")
2932404b540aSrobert	(mult:DF (float_extend:DF
2933404b540aSrobert		  (match_operand:SF 1 "reg_or_0_operand" "fG"))
2934404b540aSrobert		 (match_operand:DF 2 "reg_or_0_operand" "fG")))]
2935404b540aSrobert  "TARGET_FP && alpha_fptm < ALPHA_FPTM_SU"
2936404b540aSrobert  "mul%-%/ %R1,%R2,%0"
2937404b540aSrobert  [(set_attr "type" "fmul")
2938404b540aSrobert   (set_attr "trap" "yes")
2939404b540aSrobert   (set_attr "round_suffix" "normal")
2940404b540aSrobert   (set_attr "trap_suffix" "u_su_sui")])
2941404b540aSrobert
2942404b540aSrobert(define_insn "*muldf_ext2"
2943404b540aSrobert  [(set (match_operand:DF 0 "register_operand" "=f")
2944404b540aSrobert	(mult:DF (float_extend:DF
2945404b540aSrobert		  (match_operand:SF 1 "reg_or_0_operand" "%fG"))
2946404b540aSrobert		 (float_extend:DF
2947404b540aSrobert		  (match_operand:SF 2 "reg_or_0_operand" "fG"))))]
2948404b540aSrobert  "TARGET_FP && alpha_fptm < ALPHA_FPTM_SU"
2949404b540aSrobert  "mul%-%/ %R1,%R2,%0"
2950404b540aSrobert  [(set_attr "type" "fmul")
2951404b540aSrobert   (set_attr "trap" "yes")
2952404b540aSrobert   (set_attr "round_suffix" "normal")
2953404b540aSrobert   (set_attr "trap_suffix" "u_su_sui")])
2954404b540aSrobert
2955404b540aSrobert(define_expand "multf3"
2956404b540aSrobert  [(use (match_operand 0 "register_operand" ""))
2957404b540aSrobert   (use (match_operand 1 "general_operand" ""))
2958404b540aSrobert   (use (match_operand 2 "general_operand" ""))]
2959404b540aSrobert  "TARGET_HAS_XFLOATING_LIBS"
2960404b540aSrobert  "alpha_emit_xfloating_arith (MULT, operands); DONE;")
2961404b540aSrobert
2962404b540aSrobert(define_insn "*subsf3_ieee"
2963404b540aSrobert  [(set (match_operand:SF 0 "register_operand" "=&f")
2964404b540aSrobert	(minus:SF (match_operand:SF 1 "reg_or_0_operand" "fG")
2965404b540aSrobert		  (match_operand:SF 2 "reg_or_0_operand" "fG")))]
2966404b540aSrobert  "TARGET_FP && alpha_fptm >= ALPHA_FPTM_SU"
2967404b540aSrobert  "sub%,%/ %R1,%R2,%0"
2968404b540aSrobert  [(set_attr "type" "fadd")
2969404b540aSrobert   (set_attr "trap" "yes")
2970404b540aSrobert   (set_attr "round_suffix" "normal")
2971404b540aSrobert   (set_attr "trap_suffix" "u_su_sui")])
2972404b540aSrobert
2973404b540aSrobert(define_insn "subsf3"
2974404b540aSrobert  [(set (match_operand:SF 0 "register_operand" "=f")
2975404b540aSrobert	(minus:SF (match_operand:SF 1 "reg_or_0_operand" "fG")
2976404b540aSrobert		  (match_operand:SF 2 "reg_or_0_operand" "fG")))]
2977404b540aSrobert  "TARGET_FP"
2978404b540aSrobert  "sub%,%/ %R1,%R2,%0"
2979404b540aSrobert  [(set_attr "type" "fadd")
2980404b540aSrobert   (set_attr "trap" "yes")
2981404b540aSrobert   (set_attr "round_suffix" "normal")
2982404b540aSrobert   (set_attr "trap_suffix" "u_su_sui")])
2983404b540aSrobert
2984404b540aSrobert(define_insn "*subdf3_ieee"
2985404b540aSrobert  [(set (match_operand:DF 0 "register_operand" "=&f")
2986404b540aSrobert	(minus:DF (match_operand:DF 1 "reg_or_0_operand" "fG")
2987404b540aSrobert		  (match_operand:DF 2 "reg_or_0_operand" "fG")))]
2988404b540aSrobert  "TARGET_FP && alpha_fptm >= ALPHA_FPTM_SU"
2989404b540aSrobert  "sub%-%/ %R1,%R2,%0"
2990404b540aSrobert  [(set_attr "type" "fadd")
2991404b540aSrobert   (set_attr "trap" "yes")
2992404b540aSrobert   (set_attr "round_suffix" "normal")
2993404b540aSrobert   (set_attr "trap_suffix" "u_su_sui")])
2994404b540aSrobert
2995404b540aSrobert(define_insn "subdf3"
2996404b540aSrobert  [(set (match_operand:DF 0 "register_operand" "=f")
2997404b540aSrobert	(minus:DF (match_operand:DF 1 "reg_or_0_operand" "fG")
2998404b540aSrobert		  (match_operand:DF 2 "reg_or_0_operand" "fG")))]
2999404b540aSrobert  "TARGET_FP"
3000404b540aSrobert  "sub%-%/ %R1,%R2,%0"
3001404b540aSrobert  [(set_attr "type" "fadd")
3002404b540aSrobert   (set_attr "trap" "yes")
3003404b540aSrobert   (set_attr "round_suffix" "normal")
3004404b540aSrobert   (set_attr "trap_suffix" "u_su_sui")])
3005404b540aSrobert
3006404b540aSrobert(define_insn "*subdf_ext1"
3007404b540aSrobert  [(set (match_operand:DF 0 "register_operand" "=f")
3008404b540aSrobert	(minus:DF (float_extend:DF
3009404b540aSrobert		   (match_operand:SF 1 "reg_or_0_operand" "fG"))
3010404b540aSrobert		  (match_operand:DF 2 "reg_or_0_operand" "fG")))]
3011404b540aSrobert  "TARGET_FP && alpha_fptm < ALPHA_FPTM_SU"
3012404b540aSrobert  "sub%-%/ %R1,%R2,%0"
3013404b540aSrobert  [(set_attr "type" "fadd")
3014404b540aSrobert   (set_attr "trap" "yes")
3015404b540aSrobert   (set_attr "round_suffix" "normal")
3016404b540aSrobert   (set_attr "trap_suffix" "u_su_sui")])
3017404b540aSrobert
3018404b540aSrobert(define_insn "*subdf_ext2"
3019404b540aSrobert  [(set (match_operand:DF 0 "register_operand" "=f")
3020404b540aSrobert	(minus:DF (match_operand:DF 1 "reg_or_0_operand" "fG")
3021404b540aSrobert		  (float_extend:DF
3022404b540aSrobert		   (match_operand:SF 2 "reg_or_0_operand" "fG"))))]
3023404b540aSrobert  "TARGET_FP && alpha_fptm < ALPHA_FPTM_SU"
3024404b540aSrobert  "sub%-%/ %R1,%R2,%0"
3025404b540aSrobert  [(set_attr "type" "fadd")
3026404b540aSrobert   (set_attr "trap" "yes")
3027404b540aSrobert   (set_attr "round_suffix" "normal")
3028404b540aSrobert   (set_attr "trap_suffix" "u_su_sui")])
3029404b540aSrobert
3030404b540aSrobert(define_insn "*subdf_ext3"
3031404b540aSrobert  [(set (match_operand:DF 0 "register_operand" "=f")
3032404b540aSrobert	(minus:DF (float_extend:DF
3033404b540aSrobert		   (match_operand:SF 1 "reg_or_0_operand" "fG"))
3034404b540aSrobert		  (float_extend:DF
3035404b540aSrobert		   (match_operand:SF 2 "reg_or_0_operand" "fG"))))]
3036404b540aSrobert  "TARGET_FP && alpha_fptm < ALPHA_FPTM_SU"
3037404b540aSrobert  "sub%-%/ %R1,%R2,%0"
3038404b540aSrobert  [(set_attr "type" "fadd")
3039404b540aSrobert   (set_attr "trap" "yes")
3040404b540aSrobert   (set_attr "round_suffix" "normal")
3041404b540aSrobert   (set_attr "trap_suffix" "u_su_sui")])
3042404b540aSrobert
3043404b540aSrobert(define_expand "subtf3"
3044404b540aSrobert  [(use (match_operand 0 "register_operand" ""))
3045404b540aSrobert   (use (match_operand 1 "general_operand" ""))
3046404b540aSrobert   (use (match_operand 2 "general_operand" ""))]
3047404b540aSrobert  "TARGET_HAS_XFLOATING_LIBS"
3048404b540aSrobert  "alpha_emit_xfloating_arith (MINUS, operands); DONE;")
3049404b540aSrobert
3050404b540aSrobert(define_insn "*sqrtsf2_ieee"
3051404b540aSrobert  [(set (match_operand:SF 0 "register_operand" "=&f")
3052404b540aSrobert	(sqrt:SF (match_operand:SF 1 "reg_or_0_operand" "fG")))]
3053404b540aSrobert  "TARGET_FP && TARGET_FIX && alpha_fptm >= ALPHA_FPTM_SU"
3054404b540aSrobert  "sqrt%,%/ %R1,%0"
3055404b540aSrobert  [(set_attr "type" "fsqrt")
3056404b540aSrobert   (set_attr "opsize" "si")
3057404b540aSrobert   (set_attr "trap" "yes")
3058404b540aSrobert   (set_attr "round_suffix" "normal")
3059404b540aSrobert   (set_attr "trap_suffix" "u_su_sui")])
3060404b540aSrobert
3061404b540aSrobert(define_insn "sqrtsf2"
3062404b540aSrobert  [(set (match_operand:SF 0 "register_operand" "=f")
3063404b540aSrobert	(sqrt:SF (match_operand:SF 1 "reg_or_0_operand" "fG")))]
3064404b540aSrobert  "TARGET_FP && TARGET_FIX"
3065404b540aSrobert  "sqrt%,%/ %R1,%0"
3066404b540aSrobert  [(set_attr "type" "fsqrt")
3067404b540aSrobert   (set_attr "opsize" "si")
3068404b540aSrobert   (set_attr "trap" "yes")
3069404b540aSrobert   (set_attr "round_suffix" "normal")
3070404b540aSrobert   (set_attr "trap_suffix" "u_su_sui")])
3071404b540aSrobert
3072404b540aSrobert(define_insn "*sqrtdf2_ieee"
3073404b540aSrobert  [(set (match_operand:DF 0 "register_operand" "=&f")
3074404b540aSrobert	(sqrt:DF (match_operand:DF 1 "reg_or_0_operand" "fG")))]
3075404b540aSrobert  "TARGET_FP && TARGET_FIX && alpha_fptm >= ALPHA_FPTM_SU"
3076404b540aSrobert  "sqrt%-%/ %R1,%0"
3077404b540aSrobert  [(set_attr "type" "fsqrt")
3078404b540aSrobert   (set_attr "trap" "yes")
3079404b540aSrobert   (set_attr "round_suffix" "normal")
3080404b540aSrobert   (set_attr "trap_suffix" "u_su_sui")])
3081404b540aSrobert
3082404b540aSrobert(define_insn "sqrtdf2"
3083404b540aSrobert  [(set (match_operand:DF 0 "register_operand" "=f")
3084404b540aSrobert	(sqrt:DF (match_operand:DF 1 "reg_or_0_operand" "fG")))]
3085404b540aSrobert  "TARGET_FP && TARGET_FIX"
3086404b540aSrobert  "sqrt%-%/ %R1,%0"
3087404b540aSrobert  [(set_attr "type" "fsqrt")
3088404b540aSrobert   (set_attr "trap" "yes")
3089404b540aSrobert   (set_attr "round_suffix" "normal")
3090404b540aSrobert   (set_attr "trap_suffix" "u_su_sui")])
3091404b540aSrobert
3092404b540aSrobert;; Next are all the integer comparisons, and conditional moves and branches
3093404b540aSrobert;; and some of the related define_expand's and define_split's.
3094404b540aSrobert
3095404b540aSrobert(define_insn "*setcc_internal"
3096404b540aSrobert  [(set (match_operand 0 "register_operand" "=r")
3097404b540aSrobert	(match_operator 1 "alpha_comparison_operator"
3098404b540aSrobert			   [(match_operand:DI 2 "register_operand" "r")
3099404b540aSrobert			    (match_operand:DI 3 "reg_or_8bit_operand" "rI")]))]
3100404b540aSrobert  "GET_MODE_CLASS (GET_MODE (operands[0])) == MODE_INT
3101404b540aSrobert   && GET_MODE_SIZE (GET_MODE (operands[0])) <= 8
3102404b540aSrobert   && GET_MODE (operands[0]) == GET_MODE (operands[1])"
3103404b540aSrobert  "cmp%C1 %2,%3,%0"
3104404b540aSrobert  [(set_attr "type" "icmp")])
3105404b540aSrobert
3106404b540aSrobert;; Yes, we can technically support reg_or_8bit_operand in operand 2,
3107404b540aSrobert;; but that's non-canonical rtl and allowing that causes inefficiencies
3108404b540aSrobert;; from cse on.
3109404b540aSrobert(define_insn "*setcc_swapped_internal"
3110404b540aSrobert  [(set (match_operand 0 "register_operand" "=r")
3111404b540aSrobert        (match_operator 1 "alpha_swapped_comparison_operator"
3112404b540aSrobert			   [(match_operand:DI 2 "register_operand" "r")
3113404b540aSrobert			    (match_operand:DI 3 "reg_or_0_operand" "rJ")]))]
3114404b540aSrobert  "GET_MODE_CLASS (GET_MODE (operands[0])) == MODE_INT
3115404b540aSrobert   && GET_MODE_SIZE (GET_MODE (operands[0])) <= 8
3116404b540aSrobert   && GET_MODE (operands[0]) == GET_MODE (operands[1])"
3117404b540aSrobert  "cmp%c1 %r3,%2,%0"
3118404b540aSrobert  [(set_attr "type" "icmp")])
3119404b540aSrobert
3120404b540aSrobert;; Use match_operator rather than ne directly so that we can match
3121404b540aSrobert;; multiple integer modes.
3122404b540aSrobert(define_insn "*setne_internal"
3123404b540aSrobert  [(set (match_operand 0 "register_operand" "=r")
3124404b540aSrobert	(match_operator 1 "signed_comparison_operator"
3125404b540aSrobert			  [(match_operand:DI 2 "register_operand" "r")
3126404b540aSrobert			   (const_int 0)]))]
3127404b540aSrobert  "GET_MODE_CLASS (GET_MODE (operands[0])) == MODE_INT
3128404b540aSrobert   && GET_MODE_SIZE (GET_MODE (operands[0])) <= 8
3129404b540aSrobert   && GET_CODE (operands[1]) == NE
3130404b540aSrobert   && GET_MODE (operands[0]) == GET_MODE (operands[1])"
3131404b540aSrobert  "cmpult $31,%2,%0"
3132404b540aSrobert  [(set_attr "type" "icmp")])
3133404b540aSrobert
3134404b540aSrobert;; The mode folding trick can't be used with const_int operands, since
3135404b540aSrobert;; reload needs to know the proper mode.
3136404b540aSrobert;;
3137404b540aSrobert;; Use add_operand instead of the more seemingly natural reg_or_8bit_operand
3138404b540aSrobert;; in order to create more pairs of constants.  As long as we're allowing
3139404b540aSrobert;; two constants at the same time, and will have to reload one of them...
3140404b540aSrobert
3141404b540aSrobert(define_insn "*movqicc_internal"
3142404b540aSrobert  [(set (match_operand:QI 0 "register_operand" "=r,r,r,r")
3143404b540aSrobert	(if_then_else:QI
3144404b540aSrobert	 (match_operator 2 "signed_comparison_operator"
3145404b540aSrobert			 [(match_operand:DI 3 "reg_or_0_operand" "rJ,rJ,J,J")
3146404b540aSrobert			  (match_operand:DI 4 "reg_or_0_operand" "J,J,rJ,rJ")])
3147404b540aSrobert	 (match_operand:QI 1 "add_operand" "rI,0,rI,0")
3148404b540aSrobert	 (match_operand:QI 5 "add_operand" "0,rI,0,rI")))]
3149404b540aSrobert  "(operands[3] == const0_rtx) ^ (operands[4] == const0_rtx)"
3150404b540aSrobert  "@
3151404b540aSrobert   cmov%C2 %r3,%1,%0
3152404b540aSrobert   cmov%D2 %r3,%5,%0
3153404b540aSrobert   cmov%c2 %r4,%1,%0
3154404b540aSrobert   cmov%d2 %r4,%5,%0"
3155404b540aSrobert  [(set_attr "type" "icmov")])
3156404b540aSrobert
3157404b540aSrobert(define_insn "*movhicc_internal"
3158404b540aSrobert  [(set (match_operand:HI 0 "register_operand" "=r,r,r,r")
3159404b540aSrobert	(if_then_else:HI
3160404b540aSrobert	 (match_operator 2 "signed_comparison_operator"
3161404b540aSrobert			 [(match_operand:DI 3 "reg_or_0_operand" "rJ,rJ,J,J")
3162404b540aSrobert			  (match_operand:DI 4 "reg_or_0_operand" "J,J,rJ,rJ")])
3163404b540aSrobert	 (match_operand:HI 1 "add_operand" "rI,0,rI,0")
3164404b540aSrobert	 (match_operand:HI 5 "add_operand" "0,rI,0,rI")))]
3165404b540aSrobert  "(operands[3] == const0_rtx) ^ (operands[4] == const0_rtx)"
3166404b540aSrobert  "@
3167404b540aSrobert   cmov%C2 %r3,%1,%0
3168404b540aSrobert   cmov%D2 %r3,%5,%0
3169404b540aSrobert   cmov%c2 %r4,%1,%0
3170404b540aSrobert   cmov%d2 %r4,%5,%0"
3171404b540aSrobert  [(set_attr "type" "icmov")])
3172404b540aSrobert
3173404b540aSrobert(define_insn "*movsicc_internal"
3174404b540aSrobert  [(set (match_operand:SI 0 "register_operand" "=r,r,r,r")
3175404b540aSrobert	(if_then_else:SI
3176404b540aSrobert	 (match_operator 2 "signed_comparison_operator"
3177404b540aSrobert			 [(match_operand:DI 3 "reg_or_0_operand" "rJ,rJ,J,J")
3178404b540aSrobert			  (match_operand:DI 4 "reg_or_0_operand" "J,J,rJ,rJ")])
3179404b540aSrobert	 (match_operand:SI 1 "add_operand" "rI,0,rI,0")
3180404b540aSrobert	 (match_operand:SI 5 "add_operand" "0,rI,0,rI")))]
3181404b540aSrobert  "(operands[3] == const0_rtx) ^ (operands[4] == const0_rtx)"
3182404b540aSrobert  "@
3183404b540aSrobert   cmov%C2 %r3,%1,%0
3184404b540aSrobert   cmov%D2 %r3,%5,%0
3185404b540aSrobert   cmov%c2 %r4,%1,%0
3186404b540aSrobert   cmov%d2 %r4,%5,%0"
3187404b540aSrobert  [(set_attr "type" "icmov")])
3188404b540aSrobert
3189404b540aSrobert(define_insn "*movdicc_internal"
3190404b540aSrobert  [(set (match_operand:DI 0 "register_operand" "=r,r,r,r")
3191404b540aSrobert	(if_then_else:DI
3192404b540aSrobert	 (match_operator 2 "signed_comparison_operator"
3193404b540aSrobert			 [(match_operand:DI 3 "reg_or_0_operand" "rJ,rJ,J,J")
3194404b540aSrobert			  (match_operand:DI 4 "reg_or_0_operand" "J,J,rJ,rJ")])
3195404b540aSrobert	 (match_operand:DI 1 "add_operand" "rI,0,rI,0")
3196404b540aSrobert	 (match_operand:DI 5 "add_operand" "0,rI,0,rI")))]
3197404b540aSrobert  "(operands[3] == const0_rtx) ^ (operands[4] == const0_rtx)"
3198404b540aSrobert  "@
3199404b540aSrobert   cmov%C2 %r3,%1,%0
3200404b540aSrobert   cmov%D2 %r3,%5,%0
3201404b540aSrobert   cmov%c2 %r4,%1,%0
3202404b540aSrobert   cmov%d2 %r4,%5,%0"
3203404b540aSrobert  [(set_attr "type" "icmov")])
3204404b540aSrobert
3205404b540aSrobert(define_insn "*movqicc_lbc"
3206404b540aSrobert  [(set (match_operand:QI 0 "register_operand" "=r,r")
3207404b540aSrobert	(if_then_else:QI
3208404b540aSrobert	 (eq (zero_extract:DI (match_operand:DI 2 "reg_or_0_operand" "rJ,rJ")
3209404b540aSrobert			      (const_int 1)
3210404b540aSrobert			      (const_int 0))
3211404b540aSrobert	     (const_int 0))
3212404b540aSrobert	 (match_operand:QI 1 "reg_or_8bit_operand" "rI,0")
3213404b540aSrobert	 (match_operand:QI 3 "reg_or_8bit_operand" "0,rI")))]
3214404b540aSrobert  ""
3215404b540aSrobert  "@
3216404b540aSrobert   cmovlbc %r2,%1,%0
3217404b540aSrobert   cmovlbs %r2,%3,%0"
3218404b540aSrobert  [(set_attr "type" "icmov")])
3219404b540aSrobert
3220404b540aSrobert(define_insn "*movhicc_lbc"
3221404b540aSrobert  [(set (match_operand:HI 0 "register_operand" "=r,r")
3222404b540aSrobert	(if_then_else:HI
3223404b540aSrobert	 (eq (zero_extract:DI (match_operand:DI 2 "reg_or_0_operand" "rJ,rJ")
3224404b540aSrobert			      (const_int 1)
3225404b540aSrobert			      (const_int 0))
3226404b540aSrobert	     (const_int 0))
3227404b540aSrobert	 (match_operand:HI 1 "reg_or_8bit_operand" "rI,0")
3228404b540aSrobert	 (match_operand:HI 3 "reg_or_8bit_operand" "0,rI")))]
3229404b540aSrobert  ""
3230404b540aSrobert  "@
3231404b540aSrobert   cmovlbc %r2,%1,%0
3232404b540aSrobert   cmovlbs %r2,%3,%0"
3233404b540aSrobert  [(set_attr "type" "icmov")])
3234404b540aSrobert
3235404b540aSrobert(define_insn "*movsicc_lbc"
3236404b540aSrobert  [(set (match_operand:SI 0 "register_operand" "=r,r")
3237404b540aSrobert	(if_then_else:SI
3238404b540aSrobert	 (eq (zero_extract:DI (match_operand:DI 2 "reg_or_0_operand" "rJ,rJ")
3239404b540aSrobert			      (const_int 1)
3240404b540aSrobert			      (const_int 0))
3241404b540aSrobert	     (const_int 0))
3242404b540aSrobert	 (match_operand:SI 1 "reg_or_8bit_operand" "rI,0")
3243404b540aSrobert	 (match_operand:SI 3 "reg_or_8bit_operand" "0,rI")))]
3244404b540aSrobert  ""
3245404b540aSrobert  "@
3246404b540aSrobert   cmovlbc %r2,%1,%0
3247404b540aSrobert   cmovlbs %r2,%3,%0"
3248404b540aSrobert  [(set_attr "type" "icmov")])
3249404b540aSrobert
3250404b540aSrobert(define_insn "*movdicc_lbc"
3251404b540aSrobert  [(set (match_operand:DI 0 "register_operand" "=r,r")
3252404b540aSrobert	(if_then_else:DI
3253404b540aSrobert	 (eq (zero_extract:DI (match_operand:DI 2 "reg_or_0_operand" "rJ,rJ")
3254404b540aSrobert			      (const_int 1)
3255404b540aSrobert			      (const_int 0))
3256404b540aSrobert	     (const_int 0))
3257404b540aSrobert	 (match_operand:DI 1 "reg_or_8bit_operand" "rI,0")
3258404b540aSrobert	 (match_operand:DI 3 "reg_or_8bit_operand" "0,rI")))]
3259404b540aSrobert  ""
3260404b540aSrobert  "@
3261404b540aSrobert   cmovlbc %r2,%1,%0
3262404b540aSrobert   cmovlbs %r2,%3,%0"
3263404b540aSrobert  [(set_attr "type" "icmov")])
3264404b540aSrobert
3265404b540aSrobert(define_insn "*movqicc_lbs"
3266404b540aSrobert  [(set (match_operand:QI 0 "register_operand" "=r,r")
3267404b540aSrobert	(if_then_else:QI
3268404b540aSrobert	 (ne (zero_extract:DI (match_operand:DI 2 "reg_or_0_operand" "rJ,rJ")
3269404b540aSrobert			      (const_int 1)
3270404b540aSrobert			      (const_int 0))
3271404b540aSrobert	     (const_int 0))
3272404b540aSrobert	 (match_operand:QI 1 "reg_or_8bit_operand" "rI,0")
3273404b540aSrobert	 (match_operand:QI 3 "reg_or_8bit_operand" "0,rI")))]
3274404b540aSrobert  ""
3275404b540aSrobert  "@
3276404b540aSrobert   cmovlbs %r2,%1,%0
3277404b540aSrobert   cmovlbc %r2,%3,%0"
3278404b540aSrobert  [(set_attr "type" "icmov")])
3279404b540aSrobert
3280404b540aSrobert(define_insn "*movhicc_lbs"
3281404b540aSrobert  [(set (match_operand:HI 0 "register_operand" "=r,r")
3282404b540aSrobert	(if_then_else:HI
3283404b540aSrobert	 (ne (zero_extract:DI (match_operand:DI 2 "reg_or_0_operand" "rJ,rJ")
3284404b540aSrobert			      (const_int 1)
3285404b540aSrobert			      (const_int 0))
3286404b540aSrobert	     (const_int 0))
3287404b540aSrobert	 (match_operand:HI 1 "reg_or_8bit_operand" "rI,0")
3288404b540aSrobert	 (match_operand:HI 3 "reg_or_8bit_operand" "0,rI")))]
3289404b540aSrobert  ""
3290404b540aSrobert  "@
3291404b540aSrobert   cmovlbs %r2,%1,%0
3292404b540aSrobert   cmovlbc %r2,%3,%0"
3293404b540aSrobert  [(set_attr "type" "icmov")])
3294404b540aSrobert
3295404b540aSrobert(define_insn "*movsicc_lbs"
3296404b540aSrobert  [(set (match_operand:SI 0 "register_operand" "=r,r")
3297404b540aSrobert	(if_then_else:SI
3298404b540aSrobert	 (ne (zero_extract:DI (match_operand:DI 2 "reg_or_0_operand" "rJ,rJ")
3299404b540aSrobert			      (const_int 1)
3300404b540aSrobert			      (const_int 0))
3301404b540aSrobert	     (const_int 0))
3302404b540aSrobert	 (match_operand:SI 1 "reg_or_8bit_operand" "rI,0")
3303404b540aSrobert	 (match_operand:SI 3 "reg_or_8bit_operand" "0,rI")))]
3304404b540aSrobert  ""
3305404b540aSrobert  "@
3306404b540aSrobert   cmovlbs %r2,%1,%0
3307404b540aSrobert   cmovlbc %r2,%3,%0"
3308404b540aSrobert  [(set_attr "type" "icmov")])
3309404b540aSrobert
3310404b540aSrobert(define_insn "*movdicc_lbs"
3311404b540aSrobert  [(set (match_operand:DI 0 "register_operand" "=r,r")
3312404b540aSrobert	(if_then_else:DI
3313404b540aSrobert	 (ne (zero_extract:DI (match_operand:DI 2 "reg_or_0_operand" "rJ,rJ")
3314404b540aSrobert			      (const_int 1)
3315404b540aSrobert			      (const_int 0))
3316404b540aSrobert	     (const_int 0))
3317404b540aSrobert	 (match_operand:DI 1 "reg_or_8bit_operand" "rI,0")
3318404b540aSrobert	 (match_operand:DI 3 "reg_or_8bit_operand" "0,rI")))]
3319404b540aSrobert  ""
3320404b540aSrobert  "@
3321404b540aSrobert   cmovlbs %r2,%1,%0
3322404b540aSrobert   cmovlbc %r2,%3,%0"
3323404b540aSrobert  [(set_attr "type" "icmov")])
3324404b540aSrobert
3325404b540aSrobert;; For ABS, we have two choices, depending on whether the input and output
3326404b540aSrobert;; registers are the same or not.
3327404b540aSrobert(define_expand "absdi2"
3328404b540aSrobert  [(set (match_operand:DI 0 "register_operand" "")
3329404b540aSrobert	(abs:DI (match_operand:DI 1 "register_operand" "")))]
3330404b540aSrobert  ""
3331404b540aSrobert{
3332404b540aSrobert  if (rtx_equal_p (operands[0], operands[1]))
3333404b540aSrobert    emit_insn (gen_absdi2_same (operands[0], gen_reg_rtx (DImode)));
3334404b540aSrobert  else
3335404b540aSrobert    emit_insn (gen_absdi2_diff (operands[0], operands[1]));
3336404b540aSrobert  DONE;
3337404b540aSrobert})
3338404b540aSrobert
3339404b540aSrobert(define_expand "absdi2_same"
3340404b540aSrobert  [(set (match_operand:DI 1 "register_operand" "")
3341404b540aSrobert	(neg:DI (match_operand:DI 0 "register_operand" "")))
3342404b540aSrobert   (set (match_dup 0)
3343404b540aSrobert	(if_then_else:DI (ge (match_dup 0) (const_int 0))
3344404b540aSrobert			 (match_dup 0)
3345404b540aSrobert			 (match_dup 1)))]
3346404b540aSrobert  ""
3347404b540aSrobert  "")
3348404b540aSrobert
3349404b540aSrobert(define_expand "absdi2_diff"
3350404b540aSrobert  [(set (match_operand:DI 0 "register_operand" "")
3351404b540aSrobert	(neg:DI (match_operand:DI 1 "register_operand" "")))
3352404b540aSrobert   (set (match_dup 0)
3353404b540aSrobert	(if_then_else:DI (lt (match_dup 1) (const_int 0))
3354404b540aSrobert			 (match_dup 0)
3355404b540aSrobert			 (match_dup 1)))]
3356404b540aSrobert  ""
3357404b540aSrobert  "")
3358404b540aSrobert
3359404b540aSrobert(define_split
3360404b540aSrobert  [(set (match_operand:DI 0 "register_operand" "")
3361404b540aSrobert	(abs:DI (match_dup 0)))
3362404b540aSrobert   (clobber (match_operand:DI 1 "register_operand" ""))]
3363404b540aSrobert  ""
3364404b540aSrobert  [(set (match_dup 1) (neg:DI (match_dup 0)))
3365404b540aSrobert   (set (match_dup 0) (if_then_else:DI (ge (match_dup 0) (const_int 0))
3366404b540aSrobert				       (match_dup 0) (match_dup 1)))]
3367404b540aSrobert  "")
3368404b540aSrobert
3369404b540aSrobert(define_split
3370404b540aSrobert  [(set (match_operand:DI 0 "register_operand" "")
3371404b540aSrobert	(abs:DI (match_operand:DI 1 "register_operand" "")))]
3372404b540aSrobert  "! rtx_equal_p (operands[0], operands[1])"
3373404b540aSrobert  [(set (match_dup 0) (neg:DI (match_dup 1)))
3374404b540aSrobert   (set (match_dup 0) (if_then_else:DI (lt (match_dup 1) (const_int 0))
3375404b540aSrobert				       (match_dup 0) (match_dup 1)))]
3376404b540aSrobert  "")
3377404b540aSrobert
3378404b540aSrobert(define_split
3379404b540aSrobert  [(set (match_operand:DI 0 "register_operand" "")
3380404b540aSrobert	(neg:DI (abs:DI (match_dup 0))))
3381404b540aSrobert   (clobber (match_operand:DI 1 "register_operand" ""))]
3382404b540aSrobert  ""
3383404b540aSrobert  [(set (match_dup 1) (neg:DI (match_dup 0)))
3384404b540aSrobert   (set (match_dup 0) (if_then_else:DI (le (match_dup 0) (const_int 0))
3385404b540aSrobert				       (match_dup 0) (match_dup 1)))]
3386404b540aSrobert  "")
3387404b540aSrobert
3388404b540aSrobert(define_split
3389404b540aSrobert  [(set (match_operand:DI 0 "register_operand" "")
3390404b540aSrobert	(neg:DI (abs:DI (match_operand:DI 1 "register_operand" ""))))]
3391404b540aSrobert  "! rtx_equal_p (operands[0], operands[1])"
3392404b540aSrobert  [(set (match_dup 0) (neg:DI (match_dup 1)))
3393404b540aSrobert   (set (match_dup 0) (if_then_else:DI (gt (match_dup 1) (const_int 0))
3394404b540aSrobert				       (match_dup 0) (match_dup 1)))]
3395404b540aSrobert  "")
3396404b540aSrobert
3397404b540aSrobert(define_insn "sminqi3"
3398404b540aSrobert  [(set (match_operand:QI 0 "register_operand" "=r")
3399404b540aSrobert	(smin:QI (match_operand:QI 1 "reg_or_0_operand" "%rJ")
3400404b540aSrobert		 (match_operand:QI 2 "reg_or_8bit_operand" "rI")))]
3401404b540aSrobert  "TARGET_MAX"
3402404b540aSrobert  "minsb8 %r1,%2,%0"
3403404b540aSrobert  [(set_attr "type" "mvi")])
3404404b540aSrobert
3405404b540aSrobert(define_insn "uminqi3"
3406404b540aSrobert  [(set (match_operand:QI 0 "register_operand" "=r")
3407404b540aSrobert	(umin:QI (match_operand:QI 1 "reg_or_0_operand" "%rJ")
3408404b540aSrobert		 (match_operand:QI 2 "reg_or_8bit_operand" "rI")))]
3409404b540aSrobert  "TARGET_MAX"
3410404b540aSrobert  "minub8 %r1,%2,%0"
3411404b540aSrobert  [(set_attr "type" "mvi")])
3412404b540aSrobert
3413404b540aSrobert(define_insn "smaxqi3"
3414404b540aSrobert  [(set (match_operand:QI 0 "register_operand" "=r")
3415404b540aSrobert	(smax:QI (match_operand:QI 1 "reg_or_0_operand" "%rJ")
3416404b540aSrobert		 (match_operand:QI 2 "reg_or_8bit_operand" "rI")))]
3417404b540aSrobert  "TARGET_MAX"
3418404b540aSrobert  "maxsb8 %r1,%2,%0"
3419404b540aSrobert  [(set_attr "type" "mvi")])
3420404b540aSrobert
3421404b540aSrobert(define_insn "umaxqi3"
3422404b540aSrobert  [(set (match_operand:QI 0 "register_operand" "=r")
3423404b540aSrobert	(umax:QI (match_operand:QI 1 "reg_or_0_operand" "%rJ")
3424404b540aSrobert		 (match_operand:QI 2 "reg_or_8bit_operand" "rI")))]
3425404b540aSrobert  "TARGET_MAX"
3426404b540aSrobert  "maxub8 %r1,%2,%0"
3427404b540aSrobert  [(set_attr "type" "mvi")])
3428404b540aSrobert
3429404b540aSrobert(define_insn "sminhi3"
3430404b540aSrobert  [(set (match_operand:HI 0 "register_operand" "=r")
3431404b540aSrobert	(smin:HI (match_operand:HI 1 "reg_or_0_operand" "%rJ")
3432404b540aSrobert		 (match_operand:HI 2 "reg_or_8bit_operand" "rI")))]
3433404b540aSrobert  "TARGET_MAX"
3434404b540aSrobert  "minsw4 %r1,%2,%0"
3435404b540aSrobert  [(set_attr "type" "mvi")])
3436404b540aSrobert
3437404b540aSrobert(define_insn "uminhi3"
3438404b540aSrobert  [(set (match_operand:HI 0 "register_operand" "=r")
3439404b540aSrobert	(umin:HI (match_operand:HI 1 "reg_or_0_operand" "%rJ")
3440404b540aSrobert		 (match_operand:HI 2 "reg_or_8bit_operand" "rI")))]
3441404b540aSrobert  "TARGET_MAX"
3442404b540aSrobert  "minuw4 %r1,%2,%0"
3443404b540aSrobert  [(set_attr "type" "mvi")])
3444404b540aSrobert
3445404b540aSrobert(define_insn "smaxhi3"
3446404b540aSrobert  [(set (match_operand:HI 0 "register_operand" "=r")
3447404b540aSrobert	(smax:HI (match_operand:HI 1 "reg_or_0_operand" "%rJ")
3448404b540aSrobert		 (match_operand:HI 2 "reg_or_8bit_operand" "rI")))]
3449404b540aSrobert  "TARGET_MAX"
3450404b540aSrobert  "maxsw4 %r1,%2,%0"
3451404b540aSrobert  [(set_attr "type" "mvi")])
3452404b540aSrobert
3453404b540aSrobert(define_insn "umaxhi3"
3454404b540aSrobert  [(set (match_operand:HI 0 "register_operand" "=r")
3455404b540aSrobert	(umax:HI (match_operand:HI 1 "reg_or_0_operand" "%rJ")
3456404b540aSrobert		 (match_operand:HI 2 "reg_or_8bit_operand" "rI")))]
3457404b540aSrobert  "TARGET_MAX"
3458404b540aSrobert  "maxuw4 %r1,%2,%0"
3459404b540aSrobert  [(set_attr "type" "mvi")])
3460404b540aSrobert
3461404b540aSrobert(define_expand "smaxdi3"
3462404b540aSrobert  [(set (match_dup 3)
3463404b540aSrobert	(le:DI (match_operand:DI 1 "reg_or_0_operand" "")
3464404b540aSrobert	       (match_operand:DI 2 "reg_or_8bit_operand" "")))
3465404b540aSrobert   (set (match_operand:DI 0 "register_operand" "")
3466404b540aSrobert	(if_then_else:DI (eq (match_dup 3) (const_int 0))
3467404b540aSrobert			 (match_dup 1) (match_dup 2)))]
3468404b540aSrobert  ""
3469404b540aSrobert  { operands[3] = gen_reg_rtx (DImode); })
3470404b540aSrobert
3471404b540aSrobert(define_split
3472404b540aSrobert  [(set (match_operand:DI 0 "register_operand" "")
3473404b540aSrobert	(smax:DI (match_operand:DI 1 "reg_or_0_operand" "")
3474404b540aSrobert		 (match_operand:DI 2 "reg_or_8bit_operand" "")))
3475404b540aSrobert   (clobber (match_operand:DI 3 "register_operand" ""))]
3476404b540aSrobert  "operands[2] != const0_rtx"
3477404b540aSrobert  [(set (match_dup 3) (le:DI (match_dup 1) (match_dup 2)))
3478404b540aSrobert   (set (match_dup 0) (if_then_else:DI (eq (match_dup 3) (const_int 0))
3479404b540aSrobert				       (match_dup 1) (match_dup 2)))]
3480404b540aSrobert  "")
3481404b540aSrobert
3482404b540aSrobert(define_insn "*smax_const0"
3483404b540aSrobert  [(set (match_operand:DI 0 "register_operand" "=r")
3484404b540aSrobert	(smax:DI (match_operand:DI 1 "register_operand" "0")
3485404b540aSrobert		 (const_int 0)))]
3486404b540aSrobert  ""
3487404b540aSrobert  "cmovlt %0,0,%0"
3488404b540aSrobert  [(set_attr "type" "icmov")])
3489404b540aSrobert
3490404b540aSrobert(define_expand "smindi3"
3491404b540aSrobert  [(set (match_dup 3)
3492404b540aSrobert	(lt:DI (match_operand:DI 1 "reg_or_0_operand" "")
3493404b540aSrobert	       (match_operand:DI 2 "reg_or_8bit_operand" "")))
3494404b540aSrobert   (set (match_operand:DI 0 "register_operand" "")
3495404b540aSrobert	(if_then_else:DI (ne (match_dup 3) (const_int 0))
3496404b540aSrobert			 (match_dup 1) (match_dup 2)))]
3497404b540aSrobert  ""
3498404b540aSrobert  { operands[3] = gen_reg_rtx (DImode); })
3499404b540aSrobert
3500404b540aSrobert(define_split
3501404b540aSrobert  [(set (match_operand:DI 0 "register_operand" "")
3502404b540aSrobert	(smin:DI (match_operand:DI 1 "reg_or_0_operand" "")
3503404b540aSrobert		 (match_operand:DI 2 "reg_or_8bit_operand" "")))
3504404b540aSrobert   (clobber (match_operand:DI 3 "register_operand" ""))]
3505404b540aSrobert  "operands[2] != const0_rtx"
3506404b540aSrobert  [(set (match_dup 3) (lt:DI (match_dup 1) (match_dup 2)))
3507404b540aSrobert   (set (match_dup 0) (if_then_else:DI (ne (match_dup 3) (const_int 0))
3508404b540aSrobert				       (match_dup 1) (match_dup 2)))]
3509404b540aSrobert  "")
3510404b540aSrobert
3511404b540aSrobert(define_insn "*smin_const0"
3512404b540aSrobert  [(set (match_operand:DI 0 "register_operand" "=r")
3513404b540aSrobert	(smin:DI (match_operand:DI 1 "register_operand" "0")
3514404b540aSrobert		 (const_int 0)))]
3515404b540aSrobert  ""
3516404b540aSrobert  "cmovgt %0,0,%0"
3517404b540aSrobert  [(set_attr "type" "icmov")])
3518404b540aSrobert
3519404b540aSrobert(define_expand "umaxdi3"
3520404b540aSrobert  [(set (match_dup 3)
3521404b540aSrobert	(leu:DI (match_operand:DI 1 "reg_or_0_operand" "")
3522404b540aSrobert		(match_operand:DI 2 "reg_or_8bit_operand" "")))
3523404b540aSrobert   (set (match_operand:DI 0 "register_operand" "")
3524404b540aSrobert	(if_then_else:DI (eq (match_dup 3) (const_int 0))
3525404b540aSrobert			 (match_dup 1) (match_dup 2)))]
3526404b540aSrobert  ""
3527404b540aSrobert  "operands[3] = gen_reg_rtx (DImode);")
3528404b540aSrobert
3529404b540aSrobert(define_split
3530404b540aSrobert  [(set (match_operand:DI 0 "register_operand" "")
3531404b540aSrobert	(umax:DI (match_operand:DI 1 "reg_or_0_operand" "")
3532404b540aSrobert		 (match_operand:DI 2 "reg_or_8bit_operand" "")))
3533404b540aSrobert   (clobber (match_operand:DI 3 "register_operand" ""))]
3534404b540aSrobert  "operands[2] != const0_rtx"
3535404b540aSrobert  [(set (match_dup 3) (leu:DI (match_dup 1) (match_dup 2)))
3536404b540aSrobert   (set (match_dup 0) (if_then_else:DI (eq (match_dup 3) (const_int 0))
3537404b540aSrobert				       (match_dup 1) (match_dup 2)))]
3538404b540aSrobert  "")
3539404b540aSrobert
3540404b540aSrobert(define_expand "umindi3"
3541404b540aSrobert  [(set (match_dup 3)
3542404b540aSrobert	(ltu:DI (match_operand:DI 1 "reg_or_0_operand" "")
3543404b540aSrobert		(match_operand:DI 2 "reg_or_8bit_operand" "")))
3544404b540aSrobert   (set (match_operand:DI 0 "register_operand" "")
3545404b540aSrobert	(if_then_else:DI (ne (match_dup 3) (const_int 0))
3546404b540aSrobert			 (match_dup 1) (match_dup 2)))]
3547404b540aSrobert  ""
3548404b540aSrobert  "operands[3] = gen_reg_rtx (DImode);")
3549404b540aSrobert
3550404b540aSrobert(define_split
3551404b540aSrobert  [(set (match_operand:DI 0 "register_operand" "")
3552404b540aSrobert	(umin:DI (match_operand:DI 1 "reg_or_0_operand" "")
3553404b540aSrobert		 (match_operand:DI 2 "reg_or_8bit_operand" "")))
3554404b540aSrobert   (clobber (match_operand:DI 3 "register_operand" ""))]
3555404b540aSrobert  "operands[2] != const0_rtx"
3556404b540aSrobert  [(set (match_dup 3) (ltu:DI (match_dup 1) (match_dup 2)))
3557404b540aSrobert   (set (match_dup 0) (if_then_else:DI (ne (match_dup 3) (const_int 0))
3558404b540aSrobert				       (match_dup 1) (match_dup 2)))]
3559404b540aSrobert  "")
3560404b540aSrobert
3561404b540aSrobert(define_insn "*bcc_normal"
3562404b540aSrobert  [(set (pc)
3563404b540aSrobert	(if_then_else
3564404b540aSrobert	 (match_operator 1 "signed_comparison_operator"
3565404b540aSrobert			 [(match_operand:DI 2 "reg_or_0_operand" "rJ")
3566404b540aSrobert			  (const_int 0)])
3567404b540aSrobert	 (label_ref (match_operand 0 "" ""))
3568404b540aSrobert	 (pc)))]
3569404b540aSrobert  ""
3570404b540aSrobert  "b%C1 %r2,%0"
3571404b540aSrobert  [(set_attr "type" "ibr")])
3572404b540aSrobert
3573404b540aSrobert(define_insn "*bcc_reverse"
3574404b540aSrobert  [(set (pc)
3575404b540aSrobert	(if_then_else
3576404b540aSrobert	 (match_operator 1 "signed_comparison_operator"
3577404b540aSrobert			 [(match_operand:DI 2 "register_operand" "r")
3578404b540aSrobert			  (const_int 0)])
3579404b540aSrobert
3580404b540aSrobert	 (pc)
3581404b540aSrobert	 (label_ref (match_operand 0 "" ""))))]
3582404b540aSrobert  ""
3583404b540aSrobert  "b%c1 %2,%0"
3584404b540aSrobert  [(set_attr "type" "ibr")])
3585404b540aSrobert
3586404b540aSrobert(define_insn "*blbs_normal"
3587404b540aSrobert  [(set (pc)
3588404b540aSrobert	(if_then_else
3589404b540aSrobert	 (ne (zero_extract:DI (match_operand:DI 1 "reg_or_0_operand" "rJ")
3590404b540aSrobert			      (const_int 1)
3591404b540aSrobert			      (const_int 0))
3592404b540aSrobert	     (const_int 0))
3593404b540aSrobert	 (label_ref (match_operand 0 "" ""))
3594404b540aSrobert	 (pc)))]
3595404b540aSrobert  ""
3596404b540aSrobert  "blbs %r1,%0"
3597404b540aSrobert  [(set_attr "type" "ibr")])
3598404b540aSrobert
3599404b540aSrobert(define_insn "*blbc_normal"
3600404b540aSrobert  [(set (pc)
3601404b540aSrobert	(if_then_else
3602404b540aSrobert	 (eq (zero_extract:DI (match_operand:DI 1 "reg_or_0_operand" "rJ")
3603404b540aSrobert			      (const_int 1)
3604404b540aSrobert			      (const_int 0))
3605404b540aSrobert	     (const_int 0))
3606404b540aSrobert	 (label_ref (match_operand 0 "" ""))
3607404b540aSrobert	 (pc)))]
3608404b540aSrobert  ""
3609404b540aSrobert  "blbc %r1,%0"
3610404b540aSrobert  [(set_attr "type" "ibr")])
3611404b540aSrobert
3612404b540aSrobert(define_split
3613404b540aSrobert  [(parallel
3614404b540aSrobert    [(set (pc)
3615404b540aSrobert	  (if_then_else
3616404b540aSrobert	   (match_operator 1 "comparison_operator"
3617404b540aSrobert			   [(zero_extract:DI (match_operand:DI 2 "register_operand" "")
3618404b540aSrobert					     (const_int 1)
3619404b540aSrobert					     (match_operand:DI 3 "const_int_operand" ""))
3620404b540aSrobert			    (const_int 0)])
3621404b540aSrobert	   (label_ref (match_operand 0 "" ""))
3622404b540aSrobert	   (pc)))
3623404b540aSrobert     (clobber (match_operand:DI 4 "register_operand" ""))])]
3624404b540aSrobert  "INTVAL (operands[3]) != 0"
3625404b540aSrobert  [(set (match_dup 4)
3626404b540aSrobert	(lshiftrt:DI (match_dup 2) (match_dup 3)))
3627404b540aSrobert   (set (pc)
3628404b540aSrobert	(if_then_else (match_op_dup 1
3629404b540aSrobert				    [(zero_extract:DI (match_dup 4)
3630404b540aSrobert						      (const_int 1)
3631404b540aSrobert						      (const_int 0))
3632404b540aSrobert				     (const_int 0)])
3633404b540aSrobert		      (label_ref (match_dup 0))
3634404b540aSrobert		      (pc)))]
3635404b540aSrobert  "")
3636404b540aSrobert
3637404b540aSrobert;; The following are the corresponding floating-point insns.  Recall
3638404b540aSrobert;; we need to have variants that expand the arguments from SFmode
3639404b540aSrobert;; to DFmode.
3640404b540aSrobert
3641404b540aSrobert(define_insn "*cmpdf_ieee"
3642404b540aSrobert  [(set (match_operand:DF 0 "register_operand" "=&f")
3643404b540aSrobert	(match_operator:DF 1 "alpha_fp_comparison_operator"
3644404b540aSrobert			   [(match_operand:DF 2 "reg_or_0_operand" "fG")
3645404b540aSrobert			    (match_operand:DF 3 "reg_or_0_operand" "fG")]))]
3646404b540aSrobert  "TARGET_FP && alpha_fptm >= ALPHA_FPTM_SU"
3647404b540aSrobert  "cmp%-%C1%/ %R2,%R3,%0"
3648404b540aSrobert  [(set_attr "type" "fadd")
3649404b540aSrobert   (set_attr "trap" "yes")
3650404b540aSrobert   (set_attr "trap_suffix" "su")])
3651404b540aSrobert
3652404b540aSrobert(define_insn "*cmpdf_internal"
3653404b540aSrobert  [(set (match_operand:DF 0 "register_operand" "=f")
3654404b540aSrobert	(match_operator:DF 1 "alpha_fp_comparison_operator"
3655404b540aSrobert			   [(match_operand:DF 2 "reg_or_0_operand" "fG")
3656404b540aSrobert			    (match_operand:DF 3 "reg_or_0_operand" "fG")]))]
3657404b540aSrobert  "TARGET_FP && alpha_fptm < ALPHA_FPTM_SU"
3658404b540aSrobert  "cmp%-%C1%/ %R2,%R3,%0"
3659404b540aSrobert  [(set_attr "type" "fadd")
3660404b540aSrobert   (set_attr "trap" "yes")
3661404b540aSrobert   (set_attr "trap_suffix" "su")])
3662404b540aSrobert
3663404b540aSrobert(define_insn "*cmpdf_ieee_ext1"
3664404b540aSrobert  [(set (match_operand:DF 0 "register_operand" "=&f")
3665404b540aSrobert	(match_operator:DF 1 "alpha_fp_comparison_operator"
3666404b540aSrobert			   [(float_extend:DF
3667404b540aSrobert			     (match_operand:SF 2 "reg_or_0_operand" "fG"))
3668404b540aSrobert			    (match_operand:DF 3 "reg_or_0_operand" "fG")]))]
3669404b540aSrobert  "TARGET_FP && alpha_fptm >= ALPHA_FPTM_SU"
3670404b540aSrobert  "cmp%-%C1%/ %R2,%R3,%0"
3671404b540aSrobert  [(set_attr "type" "fadd")
3672404b540aSrobert   (set_attr "trap" "yes")
3673404b540aSrobert   (set_attr "trap_suffix" "su")])
3674404b540aSrobert
3675404b540aSrobert(define_insn "*cmpdf_ext1"
3676404b540aSrobert  [(set (match_operand:DF 0 "register_operand" "=f")
3677404b540aSrobert	(match_operator:DF 1 "alpha_fp_comparison_operator"
3678404b540aSrobert			   [(float_extend:DF
3679404b540aSrobert			     (match_operand:SF 2 "reg_or_0_operand" "fG"))
3680404b540aSrobert			    (match_operand:DF 3 "reg_or_0_operand" "fG")]))]
3681404b540aSrobert  "TARGET_FP && alpha_fptm < ALPHA_FPTM_SU"
3682404b540aSrobert  "cmp%-%C1%/ %R2,%R3,%0"
3683404b540aSrobert  [(set_attr "type" "fadd")
3684404b540aSrobert   (set_attr "trap" "yes")
3685404b540aSrobert   (set_attr "trap_suffix" "su")])
3686404b540aSrobert
3687404b540aSrobert(define_insn "*cmpdf_ieee_ext2"
3688404b540aSrobert  [(set (match_operand:DF 0 "register_operand" "=&f")
3689404b540aSrobert	(match_operator:DF 1 "alpha_fp_comparison_operator"
3690404b540aSrobert			   [(match_operand:DF 2 "reg_or_0_operand" "fG")
3691404b540aSrobert			    (float_extend:DF
3692404b540aSrobert			     (match_operand:SF 3 "reg_or_0_operand" "fG"))]))]
3693404b540aSrobert  "TARGET_FP && alpha_fptm >= ALPHA_FPTM_SU"
3694404b540aSrobert  "cmp%-%C1%/ %R2,%R3,%0"
3695404b540aSrobert  [(set_attr "type" "fadd")
3696404b540aSrobert   (set_attr "trap" "yes")
3697404b540aSrobert   (set_attr "trap_suffix" "su")])
3698404b540aSrobert
3699404b540aSrobert(define_insn "*cmpdf_ext2"
3700404b540aSrobert  [(set (match_operand:DF 0 "register_operand" "=f")
3701404b540aSrobert	(match_operator:DF 1 "alpha_fp_comparison_operator"
3702404b540aSrobert			   [(match_operand:DF 2 "reg_or_0_operand" "fG")
3703404b540aSrobert			    (float_extend:DF
3704404b540aSrobert			     (match_operand:SF 3 "reg_or_0_operand" "fG"))]))]
3705404b540aSrobert  "TARGET_FP && alpha_fptm < ALPHA_FPTM_SU"
3706404b540aSrobert  "cmp%-%C1%/ %R2,%R3,%0"
3707404b540aSrobert  [(set_attr "type" "fadd")
3708404b540aSrobert   (set_attr "trap" "yes")
3709404b540aSrobert   (set_attr "trap_suffix" "su")])
3710404b540aSrobert
3711404b540aSrobert(define_insn "*cmpdf_ieee_ext3"
3712404b540aSrobert  [(set (match_operand:DF 0 "register_operand" "=&f")
3713404b540aSrobert	(match_operator:DF 1 "alpha_fp_comparison_operator"
3714404b540aSrobert			   [(float_extend:DF
3715404b540aSrobert			     (match_operand:SF 2 "reg_or_0_operand" "fG"))
3716404b540aSrobert			    (float_extend:DF
3717404b540aSrobert			     (match_operand:SF 3 "reg_or_0_operand" "fG"))]))]
3718404b540aSrobert  "TARGET_FP && alpha_fptm >= ALPHA_FPTM_SU"
3719404b540aSrobert  "cmp%-%C1%/ %R2,%R3,%0"
3720404b540aSrobert  [(set_attr "type" "fadd")
3721404b540aSrobert   (set_attr "trap" "yes")
3722404b540aSrobert   (set_attr "trap_suffix" "su")])
3723404b540aSrobert
3724404b540aSrobert(define_insn "*cmpdf_ext3"
3725404b540aSrobert  [(set (match_operand:DF 0 "register_operand" "=f")
3726404b540aSrobert	(match_operator:DF 1 "alpha_fp_comparison_operator"
3727404b540aSrobert			   [(float_extend:DF
3728404b540aSrobert			     (match_operand:SF 2 "reg_or_0_operand" "fG"))
3729404b540aSrobert			    (float_extend:DF
3730404b540aSrobert			     (match_operand:SF 3 "reg_or_0_operand" "fG"))]))]
3731404b540aSrobert  "TARGET_FP && alpha_fptm < ALPHA_FPTM_SU"
3732404b540aSrobert  "cmp%-%C1%/ %R2,%R3,%0"
3733404b540aSrobert  [(set_attr "type" "fadd")
3734404b540aSrobert   (set_attr "trap" "yes")
3735404b540aSrobert   (set_attr "trap_suffix" "su")])
3736404b540aSrobert
3737404b540aSrobert(define_insn "*movdfcc_internal"
3738404b540aSrobert  [(set (match_operand:DF 0 "register_operand" "=f,f")
3739404b540aSrobert	(if_then_else:DF
3740404b540aSrobert	 (match_operator 3 "signed_comparison_operator"
3741404b540aSrobert			 [(match_operand:DF 4 "reg_or_0_operand" "fG,fG")
3742404b540aSrobert			  (match_operand:DF 2 "const0_operand" "G,G")])
3743404b540aSrobert	 (match_operand:DF 1 "reg_or_0_operand" "fG,0")
3744404b540aSrobert	 (match_operand:DF 5 "reg_or_0_operand" "0,fG")))]
3745404b540aSrobert  "TARGET_FP"
3746404b540aSrobert  "@
3747404b540aSrobert   fcmov%C3 %R4,%R1,%0
3748404b540aSrobert   fcmov%D3 %R4,%R5,%0"
3749404b540aSrobert  [(set_attr "type" "fcmov")])
3750404b540aSrobert
3751404b540aSrobert(define_insn "*movsfcc_internal"
3752404b540aSrobert  [(set (match_operand:SF 0 "register_operand" "=f,f")
3753404b540aSrobert	(if_then_else:SF
3754404b540aSrobert	 (match_operator 3 "signed_comparison_operator"
3755404b540aSrobert			 [(match_operand:DF 4 "reg_or_0_operand" "fG,fG")
3756404b540aSrobert			  (match_operand:DF 2 "const0_operand" "G,G")])
3757404b540aSrobert	 (match_operand:SF 1 "reg_or_0_operand" "fG,0")
3758404b540aSrobert	 (match_operand:SF 5 "reg_or_0_operand" "0,fG")))]
3759404b540aSrobert  "TARGET_FP"
3760404b540aSrobert  "@
3761404b540aSrobert   fcmov%C3 %R4,%R1,%0
3762404b540aSrobert   fcmov%D3 %R4,%R5,%0"
3763404b540aSrobert  [(set_attr "type" "fcmov")])
3764404b540aSrobert
3765404b540aSrobert(define_insn "*movdfcc_ext1"
3766404b540aSrobert  [(set (match_operand:DF 0 "register_operand" "=f,f")
3767404b540aSrobert	(if_then_else:DF
3768404b540aSrobert	 (match_operator 3 "signed_comparison_operator"
3769404b540aSrobert			 [(match_operand:DF 4 "reg_or_0_operand" "fG,fG")
3770404b540aSrobert			  (match_operand:DF 2 "const0_operand" "G,G")])
3771404b540aSrobert	 (float_extend:DF (match_operand:SF 1 "reg_or_0_operand" "fG,0"))
3772404b540aSrobert	 (match_operand:DF 5 "reg_or_0_operand" "0,fG")))]
3773404b540aSrobert  "TARGET_FP"
3774404b540aSrobert  "@
3775404b540aSrobert   fcmov%C3 %R4,%R1,%0
3776404b540aSrobert   fcmov%D3 %R4,%R5,%0"
3777404b540aSrobert  [(set_attr "type" "fcmov")])
3778404b540aSrobert
3779404b540aSrobert(define_insn "*movdfcc_ext2"
3780404b540aSrobert  [(set (match_operand:DF 0 "register_operand" "=f,f")
3781404b540aSrobert	(if_then_else:DF
3782404b540aSrobert	 (match_operator 3 "signed_comparison_operator"
3783404b540aSrobert			 [(float_extend:DF
3784404b540aSrobert			   (match_operand:SF 4 "reg_or_0_operand" "fG,fG"))
3785404b540aSrobert			  (match_operand:DF 2 "const0_operand" "G,G")])
3786404b540aSrobert	 (match_operand:DF 1 "reg_or_0_operand" "fG,0")
3787404b540aSrobert	 (match_operand:DF 5 "reg_or_0_operand" "0,fG")))]
3788404b540aSrobert  "TARGET_FP"
3789404b540aSrobert  "@
3790404b540aSrobert   fcmov%C3 %R4,%R1,%0
3791404b540aSrobert   fcmov%D3 %R4,%R5,%0"
3792404b540aSrobert  [(set_attr "type" "fcmov")])
3793404b540aSrobert
3794404b540aSrobert(define_insn "*movdfcc_ext3"
3795404b540aSrobert  [(set (match_operand:SF 0 "register_operand" "=f,f")
3796404b540aSrobert	(if_then_else:SF
3797404b540aSrobert	 (match_operator 3 "signed_comparison_operator"
3798404b540aSrobert			 [(float_extend:DF
3799404b540aSrobert			   (match_operand:SF 4 "reg_or_0_operand" "fG,fG"))
3800404b540aSrobert			  (match_operand:DF 2 "const0_operand" "G,G")])
3801404b540aSrobert	 (match_operand:SF 1 "reg_or_0_operand" "fG,0")
3802404b540aSrobert	 (match_operand:SF 5 "reg_or_0_operand" "0,fG")))]
3803404b540aSrobert  "TARGET_FP"
3804404b540aSrobert  "@
3805404b540aSrobert   fcmov%C3 %R4,%R1,%0
3806404b540aSrobert   fcmov%D3 %R4,%R5,%0"
3807404b540aSrobert  [(set_attr "type" "fcmov")])
3808404b540aSrobert
3809404b540aSrobert(define_insn "*movdfcc_ext4"
3810404b540aSrobert  [(set (match_operand:DF 0 "register_operand" "=f,f")
3811404b540aSrobert	(if_then_else:DF
3812404b540aSrobert	 (match_operator 3 "signed_comparison_operator"
3813404b540aSrobert			 [(float_extend:DF
3814404b540aSrobert			   (match_operand:SF 4 "reg_or_0_operand" "fG,fG"))
3815404b540aSrobert			  (match_operand:DF 2 "const0_operand" "G,G")])
3816404b540aSrobert	 (float_extend:DF (match_operand:SF 1 "reg_or_0_operand" "fG,0"))
3817404b540aSrobert	 (match_operand:DF 5 "reg_or_0_operand" "0,fG")))]
3818404b540aSrobert  "TARGET_FP"
3819404b540aSrobert  "@
3820404b540aSrobert   fcmov%C3 %R4,%R1,%0
3821404b540aSrobert   fcmov%D3 %R4,%R5,%0"
3822404b540aSrobert  [(set_attr "type" "fcmov")])
3823404b540aSrobert
3824404b540aSrobert(define_expand "smaxdf3"
3825404b540aSrobert  [(set (match_dup 3)
3826404b540aSrobert	(le:DF (match_operand:DF 1 "reg_or_0_operand" "")
3827404b540aSrobert	       (match_operand:DF 2 "reg_or_0_operand" "")))
3828404b540aSrobert   (set (match_operand:DF 0 "register_operand" "")
3829404b540aSrobert	(if_then_else:DF (eq (match_dup 3) (match_dup 4))
3830404b540aSrobert			 (match_dup 1) (match_dup 2)))]
3831404b540aSrobert  "TARGET_FP"
3832404b540aSrobert{
3833404b540aSrobert  operands[3] = gen_reg_rtx (DFmode);
3834404b540aSrobert  operands[4] = CONST0_RTX (DFmode);
3835404b540aSrobert})
3836404b540aSrobert
3837404b540aSrobert(define_expand "smindf3"
3838404b540aSrobert  [(set (match_dup 3)
3839404b540aSrobert	(lt:DF (match_operand:DF 1 "reg_or_0_operand" "")
3840404b540aSrobert	       (match_operand:DF 2 "reg_or_0_operand" "")))
3841404b540aSrobert   (set (match_operand:DF 0 "register_operand" "")
3842404b540aSrobert	(if_then_else:DF (ne (match_dup 3) (match_dup 4))
3843404b540aSrobert			 (match_dup 1) (match_dup 2)))]
3844404b540aSrobert  "TARGET_FP"
3845404b540aSrobert{
3846404b540aSrobert  operands[3] = gen_reg_rtx (DFmode);
3847404b540aSrobert  operands[4] = CONST0_RTX (DFmode);
3848404b540aSrobert})
3849404b540aSrobert
3850404b540aSrobert(define_expand "smaxsf3"
3851404b540aSrobert  [(set (match_dup 3)
3852404b540aSrobert	(le:DF (float_extend:DF (match_operand:SF 1 "reg_or_0_operand" ""))
3853404b540aSrobert	       (float_extend:DF (match_operand:SF 2 "reg_or_0_operand" ""))))
3854404b540aSrobert   (set (match_operand:SF 0 "register_operand" "")
3855404b540aSrobert	(if_then_else:SF (eq (match_dup 3) (match_dup 4))
3856404b540aSrobert			 (match_dup 1) (match_dup 2)))]
3857404b540aSrobert  "TARGET_FP"
3858404b540aSrobert{
3859404b540aSrobert  operands[3] = gen_reg_rtx (DFmode);
3860404b540aSrobert  operands[4] = CONST0_RTX (DFmode);
3861404b540aSrobert})
3862404b540aSrobert
3863404b540aSrobert(define_expand "sminsf3"
3864404b540aSrobert  [(set (match_dup 3)
3865404b540aSrobert	(lt:DF (float_extend:DF (match_operand:SF 1 "reg_or_0_operand" ""))
3866404b540aSrobert	       (float_extend:DF (match_operand:SF 2 "reg_or_0_operand" ""))))
3867404b540aSrobert   (set (match_operand:SF 0 "register_operand" "")
3868404b540aSrobert	(if_then_else:SF (ne (match_dup 3) (match_dup 4))
3869404b540aSrobert		      (match_dup 1) (match_dup 2)))]
3870404b540aSrobert  "TARGET_FP"
3871404b540aSrobert{
3872404b540aSrobert  operands[3] = gen_reg_rtx (DFmode);
3873404b540aSrobert  operands[4] = CONST0_RTX (DFmode);
3874404b540aSrobert})
3875404b540aSrobert
3876404b540aSrobert(define_insn "*fbcc_normal"
3877404b540aSrobert  [(set (pc)
3878404b540aSrobert	(if_then_else
3879404b540aSrobert	 (match_operator 1 "signed_comparison_operator"
3880404b540aSrobert			 [(match_operand:DF 2 "reg_or_0_operand" "fG")
3881404b540aSrobert			  (match_operand:DF 3 "const0_operand" "G")])
3882404b540aSrobert	 (label_ref (match_operand 0 "" ""))
3883404b540aSrobert	 (pc)))]
3884404b540aSrobert  "TARGET_FP"
3885404b540aSrobert  "fb%C1 %R2,%0"
3886404b540aSrobert  [(set_attr "type" "fbr")])
3887404b540aSrobert
3888404b540aSrobert(define_insn "*fbcc_ext_normal"
3889404b540aSrobert  [(set (pc)
3890404b540aSrobert	(if_then_else
3891404b540aSrobert	 (match_operator 1 "signed_comparison_operator"
3892404b540aSrobert			 [(float_extend:DF
3893404b540aSrobert			   (match_operand:SF 2 "reg_or_0_operand" "fG"))
3894404b540aSrobert			  (match_operand:DF 3 "const0_operand" "G")])
3895404b540aSrobert	 (label_ref (match_operand 0 "" ""))
3896404b540aSrobert	 (pc)))]
3897404b540aSrobert  "TARGET_FP"
3898404b540aSrobert  "fb%C1 %R2,%0"
3899404b540aSrobert  [(set_attr "type" "fbr")])
3900404b540aSrobert
3901404b540aSrobert;; These are the main define_expand's used to make conditional branches
3902404b540aSrobert;; and compares.
3903404b540aSrobert
3904404b540aSrobert(define_expand "cmpdf"
3905404b540aSrobert  [(set (cc0) (compare (match_operand:DF 0 "reg_or_0_operand" "")
3906404b540aSrobert		       (match_operand:DF 1 "reg_or_0_operand" "")))]
3907404b540aSrobert  "TARGET_FP"
3908404b540aSrobert{
3909404b540aSrobert  alpha_compare.op0 = operands[0];
3910404b540aSrobert  alpha_compare.op1 = operands[1];
3911404b540aSrobert  alpha_compare.fp_p = 1;
3912404b540aSrobert  DONE;
3913404b540aSrobert})
3914404b540aSrobert
3915404b540aSrobert(define_expand "cmptf"
3916404b540aSrobert  [(set (cc0) (compare (match_operand:TF 0 "general_operand" "")
3917404b540aSrobert		       (match_operand:TF 1 "general_operand" "")))]
3918404b540aSrobert  "TARGET_HAS_XFLOATING_LIBS"
3919404b540aSrobert{
3920404b540aSrobert  alpha_compare.op0 = operands[0];
3921404b540aSrobert  alpha_compare.op1 = operands[1];
3922404b540aSrobert  alpha_compare.fp_p = 1;
3923404b540aSrobert  DONE;
3924404b540aSrobert})
3925404b540aSrobert
3926404b540aSrobert(define_expand "cmpdi"
3927404b540aSrobert  [(set (cc0) (compare (match_operand:DI 0 "some_operand" "")
3928404b540aSrobert		       (match_operand:DI 1 "some_operand" "")))]
3929404b540aSrobert  ""
3930404b540aSrobert{
3931404b540aSrobert  alpha_compare.op0 = operands[0];
3932404b540aSrobert  alpha_compare.op1 = operands[1];
3933404b540aSrobert  alpha_compare.fp_p = 0;
3934404b540aSrobert  DONE;
3935404b540aSrobert})
3936404b540aSrobert
3937404b540aSrobert(define_expand "beq"
3938404b540aSrobert  [(set (pc)
3939404b540aSrobert	(if_then_else (match_dup 1)
3940404b540aSrobert		      (label_ref (match_operand 0 "" ""))
3941404b540aSrobert		      (pc)))]
3942404b540aSrobert  ""
3943404b540aSrobert  "{ operands[1] = alpha_emit_conditional_branch (EQ); }")
3944404b540aSrobert
3945404b540aSrobert(define_expand "bne"
3946404b540aSrobert  [(set (pc)
3947404b540aSrobert	(if_then_else (match_dup 1)
3948404b540aSrobert		      (label_ref (match_operand 0 "" ""))
3949404b540aSrobert		      (pc)))]
3950404b540aSrobert  ""
3951404b540aSrobert  "{ operands[1] = alpha_emit_conditional_branch (NE); }")
3952404b540aSrobert
3953404b540aSrobert(define_expand "blt"
3954404b540aSrobert  [(set (pc)
3955404b540aSrobert	(if_then_else (match_dup 1)
3956404b540aSrobert		      (label_ref (match_operand 0 "" ""))
3957404b540aSrobert		      (pc)))]
3958404b540aSrobert  ""
3959404b540aSrobert  "{ operands[1] = alpha_emit_conditional_branch (LT); }")
3960404b540aSrobert
3961404b540aSrobert(define_expand "ble"
3962404b540aSrobert  [(set (pc)
3963404b540aSrobert	(if_then_else (match_dup 1)
3964404b540aSrobert		      (label_ref (match_operand 0 "" ""))
3965404b540aSrobert		      (pc)))]
3966404b540aSrobert  ""
3967404b540aSrobert  "{ operands[1] = alpha_emit_conditional_branch (LE); }")
3968404b540aSrobert
3969404b540aSrobert(define_expand "bgt"
3970404b540aSrobert  [(set (pc)
3971404b540aSrobert	(if_then_else (match_dup 1)
3972404b540aSrobert		      (label_ref (match_operand 0 "" ""))
3973404b540aSrobert		      (pc)))]
3974404b540aSrobert  ""
3975404b540aSrobert  "{ operands[1] = alpha_emit_conditional_branch (GT); }")
3976404b540aSrobert
3977404b540aSrobert(define_expand "bge"
3978404b540aSrobert  [(set (pc)
3979404b540aSrobert	(if_then_else (match_dup 1)
3980404b540aSrobert		      (label_ref (match_operand 0 "" ""))
3981404b540aSrobert		      (pc)))]
3982404b540aSrobert  ""
3983404b540aSrobert  "{ operands[1] = alpha_emit_conditional_branch (GE); }")
3984404b540aSrobert
3985404b540aSrobert(define_expand "bltu"
3986404b540aSrobert  [(set (pc)
3987404b540aSrobert	(if_then_else (match_dup 1)
3988404b540aSrobert		      (label_ref (match_operand 0 "" ""))
3989404b540aSrobert		      (pc)))]
3990404b540aSrobert  ""
3991404b540aSrobert  "{ operands[1] = alpha_emit_conditional_branch (LTU); }")
3992404b540aSrobert
3993404b540aSrobert(define_expand "bleu"
3994404b540aSrobert  [(set (pc)
3995404b540aSrobert	(if_then_else (match_dup 1)
3996404b540aSrobert		      (label_ref (match_operand 0 "" ""))
3997404b540aSrobert		      (pc)))]
3998404b540aSrobert  ""
3999404b540aSrobert  "{ operands[1] = alpha_emit_conditional_branch (LEU); }")
4000404b540aSrobert
4001404b540aSrobert(define_expand "bgtu"
4002404b540aSrobert  [(set (pc)
4003404b540aSrobert	(if_then_else (match_dup 1)
4004404b540aSrobert		      (label_ref (match_operand 0 "" ""))
4005404b540aSrobert		      (pc)))]
4006404b540aSrobert  ""
4007404b540aSrobert  "{ operands[1] = alpha_emit_conditional_branch (GTU); }")
4008404b540aSrobert
4009404b540aSrobert(define_expand "bgeu"
4010404b540aSrobert  [(set (pc)
4011404b540aSrobert	(if_then_else (match_dup 1)
4012404b540aSrobert		      (label_ref (match_operand 0 "" ""))
4013404b540aSrobert		      (pc)))]
4014404b540aSrobert  ""
4015404b540aSrobert  "{ operands[1] = alpha_emit_conditional_branch (GEU); }")
4016404b540aSrobert
4017404b540aSrobert(define_expand "bunordered"
4018404b540aSrobert  [(set (pc)
4019404b540aSrobert	(if_then_else (match_dup 1)
4020404b540aSrobert		      (label_ref (match_operand 0 "" ""))
4021404b540aSrobert		      (pc)))]
4022404b540aSrobert  ""
4023404b540aSrobert  "{ operands[1] = alpha_emit_conditional_branch (UNORDERED); }")
4024404b540aSrobert
4025404b540aSrobert(define_expand "bordered"
4026404b540aSrobert  [(set (pc)
4027404b540aSrobert	(if_then_else (match_dup 1)
4028404b540aSrobert		      (label_ref (match_operand 0 "" ""))
4029404b540aSrobert		      (pc)))]
4030404b540aSrobert  ""
4031404b540aSrobert  "{ operands[1] = alpha_emit_conditional_branch (ORDERED); }")
4032404b540aSrobert
4033404b540aSrobert(define_expand "seq"
4034404b540aSrobert  [(set (match_operand:DI 0 "register_operand" "")
4035404b540aSrobert	(match_dup 1))]
4036404b540aSrobert  ""
4037404b540aSrobert  "{ if ((operands[1] = alpha_emit_setcc (EQ)) == NULL_RTX) FAIL; }")
4038404b540aSrobert
4039404b540aSrobert(define_expand "sne"
4040404b540aSrobert  [(set (match_operand:DI 0 "register_operand" "")
4041404b540aSrobert	(match_dup 1))]
4042404b540aSrobert  ""
4043404b540aSrobert  "{ if ((operands[1] = alpha_emit_setcc (NE)) == NULL_RTX) FAIL; }")
4044404b540aSrobert
4045404b540aSrobert(define_expand "slt"
4046404b540aSrobert  [(set (match_operand:DI 0 "register_operand" "")
4047404b540aSrobert	(match_dup 1))]
4048404b540aSrobert  ""
4049404b540aSrobert  "{ if ((operands[1] = alpha_emit_setcc (LT)) == NULL_RTX) FAIL; }")
4050404b540aSrobert
4051404b540aSrobert(define_expand "sle"
4052404b540aSrobert  [(set (match_operand:DI 0 "register_operand" "")
4053404b540aSrobert	(match_dup 1))]
4054404b540aSrobert  ""
4055404b540aSrobert  "{ if ((operands[1] = alpha_emit_setcc (LE)) == NULL_RTX) FAIL; }")
4056404b540aSrobert
4057404b540aSrobert(define_expand "sgt"
4058404b540aSrobert  [(set (match_operand:DI 0 "register_operand" "")
4059404b540aSrobert	(match_dup 1))]
4060404b540aSrobert  ""
4061404b540aSrobert  "{ if ((operands[1] = alpha_emit_setcc (GT)) == NULL_RTX) FAIL; }")
4062404b540aSrobert
4063404b540aSrobert(define_expand "sge"
4064404b540aSrobert  [(set (match_operand:DI 0 "register_operand" "")
4065404b540aSrobert	(match_dup 1))]
4066404b540aSrobert  ""
4067404b540aSrobert  "{ if ((operands[1] = alpha_emit_setcc (GE)) == NULL_RTX) FAIL; }")
4068404b540aSrobert
4069404b540aSrobert(define_expand "sltu"
4070404b540aSrobert  [(set (match_operand:DI 0 "register_operand" "")
4071404b540aSrobert	(match_dup 1))]
4072404b540aSrobert  ""
4073404b540aSrobert  "{ if ((operands[1] = alpha_emit_setcc (LTU)) == NULL_RTX) FAIL; }")
4074404b540aSrobert
4075404b540aSrobert(define_expand "sleu"
4076404b540aSrobert  [(set (match_operand:DI 0 "register_operand" "")
4077404b540aSrobert	(match_dup 1))]
4078404b540aSrobert  ""
4079404b540aSrobert  "{ if ((operands[1] = alpha_emit_setcc (LEU)) == NULL_RTX) FAIL; }")
4080404b540aSrobert
4081404b540aSrobert(define_expand "sgtu"
4082404b540aSrobert  [(set (match_operand:DI 0 "register_operand" "")
4083404b540aSrobert	(match_dup 1))]
4084404b540aSrobert  ""
4085404b540aSrobert  "{ if ((operands[1] = alpha_emit_setcc (GTU)) == NULL_RTX) FAIL; }")
4086404b540aSrobert
4087404b540aSrobert(define_expand "sgeu"
4088404b540aSrobert  [(set (match_operand:DI 0 "register_operand" "")
4089404b540aSrobert	(match_dup 1))]
4090404b540aSrobert  ""
4091404b540aSrobert  "{ if ((operands[1] = alpha_emit_setcc (GEU)) == NULL_RTX) FAIL; }")
4092404b540aSrobert
4093404b540aSrobert(define_expand "sunordered"
4094404b540aSrobert  [(set (match_operand:DI 0 "register_operand" "")
4095404b540aSrobert	(match_dup 1))]
4096404b540aSrobert  ""
4097404b540aSrobert  "{ if ((operands[1] = alpha_emit_setcc (UNORDERED)) == NULL_RTX) FAIL; }")
4098404b540aSrobert
4099404b540aSrobert(define_expand "sordered"
4100404b540aSrobert  [(set (match_operand:DI 0 "register_operand" "")
4101404b540aSrobert	(match_dup 1))]
4102404b540aSrobert  ""
4103404b540aSrobert  "{ if ((operands[1] = alpha_emit_setcc (ORDERED)) == NULL_RTX) FAIL; }")
4104404b540aSrobert
4105404b540aSrobert;; These are the main define_expand's used to make conditional moves.
4106404b540aSrobert
4107404b540aSrobert(define_expand "movsicc"
4108404b540aSrobert  [(set (match_operand:SI 0 "register_operand" "")
4109404b540aSrobert	(if_then_else:SI (match_operand 1 "comparison_operator" "")
4110404b540aSrobert			 (match_operand:SI 2 "reg_or_8bit_operand" "")
4111404b540aSrobert			 (match_operand:SI 3 "reg_or_8bit_operand" "")))]
4112404b540aSrobert  ""
4113404b540aSrobert{
4114404b540aSrobert  if ((operands[1] = alpha_emit_conditional_move (operands[1], SImode)) == 0)
4115404b540aSrobert    FAIL;
4116404b540aSrobert})
4117404b540aSrobert
4118404b540aSrobert(define_expand "movdicc"
4119404b540aSrobert  [(set (match_operand:DI 0 "register_operand" "")
4120404b540aSrobert	(if_then_else:DI (match_operand 1 "comparison_operator" "")
4121404b540aSrobert			 (match_operand:DI 2 "reg_or_8bit_operand" "")
4122404b540aSrobert			 (match_operand:DI 3 "reg_or_8bit_operand" "")))]
4123404b540aSrobert  ""
4124404b540aSrobert{
4125404b540aSrobert  if ((operands[1] = alpha_emit_conditional_move (operands[1], DImode)) == 0)
4126404b540aSrobert    FAIL;
4127404b540aSrobert})
4128404b540aSrobert
4129404b540aSrobert(define_expand "movsfcc"
4130404b540aSrobert  [(set (match_operand:SF 0 "register_operand" "")
4131404b540aSrobert	(if_then_else:SF (match_operand 1 "comparison_operator" "")
4132404b540aSrobert			 (match_operand:SF 2 "reg_or_8bit_operand" "")
4133404b540aSrobert			 (match_operand:SF 3 "reg_or_8bit_operand" "")))]
4134404b540aSrobert  ""
4135404b540aSrobert{
4136404b540aSrobert  if ((operands[1] = alpha_emit_conditional_move (operands[1], SFmode)) == 0)
4137404b540aSrobert    FAIL;
4138404b540aSrobert})
4139404b540aSrobert
4140404b540aSrobert(define_expand "movdfcc"
4141404b540aSrobert  [(set (match_operand:DF 0 "register_operand" "")
4142404b540aSrobert	(if_then_else:DF (match_operand 1 "comparison_operator" "")
4143404b540aSrobert			 (match_operand:DF 2 "reg_or_8bit_operand" "")
4144404b540aSrobert			 (match_operand:DF 3 "reg_or_8bit_operand" "")))]
4145404b540aSrobert  ""
4146404b540aSrobert{
4147404b540aSrobert  if ((operands[1] = alpha_emit_conditional_move (operands[1], DFmode)) == 0)
4148404b540aSrobert    FAIL;
4149404b540aSrobert})
4150404b540aSrobert
4151404b540aSrobert;; These define_split definitions are used in cases when comparisons have
4152404b540aSrobert;; not be stated in the correct way and we need to reverse the second
4153404b540aSrobert;; comparison.  For example, x >= 7 has to be done as x < 6 with the
4154404b540aSrobert;; comparison that tests the result being reversed.  We have one define_split
4155404b540aSrobert;; for each use of a comparison.  They do not match valid insns and need
4156404b540aSrobert;; not generate valid insns.
4157404b540aSrobert;;
4158404b540aSrobert;; We can also handle equality comparisons (and inequality comparisons in
4159404b540aSrobert;; cases where the resulting add cannot overflow) by doing an add followed by
4160404b540aSrobert;; a comparison with zero.  This is faster since the addition takes one
4161404b540aSrobert;; less cycle than a compare when feeding into a conditional move.
4162404b540aSrobert;; For this case, we also have an SImode pattern since we can merge the add
4163404b540aSrobert;; and sign extend and the order doesn't matter.
4164404b540aSrobert;;
4165404b540aSrobert;; We do not do this for floating-point, since it isn't clear how the "wrong"
4166404b540aSrobert;; operation could have been generated.
4167404b540aSrobert
4168404b540aSrobert(define_split
4169404b540aSrobert  [(set (match_operand:DI 0 "register_operand" "")
4170404b540aSrobert	(if_then_else:DI
4171404b540aSrobert	 (match_operator 1 "comparison_operator"
4172404b540aSrobert			 [(match_operand:DI 2 "reg_or_0_operand" "")
4173404b540aSrobert			  (match_operand:DI 3 "reg_or_cint_operand" "")])
4174404b540aSrobert	 (match_operand:DI 4 "reg_or_cint_operand" "")
4175404b540aSrobert	 (match_operand:DI 5 "reg_or_cint_operand" "")))
4176404b540aSrobert   (clobber (match_operand:DI 6 "register_operand" ""))]
4177404b540aSrobert  "operands[3] != const0_rtx"
4178404b540aSrobert  [(set (match_dup 6) (match_dup 7))
4179404b540aSrobert   (set (match_dup 0)
4180404b540aSrobert	(if_then_else:DI (match_dup 8) (match_dup 4) (match_dup 5)))]
4181404b540aSrobert{
4182404b540aSrobert  enum rtx_code code = GET_CODE (operands[1]);
4183404b540aSrobert  int unsignedp = (code == GEU || code == LEU || code == GTU || code == LTU);
4184404b540aSrobert
4185404b540aSrobert  /* If we are comparing for equality with a constant and that constant
4186404b540aSrobert     appears in the arm when the register equals the constant, use the
4187404b540aSrobert     register since that is more likely to match (and to produce better code
4188404b540aSrobert     if both would).  */
4189404b540aSrobert
4190404b540aSrobert  if (code == EQ && GET_CODE (operands[3]) == CONST_INT
4191404b540aSrobert      && rtx_equal_p (operands[4], operands[3]))
4192404b540aSrobert    operands[4] = operands[2];
4193404b540aSrobert
4194404b540aSrobert  else if (code == NE && GET_CODE (operands[3]) == CONST_INT
4195404b540aSrobert	   && rtx_equal_p (operands[5], operands[3]))
4196404b540aSrobert    operands[5] = operands[2];
4197404b540aSrobert
4198404b540aSrobert  if (code == NE || code == EQ
4199404b540aSrobert      || (extended_count (operands[2], DImode, unsignedp) >= 1
4200404b540aSrobert	  && extended_count (operands[3], DImode, unsignedp) >= 1))
4201404b540aSrobert    {
4202404b540aSrobert      if (GET_CODE (operands[3]) == CONST_INT)
4203404b540aSrobert	operands[7] = gen_rtx_PLUS (DImode, operands[2],
4204404b540aSrobert				    GEN_INT (- INTVAL (operands[3])));
4205404b540aSrobert      else
4206404b540aSrobert	operands[7] = gen_rtx_MINUS (DImode, operands[2], operands[3]);
4207404b540aSrobert
4208404b540aSrobert      operands[8] = gen_rtx_fmt_ee (code, VOIDmode, operands[6], const0_rtx);
4209404b540aSrobert    }
4210404b540aSrobert
4211404b540aSrobert  else if (code == EQ || code == LE || code == LT
4212404b540aSrobert	   || code == LEU || code == LTU)
4213404b540aSrobert    {
4214404b540aSrobert      operands[7] = gen_rtx_fmt_ee (code, DImode, operands[2], operands[3]);
4215404b540aSrobert      operands[8] = gen_rtx_NE (VOIDmode, operands[6], const0_rtx);
4216404b540aSrobert    }
4217404b540aSrobert  else
4218404b540aSrobert    {
4219404b540aSrobert      operands[7] = gen_rtx_fmt_ee (reverse_condition (code), DImode,
4220404b540aSrobert				    operands[2], operands[3]);
4221404b540aSrobert      operands[8] = gen_rtx_EQ (VOIDmode, operands[6], const0_rtx);
4222404b540aSrobert    }
4223404b540aSrobert})
4224404b540aSrobert
4225404b540aSrobert(define_split
4226404b540aSrobert  [(set (match_operand:DI 0 "register_operand" "")
4227404b540aSrobert	(if_then_else:DI
4228404b540aSrobert	 (match_operator 1 "comparison_operator"
4229404b540aSrobert			 [(match_operand:SI 2 "reg_or_0_operand" "")
4230404b540aSrobert			  (match_operand:SI 3 "reg_or_cint_operand" "")])
4231404b540aSrobert	 (match_operand:DI 4 "reg_or_8bit_operand" "")
4232404b540aSrobert	 (match_operand:DI 5 "reg_or_8bit_operand" "")))
4233404b540aSrobert   (clobber (match_operand:DI 6 "register_operand" ""))]
4234404b540aSrobert  "operands[3] != const0_rtx
4235404b540aSrobert   && (GET_CODE (operands[1]) == EQ || GET_CODE (operands[1]) == NE)"
4236404b540aSrobert  [(set (match_dup 6) (match_dup 7))
4237404b540aSrobert   (set (match_dup 0)
4238404b540aSrobert	(if_then_else:DI (match_dup 8) (match_dup 4) (match_dup 5)))]
4239404b540aSrobert{
4240404b540aSrobert  enum rtx_code code = GET_CODE (operands[1]);
4241404b540aSrobert  int unsignedp = (code == GEU || code == LEU || code == GTU || code == LTU);
4242404b540aSrobert  rtx tem;
4243404b540aSrobert
4244404b540aSrobert  if ((code != NE && code != EQ
4245404b540aSrobert       && ! (extended_count (operands[2], DImode, unsignedp) >= 1
4246404b540aSrobert	     && extended_count (operands[3], DImode, unsignedp) >= 1)))
4247404b540aSrobert    FAIL;
4248404b540aSrobert
4249404b540aSrobert  if (GET_CODE (operands[3]) == CONST_INT)
4250404b540aSrobert    tem = gen_rtx_PLUS (SImode, operands[2],
4251404b540aSrobert			GEN_INT (- INTVAL (operands[3])));
4252404b540aSrobert  else
4253404b540aSrobert    tem = gen_rtx_MINUS (SImode, operands[2], operands[3]);
4254404b540aSrobert
4255404b540aSrobert  operands[7] = gen_rtx_SIGN_EXTEND (DImode, tem);
4256404b540aSrobert  operands[8] = gen_rtx_fmt_ee (GET_CODE (operands[1]), VOIDmode,
4257404b540aSrobert				operands[6], const0_rtx);
4258404b540aSrobert})
4259404b540aSrobert
4260404b540aSrobert;; Prefer to use cmp and arithmetic when possible instead of a cmove.
4261404b540aSrobert
4262404b540aSrobert(define_split
4263404b540aSrobert  [(set (match_operand 0 "register_operand" "")
4264404b540aSrobert	(if_then_else (match_operator 1 "signed_comparison_operator"
4265404b540aSrobert			   [(match_operand:DI 2 "reg_or_0_operand" "")
4266404b540aSrobert			    (const_int 0)])
4267404b540aSrobert	  (match_operand 3 "const_int_operand" "")
4268404b540aSrobert	  (match_operand 4 "const_int_operand" "")))]
4269404b540aSrobert  ""
4270404b540aSrobert  [(const_int 0)]
4271404b540aSrobert{
4272404b540aSrobert  if (alpha_split_conditional_move (GET_CODE (operands[1]), operands[0],
4273404b540aSrobert				    operands[2], operands[3], operands[4]))
4274404b540aSrobert    DONE;
4275404b540aSrobert  else
4276404b540aSrobert    FAIL;
4277404b540aSrobert})
4278404b540aSrobert
4279404b540aSrobert;; ??? Why combine is allowed to create such non-canonical rtl, I don't know.
4280404b540aSrobert;; Oh well, we match it in movcc, so it must be partially our fault.
4281404b540aSrobert(define_split
4282404b540aSrobert  [(set (match_operand 0 "register_operand" "")
4283404b540aSrobert	(if_then_else (match_operator 1 "signed_comparison_operator"
4284404b540aSrobert			   [(const_int 0)
4285404b540aSrobert			    (match_operand:DI 2 "reg_or_0_operand" "")])
4286404b540aSrobert	  (match_operand 3 "const_int_operand" "")
4287404b540aSrobert	  (match_operand 4 "const_int_operand" "")))]
4288404b540aSrobert  ""
4289404b540aSrobert  [(const_int 0)]
4290404b540aSrobert{
4291404b540aSrobert  if (alpha_split_conditional_move (swap_condition (GET_CODE (operands[1])),
4292404b540aSrobert				    operands[0], operands[2], operands[3],
4293404b540aSrobert				    operands[4]))
4294404b540aSrobert    DONE;
4295404b540aSrobert  else
4296404b540aSrobert    FAIL;
4297404b540aSrobert})
4298404b540aSrobert
4299404b540aSrobert(define_insn_and_split "*cmp_sadd_di"
4300404b540aSrobert  [(set (match_operand:DI 0 "register_operand" "=r")
4301404b540aSrobert	(plus:DI (if_then_else:DI
4302404b540aSrobert		   (match_operator 1 "alpha_zero_comparison_operator"
4303404b540aSrobert		     [(match_operand:DI 2 "reg_or_0_operand" "rJ")
4304404b540aSrobert		      (const_int 0)])
4305404b540aSrobert		   (match_operand:DI 3 "const48_operand" "I")
4306404b540aSrobert		   (const_int 0))
4307404b540aSrobert	         (match_operand:DI 4 "sext_add_operand" "rIO")))
4308404b540aSrobert   (clobber (match_scratch:DI 5 "=r"))]
4309404b540aSrobert  ""
4310404b540aSrobert  "#"
4311404b540aSrobert  "! no_new_pseudos || reload_completed"
4312404b540aSrobert  [(set (match_dup 5)
4313404b540aSrobert	(match_op_dup:DI 1 [(match_dup 2) (const_int 0)]))
4314404b540aSrobert   (set (match_dup 0)
4315404b540aSrobert	(plus:DI (mult:DI (match_dup 5) (match_dup 3))
4316404b540aSrobert		 (match_dup 4)))]
4317404b540aSrobert{
4318404b540aSrobert  if (! no_new_pseudos)
4319404b540aSrobert    operands[5] = gen_reg_rtx (DImode);
4320404b540aSrobert  else if (reg_overlap_mentioned_p (operands[5], operands[4]))
4321404b540aSrobert    operands[5] = operands[0];
4322404b540aSrobert})
4323404b540aSrobert
4324404b540aSrobert(define_insn_and_split "*cmp_sadd_si"
4325404b540aSrobert  [(set (match_operand:SI 0 "register_operand" "=r")
4326404b540aSrobert	(plus:SI (if_then_else:SI
4327404b540aSrobert		   (match_operator 1 "alpha_zero_comparison_operator"
4328404b540aSrobert		     [(match_operand:DI 2 "reg_or_0_operand" "rJ")
4329404b540aSrobert		      (const_int 0)])
4330404b540aSrobert		   (match_operand:SI 3 "const48_operand" "I")
4331404b540aSrobert		   (const_int 0))
4332404b540aSrobert	         (match_operand:SI 4 "sext_add_operand" "rIO")))
4333404b540aSrobert   (clobber (match_scratch:SI 5 "=r"))]
4334404b540aSrobert  ""
4335404b540aSrobert  "#"
4336404b540aSrobert  "! no_new_pseudos || reload_completed"
4337404b540aSrobert  [(set (match_dup 5)
4338404b540aSrobert	(match_op_dup:SI 1 [(match_dup 2) (const_int 0)]))
4339404b540aSrobert   (set (match_dup 0)
4340404b540aSrobert	(plus:SI (mult:SI (match_dup 5) (match_dup 3))
4341404b540aSrobert		 (match_dup 4)))]
4342404b540aSrobert{
4343404b540aSrobert  if (! no_new_pseudos)
4344404b540aSrobert    operands[5] = gen_reg_rtx (DImode);
4345404b540aSrobert  else if (reg_overlap_mentioned_p (operands[5], operands[4]))
4346404b540aSrobert    operands[5] = operands[0];
4347404b540aSrobert})
4348404b540aSrobert
4349404b540aSrobert(define_insn_and_split "*cmp_sadd_sidi"
4350404b540aSrobert  [(set (match_operand:DI 0 "register_operand" "=r")
4351404b540aSrobert	(sign_extend:DI
4352404b540aSrobert	  (plus:SI (if_then_else:SI
4353404b540aSrobert		     (match_operator 1 "alpha_zero_comparison_operator"
4354404b540aSrobert		       [(match_operand:DI 2 "reg_or_0_operand" "rJ")
4355404b540aSrobert		        (const_int 0)])
4356404b540aSrobert		     (match_operand:SI 3 "const48_operand" "I")
4357404b540aSrobert		     (const_int 0))
4358404b540aSrobert	           (match_operand:SI 4 "sext_add_operand" "rIO"))))
4359404b540aSrobert   (clobber (match_scratch:SI 5 "=r"))]
4360404b540aSrobert  ""
4361404b540aSrobert  "#"
4362404b540aSrobert  "! no_new_pseudos || reload_completed"
4363404b540aSrobert  [(set (match_dup 5)
4364404b540aSrobert	(match_op_dup:SI 1 [(match_dup 2) (const_int 0)]))
4365404b540aSrobert   (set (match_dup 0)
4366404b540aSrobert	(sign_extend:DI (plus:SI (mult:SI (match_dup 5) (match_dup 3))
4367404b540aSrobert				 (match_dup 4))))]
4368404b540aSrobert{
4369404b540aSrobert  if (! no_new_pseudos)
4370404b540aSrobert    operands[5] = gen_reg_rtx (DImode);
4371404b540aSrobert  else if (reg_overlap_mentioned_p (operands[5], operands[4]))
4372404b540aSrobert    operands[5] = operands[0];
4373404b540aSrobert})
4374404b540aSrobert
4375404b540aSrobert(define_insn_and_split "*cmp_ssub_di"
4376404b540aSrobert  [(set (match_operand:DI 0 "register_operand" "=r")
4377404b540aSrobert	(minus:DI (if_then_else:DI
4378404b540aSrobert		    (match_operator 1 "alpha_zero_comparison_operator"
4379404b540aSrobert		      [(match_operand:DI 2 "reg_or_0_operand" "rJ")
4380404b540aSrobert		       (const_int 0)])
4381404b540aSrobert		    (match_operand:DI 3 "const48_operand" "I")
4382404b540aSrobert		    (const_int 0))
4383404b540aSrobert	          (match_operand:DI 4 "reg_or_8bit_operand" "rI")))
4384404b540aSrobert   (clobber (match_scratch:DI 5 "=r"))]
4385404b540aSrobert  ""
4386404b540aSrobert  "#"
4387404b540aSrobert  "! no_new_pseudos || reload_completed"
4388404b540aSrobert  [(set (match_dup 5)
4389404b540aSrobert	(match_op_dup:DI 1 [(match_dup 2) (const_int 0)]))
4390404b540aSrobert   (set (match_dup 0)
4391404b540aSrobert	(minus:DI (mult:DI (match_dup 5) (match_dup 3))
4392404b540aSrobert		  (match_dup 4)))]
4393404b540aSrobert{
4394404b540aSrobert  if (! no_new_pseudos)
4395404b540aSrobert    operands[5] = gen_reg_rtx (DImode);
4396404b540aSrobert  else if (reg_overlap_mentioned_p (operands[5], operands[4]))
4397404b540aSrobert    operands[5] = operands[0];
4398404b540aSrobert})
4399404b540aSrobert
4400404b540aSrobert(define_insn_and_split "*cmp_ssub_si"
4401404b540aSrobert  [(set (match_operand:SI 0 "register_operand" "=r")
4402404b540aSrobert	(minus:SI (if_then_else:SI
4403404b540aSrobert		    (match_operator 1 "alpha_zero_comparison_operator"
4404404b540aSrobert		      [(match_operand:DI 2 "reg_or_0_operand" "rJ")
4405404b540aSrobert		       (const_int 0)])
4406404b540aSrobert		    (match_operand:SI 3 "const48_operand" "I")
4407404b540aSrobert		    (const_int 0))
4408404b540aSrobert	          (match_operand:SI 4 "reg_or_8bit_operand" "rI")))
4409404b540aSrobert   (clobber (match_scratch:SI 5 "=r"))]
4410404b540aSrobert  ""
4411404b540aSrobert  "#"
4412404b540aSrobert  "! no_new_pseudos || reload_completed"
4413404b540aSrobert  [(set (match_dup 5)
4414404b540aSrobert	(match_op_dup:SI 1 [(match_dup 2) (const_int 0)]))
4415404b540aSrobert   (set (match_dup 0)
4416404b540aSrobert	(minus:SI (mult:SI (match_dup 5) (match_dup 3))
4417404b540aSrobert		 (match_dup 4)))]
4418404b540aSrobert{
4419404b540aSrobert  if (! no_new_pseudos)
4420404b540aSrobert    operands[5] = gen_reg_rtx (DImode);
4421404b540aSrobert  else if (reg_overlap_mentioned_p (operands[5], operands[4]))
4422404b540aSrobert    operands[5] = operands[0];
4423404b540aSrobert})
4424404b540aSrobert
4425404b540aSrobert(define_insn_and_split "*cmp_ssub_sidi"
4426404b540aSrobert  [(set (match_operand:DI 0 "register_operand" "=r")
4427404b540aSrobert	(sign_extend:DI
4428404b540aSrobert	  (minus:SI (if_then_else:SI
4429404b540aSrobert		      (match_operator 1 "alpha_zero_comparison_operator"
4430404b540aSrobert		        [(match_operand:DI 2 "reg_or_0_operand" "rJ")
4431404b540aSrobert		         (const_int 0)])
4432404b540aSrobert		      (match_operand:SI 3 "const48_operand" "I")
4433404b540aSrobert		      (const_int 0))
4434404b540aSrobert	            (match_operand:SI 4 "reg_or_8bit_operand" "rI"))))
4435404b540aSrobert   (clobber (match_scratch:SI 5 "=r"))]
4436404b540aSrobert  ""
4437404b540aSrobert  "#"
4438404b540aSrobert  "! no_new_pseudos || reload_completed"
4439404b540aSrobert  [(set (match_dup 5)
4440404b540aSrobert	(match_op_dup:SI 1 [(match_dup 2) (const_int 0)]))
4441404b540aSrobert   (set (match_dup 0)
4442404b540aSrobert	(sign_extend:DI (minus:SI (mult:SI (match_dup 5) (match_dup 3))
4443404b540aSrobert				  (match_dup 4))))]
4444404b540aSrobert{
4445404b540aSrobert  if (! no_new_pseudos)
4446404b540aSrobert    operands[5] = gen_reg_rtx (DImode);
4447404b540aSrobert  else if (reg_overlap_mentioned_p (operands[5], operands[4]))
4448404b540aSrobert    operands[5] = operands[0];
4449404b540aSrobert})
4450404b540aSrobert
4451404b540aSrobert;; Here are the CALL and unconditional branch insns.  Calls on NT and OSF
4452404b540aSrobert;; work differently, so we have different patterns for each.
4453404b540aSrobert
4454404b540aSrobert;; On Unicos/Mk a call information word (CIW) must be generated for each
4455404b540aSrobert;; call. The CIW contains information about arguments passed in registers
4456404b540aSrobert;; and is stored in the caller's SSIB. Its offset relative to the beginning
4457404b540aSrobert;; of the SSIB is passed in $25. Handling this properly is quite complicated
4458404b540aSrobert;; in the presence of inlining since the CIWs for calls performed by the
4459404b540aSrobert;; inlined function must be stored in the SSIB of the function it is inlined
4460404b540aSrobert;; into as well. We encode the CIW in an unspec and append it to the list
4461404b540aSrobert;; of the CIWs for the current function only when the instruction for loading
4462404b540aSrobert;; $25 is generated.
4463404b540aSrobert
4464404b540aSrobert(define_expand "call"
4465404b540aSrobert  [(use (match_operand:DI 0 "" ""))
4466404b540aSrobert   (use (match_operand 1 "" ""))
4467404b540aSrobert   (use (match_operand 2 "" ""))
4468404b540aSrobert   (use (match_operand 3 "" ""))]
4469404b540aSrobert  ""
4470404b540aSrobert{
4471404b540aSrobert  if (TARGET_ABI_WINDOWS_NT)
4472404b540aSrobert    emit_call_insn (gen_call_nt (operands[0], operands[1]));
4473404b540aSrobert  else if (TARGET_ABI_OPEN_VMS)
4474404b540aSrobert    emit_call_insn (gen_call_vms (operands[0], operands[2]));
4475404b540aSrobert  else if (TARGET_ABI_UNICOSMK)
4476404b540aSrobert    emit_call_insn (gen_call_umk (operands[0], operands[2]));
4477404b540aSrobert  else
4478404b540aSrobert    emit_call_insn (gen_call_osf (operands[0], operands[1]));
4479404b540aSrobert  DONE;
4480404b540aSrobert})
4481404b540aSrobert
4482404b540aSrobert(define_expand "sibcall"
4483404b540aSrobert  [(parallel [(call (mem:DI (match_operand 0 "" ""))
4484404b540aSrobert			    (match_operand 1 "" ""))
4485404b540aSrobert	      (unspec [(reg:DI 29)] UNSPEC_SIBCALL)])]
4486404b540aSrobert  "TARGET_ABI_OSF"
4487404b540aSrobert{
4488404b540aSrobert  gcc_assert (GET_CODE (operands[0]) == MEM);
4489404b540aSrobert  operands[0] = XEXP (operands[0], 0);
4490404b540aSrobert})
4491404b540aSrobert
4492404b540aSrobert(define_expand "call_osf"
4493404b540aSrobert  [(parallel [(call (mem:DI (match_operand 0 "" ""))
4494404b540aSrobert		    (match_operand 1 "" ""))
4495404b540aSrobert	      (use (reg:DI 29))
4496404b540aSrobert	      (clobber (reg:DI 26))])]
4497404b540aSrobert  ""
4498404b540aSrobert{
4499404b540aSrobert  gcc_assert (GET_CODE (operands[0]) == MEM);
4500404b540aSrobert
4501404b540aSrobert  operands[0] = XEXP (operands[0], 0);
4502404b540aSrobert  if (! call_operand (operands[0], Pmode))
4503404b540aSrobert    operands[0] = copy_to_mode_reg (Pmode, operands[0]);
4504404b540aSrobert})
4505404b540aSrobert
4506404b540aSrobert(define_expand "call_nt"
4507404b540aSrobert  [(parallel [(call (mem:DI (match_operand 0 "" ""))
4508404b540aSrobert		    (match_operand 1 "" ""))
4509404b540aSrobert	      (clobber (reg:DI 26))])]
4510404b540aSrobert  ""
4511404b540aSrobert{
4512404b540aSrobert  gcc_assert (GET_CODE (operands[0]) == MEM);
4513404b540aSrobert
4514404b540aSrobert  operands[0] = XEXP (operands[0], 0);
4515404b540aSrobert  if (GET_CODE (operands[0]) != SYMBOL_REF && GET_CODE (operands[0]) != REG)
4516404b540aSrobert    operands[0] = force_reg (DImode, operands[0]);
4517404b540aSrobert})
4518404b540aSrobert
4519404b540aSrobert;; Calls on Unicos/Mk are always indirect.
4520404b540aSrobert;; op 0: symbol ref for called function
4521404b540aSrobert;; op 1: CIW for $25 represented by an unspec
4522404b540aSrobert
4523404b540aSrobert(define_expand "call_umk"
4524404b540aSrobert   [(parallel [(call (mem:DI (match_operand 0 "" ""))
4525404b540aSrobert		     (match_operand 1 "" ""))
4526404b540aSrobert	       (use (reg:DI 25))
4527404b540aSrobert	       (clobber (reg:DI 26))])]
4528404b540aSrobert   ""
4529404b540aSrobert{
4530404b540aSrobert  gcc_assert (GET_CODE (operands[0]) == MEM);
4531404b540aSrobert
4532404b540aSrobert  /* Always load the address of the called function into a register;
4533404b540aSrobert     load the CIW in $25.  */
4534404b540aSrobert
4535404b540aSrobert  operands[0] = XEXP (operands[0], 0);
4536404b540aSrobert  if (GET_CODE (operands[0]) != REG)
4537404b540aSrobert    operands[0] = force_reg (DImode, operands[0]);
4538404b540aSrobert
4539404b540aSrobert  emit_move_insn (gen_rtx_REG (DImode, 25), operands[1]);
4540404b540aSrobert})
4541404b540aSrobert
4542404b540aSrobert;;
4543404b540aSrobert;; call openvms/alpha
4544404b540aSrobert;; op 0: symbol ref for called function
4545404b540aSrobert;; op 1: next_arg_reg (argument information value for R25)
4546404b540aSrobert;;
4547404b540aSrobert(define_expand "call_vms"
4548404b540aSrobert  [(parallel [(call (mem:DI (match_operand 0 "" ""))
4549404b540aSrobert		    (match_operand 1 "" ""))
4550404b540aSrobert	      (use (match_dup 2))
4551404b540aSrobert	      (use (reg:DI 25))
4552404b540aSrobert	      (use (reg:DI 26))
4553404b540aSrobert	      (clobber (reg:DI 27))])]
4554404b540aSrobert  ""
4555404b540aSrobert{
4556404b540aSrobert  gcc_assert (GET_CODE (operands[0]) == MEM);
4557404b540aSrobert
4558404b540aSrobert  operands[0] = XEXP (operands[0], 0);
4559404b540aSrobert
4560404b540aSrobert  /* Always load AI with argument information, then handle symbolic and
4561404b540aSrobert     indirect call differently.  Load RA and set operands[2] to PV in
4562404b540aSrobert     both cases.  */
4563404b540aSrobert
4564404b540aSrobert  emit_move_insn (gen_rtx_REG (DImode, 25), operands[1]);
4565404b540aSrobert  if (GET_CODE (operands[0]) == SYMBOL_REF)
4566404b540aSrobert    {
4567404b540aSrobert      alpha_need_linkage (XSTR (operands[0], 0), 0);
4568404b540aSrobert
4569404b540aSrobert      operands[2] = const0_rtx;
4570404b540aSrobert    }
4571404b540aSrobert  else
4572404b540aSrobert    {
4573404b540aSrobert      emit_move_insn (gen_rtx_REG (Pmode, 26),
4574404b540aSrobert		      gen_rtx_MEM (Pmode, plus_constant (operands[0], 8)));
4575404b540aSrobert      operands[2] = operands[0];
4576404b540aSrobert    }
4577404b540aSrobert
4578404b540aSrobert})
4579404b540aSrobert
4580404b540aSrobert(define_expand "call_value"
4581404b540aSrobert  [(use (match_operand 0 "" ""))
4582404b540aSrobert   (use (match_operand:DI 1 "" ""))
4583404b540aSrobert   (use (match_operand 2 "" ""))
4584404b540aSrobert   (use (match_operand 3 "" ""))
4585404b540aSrobert   (use (match_operand 4 "" ""))]
4586404b540aSrobert  ""
4587404b540aSrobert{
4588404b540aSrobert  if (TARGET_ABI_WINDOWS_NT)
4589404b540aSrobert    emit_call_insn (gen_call_value_nt (operands[0], operands[1], operands[2]));
4590404b540aSrobert  else if (TARGET_ABI_OPEN_VMS)
4591404b540aSrobert    emit_call_insn (gen_call_value_vms (operands[0], operands[1],
4592404b540aSrobert					operands[3]));
4593404b540aSrobert  else if (TARGET_ABI_UNICOSMK)
4594404b540aSrobert    emit_call_insn (gen_call_value_umk (operands[0], operands[1],
4595404b540aSrobert					operands[3]));
4596404b540aSrobert  else
4597404b540aSrobert    emit_call_insn (gen_call_value_osf (operands[0], operands[1],
4598404b540aSrobert					operands[2]));
4599404b540aSrobert  DONE;
4600404b540aSrobert})
4601404b540aSrobert
4602404b540aSrobert(define_expand "sibcall_value"
4603404b540aSrobert  [(parallel [(set (match_operand 0 "" "")
4604404b540aSrobert		   (call (mem:DI (match_operand 1 "" ""))
4605404b540aSrobert		         (match_operand 2 "" "")))
4606404b540aSrobert	      (unspec [(reg:DI 29)] UNSPEC_SIBCALL)])]
4607404b540aSrobert  "TARGET_ABI_OSF"
4608404b540aSrobert{
4609404b540aSrobert  gcc_assert (GET_CODE (operands[1]) == MEM);
4610404b540aSrobert  operands[1] = XEXP (operands[1], 0);
4611404b540aSrobert})
4612404b540aSrobert
4613404b540aSrobert(define_expand "call_value_osf"
4614404b540aSrobert  [(parallel [(set (match_operand 0 "" "")
4615404b540aSrobert		   (call (mem:DI (match_operand 1 "" ""))
4616404b540aSrobert			 (match_operand 2 "" "")))
4617404b540aSrobert	      (use (reg:DI 29))
4618404b540aSrobert	      (clobber (reg:DI 26))])]
4619404b540aSrobert  ""
4620404b540aSrobert{
4621404b540aSrobert  gcc_assert (GET_CODE (operands[1]) == MEM);
4622404b540aSrobert
4623404b540aSrobert  operands[1] = XEXP (operands[1], 0);
4624404b540aSrobert  if (! call_operand (operands[1], Pmode))
4625404b540aSrobert    operands[1] = copy_to_mode_reg (Pmode, operands[1]);
4626404b540aSrobert})
4627404b540aSrobert
4628404b540aSrobert(define_expand "call_value_nt"
4629404b540aSrobert  [(parallel [(set (match_operand 0 "" "")
4630404b540aSrobert		   (call (mem:DI (match_operand 1 "" ""))
4631404b540aSrobert			 (match_operand 2 "" "")))
4632404b540aSrobert	      (clobber (reg:DI 26))])]
4633404b540aSrobert  ""
4634404b540aSrobert{
4635404b540aSrobert  gcc_assert (GET_CODE (operands[1]) == MEM);
4636404b540aSrobert
4637404b540aSrobert  operands[1] = XEXP (operands[1], 0);
4638404b540aSrobert  if (GET_CODE (operands[1]) != SYMBOL_REF && GET_CODE (operands[1]) != REG)
4639404b540aSrobert    operands[1] = force_reg (DImode, operands[1]);
4640404b540aSrobert})
4641404b540aSrobert
4642404b540aSrobert(define_expand "call_value_vms"
4643404b540aSrobert  [(parallel [(set (match_operand 0 "" "")
4644404b540aSrobert		   (call (mem:DI (match_operand:DI 1 "" ""))
4645404b540aSrobert			 (match_operand 2 "" "")))
4646404b540aSrobert	      (use (match_dup 3))
4647404b540aSrobert	      (use (reg:DI 25))
4648404b540aSrobert	      (use (reg:DI 26))
4649404b540aSrobert	      (clobber (reg:DI 27))])]
4650404b540aSrobert  ""
4651404b540aSrobert{
4652404b540aSrobert  gcc_assert (GET_CODE (operands[1]) == MEM);
4653404b540aSrobert
4654404b540aSrobert  operands[1] = XEXP (operands[1], 0);
4655404b540aSrobert
4656404b540aSrobert  /* Always load AI with argument information, then handle symbolic and
4657404b540aSrobert     indirect call differently.  Load RA and set operands[3] to PV in
4658404b540aSrobert     both cases.  */
4659404b540aSrobert
4660404b540aSrobert  emit_move_insn (gen_rtx_REG (DImode, 25), operands[2]);
4661404b540aSrobert  if (GET_CODE (operands[1]) == SYMBOL_REF)
4662404b540aSrobert    {
4663404b540aSrobert      alpha_need_linkage (XSTR (operands[1], 0), 0);
4664404b540aSrobert
4665404b540aSrobert      operands[3] = const0_rtx;
4666404b540aSrobert    }
4667404b540aSrobert  else
4668404b540aSrobert    {
4669404b540aSrobert      emit_move_insn (gen_rtx_REG (Pmode, 26),
4670404b540aSrobert		      gen_rtx_MEM (Pmode, plus_constant (operands[1], 8)));
4671404b540aSrobert      operands[3] = operands[1];
4672404b540aSrobert    }
4673404b540aSrobert})
4674404b540aSrobert
4675404b540aSrobert(define_expand "call_value_umk"
4676404b540aSrobert  [(parallel [(set (match_operand 0 "" "")
4677404b540aSrobert		   (call (mem:DI (match_operand 1 "" ""))
4678404b540aSrobert			 (match_operand 2 "" "")))
4679404b540aSrobert	      (use (reg:DI 25))
4680404b540aSrobert	      (clobber (reg:DI 26))])]
4681404b540aSrobert  ""
4682404b540aSrobert{
4683404b540aSrobert  gcc_assert (GET_CODE (operands[1]) == MEM);
4684404b540aSrobert
4685404b540aSrobert  operands[1] = XEXP (operands[1], 0);
4686404b540aSrobert  if (GET_CODE (operands[1]) != REG)
4687404b540aSrobert    operands[1] = force_reg (DImode, operands[1]);
4688404b540aSrobert
4689404b540aSrobert  emit_move_insn (gen_rtx_REG (DImode, 25), operands[2]);
4690404b540aSrobert})
4691404b540aSrobert
4692404b540aSrobert(define_insn "*call_osf_1_er"
4693404b540aSrobert  [(call (mem:DI (match_operand:DI 0 "call_operand" "c,R,s"))
4694404b540aSrobert	 (match_operand 1 "" ""))
4695404b540aSrobert   (use (reg:DI 29))
4696404b540aSrobert   (clobber (reg:DI 26))]
4697404b540aSrobert  "TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF"
4698404b540aSrobert  "@
4699404b540aSrobert   jsr $26,(%0),0\;ldah $29,0($26)\t\t!gpdisp!%*\;lda $29,0($29)\t\t!gpdisp!%*
4700404b540aSrobert   bsr $26,%0\t\t!samegp
4701404b540aSrobert   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!%*"
4702404b540aSrobert  [(set_attr "type" "jsr")
4703404b540aSrobert   (set_attr "length" "12,*,16")])
4704404b540aSrobert
4705404b540aSrobert;; We must use peep2 instead of a split because we need accurate life
4706404b540aSrobert;; information for $gp.  Consider the case of { bar(); while (1); }.
4707404b540aSrobert(define_peephole2
4708404b540aSrobert  [(parallel [(call (mem:DI (match_operand:DI 0 "call_operand" ""))
4709404b540aSrobert		    (match_operand 1 "" ""))
4710404b540aSrobert	      (use (reg:DI 29))
4711404b540aSrobert	      (clobber (reg:DI 26))])]
4712404b540aSrobert  "TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF && reload_completed
4713404b540aSrobert   && ! samegp_function_operand (operands[0], Pmode)
4714404b540aSrobert   && (peep2_regno_dead_p (1, 29)
4715404b540aSrobert       || find_reg_note (insn, REG_NORETURN, NULL_RTX))"
4716404b540aSrobert  [(parallel [(call (mem:DI (match_dup 2))
4717404b540aSrobert		    (match_dup 1))
4718404b540aSrobert	      (set (reg:DI 26) (plus:DI (pc) (const_int 4)))
4719404b540aSrobert	      (unspec_volatile [(reg:DI 29)] UNSPECV_BLOCKAGE)
4720404b540aSrobert	      (use (match_dup 0))
4721404b540aSrobert	      (use (match_dup 3))])]
4722404b540aSrobert{
4723404b540aSrobert  if (CONSTANT_P (operands[0]))
4724404b540aSrobert    {
4725404b540aSrobert      operands[2] = gen_rtx_REG (Pmode, 27);
4726404b540aSrobert      operands[3] = GEN_INT (alpha_next_sequence_number++);
4727404b540aSrobert      emit_insn (gen_movdi_er_high_g (operands[2], pic_offset_table_rtx,
4728404b540aSrobert				      operands[0], operands[3]));
4729404b540aSrobert    }
4730404b540aSrobert  else
4731404b540aSrobert    {
4732404b540aSrobert      operands[2] = operands[0];
4733404b540aSrobert      operands[0] = const0_rtx;
4734404b540aSrobert      operands[3] = const0_rtx;
4735404b540aSrobert    }
4736404b540aSrobert})
4737404b540aSrobert
4738404b540aSrobert(define_peephole2
4739404b540aSrobert  [(parallel [(call (mem:DI (match_operand:DI 0 "call_operand" ""))
4740404b540aSrobert		    (match_operand 1 "" ""))
4741404b540aSrobert	      (use (reg:DI 29))
4742404b540aSrobert	      (clobber (reg:DI 26))])]
4743404b540aSrobert  "TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF && reload_completed
4744404b540aSrobert   && ! samegp_function_operand (operands[0], Pmode)
4745404b540aSrobert   && ! (peep2_regno_dead_p (1, 29)
4746404b540aSrobert         || find_reg_note (insn, REG_NORETURN, NULL_RTX))"
4747404b540aSrobert  [(parallel [(call (mem:DI (match_dup 2))
4748404b540aSrobert		    (match_dup 1))
4749404b540aSrobert	      (set (reg:DI 26) (plus:DI (pc) (const_int 4)))
4750404b540aSrobert	      (unspec_volatile [(reg:DI 29)] UNSPECV_BLOCKAGE)
4751404b540aSrobert	      (use (match_dup 0))
4752404b540aSrobert	      (use (match_dup 4))])
4753404b540aSrobert   (set (reg:DI 29)
4754404b540aSrobert	(unspec_volatile:DI [(reg:DI 26) (match_dup 3)] UNSPECV_LDGP1))
4755404b540aSrobert   (set (reg:DI 29)
4756404b540aSrobert	(unspec:DI [(reg:DI 29) (match_dup 3)] UNSPEC_LDGP2))]
4757404b540aSrobert{
4758404b540aSrobert  if (CONSTANT_P (operands[0]))
4759404b540aSrobert    {
4760404b540aSrobert      operands[2] = gen_rtx_REG (Pmode, 27);
4761404b540aSrobert      operands[4] = GEN_INT (alpha_next_sequence_number++);
4762404b540aSrobert      emit_insn (gen_movdi_er_high_g (operands[2], pic_offset_table_rtx,
4763404b540aSrobert				      operands[0], operands[4]));
4764404b540aSrobert    }
4765404b540aSrobert  else
4766404b540aSrobert    {
4767404b540aSrobert      operands[2] = operands[0];
4768404b540aSrobert      operands[0] = const0_rtx;
4769404b540aSrobert      operands[4] = const0_rtx;
4770404b540aSrobert    }
4771404b540aSrobert  operands[3] = GEN_INT (alpha_next_sequence_number++);
4772404b540aSrobert})
4773404b540aSrobert
4774404b540aSrobert;; We add a blockage unspec_volatile to prevent insns from moving down
4775404b540aSrobert;; from above the call to in between the call and the ldah gpdisp.
4776404b540aSrobert
4777404b540aSrobert(define_insn "*call_osf_2_er"
4778404b540aSrobert  [(call (mem:DI (match_operand:DI 0 "register_operand" "c"))
4779404b540aSrobert	 (match_operand 1 "" ""))
4780404b540aSrobert   (set (reg:DI 26) (plus:DI (pc) (const_int 4)))
4781404b540aSrobert   (unspec_volatile [(reg:DI 29)] UNSPECV_BLOCKAGE)
4782404b540aSrobert   (use (match_operand 2 "" ""))
4783404b540aSrobert   (use (match_operand 3 "const_int_operand" ""))]
4784404b540aSrobert  "TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF"
4785404b540aSrobert  "jsr $26,(%0),%2%J3"
4786404b540aSrobert  [(set_attr "type" "jsr")
4787404b540aSrobert   (set_attr "cannot_copy" "true")])
4788404b540aSrobert
4789404b540aSrobert;; We output a nop after noreturn calls at the very end of the function to
4790404b540aSrobert;; ensure that the return address always remains in the caller's code range,
4791404b540aSrobert;; as not doing so might confuse unwinding engines.
4792404b540aSrobert;;
4793404b540aSrobert;; The potential change in insn length is not reflected in the length
4794404b540aSrobert;; attributes at this stage. Since the extra space is only actually added at
4795404b540aSrobert;; the very end of the compilation process (via final/print_operand), it
4796404b540aSrobert;; really seems harmless and not worth the trouble of some extra computation
4797404b540aSrobert;; cost and complexity.
4798404b540aSrobert
4799404b540aSrobert(define_insn "*call_osf_1_noreturn"
4800404b540aSrobert  [(call (mem:DI (match_operand:DI 0 "call_operand" "c,R,s"))
4801404b540aSrobert	 (match_operand 1 "" ""))
4802404b540aSrobert   (use (reg:DI 29))
4803404b540aSrobert   (clobber (reg:DI 26))]
4804404b540aSrobert  "! TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF
4805404b540aSrobert   && find_reg_note (insn, REG_NORETURN, NULL_RTX)"
4806404b540aSrobert  "@
4807404b540aSrobert   jsr $26,($27),0%+
4808404b540aSrobert   bsr $26,$%0..ng%+
4809404b540aSrobert   jsr $26,%0%+"
4810404b540aSrobert  [(set_attr "type" "jsr")
4811404b540aSrobert   (set_attr "length" "*,*,8")])
4812404b540aSrobert
4813404b540aSrobert(define_insn "*call_osf_1"
4814404b540aSrobert  [(call (mem:DI (match_operand:DI 0 "call_operand" "c,R,s"))
4815404b540aSrobert	 (match_operand 1 "" ""))
4816404b540aSrobert   (use (reg:DI 29))
4817404b540aSrobert   (clobber (reg:DI 26))]
4818404b540aSrobert  "! TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF"
4819404b540aSrobert  "@
4820404b540aSrobert   jsr $26,($27),0\;ldgp $29,0($26)
4821404b540aSrobert   bsr $26,$%0..ng
4822404b540aSrobert   jsr $26,%0\;ldgp $29,0($26)"
4823404b540aSrobert  [(set_attr "type" "jsr")
4824404b540aSrobert   (set_attr "length" "12,*,16")])
4825404b540aSrobert
4826404b540aSrobert;; Note that the DEC assembler expands "jmp foo" with $at, which
4827404b540aSrobert;; doesn't do what we want.
4828404b540aSrobert(define_insn "*sibcall_osf_1_er"
4829404b540aSrobert  [(call (mem:DI (match_operand:DI 0 "symbolic_operand" "R,s"))
4830404b540aSrobert	 (match_operand 1 "" ""))
4831404b540aSrobert   (unspec [(reg:DI 29)] UNSPEC_SIBCALL)]
4832404b540aSrobert  "TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF"
4833404b540aSrobert  "@
4834404b540aSrobert   br $31,%0\t\t!samegp
4835404b540aSrobert   ldq $27,%0($29)\t\t!literal!%#\;jmp $31,($27),%0\t\t!lituse_jsr!%#"
4836404b540aSrobert  [(set_attr "type" "jsr")
4837404b540aSrobert   (set_attr "length" "*,8")])
4838404b540aSrobert
4839404b540aSrobert(define_insn "*sibcall_osf_1"
4840404b540aSrobert  [(call (mem:DI (match_operand:DI 0 "symbolic_operand" "R,s"))
4841404b540aSrobert	 (match_operand 1 "" ""))
4842404b540aSrobert   (unspec [(reg:DI 29)] UNSPEC_SIBCALL)]
4843404b540aSrobert  "! TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF"
4844404b540aSrobert  "@
4845404b540aSrobert   br $31,$%0..ng
4846404b540aSrobert   lda $27,%0\;jmp $31,($27),%0"
4847404b540aSrobert  [(set_attr "type" "jsr")
4848404b540aSrobert   (set_attr "length" "*,8")])
4849404b540aSrobert
4850404b540aSrobert(define_insn "*call_nt_1"
4851404b540aSrobert  [(call (mem:DI (match_operand:DI 0 "call_operand" "r,R,s"))
4852404b540aSrobert	 (match_operand 1 "" ""))
4853404b540aSrobert   (clobber (reg:DI 26))]
4854404b540aSrobert  "TARGET_ABI_WINDOWS_NT"
4855404b540aSrobert  "@
4856404b540aSrobert   jsr $26,(%0)
4857404b540aSrobert   bsr $26,%0
4858404b540aSrobert   jsr $26,%0"
4859404b540aSrobert  [(set_attr "type" "jsr")
4860404b540aSrobert   (set_attr "length" "*,*,12")])
4861404b540aSrobert
4862404b540aSrobert; GAS relies on the order and position of instructions output below in order
4863404b540aSrobert; to generate relocs for VMS link to potentially optimize the call.
4864404b540aSrobert; Please do not molest.
4865404b540aSrobert(define_insn "*call_vms_1"
4866404b540aSrobert  [(call (mem:DI (match_operand:DI 0 "call_operand" "r,s"))
4867404b540aSrobert	 (match_operand 1 "" ""))
4868404b540aSrobert   (use (match_operand:DI 2 "nonmemory_operand" "r,n"))
4869404b540aSrobert   (use (reg:DI 25))
4870404b540aSrobert   (use (reg:DI 26))
4871404b540aSrobert   (clobber (reg:DI 27))]
4872404b540aSrobert  "TARGET_ABI_OPEN_VMS"
4873404b540aSrobert{
4874404b540aSrobert  switch (which_alternative)
4875404b540aSrobert    {
4876404b540aSrobert    case 0:
4877404b540aSrobert   	return "mov %2,$27\;jsr $26,0\;ldq $27,0($29)";
4878404b540aSrobert    case 1:
4879404b540aSrobert	operands [2] = alpha_use_linkage (operands [0], cfun->decl, 1, 0);
4880404b540aSrobert	operands [3] = alpha_use_linkage (operands [0], cfun->decl, 0, 0);
4881404b540aSrobert   	return "ldq $26,%3\;ldq $27,%2\;jsr $26,%0\;ldq $27,0($29)";
4882404b540aSrobert    default:
4883404b540aSrobert      gcc_unreachable ();
4884404b540aSrobert    }
4885404b540aSrobert}
4886404b540aSrobert  [(set_attr "type" "jsr")
4887404b540aSrobert   (set_attr "length" "12,16")])
4888404b540aSrobert
4889404b540aSrobert(define_insn "*call_umk_1"
4890404b540aSrobert  [(call (mem:DI (match_operand:DI 0 "call_operand" "r"))
4891404b540aSrobert	 (match_operand 1 "" ""))
4892404b540aSrobert   (use (reg:DI 25))
4893404b540aSrobert   (clobber (reg:DI 26))]
4894404b540aSrobert  "TARGET_ABI_UNICOSMK"
4895404b540aSrobert  "jsr $26,(%0)"
4896404b540aSrobert  [(set_attr "type" "jsr")])
4897404b540aSrobert
4898404b540aSrobert;; Call subroutine returning any type.
4899404b540aSrobert
4900404b540aSrobert(define_expand "untyped_call"
4901404b540aSrobert  [(parallel [(call (match_operand 0 "" "")
4902404b540aSrobert		    (const_int 0))
4903404b540aSrobert	      (match_operand 1 "" "")
4904404b540aSrobert	      (match_operand 2 "" "")])]
4905404b540aSrobert  ""
4906404b540aSrobert{
4907404b540aSrobert  int i;
4908404b540aSrobert
4909404b540aSrobert  emit_call_insn (GEN_CALL (operands[0], const0_rtx, NULL, const0_rtx));
4910404b540aSrobert
4911404b540aSrobert  for (i = 0; i < XVECLEN (operands[2], 0); i++)
4912404b540aSrobert    {
4913404b540aSrobert      rtx set = XVECEXP (operands[2], 0, i);
4914404b540aSrobert      emit_move_insn (SET_DEST (set), SET_SRC (set));
4915404b540aSrobert    }
4916404b540aSrobert
4917404b540aSrobert  /* The optimizer does not know that the call sets the function value
4918404b540aSrobert     registers we stored in the result block.  We avoid problems by
4919404b540aSrobert     claiming that all hard registers are used and clobbered at this
4920404b540aSrobert     point.  */
4921404b540aSrobert  emit_insn (gen_blockage ());
4922404b540aSrobert
4923404b540aSrobert  DONE;
4924404b540aSrobert})
4925404b540aSrobert
4926404b540aSrobert;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
4927404b540aSrobert;; all of memory.  This blocks insns from being moved across this point.
4928404b540aSrobert
4929404b540aSrobert(define_insn "blockage"
4930404b540aSrobert  [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
4931404b540aSrobert  ""
4932404b540aSrobert  ""
4933404b540aSrobert  [(set_attr "length" "0")
4934404b540aSrobert   (set_attr "type" "none")])
4935404b540aSrobert
4936404b540aSrobert(define_insn "jump"
4937404b540aSrobert  [(set (pc)
4938404b540aSrobert	(label_ref (match_operand 0 "" "")))]
4939404b540aSrobert  ""
4940404b540aSrobert  "br $31,%l0"
4941404b540aSrobert  [(set_attr "type" "ibr")])
4942404b540aSrobert
4943404b540aSrobert(define_expand "return"
4944404b540aSrobert  [(return)]
4945404b540aSrobert  "direct_return ()"
4946404b540aSrobert  "")
4947404b540aSrobert
4948404b540aSrobert(define_insn "*return_internal"
4949404b540aSrobert  [(return)]
4950404b540aSrobert  "reload_completed"
4951404b540aSrobert  "ret $31,($26),1"
4952404b540aSrobert  [(set_attr "type" "ibr")])
4953404b540aSrobert
4954404b540aSrobert(define_insn "indirect_jump"
4955404b540aSrobert  [(set (pc) (match_operand:DI 0 "register_operand" "r"))]
4956404b540aSrobert  ""
4957404b540aSrobert  "jmp $31,(%0),0"
4958404b540aSrobert  [(set_attr "type" "ibr")])
4959404b540aSrobert
4960404b540aSrobert(define_expand "tablejump"
4961404b540aSrobert  [(parallel [(set (pc)
4962404b540aSrobert		   (match_operand 0 "register_operand" ""))
4963404b540aSrobert	      (use (label_ref:DI (match_operand 1 "" "")))])]
4964404b540aSrobert  ""
4965404b540aSrobert{
4966404b540aSrobert  if (TARGET_ABI_WINDOWS_NT)
4967404b540aSrobert    {
4968404b540aSrobert      rtx dest = gen_reg_rtx (DImode);
4969404b540aSrobert      emit_insn (gen_extendsidi2 (dest, operands[0]));
4970404b540aSrobert      operands[0] = dest;
4971404b540aSrobert    }
4972404b540aSrobert  else if (TARGET_ABI_OSF)
4973404b540aSrobert    {
4974404b540aSrobert      rtx dest = gen_reg_rtx (DImode);
4975404b540aSrobert      emit_insn (gen_extendsidi2 (dest, operands[0]));
4976404b540aSrobert      emit_insn (gen_adddi3 (dest, pic_offset_table_rtx, dest));
4977404b540aSrobert      operands[0] = dest;
4978404b540aSrobert    }
4979404b540aSrobert})
4980404b540aSrobert
4981404b540aSrobert(define_insn "*tablejump_osf_nt_internal"
4982404b540aSrobert  [(set (pc)
4983404b540aSrobert	(match_operand:DI 0 "register_operand" "r"))
4984404b540aSrobert   (use (label_ref:DI (match_operand 1 "" "")))]
4985404b540aSrobert  "(TARGET_ABI_OSF || TARGET_ABI_WINDOWS_NT)
4986404b540aSrobert   && alpha_tablejump_addr_vec (insn)"
4987404b540aSrobert{
4988404b540aSrobert  operands[2] = alpha_tablejump_best_label (insn);
4989404b540aSrobert  return "jmp $31,(%0),%2";
4990404b540aSrobert}
4991404b540aSrobert  [(set_attr "type" "ibr")])
4992404b540aSrobert
4993404b540aSrobert(define_insn "*tablejump_internal"
4994404b540aSrobert  [(set (pc)
4995404b540aSrobert	(match_operand:DI 0 "register_operand" "r"))
4996404b540aSrobert   (use (label_ref (match_operand 1 "" "")))]
4997404b540aSrobert  ""
4998404b540aSrobert  "jmp $31,(%0),0"
4999404b540aSrobert  [(set_attr "type" "ibr")])
5000404b540aSrobert
5001404b540aSrobert;; Cache flush.  Used by INITIALIZE_TRAMPOLINE.  0x86 is PAL_imb, but we don't
5002404b540aSrobert;; want to have to include pal.h in our .s file.
5003404b540aSrobert;;
5004404b540aSrobert;; Technically the type for call_pal is jsr, but we use that for determining
5005404b540aSrobert;; if we need a GP.  Use ibr instead since it has the same EV5 scheduling
5006404b540aSrobert;; characteristics.
5007404b540aSrobert(define_insn "imb"
5008404b540aSrobert  [(unspec_volatile [(const_int 0)] UNSPECV_IMB)]
5009404b540aSrobert  ""
5010404b540aSrobert  "call_pal 0x86"
5011404b540aSrobert  [(set_attr "type" "callpal")])
5012404b540aSrobert
5013404b540aSrobert;; BUGCHK is documented common to OSF/1 and VMS PALcode.
5014404b540aSrobert;; NT does not document anything at 0x81 -- presumably it would generate
5015404b540aSrobert;; the equivalent of SIGILL, but this isn't that important.
5016404b540aSrobert;; ??? Presuming unicosmk uses either OSF/1 or VMS PALcode.
5017404b540aSrobert(define_insn "trap"
5018404b540aSrobert  [(trap_if (const_int 1) (const_int 0))]
5019404b540aSrobert  "!TARGET_ABI_WINDOWS_NT"
5020404b540aSrobert  "call_pal 0x81"
5021404b540aSrobert  [(set_attr "type" "callpal")])
5022404b540aSrobert
5023404b540aSrobert;; For userland, we load the thread pointer from the TCB.
5024404b540aSrobert;; For the kernel, we load the per-cpu private value.
5025404b540aSrobert
5026404b540aSrobert(define_insn "load_tp"
5027404b540aSrobert  [(set (match_operand:DI 0 "register_operand" "=v")
5028404b540aSrobert	(unspec:DI [(const_int 0)] UNSPEC_TP))]
5029404b540aSrobert  "TARGET_ABI_OSF"
5030404b540aSrobert{
5031404b540aSrobert  if (TARGET_TLS_KERNEL)
5032404b540aSrobert    return "call_pal 0x32";
5033404b540aSrobert  else
5034404b540aSrobert    return "call_pal 0x9e";
5035404b540aSrobert}
5036404b540aSrobert  [(set_attr "type" "callpal")])
5037404b540aSrobert
5038404b540aSrobert;; For completeness, and possibly a __builtin function, here's how to
5039404b540aSrobert;; set the thread pointer.  Since we don't describe enough of this
5040404b540aSrobert;; quantity for CSE, we have to use a volatile unspec, and then there's
5041404b540aSrobert;; not much point in creating an R16_REG register class.
5042404b540aSrobert
5043404b540aSrobert(define_expand "set_tp"
5044404b540aSrobert  [(set (reg:DI 16) (match_operand:DI 0 "input_operand" ""))
5045404b540aSrobert   (unspec_volatile [(reg:DI 16)] UNSPECV_SET_TP)]
5046404b540aSrobert  "TARGET_ABI_OSF"
5047404b540aSrobert  "")
5048404b540aSrobert
5049404b540aSrobert(define_insn "*set_tp"
5050404b540aSrobert  [(unspec_volatile [(reg:DI 16)] UNSPECV_SET_TP)]
5051404b540aSrobert  "TARGET_ABI_OSF"
5052404b540aSrobert{
5053404b540aSrobert  if (TARGET_TLS_KERNEL)
5054404b540aSrobert    return "call_pal 0x31";
5055404b540aSrobert  else
5056404b540aSrobert    return "call_pal 0x9f";
5057404b540aSrobert}
5058404b540aSrobert  [(set_attr "type" "callpal")])
5059404b540aSrobert
5060404b540aSrobert;; Finally, we have the basic data motion insns.  The byte and word insns
5061404b540aSrobert;; are done via define_expand.  Start with the floating-point insns, since
5062404b540aSrobert;; they are simpler.
5063404b540aSrobert
5064404b540aSrobert(define_insn "*movsf_nofix"
5065404b540aSrobert  [(set (match_operand:SF 0 "nonimmediate_operand" "=f,f,*r,*r,m,m")
5066404b540aSrobert	(match_operand:SF 1 "input_operand" "fG,m,*rG,m,fG,*r"))]
5067404b540aSrobert  "TARGET_FPREGS && ! TARGET_FIX
5068404b540aSrobert   && (register_operand (operands[0], SFmode)
5069404b540aSrobert       || reg_or_0_operand (operands[1], SFmode))"
5070404b540aSrobert  "@
5071404b540aSrobert   cpys %R1,%R1,%0
5072404b540aSrobert   ld%, %0,%1
5073404b540aSrobert   bis $31,%r1,%0
5074404b540aSrobert   ldl %0,%1
5075404b540aSrobert   st%, %R1,%0
5076404b540aSrobert   stl %r1,%0"
5077404b540aSrobert  [(set_attr "type" "fcpys,fld,ilog,ild,fst,ist")])
5078404b540aSrobert
5079404b540aSrobert(define_insn "*movsf_fix"
5080404b540aSrobert  [(set (match_operand:SF 0 "nonimmediate_operand" "=f,f,*r,*r,m,m,f,*r")
5081404b540aSrobert	(match_operand:SF 1 "input_operand" "fG,m,*rG,m,fG,*r,*r,f"))]
5082404b540aSrobert  "TARGET_FPREGS && TARGET_FIX
5083404b540aSrobert   && (register_operand (operands[0], SFmode)
5084404b540aSrobert       || reg_or_0_operand (operands[1], SFmode))"
5085404b540aSrobert  "@
5086404b540aSrobert   cpys %R1,%R1,%0
5087404b540aSrobert   ld%, %0,%1
5088404b540aSrobert   bis $31,%r1,%0
5089404b540aSrobert   ldl %0,%1
5090404b540aSrobert   st%, %R1,%0
5091404b540aSrobert   stl %r1,%0
5092404b540aSrobert   itofs %1,%0
5093404b540aSrobert   ftois %1,%0"
5094404b540aSrobert  [(set_attr "type" "fcpys,fld,ilog,ild,fst,ist,itof,ftoi")])
5095404b540aSrobert
5096404b540aSrobert(define_insn "*movsf_nofp"
5097404b540aSrobert  [(set (match_operand:SF 0 "nonimmediate_operand" "=r,r,m")
5098404b540aSrobert	(match_operand:SF 1 "input_operand" "rG,m,r"))]
5099404b540aSrobert  "! TARGET_FPREGS
5100404b540aSrobert   && (register_operand (operands[0], SFmode)
5101404b540aSrobert       || reg_or_0_operand (operands[1], SFmode))"
5102404b540aSrobert  "@
5103404b540aSrobert   bis $31,%r1,%0
5104404b540aSrobert   ldl %0,%1
5105404b540aSrobert   stl %r1,%0"
5106404b540aSrobert  [(set_attr "type" "ilog,ild,ist")])
5107404b540aSrobert
5108404b540aSrobert(define_insn "*movdf_nofix"
5109404b540aSrobert  [(set (match_operand:DF 0 "nonimmediate_operand" "=f,f,*r,*r,m,m")
5110404b540aSrobert	(match_operand:DF 1 "input_operand" "fG,m,*rG,m,fG,*r"))]
5111404b540aSrobert  "TARGET_FPREGS && ! TARGET_FIX
5112404b540aSrobert   && (register_operand (operands[0], DFmode)
5113404b540aSrobert       || reg_or_0_operand (operands[1], DFmode))"
5114404b540aSrobert  "@
5115404b540aSrobert   cpys %R1,%R1,%0
5116404b540aSrobert   ld%- %0,%1
5117404b540aSrobert   bis $31,%r1,%0
5118404b540aSrobert   ldq %0,%1
5119404b540aSrobert   st%- %R1,%0
5120404b540aSrobert   stq %r1,%0"
5121404b540aSrobert  [(set_attr "type" "fcpys,fld,ilog,ild,fst,ist")])
5122404b540aSrobert
5123404b540aSrobert(define_insn "*movdf_fix"
5124404b540aSrobert  [(set (match_operand:DF 0 "nonimmediate_operand" "=f,f,*r,*r,m,m,f,*r")
5125404b540aSrobert	(match_operand:DF 1 "input_operand" "fG,m,*rG,m,fG,*r,*r,f"))]
5126404b540aSrobert  "TARGET_FPREGS && TARGET_FIX
5127404b540aSrobert   && (register_operand (operands[0], DFmode)
5128404b540aSrobert       || reg_or_0_operand (operands[1], DFmode))"
5129404b540aSrobert  "@
5130404b540aSrobert   cpys %R1,%R1,%0
5131404b540aSrobert   ld%- %0,%1
5132404b540aSrobert   bis $31,%r1,%0
5133404b540aSrobert   ldq %0,%1
5134404b540aSrobert   st%- %R1,%0
5135404b540aSrobert   stq %r1,%0
5136404b540aSrobert   itoft %1,%0
5137404b540aSrobert   ftoit %1,%0"
5138404b540aSrobert  [(set_attr "type" "fcpys,fld,ilog,ild,fst,ist,itof,ftoi")])
5139404b540aSrobert
5140404b540aSrobert(define_insn "*movdf_nofp"
5141404b540aSrobert  [(set (match_operand:DF 0 "nonimmediate_operand" "=r,r,m")
5142404b540aSrobert	(match_operand:DF 1 "input_operand" "rG,m,r"))]
5143404b540aSrobert  "! TARGET_FPREGS
5144404b540aSrobert   && (register_operand (operands[0], DFmode)
5145404b540aSrobert       || reg_or_0_operand (operands[1], DFmode))"
5146404b540aSrobert  "@
5147404b540aSrobert   bis $31,%r1,%0
5148404b540aSrobert   ldq %0,%1
5149404b540aSrobert   stq %r1,%0"
5150404b540aSrobert  [(set_attr "type" "ilog,ild,ist")])
5151404b540aSrobert
5152404b540aSrobert;; Subregs suck for register allocation.  Pretend we can move TFmode
5153404b540aSrobert;; data between general registers until after reload.
5154404b540aSrobert
5155404b540aSrobert(define_insn_and_split "*movtf_internal"
5156404b540aSrobert  [(set (match_operand:TF 0 "nonimmediate_operand" "=r,o")
5157404b540aSrobert	(match_operand:TF 1 "input_operand" "roG,rG"))]
5158404b540aSrobert  "register_operand (operands[0], TFmode)
5159404b540aSrobert   || reg_or_0_operand (operands[1], TFmode)"
5160404b540aSrobert  "#"
5161404b540aSrobert  "reload_completed"
5162404b540aSrobert  [(set (match_dup 0) (match_dup 2))
5163404b540aSrobert   (set (match_dup 1) (match_dup 3))]
5164404b540aSrobert{
5165404b540aSrobert  alpha_split_tmode_pair (operands, TFmode, true);
5166404b540aSrobert})
5167404b540aSrobert
5168404b540aSrobert(define_expand "movsf"
5169404b540aSrobert  [(set (match_operand:SF 0 "nonimmediate_operand" "")
5170404b540aSrobert	(match_operand:SF 1 "general_operand" ""))]
5171404b540aSrobert  ""
5172404b540aSrobert{
5173404b540aSrobert  if (GET_CODE (operands[0]) == MEM
5174404b540aSrobert      && ! reg_or_0_operand (operands[1], SFmode))
5175404b540aSrobert    operands[1] = force_reg (SFmode, operands[1]);
5176404b540aSrobert})
5177404b540aSrobert
5178404b540aSrobert(define_expand "movdf"
5179404b540aSrobert  [(set (match_operand:DF 0 "nonimmediate_operand" "")
5180404b540aSrobert	(match_operand:DF 1 "general_operand" ""))]
5181404b540aSrobert  ""
5182404b540aSrobert{
5183404b540aSrobert  if (GET_CODE (operands[0]) == MEM
5184404b540aSrobert      && ! reg_or_0_operand (operands[1], DFmode))
5185404b540aSrobert    operands[1] = force_reg (DFmode, operands[1]);
5186404b540aSrobert})
5187404b540aSrobert
5188404b540aSrobert(define_expand "movtf"
5189404b540aSrobert  [(set (match_operand:TF 0 "nonimmediate_operand" "")
5190404b540aSrobert	(match_operand:TF 1 "general_operand" ""))]
5191404b540aSrobert  ""
5192404b540aSrobert{
5193404b540aSrobert  if (GET_CODE (operands[0]) == MEM
5194404b540aSrobert      && ! reg_or_0_operand (operands[1], TFmode))
5195404b540aSrobert    operands[1] = force_reg (TFmode, operands[1]);
5196404b540aSrobert})
5197404b540aSrobert
5198404b540aSrobert(define_insn "*movsi"
5199404b540aSrobert  [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,r,r,r,m")
5200404b540aSrobert	(match_operand:SI 1 "input_operand" "rJ,K,L,n,m,rJ"))]
5201404b540aSrobert  "(TARGET_ABI_OSF || TARGET_ABI_UNICOSMK)
5202404b540aSrobert   && (register_operand (operands[0], SImode)
5203404b540aSrobert       || reg_or_0_operand (operands[1], SImode))"
5204404b540aSrobert  "@
5205404b540aSrobert   bis $31,%r1,%0
5206404b540aSrobert   lda %0,%1($31)
5207404b540aSrobert   ldah %0,%h1($31)
5208404b540aSrobert   #
5209404b540aSrobert   ldl %0,%1
5210404b540aSrobert   stl %r1,%0"
5211404b540aSrobert  [(set_attr "type" "ilog,iadd,iadd,multi,ild,ist")])
5212404b540aSrobert
5213404b540aSrobert(define_insn "*movsi_nt_vms"
5214404b540aSrobert  [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,r,r,r,r,m")
5215404b540aSrobert	(match_operand:SI 1 "input_operand" "rJ,K,L,s,n,m,rJ"))]
5216404b540aSrobert  "(TARGET_ABI_WINDOWS_NT || TARGET_ABI_OPEN_VMS)
5217404b540aSrobert    && (register_operand (operands[0], SImode)
5218404b540aSrobert        || reg_or_0_operand (operands[1], SImode))"
5219404b540aSrobert  "@
5220404b540aSrobert   bis $31,%1,%0
5221404b540aSrobert   lda %0,%1
5222404b540aSrobert   ldah %0,%h1
5223404b540aSrobert   lda %0,%1
5224404b540aSrobert   #
5225404b540aSrobert   ldl %0,%1
5226404b540aSrobert   stl %r1,%0"
5227404b540aSrobert  [(set_attr "type" "ilog,iadd,iadd,ldsym,multi,ild,ist")])
5228404b540aSrobert
5229404b540aSrobert(define_insn "*movhi_nobwx"
5230404b540aSrobert  [(set (match_operand:HI 0 "register_operand" "=r,r")
5231404b540aSrobert	(match_operand:HI 1 "input_operand" "rJ,n"))]
5232404b540aSrobert  "! TARGET_BWX
5233404b540aSrobert   && (register_operand (operands[0], HImode)
5234404b540aSrobert       || register_operand (operands[1], HImode))"
5235404b540aSrobert  "@
5236404b540aSrobert   bis $31,%r1,%0
5237404b540aSrobert   lda %0,%L1($31)"
5238404b540aSrobert  [(set_attr "type" "ilog,iadd")])
5239404b540aSrobert
5240404b540aSrobert(define_insn "*movhi_bwx"
5241404b540aSrobert  [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
5242404b540aSrobert	(match_operand:HI 1 "input_operand" "rJ,n,m,rJ"))]
5243404b540aSrobert  "TARGET_BWX
5244404b540aSrobert   && (register_operand (operands[0], HImode)
5245404b540aSrobert       || reg_or_0_operand (operands[1], HImode))"
5246404b540aSrobert  "@
5247404b540aSrobert   bis $31,%r1,%0
5248404b540aSrobert   lda %0,%L1($31)
5249404b540aSrobert   ldwu %0,%1
5250404b540aSrobert   stw %r1,%0"
5251404b540aSrobert  [(set_attr "type" "ilog,iadd,ild,ist")])
5252404b540aSrobert
5253404b540aSrobert(define_insn "*movqi_nobwx"
5254404b540aSrobert  [(set (match_operand:QI 0 "register_operand" "=r,r")
5255404b540aSrobert	(match_operand:QI 1 "input_operand" "rJ,n"))]
5256404b540aSrobert  "! TARGET_BWX
5257404b540aSrobert   && (register_operand (operands[0], QImode)
5258404b540aSrobert       || register_operand (operands[1], QImode))"
5259404b540aSrobert  "@
5260404b540aSrobert   bis $31,%r1,%0
5261404b540aSrobert   lda %0,%L1($31)"
5262404b540aSrobert  [(set_attr "type" "ilog,iadd")])
5263404b540aSrobert
5264404b540aSrobert(define_insn "*movqi_bwx"
5265404b540aSrobert  [(set (match_operand:QI 0 "nonimmediate_operand" "=r,r,r,m")
5266404b540aSrobert	(match_operand:QI 1 "input_operand" "rJ,n,m,rJ"))]
5267404b540aSrobert  "TARGET_BWX
5268404b540aSrobert   && (register_operand (operands[0], QImode)
5269404b540aSrobert       || reg_or_0_operand (operands[1], QImode))"
5270404b540aSrobert  "@
5271404b540aSrobert   bis $31,%r1,%0
5272404b540aSrobert   lda %0,%L1($31)
5273404b540aSrobert   ldbu %0,%1
5274404b540aSrobert   stb %r1,%0"
5275404b540aSrobert  [(set_attr "type" "ilog,iadd,ild,ist")])
5276404b540aSrobert
5277404b540aSrobert;; We do two major things here: handle mem->mem and construct long
5278404b540aSrobert;; constants.
5279404b540aSrobert
5280404b540aSrobert(define_expand "movsi"
5281404b540aSrobert  [(set (match_operand:SI 0 "nonimmediate_operand" "")
5282404b540aSrobert	(match_operand:SI 1 "general_operand" ""))]
5283404b540aSrobert  ""
5284404b540aSrobert{
5285404b540aSrobert  if (alpha_expand_mov (SImode, operands))
5286404b540aSrobert    DONE;
5287404b540aSrobert})
5288404b540aSrobert
5289404b540aSrobert;; Split a load of a large constant into the appropriate two-insn
5290404b540aSrobert;; sequence.
5291404b540aSrobert
5292404b540aSrobert(define_split
5293404b540aSrobert  [(set (match_operand:SI 0 "register_operand" "")
5294404b540aSrobert	(match_operand:SI 1 "non_add_const_operand" ""))]
5295404b540aSrobert  ""
5296404b540aSrobert  [(const_int 0)]
5297404b540aSrobert{
5298404b540aSrobert  if (alpha_split_const_mov (SImode, operands))
5299404b540aSrobert    DONE;
5300404b540aSrobert  else
5301404b540aSrobert    FAIL;
5302404b540aSrobert})
5303404b540aSrobert
5304404b540aSrobert;; Split the load of an address into a four-insn sequence on Unicos/Mk.
5305404b540aSrobert;; Always generate a REG_EQUAL note for the last instruction to facilitate
5306404b540aSrobert;; optimizations. If the symbolic operand is a label_ref, generate REG_LABEL
5307404b540aSrobert;; notes and update LABEL_NUSES because this is not done automatically.
5308404b540aSrobert;; Labels may be incorrectly deleted if we don't do this.
5309404b540aSrobert;;
5310404b540aSrobert;; Describing what the individual instructions do correctly is too complicated
5311404b540aSrobert;; so use UNSPECs for each of the three parts of an address.
5312404b540aSrobert
5313404b540aSrobert(define_split
5314404b540aSrobert  [(set (match_operand:DI 0 "register_operand" "")
5315404b540aSrobert	(match_operand:DI 1 "symbolic_operand" ""))]
5316404b540aSrobert  "TARGET_ABI_UNICOSMK && reload_completed"
5317404b540aSrobert  [(const_int 0)]
5318404b540aSrobert{
5319404b540aSrobert  rtx insn1, insn2, insn3;
5320404b540aSrobert
5321404b540aSrobert  insn1 = emit_insn (gen_umk_laum (operands[0], operands[1]));
5322404b540aSrobert  emit_insn (gen_ashldi3 (operands[0], operands[0], GEN_INT (32)));
5323404b540aSrobert  insn2 = emit_insn (gen_umk_lalm (operands[0], operands[0], operands[1]));
5324404b540aSrobert  insn3 = emit_insn (gen_umk_lal (operands[0], operands[0], operands[1]));
5325404b540aSrobert  REG_NOTES (insn3) = gen_rtx_EXPR_LIST (REG_EQUAL, operands[1],
5326404b540aSrobert					 REG_NOTES (insn3));
5327404b540aSrobert  if (GET_CODE (operands[1]) == LABEL_REF)
5328404b540aSrobert    {
5329404b540aSrobert      rtx label;
5330404b540aSrobert
5331404b540aSrobert      label = XEXP (operands[1], 0);
5332404b540aSrobert      REG_NOTES (insn1) = gen_rtx_EXPR_LIST (REG_LABEL, label,
5333404b540aSrobert					     REG_NOTES (insn1));
5334404b540aSrobert      REG_NOTES (insn2) = gen_rtx_EXPR_LIST (REG_LABEL, label,
5335404b540aSrobert					     REG_NOTES (insn2));
5336404b540aSrobert      REG_NOTES (insn3) = gen_rtx_EXPR_LIST (REG_LABEL, label,
5337404b540aSrobert					     REG_NOTES (insn3));
5338404b540aSrobert      LABEL_NUSES (label) += 3;
5339404b540aSrobert    }
5340404b540aSrobert  DONE;
5341404b540aSrobert})
5342404b540aSrobert
5343404b540aSrobert;; Instructions for loading the three parts of an address on Unicos/Mk.
5344404b540aSrobert
5345404b540aSrobert(define_insn "umk_laum"
5346404b540aSrobert  [(set (match_operand:DI 0 "register_operand" "=r")
5347404b540aSrobert	(unspec:DI [(match_operand:DI 1 "symbolic_operand" "")]
5348404b540aSrobert		   UNSPEC_UMK_LAUM))]
5349404b540aSrobert  "TARGET_ABI_UNICOSMK"
5350404b540aSrobert  "laum %r0,%t1($31)"
5351404b540aSrobert  [(set_attr "type" "iadd")])
5352404b540aSrobert
5353404b540aSrobert(define_insn "umk_lalm"
5354404b540aSrobert  [(set (match_operand:DI 0 "register_operand" "=r")
5355404b540aSrobert	(plus:DI (match_operand:DI 1 "register_operand" "r")
5356404b540aSrobert		 (unspec:DI [(match_operand:DI 2 "symbolic_operand" "")]
5357404b540aSrobert			    UNSPEC_UMK_LALM)))]
5358404b540aSrobert  "TARGET_ABI_UNICOSMK"
5359404b540aSrobert  "lalm %r0,%t2(%r1)"
5360404b540aSrobert  [(set_attr "type" "iadd")])
5361404b540aSrobert
5362404b540aSrobert(define_insn "umk_lal"
5363404b540aSrobert  [(set (match_operand:DI 0 "register_operand" "=r")
5364404b540aSrobert	(plus:DI (match_operand:DI 1 "register_operand" "r")
5365404b540aSrobert		 (unspec:DI [(match_operand:DI 2 "symbolic_operand" "")]
5366404b540aSrobert			    UNSPEC_UMK_LAL)))]
5367404b540aSrobert  "TARGET_ABI_UNICOSMK"
5368404b540aSrobert  "lal %r0,%t2(%r1)"
5369404b540aSrobert  [(set_attr "type" "iadd")])
5370404b540aSrobert
5371404b540aSrobert;; Add a new call information word to the current function's list of CIWs
5372404b540aSrobert;; and load its index into $25. Doing it here ensures that the CIW will be
5373404b540aSrobert;; associated with the correct function even in the presence of inlining.
5374404b540aSrobert
5375404b540aSrobert(define_insn "*umk_load_ciw"
5376404b540aSrobert  [(set (reg:DI 25)
5377404b540aSrobert	(unspec:DI [(match_operand 0 "" "")] UNSPEC_UMK_LOAD_CIW))]
5378404b540aSrobert  "TARGET_ABI_UNICOSMK"
5379404b540aSrobert{
5380404b540aSrobert  operands[0] = unicosmk_add_call_info_word (operands[0]);
5381404b540aSrobert  return "lda $25,%0";
5382404b540aSrobert}
5383404b540aSrobert  [(set_attr "type" "iadd")])
5384404b540aSrobert
5385404b540aSrobert(define_insn "*movdi_er_low_l"
5386404b540aSrobert  [(set (match_operand:DI 0 "register_operand" "=r")
5387404b540aSrobert	(lo_sum:DI (match_operand:DI 1 "register_operand" "r")
5388404b540aSrobert		   (match_operand:DI 2 "local_symbolic_operand" "")))]
5389404b540aSrobert  "TARGET_EXPLICIT_RELOCS"
5390404b540aSrobert{
5391404b540aSrobert  if (true_regnum (operands[1]) == 29)
5392404b540aSrobert    return "lda %0,%2(%1)\t\t!gprel";
5393404b540aSrobert  else
5394404b540aSrobert    return "lda %0,%2(%1)\t\t!gprellow";
5395404b540aSrobert}
5396404b540aSrobert  [(set_attr "usegp" "yes")])
5397404b540aSrobert
5398404b540aSrobert(define_split
5399404b540aSrobert  [(set (match_operand:DI 0 "register_operand" "")
5400404b540aSrobert	(match_operand:DI 1 "small_symbolic_operand" ""))]
5401404b540aSrobert  "TARGET_EXPLICIT_RELOCS && reload_completed"
5402404b540aSrobert  [(set (match_dup 0)
5403404b540aSrobert	(lo_sum:DI (match_dup 2) (match_dup 1)))]
5404404b540aSrobert  "operands[2] = pic_offset_table_rtx;")
5405404b540aSrobert
5406404b540aSrobert(define_split
5407404b540aSrobert  [(set (match_operand:DI 0 "register_operand" "")
5408404b540aSrobert	(match_operand:DI 1 "local_symbolic_operand" ""))]
5409404b540aSrobert  "TARGET_EXPLICIT_RELOCS && reload_completed"
5410404b540aSrobert  [(set (match_dup 0)
5411404b540aSrobert	(plus:DI (match_dup 2) (high:DI (match_dup 1))))
5412404b540aSrobert   (set (match_dup 0)
5413404b540aSrobert	(lo_sum:DI (match_dup 0) (match_dup 1)))]
5414404b540aSrobert  "operands[2] = pic_offset_table_rtx;")
5415404b540aSrobert
5416404b540aSrobert(define_split
5417404b540aSrobert  [(match_operand 0 "some_small_symbolic_operand" "")]
5418404b540aSrobert  ""
5419404b540aSrobert  [(match_dup 0)]
5420404b540aSrobert  "operands[0] = split_small_symbolic_operand (operands[0]);")
5421404b540aSrobert
5422404b540aSrobert;; Accepts any symbolic, not just global, since function calls that
5423404b540aSrobert;; don't go via bsr still use !literal in hopes of linker relaxation.
5424404b540aSrobert(define_insn "movdi_er_high_g"
5425404b540aSrobert  [(set (match_operand:DI 0 "register_operand" "=r")
5426404b540aSrobert	(unspec:DI [(match_operand:DI 1 "register_operand" "r")
5427404b540aSrobert		    (match_operand:DI 2 "symbolic_operand" "")
5428404b540aSrobert		    (match_operand 3 "const_int_operand" "")]
5429404b540aSrobert		   UNSPEC_LITERAL))]
5430404b540aSrobert  "TARGET_EXPLICIT_RELOCS"
5431404b540aSrobert{
5432404b540aSrobert  if (INTVAL (operands[3]) == 0)
5433404b540aSrobert    return "ldq %0,%2(%1)\t\t!literal";
5434404b540aSrobert  else
5435404b540aSrobert    return "ldq %0,%2(%1)\t\t!literal!%3";
5436404b540aSrobert}
5437404b540aSrobert  [(set_attr "type" "ldsym")])
5438404b540aSrobert
5439404b540aSrobert(define_split
5440404b540aSrobert  [(set (match_operand:DI 0 "register_operand" "")
5441404b540aSrobert	(match_operand:DI 1 "global_symbolic_operand" ""))]
5442404b540aSrobert  "TARGET_EXPLICIT_RELOCS && reload_completed"
5443404b540aSrobert  [(set (match_dup 0)
5444404b540aSrobert	(unspec:DI [(match_dup 2)
5445404b540aSrobert		    (match_dup 1)
5446404b540aSrobert		    (const_int 0)] UNSPEC_LITERAL))]
5447404b540aSrobert  "operands[2] = pic_offset_table_rtx;")
5448404b540aSrobert
5449404b540aSrobert(define_insn "movdi_er_tlsgd"
5450404b540aSrobert  [(set (match_operand:DI 0 "register_operand" "=r")
5451404b540aSrobert	(unspec:DI [(match_operand:DI 1 "register_operand" "r")
5452404b540aSrobert		    (match_operand:DI 2 "symbolic_operand" "")
5453404b540aSrobert		    (match_operand 3 "const_int_operand" "")]
5454404b540aSrobert		   UNSPEC_TLSGD))]
5455404b540aSrobert  "HAVE_AS_TLS"
5456404b540aSrobert{
5457404b540aSrobert  if (INTVAL (operands[3]) == 0)
5458404b540aSrobert    return "lda %0,%2(%1)\t\t!tlsgd";
5459404b540aSrobert  else
5460404b540aSrobert    return "lda %0,%2(%1)\t\t!tlsgd!%3";
5461404b540aSrobert})
5462404b540aSrobert
5463404b540aSrobert(define_insn "movdi_er_tlsldm"
5464404b540aSrobert  [(set (match_operand:DI 0 "register_operand" "=r")
5465404b540aSrobert	(unspec:DI [(match_operand:DI 1 "register_operand" "r")
5466404b540aSrobert		    (match_operand 2 "const_int_operand" "")]
5467404b540aSrobert		   UNSPEC_TLSLDM))]
5468404b540aSrobert  "HAVE_AS_TLS"
5469404b540aSrobert{
5470404b540aSrobert  if (INTVAL (operands[2]) == 0)
5471404b540aSrobert    return "lda %0,%&(%1)\t\t!tlsldm";
5472404b540aSrobert  else
5473404b540aSrobert    return "lda %0,%&(%1)\t\t!tlsldm!%2";
5474404b540aSrobert})
5475404b540aSrobert
5476404b540aSrobert(define_insn "*movdi_er_gotdtp"
5477404b540aSrobert  [(set (match_operand:DI 0 "register_operand" "=r")
5478404b540aSrobert	(unspec:DI [(match_operand:DI 1 "register_operand" "r")
5479404b540aSrobert		    (match_operand:DI 2 "symbolic_operand" "")]
5480404b540aSrobert		   UNSPEC_DTPREL))]
5481404b540aSrobert  "HAVE_AS_TLS"
5482404b540aSrobert  "ldq %0,%2(%1)\t\t!gotdtprel"
5483404b540aSrobert  [(set_attr "type" "ild")
5484404b540aSrobert   (set_attr "usegp" "yes")])
5485404b540aSrobert
5486404b540aSrobert(define_split
5487404b540aSrobert  [(set (match_operand:DI 0 "register_operand" "")
5488404b540aSrobert	(match_operand:DI 1 "gotdtp_symbolic_operand" ""))]
5489404b540aSrobert  "HAVE_AS_TLS && reload_completed"
5490404b540aSrobert  [(set (match_dup 0)
5491404b540aSrobert	(unspec:DI [(match_dup 2)
5492404b540aSrobert		    (match_dup 1)] UNSPEC_DTPREL))]
5493404b540aSrobert{
5494404b540aSrobert  operands[1] = XVECEXP (XEXP (operands[1], 0), 0, 0);
5495404b540aSrobert  operands[2] = pic_offset_table_rtx;
5496404b540aSrobert})
5497404b540aSrobert
5498404b540aSrobert(define_insn "*movdi_er_gottp"
5499404b540aSrobert  [(set (match_operand:DI 0 "register_operand" "=r")
5500404b540aSrobert	(unspec:DI [(match_operand:DI 1 "register_operand" "r")
5501404b540aSrobert		    (match_operand:DI 2 "symbolic_operand" "")]
5502404b540aSrobert		   UNSPEC_TPREL))]
5503404b540aSrobert  "HAVE_AS_TLS"
5504404b540aSrobert  "ldq %0,%2(%1)\t\t!gottprel"
5505404b540aSrobert  [(set_attr "type" "ild")
5506404b540aSrobert   (set_attr "usegp" "yes")])
5507404b540aSrobert
5508404b540aSrobert(define_split
5509404b540aSrobert  [(set (match_operand:DI 0 "register_operand" "")
5510404b540aSrobert	(match_operand:DI 1 "gottp_symbolic_operand" ""))]
5511404b540aSrobert  "HAVE_AS_TLS && reload_completed"
5512404b540aSrobert  [(set (match_dup 0)
5513404b540aSrobert	(unspec:DI [(match_dup 2)
5514404b540aSrobert		    (match_dup 1)] UNSPEC_TPREL))]
5515404b540aSrobert{
5516404b540aSrobert  operands[1] = XVECEXP (XEXP (operands[1], 0), 0, 0);
5517404b540aSrobert  operands[2] = pic_offset_table_rtx;
5518404b540aSrobert})
5519404b540aSrobert
5520404b540aSrobert(define_insn "*movdi_er_nofix"
5521404b540aSrobert  [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,r,r,r,r,r,m,*f,*f,Q")
5522404b540aSrobert	(match_operand:DI 1 "input_operand" "rJ,K,L,T,s,n,m,rJ,*fJ,Q,*f"))]
5523404b540aSrobert  "TARGET_EXPLICIT_RELOCS && ! TARGET_FIX
5524404b540aSrobert   && (register_operand (operands[0], DImode)
5525404b540aSrobert       || reg_or_0_operand (operands[1], DImode))"
5526404b540aSrobert  "@
5527404b540aSrobert   mov %r1,%0
5528404b540aSrobert   lda %0,%1($31)
5529404b540aSrobert   ldah %0,%h1($31)
5530404b540aSrobert   #
5531404b540aSrobert   #
5532404b540aSrobert   #
5533404b540aSrobert   ldq%A1 %0,%1
5534404b540aSrobert   stq%A0 %r1,%0
5535404b540aSrobert   fmov %R1,%0
5536404b540aSrobert   ldt %0,%1
5537404b540aSrobert   stt %R1,%0"
5538404b540aSrobert  [(set_attr "type" "ilog,iadd,iadd,iadd,ldsym,multi,ild,ist,fcpys,fld,fst")
5539404b540aSrobert   (set_attr "usegp" "*,*,*,yes,*,*,*,*,*,*,*")])
5540404b540aSrobert
5541404b540aSrobert;; The 'U' constraint matches symbolic operands on Unicos/Mk. Those should
5542404b540aSrobert;; have been split up by the rules above but we shouldn't reject the
5543404b540aSrobert;; possibility of them getting through.
5544404b540aSrobert
5545404b540aSrobert(define_insn "*movdi_nofix"
5546404b540aSrobert  [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,r,r,r,r,r,m,*f,*f,Q")
5547404b540aSrobert	(match_operand:DI 1 "input_operand" "rJ,K,L,U,s,n,m,rJ,*fJ,Q,*f"))]
5548404b540aSrobert  "! TARGET_FIX
5549404b540aSrobert   && (register_operand (operands[0], DImode)
5550404b540aSrobert       || reg_or_0_operand (operands[1], DImode))"
5551404b540aSrobert  "@
5552404b540aSrobert   bis $31,%r1,%0
5553404b540aSrobert   lda %0,%1($31)
5554404b540aSrobert   ldah %0,%h1($31)
5555404b540aSrobert   laum %0,%t1($31)\;sll %0,32,%0\;lalm %0,%t1(%0)\;lal %0,%t1(%0)
5556404b540aSrobert   lda %0,%1
5557404b540aSrobert   #
5558404b540aSrobert   ldq%A1 %0,%1
5559404b540aSrobert   stq%A0 %r1,%0
5560404b540aSrobert   cpys %R1,%R1,%0
5561404b540aSrobert   ldt %0,%1
5562404b540aSrobert   stt %R1,%0"
5563404b540aSrobert  [(set_attr "type" "ilog,iadd,iadd,ldsym,ldsym,multi,ild,ist,fcpys,fld,fst")
5564404b540aSrobert   (set_attr "length" "*,*,*,16,*,*,*,*,*,*,*")])
5565404b540aSrobert
5566404b540aSrobert(define_insn "*movdi_er_fix"
5567404b540aSrobert  [(set (match_operand:DI 0 "nonimmediate_operand"
5568404b540aSrobert				"=r,r,r,r,r,r,r, m, *f,*f, Q, r,*f")
5569404b540aSrobert	(match_operand:DI 1 "input_operand"
5570404b540aSrobert				"rJ,K,L,T,s,n,m,rJ,*fJ, Q,*f,*f, r"))]
5571404b540aSrobert  "TARGET_EXPLICIT_RELOCS && TARGET_FIX
5572404b540aSrobert   && (register_operand (operands[0], DImode)
5573404b540aSrobert       || reg_or_0_operand (operands[1], DImode))"
5574404b540aSrobert  "@
5575404b540aSrobert   mov %r1,%0
5576404b540aSrobert   lda %0,%1($31)
5577404b540aSrobert   ldah %0,%h1($31)
5578404b540aSrobert   #
5579404b540aSrobert   #
5580404b540aSrobert   #
5581404b540aSrobert   ldq%A1 %0,%1
5582404b540aSrobert   stq%A0 %r1,%0
5583404b540aSrobert   fmov %R1,%0
5584404b540aSrobert   ldt %0,%1
5585404b540aSrobert   stt %R1,%0
5586404b540aSrobert   ftoit %1,%0
5587404b540aSrobert   itoft %1,%0"
5588404b540aSrobert  [(set_attr "type" "ilog,iadd,iadd,iadd,ldsym,multi,ild,ist,fcpys,fld,fst,ftoi,itof")
5589404b540aSrobert   (set_attr "usegp" "*,*,*,yes,*,*,*,*,*,*,*,*,*")])
5590404b540aSrobert
5591404b540aSrobert(define_insn "*movdi_fix"
5592404b540aSrobert  [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,r,r,r,r,m,*f,*f,Q,r,*f")
5593404b540aSrobert	(match_operand:DI 1 "input_operand" "rJ,K,L,s,n,m,rJ,*fJ,Q,*f,*f,r"))]
5594404b540aSrobert  "! TARGET_EXPLICIT_RELOCS && TARGET_FIX
5595404b540aSrobert   && (register_operand (operands[0], DImode)
5596404b540aSrobert       || reg_or_0_operand (operands[1], DImode))"
5597404b540aSrobert  "@
5598404b540aSrobert   bis $31,%r1,%0
5599404b540aSrobert   lda %0,%1($31)
5600404b540aSrobert   ldah %0,%h1($31)
5601404b540aSrobert   lda %0,%1
5602404b540aSrobert   #
5603404b540aSrobert   ldq%A1 %0,%1
5604404b540aSrobert   stq%A0 %r1,%0
5605404b540aSrobert   cpys %R1,%R1,%0
5606404b540aSrobert   ldt %0,%1
5607404b540aSrobert   stt %R1,%0
5608404b540aSrobert   ftoit %1,%0
5609404b540aSrobert   itoft %1,%0"
5610404b540aSrobert  [(set_attr "type" "ilog,iadd,iadd,ldsym,multi,ild,ist,fcpys,fld,fst,ftoi,itof")])
5611404b540aSrobert
5612404b540aSrobert;; VMS needs to set up "vms_base_regno" for unwinding.  This move
5613404b540aSrobert;; often appears dead to the life analysis code, at which point we
5614404b540aSrobert;; die for emitting dead prologue instructions.  Force this live.
5615404b540aSrobert
5616404b540aSrobert(define_insn "force_movdi"
5617404b540aSrobert  [(set (match_operand:DI 0 "register_operand" "=r")
5618404b540aSrobert	(unspec_volatile:DI [(match_operand:DI 1 "register_operand" "r")]
5619404b540aSrobert			    UNSPECV_FORCE_MOV))]
5620404b540aSrobert  ""
5621404b540aSrobert  "mov %1,%0"
5622404b540aSrobert  [(set_attr "type" "ilog")])
5623404b540aSrobert
5624404b540aSrobert;; We do three major things here: handle mem->mem, put 64-bit constants in
5625404b540aSrobert;; memory, and construct long 32-bit constants.
5626404b540aSrobert
5627404b540aSrobert(define_expand "movdi"
5628404b540aSrobert  [(set (match_operand:DI 0 "nonimmediate_operand" "")
5629404b540aSrobert	(match_operand:DI 1 "general_operand" ""))]
5630404b540aSrobert  ""
5631404b540aSrobert{
5632404b540aSrobert  if (alpha_expand_mov (DImode, operands))
5633404b540aSrobert    DONE;
5634404b540aSrobert})
5635404b540aSrobert
5636404b540aSrobert;; Split a load of a large constant into the appropriate two-insn
5637404b540aSrobert;; sequence.
5638404b540aSrobert
5639404b540aSrobert(define_split
5640404b540aSrobert  [(set (match_operand:DI 0 "register_operand" "")
5641404b540aSrobert	(match_operand:DI 1 "non_add_const_operand" ""))]
5642404b540aSrobert  ""
5643404b540aSrobert  [(const_int 0)]
5644404b540aSrobert{
5645404b540aSrobert  if (alpha_split_const_mov (DImode, operands))
5646404b540aSrobert    DONE;
5647404b540aSrobert  else
5648404b540aSrobert    FAIL;
5649404b540aSrobert})
5650404b540aSrobert
5651404b540aSrobert;; We need to prevent reload from splitting TImode moves, because it
5652404b540aSrobert;; might decide to overwrite a pointer with the value it points to.
5653404b540aSrobert;; In that case we have to do the loads in the appropriate order so
5654404b540aSrobert;; that the pointer is not destroyed too early.
5655404b540aSrobert
5656404b540aSrobert(define_insn_and_split "*movti_internal"
5657404b540aSrobert  [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o")
5658404b540aSrobert        (match_operand:TI 1 "input_operand" "roJ,rJ"))]
5659404b540aSrobert  "(register_operand (operands[0], TImode)
5660404b540aSrobert    /* Prevent rematerialization of constants.  */
5661404b540aSrobert    && ! CONSTANT_P (operands[1]))
5662404b540aSrobert   || reg_or_0_operand (operands[1], TImode)"
5663404b540aSrobert  "#"
5664404b540aSrobert  "reload_completed"
5665404b540aSrobert  [(set (match_dup 0) (match_dup 2))
5666404b540aSrobert   (set (match_dup 1) (match_dup 3))]
5667404b540aSrobert{
5668404b540aSrobert  alpha_split_tmode_pair (operands, TImode, true);
5669404b540aSrobert})
5670404b540aSrobert
5671404b540aSrobert(define_expand "movti"
5672404b540aSrobert  [(set (match_operand:TI 0 "nonimmediate_operand" "")
5673404b540aSrobert        (match_operand:TI 1 "general_operand" ""))]
5674404b540aSrobert  ""
5675404b540aSrobert{
5676404b540aSrobert  if (GET_CODE (operands[0]) == MEM
5677404b540aSrobert      && ! reg_or_0_operand (operands[1], TImode))
5678404b540aSrobert    operands[1] = force_reg (TImode, operands[1]);
5679404b540aSrobert
5680404b540aSrobert  if (operands[1] == const0_rtx)
5681404b540aSrobert    ;
5682404b540aSrobert  /* We must put 64-bit constants in memory.  We could keep the
5683404b540aSrobert     32-bit constants in TImode and rely on the splitter, but
5684404b540aSrobert     this doesn't seem to be worth the pain.  */
5685404b540aSrobert  else if (GET_CODE (operands[1]) == CONST_INT
5686404b540aSrobert	   || GET_CODE (operands[1]) == CONST_DOUBLE)
5687404b540aSrobert    {
5688404b540aSrobert      rtx in[2], out[2], target;
5689404b540aSrobert
5690404b540aSrobert      gcc_assert (!no_new_pseudos);
5691404b540aSrobert
5692404b540aSrobert      split_double (operands[1], &in[0], &in[1]);
5693404b540aSrobert
5694404b540aSrobert      if (in[0] == const0_rtx)
5695404b540aSrobert	out[0] = const0_rtx;
5696404b540aSrobert      else
5697404b540aSrobert	{
5698404b540aSrobert	  out[0] = gen_reg_rtx (DImode);
5699404b540aSrobert	  emit_insn (gen_movdi (out[0], in[0]));
5700404b540aSrobert	}
5701404b540aSrobert
5702404b540aSrobert      if (in[1] == const0_rtx)
5703404b540aSrobert	out[1] = const0_rtx;
5704404b540aSrobert      else
5705404b540aSrobert	{
5706404b540aSrobert	  out[1] = gen_reg_rtx (DImode);
5707404b540aSrobert	  emit_insn (gen_movdi (out[1], in[1]));
5708404b540aSrobert	}
5709404b540aSrobert
5710404b540aSrobert      if (GET_CODE (operands[0]) != REG)
5711404b540aSrobert	target = gen_reg_rtx (TImode);
5712404b540aSrobert      else
5713404b540aSrobert	target = operands[0];
5714404b540aSrobert
5715404b540aSrobert      emit_insn (gen_movdi (gen_rtx_SUBREG (DImode, target, 0), out[0]));
5716404b540aSrobert      emit_insn (gen_movdi (gen_rtx_SUBREG (DImode, target, 8), out[1]));
5717404b540aSrobert
5718404b540aSrobert      if (target != operands[0])
5719404b540aSrobert	emit_insn (gen_rtx_SET (VOIDmode, operands[0], target));
5720404b540aSrobert
5721404b540aSrobert      DONE;
5722404b540aSrobert    }
5723404b540aSrobert})
5724404b540aSrobert
5725404b540aSrobert;; These are the partial-word cases.
5726404b540aSrobert;;
5727404b540aSrobert;; First we have the code to load an aligned word.  Operand 0 is the register
5728404b540aSrobert;; in which to place the result.  It's mode is QImode or HImode.  Operand 1
5729404b540aSrobert;; is an SImode MEM at the low-order byte of the proper word.  Operand 2 is the
5730404b540aSrobert;; number of bits within the word that the value is.  Operand 3 is an SImode
5731404b540aSrobert;; scratch register.  If operand 0 is a hard register, operand 3 may be the
5732404b540aSrobert;; same register.  It is allowed to conflict with operand 1 as well.
5733404b540aSrobert
5734404b540aSrobert(define_expand "aligned_loadqi"
5735404b540aSrobert  [(set (match_operand:SI 3 "register_operand" "")
5736404b540aSrobert	(match_operand:SI 1 "memory_operand" ""))
5737404b540aSrobert   (set (match_operand:DI 0 "register_operand" "")
5738404b540aSrobert	(zero_extract:DI (subreg:DI (match_dup 3) 0)
5739404b540aSrobert			 (const_int 8)
5740404b540aSrobert			 (match_operand:DI 2 "const_int_operand" "")))]
5741404b540aSrobert
5742404b540aSrobert  ""
5743404b540aSrobert  "")
5744404b540aSrobert
5745404b540aSrobert(define_expand "aligned_loadhi"
5746404b540aSrobert  [(set (match_operand:SI 3 "register_operand" "")
5747404b540aSrobert	(match_operand:SI 1 "memory_operand" ""))
5748404b540aSrobert   (set (match_operand:DI 0 "register_operand" "")
5749404b540aSrobert	(zero_extract:DI (subreg:DI (match_dup 3) 0)
5750404b540aSrobert			 (const_int 16)
5751404b540aSrobert			 (match_operand:DI 2 "const_int_operand" "")))]
5752404b540aSrobert
5753404b540aSrobert  ""
5754404b540aSrobert  "")
5755404b540aSrobert
5756404b540aSrobert;; Similar for unaligned loads, where we use the sequence from the
5757404b540aSrobert;; Alpha Architecture manual. We have to distinguish between little-endian
5758404b540aSrobert;; and big-endian systems as the sequences are different.
5759404b540aSrobert;;
5760404b540aSrobert;; Operand 1 is the address.  Operands 2 and 3 are temporaries, where
5761404b540aSrobert;; operand 3 can overlap the input and output registers.
5762404b540aSrobert
5763404b540aSrobert(define_expand "unaligned_loadqi"
5764404b540aSrobert  [(use (match_operand:DI 0 "register_operand" ""))
5765404b540aSrobert   (use (match_operand:DI 1 "address_operand" ""))
5766404b540aSrobert   (use (match_operand:DI 2 "register_operand" ""))
5767404b540aSrobert   (use (match_operand:DI 3 "register_operand" ""))]
5768404b540aSrobert  ""
5769404b540aSrobert{
5770404b540aSrobert  if (WORDS_BIG_ENDIAN)
5771404b540aSrobert    emit_insn (gen_unaligned_loadqi_be (operands[0], operands[1],
5772404b540aSrobert					operands[2], operands[3]));
5773404b540aSrobert  else
5774404b540aSrobert    emit_insn (gen_unaligned_loadqi_le (operands[0], operands[1],
5775404b540aSrobert					operands[2], operands[3]));
5776404b540aSrobert  DONE;
5777404b540aSrobert})
5778404b540aSrobert
5779404b540aSrobert(define_expand "unaligned_loadqi_le"
5780404b540aSrobert  [(set (match_operand:DI 2 "register_operand" "")
5781404b540aSrobert	(mem:DI (and:DI (match_operand:DI 1 "address_operand" "")
5782404b540aSrobert			(const_int -8))))
5783404b540aSrobert   (set (match_operand:DI 3 "register_operand" "")
5784404b540aSrobert	(match_dup 1))
5785404b540aSrobert   (set (match_operand:DI 0 "register_operand" "")
5786404b540aSrobert	(zero_extract:DI (match_dup 2)
5787404b540aSrobert			 (const_int 8)
5788404b540aSrobert			 (ashift:DI (match_dup 3) (const_int 3))))]
5789404b540aSrobert  "! WORDS_BIG_ENDIAN"
5790404b540aSrobert  "")
5791404b540aSrobert
5792404b540aSrobert(define_expand "unaligned_loadqi_be"
5793404b540aSrobert  [(set (match_operand:DI 2 "register_operand" "")
5794404b540aSrobert	(mem:DI (and:DI (match_operand:DI 1 "address_operand" "")
5795404b540aSrobert			(const_int -8))))
5796404b540aSrobert   (set (match_operand:DI 3 "register_operand" "")
5797404b540aSrobert	(match_dup 1))
5798404b540aSrobert   (set (match_operand:DI 0 "register_operand" "")
5799404b540aSrobert	(zero_extract:DI (match_dup 2)
5800404b540aSrobert			 (const_int 8)
5801404b540aSrobert			 (minus:DI
5802404b540aSrobert			   (const_int 56)
5803404b540aSrobert			   (ashift:DI (match_dup 3) (const_int 3)))))]
5804404b540aSrobert  "WORDS_BIG_ENDIAN"
5805404b540aSrobert  "")
5806404b540aSrobert
5807404b540aSrobert(define_expand "unaligned_loadhi"
5808404b540aSrobert  [(use (match_operand:DI 0 "register_operand" ""))
5809404b540aSrobert   (use (match_operand:DI 1 "address_operand" ""))
5810404b540aSrobert   (use (match_operand:DI 2 "register_operand" ""))
5811404b540aSrobert   (use (match_operand:DI 3 "register_operand" ""))]
5812404b540aSrobert  ""
5813404b540aSrobert{
5814404b540aSrobert  if (WORDS_BIG_ENDIAN)
5815404b540aSrobert    emit_insn (gen_unaligned_loadhi_be (operands[0], operands[1],
5816404b540aSrobert					operands[2], operands[3]));
5817404b540aSrobert  else
5818404b540aSrobert    emit_insn (gen_unaligned_loadhi_le (operands[0], operands[1],
5819404b540aSrobert					operands[2], operands[3]));
5820404b540aSrobert  DONE;
5821404b540aSrobert})
5822404b540aSrobert
5823404b540aSrobert(define_expand "unaligned_loadhi_le"
5824404b540aSrobert  [(set (match_operand:DI 2 "register_operand" "")
5825404b540aSrobert	(mem:DI (and:DI (match_operand:DI 1 "address_operand" "")
5826404b540aSrobert			(const_int -8))))
5827404b540aSrobert   (set (match_operand:DI 3 "register_operand" "")
5828404b540aSrobert	(match_dup 1))
5829404b540aSrobert   (set (match_operand:DI 0 "register_operand" "")
5830404b540aSrobert	(zero_extract:DI (match_dup 2)
5831404b540aSrobert			 (const_int 16)
5832404b540aSrobert			 (ashift:DI (match_dup 3) (const_int 3))))]
5833404b540aSrobert  "! WORDS_BIG_ENDIAN"
5834404b540aSrobert  "")
5835404b540aSrobert
5836404b540aSrobert(define_expand "unaligned_loadhi_be"
5837404b540aSrobert  [(set (match_operand:DI 2 "register_operand" "")
5838404b540aSrobert	(mem:DI (and:DI (match_operand:DI 1 "address_operand" "")
5839404b540aSrobert			(const_int -8))))
5840404b540aSrobert   (set (match_operand:DI 3 "register_operand" "")
5841404b540aSrobert	(plus:DI (match_dup 1) (const_int 1)))
5842404b540aSrobert   (set (match_operand:DI 0 "register_operand" "")
5843404b540aSrobert	(zero_extract:DI (match_dup 2)
5844404b540aSrobert			 (const_int 16)
5845404b540aSrobert			 (minus:DI
5846404b540aSrobert			   (const_int 56)
5847404b540aSrobert			   (ashift:DI (match_dup 3) (const_int 3)))))]
5848404b540aSrobert  "WORDS_BIG_ENDIAN"
5849404b540aSrobert  "")
5850404b540aSrobert
5851404b540aSrobert;; Storing an aligned byte or word requires two temporaries.  Operand 0 is the
5852404b540aSrobert;; aligned SImode MEM.  Operand 1 is the register containing the
5853404b540aSrobert;; byte or word to store.  Operand 2 is the number of bits within the word that
5854404b540aSrobert;; the value should be placed.  Operands 3 and 4 are SImode temporaries.
5855404b540aSrobert
5856404b540aSrobert(define_expand "aligned_store"
5857404b540aSrobert  [(set (match_operand:SI 3 "register_operand" "")
5858404b540aSrobert	(match_operand:SI 0 "memory_operand" ""))
5859404b540aSrobert   (set (subreg:DI (match_dup 3) 0)
5860404b540aSrobert	(and:DI (subreg:DI (match_dup 3) 0) (match_dup 5)))
5861404b540aSrobert   (set (subreg:DI (match_operand:SI 4 "register_operand" "") 0)
5862404b540aSrobert	(ashift:DI (zero_extend:DI (match_operand 1 "register_operand" ""))
5863404b540aSrobert		   (match_operand:DI 2 "const_int_operand" "")))
5864404b540aSrobert   (set (subreg:DI (match_dup 4) 0)
5865404b540aSrobert	(ior:DI (subreg:DI (match_dup 4) 0) (subreg:DI (match_dup 3) 0)))
5866404b540aSrobert   (set (match_dup 0) (match_dup 4))]
5867404b540aSrobert  ""
5868404b540aSrobert{
5869404b540aSrobert  operands[5] = GEN_INT (~ (GET_MODE_MASK (GET_MODE (operands[1]))
5870404b540aSrobert			    << INTVAL (operands[2])));
5871404b540aSrobert})
5872404b540aSrobert
5873404b540aSrobert;; For the unaligned byte and halfword cases, we use code similar to that
5874404b540aSrobert;; in the ;; Architecture book, but reordered to lower the number of registers
5875404b540aSrobert;; required.  Operand 0 is the address.  Operand 1 is the data to store.
5876404b540aSrobert;; Operands 2, 3, and 4 are DImode temporaries, where operands 2 and 4 may
5877404b540aSrobert;; be the same temporary, if desired.  If the address is in a register,
5878404b540aSrobert;; operand 2 can be that register.
5879404b540aSrobert
5880404b540aSrobert(define_expand "unaligned_storeqi"
5881404b540aSrobert  [(use (match_operand:DI 0 "address_operand" ""))
5882404b540aSrobert   (use (match_operand:QI 1 "register_operand" ""))
5883404b540aSrobert   (use (match_operand:DI 2 "register_operand" ""))
5884404b540aSrobert   (use (match_operand:DI 3 "register_operand" ""))
5885404b540aSrobert   (use (match_operand:DI 4 "register_operand" ""))]
5886404b540aSrobert  ""
5887404b540aSrobert{
5888404b540aSrobert  if (WORDS_BIG_ENDIAN)
5889404b540aSrobert    emit_insn (gen_unaligned_storeqi_be (operands[0], operands[1],
5890404b540aSrobert					 operands[2], operands[3],
5891404b540aSrobert					 operands[4]));
5892404b540aSrobert  else
5893404b540aSrobert    emit_insn (gen_unaligned_storeqi_le (operands[0], operands[1],
5894404b540aSrobert					 operands[2], operands[3],
5895404b540aSrobert					 operands[4]));
5896404b540aSrobert  DONE;
5897404b540aSrobert})
5898404b540aSrobert
5899404b540aSrobert(define_expand "unaligned_storeqi_le"
5900404b540aSrobert  [(set (match_operand:DI 3 "register_operand" "")
5901404b540aSrobert	(mem:DI (and:DI (match_operand:DI 0 "address_operand" "")
5902404b540aSrobert			(const_int -8))))
5903404b540aSrobert   (set (match_operand:DI 2 "register_operand" "")
5904404b540aSrobert	(match_dup 0))
5905404b540aSrobert   (set (match_dup 3)
5906404b540aSrobert	(and:DI (not:DI (ashift:DI (const_int 255)
5907404b540aSrobert				   (ashift:DI (match_dup 2) (const_int 3))))
5908404b540aSrobert		(match_dup 3)))
5909404b540aSrobert   (set (match_operand:DI 4 "register_operand" "")
5910404b540aSrobert	(ashift:DI (zero_extend:DI (match_operand:QI 1 "register_operand" ""))
5911404b540aSrobert		   (ashift:DI (match_dup 2) (const_int 3))))
5912404b540aSrobert   (set (match_dup 4) (ior:DI (match_dup 4) (match_dup 3)))
5913404b540aSrobert   (set (mem:DI (and:DI (match_dup 0) (const_int -8)))
5914404b540aSrobert	(match_dup 4))]
5915404b540aSrobert  "! WORDS_BIG_ENDIAN"
5916404b540aSrobert  "")
5917404b540aSrobert
5918404b540aSrobert(define_expand "unaligned_storeqi_be"
5919404b540aSrobert  [(set (match_operand:DI 3 "register_operand" "")
5920404b540aSrobert	(mem:DI (and:DI (match_operand:DI 0 "address_operand" "")
5921404b540aSrobert			(const_int -8))))
5922404b540aSrobert   (set (match_operand:DI 2 "register_operand" "")
5923404b540aSrobert	(match_dup 0))
5924404b540aSrobert   (set (match_dup 3)
5925404b540aSrobert	(and:DI (not:DI (ashift:DI (const_int 255)
5926404b540aSrobert			  (minus:DI (const_int 56)
5927404b540aSrobert				    (ashift:DI (match_dup 2) (const_int 3)))))
5928404b540aSrobert		(match_dup 3)))
5929404b540aSrobert   (set (match_operand:DI 4 "register_operand" "")
5930404b540aSrobert	(ashift:DI (zero_extend:DI (match_operand:QI 1 "register_operand" ""))
5931404b540aSrobert		   (minus:DI (const_int 56)
5932404b540aSrobert		     (ashift:DI (match_dup 2) (const_int 3)))))
5933404b540aSrobert   (set (match_dup 4) (ior:DI (match_dup 4) (match_dup 3)))
5934404b540aSrobert   (set (mem:DI (and:DI (match_dup 0) (const_int -8)))
5935404b540aSrobert	(match_dup 4))]
5936404b540aSrobert  "WORDS_BIG_ENDIAN"
5937404b540aSrobert  "")
5938404b540aSrobert
5939404b540aSrobert(define_expand "unaligned_storehi"
5940404b540aSrobert  [(use (match_operand:DI 0 "address_operand" ""))
5941404b540aSrobert   (use (match_operand:HI 1 "register_operand" ""))
5942404b540aSrobert   (use (match_operand:DI 2 "register_operand" ""))
5943404b540aSrobert   (use (match_operand:DI 3 "register_operand" ""))
5944404b540aSrobert   (use (match_operand:DI 4 "register_operand" ""))]
5945404b540aSrobert  ""
5946404b540aSrobert{
5947404b540aSrobert  if (WORDS_BIG_ENDIAN)
5948404b540aSrobert    emit_insn (gen_unaligned_storehi_be (operands[0], operands[1],
5949404b540aSrobert					 operands[2], operands[3],
5950404b540aSrobert					 operands[4]));
5951404b540aSrobert  else
5952404b540aSrobert    emit_insn (gen_unaligned_storehi_le (operands[0], operands[1],
5953404b540aSrobert					 operands[2], operands[3],
5954404b540aSrobert					 operands[4]));
5955404b540aSrobert  DONE;
5956404b540aSrobert})
5957404b540aSrobert
5958404b540aSrobert(define_expand "unaligned_storehi_le"
5959404b540aSrobert  [(set (match_operand:DI 3 "register_operand" "")
5960404b540aSrobert	(mem:DI (and:DI (match_operand:DI 0 "address_operand" "")
5961404b540aSrobert			(const_int -8))))
5962404b540aSrobert   (set (match_operand:DI 2 "register_operand" "")
5963404b540aSrobert	(match_dup 0))
5964404b540aSrobert   (set (match_dup 3)
5965404b540aSrobert	(and:DI (not:DI (ashift:DI (const_int 65535)
5966404b540aSrobert				   (ashift:DI (match_dup 2) (const_int 3))))
5967404b540aSrobert		(match_dup 3)))
5968404b540aSrobert   (set (match_operand:DI 4 "register_operand" "")
5969404b540aSrobert	(ashift:DI (zero_extend:DI (match_operand:HI 1 "register_operand" ""))
5970404b540aSrobert		   (ashift:DI (match_dup 2) (const_int 3))))
5971404b540aSrobert   (set (match_dup 4) (ior:DI (match_dup 4) (match_dup 3)))
5972404b540aSrobert   (set (mem:DI (and:DI (match_dup 0) (const_int -8)))
5973404b540aSrobert	(match_dup 4))]
5974404b540aSrobert  "! WORDS_BIG_ENDIAN"
5975404b540aSrobert  "")
5976404b540aSrobert
5977404b540aSrobert(define_expand "unaligned_storehi_be"
5978404b540aSrobert  [(set (match_operand:DI 3 "register_operand" "")
5979404b540aSrobert	(mem:DI (and:DI (match_operand:DI 0 "address_operand" "")
5980404b540aSrobert			(const_int -8))))
5981404b540aSrobert   (set (match_operand:DI 2 "register_operand" "")
5982404b540aSrobert	(plus:DI (match_dup 0) (const_int 1)))
5983404b540aSrobert   (set (match_dup 3)
5984404b540aSrobert	(and:DI (not:DI (ashift:DI
5985404b540aSrobert			  (const_int 65535)
5986404b540aSrobert			  (minus:DI (const_int 56)
5987404b540aSrobert				    (ashift:DI (match_dup 2) (const_int 3)))))
5988404b540aSrobert		(match_dup 3)))
5989404b540aSrobert   (set (match_operand:DI 4 "register_operand" "")
5990404b540aSrobert	(ashift:DI (zero_extend:DI (match_operand:HI 1 "register_operand" ""))
5991404b540aSrobert		   (minus:DI (const_int 56)
5992404b540aSrobert			     (ashift:DI (match_dup 2) (const_int 3)))))
5993404b540aSrobert   (set (match_dup 4) (ior:DI (match_dup 4) (match_dup 3)))
5994404b540aSrobert   (set (mem:DI (and:DI (match_dup 0) (const_int -8)))
5995404b540aSrobert	(match_dup 4))]
5996404b540aSrobert  "WORDS_BIG_ENDIAN"
5997404b540aSrobert  "")
5998404b540aSrobert
5999404b540aSrobert;; Here are the define_expand's for QI and HI moves that use the above
6000404b540aSrobert;; patterns.  We have the normal sets, plus the ones that need scratch
6001404b540aSrobert;; registers for reload.
6002404b540aSrobert
6003404b540aSrobert(define_expand "movqi"
6004404b540aSrobert  [(set (match_operand:QI 0 "nonimmediate_operand" "")
6005404b540aSrobert	(match_operand:QI 1 "general_operand" ""))]
6006404b540aSrobert  ""
6007404b540aSrobert{
6008404b540aSrobert  if (TARGET_BWX
6009404b540aSrobert      ? alpha_expand_mov (QImode, operands)
6010404b540aSrobert      : alpha_expand_mov_nobwx (QImode, operands))
6011404b540aSrobert    DONE;
6012404b540aSrobert})
6013404b540aSrobert
6014404b540aSrobert(define_expand "movhi"
6015404b540aSrobert  [(set (match_operand:HI 0 "nonimmediate_operand" "")
6016404b540aSrobert	(match_operand:HI 1 "general_operand" ""))]
6017404b540aSrobert  ""
6018404b540aSrobert{
6019404b540aSrobert  if (TARGET_BWX
6020404b540aSrobert      ? alpha_expand_mov (HImode, operands)
6021404b540aSrobert      : alpha_expand_mov_nobwx (HImode, operands))
6022404b540aSrobert    DONE;
6023404b540aSrobert})
6024404b540aSrobert
6025404b540aSrobert;; Here are the versions for reload.  Note that in the unaligned cases
6026404b540aSrobert;; we know that the operand must not be a pseudo-register because stack
6027404b540aSrobert;; slots are always aligned references.
6028404b540aSrobert
6029404b540aSrobert(define_expand "reload_inqi"
6030404b540aSrobert  [(parallel [(match_operand:QI 0 "register_operand" "=r")
6031404b540aSrobert	      (match_operand:QI 1 "any_memory_operand" "m")
6032404b540aSrobert	      (match_operand:TI 2 "register_operand" "=&r")])]
6033404b540aSrobert  "! TARGET_BWX"
6034404b540aSrobert{
6035404b540aSrobert  rtx scratch, seq;
6036404b540aSrobert
6037404b540aSrobert  if (aligned_memory_operand (operands[1], QImode))
6038404b540aSrobert    {
6039404b540aSrobert      seq = gen_reload_inqi_help (operands[0], operands[1],
6040404b540aSrobert				  gen_rtx_REG (SImode, REGNO (operands[2])));
6041404b540aSrobert    }
6042404b540aSrobert  else
6043404b540aSrobert    {
6044404b540aSrobert      rtx addr;
6045404b540aSrobert
6046404b540aSrobert      /* It is possible that one of the registers we got for operands[2]
6047404b540aSrobert	 might coincide with that of operands[0] (which is why we made
6048404b540aSrobert	 it TImode).  Pick the other one to use as our scratch.  */
6049404b540aSrobert      if (REGNO (operands[0]) == REGNO (operands[2]))
6050404b540aSrobert	scratch = gen_rtx_REG (DImode, REGNO (operands[2]) + 1);
6051404b540aSrobert      else
6052404b540aSrobert	scratch = gen_rtx_REG (DImode, REGNO (operands[2]));
6053404b540aSrobert
6054404b540aSrobert      addr = get_unaligned_address (operands[1]);
6055404b540aSrobert      operands[0] = gen_rtx_REG (DImode, REGNO (operands[0]));
6056404b540aSrobert      seq = gen_unaligned_loadqi (operands[0], addr, scratch, operands[0]);
6057404b540aSrobert      alpha_set_memflags (seq, operands[1]);
6058404b540aSrobert    }
6059404b540aSrobert  emit_insn (seq);
6060404b540aSrobert  DONE;
6061404b540aSrobert})
6062404b540aSrobert
6063404b540aSrobert(define_expand "reload_inhi"
6064404b540aSrobert  [(parallel [(match_operand:HI 0 "register_operand" "=r")
6065404b540aSrobert	      (match_operand:HI 1 "any_memory_operand" "m")
6066404b540aSrobert	      (match_operand:TI 2 "register_operand" "=&r")])]
6067404b540aSrobert  "! TARGET_BWX"
6068404b540aSrobert{
6069404b540aSrobert  rtx scratch, seq;
6070404b540aSrobert
6071404b540aSrobert  if (aligned_memory_operand (operands[1], HImode))
6072404b540aSrobert    {
6073404b540aSrobert      seq = gen_reload_inhi_help (operands[0], operands[1],
6074404b540aSrobert				  gen_rtx_REG (SImode, REGNO (operands[2])));
6075404b540aSrobert    }
6076404b540aSrobert  else
6077404b540aSrobert    {
6078404b540aSrobert      rtx addr;
6079404b540aSrobert
6080404b540aSrobert      /* It is possible that one of the registers we got for operands[2]
6081404b540aSrobert	 might coincide with that of operands[0] (which is why we made
6082404b540aSrobert	 it TImode).  Pick the other one to use as our scratch.  */
6083404b540aSrobert      if (REGNO (operands[0]) == REGNO (operands[2]))
6084404b540aSrobert	scratch = gen_rtx_REG (DImode, REGNO (operands[2]) + 1);
6085404b540aSrobert      else
6086404b540aSrobert	scratch = gen_rtx_REG (DImode, REGNO (operands[2]));
6087404b540aSrobert
6088404b540aSrobert      addr = get_unaligned_address (operands[1]);
6089404b540aSrobert      operands[0] = gen_rtx_REG (DImode, REGNO (operands[0]));
6090404b540aSrobert      seq = gen_unaligned_loadhi (operands[0], addr, scratch, operands[0]);
6091404b540aSrobert      alpha_set_memflags (seq, operands[1]);
6092404b540aSrobert    }
6093404b540aSrobert  emit_insn (seq);
6094404b540aSrobert  DONE;
6095404b540aSrobert})
6096404b540aSrobert
6097404b540aSrobert(define_expand "reload_outqi"
6098404b540aSrobert  [(parallel [(match_operand:QI 0 "any_memory_operand" "=m")
6099404b540aSrobert	      (match_operand:QI 1 "register_operand" "r")
6100404b540aSrobert	      (match_operand:TI 2 "register_operand" "=&r")])]
6101404b540aSrobert  "! TARGET_BWX"
6102404b540aSrobert{
6103404b540aSrobert  if (aligned_memory_operand (operands[0], QImode))
6104404b540aSrobert    {
6105404b540aSrobert      emit_insn (gen_reload_outqi_help
6106404b540aSrobert		 (operands[0], operands[1],
6107404b540aSrobert		  gen_rtx_REG (SImode, REGNO (operands[2])),
6108404b540aSrobert		  gen_rtx_REG (SImode, REGNO (operands[2]) + 1)));
6109404b540aSrobert    }
6110404b540aSrobert  else
6111404b540aSrobert    {
6112404b540aSrobert      rtx addr = get_unaligned_address (operands[0]);
6113404b540aSrobert      rtx scratch1 = gen_rtx_REG (DImode, REGNO (operands[2]));
6114404b540aSrobert      rtx scratch2 = gen_rtx_REG (DImode, REGNO (operands[2]) + 1);
6115404b540aSrobert      rtx scratch3 = scratch1;
6116404b540aSrobert      rtx seq;
6117404b540aSrobert
6118404b540aSrobert      if (GET_CODE (addr) == REG)
6119404b540aSrobert	scratch1 = addr;
6120404b540aSrobert
6121404b540aSrobert      seq = gen_unaligned_storeqi (addr, operands[1], scratch1,
6122404b540aSrobert				   scratch2, scratch3);
6123404b540aSrobert      alpha_set_memflags (seq, operands[0]);
6124404b540aSrobert      emit_insn (seq);
6125404b540aSrobert    }
6126404b540aSrobert  DONE;
6127404b540aSrobert})
6128404b540aSrobert
6129404b540aSrobert(define_expand "reload_outhi"
6130404b540aSrobert  [(parallel [(match_operand:HI 0 "any_memory_operand" "=m")
6131404b540aSrobert	      (match_operand:HI 1 "register_operand" "r")
6132404b540aSrobert	      (match_operand:TI 2 "register_operand" "=&r")])]
6133404b540aSrobert  "! TARGET_BWX"
6134404b540aSrobert{
6135404b540aSrobert  if (aligned_memory_operand (operands[0], HImode))
6136404b540aSrobert    {
6137404b540aSrobert      emit_insn (gen_reload_outhi_help
6138404b540aSrobert		 (operands[0], operands[1],
6139404b540aSrobert		  gen_rtx_REG (SImode, REGNO (operands[2])),
6140404b540aSrobert		  gen_rtx_REG (SImode, REGNO (operands[2]) + 1)));
6141404b540aSrobert    }
6142404b540aSrobert  else
6143404b540aSrobert    {
6144404b540aSrobert      rtx addr = get_unaligned_address (operands[0]);
6145404b540aSrobert      rtx scratch1 = gen_rtx_REG (DImode, REGNO (operands[2]));
6146404b540aSrobert      rtx scratch2 = gen_rtx_REG (DImode, REGNO (operands[2]) + 1);
6147404b540aSrobert      rtx scratch3 = scratch1;
6148404b540aSrobert      rtx seq;
6149404b540aSrobert
6150404b540aSrobert      if (GET_CODE (addr) == REG)
6151404b540aSrobert	scratch1 = addr;
6152404b540aSrobert
6153404b540aSrobert      seq = gen_unaligned_storehi (addr, operands[1], scratch1,
6154404b540aSrobert				   scratch2, scratch3);
6155404b540aSrobert      alpha_set_memflags (seq, operands[0]);
6156404b540aSrobert      emit_insn (seq);
6157404b540aSrobert    }
6158404b540aSrobert  DONE;
6159404b540aSrobert})
6160404b540aSrobert
6161404b540aSrobert;; Helpers for the above.  The way reload is structured, we can't
6162404b540aSrobert;; always get a proper address for a stack slot during reload_foo
6163404b540aSrobert;; expansion, so we must delay our address manipulations until after.
6164404b540aSrobert
6165404b540aSrobert(define_insn_and_split "reload_inqi_help"
6166404b540aSrobert  [(set (match_operand:QI 0 "register_operand" "=r")
6167404b540aSrobert        (match_operand:QI 1 "memory_operand" "m"))
6168404b540aSrobert   (clobber (match_operand:SI 2 "register_operand" "=r"))]
6169404b540aSrobert  "! TARGET_BWX && (reload_in_progress || reload_completed)"
6170404b540aSrobert  "#"
6171404b540aSrobert  "! TARGET_BWX && reload_completed"
6172404b540aSrobert  [(const_int 0)]
6173404b540aSrobert{
6174404b540aSrobert  rtx aligned_mem, bitnum;
6175404b540aSrobert  get_aligned_mem (operands[1], &aligned_mem, &bitnum);
6176404b540aSrobert  operands[0] = gen_lowpart (DImode, operands[0]);
6177404b540aSrobert  emit_insn (gen_aligned_loadqi (operands[0], aligned_mem, bitnum,
6178404b540aSrobert				 operands[2]));
6179404b540aSrobert  DONE;
6180404b540aSrobert})
6181404b540aSrobert
6182404b540aSrobert(define_insn_and_split "reload_inhi_help"
6183404b540aSrobert  [(set (match_operand:HI 0 "register_operand" "=r")
6184404b540aSrobert        (match_operand:HI 1 "memory_operand" "m"))
6185404b540aSrobert   (clobber (match_operand:SI 2 "register_operand" "=r"))]
6186404b540aSrobert  "! TARGET_BWX && (reload_in_progress || reload_completed)"
6187404b540aSrobert  "#"
6188404b540aSrobert  "! TARGET_BWX && reload_completed"
6189404b540aSrobert  [(const_int 0)]
6190404b540aSrobert{
6191404b540aSrobert  rtx aligned_mem, bitnum;
6192404b540aSrobert  get_aligned_mem (operands[1], &aligned_mem, &bitnum);
6193404b540aSrobert  operands[0] = gen_lowpart (DImode, operands[0]);
6194404b540aSrobert  emit_insn (gen_aligned_loadhi (operands[0], aligned_mem, bitnum,
6195404b540aSrobert				 operands[2]));
6196404b540aSrobert  DONE;
6197404b540aSrobert})
6198404b540aSrobert
6199404b540aSrobert(define_insn_and_split "reload_outqi_help"
6200404b540aSrobert  [(set (match_operand:QI 0 "memory_operand" "=m")
6201404b540aSrobert        (match_operand:QI 1 "register_operand" "r"))
6202404b540aSrobert   (clobber (match_operand:SI 2 "register_operand" "=r"))
6203404b540aSrobert   (clobber (match_operand:SI 3 "register_operand" "=r"))]
6204404b540aSrobert  "! TARGET_BWX && (reload_in_progress || reload_completed)"
6205404b540aSrobert  "#"
6206404b540aSrobert  "! TARGET_BWX && reload_completed"
6207404b540aSrobert  [(const_int 0)]
6208404b540aSrobert{
6209404b540aSrobert  rtx aligned_mem, bitnum;
6210404b540aSrobert  get_aligned_mem (operands[0], &aligned_mem, &bitnum);
6211404b540aSrobert  emit_insn (gen_aligned_store (aligned_mem, operands[1], bitnum,
6212404b540aSrobert				operands[2], operands[3]));
6213404b540aSrobert  DONE;
6214404b540aSrobert})
6215404b540aSrobert
6216404b540aSrobert(define_insn_and_split "reload_outhi_help"
6217404b540aSrobert  [(set (match_operand:HI 0 "memory_operand" "=m")
6218404b540aSrobert        (match_operand:HI 1 "register_operand" "r"))
6219404b540aSrobert   (clobber (match_operand:SI 2 "register_operand" "=r"))
6220404b540aSrobert   (clobber (match_operand:SI 3 "register_operand" "=r"))]
6221404b540aSrobert  "! TARGET_BWX && (reload_in_progress || reload_completed)"
6222404b540aSrobert  "#"
6223404b540aSrobert  "! TARGET_BWX && reload_completed"
6224404b540aSrobert  [(const_int 0)]
6225404b540aSrobert{
6226404b540aSrobert  rtx aligned_mem, bitnum;
6227404b540aSrobert  get_aligned_mem (operands[0], &aligned_mem, &bitnum);
6228404b540aSrobert  emit_insn (gen_aligned_store (aligned_mem, operands[1], bitnum,
6229404b540aSrobert				operands[2], operands[3]));
6230404b540aSrobert  DONE;
6231404b540aSrobert})
6232404b540aSrobert
6233404b540aSrobert;; Vector operations
6234404b540aSrobert
6235404b540aSrobert(define_mode_macro VEC [V8QI V4HI V2SI])
6236404b540aSrobert
6237404b540aSrobert(define_expand "mov<mode>"
6238404b540aSrobert  [(set (match_operand:VEC 0 "nonimmediate_operand" "")
6239404b540aSrobert        (match_operand:VEC 1 "general_operand" ""))]
6240404b540aSrobert  ""
6241404b540aSrobert{
6242404b540aSrobert  if (alpha_expand_mov (<MODE>mode, operands))
6243404b540aSrobert    DONE;
6244404b540aSrobert})
6245404b540aSrobert
6246404b540aSrobert(define_split
6247404b540aSrobert  [(set (match_operand:VEC 0 "register_operand" "")
6248404b540aSrobert	(match_operand:VEC 1 "non_zero_const_operand" ""))]
6249404b540aSrobert  ""
6250404b540aSrobert  [(const_int 0)]
6251404b540aSrobert{
6252404b540aSrobert  if (alpha_split_const_mov (<MODE>mode, operands))
6253404b540aSrobert    DONE;
6254404b540aSrobert  else
6255404b540aSrobert    FAIL;
6256404b540aSrobert})
6257404b540aSrobert
6258404b540aSrobert
6259404b540aSrobert(define_expand "movmisalign<mode>"
6260404b540aSrobert  [(set (match_operand:VEC 0 "nonimmediate_operand" "")
6261404b540aSrobert        (match_operand:VEC 1 "general_operand" ""))]
6262404b540aSrobert  ""
6263404b540aSrobert{
6264404b540aSrobert  alpha_expand_movmisalign (<MODE>mode, operands);
6265404b540aSrobert  DONE;
6266404b540aSrobert})
6267404b540aSrobert
6268404b540aSrobert(define_insn "*mov<mode>_fix"
6269404b540aSrobert  [(set (match_operand:VEC 0 "nonimmediate_operand" "=r,r,r,m,*f,*f,m,r,*f")
6270404b540aSrobert	(match_operand:VEC 1 "input_operand" "rW,i,m,rW,*fW,m,*f,*f,r"))]
6271404b540aSrobert  "TARGET_FIX
6272404b540aSrobert   && (register_operand (operands[0], <MODE>mode)
6273404b540aSrobert       || reg_or_0_operand (operands[1], <MODE>mode))"
6274404b540aSrobert  "@
6275404b540aSrobert   bis $31,%r1,%0
6276404b540aSrobert   #
6277404b540aSrobert   ldq %0,%1
6278404b540aSrobert   stq %r1,%0
6279404b540aSrobert   cpys %R1,%R1,%0
6280404b540aSrobert   ldt %0,%1
6281404b540aSrobert   stt %R1,%0
6282404b540aSrobert   ftoit %1,%0
6283404b540aSrobert   itoft %1,%0"
6284404b540aSrobert  [(set_attr "type" "ilog,multi,ild,ist,fcpys,fld,fst,ftoi,itof")])
6285404b540aSrobert
6286404b540aSrobert(define_insn "*mov<mode>_nofix"
6287404b540aSrobert  [(set (match_operand:VEC 0 "nonimmediate_operand" "=r,r,r,m,*f,*f,m")
6288404b540aSrobert	(match_operand:VEC 1 "input_operand" "rW,i,m,rW,*fW,m,*f"))]
6289404b540aSrobert  "! TARGET_FIX
6290404b540aSrobert   && (register_operand (operands[0], <MODE>mode)
6291404b540aSrobert       || reg_or_0_operand (operands[1], <MODE>mode))"
6292404b540aSrobert  "@
6293404b540aSrobert   bis $31,%r1,%0
6294404b540aSrobert   #
6295404b540aSrobert   ldq %0,%1
6296404b540aSrobert   stq %r1,%0
6297404b540aSrobert   cpys %R1,%R1,%0
6298404b540aSrobert   ldt %0,%1
6299404b540aSrobert   stt %R1,%0"
6300404b540aSrobert  [(set_attr "type" "ilog,multi,ild,ist,fcpys,fld,fst")])
6301404b540aSrobert
6302404b540aSrobert(define_insn "uminv8qi3"
6303404b540aSrobert  [(set (match_operand:V8QI 0 "register_operand" "=r")
6304404b540aSrobert	(umin:V8QI (match_operand:V8QI 1 "reg_or_0_operand" "rW")
6305404b540aSrobert		   (match_operand:V8QI 2 "reg_or_0_operand" "rW")))]
6306404b540aSrobert  "TARGET_MAX"
6307404b540aSrobert  "minub8 %r1,%r2,%0"
6308404b540aSrobert  [(set_attr "type" "mvi")])
6309404b540aSrobert
6310404b540aSrobert(define_insn "sminv8qi3"
6311404b540aSrobert  [(set (match_operand:V8QI 0 "register_operand" "=r")
6312404b540aSrobert	(smin:V8QI (match_operand:V8QI 1 "reg_or_0_operand" "rW")
6313404b540aSrobert		   (match_operand:V8QI 2 "reg_or_0_operand" "rW")))]
6314404b540aSrobert  "TARGET_MAX"
6315404b540aSrobert  "minsb8 %r1,%r2,%0"
6316404b540aSrobert  [(set_attr "type" "mvi")])
6317404b540aSrobert
6318404b540aSrobert(define_insn "uminv4hi3"
6319404b540aSrobert  [(set (match_operand:V4HI 0 "register_operand" "=r")
6320404b540aSrobert	(umin:V4HI (match_operand:V4HI 1 "reg_or_0_operand" "rW")
6321404b540aSrobert		   (match_operand:V4HI 2 "reg_or_0_operand" "rW")))]
6322404b540aSrobert  "TARGET_MAX"
6323404b540aSrobert  "minuw4 %r1,%r2,%0"
6324404b540aSrobert  [(set_attr "type" "mvi")])
6325404b540aSrobert
6326404b540aSrobert(define_insn "sminv4hi3"
6327404b540aSrobert  [(set (match_operand:V4HI 0 "register_operand" "=r")
6328404b540aSrobert	(smin:V4HI (match_operand:V4HI 1 "reg_or_0_operand" "rW")
6329404b540aSrobert		   (match_operand:V4HI 2 "reg_or_0_operand" "rW")))]
6330404b540aSrobert  "TARGET_MAX"
6331404b540aSrobert  "minsw4 %r1,%r2,%0"
6332404b540aSrobert  [(set_attr "type" "mvi")])
6333404b540aSrobert
6334404b540aSrobert(define_insn "umaxv8qi3"
6335404b540aSrobert  [(set (match_operand:V8QI 0 "register_operand" "=r")
6336404b540aSrobert	(umax:V8QI (match_operand:V8QI 1 "reg_or_0_operand" "rW")
6337404b540aSrobert		   (match_operand:V8QI 2 "reg_or_0_operand" "rW")))]
6338404b540aSrobert  "TARGET_MAX"
6339404b540aSrobert  "maxub8 %r1,%r2,%0"
6340404b540aSrobert  [(set_attr "type" "mvi")])
6341404b540aSrobert
6342404b540aSrobert(define_insn "smaxv8qi3"
6343404b540aSrobert  [(set (match_operand:V8QI 0 "register_operand" "=r")
6344404b540aSrobert	(smax:V8QI (match_operand:V8QI 1 "reg_or_0_operand" "rW")
6345404b540aSrobert		   (match_operand:V8QI 2 "reg_or_0_operand" "rW")))]
6346404b540aSrobert  "TARGET_MAX"
6347404b540aSrobert  "maxsb8 %r1,%r2,%0"
6348404b540aSrobert  [(set_attr "type" "mvi")])
6349404b540aSrobert
6350404b540aSrobert(define_insn "umaxv4hi3"
6351404b540aSrobert  [(set (match_operand:V4HI 0 "register_operand" "=r")
6352404b540aSrobert	(umax:V4HI (match_operand:V4HI 1 "reg_or_0_operand" "rW")
6353404b540aSrobert		   (match_operand:V4HI 2 "reg_or_0_operand" "rW")))]
6354404b540aSrobert  "TARGET_MAX"
6355404b540aSrobert  "maxuw4 %r1,%r2,%0"
6356404b540aSrobert  [(set_attr "type" "mvi")])
6357404b540aSrobert
6358404b540aSrobert(define_insn "smaxv4hi3"
6359404b540aSrobert  [(set (match_operand:V4HI 0 "register_operand" "=r")
6360404b540aSrobert	(smax:V4HI (match_operand:V4HI 1 "reg_or_0_operand" "rW")
6361404b540aSrobert		   (match_operand:V4HI 2 "reg_or_0_operand" "rW")))]
6362404b540aSrobert  "TARGET_MAX"
6363404b540aSrobert  "maxsw4 %r1,%r2,%0"
6364404b540aSrobert  [(set_attr "type" "mvi")])
6365404b540aSrobert
6366404b540aSrobert(define_insn "one_cmpl<mode>2"
6367404b540aSrobert  [(set (match_operand:VEC 0 "register_operand" "=r")
6368404b540aSrobert	(not:VEC (match_operand:VEC 1 "register_operand" "r")))]
6369404b540aSrobert  ""
6370404b540aSrobert  "ornot $31,%1,%0"
6371404b540aSrobert  [(set_attr "type" "ilog")])
6372404b540aSrobert
6373404b540aSrobert(define_insn "and<mode>3"
6374404b540aSrobert  [(set (match_operand:VEC 0 "register_operand" "=r")
6375404b540aSrobert	(and:VEC (match_operand:VEC 1 "register_operand" "r")
6376404b540aSrobert		 (match_operand:VEC 2 "register_operand" "r")))]
6377404b540aSrobert  ""
6378404b540aSrobert  "and %1,%2,%0"
6379404b540aSrobert  [(set_attr "type" "ilog")])
6380404b540aSrobert
6381404b540aSrobert(define_insn "*andnot<mode>3"
6382404b540aSrobert  [(set (match_operand:VEC 0 "register_operand" "=r")
6383404b540aSrobert	(and:VEC (not:VEC (match_operand:VEC 1 "register_operand" "r"))
6384404b540aSrobert		 (match_operand:VEC 2 "register_operand" "r")))]
6385404b540aSrobert  ""
6386404b540aSrobert  "bic %2,%1,%0"
6387404b540aSrobert  [(set_attr "type" "ilog")])
6388404b540aSrobert
6389404b540aSrobert(define_insn "ior<mode>3"
6390404b540aSrobert  [(set (match_operand:VEC 0 "register_operand" "=r")
6391404b540aSrobert	(ior:VEC (match_operand:VEC 1 "register_operand" "r")
6392404b540aSrobert		 (match_operand:VEC 2 "register_operand" "r")))]
6393404b540aSrobert  ""
6394404b540aSrobert  "bis %1,%2,%0"
6395404b540aSrobert  [(set_attr "type" "ilog")])
6396404b540aSrobert
6397404b540aSrobert(define_insn "*iornot<mode>3"
6398404b540aSrobert  [(set (match_operand:VEC 0 "register_operand" "=r")
6399404b540aSrobert	(ior:VEC (not:DI (match_operand:VEC 1 "register_operand" "r"))
6400404b540aSrobert		 (match_operand:VEC 2 "register_operand" "r")))]
6401404b540aSrobert  ""
6402404b540aSrobert  "ornot %2,%1,%0"
6403404b540aSrobert  [(set_attr "type" "ilog")])
6404404b540aSrobert
6405404b540aSrobert(define_insn "xor<mode>3"
6406404b540aSrobert  [(set (match_operand:VEC 0 "register_operand" "=r")
6407404b540aSrobert	(xor:VEC (match_operand:VEC 1 "register_operand" "r")
6408404b540aSrobert		 (match_operand:VEC 2 "register_operand" "r")))]
6409404b540aSrobert  ""
6410404b540aSrobert  "xor %1,%2,%0"
6411404b540aSrobert  [(set_attr "type" "ilog")])
6412404b540aSrobert
6413404b540aSrobert(define_insn "*xornot<mode>3"
6414404b540aSrobert  [(set (match_operand:VEC 0 "register_operand" "=r")
6415404b540aSrobert	(not:VEC (xor:VEC (match_operand:VEC 1 "register_operand" "r")
6416404b540aSrobert			  (match_operand:VEC 2 "register_operand" "r"))))]
6417404b540aSrobert  ""
6418404b540aSrobert  "eqv %1,%2,%0"
6419404b540aSrobert  [(set_attr "type" "ilog")])
6420404b540aSrobert
6421404b540aSrobert(define_expand "vec_shl_<mode>"
6422404b540aSrobert  [(set (match_operand:VEC 0 "register_operand" "")
6423404b540aSrobert	(ashift:DI (match_operand:VEC 1 "register_operand" "")
6424404b540aSrobert		   (match_operand:DI 2 "reg_or_6bit_operand" "")))]
6425404b540aSrobert  ""
6426404b540aSrobert{
6427404b540aSrobert  operands[0] = gen_lowpart (DImode, operands[0]);
6428404b540aSrobert  operands[1] = gen_lowpart (DImode, operands[1]);
6429404b540aSrobert})
6430404b540aSrobert
6431404b540aSrobert(define_expand "vec_shr_<mode>"
6432404b540aSrobert  [(set (match_operand:VEC 0 "register_operand" "")
6433404b540aSrobert        (lshiftrt:DI (match_operand:VEC 1 "register_operand" "")
6434404b540aSrobert                     (match_operand:DI 2 "reg_or_6bit_operand" "")))]
6435404b540aSrobert  ""
6436404b540aSrobert{
6437404b540aSrobert  operands[0] = gen_lowpart (DImode, operands[0]);
6438404b540aSrobert  operands[1] = gen_lowpart (DImode, operands[1]);
6439404b540aSrobert})
6440404b540aSrobert
6441404b540aSrobert;; Bit field extract patterns which use ext[wlq][lh]
6442404b540aSrobert
6443404b540aSrobert(define_expand "extv"
6444404b540aSrobert  [(set (match_operand:DI 0 "register_operand" "")
6445404b540aSrobert	(sign_extract:DI (match_operand:QI 1 "memory_operand" "")
6446404b540aSrobert			 (match_operand:DI 2 "immediate_operand" "")
6447404b540aSrobert			 (match_operand:DI 3 "immediate_operand" "")))]
6448404b540aSrobert  ""
6449404b540aSrobert{
6450404b540aSrobert  int ofs;
6451404b540aSrobert
6452404b540aSrobert  /* We can do 16, 32 and 64 bit fields, if aligned on byte boundaries.  */
6453404b540aSrobert  if (INTVAL (operands[3]) % 8 != 0
6454404b540aSrobert      || (INTVAL (operands[2]) != 16
6455404b540aSrobert	  && INTVAL (operands[2]) != 32
6456404b540aSrobert	  && INTVAL (operands[2]) != 64))
6457404b540aSrobert    FAIL;
6458404b540aSrobert
6459404b540aSrobert  /* From mips.md: extract_bit_field doesn't verify that our source
6460404b540aSrobert     matches the predicate, so we force it to be a MEM here.  */
6461404b540aSrobert  if (GET_CODE (operands[1]) != MEM)
6462404b540aSrobert    FAIL;
6463404b540aSrobert
6464404b540aSrobert  /* The bit number is relative to the mode of operand 1 which is
6465404b540aSrobert     usually QImode (this might actually be a bug in expmed.c). Note
6466404b540aSrobert     that the bit number is negative in big-endian mode in this case.
6467404b540aSrobert     We have to convert that to the offset.  */
6468404b540aSrobert  if (WORDS_BIG_ENDIAN)
6469404b540aSrobert    ofs = GET_MODE_BITSIZE (GET_MODE (operands[1]))
6470404b540aSrobert          - INTVAL (operands[2]) - INTVAL (operands[3]);
6471404b540aSrobert  else
6472404b540aSrobert    ofs = INTVAL (operands[3]);
6473404b540aSrobert
6474404b540aSrobert  ofs = ofs / 8;
6475404b540aSrobert
6476404b540aSrobert  alpha_expand_unaligned_load (operands[0], operands[1],
6477404b540aSrobert			       INTVAL (operands[2]) / 8,
6478404b540aSrobert			       ofs, 1);
6479404b540aSrobert  DONE;
6480404b540aSrobert})
6481404b540aSrobert
6482404b540aSrobert(define_expand "extzv"
6483404b540aSrobert  [(set (match_operand:DI 0 "register_operand" "")
6484404b540aSrobert	(zero_extract:DI (match_operand:DI 1 "nonimmediate_operand" "")
6485404b540aSrobert			 (match_operand:DI 2 "immediate_operand" "")
6486404b540aSrobert			 (match_operand:DI 3 "immediate_operand" "")))]
6487404b540aSrobert  ""
6488404b540aSrobert{
6489404b540aSrobert  /* We can do 8, 16, 32 and 64 bit fields, if aligned on byte boundaries.  */
6490404b540aSrobert  if (INTVAL (operands[3]) % 8 != 0
6491404b540aSrobert      || (INTVAL (operands[2]) != 8
6492404b540aSrobert	  && INTVAL (operands[2]) != 16
6493404b540aSrobert	  && INTVAL (operands[2]) != 32
6494404b540aSrobert	  && INTVAL (operands[2]) != 64))
6495404b540aSrobert    FAIL;
6496404b540aSrobert
6497404b540aSrobert  if (GET_CODE (operands[1]) == MEM)
6498404b540aSrobert    {
6499404b540aSrobert      int ofs;
6500404b540aSrobert
6501404b540aSrobert      /* Fail 8 bit fields, falling back on a simple byte load.  */
6502404b540aSrobert      if (INTVAL (operands[2]) == 8)
6503404b540aSrobert	FAIL;
6504404b540aSrobert
6505404b540aSrobert      /* The bit number is relative to the mode of operand 1 which is
6506404b540aSrobert	 usually QImode (this might actually be a bug in expmed.c). Note
6507404b540aSrobert	 that the bit number is negative in big-endian mode in this case.
6508404b540aSrobert	 We have to convert that to the offset.  */
6509404b540aSrobert      if (WORDS_BIG_ENDIAN)
6510404b540aSrobert	ofs = GET_MODE_BITSIZE (GET_MODE (operands[1]))
6511404b540aSrobert	      - INTVAL (operands[2]) - INTVAL (operands[3]);
6512404b540aSrobert      else
6513404b540aSrobert	ofs = INTVAL (operands[3]);
6514404b540aSrobert
6515404b540aSrobert      ofs = ofs / 8;
6516404b540aSrobert
6517404b540aSrobert      alpha_expand_unaligned_load (operands[0], operands[1],
6518404b540aSrobert			           INTVAL (operands[2]) / 8,
6519404b540aSrobert				   ofs, 0);
6520404b540aSrobert      DONE;
6521404b540aSrobert    }
6522404b540aSrobert})
6523404b540aSrobert
6524404b540aSrobert(define_expand "insv"
6525404b540aSrobert  [(set (zero_extract:DI (match_operand:QI 0 "memory_operand" "")
6526404b540aSrobert			 (match_operand:DI 1 "immediate_operand" "")
6527404b540aSrobert			 (match_operand:DI 2 "immediate_operand" ""))
6528404b540aSrobert	(match_operand:DI 3 "register_operand" ""))]
6529404b540aSrobert  ""
6530404b540aSrobert{
6531404b540aSrobert  int ofs;
6532404b540aSrobert
6533404b540aSrobert  /* We can do 16, 32 and 64 bit fields, if aligned on byte boundaries.  */
6534404b540aSrobert  if (INTVAL (operands[2]) % 8 != 0
6535404b540aSrobert      || (INTVAL (operands[1]) != 16
6536404b540aSrobert	  && INTVAL (operands[1]) != 32
6537404b540aSrobert	  && INTVAL (operands[1]) != 64))
6538404b540aSrobert    FAIL;
6539404b540aSrobert
6540404b540aSrobert  /* From mips.md: store_bit_field doesn't verify that our source
6541404b540aSrobert     matches the predicate, so we force it to be a MEM here.  */
6542404b540aSrobert  if (GET_CODE (operands[0]) != MEM)
6543404b540aSrobert    FAIL;
6544404b540aSrobert
6545404b540aSrobert  /* The bit number is relative to the mode of operand 1 which is
6546404b540aSrobert     usually QImode (this might actually be a bug in expmed.c). Note
6547404b540aSrobert     that the bit number is negative in big-endian mode in this case.
6548404b540aSrobert     We have to convert that to the offset.  */
6549404b540aSrobert  if (WORDS_BIG_ENDIAN)
6550404b540aSrobert    ofs = GET_MODE_BITSIZE (GET_MODE (operands[0]))
6551404b540aSrobert          - INTVAL (operands[1]) - INTVAL (operands[2]);
6552404b540aSrobert  else
6553404b540aSrobert    ofs = INTVAL (operands[2]);
6554404b540aSrobert
6555404b540aSrobert  ofs = ofs / 8;
6556404b540aSrobert
6557404b540aSrobert  alpha_expand_unaligned_store (operands[0], operands[3],
6558404b540aSrobert			        INTVAL (operands[1]) / 8, ofs);
6559404b540aSrobert  DONE;
6560404b540aSrobert})
6561404b540aSrobert
6562404b540aSrobert;; Block move/clear, see alpha.c for more details.
6563404b540aSrobert;; Argument 0 is the destination
6564404b540aSrobert;; Argument 1 is the source
6565404b540aSrobert;; Argument 2 is the length
6566404b540aSrobert;; Argument 3 is the alignment
6567404b540aSrobert
6568404b540aSrobert(define_expand "movmemqi"
6569404b540aSrobert  [(parallel [(set (match_operand:BLK 0 "memory_operand" "")
6570404b540aSrobert		   (match_operand:BLK 1 "memory_operand" ""))
6571404b540aSrobert	      (use (match_operand:DI 2 "immediate_operand" ""))
6572404b540aSrobert	      (use (match_operand:DI 3 "immediate_operand" ""))])]
6573404b540aSrobert  ""
6574404b540aSrobert{
6575404b540aSrobert  if (alpha_expand_block_move (operands))
6576404b540aSrobert    DONE;
6577404b540aSrobert  else
6578404b540aSrobert    FAIL;
6579404b540aSrobert})
6580404b540aSrobert
6581404b540aSrobert(define_expand "movmemdi"
6582404b540aSrobert  [(parallel [(set (match_operand:BLK 0 "memory_operand" "")
6583404b540aSrobert		   (match_operand:BLK 1 "memory_operand" ""))
6584404b540aSrobert	      (use (match_operand:DI 2 "immediate_operand" ""))
6585404b540aSrobert	      (use (match_operand:DI 3 "immediate_operand" ""))
6586404b540aSrobert	      (use (match_dup 4))
6587404b540aSrobert	      (clobber (reg:DI 25))
6588404b540aSrobert	      (clobber (reg:DI 16))
6589404b540aSrobert	      (clobber (reg:DI 17))
6590404b540aSrobert	      (clobber (reg:DI 18))
6591404b540aSrobert	      (clobber (reg:DI 19))
6592404b540aSrobert	      (clobber (reg:DI 20))
6593404b540aSrobert	      (clobber (reg:DI 26))
6594404b540aSrobert	      (clobber (reg:DI 27))])]
6595404b540aSrobert  "TARGET_ABI_OPEN_VMS"
6596404b540aSrobert{
6597404b540aSrobert  operands[4] = gen_rtx_SYMBOL_REF (Pmode, "OTS$MOVE");
6598404b540aSrobert  alpha_need_linkage (XSTR (operands[4], 0), 0);
6599404b540aSrobert})
6600404b540aSrobert
6601404b540aSrobert(define_insn "*movmemdi_1"
6602404b540aSrobert  [(set (match_operand:BLK 0 "memory_operand" "=m,=m")
6603404b540aSrobert	(match_operand:BLK 1 "memory_operand" "m,m"))
6604404b540aSrobert   (use (match_operand:DI 2 "nonmemory_operand" "r,i"))
6605404b540aSrobert   (use (match_operand:DI 3 "immediate_operand" ""))
6606404b540aSrobert   (use (match_operand:DI 4 "call_operand" "i,i"))
6607404b540aSrobert   (clobber (reg:DI 25))
6608404b540aSrobert   (clobber (reg:DI 16))
6609404b540aSrobert   (clobber (reg:DI 17))
6610404b540aSrobert   (clobber (reg:DI 18))
6611404b540aSrobert   (clobber (reg:DI 19))
6612404b540aSrobert   (clobber (reg:DI 20))
6613404b540aSrobert   (clobber (reg:DI 26))
6614404b540aSrobert   (clobber (reg:DI 27))]
6615404b540aSrobert  "TARGET_ABI_OPEN_VMS"
6616404b540aSrobert{
6617404b540aSrobert  operands [5] = alpha_use_linkage (operands [4], cfun->decl, 0, 1);
6618404b540aSrobert  switch (which_alternative)
6619404b540aSrobert    {
6620404b540aSrobert    case 0:
6621404b540aSrobert	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)";
6622404b540aSrobert    case 1:
6623404b540aSrobert	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)";
6624404b540aSrobert    default:
6625404b540aSrobert      gcc_unreachable ();
6626404b540aSrobert    }
6627404b540aSrobert}
6628404b540aSrobert  [(set_attr "type" "multi")
6629404b540aSrobert   (set_attr "length" "28")])
6630404b540aSrobert
6631404b540aSrobert(define_expand "setmemqi"
6632404b540aSrobert  [(parallel [(set (match_operand:BLK 0 "memory_operand" "")
6633404b540aSrobert		   (match_operand 2 "const_int_operand" ""))
6634404b540aSrobert	      (use (match_operand:DI 1 "immediate_operand" ""))
6635404b540aSrobert	      (use (match_operand:DI 3 "immediate_operand" ""))])]
6636404b540aSrobert  ""
6637404b540aSrobert{
6638404b540aSrobert  /* If value to set is not zero, use the library routine.  */
6639404b540aSrobert  if (operands[2] != const0_rtx)
6640404b540aSrobert    FAIL;
6641404b540aSrobert
6642404b540aSrobert  if (alpha_expand_block_clear (operands))
6643404b540aSrobert    DONE;
6644404b540aSrobert  else
6645404b540aSrobert    FAIL;
6646404b540aSrobert})
6647404b540aSrobert
6648404b540aSrobert(define_expand "setmemdi"
6649404b540aSrobert  [(parallel [(set (match_operand:BLK 0 "memory_operand" "")
6650404b540aSrobert		   (match_operand 2 "const_int_operand" ""))
6651404b540aSrobert	      (use (match_operand:DI 1 "immediate_operand" ""))
6652404b540aSrobert	      (use (match_operand:DI 3 "immediate_operand" ""))
6653404b540aSrobert	      (use (match_dup 4))
6654404b540aSrobert	      (clobber (reg:DI 25))
6655404b540aSrobert	      (clobber (reg:DI 16))
6656404b540aSrobert	      (clobber (reg:DI 17))
6657404b540aSrobert	      (clobber (reg:DI 26))
6658404b540aSrobert	      (clobber (reg:DI 27))])]
6659404b540aSrobert  "TARGET_ABI_OPEN_VMS"
6660404b540aSrobert{
6661404b540aSrobert  /* If value to set is not zero, use the library routine.  */
6662404b540aSrobert  if (operands[2] != const0_rtx)
6663404b540aSrobert    FAIL;
6664404b540aSrobert
6665404b540aSrobert  operands[4] = gen_rtx_SYMBOL_REF (Pmode, "OTS$ZERO");
6666404b540aSrobert  alpha_need_linkage (XSTR (operands[4], 0), 0);
6667404b540aSrobert})
6668404b540aSrobert
6669404b540aSrobert(define_insn "*clrmemdi_1"
6670404b540aSrobert  [(set (match_operand:BLK 0 "memory_operand" "=m,=m")
6671404b540aSrobert		   (const_int 0))
6672404b540aSrobert   (use (match_operand:DI 1 "nonmemory_operand" "r,i"))
6673404b540aSrobert   (use (match_operand:DI 2 "immediate_operand" ""))
6674404b540aSrobert   (use (match_operand:DI 3 "call_operand" "i,i"))
6675404b540aSrobert   (clobber (reg:DI 25))
6676404b540aSrobert   (clobber (reg:DI 16))
6677404b540aSrobert   (clobber (reg:DI 17))
6678404b540aSrobert   (clobber (reg:DI 26))
6679404b540aSrobert   (clobber (reg:DI 27))]
6680404b540aSrobert  "TARGET_ABI_OPEN_VMS"
6681404b540aSrobert{
6682404b540aSrobert  operands [4] = alpha_use_linkage (operands [3], cfun->decl, 0, 1);
6683404b540aSrobert  switch (which_alternative)
6684404b540aSrobert    {
6685404b540aSrobert    case 0:
6686404b540aSrobert	return "lda $16,%0\;bis $31,%1,$17\;ldq $26,%4\;lda $25,2($31)\;jsr $26,%3\;ldq $27,0($29)";
6687404b540aSrobert    case 1:
6688404b540aSrobert	return "lda $16,%0\;lda $17,%1($31)\;ldq $26,%4\;lda $25,2($31)\;jsr $26,%3\;ldq $27,0($29)";
6689404b540aSrobert    default:
6690404b540aSrobert      gcc_unreachable ();
6691404b540aSrobert    }
6692404b540aSrobert}
6693404b540aSrobert  [(set_attr "type" "multi")
6694404b540aSrobert   (set_attr "length" "24")])
6695404b540aSrobert
6696404b540aSrobert
6697404b540aSrobert;; Subroutine of stack space allocation.  Perform a stack probe.
6698404b540aSrobert(define_expand "probe_stack"
6699404b540aSrobert  [(set (match_dup 1) (match_operand:DI 0 "const_int_operand" ""))]
6700404b540aSrobert  ""
6701404b540aSrobert{
6702404b540aSrobert  operands[1] = gen_rtx_MEM (DImode, plus_constant (stack_pointer_rtx,
6703404b540aSrobert						    INTVAL (operands[0])));
6704404b540aSrobert  MEM_VOLATILE_P (operands[1]) = 1;
6705404b540aSrobert
6706404b540aSrobert  operands[0] = const0_rtx;
6707404b540aSrobert})
6708404b540aSrobert
6709404b540aSrobert;; This is how we allocate stack space.  If we are allocating a
6710404b540aSrobert;; constant amount of space and we know it is less than 4096
6711404b540aSrobert;; bytes, we need do nothing.
6712404b540aSrobert;;
6713404b540aSrobert;; If it is more than 4096 bytes, we need to probe the stack
6714404b540aSrobert;; periodically.
6715404b540aSrobert(define_expand "allocate_stack"
6716404b540aSrobert  [(set (reg:DI 30)
6717404b540aSrobert	(plus:DI (reg:DI 30)
6718404b540aSrobert		 (match_operand:DI 1 "reg_or_cint_operand" "")))
6719404b540aSrobert   (set (match_operand:DI 0 "register_operand" "=r")
6720404b540aSrobert	(match_dup 2))]
6721404b540aSrobert  ""
6722404b540aSrobert{
6723404b540aSrobert  if (GET_CODE (operands[1]) == CONST_INT
6724404b540aSrobert      && INTVAL (operands[1]) < 32768)
6725404b540aSrobert    {
6726f462341cSnaddy      if (INTVAL (operands[1]) >= 4096
6727f462341cSnaddy	  && (flag_stack_check || STACK_CHECK_BUILTIN))
6728404b540aSrobert	{
6729404b540aSrobert	  /* We do this the same way as in the prologue and generate explicit
6730404b540aSrobert	     probes.  Then we update the stack by the constant.  */
6731404b540aSrobert
6732404b540aSrobert	  int probed = 4096;
6733404b540aSrobert
6734404b540aSrobert	  emit_insn (gen_probe_stack (GEN_INT (- probed)));
6735404b540aSrobert	  while (probed + 8192 < INTVAL (operands[1]))
6736404b540aSrobert	    emit_insn (gen_probe_stack (GEN_INT (- (probed += 8192))));
6737404b540aSrobert
6738404b540aSrobert	  if (probed + 4096 < INTVAL (operands[1]))
6739404b540aSrobert	    emit_insn (gen_probe_stack (GEN_INT (- INTVAL(operands[1]))));
6740404b540aSrobert	}
6741404b540aSrobert
6742404b540aSrobert      operands[1] = GEN_INT (- INTVAL (operands[1]));
6743404b540aSrobert      operands[2] = virtual_stack_dynamic_rtx;
6744404b540aSrobert    }
6745404b540aSrobert  else
6746404b540aSrobert    {
6747404b540aSrobert      rtx out_label = 0;
6748404b540aSrobert      rtx loop_label = gen_label_rtx ();
6749404b540aSrobert      rtx want = gen_reg_rtx (Pmode);
6750404b540aSrobert      rtx tmp = gen_reg_rtx (Pmode);
6751404b540aSrobert      rtx memref;
6752404b540aSrobert
6753404b540aSrobert      emit_insn (gen_subdi3 (want, stack_pointer_rtx,
6754404b540aSrobert			     force_reg (Pmode, operands[1])));
6755404b540aSrobert      emit_insn (gen_adddi3 (tmp, stack_pointer_rtx, GEN_INT (-4096)));
6756404b540aSrobert
6757404b540aSrobert      if (GET_CODE (operands[1]) != CONST_INT)
6758404b540aSrobert	{
6759404b540aSrobert	  out_label = gen_label_rtx ();
6760404b540aSrobert	  emit_insn (gen_cmpdi (want, tmp));
6761404b540aSrobert	  emit_jump_insn (gen_bgeu (out_label));
6762404b540aSrobert	}
6763404b540aSrobert
6764404b540aSrobert      emit_label (loop_label);
6765404b540aSrobert      memref = gen_rtx_MEM (DImode, tmp);
6766404b540aSrobert      MEM_VOLATILE_P (memref) = 1;
6767404b540aSrobert      emit_move_insn (memref, const0_rtx);
6768404b540aSrobert      emit_insn (gen_adddi3 (tmp, tmp, GEN_INT(-8192)));
6769404b540aSrobert      emit_insn (gen_cmpdi (tmp, want));
6770404b540aSrobert      emit_jump_insn (gen_bgtu (loop_label));
6771404b540aSrobert
6772404b540aSrobert      memref = gen_rtx_MEM (DImode, want);
6773404b540aSrobert      MEM_VOLATILE_P (memref) = 1;
6774404b540aSrobert      emit_move_insn (memref, const0_rtx);
6775404b540aSrobert
6776404b540aSrobert      if (out_label)
6777404b540aSrobert	emit_label (out_label);
6778404b540aSrobert
6779404b540aSrobert      emit_move_insn (stack_pointer_rtx, want);
6780404b540aSrobert      emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
6781404b540aSrobert      DONE;
6782404b540aSrobert    }
6783404b540aSrobert})
6784404b540aSrobert
6785404b540aSrobert;; This is used by alpha_expand_prolog to do the same thing as above,
6786404b540aSrobert;; except we cannot at that time generate new basic blocks, so we hide
6787404b540aSrobert;; the loop in this one insn.
6788404b540aSrobert
6789404b540aSrobert(define_insn "prologue_stack_probe_loop"
6790404b540aSrobert  [(unspec_volatile [(match_operand:DI 0 "register_operand" "r")
6791404b540aSrobert		     (match_operand:DI 1 "register_operand" "r")]
6792404b540aSrobert		    UNSPECV_PSPL)]
6793404b540aSrobert  ""
6794404b540aSrobert{
6795404b540aSrobert  operands[2] = gen_label_rtx ();
6796404b540aSrobert  (*targetm.asm_out.internal_label) (asm_out_file, "L",
6797404b540aSrobert			     CODE_LABEL_NUMBER (operands[2]));
6798404b540aSrobert
6799404b540aSrobert  return "stq $31,-8192(%1)\;subq %0,1,%0\;lda %1,-8192(%1)\;bne %0,%l2";
6800404b540aSrobert}
6801404b540aSrobert  [(set_attr "length" "16")
6802404b540aSrobert   (set_attr "type" "multi")])
6803404b540aSrobert
6804404b540aSrobert(define_expand "prologue"
6805404b540aSrobert  [(clobber (const_int 0))]
6806404b540aSrobert  ""
6807404b540aSrobert{
6808404b540aSrobert  alpha_expand_prologue ();
6809404b540aSrobert  DONE;
6810404b540aSrobert})
6811404b540aSrobert
6812404b540aSrobert;; These take care of emitting the ldgp insn in the prologue. This will be
6813404b540aSrobert;; an lda/ldah pair and we want to align them properly.  So we have two
6814404b540aSrobert;; unspec_volatile insns, the first of which emits the ldgp assembler macro
6815404b540aSrobert;; and the second of which emits nothing.  However, both are marked as type
6816404b540aSrobert;; IADD (the default) so the alignment code in alpha.c does the right thing
6817404b540aSrobert;; with them.
6818404b540aSrobert
6819404b540aSrobert(define_expand "prologue_ldgp"
6820404b540aSrobert  [(set (match_dup 0)
6821404b540aSrobert	(unspec_volatile:DI [(match_dup 1) (match_dup 2)] UNSPECV_LDGP1))
6822404b540aSrobert   (set (match_dup 0)
6823404b540aSrobert	(unspec_volatile:DI [(match_dup 0) (match_dup 2)] UNSPECV_PLDGP2))]
6824404b540aSrobert  ""
6825404b540aSrobert{
6826404b540aSrobert  operands[0] = pic_offset_table_rtx;
6827404b540aSrobert  operands[1] = gen_rtx_REG (Pmode, 27);
6828404b540aSrobert  operands[2] = (TARGET_EXPLICIT_RELOCS
6829404b540aSrobert		 ? GEN_INT (alpha_next_sequence_number++)
6830404b540aSrobert		 : const0_rtx);
6831404b540aSrobert})
6832404b540aSrobert
6833404b540aSrobert(define_insn "*ldgp_er_1"
6834404b540aSrobert  [(set (match_operand:DI 0 "register_operand" "=r")
6835404b540aSrobert	(unspec_volatile:DI [(match_operand:DI 1 "register_operand" "r")
6836404b540aSrobert			     (match_operand 2 "const_int_operand" "")]
6837404b540aSrobert			    UNSPECV_LDGP1))]
6838404b540aSrobert  "TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF"
6839404b540aSrobert  "ldah %0,0(%1)\t\t!gpdisp!%2"
6840404b540aSrobert  [(set_attr "cannot_copy" "true")])
6841404b540aSrobert
6842404b540aSrobert(define_insn "*ldgp_er_2"
6843404b540aSrobert  [(set (match_operand:DI 0 "register_operand" "=r")
6844404b540aSrobert	(unspec:DI [(match_operand:DI 1 "register_operand" "r")
6845404b540aSrobert		    (match_operand 2 "const_int_operand" "")]
6846404b540aSrobert		   UNSPEC_LDGP2))]
6847404b540aSrobert  "TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF"
6848404b540aSrobert  "lda %0,0(%1)\t\t!gpdisp!%2"
6849404b540aSrobert  [(set_attr "cannot_copy" "true")])
6850404b540aSrobert
6851404b540aSrobert(define_insn "*prologue_ldgp_er_2"
6852404b540aSrobert  [(set (match_operand:DI 0 "register_operand" "=r")
6853404b540aSrobert	(unspec_volatile:DI [(match_operand:DI 1 "register_operand" "r")
6854404b540aSrobert			     (match_operand 2 "const_int_operand" "")]
6855404b540aSrobert		   	    UNSPECV_PLDGP2))]
6856404b540aSrobert  "TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF"
6857404b540aSrobert  "lda %0,0(%1)\t\t!gpdisp!%2\n$%~..ng:"
6858404b540aSrobert  [(set_attr "cannot_copy" "true")])
6859404b540aSrobert
6860404b540aSrobert(define_insn "*prologue_ldgp_1"
6861404b540aSrobert  [(set (match_operand:DI 0 "register_operand" "=r")
6862404b540aSrobert	(unspec_volatile:DI [(match_operand:DI 1 "register_operand" "r")
6863404b540aSrobert			     (match_operand 2 "const_int_operand" "")]
6864404b540aSrobert			    UNSPECV_LDGP1))]
6865404b540aSrobert  ""
6866404b540aSrobert  "ldgp %0,0(%1)\n$%~..ng:"
6867404b540aSrobert  [(set_attr "cannot_copy" "true")])
6868404b540aSrobert
6869404b540aSrobert(define_insn "*prologue_ldgp_2"
6870404b540aSrobert  [(set (match_operand:DI 0 "register_operand" "=r")
6871404b540aSrobert	(unspec_volatile:DI [(match_operand:DI 1 "register_operand" "r")
6872404b540aSrobert			     (match_operand 2 "const_int_operand" "")]
6873404b540aSrobert		   	    UNSPECV_PLDGP2))]
6874404b540aSrobert  ""
6875404b540aSrobert  "")
6876404b540aSrobert
6877404b540aSrobert;; The _mcount profiling hook has special calling conventions, and
6878404b540aSrobert;; does not clobber all the registers that a normal call would.  So
6879404b540aSrobert;; hide the fact this is a call at all.
6880404b540aSrobert
6881404b540aSrobert(define_insn "prologue_mcount"
6882404b540aSrobert  [(unspec_volatile [(const_int 0)] UNSPECV_MCOUNT)]
6883404b540aSrobert  ""
6884404b540aSrobert{
6885404b540aSrobert  if (TARGET_EXPLICIT_RELOCS)
6886404b540aSrobert    /* Note that we cannot use a lituse_jsr reloc, since _mcount
6887404b540aSrobert       cannot be called via the PLT.  */
6888404b540aSrobert    return "ldq $28,_mcount($29)\t\t!literal\;jsr $28,($28),_mcount";
6889404b540aSrobert  else
6890404b540aSrobert    return "lda $28,_mcount\;jsr $28,($28),_mcount";
6891404b540aSrobert}
6892404b540aSrobert  [(set_attr "type" "multi")
6893404b540aSrobert   (set_attr "length" "8")])
6894404b540aSrobert
6895404b540aSrobert(define_insn "init_fp"
6896404b540aSrobert  [(set (match_operand:DI 0 "register_operand" "=r")
6897404b540aSrobert        (match_operand:DI 1 "register_operand" "r"))
6898404b540aSrobert   (clobber (mem:BLK (match_operand:DI 2 "register_operand" "=r")))]
6899404b540aSrobert  ""
6900404b540aSrobert  "bis $31,%1,%0")
6901404b540aSrobert
6902404b540aSrobert(define_expand "epilogue"
6903404b540aSrobert  [(return)]
6904404b540aSrobert  ""
6905404b540aSrobert{
6906404b540aSrobert  alpha_expand_epilogue ();
6907404b540aSrobert})
6908404b540aSrobert
6909404b540aSrobert(define_expand "sibcall_epilogue"
6910404b540aSrobert  [(return)]
6911404b540aSrobert  "TARGET_ABI_OSF"
6912404b540aSrobert{
6913404b540aSrobert  alpha_expand_epilogue ();
6914404b540aSrobert  DONE;
6915404b540aSrobert})
6916404b540aSrobert
6917404b540aSrobert(define_expand "builtin_longjmp"
6918404b540aSrobert  [(use (match_operand:DI 0 "register_operand" "r"))]
6919404b540aSrobert  "TARGET_ABI_OSF"
6920404b540aSrobert{
6921404b540aSrobert  /* The elements of the buffer are, in order:  */
6922404b540aSrobert  rtx fp = gen_rtx_MEM (Pmode, operands[0]);
6923404b540aSrobert  rtx lab = gen_rtx_MEM (Pmode, plus_constant (operands[0], 8));
6924404b540aSrobert  rtx stack = gen_rtx_MEM (Pmode, plus_constant (operands[0], 16));
6925404b540aSrobert  rtx pv = gen_rtx_REG (Pmode, 27);
6926404b540aSrobert
6927404b540aSrobert  /* This bit is the same as expand_builtin_longjmp.  */
6928404b540aSrobert  emit_move_insn (hard_frame_pointer_rtx, fp);
6929404b540aSrobert  emit_move_insn (pv, lab);
6930404b540aSrobert  emit_stack_restore (SAVE_NONLOCAL, stack, NULL_RTX);
6931404b540aSrobert  emit_insn (gen_rtx_USE (VOIDmode, hard_frame_pointer_rtx));
6932404b540aSrobert  emit_insn (gen_rtx_USE (VOIDmode, stack_pointer_rtx));
6933404b540aSrobert
6934404b540aSrobert  /* Load the label we are jumping through into $27 so that we know
6935404b540aSrobert     where to look for it when we get back to setjmp's function for
6936404b540aSrobert     restoring the gp.  */
6937404b540aSrobert  emit_jump_insn (gen_builtin_longjmp_internal (pv));
6938404b540aSrobert  emit_barrier ();
6939404b540aSrobert  DONE;
6940404b540aSrobert})
6941404b540aSrobert
6942404b540aSrobert;; This is effectively a copy of indirect_jump, but constrained such
6943404b540aSrobert;; that register renaming cannot foil our cunning plan with $27.
6944404b540aSrobert(define_insn "builtin_longjmp_internal"
6945404b540aSrobert  [(set (pc)
6946404b540aSrobert	(unspec_volatile [(match_operand:DI 0 "register_operand" "c")]
6947404b540aSrobert			 UNSPECV_LONGJMP))]
6948404b540aSrobert  ""
6949404b540aSrobert  "jmp $31,(%0),0"
6950404b540aSrobert  [(set_attr "type" "ibr")])
6951404b540aSrobert
6952404b540aSrobert(define_expand "builtin_setjmp_receiver"
6953404b540aSrobert  [(unspec_volatile [(label_ref (match_operand 0 "" ""))] UNSPECV_SETJMPR)]
6954404b540aSrobert  "TARGET_ABI_OSF"
6955404b540aSrobert  "")
6956404b540aSrobert
6957404b540aSrobert(define_insn_and_split "*builtin_setjmp_receiver_1"
6958404b540aSrobert  [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_SETJMPR)]
6959404b540aSrobert  "TARGET_ABI_OSF"
6960404b540aSrobert{
6961404b540aSrobert  if (TARGET_EXPLICIT_RELOCS)
6962404b540aSrobert    return "#";
6963404b540aSrobert  else
6964404b540aSrobert    return "br $27,$LSJ%=\n$LSJ%=:\;ldgp $29,0($27)";
6965404b540aSrobert}
6966404b540aSrobert  "&& TARGET_EXPLICIT_RELOCS && reload_completed"
6967404b540aSrobert  [(set (match_dup 1)
6968404b540aSrobert	(unspec_volatile:DI [(match_dup 2) (match_dup 3)] UNSPECV_LDGP1))
6969404b540aSrobert   (set (match_dup 1)
6970404b540aSrobert	(unspec:DI [(match_dup 1) (match_dup 3)] UNSPEC_LDGP2))]
6971404b540aSrobert{
6972404b540aSrobert  if (prev_nonnote_insn (curr_insn) != XEXP (operands[0], 0))
6973404b540aSrobert    emit_insn (gen_rtx_UNSPEC_VOLATILE (VOIDmode, gen_rtvec (1, operands[0]),
6974404b540aSrobert					UNSPECV_SETJMPR_ER));
6975404b540aSrobert  operands[1] = pic_offset_table_rtx;
6976404b540aSrobert  operands[2] = gen_rtx_REG (Pmode, 27);
6977404b540aSrobert  operands[3] = GEN_INT (alpha_next_sequence_number++);
6978404b540aSrobert}
6979404b540aSrobert  [(set_attr "length" "12")
6980404b540aSrobert   (set_attr "type" "multi")])
6981404b540aSrobert
6982404b540aSrobert(define_insn "*builtin_setjmp_receiver_er_sl_1"
6983404b540aSrobert  [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_SETJMPR_ER)]
6984404b540aSrobert  "TARGET_ABI_OSF && TARGET_EXPLICIT_RELOCS && TARGET_AS_CAN_SUBTRACT_LABELS"
6985404b540aSrobert  "lda $27,$LSJ%=-%l0($27)\n$LSJ%=:")
6986404b540aSrobert
6987404b540aSrobert(define_insn "*builtin_setjmp_receiver_er_1"
6988404b540aSrobert  [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_SETJMPR_ER)]
6989404b540aSrobert  "TARGET_ABI_OSF && TARGET_EXPLICIT_RELOCS"
6990404b540aSrobert  "br $27,$LSJ%=\n$LSJ%=:"
6991404b540aSrobert  [(set_attr "type" "ibr")])
6992404b540aSrobert
6993404b540aSrobert(define_expand "exception_receiver"
6994404b540aSrobert  [(unspec_volatile [(match_dup 0)] UNSPECV_EHR)]
6995404b540aSrobert  "TARGET_ABI_OSF"
6996404b540aSrobert{
6997404b540aSrobert  if (TARGET_LD_BUGGY_LDGP)
6998404b540aSrobert    operands[0] = alpha_gp_save_rtx ();
6999404b540aSrobert  else
7000404b540aSrobert    operands[0] = const0_rtx;
7001404b540aSrobert})
7002404b540aSrobert
7003404b540aSrobert(define_insn "*exception_receiver_2"
7004404b540aSrobert  [(unspec_volatile [(match_operand:DI 0 "memory_operand" "m")] UNSPECV_EHR)]
7005404b540aSrobert  "TARGET_ABI_OSF && TARGET_LD_BUGGY_LDGP"
7006404b540aSrobert  "ldq $29,%0"
7007404b540aSrobert  [(set_attr "type" "ild")])
7008404b540aSrobert
7009404b540aSrobert(define_insn_and_split "*exception_receiver_1"
7010404b540aSrobert  [(unspec_volatile [(const_int 0)] UNSPECV_EHR)]
7011404b540aSrobert  "TARGET_ABI_OSF"
7012404b540aSrobert{
7013404b540aSrobert  if (TARGET_EXPLICIT_RELOCS)
7014404b540aSrobert    return "ldah $29,0($26)\t\t!gpdisp!%*\;lda $29,0($29)\t\t!gpdisp!%*";
7015404b540aSrobert  else
7016404b540aSrobert    return "ldgp $29,0($26)";
7017404b540aSrobert}
7018404b540aSrobert  "&& TARGET_EXPLICIT_RELOCS && reload_completed"
7019404b540aSrobert  [(set (match_dup 0)
7020404b540aSrobert	(unspec_volatile:DI [(match_dup 1) (match_dup 2)] UNSPECV_LDGP1))
7021404b540aSrobert   (set (match_dup 0)
7022404b540aSrobert	(unspec:DI [(match_dup 0) (match_dup 2)] UNSPEC_LDGP2))]
7023404b540aSrobert{
7024404b540aSrobert  operands[0] = pic_offset_table_rtx;
7025404b540aSrobert  operands[1] = gen_rtx_REG (Pmode, 26);
7026404b540aSrobert  operands[2] = GEN_INT (alpha_next_sequence_number++);
7027404b540aSrobert}
7028404b540aSrobert  [(set_attr "length" "8")
7029404b540aSrobert   (set_attr "type" "multi")])
7030404b540aSrobert
7031404b540aSrobert(define_expand "nonlocal_goto_receiver"
7032404b540aSrobert  [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
7033404b540aSrobert   (set (reg:DI 27) (mem:DI (reg:DI 29)))
7034404b540aSrobert   (unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
7035404b540aSrobert   (use (reg:DI 27))]
7036404b540aSrobert  "TARGET_ABI_OPEN_VMS"
7037404b540aSrobert  "")
7038404b540aSrobert
7039404b540aSrobert(define_insn "arg_home"
7040404b540aSrobert  [(unspec [(const_int 0)] UNSPEC_ARG_HOME)
7041404b540aSrobert   (use (reg:DI 1))
7042404b540aSrobert   (use (reg:DI 25))
7043404b540aSrobert   (use (reg:DI 16))
7044404b540aSrobert   (use (reg:DI 17))
7045404b540aSrobert   (use (reg:DI 18))
7046404b540aSrobert   (use (reg:DI 19))
7047404b540aSrobert   (use (reg:DI 20))
7048404b540aSrobert   (use (reg:DI 21))
7049404b540aSrobert   (use (reg:DI 48))
7050404b540aSrobert   (use (reg:DI 49))
7051404b540aSrobert   (use (reg:DI 50))
7052404b540aSrobert   (use (reg:DI 51))
7053404b540aSrobert   (use (reg:DI 52))
7054404b540aSrobert   (use (reg:DI 53))
7055404b540aSrobert   (clobber (mem:BLK (const_int 0)))
7056404b540aSrobert   (clobber (reg:DI 24))
7057404b540aSrobert   (clobber (reg:DI 25))
7058404b540aSrobert   (clobber (reg:DI 0))]
7059404b540aSrobert  "TARGET_ABI_OPEN_VMS"
7060404b540aSrobert  "lda $0,OTS$HOME_ARGS\;ldq $0,8($0)\;jsr $0,OTS$HOME_ARGS"
7061404b540aSrobert  [(set_attr "length" "16")
7062404b540aSrobert   (set_attr "type" "multi")])
7063404b540aSrobert
7064404b540aSrobert;; Load the CIW into r2 for calling __T3E_MISMATCH
7065404b540aSrobert
7066404b540aSrobert(define_expand "umk_mismatch_args"
7067404b540aSrobert  [(set:DI (match_dup 1) (mem:DI (plus:DI (reg:DI 15) (const_int -16))))
7068404b540aSrobert   (set:DI (match_dup 2) (mem:DI (plus:DI (match_dup 1) (const_int -32))))
7069404b540aSrobert   (set:DI (reg:DI 1) (match_operand:DI 0 "const_int_operand" ""))
7070404b540aSrobert   (set:DI (match_dup 3) (plus:DI (mult:DI (reg:DI 25)
7071404b540aSrobert					   (const_int 8))
7072404b540aSrobert				  (match_dup 2)))
7073404b540aSrobert   (set:DI (reg:DI 2) (mem:DI (match_dup 3)))]
7074404b540aSrobert  "TARGET_ABI_UNICOSMK"
7075404b540aSrobert{
7076404b540aSrobert  operands[1] = gen_reg_rtx (DImode);
7077404b540aSrobert  operands[2] = gen_reg_rtx (DImode);
7078404b540aSrobert  operands[3] = gen_reg_rtx (DImode);
7079404b540aSrobert})
7080404b540aSrobert
7081404b540aSrobert(define_insn "arg_home_umk"
7082404b540aSrobert  [(unspec [(const_int 0)] UNSPEC_ARG_HOME)
7083404b540aSrobert   (use (reg:DI 1))
7084404b540aSrobert   (use (reg:DI 2))
7085404b540aSrobert   (use (reg:DI 16))
7086404b540aSrobert   (use (reg:DI 17))
7087404b540aSrobert   (use (reg:DI 18))
7088404b540aSrobert   (use (reg:DI 19))
7089404b540aSrobert   (use (reg:DI 20))
7090404b540aSrobert   (use (reg:DI 21))
7091404b540aSrobert   (use (reg:DI 48))
7092404b540aSrobert   (use (reg:DI 49))
7093404b540aSrobert   (use (reg:DI 50))
7094404b540aSrobert   (use (reg:DI 51))
7095404b540aSrobert   (use (reg:DI 52))
7096404b540aSrobert   (use (reg:DI 53))
7097404b540aSrobert   (clobber (mem:BLK (const_int 0)))
7098404b540aSrobert   (parallel [
7099404b540aSrobert   (clobber (reg:DI 22))
7100404b540aSrobert   (clobber (reg:DI 23))
7101404b540aSrobert   (clobber (reg:DI 24))
7102404b540aSrobert   (clobber (reg:DI 0))
7103404b540aSrobert   (clobber (reg:DI 1))
7104404b540aSrobert   (clobber (reg:DI 2))
7105404b540aSrobert   (clobber (reg:DI 3))
7106404b540aSrobert   (clobber (reg:DI 4))
7107404b540aSrobert   (clobber (reg:DI 5))
7108404b540aSrobert   (clobber (reg:DI 6))
7109404b540aSrobert   (clobber (reg:DI 7))
7110404b540aSrobert   (clobber (reg:DI 8))])]
7111404b540aSrobert  "TARGET_ABI_UNICOSMK"
7112404b540aSrobert  "laum $4,__T3E_MISMATCH($31)\;sll $4,32,$4\;lalm $4,__T3E_MISMATCH($4)\;lal $4,__T3E_MISMATCH($4)\;jsr $3,($4)"
7113404b540aSrobert  [(set_attr "length" "16")
7114404b540aSrobert   (set_attr "type" "multi")])
7115404b540aSrobert
7116404b540aSrobert;; Prefetch data.
7117404b540aSrobert;;
7118404b540aSrobert;; On EV4, these instructions are nops -- no load occurs.
7119404b540aSrobert;;
7120404b540aSrobert;; On EV5, these instructions act as a normal load, and thus can trap
7121404b540aSrobert;; if the address is invalid.  The OS may (or may not) handle this in
7122404b540aSrobert;; the entMM fault handler and suppress the fault.  If so, then this
7123404b540aSrobert;; has the effect of a read prefetch instruction.
7124404b540aSrobert;;
7125404b540aSrobert;; On EV6, these become official prefetch instructions.
7126404b540aSrobert
7127404b540aSrobert(define_insn "prefetch"
7128404b540aSrobert  [(prefetch (match_operand:DI 0 "address_operand" "p")
7129404b540aSrobert	     (match_operand:DI 1 "const_int_operand" "n")
7130404b540aSrobert	     (match_operand:DI 2 "const_int_operand" "n"))]
7131404b540aSrobert  "TARGET_FIXUP_EV5_PREFETCH || alpha_cpu == PROCESSOR_EV6"
7132404b540aSrobert{
7133404b540aSrobert  /* Interpret "no temporal locality" as this data should be evicted once
7134404b540aSrobert     it is used.  The "evict next" alternatives load the data into the cache
7135404b540aSrobert     and leave the LRU eviction counter pointing to that block.  */
7136404b540aSrobert  static const char * const alt[2][2] = {
7137404b540aSrobert    {
7138404b540aSrobert      "ldq $31,%a0",		/* read, evict next */
7139404b540aSrobert      "ldl $31,%a0",		/* read, evict last */
7140404b540aSrobert    },
7141404b540aSrobert    {
7142404b540aSrobert      "ldt $f31,%a0",		/* write, evict next */
7143404b540aSrobert      "lds $f31,%a0",		/* write, evict last */
7144404b540aSrobert    }
7145404b540aSrobert  };
7146404b540aSrobert
7147404b540aSrobert  bool write = INTVAL (operands[1]) != 0;
7148404b540aSrobert  bool lru = INTVAL (operands[2]) != 0;
7149404b540aSrobert
7150404b540aSrobert  return alt[write][lru];
7151404b540aSrobert}
7152404b540aSrobert  [(set_attr "type" "ild")])
7153404b540aSrobert
7154404b540aSrobert;; Close the trap shadow of preceding instructions.  This is generated
7155404b540aSrobert;; by alpha_reorg.
7156404b540aSrobert
7157404b540aSrobert(define_insn "trapb"
7158404b540aSrobert  [(unspec_volatile [(const_int 0)] UNSPECV_TRAPB)]
7159404b540aSrobert  ""
7160404b540aSrobert  "trapb"
7161404b540aSrobert  [(set_attr "type" "misc")])
7162404b540aSrobert
7163404b540aSrobert;; No-op instructions used by machine-dependent reorg to preserve
7164404b540aSrobert;; alignment for instruction issue.
7165404b540aSrobert;; The Unicos/Mk assembler does not support these opcodes.
7166404b540aSrobert
7167404b540aSrobert(define_insn "nop"
7168404b540aSrobert  [(const_int 0)]
7169404b540aSrobert  ""
7170404b540aSrobert  "bis $31,$31,$31"
7171404b540aSrobert  [(set_attr "type" "ilog")])
7172404b540aSrobert
7173404b540aSrobert(define_insn "fnop"
7174404b540aSrobert  [(const_int 1)]
7175404b540aSrobert  "TARGET_FP"
7176404b540aSrobert  "cpys $f31,$f31,$f31"
7177404b540aSrobert  [(set_attr "type" "fcpys")])
7178404b540aSrobert
7179404b540aSrobert(define_insn "unop"
7180404b540aSrobert  [(const_int 2)]
7181404b540aSrobert  ""
7182404b540aSrobert  "ldq_u $31,0($30)")
7183404b540aSrobert
7184404b540aSrobert;; On Unicos/Mk we use a macro for aligning code.
7185404b540aSrobert
7186404b540aSrobert(define_insn "realign"
7187404b540aSrobert  [(unspec_volatile [(match_operand 0 "immediate_operand" "i")]
7188404b540aSrobert		    UNSPECV_REALIGN)]
7189404b540aSrobert  ""
7190404b540aSrobert{
7191404b540aSrobert  if (TARGET_ABI_UNICOSMK)
7192404b540aSrobert    return "gcc@code@align %0";
7193404b540aSrobert  else
7194404b540aSrobert    return ".align %0 #realign";
7195404b540aSrobert})
7196404b540aSrobert
7197404b540aSrobert;; Instructions to be emitted from __builtins.
7198404b540aSrobert
7199404b540aSrobert(define_insn "builtin_cmpbge"
7200404b540aSrobert  [(set (match_operand:DI 0 "register_operand" "=r")
7201404b540aSrobert	(unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "rJ")
7202404b540aSrobert		    (match_operand:DI 2 "reg_or_8bit_operand" "rI")]
7203404b540aSrobert		   UNSPEC_CMPBGE))]
7204404b540aSrobert  ""
7205404b540aSrobert  "cmpbge %r1,%2,%0"
7206404b540aSrobert  ;; The EV6 data sheets list this as ILOG.  OTOH, EV6 doesn't
7207404b540aSrobert  ;; actually differentiate between ILOG and ICMP in the schedule.
7208404b540aSrobert  [(set_attr "type" "icmp")])
7209404b540aSrobert
7210404b540aSrobert(define_expand "builtin_extbl"
7211404b540aSrobert  [(match_operand:DI 0 "register_operand" "")
7212404b540aSrobert   (match_operand:DI 1 "reg_or_0_operand" "")
7213404b540aSrobert   (match_operand:DI 2 "reg_or_8bit_operand" "")]
7214404b540aSrobert  ""
7215404b540aSrobert{
7216404b540aSrobert  rtx (*gen) (rtx, rtx, rtx, rtx);
7217404b540aSrobert  if (WORDS_BIG_ENDIAN)
7218404b540aSrobert    gen = gen_extxl_be;
7219404b540aSrobert  else
7220404b540aSrobert    gen = gen_extxl_le;
7221404b540aSrobert  emit_insn ((*gen) (operands[0], operands[1], GEN_INT (8), operands[2]));
7222404b540aSrobert  DONE;
7223404b540aSrobert})
7224404b540aSrobert
7225404b540aSrobert(define_expand "builtin_extwl"
7226404b540aSrobert  [(match_operand:DI 0 "register_operand" "")
7227404b540aSrobert   (match_operand:DI 1 "reg_or_0_operand" "")
7228404b540aSrobert   (match_operand:DI 2 "reg_or_8bit_operand" "")]
7229404b540aSrobert  ""
7230404b540aSrobert{
7231404b540aSrobert  rtx (*gen) (rtx, rtx, rtx, rtx);
7232404b540aSrobert  if (WORDS_BIG_ENDIAN)
7233404b540aSrobert    gen = gen_extxl_be;
7234404b540aSrobert  else
7235404b540aSrobert    gen = gen_extxl_le;
7236404b540aSrobert  emit_insn ((*gen) (operands[0], operands[1], GEN_INT (16), operands[2]));
7237404b540aSrobert  DONE;
7238404b540aSrobert})
7239404b540aSrobert
7240404b540aSrobert(define_expand "builtin_extll"
7241404b540aSrobert  [(match_operand:DI 0 "register_operand" "")
7242404b540aSrobert   (match_operand:DI 1 "reg_or_0_operand" "")
7243404b540aSrobert   (match_operand:DI 2 "reg_or_8bit_operand" "")]
7244404b540aSrobert  ""
7245404b540aSrobert{
7246404b540aSrobert  rtx (*gen) (rtx, rtx, rtx, rtx);
7247404b540aSrobert  if (WORDS_BIG_ENDIAN)
7248404b540aSrobert    gen = gen_extxl_be;
7249404b540aSrobert  else
7250404b540aSrobert    gen = gen_extxl_le;
7251404b540aSrobert  emit_insn ((*gen) (operands[0], operands[1], GEN_INT (32), operands[2]));
7252404b540aSrobert  DONE;
7253404b540aSrobert})
7254404b540aSrobert
7255404b540aSrobert(define_expand "builtin_extql"
7256404b540aSrobert  [(match_operand:DI 0 "register_operand" "")
7257404b540aSrobert   (match_operand:DI 1 "reg_or_0_operand" "")
7258404b540aSrobert   (match_operand:DI 2 "reg_or_8bit_operand" "")]
7259404b540aSrobert  ""
7260404b540aSrobert{
7261404b540aSrobert  rtx (*gen) (rtx, rtx, rtx, rtx);
7262404b540aSrobert  if (WORDS_BIG_ENDIAN)
7263404b540aSrobert    gen = gen_extxl_be;
7264404b540aSrobert  else
7265404b540aSrobert    gen = gen_extxl_le;
7266404b540aSrobert  emit_insn ((*gen) (operands[0], operands[1], GEN_INT (64), operands[2]));
7267404b540aSrobert  DONE;
7268404b540aSrobert})
7269404b540aSrobert
7270404b540aSrobert(define_expand "builtin_extwh"
7271404b540aSrobert  [(match_operand:DI 0 "register_operand" "")
7272404b540aSrobert   (match_operand:DI 1 "reg_or_0_operand" "")
7273404b540aSrobert   (match_operand:DI 2 "reg_or_8bit_operand" "")]
7274404b540aSrobert  ""
7275404b540aSrobert{
7276404b540aSrobert  rtx (*gen) (rtx, rtx, rtx);
7277404b540aSrobert  if (WORDS_BIG_ENDIAN)
7278404b540aSrobert    gen = gen_extwh_be;
7279404b540aSrobert  else
7280404b540aSrobert    gen = gen_extwh_le;
7281404b540aSrobert  emit_insn ((*gen) (operands[0], operands[1], operands[2]));
7282404b540aSrobert  DONE;
7283404b540aSrobert})
7284404b540aSrobert
7285404b540aSrobert(define_expand "builtin_extlh"
7286404b540aSrobert  [(match_operand:DI 0 "register_operand" "")
7287404b540aSrobert   (match_operand:DI 1 "reg_or_0_operand" "")
7288404b540aSrobert   (match_operand:DI 2 "reg_or_8bit_operand" "")]
7289404b540aSrobert  ""
7290404b540aSrobert{
7291404b540aSrobert  rtx (*gen) (rtx, rtx, rtx);
7292404b540aSrobert  if (WORDS_BIG_ENDIAN)
7293404b540aSrobert    gen = gen_extlh_be;
7294404b540aSrobert  else
7295404b540aSrobert    gen = gen_extlh_le;
7296404b540aSrobert  emit_insn ((*gen) (operands[0], operands[1], operands[2]));
7297404b540aSrobert  DONE;
7298404b540aSrobert})
7299404b540aSrobert
7300404b540aSrobert(define_expand "builtin_extqh"
7301404b540aSrobert  [(match_operand:DI 0 "register_operand" "")
7302404b540aSrobert   (match_operand:DI 1 "reg_or_0_operand" "")
7303404b540aSrobert   (match_operand:DI 2 "reg_or_8bit_operand" "")]
7304404b540aSrobert  ""
7305404b540aSrobert{
7306404b540aSrobert  rtx (*gen) (rtx, rtx, rtx);
7307404b540aSrobert  if (WORDS_BIG_ENDIAN)
7308404b540aSrobert    gen = gen_extqh_be;
7309404b540aSrobert  else
7310404b540aSrobert    gen = gen_extqh_le;
7311404b540aSrobert  emit_insn ((*gen) (operands[0], operands[1], operands[2]));
7312404b540aSrobert  DONE;
7313404b540aSrobert})
7314404b540aSrobert
7315404b540aSrobert(define_expand "builtin_insbl"
7316404b540aSrobert  [(match_operand:DI 0 "register_operand" "")
7317404b540aSrobert   (match_operand:DI 1 "register_operand" "")
7318404b540aSrobert   (match_operand:DI 2 "reg_or_8bit_operand" "")]
7319404b540aSrobert  ""
7320404b540aSrobert{
7321404b540aSrobert  rtx (*gen) (rtx, rtx, rtx);
7322404b540aSrobert  if (WORDS_BIG_ENDIAN)
7323404b540aSrobert    gen = gen_insbl_be;
7324404b540aSrobert  else
7325404b540aSrobert    gen = gen_insbl_le;
7326404b540aSrobert  operands[1] = gen_lowpart (QImode, operands[1]);
7327404b540aSrobert  emit_insn ((*gen) (operands[0], operands[1], operands[2]));
7328404b540aSrobert  DONE;
7329404b540aSrobert})
7330404b540aSrobert
7331404b540aSrobert(define_expand "builtin_inswl"
7332404b540aSrobert  [(match_operand:DI 0 "register_operand" "")
7333404b540aSrobert   (match_operand:DI 1 "register_operand" "")
7334404b540aSrobert   (match_operand:DI 2 "reg_or_8bit_operand" "")]
7335404b540aSrobert  ""
7336404b540aSrobert{
7337404b540aSrobert  rtx (*gen) (rtx, rtx, rtx);
7338404b540aSrobert  if (WORDS_BIG_ENDIAN)
7339404b540aSrobert    gen = gen_inswl_be;
7340404b540aSrobert  else
7341404b540aSrobert    gen = gen_inswl_le;
7342404b540aSrobert  operands[1] = gen_lowpart (HImode, operands[1]);
7343404b540aSrobert  emit_insn ((*gen) (operands[0], operands[1], operands[2]));
7344404b540aSrobert  DONE;
7345404b540aSrobert})
7346404b540aSrobert
7347404b540aSrobert(define_expand "builtin_insll"
7348404b540aSrobert  [(match_operand:DI 0 "register_operand" "")
7349404b540aSrobert   (match_operand:DI 1 "register_operand" "")
7350404b540aSrobert   (match_operand:DI 2 "reg_or_8bit_operand" "")]
7351404b540aSrobert  ""
7352404b540aSrobert{
7353404b540aSrobert  rtx (*gen) (rtx, rtx, rtx);
7354404b540aSrobert  if (WORDS_BIG_ENDIAN)
7355404b540aSrobert    gen = gen_insll_be;
7356404b540aSrobert  else
7357404b540aSrobert    gen = gen_insll_le;
7358404b540aSrobert  operands[1] = gen_lowpart (SImode, operands[1]);
7359404b540aSrobert  emit_insn ((*gen) (operands[0], operands[1], operands[2]));
7360404b540aSrobert  emit_insn ((*gen) (operands[0], operands[1], operands[2]));
7361404b540aSrobert  DONE;
7362404b540aSrobert})
7363404b540aSrobert
7364404b540aSrobert(define_expand "builtin_insql"
7365404b540aSrobert  [(match_operand:DI 0 "register_operand" "")
7366404b540aSrobert   (match_operand:DI 1 "reg_or_0_operand" "")
7367404b540aSrobert   (match_operand:DI 2 "reg_or_8bit_operand" "")]
7368404b540aSrobert  ""
7369404b540aSrobert{
7370404b540aSrobert  rtx (*gen) (rtx, rtx, rtx);
7371404b540aSrobert  if (WORDS_BIG_ENDIAN)
7372404b540aSrobert    gen = gen_insql_be;
7373404b540aSrobert  else
7374404b540aSrobert    gen = gen_insql_le;
7375404b540aSrobert  emit_insn ((*gen) (operands[0], operands[1], operands[2]));
7376404b540aSrobert  DONE;
7377404b540aSrobert})
7378404b540aSrobert
7379404b540aSrobert(define_expand "builtin_inswh"
7380404b540aSrobert  [(match_operand:DI 0 "register_operand" "")
7381404b540aSrobert   (match_operand:DI 1 "register_operand" "")
7382404b540aSrobert   (match_operand:DI 2 "reg_or_8bit_operand" "")]
7383404b540aSrobert  ""
7384404b540aSrobert{
7385404b540aSrobert  emit_insn (gen_insxh (operands[0], operands[1], GEN_INT (16), operands[2]));
7386404b540aSrobert  DONE;
7387404b540aSrobert})
7388404b540aSrobert
7389404b540aSrobert(define_expand "builtin_inslh"
7390404b540aSrobert  [(match_operand:DI 0 "register_operand" "")
7391404b540aSrobert   (match_operand:DI 1 "register_operand" "")
7392404b540aSrobert   (match_operand:DI 2 "reg_or_8bit_operand" "")]
7393404b540aSrobert  ""
7394404b540aSrobert{
7395404b540aSrobert  emit_insn (gen_insxh (operands[0], operands[1], GEN_INT (32), operands[2]));
7396404b540aSrobert  DONE;
7397404b540aSrobert})
7398404b540aSrobert
7399404b540aSrobert(define_expand "builtin_insqh"
7400404b540aSrobert  [(match_operand:DI 0 "register_operand" "")
7401404b540aSrobert   (match_operand:DI 1 "register_operand" "")
7402404b540aSrobert   (match_operand:DI 2 "reg_or_8bit_operand" "")]
7403404b540aSrobert  ""
7404404b540aSrobert{
7405404b540aSrobert  emit_insn (gen_insxh (operands[0], operands[1], GEN_INT (64), operands[2]));
7406404b540aSrobert  DONE;
7407404b540aSrobert})
7408404b540aSrobert
7409404b540aSrobert(define_expand "builtin_mskbl"
7410404b540aSrobert  [(match_operand:DI 0 "register_operand" "")
7411404b540aSrobert   (match_operand:DI 1 "reg_or_0_operand" "")
7412404b540aSrobert   (match_operand:DI 2 "reg_or_8bit_operand" "")]
7413404b540aSrobert  ""
7414404b540aSrobert{
7415404b540aSrobert  rtx (*gen) (rtx, rtx, rtx, rtx);
7416404b540aSrobert  rtx mask;
7417404b540aSrobert  if (WORDS_BIG_ENDIAN)
7418404b540aSrobert    gen = gen_mskxl_be;
7419404b540aSrobert  else
7420404b540aSrobert    gen = gen_mskxl_le;
7421404b540aSrobert  mask = GEN_INT (0xff);
7422404b540aSrobert  emit_insn ((*gen) (operands[0], operands[1], mask, operands[2]));
7423404b540aSrobert  DONE;
7424404b540aSrobert})
7425404b540aSrobert
7426404b540aSrobert(define_expand "builtin_mskwl"
7427404b540aSrobert  [(match_operand:DI 0 "register_operand" "")
7428404b540aSrobert   (match_operand:DI 1 "reg_or_0_operand" "")
7429404b540aSrobert   (match_operand:DI 2 "reg_or_8bit_operand" "")]
7430404b540aSrobert  ""
7431404b540aSrobert{
7432404b540aSrobert  rtx (*gen) (rtx, rtx, rtx, rtx);
7433404b540aSrobert  rtx mask;
7434404b540aSrobert  if (WORDS_BIG_ENDIAN)
7435404b540aSrobert    gen = gen_mskxl_be;
7436404b540aSrobert  else
7437404b540aSrobert    gen = gen_mskxl_le;
7438404b540aSrobert  mask = GEN_INT (0xffff);
7439404b540aSrobert  emit_insn ((*gen) (operands[0], operands[1], mask, operands[2]));
7440404b540aSrobert  DONE;
7441404b540aSrobert})
7442404b540aSrobert
7443404b540aSrobert(define_expand "builtin_mskll"
7444404b540aSrobert  [(match_operand:DI 0 "register_operand" "")
7445404b540aSrobert   (match_operand:DI 1 "reg_or_0_operand" "")
7446404b540aSrobert   (match_operand:DI 2 "reg_or_8bit_operand" "")]
7447404b540aSrobert  ""
7448404b540aSrobert{
7449404b540aSrobert  rtx (*gen) (rtx, rtx, rtx, rtx);
7450404b540aSrobert  rtx mask;
7451404b540aSrobert  if (WORDS_BIG_ENDIAN)
7452404b540aSrobert    gen = gen_mskxl_be;
7453404b540aSrobert  else
7454404b540aSrobert    gen = gen_mskxl_le;
7455404b540aSrobert  mask = immed_double_const (0xffffffff, 0, DImode);
7456404b540aSrobert  emit_insn ((*gen) (operands[0], operands[1], mask, operands[2]));
7457404b540aSrobert  DONE;
7458404b540aSrobert})
7459404b540aSrobert
7460404b540aSrobert(define_expand "builtin_mskql"
7461404b540aSrobert  [(match_operand:DI 0 "register_operand" "")
7462404b540aSrobert   (match_operand:DI 1 "reg_or_0_operand" "")
7463404b540aSrobert   (match_operand:DI 2 "reg_or_8bit_operand" "")]
7464404b540aSrobert  ""
7465404b540aSrobert{
7466404b540aSrobert  rtx (*gen) (rtx, rtx, rtx, rtx);
7467404b540aSrobert  rtx mask;
7468404b540aSrobert  if (WORDS_BIG_ENDIAN)
7469404b540aSrobert    gen = gen_mskxl_be;
7470404b540aSrobert  else
7471404b540aSrobert    gen = gen_mskxl_le;
7472404b540aSrobert  mask = constm1_rtx;
7473404b540aSrobert  emit_insn ((*gen) (operands[0], operands[1], mask, operands[2]));
7474404b540aSrobert  DONE;
7475404b540aSrobert})
7476404b540aSrobert
7477404b540aSrobert(define_expand "builtin_mskwh"
7478404b540aSrobert  [(match_operand:DI 0 "register_operand" "")
7479404b540aSrobert   (match_operand:DI 1 "register_operand" "")
7480404b540aSrobert   (match_operand:DI 2 "reg_or_8bit_operand" "")]
7481404b540aSrobert  ""
7482404b540aSrobert{
7483404b540aSrobert  emit_insn (gen_mskxh (operands[0], operands[1], GEN_INT (16), operands[2]));
7484404b540aSrobert  DONE;
7485404b540aSrobert})
7486404b540aSrobert
7487404b540aSrobert(define_expand "builtin_msklh"
7488404b540aSrobert  [(match_operand:DI 0 "register_operand" "")
7489404b540aSrobert   (match_operand:DI 1 "register_operand" "")
7490404b540aSrobert   (match_operand:DI 2 "reg_or_8bit_operand" "")]
7491404b540aSrobert  ""
7492404b540aSrobert{
7493404b540aSrobert  emit_insn (gen_mskxh (operands[0], operands[1], GEN_INT (32), operands[2]));
7494404b540aSrobert  DONE;
7495404b540aSrobert})
7496404b540aSrobert
7497404b540aSrobert(define_expand "builtin_mskqh"
7498404b540aSrobert  [(match_operand:DI 0 "register_operand" "")
7499404b540aSrobert   (match_operand:DI 1 "register_operand" "")
7500404b540aSrobert   (match_operand:DI 2 "reg_or_8bit_operand" "")]
7501404b540aSrobert  ""
7502404b540aSrobert{
7503404b540aSrobert  emit_insn (gen_mskxh (operands[0], operands[1], GEN_INT (64), operands[2]));
7504404b540aSrobert  DONE;
7505404b540aSrobert})
7506404b540aSrobert
7507404b540aSrobert(define_expand "builtin_zap"
7508404b540aSrobert  [(set (match_operand:DI 0 "register_operand" "")
7509404b540aSrobert	(and:DI (unspec:DI
7510404b540aSrobert		  [(match_operand:DI 2 "reg_or_cint_operand" "")]
7511404b540aSrobert		  UNSPEC_ZAP)
7512404b540aSrobert		(match_operand:DI 1 "reg_or_cint_operand" "")))]
7513404b540aSrobert  ""
7514404b540aSrobert{
7515404b540aSrobert  if (GET_CODE (operands[2]) == CONST_INT)
7516404b540aSrobert    {
7517404b540aSrobert      rtx mask = alpha_expand_zap_mask (INTVAL (operands[2]));
7518404b540aSrobert
7519404b540aSrobert      if (mask == const0_rtx)
7520404b540aSrobert	{
7521404b540aSrobert	  emit_move_insn (operands[0], const0_rtx);
7522404b540aSrobert	  DONE;
7523404b540aSrobert	}
7524404b540aSrobert      if (mask == constm1_rtx)
7525404b540aSrobert	{
7526404b540aSrobert	  emit_move_insn (operands[0], operands[1]);
7527404b540aSrobert	  DONE;
7528404b540aSrobert	}
7529404b540aSrobert
7530404b540aSrobert      operands[1] = force_reg (DImode, operands[1]);
7531404b540aSrobert      emit_insn (gen_anddi3 (operands[0], operands[1], mask));
7532404b540aSrobert      DONE;
7533404b540aSrobert    }
7534404b540aSrobert
7535404b540aSrobert  operands[1] = force_reg (DImode, operands[1]);
7536404b540aSrobert  operands[2] = gen_lowpart (QImode, operands[2]);
7537404b540aSrobert})
7538404b540aSrobert
7539404b540aSrobert(define_insn "*builtin_zap_1"
7540404b540aSrobert  [(set (match_operand:DI 0 "register_operand" "=r,r,r,r")
7541404b540aSrobert	(and:DI (unspec:DI
7542404b540aSrobert		  [(match_operand:QI 2 "reg_or_cint_operand" "n,n,r,r")]
7543404b540aSrobert		  UNSPEC_ZAP)
7544404b540aSrobert		(match_operand:DI 1 "reg_or_cint_operand" "n,r,J,r")))]
7545404b540aSrobert  ""
7546404b540aSrobert  "@
7547404b540aSrobert   #
7548404b540aSrobert   #
7549404b540aSrobert   bis $31,$31,%0
7550404b540aSrobert   zap %r1,%2,%0"
7551404b540aSrobert  [(set_attr "type" "shift,shift,ilog,shift")])
7552404b540aSrobert
7553404b540aSrobert(define_split
7554404b540aSrobert  [(set (match_operand:DI 0 "register_operand" "")
7555404b540aSrobert	(and:DI (unspec:DI
7556404b540aSrobert		  [(match_operand:QI 2 "const_int_operand" "")]
7557404b540aSrobert		  UNSPEC_ZAP)
7558404b540aSrobert		(match_operand:DI 1 "const_int_operand" "")))]
7559404b540aSrobert  ""
7560404b540aSrobert  [(const_int 0)]
7561404b540aSrobert{
7562404b540aSrobert  rtx mask = alpha_expand_zap_mask (INTVAL (operands[2]));
7563404b540aSrobert  if (HOST_BITS_PER_WIDE_INT >= 64 || GET_CODE (mask) == CONST_INT)
7564404b540aSrobert    operands[1] = gen_int_mode (INTVAL (operands[1]) & INTVAL (mask), DImode);
7565404b540aSrobert  else
7566404b540aSrobert    {
7567404b540aSrobert      HOST_WIDE_INT c_lo = INTVAL (operands[1]);
7568404b540aSrobert      HOST_WIDE_INT c_hi = (c_lo < 0 ? -1 : 0);
7569404b540aSrobert      operands[1] = immed_double_const (c_lo & CONST_DOUBLE_LOW (mask),
7570404b540aSrobert					c_hi & CONST_DOUBLE_HIGH (mask),
7571404b540aSrobert					DImode);
7572404b540aSrobert    }
7573404b540aSrobert  emit_move_insn (operands[0], operands[1]);
7574404b540aSrobert  DONE;
7575404b540aSrobert})
7576404b540aSrobert
7577404b540aSrobert(define_split
7578404b540aSrobert  [(set (match_operand:DI 0 "register_operand" "")
7579404b540aSrobert	(and:DI (unspec:DI
7580404b540aSrobert		  [(match_operand:QI 2 "const_int_operand" "")]
7581404b540aSrobert		  UNSPEC_ZAP)
7582404b540aSrobert		(match_operand:DI 1 "register_operand" "")))]
7583404b540aSrobert  ""
7584404b540aSrobert  [(set (match_dup 0)
7585404b540aSrobert	(and:DI (match_dup 1) (match_dup 2)))]
7586404b540aSrobert{
7587404b540aSrobert  operands[2] = alpha_expand_zap_mask (INTVAL (operands[2]));
7588404b540aSrobert  if (operands[2] == const0_rtx)
7589404b540aSrobert    {
7590404b540aSrobert      emit_move_insn (operands[0], const0_rtx);
7591404b540aSrobert      DONE;
7592404b540aSrobert    }
7593404b540aSrobert  if (operands[2] == constm1_rtx)
7594404b540aSrobert    {
7595404b540aSrobert      emit_move_insn (operands[0], operands[1]);
7596404b540aSrobert      DONE;
7597404b540aSrobert    }
7598404b540aSrobert})
7599404b540aSrobert
7600404b540aSrobert(define_expand "builtin_zapnot"
7601404b540aSrobert  [(set (match_operand:DI 0 "register_operand" "")
7602404b540aSrobert	(and:DI (unspec:DI
7603404b540aSrobert		  [(not:QI (match_operand:DI 2 "reg_or_cint_operand" ""))]
7604404b540aSrobert		  UNSPEC_ZAP)
7605404b540aSrobert		(match_operand:DI 1 "reg_or_cint_operand" "")))]
7606404b540aSrobert  ""
7607404b540aSrobert{
7608404b540aSrobert  if (GET_CODE (operands[2]) == CONST_INT)
7609404b540aSrobert    {
7610404b540aSrobert      rtx mask = alpha_expand_zap_mask (~ INTVAL (operands[2]));
7611404b540aSrobert
7612404b540aSrobert      if (mask == const0_rtx)
7613404b540aSrobert	{
7614404b540aSrobert	  emit_move_insn (operands[0], const0_rtx);
7615404b540aSrobert	  DONE;
7616404b540aSrobert	}
7617404b540aSrobert      if (mask == constm1_rtx)
7618404b540aSrobert	{
7619404b540aSrobert	  emit_move_insn (operands[0], operands[1]);
7620404b540aSrobert	  DONE;
7621404b540aSrobert	}
7622404b540aSrobert
7623404b540aSrobert      operands[1] = force_reg (DImode, operands[1]);
7624404b540aSrobert      emit_insn (gen_anddi3 (operands[0], operands[1], mask));
7625404b540aSrobert      DONE;
7626404b540aSrobert    }
7627404b540aSrobert
7628404b540aSrobert  operands[1] = force_reg (DImode, operands[1]);
7629404b540aSrobert  operands[2] = gen_lowpart (QImode, operands[2]);
7630404b540aSrobert})
7631404b540aSrobert
7632404b540aSrobert(define_insn "*builtin_zapnot_1"
7633404b540aSrobert  [(set (match_operand:DI 0 "register_operand" "=r")
7634404b540aSrobert	(and:DI (unspec:DI
7635404b540aSrobert                  [(not:QI (match_operand:QI 2 "register_operand" "r"))]
7636404b540aSrobert                  UNSPEC_ZAP)
7637404b540aSrobert		(match_operand:DI 1 "reg_or_0_operand" "rJ")))]
7638404b540aSrobert  ""
7639404b540aSrobert  "zapnot %r1,%2,%0"
7640404b540aSrobert  [(set_attr "type" "shift")])
7641404b540aSrobert
7642404b540aSrobert(define_insn "builtin_amask"
7643404b540aSrobert  [(set (match_operand:DI 0 "register_operand" "=r")
7644404b540aSrobert	(unspec:DI [(match_operand:DI 1 "reg_or_8bit_operand" "rI")]
7645404b540aSrobert		   UNSPEC_AMASK))]
7646404b540aSrobert  ""
7647404b540aSrobert  "amask %1,%0"
7648404b540aSrobert  [(set_attr "type" "ilog")])
7649404b540aSrobert
7650404b540aSrobert(define_insn "builtin_implver"
7651404b540aSrobert  [(set (match_operand:DI 0 "register_operand" "=r")
7652404b540aSrobert  	(unspec:DI [(const_int 0)] UNSPEC_IMPLVER))]
7653404b540aSrobert  ""
7654404b540aSrobert  "implver %0"
7655404b540aSrobert  [(set_attr "type" "ilog")])
7656404b540aSrobert
7657404b540aSrobert(define_insn "builtin_rpcc"
7658404b540aSrobert  [(set (match_operand:DI 0 "register_operand" "=r")
7659404b540aSrobert  	(unspec_volatile:DI [(const_int 0)] UNSPECV_RPCC))]
7660404b540aSrobert  ""
7661404b540aSrobert  "rpcc %0"
7662404b540aSrobert  [(set_attr "type" "ilog")])
7663404b540aSrobert
7664404b540aSrobert(define_expand "builtin_minub8"
7665404b540aSrobert  [(match_operand:DI 0 "register_operand" "")
7666404b540aSrobert   (match_operand:DI 1 "reg_or_0_operand" "")
7667404b540aSrobert   (match_operand:DI 2 "reg_or_0_operand" "")]
7668404b540aSrobert  "TARGET_MAX"
7669404b540aSrobert{
7670404b540aSrobert  alpha_expand_builtin_vector_binop (gen_uminv8qi3, V8QImode, operands[0],
7671404b540aSrobert				     operands[1], operands[2]);
7672404b540aSrobert  DONE;
7673404b540aSrobert})
7674404b540aSrobert
7675404b540aSrobert(define_expand "builtin_minsb8"
7676404b540aSrobert  [(match_operand:DI 0 "register_operand" "")
7677404b540aSrobert   (match_operand:DI 1 "reg_or_0_operand" "")
7678404b540aSrobert   (match_operand:DI 2 "reg_or_0_operand" "")]
7679404b540aSrobert  "TARGET_MAX"
7680404b540aSrobert{
7681404b540aSrobert  alpha_expand_builtin_vector_binop (gen_sminv8qi3, V8QImode, operands[0],
7682404b540aSrobert				     operands[1], operands[2]);
7683404b540aSrobert  DONE;
7684404b540aSrobert})
7685404b540aSrobert
7686404b540aSrobert(define_expand "builtin_minuw4"
7687404b540aSrobert  [(match_operand:DI 0 "register_operand" "")
7688404b540aSrobert   (match_operand:DI 1 "reg_or_0_operand" "")
7689404b540aSrobert   (match_operand:DI 2 "reg_or_0_operand" "")]
7690404b540aSrobert  "TARGET_MAX"
7691404b540aSrobert{
7692404b540aSrobert  alpha_expand_builtin_vector_binop (gen_uminv4hi3, V4HImode, operands[0],
7693404b540aSrobert				     operands[1], operands[2]);
7694404b540aSrobert  DONE;
7695404b540aSrobert})
7696404b540aSrobert
7697404b540aSrobert(define_expand "builtin_minsw4"
7698404b540aSrobert  [(match_operand:DI 0 "register_operand" "")
7699404b540aSrobert   (match_operand:DI 1 "reg_or_0_operand" "")
7700404b540aSrobert   (match_operand:DI 2 "reg_or_0_operand" "")]
7701404b540aSrobert  "TARGET_MAX"
7702404b540aSrobert{
7703404b540aSrobert  alpha_expand_builtin_vector_binop (gen_sminv4hi3, V4HImode, operands[0],
7704404b540aSrobert				     operands[1], operands[2]);
7705404b540aSrobert  DONE;
7706404b540aSrobert})
7707404b540aSrobert
7708404b540aSrobert(define_expand "builtin_maxub8"
7709404b540aSrobert  [(match_operand:DI 0 "register_operand" "")
7710404b540aSrobert   (match_operand:DI 1 "reg_or_0_operand" "")
7711404b540aSrobert   (match_operand:DI 2 "reg_or_0_operand" "")]
7712404b540aSrobert  "TARGET_MAX"
7713404b540aSrobert{
7714404b540aSrobert  alpha_expand_builtin_vector_binop (gen_umaxv8qi3, V8QImode, operands[0],
7715404b540aSrobert				     operands[1], operands[2]);
7716404b540aSrobert  DONE;
7717404b540aSrobert})
7718404b540aSrobert
7719404b540aSrobert(define_expand "builtin_maxsb8"
7720404b540aSrobert  [(match_operand:DI 0 "register_operand" "")
7721404b540aSrobert   (match_operand:DI 1 "reg_or_0_operand" "")
7722404b540aSrobert   (match_operand:DI 2 "reg_or_0_operand" "")]
7723404b540aSrobert  "TARGET_MAX"
7724404b540aSrobert{
7725404b540aSrobert  alpha_expand_builtin_vector_binop (gen_smaxv8qi3, V8QImode, operands[0],
7726404b540aSrobert				     operands[1], operands[2]);
7727404b540aSrobert  DONE;
7728404b540aSrobert})
7729404b540aSrobert
7730404b540aSrobert(define_expand "builtin_maxuw4"
7731404b540aSrobert  [(match_operand:DI 0 "register_operand" "")
7732404b540aSrobert   (match_operand:DI 1 "reg_or_0_operand" "")
7733404b540aSrobert   (match_operand:DI 2 "reg_or_0_operand" "")]
7734404b540aSrobert  "TARGET_MAX"
7735404b540aSrobert{
7736404b540aSrobert  alpha_expand_builtin_vector_binop (gen_umaxv4hi3, V4HImode, operands[0],
7737404b540aSrobert				     operands[1], operands[2]);
7738404b540aSrobert  DONE;
7739404b540aSrobert})
7740404b540aSrobert
7741404b540aSrobert(define_expand "builtin_maxsw4"
7742404b540aSrobert  [(match_operand:DI 0 "register_operand" "")
7743404b540aSrobert   (match_operand:DI 1 "reg_or_0_operand" "")
7744404b540aSrobert   (match_operand:DI 2 "reg_or_0_operand" "")]
7745404b540aSrobert  "TARGET_MAX"
7746404b540aSrobert{
7747404b540aSrobert  alpha_expand_builtin_vector_binop (gen_smaxv4hi3, V4HImode, operands[0],
7748404b540aSrobert				     operands[1], operands[2]);
7749404b540aSrobert  DONE;
7750404b540aSrobert})
7751404b540aSrobert
7752404b540aSrobert(define_insn "builtin_perr"
7753404b540aSrobert  [(set (match_operand:DI 0 "register_operand" "=r")
7754404b540aSrobert	(unspec:DI [(match_operand:DI 1 "reg_or_0_operand" "%rJ")
7755404b540aSrobert		    (match_operand:DI 2 "reg_or_8bit_operand" "rJ")]
7756404b540aSrobert		   UNSPEC_PERR))]
7757404b540aSrobert  "TARGET_MAX"
7758404b540aSrobert  "perr %r1,%r2,%0"
7759404b540aSrobert  [(set_attr "type" "mvi")])
7760404b540aSrobert
7761404b540aSrobert(define_expand "builtin_pklb"
7762404b540aSrobert  [(set (match_operand:DI 0 "register_operand" "")
7763404b540aSrobert	(vec_concat:V8QI
7764404b540aSrobert	  (vec_concat:V4QI
7765404b540aSrobert	    (truncate:V2QI (match_operand:DI 1 "register_operand" ""))
7766404b540aSrobert	    (match_dup 2))
7767404b540aSrobert	  (match_dup 3)))]
7768404b540aSrobert  "TARGET_MAX"
7769404b540aSrobert{
7770404b540aSrobert  operands[0] = gen_lowpart (V8QImode, operands[0]);
7771404b540aSrobert  operands[1] = gen_lowpart (V2SImode, operands[1]);
7772404b540aSrobert  operands[2] = CONST0_RTX (V2QImode);
7773404b540aSrobert  operands[3] = CONST0_RTX (V4QImode);
7774404b540aSrobert})
7775404b540aSrobert
7776404b540aSrobert(define_insn "*pklb"
7777404b540aSrobert  [(set (match_operand:V8QI 0 "register_operand" "=r")
7778404b540aSrobert	(vec_concat:V8QI
7779404b540aSrobert	  (vec_concat:V4QI
7780404b540aSrobert	    (truncate:V2QI (match_operand:V2SI 1 "register_operand" "r"))
7781404b540aSrobert	    (match_operand:V2QI 2 "const0_operand" ""))
7782404b540aSrobert	  (match_operand:V4QI 3 "const0_operand" "")))]
7783404b540aSrobert  "TARGET_MAX"
7784404b540aSrobert  "pklb %r1,%0"
7785404b540aSrobert  [(set_attr "type" "mvi")])
7786404b540aSrobert
7787404b540aSrobert(define_expand "builtin_pkwb"
7788404b540aSrobert  [(set (match_operand:DI 0 "register_operand" "")
7789404b540aSrobert	(vec_concat:V8QI
7790404b540aSrobert	  (truncate:V4QI (match_operand:DI 1 "register_operand" ""))
7791404b540aSrobert	  (match_dup 2)))]
7792404b540aSrobert  "TARGET_MAX"
7793404b540aSrobert{
7794404b540aSrobert  operands[0] = gen_lowpart (V8QImode, operands[0]);
7795404b540aSrobert  operands[1] = gen_lowpart (V4HImode, operands[1]);
7796404b540aSrobert  operands[2] = CONST0_RTX (V4QImode);
7797404b540aSrobert})
7798404b540aSrobert
7799404b540aSrobert(define_insn "*pkwb"
7800404b540aSrobert  [(set (match_operand:V8QI 0 "register_operand" "=r")
7801404b540aSrobert	(vec_concat:V8QI
7802404b540aSrobert	  (truncate:V4QI (match_operand:V4HI 1 "register_operand" "r"))
7803404b540aSrobert	  (match_operand:V4QI 2 "const0_operand" "")))]
7804404b540aSrobert  "TARGET_MAX"
7805404b540aSrobert  "pkwb %r1,%0"
7806404b540aSrobert  [(set_attr "type" "mvi")])
7807404b540aSrobert
7808404b540aSrobert(define_expand "builtin_unpkbl"
7809404b540aSrobert  [(set (match_operand:DI 0 "register_operand" "")
7810404b540aSrobert	(zero_extend:V2SI
7811404b540aSrobert	  (vec_select:V2QI (match_operand:DI 1 "register_operand" "")
7812404b540aSrobert			   (parallel [(const_int 0) (const_int 1)]))))]
7813404b540aSrobert  "TARGET_MAX"
7814404b540aSrobert{
7815404b540aSrobert  operands[0] = gen_lowpart (V2SImode, operands[0]);
7816404b540aSrobert  operands[1] = gen_lowpart (V8QImode, operands[1]);
7817404b540aSrobert})
7818404b540aSrobert
7819404b540aSrobert(define_insn "*unpkbl"
7820404b540aSrobert  [(set (match_operand:V2SI 0 "register_operand" "=r")
7821404b540aSrobert	(zero_extend:V2SI
7822404b540aSrobert	  (vec_select:V2QI (match_operand:V8QI 1 "reg_or_0_operand" "rW")
7823404b540aSrobert			   (parallel [(const_int 0) (const_int 1)]))))]
7824404b540aSrobert  "TARGET_MAX"
7825404b540aSrobert  "unpkbl %r1,%0"
7826404b540aSrobert  [(set_attr "type" "mvi")])
7827404b540aSrobert
7828404b540aSrobert(define_expand "builtin_unpkbw"
7829404b540aSrobert  [(set (match_operand:DI 0 "register_operand" "")
7830404b540aSrobert	(zero_extend:V4HI
7831404b540aSrobert	  (vec_select:V4QI (match_operand:DI 1 "register_operand" "")
7832404b540aSrobert			   (parallel [(const_int 0)
7833404b540aSrobert				      (const_int 1)
7834404b540aSrobert				      (const_int 2)
7835404b540aSrobert				      (const_int 3)]))))]
7836404b540aSrobert  "TARGET_MAX"
7837404b540aSrobert{
7838404b540aSrobert  operands[0] = gen_lowpart (V4HImode, operands[0]);
7839404b540aSrobert  operands[1] = gen_lowpart (V8QImode, operands[1]);
7840404b540aSrobert})
7841404b540aSrobert
7842404b540aSrobert(define_insn "*unpkbw"
7843404b540aSrobert  [(set (match_operand:V4HI 0 "register_operand" "=r")
7844404b540aSrobert	(zero_extend:V4HI
7845404b540aSrobert	  (vec_select:V4QI (match_operand:V8QI 1 "reg_or_0_operand" "rW")
7846404b540aSrobert			   (parallel [(const_int 0)
7847404b540aSrobert				      (const_int 1)
7848404b540aSrobert				      (const_int 2)
7849404b540aSrobert				      (const_int 3)]))))]
7850404b540aSrobert  "TARGET_MAX"
7851404b540aSrobert  "unpkbw %r1,%0"
7852404b540aSrobert  [(set_attr "type" "mvi")])
7853404b540aSrobert
7854404b540aSrobert(include "sync.md")
7855404b540aSrobert
7856404b540aSrobert;; The call patterns are at the end of the file because their
7857404b540aSrobert;; wildcard operand0 interferes with nice recognition.
7858404b540aSrobert
7859404b540aSrobert(define_insn "*call_value_osf_1_er"
7860404b540aSrobert  [(set (match_operand 0 "" "")
7861404b540aSrobert	(call (mem:DI (match_operand:DI 1 "call_operand" "c,R,s"))
7862404b540aSrobert	      (match_operand 2 "" "")))
7863404b540aSrobert   (use (reg:DI 29))
7864404b540aSrobert   (clobber (reg:DI 26))]
7865404b540aSrobert  "TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF"
7866404b540aSrobert  "@
7867404b540aSrobert   jsr $26,(%1),0\;ldah $29,0($26)\t\t!gpdisp!%*\;lda $29,0($29)\t\t!gpdisp!%*
7868404b540aSrobert   bsr $26,%1\t\t!samegp
7869404b540aSrobert   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!%*"
7870404b540aSrobert  [(set_attr "type" "jsr")
7871404b540aSrobert   (set_attr "length" "12,*,16")])
7872404b540aSrobert
7873404b540aSrobert;; We must use peep2 instead of a split because we need accurate life
7874404b540aSrobert;; information for $gp.  Consider the case of { bar(); while (1); }.
7875404b540aSrobert(define_peephole2
7876404b540aSrobert  [(parallel [(set (match_operand 0 "" "")
7877404b540aSrobert		   (call (mem:DI (match_operand:DI 1 "call_operand" ""))
7878404b540aSrobert		         (match_operand 2 "" "")))
7879404b540aSrobert	      (use (reg:DI 29))
7880404b540aSrobert	      (clobber (reg:DI 26))])]
7881404b540aSrobert  "TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF && reload_completed
7882404b540aSrobert   && ! samegp_function_operand (operands[1], Pmode)
7883404b540aSrobert   && (peep2_regno_dead_p (1, 29)
7884404b540aSrobert       || find_reg_note (insn, REG_NORETURN, NULL_RTX))"
7885404b540aSrobert  [(parallel [(set (match_dup 0)
7886404b540aSrobert		   (call (mem:DI (match_dup 3))
7887404b540aSrobert			 (match_dup 2)))
7888404b540aSrobert	      (set (reg:DI 26) (plus:DI (pc) (const_int 4)))
7889404b540aSrobert	      (unspec_volatile [(reg:DI 29)] UNSPECV_BLOCKAGE)
7890404b540aSrobert	      (use (match_dup 1))
7891404b540aSrobert	      (use (match_dup 4))])]
7892404b540aSrobert{
7893404b540aSrobert  if (CONSTANT_P (operands[1]))
7894404b540aSrobert    {
7895404b540aSrobert      operands[3] = gen_rtx_REG (Pmode, 27);
7896404b540aSrobert      operands[4] = GEN_INT (alpha_next_sequence_number++);
7897404b540aSrobert      emit_insn (gen_movdi_er_high_g (operands[3], pic_offset_table_rtx,
7898404b540aSrobert				      operands[1], operands[4]));
7899404b540aSrobert    }
7900404b540aSrobert  else
7901404b540aSrobert    {
7902404b540aSrobert      operands[3] = operands[1];
7903404b540aSrobert      operands[1] = const0_rtx;
7904404b540aSrobert      operands[4] = const0_rtx;
7905404b540aSrobert    }
7906404b540aSrobert})
7907404b540aSrobert
7908404b540aSrobert(define_peephole2
7909404b540aSrobert  [(parallel [(set (match_operand 0 "" "")
7910404b540aSrobert		   (call (mem:DI (match_operand:DI 1 "call_operand" ""))
7911404b540aSrobert		         (match_operand 2 "" "")))
7912404b540aSrobert	      (use (reg:DI 29))
7913404b540aSrobert	      (clobber (reg:DI 26))])]
7914404b540aSrobert  "TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF && reload_completed
7915404b540aSrobert   && ! samegp_function_operand (operands[1], Pmode)
7916404b540aSrobert   && ! (peep2_regno_dead_p (1, 29)
7917404b540aSrobert         || find_reg_note (insn, REG_NORETURN, NULL_RTX))"
7918404b540aSrobert  [(parallel [(set (match_dup 0)
7919404b540aSrobert		   (call (mem:DI (match_dup 3))
7920404b540aSrobert			 (match_dup 2)))
7921404b540aSrobert	      (set (reg:DI 26) (plus:DI (pc) (const_int 4)))
7922404b540aSrobert	      (unspec_volatile [(reg:DI 29)] UNSPECV_BLOCKAGE)
7923404b540aSrobert	      (use (match_dup 1))
7924404b540aSrobert	      (use (match_dup 5))])
7925404b540aSrobert   (set (reg:DI 29)
7926404b540aSrobert	(unspec_volatile:DI [(reg:DI 26) (match_dup 4)] UNSPECV_LDGP1))
7927404b540aSrobert   (set (reg:DI 29)
7928404b540aSrobert	(unspec:DI [(reg:DI 29) (match_dup 4)] UNSPEC_LDGP2))]
7929404b540aSrobert{
7930404b540aSrobert  if (CONSTANT_P (operands[1]))
7931404b540aSrobert    {
7932404b540aSrobert      operands[3] = gen_rtx_REG (Pmode, 27);
7933404b540aSrobert      operands[5] = GEN_INT (alpha_next_sequence_number++);
7934404b540aSrobert      emit_insn (gen_movdi_er_high_g (operands[3], pic_offset_table_rtx,
7935404b540aSrobert				      operands[1], operands[5]));
7936404b540aSrobert    }
7937404b540aSrobert  else
7938404b540aSrobert    {
7939404b540aSrobert      operands[3] = operands[1];
7940404b540aSrobert      operands[1] = const0_rtx;
7941404b540aSrobert      operands[5] = const0_rtx;
7942404b540aSrobert    }
7943404b540aSrobert  operands[4] = GEN_INT (alpha_next_sequence_number++);
7944404b540aSrobert})
7945404b540aSrobert
7946404b540aSrobert;; We add a blockage unspec_volatile to prevent insns from moving down
7947404b540aSrobert;; from above the call to in between the call and the ldah gpdisp.
7948404b540aSrobert(define_insn "*call_value_osf_2_er"
7949404b540aSrobert  [(set (match_operand 0 "" "")
7950404b540aSrobert	(call (mem:DI (match_operand:DI 1 "register_operand" "c"))
7951404b540aSrobert	      (match_operand 2 "" "")))
7952404b540aSrobert   (set (reg:DI 26)
7953404b540aSrobert	(plus:DI (pc) (const_int 4)))
7954404b540aSrobert   (unspec_volatile [(reg:DI 29)] UNSPECV_BLOCKAGE)
7955404b540aSrobert   (use (match_operand 3 "" ""))
7956404b540aSrobert   (use (match_operand 4 "" ""))]
7957404b540aSrobert  "TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF"
7958404b540aSrobert  "jsr $26,(%1),%3%J4"
7959404b540aSrobert  [(set_attr "type" "jsr")
7960404b540aSrobert   (set_attr "cannot_copy" "true")])
7961404b540aSrobert
7962404b540aSrobert(define_insn "*call_value_osf_1_noreturn"
7963404b540aSrobert  [(set (match_operand 0 "" "")
7964404b540aSrobert	(call (mem:DI (match_operand:DI 1 "call_operand" "c,R,s"))
7965404b540aSrobert	      (match_operand 2 "" "")))
7966404b540aSrobert   (use (reg:DI 29))
7967404b540aSrobert   (clobber (reg:DI 26))]
7968404b540aSrobert  "! TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF
7969404b540aSrobert   && find_reg_note (insn, REG_NORETURN, NULL_RTX)"
7970404b540aSrobert  "@
7971404b540aSrobert   jsr $26,($27),0%+
7972404b540aSrobert   bsr $26,$%1..ng%+
7973404b540aSrobert   jsr $26,%1%+"
7974404b540aSrobert  [(set_attr "type" "jsr")
7975404b540aSrobert   (set_attr "length" "*,*,8")])
7976404b540aSrobert
7977404b540aSrobert(define_insn_and_split "call_value_osf_tlsgd"
7978404b540aSrobert  [(set (match_operand 0 "" "")
7979404b540aSrobert	(call (mem:DI (match_operand:DI 1 "symbolic_operand" ""))
7980404b540aSrobert	      (const_int 0)))
7981404b540aSrobert   (unspec [(match_operand:DI 2 "const_int_operand" "")] UNSPEC_TLSGD_CALL)
7982404b540aSrobert   (use (reg:DI 29))
7983404b540aSrobert   (clobber (reg:DI 26))]
7984404b540aSrobert  "HAVE_AS_TLS"
7985404b540aSrobert  "#"
7986404b540aSrobert  "&& reload_completed"
7987404b540aSrobert  [(set (match_dup 3)
7988404b540aSrobert	(unspec:DI [(match_dup 5)
7989404b540aSrobert		    (match_dup 1)
7990404b540aSrobert		    (match_dup 2)] UNSPEC_LITERAL))
7991404b540aSrobert   (parallel [(set (match_dup 0)
7992404b540aSrobert		   (call (mem:DI (match_dup 3))
7993404b540aSrobert			 (const_int 0)))
7994404b540aSrobert	      (set (reg:DI 26) (plus:DI (pc) (const_int 4)))
7995404b540aSrobert	      (unspec_volatile [(match_dup 5)] UNSPECV_BLOCKAGE)
7996404b540aSrobert	      (use (match_dup 1))
7997404b540aSrobert	      (use (unspec [(match_dup 2)] UNSPEC_TLSGD_CALL))])
7998404b540aSrobert   (set (match_dup 5)
7999404b540aSrobert	(unspec_volatile:DI [(reg:DI 26) (match_dup 4)] UNSPECV_LDGP1))
8000404b540aSrobert   (set (match_dup 5)
8001404b540aSrobert	(unspec:DI [(match_dup 5) (match_dup 4)] UNSPEC_LDGP2))]
8002404b540aSrobert{
8003404b540aSrobert  operands[3] = gen_rtx_REG (Pmode, 27);
8004404b540aSrobert  operands[4] = GEN_INT (alpha_next_sequence_number++);
8005404b540aSrobert  operands[5] = pic_offset_table_rtx;
8006404b540aSrobert}
8007404b540aSrobert  [(set_attr "type" "multi")])
8008404b540aSrobert
8009404b540aSrobert(define_insn_and_split "call_value_osf_tlsldm"
8010404b540aSrobert  [(set (match_operand 0 "" "")
8011404b540aSrobert	(call (mem:DI (match_operand:DI 1 "symbolic_operand" ""))
8012404b540aSrobert	      (const_int 0)))
8013404b540aSrobert   (unspec [(match_operand:DI 2 "const_int_operand" "")] UNSPEC_TLSLDM_CALL)
8014404b540aSrobert   (use (reg:DI 29))
8015404b540aSrobert   (clobber (reg:DI 26))]
8016404b540aSrobert  "HAVE_AS_TLS"
8017404b540aSrobert  "#"
8018404b540aSrobert  "&& reload_completed"
8019404b540aSrobert  [(set (match_dup 3)
8020404b540aSrobert	(unspec:DI [(match_dup 5)
8021404b540aSrobert		    (match_dup 1)
8022404b540aSrobert		    (match_dup 2)] UNSPEC_LITERAL))
8023404b540aSrobert   (parallel [(set (match_dup 0)
8024404b540aSrobert		   (call (mem:DI (match_dup 3))
8025404b540aSrobert			 (const_int 0)))
8026404b540aSrobert	      (set (reg:DI 26) (plus:DI (pc) (const_int 4)))
8027404b540aSrobert	      (unspec_volatile [(match_dup 5)] UNSPECV_BLOCKAGE)
8028404b540aSrobert	      (use (match_dup 1))
8029404b540aSrobert	      (use (unspec [(match_dup 2)] UNSPEC_TLSLDM_CALL))])
8030404b540aSrobert   (set (reg:DI 29)
8031404b540aSrobert	(unspec_volatile:DI [(reg:DI 26) (match_dup 4)] UNSPECV_LDGP1))
8032404b540aSrobert   (set (reg:DI 29)
8033404b540aSrobert	(unspec:DI [(reg:DI 29) (match_dup 4)] UNSPEC_LDGP2))]
8034404b540aSrobert{
8035404b540aSrobert  operands[3] = gen_rtx_REG (Pmode, 27);
8036404b540aSrobert  operands[4] = GEN_INT (alpha_next_sequence_number++);
8037404b540aSrobert  operands[5] = pic_offset_table_rtx;
8038404b540aSrobert}
8039404b540aSrobert  [(set_attr "type" "multi")])
8040404b540aSrobert
8041404b540aSrobert(define_insn "*call_value_osf_1"
8042404b540aSrobert  [(set (match_operand 0 "" "")
8043404b540aSrobert	(call (mem:DI (match_operand:DI 1 "call_operand" "c,R,s"))
8044404b540aSrobert	      (match_operand 2 "" "")))
8045404b540aSrobert   (use (reg:DI 29))
8046404b540aSrobert   (clobber (reg:DI 26))]
8047404b540aSrobert  "! TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF"
8048404b540aSrobert  "@
8049404b540aSrobert   jsr $26,($27),0\;ldgp $29,0($26)
8050404b540aSrobert   bsr $26,$%1..ng
8051404b540aSrobert   jsr $26,%1\;ldgp $29,0($26)"
8052404b540aSrobert  [(set_attr "type" "jsr")
8053404b540aSrobert   (set_attr "length" "12,*,16")])
8054404b540aSrobert
8055404b540aSrobert(define_insn "*sibcall_value_osf_1_er"
8056404b540aSrobert  [(set (match_operand 0 "" "")
8057404b540aSrobert	(call (mem:DI (match_operand:DI 1 "symbolic_operand" "R,s"))
8058404b540aSrobert	      (match_operand 2 "" "")))
8059404b540aSrobert   (unspec [(reg:DI 29)] UNSPEC_SIBCALL)]
8060404b540aSrobert  "TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF"
8061404b540aSrobert  "@
8062404b540aSrobert   br $31,%1\t\t!samegp
8063404b540aSrobert   ldq $27,%1($29)\t\t!literal!%#\;jmp $31,($27),%1\t\t!lituse_jsr!%#"
8064404b540aSrobert  [(set_attr "type" "jsr")
8065404b540aSrobert   (set_attr "length" "*,8")])
8066404b540aSrobert
8067404b540aSrobert(define_insn "*sibcall_value_osf_1"
8068404b540aSrobert  [(set (match_operand 0 "" "")
8069404b540aSrobert	(call (mem:DI (match_operand:DI 1 "symbolic_operand" "R,s"))
8070404b540aSrobert	      (match_operand 2 "" "")))
8071404b540aSrobert   (unspec [(reg:DI 29)] UNSPEC_SIBCALL)]
8072404b540aSrobert  "! TARGET_EXPLICIT_RELOCS && TARGET_ABI_OSF"
8073404b540aSrobert  "@
8074404b540aSrobert   br $31,$%1..ng
8075404b540aSrobert   lda $27,%1\;jmp $31,($27),%1"
8076404b540aSrobert  [(set_attr "type" "jsr")
8077404b540aSrobert   (set_attr "length" "*,8")])
8078404b540aSrobert
8079404b540aSrobert(define_insn "*call_value_nt_1"
8080404b540aSrobert  [(set (match_operand 0 "" "")
8081404b540aSrobert	(call (mem:DI (match_operand:DI 1 "call_operand" "r,R,s"))
8082404b540aSrobert	      (match_operand 2 "" "")))
8083404b540aSrobert   (clobber (reg:DI 26))]
8084404b540aSrobert  "TARGET_ABI_WINDOWS_NT"
8085404b540aSrobert  "@
8086404b540aSrobert   jsr $26,(%1)
8087404b540aSrobert   bsr $26,%1
8088404b540aSrobert   jsr $26,%1"
8089404b540aSrobert  [(set_attr "type" "jsr")
8090404b540aSrobert   (set_attr "length" "*,*,12")])
8091404b540aSrobert
8092404b540aSrobert; GAS relies on the order and position of instructions output below in order
8093404b540aSrobert; to generate relocs for VMS link to potentially optimize the call.
8094404b540aSrobert; Please do not molest.
8095404b540aSrobert(define_insn "*call_value_vms_1"
8096404b540aSrobert  [(set (match_operand 0 "" "")
8097404b540aSrobert	(call (mem:DI (match_operand:DI 1 "call_operand" "r,s"))
8098404b540aSrobert	      (match_operand 2 "" "")))
8099404b540aSrobert   (use (match_operand:DI 3 "nonmemory_operand" "r,n"))
8100404b540aSrobert   (use (reg:DI 25))
8101404b540aSrobert   (use (reg:DI 26))
8102404b540aSrobert   (clobber (reg:DI 27))]
8103404b540aSrobert  "TARGET_ABI_OPEN_VMS"
8104404b540aSrobert{
8105404b540aSrobert  switch (which_alternative)
8106404b540aSrobert    {
8107404b540aSrobert    case 0:
8108404b540aSrobert   	return "mov %3,$27\;jsr $26,0\;ldq $27,0($29)";
8109404b540aSrobert    case 1:
8110404b540aSrobert	operands [3] = alpha_use_linkage (operands [1], cfun->decl, 1, 0);
8111404b540aSrobert	operands [4] = alpha_use_linkage (operands [1], cfun->decl, 0, 0);
8112404b540aSrobert   	return "ldq $26,%4\;ldq $27,%3\;jsr $26,%1\;ldq $27,0($29)";
8113404b540aSrobert    default:
8114404b540aSrobert      gcc_unreachable ();
8115404b540aSrobert    }
8116404b540aSrobert}
8117404b540aSrobert  [(set_attr "type" "jsr")
8118404b540aSrobert   (set_attr "length" "12,16")])
8119404b540aSrobert
8120404b540aSrobert(define_insn "*call_value_umk"
8121404b540aSrobert  [(set (match_operand 0 "" "")
8122404b540aSrobert	(call (mem:DI (match_operand:DI 1 "call_operand" "r"))
8123404b540aSrobert	      (match_operand 2 "" "")))
8124404b540aSrobert   (use (reg:DI 25))
8125404b540aSrobert   (clobber (reg:DI 26))]
8126404b540aSrobert  "TARGET_ABI_UNICOSMK"
8127404b540aSrobert  "jsr $26,(%1)"
8128404b540aSrobert  [(set_attr "type" "jsr")])
8129